From b4f310c2be3ff6ec1510688a33df54792d8ffb29 Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Fri, 17 Aug 2018 16:06:47 +0200 Subject: [PATCH] add cyrussasl, iconv, openssl to libs for optional usage (if system does not provide) --- libs/cyrussasl/AUTHORS | 48 + libs/cyrussasl/COPYING | 44 + libs/cyrussasl/ChangeLog | 3440 ++++ libs/cyrussasl/INSTALL | 302 + libs/cyrussasl/INSTALL.TXT | 1 + libs/cyrussasl/NEWS | 503 + libs/cyrussasl/README | 21 + libs/cyrussasl/include/sasl/Makefile.am | 65 + libs/cyrussasl/include/sasl/NTMakefile | 65 + libs/cyrussasl/include/sasl/config.h | 607 + libs/cyrussasl/include/sasl/exits.h | 118 + libs/cyrussasl/include/sasl/gai.h | 108 + libs/cyrussasl/include/sasl/hmac-md5.h | 59 + libs/cyrussasl/include/sasl/makemd5.c | 246 + libs/cyrussasl/include/sasl/md5.h | 42 + libs/cyrussasl/include/sasl/md5global.h | 38 + libs/cyrussasl/include/sasl/prop.h | 186 + libs/cyrussasl/include/sasl/sasl.h | 1321 ++ libs/cyrussasl/include/sasl/saslplug.h | 986 + libs/cyrussasl/include/sasl/saslutil.h | 99 + libs/cyrussasl/lib/Makefile.am | 104 + libs/cyrussasl/lib/NTMakefile | 128 + libs/cyrussasl/lib/auxprop.c | 1198 ++ libs/cyrussasl/lib/canonusr.c | 462 + libs/cyrussasl/lib/checkpw.c | 1097 ++ libs/cyrussasl/lib/client.c | 1349 ++ libs/cyrussasl/lib/common.c | 2622 +++ libs/cyrussasl/lib/config.c | 168 + libs/cyrussasl/lib/dlopen.c | 562 + libs/cyrussasl/lib/external.c | 410 + libs/cyrussasl/lib/getaddrinfo.c | 254 + libs/cyrussasl/lib/getnameinfo.c | 108 + libs/cyrussasl/lib/getsubopt.c | 114 + libs/cyrussasl/lib/md5.c | 527 + libs/cyrussasl/lib/saslint.h | 528 + libs/cyrussasl/lib/saslutil.c | 812 + libs/cyrussasl/lib/server.c | 2398 +++ libs/cyrussasl/lib/seterror.c | 263 + libs/cyrussasl/lib/snprintf.c | 784 + libs/cyrussasl/lib/staticopen.h | 184 + libs/cyrussasl/lib/windlopen.c | 330 + libs/cyrussasl/plugins/Makefile.am | 158 + libs/cyrussasl/plugins/NTMakefile | 325 + libs/cyrussasl/plugins/anonymous.c | 390 + libs/cyrussasl/plugins/anonymous_init.c | 43 + libs/cyrussasl/plugins/cram.c | 689 + libs/cyrussasl/plugins/crammd5_init.c | 43 + libs/cyrussasl/plugins/digestmd5.c | 4655 +++++ libs/cyrussasl/plugins/digestmd5_init.c | 43 + libs/cyrussasl/plugins/gs2.c | 1851 ++ libs/cyrussasl/plugins/gs2_init.c | 43 + libs/cyrussasl/plugins/gs2_token.c | 324 + libs/cyrussasl/plugins/gs2_token.h | 58 + libs/cyrussasl/plugins/gssapi.c | 2076 +++ libs/cyrussasl/plugins/gssapiv2_init.c | 43 + libs/cyrussasl/plugins/kerberos4.c | 1406 ++ libs/cyrussasl/plugins/kerberos4_init.c | 43 + libs/cyrussasl/plugins/ldapdb.c | 569 + libs/cyrussasl/plugins/ldapdb_init.c | 39 + libs/cyrussasl/plugins/login.c | 496 + libs/cyrussasl/plugins/login_init.c | 43 + libs/cyrussasl/plugins/ntlm.c | 2175 +++ libs/cyrussasl/plugins/ntlm_init.c | 43 + libs/cyrussasl/plugins/otp.c | 1851 ++ libs/cyrussasl/plugins/otp.h | 311 + libs/cyrussasl/plugins/otp_init.c | 43 + libs/cyrussasl/plugins/passdss.c | 1682 ++ libs/cyrussasl/plugins/passdss_init.c | 43 + libs/cyrussasl/plugins/plain.c | 491 + libs/cyrussasl/plugins/plain_init.c | 43 + libs/cyrussasl/plugins/plugin_common.c | 924 + libs/cyrussasl/plugins/plugin_common.h | 222 + libs/cyrussasl/plugins/sasldb.c | 317 + libs/cyrussasl/plugins/sasldb_init.c | 38 + libs/cyrussasl/plugins/scram.c | 2722 +++ libs/cyrussasl/plugins/scram_init.c | 43 + libs/cyrussasl/plugins/sql.c | 1359 ++ libs/cyrussasl/plugins/sql_init.c | 38 + libs/cyrussasl/plugins/srp.c | 3184 ++++ libs/cyrussasl/plugins/srp_init.c | 43 + libs/libiconv/AUTHORS | 1 + libs/libiconv/COPYING | 674 + libs/libiconv/COPYING.LIB | 482 + libs/libiconv/ChangeLog | 4913 +++++ libs/libiconv/DEPENDENCIES | 1 + libs/libiconv/DESIGN | 64 + libs/libiconv/HACKING | 64 + libs/libiconv/INSTALL.generic | 273 + libs/libiconv/NEWS | 184 + libs/libiconv/NOTES | 399 + libs/libiconv/PORTS | 46 + libs/libiconv/README | 171 + libs/libiconv/README.djgpp | 3 + libs/libiconv/README.woe32 | 37 + libs/libiconv/THANKS | 15 + libs/libiconv/config.h | 927 + libs/libiconv/include/iconv.h | 248 + libs/libiconv/lib/aliases.gperf | 358 + libs/libiconv/lib/aliases.h | 1719 ++ libs/libiconv/lib/aliases2.h | 40 + libs/libiconv/lib/aliases_aix.h | 18 + libs/libiconv/lib/aliases_aix_sysaix.h | 24 + libs/libiconv/lib/aliases_dos.h | 48 + libs/libiconv/lib/aliases_extra.h | 12 + libs/libiconv/lib/aliases_osf1.h | 2 + libs/libiconv/lib/aliases_osf1_sysosf1.h | 4 + libs/libiconv/lib/aliases_sysaix.gperf | 367 + libs/libiconv/lib/aliases_sysaix.h | 1769 ++ libs/libiconv/lib/aliases_syshpux.gperf | 368 + libs/libiconv/lib/aliases_syshpux.h | 1773 ++ libs/libiconv/lib/aliases_sysosf1.gperf | 363 + libs/libiconv/lib/aliases_sysosf1.h | 1745 ++ libs/libiconv/lib/aliases_syssolaris.gperf | 365 + libs/libiconv/lib/aliases_syssolaris.h | 1756 ++ libs/libiconv/lib/armscii_8.h | 116 + libs/libiconv/lib/ascii.h | 44 + libs/libiconv/lib/atarist.h | 158 + libs/libiconv/lib/big5.h | 4160 +++++ libs/libiconv/lib/big5_2003.h | 476 + libs/libiconv/lib/big5hkscs1999.h | 197 + libs/libiconv/lib/big5hkscs2001.h | 215 + libs/libiconv/lib/big5hkscs2004.h | 231 + libs/libiconv/lib/big5hkscs2008.h | 247 + libs/libiconv/lib/c99.h | 125 + libs/libiconv/lib/canonical.h | 110 + libs/libiconv/lib/canonical_aix.h | 9 + libs/libiconv/lib/canonical_aix_sysaix.h | 9 + libs/libiconv/lib/canonical_dos.h | 15 + libs/libiconv/lib/canonical_extra.h | 7 + libs/libiconv/lib/canonical_local.h | 2 + libs/libiconv/lib/canonical_local_sysaix.h | 2 + libs/libiconv/lib/canonical_local_syshpux.h | 2 + libs/libiconv/lib/canonical_local_sysosf1.h | 2 + .../libiconv/lib/canonical_local_syssolaris.h | 2 + libs/libiconv/lib/canonical_osf1.h | 2 + libs/libiconv/lib/canonical_osf1_sysosf1.h | 2 + libs/libiconv/lib/canonical_sysaix.h | 110 + libs/libiconv/lib/canonical_syshpux.h | 110 + libs/libiconv/lib/canonical_sysosf1.h | 110 + libs/libiconv/lib/canonical_syssolaris.h | 110 + libs/libiconv/lib/ces_big5.h | 70 + libs/libiconv/lib/ces_gbk.h | 65 + libs/libiconv/lib/cjk_variants.h | 4241 +++++ libs/libiconv/lib/cns11643.h | 41 + libs/libiconv/lib/cns11643_1.h | 893 + libs/libiconv/lib/cns11643_15.h | 1083 ++ libs/libiconv/lib/cns11643_2.h | 1112 ++ libs/libiconv/lib/cns11643_3.h | 974 + libs/libiconv/lib/cns11643_4.h | 61 + libs/libiconv/lib/cns11643_4a.h | 460 + libs/libiconv/lib/cns11643_4b.h | 668 + libs/libiconv/lib/cns11643_5.h | 1278 ++ libs/libiconv/lib/cns11643_6.h | 968 + libs/libiconv/lib/cns11643_7.h | 988 + libs/libiconv/lib/cns11643_inv.h | 15412 ++++++++++++++++ libs/libiconv/lib/config.h | 72 + libs/libiconv/lib/converters.h | 298 + libs/libiconv/lib/cp1046.h | 157 + libs/libiconv/lib/cp1124.h | 102 + libs/libiconv/lib/cp1125.h | 129 + libs/libiconv/lib/cp1129.h | 121 + libs/libiconv/lib/cp1131.h | 132 + libs/libiconv/lib/cp1133.h | 110 + libs/libiconv/lib/cp1161.h | 89 + libs/libiconv/lib/cp1162.h | 70 + libs/libiconv/lib/cp1163.h | 63 + libs/libiconv/lib/cp1250.h | 139 + libs/libiconv/lib/cp1251.h | 131 + libs/libiconv/lib/cp1252.h | 103 + libs/libiconv/lib/cp1253.h | 122 + libs/libiconv/lib/cp1254.h | 146 + libs/libiconv/lib/cp1255.h | 380 + libs/libiconv/lib/cp1256.h | 153 + libs/libiconv/lib/cp1257.h | 139 + libs/libiconv/lib/cp1258.h | 288 + libs/libiconv/lib/cp437.h | 156 + libs/libiconv/lib/cp737.h | 141 + libs/libiconv/lib/cp775.h | 142 + libs/libiconv/lib/cp850.h | 124 + libs/libiconv/lib/cp852.h | 143 + libs/libiconv/lib/cp853.h | 151 + libs/libiconv/lib/cp855.h | 128 + libs/libiconv/lib/cp856.h | 134 + libs/libiconv/lib/cp857.h | 138 + libs/libiconv/lib/cp858.h | 61 + libs/libiconv/lib/cp860.h | 149 + libs/libiconv/lib/cp861.h | 156 + libs/libiconv/lib/cp862.h | 155 + libs/libiconv/lib/cp863.h | 156 + libs/libiconv/lib/cp864.h | 188 + libs/libiconv/lib/cp865.h | 156 + libs/libiconv/lib/cp866.h | 125 + libs/libiconv/lib/cp869.h | 137 + libs/libiconv/lib/cp874.h | 111 + libs/libiconv/lib/cp922.h | 99 + libs/libiconv/lib/cp932.h | 240 + libs/libiconv/lib/cp932ext.h | 709 + libs/libiconv/lib/cp936.h | 126 + libs/libiconv/lib/cp936ext.h | 99 + libs/libiconv/lib/cp943.h | 29 + libs/libiconv/lib/cp949.h | 128 + libs/libiconv/lib/cp950.h | 284 + libs/libiconv/lib/cp950ext.h | 161 + libs/libiconv/lib/dec_hanyu.h | 115 + libs/libiconv/lib/dec_kanji.h | 71 + libs/libiconv/lib/encodings.def | 1030 ++ libs/libiconv/lib/encodings_aix.def | 97 + libs/libiconv/lib/encodings_dos.def | 127 + libs/libiconv/lib/encodings_extra.def | 57 + libs/libiconv/lib/encodings_local.def | 29 + libs/libiconv/lib/encodings_osf1.def | 37 + libs/libiconv/lib/euc_cn.h | 72 + libs/libiconv/lib/euc_jisx0213.h | 268 + libs/libiconv/lib/euc_jp.h | 191 + libs/libiconv/lib/euc_kr.h | 74 + libs/libiconv/lib/euc_tw.h | 116 + libs/libiconv/lib/flags.h | 157 + libs/libiconv/lib/flushwc.h | 37 + libs/libiconv/lib/gb12345.h | 67 + libs/libiconv/lib/gb12345ext.h | 1796 ++ libs/libiconv/lib/gb18030.h | 382 + libs/libiconv/lib/gb18030ext.h | 328 + libs/libiconv/lib/gb18030uni.h | 249 + libs/libiconv/lib/gb2312.h | 2571 +++ libs/libiconv/lib/gbk.h | 169 + libs/libiconv/lib/gbkext1.h | 853 + libs/libiconv/lib/gbkext2.h | 1174 ++ libs/libiconv/lib/gbkext_inv.h | 2343 +++ libs/libiconv/lib/genaliases.c | 104 + libs/libiconv/lib/genaliases2.c | 83 + libs/libiconv/lib/genflags.c | 114 + libs/libiconv/lib/gentranslit.c | 258 + libs/libiconv/lib/georgian_academy.h | 106 + libs/libiconv/lib/georgian_ps.h | 123 + libs/libiconv/lib/hkscs1999.h | 3005 +++ libs/libiconv/lib/hkscs2001.h | 683 + libs/libiconv/lib/hkscs2004.h | 679 + libs/libiconv/lib/hkscs2008.h | 467 + libs/libiconv/lib/hp_roman8.h | 119 + libs/libiconv/lib/hz.h | 163 + libs/libiconv/lib/iconv.c | 610 + libs/libiconv/lib/iconv_open1.h | 229 + libs/libiconv/lib/iconv_open2.h | 89 + libs/libiconv/lib/iso2022_cn.h | 324 + libs/libiconv/lib/iso2022_cnext.h | 590 + libs/libiconv/lib/iso2022_jp.h | 216 + libs/libiconv/lib/iso2022_jp1.h | 264 + libs/libiconv/lib/iso2022_jp2.h | 693 + libs/libiconv/lib/iso2022_jp3.h | 538 + libs/libiconv/lib/iso2022_kr.h | 222 + libs/libiconv/lib/iso646_cn.h | 58 + libs/libiconv/lib/iso646_jp.h | 60 + libs/libiconv/lib/iso8859_1.h | 41 + libs/libiconv/lib/iso8859_10.h | 106 + libs/libiconv/lib/iso8859_11.h | 52 + libs/libiconv/lib/iso8859_13.h | 109 + libs/libiconv/lib/iso8859_14.h | 127 + libs/libiconv/lib/iso8859_15.h | 81 + libs/libiconv/lib/iso8859_16.h | 116 + libs/libiconv/lib/iso8859_2.h | 112 + libs/libiconv/lib/iso8859_3.h | 118 + libs/libiconv/lib/iso8859_4.h | 112 + libs/libiconv/lib/iso8859_5.h | 95 + libs/libiconv/lib/iso8859_6.h | 98 + libs/libiconv/lib/iso8859_7.h | 111 + libs/libiconv/lib/iso8859_8.h | 107 + libs/libiconv/lib/iso8859_9.h | 85 + libs/libiconv/lib/isoir165.h | 159 + libs/libiconv/lib/isoir165ext.h | 800 + libs/libiconv/lib/java.h | 137 + libs/libiconv/lib/jisx0201.h | 66 + libs/libiconv/lib/jisx0208.h | 2415 +++ libs/libiconv/lib/jisx0212.h | 2189 +++ libs/libiconv/lib/jisx0213.h | 5924 ++++++ libs/libiconv/lib/johab.h | 139 + libs/libiconv/lib/johab_hangul.h | 262 + libs/libiconv/lib/koi8_r.h | 153 + libs/libiconv/lib/koi8_ru.h | 159 + libs/libiconv/lib/koi8_t.h | 143 + libs/libiconv/lib/koi8_u.h | 161 + libs/libiconv/lib/ksc5601.h | 3022 +++ libs/libiconv/lib/loop_unicode.h | 527 + libs/libiconv/lib/loop_wchar.h | 474 + libs/libiconv/lib/loops.h | 25 + libs/libiconv/lib/mac_arabic.h | 132 + libs/libiconv/lib/mac_centraleurope.h | 139 + libs/libiconv/lib/mac_croatian.h | 165 + libs/libiconv/lib/mac_cyrillic.h | 136 + libs/libiconv/lib/mac_greek.h | 135 + libs/libiconv/lib/mac_hebrew.h | 132 + libs/libiconv/lib/mac_iceland.h | 162 + libs/libiconv/lib/mac_roman.h | 167 + libs/libiconv/lib/mac_romania.h | 165 + libs/libiconv/lib/mac_thai.h | 128 + libs/libiconv/lib/mac_turkish.h | 163 + libs/libiconv/lib/mac_ukraine.h | 143 + libs/libiconv/lib/mulelao.h | 96 + libs/libiconv/lib/nextstep.h | 141 + libs/libiconv/lib/pt154.h | 118 + libs/libiconv/lib/relocatable.c | 483 + libs/libiconv/lib/relocatable.h | 83 + libs/libiconv/lib/riscos1.h | 96 + libs/libiconv/lib/rk1048.h | 145 + libs/libiconv/lib/shift_jisx0213.h | 310 + libs/libiconv/lib/sjis.h | 132 + libs/libiconv/lib/stamp-h2 | 1 + libs/libiconv/lib/tcvn.h | 291 + libs/libiconv/lib/tds565.h | 107 + libs/libiconv/lib/tis620.h | 52 + libs/libiconv/lib/translit.def | 3918 ++++ libs/libiconv/lib/translit.h | 4411 +++++ libs/libiconv/lib/ucs2.h | 68 + libs/libiconv/lib/ucs2be.h | 51 + libs/libiconv/lib/ucs2internal.h | 51 + libs/libiconv/lib/ucs2le.h | 51 + libs/libiconv/lib/ucs2swapped.h | 60 + libs/libiconv/lib/ucs4.h | 69 + libs/libiconv/lib/ucs4be.h | 46 + libs/libiconv/lib/ucs4internal.h | 43 + libs/libiconv/lib/ucs4le.h | 46 + libs/libiconv/lib/ucs4swapped.h | 53 + libs/libiconv/lib/uhc_1.h | 1725 ++ libs/libiconv/lib/uhc_2.h | 1022 + libs/libiconv/lib/utf16.h | 113 + libs/libiconv/lib/utf16be.h | 80 + libs/libiconv/lib/utf16le.h | 80 + libs/libiconv/lib/utf32.h | 93 + libs/libiconv/lib/utf32be.h | 55 + libs/libiconv/lib/utf32le.h | 55 + libs/libiconv/lib/utf7.h | 355 + libs/libiconv/lib/utf8.h | 128 + libs/libiconv/lib/vietcomb.h | 466 + libs/libiconv/lib/viscii.h | 141 + libs/libiconv/libcharset/AUTHORS | 1 + libs/libiconv/libcharset/COPYING.LIB | 482 + libs/libiconv/libcharset/ChangeLog | 699 + libs/libiconv/libcharset/DEPENDENCIES | 1 + libs/libiconv/libcharset/HACKING | 36 + libs/libiconv/libcharset/INSTALL.generic | 273 + libs/libiconv/libcharset/INTEGRATE | 154 + libs/libiconv/libcharset/NEWS | 5 + libs/libiconv/libcharset/README | 62 + libs/libiconv/libcharset/README.djgpp | 3 + libs/libiconv/libcharset/README.woe32 | 4 + libs/libiconv/libcharset/include/export.h | 6 + .../libcharset/include/localcharset.h | 48 + libs/libiconv/libcharset/lib/localcharset.c | 548 + libs/openssl/Android.mk | 7 + libs/openssl/Application.mk | 4 + libs/openssl/CHANGES | 10737 +++++++++++ libs/openssl/LICENSE | 127 + libs/openssl/README | 119 + libs/openssl/android-config.mk | 17 + libs/openssl/crypto/LPdir_nyi.c | 47 + libs/openssl/crypto/LPdir_unix.c | 126 + libs/openssl/crypto/LPdir_vms.c | 195 + libs/openssl/crypto/LPdir_win.c | 170 + libs/openssl/crypto/LPdir_win32.c | 33 + libs/openssl/crypto/LPdir_wince.c | 36 + libs/openssl/crypto/aes/README | 3 + libs/openssl/crypto/aes/aes.h | 149 + libs/openssl/crypto/aes/aes_cbc.c | 66 + libs/openssl/crypto/aes/aes_cfb.c | 85 + libs/openssl/crypto/aes/aes_core.c | 1363 ++ libs/openssl/crypto/aes/aes_ctr.c | 63 + libs/openssl/crypto/aes/aes_ecb.c | 73 + libs/openssl/crypto/aes/aes_ige.c | 323 + libs/openssl/crypto/aes/aes_locl.h | 89 + libs/openssl/crypto/aes/aes_misc.c | 86 + libs/openssl/crypto/aes/aes_ofb.c | 61 + libs/openssl/crypto/aes/aes_wrap.c | 250 + libs/openssl/crypto/aes/aes_x86core.c | 1070 ++ libs/openssl/crypto/aes/asm/aes-586.pl | 2980 +++ libs/openssl/crypto/aes/asm/aes-armv4.pl | 1134 ++ libs/openssl/crypto/aes/asm/aes-ia64.S | 1123 ++ libs/openssl/crypto/aes/asm/aes-mips.pl | 1611 ++ libs/openssl/crypto/aes/asm/aes-parisc.pl | 1022 + libs/openssl/crypto/aes/asm/aes-ppc.pl | 1365 ++ libs/openssl/crypto/aes/asm/aes-s390x.pl | 2237 +++ libs/openssl/crypto/aes/asm/aes-sparcv9.pl | 1182 ++ libs/openssl/crypto/aes/asm/aes-x86_64.pl | 2819 +++ .../crypto/aes/asm/aesni-sha1-x86_64.pl | 1250 ++ libs/openssl/crypto/aes/asm/aesni-x86.pl | 2189 +++ libs/openssl/crypto/aes/asm/aesni-x86_64.pl | 3071 +++ libs/openssl/crypto/aes/asm/bsaes-x86_64.pl | 3108 ++++ libs/openssl/crypto/aes/asm/vpaes-x86.pl | 903 + libs/openssl/crypto/aes/asm/vpaes-x86_64.pl | 1207 ++ libs/openssl/crypto/alphacpuid.pl | 126 + libs/openssl/crypto/arm_arch.h | 51 + libs/openssl/crypto/armcap.c | 81 + libs/openssl/crypto/armv4cpuid.S | 154 + libs/openssl/crypto/asn1/a_bitstr.c | 262 + libs/openssl/crypto/asn1/a_bool.c | 111 + libs/openssl/crypto/asn1/a_bytes.c | 306 + libs/openssl/crypto/asn1/a_d2i_fp.c | 284 + libs/openssl/crypto/asn1/a_digest.c | 111 + libs/openssl/crypto/asn1/a_dup.c | 117 + libs/openssl/crypto/asn1/a_enum.c | 181 + libs/openssl/crypto/asn1/a_gentm.c | 270 + libs/openssl/crypto/asn1/a_i2d_fp.c | 157 + libs/openssl/crypto/asn1/a_int.c | 464 + libs/openssl/crypto/asn1/a_mbstr.c | 423 + libs/openssl/crypto/asn1/a_object.c | 402 + libs/openssl/crypto/asn1/a_octet.c | 78 + libs/openssl/crypto/asn1/a_print.c | 129 + libs/openssl/crypto/asn1/a_set.c | 238 + libs/openssl/crypto/asn1/a_sign.c | 331 + libs/openssl/crypto/asn1/a_strex.c | 649 + libs/openssl/crypto/asn1/a_strnid.c | 313 + libs/openssl/crypto/asn1/a_time.c | 198 + libs/openssl/crypto/asn1/a_type.c | 155 + libs/openssl/crypto/asn1/a_utctm.c | 330 + libs/openssl/crypto/asn1/a_utf8.c | 237 + libs/openssl/crypto/asn1/a_verify.c | 231 + libs/openssl/crypto/asn1/ameth_lib.c | 462 + libs/openssl/crypto/asn1/asn1.h | 1417 ++ libs/openssl/crypto/asn1/asn1_err.c | 354 + libs/openssl/crypto/asn1/asn1_gen.c | 831 + libs/openssl/crypto/asn1/asn1_lib.c | 479 + libs/openssl/crypto/asn1/asn1_locl.h | 132 + libs/openssl/crypto/asn1/asn1_mac.h | 579 + libs/openssl/crypto/asn1/asn1_par.c | 424 + libs/openssl/crypto/asn1/asn1t.h | 973 + libs/openssl/crypto/asn1/asn_mime.c | 974 + libs/openssl/crypto/asn1/asn_moid.c | 153 + libs/openssl/crypto/asn1/asn_pack.c | 207 + libs/openssl/crypto/asn1/bio_asn1.c | 482 + libs/openssl/crypto/asn1/bio_ndef.c | 248 + libs/openssl/crypto/asn1/charmap.h | 15 + libs/openssl/crypto/asn1/charmap.pl | 83 + libs/openssl/crypto/asn1/d2i_pr.c | 175 + libs/openssl/crypto/asn1/d2i_pu.c | 136 + libs/openssl/crypto/asn1/evp_asn1.c | 195 + libs/openssl/crypto/asn1/f_enum.c | 203 + libs/openssl/crypto/asn1/f_int.c | 215 + libs/openssl/crypto/asn1/f_string.c | 209 + libs/openssl/crypto/asn1/i2d_pr.c | 78 + libs/openssl/crypto/asn1/i2d_pu.c | 93 + libs/openssl/crypto/asn1/n_pkey.c | 345 + libs/openssl/crypto/asn1/nsseq.c | 84 + libs/openssl/crypto/asn1/p5_pbe.c | 143 + libs/openssl/crypto/asn1/p5_pbev2.c | 280 + libs/openssl/crypto/asn1/p8_pkey.c | 145 + libs/openssl/crypto/asn1/t_bitst.c | 105 + libs/openssl/crypto/asn1/t_crl.c | 133 + libs/openssl/crypto/asn1/t_pkey.c | 113 + libs/openssl/crypto/asn1/t_req.c | 254 + libs/openssl/crypto/asn1/t_spki.c | 108 + libs/openssl/crypto/asn1/t_x509.c | 541 + libs/openssl/crypto/asn1/t_x509a.c | 115 + libs/openssl/crypto/asn1/tasn_dec.c | 1229 ++ libs/openssl/crypto/asn1/tasn_enc.c | 659 + libs/openssl/crypto/asn1/tasn_fre.c | 249 + libs/openssl/crypto/asn1/tasn_new.c | 381 + libs/openssl/crypto/asn1/tasn_prn.c | 585 + libs/openssl/crypto/asn1/tasn_typ.c | 149 + libs/openssl/crypto/asn1/tasn_utl.c | 275 + libs/openssl/crypto/asn1/x_algor.c | 148 + libs/openssl/crypto/asn1/x_attrib.c | 124 + libs/openssl/crypto/asn1/x_bignum.c | 153 + libs/openssl/crypto/asn1/x_crl.c | 515 + libs/openssl/crypto/asn1/x_exten.c | 77 + libs/openssl/crypto/asn1/x_info.c | 117 + libs/openssl/crypto/asn1/x_long.c | 196 + libs/openssl/crypto/asn1/x_name.c | 538 + libs/openssl/crypto/asn1/x_nx509.c | 72 + libs/openssl/crypto/asn1/x_pkey.c | 153 + libs/openssl/crypto/asn1/x_pubkey.c | 374 + libs/openssl/crypto/asn1/x_req.c | 116 + libs/openssl/crypto/asn1/x_sig.c | 69 + libs/openssl/crypto/asn1/x_spki.c | 82 + libs/openssl/crypto/asn1/x_val.c | 69 + libs/openssl/crypto/asn1/x_x509.c | 219 + libs/openssl/crypto/asn1/x_x509a.c | 193 + libs/openssl/crypto/bf/COPYRIGHT | 46 + libs/openssl/crypto/bf/INSTALL | 14 + libs/openssl/crypto/bf/README | 8 + libs/openssl/crypto/bf/VERSION | 6 + libs/openssl/crypto/bf/asm/bf-586.pl | 137 + libs/openssl/crypto/bf/asm/bf-686.pl | 127 + libs/openssl/crypto/bf/asm/readme | 10 + libs/openssl/crypto/bf/bf_cbc.c | 135 + libs/openssl/crypto/bf/bf_cfb64.c | 123 + libs/openssl/crypto/bf/bf_ecb.c | 100 + libs/openssl/crypto/bf/bf_enc.c | 300 + libs/openssl/crypto/bf/bf_locl.h | 221 + libs/openssl/crypto/bf/bf_ofb64.c | 110 + libs/openssl/crypto/bf/bf_opts.c | 324 + libs/openssl/crypto/bf/bf_pi.h | 579 + libs/openssl/crypto/bf/bf_skey.c | 125 + libs/openssl/crypto/bf/bfs.cpp | 67 + libs/openssl/crypto/bf/bfspeed.c | 265 + libs/openssl/crypto/bf/bftest.c | 538 + libs/openssl/crypto/bf/blowfish.h | 130 + libs/openssl/crypto/bio/b_dump.c | 183 + libs/openssl/crypto/bio/b_print.c | 863 + libs/openssl/crypto/bio/b_sock.c | 958 + libs/openssl/crypto/bio/bf_buff.c | 517 + libs/openssl/crypto/bio/bf_lbuf.c | 391 + libs/openssl/crypto/bio/bf_nbio.c | 253 + libs/openssl/crypto/bio/bf_null.c | 189 + libs/openssl/crypto/bio/bio.h | 879 + libs/openssl/crypto/bio/bio_cb.c | 145 + libs/openssl/crypto/bio/bio_err.c | 157 + libs/openssl/crypto/bio/bio_lcl.h | 36 + libs/openssl/crypto/bio/bio_lib.c | 596 + libs/openssl/crypto/bio/bss_acpt.c | 463 + libs/openssl/crypto/bio/bss_bio.c | 886 + libs/openssl/crypto/bio/bss_conn.c | 612 + libs/openssl/crypto/bio/bss_dgram.c | 2011 ++ libs/openssl/crypto/bio/bss_fd.c | 312 + libs/openssl/crypto/bio/bss_file.c | 472 + libs/openssl/crypto/bio/bss_log.c | 453 + libs/openssl/crypto/bio/bss_mem.c | 311 + libs/openssl/crypto/bio/bss_null.c | 149 + libs/openssl/crypto/bio/bss_rtcp.c | 319 + libs/openssl/crypto/bio/bss_sock.c | 287 + libs/openssl/crypto/bn/asm/README | 27 + libs/openssl/crypto/bn/asm/alpha-mont.pl | 321 + libs/openssl/crypto/bn/asm/armv4-gf2m.pl | 278 + libs/openssl/crypto/bn/asm/armv4-mont.pl | 204 + libs/openssl/crypto/bn/asm/bn-586.pl | 774 + libs/openssl/crypto/bn/asm/co-586.pl | 287 + libs/openssl/crypto/bn/asm/ia64-mont.pl | 851 + libs/openssl/crypto/bn/asm/ia64.S | 1555 ++ libs/openssl/crypto/bn/asm/mips-mont.pl | 426 + libs/openssl/crypto/bn/asm/mips.pl | 2234 +++ libs/openssl/crypto/bn/asm/mips3-mont.pl | 327 + .../openssl/crypto/bn/asm/modexp512-x86_64.pl | 1497 ++ libs/openssl/crypto/bn/asm/pa-risc2.s | 1618 ++ libs/openssl/crypto/bn/asm/pa-risc2W.s | 1605 ++ libs/openssl/crypto/bn/asm/parisc-mont.pl | 995 + libs/openssl/crypto/bn/asm/ppc-mont.pl | 334 + libs/openssl/crypto/bn/asm/ppc.pl | 1998 ++ libs/openssl/crypto/bn/asm/ppc64-mont.pl | 1088 ++ libs/openssl/crypto/bn/asm/s390x-gf2m.pl | 221 + libs/openssl/crypto/bn/asm/s390x-mont.pl | 277 + libs/openssl/crypto/bn/asm/s390x.S | 678 + libs/openssl/crypto/bn/asm/sparcv8.S | 1458 ++ libs/openssl/crypto/bn/asm/sparcv8plus.S | 1558 ++ libs/openssl/crypto/bn/asm/sparcv9-mont.pl | 606 + libs/openssl/crypto/bn/asm/sparcv9a-mont.pl | 882 + libs/openssl/crypto/bn/asm/via-mont.pl | 242 + libs/openssl/crypto/bn/asm/vms.mar | 6440 +++++++ libs/openssl/crypto/bn/asm/x86-gf2m.pl | 313 + libs/openssl/crypto/bn/asm/x86-mont.pl | 608 + libs/openssl/crypto/bn/asm/x86.pl | 28 + libs/openssl/crypto/bn/asm/x86/add.pl | 76 + libs/openssl/crypto/bn/asm/x86/comba.pl | 277 + libs/openssl/crypto/bn/asm/x86/div.pl | 15 + libs/openssl/crypto/bn/asm/x86/f | 3 + libs/openssl/crypto/bn/asm/x86/mul.pl | 77 + libs/openssl/crypto/bn/asm/x86/mul_add.pl | 87 + libs/openssl/crypto/bn/asm/x86/sqr.pl | 60 + libs/openssl/crypto/bn/asm/x86/sub.pl | 76 + libs/openssl/crypto/bn/asm/x86_64-gcc.c | 636 + libs/openssl/crypto/bn/asm/x86_64-gf2m.pl | 390 + libs/openssl/crypto/bn/asm/x86_64-mont.pl | 1715 ++ libs/openssl/crypto/bn/asm/x86_64-mont5.pl | 1208 ++ libs/openssl/crypto/bn/bn.h | 967 + libs/openssl/crypto/bn/bn.mul | 19 + libs/openssl/crypto/bn/bn_add.c | 313 + libs/openssl/crypto/bn/bn_asm.c | 1094 ++ libs/openssl/crypto/bn/bn_blind.c | 385 + libs/openssl/crypto/bn/bn_const.c | 547 + libs/openssl/crypto/bn/bn_ctx.c | 448 + libs/openssl/crypto/bn/bn_depr.c | 115 + libs/openssl/crypto/bn/bn_div.c | 477 + libs/openssl/crypto/bn/bn_err.c | 154 + libs/openssl/crypto/bn/bn_exp.c | 1183 ++ libs/openssl/crypto/bn/bn_exp2.c | 303 + libs/openssl/crypto/bn/bn_gcd.c | 702 + libs/openssl/crypto/bn/bn_gf2m.c | 1301 ++ libs/openssl/crypto/bn/bn_kron.c | 186 + libs/openssl/crypto/bn/bn_lcl.h | 510 + libs/openssl/crypto/bn/bn_lib.c | 916 + libs/openssl/crypto/bn/bn_mod.c | 316 + libs/openssl/crypto/bn/bn_mont.c | 558 + libs/openssl/crypto/bn/bn_mpi.c | 128 + libs/openssl/crypto/bn/bn_mul.c | 1164 ++ libs/openssl/crypto/bn/bn_nist.c | 1262 ++ libs/openssl/crypto/bn/bn_prime.c | 515 + libs/openssl/crypto/bn/bn_prime.h | 326 + libs/openssl/crypto/bn/bn_prime.pl | 119 + libs/openssl/crypto/bn/bn_print.c | 397 + libs/openssl/crypto/bn/bn_rand.c | 295 + libs/openssl/crypto/bn/bn_recp.c | 252 + libs/openssl/crypto/bn/bn_shift.c | 224 + libs/openssl/crypto/bn/bn_sqr.c | 290 + libs/openssl/crypto/bn/bn_sqrt.c | 409 + libs/openssl/crypto/bn/bn_word.c | 227 + libs/openssl/crypto/bn/bn_x931p.c | 277 + libs/openssl/crypto/bn/bnspeed.c | 232 + libs/openssl/crypto/bn/bntest.c | 2137 +++ libs/openssl/crypto/bn/divtest.c | 42 + libs/openssl/crypto/bn/exp.c | 61 + libs/openssl/crypto/bn/expspeed.c | 381 + libs/openssl/crypto/bn/exptest.c | 313 + libs/openssl/crypto/bn/todo | 3 + libs/openssl/crypto/bn/vms-helper.c | 68 + libs/openssl/crypto/buffer/buf_err.c | 97 + libs/openssl/crypto/buffer/buf_str.c | 126 + libs/openssl/crypto/buffer/buffer.c | 187 + libs/openssl/crypto/buffer/buffer.h | 124 + libs/openssl/crypto/camellia/asm/cmll-x86.pl | 1138 ++ .../crypto/camellia/asm/cmll-x86_64.pl | 1081 ++ libs/openssl/crypto/camellia/camellia.c | 584 + libs/openssl/crypto/camellia/camellia.h | 132 + libs/openssl/crypto/camellia/cmll_cbc.c | 66 + libs/openssl/crypto/camellia/cmll_cfb.c | 141 + libs/openssl/crypto/camellia/cmll_ctr.c | 64 + libs/openssl/crypto/camellia/cmll_ecb.c | 73 + libs/openssl/crypto/camellia/cmll_locl.h | 88 + libs/openssl/crypto/camellia/cmll_misc.c | 80 + libs/openssl/crypto/camellia/cmll_ofb.c | 122 + libs/openssl/crypto/camellia/cmll_utl.c | 64 + libs/openssl/crypto/cast/asm/cast-586.pl | 177 + libs/openssl/crypto/cast/asm/readme | 7 + libs/openssl/crypto/cast/c_cfb64.c | 123 + libs/openssl/crypto/cast/c_ecb.c | 83 + libs/openssl/crypto/cast/c_enc.c | 200 + libs/openssl/crypto/cast/c_ofb64.c | 110 + libs/openssl/crypto/cast/c_skey.c | 175 + libs/openssl/crypto/cast/cast.h | 107 + libs/openssl/crypto/cast/cast_lcl.h | 225 + libs/openssl/crypto/cast/cast_s.h | 592 + libs/openssl/crypto/cast/cast_spd.c | 262 + libs/openssl/crypto/cast/castopts.c | 334 + libs/openssl/crypto/cast/casts.cpp | 70 + libs/openssl/crypto/cast/casttest.c | 241 + libs/openssl/crypto/cmac/cm_ameth.c | 96 + libs/openssl/crypto/cmac/cm_pmeth.c | 216 + libs/openssl/crypto/cmac/cmac.c | 298 + libs/openssl/crypto/cmac/cmac.h | 82 + libs/openssl/crypto/cms/cms.h | 505 + libs/openssl/crypto/cms/cms_asn1.c | 381 + libs/openssl/crypto/cms/cms_att.c | 197 + libs/openssl/crypto/cms/cms_cd.c | 134 + libs/openssl/crypto/cms/cms_dd.c | 145 + libs/openssl/crypto/cms/cms_enc.c | 260 + libs/openssl/crypto/cms/cms_env.c | 814 + libs/openssl/crypto/cms/cms_err.c | 293 + libs/openssl/crypto/cms/cms_ess.c | 395 + libs/openssl/crypto/cms/cms_io.c | 133 + libs/openssl/crypto/cms/cms_lcl.h | 443 + libs/openssl/crypto/cms/cms_lib.c | 595 + libs/openssl/crypto/cms/cms_pwri.c | 435 + libs/openssl/crypto/cms/cms_sd.c | 902 + libs/openssl/crypto/cms/cms_smime.c | 796 + libs/openssl/crypto/comp/c_rle.c | 62 + libs/openssl/crypto/comp/c_zlib.c | 763 + libs/openssl/crypto/comp/comp.h | 83 + libs/openssl/crypto/comp/comp_err.c | 98 + libs/openssl/crypto/comp/comp_lib.c | 66 + libs/openssl/crypto/conf/README | 73 + libs/openssl/crypto/conf/cnf_save.c | 104 + libs/openssl/crypto/conf/conf.h | 267 + libs/openssl/crypto/conf/conf_api.c | 305 + libs/openssl/crypto/conf/conf_api.h | 89 + libs/openssl/crypto/conf/conf_def.c | 706 + libs/openssl/crypto/conf/conf_def.h | 181 + libs/openssl/crypto/conf/conf_err.c | 133 + libs/openssl/crypto/conf/conf_lib.c | 391 + libs/openssl/crypto/conf/conf_mall.c | 81 + libs/openssl/crypto/conf/conf_mod.c | 597 + libs/openssl/crypto/conf/conf_sap.c | 99 + libs/openssl/crypto/conf/keysets.pl | 185 + libs/openssl/crypto/conf/ssleay.cnf | 78 + libs/openssl/crypto/conf/test.c | 97 + libs/openssl/crypto/constant_time_locl.h | 211 + libs/openssl/crypto/constant_time_test.c | 304 + libs/openssl/crypto/cpt_err.c | 104 + libs/openssl/crypto/cryptlib.c | 1005 + libs/openssl/crypto/cryptlib.h | 111 + libs/openssl/crypto/crypto-lib.com | 1537 ++ libs/openssl/crypto/crypto.h | 661 + libs/openssl/crypto/cversion.c | 103 + libs/openssl/crypto/des/COPYRIGHT | 50 + libs/openssl/crypto/des/DES.pm | 19 + libs/openssl/crypto/des/DES.xs | 268 + libs/openssl/crypto/des/FILES0 | 96 + libs/openssl/crypto/des/INSTALL | 69 + libs/openssl/crypto/des/Imakefile | 35 + libs/openssl/crypto/des/KERBEROS | 41 + libs/openssl/crypto/des/README | 54 + libs/openssl/crypto/des/VERSION | 412 + libs/openssl/crypto/des/asm/crypt586.pl | 209 + libs/openssl/crypto/des/asm/des-586.pl | 453 + libs/openssl/crypto/des/asm/des_enc.m4 | 2099 +++ libs/openssl/crypto/des/asm/desboth.pl | 79 + libs/openssl/crypto/des/asm/readme | 131 + libs/openssl/crypto/des/cbc3_enc.c | 95 + libs/openssl/crypto/des/cbc_cksm.c | 103 + libs/openssl/crypto/des/cbc_enc.c | 61 + libs/openssl/crypto/des/cfb64ede.c | 249 + libs/openssl/crypto/des/cfb64enc.c | 122 + libs/openssl/crypto/des/cfb_enc.c | 199 + libs/openssl/crypto/des/des-lib.com | 1005 + libs/openssl/crypto/des/des.c | 868 + libs/openssl/crypto/des/des.h | 257 + libs/openssl/crypto/des/des.pod | 217 + libs/openssl/crypto/des/des3s.cpp | 67 + libs/openssl/crypto/des/des_enc.c | 389 + libs/openssl/crypto/des/des_locl.h | 441 + libs/openssl/crypto/des/des_old.c | 345 + libs/openssl/crypto/des/des_old.h | 497 + libs/openssl/crypto/des/des_old2.c | 80 + libs/openssl/crypto/des/des_opts.c | 641 + libs/openssl/crypto/des/des_ver.h | 73 + libs/openssl/crypto/des/dess.cpp | 67 + libs/openssl/crypto/des/destest.c | 929 + libs/openssl/crypto/des/ecb3_enc.c | 82 + libs/openssl/crypto/des/ecb_enc.c | 124 + libs/openssl/crypto/des/ede_cbcm_enc.c | 189 + libs/openssl/crypto/des/enc_read.c | 235 + libs/openssl/crypto/des/enc_writ.c | 182 + libs/openssl/crypto/des/fcrypt.c | 167 + libs/openssl/crypto/des/fcrypt_b.c | 140 + libs/openssl/crypto/des/makefile.bc | 50 + libs/openssl/crypto/des/ncbc_enc.c | 154 + libs/openssl/crypto/des/ofb64ede.c | 123 + libs/openssl/crypto/des/ofb64enc.c | 109 + libs/openssl/crypto/des/ofb_enc.c | 131 + libs/openssl/crypto/des/options.txt | 39 + libs/openssl/crypto/des/pcbc_enc.c | 115 + libs/openssl/crypto/des/qud_cksm.c | 143 + libs/openssl/crypto/des/rand_key.c | 67 + libs/openssl/crypto/des/read2pwd.c | 140 + libs/openssl/crypto/des/read_pwd.c | 533 + libs/openssl/crypto/des/rpc_des.h | 130 + libs/openssl/crypto/des/rpc_enc.c | 100 + libs/openssl/crypto/des/rpw.c | 94 + libs/openssl/crypto/des/set_key.c | 447 + libs/openssl/crypto/des/speed.c | 299 + libs/openssl/crypto/des/spr.h | 212 + libs/openssl/crypto/des/str2key.c | 164 + libs/openssl/crypto/des/times/486-50.sol | 16 + libs/openssl/crypto/des/times/586-100.lnx | 20 + libs/openssl/crypto/des/times/686-200.fre | 18 + libs/openssl/crypto/des/times/aix.cc | 26 + libs/openssl/crypto/des/times/alpha.cc | 18 + libs/openssl/crypto/des/times/hpux.cc | 17 + libs/openssl/crypto/des/times/sparc.gcc | 17 + libs/openssl/crypto/des/times/usparc.cc | 31 + libs/openssl/crypto/des/typemap | 34 + libs/openssl/crypto/des/xcbc_enc.c | 216 + libs/openssl/crypto/dh/dh.h | 287 + libs/openssl/crypto/dh/dh1024.pem | 5 + libs/openssl/crypto/dh/dh192.pem | 3 + libs/openssl/crypto/dh/dh2048.pem | 16 + libs/openssl/crypto/dh/dh4096.pem | 14 + libs/openssl/crypto/dh/dh512.pem | 4 + libs/openssl/crypto/dh/dh_ameth.c | 492 + libs/openssl/crypto/dh/dh_asn1.c | 95 + libs/openssl/crypto/dh/dh_check.c | 147 + libs/openssl/crypto/dh/dh_depr.c | 82 + libs/openssl/crypto/dh/dh_err.c | 120 + libs/openssl/crypto/dh/dh_gen.c | 204 + libs/openssl/crypto/dh/dh_key.c | 275 + libs/openssl/crypto/dh/dh_lib.c | 263 + libs/openssl/crypto/dh/dh_pmeth.c | 245 + libs/openssl/crypto/dh/dh_prn.c | 79 + libs/openssl/crypto/dh/dhtest.c | 241 + libs/openssl/crypto/dh/example | 50 + libs/openssl/crypto/dh/generate | 65 + libs/openssl/crypto/dh/p1024.c | 92 + libs/openssl/crypto/dh/p192.c | 80 + libs/openssl/crypto/dh/p512.c | 85 + libs/openssl/crypto/dsa/README | 4 + libs/openssl/crypto/dsa/dsa.h | 329 + libs/openssl/crypto/dsa/dsa_ameth.c | 674 + libs/openssl/crypto/dsa/dsa_asn1.c | 202 + libs/openssl/crypto/dsa/dsa_depr.c | 113 + libs/openssl/crypto/dsa/dsa_err.c | 130 + libs/openssl/crypto/dsa/dsa_gen.c | 379 + libs/openssl/crypto/dsa/dsa_key.c | 145 + libs/openssl/crypto/dsa/dsa_lib.c | 329 + libs/openssl/crypto/dsa/dsa_locl.h | 61 + libs/openssl/crypto/dsa/dsa_ossl.c | 426 + libs/openssl/crypto/dsa/dsa_pmeth.c | 308 + libs/openssl/crypto/dsa/dsa_prn.c | 119 + libs/openssl/crypto/dsa/dsa_sign.c | 110 + libs/openssl/crypto/dsa/dsa_vrf.c | 75 + libs/openssl/crypto/dsa/dsagen.c | 115 + libs/openssl/crypto/dsa/dsatest.c | 268 + libs/openssl/crypto/dsa/fips186a.txt | 122 + libs/openssl/crypto/dso/README | 22 + libs/openssl/crypto/dso/dso.h | 451 + libs/openssl/crypto/dso/dso_beos.c | 253 + libs/openssl/crypto/dso/dso_dl.c | 380 + libs/openssl/crypto/dso/dso_dlfcn.c | 465 + libs/openssl/crypto/dso/dso_err.c | 158 + libs/openssl/crypto/dso/dso_lib.c | 447 + libs/openssl/crypto/dso/dso_null.c | 92 + libs/openssl/crypto/dso/dso_openssl.c | 83 + libs/openssl/crypto/dso/dso_vms.c | 547 + libs/openssl/crypto/dso/dso_win32.c | 785 + libs/openssl/crypto/ebcdic.c | 284 + libs/openssl/crypto/ebcdic.h | 26 + libs/openssl/crypto/ec/ec.h | 1193 ++ libs/openssl/crypto/ec/ec2_mult.c | 463 + libs/openssl/crypto/ec/ec2_oct.c | 403 + libs/openssl/crypto/ec/ec2_smpl.c | 797 + libs/openssl/crypto/ec/ec_ameth.c | 627 + libs/openssl/crypto/ec/ec_asn1.c | 1326 ++ libs/openssl/crypto/ec/ec_check.c | 120 + libs/openssl/crypto/ec/ec_curve.c | 2615 +++ libs/openssl/crypto/ec/ec_cvt.c | 168 + libs/openssl/crypto/ec/ec_err.c | 319 + libs/openssl/crypto/ec/ec_key.c | 563 + libs/openssl/crypto/ec/ec_lcl.h | 543 + libs/openssl/crypto/ec/ec_lib.c | 1059 ++ libs/openssl/crypto/ec/ec_mult.c | 913 + libs/openssl/crypto/ec/ec_oct.c | 192 + libs/openssl/crypto/ec/ec_pmeth.c | 332 + libs/openssl/crypto/ec/ec_print.c | 179 + libs/openssl/crypto/ec/eck_prn.c | 369 + libs/openssl/crypto/ec/ecp_mont.c | 308 + libs/openssl/crypto/ec/ecp_nist.c | 220 + libs/openssl/crypto/ec/ecp_nistp224.c | 1769 ++ libs/openssl/crypto/ec/ecp_nistp256.c | 2369 +++ libs/openssl/crypto/ec/ecp_nistp521.c | 2148 +++ libs/openssl/crypto/ec/ecp_nistputil.c | 218 + libs/openssl/crypto/ec/ecp_oct.c | 428 + libs/openssl/crypto/ec/ecp_smpl.c | 1418 ++ libs/openssl/crypto/ec/ectest.c | 1861 ++ libs/openssl/crypto/ecdh/ecdh.h | 127 + libs/openssl/crypto/ecdh/ecdhtest.c | 410 + libs/openssl/crypto/ecdh/ech_err.c | 98 + libs/openssl/crypto/ecdh/ech_key.c | 81 + libs/openssl/crypto/ecdh/ech_lib.c | 265 + libs/openssl/crypto/ecdh/ech_locl.h | 104 + libs/openssl/crypto/ecdh/ech_ossl.c | 208 + libs/openssl/crypto/ecdsa/ecdsa.h | 260 + libs/openssl/crypto/ecdsa/ecdsatest.c | 556 + libs/openssl/crypto/ecdsa/ecs_asn1.c | 67 + libs/openssl/crypto/ecdsa/ecs_err.c | 106 + libs/openssl/crypto/ecdsa/ecs_lib.c | 277 + libs/openssl/crypto/ecdsa/ecs_locl.h | 116 + libs/openssl/crypto/ecdsa/ecs_ossl.c | 442 + libs/openssl/crypto/ecdsa/ecs_sign.c | 106 + libs/openssl/crypto/ecdsa/ecs_vrf.c | 112 + libs/openssl/crypto/engine/README | 211 + libs/openssl/crypto/engine/eng_all.c | 139 + libs/openssl/crypto/engine/eng_cnf.c | 242 + libs/openssl/crypto/engine/eng_cryptodev.c | 1473 ++ libs/openssl/crypto/engine/eng_ctrl.c | 385 + libs/openssl/crypto/engine/eng_dyn.c | 568 + libs/openssl/crypto/engine/eng_err.c | 181 + libs/openssl/crypto/engine/eng_fat.c | 181 + libs/openssl/crypto/engine/eng_init.c | 157 + libs/openssl/crypto/engine/eng_int.h | 224 + libs/openssl/crypto/engine/eng_lib.c | 347 + libs/openssl/crypto/engine/eng_list.c | 405 + libs/openssl/crypto/engine/eng_openssl.c | 402 + libs/openssl/crypto/engine/eng_pkey.c | 186 + libs/openssl/crypto/engine/eng_rdrand.c | 149 + libs/openssl/crypto/engine/eng_rsax.c | 701 + libs/openssl/crypto/engine/eng_table.c | 358 + libs/openssl/crypto/engine/engine.h | 961 + libs/openssl/crypto/engine/enginetest.c | 269 + libs/openssl/crypto/engine/tb_asnmth.c | 246 + libs/openssl/crypto/engine/tb_cipher.c | 143 + libs/openssl/crypto/engine/tb_dh.c | 124 + libs/openssl/crypto/engine/tb_digest.c | 143 + libs/openssl/crypto/engine/tb_dsa.c | 124 + libs/openssl/crypto/engine/tb_ecdh.c | 139 + libs/openssl/crypto/engine/tb_ecdsa.c | 124 + libs/openssl/crypto/engine/tb_pkmeth.c | 166 + libs/openssl/crypto/engine/tb_rand.c | 124 + libs/openssl/crypto/engine/tb_rsa.c | 124 + libs/openssl/crypto/engine/tb_store.c | 129 + libs/openssl/crypto/err/err.c | 1145 ++ libs/openssl/crypto/err/err.h | 389 + libs/openssl/crypto/err/err_all.c | 168 + libs/openssl/crypto/err/err_prn.c | 113 + libs/openssl/crypto/err/openssl.ec | 97 + libs/openssl/crypto/evp/bio_b64.c | 573 + libs/openssl/crypto/evp/bio_enc.c | 428 + libs/openssl/crypto/evp/bio_md.c | 272 + libs/openssl/crypto/evp/bio_ok.c | 624 + libs/openssl/crypto/evp/c_all.c | 90 + libs/openssl/crypto/evp/c_allc.c | 230 + libs/openssl/crypto/evp/c_alld.c | 114 + libs/openssl/crypto/evp/digest.c | 396 + libs/openssl/crypto/evp/e_aes.c | 1286 ++ libs/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c | 602 + libs/openssl/crypto/evp/e_bf.c | 87 + libs/openssl/crypto/evp/e_camellia.c | 119 + libs/openssl/crypto/evp/e_cast.c | 89 + libs/openssl/crypto/evp/e_des.c | 223 + libs/openssl/crypto/evp/e_des3.c | 319 + libs/openssl/crypto/evp/e_dsa.c | 69 + libs/openssl/crypto/evp/e_idea.c | 119 + libs/openssl/crypto/evp/e_null.c | 103 + libs/openssl/crypto/evp/e_old.c | 164 + libs/openssl/crypto/evp/e_rc2.c | 235 + libs/openssl/crypto/evp/e_rc4.c | 133 + libs/openssl/crypto/evp/e_rc4_hmac_md5.c | 308 + libs/openssl/crypto/evp/e_rc5.c | 122 + libs/openssl/crypto/evp/e_seed.c | 82 + libs/openssl/crypto/evp/e_xcbc_d.c | 130 + libs/openssl/crypto/evp/encode.c | 460 + libs/openssl/crypto/evp/evp.h | 1480 ++ libs/openssl/crypto/evp/evp_acnf.c | 73 + libs/openssl/crypto/evp/evp_cnf.c | 118 + libs/openssl/crypto/evp/evp_enc.c | 653 + libs/openssl/crypto/evp/evp_err.c | 251 + libs/openssl/crypto/evp/evp_extra_test.c | 489 + libs/openssl/crypto/evp/evp_fips.c | 310 + libs/openssl/crypto/evp/evp_key.c | 195 + libs/openssl/crypto/evp/evp_lib.c | 336 + libs/openssl/crypto/evp/evp_locl.h | 370 + libs/openssl/crypto/evp/evp_pbe.c | 312 + libs/openssl/crypto/evp/evp_pkey.c | 229 + libs/openssl/crypto/evp/evp_test.c | 424 + libs/openssl/crypto/evp/evptests.txt | 334 + libs/openssl/crypto/evp/m_dss.c | 106 + libs/openssl/crypto/evp/m_dss1.c | 108 + libs/openssl/crypto/evp/m_ecdsa.c | 156 + libs/openssl/crypto/evp/m_md2.c | 106 + libs/openssl/crypto/evp/m_md4.c | 108 + libs/openssl/crypto/evp/m_md5.c | 107 + libs/openssl/crypto/evp/m_mdc2.c | 108 + libs/openssl/crypto/evp/m_null.c | 98 + libs/openssl/crypto/evp/m_ripemd.c | 107 + libs/openssl/crypto/evp/m_sha.c | 106 + libs/openssl/crypto/evp/m_sha1.c | 239 + libs/openssl/crypto/evp/m_sigver.c | 187 + libs/openssl/crypto/evp/m_wp.c | 48 + libs/openssl/crypto/evp/names.c | 215 + libs/openssl/crypto/evp/openbsd_hw.c | 431 + libs/openssl/crypto/evp/p5_crpt.c | 149 + libs/openssl/crypto/evp/p5_crpt2.c | 334 + libs/openssl/crypto/evp/p_dec.c | 87 + libs/openssl/crypto/evp/p_enc.c | 87 + libs/openssl/crypto/evp/p_lib.c | 456 + libs/openssl/crypto/evp/p_open.c | 129 + libs/openssl/crypto/evp/p_seal.c | 121 + libs/openssl/crypto/evp/p_sign.c | 133 + libs/openssl/crypto/evp/p_verify.c | 116 + libs/openssl/crypto/evp/pmeth_fn.c | 346 + libs/openssl/crypto/evp/pmeth_gn.c | 220 + libs/openssl/crypto/evp/pmeth_lib.c | 609 + libs/openssl/crypto/ex_data.c | 646 + libs/openssl/crypto/fips_err.h | 223 + libs/openssl/crypto/fips_ers.c | 7 + libs/openssl/crypto/hmac/hm_ameth.c | 167 + libs/openssl/crypto/hmac/hm_pmeth.c | 262 + libs/openssl/crypto/hmac/hmac.c | 258 + libs/openssl/crypto/hmac/hmac.h | 109 + libs/openssl/crypto/hmac/hmactest.c | 332 + libs/openssl/crypto/ia64cpuid.S | 167 + libs/openssl/crypto/idea/i_cbc.c | 171 + libs/openssl/crypto/idea/i_cfb64.c | 123 + libs/openssl/crypto/idea/i_ecb.c | 88 + libs/openssl/crypto/idea/i_ofb64.c | 110 + libs/openssl/crypto/idea/i_skey.c | 171 + libs/openssl/crypto/idea/idea.h | 105 + libs/openssl/crypto/idea/idea_lcl.h | 216 + libs/openssl/crypto/idea/idea_spd.c | 283 + libs/openssl/crypto/idea/ideatest.c | 232 + libs/openssl/crypto/idea/version | 12 + libs/openssl/crypto/install-crypto.com | 199 + libs/openssl/crypto/jpake/jpake.c | 511 + libs/openssl/crypto/jpake/jpake.h | 128 + libs/openssl/crypto/jpake/jpake_err.c | 108 + libs/openssl/crypto/jpake/jpaketest.c | 185 + libs/openssl/crypto/krb5/krb5_asn.c | 162 + libs/openssl/crypto/krb5/krb5_asn.h | 240 + libs/openssl/crypto/lhash/lh_stats.c | 246 + libs/openssl/crypto/lhash/lh_test.c | 88 + libs/openssl/crypto/lhash/lhash.c | 458 + libs/openssl/crypto/lhash/lhash.h | 240 + libs/openssl/crypto/lhash/num.pl | 17 + libs/openssl/crypto/md2/md2.c | 119 + libs/openssl/crypto/md2/md2.h | 94 + libs/openssl/crypto/md2/md2_dgst.c | 224 + libs/openssl/crypto/md2/md2_one.c | 96 + libs/openssl/crypto/md2/md2test.c | 142 + libs/openssl/crypto/md32_common.h | 410 + libs/openssl/crypto/md4/md4.c | 121 + libs/openssl/crypto/md4/md4.h | 119 + libs/openssl/crypto/md4/md4_dgst.c | 199 + libs/openssl/crypto/md4/md4_locl.h | 113 + libs/openssl/crypto/md4/md4_one.c | 96 + libs/openssl/crypto/md4/md4s.cpp | 78 + libs/openssl/crypto/md4/md4test.c | 133 + libs/openssl/crypto/md5/asm/md5-586.pl | 307 + libs/openssl/crypto/md5/asm/md5-ia64.S | 992 + libs/openssl/crypto/md5/asm/md5-x86_64.pl | 370 + libs/openssl/crypto/md5/md5.c | 121 + libs/openssl/crypto/md5/md5.h | 119 + libs/openssl/crypto/md5/md5_dgst.c | 216 + libs/openssl/crypto/md5/md5_locl.h | 131 + libs/openssl/crypto/md5/md5_one.c | 96 + libs/openssl/crypto/md5/md5s.cpp | 78 + libs/openssl/crypto/md5/md5test.c | 138 + libs/openssl/crypto/mdc2/mdc2.h | 94 + libs/openssl/crypto/mdc2/mdc2_one.c | 76 + libs/openssl/crypto/mdc2/mdc2dgst.c | 196 + libs/openssl/crypto/mdc2/mdc2test.c | 146 + libs/openssl/crypto/mem.c | 466 + libs/openssl/crypto/mem_clr.c | 81 + libs/openssl/crypto/mem_dbg.c | 830 + libs/openssl/crypto/modes/asm/ghash-alpha.pl | 460 + libs/openssl/crypto/modes/asm/ghash-armv4.pl | 429 + libs/openssl/crypto/modes/asm/ghash-ia64.pl | 463 + libs/openssl/crypto/modes/asm/ghash-parisc.pl | 731 + libs/openssl/crypto/modes/asm/ghash-s390x.pl | 262 + .../openssl/crypto/modes/asm/ghash-sparcv9.pl | 330 + libs/openssl/crypto/modes/asm/ghash-x86.pl | 1342 ++ libs/openssl/crypto/modes/asm/ghash-x86_64.pl | 806 + libs/openssl/crypto/modes/cbc128.c | 207 + libs/openssl/crypto/modes/ccm128.c | 479 + libs/openssl/crypto/modes/cfb128.c | 254 + libs/openssl/crypto/modes/ctr128.c | 263 + libs/openssl/crypto/modes/cts128.c | 544 + libs/openssl/crypto/modes/gcm128.c | 2289 +++ libs/openssl/crypto/modes/modes.h | 153 + libs/openssl/crypto/modes/modes_lcl.h | 133 + libs/openssl/crypto/modes/ofb128.c | 124 + libs/openssl/crypto/modes/xts128.c | 204 + libs/openssl/crypto/o_dir.c | 86 + libs/openssl/crypto/o_dir.h | 55 + libs/openssl/crypto/o_dir_test.c | 68 + libs/openssl/crypto/o_fips.c | 96 + libs/openssl/crypto/o_init.c | 83 + libs/openssl/crypto/o_str.c | 116 + libs/openssl/crypto/o_str.h | 69 + libs/openssl/crypto/o_time.c | 380 + libs/openssl/crypto/o_time.h | 68 + libs/openssl/crypto/objects/o_names.c | 366 + libs/openssl/crypto/objects/obj_dat.c | 801 + libs/openssl/crypto/objects/obj_dat.h | 5095 +++++ libs/openssl/crypto/objects/obj_dat.pl | 307 + libs/openssl/crypto/objects/obj_err.c | 100 + libs/openssl/crypto/objects/obj_lib.c | 135 + libs/openssl/crypto/objects/obj_mac.h | 4031 ++++ libs/openssl/crypto/objects/obj_mac.num | 919 + libs/openssl/crypto/objects/obj_xref.c | 222 + libs/openssl/crypto/objects/obj_xref.h | 74 + libs/openssl/crypto/objects/obj_xref.txt | 46 + libs/openssl/crypto/objects/objects.README | 44 + libs/openssl/crypto/objects/objects.h | 1143 ++ libs/openssl/crypto/objects/objects.pl | 240 + libs/openssl/crypto/objects/objects.txt | 1292 ++ libs/openssl/crypto/objects/objxref.pl | 115 + libs/openssl/crypto/ocsp/ocsp.h | 626 + libs/openssl/crypto/ocsp/ocsp_asn.c | 183 + libs/openssl/crypto/ocsp/ocsp_cl.c | 383 + libs/openssl/crypto/ocsp/ocsp_err.c | 149 + libs/openssl/crypto/ocsp/ocsp_ext.c | 566 + libs/openssl/crypto/ocsp/ocsp_ht.c | 476 + libs/openssl/crypto/ocsp/ocsp_lib.c | 284 + libs/openssl/crypto/ocsp/ocsp_prn.c | 299 + libs/openssl/crypto/ocsp/ocsp_srv.c | 271 + libs/openssl/crypto/ocsp/ocsp_vfy.c | 454 + libs/openssl/crypto/opensslconf.h | 253 + libs/openssl/crypto/opensslconf.h.in | 154 + libs/openssl/crypto/opensslv.h | 97 + libs/openssl/crypto/ossl_typ.h | 209 + libs/openssl/crypto/pariscid.pl | 225 + libs/openssl/crypto/pem/message | 16 + libs/openssl/crypto/pem/pem.h | 611 + libs/openssl/crypto/pem/pem2.h | 70 + libs/openssl/crypto/pem/pem_all.c | 426 + libs/openssl/crypto/pem/pem_err.c | 166 + libs/openssl/crypto/pem/pem_info.c | 394 + libs/openssl/crypto/pem/pem_lib.c | 860 + libs/openssl/crypto/pem/pem_oth.c | 86 + libs/openssl/crypto/pem/pem_pk8.c | 259 + libs/openssl/crypto/pem/pem_pkey.c | 243 + libs/openssl/crypto/pem/pem_seal.c | 191 + libs/openssl/crypto/pem/pem_sign.c | 101 + libs/openssl/crypto/pem/pem_x509.c | 68 + libs/openssl/crypto/pem/pem_xaux.c | 70 + libs/openssl/crypto/pem/pkcs7.lis | 22 + libs/openssl/crypto/pem/pvkfmt.c | 888 + libs/openssl/crypto/perlasm/cbc.pl | 349 + libs/openssl/crypto/perlasm/ppc-xlate.pl | 159 + libs/openssl/crypto/perlasm/readme | 124 + libs/openssl/crypto/perlasm/x86_64-xlate.pl | 1080 ++ libs/openssl/crypto/perlasm/x86asm.pl | 260 + libs/openssl/crypto/perlasm/x86gas.pl | 253 + libs/openssl/crypto/perlasm/x86masm.pl | 198 + libs/openssl/crypto/perlasm/x86nasm.pl | 177 + libs/openssl/crypto/pkcs12/p12_add.c | 258 + libs/openssl/crypto/pkcs12/p12_asn.c | 125 + libs/openssl/crypto/pkcs12/p12_attr.c | 147 + libs/openssl/crypto/pkcs12/p12_crpt.c | 119 + libs/openssl/crypto/pkcs12/p12_crt.c | 358 + libs/openssl/crypto/pkcs12/p12_decr.c | 198 + libs/openssl/crypto/pkcs12/p12_init.c | 92 + libs/openssl/crypto/pkcs12/p12_key.c | 238 + libs/openssl/crypto/pkcs12/p12_kiss.c | 299 + libs/openssl/crypto/pkcs12/p12_mutl.c | 195 + libs/openssl/crypto/pkcs12/p12_npas.c | 235 + libs/openssl/crypto/pkcs12/p12_p8d.c | 70 + libs/openssl/crypto/pkcs12/p12_p8e.c | 101 + libs/openssl/crypto/pkcs12/p12_utl.c | 161 + libs/openssl/crypto/pkcs12/pk12err.c | 149 + libs/openssl/crypto/pkcs12/pkcs12.h | 342 + libs/openssl/crypto/pkcs7/bio_pk7.c | 70 + libs/openssl/crypto/pkcs7/pk7_asn1.c | 251 + libs/openssl/crypto/pkcs7/pk7_attr.c | 165 + libs/openssl/crypto/pkcs7/pk7_dgst.c | 65 + libs/openssl/crypto/pkcs7/pk7_doit.c | 1295 ++ libs/openssl/crypto/pkcs7/pk7_enc.c | 75 + libs/openssl/crypto/pkcs7/pk7_lib.c | 646 + libs/openssl/crypto/pkcs7/pk7_mime.c | 96 + libs/openssl/crypto/pkcs7/pk7_smime.c | 586 + libs/openssl/crypto/pkcs7/pkcs7.h | 481 + libs/openssl/crypto/pkcs7/pkcs7err.c | 207 + libs/openssl/crypto/ppccap.c | 129 + libs/openssl/crypto/ppccpuid.pl | 132 + libs/openssl/crypto/pqueue/pq_test.c | 94 + libs/openssl/crypto/pqueue/pqueue.c | 235 + libs/openssl/crypto/pqueue/pqueue.h | 99 + libs/openssl/crypto/rand/md_rand.c | 592 + libs/openssl/crypto/rand/rand.h | 150 + libs/openssl/crypto/rand/rand_egd.c | 292 + libs/openssl/crypto/rand/rand_err.c | 100 + libs/openssl/crypto/rand/rand_lcl.h | 158 + libs/openssl/crypto/rand/rand_lib.c | 300 + libs/openssl/crypto/rand/rand_nw.c | 179 + libs/openssl/crypto/rand/rand_os2.c | 170 + libs/openssl/crypto/rand/rand_unix.c | 447 + libs/openssl/crypto/rand/rand_vms.c | 159 + libs/openssl/crypto/rand/rand_win.c | 751 + libs/openssl/crypto/rand/randfile.c | 337 + libs/openssl/crypto/rand/randtest.c | 209 + libs/openssl/crypto/rc2/rc2.h | 103 + libs/openssl/crypto/rc2/rc2_cbc.c | 228 + libs/openssl/crypto/rc2/rc2_ecb.c | 92 + libs/openssl/crypto/rc2/rc2_locl.h | 155 + libs/openssl/crypto/rc2/rc2_skey.c | 157 + libs/openssl/crypto/rc2/rc2cfb64.c | 123 + libs/openssl/crypto/rc2/rc2ofb64.c | 110 + libs/openssl/crypto/rc2/rc2speed.c | 262 + libs/openssl/crypto/rc2/rc2test.c | 274 + libs/openssl/crypto/rc2/rrc2.doc | 219 + libs/openssl/crypto/rc2/tab.c | 84 + libs/openssl/crypto/rc2/version | 22 + libs/openssl/crypto/rc4/asm/rc4-586.pl | 410 + libs/openssl/crypto/rc4/asm/rc4-ia64.pl | 755 + libs/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl | 632 + libs/openssl/crypto/rc4/asm/rc4-parisc.pl | 314 + libs/openssl/crypto/rc4/asm/rc4-s390x.pl | 234 + libs/openssl/crypto/rc4/asm/rc4-x86_64.pl | 677 + libs/openssl/crypto/rc4/rc4.c | 179 + libs/openssl/crypto/rc4/rc4.h | 88 + libs/openssl/crypto/rc4/rc4_enc.c | 334 + libs/openssl/crypto/rc4/rc4_locl.h | 5 + libs/openssl/crypto/rc4/rc4_skey.c | 116 + libs/openssl/crypto/rc4/rc4_utl.c | 62 + libs/openssl/crypto/rc4/rc4s.cpp | 73 + libs/openssl/crypto/rc4/rc4speed.c | 239 + libs/openssl/crypto/rc4/rc4test.c | 235 + libs/openssl/crypto/rc4/rrc4.doc | 278 + libs/openssl/crypto/rc5/asm/rc5-586.pl | 110 + libs/openssl/crypto/rc5/rc5.h | 115 + libs/openssl/crypto/rc5/rc5_ecb.c | 83 + libs/openssl/crypto/rc5/rc5_enc.c | 209 + libs/openssl/crypto/rc5/rc5_locl.h | 204 + libs/openssl/crypto/rc5/rc5_skey.c | 110 + libs/openssl/crypto/rc5/rc5cfb64.c | 123 + libs/openssl/crypto/rc5/rc5ofb64.c | 110 + libs/openssl/crypto/rc5/rc5s.cpp | 70 + libs/openssl/crypto/rc5/rc5speed.c | 265 + libs/openssl/crypto/rc5/rc5test.c | 381 + libs/openssl/crypto/ripemd/README | 15 + libs/openssl/crypto/ripemd/asm/rips.cpp | 82 + libs/openssl/crypto/ripemd/asm/rmd-586.pl | 591 + libs/openssl/crypto/ripemd/ripemd.h | 105 + libs/openssl/crypto/ripemd/rmd160.c | 121 + libs/openssl/crypto/ripemd/rmd_dgst.c | 334 + libs/openssl/crypto/ripemd/rmd_locl.h | 149 + libs/openssl/crypto/ripemd/rmd_one.c | 77 + libs/openssl/crypto/ripemd/rmdconst.h | 398 + libs/openssl/crypto/ripemd/rmdtest.c | 143 + libs/openssl/crypto/rsa/rsa.h | 610 + libs/openssl/crypto/rsa/rsa_ameth.c | 649 + libs/openssl/crypto/rsa/rsa_asn1.c | 123 + libs/openssl/crypto/rsa/rsa_chk.c | 214 + libs/openssl/crypto/rsa/rsa_crpt.c | 247 + libs/openssl/crypto/rsa/rsa_depr.c | 107 + libs/openssl/crypto/rsa/rsa_eay.c | 904 + libs/openssl/crypto/rsa/rsa_err.c | 231 + libs/openssl/crypto/rsa/rsa_gen.c | 250 + libs/openssl/crypto/rsa/rsa_lib.c | 336 + libs/openssl/crypto/rsa/rsa_locl.h | 4 + libs/openssl/crypto/rsa/rsa_none.c | 94 + libs/openssl/crypto/rsa/rsa_null.c | 155 + libs/openssl/crypto/rsa/rsa_oaep.c | 257 + libs/openssl/crypto/rsa/rsa_pk1.c | 275 + libs/openssl/crypto/rsa/rsa_pmeth.c | 665 + libs/openssl/crypto/rsa/rsa_prn.c | 92 + libs/openssl/crypto/rsa/rsa_pss.c | 290 + libs/openssl/crypto/rsa/rsa_saos.c | 148 + libs/openssl/crypto/rsa/rsa_sign.c | 312 + libs/openssl/crypto/rsa/rsa_ssl.c | 149 + libs/openssl/crypto/rsa/rsa_test.c | 339 + libs/openssl/crypto/rsa/rsa_x931.c | 167 + libs/openssl/crypto/s390xcap.c | 41 + libs/openssl/crypto/s390xcpuid.S | 99 + libs/openssl/crypto/seed/seed.c | 711 + libs/openssl/crypto/seed/seed.h | 149 + libs/openssl/crypto/seed/seed_cbc.c | 65 + libs/openssl/crypto/seed/seed_cfb.c | 118 + libs/openssl/crypto/seed/seed_ecb.c | 61 + libs/openssl/crypto/seed/seed_locl.h | 115 + libs/openssl/crypto/seed/seed_ofb.c | 117 + libs/openssl/crypto/sha/asm/README | 1 + libs/openssl/crypto/sha/asm/sha1-586.pl | 1229 ++ libs/openssl/crypto/sha/asm/sha1-alpha.pl | 322 + .../crypto/sha/asm/sha1-armv4-large.pl | 248 + libs/openssl/crypto/sha/asm/sha1-ia64.pl | 305 + libs/openssl/crypto/sha/asm/sha1-mips.pl | 354 + libs/openssl/crypto/sha/asm/sha1-parisc.pl | 260 + libs/openssl/crypto/sha/asm/sha1-ppc.pl | 326 + libs/openssl/crypto/sha/asm/sha1-s390x.pl | 246 + libs/openssl/crypto/sha/asm/sha1-sparcv9.pl | 284 + libs/openssl/crypto/sha/asm/sha1-sparcv9a.pl | 601 + libs/openssl/crypto/sha/asm/sha1-thumb.pl | 259 + libs/openssl/crypto/sha/asm/sha1-x86_64.pl | 1261 ++ libs/openssl/crypto/sha/asm/sha256-586.pl | 249 + libs/openssl/crypto/sha/asm/sha256-armv4.pl | 211 + libs/openssl/crypto/sha/asm/sha512-586.pl | 644 + libs/openssl/crypto/sha/asm/sha512-armv4.pl | 582 + libs/openssl/crypto/sha/asm/sha512-ia64.pl | 672 + libs/openssl/crypto/sha/asm/sha512-mips.pl | 455 + libs/openssl/crypto/sha/asm/sha512-parisc.pl | 793 + libs/openssl/crypto/sha/asm/sha512-ppc.pl | 460 + libs/openssl/crypto/sha/asm/sha512-s390x.pl | 322 + libs/openssl/crypto/sha/asm/sha512-sparcv9.pl | 594 + libs/openssl/crypto/sha/asm/sha512-x86_64.pl | 451 + libs/openssl/crypto/sha/sha.c | 118 + libs/openssl/crypto/sha/sha.h | 214 + libs/openssl/crypto/sha/sha1.c | 121 + libs/openssl/crypto/sha/sha1_one.c | 79 + libs/openssl/crypto/sha/sha1dgst.c | 74 + libs/openssl/crypto/sha/sha1test.c | 174 + libs/openssl/crypto/sha/sha256.c | 387 + libs/openssl/crypto/sha/sha256t.c | 158 + libs/openssl/crypto/sha/sha512.c | 671 + libs/openssl/crypto/sha/sha512t.c | 196 + libs/openssl/crypto/sha/sha_dgst.c | 74 + libs/openssl/crypto/sha/sha_locl.h | 500 + libs/openssl/crypto/sha/sha_one.c | 79 + libs/openssl/crypto/sha/shatest.c | 174 + libs/openssl/crypto/sparccpuid.S | 402 + libs/openssl/crypto/sparcv9cap.c | 245 + libs/openssl/crypto/srp/srp.h | 179 + libs/openssl/crypto/srp/srp_grps.h | 528 + libs/openssl/crypto/srp/srp_lcl.h | 84 + libs/openssl/crypto/srp/srp_lib.c | 357 + libs/openssl/crypto/srp/srp_vfy.c | 705 + libs/openssl/crypto/srp/srptest.c | 154 + libs/openssl/crypto/stack/safestack.h | 2536 +++ libs/openssl/crypto/stack/stack.c | 350 + libs/openssl/crypto/stack/stack.h | 106 + libs/openssl/crypto/store/README | 95 + libs/openssl/crypto/store/store.h | 658 + libs/openssl/crypto/store/str_err.c | 258 + libs/openssl/crypto/store/str_lib.c | 1772 ++ libs/openssl/crypto/store/str_locl.h | 125 + libs/openssl/crypto/store/str_mem.c | 383 + libs/openssl/crypto/store/str_meth.c | 280 + libs/openssl/crypto/symhacks.h | 486 + libs/openssl/crypto/threads/README | 14 + libs/openssl/crypto/threads/mttest.c | 1211 ++ libs/openssl/crypto/threads/netware.bat | 79 + libs/openssl/crypto/threads/ptest.bat | 4 + libs/openssl/crypto/threads/pthreads-vms.com | 14 + libs/openssl/crypto/threads/th-lock.c | 389 + libs/openssl/crypto/threads/win32.bat | 4 + libs/openssl/crypto/ts/ts.h | 862 + libs/openssl/crypto/ts/ts_asn1.c | 326 + libs/openssl/crypto/ts/ts_conf.c | 491 + libs/openssl/crypto/ts/ts_err.c | 188 + libs/openssl/crypto/ts/ts_lib.c | 143 + libs/openssl/crypto/ts/ts_req_print.c | 104 + libs/openssl/crypto/ts/ts_req_utils.c | 232 + libs/openssl/crypto/ts/ts_rsp_print.c | 281 + libs/openssl/crypto/ts/ts_rsp_sign.c | 1025 + libs/openssl/crypto/ts/ts_rsp_utils.c | 396 + libs/openssl/crypto/ts/ts_rsp_verify.c | 737 + libs/openssl/crypto/ts/ts_verify_ctx.c | 162 + libs/openssl/crypto/txt_db/txt_db.c | 381 + libs/openssl/crypto/txt_db/txt_db.h | 112 + libs/openssl/crypto/ui/ui.h | 415 + libs/openssl/crypto/ui/ui_compat.c | 69 + libs/openssl/crypto/ui/ui_compat.h | 88 + libs/openssl/crypto/ui/ui_err.c | 111 + libs/openssl/crypto/ui/ui_lib.c | 870 + libs/openssl/crypto/ui/ui_locl.h | 145 + libs/openssl/crypto/ui/ui_openssl.c | 717 + libs/openssl/crypto/ui/ui_util.c | 93 + libs/openssl/crypto/uid.c | 88 + libs/openssl/crypto/vms_rms.h | 50 + libs/openssl/crypto/whrlpool/asm/wp-mmx.pl | 493 + libs/openssl/crypto/whrlpool/asm/wp-x86_64.pl | 590 + libs/openssl/crypto/whrlpool/whrlpool.h | 41 + libs/openssl/crypto/whrlpool/wp_block.c | 780 + libs/openssl/crypto/whrlpool/wp_dgst.c | 257 + libs/openssl/crypto/whrlpool/wp_locl.h | 3 + libs/openssl/crypto/whrlpool/wp_test.c | 241 + libs/openssl/crypto/x509/by_dir.c | 436 + libs/openssl/crypto/x509/by_file.c | 277 + libs/openssl/crypto/x509/verify_extra_test.c | 209 + libs/openssl/crypto/x509/x509.h | 1302 ++ libs/openssl/crypto/x509/x509_att.c | 384 + libs/openssl/crypto/x509/x509_cmp.c | 354 + libs/openssl/crypto/x509/x509_d2.c | 109 + libs/openssl/crypto/x509/x509_def.c | 92 + libs/openssl/crypto/x509/x509_err.c | 179 + libs/openssl/crypto/x509/x509_ext.c | 211 + libs/openssl/crypto/x509/x509_lu.c | 684 + libs/openssl/crypto/x509/x509_obj.c | 230 + libs/openssl/crypto/x509/x509_r2x.c | 113 + libs/openssl/crypto/x509/x509_req.c | 328 + libs/openssl/crypto/x509/x509_set.c | 147 + libs/openssl/crypto/x509/x509_trs.c | 310 + libs/openssl/crypto/x509/x509_txt.c | 191 + libs/openssl/crypto/x509/x509_v3.c | 284 + libs/openssl/crypto/x509/x509_vfy.c | 2230 +++ libs/openssl/crypto/x509/x509_vfy.h | 595 + libs/openssl/crypto/x509/x509_vpm.c | 433 + libs/openssl/crypto/x509/x509cset.c | 167 + libs/openssl/crypto/x509/x509name.c | 397 + libs/openssl/crypto/x509/x509rset.c | 85 + libs/openssl/crypto/x509/x509spki.c | 123 + libs/openssl/crypto/x509/x509type.c | 127 + libs/openssl/crypto/x509/x_all.c | 544 + libs/openssl/crypto/x509v3/ext_dat.h | 133 + libs/openssl/crypto/x509v3/pcy_cache.c | 269 + libs/openssl/crypto/x509v3/pcy_data.c | 129 + libs/openssl/crypto/x509v3/pcy_int.h | 217 + libs/openssl/crypto/x509v3/pcy_lib.c | 167 + libs/openssl/crypto/x509v3/pcy_map.c | 130 + libs/openssl/crypto/x509v3/pcy_node.c | 190 + libs/openssl/crypto/x509v3/pcy_tree.c | 831 + libs/openssl/crypto/x509v3/tabtest.c | 92 + libs/openssl/crypto/x509v3/v3_addr.c | 1344 ++ libs/openssl/crypto/x509v3/v3_akey.c | 205 + libs/openssl/crypto/x509v3/v3_akeya.c | 73 + libs/openssl/crypto/x509v3/v3_alt.c | 609 + libs/openssl/crypto/x509v3/v3_asid.c | 896 + libs/openssl/crypto/x509v3/v3_bcons.c | 132 + libs/openssl/crypto/x509v3/v3_bitst.c | 142 + libs/openssl/crypto/x509v3/v3_conf.c | 532 + libs/openssl/crypto/x509v3/v3_cpols.c | 491 + libs/openssl/crypto/x509v3/v3_crld.c | 562 + libs/openssl/crypto/x509v3/v3_enum.c | 100 + libs/openssl/crypto/x509v3/v3_extku.c | 149 + libs/openssl/crypto/x509v3/v3_genn.c | 250 + libs/openssl/crypto/x509v3/v3_ia5.c | 119 + libs/openssl/crypto/x509v3/v3_info.c | 210 + libs/openssl/crypto/x509v3/v3_int.c | 92 + libs/openssl/crypto/x509v3/v3_lib.c | 341 + libs/openssl/crypto/x509v3/v3_ncons.c | 479 + libs/openssl/crypto/x509v3/v3_ocsp.c | 312 + libs/openssl/crypto/x509v3/v3_pci.c | 317 + libs/openssl/crypto/x509v3/v3_pcia.c | 56 + libs/openssl/crypto/x509v3/v3_pcons.c | 139 + libs/openssl/crypto/x509v3/v3_pku.c | 114 + libs/openssl/crypto/x509v3/v3_pmaps.c | 156 + libs/openssl/crypto/x509v3/v3_prn.c | 259 + libs/openssl/crypto/x509v3/v3_purp.c | 836 + libs/openssl/crypto/x509v3/v3_skey.c | 150 + libs/openssl/crypto/x509v3/v3_sxnet.c | 273 + libs/openssl/crypto/x509v3/v3_utl.c | 919 + libs/openssl/crypto/x509v3/v3conf.c | 129 + libs/openssl/crypto/x509v3/v3err.c | 246 + libs/openssl/crypto/x509v3/v3prin.c | 99 + libs/openssl/crypto/x509v3/x509v3.h | 1015 + libs/openssl/crypto/x86_64cpuid.pl | 284 + libs/openssl/crypto/x86cpuid.pl | 358 + libs/openssl/e_os.h | 775 + libs/openssl/e_os2.h | 328 + libs/openssl/include/openssl/aes.h | 1 + libs/openssl/include/openssl/asn1.h | 1 + libs/openssl/include/openssl/asn1_mac.h | 1 + libs/openssl/include/openssl/asn1t.h | 1 + libs/openssl/include/openssl/bio.h | 1 + libs/openssl/include/openssl/blowfish.h | 1 + libs/openssl/include/openssl/bn.h | 1 + libs/openssl/include/openssl/buffer.h | 1 + libs/openssl/include/openssl/camellia.h | 1 + libs/openssl/include/openssl/cast.h | 1 + libs/openssl/include/openssl/cmac.h | 1 + libs/openssl/include/openssl/cms.h | 1 + libs/openssl/include/openssl/comp.h | 1 + libs/openssl/include/openssl/conf.h | 1 + libs/openssl/include/openssl/conf_api.h | 1 + libs/openssl/include/openssl/crypto.h | 1 + libs/openssl/include/openssl/des.h | 1 + libs/openssl/include/openssl/des_old.h | 1 + libs/openssl/include/openssl/dh.h | 1 + libs/openssl/include/openssl/dsa.h | 1 + libs/openssl/include/openssl/dso.h | 1 + libs/openssl/include/openssl/dtls1.h | 268 + libs/openssl/include/openssl/e_os2.h | 1 + libs/openssl/include/openssl/ebcdic.h | 1 + libs/openssl/include/openssl/ec.h | 1 + libs/openssl/include/openssl/ecdh.h | 1 + libs/openssl/include/openssl/ecdsa.h | 1 + libs/openssl/include/openssl/engine.h | 1 + libs/openssl/include/openssl/err.h | 1 + libs/openssl/include/openssl/evp.h | 1 + libs/openssl/include/openssl/hmac.h | 1 + libs/openssl/include/openssl/idea.h | 1 + libs/openssl/include/openssl/krb5_asn.h | 1 + libs/openssl/include/openssl/kssl.h | 197 + libs/openssl/include/openssl/kssl_lcl.h | 88 + libs/openssl/include/openssl/lhash.h | 1 + libs/openssl/include/openssl/md4.h | 1 + libs/openssl/include/openssl/md5.h | 1 + libs/openssl/include/openssl/mdc2.h | 1 + libs/openssl/include/openssl/modes.h | 1 + libs/openssl/include/openssl/obj_mac.h | 1 + libs/openssl/include/openssl/objects.h | 1 + libs/openssl/include/openssl/ocsp.h | 1 + libs/openssl/include/openssl/opensslconf.h | 1 + libs/openssl/include/openssl/opensslv.h | 1 + libs/openssl/include/openssl/ossl_typ.h | 1 + libs/openssl/include/openssl/pem.h | 1 + libs/openssl/include/openssl/pem2.h | 1 + libs/openssl/include/openssl/pkcs12.h | 1 + libs/openssl/include/openssl/pkcs7.h | 1 + libs/openssl/include/openssl/pqueue.h | 1 + libs/openssl/include/openssl/rand.h | 1 + libs/openssl/include/openssl/rc2.h | 1 + libs/openssl/include/openssl/rc4.h | 1 + libs/openssl/include/openssl/ripemd.h | 1 + libs/openssl/include/openssl/rsa.h | 1 + libs/openssl/include/openssl/safestack.h | 1 + libs/openssl/include/openssl/seed.h | 1 + libs/openssl/include/openssl/sha.h | 1 + libs/openssl/include/openssl/srp.h | 1 + libs/openssl/include/openssl/srtp.h | 148 + libs/openssl/include/openssl/ssl.h | 2770 +++ libs/openssl/include/openssl/ssl2.h | 265 + libs/openssl/include/openssl/ssl23.h | 84 + libs/openssl/include/openssl/ssl3.h | 732 + libs/openssl/include/openssl/ssl_locl.h | 1246 ++ libs/openssl/include/openssl/stack.h | 1 + libs/openssl/include/openssl/symhacks.h | 1 + libs/openssl/include/openssl/tls1.h | 785 + libs/openssl/include/openssl/ts.h | 1 + libs/openssl/include/openssl/txt_db.h | 1 + libs/openssl/include/openssl/ui.h | 1 + libs/openssl/include/openssl/ui_compat.h | 1 + libs/openssl/include/openssl/whrlpool.h | 1 + libs/openssl/include/openssl/x509.h | 1 + libs/openssl/include/openssl/x509_vfy.h | 1 + libs/openssl/include/openssl/x509v3.h | 1 + libs/openssl/ssl/bio_ssl.c | 591 + libs/openssl/ssl/d1_both.c | 1700 ++ libs/openssl/ssl/d1_clnt.c | 1713 ++ libs/openssl/ssl/d1_enc.c | 251 + libs/openssl/ssl/d1_lib.c | 511 + libs/openssl/ssl/d1_meth.c | 74 + libs/openssl/ssl/d1_pkt.c | 1905 ++ libs/openssl/ssl/d1_srtp.c | 449 + libs/openssl/ssl/d1_srvr.c | 1759 ++ libs/openssl/ssl/kssl.c | 2260 +++ libs/openssl/ssl/s23_clnt.c | 790 + libs/openssl/ssl/s23_lib.c | 185 + libs/openssl/ssl/s23_meth.c | 89 + libs/openssl/ssl/s23_pkt.c | 113 + libs/openssl/ssl/s23_srvr.c | 647 + libs/openssl/ssl/s2_clnt.c | 1094 ++ libs/openssl/ssl/s2_enc.c | 197 + libs/openssl/ssl/s2_lib.c | 573 + libs/openssl/ssl/s2_meth.c | 91 + libs/openssl/ssl/s2_pkt.c | 725 + libs/openssl/ssl/s2_srvr.c | 1171 ++ libs/openssl/ssl/s3_both.c | 818 + libs/openssl/ssl/s3_cbc.c | 820 + libs/openssl/ssl/s3_clnt.c | 3570 ++++ libs/openssl/ssl/s3_enc.c | 934 + libs/openssl/ssl/s3_lib.c | 4366 +++++ libs/openssl/ssl/s3_meth.c | 74 + libs/openssl/ssl/s3_pkt.c | 1576 ++ libs/openssl/ssl/s3_srvr.c | 3649 ++++ libs/openssl/ssl/ssl-lib.com | 1229 ++ libs/openssl/ssl/ssl_algs.c | 151 + libs/openssl/ssl/ssl_asn1.c | 636 + libs/openssl/ssl/ssl_cert.c | 799 + libs/openssl/ssl/ssl_ciph.c | 1911 ++ libs/openssl/ssl/ssl_err.c | 797 + libs/openssl/ssl/ssl_err2.c | 69 + libs/openssl/ssl/ssl_lib.c | 3325 ++++ libs/openssl/ssl/ssl_rsa.c | 749 + libs/openssl/ssl/ssl_sess.c | 1302 ++ libs/openssl/ssl/ssl_stat.c | 1078 ++ libs/openssl/ssl/ssl_txt.c | 260 + libs/openssl/ssl/ssl_utst.c | 72 + libs/openssl/ssl/t1_clnt.c | 88 + libs/openssl/ssl/t1_enc.c | 1343 ++ libs/openssl/ssl/t1_lib.c | 2706 +++ libs/openssl/ssl/t1_meth.c | 81 + libs/openssl/ssl/t1_reneg.c | 292 + libs/openssl/ssl/t1_srvr.c | 89 + libs/openssl/ssl/tls_srp.c | 542 + 1507 files changed, 611544 insertions(+) create mode 100644 libs/cyrussasl/AUTHORS create mode 100644 libs/cyrussasl/COPYING create mode 100644 libs/cyrussasl/ChangeLog create mode 100644 libs/cyrussasl/INSTALL create mode 100644 libs/cyrussasl/INSTALL.TXT create mode 100644 libs/cyrussasl/NEWS create mode 100644 libs/cyrussasl/README create mode 100644 libs/cyrussasl/include/sasl/Makefile.am create mode 100644 libs/cyrussasl/include/sasl/NTMakefile create mode 100644 libs/cyrussasl/include/sasl/config.h create mode 100644 libs/cyrussasl/include/sasl/exits.h create mode 100644 libs/cyrussasl/include/sasl/gai.h create mode 100755 libs/cyrussasl/include/sasl/hmac-md5.h create mode 100644 libs/cyrussasl/include/sasl/makemd5.c create mode 100644 libs/cyrussasl/include/sasl/md5.h create mode 100644 libs/cyrussasl/include/sasl/md5global.h create mode 100644 libs/cyrussasl/include/sasl/prop.h create mode 100755 libs/cyrussasl/include/sasl/sasl.h create mode 100755 libs/cyrussasl/include/sasl/saslplug.h create mode 100755 libs/cyrussasl/include/sasl/saslutil.h create mode 100644 libs/cyrussasl/lib/Makefile.am create mode 100755 libs/cyrussasl/lib/NTMakefile create mode 100644 libs/cyrussasl/lib/auxprop.c create mode 100644 libs/cyrussasl/lib/canonusr.c create mode 100644 libs/cyrussasl/lib/checkpw.c create mode 100644 libs/cyrussasl/lib/client.c create mode 100644 libs/cyrussasl/lib/common.c create mode 100644 libs/cyrussasl/lib/config.c create mode 100644 libs/cyrussasl/lib/dlopen.c create mode 100644 libs/cyrussasl/lib/external.c create mode 100644 libs/cyrussasl/lib/getaddrinfo.c create mode 100644 libs/cyrussasl/lib/getnameinfo.c create mode 100644 libs/cyrussasl/lib/getsubopt.c create mode 100644 libs/cyrussasl/lib/md5.c create mode 100644 libs/cyrussasl/lib/saslint.h create mode 100644 libs/cyrussasl/lib/saslutil.c create mode 100644 libs/cyrussasl/lib/server.c create mode 100644 libs/cyrussasl/lib/seterror.c create mode 100644 libs/cyrussasl/lib/snprintf.c create mode 100644 libs/cyrussasl/lib/staticopen.h create mode 100644 libs/cyrussasl/lib/windlopen.c create mode 100644 libs/cyrussasl/plugins/Makefile.am create mode 100755 libs/cyrussasl/plugins/NTMakefile create mode 100644 libs/cyrussasl/plugins/anonymous.c create mode 100644 libs/cyrussasl/plugins/anonymous_init.c create mode 100644 libs/cyrussasl/plugins/cram.c create mode 100644 libs/cyrussasl/plugins/crammd5_init.c create mode 100644 libs/cyrussasl/plugins/digestmd5.c create mode 100644 libs/cyrussasl/plugins/digestmd5_init.c create mode 100644 libs/cyrussasl/plugins/gs2.c create mode 100644 libs/cyrussasl/plugins/gs2_init.c create mode 100644 libs/cyrussasl/plugins/gs2_token.c create mode 100644 libs/cyrussasl/plugins/gs2_token.h create mode 100644 libs/cyrussasl/plugins/gssapi.c create mode 100644 libs/cyrussasl/plugins/gssapiv2_init.c create mode 100644 libs/cyrussasl/plugins/kerberos4.c create mode 100644 libs/cyrussasl/plugins/kerberos4_init.c create mode 100644 libs/cyrussasl/plugins/ldapdb.c create mode 100644 libs/cyrussasl/plugins/ldapdb_init.c create mode 100644 libs/cyrussasl/plugins/login.c create mode 100644 libs/cyrussasl/plugins/login_init.c create mode 100644 libs/cyrussasl/plugins/ntlm.c create mode 100644 libs/cyrussasl/plugins/ntlm_init.c create mode 100644 libs/cyrussasl/plugins/otp.c create mode 100644 libs/cyrussasl/plugins/otp.h create mode 100644 libs/cyrussasl/plugins/otp_init.c create mode 100644 libs/cyrussasl/plugins/passdss.c create mode 100644 libs/cyrussasl/plugins/passdss_init.c create mode 100644 libs/cyrussasl/plugins/plain.c create mode 100644 libs/cyrussasl/plugins/plain_init.c create mode 100644 libs/cyrussasl/plugins/plugin_common.c create mode 100644 libs/cyrussasl/plugins/plugin_common.h create mode 100644 libs/cyrussasl/plugins/sasldb.c create mode 100644 libs/cyrussasl/plugins/sasldb_init.c create mode 100644 libs/cyrussasl/plugins/scram.c create mode 100644 libs/cyrussasl/plugins/scram_init.c create mode 100644 libs/cyrussasl/plugins/sql.c create mode 100644 libs/cyrussasl/plugins/sql_init.c create mode 100644 libs/cyrussasl/plugins/srp.c create mode 100644 libs/cyrussasl/plugins/srp_init.c create mode 100644 libs/libiconv/AUTHORS create mode 100644 libs/libiconv/COPYING create mode 100644 libs/libiconv/COPYING.LIB create mode 100644 libs/libiconv/ChangeLog create mode 100644 libs/libiconv/DEPENDENCIES create mode 100644 libs/libiconv/DESIGN create mode 100644 libs/libiconv/HACKING create mode 100644 libs/libiconv/INSTALL.generic create mode 100644 libs/libiconv/NEWS create mode 100644 libs/libiconv/NOTES create mode 100644 libs/libiconv/PORTS create mode 100644 libs/libiconv/README create mode 100644 libs/libiconv/README.djgpp create mode 100644 libs/libiconv/README.woe32 create mode 100644 libs/libiconv/THANKS create mode 100644 libs/libiconv/config.h create mode 100644 libs/libiconv/include/iconv.h create mode 100644 libs/libiconv/lib/aliases.gperf create mode 100644 libs/libiconv/lib/aliases.h create mode 100644 libs/libiconv/lib/aliases2.h create mode 100644 libs/libiconv/lib/aliases_aix.h create mode 100644 libs/libiconv/lib/aliases_aix_sysaix.h create mode 100644 libs/libiconv/lib/aliases_dos.h create mode 100644 libs/libiconv/lib/aliases_extra.h create mode 100644 libs/libiconv/lib/aliases_osf1.h create mode 100644 libs/libiconv/lib/aliases_osf1_sysosf1.h create mode 100644 libs/libiconv/lib/aliases_sysaix.gperf create mode 100644 libs/libiconv/lib/aliases_sysaix.h create mode 100644 libs/libiconv/lib/aliases_syshpux.gperf create mode 100644 libs/libiconv/lib/aliases_syshpux.h create mode 100644 libs/libiconv/lib/aliases_sysosf1.gperf create mode 100644 libs/libiconv/lib/aliases_sysosf1.h create mode 100644 libs/libiconv/lib/aliases_syssolaris.gperf create mode 100644 libs/libiconv/lib/aliases_syssolaris.h create mode 100644 libs/libiconv/lib/armscii_8.h create mode 100644 libs/libiconv/lib/ascii.h create mode 100644 libs/libiconv/lib/atarist.h create mode 100644 libs/libiconv/lib/big5.h create mode 100644 libs/libiconv/lib/big5_2003.h create mode 100644 libs/libiconv/lib/big5hkscs1999.h create mode 100644 libs/libiconv/lib/big5hkscs2001.h create mode 100644 libs/libiconv/lib/big5hkscs2004.h create mode 100644 libs/libiconv/lib/big5hkscs2008.h create mode 100644 libs/libiconv/lib/c99.h create mode 100644 libs/libiconv/lib/canonical.h create mode 100644 libs/libiconv/lib/canonical_aix.h create mode 100644 libs/libiconv/lib/canonical_aix_sysaix.h create mode 100644 libs/libiconv/lib/canonical_dos.h create mode 100644 libs/libiconv/lib/canonical_extra.h create mode 100644 libs/libiconv/lib/canonical_local.h create mode 100644 libs/libiconv/lib/canonical_local_sysaix.h create mode 100644 libs/libiconv/lib/canonical_local_syshpux.h create mode 100644 libs/libiconv/lib/canonical_local_sysosf1.h create mode 100644 libs/libiconv/lib/canonical_local_syssolaris.h create mode 100644 libs/libiconv/lib/canonical_osf1.h create mode 100644 libs/libiconv/lib/canonical_osf1_sysosf1.h create mode 100644 libs/libiconv/lib/canonical_sysaix.h create mode 100644 libs/libiconv/lib/canonical_syshpux.h create mode 100644 libs/libiconv/lib/canonical_sysosf1.h create mode 100644 libs/libiconv/lib/canonical_syssolaris.h create mode 100644 libs/libiconv/lib/ces_big5.h create mode 100644 libs/libiconv/lib/ces_gbk.h create mode 100644 libs/libiconv/lib/cjk_variants.h create mode 100644 libs/libiconv/lib/cns11643.h create mode 100644 libs/libiconv/lib/cns11643_1.h create mode 100644 libs/libiconv/lib/cns11643_15.h create mode 100644 libs/libiconv/lib/cns11643_2.h create mode 100644 libs/libiconv/lib/cns11643_3.h create mode 100644 libs/libiconv/lib/cns11643_4.h create mode 100644 libs/libiconv/lib/cns11643_4a.h create mode 100644 libs/libiconv/lib/cns11643_4b.h create mode 100644 libs/libiconv/lib/cns11643_5.h create mode 100644 libs/libiconv/lib/cns11643_6.h create mode 100644 libs/libiconv/lib/cns11643_7.h create mode 100644 libs/libiconv/lib/cns11643_inv.h create mode 100644 libs/libiconv/lib/config.h create mode 100644 libs/libiconv/lib/converters.h create mode 100644 libs/libiconv/lib/cp1046.h create mode 100644 libs/libiconv/lib/cp1124.h create mode 100644 libs/libiconv/lib/cp1125.h create mode 100644 libs/libiconv/lib/cp1129.h create mode 100644 libs/libiconv/lib/cp1131.h create mode 100644 libs/libiconv/lib/cp1133.h create mode 100644 libs/libiconv/lib/cp1161.h create mode 100644 libs/libiconv/lib/cp1162.h create mode 100644 libs/libiconv/lib/cp1163.h create mode 100644 libs/libiconv/lib/cp1250.h create mode 100644 libs/libiconv/lib/cp1251.h create mode 100644 libs/libiconv/lib/cp1252.h create mode 100644 libs/libiconv/lib/cp1253.h create mode 100644 libs/libiconv/lib/cp1254.h create mode 100644 libs/libiconv/lib/cp1255.h create mode 100644 libs/libiconv/lib/cp1256.h create mode 100644 libs/libiconv/lib/cp1257.h create mode 100644 libs/libiconv/lib/cp1258.h create mode 100644 libs/libiconv/lib/cp437.h create mode 100644 libs/libiconv/lib/cp737.h create mode 100644 libs/libiconv/lib/cp775.h create mode 100644 libs/libiconv/lib/cp850.h create mode 100644 libs/libiconv/lib/cp852.h create mode 100644 libs/libiconv/lib/cp853.h create mode 100644 libs/libiconv/lib/cp855.h create mode 100644 libs/libiconv/lib/cp856.h create mode 100644 libs/libiconv/lib/cp857.h create mode 100644 libs/libiconv/lib/cp858.h create mode 100644 libs/libiconv/lib/cp860.h create mode 100644 libs/libiconv/lib/cp861.h create mode 100644 libs/libiconv/lib/cp862.h create mode 100644 libs/libiconv/lib/cp863.h create mode 100644 libs/libiconv/lib/cp864.h create mode 100644 libs/libiconv/lib/cp865.h create mode 100644 libs/libiconv/lib/cp866.h create mode 100644 libs/libiconv/lib/cp869.h create mode 100644 libs/libiconv/lib/cp874.h create mode 100644 libs/libiconv/lib/cp922.h create mode 100644 libs/libiconv/lib/cp932.h create mode 100644 libs/libiconv/lib/cp932ext.h create mode 100644 libs/libiconv/lib/cp936.h create mode 100644 libs/libiconv/lib/cp936ext.h create mode 100644 libs/libiconv/lib/cp943.h create mode 100644 libs/libiconv/lib/cp949.h create mode 100644 libs/libiconv/lib/cp950.h create mode 100644 libs/libiconv/lib/cp950ext.h create mode 100644 libs/libiconv/lib/dec_hanyu.h create mode 100644 libs/libiconv/lib/dec_kanji.h create mode 100644 libs/libiconv/lib/encodings.def create mode 100644 libs/libiconv/lib/encodings_aix.def create mode 100644 libs/libiconv/lib/encodings_dos.def create mode 100644 libs/libiconv/lib/encodings_extra.def create mode 100644 libs/libiconv/lib/encodings_local.def create mode 100644 libs/libiconv/lib/encodings_osf1.def create mode 100644 libs/libiconv/lib/euc_cn.h create mode 100644 libs/libiconv/lib/euc_jisx0213.h create mode 100644 libs/libiconv/lib/euc_jp.h create mode 100644 libs/libiconv/lib/euc_kr.h create mode 100644 libs/libiconv/lib/euc_tw.h create mode 100644 libs/libiconv/lib/flags.h create mode 100644 libs/libiconv/lib/flushwc.h create mode 100644 libs/libiconv/lib/gb12345.h create mode 100644 libs/libiconv/lib/gb12345ext.h create mode 100644 libs/libiconv/lib/gb18030.h create mode 100644 libs/libiconv/lib/gb18030ext.h create mode 100644 libs/libiconv/lib/gb18030uni.h create mode 100644 libs/libiconv/lib/gb2312.h create mode 100644 libs/libiconv/lib/gbk.h create mode 100644 libs/libiconv/lib/gbkext1.h create mode 100644 libs/libiconv/lib/gbkext2.h create mode 100644 libs/libiconv/lib/gbkext_inv.h create mode 100644 libs/libiconv/lib/genaliases.c create mode 100644 libs/libiconv/lib/genaliases2.c create mode 100644 libs/libiconv/lib/genflags.c create mode 100644 libs/libiconv/lib/gentranslit.c create mode 100644 libs/libiconv/lib/georgian_academy.h create mode 100644 libs/libiconv/lib/georgian_ps.h create mode 100644 libs/libiconv/lib/hkscs1999.h create mode 100644 libs/libiconv/lib/hkscs2001.h create mode 100644 libs/libiconv/lib/hkscs2004.h create mode 100644 libs/libiconv/lib/hkscs2008.h create mode 100644 libs/libiconv/lib/hp_roman8.h create mode 100644 libs/libiconv/lib/hz.h create mode 100644 libs/libiconv/lib/iconv.c create mode 100644 libs/libiconv/lib/iconv_open1.h create mode 100644 libs/libiconv/lib/iconv_open2.h create mode 100644 libs/libiconv/lib/iso2022_cn.h create mode 100644 libs/libiconv/lib/iso2022_cnext.h create mode 100644 libs/libiconv/lib/iso2022_jp.h create mode 100644 libs/libiconv/lib/iso2022_jp1.h create mode 100644 libs/libiconv/lib/iso2022_jp2.h create mode 100644 libs/libiconv/lib/iso2022_jp3.h create mode 100644 libs/libiconv/lib/iso2022_kr.h create mode 100644 libs/libiconv/lib/iso646_cn.h create mode 100644 libs/libiconv/lib/iso646_jp.h create mode 100644 libs/libiconv/lib/iso8859_1.h create mode 100644 libs/libiconv/lib/iso8859_10.h create mode 100644 libs/libiconv/lib/iso8859_11.h create mode 100644 libs/libiconv/lib/iso8859_13.h create mode 100644 libs/libiconv/lib/iso8859_14.h create mode 100644 libs/libiconv/lib/iso8859_15.h create mode 100644 libs/libiconv/lib/iso8859_16.h create mode 100644 libs/libiconv/lib/iso8859_2.h create mode 100644 libs/libiconv/lib/iso8859_3.h create mode 100644 libs/libiconv/lib/iso8859_4.h create mode 100644 libs/libiconv/lib/iso8859_5.h create mode 100644 libs/libiconv/lib/iso8859_6.h create mode 100644 libs/libiconv/lib/iso8859_7.h create mode 100644 libs/libiconv/lib/iso8859_8.h create mode 100644 libs/libiconv/lib/iso8859_9.h create mode 100644 libs/libiconv/lib/isoir165.h create mode 100644 libs/libiconv/lib/isoir165ext.h create mode 100644 libs/libiconv/lib/java.h create mode 100644 libs/libiconv/lib/jisx0201.h create mode 100644 libs/libiconv/lib/jisx0208.h create mode 100644 libs/libiconv/lib/jisx0212.h create mode 100644 libs/libiconv/lib/jisx0213.h create mode 100644 libs/libiconv/lib/johab.h create mode 100644 libs/libiconv/lib/johab_hangul.h create mode 100644 libs/libiconv/lib/koi8_r.h create mode 100644 libs/libiconv/lib/koi8_ru.h create mode 100644 libs/libiconv/lib/koi8_t.h create mode 100644 libs/libiconv/lib/koi8_u.h create mode 100644 libs/libiconv/lib/ksc5601.h create mode 100644 libs/libiconv/lib/loop_unicode.h create mode 100644 libs/libiconv/lib/loop_wchar.h create mode 100644 libs/libiconv/lib/loops.h create mode 100644 libs/libiconv/lib/mac_arabic.h create mode 100644 libs/libiconv/lib/mac_centraleurope.h create mode 100644 libs/libiconv/lib/mac_croatian.h create mode 100644 libs/libiconv/lib/mac_cyrillic.h create mode 100644 libs/libiconv/lib/mac_greek.h create mode 100644 libs/libiconv/lib/mac_hebrew.h create mode 100644 libs/libiconv/lib/mac_iceland.h create mode 100644 libs/libiconv/lib/mac_roman.h create mode 100644 libs/libiconv/lib/mac_romania.h create mode 100644 libs/libiconv/lib/mac_thai.h create mode 100644 libs/libiconv/lib/mac_turkish.h create mode 100644 libs/libiconv/lib/mac_ukraine.h create mode 100644 libs/libiconv/lib/mulelao.h create mode 100644 libs/libiconv/lib/nextstep.h create mode 100644 libs/libiconv/lib/pt154.h create mode 100644 libs/libiconv/lib/relocatable.c create mode 100644 libs/libiconv/lib/relocatable.h create mode 100644 libs/libiconv/lib/riscos1.h create mode 100644 libs/libiconv/lib/rk1048.h create mode 100644 libs/libiconv/lib/shift_jisx0213.h create mode 100644 libs/libiconv/lib/sjis.h create mode 100644 libs/libiconv/lib/stamp-h2 create mode 100644 libs/libiconv/lib/tcvn.h create mode 100644 libs/libiconv/lib/tds565.h create mode 100644 libs/libiconv/lib/tis620.h create mode 100644 libs/libiconv/lib/translit.def create mode 100644 libs/libiconv/lib/translit.h create mode 100644 libs/libiconv/lib/ucs2.h create mode 100644 libs/libiconv/lib/ucs2be.h create mode 100644 libs/libiconv/lib/ucs2internal.h create mode 100644 libs/libiconv/lib/ucs2le.h create mode 100644 libs/libiconv/lib/ucs2swapped.h create mode 100644 libs/libiconv/lib/ucs4.h create mode 100644 libs/libiconv/lib/ucs4be.h create mode 100644 libs/libiconv/lib/ucs4internal.h create mode 100644 libs/libiconv/lib/ucs4le.h create mode 100644 libs/libiconv/lib/ucs4swapped.h create mode 100644 libs/libiconv/lib/uhc_1.h create mode 100644 libs/libiconv/lib/uhc_2.h create mode 100644 libs/libiconv/lib/utf16.h create mode 100644 libs/libiconv/lib/utf16be.h create mode 100644 libs/libiconv/lib/utf16le.h create mode 100644 libs/libiconv/lib/utf32.h create mode 100644 libs/libiconv/lib/utf32be.h create mode 100644 libs/libiconv/lib/utf32le.h create mode 100644 libs/libiconv/lib/utf7.h create mode 100644 libs/libiconv/lib/utf8.h create mode 100644 libs/libiconv/lib/vietcomb.h create mode 100644 libs/libiconv/lib/viscii.h create mode 100644 libs/libiconv/libcharset/AUTHORS create mode 100644 libs/libiconv/libcharset/COPYING.LIB create mode 100644 libs/libiconv/libcharset/ChangeLog create mode 100644 libs/libiconv/libcharset/DEPENDENCIES create mode 100644 libs/libiconv/libcharset/HACKING create mode 100644 libs/libiconv/libcharset/INSTALL.generic create mode 100644 libs/libiconv/libcharset/INTEGRATE create mode 100644 libs/libiconv/libcharset/NEWS create mode 100644 libs/libiconv/libcharset/README create mode 100644 libs/libiconv/libcharset/README.djgpp create mode 100644 libs/libiconv/libcharset/README.woe32 create mode 100644 libs/libiconv/libcharset/include/export.h create mode 100644 libs/libiconv/libcharset/include/localcharset.h create mode 100644 libs/libiconv/libcharset/lib/localcharset.c create mode 100644 libs/openssl/Android.mk create mode 100644 libs/openssl/Application.mk create mode 100644 libs/openssl/CHANGES create mode 100644 libs/openssl/LICENSE create mode 100644 libs/openssl/README create mode 100644 libs/openssl/android-config.mk create mode 100644 libs/openssl/crypto/LPdir_nyi.c create mode 100644 libs/openssl/crypto/LPdir_unix.c create mode 100644 libs/openssl/crypto/LPdir_vms.c create mode 100644 libs/openssl/crypto/LPdir_win.c create mode 100644 libs/openssl/crypto/LPdir_win32.c create mode 100644 libs/openssl/crypto/LPdir_wince.c create mode 100644 libs/openssl/crypto/aes/README create mode 100644 libs/openssl/crypto/aes/aes.h create mode 100644 libs/openssl/crypto/aes/aes_cbc.c create mode 100644 libs/openssl/crypto/aes/aes_cfb.c create mode 100644 libs/openssl/crypto/aes/aes_core.c create mode 100644 libs/openssl/crypto/aes/aes_ctr.c create mode 100644 libs/openssl/crypto/aes/aes_ecb.c create mode 100644 libs/openssl/crypto/aes/aes_ige.c create mode 100644 libs/openssl/crypto/aes/aes_locl.h create mode 100644 libs/openssl/crypto/aes/aes_misc.c create mode 100644 libs/openssl/crypto/aes/aes_ofb.c create mode 100644 libs/openssl/crypto/aes/aes_wrap.c create mode 100644 libs/openssl/crypto/aes/aes_x86core.c create mode 100755 libs/openssl/crypto/aes/asm/aes-586.pl create mode 100644 libs/openssl/crypto/aes/asm/aes-armv4.pl create mode 100644 libs/openssl/crypto/aes/asm/aes-ia64.S create mode 100644 libs/openssl/crypto/aes/asm/aes-mips.pl create mode 100644 libs/openssl/crypto/aes/asm/aes-parisc.pl create mode 100644 libs/openssl/crypto/aes/asm/aes-ppc.pl create mode 100644 libs/openssl/crypto/aes/asm/aes-s390x.pl create mode 100755 libs/openssl/crypto/aes/asm/aes-sparcv9.pl create mode 100755 libs/openssl/crypto/aes/asm/aes-x86_64.pl create mode 100644 libs/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl create mode 100644 libs/openssl/crypto/aes/asm/aesni-x86.pl create mode 100644 libs/openssl/crypto/aes/asm/aesni-x86_64.pl create mode 100644 libs/openssl/crypto/aes/asm/bsaes-x86_64.pl create mode 100644 libs/openssl/crypto/aes/asm/vpaes-x86.pl create mode 100644 libs/openssl/crypto/aes/asm/vpaes-x86_64.pl create mode 100644 libs/openssl/crypto/alphacpuid.pl create mode 100644 libs/openssl/crypto/arm_arch.h create mode 100644 libs/openssl/crypto/armcap.c create mode 100644 libs/openssl/crypto/armv4cpuid.S create mode 100644 libs/openssl/crypto/asn1/a_bitstr.c create mode 100644 libs/openssl/crypto/asn1/a_bool.c create mode 100644 libs/openssl/crypto/asn1/a_bytes.c create mode 100644 libs/openssl/crypto/asn1/a_d2i_fp.c create mode 100644 libs/openssl/crypto/asn1/a_digest.c create mode 100644 libs/openssl/crypto/asn1/a_dup.c create mode 100644 libs/openssl/crypto/asn1/a_enum.c create mode 100644 libs/openssl/crypto/asn1/a_gentm.c create mode 100644 libs/openssl/crypto/asn1/a_i2d_fp.c create mode 100644 libs/openssl/crypto/asn1/a_int.c create mode 100644 libs/openssl/crypto/asn1/a_mbstr.c create mode 100644 libs/openssl/crypto/asn1/a_object.c create mode 100644 libs/openssl/crypto/asn1/a_octet.c create mode 100644 libs/openssl/crypto/asn1/a_print.c create mode 100644 libs/openssl/crypto/asn1/a_set.c create mode 100644 libs/openssl/crypto/asn1/a_sign.c create mode 100644 libs/openssl/crypto/asn1/a_strex.c create mode 100644 libs/openssl/crypto/asn1/a_strnid.c create mode 100644 libs/openssl/crypto/asn1/a_time.c create mode 100644 libs/openssl/crypto/asn1/a_type.c create mode 100644 libs/openssl/crypto/asn1/a_utctm.c create mode 100644 libs/openssl/crypto/asn1/a_utf8.c create mode 100644 libs/openssl/crypto/asn1/a_verify.c create mode 100644 libs/openssl/crypto/asn1/ameth_lib.c create mode 100644 libs/openssl/crypto/asn1/asn1.h create mode 100644 libs/openssl/crypto/asn1/asn1_err.c create mode 100644 libs/openssl/crypto/asn1/asn1_gen.c create mode 100644 libs/openssl/crypto/asn1/asn1_lib.c create mode 100644 libs/openssl/crypto/asn1/asn1_locl.h create mode 100644 libs/openssl/crypto/asn1/asn1_mac.h create mode 100644 libs/openssl/crypto/asn1/asn1_par.c create mode 100644 libs/openssl/crypto/asn1/asn1t.h create mode 100644 libs/openssl/crypto/asn1/asn_mime.c create mode 100644 libs/openssl/crypto/asn1/asn_moid.c create mode 100644 libs/openssl/crypto/asn1/asn_pack.c create mode 100644 libs/openssl/crypto/asn1/bio_asn1.c create mode 100644 libs/openssl/crypto/asn1/bio_ndef.c create mode 100644 libs/openssl/crypto/asn1/charmap.h create mode 100644 libs/openssl/crypto/asn1/charmap.pl create mode 100644 libs/openssl/crypto/asn1/d2i_pr.c create mode 100644 libs/openssl/crypto/asn1/d2i_pu.c create mode 100644 libs/openssl/crypto/asn1/evp_asn1.c create mode 100644 libs/openssl/crypto/asn1/f_enum.c create mode 100644 libs/openssl/crypto/asn1/f_int.c create mode 100644 libs/openssl/crypto/asn1/f_string.c create mode 100644 libs/openssl/crypto/asn1/i2d_pr.c create mode 100644 libs/openssl/crypto/asn1/i2d_pu.c create mode 100644 libs/openssl/crypto/asn1/n_pkey.c create mode 100644 libs/openssl/crypto/asn1/nsseq.c create mode 100644 libs/openssl/crypto/asn1/p5_pbe.c create mode 100644 libs/openssl/crypto/asn1/p5_pbev2.c create mode 100644 libs/openssl/crypto/asn1/p8_pkey.c create mode 100644 libs/openssl/crypto/asn1/t_bitst.c create mode 100644 libs/openssl/crypto/asn1/t_crl.c create mode 100644 libs/openssl/crypto/asn1/t_pkey.c create mode 100644 libs/openssl/crypto/asn1/t_req.c create mode 100644 libs/openssl/crypto/asn1/t_spki.c create mode 100644 libs/openssl/crypto/asn1/t_x509.c create mode 100644 libs/openssl/crypto/asn1/t_x509a.c create mode 100644 libs/openssl/crypto/asn1/tasn_dec.c create mode 100644 libs/openssl/crypto/asn1/tasn_enc.c create mode 100644 libs/openssl/crypto/asn1/tasn_fre.c create mode 100644 libs/openssl/crypto/asn1/tasn_new.c create mode 100644 libs/openssl/crypto/asn1/tasn_prn.c create mode 100644 libs/openssl/crypto/asn1/tasn_typ.c create mode 100644 libs/openssl/crypto/asn1/tasn_utl.c create mode 100644 libs/openssl/crypto/asn1/x_algor.c create mode 100644 libs/openssl/crypto/asn1/x_attrib.c create mode 100644 libs/openssl/crypto/asn1/x_bignum.c create mode 100644 libs/openssl/crypto/asn1/x_crl.c create mode 100644 libs/openssl/crypto/asn1/x_exten.c create mode 100644 libs/openssl/crypto/asn1/x_info.c create mode 100644 libs/openssl/crypto/asn1/x_long.c create mode 100644 libs/openssl/crypto/asn1/x_name.c create mode 100644 libs/openssl/crypto/asn1/x_nx509.c create mode 100644 libs/openssl/crypto/asn1/x_pkey.c create mode 100644 libs/openssl/crypto/asn1/x_pubkey.c create mode 100644 libs/openssl/crypto/asn1/x_req.c create mode 100644 libs/openssl/crypto/asn1/x_sig.c create mode 100644 libs/openssl/crypto/asn1/x_spki.c create mode 100644 libs/openssl/crypto/asn1/x_val.c create mode 100644 libs/openssl/crypto/asn1/x_x509.c create mode 100644 libs/openssl/crypto/asn1/x_x509a.c create mode 100644 libs/openssl/crypto/bf/COPYRIGHT create mode 100644 libs/openssl/crypto/bf/INSTALL create mode 100644 libs/openssl/crypto/bf/README create mode 100644 libs/openssl/crypto/bf/VERSION create mode 100644 libs/openssl/crypto/bf/asm/bf-586.pl create mode 100644 libs/openssl/crypto/bf/asm/bf-686.pl create mode 100644 libs/openssl/crypto/bf/asm/readme create mode 100644 libs/openssl/crypto/bf/bf_cbc.c create mode 100644 libs/openssl/crypto/bf/bf_cfb64.c create mode 100644 libs/openssl/crypto/bf/bf_ecb.c create mode 100644 libs/openssl/crypto/bf/bf_enc.c create mode 100644 libs/openssl/crypto/bf/bf_locl.h create mode 100644 libs/openssl/crypto/bf/bf_ofb64.c create mode 100644 libs/openssl/crypto/bf/bf_opts.c create mode 100644 libs/openssl/crypto/bf/bf_pi.h create mode 100644 libs/openssl/crypto/bf/bf_skey.c create mode 100644 libs/openssl/crypto/bf/bfs.cpp create mode 100644 libs/openssl/crypto/bf/bfspeed.c create mode 100644 libs/openssl/crypto/bf/bftest.c create mode 100644 libs/openssl/crypto/bf/blowfish.h create mode 100644 libs/openssl/crypto/bio/b_dump.c create mode 100644 libs/openssl/crypto/bio/b_print.c create mode 100644 libs/openssl/crypto/bio/b_sock.c create mode 100644 libs/openssl/crypto/bio/bf_buff.c create mode 100644 libs/openssl/crypto/bio/bf_lbuf.c create mode 100644 libs/openssl/crypto/bio/bf_nbio.c create mode 100644 libs/openssl/crypto/bio/bf_null.c create mode 100644 libs/openssl/crypto/bio/bio.h create mode 100644 libs/openssl/crypto/bio/bio_cb.c create mode 100644 libs/openssl/crypto/bio/bio_err.c create mode 100644 libs/openssl/crypto/bio/bio_lcl.h create mode 100644 libs/openssl/crypto/bio/bio_lib.c create mode 100644 libs/openssl/crypto/bio/bss_acpt.c create mode 100644 libs/openssl/crypto/bio/bss_bio.c create mode 100644 libs/openssl/crypto/bio/bss_conn.c create mode 100644 libs/openssl/crypto/bio/bss_dgram.c create mode 100644 libs/openssl/crypto/bio/bss_fd.c create mode 100644 libs/openssl/crypto/bio/bss_file.c create mode 100644 libs/openssl/crypto/bio/bss_log.c create mode 100644 libs/openssl/crypto/bio/bss_mem.c create mode 100644 libs/openssl/crypto/bio/bss_null.c create mode 100644 libs/openssl/crypto/bio/bss_rtcp.c create mode 100644 libs/openssl/crypto/bio/bss_sock.c create mode 100644 libs/openssl/crypto/bn/asm/README create mode 100644 libs/openssl/crypto/bn/asm/alpha-mont.pl create mode 100644 libs/openssl/crypto/bn/asm/armv4-gf2m.pl create mode 100644 libs/openssl/crypto/bn/asm/armv4-mont.pl create mode 100644 libs/openssl/crypto/bn/asm/bn-586.pl create mode 100644 libs/openssl/crypto/bn/asm/co-586.pl create mode 100644 libs/openssl/crypto/bn/asm/ia64-mont.pl create mode 100644 libs/openssl/crypto/bn/asm/ia64.S create mode 100644 libs/openssl/crypto/bn/asm/mips-mont.pl create mode 100644 libs/openssl/crypto/bn/asm/mips.pl create mode 100644 libs/openssl/crypto/bn/asm/mips3-mont.pl create mode 100644 libs/openssl/crypto/bn/asm/modexp512-x86_64.pl create mode 100644 libs/openssl/crypto/bn/asm/pa-risc2.s create mode 100644 libs/openssl/crypto/bn/asm/pa-risc2W.s create mode 100644 libs/openssl/crypto/bn/asm/parisc-mont.pl create mode 100644 libs/openssl/crypto/bn/asm/ppc-mont.pl create mode 100644 libs/openssl/crypto/bn/asm/ppc.pl create mode 100644 libs/openssl/crypto/bn/asm/ppc64-mont.pl create mode 100644 libs/openssl/crypto/bn/asm/s390x-gf2m.pl create mode 100644 libs/openssl/crypto/bn/asm/s390x-mont.pl create mode 100755 libs/openssl/crypto/bn/asm/s390x.S create mode 100644 libs/openssl/crypto/bn/asm/sparcv8.S create mode 100644 libs/openssl/crypto/bn/asm/sparcv8plus.S create mode 100644 libs/openssl/crypto/bn/asm/sparcv9-mont.pl create mode 100755 libs/openssl/crypto/bn/asm/sparcv9a-mont.pl create mode 100644 libs/openssl/crypto/bn/asm/via-mont.pl create mode 100644 libs/openssl/crypto/bn/asm/vms.mar create mode 100644 libs/openssl/crypto/bn/asm/x86-gf2m.pl create mode 100755 libs/openssl/crypto/bn/asm/x86-mont.pl create mode 100644 libs/openssl/crypto/bn/asm/x86.pl create mode 100644 libs/openssl/crypto/bn/asm/x86/add.pl create mode 100644 libs/openssl/crypto/bn/asm/x86/comba.pl create mode 100644 libs/openssl/crypto/bn/asm/x86/div.pl create mode 100644 libs/openssl/crypto/bn/asm/x86/f create mode 100644 libs/openssl/crypto/bn/asm/x86/mul.pl create mode 100644 libs/openssl/crypto/bn/asm/x86/mul_add.pl create mode 100644 libs/openssl/crypto/bn/asm/x86/sqr.pl create mode 100644 libs/openssl/crypto/bn/asm/x86/sub.pl create mode 100644 libs/openssl/crypto/bn/asm/x86_64-gcc.c create mode 100644 libs/openssl/crypto/bn/asm/x86_64-gf2m.pl create mode 100755 libs/openssl/crypto/bn/asm/x86_64-mont.pl create mode 100755 libs/openssl/crypto/bn/asm/x86_64-mont5.pl create mode 100644 libs/openssl/crypto/bn/bn.h create mode 100644 libs/openssl/crypto/bn/bn.mul create mode 100644 libs/openssl/crypto/bn/bn_add.c create mode 100644 libs/openssl/crypto/bn/bn_asm.c create mode 100644 libs/openssl/crypto/bn/bn_blind.c create mode 100644 libs/openssl/crypto/bn/bn_const.c create mode 100644 libs/openssl/crypto/bn/bn_ctx.c create mode 100644 libs/openssl/crypto/bn/bn_depr.c create mode 100644 libs/openssl/crypto/bn/bn_div.c create mode 100644 libs/openssl/crypto/bn/bn_err.c create mode 100644 libs/openssl/crypto/bn/bn_exp.c create mode 100644 libs/openssl/crypto/bn/bn_exp2.c create mode 100644 libs/openssl/crypto/bn/bn_gcd.c create mode 100644 libs/openssl/crypto/bn/bn_gf2m.c create mode 100644 libs/openssl/crypto/bn/bn_kron.c create mode 100644 libs/openssl/crypto/bn/bn_lcl.h create mode 100644 libs/openssl/crypto/bn/bn_lib.c create mode 100644 libs/openssl/crypto/bn/bn_mod.c create mode 100644 libs/openssl/crypto/bn/bn_mont.c create mode 100644 libs/openssl/crypto/bn/bn_mpi.c create mode 100644 libs/openssl/crypto/bn/bn_mul.c create mode 100644 libs/openssl/crypto/bn/bn_nist.c create mode 100644 libs/openssl/crypto/bn/bn_prime.c create mode 100644 libs/openssl/crypto/bn/bn_prime.h create mode 100644 libs/openssl/crypto/bn/bn_prime.pl create mode 100644 libs/openssl/crypto/bn/bn_print.c create mode 100644 libs/openssl/crypto/bn/bn_rand.c create mode 100644 libs/openssl/crypto/bn/bn_recp.c create mode 100644 libs/openssl/crypto/bn/bn_shift.c create mode 100644 libs/openssl/crypto/bn/bn_sqr.c create mode 100644 libs/openssl/crypto/bn/bn_sqrt.c create mode 100644 libs/openssl/crypto/bn/bn_word.c create mode 100644 libs/openssl/crypto/bn/bn_x931p.c create mode 100644 libs/openssl/crypto/bn/bnspeed.c create mode 100644 libs/openssl/crypto/bn/bntest.c create mode 100644 libs/openssl/crypto/bn/divtest.c create mode 100644 libs/openssl/crypto/bn/exp.c create mode 100644 libs/openssl/crypto/bn/expspeed.c create mode 100644 libs/openssl/crypto/bn/exptest.c create mode 100644 libs/openssl/crypto/bn/todo create mode 100644 libs/openssl/crypto/bn/vms-helper.c create mode 100644 libs/openssl/crypto/buffer/buf_err.c create mode 100644 libs/openssl/crypto/buffer/buf_str.c create mode 100644 libs/openssl/crypto/buffer/buffer.c create mode 100644 libs/openssl/crypto/buffer/buffer.h create mode 100644 libs/openssl/crypto/camellia/asm/cmll-x86.pl create mode 100644 libs/openssl/crypto/camellia/asm/cmll-x86_64.pl create mode 100644 libs/openssl/crypto/camellia/camellia.c create mode 100644 libs/openssl/crypto/camellia/camellia.h create mode 100644 libs/openssl/crypto/camellia/cmll_cbc.c create mode 100644 libs/openssl/crypto/camellia/cmll_cfb.c create mode 100644 libs/openssl/crypto/camellia/cmll_ctr.c create mode 100644 libs/openssl/crypto/camellia/cmll_ecb.c create mode 100644 libs/openssl/crypto/camellia/cmll_locl.h create mode 100644 libs/openssl/crypto/camellia/cmll_misc.c create mode 100644 libs/openssl/crypto/camellia/cmll_ofb.c create mode 100644 libs/openssl/crypto/camellia/cmll_utl.c create mode 100644 libs/openssl/crypto/cast/asm/cast-586.pl create mode 100644 libs/openssl/crypto/cast/asm/readme create mode 100644 libs/openssl/crypto/cast/c_cfb64.c create mode 100644 libs/openssl/crypto/cast/c_ecb.c create mode 100644 libs/openssl/crypto/cast/c_enc.c create mode 100644 libs/openssl/crypto/cast/c_ofb64.c create mode 100644 libs/openssl/crypto/cast/c_skey.c create mode 100644 libs/openssl/crypto/cast/cast.h create mode 100644 libs/openssl/crypto/cast/cast_lcl.h create mode 100644 libs/openssl/crypto/cast/cast_s.h create mode 100644 libs/openssl/crypto/cast/cast_spd.c create mode 100644 libs/openssl/crypto/cast/castopts.c create mode 100644 libs/openssl/crypto/cast/casts.cpp create mode 100644 libs/openssl/crypto/cast/casttest.c create mode 100644 libs/openssl/crypto/cmac/cm_ameth.c create mode 100644 libs/openssl/crypto/cmac/cm_pmeth.c create mode 100644 libs/openssl/crypto/cmac/cmac.c create mode 100644 libs/openssl/crypto/cmac/cmac.h create mode 100644 libs/openssl/crypto/cms/cms.h create mode 100644 libs/openssl/crypto/cms/cms_asn1.c create mode 100644 libs/openssl/crypto/cms/cms_att.c create mode 100644 libs/openssl/crypto/cms/cms_cd.c create mode 100644 libs/openssl/crypto/cms/cms_dd.c create mode 100644 libs/openssl/crypto/cms/cms_enc.c create mode 100644 libs/openssl/crypto/cms/cms_env.c create mode 100644 libs/openssl/crypto/cms/cms_err.c create mode 100644 libs/openssl/crypto/cms/cms_ess.c create mode 100644 libs/openssl/crypto/cms/cms_io.c create mode 100644 libs/openssl/crypto/cms/cms_lcl.h create mode 100644 libs/openssl/crypto/cms/cms_lib.c create mode 100644 libs/openssl/crypto/cms/cms_pwri.c create mode 100644 libs/openssl/crypto/cms/cms_sd.c create mode 100644 libs/openssl/crypto/cms/cms_smime.c create mode 100644 libs/openssl/crypto/comp/c_rle.c create mode 100644 libs/openssl/crypto/comp/c_zlib.c create mode 100644 libs/openssl/crypto/comp/comp.h create mode 100644 libs/openssl/crypto/comp/comp_err.c create mode 100644 libs/openssl/crypto/comp/comp_lib.c create mode 100644 libs/openssl/crypto/conf/README create mode 100644 libs/openssl/crypto/conf/cnf_save.c create mode 100644 libs/openssl/crypto/conf/conf.h create mode 100644 libs/openssl/crypto/conf/conf_api.c create mode 100644 libs/openssl/crypto/conf/conf_api.h create mode 100644 libs/openssl/crypto/conf/conf_def.c create mode 100644 libs/openssl/crypto/conf/conf_def.h create mode 100644 libs/openssl/crypto/conf/conf_err.c create mode 100644 libs/openssl/crypto/conf/conf_lib.c create mode 100644 libs/openssl/crypto/conf/conf_mall.c create mode 100644 libs/openssl/crypto/conf/conf_mod.c create mode 100644 libs/openssl/crypto/conf/conf_sap.c create mode 100644 libs/openssl/crypto/conf/keysets.pl create mode 100644 libs/openssl/crypto/conf/ssleay.cnf create mode 100644 libs/openssl/crypto/conf/test.c create mode 100644 libs/openssl/crypto/constant_time_locl.h create mode 100644 libs/openssl/crypto/constant_time_test.c create mode 100644 libs/openssl/crypto/cpt_err.c create mode 100644 libs/openssl/crypto/cryptlib.c create mode 100644 libs/openssl/crypto/cryptlib.h create mode 100644 libs/openssl/crypto/crypto-lib.com create mode 100644 libs/openssl/crypto/crypto.h create mode 100644 libs/openssl/crypto/cversion.c create mode 100644 libs/openssl/crypto/des/COPYRIGHT create mode 100644 libs/openssl/crypto/des/DES.pm create mode 100644 libs/openssl/crypto/des/DES.xs create mode 100644 libs/openssl/crypto/des/FILES0 create mode 100644 libs/openssl/crypto/des/INSTALL create mode 100644 libs/openssl/crypto/des/Imakefile create mode 100644 libs/openssl/crypto/des/KERBEROS create mode 100644 libs/openssl/crypto/des/README create mode 100644 libs/openssl/crypto/des/VERSION create mode 100644 libs/openssl/crypto/des/asm/crypt586.pl create mode 100644 libs/openssl/crypto/des/asm/des-586.pl create mode 100644 libs/openssl/crypto/des/asm/des_enc.m4 create mode 100644 libs/openssl/crypto/des/asm/desboth.pl create mode 100644 libs/openssl/crypto/des/asm/readme create mode 100644 libs/openssl/crypto/des/cbc3_enc.c create mode 100644 libs/openssl/crypto/des/cbc_cksm.c create mode 100644 libs/openssl/crypto/des/cbc_enc.c create mode 100644 libs/openssl/crypto/des/cfb64ede.c create mode 100644 libs/openssl/crypto/des/cfb64enc.c create mode 100644 libs/openssl/crypto/des/cfb_enc.c create mode 100644 libs/openssl/crypto/des/des-lib.com create mode 100644 libs/openssl/crypto/des/des.c create mode 100644 libs/openssl/crypto/des/des.h create mode 100644 libs/openssl/crypto/des/des.pod create mode 100644 libs/openssl/crypto/des/des3s.cpp create mode 100644 libs/openssl/crypto/des/des_enc.c create mode 100644 libs/openssl/crypto/des/des_locl.h create mode 100644 libs/openssl/crypto/des/des_old.c create mode 100644 libs/openssl/crypto/des/des_old.h create mode 100644 libs/openssl/crypto/des/des_old2.c create mode 100644 libs/openssl/crypto/des/des_opts.c create mode 100644 libs/openssl/crypto/des/des_ver.h create mode 100644 libs/openssl/crypto/des/dess.cpp create mode 100644 libs/openssl/crypto/des/destest.c create mode 100644 libs/openssl/crypto/des/ecb3_enc.c create mode 100644 libs/openssl/crypto/des/ecb_enc.c create mode 100644 libs/openssl/crypto/des/ede_cbcm_enc.c create mode 100644 libs/openssl/crypto/des/enc_read.c create mode 100644 libs/openssl/crypto/des/enc_writ.c create mode 100644 libs/openssl/crypto/des/fcrypt.c create mode 100644 libs/openssl/crypto/des/fcrypt_b.c create mode 100644 libs/openssl/crypto/des/makefile.bc create mode 100644 libs/openssl/crypto/des/ncbc_enc.c create mode 100644 libs/openssl/crypto/des/ofb64ede.c create mode 100644 libs/openssl/crypto/des/ofb64enc.c create mode 100644 libs/openssl/crypto/des/ofb_enc.c create mode 100644 libs/openssl/crypto/des/options.txt create mode 100644 libs/openssl/crypto/des/pcbc_enc.c create mode 100644 libs/openssl/crypto/des/qud_cksm.c create mode 100644 libs/openssl/crypto/des/rand_key.c create mode 100644 libs/openssl/crypto/des/read2pwd.c create mode 100644 libs/openssl/crypto/des/read_pwd.c create mode 100644 libs/openssl/crypto/des/rpc_des.h create mode 100644 libs/openssl/crypto/des/rpc_enc.c create mode 100644 libs/openssl/crypto/des/rpw.c create mode 100644 libs/openssl/crypto/des/set_key.c create mode 100644 libs/openssl/crypto/des/speed.c create mode 100644 libs/openssl/crypto/des/spr.h create mode 100644 libs/openssl/crypto/des/str2key.c create mode 100644 libs/openssl/crypto/des/times/486-50.sol create mode 100644 libs/openssl/crypto/des/times/586-100.lnx create mode 100644 libs/openssl/crypto/des/times/686-200.fre create mode 100644 libs/openssl/crypto/des/times/aix.cc create mode 100644 libs/openssl/crypto/des/times/alpha.cc create mode 100644 libs/openssl/crypto/des/times/hpux.cc create mode 100644 libs/openssl/crypto/des/times/sparc.gcc create mode 100644 libs/openssl/crypto/des/times/usparc.cc create mode 100644 libs/openssl/crypto/des/typemap create mode 100644 libs/openssl/crypto/des/xcbc_enc.c create mode 100644 libs/openssl/crypto/dh/dh.h create mode 100644 libs/openssl/crypto/dh/dh1024.pem create mode 100644 libs/openssl/crypto/dh/dh192.pem create mode 100644 libs/openssl/crypto/dh/dh2048.pem create mode 100644 libs/openssl/crypto/dh/dh4096.pem create mode 100644 libs/openssl/crypto/dh/dh512.pem create mode 100644 libs/openssl/crypto/dh/dh_ameth.c create mode 100644 libs/openssl/crypto/dh/dh_asn1.c create mode 100644 libs/openssl/crypto/dh/dh_check.c create mode 100644 libs/openssl/crypto/dh/dh_depr.c create mode 100644 libs/openssl/crypto/dh/dh_err.c create mode 100644 libs/openssl/crypto/dh/dh_gen.c create mode 100644 libs/openssl/crypto/dh/dh_key.c create mode 100644 libs/openssl/crypto/dh/dh_lib.c create mode 100644 libs/openssl/crypto/dh/dh_pmeth.c create mode 100644 libs/openssl/crypto/dh/dh_prn.c create mode 100644 libs/openssl/crypto/dh/dhtest.c create mode 100644 libs/openssl/crypto/dh/example create mode 100644 libs/openssl/crypto/dh/generate create mode 100644 libs/openssl/crypto/dh/p1024.c create mode 100644 libs/openssl/crypto/dh/p192.c create mode 100644 libs/openssl/crypto/dh/p512.c create mode 100644 libs/openssl/crypto/dsa/README create mode 100644 libs/openssl/crypto/dsa/dsa.h create mode 100644 libs/openssl/crypto/dsa/dsa_ameth.c create mode 100644 libs/openssl/crypto/dsa/dsa_asn1.c create mode 100644 libs/openssl/crypto/dsa/dsa_depr.c create mode 100644 libs/openssl/crypto/dsa/dsa_err.c create mode 100644 libs/openssl/crypto/dsa/dsa_gen.c create mode 100644 libs/openssl/crypto/dsa/dsa_key.c create mode 100644 libs/openssl/crypto/dsa/dsa_lib.c create mode 100644 libs/openssl/crypto/dsa/dsa_locl.h create mode 100644 libs/openssl/crypto/dsa/dsa_ossl.c create mode 100644 libs/openssl/crypto/dsa/dsa_pmeth.c create mode 100644 libs/openssl/crypto/dsa/dsa_prn.c create mode 100644 libs/openssl/crypto/dsa/dsa_sign.c create mode 100644 libs/openssl/crypto/dsa/dsa_vrf.c create mode 100644 libs/openssl/crypto/dsa/dsagen.c create mode 100644 libs/openssl/crypto/dsa/dsatest.c create mode 100644 libs/openssl/crypto/dsa/fips186a.txt create mode 100644 libs/openssl/crypto/dso/README create mode 100644 libs/openssl/crypto/dso/dso.h create mode 100644 libs/openssl/crypto/dso/dso_beos.c create mode 100644 libs/openssl/crypto/dso/dso_dl.c create mode 100644 libs/openssl/crypto/dso/dso_dlfcn.c create mode 100644 libs/openssl/crypto/dso/dso_err.c create mode 100644 libs/openssl/crypto/dso/dso_lib.c create mode 100644 libs/openssl/crypto/dso/dso_null.c create mode 100644 libs/openssl/crypto/dso/dso_openssl.c create mode 100644 libs/openssl/crypto/dso/dso_vms.c create mode 100644 libs/openssl/crypto/dso/dso_win32.c create mode 100644 libs/openssl/crypto/ebcdic.c create mode 100644 libs/openssl/crypto/ebcdic.h create mode 100644 libs/openssl/crypto/ec/ec.h create mode 100644 libs/openssl/crypto/ec/ec2_mult.c create mode 100644 libs/openssl/crypto/ec/ec2_oct.c create mode 100644 libs/openssl/crypto/ec/ec2_smpl.c create mode 100644 libs/openssl/crypto/ec/ec_ameth.c create mode 100644 libs/openssl/crypto/ec/ec_asn1.c create mode 100644 libs/openssl/crypto/ec/ec_check.c create mode 100644 libs/openssl/crypto/ec/ec_curve.c create mode 100644 libs/openssl/crypto/ec/ec_cvt.c create mode 100644 libs/openssl/crypto/ec/ec_err.c create mode 100644 libs/openssl/crypto/ec/ec_key.c create mode 100644 libs/openssl/crypto/ec/ec_lcl.h create mode 100644 libs/openssl/crypto/ec/ec_lib.c create mode 100644 libs/openssl/crypto/ec/ec_mult.c create mode 100644 libs/openssl/crypto/ec/ec_oct.c create mode 100644 libs/openssl/crypto/ec/ec_pmeth.c create mode 100644 libs/openssl/crypto/ec/ec_print.c create mode 100644 libs/openssl/crypto/ec/eck_prn.c create mode 100644 libs/openssl/crypto/ec/ecp_mont.c create mode 100644 libs/openssl/crypto/ec/ecp_nist.c create mode 100644 libs/openssl/crypto/ec/ecp_nistp224.c create mode 100644 libs/openssl/crypto/ec/ecp_nistp256.c create mode 100644 libs/openssl/crypto/ec/ecp_nistp521.c create mode 100644 libs/openssl/crypto/ec/ecp_nistputil.c create mode 100644 libs/openssl/crypto/ec/ecp_oct.c create mode 100644 libs/openssl/crypto/ec/ecp_smpl.c create mode 100644 libs/openssl/crypto/ec/ectest.c create mode 100644 libs/openssl/crypto/ecdh/ecdh.h create mode 100644 libs/openssl/crypto/ecdh/ecdhtest.c create mode 100644 libs/openssl/crypto/ecdh/ech_err.c create mode 100644 libs/openssl/crypto/ecdh/ech_key.c create mode 100644 libs/openssl/crypto/ecdh/ech_lib.c create mode 100644 libs/openssl/crypto/ecdh/ech_locl.h create mode 100644 libs/openssl/crypto/ecdh/ech_ossl.c create mode 100644 libs/openssl/crypto/ecdsa/ecdsa.h create mode 100644 libs/openssl/crypto/ecdsa/ecdsatest.c create mode 100644 libs/openssl/crypto/ecdsa/ecs_asn1.c create mode 100644 libs/openssl/crypto/ecdsa/ecs_err.c create mode 100644 libs/openssl/crypto/ecdsa/ecs_lib.c create mode 100644 libs/openssl/crypto/ecdsa/ecs_locl.h create mode 100644 libs/openssl/crypto/ecdsa/ecs_ossl.c create mode 100644 libs/openssl/crypto/ecdsa/ecs_sign.c create mode 100644 libs/openssl/crypto/ecdsa/ecs_vrf.c create mode 100644 libs/openssl/crypto/engine/README create mode 100644 libs/openssl/crypto/engine/eng_all.c create mode 100644 libs/openssl/crypto/engine/eng_cnf.c create mode 100644 libs/openssl/crypto/engine/eng_cryptodev.c create mode 100644 libs/openssl/crypto/engine/eng_ctrl.c create mode 100644 libs/openssl/crypto/engine/eng_dyn.c create mode 100644 libs/openssl/crypto/engine/eng_err.c create mode 100644 libs/openssl/crypto/engine/eng_fat.c create mode 100644 libs/openssl/crypto/engine/eng_init.c create mode 100644 libs/openssl/crypto/engine/eng_int.h create mode 100644 libs/openssl/crypto/engine/eng_lib.c create mode 100644 libs/openssl/crypto/engine/eng_list.c create mode 100644 libs/openssl/crypto/engine/eng_openssl.c create mode 100644 libs/openssl/crypto/engine/eng_pkey.c create mode 100644 libs/openssl/crypto/engine/eng_rdrand.c create mode 100644 libs/openssl/crypto/engine/eng_rsax.c create mode 100644 libs/openssl/crypto/engine/eng_table.c create mode 100644 libs/openssl/crypto/engine/engine.h create mode 100644 libs/openssl/crypto/engine/enginetest.c create mode 100644 libs/openssl/crypto/engine/tb_asnmth.c create mode 100644 libs/openssl/crypto/engine/tb_cipher.c create mode 100644 libs/openssl/crypto/engine/tb_dh.c create mode 100644 libs/openssl/crypto/engine/tb_digest.c create mode 100644 libs/openssl/crypto/engine/tb_dsa.c create mode 100644 libs/openssl/crypto/engine/tb_ecdh.c create mode 100644 libs/openssl/crypto/engine/tb_ecdsa.c create mode 100644 libs/openssl/crypto/engine/tb_pkmeth.c create mode 100644 libs/openssl/crypto/engine/tb_rand.c create mode 100644 libs/openssl/crypto/engine/tb_rsa.c create mode 100644 libs/openssl/crypto/engine/tb_store.c create mode 100644 libs/openssl/crypto/err/err.c create mode 100644 libs/openssl/crypto/err/err.h create mode 100644 libs/openssl/crypto/err/err_all.c create mode 100644 libs/openssl/crypto/err/err_prn.c create mode 100644 libs/openssl/crypto/err/openssl.ec create mode 100644 libs/openssl/crypto/evp/bio_b64.c create mode 100644 libs/openssl/crypto/evp/bio_enc.c create mode 100644 libs/openssl/crypto/evp/bio_md.c create mode 100644 libs/openssl/crypto/evp/bio_ok.c create mode 100644 libs/openssl/crypto/evp/c_all.c create mode 100644 libs/openssl/crypto/evp/c_allc.c create mode 100644 libs/openssl/crypto/evp/c_alld.c create mode 100644 libs/openssl/crypto/evp/digest.c create mode 100644 libs/openssl/crypto/evp/e_aes.c create mode 100644 libs/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c create mode 100644 libs/openssl/crypto/evp/e_bf.c create mode 100644 libs/openssl/crypto/evp/e_camellia.c create mode 100644 libs/openssl/crypto/evp/e_cast.c create mode 100644 libs/openssl/crypto/evp/e_des.c create mode 100644 libs/openssl/crypto/evp/e_des3.c create mode 100644 libs/openssl/crypto/evp/e_dsa.c create mode 100644 libs/openssl/crypto/evp/e_idea.c create mode 100644 libs/openssl/crypto/evp/e_null.c create mode 100644 libs/openssl/crypto/evp/e_old.c create mode 100644 libs/openssl/crypto/evp/e_rc2.c create mode 100644 libs/openssl/crypto/evp/e_rc4.c create mode 100644 libs/openssl/crypto/evp/e_rc4_hmac_md5.c create mode 100644 libs/openssl/crypto/evp/e_rc5.c create mode 100644 libs/openssl/crypto/evp/e_seed.c create mode 100644 libs/openssl/crypto/evp/e_xcbc_d.c create mode 100644 libs/openssl/crypto/evp/encode.c create mode 100644 libs/openssl/crypto/evp/evp.h create mode 100644 libs/openssl/crypto/evp/evp_acnf.c create mode 100644 libs/openssl/crypto/evp/evp_cnf.c create mode 100644 libs/openssl/crypto/evp/evp_enc.c create mode 100644 libs/openssl/crypto/evp/evp_err.c create mode 100644 libs/openssl/crypto/evp/evp_extra_test.c create mode 100644 libs/openssl/crypto/evp/evp_fips.c create mode 100644 libs/openssl/crypto/evp/evp_key.c create mode 100644 libs/openssl/crypto/evp/evp_lib.c create mode 100644 libs/openssl/crypto/evp/evp_locl.h create mode 100644 libs/openssl/crypto/evp/evp_pbe.c create mode 100644 libs/openssl/crypto/evp/evp_pkey.c create mode 100644 libs/openssl/crypto/evp/evp_test.c create mode 100644 libs/openssl/crypto/evp/evptests.txt create mode 100644 libs/openssl/crypto/evp/m_dss.c create mode 100644 libs/openssl/crypto/evp/m_dss1.c create mode 100644 libs/openssl/crypto/evp/m_ecdsa.c create mode 100644 libs/openssl/crypto/evp/m_md2.c create mode 100644 libs/openssl/crypto/evp/m_md4.c create mode 100644 libs/openssl/crypto/evp/m_md5.c create mode 100644 libs/openssl/crypto/evp/m_mdc2.c create mode 100644 libs/openssl/crypto/evp/m_null.c create mode 100644 libs/openssl/crypto/evp/m_ripemd.c create mode 100644 libs/openssl/crypto/evp/m_sha.c create mode 100644 libs/openssl/crypto/evp/m_sha1.c create mode 100644 libs/openssl/crypto/evp/m_sigver.c create mode 100644 libs/openssl/crypto/evp/m_wp.c create mode 100644 libs/openssl/crypto/evp/names.c create mode 100644 libs/openssl/crypto/evp/openbsd_hw.c create mode 100644 libs/openssl/crypto/evp/p5_crpt.c create mode 100644 libs/openssl/crypto/evp/p5_crpt2.c create mode 100644 libs/openssl/crypto/evp/p_dec.c create mode 100644 libs/openssl/crypto/evp/p_enc.c create mode 100644 libs/openssl/crypto/evp/p_lib.c create mode 100644 libs/openssl/crypto/evp/p_open.c create mode 100644 libs/openssl/crypto/evp/p_seal.c create mode 100644 libs/openssl/crypto/evp/p_sign.c create mode 100644 libs/openssl/crypto/evp/p_verify.c create mode 100644 libs/openssl/crypto/evp/pmeth_fn.c create mode 100644 libs/openssl/crypto/evp/pmeth_gn.c create mode 100644 libs/openssl/crypto/evp/pmeth_lib.c create mode 100644 libs/openssl/crypto/ex_data.c create mode 100644 libs/openssl/crypto/fips_err.h create mode 100644 libs/openssl/crypto/fips_ers.c create mode 100644 libs/openssl/crypto/hmac/hm_ameth.c create mode 100644 libs/openssl/crypto/hmac/hm_pmeth.c create mode 100644 libs/openssl/crypto/hmac/hmac.c create mode 100644 libs/openssl/crypto/hmac/hmac.h create mode 100644 libs/openssl/crypto/hmac/hmactest.c create mode 100644 libs/openssl/crypto/ia64cpuid.S create mode 100644 libs/openssl/crypto/idea/i_cbc.c create mode 100644 libs/openssl/crypto/idea/i_cfb64.c create mode 100644 libs/openssl/crypto/idea/i_ecb.c create mode 100644 libs/openssl/crypto/idea/i_ofb64.c create mode 100644 libs/openssl/crypto/idea/i_skey.c create mode 100644 libs/openssl/crypto/idea/idea.h create mode 100644 libs/openssl/crypto/idea/idea_lcl.h create mode 100644 libs/openssl/crypto/idea/idea_spd.c create mode 100644 libs/openssl/crypto/idea/ideatest.c create mode 100644 libs/openssl/crypto/idea/version create mode 100755 libs/openssl/crypto/install-crypto.com create mode 100644 libs/openssl/crypto/jpake/jpake.c create mode 100644 libs/openssl/crypto/jpake/jpake.h create mode 100644 libs/openssl/crypto/jpake/jpake_err.c create mode 100644 libs/openssl/crypto/jpake/jpaketest.c create mode 100644 libs/openssl/crypto/krb5/krb5_asn.c create mode 100644 libs/openssl/crypto/krb5/krb5_asn.h create mode 100644 libs/openssl/crypto/lhash/lh_stats.c create mode 100644 libs/openssl/crypto/lhash/lh_test.c create mode 100644 libs/openssl/crypto/lhash/lhash.c create mode 100644 libs/openssl/crypto/lhash/lhash.h create mode 100644 libs/openssl/crypto/lhash/num.pl create mode 100644 libs/openssl/crypto/md2/md2.c create mode 100644 libs/openssl/crypto/md2/md2.h create mode 100644 libs/openssl/crypto/md2/md2_dgst.c create mode 100644 libs/openssl/crypto/md2/md2_one.c create mode 100644 libs/openssl/crypto/md2/md2test.c create mode 100644 libs/openssl/crypto/md32_common.h create mode 100644 libs/openssl/crypto/md4/md4.c create mode 100644 libs/openssl/crypto/md4/md4.h create mode 100644 libs/openssl/crypto/md4/md4_dgst.c create mode 100644 libs/openssl/crypto/md4/md4_locl.h create mode 100644 libs/openssl/crypto/md4/md4_one.c create mode 100644 libs/openssl/crypto/md4/md4s.cpp create mode 100644 libs/openssl/crypto/md4/md4test.c create mode 100644 libs/openssl/crypto/md5/asm/md5-586.pl create mode 100644 libs/openssl/crypto/md5/asm/md5-ia64.S create mode 100755 libs/openssl/crypto/md5/asm/md5-x86_64.pl create mode 100644 libs/openssl/crypto/md5/md5.c create mode 100644 libs/openssl/crypto/md5/md5.h create mode 100644 libs/openssl/crypto/md5/md5_dgst.c create mode 100644 libs/openssl/crypto/md5/md5_locl.h create mode 100644 libs/openssl/crypto/md5/md5_one.c create mode 100644 libs/openssl/crypto/md5/md5s.cpp create mode 100644 libs/openssl/crypto/md5/md5test.c create mode 100644 libs/openssl/crypto/mdc2/mdc2.h create mode 100644 libs/openssl/crypto/mdc2/mdc2_one.c create mode 100644 libs/openssl/crypto/mdc2/mdc2dgst.c create mode 100644 libs/openssl/crypto/mdc2/mdc2test.c create mode 100644 libs/openssl/crypto/mem.c create mode 100644 libs/openssl/crypto/mem_clr.c create mode 100644 libs/openssl/crypto/mem_dbg.c create mode 100644 libs/openssl/crypto/modes/asm/ghash-alpha.pl create mode 100644 libs/openssl/crypto/modes/asm/ghash-armv4.pl create mode 100755 libs/openssl/crypto/modes/asm/ghash-ia64.pl create mode 100644 libs/openssl/crypto/modes/asm/ghash-parisc.pl create mode 100644 libs/openssl/crypto/modes/asm/ghash-s390x.pl create mode 100644 libs/openssl/crypto/modes/asm/ghash-sparcv9.pl create mode 100644 libs/openssl/crypto/modes/asm/ghash-x86.pl create mode 100644 libs/openssl/crypto/modes/asm/ghash-x86_64.pl create mode 100644 libs/openssl/crypto/modes/cbc128.c create mode 100644 libs/openssl/crypto/modes/ccm128.c create mode 100644 libs/openssl/crypto/modes/cfb128.c create mode 100644 libs/openssl/crypto/modes/ctr128.c create mode 100644 libs/openssl/crypto/modes/cts128.c create mode 100644 libs/openssl/crypto/modes/gcm128.c create mode 100644 libs/openssl/crypto/modes/modes.h create mode 100644 libs/openssl/crypto/modes/modes_lcl.h create mode 100644 libs/openssl/crypto/modes/ofb128.c create mode 100644 libs/openssl/crypto/modes/xts128.c create mode 100644 libs/openssl/crypto/o_dir.c create mode 100644 libs/openssl/crypto/o_dir.h create mode 100644 libs/openssl/crypto/o_dir_test.c create mode 100644 libs/openssl/crypto/o_fips.c create mode 100644 libs/openssl/crypto/o_init.c create mode 100644 libs/openssl/crypto/o_str.c create mode 100644 libs/openssl/crypto/o_str.h create mode 100644 libs/openssl/crypto/o_time.c create mode 100644 libs/openssl/crypto/o_time.h create mode 100644 libs/openssl/crypto/objects/o_names.c create mode 100644 libs/openssl/crypto/objects/obj_dat.c create mode 100644 libs/openssl/crypto/objects/obj_dat.h create mode 100644 libs/openssl/crypto/objects/obj_dat.pl create mode 100644 libs/openssl/crypto/objects/obj_err.c create mode 100644 libs/openssl/crypto/objects/obj_lib.c create mode 100644 libs/openssl/crypto/objects/obj_mac.h create mode 100644 libs/openssl/crypto/objects/obj_mac.num create mode 100644 libs/openssl/crypto/objects/obj_xref.c create mode 100644 libs/openssl/crypto/objects/obj_xref.h create mode 100644 libs/openssl/crypto/objects/obj_xref.txt create mode 100644 libs/openssl/crypto/objects/objects.README create mode 100644 libs/openssl/crypto/objects/objects.h create mode 100644 libs/openssl/crypto/objects/objects.pl create mode 100644 libs/openssl/crypto/objects/objects.txt create mode 100644 libs/openssl/crypto/objects/objxref.pl create mode 100644 libs/openssl/crypto/ocsp/ocsp.h create mode 100644 libs/openssl/crypto/ocsp/ocsp_asn.c create mode 100644 libs/openssl/crypto/ocsp/ocsp_cl.c create mode 100644 libs/openssl/crypto/ocsp/ocsp_err.c create mode 100644 libs/openssl/crypto/ocsp/ocsp_ext.c create mode 100644 libs/openssl/crypto/ocsp/ocsp_ht.c create mode 100644 libs/openssl/crypto/ocsp/ocsp_lib.c create mode 100644 libs/openssl/crypto/ocsp/ocsp_prn.c create mode 100644 libs/openssl/crypto/ocsp/ocsp_srv.c create mode 100644 libs/openssl/crypto/ocsp/ocsp_vfy.c create mode 100644 libs/openssl/crypto/opensslconf.h create mode 100644 libs/openssl/crypto/opensslconf.h.in create mode 100644 libs/openssl/crypto/opensslv.h create mode 100644 libs/openssl/crypto/ossl_typ.h create mode 100644 libs/openssl/crypto/pariscid.pl create mode 100644 libs/openssl/crypto/pem/message create mode 100644 libs/openssl/crypto/pem/pem.h create mode 100644 libs/openssl/crypto/pem/pem2.h create mode 100644 libs/openssl/crypto/pem/pem_all.c create mode 100644 libs/openssl/crypto/pem/pem_err.c create mode 100644 libs/openssl/crypto/pem/pem_info.c create mode 100644 libs/openssl/crypto/pem/pem_lib.c create mode 100644 libs/openssl/crypto/pem/pem_oth.c create mode 100644 libs/openssl/crypto/pem/pem_pk8.c create mode 100644 libs/openssl/crypto/pem/pem_pkey.c create mode 100644 libs/openssl/crypto/pem/pem_seal.c create mode 100644 libs/openssl/crypto/pem/pem_sign.c create mode 100644 libs/openssl/crypto/pem/pem_x509.c create mode 100644 libs/openssl/crypto/pem/pem_xaux.c create mode 100644 libs/openssl/crypto/pem/pkcs7.lis create mode 100644 libs/openssl/crypto/pem/pvkfmt.c create mode 100644 libs/openssl/crypto/perlasm/cbc.pl create mode 100755 libs/openssl/crypto/perlasm/ppc-xlate.pl create mode 100644 libs/openssl/crypto/perlasm/readme create mode 100755 libs/openssl/crypto/perlasm/x86_64-xlate.pl create mode 100644 libs/openssl/crypto/perlasm/x86asm.pl create mode 100644 libs/openssl/crypto/perlasm/x86gas.pl create mode 100644 libs/openssl/crypto/perlasm/x86masm.pl create mode 100644 libs/openssl/crypto/perlasm/x86nasm.pl create mode 100644 libs/openssl/crypto/pkcs12/p12_add.c create mode 100644 libs/openssl/crypto/pkcs12/p12_asn.c create mode 100644 libs/openssl/crypto/pkcs12/p12_attr.c create mode 100644 libs/openssl/crypto/pkcs12/p12_crpt.c create mode 100644 libs/openssl/crypto/pkcs12/p12_crt.c create mode 100644 libs/openssl/crypto/pkcs12/p12_decr.c create mode 100644 libs/openssl/crypto/pkcs12/p12_init.c create mode 100644 libs/openssl/crypto/pkcs12/p12_key.c create mode 100644 libs/openssl/crypto/pkcs12/p12_kiss.c create mode 100644 libs/openssl/crypto/pkcs12/p12_mutl.c create mode 100644 libs/openssl/crypto/pkcs12/p12_npas.c create mode 100644 libs/openssl/crypto/pkcs12/p12_p8d.c create mode 100644 libs/openssl/crypto/pkcs12/p12_p8e.c create mode 100644 libs/openssl/crypto/pkcs12/p12_utl.c create mode 100644 libs/openssl/crypto/pkcs12/pk12err.c create mode 100644 libs/openssl/crypto/pkcs12/pkcs12.h create mode 100644 libs/openssl/crypto/pkcs7/bio_pk7.c create mode 100644 libs/openssl/crypto/pkcs7/pk7_asn1.c create mode 100644 libs/openssl/crypto/pkcs7/pk7_attr.c create mode 100644 libs/openssl/crypto/pkcs7/pk7_dgst.c create mode 100644 libs/openssl/crypto/pkcs7/pk7_doit.c create mode 100644 libs/openssl/crypto/pkcs7/pk7_enc.c create mode 100644 libs/openssl/crypto/pkcs7/pk7_lib.c create mode 100644 libs/openssl/crypto/pkcs7/pk7_mime.c create mode 100644 libs/openssl/crypto/pkcs7/pk7_smime.c create mode 100644 libs/openssl/crypto/pkcs7/pkcs7.h create mode 100644 libs/openssl/crypto/pkcs7/pkcs7err.c create mode 100644 libs/openssl/crypto/ppccap.c create mode 100755 libs/openssl/crypto/ppccpuid.pl create mode 100644 libs/openssl/crypto/pqueue/pq_test.c create mode 100644 libs/openssl/crypto/pqueue/pqueue.c create mode 100644 libs/openssl/crypto/pqueue/pqueue.h create mode 100644 libs/openssl/crypto/rand/md_rand.c create mode 100644 libs/openssl/crypto/rand/rand.h create mode 100644 libs/openssl/crypto/rand/rand_egd.c create mode 100644 libs/openssl/crypto/rand/rand_err.c create mode 100644 libs/openssl/crypto/rand/rand_lcl.h create mode 100644 libs/openssl/crypto/rand/rand_lib.c create mode 100644 libs/openssl/crypto/rand/rand_nw.c create mode 100644 libs/openssl/crypto/rand/rand_os2.c create mode 100644 libs/openssl/crypto/rand/rand_unix.c create mode 100644 libs/openssl/crypto/rand/rand_vms.c create mode 100644 libs/openssl/crypto/rand/rand_win.c create mode 100644 libs/openssl/crypto/rand/randfile.c create mode 100644 libs/openssl/crypto/rand/randtest.c create mode 100644 libs/openssl/crypto/rc2/rc2.h create mode 100644 libs/openssl/crypto/rc2/rc2_cbc.c create mode 100644 libs/openssl/crypto/rc2/rc2_ecb.c create mode 100644 libs/openssl/crypto/rc2/rc2_locl.h create mode 100644 libs/openssl/crypto/rc2/rc2_skey.c create mode 100644 libs/openssl/crypto/rc2/rc2cfb64.c create mode 100644 libs/openssl/crypto/rc2/rc2ofb64.c create mode 100644 libs/openssl/crypto/rc2/rc2speed.c create mode 100644 libs/openssl/crypto/rc2/rc2test.c create mode 100644 libs/openssl/crypto/rc2/rrc2.doc create mode 100644 libs/openssl/crypto/rc2/tab.c create mode 100644 libs/openssl/crypto/rc2/version create mode 100644 libs/openssl/crypto/rc4/asm/rc4-586.pl create mode 100644 libs/openssl/crypto/rc4/asm/rc4-ia64.pl create mode 100644 libs/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl create mode 100644 libs/openssl/crypto/rc4/asm/rc4-parisc.pl create mode 100644 libs/openssl/crypto/rc4/asm/rc4-s390x.pl create mode 100755 libs/openssl/crypto/rc4/asm/rc4-x86_64.pl create mode 100644 libs/openssl/crypto/rc4/rc4.c create mode 100644 libs/openssl/crypto/rc4/rc4.h create mode 100644 libs/openssl/crypto/rc4/rc4_enc.c create mode 100644 libs/openssl/crypto/rc4/rc4_locl.h create mode 100644 libs/openssl/crypto/rc4/rc4_skey.c create mode 100644 libs/openssl/crypto/rc4/rc4_utl.c create mode 100644 libs/openssl/crypto/rc4/rc4s.cpp create mode 100644 libs/openssl/crypto/rc4/rc4speed.c create mode 100644 libs/openssl/crypto/rc4/rc4test.c create mode 100644 libs/openssl/crypto/rc4/rrc4.doc create mode 100644 libs/openssl/crypto/rc5/asm/rc5-586.pl create mode 100644 libs/openssl/crypto/rc5/rc5.h create mode 100644 libs/openssl/crypto/rc5/rc5_ecb.c create mode 100644 libs/openssl/crypto/rc5/rc5_enc.c create mode 100644 libs/openssl/crypto/rc5/rc5_locl.h create mode 100644 libs/openssl/crypto/rc5/rc5_skey.c create mode 100644 libs/openssl/crypto/rc5/rc5cfb64.c create mode 100644 libs/openssl/crypto/rc5/rc5ofb64.c create mode 100644 libs/openssl/crypto/rc5/rc5s.cpp create mode 100644 libs/openssl/crypto/rc5/rc5speed.c create mode 100644 libs/openssl/crypto/rc5/rc5test.c create mode 100644 libs/openssl/crypto/ripemd/README create mode 100644 libs/openssl/crypto/ripemd/asm/rips.cpp create mode 100644 libs/openssl/crypto/ripemd/asm/rmd-586.pl create mode 100644 libs/openssl/crypto/ripemd/ripemd.h create mode 100644 libs/openssl/crypto/ripemd/rmd160.c create mode 100644 libs/openssl/crypto/ripemd/rmd_dgst.c create mode 100644 libs/openssl/crypto/ripemd/rmd_locl.h create mode 100644 libs/openssl/crypto/ripemd/rmd_one.c create mode 100644 libs/openssl/crypto/ripemd/rmdconst.h create mode 100644 libs/openssl/crypto/ripemd/rmdtest.c create mode 100644 libs/openssl/crypto/rsa/rsa.h create mode 100644 libs/openssl/crypto/rsa/rsa_ameth.c create mode 100644 libs/openssl/crypto/rsa/rsa_asn1.c create mode 100644 libs/openssl/crypto/rsa/rsa_chk.c create mode 100644 libs/openssl/crypto/rsa/rsa_crpt.c create mode 100644 libs/openssl/crypto/rsa/rsa_depr.c create mode 100644 libs/openssl/crypto/rsa/rsa_eay.c create mode 100644 libs/openssl/crypto/rsa/rsa_err.c create mode 100644 libs/openssl/crypto/rsa/rsa_gen.c create mode 100644 libs/openssl/crypto/rsa/rsa_lib.c create mode 100644 libs/openssl/crypto/rsa/rsa_locl.h create mode 100644 libs/openssl/crypto/rsa/rsa_none.c create mode 100644 libs/openssl/crypto/rsa/rsa_null.c create mode 100644 libs/openssl/crypto/rsa/rsa_oaep.c create mode 100644 libs/openssl/crypto/rsa/rsa_pk1.c create mode 100644 libs/openssl/crypto/rsa/rsa_pmeth.c create mode 100644 libs/openssl/crypto/rsa/rsa_prn.c create mode 100644 libs/openssl/crypto/rsa/rsa_pss.c create mode 100644 libs/openssl/crypto/rsa/rsa_saos.c create mode 100644 libs/openssl/crypto/rsa/rsa_sign.c create mode 100644 libs/openssl/crypto/rsa/rsa_ssl.c create mode 100644 libs/openssl/crypto/rsa/rsa_test.c create mode 100644 libs/openssl/crypto/rsa/rsa_x931.c create mode 100644 libs/openssl/crypto/s390xcap.c create mode 100644 libs/openssl/crypto/s390xcpuid.S create mode 100644 libs/openssl/crypto/seed/seed.c create mode 100644 libs/openssl/crypto/seed/seed.h create mode 100644 libs/openssl/crypto/seed/seed_cbc.c create mode 100644 libs/openssl/crypto/seed/seed_cfb.c create mode 100644 libs/openssl/crypto/seed/seed_ecb.c create mode 100644 libs/openssl/crypto/seed/seed_locl.h create mode 100644 libs/openssl/crypto/seed/seed_ofb.c create mode 100644 libs/openssl/crypto/sha/asm/README create mode 100644 libs/openssl/crypto/sha/asm/sha1-586.pl create mode 100644 libs/openssl/crypto/sha/asm/sha1-alpha.pl create mode 100644 libs/openssl/crypto/sha/asm/sha1-armv4-large.pl create mode 100644 libs/openssl/crypto/sha/asm/sha1-ia64.pl create mode 100644 libs/openssl/crypto/sha/asm/sha1-mips.pl create mode 100644 libs/openssl/crypto/sha/asm/sha1-parisc.pl create mode 100755 libs/openssl/crypto/sha/asm/sha1-ppc.pl create mode 100644 libs/openssl/crypto/sha/asm/sha1-s390x.pl create mode 100644 libs/openssl/crypto/sha/asm/sha1-sparcv9.pl create mode 100644 libs/openssl/crypto/sha/asm/sha1-sparcv9a.pl create mode 100644 libs/openssl/crypto/sha/asm/sha1-thumb.pl create mode 100755 libs/openssl/crypto/sha/asm/sha1-x86_64.pl create mode 100644 libs/openssl/crypto/sha/asm/sha256-586.pl create mode 100644 libs/openssl/crypto/sha/asm/sha256-armv4.pl create mode 100644 libs/openssl/crypto/sha/asm/sha512-586.pl create mode 100644 libs/openssl/crypto/sha/asm/sha512-armv4.pl create mode 100755 libs/openssl/crypto/sha/asm/sha512-ia64.pl create mode 100644 libs/openssl/crypto/sha/asm/sha512-mips.pl create mode 100755 libs/openssl/crypto/sha/asm/sha512-parisc.pl create mode 100755 libs/openssl/crypto/sha/asm/sha512-ppc.pl create mode 100644 libs/openssl/crypto/sha/asm/sha512-s390x.pl create mode 100644 libs/openssl/crypto/sha/asm/sha512-sparcv9.pl create mode 100755 libs/openssl/crypto/sha/asm/sha512-x86_64.pl create mode 100644 libs/openssl/crypto/sha/sha.c create mode 100644 libs/openssl/crypto/sha/sha.h create mode 100644 libs/openssl/crypto/sha/sha1.c create mode 100644 libs/openssl/crypto/sha/sha1_one.c create mode 100644 libs/openssl/crypto/sha/sha1dgst.c create mode 100644 libs/openssl/crypto/sha/sha1test.c create mode 100644 libs/openssl/crypto/sha/sha256.c create mode 100644 libs/openssl/crypto/sha/sha256t.c create mode 100644 libs/openssl/crypto/sha/sha512.c create mode 100644 libs/openssl/crypto/sha/sha512t.c create mode 100644 libs/openssl/crypto/sha/sha_dgst.c create mode 100644 libs/openssl/crypto/sha/sha_locl.h create mode 100644 libs/openssl/crypto/sha/sha_one.c create mode 100644 libs/openssl/crypto/sha/shatest.c create mode 100644 libs/openssl/crypto/sparccpuid.S create mode 100644 libs/openssl/crypto/sparcv9cap.c create mode 100644 libs/openssl/crypto/srp/srp.h create mode 100644 libs/openssl/crypto/srp/srp_grps.h create mode 100644 libs/openssl/crypto/srp/srp_lcl.h create mode 100644 libs/openssl/crypto/srp/srp_lib.c create mode 100644 libs/openssl/crypto/srp/srp_vfy.c create mode 100644 libs/openssl/crypto/srp/srptest.c create mode 100644 libs/openssl/crypto/stack/safestack.h create mode 100644 libs/openssl/crypto/stack/stack.c create mode 100644 libs/openssl/crypto/stack/stack.h create mode 100644 libs/openssl/crypto/store/README create mode 100644 libs/openssl/crypto/store/store.h create mode 100644 libs/openssl/crypto/store/str_err.c create mode 100644 libs/openssl/crypto/store/str_lib.c create mode 100644 libs/openssl/crypto/store/str_locl.h create mode 100644 libs/openssl/crypto/store/str_mem.c create mode 100644 libs/openssl/crypto/store/str_meth.c create mode 100644 libs/openssl/crypto/symhacks.h create mode 100644 libs/openssl/crypto/threads/README create mode 100644 libs/openssl/crypto/threads/mttest.c create mode 100644 libs/openssl/crypto/threads/netware.bat create mode 100755 libs/openssl/crypto/threads/ptest.bat create mode 100644 libs/openssl/crypto/threads/pthreads-vms.com create mode 100644 libs/openssl/crypto/threads/th-lock.c create mode 100755 libs/openssl/crypto/threads/win32.bat create mode 100644 libs/openssl/crypto/ts/ts.h create mode 100644 libs/openssl/crypto/ts/ts_asn1.c create mode 100644 libs/openssl/crypto/ts/ts_conf.c create mode 100644 libs/openssl/crypto/ts/ts_err.c create mode 100644 libs/openssl/crypto/ts/ts_lib.c create mode 100644 libs/openssl/crypto/ts/ts_req_print.c create mode 100644 libs/openssl/crypto/ts/ts_req_utils.c create mode 100644 libs/openssl/crypto/ts/ts_rsp_print.c create mode 100644 libs/openssl/crypto/ts/ts_rsp_sign.c create mode 100644 libs/openssl/crypto/ts/ts_rsp_utils.c create mode 100644 libs/openssl/crypto/ts/ts_rsp_verify.c create mode 100644 libs/openssl/crypto/ts/ts_verify_ctx.c create mode 100644 libs/openssl/crypto/txt_db/txt_db.c create mode 100644 libs/openssl/crypto/txt_db/txt_db.h create mode 100644 libs/openssl/crypto/ui/ui.h create mode 100644 libs/openssl/crypto/ui/ui_compat.c create mode 100644 libs/openssl/crypto/ui/ui_compat.h create mode 100644 libs/openssl/crypto/ui/ui_err.c create mode 100644 libs/openssl/crypto/ui/ui_lib.c create mode 100644 libs/openssl/crypto/ui/ui_locl.h create mode 100644 libs/openssl/crypto/ui/ui_openssl.c create mode 100644 libs/openssl/crypto/ui/ui_util.c create mode 100644 libs/openssl/crypto/uid.c create mode 100644 libs/openssl/crypto/vms_rms.h create mode 100644 libs/openssl/crypto/whrlpool/asm/wp-mmx.pl create mode 100644 libs/openssl/crypto/whrlpool/asm/wp-x86_64.pl create mode 100644 libs/openssl/crypto/whrlpool/whrlpool.h create mode 100644 libs/openssl/crypto/whrlpool/wp_block.c create mode 100644 libs/openssl/crypto/whrlpool/wp_dgst.c create mode 100644 libs/openssl/crypto/whrlpool/wp_locl.h create mode 100644 libs/openssl/crypto/whrlpool/wp_test.c create mode 100644 libs/openssl/crypto/x509/by_dir.c create mode 100644 libs/openssl/crypto/x509/by_file.c create mode 100644 libs/openssl/crypto/x509/verify_extra_test.c create mode 100644 libs/openssl/crypto/x509/x509.h create mode 100644 libs/openssl/crypto/x509/x509_att.c create mode 100644 libs/openssl/crypto/x509/x509_cmp.c create mode 100644 libs/openssl/crypto/x509/x509_d2.c create mode 100644 libs/openssl/crypto/x509/x509_def.c create mode 100644 libs/openssl/crypto/x509/x509_err.c create mode 100644 libs/openssl/crypto/x509/x509_ext.c create mode 100644 libs/openssl/crypto/x509/x509_lu.c create mode 100644 libs/openssl/crypto/x509/x509_obj.c create mode 100644 libs/openssl/crypto/x509/x509_r2x.c create mode 100644 libs/openssl/crypto/x509/x509_req.c create mode 100644 libs/openssl/crypto/x509/x509_set.c create mode 100644 libs/openssl/crypto/x509/x509_trs.c create mode 100644 libs/openssl/crypto/x509/x509_txt.c create mode 100644 libs/openssl/crypto/x509/x509_v3.c create mode 100644 libs/openssl/crypto/x509/x509_vfy.c create mode 100644 libs/openssl/crypto/x509/x509_vfy.h create mode 100644 libs/openssl/crypto/x509/x509_vpm.c create mode 100644 libs/openssl/crypto/x509/x509cset.c create mode 100644 libs/openssl/crypto/x509/x509name.c create mode 100644 libs/openssl/crypto/x509/x509rset.c create mode 100644 libs/openssl/crypto/x509/x509spki.c create mode 100644 libs/openssl/crypto/x509/x509type.c create mode 100644 libs/openssl/crypto/x509/x_all.c create mode 100644 libs/openssl/crypto/x509v3/ext_dat.h create mode 100644 libs/openssl/crypto/x509v3/pcy_cache.c create mode 100644 libs/openssl/crypto/x509v3/pcy_data.c create mode 100644 libs/openssl/crypto/x509v3/pcy_int.h create mode 100644 libs/openssl/crypto/x509v3/pcy_lib.c create mode 100644 libs/openssl/crypto/x509v3/pcy_map.c create mode 100644 libs/openssl/crypto/x509v3/pcy_node.c create mode 100644 libs/openssl/crypto/x509v3/pcy_tree.c create mode 100644 libs/openssl/crypto/x509v3/tabtest.c create mode 100644 libs/openssl/crypto/x509v3/v3_addr.c create mode 100644 libs/openssl/crypto/x509v3/v3_akey.c create mode 100644 libs/openssl/crypto/x509v3/v3_akeya.c create mode 100644 libs/openssl/crypto/x509v3/v3_alt.c create mode 100644 libs/openssl/crypto/x509v3/v3_asid.c create mode 100644 libs/openssl/crypto/x509v3/v3_bcons.c create mode 100644 libs/openssl/crypto/x509v3/v3_bitst.c create mode 100644 libs/openssl/crypto/x509v3/v3_conf.c create mode 100644 libs/openssl/crypto/x509v3/v3_cpols.c create mode 100644 libs/openssl/crypto/x509v3/v3_crld.c create mode 100644 libs/openssl/crypto/x509v3/v3_enum.c create mode 100644 libs/openssl/crypto/x509v3/v3_extku.c create mode 100644 libs/openssl/crypto/x509v3/v3_genn.c create mode 100644 libs/openssl/crypto/x509v3/v3_ia5.c create mode 100644 libs/openssl/crypto/x509v3/v3_info.c create mode 100644 libs/openssl/crypto/x509v3/v3_int.c create mode 100644 libs/openssl/crypto/x509v3/v3_lib.c create mode 100644 libs/openssl/crypto/x509v3/v3_ncons.c create mode 100644 libs/openssl/crypto/x509v3/v3_ocsp.c create mode 100644 libs/openssl/crypto/x509v3/v3_pci.c create mode 100644 libs/openssl/crypto/x509v3/v3_pcia.c create mode 100644 libs/openssl/crypto/x509v3/v3_pcons.c create mode 100644 libs/openssl/crypto/x509v3/v3_pku.c create mode 100644 libs/openssl/crypto/x509v3/v3_pmaps.c create mode 100644 libs/openssl/crypto/x509v3/v3_prn.c create mode 100644 libs/openssl/crypto/x509v3/v3_purp.c create mode 100644 libs/openssl/crypto/x509v3/v3_skey.c create mode 100644 libs/openssl/crypto/x509v3/v3_sxnet.c create mode 100644 libs/openssl/crypto/x509v3/v3_utl.c create mode 100644 libs/openssl/crypto/x509v3/v3conf.c create mode 100644 libs/openssl/crypto/x509v3/v3err.c create mode 100644 libs/openssl/crypto/x509v3/v3prin.c create mode 100644 libs/openssl/crypto/x509v3/x509v3.h create mode 100644 libs/openssl/crypto/x86_64cpuid.pl create mode 100644 libs/openssl/crypto/x86cpuid.pl create mode 100644 libs/openssl/e_os.h create mode 100644 libs/openssl/e_os2.h create mode 120000 libs/openssl/include/openssl/aes.h create mode 120000 libs/openssl/include/openssl/asn1.h create mode 120000 libs/openssl/include/openssl/asn1_mac.h create mode 120000 libs/openssl/include/openssl/asn1t.h create mode 120000 libs/openssl/include/openssl/bio.h create mode 120000 libs/openssl/include/openssl/blowfish.h create mode 120000 libs/openssl/include/openssl/bn.h create mode 120000 libs/openssl/include/openssl/buffer.h create mode 120000 libs/openssl/include/openssl/camellia.h create mode 120000 libs/openssl/include/openssl/cast.h create mode 120000 libs/openssl/include/openssl/cmac.h create mode 120000 libs/openssl/include/openssl/cms.h create mode 120000 libs/openssl/include/openssl/comp.h create mode 120000 libs/openssl/include/openssl/conf.h create mode 120000 libs/openssl/include/openssl/conf_api.h create mode 120000 libs/openssl/include/openssl/crypto.h create mode 120000 libs/openssl/include/openssl/des.h create mode 120000 libs/openssl/include/openssl/des_old.h create mode 120000 libs/openssl/include/openssl/dh.h create mode 120000 libs/openssl/include/openssl/dsa.h create mode 120000 libs/openssl/include/openssl/dso.h create mode 100644 libs/openssl/include/openssl/dtls1.h create mode 120000 libs/openssl/include/openssl/e_os2.h create mode 120000 libs/openssl/include/openssl/ebcdic.h create mode 120000 libs/openssl/include/openssl/ec.h create mode 120000 libs/openssl/include/openssl/ecdh.h create mode 120000 libs/openssl/include/openssl/ecdsa.h create mode 120000 libs/openssl/include/openssl/engine.h create mode 120000 libs/openssl/include/openssl/err.h create mode 120000 libs/openssl/include/openssl/evp.h create mode 120000 libs/openssl/include/openssl/hmac.h create mode 120000 libs/openssl/include/openssl/idea.h create mode 120000 libs/openssl/include/openssl/krb5_asn.h create mode 100644 libs/openssl/include/openssl/kssl.h create mode 100644 libs/openssl/include/openssl/kssl_lcl.h create mode 120000 libs/openssl/include/openssl/lhash.h create mode 120000 libs/openssl/include/openssl/md4.h create mode 120000 libs/openssl/include/openssl/md5.h create mode 120000 libs/openssl/include/openssl/mdc2.h create mode 120000 libs/openssl/include/openssl/modes.h create mode 120000 libs/openssl/include/openssl/obj_mac.h create mode 120000 libs/openssl/include/openssl/objects.h create mode 120000 libs/openssl/include/openssl/ocsp.h create mode 120000 libs/openssl/include/openssl/opensslconf.h create mode 120000 libs/openssl/include/openssl/opensslv.h create mode 120000 libs/openssl/include/openssl/ossl_typ.h create mode 120000 libs/openssl/include/openssl/pem.h create mode 120000 libs/openssl/include/openssl/pem2.h create mode 120000 libs/openssl/include/openssl/pkcs12.h create mode 120000 libs/openssl/include/openssl/pkcs7.h create mode 120000 libs/openssl/include/openssl/pqueue.h create mode 120000 libs/openssl/include/openssl/rand.h create mode 120000 libs/openssl/include/openssl/rc2.h create mode 120000 libs/openssl/include/openssl/rc4.h create mode 120000 libs/openssl/include/openssl/ripemd.h create mode 120000 libs/openssl/include/openssl/rsa.h create mode 120000 libs/openssl/include/openssl/safestack.h create mode 120000 libs/openssl/include/openssl/seed.h create mode 120000 libs/openssl/include/openssl/sha.h create mode 120000 libs/openssl/include/openssl/srp.h create mode 100644 libs/openssl/include/openssl/srtp.h create mode 100644 libs/openssl/include/openssl/ssl.h create mode 100644 libs/openssl/include/openssl/ssl2.h create mode 100644 libs/openssl/include/openssl/ssl23.h create mode 100644 libs/openssl/include/openssl/ssl3.h create mode 100644 libs/openssl/include/openssl/ssl_locl.h create mode 120000 libs/openssl/include/openssl/stack.h create mode 120000 libs/openssl/include/openssl/symhacks.h create mode 100644 libs/openssl/include/openssl/tls1.h create mode 120000 libs/openssl/include/openssl/ts.h create mode 120000 libs/openssl/include/openssl/txt_db.h create mode 120000 libs/openssl/include/openssl/ui.h create mode 120000 libs/openssl/include/openssl/ui_compat.h create mode 120000 libs/openssl/include/openssl/whrlpool.h create mode 120000 libs/openssl/include/openssl/x509.h create mode 120000 libs/openssl/include/openssl/x509_vfy.h create mode 120000 libs/openssl/include/openssl/x509v3.h create mode 100644 libs/openssl/ssl/bio_ssl.c create mode 100644 libs/openssl/ssl/d1_both.c create mode 100644 libs/openssl/ssl/d1_clnt.c create mode 100644 libs/openssl/ssl/d1_enc.c create mode 100644 libs/openssl/ssl/d1_lib.c create mode 100644 libs/openssl/ssl/d1_meth.c create mode 100644 libs/openssl/ssl/d1_pkt.c create mode 100644 libs/openssl/ssl/d1_srtp.c create mode 100644 libs/openssl/ssl/d1_srvr.c create mode 100644 libs/openssl/ssl/kssl.c create mode 100644 libs/openssl/ssl/s23_clnt.c create mode 100644 libs/openssl/ssl/s23_lib.c create mode 100644 libs/openssl/ssl/s23_meth.c create mode 100644 libs/openssl/ssl/s23_pkt.c create mode 100644 libs/openssl/ssl/s23_srvr.c create mode 100644 libs/openssl/ssl/s2_clnt.c create mode 100644 libs/openssl/ssl/s2_enc.c create mode 100644 libs/openssl/ssl/s2_lib.c create mode 100644 libs/openssl/ssl/s2_meth.c create mode 100644 libs/openssl/ssl/s2_pkt.c create mode 100644 libs/openssl/ssl/s2_srvr.c create mode 100644 libs/openssl/ssl/s3_both.c create mode 100644 libs/openssl/ssl/s3_cbc.c create mode 100644 libs/openssl/ssl/s3_clnt.c create mode 100644 libs/openssl/ssl/s3_enc.c create mode 100644 libs/openssl/ssl/s3_lib.c create mode 100644 libs/openssl/ssl/s3_meth.c create mode 100644 libs/openssl/ssl/s3_pkt.c create mode 100644 libs/openssl/ssl/s3_srvr.c create mode 100644 libs/openssl/ssl/ssl-lib.com create mode 100644 libs/openssl/ssl/ssl_algs.c create mode 100644 libs/openssl/ssl/ssl_asn1.c create mode 100644 libs/openssl/ssl/ssl_cert.c create mode 100644 libs/openssl/ssl/ssl_ciph.c create mode 100644 libs/openssl/ssl/ssl_err.c create mode 100644 libs/openssl/ssl/ssl_err2.c create mode 100644 libs/openssl/ssl/ssl_lib.c create mode 100644 libs/openssl/ssl/ssl_rsa.c create mode 100644 libs/openssl/ssl/ssl_sess.c create mode 100644 libs/openssl/ssl/ssl_stat.c create mode 100644 libs/openssl/ssl/ssl_txt.c create mode 100644 libs/openssl/ssl/ssl_utst.c create mode 100644 libs/openssl/ssl/t1_clnt.c create mode 100644 libs/openssl/ssl/t1_enc.c create mode 100644 libs/openssl/ssl/t1_lib.c create mode 100644 libs/openssl/ssl/t1_meth.c create mode 100644 libs/openssl/ssl/t1_reneg.c create mode 100644 libs/openssl/ssl/t1_srvr.c create mode 100644 libs/openssl/ssl/tls_srp.c diff --git a/libs/cyrussasl/AUTHORS b/libs/cyrussasl/AUTHORS new file mode 100644 index 00000000..437a27e3 --- /dev/null +++ b/libs/cyrussasl/AUTHORS @@ -0,0 +1,48 @@ +Rob Siemborski wrote and tested the conversion +to the SASLv2 API. + +Ken Murchison worked on the OTP, NTLM, SRP and SQL +plugins, as well as helping to track down bugs as they appear. He also +added support for HTTP authentication. + +Rob Earhart wrote the build/installation procedure, +wrote and tested some of the code, and provided general guidance and +coding advice. + +Leif Johansson wrote the GSSAPI plugin, with +contributions from Sam Hartman . + +Leandro Santi added Courier authdaemon support. + +Alexey Melnikov wrote the first pass of the +DIGEST-MD5 plugin and continues to work on it. He also wrote +a good deal of the current Windows support. + +Rainer Schoepf contributed the LOGIN plugin, +based on Tim Martin's PLAIN plugin. + +Simon Loader wrote the MySQL auxprop module. + +Rolf Braun wrote the MacOS ports. + +Howard Chu put a good deal of work into OS/390 +portability, correct building of static libraries, and a slew +of misc. bugfixes. + +Tim Martin wrote, debugged, and tested +most of the SASLv1 code. + +Larry Greenfield complained. a lot. + +Chris Newman wrote the initial version of the +SASL API, as well as the version 2 SASL API (documented in sasl.h, +saslutil.h, saslplug.h, and prop.h). + +Ryan Troll started the Windows port, +and both Larry Greenfield and Alexey Melnikov have done more work on it. + +getaddrinfo.c was written by Hajimu UMEMOTO +which is based on the IPv6 code written by KIKUCHI Takahiro + + +$Id: AUTHORS,v 1.18 2006/12/01 17:34:58 mel Exp $ diff --git a/libs/cyrussasl/COPYING b/libs/cyrussasl/COPYING new file mode 100644 index 00000000..3f56f305 --- /dev/null +++ b/libs/cyrussasl/COPYING @@ -0,0 +1,44 @@ +/* CMU libsasl + * Tim Martin + * Rob Earhart + * Rob Siemborski + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ diff --git a/libs/cyrussasl/ChangeLog b/libs/cyrussasl/ChangeLog new file mode 100644 index 00000000..4b97e79c --- /dev/null +++ b/libs/cyrussasl/ChangeLog @@ -0,0 +1,3440 @@ +2012-10-12 Alexey Melnikov + * Getting ready for 2.1.25. + +2012-07-06 Alexey Melnikov + * saslauthd/auth_krb5.c: Fixed a crash in the auth_krb5.c + (bug # 2706). Patch by Nalin Dahyabhai. + +2012-07-03 Alexey Melnikov + * config/ltconfig: Fixed incorrect Darwin version matching in ltconfig + (bug # 3713). Patch by Joshua Root. + +2012-06-08 Alexey Melnikov + * Fixed PLAIN/LOGIN authentication failure when using saslauthd + with no auxprop plugins (bug # 3590). + +2012-06-08 Alexey Melnikov + * Added generation of pkg-config .pc file for Cyrus SASL. + Patch by Dilyan Palauzov. + +2012-06-03 Alexey Melnikov + * Correctly updated libtool version for libsasl and its plugins due + to ABI changes (bug # 3692). + +2012-06-02 Alexey Melnikov + * Better error reporting from auth_getpwent.c/auth_shadow.c + (bug # 3134). Based on a patch by Greg A. Woods. + +2012-06-02 Alexey Melnikov + * Improved error logging on failure to load plugins. + Patch by Greg A. Woods. + +2012-05-30 Alexey Melnikov + * plugins/otp.c, plugins/srp.c: Removed calling of EVP_cleanup() + on SRP/OTP plugin shutdown + +2012-05-30 Alexey Melnikov + * saslauthd/auth_httpform.c: Encode the parameter values passed to + auth_httpform, not the whole POST data. + +2012-05-30 Alexey Melnikov + * lib/config.c, saslauthd/cfile.c: Fixed file descriptor leaks + throughout the code (bug # 3702). Slightly reformatted patch + by Manfred Weichel. + +2012-05-29 Alexey Melnikov + * bug in "saslauthd -a rimap" - not reading the whole IMAP greeting + (bug # 3211). Patch from Lutz Mark (via Red Hat) + +2012-05-29 Alexey Melnikov + * Modernize SASL malloc/realloc callback prototypes + +2012-05-29 Alexey Melnikov + * lib/saslutil.c: Fixed broken logic in get_fqhostname() when + abort_if_no_fqdn is 0 (bug # 3589). Patch by baggins@pld-linux.org + +2012-05-28 Alexey Melnikov + * sasldb/db_berkeley.c, utils/dbconverter-2.c: Added support for + BerkleyDB 5.X or later (Patch by Howard Chu) + +2012-04-20 Alexey Melnikov + * lib/client.c, lib/server.c, lib/saslint.h: Make server and client + side global callbacks private to server.c/client.c respectively + +2012-02-10 Ken Murchison + * plugins/digestmd5.c: better handling of HTTP reauth cases. + +2012-01-28 Ken Murchison + * plugins/digestmd5.c: Correctly send "stale" directive to prevent + clients from (re)promtping for password + +2011-11-25 Alexey Melnikov + * plugins/gs2.c: Updated GS2 plugin not to lose minor GSS-API + status codes on errors (based on a patch from Ralf Haferkamp + ) + +2011-11-21 Alexey Melnikov + * plugins/gssapi.c: Only check out_flags once authentication is + successfully completed + +2011-11-09 Ken Murchison + * cmulocal/sasl2.m4, plugins/gssapi.c, utils/testsuite.c: + Added GSS-SPNEGO plugin which can also be used for HTTP + Negotiate authentication (RFC 4559) + +2011-11-08 Ken Murchison + * plugins/ntlm.c: Flag client-side of NTLM plugin as HTTP-ready + +2011-11-08 Ken Murchison + * include/saslutil.h, lib/config.c, lib/server.c + Added sasl_config_done() to plug a memory leak when using an + application specific config file + +2011-10-07 Alexey Melnikov + * plugins/gssapi.c: Fixed a segfault in gssapi.c + (patch by Phil Pennock) + +2011-09-22 Alexey Melnikov + * config/ltconfig, saslauthd/config/ltconfig: Fixed Cyrus SASL + build on some versions of Mac OS. + +2011-09-22 Alexey Melnikov + * saslauthd/auth_rimap.c: qstring incorrectly appending + the closing double quote. (Merge from RedHat) + +2011-09-22 Alexey Melnikov + * lib/common.c: unlock the mutex in sasl_dispose if the context + was freed by another thread. (Merge from RedHat) + +2011-09-22 Alexey Melnikov + * Makefile.am: "lib" should be built before "plugins" + (Patch from marcandre.lureau@redhat.com) + +2011-09-22 Alexey Melnikov + * lib/saslutil.c: MINGW32 doesn't have rand_s + (Patch from marcandre.lureau@redhat.com) + +2011-09-22 Alexey Melnikov + * configure.in: Various build fixes for MINGW32 + (including defining sleep()) + (Patch from marcandre.lureau@redhat.com) + +2011-09-15 Alexey Melnikov + * sample/client.c: Added additional typecasts to kill warnings + about incompatible callback types + +2011-09-13 Alexey Melnikov + * configure.in, config/ltconfig, config/ltmain.sh: + MacOS X related build fixes: use .plugin when building + SASL plugins, fixed version number calculation, + don't generate multiple symlinks. + Also use LD_RUN_PATH as rpath. (patches by Chris Ridd) + +2011-09-12 Alexey Melnikov + * win32/common.mak: Add _CRT_SECURE_NO_DEPRECATE define + to suppress warnings about use of strdup, snprintf, etc. + +2011-09-12 Alexey Melnikov + * sasldb/db_berkeley.c: + Fixed warnings about incompatible callback types. + +2011-09-12 Alexey Melnikov + * lib/NTMakefile plugins/NTMakefile: + Make sure that copied .c files are only rebuilt when changed. + +2011-09-07 Ken Murchison + * plugins/scram.c: + Fixed 3 memory leaks in SCRAM. Final 2.1.25. + +2011-09-07 Alexey Melnikov + * configure.in, plugins/NTMakefile, plugins/cram.c: + Allow use of cmusaslsecretCRAM-MD5 property to be disabled. + +2011-09-02 Alexey Melnikov + * config/config.guess, config/config.sub, + saslauthd/config/config.guess, saslauthd/config/config.sub: + Updated config to the latest GNU snapshot. + +2011-09-01 Alexey Melnikov + * lib/server.c: Make sure that a failed authorization doesn't preclude + further SASL authentication attempts from working. + +2011-09-01 Alexey Melnikov + * lib/server.c: Fixed some aspects of mech_avail callback handling + in the server side SASL code. + +2011-09-01 Alexey Melnikov + * config/ltconfig, saslauthd/config/ltconfig: Fix SASL's libtool + MacOS/X 64-bit file magic. (Patch by Kurt Zeilenga) + +2011-09-01 Alexey Melnikov + * plugins/scram.c: Fixed some additional Windows warnings and + a memory leak in SCRAM. + +2011-09-01 Alexey Melnikov + * plugins/scram.c: Fix size_t * v. unsigned * bug. + (Patch by Kurt Zeilenga) + +2011-09-01 Alexey Melnikov + * lib/server.c: Fixed a crash caused by aborted SASL authentication + and initiation of another one using the same SASL context. + +2011-09-01 Alexey Melnikov + * include/md5.h, include/sasl.h, include/saslplug.h, lib/auxprop.c, + lib/canonusr.c, lib/client.c, lib/common.c, lib/saslint.h, lib/server.c, + lib/seterror.c, plugins/otp.c, plugins/plugin_common.c, + sasldb/db_berkeley.c, sample/sample-client.c, sample/sample-server.c, + utils/pluginviewer.c, utils/sasldblistusers.c, utils/saslpasswd.c, + utils/testsuite.c: Many of the SASL includes define function pointers + without specifying arguments. In C, the () is treated as unspecified, + rather than (void), hence this is technically not a prototype, + and gcc warns about it. (Patch by Dave Cridland and Alexey Melnikov) + +2011-09-01 Alexey Melnikov + * lib/server.c: Better server plugin API mismatch reporting + +2011-05-23 Alexey Melnikov + * plugins/gs2.c, plugins/gs2_token.c, plugins/gs2_token.h, + cmulocal/sasl2.m4: Use draft-josefsson-gss-capsulate-01 if present. + Negative SASL errors are fatal. (Patch from Luke Howard.) + +2011-05-13 Ken Murchison + * include/sasl.h, plugins/digest-md5.c: + Allow for non-persistent connections when using DIGEST-MD5 plugin + for server-side HTTP Digest (RFC 2617). Also make sure that an + HTTP request is handed to plugin when required. + +2011-04-19 Alexey Melnikov + * plugins/gssapi.c: Fix to build GSSAPI with Heimdal (patch from + Russ Allbery from Debian) + +2011-04-18 Alexey Melnikov + * plugins/gs2_token.h: Added gs2_token.h for the "make dist" target + (patch by Dan White) + +2011-04-13 Alexey Melnikov + * cmulocal/sasl2.m4: Only enable GS2 plugin if + gss_inquire_mech_for_saslname is defined in gssapi.h + +2011-04-12 Alexey Melnikov + * plugins/Makefile.am, plugins/makeinit.sh, plugins/ldapdb.c: + LDAPDB build fixes from Dan White + +2011-04-05 Alexey Melnikov + * configure.in, plugins/Makefile.am, plugins/NTMakefile, + plugins/makeinit.sh, lib/staticopen.h, win32/include/config.h: + Enabled SCRAM plugin build + +2011-03-25 Alexey Melnikov + * plugins/Makefile.am, plugins/makeinit.sh, plugins/gs2_token.h, + plugins/gs2_token.c, README.GS2, cmulocal/sasl2.m4: GS2 plugin + from Luke Howard + +2011-01-25 Ken Murchison + * include/sasl.h, include/saslplug.h, lib/client.c, lib/common.c, + plugins/digest-md5.c sample/http_digest_client.c: + Allow DIGEST-MD5 plugin to be used for client-side + HTTP Digest (RFC 2617) + +2011-01-21 Alexey Melnikov + * plugins/scram.c: Added support for channel bindings to SCRAM-SHA-1. + +2011-01-21 Alexey Melnikov + * lib/client.c, lib/server.c, lib/common.c, lib/saslint.h: Fixed libsasl + to accept *-PLUS SASL mechanism names in client_mech_list/mech_list + options. As *-PLUS mechanism names were synthesized and didn't + correspond to real plugin names, setting client_mech_list to + "SCRAM-SHA-1-PLUS" (for example) was resulting in authentication + failure due to inability to find a matching SASL plugin. + +2011-01-21 Alexey Melnikov + * include/saslplug.h, lib/client.c: Fixed handling of channel bindings + on the client side. The client side was failing to select a suitable + SASL mechanism when the application specified channel bindings, but + didn't make them mandatory to use. In such a configuration, if a + non channel binding capable mechanism was selected through + "client_mech_list" SASL option, sasl_client_start would fail. + For example if the server supports both SCRAM-SHA-1[-PLUS] and + PLAIN and "client_mech_list" was set to "PLAIN", authentication + would never work. + +2011-01-21 Alexey Melnikov + * lib/client.c, lib/server.c: Better default ordering of SASL mechanisms. + Ordering by plugins max_ssf produces wrong result in case an application + using SASL doesn't care about SASL security layers. Before this change + DIGEST-MD5 was always preferred over SCRAM-SHA-1[-PLUS]. In particular + this change takes support for channel bindings into considerations. + +2011-01-19 Ken Murchison + * include/sasl.h, include/saslplug.h, + lib/common.c, lib/server.c, plugins/digest-md5.c: + Changed server-side of HTTP Digest so that the application + must pass an HTTP Request structure (Method/URI/Entity-Body) + rather than just the HTTP Method + +2011-01-19 Alexey Melnikov + * lib/server.c: Server side SASL context should list *-PLUS SASL + mechanisms before the corresponding non-PLUS mechanisms for naive + SASL clients. + +2011-01-19 Alexey Melnikov + * lib/common.c: Fixed some Windows warnings in SASL security layer + handling. + +2011-01-19 Alexey Melnikov + * plugins/scram.c: Made the default number of SCRAM hash iterations + configurable using a new SASL option called "scram_iteration_counter". + Also fixed a couple of error messages. + +2011-01-19 Alexey Melnikov + * utils/pluginviewer.c: Fixed some Linux warnings in pluginviewer. + +2011-01-19 Alexey Melnikov + * plugins/scram.c: Added support for storing SCRAM secrets in + authPassword attribute. Also added the "scram_secret_generate" option + for controlling if authPassword SCRAM secret should be generated + or not. By default (when not specified) the authPassword SCRAM secret + is NOT generated. + +2011-01-19 Alexey Melnikov + * plugins/scram.c: Updated the SCRAM plugin not to use the hardcoded + SCRAM-SHA-1 plugin name in logging. + +2011-01-18 Alexey Melnikov + * plugins/digestmd5.c: Use the same username for reauthentication + cache lookup and update. Thanks to Ken for pointing out the + problem. + +2011-01-14 Ken Murchison + * plugins/ntlm.c: Flag NTLM plugin as HTTP-ready + +2011-01-14 Ken Murchison + * include/sasl.h, include/saslplug.h, + lib/common.c, lib/server.c, plugins/digest-md5.c: + Allow DIGEST-MD5 plugin to be used for server-side + HTTP Digest (RFC 2617) + +2010-12-01 Alexey Melnikov + * lib/server.c: Some reformatting and safer handling of 'free + after SASL server shutdown' condition in server_dispose. + +2010-12-01 Alexey Melnikov + * lib/server.c: server_idle needs to obey server's SASL mechanism + list from the server context. + +2010-12-01 Alexey Melnikov + * lib/client.c, lib/saslint.h: Added support for ordering + SASL mechanisms by strength (on the client side), + or using the client_mech_list option. + +2010-12-01 Alexey Melnikov + * include/sasl.h, include/saslplug.h, lib/client.c, lib/common.c, + lib/saslint.h, lib/server.c, sample/Makefile.am, sample/client.c, + sample/server.c: Added support for channel bindings + (patch by Luke Howard). + +2010-12-01 Alexey Melnikov + * lib/saslutil.c: Fixed the random number generator on Windows + to actually produce random output on each run. + +2010-12-01 Alexey Melnikov + * lib/common.c: Updated textual representations of some error + messages + +2010-11-30 Alexey Melnikov + * plugins/digestmd5.c: Eliminated some "signed/unsigned mismatch" + warnings. + +2010-11-30 Alexey Melnikov + * plugins/digestmd5.c, plugins/srp.c, plugins/otp.c, + plugins/ntlm.c, plugins/login.c, plugins/cram.c: + Be protective against calling sasl_server_step + once authentication has failed. + +2010-11-30 Alexey Melnikov + * plugins/digestmd5.c: Minimize the number of auxprop lookups + in the server side DIGEST-MD5 plugin for the most common + case when authentication and authorization identities are + the same. + +2010-11-30 Alexey Melnikov + * plugins/digestmd5.c: Updated digestmd5_server_mech_step2() + to be more defensive against empty client input. + +2010-11-30 Alexey Melnikov + * plugins/digestmd5.c: Fixed some memory leaks on failed + plugin initialization. Prevent potential race condition + when freeding plugin state. Set the freed reauthentication + cache mutex to NULL, to make errors due to mutex access + after free more obvious. + +2010-11-30 Alexey Melnikov + * plugins/digestmd5.c: Test against broken UTF-8 based hashes + if calculation using special ISO-8859-1 code fails. + This affected some XMPP clients. Patch by Dave Cridland + . + +2010-11-30 Alexey Melnikov + * plugins/digestmd5.c: Fixed an interop problem with some + LDAP clients ignoring server advertised realm + and providing their own. + +2009-08-14 Alexey Melnikov + * saslauthd/auth_shadow.c: Rolled back the previous commit + (#define _XOPEN_SOURCE before including unistd.h), + as this seems to break Solaris 8 build. Note that crypt.h + should be present on a Solaris 8 machine, as well is on Debian, + so this shouldn't be a problem. + +2009-08-04 Alexey Melnikov + * plugins/gssapi.c: Properly set serveroutlen to 0 in one place. + Don't send empty challenge once server context establishment is done, + as this is in violation of the RFC 2222 and its successor. + +2009-07-24 Alexey Melnikov + * plugins/gssapi.c: Don't send maxbuf, if no security layer + can be established. Added additional checks for buffer lengths. + +2009-05-20 Ken Murchison + * configure.in, cmulocal/sasl2.m4, + config/kerberos_v4.m4, config/plain.m4, config/sasldb.m4, + lib/Makefile.am: Fixes to allow static libs to be built in the + CMU build environment + +2009-05-07 Ken Murchison + * configure.in, include/sasl.h, lib/Makefile.am, + plugins/Makefile.am, saslauthd/configure.in, sasldb/Makefile.am, + win32/common.mak, win32/include/config.h: 2.1.24 + +2009-05-03 Alexey Melnikov + * sample/sample-client.c, sample/sample-server.c, utils/smtptest.c: + Fixed bug # 2895 (passing LF to sasl_decode64) + +2009-05-03 Alexey Melnikov + * lib/NTMakefile: Disabled annoying warnings about use of + deprecated standard C library functions, enabled + warnings about Windows64 portability + +2009-05-03 Alexey Melnikov + * configure.in: Added support for SQLite3 + (patch by Maxim Gorbachyov) + +2009-04-27 Ken Murchison + * lib/saslutil.c: Fixed CERT VU#238019 (make sure sasl_encode64() + always NUL terminates output or returns SASL_BUFOVER). + +2009-04-11 Alexey Melnikov + * plugins/sql.c: Fixed SQLite lookup function. + Also fixed SASL PLAIN authentication when used with + SQLite auxprop backend. + +2009-04-11 Alexey Melnikov + * lib/dlopen.c: Updated to use .plugin extension on MacOS + +2009-04-08 Alexey Melnikov + * lib/client.c, lib/server.c: Removed unused mutexes + (bug # 3141) + +2009-03-10 Alexey Melnikov + * include/sasl.h, include/saslplug.h, lib/canonusr.c, + lib/checkpw.c, plugins/sasldb.c, plugins/sql.c: + Added direct support for hashed password to auxprop API + +2009-03-10 Alexey Melnikov + * include/sasl.h, lib/canonusr.c, lib/external.c, + plugins/gssapi.c, plugins/kerberos4.c: Make auxprop lookup + calls in SASL GSSAPI/EXTERNAL optional + +2009-03-10 Alexey Melnikov + * plugins/sasldb.c: A better fix for spurious 'user not found' + errors caused by an attempt to delete a non-existent property + +2009-02-21 Alexey Melnikov + * include/saslutil.h, lib/saslint.h: Made sasl_config_init public + +2009-02-20 Alexey Melnikov + * lib/saslint.h, lib/client.c, lib/common.c, lib/server.c: + Make sure that sasl_set_alloc() has no effect once sasl_client_init() + or sasl_server_init() is called [patch from Debian by + fabbe@debian.org] + +2009-02-20 Alexey Melnikov + * plugins/digestmd5.c: GCC 4.4 requires that the #elif + preprocessor directive have a test condition [patch from Debian by + fabbe@paniq.net] + +2009-02-20 Alexey Melnikov + * saslauthd/lak.c: Define LDAP_DEPRECATED so that ldap_get_values + is properly defined when compiling [patch from Debian by + Dann Frazier ] + +2009-02-20 Alexey Melnikov + * saslauthd/auth_sasldb.c: pid_file_lock is created with a mask + of 644 instead of 0644 [patch from Debian by Sam Hocevar ] + +2009-02-20 Alexey Melnikov + * saslauthd/auth_sasldb.c: Include config.h so that MAXHOSTNAMELEN + is available when building on hurd-i386 [patch from Debian + by mbanck@debian.org] + +2009-02-20 Alexey Melnikov + * saslauthd/auth_shadow.c: Define _XOPEN_SOURCE before including + unistd.h, so that crypt is correctly defined [patch from Debian + by dannf@debian.org] + +2009-02-14 Alexey Melnikov + * utils/pluginviewer.c: Code cleanup, improved human readable messages + +2009-02-14 Alexey Melnikov + * lib/config.c: Strip trailing spaces from config file option + values (bug # 3139, bug # 3041) + +2009-02-14 Alexey Melnikov + * plugins/otp.c: Don't use a stack variable for an OTP prompt + (bug # 2822) + +2009-02-13 Alexey Melnikov + * saslauthd/auth_getpwent.c: Fixed Solaris build (patch by Leena + Heino for bug # 2666) + +2009-02-13 Alexey Melnikov + * include/saslplug.h, lib/server.c, plugins/anonymous.c, + plugins/gssapi.c, plugins/otp.c: Partial support for the + SASL_FEAT_DONTUSE_USERPASSWD feature + +2009-01-28 Alexey Melnikov + * include/sasl.h, lib/auxprop.c, lib/common.c, lib/server.c: + Don't treat a constraint violation as an error to store an auxprop + property + +2009-01-28 Alexey Melnikov + * include/sasl.h, lib/server.c: Extended libsasl (auxprop) to support + user deletion + +2009-01-28 Alexey Melnikov + * plugins/otp.c: Downgrade the failure to store OTP secret to debug level + +2009-01-25 Alexey Melnikov + * lib/windlopen.c: Free handles of shared libraries on Windows + that were loaded but are not SASL plugins (patch by Petr Prazak) + [Bug # 2089]. + +2008-11-23 Alexey Melnikov + * plugins/NTMakefile, win32/common.mak: Added support for building + SQLite3 on Windows. + +2008-11-23 Alexey Melnikov + * plugins/ldapdb.c: Updated LDAPDB lookup function to match auxprop + API changes + +2008-11-15 Alexey Melnikov + * plugins/sql.c: Added SQLITE3 support (patch by Maxim Gorbachyov) + +2008-10-31 Ken Murchison + * lib/saslint.h, lib/server.c: order advertised mechanisms + per the specified 'mech_list' option or by relative "strength" + +2008-10-30 Alexey Melnikov + * plugins/digestmd5.c: Fixed more portability warnings. + Fixed some rare memory leaks. More detailed error reporting. + +2008-10-30 Alexey Melnikov + * win32/include/config.h, lib/canonusr.c, lib/config.c, + sasldb/allockey.c, utils/saslpasswd.c, utils/testsuite.c, + sample/sample-server.c, plugins/anonymous.c, plugins/digestmd5.c, + plugins/login.c, plugins/ntlm.c, plugins/otp.c: + Fixed Windows 64 portability and other types of warnings + +2008-10-29 Alexey Melnikov + * win32/common.mak: Added support for building libraries. + Added support for Windows64. + +2008-10-29 Alexey Melnikov + * lib/common.c: Prevent freeing of common state on a subsequent + call to _sasl_common_init. Make sure that the last global callback + always wins. + +2008-10-29 Alexey Melnikov + * lib/saslint.h, lib/canonusr.c, lib/checkpw.c, lib/client.c, + lib/server.c: Further fixes to auxprop lookup and _sasl_canon_user + cleanup + +2008-10-29 Alexey Melnikov + * include/saslplug.h, lib/auxprop.c, lib/canonusr.c, lib/saslint.h, + plugins/sasldb.c, plugins/sql.c: + Extended SASL auxprop_lookup to return error code + +2008-10-29 Alexey Melnikov + * lib/saslutil.c: Fixed Mac OS X 10.3 build. + +2008-10-29 Alexey Melnikov + * plugins/sql.c: Uninitialized variables cause crash when + the searched user is not found (patch from + Maxim Gorbachyov ) + +2008-10-23 Alexey Melnikov + * sasldb/db_berkeley.c: Return SASL_NOUSER instead of SASL_FAIL + when the database file doesn't exist + +2008-10-23 Alexey Melnikov + * lib/checkpw.c: Updated sasl_user_exists so that it can handle + passwordless accounts (e.g. disabled) + +2008-10-23 Alexey Melnikov + * include/saslutil.h, lib/saslint.h, lib/client.c, lib/common.c, + lib/saslutil.c, lib/server.c: Added hostname canonicalization + +2008-10-22 Alexey Melnikov + * lib/NTMakefile, utils/NTMakefile, sample/NTMakefile, + plugins/NTMakefile: Updated to build with VC 8.0 (VC++ 2005) + +2008-10-22 Alexey Melnikov + * lib/NTMakefile: Don't install .exp and .manifest files. + Updated build dependencies. + +2008-10-21 Alexey Melnikov + * lib/saslint.h, lib/client.c, lib/common.c, lib/server.c: + Implemented sasl_client_done/sasl_server_done + +2008-10-19 Alexey Melnikov + * plugins/login.c, plugins/plain.c: Advertise + SASL_SEC_PASS_CREDENTIALS feature in PLAIN and LOGIN + +2008-10-02 Ken Murchison + * lib/checkpw.c: Fixed potential buffer overflow in + saslautd_verify_password(). + +2008-09-30 Alexey Melnikov + * lib/common.c: Fixed sasl_set_mutex() to disallow changing + mutex management functions once sasl_server_init/ + sasl_client_init is called. Failure to do this is causing + a crash while locking mutexes. [Bug # 3083] + +2008-01-24 Ken Murchison + * plugins/ntlm.c: Fixed crash in calculating NTv2 reponse + (patch from Tim Costen from Isode) + +2008-01-23 Ken Murchison + * plugins/ntlm.c, doc/options.html: allow a comma separated + list of servernames in 'ntlm_server' option + (patch from Enrico Persiani ) + +2008-01-23 Ken Murchison + * plugins/ldapdb.c, plugins/makeinit.sh, doc/options.html: + Added code to extend ldapdb into a canon_user plugin + in addition to its existing auxprop plugin functionality + (patch from Howard Chu + and Torsten Schlabach ) + +2008-01-23 Ken Murchison + * saslauthd/auth_rimap.c: fixed bug counting double-quotes in + username/password. Also fixed bug zeroing password. + (patch from Robert Sanderson ) + +2008-01-23 Ken Murchison + * saslauthd/auth_krb.c: improved diagnostic in the + k5support_verify_tgt() function. Now, detailed krb5 error + information will be given out in the LOG_DEBUG syslog + channel (based on patch from Enrico Scholz + ) + +2007-06-13 Alexey Melnikov + * lib/dlopen.c: 64bit HP-UX uses .so for shared libraries + (patch by Nathan Kinder ). + +2007-06-13 Alexey Melnikov + * plugins/digestmd5.c: Fixed a memory leak in the DIGEST-MD5 + security layer (based on patch from Nathan Kinder + ). + +2007-05-14 Alexey Melnikov + * man/*: updated to reference RFC 4422 instead of + RFC 2222. + +2007-03-02 Alexey Melnikov + * plugins/sasldb.c, plugins/sql.c: Ignore properties + starting with '*' in the auxprop store function. + +2007-02-14 Alexey Melnikov + * plugins/digestmd5.c: Fixed parsing of challenges/ + responses with extra commas. + +2007-01-29 Alexey Melnikov + * plugins/gssapi.c: Check that params->serverFQDN is + not NULL before using strlen on it (reported by + Steven Simon ) + +2006-12-01 Alexey Melnikov + * lib/common.c: Typecast iov_base to (char *), + in case it is defined as "void *" on a platform + like HPUX (Olaf Flebbe). + +2006-11-27 Alexey Melnikov + * plugins/digestmd5.c: Cleaned up comments and + some error messages. + +2006-08-24 Alexey Melnikov + * lib/dlopen.c: Fixed segfault in dlclose on HPUX, + based on feedback from . + +2006-07-16 Alexey Melnikov + * win32/common.mak: Abstracted out compiler command + line options for exception handling. + +2006-07-04 Alexey Melnikov + * saslauthd/auth_shadow.c: Include crypt.h, so that crypt() + is defined. This fixes crash on x64 Suse where + sizeof(int) != sizeof(char *). Based on patch from + rhafer@suse.de. + +2006-06-26 Alexey Melnikov + * plugins/digestmd5.c: Allow for multiple qop options + from the server and require a single qop option + from the client. + +2006-05-19 Ken Murchison + * Makefile.am: include INSTALL.TXT in distro + *** Ready for 2.1.22 + +2006-05-18 Ken Murchison + * cmulocal/sasl2.m4: patch to compile with MIT krb5 1.4.3 + (Philip Guenther ) + +2006-05-18 Alexey Melnikov + * configure.in: Fixed default value in help for the + --with-authdaemond command line option (Philip Guenther). + +2006-05-17 Alexey Melnikov + * NEWS: Ready for 2.1.22 + +2006-05-17 Alexey Melnikov + * utils/Makefile.am: enable pluginviewer in the default build. + +2006-04-26 Ken Murchison + * lib/server.c: call do_authorization() after successful APOP + +2006-04-26 Alexey Melnikov + * plugins/digestmd5.c: If neither DES nor RC4 cipher is selected, + advertise maxssf of 1 (integrity protection). + +2006-04-26 Alexey Melnikov + * utils/pluginviewer.c: Must set fully qualified domain name + in sasl_client_new, or some plugins will not be shown. + +2006-04-26 Alexey Melnikov + * lib/client.c: Replaced wrong "break" statement with + "continue" in the client side list function. + +2006-04-25 Alexey Melnikov + * plugins/NTMakefile: Enable RC4 cipher in Windows build. + +2006-04-25 Alexey Melnikov + * plugins/digestmd5.c: Make sure that SASL packets + shorter than 16 bytes don't cause buffer overrun. + Also prevent an error report from BoundsChecker + regarding pointer being out of range. + +2006-04-25 Alexey Melnikov + * win32/common.mak: Fixed bug of not setting CODEGEN + (code generation option) if STATIC is set. + +2006-04-24 Alexey Melnikov + * plugins/passdss.c, plugins/srp.c: Added include files required + by OpenSSL 0.9.8 (original patch by Dan Nicholson). + +2006-04-24 Alexey Melnikov + * utils/NTMakefile: testsuite.exe doesn't depend on saslSASLDB.dll. + +2006-04-24 Alexey Melnikov + * doc/windows.html: Updated Windows build instructions. + +2006-04-20 Alexey Melnikov + * utils/testsuite.c: Removed sasl_encode test which is no longer + valid due to changed in sasl_encodev. + Also properly terminated all property request lists with NULL. + +2006-04-19 Ken Murchison + * saslauthd/auth_shadow.c, saslauthd/configure.in: Check for 4/5 + argument versions of getXXname_r(). + +2006-04-19 Alexey Melnikov + * lib/common.c: Andrey V. Malyshev pointed out that the SASL + context is always NULL when the default logging callback + _sasl_syslog is called. In particular this means that + the log_level configuration option is always ignored. + +2006-04-19 Alexey Melnikov + * configure.in: Search for application configuration + files in /usr/lib/sasl2 by default and fall back to + /etc/sasl2 if not found. + +2006-04-19 Alexey Melnikov + * plugins/digestmd5.c: Handle missing realm option from + the client as the empty string. This match the behavior + prescribed in RFC 2831. + +2006-04-19 Alexey Melnikov + * saslauthd/Makefile.am: Enable testsaslauthd build + by default. + +2006-04-18 Alexey Melnikov + * lib/saslint.h, lib/common.c: Added support for spliting + big data blocks (bigger than maxbuf) into multiple SASL + packets in sasl_encodev. + +2006-04-10 Alexey Melnikov + * utils/Makefile.am: Added the pluginviewer man page. + Reordered link dependencies for saslpasswds/sasldblistusers2. + +2006-04-10 Alexey Melnikov + * utils/pluginviewer.8: Added man page for pluginviewer. + +2006-04-10 Alexey Melnikov + * utils/pluginviewer.c: Deleted unused command line parameters + and cleaned up usage output. + +2006-04-10 Alexey Melnikov + * include/gai.h: Use HAVE_GETADDRINFO (instead of HAVE_GETNAMEINFO) + to protect definition of getaddrinfo(). + +2006-04-10 Alexey Melnikov + * include/sasl.h: Allocated some GSSAPI specific properties + for Nico Williams (Sun) + +2006-04-10 Alexey Melnikov + * lib/common.c: Free default_plugin_path and + default_conf_path variables in sasl_done. + +2006-04-10 Alexey Melnikov + * sasldb/allockey.c: Cleaned up some warnings + +2006-04-10 Alexey Melnikov + * win32/include/config.h: Deleted a misleading comment + +2006-04-06 Jeffrey Teaton + * saslauthd/auth_rimap.c: patch from Dale Sedivec to prevent + segfault when saslauth free()s returned string + * plugins/sql.c: patch from Matthew Hardin to do better + error checking for mysql_real_query + +2006-04-03 Alexey Melnikov + * configure.in, plugins/NTMakefile, plugins/sasldb.c, + sasldb/db_berkeley.c, sasldb/sasldb.h: + Patch to keep BerkleyDB handle open between operations + (for performance reason). New behavior can be enabled + with --enable-keep-db-open. Original patch by Curtis King. + +2006-03-14 Alexey Melnikov + * lib/server.c: Fixed bug # 2796: load_config now + looks in all directories for the config file, + not just in the first one. + +2006-03-14 Alexey Melnikov + * include/saslplug.h, lib/auxprop.c, lib/client.c + lib/server.c, utils/Makefile.am, utils/NTMakefile, + utils/pluginviewer.c [new]: + Added support for reporting information about + loaded auxprop plugins. Changed the first parameter + to sasl_server_plugin_info/sasl_client_plugin_info + to be "const char *". Added new utility for + reporting information about client and server side + authentication plugins and auxprop plugins (e.g. + supported features, methods, etc.). + +2006-03-13 Alexey Melnikov + * saslauthd/Makefile.am, saslauthd/auth_httpform.c, + saslauthd/auth_httpform.h, saslauthd/configure.in, + saslauthd/mechanisms.c, saslauthd/mechanisms.h: + Added support for HTTP POST password validation + in saslauthd (patch by Joe Ammann ) + +2006-03-13 Alexey Melnikov + * cmulocal/openldap.m4: Allow for compilation + with OpenLDAP 2.3+. + +2006-03-13 Alexey Melnikov + * lib/saslutil.c, utils/testsuite.c: Various + fixes to sasl_decode64: don't ignore partial + base64 data, don't allow any data after the '=' + sign, etc.). + +2006-03-13 Alexey Melnikov + * lib/saslint.h: Increase canonicalization buffer + size to 1024 bytes, as Luke Howard has reported + that 256 is too small for some certificates. + +2006-03-13 Alexey Melnikov + * lib/NTMakefile: Include Cyrus version of + getnameinfo() when compiling with Visual Studio 6, + as Windows SDK emulation is not available. + +2006-02-13 Alexey Melnikov + * include/sasl.h, lib/common.c: Added sasl_set_path + function (for a more convenient way of setting + plugin and config paths. Changed the default + sasl_getpath_t/sasl_getconfpath_t callbacks to + calculate the value only once and cache it + for later use. + +2006-02-13 Alexey Melnikov + * configure.in, include/sasl.h, lib/common.c, + lib/saslinit.h, lib/server.c, man/Makefile.am, + man/sasl_callbacks.3, man/sasl_getconfpath_t.3, + win32/include/config.h: Added a new sasl_getconf_t + callback for specifying where SASL configuration files + can be found. Based on patch from Artur Frysiak + for SASL v1, updated by Gentoo + folks for SASL v2 and further modified by + Andreas Hasenack . + +2006-01-31 Alexey Melnikov + * INSTALL, INSTALL.TXT: Renamed INSTALL to INSTALL.TXT + as the former conflicts with Windows "install" target + (and Windows file names are case-insensitive). + +2005-08-11 Alexey Melnikov + * plugins/sasldb.c: Return SASL_NOUSER only if all calls to + _sasldb_putdata() return SASL_NOUSER. This prevents spurious + SASL_NOUSER errors. + +2005-07-07 Alexey Melnikov + * plugins/ntlm.c: Added include in order to fix + building with OpenSSL 0.9.8. + +2005-05-19 Derrick Brashear + * config/libtool.m4: do proper quoting, from Andreas Winkelmann + * configure.in: clean up enable switches, from Patrick Welche + * config/sasldb.m4: fix macro names, from Andreas Winkelmann + * lib/client.c: deal with gcc4 strictness, from Steven Simon + +2005-05-16 Derrick Brashear + * configure.in, include/sasl.h, lib/Makefile.am, + plugins/Makefile.am, saslauthd/configure.in, sasldb/Makefile.am, + win32/common.mak, win32/include/config.h: 2.1.21 + * Makefile.am: fix dist-hook to run makeinit.sh in plugins/ + +2005-05-15 Derrick Brashear + * saslauthd/lak.c: leak fix from Igor Brezac + +2005-05-15 Alexey Melnikov + * plugins/NTMakefile: ldapdb on Windows might depend on OpenSSL. + +2005-05-06 Derrick Brashear + * configure.in, saslauthd/auth_pam.c: detect pam header location also + where MacOS provides it, and use it there + * utils/Makefile.am: change link order for MacOS + * configure.in: provide option to disable installing MacOS SASL2 + framework + * configure.in, config/kerberos_v4.m4, config/plain.m4, + config/sasldb.m4, lib/Makefile.am, sasldb/Makefile.am, + (cmulocal/sasl2.m4): fix case where we are building + --enable-static --with-dblib=none causing automake's dependancy + stuff to screw us when we try to build files with .. in their path + +2005-04-11 Derrick Brashear + * configure.in, plugins/digestmd5.c: detect and include des.h if it + exists, otherwise assume we don't need it (Solaris 9) + +2005-04-11 Derrick Brashear + * sasldb/Makefile.am, config/sasldb.m4: work around HP-UX make's + inability to have pipes in $(shell ...) by setting + LOCAL_SASL_DB_BACKEND_STATIC at the same time as + SASL_DB_BACKEND_STATIC. + +2005-03-15 Alexey Melnikov + * lib/dlopen.c: log the reason for opendir() failure + when loading plugin. + +2005-03-08 Alexey Melnikov + * man/sasl_auxprop.3, man/sasl_auxprop_getctx.3, + man/sasl_auxprop_request.3, man/sasl_canon_user_t.3, + man/sasl_client_init.3, man/sasl_client_new.3, + man/sasl_client_start.3, man/sasl_client_step.3, + man/sasl_decode.3, man/sasl_errdetail.3, man/sasl_errstring.3, + man/sasl_getpath_t.3, man/sasl_getrealm_t.3, + man/sasl_getsecret_t.3, man/sasl_server_init.3, + man/sasl_server_new.3, man/sasl_server_start.3, + man/sasl_server_step.3, man/sasl_setpass.3, + man/sasl_user_exists.3, man/sasl_verifyfile_t.3: multiple + spelling corrections from Steven Simon . + +2005-03-07 Alexey Melnikov + * utils/saslpasswd2.8, utils/sasldblistusers2.8: updated manpages. + +2005-03-01 Derrick Brashear + * lib/common.c: honor log level setting + +2005-02-28 Derrick Brashear + * README.ldapdb: ldapdb license info + +2005-02-25 Alexey Melnikov + * include/sasl.h, lib/common.c: Added SASL_VERSION_FULL + define + +2005-02-22 Alexey Melnikov + * plugins/NTMakefile, win32/common.mak: Windows build of the ldapdb + auxprop plugin + +2005-02-16 Derrick Brashear + * configure.in, doc/install.html, doc/options.html, doc/readme.html, + doc/sysadmin.html, lib/staticopen.h, plugins/Makefile.am, + plugins/ldapdb.c, plugins/makeinit.sh: pull in ldapdb auxprop + plugin, from Igor Brezac (Howard Chu's plugin) + +2005-02-14 Derrick Brashear + * saslauthd/krbtf.c: updated from CMUCS + * saslauthd/auth_krb5.c: log the krb5 error return if get_creds fails + +2005-02-01 Alexey Melnikov + * win32/include/config.h: Updated to match gai.h changes. + * win32/include/config.h: added define for the OTP plugin. + +2005-01-27 Derrick Brashear + * configure.in, include/gai.h: move AI_NUMERICHOSTS definitions + to config.h because gai.h is not always included. + +2005-01-10 Derrick Brashear + * saslauthd/auth_krb5.c, saslauthd/auth_krb4.c, + saslauthd/krbtf.h (added), saslauthd/krbtf.c (added), + saslauthd/cfile.h (added), saslauthd/cfile.c (added), + saslauthd/Makefile.am: Kerberos V4/V5 alternate keytab + in saslauthd, plus common code merging (from David Eckhardt + via Dale Moore) + +2004-12-08 Alexey Melnikov + * doc/windows.html: Updated as per recent build changes. + * plugins/ntlm.c: Fixed NTLM build on Windows, + as compiler was complaining about array size not being + a const. + * lib/NTMakefile, plugins/NTMakefile, win32/common.mak, + win32/include/config.h: Use native IPv6 support on Windows, + falling back to Microsoft emulation. Cleaner support + for Visual Studio 6. + +2004-11-24 Ken Murchison + * plugins/sql.c: squashed unused parameter warnings + +2004-11-24 Ken Murchison + * plugins/passdss.c: added; PASSDSS-3DES-1 implementation + * configure.in, plugins/Makefile.am, plugins/makeinit.sh: + added support for PASSDSS + * doc/draft-newman-sasl-passdss-xx.txt: added + * doc/index.html, doc/Makefile.am: added PASSDSS draft + +2004-11-19 Derrick Brashear + * saslauthd/auth_krb5.c: verify against the service we + were passed. needs to be made configurable. + +2004-11-10 Alexey Melnikov + * doc/draft-burdis-cat-srp-sasl-08.txt: deleted + * doc/draft-ietf-sasl-anon-02.txt: deleted + * doc/draft-ietf-sasl-crammd5-01.txt: deleted + * doc/draft-ietf-sasl-gssapi-00.txt: deleted + * doc/draft-ietf-sasl-plain-03.txt: deleted + * doc/draft-ietf-sasl-rfc2222bis-03.txt: deleted + * doc/draft-ietf-sasl-rfc2831bis-02.txt: deleted + * doc/draft-ietf-sasl-saslprep-04.txt: deleted + * doc/draft-newman-sasl-c-api-01.txt: deleted + * doc/draft-burdis-cat-srp-sasl-xx.txt: added + * doc/draft-ietf-sasl-anon-xx.txt: added + * doc/draft-ietf-sasl-crammd5-xx.txt: added + * doc/draft-ietf-sasl-gssapi-xx.txt: added + * doc/draft-ietf-sasl-plain-xx.txt: added + * doc/draft-ietf-sasl-rfc2222bis-xx.txt: added + * doc/draft-ietf-sasl-rfc2831bis-xx.txt: added + * doc/draft-ietf-sasl-saslprep-xx.txt: added + * doc/draft-newman-sasl-c-api-xx.txt: added + * doc/index.html, doc/Makefile.am: Renamed the files + +2004-11-02 Alexey Melnikov + * include/saslplug.h, lib/common.c, lib/saslint.h, + lib/client.c: Added sasl_client_plugin_info(). + +2004-10-26 Alexey Melnikov + * sample/sample-client.c, sample/sample-server.c: Fixed several + 64 bit portability warnings. + * utils/testsuite.c: Fixed several 64 bit portability warnings. + * utils/saslpasswd.c: Fixed typo in an auxprop name. + * include/saslplug.h, lib/common.c, lib/saslint.h, + lib/server.c: Added sasl_server_plugin_info(). + +2004-10-24 Derrick Brashear + * lib/common.c: initialize path in case caller didn't. + +2004-10-24 Derrick Brashear + * Prep for 2.1.20 + +2004-10-19 Derrick Brashear + * Makefile.am, saslauthd/Makefile.am: require automake 1.7; + prior versions require AM_CONFIG_HEADER and dislike AM_LDFLAGS + +2004-10-14 Ken Murchison + * plugins/ntlm.c: portability fixes from Alexey, and squashed a + signed/unsigned warning + +2004-10-14 Alexey Melnikov + * lib/NTMakefile: Don't install intermediate file libsasl.res + +2004-09-22 Derrick Brashear + * lib/common.c: don't honor SASL_PATH in setuid environment. + from Gentoo + +2004-09-08 Alexey Melnikov + * plugins/cram.c, plugins/anonymous.c, plugins/login.c, + plugins/plain.c, plugins/sasldb.c: Fixed several 64 bit + portability warnings + +2004-09-02 Derrick Brashear + * plugins/kerberosv4.c: simple explanation in the code of one + possible error you might see in strange circumstances; + i should probably make openssl's des unable to be used if + mit krb5 is being used. + +2004-08-06 Derrick Brashear + * plugins/cram.c: initialize authid to null so stack garbage + is not pushed into _sasl_canon_user + +2004-07-29 Rob Siemborski + * plugins/digestmd5.c: Fix handling of client realm callback + (Alexey Melnikov ) + +2004-07-21 Rob Siemborski + * plugins/gssapi.c: Memory management cleanup + (Alexey Melnikov ) + +2004-07-15 Rob Siemborski + * configure.in, plugins/gssapi.c: Wrap all GSS calls + in mutexes when required by the implementation. + (based on a patch by Simon Wilkinson ) + +2004-07-06 Rob Siemborski + * plugins/digestmd5.c: Fix potential buffer overflow, call + add_to_challenge in 2 more places (Alexey Melnikov + ) + * lib/server.c, lib/saslint.h, lib/common.c: don't directly + store buffers in the params structure + * plugins/gssapi.c: Fix server side maxoutbuf calculation + (Sam Hartman ) + * plugins/gssapi.c: Use gss_wrap_size_limit on client side too + * Ready for 2.1.19 + +2004-07-01 Rob Siemborski + * Prep for 2.1.19 + +2004-06-30 Rob Siemborski + * saslauthd/auth_rimap.c: Fix Tru64 compilation problem + * plugins/sql.c: Don't leak settings variable if init fails + * utils/testsuite.c: Update for current library + * plugins/digestmd5.c: Quoting fixes for client side + (Alexey Melnikov ) + +2004-06-23 Rob Siemborski + * saslauthd/lak.c: Minor bugfixes, support %R token + (Igor Brezac ) + * plugins/otp.c: Use plugin supplied authid for mech calculations + (Alexey Melnikov ) + * lib/auxprop.c: Use getopt callback from connection context when + storing auxprops (Alexey Melnikov ) + * plugins/otp.c, plugins/srp.c, plugins/plugin_common.c: Use correct + form of userid (user@realm) when running setpass methods + (Alexey Melnikov ) + * saslauthd/configure.in: Handle LTLIBOBJS + +2004-06-18 Rob Siemborski + * plugins/NTMakefile: Remove only recognized (generated) .rc files, + not just *.rc. This will allow for plugins with own resource files. + Also corrected spelling mistake in OPENSSL (Alexey Melnikov + ) + * lib/server.c, include/sasl.h: Support for SASL_SET_CURMECH_ONLY + flag to sasl_setpass() (Alexey Melnikov ) + +2004-06-16 Ken Murchison + * lib/server.c: use more accurate errors codes for mech_permitted() + +2004-06-16 Ken Murchison + * plugins/srp.c: don't used the parsed authid for calculations + (Alexey Melnikov ) + +2004-06-16 Rob Siemborski + * Support for forwarding of GSSAPI credentials + (Morten Olsen ) + +2004-06-03 Rob Siemborski + * win32/config.mak: Remove unneeded libraries + (Alexey Melnikov ) + +2004-06-02 Rob Siemborski + * Spelling Fixes (selsky@columbia.edu) + +2004-05-27 Rob Siemborski + * SQLite support (Norikatsu Shigemura ) + * SQLite support on windows (Alexey Melnikov + ) + +2004-05-25 Ken Murchison + * plugins/digest-md5.c: use separate global contexts for client/server + +2004-05-21 Rob Siemborski + * configure.in, lib/Makefile.am: Better handling of -ldoor library + addition (only add it to base library, don't add -lpthread) + * saslauthd/auth_krb5.c: zero out the krb5_data structure + before use + +2004-05-20 Rob Siemborski + * include/sasl.h, lib/common.c, lib/saslint.h, lib/server.c: + Add SASL_APPNAME to sasl_getprop/sasl_setprop for further + compatibilty with SASL C API draft + (Alexey Melnikov ) + +2004-05-18 Ken Murchison + * plugins/digest-md5.c: made the global context a struct + containing the reauth_cache so we can NULL it after we free it + +2004-05-07 Ken Murchison + * contrib/stripplus_canonuser.patch: added + +2004-04-27 Rob Siemborski + * saslauthd/auth_shadow.c: Make thread-safe + (Steve Barber ) + +2004-04-26 Rob Siemborski + * saslauthd/auth_krb5.c: Alternate realm support for Kerberos 5 + +2004-04-16 Ken Murchison + * plugins/ntlm.c: Mac OS X fix + (Chris Ridd ) + +2004-04-14 Ken Murchison + * plugins/plain.c: don't include authzid in response unless + specified by client + +2004-03-29 Rob Siemborski + * sample/server.c: Ensure that len has a value + +2004-03-25 Rob Siemborski + * saslauthd/saslauthd-main.c: add -r option to saslauthd for combining + user and realm into user@realm (for the userid). Based on a patch + by Jeremy Rumpf . + +2004-03-17 Rob Siemborski + * lib/checkpw.c: Include errno.h when HAVE_AUTHDAEMON is defined + * doc/windows.html: Updates (Alexey Melnikov ) + +2004-03-16 Rob Siemborski + * configure.in: Properly use CMU_ADD_LIBPATH_TO for pgsql and mysql + +2004-03-10 Rob Siemborski + * lib/dlopen.c: HPUX 11 Fix (Alexey Melnikov ) + * Add sasl_version_info() (Alexey Melnikov ) + * Add a bunch of NTMakefile files to EXTRA_DIST in Makefile.am's + * Ready for 2.1.18 + +2004-03-08 Rob Siemborski + * NI_WITHSCOPEID fixes (Hajimu UMEMOTO ) - correct + Solaris 9 IPLOCALPORT/IPREMOTEPORT issue + +2004-02-24 Rob Siemborski + * acinclude.m4: move to config/libtool.m4 + * saslauthd/lak.[ch]: Added filter based group membership check + (Paul Bender , Igor Brezac ) + +2004-02-23 Rob Siemborski + * plugins/NTMakefile: Enable DO_SRP_SETPASS on windows + (Alexey Melnikov ) + * doc/windows.html: Updates + (Alexey Melnikov ) + * win32/: Add version resource info to plugins + (Alexey Melnikov ) + * plugins/digestmd5.c: Comments and other cleanup + +2004-02-20 Rob Siemborski + * lib/server.c, include/saslplug.h: Allow "temporary failure" + return values from mech_avail + * lib/canonusr.c, lib/server.c: Comment Nits + (Alexey Melnikov ) + * plugins/NTMakefile, plugins/plugin_common.h, + plugins/plugin_common.c, plugins/otp.c: build OTP on Windows + (Alexey Melnikov ) + +2004-02-19 Ken Murchison + * plugins/ntlm.c, sample/server.c, sample/client.c: + error checking of getnameinfo() (Paul Kranenburg ) + * plugins/ntlm.c: alignment and endian fixes in load_session_setup() + (Paul Kranenburg ) + +2004-02-18 Rob Siemborski + * doc/NTMakefile, NTMakefile: nmake install support + for doc/ (Alexey Melnikov ) + * plugins/digestmd5.c: Check that digest-uri is only sent once + (Alexey Melnikov ) + * utils/Makefile.am: add LIB_PGSQL to static link line + +2004-02-17 Rob Siemborski + * win32/include/config.h: caddr_t might be already defined + elsewhere (Alexey Melnikov ) + * lib/NTMakefile, include/saslutil.h: getopt might be already + defined elsewhere. The change will produce libsasl.dll which exports + getopt, buat a define can be used to prevent import of getopt from + libsasl.dll. (Alexey Melnikov ) + +2004-02-16 Rob Siemborski + * configure.in: Remove deprecated AC_PROG_RANLIB, CMU_PROG_LIBTOOL + (Patrick Welche ) + * lib/dlopen.c: OpenBSD ELF patch (J.C. Roberts) + +2004-02-06 Rob Siemborski + * lib/NTMakefile, utils/NTMakefile: fix "clean" target + (Alexey Melnikov ) + * General winsock.h -> winsock2.h conversion + (Alexey Melnikov ) + * plugins/plugin_common.h: add extern "C" wrapper + (Alexey Melnikov ) + +2004-01-23 Rob Siemborski + * Remove "experimental" designation from saslauthd/ldap + * Correct handling of sasl_setpass errors when no + mechanisms implement the setpass interface + (Alexey Melnikov ) + +2004-01-20 Rob Siemborski + * configure.in: minor sql nit (Edward Rudd ) + * lib/staticopen.h: MYSQL should be SQL + (Edward Rudd ) + +2004-01-12 Rob Siemborski + * win32/include/config.h: fix VC++ 6.0 compiles + (Alexey Melnikov ) + * configure.in: Correct use of AC_LIBOBJ, quote macro names + defined by AC_DEFUN, Use enable_shared to determine whether + to enable the shared plugin. + (Maciej W. Rozycki ) + * plugins/srp.c: Fix typos + (Maciej W. Rozycki ) + * saslauthd/configure.in: Correct use of AC_LIBOBJ + (Maciej W. Rozycki ) + +2004-01-08 Ken Murchison + * plugins/sql.c: better error logging + +2004-01-07 Rob Siemborski + * lib/checkpw.c & others: Support for Courier-IMAP authdaemond + use during password verification (Leandro Santi + ) + +2003-12-30 Rob Siemborski + * saslauthd/lak.c: Fix NULL pointer dereference + (Simon Brady ) + * saslauthd/lak.c, lak.h, LDAP_SASLAUTHD: Improved retry handler, + Improved logging/debug messages, Fixed String checks, config + option changes (Igor Brezac ) + +2003-12-22 Rob Siemborski + * plugins/digestmd5.c: Fix memory leak + (Alexey Melnikov ) + +2003-12-18 Rob Siemborski + * plugins/plugin_common.c: Fix handling of blob unwrapping + in _plug_decode + * lib/checkpw.c: Fix some file descriptor leaks during failures + in the saslauthd code. + +2003-12-15 Rob Siemborksi + * utils/saslauthd.c: Fix Typo + (Alexey Melnikov ) + * plugins/plugin_common.c: Fix potential memory leak + * lib/external.c: Limit size of authzids in EXTERNAL + * plugins/gssapi.c: Pre-init some variables + * lib/cram.c: Detect possible buffer overrun + * lib/checkpw.c: Post-fence bug + (Leandro Santi ) + +2003-12-12 Rob Siemborski + * saslauthd/lak.c: assign null to free + variables (Juan Felipe Garcia ) + * saslauthd/lak.c: Improve retry when ldap connection is reset + (1st pass) (Igor Brezac ) + +2003-12-11 Rolf Braun + * Several MacOS X Fixes + +2003-12-06 Ken Murchison + * lib/checkpw.c, lib/server.c, + plugins/cram.c, plugins/digestmd5.c, plugins/ntlm.c, + plugins/otp.c, plugins/srp.c: erase the plaintext password + property from the context when we're done with it + +2003-12-01 Ken Murchison + * doc/draft-ietf-sasl-crammd5-01.txt: added + * doc/draft-ietf-sasl-gssapi-00.txt: added + * doc/draft-ietf-sasl-plain-03.txt: added + * doc/draft-ietf-sasl-rfc2222bis-03.txt: added + * doc/draft-ietf-sasl-saslprep-04.txt: added + * doc/draft-ietf-sasl-crammd5-00.txt: deleted + * doc/draft-ietf-cat-sasl-gssapi-05.txt: deleted + * doc/draft-ietf-sasl-plain-02.txt: deleted + * doc/draft-ietf-sasl-rfc2222bis-02.txt: deleted + * doc/draft-ietf-sasl-saslprep-03.txt: deleted + * doc/index.html, doc/Makefile.am: updated to latest version of + SASL drafts + +2003-12-01 Rob Siemborski + * Fix build nit in IRIX. + * Actual 2.1.17 release. + +2003-11-28 Rob Siemborski + * Ready for 2.1.17 + +2003-11-19 Rob Siemborski + * config/kerberos_v4.m4: Disable KERBEROS_V4 support by default + +2003-11-14 Rob Siemborski + * lib/server.c: do authorization callback in sasl_checkpass() + (Chris Newman ) + +2003-11-11 Ken Murchison + * lib/client.c: allow serverFDQN to be NULL in sasl_client_new() + * plugins/digestmd5.c, gssapi.c: require that we have serverFQDN + for the client side of the plugin + +2003-11-07 Rob Siemborski + * --with-gss_impl configure option + (Alexey Melnikov ) + +2003-11-06 Rob Siemborski + * nmake install support for Win32 + (Alexey Melnikov ) + +2003-11-03 Ken Murchison + * include/saslplug.h, lib/server.c, plugins/cram.c, + plugins/digestmd5.c, plugins/ntlm.c, plugins/otp.c, + plugins/srp.c: return SASL_TRANS to the application where + appropriate (auto_transition enabled with writable auxprop) + +2003-10-30 Rob Siemborski + * saslauthd/lak.c: OpenLDAP 2.0 Compatability Fix + (Igor Brezac ) + * saslauthd/ipc_unix.c: Fix buglet of not using saved errno + value (Jeremy Rumpf ) + +2003-10-20 Rob Siemborski + * Win64 warning squashing (Alexey Melnikov ) + * GSSAPI cleanups and fixes (Alexey Melnikov ) + +2003-10-14 Rob Siemborski + * Ready for 2.1.16-BETA + +2003-10-08 Rob Siemborski + * Support for autoconf 2.57, automake 1.7 + * Minor m4 quoting fixes (Patrick Welche ) + +2003-10-07 Ken Murchison + * plugins/sql.c: removed sql_delete - don't DELETE rows from the + table, just set the properties to NULL; + fix a stupid logic error in my PgSQL changes + * doc/options.html: removed sql_delete option; clarifications + * doc/install.html: note that we require PostgreSQL v7.2+ + +2003-10-06 Ken Murchison + * plugins/sql.c: use the correct propctx in sql_auxprop_store() + +2003-10-06 Maya Nigrosh + * plugins/sql.c: tiny bugfix to begin pgsql transactions + +2003-10-04 Ken Murchison + * plugins/sql.c: only do a txn when we have a property to fetch; + _pgsql_open() cleanup/fixes; more intelligient sql_usessl parsing; + require sql_select option + * doc/options.html: reorganized SQL option descriptions + +2003-10-03 Rob Siemborski + * sasldb/allockey.c, sasldb/sasldb.h, utils/sasldblistusers.c: + Add enumeration capability to the sasldb API + (Alexey Melnikov ) + +2003-10-02 Ken Murchison + * plugins/sql.c: changed abstraction layer for transactions + +2003-10-01 Rob Siemborski + * doc/: Documentation Update + (Alexey Melnikov ) + * plugins/NTMakefile, plugins/srp.c: Win32 SRP Support + (Alexey Melnikov ) + +2003-09-30 Rob Siemborski + * plugins/digestmd5.c: Clean up some warnings + * lib/canonusr.c, win32/include/config.h, win32/common.mak, + include/saslplug.h: Minor Cleanup + (Alexey Melnikov ) + * utils/NTMakefile, utils/sasldblistusers.c, utils/saslpasswd.c: + Add version options to command line utilities + (Alexey Melnikov ) + +2003-09-29 Ken Murchison + * plugins/sql.c, doc/options.html: added sql_update and sql_delete + for a complete auxprop_store() implementation; logic cleanup + +2003-09-25 Rob Siemborski + * utils/saslpasswd.c: Win32 perror() related patch + (Alexey Melnikov ) + +2003-09-25 Ken Murchison + * plugins/sql.c: renamed sql_statement to sql_select, + cleanup and bugfixes + +2003-09-23 Rob Siemborski + * doc/gssapi.html: Misc updates + (Alexey Melnikov ) + * lib/Makefile.am, plugins/Makefile.am, saslauthd/Makefile.am, + sasldb/Makefile.am: Cleanup INCLUDES for different build + directories. (Alexey Melnikov ) + +2003-09-23 Maya Nigrosh + * plugins/sql.c: put transaction handling around the entirety of + the queries, and not just per-property; return the result status + of bad postgres tuples + +2003-09-22 Maya Nigrosh + * plugins/sql.c: added semicolon at the end of each sql statement + +2003-09-19 Maya Nigrosh + * plugins/sql.c: moved transaction handling to a more useful place, + minor bugfixes + +2003-09-18 Ken Murchison + * lib/server.c: log a message when no password change is attempted + (Alexey Melnikov ) + +2003-09-17 Ken Murchison + * plugins/sql.c: misc fixes from Patrick Welche + +2003-09-16 Ken Murchison + * doc/mechanisms.html: updated to latest versions of LOGIN and + SRP drafts + +2003-09-15 Ken Murchison + * doc/draft-ietf-sasl-rfc2222bis-02.txt: added + * doc/draft-ietf-sasl-rfc2222bis-01.txt: deleted + * doc/index.html, doc/Makefile.am: updated to latest version of + SASL draft + +2003-09-14 Ken Murchison + * plugins/ntlm.c, plugins/plugin_common.[ch]: Win32 support + (Alexey Melnikov ) + +2003-09-12 Rob Siemborski + * plugins/sql.c: Log errors on connect failures + (based on patch from Bruce M Simpson ) + * plugins/NTMakefile: Add support for GSSAPI=CyberSafe + (Alexey Melnikov ) + +2003-09-10 Maya Nigrosh + * plugins/sql.c: created generic sql store function, added + transaction handling to sql statements + * doc/options.html: put pretty new options in the documentation + +2003-09-10 Rob Siemborski + * plugins/gssapi.c, win32/config.mak, sample/: Win32 Fixes + (Alexey Melnikov ) + +2003-09-09 Rob Siemborski + * lib/NTMakefile: Minor nit + (Alexey Melnikov ) + +2003-09-09 Ken Murchison + * plugins/ntlm.c: use retry_read() instead of just read() + * lib/checkpw.c, plugins/ntlm.c, saslauthd/utils.c: + squash signed/unsigned warning + +2003-09-08 Ken Murchison + * plugins/ntlm.c: fix byte-alignment and password handling problems + +2003-09-03 Rob Siemborski + * lib/checkpw.c: Check return value of door_call + (Gary Mills ) + * saslauthd/ipc_doors.c: Implement thread limiting, + minor cleanup and error checking + (Gary Mills ) + * plugins/digestmd5.c: Fix minor interop issues, limit maxbuf + (Alexey Melnikov ) + +2003-09-02 Ken Murchison + * plugins/ntlm.c, doc/options.html: added support for NTLMv2 responses; + fixed potential buffer overflow + +2003-09-02 Rob Siemborski + * lib/common.c, lib/server.c, lib/NTMakefile, include/md5.h: + more windows compatibility + (Alexey Melnikov ) + * plugins/NTMakefile: Add ability to build NTLM plugin under + Win32 (Alexey Melnikov ) + * utils/NTMakefile: Add ability to build testsuite + (Alexey Melnikov ) + * saslauthd/lak.c: Minor error message fix + (Igor Brezac ) + +2003-08-29 Ken Murchison + * doc/draft-murchison-sasl-login-00.txt: added + * doc/draft-sasl-login.txt: deleted + * doc/index.html, doc/Makefile.am: updated to "official" LOGIN draft + +2003-08-29 Rob Siemborski + * plugins/gssapi.c: properly compute GSSAPI MAXOUTBUF + (Paul Turgyan ) + * Further Win32 cleanup + HIER_DELIMITER usage + (Alexey Melnikov ) + +2003-08-28 Rob Siemborski + * include/md5.h, lib/md5.c: Misc cleanup + (Alexey Melnikov ) + * utils/sasldblistusers.c: UI Cleanup, Win32 support + (Alexey Melnikov ) + * acconfig.h: add HIER_DELIMITER + +2003-08-27 Ken Murchison + * plugins/digestmd5.c: handle OpenSSL 0.9.7+ w/o old DES support + +2003-08-26 Ken Murchison + * plugins/ntlm.c: only send one NT/LM response to server + (NT preferred); don't use canonified authid when proxying + +2003-08-24 Ken Murchison + * plugins/ntlm.c, doc/options.html: allow NTLM authentication to + be optionally proxied to an NT server (ntlm_server option) + +2003-08-24 Ken Murchison + * lib/common.c: added support for unsigned int types in _sasl_log() + +2003-08-18 Rob Siemborski + * Improvements in Win32 build system from Alexey Melnikov + + +2003-08-14 Rob Siemborski + * doc/*: Massive documentation updates. + +2003-08-13 Ken Murchison + * doc/index.html: added reference to a CIFS (SMB/NTLM) document + +2003-08-12 Ken Murchison + * doc/index.html: added reference to a good NTLM document + +2003-07-29 Ken Murchison + * plugins/cram.c: don't truncate long secrets to 64 bytes on the + client-side of CRAM-MD5 (jiang_xiong@yahoo.com) + +2003-07-28 Rob Siemborski + * plugins/gssapi.c: another missed pointer init + (Will Fiveash ) + +2003-07-26 Rob Siemborski + * lib/server.c: Missed pointer initialization fix + ("Dave Cridland [Home]" ) + +2003-07-26 Ken Murchison + * plugins/digestmd5.c: merged privacy and integrity security layer + code and removed use of tmp buffers for security layer + +2003-07-25 Ken Murchison + * plugins/srp.c: removed use of tmp buffer for security layer; + don't make a big buffer out of iovecs when encoding + * lib/server.c, plugins/login.c, plugins/plain.c: better handling + of auto_transition -- doesn't try to transition from auxprop to + auxprop + +2003-07-25 Rob Siemborski + * configure.in: Fix up some mysql/pgsql detection + * plugins/gssapi.c: improved error reporting + (William Fiveash ) + * cmulocal/sasl2.m4, saslauthd/mechanisms.h: Improved + GSSAPI detection (don't default to MIT, require HAVE_KRB5_H + for the kerberos5 saslauthd module) + (Rainer Orth ) + +2003-07-24 Ken Murchison + * plugins/srp.c: updated security layer code to be closer to draft -08 + +2003-07-23 Rob Siemborksi + * saslauthd/utils.[ch], saslauthd/configure.in: Detect/replace + strlcpy and strlcat (based on ideas from + Igor Brezac ) + +2003-07-22 Ken Murchison + * plugins/digestmd5.c, plugins/gssapi.c, plugins/kerberos4.c, + plugins/plugin_common.[ch]: moved encoded packet buffering into + _plug_decode() + +2003-07-21 Ken Murchison + * plugins/srp.c: updated auth code to draft -08 (layers still need + to be updated) + * configure.in, plugins/srp.c: use auxprop_store() instead of + direct sasldb access + +2003-07-21 Rob Siemborski + * configure.in: add runpath information for MySQL and Postgres; + better behavior for the interaction of --enable-sql and + --with-mysql / --with-pgsql + * saslauthd/lak.[ch]: %d to be derived from %u if it can be, + otherwise use %r (to account for the recent change in the + core library). Add ldap_default_realm parameter + (Igor Brezac ) + +2003-07-18 Rob Siemborski + * plugins/digestmd5.c: Client side of digest md5 doesn't + have quotes around its cypher= directive (Bug 2113). + * saslauthd/lak.[ch]: support for ldap sasl binds, + support for tls (Igor Brezac ) + +2003-07-17 Ken Murchison + * include/sasl.h, include/saslplug.h, + * lib/auxprop.c, lib/common.c, lib/server.c, plugins/sasldb.c: + implemented writable auxprops + * configure.in, plugins/otp.c, utils/saslpasswd: use + auxprop_store() instead of direct sasldb access + * doc/options.html, lib/server.c: implemented 'noplain' option for + auto_transition + +2003-07-17 Rob Siemborski + * lib/config.c: Remove sasl_config_getint and sasl_config_getswitch + because they are unused and confusing + * lib/checkpw.c: Correctly split realm from username in + saslauthd_verify_password + +2003-07-15 Ken Murchison + * plugins/sql.c, doc/options.html: added sql_usessl option + +2003-07-15 Ken Murchison + * plugins/mysql.c: deleted + * plugins/sql.c: added + * acconfig.h, configure.in, + doc/components.html, doc/options.html, doc/sysadmin.html, + plugins/Makefile.am, plugins/makeinit.sh: deprecated MySQL plugin + in favor of a new generic SQL plugin (currently supports MySQL and + PostgreSQL) + +2003-07-15 Rob Siemborski + * Ready for 2.1.15 + +2003-07-03 Rob Siemborski + * doc/components.html: added in the hopes that this gives a better + description of how all the components interact + +2003-07-02 Ken Murchison + * doc/draft-ietf-sasl-anon-02.txt: added + * doc/draft-ietf-sasl-plain-02.txt: added + * doc/draft-ietf-sasl-saslprep-03.txt: added + * doc/draft-ietf-sasl-anon-01.txt: deleted + * doc/draft-ietf-sasl-plain-01.txt: deleted + * doc/index.html, doc/Makefile.am: updated to latest versions of + PLAIN, ANONYMOUS, SASLprep drafts + +2003-07-02 Rob Siemborski + * acconfig.h, cmulocal/sasl2.m4, plugins/gssapi.c: + Properly detect HAVE_GSS_C_NT_USER_NAME + (Rainer Orth ) + +2003-07-01 Rob Siemborski + * plugins/kerberos4.c: Fix some maxoutbuf handling issues + +2003-07-01 Rob Siemborski + * plugins/mysql.c: Check return value of mysql_init + (Ivan Kelly ) + +2003-07-01 Ken Murchison + * doc/draft-burdis-cat-srp-sasl-08.txt: added + * doc/draft-ietf-sasl-rfc2222bis-01.txt: added + * doc/draft-ietf-sasl-rfc2831bis-02.txt: added + * doc/draft-burdis-cat-srp-sasl-06.txt: deleted + * doc/draft-ietf-sasl-rfc2222bis-00.txt: deleted + * doc/draft-ietf-sasl-rfc2831bis-01.txt: deleted + * doc/index.html, doc/Makefile.am: updated to latest versions of + SASL, SRP, DIGEST-MD5 drafts + +2003-06-30 Rob Siemborski + * plugins/mysql.c: Call mysql_init() too + (Hajimu UMEMOTO ) + +2003-06-28 Rob Siemborski + * doc/sysadmin.html: Add more text about how to use realms. + +2003-06-27 Rob Siemborski + * Ready for 2.1.14 + +2003-06-11 Rolf Braun + * config/kerberos_v4.m4: + fix fallback to -lkrb4 when --enable-krb4 is specified + * config/ltconfig: + * config/ltmain.sh: + make the darwin libtool work on OS X v10.2 + (bash/zsh shell syntax, and don't link bundles with extra args) + * dlcompat-20010505/dlopen.c: back out bogus delimiter change + * doc/macosx.html: update for 10.2 and add known problems section + * mac/osx_cfm_glue/cfmglue.c: fix sasl_done followed by client_init + +2003-06-11 Rob Siemborski + * man/sasl_client_new.3, man/sasl_server_new.3: + Security flags don't belong here, connection flags do. + +2003-06-10 Ken Murchison + * doc/draft-ietf-sasl-crammd5-00.txt: added + * doc/draft-nerenberg-sasl-crammd5-03.txt: deleted + * doc/index.html, doc/Makefile.am: updated to WG version of + CRAM-MD5 draft + +2003-05-30 Rob Siemborski + * plugins/gssapi.c: If we get an empty output token back + from gss_accept_sec_context, return + an empty string to transmit to the client. + +2003-05-30 Ken Murchison + * doc/draft-ietf-sasl-rfc2831bis-01.txt: added + * doc/draft-ietf-sasl-rfc2831bis-00.txt: deleted + * doc/index.html, doc/Makefile.am: updated to latest version of + DIGEST-MD5 draft + +2003-05-28 Ken Murchison + * doc/draft-ietf-sasl-anon-01.txt: added + * doc/draft-ietf-sasl-plain-01.txt: added + * doc/draft-ietf-sasl-rfc2222bis-00.txt: added + * doc/draft-ietf-sasl-anon-00.txt: deleted + * doc/draft-ietf-sasl-plain-00.txt: deleted + * doc/draft-myers-saslrev-02.txt: deleted + * doc/index.html, doc/Makefile.am: updated to latest versions of + SASL, PLAIN, ANONYMOUS drafts + +2003-05-21 Rob Siemborski + * saslauthd/ipc_unix.c: Accept File Descriptor Locking + Fixes (found by Leena Heino ) + * saslauthd/cache.c: Similar fixes + (Jeremy Rumpf ) + +2003-05-15 Rob Siemborski + * configure.in: Actually listen to --disable-java + (Maciej W. Rozycki ) + * saslauthd/saslauthd-main.h: Increase listen backlog to + match Cyrus master process (Igor Brezac ) + +2003-05-14 Rob Siemborski + * config/kerberos_v4.m4: Minor nit + (Carlos Velasco ) + * plugins/gssapi.c: Use GSS_C_NT_USER_NAME + to work around Solaris 8/9 libgss bug. + (gssapi_client_mech_step): Pass GSS_C_NO_BUFFER to first + invocation of gss_init_sec_context to work around Solaris 8/9 + mech_krb5 bug. (Rainer Orth ) + * cmulocal/sasl2.m4: Check for Sun SEAM GSS-API implementation + (Rainer Orth ) + * saslauthd/configure.in: Check for krb5.h. Don't define if GSSAPI + is present. (Rainer Orth ) + * saslauthd/mechanisms.h: Test for HAVE_KRB5_H instead of HAVE_GSSAPI_H + to activate AUTH_KRB5. (Rainer Orth ) + * plugins/mysql.c: Use mysql_real_connect() instead of mysql_connect() + (Petri Riihikallio ) + * saslauthd/: Misc ANSI C cleanups (Jeremy Rumpf ) + +2003-05-13 Rob Siemborski + * config/sasldb.m4, utils/Makefile.am: fix installation of man + pages that are homed in the utils/ directory + * include/*.h: Add extern "C" blocks for C++ compiles + +2003-05-06 Rob Siemborski + * saslauthd/saslauthd-main.c: misc spelling and UI cleanups + +2003-04-16 Rob Siemborski + * saslauthd/saslauthd-main.c: Don't set the auth mech until + all options have been processed. (Peter Stamfest ) + * lib/client.c, lib/common.c, lib/saslint.h, lib/server.c: Do + reference counting of the number of times sasl has been inited/doned. + +2003-04-15 Rob Siemborski + * config/ltmain.sh: fix some portability problems in the use of expr + (Oliver Eikemeier ) + +2003-04-14 Rob Siemborski + * Ready for 2.1.13 + +2003-04-08 Rob Siemborski + * lib/external.c, lib/server.c: use mech_avail to disable + EXTERNAL instead of special casing it (Chris Newman + ) + +2003-03-31 Rob Siemborski + * saslauthd/ipc_unix.c, saslauthd/saslauthd-main.c, + saslauthd/saslauthd-main.h: use the pidfile locking from + the Cyrus IMAPd master process (implemented for saslauthd by + Igor Brezac ) + * configure.in, acconfig.h: Add configure option to set what + we use for /dev/random + +2003-03-28 Rob Siemborski + * saslauthd/: Unify the source files so that the IPC methods + are broken out into a separate API. Cacheing of authentication + credentials is also available as a command-line option. + Other changes include: Remove Time of Day Flag, omit + SO_REUSEADDR on AF_UNIX sockets, make using the accept-socket + locking runtime configurable, and misc other cleanup. + (Jeremy Rumpf ) + +2003-03-26 Rob Siemborski + * plugins/plain.c: Defend against memory leak on canon_user + failure (Chris Newman ) + +2003-03-19 Rob Siemborski + * lib/auxprop.c, lib/checkpw.c, lib/common.c, lib/saslutil.c, + lib/server.c: Assorted minor fixes from Sun Microsystems + (provided by Chris Newman ) + +2003-03-13 Rob Siemborski + * saslauthd/lak.c: Fix a memset length. (Igor Brezac ) + +2003-03-06 Rob Siemborski + * plugins/digestmd5.c: fix parity of digest-uri test + * lib/client.c, common.c, saslint.h, server.c: Pass global + callbacks to global utils structure + (Howard Chu ) + * saslauthd/auth_krb5.c: Fix memory/file descriptor leak + in krb5 authentication (Jonathen Chen ) + * saslauthd/lak.c, lak.h, LDAP_SASLAUTHD: Remove ldap_cache + code, and rename MAX() to LAK_MAX() + +2003-02-20 Ken Murchison + * doc/draft-ietf-sasl-rfc2831bis-00.txt: added + * doc/draft-melnikov-rfc2831bis-02.txt: deleted + * doc/draft-newman-sasl-c-api-01.txt: added + * doc/draft-newman-sasl-c-api-00.txt: deleted + * doc/index.html: updated to WG version of DIGEST-MD5 draft, + updated to latest C API draft + * doc/Makefile.am: updated to WG version of DIGEST-MD5 draft, + updated to latest C API draft + +2003-02-12 Lawrence Greenfield + * plugins/digestmd5.c: verify the service component of digest-uri + +2003-02-11 Ken Murchison + * doc/draft-ietf-sasl-anon-00.txt: added + * doc/draft-ietf-sasl-plain-00.txt: added + * doc/draft-zeilenga-sasl-anon-01.txt: deleted + * doc/draft-zeilenga-sasl-plain-01.txt: deleted + * doc/index.html: updated to WG versions of ANONYMOUS, PLAIN drafts + +2003-02-03 Rob Siemborski + * cmulocal/sasl2.m4: Don't use -ldes to check for Heimdal + * saslauthd/auth_krb4.c, saslauthd/auth_shadow.c, + saslauthd/auth_getpwent.c, lib/kerberos4.c: + Smarter checking of #includs for des.h + (Mark Keasling ) + * saslauthd/testsaslauthd.c, saslauthd/saslauthd-doors.c: + retry_read() should use a char * buffer not a void * + buffer (Mark Keasling ) + * cmulocal/berkdb.m4: Set CPPFLAGS around tests + (based on patch from Leena Heino ) + * config/sasldb.m4: Actually use results of Berkeley DB tests + (Leena Heino ) + * Ready for 2.1.12 + +2003-01-31 Rob Siemborski + * Ready for 2.1.11 + * utils/Makefile.am: Ensure that dbconverter-2 can see the sasldb + include directory. + +2003-01-29 Rob Siemborski + * plugins/digestmd5.c: Fix a situation where the realm wasn't + being set for the client context, causing a segfault + * config/kerberos_v4.m4: first check des_* then check DES_* + during OpenSSL tests (based on ideas from + Leena Heino ) + +2003-01-28 Rob Siemborski + * config/sasldb.m4: Don't build sasldb plugin if compiling + --with-dblib=none, since it will only fail to load anyway. + +2003-01-27 Rob Siemborski + * saslauthd/configure.in: use CMU_ADD_LIBPATH for LDAP support + (Simon Brady ) + +2003-01-23 Rob Siemborski + * saslauthd/acconfig.h: protect file from being included more than + once (reported by Jeremy Rumpf ) + * saslauthd/configure.in, configure.in: Move OpenSSL detection into + cmulocal, detect openssl for use with lak.c + +2003-01-21 Ken Murchison + * plugins/ntlm.c: only _require_ one response (LM and/or NT), not both + +2003-01-09 Rob Siemborski + * saslauthd/lak.c, saslauthd/lak.h: Add the fastbind auth method + (Simon Brady ) + +2003-01-01 Ken Murchison + * saslauthd/configure.in, saslauthd/Makefile.am: don't make + -lcrypt dependent upon --enable-plain + +2002-12-11 Ken Murchison + * plugins/otp.c: set SASL_FEAT_ALLOWS_PROXY on client side + +2002-12-10 Ken Murchison + * plugins/otp.c: explicitly #include to resolve + OpenBSD/OpenSSL cruftiness + +2002-12-10 Rob Siemborksi + * saslauthd/saslauthd-doors.c: Fix a potential memory leak when + we call door_return() + +2002-12-09 Rob Siemborski + * lib/auxprop.c: Correct leak in prop_clear, also update list_end + in prop_request. + * doc/options.html: Update use of saslauthd_path to be correct + +2002-12-06 Rob Siemborski + * Ready for 2.1.10 + +2002-12-05 Larry Greenfield + * plugins/digestmd5.c: DES key fixes. stupid DES libraries want + the key in the stupid DES parity format. + * plugins/digestmd5.c: refactored some of the cipher code so that + there isn't RC4 state around when we're using DES and vice versa + +2002-12-05 Rob Siemborski + * saslauthd/lak.c: Allocate a large enough buffer to account for + a completely escaped username. (lak_escape and lak_filter) + * lib/common.c: Ensure there is enough space for the trailing \0 + in _sasl_log + +2002-12-04 Rob Siemborski + * lib/canonusr.c: Check for potential buffer overflow + +2002-12-03 Ken Murchison + * plugins/digestmd5.c: major fast reauth rewrite, mech_step cleanup + * doc/options.html: server-side reauth is disabled by default + +2002-11-24 Ken Murchison + * plugins/login.c: allow authid to be passed in initial response + * doc/draft-sasl-login.txt, doc/mechanisms.html: + documentation updates re: initial response + +2002-11-07 Ken Murchison + * doc/draft-nerenberg-sasl-crammd5-03.txt: added + * doc/draft-nerenberg-sasl-crammd5-02.txt: deleted + * doc/draft-zeilenga-sasl-anon-01.txt: added + * doc/draft-zeilenga-sasl-anon-00.txt: deleted + * doc/draft-zeilenga-sasl-plain-01.txt: added + * doc/draft-zeilenga-sasl-plain-00.txt: deleted + * doc/index.html: updated to latest CRAM-MD5, ANONYMOUS, PLAIN drafts + +2002-11-01 Rob Siemborski + * plugins/kerberos4.c: Make at most 1 canon_user call, not two. + (Howard Chu ) + +2002-10-25 Rob Siemborski + * saslauthd/lak.c: minor cleanups + +2002-10-24 Rob Siemborski + * saslauthd/lak.c: fix problem where saslauthd stops LDAP + authentications when ldap_auth_method is bind. + (Igor Brezac ) + * doc/sysadmin.html, doc/options.html, saslauthd/saslauthd.mdoc: + documentation updates re: saslauthd mux path + +2002-10-23 Ken Murchison + * lib/external.c: added SASL_SEC_NOANONYMOUS to client side + (Howard Chu, ) + +2002-10-21 Ken Murchison + * plugins/ntlm.c: NTLM probably doesn't offer perfect forward secrecy + * doc/mechanisms: added table of properties/features + +2002-10-20 Ken Murchison + * saslauthd/lak.ch: consolidated hashed password checking code + +2002-10-18 Rob Siemborski + * saslauthd/lak.[ch], saslauthd/auth_ldap.c: + Code cleanup, now support {SHA}, {SSHA}, {MD5}, and {SMD5} hashes, + misc other cleanup. (Igor Brezac and + Thomas Lussnig ) + +2002-10-17 Ken Murchison + * doc/draft-melnikov-rfc2831bis-02.txt: added + * doc/draft-melnikov-rfc2831bis-01.txt: deleted + * doc/index.html: updated to latest RFC 2831bis draft + +2002-10-11 Rob Siemborski + * lib/Makefile.am: add missing staticopen.h to EXTRA_DIST, + fix some dependencies + * Ready for 2.1.9 + +2002-10-10 Rob Siemborski + * Ready for 2.1.8 + +2002-10-09 Rob Siemborski + * lib/client.c: Allow plaintext mechanisms under an external security + layer. + +2002-10-07 Rob Siemborski + * sample/server.c: Fix some IPV6 defines + (Marshall Rose ) + +2002-10-02 Ken Murchison + * lib/checkpw.c: return SASL_NOUSER when we can't find APOP secret + * lib/server.c: plug APOP memory leak and consolidate canonification + * configure.in: force the use of a cache file + (Carlos Velasco ) + +2002-10-02 Rob Siemborski + * lib/checkpw.c: Fix some misuses of sasl_seterror + (Martin Exler ) + +2002-09-24 Rob Siemborski + * config/sasl2.m4, saslauthd/Makefile.am: GSSAPI doesn't need + to link ndbm. Also cleanup some sasldb linking in saslauthd. + +2002-09-23 Rob Siemborski + * config/kerberos_v4.m4: Don't compile with kerberos unless we + have both the libs and the headers (Carlos Velasco + ) + +2002-09-19 Rob Siemborski + * plugins/gssapi.c: endinaness corrections + * sasldb/db_berkeley.c, utils/dbconverter-2.c: Berkley DB 4.1 + support (Mika Iisakkila ) + +2002-09-19 Ken Murchison + * plugins/plugin_common.[ch]: make SASL_CB_USER and result optional + * plugins/anonymous.c: use SASL_CB_USER for fetching trace info, + don't require SASL_CB_AUTHNAME + * plugins/gssapi.c, plugins/kerberos.c: don't require SASL_CB_USER + * lib/external.c: define SASL_FEAT_ALLOWS_PROXY for this mechanism, + don't require SASL_CB_USER + +2002-09-18 Rob Siemborski + * plugins/srp.c, plugins/kerberos4.c: correct maxoutbuf handling + * plugins/digestmd5.c: correct maxoutbuf handling, actually + send maxbuf to the remote. + * lib/common.c: sanity check security properties + +2002-09-17 Ken Murchison + * plugins/ntlm.c: home-grown client/server NTLM implementation + * configure.in: NTLM depends on OpenSSL libcrypto + * doc/sysadmin.html: added NTLM blurb + +2002-09-16 Rob Siemborski + * lib/canonusr.c: don't index begin_u with -1 + (Randy Kunkee ) + * doc/sysadmin.html: cleanup + * utils/saslpasswd.c: don't exit with -SASL_FAIL + * saslauthd/saslauthd-unix.c: use a char* instead of a void* in + retry_read + +2002-09-12 Ken Murchison + * lib/common.c: NULL outbuf if we get no output from sasl_decode() + +2002-09-11 Rob Siemborski + * plugins/mysql.c: Actually loop through the potential servers + properly (Seow Kok Heng ) + * acinclude.m4: Added copy of the correct libtool macros as + acinclude.m4 + * configure.in: fix for gcc 3.x + (Carlos Velasco ) + +2002-09-10 Rob Siemborski + * lib/server.c: Better handling of add_plugin failures + +2002-09-10 Ken Murchison + * acconfig.h, configure.in: enable/disable NTLM + * lib/staticopen.h, plugins/Makefile.am, makeinit.sh, ntlm.c: + added NTLM support (client-side only) + +2002-09-07 Rob Siemborski + * saslauthd/configure.in, saslauthd/Makefile.am: don't + do configure substitutions for the saslauthd_SOURCES variable + (Carlos Velasco ) + +2002-09-05 Rob Siemborski + * doc/os390.html: added + * doc/index.html: referenced os390.html and macosx.html + * lib/Makefile.am: better handling of plugin_common + +2002-09-04 Rob Siemborski + * (throughout) Extensive cleanup of how we build static and + shared versions of libsasl. Also some more portability + fixes (Howard Chu ) + +2002-09-04 Rob Siemborski + * acconfig.h, configure.in: Actually check for sysexits.h, + varargs.h, and stdarg.h + * lib/checkpw.c: compatibility patch for retry_read + (Howard Chu ) + +2002-09-03 Rob Siemborski + * (throughout) fix handling of sys/param.h + * (throughout) fix handling of time.h and sys/time.h + * include/exits.h: include a replacement for sysexits.h + * acconfig.h: define MAXHOSTNAMELEN if it isn't + * lib/getaddrinfo.c, config/ipv6.m4: minor fixes for partial + getaddrinfo/getnameinfo implementations + * (Above changes are all from or based on ideas from + Howard Chu ) + +2002-08-28 Rob Siemborski + * lib/client.c, lib/saslint.h: Properly handle client-side + serverFQDN and clientFQDN + +2002-08-19 Rob Siemborski + * lib/dlopen.c: use correct paths when a .la file is not present + (Justin Gibbs ) + +2002-08-13 Rob Siemborski + * doc/sysadmin.html: fix some /usr/lib/sasl references to + /usr/lib/sasl2 (Andrew Jones ) + +2002-08-09 Rob Siemborski + * saslauthd/Makefile.am: fix small parts of the saslauthd.8 build + process. + * Ready for 2.1.7 + +2002-08-06 Ken Murchison + * plugins/digestmd5.c: disable/remove server-side fast reauth + +2002-08-02 Rob Siemborski + * include/sasl.h, lib/common.c: Add SASL_AUTHUSER as a parameter + to sasl_getprop + +2002-08-01 Rob Siemborski + * saslauthd/lak.c: allow use of more than one %u or %r in the filter + (Laurent Larquère ) + +2002-07-30 Rob Siemborski + * lib/client.c, lib/server.c: Add checks for SASL_NEED_PROXY and + SASL_FEAT_ALLOWS_PROXY + * include/sasl.h, include/saslplug.h: Add SASL_NEED_PROXY and + SASL_FEAT_ALLOWS_PROXY + * plugins/digestmd5.c, plugins/gssapi.c, plugins/kerberos4.c, + plugins/otp.c, plugins/plain.c, plugins/srp.c: define + SASL_FEAT_ALLOWS_PROXY for these mechanisms + +2002-07-27 Rob Siemborski + * saslauthd/auth_sasldb.c: Include mechanisms.h in a reasonable place. + +2002-07-24 Rob Siemborski + * saslauthd/Makefile.am: Fix DEFS to still supply -I. and -I.. + * configure.in: Make --with-ldap show up in top level configure script, + make saslauthd compile by default + * lib/saslutil.c: use read() and not fread() on /dev/random to preserve + entropy + * doc/sysadmin.html: Add note about using /dev/urandom + +2002-07-19 Rob Siemborski + * doc/sysadmin.html, doc/readme.html, doc/upgrading.html: + Misc. documentation cleanup (Joe Rhett ) + +2002-07-17 Ken Murchison + * lib/canonusr.c: update length of user string to length of output + from callback + +2002-07-16 Rob Siemborski + * plugins/cram.c: Fix a security problem in the verification of + the digest string. (Andrew Jones ) + * Ready for 2.1.6 + +2002-07-06 Rob Siemborski + * plugins/mysql.c: Further memory management cleanup. (never + strdup the options, and therefore don't free staticly allocated + strings) + * man/sasl_getopt_t.3: Clarify semantics of memory management + +2002-07-05 Rob Siemborski + * saslauthd/lak.c: Better handling of downed ldap servers + (Igor Brezac ) + * sasldb/db_berkeley.c, utils/dbconverter-2.c: Use db_strerror() + rather than strerror() for Berkeley DB error values. + (J.H.M. Dassen (Ray) ) + * saslauthd/Makefile.am, saslauthd/auth_ldap.c: don't + hardwire the saslauthd conf file + (J.H.M. Dassen (Ray) ) + +2002-07-03 Rob Siemborski + * man/sasl_user_exists.3: fix sasl_idle reference + +2002-07-02 Rob Siemborski + * lib/auxprop.c: Can now select multiple auxprop plugins + * doc/options.html: updated for above + * lib/client.c: improve mechanism selection to include + number of security flags + +2002-06-27 Ken Murchison + * doc/draft-zeilenga-sasl-plain-00.txt: added + * doc/index.html: added PLAIN draft + +2002-06-26 Ken Murchison + * doc/draft-zeilenga-sasl-anon-00.txt: added + * doc/index.html: added ANONYMOUS draft + +2002-06-20 Rob Siemborski + * lib/auxprop.c: Make "cound not find auxprop plugin" warning + log at LOG_DEBUG + +2002-06-19 Rob Siemborski + * plugins/digestmd5.c: create layer keys for integrity as + well as privacy + * saslauthd/auth_ldap.[ch], saslauthd/lak.[ch]: + Large rewrite (Igor Brezac ) + * lib/client.c, lib/server.c, lib/common.c: + Actually set most of the sparams and cparams structures + +2002-06-19 Ken Murchison + * doc/draft-melnikov-rfc2831bis-01.txt: added + * doc/draft-melnikov-rfc2831bis-00.txt: deleted + * doc/index.html: updated to latest RFC 2831bis draft + +2002-06-18 Ken Murchison + * doc/draft-nerenberg-sasl-crammd5-02.txt: added + * doc/draft-nerenberg-sasl-crammd5-01.txt: deleted + * doc/index.html: updated to latest CRAM-MD5 draft + +2002-06-17 Rob Siemborski + * plugins/login.c, plugins/plain.c: Canonicalize username before + doing checkpass + +2002-06-14 Rob Siemborski + * lib/client.c, lib/server.c, lib/saslint.h, lib/common.c. + lib/seterror.c: continued size_t vs unsigned cleanups + +2002-06-13 Rob Siemborski + * saslauthd/ : remove LDAP support + * Ready for 2.1.5 + +2002-06-12 Rob Siemborski + * plugins/digestmd5.c: rename get_realm to get_server_realm, and + pay attention to its return value + * lib/external.c, lib/seterror.c: cleanup size_t/unsigned confusion + +2002-06-10 Rob Siemborski + * sasldb/Makefile.am: fix handling of allockey (only include it once) + * plugins/kerberos4.c: fix a reference count leak + * Ready for 2.1.4 + +2002-05-28 Rob Siemborski + * saslauthd/LDAP_SASLAUTHD, saslauthd/saslauthd.mdoc: + Update documentation for LDAP and Saslauthd as per + Igor Brezac + +2002-05-22 Lawrence Greenfield + * lib/checkpw.c: close door file descriptor in + saslauthd_verify_password + +2002-05-21 Rob Siemborski + * saslauthd/auth_krb5.c: fix a leak due to not + calling krb5_cc_destroy on failure + +2002-05-17 Rob Siemborski + * saslauthd/saslauthd-*.c: support a generic mechanism option -O + instead of -H + * saslauthd/auth_ldap.c, lak.c, et. al: auth_ldap overhaul + (Igor Brezac ) + * lib/common.c, include/sasl.h: add sasl_version + +2002-05-13 Rob Siemborski + * lib/checkpw.c: use "*cmusaslsecretPLAIN" in auxprop_verify_password + (Howard Chu, ), also only make a single + canon_user call. + +2002-05-13 Ken Murchison + * plugins/plugin_common.c: set the return code to SASL_FAIL, and + NULL the results of the _plug_get_*() functions before we get + started + * plugins/digestmd5.c, otp.c, plain.c, srp.c: check for NULL or + empty authzid from callback + +2002-05-09 Rob Siemborski + * saslauthd/configure.in: --with-ldap now takes a path + +2002-05-08 Rob Siemborski + * saslauthd/acconfig.h, auth_ldap.c, configure.in, lak.c, lak.h: + Misc compile/portability fixes (mostly header-related) + * utils/testsuite.c: minor getopt() parameter fix + (Claus Assmann ) + * lib/checkpw.c: fix some warnings + +2002-05-07 Rob Siemborski + * Ready for 2.1.3-BETA + +2002-05-06 Rob Siemborski + * include/saslplug.h: add name member for canon_user plugins + * lib/canonusr.c: use name member + +2002-05-06 Ken Murchison + * plugins/digestmd5.c: added client-side reauth + +2002-05-05 Ken Murchison + * lib/client.c: pass global_context to mech_new() + * lib/server.c: don't free global_context (the plugin should free it) + * utils/testsuite: swapped serverlast tests so that the + descriptions are correct + +2002-05-03 Ken Murchison + * plugins/digestmd5.c: added server-side reauth + * doc/index.html: added Marshall Rose's SASL papers + * doc/options.html: added 'reauth_timeout' + +2002-05-03 Rob Siemborski + * plugins/kerberos4.c: fix compile errors + * config/kerberos_v4.m4, plugins/digestmd5.c: fix des_cbc_encrypt + interoperability problem (OpenSSL) + * saslauthd/Makefile.am, acconfig.h, auth_ldap.c, auth_ldap.h, + configure.in, lak.c, lak.h, mechanisms.c, mechanisms.h, + saslauthd.conf: added experimental LDAP saslauthd module + (by Igor Brezac ) + * include/saslplug.h: give auxprop plugins a name + * plugins/sasldb.c: give sasldb plugin a name + * lib/auxprop.c: allow auxprop selection + * doc/options.html: document auxprop_plugin option + +2002-05-01 Ken Murchison + * plugins/digestmd5.c, gssapi.c, kerberos4.c, srp.c: + general plugin cleanup - standardizing structure + +2002-04-30 Rob Siemborski + * plugins/gssapi.c: Minor cleanup of struct hack in context structure + +2002-04-30 Ken Murchison + * plugins/plugin_common.[ch], anonymous.c, cram.c, login.c, otp.c, + plain.c, sasldb.c, srp.c, + lib/client.c, external.c, saslint.h, server.c: general plugin + cleanup - reusing more common code, standardizing structure + +2002-04-28 Ken Murchison + * plugins/plugin_common.[ch], anonymous.c, cram.c, digestmd5.c, + gssapi.c, kerberosv4.c, login.c, otp.c, plain.c, srp.c, + lib/external.c:finalize movement of callback/interaction stuff + into plugin_common + +2002-04-27 Ken Murchison + * plugins/plugin_common.[ch], anonymous.c, cram.c, digestmd5.c, + gssapi.c, kerberosv4.c, login.c, otp.c, plain.c, srp.c, + lib/external.c: move make_prompts stuff into plugin_common + * utils/testsuite.c: allow for testing of EXTERNAL + +2002-04-26 Rob Siemborski + * sasldb/allockey.c: be sure to set userPassword and not *userPassword + +2002-04-26 Ken Murchison + * lib/client.c, server.c: check 'doneflag' just before mech_step() + * plugins/plugin_common.[ch], anonymous.c, cram.c, digestmd5.c, + gssapi.c, kerberosv4.c, login.c, otp.c, plain.c, srp.c, + lib/external.c, Makefile.am: move callback/interaction stuff + into plugin_common + * plugins/plugin_common.[ch], digestmd5.c, gssapi.c, + kerberosv4.c, srp.c: move decode/concatenation of multiple + packets into plugin_common + * utils/testsuite.c: set SASL_AUTH_EXTERNAL so we can test EXTERNAL + +2002-04-25 Ken Murchison + * plugins/otp.c: don't free the secret when we get data from a + callback (and don't copy it) + * plugins/gssapi.c, plain.c: make sure to set 'doneflag' when done + * lib/client.c, server.c: don't call mech_step() if 'doneflag' is set + +2002-04-24 Rob Siemborski + * plugins/cram.c, digestmd5.c, login.c, plain.c, srp.c: don't + free the secret when we get data from a callback (and don't copy it) + +2002-04-22 Rob Siemborski + * include/gai.h: Fix for compatibility with older glibc versions + (Howard Chu, ) + * plugins/gssapi.c: Don't always send authzid on client side + (Howard Chu, ) + +2002-04-18 Rob Siemborski + * saslauthd/auth_sasldb.c: Use "use_realm" instead of "realm" + for lookup of secret. (Jonas Oberg ) + * plugins/gssapi.c: Correct handling of client-side authid and + authzid (Howard Chu, ) + * lib/external.c: Better handling of user canonicalization + (Howard Chu, ) + * plugins/cram.c, digestmd5.c, gssapi.c, kerberos4.c, + login.c, otp.c, plain.c, srp.c: zero out prompt_need structures + before use + +2002-04-17 Rob Siemborski + * plugins/cram.c, digestmd5.c, srp.c: Adjust cmusaslsecretFOO to + *cmusaslsecretFOO + * plugins/sasldb.c: correctly handle *(property) + * lib/canonusr.c, server.c: Lookup authzid and authid auxprops + correctly (and in the same place). + * include/sasl.h, saslplug.h: Fix auxprop lookups + (e.g. SASL_AUXPROP_AUTHZID) + +2002-04-15 Rob Siemborski + * plugins/gssapi.c: Handle null authzid's correctly + * lib/server.c: fix a strcmp() that should be a memcmp() + +2002-04-15 Rob Siemborski + * plugins/gssapi.c: fix how name_token and name_without_realm are + freed. + +2002-04-12 Ken Murchison + * doc/draft-melnikov-rfc2831bis-00.txt: added + * doc/draft-myers-saslrev-02.txt: moved TOC + * doc/draft-myers-saslrev-02.txt: added + * doc/draft-myers-saslrev-01.txt: deleted + * doc/index.html: changed link to updated saslrev draft, + added KERBEROS_V4 notation, + added link to rfc2831bis draft + +2002-04-08 Ken Murchison + * lib/server.c, doc/options.html: allow multiple pwcheck_methods + +2002-04-03 Rob Siemborski + * saslauthd/configure.in: properly define AUTH_KRB5 + * saslauthd/auth_krb5.c: changes for MIT KRB5 + +2002-03-27 Rob Siemborski + * Removed check for db3/db.h (people can just use --with-bdb-incdir) + +2002-03-26 Rob Siemborski + * Ready for 2.1.2 + +2002-03-11 Rob Siemborski + * plugins/kerberos4.c: Fix a race condition during mutex allocation + +2002-03-04 Rob Siemborski + * lib/checkpw.c: Stop logging "authentication failed" message + * plugins/gssapi.c: Reduce log level of "gss_accept_context" message + +2002-02-27 Rob Siemborski + * saslauthd/saslauthd.mdoc: Clarify that sasldb with saslauthd + is not what you want to be doing. + * doc/sysadmin.html: Update "sasldb" verifier to "auxprop" + +2002-02-22 Rob Siemborski + * lib/checkpw.c: made retry_read static + +2002-02-21 Rob Siemborski + * lib/checkpw.c (auxprop_verify_password) report SASL_NOUSER instead + of SASL_FAIL. + * lib/client.c, lib/server.c: More Complete returning of SASL_NOTINIT + * utils/testsuite.c: Better checking for SASL_NOTINIT + +2002-02-11 Ken Murchison + * plugins/srp.c: removed OpenSSL 0.9.6 dependencies, small bugfix + * configure.in: cleaned up OpenSSL (libcrypto) check + +2002-02-05 Rob Siemborski + * contrib/tclsasl: Add Marshall Rose's + tclsasl patch. + * plugins/anonymous.c: No longer append extra NUL to client response + +2002-02-04 Rob Siemborski + * utils/saslpasswd.c: Added -n option (Ken Murchison) + * lib/dlopen.c: Removed confusing entry point message. + * Ready for 2.1.1 + +2002-02-01 Ken Murchison + * plugins/srp.c: fixed srp_setpass() + +2002-01-31 Ken Murchison + * include/sasl.h, lib/server.c, + plugins/digestmd5.c, gssapi.c, kerberos4.c, srp.c: + added SASL_SEC_MUTUAL_AUTH + * plugins/srp.c: cleanup error messages and return codes + +2002-01-30 Ken Murchison + * plugins/otp.c, plugins/otp.h: added non-OPIE client/server + implementation (requires OpenSSL) + * configure.in: OTP now requires OpenSSL, OPIE is optional + * doc/options.html, doc/readme.html, doc/sysadmin.html, doc/TODO: + updated for new OTP implementation + +2002-01-25 Rob Siemborski + * saslauthd/Makefile.am: Correct multiple EXTRA_DIST bug + * saslauthd/Makefile.am: small typo fixed (Leena Heino ) + +2002-01-23 Rob Siemborski + * utils/dbconverter-2.c (main): More intelligent default paths + * acconfig.h: #ifndef's for _GNU_SOURCE (Assar ) + +2002-01-22 Rob Siemborski + * lib/common.c: Complete definition of sasl_global_listmech + (from Love ) + * lib/client.c: added checks for _sasl_client_active to + sasl_client_new and sasl_client_start + +2002-01-21 Ken Murchison + * doc/draft-myers-saslrev-01.txt: moved TOC + * doc/draft-ietf-cat-sasl-gssapi-05.txt: moved TOC + * doc/draft-nerenberg-sasl-crammd5-01.txt: added + * doc/draft-nerenberg-sasl-crammd5-00.txt: deleted + * doc/index.html: changed link to updated draft + * plugins/login.c (login_client_mech_step): fix client-first + handling + +2002-01-21 Rob Siemborski + * lib/server.c (sasl_server_start): null out *serverout and + *serveroutlen, just in case. + * lib/external.c: Added correct required_prompts + * saslauthd/testsaslauthd.c: Added simple saslauthd client + * saslauthd/Makefile.am: rules for testsaslauthd + * doc/sysadmin.html: updated to reference testsaslauthd + * saslauthd/saslauthd.c: allow -n 0 (for fork-per-connection) + * saslauthd/saslauthd.mdoc: documentation of -n 0 + * plugins/cram.c (crammd5_client_mech_step): fix client-first + handling + * sasldb/db_gdbm.c: improved error reporting + (Courtesy Marshall T. Rose + * config/sasldb.m4: improved gdbm configure handling + (Courtesy Marshall T. Rose + * config/kerberos_v4.m4: Detect OpenSSL libdes first. + (Courtesy Marshall T. Rose + * plugins/cram.c, digestmd5.c, kervberos4.c, login.c, + lib/client.c, server.c, include/saslplug.h: + Cleaner client-first ABI. + +2002-01-19 Ken Murchison + * plugins/otp.c: set serverout to NULL where we have nothing to + send instead of the empty string + * plugins/srp.c: let glue code handle client-last/server-last + situation by setting serverout appropriately + +2002-01-19 Rob Siemborski + * plugins/plain.c, plugins/login.c, plugins/digestmd5.c: + set serverout to NULL where we have nothing to send instead of + the empty string + * include/saslplug.h, lib/client.c, lib/server.c: eliminated + SASL_FEAT_WANT_SERVER_LAST in favor of clever setting of serverout + * plugins/digestmd5.c: removed SASL_FEAT_WANT_SERVER_LAST + +2002-01-18 Ken Murchison + * plugins/srp.c: updated to draft-burdis-cat-srp-sasl-06 + * plugins/srp.c: server uses external SSF + * plugins/srp.c: server sends mandatory options based on min SSF + * doc/draft-burdis-cat-srp-sasl-06.txt: added + * doc/draft-burdis-cat-srp-sasl-05.txt: deleted + * doc/index.html: changed link to updated draft + +2002-01-17 Rob Siemborski + * plugins/kerberos4.c: Actually allocate a mutex on the client side + +2002-01-16 Rob Siemborski + * lib/server.c (mech_permitted): fixed incorrect return value of + SASL_NOMECH that should have been 0. + * lib/common.c (sasl_errdetail): fixed core if passed in conn is NULL + * plugins/digestmd5.c (encode_tmp_buf): removed unneeded buffer + +2002-01-16 Ken Murchison + * plugins/srp.c: fixed layer decoding to handle multiple packets + * plugins/srp.c: plugged memory leaks (now passes testsuite) + * plugins/srp.c: more logging + * plugins/srp.c: lots of other nits, bug fixes + * utils/testsuite.c: added SSF=0/56 test + +2002-01-14 Rob Siemborski + * saslauthd/auth_krb4.c (auth_krb4): fix tf_name memory leak, + and other efficency fixes + +2002-01-11 Rob Siemborski + * include/saslplug.h: Add flags member to params structures + * lib/client.c, lib/server.c: flags parameter to sasl_*_new + now gets to the plugins + +2002-01-10 Rob Siemborski + * include/sasl.h: Update for sasl_global_listmech API + * lib/common.c, lib/client.c, lib/server.c: sasl_global_listmech() + * lib/dlopen.c (_parse_la): fix parseing of dlname= line + * Ready for 2.1.0 + +2002-01-09 Ken Murchison + * plugins/otp.c: fixed security_flags + * plugins/srp.c: corrected integrity layer encoding + * plugins/srp.c: finished maxbuffersize handling + * plugins/srp.c: fixed security_flags + * doc/index.html: added reference to SRP paper + +2002-01-09 Rob Siemborski + * lib/common.c (sasl_decode): Removed maxoutbuf check + * man/sasl_setprop.3: Minor clarifications + * plugins/digestmd5.c, plugins/gssapi.c, plugins/kerberos4.c: + Assorted security layer fixes (maxoutbuf setting, mech_ssf setting) + * lib/common.c, lib/client.c, lib/server.c, lib/saslint.h: + Allowed client-side sasl_listmech calls. + * include/sasl.h: Minor cosmetic fix to comments + * doc/programming.html: Interaction memory management clarifications + * lib/common.c: Fix several crash problems in getprop + (Courtesy Marshall T. Rose ) + +2002-01-05 Lawrence Greenfield + * saslauthd/saslauthd.c: F_SETLK doesn't block; F_SETLKW does + * saslauthd/saslauthd.c: detect errors somewhat better + +2002-01-04 Rob Siemborski + * lib/common.c: Allow sasl_setprop for SASL_DEFUSERREALM + +2002-01-04 Ken Murchison + * plugins/srp.c: don't send M2 if using a confidentiality layer + * plugins/srp.c: more constraint checks + * plugins/otp.c: improve standard hex/word response detection + * doc/install.html, doc/sysadmin.html, contrib/opie-2.4-fixes: + add patch for OPIE 2.4 to enable extended responses + +2002-01-03 Ken Murchison + * configure.in: removed check fpr gmp + * plugins/srp.c: migrated to OpenSSL's BN (removed GNU MP dependency) + +2001-12-20 Rob Siemborski + * sasldb/db_ndbm.c: Fixed small memory leak + (Courtesy Howard Chu ) + +2001-12-18 Ken Murchison + * plugins/srp.c: more constraint checks + +2001-12-17 Rob Siemborski + * saslauthd/saslauthd.c: Prefork a number of processes to handle + connections. + * saslauthd/auth_krb4.c: Handle concurrent accesses better. + +2001-12-15 Ken Murchison + * plugins/srp.c: added confidentiality layers + +2001-12-14 Ken Murchison + * plugins/srp.c: improved client/server layer option handling + * plugins/srp.c: added client-side support for mandatory options + * plugins/srp.c: added framework for confidentiality layers + * plugins/srp.c: added some data sanity checking (thanks to + Tom Holroyd for feedback) + +2001-12-13 Rob Siemborski + * lib/server.c, lib/common.c: Fix handling of + global callbacks so that plugin_list works again + +2001-12-12 Rob Siemborski + * pwcheck/Makefile.am: Added include of ../lib + (from Hajimu UMEMOTO ) + +2001-12-11 Rob Siemborski + * sasldb/db_ndbm.c: fix call to dbm_nextkey, from + Scot W. Hetzel + +2001-12-10 Rob Siemborski + * doc/plugprog.html: Update for new user canonicalization usage. + * man/sasl_canon_user.3: Update for new user canonicalization usage. + * configure.in: Actually set STATIC_GSSAPIV2 when necessary + +2001-12-08 Ken Murchison + * plugins/srp.c: make sure we have the HMAC before trying to use it + * plugins/srp.c: don't advertise server integrity w/o HMAC-SHA-1 + * plugins/srp.c: move EVP_cleanup() to mech_free so mech can be reused + +2001-12-07 Ken Murchison + * configure.in: SRP now requires OpenSSL + * plugins/srp.c: migrated to OpenSSL's MDA/cipher abstraction API + * plugins/srp.c: added RIPEMD-160 support + * plugins/srp.c: using "standard ACSII names" for MDA-names as + documented by [SCAN] (until determined otherwise) + * plugins/srp.c: using updated canon_user API to allow separate + canonicalization of authid and authzid. + +2001-12-06 Rob Siemborski + * lib/canonusr.c: Better logging when desired plugin is not found. + * lib/checkpw.c: spelling error fixed. + * lib/canonusr.c, lib/checkpw.c, lib/client.c, lib/external.c, + lib/saslint.h, lib/server.c, include/sasl.h, include/saslplug.h, + plugins/*.c: Updated canon_user API to allow separate + canonicalization of authid and authzid. + +2001-12-05 Rob Siemborski + * saslauthd/Makefile.am, saslauthd/acconfig.h, saslauthd/configure.in: + Solaris 7 and FreeBSD (FreeBSD is courtesy of Claus Assmann + ) + * sasldb/Makefile.am: link order fix (Courtesy Claus Assmann + ) + +2001-12-05 Ken Murchison + * configure.in: + * plugins/Makefile.am: only build SRP with sasldb libs when + srp_setpass() is enabled + * plugins/srp.c: added HMAC-SHA-160 integrity layer + * plugins/srp.c: don't offer integrity layers unless HMAC-SHA-160 + is available (mandatory) + * plugins/srp.c: fixed multiple integrity/confidentiality layer + client-side bug + * plugins/srp.c: fixed delete SRP secret bug + * plugins/srp.c: removed VL() stuff + +2001-12-04 Rob Siemborski + * utils/Makefile.am, config/sasldb.m4: Build sasldblistusers2 + and saslpasswd2. Default database now /etc/sasldb2 + * INSTALL, README, doc/index.html, doc/upgrading.html: Update + with upgrading instructions in preparation for release. + * doc/, /: Documentation reorganization, convert README and INSTALL to + HTML format. + * Bumped appropriate version numbers, Ready for 2.0.5-BETA + +2001-12-04 Ken Murchison + * acconfig.h, configure.in: dependency checking for SRP + * acconfig.h, configure.in: + * plugins/srp.c: made srp_setpass() a compile-time option (default=off) + * plugins/srp.c: use auxprop to fetch cmusaslsecretSRP/userPassword + * plugins/srp.c: code cleanup + * acconfig.h, configure.in: + * doc/sysadmin.html: + * plugins/otp.c: made otp_setpass() a compile-time option (default=off) + +2001-12-02 Ken Murchison + * plugins/srp.c: fixed SHA1 support + * plugins/srp.c: changed calculation of 'x' to coincide with draft -05 + * plugins/srp.c: code cleanup + +2001-12-01 Ken Murchison + * plugins/srp.c: abstracted MDA interface + * plugins/srp.c: added SHA1 support (not working) + +2001-11-30 Ken Murchison + * plugins/srp.c: renumbered steps to start at 1 + * plugins/srp.c: check plugin API version instead of SRP_VERSION + * plugins/srp.c: changed data exchanges to conform to draft -05 + +2001-11-29 Ken Murchison + * plugins/srp.c: code now compiles and runs + * plugins/Makefile.am: added sasldb libs to SRP build + +2001-11-24 Ken Murchison + * lib/external.c: made EXTERNAL a client-send-first mechanism + * doc/index.html: added CRAM-MD5 draft + +2001-11-22 Ken Murchison + * plugins/otp.c: fixed otp_setpass() bug + * doc/sysadmin.html: OTP additions/changes + +2001-11-19 Rob Siemborski + * utils/saslpasswd.c: Corrected disable handling + +2001-11-17 Ken Murchison + * doc/index.html, rfc2945.txt, rfc3174.txt: specification additions + * doc/Makefile.am: Updated included RFCs and IDs + +2001-11-14 Ken Murchison + * lib/server.c, doc/options.html: added 'mech_list' option + +2001-11-14 Rob Siemborski + * sasldb/allockey.c: removed an assert() call + * sasldb/db_ndmb.c, sasldb/db_gdbm.c: Fixed cntxt's to be conn's + +2001-11-13 Ken Murchison + * acconfig.h, configure.in: + * plugins/otp.c: support client-side OTP without OPIE + +2001-11-08 Ken Murchison + * plugins/otp.c: allow entry of one-time password via + SASL_CB_ECHOPROMPT callback + * plugins/otp.c: code cleanup + * doc/index.html, draft*.txt: specification updates/additions + +2001-11-08 Rob Siemborski + * plugins/cram.c, digestmd5.c, sasldb.c: Removed all assert() + calls from supported plugins. + +2001-11-07 Rob Siemborski + * utils/testsuite.c: added proxy policy checks + * lib/checkpw.c (_sasl_auxprop_verify_apop): correct handling + of seterror calls + +2001-11-06 Rob Siemborski + * lib/canonusr.c (_canonuser_internal): added necessary seterror calls + * doc/Makefile.am: Updated included RFCs and IDs + * lib/canonusr.c, lib/server.c: Corrected authzid/authid handling + * plugins/digestmd5.c: Unconfused authzid/authid in server call to + canon_user + +2001-11-01 Rob Siemborski + * plugins/gssapi.c, plugins/kerberos4.c: Get rid of unnecessary + buffer copy in security layer encodes. + +2001-10-24 Ken Murchison + * plugins/otp.c: added otp_setpass() so that saslpasswd can + be used instead of opiepasswd on closed systems + * doc/sysadmin.html: OTP additions/changes + +2001-10-22 Ken Murchison + * acconfig.h, configure.in: detect OPIE, enable/disable OTP + * plugins/Makefile.am, makeinit.sh, otp.c: added OTP support + (still need work on RFC2444 compliance - depends on OPIE changes) + * doc/index.html, options.html, sysadmin.html, rfc*.txt: + OTP additions/changes + +2001-10-18 Rob Siemborski + * utils/testsuite.c: Test DES harder for DIGEST-MD5 + * plugins/digestmd5.c (enc_des): Get rid of one buffer copy. + * plugins/digestmd5.c (dec_des, dec_3des): correct handling of + padding length check. + +2001-10-17 Rob Siemborski + * config/sasldb.m4: detect berkeley db 4 + * plugins/gssapi.c, cram.c, kerberos4.c, digestmd5.c: have dispose + calls deal with the possibility of a null context + +2001-10-16 Rob Siemborski + * saslauthd/Makefile.am: Link LIB_PAM as well, if needed + * plugins/digestmd5.c: Don't send a trailing nul on challenge and + responses. + * lib/server.c (sasl_server_start, sasl_server_step): Deal with + authentication failures better. (Reported by Larry Rosenbaum + ) + +2001-10-02 Rob Siemborski + * saslauthd/Makefile.am, saslauthd/auth_sasldb.c, + saslauthd/configure.in: Changes to allow extraction of saslauthd + as needed. + +2001-09-19 Rob Siemborski + * lib/getaddrinfo.c (getaddrinfo): Correct fix for + AI_PASSIVE bug from Hajimu UMEMOTO + * plugins/plugin_common.c, lib/common.c (_*_ipfromstring): + revert to previous versions. + + * plugins/Makefile.am: Include necessry compatibility objects + as needed. + * lib/Makefile.am: compatibility code for static libsasl + * configure.in: small changes to make compatibility objects easy + to use. + +2001-09-18 Rob Siemborski + * plugins/plugin_common.c, lib/common.c (_*_ipfromstring): + no longer use AI_PASSIVE hint for getaddrinfo + +2001-09-13 Rob Siemborski + * saslauthd/auth_sasldb.c, saslauthd/auth_sasldb.h: + Added experimental sasldb saslauthd module + * saslauthd/configure.in: sasldb related config changes, + do not config if disabled + +2001-09-12 Rob Siemborski + * saslauthd/*, lib/checkpw.c (saslauthd_verify_password): + merged new saslauthd protocol from Ken Murchison + +2001-08-30 Rob Siemborski + + * configure.in, saslauthd/configure.in: check for inet_aton + in libresolv.so, so as to link it if necessary + + * config/sasldb.m4 (BERKELEY_DB_CHK_LIB): set runpath of library + if necessary + +2001-08-29 Rob Siemborski + + * utils/testsuite.c: Minor testsuite fix (include paths) + + * Ready for 2.0.4-BETA + +2001-08-24 Rolf Braun + + * Mac OS 9 and X support, including Carbon + Mac OS 9 Classic support based on the SASL v1 code + by Aaron Wohl + + * updated ltconfig and ltmain.sh + * acconfig.h: + * configure.in: + * lib/saslutil.c: use random() when jrand48() isn't available + + * dlcompat-20010505: + dlcompat included for OS X support, compiles separately + * lib/dlopen.c: prefix symbols with underscore on OS X, as on OpenBSD + note that this is also detected automatically by configure, + this only helps when cross-compiling (for OS X?) + + * acconfig.h: + * configure.in: + * config/kerberos_v4.m4 + look for libdes524 when libdes doesn't exist. + look for libkrb4 when libkrb doesn't exist. + + * lib/saslint.h: + * lib/common.c: + * lib/seterror.c: + * lib/Makefile.am: + split sasl_seterror() into a new file. + add_string -> _sasl_add_string and made this non-static + so seterror can use it. + added _sasl_get_errorbuf to go into the conn_t struct + so we don't have to know the format of that struct when + seterror.c is linked from glue code (i.e., the Mac OS X CFM glue) + + * acconfig.h: + fix the order of the fake iovec struct for systems that + don't have it (like Mac OS 9) so it's the same order as + most Unixes that do (like Mac OS X) -- the CFM glue needs this + + * acconfig.h: + include before we include + + * plugins/kerberos4.c: + * lib/checkpw.c: + * acconfig.h: + * configure.in: + check for krb_get_err_txt in the kerberos 4 library, + and use it instead of the krb_err_txt[] array if available + + * plugins/kerberos4.c: + define KEYFILE to "/etc/srvtab" if not already defined + by the kerberos 4 headers (needed for MIT KfM 4.0) + + * doc/macosx.html: added this + * README: point Mac OS X users to doc/macosx.html + * doc/Makefile.am: add doc/macosx.html to distfiles + + * Makefile.am: + * lib/Makefile.am: + * include/Makefile.am: + * config/Info.plist: + * configure.in: + when building on Mac OS X, install a framework + in /Library/Frameworks + + * mac/*: + projects and support files for Mac OS 9, classic and Carbon + * mac/osx_cfm_glue: + the glue to allow CFM Carbon applications under Mac OS X + call the Unix-layer SASL library + + * lib/common.c: + * lib/canonusr.c: + don't do the auxprop stuff on Mac OS 9 + + * lib/getaddrinfo.c: + don't look up hostnames on Mac OS 9 (we only officially + support passing IP address strings anyway) + + * lib/getaddrinfo.c: + * plugins/plugin_common.c: + * plugins/plugin_common.h: + don't include headers on Mac OS 9 that we don't have. + + * sample/sample-client.c: + add a cast for Mac OS 9 (different type handling of char) + + * plugins/makeinit.sh: + include the stub header to export the right symbols on Mac OS 9 + +2001-08-20 Rob Siemborski + * plugins/gssapi.c (gssapi_server_mech_step): fixed accidental + back link into glue code + + * config/kerberos4.m4: Actually link in -lkrb + +2001-08-15 Rob Siemborski + * lib/common.c (_sasl_iptostring): #if 0'd out. + + * lib/server.c (sasl_user_exists): only check the verifier we + are using + + * config/kerberos_v4.m4 (SASL_DES_CHK): added + * config/kerberos_v4.m4 (SASL_KERBEROS_V4_CHK): included + entire check from configure.in + * configure.in: moved kerberos 4 code completely out. + * saslauthd/acconfig.h (WITH_DES, WITH_SSL_DES): Added + DES-related symbols + +2001-08-14 Rob Siemborski + * configure.in: Check for sys/uio.h + * saslauthd/configure.in: Check for sys/uio.h + * config.h: Do the Right Thing for struct iovec (and + no longer include sys/uio.h elsewhere) + * saslauthd/config.h: Do the Right Thing for struct iovec (and + no longer include sys/uio.h elsewhere) + +2001-08-13 Rob Siemborski + * plugins/digestmd5.c (init_des, init_3des, enc_des, dec_des, + enc_3des, dec_3des): fixed interoperability problems, + 3des was not decrypting with correct key and des was not + setting up the initial vector. + + * lib/checkpw.c (always_true): log users who log in via this verifier + +2001-08-13 Rob Siemborski + * utils/testsuite.c (giveokpath): fix memory leak + + * lib/common.c (sasl_ipfromstring): add call to freeaddrinfo() + * plugins/plugin_common.c (_plug_ipfromstring): add call to + freeaddrinfo() + + * lib/saslutil.c (sasl_randseed): actually initialize the randpool + + * saslauthd/auth_getpwent.c (auth_getpwent): clear a warning + * saslauthd/auth_shadow.c (auth_shadow): clear a similar warning + + * utils/Makefile.am (EXTRA_DIST): Actually include the needed files + + * saslauthd/configure.in: Handle shadow passwords correctly + * saslauthd/acconfig.h: Handle shadow passwords correctly + + * lib/checkpw.c (always_true): added + * configure.in: added check for alwaystrue verifier + * acconfig.h: added HAVE_ALWAYSTRUE + * doc/options.html: alwaystrue verifier documented + +2001-08-11 Rob Siemborski + * saslauthd/: Now configures separately from SASL, so as + to localize tests for that package within that package + + * utils/dbconverter-2.c (listusers_cb): fix handling of APOP + +2001-08-10 Rob Siemborski + * saslauthd/Makefile.am (install-data-local): + correct handling of $(DESTDIR) (and create the directory if it + isn't there) [Amos Gouaux ] + + * lib/server.c (sasl_server_init): Added plugname to add_plugin + call for EXTERNAL + + * doc/index.html: updated + * doc/appconvert.html: cleaned up + +2001-08-09 Rob Siemborski + * plugins/digestmd5.c (digestmd5_client_mech_step): handle + missing authorization name + * plugins/plain.c (plain_client_mech_step): handle + missing authorization name + + * include/sasl.h: better documentation of SASL_CB_CANON_USER + +2001-08-08 Rob Siemborski + * saslauthd/saslauthd.mdoc: updated re: pam + * saslauthd/saslauthd.8: regenerated + * saslauthd/Makefile.am: Link against PLAIN_LIBS also + (from Ken Murchison ) + +2001-08-07 Rob Siemborski + * lib/client.c (sasl_server_step): corrected maxoutbuf handleing + * lib/server.c (sasl_server_step): corrected maxoutbuf handleing + * lib/saslint.h (DEFAULT_MAXOUTBUF): removed + + * lib/common.c (sasl_encodev, sasl_decode): maxbufsize checking + + * utils/testsuite.c (testseclayer,doauth): more security layer + checking. Added parameter to doauth to disable fatal() calls, + updated all callers. + + * utils/smtptest.c (main): added ability to support LMTP + + * plugins/gssapi.c: conform with draft-ietf-cat-sasl-gssapi-05.txt + + * doc/draft-ietf-cat-sasl-gssapi-05.txt: added + * doc/Makefile.am (EXTRA_DIST): added above to EXTRA_DIST + +2001-08-06 Rob Siemborski + * utils/dbconverter-2.c (listusers_cb): handle PLAIN-APOP + + * lib/client.c (sasl_client_add_plugin, client_done): + save plugin name + * lib/server.c (sasl_server_add_plugin, server_done): + save plugin name + * lib/dlopen.c (_sasl_plugin_load): correctly pass pluginname + * lib/common.c (sasl_getprop): implement SASL_AUTHSOURCE properly + * lib/saslint.h (cmechanism_t, mechanism_t): added plugname field + * lib/canonusr.c (internal_canonuser_init): no longer limit + based on plugname + * plugins/sasldb.c (sasldb_auxprop_plug_init): no longer limit + based on plugname + +2001-08-01 Rob Siemborski + * utils/smtptest.c (iptostring): better behaved w.r.t endianness + + * plugins/cram.c (crammd5_server_mech_step): support for old-style + secrets + * plugins/digestmd5.c (digestmd5_server_mech_step): support for + old-style secrets + * lib/checkpw.c (auxprop_verify_password,_sasl_make_plain_secret): + support for old-style secrets + * utils/dbconverter-2.c: added + * utils/sasldblistusers.c (listusers): Print out property names + as well as username@realm format. + * utils/saslpasswd.c (_sasl_sasldb_set_pass): Correctly handle updates + that concern old-style secrets + + * sasldb/allockey.c: Added a missing null to propName in key parser + +2001-07-31 Rob Siemborski + * plugins/kerberos4.c (mech_avail): made static + + * plugins/kerberos4.c (mech_avail): fixed ipv4 check + (patch from Hajimu UMEMOTO ) + + * doc/appconvert.html: vague guide documenting our experience + porting Cyrus IMAPd to use SASLv2 + * doc/Makefile.am: added appconvert.html + + * lib/client.c (sasl_client_new): fixed ip address setting to hit + relevant params structures as well + * lib/server.c (sasl_server_new): fixed ip address setting to hit + relevant params structures as well + * lib/common.c (sasl_setprop): fixed ip address setting to hit + relevant params structures as well + + * lib/common.c (sasl_seterror): fixed spelling error + +2001-07-30 Rob Siemborski + * sasldb/db_berkeley.c: utils->seterror() calls + * sasldb/db_gdbm.c: utils->seterror() calls + * sasldb/db_ndbm.c: utils->seterror() calls + * sasldb/allockey.c: utils->seterror() calls + + * lib/common.c (sasl_seterror): still call logging callback with a + null sasl_conn_t + + * plugins/sasldb.c (sasldb_auxprop_lookup): support for multiple + properties + + * plugins/Makefile.am: added -module to LDFLAGS + + * config/sasldb.m4: Allow specification of exact berkeley db + lib and include paths + * sasldb/Makefile.am: Add proper include directory + + * sasldb/sasldb.m4 (SASL_DB_BACKEND_STATIC): include allockey.o + + * Ready for 2.0.3-BETA + + * plugins/kerberos4.c (kerberos4_server_plug_init): reset + srvtab when we do not load correctly. + + * lib/staticopen.c (_sasl_load_plugins): do not fail + if a single plugin load fails + + * include/sasl.h (SASL_CLIENT_FALLBACK): removed + +2001-07-27 Rob Siemborski + * configure.in: extracted SASLDB-related checking + * config/sasldb.m4: added + + * configure.in: now cache the JNI include directory path + + * utils/testsuite.c: switch some sasl_errstrings to sasl_errdetail + * plugins/gssapi.c: Fix error reporting + + * plugins/gssapi.c: Required SASL_CB_USER instead of SASL_CB_AUTHNAME + + * plugins/anonymous.c: Function name standardization + * plugins/cram.c: Function name standardization + * plugins/digestmd5.c: Function name standardization + * plugins/gssapi.c: Function name standardization + * plugins/kerberos.c: Function name standardization + * plugins/login.c: Function name standardization + * plugins/plain.c: Function name standardization + + * sasldb/allockey.c: Generalized SASLdb API + * sasldb/db_berkeley.c: Generalized SASLdb API + * sasldb/db_gdbm.c: Generalized SASLdb API + * sasldb/db_ndbm.c: Generalized SASLdb API + * sasldb/db_none.c: Generalized SASLdb API + * sasldb/db_testw32.c: Added #error to block compile so the API will + be fixed when we do the Win 32 port + * plugins/sasldb.c: Use new SASLdb API + * utils/saslpasswd.c: Use new SASLdb API + +2001-07-26 Rob Siemborski + * lib/common.c (_sasl_getcallback): fixed reference to + possibly NULL conn + + * configure.in: only build saslpasswd and sasldblistusers + if we have a meaningfull libsasldb (e.g. not db_none), + * utils/Makefile.am: only build saslpasswd and sasldblistusers + if we have a meaningfull libsasldb (e.g. not db_none), + + * configure.in: conditionally build smtptest + * utils/Makefile.am: conditionally build smtptest + + * sasldb/allockey.c (_sasldb_parse_key): added + + * sasldb/sasldb.h: New key list access API, added parameter to + sasl_check_db (all callers updated, all callees updated) + * sasldb/db_berkeley.c: Implement key list access API + * sasldb/db_gdbm.c: Implement key list access API + * sasldb/db_ndbm.c: Implement key list access API + * sasldb/db_none.c: Implement key list access API + + * utils/sasldblistuser.c: Use libsasldb instead of internal + functions. + + * utils/saslpasswd.c: No longer have separate global_utils, + call sasl_dispose and sasl_done + + * acconfig.h: check for inttypes.h + * configure.in: check for inttypes.h + * plugins/plugin_common.c: include, if necessary, inttypes.h, + reference uint32_t instead of u_int32_t + +2001-07-25 Rob Siemborski + * lib/saslint.h: changed "sasldb" verifier to "auxprop" + * lib/server.c: changed "sasldb" verifier to "auxprop" + * lib/checkpw.c: changed "sasldb" verifier to "auxprop" + * utils/testsuite.c: changed "sasldb" verifier to "auxprop" + * doc/options.html: changed "sasldb" verifier to "auxprop" + + * README: updated upgrade information + + * utils/Makefile.am (CLEANFILES): added + + * sasldb/allockey.c (alloc_key): single place for alloc_key() + Removed alloc_key from other source files. + * sasldb/sasldb.h: added declaration of alloc_key() + + * configure.in: added checks for db-3.3 and db3.3 + + * plugins/digestmd5.c (get_realm): now error on empty user_realm + + * plugins/cram.c (client_required_prompts): removed redundant + required_prompts + + * plugins/plain.c (client_continue_step): server-send-last error + + * utils/testsuite.c (main): detailed client-send-first, + server-send-last checking + +2001-07-24 Rob Siemborski + * plugins/sasldb.c: Cleaned up calls into the glue code + + * java/Test/*: Cleaned up java test utilities + + * configure.in: Minor GSSAPI configure changes + + * utils/saslpasswd.c: Clarfied -d option for saslpasswd + * utils/saslpasswd.8: Clarfied -d option for saslpasswd + + * doc/plugprog.html: Added plugin programmer's guide + * doc/index.html: linked to plugin programmer's guide + + * configure.in: corrected configure checking of Berkeley DB + (from Scot W. Hetzel ) + + * configure.in: corrected checking for libcom_err + (from Scot W. Hetzel ) + +2001-07-23 Rob Siemborski + * configure.in: Added check for db3/db.h + + * plugins/kerberos4.c Added mech_avail (checks for IP info) + + * lib/common.c: Fixed setting of serverFQDN in _sasl_conn_init + + * lib/server.c: Fully Implemented mech_avail calls in glue code + + * lib/server.c: Fixed allocation/destruction of sasl_conn_t's + * lib/client.c: Fixed allocation/destruction of sasl_conn_t's + * lib/common.c: Rely on earlier initialization in server.c and client.c + + * doc/options.html: added + + * ChangeLog: back to standard format + +2001-07-20 Rob Siemborski + * Can now deal with variable client-first mechs such as + DIGEST-MD5, though this interface is subject to change + * Modified parseuser to deal better with default realms + * Simplified realm handling in DIGEST-MD5 (getrealm callback + is no longer required). + * Cleaned up some memory management issues in DIGEST-MD5 + +2001-07-19 Rob Siemborski + * Fixed prototype of sasl_getpath_t to be in conformance with + memory allocation rules + * Fixed up samples directory + * Try to dlopen using information in .la file if available + (based on patch from + Stoned Elipot ) + * Resolution of most of the server-send-first and client-send-last + issues (using mechanism feature flags) + +2001-07-18 Rob Siemborski + * Updated config.guess and config.sub + * Better underscore checking for dlsym + * Resolved possible global_utils namespace collision + * Updated sasldb library to be expandable to multiple properties + if the need arises in the future. + * IPv6 support from Hajimu UMEMOTO + +2001-07-17 Rob Siemborski + * Extricated sasldb support to an auxprop plugin only. + sasldb modifications can now only be done through the saslpasswd + interface. + +2001-07-13 Rob Siemborski + * Fixed buffer overrun problem in sasldb auxprop plugin + * Removed severe memory leak from testsuite + * Version 2.0.2-ALPHA Released + +2001-07-11 Rob Siemborski + * error reporting in KERBEROS_V4 plugin + * vague handling of SASL_AUTHSOURCE for getprop + * random misc error reporting bugs + * basic error messages for GSSAPI plugin + +2001-07-10 Rob Siemborski + * added client-send-first logic in glue code + * removed some client-send-first logic in mechanisms + * removed IPv4 specifics from sasl_conn_t + * Much gluecode error revamping (store the error code + in sasl_conn_t) + +2001-07-09 Rob Siemborski + * Removed dependency on "name" in canonuser plugin structure + * Update configure.in from a new configure.scan + * Update copyright info in man pages, finished all API man pages + * Added auxprop tests to testsuite + * Added userdb callback support + +2001-07-09 Rob Siemborski + * First attempt at making the java code work again + * Minor memory and byte order bugfixes + * Added testing support for dmalloc (--with-dmalloc) + +2001-07-06 Rob Siemborski + * Loading of auxprop and canonuser plugins from DSOs + (This still sucks performance wise, and will be fixed soon) + * Fixed some lack of indirection in the plugins + * Reverted to the v1 entry points for the plugins + * Cleaned up a good deal of the library loading code so it + now only gets called from the sasl_*_init functions, and + all the cleanup happens in the common sasl_done function + * Added SASL_IPREMOTEPORT and SASL_IPLOCALPORT to setprop, + and now _sasl_conn_init calls it to do the same work. + +2001-07-05 Rob Siemborski + * Working libsfsasl and smtptest program (--with-sfio) + * Fixed sasldblistusers (atleast for Berkeley DB) + * seterror() calls in ANONYMOUS, CRAM, PLAIN and LOGIN + * Some new manpages + +2001-07-03 Rob Siemborski + * Static library compilation now optional (--with-staticsasl) + Note that this is different from --enable-static, which causes + libtool to build static versions of everything is is almost + certainly NOT what you want. + * Removed all references to the ancient NANA code. + * Updated some documentation. + +2001-07-02 Rob Siemborski + * Improved allocation efficiency of KERBEROS_V4, DIGEST-MD5, + and GSSAPI security layers. + * Fixed a decode bug in DIGEST-MD5 (and testsuite improvements to + help find similar ones) + * Fixed a number of solaris compiler warnings + * Static Library Build Support + +2001-06-30 Rob Siemborski + * Cleanup of some man pages (added sasl_errors.3) + +2001-06-29 Rob Siemborski + * Cleanup of APOP Code + new man page (Ken Murchison ) + * Cleanup of comments in some files (Ken Murchison ) + * Fixed some compiler errors on Solaris using /opt/SUNWspro/bin/cc + (Reported by Mei-Hui Su + +2001-06-28 Rob Siemborski + * Improved memory allocation in default sasl_decode handler + * Added ability to disable sasl_checkapop (--disable-checkapop) + * Re-initialized kerberos mutex to NULL after it was freed + +2001-06-28 Rob Siemborski + * Fixed a severe bug in DIGEST-MD5 Plugin + * KERBEROS_V4 plugin now thread safe + * Version 2.0.1-ALPHA Released (due to DIGEST-MD5 problem) + +2001-06-27 Rob Siemborski + * Version 2.0.0-ALPHA Released diff --git a/libs/cyrussasl/INSTALL b/libs/cyrussasl/INSTALL new file mode 100644 index 00000000..2550dab7 --- /dev/null +++ b/libs/cyrussasl/INSTALL @@ -0,0 +1,302 @@ +Installation Instructions +************************* + +Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, +2006, 2007, 2008, 2009 Free Software Foundation, Inc. + + This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + + Briefly, the shell commands `./configure; make; make install' should +configure, build, and install this package. The following +more-detailed instructions are generic; see the `README' file for +instructions specific to this package. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. Caching is +disabled by default to prevent problems with accidental use of stale +cache files. + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You need `configure.ac' if +you want to change it or regenerate `configure' using a newer version +of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. + + Running `configure' might take a while. While running, it prints + some messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + + 6. Often, you can also type `make uninstall' to remove the installed + files again. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c99 CFLAGS=-g LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you can use GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + With a non-GNU `make', it is safer to compile the package for one +architecture at a time in the source code directory. After you have +installed the package for one architecture, use `make distclean' before +reconfiguring for another architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple `-arch' options to the +compiler but only a single `-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases, you +may have to build one architecture at a time and combine the results +using the `lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' installs the package's commands under +`/usr/local/bin', include files under `/usr/local/include', etc. You +can specify an installation prefix other than `/usr/local' by giving +`configure' the option `--prefix=PREFIX'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +pass the option `--exec-prefix=PREFIX' to `configure', the package uses +PREFIX as the prefix for installing programs and libraries. +Documentation and other data files still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=DIR' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Particular systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU +CC is not installed, it is recommended to use the following options in +order to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On Solaris, don't put `/usr/ucb' early in your `PATH'. This +directory contains several dysfunctional programs; working variants of +these programs are available in `/usr/bin'. So, if you need `/usr/ucb' +in your `PATH', put it _after_ `/usr/bin'. + + On Haiku, software installed for all users goes in `/boot/common', +not `/usr/local'. It is recommended to use the following options: + + ./configure --prefix=/boot/common + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS + KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the option `--target=TYPE' to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +causes the specified `gcc' to be used as the C compiler (unless it is +overridden in the site shell script). + +Unfortunately, this technique does not work for `CONFIG_SHELL' due to +an Autoconf bug. Until the bug is fixed you can use this workaround: + + CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of all of the options to `configure', and exit. + +`--help=short' +`--help=recursive' + Print a summary of the options unique to this package's + `configure', and exit. The `short' variant lists options used + only in the top level, while the `recursive' variant lists options + also present in any nested packages. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--prefix=DIR' + Use DIR as the installation prefix. *Note Installation Names:: + for more details, including other options available for fine-tuning + the installation locations. + +`--no-create' +`-n' + Run the configure checks, but stop before creating any output + files. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/libs/cyrussasl/INSTALL.TXT b/libs/cyrussasl/INSTALL.TXT new file mode 100644 index 00000000..bc759c1c --- /dev/null +++ b/libs/cyrussasl/INSTALL.TXT @@ -0,0 +1 @@ +For installation instructions, see doc/install.html. diff --git a/libs/cyrussasl/NEWS b/libs/cyrussasl/NEWS new file mode 100644 index 00000000..b9add573 --- /dev/null +++ b/libs/cyrussasl/NEWS @@ -0,0 +1,503 @@ +New in 2.1.26 +------------- + +* Modernize SASL malloc/realloc callback prototypes +* Added sasl_config_done() to plug a memory leak when using an application + specific config file +* Fixed PLAIN/LOGIN authentication failure when using saslauthd + with no auxprop plugins (bug # 3590). +* unlock the mutex in sasl_dispose if the context was freed by another thread +* MINGW32 compatibility patches +* Fixed broken logic in get_fqhostname() when abort_if_no_fqdn is 0 +* Fixed some memory leaks in libsasl +* GSSAPI plugin: + - Fixed a segfault in gssapi.c introduced in 2.1.25. + - Code refactoring + - Added support for GSS-SPNEGO SASL mechanism (Unix only), which is also + HTTP capable +* GS2 plugin: + - Updated GS2 plugin not to lose minor GSS-API status codes on errors +* DIGEST-MD5 plugin: + - Correctly send "stale" directive to prevent clients from (re)promtping + for password + - Better handling of HTTP reauthentication cases + - fixed some memory leaks +* SASLDB plugin: + - Added support for BerkleyDB 5.X or later +* OTP plugin: + - Removed calling of EVP_cleanup() on plugin shutdown in order to prevent + TLS from failing in calling applications +* SRP plugin: + - Removed calling of EVP_cleanup() on plugin shutdown in order to prevent + TLS from failing in calling applications +* saslauthd: + - auth_rimap.c: qstring incorrectly appending the closing double quote, + which might be causing crashes + - auth_rimap.c: read the whole IMAP greeting + - better error reporting from some drivers + - fixed some memory leaks + +New in 2.1.25 +------------- + +* Make sure that a failed authorization doesn't preclude + further server-side SASL authentication attempts from working. +* Fixed a crash caused by aborted SASL authentication + and initiation of another one using the same SASL context. +* (Windows) Fixed the random number generator to actually produce random + output on each run. +* Be protective against calling sasl_server_step once authentication + has failed (multiple SASL plugins) +* Fixed several bugs in the mech_avail callback handling + in the server side code. +* Added support for channel bindings +* Added support for ordering SASL mechanisms by strength (on the client side), + or using the "client_mech_list" option. +* server_idle needs to obey server's SASL mechanism list from the server + context. +* Better server plugin API mismatch reporting +* Build: + - Updated config to the latest GNU snapshot + - Fixed SASL's libtool MacOS/X 64-bit file magic +* New SASL plugin: SCRAM +* New SASL plugin: GS2 +* DIGEST-MD5 plugin: + - Allow DIGEST-MD5 plugin to be used for client-side and + server-side HTTP Digest, including running over non-persistent + connections (RFC 2617) + - Use the same username for reauthentication cache lookup and update + - Minimize the number of auxprop lookups in the server side DIGEST-MD5 + plugin for the most common case when authentication and authorization + identities are the same. + - Updated digestmd5_server_mech_step2() to be more defensive against + empty client input. + - Fixed some memory leaks on failed plugin initialization. + Prevent potential race condition when freeding plugin state. + Set the freed reauthentication cache mutex to NULL, to make errors + due to mutex access after free more obvious. + - Test against broken UTF-8 based hashes if calculation using special + ISO-8859-1 code fails. + - Fixed an interop problem with some LDAP clients ignoring server + advertised realm and providing their own. +* GSSAPI plugin: + - Fix to build GSSAPI with Heimdal + - Properly set serveroutlen to 0 in one place. + Don't send empty challenge once server context establishment is done, + as this is in violation of the RFC 2222 and its successor. + - Don't send maxbuf, if no security layer can be established. + Added additional checks for buffer lengths. +* LDAPDB plugin: + - build fixes + +New in 2.1.24 +------------- + +* Order advertised server-side SASL mechanisms per the specified 'mech_list' + option or by relative "strength" +* Make sure that sasl_set_alloc() has no effect once sasl_client_init() + or sasl_server_init() is called +* Fixed sasl_set_mutex() to disallow changing mutex management functions + once sasl_server_init()/sasl_client_init() is called (bug # 3083) +* Removed unused mutexes in lib/client.c and lib/server.c (bug # 3141) +* Added direct support for hashed password to auxprop API +* Don't treat a constraint violation as an error to store an auxprop property +* Extended libsasl (auxprop) to support user deletion +* Extended SASL auxprop_lookup to return error code +* Updated sasl_user_exists() so that it can handle passwordless accounts (e.g. disabled) +* (Windows) Free handles of shared libraries on Windows that were loaded + but are not SASL plugins (bug # 2089) +* Prevent freeing of common state on a subsequent call to _sasl_common_init. + Make sure that the last global callback always wins. +* Implemented sasl_client_done()/sasl_server_done() +* Added automatic hostname canonicalization inside libsasl +* Made sasl_config_init() public +* Strip trailing spaces from server config file option values (bug # 3139, bug # 3041) +* Fixed potential buffer overflow in saslautd_verify_password(). +* Fixed segfault in dlclose() on HPUX +* Various bugfixes for 64bit platforms +* Fixed bug # 2895 (passing LF to sasl_decode64) in sample/sample-client.c, + sample/sample-server.c, utils/smtptest.c +* pluginviewer: Code cleanup, improved human readable messages +* Build: + - (Windows) Updated makefiles to build with VC 8.0 (VC++ 2005) + - (Windows) Added Windows64 build + - Updated to use .plugin extension on MacOS + - Changed 64bit HP-UX build to use .so for shared libraries +* saslauthd: + - Fixed bug counting double-quotes in username/password in + auth_rimap.c. Also fixed bug zeroing password. + - auth_krb.c: improved diagnostic in the k5support_verify_tgt() function. + - auth_sasldb.c: pid_file_lock is created with a mask of 644 instead of 0644 + - auth_shadow.c: Define _XOPEN_SOURCE before including unistd.h, + so that crypt is correctly defined + - auth_getpwent.c: Fixed Solaris build +* SASLDB plugin: + - Fixed spurious 'user not found' errors caused by an attempt + to delete a non-existent property + - Added direct support for hashed password to auxprop API + - Sleepycat driver: Return SASL_NOUSER instead of SASL_FAIL when the database + file doesn't exist + - Ignore properties starting with '*' in the auxprop store function +* SQL plugin: + - Added support for SQLITE3 + - Uninitialized variables can cause crash when the searched user is not found + - Added direct support for hashed password + - Ignore properties starting with '*' in the auxprop store function +* LDAPDB plugin: + - Added code to extend LDAPDB into a canon_user plugin in addition + to its existing auxprop plugin functionality +* PLAIN plugin: + - Advertise SASL_SEC_PASS_CREDENTIALS feature +* LOGIN plugin: + - Advertise SASL_SEC_PASS_CREDENTIALS feature +* DIGEST-MD5 plugin: + - Fixed a memory leak in the DIGEST-MD5 security layer + - Fixed memory leaks in client-side reauth and other places + - More detailed error reporting. + - Fixed parsing of challenges/responses with extra commas. + - Allow for multiple qop options from the server and require + a single qop option from the client. +* GSSAPI plugin: + - Check that params->serverFQDN is not NULL before using strlen on it + - Make auxprop lookup calls optional +* EXTERNAL plugin: + - Make auxprop lookup calls optional +* NTLM plugin: + - allow a comma separated list of servernames in 'ntlm_server' option + - Fixed crash in calculating NTv2 reponse +* OTP plugin: + - Don't use a stack variable for an OTP prompt (bug # 2822) + - Downgrade the failure to store OTP secret to debug level +* KERBEROS_V4 plugin: + - Make auxprop lookup calls optional + +New in 2.1.23 +------------- + +* Fixed CERT VU#238019 (make sure sasl_encode64() always NUL + terminates output or returns SASL_BUFOVER) + +New in 2.1.22 +------------- + +* Added support for spliting big data blocks (bigger than maxbuf) + into multiple SASL packets in sasl_encodev +* Various sasl_decode64() fixes +* Increase canonicalization buffer size to 1024 bytes +* Call do_authorization() after successful APOP authentication +* Allow for configuration file location to be configurable independently + of plugin location (bug # 2795) +* Added sasl_set_path function, which provides a more convenient way + of setting plugin and config paths. Changed the default + sasl_getpath_t/sasl_getconfpath_t callbacks to calculate + the value only once and cache it for later use. +* Fixed load_config to search for the config file in all directories + (bug # 2796). Changed the default search path to be + /usr/lib/sasl2:/etc/sasl2 +* Don't ignore log_level configuration option in default UNIX syslog + logging callback +* (Windows) Minor IPv6 related changes in Makefiles for Visual Studio 6 +* (Windows) Fixed bug of not setting the CODEGEN (code generation option) + nmake option if STATIC nmake option is set. +* Several fixed to DIGEST-MD5 plugin: + - Enable RC4 cipher in Windows build of DIGEST-MD5 + - Server side: handle missing realm option as if realm="" was sent + - Fix DIGEST-MD5 to properly advertise maxssf when both DES and RC4 + are disabled + - Check that DIGEST-MD5 SASL packet are no shorter than 16 bytes +* Several changes/fixed to SASLDB plugin: + - Prevent spurious SASL_NOUSER errors + - Added ability to keep BerkleyDB handle open between operations + (for performance reason). New behavior can be enabled + with --enable-keep-db-open. +* Better error checking in SQL (MySQL) auxprop plugin code +* Added support for HTTP POST password validation in saslauthd +* Added new application ("pluginviewer") that helps report information + about installed plugins +* Allow for building with OpenSSL 0.9.8 +* Allow for building with OpenLDAP 2.3+ +* Several quoting fixes to configure script +* A large number of other minor bugfixes and cleanups + +New in 2.1.21 +------------- +* Fixes DIGEST-MD5 server side segfault caused by the client not sending + any realms +* Minor Other bugfixes + +New in 2.1.20 +------------- +* Fixes to cram plugin to avoid attempting to canonify uninitialized data. +* NTLM portability fixes. +* Avoid potential attack using SASL_PATH when sasl is used in a setuid + environment. +* A trivial number of small bugfixes. + +New in 2.1.19 +------------- +* Fixes to saslauthd to allow better integration with realms (-r flag to + saslauthd, %R token in LDAP module) +* Support for forwarding of GSSAPI credentials +* SQLite support for the SQL plugin +* A nontrivial number of small bugfixes. + +New in 2.1.18 +------------- +* saslauthd/LDAP no longer tagged "experimental" +* Add group membership check to saslauthd/LDAP +* Fix Solaris 9 "NI_WITHSCOPEID" issue +* Fix missing "getaddrinfo.c" and other distribution problems +* Significant Windows enhancements +* A large number of other minor bugfixes and cleanups + +New in 2.1.17 +------------- +* Allow selection of GSSAPI implementation explicitly (--with-gss_impl) +* Other GSSAPI detection improvements +* Now correctly do authorizaton callback in sasl_checkpass() +* Disable KERBEROS_V4 by default +* Continued Win32/Win64 Improvements +* Minor Other bugfixes + +New in 2.1.16-BETA +------------------ +* Significantly improved Win32 support +* Writable auxprop support +* Expanded SQL support (including postgres) +* Significantly improved documentation +* Improved realm/username handling with saslauthd +* Support for modern automake and autoconf + +New in 2.1.15 +------------- +* Fix a number of build issues +* Add a doc/components.html that hopefully describes how things + interact better. + +New in 2.1.14 +------------- +* OS X 10.2 support +* Support for the Sun SEAM GSSAPI implementation +* Support for MySQL 4 +* A number of build fixes +* Other minor bugfixes + +New in 2.1.13 +------------- +* Add a configure option to allow specification of what /dev/random to use. +* Addition of a saslauthd credential cache feature (-c option). +* Unification of the saslauthd ipc method code. +* Fix a number of autoconf issues. +* A significant number of fixes throughout the library from Sun Microsystems. +* Other minor bugfixes. + +New in 2.1.12 +------------- +* Distribute in Solaris tar (not GNU tar format) +* Fix a number of build/configure related issues. + +New in 2.1.11 +------------- +* Add the fastbind auth method to the saslauthd LDAP module. +* Fix a potential memory leak in the doors version of saslauthd. +* NTLM now only requires one of LM or NT, not both. +* Fix a variety of Berkeley DB, LDAP, OpenSSL, and other build issues. +* Win32 support compiles, but no documentation as of yet. + +New in 2.1.10 +------------- +* Further DIGEST-MD5 DES interoperability fixes. Now works against Active + Directory. +* Fix some potential buffer overflows. +* Misc. cleanups in the saslauthd LDAP module +* Fix security properties of NTLM and EXTERNAL + +New in 2.1.9 +------------ +* Include missing lib/staticopen.h file. + +New in 2.1.8 +------------ +* Support for the NTLM mechanism (Ken Murchison ) +* Support libtool --enable-shared and --enable-static + (Howard Chu ) +* OS/390 Support (Howard Chu ) +* Berkeley DB 4.1 Support (Mika Iisakkila ) +* Documentation fixes +* The usual round of assorted other minor bugfixes. + +New in 2.1.7 +------------ +* Add SASL_AUTHUSER as a parameter to sasl_getprop +* Allow applications to require proxy-capable mechanisms (SASL_NEED_PROXY) +* Performance improvements in our treatment of /dev/random +* Removal of buggy DIGEST-MD5 reauth support. +* Documentation fixes +* Assorted other minor bugfixes. + +New in 2.1.6 +------------ +* Security fix for the CRAM-MD5 plugin to check the full length of the + digest string. +* Return of the Experimental LDAP saslauthd module. +* Addition of Experimental MySQL auxprop plugin. +* Can now select multiple auxprop plugins (and a priority ordering) +* Mechanism selection now includes number of security flags +* Mac OS X 10.1 Fixes +* Misc other minor bugfixes. + +New in 2.1.5 +------------ +* Remove LDAP support due to copyright concerns. +* Minor bugfixes. + +New in 2.1.4 +------------ +* Enhancements and cleanup to the experimental LDAP saslauthd module + (Igor Brezac ) +* Addition of a new sasl_version() API +* Misc. Bugfixes + +New in 2.1.3-BETA +----------------- +* Significant amount of plugin cleanup / standardization. A good deal of code + is now shared between them. (mostly due to Ken Murchison ) +* DIGEST-MD5 now supports reauthentication. Also has a fix for DES + interoperability. +* saslauthd now supports the Solaris "doors" IPC method + (--with-ipctype=doors) +* Significant GSSAPI fixes (mostly due to Howard Chu ) +* Auxprop interface now correctly deals with the * prefix indicating + authid vs. authzid. (May break some incompatible auxprop plugins). +* We now allow multiple pwcheck_method(s). Also you can restrict auxprop + plugins to the use of a single plugin. +* Added an experimental saslauthd LDAP module (Igor Brezac ) +* Removed check for db3/db.h +* Misc. documentation updates. (Marshall Rose, and others) +* Other misc. bugfixes. + +New in 2.1.2 +------------ +* Mostly a minor-bugfix release +* Improved documentation / cleanup of old references to obsolete + pwcheck_methods +* Better error reporting for auxprop password verifiers + +New in 2.1.1 +------------ +* Many minor bugfixes throughout. +* Improvements to OTP and SRP mechanisms (now compliant with + draft-burdis-cat-srp-sasl-06.txt) +* API additions including sasl_global_listmech, and a cleaner handling of + client-first and server-last semantics (no application level changes) +* Minor documentation improvements + +New in 2.1.0 +------------ +* The Cyrus SASL library is now considered stable. It is still not backwards + compatible with applications that require SASLv1. +* Minor API changes occured, namely the canon_user callback interface. +* saslauthd now preforks a number of processes to handle connections +* Many bugfixes through the entire library. + +New in 2.0.5-BETA +----------------- +* THIS IS A BETA-QUALITY RELEASE THAT IS NOT INTENDED FOR PRODUCTION USE. + IT *WILL BREAK* ANY APPLICATION EXPECTING THE SASLv1 API. +* Improved performance of security layers in KERBEROS_V4, GSSAPI, and DIGEST. +* This release includes an OTP plugin that requires libopie. +* SRP plugin now in alpha stage. +* Includes many significant bugfixes throughout the library. + +New in 2.0.4-BETA +----------------- +* THIS IS A BETA-QUALITY RELEASE THAT IS ONLY INTENDED FOR USE BY + DEVELOPERS WHOSE APPLICATIONS MAKE USE OF THE CYRUS SASL LIBRARY. + IT *WILL BREAK* ANY APPLICATION EXPECTING THE SASLv1 API. +* This release now includes Mac OS 9 and Mac OS X support. +* Significant new features include + * DES and 3DES Encryption should now be working for DIGEST-MD5 + * Improved configuration system + * Improved documentation (now includes plugin writers guide) + * Many other bugfixes (see ChangeLog) + +New in 2.0.3-BETA +----------------- +* THIS IS A BETA-QUALITY RELEASE THAT IS ONLY INTENDED FOR USE BY + DEVELOPERS WHOSE APPLICATIONS MAKE USE OF THE CYRUS SASL LIBRARY. + IT *WILL BREAK* ANY APPLICATION EXPECTING THE SASLv1 API. +* This library should be fairly close to the core features that will be + released in a final version of Cyrus SASLv2. It very likely has bugs. +* Major new features included in this release: + - The glue code now correctly handles client-send-first and server-send-last + situations based on what the protocol and mechanism each support. + - The sasldb code has been extracted from the main library and now resides + in a separate libsasldb.la that is available at build time. + - SASLdb now supports multiple auxiliary properties, though as distributed + only userPassword is implemented and used. + - Much improved configure checking for various items, including + Berkeley DB, Kerberos, and GSSAPI. + - Better (more standard) handling of realms in DIGEST-MD5. + - A new Plugin Programmer's guide. + - IPv6 support. + - Error reporting now works in the GSSAPI plugin. +* See the ChangeLog for a more detailed list of changes. + +New in 2.0.2-ALPHA +------------------ +* THIS IS AN ALPHA-QUALITY RELEASE THAT IS ONLY INTENDED FOR DEVELOPERS + WHOSE APPLICATIONS MAKE USE OF THE CYRUS SASL LIBRARY. +* This release is intended to show developers that use Cyrus SASL what + direction we are planning on taking the library so that they can make + plans to migrate their applications accordingly +* Major new features included in this release: + - Ability to compile a static library including all mechanisms. This + means lower memory usage and faster mechanism loading time, but + is not for everyone (or even many people). See doc/advanced.html, + as well as the '--with-staticsasl' configure flag. + - Man pages should now all be present and are close to being correct. + - Can now build libsfsasl and the smtptest program (using the --with-sfio + configure flag) + - Reverted to the v1 entry points for mechanisms, to allow v1 mechanisms + to fail loading cleanly. + - Auxprop and canon_user plugins can now load from DSOs + - Java code now compiles (but is not well tested, or up to date with the + current Java API draft) + - Error handling and use of sasl_errdetail has been fleshed out and + should now work in most cases. +* Still Coming: + - Cleanup of the client-send-first and server-send-last situation + - Error reporting in GSSAPI plugin + - Move the sasldb code out of the main library and into plugins and + utilities only. + +New in 2.0.0-ALPHA +------------------ +* THIS IS AN ALPHA-QUALITY RELEASE THAT IS ONLY INTENDED FOR DEVELOPERS + WHOSE APPLICATIONS MAKE USE OF THE CYRUS SASL LIBRARY. +* This release is intended to show developers that use Cyrus SASL what + direction we are planning on taking the library so that they can make + plans to migrate their applications accordingly +* This release implements the SASLv2 API. + Some of the major improvements in the API include: + - Memory management is now sane (whoever allocates the memory is responsible + for freeing it) + - Auxiliary Property plugin support (ability to interface with directory + services as part of authentication) + - Username canonification plugin support + - Improved error reporting (not fully implemented in this release) + - Database support has been simplified. We now maintain only a single + store of plaintext passwords that is shared by all supplied plugins + (using the auxiliary property interface). + The new API is more fully documented in the header files sasl.h, saslplug.h + saslutil.h, and prop.h. The man pages, programmers guide, and system + administrators guide have also been rewritten to deal with the new API. +* There is still a good amount of work to be done, and as this code is alpha + quality, it has bugs, known and unknown. Please either use our bugzilla at + http://bugzilla.andrew.cmu.edu, or email cyrus-bugs@andrew.cmu.edu with + questions, comments, or bug reports. + - Most notably, the Java bindings have not been converted to work with + the new API, and thus will not compile successfully. + - The current development branch with this source is in our + cvs repository as the "sasl-v2-rjs3" branch of the "sasl" collection. + (see http://asg.web.cmu.edu/cyrus/download/anoncvs.html for more info) diff --git a/libs/cyrussasl/README b/libs/cyrussasl/README new file mode 100644 index 00000000..b55280e0 --- /dev/null +++ b/libs/cyrussasl/README @@ -0,0 +1,21 @@ +This is the Cyrus SASL API implentation. It can be used on the client +or server side to provide authentication and authorization services. +See RFC 4422 for more information. + +The latest version is available at: +ftp://ftp.andrew.cmu.edu/pub/cyrus-mail + +There's a mailing list for Cyrus SASL. Subscribe by sending a message +to majordomo@lists.andrew.cmu.edu with the body "subscribe +cyrus-sasl". The mailing list is available via anonymous IMAP at +imap://cyrus.andrew.cmu.edu/archive.cyrus-sasl or via the web at +http://asg.web.cmu.edu/archive/mailbox.php3?mailbox=archive.cyrus-sasl. + +If you are looking to port SASLv1 applications to SASLv2, please see +doc/appconvert.html + +Bugs can be searched/reported at: http://bugzilla.cyrussasl.org + +DOCUMENTATION +-------------- +Please see doc/index.html for the remainder of the documentation. diff --git a/libs/cyrussasl/include/sasl/Makefile.am b/libs/cyrussasl/include/sasl/Makefile.am new file mode 100644 index 00000000..5ea5be23 --- /dev/null +++ b/libs/cyrussasl/include/sasl/Makefile.am @@ -0,0 +1,65 @@ +# Makefile.am for SASL includes +# Rob Earhart +# +################################################################ +# Copyright (c) 2000 Carnegie Mellon University. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The name "Carnegie Mellon University" must not be used to +# endorse or promote products derived from this software without +# prior written permission. For permission or any other legal +# details, please contact +# Office of Technology Transfer +# Carnegie Mellon University +# 5000 Forbes Avenue +# Pittsburgh, PA 15213-3890 +# (412) 268-4387, fax: (412) 268-7395 +# tech-transfer@andrew.cmu.edu +# +# 4. Redistributions of any form whatsoever must retain the following +# acknowledgment: +# "This product includes software developed by Computing Services +# at Carnegie Mellon University (http://www.cmu.edu/computing/)." +# +# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO +# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE +# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN +# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING +# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +################################################################ + +noinst_HEADERS = gai.h exits.h + +saslincludedir = $(includedir)/sasl +saslinclude_HEADERS = hmac-md5.h md5.h md5global.h sasl.h saslplug.h saslutil.h prop.h + +noinst_PROGRAMS = makemd5 + +makemd5_SOURCES = makemd5.c + +md5global.h: makemd5 + -rm -f md5global.h + ./makemd5 md5global.h + +EXTRA_DIST = NTMakefile +DISTCLEANFILES = md5global.h + +if MACOSX +framedir = /Library/Frameworks/SASL2.framework +frameheaderdir = $(framedir)/Versions/A/Headers +frameheader_DATA = $(saslinclude_HEADERS) +endif diff --git a/libs/cyrussasl/include/sasl/NTMakefile b/libs/cyrussasl/include/sasl/NTMakefile new file mode 100644 index 00000000..49366dc2 --- /dev/null +++ b/libs/cyrussasl/include/sasl/NTMakefile @@ -0,0 +1,65 @@ +# NTMakefile for SASL, include directory +# Alexey Melnikov +# +################################################################ +# Copyright (c) 2003 Carnegie Mellon University. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The name "Carnegie Mellon University" must not be used to +# endorse or promote products derived from this software without +# prior written permission. For permission or any other legal +# details, please contact +# Office of Technology Transfer +# Carnegie Mellon University +# 5000 Forbes Avenue +# Pittsburgh, PA 15213-3890 +# (412) 268-4387, fax: (412) 268-7395 +# tech-transfer@andrew.cmu.edu +# +# 4. Redistributions of any form whatsoever must retain the following +# acknowledgment: +# "This product includes software developed by Computing Services +# at Carnegie Mellon University (http://www.cmu.edu/computing/)." +# +# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO +# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE +# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN +# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING +# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +################################################################ + +#Suppress verbose output from defaulting values +VERBOSE=0 + +!INCLUDE ..\win32\common.mak + +includedir = $(prefix)\include + +saslincludedir = $(includedir)\sasl\ + +saslinclude_HEADERS = hmac-md5.h md5.h sasl.h saslplug.h saslutil.h prop.h + +# The first target get executed by default. We don't want this to be "install" +all: + @echo Nothing to be done for $@ + +# +# /I flag to xcopy tells to treat the last parameter as directory and create all missing levels +# +install: $(saslinclude_HEADERS) + !xcopy sasl*.h $(saslincludedir) /I /F /Y + !xcopy $? $(saslincludedir) /I /F /Y diff --git a/libs/cyrussasl/include/sasl/config.h b/libs/cyrussasl/include/sasl/config.h new file mode 100644 index 00000000..be363b30 --- /dev/null +++ b/libs/cyrussasl/include/sasl/config.h @@ -0,0 +1,607 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.in by autoheader. */ + + +/* acconfig.h - autoheader configuration input */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef CONFIG_H +#define CONFIG_H + + +/* Runtime config file location */ +#define CONFIGDIR "/usr/lib/sasl2:/etc/sasl2" + +/* Do we need a leading _ for dlsym? */ +/* #undef DLSYM_NEEDS_UNDERSCORE */ + +/* Should we build a shared plugin (via dlopen) library? */ +/* #undef DO_DLOPEN */ + +/* should we support sasl_checkapop? */ +#define DO_SASL_CHECKAPOP /**/ + +/* should we support setpass() for SRP? */ +/* #undef DO_SRP_SETPASS */ + +/* should we mutex-wrap calls into the GSS library? */ +#define GSS_USE_MUTEXES /**/ + +/* Enable 'alwaystrue' password verifier? */ +/* #undef HAVE_ALWAYSTRUE */ + +/* Include support for Courier's authdaemond? */ +#define HAVE_AUTHDAEMON /**/ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_DES_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `dns_lookup' function. */ +/* #undef HAVE_DNS_LOOKUP */ + +/* Define to 1 if you have the `dn_expand' function. */ +#define HAVE_DN_EXPAND 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Do we have a getaddrinfo? */ +#define HAVE_GETADDRINFO /**/ + +/* Define to 1 if you have the `getdomainname' function. */ +#define HAVE_GETDOMAINNAME 1 + +/* Define to 1 if you have the `gethostname' function. */ +#define HAVE_GETHOSTNAME 1 + +/* Do we have a getnameinfo() function? */ +#define HAVE_GETNAMEINFO /**/ + +/* Define to 1 if you have the `getpassphrase' function. */ +/* #undef HAVE_GETPASSPHRASE */ + +/* Define to 1 if you have the `getpwnam' function. */ +#define HAVE_GETPWNAM 1 + +/* Define to 1 if you have the `getspnam' function. */ +/* #undef HAVE_GETSPNAM */ + +/* do we have getsubopt()? */ +#define HAVE_GETSUBOPT /**/ + +/* Define to 1 if you have the `gettimeofday' function. */ +#define HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_GSSAPI_GSSAPI_EXT_H */ + +/* Define if you have the gssapi.h header file */ +#define HAVE_GSSAPI_H /**/ + +/* Define to 1 if you have the `gsskrb5_register_acceptor_identity' function. + */ +/* #undef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY */ + +/* Define if your GSSAPI implementation defines GSS_C_NT_HOSTBASED_SERVICE */ +#define HAVE_GSS_C_NT_HOSTBASED_SERVICE /**/ + +/* Define if your GSSAPI implementation defines GSS_C_NT_USER_NAME */ +#define HAVE_GSS_C_NT_USER_NAME /**/ + +/* Define to 1 if you have the `gss_decapsulate_token' function. */ +/* #undef HAVE_GSS_DECAPSULATE_TOKEN */ + +/* Define to 1 if you have the `gss_encapsulate_token' function. */ +/* #undef HAVE_GSS_ENCAPSULATE_TOKEN */ + +/* Define to 1 if you have the `gss_get_name_attribute' function. */ +/* #undef HAVE_GSS_GET_NAME_ATTRIBUTE */ + +/* Define to 1 if you have the `gss_oid_equal' function. */ +/* #undef HAVE_GSS_OID_EQUAL */ + +/* Define to 1 if you have the `inet_aton' function. */ +#define HAVE_INET_ATON 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `jrand48' function. */ +#define HAVE_JRAND48 1 + +/* Do we have Kerberos 4 Support? */ +/* #undef HAVE_KRB */ + +/* Define to 1 if you have the `krb_get_err_text' function. */ +/* #undef HAVE_KRB_GET_ERR_TEXT */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LBER_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_LDAP_H */ + +/* Define to 1 if you have the `resolv' library (-lresolv). */ +#define HAVE_LIBRESOLV 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MALLOC_H */ + +/* Define to 1 if you have the `memcpy' function. */ +#define HAVE_MEMCPY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `mkdir' function. */ +#define HAVE_MKDIR 1 + +/* Do we have mysql support? */ +/* #undef HAVE_MYSQL */ + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Do we have OpenSSL? */ +#define HAVE_OPENSSL /**/ + +/* Use OPIE for server-side OTP? */ +/* #undef HAVE_OPIE */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PAM_PAM_APPL_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_PATHS_H 1 + +/* Do we have Postgres support? */ +/* #undef HAVE_PGSQL */ + +/* Include Support for pwcheck daemon? */ +/* #undef HAVE_PWCHECK */ + +/* Include support for saslauthd? */ +#define HAVE_SASLAUTHD /**/ + +/* Define to 1 if you have the header file. */ +#define HAVE_SECURITY_PAM_APPL_H 1 + +/* Define to 1 if you have the `select' function. */ +#define HAVE_SELECT 1 + +/* Does the system have snprintf()? */ +#define HAVE_SNPRINTF /**/ + +/* Does sockaddr have an sa_len? */ +/* #undef HAVE_SOCKADDR_SA_LEN */ + +/* Define to 1 if you have the `socket' function. */ +#define HAVE_SOCKET 1 + +/* Do we have a socklen_t? */ +#define HAVE_SOCKLEN_T /**/ + +/* Do we have SQLite support? */ +/* #undef HAVE_SQLITE */ + +/* Do we have SQLite3 support? */ +/* #undef HAVE_SQLITE3 */ + +/* Is there an ss_family in sockaddr_storage? */ +#define HAVE_SS_FAMILY /**/ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDARG_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strspn' function. */ +#define HAVE_STRSPN 1 + +/* Define to 1 if you have the `strstr' function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 if you have the `strtol' function. */ +#define HAVE_STRTOL 1 + +/* Do we have struct sockaddr_stroage? */ +#define HAVE_STRUCT_SOCKADDR_STORAGE /**/ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYSEXITS_H 1 + +/* Define to 1 if you have the `syslog' function. */ +#define HAVE_SYSLOG 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYSLOG_H 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_FILE_H 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_UIO_H 1 + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_VARARGS_H */ + +/* Does the system have vsnprintf()? */ +#define HAVE_VSNPRINTF /**/ + +/* define if your compiler has __attribute__ */ +#define HAVE___ATTRIBUTE__ 1 + +/* Should we keep handle to Berkeley DB open in SASLDB plugin? */ +/* #undef KEEP_DB_OPEN */ + +/* Ignore IP Address in Kerberos 4 tickets? */ +/* #undef KRB4_IGNORE_IP_ADDRESS */ + +/* Name of package */ +#define PACKAGE "cyrus-sasl" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* Where do we look for Courier authdaemond's socket? */ +#define PATH_AUTHDAEMON_SOCKET "/dev/null" + +/* Where do we look for saslauthd's socket? */ +#define PATH_SASLAUTHD_RUNDIR "/var/state/saslauthd" + +/* Runtime plugin location */ +#define PLUGINDIR "/usr/lib/sasl2" + +/* Force a preferred mechanism */ +/* #undef PREFER_MECH */ + +/* Location of pwcheck socket */ +/* #undef PWCHECKDIR */ + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Use BerkeleyDB for SASLdb */ +/* #undef SASL_BERKELEYDB */ + +/* Path to default SASLdb database */ +#define SASL_DB_PATH "/etc/sasldb2" + +/* File to use for source of randomness */ +#define SASL_DEV_RANDOM "/dev/random" + +/* Use GDBM for SASLdb */ +/* #undef SASL_GDBM */ + +/* Use NDBM for SASLdb */ +#define SASL_NDBM /**/ + +/* The size of `long', as computed by sizeof. */ +#define SIZEOF_LONG 8 + +/* Link ANONYMOUS Staticly */ +#define STATIC_ANONYMOUS /**/ + +/* Link CRAM-MD5 Staticly */ +#define STATIC_CRAMMD5 /**/ + +/* Link DIGEST-MD5 Staticly */ +#define STATIC_DIGESTMD5 /**/ + +/* Link GSSAPI Staticly */ +/* #undef STATIC_GSSAPIV2 */ + +/* User KERBEROS_V4 Staticly */ +/* #undef STATIC_KERBEROS4 */ + +/* Link ldapdb plugin Staticly */ +/* #undef STATIC_LDAPDB */ + +/* Link LOGIN Staticly */ +#define STATIC_LOGIN + +/* Link NTLM Staticly */ +/* #undef STATIC_NTLM */ + +/* Link OTP Staticly */ +#define STATIC_OTP /**/ + +/* Link PASSDSS Staticly */ +/* #undef STATIC_PASSDSS */ + +/* Link PLAIN Staticly */ +#define STATIC_PLAIN /**/ + +/* Link SASLdb Staticly */ +/* #undef STATIC_SASLDB */ + +/* Link SCRAM Staticly */ +#define STATIC_SCRAM /**/ + +/* Link SQL plugin staticly */ +/* #undef STATIC_SQL */ + +/* Link SRP Staticly */ +/* #undef STATIC_SRP */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if you can safely include both and . */ +#define TIME_WITH_SYS_TIME 1 + +/* Should we try to dlopen() plugins while staticly compiled? */ +/* #undef TRY_DLOPEN_WHEN_STATIC */ + +/* use the doors IPC API for saslauthd? */ +/* #undef USE_DOORS */ + +/* Version number of package */ +#define VERSION "2.1.25" + +/* Use DES */ +#define WITH_DES /**/ + +/* Linking against dmalloc? */ +/* #undef WITH_DMALLOC */ + +/* Use internal RC4 implementation? */ +#define WITH_RC4 /**/ + +/* Use OpenSSL DES Implementation */ +#define WITH_SSL_DES /**/ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Define to `int' if does not define. */ +/* #undef mode_t */ + +/* Define to `int' if does not define. */ +/* #undef pid_t */ + + + + +/* Create a struct iovec if we need one */ +#if !defined(_WIN32) && !defined(HAVE_SYS_UIO_H) +/* (win32 is handled in sasl.h) */ +struct iovec { + char *iov_base; + long iov_len; +}; +#else +#include +#include +#endif + +/* location of the random number generator */ +#ifdef DEV_RANDOM +/* #undef DEV_RANDOM */ +#endif +#define DEV_RANDOM SASL_DEV_RANDOM + +/* if we've got krb_get_err_txt, we might as well use it; + especially since krb_err_txt isn't in some newer distributions + (MIT Kerb for Mac 4 being a notable example). If we don't have + it, we fall back to the krb_err_txt array */ +#ifdef HAVE_KRB_GET_ERR_TEXT +#define get_krb_err_txt krb_get_err_text +#else +#define get_krb_err_txt(X) (krb_err_txt[(X)]) +#endif + +/* Make Solaris happy... */ +#ifndef __EXTENSIONS__ +#define __EXTENSIONS__ +#endif + +/* Make Linux happy... */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif + +#ifndef HAVE___ATTRIBUTE__ +/* Can't use attributes... */ +#define __attribute__(foo) +#endif + +#define SASL_PATH_ENV_VAR "SASL_PATH" +#define SASL_CONF_PATH_ENV_VAR "SASL_CONF_PATH" + +#include +#include +#include +#ifndef WIN32 +# include +# ifdef HAVE_SYS_PARAM_H +# include +# endif +#else /* WIN32 */ +# include +#endif /* WIN32 */ +#include + +#include + +#ifndef HAVE_SOCKLEN_T +typedef unsigned int socklen_t; +#endif /* HAVE_SOCKLEN_T */ + +#ifndef HAVE_STRUCT_SOCKADDR_STORAGE +#define _SS_MAXSIZE 128 /* Implementation specific max size */ +#define _SS_PADSIZE (_SS_MAXSIZE - sizeof (struct sockaddr)) + +struct sockaddr_storage { + struct sockaddr ss_sa; + char __ss_pad2[_SS_PADSIZE]; +}; +# define ss_family ss_sa.sa_family +#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ + +#ifndef AF_INET6 +/* Define it to something that should never appear */ +#define AF_INET6 AF_MAX +#endif + +#ifndef HAVE_GETADDRINFO +#define getaddrinfo sasl_getaddrinfo +#define freeaddrinfo sasl_freeaddrinfo +#define gai_strerror sasl_gai_strerror +#endif + +#ifndef HAVE_GETNAMEINFO +#define getnameinfo sasl_getnameinfo +#endif + +#if !defined(HAVE_GETNAMEINFO) || !defined(HAVE_GETADDRINFO) +#include "gai.h" +#endif + +#ifndef AI_NUMERICHOST /* support glibc 2.0.x */ +#define AI_NUMERICHOST 4 +#define NI_NUMERICHOST 2 +#define NI_NAMEREQD 4 +#define NI_NUMERICSERV 8 +#endif + +/* Defined in RFC 1035. max strlen is only 253 due to length bytes. */ +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 255 +#endif + +// #ifndef HAVE_SYSEXITS_H +// #include "exits.h" +// #else +// #include "sysexits.h" +// #endif + +/* Get the correct time.h */ +#if TIME_WITH_SYS_TIME +# include +# include +#else +# if HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +#ifndef HIER_DELIMITER +#define HIER_DELIMITER '/' +#endif + +#endif /* CONFIG_H */ + diff --git a/libs/cyrussasl/include/sasl/exits.h b/libs/cyrussasl/include/sasl/exits.h new file mode 100644 index 00000000..464cb11b --- /dev/null +++ b/libs/cyrussasl/include/sasl/exits.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)sysexits.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _SYSEXITS_H_ +#define _SYSEXITS_H_ + +/* + * SYSEXITS.H -- Exit status codes for system programs. + * + * This include file attempts to categorize possible error + * exit statuses for system programs, notably delivermail + * and the Berkeley network. + * + * Error numbers begin at EX__BASE to reduce the possibility of + * clashing with other exit statuses that random programs may + * already return. The meaning of the codes is approximately + * as follows: + * + * EX_USAGE -- The command was used incorrectly, e.g., with + * the wrong number of arguments, a bad flag, a bad + * syntax in a parameter, or whatever. + * EX_DATAERR -- The input data was incorrect in some way. + * This should only be used for user's data & not + * system files. + * EX_NOINPUT -- An input file (not a system file) did not + * exist or was not readable. This could also include + * errors like "No message" to a mailer (if it cared + * to catch it). + * EX_NOUSER -- The user specified did not exist. This might + * be used for mail addresses or remote logins. + * EX_NOHOST -- The host specified did not exist. This is used + * in mail addresses or network requests. + * EX_UNAVAILABLE -- A service is unavailable. This can occur + * if a support program or file does not exist. This + * can also be used as a catchall message when something + * you wanted to do doesn't work, but you don't know + * why. + * EX_SOFTWARE -- An internal software error has been detected. + * This should be limited to non-operating system related + * errors as possible. + * EX_OSERR -- An operating system error has been detected. + * This is intended to be used for such things as "cannot + * fork", "cannot create pipe", or the like. It includes + * things like getuid returning a user that does not + * exist in the passwd file. + * EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp, + * etc.) does not exist, cannot be opened, or has some + * sort of error (e.g., syntax error). + * EX_CANTCREAT -- A (user specified) output file cannot be + * created. + * EX_IOERR -- An error occurred while doing I/O on some file. + * EX_TEMPFAIL -- temporary failure, indicating something that + * is not really an error. In sendmail, this means + * that a mailer (e.g.) could not create a connection, + * and the request should be reattempted later. + * EX_PROTOCOL -- the remote system returned something that + * was "not possible" during a protocol exchange. + * EX_NOPERM -- You did not have sufficient permission to + * perform the operation. This is not intended for + * file system problems, which should use NOINPUT or + * CANTCREAT, but rather for higher level permissions. + */ + +#define EX_OK 0 /* successful termination */ + +#define EX__BASE 64 /* base value for error messages */ + +#define EX_USAGE 64 /* command line usage error */ +#define EX_DATAERR 65 /* data format error */ +#define EX_NOINPUT 66 /* cannot open input */ +#define EX_NOUSER 67 /* addressee unknown */ +#define EX_NOHOST 68 /* host name unknown */ +#define EX_UNAVAILABLE 69 /* service unavailable */ +#define EX_SOFTWARE 70 /* internal software error */ +#define EX_OSERR 71 /* system error (e.g., can't fork) */ +#define EX_OSFILE 72 /* critical OS file missing */ +#define EX_CANTCREAT 73 /* can't create (user) output file */ +#define EX_IOERR 74 /* input/output error */ +#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ +#define EX_PROTOCOL 76 /* remote error in protocol */ +#define EX_NOPERM 77 /* permission denied */ +#define EX_CONFIG 78 /* configuration error */ + +#define EX__MAX 78 /* maximum listed value */ + +#endif /* !_SYSEXITS_H_ */ diff --git a/libs/cyrussasl/include/sasl/gai.h b/libs/cyrussasl/include/sasl/gai.h new file mode 100644 index 00000000..d77ad112 --- /dev/null +++ b/libs/cyrussasl/include/sasl/gai.h @@ -0,0 +1,108 @@ +/* + * Mar 8, 2000 by Hajimu UMEMOTO + * $Id: gai.h,v 1.8 2006/04/10 13:36:20 mel Exp $ + * + * This module is besed on ssh-1.2.27-IPv6-1.5 written by + * KIKUCHI Takahiro + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * fake library for ssh + * + * This file is included in getaddrinfo.c and getnameinfo.c. + * See getaddrinfo.c and getnameinfo.c. + */ + +#ifndef _GAI_H_ +#define _GAI_H_ + +#ifndef NI_MAXHOST +#define NI_MAXHOST 1025 +#endif +#ifndef NI_MAXSERV +#define NI_MAXSERV 32 +#endif + +/* for old netdb.h */ +#ifndef EAI_NODATA +#define EAI_NODATA 1 +#define EAI_MEMORY 2 +#define EAI_FAMILY 5 /* ai_family not supported */ +#define EAI_SERVICE 9 /* servname not supported for ai_socktype */ +#endif + +/* dummy value for old netdb.h */ +#ifndef AI_PASSIVE +#define AI_PASSIVE 1 +#define AI_CANONNAME 2 +struct addrinfo { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for hostname */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo *ai_next; /* next structure in linked list */ +}; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HAVE_GETNAMEINFO +int getnameinfo(const struct sockaddr *, socklen_t, char *, + size_t, char *, size_t, int); +#endif + +#ifndef HAVE_GETADDRINFO +int getaddrinfo(const char *, const char *, + const struct addrinfo *, struct addrinfo **); +void freeaddrinfo(struct addrinfo *); +char *gai_strerror(int); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/cyrussasl/include/sasl/hmac-md5.h b/libs/cyrussasl/include/sasl/hmac-md5.h new file mode 100755 index 00000000..babe0031 --- /dev/null +++ b/libs/cyrussasl/include/sasl/hmac-md5.h @@ -0,0 +1,59 @@ +/* hmac-md5.h -- HMAC_MD5 functions + */ + +#ifndef HMAC_MD5_H +#define HMAC_MD5_H 1 + +#define HMAC_MD5_SIZE 16 + +/* intermediate MD5 context */ +typedef struct HMAC_MD5_CTX_s { + MD5_CTX ictx, octx; +} HMAC_MD5_CTX; + +/* intermediate HMAC state + * values stored in network byte order (Big Endian) + */ +typedef struct HMAC_MD5_STATE_s { + UINT4 istate[4]; + UINT4 ostate[4]; +} HMAC_MD5_STATE; + +#ifdef __cplusplus +extern "C" { +#endif + +/* One step hmac computation + * + * digest may be same as text or key + */ +void _sasl_hmac_md5(const unsigned char *text, int text_len, + const unsigned char *key, int key_len, + unsigned char digest[HMAC_MD5_SIZE]); + +/* create context from key + */ +void _sasl_hmac_md5_init(HMAC_MD5_CTX *hmac, + const unsigned char *key, int key_len); + +/* precalculate intermediate state from key + */ +void _sasl_hmac_md5_precalc(HMAC_MD5_STATE *hmac, + const unsigned char *key, int key_len); + +/* initialize context from intermediate state + */ +void _sasl_hmac_md5_import(HMAC_MD5_CTX *hmac, HMAC_MD5_STATE *state); + +#define _sasl_hmac_md5_update(hmac, text, text_len) _sasl_MD5Update(&(hmac)->ictx, (text), (text_len)) + +/* finish hmac from intermediate result. Intermediate result is zeroed. + */ +void _sasl_hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE], + HMAC_MD5_CTX *hmac); + +#ifdef __cplusplus +} +#endif + +#endif /* HMAC_MD5_H */ diff --git a/libs/cyrussasl/include/sasl/makemd5.c b/libs/cyrussasl/include/sasl/makemd5.c new file mode 100644 index 00000000..eaf78aa1 --- /dev/null +++ b/libs/cyrussasl/include/sasl/makemd5.c @@ -0,0 +1,246 @@ +/* creates the md5global.h file. + * Derived from KTH kerberos library bits.c program + * Tim Martin + * $Id: makemd5.c,v 1.4 2003/02/13 19:55:52 rjs3 Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Copyright (c) 1997, 1998 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Kungliga Tekniska + * Högskolan and its contributors. + * + * 4. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + + + +#include +#include +#include +#include + + +static void +my_strupr(char *s) +{ + char *p = s; + while(*p){ + if(islower((int) *p)) + *p = toupper((int) *p); + p++; + } +} + + +#define BITSIZE(TYPE) \ +{ \ + int b = 0; TYPE x = 1, zero = 0; char *pre = "U"; \ + char tmp[128], tmp2[128]; \ + while(x){ x <<= 1; b++; if(x < zero) pre=""; } \ + if(b >= len){ \ + int tabs; \ + sprintf(tmp, "%sINT%d" , pre, len/8); \ + sprintf(tmp2, "typedef %s %s;", #TYPE, tmp); \ + my_strupr(tmp); \ + tabs = 5 - strlen(tmp2) / 8; \ + fprintf(f, "%s", tmp2); \ + while(tabs-- > 0) fprintf(f, "\t"); \ + fprintf(f, "/* %2d bits */\n", b); \ + return; \ + } \ +} + +static void +try_signed(FILE *f, int len) +{ + BITSIZE(signed char); + BITSIZE(short); + BITSIZE(int); + BITSIZE(long); +#ifdef HAVE_LONG_LONG + BITSIZE(long long); +#endif + fprintf(f, "/* There is no %d bit type */\n", len); +} + +static void +try_unsigned(FILE *f, int len) +{ + BITSIZE(unsigned char); + BITSIZE(unsigned short); + BITSIZE(unsigned int); + BITSIZE(unsigned long); +#ifdef HAVE_LONG_LONG + BITSIZE(unsigned long long); +#endif + fprintf(f, "/* There is no %d bit type */\n", len); +} + +static int print_pre(FILE *f) +{ + fprintf(f, + "/* GLOBAL.H - RSAREF types and constants\n" + " */\n" + "#ifndef MD5GLOBAL_H\n" + "#define MD5GLOBAL_H\n" + "\n" + "/* PROTOTYPES should be set to one if and only if the compiler supports\n" + " function argument prototyping.\n" + "The following makes PROTOTYPES default to 0 if it has not already\n" + " been defined with C compiler flags.\n" + " */\n" + "#ifndef PROTOTYPES\n" + "#define PROTOTYPES 0\n" + "#endif\n" + "\n" + "/* POINTER defines a generic pointer type */\n" + "typedef unsigned char *POINTER;\n" + "\n" + ); + return 1; +} + +static int print_post(FILE *f) +{ + fprintf(f, "\n" + "/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.\n" + "If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it\n" + "returns an empty list.\n" + "*/\n" + "#if PROTOTYPES\n" + "#define PROTO_LIST(list) list\n" + "#else\n" + "#define PROTO_LIST(list) ()\n" + "#endif\n" + "\n" + "#endif /* MD5GLOBAL_H */\n\n" + ); + + return 1; +} + + +int main(int argc, char **argv) +{ + FILE *f; + char *fn, *hb; + + if(argc < 2){ + fn = "bits.h"; + hb = "__BITS_H__"; + f = stdout; + } else { + char *p; + fn = argv[1]; + hb = malloc(strlen(fn) + 5); + sprintf(hb, "__%s__", fn); + for(p = hb; *p; p++){ + if(!isalnum((int) *p)) + *p = '_'; + } + f = fopen(argv[1], "w"); + } + + print_pre(f); + +#ifndef HAVE_INT8_T + try_signed (f, 8); +#endif /* HAVE_INT8_T */ +#ifndef HAVE_INT16_T + try_signed (f, 16); +#endif /* HAVE_INT16_T */ +#ifndef HAVE_INT32_T + try_signed (f, 32); +#endif /* HAVE_INT32_T */ +#ifndef HAVE_INT64_T + try_signed (f, 64); +#endif /* HAVE_INT64_T */ + +#ifndef HAVE_U_INT8_T + try_unsigned (f, 8); +#endif /* HAVE_INT8_T */ +#ifndef HAVE_U_INT16_T + try_unsigned (f, 16); +#endif /* HAVE_U_INT16_T */ +#ifndef HAVE_U_INT32_T + try_unsigned (f, 32); +#endif /* HAVE_U_INT32_T */ +#ifndef HAVE_U_INT64_T + try_unsigned (f, 64); +#endif /* HAVE_U_INT64_T */ + + print_post(f); + + fclose(f); + + return 0; +} diff --git a/libs/cyrussasl/include/sasl/md5.h b/libs/cyrussasl/include/sasl/md5.h new file mode 100644 index 00000000..2f3745dc --- /dev/null +++ b/libs/cyrussasl/include/sasl/md5.h @@ -0,0 +1,42 @@ +/* MD5.H - header file for MD5C.C + */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. +These notices must be retained in any copies of any part of this +documentation and/or software. + */ + +/* MD5 context. */ +typedef struct { + UINT4 state[4]; /* state (ABCD) */ + UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ + unsigned char buffer[64]; /* input buffer */ +} MD5_CTX; + +#ifdef __cplusplus +extern "C" { +#endif + +void _sasl_MD5Init (MD5_CTX *); +void _sasl_MD5Update (MD5_CTX *, const unsigned char *, unsigned int); +void _sasl_MD5Final (unsigned char [16], MD5_CTX *); + +#ifdef __cplusplus +} +#endif diff --git a/libs/cyrussasl/include/sasl/md5global.h b/libs/cyrussasl/include/sasl/md5global.h new file mode 100644 index 00000000..fbd7455f --- /dev/null +++ b/libs/cyrussasl/include/sasl/md5global.h @@ -0,0 +1,38 @@ +/* GLOBAL.H - RSAREF types and constants + */ +#ifndef MD5GLOBAL_H +#define MD5GLOBAL_H + +/* PROTOTYPES should be set to one if and only if the compiler supports + function argument prototyping. +The following makes PROTOTYPES default to 0 if it has not already + been defined with C compiler flags. + */ +#ifndef PROTOTYPES +#define PROTOTYPES 0 +#endif + +/* POINTER defines a generic pointer type */ +typedef unsigned char *POINTER; + +typedef signed char INT1; /* 8 bits */ +typedef short INT2; /* 16 bits */ +typedef int INT4; /* 32 bits */ +/* There is no 64 bit type */ +typedef unsigned char UINT1; /* 8 bits */ +typedef unsigned short UINT2; /* 16 bits */ +typedef unsigned int UINT4; /* 32 bits */ +/* There is no 64 bit type */ + +/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. +If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it +returns an empty list. +*/ +#if PROTOTYPES +#define PROTO_LIST(list) list +#else +#define PROTO_LIST(list) () +#endif + +#endif /* MD5GLOBAL_H */ + diff --git a/libs/cyrussasl/include/sasl/prop.h b/libs/cyrussasl/include/sasl/prop.h new file mode 100644 index 00000000..fed3fa77 --- /dev/null +++ b/libs/cyrussasl/include/sasl/prop.h @@ -0,0 +1,186 @@ +/* prop.h -- property request/response management routines + * + * Author: Chris Newman + * Removal of implementation-specific details by: Rob Siemborski + * + * This is intended to be used to create a list of properties to request, + * and _then_ request values for all properties. Any change to the request + * list will discard any existing values. This assumption allows a very + * efficient and simple memory model. This was designed for SASL API auxiliary + * property support, but would be fine for other contexts where this property + * model is appropriate. + * + * The "struct propctx" is allocated by prop_new and is a fixed size structure. + * If a prop_init() call were added, it would be reasonable to embed a "struct + * propctx" in another structure. prop_new also allocates a pool of memory + * (in the vbase field) which will be used for an array of "struct propval" + * to list all the requested properties. + * + * Properties may be multi-valued. + */ + +#ifndef PROP_H +#define PROP_H 1 + +/* The following ifdef block is the standard way of creating macros + * which make exporting from a DLL simpler. All files within this DLL + * are compiled with the LIBSASL_EXPORTS symbol defined on the command + * line. this symbol should not be defined on any project that uses + * this DLL. This way any other project whose source files include + * this file see LIBSASL_API functions as being imported from a DLL, + * wheras this DLL sees symbols defined with this macro as being + * exported. */ +/* Under Unix, life is simpler: we just need to mark library functions + * as extern. (Technically, we don't even have to do that.) */ +#ifdef WIN32 +# ifdef LIBSASL_EXPORTS +# define LIBSASL_API extern __declspec(dllexport) +# else /* LIBSASL_EXPORTS */ +# define LIBSASL_API extern __declspec(dllimport) +# endif /* LIBSASL_EXPORTS */ +#else /* WIN32 */ +# define LIBSASL_API extern +#endif /* WIN32 */ + +/* Same as above, but used during a variable declaration. */ +#ifdef WIN32 +# ifdef LIBSASL_EXPORTS +# define LIBSASL_VAR extern __declspec(dllexport) +# else /* LIBSASL_EXPORTS */ +# define LIBSASL_VAR extern __declspec(dllimport) +# endif /* LIBSASL_EXPORTS */ +#else /* WIN32 */ +# define LIBSASL_VAR extern +#endif /* WIN32 */ + +/* the resulting structure for property values + */ +struct propval { + const char *name; /* name of property; NULL = end of list */ + /* same pointer used in request will be used here */ + const char **values; /* list of strings, values == NULL if property not + * found, *values == NULL if property found with + * no values */ + unsigned nvalues; /* total number of value strings */ + unsigned valsize; /* total size in characters of all value strings */ +}; + +/* + * private internal structure + */ +#define PROP_DEFAULT 4 /* default number of propvals to assume */ +struct propctx; + +#ifdef __cplusplus +extern "C" { +#endif + +/* create a property context + * estimate -- an estimate of the storage needed for requests & responses + * 0 will use module default + * returns a new property context on success and NULL on any error + */ +LIBSASL_API struct propctx *prop_new(unsigned estimate); + +/* create new propctx which duplicates the contents of an existing propctx + * returns SASL_OK on success + * possible other return values include: SASL_NOMEM, SASL_BADPARAM + */ +LIBSASL_API int prop_dup(struct propctx *src_ctx, struct propctx **dst_ctx); + +/* Add property names to request + * ctx -- context from prop_new() + * names -- list of property names; must persist until context freed + * or requests cleared (This extends to other contexts that + * are dup'ed from this one, and their children, etc) + * + * NOTE: may clear values from context as side-effect + * returns SASL_OK on success + * possible other return values include: SASL_NOMEM, SASL_BADPARAM + */ +LIBSASL_API int prop_request(struct propctx *ctx, const char **names); + +/* return array of struct propval from the context + * return value persists until next call to + * prop_request, prop_clear or prop_dispose on context + * + * returns NULL on error + */ +LIBSASL_API const struct propval *prop_get(struct propctx *ctx); + +/* Fill in an array of struct propval based on a list of property names + * return value persists until next call to + * prop_request, prop_clear or prop_dispose on context + * returns number of matching properties which were found (values != NULL) + * if a name requested here was never requested by a prop_request, then + * the name field of the associated vals entry will be set to NULL + * + * The vals array MUST be atleast as long as the names array. + * + * returns # of matching properties on success + * possible other return values include: SASL_BADPARAM + */ +LIBSASL_API int prop_getnames(struct propctx *ctx, const char **names, + struct propval *vals); + +/* clear values and optionally requests from property context + * ctx -- property context + * requests -- 0 = don't clear requests, 1 = clear requests + */ +LIBSASL_API void prop_clear(struct propctx *ctx, int requests); + +/* erase the value of a property + */ +LIBSASL_API void prop_erase(struct propctx *ctx, const char *name); + +/* dispose of property context + * ctx -- is disposed and set to NULL; noop if ctx or *ctx is NULL + */ +LIBSASL_API void prop_dispose(struct propctx **ctx); + + +/****fetcher interfaces****/ + +/* format the requested property names into a string + * ctx -- context from prop_new()/prop_request() + * sep -- separator between property names (unused if none requested) + * seplen -- length of separator, if < 0 then strlen(sep) will be used + * outbuf -- output buffer + * outmax -- maximum length of output buffer including NUL terminator + * outlen -- set to length of output string excluding NUL terminator + * returns SASL_OK on success + * returns SASL_BADPARAM or amount of additional space needed on failure + */ +LIBSASL_API int prop_format(struct propctx *ctx, const char *sep, int seplen, + char *outbuf, unsigned outmax, unsigned *outlen); + +/* add a property value to the context + * ctx -- context from prop_new()/prop_request() + * name -- name of property to which value will be added + * if NULL, add to the same name as previous prop_set/setvals call + * value -- a value for the property; will be copied into context + * if NULL, remove existing values + * vallen -- length of value, if <= 0 then strlen(value) will be used + * returns SASL_OK on success + * possible error return values include: SASL_BADPARAM, SASL_NOMEM + */ +LIBSASL_API int prop_set(struct propctx *ctx, const char *name, + const char *value, int vallen); + +/* set the values for a property + * ctx -- context from prop_new()/prop_request() + * name -- name of property to which value will be added + * if NULL, add to the same name as previous prop_set/setvals call + * values -- array of values, ending in NULL. Each value is a NUL terminated + * string + * returns SASL_OK on success + * possible error return values include: SASL_BADPARAM, SASL_NOMEM + */ +LIBSASL_API int prop_setvals(struct propctx *ctx, const char *name, + const char **values); + +#ifdef __cplusplus +} +#endif + +#endif /* PROP_H */ diff --git a/libs/cyrussasl/include/sasl/sasl.h b/libs/cyrussasl/include/sasl/sasl.h new file mode 100755 index 00000000..fef4d510 --- /dev/null +++ b/libs/cyrussasl/include/sasl/sasl.h @@ -0,0 +1,1321 @@ +/* This is a proposed C API for support of SASL + * + *********************************IMPORTANT******************************* + * send email to chris.newman@innosoft.com and cyrus-bugs@andrew.cmu.edu * + * if you need to add new error codes, callback types, property values, * + * etc. It is important to keep the multiple implementations of this * + * API from diverging. * + *********************************IMPORTANT******************************* + * + * Basic Type Summary: + * sasl_conn_t Context for a SASL connection negotiation + * sasl_ssf_t Security layer Strength Factor + * sasl_callback_t A typed client/server callback function and context + * sasl_interact_t A client interaction descriptor + * sasl_secret_t A client password + * sasl_rand_t Random data context structure + * sasl_security_properties_t An application's required security level + * + * Callbacks: + * sasl_getopt_t client/server: Get an option value + * sasl_logmsg_t client/server: Log message handler + * sasl_getsimple_t client: Get user/language list + * sasl_getsecret_t client: Get authentication secret + * sasl_chalprompt_t client: Display challenge and prompt for response + * + * Server only Callbacks: + * sasl_authorize_t user authorization policy callback + * sasl_getconfpath_t get path to search for config file + * sasl_server_userdb_checkpass check password and auxprops in userdb + * sasl_server_userdb_setpass set password in userdb + * sasl_server_canon_user canonicalize username routine + * + * Client/Server Function Summary: + * sasl_done Release all SASL global state + * sasl_dispose Connection done: Dispose of sasl_conn_t + * sasl_getprop Get property (e.g., user name, security layer info) + * sasl_setprop Set property (e.g., external ssf) + * sasl_errdetail Generate string from last error on connection + * sasl_errstring Translate sasl error code to a string + * sasl_encode Encode data to send using security layer + * sasl_decode Decode data received using security layer + * + * Utility functions: + * sasl_encode64 Encode data to send using MIME base64 encoding + * sasl_decode64 Decode data received using MIME base64 encoding + * sasl_erasebuffer Erase a buffer + * + * Client Function Summary: + * sasl_client_init Load and initialize client plug-ins (call once) + * sasl_client_new Initialize client connection context: sasl_conn_t + * sasl_client_start Select mechanism for connection + * sasl_client_step Perform one authentication step + * + * Server Function Summary + * sasl_server_init Load and initialize server plug-ins (call once) + * sasl_server_new Initialize server connection context: sasl_conn_t + * sasl_listmech Create list of available mechanisms + * sasl_server_start Begin an authentication exchange + * sasl_server_step Perform one authentication exchange step + * sasl_checkpass Check a plaintext passphrase + * sasl_checkapop Check an APOP challenge/response (uses pseudo "APOP" + * mechanism similar to CRAM-MD5 mechanism; optional) + * sasl_user_exists Check if user exists + * sasl_setpass Change a password or add a user entry + * sasl_auxprop_request Request auxiliary properties + * sasl_auxprop_getctx Get auxiliary property context for connection + * sasl_auxprop_store Store a set of auxiliary properties + * + * Basic client model: + * 1. client calls sasl_client_init() at startup to load plug-ins + * 2. when connection formed, call sasl_client_new() + * 3. once list of supported mechanisms received from server, client + * calls sasl_client_start(). goto 4a + * 4. client calls sasl_client_step() + * [4a. If SASL_INTERACT, fill in prompts and goto 4 + * -- doesn't happen if callbacks provided] + * 4b. If SASL error, goto 7 or 3 + * 4c. If SASL_OK, continue or goto 6 if last server response was success + * 5. send message to server, wait for response + * 5a. On data or success with server response, goto 4 + * 5b. On failure goto 7 or 3 + * 5c. On success with no server response continue + * 6. continue with application protocol until connection closes + * call sasl_getprop/sasl_encode/sasl_decode() if using security layer + * 7. call sasl_dispose(), may return to step 2 + * 8. call sasl_done() when program terminates + * + * Basic Server model: + * 1. call sasl_server_init() at startup to load plug-ins + * 2. On connection, call sasl_server_new() + * 3. call sasl_listmech() and send list to client] + * 4. after client AUTH command, call sasl_server_start(), goto 5a + * 5. call sasl_server_step() + * 5a. If SASL_CONTINUE, output to client, wait response, repeat 5 + * 5b. If SASL error, then goto 7 + * 5c. If SASL_OK, move on + * 6. continue with application protocol until connection closes + * call sasl_getprop to get username + * call sasl_getprop/sasl_encode/sasl_decode() if using security layer + * 7. call sasl_dispose(), may return to step 2 + * 8. call sasl_done() when program terminates + * + ************************************************* + * IMPORTANT NOTE: server realms / username syntax + * + * If a user name contains a "@", then the rightmost "@" in the user name + * separates the account name from the realm in which this account is + * located. A single server may support multiple realms. If the + * server knows the realm at connection creation time (e.g., a server + * with multiple IP addresses tightly binds one address to a specific + * realm) then that realm must be passed in the user_realm field of + * the sasl_server_new call. If user_realm is non-empty and an + * unqualified user name is supplied, then the canon_user facility is + * expected to append "@" and user_realm to the user name. The canon_user + * facility may treat other characters such as "%" as equivalent to "@". + * + * If the server forbids the use of "@" in user names for other + * purposes, this simplifies security validation. + */ + +#ifndef SASL_H +#define SASL_H 1 + +/* Keep in sync with win32/common.mak */ +#define SASL_VERSION_MAJOR 2 +#define SASL_VERSION_MINOR 1 +#define SASL_VERSION_STEP 26 + +/* A convenience macro: same as was defined in the OpenLDAP LDAPDB */ +#define SASL_VERSION_FULL ((SASL_VERSION_MAJOR << 16) |\ + (SASL_VERSION_MINOR << 8) | SASL_VERSION_STEP) + +#include "prop.h" + +/************* + * Basic API * + *************/ + +/* SASL result codes: */ +#define SASL_CONTINUE 1 /* another step is needed in authentication */ +#define SASL_OK 0 /* successful result */ +#define SASL_FAIL -1 /* generic failure */ +#define SASL_NOMEM -2 /* memory shortage failure */ +#define SASL_BUFOVER -3 /* overflowed buffer */ +#define SASL_NOMECH -4 /* mechanism not supported */ +#define SASL_BADPROT -5 /* bad protocol / cancel */ +#define SASL_NOTDONE -6 /* can't request info until later in exchange */ +#define SASL_BADPARAM -7 /* invalid parameter supplied */ +#define SASL_TRYAGAIN -8 /* transient failure (e.g., weak key) */ +#define SASL_BADMAC -9 /* integrity check failed */ +#define SASL_NOTINIT -12 /* SASL library not initialized */ + /* -- client only codes -- */ +#define SASL_INTERACT 2 /* needs user interaction */ +#define SASL_BADSERV -10 /* server failed mutual authentication step */ +#define SASL_WRONGMECH -11 /* mechanism doesn't support requested feature */ + /* -- server only codes -- */ +#define SASL_BADAUTH -13 /* authentication failure */ +#define SASL_NOAUTHZ -14 /* authorization failure */ +#define SASL_TOOWEAK -15 /* mechanism too weak for this user */ +#define SASL_ENCRYPT -16 /* encryption needed to use mechanism */ +#define SASL_TRANS -17 /* One time use of a plaintext password will + enable requested mechanism for user */ +#define SASL_EXPIRED -18 /* passphrase expired, has to be reset */ +#define SASL_DISABLED -19 /* account disabled */ +#define SASL_NOUSER -20 /* user not found */ +#define SASL_BADVERS -23 /* version mismatch with plug-in */ +#define SASL_UNAVAIL -24 /* remote authentication server unavailable */ +#define SASL_NOVERIFY -26 /* user exists, but no verifier for user */ + /* -- codes for password setting -- */ +#define SASL_PWLOCK -21 /* passphrase locked */ +#define SASL_NOCHANGE -22 /* requested change was not needed */ +#define SASL_WEAKPASS -27 /* passphrase is too weak for security policy */ +#define SASL_NOUSERPASS -28 /* user supplied passwords not permitted */ +#define SASL_NEED_OLD_PASSWD -29 /* sasl_setpass needs old password in order + to perform password change */ +#define SASL_CONSTRAINT_VIOLAT -30 /* a property can't be stored, + because of some constrains/policy violation */ + +#define SASL_BADBINDING -32 /* channel binding failure */ + +/* max size of a sasl mechanism name */ +#define SASL_MECHNAMEMAX 20 + +#ifdef _WIN32 +/* Define to have the same layout as a WSABUF */ +#ifndef STRUCT_IOVEC_DEFINED +#define STRUCT_IOVEC_DEFINED 1 +struct iovec { + long iov_len; + char *iov_base; +}; +#endif +#else +struct iovec; /* Defined in OS headers */ +#endif + + +/* per-connection SASL negotiation state for client or server + */ +typedef struct sasl_conn sasl_conn_t; + +/* Plain text password structure. + * len is the length of the password, data is the text. + */ +typedef struct sasl_secret { + unsigned long len; + unsigned char data[1]; /* variable sized */ +} sasl_secret_t; + +/* random data context structure + */ +typedef struct sasl_rand_s sasl_rand_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/**************************** + * Configure Basic Services * + ****************************/ + +/* the following functions are used to adjust how allocation and mutexes work + * they must be called before all other SASL functions: + */ + +/* memory allocation functions which may optionally be replaced: + */ +typedef void *sasl_malloc_t(size_t); +typedef void *sasl_calloc_t(size_t, size_t); +typedef void *sasl_realloc_t(void *, size_t); +typedef void sasl_free_t(void *); + +LIBSASL_API void sasl_set_alloc(sasl_malloc_t *, + sasl_calloc_t *, + sasl_realloc_t *, + sasl_free_t *); + +/* mutex functions which may optionally be replaced: + * sasl_mutex_alloc allocates a mutex structure + * sasl_mutex_lock blocks until mutex locked + * returns -1 on deadlock or parameter error + * returns 0 on success + * sasl_mutex_unlock unlocks mutex if it's locked + * returns -1 if not locked or parameter error + * returns 0 on success + * sasl_mutex_free frees a mutex structure + */ +typedef void *sasl_mutex_alloc_t(void); +typedef int sasl_mutex_lock_t(void *mutex); +typedef int sasl_mutex_unlock_t(void *mutex); +typedef void sasl_mutex_free_t(void *mutex); +LIBSASL_API void sasl_set_mutex(sasl_mutex_alloc_t *, sasl_mutex_lock_t *, + sasl_mutex_unlock_t *, sasl_mutex_free_t *); + +/***************************** + * Security preference types * + *****************************/ + +/* security layer strength factor -- an unsigned integer usable by the caller + * to specify approximate security layer strength desired. Roughly + * correlated to effective key length for encryption. + * 0 = no protection + * 1 = integrity protection only + * 40 = 40-bit DES or 40-bit RC2/RC4 + * 56 = DES + * 112 = triple-DES + * 128 = 128-bit RC2/RC4/BLOWFISH + * 256 = baseline AES + */ +typedef unsigned sasl_ssf_t; + +/* usage flags provided to sasl_server_new and sasl_client_new: + */ +#define SASL_SUCCESS_DATA 0x0004 /* server supports data on success */ +#define SASL_NEED_PROXY 0x0008 /* require a mech that allows proxying */ +#define SASL_NEED_HTTP 0x0010 /* require a mech that can do HTTP auth */ + +/*************************** + * Security Property Types * + ***************************/ + +/* Structure specifying the client or server's security policy + * and optional additional properties. + */ + +/* These are the various security flags apps can specify. */ +/* NOPLAINTEXT -- don't permit mechanisms susceptible to simple + * passive attack (e.g., PLAIN, LOGIN) + * NOACTIVE -- protection from active (non-dictionary) attacks + * during authentication exchange. + * Authenticates server. + * NODICTIONARY -- don't permit mechanisms susceptible to passive + * dictionary attack + * FORWARD_SECRECY -- require forward secrecy between sessions + * (breaking one won't help break next) + * NOANONYMOUS -- don't permit mechanisms that allow anonymous login + * PASS_CREDENTIALS -- require mechanisms which pass client + * credentials, and allow mechanisms which can pass + * credentials to do so + * MUTUAL_AUTH -- require mechanisms which provide mutual + * authentication + */ +#define SASL_SEC_NOPLAINTEXT 0x0001 +#define SASL_SEC_NOACTIVE 0x0002 +#define SASL_SEC_NODICTIONARY 0x0004 +#define SASL_SEC_FORWARD_SECRECY 0x0008 +#define SASL_SEC_NOANONYMOUS 0x0010 +#define SASL_SEC_PASS_CREDENTIALS 0x0020 +#define SASL_SEC_MUTUAL_AUTH 0x0040 +#define SASL_SEC_MAXIMUM 0x00FF + +typedef struct sasl_security_properties +{ + /* security strength factor + * min_ssf = minimum acceptable final level + * max_ssf = maximum acceptable final level + */ + sasl_ssf_t min_ssf; + sasl_ssf_t max_ssf; + + /* Maximum security layer receive buffer size. + * 0=security layer not supported + */ + unsigned maxbufsize; + + /* bitfield for attacks to protect against */ + unsigned security_flags; + + /* NULL terminated array of additional property names, values */ + const char **property_names; + const char **property_values; +} sasl_security_properties_t; + +/****************** + * Callback types * + ******************/ + +/* + * Extensible type for a client/server callbacks + * id -- identifies callback type + * proc -- procedure call arguments vary based on id + * context -- context passed to procedure + */ +/* Note that any memory that is allocated by the callback needs to be + * freed by the application, be it via function call or interaction. + * + * It may be freed after sasl_*_step returns SASL_OK. if the mechanism + * requires this information to persist (for a security layer, for example) + * it must maintain a private copy. + */ +typedef struct sasl_callback { + /* Identifies the type of the callback function. + * Mechanisms must ignore callbacks with id's they don't recognize. + */ + unsigned long id; + int (*proc)(void); /* Callback function. Types of arguments vary by 'id' */ + void *context; +} sasl_callback_t; + +/* callback ids & functions: + */ +#define SASL_CB_LIST_END 0 /* end of list */ + +/* option reading callback -- this allows a SASL configuration to be + * encapsulated in the caller's configuration system. Some implementations + * may use default config file(s) if this is omitted. Configuration items + * may be plugin-specific and are arbitrary strings. + * + * inputs: + * context -- option context from callback record + * plugin_name -- name of plugin (NULL = general SASL option) + * option -- name of option + * output: + * result -- set to result which persists until next getopt in + * same thread, unchanged if option not found + * len -- length of result (may be NULL) + * returns: + * SASL_OK -- no error + * SASL_FAIL -- error + */ +typedef int sasl_getopt_t(void *context, const char *plugin_name, + const char *option, + const char **result, unsigned *len); +#define SASL_CB_GETOPT 1 + +/* Logging levels for use with the logging callback function. */ +#define SASL_LOG_NONE 0 /* don't log anything */ +#define SASL_LOG_ERR 1 /* log unusual errors (default) */ +#define SASL_LOG_FAIL 2 /* log all authentication failures */ +#define SASL_LOG_WARN 3 /* log non-fatal warnings */ +#define SASL_LOG_NOTE 4 /* more verbose than LOG_WARN */ +#define SASL_LOG_DEBUG 5 /* more verbose than LOG_NOTE */ +#define SASL_LOG_TRACE 6 /* traces of internal protocols */ +#define SASL_LOG_PASS 7 /* traces of internal protocols, including + * passwords */ + +/* logging callback -- this allows plugins and the middleware to + * log operations they perform. + * inputs: + * context -- logging context from the callback record + * level -- logging level; see above + * message -- message to log + * returns: + * SASL_OK -- no error + * SASL_FAIL -- error + */ +typedef int sasl_log_t(void *context, + int level, + const char *message); +#define SASL_CB_LOG 2 + +/* getpath callback -- this allows applications to specify the + * colon-separated path to search for plugins (by default, + * taken from an implementation-specific location). + * inputs: + * context -- getpath context from the callback record + * outputs: + * path -- colon seperated path + * returns: + * SASL_OK -- no error + * SASL_FAIL -- error + */ +typedef int sasl_getpath_t(void *context, + const char **path); + +#define SASL_CB_GETPATH 3 + +/* verify file callback -- this allows applications to check if they + * want SASL to use files, file by file. This is intended to allow + * applications to sanity check the environment to make sure plugins + * or the configuration file can't be written to, etc. + * inputs: + * context -- verifypath context from the callback record + * file -- full path to file to verify + * type -- type of file to verify (see below) + + * returns: + * SASL_OK -- no error (file can safely be used) + * SASL_CONTINUE -- continue WITHOUT using this file + * SASL_FAIL -- error + */ + +/* these are the types of files libsasl will ask about */ +typedef enum { + SASL_VRFY_PLUGIN=0, /* a DLL/shared library plug-in */ + SASL_VRFY_CONF=1, /* a configuration file */ + SASL_VRFY_PASSWD=2, /* a password storage file/db */ + SASL_VRFY_OTHER=3 /* some other file */ +} sasl_verify_type_t; + +typedef int sasl_verifyfile_t(void *context, + const char *file, sasl_verify_type_t type); +#define SASL_CB_VERIFYFILE 4 + +/* getconfpath callback -- this allows applications to specify the + * colon-separated path to search for config files (by default, + * taken from the SASL_CONF_PATH environment variable). + * inputs: + * context -- getconfpath context from the callback record + * outputs: + * path -- colon seperated path (allocated on the heap; the + * library will free it using the sasl_free_t * + * passed to sasl_set_callback, or the standard free() + * library call). + * returns: + * SASL_OK -- no error + * SASL_FAIL -- error + */ +typedef int sasl_getconfpath_t(void *context, + char **path); + +#define SASL_CB_GETCONFPATH 5 + +/* client/user interaction callbacks: + */ +/* Simple prompt -- result must persist until next call to getsimple on + * same connection or until connection context is disposed + * inputs: + * context -- context from callback structure + * id -- callback id + * outputs: + * result -- set to NUL terminated string + * NULL = user cancel + * len -- length of result + * returns SASL_OK + */ +typedef int sasl_getsimple_t(void *context, int id, + const char **result, unsigned *len); +#define SASL_CB_USER 0x4001 /* client user identity to login as */ +#define SASL_CB_AUTHNAME 0x4002 /* client authentication name */ +#define SASL_CB_LANGUAGE 0x4003 /* comma separated list of RFC 1766 + * language codes in order of preference + * to be used to localize client prompts + * or server error codes */ +#define SASL_CB_CNONCE 0x4007 /* caller supplies client-nonce + * primarily for testing purposes */ + +/* get a sasl_secret_t (plaintext password with length) + * inputs: + * conn -- connection context + * context -- context from callback structure + * id -- callback id + * outputs: + * psecret -- set to NULL to cancel + * set to password structure which must persist until + * next call to getsecret in same connection, but middleware + * will erase password data when it's done with it. + * returns SASL_OK + */ +typedef int sasl_getsecret_t(sasl_conn_t *conn, void *context, int id, + sasl_secret_t **psecret); +#define SASL_CB_PASS 0x4004 /* client passphrase-based secret */ + + +/* prompt for input in response to a challenge. + * input: + * context -- context from callback structure + * id -- callback id + * challenge -- server challenge + * output: + * result -- NUL terminated result, NULL = user cancel + * len -- length of result + * returns SASL_OK + */ +typedef int sasl_chalprompt_t(void *context, int id, + const char *challenge, + const char *prompt, const char *defresult, + const char **result, unsigned *len); +#define SASL_CB_ECHOPROMPT 0x4005 /* challenge and client enterred result */ +#define SASL_CB_NOECHOPROMPT 0x4006 /* challenge and client enterred result */ + +/* prompt (or autoselect) the realm to do authentication in. + * may get a list of valid realms. + * input: + * context -- context from callback structure + * id -- callback id + * availrealms -- available realms; string list; NULL terminated + * list may be empty. + * output: + * result -- NUL terminated realm; NULL is equivalent to "" + * returns SASL_OK + * result must persist until the next callback + */ +typedef int sasl_getrealm_t(void *context, int id, + const char **availrealms, + const char **result); +#define SASL_CB_GETREALM (0x4008) /* realm to attempt authentication in */ + +/* server callbacks: + */ + +/* improved callback to verify authorization; + * canonicalization now handled elsewhere + * conn -- connection context + * requested_user -- the identity/username to authorize (NUL terminated) + * rlen -- length of requested_user + * auth_identity -- the identity associated with the secret (NUL terminated) + * alen -- length of auth_identity + * default_realm -- default user realm, as passed to sasl_server_new if + * urlen -- length of default realm + * propctx -- auxiliary properties + * returns SASL_OK on success, + * SASL_NOAUTHZ or other SASL response on failure + */ +typedef int sasl_authorize_t(sasl_conn_t *conn, + void *context, + const char *requested_user, unsigned rlen, + const char *auth_identity, unsigned alen, + const char *def_realm, unsigned urlen, + struct propctx *propctx); +#define SASL_CB_PROXY_POLICY 0x8001 + +/* functions for "userdb" based plugins to call to get/set passwords. + * the location for the passwords is determined by the caller or middleware. + * plug-ins may get passwords from other locations. + */ + +/* callback to verify a plaintext password against the caller-supplied + * user database. This is necessary to allow additional s for + * encoding of the userPassword property. + * user -- NUL terminated user name with user@realm syntax + * pass -- password to check (may not be NUL terminated) + * passlen -- length of password to check + * propctx -- auxiliary properties for user + */ +typedef int sasl_server_userdb_checkpass_t(sasl_conn_t *conn, + void *context, + const char *user, + const char *pass, + unsigned passlen, + struct propctx *propctx); +#define SASL_CB_SERVER_USERDB_CHECKPASS (0x8005) + +/* callback to store/change a plaintext password in the user database + * user -- NUL terminated user name with user@realm syntax + * pass -- password to store (may not be NUL terminated) + * passlen -- length of password to store + * propctx -- auxiliary properties (not stored) + * flags -- see SASL_SET_* flags below (SASL_SET_CREATE optional) + */ +typedef int sasl_server_userdb_setpass_t(sasl_conn_t *conn, + void *context, + const char *user, + const char *pass, + unsigned passlen, + struct propctx *propctx, + unsigned flags); +#define SASL_CB_SERVER_USERDB_SETPASS (0x8006) + +/* callback for a server-supplied user canonicalization function. + * + * This function is called directly after the mechanism has the + * authentication and authorization IDs. It is called before any + * User Canonicalization plugin is called. It has the responsibility + * of copying its output into the provided output buffers. + * + * in, inlen -- user name to canonicalize, may not be NUL terminated + * may be same buffer as out + * flags -- not currently used, supplied by auth mechanism + * user_realm -- the user realm (may be NULL in case of client) + * out -- buffer to copy user name + * out_max -- max length of user name + * out_len -- set to length of user name + * + * returns + * SASL_OK on success + * SASL_BADPROT username contains invalid character + */ + +/* User Canonicalization Function Flags */ + +#define SASL_CU_NONE 0x00 /* Not a valid flag to pass */ +/* One of the following two is required */ +#define SASL_CU_AUTHID 0x01 +#define SASL_CU_AUTHZID 0x02 + +/* Combine the following with SASL_CU_AUTHID, if you don't want + to fail if auxprop returned SASL_NOUSER/SASL_NOMECH. + This flag has no effect on SASL_CU_AUTHZID. */ +#define SASL_CU_EXTERNALLY_VERIFIED 0x04 + +#define SASL_CU_OVERRIDE 0x08 /* mapped to SASL_AUXPROP_OVERRIDE */ + +/* The following CU flags are passed "as is" down to auxprop lookup */ +#define SASL_CU_ASIS_MASK 0xFFF0 +/* NOTE: Keep in sync with SASL_AUXPROP_ flags */ +#define SASL_CU_VERIFY_AGAINST_HASH 0x10 + + +typedef int sasl_canon_user_t(sasl_conn_t *conn, + void *context, + const char *in, unsigned inlen, + unsigned flags, + const char *user_realm, + char *out, + unsigned out_max, unsigned *out_len); + +#define SASL_CB_CANON_USER (0x8007) + +/********************************** + * Common Client/server functions * + **********************************/ + +/* Types of paths to set (see sasl_set_path below). */ +#define SASL_PATH_TYPE_PLUGIN 0 +#define SASL_PATH_TYPE_CONFIG 1 + +/* a simpler way to set plugin path or configuration file path + * without the need to set sasl_getpath_t callback. + * + * This function can be called before sasl_server_init/sasl_client_init. + */ +LIBSASL_API int sasl_set_path (int path_type, char * path); + +/* get sasl library version information + * implementation is a vendor-defined string + * version is a vender-defined representation of the version #. + * + * This function is being deprecated in favor of sasl_version_info. */ +LIBSASL_API void sasl_version(const char **implementation, + int *version); + +/* Extended version of sasl_version(). + * + * This function is to be used + * for library version display and logging + * for bug workarounds in old library versions + * + * The sasl_version_info is not to be used for API feature detection. + * + * All parameters are optional. If NULL is specified, the value is not returned. + */ +LIBSASL_API void sasl_version_info (const char **implementation, + const char **version_string, + int *version_major, + int *version_minor, + int *version_step, + int *version_patch); + +/* dispose of all SASL plugins. Connection + * states have to be disposed of before calling this. + * + * This function is DEPRECATED in favour of sasl_server_done/ + * sasl_client_done. + */ +LIBSASL_API void sasl_done(void); + +/* dispose of all SASL plugins. Connection + * states have to be disposed of before calling this. + * This function should be called instead of sasl_done(), + whenever possible. + */ +LIBSASL_API int sasl_server_done(void); + +/* dispose of all SASL plugins. Connection + * states have to be disposed of before calling this. + * This function should be called instead of sasl_done(), + whenever possible. + */ +LIBSASL_API int sasl_client_done(void); + +/* dispose connection state, sets it to NULL + * checks for pointer to NULL + */ +LIBSASL_API void sasl_dispose(sasl_conn_t **pconn); + +/* translate an error number into a string + * input: + * saslerr -- the error number + * langlist -- comma separated list of RFC 1766 languages (may be NULL) + * results: + * outlang -- the language actually used (may be NULL if don't care) + * returns: + * the error message in UTF-8 (only the US-ASCII subset if langlist is NULL) + */ +LIBSASL_API const char *sasl_errstring(int saslerr, + const char *langlist, + const char **outlang); + +/* get detail about the last error that occurred on a connection + * text is sanitized so it's suitable to send over the wire + * (e.g., no distinction between SASL_BADAUTH and SASL_NOUSER) + * input: + * conn -- mandatory connection context + * returns: + * the error message in UTF-8 (only the US-ASCII subset permitted if no + * SASL_CB_LANGUAGE callback is present) + */ +LIBSASL_API const char *sasl_errdetail(sasl_conn_t *conn); + +/* set the error string which will be returned by sasl_errdetail() using + * syslog()-style formatting (e.g. printf-style with %m as most recent + * errno error) + * + * primarily for use by server callbacks such as the sasl_authorize_t + * callback and internally to plug-ins + * + * This will also trigger a call to the SASL logging callback (if any) + * with a level of SASL_LOG_FAIL unless the SASL_NOLOG flag is set. + * + * Messages should be sensitive to the current language setting. If there + * is no SASL_CB_LANGUAGE callback messages MUST be US-ASCII otherwise UTF-8 + * is used and use of RFC 2482 for mixed-language text is encouraged. + * + * if conn is NULL, function does nothing + */ +LIBSASL_API void sasl_seterror(sasl_conn_t *conn, unsigned flags, + const char *fmt, ...); +#define SASL_NOLOG 0x01 + +/* get property from SASL connection state + * propnum -- property number + * pvalue -- pointer to value + * returns: + * SASL_OK -- no error + * SASL_NOTDONE -- property not available yet + * SASL_BADPARAM -- bad property number + */ +LIBSASL_API int sasl_getprop(sasl_conn_t *conn, int propnum, + const void **pvalue); +#define SASL_USERNAME 0 /* pointer to NUL terminated user name */ +#define SASL_SSF 1 /* security layer security strength factor, + * if 0, call to sasl_encode, sasl_decode + * unnecessary */ +#define SASL_MAXOUTBUF 2 /* security layer max output buf unsigned */ +#define SASL_DEFUSERREALM 3 /* default realm passed to server_new */ + /* or set with setprop */ +#define SASL_GETOPTCTX 4 /* context for getopt callback */ +#define SASL_CALLBACK 7 /* current callback function list */ +#define SASL_IPLOCALPORT 8 /* iplocalport string passed to server_new */ +#define SASL_IPREMOTEPORT 9 /* ipremoteport string passed to server_new */ + +/* This returns a string which is either empty or has an error message + * from sasl_seterror (e.g., from a plug-in or callback). It differs + * from the result of sasl_errdetail() which also takes into account the + * last return status code. + */ +#define SASL_PLUGERR 10 + +/* a handle to any delegated credentials or NULL if none is present + * is returned by the mechanism. The user will probably need to know + * which mechanism was used to actually known how to make use of them + * currently only implemented for the gssapi mechanism */ +#define SASL_DELEGATEDCREDS 11 + +#define SASL_SERVICE 12 /* service passed to sasl_*_new */ +#define SASL_SERVERFQDN 13 /* serverFQDN passed to sasl_*_new */ +#define SASL_AUTHSOURCE 14 /* name of auth source last used, useful + * for failed authentication tracking */ +#define SASL_MECHNAME 15 /* active mechanism name, if any */ +#define SASL_AUTHUSER 16 /* authentication/admin user */ +#define SASL_APPNAME 17 /* application name (used for logging/ + configuration), same as appname parameter + to sasl_server_init */ + +/* GSS-API credential handle for sasl_client_step() or sasl_server_step(). + * The application is responsible for releasing this credential handle. */ +#define SASL_GSS_CREDS 18 + +/* GSS name (gss_name_t) of the peer, as output by gss_inquire_context() + * or gss_accept_sec_context(). + * On server end this is similar to SASL_USERNAME, but the gss_name_t + * structure can contain additional attributes associated with the peer. + */ +#define SASL_GSS_PEER_NAME 19 + +/* Local GSS name (gss_name_t) as output by gss_inquire_context(). This + * is particularly useful for servers that respond to multiple names. */ +#define SASL_GSS_LOCAL_NAME 20 + +/* Channel binding information. Memory is managed by the caller. */ +typedef struct sasl_channel_binding { + const char *name; + int critical; + unsigned long len; + const unsigned char *data; +} sasl_channel_binding_t; + +#define SASL_CHANNEL_BINDING 21 + +/* HTTP Request (RFC 2616) - ONLY used for HTTP Digest Auth (RFC 2617) */ +typedef struct sasl_http_request { + const char *method; /* HTTP Method */ + const char *uri; /* request-URI */ + const unsigned char *entity; /* entity-body */ + unsigned long elen; /* entity-body length */ + unsigned non_persist; /* Is it a non-persistent connection? */ +} sasl_http_request_t; + +#define SASL_HTTP_REQUEST 22 + +/* set property in SASL connection state + * returns: + * SASL_OK -- value set + * SASL_BADPARAM -- invalid property or value + */ +LIBSASL_API int sasl_setprop(sasl_conn_t *conn, + int propnum, + const void *value); +#define SASL_SSF_EXTERNAL 100 /* external SSF active (sasl_ssf_t *) */ +#define SASL_SEC_PROPS 101 /* sasl_security_properties_t */ +#define SASL_AUTH_EXTERNAL 102 /* external authentication ID (const char *) */ + +/* If the SASL_AUTH_EXTERNAL value is non-NULL, then a special version of the + * EXTERNAL mechanism is enabled (one for server-embedded EXTERNAL mechanisms). + * Otherwise, the EXTERNAL mechanism will be absent unless a plug-in + * including EXTERNAL is present. + */ + +/* do precalculations during an idle period or network round trip + * may pass NULL to precompute for some mechanisms prior to connect + * returns 1 if action taken, 0 if no action taken + */ +LIBSASL_API int sasl_idle(sasl_conn_t *conn); + +/************** + * Client API * + **************/ + +/* list of client interactions with user for caller to fill in + */ +typedef struct sasl_interact { + unsigned long id; /* same as client/user callback ID */ + const char *challenge; /* presented to user (e.g. OTP challenge) */ + const char *prompt; /* presented to user (e.g. "Username: ") */ + const char *defresult; /* default result string */ + const void *result; /* set to point to result */ + unsigned len; /* set to length of result */ +} sasl_interact_t; + +/* initialize the SASL client drivers + * callbacks -- base callbacks for all client connections; + * must include getopt callback + * returns: + * SASL_OK -- Success + * SASL_NOMEM -- Not enough memory + * SASL_BADVERS -- Mechanism version mismatch + * SASL_BADPARAM -- missing getopt callback or error in config file + * SASL_NOMECH -- No mechanisms available + * ... + */ +LIBSASL_API int sasl_client_init(const sasl_callback_t *callbacks); + +/* initialize a client exchange based on the specified mechanism + * service -- registered name of the service using SASL (e.g. "imap") + * serverFQDN -- the fully qualified domain name of the server + * iplocalport -- client IPv4/IPv6 domain literal string with port + * (if NULL, then mechanisms requiring IPaddr are disabled) + * ipremoteport -- server IPv4/IPv6 domain literal string with port + * (if NULL, then mechanisms requiring IPaddr are disabled) + * prompt_supp -- list of client interactions supported + * may also include sasl_getopt_t context & call + * NULL prompt_supp = user/pass via SASL_INTERACT only + * NULL proc = interaction supported via SASL_INTERACT + * flags -- server usage flags (see above) + * in/out: + * pconn -- connection negotiation structure + * pointer to NULL => allocate new + * + * Returns: + * SASL_OK -- success + * SASL_NOMECH -- no mechanism meets requested properties + * SASL_NOMEM -- not enough memory + */ +LIBSASL_API int sasl_client_new(const char *service, + const char *serverFQDN, + const char *iplocalport, + const char *ipremoteport, + const sasl_callback_t *prompt_supp, + unsigned flags, + sasl_conn_t **pconn); + +/* select a mechanism for a connection + * mechlist -- mechanisms server has available (punctuation ignored) + * if NULL, then discard cached info and retry last mech + * output: + * prompt_need -- on SASL_INTERACT, list of prompts needed to continue + * may be NULL if callbacks provided + * clientout -- the initial client response to send to the server + * will be valid until next call to client_start/client_step + * NULL if mech doesn't include initial client challenge + * mech -- set to mechansm name of selected mechanism (may be NULL) + * + * Returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + * SASL_NOMECH -- no mechanism meets requested properties + * SASL_INTERACT -- user interaction needed to fill in prompt_need list + */ +LIBSASL_API int sasl_client_start(sasl_conn_t *conn, + const char *mechlist, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + const char **mech); + +/* do a single authentication step. + * serverin -- the server message received by the client, MUST have a NUL + * sentinel, not counted by serverinlen + * output: + * prompt_need -- on SASL_INTERACT, list of prompts needed to continue + * clientout -- the client response to send to the server + * will be valid until next call to client_start/client_step + * + * returns: + * SASL_OK -- success + * SASL_INTERACT -- user interaction needed to fill in prompt_need list + * SASL_BADPROT -- server protocol incorrect/cancelled + * SASL_BADSERV -- server failed mutual auth + */ +LIBSASL_API int sasl_client_step(sasl_conn_t *conn, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen); + +/************** + * Server API * + **************/ + +/* initialize server drivers, done once per process + * callbacks -- callbacks for all server connections; must include + * getopt callback + * appname -- name of calling application (for lower level logging) + * results: + * state -- server state + * returns: + * SASL_OK -- success + * SASL_BADPARAM -- error in config file + * SASL_NOMEM -- memory failure + * SASL_BADVERS -- Mechanism version mismatch + */ +LIBSASL_API int sasl_server_init(const sasl_callback_t *callbacks, + const char *appname); + +/* IP/port syntax: + * a.b.c.d;p where a-d are 0-255 and p is 0-65535 port number. + * e:f:g:h:i:j:k:l;p where e-l are 0000-ffff lower-case hexidecimal + * e:f:g:h:i:j:a.b.c.d;p alternate syntax for previous + * + * Note that one or more "0" fields in f-k can be replaced with "::" + * Thus: e:f:0000:0000:0000:j:k:l;p + * can be abbreviated: e:f::j:k:l;p + * + * A buffer of size 52 is adequate for the longest format with NUL terminator. + */ + +/* create context for a single SASL connection + * service -- registered name of the service using SASL (e.g. "imap") + * serverFQDN -- Fully qualified domain name of server. NULL means use + * gethostname() or equivalent. + * Useful for multi-homed servers. + * user_realm -- permits multiple user realms on server, NULL = default + * iplocalport -- server IPv4/IPv6 domain literal string with port + * (if NULL, then mechanisms requiring IPaddr are disabled) + * ipremoteport -- client IPv4/IPv6 domain literal string with port + * (if NULL, then mechanisms requiring IPaddr are disabled) + * callbacks -- callbacks (e.g., authorization, lang, new getopt context) + * flags -- usage flags (see above) + * returns: + * pconn -- new connection context + * + * returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + */ +LIBSASL_API int sasl_server_new(const char *service, + const char *serverFQDN, + const char *user_realm, + const char *iplocalport, + const char *ipremoteport, + const sasl_callback_t *callbacks, + unsigned flags, + sasl_conn_t **pconn); + +/* Return an array of NUL-terminated strings, terminated by a NULL pointer, + * which lists all possible mechanisms that the library can supply + * + * Returns NULL on failure. */ +LIBSASL_API const char ** sasl_global_listmech(void); + +/* This returns a list of mechanisms in a NUL-terminated string + * conn -- the connection to list mechanisms for (either client + * or server) + * user -- restricts mechanisms to those available to that user + * (may be NULL, not used for client case) + * prefix -- appended to beginning of result + * sep -- appended between mechanisms + * suffix -- appended to end of result + * results: + * result -- NUL terminated result which persists until next + * call to sasl_listmech for this sasl_conn_t + * plen -- gets length of result (excluding NUL), may be NULL + * pcount -- gets number of mechanisms, may be NULL + * + * returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + * SASL_NOMECH -- no enabled mechanisms + */ +LIBSASL_API int sasl_listmech(sasl_conn_t *conn, + const char *user, + const char *prefix, + const char *sep, + const char *suffix, + const char **result, + unsigned *plen, + int *pcount); + +/* start a mechanism exchange within a connection context + * mech -- the mechanism name client requested + * clientin -- client initial response (NUL terminated), NULL if empty + * clientinlen -- length of initial response + * serverout -- initial server challenge, NULL if done + * (library handles freeing this string) + * serveroutlen -- length of initial server challenge + * output: + * pconn -- the connection negotiation state on success + * + * Same returns as sasl_server_step() or + * SASL_NOMECH if mechanism not available. + */ +LIBSASL_API int sasl_server_start(sasl_conn_t *conn, + const char *mech, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen); + +/* perform one step of the SASL exchange + * inputlen & input -- client data + * NULL on first step if no optional client step + * outputlen & output -- set to the server data to transmit + * to the client in the next step + * (library handles freeing this) + * + * returns: + * SASL_OK -- exchange is complete. + * SASL_CONTINUE -- indicates another step is necessary. + * SASL_TRANS -- entry for user exists, but not for mechanism + * and transition is possible + * SASL_BADPARAM -- service name needed + * SASL_BADPROT -- invalid input from client + * ... + */ +LIBSASL_API int sasl_server_step(sasl_conn_t *conn, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen); + +/* check if an apop exchange is valid + * (note this is an optional part of the SASL API) + * if challenge is NULL, just check if APOP is enabled + * inputs: + * challenge -- challenge which was sent to client + * challen -- length of challenge, 0 = strlen(challenge) + * response -- client response, " " (RFC 1939) + * resplen -- length of response, 0 = strlen(response) + * returns + * SASL_OK -- success + * SASL_BADAUTH -- authentication failed + * SASL_BADPARAM -- missing challenge + * SASL_BADPROT -- protocol error (e.g., response in wrong format) + * SASL_NOVERIFY -- user found, but no verifier + * SASL_NOMECH -- mechanism not supported + * SASL_NOUSER -- user not found + */ +LIBSASL_API int sasl_checkapop(sasl_conn_t *conn, + const char *challenge, unsigned challen, + const char *response, unsigned resplen); + +/* check if a plaintext password is valid + * if user is NULL, check if plaintext passwords are enabled + * inputs: + * user -- user to query in current user_domain + * userlen -- length of username, 0 = strlen(user) + * pass -- plaintext password to check + * passlen -- length of password, 0 = strlen(pass) + * returns + * SASL_OK -- success + * SASL_NOMECH -- mechanism not supported + * SASL_NOVERIFY -- user found, but no verifier + * SASL_NOUSER -- user not found + */ +LIBSASL_API int sasl_checkpass(sasl_conn_t *conn, + const char *user, unsigned userlen, + const char *pass, unsigned passlen); + +/* check if a user exists on server + * conn -- connection context + * service -- registered name of the service using SASL (e.g. "imap") + * user_realm -- permits multiple user realms on server, NULL = default + * user -- NUL terminated user name + * + * returns: + * SASL_OK -- success + * SASL_DISABLED -- account disabled + * SASL_NOUSER -- user not found + * SASL_NOVERIFY -- user found, but no usable mechanism + * SASL_NOMECH -- no mechanisms enabled + * SASL_UNAVAIL -- remote authentication server unavailable, try again later + */ +LIBSASL_API int sasl_user_exists(sasl_conn_t *conn, + const char *service, + const char *user_realm, + const char *user); + +/* set the password for a user + * conn -- SASL connection + * user -- user name + * pass -- plaintext password, may be NULL to remove user + * passlen -- length of password, 0 = strlen(pass) + * oldpass -- NULL will sometimes work + * oldpasslen -- length of password, 0 = strlen(oldpass) + * flags -- see flags below + * + * returns: + * SASL_NOCHANGE -- proper entry already exists + * SASL_NOMECH -- no authdb supports password setting as configured + * SASL_NOVERIFY -- user exists, but no settable password present + * SASL_DISABLED -- account disabled + * SASL_PWLOCK -- password locked + * SASL_WEAKPASS -- password too weak for security policy + * SASL_NOUSERPASS -- user-supplied passwords not permitted + * SASL_FAIL -- OS error + * SASL_BADPARAM -- password too long + * SASL_OK -- successful + */ +LIBSASL_API int sasl_setpass(sasl_conn_t *conn, + const char *user, + const char *pass, unsigned passlen, + const char *oldpass, unsigned oldpasslen, + unsigned flags); +#define SASL_SET_CREATE 0x01 /* create a new entry for user */ +#define SASL_SET_DISABLE 0x02 /* disable user account */ +#define SASL_SET_NOPLAIN 0x04 /* do not store secret in plain text */ +#define SASL_SET_CURMECH_ONLY 0x08 /* set the mechanism specific password only. + fail if no current mechanism */ + +/********************************************************* + * Auxiliary Property Support -- added by cjn 1999-09-29 * + *********************************************************/ + +#define SASL_AUX_END NULL /* last auxiliary property */ + +#define SASL_AUX_ALL "*" /* A special flag to signal user deletion */ + +/* traditional Posix items (should be implemented on Posix systems) */ +#define SASL_AUX_PASSWORD_PROP "userPassword" /* User Password */ +#define SASL_AUX_PASSWORD "*" SASL_AUX_PASSWORD_PROP /* User Password (of authid) */ +#define SASL_AUX_UIDNUM "uidNumber" /* UID number for the user */ +#define SASL_AUX_GIDNUM "gidNumber" /* GID for the user */ +#define SASL_AUX_FULLNAME "gecos" /* full name of the user, unix-style */ +#define SASL_AUX_HOMEDIR "homeDirectory" /* home directory for user */ +#define SASL_AUX_SHELL "loginShell" /* login shell for the user */ + +/* optional additional items (not necessarily implemented) */ +/* single preferred mail address for user canonically-quoted + * RFC821/822 syntax */ +#define SASL_AUX_MAILADDR "mail" +/* path to unix-style mailbox for user */ +#define SASL_AUX_UNIXMBX "mailMessageStore" +/* SMTP mail channel name to use if user authenticates successfully */ +#define SASL_AUX_MAILCHAN "mailSMTPSubmitChannel" + +/* Request a set of auxiliary properties + * conn connection context + * propnames list of auxiliary property names to request ending with + * NULL. + * + * Subsequent calls will add items to the request list. Call with NULL + * to clear the request list. + * + * errors + * SASL_OK -- success + * SASL_BADPARAM -- bad count/conn parameter + * SASL_NOMEM -- out of memory + */ +LIBSASL_API int sasl_auxprop_request(sasl_conn_t *conn, + const char **propnames); + +/* Returns current auxiliary property context. + * Use functions in prop.h to access content + * + * if authentication hasn't completed, property values may be empty/NULL + * + * properties not recognized by active plug-ins will be left empty/NULL + * + * returns NULL if conn is invalid. + */ +LIBSASL_API struct propctx *sasl_auxprop_getctx(sasl_conn_t *conn); + +/* Store the set of auxiliary properties for the given user. + * Use functions in prop.h to set the content. + * + * conn connection context + * ctx property context from prop_new()/prop_request()/prop_set() + * user NUL terminated user + * + * Call with NULL 'ctx' to see if the backend allows storing properties. + * + * errors + * SASL_OK -- success + * SASL_NOMECH -- can not store some/all properties + * SASL_BADPARAM -- bad conn/ctx/user parameter + * SASL_NOMEM -- out of memory + * SASL_FAIL -- failed to store + */ +LIBSASL_API int sasl_auxprop_store(sasl_conn_t *conn, + struct propctx *ctx, const char *user); + +/********************** + * security layer API * + **********************/ + +/* encode a block of data for transmission using security layer, + * returning the input buffer if there is no security layer. + * output is only valid until next call to sasl_encode or sasl_encodev + * returns: + * SASL_OK -- success (returns input if no layer negotiated) + * SASL_NOTDONE -- security layer negotiation not finished + * SASL_BADPARAM -- inputlen is greater than the SASL_MAXOUTBUF + */ +LIBSASL_API int sasl_encode(sasl_conn_t *conn, + const char *input, unsigned inputlen, + const char **output, unsigned *outputlen); + +/* encode a block of data for transmission using security layer + * output is only valid until next call to sasl_encode or sasl_encodev + * returns: + * SASL_OK -- success (returns input if no layer negotiated) + * SASL_NOTDONE -- security layer negotiation not finished + * SASL_BADPARAM -- input length is greater than the SASL_MAXOUTBUF + * or no security layer + */ +LIBSASL_API int sasl_encodev(sasl_conn_t *conn, + const struct iovec *invec, unsigned numiov, + const char **output, unsigned *outputlen); + +/* decode a block of data received using security layer + * returning the input buffer if there is no security layer. + * output is only valid until next call to sasl_decode + * + * if outputlen is 0 on return, than the value of output is undefined. + * + * returns: + * SASL_OK -- success (returns input if no layer negotiated) + * SASL_NOTDONE -- security layer negotiation not finished + * SASL_BADMAC -- bad message integrity check + */ +LIBSASL_API int sasl_decode(sasl_conn_t *conn, + const char *input, unsigned inputlen, + const char **output, unsigned *outputlen); + +#ifdef __cplusplus +} +#endif + +#endif /* SASL_H */ diff --git a/libs/cyrussasl/include/sasl/saslplug.h b/libs/cyrussasl/include/sasl/saslplug.h new file mode 100755 index 00000000..29302e8d --- /dev/null +++ b/libs/cyrussasl/include/sasl/saslplug.h @@ -0,0 +1,986 @@ +/* saslplug.h -- API for SASL plug-ins + */ + +#ifndef SASLPLUG_H +#define SASLPLUG_H 1 + +#ifndef MD5GLOBAL_H +#include "md5global.h" +#endif +#ifndef MD5_H +#include "md5.h" +#endif +#ifndef HMAC_MD5_H +#include "hmac-md5.h" +#endif +#ifndef PROP_H +#include "prop.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* callback to lookup a sasl_callback_t for a connection + * input: + * conn -- the connection to lookup a callback for + * callbacknum -- the number of the callback + * output: + * pproc -- pointer to the callback function (set to NULL on failure) + * pcontext -- pointer to the callback context (set to NULL on failure) + * returns: + * SASL_OK -- no error + * SASL_FAIL -- unable to find a callback of the requested type + * SASL_INTERACT -- caller must use interaction to get data + */ +typedef int (*sasl_callback_ft)(void); +typedef int sasl_getcallback_t(sasl_conn_t *conn, + unsigned long callbackid, + sasl_callback_ft * pproc, + void **pcontext); + +/* The sasl_utils structure will remain backwards compatible unless + * the SASL_*_PLUG_VERSION is changed incompatibly + * higher SASL_UTILS_VERSION numbers indicate more functions are available + */ +#define SASL_UTILS_VERSION 4 + +/* utility function set for plug-ins + */ +typedef struct sasl_utils { + int version; + + /* contexts */ + sasl_conn_t *conn; + sasl_rand_t *rpool; + void *getopt_context; + + /* option function */ + sasl_getopt_t *getopt; + + /* allocation functions: */ + sasl_malloc_t *malloc; + sasl_calloc_t *calloc; + sasl_realloc_t *realloc; + sasl_free_t *free; + + /* mutex functions: */ + sasl_mutex_alloc_t *mutex_alloc; + sasl_mutex_lock_t *mutex_lock; + sasl_mutex_unlock_t *mutex_unlock; + sasl_mutex_free_t *mutex_free; + + /* MD5 hash and HMAC functions */ + void (*MD5Init)(MD5_CTX *); + void (*MD5Update)(MD5_CTX *, const unsigned char *text, unsigned int len); + void (*MD5Final)(unsigned char [16], MD5_CTX *); + void (*hmac_md5)(const unsigned char *text, int text_len, + const unsigned char *key, int key_len, + unsigned char [16]); + void (*hmac_md5_init)(HMAC_MD5_CTX *, const unsigned char *key, int len); + /* hmac_md5_update() is just a call to MD5Update on inner context */ + void (*hmac_md5_final)(unsigned char [16], HMAC_MD5_CTX *); + void (*hmac_md5_precalc)(HMAC_MD5_STATE *, + const unsigned char *key, int len); + void (*hmac_md5_import)(HMAC_MD5_CTX *, HMAC_MD5_STATE *); + + /* mechanism utility functions (same as above): */ + int (*mkchal)(sasl_conn_t *conn, char *buf, unsigned maxlen, + unsigned hostflag); + int (*utf8verify)(const char *str, unsigned len); + void (*rand)(sasl_rand_t *rpool, char *buf, unsigned len); + void (*churn)(sasl_rand_t *rpool, const char *data, unsigned len); + + /* This allows recursive calls to the sasl_checkpass() routine from + * within a SASL plug-in. This MUST NOT be used in the PLAIN mechanism + * as sasl_checkpass MAY be a front-end for the PLAIN mechanism. + * This is intended for use by the non-standard LOGIN mechanism and + * potentially by a future mechanism which uses public-key technology to + * set up a lightweight encryption layer just for sending a password. + */ + int (*checkpass)(sasl_conn_t *conn, + const char *user, unsigned userlen, + const char *pass, unsigned passlen); + + /* Access to base64 encode/decode routines */ + int (*decode64)(const char *in, unsigned inlen, + char *out, unsigned outmax, unsigned *outlen); + int (*encode64)(const char *in, unsigned inlen, + char *out, unsigned outmax, unsigned *outlen); + + /* erase a buffer */ + void (*erasebuffer)(char *buf, unsigned len); + + /* callback to sasl_getprop() and sasl_setprop() */ + int (*getprop)(sasl_conn_t *conn, int propnum, const void **pvalue); + int (*setprop)(sasl_conn_t *conn, int propnum, const void *value); + + /* callback function */ + sasl_getcallback_t *getcallback; + + /* format a message and then pass it to the SASL_CB_LOG callback + * + * use syslog()-style formatting (printf with %m as a human readable text + * (strerror()) for the error specified as the parameter). + * The implementation may use a fixed size buffer not smaller + * than 512 octets if it securely truncates the message. + * + * level is a SASL_LOG_* level (see sasl.h) + */ + void (*log)(sasl_conn_t *conn, int level, const char *fmt, ...); + + /* callback to sasl_seterror() */ + void (*seterror)(sasl_conn_t *conn, unsigned flags, const char *fmt, ...); + + /* spare function pointer */ + int *(*spare_fptr)(void); + + /* auxiliary property utilities */ + struct propctx *(*prop_new)(unsigned estimate); + int (*prop_dup)(struct propctx *src_ctx, struct propctx **dst_ctx); + int (*prop_request)(struct propctx *ctx, const char **names); + const struct propval *(*prop_get)(struct propctx *ctx); + int (*prop_getnames)(struct propctx *ctx, const char **names, + struct propval *vals); + void (*prop_clear)(struct propctx *ctx, int requests); + void (*prop_dispose)(struct propctx **ctx); + int (*prop_format)(struct propctx *ctx, const char *sep, int seplen, + char *outbuf, unsigned outmax, unsigned *outlen); + int (*prop_set)(struct propctx *ctx, const char *name, + const char *value, int vallen); + int (*prop_setvals)(struct propctx *ctx, const char *name, + const char **values); + void (*prop_erase)(struct propctx *ctx, const char *name); + int (*auxprop_store)(sasl_conn_t *conn, + struct propctx *ctx, const char *user); + + /* for additions which don't require a version upgrade; set to 0 */ + int (*spare_fptr1)(void); + int (*spare_fptr2)(void); +} sasl_utils_t; + +/* + * output parameters from SASL API + * + * created / destroyed by the glue code, though probably filled in + * by a combination of the plugin, the glue code, and the canon_user callback. + * + */ +typedef struct sasl_out_params { + unsigned doneflag; /* exchange complete */ + + const char *user; /* canonicalized user name */ + const char *authid; /* canonicalized authentication id */ + + unsigned ulen; /* length of canonicalized user name */ + unsigned alen; /* length of canonicalized authid */ + + /* security layer information */ + unsigned maxoutbuf; /* Maximum buffer size, which will + produce buffer no bigger than the + negotiated SASL maximum buffer size */ + sasl_ssf_t mech_ssf; /* Should be set non-zero if negotiation of a + * security layer was *attempted*, even if + * the negotiation failed */ + void *encode_context; + int (*encode)(void *context, const struct iovec *invec, unsigned numiov, + const char **output, unsigned *outputlen); + void *decode_context; + int (*decode)(void *context, const char *input, unsigned inputlen, + const char **output, unsigned *outputlen); + + /* Pointer to delegated (client's) credentials, if supported by + the SASL mechanism */ + void *client_creds; + + /* for additions which don't require a version upgrade; set to 0 */ + const void *gss_peer_name; + const void *gss_local_name; + const char *cbindingname; /* channel binding name from packet */ + int (*spare_fptr1)(void); + int (*spare_fptr2)(void); + unsigned int cbindingdisp; /* channel binding disposition from client */ + int spare_int2; + int spare_int3; + int spare_int4; + + /* set to 0 initially, this allows a plugin with extended parameters + * to work with an older framework by updating version as parameters + * are added. + */ + int param_version; +} sasl_out_params_t; + + + +/* Used by both client and server side plugins */ +typedef enum { + SASL_INFO_LIST_START = 0, + SASL_INFO_LIST_MECH, + SASL_INFO_LIST_END +} sasl_info_callback_stage_t; + +/****************************** + * Channel binding macros ** + ******************************/ + +typedef enum { + SASL_CB_DISP_NONE = 0, /* client did not support CB */ + SASL_CB_DISP_WANT, /* client supports CB, thinks server does not */ + SASL_CB_DISP_USED /* client supports and used CB */ +} sasl_cbinding_disp_t; + +/* TRUE if channel binding is non-NULL */ +#define SASL_CB_PRESENT(params) ((params)->cbinding != NULL) +/* TRUE if channel binding is marked critical */ +#define SASL_CB_CRITICAL(params) (SASL_CB_PRESENT(params) && \ + (params)->cbinding->critical) + +/****************************** + * Client Mechanism Functions * + ******************************/ + +/* + * input parameters to client SASL plugin + * + * created / destroyed by the glue code + * + */ +typedef struct sasl_client_params { + const char *service; /* service name */ + const char *serverFQDN; /* server fully qualified domain name */ + const char *clientFQDN; /* client's fully qualified domain name */ + const sasl_utils_t *utils; /* SASL API utility routines -- + * for a particular sasl_conn_t, + * MUST remain valid until mech_free is + * called */ + const sasl_callback_t *prompt_supp; /* client callback list */ + const char *iplocalport; /* server IP domain literal & port */ + const char *ipremoteport; /* client IP domain literal & port */ + + unsigned servicelen; /* length of service */ + unsigned slen; /* length of serverFQDN */ + unsigned clen; /* length of clientFQDN */ + unsigned iploclen; /* length of iplocalport */ + unsigned ipremlen; /* length of ipremoteport */ + + /* application's security requirements & info */ + sasl_security_properties_t props; + sasl_ssf_t external_ssf; /* external SSF active */ + + /* for additions which don't require a version upgrade; set to 0 */ + const void *gss_creds; /* GSS credential handle */ + const sasl_channel_binding_t *cbinding; /* client channel binding */ + const sasl_http_request_t *http_request;/* HTTP Digest request method */ + void *spare_ptr4; + + /* Canonicalize a user name from on-wire to internal format + * added rjs3 2001-05-23 + * Must be called once user name aquired if canon_user is non-NULL. + * conn connection context + * in user name from wire protocol (need not be NUL terminated) + * len length of user name from wire protocol (0 = strlen(user)) + * flags for SASL_CU_* flags + * oparams the user, authid, ulen, alen, fields are + * set appropriately after canonicalization/copying and + * authorization of arguments + * + * responsible for setting user, ulen, authid, and alen in the oparams + * structure + * + * default behavior is to strip leading and trailing whitespace, as + * well as allocating space for and copying the parameters. + * + * results: + * SASL_OK -- success + * SASL_NOMEM -- out of memory + * SASL_BADPARAM -- invalid conn + * SASL_BADPROT -- invalid user/authid + */ + int (*canon_user)(sasl_conn_t *conn, + const char *in, unsigned len, + unsigned flags, + sasl_out_params_t *oparams); + + int (*spare_fptr1)(void); + + unsigned int cbindingdisp; + int spare_int2; + int spare_int3; + + /* flags field as passed to sasl_client_new */ + unsigned flags; + + /* set to 0 initially, this allows a plugin with extended parameters + * to work with an older framework by updating version as parameters + * are added. + */ + int param_version; +} sasl_client_params_t; + +/* features shared between client and server */ +/* These allow the glue code to handle client-first and server-last issues */ + +/* This indicates that the mechanism prefers to do client-send-first + * if the protocol allows it. */ +#define SASL_FEAT_WANT_CLIENT_FIRST 0x0002 + +/* This feature is deprecated. Instead, plugins should set *serverout to + * non-NULL and return SASL_OK intelligently to allow flexible use of + * server-last semantics +#define SASL_FEAT_WANT_SERVER_LAST 0x0004 +*/ + +/* This feature is deprecated. Instead, plugins should correctly set + * SASL_FEAT_SERVER_FIRST as needed +#define SASL_FEAT_INTERNAL_CLIENT_FIRST 0x0008 +*/ + +/* This indicates that the plugin is server-first only. + * Not defining either of SASL_FEAT_SERVER_FIRST or + * SASL_FEAT_WANT_CLIENT_FIRST indicates that the mechanism + * will handle the client-first situation internally. + */ +#define SASL_FEAT_SERVER_FIRST 0x0010 + +/* This plugin allows proxying */ +#define SASL_FEAT_ALLOWS_PROXY 0x0020 + +/* server plugin don't use cleartext userPassword attribute */ +#define SASL_FEAT_DONTUSE_USERPASSWD 0x0080 + +/* Underlying mechanism uses GSS framing */ +#define SASL_FEAT_GSS_FRAMING 0x0100 + +/* Underlying mechanism supports channel binding */ +#define SASL_FEAT_CHANNEL_BINDING 0x0800 + +/* This plugin can be used for HTTP authentication */ +#define SASL_FEAT_SUPPORTS_HTTP 0x1000 + +/* client plug-in features */ +#define SASL_FEAT_NEEDSERVERFQDN 0x0001 + +/* a C object for a client mechanism + */ +typedef struct sasl_client_plug { + /* mechanism name */ + const char *mech_name; + + /* best mech additional security layer strength factor */ + sasl_ssf_t max_ssf; + + /* best security flags, as defined in sasl_security_properties_t */ + unsigned security_flags; + + /* features of plugin */ + unsigned features; + + /* required prompt ids, NULL = user/pass only */ + const unsigned long *required_prompts; + + /* global state for mechanism */ + void *glob_context; + + /* create context for mechanism, using params supplied + * glob_context -- from above + * params -- params from sasl_client_new + * conn_context -- context for one connection + * returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + * SASL_WRONGMECH -- mech doesn't support security params + */ + int (*mech_new)(void *glob_context, + sasl_client_params_t *cparams, + void **conn_context); + + /* perform one step of exchange. NULL is passed for serverin on + * first step. + * returns: + * SASL_OK -- success + * SASL_INTERACT -- user interaction needed to fill in prompts + * SASL_BADPROT -- server protocol incorrect/cancelled + * SASL_BADSERV -- server failed mutual auth + */ + int (*mech_step)(void *conn_context, + sasl_client_params_t *cparams, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams); + + /* dispose of connection context from mech_new + */ + void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils); + + /* free all global space used by mechanism + * mech_dispose must be called on all mechanisms first + */ + void (*mech_free)(void *glob_context, const sasl_utils_t *utils); + + /* perform precalculations during a network round-trip + * or idle period. conn_context may be NULL + * returns 1 if action taken, 0 if no action taken + */ + int (*idle)(void *glob_context, + void *conn_context, + sasl_client_params_t *cparams); + + /* for additions which don't require a version upgrade; set to 0 */ + int (*spare_fptr1)(void); + int (*spare_fptr2)(void); +} sasl_client_plug_t; + +#define SASL_CLIENT_PLUG_VERSION 4 + +/* plug-in entry point: + * utils -- utility callback functions + * max_version -- highest client plug version supported + * returns: + * out_version -- client plug version of result + * pluglist -- list of mechanism plug-ins + * plugcount -- number of mechanism plug-ins + * results: + * SASL_OK -- success + * SASL_NOMEM -- failure + * SASL_BADVERS -- max_version too small + * SASL_BADPARAM -- bad config string + * ... + */ +typedef int sasl_client_plug_init_t(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount); + + +/* add a client plug-in + */ +LIBSASL_API int sasl_client_add_plugin(const char *plugname, + sasl_client_plug_init_t *cplugfunc); + +typedef struct client_sasl_mechanism +{ + int version; + + char *plugname; + const sasl_client_plug_t *plug; +} client_sasl_mechanism_t; + +typedef void sasl_client_info_callback_t (client_sasl_mechanism_t *m, + sasl_info_callback_stage_t stage, + void *rock); + +/* Dump information about available client plugins */ +LIBSASL_API int sasl_client_plugin_info (const char *mech_list, + sasl_client_info_callback_t *info_cb, + void *info_cb_rock); + + +/******************** + * Server Functions * + ********************/ + +/* log message formatting routine */ +typedef void sasl_logmsg_p(sasl_conn_t *conn, const char *fmt, ...); + +/* + * input parameters to server SASL plugin + * + * created / destroyed by the glue code + * + */ +typedef struct sasl_server_params { + const char *service; /* NULL = default service for user_exists + and setpass */ + const char *appname; /* name of calling application */ + const char *serverFQDN; /* server default fully qualified domain name + * (e.g., gethostname) */ + const char *user_realm; /* realm for user (NULL = client supplied) */ + const char *iplocalport; /* server IP domain literal & port */ + const char *ipremoteport; /* client IP domain literal & port */ + + unsigned servicelen; /* length of service */ + unsigned applen; /* length of appname */ + unsigned slen; /* length of serverFQDN */ + unsigned urlen; /* length of user_realm */ + unsigned iploclen; /* length of iplocalport */ + unsigned ipremlen; /* length of ipremoteport */ + + /* This indicates the level of logging desired. See SASL_LOG_* + * in sasl.h + * + * Plug-ins can ignore this and just pass their desired level to + * the log callback. This is primarily used to eliminate logging which + * might be a performance problem (e.g., full protocol trace) and + * to select between SASL_LOG_TRACE and SASL_LOG_PASS alternatives + */ + int log_level; + + const sasl_utils_t *utils; /* SASL API utility routines -- + * for a particular sasl_conn_t, + * MUST remain valid until mech_free is + * called */ + const sasl_callback_t *callbacks; /* Callbacks from application */ + + /* application's security requirements */ + sasl_security_properties_t props; + sasl_ssf_t external_ssf; /* external SSF active */ + + /* Pointer to the function which takes the plaintext passphrase and + * transitions a user to non-plaintext mechanisms via setpass calls. + * (NULL = auto transition not enabled/supported) + * + * If passlen is 0, it defaults to strlen(pass). + * returns 0 if no entry added, 1 if entry added + */ + int (*transition)(sasl_conn_t *conn, const char *pass, unsigned passlen); + + /* Canonicalize a user name from on-wire to internal format + * added cjn 1999-09-21 + * Must be called once user name acquired if canon_user is non-NULL. + * conn connection context + * user user name from wire protocol (need not be NUL terminated) + * ulen length of user name from wire protocol (0 = strlen(user)) + * flags for SASL_CU_* flags + * oparams the user, authid, ulen, alen, fields are + * set appropriately after canonicalization/copying and + * authorization of arguments + * + * responsible for setting user, ulen, authid, and alen in the oparams + * structure + * + * default behavior is to strip leading and trailing whitespace, as + * well as allocating space for and copying the parameters. + * + * results: + * SASL_OK -- success + * SASL_NOMEM -- out of memory + * SASL_BADPARAM -- invalid conn + * SASL_BADPROT -- invalid user/authid + */ + int (*canon_user)(sasl_conn_t *conn, + const char *user, unsigned ulen, + unsigned flags, + sasl_out_params_t *oparams); + + /* auxiliary property context (see definitions in prop.h) + * added cjn 2000-01-30 + * + * NOTE: these properties are the ones associated with the + * canonicalized "user" (user to login as / authorization id), not + * the "authid" (user whose credentials are used / authentication id) + * Prefix the property name with a "*" if a property associated with + * the "authid" is interesting. + */ + struct propctx *propctx; + + /* for additions which don't require a version upgrade; set to 0 */ + const void *gss_creds; /* GSS credential handle */ + const sasl_channel_binding_t *cbinding; /* server channel binding */ + const sasl_http_request_t *http_request;/* HTTP Digest request method */ + void *spare_ptr4; + int (*spare_fptr1)(void); + int (*spare_fptr2)(void); + int spare_int1; + int spare_int2; + int spare_int3; + + /* flags field as passed to sasl_server_new */ + unsigned flags; + + /* set to 0 initially, this allows a plugin with extended parameters + * to work with an older framework by updating version as parameters + * are added. + */ + int param_version; +} sasl_server_params_t; + +/* logging levels (more levels may be added later, if necessary): + */ +#define SASL_LOG_NONE 0 /* don't log anything */ +#define SASL_LOG_ERR 1 /* log unusual errors (default) */ +#define SASL_LOG_FAIL 2 /* log all authentication failures */ +#define SASL_LOG_WARN 3 /* log non-fatal warnings */ +#define SASL_LOG_NOTE 4 /* more verbose than LOG_WARN */ +#define SASL_LOG_DEBUG 5 /* more verbose than LOG_NOTE */ +#define SASL_LOG_TRACE 6 /* traces of internal protocols */ +#define SASL_LOG_PASS 7 /* traces of internal protocols, including + * passwords */ + +/* additional flags for setpass() function below: + */ +/* SASL_SET_CREATE create user if pass non-NULL */ +/* SASL_SET_DISABLE disable user */ +#define SASL_SET_REMOVE SASL_SET_CREATE /* remove user if pass is NULL */ + +/* features for server plug-in + */ +#define SASL_FEAT_SERVICE 0x0200 /* service-specific passwords supported */ +#define SASL_FEAT_GETSECRET 0x0400 /* sasl_server_{get,put}secret_t callbacks + * required by plug-in */ + +/* a C object for a server mechanism + */ +typedef struct sasl_server_plug { + /* mechanism name */ + const char *mech_name; + + /* best mech additional security layer strength factor */ + sasl_ssf_t max_ssf; + + /* best security flags, as defined in sasl_security_properties_t */ + unsigned security_flags; + + /* features of plugin */ + unsigned features; + + /* global state for mechanism */ + void *glob_context; + + /* create a new mechanism handler + * glob_context -- global context + * sparams -- server config params + * challenge -- server challenge from previous instance or NULL + * challen -- length of challenge from previous instance or 0 + * out: + * conn_context -- connection context + * errinfo -- error information + * + * returns: + * SASL_OK -- successfully created mech instance + * SASL_* -- any other server error code + */ + int (*mech_new)(void *glob_context, + sasl_server_params_t *sparams, + const char *challenge, + unsigned challen, + void **conn_context); + + /* perform one step in exchange + * + * returns: + * SASL_OK -- success, all done + * SASL_CONTINUE -- success, one more round trip + * SASL_* -- any other server error code + */ + int (*mech_step)(void *conn_context, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams); + + /* dispose of a connection state + */ + void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils); + + /* free global state for mechanism + * mech_dispose must be called on all mechanisms first + */ + void (*mech_free)(void *glob_context, const sasl_utils_t *utils); + + /* set a password (optional) + * glob_context -- global context + * sparams -- service, middleware utilities, etc. props ignored + * user -- user name + * pass -- password/passphrase (NULL = disable/remove/delete) + * passlen -- length of password/passphrase + * oldpass -- old password/passphrase (NULL = transition) + * oldpasslen -- length of password/passphrase + * flags -- see above + * + * returns: + * SASL_NOCHANGE -- no change was needed + * SASL_NOUSER -- no entry for user + * SASL_NOVERIFY -- no mechanism compatible entry for user + * SASL_PWLOCK -- password locked + * SASL_DIABLED -- account disabled + * etc. + */ + int (*setpass)(void *glob_context, + sasl_server_params_t *sparams, + const char *user, + const char *pass, unsigned passlen, + const char *oldpass, unsigned oldpasslen, + unsigned flags); + + /* query which mechanisms are available for user + * glob_context -- context + * sparams -- service, middleware utilities, etc. props ignored + * user -- NUL terminated user name + * maxmech -- max number of strings in mechlist (0 = no output) + * output: + * mechlist -- an array of C string pointers, filled in with + * mechanism names available to the user + * + * returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + * SASL_FAIL -- lower level failure + * SASL_DISABLED -- account disabled + * SASL_NOUSER -- user not found + * SASL_BUFOVER -- maxmech is too small + * SASL_NOVERIFY -- user found, but no mechanisms available + */ + int (*user_query)(void *glob_context, + sasl_server_params_t *sparams, + const char *user, + int maxmech, + const char **mechlist); + + /* perform precalculations during a network round-trip + * or idle period. conn_context may be NULL (optional) + * returns 1 if action taken, 0 if no action taken + */ + int (*idle)(void *glob_context, + void *conn_context, + sasl_server_params_t *sparams); + + /* check if mechanism is available + * optional--if NULL, mechanism is available based on ENABLE= in config + * + * If this routine sets conn_context to a non-NULL value, then the call + * to mech_new will be skipped. This should not be done unless + * there's a significant performance benefit, since it can cause + * additional memory allocation in SASL core code to keep track of + * contexts potentially for multiple mechanisms. + * + * This is called by the first call to sasl_listmech() for a + * given connection context, thus for a given protocol it may + * never be called. Note that if mech_avail returns SASL_NOMECH, + * then that mechanism is considered disabled for the remainder + * of the session. If mech_avail returns SASL_NOTDONE, then a + * future call to mech_avail may still return either SASL_OK + * or SASL_NOMECH. + * + * returns SASL_OK on success, + * SASL_NOTDONE if mech is not available now, but may be later + * (e.g. EXTERNAL w/o auth_id) + * SASL_NOMECH if mech disabled + */ + int (*mech_avail)(void *glob_context, + sasl_server_params_t *sparams, + void **conn_context); + + /* for additions which don't require a version upgrade; set to 0 */ + int (*spare_fptr2)(void); +} sasl_server_plug_t; + +#define SASL_SERVER_PLUG_VERSION 4 + +/* plug-in entry point: + * utils -- utility callback functions + * plugname -- name of plug-in (may be NULL) + * max_version -- highest server plug version supported + * returns: + * out_version -- server plug-in version of result + * pluglist -- list of mechanism plug-ins + * plugcount -- number of mechanism plug-ins + * results: + * SASL_OK -- success + * SASL_NOMEM -- failure + * SASL_BADVERS -- max_version too small + * SASL_BADPARAM -- bad config string + * ... + */ +typedef int sasl_server_plug_init_t(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount); + +/* + * add a server plug-in + */ +LIBSASL_API int sasl_server_add_plugin(const char *plugname, + sasl_server_plug_init_t *splugfunc); + + +typedef struct server_sasl_mechanism +{ + int version; + int condition; /* set to SASL_NOUSER if no available users; + set to SASL_CONTINUE if delayed plugin loading */ + char *plugname; /* for AUTHSOURCE tracking */ + const sasl_server_plug_t *plug; + char *f; /* where should i load the mechanism from? */ +} server_sasl_mechanism_t; + +typedef void sasl_server_info_callback_t (server_sasl_mechanism_t *m, + sasl_info_callback_stage_t stage, + void *rock); + + +/* Dump information about available server plugins (separate functions are + used for canon and auxprop plugins) */ +LIBSASL_API int sasl_server_plugin_info (const char *mech_list, + sasl_server_info_callback_t *info_cb, + void *info_cb_rock); + + +/********************************************************* + * user canonicalization plug-in -- added cjn 1999-09-29 * + *********************************************************/ + +typedef struct sasl_canonuser { + /* optional features of plugin (set to 0) */ + int features; + + /* spare integer (set to 0) */ + int spare_int1; + + /* global state for plugin */ + void *glob_context; + + /* name of plugin */ + char *name; + + /* free global state for plugin */ + void (*canon_user_free)(void *glob_context, const sasl_utils_t *utils); + + /* canonicalize a username + * glob_context -- global context from this structure + * sparams -- server params, note user_realm&propctx elements + * user -- user to login as (may not be NUL terminated) + * len -- length of user name (0 = strlen(user)) + * flags -- for SASL_CU_* flags + * out -- buffer to copy user name + * out_max -- max length of user name + * out_len -- set to length of user name + * + * note that the output buffers MAY be the same as the input buffers. + * + * returns + * SASL_OK on success + * SASL_BADPROT username contains invalid character + */ + int (*canon_user_server)(void *glob_context, + sasl_server_params_t *sparams, + const char *user, unsigned len, + unsigned flags, + char *out, + unsigned out_umax, unsigned *out_ulen); + + int (*canon_user_client)(void *glob_context, + sasl_client_params_t *cparams, + const char *user, unsigned len, + unsigned flags, + char *out, + unsigned out_max, unsigned *out_len); + + /* for additions which don't require a version upgrade; set to 0 */ + int (*spare_fptr1)(void); + int (*spare_fptr2)(void); + int (*spare_fptr3)(void); +} sasl_canonuser_plug_t; + +#define SASL_CANONUSER_PLUG_VERSION 5 + +/* default name for canonuser plug-in entry point is "sasl_canonuser_init" + * similar to sasl_server_plug_init model, except only returns one + * sasl_canonuser_plug_t structure; + */ +typedef int sasl_canonuser_init_t(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_canonuser_plug_t **plug, + const char *plugname); + +/* add a canonuser plugin + */ +LIBSASL_API int sasl_canonuser_add_plugin(const char *plugname, + sasl_canonuser_init_t *canonuserfunc); + +/****************************************************** + * auxiliary property plug-in -- added cjn 1999-09-29 * + ******************************************************/ + +typedef struct sasl_auxprop_plug { + /* optional features of plugin (none defined yet, set to 0) */ + int features; + + /* spare integer, must be set to 0 */ + int spare_int1; + + /* global state for plugin */ + void *glob_context; + + /* free global state for plugin (OPTIONAL) */ + void (*auxprop_free)(void *glob_context, const sasl_utils_t *utils); + + /* fill in fields of an auxiliary property context + * last element in array has id of SASL_AUX_END + * elements with non-0 len should be ignored. + */ + int (*auxprop_lookup)(void *glob_context, + sasl_server_params_t *sparams, + unsigned flags, + const char *user, unsigned ulen); + + /* name of the auxprop plugin */ + char *name; + + /* store the fields/values of an auxiliary property context (OPTIONAL) + * + * if ctx is NULL, just check if storing properties is enabled + * + * returns + * SASL_OK on success + * SASL_FAIL on failure + */ + int (*auxprop_store)(void *glob_context, + sasl_server_params_t *sparams, + struct propctx *ctx, + const char *user, unsigned ulen); +} sasl_auxprop_plug_t; + +/* auxprop lookup flags */ +#define SASL_AUXPROP_OVERRIDE 0x01 /* if clear, ignore auxiliary properties + * with non-zero len field. If set, + * override value of those properties */ +#define SASL_AUXPROP_AUTHZID 0x02 /* if clear, we are looking up the + * authid flags (prefixed with *), otherwise + * we are looking up the authzid flags + * (no prefix) */ + +/* NOTE: Keep in sync with SASL_CU_ flags */ +#define SASL_AUXPROP_VERIFY_AGAINST_HASH 0x10 + + +#define SASL_AUXPROP_PLUG_VERSION 8 + +/* default name for auxprop plug-in entry point is "sasl_auxprop_init" + * similar to sasl_server_plug_init model, except only returns one + * sasl_auxprop_plug_t structure; + */ +typedef int sasl_auxprop_init_t(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_auxprop_plug_t **plug, + const char *plugname); + +/* add an auxiliary property plug-in + */ +LIBSASL_API int sasl_auxprop_add_plugin(const char *plugname, + sasl_auxprop_init_t *auxpropfunc); + +typedef void auxprop_info_callback_t (sasl_auxprop_plug_t *m, + sasl_info_callback_stage_t stage, + void *rock); + +/* Dump information about available auxprop plugins (separate functions are + used for canon and server authentication plugins) */ +LIBSASL_API int auxprop_plugin_info (const char *mech_list, + auxprop_info_callback_t *info_cb, + void *info_cb_rock); + +#ifdef __cplusplus +} +#endif + +#endif /* SASLPLUG_H */ diff --git a/libs/cyrussasl/include/sasl/saslutil.h b/libs/cyrussasl/include/sasl/saslutil.h new file mode 100755 index 00000000..e0fa47c5 --- /dev/null +++ b/libs/cyrussasl/include/sasl/saslutil.h @@ -0,0 +1,99 @@ +/* saslutil.h -- various utility functions in SASL library + */ + +#ifndef SASLUTIL_H +#define SASLUTIL_H 1 + +#ifndef SASL_H +#include "sasl.h" +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* base64 decode + * in -- input data + * inlen -- length of input data + * out -- output data (may be same as in, must have enough space) + * outmax -- max size of output buffer + * result: + * outlen -- actual output length + * + * returns SASL_BADPROT on bad base64, + * SASL_BUFOVER if result won't fit + * SASL_OK on success + */ +LIBSASL_API int sasl_decode64(const char *in, unsigned inlen, + char *out, unsigned outmax, unsigned *outlen); + +/* base64 encode + * in -- input data + * inlen -- input data length + * out -- output buffer (will be NUL terminated) + * outmax -- max size of output buffer + * result: + * outlen -- gets actual length of output buffer (optional) + * + * Returns SASL_OK on success, SASL_BUFOVER if result won't fit + */ +LIBSASL_API int sasl_encode64(const char *in, unsigned inlen, + char *out, unsigned outmax, unsigned *outlen); + +/* make a challenge string (NUL terminated) + * buf -- buffer for result + * maxlen -- max length of result + * hostflag -- 0 = don't include hostname, 1 = include hostname + * returns final length or 0 if not enough space + */ +LIBSASL_API int sasl_mkchal(sasl_conn_t *conn, char *buf, + unsigned maxlen, unsigned hostflag); + +/* verify a string is valid UTF-8 + * if len == 0, strlen(str) will be used. + * returns SASL_BADPROT on error, SASL_OK on success + */ +LIBSASL_API int sasl_utf8verify(const char *str, unsigned len); + +/* create random pool seeded with OS-based params */ +LIBSASL_API int sasl_randcreate(sasl_rand_t **rpool); + +/* free random pool from randcreate */ +LIBSASL_API void sasl_randfree(sasl_rand_t **rpool); + +/* seed random number generator */ +LIBSASL_API void sasl_randseed(sasl_rand_t *rpool, const char *seed, + unsigned len); + +/* generate random octets */ +LIBSASL_API void sasl_rand(sasl_rand_t *rpool, char *buf, unsigned len); + +/* churn data into random number generator */ +LIBSASL_API void sasl_churn(sasl_rand_t *rpool, const char *data, + unsigned len); + +/* erase a security sensitive buffer or password. + * Implementation may use recovery-resistant erase logic. + */ +LIBSASL_API void sasl_erasebuffer(char *pass, unsigned len); + +/* Lowercase string in place */ +LIBSASL_API char *sasl_strlower (char *val); + +LIBSASL_API int sasl_config_init(const char *filename); + +LIBSASL_API void sasl_config_done(void); + +#ifdef WIN32 +/* Just in case a different DLL defines this as well */ +#if defined(NEED_GETOPT) +LIBSASL_API int getopt(int argc, char **argv, char *optstring); +#endif +LIBSASL_API char * getpass(const char *prompt); +#endif /* WIN32 */ + +#ifdef __cplusplus +} +#endif + +#endif /* SASLUTIL_H */ diff --git a/libs/cyrussasl/lib/Makefile.am b/libs/cyrussasl/lib/Makefile.am new file mode 100644 index 00000000..b8964a87 --- /dev/null +++ b/libs/cyrussasl/lib/Makefile.am @@ -0,0 +1,104 @@ +# Makefile.am for the SASL library +# Rob Earhart +# $Id: Makefile.am,v 1.88 2011/09/05 14:18:10 murch Exp $ +# Copyright (c) 2000 Carnegie Mellon University. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The name "Carnegie Mellon University" must not be used to +# endorse or promote products derived from this software without +# prior written permission. For permission or any other legal +# details, please contact +# Office of Technology Transfer +# Carnegie Mellon University +# 5000 Forbes Avenue +# Pittsburgh, PA 15213-3890 +# (412) 268-4387, fax: (412) 268-7395 +# tech-transfer@andrew.cmu.edu +# +# 4. Redistributions of any form whatsoever must retain the following +# acknowledgment: +# "This product includes software developed by Computing Services +# at Carnegie Mellon University (http://www.cmu.edu/computing/)." +# +# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO +# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE +# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN +# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING +# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# + +# Library version info - here at the top, for sanity +# See +# CURRENT:REVISION:AGE +sasl_version = 3:0:0 + +INCLUDES=-DLIBSASL_EXPORTS=1 -I$(top_srcdir)/include -I$(top_srcdir)/plugins -I$(top_builddir)/include -I$(top_srcdir)/sasldb + +EXTRA_DIST = windlopen.c staticopen.h NTMakefile +EXTRA_LIBRARIES = libsasl2.a +noinst_LIBRARIES = @SASL_STATIC_LIBS@ +libsasl2_a_SOURCES= + +BUILT_SOURCES = $(SASL_STATIC_SRCS) + +common_headers = saslint.h +common_sources = auxprop.c canonusr.c checkpw.c client.c common.c config.c external.c md5.c saslutil.c server.c seterror.c dlopen.c ../plugins/plugin_common.c + +LTLIBOBJS = @LTLIBOBJS@ +LIBOBJS = @LIBOBJS@ +LIB_DOOR= @LIB_DOOR@ + +lib_LTLIBRARIES = libsasl2.la + +libsasl2_la_SOURCES = $(common_sources) $(common_headers) +libsasl2_la_LDFLAGS = -version-info $(sasl_version) +libsasl2_la_DEPENDENCIES = $(LTLIBOBJS) +libsasl2_la_LIBADD = $(LTLIBOBJS) $(SASL_DL_LIB) $(LIB_SOCKET) $(LIB_DOOR) + +if MACOSX +framedir = /Library/Frameworks/SASL2.framework +install-exec-hook: + $(mkinstalldirs) $(framedir)/Versions/A + ln -fs $(libdir)/libsasl2.dylib $(framedir)/Versions/A/SASL2 + cd $(framedir) ; ln -fs Versions/A/SASL2 . +else +install-exec-hook: +endif + +libsasl2.a: libsasl2.la $(SASL_STATIC_OBJS) + @echo adding static plugins and dependencies + $(AR) cru .libs/$@ $(SASL_STATIC_OBJS) + @for i in ./libsasl2.la ../sasldb/libsasldb.la ../plugins/lib*.la; do \ + if test ! -f $$i; then continue; fi; . $$i; \ + for j in $$dependency_libs foo; do \ + case $$j in foo) ;; \ + -L*) for k in $$depdirs foo; do \ + if test $$k = $$j; then break; fi; done; \ + if test $$k = foo; then depdirs="$$depdirs $$j"; fi ;; \ + -l*) for k in $$deplibs foo; do \ + if test $$k = $$j; then break; fi; done; \ + if test $$k = foo; then deplibs="$$deplibs $$j"; fi ;; \ + esac; done; dependency_libs=""; done; \ + sed -e "/^dependency_libs=/s%=.*%='$${depdirs}$${deplibs}'%" \ + libsasl2.la >TMP.$$ && mv TMP.$$ libsasl2.la + rm -f $@ + ln -s .libs/$@ $@ + +$(SASL_STATIC_SRCS): linksrcs + +linksrcs: + -ln -s $(SASL_STATIC_SRCS) . + diff --git a/libs/cyrussasl/lib/NTMakefile b/libs/cyrussasl/lib/NTMakefile new file mode 100755 index 00000000..817f9a4b --- /dev/null +++ b/libs/cyrussasl/lib/NTMakefile @@ -0,0 +1,128 @@ +!INCLUDE ..\win32\common.mak + +# WS2tcpip.h included in Visual Studio 7 provides getaddrinfo, ... +# emulation on Windows, so there is no need to build getaddrinfo.c + +!IF "$(VCVER)" == "6" +compat_sources = getaddrinfo.c getnameinfo.c +compat_objs = getaddrinfo.obj getnameinfo.obj +!ENDIF + + +libsasl_sources = auxprop.c canonusr.c checkpw.c client.c common.c config.c external.c md5.c saslutil.c server.c seterror.c windlopen.c getsubopt.c plugin_common.c plugin_common.h $(compat_sources) +libsasl_objs = auxprop.obj canonusr.obj checkpw.obj client.obj common.obj config.obj external.obj md5.obj saslutil.obj server.obj seterror.obj windlopen.obj getsubopt.obj plugin_common.obj $(compat_objs) +libsasl_res = libsasl.res +libsasl_out = libsasl.dll libsasl.exp libsasl.lib $(libsasl_res) + +CPPFLAGS = /wd4996 /Wp64 /D NEED_GETOPT /I "..\win32\include" /I "." /I "..\include" /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "LIBSASL_EXPORTS" + +!IF $(TARGET_WIN_SYSTEM) >= 51 +CPPFLAGS = /D TARGET_WIN_SYSTEM=$(TARGET_WIN_SYSTEM) $(CPPFLAGS) +!ENDIF + +all_objs = $(libsasl_objs) +all_out = $(libsasl_out) + +libdir = $(prefix)\lib +bindir = $(prefix)\bin +exclude_list = binexclude.lst + +all: all-recursive + +# +# /I flag to xcopy tells to treat the last parameter as directory and create all missing levels +# +# In order to force xcopy not to confirm if the second parameter is file or directory, +# the first parameter has to contain a wildcard character. For example, we use libsasl.l*, +# instead of libsasl.lib. Ugly, but works! +# +install: libsasl.dll + @echo libsasl.exp > $(exclude_list) + @echo libsasl.res >> $(exclude_list) + @echo libsasl.dll.manifest >> $(exclude_list) +# .lib is excluded only because it is copied separately below + @echo libsasl.lib >> $(exclude_list) + @xcopy libsasl.* $(bindir) /I /F /Y /EXCLUDE:$(exclude_list) + @xcopy libsasl.l* $(libdir) /I /F /Y + +all-recursive: libsasl.dll + +libsasl.dll: $(libsasl_objs) $(libsasl_res) + $(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"libsasl.dll" /implib:"libsasl.lib" /pdb:"libsasl.pdb" $(libsasl_objs) $(libsasl_res) +<< + IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2 + +plugin_common.c: ..\plugins\plugin_common.c plugin_common.h + xcopy /D /Y ..\plugins\plugin_common.c . + +plugin_common.h: ..\plugins\plugin_common.h + xcopy /D /Y ..\plugins\plugin_common.h . + +auxprop.obj checkpw.obj client.obj common.obj external.obj plugin_common.obj server.obj seterror.obj: ..\include\saslplug.h + +auxprop.obj canonusr.obj checkpw.obj client.obj common.obj config.obj external.obj getsubopt.obj md5.obj plugin_common.obj server.obj seterror.obj windlopen.obj: ..\include\sasl.h ..\include\prop.h + +auxprop.obj canonusr.obj checkpw.obj client.obj common.obj config.obj dlopen.obj external.obj saslutil.obj server.obj seterror.obj windlopen.obj: saslint.h + +CLEAN : + -@erase $(all_objs) + -@erase "*.idb" + -@erase "*.pdb" + -@erase "*.manifest" + -@erase $(all_out) + -@erase plugin_common.h + -@erase plugin_common.c + -@erase $(exclude_list) + +$(libsasl_res): NTMakefile + rc /fo"$(libsasl_res)" << +#include "windows.h" + +VS_VERSION_INFO VERSIONINFO + FILEVERSION $(SASL_VERSION_MAJOR),$(SASL_VERSION_MINOR),$(SASL_VERSION_STEP),0 + PRODUCTVERSION $(SASL_VERSION_MAJOR),$(SASL_VERSION_MINOR),$(SASL_VERSION_STEP),0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Carnegie Mellon University\0" + VALUE "FileDescription", "CMU SASL API v2\0" + VALUE "FileVersion", "$(SASL_VERSION_MAJOR).$(SASL_VERSION_MINOR).$(SASL_VERSION_STEP).0\0" + VALUE "InternalName", "libsasl\0" + VALUE "LegalCopyright", "Copyright (c) Carnegie Mellon University 2002-2012\0" + VALUE "OriginalFilename", "libsasl.dll\0" + VALUE "ProductName", "Carnegie Mellon University SASL\0" + VALUE "ProductVersion", "$(SASL_VERSION_MAJOR).$(SASL_VERSION_MINOR).$(SASL_VERSION_STEP)-0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END +<< + +.c.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< diff --git a/libs/cyrussasl/lib/auxprop.c b/libs/cyrussasl/lib/auxprop.c new file mode 100644 index 00000000..0644e5fb --- /dev/null +++ b/libs/cyrussasl/lib/auxprop.c @@ -0,0 +1,1198 @@ +/* auxprop.c - auxilliary property support + * Rob Siemborski + * $Id: auxprop.c,v 1.21 2011/09/01 14:12:53 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include "saslint.h" + +struct proppool +{ + struct proppool *next; + + size_t size; /* Size of Block */ + size_t unused; /* Space unused in this pool between end + * of char** area and beginning of char* area */ + + char data[1]; /* Variable Sized */ +}; + +struct propctx { + struct propval *values; + struct propval *prev_val; /* Previous value used by set/setvalues */ + + unsigned used_values, allocated_values; + + char *data_end; /* Bottom of string area in current pool */ + char **list_end; /* Top of list area in current pool */ + + struct proppool *mem_base; + struct proppool *mem_cur; +}; + +typedef struct auxprop_plug_list +{ + struct auxprop_plug_list *next; + const sasl_auxprop_plug_t *plug; +} auxprop_plug_list_t; + +static auxprop_plug_list_t *auxprop_head = NULL; + +static struct proppool *alloc_proppool(size_t size) +{ + struct proppool *ret; + /* minus 1 for the one that is already a part of the array + * in the struct */ + size_t total_size = sizeof(struct proppool) + size - 1; + ret = sasl_ALLOC(total_size); + if(!ret) return NULL; + + memset(ret, 0, total_size); + + ret->size = ret->unused = size; + + return ret; +} + +/* Resize a proppool. Invalidates the unused value for this pool */ +static struct proppool *resize_proppool(struct proppool *pool, size_t size) +{ + struct proppool *ret; + + if(pool->size >= size) return pool; + ret = sasl_REALLOC(pool, sizeof(struct proppool) + size); + if(!ret) return NULL; + + ret->size = size; + + return ret; +} + +static int prop_init(struct propctx *ctx, unsigned estimate) +{ + const unsigned VALUES_SIZE = PROP_DEFAULT * sizeof(struct propval); + + ctx->mem_base = alloc_proppool(VALUES_SIZE + estimate); + if(!ctx->mem_base) return SASL_NOMEM; + + ctx->mem_cur = ctx->mem_base; + + ctx->values = (struct propval *)ctx->mem_base->data; + ctx->mem_base->unused = ctx->mem_base->size - VALUES_SIZE; + ctx->allocated_values = PROP_DEFAULT; + ctx->used_values = 0; + + ctx->data_end = ctx->mem_base->data + ctx->mem_base->size; + ctx->list_end = (char **)(ctx->mem_base->data + VALUES_SIZE); + + ctx->prev_val = NULL; + + return SASL_OK; +} + +/* create a property context + * estimate -- an estimate of the storage needed for requests & responses + * 0 will use module default + * returns NULL on error + */ +struct propctx *prop_new(unsigned estimate) +{ + struct propctx *new_ctx; + + if(!estimate) estimate = PROP_DEFAULT * 255; + + new_ctx = sasl_ALLOC(sizeof(struct propctx)); + if(!new_ctx) return NULL; + + if(prop_init(new_ctx, estimate) != SASL_OK) { + prop_dispose(&new_ctx); + } + + return new_ctx; +} + +/* create new propctx which duplicates the contents of an existing propctx + * returns -1 on error + */ +int prop_dup(struct propctx *src_ctx, struct propctx **dst_ctx) +{ + struct proppool *pool; + struct propctx *retval = NULL; + unsigned i; + int result; + unsigned total_size = 0; + size_t values_size; + + if(!src_ctx || !dst_ctx) return SASL_BADPARAM; + + /* What is the total allocated size of src_ctx? */ + pool = src_ctx->mem_base; + while(pool) { + total_size += (unsigned) pool->size; + pool = pool->next; + } + + /* allocate the new context */ + retval = prop_new(total_size); + if(!retval) return SASL_NOMEM; + + retval->used_values = src_ctx->used_values; + retval->allocated_values = src_ctx->used_values + 1; + + values_size = (retval->allocated_values * sizeof(struct propval)); + + retval->mem_base->unused = retval->mem_base->size - values_size; + + retval->list_end = (char **)(retval->mem_base->data + values_size); + /* data_end should still be OK */ + + /* Now dup the values */ + for(i=0; iused_values; i++) { + retval->values[i].name = src_ctx->values[i].name; + result = prop_setvals(retval, retval->values[i].name, + src_ctx->values[i].values); + if(result != SASL_OK) + goto fail; + } + + retval->prev_val = src_ctx->prev_val; + + *dst_ctx = retval; + return SASL_OK; + + fail: + if(retval) prop_dispose(&retval); + return result; +} + +/* + * dispose of property context + * ctx -- is disposed and set to NULL; noop if ctx or *ctx is NULL + */ +void prop_dispose(struct propctx **ctx) +{ + struct proppool *tmp; + + if(!ctx || !*ctx) return; + + while((*ctx)->mem_base) { + tmp = (*ctx)->mem_base; + (*ctx)->mem_base = tmp->next; + sasl_FREE(tmp); + } + + sasl_FREE(*ctx); + *ctx = NULL; + + return; +} + +/* Add property names to request + * ctx -- context from prop_new() + * names -- list of property names; must persist until context freed + * or requests cleared + * + * NOTE: may clear values from context as side-effect + * returns -1 on error + */ +int prop_request(struct propctx *ctx, const char **names) +{ + unsigned i, new_values, total_values; + + if(!ctx || !names) return SASL_BADPARAM; + + /* Count how many we need to add */ + for(new_values=0; names[new_values]; new_values++); + + /* Do we need to add ANY? */ + if(!new_values) return SASL_OK; + + /* We always want at least one extra to mark the end of the array */ + total_values = new_values + ctx->used_values + 1; + + /* Do we need to increase the size of our propval table? */ + if(total_values > ctx->allocated_values) { + unsigned max_in_pool; + + /* Do we need a larger base pool? */ + max_in_pool = (unsigned) (ctx->mem_base->size / sizeof(struct propval)); + + if(total_values <= max_in_pool) { + /* Don't increase the size of the base pool, just use what + we need */ + ctx->allocated_values = total_values; + ctx->mem_base->unused = + ctx->mem_base->size - (sizeof(struct propval) + * ctx->allocated_values); + } else { + /* We need to allocate more! */ + unsigned new_alloc_length; + size_t new_size; + + new_alloc_length = 2 * ctx->allocated_values; + while(total_values > new_alloc_length) { + new_alloc_length *= 2; + } + + new_size = new_alloc_length * sizeof(struct propval); + ctx->mem_base = resize_proppool(ctx->mem_base, new_size); + + if(!ctx->mem_base) { + ctx->values = NULL; + ctx->allocated_values = ctx->used_values = 0; + return SASL_NOMEM; + } + + /* It worked! Update the structure! */ + ctx->values = (struct propval *)ctx->mem_base->data; + ctx->allocated_values = new_alloc_length; + ctx->mem_base->unused = ctx->mem_base->size + - sizeof(struct propval) * ctx->allocated_values; + } + + /* Clear out new propvals */ + memset(&(ctx->values[ctx->used_values]), 0, + sizeof(struct propval) * (ctx->allocated_values - ctx->used_values)); + + /* Finish updating the context -- we've extended the list! */ + /* ctx->list_end = (char **)(ctx->values + ctx->allocated_values); */ + /* xxx test here */ + ctx->list_end = (char **)(ctx->values + total_values); + } + + /* Now do the copy, or referencing rather */ + for(i=0;iused_values;j++) { + if(!strcmp(ctx->values[j].name, names[i])) { + flag = 1; + break; + } + } + + /* We already have it... skip! */ + if(flag) continue; + + ctx->values[ctx->used_values++].name = names[i]; + } + + prop_clear(ctx, 0); + + return SASL_OK; +} + +/* return array of struct propval from the context + * return value persists until next call to + * prop_request, prop_clear or prop_dispose on context + */ +const struct propval *prop_get(struct propctx *ctx) +{ + if(!ctx) return NULL; + + return ctx->values; +} + +/* Fill in an array of struct propval based on a list of property names + * return value persists until next call to + * prop_request, prop_clear or prop_dispose on context + * returns -1 on error (no properties ever requested, ctx NULL, etc) + * returns number of matching properties which were found (values != NULL) + * if a name requested here was never requested by a prop_request, then + * the name field of the associated vals entry will be set to NULL + */ +int prop_getnames(struct propctx *ctx, const char **names, + struct propval *vals) +{ + int found_names = 0; + + struct propval *cur = vals; + const char **curname; + + if(!ctx || !names || !vals) return SASL_BADPARAM; + + for(curname = names; *curname; curname++) { + struct propval *val; + for(val = ctx->values; val->name; val++) { + if(!strcmp(*curname,val->name)) { + found_names++; + memcpy(cur, val, sizeof(struct propval)); + goto next; + } + } + + /* If we are here, we didn't find it */ + memset(cur, 0, sizeof(struct propval)); + + next: + cur++; + } + + return found_names; +} + + +/* clear values and optionally requests from property context + * ctx -- property context + * requests -- 0 = don't clear requests, 1 = clear requests + */ +void prop_clear(struct propctx *ctx, int requests) +{ + struct proppool *new_pool, *tmp; + unsigned i; + + /* We're going to need a new proppool once we reset things */ + new_pool = alloc_proppool(ctx->mem_base->size + + (ctx->used_values+1) * sizeof(struct propval)); + + if(requests) { + /* We're wiping the whole shebang */ + ctx->used_values = 0; + } else { + /* Need to keep around old requets */ + struct propval *new_values = (struct propval *)new_pool->data; + for(i=0; iused_values; i++) { + new_values[i].name = ctx->values[i].name; + } + } + + while(ctx->mem_base) { + tmp = ctx->mem_base; + ctx->mem_base = tmp->next; + sasl_FREE(tmp); + } + + /* Update allocation-related metadata */ + ctx->allocated_values = ctx->used_values+1; + new_pool->unused = + new_pool->size - (ctx->allocated_values * sizeof(struct propval)); + + /* Setup pointers for the values array */ + ctx->values = (struct propval *)new_pool->data; + ctx->prev_val = NULL; + + /* Setup the pools */ + ctx->mem_base = ctx->mem_cur = new_pool; + + /* Reset list_end and data_end for the new memory pool */ + ctx->list_end = + (char **)((char *)ctx->mem_base->data + ctx->allocated_values * sizeof(struct propval)); + ctx->data_end = (char *)ctx->mem_base->data + ctx->mem_base->size; + + return; +} + +/* + * erase the value of a property + */ +void prop_erase(struct propctx *ctx, const char *name) +{ + struct propval *val; + int i; + + if(!ctx || !name) return; + + for(val = ctx->values; val->name; val++) { + if(!strcmp(name,val->name)) { + if(!val->values) break; + + /* + * Yes, this is casting away the const, but + * we should be okay because the only place this + * memory should be is in the proppool's + */ + for(i=0;val->values[i];i++) { + memset((void *)(val->values[i]),0,strlen(val->values[i])); + val->values[i] = NULL; + } + + val->values = NULL; + val->nvalues = 0; + val->valsize = 0; + break; + } + } + + return; +} + +/****fetcher interfaces****/ + +/* format the requested property names into a string + * ctx -- context from prop_new()/prop_request() + * sep -- separator between property names (unused if none requested) + * seplen -- length of separator, if < 0 then strlen(sep) will be used + * outbuf -- output buffer + * outmax -- maximum length of output buffer including NUL terminator + * outlen -- set to length of output string excluding NUL terminator + * returns 0 on success and amount of additional space needed on failure + */ +int prop_format(struct propctx *ctx, const char *sep, int seplen, + char *outbuf, unsigned outmax, unsigned *outlen) +{ + unsigned needed, flag = 0; + struct propval *val; + + if (!ctx || !outbuf) return SASL_BADPARAM; + + if (!sep) seplen = 0; + if (seplen < 0) seplen = (int) strlen(sep); +/* If seplen is negative now we have overflow. + But if you have a string longer than 2Gb, you are an idiot anyway */ + if (seplen < 0) return SASL_BADPARAM; + + needed = seplen * (ctx->used_values - 1); + for(val = ctx->values; val->name; val++) { + needed += (unsigned) strlen(val->name); + } + + if(!outmax) return (needed + 1); /* Because of unsigned funkiness */ + if(needed > (outmax - 1)) return (needed - (outmax - 1)); + + *outbuf = '\0'; + if(outlen) *outlen = needed; + + if(needed == 0) return SASL_OK; + + for(val = ctx->values; val->name; val++) { + if(seplen && flag) { + strncat(outbuf, sep, seplen); + } else { + flag = 1; + } + strcat(outbuf, val->name); + } + + return SASL_OK; +} + +/* add a property value to the context + * ctx -- context from prop_new()/prop_request() + * name -- name of property to which value will be added + * if NULL, add to the same name as previous prop_set/setvals call + * value -- a value for the property; will be copied into context + * if NULL, remove existing values + * vallen -- length of value, if <= 0 then strlen(value) will be used + */ +int prop_set(struct propctx *ctx, const char *name, + const char *value, int vallen) +{ + struct propval *cur; + + if(!ctx) return SASL_BADPARAM; + if(!name && !ctx->prev_val) return SASL_BADPARAM; + + if(name) { + struct propval *val; + + ctx->prev_val = NULL; + + for(val = ctx->values; val->name; val++) { + if(!strcmp(name,val->name)){ + ctx->prev_val = val; + break; + } + } + + /* Couldn't find it! */ + if(!ctx->prev_val) return SASL_BADPARAM; + } + + cur = ctx->prev_val; + + if(name) /* New Entry */ { + unsigned nvalues = 1; /* 1 for NULL entry */ + const char **old_values = NULL; + char **tmp, **tmp2; + size_t size; + + if(cur->values) { + + if(!value) { + /* If we would be adding a null value, then we are done */ + return SASL_OK; + } + + old_values = cur->values; + tmp = (char **)cur->values; + while(*tmp) { + nvalues++; + tmp++; + } + + } + + if(value) { + nvalues++; /* for the new value */ + } + + size = nvalues * sizeof(char*); + + if(size > ctx->mem_cur->unused) { + size_t needed; + + for(needed = ctx->mem_cur->size * 2; needed < size; needed *= 2); + + /* Allocate a new proppool */ + ctx->mem_cur->next = alloc_proppool(needed); + if(!ctx->mem_cur->next) return SASL_NOMEM; + + ctx->mem_cur = ctx->mem_cur->next; + + ctx->list_end = (char **)ctx->mem_cur->data; + ctx->data_end = ctx->mem_cur->data + needed; + } + + /* Grab the memory */ + ctx->mem_cur->unused -= size; + cur->values = (const char **)ctx->list_end; + cur->values[nvalues - 1] = NULL; + + /* Finish updating the context */ + ctx->list_end = (char **)(cur->values + nvalues); + + /* If we don't have an actual value to fill in, we are done */ + if(!value) + return SASL_OK; + + tmp2 = (char **)cur->values; + if(old_values) { + tmp = (char **)old_values; + + while(*tmp) { + *tmp2 = *tmp; + tmp++; tmp2++; + } + } + + /* Now allocate the last entry */ + if(vallen <= 0) + size = (size_t)(strlen(value) + 1); + else + size = (size_t)(vallen + 1); + + if(size > ctx->mem_cur->unused) { + size_t needed; + + needed = ctx->mem_cur->size * 2; + + while(needed < size) { + needed *= 2; + } + + /* Allocate a new proppool */ + ctx->mem_cur->next = alloc_proppool(needed); + if(!ctx->mem_cur->next) return SASL_NOMEM; + + ctx->mem_cur = ctx->mem_cur->next; + ctx->list_end = (char **)ctx->mem_cur->data; + ctx->data_end = ctx->mem_cur->data + needed; + } + + /* Update the data_end pointer */ + ctx->data_end -= size; + ctx->mem_cur->unused -= size; + + /* Copy and setup the new value! */ + memcpy(ctx->data_end, value, size-1); + ctx->data_end[size - 1] = '\0'; + cur->values[nvalues - 2] = ctx->data_end; + + cur->nvalues++; + cur->valsize += ((unsigned) size - 1); + } else /* Appending an entry */ { + char **tmp; + size_t size; + + /* If we are setting it to be NULL, we are done */ + if(!value) return SASL_OK; + + size = sizeof(char*); + + /* Is it in the current pool, and will it fit in the unused space? */ + if(size > ctx->mem_cur->unused && + (void *)cur->values > (void *)(ctx->mem_cur->data) && + (void *)cur->values < (void *)(ctx->mem_cur->data + ctx->mem_cur->size)) { + /* recursively call the not-fast way */ + return prop_set(ctx, cur->name, value, vallen); + } + + /* Note the invariant: the previous value list must be + at the top of the CURRENT pool at this point */ + + /* Grab the memory */ + ctx->mem_cur->unused -= size; + ctx->list_end++; + + *(ctx->list_end - 1) = NULL; + tmp = (ctx->list_end - 2); + + /* Now allocate the last entry */ + if(vallen <= 0) + size = strlen(value) + 1; + else + size = vallen + 1; + + if(size > ctx->mem_cur->unused) { + size_t needed; + + needed = ctx->mem_cur->size * 2; + + while(needed < size) { + needed *= 2; + } + + /* Allocate a new proppool */ + ctx->mem_cur->next = alloc_proppool(needed); + if(!ctx->mem_cur->next) return SASL_NOMEM; + + ctx->mem_cur = ctx->mem_cur->next; + ctx->list_end = (char **)ctx->mem_cur->data; + ctx->data_end = ctx->mem_cur->data + needed; + } + + /* Update the data_end pointer */ + ctx->data_end -= size; + ctx->mem_cur->unused -= size; + + /* Copy and setup the new value! */ + memcpy(ctx->data_end, value, size-1); + ctx->data_end[size - 1] = '\0'; + *tmp = ctx->data_end; + + cur->nvalues++; + cur->valsize += ((unsigned) size - 1); + } + + return SASL_OK; +} + + +/* set the values for a property + * ctx -- context from prop_new()/prop_request() + * name -- name of property to which value will be added + * if NULL, add to the same name as previous prop_set/setvals call + * values -- array of values, ending in NULL. Each value is a NUL terminated + * string + */ +int prop_setvals(struct propctx *ctx, const char *name, + const char **values) +{ + const char **val = values; + int result = SASL_OK; + + if(!ctx) return SASL_BADPARAM; + + /* If they want us to add no values, we can do that */ + if(!values) return SASL_OK; + + /* Basically, use prop_set to do all our dirty work for us */ + if(name) { + result = prop_set(ctx, name, *val, 0); + val++; + } + + for(;*val;val++) { + if(result != SASL_OK) return result; + result = prop_set(ctx, NULL, *val,0); + } + + return result; +} + +/* Request a set of auxiliary properties + * conn connection context + * propnames list of auxiliary property names to request ending with + * NULL. + * + * Subsequent calls will add items to the request list. Call with NULL + * to clear the request list. + * + * errors + * SASL_OK -- success + * SASL_BADPARAM -- bad count/conn parameter + * SASL_NOMEM -- out of memory + */ +int sasl_auxprop_request(sasl_conn_t *conn, const char **propnames) +{ + int result; + sasl_server_conn_t *sconn; + + if(!conn) return SASL_BADPARAM; + if(conn->type != SASL_CONN_SERVER) + PARAMERROR(conn); + + sconn = (sasl_server_conn_t *)conn; + + if(!propnames) { + prop_clear(sconn->sparams->propctx,1); + return SASL_OK; + } + + result = prop_request(sconn->sparams->propctx, propnames); + RETURN(conn, result); +} + + +/* Returns current auxiliary property context. + * Use functions in prop.h to access content + * + * if authentication hasn't completed, property values may be empty/NULL + * + * properties not recognized by active plug-ins will be left empty/NULL + * + * returns NULL if conn is invalid. + */ +struct propctx *sasl_auxprop_getctx(sasl_conn_t *conn) +{ + sasl_server_conn_t *sconn; + + if(!conn || conn->type != SASL_CONN_SERVER) return NULL; + + sconn = (sasl_server_conn_t *)conn; + + return sconn->sparams->propctx; +} + +/* add an auxiliary property plugin */ +int sasl_auxprop_add_plugin(const char *plugname, + sasl_auxprop_init_t *auxpropfunc) +{ + int result, out_version; + auxprop_plug_list_t *new_item; + sasl_auxprop_plug_t *plug; + + result = auxpropfunc(sasl_global_utils, SASL_AUXPROP_PLUG_VERSION, + &out_version, &plug, plugname); + + /* Check if out_version is too old. + We only support the current at the moment */ + if (result == SASL_OK && out_version < SASL_AUXPROP_PLUG_VERSION) { + result = SASL_BADVERS; + } + + if(result != SASL_OK) { + _sasl_log(NULL, SASL_LOG_ERR, "auxpropfunc error %s\n", + sasl_errstring(result, NULL, NULL)); + return result; + } + + /* We require that this function is implemented */ + if(!plug->auxprop_lookup) return SASL_BADPROT; + + new_item = sasl_ALLOC(sizeof(auxprop_plug_list_t)); + if(!new_item) return SASL_NOMEM; + + /* These will load from least-important to most important */ + new_item->plug = plug; + new_item->next = auxprop_head; + auxprop_head = new_item; + + return SASL_OK; +} + +void _sasl_auxprop_free() +{ + auxprop_plug_list_t *ptr, *ptr_next; + + for(ptr = auxprop_head; ptr; ptr = ptr_next) { + ptr_next = ptr->next; + if(ptr->plug->auxprop_free) + ptr->plug->auxprop_free(ptr->plug->glob_context, + sasl_global_utils); + sasl_FREE(ptr); + } + + auxprop_head = NULL; +} + +/* Return the updated account status based on the current ("so far") and + the specific status returned by the latest auxprop call */ +static int +_sasl_account_status (int current_status, + int specific_status) +{ + switch (specific_status) { + case SASL_NOVERIFY: + specific_status = SASL_OK; + /* fall through */ + case SASL_OK: + if (current_status == SASL_NOMECH || + current_status == SASL_NOUSER) { + current_status = specific_status; + } + break; + + case SASL_NOUSER: + if (current_status == SASL_NOMECH) { + current_status = specific_status; + } + break; + + /* NOTE: The disabled flag sticks, unless we hit an error */ + case SASL_DISABLED: + if (current_status == SASL_NOMECH || + current_status == SASL_NOUSER || + current_status == SASL_OK) { + current_status = specific_status; + } + break; + + case SASL_NOMECH: + /* ignore */ + break; + + /* SASL_UNAVAIL overrides everything */ + case SASL_UNAVAIL: + current_status = specific_status; + break; + + default: + current_status = specific_status; + break; + } + return (current_status); +} + +/* Do the callbacks for auxprop lookups */ +int _sasl_auxprop_lookup(sasl_server_params_t *sparams, + unsigned flags, + const char *user, unsigned ulen) +{ + sasl_getopt_t *getopt; + int ret, found = 0; + void *context; + const char *plist = NULL; + auxprop_plug_list_t *ptr; + int result = SASL_NOMECH; + + if(_sasl_getcallback(sparams->utils->conn, + SASL_CB_GETOPT, + (sasl_callback_ft *)&getopt, + &context) == SASL_OK) { + ret = getopt(context, NULL, "auxprop_plugin", &plist, NULL); + if(ret != SASL_OK) plist = NULL; + } + + if(!plist) { + /* Do lookup in all plugins */ + + /* TODO: Ideally, each auxprop plugin should be marked if its failure + should be ignored or treated as a fatal error of the whole lookup. */ + for(ptr = auxprop_head; ptr; ptr = ptr->next) { + found=1; + ret = ptr->plug->auxprop_lookup(ptr->plug->glob_context, + sparams, flags, user, ulen); + result = _sasl_account_status (result, ret); + } + } else { + char *pluginlist = NULL, *freeptr = NULL, *thisplugin = NULL; + + if(_sasl_strdup(plist, &pluginlist, NULL) != SASL_OK) return SASL_NOMEM; + thisplugin = freeptr = pluginlist; + + /* Do lookup in all *specified* plugins, in order */ + while(*thisplugin) { + char *p; + int last=0; + + while(*thisplugin && isspace((int)*thisplugin)) thisplugin++; + if(!(*thisplugin)) break; + + for(p = thisplugin;*p != '\0' && !isspace((int)*p); p++); + if(*p == '\0') last = 1; + else *p='\0'; + + for(ptr = auxprop_head; ptr; ptr = ptr->next) { + /* Skip non-matching plugins */ + if(!ptr->plug->name + || strcasecmp(ptr->plug->name, thisplugin)) + continue; + + found=1; + ret = ptr->plug->auxprop_lookup(ptr->plug->glob_context, + sparams, flags, user, ulen); + result = _sasl_account_status (result, ret); + } + + if(last) break; + + thisplugin = p+1; + } + + sasl_FREE(freeptr); + } + + if(!found) { + _sasl_log(sparams->utils->conn, SASL_LOG_DEBUG, + "could not find auxprop plugin, was searching for '%s'", + plist ? plist : "[all]"); + } + + return result; +} + +/* Do the callbacks for auxprop stores */ +int sasl_auxprop_store(sasl_conn_t *conn, + struct propctx *ctx, const char *user) +{ + sasl_getopt_t *getopt; + int ret; + void *context; + const char *plist = NULL; + auxprop_plug_list_t *ptr; + sasl_server_params_t *sparams = NULL; + unsigned userlen = 0; + int num_constraint_violations = 0; + int total_plugins = 0; + + if (ctx) { + if (!conn || !user) + return SASL_BADPARAM; + + sparams = ((sasl_server_conn_t *) conn)->sparams; + userlen = (unsigned) strlen(user); + } + + /* Pickup getopt callback from the connection, if conn is not NULL */ + if(_sasl_getcallback(conn, SASL_CB_GETOPT, (sasl_callback_ft *)&getopt, &context) == SASL_OK) { + ret = getopt(context, NULL, "auxprop_plugin", &plist, NULL); + if(ret != SASL_OK) plist = NULL; + } + + ret = SASL_OK; + if(!plist) { + /* Do store in all plugins */ + for(ptr = auxprop_head; ptr && ret == SASL_OK; ptr = ptr->next) { + total_plugins++; + if (ptr->plug->auxprop_store) { + ret = ptr->plug->auxprop_store(ptr->plug->glob_context, + sparams, ctx, user, userlen); + if (ret == SASL_CONSTRAINT_VIOLAT) { + ret = SASL_OK; + num_constraint_violations++; + } + } + } + } else { + char *pluginlist = NULL, *freeptr = NULL, *thisplugin = NULL; + + if(_sasl_strdup(plist, &pluginlist, NULL) != SASL_OK) return SASL_FAIL; + thisplugin = freeptr = pluginlist; + + /* Do store in all *specified* plugins, in order */ + while(*thisplugin) { + char *p; + int last=0; + + while(*thisplugin && isspace((int)*thisplugin)) thisplugin++; + if(!(*thisplugin)) break; + + for(p = thisplugin;*p != '\0' && !isspace((int)*p); p++); + if(*p == '\0') last = 1; + else *p='\0'; + + for(ptr = auxprop_head; ptr && ret == SASL_OK; ptr = ptr->next) { + /* Skip non-matching plugins */ + if((!ptr->plug->name + || strcasecmp(ptr->plug->name, thisplugin))) + continue; + + total_plugins++; + if (ptr->plug->auxprop_store) { + ret = ptr->plug->auxprop_store(ptr->plug->glob_context, + sparams, ctx, user, userlen); + if (ret == SASL_CONSTRAINT_VIOLAT) { + ret = SASL_OK; + num_constraint_violations++; + } + } + } + + if(last) break; + + thisplugin = p+1; + } + + sasl_FREE(freeptr); + } + + if(total_plugins == 0) { + _sasl_log(NULL, SASL_LOG_ERR, + "could not find auxprop plugin, was searching for %s", + plist ? plist : "[all]"); + return SASL_FAIL; + } else if (total_plugins == num_constraint_violations) { + ret = SASL_CONSTRAINT_VIOLAT; + } + + return ret; +} + +/* It would be nice if we can show other information like Author, Company, Year, plugin version */ +static void +_sasl_print_mechanism (sasl_auxprop_plug_t *m, + sasl_info_callback_stage_t stage, + void *rock __attribute__((unused)) +) +{ + if (stage == SASL_INFO_LIST_START) { + printf ("List of auxprop plugins follows\n"); + return; + } else if (stage == SASL_INFO_LIST_END) { + return; + } + + /* Process the mechanism */ + printf ("Plugin \"%s\" ", m->name); + +#ifdef NOT_YET + switch (m->condition) { + case SASL_OK: + printf ("[loaded]"); + break; + + case SASL_CONTINUE: + printf ("[delayed]"); + break; + + case SASL_NOUSER: + printf ("[no users]"); + break; + + default: + printf ("[unknown]"); + break; + } +#endif + + printf (", \tAPI version: %d\n", /* m->version */ SASL_AUXPROP_PLUG_VERSION); + + /* TODO - Update for auxprop_export, etc. */ + printf ("\tsupports store: %s\n", + (m->auxprop_store != NULL) ? "yes" : "no" + ); + + /* No features defined yet */ +#ifdef NOT_YET + printf ("\n\tfeatures:"); +#endif + + printf ("\n"); +} + +/* Dump information about available auxprop plugins (separate functions are + used for canon and server authentication plugins) */ +int auxprop_plugin_info ( + const char *c_mech_list, /* space separated mechanism list or NULL for ALL */ + auxprop_info_callback_t *info_cb, + void *info_cb_rock +) +{ + auxprop_plug_list_t *m; + sasl_auxprop_plug_t plug_data; + char * cur_mech; + char *mech_list = NULL; + char * p; + + if (info_cb == NULL) { + info_cb = _sasl_print_mechanism; + } + + if (auxprop_head != NULL) { + info_cb (NULL, SASL_INFO_LIST_START, info_cb_rock); + + if (c_mech_list == NULL) { + m = auxprop_head; /* m point to beginning of the list */ + + while (m != NULL) { + /* TODO: Need to be careful when dealing with auxprop_export, etc. */ + memcpy (&plug_data, m->plug, sizeof(plug_data)); + + info_cb (&plug_data, SASL_INFO_LIST_MECH, info_cb_rock); + + m = m->next; + } + } else { + mech_list = strdup(c_mech_list); + + cur_mech = mech_list; + + while (cur_mech != NULL) { + p = strchr (cur_mech, ' '); + if (p != NULL) { + *p = '\0'; + p++; + } + + m = auxprop_head; /* m point to beginning of the list */ + + while (m != NULL) { + if (strcasecmp (cur_mech, m->plug->name) == 0) { + memcpy (&plug_data, m->plug, sizeof(plug_data)); + + info_cb (&plug_data, SASL_INFO_LIST_MECH, info_cb_rock); + } + + m = m->next; + } + + cur_mech = p; + } + + free (mech_list); + } + + info_cb (NULL, SASL_INFO_LIST_END, info_cb_rock); + + return (SASL_OK); + } + + return (SASL_NOTINIT); +} diff --git a/libs/cyrussasl/lib/canonusr.c b/libs/cyrussasl/lib/canonusr.c new file mode 100644 index 00000000..faee1038 --- /dev/null +++ b/libs/cyrussasl/lib/canonusr.c @@ -0,0 +1,462 @@ +/* canonusr.c - user canonicalization support + * Rob Siemborski + * $Id: canonusr.c,v 1.22 2011/09/01 16:33:42 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#include "saslint.h" + +typedef struct canonuser_plug_list +{ + struct canonuser_plug_list *next; + char name[PATH_MAX]; + const sasl_canonuser_plug_t *plug; +} canonuser_plug_list_t; + +static canonuser_plug_list_t *canonuser_head = NULL; + +/* default behavior: + * eliminate leading & trailing whitespace, + * null-terminate, and get into the outparams + * (handled by INTERNAL plugin) */ +/* a zero ulen or alen indicates that it is strlen(value) */ +int _sasl_canon_user(sasl_conn_t *conn, + const char *user, unsigned ulen, + unsigned flags, + sasl_out_params_t *oparams) +{ + canonuser_plug_list_t *ptr; + sasl_server_conn_t *sconn = NULL; + sasl_client_conn_t *cconn = NULL; + sasl_canon_user_t *cuser_cb; + sasl_getopt_t *getopt; + void *context; + int result; + const char *plugin_name = NULL; + char *user_buf; + unsigned *lenp; + + if(!conn) return SASL_BADPARAM; + if(!user || !oparams) return SASL_BADPARAM; + + if(flags & SASL_CU_AUTHID) { + user_buf = conn->authid_buf; + lenp = &(oparams->alen); + } else if (flags & SASL_CU_AUTHZID) { + user_buf = conn->user_buf; + lenp = &(oparams->ulen); + } else { + return SASL_BADPARAM; + } + + if(conn->type == SASL_CONN_SERVER) sconn = (sasl_server_conn_t *)conn; + else if(conn->type == SASL_CONN_CLIENT) cconn = (sasl_client_conn_t *)conn; + else return SASL_FAIL; + + if(!ulen) ulen = (unsigned int)strlen(user); + + /* check to see if we have a callback to make*/ + result = _sasl_getcallback(conn, + SASL_CB_CANON_USER, + (sasl_callback_ft *)&cuser_cb, + &context); + if(result == SASL_OK && cuser_cb) { + result = cuser_cb(conn, + context, + user, + ulen, + flags, + (conn->type == SASL_CONN_SERVER ? + sconn->user_realm : + NULL), + user_buf, + CANON_BUF_SIZE, + lenp); + + + if (result != SASL_OK) return result; + + /* Point the input copy at the stored buffer */ + user = user_buf; + ulen = *lenp; + } + + /* which plugin are we supposed to use? */ + result = _sasl_getcallback(conn, + SASL_CB_GETOPT, + (sasl_callback_ft *)&getopt, + &context); + if (result == SASL_OK && getopt) { + getopt(context, NULL, "canon_user_plugin", &plugin_name, NULL); + } + + if (!plugin_name) { + /* Use Default */ + plugin_name = "INTERNAL"; + } + + for (ptr = canonuser_head; ptr; ptr = ptr->next) { + /* A match is if we match the internal name of the plugin, or if + * we match the filename (old-style) */ + if ((ptr->plug->name && !strcmp(plugin_name, ptr->plug->name)) + || !strcmp(plugin_name, ptr->name)) break; + } + + /* We clearly don't have this one! */ + if (!ptr) { + sasl_seterror(conn, 0, "desired canon_user plugin %s not found", + plugin_name); + return SASL_NOMECH; + } + + if (sconn) { + /* we're a server */ + result = ptr->plug->canon_user_server(ptr->plug->glob_context, + sconn->sparams, + user, ulen, + flags, + user_buf, + CANON_BUF_SIZE, lenp); + } else { + /* we're a client */ + result = ptr->plug->canon_user_client(ptr->plug->glob_context, + cconn->cparams, + user, ulen, + flags, + user_buf, + CANON_BUF_SIZE, lenp); + } + + if (result != SASL_OK) return result; + + if ((flags & SASL_CU_AUTHID) && (flags & SASL_CU_AUTHZID)) { + /* We did both, so we need to copy the result into + * the buffer for the authzid from the buffer for the authid */ + memcpy(conn->user_buf, conn->authid_buf, CANON_BUF_SIZE); + oparams->ulen = oparams->alen; + } + + /* Set the appropriate oparams (lengths have already been set by lenp) */ + if (flags & SASL_CU_AUTHID) { + oparams->authid = conn->authid_buf; + } + + if (flags & SASL_CU_AUTHZID) { + oparams->user = conn->user_buf; + } + + RETURN(conn, result); +} + +/* Lookup all properties for authentication and/or authorization identity. */ +static int _sasl_auxprop_lookup_user_props (sasl_conn_t *conn, + unsigned flags, + sasl_out_params_t *oparams) +{ + sasl_server_conn_t *sconn = NULL; + int result = SASL_OK; + + if (!conn) return SASL_BADPARAM; + if (!oparams) return SASL_BADPARAM; + +#ifndef macintosh + if (conn->type == SASL_CONN_SERVER) sconn = (sasl_server_conn_t *)conn; + + /* do auxprop lookups (server only) */ + if (sconn) { + int authz_result; + unsigned auxprop_lookup_flags = flags & SASL_CU_ASIS_MASK; + + if (flags & SASL_CU_OVERRIDE) { + auxprop_lookup_flags |= SASL_AUXPROP_OVERRIDE; + } + + if (flags & SASL_CU_AUTHID) { + result = _sasl_auxprop_lookup(sconn->sparams, + auxprop_lookup_flags, + oparams->authid, + oparams->alen); + } else { + result = SASL_CONTINUE; + } + if (flags & SASL_CU_AUTHZID) { + authz_result = _sasl_auxprop_lookup(sconn->sparams, + auxprop_lookup_flags | SASL_AUXPROP_AUTHZID, + oparams->user, + oparams->ulen); + + if (result == SASL_CONTINUE) { + /* Only SASL_CU_AUTHZID was requested. + The authz_result value is authoritative. */ + result = authz_result; + } else if (result == SASL_OK && authz_result != SASL_NOUSER) { + /* Use the authz_result value, unless "result" + already contains an error */ + result = authz_result; + } + } + + if ((flags & SASL_CU_EXTERNALLY_VERIFIED) && (result == SASL_NOUSER || result == SASL_NOMECH)) { + /* The called has explicitly told us that the authentication identity + was already verified or will be verified independently. + So a failure to retrieve any associated properties + is not an error. For example the caller is using Kerberos to verify user, + but the LDAPDB/SASLDB auxprop plugin doesn't contain any auxprops for + the user. + Another case is PLAIN/LOGIN not using auxprop to verify user passwords. */ + result = SASL_OK; + } + } +#endif + + RETURN(conn, result); +} + +/* default behavior: + * Eliminate leading & trailing whitespace, + * null-terminate, and get into the outparams + * (handled by INTERNAL plugin). + * + * Server only: Also does auxprop lookups once username + * is canonicalized. */ +int _sasl_canon_user_lookup (sasl_conn_t *conn, + const char *user, + unsigned ulen, + unsigned flags, + sasl_out_params_t *oparams) +{ + int result; + + result = _sasl_canon_user (conn, + user, + ulen, + flags, + oparams); + if (result == SASL_OK) { + result = _sasl_auxprop_lookup_user_props (conn, + flags, + oparams); + } + + RETURN(conn, result); +} + +void _sasl_canonuser_free() +{ + canonuser_plug_list_t *ptr, *ptr_next; + + for(ptr = canonuser_head; ptr; ptr = ptr_next) { + ptr_next = ptr->next; + if(ptr->plug->canon_user_free) + ptr->plug->canon_user_free(ptr->plug->glob_context, + sasl_global_utils); + sasl_FREE(ptr); + } + + canonuser_head = NULL; +} + +int sasl_canonuser_add_plugin(const char *plugname, + sasl_canonuser_init_t *canonuserfunc) +{ + int result, out_version; + canonuser_plug_list_t *new_item; + sasl_canonuser_plug_t *plug; + + if(!plugname || strlen(plugname) > (PATH_MAX - 1)) { + sasl_seterror(NULL, 0, + "bad plugname passed to sasl_canonuser_add_plugin\n"); + return SASL_BADPARAM; + } + + result = canonuserfunc(sasl_global_utils, SASL_CANONUSER_PLUG_VERSION, + &out_version, &plug, plugname); + + if(result != SASL_OK) { + _sasl_log(NULL, SASL_LOG_ERR, "%s_canonuser_plug_init() failed in sasl_canonuser_add_plugin(): %z\n", + plugname, result); + return result; + } + + if(!plug->canon_user_server && !plug->canon_user_client) { + /* We need at least one of these implemented */ + _sasl_log(NULL, SASL_LOG_ERR, + "canonuser plugin '%s' without either client or server side", plugname); + return SASL_BADPROT; + } + + new_item = sasl_ALLOC(sizeof(canonuser_plug_list_t)); + if(!new_item) return SASL_NOMEM; + + strncpy(new_item->name, plugname, PATH_MAX); + + new_item->plug = plug; + new_item->next = canonuser_head; + canonuser_head = new_item; + + return SASL_OK; +} + +#ifdef MIN +#undef MIN +#endif +#define MIN(a,b) (((a) < (b))? (a):(b)) + +static int _canonuser_internal(const sasl_utils_t *utils, + const char *user, unsigned ulen, + unsigned flags __attribute__((unused)), + char *out_user, + unsigned out_umax, unsigned *out_ulen) +{ + unsigned i; + char *in_buf, *userin; + const char *begin_u; + unsigned u_apprealm = 0; + sasl_server_conn_t *sconn = NULL; + + if(!utils || !user) return SASL_BADPARAM; + + in_buf = sasl_ALLOC((ulen + 2) * sizeof(char)); + if(!in_buf) return SASL_NOMEM; + + userin = in_buf; + + memcpy(userin, user, ulen); + userin[ulen] = '\0'; + + /* Strip User ID */ + for(i=0;isspace((int)userin[i]) && i0) ulen -= i; + + for(;ulen > 0 && isspace((int)begin_u[ulen-1]); ulen--); + if(begin_u == &(userin[ulen])) { + sasl_FREE(in_buf); + utils->seterror(utils->conn, 0, "All-whitespace username."); + return SASL_FAIL; + } + + if(utils->conn && utils->conn->type == SASL_CONN_SERVER) + sconn = (sasl_server_conn_t *)utils->conn; + + /* Need to append realm if necessary (see sasl.h) */ + if(sconn && sconn->user_realm && !strchr(user, '@')) { + u_apprealm = (unsigned) strlen(sconn->user_realm) + 1; + } + + /* Now Copy */ + memcpy(out_user, begin_u, MIN(ulen, out_umax)); + if(sconn && u_apprealm) { + if(ulen >= out_umax) return SASL_BUFOVER; + out_user[ulen] = '@'; + memcpy(&(out_user[ulen+1]), sconn->user_realm, + MIN(u_apprealm-1, out_umax-ulen-1)); + } + out_user[MIN(ulen + u_apprealm,out_umax)] = '\0'; + + if(ulen + u_apprealm > out_umax) return SASL_BUFOVER; + + if(out_ulen) *out_ulen = MIN(ulen + u_apprealm,out_umax); + + sasl_FREE(in_buf); + return SASL_OK; +} + +static int _cu_internal_server(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *user, unsigned ulen, + unsigned flags, + char *out_user, + unsigned out_umax, unsigned *out_ulen) +{ + return _canonuser_internal(sparams->utils, + user, ulen, + flags, out_user, out_umax, out_ulen); +} + +static int _cu_internal_client(void *glob_context __attribute__((unused)), + sasl_client_params_t *cparams, + const char *user, unsigned ulen, + unsigned flags, + char *out_user, + unsigned out_umax, unsigned *out_ulen) +{ + return _canonuser_internal(cparams->utils, + user, ulen, + flags, out_user, out_umax, out_ulen); +} + +static sasl_canonuser_plug_t canonuser_internal_plugin = { + 0, /* features */ + 0, /* spare */ + NULL, /* glob_context */ + "INTERNAL", /* name */ + NULL, /* canon_user_free */ + _cu_internal_server, + _cu_internal_client, + NULL, + NULL, + NULL +}; + +int internal_canonuser_init(const sasl_utils_t *utils __attribute__((unused)), + int max_version, + int *out_version, + sasl_canonuser_plug_t **plug, + const char *plugname __attribute__((unused))) +{ + if(!out_version || !plug) return SASL_BADPARAM; + + if(max_version < SASL_CANONUSER_PLUG_VERSION) return SASL_BADVERS; + + *out_version = SASL_CANONUSER_PLUG_VERSION; + + *plug = &canonuser_internal_plugin; + + return SASL_OK; +} diff --git a/libs/cyrussasl/lib/checkpw.c b/libs/cyrussasl/lib/checkpw.c new file mode 100644 index 00000000..d371f3f2 --- /dev/null +++ b/libs/cyrussasl/lib/checkpw.c @@ -0,0 +1,1097 @@ +/* SASL server API implementation + * Rob Siemborski + * Tim Martin + * $Id: checkpw.c,v 1.79 2009/05/08 00:43:44 murch Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +/* checkpw stuff */ + +#include +#include "sasl.h" +#include "saslutil.h" +#include "saslplug.h" +#include "saslint.h" + +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#ifdef USE_DOORS +#include +#include +#endif + +#include + +#ifndef WIN32 +#include +#include +#include +#include +#else +#include +#endif + +#include +#include +#include + +#ifdef HAVE_PWD_H +#include +#endif /* HAVE_PWD_H */ +#ifdef HAVE_SHADOW_H +#include +#endif /* HAVE_SHADOW_H */ + +#if defined(HAVE_PWCHECK) || defined(HAVE_SASLAUTHD) || defined(HAVE_AUTHDAEMON) +# include +# include +# include +# include +# ifdef HAVE_UNISTD_H +# include +# endif +#endif + + +/* we store the following secret to check plaintext passwords: + * + * \0 + * + * where = MD5(, "sasldb", ) + */ +static int _sasl_make_plain_secret(const char *salt, + const char *passwd, size_t passlen, + sasl_secret_t **secret) +{ + MD5_CTX ctx; + unsigned sec_len = 16 + 1 + 16; /* salt + "\0" + hash */ + + *secret = (sasl_secret_t *) sasl_ALLOC(sizeof(sasl_secret_t) + + sec_len * sizeof(char)); + if (*secret == NULL) { + return SASL_NOMEM; + } + + _sasl_MD5Init(&ctx); + _sasl_MD5Update(&ctx, salt, 16); + _sasl_MD5Update(&ctx, "sasldb", 6); + _sasl_MD5Update(&ctx, passwd, (unsigned int) passlen); + memcpy((*secret)->data, salt, 16); + (*secret)->data[16] = '\0'; + _sasl_MD5Final((*secret)->data + 17, &ctx); + (*secret)->len = sec_len; + + return SASL_OK; +} + +/* verify user password using auxprop plugins + */ +static int auxprop_verify_password(sasl_conn_t *conn, + const char *userstr, + const char *passwd, + const char *service __attribute__((unused)), + const char *user_realm __attribute__((unused))) +{ + int ret = SASL_FAIL; + int result = SASL_OK; + sasl_server_conn_t *sconn = (sasl_server_conn_t *)conn; + const char *password_request[] = { SASL_AUX_PASSWORD, + "*cmusaslsecretPLAIN", + NULL }; + struct propval auxprop_values[3]; + + if (!conn || !userstr) + return SASL_BADPARAM; + + /* We need to clear any previous results and re-canonify to + * ensure correctness */ + + prop_clear (sconn->sparams->propctx, 0); + + /* ensure its requested */ + result = prop_request(sconn->sparams->propctx, password_request); + + if(result != SASL_OK) return result; + + result = _sasl_canon_user_lookup (conn, + userstr, + 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, + &(conn->oparams)); + if(result != SASL_OK) return result; + + result = prop_getnames(sconn->sparams->propctx, password_request, + auxprop_values); + if (result < 0) { + return result; + } + + /* Verify that the returned s are correct. + But we defer checking for NULL values till after we verify + that a passwd is specified. */ + if (!auxprop_values[0].name && !auxprop_values[1].name) { + return SASL_NOUSER; + } + + /* It is possible for us to get useful information out of just + * the lookup, so we won't check that we have a password until now */ + if(!passwd) { + ret = SASL_BADPARAM; + goto done; + } + + if ((!auxprop_values[0].values || !auxprop_values[0].values[0]) + && (!auxprop_values[1].values || !auxprop_values[1].values[0])) { + return SASL_NOUSER; + } + + /* At the point this has been called, the username has been canonified + * and we've done the auxprop lookup. This should be easy. */ + if(auxprop_values[0].name + && auxprop_values[0].values + && auxprop_values[0].values[0] + && !strcmp(auxprop_values[0].values[0], passwd)) { + /* We have a plaintext version and it matched! */ + return SASL_OK; + } else if(auxprop_values[1].name + && auxprop_values[1].values + && auxprop_values[1].values[0]) { + const char *db_secret = auxprop_values[1].values[0]; + sasl_secret_t *construct; + + ret = _sasl_make_plain_secret(db_secret, passwd, + strlen(passwd), + &construct); + if (ret != SASL_OK) { + goto done; + } + + if (!memcmp(db_secret, construct->data, construct->len)) { + /* password verified! */ + ret = SASL_OK; + } else { + /* passwords do not match */ + ret = SASL_BADAUTH; + } + + sasl_FREE(construct); + } else { + /* passwords do not match */ + ret = SASL_BADAUTH; + } + + /* erase the plaintext password */ + sconn->sparams->utils->prop_erase(sconn->sparams->propctx, + password_request[0]); + + done: + /* We're not going to erase the property here because other people + * may want it */ + return ret; +} + +/* Verify user password using auxprop plugins. Allow verification against a hashed password, + * or non-retrievable password. Don't use cmusaslsecretPLAIN attribute. + * + * This function is similar to auxprop_verify_password(). + */ +static int auxprop_verify_password_hashed(sasl_conn_t *conn, + const char *userstr, + const char *passwd, + const char *service __attribute__((unused)), + const char *user_realm __attribute__((unused))) +{ + int ret = SASL_FAIL; + int result = SASL_OK; + sasl_server_conn_t *sconn = (sasl_server_conn_t *)conn; + const char *password_request[] = { SASL_AUX_PASSWORD, + NULL }; + struct propval auxprop_values[2]; + unsigned extra_cu_flags = 0; + + if (!conn || !userstr) + return SASL_BADPARAM; + + /* We need to clear any previous results and re-canonify to + * ensure correctness */ + + prop_clear(sconn->sparams->propctx, 0); + + /* ensure its requested */ + result = prop_request(sconn->sparams->propctx, password_request); + + if (result != SASL_OK) return result; + + /* We need to pass "password" down to the auxprop_lookup */ + /* NB: We don't support binary passwords */ + if (passwd != NULL) { + prop_set (sconn->sparams->propctx, + SASL_AUX_PASSWORD, + passwd, + -1); + extra_cu_flags = SASL_CU_VERIFY_AGAINST_HASH; + } + + result = _sasl_canon_user_lookup (conn, + userstr, + 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID | extra_cu_flags, + &(conn->oparams)); + + if (result != SASL_OK) return result; + + result = prop_getnames(sconn->sparams->propctx, password_request, + auxprop_values); + if (result < 0) { + return result; + } + + /* Verify that the returned s are correct. + But we defer checking for NULL values till after we verify + that a passwd is specified. */ + if (!auxprop_values[0].name && !auxprop_values[1].name) { + return SASL_NOUSER; + } + + /* It is possible for us to get useful information out of just + * the lookup, so we won't check that we have a password until now */ + if (!passwd) { + ret = SASL_BADPARAM; + goto done; + } + + if ((!auxprop_values[0].values || !auxprop_values[0].values[0])) { + return SASL_NOUSER; + } + + /* At the point this has been called, the username has been canonified + * and we've done the auxprop lookup. This should be easy. */ + + /* NB: Note that if auxprop_lookup failed to verify the password, + then the userPassword property value would be NULL */ + if (auxprop_values[0].name + && auxprop_values[0].values + && auxprop_values[0].values[0] + && !strcmp(auxprop_values[0].values[0], passwd)) { + /* We have a plaintext version and it matched! */ + return SASL_OK; + } else { + /* passwords do not match */ + ret = SASL_BADAUTH; + } + + done: + /* We're not going to erase the property here because other people + * may want it */ + return ret; +} + +#ifdef DO_SASL_CHECKAPOP +int _sasl_auxprop_verify_apop(sasl_conn_t *conn, + const char *userstr, + const char *challenge, + const char *response, + const char *user_realm __attribute__((unused))) +{ + int ret = SASL_BADAUTH; + char *userid = NULL; + char *realm = NULL; + unsigned char digest[16]; + char digeststr[33]; + const char *password_request[] = { SASL_AUX_PASSWORD, NULL }; + struct propval auxprop_values[2]; + sasl_server_conn_t *sconn = (sasl_server_conn_t *)conn; + MD5_CTX ctx; + int i; + + if (!conn || !userstr || !challenge || !response) + PARAMERROR(conn) + + /* We've done the auxprop lookup already (in our caller) */ + /* sadly, APOP has no provision for storing secrets */ + ret = prop_getnames(sconn->sparams->propctx, password_request, + auxprop_values); + if(ret < 0) { + sasl_seterror(conn, 0, "could not perform password lookup"); + goto done; + } + + if(!auxprop_values[0].name || + !auxprop_values[0].values || + !auxprop_values[0].values[0]) { + sasl_seterror(conn, 0, "could not find password"); + ret = SASL_NOUSER; + goto done; + } + + _sasl_MD5Init(&ctx); + _sasl_MD5Update(&ctx, challenge, strlen(challenge)); + _sasl_MD5Update(&ctx, auxprop_values[0].values[0], + strlen(auxprop_values[0].values[0])); + _sasl_MD5Final(digest, &ctx); + + /* erase the plaintext password */ + sconn->sparams->utils->prop_erase(sconn->sparams->propctx, + password_request[0]); + + /* convert digest from binary to ASCII hex */ + for (i = 0; i < 16; i++) + sprintf(digeststr + (i*2), "%02x", digest[i]); + + if (!strncasecmp(digeststr, response, 32)) { + /* password verified! */ + ret = SASL_OK; + } else { + /* passwords do not match */ + ret = SASL_BADAUTH; + } + + done: + if (ret == SASL_BADAUTH) sasl_seterror(conn, SASL_NOLOG, + "login incorrect"); + if (userid) sasl_FREE(userid); + if (realm) sasl_FREE(realm); + + return ret; +} +#endif /* DO_SASL_CHECKAPOP */ + +#if defined(HAVE_PWCHECK) || defined(HAVE_SASLAUTHD) || defined(HAVE_AUTHDAEMON) +/* + * Wait for file descriptor to be writable. Return with error if timeout. + */ +static int write_wait(int fd, unsigned delta) +{ + fd_set wfds; + fd_set efds; + struct timeval tv; + + /* + * Wait for file descriptor fd to be writable. Retry on + * interruptions. Return with error upon timeout. + */ + while (1) { + FD_ZERO(&wfds); + FD_ZERO(&efds); + FD_SET(fd, &wfds); + FD_SET(fd, &efds); + tv.tv_sec = (long) delta; + tv.tv_usec = 0; + switch(select(fd + 1, 0, &wfds, &efds, &tv)) { + case 0: + /* Timeout. */ + errno = ETIMEDOUT; + return -1; + case +1: + if (FD_ISSET(fd, &wfds)) { + /* Success, file descriptor is writable. */ + return 0; + } + return -1; + case -1: + if (errno == EINTR || errno == EAGAIN) + continue; + default: + /* Error catch-all. */ + return -1; + } + } + /* Not reached. */ + return -1; +} + +/* + * Keep calling the writev() system call with 'fd', 'iov', and 'iovcnt' + * until all the data is written out or an error/timeout occurs. + */ +static int retry_writev(int fd, struct iovec *iov, int iovcnt, unsigned delta) +{ + int n; + int i; + int written = 0; + static int iov_max = +#ifdef MAXIOV + MAXIOV +#else +#ifdef IOV_MAX + IOV_MAX +#else + 8192 +#endif +#endif + ; + + for (;;) { + while (iovcnt && iov[0].iov_len == 0) { + iov++; + iovcnt--; + } + + if (!iovcnt) return written; + + if (delta > 0) { + if (write_wait(fd, delta)) + return -1; + } + n = writev(fd, iov, iovcnt > iov_max ? iov_max : iovcnt); + if (n == -1) { + if (errno == EINVAL && iov_max > 10) { + iov_max /= 2; + continue; + } + if (errno == EINTR) continue; + return -1; + } + + written += n; + + for (i = 0; i < iovcnt; i++) { + if ((int) iov[i].iov_len > n) { + iov[i].iov_base = (char *)iov[i].iov_base + n; + iov[i].iov_len -= n; + break; + } + n -= iov[i].iov_len; + iov[i].iov_len = 0; + } + + if (i == iovcnt) return written; + } +} + +#endif + +#ifdef HAVE_PWCHECK +/* pwcheck daemon-authenticated login */ +static int pwcheck_verify_password(sasl_conn_t *conn, + const char *userid, + const char *passwd, + const char *service __attribute__((unused)), + const char *user_realm + __attribute__((unused))) +{ + int s; + struct sockaddr_un srvaddr; + int r; + struct iovec iov[10]; + static char response[1024]; + unsigned start, n; + char pwpath[1024]; + + if (strlen(PWCHECKDIR)+8+1 > sizeof(pwpath)) return SASL_FAIL; + + strcpy(pwpath, PWCHECKDIR); + strcat(pwpath, "/pwcheck"); + + s = socket(AF_UNIX, SOCK_STREAM, 0); + if (s == -1) return errno; + + memset((char *)&srvaddr, 0, sizeof(srvaddr)); + srvaddr.sun_family = AF_UNIX; + strncpy(srvaddr.sun_path, pwpath, sizeof(srvaddr.sun_path)); + r = connect(s, (struct sockaddr *)&srvaddr, sizeof(srvaddr)); + if (r == -1) { + sasl_seterror(conn,0,"cannot connect to pwcheck server"); + return SASL_FAIL; + } + + iov[0].iov_base = (char *)userid; + iov[0].iov_len = strlen(userid)+1; + iov[1].iov_base = (char *)passwd; + iov[1].iov_len = strlen(passwd)+1; + + retry_writev(s, iov, 2, 0); + + start = 0; + while (start < sizeof(response) - 1) { + n = read(s, response+start, sizeof(response) - 1 - start); + if (n < 1) break; + start += n; + } + + close(s); + + if (start > 1 && !strncmp(response, "OK", 2)) { + return SASL_OK; + } + + response[start] = '\0'; + sasl_seterror(conn,0,response); + return SASL_BADAUTH; +} + +#endif + +#if defined(HAVE_SASLAUTHD) || defined(HAVE_AUTHDAEMON) +static int read_wait(int fd, unsigned delta) +{ + fd_set rfds; + fd_set efds; + struct timeval tv; + /* + * Wait for file descriptor fd to be readable. Retry on + * interruptions. Return with error upon timeout. + */ + while (1) { + FD_ZERO(&rfds); + FD_ZERO(&efds); + FD_SET(fd, &rfds); + FD_SET(fd, &efds); + tv.tv_sec = (long) delta; + tv.tv_usec = 0; + switch(select(fd + 1, &rfds, 0, &efds, &tv)) { + case 0: + /* Timeout. */ + errno = ETIMEDOUT; + return -1; + case +1: + if (FD_ISSET(fd, &rfds)) { + /* Success, file descriptor is readable. */ + return 0; + } + return -1; + case -1: + if (errno == EINTR || errno == EAGAIN) + continue; + default: + /* Error catch-all. */ + return -1; + } + } + /* Not reached. */ + return -1; +} + +/* + * Keep calling the read() system call until all the data is read in, + * timeout, EOF, or an error occurs. This function returns the number + * of useful bytes, or -1 if timeout/error. + */ +static int retry_read(int fd, void *buf0, unsigned nbyte, unsigned delta) +{ + int nr; + unsigned nleft = nbyte; + char *buf = (char*) buf0; + + while (nleft >= 1) { + if (delta > 0) { + if (read_wait(fd, delta)) + return -1; + } + nr = read(fd, buf, nleft); + if (nr < 0) { + if (errno == EINTR || errno == EAGAIN) + continue; + return -1; + } else if (nr == 0) { + break; + } + buf += nr; + nleft -= nr; + } + return nbyte - nleft; +} +#endif + +#ifdef HAVE_SASLAUTHD +/* saslauthd-authenticated login */ +static int saslauthd_verify_password(sasl_conn_t *conn, + const char *userid, + const char *passwd, + const char *service, + const char *user_realm) +{ + char response[1024]; + char query[8192]; + char *query_end = query; + int s; + struct sockaddr_un srvaddr; + sasl_getopt_t *getopt; + void *context; + char pwpath[sizeof(srvaddr.sun_path)]; + const char *p = NULL; + char *freeme = NULL; +#ifdef USE_DOORS + door_arg_t arg; +#endif + + /* check to see if the user configured a rundir */ + if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context) == SASL_OK) { + getopt(context, NULL, "saslauthd_path", &p, NULL); + } + if (p) { + strncpy(pwpath, p, sizeof(pwpath)); + } else { + if (strlen(PATH_SASLAUTHD_RUNDIR) + 4 + 1 > sizeof(pwpath)) + return SASL_FAIL; + + strcpy(pwpath, PATH_SASLAUTHD_RUNDIR); + strcat(pwpath, "/mux"); + } + + /* Split out username/realm if necessary */ + if(strrchr(userid,'@') != NULL) { + char *rtmp; + + if(_sasl_strdup(userid, &freeme, NULL) != SASL_OK) + goto fail; + + userid = freeme; + rtmp = strrchr(userid,'@'); + *rtmp = '\0'; + user_realm = rtmp + 1; + } + + /* + * build request of the form: + * + * count authid count password count service count realm + */ + { + unsigned short max_len, req_len, u_len, p_len, s_len, r_len; + + max_len = (unsigned short) sizeof(query); + + /* prevent buffer overflow */ + if ((strlen(userid) > USHRT_MAX) || + (strlen(passwd) > USHRT_MAX) || + (strlen(service) > USHRT_MAX) || + (user_realm && (strlen(user_realm) > USHRT_MAX))) { + goto toobig; + } + + u_len = (strlen(userid)); + p_len = (strlen(passwd)); + s_len = (strlen(service)); + r_len = ((user_realm ? strlen(user_realm) : 0)); + + /* prevent buffer overflow */ + req_len = 30; + if (max_len - req_len < u_len) goto toobig; + req_len += u_len; + if (max_len - req_len < p_len) goto toobig; + req_len += p_len; + if (max_len - req_len < s_len) goto toobig; + req_len += s_len; + if (max_len - req_len < r_len) goto toobig; + + u_len = htons(u_len); + p_len = htons(p_len); + s_len = htons(s_len); + r_len = htons(r_len); + + memcpy(query_end, &u_len, sizeof(unsigned short)); + query_end += sizeof(unsigned short); + while (*userid) *query_end++ = *userid++; + + memcpy(query_end, &p_len, sizeof(unsigned short)); + query_end += sizeof(unsigned short); + while (*passwd) *query_end++ = *passwd++; + + memcpy(query_end, &s_len, sizeof(unsigned short)); + query_end += sizeof(unsigned short); + while (*service) *query_end++ = *service++; + + memcpy(query_end, &r_len, sizeof(unsigned short)); + query_end += sizeof(unsigned short); + if (user_realm) while (*user_realm) *query_end++ = *user_realm++; + } + +#ifdef USE_DOORS + s = open(pwpath, O_RDONLY); + if (s < 0) { + sasl_seterror(conn, 0, "cannot open door to saslauthd server: %m", errno); + goto fail; + } + + arg.data_ptr = query; + arg.data_size = query_end - query; + arg.desc_ptr = NULL; + arg.desc_num = 0; + arg.rbuf = response; + arg.rsize = sizeof(response); + + if (door_call(s, &arg) < 0) { + /* Parameters are undefined */ + close(s); + sasl_seterror(conn, 0, "door call to saslauthd server failed: %m", errno); + goto fail; + } + + if (arg.data_ptr != response || arg.data_size >= sizeof(response)) { + /* oh damn, we got back a really long response */ + munmap(arg.rbuf, arg.rsize); + close(s); + sasl_seterror(conn, 0, "saslauthd sent an overly long response"); + goto fail; + } + response[arg.data_size] = '\0'; + + close(s); +#else + /* unix sockets */ + + s = socket(AF_UNIX, SOCK_STREAM, 0); + if (s == -1) { + sasl_seterror(conn, 0, "cannot create socket for saslauthd: %m", errno); + goto fail; + } + + memset((char *)&srvaddr, 0, sizeof(srvaddr)); + srvaddr.sun_family = AF_UNIX; + strncpy(srvaddr.sun_path, pwpath, sizeof(srvaddr.sun_path)); + + { + int r = connect(s, (struct sockaddr *) &srvaddr, sizeof(srvaddr)); + if (r == -1) { + close(s); + sasl_seterror(conn, 0, "cannot connect to saslauthd server: %m", errno); + goto fail; + } + } + + { + struct iovec iov[8]; + + iov[0].iov_len = query_end - query; + iov[0].iov_base = query; + + if (retry_writev(s, iov, 1, 0) == -1) { + close(s); + sasl_seterror(conn, 0, "write failed"); + goto fail; + } + } + + { + unsigned short count = 0; + + /* + * read response of the form: + * + * count result + */ + if (retry_read(s, &count, sizeof(count), 0) < (int) sizeof(count)) { + sasl_seterror(conn, 0, "size read failed"); + goto fail; + } + + count = ntohs(count); + if (count < 2) { /* MUST have at least "OK" or "NO" */ + close(s); + sasl_seterror(conn, 0, "bad response from saslauthd"); + goto fail; + } + + count = (int)sizeof(response) <= count ? sizeof(response) - 1 : count; + if (retry_read(s, response, count, 0) < count) { + close(s); + sasl_seterror(conn, 0, "read failed"); + goto fail; + } + response[count] = '\0'; + } + + close(s); +#endif /* USE_DOORS */ + + if(freeme) free(freeme); + + if (!strncmp(response, "OK", 2)) { + return SASL_OK; + } + + sasl_seterror(conn, SASL_NOLOG, "authentication failed"); + return SASL_BADAUTH; + + toobig: + /* request just too damn big */ + sasl_seterror(conn, 0, "saslauthd request too large"); + + fail: + if (freeme) free(freeme); + return SASL_FAIL; +} + +#endif + +#ifdef HAVE_AUTHDAEMON +/* + * Preliminary support for Courier's authdaemond. + */ +#define AUTHDAEMON_IO_TIMEOUT 30 + +static int authdaemon_blocking(int fd, int block) +{ + int f, r; + + /* Get the fd's blocking bit. */ + f = fcntl(fd, F_GETFL, 0); + if (f == -1) + return -1; + + /* Adjust the bitmap accordingly. */ +#ifndef O_NONBLOCK +#define NB_BITMASK FNDELAY +#else +#define NB_BITMASK O_NONBLOCK +#endif + if (block) + f &= ~NB_BITMASK; + else + f |= NB_BITMASK; +#undef NB_BITMASK + + /* Adjust the fd's blocking bit. */ + r = fcntl(fd, F_SETFL, f); + if (r) + return -1; + + /* Success. */ + return 0; +} + +static int authdaemon_connect(sasl_conn_t *conn, const char *path) +{ + int r, s = -1; + struct sockaddr_un srvaddr; + + if (strlen(path) >= sizeof(srvaddr.sun_path)) { + sasl_seterror(conn, 0, "unix socket path too large", errno); + goto fail; + } + + s = socket(AF_UNIX, SOCK_STREAM, 0); + if (s == -1) { + sasl_seterror(conn, 0, "cannot create socket for connection to Courier authdaemond: %m", errno); + goto fail; + } + + memset((char *)&srvaddr, 0, sizeof(srvaddr)); + srvaddr.sun_family = AF_UNIX; + strncpy(srvaddr.sun_path, path, sizeof(srvaddr.sun_path) - 1); + + /* Use nonblocking unix socket connect(2). */ + if (authdaemon_blocking(s, 0)) { + sasl_seterror(conn, 0, "cannot set nonblocking bit: %m", errno); + goto fail; + } + + r = connect(s, (struct sockaddr *) &srvaddr, sizeof(srvaddr)); + if (r == -1) { + sasl_seterror(conn, 0, "cannot connect to Courier authdaemond: %m", errno); + goto fail; + } + + if (authdaemon_blocking(s, 1)) { + sasl_seterror(conn, 0, "cannot clear nonblocking bit: %m", errno); + goto fail; + } + + return s; +fail: + if (s >= 0) + close(s); + return -1; +} + +static char *authdaemon_build_query(const char *service, + const char *authtype, + const char *user, + const char *passwd) +{ + int sz; + int l = strlen(service) + + 1 + + strlen(authtype) + + 1 + + strlen(user) + + 1 + + strlen(passwd) + + 1; + char *buf, n[5]; + if (snprintf(n, sizeof(n), "%d", l) >= (int)sizeof(n)) + return NULL; + sz = strlen(n) + l + 20; + if (!(buf = sasl_ALLOC(sz))) + return NULL; + snprintf(buf, + sz, + "AUTH %s\n%s\n%s\n%s\n%s\n\n", + n, + service, + authtype, + user, + passwd); + return buf; +} + +static int authdaemon_read(int fd, void *buf0, unsigned sz) +{ + int nr; + char *buf = (char*) buf0; + if (sz <= 1) + return -1; + if ((nr = retry_read(fd, buf0, sz - 1, AUTHDAEMON_IO_TIMEOUT)) < 0) + return -1; + /* We need a null-terminated buffer. */ + buf[nr] = 0; + /* Check for overflow condition. */ + return nr + 1 < (int)sz ? 0 : -1; +} + +static int authdaemon_write(int fd, void *buf0, unsigned sz) +{ + int nw; + struct iovec io; + io.iov_len = sz; + io.iov_base = buf0; + nw = retry_writev(fd, &io, 1, AUTHDAEMON_IO_TIMEOUT); + return nw == (int)sz ? 0 : -1; +} + +static int authdaemon_talk(sasl_conn_t *conn, int sock, char *authreq) +{ + char *str; + char buf[8192]; + + if (authdaemon_write(sock, authreq, strlen(authreq))) + goto _err_out; + if (authdaemon_read(sock, buf, sizeof(buf))) + goto _err_out; + for (str = buf; *str; ) { + char *sub; + + for (sub = str; *str; ++str) { + if (*str == '\n') { + *str++ = 0; + break; + } + } + if (strcmp(sub, ".") == 0) { + /* success */ + return SASL_OK; + } + if (strcmp(sub, "FAIL") == 0) { + /* passwords do not match */ + sasl_seterror(conn, SASL_NOLOG, "authentication failed"); + return SASL_BADAUTH; + } + } +_err_out: + /* catchall: authentication error */ + sasl_seterror(conn, 0, "could not verify password"); + return SASL_FAIL; +} + +static int authdaemon_verify_password(sasl_conn_t *conn, + const char *userid, + const char *passwd, + const char *service, + const char *user_realm __attribute__((unused))) +{ + const char *p = NULL; + sasl_getopt_t *getopt; + void *context; + int result = SASL_FAIL; + char *query = NULL; + int sock = -1; + + /* check to see if the user configured a rundir */ + if (_sasl_getcallback(conn, SASL_CB_GETOPT, &getopt, &context) == SASL_OK) { + getopt(context, NULL, "authdaemond_path", &p, NULL); + } + if (!p) { + /* + * XXX should we peek at Courier's build-time config ? + */ + p = PATH_AUTHDAEMON_SOCKET; + } + + if ((sock = authdaemon_connect(conn, p)) < 0) + goto out; + if (!(query = authdaemon_build_query(service, "login", userid, passwd))) + goto out; + result = authdaemon_talk(conn, sock, query); +out: + if (sock >= 0) + close(sock), sock = -1; + if (query) + sasl_FREE(query), query = 0; + return result; +} +#endif + +#ifdef HAVE_ALWAYSTRUE +static int always_true(sasl_conn_t *conn, + const char *userstr, + const char *passwd __attribute__((unused)), + const char *service __attribute__((unused)), + const char *user_realm __attribute__((unused))) +{ + _sasl_log(conn, SASL_LOG_WARN, "AlwaysTrue Password Verifier Verified: %s", + userstr); + return SASL_OK; +} +#endif + +struct sasl_verify_password_s _sasl_verify_password[] = { + { "auxprop", &auxprop_verify_password }, + { "auxprop-hashed", &auxprop_verify_password_hashed }, +#ifdef HAVE_PWCHECK + { "pwcheck", &pwcheck_verify_password }, +#endif +#ifdef HAVE_SASLAUTHD + { "saslauthd", &saslauthd_verify_password }, +#endif +#ifdef HAVE_AUTHDAEMON + { "authdaemond", &authdaemon_verify_password }, +#endif +#ifdef HAVE_ALWAYSTRUE + { "alwaystrue", &always_true }, +#endif + { NULL, NULL } +}; diff --git a/libs/cyrussasl/lib/client.c b/libs/cyrussasl/lib/client.c new file mode 100644 index 00000000..62dfb0bf --- /dev/null +++ b/libs/cyrussasl/lib/client.c @@ -0,0 +1,1349 @@ +/* SASL client API implementation + * Rob Siemborski + * Tim Martin + * $Id: client.c,v 1.86 2011/09/01 14:12:53 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif + +/* SASL Headers */ +#include "sasl.h" +#include "saslplug.h" +#include "saslutil.h" +#include "saslint.h" + +static cmech_list_t *cmechlist; /* global var which holds the list */ +static sasl_global_callbacks_t global_callbacks_client; +static int _sasl_client_active = 0; + +static int init_mechlist() +{ + cmechlist->utils=_sasl_alloc_utils(NULL, &global_callbacks_client); + if (cmechlist->utils==NULL) + return SASL_NOMEM; + + cmechlist->mech_list=NULL; + cmechlist->mech_length=0; + + return SASL_OK; +} + +int sasl_client_done(void) +{ + int result = SASL_CONTINUE; + + if (_sasl_server_cleanup_hook == NULL && _sasl_client_cleanup_hook == NULL) { + return SASL_NOTINIT; + } + + if (_sasl_client_cleanup_hook) { + result = _sasl_client_cleanup_hook(); + + if (result == SASL_OK) { + _sasl_client_idle_hook = NULL; + _sasl_client_cleanup_hook = NULL; + } else { + return result; + } + } + + if (_sasl_server_cleanup_hook || _sasl_client_cleanup_hook) { + return result; + } + + sasl_common_done(); + + return SASL_OK; +} + +static int client_done(void) { + cmechanism_t *cm; + cmechanism_t *cprevm; + + if (!_sasl_client_active) { + return SASL_NOTINIT; + } else { + _sasl_client_active--; + } + + if(_sasl_client_active) { + /* Don't de-init yet! Our refcount is nonzero. */ + return SASL_CONTINUE; + } + + cm = cmechlist->mech_list; /* m point to beginning of the list */ + while (cm != NULL) { + cprevm = cm; + cm = cm->next; + + if (cprevm->m.plug->mech_free) { + cprevm->m.plug->mech_free(cprevm->m.plug->glob_context, + cmechlist->utils); + } + + sasl_FREE(cprevm->m.plugname); + sasl_FREE(cprevm); + } + _sasl_free_utils(&cmechlist->utils); + sasl_FREE(cmechlist); + + cmechlist = NULL; + + return SASL_OK; +} + +/* This is nearly identical to the version in server.c. + Keep in sync. */ +static int mech_compare(const sasl_client_plug_t *a, + const sasl_client_plug_t *b) +{ + unsigned sec_diff; + unsigned features_diff; + + /* XXX the following is fairly arbitrary, but its independent + of the order in which the plugins are loaded + */ + sec_diff = a->security_flags ^ b->security_flags; + if (sec_diff & a->security_flags & SASL_SEC_NOANONYMOUS) return 1; + if (sec_diff & b->security_flags & SASL_SEC_NOANONYMOUS) return -1; + if (sec_diff & a->security_flags & SASL_SEC_NOPLAINTEXT) return 1; + if (sec_diff & b->security_flags & SASL_SEC_NOPLAINTEXT) return -1; + if (sec_diff & a->security_flags & SASL_SEC_MUTUAL_AUTH) return 1; + if (sec_diff & b->security_flags & SASL_SEC_MUTUAL_AUTH) return -1; + if (sec_diff & a->security_flags & SASL_SEC_NOACTIVE) return 1; + if (sec_diff & b->security_flags & SASL_SEC_NOACTIVE) return -1; + if (sec_diff & a->security_flags & SASL_SEC_NODICTIONARY) return 1; + if (sec_diff & b->security_flags & SASL_SEC_NODICTIONARY) return -1; + if (sec_diff & a->security_flags & SASL_SEC_FORWARD_SECRECY) return 1; + if (sec_diff & b->security_flags & SASL_SEC_FORWARD_SECRECY) return -1; + + features_diff = a->features ^ b->features; + if (features_diff & a->features & SASL_FEAT_CHANNEL_BINDING) return 1; + if (features_diff & b->features & SASL_FEAT_CHANNEL_BINDING) return -1; + + if (a->max_ssf > b->max_ssf) return 1; + if (a->max_ssf < b->max_ssf) return -1; + + return 0; +} + +int sasl_client_add_plugin(const char *plugname, + sasl_client_plug_init_t *entry_point) +{ + int plugcount; + sasl_client_plug_t *pluglist; + cmechanism_t *mech, *mp; + int result; + int version; + int lupe; + + if (!plugname || !entry_point) return SASL_BADPARAM; + + result = entry_point(cmechlist->utils, + SASL_CLIENT_PLUG_VERSION, + &version, + &pluglist, + &plugcount); + + if (result != SASL_OK) + { + _sasl_log(NULL, SASL_LOG_WARN, + "sasl_client_add_plugin(): entry_point(): failed for plugname %s: %z", + plugname, result); + return result; + } + + if (version != SASL_CLIENT_PLUG_VERSION) + { + _sasl_log(NULL, SASL_LOG_WARN, + "version conflict in sasl_client_add_plugin for %s", plugname); + return SASL_BADVERS; + } + + for (lupe=0; lupe < plugcount; lupe++, pluglist++) + { + mech = sasl_ALLOC(sizeof(cmechanism_t)); + if (!mech) return SASL_NOMEM; + + mech->m.plug = pluglist; + if (_sasl_strdup(plugname, &mech->m.plugname, NULL) != SASL_OK) { + sasl_FREE(mech); + return SASL_NOMEM; + } + mech->m.version = version; + + /* sort mech_list by relative "strength" */ + mp = cmechlist->mech_list; + if (!mp || mech_compare(pluglist, mp->m.plug) >= 0) { + /* add mech to head of list */ + mech->next = cmechlist->mech_list; + cmechlist->mech_list = mech; + } else { + /* find where to insert mech into list */ + while (mp->next && + mech_compare(pluglist, mp->next->m.plug) <= 0) mp = mp->next; + mech->next = mp->next; + mp->next = mech; + } + + cmechlist->mech_length++; + } + + return SASL_OK; +} + +static int +client_idle(sasl_conn_t *conn) +{ + cmechanism_t *m; + if (! cmechlist) + return 0; + + for (m = cmechlist->mech_list; + m; + m = m->next) + if (m->m.plug->idle + && m->m.plug->idle(m->m.plug->glob_context, + conn, + conn ? ((sasl_client_conn_t *)conn)->cparams : NULL)) + return 1; + return 0; +} + +/* initialize the SASL client drivers + * callbacks -- base callbacks for all client connections + * returns: + * SASL_OK -- Success + * SASL_NOMEM -- Not enough memory + * SASL_BADVERS -- Mechanism version mismatch + * SASL_BADPARAM -- error in config file + * SASL_NOMECH -- No mechanisms available + * ... + */ + +int sasl_client_init(const sasl_callback_t *callbacks) +{ + int ret; + const add_plugin_list_t ep_list[] = { + { "sasl_client_plug_init", (add_plugin_t *)sasl_client_add_plugin }, + { "sasl_canonuser_init", (add_plugin_t *)sasl_canonuser_add_plugin }, + { NULL, NULL } + }; + + /* lock allocation type */ + _sasl_allocation_locked++; + + if(_sasl_client_active) { + /* We're already active, just increase our refcount */ + /* xxx do something with the callback structure? */ + _sasl_client_active++; + return SASL_OK; + } + + global_callbacks_client.callbacks = callbacks; + global_callbacks_client.appname = NULL; + + cmechlist=sasl_ALLOC(sizeof(cmech_list_t)); + if (cmechlist==NULL) return SASL_NOMEM; + + /* We need to call client_done if we fail now */ + _sasl_client_active = 1; + + /* load plugins */ + ret=init_mechlist(); + if (ret!=SASL_OK) { + client_done(); + return ret; + } + + sasl_client_add_plugin("EXTERNAL", &external_client_plug_init); + + ret = _sasl_common_init(&global_callbacks_client); + + if (ret == SASL_OK) + ret = _sasl_load_plugins(ep_list, + _sasl_find_getpath_callback(callbacks), + _sasl_find_verifyfile_callback(callbacks)); + + if (ret == SASL_OK) { + _sasl_client_cleanup_hook = &client_done; + _sasl_client_idle_hook = &client_idle; + + ret = _sasl_build_mechlist(); + } else { + client_done(); + } + + return ret; +} + +static void client_dispose(sasl_conn_t *pconn) +{ + sasl_client_conn_t *c_conn=(sasl_client_conn_t *) pconn; + + if (c_conn->mech && c_conn->mech->m.plug->mech_dispose) { + c_conn->mech->m.plug->mech_dispose(pconn->context, + c_conn->cparams->utils); + } + + pconn->context = NULL; + + if (c_conn->clientFQDN) + sasl_FREE(c_conn->clientFQDN); + + if (c_conn->cparams) { + _sasl_free_utils(&(c_conn->cparams->utils)); + sasl_FREE(c_conn->cparams); + } + + if (c_conn->mech_list != cmechlist->mech_list) { + /* free connection-specific mech_list */ + cmechanism_t *m, *prevm; + + m = c_conn->mech_list; /* m point to beginning of the list */ + + while (m) { + prevm = m; + m = m->next; + sasl_FREE(prevm); + } + } + + _sasl_conn_dispose(pconn); +} + +/* initialize a client exchange based on the specified mechanism + * service -- registered name of the service using SASL (e.g. "imap") + * serverFQDN -- the fully qualified domain name of the server + * iplocalport -- client IPv4/IPv6 domain literal string with port + * (if NULL, then mechanisms requiring IPaddr are disabled) + * ipremoteport -- server IPv4/IPv6 domain literal string with port + * (if NULL, then mechanisms requiring IPaddr are disabled) + * prompt_supp -- list of client interactions supported + * may also include sasl_getopt_t context & call + * NULL prompt_supp = user/pass via SASL_INTERACT only + * NULL proc = interaction supported via SASL_INTERACT + * secflags -- security flags (see above) + * in/out: + * pconn -- connection negotiation structure + * pointer to NULL => allocate new + * non-NULL => recycle storage and go for next available mech + * + * Returns: + * SASL_OK -- success + * SASL_NOMECH -- no mechanism meets requested properties + * SASL_NOMEM -- not enough memory + */ +int sasl_client_new(const char *service, + const char *serverFQDN, + const char *iplocalport, + const char *ipremoteport, + const sasl_callback_t *prompt_supp, + unsigned flags, + sasl_conn_t **pconn) +{ + int result; + char name[MAXHOSTNAMELEN]; + sasl_client_conn_t *conn; + sasl_utils_t *utils; + sasl_getopt_t *getopt; + void *context; + const char *mlist = NULL; + int plus = 0; + + if (_sasl_client_active == 0) return SASL_NOTINIT; + + /* Remember, serverFQDN, iplocalport and ipremoteport can be NULL and be valid! */ + if (!pconn || !service) + return SASL_BADPARAM; + + *pconn=sasl_ALLOC(sizeof(sasl_client_conn_t)); + if (*pconn==NULL) { + _sasl_log(NULL, SASL_LOG_ERR, + "Out of memory allocating connection context"); + return SASL_NOMEM; + } + memset(*pconn, 0, sizeof(sasl_client_conn_t)); + + (*pconn)->destroy_conn = &client_dispose; + + conn = (sasl_client_conn_t *)*pconn; + + conn->mech = NULL; + + conn->cparams=sasl_ALLOC(sizeof(sasl_client_params_t)); + if (conn->cparams==NULL) + MEMERROR(*pconn); + memset(conn->cparams,0,sizeof(sasl_client_params_t)); + + result = _sasl_conn_init(*pconn, service, flags, SASL_CONN_CLIENT, + &client_idle, serverFQDN, + iplocalport, ipremoteport, + prompt_supp, &global_callbacks_client); + if (result != SASL_OK) RETURN(*pconn, result); + + utils = _sasl_alloc_utils(*pconn, &global_callbacks_client); + if (utils == NULL) { + MEMERROR(*pconn); + } + + utils->conn= *pconn; + conn->cparams->utils = utils; + + if(_sasl_getcallback(*pconn, SASL_CB_GETOPT, (sasl_callback_ft *)&getopt, &context) == SASL_OK) { + getopt(context, NULL, "client_mech_list", &mlist, NULL); + } + + /* if we have a client_mech_list, create ordered list of + available mechanisms for this conn */ + if (mlist) { + const char *cp; + cmechanism_t *mptr, *tail = NULL; + cmechanism_t *new; + + while (*mlist) { + /* find end of current mech name */ + for (cp = mlist; *cp && !isspace((int) *cp); cp++); + + /* search for mech name in loaded plugins */ + for (mptr = cmechlist->mech_list; mptr; mptr = mptr->next) { + const sasl_client_plug_t *plug = mptr->m.plug; + + if (_sasl_is_equal_mech(mlist, plug->mech_name, (size_t) (cp - mlist), &plus)) { + /* found a match */ + break; + } + } + if (mptr) { + new = sasl_ALLOC(sizeof(cmechanism_t)); + if (!new) { + result = SASL_NOMEM; + goto failed_client_new; + } + memcpy(&new->m, &mptr->m, sizeof(client_sasl_mechanism_t)); + new->next = NULL; + + if (!conn->mech_list) { + conn->mech_list = new; + tail = conn->mech_list; + } else { + tail->next = new; + tail = new; + } + conn->mech_length++; + } + + /* find next mech name */ + mlist = cp; + while (*mlist && isspace((int) *mlist)) mlist++; + } + } else { + conn->mech_list = cmechlist->mech_list; + conn->mech_length = cmechlist->mech_length; + } + + if (conn->mech_list == NULL) { + sasl_seterror(*pconn, 0, "No worthy mechs found"); + result = SASL_NOMECH; + goto failed_client_new; + } + + /* Setup the non-lazy parts of cparams, the rest is done in + * sasl_client_start */ + conn->cparams->canon_user = &_sasl_canon_user_lookup; + conn->cparams->flags = flags; + conn->cparams->prompt_supp = (*pconn)->callbacks; + + /* get the clientFQDN (serverFQDN was set in _sasl_conn_init) */ + memset(name, 0, sizeof(name)); + if (get_fqhostname (name, MAXHOSTNAMELEN, 0) != 0) { + return (SASL_FAIL); + } + + result = _sasl_strdup(name, &conn->clientFQDN, NULL); + + if (result == SASL_OK) return SASL_OK; + +failed_client_new: + /* result isn't SASL_OK */ + _sasl_conn_dispose(*pconn); + sasl_FREE(*pconn); + *pconn = NULL; + _sasl_log(NULL, SASL_LOG_ERR, "Out of memory in sasl_client_new"); + return result; +} + +static int have_prompts(sasl_conn_t *conn, + const sasl_client_plug_t *mech) +{ + static const unsigned long default_prompts[] = { + SASL_CB_AUTHNAME, + SASL_CB_PASS, + SASL_CB_LIST_END + }; + + const unsigned long *prompt; + sasl_callback_ft pproc; + void *pcontext; + int result; + + for (prompt = (mech->required_prompts + ? mech->required_prompts : + default_prompts); + *prompt != SASL_CB_LIST_END; + prompt++) { + result = _sasl_getcallback(conn, *prompt, &pproc, &pcontext); + if (result != SASL_OK && result != SASL_INTERACT) + return 0; /* we don't have this required prompt */ + } + + return 1; /* we have all the prompts */ +} + +static int +_mech_plus_p(const char *mech, size_t len) +{ + return (len > 5 && strncasecmp(&mech[len - 5], "-PLUS", 5) == 0); +} + +/* + * Order PLUS mechanisms first. Returns NUL separated list of + * *count items. + */ +static int +_sasl_client_order_mechs(const sasl_utils_t *utils, + const char *mechs, + int has_cb_data, + char **ordered_mechs, + size_t *count, + int *server_can_cb) +{ + char *list, *listp; + size_t i, mechslen, start; + + *count = 0; + *server_can_cb = 0; + + if (mechs == NULL || mechs[0] == '\0') + return SASL_NOMECH; + + mechslen = strlen(mechs); + + listp = list = utils->malloc(mechslen + 1); + if (list == NULL) + return SASL_NOMEM; + + /* As per RFC 4422: + * SASL mechanism allowable characters are "AZ-_" + * separators can be any other characters and of any length + * even variable lengths between. + * + * But for convenience we accept lowercase ASCII. + * + * Apps should be encouraged to simply use space or comma space + * though + */ +#define ismechchar(c) (isalnum((c)) || (c) == '_' || (c) == '-') + do { + for (i = start = 0; i <= mechslen; i++) { + if (!ismechchar(mechs[i])) { + const char *mechp = &mechs[start]; + size_t len = i - start; + + if (len != 0 && + _mech_plus_p(mechp, len) == has_cb_data) { + memcpy(listp, mechp, len); + listp[len] = '\0'; + listp += len + 1; + (*count)++; + if (*server_can_cb == 0 && has_cb_data) + *server_can_cb = 1; + } + start = ++i; + } + } + if (has_cb_data) + has_cb_data = 0; + else + break; + } while (1); + + if (*count == 0) { + utils->free(list); + return SASL_NOMECH; + } + + *ordered_mechs = list; + + return SASL_OK; +} + +static INLINE int +_sasl_cbinding_disp(sasl_client_params_t *cparams, + int mech_nego, + int server_can_cb, + sasl_cbinding_disp_t *cbindingdisp) +{ + /* + * If negotiating mechanisms, then we fail immediately if the + * client requires channel binding and the server does not + * advertise support. Otherwise we send "y" (which later will + * become "p" if we select a supporting mechanism). + * + * If the client explicitly selected a mechanism, then we only + * send channel bindings if they're marked critical. + */ + + *cbindingdisp = SASL_CB_DISP_NONE; + + if (SASL_CB_PRESENT(cparams)) { + if (mech_nego) { + if (!server_can_cb && SASL_CB_CRITICAL(cparams)) { + return SASL_NOMECH; + } else { + *cbindingdisp = SASL_CB_DISP_WANT; + } + } else if (SASL_CB_CRITICAL(cparams)) { + *cbindingdisp = SASL_CB_DISP_USED; + } + } + + return SASL_OK; +} + +/* select a mechanism for a connection + * mechlist -- mechanisms server has available (punctuation ignored) + * secret -- optional secret from previous session + * output: + * prompt_need -- on SASL_INTERACT, list of prompts needed to continue + * clientout -- the initial client response to send to the server + * mech -- set to mechanism name + * + * Returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + * SASL_NOMECH -- no mechanism meets requested properties + * SASL_INTERACT -- user interaction needed to fill in prompt_need list + */ + +/* + * SASL mechanism allowable characters are "AZ-_" + * separators can be any other characters and of any length + * even variable lengths between. + * + * But for convenience we accept lowercase ASCII. + * + * Apps should be encouraged to simply use space or comma space + * though + */ +int sasl_client_start(sasl_conn_t *conn, + const char *mechlist, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + const char **mech) +{ + sasl_client_conn_t *c_conn = (sasl_client_conn_t *) conn; + char *ordered_mechs = NULL, *name; + cmechanism_t *m = NULL, *bestm = NULL; + size_t i, list_len, name_len; + sasl_ssf_t bestssf = 0, minssf = 0; + int result, server_can_cb = 0; + sasl_cbinding_disp_t cbindingdisp; + sasl_cbinding_disp_t cur_cbindingdisp; + sasl_cbinding_disp_t best_cbindingdisp = SASL_CB_DISP_NONE; + + if (_sasl_client_active == 0) return SASL_NOTINIT; + + if (!conn) return SASL_BADPARAM; + + /* verify parameters */ + if (mechlist == NULL) { + PARAMERROR(conn); + } + + /* if prompt_need != NULL we've already been here + and just need to do the continue step again */ + + /* do a step */ + /* FIXME: Hopefully they only give us our own prompt_need back */ + if (prompt_need && *prompt_need != NULL) { + goto dostep; + } + + if (conn->props.min_ssf < conn->external.ssf) { + minssf = 0; + } else { + minssf = conn->props.min_ssf - conn->external.ssf; + } + + /* Order mechanisms so -PLUS are preferred */ + result = _sasl_client_order_mechs(c_conn->cparams->utils, + mechlist, + SASL_CB_PRESENT(c_conn->cparams), + &ordered_mechs, + &list_len, + &server_can_cb); + if (result != 0) + goto done; + + /* + * Determine channel binding disposition based on whether we + * are doing mechanism negotiation and whether server supports + * channel bindings. + */ + result = _sasl_cbinding_disp(c_conn->cparams, + (list_len > 1), + server_can_cb, + &cbindingdisp); + if (result != 0) + goto done; + + for (i = 0, name = ordered_mechs; i < list_len; i++) { + + name_len = strlen(name); + + /* for each mechanism in client's list */ + for (m = c_conn->mech_list; m != NULL; m = m->next) { + unsigned myflags; + int plus; + + if (!_sasl_is_equal_mech(name, m->m.plug->mech_name, name_len, &plus)) { + continue; + } + + /* Do we have the prompts for it? */ + if (!have_prompts(conn, m->m.plug)) + break; + + /* Is it strong enough? */ + if (minssf > m->m.plug->max_ssf) + break; + + myflags = conn->props.security_flags; + + /* if there's an external layer with a better SSF then this is no + * longer considered a plaintext mechanism + */ + if ((conn->props.min_ssf <= conn->external.ssf) && + (conn->external.ssf > 1)) { + myflags &= ~SASL_SEC_NOPLAINTEXT; + } + + /* Does it meet our security properties? */ + if (((myflags ^ m->m.plug->security_flags) & myflags) != 0) { + break; + } + + /* Can we meet it's features? */ + if (cbindingdisp == SASL_CB_DISP_USED && + !(m->m.plug->features & SASL_FEAT_CHANNEL_BINDING)) { + break; + } + + if ((m->m.plug->features & SASL_FEAT_NEEDSERVERFQDN) + && !conn->serverFQDN) { + break; + } + + /* Can it meet our features? */ + if ((conn->flags & SASL_NEED_PROXY) && + !(m->m.plug->features & SASL_FEAT_ALLOWS_PROXY)) { + break; + } + + if ((conn->flags & SASL_NEED_HTTP) && + !(m->m.plug->features & SASL_FEAT_SUPPORTS_HTTP)) { + break; + } + + /* compare security flags, only take new mechanism if it has + * all the security flags of the previous one. + * + * From the mechanisms we ship with, this yields the order: + * + * SRP + * GSSAPI + KERBEROS_V4 + * DIGEST + OTP + * CRAM + EXTERNAL + * PLAIN + LOGIN + ANONYMOUS + * + * This might be improved on by comparing the numeric value of + * the bitwise-or'd security flags, which splits DIGEST/OTP, + * CRAM/EXTERNAL, and PLAIN/LOGIN from ANONYMOUS, but then we + * are depending on the numeric values of the flags (which may + * change, and their ordering could be considered dumb luck. + */ + + if (bestm && + ((m->m.plug->security_flags ^ bestm->m.plug->security_flags) & + bestm->m.plug->security_flags)) { + break; + } + + if (SASL_CB_PRESENT(c_conn->cparams) && plus) { + cur_cbindingdisp = SASL_CB_DISP_USED; + } else { + cur_cbindingdisp = cbindingdisp; + } + + if (bestm && (best_cbindingdisp > cur_cbindingdisp)) { + break; + } + +#ifdef PREFER_MECH + if (strcasecmp(m->m.plug->mech_name, PREFER_MECH) && + bestm && m->m.plug->max_ssf <= bestssf) { + /* this mechanism isn't our favorite, and it's no better + than what we already have! */ + break; + } +#else + if (bestm && m->m.plug->max_ssf <= bestssf) { + /* this mechanism is no better than what we already have! */ + break; + } +#endif + + if (mech) { + *mech = m->m.plug->mech_name; + } + + best_cbindingdisp = cur_cbindingdisp; + bestssf = m->m.plug->max_ssf; + bestm = m; + break; + } + name += strlen(name) + 1; + } + + if (bestm == NULL) { + sasl_seterror(conn, 0, "No worthy mechs found"); + result = SASL_NOMECH; + goto done; + } + + /* make (the rest of) cparams */ + c_conn->cparams->service = conn->service; + c_conn->cparams->servicelen = (unsigned) strlen(conn->service); + + if (conn->serverFQDN) { + c_conn->cparams->serverFQDN = conn->serverFQDN; + c_conn->cparams->slen = (unsigned) strlen(conn->serverFQDN); + } + + c_conn->cparams->clientFQDN = c_conn->clientFQDN; + c_conn->cparams->clen = (unsigned) strlen(c_conn->clientFQDN); + + c_conn->cparams->external_ssf = conn->external.ssf; + c_conn->cparams->props = conn->props; + c_conn->cparams->cbindingdisp = best_cbindingdisp; + c_conn->mech = bestm; + + /* init that plugin */ + result = c_conn->mech->m.plug->mech_new(c_conn->mech->m.plug->glob_context, + c_conn->cparams, + &(conn->context)); + if (result != SASL_OK) goto done; + + /* do a step -- but only if we can do a client-send-first */ + dostep: + if(clientout) { + if(c_conn->mech->m.plug->features & SASL_FEAT_SERVER_FIRST) { + *clientout = NULL; + *clientoutlen = 0; + result = SASL_CONTINUE; + } else { + result = sasl_client_step(conn, NULL, 0, prompt_need, + clientout, clientoutlen); + } + } + else + result = SASL_CONTINUE; + + done: + if (ordered_mechs != NULL) + c_conn->cparams->utils->free(ordered_mechs); + RETURN(conn, result); +} + +/* do a single authentication step. + * serverin -- the server message received by the client, MUST have a NUL + * sentinel, not counted by serverinlen + * output: + * prompt_need -- on SASL_INTERACT, list of prompts needed to continue + * clientout -- the client response to send to the server + * + * returns: + * SASL_OK -- success + * SASL_INTERACT -- user interaction needed to fill in prompt_need list + * SASL_BADPROT -- server protocol incorrect/cancelled + * SASL_BADSERV -- server failed mutual auth + */ + +int sasl_client_step(sasl_conn_t *conn, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen) +{ + sasl_client_conn_t *c_conn= (sasl_client_conn_t *) conn; + int result; + + if (_sasl_client_active == 0) return SASL_NOTINIT; + if (!conn) return SASL_BADPARAM; + + /* check parameters */ + if ((serverin==NULL) && (serverinlen>0)) + PARAMERROR(conn); + + /* Don't do another step if the plugin told us that we're done */ + if (conn->oparams.doneflag) { + _sasl_log(conn, SASL_LOG_ERR, "attempting client step after doneflag"); + return SASL_FAIL; + } + + if(clientout) *clientout = NULL; + if(clientoutlen) *clientoutlen = 0; + + /* do a step */ + result = c_conn->mech->m.plug->mech_step(conn->context, + c_conn->cparams, + serverin, + serverinlen, + prompt_need, + clientout, clientoutlen, + &conn->oparams); + + if (result == SASL_OK) { + /* So we're done on this end, but if both + * 1. the mech does server-send-last + * 2. the protocol does not + * we need to return no data */ + if(!*clientout && !(conn->flags & SASL_SUCCESS_DATA)) { + *clientout = ""; + *clientoutlen = 0; + } + + if(!conn->oparams.maxoutbuf) { + conn->oparams.maxoutbuf = conn->props.maxbufsize; + } + + if(conn->oparams.user == NULL || conn->oparams.authid == NULL) { + sasl_seterror(conn, 0, + "mech did not call canon_user for both authzid and authid"); + result = SASL_BADPROT; + } + } + + RETURN(conn,result); +} + +/* returns the length of all the mechanisms + * added up + */ + +static unsigned mech_names_len(cmechanism_t *mech_list) +{ + cmechanism_t *listptr; + unsigned result = 0; + + for (listptr = mech_list; + listptr; + listptr = listptr->next) + result += (unsigned) strlen(listptr->m.plug->mech_name); + + return result; +} + + +int _sasl_client_listmech(sasl_conn_t *conn, + const char *prefix, + const char *sep, + const char *suffix, + const char **result, + unsigned *plen, + int *pcount) +{ + sasl_client_conn_t *c_conn = (sasl_client_conn_t *)conn; + cmechanism_t *m = NULL; + sasl_ssf_t minssf = 0; + int ret; + size_t resultlen; + int flag; + const char *mysep; + + if (_sasl_client_active == 0) return SASL_NOTINIT; + if (!conn) return SASL_BADPARAM; + if (conn->type != SASL_CONN_CLIENT) PARAMERROR(conn); + + if (! result) + PARAMERROR(conn); + + if (plen != NULL) + *plen = 0; + if (pcount != NULL) + *pcount = 0; + + if (sep) { + mysep = sep; + } else { + mysep = " "; + } + + if (conn->props.min_ssf < conn->external.ssf) { + minssf = 0; + } else { + minssf = conn->props.min_ssf - conn->external.ssf; + } + + if (!c_conn->mech_list || c_conn->mech_length <= 0) { + INTERROR(conn, SASL_NOMECH); + } + + resultlen = (prefix ? strlen(prefix) : 0) + + (strlen(mysep) * (c_conn->mech_length - 1)) + + mech_names_len(c_conn->mech_list) + + (suffix ? strlen(suffix) : 0) + + 1; + ret = _buf_alloc(&conn->mechlist_buf, + &conn->mechlist_buf_len, + resultlen); + if (ret != SASL_OK) MEMERROR(conn); + + if (prefix) { + strcpy (conn->mechlist_buf,prefix); + } else { + *(conn->mechlist_buf) = '\0'; + } + + flag = 0; + for (m = c_conn->mech_list; m != NULL; m = m->next) { + /* do we have the prompts for it? */ + if (!have_prompts(conn, m->m.plug)) { + continue; + } + + /* is it strong enough? */ + if (minssf > m->m.plug->max_ssf) { + continue; + } + + /* does it meet our security properties? */ + if (((conn->props.security_flags ^ m->m.plug->security_flags) + & conn->props.security_flags) != 0) { + continue; + } + + /* Can we meet it's features? */ + if ((m->m.plug->features & SASL_FEAT_NEEDSERVERFQDN) + && !conn->serverFQDN) { + continue; + } + + /* Can it meet our features? */ + if ((conn->flags & SASL_NEED_PROXY) && + !(m->m.plug->features & SASL_FEAT_ALLOWS_PROXY)) { + continue; + } + + /* Okay, we like it, add it to the list! */ + + if (pcount != NULL) + (*pcount)++; + + /* print seperator */ + if (flag) { + strcat(conn->mechlist_buf, mysep); + } else { + flag = 1; + } + + /* now print the mechanism name */ + strcat(conn->mechlist_buf, m->m.plug->mech_name); + } + + if (suffix) + strcat(conn->mechlist_buf,suffix); + + if (plen!=NULL) + *plen = (unsigned) strlen(conn->mechlist_buf); + + *result = conn->mechlist_buf; + + return SASL_OK; +} + +sasl_string_list_t *_sasl_client_mechs(void) +{ + cmechanism_t *listptr; + sasl_string_list_t *retval = NULL, *next=NULL; + + if(!_sasl_client_active) return NULL; + + /* make list */ + for (listptr = cmechlist->mech_list; listptr; listptr = listptr->next) { + next = sasl_ALLOC(sizeof(sasl_string_list_t)); + + if(!next && !retval) return NULL; + else if(!next) { + next = retval->next; + do { + sasl_FREE(retval); + retval = next; + next = retval->next; + } while(next); + return NULL; + } + + next->d = listptr->m.plug->mech_name; + + if(!retval) { + next->next = NULL; + retval = next; + } else { + next->next = retval; + retval = next; + } + } + + return retval; +} + + + + +/* It would be nice if we can show other information like Author, Company, Year, plugin version */ +static void +_sasl_print_mechanism ( + client_sasl_mechanism_t *m, + sasl_info_callback_stage_t stage, + void *rock __attribute__((unused)) +) +{ + char delimiter; + + if (stage == SASL_INFO_LIST_START) { + printf ("List of client plugins follows\n"); + return; + } else if (stage == SASL_INFO_LIST_END) { + return; + } + + /* Process the mechanism */ + printf ("Plugin \"%s\" ", m->plugname); + + /* There is no delay loading for client side plugins */ + printf ("[loaded]"); + + printf (", \tAPI version: %d\n", m->version); + + if (m->plug != NULL) { + printf ("\tSASL mechanism: %s, best SSF: %d\n", + m->plug->mech_name, + m->plug->max_ssf); + + printf ("\tsecurity flags:"); + + delimiter = ' '; + if (m->plug->security_flags & SASL_SEC_NOANONYMOUS) { + printf ("%cNO_ANONYMOUS", delimiter); + delimiter = '|'; + } + + if (m->plug->security_flags & SASL_SEC_NOPLAINTEXT) { + printf ("%cNO_PLAINTEXT", delimiter); + delimiter = '|'; + } + + if (m->plug->security_flags & SASL_SEC_NOACTIVE) { + printf ("%cNO_ACTIVE", delimiter); + delimiter = '|'; + } + + if (m->plug->security_flags & SASL_SEC_NODICTIONARY) { + printf ("%cNO_DICTIONARY", delimiter); + delimiter = '|'; + } + + if (m->plug->security_flags & SASL_SEC_FORWARD_SECRECY) { + printf ("%cFORWARD_SECRECY", delimiter); + delimiter = '|'; + } + + if (m->plug->security_flags & SASL_SEC_PASS_CREDENTIALS) { + printf ("%cPASS_CREDENTIALS", delimiter); + delimiter = '|'; + } + + if (m->plug->security_flags & SASL_SEC_MUTUAL_AUTH) { + printf ("%cMUTUAL_AUTH", delimiter); + delimiter = '|'; + } + + + + printf ("\n\tfeatures:"); + + delimiter = ' '; + if (m->plug->features & SASL_FEAT_WANT_CLIENT_FIRST) { + printf ("%cWANT_CLIENT_FIRST", delimiter); + delimiter = '|'; + } + + if (m->plug->features & SASL_FEAT_SERVER_FIRST) { + printf ("%cSERVER_FIRST", delimiter); + delimiter = '|'; + } + + if (m->plug->features & SASL_FEAT_ALLOWS_PROXY) { + printf ("%cPROXY_AUTHENTICATION", delimiter); + delimiter = '|'; + } + + if (m->plug->features & SASL_FEAT_NEEDSERVERFQDN) { + printf ("%cNEED_SERVER_FQDN", delimiter); + delimiter = '|'; + } + + if (m->plug->features & SASL_FEAT_GSS_FRAMING) { + printf ("%cGSS_FRAMING", delimiter); + delimiter = '|'; + } + + if (m->plug->features & SASL_FEAT_CHANNEL_BINDING) { + printf ("%cCHANNEL_BINDING", delimiter); + delimiter = '|'; + } + + if (m->plug->features & SASL_FEAT_SUPPORTS_HTTP) { + printf ("%cSUPPORTS_HTTP", delimiter); + delimiter = '|'; + } + } + +/* Delay loading is not supported for the client side plugins: + if (m->f) { + printf ("\n\twill be loaded from \"%s\"", m->f); + } + */ + + printf ("\n"); +} + + +/* Dump information about available client plugins */ +int sasl_client_plugin_info ( + const char *c_mech_list, /* space separated mechanism list or NULL for ALL */ + sasl_client_info_callback_t *info_cb, + void *info_cb_rock +) +{ + cmechanism_t *m; + client_sasl_mechanism_t plug_data; + char * cur_mech; + char * mech_list = NULL; + char * p; + + if (info_cb == NULL) { + info_cb = _sasl_print_mechanism; + } + + if (cmechlist != NULL) { + info_cb (NULL, SASL_INFO_LIST_START, info_cb_rock); + + if (c_mech_list == NULL) { + m = cmechlist->mech_list; /* m point to beginning of the list */ + + while (m != NULL) { + memcpy (&plug_data, &m->m, sizeof(plug_data)); + + info_cb (&plug_data, SASL_INFO_LIST_MECH, info_cb_rock); + + m = m->next; + } + } else { + mech_list = strdup (c_mech_list); + + cur_mech = mech_list; + + while (cur_mech != NULL) { + p = strchr (cur_mech, ' '); + if (p != NULL) { + *p = '\0'; + p++; + } + + m = cmechlist->mech_list; /* m point to beginning of the list */ + + while (m != NULL) { + if (strcasecmp (cur_mech, m->m.plug->mech_name) == 0) { + memcpy (&plug_data, &m->m, sizeof(plug_data)); + + info_cb (&plug_data, SASL_INFO_LIST_MECH, info_cb_rock); + } + + m = m->next; + } + + cur_mech = p; + } + + free (mech_list); + } + + info_cb (NULL, SASL_INFO_LIST_END, info_cb_rock); + + return (SASL_OK); + } + + return (SASL_NOTINIT); +} diff --git a/libs/cyrussasl/lib/common.c b/libs/cyrussasl/lib/common.c new file mode 100644 index 00000000..e0f59ebc --- /dev/null +++ b/libs/cyrussasl/lib/common.c @@ -0,0 +1,2622 @@ +/* common.c - Functions that are common to server and clinet + * Rob Siemborski + * Tim Martin + * $Id: common.c,v 1.134 2011/09/22 14:40:30 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#ifdef HAVE_SYSLOG +#include +#endif +#include +#include +#include + +#include +#include +#include +#include "saslint.h" + +#ifdef HAVE_UNISTD_H +#include +#endif + +static const char *implementation_string = "Cyrus SASL"; + +#define VSTR0(maj, min, step) #maj "." #min "." #step +#define VSTR(maj, min, step) VSTR0(maj, min, step) +#define SASL_VERSION_STRING VSTR(SASL_VERSION_MAJOR, SASL_VERSION_MINOR, \ + SASL_VERSION_STEP) + +static int _sasl_getpath(void *context __attribute__((unused)), const char **path); +static int _sasl_getpath_simple(void *context __attribute__((unused)), const char **path); +static int _sasl_getconfpath(void *context __attribute__((unused)), char ** path); +static int _sasl_getconfpath_simple(void *context __attribute__((unused)), const char **path); + +#if !defined(WIN32) +static char * _sasl_get_default_unix_path(void *context __attribute__((unused)), + char * env_var_name, char * default_value); +#else +/* NB: Always returned allocated value */ +static char * _sasl_get_default_win_path(void *context __attribute__((unused)), + char * reg_attr_name, char * default_value); +#endif + + +static const char build_ident[] = "$Build: libsasl " PACKAGE "-" VERSION " $"; + +/* It turns out to be convenient to have a shared sasl_utils_t */ +const sasl_utils_t *sasl_global_utils = NULL; + +/* Should be a null-terminated array that lists the available mechanisms */ +static char **global_mech_list = NULL; + +void *free_mutex = NULL; + +int (*_sasl_client_cleanup_hook)(void) = NULL; +int (*_sasl_server_cleanup_hook)(void) = NULL; +int (*_sasl_client_idle_hook)(sasl_conn_t *conn) = NULL; +int (*_sasl_server_idle_hook)(sasl_conn_t *conn) = NULL; + +sasl_allocation_utils_t _sasl_allocation_utils={ + (sasl_malloc_t *) &malloc, + (sasl_calloc_t *) &calloc, + (sasl_realloc_t *) &realloc, + (sasl_free_t *) &free +}; +int _sasl_allocation_locked = 0; + +#define SASL_ENCODEV_EXTRA 4096 + +/* Default getpath/getconfpath callbacks. These can be edited by sasl_set_path(). */ +static sasl_callback_t default_getpath_cb = { + SASL_CB_GETPATH, (sasl_callback_ft)&_sasl_getpath, NULL +}; +static sasl_callback_t default_getconfpath_cb = { + SASL_CB_GETCONFPATH, (sasl_callback_ft)&_sasl_getconfpath, NULL +}; + +static char * default_plugin_path = NULL; +static char * default_conf_path = NULL; + +static int _sasl_global_getopt(void *context, + const char *plugin_name, + const char *option, + const char ** result, + unsigned *len); + +/* Intenal mutex functions do as little as possible (no thread protection) */ +static void *sasl_mutex_alloc(void) +{ + return (void *)0x1; +} + +static int sasl_mutex_lock(void *mutex __attribute__((unused))) +{ + return SASL_OK; +} + +static int sasl_mutex_unlock(void *mutex __attribute__((unused))) +{ + return SASL_OK; +} + +static void sasl_mutex_free(void *mutex __attribute__((unused))) +{ + return; +} + +sasl_mutex_utils_t _sasl_mutex_utils={ + &sasl_mutex_alloc, + &sasl_mutex_lock, + &sasl_mutex_unlock, + &sasl_mutex_free +}; + +void sasl_set_mutex(sasl_mutex_alloc_t *n, + sasl_mutex_lock_t *l, + sasl_mutex_unlock_t *u, + sasl_mutex_free_t *d) +{ + /* Disallow mutex function changes once sasl_client_init + and/or sasl_server_init is called */ + if (_sasl_server_cleanup_hook || _sasl_client_cleanup_hook) { + return; + } + + _sasl_mutex_utils.alloc=n; + _sasl_mutex_utils.lock=l; + _sasl_mutex_utils.unlock=u; + _sasl_mutex_utils.free=d; +} + +/* copy a string to malloced memory */ +int _sasl_strdup(const char *in, char **out, size_t *outlen) +{ + size_t len = strlen(in); + if (outlen) *outlen = len; + *out=sasl_ALLOC((unsigned) len + 1); + if (! *out) return SASL_NOMEM; + strcpy((char *) *out, in); + return SASL_OK; +} + +/* adds a string to the buffer; reallocing if need be */ +int _sasl_add_string(char **out, size_t *alloclen, + size_t *outlen, const char *add) +{ + size_t addlen; + + if (add==NULL) add = "(null)"; + + addlen=strlen(add); /* only compute once */ + if (_buf_alloc(out, alloclen, (*outlen)+addlen)!=SASL_OK) + return SASL_NOMEM; + + strncpy(*out + *outlen, add, addlen); + *outlen += addlen; + + return SASL_OK; +} + +/* a simpler way to set plugin path or configuration file path + * without the need to set sasl_getpath_t callback. + * + * This function can be called before sasl_server_init/sasl_client_init. + * + * Don't call this function without locking in a multithreaded application. + */ +int sasl_set_path (int path_type, char * path) +{ + int result; + + if (path == NULL) { + return (SASL_FAIL); + } + + switch (path_type) { + case SASL_PATH_TYPE_PLUGIN: + if (default_plugin_path != NULL) { + sasl_FREE (default_plugin_path); + default_plugin_path = NULL; + } + result = _sasl_strdup (path, &default_plugin_path, NULL); + if (result != SASL_OK) { + return (result); + } + + /* Update the default getpath_t callback */ + default_getpath_cb.proc = (sasl_callback_ft)&_sasl_getpath_simple; + break; + + case SASL_PATH_TYPE_CONFIG: + if (default_conf_path != NULL) { + sasl_FREE (default_conf_path); + default_conf_path = NULL; + } + result = _sasl_strdup (path, &default_conf_path, NULL); + if (result != SASL_OK) { + return (result); + } + + /* Update the default getpath_t callback */ + default_getconfpath_cb.proc = (sasl_callback_ft)&_sasl_getconfpath_simple; + break; + + default: + return (SASL_FAIL); + } + + return (SASL_OK); +} + +/* return the version of the cyrus sasl library as compiled, + * using 32 bits: high byte is major version, second byte is minor version, + * low 16 bits are step #. + * Patch version is not available using this function, + * use sasl_version_info() instead. + */ +void sasl_version(const char **implementation, int *version) +{ + if(implementation) *implementation = implementation_string; + /* NB: the format is not the same as in SASL_VERSION_FULL */ + if(version) *version = (SASL_VERSION_MAJOR << 24) | + (SASL_VERSION_MINOR << 16) | + (SASL_VERSION_STEP); +} + +/* Extended version of sasl_version above */ +void sasl_version_info (const char **implementation, const char **version_string, + int *version_major, int *version_minor, int *version_step, + int *version_patch) +{ + if (implementation) *implementation = implementation_string; + if (version_string) *version_string = SASL_VERSION_STRING; + if (version_major) *version_major = SASL_VERSION_MAJOR; + if (version_minor) *version_minor = SASL_VERSION_MINOR; + if (version_step) *version_step = SASL_VERSION_STEP; + /* Version patch is always 0 for CMU SASL */ + if (version_patch) *version_patch = 0; +} + +/* security-encode a regular string. Mostly a wrapper for sasl_encodev */ +/* output is only valid until next call to sasl_encode or sasl_encodev */ +int sasl_encode(sasl_conn_t *conn, const char *input, + unsigned inputlen, + const char **output, unsigned *outputlen) +{ + int result; + struct iovec tmp; + + if(!conn) return SASL_BADPARAM; + if(!input || !inputlen || !output || !outputlen) + PARAMERROR(conn); + + /* maxoutbuf checking is done in sasl_encodev */ + + /* Note: We are casting a const pointer here, but it's okay + * because we believe people downstream of us are well-behaved, and the + * alternative is an absolute mess, performance-wise. */ + tmp.iov_base = (void *)input; + tmp.iov_len = inputlen; + + result = sasl_encodev(conn, &tmp, 1, output, outputlen); + + RETURN(conn, result); +} + +/* Internal function that doesn't do any verification */ +static int +_sasl_encodev (sasl_conn_t *conn, + const struct iovec *invec, + unsigned numiov, + int * p_num_packets, /* number of packets generated so far */ + const char **output, /* previous output, if *p_num_packets > 0 */ + unsigned *outputlen) +{ + int result; + char * new_buf; + + assert (conn->oparams.encode != NULL); + + if (*p_num_packets == 1) { + /* This is the second call to this function, + so we need to allocate a new output buffer + and copy existing data there. */ + conn->multipacket_encoded_data.curlen = *outputlen; + if (conn->multipacket_encoded_data.data == NULL) { + conn->multipacket_encoded_data.reallen = + conn->multipacket_encoded_data.curlen + SASL_ENCODEV_EXTRA; + conn->multipacket_encoded_data.data = + sasl_ALLOC(conn->multipacket_encoded_data.reallen + 1); + + if (conn->multipacket_encoded_data.data == NULL) { + MEMERROR(conn); + } + } else { + /* A buffer left from a previous sasl_encodev call. + Make sure it is big enough. */ + if (conn->multipacket_encoded_data.curlen > + conn->multipacket_encoded_data.reallen) { + conn->multipacket_encoded_data.reallen = + conn->multipacket_encoded_data.curlen + SASL_ENCODEV_EXTRA; + + new_buf = sasl_REALLOC(conn->multipacket_encoded_data.data, + conn->multipacket_encoded_data.reallen + 1); + if (new_buf == NULL) { + MEMERROR(conn); + } + conn->multipacket_encoded_data.data = new_buf; + } + } + + memcpy (conn->multipacket_encoded_data.data, + *output, + *outputlen); + } + + result = conn->oparams.encode(conn->context, + invec, + numiov, + output, + outputlen); + + if (*p_num_packets > 0 && result == SASL_OK) { + /* Is the allocated buffer big enough? If not, grow it. */ + if ((conn->multipacket_encoded_data.curlen + *outputlen) > + conn->multipacket_encoded_data.reallen) { + conn->multipacket_encoded_data.reallen = + conn->multipacket_encoded_data.curlen + *outputlen; + new_buf = sasl_REALLOC(conn->multipacket_encoded_data.data, + conn->multipacket_encoded_data.reallen + 1); + if (new_buf == NULL) { + MEMERROR(conn); + } + conn->multipacket_encoded_data.data = new_buf; + } + + /* Append new data to the end of the buffer */ + memcpy (conn->multipacket_encoded_data.data + + conn->multipacket_encoded_data.curlen, + *output, + *outputlen); + conn->multipacket_encoded_data.curlen += *outputlen; + + *output = conn->multipacket_encoded_data.data; + *outputlen = (unsigned)conn->multipacket_encoded_data.curlen; + } + + (*p_num_packets)++; + + RETURN(conn, result); +} + +/* security-encode an iovec */ +/* output is only valid until the next call to sasl_encode or sasl_encodev */ +int sasl_encodev(sasl_conn_t *conn, + const struct iovec *invec, + unsigned numiov, + const char **output, + unsigned *outputlen) +{ + int result = SASL_OK; + unsigned i; + unsigned j; + size_t total_size = 0; + struct iovec *cur_invec = NULL; + struct iovec last_invec; + unsigned cur_numiov; + char * next_buf = NULL; + size_t remainder_len; + unsigned index_offset; + unsigned allocated = 0; + /* Number of generated SASL packets */ + int num_packets = 0; + + if (!conn) return SASL_BADPARAM; + if (! invec || ! output || ! outputlen || numiov < 1) { + PARAMERROR(conn); + } + + if (!conn->props.maxbufsize) { + sasl_seterror(conn, 0, + "called sasl_encode[v] with application that does not support security layers"); + return SASL_TOOWEAK; + } + + /* If oparams.encode is NULL, this means there is no SASL security + layer in effect, so no SASL framing is needed. */ + if (conn->oparams.encode == NULL) { + result = _iovec_to_buf(invec, numiov, &conn->encode_buf); + if (result != SASL_OK) INTERROR(conn, result); + + *output = conn->encode_buf->data; + *outputlen = (unsigned) conn->encode_buf->curlen; + + RETURN(conn, result); + } + + /* This might be better to check on a per-plugin basis, but I think + * it's cleaner and more effective here. It also encourages plugins + * to be honest about what they accept */ + + last_invec.iov_base = NULL; + remainder_len = 0; + next_buf = NULL; + i = 0; + while (i < numiov) { + if ((total_size + invec[i].iov_len) > conn->oparams.maxoutbuf) { + + /* CLAIM: total_size < conn->oparams.maxoutbuf */ + + /* Fit as many bytes in last_invec, so that we have conn->oparams.maxoutbuf + bytes in total. */ + last_invec.iov_len = conn->oparams.maxoutbuf - total_size; + /* Point to the first byte of the current record. */ + last_invec.iov_base = invec[i].iov_base; + + /* Note that total_size < conn->oparams.maxoutbuf */ + /* The total size of the iov is bigger then the other end can accept. + So we allocate a new iov that contains just enough. */ + + /* +1 --- for the tail record */ + cur_numiov = i + 1; + + /* +1 --- just in case we need the head record */ + if ((cur_numiov + 1) > allocated) { + struct iovec *new_invec; + + allocated = cur_numiov + 1; + new_invec = sasl_REALLOC (cur_invec, sizeof(struct iovec) * allocated); + if (new_invec == NULL) { + if (cur_invec != NULL) { + sasl_FREE(cur_invec); + } + MEMERROR(conn); + } + cur_invec = new_invec; + } + + if (next_buf != NULL) { + cur_invec[0].iov_base = next_buf; + cur_invec[0].iov_len = (long)remainder_len; + cur_numiov++; + index_offset = 1; + } else { + index_offset = 0; + } + + if (i > 0) { + /* Copy all previous chunks */ + /* NOTE - The starting index in invec is always 0 */ + for (j = 0; j < i; j++) { + cur_invec[j + index_offset] = invec[j]; + } + } + + /* Initialize the last record */ + cur_invec[i + index_offset] = last_invec; + + result = _sasl_encodev (conn, + cur_invec, + cur_numiov, + &num_packets, + output, + outputlen); + + if (result != SASL_OK) { + goto cleanup; + } + + /* Point to the first byte that wouldn't fit into + the conn->oparams.maxoutbuf buffer. */ + /* Note, if next_buf points to the very end of the IOV record, + it will be reset to NULL below */ + /* Note, that some platforms define iov_base as "void *", + thus the typecase below */ + next_buf = (char *) last_invec.iov_base + last_invec.iov_len; + /* Note - remainder_len is how many bytes left to be encoded in + the current IOV slot. */ + remainder_len = (total_size + invec[i].iov_len) - conn->oparams.maxoutbuf; + + /* Skip all consumed IOV records */ + invec += i + 1; + numiov = numiov - (i + 1); + i = 0; + + while (remainder_len > conn->oparams.maxoutbuf) { + last_invec.iov_base = next_buf; + last_invec.iov_len = conn->oparams.maxoutbuf; + + /* Note, if next_buf points to the very end of the IOV record, + it will be reset to NULL below */ + /* Note, that some platforms define iov_base as "void *", + thus the typecase below */ + next_buf = (char *) last_invec.iov_base + last_invec.iov_len; + remainder_len = remainder_len - conn->oparams.maxoutbuf; + + result = _sasl_encodev (conn, + &last_invec, + 1, + &num_packets, + output, + outputlen); + if (result != SASL_OK) { + goto cleanup; + } + } + + total_size = remainder_len; + + if (remainder_len == 0) { + /* Just clear next_buf */ + next_buf = NULL; + } + } else { + total_size += invec[i].iov_len; + i++; + } + } + + /* CLAIM - The remaining data is shorter then conn->oparams.maxoutbuf. */ + + /* Force encoding of any partial buffer. Might not be optimal on the wire. */ + if (next_buf != NULL) { + last_invec.iov_base = next_buf; + last_invec.iov_len = (long)remainder_len; + + result = _sasl_encodev (conn, + &last_invec, + 1, + &num_packets, + output, + outputlen); + + if (result != SASL_OK) { + goto cleanup; + } + } + + if (numiov > 0) { + result = _sasl_encodev (conn, + invec, + numiov, + &num_packets, + output, + outputlen); + } + +cleanup: + if (cur_invec != NULL) { + sasl_FREE(cur_invec); + } + + RETURN(conn, result); +} + +/* output is only valid until next call to sasl_decode */ +int sasl_decode(sasl_conn_t *conn, + const char *input, unsigned inputlen, + const char **output, unsigned *outputlen) +{ + int result; + + if(!conn) return SASL_BADPARAM; + if(!input || !output || !outputlen) + PARAMERROR(conn); + + if(!conn->props.maxbufsize) { + sasl_seterror(conn, 0, + "called sasl_decode with application that does not support security layers"); + RETURN(conn, SASL_TOOWEAK); + } + + if(conn->oparams.decode == NULL) + { + /* Since we know how long the output is maximally, we can + * just allocate it to begin with, and never need another + * allocation! */ + + /* However, if they pass us more than they actually can take, + * we cannot help them... */ + if(inputlen > conn->props.maxbufsize) { + sasl_seterror(conn, 0, + "input too large for default sasl_decode"); + RETURN(conn,SASL_BUFOVER); + } + + if(!conn->decode_buf) + conn->decode_buf = sasl_ALLOC(conn->props.maxbufsize + 1); + if(!conn->decode_buf) + MEMERROR(conn); + + memcpy(conn->decode_buf, input, inputlen); + conn->decode_buf[inputlen] = '\0'; + *output = conn->decode_buf; + *outputlen = inputlen; + + return SASL_OK; + } else { + result = conn->oparams.decode(conn->context, input, inputlen, + output, outputlen); + + /* NULL an empty buffer (for misbehaved applications) */ + if (*outputlen == 0) *output = NULL; + + RETURN(conn, result); + } + + INTERROR(conn, SASL_FAIL); +} + + +void +sasl_set_alloc(sasl_malloc_t *m, + sasl_calloc_t *c, + sasl_realloc_t *r, + sasl_free_t *f) +{ + if (_sasl_allocation_locked++) return; + + _sasl_allocation_utils.malloc=m; + _sasl_allocation_utils.calloc=c; + _sasl_allocation_utils.realloc=r; + _sasl_allocation_utils.free=f; +} + +void sasl_common_done(void) +{ + /* NOTE - the caller will need to reinitialize the values, + if it is going to call sasl_client_init/sasl_server_init again. */ + if (default_plugin_path != NULL) { + sasl_FREE (default_plugin_path); + default_plugin_path = NULL; + } + if (default_conf_path != NULL) { + sasl_FREE (default_conf_path); + default_conf_path = NULL; + } + + _sasl_canonuser_free(); + _sasl_done_with_plugins(); + + sasl_MUTEX_FREE(free_mutex); + free_mutex = NULL; + + _sasl_free_utils(&sasl_global_utils); + + if (global_mech_list) { + sasl_FREE(global_mech_list); + global_mech_list = NULL; + } +} + +/* This function is for backward compatibility */ +void sasl_done(void) +{ + if (_sasl_server_cleanup_hook && _sasl_server_cleanup_hook() == SASL_OK) { + _sasl_server_idle_hook = NULL; + _sasl_server_cleanup_hook = NULL; + } + + if (_sasl_client_cleanup_hook && _sasl_client_cleanup_hook() == SASL_OK) { + _sasl_client_idle_hook = NULL; + _sasl_client_cleanup_hook = NULL; + } + + if (_sasl_server_cleanup_hook || _sasl_client_cleanup_hook) { + return; + } + + sasl_common_done(); +} + +/* fills in the base sasl_conn_t info */ +int _sasl_conn_init(sasl_conn_t *conn, + const char *service, + unsigned int flags, + enum Sasl_conn_type type, + int (*idle_hook)(sasl_conn_t *conn), + const char *serverFQDN, + const char *iplocalport, + const char *ipremoteport, + const sasl_callback_t *callbacks, + const sasl_global_callbacks_t *global_callbacks) { + int result = SASL_OK; + + conn->type = type; + + result = _sasl_strdup(service, &conn->service, NULL); + if (result != SASL_OK) + MEMERROR(conn); + + memset(&conn->oparams, 0, sizeof(sasl_out_params_t)); + memset(&conn->external, 0, sizeof(_sasl_external_properties_t)); + + conn->flags = flags; + + result = sasl_setprop(conn, SASL_IPLOCALPORT, iplocalport); + if(result != SASL_OK) + RETURN(conn, result); + + result = sasl_setprop(conn, SASL_IPREMOTEPORT, ipremoteport); + if(result != SASL_OK) + RETURN(conn, result); + + conn->encode_buf = NULL; + conn->context = NULL; + conn->secret = NULL; + conn->idle_hook = idle_hook; + conn->callbacks = callbacks; + conn->global_callbacks = global_callbacks; + + memset(&conn->props, 0, sizeof(conn->props)); + + /* Start this buffer out as an empty string */ + conn->error_code = SASL_OK; + conn->errdetail_buf = conn->error_buf = NULL; + conn->errdetail_buf_len = conn->error_buf_len = 150; + + result = _buf_alloc(&conn->error_buf, &conn->error_buf_len, 150); + if(result != SASL_OK) MEMERROR(conn); + result = _buf_alloc(&conn->errdetail_buf, &conn->errdetail_buf_len, 150); + if(result != SASL_OK) MEMERROR(conn); + + conn->error_buf[0] = '\0'; + conn->errdetail_buf[0] = '\0'; + + conn->decode_buf = NULL; + + if(serverFQDN) { + result = _sasl_strdup(serverFQDN, &conn->serverFQDN, NULL); + sasl_strlower (conn->serverFQDN); + } else if (conn->type == SASL_CONN_SERVER) { + /* We can fake it because we *are* the server */ + char name[MAXHOSTNAMELEN]; + memset(name, 0, sizeof(name)); + if (get_fqhostname (name, MAXHOSTNAMELEN, 0) != 0) { + return (SASL_FAIL); + } + + result = _sasl_strdup(name, &conn->serverFQDN, NULL); + } else { + conn->serverFQDN = NULL; + } + + + if(result != SASL_OK) MEMERROR( conn ); + + RETURN(conn, SASL_OK); +} + +int _sasl_common_init(sasl_global_callbacks_t *global_callbacks) +{ + int result; + + /* The last specified global callback always wins */ + if (sasl_global_utils != NULL) { + sasl_utils_t * global_utils = (sasl_utils_t *)sasl_global_utils; + global_utils->getopt = &_sasl_global_getopt; + global_utils->getopt_context = global_callbacks; + } + + /* Do nothing if we are already initialized */ + if (free_mutex) { + return SASL_OK; + } + + /* Setup the global utilities */ + if(!sasl_global_utils) { + sasl_global_utils = _sasl_alloc_utils(NULL, global_callbacks); + if(sasl_global_utils == NULL) return SASL_NOMEM; + } + + /* Init the canon_user plugin */ + result = sasl_canonuser_add_plugin("INTERNAL", internal_canonuser_init); + if(result != SASL_OK) return result; + + if (!free_mutex) { + free_mutex = sasl_MUTEX_ALLOC(); + } + if (!free_mutex) return SASL_FAIL; + + return SASL_OK; +} + +/* dispose connection state, sets it to NULL + * checks for pointer to NULL + */ +void sasl_dispose(sasl_conn_t **pconn) +{ + int result; + + if (! pconn) return; + if (! *pconn) return; + + /* serialize disposes. this is necessary because we can't + dispose of conn->mutex if someone else is locked on it */ + result = sasl_MUTEX_LOCK(free_mutex); + if (result!=SASL_OK) return; + + /* *pconn might have become NULL by now */ + if (! (*pconn)) + { + sasl_MUTEX_UNLOCK(free_mutex); + return; + } + + (*pconn)->destroy_conn(*pconn); + sasl_FREE(*pconn); + *pconn=NULL; + + sasl_MUTEX_UNLOCK(free_mutex); +} + +void _sasl_conn_dispose(sasl_conn_t *conn) { + if (conn->serverFQDN) + sasl_FREE(conn->serverFQDN); + + if (conn->external.auth_id) + sasl_FREE(conn->external.auth_id); + + if(conn->encode_buf) { + if(conn->encode_buf->data) sasl_FREE(conn->encode_buf->data); + sasl_FREE(conn->encode_buf); + } + + if(conn->error_buf) + sasl_FREE(conn->error_buf); + + if(conn->errdetail_buf) + sasl_FREE(conn->errdetail_buf); + + if(conn->decode_buf) + sasl_FREE(conn->decode_buf); + + if(conn->mechlist_buf) + sasl_FREE(conn->mechlist_buf); + + if(conn->service) + sasl_FREE(conn->service); + + if (conn->multipacket_encoded_data.data) { + sasl_FREE(conn->multipacket_encoded_data.data); + } + + /* oparams sub-members should be freed by the plugin, in so much + * as they were allocated by the plugin */ +} + + +/* get property from SASL connection state + * propnum -- property number + * pvalue -- pointer to value + * returns: + * SASL_OK -- no error + * SASL_NOTDONE -- property not available yet + * SASL_BADPARAM -- bad property number or SASL context is NULL + */ +int sasl_getprop(sasl_conn_t *conn, int propnum, const void **pvalue) +{ + int result = SASL_OK; + sasl_getopt_t *getopt; + void *context; + + if (! conn) return SASL_BADPARAM; + if (! pvalue) PARAMERROR(conn); + + switch(propnum) + { + case SASL_SSF: + *(sasl_ssf_t **)pvalue= &conn->oparams.mech_ssf; + break; + case SASL_MAXOUTBUF: + *(unsigned **)pvalue = &conn->oparams.maxoutbuf; + break; + case SASL_GETOPTCTX: + result = _sasl_getcallback(conn, SASL_CB_GETOPT, (sasl_callback_ft *)&getopt, &context); + if(result != SASL_OK) break; + + *(void **)pvalue = context; + break; + case SASL_CALLBACK: + *(const sasl_callback_t **)pvalue = conn->callbacks; + break; + case SASL_IPLOCALPORT: + if(conn->got_ip_local) + *(const char **)pvalue = conn->iplocalport; + else { + *(const char **)pvalue = NULL; + result = SASL_NOTDONE; + } + break; + case SASL_IPREMOTEPORT: + if(conn->got_ip_remote) + *(const char **)pvalue = conn->ipremoteport; + else { + *(const char **)pvalue = NULL; + result = SASL_NOTDONE; + } + break; + case SASL_USERNAME: + if(! conn->oparams.user) + result = SASL_NOTDONE; + else + *((const char **)pvalue) = conn->oparams.user; + break; + case SASL_AUTHUSER: + if(! conn->oparams.authid) + result = SASL_NOTDONE; + else + *((const char **)pvalue) = conn->oparams.authid; + break; + case SASL_APPNAME: + /* Currently we only support server side contexts, but we should + be able to extend this to support client side contexts as well */ + if(conn->type != SASL_CONN_SERVER) result = SASL_BADPROT; + else + *((const char **)pvalue) = ((sasl_server_conn_t *)conn)->sparams->appname; + break; + case SASL_SERVERFQDN: + *((const char **)pvalue) = conn->serverFQDN; + break; + case SASL_DEFUSERREALM: + if(conn->type != SASL_CONN_SERVER) result = SASL_BADPROT; + else + *((const char **)pvalue) = ((sasl_server_conn_t *)conn)->user_realm; + break; + case SASL_SERVICE: + *((const char **)pvalue) = conn->service; + break; + case SASL_AUTHSOURCE: /* name of plugin (not name of mech) */ + if(conn->type == SASL_CONN_CLIENT) { + if(!((sasl_client_conn_t *)conn)->mech) { + result = SASL_NOTDONE; + break; + } + *((const char **)pvalue) = + ((sasl_client_conn_t *)conn)->mech->m.plugname; + } else if (conn->type == SASL_CONN_SERVER) { + if(!((sasl_server_conn_t *)conn)->mech) { + result = SASL_NOTDONE; + break; + } + *((const char **)pvalue) = + ((sasl_server_conn_t *)conn)->mech->m.plugname; + } else { + result = SASL_BADPARAM; + } + break; + case SASL_MECHNAME: /* name of mech */ + if(conn->type == SASL_CONN_CLIENT) { + if(!((sasl_client_conn_t *)conn)->mech) { + result = SASL_NOTDONE; + break; + } + *((const char **)pvalue) = + ((sasl_client_conn_t *)conn)->mech->m.plug->mech_name; + } else if (conn->type == SASL_CONN_SERVER) { + if(!((sasl_server_conn_t *)conn)->mech) { + result = SASL_NOTDONE; + break; + } + *((const char **)pvalue) = + ((sasl_server_conn_t *)conn)->mech->m.plug->mech_name; + } else { + result = SASL_BADPARAM; + } + + if(!(*pvalue) && result == SASL_OK) result = SASL_NOTDONE; + break; + case SASL_PLUGERR: + *((const char **)pvalue) = conn->error_buf; + break; + case SASL_DELEGATEDCREDS: + /* We can't really distinguish between "no delegated credentials" + and "authentication not finished" */ + if(! conn->oparams.client_creds) + result = SASL_NOTDONE; + else + *((const char **)pvalue) = conn->oparams.client_creds; + break; + case SASL_GSS_PEER_NAME: + if(! conn->oparams.gss_peer_name) + result = SASL_NOTDONE; + else + *((const char **)pvalue) = conn->oparams.gss_peer_name; + break; + case SASL_GSS_LOCAL_NAME: + if(! conn->oparams.gss_peer_name) + result = SASL_NOTDONE; + else + *((const char **)pvalue) = conn->oparams.gss_local_name; + break; + case SASL_SSF_EXTERNAL: + *((const sasl_ssf_t **)pvalue) = &conn->external.ssf; + break; + case SASL_AUTH_EXTERNAL: + *((const char **)pvalue) = conn->external.auth_id; + break; + case SASL_SEC_PROPS: + *((const sasl_security_properties_t **)pvalue) = &conn->props; + break; + case SASL_GSS_CREDS: + if(conn->type == SASL_CONN_CLIENT) + *(void **)pvalue = + ((sasl_client_conn_t *)conn)->cparams->gss_creds; + else + *(void **)pvalue = + ((sasl_server_conn_t *)conn)->sparams->gss_creds; + break; + case SASL_HTTP_REQUEST: { + if (conn->type == SASL_CONN_SERVER) + *(const sasl_http_request_t **)pvalue = + ((sasl_server_conn_t *)conn)->sparams->http_request; + else + *(const sasl_http_request_t **)pvalue = + ((sasl_client_conn_t *)conn)->cparams->http_request; + break; + } + default: + result = SASL_BADPARAM; + } + + if(result == SASL_BADPARAM) { + PARAMERROR(conn); + } else if(result == SASL_NOTDONE) { + sasl_seterror(conn, SASL_NOLOG, + "Information that was requested is not yet available."); + RETURN(conn, result); + } else if(result != SASL_OK) { + INTERROR(conn, result); + } else + RETURN(conn, result); +} + +/* set property in SASL connection state + * returns: + * SASL_OK -- value set + * SASL_BADPARAM -- invalid property or value + */ +int sasl_setprop(sasl_conn_t *conn, int propnum, const void *value) +{ + int result = SASL_OK; + char *str; + + /* make sure the sasl context is valid */ + if (!conn) + return SASL_BADPARAM; + + switch(propnum) + { + case SASL_SSF_EXTERNAL: + conn->external.ssf = *((sasl_ssf_t *)value); + if(conn->type == SASL_CONN_SERVER) { + ((sasl_server_conn_t*)conn)->sparams->external_ssf = + conn->external.ssf; + } else { + ((sasl_client_conn_t*)conn)->cparams->external_ssf = + conn->external.ssf; + } + break; + + case SASL_AUTH_EXTERNAL: + if(value && strlen(value)) { + result = _sasl_strdup(value, &str, NULL); + if(result != SASL_OK) MEMERROR(conn); + } else { + str = NULL; + } + + if(conn->external.auth_id) + sasl_FREE(conn->external.auth_id); + + conn->external.auth_id = str; + + break; + + case SASL_DEFUSERREALM: + if(conn->type != SASL_CONN_SERVER) { + sasl_seterror(conn, 0, "Tried to set realm on non-server connection"); + result = SASL_BADPROT; + break; + } + + if(value && strlen(value)) { + result = _sasl_strdup(value, &str, NULL); + if(result != SASL_OK) MEMERROR(conn); + } else { + PARAMERROR(conn); + } + + if(((sasl_server_conn_t *)conn)->user_realm) + sasl_FREE(((sasl_server_conn_t *)conn)->user_realm); + + ((sasl_server_conn_t *)conn)->user_realm = str; + ((sasl_server_conn_t *)conn)->sparams->user_realm = str; + + break; + + case SASL_SEC_PROPS: + { + sasl_security_properties_t *props = (sasl_security_properties_t *)value; + + if(props->maxbufsize == 0 && props->min_ssf != 0) { + sasl_seterror(conn, 0, + "Attempt to disable security layers (maxoutbuf == 0) with min_ssf > 0"); + RETURN(conn, SASL_TOOWEAK); + } + + conn->props = *props; + + if(conn->type == SASL_CONN_SERVER) { + ((sasl_server_conn_t*)conn)->sparams->props = *props; + } else { + ((sasl_client_conn_t*)conn)->cparams->props = *props; + } + + break; + } + + case SASL_IPREMOTEPORT: + { + const char *ipremoteport = (const char *)value; + if(!value) { + conn->got_ip_remote = 0; + } else if (_sasl_ipfromstring(ipremoteport, NULL, 0) + != SASL_OK) { + sasl_seterror(conn, 0, "Bad IPREMOTEPORT value"); + RETURN(conn, SASL_BADPARAM); + } else { + strcpy(conn->ipremoteport, ipremoteport); + conn->got_ip_remote = 1; + } + + if(conn->got_ip_remote) { + if(conn->type == SASL_CONN_CLIENT) { + ((sasl_client_conn_t *)conn)->cparams->ipremoteport + = conn->ipremoteport; + ((sasl_client_conn_t *)conn)->cparams->ipremlen = + (unsigned) strlen(conn->ipremoteport); + } else if (conn->type == SASL_CONN_SERVER) { + ((sasl_server_conn_t *)conn)->sparams->ipremoteport + = conn->ipremoteport; + ((sasl_server_conn_t *)conn)->sparams->ipremlen = + (unsigned) strlen(conn->ipremoteport); + } + } else { + if(conn->type == SASL_CONN_CLIENT) { + ((sasl_client_conn_t *)conn)->cparams->ipremoteport + = NULL; + ((sasl_client_conn_t *)conn)->cparams->ipremlen = 0; + } else if (conn->type == SASL_CONN_SERVER) { + ((sasl_server_conn_t *)conn)->sparams->ipremoteport + = NULL; + ((sasl_server_conn_t *)conn)->sparams->ipremlen = 0; + } + } + + break; + } + + case SASL_IPLOCALPORT: + { + const char *iplocalport = (const char *)value; + if(!value) { + conn->got_ip_local = 0; + } else if (_sasl_ipfromstring(iplocalport, NULL, 0) + != SASL_OK) { + sasl_seterror(conn, 0, "Bad IPLOCALPORT value"); + RETURN(conn, SASL_BADPARAM); + } else { + strcpy(conn->iplocalport, iplocalport); + conn->got_ip_local = 1; + } + + if(conn->got_ip_local) { + if(conn->type == SASL_CONN_CLIENT) { + ((sasl_client_conn_t *)conn)->cparams->iplocalport + = conn->iplocalport; + ((sasl_client_conn_t *)conn)->cparams->iploclen + = (unsigned) strlen(conn->iplocalport); + } else if (conn->type == SASL_CONN_SERVER) { + ((sasl_server_conn_t *)conn)->sparams->iplocalport + = conn->iplocalport; + ((sasl_server_conn_t *)conn)->sparams->iploclen + = (unsigned) strlen(conn->iplocalport); + } + } else { + if(conn->type == SASL_CONN_CLIENT) { + ((sasl_client_conn_t *)conn)->cparams->iplocalport + = NULL; + ((sasl_client_conn_t *)conn)->cparams->iploclen = 0; + } else if (conn->type == SASL_CONN_SERVER) { + ((sasl_server_conn_t *)conn)->sparams->iplocalport + = NULL; + ((sasl_server_conn_t *)conn)->sparams->iploclen = 0; + } + } + break; + } + + case SASL_APPNAME: + /* Currently we only support server side contexts, but we should + be able to extend this to support client side contexts as well */ + if(conn->type != SASL_CONN_SERVER) { + sasl_seterror(conn, 0, "Tried to set application name on non-server connection"); + result = SASL_BADPROT; + break; + } + + if(((sasl_server_conn_t *)conn)->appname) { + sasl_FREE(((sasl_server_conn_t *)conn)->appname); + ((sasl_server_conn_t *)conn)->appname = NULL; + } + + if(value && strlen(value)) { + result = _sasl_strdup(value, + &(((sasl_server_conn_t *)conn)->appname), + NULL); + if(result != SASL_OK) MEMERROR(conn); + ((sasl_server_conn_t *)conn)->sparams->appname = + ((sasl_server_conn_t *)conn)->appname; + ((sasl_server_conn_t *)conn)->sparams->applen = + (unsigned) strlen(((sasl_server_conn_t *)conn)->appname); + } else { + ((sasl_server_conn_t *)conn)->sparams->appname = NULL; + ((sasl_server_conn_t *)conn)->sparams->applen = 0; + } + break; + + case SASL_GSS_CREDS: + if(conn->type == SASL_CONN_CLIENT) + ((sasl_client_conn_t *)conn)->cparams->gss_creds = value; + else + ((sasl_server_conn_t *)conn)->sparams->gss_creds = value; + break; + + case SASL_CHANNEL_BINDING: { + const struct sasl_channel_binding *cb = (const struct sasl_channel_binding *)value; + + if (conn->type == SASL_CONN_SERVER) + ((sasl_server_conn_t *)conn)->sparams->cbinding = cb; + else + ((sasl_client_conn_t *)conn)->cparams->cbinding = cb; + break; + } + + case SASL_HTTP_REQUEST: { + const sasl_http_request_t *req = (const sasl_http_request_t *)value; + + if (conn->type == SASL_CONN_SERVER) + ((sasl_server_conn_t *)conn)->sparams->http_request = req; + else + ((sasl_client_conn_t *)conn)->cparams->http_request = req; + break; + } + + default: + sasl_seterror(conn, 0, "Unknown parameter type"); + result = SASL_BADPARAM; + } + + RETURN(conn, result); +} + +/* this is apparently no longer a user function */ +static int sasl_usererr(int saslerr) +{ + /* Hide the difference in a username failure and a password failure */ + if (saslerr == SASL_NOUSER) + return SASL_BADAUTH; + + /* otherwise return the error given; no transform necessary */ + return saslerr; +} + +const char *sasl_errstring(int saslerr, + const char *langlist __attribute__((unused)), + const char **outlang) +{ + if (outlang) *outlang="en-us"; + + switch(saslerr) + { + case SASL_CONTINUE: return "another step is needed in authentication"; + case SASL_OK: return "successful result"; + case SASL_FAIL: return "generic failure"; + case SASL_NOMEM: return "no memory available"; + case SASL_BUFOVER: return "overflowed buffer"; + case SASL_NOMECH: return "no mechanism available"; + case SASL_BADPROT: return "bad protocol / cancel"; + case SASL_NOTDONE: return "can't request information until later in exchange"; + case SASL_BADPARAM: return "invalid parameter supplied"; + case SASL_TRYAGAIN: return "transient failure (e.g., weak key)"; + case SASL_BADMAC: return "integrity check failed"; + case SASL_NOTINIT: return "SASL library is not initialized"; + /* -- client only codes -- */ + case SASL_INTERACT: return "needs user interaction"; + case SASL_BADSERV: return "server failed mutual authentication step"; + case SASL_WRONGMECH: return "mechanism doesn't support requested feature"; + /* -- server only codes -- */ + case SASL_BADAUTH: return "authentication failure"; + case SASL_NOAUTHZ: return "authorization failure"; + case SASL_TOOWEAK: return "mechanism too weak for this user"; + case SASL_ENCRYPT: return "encryption needed to use mechanism"; + case SASL_TRANS: return "One time use of a plaintext password will enable requested mechanism for user"; + case SASL_EXPIRED: return "passphrase expired, has to be reset"; + case SASL_DISABLED: return "account disabled"; + case SASL_NOUSER: return "user not found"; + case SASL_BADVERS: return "version mismatch with plug-in"; + case SASL_UNAVAIL: return "remote authentication server unavailable"; + case SASL_NOVERIFY: return "user exists, but no verifier for user"; + case SASL_PWLOCK: return "passphrase locked"; + case SASL_NOCHANGE: return "requested change was not needed"; + case SASL_WEAKPASS: return "passphrase is too weak for security policy"; + case SASL_NOUSERPASS: return "user supplied passwords are not permitted"; + case SASL_NEED_OLD_PASSWD: return "sasl_setpass needs old password in order " + "to perform password change"; + case SASL_CONSTRAINT_VIOLAT: return "sasl_setpass can't store a property because " + "of a constraint violation"; + case SASL_BADBINDING: return "channel binding failure"; + + default: return "undefined error!"; + } + +} + +/* Return the sanitized error detail about the last error that occured for + * a connection */ +const char *sasl_errdetail(sasl_conn_t *conn) +{ + unsigned need_len; + const char *errstr; + char leader[128]; + + if(!conn) return NULL; + + errstr = sasl_errstring(conn->error_code, NULL, NULL); + snprintf(leader,128,"SASL(%d): %s: ", + sasl_usererr(conn->error_code), errstr); + + need_len = (unsigned) (strlen(leader) + strlen(conn->error_buf) + 12); + _buf_alloc(&conn->errdetail_buf, &conn->errdetail_buf_len, need_len); + + snprintf(conn->errdetail_buf, need_len, "%s%s", leader, conn->error_buf); + + return conn->errdetail_buf; +} + + +/* Note that this needs the global callbacks, so if you don't give getcallbacks + * a sasl_conn_t, you're going to need to pass it yourself (or else we couldn't + * have client and server at the same time */ +static int _sasl_global_getopt(void *context, + const char *plugin_name, + const char *option, + const char ** result, + unsigned *len) +{ + const sasl_global_callbacks_t * global_callbacks; + const sasl_callback_t *callback; + + global_callbacks = (const sasl_global_callbacks_t *) context; + + if (global_callbacks && global_callbacks->callbacks) { + for (callback = global_callbacks->callbacks; + callback->id != SASL_CB_LIST_END; + callback++) { + if (callback->id == SASL_CB_GETOPT) { + if (!callback->proc) return SASL_FAIL; + if (((sasl_getopt_t *)(callback->proc))(callback->context, + plugin_name, + option, + result, + len) + == SASL_OK) + return SASL_OK; + } + } + } + + /* look it up in our configuration file */ + *result = sasl_config_getstring(option, NULL); + if (*result != NULL) { + if (len) { *len = (unsigned) strlen(*result); } + return SASL_OK; + } + + return SASL_FAIL; +} + +static int +_sasl_conn_getopt(void *context, + const char *plugin_name, + const char *option, + const char ** result, + unsigned *len) +{ + sasl_conn_t * conn; + const sasl_callback_t *callback; + + if (! context) + return SASL_BADPARAM; + + conn = (sasl_conn_t *) context; + + if (conn->callbacks) + for (callback = conn->callbacks; + callback->id != SASL_CB_LIST_END; + callback++) + if (callback->id == SASL_CB_GETOPT + && (((sasl_getopt_t *)(callback->proc))(callback->context, + plugin_name, + option, + result, + len) + == SASL_OK)) + return SASL_OK; + + /* If we made it here, we didn't find an appropriate callback + * in the connection's callback list, or the callback we did + * find didn't return SASL_OK. So we attempt to use the + * global callback for this connection... */ + return _sasl_global_getopt((void *)conn->global_callbacks, + plugin_name, + option, + result, + len); +} + +#ifdef HAVE_SYSLOG +/* this is the default logging */ +static int _sasl_syslog(void *context, + int priority, + const char *message) +{ + int syslog_priority; + sasl_server_conn_t *sconn; + + if (context) { + if (((sasl_conn_t *)context)->type == SASL_CONN_SERVER) { + sconn = (sasl_server_conn_t *)context; + if (sconn->sparams->log_level < priority) + return SASL_OK; + } + } + + /* set syslog priority */ + switch(priority) { + case SASL_LOG_NONE: + return SASL_OK; + break; + case SASL_LOG_ERR: + syslog_priority = LOG_ERR; + break; + case SASL_LOG_WARN: + syslog_priority = LOG_WARNING; + break; + case SASL_LOG_NOTE: + case SASL_LOG_FAIL: + syslog_priority = LOG_NOTICE; + break; + case SASL_LOG_PASS: + case SASL_LOG_TRACE: + case SASL_LOG_DEBUG: + default: + syslog_priority = LOG_DEBUG; + break; + } + + /* do the syslog call. Do not need to call openlog? */ + syslog(syslog_priority | LOG_AUTH, "%s", message); + + return SASL_OK; +} +#endif /* HAVE_SYSLOG */ + +static int +_sasl_getsimple(void *context, + int id, + const char ** result, + size_t *len) +{ + const char *userid; + sasl_conn_t *conn; + + if (! context || ! result) return SASL_BADPARAM; + + conn = (sasl_conn_t *)context; + + switch(id) { + case SASL_CB_AUTHNAME: + userid = getenv("USER"); + if (userid != NULL) { + *result = userid; + if (len) *len = strlen(userid); + return SASL_OK; + } + userid = getenv("USERNAME"); + if (userid != NULL) { + *result = userid; + if (len) *len = strlen(userid); + return SASL_OK; + } +#ifdef WIN32 + /* for win32, try using the GetUserName standard call */ + { + DWORD i; + BOOL rval; + static char sender[128]; + + i = sizeof(sender); + rval = GetUserName(sender, &i); + if ( rval) { /* got a userid */ + *result = sender; + if (len) *len = strlen(sender); + return SASL_OK; + } + } +#endif /* WIN32 */ + return SASL_FAIL; + default: + return SASL_BADPARAM; + } +} + +static int +_sasl_getpath(void *context __attribute__((unused)), + const char ** path_dest) +{ +#if !defined(WIN32) + char *path; +#endif + int res = SASL_OK; + + if (! path_dest) { + return SASL_BADPARAM; + } + + /* Only calculate the path once. */ + if (default_plugin_path == NULL) { + +#if defined(WIN32) + /* NB: On Windows platforms this value is always allocated */ + default_plugin_path = _sasl_get_default_win_path(context, + SASL_PLUGIN_PATH_ATTR, + PLUGINDIR); +#else + /* NB: On Unix platforms this value is never allocated */ + path = _sasl_get_default_unix_path(context, + SASL_PATH_ENV_VAR, + PLUGINDIR); + + res = _sasl_strdup(path, &default_plugin_path, NULL); +#endif + } + + if (res == SASL_OK) { + *path_dest = default_plugin_path; + } + + return res; +} + +static int +_sasl_getpath_simple(void *context __attribute__((unused)), + const char **path) +{ + if (! path) { + return SASL_BADPARAM; + } + + if (default_plugin_path == NULL) { + return SASL_FAIL; + } + + *path = default_plugin_path; + + return SASL_OK; +} + +static int +_sasl_getconfpath(void *context __attribute__((unused)), + char ** path_dest) +{ +#if !defined(WIN32) + char *path; +#endif + int res = SASL_OK; + + if (! path_dest) { + return SASL_BADPARAM; + } + + /* Only calculate the path once. */ + if (default_conf_path == NULL) { + +#if defined(WIN32) + /* NB: On Windows platforms this value is always allocated */ + default_conf_path = _sasl_get_default_win_path(context, + SASL_CONF_PATH_ATTR, + CONFIGDIR); +#else + /* NB: On Unix platforms this value is never allocated */ + path = _sasl_get_default_unix_path(context, + SASL_CONF_PATH_ENV_VAR, + CONFIGDIR); + + res = _sasl_strdup(path, &default_conf_path, NULL); +#endif + } + + if (res == SASL_OK) { + *path_dest = default_conf_path; + } + + return res; +} + +static int +_sasl_getconfpath_simple(void *context __attribute__((unused)), + const char **path) +{ + if (! path) { + return SASL_BADPARAM; + } + + if (default_conf_path == NULL) { + return SASL_FAIL; + } + + *path = default_conf_path; + + return SASL_OK; +} + +static int +_sasl_verifyfile(void *context __attribute__((unused)), + char *file __attribute__((unused)), + int type __attribute__((unused))) +{ + /* always say ok */ + return SASL_OK; +} + + +static int +_sasl_proxy_policy(sasl_conn_t *conn, + void *context __attribute__((unused)), + const char *requested_user, unsigned rlen, + const char *auth_identity, unsigned alen, + const char *def_realm __attribute__((unused)), + unsigned urlen __attribute__((unused)), + struct propctx *propctx __attribute__((unused))) +{ + if (!conn) + return SASL_BADPARAM; + + if (!requested_user || *requested_user == '\0') + return SASL_OK; + + if (!auth_identity || !requested_user || rlen != alen || + (memcmp(auth_identity, requested_user, rlen) != 0)) { + sasl_seterror(conn, 0, + "Requested identity not authenticated identity"); + RETURN(conn, SASL_BADAUTH); + } + + return SASL_OK; +} + +int _sasl_getcallback(sasl_conn_t * conn, + unsigned long callbackid, + sasl_callback_ft *pproc, + void **pcontext) +{ + const sasl_callback_t *callback; + + if (!pproc || !pcontext) + PARAMERROR(conn); + + /* Some callbacks are always provided by the library */ + switch (callbackid) { + case SASL_CB_LIST_END: + /* Nothing ever gets to provide this */ + INTERROR(conn, SASL_FAIL); + case SASL_CB_GETOPT: + if (conn) { + *pproc = (sasl_callback_ft)&_sasl_conn_getopt; + *pcontext = conn; + } else { + *pproc = (sasl_callback_ft)&_sasl_global_getopt; + *pcontext = NULL; + } + return SASL_OK; + } + + /* If it's not always provided by the library, see if there's + * a version provided by the application for this connection... */ + if (conn && conn->callbacks) { + for (callback = conn->callbacks; callback->id != SASL_CB_LIST_END; + callback++) { + if (callback->id == callbackid) { + *pproc = callback->proc; + *pcontext = callback->context; + if (callback->proc) { + return SASL_OK; + } else { + return SASL_INTERACT; + } + } + } + } + + /* And, if not for this connection, see if there's one + * for all {server,client} connections... */ + if (conn && conn->global_callbacks && conn->global_callbacks->callbacks) { + for (callback = conn->global_callbacks->callbacks; + callback->id != SASL_CB_LIST_END; + callback++) { + if (callback->id == callbackid) { + *pproc = callback->proc; + *pcontext = callback->context; + if (callback->proc) { + return SASL_OK; + } else { + return SASL_INTERACT; + } + } + } + } + + /* Otherwise, see if the library provides a default callback. */ + switch (callbackid) { +#ifdef HAVE_SYSLOG + case SASL_CB_LOG: + *pproc = (sasl_callback_ft)&_sasl_syslog; + *pcontext = conn; + return SASL_OK; +#endif /* HAVE_SYSLOG */ + case SASL_CB_GETPATH: + *pproc = default_getpath_cb.proc; + *pcontext = default_getpath_cb.context; + return SASL_OK; + case SASL_CB_GETCONFPATH: + *pproc = default_getconfpath_cb.proc; + *pcontext = default_getconfpath_cb.context; + return SASL_OK; + case SASL_CB_AUTHNAME: + *pproc = (sasl_callback_ft)&_sasl_getsimple; + *pcontext = conn; + return SASL_OK; + case SASL_CB_VERIFYFILE: + *pproc = (sasl_callback_ft)&_sasl_verifyfile; + *pcontext = NULL; + return SASL_OK; + case SASL_CB_PROXY_POLICY: + *pproc = (sasl_callback_ft)&_sasl_proxy_policy; + *pcontext = NULL; + return SASL_OK; + } + + /* Unable to find a callback... */ + *pproc = NULL; + *pcontext = NULL; + sasl_seterror(conn, SASL_NOLOG, "Unable to find a callback: %d", callbackid); + RETURN(conn,SASL_FAIL); +} + + +/* + * This function is typically called from a plugin. + * It creates a string from the formatting and varargs given + * and calls the logging callback (syslog by default) + * + * %m will parse the value in the next argument as an errno string + * %z will parse the next argument as a SASL error code. + */ + +void +_sasl_log (sasl_conn_t *conn, + int level, + const char *fmt, + ...) +{ + char *out=(char *) sasl_ALLOC(250); + size_t alloclen=100; /* current allocated length */ + size_t outlen=0; /* current length of output buffer */ + size_t formatlen; + size_t pos=0; /* current position in format string */ + int result; + sasl_log_t *log_cb; + void *log_ctx; + + int ival; + unsigned int uval; + char *cval; + va_list ap; /* varargs thing */ + + if(!fmt) goto done; + if(!out) return; + + formatlen = strlen(fmt); + + /* See if we have a logging callback... */ + result = _sasl_getcallback(conn, SASL_CB_LOG, (sasl_callback_ft *)&log_cb, &log_ctx); + if (result == SASL_OK && ! log_cb) + result = SASL_FAIL; + if (result != SASL_OK) goto done; + + va_start(ap, fmt); /* start varargs */ + + while(pos9) + done=1; + } + pos++; + if (pos>formatlen) + done=1; + } + + } + } + + /* put 0 at end */ + result = _buf_alloc(&out, &alloclen, outlen+1); + if (result != SASL_OK) goto done; + out[outlen]=0; + + va_end(ap); + + /* send log message */ + result = log_cb(log_ctx, level, out); + + done: + if(out) sasl_FREE(out); +} + + + +/* Allocate and Init a sasl_utils_t structure */ +sasl_utils_t * +_sasl_alloc_utils(sasl_conn_t *conn, + sasl_global_callbacks_t *global_callbacks) +{ + sasl_utils_t *utils; + /* set util functions - need to do rest*/ + utils=sasl_ALLOC(sizeof(sasl_utils_t)); + if (utils==NULL) + return NULL; + + utils->conn = conn; + + sasl_randcreate(&utils->rpool); + + if (conn) { + utils->getopt = &_sasl_conn_getopt; + utils->getopt_context = conn; + } else { + utils->getopt = &_sasl_global_getopt; + utils->getopt_context = global_callbacks; + } + + utils->malloc=_sasl_allocation_utils.malloc; + utils->calloc=_sasl_allocation_utils.calloc; + utils->realloc=_sasl_allocation_utils.realloc; + utils->free=_sasl_allocation_utils.free; + + utils->mutex_alloc = _sasl_mutex_utils.alloc; + utils->mutex_lock = _sasl_mutex_utils.lock; + utils->mutex_unlock = _sasl_mutex_utils.unlock; + utils->mutex_free = _sasl_mutex_utils.free; + + utils->MD5Init = &_sasl_MD5Init; + utils->MD5Update= &_sasl_MD5Update; + utils->MD5Final = &_sasl_MD5Final; + utils->hmac_md5 = &_sasl_hmac_md5; + utils->hmac_md5_init = &_sasl_hmac_md5_init; + utils->hmac_md5_final = &_sasl_hmac_md5_final; + utils->hmac_md5_precalc = &_sasl_hmac_md5_precalc; + utils->hmac_md5_import = &_sasl_hmac_md5_import; + utils->mkchal = &sasl_mkchal; + utils->utf8verify = &sasl_utf8verify; + utils->rand=&sasl_rand; + utils->churn=&sasl_churn; + utils->checkpass=NULL; + + utils->encode64=&sasl_encode64; + utils->decode64=&sasl_decode64; + + utils->erasebuffer=&sasl_erasebuffer; + + utils->getprop=&sasl_getprop; + utils->setprop=&sasl_setprop; + + utils->getcallback=&_sasl_getcallback; + + utils->log=&_sasl_log; + + utils->seterror=&sasl_seterror; + +#ifndef macintosh + /* Aux Property Utilities */ + utils->prop_new=&prop_new; + utils->prop_dup=&prop_dup; + utils->prop_request=&prop_request; + utils->prop_get=&prop_get; + utils->prop_getnames=&prop_getnames; + utils->prop_clear=&prop_clear; + utils->prop_dispose=&prop_dispose; + utils->prop_format=&prop_format; + utils->prop_set=&prop_set; + utils->prop_setvals=&prop_setvals; + utils->prop_erase=&prop_erase; + utils->auxprop_store=&sasl_auxprop_store; +#endif + + /* Spares */ + utils->spare_fptr = NULL; + utils->spare_fptr1 = utils->spare_fptr2 = NULL; + + return utils; +} + +int +_sasl_free_utils(const sasl_utils_t ** utils) +{ + sasl_utils_t *nonconst; + + if(!utils) return SASL_BADPARAM; + if(!*utils) return SASL_OK; + + /* I wish we could avoid this cast, it's pretty gratuitous but it + * does make life easier to have it const everywhere else. */ + nonconst = (sasl_utils_t *)(*utils); + + sasl_randfree(&(nonconst->rpool)); + sasl_FREE(nonconst); + + *utils = NULL; + return SASL_OK; +} + +int sasl_idle(sasl_conn_t *conn) +{ + if (! conn) { + if (_sasl_server_idle_hook + && _sasl_server_idle_hook(NULL)) + return 1; + if (_sasl_client_idle_hook + && _sasl_client_idle_hook(NULL)) + return 1; + return 0; + } + + if (conn->idle_hook) + return conn->idle_hook(conn); + + return 0; +} + +static const sasl_callback_t * +_sasl_find_callback_by_type (const sasl_callback_t *callbacks, + unsigned long id) +{ + if (callbacks) { + while (callbacks->id != SASL_CB_LIST_END) { + if (callbacks->id == id) { + return callbacks; + } else { + ++callbacks; + } + } + } + return NULL; +} + +const sasl_callback_t * +_sasl_find_getpath_callback(const sasl_callback_t *callbacks) +{ + callbacks = _sasl_find_callback_by_type (callbacks, SASL_CB_GETPATH); + if (callbacks != NULL) { + return callbacks; + } else { + return &default_getpath_cb; + } +} + +const sasl_callback_t * +_sasl_find_getconfpath_callback(const sasl_callback_t *callbacks) +{ + callbacks = _sasl_find_callback_by_type (callbacks, SASL_CB_GETCONFPATH); + if (callbacks != NULL) { + return callbacks; + } else { + return &default_getconfpath_cb; + } +} + +const sasl_callback_t * +_sasl_find_verifyfile_callback(const sasl_callback_t *callbacks) +{ + static const sasl_callback_t default_verifyfile_cb = { + SASL_CB_VERIFYFILE, + (sasl_callback_ft)&_sasl_verifyfile, + NULL + }; + + callbacks = _sasl_find_callback_by_type (callbacks, SASL_CB_VERIFYFILE); + if (callbacks != NULL) { + return callbacks; + } else { + return &default_verifyfile_cb; + } +} + +/* Basically a conditional call to realloc(), if we need more */ +int _buf_alloc(char **rwbuf, size_t *curlen, size_t newlen) +{ + if(!(*rwbuf)) { + *rwbuf = sasl_ALLOC((unsigned)newlen); + if (*rwbuf == NULL) { + *curlen = 0; + return SASL_NOMEM; + } + *curlen = newlen; + } else if(*rwbuf && *curlen < newlen) { + size_t needed = 2*(*curlen); + + while(needed < newlen) + needed *= 2; + + /* WARN - We will leak the old buffer on failure */ + *rwbuf = sasl_REALLOC(*rwbuf, (unsigned)needed); + + if (*rwbuf == NULL) { + *curlen = 0; + return SASL_NOMEM; + } + *curlen = needed; + } + + return SASL_OK; +} + +/* for the mac os x cfm glue: this lets the calling function + get pointers to the error buffer without having to touch the sasl_conn_t struct */ +void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, size_t **lenhdl) +{ + *bufhdl = &conn->error_buf; + *lenhdl = &conn->error_buf_len; +} + +/* convert an iovec to a single buffer */ +int _iovec_to_buf(const struct iovec *vec, + unsigned numiov, buffer_info_t **output) +{ + unsigned i; + int ret; + buffer_info_t *out; + char *pos; + + if (!vec || !output) return SASL_BADPARAM; + + if (!(*output)) { + *output = sasl_ALLOC(sizeof(buffer_info_t)); + if (!*output) return SASL_NOMEM; + memset(*output,0,sizeof(buffer_info_t)); + } + + out = *output; + + out->curlen = 0; + for (i = 0; i < numiov; i++) { + out->curlen += vec[i].iov_len; + } + + ret = _buf_alloc(&out->data, &out->reallen, out->curlen); + + if (ret != SASL_OK) return SASL_NOMEM; + + memset(out->data, 0, out->reallen); + pos = out->data; + + for (i = 0; i < numiov; i++) { + memcpy(pos, vec[i].iov_base, vec[i].iov_len); + pos += vec[i].iov_len; + } + + return SASL_OK; +} + +/* This code might be useful in the future, but it isn't now, so.... */ +#if 0 +int _sasl_iptostring(const struct sockaddr *addr, socklen_t addrlen, + char *out, unsigned outlen) { + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; + int niflags; + + if(!addr || !out) return SASL_BADPARAM; + + niflags = (NI_NUMERICHOST | NI_NUMERICSERV); +#ifdef NI_WITHSCOPEID + if (addr->sa_family == AF_INET6) + niflags |= NI_WITHSCOPEID; +#endif + if (getnameinfo(addr, addrlen, hbuf, sizeof(hbuf), pbuf, sizeof(pbuf), + niflags) != 0) + return SASL_BADPARAM; + + if(outlen < strlen(hbuf) + strlen(pbuf) + 2) + return SASL_BUFOVER; + + snprintf(out, outlen, "%s;%s", hbuf, pbuf); + + return SASL_OK; +} +#endif + +int _sasl_ipfromstring(const char *addr, + struct sockaddr *out, socklen_t outlen) +{ + int i, j; + struct addrinfo hints, *ai = NULL; + char hbuf[NI_MAXHOST]; + + /* A NULL out pointer just implies we don't do a copy, just verify it */ + + if(!addr) return SASL_BADPARAM; + + /* Parse the address */ + for (i = 0; addr[i] != '\0' && addr[i] != ';'; i++) { + if (i >= NI_MAXHOST) + return SASL_BADPARAM; + hbuf[i] = addr[i]; + } + hbuf[i] = '\0'; + + if (addr[i] == ';') + i++; + /* XXX: Do we need this check? */ + for (j = i; addr[j] != '\0'; j++) + if (!isdigit((int)(addr[j]))) + return SASL_BADPARAM; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + if (getaddrinfo(hbuf, &addr[i], &hints, &ai) != 0) + return SASL_BADPARAM; + + if (out) { + if (outlen < (socklen_t)ai->ai_addrlen) { + freeaddrinfo(ai); + return SASL_BUFOVER; + } + memcpy(out, ai->ai_addr, ai->ai_addrlen); + } + + freeaddrinfo(ai); + + return SASL_OK; +} + +int _sasl_build_mechlist(void) +{ + int count = 0; + sasl_string_list_t *clist = NULL, *slist = NULL, *olist = NULL; + sasl_string_list_t *p, *q, **last, *p_next; + + clist = _sasl_client_mechs(); + slist = _sasl_server_mechs(); + + if(!clist) { + olist = slist; + } else { + int flag; + + /* append slist to clist, and set olist to clist */ + for(p = slist; p; p = p_next) { + flag = 0; + p_next = p->next; + + last = &clist; + for(q = clist; q; q = q->next) { + if(!strcmp(q->d, p->d)) { + /* They match, set the flag */ + flag = 1; + break; + } + last = &(q->next); + } + + if(!flag) { + *last = p; + p->next = NULL; + } else { + sasl_FREE(p); + } + } + + olist = clist; + } + + if(!olist) { + /* This is not going to be very useful */ + printf ("no olist"); + return SASL_FAIL; + } + + for (p = olist; p; p = p->next) count++; + + if(global_mech_list) { + sasl_FREE(global_mech_list); + global_mech_list = NULL; + } + + global_mech_list = sasl_ALLOC((count + 1) * sizeof(char *)); + if(!global_mech_list) return SASL_NOMEM; + + memset(global_mech_list, 0, (count + 1) * sizeof(char *)); + + count = 0; + for (p = olist; p; p = p_next) { + p_next = p->next; + + global_mech_list[count++] = (char *) p->d; + + sasl_FREE(p); + } + + return SASL_OK; +} + +const char ** sasl_global_listmech(void) +{ + return (const char **)global_mech_list; +} + +int sasl_listmech(sasl_conn_t *conn, + const char *user, + const char *prefix, + const char *sep, + const char *suffix, + const char **result, + unsigned *plen, + int *pcount) +{ + if(!conn) { + return SASL_BADPARAM; + } else if(conn->type == SASL_CONN_SERVER) { + RETURN(conn, _sasl_server_listmech(conn, user, prefix, sep, suffix, + result, plen, pcount)); + } else if (conn->type == SASL_CONN_CLIENT) { + RETURN(conn, _sasl_client_listmech(conn, prefix, sep, suffix, + result, plen, pcount)); + } + + PARAMERROR(conn); +} + +int _sasl_is_equal_mech(const char *req_mech, + const char *plug_mech, + size_t req_mech_len, + int *plus) +{ + size_t n; + + if (req_mech_len > 5 && + strcasecmp(&req_mech[req_mech_len - 5], "-PLUS") == 0) { + n = req_mech_len - 5; + *plus = 1; + } else { + n = req_mech_len; + *plus = 0; + } + + return (strncasecmp(req_mech, plug_mech, n) == 0); +} + +#ifndef WIN32 +static char * +_sasl_get_default_unix_path(void *context __attribute__((unused)), + char * env_var_name, + char * default_value) +{ + char *path = NULL; + + /* Honor external variable only in a safe environment */ + if (getuid() == geteuid() && getgid() == getegid()) { + path = getenv(env_var_name); + } + if (! path) { + path = default_value; + } + + return path; +} + +#else +/* Return NULL on failure */ +static char * +_sasl_get_default_win_path(void *context __attribute__((unused)), + char * reg_attr_name, + char * default_value) +{ + /* Open registry entry, and find all registered SASL libraries. + * + * Registry location: + * + * SOFTWARE\\Carnegie Mellon\\Project Cyrus\\SASL Library + * + * Key - value: + * + * "SearchPath" - value: PATH like (';' delimited) list + * of directories where to search for plugins + * The list may contain references to environment + * variables (e.g. %PATH%). + * + */ + HKEY hKey; + DWORD ret; + DWORD ValueType; /* value type */ + DWORD cbData; /* value size */ + BYTE * ValueData; /* value */ + DWORD cbExpandedData; /* "expanded" value size */ + BYTE * ExpandedValueData; /* "expanded" value */ + char * return_value; /* function return value */ + char * tmp; + + /* Initialization */ + ExpandedValueData = NULL; + ValueData = NULL; + return_value = NULL; + + /* Open the registry */ + ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, + SASL_ROOT_KEY, + 0, + KEY_READ, + &hKey); + + if (ret != ERROR_SUCCESS) { + /* no registry entry */ + (void) _sasl_strdup (default_value, &return_value, NULL); + return return_value; + } + + /* figure out value type and required buffer size */ + /* the size will include space for terminating NUL if required */ + RegQueryValueEx (hKey, + reg_attr_name, + NULL, /* reserved */ + &ValueType, + NULL, + &cbData); + + /* Only accept string related types */ + if (ValueType != REG_EXPAND_SZ && + ValueType != REG_MULTI_SZ && + ValueType != REG_SZ) { + return_value = NULL; + goto CLEANUP; + } + + /* Any high water mark? */ + ValueData = sasl_ALLOC(cbData); + if (ValueData == NULL) { + return_value = NULL; + goto CLEANUP; + }; + + RegQueryValueEx (hKey, + reg_attr_name, + NULL, /* reserved */ + &ValueType, + ValueData, + &cbData); + + switch (ValueType) { + case REG_EXPAND_SZ: + /* : A random starting guess */ + cbExpandedData = cbData + 1024; + ExpandedValueData = sasl_ALLOC(cbExpandedData); + if (ExpandedValueData == NULL) { + return_value = NULL; + goto CLEANUP; + }; + + cbExpandedData = ExpandEnvironmentStrings( + ValueData, + ExpandedValueData, + cbExpandedData); + + if (cbExpandedData == 0) { + /* : GetLastError() contains the reason for failure */ + return_value = NULL; + goto CLEANUP; + } + + /* : Must retry expansion with the bigger buffer */ + if (cbExpandedData > cbData + 1024) { + /* : Memory leak here if can't realloc */ + ExpandedValueData = sasl_REALLOC(ExpandedValueData, cbExpandedData); + if (ExpandedValueData == NULL) { + return_value = NULL; + goto CLEANUP; + }; + + cbExpandedData = ExpandEnvironmentStrings( + ValueData, + ExpandedValueData, + cbExpandedData); + + /* : This should not happen */ + if (cbExpandedData == 0) { + /* : GetLastError() contains the reason for failure */ + return_value = NULL; + goto CLEANUP; + } + } + + sasl_FREE(ValueData); + ValueData = ExpandedValueData; + /* : This is to prevent automatical freeing of this block on cleanup */ + ExpandedValueData = NULL; + + break; + + case REG_MULTI_SZ: + tmp = ValueData; + + /* : We shouldn't overflow here, as the buffer is guarantied + : to contain at least two consequent NULs */ + while (1) { + if (tmp[0] == '\0') { + /* : Stop the process if we found the end of the string (two consequent NULs) */ + if (tmp[1] == '\0') { + break; + } + + /* : Replace delimiting NUL with our delimiter characted */ + tmp[0] = PATHS_DELIMITER; + } + tmp += strlen(tmp); + } + break; + + case REG_SZ: + /* Do nothing, it is good as is */ + break; + + default: + return_value = NULL; + goto CLEANUP; + } + + return_value = ValueData; + +CLEANUP: + RegCloseKey(hKey); + if (ExpandedValueData != NULL) sasl_FREE(ExpandedValueData); + if (return_value == NULL) { + if (ValueData != NULL) sasl_FREE(ValueData); + } + + return (return_value); +} +#endif diff --git a/libs/cyrussasl/lib/config.c b/libs/cyrussasl/lib/config.c new file mode 100644 index 00000000..7cae3020 --- /dev/null +++ b/libs/cyrussasl/lib/config.c @@ -0,0 +1,168 @@ +/* SASL Config file API + * Rob Siemborski + * Tim Martin (originally in Cyrus distribution) + * $Id: config.c,v 1.19 2011/11/08 17:22:40 murch Exp $ + */ +/* + * Copyright (c) 1998-2009 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include "sasl.h" +#include "saslint.h" + +struct configlist { + char *key; + char *value; +}; + +static struct configlist *configlist = NULL; +static int nconfiglist = 0; + +#define CONFIGLISTGROWSIZE 100 + +int sasl_config_init(const char *filename) +{ + FILE *infile; + int lineno = 0; + int alloced = 0; + char buf[4096]; + char *p, *key; + char *tail; + int result; + + nconfiglist=0; + + infile = fopen(filename, "r"); + if (!infile) { + return SASL_CONTINUE; + } + + while (fgets(buf, sizeof(buf), infile)) { + lineno++; + + if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; + for (p = buf; *p && isspace((int) *p); p++); + if (!*p || *p == '#') continue; + + key = p; + while (*p && (isalnum((int) *p) || *p == '-' || *p == '_')) { + if (isupper((int) *p)) *p = (char) tolower(*p); + p++; + } + if (*p != ':') { + fclose(infile); + return SASL_FAIL; + } + *p++ = '\0'; + + while (*p && isspace((int) *p)) p++; + + if (!*p) { + fclose(infile); + return SASL_FAIL; + } + + /* Now strip trailing spaces, if any */ + tail = p + strlen(p) - 1; + while (tail > p && isspace((int) *tail)) { + *tail = '\0'; + tail--; + } + + if (nconfiglist == alloced) { + alloced += CONFIGLISTGROWSIZE; + configlist=sasl_REALLOC((char *)configlist, + alloced * sizeof(struct configlist)); + if (configlist == NULL) { + fclose(infile); + return SASL_NOMEM; + } + } + + result = _sasl_strdup(key, + &(configlist[nconfiglist].key), + NULL); + if (result != SASL_OK) { + fclose(infile); + return result; + } + result = _sasl_strdup(p, + &(configlist[nconfiglist].value), + NULL); + if (result != SASL_OK) { + fclose(infile); + return result; + } + + nconfiglist++; + } + fclose(infile); + + return SASL_OK; +} + +const char *sasl_config_getstring(const char *key,const char *def) +{ + int opt; + + for (opt = 0; opt < nconfiglist; opt++) { + if (*key == configlist[opt].key[0] && + !strcmp(key, configlist[opt].key)) + return configlist[opt].value; + } + return def; +} + +void sasl_config_done(void) +{ + int opt; + + for (opt = 0; opt < nconfiglist; opt++) { + if (configlist[opt].key) sasl_FREE(configlist[opt].key); + if (configlist[opt].value) sasl_FREE(configlist[opt].value); + } + + sasl_FREE(configlist); + configlist = NULL; + nconfiglist = 0; +} diff --git a/libs/cyrussasl/lib/dlopen.c b/libs/cyrussasl/lib/dlopen.c new file mode 100644 index 00000000..b9c1c800 --- /dev/null +++ b/libs/cyrussasl/lib/dlopen.c @@ -0,0 +1,562 @@ +/* dlopen.c--Unix dlopen() dynamic loader interface + * Rob Siemborski + * Rob Earhart + * $Id: dlopen.c,v 1.52 2009/04/11 10:21:43 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#ifdef HAVE_DLFCN_H +#include +#endif + +#include +#include +#include +#include + +#include +#include "saslint.h" + +#ifndef PIC +#include +#include "staticopen.h" +#endif + +#ifdef DO_DLOPEN +#if HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +#else /* HAVE_DIRENT_H */ +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +#endif /* ! HAVE_DIRENT_H */ + +#ifndef NAME_MAX +# ifdef _POSIX_NAME_MAX +# define NAME_MAX _POSIX_NAME_MAX +# else +# define NAME_MAX 16 +# endif +#endif + +#if NAME_MAX < 8 +# define NAME_MAX 8 +#endif + +#ifdef __hpux +#ifndef HAVE_DLFCN_H +#include + +typedef shl_t * dll_handle; +typedef void * dll_func; + +dll_handle +dlopen(char *fname, int mode) +{ + shl_t h = shl_load(fname, BIND_DEFERRED, 0L); + shl_t *hp = NULL; + + if (h) { + hp = (shl_t *)malloc(sizeof (shl_t)); + if (!hp) { + shl_unload(h); + } else { + *hp = h; + } + } + + return (dll_handle)hp; +} + +int +dlclose(dll_handle hp) +{ + shl_t h; + + if (hp != NULL) { + h = *((shl_t *)hp); + free(hp); + return shl_unload(h); + } else { + /* Return error */ + return -1; + } +} + +dll_func +dlsym(dll_handle h, char *n) +{ + dll_func handle; + + if (shl_findsym ((shl_t *)h, n, TYPE_PROCEDURE, &handle)) + return NULL; + + return (dll_func)handle; +} + +char *dlerror() +{ + if (errno != 0) { + return strerror(errno); + } + return "Generic shared library error"; +} + +#endif /* HAVE_DLFCN_H */ + +#ifdef __ia64 +#define SO_SUFFIX ".so" +#else +#define SO_SUFFIX ".sl" +#endif /* __ia64 */ +#elif defined(__APPLE__) +#define SO_SUFFIX ".plugin" +#else /* __APPLE__ */ +#define SO_SUFFIX ".so" +#endif + +#define LA_SUFFIX ".la" + +typedef struct lib_list +{ + struct lib_list *next; + void *library; +} lib_list_t; + +static lib_list_t *lib_list_head = NULL; + +#endif /* DO_DLOPEN */ + +int _sasl_locate_entry(void *library, const char *entryname, + void **entry_point) +{ +#ifdef DO_DLOPEN +/* note that we still check for known problem systems in + * case we are cross-compiling */ +#if defined(DLSYM_NEEDS_UNDERSCORE) || (defined(__OpenBSD__) && !defined(__ELF__)) + char adj_entryname[1024]; +#else +#define adj_entryname entryname +#endif + + if(!entryname) { + _sasl_log(NULL, SASL_LOG_ERR, + "no entryname in _sasl_locate_entry"); + return SASL_BADPARAM; + } + + if(!library) { + _sasl_log(NULL, SASL_LOG_ERR, + "no library in _sasl_locate_entry"); + return SASL_BADPARAM; + } + + if(!entry_point) { + _sasl_log(NULL, SASL_LOG_ERR, + "no entrypoint output pointer in _sasl_locate_entry"); + return SASL_BADPARAM; + } + +#if defined(DLSYM_NEEDS_UNDERSCORE) || (defined(__OpenBSD__) && !defined(__ELF__)) + snprintf(adj_entryname, sizeof adj_entryname, "_%s", entryname); +#endif + + *entry_point = NULL; + *entry_point = dlsym(library, adj_entryname); + if (*entry_point == NULL) { +#if 0 /* This message appears to confuse people */ + _sasl_log(NULL, SASL_LOG_DEBUG, + "unable to get entry point %s: %s", adj_entryname, + dlerror()); +#endif + return SASL_FAIL; + } + + return SASL_OK; +#else + return SASL_FAIL; +#endif /* DO_DLOPEN */ +} + +#ifdef DO_DLOPEN + +static int _sasl_plugin_load(char *plugin, void *library, + const char *entryname, + int (*add_plugin)(const char *, void *)) +{ + void *entry_point; + int result; + + result = _sasl_locate_entry(library, entryname, &entry_point); + if(result == SASL_OK) { + result = add_plugin(plugin, entry_point); + if(result != SASL_OK) + _sasl_log(NULL, SASL_LOG_DEBUG, + "_sasl_plugin_load failed on %s for plugin: %s\n", + entryname, plugin); + } + + return result; +} + +/* this returns the file to actually open. + * out should be a buffer of size PATH_MAX + * and may be the same as in. */ + +/* We'll use a static buffer for speed unless someone complains */ +#define MAX_LINE 2048 + +static int _parse_la(const char *prefix, const char *in, char *out) +{ + FILE *file; + size_t length; + char line[MAX_LINE]; + char *ntmp = NULL; + + if(!in || !out || !prefix || out == in) return SASL_BADPARAM; + + /* Set this so we can detect failure */ + *out = '\0'; + + length = strlen(in); + + if (strcmp(in + (length - strlen(LA_SUFFIX)), LA_SUFFIX)) { + if(!strcmp(in + (length - strlen(SO_SUFFIX)),SO_SUFFIX)) { + /* check for a .la file */ + strcpy(line, prefix); + strcat(line, in); + length = strlen(line); + *(line + (length - strlen(SO_SUFFIX))) = '\0'; + strcat(line, LA_SUFFIX); + file = fopen(line, "r"); + if(file) { + /* We'll get it on the .la open */ + fclose(file); + return SASL_FAIL; + } + } + strcpy(out, prefix); + strcat(out, in); + return SASL_OK; + } + + strcpy(line, prefix); + strcat(line, in); + + file = fopen(line, "r"); + if(!file) { + _sasl_log(NULL, SASL_LOG_WARN, + "unable to open LA file: %s", line); + return SASL_FAIL; + } + + while(!feof(file)) { + if(!fgets(line, MAX_LINE, file)) break; + if(line[strlen(line) - 1] != '\n') { + _sasl_log(NULL, SASL_LOG_WARN, + "LA file has too long of a line: %s", in); + return SASL_BUFOVER; + } + if(line[0] == '\n' || line[0] == '#') continue; + if(!strncmp(line, "dlname=", sizeof("dlname=") - 1)) { + /* We found the line with the name in it */ + char *end; + char *start; + size_t len; + end = strrchr(line, '\''); + if(!end) continue; + start = &line[sizeof("dlname=")-1]; + len = strlen(start); + if(len > 3 && start[0] == '\'') { + ntmp=&start[1]; + *end='\0'; + /* Do we have dlname="" ? */ + if(ntmp == end) { + _sasl_log(NULL, SASL_LOG_DEBUG, + "dlname is empty in .la file: %s", in); + return SASL_FAIL; + } + strcpy(out, prefix); + strcat(out, ntmp); + } + break; + } + } + if(ferror(file) || feof(file)) { + _sasl_log(NULL, SASL_LOG_WARN, + "Error reading .la: %s\n", in); + fclose(file); + return SASL_FAIL; + } + fclose(file); + + if(!(*out)) { + _sasl_log(NULL, SASL_LOG_WARN, + "Could not find a dlname line in .la file: %s", in); + return SASL_FAIL; + } + + return SASL_OK; +} +#endif /* DO_DLOPEN */ + +/* loads a plugin library */ +int _sasl_get_plugin(const char *file, + const sasl_callback_t *verifyfile_cb, + void **libraryptr) +{ +#ifdef DO_DLOPEN + int r = 0; + int flag; + void *library; + lib_list_t *newhead; + + r = ((sasl_verifyfile_t *)(verifyfile_cb->proc)) + (verifyfile_cb->context, file, SASL_VRFY_PLUGIN); + if (r != SASL_OK) return r; + +#ifdef RTLD_NOW + flag = RTLD_NOW; +#else + flag = 0; +#endif + + newhead = sasl_ALLOC(sizeof(lib_list_t)); + if(!newhead) return SASL_NOMEM; + + if (!(library = dlopen(file, flag))) { + _sasl_log(NULL, SASL_LOG_ERR, + "unable to dlopen %s: %s", file, dlerror()); + sasl_FREE(newhead); + return SASL_FAIL; + } + + newhead->library = library; + newhead->next = lib_list_head; + lib_list_head = newhead; + + *libraryptr = library; + return SASL_OK; +#else + return SASL_FAIL; +#endif /* DO_DLOPEN */ +} + +/* gets the list of mechanisms */ +int _sasl_load_plugins(const add_plugin_list_t *entrypoints, + const sasl_callback_t *getpath_cb, + const sasl_callback_t *verifyfile_cb) +{ + int result; + const add_plugin_list_t *cur_ep; +#ifdef DO_DLOPEN + char str[PATH_MAX], tmp[PATH_MAX+2], prefix[PATH_MAX+2]; + /* 1 for '/' 1 for trailing '\0' */ + char c; + int pos; + const char *path=NULL; + int position; + DIR *dp; + struct dirent *dir; +#endif +#ifndef PIC + add_plugin_t *add_plugin; + _sasl_plug_type type; + _sasl_plug_rec *p; +#endif + + if (! entrypoints + || ! getpath_cb + || getpath_cb->id != SASL_CB_GETPATH + || ! getpath_cb->proc + || ! verifyfile_cb + || verifyfile_cb->id != SASL_CB_VERIFYFILE + || ! verifyfile_cb->proc) + return SASL_BADPARAM; + +#ifndef PIC + /* do all the static plugins first */ + + for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) { + + /* What type of plugin are we looking for? */ + if(!strcmp(cur_ep->entryname, "sasl_server_plug_init")) { + type = SERVER; + add_plugin = (add_plugin_t *)sasl_server_add_plugin; + } else if (!strcmp(cur_ep->entryname, "sasl_client_plug_init")) { + type = CLIENT; + add_plugin = (add_plugin_t *)sasl_client_add_plugin; + } else if (!strcmp(cur_ep->entryname, "sasl_auxprop_plug_init")) { + type = AUXPROP; + add_plugin = (add_plugin_t *)sasl_auxprop_add_plugin; + } else if (!strcmp(cur_ep->entryname, "sasl_canonuser_init")) { + type = CANONUSER; + add_plugin = (add_plugin_t *)sasl_canonuser_add_plugin; + } else { + /* What are we looking for then? */ + return SASL_FAIL; + } + for (p=_sasl_static_plugins; p->type; p++) { + if(type == p->type) + result = add_plugin(p->name, p->plug); + } + } +#endif /* !PIC */ + +/* only do the following if: + * + * we support dlopen() + * AND we are not staticly compiled + * OR we are staticly compiled and TRY_DLOPEN_WHEN_STATIC is defined + */ +#if defined(DO_DLOPEN) && (defined(PIC) || (!defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC))) + /* get the path to the plugins */ + result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context, + &path); + if (result != SASL_OK) return result; + if (! path) return SASL_FAIL; + + if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */ + return SASL_FAIL; + } + + position=0; + do { + pos=0; + do { + c=path[position]; + position++; + str[pos]=c; + pos++; + } while ((c!=':') && (c!='=') && (c!=0)); + str[pos-1]='\0'; + + strcpy(prefix,str); + strcat(prefix,"/"); + + if ((dp=opendir(str)) !=NULL) /* ignore errors */ + { + while ((dir=readdir(dp)) != NULL) + { + size_t length; + void *library; + char *c; + char plugname[PATH_MAX]; + char name[PATH_MAX]; + + length = NAMLEN(dir); + if (length < 4) + continue; /* can not possibly be what we're looking for */ + + if (length + pos>=PATH_MAX) continue; /* too big */ + + if (strcmp(dir->d_name + (length - strlen(SO_SUFFIX)), + SO_SUFFIX) + && strcmp(dir->d_name + (length - strlen(LA_SUFFIX)), + LA_SUFFIX)) + continue; + + memcpy(name,dir->d_name,length); + name[length]='\0'; + + result = _parse_la(prefix, name, tmp); + if(result != SASL_OK) + continue; + + /* skip "lib" and cut off suffix -- + this only need be approximate */ + strcpy(plugname, name + 3); + c = strchr(plugname, (int)'.'); + if(c) *c = '\0'; + + result = _sasl_get_plugin(tmp, verifyfile_cb, &library); + + if(result != SASL_OK) + continue; + + for(cur_ep = entrypoints; cur_ep->entryname; cur_ep++) { + _sasl_plugin_load(plugname, library, cur_ep->entryname, + cur_ep->add_plugin); + /* If this fails, it's not the end of the world */ + } + } + + closedir(dp); + } else { + _sasl_log(NULL, SASL_LOG_DEBUG, + "looking for plugins in '%s', failed to open directory, error: %s", + str, + strerror(errno)); + } + + } while ((c!='=') && (c!=0)); +#endif /* defined(DO_DLOPEN) && (!defined(PIC) || (defined(PIC) && defined(TRY_DLOPEN_WHEN_STATIC))) */ + + return SASL_OK; +} + +int +_sasl_done_with_plugins(void) +{ +#ifdef DO_DLOPEN + lib_list_t *libptr, *libptr_next; + + for(libptr = lib_list_head; libptr; libptr = libptr_next) { + libptr_next = libptr->next; + if(libptr->library) + dlclose(libptr->library); + sasl_FREE(libptr); + } + + lib_list_head = NULL; +#endif /* DO_DLOPEN */ + return SASL_OK; +} diff --git a/libs/cyrussasl/lib/external.c b/libs/cyrussasl/lib/external.c new file mode 100644 index 00000000..4f56db2a --- /dev/null +++ b/libs/cyrussasl/lib/external.c @@ -0,0 +1,410 @@ +/* SASL server API implementation + * Rob Siemborski + * Tim Martin + * $Id: external.c,v 1.24 2009/03/10 16:27:52 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include "saslint.h" + +#include "../plugins/plugin_common.h" + +/***************************** Common Section *****************************/ + +static const char plugin_id[] = "$Id: external.c,v 1.24 2009/03/10 16:27:52 mel Exp $"; + +/***************************** Server Section *****************************/ + +static int +external_server_mech_new(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + void **conn_context) +{ + if (!conn_context + || !sparams + || !sparams->utils + || !sparams->utils->conn) + return SASL_BADPARAM; + + if (!sparams->utils->conn->external.auth_id) + return SASL_NOMECH; + + *conn_context = NULL; + + return SASL_OK; +} + +static int +external_server_mech_step(void *conn_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + int result; + + if (!sparams + || !sparams->utils + || !sparams->utils->conn + || !sparams->utils->getcallback + || !serverout + || !serveroutlen + || !oparams) + return SASL_BADPARAM; + + if (!sparams->utils->conn->external.auth_id) + return SASL_BADPROT; + + /* xxx arbitrary limit here */ + if (clientinlen > 16384) return SASL_BADPROT; + + if ((sparams->props.security_flags & SASL_SEC_NOANONYMOUS) && + (!strcmp(sparams->utils->conn->external.auth_id, "anonymous"))) { + sasl_seterror(sparams->utils->conn,0,"anonymous login not allowed"); + return SASL_NOAUTHZ; + } + + *serverout = NULL; + *serveroutlen = 0; + + if (!clientin) { + /* No initial data; we're in a protocol which doesn't support it. + * So we let the server app know that we need some... */ + return SASL_CONTINUE; + } + + if (clientinlen) { /* if we have a non-zero authorization id */ + /* The user's trying to authorize as someone they didn't + * authenticate as */ + result = sparams->canon_user(sparams->utils->conn, + clientin, 0, + SASL_CU_AUTHZID, oparams); + if(result != SASL_OK) return result; + + result = sparams->canon_user(sparams->utils->conn, + sparams->utils->conn->external.auth_id, 0, + SASL_CU_AUTHID | SASL_CU_EXTERNALLY_VERIFIED, oparams); + } else { + result = sparams->canon_user(sparams->utils->conn, + sparams->utils->conn->external.auth_id, 0, + SASL_CU_AUTHID | SASL_CU_EXTERNALLY_VERIFIED | SASL_CU_AUTHZID, oparams); + } + + if (result != SASL_OK) return result; + + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + return SASL_OK; +} + +static int +external_server_mech_avail(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + void **conn_context __attribute__((unused))) +{ + if (!sparams->utils->conn->external.auth_id) { + /* Return Temporary Failure */ + return SASL_NOTDONE; + } + + return SASL_OK; +} + +static sasl_server_plug_t external_server_plugins[] = +{ + { + "EXTERNAL", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS + | SASL_SEC_NODICTIONARY, /* security_flags */ + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY, /* features */ + NULL, /* glob_context */ + &external_server_mech_new, /* mech_new */ + &external_server_mech_step, /* mech_step */ + NULL, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* setpass */ + NULL, /* user_query */ + NULL, /* idle */ + &external_server_mech_avail, /* mech_avail */ + NULL /* spare */ + } +}; + +int external_server_plug_init(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount) +{ + if (!out_version || !pluglist || !plugcount) + return SASL_BADPARAM; + + if (max_version != SASL_SERVER_PLUG_VERSION) { + SETERROR( utils, "EXTERNAL version mismatch" ); + return SASL_BADVERS; + } + + *out_version = SASL_SERVER_PLUG_VERSION; + *pluglist = external_server_plugins; + *plugcount = 1; + return SASL_OK; +} + +/***************************** Client Section *****************************/ + +typedef struct client_context +{ + char *out_buf; + size_t out_buf_len; +} client_context_t; + +static int external_client_mech_new(void *glob_context __attribute__((unused)), + sasl_client_params_t *params, + void **conn_context) +{ + client_context_t *text; + + if (!params + || !params->utils + || !params->utils->conn + || !conn_context) + return SASL_BADPARAM; + + if (!params->utils->conn->external.auth_id) + return SASL_NOMECH; + + text = sasl_ALLOC(sizeof(client_context_t)); + if(!text) return SASL_NOMEM; + + memset(text, 0, sizeof(client_context_t)); + + *conn_context = text; + + return SASL_OK; +} + +static int +external_client_mech_step(void *conn_context, + sasl_client_params_t *params, + const char *serverin __attribute__((unused)), + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + client_context_t *text = (client_context_t *)conn_context; + const char *user = NULL; + int user_result = SASL_OK; + int result; + + if (!params + || !params->utils + || !params->utils->conn + || !params->utils->getcallback + || !clientout + || !clientoutlen + || !oparams) + return SASL_BADPARAM; + + if (!params->utils->conn->external.auth_id) + return SASL_BADPROT; + + if (serverinlen != 0) + return SASL_BADPROT; + + *clientout = NULL; + *clientoutlen = 0; + + /* try to get the userid */ + if (user == NULL) { + user_result = _plug_get_userid(params->utils, &user, prompt_need); + + if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) + return user_result; + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + params->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if (user_result == SASL_INTERACT) { + /* make the prompt list */ + int result = + _plug_make_prompts(params->utils, prompt_need, + user_result == SASL_INTERACT ? + "Please enter your authorization name" : NULL, + "", + NULL, NULL, + NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); + if (result != SASL_OK) return result; + + return SASL_INTERACT; + } + + *clientoutlen = user ? (unsigned) strlen(user) : 0; + + result = _buf_alloc(&text->out_buf, &text->out_buf_len, *clientoutlen + 1); + + if (result != SASL_OK) return result; + + if (user && *user) { + result = params->canon_user(params->utils->conn, + user, 0, SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) return result; + + result = params->canon_user(params->utils->conn, + params->utils->conn->external.auth_id, 0, + SASL_CU_AUTHID, oparams); + if (result != SASL_OK) return result; + + memcpy(text->out_buf, user, *clientoutlen); + } else { + result = params->canon_user(params->utils->conn, + params->utils->conn->external.auth_id, 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) return result; + } + + text->out_buf[*clientoutlen] = '\0'; + + *clientout = text->out_buf; + + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + return SASL_OK; +} + +static void +external_client_mech_dispose(void *conn_context, + const sasl_utils_t *utils __attribute__((unused))) +{ + client_context_t *text = (client_context_t *) conn_context; + + if (!text) return; + + if(text->out_buf) sasl_FREE(text->out_buf); + + sasl_FREE(text); +} + +static const unsigned long external_required_prompts[] = { + SASL_CB_LIST_END +}; + +static sasl_client_plug_t external_client_plugins[] = +{ + { + "EXTERNAL", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS + | SASL_SEC_NODICTIONARY, /* security_flags */ + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY, /* features */ + external_required_prompts, /* required_prompts */ + NULL, /* glob_context */ + &external_client_mech_new, /* mech_new */ + &external_client_mech_step, /* mech_step */ + &external_client_mech_dispose, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* idle */ + NULL, /* spare */ + NULL /* spare */ + } +}; + +int external_client_plug_init(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount) +{ + if (!utils || !out_version || !pluglist || !plugcount) + return SASL_BADPARAM; + + if (max_version != SASL_CLIENT_PLUG_VERSION) { + SETERROR( utils, "EXTERNAL version mismatch" ); + return SASL_BADVERS; + } + + *out_version = SASL_CLIENT_PLUG_VERSION; + *pluglist = external_client_plugins; + *plugcount = 1; + + return SASL_OK; +} diff --git a/libs/cyrussasl/lib/getaddrinfo.c b/libs/cyrussasl/lib/getaddrinfo.c new file mode 100644 index 00000000..c47cb52e --- /dev/null +++ b/libs/cyrussasl/lib/getaddrinfo.c @@ -0,0 +1,254 @@ +/* + * Mar 8, 2000 by Hajimu UMEMOTO + * $Id: getaddrinfo.c,v 1.8 2003/03/19 18:25:28 rjs3 Exp $ + * + * This module is based on ssh-1.2.27-IPv6-1.5 written by + * KIKUCHI Takahiro + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * fake library for ssh + * + * This file includes getaddrinfo(), freeaddrinfo() and gai_strerror(). + * These funtions are defined in rfc2133. + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For exapmle, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + * + * In the case not using 'configure --enable-ipv6', this getaddrinfo.c + * will be used if you have broken getaddrinfo or no getaddrinfo. + */ + +#include "config.h" +#ifndef WIN32 +#include +# ifndef macintosh +# include +# endif /* macintosh */ +#endif /* WIN32 */ +#include + +#ifdef WIN32 +/* : Windows socket library is missing inet_aton, emulate it with + : inet_addr. inet_aton return 0 if the address is uncorrect, a non zero + : value otherwise */ +int +inet_aton (const char *cp, struct in_addr *inp) +{ + if (cp == NULL || inp == NULL) { + return (0); + } + + /* : handle special case */ + if (strcmp (cp, "255.255.255.255") == 0) { + inp->s_addr = (unsigned int) 0xFFFFFFFF; + return (1); + } + + inp->s_addr = inet_addr (cp); + return (1); +} +#endif /* WIN32 */ + +static struct addrinfo * +malloc_ai(int port, unsigned long addr, int socktype, int proto) +{ + struct addrinfo *ai; + + ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) + + sizeof(struct sockaddr_in)); + if (ai) { + memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); + ai->ai_addr = (struct sockaddr *)(ai + 1); + /* XXX -- ssh doesn't use sa_len */ + ai->ai_addrlen = sizeof(struct sockaddr_in); +#ifdef HAVE_SOCKADDR_SA_LEN + ai->ai_addr->sa_len = sizeof(struct sockaddr_in); +#endif + ai->ai_addr->sa_family = ai->ai_family = AF_INET; + ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; + ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; + ai->ai_socktype = socktype; + ai->ai_protocol = proto; + return ai; + } else { + return NULL; + } +} + +char * +gai_strerror(int ecode) +{ + switch (ecode) { + case EAI_NODATA: + return "no address associated with hostname."; + case EAI_MEMORY: + return "memory allocation failure."; + case EAI_FAMILY: + return "ai_family not supported."; + case EAI_SERVICE: + return "servname not supported for ai_socktype."; + default: + return "unknown error."; + } +} + +void +freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *next; + + if (ai->ai_canonname) + free(ai->ai_canonname); + do { + next = ai->ai_next; + free(ai); + } while ((ai = next) != NULL); +} + +int +getaddrinfo(const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + struct addrinfo *cur, *prev = NULL; + struct hostent *hp; + struct in_addr in; + int i, port = 0, socktype, proto; + + if (hints && hints->ai_family != PF_INET && hints->ai_family != PF_UNSPEC) + return EAI_FAMILY; + + socktype = (hints && hints->ai_socktype) ? hints->ai_socktype + : SOCK_STREAM; + if (hints && hints->ai_protocol) + proto = hints->ai_protocol; + else { + switch (socktype) { + case SOCK_DGRAM: + proto = IPPROTO_UDP; + break; + case SOCK_STREAM: + proto = IPPROTO_TCP; + break; + default: + proto = 0; + break; + } + } + if (servname) { + if (isdigit((int)*servname)) + port = htons((short) atoi(servname)); + else { + struct servent *se; + char *pe_proto; + + switch (socktype) { + case SOCK_DGRAM: + pe_proto = "udp"; + break; + case SOCK_STREAM: + pe_proto = "tcp"; + break; + default: + pe_proto = NULL; + break; + } + /* xxx thread safety ? */ + if ((se = getservbyname(servname, pe_proto)) == NULL) + return EAI_SERVICE; + port = se->s_port; + } + } + if (!hostname) { + if (hints && hints->ai_flags & AI_PASSIVE) + *res = malloc_ai(port, htonl(0x00000000), socktype, proto); + else + *res = malloc_ai(port, htonl(0x7f000001), socktype, proto); + if (*res) + return 0; + else + return EAI_MEMORY; + } +#if HAVE_INET_ATON + if (inet_aton(hostname, &in)) +#else + if ((in.s_addr = inet_addr(hostname)) != -1) +#endif + { + *res = malloc_ai(port, in.s_addr, socktype, proto); + if (*res) + return 0; + else + return EAI_MEMORY; + } + if (hints && hints->ai_flags & AI_NUMERICHOST) + return EAI_NODATA; +#ifndef macintosh + /* xxx thread safety? / gethostbyname_r */ + if ((hp = gethostbyname(hostname)) && + hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { + for (i = 0; hp->h_addr_list[i]; i++) { + if ((cur = malloc_ai(port, + ((struct in_addr *)hp->h_addr_list[i])->s_addr, + socktype, proto)) == NULL) { + if (*res) + freeaddrinfo(*res); + return EAI_MEMORY; + } + if (prev) + prev->ai_next = cur; + else + *res = cur; + prev = cur; + } + if (hints && hints->ai_flags & AI_CANONNAME && *res) { + /* NOT sasl_strdup for compatibility */ + if (((*res)->ai_canonname = strdup(hp->h_name)) == NULL) { + freeaddrinfo(*res); + return EAI_MEMORY; + } + } + return 0; + } +#endif + return EAI_NODATA; +} diff --git a/libs/cyrussasl/lib/getnameinfo.c b/libs/cyrussasl/lib/getnameinfo.c new file mode 100644 index 00000000..b969301a --- /dev/null +++ b/libs/cyrussasl/lib/getnameinfo.c @@ -0,0 +1,108 @@ +/* + * Mar 8, 2000 by Hajimu UMEMOTO + * $Id: getnameinfo.c,v 1.5 2003/02/13 19:55:54 rjs3 Exp $ + * + * This module is besed on ssh-1.2.27-IPv6-1.5 written by + * KIKUCHI Takahiro + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* + * fake library for ssh + * + * This file includes getnameinfo(). + * These funtions are defined in rfc2133. + * + * But these functions are not implemented correctly. The minimum subset + * is implemented for ssh use only. For exapmle, this routine assumes + * that ai_family is AF_INET. Don't use it for another purpose. + * + * In the case not using 'configure --enable-ipv6', this getnameinfo.c + * will be used if you have broken getnameinfo or no getnameinfo. + */ + +#include "config.h" +#ifndef WIN32 +# include +#endif /* WIN32 */ +#include +#include + +int +getnameinfo(const struct sockaddr *sa, socklen_t salen __attribute__((unused)), + char *host, size_t hostlen, char *serv, size_t servlen, int flags) +{ + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + struct hostent *hp; + char tmpserv[16]; + + if (serv) { + sprintf(tmpserv, "%d", ntohs(sin->sin_port)); + if (strlen(tmpserv) > servlen) + return EAI_MEMORY; + else + strcpy(serv, tmpserv); + } + if (host) { + if (flags & NI_NUMERICHOST) { + if (strlen(inet_ntoa(sin->sin_addr)) >= hostlen) + return EAI_MEMORY; + else { + strcpy(host, inet_ntoa(sin->sin_addr)); + return 0; + } + } else { + hp = gethostbyaddr((char *)&sin->sin_addr, + sizeof(struct in_addr), AF_INET); + if (hp) { + if (strlen(hp->h_name) >= hostlen) + return EAI_MEMORY; + else { + strcpy(host, hp->h_name); + return 0; + } + } + else + return EAI_NODATA; + } + } + + return 0; +} diff --git a/libs/cyrussasl/lib/getsubopt.c b/libs/cyrussasl/lib/getsubopt.c new file mode 100644 index 00000000..38fdbcf9 --- /dev/null +++ b/libs/cyrussasl/lib/getsubopt.c @@ -0,0 +1,114 @@ +/* $NetBSD: getsubopt.c,v 1.4 1998/02/03 18:44:15 perry Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if ((!defined(WIN32))&&(!defined(macintosh))) +#include +#endif /* WIN32 */ +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)getsubopt.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: getsubopt.c,v 1.4 1998/02/03 18:44:15 perry Exp $"); +#endif +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif /* HAVE_UNISTD_H */ +#if (defined(WIN32)||(defined(macintosh))) +#include "sasl.h" +LIBSASL_API int getsubopt(char **optionp, char * const *tokens, char **valuep); +#endif /* WIN32 */ +/* + * The SVID interface to getsubopt provides no way of figuring out which + * part of the suboptions list wasn't matched. This makes error messages + * tricky... The extern variable suboptarg is a pointer to the token + * which didn't match. + */ +char *suboptarg; + +int +getsubopt(optionp, tokens, valuep) + char **optionp, **valuep; + char * const *tokens; +{ + int cnt; + char *p; + + suboptarg = *valuep = NULL; + + if (!optionp || !*optionp) + return(-1); + + /* skip leading white-space, commas */ + for (p = *optionp; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p); + + if (!*p) { + *optionp = p; + return(-1); + } + + /* save the start of the token, and skip the rest of the token. */ + for (suboptarg = p; + *++p && *p != ',' && *p != '=' && *p != ' ' && *p != '\t';); + + if (*p) { + /* + * If there's an equals sign, set the value pointer, and + * skip over the value part of the token. Terminate the + * token. + */ + if (*p == '=') { + *p = '\0'; + for (*valuep = ++p; + *p && *p != ',' && *p != ' ' && *p != '\t'; ++p); + if (*p) + *p++ = '\0'; + } else + *p++ = '\0'; + /* Skip any whitespace or commas after this token. */ + for (; *p && (*p == ',' || *p == ' ' || *p == '\t'); ++p); + } + + /* set optionp for next round. */ + *optionp = p; + + for (cnt = 0; *tokens; ++tokens, ++cnt) + if (!strcmp(suboptarg, *tokens)) + return(cnt); + return(-1); +} diff --git a/libs/cyrussasl/lib/md5.c b/libs/cyrussasl/lib/md5.c new file mode 100644 index 00000000..fbe7ae89 --- /dev/null +++ b/libs/cyrussasl/lib/md5.c @@ -0,0 +1,527 @@ +/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm + */ + +/* Function names changed to avoid namespace collisions: Rob Siemborski */ + +/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All +rights reserved. + +License to copy and use this software is granted provided that it +is identified as the "RSA Data Security, Inc. MD5 Message-Digest +Algorithm" in all material mentioning or referencing this software +or this function. + +License is also granted to make and use derivative works provided +that such works are identified as "derived from the RSA Data +Security, Inc. MD5 Message-Digest Algorithm" in all material +mentioning or referencing the derived work. + +RSA Data Security, Inc. makes no representations concerning either +the merchantability of this software or the suitability of this +software for any particular purpose. It is provided "as is" +without express or implied warranty of any kind. + +These notices must be retained in any copies of any part of this +documentation and/or software. +*/ + +#include +#include "md5global.h" +#include "md5.h" +#include "hmac-md5.h" + +#ifndef WIN32 +# include +#endif + +/* Constants for MD5Transform routine. +*/ + +#define S11 7 +#define S12 12 +#define S13 17 +#define S14 22 +#define S21 5 +#define S22 9 +#define S23 14 +#define S24 20 +#define S31 4 +#define S32 11 +#define S33 16 +#define S34 23 +#define S41 6 +#define S42 10 +#define S43 15 +#define S44 21 + +static void MD5Transform PROTO_LIST ((UINT4 [4], const unsigned char [64])); +static void Encode PROTO_LIST + ((unsigned char *, UINT4 *, unsigned int)); +static void Decode PROTO_LIST + ((UINT4 *, const unsigned char *, unsigned int)); +static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); +static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); + +static unsigned char PADDING[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* F, G, H and I are basic MD5 functions. + + */ +#ifdef I +/* This might be defined via NANA */ +#undef I +#endif + +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define I(x, y, z) ((y) ^ ((x) | (~z))) + +/* ROTATE_LEFT rotates x left n bits. + + */ + +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) + +/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. +Rotation is separate from addition to prevent recomputation. +*/ + +#define FF(a, b, c, d, x, s, ac) { (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } +#define GG(a, b, c, d, x, s, ac) { (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } +#define HH(a, b, c, d, x, s, ac) { (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } +#define II(a, b, c, d, x, s, ac) { (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); (a) = ROTATE_LEFT ((a), (s)); (a) += (b); } + +/* MD5 initialization. Begins an MD5 operation, writing a new context. +*/ + +void _sasl_MD5Init (context) +MD5_CTX *context; /* context */ +{ + context->count[0] = context->count[1] = 0; + + /* Load magic initialization constants. */ + context->state[0] = 0x67452301; + context->state[1] = 0xefcdab89; + context->state[2] = 0x98badcfe; + context->state[3] = 0x10325476; +} + +/* MD5 block update operation. Continues an MD5 message-digest + operation, processing another message block, and updating the context. +*/ + +void _sasl_MD5Update (context, input, inputLen) +MD5_CTX *context; /* context */ +const unsigned char *input; /* input block */ +unsigned int inputLen; /* length of input block */ +{ + unsigned int i, index, partLen; + + /* Compute number of bytes mod 64 */ + index = (unsigned int)((context->count[0] >> 3) & 0x3F); + + /* Update number of bits */ + if ((context->count[0] += ((UINT4)inputLen << 3)) + < ((UINT4)inputLen << 3)) + context->count[1]++; + context->count[1] += ((UINT4)inputLen >> 29); + + partLen = 64 - index; + + /* Transform as many times as possible. + +*/ + if (inputLen >= partLen) { + MD5_memcpy + ((POINTER)&context->buffer[index], (POINTER)input, partLen); MD5Transform + (context->state, context->buffer); + + for (i = partLen; i + 63 < inputLen; i += 64) + MD5Transform (context->state, &input[i]); + + index = 0; + } + else + i = 0; + + /* Buffer remaining input */ + MD5_memcpy + ((POINTER)&context->buffer[index], (POINTER)&input[i], + inputLen-i); + +} + +/* MD5 finalization. Ends an MD5 message-digest operation, writing the + the message digest and zeroizing the context. +*/ + +void _sasl_MD5Final (digest, context) +unsigned char digest[16]; /* message digest */ +MD5_CTX *context; /* context */ +{ + unsigned char bits[8]; + unsigned int index, padLen; + + /* Save number of bits */ + Encode (bits, context->count, 8); + + /* Pad out to 56 mod 64. */ + index = (unsigned int)((context->count[0] >> 3) & 0x3f); + padLen = (index < 56) ? (56 - index) : (120 - index); + _sasl_MD5Update (context, PADDING, padLen); + + /* Append length (before padding) */ + _sasl_MD5Update (context, bits, 8); + + /* Store state in digest */ + Encode (digest, context->state, 16); + + /* Zeroize sensitive information. */ + MD5_memset ((POINTER)context, 0, sizeof (*context)); +} + +/* MD5 basic transformation. Transforms state based on block. */ + +static void MD5Transform (state, block) +UINT4 state[4]; +const unsigned char block[64]; +{ + UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; + + Decode (x, block, 64); + + /* Round 1 */ + FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ + FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ + FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ + FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ + FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ + FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ + FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ + FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ + FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ + FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ + FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ + FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ + FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ + FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ + FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ + FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ + GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ + GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ + GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ + GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ + GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ + GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ + GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ + GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ + GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ + GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ + GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ + GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ + GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ + GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ + GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ + HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ + HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ + HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ + HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ + HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ + HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ + HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ + HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ + HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ + HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ + HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ + HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ + HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ + HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ + HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ + + /* Round 4 */ + II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ + II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ + II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ + II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ + II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ + II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ + II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ + II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ + II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ + II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ + II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ + II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ + II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ + II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ + II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ + II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + + /* Zeroize sensitive information. + */ + MD5_memset ((POINTER)x, 0, sizeof (x)); +} + +/* Encodes input (UINT4) into output (unsigned char). Assumes len is + a multiple of 4. + + */ + +static void Encode (output, input, len) +unsigned char *output; +UINT4 *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) { + output[j] = (unsigned char)(input[i] & 0xff); + output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); + output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); + output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); + } +} + +/* Decodes input (unsigned char) into output (UINT4). Assumes len is + a multiple of 4. + + */ + +static void Decode (output, input, len) +UINT4 *output; +const unsigned char *input; +unsigned int len; +{ + unsigned int i, j; + + for (i = 0, j = 0; j < len; i++, j += 4) + output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16) + | (((UINT4)input[j+3]) << 24); +} + +/* Note: Replace "for loop" with standard memcpy if possible. + + */ + +static void MD5_memcpy (output, input, len) +POINTER output; +POINTER input; +unsigned int len; +{ + unsigned int i; + + for (i = 0; i < len; i++) + output[i] = input[i]; +} + +/* Note: Replace "for loop" with standard memset if possible. +*/ + +static void MD5_memset (output, value, len) +POINTER output; +int value; +unsigned int len; +{ + unsigned int i; + + for (i = 0; i < len; i++) + ((char *)output)[i] = (char)value; +} + +void _sasl_hmac_md5_init(HMAC_MD5_CTX *hmac, + const unsigned char *key, + int key_len) +{ + unsigned char k_ipad[65]; /* inner padding - + * key XORd with ipad + */ + unsigned char k_opad[65]; /* outer padding - + * key XORd with opad + */ + unsigned char tk[16]; + int i; + /* if key is longer than 64 bytes reset it to key=MD5(key) */ + if (key_len > 64) { + + MD5_CTX tctx; + + _sasl_MD5Init(&tctx); + _sasl_MD5Update(&tctx, key, key_len); + _sasl_MD5Final(tk, &tctx); + + key = tk; + key_len = 16; + } + + /* + * the HMAC_MD5 transform looks like: + * + * MD5(K XOR opad, MD5(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected + */ + + /* start out by storing key in pads */ + MD5_memset((POINTER)k_ipad, '\0', sizeof k_ipad); + MD5_memset((POINTER)k_opad, '\0', sizeof k_opad); + MD5_memcpy( k_ipad, (POINTER)key, key_len); + MD5_memcpy( k_opad, (POINTER)key, key_len); + + /* XOR key with ipad and opad values */ + for (i=0; i<64; i++) { + k_ipad[i] ^= 0x36; + k_opad[i] ^= 0x5c; + } + + _sasl_MD5Init(&hmac->ictx); /* init inner context */ + _sasl_MD5Update(&hmac->ictx, k_ipad, 64); /* apply inner pad */ + + _sasl_MD5Init(&hmac->octx); /* init outer context */ + _sasl_MD5Update(&hmac->octx, k_opad, 64); /* apply outer pad */ + + /* scrub the pads and key context (if used) */ + MD5_memset((POINTER)&k_ipad, 0, sizeof(k_ipad)); + MD5_memset((POINTER)&k_opad, 0, sizeof(k_opad)); + MD5_memset((POINTER)&tk, 0, sizeof(tk)); + + /* and we're done. */ +} + +/* The precalc and import routines here rely on the fact that we pad + * the key out to 64 bytes and use that to initialize the md5 + * contexts, and that updating an md5 context with 64 bytes of data + * leaves nothing left over; all of the interesting state is contained + * in the state field, and none of it is left over in the count and + * buffer fields. So all we have to do is save the state field; we + * can zero the others when we reload it. Which is why the decision + * was made to pad the key out to 64 bytes in the first place. */ +void _sasl_hmac_md5_precalc(HMAC_MD5_STATE *state, + const unsigned char *key, + int key_len) +{ + HMAC_MD5_CTX hmac; + unsigned lupe; + + _sasl_hmac_md5_init(&hmac, key, key_len); + for (lupe = 0; lupe < 4; lupe++) { + state->istate[lupe] = htonl(hmac.ictx.state[lupe]); + state->ostate[lupe] = htonl(hmac.octx.state[lupe]); + } + MD5_memset((POINTER)&hmac, 0, sizeof(hmac)); +} + + +void _sasl_hmac_md5_import(HMAC_MD5_CTX *hmac, + HMAC_MD5_STATE *state) +{ + unsigned lupe; + MD5_memset((POINTER)hmac, 0, sizeof(HMAC_MD5_CTX)); + for (lupe = 0; lupe < 4; lupe++) { + hmac->ictx.state[lupe] = ntohl(state->istate[lupe]); + hmac->octx.state[lupe] = ntohl(state->ostate[lupe]); + } + /* Init the counts to account for our having applied + * 64 bytes of key; this works out to 0x200 (64 << 3; see + * MD5Update above...) */ + hmac->ictx.count[0] = hmac->octx.count[0] = 0x200; +} + +void _sasl_hmac_md5_final(unsigned char digest[HMAC_MD5_SIZE], + HMAC_MD5_CTX *hmac) +{ + _sasl_MD5Final(digest, &hmac->ictx); /* Finalize inner md5 */ + _sasl_MD5Update(&hmac->octx, digest, 16); /* Update outer ctx */ + _sasl_MD5Final(digest, &hmac->octx); /* Finalize outer md5 */ +} + + +void _sasl_hmac_md5(text, text_len, key, key_len, digest) +const unsigned char* text; /* pointer to data stream */ +int text_len; /* length of data stream */ +const unsigned char* key; /* pointer to authentication key */ +int key_len; /* length of authentication key */ +unsigned char *digest; /* caller digest to be filled in */ +{ + MD5_CTX context; + + unsigned char k_ipad[65]; /* inner padding - + * key XORd with ipad + */ + unsigned char k_opad[65]; /* outer padding - + * key XORd with opad + */ + unsigned char tk[16]; + int i; + /* if key is longer than 64 bytes reset it to key=MD5(key) */ + if (key_len > 64) { + + MD5_CTX tctx; + + _sasl_MD5Init(&tctx); + _sasl_MD5Update(&tctx, key, key_len); + _sasl_MD5Final(tk, &tctx); + + key = tk; + key_len = 16; + } + + /* + * the HMAC_MD5 transform looks like: + * + * MD5(K XOR opad, MD5(K XOR ipad, text)) + * + * where K is an n byte key + * ipad is the byte 0x36 repeated 64 times + * opad is the byte 0x5c repeated 64 times + * and text is the data being protected + */ + + /* start out by storing key in pads */ + MD5_memset(k_ipad, '\0', sizeof k_ipad); + MD5_memset(k_opad, '\0', sizeof k_opad); + MD5_memcpy( k_ipad, (POINTER)key, key_len); + MD5_memcpy( k_opad, (POINTER)key, key_len); + + /* XOR key with ipad and opad values */ + for (i=0; i<64; i++) { + k_ipad[i] ^= 0x36; + k_opad[i] ^= 0x5c; + } + /* + * perform inner MD5 + */ + + _sasl_MD5Init(&context); /* init context for 1st + * pass */ + _sasl_MD5Update(&context, k_ipad, 64); /* start with inner pad */ + _sasl_MD5Update(&context, text, text_len); /* then text of datagram */ + _sasl_MD5Final(digest, &context); /* finish up 1st pass */ + + /* + * perform outer MD5 + */ + _sasl_MD5Init(&context); /* init context for 2nd + * pass */ + _sasl_MD5Update(&context, k_opad, 64); /* start with outer pad */ + _sasl_MD5Update(&context, digest, 16); /* then results of 1st + * hash */ + _sasl_MD5Final(digest, &context); /* finish up 2nd pass */ + +} diff --git a/libs/cyrussasl/lib/saslint.h b/libs/cyrussasl/lib/saslint.h new file mode 100644 index 00000000..e2edb3db --- /dev/null +++ b/libs/cyrussasl/lib/saslint.h @@ -0,0 +1,528 @@ +/* saslint.h - internal SASL library definitions + * Rob Siemborski + * Tim Martin + * $Id: saslint.h,v 1.73 2011/09/01 14:12:53 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef SASLINT_H +#define SASLINT_H + +#include +#include "sasl.h" +#include "saslplug.h" +#include "saslutil.h" +#include "prop.h" + +#ifndef INLINE +#if defined (WIN32) +/* Visual Studio: "inline" keyword is not available in C, only in C++ */ +#define INLINE __inline +#else +#define INLINE inline +#endif +#endif + +/* #define'd constants */ +#define CANON_BUF_SIZE 1024 + +/* Error Handling Foo */ +/* Helpful Hints: + * -Error strings are set as soon as possible (first function in stack trace + * with a pointer to the sasl_conn_t. + * -Error codes are set as late as possible (only in the sasl api functions), + * though "as often as possible" also comes to mind to ensure correctness + * -Errors from calls to _buf_alloc, _sasl_strdup, etc are assumed to be + * memory errors. + * -Only errors (error codes < SASL_OK) should be remembered + */ +#define RETURN(conn, val) { if(conn && (val) < SASL_OK) \ + (conn)->error_code = (val); \ + return (val); } +#define MEMERROR(conn) {\ + if(conn) sasl_seterror( (conn), 0, \ + "Out of Memory in " __FILE__ " near line %d", __LINE__ ); \ + RETURN(conn, SASL_NOMEM) } +#define PARAMERROR(conn) {\ + if(conn) sasl_seterror( (conn), SASL_NOLOG, \ + "Parameter error in " __FILE__ " near line %d", __LINE__ ); \ + RETURN(conn, SASL_BADPARAM) } +#define INTERROR(conn, val) {\ + if(conn) sasl_seterror( (conn), 0, \ + "Internal Error %d in " __FILE__ " near line %d", (val),\ + __LINE__ ); \ + RETURN(conn, (val)) } + +#ifndef PATH_MAX +# ifdef WIN32 +# define PATH_MAX MAX_PATH +# else +# ifdef _POSIX_PATH_MAX +# define PATH_MAX _POSIX_PATH_MAX +# else +# define PATH_MAX 1024 /* arbitrary; probably big enough. + * will probably only be 256+64 on + * pre-posix machines */ +# endif /* _POSIX_PATH_MAX */ +# endif /* WIN32 */ +#endif + +/* : Define directory delimiter in SASL_PATH/SASL_CONF_PATH variables */ +#ifdef WIN32 +#define PATHS_DELIMITER ';' +#else +#define PATHS_DELIMITER ':' +#endif + +/* Datatype Definitions */ +typedef struct { + const sasl_callback_t *callbacks; + const char *appname; +} sasl_global_callbacks_t; + +typedef struct _sasl_external_properties +{ + sasl_ssf_t ssf; + char *auth_id; +} _sasl_external_properties_t; + +typedef struct sasl_string_list +{ + const char *d; + struct sasl_string_list *next; +} sasl_string_list_t; + +typedef struct buffer_info +{ + char *data; + size_t curlen; + size_t reallen; +} buffer_info_t; + +typedef int add_plugin_t(const char *, void *); + +typedef struct add_plugin_list +{ + const char *entryname; + add_plugin_t *add_plugin; +} add_plugin_list_t; + +enum Sasl_conn_type { SASL_CONN_UNKNOWN = 0, + SASL_CONN_SERVER = 1, + SASL_CONN_CLIENT = 2 }; + +struct sasl_conn { + enum Sasl_conn_type type; + + void (*destroy_conn)(sasl_conn_t *); /* destroy function */ + + char *service; + + unsigned int flags; /* flags passed to sasl_*_new */ + + /* IP information. A buffer of size 52 is adequate for this in its + longest format (see sasl.h) */ + int got_ip_local, got_ip_remote; + char iplocalport[NI_MAXHOST + NI_MAXSERV]; + char ipremoteport[NI_MAXHOST + NI_MAXSERV]; + + void *context; + sasl_out_params_t oparams; + + sasl_security_properties_t props; + _sasl_external_properties_t external; + + sasl_secret_t *secret; + + int (*idle_hook)(sasl_conn_t *conn); + const sasl_callback_t *callbacks; + const sasl_global_callbacks_t *global_callbacks; /* global callbacks + * connection */ + char *serverFQDN; + + /* Pointers to memory that we are responsible for */ + buffer_info_t *encode_buf; + + int error_code; + char *error_buf, *errdetail_buf; + size_t error_buf_len, errdetail_buf_len; + char *mechlist_buf; + size_t mechlist_buf_len; + + char *decode_buf; + + char user_buf[CANON_BUF_SIZE+1], authid_buf[CANON_BUF_SIZE+1]; + + /* Allocated by sasl_encodev if the output contains multiple SASL packet. */ + buffer_info_t multipacket_encoded_data; +}; + +/* Server Conn Type Information */ + +typedef struct mechanism +{ + server_sasl_mechanism_t m; + struct mechanism *next; +} mechanism_t; + +typedef struct mech_list { + const sasl_utils_t *utils; /* gotten from plug_init */ + + void *mutex; /* mutex for this data */ + mechanism_t *mech_list; /* list of loaded mechanisms */ + int mech_length; /* number of loaded mechanisms */ +} mech_list_t; + +typedef struct context_list +{ + mechanism_t *mech; + void *context; /* if NULL, this mech is disabled for this connection + * otherwise, use this context instead of a call + * to mech_new */ + struct context_list *next; +} context_list_t; + +typedef struct sasl_server_conn { + sasl_conn_t base; /* parts common to server + client */ + + char *appname; /* application name buffer (for sparams) */ + char *user_realm; /* domain the user authenticating is in */ + int sent_last; /* Have we already done the last send? */ + int authenticated; + mechanism_t *mech; /* mechanism trying to use */ + sasl_server_params_t *sparams; + context_list_t *mech_contexts; + mechanism_t *mech_list; /* list of available mechanisms */ + int mech_length; /* number of available mechanisms */ +} sasl_server_conn_t; + +/* Client Conn Type Information */ + +typedef struct cmechanism +{ + client_sasl_mechanism_t m; + struct cmechanism *next; +} cmechanism_t; + +typedef struct cmech_list { + const sasl_utils_t *utils; + + void *mutex; /* mutex for this data */ + cmechanism_t *mech_list; /* list of mechanisms */ + int mech_length; /* number of mechanisms */ + +} cmech_list_t; + +typedef struct sasl_client_conn { + sasl_conn_t base; /* parts common to server + client */ + + cmechanism_t *mech; + sasl_client_params_t *cparams; + + char *clientFQDN; + + cmechanism_t *mech_list; /* list of available mechanisms */ + int mech_length; /* number of available mechanisms */ +} sasl_client_conn_t; + +typedef struct sasl_allocation_utils { + sasl_malloc_t *malloc; + sasl_calloc_t *calloc; + sasl_realloc_t *realloc; + sasl_free_t *free; +} sasl_allocation_utils_t; + +typedef struct sasl_mutex_utils { + sasl_mutex_alloc_t *alloc; + sasl_mutex_lock_t *lock; + sasl_mutex_unlock_t *unlock; + sasl_mutex_free_t *free; +} sasl_mutex_utils_t; + +typedef struct sasl_log_utils_s { + sasl_log_t *log; +} sasl_log_utils_t; + +typedef int sasl_plaintext_verifier(sasl_conn_t *conn, + const char *userid, + const char *passwd, + const char *service, + const char *user_realm); + +struct sasl_verify_password_s { + char *name; + sasl_plaintext_verifier *verify; +}; + +/* + * globals & constants + */ +/* + * common.c + */ +LIBSASL_API const sasl_utils_t *sasl_global_utils; + +extern int (*_sasl_client_idle_hook)(sasl_conn_t *conn); +extern int (*_sasl_server_idle_hook)(sasl_conn_t *conn); + +/* These return SASL_OK if we've actually finished cleanup, + * SASL_NOTINIT if that part of the library isn't initialized, and + * SASL_CONTINUE if we need to call them again */ +extern int (*_sasl_client_cleanup_hook)(void); +extern int (*_sasl_server_cleanup_hook)(void); + +extern sasl_allocation_utils_t _sasl_allocation_utils; +extern sasl_mutex_utils_t _sasl_mutex_utils; +extern int _sasl_allocation_locked; + +void sasl_common_done(void); + +extern int _sasl_is_equal_mech(const char *req_mech, + const char *plug_mech, + size_t req_mech_len, + int *plus); + +/* + * checkpw.c + */ +extern struct sasl_verify_password_s _sasl_verify_password[]; + +/* + * server.c + */ +/* (this is a function call to ensure this is read-only to the outside) */ +extern int _is_sasl_server_active(void); + +/* + * Allocation and Mutex utility macros + */ +#define sasl_ALLOC(__size__) (_sasl_allocation_utils.malloc((__size__))) +#define sasl_CALLOC(__nelem__, __size__) \ + (_sasl_allocation_utils.calloc((__nelem__), (__size__))) +#define sasl_REALLOC(__ptr__, __size__) \ + (_sasl_allocation_utils.realloc((__ptr__), (__size__))) +#define sasl_FREE(__ptr__) (_sasl_allocation_utils.free((__ptr__))) + +#define sasl_MUTEX_ALLOC() (_sasl_mutex_utils.alloc()) +#define sasl_MUTEX_LOCK(__mutex__) (_sasl_mutex_utils.lock((__mutex__))) +#define sasl_MUTEX_UNLOCK(__mutex__) (_sasl_mutex_utils.unlock((__mutex__))) +#define sasl_MUTEX_FREE(__mutex__) \ + (_sasl_mutex_utils.free((__mutex__))) + +/* function prototypes */ +/* + * dlopen.c and staticopen.c + */ +/* + * The differences here are: + * _sasl_load_plugins loads all plugins from all files + * _sasl_get_plugin loads the LIBRARY for an individual file + * _sasl_done_with_plugins frees the LIBRARIES loaded by the above 2 + * _sasl_locate_entry locates an entrypoint in a given library + */ +extern int _sasl_load_plugins(const add_plugin_list_t *entrypoints, + const sasl_callback_t *getpath_callback, + const sasl_callback_t *verifyfile_callback); +extern int _sasl_get_plugin(const char *file, + const sasl_callback_t *verifyfile_cb, + void **libraryptr); +extern int _sasl_locate_entry(void *library, const char *entryname, + void **entry_point); +extern int _sasl_done_with_plugins(); + +/* + * common.c + */ +extern const sasl_callback_t * +_sasl_find_getpath_callback(const sasl_callback_t *callbacks); + +extern const sasl_callback_t * +_sasl_find_getconfpath_callback(const sasl_callback_t *callbacks); + +extern const sasl_callback_t * +_sasl_find_verifyfile_callback(const sasl_callback_t *callbacks); + +extern int _sasl_common_init(sasl_global_callbacks_t *global_callbacks); + +extern int _sasl_conn_init(sasl_conn_t *conn, + const char *service, + unsigned int flags, + enum Sasl_conn_type type, + int (*idle_hook)(sasl_conn_t *conn), + const char *serverFQDN, + const char *iplocalport, + const char *ipremoteport, + const sasl_callback_t *callbacks, + const sasl_global_callbacks_t *global_callbacks); +extern void _sasl_conn_dispose(sasl_conn_t *conn); + +extern sasl_utils_t * +_sasl_alloc_utils(sasl_conn_t *conn, + sasl_global_callbacks_t *global_callbacks); +extern int _sasl_free_utils(const sasl_utils_t ** utils); + +extern int +_sasl_getcallback(sasl_conn_t * conn, + unsigned long callbackid, + sasl_callback_ft * pproc, + void **pcontext); + +extern void +_sasl_log(sasl_conn_t *conn, + int level, + const char *fmt, + ...); + +void _sasl_get_errorbuf(sasl_conn_t *conn, char ***bufhdl, size_t **lenhdl); +int _sasl_add_string(char **out, size_t *alloclen, + size_t *outlen, const char *add); + +/* More Generic Utilities in common.c */ +extern int _sasl_strdup(const char *in, char **out, size_t *outlen); + +/* Basically a conditional call to realloc(), if we need more */ +int _buf_alloc(char **rwbuf, size_t *curlen, size_t newlen); + +/* convert an iovec to a single buffer */ +int _iovec_to_buf(const struct iovec *vec, + unsigned numiov, buffer_info_t **output); + +/* Convert between string formats and sockaddr formats */ +int _sasl_iptostring(const struct sockaddr *addr, socklen_t addrlen, + char *out, unsigned outlen); +int _sasl_ipfromstring(const char *addr, struct sockaddr *out, + socklen_t outlen); + +/* + * external plugin (external.c) + */ +int external_client_plug_init(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount); +int external_server_plug_init(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount); + +/* Mech Listing Functions */ +int _sasl_build_mechlist(void); +int _sasl_server_listmech(sasl_conn_t *conn, + const char *user, + const char *prefix, + const char *sep, + const char *suffix, + const char **result, + unsigned *plen, + int *pcount); +int _sasl_client_listmech(sasl_conn_t *conn, + const char *prefix, + const char *sep, + const char *suffix, + const char **result, + unsigned *plen, + int *pcount); +/* Just create a straight list of them */ +sasl_string_list_t *_sasl_client_mechs(void); +sasl_string_list_t *_sasl_server_mechs(void); + +/* + * config file declarations (config.c) + */ +extern const char *sasl_config_getstring(const char *key,const char *def); + +/* checkpw.c */ +#ifdef DO_SASL_CHECKAPOP +extern int _sasl_auxprop_verify_apop(sasl_conn_t *conn, + const char *userstr, + const char *challenge, + const char *response, + const char *user_realm); +#endif /* DO_SASL_CHECKAPOP */ + +/* Auxprop Plugin (sasldb.c) */ +extern int sasldb_auxprop_plug_init(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_auxprop_plug_t **plug, + const char *plugname); + +/* + * auxprop.c + */ +extern int _sasl_auxprop_add_plugin(void *p, void *library); +extern void _sasl_auxprop_free(void); +extern int _sasl_auxprop_lookup(sasl_server_params_t *sparams, + unsigned flags, + const char *user, unsigned ulen); + +/* + * canonusr.c + */ +void _sasl_canonuser_free(); +extern int internal_canonuser_init(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_canonuser_plug_t **plug, + const char *plugname); +extern int _sasl_canon_user(sasl_conn_t *conn, + const char *user, + unsigned ulen, + unsigned flags, + sasl_out_params_t *oparams); +int _sasl_canon_user_lookup (sasl_conn_t *conn, + const char *user, + unsigned ulen, + unsigned flags, + sasl_out_params_t *oparams); + +/* + * saslutil.c + */ +int get_fqhostname( + char *name, + int namelen, + int abort_if_no_fqdn + ); + +#endif /* SASLINT_H */ diff --git a/libs/cyrussasl/lib/saslutil.c b/libs/cyrussasl/lib/saslutil.c new file mode 100644 index 00000000..61741246 --- /dev/null +++ b/libs/cyrussasl/lib/saslutil.c @@ -0,0 +1,812 @@ +/* saslutil.c + * Rob Siemborski + * Tim Martin + * $Id: saslutil.c,v 1.52 2011/09/22 14:43:01 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#if defined(WIN32) +#define _CRT_RAND_S +#endif + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_TIME_H +#include +#endif +#include "saslint.h" +#include + +/* Contains: + * + * sasl_decode64 + * sasl_encode64 + * sasl_mkchal + * sasl_utf8verify + * sasl_randcreate + * sasl_randfree + * sasl_randseed + * sasl_rand + * sasl_churn + * sasl_erasebuffer + */ + +#ifdef sun +/* gotta define gethostname ourselves on suns */ +extern int gethostname(char *, int); +#endif + +char *encode_table; +char *decode_table; + +#define RPOOL_SIZE 3 +struct sasl_rand_s { + unsigned short pool[RPOOL_SIZE]; + /* since the init time might be really bad let's make this lazy */ + int initialized; +}; + +#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) + +static char basis_64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????"; + +static char index_64[128] = { + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 +}; + +/* base64 encode + * in -- input data + * inlen -- input data length + * out -- output buffer (will be NUL terminated) + * outmax -- max size of output buffer + * result: + * outlen -- gets actual length of output buffer (optional) + * + * Returns SASL_OK on success, SASL_BUFOVER if result won't fit + */ + +int sasl_encode64(const char *_in, + unsigned inlen, + char *_out, + unsigned outmax, + unsigned *outlen) +{ + const unsigned char *in = (const unsigned char *)_in; + unsigned char *out = (unsigned char *)_out; + unsigned char oval; + char *blah; + unsigned olen; + + /* check params */ + if ((inlen > 0) && (in == NULL)) return SASL_BADPARAM; + + /* Will it fit? */ + olen = (inlen + 2) / 3 * 4; + if (outlen) { + *outlen = olen; + } + if (outmax <= olen) { + return SASL_BUFOVER; + } + + /* Do the work... */ + blah = (char *) out; + while (inlen >= 3) { + /* user provided max buffer size; make sure we don't go over it */ + *out++ = basis_64[in[0] >> 2]; + *out++ = basis_64[((in[0] << 4) & 0x30) | (in[1] >> 4)]; + *out++ = basis_64[((in[1] << 2) & 0x3c) | (in[2] >> 6)]; + *out++ = basis_64[in[2] & 0x3f]; + in += 3; + inlen -= 3; + } + if (inlen > 0) { + /* user provided max buffer size; make sure we don't go over it */ + *out++ = basis_64[in[0] >> 2]; + oval = (in[0] << 4) & 0x30; + if (inlen > 1) oval |= in[1] >> 4; + *out++ = basis_64[oval]; + *out++ = (inlen < 2) ? '=' : basis_64[(in[1] << 2) & 0x3c]; + *out++ = '='; + } + + *out = '\0'; + + return SASL_OK; +} + +/* base64 decode + * in -- input data + * inlen -- length of input data + * out -- output data (may be same as in, must have enough space) + * outmax -- max size of output buffer + * result: + * outlen -- actual output length + * + * returns: + * SASL_BADPROT on bad base64, + * SASL_BUFOVER if result won't fit, + * SASL_CONTINUE on a partial block, + * SASL_OK on success + */ + +int sasl_decode64(const char *in, + unsigned inlen, + char *out, + unsigned outmax, /* size of the buffer, not counting the NUL */ + unsigned *outlen) +{ + unsigned len = 0; + unsigned j; + int c[4]; + int saw_equal = 0; + + /* check parameters */ + if (out == NULL) return SASL_FAIL; + + if (inlen > 0 && *in == '\r') return SASL_FAIL; + + while (inlen > 3) { + /* No data is valid after an '=' character */ + if (saw_equal) { + return SASL_BADPROT; + } + + for (j = 0; j < 4; j++) { + c[j] = in[0]; + in++; + inlen--; + } + + if (CHAR64(c[0]) == -1 || CHAR64(c[1]) == -1) return SASL_BADPROT; + if (c[2] != '=' && CHAR64(c[2]) == -1) return SASL_BADPROT; + if (c[3] != '=' && CHAR64(c[3]) == -1) return SASL_BADPROT; + /* No data is valid after a '=' character, unless it is another '=' */ + if (c[2] == '=' && c[3] != '=') return SASL_BADPROT; + if (c[2] == '=' || c[3] == '=') { + saw_equal = 1; + } + + *out++ = (CHAR64(c[0]) << 2) | (CHAR64(c[1]) >> 4); + if (++len >= outmax) return SASL_BUFOVER; + if (c[2] != '=') { + *out++ = ((CHAR64(c[1]) << 4) & 0xf0) | (CHAR64(c[2]) >> 2); + if (++len >= outmax) return SASL_BUFOVER; + if (c[3] != '=') { + *out++ = ((CHAR64(c[2]) << 6) & 0xc0) | CHAR64(c[3]); + if (++len >= outmax) return SASL_BUFOVER; + } + } + } + + *out = '\0'; /* NUL terminate the output string */ + + if (outlen) *outlen = len; + + if (inlen != 0) { + if (saw_equal) { + /* Unless there is CRLF at the end? */ + return SASL_BADPROT; + } else { + return (SASL_CONTINUE); + } + } + + return SASL_OK; +} + +/* make a challenge string (NUL terminated) + * buf -- buffer for result + * maxlen -- max length of result + * hostflag -- 0 = don't include hostname, 1 = include hostname + * returns final length or 0 if not enough space + */ + +int sasl_mkchal(sasl_conn_t *conn, + char *buf, + unsigned maxlen, + unsigned hostflag) +{ + sasl_rand_t *pool = NULL; + unsigned long randnum; + int ret; + time_t now; + unsigned len; + + len = 4 /* <.>\0 */ + + (2 * 20); /* 2 numbers, 20 => max size of 64bit + * ulong in base 10 */ + if (hostflag && conn->serverFQDN) + len += (unsigned) strlen(conn->serverFQDN) + 1 /* for the @ */; + + if (maxlen < len) + return 0; + + ret = sasl_randcreate(&pool); + if(ret != SASL_OK) return 0; /* xxx sasl return code? */ + + sasl_rand(pool, (char *)&randnum, sizeof(randnum)); + sasl_randfree(&pool); + + time(&now); + + if (hostflag && conn->serverFQDN) + snprintf(buf,maxlen, "<%lu.%lu@%s>", randnum, now, conn->serverFQDN); + else + snprintf(buf,maxlen, "<%lu.%lu>", randnum, now); + + return (int) strlen(buf); +} + + /* borrowed from larry. probably works :) + * probably is also in acap server somewhere + */ +int sasl_utf8verify(const char *str, unsigned len) +{ + unsigned i; + for (i = 0; i < len; i++) { + /* how many octets? */ + int seqlen = 0; + while (str[i] & (0x80 >> seqlen)) ++seqlen; + if (seqlen == 0) continue; /* this is a valid US-ASCII char */ + if (seqlen == 1) return SASL_BADPROT; /* this shouldn't happen here */ + if (seqlen > 6) return SASL_BADPROT; /* illegal */ + while (--seqlen) + if ((str[++i] & 0xC0) != 0xF0) return SASL_BADPROT; /* needed a 10 octet */ + } + return SASL_OK; +} + +/* + * To see why this is really bad see RFC 1750 + * + * unfortunatly there currently is no way to make + * cryptographically secure pseudo random numbers + * without specialized hardware etc... + * thus, this is for nonce use only + */ +void getranddata(unsigned short ret[RPOOL_SIZE]) +{ + long curtime; + + memset(ret, 0, RPOOL_SIZE*sizeof(unsigned short)); + +#ifdef DEV_RANDOM + { + int fd; + + fd = open(DEV_RANDOM, O_RDONLY); + if(fd != -1) { + unsigned char *buf = (unsigned char *)ret; + ssize_t bytesread = 0; + size_t bytesleft = RPOOL_SIZE*sizeof(unsigned short); + + do { + bytesread = read(fd, buf, bytesleft); + if(bytesread == -1 && errno == EINTR) continue; + else if(bytesread <= 0) break; + bytesleft -= bytesread; + buf += bytesread; + } while(bytesleft != 0); + + close(fd); + } + } +#endif + +#ifdef HAVE_GETPID + ret[0] ^= (unsigned short) getpid(); +#endif + +#ifdef HAVE_GETTIMEOFDAY + { + struct timeval tv; + + /* xxx autoconf macro */ +#ifdef _SVID_GETTOD + if (!gettimeofday(&tv)) +#else + if (!gettimeofday(&tv, NULL)) +#endif + { + /* longs are guaranteed to be at least 32 bits; we need + 16 bits in each short */ + ret[0] ^= (unsigned short) (tv.tv_sec & 0xFFFF); + ret[1] ^= (unsigned short) (clock() & 0xFFFF); + ret[1] ^= (unsigned short) (tv.tv_usec >> 16); + ret[2] ^= (unsigned short) (tv.tv_usec & 0xFFFF); + return; + } + } +#endif /* HAVE_GETTIMEOFDAY */ + + /* if all else fails just use time() */ + curtime = (long) time(NULL); /* better be at least 32 bits */ + + ret[0] ^= (unsigned short) (curtime >> 16); + ret[1] ^= (unsigned short) (curtime & 0xFFFF); + ret[2] ^= (unsigned short) (clock() & 0xFFFF); + + return; +} + +int sasl_randcreate(sasl_rand_t **rpool) +{ + (*rpool)=sasl_ALLOC(sizeof(sasl_rand_t)); + if ((*rpool) == NULL) return SASL_NOMEM; + + /* init is lazy */ + (*rpool)->initialized = 0; + + return SASL_OK; +} + +void sasl_randfree(sasl_rand_t **rpool) +{ + sasl_FREE(*rpool); +} + +void sasl_randseed (sasl_rand_t *rpool, const char *seed, unsigned len) +{ + /* is it acceptable to just use the 1st 3 char's given??? */ + unsigned int lup; + + /* check params */ + if (seed == NULL) return; + if (rpool == NULL) return; + + rpool->initialized = 1; + + if (len > sizeof(unsigned short)*RPOOL_SIZE) + len = sizeof(unsigned short)*RPOOL_SIZE; + + for (lup = 0; lup < len; lup += 2) + rpool->pool[lup/2] = (seed[lup] << 8) + seed[lup + 1]; +} + +static void randinit(sasl_rand_t *rpool) +{ + if (!rpool) return; + + if (!rpool->initialized) { + getranddata(rpool->pool); + rpool->initialized = 1; +#if !(defined(WIN32)||defined(macintosh)) +#ifndef HAVE_JRAND48 + { + /* xxx varies by platform */ + unsigned int *foo = (unsigned int *)rpool->pool; + srandom(*foo); + } +#endif /* HAVE_JRAND48 */ +#elif defined(WIN32) + { + unsigned int *foo = (unsigned int *)rpool->pool; + srand(*foo); + } +#endif /* WIN32 */ + } + +} + +void sasl_rand (sasl_rand_t *rpool, char *buf, unsigned len) +{ + unsigned int lup; +#if defined(WIN32) && !defined(__MINGW32__) + unsigned int randomValue; +#endif + + /* check params */ + if (!rpool || !buf) return; + + /* init if necessary */ + randinit(rpool); + + for (lup = 0; lup < len; lup++) { +#if defined(__MINGW32__) + buf[lup] = (char) (rand() >> 8); +#elif defined(WIN32) + if (rand_s(&randomValue) != 0) { + randomValue = rand(); + } + + buf[lup] = (char) (randomValue >> 8); +#elif defined(macintosh) + buf[lup] = (char) (rand() >> 8); +#else /* !WIN32 && !macintosh */ +#ifdef HAVE_JRAND48 + buf[lup] = (char) (jrand48(rpool->pool) >> 8); +#else + buf[lup] = (char) (random() >> 8); +#endif /* HAVE_JRAND48 */ +#endif /* WIN32 */ + } +} + +/* this function is just a bad idea all around, since we're not trying to + implement a true random number generator */ +void sasl_churn (sasl_rand_t *rpool, const char *data, unsigned len) +{ + unsigned int lup; + + /* check params */ + if (!rpool || !data) return; + + /* init if necessary */ + randinit(rpool); + + for (lup=0; luppool[lup % RPOOL_SIZE] ^= data[lup]; +} + +void sasl_erasebuffer(char *buf, unsigned len) { + memset(buf, 0, len); +} + +/* Lowercase string in place */ +char *sasl_strlower ( + char *val +) +{ + int i; + + if (val == NULL) { + return (NULL); + } + +/* don't use tolower(), as it is locale dependent */ + + for (i = 0; val[i] != '\0'; i++) { + if (val[i] >= 'A' && val[i] <= 'Z') { + val[i] = val[i] - 'A' + 'a'; + } + } + + return (val); +} + +/* A version of gethostname that tries hard to return a FQDN */ +int get_fqhostname( + char *name, + int namelen, + int abort_if_no_fqdn +) +{ + int return_value; + struct addrinfo hints; + struct addrinfo *result; + + return_value = gethostname (name, namelen); + if (return_value != 0) { + return (return_value); + } + + if (strchr (name, '.') != NULL) { + goto LOWERCASE; + } + +/* gethostname hasn't returned a FQDN, we have to canonify it ourselves */ + hints.ai_family = PF_UNSPEC; + hints.ai_flags = AI_CANONNAME; + hints.ai_socktype = SOCK_STREAM; /* TCP only */ +/* A value of zero for ai_protocol indicates the caller will accept any protocol. or IPPROTO_TCP? */ + hints.ai_protocol = 0; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + hints.ai_addrlen = 0; + hints.ai_canonname = NULL; + hints.ai_addr = NULL; + hints.ai_next = NULL; + + if (getaddrinfo(name, + NULL, /* don't care abour service/port */ + &hints, + &result) != 0) { + if (abort_if_no_fqdn) { + /* errno on Unix, WSASetLastError on Windows are already done by the function */ + return (-1); + } else { + goto LOWERCASE; + } + } + + if (result == NULL || result->ai_canonname == NULL) { + freeaddrinfo (result); + if (abort_if_no_fqdn) { +#ifdef WIN32 + WSASetLastError (WSANO_DATA); +#elif defined(ENODATA) + errno = ENODATA; +#elif defined(EADDRNOTAVAIL) + errno = EADDRNOTAVAIL; +#endif + return (-1); + } else { + goto LOWERCASE; + } + } + + if (strchr (result->ai_canonname, '.') == NULL) { + freeaddrinfo (result); + if (abort_if_no_fqdn) { +#ifdef WIN32 + WSASetLastError (WSANO_DATA); +#elif defined(ENODATA) + errno = ENODATA; +#elif defined(EADDRNOTAVAIL) + errno = EADDRNOTAVAIL; +#endif + return (-1); + } else { + goto LOWERCASE; + } + } + + +/* Do we need to check for buffer overflow and set errno? */ + strncpy (name, result->ai_canonname, namelen); + freeaddrinfo (result); + +LOWERCASE: + sasl_strlower (name); + return (0); +} + +#ifdef WIN32 +/***************************************************************************** + * + * MODULE NAME : GETOPT.C + * + * COPYRIGHTS: + * This module contains code made available by IBM + * Corporation on an AS IS basis. Any one receiving the + * module is considered to be licensed under IBM copyrights + * to use the IBM-provided source code in any way he or she + * deems fit, including copying it, compiling it, modifying + * it, and redistributing it, with or without + * modifications. No license under any IBM patents or + * patent applications is to be implied from this copyright + * license. + * + * A user of the module should understand that IBM cannot + * provide technical support for the module and will not be + * responsible for any consequences of use of the program. + * + * Any notices, including this one, are not to be removed + * from the module without the prior written consent of + * IBM. + * + * AUTHOR: Original author: + * G. R. Blair (BOBBLAIR at AUSVM1) + * Internet: bobblair@bobblair.austin.ibm.com + * + * Extensively revised by: + * John Q. Walker II, Ph.D. (JOHHQ at RALVM6) + * Internet: johnq@ralvm6.vnet.ibm.com + * + *****************************************************************************/ + +/****************************************************************************** + * getopt() + * + * The getopt() function is a command line parser. It returns the next + * option character in argv that matches an option character in opstring. + * + * The argv argument points to an array of argc+1 elements containing argc + * pointers to character strings followed by a null pointer. + * + * The opstring argument points to a string of option characters; if an + * option character is followed by a colon, the option is expected to have + * an argument that may or may not be separated from it by white space. + * The external variable optarg is set to point to the start of the option + * argument on return from getopt(). + * + * The getopt() function places in optind the argv index of the next argument + * to be processed. The system initializes the external variable optind to + * 1 before the first call to getopt(). + * + * When all options have been processed (that is, up to the first nonoption + * argument), getopt() returns EOF. The special option "--" may be used to + * delimit the end of the options; EOF will be returned, and "--" will be + * skipped. + * + * The getopt() function returns a question mark (?) when it encounters an + * option character not included in opstring. This error message can be + * disabled by setting opterr to zero. Otherwise, it returns the option + * character that was detected. + * + * If the special option "--" is detected, or all options have been + * processed, EOF is returned. + * + * Options are marked by either a minus sign (-) or a slash (/). + * + * No errors are defined. + *****************************************************************************/ + +#include /* for strchr() */ + +/* static (global) variables that are specified as exported by getopt() */ +__declspec(dllexport) char *optarg = NULL; /* pointer to the start of the option argument */ +__declspec(dllexport) int optind = 1; /* number of the next argv[] to be evaluated */ +__declspec(dllexport) int opterr = 1; /* non-zero if a question mark should be returned */ + + +/* handle possible future character set concerns by putting this in a macro */ +#define _next_char(string) (char)(*(string+1)) + +int getopt(int argc, char *argv[], char *opstring) +{ + static char *pIndexPosition = NULL; /* place inside current argv string */ + char *pArgString = NULL; /* where to start from next */ + char *pOptString; /* the string in our program */ + + + if (pIndexPosition != NULL) { + /* we last left off inside an argv string */ + if (*(++pIndexPosition)) { + /* there is more to come in the most recent argv */ + pArgString = pIndexPosition; + } + } + + if (pArgString == NULL) { + /* we didn't leave off in the middle of an argv string */ + if (optind >= argc) { + /* more command-line arguments than the argument count */ + pIndexPosition = NULL; /* not in the middle of anything */ + return EOF; /* used up all command-line arguments */ + } + + /*--------------------------------------------------------------------- + * If the next argv[] is not an option, there can be no more options. + *-------------------------------------------------------------------*/ + pArgString = argv[optind++]; /* set this to the next argument ptr */ + + if (('/' != *pArgString) && /* doesn't start with a slash or a dash? */ + ('-' != *pArgString)) { + --optind; /* point to current arg once we're done */ + optarg = NULL; /* no argument follows the option */ + pIndexPosition = NULL; /* not in the middle of anything */ + return EOF; /* used up all the command-line flags */ + } + + /* check for special end-of-flags markers */ + if ((strcmp(pArgString, "-") == 0) || + (strcmp(pArgString, "--") == 0)) { + optarg = NULL; /* no argument follows the option */ + pIndexPosition = NULL; /* not in the middle of anything */ + return EOF; /* encountered the special flag */ + } + + pArgString++; /* look past the / or - */ + } + + if (':' == *pArgString) { /* is it a colon? */ + /*--------------------------------------------------------------------- + * Rare case: if opterr is non-zero, return a question mark; + * otherwise, just return the colon we're on. + *-------------------------------------------------------------------*/ + return (opterr ? (int)'?' : (int)':'); + } + else if ((pOptString = strchr(opstring, *pArgString)) == 0) { + /*--------------------------------------------------------------------- + * The letter on the command-line wasn't any good. + *-------------------------------------------------------------------*/ + optarg = NULL; /* no argument follows the option */ + pIndexPosition = NULL; /* not in the middle of anything */ + return (opterr ? (int)'?' : (int)*pArgString); + } + else { + /*--------------------------------------------------------------------- + * The letter on the command-line matches one we expect to see + *-------------------------------------------------------------------*/ + if (':' == _next_char(pOptString)) { /* is the next letter a colon? */ + /* It is a colon. Look for an argument string. */ + if ('\0' != _next_char(pArgString)) { /* argument in this argv? */ + optarg = &pArgString[1]; /* Yes, it is */ + } + else { + /*------------------------------------------------------------- + * The argument string must be in the next argv. + * But, what if there is none (bad input from the user)? + * In that case, return the letter, and optarg as NULL. + *-----------------------------------------------------------*/ + if (optind < argc) + optarg = argv[optind++]; + else { + optarg = NULL; + return (opterr ? (int)'?' : (int)*pArgString); + } + } + pIndexPosition = NULL; /* not in the middle of anything */ + } + else { + /* it's not a colon, so just return the letter */ + optarg = NULL; /* no argument follows the option */ + pIndexPosition = pArgString; /* point to the letter we're on */ + } + return (int)*pArgString; /* return the letter that matched */ + } +} + +#ifndef PASSWORD_MAX +# define PASSWORD_MAX 255 +#endif + +#include +char * +getpass(prompt) +const char *prompt; +{ + register char *p; + register int c; + static char pbuf[PASSWORD_MAX]; + + fprintf(stderr, "%s", prompt); (void) fflush(stderr); + for (p=pbuf; (c = _getch())!=13 && c!=EOF;) { + if (p < &pbuf[sizeof(pbuf)-1]) + *p++ = (char) c; + } + *p = '\0'; + fprintf(stderr, "\n"); (void) fflush(stderr); + return(pbuf); +} + + + +#endif /* WIN32 */ diff --git a/libs/cyrussasl/lib/server.c b/libs/cyrussasl/lib/server.c new file mode 100644 index 00000000..490b6521 --- /dev/null +++ b/libs/cyrussasl/lib/server.c @@ -0,0 +1,2398 @@ +/* SASL server API implementation + * Rob Siemborski + * Tim Martin + * $Id: server.c,v 1.177 2011/11/08 17:22:40 murch Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* local functions/structs don't start with sasl + */ +#include +#include +#include +#include +#include +#ifndef macintosh +#include +#include +#endif +#include +#include +#include + +#include "sasl.h" +#include "saslint.h" +#include "saslplug.h" +#include "saslutil.h" + +#define DEFAULT_CHECKPASS_MECH "auxprop" + +/* Contains functions: + * + * sasl_server_init + * sasl_server_new + * sasl_listmech + * sasl_server_start + * sasl_server_step + * sasl_checkpass + * sasl_checkapop + * sasl_user_exists + * sasl_setpass + */ + +/* if we've initialized the server sucessfully */ +static int _sasl_server_active = 0; + +/* For access by other modules */ +int _is_sasl_server_active(void) { return _sasl_server_active; } + +static int _sasl_checkpass(sasl_conn_t *conn, + const char *user, unsigned userlen, + const char *pass, unsigned passlen); + +static mech_list_t *mechlist = NULL; /* global var which holds the list */ + +static sasl_global_callbacks_t global_callbacks; + +/* set the password for a user + * conn -- SASL connection + * user -- user name + * pass -- plaintext password, may be NULL to remove user + * passlen -- length of password, 0 = strlen(pass) + * oldpass -- NULL will sometimes work + * oldpasslen -- length of password, 0 = strlen(oldpass) + * flags -- see flags below + * + * returns: + * SASL_NOCHANGE -- proper entry already exists + * SASL_NOMECH -- no authdb supports password setting as configured + * SASL_NOVERIFY -- user exists, but no settable password present + * SASL_DISABLED -- account disabled + * SASL_PWLOCK -- password locked + * SASL_WEAKPASS -- password too weak for security policy + * SASL_NOUSERPASS -- user-supplied passwords not permitted + * SASL_FAIL -- OS error + * SASL_BADPARAM -- password too long + * SASL_OK -- successful + */ + +int sasl_setpass(sasl_conn_t *conn, + const char *user, + const char *pass, + unsigned passlen, + const char *oldpass, + unsigned oldpasslen, + unsigned flags) +{ + int result = SASL_OK, tmpresult; + sasl_server_conn_t *s_conn = (sasl_server_conn_t *) conn; + const char *password_request[] = { SASL_AUX_PASSWORD_PROP, NULL }; + const char *user_delete_request[] = { SASL_AUX_PASSWORD_PROP, SASL_AUX_ALL, NULL }; + sasl_server_userdb_setpass_t *setpass_cb = NULL; + void *context = NULL; + int tried_setpass = 0; + int failed = 0; + mechanism_t *sm; + server_sasl_mechanism_t *m; + char *current_mech; + + if (!_sasl_server_active || !mechlist) return SASL_NOTINIT; + + /* check params */ + if (!conn) return SASL_BADPARAM; + if (conn->type != SASL_CONN_SERVER) PARAMERROR(conn); + + if ((!(flags & SASL_SET_DISABLE) && passlen == 0) + || ((flags & SASL_SET_CREATE) && (flags & SASL_SET_DISABLE))) + PARAMERROR(conn); + + /* Check that we have an active SASL mechanism */ + if (sasl_getprop (conn, + SASL_MECHNAME, + (const void **) ¤t_mech) != SASL_OK) { + current_mech = NULL; + } + + if ( (flags & SASL_SET_CURMECH_ONLY) && + (current_mech == NULL) ) { + sasl_seterror( conn, SASL_NOLOG, + "No current SASL mechanism available"); + RETURN(conn, SASL_BADPARAM); + } + + /* Do we want to store SASL_AUX_PASSWORD_PROP (plain text)? and + * Do we have an auxprop backend that can store properties? + */ + if ((flags & SASL_SET_DISABLE || !(flags & SASL_SET_NOPLAIN)) && + sasl_auxprop_store(NULL, NULL, NULL) == SASL_OK) { + + tried_setpass++; + + if (flags & SASL_SET_DISABLE) { + pass = NULL; + passlen = 0; + result = prop_request(s_conn->sparams->propctx, user_delete_request); + } else { + result = prop_request(s_conn->sparams->propctx, password_request); + } + if (result == SASL_OK) { + /* NOTE: When deleting users, this will work in a backward compatible way */ + result = prop_set(s_conn->sparams->propctx, SASL_AUX_PASSWORD_PROP, + pass, passlen); + } + if (result == SASL_OK && flags & SASL_SET_DISABLE) { + result = prop_set(s_conn->sparams->propctx, SASL_AUX_ALL, + NULL, 0); + } + if (result == SASL_OK) { + result = sasl_auxprop_store(conn, s_conn->sparams->propctx, user); + } + if (result != SASL_OK) { + _sasl_log(conn, SASL_LOG_ERR, + "setpass failed for %s: %z", + user, result); + failed++; + } else { + _sasl_log(conn, SASL_LOG_NOTE, + "setpass succeeded for %s", user); + } + } + + /* We want to preserve the current value of result, so we use tmpresult below */ + + /* call userdb callback function */ + tmpresult = _sasl_getcallback(conn, SASL_CB_SERVER_USERDB_SETPASS, + (sasl_callback_ft *)&setpass_cb, &context); + if (tmpresult == SASL_OK && setpass_cb) { + + tried_setpass++; + + tmpresult = setpass_cb(conn, context, user, pass, passlen, + s_conn->sparams->propctx, flags); + if(tmpresult != SASL_OK) { + if (tmpresult == SASL_CONSTRAINT_VIOLAT) { + if (result == SASL_OK) { + result = tmpresult; + } + } else { + result = tmpresult; + } + _sasl_log(conn, SASL_LOG_ERR, + "setpass callback failed for %s: %z", + user, tmpresult); + failed++; + } else { + _sasl_log(conn, SASL_LOG_NOTE, + "setpass callback succeeded for %s", user); + } + } + + /* now we let the mechanisms set their secrets */ + for (sm = s_conn->mech_list; sm; sm = sm->next) { + m = &sm->m; + + if (!m->plug->setpass) { + /* can't set pass for this mech */ + continue; + } + + /* Invoke only one setpass for the currently selected mechanism, + if SASL_SET_CURMECH_ONLY is specified */ + if ((flags & SASL_SET_CURMECH_ONLY) && + (strcmp(current_mech, m->plug->mech_name) != 0)) { + continue; + } + + tried_setpass++; + + tmpresult = m->plug->setpass(m->plug->glob_context, + ((sasl_server_conn_t *)conn)->sparams, + user, + pass, + passlen, + oldpass, oldpasslen, + flags); + if (tmpresult == SASL_OK) { + _sasl_log(conn, SASL_LOG_NOTE, + "%s: set secret for %s", m->plug->mech_name, user); + + m->condition = SASL_OK; /* if we previously thought the + mechanism didn't have any user secrets + we now think it does */ + + } else if (tmpresult == SASL_NOCHANGE) { + _sasl_log(conn, SASL_LOG_NOTE, + "%s: secret not changed for %s", m->plug->mech_name, user); + } else if (tmpresult == SASL_CONSTRAINT_VIOLAT) { + _sasl_log(conn, SASL_LOG_ERR, + "%s: failed to set secret for %s: constrain violation", + m->plug->mech_name, user); + if (result == SASL_OK) { + result = tmpresult; + } + failed++; + } else { + result = tmpresult; + _sasl_log(conn, SASL_LOG_ERR, + "%s: failed to set secret for %s: %z (%m)", + m->plug->mech_name, user, tmpresult, +#ifndef WIN32 + errno +#else + GetLastError() +#endif + ); + failed++; + } + } + + if (!tried_setpass) { + _sasl_log(conn, SASL_LOG_WARN, + "secret not changed for %s: " + "no writable auxprop plugin or setpass callback found", + user); + } else if (result == SASL_CONSTRAINT_VIOLAT) { + /* If not all setpass failed with SASL_CONSTRAINT_VIOLAT - + ignore SASL_CONSTRAINT_VIOLAT */ + if (failed < tried_setpass) { + result = SASL_OK; + } + } + + RETURN(conn, result); +} + +/* local mechanism which disposes of server */ +static void server_dispose(sasl_conn_t *pconn) +{ + sasl_server_conn_t *s_conn= (sasl_server_conn_t *) pconn; + context_list_t *cur, *cur_next; + + /* Just sanity check that sasl_server_done wasn't called yet */ + if (_sasl_server_active != 0) { + if (s_conn->mech) { + void (*mech_dispose)(void *conn_context, const sasl_utils_t *utils); + + mech_dispose = s_conn->mech->m.plug->mech_dispose; + + if (mech_dispose) { + mech_dispose(pconn->context, s_conn->sparams->utils); + } + } + pconn->context = NULL; + + for(cur = s_conn->mech_contexts; cur; cur=cur_next) { + cur_next = cur->next; + if (cur->context) { + cur->mech->m.plug->mech_dispose(cur->context, s_conn->sparams->utils); + } + sasl_FREE(cur); + } + s_conn->mech_contexts = NULL; + } + + _sasl_free_utils(&s_conn->sparams->utils); + + if (s_conn->sparams->propctx) { + prop_dispose(&s_conn->sparams->propctx); + } + + if (s_conn->appname) { + sasl_FREE(s_conn->appname); + } + + if (s_conn->user_realm) { + sasl_FREE(s_conn->user_realm); + } + + if (s_conn->sparams) { + sasl_FREE(s_conn->sparams); + } + + if (s_conn->mech_list != mechlist->mech_list) { + /* free connection-specific mech_list */ + mechanism_t *m, *prevm; + + m = s_conn->mech_list; /* m point to beginning of the list */ + + while (m) { + prevm = m; + m = m->next; + sasl_FREE(prevm); + } + } + + _sasl_conn_dispose(pconn); +} + +static int init_mechlist(void) +{ + sasl_utils_t *newutils = NULL; + + /* set util functions - need to do rest */ + newutils = _sasl_alloc_utils(NULL, &global_callbacks); + if (newutils == NULL) + return SASL_NOMEM; + + newutils->checkpass = &_sasl_checkpass; + + mechlist->utils = newutils; + mechlist->mech_list = NULL; + mechlist->mech_length = 0; + + return SASL_OK; +} + +static int mech_compare(const sasl_server_plug_t *a, + const sasl_server_plug_t *b) +{ + unsigned sec_diff; + unsigned features_diff; + + /* XXX the following is fairly arbitrary, but its independent + of the order in which the plugins are loaded + */ + sec_diff = a->security_flags ^ b->security_flags; + if (sec_diff & a->security_flags & SASL_SEC_NOANONYMOUS) return 1; + if (sec_diff & b->security_flags & SASL_SEC_NOANONYMOUS) return -1; + if (sec_diff & a->security_flags & SASL_SEC_NOPLAINTEXT) return 1; + if (sec_diff & b->security_flags & SASL_SEC_NOPLAINTEXT) return -1; + if (sec_diff & a->security_flags & SASL_SEC_MUTUAL_AUTH) return 1; + if (sec_diff & b->security_flags & SASL_SEC_MUTUAL_AUTH) return -1; + if (sec_diff & a->security_flags & SASL_SEC_NOACTIVE) return 1; + if (sec_diff & b->security_flags & SASL_SEC_NOACTIVE) return -1; + if (sec_diff & a->security_flags & SASL_SEC_NODICTIONARY) return 1; + if (sec_diff & b->security_flags & SASL_SEC_NODICTIONARY) return -1; + if (sec_diff & a->security_flags & SASL_SEC_FORWARD_SECRECY) return 1; + if (sec_diff & b->security_flags & SASL_SEC_FORWARD_SECRECY) return -1; + + features_diff = a->features ^ b->features; + if (features_diff & a->features & SASL_FEAT_CHANNEL_BINDING) return 1; + if (features_diff & b->features & SASL_FEAT_CHANNEL_BINDING) return -1; + + if (a->max_ssf > b->max_ssf) return 1; + if (a->max_ssf < b->max_ssf) return -1; + + return 0; +} + +/* + * parameters: + * p - entry point + */ +int sasl_server_add_plugin(const char *plugname, + sasl_server_plug_init_t *p) +{ + int plugcount; + sasl_server_plug_t *pluglist; + sasl_server_plug_init_t *entry_point; + int result; + int version; + int lupe; + + if(!plugname || !p) return SASL_BADPARAM; + + entry_point = (sasl_server_plug_init_t *)p; + + /* call into the shared library asking for information about it */ + /* version is filled in with the version of the plugin */ + result = entry_point(mechlist->utils, SASL_SERVER_PLUG_VERSION, &version, + &pluglist, &plugcount); + + if ((result != SASL_OK) && (result != SASL_NOUSER) + && (result != SASL_CONTINUE)) { + _sasl_log(NULL, SASL_LOG_DEBUG, + "%s_client_plug_init() failed in sasl_server_add_plugin(): %z\n", + plugname, result); + return result; + } + + /* Make sure plugin is using the same SASL version as us */ + if (version != SASL_SERVER_PLUG_VERSION) + { + _sasl_log(NULL, + SASL_LOG_ERR, + "version mismatch on sasl_server_add_plugin for '%s': %d expected, but %d reported", + plugname, + SASL_SERVER_PLUG_VERSION, + version); + return SASL_BADVERS; + } + + for (lupe=0;lupe < plugcount ;lupe++, pluglist++) + { + mechanism_t *mech, *mp; + + mech = sasl_ALLOC(sizeof(mechanism_t)); + if (! mech) return SASL_NOMEM; + memset (mech, 0, sizeof(mechanism_t)); + + mech->m.plug = pluglist; + if(_sasl_strdup(plugname, &mech->m.plugname, NULL) != SASL_OK) { + sasl_FREE(mech); + return SASL_NOMEM; + } + mech->m.version = version; + + /* whether this mech actually has any users in it's db */ + mech->m.condition = result; /* SASL_OK, SASL_CONTINUE or SASL_NOUSER */ + + /* mech->m.f = NULL; */ + + /* sort mech_list by relative "strength" */ + mp = mechlist->mech_list; + if (!mp || mech_compare(pluglist, mp->m.plug) >= 0) { + /* add mech to head of list */ + mech->next = mechlist->mech_list; + mechlist->mech_list = mech; + } else { + /* find where to insert mech into list */ + while (mp->next && + mech_compare(pluglist, mp->next->m.plug) <= 0) mp = mp->next; + mech->next = mp->next; + mp->next = mech; + } + mechlist->mech_length++; + } + + return SASL_OK; +} + +int sasl_server_done(void) +{ + int result = SASL_CONTINUE; + + if (_sasl_server_cleanup_hook == NULL && _sasl_client_cleanup_hook == NULL) { + return SASL_NOTINIT; + } + + if (_sasl_server_cleanup_hook) { + result = _sasl_server_cleanup_hook(); + + if (result == SASL_OK) { + _sasl_server_idle_hook = NULL; + _sasl_server_cleanup_hook = NULL; + } else { + return result; + } + } + + if (_sasl_server_cleanup_hook || _sasl_client_cleanup_hook) { + return result; + } + + sasl_common_done(); + + return SASL_OK; +} + +static int server_done(void) { + mechanism_t *m; + mechanism_t *prevm; + + if(_sasl_server_active == 0) + return SASL_NOTINIT; + else + _sasl_server_active--; + + if(_sasl_server_active) { + /* Don't de-init yet! Our refcount is nonzero. */ + return SASL_CONTINUE; + } + + if (mechlist != NULL) + { + m=mechlist->mech_list; /* m point to beginning of the list */ + + while (m!=NULL) + { + prevm=m; + m=m->next; + + if (prevm->m.plug->mech_free) { + prevm->m.plug->mech_free(prevm->m.plug->glob_context, + mechlist->utils); + } + + sasl_FREE(prevm->m.plugname); + sasl_FREE(prevm); + } + _sasl_free_utils(&mechlist->utils); + sasl_FREE(mechlist); + mechlist = NULL; + } + + /* Free the auxprop plugins */ + _sasl_auxprop_free(); + + global_callbacks.callbacks = NULL; + global_callbacks.appname = NULL; + + sasl_config_done(); + + return SASL_OK; +} + +static int server_idle(sasl_conn_t *conn) +{ + sasl_server_conn_t *s_conn = (sasl_server_conn_t *) conn; + mechanism_t *m; + + if (! mechlist) { + return 0; + } + + for (m = s_conn->mech_list; + m != NULL; + m = m->next) { + if (m->m.plug->idle + && m->m.plug->idle(m->m.plug->glob_context, + conn, + conn ? ((sasl_server_conn_t *)conn)->sparams : NULL)) { + return 1; + } + } + + return 0; +} + +static int load_config(const sasl_callback_t *verifyfile_cb) +{ + int result; + const char *path_to_config = NULL; + size_t path_len; + char *config_filename = NULL; + size_t len; + const sasl_callback_t *getconfpath_cb = NULL; + const char * next; + + /* If appname was not provided, behave as if there is no config file + (see also sasl_config_init() */ + if (global_callbacks.appname == NULL) { + return SASL_CONTINUE; + } + + /* get the path to the config file */ + getconfpath_cb = _sasl_find_getconfpath_callback( global_callbacks.callbacks ); + if (getconfpath_cb == NULL) return SASL_BADPARAM; + + /* getconfpath_cb->proc MUST be a sasl_getconfpath_t; if only C had a type + system */ + result = ((sasl_getconfpath_t *)(getconfpath_cb->proc))(getconfpath_cb->context, + (char **) &path_to_config); + if (result != SASL_OK) goto done; + if (path_to_config == NULL) path_to_config = ""; + + next = path_to_config; + + while (next != NULL) { + next = strchr(path_to_config, PATHS_DELIMITER); + + /* length = length of path + '/' + length of appname + ".conf" + 1 + for '\0' */ + + if (next != NULL) { + path_len = next - path_to_config; + next++; /* Skip to the next path */ + } else { + path_len = strlen(path_to_config); + } + + len = path_len + 2 + strlen(global_callbacks.appname) + 5 + 1; + + if (len > PATH_MAX ) { + result = SASL_FAIL; + goto done; + } + + /* construct the filename for the config file */ + config_filename = sasl_ALLOC((unsigned)len); + if (! config_filename) { + result = SASL_NOMEM; + goto done; + } + + snprintf(config_filename, len, "%.*s%c%s.conf", path_len, path_to_config, + HIER_DELIMITER, global_callbacks.appname); + + /* Ask the application if it's safe to use this file */ + result = ((sasl_verifyfile_t *)(verifyfile_cb->proc))(verifyfile_cb->context, + config_filename, SASL_VRFY_CONF); + + /* returns SASL_CONTINUE if the config file doesn't exist */ + if (result == SASL_OK) { + result = sasl_config_init(config_filename); + + if (result != SASL_CONTINUE) { + /* We are done */ + break; + } + } + + if (config_filename) { + sasl_FREE(config_filename); + config_filename = NULL; + } + + path_to_config = next; + } + + done: + if (config_filename) sasl_FREE(config_filename); + + return result; +} + +/* + * Verify that all the callbacks are valid + */ +static int verify_server_callbacks(const sasl_callback_t *callbacks) +{ + if (callbacks == NULL) return SASL_OK; + + while (callbacks->id != SASL_CB_LIST_END) { + if (callbacks->proc==NULL) return SASL_FAIL; + + callbacks++; + } + + return SASL_OK; +} + +static char *grab_field(char *line, char **eofield) +{ + int d = 0; + char *field; + + while (isspace((int) *line)) line++; + + /* find end of field */ + while (line[d] && !isspace(((int) line[d]))) d++; + field = sasl_ALLOC(d + 1); + if (!field) { return NULL; } + memcpy(field, line, d); + field[d] = '\0'; + *eofield = line + d; + + return field; +} + +struct secflag_map_s { + char *name; + int value; +}; + +struct secflag_map_s secflag_map[] = { + { "noplaintext", SASL_SEC_NOPLAINTEXT }, + { "noactive", SASL_SEC_NOACTIVE }, + { "nodictionary", SASL_SEC_NODICTIONARY }, + { "forward_secrecy", SASL_SEC_FORWARD_SECRECY }, + { "noanonymous", SASL_SEC_NOANONYMOUS }, + { "pass_credentials", SASL_SEC_PASS_CREDENTIALS }, + { "mutual_auth", SASL_SEC_MUTUAL_AUTH }, + { NULL, 0x0 } +}; + +static int parse_mechlist_file(const char *mechlistfile) +{ + FILE *f; + char buf[1024]; + char *t, *ptr; + int r = 0; + + f = fopen(mechlistfile, "r"); + if (!f) return SASL_FAIL; + + r = SASL_OK; + while (fgets(buf, sizeof(buf), f) != NULL) { + mechanism_t *n = sasl_ALLOC(sizeof(mechanism_t)); + sasl_server_plug_t *nplug; + + if (n == NULL) { r = SASL_NOMEM; break; } + n->m.version = SASL_SERVER_PLUG_VERSION; + n->m.condition = SASL_CONTINUE; + nplug = sasl_ALLOC(sizeof(sasl_server_plug_t)); + if (nplug == NULL) { r = SASL_NOMEM; break; } + memset(nplug, 0, sizeof(sasl_server_plug_t)); + + /* each line is: + plugin-file WS mech_name WS max_ssf *(WS security_flag) RET + */ + + /* grab file */ + n->m.f = grab_field(buf, &ptr); + + /* grab mech_name */ + nplug->mech_name = grab_field(ptr, &ptr); + + /* grab max_ssf */ + nplug->max_ssf = strtol(ptr, &ptr, 10); + + /* grab security flags */ + while (*ptr != '\n') { + struct secflag_map_s *map; + + /* read security flag */ + t = grab_field(ptr, &ptr); + map = secflag_map; + while (map->name) { + if (!strcasecmp(t, map->name)) { + nplug->security_flags |= map->value; + break; + } + map++; + } + if (!map->name) { + _sasl_log(NULL, SASL_LOG_ERR, + "%s: couldn't identify flag '%s'", + nplug->mech_name, t); + } + free(t); + } + + /* insert mechanism into mechlist */ + n->m.plug = nplug; + n->next = mechlist->mech_list; + mechlist->mech_list = n; + mechlist->mech_length++; + } + + fclose(f); + return r; +} + +/* initialize server drivers, done once per process + * callbacks -- callbacks for all server connections; must include + * getopt callback + * appname -- name of calling application + * (for lower level logging and reading of the configuration file) + * results: + * state -- server state + * returns: + * SASL_OK -- success + * SASL_BADPARAM -- error in config file + * SASL_NOMEM -- memory failure + * SASL_BADVERS -- Mechanism version mismatch + */ + +int sasl_server_init(const sasl_callback_t *callbacks, + const char *appname) +{ + int ret; + const sasl_callback_t *vf; + const char *pluginfile = NULL; +#ifdef PIC + sasl_getopt_t *getopt; + void *context; +#endif + + const add_plugin_list_t ep_list[] = { + { "sasl_server_plug_init", (add_plugin_t *)sasl_server_add_plugin }, + { "sasl_auxprop_plug_init", (add_plugin_t *)sasl_auxprop_add_plugin }, + { "sasl_canonuser_init", (add_plugin_t *)sasl_canonuser_add_plugin }, + { NULL, NULL } + }; + + /* lock allocation type */ + _sasl_allocation_locked++; + + /* we require the appname (if present) to be short enough to be a path */ + if (appname != NULL && strlen(appname) >= PATH_MAX) + return SASL_BADPARAM; + + if (_sasl_server_active) { + /* We're already active, just increase our refcount */ + /* xxx do something with the callback structure? */ + _sasl_server_active++; + return SASL_OK; + } + + ret = _sasl_common_init(&global_callbacks); + if (ret != SASL_OK) + return ret; + + /* verify that the callbacks look ok */ + ret = verify_server_callbacks(callbacks); + if (ret != SASL_OK) + return ret; + + global_callbacks.callbacks = callbacks; + + /* A shared library calling sasl_server_init will pass NULL as appname. + This should retain the original appname. */ + if (appname != NULL) { + global_callbacks.appname = appname; + } + + /* If we fail now, we have to call server_done */ + _sasl_server_active = 1; + + /* allocate mechlist and set it to empty */ + mechlist = sasl_ALLOC(sizeof(mech_list_t)); + if (mechlist == NULL) { + server_done(); + return SASL_NOMEM; + } + + ret = init_mechlist(); + if (ret != SASL_OK) { + server_done(); + return ret; + } + + vf = _sasl_find_verifyfile_callback(callbacks); + + /* load config file if applicable */ + ret = load_config(vf); + if ((ret != SASL_OK) && (ret != SASL_CONTINUE)) { + server_done(); + return ret; + } + + /* load internal plugins */ + sasl_server_add_plugin("EXTERNAL", &external_server_plug_init); + +#ifdef PIC + /* delayed loading of plugins? (DSO only, as it doesn't + * make much [any] sense to delay in the static library case) */ + if (_sasl_getcallback(NULL, SASL_CB_GETOPT, (sasl_callback_ft *)&getopt, &context) + == SASL_OK) { + /* No sasl_conn_t was given to getcallback, so we provide the + * global callbacks structure */ + ret = getopt(&global_callbacks, NULL, "plugin_list", &pluginfile, NULL); + } +#endif + + if (pluginfile != NULL) { + /* this file should contain a list of plugins available. + we'll load on demand. */ + + /* Ask the application if it's safe to use this file */ + ret = ((sasl_verifyfile_t *)(vf->proc))(vf->context, + pluginfile, + SASL_VRFY_CONF); + if (ret != SASL_OK) { + _sasl_log(NULL, SASL_LOG_ERR, + "unable to load plugin list %s: %z", pluginfile, ret); + } + + if (ret == SASL_OK) { + ret = parse_mechlist_file(pluginfile); + } + } else { + /* load all plugins now */ + ret = _sasl_load_plugins(ep_list, + _sasl_find_getpath_callback(callbacks), + _sasl_find_verifyfile_callback(callbacks)); + } + + if (ret == SASL_OK) { + _sasl_server_cleanup_hook = &server_done; + _sasl_server_idle_hook = &server_idle; + + ret = _sasl_build_mechlist(); + } else { + server_done(); + } + + return ret; +} + +/* + * Once we have the users plaintext password we + * may want to transition them. That is put entries + * for them in the passwd database for other + * stronger mechanism + * + * for example PLAIN -> CRAM-MD5 + */ +static int +_sasl_transition(sasl_conn_t * conn, + const char * pass, + unsigned passlen) +{ + const char *dotrans = "n"; + sasl_getopt_t *getopt; + int result = SASL_OK; + void *context; + unsigned flags = 0; + + if (! conn) + return SASL_BADPARAM; + + if (! conn->oparams.authid) + PARAMERROR(conn); + + /* check if this is enabled: default to false */ + if (_sasl_getcallback(conn, SASL_CB_GETOPT, (sasl_callback_ft *)&getopt, &context) == SASL_OK) + { + getopt(context, NULL, "auto_transition", &dotrans, NULL); + if (dotrans == NULL) dotrans = "n"; + } + + + if (!strcmp(dotrans, "noplain")) flags |= SASL_SET_NOPLAIN; + + if (flags || *dotrans == '1' || *dotrans == 'y' || + (*dotrans == 'o' && dotrans[1] == 'n') || *dotrans == 't') { + /* ok, it's on! */ + _sasl_log(conn, SASL_LOG_NOTE, + "transitioning user %s to auxprop database", + conn->oparams.authid); + result = sasl_setpass(conn, + conn->oparams.authid, + pass, + passlen, + NULL, 0, SASL_SET_CREATE | flags); + } + + RETURN(conn,result); +} + + +/* create context for a single SASL connection + * service -- registered name of the service using SASL (e.g. "imap") + * serverFQDN -- Fully qualified domain name of server. NULL means use + * gethostname() or equivalent. + * Useful for multi-homed servers. + * user_realm -- permits multiple user realms on server, NULL = default + * iplocalport -- server IPv4/IPv6 domain literal string with port + * (if NULL, then mechanisms requiring IPaddr are disabled) + * ipremoteport -- client IPv4/IPv6 domain literal string with port + * (if NULL, then mechanisms requiring IPaddr are disabled) + * callbacks -- callbacks (e.g., authorization, lang, new getopt context) + * flags -- usage flags (see above) + * returns: + * pconn -- new connection context + * + * returns: + * SASL_OK -- success + * SASL_NOMEM -- not enough memory + */ + +int sasl_server_new(const char *service, + const char *serverFQDN, + const char *user_realm, + const char *iplocalport, + const char *ipremoteport, + const sasl_callback_t *callbacks, + unsigned flags, + sasl_conn_t **pconn) +{ + int result; + sasl_server_conn_t *serverconn; + sasl_utils_t *utils; + sasl_getopt_t *getopt; + void *context; + const char *log_level, *auto_trans; + const char *mlist = NULL; + int plus = 0; + + if (_sasl_server_active==0) return SASL_NOTINIT; + if (! pconn) return SASL_FAIL; + if (! service) return SASL_FAIL; + + *pconn=sasl_ALLOC(sizeof(sasl_server_conn_t)); + if (*pconn==NULL) return SASL_NOMEM; + + memset(*pconn, 0, sizeof(sasl_server_conn_t)); + + serverconn = (sasl_server_conn_t *)*pconn; + + /* make sparams */ + serverconn->sparams=sasl_ALLOC(sizeof(sasl_server_params_t)); + if (serverconn->sparams==NULL) + MEMERROR(*pconn); + + memset(serverconn->sparams, 0, sizeof(sasl_server_params_t)); + + (*pconn)->destroy_conn = &server_dispose; + result = _sasl_conn_init(*pconn, service, flags, SASL_CONN_SERVER, + &server_idle, serverFQDN, + iplocalport, ipremoteport, + callbacks, &global_callbacks); + if (result != SASL_OK) + goto done_error; + + + /* set util functions - need to do rest */ + utils=_sasl_alloc_utils(*pconn, &global_callbacks); + if (!utils) { + result = SASL_NOMEM; + goto done_error; + } + + utils->checkpass = &_sasl_checkpass; + + /* Setup the propctx -> We'll assume the default size */ + serverconn->sparams->propctx=prop_new(0); + if(!serverconn->sparams->propctx) { + result = SASL_NOMEM; + goto done_error; + } + + serverconn->sparams->service = (*pconn)->service; + serverconn->sparams->servicelen = (unsigned) strlen((*pconn)->service); + + if (global_callbacks.appname && global_callbacks.appname[0] != '\0') { + result = _sasl_strdup (global_callbacks.appname, + &serverconn->appname, + NULL); + if (result != SASL_OK) { + result = SASL_NOMEM; + goto done_error; + } + serverconn->sparams->appname = serverconn->appname; + serverconn->sparams->applen = (unsigned) strlen(serverconn->sparams->appname); + } else { + serverconn->appname = NULL; + serverconn->sparams->appname = NULL; + serverconn->sparams->applen = 0; + } + + serverconn->sparams->serverFQDN = (*pconn)->serverFQDN; + serverconn->sparams->slen = (unsigned) strlen((*pconn)->serverFQDN); + + if (user_realm) { + result = _sasl_strdup(user_realm, &serverconn->user_realm, NULL); + serverconn->sparams->urlen = (unsigned) strlen(user_realm); + serverconn->sparams->user_realm = serverconn->user_realm; + } else { + serverconn->user_realm = NULL; + /* the sparams is already zeroed */ + } + + serverconn->sparams->callbacks = callbacks; + + log_level = auto_trans = NULL; + if(_sasl_getcallback(*pconn, SASL_CB_GETOPT, (sasl_callback_ft *)&getopt, &context) == SASL_OK) { + getopt(context, NULL, "log_level", &log_level, NULL); + getopt(context, NULL, "auto_transition", &auto_trans, NULL); + getopt(context, NULL, "mech_list", &mlist, NULL); + } + serverconn->sparams->log_level = log_level ? atoi(log_level) : SASL_LOG_ERR; + + serverconn->sparams->utils = utils; + + if (auto_trans && + (*auto_trans == '1' || *auto_trans == 'y' || *auto_trans == 't' || + (*auto_trans == 'o' && auto_trans[1] == 'n') || + !strcmp(auto_trans, "noplain")) && + sasl_auxprop_store(NULL, NULL, NULL) == SASL_OK) { + serverconn->sparams->transition = &_sasl_transition; + } + + /* if we have a mech_list, create ordered list of avail mechs for this conn */ + if (mlist) { + const char *cp; + mechanism_t *mptr, *tail = NULL; + + while (*mlist) { + /* find end of current mech name */ + for (cp = mlist; *cp && !isspace((int) *cp); cp++); + + /* search for mech name in loaded plugins */ + for (mptr = mechlist->mech_list; mptr; mptr = mptr->next) { + const sasl_server_plug_t *plug = mptr->m.plug; + + if (_sasl_is_equal_mech(mlist, plug->mech_name, (size_t) (cp - mlist), &plus)) { + /* found a match */ + break; + } + } + if (mptr) { + mechanism_t *new = sasl_ALLOC(sizeof(mechanism_t)); + if (!new) return SASL_NOMEM; + + memcpy(&new->m, &mptr->m, sizeof(server_sasl_mechanism_t)); + new->next = NULL; + + if (!serverconn->mech_list) { + serverconn->mech_list = new; + tail = serverconn->mech_list; + } + else { + tail->next = new; + tail = new; + } + serverconn->mech_length++; + } + + /* find next mech name */ + mlist = cp; + while (*mlist && isspace((int) *mlist)) mlist++; + } + } + else { + serverconn->mech_list = mechlist->mech_list; + serverconn->mech_length = mechlist->mech_length; + } + + serverconn->sparams->canon_user = &_sasl_canon_user_lookup; + serverconn->sparams->props = serverconn->base.props; + serverconn->sparams->flags = flags; + + if(result == SASL_OK) return SASL_OK; + + done_error: + _sasl_conn_dispose(*pconn); + sasl_FREE(*pconn); + *pconn = NULL; + return result; +} + +/* + * The rule is: + * IF mech strength + external strength < min ssf THEN FAIL. + * We also have to look at the security properties and make sure + * that this mechanism has everything we want. + */ +static int mech_permitted(sasl_conn_t *conn, + mechanism_t *mech) +{ + sasl_server_conn_t *s_conn = (sasl_server_conn_t *)conn; + const sasl_server_plug_t *plug; + int ret; + int myflags; + context_list_t *cur; + context_list_t *mech_context_list_entry = NULL; + void *context = NULL; + sasl_ssf_t minssf = 0; + + if(!conn) return SASL_NOMECH; + + if(! mech || ! mech->m.plug) { + PARAMERROR(conn); + return SASL_NOMECH; + } + + plug = mech->m.plug; + + /* setup parameters for the call to mech_avail */ + s_conn->sparams->serverFQDN=conn->serverFQDN; + s_conn->sparams->service=conn->service; + s_conn->sparams->user_realm=s_conn->user_realm; + s_conn->sparams->props=conn->props; + s_conn->sparams->external_ssf=conn->external.ssf; + + /* Check if we have banished this one already */ + for (cur = s_conn->mech_contexts; cur; cur=cur->next) { + if (cur->mech == mech) { + /* If it's not mech_avail'd, then stop now */ + if (!cur->context) { + return SASL_NOMECH; + } else { + context = cur->context; + mech_context_list_entry = cur; + } + break; + } + } + + if (conn->props.min_ssf < conn->external.ssf) { + minssf = 0; + } else { + minssf = conn->props.min_ssf - conn->external.ssf; + } + + /* Generic mechanism */ + if (plug->max_ssf < minssf) { + sasl_seterror(conn, SASL_NOLOG, + "mech %s is too weak", plug->mech_name); + return SASL_TOOWEAK; /* too weak */ + } + + if (plug->mech_avail + && (ret = plug->mech_avail(plug->glob_context, + s_conn->sparams, + (void **)&context)) != SASL_OK ) { + if (ret == SASL_NOMECH) { + /* Mark this mech as no good for this connection */ + cur = sasl_ALLOC(sizeof(context_list_t)); + if (!cur) { + MEMERROR(conn); + return SASL_NOMECH; + } + cur->context = NULL; + cur->mech = mech; + cur->next = s_conn->mech_contexts; + s_conn->mech_contexts = cur; + } + + /* SASL_NOTDONE might also get us here */ + + /* Error should be set by mech_avail call */ + return SASL_NOMECH; + } else if (context) { + if (mech_context_list_entry != NULL) { + /* Update the context. It shouldn't have changed, but who knows */ + mech_context_list_entry->context = context; + } else { + /* Save this context */ + cur = sasl_ALLOC(sizeof(context_list_t)); + if (!cur) { + MEMERROR(conn); + return SASL_NOMECH; + } + cur->context = context; + cur->mech = mech; + cur->next = s_conn->mech_contexts; + s_conn->mech_contexts = cur; + } + } + + /* Generic mechanism */ + if (plug->max_ssf < minssf) { + sasl_seterror(conn, SASL_NOLOG, "too weak"); + return SASL_TOOWEAK; /* too weak */ + } + + /* if there are no users in the secrets database we can't use this + mechanism */ + if (mech->m.condition == SASL_NOUSER) { + sasl_seterror(conn, 0, "no users in secrets db"); + return SASL_NOMECH; + } + + /* Can it meet our features? */ + if ((conn->flags & SASL_NEED_PROXY) && + !(plug->features & SASL_FEAT_ALLOWS_PROXY)) { + return SASL_NOMECH; + } + if ((conn->flags & SASL_NEED_HTTP) && + !(plug->features & SASL_FEAT_SUPPORTS_HTTP)) { + return SASL_NOMECH; + } + + /* security properties---if there are any flags that differ and are + in what the connection are requesting, then fail */ + + /* special case plaintext */ + myflags = conn->props.security_flags; + + /* if there's an external layer this is no longer plaintext */ + if ((conn->props.min_ssf <= conn->external.ssf) && + (conn->external.ssf > 1)) { + myflags &= ~SASL_SEC_NOPLAINTEXT; + } + + /* do we want to special case SASL_SEC_PASS_CREDENTIALS? nah.. */ + if ((myflags &= (myflags ^ plug->security_flags)) != 0) { + sasl_seterror(conn, SASL_NOLOG, + "security flags do not match required"); + return (myflags & SASL_SEC_NOPLAINTEXT) ? SASL_ENCRYPT : SASL_NOMECH; + } + + /* Check Features */ + if (plug->features & SASL_FEAT_GETSECRET) { + /* We no longer support sasl_server_{get,put}secret */ + sasl_seterror(conn, 0, + "mech %s requires unprovided secret facility", + plug->mech_name); + return SASL_NOMECH; + } + + return SASL_OK; +} + +/* + * make the authorization + * + */ + +static int do_authorization(sasl_server_conn_t *s_conn) +{ + int ret; + sasl_authorize_t *authproc; + void *auth_context; + + /* now let's see if authname is allowed to proxy for username! */ + + /* check the proxy callback */ + if (_sasl_getcallback(&s_conn->base, SASL_CB_PROXY_POLICY, + (sasl_callback_ft *)&authproc, &auth_context) != SASL_OK) { + INTERROR(&s_conn->base, SASL_NOAUTHZ); + } + + ret = authproc(&(s_conn->base), auth_context, + s_conn->base.oparams.user, s_conn->base.oparams.ulen, + s_conn->base.oparams.authid, s_conn->base.oparams.alen, + s_conn->user_realm, + (s_conn->user_realm ? (unsigned) strlen(s_conn->user_realm) : 0), + s_conn->sparams->propctx); + + RETURN(&s_conn->base, ret); +} + + +/* start a mechanism exchange within a connection context + * mech -- the mechanism name client requested + * clientin -- client initial response (NUL terminated), NULL if empty + * clientinlen -- length of initial response + * serverout -- initial server challenge, NULL if done + * (library handles freeing this string) + * serveroutlen -- length of initial server challenge + * output: + * pconn -- the connection negotiation state on success + * + * Same returns as sasl_server_step() or + * SASL_NOMECH if mechanism not available. + */ +int sasl_server_start(sasl_conn_t *conn, + const char *mech, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen) +{ + sasl_server_conn_t *s_conn=(sasl_server_conn_t *) conn; + int result; + context_list_t *cur, **prev; + mechanism_t *m; + size_t mech_len; + int plus = 0; + + if (_sasl_server_active==0) return SASL_NOTINIT; + + /* check parameters */ + if(!conn) return SASL_BADPARAM; + + if (!mech || ((clientin == NULL) && (clientinlen > 0))) + PARAMERROR(conn); + + if (serverout) *serverout = NULL; + if (serveroutlen) *serveroutlen = 0; + + /* make sure mech is valid mechanism + if not return appropriate error */ + m = s_conn->mech_list; + mech_len = strlen(mech); + + while (m != NULL) { + if (_sasl_is_equal_mech(mech, m->m.plug->mech_name, mech_len, &plus)) { + break; + } + + m = m->next; + } + + if (m == NULL) { + sasl_seterror(conn, 0, "Couldn't find mech %s", mech); + result = SASL_NOMECH; + goto done; + } + + /* Make sure that we're willing to use this mech */ + if ((result = mech_permitted(conn, m)) != SASL_OK) { + goto done; + } + + if (m->m.condition == SASL_CONTINUE) { + sasl_server_plug_init_t *entry_point; + void *library = NULL; + sasl_server_plug_t *pluglist; + int version, plugcount; + int l = 0; + + /* need to load this plugin */ + result = _sasl_get_plugin(m->m.f, + _sasl_find_verifyfile_callback(global_callbacks.callbacks), + &library); + + if (result == SASL_OK) { + result = _sasl_locate_entry(library, "sasl_server_plug_init", + (void **)&entry_point); + } + + if (result == SASL_OK) { + result = entry_point(mechlist->utils, SASL_SERVER_PLUG_VERSION, + &version, &pluglist, &plugcount); + } + + if (result == SASL_OK) { + /* find the correct mechanism in this plugin */ + for (l = 0; l < plugcount; l++) { + if (!strcasecmp(pluglist[l].mech_name, + m->m.plug->mech_name)) break; + } + if (l == plugcount) { + result = SASL_NOMECH; + } + } + if (result == SASL_OK) { + /* check that the parameters are the same */ + if ((pluglist[l].max_ssf != m->m.plug->max_ssf) || + (pluglist[l].security_flags != m->m.plug->security_flags)) { + _sasl_log(conn, SASL_LOG_ERR, + "%s: security parameters don't match mechlist file", + pluglist[l].mech_name); + result = SASL_NOMECH; + } + } + if (result == SASL_OK) { + /* copy mechlist over */ + sasl_FREE((sasl_server_plug_t *) m->m.plug); + m->m.plug = &pluglist[l]; + m->m.condition = SASL_OK; + } + + if (result != SASL_OK) { + /* The library will eventually be freed, don't sweat it */ + RETURN(conn, result); + } + } + + if (conn->context) { + s_conn->mech->m.plug->mech_dispose(conn->context, + s_conn->sparams->utils); + conn->context = NULL; + } + + /* We used to setup sparams HERE, but now it's done + inside of mech_permitted (which is called above) */ + prev = &s_conn->mech_contexts; + for (cur = *prev; cur; prev=&cur->next,cur=cur->next) { + if (cur->mech == m) { + if (!cur->context) { + sasl_seterror(conn, 0, + "Got past mech_permitted with a disallowed mech!"); + return SASL_NOMECH; + } + /* If we find it, we need to pull cur out of the + list so it won't be freed later! */ + *prev = cur->next; + conn->context = cur->context; + sasl_FREE(cur); + break; + } + } + + s_conn->mech = m; + + if (!conn->context) { + /* Note that we don't hand over a new challenge */ + result = s_conn->mech->m.plug->mech_new(s_conn->mech->m.plug->glob_context, + s_conn->sparams, + NULL, + 0, + &(conn->context)); + } else { + /* the work was already done by mech_avail! */ + result = SASL_OK; + } + + if (result == SASL_OK) { + if (clientin) { + if (s_conn->mech->m.plug->features & SASL_FEAT_SERVER_FIRST) { + /* Remote sent first, but mechanism does not support it. + * RFC 2222 says we fail at this point. */ + sasl_seterror(conn, + 0, + "Remote sent first but mech does not allow it."); + result = SASL_BADPROT; + } else { + /* Mech wants client-first, so let them have it */ + result = sasl_server_step(conn, + clientin, + clientinlen, + serverout, + serveroutlen); + } + } else { + if (s_conn->mech->m.plug->features & SASL_FEAT_WANT_CLIENT_FIRST) { + /* Mech wants client first anyway, so we should do that */ + if (serverout) *serverout = ""; + if (serveroutlen) *serveroutlen = 0; + result = SASL_CONTINUE; + } else { + /* Mech wants server-first, so let them have it */ + result = sasl_server_step(conn, + clientin, + clientinlen, + serverout, + serveroutlen); + } + } + } + + done: + if ( result != SASL_OK + && result != SASL_CONTINUE + && result != SASL_INTERACT) { + if (conn->context) { + s_conn->mech->m.plug->mech_dispose(conn->context, + s_conn->sparams->utils); + conn->context = NULL; + } + conn->oparams.doneflag = 0; + } + + RETURN(conn,result); +} + + +/* perform one step of the SASL exchange + * clientinlen & clientin -- client data + * NULL on first step if no optional client step + * serveroutlen & serverout -- set to the server data to transmit + * to the client in the next step + * (library handles freeing this) + * + * returns: + * SASL_OK -- exchange is complete. + * SASL_CONTINUE -- indicates another step is necessary. + * SASL_TRANS -- entry for user exists, but not for mechanism + * and transition is possible + * SASL_BADPARAM -- service name needed + * SASL_BADPROT -- invalid input from client + * ... + */ + +int sasl_server_step(sasl_conn_t *conn, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen) +{ + int ret; + sasl_server_conn_t *s_conn = (sasl_server_conn_t *) conn; /* cast */ + + /* check parameters */ + if (_sasl_server_active==0) return SASL_NOTINIT; + if (!conn) return SASL_BADPARAM; + if ((clientin==NULL) && (clientinlen>0)) + PARAMERROR(conn); + + /* If we've already done the last send, return! */ + if (s_conn->sent_last == 1) { + return SASL_OK; + } + + /* Don't do another step if the plugin told us that we're done */ + if (conn->oparams.doneflag) { + _sasl_log(conn, SASL_LOG_ERR, "attempting server step after doneflag"); + return SASL_FAIL; + } + + if (serverout) *serverout = NULL; + if (serveroutlen) *serveroutlen = 0; + + ret = s_conn->mech->m.plug->mech_step(conn->context, + s_conn->sparams, + clientin, + clientinlen, + serverout, + serveroutlen, + &conn->oparams); + + if (ret == SASL_OK) { + ret = do_authorization(s_conn); + } + + if (ret == SASL_OK) { + /* if we're done, we need to watch out for the following: + * 1. the mech does server-send-last + * 2. the protocol does not + * + * in this case, return SASL_CONTINUE and remember we are done. + */ + if(*serverout && !(conn->flags & SASL_SUCCESS_DATA)) { + s_conn->sent_last = 1; + ret = SASL_CONTINUE; + } + if(!conn->oparams.maxoutbuf) { + conn->oparams.maxoutbuf = conn->props.maxbufsize; + } + + /* Validate channel bindings */ + switch (conn->oparams.cbindingdisp) { + case SASL_CB_DISP_NONE: + if (SASL_CB_CRITICAL(s_conn->sparams)) { + sasl_seterror(conn, 0, + "server requires channel binding but client provided none"); + ret = SASL_BADBINDING; + } + break; + case SASL_CB_DISP_WANT: + if (SASL_CB_PRESENT(s_conn->sparams)) { + sasl_seterror(conn, 0, + "client incorrectly assumed server had no channel binding"); + ret = SASL_BADAUTH; + } + break; + case SASL_CB_DISP_USED: + if (!SASL_CB_PRESENT(s_conn->sparams)) { + sasl_seterror(conn, 0, + "client provided channel binding but server had none"); + ret = SASL_BADBINDING; + } else if (strcmp(conn->oparams.cbindingname, + s_conn->sparams->cbinding->name) != 0) { + sasl_seterror(conn, 0, + "client channel binding %s does not match server %s", + conn->oparams.cbindingname, s_conn->sparams->cbinding->name); + ret = SASL_BADBINDING; + } + break; + } + + if (ret == SASL_OK && + (conn->oparams.user == NULL || conn->oparams.authid == NULL)) { + sasl_seterror(conn, 0, + "mech did not call canon_user for both authzid " \ + "and authid"); + ret = SASL_BADPROT; + } + } + + if ( ret != SASL_OK + && ret != SASL_CONTINUE + && ret != SASL_INTERACT) { + if (conn->context) { + s_conn->mech->m.plug->mech_dispose(conn->context, + s_conn->sparams->utils); + conn->context = NULL; + } + conn->oparams.doneflag = 0; + } + + RETURN(conn, ret); +} + +/* returns the length of all the mechanisms + * added up + */ + +static unsigned mech_names_len(mechanism_t *mech_list) +{ + mechanism_t *listptr; + unsigned result = 0; + + for (listptr = mech_list; + listptr; + listptr = listptr->next) + result += (unsigned) strlen(listptr->m.plug->mech_name); + + return result; +} + +/* This returns a list of mechanisms in a NUL-terminated string + * + * The default behavior is to separate with spaces if sep == NULL + */ +int _sasl_server_listmech(sasl_conn_t *conn, + const char *user __attribute__((unused)), + const char *prefix, + const char *sep, + const char *suffix, + const char **result, + unsigned *plen, + int *pcount) +{ + sasl_server_conn_t *s_conn = (sasl_server_conn_t *) conn; /* cast */ + int lup; + mechanism_t *listptr; + int ret; + size_t resultlen; + int flag; + const char *mysep; + + /* if there hasn't been a sasl_sever_init() fail */ + if (_sasl_server_active==0) return SASL_NOTINIT; + if (!conn) return SASL_BADPARAM; + if (conn->type != SASL_CONN_SERVER) PARAMERROR(conn); + + if (! result) + PARAMERROR(conn); + + if (plen != NULL) + *plen = 0; + if (pcount != NULL) + *pcount = 0; + + if (sep) { + mysep = sep; + } else { + mysep = " "; + } + + if (!s_conn->mech_list || s_conn->mech_length <= 0) + INTERROR(conn, SASL_NOMECH); + + resultlen = (prefix ? strlen(prefix) : 0) + + (strlen(mysep) * (s_conn->mech_length - 1) * 2) + + (mech_names_len(s_conn->mech_list) * 2) /* including -PLUS variant */ + + (s_conn->mech_length * (sizeof("-PLUS") - 1)) + + (suffix ? strlen(suffix) : 0) + + 1; + + ret = _buf_alloc(&conn->mechlist_buf, + &conn->mechlist_buf_len, resultlen); + if(ret != SASL_OK) MEMERROR(conn); + + if (prefix) + strcpy (conn->mechlist_buf,prefix); + else + *(conn->mechlist_buf) = '\0'; + + listptr = s_conn->mech_list; + + flag = 0; + /* make list */ + for (lup = 0; lup < s_conn->mech_length; lup++) { + /* currently, we don't use the "user" parameter for anything */ + if (mech_permitted(conn, listptr) == SASL_OK) { + + /* + * If the server would never succeed in the authentication of + * the non-PLUS-variant due to policy reasons, it MUST advertise + * only the PLUS-variant. + */ + if ((listptr->m.plug->features & SASL_FEAT_CHANNEL_BINDING) && + SASL_CB_PRESENT(s_conn->sparams)) { + if (pcount != NULL) { + (*pcount)++; + } + if (flag) { + strcat(conn->mechlist_buf, mysep); + } else { + flag = 1; + } + strcat(conn->mechlist_buf, listptr->m.plug->mech_name); + strcat(conn->mechlist_buf, "-PLUS"); + } + + /* + * If the server cannot support channel binding, it SHOULD + * advertise only the non-PLUS-variant. Here, supporting channel + * binding means the underlying SASL mechanism supports it and + * the application has set some channel binding data. + */ + if (!SASL_CB_PRESENT(s_conn->sparams) || + !SASL_CB_CRITICAL(s_conn->sparams)) { + if (pcount != NULL) { + (*pcount)++; + } + if (flag) { + strcat(conn->mechlist_buf, mysep); + } else { + flag = 1; + } + strcat(conn->mechlist_buf, listptr->m.plug->mech_name); + } + } + + listptr = listptr->next; + } + + if (suffix) + strcat(conn->mechlist_buf,suffix); + + if (plen!=NULL) + *plen = (unsigned) strlen(conn->mechlist_buf); + + *result = conn->mechlist_buf; + + return SASL_OK; +} + +sasl_string_list_t *_sasl_server_mechs(void) +{ + mechanism_t *listptr; + sasl_string_list_t *retval = NULL, *next=NULL; + + if(!_sasl_server_active) return NULL; + + /* make list */ + for (listptr = mechlist->mech_list; listptr; listptr = listptr->next) { + next = sasl_ALLOC(sizeof(sasl_string_list_t)); + + if(!next && !retval) return NULL; + else if(!next) { + next = retval->next; + do { + sasl_FREE(retval); + retval = next; + next = retval->next; + } while(next); + return NULL; + } + + next->d = listptr->m.plug->mech_name; + + if(!retval) { + next->next = NULL; + retval = next; + } else { + next->next = retval; + retval = next; + } + } + + return retval; +} + +#define EOSTR(s,n) (((s)[n] == '\0') || ((s)[n] == ' ') || ((s)[n] == '\t')) +static int is_mech(const char *t, const char *m) +{ + size_t sl = strlen(m); + return ((!strncasecmp(m, t, sl)) && EOSTR(t, sl)); +} + +/* returns OK if it's valid */ +static int _sasl_checkpass(sasl_conn_t *conn, + const char *user, + unsigned userlen, + const char *pass, + unsigned passlen) +{ + sasl_server_conn_t *s_conn = (sasl_server_conn_t *) conn; + int result; + sasl_getopt_t *getopt; + sasl_server_userdb_checkpass_t *checkpass_cb; + void *context; + const char *mlist = NULL, *mech = NULL; + struct sasl_verify_password_s *v; + const char *service = conn->service; + + if (!userlen) userlen = (unsigned) strlen(user); + if (!passlen) passlen = (unsigned) strlen(pass); + + /* call userdb callback function, if available */ + result = _sasl_getcallback(conn, SASL_CB_SERVER_USERDB_CHECKPASS, + (sasl_callback_ft *)&checkpass_cb, &context); + if(result == SASL_OK && checkpass_cb) { + result = checkpass_cb(conn, context, user, pass, passlen, + s_conn->sparams->propctx); + if(result == SASL_OK) + return SASL_OK; + } + + /* figure out how to check (i.e. auxprop or saslauthd or pwcheck) */ + if (_sasl_getcallback(conn, SASL_CB_GETOPT, (sasl_callback_ft *)&getopt, &context) + == SASL_OK) { + getopt(context, NULL, "pwcheck_method", &mlist, NULL); + } + + if(!mlist) mlist = DEFAULT_CHECKPASS_MECH; + + result = SASL_NOMECH; + + mech = mlist; + while (*mech && result != SASL_OK) { + for (v = _sasl_verify_password; v->name; v++) { + if(is_mech(mech, v->name)) { + result = v->verify(conn, user, pass, service, + s_conn->user_realm); + break; + } + } + if (result != SASL_OK) { + /* skip to next mech in list */ + while (*mech && !isspace((int) *mech)) mech++; + while (*mech && isspace((int) *mech)) mech++; + } + else if (!is_mech(mech, "auxprop") && s_conn->sparams->transition) { + s_conn->sparams->transition(conn, pass, passlen); + } + } + + if (result == SASL_NOMECH) { + /* no mechanism available ?!? */ + _sasl_log(conn, SASL_LOG_ERR, "unknown password verifier(s) %s", mlist); + } + + if (result != SASL_OK) + sasl_seterror(conn, SASL_NOLOG, "checkpass failed"); + + RETURN(conn, result); +} + +/* check if a plaintext password is valid + * if user is NULL, check if plaintext passwords are enabled + * inputs: + * user -- user to query in current user_domain + * userlen -- length of username, 0 = strlen(user) + * pass -- plaintext password to check + * passlen -- length of password, 0 = strlen(pass) + * returns + * SASL_OK -- success + * SASL_NOMECH -- mechanism not supported + * SASL_NOVERIFY -- user found, but no verifier + * SASL_NOUSER -- user not found + */ +int sasl_checkpass(sasl_conn_t *conn, + const char *user, + unsigned userlen, + const char *pass, + unsigned passlen) +{ + int result; + + if (_sasl_server_active==0) return SASL_NOTINIT; + + /* check if it's just a query if we are enabled */ + if (!user) + return SASL_OK; + + if (!conn) return SASL_BADPARAM; + + /* check params */ + if (pass == NULL) + PARAMERROR(conn); + + /* canonicalize the username */ + result = _sasl_canon_user(conn, user, userlen, + SASL_CU_AUTHID | SASL_CU_AUTHZID, + &(conn->oparams)); + if(result != SASL_OK) RETURN(conn, result); + user = conn->oparams.user; + + /* Check the password and lookup additional properties */ + result = _sasl_checkpass(conn, user, userlen, pass, passlen); + + /* Do authorization */ + if(result == SASL_OK) { + result = do_authorization((sasl_server_conn_t *)conn); + } + + RETURN(conn,result); +} + +/* check if a user exists on server + * conn -- connection context (may be NULL, used to hold last error) + * service -- registered name of the service using SASL (e.g. "imap") + * user_realm -- permits multiple user realms on server, NULL = default + * user -- NUL terminated user name + * + * returns: + * SASL_OK -- success + * SASL_DISABLED -- account disabled [FIXME: currently not detected] + * SASL_NOUSER -- user not found + * SASL_NOVERIFY -- user found, but no usable mechanism [FIXME: not supported] + * SASL_NOMECH -- no mechanisms enabled + * SASL_UNAVAIL -- remote authentication server unavailable, try again later + */ +int sasl_user_exists(sasl_conn_t *conn, + const char *service, + const char *user_realm, + const char *user) +{ + int result=SASL_NOMECH; + const char *mlist = NULL, *mech = NULL; + void *context; + sasl_getopt_t *getopt; + struct sasl_verify_password_s *v; + + /* check params */ + if (_sasl_server_active==0) return SASL_NOTINIT; + if (!conn) return SASL_BADPARAM; + if (!user || conn->type != SASL_CONN_SERVER) + PARAMERROR(conn); + + if(!service) service = conn->service; + + /* figure out how to check (i.e. auxprop or saslauthd or pwcheck) */ + if (_sasl_getcallback(conn, SASL_CB_GETOPT, (sasl_callback_ft *)&getopt, &context) + == SASL_OK) { + getopt(context, NULL, "pwcheck_method", &mlist, NULL); + } + + if(!mlist) mlist = DEFAULT_CHECKPASS_MECH; + + result = SASL_NOMECH; + + mech = mlist; + while (*mech && result != SASL_OK) { + for (v = _sasl_verify_password; v->name; v++) { + if(is_mech(mech, v->name)) { + result = v->verify(conn, user, NULL, service, user_realm); + break; + } + } + if (result != SASL_OK) { + /* skip to next mech in list */ + while (*mech && !isspace((int) *mech)) mech++; + while (*mech && isspace((int) *mech)) mech++; + } + } + + /* Screen out the SASL_BADPARAM response + * we'll get from not giving a password */ + if (result == SASL_BADPARAM) { + result = SASL_OK; + } + + if (result == SASL_NOMECH) { + /* no mechanism available ?!? */ + _sasl_log(conn, SASL_LOG_ERR, "no plaintext password verifier?"); + sasl_seterror(conn, SASL_NOLOG, "no plaintext password verifier?"); + } + + RETURN(conn, result); +} + +/* check if an apop exchange is valid + * (note this is an optional part of the SASL API) + * if challenge is NULL, just check if APOP is enabled + * inputs: + * challenge -- challenge which was sent to client + * challen -- length of challenge, 0 = strlen(challenge) + * response -- client response, " " (RFC 1939) + * resplen -- length of response, 0 = strlen(response) + * returns + * SASL_OK -- success + * SASL_BADAUTH -- authentication failed + * SASL_BADPARAM -- missing challenge + * SASL_BADPROT -- protocol error (e.g., response in wrong format) + * SASL_NOVERIFY -- user found, but no verifier + * SASL_NOMECH -- mechanism not supported + * SASL_NOUSER -- user not found + */ +int sasl_checkapop(sasl_conn_t *conn, +#ifdef DO_SASL_CHECKAPOP + const char *challenge, + unsigned challen __attribute__((unused)), + const char *response, + unsigned resplen __attribute__((unused))) +#else + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + const char *response __attribute__((unused)), + unsigned resplen __attribute__((unused))) +#endif +{ +#ifdef DO_SASL_CHECKAPOP + sasl_server_conn_t *s_conn = (sasl_server_conn_t *) conn; + char *user, *user_end; + const char *password_request[] = { SASL_AUX_PASSWORD, NULL }; + size_t user_len; + int result; + + if (_sasl_server_active==0) + return SASL_NOTINIT; + + /* check if it's just a query if we are enabled */ + if(!challenge) + return SASL_OK; + + /* check params */ + if (!conn) return SASL_BADPARAM; + if (!response) + PARAMERROR(conn); + + /* Parse out username and digest. + * + * Per RFC 1939, response must be " ", where + * is a 16-octet value which is sent in hexadecimal + * format, using lower-case ASCII characters. + */ + user_end = strrchr(response, ' '); + if (!user_end || strspn(user_end + 1, "0123456789abcdef") != 32) + { + sasl_seterror(conn, 0, "Bad Digest"); + RETURN(conn,SASL_BADPROT); + } + + user_len = (size_t)(user_end - response); + user = sasl_ALLOC(user_len + 1); + memcpy(user, response, user_len); + user[user_len] = '\0'; + + result = prop_request(s_conn->sparams->propctx, password_request); + if(result != SASL_OK) + { + sasl_FREE(user); + RETURN(conn, result); + } + + /* erase the plaintext password */ + s_conn->sparams->utils->prop_erase(s_conn->sparams->propctx, + password_request[0]); + + /* canonicalize the username and lookup any associated properties */ + result = _sasl_canon_user_lookup (conn, + user, + user_len, + SASL_CU_AUTHID | SASL_CU_AUTHZID, + &(conn->oparams)); + sasl_FREE(user); + + if(result != SASL_OK) RETURN(conn, result); + + /* Do APOP verification */ + result = _sasl_auxprop_verify_apop(conn, conn->oparams.authid, + challenge, user_end + 1, s_conn->user_realm); + + /* Do authorization */ + if(result == SASL_OK) { + result = do_authorization((sasl_server_conn_t *)conn); + } else { + /* If verification failed, we don't want to encourage getprop to work */ + conn->oparams.user = NULL; + conn->oparams.authid = NULL; + } + + RETURN(conn, result); +#else /* sasl_checkapop was disabled at compile time */ + sasl_seterror(conn, SASL_NOLOG, + "sasl_checkapop called, but was disabled at compile time"); + RETURN(conn, SASL_NOMECH); +#endif /* DO_SASL_CHECKAPOP */ +} + +/* It would be nice if we can show other information like Author, Company, Year, plugin version */ +static void +_sasl_print_mechanism ( + server_sasl_mechanism_t *m, + sasl_info_callback_stage_t stage, + void *rock __attribute__((unused)) +) +{ + char delimiter; + + if (stage == SASL_INFO_LIST_START) { + printf ("List of server plugins follows\n"); + return; + } else if (stage == SASL_INFO_LIST_END) { + return; + } + + /* Process the mechanism */ + printf ("Plugin \"%s\" ", m->plugname); + + switch (m->condition) { + case SASL_OK: + printf ("[loaded]"); + break; + + case SASL_CONTINUE: + printf ("[delayed]"); + break; + + case SASL_NOUSER: + printf ("[no users]"); + break; + + default: + printf ("[unknown]"); + break; + } + + printf (", \tAPI version: %d\n", m->version); + + if (m->plug != NULL) { + printf ("\tSASL mechanism: %s, best SSF: %d, supports setpass: %s\n", + m->plug->mech_name, + m->plug->max_ssf, + (m->plug->setpass != NULL) ? "yes" : "no" + ); + + + printf ("\tsecurity flags:"); + + delimiter = ' '; + if (m->plug->security_flags & SASL_SEC_NOANONYMOUS) { + printf ("%cNO_ANONYMOUS", delimiter); + delimiter = '|'; + } + + if (m->plug->security_flags & SASL_SEC_NOPLAINTEXT) { + printf ("%cNO_PLAINTEXT", delimiter); + delimiter = '|'; + } + + if (m->plug->security_flags & SASL_SEC_NOACTIVE) { + printf ("%cNO_ACTIVE", delimiter); + delimiter = '|'; + } + + if (m->plug->security_flags & SASL_SEC_NODICTIONARY) { + printf ("%cNO_DICTIONARY", delimiter); + delimiter = '|'; + } + + if (m->plug->security_flags & SASL_SEC_FORWARD_SECRECY) { + printf ("%cFORWARD_SECRECY", delimiter); + delimiter = '|'; + } + + if (m->plug->security_flags & SASL_SEC_PASS_CREDENTIALS) { + printf ("%cPASS_CREDENTIALS", delimiter); + delimiter = '|'; + } + + if (m->plug->security_flags & SASL_SEC_MUTUAL_AUTH) { + printf ("%cMUTUAL_AUTH", delimiter); + delimiter = '|'; + } + + + + printf ("\n\tfeatures:"); + + delimiter = ' '; + if (m->plug->features & SASL_FEAT_WANT_CLIENT_FIRST) { + printf ("%cWANT_CLIENT_FIRST", delimiter); + delimiter = '|'; + } + + if (m->plug->features & SASL_FEAT_SERVER_FIRST) { + printf ("%cSERVER_FIRST", delimiter); + delimiter = '|'; + } + + if (m->plug->features & SASL_FEAT_ALLOWS_PROXY) { + printf ("%cPROXY_AUTHENTICATION", delimiter); + delimiter = '|'; + } + + if (m->plug->features & SASL_FEAT_DONTUSE_USERPASSWD) { + printf ("%cDONTUSE_USERPASSWD", delimiter); + delimiter = '|'; + } + + if (m->plug->features & SASL_FEAT_NEEDSERVERFQDN) { + printf ("%cNEED_SERVER_FQDN", delimiter); + delimiter = '|'; + } + + /* Is this one used? */ + if (m->plug->features & SASL_FEAT_SERVICE) { + printf ("%cSERVICE", delimiter); + delimiter = '|'; + } + + if (m->plug->features & SASL_FEAT_GETSECRET) { + printf ("%cNEED_GETSECRET", delimiter); + delimiter = '|'; + } + + if (m->plug->features & SASL_FEAT_GSS_FRAMING) { + printf ("%cGSS_FRAMING", delimiter); + delimiter = '|'; + } + + if (m->plug->features & SASL_FEAT_CHANNEL_BINDING) { + printf ("%cCHANNEL_BINDING", delimiter); + delimiter = '|'; + } + + if (m->plug->features & SASL_FEAT_SUPPORTS_HTTP) { + printf ("%cSUPPORTS_HTTP", delimiter); + delimiter = '|'; + } + } + + if (m->f) { + printf ("\n\twill be loaded from \"%s\"", m->f); + } + + printf ("\n"); +} + +/* Dump information about available server plugins (separate functions should be + used for canon and auxprop plugins */ +int sasl_server_plugin_info ( + const char *c_mech_list, /* space separated mechanism list or NULL for ALL */ + sasl_server_info_callback_t *info_cb, + void *info_cb_rock +) +{ + mechanism_t *m; + server_sasl_mechanism_t plug_data; + char * cur_mech; + char *mech_list = NULL; + char * p; + + if (info_cb == NULL) { + info_cb = _sasl_print_mechanism; + } + + if (mechlist != NULL) { + info_cb (NULL, SASL_INFO_LIST_START, info_cb_rock); + + if (c_mech_list == NULL) { + m = mechlist->mech_list; /* m point to beginning of the list */ + + while (m != NULL) { + memcpy (&plug_data, &m->m, sizeof(plug_data)); + + info_cb (&plug_data, SASL_INFO_LIST_MECH, info_cb_rock); + + m = m->next; + } + } else { + mech_list = strdup(c_mech_list); + + cur_mech = mech_list; + + while (cur_mech != NULL) { + p = strchr (cur_mech, ' '); + if (p != NULL) { + *p = '\0'; + p++; + } + + m = mechlist->mech_list; /* m point to beginning of the list */ + + while (m != NULL) { + if (strcasecmp (cur_mech, m->m.plug->mech_name) == 0) { + memcpy (&plug_data, &m->m, sizeof(plug_data)); + + info_cb (&plug_data, SASL_INFO_LIST_MECH, info_cb_rock); + } + + m = m->next; + } + + cur_mech = p; + } + + free (mech_list); + } + + info_cb (NULL, SASL_INFO_LIST_END, info_cb_rock); + + return (SASL_OK); + } + + return (SASL_NOTINIT); +} diff --git a/libs/cyrussasl/lib/seterror.c b/libs/cyrussasl/lib/seterror.c new file mode 100644 index 00000000..54300f55 --- /dev/null +++ b/libs/cyrussasl/lib/seterror.c @@ -0,0 +1,263 @@ +/* seterror.c - sasl_seterror split out because glue libraries + * can't pass varargs lists + * Rob Siemborski + * Tim Martin + * split from common.c by Rolf Braun + * $Id: seterror.c,v 1.10 2011/09/01 14:12:53 mel Exp $ + */ + +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#ifdef HAVE_SYSLOG +#include +#endif +#include +#include + +#include +#include +#include +#include "saslint.h" + +#ifdef WIN32 +/* need to handle the fact that errno has been defined as a function + in a dll, not an extern int */ +# ifdef errno +# undef errno +# endif /* errno */ +#endif /* WIN32 */ +#ifdef HAVE_UNISTD_H +#include +#endif + +/* this is apparently no longer a user function */ +static int _sasl_seterror_usererr(int saslerr) +{ + /* Hide the difference in a username failure and a password failure */ + if (saslerr == SASL_NOUSER) + return SASL_BADAUTH; + + /* otherwise return the error given; no transform necessary */ + return saslerr; +} + +/* set the error string which will be returned by sasl_errdetail() using + * syslog()-style formatting (e.g. printf-style with %m as the string form + * of an errno error) + * + * primarily for use by server callbacks such as the sasl_authorize_t + * callback and internally to plug-ins + * + * This will also trigger a call to the SASL logging callback (if any) + * with a level of SASL_LOG_FAIL unless the SASL_NOLOG flag is set. + * + * Messages should be sensitive to the current language setting. If there + * is no SASL_CB_LANGUAGE callback messages MUST be US-ASCII otherwise UTF-8 + * is used and use of RFC 2482 for mixed-language text is encouraged. + * + * if conn is NULL, function does nothing + */ +void sasl_seterror(sasl_conn_t *conn, + unsigned flags, + const char *fmt, ...) +{ + size_t outlen=0; /* current length of output buffer */ + size_t pos = 0; /* current position in format string */ + size_t formatlen; + int result; + sasl_log_t *log_cb = NULL; + void *log_ctx; + int ival; + char *cval; + va_list ap; /* varargs thing */ + char **error_buf; + size_t *error_buf_len; + + if(!conn) { +#ifndef SASL_OSX_CFMGLUE + if(!(flags & SASL_NOLOG)) { + /* See if we have a logging callback... */ + result = _sasl_getcallback(NULL, SASL_CB_LOG, (sasl_callback_ft *)&log_cb, &log_ctx); + if (result == SASL_OK && ! log_cb) + result = SASL_FAIL; + if (result != SASL_OK) + return; + + log_cb(log_ctx, SASL_LOG_FAIL, + "No sasl_conn_t passed to sasl_seterror"); + } +#endif /* SASL_OSX_CFMGLUE */ + return; + } else if(!fmt) return; + +/* we need to use a back end function to get the buffer because the + cfm glue can't be rooting around in the internal structs */ + _sasl_get_errorbuf(conn, &error_buf, &error_buf_len); + + formatlen = strlen(fmt); + + va_start(ap, fmt); /* start varargs */ + + while(pos9) + done=1; + } + pos++; + if (pos>formatlen) + done=1; + } + + } + } + + (*error_buf)[outlen]='\0'; /* put 0 at end */ + + va_end(ap); + +#ifndef SASL_OSX_CFMGLUE + if(!(flags & SASL_NOLOG)) { + /* See if we have a logging callback... */ + result = _sasl_getcallback(conn, SASL_CB_LOG, (sasl_callback_ft *)&log_cb, &log_ctx); + if (result == SASL_OK && ! log_cb) + result = SASL_FAIL; + if (result != SASL_OK) + return; + + result = log_cb(log_ctx, SASL_LOG_FAIL, conn->error_buf); + } +#endif /* SASL_OSX_CFMGLUE */ +} diff --git a/libs/cyrussasl/lib/snprintf.c b/libs/cyrussasl/lib/snprintf.c new file mode 100644 index 00000000..bf88c789 --- /dev/null +++ b/libs/cyrussasl/lib/snprintf.c @@ -0,0 +1,784 @@ +/************************************************************** + * Original: + * Patrick Powell Tue Apr 11 09:48:21 PDT 1995 + * A bombproof version of doprnt (dopr) included. + * Sigh. This sort of thing is always nasty do deal with. Note that + * the version here does not include floating point... + * + * snprintf() is used instead of sprintf() as it does limit checks + * for string length. This covers a nasty loophole. + * + * The other functions are there to prevent NULL pointers from + * causing nast effects. + * + * More Recently: + * Brandon Long 9/15/96 for mutt 0.43 + * This was ugly. It is still ugly. I opted out of floating point + * numbers, but the formatter understands just about everything + * from the normal C string format, at least as far as I can tell from + * the Solaris 2.5 printf(3S) man page. + * + * Brandon Long 10/22/97 for mutt 0.87.1 + * Ok, added some minimal floating point support, which means this + * probably requires libm on most operating systems. Don't yet + * support the exponent (e,E) and sigfig (g,G). Also, fmtint() + * was pretty badly broken, it just wasn't being exercised in ways + * which showed it, so that's been fixed. Also, formated the code + * to mutt conventions, and removed dead code left over from the + * original. Also, there is now a builtin-test, just compile with: + * gcc -DTEST_SNPRINTF -o snprintf snprintf.c -lm + * and run snprintf for results. + * + * Thomas Roessler 01/27/98 for mutt 0.89i + * The PGP code was using unsigned hexadecimal formats. + * Unfortunately, unsigned formats simply didn't work. + * + * Michael Elkins 03/05/98 for mutt 0.90.8 + * The original code assumed that both snprintf() and vsnprintf() were + * missing. Some systems only have snprintf() but not vsnprintf(), so + * the code is now broken down under HAVE_SNPRINTF and HAVE_VSNPRINTF. + * + **************************************************************/ + +#include + +#if !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) + +#include +# include +#include + +/* varargs declarations: */ + +#if defined(HAVE_STDARG_H) +# include +# define HAVE_STDARGS /* let's hope that works everywhere (mj) */ +# define VA_LOCAL_DECL va_list ap +# define VA_START(f) va_start(ap, f) +# define VA_SHIFT(v,t) ; /* no-op for ANSI */ +# define VA_END va_end(ap) +#else +# if defined(HAVE_VARARGS_H) +# include +# undef HAVE_STDARGS +# define VA_LOCAL_DECL va_list ap +# define VA_START(f) va_start(ap) /* f is ignored! */ +# define VA_SHIFT(v,t) v = va_arg(ap,t) +# define VA_END va_end(ap) +# else +/*XX ** NO VARARGS ** XX*/ +# endif +#endif + +/*int snprintf (char *str, size_t count, const char *fmt, ...);*/ +/*int vsnprintf (char *str, size_t count, const char *fmt, va_list arg);*/ + +static void dopr (char *buffer, size_t maxlen, const char *format, + va_list args); +static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max); +static void fmtint (char *buffer, size_t *currlen, size_t maxlen, + long value, int base, int min, int max, int flags); +static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, + long double fvalue, int min, int max, int flags); +static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c ); + +/* + * dopr(): poor man's version of doprintf + */ + +/* format read states */ +#define DP_S_DEFAULT 0 +#define DP_S_FLAGS 1 +#define DP_S_MIN 2 +#define DP_S_DOT 3 +#define DP_S_MAX 4 +#define DP_S_MOD 5 +#define DP_S_CONV 6 +#define DP_S_DONE 7 + +/* format flags - Bits */ +#define DP_F_MINUS (1 << 0) +#define DP_F_PLUS (1 << 1) +#define DP_F_SPACE (1 << 2) +#define DP_F_NUM (1 << 3) +#define DP_F_ZERO (1 << 4) +#define DP_F_UP (1 << 5) +#define DP_F_UNSIGNED (1 << 6) + +/* Conversion Flags */ +#define DP_C_SHORT 1 +#define DP_C_LONG 2 +#define DP_C_LDOUBLE 3 + +#define char_to_int(p) (p - '0') +#define MAX(p,q) ((p >= q) ? p : q) + +static void dopr (char *buffer, size_t maxlen, const char *format, va_list args) +{ + char ch; + long value; + long double fvalue; + char *strvalue; + int min; + int max; + int state; + int flags; + int cflags; + size_t currlen; + + state = DP_S_DEFAULT; + currlen = flags = cflags = min = 0; + max = -1; + ch = *format++; + + while (state != DP_S_DONE) + { + if ((ch == '\0') || (currlen >= maxlen)) + state = DP_S_DONE; + + switch(state) + { + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + dopr_outch (buffer, &currlen, maxlen, ch); + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) + { + case '-': + flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + flags |= DP_F_ZERO; + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) + { + min = 10*min + char_to_int (ch); + ch = *format++; + } + else if (ch == '*') + { + min = va_arg (args, int); + ch = *format++; + state = DP_S_DOT; + } + else + state = DP_S_DOT; + break; + case DP_S_DOT: + if (ch == '.') + { + state = DP_S_MAX; + ch = *format++; + } + else + state = DP_S_MOD; + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) + { + if (max < 0) + max = 0; + max = 10*max + char_to_int (ch); + ch = *format++; + } + else if (ch == '*') + { + max = va_arg (args, int); + ch = *format++; + state = DP_S_MOD; + } + else + state = DP_S_MOD; + break; + case DP_S_MOD: + /* Currently, we don't support Long Long, bummer */ + switch (ch) + { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + cflags = DP_C_LONG; + ch = *format++; + break; + case 'L': + cflags = DP_C_LDOUBLE; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) + { + case 'd': + case 'i': + if (cflags == DP_C_SHORT) + value = va_arg (args, short int); + else if (cflags == DP_C_LONG) + value = va_arg (args, long int); + else + value = va_arg (args, int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'o': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned short int); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else + value = va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 8, min, max, flags); + break; + case 'u': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned short int); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else + value = va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 10, min, max, flags); + break; + case 'X': + flags |= DP_F_UP; + case 'x': + flags |= DP_F_UNSIGNED; + if (cflags == DP_C_SHORT) + value = va_arg (args, unsigned short int); + else if (cflags == DP_C_LONG) + value = va_arg (args, unsigned long int); + else + value = va_arg (args, unsigned int); + fmtint (buffer, &currlen, maxlen, value, 16, min, max, flags); + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, long double); + else + fvalue = va_arg (args, double); + /* um, floating point? */ + fmtfp (buffer, &currlen, maxlen, fvalue, min, max, flags); + break; + case 'E': + flags |= DP_F_UP; + case 'e': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, long double); + else + fvalue = va_arg (args, double); + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg (args, long double); + else + fvalue = va_arg (args, double); + break; + case 'c': + dopr_outch (buffer, &currlen, maxlen, va_arg (args, int)); + break; + case 's': + strvalue = va_arg (args, char *); + if (max < 0) + max = maxlen; /* ie, no max */ + fmtstr (buffer, &currlen, maxlen, strvalue, flags, min, max); + break; + case 'p': + strvalue = va_arg (args, void *); + fmtint (buffer, &currlen, maxlen, (long) strvalue, 16, min, max, flags); + break; + case 'n': + if (cflags == DP_C_SHORT) + { + short int *num; + num = va_arg (args, short int *); + *num = currlen; + } + else if (cflags == DP_C_LONG) + { + long int *num; + num = va_arg (args, long int *); + *num = currlen; + } + else + { + int *num; + num = va_arg (args, int *); + *num = currlen; + } + break; + case '%': + dopr_outch (buffer, &currlen, maxlen, ch); + break; + case 'w': + /* not supported yet, treat as next char */ + ch = *format++; + break; + default: + /* Unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: + /* hmm? */ + break; /* some picky compilers need this */ + } + } + if (currlen < maxlen - 1) + buffer[currlen] = '\0'; + else + buffer[maxlen - 1] = '\0'; +} + +static void fmtstr (char *buffer, size_t *currlen, size_t maxlen, + char *value, int flags, int min, int max) +{ + int padlen, strln; /* amount to pad */ + int cnt = 0; + + if (value == 0) + { + value = ""; + } + + for (strln = 0; value[strln]; ++strln); /* strlen */ + padlen = min - strln; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justify */ + + while ((padlen > 0) && (cnt < max)) + { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + ++cnt; + } + while (*value && (cnt < max)) + { + dopr_outch (buffer, currlen, maxlen, *value++); + ++cnt; + } + while ((padlen < 0) && (cnt < max)) + { + dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + ++cnt; + } +} + +/* Have to handle DP_F_NUM (ie 0x and 0 alternates) */ + +static void fmtint (char *buffer, size_t *currlen, size_t maxlen, + long value, int base, int min, int max, int flags) +{ + int signvalue = 0; + unsigned long uvalue; + char convert[20]; + int place = 0; + int spadlen = 0; /* amount to space pad */ + int zpadlen = 0; /* amount to zero pad */ + int caps = 0; + + if (max < 0) + max = 0; + + uvalue = value; + + if(!(flags & DP_F_UNSIGNED)) + { + if( value < 0 ) { + signvalue = '-'; + uvalue = -value; + } + else + if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else + if (flags & DP_F_SPACE) + signvalue = ' '; + } + + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ + + do { + convert[place++] = + (caps? "0123456789ABCDEF":"0123456789abcdef") + [uvalue % (unsigned)base ]; + uvalue = (uvalue / (unsigned)base ); + } while(uvalue && (place < 20)); + if (place == 20) place--; + convert[place] = 0; + + zpadlen = max - place; + spadlen = min - MAX (max, place) - (signvalue ? 1 : 0); + if (zpadlen < 0) zpadlen = 0; + if (spadlen < 0) spadlen = 0; + if (flags & DP_F_ZERO) + { + zpadlen = MAX(zpadlen, spadlen); + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; /* Left Justifty */ + +#ifdef DEBUG_SNPRINTF + dprint (1, (debugfile, "zpad: %d, spad: %d, min: %d, max: %d, place: %d\n", + zpadlen, spadlen, min, max, place)); +#endif + + /* Spaces */ + while (spadlen > 0) + { + dopr_outch (buffer, currlen, maxlen, ' '); + --spadlen; + } + + /* Sign */ + if (signvalue) + dopr_outch (buffer, currlen, maxlen, signvalue); + + /* Zeros */ + if (zpadlen > 0) + { + while (zpadlen > 0) + { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + } + + /* Digits */ + while (place > 0) + dopr_outch (buffer, currlen, maxlen, convert[--place]); + + /* Left Justified spaces */ + while (spadlen < 0) { + dopr_outch (buffer, currlen, maxlen, ' '); + ++spadlen; + } +} + +static long double abs_val (long double value) +{ + long double result = value; + + if (value < 0) + result = -value; + + return result; +} + +static long double pow10 (int exp) +{ + long double result = 1; + + while (exp) + { + result *= 10; + exp--; + } + + return result; +} + +static long round (long double value) +{ + long intpart; + + intpart = value; + value = value - intpart; + if (value >= 0.5) + intpart++; + + return intpart; +} + +static void fmtfp (char *buffer, size_t *currlen, size_t maxlen, + long double fvalue, int min, int max, int flags) +{ + int signvalue = 0; + long double ufvalue; + char iconvert[20]; + char fconvert[20]; + int iplace = 0; + int fplace = 0; + int padlen = 0; /* amount to pad */ + int zpadlen = 0; + int caps = 0; + long intpart; + long fracpart; + + /* + * AIX manpage says the default is 0, but Solaris says the default + * is 6, and sprintf on AIX defaults to 6 + */ + if (max < 0) + max = 6; + + ufvalue = abs_val (fvalue); + + if (fvalue < 0) + signvalue = '-'; + else + if (flags & DP_F_PLUS) /* Do a sign (+/i) */ + signvalue = '+'; + else + if (flags & DP_F_SPACE) + signvalue = ' '; + +#if 0 + if (flags & DP_F_UP) caps = 1; /* Should characters be upper case? */ +#endif + + intpart = ufvalue; + + /* + * Sorry, we only support 9 digits past the decimal because of our + * conversion method + */ + if (max > 9) + max = 9; + + /* We "cheat" by converting the fractional part to integer by + * multiplying by a factor of 10 + */ + fracpart = round ((pow10 (max)) * (ufvalue - intpart)); + + if (fracpart >= pow10 (max)) + { + intpart++; + fracpart -= pow10 (max); + } + +#ifdef DEBUG_SNPRINTF + dprint (1, (debugfile, "fmtfp: %f =? %d.%d\n", fvalue, intpart, fracpart)); +#endif + + /* Convert integer part */ + do { + iconvert[iplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[intpart % 10]; + intpart = (intpart / 10); + } while(intpart && (iplace < 20)); + if (iplace == 20) iplace--; + iconvert[iplace] = 0; + + /* Convert fractional part */ + do { + fconvert[fplace++] = + (caps? "0123456789ABCDEF":"0123456789abcdef")[fracpart % 10]; + fracpart = (fracpart / 10); + } while(fracpart && (fplace < 20)); + if (fplace == 20) fplace--; + fconvert[fplace] = 0; + + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if (zpadlen < 0) + zpadlen = 0; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; /* Left Justifty */ + + if ((flags & DP_F_ZERO) && (padlen > 0)) + { + if (signvalue) + { + dopr_outch (buffer, currlen, maxlen, signvalue); + --padlen; + signvalue = 0; + } + while (padlen > 0) + { + dopr_outch (buffer, currlen, maxlen, '0'); + --padlen; + } + } + while (padlen > 0) + { + dopr_outch (buffer, currlen, maxlen, ' '); + --padlen; + } + if (signvalue) + dopr_outch (buffer, currlen, maxlen, signvalue); + + while (iplace > 0) + dopr_outch (buffer, currlen, maxlen, iconvert[--iplace]); + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + dopr_outch (buffer, currlen, maxlen, '.'); + + while (fplace > 0) + dopr_outch (buffer, currlen, maxlen, fconvert[--fplace]); + + while (zpadlen > 0) + { + dopr_outch (buffer, currlen, maxlen, '0'); + --zpadlen; + } + + while (padlen < 0) + { + dopr_outch (buffer, currlen, maxlen, ' '); + ++padlen; + } +} + +static void dopr_outch (char *buffer, size_t *currlen, size_t maxlen, char c) +{ + if (*currlen < maxlen) + buffer[(*currlen)++] = c; +} +#endif /* !defined(HAVE_SNPRINTF) || !defined(HAVE_VSNPRINTF) */ + +#ifndef HAVE_VSNPRINTF +int vsnprintf (char *str, size_t count, const char *fmt, va_list args) +{ + str[0] = 0; + dopr(str, count, fmt, args); + return(strlen(str)); +} +#endif /* !HAVE_VSNPRINTF */ + +#ifndef HAVE_SNPRINTF +/* VARARGS3 */ +#ifdef HAVE_STDARGS +int snprintf (char *str,size_t count,const char *fmt,...) +#else +int snprintf (va_alist) va_dcl +#endif +{ +#ifndef HAVE_STDARGS + char *str; + size_t count; + char *fmt; +#endif + VA_LOCAL_DECL; + + VA_START (fmt); + VA_SHIFT (str, char *); + VA_SHIFT (count, size_t ); + VA_SHIFT (fmt, char *); + (void) vsnprintf(str, count, fmt, ap); + VA_END; + return(strlen(str)); +} + +#ifdef TEST_SNPRINTF +#ifndef LONG_STRING +#define LONG_STRING 1024 +#endif +int main (void) +{ + char buf1[LONG_STRING]; + char buf2[LONG_STRING]; + char *fp_fmt[] = { + "%-1.5f", + "%1.5f", + "%123.9f", + "%10.5f", + "% 10.5f", + "%+22.9f", + "%+4.9f", + "%01.3f", + "%4f", + "%3.1f", + "%3.2f", + NULL + }; + double fp_nums[] = { -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, + 0.9996, 1.996, 4.136, 0}; + char *int_fmt[] = { + "%-1.5d", + "%1.5d", + "%123.9d", + "%5.5d", + "%10.5d", + "% 10.5d", + "%+22.33d", + "%01.3d", + "%4d", + NULL + }; + long int_nums[] = { -1, 134, 91340, 341, 0203, 0}; + int x, y; + int fail = 0; + int num = 0; + + printf ("Testing snprintf format codes against system sprintf...\n"); + + for (x = 0; fp_fmt[x] != NULL ; x++) + for (y = 0; fp_nums[y] != 0 ; y++) + { + snprintf (buf1, sizeof (buf1), fp_fmt[x], fp_nums[y]); + sprintf (buf2, fp_fmt[x], fp_nums[y]); + if (strcmp (buf1, buf2)) + { + printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", + fp_fmt[x], buf1, buf2); + fail++; + } + num++; + } + + for (x = 0; int_fmt[x] != NULL ; x++) + for (y = 0; int_nums[y] != 0 ; y++) + { + snprintf (buf1, sizeof (buf1), int_fmt[x], int_nums[y]); + sprintf (buf2, int_fmt[x], int_nums[y]); + if (strcmp (buf1, buf2)) + { + printf("snprintf doesn't match Format: %s\n\tsnprintf = %s\n\tsprintf = %s\n", + int_fmt[x], buf1, buf2); + fail++; + } + num++; + } + printf ("%d tests failed out of %d.\n", fail, num); +} +#endif /* SNPRINTF_TEST */ + +#endif /* !HAVE_SNPRINTF */ diff --git a/libs/cyrussasl/lib/staticopen.h b/libs/cyrussasl/lib/staticopen.h new file mode 100644 index 00000000..4e503195 --- /dev/null +++ b/libs/cyrussasl/lib/staticopen.h @@ -0,0 +1,184 @@ +/* staticopen.h + * Rob Siemborski + * Howard Chu + * $Id: staticopen.h,v 1.9 2011/04/05 14:50:07 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +typedef enum { + UNKNOWN = 0, SERVER = 1, CLIENT = 2, AUXPROP = 3, CANONUSER = 4 +} _sasl_plug_type; + +typedef struct { + _sasl_plug_type type; + char *name; + sasl_client_plug_init_t *plug; +} _sasl_plug_rec; + +/* For static linking */ +#define SPECIFIC_CLIENT_PLUG_INIT_PROTO( x ) \ +sasl_client_plug_init_t x##_client_plug_init + +#define SPECIFIC_SERVER_PLUG_INIT_PROTO( x ) \ +sasl_server_plug_init_t x##_server_plug_init + +#define SPECIFIC_AUXPROP_PLUG_INIT_PROTO( x ) \ +sasl_auxprop_init_t x##_auxprop_plug_init + +#define SPECIFIC_CANONUSER_PLUG_INIT_PROTO( x ) \ +sasl_canonuser_init_t x##_canonuser_plug_init + +/* Static Compillation Foo */ +#define SPECIFIC_CLIENT_PLUG_INIT( x, n )\ + { CLIENT, n, x##_client_plug_init } +#define SPECIFIC_SERVER_PLUG_INIT( x, n )\ + { SERVER, n, (sasl_client_plug_init_t *)x##_server_plug_init } +#define SPECIFIC_AUXPROP_PLUG_INIT( x, n )\ + { AUXPROP, n, (sasl_client_plug_init_t *)x##_auxprop_plug_init } +#define SPECIFIC_CANONUSER_PLUG_INIT( x, n )\ + { CANONUSER, n, (sasl_client_plug_init_t *)x##_canonuser_plug_init } + +#ifdef STATIC_ANONYMOUS +extern SPECIFIC_SERVER_PLUG_INIT_PROTO( anonymous ); +extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( anonymous ); +#endif +#ifdef STATIC_CRAMMD5 +extern SPECIFIC_SERVER_PLUG_INIT_PROTO( crammd5 ); +extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( crammd5 ); +#endif +#ifdef STATIC_DIGESTMD5 +extern SPECIFIC_SERVER_PLUG_INIT_PROTO( digestmd5 ); +extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( digestmd5 ); +#endif +#ifdef STATIC_SCRAM +extern SPECIFIC_SERVER_PLUG_INIT_PROTO( scram ); +extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( scram ); +#endif +#ifdef STATIC_GSSAPIV2 +extern SPECIFIC_SERVER_PLUG_INIT_PROTO( gssapiv2 ); +extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( gssapiv2 ); +#endif +#ifdef STATIC_KERBEROS4 +extern SPECIFIC_SERVER_PLUG_INIT_PROTO( kerberos4 ); +extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( kerberos4 ); +#endif +#ifdef STATIC_LOGIN +extern SPECIFIC_SERVER_PLUG_INIT_PROTO( login ); +extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( login ); +#endif +#ifdef STATIC_NTLM +extern SPECIFIC_SERVER_PLUG_INIT_PROTO( ntlm ); +extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( ntlm ); +#endif +#ifdef STATIC_OTP +extern SPECIFIC_SERVER_PLUG_INIT_PROTO( otp ); +extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( otp ); +#endif +#ifdef STATIC_PLAIN +extern SPECIFIC_SERVER_PLUG_INIT_PROTO( plain ); +extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( plain ); +#endif +#ifdef STATIC_SRP +extern SPECIFIC_SERVER_PLUG_INIT_PROTO( srp ); +extern SPECIFIC_CLIENT_PLUG_INIT_PROTO( srp ); +#endif +#ifdef STATIC_SASLDB +extern SPECIFIC_AUXPROP_PLUG_INIT_PROTO( sasldb ); +#endif +#ifdef STATIC_SQL +extern SPECIFIC_AUXPROP_PLUG_INIT_PROTO( sql ); +#endif +#ifdef STATIC_LDAPDB +extern SPECIFIC_AUXPROP_PLUG_INIT_PROTO( ldapdb ); +#endif + +_sasl_plug_rec _sasl_static_plugins[] = { +#ifdef STATIC_ANONYMOUS + SPECIFIC_SERVER_PLUG_INIT( anonymous, "ANONYMOUS" ), + SPECIFIC_CLIENT_PLUG_INIT( anonymous, "ANONYMOUS" ), +#endif +#ifdef STATIC_CRAMMD5 + SPECIFIC_SERVER_PLUG_INIT( crammd5, "CRAM-MD5" ), + SPECIFIC_CLIENT_PLUG_INIT( crammd5, "CRAM-MD5" ), +#endif +#ifdef STATIC_DIGESTMD5 + SPECIFIC_SERVER_PLUG_INIT( digestmd5, "DIGEST-MD5" ), + SPECIFIC_CLIENT_PLUG_INIT( digestmd5, "DIGEST-MD5" ), +#endif +#ifdef STATIC_GSSAPIV2 + SPECIFIC_SERVER_PLUG_INIT( gssapiv2, "GSSAPI" ), + SPECIFIC_CLIENT_PLUG_INIT( gssapiv2, "GSSAPI" ), +#endif +#ifdef STATIC_KERBEROS4 + SPECIFIC_SERVER_PLUG_INIT( kerberos4, "KERBEROS_V4" ), + SPECIFIC_CLIENT_PLUG_INIT( kerberos4, "KERBEROS_V4" ), +#endif +#ifdef STATIC_LOGIN + SPECIFIC_SERVER_PLUG_INIT( login, "LOGIN" ), + SPECIFIC_CLIENT_PLUG_INIT( login, "LOGIN" ), +#endif +#ifdef STATIC_NTLM + SPECIFIC_SERVER_PLUG_INIT( ntlm, "NTLM" ), + SPECIFIC_CLIENT_PLUG_INIT( ntlm, "NTLM" ), +#endif +#ifdef STATIC_OTP + SPECIFIC_SERVER_PLUG_INIT( otp, "OTP" ), + SPECIFIC_CLIENT_PLUG_INIT( otp, "OTP" ), +#endif +#ifdef STATIC_PLAIN + SPECIFIC_SERVER_PLUG_INIT( plain, "PLAIN" ), + SPECIFIC_CLIENT_PLUG_INIT( plain, "PLAIN" ), +#endif +#ifdef STATIC_SRP + SPECIFIC_SERVER_PLUG_INIT( srp, "SRP" ), + SPECIFIC_CLIENT_PLUG_INIT( srp, "SRP" ), +#endif +#ifdef STATIC_SASLDB + SPECIFIC_AUXPROP_PLUG_INIT( sasldb, "SASLDB" ), +#endif +#ifdef STATIC_SQL + SPECIFIC_AUXPROP_PLUG_INIT( sql, "SQL" ), +#endif +#ifdef STATIC_LDAPDB + SPECIFIC_AUXPROP_PLUG_INIT( ldapdb, "LDAPDB" ), +#endif + { UNKNOWN, NULL, NULL } +}; diff --git a/libs/cyrussasl/lib/windlopen.c b/libs/cyrussasl/lib/windlopen.c new file mode 100644 index 00000000..f514e0dd --- /dev/null +++ b/libs/cyrussasl/lib/windlopen.c @@ -0,0 +1,330 @@ +/* windlopen.c--Windows dynamic loader interface + * Ryan Troll + * $Id: windlopen.c,v 1.17 2009/01/25 20:20:57 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include +#include +#include "saslint.h" + +#define DLL_SUFFIX ".dll" +#define DLL_MASK "*" DLL_SUFFIX +#define DLL_MASK_LEN 5 + +const int _is_sasl_server_static = 0; + +/* : inefficient representation, but works */ +typedef struct lib_list +{ + struct lib_list *next; + HMODULE library; +} lib_list_t; + +static lib_list_t *lib_list_head = NULL; + +int _sasl_locate_entry(void *library, + const char *entryname, + void **entry_point) +{ + if(entryname == NULL) { + _sasl_log(NULL, SASL_LOG_ERR, + "no entryname in _sasl_locate_entry"); + return SASL_BADPARAM; + } + + if(library == NULL) { + _sasl_log(NULL, SASL_LOG_ERR, + "no library in _sasl_locate_entry"); + return SASL_BADPARAM; + } + + if(entry_point == NULL) { + _sasl_log(NULL, SASL_LOG_ERR, + "no entrypoint output pointer in _sasl_locate_entry"); + return SASL_BADPARAM; + } + + *entry_point = GetProcAddress(library, entryname); + + if (*entry_point == NULL) { +#if 0 /* This message appears to confuse people */ + _sasl_log(NULL, SASL_LOG_DEBUG, + "unable to get entry point %s: %s", entryname, + GetLastError()); +#endif + return SASL_FAIL; + } + + return SASL_OK; +} + +static int _sasl_plugin_load(char *plugin, void *library, + const char *entryname, + int (*add_plugin)(const char *, void *)) +{ + void *entry_point; + int result; + + result = _sasl_locate_entry(library, entryname, &entry_point); + if(result == SASL_OK) { + result = add_plugin(plugin, entry_point); + if(result != SASL_OK) + _sasl_log(NULL, SASL_LOG_DEBUG, + "_sasl_plugin_load failed on %s for plugin: %s\n", + entryname, plugin); + } + + return result; +} + +/* loads a plugin library */ +int _sasl_get_plugin(const char *file, + const sasl_callback_t *verifyfile_cb, + void **libraryptr) +{ + int r = 0; + HINSTANCE library; + lib_list_t *newhead; + + r = ((sasl_verifyfile_t *)(verifyfile_cb->proc)) + (verifyfile_cb->context, file, SASL_VRFY_PLUGIN); + if (r != SASL_OK) return r; + + newhead = sasl_ALLOC(sizeof(lib_list_t)); + if (!newhead) return SASL_NOMEM; + + if (!(library = LoadLibrary (file))) { + _sasl_log(NULL, SASL_LOG_ERR, + "unable to LoadLibrary %s: %s", file, GetLastError()); + sasl_FREE(newhead); + return SASL_FAIL; + } + + newhead->library = library; + newhead->next = lib_list_head; + lib_list_head = newhead; + + *libraryptr = library; + return SASL_OK; +} + +/* undoes actions done by _sasl_get_plugin */ +void _sasl_remove_last_plugin() +{ + lib_list_t *last_plugin = lib_list_head; + lib_list_head = lib_list_head->next; + if (last_plugin->library) { + FreeLibrary(last_plugin->library); + } + sasl_FREE(last_plugin); +} + +/* gets the list of mechanisms */ +int _sasl_load_plugins(const add_plugin_list_t *entrypoints, + const sasl_callback_t *getpath_cb, + const sasl_callback_t *verifyfile_cb) +{ + int result; + char cur_dir[PATH_MAX], full_name[PATH_MAX+2], prefix[PATH_MAX+2]; + /* 1 for '\\' 1 for trailing '\0' */ + char * pattern; + char c; + int pos; + const char *path=NULL; + int position; + const add_plugin_list_t *cur_ep; + struct stat statbuf; /* filesystem entry information */ + intptr_t fhandle; /* file handle for _findnext function */ + struct _finddata_t finddata; /* data returned by _findnext() */ + size_t prefix_len; + + if (! entrypoints + || ! getpath_cb + || getpath_cb->id != SASL_CB_GETPATH + || ! getpath_cb->proc + || ! verifyfile_cb + || verifyfile_cb->id != SASL_CB_VERIFYFILE + || ! verifyfile_cb->proc) + return SASL_BADPARAM; + + /* get the path to the plugins */ + result = ((sasl_getpath_t *)(getpath_cb->proc))(getpath_cb->context, + &path); + if (result != SASL_OK) return result; + if (! path) return SASL_FAIL; + + if (strlen(path) >= PATH_MAX) { /* no you can't buffer overrun */ + return SASL_FAIL; + } + + position=0; + do { + pos=0; + do { + c=path[position]; + position++; + cur_dir[pos]=c; + pos++; + } while ((c!=PATHS_DELIMITER) && (c!=0)); + cur_dir[pos-1]='\0'; + + +/* : check to make sure that a valid directory name was passed in */ + if (stat (cur_dir, &statbuf) < 0) { + continue; + } + if ((statbuf.st_mode & S_IFDIR) == 0) { + continue; + } + + strcpy (prefix, cur_dir); + prefix_len = strlen (prefix); + +/* : Don't append trailing \ unless required */ + if (prefix[prefix_len-1] != '\\') { + strcat (prefix,"\\"); + prefix_len++; + } + + pattern = prefix; + +/* : Check that we have enough space for "*.dll" */ + if ((prefix_len + DLL_MASK_LEN) > (sizeof(prefix) - 1)) { + _sasl_log(NULL, SASL_LOG_WARN, "plugin search mask is too big"); + continue; + } + + strcat (prefix + prefix_len, "*" DLL_SUFFIX); + + fhandle = _findfirst (pattern, &finddata); + if (fhandle == -1) { /* no matching files */ + continue; + } + +/* : Truncate "*.dll" */ + prefix[prefix_len] = '\0'; + + do { + size_t length; + void *library; + char *c; + char plugname[PATH_MAX]; + int entries; + + length = strlen(finddata.name); + if (length < 5) { /* At least .dll */ + continue; /* can not possibly be what we're looking for */ + } + +/* : Check for overflow */ + if (length + prefix_len >= PATH_MAX) continue; /* too big */ + + if (stricmp(finddata.name + (length - strlen(DLL_SUFFIX)), DLL_SUFFIX) != 0) { + continue; + } + +/* : Check that it is not a directory */ + if ((finddata.attrib & _A_SUBDIR) == _A_SUBDIR) { + continue; + } + +/* : Construct full name from prefix and name */ + + strcpy (full_name, prefix); + strcat (full_name, finddata.name); + +/* cut off .dll suffix -- this only need be approximate */ + strcpy (plugname, finddata.name); + c = strrchr(plugname, '.'); + if (c != NULL) *c = '\0'; + + result = _sasl_get_plugin (full_name, verifyfile_cb, &library); + + if (result != SASL_OK) { + continue; + } + + entries = 0; + for (cur_ep = entrypoints; cur_ep->entryname; cur_ep++) { + result = _sasl_plugin_load(plugname, + library, + cur_ep->entryname, + cur_ep->add_plugin); + if (result == SASL_OK) { + ++entries; + } + /* If this fails, it's not the end of the world */ + } + if (entries == 0) { + _sasl_remove_last_plugin(); + } + + } while (_findnext (fhandle, &finddata) == 0); + + _findclose (fhandle); + + } while ((c!='=') && (c!=0)); + + return SASL_OK; +} + +int +_sasl_done_with_plugins(void) +{ + lib_list_t *libptr, *libptr_next; + + for(libptr = lib_list_head; libptr; libptr = libptr_next) { + libptr_next = libptr->next; + if (libptr->library != NULL) { + FreeLibrary(libptr->library); + } + sasl_FREE(libptr); + } + + lib_list_head = NULL; + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/Makefile.am b/libs/cyrussasl/plugins/Makefile.am new file mode 100644 index 00000000..d570de1c --- /dev/null +++ b/libs/cyrussasl/plugins/Makefile.am @@ -0,0 +1,158 @@ +# Makefile.am for the SASL plugins +# Rob Siemborski +# Rob Earhart +# $Id: Makefile.am,v 1.86 2011/09/05 14:18:10 murch Exp $ +# +################################################################ +# Copyright (c) 2000 Carnegie Mellon University. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. The name "Carnegie Mellon University" must not be used to +# endorse or promote products derived from this software without +# prior written permission. For permission or any other legal +# details, please contact +# Office of Technology Transfer +# Carnegie Mellon University +# 5000 Forbes Avenue +# Pittsburgh, PA 15213-3890 +# (412) 268-4387, fax: (412) 268-7395 +# tech-transfer@andrew.cmu.edu +# +# 4. Redistributions of any form whatsoever must retain the following +# acknowledgment: +# "This product includes software developed by Computing Services +# at Carnegie Mellon University (http://www.cmu.edu/computing/)." +# +# CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO +# THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE +# FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN +# AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING +# OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +# +################################################################ + +# Library version info - here at the top, for sanity +# See +# CURRENT:REVISION:AGE +plugin_version = 3:0:0 + +INCLUDES=-I$(top_srcdir)/include -I$(top_srcdir)/lib -I$(top_srcdir)/sasldb -I$(top_builddir)/include +AM_LDFLAGS = -module -export-dynamic -rpath $(plugindir) -version-info $(plugin_version) + +COMPAT_OBJS = @LTGETADDRINFOOBJS@ @LTGETNAMEINFOOBJS@ @LTSNPRINTFOBJS@ + +EXTRA_DIST = makeinit.sh NTMakefile +noinst_SCRIPTS = makeinit.sh + +LIB_MYSQL = @LIB_MYSQL@ + +plugindir = @plugindir@ + +common_sources = plugin_common.c plugin_common.h + +sasldir = $(prefix)/lib/sasl2 +sasl_LTLIBRARIES = @SASL_MECHS@ +EXTRA_LTLIBRARIES = libplain.la libanonymous.la libkerberos4.la libcrammd5.la \ + libgs2.la libgssapiv2.la libdigestmd5.la liblogin.la libsrp.la libotp.la \ + libscram.la libntlm.la libpassdss.la libsasldb.la libsql.la libldapdb.la + +libplain_la_SOURCES = plain.c plain_init.c $(common_sources) +libplain_la_DEPENDENCIES = $(COMPAT_OBJS) +libplain_la_LIBADD = $(PLAIN_LIBS) $(COMPAT_OBJS) + +libanonymous_la_SOURCES = anonymous.c anonymous_init.c $(common_sources) +libanonymous_la_DEPENDENCIES = $(COMPAT_OBJS) +libanonymous_la_LIBADD = $(COMPAT_OBJS) + +libkerberos4_la_SOURCES = kerberos4.c kerberos4_init.c $(common_sources) +libkerberos4_la_DEPENDENCIES = $(COMPAT_OBJS) +libkerberos4_la_LIBADD = $(SASL_KRB_LIB) $(LIB_SOCKET) $(COMPAT_OBJS) + +libgs2_la_SOURCES = gs2.c gs2_init.c gs2_token.c gs2_token.h $(common_sources) +libgs2_la_DEPENDENCIES = $(COMPAT_OBJS) +libgs2_la_LIBADD = $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET) $(COMPAT_OBJS) + +libgssapiv2_la_SOURCES = gssapi.c gssapiv2_init.c $(common_sources) +libgssapiv2_la_DEPENDENCIES = $(COMPAT_OBJS) +libgssapiv2_la_LIBADD = $(GSSAPIBASE_LIBS) $(GSSAPI_LIBS) $(LIB_SOCKET) $(COMPAT_OBJS) + +libcrammd5_la_SOURCES = cram.c crammd5_init.c $(common_sources) +libcrammd5_la_DEPENDENCIES = $(COMPAT_OBJS) +libcrammd5_la_LIBADD = $(COMPAT_OBJS) + +libdigestmd5_la_SOURCES = digestmd5.c digestmd5_init.c $(common_sources) +libdigestmd5_la_DEPENDENCIES = $(COMPAT_OBJS) +libdigestmd5_la_LIBADD = $(LIB_DES) $(LIB_SOCKET) $(COMPAT_OBJS) + +libscram_la_SOURCES = scram.c scram_init.c $(common_sources) +libscram_la_DEPENDENCIES = $(COMPAT_OBJS) +libscram_la_LIBADD = $(SCRAM_LIBS) $(COMPAT_OBJS) + +liblogin_la_SOURCES = login.c login_init.c $(common_sources) +liblogin_la_DEPENDENCIES = $(COMPAT_OBJS) +liblogin_la_LIBADD = $(PLAIN_LIBS) $(COMPAT_OBJS) + +libsrp_la_SOURCES = srp.c srp_init.c $(common_sources) +libsrp_la_DEPENDENCIES = $(COMPAT_OBJS) +libsrp_la_LIBADD = $(SRP_LIBS) $(COMPAT_OBJS) + +libotp_la_SOURCES = otp.c otp_init.c otp.h $(common_sources) +libotp_la_DEPENDENCIES = $(COMPAT_OBJS) +libotp_la_LIBADD = $(OTP_LIBS) $(COMPAT_OBJS) + +libntlm_la_SOURCES = ntlm.c ntlm_init.c $(common_sources) +libntlm_la_DEPENDENCIES = $(COMPAT_OBJS) +libntlm_la_LIBADD = $(NTLM_LIBS) $(COMPAT_OBJS) + +libpassdss_la_SOURCES = passdss.c passdss_init.c $(common_sources) +libpassdss_la_DEPENDENCIES = $(COMPAT_OBJS) +libpassdss_la_LIBADD = $(PASSDSS_LIBS) $(COMPAT_OBJS) + +# Auxprop Plugins +libsasldb_la_SOURCES = sasldb.c sasldb_init.c $(common_sources) +libsasldb_la_DEPENDENCIES = $(COMPAT_OBJS) +libsasldb_la_LIBADD = ../sasldb/libsasldb.la $(SASL_DB_LIB) $(COMPAT_OBJS) + +libldapdb_la_SOURCES = ldapdb.c ldapdb_init.c $(common_sources) +libldapdb_la_DEPENDENCIES = $(COMPAT_OBJS) +libldapdb_la_LIBADD = $(LIB_LDAP) $(COMPAT_OBJS) + +libsql_la_SOURCES = sql.c sql_init.c $(common_sources) +libsql_la_LDFLAGS = $(LIB_MYSQL) $(LIB_PGSQL) $(LIB_SQLITE) $(LIB_SQLITE3) \ + $(AM_LDFLAGS) +libsql_la_DEPENDENCIES = $(COMPAT_OBJS) +libsql_la_LIBADD = $(COMPAT_OBJS) + + +# Instructions for making the _init files + +init_src=anonymous_init.c crammd5_init.c digestmd5_init.c scram_init.c gs2_init.c gssapiv2_init.c \ +kerberos4_init.c login_init.c plain_init.c srp_init.c otp_init.c ntlm_init.c \ +passdss_init.c sasldb_init.c sql_init.c ldapdb_init.c + + +CLEANFILES=$(init_src) + +${init_src}: $(srcdir)/makeinit.sh + $(SHELL) $(srcdir)/makeinit.sh + +# Compatibility function build rules (they build in lib/) +$(COMPAT_OBJS): + rm -f $(COMPAT_OBJS) + cd ../lib; $(MAKE) $(COMPAT_OBJS) + for file in $(COMPAT_OBJS); do ln -s ../lib/$$file .; done + + diff --git a/libs/cyrussasl/plugins/NTMakefile b/libs/cyrussasl/plugins/NTMakefile new file mode 100755 index 00000000..32dc58eb --- /dev/null +++ b/libs/cyrussasl/plugins/NTMakefile @@ -0,0 +1,325 @@ +!INCLUDE ..\win32\common.mak + +SCRAM=1 + +!IF "$(NTLM)" == "1" +PLUGINS_EXT=saslNTLM.dll +!ELSE +PLUGINS_EXT= +!ENDIF + +!IF "$(GSSAPI)" == "CyberSafe" +PLUGINS_EXT=$(PLUGINS_EXT) saslGSSAPI.dll +!ENDIF + +!IF "$(SRP)" == "1" +PLUGINS_EXT=$(PLUGINS_EXT) saslSRP.dll +!IF "$(DO_SRP_SETPASS)" == "1" +SRP_FLAGS=/DDO_SRP_SETPASS=1 +!ENDIF +!ENDIF + +!IF "$(OTP)" == "1" +PLUGINS_EXT=$(PLUGINS_EXT) saslOTP.dll +!ENDIF + +!IF "$(LDAP)" == "1" +PLUGINS_EXT=$(PLUGINS_EXT) saslLDAPDB.dll + +# NB: linking to libsasl itself!!! +LDAP_FLAGS = /I $(LDAP_INCLUDE) +LDAP_LIBS = $(LDAP_LIB_BASE)\olber32.lib $(LDAP_LIB_BASE)\oldap32.lib ..\lib\libsasl.lib +!ENDIF + +!IF "$(SQL)" == "SQLITE" +PLUGINS_EXT=$(PLUGINS_EXT) saslSQLITE.dll +SQL_FLAGS= $(SQLITE_INCLUDES) /DHAVE_SQLITE=1 +SQLITE_LIBS = /libpath:$(SQLITE_LIBPATH) libsqlite.lib +!ENDIF +!IF "$(SQL)" == "SQLITE3" +PLUGINS_EXT=$(PLUGINS_EXT) saslSQLITE.dll +SQL_FLAGS= $(SQLITE_INCLUDES3) /DHAVE_SQLITE3=1 +SQLITE_LIBS = /libpath:$(SQLITE_LIBPATH3) libsqlite3.lib +!ENDIF + +PLUGINS=saslANONYMOUS.dll \ + saslPLAIN.dll \ + saslCRAMMD5.dll \ + saslDIGESTMD5.dll \ + saslLOGIN.dll \ + saslSCRAM.dll \ + $(PLUGINS_EXT) \ + saslSASLDB.dll + +generated_rc=saslANONYMOUS.rc saslPLAIN.rc saslCRAMMD5.rc saslDIGESTMD5.rc saslLOGIN.rc saslNTLM.rc saslSCRAM.rc saslGSSAPI.rc saslSRP.rc saslOTP.rc saslSASLDB.rc saslSQLITE.rc saslLDAPDB.rc + +# WS2tcpip.h included in Visual Studio 7 provides getaddrinfo, ... +# emulation on Windows, so there is no need to build getaddrinfo.c + +!IF "$(VCVER)" == "6" +compat_sources = getaddrinfo.c getnameinfo.c +compat_objs = getaddrinfo.obj getnameinfo.obj +!ENDIF + +common_sources = plugin_common.c plugin_common.h +common_objs = plugin_common.obj $(compat_objs) + +saslANONYMOUS_sources = anonymous.c anonymous_init.c $(common_sources) +saslANONYMOUS_objs = anonymous.obj anonymous_init.obj $(common_objs) +saslANONYMOUS_out = saslANONYMOUS.dll saslANONYMOUS.exp saslANONYMOUS.lib + +saslPLAIN_sources = plain.c plain_init.c $(common_sources) +saslPLAIN_objs = plain.obj plain_init.obj $(common_objs) +saslPLAIN_out = saslPLAIN.dll saslPLAIN.exp saslPLAIN.lib + +saslCRAMMD5_sources = cram.c crammd5_init.c $(common_sources) +saslCRAMMD5_objs = cram.obj crammd5_init.obj $(common_objs) +saslCRAMMD5_out = saslCRAMMD5.dll saslCRAMMD5.exp saslCRAMMD5.lib + +saslDIGESTMD5_sources = digestmd5.c digestmd5_init.c $(common_sources) +saslDIGESTMD5_objs = digestmd5.obj digestmd5_init.obj $(common_objs) +saslDIGESTMD5_out = saslDIGESTMD5.dll saslDIGESTMD5.exp saslDIGESTMD5.lib + +saslLOGIN_sources = login.c login_init.c $(common_sources) +saslLOGIN_objs = login.obj login_init.obj $(common_objs) +saslLOGIN_out = saslLOGIN.dll saslLOGIN.exp saslLOGIN.lib + +saslSCRAM_sources = scram.c scram_init.c $(common_sources) +saslSCRAM_objs = scram.obj scram_init.obj $(common_objs) +saslSCRAM_out = saslSCRAM.dll saslSCRAM.exp saslSCRAM.lib + +saslNTLM_sources = ntlm.c ntlm_init.c $(common_sources) +saslNTLM_objs = ntlm.obj ntlm_init.obj $(common_objs) +saslNTLM_out = saslNTLM.dll saslNTLM.exp saslNTLM.lib + +saslGSSAPI_sources = gssapi.c gssapiv2_init.c $(common_sources) +saslGSSAPI_objs = gssapi.obj gssapiv2_init.obj $(common_objs) +saslGSSAPI_out = saslGSSAPI.dll saslGSSAPI.exp saslGSSAPI.lib + +saslSRP_sources = srp.c srp_init.c $(common_sources) +saslSRP_objs = srp.obj srp_init.obj $(common_objs) +saslSRP_out = saslSRP.dll saslSRP.exp saslSRP.lib + +saslOTP_sources = otp.c otp_init.c $(common_sources) +saslOTP_objs = otp.obj otp_init.obj $(common_objs) +saslOTP_out = saslOTP.dll saslOTP.exp saslOTP.lib + +saslSQL_sources = sql.c sql_init.c $(common_sources) +saslSQL_objs = sql.obj sql_init.obj $(common_objs) +# saslSQL_out is an agregation of all generated files for all SQL plugins +saslSQL_out = saslSQLITE.dll saslSQLITE.exp saslSQLITE.lib + +saslLDAPDB_sources = ldapdb.c $(common_sources) +saslLDAPDB_objs = ldapdb.obj $(common_objs) +saslLDAPDB_out = saslLDAPDB.dll saslLDAPDB.exp saslLDAPDB.lib + +!IF "$(NTLM)" == "1" || "$(SRP)" == "1" || "$(OTP)" == "1" || "$(SCRAM)" == "1" +OPENSSL_FLAGS= /I $(OPENSSL_INCLUDE) +!ELSE +OPENSSL_FLAGS= +!ENDIF + +!IF "$(GSSAPI)" == "CyberSafe" +GSS_FLAGS= /I $(GSSAPI_INCLUDE) /D "HAVE_GSS_C_NT_HOSTBASED_SERVICE" /D "HAVE_GSS_C_NT_USER_NAME" +GSS_LIBS=/libpath:$(GSSAPI_LIBPATH) gssapi32.lib +!ELSE +GSS_FLAGS= +GSS_LIBS= +!ENDIF + +CRAM_FLAGS=/DOBSOLETE_CRAM_ATTR=1 + +DIGEST_FLAGS=/D "WITH_RC4" + +# Auxprop Plugin +libsasldb_sources = allockey.c db_berkeley.c +libsasldb_objs = allockey.obj db_berkeley.obj + +saslSASLDB_sources = sasldb.c sasldb_init.c $(libsasldb_sources) $(common_sources) +saslSASLDB_objs = sasldb.obj sasldb_init.obj $(libsasldb_objs) $(common_objs) +saslSASLDB_out = saslSASLDB.dll saslSASLDB.exp saslSASLDB.lib + +all_objs = $(saslANONYMOUS_objs) $(saslPLAIN_objs) $(saslCRAMMD5_objs) $(saslDIGESTMD5_objs) $(saslLOGIN_objs) $(saslSCRAM_objs) $(saslNTLM_objs) $(saslGSSAPI_objs) $(saslSRP_objs) $(saslOTP_objs) $(saslSASLDB_objs) $(saslSQL_objs) $(saslLDAPDB_objs) +all_out = $(saslANONYMOUS_out) $(saslPLAIN_out) $(saslCRAMMD5_out) $(saslDIGESTMD5_out) $(saslLOGIN_out) $(saslSCRAM_out) $(saslNTLM_out) $(saslGSSAPI_out) $(saslSRP_out) $(saslOTP_out) $(saslSASLDB_out) $(saslSQL_out) $(saslLDAPDB_out) + +# LIBSASL_EXPORTS is required to export additional DB routines from sasldb +DB_FLAGS = /I $(DB_INCLUDE) /I "..\sasldb" /D "LIBSASL_EXPORTS" /D "KEEP_DB_OPEN" + +!IF $(TARGET_WIN_SYSTEM) >= 51 +EXTRA_FLAGS = /D TARGET_WIN_SYSTEM=$(TARGET_WIN_SYSTEM) $(EXTRA_FLAGS) +!ENDIF + +EXTRA_FLAGS=$(EXTRA_FLAGS) $(DB_FLAGS) $(OPENSSL_FLAGS) $(GSS_FLAGS) $(SRP_FLAGS) $(SQL_FLAGS) $(DIGEST_FLAGS) $(CRAM_FLAGS) $(LDAP_FLAGS) +CPPFLAGS = /I "..\win32\include" /I "." /I "..\include" $(EXTRA_FLAGS) /D "WIN32" /D "_WIN32" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" + +DB_LIBS=/libpath:$(DB_LIBPATH) $(DB_LIB) +OPENSSL_LIBS=/libpath:$(OPENSSL_LIBPATH) libeay32.lib ssleay32.lib + +# Where to install files from this directory +libdir = $(prefix)\lib +bindir = $(prefix)\bin\sasl2 + +all : all-recursive + +# +# /I flag to xcopy tells to treat the last parameter as directory and create all missing levels +# +# In order to force xcopy not to confirm if the second parameter is file or directory, +# the first parameter has to contain a wildcard character. For example, we use libsasl.l*, +# instead of libsasl.lib. Ugly, but works! +# +# Note, that we will copy all dlls here, not just $(PLUGINS). This is a bug, but it allows +# us to copy GSSAPI plugin, which might not be in $(PLUGINS). +# +install: $(PLUGINS) + @xcopy *.dll $(bindir) /I /F /Y + +all-recursive : $(PLUGINS) + +getaddrinfo.c: ..\lib\getaddrinfo.c + xcopy /D /Y ..\lib\getaddrinfo.c . + +getnameinfo.c: ..\lib\getnameinfo.c + xcopy /D /Y ..\lib\getnameinfo.c . + +allockey.c: ..\sasldb\allockey.c + xcopy /D /Y ..\sasldb\allockey.c . + +db_berkeley.c: ..\sasldb\db_berkeley.c + xcopy /D /Y ..\sasldb\db_berkeley.c . + +#Add /pdb: option? + +saslANONYMOUS.dll: $(saslANONYMOUS_objs) saslANONYMOUS.res + $(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslANONYMOUS.dll" /implib:"saslANONYMOUS.lib" $(saslANONYMOUS_objs) saslANONYMOUS.res +<< + IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2 + +saslPLAIN.dll: $(saslPLAIN_objs) saslPLAIN.res + $(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslPLAIN.dll" /implib:"saslPLAIN.lib" $(saslPLAIN_objs) saslPLAIN.res +<< + IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2 + +saslCRAMMD5.dll: $(saslCRAMMD5_objs) saslCRAMMD5.res + $(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslCRAMMD5.dll" /implib:"saslCRAMMD5.lib" $(saslCRAMMD5_objs) saslCRAMMD5.res +<< + IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2 + +saslDIGESTMD5.dll: $(saslDIGESTMD5_objs) saslDIGESTMD5.res + $(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslDIGESTMD5.dll" /implib:"saslDIGESTMD5.lib" $(saslDIGESTMD5_objs) saslDIGESTMD5.res +<< + IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2 + +saslLOGIN.dll: $(saslLOGIN_objs) saslLOGIN.res + $(LINK32DLL) @<< $(LINK32DLL_FLAGS) /out:"saslLOGIN.dll" /implib:"saslLOGIN.lib" $(saslLOGIN_objs) saslLOGIN.res +<< + IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2 + +saslSCRAM.dll: $(saslSCRAM_objs) saslSCRAM.res + $(LINK32DLL) @<< $(OPENSSL_LIBS) $(LINK32DLL_FLAGS) /out:"saslSCRAM.dll" /implib:"saslSCRAM.lib" $(saslSCRAM_objs) saslSCRAM.res +<< + IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2 + +saslNTLM.dll: $(saslNTLM_objs) saslNTLM.res + $(LINK32DLL) @<< $(OPENSSL_LIBS) $(LINK32DLL_FLAGS) /out:"saslNTLM.dll" /implib:"saslNTLM.lib" $(saslNTLM_objs) saslNTLM.res +<< + IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2 + +saslGSSAPI.dll: $(saslGSSAPI_objs) saslGSSAPI.res + $(LINK32DLL) @<< $(GSS_LIBS) $(LINK32DLL_FLAGS) /out:"saslGSSAPI.dll" /implib:"saslGSSAPI.lib" $(saslGSSAPI_objs) saslGSSAPI.res +<< + IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2 + +saslSRP.dll: $(saslSRP_objs) saslSRP.res + $(LINK32DLL) @<< $(OPENSSL_LIBS) $(LINK32DLL_FLAGS) /out:"saslSRP.dll" /implib:"saslSRP.lib" $(saslSRP_objs) saslSRP.res +<< + IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2 + +saslOTP.dll: $(saslOTP_objs) saslOTP.res + $(LINK32DLL) @<< $(OPENSSL_LIBS) $(LINK32DLL_FLAGS) /out:"saslOTP.dll" /implib:"saslOTP.lib" $(saslOTP_objs) saslOTP.res +<< + IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2 + +saslSASLDB.dll: $(saslSASLDB_objs) saslSASLDB.res + $(LINK32DLL) @<< $(DB_LIBS) $(LINK32DLL_FLAGS) /out:"saslSASLDB.dll" /implib:"saslSASLDB.lib" $(saslSASLDB_objs) saslSASLDB.res +<< + IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2 + +saslSQLITE.dll: $(saslSQL_objs) saslSQLITE.res + $(LINK32DLL) @<< $(SQLITE_LIBS) $(LINK32DLL_FLAGS) /out:"saslSQLITE.dll" /implib:"saslSQLITE.lib" $(saslSQL_objs) saslSQLITE.res +<< + IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2 + +saslLDAPDB.dll: $(saslLDAPDB_objs) saslLDAPDB.res + $(LINK32DLL) @<< $(LDAP_LIBS) $(OPENSSL_LIBS) $(LINK32DLL_FLAGS) /out:"saslLDAPDB.dll" /implib:"saslLDAPDB.lib" $(saslLDAPDB_objs) saslLDAPDB.res +<< + IF EXIST $@.manifest mt -manifest $@.manifest -outputresource:$@;2 + +CLEAN : + -@erase $(all_objs) + -@erase "*.idb" + -@erase "*.pdb" + -@erase "*.manifest" + -@erase getaddrinfo.c + -@erase allockey.c + -@erase db_berkeley.c + -@erase getnameinfo.c + -@erase $(generated_rc) + -@erase "*.res" + -@erase $(all_out) + +.c.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cpp.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.cxx.obj:: + $(CPP) @<< + $(CPP_PROJ) $< +<< + +.rc.res: + rc $< + +$(generated_rc): + copy < +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +/***************************** Common Section *****************************/ + +static const char plugin_id[] = "$Id: anonymous.c,v 1.53 2009/02/13 14:46:47 mel Exp $"; + +static const char anonymous_id[] = "anonymous"; + +/***************************** Server Section *****************************/ + +static int +anonymous_server_mech_new(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + void **conn_context) +{ + /* holds state are in */ + if (!conn_context) { + PARAMERROR( sparams->utils ); + return SASL_BADPARAM; + } + + *conn_context = NULL; + + return SASL_OK; +} + +static int +anonymous_server_mech_step(void *conn_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + char *clientdata; + int result; + + if (!sparams + || !serverout + || !serveroutlen + || !oparams) { + PARAMERROR( sparams->utils ); + return SASL_BADPARAM; + } + + *serverout = NULL; + *serveroutlen = 0; + + if (!clientin) { + return SASL_CONTINUE; + } + + /* We force a truncation 255 characters (specified by RFC 2245) */ + if (clientinlen > 255) clientinlen = 255; + + /* NULL-terminate the clientin... */ + clientdata = sparams->utils->malloc(clientinlen + 1); + if (!clientdata) { + MEMERROR(sparams->utils); + return SASL_NOMEM; + } + + strncpy(clientdata, clientin, clientinlen); + clientdata[clientinlen] = '\0'; + + sparams->utils->log(sparams->utils->conn, + SASL_LOG_NOTE, + "ANONYMOUS login: \"%s\"", + clientdata); + + if (clientdata != clientin) + sparams->utils->free(clientdata); + + result = sparams->canon_user(sparams->utils->conn, + anonymous_id, 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + + if (result != SASL_OK) return result; + + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + return SASL_OK; +} + +static sasl_server_plug_t anonymous_server_plugins[] = +{ + { + "ANONYMOUS", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOPLAINTEXT, /* security_flags */ + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_DONTUSE_USERPASSWD, /* features */ + NULL, /* glob_context */ + &anonymous_server_mech_new, /* mech_new */ + &anonymous_server_mech_step, /* mech_step */ + NULL, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* setpass */ + NULL, /* user_query */ + NULL, /* idle */ + NULL, /* mech_avail */ + NULL /* spare */ + } +}; + +int anonymous_server_plug_init(const sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_SERVER_PLUG_VERSION) { + SETERROR( utils, "ANONYMOUS version mismatch" ); + return SASL_BADVERS; + } + + *out_version = SASL_SERVER_PLUG_VERSION; + *pluglist = anonymous_server_plugins; + *plugcount = 1; + + return SASL_OK; +} + +/***************************** Client Section *****************************/ + +typedef struct client_context { + char *out_buf; + unsigned out_buf_len; +} client_context_t; + +static int +anonymous_client_mech_new(void *glob_context __attribute__((unused)), + sasl_client_params_t *cparams, + void **conn_context) +{ + client_context_t *text; + + if (!conn_context) { + PARAMERROR(cparams->utils); + return SASL_BADPARAM; + } + + /* holds state are in */ + text = cparams->utils->malloc(sizeof(client_context_t)); + if (text == NULL) { + MEMERROR(cparams->utils); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(client_context_t)); + + *conn_context = text; + + return SASL_OK; +} + +static int +anonymous_client_mech_step(void *conn_context, + sasl_client_params_t *cparams, + const char *serverin __attribute__((unused)), + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + client_context_t *text = (client_context_t *) conn_context; + size_t userlen; + char hostname[256]; + const char *user = NULL; + int user_result = SASL_OK; + int result; + + if (!cparams + || !clientout + || !clientoutlen + || !oparams) { + PARAMERROR( cparams->utils ); + return SASL_BADPARAM; + } + + *clientout = NULL; + *clientoutlen = 0; + + if (serverinlen != 0) { + SETERROR( cparams->utils, + "Nonzero serverinlen in ANONYMOUS continue_step" ); + return SASL_BADPROT; + } + + /* check if sec layer strong enough */ + if (cparams->props.min_ssf > cparams->external_ssf) { + SETERROR( cparams->utils, "SSF requested of ANONYMOUS plugin"); + return SASL_TOOWEAK; + } + + /* try to get the trace info */ + if (user == NULL) { + user_result = _plug_get_userid(cparams->utils, &user, prompt_need); + + if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) { + return user_result; + } + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + cparams->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if (user_result == SASL_INTERACT) { + /* make the prompt list */ + result = + _plug_make_prompts(cparams->utils, prompt_need, + user_result == SASL_INTERACT ? + "Please enter anonymous identification" : NULL, + "", + NULL, NULL, + NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); + if (result != SASL_OK) return result; + + return SASL_INTERACT; + } + + if (!user || !*user) { + user = anonymous_id; + } + userlen = strlen(user); + + result = cparams->canon_user(cparams->utils->conn, + anonymous_id, 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) return result; + + memset(hostname, 0, sizeof(hostname)); + gethostname(hostname, sizeof(hostname)); + hostname[sizeof(hostname)-1] = '\0'; + + *clientoutlen = (unsigned) (userlen + strlen(hostname) + 1); + + result = _plug_buf_alloc(cparams->utils, &text->out_buf, + &text->out_buf_len, *clientoutlen); + + if (result != SASL_OK) return result; + + strcpy(text->out_buf, user); + text->out_buf[userlen] = '@'; + /* use memcpy() instead of strcpy() so we don't add the NUL */ + memcpy(text->out_buf + userlen + 1, hostname, strlen(hostname)); + + *clientout = text->out_buf; + + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + return SASL_OK; +} + +static void anonymous_client_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + client_context_t *text = (client_context_t *) conn_context; + + if(!text) return; + + if (text->out_buf) utils->free(text->out_buf); + + utils->free(text); +} + +static const unsigned long anonymous_required_prompts[] = { + SASL_CB_LIST_END +}; + +static sasl_client_plug_t anonymous_client_plugins[] = +{ + { + "ANONYMOUS", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOPLAINTEXT, /* security_flags */ + SASL_FEAT_WANT_CLIENT_FIRST, /* features */ + anonymous_required_prompts, /* required_prompts */ + NULL, /* glob_context */ + &anonymous_client_mech_new, /* mech_new */ + &anonymous_client_mech_step, /* mech_step */ + &anonymous_client_dispose, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* idle */ + NULL, /* spare */ + NULL /* spare */ + } +}; + +int anonymous_client_plug_init(const sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_CLIENT_PLUG_VERSION) { + SETERROR( utils, "ANONYMOUS version mismatch" ); + return SASL_BADVERS; + } + + *out_version = SASL_CLIENT_PLUG_VERSION; + *pluglist = anonymous_client_plugins; + *plugcount = 1; + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/anonymous_init.c b/libs/cyrussasl/plugins/anonymous_init.c new file mode 100644 index 00000000..215cc20b --- /dev/null +++ b/libs/cyrussasl/plugins/anonymous_init.c @@ -0,0 +1,43 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_CLIENT_PLUG_INIT( anonymous ) +SASL_SERVER_PLUG_INIT( anonymous ) + diff --git a/libs/cyrussasl/plugins/cram.c b/libs/cyrussasl/plugins/cram.c new file mode 100644 index 00000000..8fe33cfb --- /dev/null +++ b/libs/cyrussasl/plugins/cram.c @@ -0,0 +1,689 @@ +/* CRAM-MD5 SASL plugin + * Rob Siemborski + * Tim Martin + * $Id: cram.c,v 1.87 2011/09/07 13:19:44 murch Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +/***************************** Common Section *****************************/ + +static const char plugin_id[] = "$Id: cram.c,v 1.87 2011/09/07 13:19:44 murch Exp $"; + +/* convert a string of 8bit chars to it's representation in hex + * using lowercase letters + */ +static char *convert16(unsigned char *in, int inlen, const sasl_utils_t *utils) +{ + static char hex[]="0123456789abcdef"; + int lup; + char *out; + + out = utils->malloc(inlen*2+1); + if (out == NULL) return NULL; + + for (lup=0; lup < inlen; lup++) { + out[lup*2] = hex[in[lup] >> 4]; + out[lup*2+1] = hex[in[lup] & 15]; + } + + out[lup*2] = 0; + return out; +} + + +/***************************** Server Section *****************************/ + +typedef struct server_context { + int state; + + char *challenge; +} server_context_t; + +static int +crammd5_server_mech_new(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + void **conn_context) +{ + server_context_t *text; + + /* holds state are in */ + text = sparams->utils->malloc(sizeof(server_context_t)); + if (text == NULL) { + MEMERROR( sparams->utils ); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(server_context_t)); + + text->state = 1; + + *conn_context = text; + + return SASL_OK; +} + +/* + * Returns the current time (or part of it) in string form + * maximum length=15 + */ +static char *gettime(sasl_server_params_t *sparams) +{ + char *ret; + time_t t; + + t=time(NULL); + ret= sparams->utils->malloc(15); + if (ret==NULL) return NULL; + + /* the bottom bits are really the only random ones so if + we overflow we don't want to loose them */ + snprintf(ret,15,"%lu",t%(0xFFFFFF)); + + return ret; +} + +static char *randomdigits(sasl_server_params_t *sparams) +{ + unsigned int num; + char *ret; + unsigned char temp[5]; /* random 32-bit number */ + + sparams->utils->rand(sparams->utils->rpool,(char *) temp,4); + num=(temp[0] * 256 * 256 * 256) + + (temp[1] * 256 * 256) + + (temp[2] * 256) + + (temp[3] ); + + ret = sparams->utils->malloc(15); /* there's no way an unsigned can be longer than this right? */ + if (ret == NULL) return NULL; + sprintf(ret, "%u", num); + + return ret; +} + +static int +crammd5_server_mech_step1(server_context_t *text, + sasl_server_params_t *sparams, + const char *clientin __attribute__((unused)), + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams __attribute__((unused))) +{ + char *time, *randdigits; + + /* we shouldn't have received anything */ + if (clientinlen != 0) { + SETERROR(sparams->utils, "CRAM-MD5 does not accept inital data"); + return SASL_BADPROT; + } + + /* get time and a random number for the nonce */ + time = gettime(sparams); + randdigits = randomdigits(sparams); + if ((time == NULL) || (randdigits == NULL)) { + MEMERROR( sparams->utils ); + return SASL_NOMEM; + } + + /* allocate some space for the challenge */ + text->challenge = sparams->utils->malloc(200 + 1); + if (text->challenge == NULL) { + MEMERROR(sparams->utils); + return SASL_NOMEM; + } + + /* create the challenge */ + snprintf(text->challenge, 200, "<%s.%s@%s>", randdigits, time, + sparams->serverFQDN); + + *serverout = text->challenge; + *serveroutlen = (unsigned) strlen(text->challenge); + + /* free stuff */ + sparams->utils->free(time); + sparams->utils->free(randdigits); + + text->state = 2; + + return SASL_CONTINUE; +} + +static int +crammd5_server_mech_step2(server_context_t *text, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout __attribute__((unused)), + unsigned *serveroutlen __attribute__((unused)), + sasl_out_params_t *oparams) +{ + char *userid = NULL; + sasl_secret_t *sec = NULL; + int pos; + size_t len; + int result = SASL_FAIL; + const char *password_request[] = { SASL_AUX_PASSWORD, +#if defined(OBSOLETE_CRAM_ATTR) + "*cmusaslsecretCRAM-MD5", +#endif + NULL }; + struct propval auxprop_values[3]; + HMAC_MD5_CTX tmphmac; + HMAC_MD5_STATE md5state; + int clear_md5state = 0; + char *digest_str = NULL; + UINT4 digest[4]; + + /* extract userid; everything before last space */ + pos = clientinlen-1; + while ((pos > 0) && (clientin[pos] != ' ')) pos--; + + if (pos <= 0) { + SETERROR( sparams->utils,"need authentication name"); + return SASL_BADPROT; + } + + userid = (char *) sparams->utils->malloc(pos+1); + if (userid == NULL) { + MEMERROR( sparams->utils); + return SASL_NOMEM; + } + + /* copy authstr out */ + memcpy(userid, clientin, pos); + userid[pos] = '\0'; + + result = sparams->utils->prop_request(sparams->propctx, password_request); + if (result != SASL_OK) goto done; + + /* this will trigger the getting of the aux properties */ + result = sparams->canon_user(sparams->utils->conn, + userid, 0, SASL_CU_AUTHID | SASL_CU_AUTHZID, + oparams); + if (result != SASL_OK) goto done; + + result = sparams->utils->prop_getnames(sparams->propctx, + password_request, + auxprop_values); + if (result < 0 || + ((!auxprop_values[0].name || !auxprop_values[0].values) +#if defined(OBSOLETE_CRAM_ATTR) + && (!auxprop_values[1].name || !auxprop_values[1].values) +#endif + )) { + /* We didn't find this username */ + sparams->utils->seterror(sparams->utils->conn,0, + "no secret in database"); + result = sparams->transition ? SASL_TRANS : SASL_NOUSER; + goto done; + } + + if (auxprop_values[0].name && auxprop_values[0].values) { + len = strlen(auxprop_values[0].values[0]); + if (len == 0) { + sparams->utils->seterror(sparams->utils->conn,0, + "empty secret"); + result = SASL_FAIL; + goto done; + } + + sec = sparams->utils->malloc(sizeof(sasl_secret_t) + len); + if (!sec) goto done; + + sec->len = (unsigned) len; + strncpy((char *)sec->data, auxprop_values[0].values[0], len + 1); + + clear_md5state = 1; + /* Do precalculation on plaintext secret */ + sparams->utils->hmac_md5_precalc(&md5state, /* OUT */ + sec->data, + sec->len); +#if defined(OBSOLETE_CRAM_ATTR) + } else if (auxprop_values[1].name && auxprop_values[1].values) { + /* We have a precomputed secret */ + memcpy(&md5state, auxprop_values[1].values[0], + sizeof(HMAC_MD5_STATE)); +#endif + } else { + sparams->utils->seterror(sparams->utils->conn, 0, + "Have neither type of secret"); + return SASL_FAIL; + } + + /* erase the plaintext password */ + sparams->utils->prop_erase(sparams->propctx, password_request[0]); + + /* ok this is annoying: + so we have this half-way hmac transform instead of the plaintext + that means we half to: + -import it back into a md5 context + -do an md5update with the nonce + -finalize it + */ + sparams->utils->hmac_md5_import(&tmphmac, (HMAC_MD5_STATE *) &md5state); + sparams->utils->MD5Update(&(tmphmac.ictx), + (const unsigned char *) text->challenge, + (unsigned) strlen(text->challenge)); + sparams->utils->hmac_md5_final((unsigned char *) &digest, &tmphmac); + + /* convert to base 16 with lower case letters */ + digest_str = convert16((unsigned char *) digest, 16, sparams->utils); + + /* if same then verified + * - we know digest_str is null terminated but clientin might not be + * - verify the length of clientin anyway! + */ + len = strlen(digest_str); + if (clientinlen-pos-1 < len || + strncmp(digest_str, clientin+pos+1, len) != 0) { + sparams->utils->seterror(sparams->utils->conn, 0, + "incorrect digest response"); + result = SASL_BADAUTH; + goto done; + } + + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + result = SASL_OK; + + done: + if (userid) sparams->utils->free(userid); + if (sec) _plug_free_secret(sparams->utils, &sec); + + if (digest_str) sparams->utils->free(digest_str); + if (clear_md5state) memset(&md5state, 0, sizeof(md5state)); + + return result; +} + +static int crammd5_server_mech_step(void *conn_context, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + server_context_t *text = (server_context_t *) conn_context; + + *serverout = NULL; + *serveroutlen = 0; + + if (text == NULL) { + return SASL_BADPROT; + } + + /* this should be well more than is ever needed */ + if (clientinlen > 1024) { + SETERROR(sparams->utils, "CRAM-MD5 input longer than 1024 bytes"); + return SASL_BADPROT; + } + + switch (text->state) { + + case 1: + return crammd5_server_mech_step1(text, sparams, + clientin, clientinlen, + serverout, serveroutlen, + oparams); + + case 2: + return crammd5_server_mech_step2(text, sparams, + clientin, clientinlen, + serverout, serveroutlen, + oparams); + + default: /* should never get here */ + sparams->utils->log(NULL, SASL_LOG_ERR, + "Invalid CRAM-MD5 server step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static void crammd5_server_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + server_context_t *text = (server_context_t *) conn_context; + + if (!text) return; + + if (text->challenge) _plug_free_string(utils,&(text->challenge)); + + utils->free(text); +} + +static sasl_server_plug_t crammd5_server_plugins[] = +{ + { + "CRAM-MD5", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS, /* security_flags */ + SASL_FEAT_SERVER_FIRST, /* features */ + NULL, /* glob_context */ + &crammd5_server_mech_new, /* mech_new */ + &crammd5_server_mech_step, /* mech_step */ + &crammd5_server_mech_dispose, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* setpass */ + NULL, /* user_query */ + NULL, /* idle */ + NULL, /* mech avail */ + NULL /* spare */ + } +}; + +int crammd5_server_plug_init(const sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_SERVER_PLUG_VERSION) { + SETERROR( utils, "CRAM version mismatch"); + return SASL_BADVERS; + } + + *out_version = SASL_SERVER_PLUG_VERSION; + *pluglist = crammd5_server_plugins; + *plugcount = 1; + + return SASL_OK; +} + +/***************************** Client Section *****************************/ + +typedef struct client_context { + char *out_buf; + unsigned out_buf_len; +} client_context_t; + +static int crammd5_client_mech_new(void *glob_context __attribute__((unused)), + sasl_client_params_t *params, + void **conn_context) +{ + client_context_t *text; + + /* holds state are in */ + text = params->utils->malloc(sizeof(client_context_t)); + if (text == NULL) { + MEMERROR(params->utils); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(client_context_t)); + + *conn_context = text; + + return SASL_OK; +} + +static char *make_hashed(sasl_secret_t *sec, char *nonce, int noncelen, + const sasl_utils_t *utils) +{ + unsigned char digest[24]; + char *in16; + + if (sec == NULL) return NULL; + + /* do the hmac md5 hash output 128 bits */ + utils->hmac_md5((unsigned char *) nonce, noncelen, + sec->data, sec->len, digest); + + /* convert that to hex form */ + in16 = convert16(digest, 16, utils); + if (in16 == NULL) return NULL; + + return in16; +} + +static int crammd5_client_mech_step(void *conn_context, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + client_context_t *text = (client_context_t *) conn_context; + const char *authid = NULL; + sasl_secret_t *password = NULL; + unsigned int free_password = 0; /* set if we need to free password */ + int auth_result = SASL_OK; + int pass_result = SASL_OK; + int result; + size_t maxsize; + char *in16 = NULL; + + *clientout = NULL; + *clientoutlen = 0; + + /* First check for absurd lengths */ + if (serverinlen > 1024) { + params->utils->seterror(params->utils->conn, 0, + "CRAM-MD5 input longer than 1024 bytes"); + return SASL_BADPROT; + } + + /* check if sec layer strong enough */ + if (params->props.min_ssf > params->external_ssf) { + SETERROR( params->utils, "SSF requested of CRAM-MD5 plugin"); + return SASL_TOOWEAK; + } + + /* try to get the userid */ + if (oparams->authid == NULL) { + auth_result=_plug_get_authid(params->utils, &authid, prompt_need); + + if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT)) + return auth_result; + } + + /* try to get the password */ + if (password == NULL) { + pass_result=_plug_get_password(params->utils, &password, + &free_password, prompt_need); + + if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT)) + return pass_result; + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + params->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if ((auth_result == SASL_INTERACT) || (pass_result == SASL_INTERACT)) { + /* make the prompt list */ + result = + _plug_make_prompts(params->utils, prompt_need, + NULL, NULL, + auth_result == SASL_INTERACT ? + "Please enter your authentication name" : NULL, + NULL, + pass_result == SASL_INTERACT ? + "Please enter your password" : NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); + if (result != SASL_OK) goto cleanup; + + return SASL_INTERACT; + } + + if (!password) { + PARAMERROR(params->utils); + return SASL_BADPARAM; + } + + result = params->canon_user(params->utils->conn, authid, 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) goto cleanup; + + /* + * username SP digest (keyed md5 where key is passwd) + */ + + in16 = make_hashed(password, (char *) serverin, serverinlen, + params->utils); + + if (in16 == NULL) { + SETERROR(params->utils, "whoops, make_hashed failed us this time"); + result = SASL_FAIL; + goto cleanup; + } + + maxsize = 32+1+strlen(oparams->authid)+30; + result = _plug_buf_alloc(params->utils, &(text->out_buf), + &(text->out_buf_len), (unsigned) maxsize); + if (result != SASL_OK) goto cleanup; + + snprintf(text->out_buf, maxsize, "%s %s", oparams->authid, in16); + + *clientout = text->out_buf; + *clientoutlen = (unsigned) strlen(*clientout); + + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + result = SASL_OK; + + cleanup: + /* get rid of private information */ + if (in16) _plug_free_string(params->utils, &in16); + + /* get rid of all sensitive info */ + if (free_password) _plug_free_secret(params-> utils, &password); + + return result; +} + +static void crammd5_client_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + client_context_t *text = (client_context_t *) conn_context; + + if (!text) return; + + if (text->out_buf) utils->free(text->out_buf); + + utils->free(text); +} + +static sasl_client_plug_t crammd5_client_plugins[] = +{ + { + "CRAM-MD5", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS, /* security_flags */ + SASL_FEAT_SERVER_FIRST, /* features */ + NULL, /* required_prompts */ + NULL, /* glob_context */ + &crammd5_client_mech_new, /* mech_new */ + &crammd5_client_mech_step, /* mech_step */ + &crammd5_client_mech_dispose, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* idle */ + NULL, /* spare */ + NULL /* spare */ + } +}; + +int crammd5_client_plug_init(const sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_CLIENT_PLUG_VERSION) { + SETERROR( utils, "CRAM version mismatch"); + return SASL_BADVERS; + } + + *out_version = SASL_CLIENT_PLUG_VERSION; + *pluglist = crammd5_client_plugins; + *plugcount = 1; + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/crammd5_init.c b/libs/cyrussasl/plugins/crammd5_init.c new file mode 100644 index 00000000..c5382f81 --- /dev/null +++ b/libs/cyrussasl/plugins/crammd5_init.c @@ -0,0 +1,43 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_CLIENT_PLUG_INIT( crammd5 ) +SASL_SERVER_PLUG_INIT( crammd5 ) + diff --git a/libs/cyrussasl/plugins/digestmd5.c b/libs/cyrussasl/plugins/digestmd5.c new file mode 100644 index 00000000..4ab90dd2 --- /dev/null +++ b/libs/cyrussasl/plugins/digestmd5.c @@ -0,0 +1,4655 @@ +/* DIGEST-MD5 SASL plugin + * Ken Murchison + * Rob Siemborski + * Tim Martin + * Alexey Melnikov + * $Id: digestmd5.c,v 1.205 2011/05/13 19:18:37 murch Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#include +#endif +#include +#include + +/* DES support */ +#ifdef WITH_DES +# ifdef WITH_SSL_DES +# include +# include +# if (OPENSSL_VERSION_NUMBER >= 0x0090700f) && \ + !defined(OPENSSL_ENABLE_OLD_DES_SUPPORT) +# define des_cblock DES_cblock +# define des_key_schedule DES_key_schedule +# define des_key_sched(k,ks) \ + DES_key_sched((k),&(ks)) +# define des_cbc_encrypt(i,o,l,k,iv,e) \ + DES_cbc_encrypt((i),(o),(l),&(k),(iv),(e)) +# define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + DES_ede2_cbc_encrypt((i),(o),(l),&(k1),&(k2),(iv),(e)) +# endif /* OpenSSL 0.9.7+ w/o old DES support */ +# else /* system DES library */ +#ifdef HAVE_DES_H +# include +#endif +# endif +#endif /* WITH_DES */ + +#ifdef WIN32 +# include +#else /* Unix */ +# include +#endif /* WIN32 */ + +#include +#include + +#include "plugin_common.h" + +#ifndef WIN32 +extern int strcasecmp(const char *s1, const char *s2); +#endif /* end WIN32 */ + +#ifdef macintosh +#include +#endif + +/* external definitions */ + +#ifdef sun +/* gotta define gethostname ourselves on suns */ +extern int gethostname(char *, int); +#endif + +#define bool int + +#ifndef TRUE +#define TRUE (1) +#define FALSE (0) +#endif + +/* MAX_UIN32_DIV_10 * 10 + MAX_UIN32_MOD_10 == 2^32-1 == 4294967295 */ +#define MAX_UIN32_DIV_10 429496729 +#define MAX_UIN32_MOD_10 5 + +#define DEFAULT_BUFSIZE 0xFFFF +#define MAX_SASL_BUFSIZE 0xFFFFFF + +/***************************** Common Section *****************************/ + +static const char plugin_id[] = "$Id: digestmd5.c,v 1.205 2011/05/13 19:18:37 murch Exp $"; + +/* Definitions */ +#define NONCE_SIZE (32) /* arbitrary */ + +/* Layer Flags */ +#define DIGEST_NOLAYER (1) +#define DIGEST_INTEGRITY (2) +#define DIGEST_PRIVACY (4) + +/* defines */ +#define HASHLEN 16 +typedef unsigned char HASH[HASHLEN + 1]; +#define HASHHEXLEN 32 +typedef unsigned char HASHHEX[HASHHEXLEN + 1]; + +#define MAC_SIZE 10 +#define MAC_OFFS 2 + +const char *SEALING_CLIENT_SERVER="Digest H(A1) to client-to-server sealing key magic constant"; +const char *SEALING_SERVER_CLIENT="Digest H(A1) to server-to-client sealing key magic constant"; + +const char *SIGNING_CLIENT_SERVER="Digest session key to client-to-server signing key magic constant"; +const char *SIGNING_SERVER_CLIENT="Digest session key to server-to-client signing key magic constant"; + +#define HT (9) +#define CR (13) +#define LF (10) +#define SP (32) +#define DEL (127) + +#define NEED_ESCAPING "\"\\" + +#define REALM_CHAL_PREFIX "Available realms:" + +static char *quote (char *str); + +struct context; + +/* function definitions for cipher encode/decode */ +typedef int cipher_function_t(struct context *, + const char *, + unsigned, + unsigned char[], + char *, + unsigned *); + +typedef int cipher_init_t(struct context *, unsigned char [16], + unsigned char [16]); +typedef void cipher_free_t(struct context *); + +enum Context_type { SERVER = 0, CLIENT = 1 }; + +typedef struct cipher_context cipher_context_t; + +/* cached auth info used for fast reauth */ +typedef struct reauth_entry { + char *authid; + char *realm; + unsigned char *nonce; + unsigned int nonce_count; + unsigned char *cnonce; + + union { + struct { + time_t timestamp; + } s; /* server stuff */ + + struct { + char *serverFQDN; + int protection; + struct digest_cipher *cipher; + unsigned long server_maxbuf; + + /* for HTTP mode (RFC 2617) only */ + char *algorithm; + unsigned char *opaque; + } c; /* client stuff */ + } u; +} reauth_entry_t; + +typedef struct reauth_cache { + /* static stuff */ + enum Context_type i_am; /* are we the client or server? */ + time_t timeout; + void *mutex; + unsigned size; + + reauth_entry_t *e; /* fixed-size hash table of entries */ +} reauth_cache_t; + +/* global context for reauth use */ +typedef struct digest_glob_context { + reauth_cache_t *reauth; +} digest_glob_context_t; + +/* context that stores info */ +typedef struct context { + int state; /* state in the authentication we are in */ + enum Context_type i_am; /* are we the client or server? */ + int http_mode; /* use RFC 2617 compatible protocol? */ + + reauth_cache_t *reauth; + + char *authid; + char *realm; + unsigned char *nonce; + unsigned int nonce_count; + unsigned char *cnonce; + + /* only used by the client */ + char ** realms; + int realm_cnt; + + char *response_value; + + unsigned int seqnum; + unsigned int rec_seqnum; /* for checking integrity */ + + HASH Ki_send; + HASH Ki_receive; + + HASH HA1; /* Kcc or Kcs */ + + /* copy of utils from the params structures */ + const sasl_utils_t *utils; + + /* For general use */ + char *out_buf; + unsigned out_buf_len; + + /* for encoding/decoding */ + buffer_info_t *enc_in_buf; + char *encode_buf, *decode_buf, *decode_packet_buf; + unsigned encode_buf_len, decode_buf_len, decode_packet_buf_len; + + decode_context_t decode_context; + + /* if privacy mode is used use these functions for encode and decode */ + cipher_function_t *cipher_enc; + cipher_function_t *cipher_dec; + cipher_init_t *cipher_init; + cipher_free_t *cipher_free; + struct cipher_context *cipher_enc_context; + struct cipher_context *cipher_dec_context; +} context_t; + +struct digest_cipher { + char *name; + sasl_ssf_t ssf; + int n; /* bits to make privacy key */ + int flag; /* a bitmask to make things easier for us */ + + cipher_function_t *cipher_enc; + cipher_function_t *cipher_dec; + cipher_init_t *cipher_init; + cipher_free_t *cipher_free; +}; +#if 0 +static const unsigned char *COLON = ":"; +#else +static const unsigned char COLON[] = { ':', '\0' }; +#endif +/* Hashes a string to produce an unsigned short */ +static unsigned hash(const char *str) +{ + unsigned val = 0; + int i; + + while (str && *str) { + i = (int) *str; + val ^= i; + val <<= 1; + str++; + } + + return val; +} + +static void CvtHex(HASH Bin, HASHHEX Hex) +{ + unsigned short i; + unsigned char j; + + for (i = 0; i < HASHLEN; i++) { + j = (Bin[i] >> 4) & 0xf; + if (j <= 9) + Hex[i * 2] = (j + '0'); + else + Hex[i * 2] = (j + 'a' - 10); + j = Bin[i] & 0xf; + if (j <= 9) + Hex[i * 2 + 1] = (j + '0'); + else + Hex[i * 2 + 1] = (j + 'a' - 10); + } + Hex[HASHHEXLEN] = '\0'; +} + +/* + * calculate request-digest/response-digest as per HTTP Digest spec + */ +void +DigestCalcResponse(const sasl_utils_t * utils, + HASHHEX HA1, /* HEX(H(A1)) */ + unsigned char *pszNonce, /* nonce from server */ + unsigned int pszNonceCount, /* 8 hex digits */ + unsigned char *pszCNonce, /* client nonce */ + unsigned char *pszQop, /* qop-value: "", "auth", + * "auth-int" */ + unsigned char *pszDigestUri, /* requested URL */ + unsigned char *pszMethod, + HASHHEX HEntity, /* H(entity body) if qop="auth-int" */ + HASHHEX Response /* request-digest or response-digest */ + ) +{ + MD5_CTX Md5Ctx; + HASH HA2; + HASH RespHash; + HASHHEX HA2Hex; + unsigned char ncvalue[10]; + + /* calculate H(A2) */ + utils->MD5Init(&Md5Ctx); + + if (pszMethod != NULL) { + utils->MD5Update(&Md5Ctx, pszMethod, (unsigned) strlen((char *) pszMethod)); + } + utils->MD5Update(&Md5Ctx, (unsigned char *) COLON, 1); + + /* utils->MD5Update(&Md5Ctx, (unsigned char *) "AUTHENTICATE:", 13); */ + utils->MD5Update(&Md5Ctx, pszDigestUri, (unsigned) strlen((char *) pszDigestUri)); + if (strcasecmp((char *) pszQop, "auth") != 0) { + /* append ":00000000000000000000000000000000" */ + utils->MD5Update(&Md5Ctx, COLON, 1); + utils->MD5Update(&Md5Ctx, HEntity, HASHHEXLEN); + } + utils->MD5Final(HA2, &Md5Ctx); + CvtHex(HA2, HA2Hex); + + /* calculate response */ + utils->MD5Init(&Md5Ctx); + utils->MD5Update(&Md5Ctx, HA1, HASHHEXLEN); + utils->MD5Update(&Md5Ctx, COLON, 1); + utils->MD5Update(&Md5Ctx, pszNonce, (unsigned) strlen((char *) pszNonce)); + utils->MD5Update(&Md5Ctx, COLON, 1); + if (*pszQop) { + sprintf((char *)ncvalue, "%08x", pszNonceCount); + utils->MD5Update(&Md5Ctx, ncvalue, (unsigned) strlen((char *)ncvalue)); + utils->MD5Update(&Md5Ctx, COLON, 1); + utils->MD5Update(&Md5Ctx, pszCNonce, (unsigned) strlen((char *) pszCNonce)); + utils->MD5Update(&Md5Ctx, COLON, 1); + utils->MD5Update(&Md5Ctx, pszQop, (unsigned) strlen((char *) pszQop)); + utils->MD5Update(&Md5Ctx, COLON, 1); + } + utils->MD5Update(&Md5Ctx, HA2Hex, HASHHEXLEN); + utils->MD5Final(RespHash, &Md5Ctx); + CvtHex(RespHash, Response); +} + +static bool UTF8_In_8859_1(const unsigned char *base, size_t len) +{ + const unsigned char *scan, *end; + + end = base + len; + for (scan = base; scan < end; ++scan) { + if (*scan > 0xC3) + break; /* abort if outside 8859-1 */ + if (*scan >= 0xC0 && *scan <= 0xC3) { + if (++scan == end || *scan < 0x80 || *scan > 0xBF) + break; + } + } + + /* if scan >= end, then this is a 8859-1 string. */ + return (scan >= end); +} + +/* + * if the string is entirely in the 8859-1 subset of UTF-8, then translate to + * 8859-1 prior to MD5 + */ +static void MD5_UTF8_8859_1(const sasl_utils_t * utils, + MD5_CTX * ctx, + bool In_ISO_8859_1, + const unsigned char *base, + int len) +{ + const unsigned char *scan, *end; + unsigned char cbuf; + + end = base + len; + + /* if we found a character outside 8859-1, don't alter string */ + if (!In_ISO_8859_1) { + utils->MD5Update(ctx, base, len); + return; + } + /* convert to 8859-1 prior to applying hash */ + do { + for (scan = base; scan < end && *scan < 0xC0; ++scan); + if (scan != base) + utils->MD5Update(ctx, base, (unsigned) (scan - base)); + if (scan + 1 >= end) + break; + cbuf = ((scan[0] & 0x3) << 6) | (scan[1] & 0x3f); + utils->MD5Update(ctx, &cbuf, 1); + base = scan + 2; + } + while (base < end); +} + +/** + * Returns true if it mangled the username. + */ +static bool DigestCalcSecret(const sasl_utils_t * utils, + unsigned char *pszUserName, + unsigned char *pszRealm, + unsigned char *Password, + int PasswordLen, + bool Ignore_8859, + HASH HA1) +{ + bool In_8859_1; + bool Any_8859_1 = FALSE; + MD5_CTX Md5Ctx; + + /* Chris Newman clarified that the following text in DIGEST-MD5 spec + is bogus: "if name and password are both in ISO 8859-1 charset" + We shoud use code example instead */ + + utils->MD5Init(&Md5Ctx); + + /* We have to convert UTF-8 to ISO-8859-1 if possible */ + if (Ignore_8859 == FALSE) { + In_8859_1 = UTF8_In_8859_1(pszUserName, strlen((char *) pszUserName)); + MD5_UTF8_8859_1(utils, &Md5Ctx, In_8859_1, + pszUserName, (unsigned) strlen((char *) pszUserName)); + Any_8859_1 |= In_8859_1; + } else { + utils->MD5Update(&Md5Ctx, pszUserName, (unsigned) strlen((char *) pszUserName)); + } + + utils->MD5Update(&Md5Ctx, COLON, 1); + + /* a NULL realm is equivalent to the empty string */ + if (pszRealm != NULL && pszRealm[0] != '\0') { + if (Ignore_8859 == FALSE) { + /* We have to convert UTF-8 to ISO-8859-1 if possible */ + In_8859_1 = UTF8_In_8859_1(pszRealm, strlen((char *) pszRealm)); + MD5_UTF8_8859_1(utils, &Md5Ctx, In_8859_1, + pszRealm, (unsigned) strlen((char *) pszRealm)); + Any_8859_1 |= In_8859_1; + } else { + utils->MD5Update(&Md5Ctx, pszRealm, (unsigned) strlen((char *) pszRealm)); + } + } + + utils->MD5Update(&Md5Ctx, COLON, 1); + + if (Ignore_8859 == FALSE) { + /* We have to convert UTF-8 to ISO-8859-1 if possible */ + In_8859_1 = UTF8_In_8859_1(Password, PasswordLen); + MD5_UTF8_8859_1(utils, &Md5Ctx, In_8859_1, + Password, PasswordLen); + Any_8859_1 |= In_8859_1; + } else { + utils->MD5Update(&Md5Ctx, Password, PasswordLen); + } + utils->MD5Final(HA1, &Md5Ctx); + + return Any_8859_1; +} + +static unsigned char *create_nonce(const sasl_utils_t * utils) +{ + unsigned char *base64buf; + int base64len; + + char *ret = (char *) utils->malloc(NONCE_SIZE); + if (ret == NULL) + return NULL; + + utils->rand(utils->rpool, (char *) ret, NONCE_SIZE); + + /* base 64 encode it so it has valid chars */ + base64len = (NONCE_SIZE * 4 / 3) + (NONCE_SIZE % 3 ? 4 : 0); + + base64buf = (unsigned char *) utils->malloc(base64len + 1); + if (base64buf == NULL) { + utils->seterror(utils->conn, 0, "Unable to allocate final buffer"); + return NULL; + } + + /* + * Returns SASL_OK on success, SASL_BUFOVER if result won't fit + */ + if (utils->encode64(ret, NONCE_SIZE, + (char *) base64buf, base64len, NULL) != SASL_OK) { + utils->free(ret); + return NULL; + } + utils->free(ret); + + return base64buf; +} + +static int add_to_challenge(const sasl_utils_t *utils, + char **str, unsigned *buflen, unsigned *curlen, + char *name, + unsigned char *value, + bool need_quotes) +{ + size_t namesize = strlen(name); + size_t valuesize = strlen((char *) value); + unsigned newlen; + int ret; + + newlen = (unsigned) (*curlen + 1 + namesize + 2 + valuesize + 2); + ret = _plug_buf_alloc(utils, str, buflen, newlen); + if(ret != SASL_OK) return ret; + + if (*curlen > 0) { + strcat(*str, ","); + strcat(*str, name); + } else { + strcpy(*str, name); + } + + if (need_quotes) { + strcat(*str, "=\""); + + /* Check if the value needs quoting */ + if (strpbrk ((char *)value, NEED_ESCAPING) != NULL) { + char * quoted = quote ((char *) value); + valuesize = strlen(quoted); + /* As the quoted string is bigger, make sure we have enough + space now */ + ret = _plug_buf_alloc(utils, str, buflen, newlen); + if (ret == SASL_OK) { + strcat(*str, quoted); + free (quoted); + } else { + free (quoted); + return ret; + } + } else { + strcat(*str, (char *) value); + } + strcat(*str, "\""); + } else { + strcat(*str, "="); + strcat(*str, (char *) value); + } + + *curlen = newlen; + return SASL_OK; +} + +static int is_lws_char (char c) +{ + return (c == ' ' || c == HT || c == CR || c == LF); +} + +static char *skip_lws (char *s) +{ + if (!s) return NULL; + + /* skipping spaces: */ + while (is_lws_char(s[0])) { + if (s[0] == '\0') break; + s++; + } + + return s; +} + +/* Same as skip_lws, but do this right to left */ +/* skip LWSP at the end of the value (if any), skip_r_lws returns pointer to + the first LWSP character, NUL (if there were none) or NULL if the value + is entirely from LWSP characters */ +static char *skip_r_lws (char *s) +{ + char *end; + size_t len; + + if (!s) return NULL; + + len = strlen(s); + if (len == 0) return NULL; + + /* the last character before terminating NUL */ + end = s + len - 1; + + /* skipping spaces: */ + while (end > s && (end[0] == ' ' || end[0] == HT || end[0] == CR || end[0] == LF)) { + end--; + } + + /* If all string from spaces, return NULL */ + if (end == s && (end[0] == ' ' || end[0] == HT || end[0] == CR || end[0] == LF)) { + return NULL; + } else { + return (end + 1); + } +} + +static char *skip_token (char *s, int caseinsensitive) +{ + if(!s) return NULL; + + while (s[0]>SP) { + if (s[0]==DEL || s[0]=='(' || s[0]==')' || s[0]=='<' || s[0]=='>' || + s[0]=='@' || s[0]==',' || s[0]==';' || s[0]==':' || s[0]=='\\' || + s[0]=='\'' || s[0]=='/' || s[0]=='[' || s[0]==']' || s[0]== '?' || + s[0]=='=' || s[0]== '{' || s[0]== '}') { + if (caseinsensitive == 1) { + if (!isupper((unsigned char) s[0])) + break; + } else { + break; + } + } + s++; + } + return s; +} + +/* Convert a string to 32 bit unsigned integer. + Any number of trailing spaces is allowed, but not a string + entirely comprised of spaces */ +static bool str2ul32 (char *str, unsigned long * value) +{ + unsigned int n; + char c; + + if (str == NULL) { + return (FALSE); + } + + *value = 0; + + str = skip_lws (str); + if (str[0] == '\0') { + return (FALSE); + } + + n = 0; + while (str[0] != '\0') { + c = str[0]; + if (!isdigit((int)c)) { + return (FALSE); + } + +/* Will overflow after adding additional digit */ + if (n > MAX_UIN32_DIV_10) { + return (FALSE); + } else if (n == MAX_UIN32_DIV_10 && ((unsigned) (c - '0') > MAX_UIN32_MOD_10)) { + return (FALSE); + } + + n = n * 10 + (unsigned) (c - '0'); + str++; + } + + *value = n; + return (TRUE); +} + +/* NULL - error (unbalanced quotes), + otherwise pointer to the first character after the value. + The function performs work in place. */ +static char *unquote (char *qstr) +{ + char *endvalue; + int escaped = 0; + char *outptr; + + if(!qstr) return NULL; + + if (qstr[0] == '"') { + qstr++; + outptr = qstr; + + for (endvalue = qstr; endvalue[0] != '\0'; endvalue++, outptr++) { + if (escaped) { + outptr[0] = endvalue[0]; + escaped = 0; + } + else if (endvalue[0] == '\\') { + escaped = 1; + outptr--; /* Will be incremented at the end of the loop */ + } + else if (endvalue[0] == '"') { + break; + } + else { + outptr[0] = endvalue[0]; + } + } + + if (endvalue[0] != '"') { + return NULL; + } + + while (outptr <= endvalue) { + outptr[0] = '\0'; + outptr++; + } + endvalue++; + } + else { /* not qouted value (token) */ + /* qstr already contains output */ + endvalue = skip_token(qstr,0); + }; + + return endvalue; +} + +/* Unlike unquote, this function returns an allocated quoted copy */ +static char *quote (char *str) +{ + char *p; + char *outp; + char *result; + int num_to_escape; /* How many characters need escaping */ + + if (!str) return NULL; + + num_to_escape = 0; + p = strpbrk (str, NEED_ESCAPING); + while (p != NULL) { + num_to_escape++; + p = strpbrk (p + 1, NEED_ESCAPING); + } + + if (num_to_escape == 0) { + return (strdup (str)); + } + + result = malloc (strlen(str) + num_to_escape + 1); + for (p = str, outp = result; *p; p++) { + if (*p == '"' || *p == '\\') { + *outp = '\\'; + outp++; + } + *outp = *p; + outp++; + } + + *outp = '\0'; + + return (result); +} + +static void get_pair(char **in, char **name, char **value) +{ + char *endpair; + char *curp = *in; + *name = NULL; + *value = NULL; + + if (curp == NULL) return; + + while (curp[0] != '\0') { + /* skipping spaces: */ + curp = skip_lws(curp); + + /* 'LWS "," LWS "," ...' is allowed by the DIGEST-MD5 ABNF */ + if (curp[0] == ',') { + curp++; + } else { + break; + } + } + + if (curp[0] == '\0') { + /* End of the string is not an error */ + *name = ""; + return; + } + + *name = curp; + + curp = skip_token(curp,1); + + /* strip wierd chars */ + if (curp[0] != '=' && curp[0] != '\0') { + *curp++ = '\0'; + }; + + curp = skip_lws(curp); + + if (curp[0] != '=') { /* No '=' sign */ + *name = NULL; + return; + } + + curp[0] = '\0'; + curp++; + + curp = skip_lws(curp); + + *value = (curp[0] == '"') ? curp+1 : curp; + + endpair = unquote (curp); + if (endpair == NULL) { /* Unbalanced quotes */ + *name = NULL; + *value = NULL; + return; + } + + /* An optional LWS is allowed after the value. Skip it. */ + if (is_lws_char (endpair[0])) { + /* Remove the trailing LWS from the value */ + *endpair++ = '\0'; + endpair = skip_lws(endpair); + } + + /* syntax check: MUST be '\0' or ',' */ + if (endpair[0] == ',') { + endpair[0] = '\0'; + endpair++; /* skipping <,> */ + } else if (endpair[0] != '\0') { + *name = NULL; + *value = NULL; + return; + } + + *in = endpair; +} + +#ifdef WITH_DES +struct des_context_s { + des_key_schedule keysched; /* key schedule for des initialization */ + des_cblock ivec; /* initial vector for encoding */ + des_key_schedule keysched2; /* key schedule for 3des initialization */ +}; + +typedef struct des_context_s des_context_t; + +/* slide the first 7 bytes of 'inbuf' into the high seven bits of the + first 8 bytes of 'keybuf'. 'keybuf' better be 8 bytes long or longer. */ +static void slidebits(unsigned char *keybuf, unsigned char *inbuf) +{ + keybuf[0] = inbuf[0]; + keybuf[1] = (inbuf[0]<<7) | (inbuf[1]>>1); + keybuf[2] = (inbuf[1]<<6) | (inbuf[2]>>2); + keybuf[3] = (inbuf[2]<<5) | (inbuf[3]>>3); + keybuf[4] = (inbuf[3]<<4) | (inbuf[4]>>4); + keybuf[5] = (inbuf[4]<<3) | (inbuf[5]>>5); + keybuf[6] = (inbuf[5]<<2) | (inbuf[6]>>6); + keybuf[7] = (inbuf[6]<<1); +} + +/****************************** + * + * 3DES functions + * + *****************************/ + +static int dec_3des(context_t *text, + const char *input, + unsigned inputlen, + unsigned char digest[16] __attribute__((unused)), + char *output, + unsigned *outputlen) +{ + des_context_t *c = (des_context_t *) text->cipher_dec_context; + int padding, p; + + des_ede2_cbc_encrypt((void *) input, + (void *) output, + inputlen, + c->keysched, + c->keysched2, + &c->ivec, + DES_DECRYPT); + + /* now chop off the padding */ + padding = output[inputlen - 11]; + if (padding < 1 || padding > 8) { + /* invalid padding length */ + return SASL_FAIL; + } + /* verify all padding is correct */ + for (p = 1; p <= padding; p++) { + if (output[inputlen - 10 - p] != padding) { + return SASL_FAIL; + } + } + + /* chop off the padding */ + *outputlen = inputlen - padding - 10; + + return SASL_OK; +} + +static int enc_3des(context_t *text, + const char *input, + unsigned inputlen, + unsigned char digest[16], + char *output, + unsigned *outputlen) +{ + des_context_t *c = (des_context_t *) text->cipher_enc_context; + int len; + int paddinglen; + + /* determine padding length */ + paddinglen = 8 - ((inputlen + 10) % 8); + + /* now construct the full stuff to be ciphered */ + memcpy(output, input, inputlen); /* text */ + memset(output+inputlen, paddinglen, paddinglen);/* pad */ + memcpy(output+inputlen+paddinglen, digest, 10); /* hmac */ + + len=inputlen+paddinglen+10; + + des_ede2_cbc_encrypt((void *) output, + (void *) output, + len, + c->keysched, + c->keysched2, + &c->ivec, + DES_ENCRYPT); + + *outputlen=len; + + return SASL_OK; +} + +static int init_3des(context_t *text, + unsigned char enckey[16], + unsigned char deckey[16]) +{ + des_context_t *c; + unsigned char keybuf[8]; + + /* allocate enc & dec context */ + c = (des_context_t *) text->utils->malloc(2 * sizeof(des_context_t)); + if (c == NULL) return SASL_NOMEM; + + /* setup enc context */ + slidebits(keybuf, enckey); + if (des_key_sched((des_cblock *) keybuf, c->keysched) < 0) + return SASL_FAIL; + + slidebits(keybuf, enckey + 7); + if (des_key_sched((des_cblock *) keybuf, c->keysched2) < 0) + return SASL_FAIL; + memcpy(c->ivec, ((char *) enckey) + 8, 8); + + text->cipher_enc_context = (cipher_context_t *) c; + + /* setup dec context */ + c++; + slidebits(keybuf, deckey); + if (des_key_sched((des_cblock *) keybuf, c->keysched) < 0) + return SASL_FAIL; + + slidebits(keybuf, deckey + 7); + if (des_key_sched((des_cblock *) keybuf, c->keysched2) < 0) + return SASL_FAIL; + + memcpy(c->ivec, ((char *) deckey) + 8, 8); + + text->cipher_dec_context = (cipher_context_t *) c; + + return SASL_OK; +} + + +/****************************** + * + * DES functions + * + *****************************/ + +static int dec_des(context_t *text, + const char *input, + unsigned inputlen, + unsigned char digest[16] __attribute__((unused)), + char *output, + unsigned *outputlen) +{ + des_context_t *c = (des_context_t *) text->cipher_dec_context; + int p, padding = 0; + + des_cbc_encrypt((void *) input, + (void *) output, + inputlen, + c->keysched, + &c->ivec, + DES_DECRYPT); + + /* Update the ivec (des_cbc_encrypt implementations tend to be broken in + this way) */ + memcpy(c->ivec, input + (inputlen - 8), 8); + + /* now chop off the padding */ + padding = output[inputlen - 11]; + if (padding < 1 || padding > 8) { + /* invalid padding length */ + return SASL_FAIL; + } + /* verify all padding is correct */ + for (p = 1; p <= padding; p++) { + if (output[inputlen - 10 - p] != padding) { + return SASL_FAIL; + } + } + + /* chop off the padding */ + *outputlen = inputlen - padding - 10; + + return SASL_OK; +} + +static int enc_des(context_t *text, + const char *input, + unsigned inputlen, + unsigned char digest[16], + char *output, + unsigned *outputlen) +{ + des_context_t *c = (des_context_t *) text->cipher_enc_context; + int len; + int paddinglen; + + /* determine padding length */ + paddinglen = 8 - ((inputlen+10) % 8); + + /* now construct the full stuff to be ciphered */ + memcpy(output, input, inputlen); /* text */ + memset(output+inputlen, paddinglen, paddinglen);/* pad */ + memcpy(output+inputlen+paddinglen, digest, 10); /* hmac */ + + len = inputlen + paddinglen + 10; + + des_cbc_encrypt((void *) output, + (void *) output, + len, + c->keysched, + &c->ivec, + DES_ENCRYPT); + + /* Update the ivec (des_cbc_encrypt implementations tend to be broken in + this way) */ + memcpy(c->ivec, output + (len - 8), 8); + + *outputlen = len; + + return SASL_OK; +} + +static int init_des(context_t *text, + unsigned char enckey[16], + unsigned char deckey[16]) +{ + des_context_t *c; + unsigned char keybuf[8]; + + /* allocate enc context */ + c = (des_context_t *) text->utils->malloc(2 * sizeof(des_context_t)); + if (c == NULL) return SASL_NOMEM; + + /* setup enc context */ + slidebits(keybuf, enckey); + des_key_sched((des_cblock *) keybuf, c->keysched); + + memcpy(c->ivec, ((char *) enckey) + 8, 8); + + text->cipher_enc_context = (cipher_context_t *) c; + + /* setup dec context */ + c++; + slidebits(keybuf, deckey); + des_key_sched((des_cblock *) keybuf, c->keysched); + + memcpy(c->ivec, ((char *) deckey) + 8, 8); + + text->cipher_dec_context = (cipher_context_t *) c; + + return SASL_OK; +} + +static void free_des(context_t *text) +{ + /* free des contextss. only cipher_enc_context needs to be free'd, + since cipher_dec_context was allocated at the same time. */ + if (text->cipher_enc_context) text->utils->free(text->cipher_enc_context); +} + +#endif /* WITH_DES */ + +#ifdef WITH_RC4 +/* quick generic implementation of RC4 */ +struct rc4_context_s { + unsigned char sbox[256]; + int i, j; +}; + +typedef struct rc4_context_s rc4_context_t; + +static void rc4_init(rc4_context_t *text, + const unsigned char *key, + unsigned keylen) +{ + int i, j; + + /* fill in linearly s0=0 s1=1... */ + for (i=0;i<256;i++) + text->sbox[i]=i; + + j=0; + for (i = 0; i < 256; i++) { + unsigned char tmp; + /* j = (j + Si + Ki) mod 256 */ + j = (j + text->sbox[i] + key[i % keylen]) % 256; + + /* swap Si and Sj */ + tmp = text->sbox[i]; + text->sbox[i] = text->sbox[j]; + text->sbox[j] = tmp; + } + + /* counters initialized to 0 */ + text->i = 0; + text->j = 0; +} + +static void rc4_encrypt(rc4_context_t *text, + const char *input, + char *output, + unsigned len) +{ + int tmp; + int i = text->i; + int j = text->j; + int t; + int K; + const char *input_end = input + len; + + while (input < input_end) { + i = (i + 1) % 256; + + j = (j + text->sbox[i]) % 256; + + /* swap Si and Sj */ + tmp = text->sbox[i]; + text->sbox[i] = text->sbox[j]; + text->sbox[j] = tmp; + + t = (text->sbox[i] + text->sbox[j]) % 256; + + K = text->sbox[t]; + + /* byte K is Xor'ed with plaintext */ + *output++ = *input++ ^ K; + } + + text->i = i; + text->j = j; +} + +static void rc4_decrypt(rc4_context_t *text, + const char *input, + char *output, + unsigned len) +{ + int tmp; + int i = text->i; + int j = text->j; + int t; + int K; + const char *input_end = input + len; + + while (input < input_end) { + i = (i + 1) % 256; + + j = (j + text->sbox[i]) % 256; + + /* swap Si and Sj */ + tmp = text->sbox[i]; + text->sbox[i] = text->sbox[j]; + text->sbox[j] = tmp; + + t = (text->sbox[i] + text->sbox[j]) % 256; + + K = text->sbox[t]; + + /* byte K is Xor'ed with plaintext */ + *output++ = *input++ ^ K; + } + + text->i = i; + text->j = j; +} + +static void free_rc4(context_t *text) +{ + /* free rc4 context structures */ + + if(text->cipher_enc_context) text->utils->free(text->cipher_enc_context); + if(text->cipher_dec_context) text->utils->free(text->cipher_dec_context); +} + +static int init_rc4(context_t *text, + unsigned char enckey[16], + unsigned char deckey[16]) +{ + /* allocate rc4 context structures */ + text->cipher_enc_context= + (cipher_context_t *) text->utils->malloc(sizeof(rc4_context_t)); + if (text->cipher_enc_context == NULL) return SASL_NOMEM; + + text->cipher_dec_context= + (cipher_context_t *) text->utils->malloc(sizeof(rc4_context_t)); + if (text->cipher_dec_context == NULL) return SASL_NOMEM; + + /* initialize them */ + rc4_init((rc4_context_t *) text->cipher_enc_context, + (const unsigned char *) enckey, 16); + rc4_init((rc4_context_t *) text->cipher_dec_context, + (const unsigned char *) deckey, 16); + + return SASL_OK; +} + +static int dec_rc4(context_t *text, + const char *input, + unsigned inputlen, + unsigned char digest[16] __attribute__((unused)), + char *output, + unsigned *outputlen) +{ + /* decrypt the text part & HMAC */ + rc4_decrypt((rc4_context_t *) text->cipher_dec_context, + input, output, inputlen); + + /* no padding so we just subtract the HMAC to get the text length */ + *outputlen = inputlen - 10; + + return SASL_OK; +} + +static int enc_rc4(context_t *text, + const char *input, + unsigned inputlen, + unsigned char digest[16], + char *output, + unsigned *outputlen) +{ + /* pad is zero */ + *outputlen = inputlen+10; + + /* encrypt the text part */ + rc4_encrypt((rc4_context_t *) text->cipher_enc_context, + input, + output, + inputlen); + + /* encrypt the HMAC part */ + rc4_encrypt((rc4_context_t *) text->cipher_enc_context, + (const char *) digest, + (output)+inputlen, 10); + + return SASL_OK; +} + +#endif /* WITH_RC4 */ + +struct digest_cipher available_ciphers[] = +{ +#ifdef WITH_RC4 + { "rc4-40", 40, 5, 0x01, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 }, + { "rc4-56", 56, 7, 0x02, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 }, + { "rc4", 128, 16, 0x04, &enc_rc4, &dec_rc4, &init_rc4, &free_rc4 }, +#endif +#ifdef WITH_DES + { "des", 55, 16, 0x08, &enc_des, &dec_des, &init_des, &free_des }, + { "3des", 112, 16, 0x10, &enc_3des, &dec_3des, &init_3des, &free_des }, +#endif + { NULL, 0, 0, 0, NULL, NULL, NULL, NULL } +}; + +static int create_layer_keys(context_t *text, + const sasl_utils_t *utils, + HASH key, int keylen, + unsigned char enckey[16], + unsigned char deckey[16]) +{ + MD5_CTX Md5Ctx; + + utils->log(utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 create_layer_keys()"); + + utils->MD5Init(&Md5Ctx); + utils->MD5Update(&Md5Ctx, key, keylen); + if (text->i_am == SERVER) { + utils->MD5Update(&Md5Ctx, (const unsigned char *) SEALING_SERVER_CLIENT, + (unsigned) strlen(SEALING_SERVER_CLIENT)); + } else { + utils->MD5Update(&Md5Ctx, (const unsigned char *) SEALING_CLIENT_SERVER, + (unsigned) strlen(SEALING_CLIENT_SERVER)); + } + utils->MD5Final(enckey, &Md5Ctx); + + utils->MD5Init(&Md5Ctx); + utils->MD5Update(&Md5Ctx, key, keylen); + if (text->i_am != SERVER) { + utils->MD5Update(&Md5Ctx, (const unsigned char *) SEALING_SERVER_CLIENT, + (unsigned) strlen(SEALING_SERVER_CLIENT)); + } else { + utils->MD5Update(&Md5Ctx, (const unsigned char *) SEALING_CLIENT_SERVER, + (unsigned) strlen(SEALING_CLIENT_SERVER)); + } + utils->MD5Final(deckey, &Md5Ctx); + + /* create integrity keys */ + /* sending */ + utils->MD5Init(&Md5Ctx); + utils->MD5Update(&Md5Ctx, text->HA1, HASHLEN); + if (text->i_am == SERVER) { + utils->MD5Update(&Md5Ctx, (const unsigned char *)SIGNING_SERVER_CLIENT, + (unsigned) strlen(SIGNING_SERVER_CLIENT)); + } else { + utils->MD5Update(&Md5Ctx, (const unsigned char *)SIGNING_CLIENT_SERVER, + (unsigned) strlen(SIGNING_CLIENT_SERVER)); + } + utils->MD5Final(text->Ki_send, &Md5Ctx); + + /* receiving */ + utils->MD5Init(&Md5Ctx); + utils->MD5Update(&Md5Ctx, text->HA1, HASHLEN); + if (text->i_am != SERVER) { + utils->MD5Update(&Md5Ctx, (const unsigned char *)SIGNING_SERVER_CLIENT, + (unsigned) strlen(SIGNING_SERVER_CLIENT)); + } else { + utils->MD5Update(&Md5Ctx, (const unsigned char *)SIGNING_CLIENT_SERVER, + (unsigned) strlen(SIGNING_CLIENT_SERVER)); + } + utils->MD5Final(text->Ki_receive, &Md5Ctx); + + return SASL_OK; +} + +static const unsigned short version = 1; + +/* + * privacy: + * len, CIPHER(Kc, {msg, pag, HMAC(ki, {SeqNum, msg})[0..9]}), x0001, SeqNum + * + * integrity: + * len, HMAC(ki, {SeqNum, msg})[0..9], x0001, SeqNum + */ +static int digestmd5_encode(void *context, + const struct iovec *invec, + unsigned numiov, + const char **output, + unsigned *outputlen) +{ + context_t *text = (context_t *) context; + int tmp; + unsigned int tmpnum; + unsigned short int tmpshort; + int ret; + char *out; + struct buffer_info *inblob, bufinfo; + + if(!context || !invec || !numiov || !output || !outputlen) { + PARAMERROR(text->utils); + return SASL_BADPARAM; + } + + if (numiov > 1) { + ret = _plug_iovec_to_buf(text->utils, invec, numiov, &text->enc_in_buf); + if (ret != SASL_OK) return ret; + inblob = text->enc_in_buf; + } else { + /* avoid the data copy */ + bufinfo.data = invec[0].iov_base; + bufinfo.curlen = invec[0].iov_len; + inblob = &bufinfo; + } + + /* make sure the output buffer is big enough for this blob */ + ret = _plug_buf_alloc(text->utils, &(text->encode_buf), + &(text->encode_buf_len), + (4 + /* for length */ + inblob->curlen + /* for content */ + 10 + /* for MAC */ + 8 + /* maximum pad */ + 6)); /* for ver and seqnum */ + if(ret != SASL_OK) return ret; + + /* skip by the length for now */ + out = (text->encode_buf)+4; + + /* construct (seqnum, msg) + * + * Use the output buffer so that the message text is already in place + * for an integrity-only layer. + */ + tmpnum = htonl(text->seqnum); + memcpy(text->encode_buf, &tmpnum, 4); + memcpy(text->encode_buf + 4, inblob->data, inblob->curlen); + + if (text->cipher_enc) { + unsigned char digest[16]; + + /* HMAC(ki, (seqnum, msg) ) */ + text->utils->hmac_md5((const unsigned char *) text->encode_buf, + inblob->curlen + 4, + text->Ki_send, HASHLEN, digest); + + /* calculate the encrypted part */ + text->cipher_enc(text, inblob->data, inblob->curlen, + digest, out, outputlen); + out+=(*outputlen); + } + else { + /* HMAC(ki, (seqnum, msg) ) -- put directly into output buffer */ + text->utils->hmac_md5((const unsigned char *) text->encode_buf, + inblob->curlen + 4, + text->Ki_send, HASHLEN, + (unsigned char *) text->encode_buf + + inblob->curlen + 4); + + *outputlen = inblob->curlen + 10; /* for message + CMAC */ + out+=inblob->curlen + 10; + } + + /* copy in version */ + tmpshort = htons(version); + memcpy(out, &tmpshort, 2); /* 2 bytes = version */ + + out+=2; + (*outputlen)+=2; /* for version */ + + /* put in seqnum */ + tmpnum = htonl(text->seqnum); + memcpy(out, &tmpnum, 4); /* 4 bytes = seq # */ + + (*outputlen)+=4; /* for seqnum */ + + /* put the 1st 4 bytes in */ + tmp=htonl(*outputlen); + memcpy(text->encode_buf, &tmp, 4); + + (*outputlen)+=4; + + *output = text->encode_buf; + text->seqnum++; + + return SASL_OK; +} + +static int digestmd5_decode_packet(void *context, + const char *input, + unsigned inputlen, + char **output, + unsigned *outputlen) +{ + context_t *text = (context_t *) context; + int result; + unsigned char *digest; + int tmpnum; + int lup; + unsigned short ver; + unsigned int seqnum; + unsigned char checkdigest[16]; + + if (inputlen < 16) { + text->utils->seterror(text->utils->conn, 0, "DIGEST-MD5 SASL packets must be at least 16 bytes long"); + return SASL_FAIL; + } + + /* check the version number */ + memcpy(&ver, input+inputlen-6, 2); + ver = ntohs(ver); + if (ver != version) { + text->utils->seterror(text->utils->conn, 0, "Wrong Version"); + return SASL_FAIL; + } + + /* check the sequence number */ + memcpy(&seqnum, input+inputlen-4, 4); + seqnum = ntohl(seqnum); + + if (seqnum != text->rec_seqnum) { + text->utils->seterror(text->utils->conn, 0, + "Incorrect Sequence Number: received %u, expected %u", + seqnum, + text->rec_seqnum); + return SASL_FAIL; + } + + /* allocate a buffer large enough for the output */ + result = _plug_buf_alloc(text->utils, &text->decode_packet_buf, + &text->decode_packet_buf_len, + inputlen /* length of message */ + - 6 /* skip ver and seqnum */ + + 4); /* prepend seqnum */ + if (result != SASL_OK) return result; + + /* construct (seqnum, msg) */ + tmpnum = htonl(text->rec_seqnum); + memcpy(text->decode_packet_buf, &tmpnum, 4); + + text->rec_seqnum++; /* now increment it */ + + *output = text->decode_packet_buf + 4; /* skip seqnum */ + + if (text->cipher_dec) { + /* decrypt message & HMAC into output buffer */ + result = text->cipher_dec(text, input, inputlen-6, NULL, + *output, outputlen); + if (result != SASL_OK) return result; + } + else { + /* copy message & HMAC into output buffer */ + memcpy(*output, input, inputlen - 6); + *outputlen = inputlen - 16; /* -16 to skip HMAC, ver and seqnum */ + } + digest = (unsigned char *) *output + (inputlen - 16); + + /* check the CMAC */ + + /* HMAC(ki, (seqnum, msg) ) */ + text->utils->hmac_md5((const unsigned char *) text->decode_packet_buf, + (*outputlen) + 4, + text->Ki_receive, HASHLEN, checkdigest); + + /* now check it */ + for (lup = 0; lup < 10; lup++) + if (checkdigest[lup] != digest[lup]) { + text->utils->seterror(text->utils->conn, 0, + "CMAC doesn't match at byte %d!", lup); + return SASL_FAIL; + } + + return SASL_OK; +} + +static int digestmd5_decode(void *context, + const char *input, unsigned inputlen, + const char **output, unsigned *outputlen) +{ + context_t *text = (context_t *) context; + int ret; + + ret = _plug_decode(&text->decode_context, input, inputlen, + &text->decode_buf, &text->decode_buf_len, outputlen, + digestmd5_decode_packet, text); + + *output = text->decode_buf; + + return ret; +} + +static void digestmd5_common_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + context_t *text = (context_t *) conn_context; + int lup; + + if (!text || !utils) return; + + utils->log(utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 common mech dispose"); + + if (text->authid) utils->free(text->authid); + if (text->realm) utils->free(text->realm); + + if (text->realms) { + /* need to free all the realms */ + for (lup = 0; lup < text->realm_cnt; lup++) + utils->free (text->realms[lup]); + + utils->free(text->realms); + } + + if (text->nonce) utils->free(text->nonce); + if (text->cnonce) utils->free(text->cnonce); + + if (text->cipher_free) text->cipher_free(text); + + /* free the stuff in the context */ + if (text->response_value) utils->free(text->response_value); + + _plug_decode_free(&text->decode_context); + if (text->encode_buf) utils->free(text->encode_buf); + if (text->decode_buf) utils->free(text->decode_buf); + if (text->decode_packet_buf) utils->free(text->decode_packet_buf); + if (text->out_buf) utils->free(text->out_buf); + + if (text->enc_in_buf) { + if (text->enc_in_buf->data) utils->free(text->enc_in_buf->data); + utils->free(text->enc_in_buf); + } + + utils->free(conn_context); +} + +static void clear_reauth_entry(reauth_entry_t *reauth, enum Context_type type, + const sasl_utils_t *utils) +{ + if (!reauth) return; + + if (reauth->authid) utils->free(reauth->authid); + if (reauth->realm) utils->free(reauth->realm); + if (reauth->nonce) utils->free(reauth->nonce); + if (reauth->cnonce) utils->free(reauth->cnonce); + + if (type == CLIENT) { + if (reauth->u.c.serverFQDN) utils->free(reauth->u.c.serverFQDN); + } + + memset(reauth, 0, sizeof(reauth_entry_t)); +} + +static void digestmd5_common_mech_free(void *glob_context, + const sasl_utils_t *utils) +{ + digest_glob_context_t *my_glob_context = + (digest_glob_context_t *) glob_context; + reauth_cache_t *reauth_cache = my_glob_context->reauth; + size_t n; + + utils->log(utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 common mech free"); + + /* Prevent anybody else from freeing this as well */ + my_glob_context->reauth = NULL; + + if (!reauth_cache) return; + + for (n = 0; n < reauth_cache->size; n++) { + clear_reauth_entry(&reauth_cache->e[n], reauth_cache->i_am, utils); + } + if (reauth_cache->e) utils->free(reauth_cache->e); + + if (reauth_cache->mutex) { + utils->mutex_free(reauth_cache->mutex); + reauth_cache->mutex = NULL; + } + + utils->free(reauth_cache); +} + +/***************************** Server Section *****************************/ + +typedef struct server_context { + context_t common; + + time_t timestamp; + int stale; /* last nonce is stale */ + sasl_ssf_t limitssf, requiressf; /* application defined bounds */ +} server_context_t; + +static digest_glob_context_t server_glob_context; + +static void DigestCalcHA1FromSecret(context_t * text, + const sasl_utils_t * utils, + HASH HA1, + unsigned char *authorization_id, + unsigned char *pszNonce, + unsigned char *pszCNonce, + HASHHEX SessionKey) +{ + MD5_CTX Md5Ctx; + + /* calculate session key */ + utils->MD5Init(&Md5Ctx); + if (text->http_mode) { + /* per RFC 2617 Errata ID 1649 */ + HASHHEX HA1Hex; + + CvtHex(HA1, HA1Hex); + utils->MD5Update(&Md5Ctx, HA1Hex, HASHHEXLEN); + } + else { + /* per RFC 2831 */ + utils->MD5Update(&Md5Ctx, HA1, HASHLEN); + } + utils->MD5Update(&Md5Ctx, COLON, 1); + utils->MD5Update(&Md5Ctx, pszNonce, (unsigned) strlen((char *) pszNonce)); + utils->MD5Update(&Md5Ctx, COLON, 1); + utils->MD5Update(&Md5Ctx, pszCNonce, (unsigned) strlen((char *) pszCNonce)); + if (authorization_id != NULL) { + utils->MD5Update(&Md5Ctx, COLON, 1); + utils->MD5Update(&Md5Ctx, authorization_id, + (unsigned) strlen((char *) authorization_id)); + } + utils->MD5Final(HA1, &Md5Ctx); + + CvtHex(HA1, SessionKey); + + + /* save HA1 because we need it to make the privacy and integrity keys */ + memcpy(text->HA1, HA1, sizeof(HASH)); +} + +static char *create_response(context_t * text, + const sasl_utils_t * utils, + unsigned char *nonce, + unsigned int ncvalue, + unsigned char *cnonce, + char *qop, + const sasl_http_request_t *request, + HASH Secret, + char *authorization_id, + char **response_value) +{ + HASHHEX SessionKey; + HASH EntityHash; + HASHHEX HEntity; + HASHHEX Response; + char *result; + + if (qop == NULL) qop = "auth"; + + DigestCalcHA1FromSecret(text, + utils, + Secret, + (unsigned char *) authorization_id, + nonce, + cnonce, + SessionKey); + + if (text->http_mode) { + /* per RFC 2617 */ + MD5_CTX Md5Ctx; + + utils->MD5Init(&Md5Ctx); + utils->MD5Update(&Md5Ctx, request->entity, request->elen); + utils->MD5Final(EntityHash, &Md5Ctx); + } + else { + /* per RFC 2831 */ + memset(EntityHash, 0, HASHLEN); + } + CvtHex(EntityHash, HEntity); + + /* Calculate response for comparison with client's response */ + DigestCalcResponse(utils, + SessionKey,/* HEX(H(A1)) */ + nonce, /* nonce from server */ + ncvalue, /* 8 hex digits */ + cnonce, /* client nonce */ + (unsigned char *) qop, /* qop-value: "", "auth", + * "auth-int" */ + (unsigned char *) request->uri, /* requested URL */ + (unsigned char *) request->method, + HEntity, /* H(entity body) if qop="auth-int" */ + Response /* request-digest or response-digest */ + ); + + result = utils->malloc(HASHHEXLEN + 1); + memcpy(result, Response, HASHHEXLEN); + result[HASHHEXLEN] = 0; + + /* Calculate response value for mutual auth with the client (NO Method) */ + if (response_value != NULL) { + char * new_response_value; + + DigestCalcResponse(utils, + SessionKey, /* HEX(H(A1)) */ + nonce, /* nonce from server */ + ncvalue, /* 8 hex digits */ + cnonce, /* client nonce */ + (unsigned char *) qop, /* qop-value: "", "auth", + * "auth-int" */ + (unsigned char *) request->uri, /* requested URL */ + NULL, + HEntity, /* H(entity body) if qop="auth-int" */ + Response /* request-digest or response-digest */ + ); + + new_response_value = utils->realloc(*response_value, HASHHEXLEN + 1); + if (new_response_value == NULL) { + free (*response_value); + *response_value = NULL; + return NULL; + } + *response_value = new_response_value; + + memcpy(*response_value, Response, HASHHEXLEN); + (*response_value)[HASHHEXLEN] = 0; + } + return result; +} + +static int get_server_realm(sasl_server_params_t * params, char **realm) +{ + /* look at user realm first */ + if (params->user_realm != NULL) { + if(params->user_realm[0] != '\0') { + *realm = (char *) params->user_realm; + } else { + /* Catch improperly converted apps */ + params->utils->seterror(params->utils->conn, 0, + "user_realm is an empty string!"); + return SASL_BADPARAM; + } + } else if (params->serverFQDN != NULL) { + *realm = (char *) params->serverFQDN; + } else { + params->utils->seterror(params->utils->conn, 0, + "no way to obtain DIGEST-MD5 realm"); + return SASL_FAIL; + } + + return SASL_OK; +} + +/* + * Convert hex string to int + */ +static int htoi(unsigned char *hexin, unsigned int *res) +{ + size_t lup, inlen; + inlen = strlen((char *) hexin); + + *res = 0; + for (lup = 0; lup < inlen; lup++) { + switch (hexin[lup]) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + *res = (*res << 4) + (hexin[lup] - '0'); + break; + + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + *res = (*res << 4) + (hexin[lup] - 'a' + 10); + break; + + case 'A': + case 'B': + case 'C': + case 'D': + case 'E': + case 'F': + *res = (*res << 4) + (hexin[lup] - 'A' + 10); + break; + + default: + return SASL_BADPARAM; + } + + } + + return SASL_OK; +} + +static int digestmd5_server_mech_new(void *glob_context, + sasl_server_params_t * sparams, + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + void **conn_context) +{ + context_t *text; + + /* holds state are in -- allocate server size */ + text = sparams->utils->malloc(sizeof(server_context_t)); + if (text == NULL) + return SASL_NOMEM; + memset(text, 0, sizeof(server_context_t)); + + text->state = 1; + text->i_am = SERVER; + text->http_mode = (sparams->flags & SASL_NEED_HTTP); + text->reauth = ((digest_glob_context_t *) glob_context)->reauth; + + *conn_context = text; + return SASL_OK; +} + +static int +digestmd5_server_mech_step1(server_context_t *stext, + sasl_server_params_t *sparams, + const char *clientin __attribute__((unused)), + unsigned clientinlen __attribute__((unused)), + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t * oparams __attribute__((unused))) +{ + context_t *text = (context_t *) stext; + int result; + char *realm; + unsigned char *nonce; + char *charset = "utf-8"; + char qop[1024], cipheropts[1024]; + struct digest_cipher *cipher; + unsigned resplen; + int added_conf = 0; + char maxbufstr[64]; + + sparams->utils->log(sparams->utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 server step 1"); + + /* get realm */ + result = get_server_realm(sparams, &realm); + if(result != SASL_OK) return result; + + /* what options should we offer the client? */ + qop[0] = '\0'; + cipheropts[0] = '\0'; + if (stext->requiressf == 0) { + if (*qop) strcat(qop, ","); + strcat(qop, "auth"); + } + if (stext->requiressf <= 1 && stext->limitssf >= 1) { + if (*qop) strcat(qop, ","); + strcat(qop, "auth-int"); + } + + cipher = available_ciphers; + while (cipher->name) { + /* do we allow this particular cipher? */ + if (stext->requiressf <= cipher->ssf && + stext->limitssf >= cipher->ssf) { + if (!added_conf) { + if (*qop) strcat(qop, ","); + strcat(qop, "auth-conf"); + added_conf = 1; + } + if (*cipheropts) strcat(cipheropts, ","); + strcat(cipheropts, cipher->name); + } + cipher++; + } + + if (*qop == '\0') { + /* we didn't allow anything?!? we'll return SASL_TOOWEAK, since + that's close enough */ + return SASL_TOOWEAK; + } + + /* + * digest-challenge = 1#( realm | nonce | qop-options | stale | maxbuf | + * charset | cipher-opts | auth-param ) + */ + + nonce = create_nonce(sparams->utils); + if (nonce == NULL) { + SETERROR(sparams->utils, "internal erorr: failed creating a nonce"); + return SASL_FAIL; + } + + resplen = 0; + text->out_buf = NULL; + text->out_buf_len = 0; + if (add_to_challenge(sparams->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "nonce", (unsigned char *) nonce, + TRUE) != SASL_OK) { + SETERROR(sparams->utils, "internal error: add_to_challenge failed"); + return SASL_FAIL; + } + + /* add to challenge; if we chose not to specify a realm, we won't + * send one to the client */ + if (realm && add_to_challenge(sparams->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "realm", (unsigned char *) realm, + TRUE) != SASL_OK) { + SETERROR(sparams->utils, "internal error: add_to_challenge failed"); + return SASL_FAIL; + } + /* + * qop-options A quoted string of one or more tokens indicating the + * "quality of protection" values supported by the server. The value + * "auth" indicates authentication; the value "auth-int" indicates + * authentication with integrity protection; the value "auth-conf" + * indicates authentication with integrity protection and encryption. + */ + + /* add qop to challenge */ + if (add_to_challenge(sparams->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "qop", + (unsigned char *) qop, TRUE) != SASL_OK) { + SETERROR(sparams->utils, "internal error: add_to_challenge 3 failed"); + return SASL_FAIL; + } + + /* + * Cipheropts - list of ciphers server supports + */ + /* add cipher-opts to challenge; only add if there are some */ + if (strcmp(cipheropts,"")!=0) + { + if (add_to_challenge(sparams->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "cipher", (unsigned char *) cipheropts, + TRUE) != SASL_OK) { + SETERROR(sparams->utils, + "internal error: add_to_challenge 4 failed"); + return SASL_FAIL; + } + } + + /* "stale" is true if a reauth failed because of a nonce timeout */ + if (stext->stale && + add_to_challenge(sparams->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "stale", (unsigned char *) "true", FALSE) != SASL_OK) { + SETERROR(sparams->utils, "internal error: add_to_challenge failed"); + return SASL_FAIL; + } + + /* + * maxbuf A number indicating the size of the largest buffer the server + * is able to receive when using "auth-int". If this directive is + * missing, the default value is 65536. This directive may appear at most + * once; if multiple instances are present, the client should abort the + * authentication exchange. + */ + if(sparams->props.maxbufsize) { + snprintf(maxbufstr, sizeof(maxbufstr), "%u", + sparams->props.maxbufsize); + if (add_to_challenge(sparams->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "maxbuf", + (unsigned char *) maxbufstr, FALSE) != SASL_OK) { + SETERROR(sparams->utils, + "internal error: add_to_challenge 5 failed"); + return SASL_FAIL; + } + } + + if (add_to_challenge(sparams->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "charset", + (unsigned char *) charset, FALSE) != SASL_OK) { + SETERROR(sparams->utils, "internal error: add_to_challenge 6 failed"); + return SASL_FAIL; + } + + + /* + * algorithm + * This directive is required for backwards compatibility with HTTP + * Digest, which supports other algorithms. This directive is + * required and MUST appear exactly once; if not present, or if multiple + * instances are present, the client should abort the authentication + * exchange. + * + * algorithm = "algorithm" "=" "md5-sess" + */ + + if (add_to_challenge(sparams->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "algorithm", + (unsigned char *) "md5-sess", FALSE)!=SASL_OK) { + SETERROR(sparams->utils, "internal error: add_to_challenge 7 failed"); + return SASL_FAIL; + } + + /* + * The size of a digest-challenge MUST be less than 2048 bytes!!! + */ + if (*serveroutlen > 2048) { + SETERROR(sparams->utils, + "internal error: challenge larger than 2048 bytes"); + return SASL_FAIL; + } + + text->authid = NULL; + if (_plug_strdup(sparams->utils, realm, &text->realm, NULL) != SASL_OK) { + SETERROR(sparams->utils, + "internal error: out of memory when saving realm"); + return SASL_FAIL; + } + + if (text->http_mode && + sparams->utils->mutex_lock(text->reauth->mutex) == SASL_OK) { /* LOCK */ + + /* Create an initial cache entry for non-persistent HTTP connections */ + unsigned val = hash((char *) nonce) % text->reauth->size; + + clear_reauth_entry(&text->reauth->e[val], SERVER, sparams->utils); + text->reauth->e[val].authid = NULL; + text->reauth->e[val].realm = text->realm; text->realm = NULL; + text->reauth->e[val].nonce = nonce; + text->reauth->e[val].nonce_count = 1; + text->reauth->e[val].cnonce = NULL; + text->reauth->e[val].u.s.timestamp = time(0); + + sparams->utils->mutex_unlock(text->reauth->mutex); /* UNLOCK */ + } + else { + text->nonce = nonce; + text->nonce_count = 1; + text->cnonce = NULL; + stext->timestamp = time(0); + } + + *serveroutlen = (unsigned) strlen(text->out_buf); + *serverout = text->out_buf; + + text->state = 2; + + return SASL_CONTINUE; +} + +static int digestmd5_server_mech_step2(server_context_t *stext, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t * oparams) +{ + context_t *text = (context_t *) stext; + /* verify digest */ + sasl_secret_t *sec = NULL; + int result; + char *serverresponse = NULL; + char *username = NULL; + char *authorization_id = NULL; + char *realm = NULL; + unsigned char *nonce = NULL, *cnonce = NULL; + unsigned int noncecount = 0; + char *qop = NULL; + char *digesturi = NULL; + sasl_http_request_t rfc2831_request; + const sasl_http_request_t *request; + char *response = NULL; + + /* setting the default value (65536) */ + unsigned long client_maxbuf = 65536; + int maxbuf_count = 0; /* How many maxbuf instances was found */ + + char *charset = NULL; + char *cipher = NULL; + unsigned int n = 0; + + HASH Secret; + HASH SecretBogus; + bool Try_8859_1 = FALSE; + int client_ignores_realm = 0; + char *full_username = NULL; + char *internal_username = NULL; + int canon_flags; + + /* password prop_request */ + const char *password_request[] = { SASL_AUX_PASSWORD, + "*cmusaslsecretDIGEST-MD5", + NULL }; + size_t len; + struct propval auxprop_values[2]; + + /* can we mess with clientin? copy it to be safe */ + char *in_start = NULL; + char *in = NULL; + cipher_free_t *old_cipher_free = NULL; + + sparams->utils->log(sparams->utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 server step 2"); + + if (clientinlen == 0) { + SETERROR(sparams->utils, "input expected in DIGEST-MD5, step 2"); + result = SASL_BADAUTH; + goto FreeAllMem; + } + + if (text->http_mode) { + /* per RFC 2617 (HTTP Request as set by calling application) */ + request = sparams->http_request; + if (!request) { + SETERROR(sparams->utils, + "missing HTTP request in DIGEST-MD5, step 2"); + result = SASL_BADPARAM; + goto FreeAllMem; + } + } + else { + /* per RFC 2831 */ + rfc2831_request.method = "AUTHENTICATE"; + rfc2831_request.uri = NULL; /* to be filled in below from response */ + rfc2831_request.entity = NULL; + rfc2831_request.elen = 0; + rfc2831_request.non_persist = 0; + request = &rfc2831_request; + } + + in = sparams->utils->malloc(clientinlen + 1); + + memcpy(in, clientin, clientinlen); + in[clientinlen] = 0; + + in_start = in; + + + /* parse what we got */ + while (in[0] != '\0') { + char *name = NULL, *value = NULL; + get_pair(&in, &name, &value); + + if (name == NULL) { + SETERROR(sparams->utils, + "Parse error"); + result = SASL_BADAUTH; + goto FreeAllMem; + } + + if (*name == '\0') { + break; + } + + /* Extracting parameters */ + + /* + * digest-response = 1#( username | realm | nonce | cnonce | + * nonce-count | qop | digest-uri | response | maxbuf | charset | + * cipher | auth-param ) + */ + + if (strcasecmp(name, "username") == 0) { + _plug_strdup(sparams->utils, value, &username, NULL); + } else if (strcasecmp(name, "authzid") == 0) { + _plug_strdup(sparams->utils, value, &authorization_id, NULL); + } else if (strcasecmp(name, "cnonce") == 0) { + _plug_strdup(sparams->utils, value, (char **) &cnonce, NULL); + } else if (strcasecmp(name, "nc") == 0) { + if (htoi((unsigned char *) value, &noncecount) != SASL_OK) { + SETERROR(sparams->utils, + "error converting hex to int"); + result = SASL_BADAUTH; + goto FreeAllMem; + } + } else if (strcasecmp(name, "realm") == 0) { + if (realm) { + SETERROR(sparams->utils, + "duplicate realm: authentication aborted"); + result = SASL_FAIL; + goto FreeAllMem; + } + _plug_strdup(sparams->utils, value, &realm, NULL); + } else if (strcasecmp(name, "nonce") == 0) { + _plug_strdup(sparams->utils, value, (char **) &nonce, NULL); + } else if (strcasecmp(name, "qop") == 0) { + if (qop) { + SETERROR(sparams->utils, + "duplicate qop: authentication aborted"); + result = SASL_FAIL; + goto FreeAllMem; + } + _plug_strdup(sparams->utils, value, &qop, NULL); + } else if (strcasecmp(name, "digest-uri") == 0 || /* per RFC 2831 */ + (text->http_mode && + strcasecmp(name, "uri") == 0)) { /* per RFC 2617 */ + size_t service_len; + + if (digesturi) { + SETERROR(sparams->utils, + "duplicate digest-uri: authentication aborted"); + result = SASL_FAIL; + goto FreeAllMem; + } + + _plug_strdup(sparams->utils, value, &digesturi, NULL); + + if (text->http_mode && request && request->uri) { + /* Verify digest-uri matches HTTP request (per RFC 2617) */ + if (strcmp(digesturi, request->uri)) { + result = SASL_BADAUTH; + SETERROR(sparams->utils, + "bad digest-uri: doesn't match HTTP request"); + goto FreeAllMem; + } + } + else { + /* Verify digest-uri format (per RFC 2831): + * + * digest-uri-value = serv-type "/" host [ "/" serv-name ] + */ + + /* make sure it's the service that we're expecting */ + service_len = strlen(sparams->service); + if (strncasecmp(digesturi, sparams->service, service_len) || + digesturi[service_len] != '/') { + result = SASL_BADAUTH; + SETERROR(sparams->utils, + "bad digest-uri: doesn't match service"); + goto FreeAllMem; + } + + /* xxx we don't verify the hostname component */ + + rfc2831_request.uri = digesturi; + } + + } else if (strcasecmp(name, "response") == 0) { + _plug_strdup(sparams->utils, value, &response, NULL); + } else if (strcasecmp(name, "cipher") == 0) { + _plug_strdup(sparams->utils, value, &cipher, NULL); + } else if (strcasecmp(name, "maxbuf") == 0) { + maxbuf_count++; + if (maxbuf_count != 1) { + result = SASL_BADAUTH; + SETERROR(sparams->utils, + "duplicate maxbuf: authentication aborted"); + goto FreeAllMem; + } else if (str2ul32 (value, &client_maxbuf) == FALSE) { + result = SASL_BADAUTH; + SETERROR(sparams->utils, "invalid maxbuf parameter"); + goto FreeAllMem; + } else { + if (client_maxbuf <= 16) { + result = SASL_BADAUTH; + SETERROR(sparams->utils, + "maxbuf parameter too small"); + goto FreeAllMem; + } + + if (client_maxbuf > MAX_SASL_BUFSIZE) { + result = SASL_BADAUTH; + SETERROR(sparams->utils, + "maxbuf parameter too big"); + goto FreeAllMem; + } + } + } else if (strcasecmp(name, "charset") == 0) { + if (strcasecmp(value, "utf-8") != 0) { + SETERROR(sparams->utils, "client doesn't support UTF-8"); + result = SASL_FAIL; + goto FreeAllMem; + } + _plug_strdup(sparams->utils, value, &charset, NULL); + } else if (strcasecmp(name,"algorithm") == 0) { + /* per RFC 2831: algorithm MUST be ignored if received */ + if (text->http_mode && strcasecmp(value, "md5-sess") != 0) { + /* per RFC 2617: algorithm MUST match that sent in challenge */ + SETERROR(sparams->utils, "'algorithm' isn't 'md5-sess'"); + result = SASL_FAIL; + goto FreeAllMem; + } + } else { + sparams->utils->log(sparams->utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 unrecognized pair %s/%s: ignoring", + name, value); + } + } + + /* + * username = "username" "=" <"> username-value <"> + * username-value = qdstr-val + * cnonce = "cnonce" "=" <"> cnonce-value <"> + * cnonce-value = qdstr-val + * nonce-count = "nc" "=" nc-value + * nc-value = 8LHEX + * qop = "qop" "=" qop-value + * digest-uri = "digest-uri" "=" digest-uri-value + * digest-uri-value = serv-type "/" host [ "/" serv-name ] + * serv-type = 1*ALPHA + * host = 1*( ALPHA | DIGIT | "-" | "." ) + * service = host + * response = "response" "=" <"> response-value <"> + * response-value = 32LHEX + * LHEX = "0" | "1" | "2" | "3" | "4" | "5" | + * "6" | "7" | "8" | "9" | "a" | "b" | "c" | "d" | "e" | "f" + * cipher = "cipher" "=" cipher-value + */ + /* Verifing that all required parameters were received */ + if ((username == NULL)) { + SETERROR(sparams->utils, "required parameters missing: username"); + result = SASL_BADAUTH; + goto FreeAllMem; + } + if ((nonce == NULL)) { + SETERROR(sparams->utils, "required parameters missing: nonce"); + result = SASL_BADAUTH; + goto FreeAllMem; + } + if ((noncecount == 0)) { + SETERROR(sparams->utils, "required parameters missing: noncecount"); + result = SASL_BADAUTH; + goto FreeAllMem; + } + if ((cnonce == NULL)) { + SETERROR(sparams->utils, "required parameters missing: cnonce"); + result = SASL_BADAUTH; + goto FreeAllMem; + } + if ((digesturi == NULL)) { + SETERROR(sparams->utils, "required parameters missing: digesturi"); + result = SASL_BADAUTH; + goto FreeAllMem; + } + if ((response == NULL)) { + SETERROR(sparams->utils, "required parameters missing: response"); + result = SASL_BADAUTH; + goto FreeAllMem; + } + + if (realm == NULL) { + /* From 2831bis: + If the directive is missing, "realm-value" will set to + the empty string when computing A1. */ + _plug_strdup(sparams->utils, "", &realm, NULL); + sparams->utils->log(sparams->utils->conn, SASL_LOG_DEBUG, + "The client didn't send a realm, assuming empty string."); +#if 0 + if (text->realm[0] != '\0') { + SETERROR(sparams->utils, + "realm changed: authentication aborted"); + result = SASL_BADAUTH; + goto FreeAllMem; + } +#endif + } + + if (!text->nonce) { + unsigned val = hash((char *) nonce) % text->reauth->size; + + /* reauth attempt or continuation of HTTP Digest on a + non-persistent connection, see if we have any info for this nonce */ + if (sparams->utils->mutex_lock(text->reauth->mutex) == SASL_OK) { /* LOCK */ + if (text->reauth->e[val].realm && + !strcmp(realm, text->reauth->e[val].realm) && + ((text->reauth->e[val].nonce_count == 1) || + (text->reauth->e[val].authid && + !strcmp(username, text->reauth->e[val].authid)))) { + + _plug_strdup(sparams->utils, text->reauth->e[val].realm, + &text->realm, NULL); + _plug_strdup(sparams->utils, (char *) text->reauth->e[val].nonce, + (char **) &text->nonce, NULL); + text->nonce_count = text->reauth->e[val].nonce_count; +#if 0 /* XXX Neither RFC 2617 nor RFC 2831 state that the cnonce + needs to remain constant for subsequent authentication to work */ + _plug_strdup(sparams->utils, (char *) text->reauth->e[val].cnonce, + (char **) &text->cnonce, NULL); +#endif + stext->timestamp = text->reauth->e[val].u.s.timestamp; + } + sparams->utils->mutex_unlock(text->reauth->mutex); /* UNLOCK */ + } + + if (!text->nonce) { + /* we don't have any reauth info */ + sparams->utils->log(sparams->utils->conn, SASL_LOG_DEBUG, + "No reauth info for '%s' found", nonce); + + /* we will continue processing the response to determine + if the client knows the password and return stale accordingly */ + } + } + + /* Sanity check the parameters */ + if (text->nonce) { + /* CLAIM: realm is not NULL below */ + if (text->realm == NULL) { + sparams->utils->log(sparams->utils->conn, SASL_LOG_DEBUG, + "The client specifies a realm when the server hasn't provided one. Using client's realm."); + _plug_strdup(sparams->utils, realm, &text->realm, NULL); + } else if ((strcmp(realm, text->realm) != 0) && + /* XXX - Not sure why the check for text->realm not being empty is needed, + as it should always be non-empty */ + (text->realm[0] != 0)) { + + client_ignores_realm = 1; + sparams->utils->log(sparams->utils->conn, SASL_LOG_DEBUG, + "The client tries to override server provided realm"); + if (text->realm) sparams->utils->free(text->realm); + _plug_strdup(sparams->utils, realm, &text->realm, NULL); + } + + if (strcmp((char *) nonce, (char *) text->nonce) != 0) { + SETERROR(sparams->utils, + "nonce changed: authentication aborted"); + result = SASL_BADAUTH; + goto FreeAllMem; + } +#if 0 /* XXX Possible replay attack, but we will continue processing + * the response to determine if the client knows the password and + return stale accordingly */ + if (noncecount != text->nonce_count) { + SETERROR(sparams->utils, + "incorrect nonce-count: authentication aborted"); + result = SASL_BADAUTH; + goto FreeAllMem; + } +#endif +#if 0 /* XXX Neither RFC 2617 nor RFC 2831 state that the cnonce + needs to remain constant for subsequent authentication to work */ + if (text->cnonce && strcmp((char *) cnonce, (char *) text->cnonce) != 0) { + SETERROR(sparams->utils, + "cnonce changed: authentication aborted"); + result = SASL_BADAUTH; + goto FreeAllMem; + } +#endif + } + + result = sparams->utils->prop_request(sparams->propctx, password_request); + if(result != SASL_OK) { + SETERROR(sparams->utils, "unable to obtain user password"); + goto FreeAllMem; + } + + /* this will trigger the getting of the aux properties */ + /* Note that if we don't have an authorization id, we don't use it... */ + + if (client_ignores_realm) { + if (strlen(text->realm) == 0) { + /* Don't put @ at the end of the username, if the realm is empty */ + _plug_strdup(sparams->utils, username, &full_username, NULL); + } else { + full_username = (char *) sparams->utils->malloc(strlen(username) + + strlen(text->realm) + 2); + full_username[0] = '\0'; + sprintf (full_username, "%s@%s", username, text->realm); + } + internal_username = full_username; + } else { + internal_username = username; + } + + canon_flags = SASL_CU_AUTHID; + if (!authorization_id || !*authorization_id) { + canon_flags |= SASL_CU_AUTHZID; + } + + result = sparams->canon_user(sparams->utils->conn, + internal_username, + 0, + canon_flags, + oparams); + if (result != SASL_OK) { + SETERROR(sparams->utils, "unable to canonify user and get auxprops"); + goto FreeAllMem; + } + + if (authorization_id != NULL && *authorization_id != '\0') { + result = sparams->canon_user(sparams->utils->conn, + authorization_id, 0, SASL_CU_AUTHZID, + oparams); + } + if (result != SASL_OK) { + SETERROR(sparams->utils, "unable to canonify authorization ID"); + goto FreeAllMem; + } + + result = sparams->utils->prop_getnames(sparams->propctx, password_request, + auxprop_values); + if (result < 0 || + ((!auxprop_values[0].name || !auxprop_values[0].values) && + (!auxprop_values[1].name || !auxprop_values[1].values))) { + /* We didn't find this username */ + sparams->utils->seterror(sparams->utils->conn, 0, + "no secret in database"); + result = sparams->transition ? SASL_TRANS : SASL_NOUSER; + goto FreeAllMem; + } + + if (auxprop_values[0].name && auxprop_values[0].values) { + len = strlen(auxprop_values[0].values[0]); + if (len == 0) { + sparams->utils->seterror(sparams->utils->conn,0, + "empty secret"); + result = SASL_FAIL; + goto FreeAllMem; + } + + sec = sparams->utils->malloc(sizeof(sasl_secret_t) + len); + if (!sec) { + SETERROR(sparams->utils, "unable to allocate secret"); + result = SASL_FAIL; + goto FreeAllMem; + } + + sec->len = (unsigned) len; + strncpy((char *) sec->data, auxprop_values[0].values[0], len + 1); + + /* + * Verifying response obtained from client + * + * H_URP = H({ username-value,":",realm-value,":",passwd}) sec->data + * contains H_URP + */ + + /* Calculate the secret from the plaintext password */ + { + /* + * Secret = { H( { username-value, ":", realm-value, ":", passwd } ) } + * + * (used to build A1) + */ + + Try_8859_1 = DigestCalcSecret(sparams->utils, + (unsigned char *) username, + (unsigned char *) realm, + sec->data, + sec->len, + FALSE, + Secret); + Secret[HASHLEN] = '\0'; + } + if (Try_8859_1) { + /* + * Secret = { H( { username-value, ":", realm-value, ":", passwd } ) } + * + * (used to build A1) + */ + + DigestCalcSecret(sparams->utils, + (unsigned char *) username, + (unsigned char *) realm, + sec->data, + sec->len, + TRUE, + SecretBogus); + SecretBogus[HASHLEN] = '\0'; + } + + /* We're done with sec now. Let's get rid of it */ + _plug_free_secret(sparams->utils, &sec); + } else if (auxprop_values[1].name && auxprop_values[1].values) { + /* NB: This will most likely fail for clients that + choose to ignore server-advertised realm */ + memcpy(Secret, auxprop_values[1].values[0], HASHLEN); + Secret[HASHLEN] = '\0'; + } else { + sparams->utils->seterror(sparams->utils->conn, 0, + "Have neither type of secret"); + return SASL_FAIL; + } + + /* erase the plaintext password */ + sparams->utils->prop_erase(sparams->propctx, password_request[0]); + + /* defaulting qop to "auth" if not specified */ + if (qop == NULL) { + _plug_strdup(sparams->utils, "auth", &qop, NULL); + } + + if (oparams->mech_ssf > 1) { + /* Remember the old cipher free function (if any). + It will be called later, once we are absolutely + sure that authentication was successful. */ + old_cipher_free = text->cipher_free; + /* free the old cipher context first */ + } + + /* check which layer/cipher to use */ + if ((!strcasecmp(qop, "auth-conf")) && (cipher != NULL)) { + /* see what cipher was requested */ + struct digest_cipher *cptr; + + cptr = available_ciphers; + while (cptr->name) { + /* find the cipher requested & make sure it's one we're happy + with by policy */ + if (!strcasecmp(cipher, cptr->name) && + stext->requiressf <= cptr->ssf && + stext->limitssf >= cptr->ssf) { + /* found it! */ + break; + } + cptr++; + } + + if (cptr->name) { + text->cipher_enc = cptr->cipher_enc; + text->cipher_dec = cptr->cipher_dec; + text->cipher_init = cptr->cipher_init; + text->cipher_free = cptr->cipher_free; + oparams->mech_ssf = cptr->ssf; + n = cptr->n; + } else { + /* erg? client requested something we didn't advertise! */ + sparams->utils->log(sparams->utils->conn, SASL_LOG_WARN, + "protocol violation: client requested invalid cipher"); + SETERROR(sparams->utils, "client requested invalid cipher"); + /* Mark that we attempted security layer negotiation */ + oparams->mech_ssf = 2; + result = SASL_FAIL; + goto FreeAllMem; + } + + oparams->encode=&digestmd5_encode; + oparams->decode=&digestmd5_decode; + } else if (!strcasecmp(qop, "auth-int") && + stext->requiressf <= 1 && stext->limitssf >= 1) { + oparams->encode = &digestmd5_encode; + oparams->decode = &digestmd5_decode; + oparams->mech_ssf = 1; + } else if (!strcasecmp(qop, "auth") && stext->requiressf == 0) { + oparams->encode = NULL; + oparams->decode = NULL; + oparams->mech_ssf = 0; + } else { + SETERROR(sparams->utils, + "protocol violation: client requested invalid qop"); + result = SASL_FAIL; + goto FreeAllMem; + } + + serverresponse = create_response(text, + sparams->utils, + nonce, + noncecount, + cnonce, + qop, + request, + Secret, + authorization_id, + &text->response_value); + + if (serverresponse == NULL) { + SETERROR(sparams->utils, "internal error: unable to create response"); + result = SASL_NOMEM; + goto FreeAllMem; + } + + /* if ok verified */ + if (strcmp(serverresponse, response) != 0) { + if (Try_8859_1) { + + serverresponse = create_response(text, + sparams->utils, + nonce, + noncecount, + cnonce, + qop, + request, + SecretBogus, + authorization_id, + &text->response_value); + + if (serverresponse == NULL) { + SETERROR(sparams->utils, "internal error: unable to create response"); + result = SASL_NOMEM; + goto FreeAllMem; + } + + /* if ok verified */ + if (strcmp(serverresponse, response) != 0) { + SETERROR(sparams->utils, + "client response doesn't match what we generated (tried bogus)"); + result = SASL_BADAUTH; + + goto FreeAllMem; + } + + } else { + SETERROR(sparams->utils, + "client response doesn't match what we generated"); + result = SASL_BADAUTH; + + goto FreeAllMem; + } + } + + /* see if our nonce expired */ + if (!text->nonce || + (noncecount != text->nonce_count) || + (text->reauth->timeout && + time(0) - stext->timestamp > text->reauth->timeout)) { + if (!text->nonce) SETERROR(sparams->utils, "no cached server nonce"); + else if (noncecount != text->nonce_count) + SETERROR(sparams->utils, "incorrect nonce-count"); + else SETERROR(sparams->utils, "server nonce expired"); + stext->stale = 1; + result = SASL_BADAUTH; + + goto FreeAllMem; + } + + /* + * nothing more to do; authenticated set oparams information + */ + oparams->doneflag = 1; + oparams->maxoutbuf = client_maxbuf - 4; + if (oparams->mech_ssf > 1) { + /* MAC block (privacy) */ + oparams->maxoutbuf -= 25; + } else if(oparams->mech_ssf == 1) { + /* MAC block (integrity) */ + oparams->maxoutbuf -= 16; + } + + oparams->param_version = 0; + + text->seqnum = 0; /* for integrity/privacy */ + text->rec_seqnum = 0; /* for integrity/privacy */ + text->utils = sparams->utils; + + /* Free the old security layer, if any */ + if (old_cipher_free) old_cipher_free(text); + + /* used by layers */ + _plug_decode_init(&text->decode_context, text->utils, + sparams->props.maxbufsize ? sparams->props.maxbufsize : + DEFAULT_BUFSIZE); + + if (oparams->mech_ssf > 0) { + unsigned char enckey[16]; + unsigned char deckey[16]; + + create_layer_keys(text, sparams->utils,text->HA1,n,enckey,deckey); + + /* initialize cipher if need be */ + if (text->cipher_init) { + if (text->cipher_init(text, enckey, deckey) != SASL_OK) { + sparams->utils->seterror(sparams->utils->conn, 0, + "couldn't init cipher"); + } + } + } + + /* + * The server receives and validates the "digest-response". The server + * checks that the nonce-count is "00000001". If it supports subsequent + * authentication, it saves the value of the nonce and the nonce-count. + */ + + /* + * The "username-value", "realm-value" and "passwd" are encoded according + * to the value of the "charset" directive. If "charset=UTF-8" is + * present, and all the characters of either "username-value" or "passwd" + * are in the ISO 8859-1 character set, then it must be converted to + * UTF-8 before being hashed. A sample implementation of this conversion + * is in section 8. + */ + + /* add to challenge */ + { + unsigned resplen = 0; + + if (add_to_challenge(sparams->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "rspauth", (unsigned char *) text->response_value, + text->http_mode ? TRUE : FALSE) != SASL_OK) { + SETERROR(sparams->utils, "internal error: add_to_challenge failed"); + result = SASL_FAIL; + goto FreeAllMem; + } + + if (text->http_mode) { + /* per RFC 2617 */ + char ncvalue[10]; + + if (add_to_challenge(sparams->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "cnonce", cnonce, TRUE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllMem; + } + snprintf(ncvalue, sizeof(ncvalue), "%08x", text->nonce_count); + if (add_to_challenge(sparams->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "nc", (unsigned char *) ncvalue, FALSE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllMem; + } + if (add_to_challenge(sparams->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "qop", (unsigned char *) qop, TRUE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllMem; + } + } + + /* self check */ + if (strlen(text->out_buf) > 2048) { + result = SASL_FAIL; + goto FreeAllMem; + } + } + + *serveroutlen = (unsigned) strlen(text->out_buf); + *serverout = text->out_buf; + + result = SASL_OK; + + FreeAllMem: + if (clientinlen > 0 && + text->reauth->timeout && + sparams->utils->mutex_lock(text->reauth->mutex) == SASL_OK) { /* LOCK */ + + /* Look for an entry for the nonce value */ + unsigned val = hash((char *) nonce) % text->reauth->size; + + switch (result) { + case SASL_OK: + /* successful auth, setup for future reauth */ + if (text->nonce_count == 1) { + /* successful initial auth, create new entry */ + clear_reauth_entry(&text->reauth->e[val], SERVER, sparams->utils); + text->reauth->e[val].authid = username; username = NULL; + text->reauth->e[val].realm = text->realm; text->realm = NULL; + text->reauth->e[val].nonce = text->nonce; text->nonce = NULL; + text->reauth->e[val].cnonce = cnonce; cnonce = NULL; + } + if (text->nonce_count < text->reauth->e[val].nonce_count) { + /* paranoia. prevent replay attacks */ + clear_reauth_entry(&text->reauth->e[val], SERVER, sparams->utils); + } + else { + text->reauth->e[val].nonce_count = ++text->nonce_count; + text->reauth->e[val].u.s.timestamp = time(0); + } + break; + default: + if (text->nonce_count > 1) { + /* failed reauth, clear entry */ + clear_reauth_entry(&text->reauth->e[val], SERVER, sparams->utils); + } + else { + /* failed initial auth, leave existing cache */ + } + } + sparams->utils->mutex_unlock(text->reauth->mutex); /* UNLOCK */ + } + + /* free everything */ + if (in_start) sparams->utils->free (in_start); + + if (full_username != NULL) + sparams->utils->free (full_username); + if (username != NULL) + sparams->utils->free (username); + if (authorization_id != NULL) + sparams->utils->free (authorization_id); + if (realm != NULL) + sparams->utils->free (realm); + if (nonce != NULL) + sparams->utils->free (nonce); + if (cnonce != NULL) + sparams->utils->free (cnonce); + if (response != NULL) + sparams->utils->free (response); + if (cipher != NULL) + sparams->utils->free (cipher); + if (serverresponse != NULL) + sparams->utils->free(serverresponse); + if (charset != NULL) + sparams->utils->free (charset); + if (digesturi != NULL) + sparams->utils->free (digesturi); + if (qop!=NULL) + sparams->utils->free (qop); + if (sec) + _plug_free_secret(sparams->utils, &sec); + + return result; +} + +static int digestmd5_server_mech_step(void *conn_context, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *) conn_context; + server_context_t *stext = (server_context_t *) conn_context; + + *serverout = NULL; + *serveroutlen = 0; + + if (clientinlen > 4096) return SASL_BADPROT; + + if (text == NULL) { + return SASL_BADPROT; + } + + switch (text->state) { + + case 1: + /* setup SSF limits */ + if (!text->http_mode && /* HTTP Digest doesn't need buffer */ + !sparams->props.maxbufsize) { + stext->limitssf = 0; + stext->requiressf = 0; + } else { + if (sparams->props.max_ssf < sparams->external_ssf) { + stext->limitssf = 0; + } else { + stext->limitssf = + sparams->props.max_ssf - sparams->external_ssf; + } + if (sparams->props.min_ssf < sparams->external_ssf) { + stext->requiressf = 0; + } else { + stext->requiressf = + sparams->props.min_ssf - sparams->external_ssf; + } + } + + if (clientin && text->reauth->timeout) { + /* here's where we attempt fast reauth if possible */ + if (digestmd5_server_mech_step2(stext, sparams, + clientin, clientinlen, + serverout, serveroutlen, + oparams) == SASL_OK) { + return SASL_OK; + } + + sparams->utils->log(NULL, SASL_LOG_WARN, + "DIGEST-MD5 reauth failed\n"); + + /* re-initialize everything for a fresh start */ + memset(oparams, 0, sizeof(sasl_out_params_t)); + if (text->nonce) sparams->utils->free(text->nonce); + if (text->realm) sparams->utils->free(text->realm); + text->nonce = text->realm = NULL; + + /* fall through and issue challenge */ + } + + return digestmd5_server_mech_step1(stext, sparams, + clientin, clientinlen, + serverout, serveroutlen, oparams); + + case 2: + return digestmd5_server_mech_step2(stext, sparams, + clientin, clientinlen, + serverout, serveroutlen, oparams); + + default: + sparams->utils->log(NULL, SASL_LOG_ERR, + "Invalid DIGEST-MD5 server step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static void digestmd5_server_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + server_context_t *stext = (server_context_t *) conn_context; + + if (!stext || !utils) return; + + digestmd5_common_mech_dispose(conn_context, utils); +} + +static sasl_server_plug_t digestmd5_server_plugins[] = +{ + { + "DIGEST-MD5", /* mech_name */ +#ifdef WITH_RC4 + 128, /* max_ssf */ +#elif defined(WITH_DES) + 112, +#else + 1, +#endif + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS + | SASL_SEC_MUTUAL_AUTH, /* security_flags */ + SASL_FEAT_ALLOWS_PROXY + | SASL_FEAT_SUPPORTS_HTTP, /* features */ + &server_glob_context, /* glob_context */ + &digestmd5_server_mech_new, /* mech_new */ + &digestmd5_server_mech_step, /* mech_step */ + &digestmd5_server_mech_dispose, /* mech_dispose */ + &digestmd5_common_mech_free, /* mech_free */ + NULL, /* setpass */ + NULL, /* user_query */ + NULL, /* idle */ + NULL, /* mech avail */ + NULL /* spare */ + } +}; + +int digestmd5_server_plug_init(sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount) +{ + reauth_cache_t *reauth_cache; + const char *timeout = NULL; + unsigned int len; + + if (maxversion < SASL_SERVER_PLUG_VERSION) { + return SASL_BADVERS; + } + + /* reauth cache */ + reauth_cache = utils->malloc(sizeof(reauth_cache_t)); + if (reauth_cache == NULL) { + return SASL_NOMEM; + } + memset(reauth_cache, 0, sizeof(reauth_cache_t)); + reauth_cache->i_am = SERVER; + + /* fetch and canonify the reauth_timeout */ + utils->getopt(utils->getopt_context, "DIGEST-MD5", "reauth_timeout", + &timeout, &len); + if (timeout) { + reauth_cache->timeout = (time_t) 60 * strtol(timeout, NULL, 10); + } + if (reauth_cache->timeout < 0) { + reauth_cache->timeout = 0; + } + + if (reauth_cache->timeout) { + /* mutex */ + reauth_cache->mutex = utils->mutex_alloc(); + if (!reauth_cache->mutex) { + utils->free(reauth_cache); + return SASL_FAIL; + } + + /* entries */ + reauth_cache->size = 100; + reauth_cache->e = utils->malloc(reauth_cache->size * + sizeof(reauth_entry_t)); + if (reauth_cache->e == NULL) { + utils->mutex_free(reauth_cache->mutex); + utils->free(reauth_cache); + return SASL_NOMEM; + } + memset(reauth_cache->e, 0, reauth_cache->size * sizeof(reauth_entry_t)); + } + + ((digest_glob_context_t *) digestmd5_server_plugins[0].glob_context)->reauth = reauth_cache; + + *out_version = SASL_SERVER_PLUG_VERSION; + *pluglist = digestmd5_server_plugins; + *plugcount = 1; + + return SASL_OK; +} + +/***************************** Client Section *****************************/ + +typedef struct client_context { + context_t common; + + sasl_secret_t *password; /* user password */ + unsigned int free_password; /* set if we need to free password */ + + int protection; + struct digest_cipher *cipher; + unsigned long server_maxbuf; + + /* for HTTP mode (RFC 2617) only */ + char *algorithm; + unsigned char *opaque; +} client_context_t; + +static digest_glob_context_t client_glob_context; + +/* calculate H(A1) as per spec */ +static void DigestCalcHA1(context_t * text, + const sasl_utils_t * utils, + char *pszAlg, + unsigned char *pszUserName, + unsigned char *pszRealm, + sasl_secret_t * pszPassword, + unsigned char *pszAuthorization_id, + unsigned char *pszNonce, + unsigned char *pszCNonce, + HASHHEX SessionKey) +{ + MD5_CTX Md5Ctx; + HASH HA1; + + DigestCalcSecret(utils, + pszUserName, + pszRealm, + (unsigned char *) pszPassword->data, + pszPassword->len, + FALSE, + HA1); + + if (!text->http_mode || /* per RFC 2831 */ + (pszAlg && strcasecmp(pszAlg, "md5-sess") == 0)) { /* per RFC 2617 */ + /* calculate the session key */ + utils->MD5Init(&Md5Ctx); + if (text->http_mode) { + /* per RFC 2617 Errata ID 1649 */ + HASHHEX HA1Hex; + + CvtHex(HA1, HA1Hex); + utils->MD5Update(&Md5Ctx, HA1Hex, HASHHEXLEN); + } + else { + /* per RFC 2831 */ + utils->MD5Update(&Md5Ctx, HA1, HASHLEN); + } + utils->MD5Update(&Md5Ctx, COLON, 1); + utils->MD5Update(&Md5Ctx, pszNonce, (unsigned) strlen((char *) pszNonce)); + utils->MD5Update(&Md5Ctx, COLON, 1); + utils->MD5Update(&Md5Ctx, pszCNonce, (unsigned) strlen((char *) pszCNonce)); + if (pszAuthorization_id != NULL) { + utils->MD5Update(&Md5Ctx, COLON, 1); + utils->MD5Update(&Md5Ctx, pszAuthorization_id, + (unsigned) strlen((char *) pszAuthorization_id)); + } + utils->MD5Final(HA1, &Md5Ctx); + } + + CvtHex(HA1, SessionKey); + + /* xxx rc-* use different n */ + + /* save HA1 because we'll need it for the privacy and integrity keys */ + memcpy(text->HA1, HA1, sizeof(HASH)); + +} + +static char *calculate_response(context_t * text, + const sasl_utils_t * utils, + char *algorithm, + unsigned char *username, + unsigned char *realm, + unsigned char *nonce, + unsigned int ncvalue, + unsigned char *cnonce, + char *qop, + const sasl_http_request_t *request, + sasl_secret_t * passwd, + unsigned char *authorization_id, + char **response_value) +{ + HASHHEX SessionKey; + HASH EntityHash; + HASHHEX HEntity; + HASHHEX Response; + char *result; + + /* Verifing that all parameters was defined */ + if(!username || !cnonce || !nonce || !ncvalue || !request || !passwd) { + PARAMERROR( utils ); + return NULL; + } + + if (realm == NULL) { + /* a NULL realm is equivalent to the empty string */ + realm = (unsigned char *) ""; + } + + if (qop == NULL) { + /* default to a qop of just authentication */ + qop = "auth"; + } + + DigestCalcHA1(text, + utils, + algorithm, + username, + realm, + passwd, + authorization_id, + nonce, + cnonce, + SessionKey); + + if (text->http_mode) { + /* per RFC 2617 */ + MD5_CTX Md5Ctx; + + utils->MD5Init(&Md5Ctx); + utils->MD5Update(&Md5Ctx, request->entity, request->elen); + utils->MD5Final(EntityHash, &Md5Ctx); + } + else { + /* per RFC 2831 */ + memset(EntityHash, 0, HASHLEN); + } + CvtHex(EntityHash, HEntity); + + DigestCalcResponse(utils, + SessionKey,/* HEX(H(A1)) */ + nonce, /* nonce from server */ + ncvalue, /* 8 hex digits */ + cnonce, /* client nonce */ + (unsigned char *) qop, /* qop-value: "", "auth", + * "auth-int" */ + (unsigned char *) request->uri, /* requested URL */ + (unsigned char *) request->method, + HEntity, /* H(entity body) if qop="auth-int" */ + Response /* request-digest or response-digest */ + ); + + result = utils->malloc(HASHHEXLEN + 1); + memcpy(result, Response, HASHHEXLEN); + result[HASHHEXLEN] = 0; + + if (response_value != NULL) { + char * new_response_value; + + DigestCalcResponse(utils, + SessionKey, /* HEX(H(A1)) */ + nonce, /* nonce from server */ + ncvalue, /* 8 hex digits */ + cnonce, /* client nonce */ + (unsigned char *) qop, /* qop-value: "", "auth", + * "auth-int" */ + (unsigned char *) request->uri, /* requested URL */ + NULL, + HEntity, /* H(entity body) if qop="auth-int" */ + Response /* request-digest or response-digest */ + ); + + new_response_value = utils->realloc(*response_value, HASHHEXLEN + 1); + if (new_response_value == NULL) { + free (*response_value); + *response_value = NULL; + return NULL; + } + *response_value = new_response_value; + + memcpy(*response_value, Response, HASHHEXLEN); + (*response_value)[HASHHEXLEN] = 0; + + } + + return result; +} + +static int make_client_response(context_t *text, + sasl_client_params_t *params, + sasl_out_params_t *oparams) +{ + client_context_t *ctext = (client_context_t *) text; + char *qop = NULL; + unsigned nbits = 0; + char *digesturi = NULL; + bool IsUTF8 = FALSE; + char ncvalue[10]; + char maxbufstr[64]; + char *response = NULL; + unsigned resplen = 0; + int result = SASL_OK; + cipher_free_t *old_cipher_free = NULL; + sasl_http_request_t rfc2831_request; + const sasl_http_request_t *request; + + params->utils->log(params->utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 make_client_response()"); + + if (oparams->mech_ssf > 1) { + /* Remember the old cipher free function (if any). + It will be called later, once we are absolutely + sure that authentication was successful. */ + old_cipher_free = text->cipher_free; + /* free the old cipher context first */ + } + + switch (ctext->protection) { + case DIGEST_PRIVACY: + qop = "auth-conf"; + oparams->encode = &digestmd5_encode; + oparams->decode = &digestmd5_decode; + oparams->mech_ssf = ctext->cipher->ssf; + + nbits = ctext->cipher->n; + text->cipher_enc = ctext->cipher->cipher_enc; + text->cipher_dec = ctext->cipher->cipher_dec; + text->cipher_free = ctext->cipher->cipher_free; + text->cipher_init = ctext->cipher->cipher_init; + break; + case DIGEST_INTEGRITY: + qop = "auth-int"; + oparams->encode = &digestmd5_encode; + oparams->decode = &digestmd5_decode; + oparams->mech_ssf = 1; + break; + case DIGEST_NOLAYER: + default: + qop = "auth"; + oparams->encode = NULL; + oparams->decode = NULL; + oparams->mech_ssf = 0; + } + + if (text->http_mode) { + /* per RFC 2617 (HTTP Request as set by calling application) */ + request = params->http_request; + } + else { + /* per RFC 2831 */ + digesturi = params->utils->malloc(strlen(params->service) + 1 + + strlen(params->serverFQDN) + 1 + + 1); + if (digesturi == NULL) { + result = SASL_NOMEM; + goto FreeAllocatedMem; + } + + /* allocated exactly this. safe */ + strcpy(digesturi, params->service); + strcat(digesturi, "/"); + strcat(digesturi, params->serverFQDN); + /* + * strcat (digesturi, "/"); strcat (digesturi, params->serverFQDN); + */ + + rfc2831_request.method = "AUTHENTICATE"; + rfc2831_request.uri = digesturi; + rfc2831_request.entity = NULL; + rfc2831_request.elen = 0; + rfc2831_request.non_persist = 0; + request = &rfc2831_request; + } + + /* response */ + response = + calculate_response(text, + params->utils, + ctext->algorithm, + (unsigned char *) oparams->authid, + (unsigned char *) text->realm, + text->nonce, + text->nonce_count, + text->cnonce, + qop, + request, + ctext->password, + strcmp(oparams->user, oparams->authid) ? + (unsigned char *) oparams->user : NULL, + &text->response_value); + + + resplen = 0; + if (text->out_buf) params->utils->free(text->out_buf); + text->out_buf = NULL; + text->out_buf_len = 0; + if (add_to_challenge(params->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "username", (unsigned char *) oparams->authid, + TRUE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllocatedMem; + } + + if (add_to_challenge(params->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "realm", (unsigned char *) text->realm, + TRUE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllocatedMem; + } + if (strcmp(oparams->user, oparams->authid)) { + if (add_to_challenge(params->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "authzid", (unsigned char *) oparams->user, TRUE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllocatedMem; + } + } + if (add_to_challenge(params->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "nonce", text->nonce, TRUE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllocatedMem; + } + if (add_to_challenge(params->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "cnonce", text->cnonce, TRUE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllocatedMem; + } + snprintf(ncvalue, sizeof(ncvalue), "%08x", text->nonce_count); + if (add_to_challenge(params->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "nc", (unsigned char *) ncvalue, FALSE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllocatedMem; + } + if (add_to_challenge(params->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "qop", (unsigned char *) qop, FALSE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllocatedMem; + } + if (ctext->cipher != NULL) { + if (add_to_challenge(params->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "cipher", + (unsigned char *) ctext->cipher->name, + FALSE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllocatedMem; + } + } + + if (params->props.maxbufsize) { + snprintf(maxbufstr, sizeof(maxbufstr), "%d", params->props.maxbufsize); + if (add_to_challenge(params->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "maxbuf", (unsigned char *) maxbufstr, + FALSE) != SASL_OK) { + SETERROR(params->utils, + "internal error: add_to_challenge maxbuf failed"); + goto FreeAllocatedMem; + } + } + + if (IsUTF8) { + if (add_to_challenge(params->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "charset", (unsigned char *) "utf-8", + FALSE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllocatedMem; + } + } + if (add_to_challenge(params->utils, + &text->out_buf, &text->out_buf_len, &resplen, + text->http_mode ? "uri" /* per RFC 2617 */ + : "digest-uri", /* per RFC 2831 */ + (unsigned char *) request->uri, + TRUE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllocatedMem; + } + if (text->http_mode) { + /* per RFC 2617: algorithm & opaque MUST be sent back to server */ + if (add_to_challenge(params->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "algorithm", (unsigned char *) ctext->algorithm, + FALSE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllocatedMem; + } + if (ctext->opaque) { + if (add_to_challenge(params->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "opaque", ctext->opaque, TRUE) != SASL_OK) { + result = SASL_FAIL; + goto FreeAllocatedMem; + } + } + } + if (add_to_challenge(params->utils, + &text->out_buf, &text->out_buf_len, &resplen, + "response", (unsigned char *) response, + FALSE) != SASL_OK) { + + result = SASL_FAIL; + goto FreeAllocatedMem; + } + + /* self check */ + if (strlen(text->out_buf) > 2048) { + result = SASL_FAIL; + goto FreeAllocatedMem; + } + + /* set oparams */ + oparams->maxoutbuf = ctext->server_maxbuf; + if(oparams->mech_ssf > 1) { + /* MAC block (privacy) */ + oparams->maxoutbuf -= 25; + } else if(oparams->mech_ssf == 1) { + /* MAC block (integrity) */ + oparams->maxoutbuf -= 16; + } + + text->seqnum = 0; /* for integrity/privacy */ + text->rec_seqnum = 0; /* for integrity/privacy */ + text->utils = params->utils; + + /* Free the old security layer, if any */ + if (old_cipher_free) old_cipher_free(text); + + /* used by layers */ + _plug_decode_init(&text->decode_context, text->utils, + params->props.maxbufsize ? params->props.maxbufsize : + DEFAULT_BUFSIZE); + + if (oparams->mech_ssf > 0) { + unsigned char enckey[16]; + unsigned char deckey[16]; + + create_layer_keys(text, params->utils, text->HA1, nbits, + enckey, deckey); + + /* initialize cipher if need be */ + if (text->cipher_init) { + text->cipher_init(text, enckey, deckey); + } + } + + result = SASL_OK; + + FreeAllocatedMem: + if (digesturi) params->utils->free(digesturi); + if (response) params->utils->free(response); + + return result; +} + +static int parse_server_challenge(client_context_t *ctext, + sasl_client_params_t *params, + const char *serverin, unsigned serverinlen, + char ***outrealms, int *noutrealm) +{ + context_t *text = (context_t *) ctext; + int result = SASL_OK; + char *in_start = NULL; + char *in = NULL; + char **realms = NULL; + int nrealm = 0; + sasl_ssf_t limit, musthave = 0; + sasl_ssf_t external; + int protection = 0; + int saw_qop = 0; + int ciphers = 0; + int maxbuf_count = 0; + bool IsUTF8 = FALSE; + int algorithm_count = 0; + int opaque_count = 0; + + params->utils->log(params->utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 parse_server_challenge()"); + + if (!serverin || !serverinlen) { + params->utils->seterror(params->utils->conn, 0, + "no server challenge"); + return SASL_FAIL; + } + + in_start = in = params->utils->malloc(serverinlen + 1); + if (in == NULL) return SASL_NOMEM; + + memcpy(in, serverin, serverinlen); + in[serverinlen] = 0; + + ctext->server_maxbuf = 65536; /* Default value for maxbuf */ + + /* create a new cnonce */ + text->cnonce = create_nonce(params->utils); + if (text->cnonce == NULL) { + params->utils->seterror(params->utils->conn, 0, + "failed to create cnonce"); + result = SASL_FAIL; + goto FreeAllocatedMem; + } + + /* parse the challenge */ + while (in[0] != '\0') { + char *name, *value; + + get_pair(&in, &name, &value); + + /* if parse error */ + if (name == NULL) { + params->utils->seterror(params->utils->conn, 0, "Parse error"); + result = SASL_BADAUTH; + goto FreeAllocatedMem; + } + + if (*name == '\0') { + break; + } + + if (strcasecmp(name, "realm") == 0) { + nrealm++; + + if(!realms) + realms = params->utils->malloc(sizeof(char *) * (nrealm + 1)); + else + realms = params->utils->realloc(realms, + sizeof(char *) * (nrealm + 1)); + + if (realms == NULL) { + result = SASL_NOMEM; + goto FreeAllocatedMem; + } + + _plug_strdup(params->utils, value, &realms[nrealm-1], NULL); + realms[nrealm] = NULL; + } else if (strcasecmp(name, "nonce") == 0) { + _plug_strdup(params->utils, value, (char **) &text->nonce, + NULL); + text->nonce_count = 1; + } else if (strcasecmp(name, "qop") == 0) { + saw_qop = 1; + while (value && *value) { + char *comma; + char *end_val; + +SKIP_SPACES_IN_QOP: + /* skipping spaces: */ + value = skip_lws(value); + if (*value == '\0') { + break; + } + + /* check for an extreme case when there is no data: LWSP ',' */ + if (*value == ',') { + value++; + goto SKIP_SPACES_IN_QOP; + } + + comma = strchr(value, ','); + + if (comma != NULL) { + *comma++ = '\0'; + } + + /* skip LWSP at the end of the value (if any), skip_r_lws returns pointer to + the first LWSP character, NUL (if there were none) or NULL if the value + is entirely from LWSP characters */ + end_val = skip_r_lws (value); + if (end_val == NULL) { + value = comma; + continue; + } else { + /* strip LWSP */ + *end_val = '\0'; + } + + if (strcasecmp(value, "auth-conf") == 0) { + protection |= DIGEST_PRIVACY; + } else if (strcasecmp(value, "auth-int") == 0) { + protection |= DIGEST_INTEGRITY; + } else if (strcasecmp(value, "auth") == 0) { + protection |= DIGEST_NOLAYER; + } else { + params->utils->log(params->utils->conn, SASL_LOG_DEBUG, + "Server supports unknown layer: %s\n", + value); + } + + value = comma; + } + } else if (strcasecmp(name, "cipher") == 0) { + while (value && *value) { + struct digest_cipher *cipher = available_ciphers; + char *comma; + char *end_val; + +SKIP_SPACES_IN_CIPHER: + /* skipping spaces: */ + value = skip_lws(value); + if (*value == '\0') { + break; + } + + /* check for an extreme case when there is no data: LWSP ',' */ + if (*value == ',') { + value++; + goto SKIP_SPACES_IN_CIPHER; + } + + comma = strchr(value, ','); + + if (comma != NULL) { + *comma++ = '\0'; + } + + /* skip LWSP at the end of the value, skip_r_lws returns pointer to + the first LWSP character or NULL */ + end_val = skip_r_lws (value); + if (end_val == NULL) { + value = comma; + continue; + } else { + /* strip LWSP */ + *end_val = '\0'; + } + + /* do we support this cipher? */ + while (cipher->name) { + if (!strcasecmp(value, cipher->name)) break; + cipher++; + } + if (cipher->name) { + ciphers |= cipher->flag; + } else { + params->utils->log(params->utils->conn, SASL_LOG_DEBUG, + "Server supports unknown cipher: %s\n", + value); + } + + value = comma; + } + } else if (strcasecmp(name, "stale") == 0 && ctext->password) { + /* clear any cached password */ + if (ctext->free_password) + _plug_free_secret(params->utils, &ctext->password); + ctext->password = NULL; + } else if (strcasecmp(name, "maxbuf") == 0) { + /* maxbuf A number indicating the size of the largest + * buffer the server is able to receive when using + * "auth-int". If this directive is missing, the default + * value is 65536. This directive may appear at most once; + * if multiple instances are present, the client should + * abort the authentication exchange. + */ + maxbuf_count++; + + if (maxbuf_count != 1) { + result = SASL_BADAUTH; + params->utils->seterror(params->utils->conn, 0, + "At least two maxbuf directives found. Authentication aborted"); + goto FreeAllocatedMem; + } + + if (str2ul32 (value, &ctext->server_maxbuf) == FALSE) { + result = SASL_BADAUTH; + params->utils->seterror(params->utils->conn, 0, + "Invalid maxbuf parameter received from server (%s)", value); + goto FreeAllocatedMem; + } + + if (ctext->server_maxbuf <= 16) { + result = SASL_BADAUTH; + params->utils->seterror(params->utils->conn, 0, + "Invalid maxbuf parameter received from server (too small: %s)", value); + goto FreeAllocatedMem; + } + + if (ctext->server_maxbuf > MAX_SASL_BUFSIZE) { + result = SASL_BADAUTH; + params->utils->seterror(params->utils->conn, 0, + "Invalid maxbuf parameter received from server (too big: %s)", value); + goto FreeAllocatedMem; + } + } else if (strcasecmp(name, "charset") == 0) { + if (strcasecmp(value, "utf-8") != 0) { + result = SASL_BADAUTH; + params->utils->seterror(params->utils->conn, 0, + "Charset must be UTF-8"); + goto FreeAllocatedMem; + } else { + IsUTF8 = TRUE; + } + } else if (strcasecmp(name,"algorithm")==0) { + if (text->http_mode && strcasecmp(value, "md5") == 0) { + /* per RFC 2617: need to support both "md5" and "md5-sess" */ + } + else if (strcasecmp(value, "md5-sess") != 0) + { + params->utils->seterror(params->utils->conn, 0, + "'algorithm' isn't 'md5-sess'"); + result = SASL_FAIL; + goto FreeAllocatedMem; + } + + if (text->http_mode) { + /* per RFC 2617: algorithm MUST be saved */ + _plug_strdup(params->utils, value, (char **) &ctext->algorithm, + NULL); + } + algorithm_count++; + if (algorithm_count > 1) + { + params->utils->seterror(params->utils->conn, 0, + "Must see 'algorithm' only once"); + result = SASL_FAIL; + goto FreeAllocatedMem; + } + } else if (strcasecmp(name,"opaque")==0) { + /* per RFC 2831: opaque MUST be ignored if received */ + if (text->http_mode) { + /* per RFC 2617: opaque MUST be saved */ + _plug_strdup(params->utils, value, (char **) &ctext->opaque, + NULL); + opaque_count++; + if (opaque_count > 1) + { + params->utils->seterror(params->utils->conn, 0, + "Must see 'opaque' only once"); + result = SASL_FAIL; + goto FreeAllocatedMem; + } + } + } else { + params->utils->log(params->utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 unrecognized pair %s/%s: ignoring", + name, value); + } + } + + if (protection == 0) { + /* From RFC 2831[bis]: + This directive is optional; if not present it defaults to "auth". */ + if (saw_qop == 0) { + protection = DIGEST_NOLAYER; + } else { + result = SASL_BADAUTH; + params->utils->seterror(params->utils->conn, 0, + "Server doesn't support any known qop level"); + goto FreeAllocatedMem; + } + } + + if (algorithm_count != 1) { + params->utils->seterror(params->utils->conn, 0, + "Must see 'algorithm' once. Didn't see at all"); + result = SASL_FAIL; + goto FreeAllocatedMem; + } + + /* make sure we have everything we require */ + if (text->nonce == NULL) { + params->utils->seterror(params->utils->conn, 0, + "Don't have nonce."); + result = SASL_FAIL; + goto FreeAllocatedMem; + } + + /* get requested ssf */ + external = params->external_ssf; + + /* what do we _need_? how much is too much? */ + if (!text->http_mode && /* HTTP Digest doesn't need buffer */ + params->props.maxbufsize == 0) { + musthave = 0; + limit = 0; + } else { + if (params->props.max_ssf > external) { + limit = params->props.max_ssf - external; + } else { + limit = 0; + } + if (params->props.min_ssf > external) { + musthave = params->props.min_ssf - external; + } else { + musthave = 0; + } + } + + /* we now go searching for an option that gives us at least "musthave" + and at most "limit" bits of ssf. */ + if ((limit > 1) && (protection & DIGEST_PRIVACY)) { + struct digest_cipher *cipher; + + /* let's find an encryption scheme that we like */ + cipher = available_ciphers; + while (cipher->name) { + /* examine each cipher we support, see if it meets our security + requirements, and see if the server supports it. + choose the best one of these */ + if ((limit >= cipher->ssf) && (musthave <= cipher->ssf) && + (ciphers & cipher->flag) && + (!ctext->cipher || (cipher->ssf > ctext->cipher->ssf))) { + ctext->cipher = cipher; + } + cipher++; + } + + if (ctext->cipher) { + /* we found a cipher we like */ + ctext->protection = DIGEST_PRIVACY; + } else { + /* we didn't find any ciphers we like */ + params->utils->seterror(params->utils->conn, 0, + "No good privacy layers"); + } + } + + if (ctext->cipher == NULL) { + /* we failed to find an encryption layer we liked; + can we use integrity or nothing? */ + + if ((limit >= 1) && (musthave <= 1) + && (protection & DIGEST_INTEGRITY)) { + /* integrity */ + ctext->protection = DIGEST_INTEGRITY; + } else if (musthave <= 0) { + /* no layer */ + ctext->protection = DIGEST_NOLAYER; + + /* See if server supports not having a layer */ + if ((protection & DIGEST_NOLAYER) != DIGEST_NOLAYER) { + params->utils->seterror(params->utils->conn, 0, + "Server doesn't support \"no layer\""); + result = SASL_FAIL; + goto FreeAllocatedMem; + } + } else { + params->utils->seterror(params->utils->conn, 0, + "Can't find an acceptable layer"); + result = SASL_TOOWEAK; + goto FreeAllocatedMem; + } + } + + *outrealms = realms; + *noutrealm = nrealm; + + FreeAllocatedMem: + if (in_start) params->utils->free(in_start); + + if (result != SASL_OK && realms) { + int lup; + + /* need to free all the realms */ + for (lup = 0;lup < nrealm; lup++) + params->utils->free(realms[lup]); + + params->utils->free(realms); + } + + return result; +} + +static int ask_user_info(client_context_t *ctext, + sasl_client_params_t *params, + char **realms, int nrealm, + sasl_interact_t **prompt_need, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *) ctext; + int result = SASL_OK; + const char *authid = NULL, *userid = NULL, *realm = NULL; + char *realm_chal = NULL; + int user_result = SASL_OK; + int auth_result = SASL_OK; + int pass_result = SASL_OK; + int realm_result = SASL_FAIL; + int i; + size_t len; + + params->utils->log(params->utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 ask_user_info()"); + + /* try to get the authid */ + if (oparams->authid == NULL) { + auth_result = _plug_get_authid(params->utils, &authid, prompt_need); + + if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT)) { + return auth_result; + } + } + + /* try to get the userid */ + if (oparams->user == NULL) { + user_result = _plug_get_userid(params->utils, &userid, prompt_need); + + if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) { + return user_result; + } + } + + /* try to get the password */ + if (ctext->password == NULL) { + pass_result = _plug_get_password(params->utils, &ctext->password, + &ctext->free_password, prompt_need); + if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT)) { + return pass_result; + } + } + + /* try to get the realm */ + if (text->realm == NULL) { + if (realms) { + if(nrealm == 1) { + /* only one choice */ + realm = realms[0]; + realm_result = SASL_OK; + } else { + /* ask the user */ + realm_result = _plug_get_realm(params->utils, + (const char **) realms, + (const char **) &realm, + prompt_need); + } + } + + /* fake the realm if we must */ + if ((realm_result != SASL_OK) && (realm_result != SASL_INTERACT)) { + if (params->serverFQDN) { + realm = params->serverFQDN; + } else { + return realm_result; + } + } + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + params->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if ((user_result == SASL_INTERACT) || (auth_result == SASL_INTERACT) || + (pass_result == SASL_INTERACT) || (realm_result == SASL_INTERACT)) { + + /* make our default realm */ + if (realm_result == SASL_INTERACT) { + if (realms) { + len = strlen(REALM_CHAL_PREFIX); + for (i = 0; i < nrealm; i++) { + len += strlen(realms[i]) + 4 /* " {}," */; + } + realm_chal = params->utils->malloc(len + 1); + strcpy (realm_chal, REALM_CHAL_PREFIX); + for (i = 0; i < nrealm; i++) { + strcat (realm_chal, " {"); + strcat (realm_chal, realms[i]); + strcat (realm_chal, "},"); + } + /* Replace the terminating comma with dot */ + realm_chal[len-1] = '.'; + + } else if (params->serverFQDN) { + realm_chal = params->utils->malloc(3+strlen(params->serverFQDN)); + if (realm_chal) { + sprintf(realm_chal, "{%s}", params->serverFQDN); + } else { + return SASL_NOMEM; + } + } + } + + /* make the prompt list */ + result = + _plug_make_prompts(params->utils, prompt_need, + user_result == SASL_INTERACT ? + "Please enter your authorization name" : NULL, + NULL, + auth_result == SASL_INTERACT ? + "Please enter your authentication name" : NULL, + NULL, + pass_result == SASL_INTERACT ? + "Please enter your password" : NULL, NULL, + NULL, NULL, NULL, + realm_chal ? realm_chal : "{}", + realm_result == SASL_INTERACT ? + "Please enter your realm" : NULL, + params->serverFQDN ? params->serverFQDN : NULL); + + if (result == SASL_OK) return SASL_INTERACT; + + return result; + } + + if (oparams->authid == NULL) { + if (!userid || !*userid) { + result = params->canon_user(params->utils->conn, authid, 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, + oparams); + } + else { + result = params->canon_user(params->utils->conn, + authid, 0, SASL_CU_AUTHID, oparams); + if (result != SASL_OK) return result; + + result = params->canon_user(params->utils->conn, + userid, 0, SASL_CU_AUTHZID, oparams); + } + if (result != SASL_OK) return result; + } + + /* Get an allocated version of the realm into the structure */ + if (realm && text->realm == NULL) { + _plug_strdup(params->utils, realm, (char **) &text->realm, NULL); + } + + return result; +} + +static int digestmd5_client_mech_new(void *glob_context, + sasl_client_params_t * params, + void **conn_context) +{ + context_t *text; + + if ((params->flags & SASL_NEED_HTTP) && !params->http_request) { + SETERROR(params->utils, + "DIGEST-MD5 unavailable due to lack of HTTP request"); + return SASL_BADPARAM; + } + + /* holds state are in -- allocate client size */ + text = params->utils->malloc(sizeof(client_context_t)); + if (text == NULL) + return SASL_NOMEM; + memset(text, 0, sizeof(client_context_t)); + + text->state = 1; + text->i_am = CLIENT; + text->http_mode = (params->flags & SASL_NEED_HTTP); + text->reauth = ((digest_glob_context_t *) glob_context)->reauth; + + *conn_context = text; + + return SASL_OK; +} + +static int +digestmd5_client_mech_step1(client_context_t *ctext, + sasl_client_params_t *params, + const char *serverin __attribute__((unused)), + unsigned serverinlen __attribute__((unused)), + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *) ctext; + int result = SASL_FAIL; + unsigned val; + + params->utils->log(params->utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 client step 1"); + + result = ask_user_info(ctext, params, NULL, 0, prompt_need, oparams); + if (result != SASL_OK) return result; + + /* check if we have cached info for this user on this server */ + val = hash(params->serverFQDN) % text->reauth->size; + if (params->utils->mutex_lock(text->reauth->mutex) == SASL_OK) { /* LOCK */ + if (text->reauth->e[val].u.c.serverFQDN && + !strcasecmp(text->reauth->e[val].u.c.serverFQDN, + params->serverFQDN) && + !strcmp(text->reauth->e[val].authid, oparams->authid)) { + + /* we have info, so use it */ + if (text->realm) params->utils->free(text->realm); + _plug_strdup(params->utils, text->reauth->e[val].realm, + &text->realm, NULL); + _plug_strdup(params->utils, (char *) text->reauth->e[val].nonce, + (char **) &text->nonce, NULL); + text->nonce_count = ++text->reauth->e[val].nonce_count; + _plug_strdup(params->utils, (char *) text->reauth->e[val].cnonce, + (char **) &text->cnonce, NULL); + if (text->http_mode) { + /* per RFC 2617: algorithm & opaque MUST be sent back to server */ + _plug_strdup(params->utils, + (char *) text->reauth->e[val].u.c.algorithm, + (char **) &ctext->algorithm, NULL); + if (text->reauth->e[val].u.c.opaque) { + _plug_strdup(params->utils, + (char *) text->reauth->e[val].u.c.opaque, + (char **) &ctext->opaque, NULL); + } + } + ctext->protection = text->reauth->e[val].u.c.protection; + ctext->cipher = text->reauth->e[val].u.c.cipher; + ctext->server_maxbuf = text->reauth->e[val].u.c.server_maxbuf; + } + params->utils->mutex_unlock(text->reauth->mutex); /* UNLOCK */ + } + + if (!text->nonce) { + /* we don't have any reauth info, so just return + * that there is no initial client send */ + text->state = 2; + return SASL_CONTINUE; + } + + /* + * (username | realm | nonce | cnonce | nonce-count | qop digest-uri | + * response | maxbuf | charset | auth-param ) + */ + + result = make_client_response(text, params, oparams); + if (result != SASL_OK) return result; + + *clientoutlen = (unsigned) strlen(text->out_buf); + *clientout = text->out_buf; + + text->state = 3; + return SASL_CONTINUE; +} + +static int digestmd5_client_mech_step2(client_context_t *ctext, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *) ctext; + int result = SASL_FAIL; + char **realms = NULL; + int nrealm = 0; + + params->utils->log(params->utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 client step 2"); + + if (params->props.min_ssf > params->props.max_ssf) { + return SASL_BADPARAM; + } + + /* don't bother parsing the challenge more than once */ + if (text->nonce == NULL) { + result = parse_server_challenge(ctext, params, serverin, serverinlen, + &realms, &nrealm); + if (result != SASL_OK) goto FreeAllocatedMem; + + if (nrealm == 1) { + /* only one choice! */ + text->realm = realms[0]; + + /* free realms */ + params->utils->free(realms); + realms = NULL; + } else { + /* Save realms for later use */ + text->realms = realms; + text->realm_cnt = nrealm; + } + } else { + /* Restore the list of realms */ + realms = text->realms; + nrealm = text->realm_cnt; + } + + result = ask_user_info(ctext, params, realms, nrealm, + prompt_need, oparams); + if (result != SASL_OK) goto FreeAllocatedMem; + + /* + * (username | realm | nonce | cnonce | nonce-count | qop | digest-uri | + * response | maxbuf | charset | auth-param ) + */ + + result = make_client_response(text, params, oparams); + if (result != SASL_OK) goto FreeAllocatedMem; + + *clientoutlen = (unsigned) strlen(text->out_buf); + *clientout = text->out_buf; + + text->state = 3; + + result = SASL_CONTINUE; + + FreeAllocatedMem: + return result; +} + +static int +digestmd5_client_mech_step3(client_context_t *ctext, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need __attribute__((unused)), + const char **clientout __attribute__((unused)), + unsigned *clientoutlen __attribute__((unused)), + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *) ctext; + char *in = NULL; + char *in_start; + int result = SASL_FAIL; + + params->utils->log(params->utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 client step 3"); + + /* Verify that server is really what he claims to be */ + in_start = in = params->utils->malloc(serverinlen + 1); + if (in == NULL) return SASL_NOMEM; + + memcpy(in, serverin, serverinlen); + in[serverinlen] = 0; + + /* parse the response */ + while (in[0] != '\0') { + char *name, *value; + get_pair(&in, &name, &value); + + if (name == NULL) { + params->utils->seterror(params->utils->conn, 0, + "DIGEST-MD5 Received Garbage"); + result = SASL_BADAUTH; + break; + } + + if (*name == '\0') { + break; + } + + if (strcasecmp(name, "rspauth") == 0) { + + if (strcmp(text->response_value, value) != 0) { + params->utils->seterror(params->utils->conn, 0, + "DIGEST-MD5: This server wants us to believe that he knows shared secret"); + result = SASL_BADSERV; + } else { + oparams->doneflag = 1; + oparams->param_version = 0; + + result = SASL_OK; + } + break; + } else { + params->utils->log(params->utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 unrecognized pair %s/%s: ignoring", + name, value); + } + } + + params->utils->free(in_start); + + if (params->utils->mutex_lock(text->reauth->mutex) == SASL_OK) { /* LOCK */ + unsigned val = hash(params->serverFQDN) % text->reauth->size; + switch (result) { + case SASL_OK: + if (text->nonce_count == 1) { + /* successful initial auth, setup for future reauth */ + clear_reauth_entry(&text->reauth->e[val], CLIENT, params->utils); + _plug_strdup(params->utils, oparams->authid, + &text->reauth->e[val].authid, NULL); + text->reauth->e[val].realm = text->realm; text->realm = NULL; + text->reauth->e[val].nonce = text->nonce; text->nonce = NULL; + text->reauth->e[val].nonce_count = text->nonce_count; + text->reauth->e[val].cnonce = text->cnonce; text->cnonce = NULL; + _plug_strdup(params->utils, params->serverFQDN, + &text->reauth->e[val].u.c.serverFQDN, NULL); + if (text->http_mode) { + /* per RFC 2617: algorithm & opaque MUST be saved */ + text->reauth->e[val].u.c.algorithm = ctext->algorithm; + ctext->algorithm = NULL; + text->reauth->e[val].u.c.opaque = ctext->opaque; + ctext->opaque = NULL; + } + text->reauth->e[val].u.c.protection = ctext->protection; + text->reauth->e[val].u.c.cipher = ctext->cipher; + text->reauth->e[val].u.c.server_maxbuf = ctext->server_maxbuf; + } + else { + /* reauth, we already incremented nonce_count */ + } + break; + default: + if (text->nonce_count > 1) { + /* failed reauth, clear cache */ + clear_reauth_entry(&text->reauth->e[val], CLIENT, params->utils); + } + else { + /* failed initial auth, leave existing cache */ + } + } + params->utils->mutex_unlock(text->reauth->mutex); /* UNLOCK */ + } + + return result; +} + +static int digestmd5_client_mech_step(void *conn_context, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *) conn_context; + client_context_t *ctext = (client_context_t *) conn_context; + unsigned val = hash(params->serverFQDN) % text->reauth->size; + + if (serverinlen > 2048) return SASL_BADPROT; + + *clientout = NULL; + *clientoutlen = 0; + + switch (text->state) { + + case 1: + if (!serverin) { + /* here's where we attempt fast reauth if possible */ + int reauth = 0; + + /* check if we have saved info for this server */ + if (params->utils->mutex_lock(text->reauth->mutex) == SASL_OK) { /* LOCK */ + reauth = text->reauth->e[val].u.c.serverFQDN && + !strcasecmp(text->reauth->e[val].u.c.serverFQDN, + params->serverFQDN); + params->utils->mutex_unlock(text->reauth->mutex); /* UNLOCK */ + } + if (reauth) { + return digestmd5_client_mech_step1(ctext, params, + serverin, serverinlen, + prompt_need, + clientout, clientoutlen, + oparams); + } + else { + /* we don't have any reauth info, so just return + * that there is no initial client send */ + text->state = 2; + return SASL_CONTINUE; + } + } + + /* fall through and respond to challenge */ + + case 3: + if (serverin && !strncasecmp(serverin, "rspauth=", 8)) { + return digestmd5_client_mech_step3(ctext, params, + serverin, serverinlen, + prompt_need, + clientout, clientoutlen, + oparams); + } + + /* fall through and respond to challenge */ + text->state = 2; + + /* cleanup after a failed reauth attempt */ + if (params->utils->mutex_lock(text->reauth->mutex) == SASL_OK) { /* LOCK */ + clear_reauth_entry(&text->reauth->e[val], CLIENT, params->utils); + + params->utils->mutex_unlock(text->reauth->mutex); /* UNLOCK */ + } + + if (text->realm) params->utils->free(text->realm); + if (text->nonce) params->utils->free(text->nonce); + if (text->cnonce) params->utils->free(text->cnonce); + text->realm = NULL; + text->nonce = text->cnonce = NULL; + ctext->cipher = NULL; + + case 2: + return digestmd5_client_mech_step2(ctext, params, + serverin, serverinlen, + prompt_need, + clientout, clientoutlen, + oparams); + + default: + params->utils->log(NULL, SASL_LOG_ERR, + "Invalid DIGEST-MD5 client step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static void digestmd5_client_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + client_context_t *ctext = (client_context_t *) conn_context; + + if (!ctext || !utils) return; + + utils->log(utils->conn, SASL_LOG_DEBUG, + "DIGEST-MD5 client mech dispose"); + + if (ctext->free_password) _plug_free_secret(utils, &ctext->password); + + digestmd5_common_mech_dispose(conn_context, utils); +} + +static sasl_client_plug_t digestmd5_client_plugins[] = +{ + { + "DIGEST-MD5", +#ifdef WITH_RC4 /* mech_name */ + 128, /* max ssf */ +#elif defined(WITH_DES) + 112, +#else + 1, +#endif + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS + | SASL_SEC_MUTUAL_AUTH, /* security_flags */ + SASL_FEAT_NEEDSERVERFQDN + | SASL_FEAT_ALLOWS_PROXY + | SASL_FEAT_SUPPORTS_HTTP, /* features */ + NULL, /* required_prompts */ + &client_glob_context, /* glob_context */ + &digestmd5_client_mech_new, /* mech_new */ + &digestmd5_client_mech_step, /* mech_step */ + &digestmd5_client_mech_dispose, /* mech_dispose */ + &digestmd5_common_mech_free, /* mech_free */ + NULL, /* idle */ + NULL, /* spare1 */ + NULL /* spare2 */ + } +}; + +int digestmd5_client_plug_init(sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount) +{ + reauth_cache_t *reauth_cache; + + if (maxversion < SASL_CLIENT_PLUG_VERSION) + return SASL_BADVERS; + + /* reauth cache */ + reauth_cache = utils->malloc(sizeof(reauth_cache_t)); + if (reauth_cache == NULL) + return SASL_NOMEM; + memset(reauth_cache, 0, sizeof(reauth_cache_t)); + reauth_cache->i_am = CLIENT; + + /* mutex */ + reauth_cache->mutex = utils->mutex_alloc(); + if (!reauth_cache->mutex) + return SASL_FAIL; + + /* entries */ + reauth_cache->size = 10; + reauth_cache->e = utils->malloc(reauth_cache->size * + sizeof(reauth_entry_t)); + if (reauth_cache->e == NULL) + return SASL_NOMEM; + memset(reauth_cache->e, 0, reauth_cache->size * sizeof(reauth_entry_t)); + + ((digest_glob_context_t *) digestmd5_client_plugins[0].glob_context)->reauth = reauth_cache; + + *out_version = SASL_CLIENT_PLUG_VERSION; + *pluglist = digestmd5_client_plugins; + *plugcount = 1; + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/digestmd5_init.c b/libs/cyrussasl/plugins/digestmd5_init.c new file mode 100644 index 00000000..25c4356a --- /dev/null +++ b/libs/cyrussasl/plugins/digestmd5_init.c @@ -0,0 +1,43 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_CLIENT_PLUG_INIT( digestmd5 ) +SASL_SERVER_PLUG_INIT( digestmd5 ) + diff --git a/libs/cyrussasl/plugins/gs2.c b/libs/cyrussasl/plugins/gs2.c new file mode 100644 index 00000000..42d29c97 --- /dev/null +++ b/libs/cyrussasl/plugins/gs2.c @@ -0,0 +1,1851 @@ +/* + * Copyright (c) 2010, JANET(UK) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of JANET(UK) nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include + +#ifndef KRB5_HEIMDAL +#ifdef HAVE_GSSAPI_GSSAPI_EXT_H +#include +#endif +#endif + +#include +#include +#include +#include +#include + +#include "plugin_common.h" + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include +#include "gs2_token.h" + +#define GS2_CB_FLAG_MASK 0x0F +#define GS2_CB_FLAG_N 0x00 +#define GS2_CB_FLAG_P 0x01 +#define GS2_CB_FLAG_Y 0x02 +#define GS2_NONSTD_FLAG 0x10 + +typedef struct context { + gss_ctx_id_t gss_ctx; + gss_name_t client_name; + gss_name_t server_name; + gss_cred_id_t server_creds; + gss_cred_id_t client_creds; + char *out_buf; + unsigned out_buf_len; + const sasl_utils_t *utils; + char *authid; + char *authzid; + union { + sasl_client_plug_t *client; + sasl_server_plug_t *server; + } plug; + gss_OID mechanism; + int gs2_flags; + char *cbindingname; + struct gss_channel_bindings_struct gss_cbindings; + sasl_secret_t *password; + unsigned int free_password; + OM_uint32 lifetime; +} context_t; + +static gss_OID_set gs2_mechs = GSS_C_NO_OID_SET; + +static int gs2_get_init_creds(context_t *context, + sasl_client_params_t *params, + sasl_interact_t **prompt_need, + sasl_out_params_t *oparams); + +static int gs2_verify_initial_message(context_t *text, + sasl_server_params_t *sparams, + const char *in, + unsigned inlen, + gss_buffer_t token); + +static int gs2_make_header(context_t *text, + sasl_client_params_t *cparams, + const char *authzid, + char **out, + unsigned *outlen); + +static int gs2_make_message(context_t *text, + sasl_client_params_t *cparams, + int initialContextToken, + gss_buffer_t token, + char **out, + unsigned *outlen); + +static int gs2_get_mech_attrs(const sasl_utils_t *utils, + const gss_OID mech, + unsigned int *security_flags, + unsigned int *features, + const unsigned long **prompts); + +static int gs2_indicate_mechs(const sasl_utils_t *utils); + +static int gs2_map_sasl_name(const sasl_utils_t *utils, + const char *mech, + gss_OID *oid); + +static int gs2_duplicate_buffer(const sasl_utils_t *utils, + const gss_buffer_t src, + gss_buffer_t dst); + +static int gs2_unescape_authzid(const sasl_utils_t *utils, + char **in, + unsigned *inlen, + char **authzid); + +static int gs2_escape_authzid(const sasl_utils_t *utils, + const char *in, + unsigned inlen, + char **authzid); + +/* sasl_gs_log: only logs status string returned from gss_display_status() */ +#define sasl_gs2_log(x,y,z) sasl_gs2_seterror_(x,y,z,1) +#define sasl_gs2_seterror(x,y,z) sasl_gs2_seterror_(x,y,z,0) + +static int +sasl_gs2_seterror_(const sasl_utils_t *utils, OM_uint32 maj, OM_uint32 min, + int logonly); + +static context_t * +sasl_gs2_new_context(const sasl_utils_t *utils) +{ + context_t *ret; + + ret = utils->malloc(sizeof(context_t)); + if (ret == NULL) + return NULL; + + memset(ret, 0, sizeof(context_t)); + ret->utils = utils; + + return ret; +} + +static int +sasl_gs2_free_context_contents(context_t *text) +{ + OM_uint32 min_stat; + + if (text == NULL) + return SASL_OK; + + if (text->gss_ctx != GSS_C_NO_CONTEXT) { + gss_delete_sec_context(&min_stat,&text->gss_ctx, + GSS_C_NO_BUFFER); + text->gss_ctx = GSS_C_NO_CONTEXT; + } + + if (text->client_name != GSS_C_NO_NAME) { + gss_release_name(&min_stat,&text->client_name); + text->client_name = GSS_C_NO_NAME; + } + + if (text->server_name != GSS_C_NO_NAME) { + gss_release_name(&min_stat,&text->server_name); + text->server_name = GSS_C_NO_NAME; + } + + if (text->server_creds != GSS_C_NO_CREDENTIAL) { + gss_release_cred(&min_stat, &text->server_creds); + text->server_creds = GSS_C_NO_CREDENTIAL; + } + + if (text->client_creds != GSS_C_NO_CREDENTIAL) { + gss_release_cred(&min_stat, &text->client_creds); + text->client_creds = GSS_C_NO_CREDENTIAL; + } + + if (text->authid != NULL) { + text->utils->free(text->authid); + text->authid = NULL; + } + + if (text->authzid != NULL) { + text->utils->free(text->authzid); + text->authzid = NULL; + } + + gss_release_buffer(&min_stat, &text->gss_cbindings.application_data); + + if (text->out_buf != NULL) { + text->utils->free(text->out_buf); + text->out_buf = NULL; + } + + text->out_buf_len = 0; + + if (text->cbindingname != NULL) { + text->utils->free(text->cbindingname); + text->cbindingname = NULL; + } + + if (text->free_password) + _plug_free_secret(text->utils, &text->password); + + memset(text, 0, sizeof(*text)); + + return SASL_OK; +} + +static void +gs2_common_mech_dispose(void *conn_context, const sasl_utils_t *utils) +{ + sasl_gs2_free_context_contents((context_t *)(conn_context)); + utils->free(conn_context); +} + +static void +gs2_common_mech_free(void *global_context __attribute__((unused)), + const sasl_utils_t *utils) +{ + OM_uint32 minor; + + if (gs2_mechs != GSS_C_NO_OID_SET) { + gss_release_oid_set(&minor, &gs2_mechs); + gs2_mechs = GSS_C_NO_OID_SET; + } +} + +/***************************** Server Section *****************************/ + +static int +gs2_server_mech_new(void *glob_context, + sasl_server_params_t *params, + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + void **conn_context) +{ + context_t *text; + int ret; + + text = sasl_gs2_new_context(params->utils); + if (text == NULL) { + MEMERROR(params->utils); + return SASL_NOMEM; + } + + text->gss_ctx = GSS_C_NO_CONTEXT; + text->client_name = GSS_C_NO_NAME; + text->server_name = GSS_C_NO_NAME; + text->server_creds = GSS_C_NO_CREDENTIAL; + text->client_creds = GSS_C_NO_CREDENTIAL; + text->plug.server = glob_context; + + ret = gs2_map_sasl_name(params->utils, text->plug.server->mech_name, + &text->mechanism); + if (ret != SASL_OK) { + gs2_common_mech_dispose(text, params->utils); + return ret; + } + + *conn_context = text; + + return SASL_OK; +} + +static int +gs2_server_mech_step(void *conn_context, + sasl_server_params_t *params, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *)conn_context; + gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; + OM_uint32 maj_stat = GSS_S_FAILURE, min_stat = 0; + gss_buffer_desc name_buf = GSS_C_EMPTY_BUFFER; + gss_buffer_desc short_name_buf = GSS_C_EMPTY_BUFFER; + gss_name_t without = GSS_C_NO_NAME; + gss_OID_set_desc mechs; + OM_uint32 out_flags = 0; + int ret = SASL_OK, equal = 0; + int initialContextToken = (text->gss_ctx == GSS_C_NO_CONTEXT); + char *p; + + if (serverout == NULL) { + PARAMERROR(text->utils); + return SASL_BADPARAM; + } + + *serverout = NULL; + *serveroutlen = 0; + + if (initialContextToken) { + name_buf.length = strlen(params->service) + 1 + strlen(params->serverFQDN); + name_buf.value = params->utils->malloc(name_buf.length + 1); + if (name_buf.value == NULL) { + MEMERROR(text->utils); + ret = SASL_NOMEM; + goto cleanup; + } + snprintf(name_buf.value, name_buf.length + 1, + "%s@%s", params->service, params->serverFQDN); + maj_stat = gss_import_name(&min_stat, + &name_buf, + GSS_C_NT_HOSTBASED_SERVICE, + &text->server_name); + params->utils->free(name_buf.value); + name_buf.value = NULL; + + if (GSS_ERROR(maj_stat)) + goto cleanup; + + assert(text->server_creds == GSS_C_NO_CREDENTIAL); + + mechs.count = 1; + mechs.elements = (gss_OID)text->mechanism; + + if (params->gss_creds == GSS_C_NO_CREDENTIAL) { + maj_stat = gss_acquire_cred(&min_stat, + text->server_name, + GSS_C_INDEFINITE, + &mechs, + GSS_C_ACCEPT, + &text->server_creds, + NULL, + &text->lifetime); + if (GSS_ERROR(maj_stat)) + goto cleanup; + } + + ret = gs2_verify_initial_message(text, + params, + clientin, + clientinlen, + &input_token); + if (ret != SASL_OK) + goto cleanup; + } else { + input_token.value = (void *)clientin; + input_token.length = clientinlen; + } + + maj_stat = gss_accept_sec_context(&min_stat, + &text->gss_ctx, + (params->gss_creds != GSS_C_NO_CREDENTIAL) + ? (gss_cred_id_t)params->gss_creds + : text->server_creds, + &input_token, + &text->gss_cbindings, + &text->client_name, + NULL, + &output_token, + &out_flags, + &text->lifetime, + &text->client_creds); + if (GSS_ERROR(maj_stat)) { + sasl_gs2_log(text->utils, maj_stat, min_stat); + text->utils->seterror(text->utils->conn, SASL_NOLOG, + "GS2 Failure: gss_accept_sec_context"); + ret = (maj_stat == GSS_S_BAD_BINDINGS) ? SASL_BADBINDING : SASL_BADAUTH; + goto cleanup; + } + + *serveroutlen = output_token.length; + if (output_token.value != NULL) { + ret = _plug_buf_alloc(text->utils, &text->out_buf, + &text->out_buf_len, *serveroutlen); + if (ret != SASL_OK) + goto cleanup; + memcpy(text->out_buf, output_token.value, *serveroutlen); + *serverout = text->out_buf; + } else { + /* No output token, send an empty string */ + *serverout = ""; + serveroutlen = 0; + } + + if (maj_stat == GSS_S_CONTINUE_NEEDED) { + ret = SASL_CONTINUE; + goto cleanup; + } + + assert(maj_stat == GSS_S_COMPLETE); + + if ((out_flags & GSS_C_SEQUENCE_FLAG) == 0) { + ret = SASL_BADAUTH; + goto cleanup; + } + + maj_stat = gss_display_name(&min_stat, text->client_name, + &name_buf, NULL); + if (GSS_ERROR(maj_stat)) + goto cleanup; + + ret = gs2_duplicate_buffer(params->utils, &name_buf, &short_name_buf); + if (ret != 0) + goto cleanup; + + p = (char *)memchr(name_buf.value, '@', name_buf.length); + if (p != NULL) { + short_name_buf.length = (p - (char *)name_buf.value); + + maj_stat = gss_import_name(&min_stat, + &short_name_buf, + GSS_C_NT_USER_NAME, + &without); + if (GSS_ERROR(maj_stat)) { + goto cleanup; + } + + maj_stat = gss_compare_name(&min_stat, text->client_name, + without, &equal); + if (GSS_ERROR(maj_stat)) { + goto cleanup; + } + + if (equal) + ((char *)short_name_buf.value)[short_name_buf.length] = '\0'; + } + + text->authid = (char *)short_name_buf.value; + short_name_buf.value = NULL; + short_name_buf.length = 0; + + if (text->authzid != NULL) { + ret = params->canon_user(params->utils->conn, + text->authzid, 0, + SASL_CU_AUTHZID, oparams); + if (ret != SASL_OK) { + goto cleanup; + } + } + + ret = params->canon_user(params->utils->conn, + text->authid, 0, + text->authzid == NULL + ? (SASL_CU_AUTHZID | SASL_CU_AUTHID) + : SASL_CU_AUTHID, + oparams); + if (ret != SASL_OK) { + goto cleanup; + } + + switch (text->gs2_flags & GS2_CB_FLAG_MASK) { + case GS2_CB_FLAG_N: + oparams->cbindingdisp = SASL_CB_DISP_NONE; + break; + case GS2_CB_FLAG_P: + oparams->cbindingdisp = SASL_CB_DISP_USED; + oparams->cbindingname = text->cbindingname; + break; + case GS2_CB_FLAG_Y: + oparams->cbindingdisp = SASL_CB_DISP_WANT; + break; + } + + if (text->client_creds != GSS_C_NO_CREDENTIAL) + oparams->client_creds = &text->client_creds; + else + oparams->client_creds = NULL; + + oparams->gss_peer_name = text->client_name; + oparams->gss_local_name = text->server_name; + oparams->maxoutbuf = 0xFFFFFF; + oparams->encode = NULL; + oparams->decode = NULL; + oparams->mech_ssf = 0; + oparams->doneflag = 1; + + ret = SASL_OK; + +cleanup: + if (ret == SASL_OK && maj_stat != GSS_S_COMPLETE) { + sasl_gs2_seterror(text->utils, maj_stat, min_stat); + ret = SASL_FAIL; + } + + if (initialContextToken) { + gss_release_buffer(&min_stat, &input_token); + } + gss_release_buffer(&min_stat, &name_buf); + gss_release_buffer(&min_stat, &short_name_buf); + gss_release_buffer(&min_stat, &output_token); + gss_release_name(&min_stat, &without); + + if (ret < SASL_OK) { + sasl_gs2_free_context_contents(text); + } + + return ret; +} + +static int +gs2_common_plug_init(const sasl_utils_t *utils, + size_t plugsize, + int (*plug_alloc)(const sasl_utils_t *, + void *, + const gss_buffer_t, + const gss_OID), + void **pluglist, + int *plugcount) +{ + OM_uint32 major, minor; + size_t i, count = 0; + void *plugs = NULL; + + *pluglist = NULL; + *plugcount = 0; + + if (gs2_indicate_mechs(utils) != SASL_OK) { + return SASL_NOMECH; + } + + plugs = utils->malloc(gs2_mechs->count * plugsize); + if (plugs == NULL) { + MEMERROR(utils); + return SASL_NOMEM; + } + memset(plugs, 0, gs2_mechs->count * plugsize); + + for (i = 0; i < gs2_mechs->count; i++) { + gss_buffer_desc sasl_mech_name = GSS_C_EMPTY_BUFFER; + + major = gss_inquire_saslname_for_mech(&minor, + &gs2_mechs->elements[i], + &sasl_mech_name, + GSS_C_NO_BUFFER, + GSS_C_NO_BUFFER); + if (GSS_ERROR(major)) + continue; + +#define PLUG_AT(index) (void *)((unsigned char *)plugs + (count * plugsize)) + + if (plug_alloc(utils, PLUG_AT(count), &sasl_mech_name, + &gs2_mechs->elements[i]) == SASL_OK) + count++; + + gss_release_buffer(&minor, &sasl_mech_name); + } + + if (count == 0) { + utils->free(plugs); + return SASL_NOMECH; + } + + *pluglist = plugs; + *plugcount = count; + + return SASL_OK; +} + +static int +gs2_server_plug_alloc(const sasl_utils_t *utils, + void *plug, + gss_buffer_t sasl_name, + gss_OID mech) +{ + int ret; + sasl_server_plug_t *splug = (sasl_server_plug_t *)plug; + gss_buffer_desc buf; + + memset(splug, 0, sizeof(*splug)); + + ret = gs2_get_mech_attrs(utils, mech, + &splug->security_flags, + &splug->features, + NULL); + if (ret != SASL_OK) + return ret; + + ret = gs2_duplicate_buffer(utils, sasl_name, &buf); + if (ret != SASL_OK) + return ret; + + splug->mech_name = (char *)buf.value; + splug->glob_context = plug; + splug->mech_new = gs2_server_mech_new; + splug->mech_step = gs2_server_mech_step; + splug->mech_dispose = gs2_common_mech_dispose; + splug->mech_free = gs2_common_mech_free; + + return SASL_OK; +} + +static sasl_server_plug_t *gs2_server_plugins; +static int gs2_server_plugcount; + +int +gs2_server_plug_init(const sasl_utils_t *utils, + int maxversion, + int *outversion, + sasl_server_plug_t **pluglist, + int *plugcount) +{ + int ret; + + *pluglist = NULL; + *plugcount = 0; + + if (maxversion < SASL_SERVER_PLUG_VERSION) + return SASL_BADVERS; + + *outversion = SASL_SERVER_PLUG_VERSION; + + if (gs2_server_plugins == NULL) { + ret = gs2_common_plug_init(utils, + sizeof(sasl_server_plug_t), + gs2_server_plug_alloc, + (void **)&gs2_server_plugins, + &gs2_server_plugcount); + if (ret != SASL_OK) + return ret; + } + + *pluglist = gs2_server_plugins; + *plugcount = gs2_server_plugcount; + + return SASL_OK; +} + +/***************************** Client Section *****************************/ + +static int gs2_client_mech_step(void *conn_context, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *)conn_context; + gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; + gss_buffer_desc name_buf = GSS_C_EMPTY_BUFFER; + OM_uint32 maj_stat = GSS_S_FAILURE, min_stat = 0; + OM_uint32 req_flags, ret_flags; + int ret = SASL_FAIL; + int initialContextToken; + + *clientout = NULL; + *clientoutlen = 0; + + if (text->gss_ctx == GSS_C_NO_CONTEXT) { + ret = gs2_get_init_creds(text, params, prompt_need, oparams); + if (ret != SASL_OK) { + goto cleanup; + } + + initialContextToken = 1; + } else { + initialContextToken = 0; + } + + if (text->server_name == GSS_C_NO_NAME) { /* only once */ + name_buf.length = strlen(params->service) + 1 + strlen(params->serverFQDN); + name_buf.value = params->utils->malloc(name_buf.length + 1); + if (name_buf.value == NULL) { + ret = SASL_NOMEM; + goto cleanup; + } + if (params->serverFQDN == NULL || + strlen(params->serverFQDN) == 0) { + SETERROR(text->utils, "GS2 Failure: no serverFQDN"); + ret = SASL_FAIL; + goto cleanup; + } + + snprintf(name_buf.value, name_buf.length + 1, + "%s@%s", params->service, params->serverFQDN); + + maj_stat = gss_import_name(&min_stat, + &name_buf, + GSS_C_NT_HOSTBASED_SERVICE, + &text->server_name); + params->utils->free(name_buf.value); + name_buf.value = NULL; + + if (GSS_ERROR(maj_stat)) { + ret = SASL_OK; + goto cleanup; + } + } + + /* From GSSAPI plugin: apparently this is for some IMAP bug workaround */ + if (serverinlen == 0 && text->gss_ctx != GSS_C_NO_CONTEXT) { + gss_delete_sec_context(&min_stat, &text->gss_ctx, GSS_C_NO_BUFFER); + text->gss_ctx = GSS_C_NO_CONTEXT; + } + + input_token.value = (void *)serverin; + input_token.length = serverinlen; + + if (initialContextToken) { + if ((text->plug.client->features & SASL_FEAT_GSS_FRAMING) == 0) + text->gs2_flags |= GS2_NONSTD_FLAG; + + switch (params->cbindingdisp) { + case SASL_CB_DISP_NONE: + text->gs2_flags |= GS2_CB_FLAG_N; + break; + case SASL_CB_DISP_USED: + text->gs2_flags |= GS2_CB_FLAG_P; + break; + case SASL_CB_DISP_WANT: + text->gs2_flags |= GS2_CB_FLAG_Y; + break; + } + + ret = gs2_make_header(text, params, + strcmp(oparams->user, oparams->authid) ? + (char *) oparams->user : NULL, + &text->out_buf, &text->out_buf_len); + if (ret != 0) { + goto cleanup; + } + } + + req_flags = GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG; + + maj_stat = gss_init_sec_context(&min_stat, + (params->gss_creds != GSS_C_NO_CREDENTIAL) + ? (gss_cred_id_t)params->gss_creds + : text->client_creds, + &text->gss_ctx, + text->server_name, + (gss_OID)text->mechanism, + req_flags, + GSS_C_INDEFINITE, + &text->gss_cbindings, + serverinlen ? &input_token : GSS_C_NO_BUFFER, + NULL, + &output_token, + &ret_flags, + &text->lifetime); + if (GSS_ERROR(maj_stat)) { + ret = SASL_OK; + goto cleanup; + } + + ret = gs2_make_message(text, params, initialContextToken, &output_token, + &text->out_buf, &text->out_buf_len); + if (ret != 0) { + goto cleanup; + } + + *clientout = text->out_buf; + *clientoutlen = text->out_buf_len; + + if (maj_stat == GSS_S_CONTINUE_NEEDED) { + ret = SASL_CONTINUE; + goto cleanup; + } + + if (text->client_name != GSS_C_NO_NAME) { + gss_release_name(&min_stat, &text->client_name); + } + maj_stat = gss_inquire_context(&min_stat, + text->gss_ctx, + &text->client_name, + NULL, + &text->lifetime, + NULL, + &ret_flags, /* flags */ + NULL, + NULL); + if (GSS_ERROR(maj_stat)) { + ret = SASL_OK; + goto cleanup; + } + + if ((ret_flags & req_flags) != req_flags) { + ret = SASL_BADAUTH; + goto cleanup; + } + + maj_stat = gss_display_name(&min_stat, + text->client_name, + &name_buf, + NULL); + if (GSS_ERROR(maj_stat)) { + ret = SASL_OK; + goto cleanup; + } + + oparams->gss_peer_name = text->server_name; + oparams->gss_local_name = text->client_name; + oparams->encode = NULL; + oparams->decode = NULL; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0xFFFFFF; + oparams->doneflag = 1; + + ret = SASL_OK; + +cleanup: + if (ret == SASL_OK && maj_stat != GSS_S_COMPLETE) { + sasl_gs2_seterror(text->utils, maj_stat, min_stat); + ret = SASL_FAIL; + } + + gss_release_buffer(&min_stat, &output_token); + gss_release_buffer(&min_stat, &name_buf); + + if (ret < SASL_OK) { + sasl_gs2_free_context_contents(text); + } + + return ret; +} + +static int gs2_client_mech_new(void *glob_context, + sasl_client_params_t *params, + void **conn_context) +{ + context_t *text; + int ret; + + text = sasl_gs2_new_context(params->utils); + if (text == NULL) { + MEMERROR(params->utils); + return SASL_NOMEM; + } + + text->gss_ctx = GSS_C_NO_CONTEXT; + text->client_name = GSS_C_NO_NAME; + text->server_creds = GSS_C_NO_CREDENTIAL; + text->client_creds = GSS_C_NO_CREDENTIAL; + text->plug.client = glob_context; + + ret = gs2_map_sasl_name(params->utils, text->plug.client->mech_name, + &text->mechanism); + if (ret != SASL_OK) { + gs2_common_mech_dispose(text, params->utils); + return ret; + } + + *conn_context = text; + + return SASL_OK; +} + +static int +gs2_client_plug_alloc(const sasl_utils_t *utils, + void *plug, + gss_buffer_t sasl_name, + gss_OID mech) +{ + int ret; + sasl_client_plug_t *cplug = (sasl_client_plug_t *)plug; + gss_buffer_desc buf; + + memset(cplug, 0, sizeof(*cplug)); + + ret = gs2_get_mech_attrs(utils, mech, + &cplug->security_flags, + &cplug->features, + &cplug->required_prompts); + if (ret != SASL_OK) + return ret; + + ret = gs2_duplicate_buffer(utils, sasl_name, &buf); + if (ret != SASL_OK) + return ret; + + cplug->mech_name = (char *)buf.value; + cplug->features |= SASL_FEAT_NEEDSERVERFQDN; + cplug->glob_context = plug; + cplug->mech_new = gs2_client_mech_new; + cplug->mech_step = gs2_client_mech_step; + cplug->mech_dispose = gs2_common_mech_dispose; + cplug->mech_free = gs2_common_mech_free; + + return SASL_OK; +} + +static sasl_client_plug_t *gs2_client_plugins; +static int gs2_client_plugcount; + +int +gs2_client_plug_init(const sasl_utils_t *utils, + int maxversion, + int *outversion, + sasl_client_plug_t **pluglist, + int *plugcount) +{ + int ret; + + *pluglist = NULL; + *plugcount = 0; + + if (maxversion < SASL_CLIENT_PLUG_VERSION) + return SASL_BADVERS; + + *outversion = SASL_CLIENT_PLUG_VERSION; + + if (gs2_client_plugins == NULL) { + ret = gs2_common_plug_init(utils, + sizeof(sasl_client_plug_t), + gs2_client_plug_alloc, + (void **)&gs2_client_plugins, + &gs2_client_plugcount); + if (ret != SASL_OK) + return ret; + } + + *pluglist = gs2_client_plugins; + *plugcount = gs2_client_plugcount; + + return SASL_OK; +} + +/* + * Copy header and application channel bindings to GSS channel bindings + * structure in context. + */ +static int +gs2_save_cbindings(context_t *text, + gss_buffer_t header, + const sasl_channel_binding_t *cbinding) +{ + gss_buffer_t gss_cbindings = &text->gss_cbindings.application_data; + size_t len; + unsigned char *p; + + assert(gss_cbindings->value == NULL); + + /* + * The application-data field MUST be set to the gs2-header, excluding + * the initial [gs2-nonstd-flag ","] part, concatenated with, when a + * gs2-cb-flag of "p" is used, the application's channel binding data. + */ + len = header->length; + if (text->gs2_flags & GS2_NONSTD_FLAG) { + assert(len > 2); + len -= 2; + } + if ((text->gs2_flags & GS2_CB_FLAG_MASK) == GS2_CB_FLAG_P && + cbinding != NULL) { + len += cbinding->len; + } + + gss_cbindings->length = len; + gss_cbindings->value = text->utils->malloc(len); + if (gss_cbindings->value == NULL) + return SASL_NOMEM; + + p = (unsigned char *)gss_cbindings->value; + if (text->gs2_flags & GS2_NONSTD_FLAG) { + memcpy(p, (unsigned char *)header->value + 2, header->length - 2); + p += header->length - 2; + } else { + memcpy(p, header->value, header->length); + p += header->length; + } + + if ((text->gs2_flags & GS2_CB_FLAG_MASK) == GS2_CB_FLAG_P && + cbinding != NULL) { + memcpy(p, cbinding->data, cbinding->len); + } + + return SASL_OK; +} + +#define CHECK_REMAIN(n) do { if (remain < (n)) return SASL_BADPROT; } while (0) + +/* + * Verify gs2-header, save authzid and channel bindings to context. + */ +static int +gs2_verify_initial_message(context_t *text, + sasl_server_params_t *sparams, + const char *in, + unsigned inlen, + gss_buffer_t token) +{ + OM_uint32 major, minor; + char *p = (char *)in; + unsigned remain = inlen; + int ret; + gss_buffer_desc buf = GSS_C_EMPTY_BUFFER; + + assert(text->cbindingname == NULL); + assert(text->authzid == NULL); + + token->length = 0; + token->value = NULL; + + /* minimum header includes CB flag and non-zero GSS token */ + CHECK_REMAIN(4); /* [pny],,. */ + + /* non-standard GSS framing flag */ + if (remain > 1 && memcmp(p, "F,", 2) == 0) { + text->gs2_flags |= GS2_NONSTD_FLAG; + remain -= 2; + p += 2; + } + + /* SASL channel bindings */ + CHECK_REMAIN(1); /* [pny] */ + remain--; + switch (*p++) { + case 'p': + CHECK_REMAIN(1); /* = */ + remain--; + if (*p++ != '=') + return SASL_BADPROT; + + ret = gs2_unescape_authzid(text->utils, &p, &remain, &text->cbindingname); + if (ret != SASL_OK) + return ret; + + text->gs2_flags |= GS2_CB_FLAG_P; + break; + case 'n': + text->gs2_flags |= GS2_CB_FLAG_N; + break; + case 'y': + text->gs2_flags |= GS2_CB_FLAG_Y; + break; + } + + CHECK_REMAIN(1); /* , */ + remain--; + if (*p++ != ',') + return SASL_BADPROT; + + /* authorization identity */ + if (remain > 1 && memcmp(p, "a=", 2) == 0) { + CHECK_REMAIN(2); + remain -= 2; + p += 2; + + ret = gs2_unescape_authzid(text->utils, &p, &remain, &text->authzid); + if (ret != SASL_OK) + return ret; + } + + /* end of header */ + CHECK_REMAIN(1); /* , */ + remain--; + if (*p++ != ',') + return SASL_BADPROT; + + buf.length = inlen - remain; + buf.value = (void *)in; + + /* stash channel bindings to pass into gss_accept_sec_context() */ + ret = gs2_save_cbindings(text, &buf, sparams->cbinding); + if (ret != SASL_OK) + return ret; + + if (text->gs2_flags & GS2_NONSTD_FLAG) { + buf.length = remain; + buf.value = p; + } else { + gss_buffer_desc tmp; + + tmp.length = remain; + tmp.value = p; + + major = gss_encapsulate_token(&tmp, text->mechanism, &buf); + if (GSS_ERROR(major)) + return SASL_NOMEM; + } + + token->value = text->utils->malloc(buf.length); + if (token->value == NULL) + return SASL_NOMEM; + + token->length = buf.length; + memcpy(token->value, buf.value, buf.length); + + if ((text->gs2_flags & GS2_NONSTD_FLAG) == 0) + gss_release_buffer(&minor, &buf); + + return SASL_OK; +} + +/* + * Create gs2-header, save channel bindings to context. + */ +static int +gs2_make_header(context_t *text, + sasl_client_params_t *cparams, + const char *authzid, + char **out, + unsigned *outlen) +{ + size_t required = 0; + size_t wire_authzid_len = 0, cbnamelen = 0; + char *wire_authzid = NULL; + char *p; + int ret; + gss_buffer_desc buf; + + *out = NULL; + *outlen = 0; + + /* non-standard GSS framing flag */ + if (text->gs2_flags & GS2_NONSTD_FLAG) + required += 2; /* F, */ + + /* SASL channel bindings */ + switch (text->gs2_flags & GS2_CB_FLAG_MASK) { + case GS2_CB_FLAG_P: + if (!SASL_CB_PRESENT(cparams)) + return SASL_BADPARAM; + cbnamelen = strlen(cparams->cbinding->name); + required += 1 /*=*/ + cbnamelen; + /* fallthrough */ + case GS2_CB_FLAG_N: + case GS2_CB_FLAG_Y: + required += 2; /* [pny], */ + break; + default: + return SASL_BADPARAM; + } + + /* authorization identity */ + if (authzid != NULL) { + ret = gs2_escape_authzid(text->utils, authzid, + strlen(authzid), &wire_authzid); + if (ret != SASL_OK) + return ret; + + wire_authzid_len = strlen(wire_authzid); + required += 2 /* a= */ + wire_authzid_len; + } + + required += 1; /* trailing comma */ + + ret = _plug_buf_alloc(text->utils, out, outlen, required); + if (ret != SASL_OK) { + text->utils->free(wire_authzid); + return ret; + } + + *out = text->out_buf; + *outlen = required; + + p = (char *)text->out_buf; + if (text->gs2_flags & GS2_NONSTD_FLAG) { + *p++ = 'F'; + *p++ = ','; + } + switch (text->gs2_flags & GS2_CB_FLAG_MASK) { + case GS2_CB_FLAG_P: + memcpy(p, "p=", 2); + memcpy(p + 2, cparams->cbinding->name, cbnamelen); + p += 2 + cbnamelen; + break; + case GS2_CB_FLAG_N: + *p++ = 'n'; + break; + case GS2_CB_FLAG_Y: + *p++ = 'y'; + break; + } + *p++ = ','; + if (wire_authzid != NULL) { + memcpy(p, "a=", 2); + memcpy(p + 2, wire_authzid, wire_authzid_len); + text->utils->free(wire_authzid); + p += 2 + wire_authzid_len; + } + *p++ = ','; + + assert(p == (char *)text->out_buf + required); + + buf.length = required; + buf.value = *out; + + ret = gs2_save_cbindings(text, &buf, cparams->cbinding); + if (ret != SASL_OK) + return ret; + + return SASL_OK; +} + +/* + * Convert a GSS token to a GS2 one + */ +static int +gs2_make_message(context_t *text, + sasl_client_params_t *cparams __attribute__((unused)), + int initialContextToken, + gss_buffer_t token, + char **out, + unsigned *outlen) +{ + OM_uint32 major, minor; + int ret; + unsigned header_len = 0; + gss_buffer_desc decap_token = GSS_C_EMPTY_BUFFER; + + if (initialContextToken) { + header_len = *outlen; + + major = gss_decapsulate_token(token, text->mechanism, &decap_token); + if ((major == GSS_S_DEFECTIVE_TOKEN && + (text->plug.client->features & SASL_FEAT_GSS_FRAMING)) || + GSS_ERROR(major)) + return SASL_FAIL; + + token = &decap_token; + } + + ret = _plug_buf_alloc(text->utils, out, outlen, + header_len + token->length); + if (ret != 0) + return ret; + + memcpy(*out + header_len, token->value, token->length); + *outlen = header_len + token->length; + + if (initialContextToken) + gss_release_buffer(&minor, &decap_token); + + return SASL_OK; +} + +static const unsigned long gs2_required_prompts[] = { + SASL_CB_LIST_END +}; + +/* + * Map GSS mechanism attributes to SASL ones + */ +static int +gs2_get_mech_attrs(const sasl_utils_t *utils, + const gss_OID mech, + unsigned int *security_flags, + unsigned int *features, + const unsigned long **prompts) +{ + OM_uint32 major, minor; + int present; + gss_OID_set attrs = GSS_C_NO_OID_SET; + + major = gss_inquire_attrs_for_mech(&minor, mech, &attrs, NULL); + if (GSS_ERROR(major)) { + utils->seterror(utils->conn, SASL_NOLOG, + "GS2 Failure: gss_inquire_attrs_for_mech"); + return SASL_FAIL; + } + + *security_flags = SASL_SEC_NOPLAINTEXT | SASL_SEC_NOACTIVE; + *features = SASL_FEAT_WANT_CLIENT_FIRST | SASL_FEAT_CHANNEL_BINDING; + if (prompts != NULL) + *prompts = gs2_required_prompts; + +#define MA_PRESENT(a) (gss_test_oid_set_member(&minor, (gss_OID)(a), \ + attrs, &present) == GSS_S_COMPLETE && \ + present) + + if (MA_PRESENT(GSS_C_MA_PFS)) + *security_flags |= SASL_SEC_FORWARD_SECRECY; + if (!MA_PRESENT(GSS_C_MA_AUTH_INIT_ANON)) + *security_flags |= SASL_SEC_NOANONYMOUS; + if (MA_PRESENT(GSS_C_MA_DELEG_CRED)) + *security_flags |= SASL_SEC_PASS_CREDENTIALS; + if (MA_PRESENT(GSS_C_MA_AUTH_TARG)) + *security_flags |= SASL_SEC_MUTUAL_AUTH; + if (MA_PRESENT(GSS_C_MA_AUTH_INIT_INIT) && prompts != NULL) + *prompts = NULL; + if (MA_PRESENT(GSS_C_MA_ITOK_FRAMED)) + *features |= SASL_FEAT_GSS_FRAMING; + + gss_release_oid_set(&minor, &attrs); + + return SASL_OK; +} + +/* + * Enumerate GSS mechanisms that can be used for GS2 + */ +static int gs2_indicate_mechs(const sasl_utils_t *utils) +{ + OM_uint32 major, minor; + gss_OID_desc desired_oids[3]; + gss_OID_set_desc desired_attrs; + gss_OID_desc except_oids[3]; + gss_OID_set_desc except_attrs; + + if (gs2_mechs != GSS_C_NO_OID_SET) + return SASL_OK; + + desired_oids[0] = *GSS_C_MA_AUTH_INIT; + desired_oids[1] = *GSS_C_MA_AUTH_TARG; + desired_oids[2] = *GSS_C_MA_CBINDINGS; + desired_attrs.count = sizeof(desired_oids)/sizeof(desired_oids[0]); + desired_attrs.elements = desired_oids; + + except_oids[0] = *GSS_C_MA_MECH_NEGO; + except_oids[1] = *GSS_C_MA_NOT_MECH; + except_oids[2] = *GSS_C_MA_DEPRECATED; + + except_attrs.count = sizeof(except_oids)/sizeof(except_oids[0]); + except_attrs.elements = except_oids; + + major = gss_indicate_mechs_by_attrs(&minor, + &desired_attrs, + &except_attrs, + GSS_C_NO_OID_SET, + &gs2_mechs); + if (GSS_ERROR(major)) { + utils->seterror(utils->conn, SASL_NOLOG, + "GS2 Failure: gss_indicate_mechs_by_attrs"); + return SASL_FAIL; + } + + return (gs2_mechs->count > 0) ? SASL_OK : SASL_NOMECH; +} + +/* + * Map SASL mechanism name to OID + */ +static int +gs2_map_sasl_name(const sasl_utils_t *utils, + const char *mech, + gss_OID *oid) +{ + OM_uint32 major, minor; + gss_buffer_desc buf; + + buf.length = strlen(mech); + buf.value = (void *)mech; + + major = gss_inquire_mech_for_saslname(&minor, &buf, oid); + if (GSS_ERROR(major)) { + utils->seterror(utils->conn, SASL_NOLOG, + "GS2 Failure: gss_inquire_mech_for_saslname"); + return SASL_FAIL; + } + + return SASL_OK; +} + +static int +gs2_duplicate_buffer(const sasl_utils_t *utils, + const gss_buffer_t src, + gss_buffer_t dst) +{ + dst->value = utils->malloc(src->length + 1); + if (dst->value == NULL) + return SASL_NOMEM; + + memcpy(dst->value, src->value, src->length); + ((char *)dst->value)[src->length] = '\0'; + dst->length = src->length; + + return SASL_OK; +} + +static int +gs2_unescape_authzid(const sasl_utils_t *utils, + char **endp, + unsigned *remain, + char **authzid) +{ + char *in = *endp; + size_t i, len, inlen = *remain; + char *p; + + *endp = NULL; + + for (i = 0, len = 0; i < inlen; i++) { + if (in[i] == ',') { + *endp = &in[i]; + *remain -= i; + break; + } else if (in[i] == '=') { + if (inlen <= i + 2) + return SASL_BADPROT; + i += 2; + } + len++; + } + + if (len == 0 || *endp == NULL) + return SASL_BADPROT; + + p = *authzid = utils->malloc(len + 1); + if (*authzid == NULL) + return SASL_NOMEM; + + for (i = 0; i < inlen; i++) { + if (in[i] == ',') + break; + else if (in[i] == '=') { + if (memcmp(&in[i + 1], "2C", 2) == 0) + *p++ = ','; + else if (memcmp(&in[i + 1], "3D", 2) == 0) + *p++ = '='; + else { + utils->free(*authzid); + *authzid = NULL; + return SASL_BADPROT; + } + i += 2; + } else + *p++ = in[i]; + } + + *p = '\0'; + + return SASL_OK; +} + +static int +gs2_escape_authzid(const sasl_utils_t *utils, + const char *in, + unsigned inlen, + char **authzid) +{ + size_t i; + char *p; + + p = *authzid = utils->malloc((inlen * 3) + 1); + if (*authzid == NULL) + return SASL_NOMEM; + + for (i = 0; i < inlen; i++) { + if (in[i] == ',') { + memcpy(p, "=2C", 3); + p += 3; + } else if (in[i] == '=') { + memcpy(p, "=3D", 3); + p += 3; + } else { + *p++ = in[i]; + } + } + + *p = '\0'; + + return SASL_OK; +} + +#define GOT_CREDS(text, params) ((text)->client_creds != NULL || (params)->gss_creds != NULL) +#define CRED_ERROR(status) ((status) == GSS_S_CRED_UNAVAIL || (status) == GSS_S_NO_CRED) + +/* + * Determine the authentication identity from the application supplied + * GSS credential, the application supplied identity, and the default + * GSS credential, in that order. Then, acquire credentials. + */ +static int +gs2_get_init_creds(context_t *text, + sasl_client_params_t *params, + sasl_interact_t **prompt_need, + sasl_out_params_t *oparams) +{ + int result = SASL_OK; + const char *authid = NULL, *userid = NULL; + int user_result = SASL_OK; + int auth_result = SASL_OK; + int pass_result = SASL_OK; + OM_uint32 maj_stat = GSS_S_COMPLETE, min_stat = 0; + gss_OID_set_desc mechs; + gss_buffer_desc cred_authid = GSS_C_EMPTY_BUFFER; + gss_buffer_desc name_buf = GSS_C_EMPTY_BUFFER; + + mechs.count = 1; + mechs.elements = (gss_OID)text->mechanism; + + /* + * Get the authentication identity from the application. + */ + if (oparams->authid == NULL) { + auth_result = _plug_get_authid(params->utils, &authid, prompt_need); + if (auth_result != SASL_OK && auth_result != SASL_INTERACT) { + result = auth_result; + goto cleanup; + } + } + + /* + * Get the authorization identity from the application. + */ + if (oparams->user == NULL) { + user_result = _plug_get_userid(params->utils, &userid, prompt_need); + if (user_result != SASL_OK && user_result != SASL_INTERACT) { + result = user_result; + goto cleanup; + } + } + + /* + * Canonicalize the authentication and authorization identities before + * calling GSS_Import_name. + */ + if (auth_result == SASL_OK && user_result == SASL_OK && + oparams->authid == NULL) { + if (userid == NULL || userid[0] == '\0') { + result = params->canon_user(params->utils->conn, authid, 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, + oparams); + } else { + result = params->canon_user(params->utils->conn, + authid, 0, SASL_CU_AUTHID, oparams); + if (result != SASL_OK) + goto cleanup; + + result = params->canon_user(params->utils->conn, + userid, 0, SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) + goto cleanup; + } + + if (oparams->authid != NULL) { + name_buf.length = strlen(oparams->authid); + name_buf.value = (void *)oparams->authid; + + assert(text->client_name == GSS_C_NO_NAME); + + maj_stat = gss_import_name(&min_stat, + &name_buf, + GSS_C_NT_USER_NAME, + &text->client_name); + if (GSS_ERROR(maj_stat)) + goto cleanup; + } + } + + /* + * If application didn't provide an authid, then use the default + * credential. If that doesn't work, give up. + */ + if (!GOT_CREDS(text, params) && oparams->authid == NULL) { + maj_stat = gss_acquire_cred(&min_stat, + GSS_C_NO_NAME, + GSS_C_INDEFINITE, + &mechs, + GSS_C_INITIATE, + &text->client_creds, + NULL, + &text->lifetime); + if (GSS_ERROR(maj_stat)) + goto cleanup; + + assert(text->client_name == GSS_C_NO_NAME); + + maj_stat = gss_inquire_cred(&min_stat, + params->gss_creds + ? (gss_cred_id_t)params->gss_creds + : text->client_creds, + &text->client_name, + NULL, + NULL, + NULL); + if (GSS_ERROR(maj_stat)) + goto cleanup; + + maj_stat = gss_display_name(&min_stat, + text->client_name, + &cred_authid, + NULL); + if (GSS_ERROR(maj_stat)) + goto cleanup; + + if (userid == NULL || userid[0] == '\0') { + result = params->canon_user(params->utils->conn, + cred_authid.value, cred_authid.length, + SASL_CU_AUTHID | SASL_CU_AUTHZID, + oparams); + } else { + result = params->canon_user(params->utils->conn, + cred_authid.value, cred_authid.length, + SASL_CU_AUTHID, oparams); + if (result != SASL_OK) + goto cleanup; + + result = params->canon_user(params->utils->conn, + cred_authid.value, cred_authid.length, + SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) + goto cleanup; + } + } + + /* + * Armed with the authentication identity, try to get a credential without + * a password. + */ + if (!GOT_CREDS(text, params) && text->client_name != GSS_C_NO_NAME) { + maj_stat = gss_acquire_cred(&min_stat, + text->client_name, + GSS_C_INDEFINITE, + &mechs, + GSS_C_INITIATE, + &text->client_creds, + NULL, + &text->lifetime); + if (GSS_ERROR(maj_stat) && !CRED_ERROR(maj_stat)) + goto cleanup; + } + + /* + * If that failed, try to get a credential with a password. + */ + if (!GOT_CREDS(text, params)) { + if (text->password == NULL) { + pass_result = _plug_get_password(params->utils, &text->password, + &text->free_password, prompt_need); + if (pass_result != SASL_OK && pass_result != SASL_INTERACT) { + result = pass_result; + goto cleanup; + } + } + + if (text->password != NULL) { + gss_buffer_desc password_buf; + + password_buf.length = text->password->len; + password_buf.value = text->password->data; + + maj_stat = gss_acquire_cred_with_password(&min_stat, + text->client_name, + &password_buf, + GSS_C_INDEFINITE, + &mechs, + GSS_C_INITIATE, + &text->client_creds, + NULL, + &text->lifetime); + if (GSS_ERROR(maj_stat)) + goto cleanup; + } + } + + maj_stat = GSS_S_COMPLETE; + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + params->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if (user_result == SASL_INTERACT || auth_result == SASL_INTERACT || + pass_result == SASL_INTERACT) { + /* make the prompt list */ + result = + _plug_make_prompts(params->utils, prompt_need, + user_result == SASL_INTERACT ? + "Please enter your authorization name" : NULL, + NULL, + auth_result == SASL_INTERACT ? + "Please enter your authentication name" : NULL, + NULL, + pass_result == SASL_INTERACT ? + "Please enter your password" : NULL, NULL, + NULL, NULL, NULL, + NULL, + NULL, NULL); + if (result == SASL_OK) + result = SASL_INTERACT; + } + +cleanup: + if (result == SASL_OK && maj_stat != GSS_S_COMPLETE) { + sasl_gs2_seterror(text->utils, maj_stat, min_stat); + result = SASL_FAIL; + } + + gss_release_buffer(&min_stat, &cred_authid); + + return result; +} + +static int +sasl_gs2_seterror_(const sasl_utils_t *utils, OM_uint32 maj, OM_uint32 min, + int logonly) +{ + OM_uint32 maj_stat, min_stat; + gss_buffer_desc msg; + OM_uint32 msg_ctx; + int ret; + char *out = NULL; + unsigned int len, curlen = 0; + const char prefix[] = "GS2 Error: "; + + len = sizeof(prefix); + ret = _plug_buf_alloc(utils, &out, &curlen, 256); + if (ret != SASL_OK) + return SASL_OK; + + strcpy(out, prefix); + + msg_ctx = 0; + while (1) { + maj_stat = gss_display_status(&min_stat, maj, + GSS_C_GSS_CODE, GSS_C_NULL_OID, + &msg_ctx, &msg); + + if (GSS_ERROR(maj_stat)) { + if (logonly) { + utils->log(utils->conn, SASL_LOG_FAIL, + "GS2 Failure: (could not get major error message)"); + } else { + utils->seterror(utils->conn, 0, + "GS2 Failure " + "(could not get major error message)"); + } + utils->free(out); + return SASL_OK; + } + + len += len + msg.length; + ret = _plug_buf_alloc(utils, &out, &curlen, len); + if (ret != SASL_OK) { + utils->free(out); + return SASL_OK; + } + + strcat(out, msg.value); + + gss_release_buffer(&min_stat, &msg); + + if (!msg_ctx) + break; + } + + /* Now get the minor status */ + + len += 2; + ret = _plug_buf_alloc(utils, &out, &curlen, len); + if (ret != SASL_OK) { + utils->free(out); + return SASL_NOMEM; + } + + strcat(out, " ("); + + msg_ctx = 0; + while (1) { + maj_stat = gss_display_status(&min_stat, min, + GSS_C_MECH_CODE, GSS_C_NULL_OID, + &msg_ctx, &msg); + + if (GSS_ERROR(maj_stat)) { + if (logonly) { + utils->log(utils->conn, SASL_LOG_FAIL, + "GS2 Failure: (could not get minor error message)"); + } else { + utils->seterror(utils->conn, 0, + "GS2 Failure " + "(could not get minor error message)"); + } + utils->free(out); + return SASL_OK; + } + + len += len + msg.length; + + ret = _plug_buf_alloc(utils, &out, &curlen, len); + if (ret != SASL_OK) { + utils->free(out); + return SASL_NOMEM; + } + + strcat(out, msg.value); + + gss_release_buffer(&min_stat, &msg); + + if (!msg_ctx) + break; + } + + len += 1; + ret = _plug_buf_alloc(utils, &out, &curlen, len); + if (ret != SASL_OK) { + utils->free(out); + return SASL_NOMEM; + } + + strcat(out, ")"); + + if (logonly) { + utils->log(utils->conn, SASL_LOG_FAIL, out); + } else { + utils->seterror(utils->conn, 0, out); + } + utils->free(out); + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/gs2_init.c b/libs/cyrussasl/plugins/gs2_init.c new file mode 100644 index 00000000..31060613 --- /dev/null +++ b/libs/cyrussasl/plugins/gs2_init.c @@ -0,0 +1,43 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_CLIENT_PLUG_INIT( gs2 ) +SASL_SERVER_PLUG_INIT( gs2 ) + diff --git a/libs/cyrussasl/plugins/gs2_token.c b/libs/cyrussasl/plugins/gs2_token.c new file mode 100644 index 00000000..2c492981 --- /dev/null +++ b/libs/cyrussasl/plugins/gs2_token.c @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2011, PADL Software Pty Ltd. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of PADL Software nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include + +#include "gs2_token.h" + +/* + * $Id: gs2_token.c,v 1.2 2011/05/23 14:45:40 mel Exp $ + */ + +#ifndef HAVE_GSS_ENCAPSULATE_TOKEN +/* XXXX this code currently makes the assumption that a mech oid will + never be longer than 127 bytes. This assumption is not inherent in + the interfaces, so the code can be fixed if the OSI namespace + balloons unexpectedly. */ + +/* + * Each token looks like this: + * 0x60 tag for APPLICATION 0, SEQUENCE + * (constructed, definite-length) + * possible multiple bytes, need to parse/generate + * 0x06 tag for OBJECT IDENTIFIER + * compile-time constant string (assume 1 byte) + * compile-time constant string + * the ANY containing the application token + * bytes 0,1 are the token type + * bytes 2,n are the token data + * + * Note that the token type field is a feature of RFC 1964 mechanisms and + * is not used by other GSSAPI mechanisms. As such, a token type of -1 + * is interpreted to mean that no token type should be expected or + * generated. + * + * For the purposes of this abstraction, the token "header" consists of + * the sequence tag and length octets, the mech OID DER encoding, and the + * first two inner bytes, which indicate the token type. The token + * "body" consists of everything else. + */ + +static size_t +der_length_size(size_t length) +{ + if (length < (1<<7)) + return 1; + else if (length < (1<<8)) + return 2; +#if INT_MAX == 0x7fff + else + return 3; +#else + else if (length < (1<<16)) + return 3; + else if (length < (1<<24)) + return 4; + else + return 5; +#endif +} + +static void +der_write_length(unsigned char **buf, size_t length) +{ + if (length < (1<<7)) { + *(*buf)++ = (unsigned char)length; + } else { + *(*buf)++ = (unsigned char)(der_length_size(length)+127); +#if INT_MAX > 0x7fff + if (length >= (1<<24)) + *(*buf)++ = (unsigned char)(length>>24); + if (length >= (1<<16)) + *(*buf)++ = (unsigned char)((length>>16)&0xff); +#endif + if (length >= (1<<8)) + *(*buf)++ = (unsigned char)((length>>8)&0xff); + *(*buf)++ = (unsigned char)(length&0xff); + } +} + +/* returns the length of a token, given the mech oid and the body size */ + +static size_t +token_size(const gss_OID_desc *mech, size_t body_size) +{ + /* set body_size to sequence contents size */ + body_size += 2 + (size_t) mech->length; /* NEED overflow check */ + return 1 + der_length_size(body_size) + body_size; +} + +/* fills in a buffer with the token header. The buffer is assumed to + be the right size. buf is advanced past the token header */ + +static void +make_token_header( + const gss_OID_desc *mech, + size_t body_size, + unsigned char **buf) +{ + *(*buf)++ = 0x60; + der_write_length(buf, 2 + mech->length + body_size); + *(*buf)++ = 0x06; + *(*buf)++ = (unsigned char)mech->length; + memcpy(*buf, mech->elements, mech->length); + *buf += mech->length; +} + +OM_uint32 +gs2_encapsulate_token(const gss_buffer_t input_token, + const gss_OID token_oid, + gss_buffer_t output_token) +{ + size_t tokenSize; + unsigned char *buf; + + if (input_token == GSS_C_NO_BUFFER || token_oid == GSS_C_NO_OID) + return GSS_S_CALL_INACCESSIBLE_READ; + + if (output_token == GSS_C_NO_BUFFER) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + tokenSize = token_size(token_oid, input_token->length); + + output_token->value = malloc(tokenSize); + if (output_token->value == NULL) + return GSS_S_FAILURE; + + buf = output_token->value; + + make_token_header(token_oid, input_token->length, &buf); + memcpy(buf, input_token->value, input_token->length); + output_token->length = tokenSize; + + return GSS_S_COMPLETE; +} +#endif + + +#ifndef HAVE_GSS_DECAPSULATE_TOKEN +/* returns decoded length, or < 0 on failure. Advances buf and + decrements bufsize */ + +static int +der_read_length(unsigned char **buf, ssize_t *bufsize) +{ + unsigned char sf; + int ret; + + if (*bufsize < 1) + return -1; + + sf = *(*buf)++; + (*bufsize)--; + if (sf & 0x80) { + if ((sf &= 0x7f) > ((*bufsize)-1)) + return -1; + if (sf > sizeof(int)) + return -1; + ret = 0; + for (; sf; sf--) { + ret = (ret<<8) + (*(*buf)++); + (*bufsize)--; + } + } else { + ret = sf; + } + + return ret; +} + +/* + * Given a buffer containing a token, reads and verifies the token, + * leaving buf advanced past the token header, and setting body_size + * to the number of remaining bytes. Returns 0 on success, + * G_BAD_TOK_HEADER for a variety of errors, and G_WRONG_MECH if the + * mechanism in the token does not match the mech argument. buf and + * *body_size are left unmodified on error. + */ + +static OM_uint32 +verify_token_header(OM_uint32 *minor, + const gss_OID mech, + size_t *body_size, + unsigned char **buf_in, + size_t toksize_in) +{ + unsigned char *buf = *buf_in; + ssize_t seqsize; + gss_OID_desc toid; + ssize_t toksize = (ssize_t)toksize_in; + + *minor = 0; + + if ((toksize -= 1) < 0) + return GSS_S_DEFECTIVE_TOKEN; + + if (*buf++ != 0x60) + return GSS_S_DEFECTIVE_TOKEN; + + seqsize = der_read_length(&buf, &toksize); + if (seqsize < 0) + return GSS_S_DEFECTIVE_TOKEN; + + if (seqsize != toksize) + return GSS_S_DEFECTIVE_TOKEN; + + if ((toksize -= 1) < 0) + return GSS_S_DEFECTIVE_TOKEN; + + if (*buf++ != 0x06) + return GSS_S_DEFECTIVE_TOKEN; + + if ((toksize -= 1) < 0) + return GSS_S_DEFECTIVE_TOKEN; + + toid.length = *buf++; + + if ((toksize -= toid.length) < 0) + return GSS_S_DEFECTIVE_TOKEN; + + toid.elements = buf; + buf += toid.length; + + if (!gss_oid_equal(&toid, mech)) + return GSS_S_DEFECTIVE_TOKEN; + + *buf_in = buf; + *body_size = toksize; + + return GSS_S_COMPLETE; +} + +OM_uint32 +gs2_decapsulate_token(const gss_buffer_t input_token, + const gss_OID token_oid, + gss_buffer_t output_token) +{ + OM_uint32 major, minor; + size_t body_size = 0; + unsigned char *buf_in; + + if (input_token == GSS_C_NO_BUFFER || token_oid == GSS_C_NO_OID) + return GSS_S_CALL_INACCESSIBLE_READ; + + if (output_token == GSS_C_NO_BUFFER) + return GSS_S_CALL_INACCESSIBLE_WRITE; + + buf_in = input_token->value; + + major = verify_token_header(&minor, token_oid, &body_size, &buf_in, + input_token->length); + if (minor != 0) + return GSS_S_DEFECTIVE_TOKEN; + + output_token->value = malloc(body_size); + if (output_token->value == NULL) + return GSS_S_FAILURE; + + memcpy(output_token->value, buf_in, body_size); + output_token->length = body_size; + + return GSS_S_COMPLETE; +} +#endif + +#ifndef HAVE_GSS_OID_EQUAL +int +gs2_oid_equal(const gss_OID o1, const gss_OID o2) +{ + return o1->length == o2->length && + (memcmp(o1->elements, o2->elements, o1->length) == 0); +} +#endif diff --git a/libs/cyrussasl/plugins/gs2_token.h b/libs/cyrussasl/plugins/gs2_token.h new file mode 100644 index 00000000..f7e2f745 --- /dev/null +++ b/libs/cyrussasl/plugins/gs2_token.h @@ -0,0 +1,58 @@ +/* + * Copyright 1993 by OpenVision Technologies, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software + * and its documentation for any purpose is hereby granted without fee, + * provided that the above copyright notice appears in all copies and + * that both that copyright notice and this permission notice appear in + * supporting documentation, and that the name of OpenVision not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. OpenVision makes no + * representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * OPENVISION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL OPENVISION BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF + * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR + * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _GS2_TOKEN_H_ +#define _GS2_TOKEN_H_ 1 + +#include + +#include + +#ifndef KRB5_HEIMDAL +#ifdef HAVE_GSSAPI_GSSAPI_EXT_H +#include +#endif +#endif + +#ifndef HAVE_GSS_DECAPSULATE_TOKEN +OM_uint32 +gs2_decapsulate_token(const gss_buffer_t input_token, + const gss_OID token_oid, + gss_buffer_t output_token); +#define gss_decapsulate_token gs2_decapsulate_token +#endif + +#ifndef HAVE_GSS_ENCAPSULATE_TOKEN +OM_uint32 +gs2_encapsulate_token(const gss_buffer_t input_token, + const gss_OID token_oid, + gss_buffer_t output_token); +#define gss_encapsulate_token gs2_encapsulate_token +#endif + +#ifndef HAVE_GSS_OID_EQUAL +int +gs2_oid_equal(const gss_OID o1, const gss_OID o2); +#define gss_oid_equal gs2_oid_equal +#endif + +#endif /* _GS2_TOKEN_H_ */ diff --git a/libs/cyrussasl/plugins/gssapi.c b/libs/cyrussasl/plugins/gssapi.c new file mode 100644 index 00000000..2fd1b3b7 --- /dev/null +++ b/libs/cyrussasl/plugins/gssapi.c @@ -0,0 +1,2076 @@ +/* GSSAPI SASL plugin + * Leif Johansson + * Rob Siemborski (SASL v2 Conversion) + * $Id: gssapi.c,v 1.115 2011/11/21 15:12:35 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#ifdef HAVE_GSSAPI_H +#include +#else +#include +#endif + +#ifdef WIN32 +# include + +# ifndef R_OK +# define R_OK 04 +# endif +/* we also need io.h for access() prototype */ +# include +#else +# include +# include +# include +# include +# include +#endif /* WIN32 */ +#include +#include +#include +#include +#include + +#include "plugin_common.h" + +#ifdef HAVE_UNISTD_H +#include +#endif + +#include +#include + +/***************************** Common Section *****************************/ + +static const char plugin_id[] = "$Id: gssapi.c,v 1.115 2011/11/21 15:12:35 mel Exp $"; + +static const char * GSSAPI_BLANK_STRING = ""; + +static gss_OID_desc gss_spnego_oid = { 6, (void *) "\x2b\x06\x01\x05\x05\x02" }; + +#if !defined(HAVE_GSS_C_NT_HOSTBASED_SERVICE) && !defined(GSS_C_NT_HOSTBASED_SERVICE) +extern gss_OID gss_nt_service_name; +#define GSS_C_NT_HOSTBASED_SERVICE gss_nt_service_name +#endif + +#ifdef WANT_KERBEROS5_3DES +/* Check if CyberSafe flag is defined */ +#ifdef CSF_GSS_C_DES3_FLAG +#define K5_MAX_SSF 112 +#endif + +/* Heimdal and MIT use the following */ +#ifdef GSS_KRB5_CONF_C_QOP_DES3_KD +#define K5_MAX_SSF 112 +#endif + +#endif + +#ifndef K5_MAX_SSF +/* All Kerberos implementations support DES */ +#define K5_MAX_SSF 56 +#endif + +/* GSSAPI SASL Mechanism by Leif Johansson + * inspired by the kerberos mechanism and the gssapi_server and + * gssapi_client from the heimdal distribution by Assar Westerlund + * and Johan Danielsson . + * See the configure.in file for details on dependencies. + * + * Important contributions from Sam Hartman . + * + * This code was tested with the following distributions of Kerberos: + * Heimdal (http://www.pdc.kth.se/heimdal), MIT (http://web.mit.edu/kerberos/www/) + * CyberSafe (http://www.cybersafe.com/) and SEAM. + */ + +#ifdef GSS_USE_MUTEXES +#define GSS_LOCK_MUTEX(utils) \ + if(((sasl_utils_t *)(utils))->mutex_lock(gss_mutex) != 0) { \ + return SASL_FAIL; \ + } + +#define GSS_UNLOCK_MUTEX(utils) \ + if(((sasl_utils_t *)(utils))->mutex_unlock(gss_mutex) != 0) { \ + return SASL_FAIL; \ + } + +static void *gss_mutex = NULL; +#else +#define GSS_LOCK_MUTEX(utils) +#define GSS_UNLOCK_MUTEX(utils) +#endif + +typedef struct context { + int state; + + gss_OID mech_type; /* GSS-SPNEGO or GSSAPI */ + int http_mode; /* use RFC 4559 compatible protocol? */ + + gss_ctx_id_t gss_ctx; + gss_name_t client_name; + gss_name_t server_name; + gss_cred_id_t server_creds; + gss_cred_id_t client_creds; + + sasl_ssf_t limitssf, requiressf; /* application defined bounds, for the + server */ + unsigned char qop; /* as allowed by GSSAPI */ + + const sasl_utils_t *utils; + + /* layers buffering */ + decode_context_t decode_context; + + char *encode_buf; /* For encoding/decoding mem management */ + char *decode_buf; + char *decode_once_buf; + unsigned encode_buf_len; + unsigned decode_buf_len; + unsigned decode_once_buf_len; + buffer_info_t *enc_in_buf; + + char *out_buf; /* per-step mem management */ + unsigned out_buf_len; + + char *authid; /* hold the authid between steps - server */ + const char *user; /* hold the userid between steps - client */ +} context_t; + +enum { + SASL_GSSAPI_STATE_AUTHNEG = 1, + SASL_GSSAPI_STATE_SSFCAP = 2, + SASL_GSSAPI_STATE_SSFREQ = 3, + SASL_GSSAPI_STATE_AUTHENTICATED = 4 +}; + +#define LAYER_CONFIDENTIALITY 4 +#define LAYER_INTEGRITY 2 +#define LAYER_NONE 1 + +/* sasl_gss_log: only logs status string returned from gss_display_status() */ +#define sasl_gss_log(x,y,z) sasl_gss_seterror_(x,y,z,1) +#define sasl_gss_seterror(x,y,z) sasl_gss_seterror_(x,y,z,0) + +static int +sasl_gss_seterror_(const sasl_utils_t *utils, OM_uint32 maj, OM_uint32 min, + int logonly) +{ + OM_uint32 maj_stat, min_stat; + gss_buffer_desc msg; + OM_uint32 msg_ctx; + int ret; + char *out = NULL; + size_t len, curlen = 0; + const char prefix[] = "GSSAPI Error: "; + + if (!utils) return SASL_OK; + + len = sizeof(prefix); + ret = _plug_buf_alloc(utils, &out, &curlen, 256); + if (ret != SASL_OK) return SASL_NOMEM; + + strcpy(out, prefix); + + msg_ctx = 0; + while (1) { + GSS_LOCK_MUTEX(utils); + maj_stat = gss_display_status(&min_stat, maj, + GSS_C_GSS_CODE, GSS_C_NULL_OID, + &msg_ctx, &msg); + GSS_UNLOCK_MUTEX(utils); + + if(GSS_ERROR(maj_stat)) { + if (logonly) { + utils->log(utils->conn, SASL_LOG_FAIL, + "GSSAPI Failure: (could not get major error message)"); + } else { + utils->seterror(utils->conn, 0, + "GSSAPI Failure " + "(could not get major error message)"); + } + utils->free(out); + return SASL_OK; + } + + len += len + msg.length; + ret = _plug_buf_alloc(utils, &out, &curlen, len); + + if(ret != SASL_OK) { + utils->free(out); + return SASL_NOMEM; + } + + strcat(out, msg.value); + + GSS_LOCK_MUTEX(utils); + gss_release_buffer(&min_stat, &msg); + GSS_UNLOCK_MUTEX(utils); + + if (!msg_ctx) + break; + } + + /* Now get the minor status */ + + len += 2; + ret = _plug_buf_alloc(utils, &out, &curlen, len); + if(ret != SASL_OK) { + utils->free(out); + return SASL_NOMEM; + } + + strcat(out, " ("); + + msg_ctx = 0; + while (1) { + GSS_LOCK_MUTEX(utils); + maj_stat = gss_display_status(&min_stat, min, + GSS_C_MECH_CODE, GSS_C_NULL_OID, + &msg_ctx, &msg); + GSS_UNLOCK_MUTEX(utils); + + if(GSS_ERROR(maj_stat)) { + if (logonly) { + utils->log(utils->conn, SASL_LOG_FAIL, + "GSSAPI Failure: (could not get minor error message)"); + } else { + utils->seterror(utils->conn, 0, + "GSSAPI Failure " + "(could not get minor error message)"); + } + utils->free(out); + return SASL_OK; + } + + len += len + msg.length; + + ret = _plug_buf_alloc(utils, &out, &curlen, len); + if(ret != SASL_OK) { + utils->free(out); + return SASL_NOMEM; + } + + strcat(out, msg.value); + + GSS_LOCK_MUTEX(utils); + gss_release_buffer(&min_stat, &msg); + GSS_UNLOCK_MUTEX(utils); + + if (!msg_ctx) + break; + } + + len += 1; + ret = _plug_buf_alloc(utils, &out, &curlen, len); + if(ret != SASL_OK) { + utils->free(out); + return SASL_NOMEM; + } + + strcat(out, ")"); + + if (logonly) { + utils->log(utils->conn, SASL_LOG_FAIL, out); + } else { + utils->seterror(utils->conn, 0, out); + } + utils->free(out); + + return SASL_OK; +} + +static int +sasl_gss_encode(void *context, const struct iovec *invec, unsigned numiov, + const char **output, unsigned *outputlen, int privacy) +{ + context_t *text = (context_t *)context; + OM_uint32 maj_stat, min_stat; + gss_buffer_t input_token, output_token; + gss_buffer_desc real_input_token, real_output_token; + int ret; + struct buffer_info *inblob, bufinfo; + + if (!output) return SASL_BADPARAM; + + if (numiov > 1) { + ret = _plug_iovec_to_buf(text->utils, invec, numiov, &text->enc_in_buf); + if (ret != SASL_OK) return ret; + inblob = text->enc_in_buf; + } else { + bufinfo.data = invec[0].iov_base; + bufinfo.curlen = invec[0].iov_len; + inblob = &bufinfo; + } + + if (text->state != SASL_GSSAPI_STATE_AUTHENTICATED) return SASL_NOTDONE; + + input_token = &real_input_token; + + real_input_token.value = inblob->data; + real_input_token.length = inblob->curlen; + + output_token = &real_output_token; + output_token->value = NULL; + output_token->length = 0; + + GSS_LOCK_MUTEX(text->utils); + maj_stat = gss_wrap (&min_stat, + text->gss_ctx, + privacy, + GSS_C_QOP_DEFAULT, + input_token, + NULL, + output_token); + GSS_UNLOCK_MUTEX(text->utils); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); + if (output_token->value) { + GSS_LOCK_MUTEX(text->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(text->utils); + } + return SASL_FAIL; + } + + if (output_token->value && output) { + unsigned char * p; + + ret = _plug_buf_alloc(text->utils, + &(text->encode_buf), + &(text->encode_buf_len), + output_token->length + 4); + + if (ret != SASL_OK) { + GSS_LOCK_MUTEX(text->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(text->utils); + return ret; + } + + p = (unsigned char *) text->encode_buf; + + p[0] = (output_token->length>>24) & 0xFF; + p[1] = (output_token->length>>16) & 0xFF; + p[2] = (output_token->length>>8) & 0xFF; + p[3] = output_token->length & 0xFF; + + memcpy(text->encode_buf + 4, output_token->value, output_token->length); + } + + if (outputlen) { + *outputlen = output_token->length + 4; + } + + *output = text->encode_buf; + + if (output_token->value) { + GSS_LOCK_MUTEX(text->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(text->utils); + } + + return SASL_OK; +} + +static int gssapi_privacy_encode(void *context, const struct iovec *invec, + unsigned numiov, const char **output, + unsigned *outputlen) +{ + return sasl_gss_encode(context,invec,numiov,output,outputlen,1); +} + +static int gssapi_integrity_encode(void *context, const struct iovec *invec, + unsigned numiov, const char **output, + unsigned *outputlen) +{ + return sasl_gss_encode(context,invec,numiov,output,outputlen,0); +} + +static int +gssapi_decode_packet(void *context, + const char *input, + unsigned inputlen, + char **output, + unsigned *outputlen) +{ + context_t *text = (context_t *) context; + OM_uint32 maj_stat, min_stat; + gss_buffer_t input_token, output_token; + gss_buffer_desc real_input_token, real_output_token; + int result; + + if (text->state != SASL_GSSAPI_STATE_AUTHENTICATED) { + SETERROR(text->utils, "GSSAPI Failure"); + return SASL_NOTDONE; + } + + input_token = &real_input_token; + real_input_token.value = (char *) input; + real_input_token.length = inputlen; + + output_token = &real_output_token; + output_token->value = NULL; + output_token->length = 0; + + GSS_LOCK_MUTEX(text->utils); + maj_stat = gss_unwrap (&min_stat, + text->gss_ctx, + input_token, + output_token, + NULL, + NULL); + GSS_UNLOCK_MUTEX(text->utils); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils,maj_stat,min_stat); + if (output_token->value) { + GSS_LOCK_MUTEX(text->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(text->utils); + } + return SASL_FAIL; + } + + if (outputlen) { + *outputlen = output_token->length; + } + + if (output_token->value) { + if (output) { + result = _plug_buf_alloc(text->utils, &text->decode_once_buf, + &text->decode_once_buf_len, + *outputlen); + if (result != SASL_OK) { + GSS_LOCK_MUTEX(text->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(text->utils); + return result; + } + *output = text->decode_once_buf; + memcpy(*output, output_token->value, *outputlen); + } + GSS_LOCK_MUTEX(text->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(text->utils); + } + + return SASL_OK; +} + +static int gssapi_decode(void *context, + const char *input, unsigned inputlen, + const char **output, unsigned *outputlen) +{ + context_t *text = (context_t *) context; + int ret; + + ret = _plug_decode(&text->decode_context, input, inputlen, + &text->decode_buf, &text->decode_buf_len, outputlen, + gssapi_decode_packet, text); + + *output = text->decode_buf; + + return ret; +} + +static context_t *sasl_gss_new_context(const sasl_utils_t *utils) +{ + context_t *ret; + + ret = utils->malloc(sizeof(context_t)); + if(!ret) return NULL; + + memset(ret,0,sizeof(context_t)); + ret->utils = utils; + + return ret; +} + +static int sasl_gss_free_context_contents(context_t *text) +{ + OM_uint32 maj_stat, min_stat; + + if (!text) return SASL_OK; + + GSS_LOCK_MUTEX(text->utils); + + if (text->gss_ctx != GSS_C_NO_CONTEXT) { + maj_stat = gss_delete_sec_context(&min_stat,&text->gss_ctx, + GSS_C_NO_BUFFER); + text->gss_ctx = GSS_C_NO_CONTEXT; + } + + if (text->client_name != GSS_C_NO_NAME) { + maj_stat = gss_release_name(&min_stat,&text->client_name); + text->client_name = GSS_C_NO_NAME; + } + + if (text->server_name != GSS_C_NO_NAME) { + maj_stat = gss_release_name(&min_stat,&text->server_name); + text->server_name = GSS_C_NO_NAME; + } + + if ( text->server_creds != GSS_C_NO_CREDENTIAL) { + maj_stat = gss_release_cred(&min_stat, &text->server_creds); + text->server_creds = GSS_C_NO_CREDENTIAL; + } + + if ( text->client_creds != GSS_C_NO_CREDENTIAL) { + maj_stat = gss_release_cred(&min_stat, &text->client_creds); + text->client_creds = GSS_C_NO_CREDENTIAL; + } + + GSS_UNLOCK_MUTEX(text->utils); + + if (text->out_buf) { + text->utils->free(text->out_buf); + text->out_buf = NULL; + } + + if (text->encode_buf) { + text->utils->free(text->encode_buf); + text->encode_buf = NULL; + } + + if (text->decode_buf) { + text->utils->free(text->decode_buf); + text->decode_buf = NULL; + } + + if (text->decode_once_buf) { + text->utils->free(text->decode_once_buf); + text->decode_once_buf = NULL; + } + + if (text->enc_in_buf) { + if(text->enc_in_buf->data) text->utils->free(text->enc_in_buf->data); + text->utils->free(text->enc_in_buf); + text->enc_in_buf = NULL; + } + + _plug_decode_free(&text->decode_context); + + if (text->authid) { /* works for both client and server */ + text->utils->free(text->authid); + text->authid = NULL; + } + + return SASL_OK; + +} + +static void gssapi_common_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + sasl_gss_free_context_contents((context_t *)(conn_context)); + utils->free(conn_context); +} + +static void gssapi_common_mech_free(void *global_context __attribute__((unused)), + const sasl_utils_t *utils) +{ +#ifdef GSS_USE_MUTEXES + if (gss_mutex) { + utils->mutex_free(gss_mutex); + gss_mutex=NULL; + } +#endif +} + +/***************************** Server Section *****************************/ + +static int +gssapi_server_mech_new(void *glob_context __attribute__((unused)), + sasl_server_params_t *params, + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + void **conn_context) +{ + context_t *text; + + text = sasl_gss_new_context(params->utils); + if (text == NULL) { + MEMERROR(params->utils); + return SASL_NOMEM; + } + + text->gss_ctx = GSS_C_NO_CONTEXT; + text->client_name = GSS_C_NO_NAME; + text->server_name = GSS_C_NO_NAME; + text->server_creds = GSS_C_NO_CREDENTIAL; + text->client_creds = GSS_C_NO_CREDENTIAL; + text->state = SASL_GSSAPI_STATE_AUTHNEG; + + text->http_mode = (params->flags & SASL_NEED_HTTP); + + *conn_context = text; + + return SASL_OK; +} + +static int +gssapi_server_mech_authneg(context_t *text, + sasl_server_params_t *params, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams __attribute__((unused))) +{ + gss_buffer_t input_token, output_token; + gss_buffer_desc real_input_token, real_output_token; + OM_uint32 maj_stat = 0, min_stat = 0; + gss_buffer_desc name_token; + int ret, equal = 0; + unsigned out_flags = 0; + gss_cred_id_t server_creds = (gss_cred_id_t) params->gss_creds; + gss_buffer_desc name_without_realm; + gss_name_t client_name_MN = NULL, without = NULL; + gss_OID mech_type; + + input_token = &real_input_token; + output_token = &real_output_token; + output_token->value = NULL; output_token->length = 0; + input_token->value = NULL; input_token->length = 0; + + if (text->server_name == GSS_C_NO_NAME) { /* only once */ + if (params->serverFQDN == NULL + || strlen(params->serverFQDN) == 0) { + SETERROR(text->utils, "GSSAPI Failure: no serverFQDN"); + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + name_token.length = strlen(params->service) + 1 + strlen(params->serverFQDN); + name_token.value = (char *)params->utils->malloc((name_token.length + 1) * sizeof(char)); + if (name_token.value == NULL) { + MEMERROR(text->utils); + sasl_gss_free_context_contents(text); + return SASL_NOMEM; + } + sprintf(name_token.value,"%s@%s", params->service, params->serverFQDN); + + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_import_name (&min_stat, + &name_token, + GSS_C_NT_HOSTBASED_SERVICE, + &text->server_name); + GSS_UNLOCK_MUTEX(params->utils); + + params->utils->free(name_token.value); + name_token.value = NULL; + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + + if ( text->server_creds != GSS_C_NO_CREDENTIAL) { + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_release_cred(&min_stat, &text->server_creds); + GSS_UNLOCK_MUTEX(params->utils); + text->server_creds = GSS_C_NO_CREDENTIAL; + } + + /* If caller didn't provide creds already */ + if ( server_creds == GSS_C_NO_CREDENTIAL) { + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_acquire_cred(&min_stat, + text->server_name, + GSS_C_INDEFINITE, + GSS_C_NO_OID_SET, + GSS_C_ACCEPT, + &text->server_creds, + NULL, + NULL); + GSS_UNLOCK_MUTEX(params->utils); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + server_creds = text->server_creds; + } + } + + if (clientinlen) { + real_input_token.value = (void *)clientin; + real_input_token.length = clientinlen; + } + + + GSS_LOCK_MUTEX(params->utils); + maj_stat = + gss_accept_sec_context(&min_stat, + &(text->gss_ctx), + server_creds, + input_token, + GSS_C_NO_CHANNEL_BINDINGS, + &text->client_name, + &mech_type, + output_token, + &out_flags, + NULL, /* context validity period */ + &(text->client_creds)); + GSS_UNLOCK_MUTEX(params->utils); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_log(text->utils, maj_stat, min_stat); + text->utils->seterror(text->utils->conn, SASL_NOLOG, "GSSAPI Failure: gss_accept_sec_context"); + if (output_token->value) { + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + } + sasl_gss_free_context_contents(text); + return SASL_BADAUTH; + } + + if (serveroutlen) { + *serveroutlen = output_token->length; + } + if (output_token->value) { + if (serverout) { + ret = _plug_buf_alloc(text->utils, &(text->out_buf), + &(text->out_buf_len), *serveroutlen); + if(ret != SASL_OK) { + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + return ret; + } + memcpy(text->out_buf, output_token->value, *serveroutlen); + *serverout = text->out_buf; + } + + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + } else { + /* No output token, send an empty string */ + *serverout = GSSAPI_BLANK_STRING; + *serveroutlen = 0; + } + + if (maj_stat == GSS_S_CONTINUE_NEEDED) { + /* Context isn't complete */ + return SASL_CONTINUE; + } + + assert(maj_stat == GSS_S_COMPLETE); + + /* When GSS_Accept_sec_context returns GSS_S_COMPLETE, the server + examines the context to ensure that it provides a level of protection + permitted by the server's security policy. In particular, if the + integ_avail flag is not set in the context, then no security layer + can be offered or accepted. If the conf_avail flag is not set in the + context, then no security layer with confidentiality can be offered + or accepted. */ + if ((out_flags & GSS_C_INTEG_FLAG) == 0) { + /* if the integ_avail flag is not set in the context, + then no security layer can be offered or accepted. */ + text->qop = LAYER_NONE; + } else if ((out_flags & GSS_C_CONF_FLAG) == 0) { + /* If the conf_avail flag is not set in the context, + then no security layer with confidentiality can be offered + or accepted. */ + text->qop = LAYER_NONE | LAYER_INTEGRITY; + } else { + text->qop = LAYER_NONE | LAYER_INTEGRITY | LAYER_CONFIDENTIALITY; + } + + if ((params->props.security_flags & SASL_SEC_PASS_CREDENTIALS) && + (!(out_flags & GSS_C_DELEG_FLAG) || + text->client_creds == GSS_C_NO_CREDENTIAL) ) + { + text->utils->seterror(text->utils->conn, SASL_LOG_WARN, + "GSSAPI warning: no credentials were passed"); + /* continue with authentication */ + } + + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_canonicalize_name(&min_stat, + text->client_name, + mech_type, + &client_name_MN); + GSS_UNLOCK_MUTEX(params->utils); + + if (GSS_ERROR(maj_stat)) { + SETERROR(text->utils, "GSSAPI Failure: gss_canonicalize_name"); + sasl_gss_free_context_contents(text); + return SASL_BADAUTH; + } + + name_token.value = NULL; + name_without_realm.value = NULL; + + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_display_name (&min_stat, + client_name_MN, + &name_token, + NULL); + GSS_UNLOCK_MUTEX(params->utils); + + if (GSS_ERROR(maj_stat)) { + SETERROR(text->utils, "GSSAPI Failure: gss_display_name"); + sasl_gss_free_context_contents(text); + ret = SASL_BADAUTH; + goto cleanup; + } + + /* If the id contains a realm get the identifier for the user + without the realm and see if it's the same id (i.e. + tmartin == tmartin@ANDREW.CMU.EDU. If this is the case we just want + to return the id (i.e. just "tmartin" */ + if (strchr((char *) name_token.value, (int) '@') != NULL) { + /* NOTE: libc malloc, as it is freed below by a gssapi internal + * function! */ + name_without_realm.value = params->utils->malloc(strlen(name_token.value)+1); + if (name_without_realm.value == NULL) { + MEMERROR(text->utils); + ret = SASL_NOMEM; + goto cleanup; + } + + strcpy(name_without_realm.value, name_token.value); + + /* cut off string at '@' */ + (strchr(name_without_realm.value,'@'))[0] = '\0'; + + name_without_realm.length = strlen( (char *) name_without_realm.value ); + + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_import_name (&min_stat, + &name_without_realm, + /* Solaris 8/9 gss_import_name doesn't accept GSS_C_NULL_OID here, + so use GSS_C_NT_USER_NAME instead if available. */ +#ifdef HAVE_GSS_C_NT_USER_NAME + GSS_C_NT_USER_NAME, +#else + GSS_C_NULL_OID, +#endif + &without); + GSS_UNLOCK_MUTEX(params->utils); + + if (GSS_ERROR(maj_stat)) { + SETERROR(text->utils, "GSSAPI Failure: gss_import_name"); + sasl_gss_free_context_contents(text); + ret = SASL_BADAUTH; + goto cleanup; + } + + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_compare_name(&min_stat, + client_name_MN, + without, + &equal); + GSS_UNLOCK_MUTEX(params->utils); + + if (GSS_ERROR(maj_stat)) { + SETERROR(text->utils, "GSSAPI Failure: gss_compare_name"); + sasl_gss_free_context_contents(text); + ret = SASL_BADAUTH; + goto cleanup; + } + + } else { + equal = 0; + } + + if (equal) { + text->authid = strdup(name_without_realm.value); + } else { + text->authid = strdup(name_token.value); + } + + if (text->authid == NULL) { + MEMERROR(params->utils); + ret = SASL_NOMEM; + goto cleanup; + } + + if (text->http_mode) { + /* HTTP doesn't do any ssf negotiation */ + text->state = SASL_GSSAPI_STATE_AUTHENTICATED; + ret = SASL_OK; + } + else { + /* Switch to ssf negotiation */ + text->state = SASL_GSSAPI_STATE_SSFCAP; + ret = SASL_CONTINUE; + } + + cleanup: + if (client_name_MN) { + GSS_LOCK_MUTEX(params->utils); + gss_release_name(&min_stat, &client_name_MN); + GSS_UNLOCK_MUTEX(params->utils); + } + if (name_token.value) { + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, &name_token); + GSS_UNLOCK_MUTEX(params->utils); + } + if (name_without_realm.value) { + params->utils->free(name_without_realm.value); + } + if (without) { + GSS_LOCK_MUTEX(params->utils); + gss_release_name(&min_stat, &without); + GSS_UNLOCK_MUTEX(params->utils); + } + + return ret; +} + +static int +gssapi_server_mech_ssfcap(context_t *text, + sasl_server_params_t *params, + const char *clientin __attribute__((unused)), + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams __attribute__((unused))) +{ + gss_buffer_t input_token, output_token; + gss_buffer_desc real_input_token, real_output_token; + OM_uint32 maj_stat = 0, min_stat = 0; + unsigned char sasldata[4]; + int ret; + + input_token = &real_input_token; + output_token = &real_output_token; + output_token->value = NULL; output_token->length = 0; + + + if (clientinlen != 0) { + SETERROR(text->utils, "GSSAPI server is not expecting data at this stage"); + sasl_gss_free_context_contents(text); + return SASL_BADAUTH; + } + + /* we have to decide what sort of encryption/integrity/etc., + we support */ + if (params->props.max_ssf < params->external_ssf) { + text->limitssf = 0; + } else { + text->limitssf = params->props.max_ssf - params->external_ssf; + } + if (params->props.min_ssf < params->external_ssf) { + text->requiressf = 0; + } else { + text->requiressf = params->props.min_ssf - params->external_ssf; + } + + /* build up our security properties token */ + if (text->requiressf != 0 && + (text->qop & (LAYER_INTEGRITY|LAYER_CONFIDENTIALITY))) { + if (params->props.maxbufsize > 0xFFFFFF) { + /* make sure maxbufsize isn't too large */ + /* maxbufsize = 0xFFFFFF */ + sasldata[1] = sasldata[2] = sasldata[3] = 0xFF; + } else { + sasldata[1] = (params->props.maxbufsize >> 16) & 0xFF; + sasldata[2] = (params->props.maxbufsize >> 8) & 0xFF; + sasldata[3] = (params->props.maxbufsize >> 0) & 0xFF; + } + } else { + /* From RFC 4752: "The client verifies that the server maximum buffer is 0 + if the server does not advertise support for any security layer." */ + sasldata[1] = sasldata[2] = sasldata[3] = 0; + } + + sasldata[0] = 0; + if(text->requiressf != 0 && !params->props.maxbufsize) { + params->utils->seterror(params->utils->conn, 0, + "GSSAPI needs a security layer but one is forbidden"); + return SASL_TOOWEAK; + } + + if (text->requiressf == 0) { + sasldata[0] |= LAYER_NONE; /* authentication */ + } + if ((text->qop & LAYER_INTEGRITY) && + text->requiressf <= 1 && + text->limitssf >= 1 && + params->props.maxbufsize) { + sasldata[0] |= LAYER_INTEGRITY; + } + if ((text->qop & LAYER_CONFIDENTIALITY) && + text->requiressf <= K5_MAX_SSF && + text->limitssf >= K5_MAX_SSF && + params->props.maxbufsize) { + sasldata[0] |= LAYER_CONFIDENTIALITY; + } + + /* Remember what we want and can offer */ + text->qop = sasldata[0]; + + real_input_token.value = (void *)sasldata; + real_input_token.length = 4; + + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_wrap(&min_stat, + text->gss_ctx, + 0, /* Just integrity checking here */ + GSS_C_QOP_DEFAULT, + input_token, + NULL, + output_token); + GSS_UNLOCK_MUTEX(params->utils); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); + if (output_token->value) { + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + } + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + + + if (serveroutlen) + *serveroutlen = output_token->length; + if (output_token->value) { + if (serverout) { + ret = _plug_buf_alloc(text->utils, &(text->out_buf), + &(text->out_buf_len), *serveroutlen); + if(ret != SASL_OK) { + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + return ret; + } + memcpy(text->out_buf, output_token->value, *serveroutlen); + *serverout = text->out_buf; + } + + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + } + + /* Wait for ssf request and authid */ + text->state = SASL_GSSAPI_STATE_SSFREQ; + + return SASL_CONTINUE; +} + +static int +gssapi_server_mech_ssfreq(context_t *text, + sasl_server_params_t *params, + const char *clientin, + unsigned clientinlen, + const char **serverout __attribute__((unused)), + unsigned *serveroutlen __attribute__((unused)), + sasl_out_params_t *oparams) +{ + gss_buffer_t input_token, output_token; + gss_buffer_desc real_input_token, real_output_token; + OM_uint32 maj_stat = 0, min_stat = 0; + OM_uint32 max_input; + int layerchoice; + + input_token = &real_input_token; + output_token = &real_output_token; + output_token->value = NULL; output_token->length = 0; + + real_input_token.value = (void *)clientin; + real_input_token.length = clientinlen; + + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_unwrap(&min_stat, + text->gss_ctx, + input_token, + output_token, + NULL, + NULL); + GSS_UNLOCK_MUTEX(params->utils); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + + if (output_token->length < 4) { + SETERROR(text->utils, + "token too short"); + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + + layerchoice = (int)(((char *)(output_token->value))[0]); + if (layerchoice == LAYER_NONE && + (text->qop & LAYER_NONE)) { /* no encryption */ + oparams->encode = NULL; + oparams->decode = NULL; + oparams->mech_ssf = 0; + } else if (layerchoice == LAYER_INTEGRITY && + (text->qop & LAYER_INTEGRITY)) { /* integrity */ + oparams->encode = &gssapi_integrity_encode; + oparams->decode = &gssapi_decode; + oparams->mech_ssf = 1; + } else if ((layerchoice == LAYER_CONFIDENTIALITY || + /* For compatibility with broken clients setting both bits */ + layerchoice == (LAYER_CONFIDENTIALITY|LAYER_INTEGRITY)) && + (text->qop & LAYER_CONFIDENTIALITY)) { /* privacy */ + oparams->encode = &gssapi_privacy_encode; + oparams->decode = &gssapi_decode; + /* FIX ME: Need to extract the proper value here */ + oparams->mech_ssf = K5_MAX_SSF; + } else { + /* not a supported encryption layer */ + SETERROR(text->utils, + "protocol violation: client requested invalid layer"); + /* Mark that we attempted negotiation */ + oparams->mech_ssf = 2; + if (output_token->value) { + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + } + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + + if (output_token->length > 4) { + int ret; + + ret = params->canon_user(params->utils->conn, + ((char *) output_token->value) + 4, + (output_token->length - 4) * sizeof(char), + SASL_CU_AUTHZID, oparams); + + if (ret != SASL_OK) { + sasl_gss_free_context_contents(text); + return ret; + } + } + + /* No matter what, set the rest of the oparams */ + + oparams->maxoutbuf = + (((unsigned char *) output_token->value)[1] << 16) | + (((unsigned char *) output_token->value)[2] << 8) | + (((unsigned char *) output_token->value)[3] << 0); + + if (oparams->mech_ssf) { + maj_stat = gss_wrap_size_limit( &min_stat, + text->gss_ctx, + 1, + GSS_C_QOP_DEFAULT, + (OM_uint32) oparams->maxoutbuf, + &max_input); + + if(max_input > oparams->maxoutbuf) { + /* Heimdal appears to get this wrong */ + oparams->maxoutbuf -= (max_input - oparams->maxoutbuf); + } else { + /* This code is actually correct */ + oparams->maxoutbuf = max_input; + } + } + + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + + text->state = SASL_GSSAPI_STATE_AUTHENTICATED; + + /* used by layers */ + _plug_decode_init(&text->decode_context, + text->utils, + (params->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF : + params->props.maxbufsize); + + return SASL_OK; +} + +static int +gssapi_server_mech_step(void *conn_context, + sasl_server_params_t *params, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *) conn_context; + int ret; + + if (!serverout) { + PARAMERROR(text->utils); + return SASL_BADPARAM; + } + + *serverout = NULL; + *serveroutlen = 0; + + if (text == NULL) return SASL_BADPROT; + + params->utils->log(NULL, SASL_LOG_DEBUG, + "GSSAPI server step %d\n", text->state); + + switch (text->state) { + + case SASL_GSSAPI_STATE_AUTHNEG: + ret = gssapi_server_mech_authneg(text, params, clientin, clientinlen, + serverout, serveroutlen, oparams); + if (ret != SASL_CONTINUE || *serveroutlen) break; + + /* Pretend that we just got an empty response from the client */ + clientinlen = 0; + + /* fall through */ + + case SASL_GSSAPI_STATE_SSFCAP: + ret = gssapi_server_mech_ssfcap(text, params, clientin, clientinlen, + serverout, serveroutlen, oparams); + break; + + case SASL_GSSAPI_STATE_SSFREQ: + ret = gssapi_server_mech_ssfreq(text, params, clientin, clientinlen, + serverout, serveroutlen, oparams); + break; + + default: + params->utils->log(NULL, SASL_LOG_ERR, + "Invalid GSSAPI server step %d\n", text->state); + return SASL_FAIL; + } + + if (ret == SASL_OK) { + ret = params->canon_user(params->utils->conn, + text->authid, + 0, /* strlen(text->authid) */ + (oparams->user ? 0 : SASL_CU_AUTHZID) + | SASL_CU_AUTHID | SASL_CU_EXTERNALLY_VERIFIED, + oparams); + + if (ret != SASL_OK) { + sasl_gss_free_context_contents(text); + return ret; + } + + if (text->client_creds != GSS_C_NO_CREDENTIAL) { + oparams->client_creds = &text->client_creds; + } + else { + oparams->client_creds = NULL; + } + + oparams->doneflag = 1; + } + + return ret; +} + +static sasl_server_plug_t gssapi_server_plugins[] = +{ + { + "GSSAPI", /* mech_name */ + K5_MAX_SSF, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOACTIVE + | SASL_SEC_NOANONYMOUS + | SASL_SEC_MUTUAL_AUTH /* security_flags */ + | SASL_SEC_PASS_CREDENTIALS, + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY + | SASL_FEAT_DONTUSE_USERPASSWD, /* features */ + NULL, /* glob_context */ + &gssapi_server_mech_new, /* mech_new */ + &gssapi_server_mech_step, /* mech_step */ + &gssapi_common_mech_dispose, /* mech_dispose */ + &gssapi_common_mech_free, /* mech_free */ + NULL, /* setpass */ + NULL, /* user_query */ + NULL, /* idle */ + NULL, /* mech_avail */ + NULL /* spare */ + } +#ifdef HAVE_GSS_SPNEGO + ,{ + "GSS-SPNEGO", /* mech_name */ + K5_MAX_SSF, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOACTIVE + | SASL_SEC_NOANONYMOUS + | SASL_SEC_MUTUAL_AUTH /* security_flags */ + | SASL_SEC_PASS_CREDENTIALS, + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY + | SASL_FEAT_DONTUSE_USERPASSWD + | SASL_FEAT_SUPPORTS_HTTP, /* features */ + NULL, /* glob_context */ + &gssapi_server_mech_new, /* mech_new */ + &gssapi_server_mech_step, /* mech_step */ + &gssapi_common_mech_dispose, /* mech_dispose */ + &gssapi_common_mech_free, /* mech_free */ + NULL, /* setpass */ + NULL, /* user_query */ + NULL, /* idle */ + NULL, /* mech_avail */ + NULL /* spare */ + } +#endif +}; + +int gssapiv2_server_plug_init( +#ifndef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY + const sasl_utils_t *utils __attribute__((unused)), +#else + const sasl_utils_t *utils, +#endif + int maxversion, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount) +{ +#ifdef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY + const char *keytab = NULL; + char keytab_path[1024]; + unsigned int rl; +#endif + + if (maxversion < SASL_SERVER_PLUG_VERSION) { + return SASL_BADVERS; + } + +#ifdef HAVE_GSSKRB5_REGISTER_ACCEPTOR_IDENTITY + /* unfortunately, we don't check for readability of keytab if it's + the standard one, since we don't know where it is */ + + /* FIXME: This code is broken */ + + utils->getopt(utils->getopt_context, "GSSAPI", "keytab", &keytab, &rl); + if (keytab != NULL) { + if (access(keytab, R_OK) != 0) { + utils->log(NULL, SASL_LOG_ERR, + "Could not find keytab file: %s: %m", + keytab, errno); + return SASL_FAIL; + } + + if(strlen(keytab) > 1024) { + utils->log(NULL, SASL_LOG_ERR, + "path to keytab is > 1024 characters"); + return SASL_BUFOVER; + } + + strncpy(keytab_path, keytab, 1024); + + gsskrb5_register_acceptor_identity(keytab_path); + } +#endif + + *out_version = SASL_SERVER_PLUG_VERSION; + *pluglist = gssapi_server_plugins; +#ifdef HAVE_GSS_SPNEGO + *plugcount = 2; +#else + *plugcount = 1; +#endif + +#ifdef GSS_USE_MUTEXES + if (!gss_mutex) { + gss_mutex = utils->mutex_alloc(); + if (!gss_mutex) { + return SASL_FAIL; + } + } +#endif + + return SASL_OK; +} + +/***************************** Client Section *****************************/ + +static int gssapi_client_mech_new(void *glob_context, + sasl_client_params_t *params, + void **conn_context) +{ + context_t *text; + + /* holds state are in */ + text = sasl_gss_new_context(params->utils); + if (text == NULL) { + MEMERROR(params->utils); + return SASL_NOMEM; + } + + text->state = SASL_GSSAPI_STATE_AUTHNEG; + text->mech_type = (gss_OID) glob_context; + text->gss_ctx = GSS_C_NO_CONTEXT; + text->client_name = GSS_C_NO_NAME; + text->server_creds = GSS_C_NO_CREDENTIAL; + text->client_creds = GSS_C_NO_CREDENTIAL; + + text->http_mode = (params->flags & SASL_NEED_HTTP); + + *conn_context = text; + + return SASL_OK; +} + +static int gssapi_client_mech_step(void *conn_context, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *)conn_context; + gss_buffer_t input_token, output_token; + gss_buffer_desc real_input_token, real_output_token; + OM_uint32 maj_stat = 0, min_stat = 0; + OM_uint32 max_input; + gss_buffer_desc name_token; + int ret; + OM_uint32 req_flags = 0, out_req_flags = 0; + input_token = &real_input_token; + output_token = &real_output_token; + output_token->value = NULL; + input_token->value = NULL; + input_token->length = 0; + gss_cred_id_t client_creds = (gss_cred_id_t)params->gss_creds; + + *clientout = NULL; + *clientoutlen = 0; + + params->utils->log(NULL, SASL_LOG_DEBUG, + "GSSAPI client step %d", text->state); + + switch (text->state) { + + case SASL_GSSAPI_STATE_AUTHNEG: + /* try to get the userid */ + if (text->user == NULL) { + int user_result = SASL_OK; + + user_result = _plug_get_userid(params->utils, &text->user, + prompt_need); + + if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) { + sasl_gss_free_context_contents(text); + return user_result; + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + params->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if (user_result == SASL_INTERACT) { + /* make the prompt list */ + int result = + _plug_make_prompts(params->utils, prompt_need, + user_result == SASL_INTERACT ? + "Please enter your authorization name" : NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); + if (result != SASL_OK) return result; + + return SASL_INTERACT; + } + } + + if (text->server_name == GSS_C_NO_NAME) { /* only once */ + if (params->serverFQDN == NULL + || strlen(params->serverFQDN) == 0) { + SETERROR(text->utils, "GSSAPI Failure: no serverFQDN"); + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + name_token.length = strlen(params->service) + 1 + strlen(params->serverFQDN); + name_token.value = (char *)params->utils->malloc((name_token.length + 1) * sizeof(char)); + if (name_token.value == NULL) { + sasl_gss_free_context_contents(text); + return SASL_NOMEM; + } + + sprintf(name_token.value,"%s@%s", params->service, params->serverFQDN); + + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_import_name (&min_stat, + &name_token, + GSS_C_NT_HOSTBASED_SERVICE, + &text->server_name); + GSS_UNLOCK_MUTEX(params->utils); + + params->utils->free(name_token.value); + name_token.value = NULL; + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + } + + if (serverinlen == 0) + input_token = GSS_C_NO_BUFFER; + + if (serverinlen) { + real_input_token.value = (void *)serverin; + real_input_token.length = serverinlen; + } + else if (text->gss_ctx != GSS_C_NO_CONTEXT ) { + /* This can't happen under GSSAPI: we have a non-null context + * and no input from the server. However, thanks to Imap, + * which discards our first output, this happens all the time. + * Throw away the context and try again. */ + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_delete_sec_context (&min_stat,&text->gss_ctx,GSS_C_NO_BUFFER); + GSS_UNLOCK_MUTEX(params->utils); + text->gss_ctx = GSS_C_NO_CONTEXT; + } + + /* Setup req_flags properly */ + req_flags = GSS_C_INTEG_FLAG; + if (params->props.max_ssf > params->external_ssf) { + /* We are requesting a security layer */ + req_flags |= GSS_C_MUTUAL_FLAG | GSS_C_SEQUENCE_FLAG; + /* Any SSF bigger than 1 is confidentiality. */ + /* Let's check if the client of the API requires confidentiality, + and it wasn't already provided by an external layer */ + if (params->props.max_ssf - params->external_ssf > 1) { + /* We want to try for privacy */ + req_flags |= GSS_C_CONF_FLAG; + } + } + + if (params->props.security_flags & SASL_SEC_PASS_CREDENTIALS) { + req_flags = req_flags | GSS_C_DELEG_FLAG; + } + + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_init_sec_context(&min_stat, + client_creds, /* GSS_C_NO_CREDENTIAL */ + &text->gss_ctx, + text->server_name, + text->mech_type, + req_flags, + 0, + GSS_C_NO_CHANNEL_BINDINGS, + input_token, + NULL, + output_token, + &out_req_flags, + NULL); + GSS_UNLOCK_MUTEX(params->utils); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); + if (output_token->value) { + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + } + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + + if ((out_req_flags & GSS_C_INTEG_FLAG) == 0) { + /* if the integ_avail flag is not set in the context, + then no security layer can be offered or accepted. */ + text->qop = LAYER_NONE; + } else if ((out_req_flags & GSS_C_CONF_FLAG) == 0) { + /* If the conf_avail flag is not set in the context, + then no security layer with confidentiality can be offered + or accepted. */ + text->qop = LAYER_NONE | LAYER_INTEGRITY; + } else { + text->qop = LAYER_NONE | LAYER_INTEGRITY | LAYER_CONFIDENTIALITY; + } + + if ((out_req_flags & GSS_C_DELEG_FLAG) != (req_flags & GSS_C_DELEG_FLAG)) { + text->utils->seterror(text->utils->conn, SASL_LOG_WARN, "GSSAPI warning: no credentials were passed"); + /* not a fatal error */ + } + + *clientoutlen = output_token->length; + + if (output_token->value) { + if (clientout) { + ret = _plug_buf_alloc(text->utils, &(text->out_buf), + &(text->out_buf_len), *clientoutlen); + if(ret != SASL_OK) { + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + return ret; + } + memcpy(text->out_buf, output_token->value, *clientoutlen); + *clientout = text->out_buf; + } + + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + } + + if (maj_stat == GSS_S_COMPLETE) { + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_inquire_context(&min_stat, + text->gss_ctx, + &text->client_name, + NULL, /* targ_name */ + NULL, /* lifetime */ + NULL, /* mech */ + /* FIX ME: Should check the resulting flags here */ + NULL, /* flags */ + NULL, /* local init */ + NULL); /* open */ + GSS_UNLOCK_MUTEX(params->utils); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + + name_token.length = 0; + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_display_name(&min_stat, + text->client_name, + &name_token, + NULL); + GSS_UNLOCK_MUTEX(params->utils); + + if (GSS_ERROR(maj_stat)) { + if (name_token.value) { + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, &name_token); + GSS_UNLOCK_MUTEX(params->utils); + } + SETERROR(text->utils, "GSSAPI Failure"); + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + + if (text->user && text->user[0]) { + ret = params->canon_user(params->utils->conn, + text->user, 0, + SASL_CU_AUTHZID, oparams); + if (ret == SASL_OK) + ret = params->canon_user(params->utils->conn, + name_token.value, 0, + SASL_CU_AUTHID, oparams); + } else { + ret = params->canon_user(params->utils->conn, + name_token.value, 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, + oparams); + } + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, &name_token); + GSS_UNLOCK_MUTEX(params->utils); + + if (ret != SASL_OK) return ret; + + if (text->http_mode) { + /* HTTP doesn't do any ssf negotiation */ + text->state = SASL_GSSAPI_STATE_AUTHENTICATED; + oparams->doneflag = 1; + return SASL_OK; + } + + /* Switch to ssf negotiation */ + text->state = SASL_GSSAPI_STATE_SSFCAP; + } + + return SASL_CONTINUE; + + case SASL_GSSAPI_STATE_SSFCAP: { + sasl_security_properties_t *secprops = &(params->props); + unsigned int alen, external = params->external_ssf; + sasl_ssf_t need, allowed; + char serverhas, mychoice; + + real_input_token.value = (void *) serverin; + real_input_token.length = serverinlen; + + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_unwrap(&min_stat, + text->gss_ctx, + input_token, + output_token, + NULL, + NULL); + GSS_UNLOCK_MUTEX(params->utils); + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); + sasl_gss_free_context_contents(text); + if (output_token->value) { + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + } + return SASL_FAIL; + } + + if (output_token->length != 4) { + SETERROR(text->utils, + (output_token->length < 4) ? "token too short" : "token too long"); + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + + /* taken from kerberos.c */ + if (secprops->min_ssf > (K5_MAX_SSF + external)) { + return SASL_TOOWEAK; + } else if (secprops->min_ssf > secprops->max_ssf) { + return SASL_BADPARAM; + } + + /* need bits of layer -- sasl_ssf_t is unsigned so be careful */ + if (secprops->max_ssf >= external) { + allowed = secprops->max_ssf - external; + } else { + allowed = 0; + } + if (secprops->min_ssf >= external) { + need = secprops->min_ssf - external; + } else { + /* good to go */ + need = 0; + } + + /* bit mask of server support */ + serverhas = ((char *)output_token->value)[0]; + + /* use the strongest layer available */ + if ((text->qop & LAYER_CONFIDENTIALITY) && + allowed >= K5_MAX_SSF && + need <= K5_MAX_SSF && + (serverhas & LAYER_CONFIDENTIALITY)) { + + const char *ad_compat; + + /* encryption */ + oparams->encode = &gssapi_privacy_encode; + oparams->decode = &gssapi_decode; + /* FIX ME: Need to extract the proper value here */ + oparams->mech_ssf = K5_MAX_SSF; + mychoice = LAYER_CONFIDENTIALITY; + + if (serverhas & LAYER_INTEGRITY) { + /* should we send an AD compatible choice of security layers? */ + params->utils->getopt(params->utils->getopt_context, + "GSSAPI", + "ad_compat", + &ad_compat, + NULL); + if (ad_compat && + (ad_compat[0] == '1' || ad_compat[0] == 'y' || + (ad_compat[0] == 'o' && ad_compat[1] == 'n') || + ad_compat[0] == 't')) { + mychoice = LAYER_INTEGRITY|LAYER_CONFIDENTIALITY; + } + } + } else if ((text->qop & LAYER_INTEGRITY) && + allowed >= 1 && + need <= 1 && + (serverhas & LAYER_INTEGRITY)) { + /* integrity */ + oparams->encode = &gssapi_integrity_encode; + oparams->decode = &gssapi_decode; + oparams->mech_ssf = 1; + mychoice = LAYER_INTEGRITY; + } else if ((text->qop & LAYER_NONE) && + need <= 0 && (serverhas & LAYER_NONE)) { + /* no layer */ + oparams->encode = NULL; + oparams->decode = NULL; + oparams->mech_ssf = 0; + mychoice = LAYER_NONE; + } else { + /* there's no appropriate layering for us! */ + sasl_gss_free_context_contents(text); + return SASL_TOOWEAK; + } + + oparams->maxoutbuf = + (((unsigned char *) output_token->value)[1] << 16) | + (((unsigned char *) output_token->value)[2] << 8) | + (((unsigned char *) output_token->value)[3] << 0); + + if (oparams->mech_ssf) { + maj_stat = gss_wrap_size_limit( &min_stat, + text->gss_ctx, + 1, + GSS_C_QOP_DEFAULT, + (OM_uint32) oparams->maxoutbuf, + &max_input); + + if (max_input > oparams->maxoutbuf) { + /* Heimdal appears to get this wrong */ + oparams->maxoutbuf -= (max_input - oparams->maxoutbuf); + } else { + /* This code is actually correct */ + oparams->maxoutbuf = max_input; + } + } + + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + + /* oparams->user is always set, due to canon_user requirements. + * Make sure the client actually requested it though, by checking + * if our context was set. + */ + if (text->user && text->user[0]) { + alen = strlen(oparams->user); + } else { + alen = 0; + } + + input_token->length = 4 + alen; + input_token->value = + (char *)params->utils->malloc((input_token->length + 1)*sizeof(char)); + if (input_token->value == NULL) { + sasl_gss_free_context_contents(text); + return SASL_NOMEM; + } + + if (alen) + memcpy((char *)input_token->value+4,oparams->user,alen); + + /* build up our security properties token */ + if (mychoice > 1) { + if (params->props.maxbufsize > 0xFFFFFF) { + /* make sure maxbufsize isn't too large */ + /* maxbufsize = 0xFFFFFF */ + ((unsigned char *)input_token->value)[1] = 0xFF; + ((unsigned char *)input_token->value)[2] = 0xFF; + ((unsigned char *)input_token->value)[3] = 0xFF; + } else { + ((unsigned char *)input_token->value)[1] = + (params->props.maxbufsize >> 16) & 0xFF; + ((unsigned char *)input_token->value)[2] = + (params->props.maxbufsize >> 8) & 0xFF; + ((unsigned char *)input_token->value)[3] = + (params->props.maxbufsize >> 0) & 0xFF; + } + } else { + ((unsigned char *)input_token->value)[1] = 0; + ((unsigned char *)input_token->value)[2] = 0; + ((unsigned char *)input_token->value)[3] = 0; + } + ((unsigned char *)input_token->value)[0] = mychoice; + + GSS_LOCK_MUTEX(params->utils); + maj_stat = gss_wrap (&min_stat, + text->gss_ctx, + 0, /* Just integrity checking here */ + GSS_C_QOP_DEFAULT, + input_token, + NULL, + output_token); + GSS_UNLOCK_MUTEX(params->utils); + + params->utils->free(input_token->value); + input_token->value = NULL; + + if (GSS_ERROR(maj_stat)) { + sasl_gss_seterror(text->utils, maj_stat, min_stat); + if (output_token->value) { + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + } + sasl_gss_free_context_contents(text); + return SASL_FAIL; + } + + if (clientoutlen) { + *clientoutlen = output_token->length; + } + if (output_token->value) { + if (clientout) { + ret = _plug_buf_alloc(text->utils, + &(text->out_buf), + &(text->out_buf_len), + *clientoutlen); + if (ret != SASL_OK) { + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + return ret; + } + memcpy(text->out_buf, output_token->value, *clientoutlen); + *clientout = text->out_buf; + } + + GSS_LOCK_MUTEX(params->utils); + gss_release_buffer(&min_stat, output_token); + GSS_UNLOCK_MUTEX(params->utils); + + } + + text->state = SASL_GSSAPI_STATE_AUTHENTICATED; + + oparams->doneflag = 1; + + /* used by layers */ + _plug_decode_init(&text->decode_context, text->utils, + (params->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF : + params->props.maxbufsize); + + return SASL_OK; + } + + default: + params->utils->log(NULL, SASL_LOG_ERR, + "Invalid GSSAPI client step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static const unsigned long gssapi_required_prompts[] = { + SASL_CB_LIST_END +}; + +static sasl_client_plug_t gssapi_client_plugins[] = +{ + { + "GSSAPI", /* mech_name */ + K5_MAX_SSF, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOACTIVE + | SASL_SEC_NOANONYMOUS + | SASL_SEC_MUTUAL_AUTH + | SASL_SEC_PASS_CREDENTIALS, /* security_flags */ + SASL_FEAT_NEEDSERVERFQDN + | SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY, /* features */ + gssapi_required_prompts, /* required_prompts */ + GSS_C_NO_OID, /* glob_context */ + &gssapi_client_mech_new, /* mech_new */ + &gssapi_client_mech_step, /* mech_step */ + &gssapi_common_mech_dispose, /* mech_dispose */ + &gssapi_common_mech_free, /* mech_free */ + NULL, /* idle */ + NULL, /* spare */ + NULL /* spare */ + } +#ifdef HAVE_GSS_SPNEGO + ,{ + "GSS-SPNEGO", /* mech_name */ + K5_MAX_SSF, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOACTIVE + | SASL_SEC_NOANONYMOUS + | SASL_SEC_MUTUAL_AUTH + | SASL_SEC_PASS_CREDENTIALS, /* security_flags */ + SASL_FEAT_NEEDSERVERFQDN + | SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY + | SASL_FEAT_SUPPORTS_HTTP, /* features */ + gssapi_required_prompts, /* required_prompts */ + &gss_spnego_oid, /* glob_context */ + &gssapi_client_mech_new, /* mech_new */ + &gssapi_client_mech_step, /* mech_step */ + &gssapi_common_mech_dispose, /* mech_dispose */ + &gssapi_common_mech_free, /* mech_free */ + NULL, /* idle */ + NULL, /* spare */ + NULL /* spare */ + } +#endif +}; + +int gssapiv2_client_plug_init(const sasl_utils_t *utils __attribute__((unused)), + int maxversion, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_CLIENT_PLUG_VERSION) { + SETERROR(utils, "Version mismatch in GSSAPI"); + return SASL_BADVERS; + } + + *out_version = SASL_CLIENT_PLUG_VERSION; + *pluglist = gssapi_client_plugins; +#ifdef HAVE_GSS_SPNEGO + *plugcount = 2; +#else + *plugcount = 1; +#endif + +#ifdef GSS_USE_MUTEXES + if(!gss_mutex) { + gss_mutex = utils->mutex_alloc(); + if(!gss_mutex) { + return SASL_FAIL; + } + } +#endif + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/gssapiv2_init.c b/libs/cyrussasl/plugins/gssapiv2_init.c new file mode 100644 index 00000000..04c9a15e --- /dev/null +++ b/libs/cyrussasl/plugins/gssapiv2_init.c @@ -0,0 +1,43 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_CLIENT_PLUG_INIT( gssapiv2 ) +SASL_SERVER_PLUG_INIT( gssapiv2 ) + diff --git a/libs/cyrussasl/plugins/kerberos4.c b/libs/cyrussasl/plugins/kerberos4.c new file mode 100644 index 00000000..25d91830 --- /dev/null +++ b/libs/cyrussasl/plugins/kerberos4.c @@ -0,0 +1,1406 @@ +/* Kerberos4 SASL plugin + * Rob Siemborski + * Tim Martin + * $Id: kerberos4.c,v 1.100 2009/03/10 16:27:52 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include + +#ifdef WITH_DES +# ifdef WITH_SSL_DES +# include +# else +# include +# endif /* WITH_SSL_DES */ +#endif /* WITH_DES */ + +#ifdef WIN32 +# include +#elif defined(macintosh) +#include +#else +# include +# include +# include +# include +# include +#endif /* WIN32 */ +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include + +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +/* + * krb.h doenst include some functions and mac compiler is picky + * about declartions + */ +#include +#include +#endif + +#ifdef WIN32 +/* This must be after sasl.h, saslutil.h */ +# include "saslKERBEROSV4.h" + +/* KClient doesn't define this */ +typedef struct krb_principal { + char name[ANAME_SZ]; + char instance[INST_SZ]; + char realm[REALM_SZ]; +} krb_principal; + +/* This isn't defined under WIN32. For access() */ +#ifndef R_OK +#define R_OK 04 +#endif +/* we also need io.h for access() prototype */ +#include +#endif /* WIN32 */ + +#ifdef sun +/* gotta define gethostname ourselves on suns */ +extern int gethostname(char *, int); +#endif + +/***************************** Common Section *****************************/ + +static const char plugin_id[] = "$Id: kerberos4.c,v 1.100 2009/03/10 16:27:52 mel Exp $"; + +#ifndef KEYFILE +#define KEYFILE "/etc/srvtab"; +#endif + +#define KRB_SECFLAG_NONE (1) +#define KRB_SECFLAG_INTEGRITY (2) +#define KRB_SECFLAG_ENCRYPTION (4) +#define KRB_SECFLAGS (7) +#define KRB_SECFLAG_CREDENTIALS (8) + +#define KRB_DES_SECURITY_BITS (56) +#define KRB_INTEGRITY_BITS (1) + +typedef enum Krb_sec { + KRB_SEC_NONE = 0, + KRB_SEC_INTEGRITY = 1, + KRB_SEC_ENCRYPTION = 2 +} Krb_sec_t; + +typedef struct context { + int state; + + int challenge; /* this is the challenge (32 bit int) used + for the authentication */ + + char *service; /* kerberos service */ + char instance[ANAME_SZ]; + char pname[ANAME_SZ]; + char pinst[INST_SZ]; + char prealm[REALM_SZ]; + char *hostname; /* hostname */ + char *realm; /* kerberos realm */ + char *auth; /* */ + + CREDENTIALS credentials; + + des_cblock key; /* session key */ + des_cblock session; /* session key */ + + des_key_schedule init_keysched; /* key schedule for initialization */ + des_key_schedule enc_keysched; /* encryption key schedule */ + des_key_schedule dec_keysched; /* decryption key schedule */ + + + struct sockaddr_in ip_local; /* local ip address and port. + needed for layers */ + struct sockaddr_in ip_remote; /* remote ip address and port. + needed for layers */ + + const sasl_utils_t *utils; /* this is useful to have around */ + + Krb_sec_t sec_type; + char *encode_buf; /* For encoding/decoding mem management */ + char *decode_buf; + char *decode_once_buf; + unsigned encode_buf_len; + unsigned decode_buf_len; + unsigned decode_once_buf_len; + buffer_info_t *enc_in_buf; + + decode_context_t decode_context; + + char *out_buf; /* per-step mem management */ + unsigned out_buf_len; + + const char *user; /* used by client */ + + int secflags; /* client/server supports layers? */ + + long time_sec; /* These are used to make sure we are getting */ + char time_5ms; /* strictly increasing timestamps */ + +} context_t; + +#define KRB_LOCK_MUTEX(utils) \ + if(((sasl_utils_t *)(utils))->mutex_lock(krb_mutex) != 0) { \ + ((sasl_utils_t *)(utils))->seterror(((sasl_utils_t *)(utils))->conn, \ + 0, "error locking mutex"); \ + return SASL_FAIL; \ + } +#define KRB_UNLOCK_MUTEX(utils) \ + if(((sasl_utils_t *)(utils))->mutex_unlock(krb_mutex) != 0) { \ + ((sasl_utils_t *)(utils))->seterror(((sasl_utils_t *)(utils))->conn, \ + 0, "error unlocking mutex"); \ + return SASL_FAIL; \ + } + +/* Mutex for not-thread-safe kerberos 4 library */ +static void *krb_mutex = NULL; +static char *srvtab = NULL; +static unsigned refcount = 0; + +static int kerberosv4_encode(void *context, + const struct iovec *invec, + unsigned numiov, + const char **output, + unsigned *outputlen) +{ + int len, ret; + context_t *text = (context_t *)context; + struct buffer_info *inblob, bufinfo; + + if(numiov > 1) { + ret = _plug_iovec_to_buf(text->utils, invec, numiov, &text->enc_in_buf); + if(ret != SASL_OK) return ret; + inblob = text->enc_in_buf; + } else { + bufinfo.data = invec[0].iov_base; + bufinfo.curlen = invec[0].iov_len; + inblob = &bufinfo; + } + + ret = _plug_buf_alloc(text->utils, &(text->encode_buf), + &text->encode_buf_len, inblob->curlen+40); + + if(ret != SASL_OK) return ret; + + KRB_LOCK_MUTEX(text->utils); + + if (text->sec_type == KRB_SEC_ENCRYPTION) { + /* Type incompatibility on 4th arg probably means you're + building against krb4 in MIT krb5, but got the OpenSSL + headers in your way. You need to not use openssl/des.h with + MIT kerberos. */ + len=krb_mk_priv(inblob->data, (text->encode_buf+4), + inblob->curlen, text->init_keysched, + &text->session, &text->ip_local, + &text->ip_remote); + } else if (text->sec_type == KRB_SEC_INTEGRITY) { + len=krb_mk_safe(inblob->data, (text->encode_buf+4), + inblob->curlen, + &text->session, &text->ip_local, &text->ip_remote); + } else { + len = -1; + } + + KRB_UNLOCK_MUTEX(text->utils); + + /* returns -1 on error */ + if (len==-1) return SASL_FAIL; + + /* now copy in the len of the buffer in network byte order */ + *outputlen=len+4; + len=htonl(len); + memcpy(text->encode_buf, &len, 4); + + /* Setup the const pointer */ + *output = text->encode_buf; + + return SASL_OK; +} + +static int kerberosv4_decode_packet(void *context, + const char *input, unsigned inputlen, + char **output, unsigned *outputlen) +{ + context_t *text = (context_t *) context; + int result; + MSG_DAT data; + + memset(&data,0,sizeof(MSG_DAT)); + + KRB_LOCK_MUTEX(text->utils); + + if (text->sec_type == KRB_SEC_ENCRYPTION) { + result=krb_rd_priv(input, inputlen, text->init_keysched, + &text->session, &text->ip_remote, + &text->ip_local, &data); + } else if (text->sec_type == KRB_SEC_INTEGRITY) { + result = krb_rd_safe(input, inputlen, + &text->session, &text->ip_remote, + &text->ip_local, &data); + } else { + KRB_UNLOCK_MUTEX(text->utils); + text->utils->seterror(text->utils->conn, 0, + "KERBEROS_4 decode called with KRB_SEC_NONE"); + return SASL_FAIL; + } + + KRB_UNLOCK_MUTEX(text->utils); + + /* see if the krb library gave us a failure */ + if (result != 0) { + text->utils->seterror(text->utils->conn, 0, get_krb_err_txt(result)); + return SASL_FAIL; + } + + /* check to make sure the timestamps are ok */ + if ((data.time_sec < text->time_sec) || /* if an earlier time */ + (((data.time_sec == text->time_sec) && /* or the exact same time */ + (data.time_5ms < text->time_5ms)))) + { + text->utils->seterror(text->utils->conn, 0, "timestamps not ok"); + return SASL_FAIL; + } + + text->time_sec = data.time_sec; + text->time_5ms = data.time_5ms; + + result = _plug_buf_alloc(text->utils, &text->decode_once_buf, + &text->decode_once_buf_len, + data.app_length + 1); + if(result != SASL_OK) + return result; + + *output = text->decode_once_buf; + *outputlen = data.app_length; + memcpy(*output, data.app_data, data.app_length); + (*output)[*outputlen] = '\0'; + + return SASL_OK; +} + +static int kerberosv4_decode(void *context, + const char *input, unsigned inputlen, + const char **output, unsigned *outputlen) +{ + context_t *text = (context_t *) context; + int ret; + + ret = _plug_decode(&text->decode_context, input, inputlen, + &text->decode_buf, &text->decode_buf_len, outputlen, + kerberosv4_decode_packet, text); + + *output = text->decode_buf; + + return ret; +} + +static int new_text(const sasl_utils_t *utils, context_t **text) +{ + context_t *ret = (context_t *) utils->malloc(sizeof(context_t)); + + if (ret == NULL) { + MEMERROR(utils); + return SASL_NOMEM; + } + + memset(ret, 0, sizeof(context_t)); + + ret->state = 1; + ret->utils = utils; + + *text = ret; + + return SASL_OK; +} + +static void kerberosv4_common_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + context_t *text = (context_t *)conn_context; + + if(!text) return; + + _plug_decode_free(&text->decode_context); + if (text->encode_buf) utils->free(text->encode_buf); + if (text->decode_buf) utils->free(text->decode_buf); + if (text->decode_once_buf) utils->free(text->decode_once_buf); + if (text->out_buf) utils->free(text->out_buf); + if (text->enc_in_buf) { + if(text->enc_in_buf->data) utils->free(text->enc_in_buf->data); + utils->free(text->enc_in_buf); + } + /* no need to free userid, it's just the interaction result */ + + utils->free(text); +} + +static void +kerberosv4_common_mech_free(void *glob_context __attribute__((unused)), + const sasl_utils_t *utils) +{ + if (krb_mutex) { + utils->mutex_free(krb_mutex); + krb_mutex = NULL; /* in case we need to re-use it */ + } + refcount--; + if (srvtab && !refcount) { + utils->free(srvtab); + srvtab = NULL; + } +} + +/***************************** Server Section *****************************/ + +static int cando_sec(sasl_security_properties_t *props, + int external_ssf, + int secflag) +{ + int need; + int musthave; + + if(props->maxbufsize == 0) { + need = musthave = 0; + } else { + need = props->max_ssf - external_ssf; + musthave = props->min_ssf - external_ssf; + } + + switch (secflag) { + case KRB_SECFLAG_NONE: + if (musthave <= 0) + return 1; + break; + case KRB_SECFLAG_INTEGRITY: + if ((musthave <= KRB_INTEGRITY_BITS) + && (KRB_INTEGRITY_BITS <= need)) + return 1; + break; + case KRB_SECFLAG_ENCRYPTION: + if ((musthave <= KRB_DES_SECURITY_BITS) + && (KRB_DES_SECURITY_BITS <= need)) + return 1; + break; + case KRB_SECFLAG_CREDENTIALS: + if (props->security_flags & SASL_SEC_PASS_CREDENTIALS) + return 1; + break; + } + return 0; +} + +static int ipv4_ipfromstring(const sasl_utils_t *utils, const char *addr, + struct sockaddr_in *out) +{ + struct sockaddr_storage ss; + int result; + + result = _plug_ipfromstring(utils, addr, + (struct sockaddr *)&ss, sizeof(ss)); + if (result != SASL_OK) { + /* couldn't get local IP address */ + return result; + } + /* Kerberos_V4 supports only IPv4 */ + if (((struct sockaddr *)&ss)->sa_family != AF_INET) + return SASL_FAIL; + memcpy(out, &ss, sizeof(struct sockaddr_in)); + + return SASL_OK; +} + +#ifndef macintosh +static int +kerberosv4_server_mech_new(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + void **conn_context) +{ + return new_text(sparams->utils, (context_t **) conn_context); +} + +static int kerberosv4_server_mech_step(void *conn_context, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *) conn_context; + int result; + + *serverout = NULL; + *serveroutlen = 0; + + switch (text->state) { + + case 1: { + /* random 32-bit number */ + int randocts, nchal; + + /* shouldn't we check for erroneous client input here?!? */ + + sparams->utils->rand(sparams->utils->rpool,(char *) &randocts , + sizeof(randocts)); + text->challenge=randocts; + nchal = htonl(text->challenge); + + result = _plug_buf_alloc(text->utils, &text->out_buf, + &text->out_buf_len, 5); + if (result != SASL_OK) return result; + + memcpy(text->out_buf,&nchal,4); + *serverout = text->out_buf; + *serveroutlen = 4; + + text->state = 2; + + return SASL_CONTINUE; + } + + case 2: { + int nchal; + unsigned char sout[8]; + AUTH_DAT ad; + KTEXT_ST ticket; + unsigned lup; + struct sockaddr_in addr; + char *dot; + + /* received authenticator */ + + /* create ticket */ + if (clientinlen > MAX_KTXT_LEN) { + text->utils->seterror(text->utils->conn,0, + "request larger than maximum ticket size"); + return SASL_FAIL; + } + + ticket.length=clientinlen; + for (lup = 0; lup < clientinlen; lup++) + ticket.dat[lup] = clientin[lup]; + + KRB_LOCK_MUTEX(sparams->utils); + + text->realm = krb_realmofhost(sparams->serverFQDN); + + /* get instance */ + strncpy (text->instance, krb_get_phost (sparams->serverFQDN), + sizeof (text->instance)); + + KRB_UNLOCK_MUTEX(sparams->utils); + + text->instance[sizeof(text->instance)-1] = 0; + + /* At some sites, krb_get_phost() sensibly but + * atypically returns FQDNs, versus the first component, + * which is what we need for RFC2222 section 7.1 + */ + dot = strchr(text->instance, '.'); + if (dot) *dot = '\0'; + + memset(&addr, 0, sizeof(struct sockaddr_in)); + +#ifndef KRB4_IGNORE_IP_ADDRESS + /* (we ignore IP addresses in krb4 tickets at CMU to facilitate moving + from machine to machine) */ + + /* get ip number in addr*/ + result = ipv4_ipfromstring(sparams->utils, sparams->ipremoteport, &addr); + if (result != SASL_OK || !sparams->ipremoteport) { + SETERROR(text->utils, "couldn't get remote IP address"); + return result; + } +#endif + + /* check ticket */ + + KRB_LOCK_MUTEX(sparams->utils); + result = krb_rd_req(&ticket, (char *) sparams->service, text->instance, + addr.sin_addr.s_addr, &ad, srvtab); + KRB_UNLOCK_MUTEX(sparams->utils); + + if (result) { /* if fails mechanism fails */ + text->utils->seterror(text->utils->conn,0, + "krb_rd_req failed service=%s instance=%s error code=%s (%i)", + sparams->service, text->instance,get_krb_err_txt(result),result); + return SASL_BADAUTH; + } + + /* 8 octets of data + * 1-4 checksum+1 + * 5 security layers + * 6-8max cipher text buffer size + * use DES ECB in the session key + */ + + nchal=htonl(text->challenge+1); + memcpy(sout, &nchal, 4); + sout[4]= 0; + if (cando_sec(&sparams->props, sparams->external_ssf, + KRB_SECFLAG_NONE)) + sout[4] |= KRB_SECFLAG_NONE; + if (cando_sec(&sparams->props, sparams->external_ssf, + KRB_SECFLAG_INTEGRITY)) + sout[4] |= KRB_SECFLAG_INTEGRITY; + if (cando_sec(&sparams->props, sparams->external_ssf, + KRB_SECFLAG_ENCRYPTION)) + sout[4] |= KRB_SECFLAG_ENCRYPTION; + if (cando_sec(&sparams->props, sparams->external_ssf, + KRB_SECFLAG_CREDENTIALS)) + sout[4] |= KRB_SECFLAG_CREDENTIALS; + + if(sparams->props.maxbufsize) { + int tmpmaxbuf = (sparams->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF : sparams->props.maxbufsize; + + sout[5]=((tmpmaxbuf >> 16) & 0xFF); + sout[6]=((tmpmaxbuf >> 8) & 0xFF); + sout[7]=(tmpmaxbuf & 0xFF); + } else { + /* let's say we can support up to 64K */ + /* no inherent inability with our layers to support more */ + + sout[5]=0x00; /* max ciphertext buffer size */ + sout[6]=0xFF; + sout[7]=0xFF; + } + + memcpy(text->session, ad.session, 8); + memcpy(text->pname, ad.pname, sizeof(text->pname)); + memcpy(text->pinst, ad.pinst, sizeof(text->pinst)); + memcpy(text->prealm, ad.prealm, sizeof(text->prealm)); + des_key_sched(&ad.session, text->init_keysched); + + /* make keyschedule for encryption and decryption */ + des_key_sched(&ad.session, text->enc_keysched); + des_key_sched(&ad.session, text->dec_keysched); + + des_ecb_encrypt((des_cblock *)sout, + (des_cblock *)sout, + text->init_keysched, + DES_ENCRYPT); + + result = _plug_buf_alloc(text->utils, &text->out_buf, + &text->out_buf_len, 9); + if(result != SASL_OK) + return result; + + memcpy(text->out_buf,&sout,8); + *serverout = text->out_buf; + *serveroutlen = 8; + + text->state = 3; + + return SASL_CONTINUE; + } + + case 3: { + int result; + int testnum; + int flag; + unsigned char *in; + + if ((clientinlen == 0) || (clientinlen % 8 != 0)) { + text->utils->seterror(text->utils->conn,0, + "Response to challengs is not a multiple of 8 octets (a DES block)"); + return SASL_FAIL; + } + + /* we need to make a copy because des does in place decrpytion */ + in = sparams->utils->malloc(clientinlen + 1); + if (in == NULL) { + MEMERROR(sparams->utils); + return SASL_NOMEM; + } + + memcpy(in, clientin, clientinlen); + in[clientinlen] = '\0'; + + /* decrypt; verify checksum */ + + des_pcbc_encrypt((des_cblock *)in, + (des_cblock *)in, + clientinlen, + text->init_keysched, + &text->session, + DES_DECRYPT); + + testnum = (in[0]*256*256*256)+(in[1]*256*256)+(in[2]*256)+in[3]; + + if (testnum != text->challenge) { + SETERROR(sparams->utils, "incorrect response to challenge"); + return SASL_BADAUTH; + } + + if (!cando_sec(&sparams->props, sparams->external_ssf, + in[4] & KRB_SECFLAGS)) { + SETERROR(sparams->utils, + "invalid security property specified"); + return SASL_BADPROT; + } + + oparams->encode = &kerberosv4_encode; + oparams->decode = &kerberosv4_decode; + + switch (in[4] & KRB_SECFLAGS) { + case KRB_SECFLAG_NONE: + text->sec_type = KRB_SEC_NONE; + oparams->encode = NULL; + oparams->decode = NULL; + oparams->mech_ssf = 0; + break; + case KRB_SECFLAG_INTEGRITY: + text->sec_type = KRB_SEC_INTEGRITY; + oparams->mech_ssf = KRB_INTEGRITY_BITS; + break; + case KRB_SECFLAG_ENCRYPTION: + text->sec_type = KRB_SEC_ENCRYPTION; + oparams->mech_ssf = KRB_DES_SECURITY_BITS; + break; + default: + /* Mark that we tried */ + oparams->mech_ssf = 2; + SETERROR(sparams->utils, "not a supported encryption layer"); + return SASL_BADPROT; + } + + /* get ip data */ + /* get ip number in addr*/ + result = ipv4_ipfromstring(sparams->utils, + sparams->iplocalport, &(text->ip_local)); + if (result != SASL_OK) { + SETERROR(sparams->utils, "couldn't get local ip address"); + /* couldn't get local IP address */ + return result; + } + + result = ipv4_ipfromstring(sparams->utils, + sparams->ipremoteport, &(text->ip_remote)); + if (result != SASL_OK) { + SETERROR(sparams->utils, "couldn't get remote ip address"); + /* couldn't get remote IP address */ + return result; + } + + /* fill in oparams */ + oparams->maxoutbuf = (in[5] << 16) + (in[6] << 8) + in[7]; + if(oparams->mech_ssf) { + /* FIXME: Likely to be too large */ + oparams->maxoutbuf -= 50; + } + + if (sparams->canon_user) { + char *user=NULL, *authid=NULL; + size_t ulen = 0, alen = strlen(text->pname); + int ret, cflag = SASL_CU_AUTHID | SASL_CU_EXTERNALLY_VERIFIED; + + if (text->pinst[0]) { + alen += strlen(text->pinst) + 1 /* for the . */; + } + flag = 0; + if (strcmp(text->realm, text->prealm)) { + alen += strlen(text->prealm) + 1 /* for the @ */; + flag = 1; + } + + authid = sparams->utils->malloc(alen + 1); + if (!authid) { + MEMERROR(sparams->utils); + return SASL_NOMEM; + } + + strcpy(authid, text->pname); + if (text->pinst[0]) { + strcat(authid, "."); + strcat(authid, text->pinst); + } + if (flag) { + strcat(authid, "@"); + strcat(authid, text->prealm); + } + + if (in[8]) { + user = sparams->utils->malloc(strlen((char *) in + 8) + 1); + if (!user) { + MEMERROR(sparams->utils); + return SASL_NOMEM; + } + + strcpy(user, (char *) in + 8); + ulen = strlen(user); + } else { + cflag |= SASL_CU_AUTHZID; + } + + ret = sparams->canon_user(sparams->utils->conn, authid, alen, + cflag, oparams); + sparams->utils->free(authid); + if (ret != SASL_OK) { + if (user) + sparams->utils->free(user); + return ret; + } + + if (user) { + ret = sparams->canon_user(sparams->utils->conn, user, ulen, + SASL_CU_AUTHZID, oparams); + + sparams->utils->free(user); + } + + if (ret != SASL_OK) return ret; + } + + /* nothing more to do; authenticated */ + oparams->doneflag = 1; + oparams->param_version = 0; + + /* used by layers */ + _plug_decode_init(&text->decode_context, text->utils, + (sparams->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF : + sparams->props.maxbufsize); + + sparams->utils->free(in); + + return SASL_OK; + } + + default: + sparams->utils->log(NULL, SASL_LOG_ERR, + "Invalid Kerberos server step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static int kerberosv4_mech_avail(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + void **conn_context __attribute__((unused))) +{ + struct sockaddr_in addr; + + if (!sparams->iplocalport || !sparams->ipremoteport + || ipv4_ipfromstring(sparams->utils, + sparams->iplocalport, &addr) != SASL_OK + || ipv4_ipfromstring(sparams->utils, + sparams->ipremoteport, &addr) != SASL_OK) { + SETERROR(sparams->utils, + "KERBEROS_V4 unavailable due to lack of IPv4 information"); + return SASL_NOMECH; + } + + return SASL_OK; +} + + +static sasl_server_plug_t kerberosv4_server_plugins[] = +{ + { + "KERBEROS_V4", /* mech_name */ + KRB_DES_SECURITY_BITS, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOACTIVE + | SASL_SEC_NOANONYMOUS + | SASL_SEC_MUTUAL_AUTH, /* security_flags */ + SASL_FEAT_SERVER_FIRST + | SASL_FEAT_ALLOWS_PROXY, /* features */ + NULL, /* glob_context */ + &kerberosv4_server_mech_new, /* mech_new */ + &kerberosv4_server_mech_step, /* mech_step */ + &kerberosv4_common_mech_dispose,/* mech_dispose */ + &kerberosv4_common_mech_free, /* mech_free */ + NULL, /* setpass */ + NULL, /* user_query */ + NULL, /* idle */ + &kerberosv4_mech_avail, /* mech_avail */ + NULL /* spare */ + } +}; +#endif /* macintosh */ + +int kerberos4_server_plug_init(const sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount) +{ +#ifdef macintosh + return SASL_BADVERS; +#else + const char *ret; + unsigned int rl; + + if (maxversion < SASL_SERVER_PLUG_VERSION) { + return SASL_BADVERS; + } + + + if (!krb_mutex) { + krb_mutex = utils->mutex_alloc(); + if(!krb_mutex) { + return SASL_FAIL; + } + } + + if (!srvtab) { + utils->getopt(utils->getopt_context, + "KERBEROS_V4", "srvtab", &ret, &rl); + + if (ret == NULL) { + ret = KEYFILE; + rl = strlen(ret); + } + + srvtab = utils->malloc(sizeof(char) * (rl + 1)); + if(!srvtab) { + MEMERROR(utils); + return SASL_NOMEM; + } + + strcpy(srvtab, ret); + } + + refcount++; + + /* fail if we can't open the srvtab file */ + if (access(srvtab, R_OK) != 0) { + utils->log(NULL, SASL_LOG_ERR, + "can't access srvtab file %s: %m", srvtab, errno); + if(!(--refcount)) { + utils->free(srvtab); + srvtab=NULL; + } + return SASL_FAIL; + } + + *out_version = SASL_SERVER_PLUG_VERSION; + *pluglist = kerberosv4_server_plugins; + *plugcount = 1; + + return SASL_OK; +#endif +} + +/***************************** Client Section *****************************/ + +static int +kerberosv4_client_mech_new(void *glob_context __attribute__((unused)), + sasl_client_params_t *params, + void **conn_context) +{ + return new_text(params->utils, (context_t **) conn_context); +} + +static int kerberosv4_client_mech_step(void *conn_context, + sasl_client_params_t *cparams, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *) conn_context; + KTEXT_ST authent; + int ret; + + *clientout = NULL; + *clientoutlen = 0; + + authent.length = MAX_KTXT_LEN; + + switch (text->state) { + + case 1: { + /* We should've just recieved a 32-bit number in network byte order. + * We want to reply with an authenticator. */ + int result; + KTEXT_ST ticket; + char *dot; + + memset(&ticket, 0L, sizeof(ticket)); + ticket.length = MAX_KTXT_LEN; + + if (serverinlen != 4) { + text->utils->seterror(text->utils->conn, 0, + "server challenge not 4 bytes long"); + return SASL_BADPROT; + } + + memcpy(&text->challenge, serverin, 4); + + text->challenge=ntohl(text->challenge); + + if (cparams->serverFQDN == NULL) { + cparams->utils->log(NULL, SASL_LOG_ERR, + "no 'serverFQDN' set"); + SETERROR(text->utils, "paramater error"); + return SASL_BADPARAM; + } + if (cparams->service == NULL) { + cparams->utils->log(NULL, SASL_LOG_ERR, + "no 'service' set"); + SETERROR(text->utils, "paramater error"); + return SASL_BADPARAM; + } + + KRB_LOCK_MUTEX(cparams->utils); + text->realm=krb_realmofhost(cparams->serverFQDN); + text->hostname=(char *) cparams->serverFQDN; + + /* the instance of the principal we're authenticating with */ + strncpy (text->instance, krb_get_phost (cparams->serverFQDN), + sizeof (text->instance)); + + /* text->instance is NULL terminated unless it was too long */ + text->instance[sizeof(text->instance)-1] = '\0'; + + /* At some sites, krb_get_phost() sensibly but + * atypically returns FQDNs, versus the first component, + * which is what we need for RFC2222 section 7.1 + */ + dot = strchr(text->instance, '.'); + if (dot) *dot = '\0'; + +#ifndef macintosh + if ((result = krb_mk_req(&ticket, (char *) cparams->service, + text->instance, text->realm, text->challenge))) +#else + memset(&text->credentials,0,sizeof(text->credentials)); + if (kcglue_krb_mk_req(ticket.dat, + &ticket.length, + cparams->service, + text->instance, + text->realm, + text->challenge, + &text->credentials.session, + text->credentials.pname, + text->credentials.pinst) != 0) +#endif + { + KRB_UNLOCK_MUTEX(cparams->utils); + + text->utils->seterror(text->utils->conn,SASL_NOLOG, + "krb_mk_req() failed"); + + cparams->utils->log(NULL, SASL_LOG_ERR, + "krb_mk_req() failed: %s (%d)", + get_krb_err_txt(result), result); + return SASL_FAIL; + } + + KRB_UNLOCK_MUTEX(cparams->utils); + + ret = _plug_buf_alloc(text->utils, &(text->out_buf), + &(text->out_buf_len), ticket.length); + if (ret != SASL_OK) return ret; + + memcpy(text->out_buf, ticket.dat, ticket.length); + + *clientout = text->out_buf; + *clientoutlen = ticket.length; + + text->state = 2; + + return SASL_CONTINUE; + } + + /* challenge #2 */ + case 2: { + int need = 0; + int musthave = 0; + int testnum; + int nchal; + unsigned char *sout = NULL; + unsigned len; + unsigned char in[8]; + int result; + int servermaxbuf; + char *buf; + int user_result = SASL_OK; + + /* try to get the authid */ + if (text->user == NULL) { + user_result = _plug_get_userid(cparams->utils, &text->user, + prompt_need); + + if (user_result != SASL_OK && user_result != SASL_INTERACT) + return user_result; + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + cparams->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if (user_result == SASL_INTERACT) { + /* make the prompt list */ + int result = + _plug_make_prompts(cparams->utils, prompt_need, + user_result == SASL_INTERACT ? + "Please enter your authorization name" : NULL, NULL, + NULL, NULL, + NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); + if (result!=SASL_OK) return result; + + return SASL_INTERACT; + } + + /* must be 8 octets */ + if (serverinlen!=8) { + SETERROR(cparams->utils, + "server response not 8 bytes long"); + return SASL_BADAUTH; + } + + memcpy(in, serverin, 8); + +#ifndef macintosh + /* get credentials */ + KRB_LOCK_MUTEX(cparams->utils); + result = krb_get_cred((char *)cparams->service, + text->instance, + text->realm, + &text->credentials); + KRB_UNLOCK_MUTEX(cparams->utils); + + if(result != 0) { + cparams->utils->log(NULL, SASL_LOG_ERR, + "krb_get_cred() failed: %s (%d)", + get_krb_err_txt(result), result); + SETERROR(cparams->utils, "krb_get_cred() failed"); + return SASL_BADAUTH; + } +#endif + memcpy(text->session, text->credentials.session, 8); + + /* make key schedule for encryption and decryption */ + des_key_sched(&text->session, text->init_keysched); + des_key_sched(&text->session, text->enc_keysched); + des_key_sched(&text->session, text->dec_keysched); + + /* decrypt from server */ + des_ecb_encrypt((des_cblock *)in, (des_cblock *)in, + text->init_keysched, DES_DECRYPT); + + /* convert to 32bit int */ + testnum = (in[0]*256*256*256)+(in[1]*256*256)+(in[2]*256)+in[3]; + + /* verify data 1st 4 octets must be equal to chal+1 */ + if (testnum != text->challenge+1) { + SETERROR(cparams->utils,"server response incorrect"); + return SASL_BADAUTH; + } + + /* construct 8 octets + * 1-4 - original checksum + * 5 - bitmask of sec layer + * 6-8 max buffer size + */ + if (cparams->props.min_ssf > + KRB_DES_SECURITY_BITS + cparams->external_ssf) { + SETERROR(cparams->utils, + "minimum ssf too strong for this mechanism"); + return SASL_TOOWEAK; + } else if (cparams->props.min_ssf > cparams->props.max_ssf) { + SETERROR(cparams->utils, + "minimum ssf larger than maximum ssf"); + return SASL_BADPARAM; + } + + /* create stuff to send to server */ + sout = (char *) + cparams->utils->malloc(9+(text->user ? strlen(text->user) : 0)+9); + if (!sout) { + MEMERROR(cparams->utils); + return SASL_NOMEM; + } + + nchal = htonl(text->challenge); + memcpy(sout, &nchal, 4); + + /* need bits of layer */ + if(cparams->props.maxbufsize == 0) { + need = musthave = 0; + } else { + need = cparams->props.max_ssf - cparams->external_ssf; + musthave = cparams->props.min_ssf - cparams->external_ssf; + } + + oparams->decode = &kerberosv4_decode; + oparams->encode = &kerberosv4_encode; + + if ((in[4] & KRB_SECFLAG_ENCRYPTION) + && (need>=56) && (musthave <= 56)) { + /* encryption */ + text->sec_type = KRB_SEC_ENCRYPTION; + oparams->mech_ssf = 56; + sout[4] = KRB_SECFLAG_ENCRYPTION; + /* using encryption layer */ + } else if ((in[4] & KRB_SECFLAG_INTEGRITY) + && (need >= 1) && (musthave <= 1)) { + /* integrity */ + text->sec_type = KRB_SEC_INTEGRITY; + oparams->mech_ssf=1; + sout[4] = KRB_SECFLAG_INTEGRITY; + /* using integrity layer */ + } else if ((in[4] & KRB_SECFLAG_NONE) && (musthave <= 0)) { + /* no layer */ + text->sec_type = KRB_SEC_NONE; + oparams->encode=NULL; + oparams->decode=NULL; + oparams->mech_ssf=0; + sout[4] = KRB_SECFLAG_NONE; + } else { + /* Mark that we tried */ + oparams->mech_ssf=2; + SETERROR(cparams->utils, + "unable to agree on layers with server"); + return SASL_BADPROT; + } + + servermaxbuf = in[5]*256*256+in[6]*256+in[7]; + oparams->maxoutbuf = servermaxbuf; + if (oparams->mech_ssf) { + /* FIXME: Likely to be too large */ + oparams->maxoutbuf -= 50; + } + + if(cparams->props.maxbufsize) { + int tmpmaxbuf = ( cparams->props.maxbufsize > 0xFFFFFF ) ? 0xFFFFFF : cparams->props.maxbufsize; + + sout[5]=((tmpmaxbuf >> 16) & 0xFF); + sout[6]=((tmpmaxbuf >> 8) & 0xFF); + sout[7]=(tmpmaxbuf & 0xFF); + } else { + /* let's say we can support up to 64K */ + /* no inherent inability with our layers to support more */ + + sout[5]=0x00; /* max ciphertext buffer size */ + sout[6]=0xFF; + sout[7]=0xFF; + } + + sout[8] = 0x00; /* just to be safe */ + + /* append userid */ + len = 9; /* 8 + trailing NULL */ + if (text->user) { + strcpy((char *)sout + 8, text->user); + len += strlen(text->user); + } + + /* append 0 based octets so is multiple of 8 */ + while(len % 8) { + sout[len]=0; + len++; + } + sout[len]=0; + + des_pcbc_encrypt((des_cblock *)sout, + (des_cblock *)sout, + len, + text->init_keysched, + (des_cblock *)text->session, + DES_ENCRYPT); + + result = _plug_buf_alloc(text->utils, &text->out_buf, + &text->out_buf_len, len); + if (result != SASL_OK) return result; + + memcpy(text->out_buf, sout, len); + + *clientout = text->out_buf; + *clientoutlen = len; + + /* nothing more to do; should be authenticated */ + if(cparams->iplocalport) { + result = ipv4_ipfromstring(cparams->utils, + cparams->iplocalport, + &(text->ip_local)); + if (result != SASL_OK) { + /* couldn't get local IP address */ + return result; + } + } + + if (cparams->ipremoteport) { + result = ipv4_ipfromstring(cparams->utils, + cparams->ipremoteport, + &(text->ip_remote)); + if (result != SASL_OK) { + /* couldn't get local IP address */ + return result; + } + } + + buf = cparams->utils->malloc(strlen(text->credentials.pname) + + strlen(text->credentials.pinst) + + 2); + if (!buf) { + MEMERROR(cparams->utils); + return SASL_NOMEM; + } + strcpy(buf, text->credentials.pname); + if (text->credentials.pinst[0]) { + strcat(buf, "."); + strcat(buf, text->credentials.pinst); + } + + if (text->user && !text->user[0]) { + text->user = NULL; + } + + ret = cparams->canon_user(cparams->utils->conn, buf, 0, + SASL_CU_AUTHID, oparams); + if (ret != SASL_OK) { + cparams->utils->free(buf); + cparams->utils->free(sout); + return ret; + } + + if (!text->user) { + /* 0 in length fields means use strlen() */ + ret = cparams->canon_user(cparams->utils->conn, buf, 0, + SASL_CU_AUTHZID, oparams); + } else { + ret = cparams->canon_user(cparams->utils->conn, text->user, 0, + SASL_CU_AUTHZID, oparams); + } + + cparams->utils->free(buf); + + oparams->doneflag = 1; + oparams->param_version = 0; + + /* used by layers */ + _plug_decode_init(&text->decode_context, text->utils, + (cparams->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF : + cparams->props.maxbufsize); + + if (sout) cparams->utils->free(sout); + + return SASL_OK; + } + + default: + cparams->utils->log(NULL, SASL_LOG_ERR, + "Invalid Kerberos client step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static const long kerberosv4_required_prompts[] = { + SASL_CB_LIST_END +}; + +static sasl_client_plug_t kerberosv4_client_plugins[] = +{ + { + "KERBEROS_V4", /* mech_name */ + KRB_DES_SECURITY_BITS, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOACTIVE + | SASL_SEC_NOANONYMOUS + | SASL_SEC_MUTUAL_AUTH, /* security_flags */ + SASL_FEAT_NEEDSERVERFQDN + | SASL_FEAT_SERVER_FIRST + | SASL_FEAT_ALLOWS_PROXY, /* features */ + kerberosv4_required_prompts, /* required_prompts */ + NULL, /* glob_context */ + &kerberosv4_client_mech_new, /* mech_new */ + &kerberosv4_client_mech_step, /* mech_step */ + &kerberosv4_common_mech_dispose,/* mech_dispose */ + &kerberosv4_common_mech_free, /* mech_free */ + NULL, /* idle */ + NULL, /* spare */ + NULL /* spare */ + } +}; + +int kerberos4_client_plug_init(const sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_CLIENT_PLUG_VERSION) { + SETERROR(utils, "Wrong KERBEROS_V4 version"); + return SASL_BADVERS; + } + + if(!krb_mutex) { + krb_mutex = utils->mutex_alloc(); + if(!krb_mutex) { + return SASL_FAIL; + } + } + + *out_version = SASL_CLIENT_PLUG_VERSION; + *pluglist = kerberosv4_client_plugins; + *plugcount = 1; + + refcount++; + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/kerberos4_init.c b/libs/cyrussasl/plugins/kerberos4_init.c new file mode 100644 index 00000000..10580333 --- /dev/null +++ b/libs/cyrussasl/plugins/kerberos4_init.c @@ -0,0 +1,43 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_CLIENT_PLUG_INIT( kerberos4 ) +SASL_SERVER_PLUG_INIT( kerberos4 ) + diff --git a/libs/cyrussasl/plugins/ldapdb.c b/libs/cyrussasl/plugins/ldapdb.c new file mode 100644 index 00000000..ddead7f3 --- /dev/null +++ b/libs/cyrussasl/plugins/ldapdb.c @@ -0,0 +1,569 @@ +/* $OpenLDAP: pkg/ldap/contrib/ldapsasl/ldapdb.c,v 1.1.2.7 2003/11/29 22:10:03 hyc Exp $ */ +/* SASL LDAP auxprop+canonuser implementation + * Copyright (C) 2002-2007 Howard Chu, All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ + +#include + +#include +#include + +#include "sasl.h" +#include "saslutil.h" +#include "saslplug.h" + +#include "plugin_common.h" + +#include + +static char ldapdb[] = "ldapdb"; + +typedef struct ldapctx { + int inited; /* Have we already read the config? */ + const char *uri; /* URI of LDAP server */ + struct berval id; /* SASL authcid to bind as */ + struct berval pw; /* password for bind */ + struct berval mech; /* SASL mech */ + int use_tls; /* Issue StartTLS request? */ + struct berval canon; /* Use attr in user entry for canonical name */ +} ldapctx; + +static ldapctx ldapdb_ctx; + +static int ldapdb_interact(LDAP *ld, unsigned flags __attribute__((unused)), + void *def, void *inter) +{ + sasl_interact_t *in = inter; + ldapctx *ctx = def; + struct berval p; + + for (;in->id != SASL_CB_LIST_END;in++) + { + p.bv_val = NULL; + switch(in->id) + { + case SASL_CB_GETREALM: + ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &p.bv_val); + if (p.bv_val) p.bv_len = strlen(p.bv_val); + break; + case SASL_CB_AUTHNAME: + p = ctx->id; + break; + case SASL_CB_PASS: + p = ctx->pw; + break; + } + if (p.bv_val) + { + in->result = p.bv_val; + in->len = p.bv_len; + } + } + return LDAP_SUCCESS; +} + +typedef struct connparm { + LDAP *ld; + LDAPControl c; + LDAPControl *ctrl[2]; + struct berval *dn; +} connparm; + +static int ldapdb_connect(ldapctx *ctx, sasl_server_params_t *sparams, + const char *user, unsigned ulen, connparm *cp) +{ + int i; + char *authzid; + + if((i=ldap_initialize(&cp->ld, ctx->uri))) { + return i; + } + + authzid = sparams->utils->malloc(ulen + sizeof("u:")); + if (!authzid) { + return LDAP_NO_MEMORY; + } + strcpy(authzid, "u:"); + strcpy(authzid+2, user); + cp->c.ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ; + cp->c.ldctl_value.bv_val = authzid; + cp->c.ldctl_value.bv_len = ulen + 2; + cp->c.ldctl_iscritical = 1; + + i = LDAP_VERSION3; + ldap_set_option(cp->ld, LDAP_OPT_PROTOCOL_VERSION, &i); + + /* If TLS is set and it fails, continue or bail out as requested */ + if (ctx->use_tls && (i=ldap_start_tls_s(cp->ld, NULL, NULL)) != LDAP_SUCCESS + && ctx->use_tls > 1) { + sparams->utils->free(authzid); + return i; + } + + i = ldap_sasl_interactive_bind_s(cp->ld, NULL, ctx->mech.bv_val, NULL, + NULL, LDAP_SASL_QUIET, ldapdb_interact, ctx); + if (i != LDAP_SUCCESS) { + sparams->utils->free(authzid); + return i; + } + + cp->ctrl[0] = &cp->c; + cp->ctrl[1] = NULL; + i = ldap_whoami_s(cp->ld, &cp->dn, cp->ctrl, NULL); + if (i == LDAP_SUCCESS && cp->dn) { + if (!cp->dn->bv_val || strncmp(cp->dn->bv_val, "dn:", 3)) { + ber_bvfree(cp->dn); + cp->dn = NULL; + i = LDAP_INVALID_SYNTAX; + } else { + cp->c.ldctl_value = *(cp->dn); + } + } + sparams->utils->free(authzid); + return i; +} + +static int ldapdb_auxprop_lookup(void *glob_context, + sasl_server_params_t *sparams, + unsigned flags, + const char *user, + unsigned ulen) +{ + ldapctx *ctx = glob_context; + connparm cp; + int ret, i, n, *aindx; + int result; + int j; + const struct propval *pr; + struct berval **bvals; + LDAPMessage *msg, *res; + char **attrs = NULL; + + if(!ctx || !sparams || !user) return SASL_BADPARAM; + + pr = sparams->utils->prop_get(sparams->propctx); + if (!pr) return SASL_FAIL; + + /* count how many attrs to fetch */ + for(i = 0, n = 0; pr[i].name; i++) { + if(pr[i].name[0] == '*' && (flags & SASL_AUXPROP_AUTHZID)) + continue; + if(pr[i].values && !(flags & SASL_AUXPROP_OVERRIDE)) + continue; + n++; + } + + /* nothing to do, bail out */ + if (!n) return SASL_OK; + + /* alloc an array of attr names for search, and index to the props */ + attrs = sparams->utils->malloc((n+1)*sizeof(char *)*2); + if (!attrs) { + result = SASL_NOMEM; + goto done; + } + + aindx = (int *)(attrs + n + 1); + + /* copy attr list */ + for (i=0, n=0; pr[i].name; i++) { + if(pr[i].name[0] == '*' && (flags & SASL_AUXPROP_AUTHZID)) + continue; + if(pr[i].values && !(flags & SASL_AUXPROP_OVERRIDE)) + continue; + attrs[n] = (char *)pr[i].name; + if (pr[i].name[0] == '*') attrs[n]++; + aindx[n] = i; + n++; + } + attrs[n] = NULL; + + if ((ret = ldapdb_connect(ctx, sparams, user, ulen, &cp)) != LDAP_SUCCESS) { + goto process_ldap_error; + } + + ret = ldap_search_ext_s(cp.ld, cp.dn->bv_val+3, LDAP_SCOPE_BASE, + "(objectclass=*)", attrs, 0, cp.ctrl, NULL, NULL, 1, &res); + ber_bvfree(cp.dn); + + if (ret != LDAP_SUCCESS) { + goto process_ldap_error; + } + + /* Assume no user by default */ + ret = LDAP_NO_SUCH_OBJECT; + + for (msg = ldap_first_message(cp.ld, res); + msg; + msg = ldap_next_message(cp.ld, msg)) { + if (ldap_msgtype(msg) != LDAP_RES_SEARCH_ENTRY) continue; + + /* Presence of a search result response indicates that the user exists */ + ret = LDAP_SUCCESS; + + for (i = 0; i < n; i++) { + bvals = ldap_get_values_len(cp.ld, msg, attrs[i]); + if (!bvals) continue; + + if (pr[aindx[i]].values) { + sparams->utils->prop_erase(sparams->propctx, pr[aindx[i]].name); + } + + for ( j = 0; bvals[j] != NULL; j++ ) { + sparams->utils->prop_set(sparams->propctx, + pr[aindx[i]].name, + bvals[j]->bv_val, + bvals[j]->bv_len); + } + ber_bvecfree(bvals); + } + } + ldap_msgfree(res); + + process_ldap_error: + switch (ret) { + case LDAP_SUCCESS: + result = SASL_OK; + break; + + case LDAP_NO_SUCH_OBJECT: + result = SASL_NOUSER; + break; + + case LDAP_NO_MEMORY: + result = SASL_NOMEM; + break; + + case LDAP_SERVER_DOWN: + case LDAP_BUSY: + case LDAP_UNAVAILABLE: + case LDAP_CONNECT_ERROR: + result = SASL_UNAVAIL; + break; + +#if defined(LDAP_PROXY_AUTHZ_FAILURE) + case LDAP_PROXY_AUTHZ_FAILURE: +#endif + case LDAP_INAPPROPRIATE_AUTH: + case LDAP_INVALID_CREDENTIALS: + case LDAP_INSUFFICIENT_ACCESS: + result = SASL_BADAUTH; + break; + + default: + result = SASL_FAIL; + break; + } + + done: + if(attrs) sparams->utils->free(attrs); + if(cp.ld) ldap_unbind_ext(cp.ld, NULL, NULL); + + return result; +} + +static int ldapdb_auxprop_store(void *glob_context, + sasl_server_params_t *sparams, + struct propctx *prctx, + const char *user, + unsigned ulen) +{ + ldapctx *ctx = glob_context; + connparm cp; + const struct propval *pr; + int i, n; + LDAPMod **mods; + + /* just checking if we are enabled */ + if (!prctx) return SASL_OK; + + if (!sparams || !user) return SASL_BADPARAM; + + pr = sparams->utils->prop_get(prctx); + if (!pr) return SASL_BADPARAM; + + for (n=0; pr[n].name; n++); + if (!n) return SASL_BADPARAM; + + mods = sparams->utils->malloc((n+1) * sizeof(LDAPMod*) + n * sizeof(LDAPMod)); + if (!mods) return SASL_NOMEM; + + if((i=ldapdb_connect(ctx, sparams, user, ulen, &cp)) == 0) { + + for (i=0; imod_op = LDAP_MOD_REPLACE; + mods[i]->mod_type = (char *)pr[i].name; + mods[i]->mod_values = (char **)pr[i].values; + } + mods[i] = NULL; + + i = ldap_modify_ext_s(cp.ld, cp.dn->bv_val+3, mods, cp.ctrl, NULL); + ber_bvfree(cp.dn); + } + + sparams->utils->free(mods); + + if (i) { + sparams->utils->seterror(sparams->utils->conn, 0, + ldap_err2string(i)); + if (i == LDAP_NO_MEMORY) i = SASL_NOMEM; + else i = SASL_FAIL; + } + if(cp.ld) ldap_unbind_ext(cp.ld, NULL, NULL); + return i; +} + +static int +ldapdb_canon_server(void *glob_context, + sasl_server_params_t *sparams, + const char *user, + unsigned ulen, + unsigned flags, + char *out, + unsigned out_max, + unsigned *out_ulen) +{ + ldapctx *ctx = glob_context; + connparm cp; + struct berval **bvals; + LDAPMessage *msg, *res; + char *rdn, *attrs[2]; + unsigned len; + int ret; + + if(!ctx || !sparams || !user) return SASL_BADPARAM; + + /* If no canon attribute was configured, we can't do anything */ + if(!ctx->canon.bv_val) return SASL_BADPARAM; + + /* Trim whitespace */ + while(isspace(*(unsigned char *)user)) { + user++; + ulen--; + } + while(isspace((unsigned char)user[ulen-1])) { + ulen--; + } + + if (!ulen) { + sparams->utils->seterror(sparams->utils->conn, 0, + "All-whitespace username."); + return SASL_FAIL; + } + + ret = ldapdb_connect(ctx, sparams, user, ulen, &cp); + if ( ret ) goto done; + + /* See if the RDN uses the canon attr. If so, just use the RDN + * value, we don't need to do a search. + */ + rdn = cp.dn->bv_val+3; + if (!strncasecmp(ctx->canon.bv_val, rdn, ctx->canon.bv_len) && + rdn[ctx->canon.bv_len] == '=') { + char *comma; + rdn += ctx->canon.bv_len + 1; + comma = strchr(rdn, ','); + if ( comma ) + len = comma - rdn; + else + len = cp.dn->bv_len - (rdn - cp.dn->bv_val); + if ( len > out_max ) + len = out_max; + memcpy(out, rdn, len); + out[len] = '\0'; + *out_ulen = len; + ret = SASL_OK; + ber_bvfree(cp.dn); + goto done; + } + + /* Have to read the user's entry */ + attrs[0] = ctx->canon.bv_val; + attrs[1] = NULL; + ret = ldap_search_ext_s(cp.ld, cp.dn->bv_val+3, LDAP_SCOPE_BASE, + "(objectclass=*)", attrs, 0, cp.ctrl, NULL, NULL, 1, &res); + ber_bvfree(cp.dn); + + if (ret != LDAP_SUCCESS) goto done; + + for(msg=ldap_first_message(cp.ld, res); msg; msg=ldap_next_message(cp.ld, msg)) + { + if (ldap_msgtype(msg) != LDAP_RES_SEARCH_ENTRY) continue; + bvals = ldap_get_values_len(cp.ld, msg, attrs[0]); + if (!bvals) continue; + len = bvals[0]->bv_len; + if ( len > out_max ) + len = out_max; + memcpy(out, bvals[0]->bv_val, len); + *out_ulen = len; + ber_bvecfree(bvals); + } + ldap_msgfree(res); + + done: + if(cp.ld) ldap_unbind_ext(cp.ld, NULL, NULL); + if (ret) { + sparams->utils->seterror(sparams->utils->conn, 0, + ldap_err2string(ret)); + if (ret == LDAP_NO_MEMORY) ret = SASL_NOMEM; + else ret = SASL_FAIL; + } + return ret; +} + +static int +ldapdb_canon_client(void *glob_context, + sasl_client_params_t *cparams, + const char *user, + unsigned ulen, + unsigned flags, + char *out, + unsigned out_max, + unsigned *out_ulen) +{ + if(!cparams || !user) return SASL_BADPARAM; + + /* Trim whitespace */ + while(isspace(*(unsigned char *)user)) { + user++; + ulen--; + } + while(isspace((unsigned char)user[ulen-1])) { + ulen--; + } + + if (!ulen) { + cparams->utils->seterror(cparams->utils->conn, 0, + "All-whitespace username."); + return SASL_FAIL; + } + + if (ulen > out_max) return SASL_BUFOVER; + + memcpy(out, user, ulen); + out[ulen] = '\0'; + *out_ulen = ulen; + return SASL_OK; +} + +static int +ldapdb_config(const sasl_utils_t *utils) +{ + ldapctx *p = &ldapdb_ctx; + const char *s; + unsigned len; + + if(p->inited) return SASL_OK; + + utils->getopt(utils->getopt_context, ldapdb, "ldapdb_uri", &p->uri, NULL); + if(!p->uri) return SASL_BADPARAM; + + utils->getopt(utils->getopt_context, ldapdb, "ldapdb_id", + (const char **)&p->id.bv_val, &len); + p->id.bv_len = len; + utils->getopt(utils->getopt_context, ldapdb, "ldapdb_pw", + (const char **)&p->pw.bv_val, &len); + p->pw.bv_len = len; + utils->getopt(utils->getopt_context, ldapdb, "ldapdb_mech", + (const char **)&p->mech.bv_val, &len); + p->mech.bv_len = len; + utils->getopt(utils->getopt_context, ldapdb, "ldapdb_starttls", &s, NULL); + if (s) + { + if (!strcasecmp(s, "demand")) p->use_tls = 2; + else if (!strcasecmp(s, "try")) p->use_tls = 1; + } + utils->getopt(utils->getopt_context, ldapdb, "ldapdb_rc", &s, &len); + if (s) + { + char *str = utils->malloc(sizeof("LDAPRC=")+len); + if (!str) return SASL_NOMEM; + strcpy( str, "LDAPRC=" ); + strcpy( str + sizeof("LDAPRC=")-1, s ); + if (putenv(str)) + { + utils->free(str); + return SASL_NOMEM; + } + } + utils->getopt(utils->getopt_context, ldapdb, "ldapdb_canon_attr", + (const char **)&p->canon.bv_val, &len); + p->canon.bv_len = len; + p->inited = 1; + + return SASL_OK; +} + +static sasl_auxprop_plug_t ldapdb_auxprop_plugin = { + 0, /* Features */ + 0, /* spare */ + &ldapdb_ctx, /* glob_context */ + NULL, /* auxprop_free */ + ldapdb_auxprop_lookup, /* auxprop_lookup */ + ldapdb, /* name */ + ldapdb_auxprop_store /* auxprop store */ +}; + +int ldapdb_auxprop_plug_init(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_auxprop_plug_t **plug, + const char *plugname __attribute__((unused))) +{ + int rc; + + if(!out_version || !plug) return SASL_BADPARAM; + + if(max_version < SASL_AUXPROP_PLUG_VERSION) return SASL_BADVERS; + + rc = ldapdb_config(utils); + + *out_version = SASL_AUXPROP_PLUG_VERSION; + + *plug = &ldapdb_auxprop_plugin; + + return rc; +} + +static sasl_canonuser_plug_t ldapdb_canonuser_plugin = { + 0, /* features */ + 0, /* spare */ + &ldapdb_ctx, /* glob_context */ + ldapdb, /* name */ + NULL, /* canon_user_free */ + ldapdb_canon_server, /* canon_user_server */ + ldapdb_canon_client, /* canon_user_client */ + NULL, + NULL, + NULL +}; + +int ldapdb_canonuser_plug_init(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_canonuser_plug_t **plug, + const char *plugname __attribute__((unused))) +{ + int rc; + + if(!out_version || !plug) return SASL_BADPARAM; + + if(max_version < SASL_CANONUSER_PLUG_VERSION) return SASL_BADVERS; + + rc = ldapdb_config(utils); + + *out_version = SASL_CANONUSER_PLUG_VERSION; + + *plug = &ldapdb_canonuser_plugin; + + return rc; +} diff --git a/libs/cyrussasl/plugins/ldapdb_init.c b/libs/cyrussasl/plugins/ldapdb_init.c new file mode 100644 index 00000000..8840bc2a --- /dev/null +++ b/libs/cyrussasl/plugins/ldapdb_init.c @@ -0,0 +1,39 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_AUXPROP_PLUG_INIT( ldapdb ) + +SASL_CANONUSER_PLUG_INIT( ldapdb ) diff --git a/libs/cyrussasl/plugins/login.c b/libs/cyrussasl/plugins/login.c new file mode 100644 index 00000000..f2a05ac5 --- /dev/null +++ b/libs/cyrussasl/plugins/login.c @@ -0,0 +1,496 @@ +/* Login SASL plugin + * Rob Siemborski (SASLv2 Conversion) + * contributed by Rainer Schoepf + * based on PLAIN, by Tim Martin + * $Id: login.c,v 1.31 2010/11/30 11:41:47 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "plugin_common.h" + +/***************************** Common Section *****************************/ + +static const char plugin_id[] = "$Id: login.c,v 1.31 2010/11/30 11:41:47 mel Exp $"; + +/***************************** Server Section *****************************/ + +typedef struct context { + int state; + + char *username; + unsigned username_len; +} server_context_t; + +static int login_server_mech_new(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + void **conn_context) +{ + server_context_t *text; + + /* holds state are in */ + text = sparams->utils->malloc(sizeof(server_context_t)); + if (text == NULL) { + MEMERROR( sparams->utils ); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(server_context_t)); + + text->state = 1; + + *conn_context = text; + + return SASL_OK; +} + +#define USERNAME_CHALLENGE "Username:" +#define PASSWORD_CHALLENGE "Password:" + +static int login_server_mech_step(void *conn_context, + sasl_server_params_t *params, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + server_context_t *text = (server_context_t *) conn_context; + + *serverout = NULL; + *serveroutlen = 0; + + if (text == NULL) { + return SASL_BADPROT; + } + + switch (text->state) { + + case 1: + text->state = 2; + + /* Check inlen, (possibly we have already the user name) */ + /* In this case fall through to state 2 */ + if (clientinlen == 0) { + /* demand username */ + + *serveroutlen = (unsigned) strlen(USERNAME_CHALLENGE); + *serverout = USERNAME_CHALLENGE; + + return SASL_CONTINUE; + } + + + case 2: + /* Catch really long usernames */ + if (clientinlen > 1024) { + SETERROR(params->utils, "username too long (>1024 characters)"); + return SASL_BADPROT; + } + + /* get username */ + text->username = + params->utils->malloc(sizeof(sasl_secret_t) + clientinlen + 1); + if (!text->username) { + MEMERROR( params->utils ); + return SASL_NOMEM; + } + + strncpy(text->username, clientin, clientinlen); + text->username_len = clientinlen; + text->username[clientinlen] = '\0'; + + /* demand password */ + *serveroutlen = (unsigned) strlen(PASSWORD_CHALLENGE); + *serverout = PASSWORD_CHALLENGE; + + text->state = 3; + + return SASL_CONTINUE; + + + case 3: { + sasl_secret_t *password; + int result; + + /* Catch really long passwords */ + if (clientinlen > 1024) { + SETERROR(params->utils, + "clientinlen is > 1024 characters in LOGIN plugin"); + return SASL_BADPROT; + } + + /* get password */ + password = + params->utils->malloc(sizeof(sasl_secret_t) + clientinlen + 1); + if (!password) { + MEMERROR(params->utils); + return SASL_NOMEM; + } + + strncpy((char *) password->data, clientin, clientinlen); + password->data[clientinlen] = '\0'; + password->len = clientinlen; + + /* canonicalize username first, so that password verification is + * done against the canonical id */ + result = params->canon_user(params->utils->conn, + text->username, + text->username_len, + SASL_CU_AUTHID | SASL_CU_AUTHZID | SASL_CU_EXTERNALLY_VERIFIED, + oparams); + if (result != SASL_OK) return result; + + /* verify_password - return sasl_ok on success */ + result = params->utils->checkpass(params->utils->conn, + oparams->authid, oparams->alen, + (char *) password->data, password->len); + + if (result != SASL_OK) { + _plug_free_secret(params->utils, &password); + return result; + } + + _plug_free_secret(params->utils, &password); + + *serverout = NULL; + *serveroutlen = 0; + + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + return SASL_OK; + } + + + default: + params->utils->log(NULL, SASL_LOG_ERR, + "Invalid LOGIN server step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static void login_server_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + server_context_t *text = (server_context_t *) conn_context; + + if (!text) return; + + if (text->username) utils->free(text->username); + + utils->free(text); +} + +static sasl_server_plug_t login_server_plugins[] = +{ + { + "LOGIN", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOANONYMOUS + | SASL_SEC_PASS_CREDENTIALS, /* security_flags */ + 0, /* features */ + NULL, /* glob_context */ + &login_server_mech_new, /* mech_new */ + &login_server_mech_step, /* mech_step */ + &login_server_mech_dispose, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* setpass */ + NULL, /* user_query */ + NULL, /* idle */ + NULL, /* mech_avail */ + NULL /* spare */ + } +}; + +int login_server_plug_init(sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_SERVER_PLUG_VERSION) { + SETERROR(utils, "LOGIN version mismatch"); + return SASL_BADVERS; + } + + *out_version = SASL_SERVER_PLUG_VERSION; + *pluglist = login_server_plugins; + *plugcount = 1; + + return SASL_OK; +} + +/***************************** Client Section *****************************/ + +typedef struct client_context { + int state; + + sasl_secret_t *password; + unsigned int free_password; /* set if we need to free password */ +} client_context_t; + +static int login_client_mech_new(void *glob_context __attribute__((unused)), + sasl_client_params_t *params, + void **conn_context) +{ + client_context_t *text; + + /* holds state are in */ + text = params->utils->malloc(sizeof(client_context_t)); + if (text == NULL) { + MEMERROR(params->utils); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(client_context_t)); + + text->state = 1; + + *conn_context = text; + + return SASL_OK; +} + +static int login_client_mech_step(void *conn_context, + sasl_client_params_t *params, + const char *serverin __attribute__((unused)), + unsigned serverinlen __attribute__((unused)), + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + client_context_t *text = (client_context_t *) conn_context; + + *clientout = NULL; + *clientoutlen = 0; + + switch (text->state) { + + case 1: { + const char *user = NULL; + int auth_result = SASL_OK; + int pass_result = SASL_OK; + int result; + + /* check if sec layer strong enough */ + if (params->props.min_ssf > params->external_ssf) { + SETERROR( params->utils, "SSF requested of LOGIN plugin"); + return SASL_TOOWEAK; + } + + /* try to get the userid */ + /* Note: we want to grab the authname and not the userid, which is + * who we AUTHORIZE as, and will be the same as the authname + * for the LOGIN mech. + */ + if (oparams->user == NULL) { + auth_result = _plug_get_authid(params->utils, &user, prompt_need); + + if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT)) + return auth_result; + } + + /* try to get the password */ + if (text->password == NULL) { + pass_result = _plug_get_password(params->utils, &text->password, + &text->free_password, prompt_need); + + if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT)) + return pass_result; + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + params->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if ((auth_result == SASL_INTERACT) || (pass_result == SASL_INTERACT)) { + /* make the prompt list */ + result = + _plug_make_prompts(params->utils, prompt_need, + NULL, NULL, + auth_result == SASL_INTERACT ? + "Please enter your authentication name" : NULL, + NULL, + pass_result == SASL_INTERACT ? + "Please enter your password" : NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); + if (result != SASL_OK) return result; + + return SASL_INTERACT; + } + + if (!text->password) { + PARAMERROR(params->utils); + return SASL_BADPARAM; + } + + result = params->canon_user(params->utils->conn, user, 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) return result; + + /* server should have sent request for username - we ignore it */ + if (!serverin) { + SETERROR( params->utils, + "Server didn't issue challenge for USERNAME"); + return SASL_BADPROT; + } + + if (!clientout) { + PARAMERROR( params->utils ); + return SASL_BADPARAM; + } + + if (clientoutlen) *clientoutlen = oparams->alen; + *clientout = oparams->authid; + + text->state = 2; + + return SASL_CONTINUE; + } + + case 2: + /* server should have sent request for password - we ignore it */ + if (!serverin) { + SETERROR( params->utils, + "Server didn't issue challenge for PASSWORD"); + return SASL_BADPROT; + } + + if (!clientout) { + PARAMERROR(params->utils); + return SASL_BADPARAM; + } + + if (clientoutlen) *clientoutlen = text->password->len; + *clientout = (char *) text->password->data; + + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + return SASL_OK; + + default: + params->utils->log(NULL, SASL_LOG_ERR, + "Invalid LOGIN client step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static void login_client_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + client_context_t *text = (client_context_t *) conn_context; + + if (!text) return; + + /* free sensitive info */ + if (text->free_password) _plug_free_secret(utils, &(text->password)); + + utils->free(text); +} + +static sasl_client_plug_t login_client_plugins[] = +{ + { + "LOGIN", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOANONYMOUS + | SASL_SEC_PASS_CREDENTIALS, /* security_flags */ + SASL_FEAT_SERVER_FIRST, /* features */ + NULL, /* required_prompts */ + NULL, /* glob_context */ + &login_client_mech_new, /* mech_new */ + &login_client_mech_step, /* mech_step */ + &login_client_mech_dispose, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* idle */ + NULL, /* spare */ + NULL /* spare */ + } +}; + +int login_client_plug_init(sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_CLIENT_PLUG_VERSION) { + SETERROR(utils, "Version mismatch in LOGIN"); + return SASL_BADVERS; + } + + *out_version = SASL_CLIENT_PLUG_VERSION; + *pluglist = login_client_plugins; + *plugcount = 1; + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/login_init.c b/libs/cyrussasl/plugins/login_init.c new file mode 100644 index 00000000..cad75752 --- /dev/null +++ b/libs/cyrussasl/plugins/login_init.c @@ -0,0 +1,43 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_CLIENT_PLUG_INIT( login ) +SASL_SERVER_PLUG_INIT( login ) + diff --git a/libs/cyrussasl/plugins/ntlm.c b/libs/cyrussasl/plugins/ntlm.c new file mode 100644 index 00000000..79ea47ca --- /dev/null +++ b/libs/cyrussasl/plugins/ntlm.c @@ -0,0 +1,2175 @@ +/* NTLM SASL plugin + * Ken Murchison + * $Id: ntlm.c,v 1.37 2011/11/08 17:31:55 murch Exp $ + * + * References: + * http://www.innovation.ch/java/ntlm.html + * http://www.opengroup.org/comsource/techref2/NCH1222X.HTM + * http://www.ubiqx.org/cifs/rfc-draft/draft-leach-cifs-v1-spec-02.html + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +# include /* for getpid */ + typedef int pid_t; +#else +# include +# include +# include +# include +# include + +#ifndef SYS_NMLN + struct utsname dummy; +# define SYS_NMLN sizeof(dummy.sysname) +#endif + +# define closesocket(sock) close(sock) + typedef int SOCKET; +#endif /* WIN32 */ + +#include +#include +#include +#include +#include +#if (OPENSSL_VERSION_NUMBER >= 0x0090700f) && \ + !defined(OPENSSL_ENABLE_OLD_DES_SUPPORT) +# define des_cblock DES_cblock +# define des_key_schedule DES_key_schedule +# define des_set_odd_parity(k) \ + DES_set_odd_parity((k)) +# define des_set_key(k,ks) \ + DES_set_key((k),&(ks)) +# define des_key_sched(k,ks) \ + DES_key_sched((k),&(ks)) +# define des_ecb_encrypt(i,o,k,e) \ + DES_ecb_encrypt((i),(o),&(k),(e)) +#endif /* OpenSSL 0.9.7+ w/o old DES support */ + +#include +#define MD5_H /* suppress internal MD5 */ +#include + +#include "plugin_common.h" + +/***************************** Common Section *****************************/ + +static const char plugin_id[] = "$Id: ntlm.c,v 1.37 2011/11/08 17:31:55 murch Exp $"; + +#ifdef WIN32 +static ssize_t writev (SOCKET fd, const struct iovec *iov, size_t iovcnt); + +ssize_t writev (SOCKET fd, const struct iovec *iov, size_t iovcnt) +{ + ssize_t nwritten; /* amount written */ + ssize_t nbytes; + size_t i; + + nbytes = 0; + + for (i = 0; i < iovcnt; i++) { + if ((nwritten = send (fd, iov[i].iov_base, iov[i].iov_len, 0)) == SOCKET_ERROR) { +/* Unless socket is nonblocking, we should always write everything */ + return (-1); + } + + nbytes += nwritten; + + if (nwritten < iov[i].iov_len) { + break; + } + } + return (nbytes); +} +#endif /* WIN32 */ + +#ifndef UINT16_MAX +#define UINT16_MAX 65535U +#endif + +#if UINT_MAX == UINT16_MAX +typedef unsigned int uint16; +#elif USHRT_MAX == UINT16_MAX +typedef unsigned short uint16; +#else +#error dont know what to use for uint16 +#endif + +#ifndef UINT32_MAX +#define UINT32_MAX 4294967295U +#endif + +#if UINT_MAX == UINT32_MAX +typedef unsigned int uint32; +#elif ULONG_MAX == UINT32_MAX +typedef unsigned long uint32; +#elif USHRT_MAX == UINT32_MAX +typedef unsigned short uint32; +#else +#error dont know what to use for uint32 +#endif + +#define NTLM_SIGNATURE "NTLMSSP" + +enum { + NTLM_TYPE_REQUEST = 1, + NTLM_TYPE_CHALLENGE = 2, + NTLM_TYPE_RESPONSE = 3 +}; + +enum { + NTLM_USE_UNICODE = 0x00001, + NTLM_USE_ASCII = 0x00002, + NTLM_ASK_TARGET = 0x00004, + NTLM_AUTH_NTLM = 0x00200, + NTLM_ALWAYS_SIGN = 0x08000, + NTLM_TARGET_IS_DOMAIN = 0x10000, + NTLM_TARGET_IS_SERVER = 0x20000, + NTLM_FLAGS_MASK = 0x0ffff +}; + +enum { + NTLM_NONCE_LENGTH = 8, + NTLM_HASH_LENGTH = 21, + NTLM_RESP_LENGTH = 24, + NTLM_SESSKEY_LENGTH = 16, +}; + +enum { + NTLM_SIG_OFFSET = 0, + NTLM_TYPE_OFFSET = 8, + + NTLM_TYPE1_FLAGS_OFFSET = 12, + NTLM_TYPE1_DOMAIN_OFFSET = 16, + NTLM_TYPE1_WORKSTN_OFFSET = 24, + NTLM_TYPE1_DATA_OFFSET = 32, + NTLM_TYPE1_MINSIZE = 16, + + NTLM_TYPE2_TARGET_OFFSET = 12, + NTLM_TYPE2_FLAGS_OFFSET = 20, + NTLM_TYPE2_CHALLENGE_OFFSET = 24, + NTLM_TYPE2_CONTEXT_OFFSET = 32, + NTLM_TYPE2_TARGETINFO_OFFSET= 40, + NTLM_TYPE2_DATA_OFFSET = 48, + NTLM_TYPE2_MINSIZE = 32, + + NTLM_TYPE3_LMRESP_OFFSET = 12, + NTLM_TYPE3_NTRESP_OFFSET = 20, + NTLM_TYPE3_DOMAIN_OFFSET = 28, + NTLM_TYPE3_USER_OFFSET = 36, + NTLM_TYPE3_WORKSTN_OFFSET = 44, + NTLM_TYPE3_SESSIONKEY_OFFSET= 52, + NTLM_TYPE3_FLAGS_OFFSET = 60, + NTLM_TYPE3_DATA_OFFSET = 64, + NTLM_TYPE3_MINSIZE = 52, + + NTLM_BUFFER_LEN_OFFSET = 0, + NTLM_BUFFER_MAXLEN_OFFSET = 2, + NTLM_BUFFER_OFFSET_OFFSET = 4, + NTLM_BUFFER_SIZE = 8 +}; + +/* return the length of a string (even if it is NULL) */ +#define xstrlen(s) (s ? strlen(s) : 0) + +/* machine-independent routines to convert to/from Intel byte-order */ +#define htois(is, hs) \ + (is)[0] = hs & 0xff; \ + (is)[1] = hs >> 8 + +#define itohs(is) \ + ((is)[0] | ((is)[1] << 8)) + +#define htoil(il, hl) \ + (il)[0] = hl & 0xff; \ + (il)[1] = (hl >> 8) & 0xff; \ + (il)[2] = (hl >> 16) & 0xff; \ + (il)[3] = hl >> 24 + +#define itohl(il) \ + ((il)[0] | ((il)[1] << 8) | ((il)[2] << 16) | ((il)[3] << 24)) + +/* convert string to all upper case */ +static const char *ucase(const char *str, size_t len) +{ + char *cp = (char *) str; + + if (!len) len = xstrlen(str); + + while (len && cp && *cp) { + *cp = toupper((int) *cp); + cp++; + len--; + } + + return (str); +} + +/* copy src to dst as unicode (in Intel byte-order) */ +static void to_unicode(u_char *dst, const char *src, int len) +{ + for (; len; len--) { + *dst++ = *src++; + *dst++ = 0; + } +} + +/* copy unicode src (in Intel byte-order) to dst */ +static void from_unicode(char *dst, u_char *src, int len) +{ + for (; len; len--) { + *dst++ = *src & 0x7f; + src += 2; + } +} + +/* load a string into an NTLM buffer */ +static void load_buffer(u_char *buf, const u_char *str, uint16 len, + int unicode, u_char *base, uint32 *offset) +{ + if (len) { + if (unicode) { + to_unicode(base + *offset, str, len); + len *= 2; + } + else { + memcpy(base + *offset, str, len); + } + } + + htois(buf + NTLM_BUFFER_LEN_OFFSET, len); + htois(buf + NTLM_BUFFER_MAXLEN_OFFSET, len); + htoil(buf + NTLM_BUFFER_OFFSET_OFFSET, *offset); + *offset += len; +} + +/* unload a string from an NTLM buffer */ +static int unload_buffer(const sasl_utils_t *utils, const u_char *buf, + u_char **str, unsigned *outlen, + int unicode, const u_char *base, unsigned msglen) +{ + uint16 len = itohs(buf + NTLM_BUFFER_LEN_OFFSET); + + if (len) { + uint32 offset; + + *str = utils->malloc(len + 1); /* add 1 for NUL */ + if (*str == NULL) { + MEMERROR(utils); + return SASL_NOMEM; + } + + offset = itohl(buf + NTLM_BUFFER_OFFSET_OFFSET); + + /* sanity check */ + if (offset > msglen || len > (msglen - offset)) return SASL_BADPROT; + + if (unicode) { + len /= 2; + from_unicode((char *) *str, (u_char *) base + offset, len); + } + else + memcpy(*str, base + offset, len); + + (*str)[len] = '\0'; /* add NUL */ + } + else { + *str = NULL; + } + + if (outlen) *outlen = len; + + return SASL_OK; +} + +/* + * NTLM encryption/authentication routines per section 2.10 of + * draft-leach-cifs-v1-spec-02 + */ +static void E(unsigned char *out, unsigned char *K, unsigned Klen, + unsigned char *D, unsigned Dlen) + +{ + unsigned k, d; + des_cblock K64; + des_key_schedule ks; + unsigned char *Dp; +#define KEY_SIZE 7 +#define BLOCK_SIZE 8 + + for (k = 0; k < Klen; k += KEY_SIZE, K += KEY_SIZE) { + /* convert 56-bit key to 64-bit */ + K64[0] = K[0]; + K64[1] = ((K[0] << 7) & 0xFF) | (K[1] >> 1); + K64[2] = ((K[1] << 6) & 0xFF) | (K[2] >> 2); + K64[3] = ((K[2] << 5) & 0xFF) | (K[3] >> 3); + K64[4] = ((K[3] << 4) & 0xFF) | (K[4] >> 4); + K64[5] = ((K[4] << 3) & 0xFF) | (K[5] >> 5); + K64[6] = ((K[5] << 2) & 0xFF) | (K[6] >> 6); + K64[7] = (K[6] << 1) & 0xFF; + + des_set_odd_parity(&K64); /* XXX is this necessary? */ + des_set_key(&K64, ks); + + for (d = 0, Dp = D; d < Dlen; + d += BLOCK_SIZE, Dp += BLOCK_SIZE, out += BLOCK_SIZE) { + des_ecb_encrypt((void *) Dp, (void *) out, ks, DES_ENCRYPT); + } + } +} + +static unsigned char *P16_lm(unsigned char *P16, sasl_secret_t *passwd, + const sasl_utils_t *utils __attribute__((unused)), + char **buf __attribute__((unused)), + unsigned *buflen __attribute__((unused)), + int *result) +{ + char P14[14]; + unsigned char S8[] = { 0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 }; + + strncpy(P14, passwd->data, sizeof(P14)); + ucase(P14, sizeof(P14)); + + E(P16, P14, sizeof(P14), S8, sizeof(S8)); + *result = SASL_OK; + return P16; +} + +static unsigned char *P16_nt(unsigned char *P16, sasl_secret_t *passwd, + const sasl_utils_t *utils, + char **buf, unsigned *buflen, int *result) +{ + if (_plug_buf_alloc(utils, buf, buflen, 2 * passwd->len) != SASL_OK) { + SETERROR(utils, "cannot allocate P16_nt unicode buffer"); + *result = SASL_NOMEM; + } + else { + to_unicode(*buf, passwd->data, passwd->len); + MD4(*buf, 2 * passwd->len, P16); + *result = SASL_OK; + } + return P16; +} + +static unsigned char *P21(unsigned char *P21, sasl_secret_t *passwd, + unsigned char * (*P16)(unsigned char *, + sasl_secret_t *, + const sasl_utils_t *, + char **, unsigned *, int *), + const sasl_utils_t *utils, + char **buf, unsigned *buflen, int *result) +{ + memset(P16(P21, passwd, utils, buf, buflen, result) + 16, 0, 5); + return P21; +} + +static unsigned char *P24(unsigned char *P24, unsigned char *P21, + unsigned char *C8) + +{ + E(P24, P21, NTLM_HASH_LENGTH, C8, NTLM_NONCE_LENGTH); + return P24; +} + +static unsigned char *V2(unsigned char *V2, sasl_secret_t *passwd, + const char *authid, const char *target, + const unsigned char *challenge, + const unsigned char *blob, unsigned bloblen, + const sasl_utils_t *utils, + char **buf, unsigned *buflen, int *result) +{ + HMAC_CTX ctx; + unsigned char hash[EVP_MAX_MD_SIZE]; + char *upper; + unsigned int len; + + /* Allocate enough space for the unicode target */ + len = (unsigned int) (strlen(authid) + xstrlen(target)); + if (_plug_buf_alloc(utils, buf, buflen, 2 * len + 1) != SASL_OK) { + SETERROR(utils, "cannot allocate NTLMv2 hash"); + *result = SASL_NOMEM; + } + else { + /* NTLMv2hash = HMAC-MD5(NTLMhash, unicode(ucase(authid + domain))) */ + P16_nt(hash, passwd, utils, buf, buflen, result); + + /* Use the tail end of the buffer for ucase() conversion */ + upper = *buf + len; + strcpy(upper, authid); + if (target) strcat(upper, target); + ucase(upper, len); + to_unicode(*buf, upper, len); + + HMAC(EVP_md5(), hash, MD4_DIGEST_LENGTH, *buf, 2 * len, hash, &len); + + /* V2 = HMAC-MD5(NTLMv2hash, challenge + blob) + blob */ + HMAC_Init(&ctx, hash, len, EVP_md5()); + HMAC_Update(&ctx, challenge, NTLM_NONCE_LENGTH); + HMAC_Update(&ctx, blob, bloblen); + HMAC_Final(&ctx, V2, &len); + HMAC_cleanup(&ctx); + + /* the blob is concatenated outside of this function */ + + *result = SASL_OK; + } + + return V2; +} + +/***************************** Server Section *****************************/ + +typedef struct server_context { + int state; + + uint32 flags; + unsigned char nonce[NTLM_NONCE_LENGTH]; + + /* per-step mem management */ + char *out_buf; + unsigned out_buf_len; + + /* socket to remote authentication host */ + SOCKET sock; + +} server_context_t; + +#define N(a) (sizeof (a) / sizeof (a[0])) + +#define SMB_HDR_PROTOCOL "\xffSMB" + +typedef struct { + unsigned char protocol[4]; + unsigned char command; + uint32 status; + unsigned char flags; + uint16 flags2; + uint16 PidHigh; + unsigned char extra[10]; + uint16 tid; + uint16 pid; + uint16 uid; + uint16 mid; +} SMB_Header; + +typedef struct { + uint16 dialect_index; + unsigned char security_mode; + uint16 max_mpx_count; + uint16 max_number_vcs; + uint32 max_buffer_size; + uint32 max_raw_size; + uint32 session_key; + uint32 capabilities; + uint32 system_time_low; + uint32 system_time_high; + uint16 server_time_zone; + unsigned char encryption_key_length; +} SMB_NegProt_Resp; + +typedef struct { + unsigned char andx_command; + unsigned char andx_reserved; + uint16 andx_offset; + uint16 max_buffer_size; + uint16 max_mpx_count; + uint16 vc_number; + uint32 session_key; + uint16 case_insensitive_passwd_len; + uint16 case_sensitive_passwd_len; + uint32 reserved; + uint32 capabilities; +} SMB_SessionSetup; + +typedef struct { + unsigned char andx_command; + unsigned char andx_reserved; + uint16 andx_offset; + uint16 action; +} SMB_SessionSetup_Resp; + +enum { + NBT_SESSION_REQUEST = 0x81, + NBT_POSITIVE_SESSION_RESP = 0x82, + NBT_NEGATIVE_SESSION_RESP = 0x83, + NBT_ERR_NO_LISTEN_CALLED = 0x80, + NBT_ERR_NO_LISTEN_CALLING = 0x81, + NBT_ERR_CALLED_NOT_PRESENT = 0x82, + NBT_ERR_INSUFFICIENT_RESRC = 0x83, + NBT_ERR_UNSPECIFIED = 0x8F, + + SMB_HDR_SIZE = 32, + + SMB_COM_NEGOTIATE_PROTOCOL = 0x72, + SMB_COM_SESSION_SETUP_ANDX = 0x73, + SMB_COM_NONE = 0xFF, + + SMB_FLAGS_SERVER_TO_REDIR = 0x80, + + SMB_FLAGS2_ERR_STATUS = 0x4000, + SMB_FLAGS2_UNICODE = 0x8000, + + SMB_NEGPROT_RESP_SIZE = 34, + + SMB_SECURITY_MODE_USER = 0x1, + SMB_SECURITY_MODE_ENCRYPT = 0x2, + SMB_SECURITY_MODE_SIGN = 0x4, + SMB_SECURITY_MODE_SIGN_REQ = 0x8, + + SMB_CAP_UNICODE = 0x0004, + SMB_CAP_STATUS32 = 0x0040, + SMB_CAP_EXTENDED_SECURITY = 0x80000000, + + SMB_SESSION_SETUP_SIZE = 26, + SMB_SESSION_SETUP_RESP_SIZE = 6, + + SMB_REQUEST_MODE_GUEST = 0x1 +}; + +static const char *SMB_DIALECTS[] = { +#if 0 + "\x02PC NETWORK PROGRAM 1.0", + "\x02PCLAN1.0", + "\x02MICROSOFT NETWORKS 1.03", + "\x02MICROSOFT NETWORKS 3.0", + "\x02LANMAN1.0", + "\x02Windows for Workgroups 3.1a", + "\x02LM1.2X002", + "\x02DOS LM1.2X002", + "\x02DOS LANLAM2.1", + "\x02LANMAN2.1", +#endif + "\x02NT LM 0.12" +}; + +static void load_smb_header(unsigned char buf[], SMB_Header *hdr) +{ + unsigned char *p = buf; + + memcpy(p, SMB_HDR_PROTOCOL, 4); p += 4; + *p++ = hdr->command; + htoil(p, hdr->status); p += 4; + *p++ = hdr->flags; + htois(p, hdr->flags2); p += 2; + htois(p, hdr->PidHigh); p += 2; + memcpy(p, hdr->extra, 10); p += 10; + htois(p, hdr->tid); p += 2; + htois(p, hdr->pid); p += 2; + htois(p, hdr->uid); p += 2; + htois(p, hdr->mid); +} + +static void unload_smb_header(unsigned char buf[], SMB_Header *hdr) +{ + unsigned char *p = buf; + + memcpy(hdr->protocol, p, 4); p += 4; + hdr->command = *p++; + hdr->status = itohl(p); p += 4; + hdr->flags = *p++; + hdr->flags2 = itohs(p); p += 2; + hdr->PidHigh = itohs(p); p += 2; + memcpy(hdr->extra, p, 10); p += 10; + hdr->tid = itohs(p); p += 2; + hdr->pid = itohs(p); p += 2; + hdr->uid = itohs(p); p += 2; + hdr->mid = itohs(p); +} + +static void unload_negprot_resp(unsigned char buf[], SMB_NegProt_Resp *resp) +{ + unsigned char *p = buf; + + resp->dialect_index = itohs(p); p += 2; + resp->security_mode = *p++; + resp->max_mpx_count = itohs(p); p += 2; + resp->max_number_vcs = itohs(p); p += 2; + resp->max_buffer_size = itohl(p); p += 4; + resp->max_raw_size = itohl(p); p += 4; + resp->session_key = itohl(p); p += 4; + resp->capabilities = itohl(p); p += 4; + resp->system_time_low = itohl(p); p += 4; + resp->system_time_high = itohl(p); p += 4; + resp->server_time_zone = itohs(p); p += 2; + resp->encryption_key_length = *p; +} + +static void load_session_setup(unsigned char buf[], SMB_SessionSetup *setup) +{ + unsigned char *p = buf; + + *p++ = setup->andx_command; + *p++ = setup->andx_reserved; + htois(p, setup->andx_offset); p += 2; + htois(p, setup->max_buffer_size); p += 2; + htois(p, setup->max_mpx_count); p += 2; + htois(p, setup->vc_number); p += 2; + htoil(p, setup->session_key); p += 4; + htois(p, setup->case_insensitive_passwd_len); p += 2; + htois(p, setup->case_sensitive_passwd_len); p += 2; + htoil(p, setup->reserved); p += 4; + htoil(p, setup->capabilities); p += 4; +} + +static void unload_session_setup_resp(unsigned char buf[], + SMB_SessionSetup_Resp *resp) +{ + unsigned char *p = buf; + + resp->andx_command = *p++; + resp->andx_reserved = *p++; + resp->andx_offset = itohs(p); p += 2; + resp->action = itohs(p); +} + +/* + * Keep calling the writev() system call with 'fd', 'iov', and 'iovcnt' + * until all the data is written out or an error occurs. + */ +static int retry_writev(SOCKET fd, struct iovec *iov, int iovcnt) +{ + int n; + int i; + int written = 0; + static int iov_max = +#ifdef MAXIOV + MAXIOV +#else +#ifdef IOV_MAX + IOV_MAX +#else + 8192 +#endif +#endif + ; + + for (;;) { + while (iovcnt && iov[0].iov_len == 0) { + iov++; + iovcnt--; + } + + if (!iovcnt) return written; + + n = (int) writev(fd, iov, iovcnt > iov_max ? iov_max : iovcnt); + if (n == -1) { +#ifndef WIN32 + if (errno == EINVAL && iov_max > 10) { + iov_max /= 2; + continue; + } + if (errno == EINTR) continue; +#endif + return -1; + } + + written += n; + + for (i = 0; i < iovcnt; i++) { + if ((int) iov[i].iov_len > n) { + iov[i].iov_base = (char *) iov[i].iov_base + n; + iov[i].iov_len -= n; + break; + } + n -= iov[i].iov_len; + iov[i].iov_len = 0; + } + + if (i == iovcnt) return written; + } +} + +/* + * Keep calling the read() system call with 'fd', 'buf', and 'nbyte' + * until all the data is read in or an error occurs. + */ +static int retry_read(SOCKET fd, char *buf0, unsigned nbyte) +{ + int n; + int nread = 0; + char *buf = buf0; + + if (nbyte == 0) return 0; + + for (;;) { +/* Can't use read() on sockets on Windows, but recv works on all platforms */ + n = recv (fd, buf, nbyte, 0); + if (n == -1 || n == 0) { +#ifndef WIN32 + if (errno == EINTR || errno == EAGAIN) continue; +#endif + return -1; + } + + nread += n; + + if (n >= (int) nbyte) return nread; + + buf += n; + nbyte -= n; + } +} + +static void make_netbios_name(const char *in, unsigned char out[]) +{ + size_t i, j = 0, n; + + /* create a NetBIOS name from the DNS name + * + * - use up to the first 16 chars of the first part of the hostname + * - convert to all uppercase + * - use the tail end of the output buffer as temp space + */ + n = strcspn(in, "."); + if (n > 16) n = 16; + strncpy(out+18, in, n); + in = out+18; + ucase(in, n); + + out[j++] = 0x20; + for (i = 0; i < n; i++) { + out[j++] = ((in[i] >> 4) & 0xf) + 0x41; + out[j++] = (in[i] & 0xf) + 0x41; + } + for (; i < 16; i++) { + out[j++] = ((0x20 >> 4) & 0xf) + 0x41; + out[j++] = (0x20 & 0xf) + 0x41; + } + out[j] = 0; +} + +static SOCKET smb_connect_server(const sasl_utils_t *utils, const char *client, + const char *server) +{ + struct addrinfo hints; + struct addrinfo *ai = NULL, *r; + SOCKET s = (SOCKET) -1; + int err; + char * error_str; +#ifdef WIN32 + DWORD saved_errno; +#else + int saved_errno; +#endif + int niflags; + char *port = "139"; + char hbuf[NI_MAXHOST], pbuf[NI_MAXSERV]; + + unsigned char called[34]; + unsigned char calling[34]; + struct iovec iov[3]; + uint32 pkt; + int rc; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_CANONNAME; + if ((err = getaddrinfo(server, port, &hints, &ai)) != 0) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: getaddrinfo %s/%s: %s", + server, port, gai_strerror(err)); + return -1; + } + + /* Make sure we have AF_INET or AF_INET6 addresses. */ + if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) { + utils->log(NULL, SASL_LOG_ERR, "NTLM: no IP address info for %s", + ai->ai_canonname ? ai->ai_canonname : server); + freeaddrinfo(ai); + return -1; + } + + /* establish connection to authentication server */ + for (r = ai; r; r = r->ai_next) { + s = socket(r->ai_family, r->ai_socktype, r->ai_protocol); + if (s < 0) + continue; + if (connect(s, r->ai_addr, r->ai_addrlen) >= 0) + break; +#ifdef WIN32 + saved_errno = WSAGetLastError(); +#else + saved_errno = errno; +#endif + closesocket (s); + s = -1; + niflags = (NI_NUMERICHOST | NI_NUMERICSERV); +#ifdef NI_WITHSCOPEID + if (r->ai_family == AF_INET6) + niflags |= NI_WITHSCOPEID; +#endif + if (getnameinfo(r->ai_addr, r->ai_addrlen, hbuf, sizeof(hbuf), + pbuf, sizeof(pbuf), niflags) != 0) { + strcpy(hbuf, "unknown"); + strcpy(pbuf, "unknown"); + } + + /* Can't use errno (and %m), as it doesn't contain + * the socket error on Windows */ + error_str = _plug_get_error_message (utils, saved_errno); + utils->log(NULL, SASL_LOG_WARN, "NTLM: connect %s[%s]/%s: %s", + ai->ai_canonname ? ai->ai_canonname : server, + hbuf, + pbuf, + error_str); + utils->free (error_str); + } + if (s < 0) { + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, NULL, 0, + pbuf, sizeof(pbuf), NI_NUMERICSERV) != 0) { + strcpy(pbuf, "unknown"); + } + utils->log(NULL, SASL_LOG_ERR, "NTLM: couldn't connect to %s/%s", + ai->ai_canonname ? ai->ai_canonname : server, pbuf); + freeaddrinfo(ai); + return -1; + } + + freeaddrinfo(ai); + + /*** send NetBIOS session request ***/ + + /* get length of data */ + pkt = sizeof(called) + sizeof(calling); + + /* make sure length is less than 17 bits */ + if (pkt >= (1 << 17)) { + closesocket(s); + return -1; + } + + /* prepend the packet type */ + pkt |= (NBT_SESSION_REQUEST << 24); + pkt = htonl(pkt); + + /* XXX should determine the real NetBIOS name */ + make_netbios_name(server, called); + make_netbios_name(client, calling); + + iov[0].iov_base = (void *) &pkt; + iov[0].iov_len = sizeof(pkt); + iov[1].iov_base = called; + iov[1].iov_len = sizeof(called); + iov[2].iov_base = calling; + iov[2].iov_len = sizeof(calling); + + rc = retry_writev(s, iov, N(iov)); + if (rc == -1) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: error sending NetBIOS session request"); + closesocket(s); + return -1; + } + + rc = retry_read(s, (char *) &pkt, sizeof(pkt)); + pkt = ntohl(pkt); + if (rc == -1 || pkt != (uint32) (NBT_POSITIVE_SESSION_RESP << 24)) { + unsigned char ec = NBT_ERR_UNSPECIFIED; + char *errstr; + + retry_read(s, (char *) &ec, sizeof(ec)); + switch (ec) { + case NBT_ERR_NO_LISTEN_CALLED: + errstr = "Not listening on called name"; + break; + case NBT_ERR_NO_LISTEN_CALLING: + errstr = "Not listening for calling name"; + break; + case NBT_ERR_CALLED_NOT_PRESENT: + errstr = "Called name not present"; + break; + case NBT_ERR_INSUFFICIENT_RESRC: + errstr = "Called name present, but insufficient resources"; + break; + default: + errstr = "Unspecified error"; + } + utils->log(NULL, SASL_LOG_ERR, + "NTLM: negative NetBIOS session response: %s", errstr); + closesocket(s); + return -1; + } + + return s; +} + +static int smb_negotiate_protocol(const sasl_utils_t *utils, + server_context_t *text, char **domain) +{ + SMB_Header hdr; + SMB_NegProt_Resp resp; + unsigned char hbuf[SMB_HDR_SIZE], *p; + unsigned char wordcount = 0; + unsigned char bc[sizeof(uint16)]; + uint16 bytecount; + uint32 len, nl; + int n_dialects = N(SMB_DIALECTS); + struct iovec iov[4+N(SMB_DIALECTS)]; + int i, n; + int rc; + pid_t current_pid; + + /*** create a negotiate protocol request ***/ + + /* create a header */ + memset(&hdr, 0, sizeof(hdr)); + hdr.command = SMB_COM_NEGOTIATE_PROTOCOL; +#if 0 + hdr.flags2 = SMB_FLAGS2_ERR_STATUS; + if (text->flags & NTLM_USE_UNICODE) hdr.flags2 |= SMB_FLAGS2_UNICODE; +#endif + current_pid = getpid(); + if (sizeof(current_pid) <= 2) { + hdr.pid = (uint16) current_pid; + hdr.PidHigh = 0; + } else { + hdr.pid = (uint16) (((uint32) current_pid) & 0xFFFF); + hdr.PidHigh = (uint16) (((uint32) current_pid) >> 16); + } + + load_smb_header(hbuf, &hdr); + + /* put together all of the pieces of the request */ + n = 0; + iov[n].iov_base = (void *) &nl; + iov[n++].iov_len = sizeof(len); + iov[n].iov_base = hbuf; + iov[n++].iov_len = SMB_HDR_SIZE; + iov[n].iov_base = &wordcount; + iov[n++].iov_len = sizeof(wordcount); + iov[n].iov_base = (void *) &bc; + iov[n++].iov_len = sizeof(bc); + + /* add our supported dialects */ + for (i = 0; i < n_dialects; i++) { + iov[n].iov_base = (char *) SMB_DIALECTS[i]; + iov[n++].iov_len = (long) strlen(SMB_DIALECTS[i]) + 1; + } + + /* total up the lengths */ + len = bytecount = 0; + for (i = 1; i < 4; i++) len += iov[i].iov_len; + for (i = 4; i < n; i++) bytecount += (uint16) iov[i].iov_len; + len += bytecount; + nl = htonl(len); + htois((char *) &bc, bytecount); + + /* send it */ + rc = retry_writev(text->sock, iov, n); + if (rc == -1) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: error sending NEGPROT request"); + return SASL_FAIL; + } + + /*** read the negotiate protocol response ***/ + + /* read the total length */ + rc = retry_read(text->sock, (char *) &nl, sizeof(nl)); + if (rc < (int) sizeof(nl)) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: error reading NEGPROT response length"); + return SASL_FAIL; + } + + /* read the data */ + len = ntohl(nl); + if (_plug_buf_alloc(utils, &text->out_buf, &text->out_buf_len, + len) != SASL_OK) { + SETERROR(utils, "cannot allocate NTLM NEGPROT response buffer"); + return SASL_NOMEM; + } + + rc = retry_read(text->sock, text->out_buf, len); + if (rc < (int) len) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: error reading NEGPROT response"); + return SASL_FAIL; + } + p = text->out_buf; + + /* parse the header */ + if (len < SMB_HDR_SIZE) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: not enough data for NEGPROT response header"); + return SASL_FAIL; + } + unload_smb_header(p, &hdr); + p += SMB_HDR_SIZE; + len -= SMB_HDR_SIZE; + + /* sanity check the header */ + if (memcmp(hdr.protocol, SMB_HDR_PROTOCOL, 4) /* correct protocol */ + || hdr.command != SMB_COM_NEGOTIATE_PROTOCOL /* correct command */ + || hdr.status /* no errors */ + || !(hdr.flags & SMB_FLAGS_SERVER_TO_REDIR)) { /* response */ + utils->log(NULL, SASL_LOG_ERR, + "NTLM: error in NEGPROT response header: %ld", + hdr.status); + return SASL_FAIL; + } + + /* get the wordcount */ + if (len < 1) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: not enough data for NEGPROT response wordcount"); + return SASL_FAIL; + } + wordcount = *p++; + len--; + + /* parse the parameters */ + if (wordcount != SMB_NEGPROT_RESP_SIZE / sizeof(uint16)) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: incorrect NEGPROT wordcount for NT LM 0.12"); + return SASL_FAIL; + } + unload_negprot_resp(p, &resp); + p += SMB_NEGPROT_RESP_SIZE; + len -= SMB_NEGPROT_RESP_SIZE; + + /* sanity check the parameters */ + if (resp.dialect_index != 0 + || !(resp.security_mode & SMB_SECURITY_MODE_USER) + || !(resp.security_mode & SMB_SECURITY_MODE_ENCRYPT) + || resp.security_mode & SMB_SECURITY_MODE_SIGN_REQ + || resp.capabilities & SMB_CAP_EXTENDED_SECURITY + || resp.encryption_key_length != NTLM_NONCE_LENGTH) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: error in NEGPROT response parameters"); + return SASL_FAIL; + } + + /* get the bytecount */ + if (len < 2) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: not enough data for NEGPROT response bytecount"); + return SASL_FAIL; + } + bytecount = itohs(p); + p += 2; + len -= 2; + if (len != bytecount) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: incorrect bytecount for NEGPROT response data"); + return SASL_FAIL; + } + + /* parse the data */ + memcpy(text->nonce, p, resp.encryption_key_length); + p += resp.encryption_key_length; + len -= resp.encryption_key_length; + + /* if client asked for target, send domain */ + if (text->flags & NTLM_ASK_TARGET) { + *domain = utils->malloc(len); + if (domain == NULL) { + MEMERROR(utils); + return SASL_NOMEM; + } + memcpy(*domain, p, len); + from_unicode(*domain, *domain, len); + + text->flags |= NTLM_TARGET_IS_DOMAIN; + } + + return SASL_OK; +} + +static int smb_session_setup(const sasl_utils_t *utils, server_context_t *text, + const char *authid, char *domain, + unsigned char *lm_resp, unsigned lm_resp_len, + unsigned char *nt_resp, unsigned nt_resp_len) +{ + SMB_Header hdr; + SMB_SessionSetup setup; + SMB_SessionSetup_Resp resp; + unsigned char hbuf[SMB_HDR_SIZE], sbuf[SMB_SESSION_SETUP_SIZE], *p; + unsigned char wordcount = SMB_SESSION_SETUP_SIZE / sizeof(uint16); + unsigned char bc[sizeof(uint16)]; + uint16 bytecount; + uint32 len, nl; + struct iovec iov[12]; + int i, n; + int rc; +#ifdef WIN32 + char osbuf[80]; +#else + char osbuf[2*SYS_NMLN+2]; +#endif + char lanman[20]; + pid_t current_pid; + + /*** create a session setup request ***/ + + /* create a header */ + memset(&hdr, 0, sizeof(hdr)); + hdr.command = SMB_COM_SESSION_SETUP_ANDX; +#if 0 + hdr.flags2 = SMB_FLAGS2_ERR_STATUS; + if (text->flags & NTLM_USE_UNICODE) hdr.flags2 |= SMB_FLAGS2_UNICODE; +#endif + current_pid = getpid(); + if (sizeof(current_pid) <= 2) { + hdr.pid = (uint16) current_pid; + hdr.PidHigh = 0; + } else { + hdr.pid = (uint16) (((uint32) current_pid) & 0xFFFF); + hdr.PidHigh = (uint16) (((uint32) current_pid) >> 16); + } + + load_smb_header(hbuf, &hdr); + + /* create a the setup parameters */ + memset(&setup, 0, sizeof(setup)); + setup.andx_command = SMB_COM_NONE; + setup.max_buffer_size = 0xFFFF; + if (lm_resp) setup.case_insensitive_passwd_len = lm_resp_len; + if (nt_resp) setup.case_sensitive_passwd_len = nt_resp_len; +#if 0 + if (text->flags & NTLM_USE_UNICODE) + setup.capabilities = SMB_CAP_UNICODE; +#endif + load_session_setup(sbuf, &setup); + + _plug_snprintf_os_info (osbuf, sizeof(osbuf)); + + snprintf(lanman, sizeof(lanman), "Cyrus SASL %u.%u.%u", + SASL_VERSION_MAJOR, SASL_VERSION_MINOR, + SASL_VERSION_STEP); + + /* put together all of the pieces of the request */ + n = 0; + iov[n].iov_base = (void *) &nl; + iov[n++].iov_len = sizeof(len); + iov[n].iov_base = hbuf; + iov[n++].iov_len = SMB_HDR_SIZE; + iov[n].iov_base = &wordcount; + iov[n++].iov_len = sizeof(wordcount); + iov[n].iov_base = sbuf; + iov[n++].iov_len = SMB_SESSION_SETUP_SIZE; + iov[n].iov_base = (void *) &bc; + iov[n++].iov_len = sizeof(bc); + if (lm_resp) { + iov[n].iov_base = lm_resp; + iov[n++].iov_len = NTLM_RESP_LENGTH; + } + if (nt_resp) { + iov[n].iov_base = nt_resp; + iov[n++].iov_len = NTLM_RESP_LENGTH; + } + iov[n].iov_base = (char*) authid; + iov[n++].iov_len = (long) strlen(authid) + 1; + if (!domain) domain = ""; + iov[n].iov_base = domain; + iov[n++].iov_len = (long) strlen(domain) + 1; + iov[n].iov_base = osbuf; + iov[n++].iov_len = (long) strlen(osbuf) + 1; + iov[n].iov_base = lanman; + iov[n++].iov_len = (long) strlen(lanman) + 1; + + /* total up the lengths */ + len = bytecount = 0; + for (i = 1; i < 5; i++) len += iov[i].iov_len; + for (i = 5; i < n; i++) bytecount += (uint16) iov[i].iov_len; + len += bytecount; + nl = htonl(len); + htois((char *) &bc, bytecount); + + /* send it */ + rc = retry_writev(text->sock, iov, n); + if (rc == -1) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: error sending SESSIONSETUP request"); + return SASL_FAIL; + } + + /*** read the session setup response ***/ + + /* read the total length */ + rc = retry_read(text->sock, (char *) &nl, sizeof(nl)); + if (rc < (int) sizeof(nl)) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: error reading SESSIONSETUP response length"); + return SASL_FAIL; + } + + /* read the data */ + len = ntohl(nl); + if (_plug_buf_alloc(utils, &text->out_buf, &text->out_buf_len, + len) != SASL_OK) { + SETERROR(utils, + "cannot allocate NTLM SESSIONSETUP response buffer"); + return SASL_NOMEM; + } + + rc = retry_read(text->sock, text->out_buf, len); + if (rc < (int) len) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: error reading SESSIONSETUP response"); + return SASL_FAIL; + } + p = text->out_buf; + + /* parse the header */ + if (len < SMB_HDR_SIZE) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: not enough data for SESSIONSETUP response header"); + return SASL_FAIL; + } + unload_smb_header(p, &hdr); + p += SMB_HDR_SIZE; + len -= SMB_HDR_SIZE; + + /* sanity check the header */ + if (memcmp(hdr.protocol, SMB_HDR_PROTOCOL, 4) /* correct protocol */ + || hdr.command != SMB_COM_SESSION_SETUP_ANDX /* correct command */ + || !(hdr.flags & SMB_FLAGS_SERVER_TO_REDIR)) { /* response */ + utils->log(NULL, SASL_LOG_ERR, + "NTLM: error in SESSIONSETUP response header"); + return SASL_FAIL; + } + + /* check auth success */ + if (hdr.status) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: auth failure: %ld", hdr.status); + return SASL_BADAUTH; + } + + /* get the wordcount */ + if (len < 1) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: not enough data for SESSIONSETUP response wordcount"); + return SASL_FAIL; + } + wordcount = *p++; + len--; + + /* parse the parameters */ + if (wordcount < SMB_SESSION_SETUP_RESP_SIZE / sizeof(uint16)) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: incorrect SESSIONSETUP wordcount"); + return SASL_FAIL; + } + unload_session_setup_resp(p, &resp); + + /* check auth success */ + if (resp.action & SMB_REQUEST_MODE_GUEST) { + utils->log(NULL, SASL_LOG_ERR, + "NTLM: authenticated as guest"); + return SASL_BADAUTH; + } + + return SASL_OK; +} + +/* + * Create a server challenge message (type 2) consisting of: + * + * signature (8 bytes) + * message type (uint32) + * target name (buffer) + * flags (uint32) + * challenge (8 bytes) + * context (8 bytes) + * target info (buffer) + * data + */ +static int create_challenge(const sasl_utils_t *utils, + char **buf, unsigned *buflen, + const char *target, uint32 flags, + const u_char *nonce, unsigned *outlen) +{ + uint32 offset = NTLM_TYPE2_DATA_OFFSET; + u_char *base; + + if (!nonce) { + SETERROR(utils, "need nonce for NTLM challenge"); + return SASL_FAIL; + } + + *outlen = offset + 2 * (unsigned) xstrlen(target); + + if (_plug_buf_alloc(utils, buf, buflen, *outlen) != SASL_OK) { + SETERROR(utils, "cannot allocate NTLM challenge"); + return SASL_NOMEM; + } + + base = *buf; + memset(base, 0, *outlen); + memcpy(base + NTLM_SIG_OFFSET, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)); + htoil(base + NTLM_TYPE_OFFSET, NTLM_TYPE_CHALLENGE); + load_buffer(base + NTLM_TYPE2_TARGET_OFFSET, + ucase(target, 0), (uint16) xstrlen(target), flags & NTLM_USE_UNICODE, + base, &offset); + htoil(base + NTLM_TYPE2_FLAGS_OFFSET, flags); + memcpy(base + NTLM_TYPE2_CHALLENGE_OFFSET, nonce, NTLM_NONCE_LENGTH); + + return SASL_OK; +} + +static int ntlm_server_mech_new(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + void **conn_context) +{ + server_context_t *text; + const char *serv; + unsigned int len; + SOCKET sock = (SOCKET) -1; + + sparams->utils->getopt(sparams->utils->getopt_context, + "NTLM", "ntlm_server", &serv, &len); + if (serv) { + unsigned int i,j; + char *tmp, *next; + + /* strip any whitespace */ + if(_plug_strdup(sparams->utils, serv, &tmp, NULL) != SASL_OK) { + MEMERROR( sparams->utils ); + return SASL_NOMEM; + } + for(i=0, j=0; iutils, sparams->serverFQDN, serv); + } while(sock == (SOCKET) -1 && next); + + sparams->utils->free(tmp); + if (sock == (SOCKET) -1) return SASL_UNAVAIL; + } + + /* holds state are in */ + text = sparams->utils->malloc(sizeof(server_context_t)); + if (text == NULL) { + MEMERROR( sparams->utils ); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(server_context_t)); + + text->state = 1; + text->sock = sock; + + *conn_context = text; + + return SASL_OK; +} + +static int ntlm_server_mech_step1(server_context_t *text, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams __attribute__((unused))) +{ + char *domain = NULL; + int result; + + if (!clientin || clientinlen < NTLM_TYPE1_MINSIZE || + memcmp(clientin, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)) || + itohl(clientin + NTLM_TYPE_OFFSET) != NTLM_TYPE_REQUEST) { + SETERROR(sparams->utils, "client didn't issue valid NTLM request"); + return SASL_BADPROT; + } + + text->flags = itohl(clientin + NTLM_TYPE1_FLAGS_OFFSET); + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "client flags: %x", text->flags); + + text->flags &= NTLM_FLAGS_MASK; /* mask off the bits we don't support */ + + /* if client can do Unicode, turn off ASCII */ + if (text->flags & NTLM_USE_UNICODE) text->flags &= ~NTLM_USE_ASCII; + + if (text->sock == -1) { + /* generate challenge internally */ + + /* if client asked for target, use FQDN as server target */ + if (text->flags & NTLM_ASK_TARGET) { + result = _plug_strdup(sparams->utils, sparams->serverFQDN, + &domain, NULL); + if (result != SASL_OK) return result; + + text->flags |= NTLM_TARGET_IS_SERVER; + } + + /* generate a nonce */ + sparams->utils->rand(sparams->utils->rpool, + (char *) text->nonce, NTLM_NONCE_LENGTH); + } + else { + /* proxy the response/challenge */ + result = smb_negotiate_protocol(sparams->utils, text, &domain); + if (result != SASL_OK) goto cleanup; + } + + result = create_challenge(sparams->utils, + &text->out_buf, &text->out_buf_len, + domain, text->flags, text->nonce, serveroutlen); + if (result != SASL_OK) goto cleanup; + + *serverout = text->out_buf; + + text->state = 2; + + result = SASL_CONTINUE; + + cleanup: + if (domain) sparams->utils->free(domain); + + return result; +} + +static int ntlm_server_mech_step2(server_context_t *text, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout __attribute__((unused)), + unsigned *serveroutlen __attribute__((unused)), + sasl_out_params_t *oparams) +{ + unsigned char *lm_resp = NULL, *nt_resp = NULL; + char *domain = NULL, *authid = NULL; + unsigned lm_resp_len, nt_resp_len, domain_len, authid_len; + int result; + + if (!clientin || clientinlen < NTLM_TYPE3_MINSIZE || + memcmp(clientin, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)) || + itohl(clientin + NTLM_TYPE_OFFSET) != NTLM_TYPE_RESPONSE) { + SETERROR(sparams->utils, "client didn't issue valid NTLM response"); + return SASL_BADPROT; + } + + result = unload_buffer(sparams->utils, clientin + NTLM_TYPE3_LMRESP_OFFSET, + (u_char **) &lm_resp, &lm_resp_len, 0, + clientin, clientinlen); + if (result != SASL_OK) goto cleanup; + + result = unload_buffer(sparams->utils, clientin + NTLM_TYPE3_NTRESP_OFFSET, + (u_char **) &nt_resp, &nt_resp_len, 0, + clientin, clientinlen); + if (result != SASL_OK) goto cleanup; + + result = unload_buffer(sparams->utils, clientin + NTLM_TYPE3_DOMAIN_OFFSET, + (u_char **) &domain, &domain_len, + text->flags & NTLM_USE_UNICODE, + clientin, clientinlen); + if (result != SASL_OK) goto cleanup; + + result = unload_buffer(sparams->utils, clientin + NTLM_TYPE3_USER_OFFSET, + (u_char **) &authid, &authid_len, + text->flags & NTLM_USE_UNICODE, + clientin, clientinlen); + if (result != SASL_OK) goto cleanup; + + /* require at least one response and an authid */ + if ((!lm_resp && !nt_resp) || + (lm_resp && lm_resp_len < NTLM_RESP_LENGTH) || + (nt_resp && nt_resp_len < NTLM_RESP_LENGTH) || + !authid) { + SETERROR(sparams->utils, "client issued incorrect/nonexistent responses"); + result = SASL_BADPROT; + goto cleanup; + } + + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "client user: %s", authid); + if (domain) sparams->utils->log(NULL, SASL_LOG_DEBUG, + "client domain: %s", domain); + + if (text->sock == -1) { + /* verify the response internally */ + + sasl_secret_t *password = NULL; + size_t pass_len; + const char *password_request[] = { SASL_AUX_PASSWORD, + NULL }; + struct propval auxprop_values[2]; + unsigned char hash[NTLM_HASH_LENGTH]; + unsigned char resp[NTLM_RESP_LENGTH]; + + /* fetch user's password */ + result = sparams->utils->prop_request(sparams->propctx, password_request); + if (result != SASL_OK) goto cleanup; + + /* this will trigger the getting of the aux properties */ + result = sparams->canon_user(sparams->utils->conn, authid, authid_len, + SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) goto cleanup; + + result = sparams->utils->prop_getnames(sparams->propctx, + password_request, + auxprop_values); + if (result < 0 || + (!auxprop_values[0].name || !auxprop_values[0].values)) { + /* We didn't find this username */ + SETERROR(sparams->utils, "no secret in database"); + result = sparams->transition ? SASL_TRANS : SASL_NOUSER; + goto cleanup; + } + + pass_len = strlen(auxprop_values[0].values[0]); + if (pass_len == 0) { + SETERROR(sparams->utils, "empty secret"); + result = SASL_FAIL; + goto cleanup; + } + + password = sparams->utils->malloc(sizeof(sasl_secret_t) + pass_len); + if (!password) { + result = SASL_NOMEM; + goto cleanup; + } + + password->len = (unsigned) pass_len; + strncpy(password->data, auxprop_values[0].values[0], pass_len + 1); + + /* erase the plaintext password */ + sparams->utils->prop_erase(sparams->propctx, password_request[0]); + + /* calculate our own response(s) and compare with client's */ + result = SASL_OK; + if (nt_resp && (nt_resp_len > NTLM_RESP_LENGTH)) { + /* Try NTv2 response */ + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "calculating NTv2 response"); + V2(resp, password, authid, domain, text->nonce, + nt_resp + MD5_DIGEST_LENGTH, nt_resp_len - MD5_DIGEST_LENGTH, + sparams->utils, &text->out_buf, &text->out_buf_len, + &result); + + /* No need to compare the blob */ + if (memcmp(nt_resp, resp, MD5_DIGEST_LENGTH)) { + SETERROR(sparams->utils, "incorrect NTLMv2 response"); + result = SASL_BADAUTH; + } + } + else if (nt_resp) { + /* Try NT response */ + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "calculating NT response"); + P24(resp, P21(hash, password, P16_nt, sparams->utils, + &text->out_buf, &text->out_buf_len, &result), + text->nonce); + if (memcmp(nt_resp, resp, NTLM_RESP_LENGTH)) { + SETERROR(sparams->utils, "incorrect NTLM response"); + result = SASL_BADAUTH; + } + } + else if (lm_resp) { + /* Try LMv2 response */ + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "calculating LMv2 response"); + V2(resp, password, authid, domain, text->nonce, + lm_resp + MD5_DIGEST_LENGTH, lm_resp_len - MD5_DIGEST_LENGTH, + sparams->utils, &text->out_buf, &text->out_buf_len, + &result); + + /* No need to compare the blob */ + if (memcmp(lm_resp, resp, MD5_DIGEST_LENGTH)) { + /* Try LM response */ + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "calculating LM response"); + P24(resp, P21(hash, password, P16_lm, sparams->utils, + &text->out_buf, &text->out_buf_len, &result), + text->nonce); + if (memcmp(lm_resp, resp, NTLM_RESP_LENGTH)) { + SETERROR(sparams->utils, "incorrect LMv1/v2 response"); + result = SASL_BADAUTH; + } + } + } + + _plug_free_secret(sparams->utils, &password); + + if (result != SASL_OK) goto cleanup; + } + else { + /* proxy the response */ + result = smb_session_setup(sparams->utils, text, authid, domain, + lm_resp, lm_resp_len, nt_resp, nt_resp_len); + if (result != SASL_OK) goto cleanup; + + result = sparams->canon_user(sparams->utils->conn, authid, authid_len, + SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) goto cleanup; + } + + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + result = SASL_OK; + + cleanup: + if (lm_resp) sparams->utils->free(lm_resp); + if (nt_resp) sparams->utils->free(nt_resp); + if (domain) sparams->utils->free(domain); + if (authid) sparams->utils->free(authid); + + return result; +} + +static int ntlm_server_mech_step(void *conn_context, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + server_context_t *text = (server_context_t *) conn_context; + + *serverout = NULL; + *serveroutlen = 0; + + if (text == NULL) { + return SASL_BADPROT; + } + + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "NTLM server step %d\n", text->state); + + switch (text->state) { + + case 1: + return ntlm_server_mech_step1(text, sparams, clientin, clientinlen, + serverout, serveroutlen, oparams); + + case 2: + return ntlm_server_mech_step2(text, sparams, clientin, clientinlen, + serverout, serveroutlen, oparams); + + default: + sparams->utils->log(NULL, SASL_LOG_ERR, + "Invalid NTLM server step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static void ntlm_server_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + server_context_t *text = (server_context_t *) conn_context; + + if (!text) return; + + if (text->out_buf) utils->free(text->out_buf); + if (text->sock != -1) closesocket(text->sock); + + utils->free(text); +} + +static sasl_server_plug_t ntlm_server_plugins[] = +{ + { + "NTLM", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS, /* security_flags */ + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_SUPPORTS_HTTP, /* features */ + NULL, /* glob_context */ + &ntlm_server_mech_new, /* mech_new */ + &ntlm_server_mech_step, /* mech_step */ + &ntlm_server_mech_dispose, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* setpass */ + NULL, /* user_query */ + NULL, /* idle */ + NULL, /* mech_avail */ + NULL /* spare */ + } +}; + +int ntlm_server_plug_init(sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_SERVER_PLUG_VERSION) { + SETERROR(utils, "NTLM version mismatch"); + return SASL_BADVERS; + } + + *out_version = SASL_SERVER_PLUG_VERSION; + *pluglist = ntlm_server_plugins; + *plugcount = 1; + + return SASL_OK; +} + +/***************************** Client Section *****************************/ + +typedef struct client_context { + int state; + + /* per-step mem management */ + char *out_buf; + unsigned out_buf_len; + +} client_context_t; + +/* + * Create a client request (type 1) consisting of: + * + * signature (8 bytes) + * message type (uint32) + * flags (uint32) + * domain (buffer) + * workstation (buffer) + * data + */ +static int create_request(const sasl_utils_t *utils, + char **buf, unsigned *buflen, + const char *domain, const char *wkstn, + unsigned *outlen) +{ + uint32 flags = ( NTLM_USE_UNICODE | NTLM_USE_ASCII | + NTLM_ASK_TARGET | NTLM_AUTH_NTLM ); + uint32 offset = NTLM_TYPE1_DATA_OFFSET; + u_char *base; + + *outlen = (unsigned) (offset + xstrlen(domain) + xstrlen(wkstn)); + if (_plug_buf_alloc(utils, buf, buflen, *outlen) != SASL_OK) { + SETERROR(utils, "cannot allocate NTLM request"); + return SASL_NOMEM; + } + + base = *buf; + memset(base, 0, *outlen); + memcpy(base + NTLM_SIG_OFFSET, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)); + htoil(base + NTLM_TYPE_OFFSET, NTLM_TYPE_REQUEST); + htoil(base + NTLM_TYPE1_FLAGS_OFFSET, flags); + load_buffer(base + NTLM_TYPE1_DOMAIN_OFFSET, + domain, (uint16) xstrlen(domain), 0, base, &offset); + load_buffer(base + NTLM_TYPE1_WORKSTN_OFFSET, + wkstn, (uint16) xstrlen(wkstn), 0, base, &offset); + + return SASL_OK; +} + +/* + * Create a client response (type 3) consisting of: + * + * signature (8 bytes) + * message type (uint32) + * LM/LMv2 response (buffer) + * NTLM/NTLMv2 response (buffer) + * domain (buffer) + * user name (buffer) + * workstation (buffer) + * session key (buffer) + * flags (uint32) + * data + */ +static int create_response(const sasl_utils_t *utils, + char **buf, unsigned *buflen, + const u_char *lm_resp, const u_char *nt_resp, + const char *domain, const char *user, + const char *wkstn, const u_char *key, + uint32 flags, unsigned *outlen) +{ + uint32 offset = NTLM_TYPE3_DATA_OFFSET; + u_char *base; + + if (!lm_resp && !nt_resp) { + SETERROR(utils, "need at least one NT/LM response"); + return SASL_FAIL; + } + + *outlen = (unsigned) (offset + (flags & NTLM_USE_UNICODE ? 2 : 1) * + (xstrlen(domain) + xstrlen(user) + xstrlen(wkstn))); + if (lm_resp) *outlen += NTLM_RESP_LENGTH; + if (nt_resp) *outlen += NTLM_RESP_LENGTH; + if (key) *outlen += NTLM_SESSKEY_LENGTH; + + if (_plug_buf_alloc(utils, buf, buflen, *outlen) != SASL_OK) { + SETERROR(utils, "cannot allocate NTLM response"); + return SASL_NOMEM; + } + + base = *buf; + memset(base, 0, *outlen); + memcpy(base + NTLM_SIG_OFFSET, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)); + htoil(base + NTLM_TYPE_OFFSET, NTLM_TYPE_RESPONSE); + load_buffer(base + NTLM_TYPE3_LMRESP_OFFSET, + lm_resp, lm_resp ? NTLM_RESP_LENGTH : 0, 0, base, &offset); + load_buffer(base + NTLM_TYPE3_NTRESP_OFFSET, + nt_resp, nt_resp ? NTLM_RESP_LENGTH : 0, 0, base, &offset); + load_buffer(base + NTLM_TYPE3_DOMAIN_OFFSET, + ucase(domain, 0), (uint16) xstrlen(domain), flags & NTLM_USE_UNICODE, + base, &offset); + load_buffer(base + NTLM_TYPE3_USER_OFFSET, + user, (uint16) xstrlen(user), flags & NTLM_USE_UNICODE, base, &offset); + load_buffer(base + NTLM_TYPE3_WORKSTN_OFFSET, + ucase(wkstn, 0), (uint16) xstrlen(wkstn), flags & NTLM_USE_UNICODE, + base, &offset); + load_buffer(base + NTLM_TYPE3_SESSIONKEY_OFFSET, + key, key ? NTLM_SESSKEY_LENGTH : 0, 0, base, &offset); + htoil(base + NTLM_TYPE3_FLAGS_OFFSET, flags); + + return SASL_OK; +} + +static int ntlm_client_mech_new(void *glob_context __attribute__((unused)), + sasl_client_params_t *params, + void **conn_context) +{ + client_context_t *text; + + /* holds state are in */ + text = params->utils->malloc(sizeof(client_context_t)); + if (text == NULL) { + MEMERROR( params->utils ); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(client_context_t)); + + text->state = 1; + + *conn_context = text; + + return SASL_OK; +} + +static int ntlm_client_mech_step1(client_context_t *text, + sasl_client_params_t *params, + const char *serverin __attribute__((unused)), + unsigned serverinlen __attribute__((unused)), + sasl_interact_t **prompt_need __attribute__((unused)), + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams __attribute__((unused))) +{ + int result; + + /* check if sec layer strong enough */ + if (params->props.min_ssf > params->external_ssf) { + SETERROR(params->utils, "SSF requested of NTLM plugin"); + return SASL_TOOWEAK; + } + + /* we don't care about domain or wkstn */ + result = create_request(params->utils, &text->out_buf, &text->out_buf_len, + NULL, NULL, clientoutlen); + if (result != SASL_OK) return result; + + *clientout = text->out_buf; + + text->state = 2; + + return SASL_CONTINUE; +} + +static int ntlm_client_mech_step2(client_context_t *text, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + const char *authid = NULL; + sasl_secret_t *password = NULL; + unsigned int free_password; /* set if we need to free password */ + char *domain = NULL; + int auth_result = SASL_OK; + int pass_result = SASL_OK; + uint32 flags = 0; + unsigned char hash[NTLM_HASH_LENGTH]; + unsigned char resp[NTLM_RESP_LENGTH], *lm_resp = NULL, *nt_resp = NULL; + int result; + const char *sendv2; + + if (!serverin || serverinlen < NTLM_TYPE2_MINSIZE || + memcmp(serverin, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)) || + itohl(serverin + NTLM_TYPE_OFFSET) != NTLM_TYPE_CHALLENGE) { + SETERROR(params->utils, "server didn't issue valid NTLM challenge"); + return SASL_BADPROT; + } + + /* try to get the authid */ + if (oparams->authid == NULL) { + auth_result = _plug_get_authid(params->utils, &authid, prompt_need); + + if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT)) + return auth_result; + } + + /* try to get the password */ + if (password == NULL) { + pass_result = _plug_get_password(params->utils, &password, + &free_password, prompt_need); + + if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT)) + return pass_result; + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + params->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if ((auth_result == SASL_INTERACT) || (pass_result == SASL_INTERACT)) { + /* make the prompt list */ + result = + _plug_make_prompts(params->utils, prompt_need, + NULL, NULL, + auth_result == SASL_INTERACT ? + "Please enter your authentication name" : NULL, + NULL, + pass_result == SASL_INTERACT ? + "Please enter your password" : NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); + if (result != SASL_OK) goto cleanup; + + return SASL_INTERACT; + } + + result = params->canon_user(params->utils->conn, authid, 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) goto cleanup; + + flags = itohl(serverin + NTLM_TYPE2_FLAGS_OFFSET); + params->utils->log(NULL, SASL_LOG_DEBUG, + "server flags: %x", flags); + + flags &= NTLM_FLAGS_MASK; /* mask off the bits we don't support */ + + result = unload_buffer(params->utils, serverin + NTLM_TYPE2_TARGET_OFFSET, + (u_char **) &domain, NULL, + flags & NTLM_USE_UNICODE, + (u_char *) serverin, serverinlen); + if (result != SASL_OK) goto cleanup; + params->utils->log(NULL, SASL_LOG_DEBUG, + "server domain: %s", domain); + + /* should we send a NTLMv2 response? */ + params->utils->getopt(params->utils->getopt_context, + "NTLM", "ntlm_v2", &sendv2, NULL); + if (sendv2 && + (sendv2[0] == '1' || sendv2[0] == 'y' || + (sendv2[0] == 'o' && sendv2[1] == 'n') || sendv2[0] == 't')) { + + /* put the cnonce in place after the LMv2 HMAC */ + char *cnonce = resp + MD5_DIGEST_LENGTH; + + params->utils->log(NULL, SASL_LOG_DEBUG, + "calculating LMv2 response"); + + params->utils->rand(params->utils->rpool, cnonce, NTLM_NONCE_LENGTH); + + V2(resp, password, oparams->authid, domain, + serverin + NTLM_TYPE2_CHALLENGE_OFFSET, cnonce, NTLM_NONCE_LENGTH, + params->utils, &text->out_buf, &text->out_buf_len, &result); + + lm_resp = resp; + } + else if (flags & NTLM_AUTH_NTLM) { + params->utils->log(NULL, SASL_LOG_DEBUG, + "calculating NT response"); + P24(resp, P21(hash, password, P16_nt, params->utils, + &text->out_buf, &text->out_buf_len, &result), + (unsigned char *) serverin + NTLM_TYPE2_CHALLENGE_OFFSET); + nt_resp = resp; + } + else { + params->utils->log(NULL, SASL_LOG_DEBUG, + "calculating LM response"); + P24(resp, P21(hash, password, P16_lm, params->utils, + &text->out_buf, &text->out_buf_len, &result), + (unsigned char *) serverin + NTLM_TYPE2_CHALLENGE_OFFSET); + lm_resp = resp; + } + if (result != SASL_OK) goto cleanup; + + /* we don't care about workstn or session key */ + result = create_response(params->utils, &text->out_buf, &text->out_buf_len, + lm_resp, nt_resp, domain, oparams->authid, + NULL, NULL, flags, clientoutlen); + if (result != SASL_OK) goto cleanup; + + *clientout = text->out_buf; + + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + result = SASL_OK; + + cleanup: + if (domain) params->utils->free(domain); + if (free_password) _plug_free_secret(params->utils, &password); + + return result; +} + +static int ntlm_client_mech_step(void *conn_context, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + client_context_t *text = (client_context_t *) conn_context; + + *clientout = NULL; + *clientoutlen = 0; + + params->utils->log(NULL, SASL_LOG_DEBUG, + "NTLM client step %d\n", text->state); + + switch (text->state) { + + case 1: + return ntlm_client_mech_step1(text, params, serverin, serverinlen, + prompt_need, clientout, clientoutlen, + oparams); + + case 2: + return ntlm_client_mech_step2(text, params, serverin, serverinlen, + prompt_need, clientout, clientoutlen, + oparams); + + default: + params->utils->log(NULL, SASL_LOG_ERR, + "Invalid NTLM client step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static void ntlm_client_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + client_context_t *text = (client_context_t *) conn_context; + + if (!text) return; + + if (text->out_buf) utils->free(text->out_buf); + + utils->free(text); +} + +static sasl_client_plug_t ntlm_client_plugins[] = +{ + { + "NTLM", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS, /* security_flags */ + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_SUPPORTS_HTTP, /* features */ + NULL, /* required_prompts */ + NULL, /* glob_context */ + &ntlm_client_mech_new, /* mech_new */ + &ntlm_client_mech_step, /* mech_step */ + &ntlm_client_mech_dispose, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* idle */ + NULL, /* spare */ + NULL /* spare */ + } +}; + +int ntlm_client_plug_init(sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_CLIENT_PLUG_VERSION) { + SETERROR(utils, "NTLM version mismatch"); + return SASL_BADVERS; + } + + *out_version = SASL_CLIENT_PLUG_VERSION; + *pluglist = ntlm_client_plugins; + *plugcount = 1; + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/ntlm_init.c b/libs/cyrussasl/plugins/ntlm_init.c new file mode 100644 index 00000000..a336fda8 --- /dev/null +++ b/libs/cyrussasl/plugins/ntlm_init.c @@ -0,0 +1,43 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_CLIENT_PLUG_INIT( ntlm ) +SASL_SERVER_PLUG_INIT( ntlm ) + diff --git a/libs/cyrussasl/plugins/otp.c b/libs/cyrussasl/plugins/otp.c new file mode 100644 index 00000000..dd730651 --- /dev/null +++ b/libs/cyrussasl/plugins/otp.c @@ -0,0 +1,1851 @@ +/* OTP SASL plugin + * Ken Murchison + * $Id: otp.c,v 1.43 2011/09/01 14:12:18 mel Exp $ + */ +/* + * Copyright (c) 1998-2009 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include + +#include +#include /* XXX hack for OpenBSD/OpenSSL cruftiness */ + +#include +#define MD5_H /* suppress internal MD5 */ +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +/***************************** Common Section *****************************/ + +static const char plugin_id[] = "$Id: otp.c,v 1.43 2011/09/01 14:12:18 mel Exp $"; + +#define OTP_SEQUENCE_MAX 9999 +#define OTP_SEQUENCE_DEFAULT 499 +#define OTP_SEQUENCE_REINIT 490 +#define OTP_SEED_MIN 1 +#define OTP_SEED_MAX 16 +#define OTP_HASH_SIZE 8 /* 64 bits */ +#define OTP_CHALLENGE_MAX 100 +#define OTP_RESPONSE_MAX 100 +#define OTP_HEX_TYPE "hex:" +#define OTP_WORD_TYPE "word:" +#define OTP_INIT_HEX_TYPE "init-hex:" +#define OTP_INIT_WORD_TYPE "init-word:" + +typedef struct algorithm_option_s { + const char *name; /* name used in challenge/response */ + int swab; /* number of bytes to swab (0, 1, 2, 4, 8) */ + const char *evp_name; /* name used for lookup in EVP table */ +} algorithm_option_t; + +static algorithm_option_t algorithm_options[] = { + {"md4", 0, "md4"}, + {"md5", 0, "md5"}, + {"sha1", 4, "sha1"}, + {NULL, 0, NULL} +}; + +/* Convert the binary data into ASCII hex */ +void bin2hex(unsigned char *bin, int binlen, char *hex) +{ + int i; + unsigned char c; + + for (i = 0; i < binlen; i++) { + c = (bin[i] >> 4) & 0xf; + hex[i*2] = (c > 9) ? ('a' + c - 10) : ('0' + c); + c = bin[i] & 0xf; + hex[i*2+1] = (c > 9) ? ('a' + c - 10) : ('0' + c); + } + hex[i*2] = '\0'; +} + +/* + * Hash the data using the given algorithm and fold it into 64 bits, + * swabbing bytes if necessary. + */ +static void otp_hash(const EVP_MD *md, char *in, size_t inlen, + unsigned char *out, int swab) +{ + EVP_MD_CTX mdctx; + char hash[EVP_MAX_MD_SIZE]; + unsigned int i; + int j; + unsigned hashlen; + + EVP_DigestInit(&mdctx, md); + EVP_DigestUpdate(&mdctx, in, inlen); + EVP_DigestFinal(&mdctx, hash, &hashlen); + + /* Fold the result into 64 bits */ + for (i = OTP_HASH_SIZE; i < hashlen; i++) { + hash[i % OTP_HASH_SIZE] ^= hash[i]; + } + + /* Swab bytes */ + if (swab) { + for (i = 0; i < OTP_HASH_SIZE;) { + for (j = swab-1; j > -swab; i++, j-=2) + out[i] = hash[i+j]; + } + } + else + memcpy(out, hash, OTP_HASH_SIZE); +} + +static int generate_otp(const sasl_utils_t *utils, + algorithm_option_t *alg, unsigned seq, char *seed, + char *secret, char *otp) +{ + const EVP_MD *md; + char *key; + + if (!(md = EVP_get_digestbyname(alg->evp_name))) { + utils->seterror(utils->conn, 0, + "OTP algorithm %s is not available", alg->evp_name); + return SASL_FAIL; + } + + if ((key = utils->malloc(strlen(seed) + strlen(secret) + 1)) == NULL) { + SETERROR(utils, "cannot allocate OTP key"); + return SASL_NOMEM; + } + + /* initial step */ + strcpy(key, seed); + strcat(key, secret); + otp_hash(md, key, strlen(key), otp, alg->swab); + + /* computation step */ + while (seq-- > 0) + otp_hash(md, otp, OTP_HASH_SIZE, otp, alg->swab); + + utils->free(key); + + return SASL_OK; +} + +static int parse_challenge(const sasl_utils_t *utils, + char *chal, algorithm_option_t **alg, + unsigned *seq, char *seed, int is_init) +{ + char *c; + algorithm_option_t *opt; + int n; + + c = chal; + + /* eat leading whitespace */ + while (*c && isspace((int) *c)) c++; + + if (!is_init) { + /* check the prefix */ + if (!*c || strncmp(c, "otp-", 4)) { + SETERROR(utils, "not an OTP challenge"); + return SASL_BADPROT; + } + + /* skip the prefix */ + c += 4; + } + + /* find the algorithm */ + opt = algorithm_options; + while (opt->name) { + if (!strncmp(c, opt->name, strlen(opt->name))) { + break; + } + opt++; + } + + /* didn't find the algorithm in our list */ + if (!opt->name) { + utils->seterror(utils->conn, 0, "OTP algorithm '%s' not supported", c); + return SASL_BADPROT; + } + + /* skip algorithm name */ + c += strlen(opt->name); + *alg = opt; + + /* eat whitespace */ + if (!isspace((int) *c)) { + SETERROR(utils, "no whitespace between OTP algorithm and sequence"); + return SASL_BADPROT; + } + while (*c && isspace((int) *c)) c++; + + /* grab the sequence */ + if ((*seq = strtoul(c, &c, 10)) > OTP_SEQUENCE_MAX) { + utils->seterror(utils->conn, 0, "sequence > %u", OTP_SEQUENCE_MAX); + return SASL_BADPROT; + } + + /* eat whitespace */ + if (!isspace((int) *c)) { + SETERROR(utils, "no whitespace between OTP sequence and seed"); + return SASL_BADPROT; + } + while (*c && isspace((int) *c)) c++; + + /* grab the seed, converting to lowercase as we go */ + n = 0; + while (*c && isalnum((int) *c) && (n < OTP_SEED_MAX)) + seed[n++] = tolower((int) *c++); + if (n > OTP_SEED_MAX) { + utils->seterror(utils->conn, 0, "OTP seed length > %u", OTP_SEED_MAX); + return SASL_BADPROT; + } + else if (n < OTP_SEED_MIN) { + utils->seterror(utils->conn, 0, "OTP seed length < %u", OTP_SEED_MIN); + return SASL_BADPROT; + } + seed[n] = '\0'; + + if (!is_init) { + /* eat whitespace */ + if (!isspace((int) *c)) { + SETERROR(utils, "no whitespace between OTP seed and extensions"); + return SASL_BADPROT; + } + while (*c && isspace((int) *c)) c++; + + /* make sure this is an extended challenge */ + if (strncmp(c, "ext", 3) || + (*(c+=3) && + !(isspace((int) *c) || (*c == ',') || + (*c == '\r') || (*c == '\n')))) { + SETERROR(utils, "not an OTP extended challenge"); + return SASL_BADPROT; + } + } + + return SASL_OK; +} + +static void +otp_common_mech_free(void *global_context __attribute__((unused)), + const sasl_utils_t *utils __attribute__((unused))) +{ + /* Don't call EVP_cleanup(); here, as this might confuse the calling + application if it also uses OpenSSL */ +} + +/***************************** Server Section *****************************/ + +#ifdef HAVE_OPIE +#include +#endif + +typedef struct server_context { + int state; + + char *authid; + int locked; /* is the user's secret locked? */ + algorithm_option_t *alg; +#ifdef HAVE_OPIE + struct opie opie; +#else + char *realm; + unsigned seq; + char seed[OTP_SEED_MAX+1]; + unsigned char otp[OTP_HASH_SIZE]; + time_t timestamp; /* time we locked the secret */ +#endif /* HAVE_OPIE */ + + char *out_buf; + unsigned out_buf_len; +} server_context_t; + +static int otp_server_mech_new(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + void **conn_context) +{ + server_context_t *text; + + /* holds state are in */ + text = sparams->utils->malloc(sizeof(server_context_t)); + if (text == NULL) { + MEMERROR(sparams->utils); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(server_context_t)); + + text->state = 1; + + *conn_context = text; + + return SASL_OK; +} + +#ifdef HAVE_OPIE + +#ifndef OPIE_KEYFILE +#define OPIE_KEYFILE "/etc/opiekeys" +#endif + +static int opie_server_mech_step(void *conn_context, + sasl_server_params_t *params, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + server_context_t *text = (server_context_t *) conn_context; + + *serverout = NULL; + *serveroutlen = 0; + + if (text == NULL) { + return SASL_BADPROT; + } + + switch (text->state) { + + case 1: { + const char *authzid; + const char *authid; + size_t authid_len; + unsigned lup = 0; + int result; + + /* should have received authzid NUL authid */ + + /* get authzid */ + authzid = clientin; + while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup; + + if (lup >= clientinlen) { + SETERROR(params->utils, "Can only find OTP authzid (no authid)"); + return SASL_BADPROT; + } + + /* get authid */ + ++lup; + authid = clientin + lup; + while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup; + + authid_len = clientin + lup - authid; + + if (lup != clientinlen) { + SETERROR(params->utils, + "Got more data than we were expecting in the OTP plugin\n"); + return SASL_BADPROT; + } + + text->authid = params->utils->malloc(authid_len + 1); + if (text->authid == NULL) { + MEMERROR(params->utils); + return SASL_NOMEM; + } + + /* we can't assume that authen is null-terminated */ + strncpy(text->authid, authid, authid_len); + text->authid[authid_len] = '\0'; + + result = params->canon_user(params->utils->conn, text->authid, 0, + SASL_CU_AUTHID, oparams); + if (result != SASL_OK) return result; + + result = params->canon_user(params->utils->conn, + strlen(authzid) ? authzid : text->authid, + 0, SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) return result; + + result = _plug_buf_alloc(params->utils, &(text->out_buf), + &(text->out_buf_len), OTP_CHALLENGE_MAX+1); + if (result != SASL_OK) return result; + + /* create challenge - return sasl_continue on success */ + result = opiechallenge(&text->opie, text->authid, text->out_buf); + + switch (result) { + case 0: + text->locked = 1; + + *serverout = text->out_buf; + *serveroutlen = strlen(text->out_buf); + + text->state = 2; + return SASL_CONTINUE; + + case 1: + SETERROR(params->utils, "opiechallenge: user not found or locked"); + return SASL_NOUSER; + + default: + SETERROR(params->utils, + "opiechallenge: system error (file, memory, I/O)"); + return SASL_FAIL; + } + } + + case 2: { + char response[OPIE_RESPONSE_MAX+1]; + int result; + + /* should have received extended response, + but we'll take anything that we can verify */ + + if (clientinlen > OPIE_RESPONSE_MAX) { + SETERROR(params->utils, "response too long"); + return SASL_BADPROT; + } + + /* we can't assume that the response is null-terminated */ + strncpy(response, clientin, clientinlen); + response[clientinlen] = '\0'; + + /* verify response */ + result = opieverify(&text->opie, response); + text->locked = 0; + + switch (result) { + case 0: + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + return SASL_OK; + + case 1: + SETERROR(params->utils, "opieverify: invalid/incorrect response"); + return SASL_BADAUTH; + + default: + SETERROR(params->utils, + "opieverify: system error (file, memory, I/O)"); + return SASL_FAIL; + } + } + + default: + params->utils->log(NULL, SASL_LOG_ERR, + "Invalid OTP server step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static void opie_server_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + server_context_t *text = (server_context_t *) conn_context; + + if (!text) return; + + /* if we created a challenge, but bailed before the verification of the + response, do a verify here to release the lock on the user key */ + if (text->locked) opieverify(&text->opie, ""); + + if (text->authid) _plug_free_string(utils, &(text->authid)); + + if (text->out_buf) utils->free(text->out_buf); + + utils->free(text); +} + +static int opie_mech_avail(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + void **conn_context __attribute__((unused))) +{ + const char *fname; + unsigned int len; + + sparams->utils->getopt(sparams->utils->getopt_context, + "OTP", "opiekeys", &fname, &len); + + if (!fname) fname = OPIE_KEYFILE; + + if (access(fname, R_OK|W_OK) != 0) { + sparams->utils->log(NULL, SASL_LOG_ERR, + "OTP unavailable because " + "can't read/write key database %s: %m", + fname, errno); + return SASL_NOMECH; + } + + return SASL_OK; +} + +static sasl_server_plug_t otp_server_plugins[] = +{ + { + "OTP", + 0, + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS + | SASL_SEC_FORWARD_SECRECY, + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_DONTUSE_USERPASSWD + | SASL_FEAT_ALLOWS_PROXY, + NULL, + &otp_server_mech_new, + &opie_server_mech_step, + &opie_server_mech_dispose, + &otp_common_mech_free, + NULL, + NULL, + NULL, + &opie_mech_avail, + NULL + } +}; +#else /* HAVE_OPIE */ + +#include "otp.h" + +#define OTP_MDA_DEFAULT "md5" +#define OTP_LOCK_TIMEOUT 5 * 60 /* 5 minutes */ + +/* Convert the ASCII hex into binary data */ +int hex2bin(char *hex, unsigned char *bin, int binlen) +{ + int i; + char *c; + unsigned char msn, lsn; + + memset(bin, 0, binlen); + + for (c = hex, i = 0; i < binlen; c++) { + /* whitespace */ + if (isspace((int) *c)) + continue; + /* end of string, or non-hex char */ + if (!*c || !*(c+1) || !isxdigit((int) *c)) + break; + + msn = (*c > '9') ? tolower((int) *c) - 'a' + 10 : *c - '0'; + c++; + lsn = (*c > '9') ? tolower((int) *c) - 'a' + 10 : *c - '0'; + + bin[i++] = (unsigned char) (msn << 4) | lsn; + } + + return (i < binlen) ? SASL_BADAUTH : SASL_OK; +} + +static int make_secret(const sasl_utils_t *utils, + const char *alg, unsigned seq, char *seed, char *otp, + time_t timeout, sasl_secret_t **secret) +{ + size_t sec_len; + unsigned char *data; + char buf[2*OTP_HASH_SIZE+1]; + + /* + * secret is stored as: + * + * \t \t \t \t \0 + * + * is used as a "lock" when an auth is in progress + * we just set it to zero here (no lock) + */ + sec_len = strlen(alg)+1+4+1+strlen(seed)+1+2*OTP_HASH_SIZE+1+20+1; + *secret = utils->malloc(sizeof(sasl_secret_t)+sec_len); + if (!*secret) { + return SASL_NOMEM; + } + + (*secret)->len = (unsigned) sec_len; + data = (*secret)->data; + + bin2hex(otp, OTP_HASH_SIZE, buf); + buf[2*OTP_HASH_SIZE] = '\0'; + + sprintf(data, "%s\t%04d\t%s\t%s\t%020ld", + alg, seq, seed, buf, timeout); + + return SASL_OK; +} + +static int parse_secret(const sasl_utils_t *utils, + char *secret, size_t seclen, + char *alg, unsigned *seq, char *seed, + unsigned char *otp, + time_t *timeout) +{ + if (strlen(secret) < seclen) { + unsigned char *c; + + /* + * old-style (binary) secret is stored as: + * + * \0 \0 \0 + * + */ + + if (seclen < (3+1+1+1+OTP_SEED_MIN+1+OTP_HASH_SIZE+sizeof(time_t))) { + SETERROR(utils, "OTP secret too short"); + return SASL_FAIL; + } + + c = secret; + + strcpy(alg, (char*) c); + c += strlen(alg)+1; + + *seq = strtoul(c, NULL, 10); + c += 5; + + strcpy(seed, (char*) c); + c += strlen(seed)+1; + + memcpy(otp, c, OTP_HASH_SIZE); + c += OTP_HASH_SIZE; + + memcpy(timeout, c, sizeof(time_t)); + + return SASL_OK; + } + + else { + char buf[2*OTP_HASH_SIZE+1]; + + /* + * new-style (ASCII) secret is stored as: + * + * \t \t \t \t \0 + * + */ + + if (seclen < (3+1+1+1+OTP_SEED_MIN+1+2*OTP_HASH_SIZE+1+20)) { + SETERROR(utils, "OTP secret too short"); + return SASL_FAIL; + } + + sscanf(secret, "%s\t%04d\t%s\t%s\t%020ld", + alg, seq, seed, buf, timeout); + + hex2bin(buf, otp, OTP_HASH_SIZE); + + return SASL_OK; + } +} + +/* Compare two string pointers */ +static int strptrcasecmp(const void *arg1, const void *arg2) +{ + return (strcasecmp(*((char**) arg1), *((char**) arg2))); +} + +/* Convert the 6 words into binary data */ +static int word2bin(const sasl_utils_t *utils, + char *words, unsigned char *bin, const EVP_MD *md) +{ + int i, j; + char *c, *word, buf[OTP_RESPONSE_MAX+1]; + void *base; + int nmemb; + unsigned long x = 0; + unsigned char bits[OTP_HASH_SIZE+1]; /* 1 for checksum */ + unsigned char chksum; + int bit, fbyte, lbyte; + const char **str_ptr; + int alt_dict = 0; + + /* this is a destructive operation, so make a work copy */ + strcpy(buf, words); + memset(bits, 0, 9); + + for (c = buf, bit = 0, i = 0; i < 6; i++, c++, bit+=11) { + while (*c && isspace((int) *c)) c++; + word = c; + while (*c && isalpha((int) *c)) c++; + if (!*c && i < 5) break; + *c = '\0'; + if (strlen(word) < 1 || strlen(word) > 4) { + utils->log(NULL, SASL_LOG_DEBUG, + "incorrect word length '%s'", word); + return SASL_BADAUTH; + } + + /* standard dictionary */ + if (!alt_dict) { + if (strlen(word) < 4) { + base = otp_std_dict; + nmemb = OTP_4LETTER_OFFSET; + } + else { + base = otp_std_dict + OTP_4LETTER_OFFSET; + nmemb = OTP_STD_DICT_SIZE - OTP_4LETTER_OFFSET; + } + + str_ptr = (const char**) bsearch((void*) &word, base, nmemb, + sizeof(const char*), + strptrcasecmp); + if (str_ptr) { + x = (unsigned long) (str_ptr - otp_std_dict); + } + else if (i == 0) { + /* couldn't find first word, try alternate dictionary */ + alt_dict = 1; + } + else { + utils->log(NULL, SASL_LOG_DEBUG, + "word '%s' not found in dictionary", word); + return SASL_BADAUTH; + } + } + + /* alternate dictionary */ + if (alt_dict) { + EVP_MD_CTX mdctx; + char hash[EVP_MAX_MD_SIZE]; + int hashlen; + + EVP_DigestInit(&mdctx, md); + EVP_DigestUpdate(&mdctx, word, strlen(word)); + EVP_DigestFinal(&mdctx, hash, &hashlen); + + /* use lowest 11 bits */ + x = ((hash[hashlen-2] & 0x7) << 8) | hash[hashlen-1]; + } + + /* left align 11 bits on byte boundary */ + x <<= (8 - ((bit+11) % 8)); + /* first output byte containing some of our 11 bits */ + fbyte = bit / 8; + /* last output byte containing some of our 11 bits */ + lbyte = (bit+11) / 8; + /* populate the output bytes with the 11 bits */ + for (j = lbyte; j >= fbyte; j--, x >>= 8) + bits[j] |= (unsigned char) (x & 0xff); + } + + if (i < 6) { + utils->log(NULL, SASL_LOG_DEBUG, "not enough words (%d)", i); + return SASL_BADAUTH; + } + + /* see if the 2-bit checksum is correct */ + for (chksum = 0, i = 0; i < 8; i++) { + for (j = 0; j < 4; j++) { + chksum += ((bits[i] >> (2 * j)) & 0x3); + } + } + chksum <<= 6; + + if (chksum != bits[8]) { + utils->log(NULL, SASL_LOG_DEBUG, "incorrect parity"); + return SASL_BADAUTH; + } + + memcpy(bin, bits, OTP_HASH_SIZE); + + return SASL_OK; +} + +static int verify_response(server_context_t *text, const sasl_utils_t *utils, + char *response) +{ + const EVP_MD *md; + char *c; + int do_init = 0; + unsigned char cur_otp[OTP_HASH_SIZE], prev_otp[OTP_HASH_SIZE]; + int r; + + /* find the MDA */ + if (!(md = EVP_get_digestbyname(text->alg->evp_name))) { + utils->seterror(utils->conn, 0, + "OTP algorithm %s is not available", + text->alg->evp_name); + return SASL_FAIL; + } + + /* eat leading whitespace */ + c = response; + while (isspace((int) *c)) c++; + + if (strchr(c, ':')) { + if (!strncasecmp(c, OTP_HEX_TYPE, strlen(OTP_HEX_TYPE))) { + r = hex2bin(c+strlen(OTP_HEX_TYPE), cur_otp, OTP_HASH_SIZE); + } + else if (!strncasecmp(c, OTP_WORD_TYPE, strlen(OTP_WORD_TYPE))) { + r = word2bin(utils, c+strlen(OTP_WORD_TYPE), cur_otp, md); + } + else if (!strncasecmp(c, OTP_INIT_HEX_TYPE, + strlen(OTP_INIT_HEX_TYPE))) { + do_init = 1; + r = hex2bin(c+strlen(OTP_INIT_HEX_TYPE), cur_otp, OTP_HASH_SIZE); + } + else if (!strncasecmp(c, OTP_INIT_WORD_TYPE, + strlen(OTP_INIT_WORD_TYPE))) { + do_init = 1; + r = word2bin(utils, c+strlen(OTP_INIT_WORD_TYPE), cur_otp, md); + } + else { + SETERROR(utils, "unknown OTP extended response type"); + r = SASL_BADAUTH; + } + } + else { + /* standard response, try word first, and then hex */ + r = word2bin(utils, c, cur_otp, md); + if (r != SASL_OK) + r = hex2bin(c, cur_otp, OTP_HASH_SIZE); + } + + if (r == SASL_OK) { + /* do one more hash (previous otp) and compare to stored otp */ + otp_hash(md, cur_otp, OTP_HASH_SIZE, prev_otp, text->alg->swab); + + if (!memcmp(prev_otp, text->otp, OTP_HASH_SIZE)) { + /* update the secret with this seq/otp */ + memcpy(text->otp, cur_otp, OTP_HASH_SIZE); + text->seq--; + r = SASL_OK; + } + else + r = SASL_BADAUTH; + } + + /* if this is an init- attempt, let's check it out */ + if (r == SASL_OK && do_init) { + char *new_chal = NULL, *new_resp = NULL; + algorithm_option_t *alg; + unsigned seq; + char seed[OTP_SEED_MAX+1]; + unsigned char new_otp[OTP_HASH_SIZE]; + + /* find the challenge and response fields */ + new_chal = strchr(c+strlen(OTP_INIT_WORD_TYPE), ':'); + if (new_chal) { + *new_chal++ = '\0'; + new_resp = strchr(new_chal, ':'); + if (new_resp) + *new_resp++ = '\0'; + } + + if (!(new_chal && new_resp)) + return SASL_BADAUTH; + + if ((r = parse_challenge(utils, new_chal, &alg, &seq, seed, 1)) + != SASL_OK) { + return r; + } + + if (seq < 1 || !strcasecmp(seed, text->seed)) + return SASL_BADAUTH; + + /* find the MDA */ + if (!(md = EVP_get_digestbyname(alg->evp_name))) { + utils->seterror(utils->conn, 0, + "OTP algorithm %s is not available", + alg->evp_name); + return SASL_BADAUTH; + } + + if (!strncasecmp(c, OTP_INIT_HEX_TYPE, strlen(OTP_INIT_HEX_TYPE))) { + r = hex2bin(new_resp, new_otp, OTP_HASH_SIZE); + } + else if (!strncasecmp(c, OTP_INIT_WORD_TYPE, + strlen(OTP_INIT_WORD_TYPE))) { + r = word2bin(utils, new_resp, new_otp, md); + } + + if (r == SASL_OK) { + /* setup for new secret */ + text->alg = alg; + text->seq = seq; + strcpy(text->seed, seed); + memcpy(text->otp, new_otp, OTP_HASH_SIZE); + } + } + + return r; +} + +static int otp_server_mech_step1(server_context_t *text, + sasl_server_params_t *params, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + const char *authzid; + const char *authidp; + size_t authid_len; + unsigned lup = 0; + int result, n; + const char *lookup_request[] = { "*cmusaslsecretOTP", + NULL }; + const char *store_request[] = { "cmusaslsecretOTP", + NULL }; + struct propval auxprop_values[2]; + char mda[10]; + time_t timeout; + sasl_secret_t *sec = NULL; + struct propctx *propctx = NULL; + + /* should have received authzid NUL authid */ + + /* get authzid */ + authzid = clientin; + while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup; + + if (lup >= clientinlen) { + SETERROR(params->utils, "Can only find OTP authzid (no authid)"); + return SASL_BADPROT; + } + + /* get authid */ + ++lup; + authidp = clientin + lup; + while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup; + + authid_len = clientin + lup - authidp; + + if (lup != clientinlen) { + SETERROR(params->utils, + "Got more data than we were expecting in the OTP plugin\n"); + return SASL_BADPROT; + } + + text->authid = params->utils->malloc(authid_len + 1); + if (text->authid == NULL) { + MEMERROR(params->utils); + return SASL_NOMEM; + } + + /* we can't assume that authid is null-terminated */ + strncpy(text->authid, authidp, authid_len); + text->authid[authid_len] = '\0'; + + n = 0; + do { + /* Get user secret */ + result = params->utils->prop_request(params->propctx, + lookup_request); + if (result != SASL_OK) return result; + + /* this will trigger the getting of the aux properties. + Must use the fully qualified authid here */ + result = params->canon_user(params->utils->conn, text->authid, 0, + SASL_CU_AUTHID, oparams); + if (result != SASL_OK) return result; + + result = params->canon_user(params->utils->conn, + strlen(authzid) ? authzid : text->authid, + 0, SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) return result; + + result = params->utils->prop_getnames(params->propctx, + lookup_request, + auxprop_values); + if (result < 0 || + (!auxprop_values[0].name || !auxprop_values[0].values)) { + /* We didn't find this username */ + SETERROR(params->utils, "no OTP secret in database"); + result = params->transition ? SASL_TRANS : SASL_NOUSER; + return (result); + } + + if (auxprop_values[0].name && auxprop_values[0].values) { + result = parse_secret(params->utils, + (char*) auxprop_values[0].values[0], + auxprop_values[0].valsize, + mda, &text->seq, text->seed, text->otp, + &timeout); + + if (result != SASL_OK) return result; + } else { + SETERROR(params->utils, "don't have an OTP secret"); + return SASL_FAIL; + } + + text->timestamp = time(0); + } + /* + * check lock timeout + * + * we try 10 times in 1 second intervals in order to give the other + * auth attempt time to finish + */ + while ((text->timestamp < timeout) && (n++ < 10) && !sleep(1)); + + if (text->timestamp < timeout) { + SETERROR(params->utils, + "simultaneous OTP authentications not permitted"); + return SASL_TRYAGAIN; + } + + /* check sequence number */ + if (text->seq <= 1) { + SETERROR(params->utils, "OTP has expired (sequence <= 1)"); + return SASL_EXPIRED; + } + + /* find algorithm */ + text->alg = algorithm_options; + while (text->alg->name) { + if (!strcasecmp(text->alg->name, mda)) + break; + + text->alg++; + } + + if (!text->alg->name) { + params->utils->seterror(params->utils->conn, 0, + "unknown OTP algorithm '%s'", mda); + return SASL_FAIL; + } + + /* remake the secret with a timeout */ + result = make_secret(params->utils, text->alg->name, text->seq, + text->seed, text->otp, + text->timestamp + OTP_LOCK_TIMEOUT, &sec); + if (result != SASL_OK) { + SETERROR(params->utils, "error making OTP secret"); + return result; + } + + /* do the store */ + propctx = params->utils->prop_new(0); + if (!propctx) + result = SASL_FAIL; + if (result == SASL_OK) + result = params->utils->prop_request(propctx, store_request); + if (result == SASL_OK) + result = params->utils->prop_set(propctx, "cmusaslsecretOTP", + sec->data, sec->len); + if (result == SASL_OK) + result = params->utils->auxprop_store(params->utils->conn, + propctx, text->authid); + if (propctx) + params->utils->prop_dispose(&propctx); + + if (sec) params->utils->free(sec); + + if (result != SASL_OK) { + SETERROR(params->utils, "Error putting OTP secret"); + return result; + } + + text->locked = 1; + + result = _plug_buf_alloc(params->utils, &(text->out_buf), + &(text->out_buf_len), OTP_CHALLENGE_MAX+1); + if (result != SASL_OK) return result; + + /* create challenge */ + sprintf(text->out_buf, "otp-%s %u %s ext", + text->alg->name, text->seq-1, text->seed); + + *serverout = text->out_buf; + *serveroutlen = (unsigned) strlen(text->out_buf); + + text->state = 2; + + return SASL_CONTINUE; +} + +static int +otp_server_mech_step2(server_context_t *text, + sasl_server_params_t *params, + const char *clientin, + unsigned clientinlen, + const char **serverout __attribute__((unused)), + unsigned *serveroutlen __attribute__((unused)), + sasl_out_params_t *oparams) +{ + char response[OTP_RESPONSE_MAX+1]; + int result; + sasl_secret_t *sec = NULL; + struct propctx *propctx = NULL; + const char *store_request[] = { "cmusaslsecretOTP", + NULL }; + + if (clientinlen > OTP_RESPONSE_MAX) { + SETERROR(params->utils, "OTP response too long"); + return SASL_BADPROT; + } + + /* we can't assume that the response is null-terminated */ + strncpy(response, clientin, clientinlen); + response[clientinlen] = '\0'; + + /* check timeout */ + if (time(0) > text->timestamp + OTP_LOCK_TIMEOUT) { + SETERROR(params->utils, "OTP: server timed out"); + return SASL_UNAVAIL; + } + + /* verify response */ + result = verify_response(text, params->utils, response); + if (result != SASL_OK) return result; + + /* make the new secret */ + result = make_secret(params->utils, text->alg->name, text->seq, + text->seed, text->otp, 0, &sec); + if (result != SASL_OK) { + SETERROR(params->utils, "error making OTP secret"); + } + + /* do the store */ + propctx = params->utils->prop_new(0); + if (!propctx) + result = SASL_FAIL; + if (result == SASL_OK) + result = params->utils->prop_request(propctx, store_request); + if (result == SASL_OK) + result = params->utils->prop_set(propctx, "cmusaslsecretOTP", + sec->data, sec->len); + if (result == SASL_OK) + result = params->utils->auxprop_store(params->utils->conn, + propctx, text->authid); + if (propctx) + params->utils->prop_dispose(&propctx); + + if (result) { + SETERROR(params->utils, "Error putting OTP secret"); + } + + text->locked = 0; + + if (sec) _plug_free_secret(params->utils, &sec); + + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + return result; +} + +static int otp_server_mech_step(void *conn_context, + sasl_server_params_t *params, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + server_context_t *text = (server_context_t *) conn_context; + + *serverout = NULL; + *serveroutlen = 0; + + switch (text->state) { + + case 1: + return otp_server_mech_step1(text, params, clientin, clientinlen, + serverout, serveroutlen, oparams); + + case 2: + return otp_server_mech_step2(text, params, clientin, clientinlen, + serverout, serveroutlen, oparams); + + default: + params->utils->log(NULL, SASL_LOG_ERR, + "Invalid OTP server step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static void otp_server_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + server_context_t *text = (server_context_t *) conn_context; + sasl_secret_t *sec; + struct propctx *propctx = NULL; + const char *store_request[] = { "cmusaslsecretOTP", + NULL }; + int r; + + if (!text) return; + + /* if we created a challenge, but bailed before the verification of the + response, release the lock on the user key */ + if (text->locked && (time(0) < text->timestamp + OTP_LOCK_TIMEOUT)) { + r = make_secret(utils, text->alg->name, text->seq, + text->seed, text->otp, 0, &sec); + if (r != SASL_OK) { + SETERROR(utils, "error making OTP secret"); + if (sec) utils->free(sec); + sec = NULL; + } + + /* do the store */ + propctx = utils->prop_new(0); + if (!propctx) + r = SASL_FAIL; + if (!r) + r = utils->prop_request(propctx, store_request); + if (!r) + r = utils->prop_set(propctx, "cmusaslsecretOTP", + (sec ? sec->data : NULL), + (sec ? sec->len : 0)); + if (!r) + r = utils->auxprop_store(utils->conn, propctx, text->authid); + if (propctx) + utils->prop_dispose(&propctx); + + if (r) { + SETERROR(utils, "Error putting OTP secret"); + } + + if (sec) _plug_free_secret(utils, &sec); + } + + if (text->authid) _plug_free_string(utils, &(text->authid)); + if (text->realm) _plug_free_string(utils, &(text->realm)); + + if (text->out_buf) utils->free(text->out_buf); + + utils->free(text); +} + +static int otp_setpass(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *userstr, + const char *pass, + unsigned passlen __attribute__((unused)), + const char *oldpass __attribute__((unused)), + unsigned oldpasslen __attribute__((unused)), + unsigned flags) +{ + int r; + char *user = NULL; + char *user_only = NULL; + char *realm = NULL; + sasl_secret_t *sec; + struct propctx *propctx = NULL; + const char *store_request[] = { "cmusaslsecretOTP", + NULL }; + + /* Do we have a backend that can store properties? */ + if (!sparams->utils->auxprop_store || + sparams->utils->auxprop_store(NULL, NULL, NULL) != SASL_OK) { + SETERROR(sparams->utils, "OTP: auxprop backend can't store properties"); + return SASL_NOMECH; + } + + r = _plug_parseuser(sparams->utils, + &user_only, + &realm, + sparams->user_realm, + sparams->serverFQDN, + userstr); + if (r) { + SETERROR(sparams->utils, "OTP: Error parsing user"); + return r; + } + + r = _plug_make_fulluser(sparams->utils, &user, user_only, realm); + if (r) { + goto cleanup; + } + + if ((flags & SASL_SET_DISABLE) || pass == NULL) { + sec = NULL; + } else { + algorithm_option_t *algs; + const char *mda; + unsigned int len; + unsigned short randnum; + char seed[OTP_SEED_MAX+1]; + char otp[OTP_HASH_SIZE]; + + sparams->utils->getopt(sparams->utils->getopt_context, + "OTP", "otp_mda", &mda, &len); + if (!mda) mda = OTP_MDA_DEFAULT; + + algs = algorithm_options; + while (algs->name) { + if (!strcasecmp(algs->name, mda) || + !strcasecmp(algs->evp_name, mda)) + break; + + algs++; + } + + if (!algs->name) { + sparams->utils->seterror(sparams->utils->conn, 0, + "unknown OTP algorithm '%s'", mda); + r = SASL_FAIL; + goto cleanup; + } + + sparams->utils->rand(sparams->utils->rpool, + (char*) &randnum, sizeof(randnum)); + sprintf(seed, "%.2s%04u", sparams->serverFQDN, (randnum % 9999) + 1); + + r = generate_otp(sparams->utils, algs, OTP_SEQUENCE_DEFAULT, + seed, (char*) pass, otp); + if (r != SASL_OK) { + /* generate_otp() takes care of error message */ + goto cleanup; + } + + r = make_secret(sparams->utils, algs->name, OTP_SEQUENCE_DEFAULT, + seed, otp, 0, &sec); + if (r != SASL_OK) { + SETERROR(sparams->utils, "error making OTP secret"); + goto cleanup; + } + } + + /* do the store */ + propctx = sparams->utils->prop_new(0); + if (!propctx) + r = SASL_FAIL; + if (!r) + r = sparams->utils->prop_request(propctx, store_request); + if (!r) + r = sparams->utils->prop_set(propctx, "cmusaslsecretOTP", + (sec ? sec->data : NULL), + (sec ? sec->len : 0)); + if (!r) + r = sparams->utils->auxprop_store(sparams->utils->conn, propctx, user); + if (propctx) + sparams->utils->prop_dispose(&propctx); + + if (r) { + SETERROR(sparams->utils, "Error putting OTP secret"); + goto cleanup; + } + + sparams->utils->log(NULL, SASL_LOG_DEBUG, "Setpass for OTP successful\n"); + + cleanup: + + if (user) _plug_free_string(sparams->utils, &user); + if (user_only) _plug_free_string(sparams->utils, &user_only); + if (realm) _plug_free_string(sparams->utils, &realm); + if (sec) _plug_free_secret(sparams->utils, &sec); + + return r; +} + +static int otp_mech_avail(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + void **conn_context __attribute__((unused))) +{ + /* Do we have a backend that can store properties? */ + if (!sparams->utils->auxprop_store || + sparams->utils->auxprop_store(NULL, NULL, NULL) != SASL_OK) { + sparams->utils->log(NULL, + SASL_LOG_DEBUG, + "OTP: auxprop backend can't store properties"); + return SASL_NOMECH; + } + + return SASL_OK; +} + +static sasl_server_plug_t otp_server_plugins[] = +{ + { + "OTP", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS + | SASL_SEC_FORWARD_SECRECY, /* security_flags */ + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY, /* features */ + NULL, /* glob_context */ + &otp_server_mech_new, /* mech_new */ + &otp_server_mech_step, /* mech_step */ + &otp_server_mech_dispose, /* mech_dispose */ + &otp_common_mech_free, /* mech_free */ + &otp_setpass, /* setpass */ + NULL, /* user_query */ + NULL, /* idle */ + &otp_mech_avail, /* mech avail */ + NULL /* spare */ + } +}; +#endif /* HAVE_OPIE */ + +int otp_server_plug_init(const sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_SERVER_PLUG_VERSION) { + SETERROR(utils, "OTP version mismatch"); + return SASL_BADVERS; + } + + *out_version = SASL_SERVER_PLUG_VERSION; + *pluglist = otp_server_plugins; + *plugcount = 1; + + /* Add all digests */ + OpenSSL_add_all_digests(); + + return SASL_OK; +} + +/***************************** Client Section *****************************/ + +typedef struct client_context { + int state; + + sasl_secret_t *password; + unsigned int free_password; /* set if we need to free password */ + + const char *otpassword; + + char *out_buf; + unsigned out_buf_len; + + char challenge[OTP_CHALLENGE_MAX+1]; +} client_context_t; + +static int otp_client_mech_new(void *glob_context __attribute__((unused)), + sasl_client_params_t *params, + void **conn_context) +{ + client_context_t *text; + + /* holds state are in */ + text = params->utils->malloc(sizeof(client_context_t)); + if (text == NULL) { + MEMERROR( params->utils ); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(client_context_t)); + + text->state = 1; + + *conn_context = text; + + return SASL_OK; +} + +static int otp_client_mech_step1(client_context_t *text, + sasl_client_params_t *params, + const char *serverin __attribute__((unused)), + unsigned serverinlen __attribute__((unused)), + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + const char *user = NULL, *authid = NULL; + int user_result = SASL_OK; + int auth_result = SASL_OK; + int pass_result = SASL_OK; + sasl_chalprompt_t *echo_cb; + void *echo_context; + int result; + + /* check if sec layer strong enough */ + if (params->props.min_ssf > params->external_ssf) { + SETERROR( params->utils, "SSF requested of OTP plugin"); + return SASL_TOOWEAK; + } + + /* try to get the authid */ + if (oparams->authid == NULL) { + auth_result = _plug_get_authid(params->utils, &authid, prompt_need); + + if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT)) + return auth_result; + } + + /* try to get the userid */ + if (oparams->user == NULL) { + user_result = _plug_get_userid(params->utils, &user, prompt_need); + + if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) + return user_result; + } + + /* try to get the secret pass-phrase if we don't have a chalprompt */ + if ((params->utils->getcallback(params->utils->conn, SASL_CB_ECHOPROMPT, + (sasl_callback_ft *)&echo_cb, &echo_context) == SASL_FAIL) && + (text->password == NULL)) { + pass_result = _plug_get_password(params->utils, &text->password, + &text->free_password, prompt_need); + + if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT)) + return pass_result; + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + params->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if ((user_result == SASL_INTERACT) || (auth_result == SASL_INTERACT) || + (pass_result == SASL_INTERACT)) { + /* make the prompt list */ + result = + _plug_make_prompts(params->utils, prompt_need, + user_result == SASL_INTERACT ? + "Please enter your authorization name" : NULL, + NULL, + auth_result == SASL_INTERACT ? + "Please enter your authentication name" : NULL, + NULL, + pass_result == SASL_INTERACT ? + "Please enter your secret pass-phrase" : NULL, + NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); + if (result != SASL_OK) return result; + + return SASL_INTERACT; + } + + if (!user || !*user) { + result = params->canon_user(params->utils->conn, authid, 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + } + else { + result = params->canon_user(params->utils->conn, user, 0, + SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) return result; + + result = params->canon_user(params->utils->conn, authid, 0, + SASL_CU_AUTHID, oparams); + } + if (result != SASL_OK) return result; + + /* send authorized id NUL authentication id */ + *clientoutlen = oparams->ulen + 1 + oparams->alen; + + /* remember the extra NUL on the end for stupid clients */ + result = _plug_buf_alloc(params->utils, &(text->out_buf), + &(text->out_buf_len), *clientoutlen + 1); + if (result != SASL_OK) return result; + + memset(text->out_buf, 0, *clientoutlen + 1); + memcpy(text->out_buf, oparams->user, oparams->ulen); + memcpy(text->out_buf+oparams->ulen+1, oparams->authid, oparams->alen); + *clientout = text->out_buf; + + text->state = 2; + + return SASL_CONTINUE; +} + +static int otp_client_mech_step2(client_context_t *text, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + int echo_result = SASL_OK; + int result; + + if (serverinlen > OTP_CHALLENGE_MAX) { + SETERROR(params->utils, "OTP challenge too long"); + return SASL_BADPROT; + } + + /* we can't assume that challenge is null-terminated */ + strncpy(text->challenge, serverin, serverinlen); + text->challenge[serverinlen] = '\0'; + + /* try to get the one-time password if we don't have the secret */ + if ((text->password == NULL) && (text->otpassword == NULL)) { + echo_result = _plug_challenge_prompt(params->utils, + SASL_CB_ECHOPROMPT, + text->challenge, + "Please enter your one-time password", + &text->otpassword, + prompt_need); + + if ((echo_result != SASL_OK) && (echo_result != SASL_INTERACT)) + return echo_result; + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + params->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if (echo_result == SASL_INTERACT) { + /* make the prompt list */ + result = + _plug_make_prompts(params->utils, + prompt_need, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + text->challenge, + "Please enter your one-time password", + NULL, + NULL, + NULL, + NULL); + if (result != SASL_OK) return result; + + return SASL_INTERACT; + } + + /* the application provided us with a one-time password so use it */ + if (text->otpassword) { + *clientout = text->otpassword; + *clientoutlen = (unsigned) strlen(text->otpassword); + } + /* generate our own response using the user's secret pass-phrase */ + else { + algorithm_option_t *alg; + unsigned seq; + char seed[OTP_SEED_MAX+1]; + char otp[OTP_HASH_SIZE]; + int init_done = 0; + + /* parse challenge */ + result = parse_challenge(params->utils, + text->challenge, + &alg, + &seq, + seed, + 0); + if (result != SASL_OK) return result; + + if (!text->password) { + PARAMERROR(params->utils); + return SASL_BADPARAM; + } + + if (seq < 1) { + SETERROR(params->utils, "OTP has expired (sequence < 1)"); + return SASL_EXPIRED; + } + + /* generate otp */ + result = generate_otp(params->utils, alg, seq, seed, + text->password->data, otp); + if (result != SASL_OK) return result; + + result = _plug_buf_alloc(params->utils, &(text->out_buf), + &(text->out_buf_len), OTP_RESPONSE_MAX+1); + if (result != SASL_OK) return result; + + if (seq < OTP_SEQUENCE_REINIT) { + unsigned short randnum; + char new_seed[OTP_SEED_MAX+1]; + char new_otp[OTP_HASH_SIZE]; + + /* try to reinitialize */ + + /* make sure we have a different seed */ + do { + params->utils->rand(params->utils->rpool, + (char*) &randnum, sizeof(randnum)); + sprintf(new_seed, "%.2s%04u", params->serverFQDN, + (randnum % 9999) + 1); + } while (!strcasecmp(seed, new_seed)); + + result = generate_otp(params->utils, alg, OTP_SEQUENCE_DEFAULT, + new_seed, text->password->data, new_otp); + + if (result == SASL_OK) { + /* create an init-hex response */ + strcpy(text->out_buf, OTP_INIT_HEX_TYPE); + bin2hex(otp, OTP_HASH_SIZE, + text->out_buf+strlen(text->out_buf)); + sprintf(text->out_buf+strlen(text->out_buf), ":%s %u %s:", + alg->name, OTP_SEQUENCE_DEFAULT, new_seed); + bin2hex(new_otp, OTP_HASH_SIZE, + text->out_buf+strlen(text->out_buf)); + init_done = 1; + } + else { + /* just do a regular response */ + } + } + + if (!init_done) { + /* created hex response */ + strcpy(text->out_buf, OTP_HEX_TYPE); + bin2hex(otp, OTP_HASH_SIZE, text->out_buf+strlen(text->out_buf)); + } + + *clientout = text->out_buf; + *clientoutlen = (unsigned) strlen(text->out_buf); + } + + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + return SASL_OK; +} + +static int otp_client_mech_step(void *conn_context, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + client_context_t *text = (client_context_t *) conn_context; + + *clientout = NULL; + *clientoutlen = 0; + + switch (text->state) { + + case 1: + return otp_client_mech_step1(text, params, serverin, serverinlen, + prompt_need, clientout, clientoutlen, + oparams); + + case 2: + return otp_client_mech_step2(text, params, serverin, serverinlen, + prompt_need, clientout, clientoutlen, + oparams); + + default: + params->utils->log(NULL, SASL_LOG_ERR, + "Invalid OTP client step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static void otp_client_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + client_context_t *text = (client_context_t *) conn_context; + + if (!text) return; + + if (text->free_password) _plug_free_secret(utils, &(text->password)); + + if (text->out_buf) utils->free(text->out_buf); + + utils->free(text); +} + +static sasl_client_plug_t otp_client_plugins[] = +{ + { + "OTP", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS + | SASL_SEC_FORWARD_SECRECY, /* security_flags */ + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY, /* features */ + NULL, /* required_prompts */ + NULL, /* glob_context */ + &otp_client_mech_new, /* mech_new */ + &otp_client_mech_step, /* mech_step */ + &otp_client_mech_dispose, /* mech_dispose */ + &otp_common_mech_free, /* mech_free */ + NULL, /* idle */ + NULL, /* spare */ + NULL /* spare */ + } +}; + +int otp_client_plug_init(sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_CLIENT_PLUG_VERSION) { + SETERROR(utils, "OTP version mismatch"); + return SASL_BADVERS; + } + + *out_version = SASL_CLIENT_PLUG_VERSION; + *pluglist = otp_client_plugins; + *plugcount = 1; + + /* Add all digests */ + OpenSSL_add_all_digests(); + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/otp.h b/libs/cyrussasl/plugins/otp.h new file mode 100644 index 00000000..722aca23 --- /dev/null +++ b/libs/cyrussasl/plugins/otp.h @@ -0,0 +1,311 @@ +/* OTP SASL plugin + * Ken Murchison + * $Id: otp.h,v 1.2 2003/02/13 19:56:04 rjs3 Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _OTP_H_ +#define _OTP_H_ + +/* Standard dictionary from RFC2289 */ +#define OTP_STD_DICT_SIZE 2048 +#define OTP_4LETTER_OFFSET 571 + +static const char *otp_std_dict[OTP_STD_DICT_SIZE] = +{ "A", "ABE", "ACE", "ACT", "AD", "ADA", "ADD", +"AGO", "AID", "AIM", "AIR", "ALL", "ALP", "AM", "AMY", +"AN", "ANA", "AND", "ANN", "ANT", "ANY", "APE", "APS", +"APT", "ARC", "ARE", "ARK", "ARM", "ART", "AS", "ASH", +"ASK", "AT", "ATE", "AUG", "AUK", "AVE", "AWE", "AWK", +"AWL", "AWN", "AX", "AYE", "BAD", "BAG", "BAH", "BAM", +"BAN", "BAR", "BAT", "BAY", "BE", "BED", "BEE", "BEG", +"BEN", "BET", "BEY", "BIB", "BID", "BIG", "BIN", "BIT", +"BOB", "BOG", "BON", "BOO", "BOP", "BOW", "BOY", "BUB", +"BUD", "BUG", "BUM", "BUN", "BUS", "BUT", "BUY", "BY", +"BYE", "CAB", "CAL", "CAM", "CAN", "CAP", "CAR", "CAT", +"CAW", "COD", "COG", "COL", "CON", "COO", "COP", "COT", +"COW", "COY", "CRY", "CUB", "CUE", "CUP", "CUR", "CUT", +"DAB", "DAD", "DAM", "DAN", "DAR", "DAY", "DEE", "DEL", +"DEN", "DES", "DEW", "DID", "DIE", "DIG", "DIN", "DIP", +"DO", "DOE", "DOG", "DON", "DOT", "DOW", "DRY", "DUB", +"DUD", "DUE", "DUG", "DUN", "EAR", "EAT", "ED", "EEL", +"EGG", "EGO", "ELI", "ELK", "ELM", "ELY", "EM", "END", +"EST", "ETC", "EVA", "EVE", "EWE", "EYE", "FAD", "FAN", +"FAR", "FAT", "FAY", "FED", "FEE", "FEW", "FIB", "FIG", +"FIN", "FIR", "FIT", "FLO", "FLY", "FOE", "FOG", "FOR", +"FRY", "FUM", "FUN", "FUR", "GAB", "GAD", "GAG", "GAL", +"GAM", "GAP", "GAS", "GAY", "GEE", "GEL", "GEM", "GET", +"GIG", "GIL", "GIN", "GO", "GOT", "GUM", "GUN", "GUS", +"GUT", "GUY", "GYM", "GYP", "HA", "HAD", "HAL", "HAM", +"HAN", "HAP", "HAS", "HAT", "HAW", "HAY", "HE", "HEM", +"HEN", "HER", "HEW", "HEY", "HI", "HID", "HIM", "HIP", +"HIS", "HIT", "HO", "HOB", "HOC", "HOE", "HOG", "HOP", +"HOT", "HOW", "HUB", "HUE", "HUG", "HUH", "HUM", "HUT", +"I", "ICY", "IDA", "IF", "IKE", "ILL", "INK", "INN", +"IO", "ION", "IQ", "IRA", "IRE", "IRK", "IS", "IT", +"ITS", "IVY", "JAB", "JAG", "JAM", "JAN", "JAR", "JAW", +"JAY", "JET", "JIG", "JIM", "JO", "JOB", "JOE", "JOG", +"JOT", "JOY", "JUG", "JUT", "KAY", "KEG", "KEN", "KEY", +"KID", "KIM", "KIN", "KIT", "LA", "LAB", "LAC", "LAD", +"LAG", "LAM", "LAP", "LAW", "LAY", "LEA", "LED", "LEE", +"LEG", "LEN", "LEO", "LET", "LEW", "LID", "LIE", "LIN", +"LIP", "LIT", "LO", "LOB", "LOG", "LOP", "LOS", "LOT", +"LOU", "LOW", "LOY", "LUG", "LYE", "MA", "MAC", "MAD", +"MAE", "MAN", "MAO", "MAP", "MAT", "MAW", "MAY", "ME", +"MEG", "MEL", "MEN", "MET", "MEW", "MID", "MIN", "MIT", +"MOB", "MOD", "MOE", "MOO", "MOP", "MOS", "MOT", "MOW", +"MUD", "MUG", "MUM", "MY", "NAB", "NAG", "NAN", "NAP", +"NAT", "NAY", "NE", "NED", "NEE", "NET", "NEW", "NIB", +"NIL", "NIP", "NIT", "NO", "NOB", "NOD", "NON", "NOR", +"NOT", "NOV", "NOW", "NU", "NUN", "NUT", "O", "OAF", +"OAK", "OAR", "OAT", "ODD", "ODE", "OF", "OFF", "OFT", +"OH", "OIL", "OK", "OLD", "ON", "ONE", "OR", "ORB", +"ORE", "ORR", "OS", "OTT", "OUR", "OUT", "OVA", "OW", +"OWE", "OWL", "OWN", "OX", "PA", "PAD", "PAL", "PAM", +"PAN", "PAP", "PAR", "PAT", "PAW", "PAY", "PEA", "PEG", +"PEN", "PEP", "PER", "PET", "PEW", "PHI", "PI", "PIE", +"PIN", "PIT", "PLY", "PO", "POD", "POE", "POP", "POT", +"POW", "PRO", "PRY", "PUB", "PUG", "PUN", "PUP", "PUT", +"QUO", "RAG", "RAM", "RAN", "RAP", "RAT", "RAW", "RAY", +"REB", "RED", "REP", "RET", "RIB", "RID", "RIG", "RIM", +"RIO", "RIP", "ROB", "ROD", "ROE", "RON", "ROT", "ROW", +"ROY", "RUB", "RUE", "RUG", "RUM", "RUN", "RYE", "SAC", +"SAD", "SAG", "SAL", "SAM", "SAN", "SAP", "SAT", "SAW", +"SAY", "SEA", "SEC", "SEE", "SEN", "SET", "SEW", "SHE", +"SHY", "SIN", "SIP", "SIR", "SIS", "SIT", "SKI", "SKY", +"SLY", "SO", "SOB", "SOD", "SON", "SOP", "SOW", "SOY", +"SPA", "SPY", "SUB", "SUD", "SUE", "SUM", "SUN", "SUP", +"TAB", "TAD", "TAG", "TAN", "TAP", "TAR", "TEA", "TED", +"TEE", "TEN", "THE", "THY", "TIC", "TIE", "TIM", "TIN", +"TIP", "TO", "TOE", "TOG", "TOM", "TON", "TOO", "TOP", +"TOW", "TOY", "TRY", "TUB", "TUG", "TUM", "TUN", "TWO", +"UN", "UP", "US", "USE", "VAN", "VAT", "VET", "VIE", +"WAD", "WAG", "WAR", "WAS", "WAY", "WE", "WEB", "WED", +"WEE", "WET", "WHO", "WHY", "WIN", "WIT", "WOK", "WON", +"WOO", "WOW", "WRY", "WU", "YAM", "YAP", "YAW", "YE", +"YEA", "YES", "YET", "YOU", "ABED", "ABEL", "ABET", "ABLE", +"ABUT", "ACHE", "ACID", "ACME", "ACRE", "ACTA", "ACTS", "ADAM", +"ADDS", "ADEN", "AFAR", "AFRO", "AGEE", "AHEM", "AHOY", "AIDA", +"AIDE", "AIDS", "AIRY", "AJAR", "AKIN", "ALAN", "ALEC", "ALGA", +"ALIA", "ALLY", "ALMA", "ALOE", "ALSO", "ALTO", "ALUM", "ALVA", +"AMEN", "AMES", "AMID", "AMMO", "AMOK", "AMOS", "AMRA", "ANDY", +"ANEW", "ANNA", "ANNE", "ANTE", "ANTI", "AQUA", "ARAB", "ARCH", +"AREA", "ARGO", "ARID", "ARMY", "ARTS", "ARTY", "ASIA", "ASKS", +"ATOM", "AUNT", "AURA", "AUTO", "AVER", "AVID", "AVIS", "AVON", +"AVOW", "AWAY", "AWRY", "BABE", "BABY", "BACH", "BACK", "BADE", +"BAIL", "BAIT", "BAKE", "BALD", "BALE", "BALI", "BALK", "BALL", +"BALM", "BAND", "BANE", "BANG", "BANK", "BARB", "BARD", "BARE", +"BARK", "BARN", "BARR", "BASE", "BASH", "BASK", "BASS", "BATE", +"BATH", "BAWD", "BAWL", "BEAD", "BEAK", "BEAM", "BEAN", "BEAR", +"BEAT", "BEAU", "BECK", "BEEF", "BEEN", "BEER", "BEET", "BELA", +"BELL", "BELT", "BEND", "BENT", "BERG", "BERN", "BERT", "BESS", +"BEST", "BETA", "BETH", "BHOY", "BIAS", "BIDE", "BIEN", "BILE", +"BILK", "BILL", "BIND", "BING", "BIRD", "BITE", "BITS", "BLAB", +"BLAT", "BLED", "BLEW", "BLOB", "BLOC", "BLOT", "BLOW", "BLUE", +"BLUM", "BLUR", "BOAR", "BOAT", "BOCA", "BOCK", "BODE", "BODY", +"BOGY", "BOHR", "BOIL", "BOLD", "BOLO", "BOLT", "BOMB", "BONA", +"BOND", "BONE", "BONG", "BONN", "BONY", "BOOK", "BOOM", "BOON", +"BOOT", "BORE", "BORG", "BORN", "BOSE", "BOSS", "BOTH", "BOUT", +"BOWL", "BOYD", "BRAD", "BRAE", "BRAG", "BRAN", "BRAY", "BRED", +"BREW", "BRIG", "BRIM", "BROW", "BUCK", "BUDD", "BUFF", "BULB", +"BULK", "BULL", "BUNK", "BUNT", "BUOY", "BURG", "BURL", "BURN", +"BURR", "BURT", "BURY", "BUSH", "BUSS", "BUST", "BUSY", "BYTE", +"CADY", "CAFE", "CAGE", "CAIN", "CAKE", "CALF", "CALL", "CALM", +"CAME", "CANE", "CANT", "CARD", "CARE", "CARL", "CARR", "CART", +"CASE", "CASH", "CASK", "CAST", "CAVE", "CEIL", "CELL", "CENT", +"CERN", "CHAD", "CHAR", "CHAT", "CHAW", "CHEF", "CHEN", "CHEW", +"CHIC", "CHIN", "CHOU", "CHOW", "CHUB", "CHUG", "CHUM", "CITE", +"CITY", "CLAD", "CLAM", "CLAN", "CLAW", "CLAY", "CLOD", "CLOG", +"CLOT", "CLUB", "CLUE", "COAL", "COAT", "COCA", "COCK", "COCO", +"CODA", "CODE", "CODY", "COED", "COIL", "COIN", "COKE", "COLA", +"COLD", "COLT", "COMA", "COMB", "COME", "COOK", "COOL", "COON", +"COOT", "CORD", "CORE", "CORK", "CORN", "COST", "COVE", "COWL", +"CRAB", "CRAG", "CRAM", "CRAY", "CREW", "CRIB", "CROW", "CRUD", +"CUBA", "CUBE", "CUFF", "CULL", "CULT", "CUNY", "CURB", "CURD", +"CURE", "CURL", "CURT", "CUTS", "DADE", "DALE", "DAME", "DANA", +"DANE", "DANG", "DANK", "DARE", "DARK", "DARN", "DART", "DASH", +"DATA", "DATE", "DAVE", "DAVY", "DAWN", "DAYS", "DEAD", "DEAF", +"DEAL", "DEAN", "DEAR", "DEBT", "DECK", "DEED", "DEEM", "DEER", +"DEFT", "DEFY", "DELL", "DENT", "DENY", "DESK", "DIAL", "DICE", +"DIED", "DIET", "DIME", "DINE", "DING", "DINT", "DIRE", "DIRT", +"DISC", "DISH", "DISK", "DIVE", "DOCK", "DOES", "DOLE", "DOLL", +"DOLT", "DOME", "DONE", "DOOM", "DOOR", "DORA", "DOSE", "DOTE", +"DOUG", "DOUR", "DOVE", "DOWN", "DRAB", "DRAG", "DRAM", "DRAW", +"DREW", "DRUB", "DRUG", "DRUM", "DUAL", "DUCK", "DUCT", "DUEL", +"DUET", "DUKE", "DULL", "DUMB", "DUNE", "DUNK", "DUSK", "DUST", +"DUTY", "EACH", "EARL", "EARN", "EASE", "EAST", "EASY", "EBEN", +"ECHO", "EDDY", "EDEN", "EDGE", "EDGY", "EDIT", "EDNA", "EGAN", +"ELAN", "ELBA", "ELLA", "ELSE", "EMIL", "EMIT", "EMMA", "ENDS", +"ERIC", "EROS", "EVEN", "EVER", "EVIL", "EYED", "FACE", "FACT", +"FADE", "FAIL", "FAIN", "FAIR", "FAKE", "FALL", "FAME", "FANG", +"FARM", "FAST", "FATE", "FAWN", "FEAR", "FEAT", "FEED", "FEEL", +"FEET", "FELL", "FELT", "FEND", "FERN", "FEST", "FEUD", "FIEF", +"FIGS", "FILE", "FILL", "FILM", "FIND", "FINE", "FINK", "FIRE", +"FIRM", "FISH", "FISK", "FIST", "FITS", "FIVE", "FLAG", "FLAK", +"FLAM", "FLAT", "FLAW", "FLEA", "FLED", "FLEW", "FLIT", "FLOC", +"FLOG", "FLOW", "FLUB", "FLUE", "FOAL", "FOAM", "FOGY", "FOIL", +"FOLD", "FOLK", "FOND", "FONT", "FOOD", "FOOL", "FOOT", "FORD", +"FORE", "FORK", "FORM", "FORT", "FOSS", "FOUL", "FOUR", "FOWL", +"FRAU", "FRAY", "FRED", "FREE", "FRET", "FREY", "FROG", "FROM", +"FUEL", "FULL", "FUME", "FUND", "FUNK", "FURY", "FUSE", "FUSS", +"GAFF", "GAGE", "GAIL", "GAIN", "GAIT", "GALA", "GALE", "GALL", +"GALT", "GAME", "GANG", "GARB", "GARY", "GASH", "GATE", "GAUL", +"GAUR", "GAVE", "GAWK", "GEAR", "GELD", "GENE", "GENT", "GERM", +"GETS", "GIBE", "GIFT", "GILD", "GILL", "GILT", "GINA", "GIRD", +"GIRL", "GIST", "GIVE", "GLAD", "GLEE", "GLEN", "GLIB", "GLOB", +"GLOM", "GLOW", "GLUE", "GLUM", "GLUT", "GOAD", "GOAL", "GOAT", +"GOER", "GOES", "GOLD", "GOLF", "GONE", "GONG", "GOOD", "GOOF", +"GORE", "GORY", "GOSH", "GOUT", "GOWN", "GRAB", "GRAD", "GRAY", +"GREG", "GREW", "GREY", "GRID", "GRIM", "GRIN", "GRIT", "GROW", +"GRUB", "GULF", "GULL", "GUNK", "GURU", "GUSH", "GUST", "GWEN", +"GWYN", "HAAG", "HAAS", "HACK", "HAIL", "HAIR", "HALE", "HALF", +"HALL", "HALO", "HALT", "HAND", "HANG", "HANK", "HANS", "HARD", +"HARK", "HARM", "HART", "HASH", "HAST", "HATE", "HATH", "HAUL", +"HAVE", "HAWK", "HAYS", "HEAD", "HEAL", "HEAR", "HEAT", "HEBE", +"HECK", "HEED", "HEEL", "HEFT", "HELD", "HELL", "HELM", "HERB", +"HERD", "HERE", "HERO", "HERS", "HESS", "HEWN", "HICK", "HIDE", +"HIGH", "HIKE", "HILL", "HILT", "HIND", "HINT", "HIRE", "HISS", +"HIVE", "HOBO", "HOCK", "HOFF", "HOLD", "HOLE", "HOLM", "HOLT", +"HOME", "HONE", "HONK", "HOOD", "HOOF", "HOOK", "HOOT", "HORN", +"HOSE", "HOST", "HOUR", "HOVE", "HOWE", "HOWL", "HOYT", "HUCK", +"HUED", "HUFF", "HUGE", "HUGH", "HUGO", "HULK", "HULL", "HUNK", +"HUNT", "HURD", "HURL", "HURT", "HUSH", "HYDE", "HYMN", "IBIS", +"ICON", "IDEA", "IDLE", "IFFY", "INCA", "INCH", "INTO", "IONS", +"IOTA", "IOWA", "IRIS", "IRMA", "IRON", "ISLE", "ITCH", "ITEM", +"IVAN", "JACK", "JADE", "JAIL", "JAKE", "JANE", "JAVA", "JEAN", +"JEFF", "JERK", "JESS", "JEST", "JIBE", "JILL", "JILT", "JIVE", +"JOAN", "JOBS", "JOCK", "JOEL", "JOEY", "JOHN", "JOIN", "JOKE", +"JOLT", "JOVE", "JUDD", "JUDE", "JUDO", "JUDY", "JUJU", "JUKE", +"JULY", "JUNE", "JUNK", "JUNO", "JURY", "JUST", "JUTE", "KAHN", +"KALE", "KANE", "KANT", "KARL", "KATE", "KEEL", "KEEN", "KENO", +"KENT", "KERN", "KERR", "KEYS", "KICK", "KILL", "KIND", "KING", +"KIRK", "KISS", "KITE", "KLAN", "KNEE", "KNEW", "KNIT", "KNOB", +"KNOT", "KNOW", "KOCH", "KONG", "KUDO", "KURD", "KURT", "KYLE", +"LACE", "LACK", "LACY", "LADY", "LAID", "LAIN", "LAIR", "LAKE", +"LAMB", "LAME", "LAND", "LANE", "LANG", "LARD", "LARK", "LASS", +"LAST", "LATE", "LAUD", "LAVA", "LAWN", "LAWS", "LAYS", "LEAD", +"LEAF", "LEAK", "LEAN", "LEAR", "LEEK", "LEER", "LEFT", "LEND", +"LENS", "LENT", "LEON", "LESK", "LESS", "LEST", "LETS", "LIAR", +"LICE", "LICK", "LIED", "LIEN", "LIES", "LIEU", "LIFE", "LIFT", +"LIKE", "LILA", "LILT", "LILY", "LIMA", "LIMB", "LIME", "LIND", +"LINE", "LINK", "LINT", "LION", "LISA", "LIST", "LIVE", "LOAD", +"LOAF", "LOAM", "LOAN", "LOCK", "LOFT", "LOGE", "LOIS", "LOLA", +"LONE", "LONG", "LOOK", "LOON", "LOOT", "LORD", "LORE", "LOSE", +"LOSS", "LOST", "LOUD", "LOVE", "LOWE", "LUCK", "LUCY", "LUGE", +"LUKE", "LULU", "LUND", "LUNG", "LURA", "LURE", "LURK", "LUSH", +"LUST", "LYLE", "LYNN", "LYON", "LYRA", "MACE", "MADE", "MAGI", +"MAID", "MAIL", "MAIN", "MAKE", "MALE", "MALI", "MALL", "MALT", +"MANA", "MANN", "MANY", "MARC", "MARE", "MARK", "MARS", "MART", +"MARY", "MASH", "MASK", "MASS", "MAST", "MATE", "MATH", "MAUL", +"MAYO", "MEAD", "MEAL", "MEAN", "MEAT", "MEEK", "MEET", "MELD", +"MELT", "MEMO", "MEND", "MENU", "MERT", "MESH", "MESS", "MICE", +"MIKE", "MILD", "MILE", "MILK", "MILL", "MILT", "MIMI", "MIND", +"MINE", "MINI", "MINK", "MINT", "MIRE", "MISS", "MIST", "MITE", +"MITT", "MOAN", "MOAT", "MOCK", "MODE", "MOLD", "MOLE", "MOLL", +"MOLT", "MONA", "MONK", "MONT", "MOOD", "MOON", "MOOR", "MOOT", +"MORE", "MORN", "MORT", "MOSS", "MOST", "MOTH", "MOVE", "MUCH", +"MUCK", "MUDD", "MUFF", "MULE", "MULL", "MURK", "MUSH", "MUST", +"MUTE", "MUTT", "MYRA", "MYTH", "NAGY", "NAIL", "NAIR", "NAME", +"NARY", "NASH", "NAVE", "NAVY", "NEAL", "NEAR", "NEAT", "NECK", +"NEED", "NEIL", "NELL", "NEON", "NERO", "NESS", "NEST", "NEWS", +"NEWT", "NIBS", "NICE", "NICK", "NILE", "NINA", "NINE", "NOAH", +"NODE", "NOEL", "NOLL", "NONE", "NOOK", "NOON", "NORM", "NOSE", +"NOTE", "NOUN", "NOVA", "NUDE", "NULL", "NUMB", "OATH", "OBEY", +"OBOE", "ODIN", "OHIO", "OILY", "OINT", "OKAY", "OLAF", "OLDY", +"OLGA", "OLIN", "OMAN", "OMEN", "OMIT", "ONCE", "ONES", "ONLY", +"ONTO", "ONUS", "ORAL", "ORGY", "OSLO", "OTIS", "OTTO", "OUCH", +"OUST", "OUTS", "OVAL", "OVEN", "OVER", "OWLY", "OWNS", "QUAD", +"QUIT", "QUOD", "RACE", "RACK", "RACY", "RAFT", "RAGE", "RAID", +"RAIL", "RAIN", "RAKE", "RANK", "RANT", "RARE", "RASH", "RATE", +"RAVE", "RAYS", "READ", "REAL", "REAM", "REAR", "RECK", "REED", +"REEF", "REEK", "REEL", "REID", "REIN", "RENA", "REND", "RENT", +"REST", "RICE", "RICH", "RICK", "RIDE", "RIFT", "RILL", "RIME", +"RING", "RINK", "RISE", "RISK", "RITE", "ROAD", "ROAM", "ROAR", +"ROBE", "ROCK", "RODE", "ROIL", "ROLL", "ROME", "ROOD", "ROOF", +"ROOK", "ROOM", "ROOT", "ROSA", "ROSE", "ROSS", "ROSY", "ROTH", +"ROUT", "ROVE", "ROWE", "ROWS", "RUBE", "RUBY", "RUDE", "RUDY", +"RUIN", "RULE", "RUNG", "RUNS", "RUNT", "RUSE", "RUSH", "RUSK", +"RUSS", "RUST", "RUTH", "SACK", "SAFE", "SAGE", "SAID", "SAIL", +"SALE", "SALK", "SALT", "SAME", "SAND", "SANE", "SANG", "SANK", +"SARA", "SAUL", "SAVE", "SAYS", "SCAN", "SCAR", "SCAT", "SCOT", +"SEAL", "SEAM", "SEAR", "SEAT", "SEED", "SEEK", "SEEM", "SEEN", +"SEES", "SELF", "SELL", "SEND", "SENT", "SETS", "SEWN", "SHAG", +"SHAM", "SHAW", "SHAY", "SHED", "SHIM", "SHIN", "SHOD", "SHOE", +"SHOT", "SHOW", "SHUN", "SHUT", "SICK", "SIDE", "SIFT", "SIGH", +"SIGN", "SILK", "SILL", "SILO", "SILT", "SINE", "SING", "SINK", +"SIRE", "SITE", "SITS", "SITU", "SKAT", "SKEW", "SKID", "SKIM", +"SKIN", "SKIT", "SLAB", "SLAM", "SLAT", "SLAY", "SLED", "SLEW", +"SLID", "SLIM", "SLIT", "SLOB", "SLOG", "SLOT", "SLOW", "SLUG", +"SLUM", "SLUR", "SMOG", "SMUG", "SNAG", "SNOB", "SNOW", "SNUB", +"SNUG", "SOAK", "SOAR", "SOCK", "SODA", "SOFA", "SOFT", "SOIL", +"SOLD", "SOME", "SONG", "SOON", "SOOT", "SORE", "SORT", "SOUL", +"SOUR", "SOWN", "STAB", "STAG", "STAN", "STAR", "STAY", "STEM", +"STEW", "STIR", "STOW", "STUB", "STUN", "SUCH", "SUDS", "SUIT", +"SULK", "SUMS", "SUNG", "SUNK", "SURE", "SURF", "SWAB", "SWAG", +"SWAM", "SWAN", "SWAT", "SWAY", "SWIM", "SWUM", "TACK", "TACT", +"TAIL", "TAKE", "TALE", "TALK", "TALL", "TANK", "TASK", "TATE", +"TAUT", "TEAL", "TEAM", "TEAR", "TECH", "TEEM", "TEEN", "TEET", +"TELL", "TEND", "TENT", "TERM", "TERN", "TESS", "TEST", "THAN", +"THAT", "THEE", "THEM", "THEN", "THEY", "THIN", "THIS", "THUD", +"THUG", "TICK", "TIDE", "TIDY", "TIED", "TIER", "TILE", "TILL", +"TILT", "TIME", "TINA", "TINE", "TINT", "TINY", "TIRE", "TOAD", +"TOGO", "TOIL", "TOLD", "TOLL", "TONE", "TONG", "TONY", "TOOK", +"TOOL", "TOOT", "TORE", "TORN", "TOTE", "TOUR", "TOUT", "TOWN", +"TRAG", "TRAM", "TRAY", "TREE", "TREK", "TRIG", "TRIM", "TRIO", +"TROD", "TROT", "TROY", "TRUE", "TUBA", "TUBE", "TUCK", "TUFT", +"TUNA", "TUNE", "TUNG", "TURF", "TURN", "TUSK", "TWIG", "TWIN", +"TWIT", "ULAN", "UNIT", "URGE", "USED", "USER", "USES", "UTAH", +"VAIL", "VAIN", "VALE", "VARY", "VASE", "VAST", "VEAL", "VEDA", +"VEIL", "VEIN", "VEND", "VENT", "VERB", "VERY", "VETO", "VICE", +"VIEW", "VINE", "VISE", "VOID", "VOLT", "VOTE", "WACK", "WADE", +"WAGE", "WAIL", "WAIT", "WAKE", "WALE", "WALK", "WALL", "WALT", +"WAND", "WANE", "WANG", "WANT", "WARD", "WARM", "WARN", "WART", +"WASH", "WAST", "WATS", "WATT", "WAVE", "WAVY", "WAYS", "WEAK", +"WEAL", "WEAN", "WEAR", "WEED", "WEEK", "WEIR", "WELD", "WELL", +"WELT", "WENT", "WERE", "WERT", "WEST", "WHAM", "WHAT", "WHEE", +"WHEN", "WHET", "WHOA", "WHOM", "WICK", "WIFE", "WILD", "WILL", +"WIND", "WINE", "WING", "WINK", "WINO", "WIRE", "WISE", "WISH", +"WITH", "WOLF", "WONT", "WOOD", "WOOL", "WORD", "WORE", "WORK", +"WORM", "WORN", "WOVE", "WRIT", "WYNN", "YALE", "YANG", "YANK", +"YARD", "YARN", "YAWL", "YAWN", "YEAH", "YEAR", "YELL", "YOGA", +"YOKE" }; + +#endif /* _OTP_H_ */ diff --git a/libs/cyrussasl/plugins/otp_init.c b/libs/cyrussasl/plugins/otp_init.c new file mode 100644 index 00000000..cd116849 --- /dev/null +++ b/libs/cyrussasl/plugins/otp_init.c @@ -0,0 +1,43 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_CLIENT_PLUG_INIT( otp ) +SASL_SERVER_PLUG_INIT( otp ) + diff --git a/libs/cyrussasl/plugins/passdss.c b/libs/cyrussasl/plugins/passdss.c new file mode 100644 index 00000000..4304f481 --- /dev/null +++ b/libs/cyrussasl/plugins/passdss.c @@ -0,0 +1,1682 @@ +/* PASSDSS-3DES-1 SASL plugin + * Ken Murchison + * $Id: passdss.c,v 1.5 2008/10/29 17:59:41 murch Exp $ + */ +/* + * Copyright (c) 1998-2004 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Notes: + * + */ + +#include +#include +#include +#include + +/* check OpenSSL version */ +#include +#if (OPENSSL_VERSION_NUMBER < 0x0090700f) +#error OpenSSL 0.9.7 or later is required +#endif + +/* for big number support */ +#include + +/* for Diffie-Hellman support */ +#include + +/* for digest and cipher support */ +#include +#include +#include +#include +#include + +#include +#define MD5_H /* suppress internal MD5 */ +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +/***************************** Common Section *****************************/ + +static const char plugin_id[] = "$Id: passdss.c,v 1.5 2008/10/29 17:59:41 murch Exp $"; + +const char g[] = "2"; +const char N[] = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF"; + +#define NO_LAYER_FLAG (1<<0) +#define INTEGRITY_LAYER_FLAG (1<<1) +#define PRIVACY_LAYER_FLAG (1<<2) + +#define NO_LAYER_SSF 0 +#define INTEGRITY_LAYER_SSF 1 +#define PRIVACY_LAYER_SSF 112 + +typedef struct context { + int state; + + char *authid; /* authentication id (server) */ + char *userid; /* authorization id (server) */ + sasl_secret_t *password; /* user secret (client) */ + unsigned int free_password; /* set if we need to free password */ + + DH *dh; /* Diffie-Hellman parameters */ + + /* copy of utils from the params structures */ + const sasl_utils_t *utils; + + /* per-step mem management */ + char *out_buf; + unsigned out_buf_len; + + /* security layer foo */ + unsigned char secmask; /* bitmask of enabled security layers */ + unsigned char padding[EVP_MAX_BLOCK_LENGTH]; /* block of NULs */ + + HMAC_CTX hmac_send_ctx; + HMAC_CTX hmac_recv_ctx; + + unsigned char send_integrity_key[4 + EVP_MAX_MD_SIZE]; /* +4 for pktnum */ + unsigned char recv_integrity_key[4 + EVP_MAX_MD_SIZE]; /* +4 for pktnum */ + unsigned char *cs_integrity_key; /* ptr to bare key in send/recv key */ + unsigned char *sc_integrity_key; /* ptr to bare key in send/recv key */ + + EVP_CIPHER_CTX cipher_enc_ctx; + EVP_CIPHER_CTX cipher_dec_ctx; + unsigned blk_siz; + + unsigned char cs_encryption_iv[EVP_MAX_MD_SIZE]; + unsigned char sc_encryption_iv[EVP_MAX_MD_SIZE]; + unsigned char cs_encryption_key[2 * EVP_MAX_MD_SIZE]; + unsigned char sc_encryption_key[2 * EVP_MAX_MD_SIZE]; + + /* replay detection sequence numbers */ + uint32_t pktnum_out; + uint32_t pktnum_in; + + /* for encoding/decoding mem management */ + char *encode_buf, *decode_buf, *decode_pkt_buf; + unsigned encode_buf_len, decode_buf_len, decode_pkt_buf_len; + + /* layers buffering */ + decode_context_t decode_context; + +} context_t; + + +static int passdss_encode(void *context, + const struct iovec *invec, + unsigned numiov, + const char **output, + unsigned *outputlen) +{ + context_t *text = (context_t *) context; + unsigned long inputlen; + unsigned char hmac[EVP_MAX_MD_SIZE]; + unsigned i, hmaclen; + uint32_t tmpnum; + int ret; + + if (!context || !invec || !numiov || !output || !outputlen) { + PARAMERROR( text->utils ); + return SASL_BADPARAM; + } + + /* calculate total size of input */ + for (i = 0, inputlen = 0; i < numiov; i++) + inputlen += invec[i].iov_len; + + /* allocate a buffer for the output */ + ret = _plug_buf_alloc(text->utils, &text->encode_buf, + &text->encode_buf_len, + 4 + /* length */ + inputlen + /* content */ + EVP_MAX_MD_SIZE + /* HMAC */ + EVP_MAX_BLOCK_LENGTH - 1); /* padding */ + if (ret != SASL_OK) return ret; + + *outputlen = 4; /* skip length */ + + /* prepend packet number to integrity key */ + tmpnum = htonl(text->pktnum_out++); + memcpy(text->send_integrity_key, &tmpnum, 4); + + /* key the HMAC */ + HMAC_Init_ex(&text->hmac_send_ctx, text->send_integrity_key, + 4+SHA_DIGEST_LENGTH, EVP_sha1(), NULL); + + /* operate on each iovec */ + for (i = 0; i < numiov; i++) { + /* hash the content */ + HMAC_Update(&text->hmac_send_ctx, invec[i].iov_base, invec[i].iov_len); + + if (text->secmask & PRIVACY_LAYER_FLAG) { + unsigned enclen; + + /* encrypt the data into the output buffer */ + EVP_EncryptUpdate(&text->cipher_enc_ctx, + text->encode_buf + *outputlen, &enclen, + invec[i].iov_base, invec[i].iov_len); + *outputlen += enclen; + } + else { + /* copy the raw input to the output */ + memcpy(text->encode_buf + *outputlen, invec[i].iov_base, + invec[i].iov_len); + *outputlen += invec[i].iov_len; + } + } + + /* calculate the HMAC */ + HMAC_Final(&text->hmac_send_ctx, hmac, &hmaclen); + + if (text->secmask & PRIVACY_LAYER_FLAG) { + unsigned enclen; + unsigned char padlen; + + /* encrypt the HMAC into the output buffer */ + EVP_EncryptUpdate(&text->cipher_enc_ctx, + text->encode_buf + *outputlen, &enclen, + hmac, hmaclen); + *outputlen += enclen; + + /* pad output buffer to multiple of blk_siz + with padlen-1 as last octet */ + padlen = text->blk_siz - ((inputlen + hmaclen) % text->blk_siz) - 1; + EVP_EncryptUpdate(&text->cipher_enc_ctx, + text->encode_buf + *outputlen, &enclen, + text->padding, padlen); + *outputlen += enclen; + EVP_EncryptUpdate(&text->cipher_enc_ctx, + text->encode_buf + *outputlen, &enclen, + &padlen, 1); + *outputlen += enclen; + + /* encrypt the last block of data into the output buffer */ + EVP_EncryptFinal_ex(&text->cipher_enc_ctx, + text->encode_buf + *outputlen, &enclen); + *outputlen += enclen; + } + else { + /* copy the HMAC to the output */ + memcpy(text->encode_buf + *outputlen, hmac, hmaclen); + *outputlen += hmaclen; + } + + /* prepend the length of the output */ + tmpnum = *outputlen - 4; + tmpnum = htonl(tmpnum); + memcpy(text->encode_buf, &tmpnum, 4); + + *output = text->encode_buf; + + return SASL_OK; +} + +/* Decode a single PASSDSS packet */ +static int passdss_decode_packet(void *context, + const char *input, + unsigned inputlen, + char **output, + unsigned *outputlen) +{ + context_t *text = (context_t *) context; + uint32_t tmpnum; + unsigned char hmac[EVP_MAX_MD_SIZE]; + unsigned hmaclen; + int ret; + + if (text->secmask & PRIVACY_LAYER_FLAG) { + unsigned declen, padlen; + + /* allocate a buffer for the output */ + ret = _plug_buf_alloc(text->utils, &(text->decode_pkt_buf), + &(text->decode_pkt_buf_len), inputlen); + if (ret != SASL_OK) return ret; + + /* decrypt the data into the output buffer */ + ret = EVP_DecryptUpdate(&text->cipher_dec_ctx, + text->decode_pkt_buf, &declen, + (char *) input, inputlen); + if (ret) + EVP_DecryptFinal_ex(&text->cipher_dec_ctx, /* should be no output */ + text->decode_pkt_buf + declen, &declen); + if (!ret) { + SETERROR(text->utils, "Error decrypting input"); + return SASL_BADPROT; + } + input = text->decode_pkt_buf; + + /* trim padding */ + padlen = text->decode_pkt_buf[inputlen - 1] + 1; + inputlen -= padlen; + } + + /* trim HMAC */ + inputlen -= SHA_DIGEST_LENGTH; + + /* prepend packet number to integrity key */ + tmpnum = htonl(text->pktnum_in++); + memcpy(text->recv_integrity_key, &tmpnum, 4); + + /* calculate the HMAC */ + HMAC(EVP_sha1(), text->recv_integrity_key, 4+SHA_DIGEST_LENGTH, + input, inputlen, hmac, &hmaclen); + + /* verify HMAC */ + if (memcmp(hmac, input+inputlen, hmaclen)) { + SETERROR(text->utils, "HMAC is incorrect\n"); + return SASL_BADMAC; + } + + *output = (char *) input; + *outputlen = inputlen; + + return SASL_OK; +} + +/* Decode and concatenate multiple PASSDSS packets */ +static int passdss_decode(void *context, + const char *input, unsigned inputlen, + const char **output, unsigned *outputlen) +{ + context_t *text = (context_t *) context; + int ret; + + ret = _plug_decode(&text->decode_context, input, inputlen, + &text->decode_buf, &text->decode_buf_len, outputlen, + passdss_decode_packet, text); + + *output = text->decode_buf; + + return ret; +} + +#define MAX_MPI_LEN 2147483643 +#define MAX_UTF8_LEN 2147483643 + +/* + * Create/append to a PASSDSS buffer from the data specified by the fmt string. + */ +static int MakeBuffer(const sasl_utils_t *utils, char **buf, unsigned offset, + unsigned *buflen, unsigned *outlen, const char *fmt, ...) +{ + va_list ap; + char *p, *out = NULL, *lptr = NULL; + int r, alloclen, len = -1, argc = 0; + BIGNUM *mpi; + char *os, *str; + uint32_t u, nl; + + /* first pass to calculate size of buffer */ + va_start(ap, fmt); + for (p = (char *) fmt, alloclen = offset; *p; p++) { + if (*p != '%') { + alloclen++; + continue; + } + + /* check for length prefix ('a', 'o', 'u', and 's' only) */ + if (*++p == '*') { + /* arg is length of next arg */ + len = va_arg(ap, int); + p++; + } + else if (isdigit((int) *p)) { + len = 0; + while (isdigit((int) *p)) len = 10 * len + *p++ - '0'; + } + + switch (*p) { + case 'a': + /* insert total length of next N args */ + alloclen += 4; + break; + + case 'm': + /* MPI */ + mpi = va_arg(ap, BIGNUM *); + len = BN_num_bytes(mpi); + if (len > MAX_MPI_LEN) { + utils->log(NULL, SASL_LOG_ERR, + "String too long to create mpi string\n"); + r = SASL_FAIL; + goto done; + } + alloclen += len + 4; + break; + + case 'o': + /* octet sequence (len given by prefix) */ + alloclen += len; + os = va_arg(ap, char *); + break; + + case 's': + /* string */ + str = va_arg(ap, char *); + if (len == -1) len = strlen(str); + if (len > MAX_UTF8_LEN) { + utils->log(NULL, SASL_LOG_ERR, + "String too long to create utf8 string\n"); + r = SASL_FAIL; + goto done; + } + alloclen += len + 4; + break; + + case 'u': + /* unsigned int */ + u = va_arg(ap, uint32_t); + if (len == -1) len = 4; + alloclen += len; + break; + + default: + alloclen++; + break; + } + + len = -1; + } + va_end(ap); + + r = _plug_buf_alloc(utils, buf, buflen, alloclen); + if (r != SASL_OK) return r; + + out = *buf + offset; + + /* second pass to fill buffer */ + va_start(ap, fmt); + for (p = (char *) fmt; *p; p++) { + if (*p != '%') { + *out = *p; + out++; + continue; + } + + /* check for length prefix ('a', 'o', 'u', and 's' only) */ + if (*++p == '*') { + /* arg is length of next arg */ + len = va_arg(ap, int); + p++; + } + else if (isdigit((int) *p)) { + len = 0; + while (isdigit((int) *p)) len = 10 * len + *p++ - '0'; + } + + switch (*p) { + case 'a': + /* total length of next N args */ + argc = len; + len = -1; + lptr = out; + out += 4; + continue; + break; + + case 'm': + /* MPI */ + mpi = va_arg(ap, BIGNUM *); + len = BN_bn2bin(mpi, out+4); + nl = htonl(len); + memcpy(out, &nl, 4); /* add 4 byte len (network order) */ + out += len + 4; + break; + + case 'o': + /* octet sequence (len given by prefix) */ + os = va_arg(ap, char *); + memcpy(out, os, len); /* add data */ + out += len; + break; + + case 's': + /* string (len possibly given by prefix) */ + str = va_arg(ap, char *); + /* xxx do actual utf8 conversion */ + if (len == -1) len = strlen(str); + nl = htonl(len); + memcpy(out, &nl, 4); /* add 4 byte len (network order) */ + memcpy(out+4, str, len); /* add string */ + out += len + 4; + break; + + case 'u': + /* unsigned int */ + u = va_arg(ap, uint32_t); + nl = htonl(u); + if (len == -1) len = 4; + memcpy(out, &nl + 4 - len, len); + out += len; + break; + + default: + *out = *p; + out++; + break; + } + + /* see if we're done counting args */ + if (lptr && !--argc) { + len = out - lptr - 4; + nl = htonl(len); + memcpy(lptr, &nl, 4); /* insert 4 byte len (network order) */ + lptr = NULL; + } + + len = -1; + } + done: + va_end(ap); + + *outlen = out - *buf; + + return r; +} + +/* + * Extract a PASSDSS buffer into the data specified by the fmt string. + */ +static int UnBuffer(const sasl_utils_t *utils, const char *buf, + unsigned buflen, const char *fmt, ...) +{ + va_list ap; + char *p; + BIGNUM **mpi; + char **os, **str; + uint32_t *u, nl; + unsigned len; + enum { OCTET_REFERENCE, /* just point to the data (reference it) */ + OCTET_COPY, /* copy the data into the given buffer */ + OCTET_ALLOC /* alloc space for the data, then copy */ + } octet_flag; + int r = SASL_OK; + + va_start(ap, fmt); + for (p = (char *) fmt; *p; p++) { + if (*p != '%') { + if (*buf != *p) { + r = SASL_BADPROT; + goto done; + } + buf++; + buflen--; + continue; + } + p++; + + /* check for octet flags */ + octet_flag = OCTET_COPY; + if (*p == '-') { + octet_flag = OCTET_REFERENCE; + p++; + } + else if (*p == '+') { + octet_flag = OCTET_ALLOC; + p++; + } + + /* check for length prefix ('o', 'u', and 'p' only) */ + len = 0; + if (*p == '*') { + /* arg is length of next arg */ + len = va_arg(ap, int); + p++; + } + else if (isdigit((int) *p)) { + len = 0; + while (isdigit((int) *p)) len = 10 * len + *p++ - '0'; + } + + switch (*p) { + case 'm': + /* MPI */ + mpi = va_arg(ap, BIGNUM **); + + if (buflen < 4) { + SETERROR(utils, "Buffer is not big enough to be PASSDSS MPI\n"); + r = SASL_BADPROT; + goto done; + } + + /* get the length */ + memcpy(&nl, buf, 4); + len = ntohl(nl); + buf += 4; + buflen -= 4; + + /* make sure it's right */ + if (len > buflen) { + SETERROR(utils, "Not enough data for this PASSDSS MPI\n"); + r = SASL_BADPROT; + goto done; + } + + if (mpi) { + if (!*mpi) *mpi = BN_new(); + BN_init(*mpi); + BN_bin2bn(buf, len, *mpi); + } + break; + + case 'o': + /* octet sequence (len given by prefix) */ + os = va_arg(ap, char **); + + /* make sure it's right */ + if (len > buflen) { + SETERROR(utils, "Not enough data for this PASSDSS os\n"); + r = SASL_BADPROT; + goto done; + } + + if (os) { + if (octet_flag == OCTET_REFERENCE) + *os = (char *) buf; + else { + if (octet_flag == OCTET_ALLOC && + (*os = (char *) utils->malloc(len)) == NULL) { + r = SASL_NOMEM; + goto done; + } + + memcpy(*os, buf, len); + } + } + break; + + case 'p': + /* padding (max len given by prefix) */ + + if (buflen < len) len = buflen; + break; + + case 's': + /* string */ + str = va_arg(ap, char **); + if (str) *str = NULL; + + if (buflen < 4) { + SETERROR(utils, "Buffer is not big enough to be PASSDSS string\n"); + r = SASL_BADPROT; + goto done; + } + + /* get the length */ + memcpy(&nl, buf, 4); + len = ntohl(nl); + buf += 4; + buflen -= 4; + + /* make sure it's right */ + if (len > buflen) { + SETERROR(utils, "Not enough data for this PASSDSS string\n"); + r = SASL_BADPROT; + goto done; + } + + if (str) { + *str = (char *) utils->malloc(len+1); /* +1 for NUL */ + if (!*str) { + r = SASL_NOMEM; + goto done; + } + + memcpy(*str, buf, len); + (*str)[len] = '\0'; + } + break; + + case 'u': + /* unsigned int */ + u = va_arg(ap, uint32_t*); + + if (!len) len = 4; + if (buflen < len) { + SETERROR(utils, "Buffer is not big enough to be PASSDSS uint32\n"); + r = SASL_BADPROT; + goto done; + } + + if (u) { + memset(u, 0, 4); + memcpy(u + 4 - len, buf, len); + *u = ntohl(*u); + } + break; + + default: + len = 1; + if (*buf != *p) { + r = SASL_BADPROT; + goto done; + } + break; + } + + buf += len; + buflen -= len; + } + + if (buflen != 0) { + SETERROR(utils, "Extra data in PASSDSS buffer\n"); + r = SASL_BADPROT; + } + + done: + va_end(ap); + + return r; +} + +#define DOHASH(out, in1, len1, in2, len2, in3, len3) \ + EVP_DigestInit(&mdctx, EVP_sha1()); \ + EVP_DigestUpdate(&mdctx, in1, len1); \ + EVP_DigestUpdate(&mdctx, in2, len2); \ + EVP_DigestUpdate(&mdctx, in3, len3); \ + EVP_DigestFinal(&mdctx, out, NULL) + +void CalcLayerParams(context_t *text, char *K, unsigned Klen, + char *hash, unsigned hashlen) +{ + EVP_MD_CTX mdctx; + + DOHASH(text->cs_encryption_iv, K, Klen, "A", 1, hash, hashlen); + DOHASH(text->sc_encryption_iv, K, Klen, "B", 1, hash, hashlen); + DOHASH(text->cs_encryption_key, K, Klen, "C", 1, hash, hashlen); + DOHASH(text->cs_encryption_key + hashlen, K, Klen, "", 0, + text->cs_encryption_key, hashlen); + DOHASH(text->sc_encryption_key, K, Klen, "D", 1, hash, hashlen); + DOHASH(text->sc_encryption_key + hashlen, K, Klen, "", 0, + text->sc_encryption_key, hashlen); + DOHASH(text->cs_integrity_key, K, Klen, "E", 1, hash, hashlen); + DOHASH(text->sc_integrity_key, K, Klen, "F", 1, hash, hashlen); +} + +/* + * Dispose of a PASSDSS context (could be server or client) + */ +static void passdss_common_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + context_t *text = (context_t *) conn_context; + + if (!text) return; + + if (text->authid) utils->free(text->authid); + if (text->userid) utils->free(text->userid); + if (text->free_password) _plug_free_secret(utils, &(text->password)); + + if (text->dh) DH_free(text->dh); + + HMAC_CTX_cleanup(&text->hmac_send_ctx); + HMAC_CTX_cleanup(&text->hmac_recv_ctx); + + EVP_CIPHER_CTX_cleanup(&text->cipher_enc_ctx); + EVP_CIPHER_CTX_cleanup(&text->cipher_dec_ctx); + + _plug_decode_free(&text->decode_context); + + if (text->encode_buf) utils->free(text->encode_buf); + if (text->decode_buf) utils->free(text->decode_buf); + if (text->decode_pkt_buf) utils->free(text->decode_pkt_buf); + if (text->out_buf) utils->free(text->out_buf); + + utils->free(text); +} + +/***************************** Server Section *****************************/ + +static int passdss_server_mech_new(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + void **conn_context) +{ + context_t *text; + + /* holds state are in */ + text = sparams->utils->malloc(sizeof(context_t)); + if (text == NULL) { + MEMERROR(sparams->utils); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(context_t)); + + text->state = 1; + text->utils = sparams->utils; + text->cs_integrity_key = text->recv_integrity_key + 4; + text->sc_integrity_key = text->send_integrity_key + 4; + + *conn_context = text; + + return SASL_OK; +} + +static int +passdss_server_mech_step1(context_t *text, + sasl_server_params_t *params, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams __attribute__((unused))) +{ + BIGNUM *X = NULL; + DSA *dsa = NULL; + unsigned char *K = NULL; + unsigned Klen, hashlen; + int need, musthave; + EVP_MD_CTX mdctx; + unsigned char hash[EVP_MAX_MD_SIZE]; + DSA_SIG *sig = NULL; + int result; + + /* Expect: + * + * (1) string azname ; authorization name + * (2) string authname ; authentication name + * (3) mpint X ; Diffie-Hellman parameter X + */ + + result = UnBuffer(params->utils, clientin, clientinlen, + "%s%s%m", &text->userid, &text->authid, &X); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error UnBuffering input in step 1"); + goto cleanup; + } + + /* Fetch DSA (XXX create one for now) */ + dsa = DSA_generate_parameters(1024, NULL, 0, NULL, NULL, NULL, NULL); + if (!dsa) { + result = SASL_FAIL; + goto cleanup; + } + DSA_generate_key(dsa); + + /* Create Diffie-Hellman parameters */ + text->dh = DH_new(); + BN_hex2bn(&text->dh->p, N); + BN_hex2bn(&text->dh->g, g); + DH_generate_key(text->dh); + + /* Alloc space for shared secret K as mpint */ + K = text->utils->malloc(DH_size(text->dh) + 4); + if (!K) { + params->utils->log(NULL, SASL_LOG_ERR, "Error allocing K\n"); + result = SASL_NOMEM; + goto cleanup; + } + + /* Calculate DH shared secret (leave space at head for length) */ + Klen = DH_compute_key(K+4, X, text->dh); + + /* Prepend length in network byte order (make it a mpint) */ + *((uint32_t *) K) = htonl(Klen); + Klen += 4; + + /* Which layers can we support? */ + if (params->props.maxbufsize < 32) { + need = musthave = 0; + } else { + need = params->props.max_ssf - params->external_ssf; + musthave = params->props.min_ssf - params->external_ssf; + } + + if (musthave <= NO_LAYER_SSF) + text->secmask |= NO_LAYER_FLAG; + if ((musthave <= INTEGRITY_LAYER_SSF) && (INTEGRITY_LAYER_SSF <= need)) + text->secmask |= INTEGRITY_LAYER_FLAG; + if ((musthave <= PRIVACY_LAYER_SSF) && (PRIVACY_LAYER_SSF <= need)) + text->secmask |= PRIVACY_LAYER_FLAG; + + + /* Send out: + * + * (4) uint32 pklength ; length of SSH-style DSA server public key + * string "ssh-dss" ; constant string "ssh-dss" (lower case) + * mpint p ; DSA public key parameters + * mpint q + * mpint g + * mpint y + * (5) mpint Y ; Diffie-Hellman parameter Y + * (6) OCTET ssecmask ; SASL security layers offered + * (7) 3 OCTET sbuflen ; maximum server security layer block size + * (8) uint32 siglength ; length of SSH-style dss signature + * string "ssh-dss" ; constant string "ssh-dss" (lower case) + * mpint r ; DSA signature parameters + * mpint s + */ + + /* Items (4) - (7) */ + result = MakeBuffer(text->utils, &text->out_buf, 0, &text->out_buf_len, + serveroutlen, "%5a%s%m%m%m%m%m%1o%3u", + "ssh-dss", dsa->p, dsa->q, dsa->g, dsa->pub_key, + text->dh->pub_key, &text->secmask, + (params->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF : + params->props.maxbufsize); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n"); + goto cleanup; + } + + /* Hash (1) - (7) and K */ + EVP_DigestInit(&mdctx, EVP_sha1()); + /* (1) - (3) */ + EVP_DigestUpdate(&mdctx, clientin, clientinlen); + /* (4) - (7) */ + EVP_DigestUpdate(&mdctx, text->out_buf, *serveroutlen); + /* K */ + EVP_DigestUpdate(&mdctx, K, Klen); + EVP_DigestFinal(&mdctx, hash, &hashlen); + + /* Calculate security layer params */ + CalcLayerParams(text, K, Klen, hash, hashlen); + + /* Start cli-hmac */ + HMAC_CTX_init(&text->hmac_recv_ctx); + HMAC_Init_ex(&text->hmac_recv_ctx, text->cs_integrity_key, + SHA_DIGEST_LENGTH, EVP_sha1(), NULL); + /* (1) - (3) */ + HMAC_Update(&text->hmac_recv_ctx, clientin, clientinlen); + /* (4) - (7) */ + HMAC_Update(&text->hmac_recv_ctx, text->out_buf, *serveroutlen); + + /* Sign the hash */ + sig = DSA_do_sign(hash, hashlen, dsa); + if (!sig) { + params->utils->log(NULL, SASL_LOG_ERR, + "Error calculating DSS signature\n"); + result = SASL_FAIL; + goto cleanup; + } + + /* Item (8) */ + result = MakeBuffer(text->utils, &text->out_buf, *serveroutlen, + &text->out_buf_len, serveroutlen, + "%3a%s%m%m", "ssh-dss", sig->r, sig->s); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n"); + goto cleanup; + } + *serverout = text->out_buf; + + text->state = 2; + result = SASL_CONTINUE; + + cleanup: + if (X) BN_free(X); + if (K) text->utils->free(K); + if (dsa) DSA_free(dsa); + if (sig) DSA_SIG_free(sig); + + return result; +} + +static int +passdss_server_mech_step2(context_t *text, + sasl_server_params_t *params, + const char *clientin, + unsigned clientinlen, + const char **serverout __attribute__((unused)), + unsigned *serveroutlen __attribute__((unused)), + sasl_out_params_t *oparams) +{ + char *password = NULL; + unsigned declen, hmaclen; + unsigned char *csecmask, *cli_hmac, hmac[EVP_MAX_MD_SIZE]; + uint32_t cbufsiz; + int r, result = SASL_OK; + + /* Expect (3DES encrypted): + * + * (9) OCTET csecmask ; SASL security layer selection + * 3 OCTET cbuflen ; maximum client block size + * string passphrase ; the user's passphrase + * 20 OCTET cli-hmac ; a client HMAC-SHA-1 signature + */ + + /* Alloc space for the decrypted input */ + result = _plug_buf_alloc(text->utils, &text->decode_pkt_buf, + &text->decode_pkt_buf_len, clientinlen); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, + "Error allocating decrypt buffer in step 2\n"); + goto cleanup; + } + + /* Initialize decrypt cipher */ + EVP_CIPHER_CTX_init(&text->cipher_dec_ctx); + EVP_DecryptInit_ex(&text->cipher_dec_ctx, EVP_des_ede3_cbc(), NULL, + text->cs_encryption_key, text->cs_encryption_iv); + EVP_CIPHER_CTX_set_padding(&text->cipher_dec_ctx, 0); + text->blk_siz = EVP_CIPHER_CTX_block_size(&text->cipher_dec_ctx); + + /* Decrypt the blob */ + r = EVP_DecryptUpdate(&text->cipher_dec_ctx, text->decode_pkt_buf, &declen, + clientin, clientinlen); + if (r) + r = EVP_DecryptFinal_ex(&text->cipher_dec_ctx, /* should be no output */ + text->decode_pkt_buf + declen, &declen); + if (!r) { + params->utils->seterror(params->utils->conn, 0, + "Error decrypting input in step 2"); + result = SASL_BADPROT; + goto cleanup; + } + clientin = text->decode_pkt_buf; + + result = UnBuffer(params->utils, clientin, clientinlen, + "%-1o%3u%s%-*o%*p", &csecmask, &cbufsiz, &password, + SHA_DIGEST_LENGTH, &cli_hmac, text->blk_siz - 1); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error UnBuffering input in step 2"); + goto cleanup; + } + + /* Finish cli-hmac */ + /* (1) - (7) hashed in step 1 */ + /* 1st 4 bytes of (9) */ + HMAC_Update(&text->hmac_recv_ctx, clientin, 4); + HMAC_Final(&text->hmac_recv_ctx, hmac, &hmaclen); + + /* Verify cli-hmac */ + if (memcmp(cli_hmac, hmac, hmaclen)) { + params->utils->seterror(params->utils->conn, 0, + "Client HMAC verification failed"); + result = SASL_BADMAC; + goto cleanup; + } + + /* Canonicalize authentication ID first, so that password verification + * is only against the canonical id */ + result = params->canon_user(params->utils->conn, + text->authid, 0, SASL_CU_AUTHID, oparams); + if (result != SASL_OK) { + return result; + } + + /* Verify password - return sasl_ok on success */ + result = params->utils->checkpass(params->utils->conn, + oparams->authid, oparams->alen, + password, strlen(password)); + + if (result != SASL_OK) { + params->utils->seterror(params->utils->conn, 0, + "Password verification failed"); + goto cleanup; + } + + /* Canonicalize and store the authorization ID */ + /* We need to do this after calling verify_user just in case verify_user + * needed to get auxprops itself */ + result = params->canon_user(params->utils->conn, + *text->userid ? text->userid : text->authid, 0, + SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) return result; + + /* See which layer the client selected */ + text->secmask &= *csecmask; + if (text->secmask & PRIVACY_LAYER_FLAG) { + oparams->mech_ssf = PRIVACY_LAYER_SSF; + } else if (text->secmask & INTEGRITY_LAYER_FLAG) { + oparams->mech_ssf = INTEGRITY_LAYER_SSF; + } else if (text->secmask & NO_LAYER_FLAG) { + oparams->mech_ssf = NO_LAYER_SSF; + } else { + /* Mark that we tried */ + oparams->mech_ssf = 2; + SETERROR(params->utils, + "unable to agree on layers with server"); + return SASL_BADPROT; + } + + /* Set oparams */ + oparams->doneflag = 1; + oparams->param_version = 0; + + if (oparams->mech_ssf > 0) { + oparams->encode = &passdss_encode; + oparams->decode = &passdss_decode; + oparams->maxoutbuf = cbufsiz - 4 - SHA_DIGEST_LENGTH; /* -len -HMAC */ + + HMAC_CTX_init(&text->hmac_send_ctx); + + if (oparams->mech_ssf > 1) { + oparams->maxoutbuf -= text->blk_siz-1; /* padding */ + + /* Initialize encrypt cipher */ + EVP_CIPHER_CTX_init(&text->cipher_enc_ctx); + EVP_EncryptInit_ex(&text->cipher_enc_ctx, EVP_des_ede3_cbc(), NULL, + text->sc_encryption_key, text->sc_encryption_iv); + EVP_CIPHER_CTX_set_padding(&text->cipher_enc_ctx, 0); + } + + _plug_decode_init(&text->decode_context, text->utils, + (params->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF : + params->props.maxbufsize); + } + else { + oparams->encode = NULL; + oparams->decode = NULL; + oparams->maxoutbuf = 0; + } + + result = SASL_OK; + + cleanup: + if (password) _plug_free_string(params->utils, &password); + + return result; +} + +static int passdss_server_mech_step(void *conn_context, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *) conn_context; + + if (!sparams + || !serverout + || !serveroutlen + || !oparams) + return SASL_BADPARAM; + + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "PASSDSS server step %d\n", text->state); + + *serverout = NULL; + *serveroutlen = 0; + + switch (text->state) { + + case 1: + return passdss_server_mech_step1(text, sparams, clientin, clientinlen, + serverout, serveroutlen, oparams); + + case 2: + return passdss_server_mech_step2(text, sparams, clientin, clientinlen, + serverout, serveroutlen, oparams); + + default: + sparams->utils->seterror(sparams->utils->conn, 0, + "Invalid PASSDSS server step %d", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static sasl_server_plug_t passdss_server_plugins[] = +{ + { + "PASSDSS-3DES-1", /* mech_name */ + 112, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS + | SASL_SEC_NOACTIVE + | SASL_SEC_NODICTIONARY + | SASL_SEC_FORWARD_SECRECY + | SASL_SEC_PASS_CREDENTIALS + | SASL_SEC_MUTUAL_AUTH, /* security_flags */ + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY, /* features */ + NULL, /* glob_context */ + &passdss_server_mech_new, /* mech_new */ + &passdss_server_mech_step, /* mech_step */ + &passdss_common_mech_dispose, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* setpass */ + NULL, /* user_query */ + NULL, /* idle */ + NULL, /* mech_avail */ + NULL /* spare */ + } +}; + +int passdss_server_plug_init(const sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_SERVER_PLUG_VERSION) { + SETERROR(utils, "PASSDSS version mismatch"); + return SASL_BADVERS; + } + + *out_version = SASL_SERVER_PLUG_VERSION; + *pluglist = passdss_server_plugins; + *plugcount = 1; + + return SASL_OK; +} + +/***************************** Client Section *****************************/ + +static int passdss_client_mech_new(void *glob_context __attribute__((unused)), + sasl_client_params_t *params, + void **conn_context) +{ + context_t *text; + + /* holds state are in */ + text = params->utils->malloc(sizeof(context_t)); + if (text == NULL) { + MEMERROR(params->utils); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(context_t)); + + text->state = 1; + text->utils = params->utils; + text->cs_integrity_key = text->send_integrity_key + 4; + text->sc_integrity_key = text->recv_integrity_key + 4; + + *conn_context = text; + + return SASL_OK; +} + +static int +passdss_client_mech_step1(context_t *text, + sasl_client_params_t *params, + const char *serverin __attribute__((unused)), + unsigned serverinlen __attribute__((unused)), + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + const char *user = NULL, *authid = NULL; + int user_result = SASL_OK; + int auth_result = SASL_OK; + int pass_result = SASL_OK; + int result; + + /* Expect: absolutely nothing */ + if (serverinlen > 0) { + SETERROR(params->utils, "Invalid input to first step of PASSDSS\n"); + return SASL_BADPROT; + } + + /* check if security layer is strong enough */ + if (params->props.min_ssf > PRIVACY_LAYER_SSF + params->external_ssf) { + SETERROR(params->utils, + "minimum ssf too strong for PASSDSS"); + return SASL_TOOWEAK; + } + + /* try to get the authid */ + if (oparams->authid == NULL) { + auth_result = _plug_get_authid(params->utils, &authid, prompt_need); + + if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT)) + return auth_result; + } + + /* try to get the userid */ + if (oparams->user == NULL) { + user_result = _plug_get_userid(params->utils, &user, prompt_need); + + if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) + return user_result; + } + + /* try to get the password */ + if (text->password == NULL) { + pass_result = _plug_get_password(params->utils, &text->password, + &text->free_password, prompt_need); + + if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT)) + return pass_result; + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + params->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if ((user_result == SASL_INTERACT) || (auth_result == SASL_INTERACT) || + (pass_result == SASL_INTERACT)) { + /* make the prompt list */ + result = + _plug_make_prompts(params->utils, prompt_need, + user_result == SASL_INTERACT ? + "Please enter your authorization name" : NULL, + NULL, + auth_result == SASL_INTERACT ? + "Please enter your authentication name" : NULL, + NULL, + pass_result == SASL_INTERACT ? + "Please enter your password" : NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); + if (result != SASL_OK) goto cleanup; + + return SASL_INTERACT; + } + + if (!text->password) { + PARAMERROR(params->utils); + return SASL_BADPARAM; + } + + if (!user || !*user) { + result = params->canon_user(params->utils->conn, authid, 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + } + else { + result = params->canon_user(params->utils->conn, user, 0, + SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) goto cleanup; + + result = params->canon_user(params->utils->conn, authid, 0, + SASL_CU_AUTHID, oparams); + } + if (result != SASL_OK) goto cleanup; + + /* create Diffie-Hellman parameters */ + text->dh = DH_new(); + BN_hex2bn(&text->dh->p, N); + BN_hex2bn(&text->dh->g, g); + DH_generate_key(text->dh); + + + /* Send out: + * + * (1) string azname ; authorization name + * (2) string authname ; authentication name + * (3) mpint X ; Diffie-Hellman parameter X + */ + + result = MakeBuffer(text->utils, &text->out_buf, 0, &text->out_buf_len, + clientoutlen, "%s%s%m", + (user && *user) ? (char *) oparams->user : "", + (char *) oparams->authid, text->dh->pub_key); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n"); + goto cleanup; + } + *clientout = text->out_buf; + + text->state = 2; + result = SASL_CONTINUE; + + cleanup: + + return result; +} + +static int +passdss_client_mech_step2(context_t *text, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need __attribute__((unused)), + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + DSA *dsa = DSA_new(); + DSA_SIG *sig = DSA_SIG_new(); + BIGNUM *Y = NULL; + uint32_t siglen; + unsigned char *K = NULL; + unsigned Klen, hashlen, enclen; + unsigned char *ssecmask; + uint32_t sbufsiz; + EVP_MD_CTX mdctx; + unsigned char hash[EVP_MAX_MD_SIZE]; + int need, musthave; + int result, r; + + /* Expect: + * + * (4) uint32 pklength ; length of SSH-style DSA server public key + * string "ssh-dss" ; constant string "ssh-dss" (lower case) + * mpint p ; DSA public key parameters + * mpint q + * mpint g + * mpint y + * (5) mpint Y ; Diffie-Hellman parameter Y + * (6) OCTET ssecmask ; SASL security layers offered + * (7) 3 OCTET sbuflen ; maximum server security layer block size + * (8) uint32 siglength ; length of SSH-style dss signature + * string "ssh-dss" ; constant string "ssh-dss" (lower case) + * mpint r ; DSA signature parameters + * mpint s + */ + + result = UnBuffer(params->utils, serverin, serverinlen, + "%u%3p\7ssh-dss%m%m%m%m%m%-1o%3u%u%3p\7ssh-dss%m%m", + NULL, &dsa->p, &dsa->q, &dsa->g, &dsa->pub_key, + &Y, &ssecmask, &sbufsiz, &siglen, &sig->r, &sig->s); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error UnBuffering input in step 2"); + goto cleanup; + } + + /* XXX Validate server DSA public key */ + + /* Alloc space for shared secret K as mpint */ + K = text->utils->malloc(DH_size(text->dh) + 4); + if (!K) { + params->utils->log(NULL, SASL_LOG_ERR, "Error allocing K\n"); + result = SASL_NOMEM; + goto cleanup; + } + + /* Calculate DH shared secret (leave space at head for length) */ + Klen = DH_compute_key(K+4, Y, text->dh); + + /* Prepend length in network byte order (make it a mpint) */ + *((uint32_t *) K) = htonl(Klen); + Klen += 4; + + /* Hash (1) - (7) and K */ + EVP_DigestInit(&mdctx, EVP_sha1()); + /* (1) - (3) (output from step 1 still in buffer) */ + EVP_DigestUpdate(&mdctx, text->out_buf, text->out_buf_len); + /* (4) - (7) */ + EVP_DigestUpdate(&mdctx, serverin, serverinlen - siglen - 4); + /* K */ + EVP_DigestUpdate(&mdctx, K, Klen); + EVP_DigestFinal(&mdctx, hash, &hashlen); + + /* Verify signature on the hash */ + result = DSA_do_verify(hash, hashlen, sig, dsa); + if (result != 1) { + params->utils->log(NULL, SASL_LOG_ERR, + (result == 0) ? "Incorrect DSS signature\n" : + "Error verifying DSS signature\n"); + result = (result == 0) ? SASL_BADPROT : SASL_FAIL; + goto cleanup; + } + + /* Calculate security layer params */ + CalcLayerParams(text, K, Klen, hash, hashlen); + + /* Initialize encrypt cipher */ + EVP_CIPHER_CTX_init(&text->cipher_enc_ctx); + EVP_EncryptInit_ex(&text->cipher_enc_ctx, EVP_des_ede3_cbc(), NULL, + text->cs_encryption_key, text->cs_encryption_iv); + EVP_CIPHER_CTX_set_padding(&text->cipher_enc_ctx, 0); + text->blk_siz = EVP_CIPHER_CTX_block_size(&text->cipher_enc_ctx); + + /* pick a layer */ + if (params->props.maxbufsize < 32) { + need = musthave = 0; + } else { + need = params->props.max_ssf - params->external_ssf; + musthave = params->props.min_ssf - params->external_ssf; + } + + if ((*ssecmask & PRIVACY_LAYER_FLAG) && + (need >= PRIVACY_LAYER_SSF) && (musthave <= PRIVACY_LAYER_SSF)) { + text->secmask = PRIVACY_LAYER_FLAG; + oparams->mech_ssf = PRIVACY_LAYER_SSF; + } else if ((*ssecmask & INTEGRITY_LAYER_FLAG) && + (need >= INTEGRITY_LAYER_SSF) && + (musthave <= INTEGRITY_LAYER_SSF)) { + text->secmask =INTEGRITY_LAYER_FLAG; + oparams->mech_ssf = INTEGRITY_LAYER_SSF; + } else if ((*ssecmask & NO_LAYER_FLAG) && (musthave <= NO_LAYER_SSF)) { + text->secmask = NO_LAYER_FLAG; + oparams->mech_ssf = NO_LAYER_SSF; + } else { + /* Mark that we tried */ + oparams->mech_ssf = 2; + SETERROR(params->utils, + "unable to agree on layers with server"); + return SASL_BADPROT; + } + + /* Start cli-hmac */ + HMAC_CTX_init(&text->hmac_send_ctx); + HMAC_Init_ex(&text->hmac_send_ctx, text->cs_integrity_key, + SHA_DIGEST_LENGTH, EVP_sha1(), NULL); + /* (1) - (3) (output from step 1 still in buffer) */ + HMAC_Update(&text->hmac_send_ctx, text->out_buf, text->out_buf_len); + /* (4) - (7) */ + HMAC_Update(&text->hmac_send_ctx, serverin, serverinlen - siglen - 4); + + + /* Send out (3DES encrypted): + * + * (9) OCTET csecmask ; SASL security layer selection + * 3 OCTET cbuflen ; maximum client block size + * string passphrase ; the user's passphrase + * 20 OCTET cli-hmac ; a client HMAC-SHA-1 signature + */ + + result = MakeBuffer(text->utils, &text->out_buf, 0, + &text->out_buf_len, clientoutlen, "%1o%3u%*s", + &text->secmask, + (params->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF : + params->props.maxbufsize, + text->password->len, text->password->data); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n"); + goto cleanup; + } + + /* Finish cli-hmac */ + /* 1st 4 bytes of (9) */ + HMAC_Update(&text->hmac_send_ctx, text->out_buf, 4); + HMAC_Final(&text->hmac_send_ctx, hash, &hashlen); + + /* Add HMAC and pad to fill no more than current block */ + result = MakeBuffer(text->utils, &text->out_buf, *clientoutlen, + &text->out_buf_len, clientoutlen, "%*o%*o", + hashlen, hash, text->blk_siz - 1, text->padding); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n"); + goto cleanup; + } + + /* Alloc space for the encrypted output */ + result = _plug_buf_alloc(text->utils, &text->encode_buf, + &text->encode_buf_len, *clientoutlen); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, + "Error allocating encrypt buffer in step 2\n"); + goto cleanup; + } + + /* Encrypt (9) (here we calculate the exact number of full blocks) */ + r = EVP_EncryptUpdate(&text->cipher_enc_ctx, text->encode_buf, + clientoutlen, text->out_buf, + text->blk_siz * (*clientoutlen / text->blk_siz)); + if (r) + r = EVP_EncryptFinal_ex(&text->cipher_enc_ctx, /* should be no output */ + text->encode_buf + *clientoutlen, &enclen); + if (!r) { + params->utils->seterror(params->utils->conn, 0, + "Error encrypting output in step 2"); + result = SASL_FAIL; + goto cleanup; + } + *clientout = text->encode_buf; + + /* Set oparams */ + oparams->doneflag = 1; + oparams->param_version = 0; + + if (oparams->mech_ssf > 0) { + oparams->encode = &passdss_encode; + oparams->decode = &passdss_decode; + oparams->maxoutbuf = sbufsiz - 4 - SHA_DIGEST_LENGTH; /* -len -HMAC */ + + HMAC_CTX_init(&text->hmac_recv_ctx); + + if (oparams->mech_ssf > 1) { + oparams->maxoutbuf -= text->blk_siz-1; /* padding */ + + /* Initialize decrypt cipher */ + EVP_CIPHER_CTX_init(&text->cipher_dec_ctx); + EVP_DecryptInit_ex(&text->cipher_dec_ctx, EVP_des_ede3_cbc(), NULL, + text->sc_encryption_key, text->sc_encryption_iv); + EVP_CIPHER_CTX_set_padding(&text->cipher_dec_ctx, 0); + } + + _plug_decode_init(&text->decode_context, text->utils, + (params->props.maxbufsize > 0xFFFFFF) ? 0xFFFFFF : + params->props.maxbufsize); + } + else { + oparams->encode = NULL; + oparams->decode = NULL; + oparams->maxoutbuf = 0; + } + + result = SASL_OK; + + cleanup: + if (Y) BN_free(Y); + if (K) text->utils->free(K); + if (dsa) DSA_free(dsa); + if (sig) DSA_SIG_free(sig); + + return result; +} + +static int passdss_client_mech_step(void *conn_context, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *) conn_context; + + params->utils->log(NULL, SASL_LOG_DEBUG, + "PASSDSS client step %d\n", text->state); + + *clientout = NULL; + *clientoutlen = 0; + + switch (text->state) { + + case 1: + return passdss_client_mech_step1(text, params, serverin, serverinlen, + prompt_need, clientout, clientoutlen, + oparams); + + case 2: + return passdss_client_mech_step2(text, params, serverin, serverinlen, + prompt_need, clientout, clientoutlen, + oparams); + + default: + params->utils->log(NULL, SASL_LOG_ERR, + "Invalid PASSDSS client step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + + +static sasl_client_plug_t passdss_client_plugins[] = +{ + { + "PASSDSS-3DES-1", /* mech_name */ + 112, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS + | SASL_SEC_NOACTIVE + | SASL_SEC_NODICTIONARY + | SASL_SEC_FORWARD_SECRECY + | SASL_SEC_PASS_CREDENTIALS + | SASL_SEC_MUTUAL_AUTH, /* security_flags */ + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY, /* features */ + NULL, /* required_prompts */ + NULL, /* glob_context */ + &passdss_client_mech_new, /* mech_new */ + &passdss_client_mech_step, /* mech_step */ + &passdss_common_mech_dispose, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* idle */ + NULL, /* spare */ + NULL /* spare */ + } +}; + +int passdss_client_plug_init(sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_CLIENT_PLUG_VERSION) { + SETERROR(utils, "PASSDSS version mismatch"); + return SASL_BADVERS; + } + + *out_version = SASL_CLIENT_PLUG_VERSION; + *pluglist = passdss_client_plugins; + *plugcount = 1; + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/passdss_init.c b/libs/cyrussasl/plugins/passdss_init.c new file mode 100644 index 00000000..3a35fb72 --- /dev/null +++ b/libs/cyrussasl/plugins/passdss_init.c @@ -0,0 +1,43 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_CLIENT_PLUG_INIT( passdss ) +SASL_SERVER_PLUG_INIT( passdss ) + diff --git a/libs/cyrussasl/plugins/plain.c b/libs/cyrussasl/plugins/plain.c new file mode 100644 index 00000000..e6180a1c --- /dev/null +++ b/libs/cyrussasl/plugins/plain.c @@ -0,0 +1,491 @@ +/* Plain SASL plugin + * Rob Siemborski + * Tim Martin + * $Id: plain.c,v 1.67 2009/06/10 16:05:19 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +/***************************** Common Section *****************************/ + +static const char plugin_id[] = "$Id: plain.c,v 1.67 2009/06/10 16:05:19 mel Exp $"; + +/***************************** Server Section *****************************/ + +static int plain_server_mech_new(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + void **conn_context) +{ + /* holds state are in */ + if (!conn_context) { + PARAMERROR( sparams->utils ); + return SASL_BADPARAM; + } + + *conn_context = NULL; + + return SASL_OK; +} + +static int plain_server_mech_step(void *conn_context __attribute__((unused)), + sasl_server_params_t *params, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + const char *author; + const char *authen; + const char *password; + unsigned password_len; + unsigned lup = 0; + int result; + char *passcopy; + unsigned canon_flags = 0; + + *serverout = NULL; + *serveroutlen = 0; + + /* should have received author-id NUL authen-id NUL password */ + + /* get author */ + author = clientin; + while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup; + + if (lup >= clientinlen) { + SETERROR(params->utils, "Can only find author (no password)"); + return SASL_BADPROT; + } + + /* get authen */ + ++lup; + authen = clientin + lup; + while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup; + + if (lup >= clientinlen) { + params->utils->seterror(params->utils->conn, 0, + "Can only find author/en (no password)"); + return SASL_BADPROT; + } + + /* get password */ + lup++; + password = clientin + lup; + while ((lup < clientinlen) && (clientin[lup] != 0)) ++lup; + + password_len = (unsigned) (clientin + lup - password); + + if (lup != clientinlen) { + SETERROR(params->utils, + "Got more data than we were expecting in the PLAIN plugin\n"); + return SASL_BADPROT; + } + + /* this kinda sucks. we need password to be null terminated + but we can't assume there is an allocated byte at the end + of password so we have to copy it */ + passcopy = params->utils->malloc(password_len + 1); + if (passcopy == NULL) { + MEMERROR(params->utils); + return SASL_NOMEM; + } + + strncpy(passcopy, password, password_len); + passcopy[password_len] = '\0'; + + /* Canonicalize userid first, so that password verification is only + * against the canonical id */ + if (!author || !*author) { + author = authen; + canon_flags = SASL_CU_AUTHZID; + } else if (strcmp(author, authen) == 0) { + /* While this isn't going to find out that and @ + are the same thing, this is good enough for many cases */ + canon_flags = SASL_CU_AUTHZID; + } + + result = params->canon_user(params->utils->conn, + authen, + 0, + SASL_CU_AUTHID | canon_flags | SASL_CU_EXTERNALLY_VERIFIED, + oparams); + if (result != SASL_OK) { + _plug_free_string(params->utils, &passcopy); + return result; + } + + /* verify password (and possibly fetch both authentication and + authorization identity related properties) - return SASL_OK + on success */ + result = params->utils->checkpass(params->utils->conn, + oparams->authid, + oparams->alen, + passcopy, + password_len); + + _plug_free_string(params->utils, &passcopy); + + if (result != SASL_OK) { + params->utils->seterror(params->utils->conn, 0, + "Password verification failed"); + return result; + } + + /* Canonicalize and store the authorization ID */ + /* We need to do this after calling verify_user just in case verify_user + * needed to get auxprops itself */ + if (canon_flags == 0) { + const struct propval *pr; + int i; + + pr = params->utils->prop_get(params->propctx); + if (!pr) { + return SASL_FAIL; + } + + /* params->utils->checkpass() might have fetched authorization identity related properties + for the wrong user name. Free these values. */ + for (i = 0; pr[i].name; i++) { + if (pr[i].name[0] == '*') { + continue; + } + + if (pr[i].values) { + params->utils->prop_erase(params->propctx, pr[i].name); + } + } + + result = params->canon_user(params->utils->conn, + author, + 0, + SASL_CU_AUTHZID, + oparams); + if (result != SASL_OK) { + return result; + } + } + + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + return SASL_OK; +} + +static sasl_server_plug_t plain_server_plugins[] = +{ + { + "PLAIN", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOANONYMOUS + | SASL_SEC_PASS_CREDENTIALS, /* security_flags */ + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY, /* features */ + NULL, /* glob_context */ + &plain_server_mech_new, /* mech_new */ + &plain_server_mech_step, /* mech_step */ + NULL, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* setpass */ + NULL, /* user_query */ + NULL, /* idle */ + NULL, /* mech_avail */ + NULL /* spare */ + } +}; + +int plain_server_plug_init(const sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_SERVER_PLUG_VERSION) { + SETERROR(utils, "PLAIN version mismatch"); + return SASL_BADVERS; + } + + *out_version = SASL_SERVER_PLUG_VERSION; + *pluglist = plain_server_plugins; + *plugcount = 1; + + return SASL_OK; +} + +/***************************** Client Section *****************************/ + +typedef struct client_context { + char *out_buf; + unsigned out_buf_len; +} client_context_t; + +static int plain_client_mech_new(void *glob_context __attribute__((unused)), + sasl_client_params_t *params, + void **conn_context) +{ + client_context_t *text; + + /* holds state are in */ + text = params->utils->malloc(sizeof(client_context_t)); + if (text == NULL) { + MEMERROR( params->utils ); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(client_context_t)); + + *conn_context = text; + + return SASL_OK; +} + +static int plain_client_mech_step(void *conn_context, + sasl_client_params_t *params, + const char *serverin __attribute__((unused)), + unsigned serverinlen __attribute__((unused)), + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + client_context_t *text = (client_context_t *) conn_context; + const char *user = NULL, *authid = NULL; + sasl_secret_t *password = NULL; + unsigned int free_password = 0; /* set if we need to free password */ + int user_result = SASL_OK; + int auth_result = SASL_OK; + int pass_result = SASL_OK; + int result; + char *p; + + *clientout = NULL; + *clientoutlen = 0; + + /* doesn't really matter how the server responds */ + + /* check if sec layer strong enough */ + if (params->props.min_ssf > params->external_ssf) { + SETERROR( params->utils, "SSF requested of PLAIN plugin"); + return SASL_TOOWEAK; + } + + /* try to get the authid */ + if (oparams->authid == NULL) { + auth_result = _plug_get_authid(params->utils, &authid, prompt_need); + + if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT)) + return auth_result; + } + + /* try to get the userid */ + if (oparams->user == NULL) { + user_result = _plug_get_userid(params->utils, &user, prompt_need); + + if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) + return user_result; + } + + /* try to get the password */ + if (password == NULL) { + pass_result = _plug_get_password(params->utils, &password, + &free_password, prompt_need); + + if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT)) + return pass_result; + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + params->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if ((user_result == SASL_INTERACT) || (auth_result == SASL_INTERACT) || + (pass_result == SASL_INTERACT)) { + /* make the prompt list */ + result = + _plug_make_prompts(params->utils, prompt_need, + user_result == SASL_INTERACT ? + "Please enter your authorization name" : NULL, + NULL, + auth_result == SASL_INTERACT ? + "Please enter your authentication name" : NULL, + NULL, + pass_result == SASL_INTERACT ? + "Please enter your password" : NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); + if (result != SASL_OK) goto cleanup; + + return SASL_INTERACT; + } + + if (!password) { + PARAMERROR(params->utils); + return SASL_BADPARAM; + } + + if (!user || !*user) { + result = params->canon_user(params->utils->conn, authid, 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + } + else { + result = params->canon_user(params->utils->conn, user, 0, + SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) goto cleanup; + + result = params->canon_user(params->utils->conn, authid, 0, + SASL_CU_AUTHID, oparams); + } + if (result != SASL_OK) goto cleanup; + + /* send authorized id NUL authentication id NUL password */ + *clientoutlen = ((user && *user ? oparams->ulen : 0) + + 1 + oparams->alen + + 1 + password->len); + + /* remember the extra NUL on the end for stupid clients */ + result = _plug_buf_alloc(params->utils, &(text->out_buf), + &(text->out_buf_len), *clientoutlen + 1); + if (result != SASL_OK) goto cleanup; + + memset(text->out_buf, 0, *clientoutlen + 1); + p = text->out_buf; + if (user && *user) { + memcpy(p, oparams->user, oparams->ulen); + p += oparams->ulen; + } + memcpy(++p, oparams->authid, oparams->alen); + p += oparams->alen; + memcpy(++p, password->data, password->len); + + *clientout = text->out_buf; + + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + result = SASL_OK; + + cleanup: + /* free sensitive info */ + if (free_password) _plug_free_secret(params->utils, &password); + + return result; +} + +static void plain_client_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + client_context_t *text = (client_context_t *) conn_context; + + if (!text) return; + + if (text->out_buf) utils->free(text->out_buf); + + utils->free(text); +} + +static sasl_client_plug_t plain_client_plugins[] = +{ + { + "PLAIN", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOANONYMOUS + | SASL_SEC_PASS_CREDENTIALS, /* security_flags */ + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY, /* features */ + NULL, /* required_prompts */ + NULL, /* glob_context */ + &plain_client_mech_new, /* mech_new */ + &plain_client_mech_step, /* mech_step */ + &plain_client_mech_dispose, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* idle */ + NULL, /* spare */ + NULL /* spare */ + } +}; + +int plain_client_plug_init(sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_CLIENT_PLUG_VERSION) { + SETERROR(utils, "PLAIN version mismatch"); + return SASL_BADVERS; + } + + *out_version = SASL_CLIENT_PLUG_VERSION; + *pluglist = plain_client_plugins; + *plugcount = 1; + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/plain_init.c b/libs/cyrussasl/plugins/plain_init.c new file mode 100644 index 00000000..0ca8f58b --- /dev/null +++ b/libs/cyrussasl/plugins/plain_init.c @@ -0,0 +1,43 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_CLIENT_PLUG_INIT( plain ) +SASL_SERVER_PLUG_INIT( plain ) + diff --git a/libs/cyrussasl/plugins/plugin_common.c b/libs/cyrussasl/plugins/plugin_common.c new file mode 100644 index 00000000..3aa6f9ab --- /dev/null +++ b/libs/cyrussasl/plugins/plugin_common.c @@ -0,0 +1,924 @@ +/* Generic SASL plugin utility functions + * Rob Siemborski + * $Id: plugin_common.c,v 1.22 2011/09/01 14:12:18 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#ifndef macintosh +#ifdef WIN32 +# include +#else +# include +# include +# include +# include +# include +#endif /* WIN32 */ +#endif /* macintosh */ +#ifdef HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include + +#include +#include +#include + +#ifdef HAVE_INTTYPES_H +#include +#endif + +#include "plugin_common.h" + +/* translate IPv4 mapped IPv6 address to IPv4 address */ +static void sockaddr_unmapped( +#ifdef IN6_IS_ADDR_V4MAPPED + struct sockaddr *sa, socklen_t *len +#else + struct sockaddr *sa __attribute__((unused)), + socklen_t *len __attribute__((unused)) +#endif +) +{ +#ifdef IN6_IS_ADDR_V4MAPPED + struct sockaddr_in6 *sin6; + struct sockaddr_in *sin4; + uint32_t addr; + int port; + + if (sa->sa_family != AF_INET6) + return; + sin6 = (struct sockaddr_in6 *)sa; + if (!IN6_IS_ADDR_V4MAPPED((&sin6->sin6_addr))) + return; + sin4 = (struct sockaddr_in *)sa; + addr = *(uint32_t *)&sin6->sin6_addr.s6_addr[12]; + port = sin6->sin6_port; + memset(sin4, 0, sizeof(struct sockaddr_in)); + sin4->sin_addr.s_addr = addr; + sin4->sin_port = port; + sin4->sin_family = AF_INET; +#ifdef HAVE_SOCKADDR_SA_LEN + sin4->sin_len = sizeof(struct sockaddr_in); +#endif + *len = sizeof(struct sockaddr_in); +#else + return; +#endif +} + +int _plug_ipfromstring(const sasl_utils_t *utils, const char *addr, + struct sockaddr *out, socklen_t outlen) +{ + int i, j; + socklen_t len; + struct sockaddr_storage ss; + struct addrinfo hints, *ai = NULL; + char hbuf[NI_MAXHOST]; + + if(!utils || !addr || !out) { + if(utils) PARAMERROR( utils ); + return SASL_BADPARAM; + } + + /* Parse the address */ + for (i = 0; addr[i] != '\0' && addr[i] != ';'; i++) { + if (i >= NI_MAXHOST) { + if(utils) PARAMERROR( utils ); + return SASL_BADPARAM; + } + hbuf[i] = addr[i]; + } + hbuf[i] = '\0'; + + if (addr[i] == ';') + i++; + /* XXX/FIXME: Do we need this check? */ + for (j = i; addr[j] != '\0'; j++) + if (!isdigit((int)(addr[j]))) { + PARAMERROR( utils ); + return SASL_BADPARAM; + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = PF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST; + + if (getaddrinfo(hbuf, &addr[i], &hints, &ai) != 0) { + PARAMERROR( utils ); + return SASL_BADPARAM; + } + + len = (socklen_t) ai->ai_addrlen; + memcpy(&ss, ai->ai_addr, len); + freeaddrinfo(ai); + sockaddr_unmapped((struct sockaddr *)&ss, &len); + if (outlen < len) { + PARAMERROR( utils ); + return SASL_BUFOVER; + } + + memcpy(out, &ss, len); + + return SASL_OK; +} + +int _plug_iovec_to_buf(const sasl_utils_t *utils, const struct iovec *vec, + unsigned numiov, buffer_info_t **output) +{ + unsigned i; + int ret; + buffer_info_t *out; + char *pos; + + if(!utils || !vec || !output) { + if(utils) PARAMERROR( utils ); + return SASL_BADPARAM; + } + + if(!(*output)) { + *output = utils->malloc(sizeof(buffer_info_t)); + if(!*output) { + MEMERROR(utils); + return SASL_NOMEM; + } + memset(*output,0,sizeof(buffer_info_t)); + } + + out = *output; + + out->curlen = 0; + for(i=0; icurlen += vec[i].iov_len; + + ret = _plug_buf_alloc(utils, &out->data, &out->reallen, out->curlen); + + if(ret != SASL_OK) { + MEMERROR(utils); + return SASL_NOMEM; + } + + memset(out->data, 0, out->reallen); + pos = out->data; + + for(i=0; imalloc(newlen); + if (*rwbuf == NULL) { + *curlen = 0; + MEMERROR(utils); + return SASL_NOMEM; + } + *curlen = newlen; + } else if(*rwbuf && *curlen < newlen) { + unsigned needed = 2*(*curlen); + + while(needed < newlen) + needed *= 2; + + *rwbuf = utils->realloc(*rwbuf, needed); + if (*rwbuf == NULL) { + *curlen = 0; + MEMERROR(utils); + return SASL_NOMEM; + } + *curlen = needed; + } + + return SASL_OK; +} + +/* copy a string */ +int _plug_strdup(const sasl_utils_t * utils, const char *in, + char **out, int *outlen) +{ + size_t len = strlen(in); + + if(!utils || !in || !out) { + if(utils) PARAMERROR(utils); + return SASL_BADPARAM; + } + + *out = utils->malloc(len + 1); + if (!*out) { + MEMERROR(utils); + return SASL_NOMEM; + } + + strcpy((char *) *out, in); + + if (outlen) + *outlen = (int) len; + + return SASL_OK; +} + +void _plug_free_string(const sasl_utils_t *utils, char **str) +{ + size_t len; + + if (!utils || !str || !(*str)) return; + + len = strlen(*str); + + utils->erasebuffer(*str, (unsigned int) len); + utils->free(*str); + + *str=NULL; +} + +void _plug_free_secret(const sasl_utils_t *utils, sasl_secret_t **secret) +{ + if(!utils || !secret || !(*secret)) return; + + utils->erasebuffer((char *)(*secret)->data, (*secret)->len); + utils->free(*secret); + *secret = NULL; +} + +/* + * Trys to find the prompt with the lookingfor id in the prompt list + * Returns it if found. NULL otherwise + */ +sasl_interact_t *_plug_find_prompt(sasl_interact_t **promptlist, + unsigned int lookingfor) +{ + sasl_interact_t *prompt; + + if (promptlist && *promptlist) { + for (prompt = *promptlist; prompt->id != SASL_CB_LIST_END; ++prompt) { + if (prompt->id==lookingfor) + return prompt; + } + } + + return NULL; +} + +/* + * Retrieve the simple string given by the callback id. + */ +int _plug_get_simple(const sasl_utils_t *utils, unsigned int id, int required, + const char **result, sasl_interact_t **prompt_need) +{ + + int ret = SASL_FAIL; + sasl_getsimple_t *simple_cb; + void *simple_context; + sasl_interact_t *prompt; + + *result = NULL; + + /* see if we were given the result in the prompt */ + prompt = _plug_find_prompt(prompt_need, id); + if (prompt != NULL) { + /* We prompted, and got.*/ + + if (required && !prompt->result) { + SETERROR(utils, "Unexpectedly missing a prompt result"); + return SASL_BADPARAM; + } + + *result = prompt->result; + return SASL_OK; + } + + /* Try to get the callback... */ + ret = utils->getcallback(utils->conn, id, (sasl_callback_ft *)&simple_cb, &simple_context); + + if (ret == SASL_FAIL && !required) + return SASL_OK; + + if (ret == SASL_OK && simple_cb) { + ret = simple_cb(simple_context, id, result, NULL); + if (ret != SASL_OK) + return ret; + + if (required && !*result) { + PARAMERROR(utils); + return SASL_BADPARAM; + } + } + + return ret; +} + +/* + * Retrieve the user password. + */ +int _plug_get_password(const sasl_utils_t *utils, sasl_secret_t **password, + unsigned int *iscopy, sasl_interact_t **prompt_need) +{ + int ret = SASL_FAIL; + sasl_getsecret_t *pass_cb; + void *pass_context; + sasl_interact_t *prompt; + + *password = NULL; + *iscopy = 0; + + /* see if we were given the password in the prompt */ + prompt = _plug_find_prompt(prompt_need, SASL_CB_PASS); + if (prompt != NULL) { + /* We prompted, and got.*/ + + if (!prompt->result) { + SETERROR(utils, "Unexpectedly missing a prompt result"); + return SASL_BADPARAM; + } + + /* copy what we got into a secret_t */ + *password = (sasl_secret_t *) utils->malloc(sizeof(sasl_secret_t) + + prompt->len + 1); + if (!*password) { + MEMERROR(utils); + return SASL_NOMEM; + } + + (*password)->len=prompt->len; + memcpy((*password)->data, prompt->result, prompt->len); + (*password)->data[(*password)->len]=0; + + *iscopy = 1; + + return SASL_OK; + } + + /* Try to get the callback... */ + ret = utils->getcallback(utils->conn, SASL_CB_PASS, + (sasl_callback_ft *)&pass_cb, &pass_context); + + if (ret == SASL_OK && pass_cb) { + ret = pass_cb(utils->conn, pass_context, SASL_CB_PASS, password); + if (ret != SASL_OK) + return ret; + + if (!*password) { + PARAMERROR(utils); + return SASL_BADPARAM; + } + } + + return ret; +} + +/* + * Retrieve the string given by the challenge prompt id. + */ +int _plug_challenge_prompt(const sasl_utils_t *utils, unsigned int id, + const char *challenge, const char *promptstr, + const char **result, sasl_interact_t **prompt_need) +{ + int ret = SASL_FAIL; + sasl_chalprompt_t *chalprompt_cb; + void *chalprompt_context; + sasl_interact_t *prompt; + + *result = NULL; + + /* see if we were given the password in the prompt */ + prompt = _plug_find_prompt(prompt_need, id); + if (prompt != NULL) { + /* We prompted, and got.*/ + + if (!prompt->result) { + SETERROR(utils, "Unexpectedly missing a prompt result"); + return SASL_BADPARAM; + } + + *result = prompt->result; + return SASL_OK; + } + + /* Try to get the callback... */ + ret = utils->getcallback(utils->conn, id, + (sasl_callback_ft *)&chalprompt_cb, &chalprompt_context); + + if (ret == SASL_OK && chalprompt_cb) { + ret = chalprompt_cb(chalprompt_context, id, + challenge, promptstr, NULL, result, NULL); + if (ret != SASL_OK) + return ret; + + if (!*result) { + PARAMERROR(utils); + return SASL_BADPARAM; + } + } + + return ret; +} + +/* + * Retrieve the client realm. + */ +int _plug_get_realm(const sasl_utils_t *utils, const char **availrealms, + const char **realm, sasl_interact_t **prompt_need) +{ + int ret = SASL_FAIL; + sasl_getrealm_t *realm_cb; + void *realm_context; + sasl_interact_t *prompt; + + *realm = NULL; + + /* see if we were given the result in the prompt */ + prompt = _plug_find_prompt(prompt_need, SASL_CB_GETREALM); + if (prompt != NULL) { + /* We prompted, and got.*/ + + if (!prompt->result) { + SETERROR(utils, "Unexpectedly missing a prompt result"); + return SASL_BADPARAM; + } + + *realm = prompt->result; + return SASL_OK; + } + + /* Try to get the callback... */ + ret = utils->getcallback(utils->conn, SASL_CB_GETREALM, + (sasl_callback_ft *)&realm_cb, &realm_context); + + if (ret == SASL_OK && realm_cb) { + ret = realm_cb(realm_context, SASL_CB_GETREALM, availrealms, realm); + if (ret != SASL_OK) + return ret; + + if (!*realm) { + PARAMERROR(utils); + return SASL_BADPARAM; + } + } + + return ret; +} + +/* + * Make the requested prompts. (prompt==NULL means we don't want it) + */ +int _plug_make_prompts(const sasl_utils_t *utils, + sasl_interact_t **prompts_res, + const char *user_prompt, const char *user_def, + const char *auth_prompt, const char *auth_def, + const char *pass_prompt, const char *pass_def, + const char *echo_chal, + const char *echo_prompt, const char *echo_def, + const char *realm_chal, + const char *realm_prompt, const char *realm_def) +{ + int num = 1; + int alloc_size; + sasl_interact_t *prompts; + + if (user_prompt) num++; + if (auth_prompt) num++; + if (pass_prompt) num++; + if (echo_prompt) num++; + if (realm_prompt) num++; + + if (num == 1) { + SETERROR( utils, "make_prompts() called with no actual prompts" ); + return SASL_FAIL; + } + + alloc_size = sizeof(sasl_interact_t)*num; + prompts = utils->malloc(alloc_size); + if (!prompts) { + MEMERROR( utils ); + return SASL_NOMEM; + } + memset(prompts, 0, alloc_size); + + *prompts_res = prompts; + + if (user_prompt) { + (prompts)->id = SASL_CB_USER; + (prompts)->challenge = "Authorization Name"; + (prompts)->prompt = user_prompt; + (prompts)->defresult = user_def; + + prompts++; + } + + if (auth_prompt) { + (prompts)->id = SASL_CB_AUTHNAME; + (prompts)->challenge = "Authentication Name"; + (prompts)->prompt = auth_prompt; + (prompts)->defresult = auth_def; + + prompts++; + } + + if (pass_prompt) { + (prompts)->id = SASL_CB_PASS; + (prompts)->challenge = "Password"; + (prompts)->prompt = pass_prompt; + (prompts)->defresult = pass_def; + + prompts++; + } + + if (echo_prompt) { + (prompts)->id = SASL_CB_ECHOPROMPT; + (prompts)->challenge = echo_chal; + (prompts)->prompt = echo_prompt; + (prompts)->defresult = echo_def; + + prompts++; + } + + if (realm_prompt) { + (prompts)->id = SASL_CB_GETREALM; + (prompts)->challenge = realm_chal; + (prompts)->prompt = realm_prompt; + (prompts)->defresult = realm_def; + + prompts++; + } + + /* add the ending one */ + (prompts)->id = SASL_CB_LIST_END; + (prompts)->challenge = NULL; + (prompts)->prompt = NULL; + (prompts)->defresult = NULL; + + return SASL_OK; +} + +void _plug_decode_init(decode_context_t *text, + const sasl_utils_t *utils, unsigned int in_maxbuf) +{ + memset(text, 0, sizeof(decode_context_t)); + + text->utils = utils; + text->needsize = 4; + text->in_maxbuf = in_maxbuf; +} + +/* + * Decode as much of the input as possible (possibly none), + * using decode_pkt() to decode individual packets. + */ +int _plug_decode(decode_context_t *text, + const char *input, unsigned inputlen, + char **output, /* output buffer */ + unsigned *outputsize, /* current size of output buffer */ + unsigned *outputlen, /* length of data in output buffer */ + int (*decode_pkt)(void *rock, + const char *input, unsigned inputlen, + char **output, unsigned *outputlen), + void *rock) +{ + unsigned int tocopy; + unsigned diff; + char *tmp; + unsigned tmplen; + int ret; + + *outputlen = 0; + + while (inputlen) { /* more input */ + if (text->needsize) { /* need to get the rest of the 4-byte size */ + + /* copy as many bytes (up to 4) as we have into size buffer */ + tocopy = (inputlen > text->needsize) ? text->needsize : inputlen; + memcpy(text->sizebuf + 4 - text->needsize, input, tocopy); + text->needsize -= tocopy; + + input += tocopy; + inputlen -= tocopy; + + if (!text->needsize) { /* we have the entire 4-byte size */ + memcpy(&(text->size), text->sizebuf, 4); + text->size = ntohl(text->size); + + if (!text->size) /* should never happen */ + return SASL_FAIL; + + if (text->size > text->in_maxbuf) { + text->utils->log(NULL, SASL_LOG_ERR, + "encoded packet size too big (%d > %d)", + text->size, text->in_maxbuf); + return SASL_FAIL; + } + + if (!text->buffer) + text->buffer = text->utils->malloc(text->in_maxbuf); + if (text->buffer == NULL) return SASL_NOMEM; + + text->cursize = 0; + } else { + /* We do NOT have the entire 4-byte size... + * wait for more data */ + return SASL_OK; + } + } + + diff = text->size - text->cursize; /* bytes needed for full packet */ + + if (inputlen < diff) { /* not a complete packet, need more input */ + memcpy(text->buffer + text->cursize, input, inputlen); + text->cursize += inputlen; + return SASL_OK; + } + + /* copy the rest of the packet */ + memcpy(text->buffer + text->cursize, input, diff); + input += diff; + inputlen -= diff; + + /* decode the packet (no need to free tmp) */ + ret = decode_pkt(rock, text->buffer, text->size, &tmp, &tmplen); + if (ret != SASL_OK) return ret; + + /* append the decoded packet to the output */ + ret = _plug_buf_alloc(text->utils, output, outputsize, + *outputlen + tmplen + 1); /* +1 for NUL */ + if (ret != SASL_OK) return ret; + + memcpy(*output + *outputlen, tmp, tmplen); + *outputlen += tmplen; + + /* protect stupid clients */ + *(*output + *outputlen) = '\0'; + + /* reset for the next packet */ + text->needsize = 4; + } + + return SASL_OK; +} + +void _plug_decode_free(decode_context_t *text) +{ + if (text->buffer) text->utils->free(text->buffer); +} + +/* returns the realm we should pretend to be in */ +int _plug_parseuser(const sasl_utils_t *utils, + char **user, char **realm, const char *user_realm, + const char *serverFQDN, const char *input) +{ + int ret; + char *r; + + if(!user || !serverFQDN) { + PARAMERROR( utils ); + return SASL_BADPARAM; + } + + r = strchr(input, '@'); + if (!r) { + /* hmmm, the user didn't specify a realm */ + if(user_realm && user_realm[0]) { + ret = _plug_strdup(utils, user_realm, realm, NULL); + } else { + /* Default to serverFQDN */ + ret = _plug_strdup(utils, serverFQDN, realm, NULL); + } + + if (ret == SASL_OK) { + ret = _plug_strdup(utils, input, user, NULL); + } + } else { + r++; + ret = _plug_strdup(utils, r, realm, NULL); + *--r = '\0'; + *user = utils->malloc(r - input + 1); + if (*user) { + strncpy(*user, input, r - input +1); + } else { + MEMERROR( utils ); + ret = SASL_NOMEM; + } + *r = '@'; + } + + return ret; +} + +int _plug_make_fulluser(const sasl_utils_t *utils, + char **fulluser, + const char * useronly, + const char *realm) +{ + if(!fulluser || !useronly || !realm) { + PARAMERROR( utils ); + return (SASL_BADPARAM); + } + + *fulluser = utils->malloc (strlen(useronly) + strlen(realm) + 2); + if (*fulluser == NULL) { + MEMERROR( utils ); + return (SASL_NOMEM); + } + + strcpy (*fulluser, useronly); + strcat (*fulluser, "@"); + strcat (*fulluser, realm); + + return (SASL_OK); +} + +char * _plug_get_error_message (const sasl_utils_t *utils, +#ifdef WIN32 + DWORD error +#else + int error +#endif + ) +{ + char * return_value; +#ifdef WIN32 + LPVOID lpMsgBuf; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */ + (LPTSTR) &lpMsgBuf, + 0, + NULL + ); + + if (_plug_strdup (utils, lpMsgBuf, &return_value, NULL) != SASL_OK) { + return_value = NULL; + } + + LocalFree( lpMsgBuf ); +#else /* !WIN32 */ + if (_plug_strdup (utils, strerror(error), &return_value, NULL) != SASL_OK) { + return_value = NULL; + } +#endif /* WIN32 */ + return (return_value); +} + +void _plug_snprintf_os_info (char * osbuf, int osbuf_len) +{ +#ifdef WIN32 + OSVERSIONINFOEX versioninfo; + char *sysname; + +/* : + DWORD dwOSVersionInfoSize; + DWORD dwMajorVersion; + DWORD dwMinorVersion; + DWORD dwBuildNumber; + TCHAR szCSDVersion[ 128 ]; +//Only NT SP 6 and later + WORD wServicePackMajor; + WORD wServicePackMinor; + WORD wSuiteMask; + BYTE wProductType; + */ + + versioninfo.dwOSVersionInfoSize = sizeof (versioninfo); + sysname = "Unknown Windows"; + + if (GetVersionEx ((OSVERSIONINFO *) &versioninfo) == FALSE) { + snprintf(osbuf, osbuf_len, "%s", sysname); + goto SKIP_OS_INFO; + } + + switch (versioninfo.dwPlatformId) { + case VER_PLATFORM_WIN32s: /* Win32s on Windows 3.1 */ + sysname = "Win32s on Windows 3.1"; +/* I can't test if dwBuildNumber has any meaning on Win32s */ + break; + + case VER_PLATFORM_WIN32_WINDOWS: /* 95/98/ME */ + switch (versioninfo.dwMinorVersion) { + case 0: + sysname = "Windows 95"; + break; + case 10: + sysname = "Windows 98"; + break; + case 90: + sysname = "Windows Me"; + break; + default: + sysname = "Unknown Windows 9X/ME series"; + break; + } +/* Clear the high order word, as it contains major/minor version */ + versioninfo.dwBuildNumber &= 0xFFFF; + break; + + case VER_PLATFORM_WIN32_NT: /* NT/2000/XP/.NET */ + if (versioninfo.dwMinorVersion > 99) { + } else { + switch (versioninfo.dwMajorVersion * 100 + versioninfo.dwMinorVersion) { + case 351: + sysname = "Windows NT 3.51"; + break; + case 400: + sysname = "Windows NT 4.0"; + break; + case 500: + sysname = "Windows 2000"; + break; + case 501: + sysname = "Windows XP/.NET"; /* or Windows .NET Server */ + break; + default: + sysname = "Unknown Windows NT series"; + break; + } + } + break; + + default: + break; + } + + snprintf(osbuf, osbuf_len, + "%s %s (Build %u)", + sysname, + versioninfo.szCSDVersion, + versioninfo.dwBuildNumber + ); + +SKIP_OS_INFO: + ; + +#else /* !WIN32 */ + struct utsname os; + + uname(&os); + snprintf(osbuf, osbuf_len, "%s %s", os.sysname, os.release); +#endif /* WIN32 */ +} + +#if defined(WIN32) +unsigned int plug_sleep (unsigned int seconds) +{ + long dwSec = seconds*1000; + Sleep (dwSec); + return 0; +} +#endif diff --git a/libs/cyrussasl/plugins/plugin_common.h b/libs/cyrussasl/plugins/plugin_common.h new file mode 100644 index 00000000..0f758975 --- /dev/null +++ b/libs/cyrussasl/plugins/plugin_common.h @@ -0,0 +1,222 @@ + +/* Generic SASL plugin utility functions + * Rob Siemborski + * $Id: plugin_common.h,v 1.21 2006/01/17 12:18:21 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _PLUGIN_COMMON_H_ +#define _PLUGIN_COMMON_H_ + +#include + +#ifndef macintosh +#ifdef WIN32 +# include +#else +# include +# include +# include +# include +#endif /* WIN32 */ +#endif /* macintosh */ + +#include +#include +#include + +#ifdef WIN32 +#define PLUG_API __declspec(dllexport) +#else +#define PLUG_API extern +#endif + +#define SASL_CLIENT_PLUG_INIT( x ) \ +extern sasl_client_plug_init_t x##_client_plug_init; \ +PLUG_API int sasl_client_plug_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_client_plug_t **pluglist, \ + int *plugcount) { \ + return x##_client_plug_init(utils, maxversion, out_version, \ + pluglist, plugcount); \ +} + +#define SASL_SERVER_PLUG_INIT( x ) \ +extern sasl_server_plug_init_t x##_server_plug_init; \ +PLUG_API int sasl_server_plug_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_server_plug_t **pluglist, \ + int *plugcount) { \ + return x##_server_plug_init(utils, maxversion, out_version, \ + pluglist, plugcount); \ +} + +#define SASL_AUXPROP_PLUG_INIT( x ) \ +extern sasl_auxprop_init_t x##_auxprop_plug_init; \ +PLUG_API int sasl_auxprop_plug_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_auxprop_plug_t **plug, \ + const char *plugname) {\ + return x##_auxprop_plug_init(utils, maxversion, out_version, \ + plug, plugname); \ +} + +#define SASL_CANONUSER_PLUG_INIT( x ) \ +extern sasl_canonuser_init_t x##_canonuser_plug_init; \ +PLUG_API int sasl_canonuser_init(const sasl_utils_t *utils, \ + int maxversion, int *out_version, \ + sasl_canonuser_plug_t **plug, \ + const char *plugname) {\ + return x##_canonuser_plug_init(utils, maxversion, out_version, \ + plug, plugname); \ +} + +/* note: msg cannot include additional variables, so if you want to + * do a printf-format string, then you need to call seterror yourself */ +#define SETERROR( utils, msg ) (utils)->seterror( (utils)->conn, 0, (msg) ) + +#ifndef MEMERROR +#define MEMERROR( utils ) \ + (utils)->seterror( (utils)->conn, 0, \ + "Out of Memory in " __FILE__ " near line %d", __LINE__ ) +#endif + +#ifndef PARAMERROR +#define PARAMERROR( utils ) \ + (utils)->seterror( (utils)->conn, 0, \ + "Parameter Error in " __FILE__ " near line %d", __LINE__ ) +#endif + +#ifndef SASLINT_H +typedef struct buffer_info +{ + char *data; + unsigned curlen; /* Current length of data in buffer */ + unsigned reallen; /* total length of buffer (>= curlen) */ +} buffer_info_t; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +int _plug_ipfromstring(const sasl_utils_t *utils, const char *addr, + struct sockaddr *out, socklen_t outlen); +int _plug_iovec_to_buf(const sasl_utils_t *utils, const struct iovec *vec, + unsigned numiov, buffer_info_t **output); +int _plug_buf_alloc(const sasl_utils_t *utils, char **rwbuf, + unsigned *curlen, unsigned newlen); +int _plug_strdup(const sasl_utils_t * utils, const char *in, + char **out, int *outlen); +void _plug_free_string(const sasl_utils_t *utils, char **str); +void _plug_free_secret(const sasl_utils_t *utils, sasl_secret_t **secret); + +#define _plug_get_userid(utils, result, prompt_need) \ + _plug_get_simple(utils, SASL_CB_USER, 0, result, prompt_need) +#define _plug_get_authid(utils, result, prompt_need) \ + _plug_get_simple(utils, SASL_CB_AUTHNAME, 1, result, prompt_need) +int _plug_get_simple(const sasl_utils_t *utils, unsigned int id, int required, + const char **result, sasl_interact_t **prompt_need); + +int _plug_get_password(const sasl_utils_t *utils, sasl_secret_t **secret, + unsigned int *iscopy, sasl_interact_t **prompt_need); + +int _plug_challenge_prompt(const sasl_utils_t *utils, unsigned int id, + const char *challenge, const char *promptstr, + const char **result, sasl_interact_t **prompt_need); + +int _plug_get_realm(const sasl_utils_t *utils, const char **availrealms, + const char **realm, sasl_interact_t **prompt_need); + +int _plug_make_prompts(const sasl_utils_t *utils, + sasl_interact_t **prompts_res, + const char *user_prompt, const char *user_def, + const char *auth_prompt, const char *auth_def, + const char *pass_prompt, const char *pass_def, + const char *echo_chal, + const char *echo_prompt, const char *echo_def, + const char *realm_chal, + const char *realm_prompt, const char *realm_def); + +typedef struct decode_context { + const sasl_utils_t *utils; + unsigned int needsize; /* How much of the 4-byte size do we need? */ + char sizebuf[4]; /* Buffer to accumulate the 4-byte size */ + unsigned int size; /* Absolute size of the encoded packet */ + char *buffer; /* Buffer to accumulate an encoded packet */ + unsigned int cursize; /* Amount of packet data in the buffer */ + unsigned int in_maxbuf; /* Maximum allowed size of an incoming encoded packet */ +} decode_context_t; + +void _plug_decode_init(decode_context_t *text, + const sasl_utils_t *utils, unsigned int in_maxbuf); + +int _plug_decode(decode_context_t *text, + const char *input, unsigned inputlen, + char **output, unsigned *outputsize, unsigned *outputlen, + int (*decode_pkt)(void *rock, + const char *input, unsigned inputlen, + char **output, unsigned *outputlen), + void *rock); + +void _plug_decode_free(decode_context_t *text); + +int _plug_parseuser(const sasl_utils_t *utils, + char **user, char **realm, const char *user_realm, + const char *serverFQDN, const char *input); + +int _plug_make_fulluser(const sasl_utils_t *utils, + char **fulluser, const char * useronly, const char *realm); + +char * _plug_get_error_message (const sasl_utils_t *utils, +#ifdef WIN32 + DWORD error +#else + int error +#endif + ); +void _plug_snprintf_os_info (char * osbuf, int osbuf_len); + +#ifdef __cplusplus +} +#endif + +#endif /* _PLUGIN_COMMON_H_ */ diff --git a/libs/cyrussasl/plugins/sasldb.c b/libs/cyrussasl/plugins/sasldb.c new file mode 100644 index 00000000..1edbb8be --- /dev/null +++ b/libs/cyrussasl/plugins/sasldb.c @@ -0,0 +1,317 @@ +/* SASL server API implementation + * Rob Siemborski + * Tim Martin + * $Id: sasldb.c,v 1.17 2009/03/10 14:37:03 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +/* sasldb stuff */ + +#include + +#include "sasl.h" +#include "saslutil.h" +#include "saslplug.h" +#include "../sasldb/sasldb.h" + +#include "plugin_common.h" + +static int sasldb_auxprop_lookup(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + unsigned flags, + const char *user, + unsigned ulen) +{ + char *userid = NULL; + char *realm = NULL; + const char *user_realm = NULL; + int ret; + const struct propval *to_fetch, *cur; + char value[8192]; + size_t value_len; + char *user_buf; + int verify_against_hashed_password; + int saw_user_password = 0; + + if (!sparams || !user) return SASL_BADPARAM; + + user_buf = sparams->utils->malloc(ulen + 1); + if(!user_buf) { + ret = SASL_NOMEM; + goto done; + } + + memcpy(user_buf, user, ulen); + user_buf[ulen] = '\0'; + + if(sparams->user_realm) { + user_realm = sparams->user_realm; + } else { + user_realm = sparams->serverFQDN; + } + + ret = _plug_parseuser(sparams->utils, &userid, &realm, user_realm, + sparams->serverFQDN, user_buf); + if(ret != SASL_OK) goto done; + + to_fetch = sparams->utils->prop_get(sparams->propctx); + if (!to_fetch) { + ret = SASL_NOMEM; + goto done; + } + + verify_against_hashed_password = flags & SASL_AUXPROP_VERIFY_AGAINST_HASH; + + /* Use a fake value to signal that we have no property to lookup */ + ret = SASL_CONTINUE; + for(cur = to_fetch; cur->name; cur++) { + int cur_ret; + const char *realname = cur->name; + + /* Only look up properties that apply to this lookup! */ + if(cur->name[0] == '*' && (flags & SASL_AUXPROP_AUTHZID)) continue; + if(!(flags & SASL_AUXPROP_AUTHZID)) { + if(cur->name[0] != '*') continue; + else realname = cur->name + 1; + } + + /* If it's there already, we want to see if it needs to be + * overridden. userPassword is a special case, because it's value + is always present if SASL_AUXPROP_VERIFY_AGAINST_HASH is specified. + When SASL_AUXPROP_VERIFY_AGAINST_HASH is set, we just clear userPassword. */ + if (cur->values && !(flags & SASL_AUXPROP_OVERRIDE) && + (verify_against_hashed_password == 0 || + strcasecmp(realname, SASL_AUX_PASSWORD_PROP) != 0)) { + continue; + } else if (cur->values) { + sparams->utils->prop_erase(sparams->propctx, cur->name); + } + + if (strcasecmp(realname, SASL_AUX_PASSWORD_PROP) == 0) { + saw_user_password = 1; + } + + cur_ret = _sasldb_getdata(sparams->utils, + sparams->utils->conn, userid, realm, + realname, value, sizeof(value), &value_len); + + /* Assumption: cur_ret is never SASL_CONTINUE */ + + /* If this is the first property we've tried to fetch ==> + always set the global error code. + If we had SASL_NOUSER ==> any other error code overrides it + (including SASL_NOUSER). */ + if (ret == SASL_CONTINUE || ret == SASL_NOUSER) { + ret = cur_ret; + } else if (ret == SASL_OK) { + /* Any error code other than SASL_NOUSER overrides SASL_OK. + (And SASL_OK overrides SASL_OK as well) */ + if (cur_ret != SASL_NOUSER) { + ret = cur_ret; + } + } + /* Any other global error code is left as is */ + + if (cur_ret != SASL_OK) { + if (cur_ret != SASL_NOUSER) { + /* No point in continuing if we hit any serious error */ + break; + } + /* We didn't find it, leave it as not found */ + continue; + } + + sparams->utils->prop_set(sparams->propctx, cur->name, + value, (unsigned) value_len); + } + + /* [Keep in sync with LDAPDB, SQL] + If ret is SASL_CONTINUE, it means that no properties were requested + (or maybe some were requested, but they already have values and + SASL_AUXPROP_OVERRIDE flag is not set). + Always return SASL_OK in this case. */ + if (ret == SASL_CONTINUE) { + ret = SASL_OK; + } + + if (flags & SASL_AUXPROP_AUTHZID) { + /* This is a lie, but the caller can't handle + when we return SASL_NOUSER for authorization identity lookup. */ + if (ret == SASL_NOUSER) { + ret = SASL_OK; + } + } else { + if (ret == SASL_NOUSER && saw_user_password == 0) { + /* Verify user existence by checking presence of + the userPassword attribute */ + ret = _sasldb_getdata(sparams->utils, + sparams->utils->conn, + userid, + realm, + SASL_AUX_PASSWORD_PROP, + value, + sizeof(value), + &value_len); + } + } + + done: + if (userid) sparams->utils->free(userid); + if (realm) sparams->utils->free(realm); + if (user_buf) sparams->utils->free(user_buf); + + return ret; +} + +static int sasldb_auxprop_store(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + struct propctx *ctx, + const char *user, + unsigned ulen) +{ + char *userid = NULL; + char *realm = NULL; + const char *user_realm = NULL; + int ret = SASL_FAIL; + const struct propval *to_store, *cur; + char *user_buf; + + /* just checking if we are enabled */ + if(!ctx) return SASL_OK; + + if(!sparams || !user) return SASL_BADPARAM; + + user_buf = sparams->utils->malloc(ulen + 1); + if(!user_buf) { + ret = SASL_NOMEM; + goto done; + } + + memcpy(user_buf, user, ulen); + user_buf[ulen] = '\0'; + + if(sparams->user_realm) { + user_realm = sparams->user_realm; + } else { + user_realm = sparams->serverFQDN; + } + + ret = _plug_parseuser(sparams->utils, &userid, &realm, user_realm, + sparams->serverFQDN, user_buf); + if(ret != SASL_OK) goto done; + + to_store = sparams->utils->prop_get(ctx); + if(!to_store) { + ret = SASL_BADPARAM; + goto done; + } + + ret = SASL_OK; + for (cur = to_store; cur->name; cur++) { + char * value = (cur->values && cur->values[0]) ? cur->values[0] : NULL; + + if (cur->name[0] == '*') { + continue; + } + + /* WARN: We only support one value right now. */ + ret = _sasldb_putdata(sparams->utils, + sparams->utils->conn, + userid, + realm, + cur->name, + value, + value ? strlen(value) : 0); + + if (value == NULL && ret == SASL_NOUSER) { + /* Deleting something which is not there is not an error */ + ret = SASL_OK; + } + + if (ret != SASL_OK) { + /* We've already failed, no point in continuing */ + break; + } + } + + done: + if (userid) sparams->utils->free(userid); + if (realm) sparams->utils->free(realm); + if (user_buf) sparams->utils->free(user_buf); + + return ret; +} + +static sasl_auxprop_plug_t sasldb_auxprop_plugin = { + 0, /* Features */ + 0, /* spare */ + NULL, /* glob_context */ + sasldb_auxprop_free, /* auxprop_free */ + sasldb_auxprop_lookup, /* auxprop_lookup */ + "sasldb", /* name */ + sasldb_auxprop_store /* auxprop_store */ +}; + +int sasldb_auxprop_plug_init(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_auxprop_plug_t **plug, + const char *plugname __attribute__((unused))) +{ + if(!out_version || !plug) return SASL_BADPARAM; + + /* Do we have database support? */ + /* Note that we can use a NULL sasl_conn_t because our + * sasl_utils_t is "blessed" with the global callbacks */ + if(_sasl_check_db(utils, NULL) != SASL_OK) + return SASL_NOMECH; + + /* Check if libsasl API is older than ours. If it is, fail */ + if(max_version < SASL_AUXPROP_PLUG_VERSION) return SASL_BADVERS; + + *out_version = SASL_AUXPROP_PLUG_VERSION; + + *plug = &sasldb_auxprop_plugin; + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/sasldb_init.c b/libs/cyrussasl/plugins/sasldb_init.c new file mode 100644 index 00000000..c75e1a89 --- /dev/null +++ b/libs/cyrussasl/plugins/sasldb_init.c @@ -0,0 +1,38 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_AUXPROP_PLUG_INIT( sasldb ) + diff --git a/libs/cyrussasl/plugins/scram.c b/libs/cyrussasl/plugins/scram.c new file mode 100644 index 00000000..62a101c9 --- /dev/null +++ b/libs/cyrussasl/plugins/scram.c @@ -0,0 +1,2722 @@ +/* SCRAM-SHA-1 SASL plugin + * Alexey Melnikov + * $Id: scram.c,v 1.26 2011/09/07 16:09:40 murch Exp $ + */ +/* + * Copyright (c) 2009-2010 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +#include +#include +#include + +/***************************** Common Section *****************************/ + +static const char plugin_id[] = "$Id: scram.c,v 1.26 2011/09/07 16:09:40 murch Exp $"; + +#define NONCE_SIZE (32) /* arbitrary */ +#define SALT_SIZE (16) /* arbitrary */ + +/* TODO: make this a configurable option? */ +#define DEFAULT_ITERATION_COUNTER 4096 +#define MIN_ITERATION_COUNTER 4096 + +#define MAX_ITERATION_COUNTER 0x10000 + +/* maximum length of the iteration_counter (as a string). Assume it is 32bits */ +#define ITERATION_COUNTER_BUF_LEN 20 + +#define SCRAM_HASH_SIZE 20 + +#define BASE64_LEN(size) (((size) / 3 * 4) + (((size) % 3) ? 4 : 0)) + +#define MAX_CLIENTIN_LEN 2048 +#define MAX_SERVERIN_LEN 2048 + +#define STRINGIZE(x) #x +#define MAX_CLIENTIN_LEN_STR STRINGIZE((MAX_CLIENTIN_LEN)) +#define MAX_SERVERIN_LEN_STR STRINGIZE((MAX_SERVERIN_LEN)) + +#define CLIENT_KEY_CONSTANT "Client Key" +#define SERVER_KEY_CONSTANT "Server Key" +#define CLIENT_KEY_CONSTANT_LEN sizeof(CLIENT_KEY_CONSTANT)-1 +#define SERVER_KEY_CONSTANT_LEN sizeof(SERVER_KEY_CONSTANT)-1 + +#define SCRAM_CB_FLAG_MASK 0x0F +#define SCRAM_CB_FLAG_N 0x00 +#define SCRAM_CB_FLAG_P 0x01 +#define SCRAM_CB_FLAG_Y 0x02 + +#ifdef SCRAM_DEBUG +#define PRINT_HASH(func,hash) print_hash(func,hash) +#else +#define PRINT_HASH(func,hash) +#endif + +/* NB: A temporary mapping for "internal errors". It would be better to add + a new SASL error code for that */ +#define SASL_SCRAM_INTERNAL SASL_NOMEM + + +#define SCRAM_SASL_MECH "SCRAM-SHA-1" +#define SCRAM_SASL_MECH_LEN 11 + +/* Holds the core salt to avoid regenerating salt each auth. */ +static unsigned char g_salt_key[SALT_SIZE]; + +/* Convert saslname = 1*(value-safe-char / "=2C" / "=3D") in place. + Returns SASL_FAIL if the encoding is invalid, otherwise SASL_OK */ +static int +decode_saslname (char *buf) +{ + char * inp; + char * outp; + + inp = outp = buf; + + while (*inp) { + if (*inp == '=') { + inp++; + if (*inp == '\0') { + return SASL_FAIL; + } + if (inp[0] == '2' && inp[1] == 'C') { + *outp = ','; + inp += 2; + } else if (inp[0] == '3' && inp[1] == 'D') { + *outp = '='; + inp += 2; + } else { + return SASL_FAIL; + } + } else { + *outp = *inp; + inp++; + } + outp++; + } + + return SASL_OK; +} + +/* Convert a username to saslname = 1*(value-safe-char / "=2C" / "=3D") + and return an allocated copy. + "freeme" contains pointer to the allocated output, or NULL, + if encoded_saslname just points to saslname. + Returns SASL_NOMEM if can't allocate memory for the output, otherwise SASL_OK */ +static int +encode_saslname (const char *saslname, + const char **encoded_saslname, + char **freeme) +{ + const char * inp; + char * outp; + int special_chars = 0; + + /* Found out if anything needs encoding */ + for (inp = saslname; *inp; inp++) { + if (*inp == ',' || *inp == '=') { + special_chars++; + } + } + + if (special_chars == 0) { + *encoded_saslname = saslname; + *freeme = NULL; + return SASL_OK; + } + + outp = malloc(strlen(saslname) + special_chars * 2 + 1); + *encoded_saslname = outp; + *freeme = outp; + if (outp == NULL) { + return SASL_NOMEM; + } + + for (inp = saslname; *inp; inp++) { + switch (*inp) { + case ',': + *outp++ = '='; + *outp++ = '2'; + *outp++ = 'C'; + break; + + case '=': + *outp++ = '='; + *outp++ = '3'; + *outp++ = 'D'; + break; + + default: + *outp++ = *inp; + } + } + + *outp = '\0'; + + return SASL_OK; +} + +static char * +create_nonce(const sasl_utils_t * utils, + char *buffer, + size_t buflen) /* Including the terminating NUL */ +{ + char *intbuf; + unsigned int estimated; + + if ((buflen - 1) % 4 != 0) { + /* NB: the algorithm below doesn't work for such length. + It needs to be adjusted to allocate + 4 bytes, + encode the last 4 bytes to a separate buffer and + then copy the necessary number of bytes to the end of the output */ + return NULL; + } + + estimated = (unsigned int)((buflen - 1) / 4 * 3); + intbuf = (char *) utils->malloc(estimated + 1); + if (intbuf == NULL) { + return NULL; + } + + utils->rand(utils->rpool, intbuf, estimated); + + /* base 64 encode it so it has valid chars */ + if (utils->encode64(intbuf, + estimated, + buffer, + (unsigned int)buflen, + NULL) != SASL_OK) { + utils->free(intbuf); + return NULL; + } + + utils->free(intbuf); + + buffer[buflen-1] = '\0'; + + return buffer; +} + +/* Useful for debugging interop issues */ +static void +print_hash (const char * func, const char * hash) +{ + int i; + + printf (" HASH in %s:", func); + for (i = 0; i < SCRAM_HASH_SIZE; i++) { + printf (" %.2X", (unsigned char)hash[i]); + } + printf ("\n"); +} + + +/* The result variable need to point to a buffer big enough for the [SHA-1] hash */ +static void +Hi (const sasl_utils_t * utils, + const char * str, + size_t str_len, + const char * salt, + size_t salt_len, + unsigned int iteration_count, + char * result) +{ + char * initial_key = NULL; + unsigned int i; + int k; + char * temp_result; + unsigned int hash_len = 0; + + initial_key = utils->malloc(salt_len + 4); + memcpy (initial_key, salt, salt_len); + initial_key[salt_len] = 0; + initial_key[salt_len+1] = 0; + initial_key[salt_len+2] = 0; + initial_key[salt_len+3] = 1; + + temp_result = utils->malloc(SCRAM_HASH_SIZE); + + /* U1 := HMAC(str, salt || INT(1)) */ + + if (HMAC(EVP_sha1(), + (const unsigned char *) str, + (int)str_len, + initial_key, + (int)salt_len + 4, + (unsigned char *)result, + &hash_len) == NULL) { + } + + memcpy(temp_result, result, SCRAM_HASH_SIZE); + + PRINT_HASH ("first HMAC in Hi()", temp_result); + + /* On each loop iteration j "temp_result" contains Uj, + while "result" contains "U1 XOR ... XOR Uj" */ + for (i = 2; i <= iteration_count; i++) { + if (HMAC(EVP_sha1(), + (const unsigned char *) str, + (int)str_len, + temp_result, + SCRAM_HASH_SIZE, + (unsigned char *)temp_result, + &hash_len) == NULL) { + } + + PRINT_HASH ("Hi() HMAC inside loop", temp_result); + + for (k = 0; k < SCRAM_HASH_SIZE; k++) { + result[k] ^= temp_result[k]; + } + + PRINT_HASH ("Hi() - accumulated result inside loop", result); + } + + utils->free(initial_key); + utils->free(temp_result); +} + +/** + * User salt is Hi(username,salt_key); + * This is fixed per reboot, to allow caching of SCRAM + * SaltedPassword. + */ +static unsigned char * +scram_server_user_salt(const sasl_utils_t * utils, + const char * username, + size_t * p_salt_len) +{ + char * result = utils->malloc(SCRAM_HASH_SIZE); + Hi(utils, username, strlen(username), g_salt_key, SALT_SIZE, 20 /* iterations */, result); + *p_salt_len = SCRAM_HASH_SIZE; + return result; +} + +static int +GenerateScramSecrets (const sasl_utils_t * utils, + const char * password, + size_t password_len, + char * salt, + size_t salt_len, + unsigned int iteration_count, + char * StoredKey, + char * ServerKey, + char ** error_text) +{ + char SaltedPassword[SCRAM_HASH_SIZE]; + char ClientKey[SCRAM_HASH_SIZE]; + sasl_secret_t *sec = NULL; + unsigned int hash_len = 0; + int result; + + *error_text = NULL; + + if (password_len == 0) { + *error_text = "empty secret"; + result = SASL_FAIL; + goto cleanup; + } + + sec = utils->malloc(sizeof(sasl_secret_t) + password_len); + if (sec == NULL) { + result = SASL_NOMEM; + goto cleanup; + } + + sec->len = (unsigned) password_len; + strncpy((char *)sec->data, password, password_len + 1); + + /* SaltedPassword := Hi(password, salt) */ + Hi (utils, + sec->data, + sec->len, + salt, + salt_len, + iteration_count, + SaltedPassword); + + /* ClientKey := HMAC(SaltedPassword, "Client Key") */ + if (HMAC(EVP_sha1(), + (const unsigned char *) SaltedPassword, + SCRAM_HASH_SIZE, + CLIENT_KEY_CONSTANT, + CLIENT_KEY_CONSTANT_LEN, + (unsigned char *)ClientKey, + &hash_len) == NULL) { + *error_text = "HMAC-SHA1 call failed"; + result = SASL_SCRAM_INTERNAL; + goto cleanup; + } + + /* StoredKey := H(ClientKey) */ + if (SHA1(ClientKey, SCRAM_HASH_SIZE, StoredKey) == NULL) { + *error_text = "SHA1 call failed"; + result = SASL_SCRAM_INTERNAL; + goto cleanup; + + } + + /* ServerKey := HMAC(SaltedPassword, "Server Key") */ + if (HMAC(EVP_sha1(), + (const unsigned char *) SaltedPassword, + SCRAM_HASH_SIZE, + SERVER_KEY_CONSTANT, + SERVER_KEY_CONSTANT_LEN, + (unsigned char *)ServerKey, + &hash_len) == NULL) { + *error_text = "HMAC-SHA1 call failed"; + result = SASL_SCRAM_INTERNAL; + goto cleanup; + } + + result = SASL_OK; + +cleanup: + if (sec) { + _plug_free_secret(utils, &sec); + } + return result; +} + +/***************************** Server Section *****************************/ + +typedef struct server_context { + int state; + + char * authentication_id; + char * authorization_id; + + char * out_buf; + unsigned out_buf_len; + char * auth_message; + size_t auth_message_len; + char * nonce; + /* in binary form */ + char * salt; + size_t salt_len; + unsigned int iteration_count; + char StoredKey[SCRAM_HASH_SIZE + 1]; + char ServerKey[SCRAM_HASH_SIZE + 1]; + + int cb_flags; + char *cbindingname; + char *gs2_header; + size_t gs2_header_length; +} server_context_t; + +static int +scram_server_mech_new(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + void **conn_context) +{ + server_context_t *text; + + /* holds state are in */ + text = sparams->utils->malloc(sizeof(server_context_t)); + if (text == NULL) { + MEMERROR( sparams->utils ); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(server_context_t)); + /* text->state = 0; */ + + *conn_context = text; + + return SASL_OK; +} + +static int +scram_server_mech_step1(server_context_t *text, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams __attribute__((unused))) +{ + char * authentication_id; + char * p; + char * nonce; + size_t client_nonce_len; + char * base64_salt = NULL; + size_t base64len; + size_t estimated_challenge_len; + size_t pure_scram_length; + char * inbuf = NULL; + const char *password_request[] = { SASL_AUX_PASSWORD, + "*authPassword", + NULL }; + int canon_flags; + struct propval auxprop_values[3]; + unsigned int hash_len = 0; + int result; + + if (clientinlen == 0) { + SETERROR(sparams->utils, SCRAM_SASL_MECH " input expected"); + return SASL_BADPROT; + } + + /* Expecting: 'gs2-cbind-flag "," [ authzid ] "," [reserved-mext ","] + username "," nonce ["," extensions]' */ + + if (clientinlen < 10) { + SETERROR(sparams->utils, "Invalid " SCRAM_SASL_MECH " input"); + return SASL_BADPROT; + } + + inbuf = sparams->utils->malloc (clientinlen + 1); + + if (inbuf == NULL) { + MEMERROR( sparams->utils ); + return SASL_NOMEM; + } + + memcpy(inbuf, clientin, clientinlen); + inbuf[clientinlen] = 0; + + if (strlen(inbuf) != clientinlen) { + SETERROR(sparams->utils, "NULs found in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + p = inbuf; + + /* gs2-cbind-flag = "p=" cb-name / "n" / "y" + ;; "n" -> client doesn't support channel binding + ;; "y" -> client does support channel binding + ;; but thinks the server does not. + ;; "p" -> client requires channel binding. + ;; The selected channel binding follows "p=". */ + switch (p[0]) { + case 'p': + if (p[1] != '=') { + SETERROR(sparams->utils, "The initial 'p' needs to be followed by '=' in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + p++; + + text->cbindingname = p + 1; + p = strchr (p, ','); + if (p == NULL) { + text->cbindingname = NULL; + + SETERROR(sparams->utils, "Channel binding name must be terminated by a comma in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + *p = '\0'; + _plug_strdup(sparams->utils, text->cbindingname, &text->cbindingname, NULL); + *p = ','; + + text->cb_flags = SCRAM_CB_FLAG_P; + break; + + case 'n': + text->cb_flags = SCRAM_CB_FLAG_N; + /* We always have at least 10 bytes, so this is safe */ + p++; + break; + + case 'y': + text->cb_flags = SCRAM_CB_FLAG_Y; + /* We always have at least 10 bytes, so this is safe */ + p++; + break; + + default: + SETERROR(sparams->utils, "The initial " SCRAM_SASL_MECH " client response needs to start with 'y', 'n' or 'p'"); + result = SASL_BADPROT; + goto cleanup; + } + + if (p[0] != ',') { + SETERROR(sparams->utils, "',' expected in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + p++; + + if (p[0] == 'a' && p[1] == '=') { + text->authorization_id = p + 2; + + p = strchr (text->authorization_id, ','); + if (p == NULL) { + text->authorization_id = NULL; + + SETERROR(sparams->utils, "At least nonce is expected in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + /* End of the GS2 header */ + p[0] = '\0'; + /* The GS2 header length DOES include the terminating comma */ + text->gs2_header_length = p - inbuf + 1; + + p++; + + /* Make a read-write copy we can modify */ + _plug_strdup(sparams->utils, text->authorization_id, &text->authorization_id, NULL); + + if (decode_saslname(text->authorization_id) != SASL_OK) { + SETERROR(sparams->utils, "Invalid authorization identity encoding in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + } else if (p[0] != ',') { + SETERROR(sparams->utils, "',' expected in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } else { + /* End of the GS2 header */ + p[0] = '\0'; + /* The GS2 header length DOES include the terminating comma */ + text->gs2_header_length = p - inbuf + 1; + + p++; + } + + text->gs2_header = sparams->utils->malloc (text->gs2_header_length + 1); + if (text->gs2_header == NULL) { + MEMERROR( sparams->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + memcpy(text->gs2_header, inbuf, text->gs2_header_length - 1); + /* Remember the comma */ + text->gs2_header[text->gs2_header_length - 1] = ','; + text->gs2_header[text->gs2_header_length] = 0; + + + + if (p[1] != '=') { + SETERROR(sparams->utils, "Invalid " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + if (p[0] == 'm') { + SETERROR(sparams->utils, "Unsupported mandatory extension to " SCRAM_SASL_MECH); + result = SASL_BADPROT; + goto cleanup; + } + + if (p[0] != 'n') { + SETERROR(sparams->utils, "Username (n=) expected in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + authentication_id = p + 2; + p = strchr (authentication_id, ','); + + /* MUST be followed by a nonce */ + if (p == NULL) { + SETERROR(sparams->utils, "Nonce expected after the username in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + *p = '\0'; + p++; + + if (decode_saslname(authentication_id) != SASL_OK) { + SETERROR(sparams->utils, "Invalid username encoding in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + _plug_strdup(sparams->utils, authentication_id, &text->authentication_id, NULL); + + if (strncmp(p, "r=", 2) != 0) { + SETERROR(sparams->utils, "Nonce expected after the username in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + p += 2; + nonce = p; + p = strchr (nonce, ','); + + if (p == NULL) { + p = nonce + strlen(nonce); + } else { + *p = '\0'; + } + + /* Generate server nonce, by appending some random stuff to the client nonce */ + client_nonce_len = strlen(nonce); + text->nonce = sparams->utils->malloc (client_nonce_len + NONCE_SIZE + 1); + + if (text->nonce == NULL) { + MEMERROR( sparams->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + strcpy (text->nonce, nonce); + + if (create_nonce(sparams->utils, + text->nonce + client_nonce_len, + NONCE_SIZE + 1) == NULL) { + MEMERROR( sparams->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + + + /* Now we fetch user's password and calculate our secret */ + result = sparams->utils->prop_request(sparams->propctx, password_request); + if (result != SASL_OK) { + goto cleanup; + } + + /* this will trigger the getting of the aux properties */ + canon_flags = SASL_CU_AUTHID; + if (text->authorization_id == NULL || *text->authorization_id == '\0') { + canon_flags |= SASL_CU_AUTHZID; + } + + result = sparams->canon_user(sparams->utils->conn, + text->authentication_id, + 0, + canon_flags, + oparams); + if (result != SASL_OK) { + SETERROR(sparams->utils, "unable to canonify user and get auxprops"); + goto cleanup; + } + + if (text->authorization_id != NULL && *text->authorization_id != '\0') { + result = sparams->canon_user(sparams->utils->conn, + text->authorization_id, + 0, + SASL_CU_AUTHZID, + oparams); + } + if (result != SASL_OK) { + SETERROR(sparams->utils, "unable to canonify authorization ID"); + goto cleanup; + } + + result = sparams->utils->prop_getnames(sparams->propctx, + password_request, + auxprop_values); + if (result < 0 || + ((!auxprop_values[0].name || !auxprop_values[0].values) && + (!auxprop_values[1].name || !auxprop_values[1].values))) { + /* We didn't find this username */ + sparams->utils->seterror(sparams->utils->conn,0, + "no secret in database"); + result = sparams->transition ? SASL_TRANS : SASL_NOUSER; + goto cleanup; + } + + if (auxprop_values[0].name && auxprop_values[0].values) { + char * error_text = NULL; + char * s_iteration_count; + char * end; + + text->salt = scram_server_user_salt(sparams->utils, text->authentication_id, &text->salt_len); + + sparams->utils->getopt(sparams->utils->getopt_context, + /* Different SCRAM hashes can have different strengh */ + SCRAM_SASL_MECH, + "scram_iteration_counter", + &s_iteration_count, + NULL); + + if (s_iteration_count != NULL) { + errno = 0; + text->iteration_count = strtoul(s_iteration_count, &end, 10); + if (s_iteration_count == end || *end != '\0' || errno != 0) { + sparams->utils->log(NULL, + SASL_LOG_DEBUG, + "Invalid iteration-count in scram_iteration_count SASL option: not a number. Using the default instead."); + s_iteration_count = NULL; + } + } + + if (s_iteration_count == NULL) { + text->iteration_count = DEFAULT_ITERATION_COUNTER; + } + + result = GenerateScramSecrets (sparams->utils, + auxprop_values[0].values[0], + strlen(auxprop_values[0].values[0]), + text->salt, + text->salt_len, + text->iteration_count, + text->StoredKey, + text->ServerKey, + &error_text); + if (result != SASL_OK) { + if (error_text != NULL) { + sparams->utils->seterror(sparams->utils->conn, 0, error_text); + } + goto cleanup; + } + + } else if (auxprop_values[1].name && auxprop_values[1].values) { + char s_iteration_count[ITERATION_COUNTER_BUF_LEN+1]; + size_t base64_salt_len; + unsigned int exact_key_len; + const char * scram_hash; + const char * p_field; + char * end; + int i; + + result = SASL_SCRAM_INTERNAL; + + for (i = 0; auxprop_values[1].values[i] != NULL; i++) { + scram_hash = auxprop_values[1].values[i]; + + /* Skip the leading spaces */ + while (*scram_hash == ' ') { + scram_hash++; + } + + if (strncmp(scram_hash, SCRAM_SASL_MECH, SCRAM_SASL_MECH_LEN) != 0) { + continue; + } + scram_hash += SCRAM_SASL_MECH_LEN; + + /* Skip spaces */ + while (*scram_hash == ' ') { + scram_hash++; + } + + if (*scram_hash != '$') { + /* syntax error, ignore the value */ + continue; + } + scram_hash++; + + /* Skip spaces */ + while (*scram_hash == ' ') { + scram_hash++; + } + + p_field = strchr(scram_hash, ':'); + if (p_field == NULL || p_field == scram_hash) { + /* syntax error, ignore the value */ + continue; + } + + if ((p_field - scram_hash) > ITERATION_COUNTER_BUF_LEN) { + /* The iteration counter is too big for us */ + SETERROR(sparams->utils, "Invalid iteration-count in " SCRAM_SASL_MECH " input: the value is too big"); + continue; + } + + memcpy(s_iteration_count, scram_hash, p_field - scram_hash); + s_iteration_count[p_field - scram_hash] = '\0'; + + errno = 0; + text->iteration_count = strtoul(s_iteration_count, &end, 10); + if (s_iteration_count == end || *end != '\0' || errno != 0) { + SETERROR(sparams->utils, "Invalid iteration-count in " SCRAM_SASL_MECH " input: not a number"); + continue; + } + + scram_hash = p_field + 1; + + p_field = scram_hash + strcspn(scram_hash, "$ "); + if (p_field == scram_hash || *p_field == '\0') { + /* syntax error, ignore the value */ + continue; + } + + base64_salt_len = p_field - scram_hash; + text->salt = (char *) sparams->utils->malloc(base64_salt_len); + if (sparams->utils->decode64(scram_hash, + (unsigned int)base64_salt_len, + text->salt, + (unsigned int)base64_salt_len, + &text->salt_len) != SASL_OK) { + SETERROR(sparams->utils, "Invalid base64 encoding of the salt in " SCRAM_SASL_MECH " stored value"); + continue; + } + + scram_hash = p_field; + + /* Skip spaces */ + while (*scram_hash == ' ') { + scram_hash++; + } + + if (*scram_hash != '$') { + /* syntax error, ignore the value */ + sparams->utils->free(text->salt); + text->salt = NULL; + continue; + } + scram_hash++; + + /* Skip spaces */ + while (*scram_hash == ' ') { + scram_hash++; + } + + p_field = strchr(scram_hash, ':'); + if (p_field == NULL || p_field == scram_hash) { + /* syntax error, ignore the value */ + sparams->utils->free(text->salt); + text->salt = NULL; + continue; + } + + if (sparams->utils->decode64(scram_hash, + (unsigned int)(p_field - scram_hash), + text->StoredKey, + SCRAM_HASH_SIZE + 1, + &exact_key_len) != SASL_OK) { + SETERROR(sparams->utils, "Invalid base64 encoding of StoredKey in " SCRAM_SASL_MECH " per-user storage"); + sparams->utils->free(text->salt); + text->salt = NULL; + continue; + } + + if (exact_key_len != SCRAM_HASH_SIZE) { + SETERROR(sparams->utils, "Invalid StoredKey in " SCRAM_SASL_MECH " per-user storage"); + sparams->utils->free(text->salt); + text->salt = NULL; + continue; + } + + scram_hash = p_field + 1; + + p_field = strchr(scram_hash, ' '); + if (p_field == NULL) { + p_field = scram_hash + strlen(scram_hash); + } + + + if (sparams->utils->decode64(scram_hash, + (unsigned int)(p_field - scram_hash), + text->ServerKey, + SCRAM_HASH_SIZE + 1, + &exact_key_len) != SASL_OK) { + SETERROR(sparams->utils, "Invalid base64 encoding of ServerKey in " SCRAM_SASL_MECH " per-user storage"); + sparams->utils->free(text->salt); + text->salt = NULL; + continue; + } + + if (exact_key_len != SCRAM_HASH_SIZE) { + SETERROR(sparams->utils, "Invalid ServerKey in " SCRAM_SASL_MECH " per-user storage"); + sparams->utils->free(text->salt); + text->salt = NULL; + continue; + } + + result = SASL_OK; + break; + } + + if (result != SASL_OK) { + sparams->utils->seterror(sparams->utils->conn, + 0, + "No valid " SCRAM_SASL_MECH " secret found"); + goto cleanup; + } + + } else { + sparams->utils->seterror(sparams->utils->conn, + 0, + "Have neither type of secret"); + return SASL_FAIL; + } + + /* erase the plaintext password */ + sparams->utils->prop_erase(sparams->propctx, password_request[0]); + + + + /* base 64 encode it so it has valid chars */ + base64len = (text->salt_len / 3 * 4) + ((text->salt_len % 3) ? 4 : 0); + + base64_salt = (char *) sparams->utils->malloc(base64len + 1); + if (base64_salt == NULL) { + MEMERROR( sparams->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + /* + * Returns SASL_OK on success, SASL_BUFOVER if result won't fit + */ + if (sparams->utils->encode64(text->salt, + (unsigned int)text->salt_len, + base64_salt, + (unsigned int)base64len + 1, + NULL) != SASL_OK) { + MEMERROR( sparams->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + base64_salt[base64len] = '\0'; + + /* Now we generate server challenge */ + estimated_challenge_len = client_nonce_len + NONCE_SIZE + + base64len + + ITERATION_COUNTER_BUF_LEN + + strlen("r=,s=,i="); + result = _plug_buf_alloc(sparams->utils, + &(text->out_buf), + &(text->out_buf_len), + (unsigned) estimated_challenge_len + 1); + if (result != SASL_OK) { + MEMERROR( sparams->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + sprintf(text->out_buf, + "r=%s,s=%s,i=%u", + text->nonce, + base64_salt, + text->iteration_count); + + + /* Save the (client response, ",", server challenge, ","). + Note, we skip the GS2 prefix here */ + pure_scram_length = clientinlen - text->gs2_header_length; + text->auth_message_len = pure_scram_length + 1 + estimated_challenge_len + 1; + text->auth_message = sparams->utils->malloc (text->auth_message_len + 1); + if (text->auth_message == NULL) { + MEMERROR( sparams->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + memcpy(text->auth_message, clientin + text->gs2_header_length, pure_scram_length); + text->auth_message[pure_scram_length] = ','; + strcpy (text->auth_message + pure_scram_length + 1, text->out_buf); + strcat (text->auth_message + pure_scram_length + 1, ","); + + /* Now remember the exact length, not the estimated one */ + text->auth_message_len = strlen(text->auth_message); + + *serverout = text->out_buf; + *serveroutlen = (unsigned) strlen(text->out_buf); + + result = SASL_CONTINUE; + text->state = 2; + +cleanup: + if (inbuf != NULL) { + sparams->utils->free(inbuf); + } + if (base64_salt != NULL) { + sparams->utils->free(base64_salt); + } + return result; +} + +static int +scram_server_mech_step2(server_context_t *text, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + char *channel_binding = NULL; + size_t channel_binding_len = 0; + char *binary_channel_binding = NULL; + unsigned binary_channel_binding_len = 0; + char *client_proof = NULL; + char *inbuf = NULL; + char *p; + int result = SASL_FAIL; + size_t proof_offset; + char * full_auth_message; + char ReceivedClientKey[SCRAM_HASH_SIZE]; + char DecodedClientProof[SCRAM_HASH_SIZE + 1]; + char CalculatedStoredKey[SCRAM_HASH_SIZE]; + char ClientSignature[SCRAM_HASH_SIZE]; + char ServerSignature[SCRAM_HASH_SIZE]; + char * nonce; + size_t client_proof_len; + size_t server_proof_len; + unsigned exact_client_proof_len; + unsigned int hash_len = 0; + int k; + + if (clientinlen == 0) { + SETERROR(sparams->utils, SCRAM_SASL_MECH " input expected"); + return SASL_BADPROT; + } + + if (clientinlen < 3 || clientin[1] != '=') { + SETERROR(sparams->utils, "Invalid " SCRAM_SASL_MECH " input"); + return SASL_BADPROT; + } + + inbuf = sparams->utils->malloc (clientinlen + 1); + + if (inbuf == NULL) { + MEMERROR( sparams->utils ); + return SASL_NOMEM; + } + + memcpy(inbuf, clientin, clientinlen); + inbuf[clientinlen] = 0; + + if (strlen(inbuf) != clientinlen) { + SETERROR(sparams->utils, "NULs found in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + /* Expecting: channel-binding "," nonce ["," extensions] "," proof */ + + p = inbuf; + + if (strncmp(p, "c=", 2) != 0) { + SETERROR(sparams->utils, "Channel binding expected in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + channel_binding = p + 2; + + p = strchr (channel_binding, ','); + if (p == NULL) { + SETERROR(sparams->utils, "At least nonce is expected in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + *p = '\0'; + p++; + + channel_binding_len = strlen(channel_binding); + + /* We can calculate the exact length, but the decoded (binary) data + is always shorter than its base64 version. */ + binary_channel_binding = (char *) sparams->utils->malloc(channel_binding_len + 1); + + if (sparams->utils->decode64(channel_binding, + (unsigned int)channel_binding_len, + binary_channel_binding, + (unsigned int)channel_binding_len, + &binary_channel_binding_len) != SASL_OK) { + SETERROR(sparams->utils, "Invalid base64 encoding of the channel bindings in " SCRAM_SASL_MECH); + result = SASL_BADPROT; + goto cleanup; + } + + if (binary_channel_binding_len < text->gs2_header_length || + strncmp(binary_channel_binding, text->gs2_header, text->gs2_header_length) != 0) { + sparams->utils->seterror (sparams->utils->conn, + 0, + "Channel bindings prefix doesn't match the one received in the GS2 header of " + SCRAM_SASL_MECH ". Expected \"%s\"", + text->gs2_header); + result = SASL_BADPROT; + goto cleanup; + } + + switch (text->cb_flags & SCRAM_CB_FLAG_MASK) { + case SCRAM_CB_FLAG_P: + binary_channel_binding_len -= (unsigned)text->gs2_header_length; + if (binary_channel_binding_len == 0) { + SETERROR(sparams->utils, "Channel bindings data expected in " SCRAM_SASL_MECH); + result = SASL_BADPROT; + goto cleanup; + } + + if (strcmp(sparams->cbinding->name, text->cbindingname) != 0) { + sparams->utils->seterror (sparams->utils->conn, + 0, + "Unsupported channel bindings type received in " SCRAM_SASL_MECH + ". Expected: %s, received: %s", + sparams->cbinding->name, + text->cbindingname); + result = SASL_BADPROT; + goto cleanup; + } + + if (binary_channel_binding_len != sparams->cbinding->len) { + sparams->utils->seterror (sparams->utils->conn, + 0, + "Unsupported channel bindings length received in " SCRAM_SASL_MECH + ". Expected lenght: %d, received: %d", + sparams->cbinding->len, + binary_channel_binding_len); + result = SASL_BADPROT; + goto cleanup; + } + + if (memcmp(binary_channel_binding + text->gs2_header_length, + sparams->cbinding->data, + binary_channel_binding_len) != 0) { + SETERROR(sparams->utils, "Channel bindings mismatch in " SCRAM_SASL_MECH); + result = SASL_BADPROT; + goto cleanup; + } + break; + } + + if (strncmp(p, "r=", 2) != 0) { + SETERROR(sparams->utils, "Nonce expected in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + nonce = p + 2; + + p = strchr (nonce, ','); + if (p == NULL) { + SETERROR(sparams->utils, "At least proof is expected in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + *p = '\0'; + p++; + + if (strcmp(nonce, text->nonce) != 0) { + SETERROR(sparams->utils, "Nonce mismatch " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + while (p[0] != '\0') { + if (strncmp(p, "p=", 2) == 0) { + client_proof = p + 2; + proof_offset = p - inbuf - 1; + break; + } + + p = strchr (p, ','); + if (p == NULL) { + break; + } + p++; + } + + if (client_proof == NULL) { + SETERROR(sparams->utils, "Client proof is expected in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + /* Check that no extension data exists after the proof */ + p = strchr (client_proof, ','); + if (p != NULL) { + SETERROR(sparams->utils, "No extension data is allowed after the client proof in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + if (strlen(client_proof) != (SCRAM_HASH_SIZE / 3 * 4 + (SCRAM_HASH_SIZE % 3 ? 4 : 0))) { + SETERROR(sparams->utils, "Invalid client proof length in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + /* Construct the full AuthMessage */ + full_auth_message = sparams->utils->realloc(text->auth_message, + text->auth_message_len + proof_offset + 1); + if (full_auth_message == NULL) { + MEMERROR( sparams->utils ); + result = SASL_NOMEM; + goto cleanup; + } + text->auth_message = full_auth_message; + + memcpy(text->auth_message + text->auth_message_len, clientin, proof_offset); + + text->auth_message_len += proof_offset; + text->auth_message[text->auth_message_len] = '\0'; + + + /* ClientSignature := HMAC(StoredKey, AuthMessage) */ + if (HMAC(EVP_sha1(), + (const unsigned char *) text->StoredKey, + SCRAM_HASH_SIZE, + text->auth_message, + (int)text->auth_message_len, + (unsigned char *)ClientSignature, + &hash_len) == NULL) { + sparams->utils->seterror(sparams->utils->conn,0, + "HMAC-SHA1 call failed"); + result = SASL_SCRAM_INTERNAL; + goto cleanup; + } + + client_proof_len = strlen(client_proof); + if (sparams->utils->decode64(client_proof, + (unsigned int)client_proof_len, + DecodedClientProof, + SCRAM_HASH_SIZE + 1, + &exact_client_proof_len) != SASL_OK) { + SETERROR(sparams->utils, "Invalid base64 encoding of the client proof in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + if (exact_client_proof_len != SCRAM_HASH_SIZE) { + SETERROR(sparams->utils, "Invalid client proof (truncated) in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + for (k = 0; k < SCRAM_HASH_SIZE; k++) { + ReceivedClientKey[k] = DecodedClientProof[k] ^ ClientSignature[k]; + } + + /* StoredKey := H(ClientKey) */ + if (SHA1(ReceivedClientKey, SCRAM_HASH_SIZE, CalculatedStoredKey) == NULL) { + sparams->utils->seterror(sparams->utils->conn,0, + "SHA1 call failed"); + result = SASL_SCRAM_INTERNAL; + goto cleanup; + } + + for (k = 0; k < SCRAM_HASH_SIZE; k++) { + if (CalculatedStoredKey[k] != text->StoredKey[k]) { + SETERROR(sparams->utils, "StoredKey mismatch"); + result = SASL_BADPROT; + goto cleanup; + } + } + + /* ServerSignature := HMAC(ServerKey, AuthMessage) */ + if (HMAC(EVP_sha1(), + (const unsigned char *) text->ServerKey, + SCRAM_HASH_SIZE, + text->auth_message, + (int)text->auth_message_len, + (unsigned char *)ServerSignature, + &hash_len) == NULL) { + sparams->utils->seterror(sparams->utils->conn,0, + "HMAC-SHA1 call failed"); + result = SASL_SCRAM_INTERNAL; + goto cleanup; + } + + server_proof_len = (SCRAM_HASH_SIZE / 3 * 4 + (SCRAM_HASH_SIZE % 3 ? 4 : 0)); + result = _plug_buf_alloc(sparams->utils, + &(text->out_buf), + &(text->out_buf_len), + (unsigned) server_proof_len + strlen("v=") + 1); + if (result != SASL_OK) { + MEMERROR( sparams->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + text->out_buf[0] = 'v'; + text->out_buf[1] = '='; + + + if (sparams->utils->encode64(ServerSignature, + SCRAM_HASH_SIZE, + text->out_buf+2, + (unsigned int)server_proof_len + 1, + NULL) != SASL_OK) { + SETERROR(sparams->utils, "Internal error"); + /* This is not quite right, but better than alternatives */ + result = SASL_NOMEM; + goto cleanup; + } + + text->out_buf[server_proof_len + 2] = '\0'; + + *serverout = text->out_buf; + *serveroutlen = (unsigned) strlen(text->out_buf); + + + /* set oparams */ + + switch (text->cb_flags & SCRAM_CB_FLAG_MASK) { + case SCRAM_CB_FLAG_N: + oparams->cbindingdisp = SASL_CB_DISP_NONE; + break; + case SCRAM_CB_FLAG_P: + oparams->cbindingdisp = SASL_CB_DISP_USED; + oparams->cbindingname = text->cbindingname; + break; + case SCRAM_CB_FLAG_Y: + oparams->cbindingdisp = SASL_CB_DISP_WANT; + break; + } + + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + result = SASL_OK; + +cleanup: + if (inbuf != NULL) { + sparams->utils->free(inbuf); + } + if (binary_channel_binding != NULL) { + sparams->utils->free(binary_channel_binding); + } + + return result; +} + +static int scram_server_mech_step(void *conn_context, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + server_context_t *text = (server_context_t *) conn_context; + + *serverout = NULL; + *serveroutlen = 0; + + if (text == NULL) { + return SASL_BADPROT; + } + + /* this should be well more than is ever needed */ + if (clientinlen > MAX_CLIENTIN_LEN) { + SETERROR(sparams->utils, SCRAM_SASL_MECH " input longer than " STRINGIZE((MAX_CLIENTIN_LEN)) " bytes"); + return SASL_BADPROT; + } + + switch (text->state) { + case 0: + text->state++; + /* Assume the protocol doesn't support initial client response */ + if (clientinlen == 0) { + return SASL_CONTINUE; + } + /* fall through */ + + case 1: + return scram_server_mech_step1(text, + sparams, + clientin, + clientinlen, + serverout, + serveroutlen, + oparams); + + case 2: + text->state++; + return scram_server_mech_step2(text, + sparams, + clientin, + clientinlen, + serverout, + serveroutlen, + oparams); + + default: /* should never get here */ + sparams->utils->log(NULL, SASL_LOG_ERR, + "Invalid " SCRAM_SASL_MECH " server step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +static int scram_setpass(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *userstr, + const char *pass, + unsigned passlen, + const char *oldpass __attribute__((unused)), + unsigned oldpasslen __attribute__((unused)), + unsigned flags) +{ + int r; + char *user = NULL; + char *user_only = NULL; + char *realm = NULL; + sasl_secret_t *sec = NULL; + struct propctx *propctx = NULL; + const char *store_request[] = { "authPassword", + NULL }; + const char *generate_scram_secret; + + /* Do we have a backend that can store properties? */ + if (!sparams->utils->auxprop_store || + sparams->utils->auxprop_store(NULL, NULL, NULL) != SASL_OK) { + SETERROR(sparams->utils, SCRAM_SASL_MECH ": auxprop backend can't store properties"); + return SASL_NOMECH; + } + + sparams->utils->getopt(sparams->utils->getopt_context, + /* This affects all SCRAM plugins, not just SCRAM-SHA-1 */ + "SCRAM", + "scram_secret_generate", + &generate_scram_secret, + NULL); + + /* NOTE: The default (when this option is not set) is NOT to generate authPassword secret */ + if (!(generate_scram_secret && + (generate_scram_secret[0] == '1' || generate_scram_secret[0] == 'y' || + (generate_scram_secret[0] == 'o' && generate_scram_secret[1] == 'n') || + generate_scram_secret[0] == 't'))) { + /* Pretend that everything is Ok, no need to generate noise in the logs */ + return SASL_OK; + } + + r = _plug_parseuser(sparams->utils, + &user_only, + &realm, + sparams->user_realm, + sparams->serverFQDN, + userstr); + if (r) { + SETERROR(sparams->utils, SCRAM_SASL_MECH ": Error parsing user"); + return r; + } + + r = _plug_make_fulluser(sparams->utils, &user, user_only, realm); + if (r) { + goto cleanup; + } + + if ((flags & SASL_SET_DISABLE) || pass == NULL) { + sec = NULL; + } else { + char * error_text = NULL; + char salt[SALT_SIZE + 1]; + char base64_salt[BASE64_LEN(SALT_SIZE) + 1]; + /* size_t salt_len = SALT_SIZE; */ + char StoredKey[SCRAM_HASH_SIZE + 1]; + char ServerKey[SCRAM_HASH_SIZE + 1]; + char base64_StoredKey[BASE64_LEN(SCRAM_HASH_SIZE) + 1]; + char base64_ServerKey[BASE64_LEN(SCRAM_HASH_SIZE) + 1]; + size_t secret_len; + unsigned int iteration_count = DEFAULT_ITERATION_COUNTER; + char * s_iteration_count; + char * end; + + sparams->utils->getopt(sparams->utils->getopt_context, + /* Different SCRAM hashes can have different strengh */ + SCRAM_SASL_MECH, + "scram_iteration_counter", + &s_iteration_count, + NULL); + + if (s_iteration_count != NULL) { + errno = 0; + iteration_count = strtoul(s_iteration_count, &end, 10); + if (s_iteration_count == end || *end != '\0' || errno != 0) { + sparams->utils->log(NULL, + SASL_LOG_DEBUG, + "Invalid iteration-count in scram_iteration_count SASL option: not a number. Using the default instead."); + s_iteration_count = NULL; + } + } + + if (s_iteration_count == NULL) { + iteration_count = DEFAULT_ITERATION_COUNTER; + } + + sparams->utils->rand(sparams->utils->rpool, salt, SALT_SIZE); + + r = GenerateScramSecrets (sparams->utils, + pass, + passlen, + salt, + SALT_SIZE, + iteration_count, + StoredKey, + ServerKey, + &error_text); + if (r != SASL_OK) { + if (error_text != NULL) { + SETERROR(sparams->utils, error_text); + } + goto cleanup; + } + + /* Returns SASL_OK on success, SASL_BUFOVER if result won't fit */ + if (sparams->utils->encode64(salt, + SALT_SIZE, + base64_salt, + BASE64_LEN(SALT_SIZE) + 1, + NULL) != SASL_OK) { + MEMERROR( sparams->utils ); + r = SASL_NOMEM; + goto cleanup; + } + + base64_salt[BASE64_LEN(SALT_SIZE)] = '\0'; + + + /* Returns SASL_OK on success, SASL_BUFOVER if result won't fit */ + if (sparams->utils->encode64(StoredKey, + SCRAM_HASH_SIZE, + base64_StoredKey, + BASE64_LEN(SCRAM_HASH_SIZE) + 1, + NULL) != SASL_OK) { + MEMERROR( sparams->utils ); + r = SASL_NOMEM; + goto cleanup; + } + + base64_StoredKey[BASE64_LEN(SCRAM_HASH_SIZE)] = '\0'; + + + + /* Returns SASL_OK on success, SASL_BUFOVER if result won't fit */ + if (sparams->utils->encode64(ServerKey, + SCRAM_HASH_SIZE, + base64_ServerKey, + BASE64_LEN(SCRAM_HASH_SIZE) + 1, + NULL) != SASL_OK) { + MEMERROR( sparams->utils ); + r = SASL_NOMEM; + goto cleanup; + } + + base64_ServerKey[BASE64_LEN(SCRAM_HASH_SIZE)] = '\0'; + + secret_len = strlen(SCRAM_SASL_MECH ":$:") + + ITERATION_COUNTER_BUF_LEN + + sizeof(base64_salt) + + sizeof(base64_StoredKey) + + sizeof(base64_ServerKey); + + sec = sparams->utils->malloc(sizeof(sasl_secret_t) + secret_len); + if (sec == NULL) { + MEMERROR( sparams->utils ); + r = SASL_NOMEM; + goto cleanup; + } + + sprintf(sec->data, + "%s$%u:%s$%s:%s", + SCRAM_SASL_MECH, + iteration_count, + base64_salt, + base64_StoredKey, + base64_ServerKey); + sec->len = (unsigned int) strlen(sec->data); + } + + /* do the store */ + propctx = sparams->utils->prop_new(0); + if (!propctx) { + r = SASL_FAIL; + } + if (!r) { + r = sparams->utils->prop_request(propctx, store_request); + } + if (!r) { + r = sparams->utils->prop_set(propctx, + "authPassword", + (sec ? sec->data : NULL), + (sec ? sec->len : 0)); + } + if (!r) { + r = sparams->utils->auxprop_store(sparams->utils->conn, propctx, user); + } + if (propctx) { + sparams->utils->prop_dispose(&propctx); + } + + if (r) { + SETERROR(sparams->utils, "Error putting " SCRAM_SASL_MECH " secret"); + goto cleanup; + } + + sparams->utils->log(NULL, SASL_LOG_DEBUG, "Setpass for " SCRAM_SASL_MECH " successful\n"); + + cleanup: + if (user) _plug_free_string(sparams->utils, &user); + if (user_only) _plug_free_string(sparams->utils, &user_only); + if (realm) _plug_free_string(sparams->utils, &realm); + if (sec) _plug_free_secret(sparams->utils, &sec); + + return r; +} + +static void scram_server_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + server_context_t *text = (server_context_t *) conn_context; + + if (!text) return; + + if (text->authentication_id) _plug_free_string(utils,&(text->authentication_id)); + if (text->authorization_id) _plug_free_string(utils,&(text->authorization_id)); + if (text->out_buf) _plug_free_string(utils,&(text->out_buf)); + if (text->auth_message) _plug_free_string(utils,&(text->auth_message)); + if (text->nonce) _plug_free_string(utils,&(text->nonce)); + if (text->salt) utils->free(text->salt); + if (text->cbindingname != NULL) { + utils->free(text->cbindingname); + text->cbindingname = NULL; + } + if (text->gs2_header != NULL) { + utils->free(text->gs2_header); + text->gs2_header = NULL; + } + + utils->free(text); +} + +static sasl_server_plug_t scram_server_plugins[] = +{ + { + SCRAM_SASL_MECH, /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOACTIVE + | SASL_SEC_NOANONYMOUS + | SASL_SEC_MUTUAL_AUTH, /* security_flags */ + SASL_FEAT_ALLOWS_PROXY + | SASL_FEAT_CHANNEL_BINDING, /* features */ + NULL, /* glob_context */ + &scram_server_mech_new, /* mech_new */ + &scram_server_mech_step, /* mech_step */ + &scram_server_mech_dispose, /* mech_dispose */ + NULL, /* mech_free */ + &scram_setpass, /* setpass */ + NULL, /* user_query */ + NULL, /* idle */ + NULL, /* mech avail */ + NULL /* spare */ + } +}; + +int scram_server_plug_init(const sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_server_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_SERVER_PLUG_VERSION) { + SETERROR( utils, SCRAM_SASL_MECH " version mismatch"); + return SASL_BADVERS; + } + + *out_version = SASL_SERVER_PLUG_VERSION; + *pluglist = scram_server_plugins; + *plugcount = 1; + utils->rand(utils->rpool, (char *)g_salt_key, SALT_SIZE); + + return SASL_OK; +} + +/***************************** Client Section *****************************/ + +typedef struct client_context { + int state; + + sasl_secret_t *password; /* user password */ + unsigned int free_password; /* set if we need to free the password */ + + char * gs2_header; + size_t gs2_header_length; + char * out_buf; + unsigned out_buf_len; + char * auth_message; + size_t auth_message_len; + char * nonce; + /* in binary form */ + char * salt; + size_t salt_len; + unsigned int iteration_count; + char SaltedPassword[SCRAM_HASH_SIZE]; + + int cb_flags; +} client_context_t; + +static int scram_client_mech_new(void *glob_context __attribute__((unused)), + sasl_client_params_t *params, + void **conn_context) +{ + client_context_t *text; + + /* holds state are in */ + text = params->utils->malloc(sizeof(client_context_t)); + if (text == NULL) { + MEMERROR(params->utils); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(client_context_t)); + + *conn_context = text; + + return SASL_OK; +} + +static int +scram_client_mech_step1(client_context_t *text, + sasl_client_params_t *params, + const char *serverin __attribute__((unused)), + unsigned serverinlen __attribute__((unused)), + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + const char *authid = NULL; + const char *userid = NULL; + int user_result = SASL_OK; + int auth_result = SASL_OK; + int pass_result = SASL_OK; + int result; + size_t maxsize; + char * encoded_authcid; + char * freeme = NULL; + char * freeme2 = NULL; + char channel_binding_state = 'n'; + const char * channel_binding_name = NULL; + char * encoded_authorization_id = NULL; + + /* check if sec layer strong enough */ + if (params->props.min_ssf > params->external_ssf) { + SETERROR( params->utils, "SSF requested of " SCRAM_SASL_MECH " plugin"); + return SASL_TOOWEAK; + } + + /* try to get the userid */ + if (oparams->authid == NULL) { + auth_result=_plug_get_authid(params->utils, &authid, prompt_need); + + if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT)) + return auth_result; + } + + /* try to get the userid */ + if (oparams->user == NULL) { + user_result = _plug_get_userid(params->utils, &userid, prompt_need); + + if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) { + return user_result; + } + } + + /* try to get the password */ + if (text->password == NULL) { + pass_result = _plug_get_password(params->utils, + &text->password, + &text->free_password, + prompt_need); + if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT)) { + return pass_result; + } + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + params->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if ((auth_result == SASL_INTERACT) || + (user_result == SASL_INTERACT) || + (pass_result == SASL_INTERACT)) { + /* make the prompt list */ + result = + _plug_make_prompts(params->utils, + prompt_need, + user_result == SASL_INTERACT ? + "Please enter your authorization name" : NULL, + NULL, + auth_result == SASL_INTERACT ? + "Please enter your authentication name" : NULL, + NULL, + pass_result == SASL_INTERACT ? + "Please enter your password" : NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL); + + if (result != SASL_OK) { + goto cleanup; + } + + return SASL_INTERACT; + } + + if (!text->password) { + PARAMERROR(params->utils); + return SASL_BADPARAM; + } + + if (oparams->authid == NULL) { + if (!userid || !*userid) { + result = params->canon_user(params->utils->conn, + authid, + 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, + oparams); + } + else { + result = params->canon_user(params->utils->conn, + authid, + 0, + SASL_CU_AUTHID, + oparams); + if (result != SASL_OK) { + goto cleanup; + } + + result = params->canon_user(params->utils->conn, + userid, + 0, + SASL_CU_AUTHZID, + oparams); + } + if (result != SASL_OK) { + goto cleanup; + } + } + + switch (params->cbindingdisp) { + case SASL_CB_DISP_NONE: + text->cb_flags = SCRAM_CB_FLAG_N; + channel_binding_state = 'n'; + break; + case SASL_CB_DISP_USED: + if (!SASL_CB_PRESENT(params)) { + result = SASL_BADPARAM; + goto cleanup; + } + channel_binding_name = params->cbinding->name; + text->cb_flags = SCRAM_CB_FLAG_P; + channel_binding_state = 'p'; + break; + case SASL_CB_DISP_WANT: + text->cb_flags = SCRAM_CB_FLAG_Y; + channel_binding_state = 'y'; + break; + } + + text->nonce = params->utils->malloc (NONCE_SIZE + 1); + + if (text->nonce == NULL) { + MEMERROR( params->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + if (create_nonce(params->utils, + text->nonce, + NONCE_SIZE + 1) == NULL) { + MEMERROR( params->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + if (userid != NULL && *userid != '\0') { + result = encode_saslname (oparams->user, + &encoded_authorization_id, + &freeme2); + + if (result != SASL_OK) { + MEMERROR( params->utils ); + result = SASL_NOMEM; + goto cleanup; + } + } + + result = encode_saslname (oparams->authid, + &encoded_authcid, + &freeme); + if (result != SASL_OK) { + MEMERROR( params->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + maxsize = strlen("p=,a=,n=,r=") + + ((channel_binding_name != NULL) ? strlen(channel_binding_name) : 0) + + ((encoded_authorization_id != NULL) ? strlen(encoded_authorization_id) : 0) + + strlen(encoded_authcid) + + strlen(text->nonce); + result = _plug_buf_alloc(params->utils, + &(text->out_buf), + &(text->out_buf_len), + (unsigned) maxsize + 1); + if (result != SASL_OK) { + MEMERROR( params->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + snprintf(text->out_buf, + maxsize + 1, + "%c%s%s,%s%s,", + channel_binding_state, + (channel_binding_name != NULL) ? "=" : "", + (channel_binding_name != NULL) ? channel_binding_name : "", + (encoded_authorization_id != NULL) ? "a=" : "", + (encoded_authorization_id != NULL) ? encoded_authorization_id : ""); + + text->gs2_header_length = strlen(text->out_buf); + _plug_strdup(params->utils, text->out_buf, &text->gs2_header, NULL); + + sprintf(text->out_buf + text->gs2_header_length, + "n=%s,r=%s", + encoded_authcid, + text->nonce); + + /* Save the copy of the client-first-message */ + + /* Need to skip the GS2 prefix here */ + _plug_strdup(params->utils, + text->out_buf + text->gs2_header_length, + &text->auth_message, + NULL); + if (text->auth_message == NULL) { + MEMERROR( params->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + text->auth_message_len = strlen(text->auth_message); + + *clientout = text->out_buf; + *clientoutlen = (unsigned) strlen(*clientout); + + result = SASL_CONTINUE; + +cleanup: + if (freeme != NULL) _plug_free_string(params->utils, &freeme); + if (freeme2 != NULL) _plug_free_string(params->utils, &freeme2); + + return result; +} + +static int +scram_client_mech_step2(client_context_t *text, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need __attribute__((unused)), + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams __attribute__((unused))) +{ + char * p; + char * nonce; + size_t server_nonce_len; + char * base64_salt = NULL; + size_t base64_salt_len; + unsigned exact_salt_len; + char * counter; + char * end; + char * inbuf = NULL; + size_t estimated_response_len; + size_t length_no_proof; + char * full_auth_message; + size_t cb_bin_length; + size_t channel_binding_data_len = 0; + size_t cb_encoded_length; + const char * channel_binding_data = NULL; + char * cb_encoded = NULL; + char * cb_bin = NULL; + int result; + char ClientKey[SCRAM_HASH_SIZE]; + char StoredKey[SCRAM_HASH_SIZE]; + char ClientSignature[SCRAM_HASH_SIZE]; + char ClientProof[SCRAM_HASH_SIZE]; + char * client_proof = NULL; + size_t client_proof_len; + int k; + unsigned int hash_len = 0; + + if (serverinlen == 0) { + SETERROR(params->utils, SCRAM_SASL_MECH " input expected"); + return SASL_BADPROT; + } + + /* [reserved-mext ","] nonce "," salt "," iteration-count ["," extensions] */ + + if (serverinlen < 3 || serverin[1] != '=') { + SETERROR(params->utils, "Invalid " SCRAM_SASL_MECH " input"); + return SASL_BADPROT; + } + + if (serverin[0] == 'm') { + SETERROR(params->utils, "Unsupported mandatory extension to " SCRAM_SASL_MECH); + return SASL_BADPROT; + } + + if (serverin[0] != 'r') { + SETERROR(params->utils, "Nonce (r=) expected in " SCRAM_SASL_MECH " input"); + return SASL_BADPROT; + } + + inbuf = params->utils->malloc (serverinlen + 1); + if (inbuf == NULL) { + MEMERROR( params->utils ); + return SASL_NOMEM; + } + + memcpy(inbuf, serverin, serverinlen); + inbuf[serverinlen] = 0; + + if (strlen(inbuf) != serverinlen) { + SETERROR(params->utils, "NULs found in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + nonce = inbuf + 2; + p = strchr (nonce, ','); + + /* MUST be followed by a salt */ + if (p == NULL) { + SETERROR(params->utils, "Salt expected after the nonce in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + *p = '\0'; + p++; + + if (strncmp(p, "s=", 2) != 0) { + SETERROR(params->utils, "Salt expected after the nonce in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + p += 2; + base64_salt = p; + + p = strchr (base64_salt, ','); + + /* MUST be followed by an iteration-count */ + if (p == NULL) { + SETERROR(params->utils, "iteration-count expected after the salt in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + *p = '\0'; + p++; + + if (strncmp(p, "i=", 2) != 0) { + SETERROR(params->utils, "iteration-count expected after the salt in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + p += 2; + counter = p; + p = strchr (counter, ','); + + if (p == NULL) { + p = counter + strlen(counter); + } else { + *p = '\0'; + } + + errno = 0; + text->iteration_count = strtoul(counter, &end, 10); + if (counter == end || *end != '\0' || errno != 0) { + SETERROR(params->utils, "Invalid iteration-count in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + if (text->iteration_count < MIN_ITERATION_COUNTER) { + } + + if (text->iteration_count > MAX_ITERATION_COUNTER) { + SETERROR(params->utils, "iteration-count is too big, refusing to compute"); + result = SASL_BADPROT; + goto cleanup; + } + + /* The client MUST verify that the initial part of the nonce + used in subsequent messages is the same as the nonce it + initially specified. */ + server_nonce_len = strlen(nonce); + + if (server_nonce_len <= NONCE_SIZE || + strncmp(nonce, text->nonce, NONCE_SIZE) != 0) { + SETERROR(params->utils, "The nonce received from the server doesn't start from the nonce sent by the client"); + result = SASL_BADPROT; + goto cleanup; + } + + /* Now we can forget about our nonce */ + params->utils->free(text->nonce); + + _plug_strdup(params->utils, nonce, &text->nonce, NULL); + + if (text->nonce == NULL) { + MEMERROR( params->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + /* base64 decode salt */ + base64_salt_len = strlen(base64_salt); + + if (base64_salt_len == 0) { + SETERROR(params->utils, "The salt can't be empty"); + result = SASL_BADPROT; + goto cleanup; + } + + if (base64_salt_len % 4 != 0) { + SETERROR(params->utils, "Invalid base64 encoding of the salt"); + result = SASL_BADPROT; + goto cleanup; + } + + text->salt_len = base64_salt_len / 4 * 3; + + text->salt = (char *) params->utils->malloc(text->salt_len + 1); + if (text->salt == NULL) { + MEMERROR( params->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + if (params->utils->decode64(base64_salt, + (unsigned int)base64_salt_len, + text->salt, + (unsigned int)text->salt_len + 1, + &exact_salt_len) != SASL_OK) { + SETERROR(params->utils, "Invalid base64 encoding of the salt in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + text->salt_len = exact_salt_len; + + /* Now we generate client response */ + + if (text->gs2_header[0] == 'p') { + + if (params->cbinding == NULL) { + result = SASL_FAIL; + goto cleanup; + } + + channel_binding_data = params->cbinding->data; + channel_binding_data_len = params->cbinding->len; + } + + cb_bin_length = text->gs2_header_length + + ((channel_binding_data != NULL) ? channel_binding_data_len : 0); + cb_encoded_length = (cb_bin_length / 3 * 4) + ((cb_bin_length % 3) ? 4 : 0); + + if (channel_binding_data != NULL) { + cb_bin = (char *) params->utils->malloc(cb_bin_length + 1); + if (cb_bin == NULL) { + MEMERROR( params->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + memcpy(cb_bin, text->gs2_header, text->gs2_header_length); + memcpy(cb_bin + text->gs2_header_length, channel_binding_data, channel_binding_data_len); + } + + cb_encoded = (char *) params->utils->malloc(cb_encoded_length + 1); + if (cb_encoded == NULL) { + MEMERROR( params->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + /* + * Returns SASL_OK on success, SASL_BUFOVER if result won't fit + */ + if (params->utils->encode64((cb_bin != NULL) ? cb_bin : text->gs2_header, + (unsigned int)cb_bin_length, + cb_encoded, + (unsigned int)cb_encoded_length + 1, + NULL) != SASL_OK) { + MEMERROR( params->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + cb_encoded[cb_encoded_length] = '\0'; + + client_proof_len = SCRAM_HASH_SIZE / 3 * 4 + ((SCRAM_HASH_SIZE % 3) ? 4 : 0); + estimated_response_len = strlen(cb_encoded)+ + strlen(text->nonce)+ + client_proof_len + + strlen("c=,r=,p="); + result = _plug_buf_alloc(params->utils, + &(text->out_buf), + &(text->out_buf_len), + (unsigned) estimated_response_len + 1); + if (result != SASL_OK) { + MEMERROR( params->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + /* channel-binding "," nonce ["," extensions] */ + sprintf(text->out_buf, + "c=%s,r=%s", + cb_encoded, + text->nonce); + + length_no_proof = strlen(text->out_buf); + + /* Build AuthMessage */ + full_auth_message = params->utils->realloc(text->auth_message, + text->auth_message_len + 1 + + serverinlen + 1 + + length_no_proof + 1); + if (full_auth_message == NULL) { + MEMERROR( params->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + text->auth_message = full_auth_message; + + text->auth_message[text->auth_message_len] = ','; + memcpy(text->auth_message + text->auth_message_len + 1, serverin, serverinlen); + text->auth_message[text->auth_message_len + 1 + serverinlen] = ','; + memcpy(text->auth_message + text->auth_message_len + 1 + serverinlen + 1, + text->out_buf, + length_no_proof); + text->auth_message_len += serverinlen + 2 + length_no_proof; + text->auth_message[text->auth_message_len] = '\0'; + + /* Calculate ClientProof */ + + /* SaltedPassword := Hi(password, salt) */ + Hi (params->utils, + text->password->data, + text->password->len, + text->salt, + text->salt_len, + text->iteration_count, + text->SaltedPassword); + + PRINT_HASH ("SaltedPassword", text->SaltedPassword); + + /* ClientKey := HMAC(SaltedPassword, "Client Key") */ + if (HMAC(EVP_sha1(), + (const unsigned char *) text->SaltedPassword, + SCRAM_HASH_SIZE, + CLIENT_KEY_CONSTANT, + CLIENT_KEY_CONSTANT_LEN, + (unsigned char *)ClientKey, + &hash_len) == NULL) { + params->utils->seterror(params->utils->conn,0, + "HMAC-SHA1 call failed"); + result = SASL_SCRAM_INTERNAL; + goto cleanup; + } + + PRINT_HASH ("ClientKey", ClientKey); + + /* StoredKey := H(ClientKey) */ + if (SHA1(ClientKey, SCRAM_HASH_SIZE, StoredKey) == NULL) { + params->utils->seterror(params->utils->conn,0, + "SHA1 call failed"); + result = SASL_SCRAM_INTERNAL; + goto cleanup; + } + + PRINT_HASH ("StoredKey", StoredKey); + + /* ClientSignature := HMAC(StoredKey, AuthMessage) */ + if (HMAC(EVP_sha1(), + (const unsigned char *)StoredKey, + SCRAM_HASH_SIZE, + text->auth_message, + (int)text->auth_message_len, + (unsigned char *)ClientSignature, + &hash_len) == NULL) { + params->utils->seterror(params->utils->conn,0, + "HMAC-SHA1 call failed"); + result = SASL_SCRAM_INTERNAL; + goto cleanup; + } + + PRINT_HASH ("ClientSignature", ClientSignature); + + /* ClientProof := ClientKey XOR ClientSignature */ + for (k = 0; k < SCRAM_HASH_SIZE; k++) { + ClientProof[k] = ClientKey[k] ^ ClientSignature[k]; + } + + PRINT_HASH ("ClientProof", ClientProof); + + /* base64-encode ClientProof */ + client_proof = (char *) params->utils->malloc(client_proof_len + 1); + if (client_proof == NULL) { + MEMERROR( params->utils ); + result = SASL_NOMEM; + goto cleanup; + } + + result = params->utils->encode64(ClientProof, + SCRAM_HASH_SIZE, + client_proof, + (unsigned int)client_proof_len + 1, + NULL); + + if (result != SASL_OK) { + goto cleanup; + } + + client_proof[client_proof_len] = '\0'; + + sprintf(text->out_buf + length_no_proof, + ",p=%s", + client_proof); + + *clientout = text->out_buf; + *clientoutlen = (unsigned) strlen(text->out_buf); + + result = SASL_CONTINUE; + +cleanup: + if (inbuf != NULL) { + params->utils->free(inbuf); + } + + if (client_proof != NULL) { + params->utils->free(client_proof); + } + + if (cb_encoded != NULL) { + params->utils->free(cb_encoded); + } + + if (cb_bin != NULL) { + params->utils->free(cb_bin); + } + + return result; +} + + +static int +scram_client_mech_step3(client_context_t *text, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need __attribute__((unused)), + const char **clientout __attribute__((unused)), + unsigned *clientoutlen __attribute__((unused)), + sasl_out_params_t *oparams) +{ + char * p; + int result; + size_t server_proof_len; + unsigned exact_server_proof_len; + char DecodedServerProof[SCRAM_HASH_SIZE + 1]; + char ServerKey[SCRAM_HASH_SIZE]; + char ServerSignature[SCRAM_HASH_SIZE]; + int k; + unsigned int hash_len = 0; + + if (serverinlen < 3) { + SETERROR(params->utils, "Invalid " SCRAM_SASL_MECH " input expected"); + return SASL_BADPROT; + } + + /* Expecting: 'verifier ["," extensions]' */ + + if (strncmp(serverin, "v=", 2) != 0) { + SETERROR(params->utils, "ServerSignature expected in " SCRAM_SASL_MECH " input"); + return SASL_BADPROT; + } + + p = strchr (serverin + 2, ','); + if (p != NULL) { + server_proof_len = p - (serverin + 2) - 1; + } else { + server_proof_len = serverinlen - 2; + } + + if (params->utils->decode64(serverin + 2, /* ServerProof */ + (unsigned int)server_proof_len, + DecodedServerProof, + SCRAM_HASH_SIZE + 1, + &exact_server_proof_len) != SASL_OK) { + SETERROR(params->utils, "Invalid base64 encoding of the server proof in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + if (exact_server_proof_len != SCRAM_HASH_SIZE) { + SETERROR(params->utils, "Invalid server proof (truncated) in " SCRAM_SASL_MECH " input"); + result = SASL_BADPROT; + goto cleanup; + } + + /* ServerKey := HMAC(SaltedPassword, "Server Key") */ + if (HMAC(EVP_sha1(), + (const unsigned char *)text->SaltedPassword, + SCRAM_HASH_SIZE, + SERVER_KEY_CONSTANT, + SERVER_KEY_CONSTANT_LEN, + (unsigned char *)ServerKey, + &hash_len) == NULL) { + params->utils->seterror(params->utils->conn,0, + "HMAC-SHA1 call failed"); + result = SASL_SCRAM_INTERNAL; + goto cleanup; + } + + /* ServerSignature := HMAC(ServerKey, AuthMessage) */ + if (HMAC(EVP_sha1(), + (const unsigned char *)ServerKey, + SCRAM_HASH_SIZE, + text->auth_message, + (int)text->auth_message_len, + (unsigned char *)ServerSignature, + &hash_len) == NULL) { + params->utils->seterror(params->utils->conn,0, + "HMAC-SHA1 call failed"); + result = SASL_SCRAM_INTERNAL; + goto cleanup; + } + + for (k = 0; k < SCRAM_HASH_SIZE; k++) { + if (DecodedServerProof[k] != ServerSignature[k]) { + SETERROR(params->utils, "ServerSignature mismatch"); + result = SASL_BADAUTH; + goto cleanup; + } + } + + /* set oparams */ + oparams->doneflag = 1; + oparams->mech_ssf = 0; + oparams->maxoutbuf = 0; + oparams->encode_context = NULL; + oparams->encode = NULL; + oparams->decode_context = NULL; + oparams->decode = NULL; + oparams->param_version = 0; + + result = SASL_OK; + +cleanup: + return result; +} + +static int scram_client_mech_step(void *conn_context, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + int result = SASL_FAIL; + client_context_t *text = (client_context_t *) conn_context; + + *clientout = NULL; + *clientoutlen = 0; + + /* this should be well more than is ever needed */ + if (serverinlen > MAX_SERVERIN_LEN) { + SETERROR(params->utils, SCRAM_SASL_MECH " input longer than " STRINGIZE((MAX_SERVERIN_LEN)) " bytes"); + return SASL_BADPROT; + } + + switch (text->state) { + case 0: + result = scram_client_mech_step1(text, + params, + serverin, + serverinlen, + prompt_need, + clientout, + clientoutlen, + oparams); + break; + + case 1: + result = scram_client_mech_step2(text, + params, + serverin, + serverinlen, + prompt_need, + clientout, + clientoutlen, + oparams); + break; + + case 2: + result = scram_client_mech_step3(text, + params, + serverin, + serverinlen, + prompt_need, + clientout, + clientoutlen, + oparams); + break; + + default: /* should never get here */ + params->utils->log(NULL, SASL_LOG_ERR, + "Invalid " SCRAM_SASL_MECH " client step %d\n", text->state); + return SASL_FAIL; + } + + if (result != SASL_INTERACT) { + text->state++; + } + return result; +} + +static void scram_client_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + client_context_t *text = (client_context_t *) conn_context; + + if (!text) return; + + /* get rid of all sensitive info */ + if (text->free_password) { + _plug_free_secret(utils, &text->password); + text->free_password = 0; + } + + if (text->gs2_header) { + utils->free(text->gs2_header); + text->gs2_header = NULL; + } + + if (text->out_buf) { + utils->free(text->out_buf); + text->out_buf = NULL; + } + + if (text->auth_message) _plug_free_string(utils,&(text->auth_message)); + if (text->nonce) _plug_free_string(utils,&(text->nonce)); + if (text->salt) utils->free(text->salt); + + utils->free(text); +} + +static sasl_client_plug_t scram_client_plugins[] = +{ + { + SCRAM_SASL_MECH, /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS + | SASL_SEC_NOACTIVE + | SASL_SEC_MUTUAL_AUTH, /* security_flags */ + SASL_FEAT_ALLOWS_PROXY + | SASL_FEAT_CHANNEL_BINDING, /* features */ + NULL, /* required_prompts */ + NULL, /* glob_context */ + &scram_client_mech_new, /* mech_new */ + &scram_client_mech_step, /* mech_step */ + &scram_client_mech_dispose, /* mech_dispose */ + NULL, /* mech_free */ + NULL, /* idle */ + NULL, /* spare */ + NULL /* spare */ + } +}; + +int scram_client_plug_init(const sasl_utils_t *utils, + int maxversion, + int *out_version, + sasl_client_plug_t **pluglist, + int *plugcount) +{ + if (maxversion < SASL_CLIENT_PLUG_VERSION) { + SETERROR( utils, SCRAM_SASL_MECH " version mismatch"); + return SASL_BADVERS; + } + + *out_version = SASL_CLIENT_PLUG_VERSION; + *pluglist = scram_client_plugins; + *plugcount = 1; + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/scram_init.c b/libs/cyrussasl/plugins/scram_init.c new file mode 100644 index 00000000..c5d828bd --- /dev/null +++ b/libs/cyrussasl/plugins/scram_init.c @@ -0,0 +1,43 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_CLIENT_PLUG_INIT( scram ) +SASL_SERVER_PLUG_INIT( scram ) + diff --git a/libs/cyrussasl/plugins/sql.c b/libs/cyrussasl/plugins/sql.c new file mode 100644 index 00000000..3b89383a --- /dev/null +++ b/libs/cyrussasl/plugins/sql.c @@ -0,0 +1,1359 @@ +/* +** +** SQL Auxprop plugin +** +** Ken Murchison +** Maya Nigrosh -- original store() and txn support +** Simon Loader -- original mysql plugin +** Patrick Welche -- original pgsql plugin +** +** $Id: sql.c,v 1.38 2009/04/11 10:48:07 mel Exp $ +** +*/ + +#include + +#include +#include +#include +#include + +#include "sasl.h" +#include "saslutil.h" +#include "saslplug.h" + +#include + +#include "plugin_common.h" + +#define sql_max(a, b) ((a) > (b) ? (a) : (b)) +#define sql_len(input) ((input) ? strlen(input) : 0) +#define sql_exists(input) ((input) && (*input)) + +typedef struct sql_engine { + const char *name; + void *(*sql_open)(char *host, char *port, int usessl, + const char *user, const char *password, + const char *database, const sasl_utils_t *utils); + int (*sql_escape_str)(char *to, const char *from); + int (*sql_begin_txn)(void *conn, const sasl_utils_t *utils); + int (*sql_commit_txn)(void *conn, const sasl_utils_t *utils); + int (*sql_rollback_txn)(void *conn, const sasl_utils_t *utils); + int (*sql_exec)(void *conn, const char *cmd, char *value, size_t size, + size_t *value_len, const sasl_utils_t *utils); + void (*sql_close)(void *conn); +} sql_engine_t; + +typedef struct sql_settings { + const sql_engine_t *sql_engine; + const char *sql_user; + const char *sql_passwd; + const char *sql_hostnames; + const char *sql_database; + const char *sql_select; + const char *sql_insert; + const char *sql_update; + int sql_usessl; +} sql_settings_t; + +static const char * SQL_BLANK_STRING = ""; +static const char * SQL_WILDCARD = "*"; +static const char * SQL_NULL_VALUE = "NULL"; + + +#ifdef HAVE_MYSQL +#include + +static void *_mysql_open(char *host, char *port, int usessl, + const char *user, const char *password, + const char *database, const sasl_utils_t *utils) +{ + MYSQL *mysql; + + if (!(mysql = mysql_init(NULL))) { + utils->log(NULL, SASL_LOG_ERR, + "sql plugin: could not execute mysql_init()"); + return NULL; + } + + return mysql_real_connect(mysql, host, user, password, database, + port ? strtoul(port, NULL, 10) : 0, NULL, + usessl ? CLIENT_SSL : 0); +} + +static int _mysql_escape_str(char *to, const char *from) +{ + return mysql_escape_string(to, from, strlen(from)); +} + +static int _mysql_exec(void *conn, const char *cmd, char *value, size_t size, + size_t *value_len, const sasl_utils_t *utils) +{ + MYSQL_RES *result; + MYSQL_ROW row; + int row_count, len; + + len = strlen(cmd); + /* mysql_real_query() doesn't want a terminating ';' */ + if (cmd[len-1] == ';') len--; + + /* + * Run the query. It is important to note that mysql_real_query + * will return success even if the sql statement + * had an error in it. However, mysql_errno() will alsways + * tell us if there was an error. Therefore we can ignore + * the result from mysql_real_query and simply check mysql_errno() + * to decide if there was really an error. + */ + (void)mysql_real_query(conn, cmd, len); + + if(mysql_errno(conn)) { + utils->log(NULL, SASL_LOG_ERR, "sql query failed: %s", + mysql_error(conn)); + return -1; + } + + /* see if we should expect some results */ + if (!mysql_field_count(conn)) { + /* no results (BEGIN, COMMIT, DELETE, INSERT, UPDATE) */ + return 0; + } + + /* get the results */ + result = mysql_store_result(conn); + if (!result) { + /* umm nothing found */ + utils->log(NULL, SASL_LOG_NOTE, "sql plugin: no result found"); + return -1; + } + + /* quick row check */ + row_count = mysql_num_rows(result); + if (!row_count) { + /* umm nothing found */ + mysql_free_result(result); + utils->log(NULL, SASL_LOG_NOTE, "sql plugin: no result found"); + return -1; + } + if (row_count > 1) { + utils->log(NULL, SASL_LOG_WARN, + "sql plugin: found duplicate row for query %s", cmd); + } + + /* now get the result set value and value_len */ + /* we only fetch one because we don't care about the rest */ + row = mysql_fetch_row(result); + if (!row || !row[0]) { + /* umm nothing found */ + utils->log(NULL, SASL_LOG_NOTE, "sql plugin: no result found"); + mysql_free_result(result); + return -1; + } + if (value) { + strncpy(value, row[0], size-2); + value[size-1] = '\0'; + if (value_len) *value_len = strlen(value); + } + + /* free result */ + mysql_free_result(result); + + return 0; +} + +static int _mysql_begin_txn(void *conn, const sasl_utils_t *utils) +{ + return _mysql_exec(conn, +#if MYSQL_VERSION_ID >= 40011 + "START TRANSACTION", +#else + "BEGIN", +#endif + NULL, 0, NULL, utils); +} + +static int _mysql_commit_txn(void *conn, const sasl_utils_t *utils) +{ + return _mysql_exec(conn, "COMMIT", NULL, 0, NULL, utils); +} + +static int _mysql_rollback_txn(void *conn, const sasl_utils_t *utils) +{ + return _mysql_exec(conn, "ROLLBACK", NULL, 0, NULL, utils); +} + +static void _mysql_close(void *conn) +{ + mysql_close(conn); +} +#endif /* HAVE_MYSQL */ + +#ifdef HAVE_PGSQL +#include + +static void *_pgsql_open(char *host, char *port, int usessl, + const char *user, const char *password, + const char *database, const sasl_utils_t *utils) +{ + PGconn *conn = NULL; + char *conninfo, *sep; + + /* create the connection info string */ + /* The 64 represents the number of characters taken by + * the keyword tokens, plus a small pad + */ + conninfo = utils->malloc(64 + sql_len(host) + sql_len(port) + + sql_len(user) + sql_len(password) + + sql_len(database)); + if (!conninfo) { + MEMERROR(utils); + return NULL; + } + + /* add each term that exists */ + conninfo[0] = '\0'; + sep = ""; + if (sql_exists(host)) { + strcat(conninfo, sep); + strcat(conninfo, "host='"); + strcat(conninfo, host); + strcat(conninfo, "'"); + sep = " "; + } + if (sql_exists(port)) { + strcat(conninfo, sep); + strcat(conninfo, "port='"); + strcat(conninfo, port); + strcat(conninfo, "'"); + sep = " "; + } + if (sql_exists(user)) { + strcat(conninfo, sep); + strcat(conninfo, "user='"); + strcat(conninfo, user); + strcat(conninfo, "'"); + sep = " "; + } + if (sql_exists(password)) { + strcat(conninfo, sep); + strcat(conninfo, "password='"); + strcat(conninfo, password); + strcat(conninfo, "'"); + sep = " "; + } + if (sql_exists(database)) { + strcat(conninfo, sep); + strcat(conninfo, "dbname='"); + strcat(conninfo, database); + strcat(conninfo, "'"); + sep = " "; + } + if (usessl) { + strcat(conninfo, sep); + strcat(conninfo, "requiressl='1'"); + } + + conn = PQconnectdb(conninfo); + free(conninfo); + + if ((PQstatus(conn) != CONNECTION_OK)) { + utils->log(NULL, SASL_LOG_ERR, "sql plugin: %s", PQerrorMessage(conn)); + return NULL; + } + + return conn; +} + +static int _pgsql_escape_str(char *to, const char *from) +{ + return PQescapeString(to, from, strlen(from)); +} + +static int _pgsql_exec(void *conn, const char *cmd, char *value, size_t size, + size_t *value_len, const sasl_utils_t *utils) +{ + PGresult *result; + int row_count; + ExecStatusType status; + + /* run the query */ + result = PQexec(conn, cmd); + + /* check the status */ + status = PQresultStatus(result); + if (status == PGRES_COMMAND_OK) { + /* no results (BEGIN, COMMIT, DELETE, INSERT, UPDATE) */ + PQclear(result); + return 0; + } + else if (status != PGRES_TUPLES_OK) { + /* error */ + utils->log(NULL, SASL_LOG_DEBUG, "sql plugin: %s ", + PQresStatus(status)); + PQclear(result); + return -1; + } + + /* quick row check */ + row_count = PQntuples(result); + if (!row_count) { + /* umm nothing found */ + utils->log(NULL, SASL_LOG_NOTE, "sql plugin: no result found"); + PQclear(result); + return -1; + } + if (row_count > 1) { + utils->log(NULL, SASL_LOG_WARN, + "sql plugin: found duplicate row for query %s", cmd); + } + + /* now get the result set value and value_len */ + /* we only fetch one because we don't care about the rest */ + if (value) { + strncpy(value, PQgetvalue(result,0,0), size-2); + value[size-1] = '\0'; + if (value_len) *value_len = strlen(value); + } + + /* free result */ + PQclear(result); + return 0; +} + +static int _pgsql_begin_txn(void *conn, const sasl_utils_t *utils) +{ + return _pgsql_exec(conn, "BEGIN;", NULL, 0, NULL, utils); +} + +static int _pgsql_commit_txn(void *conn, const sasl_utils_t *utils) +{ + return _pgsql_exec(conn, "COMMIT;", NULL, 0, NULL, utils); +} + +static int _pgsql_rollback_txn(void *conn, const sasl_utils_t *utils) +{ + return _pgsql_exec(conn, "ROLLBACK;", NULL, 0, NULL, utils); +} + +static void _pgsql_close(void *conn) +{ + PQfinish(conn); +} +#endif /* HAVE_PGSQL */ + +#ifdef HAVE_SQLITE +#include + +static void *_sqlite_open(char *host __attribute__((unused)), + char *port __attribute__((unused)), + int usessl __attribute__((unused)), + const char *user __attribute__((unused)), + const char *password __attribute__((unused)), + const char *database, const sasl_utils_t *utils) +{ + int rc; + sqlite *db; + char *zErrMsg = NULL; + + db = sqlite_open(database, 0, &zErrMsg); + if (db == NULL) { + utils->log(NULL, SASL_LOG_ERR, "sql plugin: %s", zErrMsg); + sqlite_freemem (zErrMsg); + return NULL; + } + + rc = sqlite_exec(db, "PRAGMA empty_result_callbacks = ON", NULL, NULL, &zErrMsg); + if (rc != SQLITE_OK) { + utils->log(NULL, SASL_LOG_ERR, "sql plugin: %s", zErrMsg); + sqlite_freemem (zErrMsg); + sqlite_close(db); + return NULL; + } + + return (void*)db; +} + +static int _sqlite_escape_str(char *to, const char *from) +{ + char s; + + while ( (s = *from++) != '\0' ) { + if (s == '\'' || s == '\\') { + *to++ = '\\'; + } + *to++ = s; + } + *to = '\0'; + + return 0; +} + +static int sqlite_my_callback(void *pArg, int argc __attribute__((unused)), + char **argv, + char **columnNames __attribute__((unused))) +{ + char **result = (char**)pArg; + + if (argv == NULL) { + *result = NULL; /* no record */ + } else if (argv[0] == NULL) { + *result = strdup(SQL_NULL_VALUE); /* NULL IS SQL_NULL_VALUE */ + } else { + *result = strdup(argv[0]); + } + + return /*ABORT*/1; +} + +static int _sqlite_exec(void *db, const char *cmd, char *value, size_t size, + size_t *value_len, const sasl_utils_t *utils) +{ + int rc; + char *result = NULL; + char *zErrMsg = NULL; + + rc = sqlite_exec((sqlite*)db, cmd, sqlite_my_callback, (void*)&result, &zErrMsg); + if (rc != SQLITE_OK && rc != SQLITE_ABORT) { + utils->log(NULL, SASL_LOG_DEBUG, "sql plugin: %s ", zErrMsg); + sqlite_freemem (zErrMsg); + return -1; + } + + if (rc == SQLITE_OK) { + /* no results (BEGIN, COMMIT, DELETE, INSERT, UPDATE) */ + return 0; + } + + if (result == NULL) { + /* umm nothing found */ + utils->log(NULL, SASL_LOG_NOTE, "sql plugin: no result found"); + return -1; + } + + /* XXX: Duplication cannot be found by this method. */ + + /* now get the result set value and value_len */ + /* we only fetch one because we don't care about the rest */ + if (value) { + strncpy(value, result, size - 2); + value[size - 1] = '\0'; + if (value_len) { + *value_len = strlen(value); + } + } + + /* free result */ + free(result); + return 0; +} + +static int _sqlite_begin_txn(void *db, const sasl_utils_t *utils) +{ + return _sqlite_exec(db, "BEGIN TRANSACTION", NULL, 0, NULL, utils); +} + +static int _sqlite_commit_txn(void *db, const sasl_utils_t *utils) +{ + return _sqlite_exec(db, "COMMIT TRANSACTION", NULL, 0, NULL, utils); +} + +static int _sqlite_rollback_txn(void *db, const sasl_utils_t *utils) +{ + return _sqlite_exec(db, "ROLLBACK TRANSACTION", NULL, 0, NULL, utils); +} + +static void _sqlite_close(void *db) +{ + sqlite_close((sqlite*)db); +} +#endif /* HAVE_SQLITE */ + +#ifdef HAVE_SQLITE3 +#include + +static void *_sqlite3_open(char *host __attribute__((unused)), + char *port __attribute__((unused)), + int usessl __attribute__((unused)), + const char *user __attribute__((unused)), + const char *password __attribute__((unused)), + const char *database, const sasl_utils_t *utils) +{ + int rc; + sqlite3 *db; + char *zErrMsg = NULL; + + rc = sqlite3_open(database, &db); + if (SQLITE_OK != rc) { + if (db) + utils->log(NULL, SASL_LOG_ERR, "sql plugin: %s", sqlite3_errmsg(db)); + else + utils->log(NULL, SASL_LOG_ERR, "sql plugin: %d", rc); + sqlite3_close(db); + return NULL; + } + + rc = sqlite3_exec(db, "PRAGMA empty_result_callbacks = ON", NULL, NULL, &zErrMsg); + if (rc != SQLITE_OK) { + if (zErrMsg) { + utils->log(NULL, SASL_LOG_ERR, "sql plugin: %s", zErrMsg); + sqlite3_free(zErrMsg); + } else + utils->log(NULL, SASL_LOG_DEBUG, "sql plugin: %d", rc); + sqlite3_close(db); + return NULL; + } + + return (void*)db; +} + +static int _sqlite3_escape_str(char *to, const char *from) +{ + char s; + + while ( (s = *from++) != '\0' ) { + if (s == '\'' || s == '\\') { + *to++ = '\\'; + } + *to++ = s; + } + *to = '\0'; + + return 0; +} + +static int sqlite3_my_callback(void *pArg, int argc __attribute__((unused)), + char **argv, + char **columnNames __attribute__((unused))) +{ + char **result = (char**)pArg; + + if (argv == NULL) { + *result = NULL; /* no record */ + } else if (argv[0] == NULL) { + *result = strdup(SQL_NULL_VALUE); /* NULL IS SQL_NULL_VALUE */ + } else { + *result = strdup(argv[0]); + } + + return 0; +} + +static int _sqlite3_exec(void *db, + const char *cmd, + char *value, + size_t size, + size_t *value_len, + const sasl_utils_t *utils) +{ + int rc; + char *result = NULL; + char *zErrMsg = NULL; + + rc = sqlite3_exec((sqlite3*)db, cmd, sqlite3_my_callback, (void*)&result, &zErrMsg); + if (rc != SQLITE_OK) { + if (zErrMsg) { + utils->log(NULL, SASL_LOG_DEBUG, "sql plugin: %s", zErrMsg); + sqlite3_free(zErrMsg); + } else { + utils->log(NULL, SASL_LOG_DEBUG, "sql plugin: %d", rc); + } + return -1; + } + + if (value == NULL && rc == SQLITE_OK) { + /* no results (BEGIN, COMMIT, DELETE, INSERT, UPDATE) */ + return 0; + } + + if (result == NULL) { + /* umm nothing found */ + utils->log(NULL, SASL_LOG_NOTE, "sql plugin: no result found"); + return -1; + } + + /* XXX: Duplication cannot be found by this method. */ + + /* now get the result set value and value_len */ + /* we only fetch one because we don't care about the rest */ + if (value) { + strncpy(value, result, size - 2); + value[size - 1] = '\0'; + if (value_len) { + *value_len = strlen(value); + } + } + + free(result); + return 0; +} + +static int _sqlite3_begin_txn(void *db, const sasl_utils_t *utils) +{ + return _sqlite3_exec(db, "BEGIN TRANSACTION;", NULL, 0, NULL, utils); +} + +static int _sqlite3_commit_txn(void *db, const sasl_utils_t *utils) +{ + return _sqlite3_exec(db, "COMMIT TRANSACTION;", NULL, 0, NULL, utils); +} + +static int _sqlite3_rollback_txn(void *db, const sasl_utils_t *utils) +{ + return _sqlite3_exec(db, "ROLLBACK TRANSACTION;", NULL, 0, NULL, utils); +} + +static void _sqlite3_close(void *db) +{ + sqlite3_close((sqlite3*)db); +} +#endif /* HAVE_SQLITE3 */ + +static const sql_engine_t sql_engines[] = { +#ifdef HAVE_MYSQL + { "mysql", &_mysql_open, &_mysql_escape_str, + &_mysql_begin_txn, &_mysql_commit_txn, &_mysql_rollback_txn, + &_mysql_exec, &_mysql_close }, +#endif /* HAVE_MYSQL */ +#ifdef HAVE_PGSQL + { "pgsql", &_pgsql_open, &_pgsql_escape_str, + &_pgsql_begin_txn, &_pgsql_commit_txn, &_pgsql_rollback_txn, + &_pgsql_exec, &_pgsql_close }, +#endif +#ifdef HAVE_SQLITE + { "sqlite", &_sqlite_open, &_sqlite_escape_str, + &_sqlite_begin_txn, &_sqlite_commit_txn, &_sqlite_rollback_txn, + &_sqlite_exec, &_sqlite_close }, +#endif +#ifdef HAVE_SQLITE3 + { "sqlite3", &_sqlite3_open, &_sqlite3_escape_str, + &_sqlite3_begin_txn, &_sqlite3_commit_txn, &_sqlite3_rollback_txn, + &_sqlite3_exec, &_sqlite3_close }, +#endif + { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } +}; + +/* +** Sql_create_statement +** uses statement line and allocate memory to replace +** Parts with the strings provided. +** % = no change +** %% = % +** %u = user +** %p = prop +** %r = realm +** %v = value of prop +** e.g select %p from auth where user = %u and domain = %r; +** Note: calling function must free memory. +** +*/ + +static char *sql_create_statement(const char *statement, const char *prop, + const char *user, const char *realm, + const char *value, + const sasl_utils_t *utils) +{ + const char *ptr, *line_ptr; + char *buf, *buf_ptr; + int filtersize; + int ulen, plen, rlen, vlen; + int numpercents=0; + int biggest; + size_t i; + + /* calculate memory needed for creating the complete query string. */ + ulen = (int)strlen(user); + rlen = (int)strlen(realm); + plen = (int)strlen(prop); + vlen = (int)sql_len(value); + + /* what if we have multiple %foo occurrences in the input query? */ + for (i = 0; i < strlen(statement); i++) { + if (statement[i] == '%') { + numpercents++; + } + } + + /* find the biggest of ulen, rlen, plen, vlen */ + biggest = sql_max(sql_max(ulen, rlen), sql_max(plen, vlen)); + + /* plus one for the semicolon...and don't forget the trailing 0x0 */ + filtersize = (int)strlen(statement) + 1 + (numpercents*biggest)+1; + + /* ok, now try to allocate a chunk of that size */ + buf = (char *) utils->malloc(filtersize); + + if (!buf) { + MEMERROR(utils); + return NULL; + } + + buf_ptr = buf; + line_ptr = statement; + + /* replace the strings */ + while ( (ptr = strchr(line_ptr, '%')) ) { + /* copy up to but not including the next % */ + memcpy(buf_ptr, line_ptr, ptr - line_ptr); + buf_ptr += ptr - line_ptr; + ptr++; + switch (ptr[0]) { + case '%': + buf_ptr[0] = '%'; + buf_ptr++; + break; + case 'u': + memcpy(buf_ptr, user, ulen); + buf_ptr += ulen; + break; + case 'r': + memcpy(buf_ptr, realm, rlen); + buf_ptr += rlen; + break; + case 'p': + memcpy(buf_ptr, prop, plen); + buf_ptr += plen; + break; + case 'v': + if (value != NULL) { + memcpy(buf_ptr, value, vlen); + buf_ptr += vlen; + } + else { + utils->log(NULL, SASL_LOG_ERR, + "'%%v' shouldn't be in a SELECT or DELETE"); + } + break; + default: + buf_ptr[0] = '%'; + buf_ptr[1] = ptr[0]; + buf_ptr += 2; + break; + } + ptr++; + line_ptr = ptr; + } + + memcpy(buf_ptr, line_ptr, strlen(line_ptr)+1); + /* Make sure the current portion of the statement ends with a semicolon */ + if (buf_ptr[strlen(buf_ptr-1)] != ';') { + strcat(buf_ptr, ";"); + } + + return (buf); +} + +/* sql_get_settings + * + * Get the auxprop settings and put them in the global context array +*/ +static void sql_get_settings(const sasl_utils_t *utils, void *glob_context) +{ + sql_settings_t *settings; + int r; + const char *usessl, *engine_name; + const sql_engine_t *e; + + settings = (sql_settings_t *) glob_context; + + r = utils->getopt(utils->getopt_context,"SQL", "sql_engine", + &engine_name, NULL); + if (r || !engine_name) { + engine_name = "mysql"; + } + + /* find the correct engine */ + e = sql_engines; + while (e->name) { + if (!strcasecmp(engine_name, e->name)) break; + e++; + } + + if (!e->name) { + utils->log(NULL, SASL_LOG_ERR, "SQL engine '%s' not supported", + engine_name); + } + + settings->sql_engine = e; + + r = utils->getopt(utils->getopt_context,"SQL","sql_user", + &settings->sql_user, NULL); + if ( r || !settings->sql_user ) { + settings->sql_user = SQL_BLANK_STRING; + } + + r = utils->getopt(utils->getopt_context,"SQL", "sql_passwd", + &settings->sql_passwd, NULL); + if (r || !settings->sql_passwd ) { + settings->sql_passwd = SQL_BLANK_STRING; + } + + r = utils->getopt(utils->getopt_context,"SQL", "sql_hostnames", + &settings->sql_hostnames, NULL); + if (r || !settings->sql_hostnames ) { + settings->sql_hostnames = SQL_BLANK_STRING; + } + + r = utils->getopt(utils->getopt_context,"SQL", "sql_database", + &settings->sql_database, NULL); + if (r || !settings->sql_database ) { + settings->sql_database = SQL_BLANK_STRING; + } + + r = utils->getopt(utils->getopt_context,"SQL", "sql_select", + &settings->sql_select, NULL); + if (r || !settings->sql_select ) { + /* backwards compatibility */ + r = utils->getopt(utils->getopt_context,"SQL", "sql_statement", + &settings->sql_select, NULL); + if (r || !settings->sql_select) { + settings->sql_select = SQL_BLANK_STRING; + } + } + + r = utils->getopt(utils->getopt_context, "SQL", "sql_insert", + &settings->sql_insert, NULL); + if (r || !settings->sql_insert) { + settings->sql_insert = SQL_BLANK_STRING; + } + + r = utils->getopt(utils->getopt_context, "SQL", "sql_update", + &settings->sql_update, NULL); + if (r || !settings->sql_update) { + settings->sql_update = SQL_BLANK_STRING; + } + + r = utils->getopt(utils->getopt_context, "SQL", "sql_usessl", + &usessl, NULL); + if (r || !usessl) usessl = "no"; + + if (*usessl == '1' || *usessl == 'y' || *usessl == 't' || + (*usessl == 'o' && usessl[1] == 'n')) { + settings->sql_usessl = 1; + } else { + settings->sql_usessl = 0; + } +} + +static void *sql_connect(sql_settings_t *settings, const sasl_utils_t *utils) +{ + void *conn = NULL; + char *db_host_ptr = NULL; + char *db_host = NULL; + char *cur_host, *cur_port; + + /* loop around hostnames till we get a connection + * it should probably save the connection but for + * now we will just disconnect everytime + */ + utils->log(NULL, SASL_LOG_DEBUG, + "sql plugin try and connect to a host\n"); + + /* create a working version of the hostnames */ + _plug_strdup(utils, settings->sql_hostnames, &db_host_ptr, NULL); + db_host = db_host_ptr; + cur_host = db_host; + while (cur_host != NULL) { + db_host = strchr(db_host,','); + if (db_host != NULL) { + db_host[0] = '\0'; + + /* loop till we find some text */ + while (!isalnum(db_host[0])) db_host++; + } + + utils->log(NULL, SASL_LOG_DEBUG, + "sql plugin trying to open db '%s' on host '%s'%s\n", + settings->sql_database, cur_host, + settings->sql_usessl ? " using SSL" : ""); + + /* set the optional port */ + if ((cur_port = strchr(cur_host, ':'))) *cur_port++ = '\0'; + + conn = settings->sql_engine->sql_open(cur_host, cur_port, + settings->sql_usessl, + settings->sql_user, + settings->sql_passwd, + settings->sql_database, + utils); + if (conn) break; + + utils->log(NULL, SASL_LOG_ERR, + "sql plugin could not connect to host %s", cur_host); + + cur_host = db_host; + } + + if (db_host_ptr) utils->free(db_host_ptr); + + return conn; +} + +static int sql_auxprop_lookup(void *glob_context, + sasl_server_params_t *sparams, + unsigned flags, + const char *user, + unsigned ulen) +{ + char *userid = NULL; + /* realm could be used for something clever */ + char *realm = NULL; + const char *user_realm = NULL; + const struct propval *to_fetch, *cur; + char value[8192]; + size_t value_len; + char *user_buf; + char *query = NULL; + char *escap_userid = NULL; + char *escap_realm = NULL; + sql_settings_t *settings; + int verify_against_hashed_password; + int saw_user_password = 0; + void *conn = NULL; + int do_txn = 0; + int ret; + + if (!glob_context || !sparams || !user) return SASL_BADPARAM; + + /* setup the settings */ + settings = (sql_settings_t *) glob_context; + + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "sql plugin Parse the username %s\n", user); + + user_buf = sparams->utils->malloc(ulen + 1); + if (!user_buf) { + ret = SASL_NOMEM; + goto done; + } + + memcpy(user_buf, user, ulen); + user_buf[ulen] = '\0'; + + if(sparams->user_realm) { + user_realm = sparams->user_realm; + } else { + user_realm = sparams->serverFQDN; + } + + if ((ret = _plug_parseuser(sparams->utils, + &userid, + &realm, + user_realm, + sparams->serverFQDN, + user_buf)) != SASL_OK ) { + goto done; + } + + /* just need to escape userid and realm now */ + /* allocate some memory */ + escap_userid = (char *)sparams->utils->malloc(strlen(userid)*2+1); + escap_realm = (char *)sparams->utils->malloc(strlen(realm)*2+1); + + if (!escap_userid || !escap_realm) { + ret = SASL_NOMEM; + goto done; + } + + /*************************************/ + + /* find out what we need to get */ + /* this corrupts const char *user */ + to_fetch = sparams->utils->prop_get(sparams->propctx); + if (!to_fetch) { + ret = SASL_NOMEM; + goto done; + } + + conn = sql_connect(settings, sparams->utils); + if (!conn) { + sparams->utils->log(NULL, SASL_LOG_ERR, + "sql plugin couldn't connect to any host\n"); + /* TODO: in the future we might want to extend the internal + SQL driver API to return a more detailed error */ + ret = SASL_FAIL; + goto done; + } + + /* escape out */ + settings->sql_engine->sql_escape_str(escap_userid, userid); + settings->sql_engine->sql_escape_str(escap_realm, realm); + + verify_against_hashed_password = flags & SASL_AUXPROP_VERIFY_AGAINST_HASH; + + /* Assume that nothing is found */ + ret = SASL_NOUSER; + for (cur = to_fetch; cur->name; cur++) { + char *realname = (char *) cur->name; + + /* Only look up properties that apply to this lookup! */ + if (cur->name[0] == '*' + && (flags & SASL_AUXPROP_AUTHZID)) + continue; + if (!(flags & SASL_AUXPROP_AUTHZID)) { + if(cur->name[0] != '*') + continue; + else + realname = (char*)cur->name + 1; + } + + /* If it's there already, we want to see if it needs to be + * overridden. userPassword is a special case, because it's value + is always present if SASL_AUXPROP_VERIFY_AGAINST_HASH is specified. + When SASL_AUXPROP_VERIFY_AGAINST_HASH is set, we just clear userPassword. */ + if (cur->values && !(flags & SASL_AUXPROP_OVERRIDE) && + (verify_against_hashed_password == 0 || + strcasecmp(realname, SASL_AUX_PASSWORD_PROP) != 0)) { + continue; + } else if (cur->values) { + sparams->utils->prop_erase(sparams->propctx, cur->name); + } + + if (strcasecmp(realname, SASL_AUX_PASSWORD_PROP) == 0) { + saw_user_password = 1; + } + + if (!do_txn) { + do_txn = 1; + sparams->utils->log(NULL, SASL_LOG_DEBUG, "begin transaction"); + if (settings->sql_engine->sql_begin_txn(conn, sparams->utils)) { + sparams->utils->log(NULL, SASL_LOG_ERR, + "Unable to begin transaction\n"); + } + } + + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "sql plugin create statement from %s %s %s\n", + realname, escap_userid, escap_realm); + + /* create a statement that we will use */ + query = sql_create_statement(settings->sql_select, + realname,escap_userid, + escap_realm, NULL, + sparams->utils); + if (query == NULL) { + ret = SASL_NOMEM; + break; + } + + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "sql plugin doing query %s\n", query); + + value[0] = '\0'; + value_len = 0; + /* run the query */ + if (!settings->sql_engine->sql_exec(conn, query, value, sizeof(value), + &value_len, sparams->utils)) { + sparams->utils->prop_set(sparams->propctx, + cur->name, + value, + (int)value_len); + ret = SASL_OK; + } + + sparams->utils->free(query); + } + + if (flags & SASL_AUXPROP_AUTHZID) { + /* This is a lie, but the caller can't handle + when we return SASL_NOUSER for authorization identity lookup. */ + if (ret == SASL_NOUSER) { + ret = SASL_OK; + } + } else { + if (ret == SASL_NOUSER && saw_user_password == 0) { + /* Verify user existence by checking presence of + the userPassword attribute */ + if (!do_txn) { + do_txn = 1; + sparams->utils->log(NULL, SASL_LOG_DEBUG, "begin transaction"); + if (settings->sql_engine->sql_begin_txn(conn, sparams->utils)) { + sparams->utils->log(NULL, SASL_LOG_ERR, + "Unable to begin transaction\n"); + } + } + + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "sql plugin create statement from %s %s %s\n", + SASL_AUX_PASSWORD_PROP, + escap_userid, + escap_realm); + + /* create a statement that we will use */ + query = sql_create_statement(settings->sql_select, + SASL_AUX_PASSWORD_PROP, + escap_userid, + escap_realm, + NULL, + sparams->utils); + if (query == NULL) { + ret = SASL_NOMEM; + } else { + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "sql plugin doing query %s\n", query); + + value[0] = '\0'; + value_len = 0; + /* run the query */ + if (!settings->sql_engine->sql_exec(conn, + query, + value, + sizeof(value), + &value_len, + sparams->utils)) { + ret = SASL_OK; + } + + sparams->utils->free(query); + } + } + } + + + if (do_txn) { + sparams->utils->log(NULL, SASL_LOG_DEBUG, "commit transaction"); + if (settings->sql_engine->sql_commit_txn(conn, sparams->utils)) { + sparams->utils->log(NULL, SASL_LOG_ERR, + "Unable to commit transaction\n"); + /* Failure of the commit is non fatal when reading values */ + } + } + + done: + if (escap_userid) sparams->utils->free(escap_userid); + if (escap_realm) sparams->utils->free(escap_realm); + if (conn) settings->sql_engine->sql_close(conn); + if (userid) sparams->utils->free(userid); + if (realm) sparams->utils->free(realm); + if (user_buf) sparams->utils->free(user_buf); + + return (ret); +} + +static int sql_auxprop_store(void *glob_context, + sasl_server_params_t *sparams, + struct propctx *ctx, + const char *user, + unsigned ulen) +{ + char *userid = NULL; + char *realm = NULL; + const char *user_realm = NULL; + int ret = SASL_FAIL; + const struct propval *to_store, *cur; + + char *user_buf; + char *statement = NULL; + char *escap_userid = NULL; + char *escap_realm = NULL; + const char *cmd; + + sql_settings_t *settings; + void *conn = NULL; + + settings = (sql_settings_t *) glob_context; + + /* just checking if we are enabled */ + if (!ctx && + sql_exists(settings->sql_insert) && + sql_exists(settings->sql_update)) return SASL_OK; + + /* make sure our input is okay */ + if (!glob_context || !sparams || !user) return SASL_BADPARAM; + + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "sql plugin Parse the username %s\n", user); + + user_buf = sparams->utils->malloc(ulen + 1); + if (!user_buf) { + ret = SASL_NOMEM; + goto done; + } + + memcpy(user_buf, user, ulen); + user_buf[ulen] = '\0'; + + if (sparams->user_realm) { + user_realm = sparams->user_realm; + } + else { + user_realm = sparams->serverFQDN; + } + + ret = _plug_parseuser(sparams->utils, &userid, &realm, user_realm, + sparams->serverFQDN, user_buf); + if (ret != SASL_OK) goto done; + + /* just need to escape userid and realm now */ + /* allocate some memory */ + + escap_userid = (char *) sparams->utils->malloc(strlen(userid)*2+1); + escap_realm = (char *) sparams->utils->malloc(strlen(realm)*2+1); + + if (!escap_userid || !escap_realm) { + MEMERROR(sparams->utils); + goto done; + } + + to_store = sparams->utils->prop_get(ctx); + + if (!to_store) { + ret = SASL_BADPARAM; + goto done; + } + + conn = sql_connect(settings, sparams->utils); + if (!conn) { + sparams->utils->log(NULL, SASL_LOG_ERR, + "sql plugin couldn't connect to any host\n"); + goto done; + } + + settings->sql_engine->sql_escape_str(escap_userid, userid); + settings->sql_engine->sql_escape_str(escap_realm, realm); + + if (settings->sql_engine->sql_begin_txn(conn, sparams->utils)) { + sparams->utils->log(NULL, SASL_LOG_ERR, + "Unable to begin transaction\n"); + } + for (cur = to_store; ret == SASL_OK && cur->name; cur++) { + + if (cur->name[0] == '*') { + continue; + } + + /* determine which command we need */ + /* see if we already have a row for this user */ + statement = sql_create_statement(settings->sql_select, + SQL_WILDCARD, escap_userid, + escap_realm, NULL, + sparams->utils); + if (!settings->sql_engine->sql_exec(conn, statement, NULL, 0, NULL, + sparams->utils)) { + /* already have a row => UPDATE */ + cmd = settings->sql_update; + } else { + /* new row => INSERT */ + cmd = settings->sql_insert; + } + sparams->utils->free(statement); + + /* create a statement that we will use */ + statement = sql_create_statement(cmd, cur->name, escap_userid, + escap_realm, + cur->values && cur->values[0] ? + cur->values[0] : SQL_NULL_VALUE, + sparams->utils); + + { + char *log_statement = + sql_create_statement(cmd, cur->name, + escap_userid, + escap_realm, + cur->values && cur->values[0] ? + "" : SQL_NULL_VALUE, + sparams->utils); + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "sql plugin doing statement %s\n", + log_statement); + sparams->utils->free(log_statement); + } + + /* run the statement */ + if (settings->sql_engine->sql_exec(conn, statement, NULL, 0, NULL, + sparams->utils)) { + ret = SASL_FAIL; + } + + sparams->utils->free(statement); + } + if (ret != SASL_OK) { + sparams->utils->log(NULL, SASL_LOG_ERR, + "Failed to store auxprop; aborting transaction\n"); + if (settings->sql_engine->sql_rollback_txn(conn, sparams->utils)) { + sparams->utils->log(NULL, SASL_LOG_ERR, + "Unable to rollback transaction\n"); + } + } + else if (settings->sql_engine->sql_commit_txn(conn, sparams->utils)) { + sparams->utils->log(NULL, SASL_LOG_ERR, + "Unable to commit transaction\n"); + } + + done: + if (escap_userid) sparams->utils->free(escap_userid); + if (escap_realm) sparams->utils->free(escap_realm); + if (conn) settings->sql_engine->sql_close(conn); + if (userid) sparams->utils->free(userid); + if (realm) sparams->utils->free(realm); + if (user_buf) sparams->utils->free(user_buf); + + return ret; + + /* do a little dance */ +} + + +static void sql_auxprop_free(void *glob_context, const sasl_utils_t *utils) +{ + sql_settings_t *settings; + + settings = (sql_settings_t *)glob_context; + + if (!settings) return; + + utils->log(NULL, SASL_LOG_DEBUG, "sql freeing memory\n"); + + utils->free(settings); +} + +static sasl_auxprop_plug_t sql_auxprop_plugin = { + 0, /* Features */ + 0, /* spare */ + NULL, /* glob_context */ + sql_auxprop_free, /* auxprop_free */ + sql_auxprop_lookup, /* auxprop_lookup */ + "sql", /* name */ + sql_auxprop_store /* auxprop_store */ +}; + +int sql_auxprop_plug_init(const sasl_utils_t *utils, + int max_version, + int *out_version, + sasl_auxprop_plug_t **plug, + const char *plugname __attribute__((unused))) +{ + sql_settings_t *settings; + + if (!out_version || !plug) return SASL_BADPARAM; + + if (max_version < SASL_AUXPROP_PLUG_VERSION) return SASL_BADVERS; + *out_version = SASL_AUXPROP_PLUG_VERSION; + + *plug = &sql_auxprop_plugin; + + settings = (sql_settings_t *) utils->malloc(sizeof(sql_settings_t)); + + if (!settings) { + MEMERROR(utils); + return SASL_NOMEM; + } + + memset(settings, 0, sizeof(sql_settings_t)); + sql_get_settings(utils, settings); + + if (!settings->sql_engine->name) return SASL_NOMECH; + + if (!sql_exists(settings->sql_select)) { + utils->log(NULL, SASL_LOG_ERR, "sql_select option missing"); + utils->free(settings); + return SASL_NOMECH; + } + + utils->log(NULL, SASL_LOG_DEBUG, + "sql auxprop plugin using %s engine\n", + settings->sql_engine->name); + + sql_auxprop_plugin.glob_context = settings; + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/sql_init.c b/libs/cyrussasl/plugins/sql_init.c new file mode 100644 index 00000000..ffbe2e86 --- /dev/null +++ b/libs/cyrussasl/plugins/sql_init.c @@ -0,0 +1,38 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_AUXPROP_PLUG_INIT( sql ) + diff --git a/libs/cyrussasl/plugins/srp.c b/libs/cyrussasl/plugins/srp.c new file mode 100644 index 00000000..a07561c6 --- /dev/null +++ b/libs/cyrussasl/plugins/srp.c @@ -0,0 +1,3184 @@ +/* SRP SASL plugin + * Ken Murchison + * Tim Martin 3/17/00 + * $Id: srp.c,v 1.59 2010/11/30 11:41:47 mel Exp $ + */ +/* + * Copyright (c) 1998-2003 Carnegie Mellon University. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. The name "Carnegie Mellon University" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For permission or any other legal + * details, please contact + * Office of Technology Transfer + * Carnegie Mellon University + * 5000 Forbes Avenue + * Pittsburgh, PA 15213-3890 + * (412) 268-4387, fax: (412) 268-7395 + * tech-transfer@andrew.cmu.edu + * + * 4. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by Computing Services + * at Carnegie Mellon University (http://www.cmu.edu/computing/)." + * + * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE + * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Notes: + * + * - The authentication exchanges *should* be correct (per draft -08) + * but we won't know until we do some interop testing. + * + * - The security layers don't conform to draft -08: + * o We don't use eos() and os() elements in an SRP buffer, we send + * just the bare octets. + * o We don't yet use the PRNG() and KDF() primatives described in + * section 5.1. + * + * - Are we using cIV and sIV correctly for encrypt/decrypt? + * + * - We don't implement fast reauth. + */ + +#include +#include +#include +#include +#include +#include + +#ifndef UINT32_MAX +#define UINT32_MAX 4294967295U +#endif + +#if UINT_MAX == UINT32_MAX +typedef unsigned int uint32; +#elif ULONG_MAX == UINT32_MAX +typedef unsigned long uint32; +#elif USHRT_MAX == UINT32_MAX +typedef unsigned short uint32; +#else +#error dont know what to use for uint32 +#endif + +/* for big number support */ +#include + +/* for digest and cipher support */ +#include +#include +#include + +#include +#define MD5_H /* suppress internal MD5 */ +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +/***************************** Common Section *****************************/ + +static const char plugin_id[] = "$Id: srp.c,v 1.59 2010/11/30 11:41:47 mel Exp $"; + +/* Size limit of cipher block size */ +#define SRP_MAXBLOCKSIZE 16 +/* Size limit of SRP buffer */ +#define SRP_MAXBUFFERSIZE 2147483643 + +#define DEFAULT_MDA "SHA-1" + +#define OPTION_MDA "mda=" +#define OPTION_REPLAY_DETECTION "replay_detection" +#define OPTION_INTEGRITY "integrity=" +#define OPTION_CONFIDENTIALITY "confidentiality=" +#define OPTION_MANDATORY "mandatory=" +#define OPTION_MAXBUFFERSIZE "maxbuffersize=" + +/* Table of recommended Modulus (base 16) and Generator pairs */ +struct Ng { + char *N; + unsigned long g; +} Ng_tab[] = { + /* [264 bits] */ + { "115B8B692E0E045692CF280B436735C77A5A9E8A9E7ED56C965F87DB5B2A2ECE3", + 2 + }, + /* [384 bits] */ + { "8025363296FB943FCE54BE717E0E2958A02A9672EF561953B2BAA3BAACC3ED5754EB764C7AB7184578C57D5949CCB41B", + 2 + }, + /* [512 bits] */ + { "D4C7F8A2B32C11B8FBA9581EC4BA4F1B04215642EF7355E37C0FC0443EF756EA2C6B8EEB755A1C723027663CAA265EF785B8FF6A9B35227A52D86633DBDFCA43", + 2 + }, + /* [640 bits] */ + { "C94D67EB5B1A2346E8AB422FC6A0EDAEDA8C7F894C9EEEC42F9ED250FD7F0046E5AF2CF73D6B2FA26BB08033DA4DE322E144E7A8E9B12A0E4637F6371F34A2071C4B3836CBEEAB15034460FAA7ADF483", + 2 + }, + /* [768 bits] */ + { "B344C7C4F8C495031BB4E04FF8F84EE95008163940B9558276744D91F7CC9F402653BE7147F00F576B93754BCDDF71B636F2099E6FFF90E79575F3D0DE694AFF737D9BE9713CEF8D837ADA6380B1093E94B6A529A8C6C2BE33E0867C60C3262B", + 2 + }, + /* [1024 bits] */ + { "EEAF0AB9ADB38DD69C33F80AFA8FC5E86072618775FF3C0B9EA2314C9C256576D674DF7496EA81D3383B4813D692C6E0E0D5D8E250B98BE48E495C1D6089DAD15DC7D7B46154D6B6CE8EF4AD69B15D4982559B297BCF1885C529F566660E57EC68EDBC3C05726CC02FD4CBF4976EAA9AFD5138FE8376435B9FC61D2FC0EB06E3", + 2 + }, + /* [1280 bits] */ + { "D77946826E811914B39401D56A0A7843A8E7575D738C672A090AB1187D690DC43872FC06A7B6A43F3B95BEAEC7DF04B9D242EBDC481111283216CE816E004B786C5FCE856780D41837D95AD787A50BBE90BD3A9C98AC0F5FC0DE744B1CDE1891690894BC1F65E00DE15B4B2AA6D87100C9ECC2527E45EB849DEB14BB2049B163EA04187FD27C1BD9C7958CD40CE7067A9C024F9B7C5A0B4F5003686161F0605B", + 2 + }, + /* [1536 bits] */ + { "9DEF3CAFB939277AB1F12A8617A47BBBDBA51DF499AC4C80BEEEA9614B19CC4D5F4F5F556E27CBDE51C6A94BE4607A291558903BA0D0F84380B655BB9A22E8DCDF028A7CEC67F0D08134B1C8B97989149B609E0BE3BAB63D47548381DBC5B1FC764E3F4B53DD9DA1158BFD3E2B9C8CF56EDF019539349627DB2FD53D24B7C48665772E437D6C7F8CE442734AF7CCB7AE837C264AE3A9BEB87F8A2FE9B8B5292E5A021FFF5E91479E8CE7A28C2442C6F315180F93499A234DCF76E3FED135F9BB", + 2 + }, + /* [2048 bits] */ + { "AC6BDB41324A9A9BF166DE5E1389582FAF72B6651987EE07FC3192943DB56050A37329CBB4A099ED8193E0757767A13DD52312AB4B03310DCD7F48A9DA04FD50E8083969EDB767B0CF6095179A163AB3661A05FBD5FAAAE82918A9962F0B93B855F97993EC975EEAA80D740ADBF4FF747359D041D5C33EA71D281E446B14773BCA97B43A23FB801676BD207A436C6481F1D2B9078717461A5B9D32E688F87748544523B524B0D57D5EA77A2775D2ECFA032CFBDBF52FB3786160279004E57AE6AF874E7303CE53299CCC041C7BC308D82A5698F3A8D0C38271AE35F8E9DBFBB694B5C803D89F7AE435DE236D525F54759B65E372FCD68EF20FA7111F9E4AFF73", + 2 + } +}; + +#define NUM_Ng (sizeof(Ng_tab) / sizeof(struct Ng)) + + +typedef struct layer_option_s { + const char *name; /* name used in option strings */ + unsigned enabled; /* enabled? determined at run-time */ + unsigned bit; /* unique bit in bitmask */ + sasl_ssf_t ssf; /* ssf of layer */ + const char *evp_name; /* name used for lookup in EVP table */ +} layer_option_t; + +static layer_option_t digest_options[] = { + { "SHA-1", 0, (1<<0), 1, "sha1" }, + { "RIPEMD-160", 0, (1<<1), 1, "rmd160" }, + { "MD5", 0, (1<<2), 1, "md5" }, + { NULL, 0, 0, 0, NULL } +}; +static layer_option_t *default_digest = &digest_options[0]; +static layer_option_t *server_mda = NULL; + +static layer_option_t cipher_options[] = { + { "DES", 0, (1<<0), 56, "des-ofb" }, + { "3DES", 0, (1<<1), 112, "des-ede-ofb" }, + { "AES", 0, (1<<2), 128, "aes-128-ofb" }, + { "Blowfish", 0, (1<<3), 128, "bf-ofb" }, + { "CAST-128", 0, (1<<4), 128, "cast5-ofb" }, + { "IDEA", 0, (1<<5), 128, "idea-ofb" }, + { NULL, 0, 0, 0, NULL} +}; +/* XXX Hack until OpenSSL 0.9.7 */ +#if OPENSSL_VERSION_NUMBER < 0x00907000L +static layer_option_t *default_cipher = &cipher_options[0]; +#else +static layer_option_t *default_cipher = &cipher_options[2]; +#endif + + +enum { + BIT_REPLAY_DETECTION= (1<<0), + BIT_INTEGRITY= (1<<1), + BIT_CONFIDENTIALITY= (1<<2) +}; + +typedef struct srp_options_s { + unsigned mda; /* bitmask of MDAs */ + unsigned replay_detection; /* replay detection on/off flag */ + unsigned integrity; /* bitmask of integrity layers */ + unsigned confidentiality; /* bitmask of confidentiality layers */ + unsigned mandatory; /* bitmask of mandatory layers */ + unsigned long maxbufsize; /* max # bytes processed by security layer */ +} srp_options_t; + +/* The main SRP context */ +typedef struct context { + int state; + + BIGNUM N; /* safe prime modulus */ + BIGNUM g; /* generator */ + + BIGNUM v; /* password verifier */ + + BIGNUM b; /* server private key */ + BIGNUM B; /* server public key */ + + BIGNUM a; /* client private key */ + BIGNUM A; /* client public key */ + + char K[EVP_MAX_MD_SIZE]; /* shared context key */ + int Klen; + + char M1[EVP_MAX_MD_SIZE]; /* client evidence */ + int M1len; + + char *authid; /* authentication id (server) */ + char *userid; /* authorization id (server) */ + sasl_secret_t *password; /* user secret (client) */ + unsigned int free_password; /* set if we need to free password */ + + char *client_options; + char *server_options; + + srp_options_t client_opts; /* cache between client steps */ + char cIV[SRP_MAXBLOCKSIZE]; /* cache between client steps */ + + char *salt; /* password salt */ + int saltlen; + + const EVP_MD *md; /* underlying MDA */ + + /* copy of utils from the params structures */ + const sasl_utils_t *utils; + + /* per-step mem management */ + char *out_buf; + unsigned out_buf_len; + + /* Layer foo */ + unsigned layer; /* bitmask of enabled layers */ + const EVP_MD *hmac_md; /* HMAC for integrity */ + HMAC_CTX hmac_send_ctx; + HMAC_CTX hmac_recv_ctx; + + const EVP_CIPHER *cipher; /* cipher for confidentiality */ + EVP_CIPHER_CTX cipher_enc_ctx; + EVP_CIPHER_CTX cipher_dec_ctx; + + /* replay detection sequence numbers */ + int seqnum_out; + int seqnum_in; + + /* for encoding/decoding mem management */ + char *encode_buf, *decode_buf, *decode_pkt_buf; + unsigned encode_buf_len, decode_buf_len, decode_pkt_buf_len; + + /* layers buffering */ + decode_context_t decode_context; + +} context_t; + +static int srp_encode(void *context, + const struct iovec *invec, + unsigned numiov, + const char **output, + unsigned *outputlen) +{ + context_t *text = (context_t *) context; + unsigned i; + char *input; + unsigned long inputlen, tmpnum; + int ret; + + if (!context || !invec || !numiov || !output || !outputlen) { + PARAMERROR( text->utils ); + return SASL_BADPARAM; + } + + /* calculate total size of input */ + for (i = 0, inputlen = 0; i < numiov; i++) + inputlen += invec[i].iov_len; + + /* allocate a buffer for the output */ + ret = _plug_buf_alloc(text->utils, &text->encode_buf, + &text->encode_buf_len, + 4 + /* for length */ + inputlen + /* for content */ + SRP_MAXBLOCKSIZE + /* for PKCS padding */ + EVP_MAX_MD_SIZE); /* for HMAC */ + if (ret != SASL_OK) return ret; + + *outputlen = 4; /* length */ + + /* operate on each iovec */ + for (i = 0; i < numiov; i++) { + input = invec[i].iov_base; + inputlen = invec[i].iov_len; + + if (text->layer & BIT_CONFIDENTIALITY) { + unsigned enclen; + + /* encrypt the data into the output buffer */ + EVP_EncryptUpdate(&text->cipher_enc_ctx, + text->encode_buf + *outputlen, &enclen, + input, inputlen); + *outputlen += enclen; + + /* switch the input to the encrypted data */ + input = text->encode_buf + 4; + inputlen = *outputlen - 4; + } + else { + /* copy the raw input to the output */ + memcpy(text->encode_buf + *outputlen, input, inputlen); + *outputlen += inputlen; + } + } + + if (text->layer & BIT_CONFIDENTIALITY) { + unsigned enclen; + + /* encrypt the last block of data into the output buffer */ + EVP_EncryptFinal(&text->cipher_enc_ctx, + text->encode_buf + *outputlen, &enclen); + *outputlen += enclen; + } + + if (text->layer & BIT_INTEGRITY) { + unsigned hashlen; + + /* hash the content */ + HMAC_Update(&text->hmac_send_ctx, text->encode_buf+4, *outputlen-4); + + if (text->layer & BIT_REPLAY_DETECTION) { + /* hash the sequence number */ + tmpnum = htonl(text->seqnum_out); + HMAC_Update(&text->hmac_send_ctx, (char *) &tmpnum, 4); + + text->seqnum_out++; + } + + /* append the HMAC into the output buffer */ + HMAC_Final(&text->hmac_send_ctx, text->encode_buf + *outputlen, + &hashlen); + *outputlen += hashlen; + } + + /* prepend the length of the output */ + tmpnum = *outputlen - 4; + tmpnum = htonl(tmpnum); + memcpy(text->encode_buf, &tmpnum, 4); + + *output = text->encode_buf; + + return SASL_OK; +} + +/* decode a single SRP packet */ +static int srp_decode_packet(void *context, + const char *input, + unsigned inputlen, + char **output, + unsigned *outputlen) +{ + context_t *text = (context_t *) context; + int ret; + + if (text->layer & BIT_INTEGRITY) { + const char *hash; + char myhash[EVP_MAX_MD_SIZE]; + unsigned hashlen, myhashlen, i; + unsigned long tmpnum; + + hashlen = EVP_MD_size(text->hmac_md); + + if (inputlen < hashlen) { + text->utils->seterror(text->utils->conn, 0, + "SRP input is smaller " + "than hash length: %d vs %d\n", + inputlen, hashlen); + return SASL_BADPROT; + } + + inputlen -= hashlen; + hash = input + inputlen; + + /* create our own hash from the input */ + HMAC_Update(&text->hmac_recv_ctx, input, inputlen); + + if (text->layer & BIT_REPLAY_DETECTION) { + /* hash the sequence number */ + tmpnum = htonl(text->seqnum_in); + HMAC_Update(&text->hmac_recv_ctx, (char *) &tmpnum, 4); + + text->seqnum_in++; + } + + HMAC_Final(&text->hmac_recv_ctx, myhash, &myhashlen); + + /* compare hashes */ + for (i = 0; i < hashlen; i++) { + if ((myhashlen != hashlen) || (myhash[i] != hash[i])) { + SETERROR(text->utils, "Hash is incorrect\n"); + return SASL_BADMAC; + } + } + } + + ret = _plug_buf_alloc(text->utils, &(text->decode_pkt_buf), + &(text->decode_pkt_buf_len), + inputlen); + if (ret != SASL_OK) return ret; + + if (text->layer & BIT_CONFIDENTIALITY) { + unsigned declen; + + /* decrypt the data into the output buffer */ + EVP_DecryptUpdate(&text->cipher_dec_ctx, + text->decode_pkt_buf, &declen, + (char *) input, inputlen); + *outputlen = declen; + + EVP_DecryptFinal(&text->cipher_dec_ctx, + text->decode_pkt_buf + declen, &declen); + *outputlen += declen; + } else { + /* copy the raw input to the output */ + memcpy(text->decode_pkt_buf, input, inputlen); + *outputlen = inputlen; + } + + *output = text->decode_pkt_buf; + + return SASL_OK; +} + +/* decode and concatenate multiple SRP packets */ +static int srp_decode(void *context, + const char *input, unsigned inputlen, + const char **output, unsigned *outputlen) +{ + context_t *text = (context_t *) context; + int ret; + + ret = _plug_decode(&text->decode_context, input, inputlen, + &text->decode_buf, &text->decode_buf_len, outputlen, + srp_decode_packet, text); + + *output = text->decode_buf; + + return ret; +} + +/* + * Convert a big integer to it's byte representation + */ +static int BigIntToBytes(BIGNUM *num, char *out, int maxoutlen, int *outlen) +{ + int len; + + len = BN_num_bytes(num); + + if (len > maxoutlen) return SASL_FAIL; + + *outlen = BN_bn2bin(num, out); + + return SASL_OK; +} + +/* + * Compare a big integer against a word. + */ +static int BigIntCmpWord(BIGNUM *a, BN_ULONG w) +{ + BIGNUM *b = BN_new(); + int r; + + BN_set_word(b, w); + r = BN_cmp(a, b); + BN_free(b); + return r; +} + +/* + * Generate a random big integer. + */ +static void GetRandBigInt(BIGNUM *out) +{ + BN_init(out); + + /* xxx likely should use sasl random funcs */ + BN_rand(out, SRP_MAXBLOCKSIZE*8, 0, 0); +} + +#define MAX_BUFFER_LEN 2147483643 +#define MAX_MPI_LEN 65535 +#define MAX_UTF8_LEN 65535 +#define MAX_OS_LEN 255 + +/* + * Make an SRP buffer from the data specified by the fmt string. + */ +static int MakeBuffer(const sasl_utils_t *utils, char **buf, unsigned *buflen, + unsigned *outlen, const char *fmt, ...) +{ + va_list ap; + char *p, *out = NULL; + int r, alloclen, len; + BIGNUM *mpi; + char *os, *str, c; + uint32 u; + short ns; + long totlen; + + /* first pass to calculate size of buffer */ + va_start(ap, fmt); + for (p = (char *) fmt, alloclen = 0; *p; p++) { + if (*p != '%') { + alloclen++; + continue; + } + + switch (*++p) { + case 'm': + /* MPI */ + mpi = va_arg(ap, BIGNUM *); + len = BN_num_bytes(mpi); + if (len > MAX_MPI_LEN) { + utils->log(NULL, SASL_LOG_ERR, + "String too long to create mpi string\n"); + r = SASL_FAIL; + goto done; + } + alloclen += len + 2; + break; + + case 'o': + /* octet sequence (len followed by data) */ + len = va_arg(ap, int); + if (len > MAX_OS_LEN) { + utils->log(NULL, SASL_LOG_ERR, + "String too long to create os string\n"); + r = SASL_FAIL; + goto done; + } + alloclen += len + 1; + os = va_arg(ap, char *); + break; + + case 's': + /* string */ + str = va_arg(ap, char *); + len = strlen(str); + if (len > MAX_UTF8_LEN) { + utils->log(NULL, SASL_LOG_ERR, + "String too long to create utf8 string\n"); + r = SASL_FAIL; + goto done; + } + alloclen += len + 2; + break; + + case 'u': + /* unsigned int */ + u = va_arg(ap, uint32); + alloclen += sizeof(uint32); + break; + + case 'c': + /* char */ + c = va_arg(ap, int) & 0xFF; + alloclen += 1; + break; + + default: + alloclen += 1; + break; + } + } + va_end(ap); + + if (alloclen > MAX_BUFFER_LEN) { + utils->log(NULL, SASL_LOG_ERR, + "String too long to create SRP buffer string\n"); + return SASL_FAIL; + } + + alloclen += 4; + r = _plug_buf_alloc(utils, buf, buflen, alloclen); + if (r != SASL_OK) return r; + + out = *buf + 4; /* skip size for now */ + + /* second pass to fill buffer */ + va_start(ap, fmt); + for (p = (char *) fmt; *p; p++) { + if (*p != '%') { + *out = *p; + out++; + continue; + } + + switch (*++p) { + case 'm': + /* MPI */ + mpi = va_arg(ap, BIGNUM *); + r = BigIntToBytes(mpi, out+2, BN_num_bytes(mpi), &len); + if (r) goto done; + ns = htons(len); + memcpy(out, &ns, 2); /* add 2 byte len (network order) */ + out += len + 2; + break; + + case 'o': + /* octet sequence (len followed by data) */ + len = va_arg(ap, int); + os = va_arg(ap, char *); + *out = len & 0xFF; /* add 1 byte len */ + memcpy(out+1, os, len); /* add data */ + out += len+1; + break; + + case 's': + /* string */ + str = va_arg(ap, char *); + /* xxx do actual utf8 conversion */ + len = strlen(str); + ns = htons(len); + memcpy(out, &ns, 2); /* add 2 byte len (network order) */ + memcpy(out+2, str, len); /* add string */ + out += len + 2; + break; + + case 'u': + /* unsigned int */ + u = va_arg(ap, uint32); + u = htonl(u); + memcpy(out, &u, sizeof(uint32)); + out += sizeof(uint32); + break; + + case 'c': + /* char */ + c = va_arg(ap, int) & 0xFF; + *out = c; + out++; + break; + + default: + *out = *p; + out++; + break; + } + } + done: + va_end(ap); + + *outlen = out - *buf; + + /* add 4 byte len (network order) */ + totlen = htonl(*outlen - 4); + memcpy(*buf, &totlen, 4); + + return r; +} + +/* + * Extract an SRP buffer into the data specified by the fmt string. + * + * A '-' flag means don't allocate memory for the data ('o' only). + */ +static int UnBuffer(const sasl_utils_t *utils, const char *buf, + unsigned buflen, const char *fmt, ...) +{ + va_list ap; + char *p; + int r = SASL_OK, noalloc; + BIGNUM *mpi; + char **os, **str; + uint32 *u; + unsigned short ns; + unsigned len; + + if (!buf || buflen < 4) { + utils->seterror(utils->conn, 0, + "Buffer is not big enough to be SRP buffer: %d\n", + buflen); + return SASL_BADPROT; + } + + /* get the length */ + memcpy(&len, buf, 4); + len = ntohl(len); + buf += 4; + buflen -= 4; + + /* make sure it's right */ + if (len != buflen) { + SETERROR(utils, "SRP Buffer isn't of the right length\n"); + return SASL_BADPROT; + } + + va_start(ap, fmt); + for (p = (char *) fmt; *p; p++) { + if (*p != '%') { + if (*buf != *p) { + r = SASL_BADPROT; + goto done; + } + buf++; + buflen--; + continue; + } + + /* check for noalloc flag */ + if ((noalloc = (*++p == '-'))) ++p; + + switch (*p) { + case 'm': + /* MPI */ + if (buflen < 2) { + SETERROR(utils, "Buffer is not big enough to be SRP MPI\n"); + r = SASL_BADPROT; + goto done; + } + + /* get the length */ + memcpy(&ns, buf, 2); + len = ntohs(ns); + buf += 2; + buflen -= 2; + + /* make sure it's right */ + if (len > buflen) { + SETERROR(utils, "Not enough data for this SRP MPI\n"); + r = SASL_BADPROT; + goto done; + } + + mpi = va_arg(ap, BIGNUM *); + BN_init(mpi); + BN_bin2bn(buf, len, mpi); + break; + + case 'o': + /* octet sequence (len followed by data) */ + if (buflen < 1) { + SETERROR(utils, "Buffer is not big enough to be SRP os\n"); + r = SASL_BADPROT; + goto done; + } + + /* get the length */ + len = (unsigned char) *buf; + buf++; + buflen--; + + /* make sure it's right */ + if (len > buflen) { + SETERROR(utils, "Not enough data for this SRP os\n"); + r = SASL_BADPROT; + goto done; + } + + *(va_arg(ap, int *)) = len; + os = va_arg(ap, char **); + + if (noalloc) + *os = (char *) buf; + else { + *os = (char *) utils->malloc(len); + if (!*os) { + r = SASL_NOMEM; + goto done; + } + + memcpy(*os, buf, len); + } + break; + + case 's': + /* string */ + if (buflen < 2) { + SETERROR(utils, "Buffer is not big enough to be SRP UTF8\n"); + r = SASL_BADPROT; + goto done; + } + + /* get the length */ + memcpy(&ns, buf, 2); + len = ntohs(ns); + buf += 2; + buflen -= 2; + + /* make sure it's right */ + if (len > buflen) { + SETERROR(utils, "Not enough data for this SRP UTF8\n"); + r = SASL_BADPROT; + goto done; + } + + str = va_arg(ap, char **); + *str = (char *) utils->malloc(len+1); /* +1 for NUL */ + if (!*str) { + r = SASL_NOMEM; + goto done; + } + + memcpy(*str, buf, len); + (*str)[len] = '\0'; + break; + + case 'u': + /* unsigned int */ + if (buflen < sizeof(uint32)) { + SETERROR(utils, "Buffer is not big enough to be SRP uint\n"); + r = SASL_BADPROT; + goto done; + } + + len = sizeof(uint32); + u = va_arg(ap, uint32*); + memcpy(u, buf, len); + *u = ntohs(*u); + break; + + case 'c': + /* char */ + if (buflen < 1) { + SETERROR(utils, "Buffer is not big enough to be SRP char\n"); + r = SASL_BADPROT; + goto done; + } + + len = 1; + *(va_arg(ap, char *)) = *buf; + break; + + default: + len = 1; + if (*buf != *p) { + r = SASL_BADPROT; + goto done; + } + break; + } + + buf += len; + buflen -= len; + } + + done: + va_end(ap); + + if (buflen != 0) { + SETERROR(utils, "Extra data in SRP buffer\n"); + r = SASL_BADPROT; + } + + return r; +} + +/* + * Apply the hash function to the data specifed by the fmt string. + */ +static int MakeHash(const EVP_MD *md, unsigned char hash[], int *hashlen, + const char *fmt, ...) +{ + va_list ap; + char *p, buf[4096], *in; + int inlen; + EVP_MD_CTX mdctx; + int r = 0, hflag; + + EVP_DigestInit(&mdctx, md); + + va_start(ap, fmt); + for (p = (char *) fmt; *p; p++) { + if (*p != '%') { + in = p; + inlen = 1; + hflag = 0; + } + else { + if ((hflag = (*++p == 'h'))) ++p; + + switch (*p) { + case 'm': { + /* MPI */ + BIGNUM *mval = va_arg(ap, BIGNUM *); + + in = buf; + r = BigIntToBytes(mval, buf, sizeof(buf)-1, &inlen); + if (r) goto done; + break; + } + + case 'o': { + /* octet sequence (len followed by data) */ + inlen = va_arg(ap, int); + in = va_arg(ap, char *); + break; + } + + case 's': + /* string */ + in = va_arg(ap, char *); + inlen = strlen(in); + break; + + case 'u': { + /* unsigned int */ + uint32 uval = va_arg(ap, uint32); + + in = buf; + inlen = sizeof(uint32); + *((uint32 *) buf) = htonl(uval); + break; + } + + default: + in = p; + inlen = 1; + break; + } + } + + if (hflag) { + /* hash data separately before adding to current hash */ + EVP_MD_CTX tmpctx; + + EVP_DigestInit(&tmpctx, md); + EVP_DigestUpdate(&tmpctx, in, inlen); + EVP_DigestFinal(&tmpctx, buf, &inlen); + in = buf; + } + + EVP_DigestUpdate(&mdctx, in, inlen); + } + done: + va_end(ap); + + EVP_DigestFinal(&mdctx, hash, hashlen); + + return r; +} + +static int CalculateX(context_t *text, const char *salt, int saltlen, + const char *user, const char *pass, int passlen, + BIGNUM *x) +{ + char hash[EVP_MAX_MD_SIZE]; + int hashlen; + + /* x = H(salt | H(user | ':' | pass)) */ + MakeHash(text->md, hash, &hashlen, "%s:%o", user, passlen, pass); + MakeHash(text->md, hash, &hashlen, "%o%o", saltlen, salt, hashlen, hash); + + BN_init(x); + BN_bin2bn(hash, hashlen, x); + + return SASL_OK; +} + +static int CalculateM1(context_t *text, BIGNUM *N, BIGNUM *g, + char *U, char *salt, int saltlen, + BIGNUM *A, BIGNUM *B, char *K, int Klen, + char *I, char *L, char *M1, int *M1len) +{ + int r, i, len; + unsigned char Nhash[EVP_MAX_MD_SIZE]; + unsigned char ghash[EVP_MAX_MD_SIZE]; + unsigned char Ng[EVP_MAX_MD_SIZE]; + + /* bytes(H( bytes(N) )) ^ bytes( H( bytes(g) )) + ^ is the bitwise XOR operator. */ + r = MakeHash(text->md, Nhash, &len, "%m", N); + if (r) return r; + r = MakeHash(text->md, ghash, &len, "%m", g); + if (r) return r; + + for (i = 0; i < len; i++) { + Ng[i] = (Nhash[i] ^ ghash[i]); + } + + r = MakeHash(text->md, M1, M1len, "%o%hs%o%m%m%o%hs%hs", + len, Ng, U, saltlen, salt, A, B, Klen, K, I, L); + + return r; +} + +static int CalculateM2(context_t *text, BIGNUM *A, + char *M1, int M1len, char *K, int Klen, + char *I, char *o, char *sid, uint32 ttl, + char *M2, int *M2len) +{ + int r; + + r = MakeHash(text->md, M2, M2len, "%m%o%o%hs%hs%s%u", + A, M1len, M1, Klen, K, I, o, sid, ttl); + + return r; +} + +/* Parse an option out of an option string + * Place found option in 'option' + * 'nextptr' points to rest of string or NULL if at end + */ +static int ParseOption(const sasl_utils_t *utils, + char *in, char **option, char **nextptr) +{ + char *comma; + int len; + int i; + + if (strlen(in) == 0) { + *option = NULL; + return SASL_OK; + } + + comma = strchr(in,','); + if (comma == NULL) comma = in + strlen(in); + + len = comma - in; + + *option = utils->malloc(len + 1); + if (!*option) return SASL_NOMEM; + + /* lowercase string */ + for (i = 0; i < len; i++) { + (*option)[i] = tolower((int)in[i]); + } + (*option)[len] = '\0'; + + if (*comma) { + *nextptr = comma+1; + } else { + *nextptr = NULL; + } + + return SASL_OK; +} + +static int FindBit(char *name, layer_option_t *opts) +{ + while (opts->name) { + if (!strcasecmp(name, opts->name)) { + return opts->bit; + } + + opts++; + } + + return 0; +} + +static layer_option_t *FindOptionFromBit(unsigned bit, layer_option_t *opts) +{ + while (opts->name) { + if (opts->bit == bit) { + return opts; + } + + opts++; + } + + return NULL; +} + +static int ParseOptionString(const sasl_utils_t *utils, + char *str, srp_options_t *opts, int isserver) +{ + if (!strncasecmp(str, OPTION_MDA, strlen(OPTION_MDA))) { + + int bit = FindBit(str+strlen(OPTION_MDA), digest_options); + + if (isserver && (!bit || opts->mda)) { + opts->mda = -1; + if (!bit) + utils->seterror(utils->conn, 0, + "SRP MDA %s not supported\n", + str+strlen(OPTION_MDA)); + else + SETERROR(utils, "Multiple SRP MDAs given\n"); + return SASL_BADPROT; + } + + opts->mda |= bit; + + } else if (!strcasecmp(str, OPTION_REPLAY_DETECTION)) { + if (opts->replay_detection) { + SETERROR(utils, "SRP Replay Detection option appears twice\n"); + return SASL_BADPROT; + } + opts->replay_detection = 1; + + } else if (!strncasecmp(str, OPTION_INTEGRITY, strlen(OPTION_INTEGRITY)) && + !strncasecmp(str+strlen(OPTION_INTEGRITY), "HMAC-", 5)) { + + int bit = FindBit(str+strlen(OPTION_INTEGRITY)+5, digest_options); + + if (isserver && (!bit || opts->integrity)) { + opts->integrity = -1; + if (!bit) + utils->seterror(utils->conn, 0, + "SRP Integrity option %s not supported\n", + str+strlen(OPTION_INTEGRITY)); + else + SETERROR(utils, "Multiple SRP Integrity options given\n"); + return SASL_BADPROT; + } + + opts->integrity |= bit; + + } else if (!strncasecmp(str, OPTION_CONFIDENTIALITY, + strlen(OPTION_CONFIDENTIALITY))) { + + int bit = FindBit(str+strlen(OPTION_CONFIDENTIALITY), + cipher_options); + + if (isserver && (!bit || opts->confidentiality)) { + opts->confidentiality = -1; + if (!bit) + utils->seterror(utils->conn, 0, + "SRP Confidentiality option %s not supported\n", + str+strlen(OPTION_CONFIDENTIALITY)); + else + SETERROR(utils, + "Multiple SRP Confidentiality options given\n"); + return SASL_FAIL; + } + + opts->confidentiality |= bit; + + } else if (!isserver && !strncasecmp(str, OPTION_MANDATORY, + strlen(OPTION_MANDATORY))) { + + char *layer = str+strlen(OPTION_MANDATORY); + + if (!strcasecmp(layer, OPTION_REPLAY_DETECTION)) + opts->mandatory |= BIT_REPLAY_DETECTION; + else if (!strncasecmp(layer, OPTION_INTEGRITY, + strlen(OPTION_INTEGRITY)-1)) + opts->mandatory |= BIT_INTEGRITY; + else if (!strncasecmp(layer, OPTION_CONFIDENTIALITY, + strlen(OPTION_CONFIDENTIALITY)-1)) + opts->mandatory |= BIT_CONFIDENTIALITY; + else { + utils->seterror(utils->conn, 0, + "Mandatory SRP option %s not supported\n", layer); + return SASL_BADPROT; + } + + } else if (!strncasecmp(str, OPTION_MAXBUFFERSIZE, + strlen(OPTION_MAXBUFFERSIZE))) { + + opts->maxbufsize = strtoul(str+strlen(OPTION_MAXBUFFERSIZE), NULL, 10); + + if (opts->maxbufsize > SRP_MAXBUFFERSIZE) { + utils->seterror(utils->conn, 0, + "SRP Maxbuffersize %lu too big (> %lu)\n", + opts->maxbufsize, SRP_MAXBUFFERSIZE); + return SASL_BADPROT; + } + + } else { + /* Ignore unknown options */ + } + + return SASL_OK; +} + +static int ParseOptions(const sasl_utils_t *utils, + char *in, srp_options_t *out, int isserver) +{ + int r; + + memset(out, 0, sizeof(srp_options_t)); + out->maxbufsize = SRP_MAXBUFFERSIZE; + + while (in) { + char *opt; + + r = ParseOption(utils, in, &opt, &in); + if (r) return r; + + if (opt == NULL) return SASL_OK; + + utils->log(NULL, SASL_LOG_DEBUG, "Got option: [%s]\n",opt); + + r = ParseOptionString(utils, opt, out, isserver); + utils->free(opt); + + if (r) return r; + } + + return SASL_OK; +} + +static layer_option_t *FindBest(int available, sasl_ssf_t min_ssf, + sasl_ssf_t max_ssf, layer_option_t *opts) +{ + layer_option_t *best = NULL; + + if (!available) return NULL; + + while (opts->name) { + if (opts->enabled && (available & opts->bit) && + (opts->ssf >= min_ssf) && (opts->ssf <= max_ssf) && + (!best || (opts->ssf > best->ssf))) { + best = opts; + } + + opts++; + } + + return best; +} + +static int OptionsToString(const sasl_utils_t *utils, + srp_options_t *opts, char **out) +{ + char *ret = NULL; + int alloced = 0; + int first = 1; + layer_option_t *optlist; + + ret = utils->malloc(1); + if (!ret) return SASL_NOMEM; + alloced = 1; + ret[0] = '\0'; + + optlist = digest_options; + while(optlist->name) { + if (opts->mda & optlist->bit) { + alloced += strlen(OPTION_MDA)+strlen(optlist->name)+1; + ret = utils->realloc(ret, alloced); + if (!ret) return SASL_NOMEM; + + if (!first) strcat(ret, ","); + strcat(ret, OPTION_MDA); + strcat(ret, optlist->name); + first = 0; + } + + optlist++; + } + + if (opts->replay_detection) { + alloced += strlen(OPTION_REPLAY_DETECTION)+1; + ret = utils->realloc(ret, alloced); + if (!ret) return SASL_NOMEM; + + if (!first) strcat(ret, ","); + strcat(ret, OPTION_REPLAY_DETECTION); + first = 0; + } + + optlist = digest_options; + while(optlist->name) { + if (opts->integrity & optlist->bit) { + alloced += strlen(OPTION_INTEGRITY)+5+strlen(optlist->name)+1; + ret = utils->realloc(ret, alloced); + if (!ret) return SASL_NOMEM; + + if (!first) strcat(ret, ","); + strcat(ret, OPTION_INTEGRITY); + strcat(ret, "HMAC-"); + strcat(ret, optlist->name); + first = 0; + } + + optlist++; + } + + optlist = cipher_options; + while(optlist->name) { + if (opts->confidentiality & optlist->bit) { + alloced += strlen(OPTION_CONFIDENTIALITY)+strlen(optlist->name)+1; + ret = utils->realloc(ret, alloced); + if (!ret) return SASL_NOMEM; + + if (!first) strcat(ret, ","); + strcat(ret, OPTION_CONFIDENTIALITY); + strcat(ret, optlist->name); + first = 0; + } + + optlist++; + } + + if ((opts->integrity || opts->confidentiality) && + opts->maxbufsize < SRP_MAXBUFFERSIZE) { + alloced += strlen(OPTION_MAXBUFFERSIZE)+10+1; + ret = utils->realloc(ret, alloced); + if (!ret) return SASL_NOMEM; + + if (!first) strcat(ret, ","); + strcat(ret, OPTION_MAXBUFFERSIZE); + sprintf(ret+strlen(ret), "%lu", opts->maxbufsize); + first = 0; + } + + if (opts->mandatory & BIT_REPLAY_DETECTION) { + alloced += strlen(OPTION_MANDATORY)+strlen(OPTION_REPLAY_DETECTION)+1; + ret = utils->realloc(ret, alloced); + if (!ret) return SASL_NOMEM; + + if (!first) strcat(ret, ","); + strcat(ret, OPTION_MANDATORY); + strcat(ret, OPTION_REPLAY_DETECTION); + first = 0; + } + + if (opts->mandatory & BIT_INTEGRITY) { + alloced += strlen(OPTION_MANDATORY)+strlen(OPTION_INTEGRITY)-1+1; + ret = utils->realloc(ret, alloced); + if (!ret) return SASL_NOMEM; + + if (!first) strcat(ret, ","); + strcat(ret, OPTION_MANDATORY); + strncat(ret, OPTION_INTEGRITY, strlen(OPTION_INTEGRITY)-1); + /* terminate string */ + ret[alloced-1] = '\0'; + first = 0; + } + + if (opts->mandatory & BIT_CONFIDENTIALITY) { + alloced += strlen(OPTION_MANDATORY)+strlen(OPTION_CONFIDENTIALITY)-1+1; + ret = utils->realloc(ret, alloced); + if (!ret) return SASL_NOMEM; + + if (!first) strcat(ret, ","); + strcat(ret, OPTION_MANDATORY); + strncat(ret, OPTION_CONFIDENTIALITY, strlen(OPTION_CONFIDENTIALITY)-1); + /* terminate string */ + ret[alloced-1] = '\0'; + first = 0; + } + + *out = ret; + return SASL_OK; +} + + +/* + * Set the selected MDA. + */ +static int SetMDA(srp_options_t *opts, context_t *text) +{ + layer_option_t *opt; + + opt = FindOptionFromBit(opts->mda, digest_options); + if (!opt) { + text->utils->log(NULL, SASL_LOG_ERR, + "Unable to find SRP MDA option now\n"); + return SASL_FAIL; + } + + text->md = EVP_get_digestbyname(opt->evp_name); + + return SASL_OK; +} + +/* + * Setup the selected security layer. + */ +static int LayerInit(srp_options_t *opts, context_t *text, + sasl_out_params_t *oparams, char *enc_IV, char *dec_IV, + unsigned maxbufsize) +{ + layer_option_t *opt; + + if ((opts->integrity == 0) && (opts->confidentiality == 0)) { + oparams->encode = NULL; + oparams->decode = NULL; + oparams->mech_ssf = 0; + text->utils->log(NULL, SASL_LOG_DEBUG, "Using no protection\n"); + return SASL_OK; + } + + oparams->encode = &srp_encode; + oparams->decode = &srp_decode; + oparams->maxoutbuf = opts->maxbufsize - 4; /* account for 4-byte length */ + + _plug_decode_init(&text->decode_context, text->utils, maxbufsize); + + if (opts->replay_detection) { + text->utils->log(NULL, SASL_LOG_DEBUG, "Using replay detection\n"); + + text->layer |= BIT_REPLAY_DETECTION; + + /* If no integrity layer specified, use default */ + if (!opts->integrity) + opts->integrity = default_digest->bit; + } + + if (opts->integrity) { + text->utils->log(NULL, SASL_LOG_DEBUG, "Using integrity protection\n"); + + text->layer |= BIT_INTEGRITY; + + opt = FindOptionFromBit(opts->integrity, digest_options); + if (!opt) { + text->utils->log(NULL, SASL_LOG_ERR, + "Unable to find SRP integrity layer option\n"); + return SASL_FAIL; + } + + oparams->mech_ssf = opt->ssf; + + /* Initialize the HMACs */ + text->hmac_md = EVP_get_digestbyname(opt->evp_name); + HMAC_Init(&text->hmac_send_ctx, text->K, text->Klen, text->hmac_md); + HMAC_Init(&text->hmac_recv_ctx, text->K, text->Klen, text->hmac_md); + + /* account for HMAC */ + oparams->maxoutbuf -= EVP_MD_size(text->hmac_md); + } + + if (opts->confidentiality) { + text->utils->log(NULL, SASL_LOG_DEBUG, + "Using confidentiality protection\n"); + + text->layer |= BIT_CONFIDENTIALITY; + + opt = FindOptionFromBit(opts->confidentiality, cipher_options); + if (!opt) { + text->utils->log(NULL, SASL_LOG_ERR, + "Unable to find SRP confidentiality layer option\n"); + return SASL_FAIL; + } + + oparams->mech_ssf = opt->ssf; + + /* Initialize the ciphers */ + text->cipher = EVP_get_cipherbyname(opt->evp_name); + + EVP_CIPHER_CTX_init(&text->cipher_enc_ctx); + EVP_EncryptInit(&text->cipher_enc_ctx, text->cipher, text->K, enc_IV); + + EVP_CIPHER_CTX_init(&text->cipher_dec_ctx); + EVP_DecryptInit(&text->cipher_dec_ctx, text->cipher, text->K, dec_IV); + } + + return SASL_OK; +} + +static void LayerCleanup(context_t *text) +{ + if (text->layer & BIT_INTEGRITY) { + HMAC_cleanup(&text->hmac_send_ctx); + HMAC_cleanup(&text->hmac_recv_ctx); + } + + if (text->layer & BIT_CONFIDENTIALITY) { + EVP_CIPHER_CTX_cleanup(&text->cipher_enc_ctx); + EVP_CIPHER_CTX_cleanup(&text->cipher_dec_ctx); + } +} + + +/* + * Dispose of a SRP context (could be server or client) + */ +static void srp_common_mech_dispose(void *conn_context, + const sasl_utils_t *utils) +{ + context_t *text = (context_t *) conn_context; + + if (!text) return; + + BN_clear_free(&text->N); + BN_clear_free(&text->g); + BN_clear_free(&text->v); + BN_clear_free(&text->b); + BN_clear_free(&text->B); + BN_clear_free(&text->a); + BN_clear_free(&text->A); + + if (text->authid) utils->free(text->authid); + if (text->userid) utils->free(text->userid); + if (text->free_password) _plug_free_secret(utils, &(text->password)); + if (text->salt) utils->free(text->salt); + + if (text->client_options) utils->free(text->client_options); + if (text->server_options) utils->free(text->server_options); + + LayerCleanup(text); + _plug_decode_free(&text->decode_context); + + if (text->encode_buf) utils->free(text->encode_buf); + if (text->decode_buf) utils->free(text->decode_buf); + if (text->decode_pkt_buf) utils->free(text->decode_pkt_buf); + if (text->out_buf) utils->free(text->out_buf); + + utils->free(text); +} + +static void +srp_common_mech_free(void *global_context __attribute__((unused)), + const sasl_utils_t *utils __attribute__((unused))) +{ + /* Don't call EVP_cleanup(); here, as this might confuse the calling + application if it also uses OpenSSL */ +} + + +/***************************** Server Section *****************************/ + +/* A large safe prime (N = 2q+1, where q is prime) + * + * Use N with the most bits from our table. + * + * All arithmetic is done modulo N + */ +static int generate_N_and_g(BIGNUM *N, BIGNUM *g) +{ + int result; + + BN_init(N); + result = BN_hex2bn(&N, Ng_tab[NUM_Ng-1].N); + if (!result) return SASL_FAIL; + + BN_init(g); + BN_set_word(g, Ng_tab[NUM_Ng-1].g); + + return SASL_OK; +} + +static int CalculateV(context_t *text, + BIGNUM *N, BIGNUM *g, + const char *user, + const char *pass, unsigned passlen, + BIGNUM *v, char **salt, int *saltlen) +{ + BIGNUM x; + BN_CTX *ctx = BN_CTX_new(); + int r; + + /* generate */ + *saltlen = SRP_MAXBLOCKSIZE; + *salt = (char *)text->utils->malloc(*saltlen); + if (!*salt) return SASL_NOMEM; + text->utils->rand(text->utils->rpool, *salt, *saltlen); + + r = CalculateX(text, *salt, *saltlen, user, pass, passlen, &x); + if (r) { + text->utils->seterror(text->utils->conn, 0, + "Error calculating 'x'"); + return r; + } + + /* v = g^x % N */ + BN_init(v); + BN_mod_exp(v, g, &x, N, ctx); + + BN_CTX_free(ctx); + BN_clear_free(&x); + + return r; +} + +static int CalculateB(context_t *text __attribute__((unused)), + BIGNUM *v, BIGNUM *N, BIGNUM *g, BIGNUM *b, BIGNUM *B) +{ + BIGNUM v3; + BN_CTX *ctx = BN_CTX_new(); + + /* Generate b */ + GetRandBigInt(b); + + /* Per [SRP]: make sure b > log[g](N) -- g is always 2 */ + BN_add_word(b, BN_num_bits(N)); + + /* B = (3v + g^b) % N */ + BN_init(&v3); + BN_set_word(&v3, 3); + BN_mod_mul(&v3, &v3, v, N, ctx); + BN_init(B); + BN_mod_exp(B, g, b, N, ctx); +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + BN_mod_add(B, B, &v3, N, ctx); +#else + BN_add(B, B, &v3); + BN_mod(B, B, N, ctx); +#endif + + BN_CTX_free(ctx); + + return SASL_OK; +} + +static int ServerCalculateK(context_t *text, BIGNUM *v, + BIGNUM *N, BIGNUM *A, BIGNUM *b, BIGNUM *B, + char *K, int *Klen) +{ + unsigned char hash[EVP_MAX_MD_SIZE]; + int hashlen; + BIGNUM u; + BIGNUM base; + BIGNUM S; + BN_CTX *ctx = BN_CTX_new(); + int r; + + /* u = H(A | B) */ + r = MakeHash(text->md, hash, &hashlen, "%m%m", A, B); + if (r) return r; + + BN_init(&u); + BN_bin2bn(hash, hashlen, &u); + + /* S = (Av^u) ^ b % N */ + BN_init(&base); + BN_mod_exp(&base, v, &u, N, ctx); + BN_mod_mul(&base, &base, A, N, ctx); + + BN_init(&S); + BN_mod_exp(&S, &base, b, N, ctx); + + /* per Tom Wu: make sure Av^u != 1 (mod N) */ + if (BN_is_one(&base)) { + SETERROR(text->utils, "Unsafe SRP value for 'Av^u'\n"); + r = SASL_BADPROT; + goto err; + } + + /* per Tom Wu: make sure Av^u != -1 (mod N) */ + BN_add_word(&base, 1); + if (BN_cmp(&S, N) == 0) { + SETERROR(text->utils, "Unsafe SRP value for 'Av^u'\n"); + r = SASL_BADPROT; + goto err; + } + + /* K = H(S) */ + r = MakeHash(text->md, K, Klen, "%m", &S); + if (r) goto err; + + r = SASL_OK; + + err: + BN_CTX_free(ctx); + BN_clear_free(&u); + BN_clear_free(&base); + BN_clear_free(&S); + + return r; +} + +static int ParseUserSecret(const sasl_utils_t *utils, + char *secret, size_t seclen, + char **mda, BIGNUM *v, char **salt, int *saltlen) +{ + int r; + + /* The secret data is stored as suggested in RFC 2945: + * + * { utf8(mda) mpi(v) os(salt) } (base64 encoded) + */ + r = utils->decode64(secret, seclen, secret, seclen, &seclen); + + if (!r) + r = UnBuffer(utils, secret, seclen, "%s%m%o", mda, v, saltlen, salt); + if (r) { + utils->seterror(utils->conn, 0, + "Error UnBuffering user secret"); + } + + return r; +} + +static int CreateServerOptions(sasl_server_params_t *sparams, char **out) +{ + srp_options_t opts; + sasl_ssf_t limitssf, requiressf; + layer_option_t *optlist; + + /* zero out options */ + memset(&opts,0,sizeof(srp_options_t)); + + /* Add mda */ + opts.mda = server_mda->bit; + + if(sparams->props.maxbufsize == 0) { + limitssf = 0; + requiressf = 0; + } else { + if (sparams->props.max_ssf < sparams->external_ssf) { + limitssf = 0; + } else { + limitssf = sparams->props.max_ssf - sparams->external_ssf; + } + if (sparams->props.min_ssf < sparams->external_ssf) { + requiressf = 0; + } else { + requiressf = sparams->props.min_ssf - sparams->external_ssf; + } + } + + /* + * Add integrity options + * Can't advertise integrity w/o support for default HMAC + */ + if (default_digest->enabled) { + optlist = digest_options; + while(optlist->name) { + if (optlist->enabled && + /*(requiressf <= 1) &&*/ (limitssf >= 1)) { + opts.integrity |= optlist->bit; + } + optlist++; + } + } + + /* if we set any integrity options we can advertise replay detection */ + if (opts.integrity) { + opts.replay_detection = 1; + } + + /* + * Add confidentiality options + * Can't advertise confidentiality w/o support for default cipher + */ + if (default_cipher->enabled) { + optlist = cipher_options; + while(optlist->name) { + if (optlist->enabled && + (requiressf <= optlist->ssf) && + (limitssf >= optlist->ssf)) { + opts.confidentiality |= optlist->bit; + } + optlist++; + } + } + + /* Add mandatory options */ + if (requiressf >= 1) + opts.mandatory = BIT_REPLAY_DETECTION | BIT_INTEGRITY; + if (requiressf > 1) + opts.mandatory |= BIT_CONFIDENTIALITY; + + /* Add maxbuffersize */ + opts.maxbufsize = SRP_MAXBUFFERSIZE; + if (sparams->props.maxbufsize && + sparams->props.maxbufsize < opts.maxbufsize) + opts.maxbufsize = sparams->props.maxbufsize; + + return OptionsToString(sparams->utils, &opts, out); +} + +static int +srp_server_mech_new(void *glob_context __attribute__((unused)), + sasl_server_params_t *params, + const char *challenge __attribute__((unused)), + unsigned challen __attribute__((unused)), + void **conn_context) +{ + context_t *text; + + /* holds state are in */ + text = params->utils->malloc(sizeof(context_t)); + if (text == NULL) { + MEMERROR(params->utils); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(context_t)); + + text->state = 1; + text->utils = params->utils; + text->md = EVP_get_digestbyname(server_mda->evp_name); + + *conn_context = text; + + return SASL_OK; +} + +static int srp_server_mech_step1(context_t *text, + sasl_server_params_t *params, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + int result; + char *sid = NULL; + char *cn = NULL; + int cnlen; + char *realm = NULL; + char *user = NULL; + const char *password_request[] = { "*cmusaslsecretSRP", + SASL_AUX_PASSWORD, + NULL }; + struct propval auxprop_values[3]; + + /* Expect: + * + * U - authentication identity + * I - authorization identity + * sid - session id + * cn - client nonce + * + * { utf8(U) utf8(I) utf8(sid) os(cn) } + * + */ + result = UnBuffer(params->utils, clientin, clientinlen, + "%s%s%s%o", &text->authid, &text->userid, &sid, + &cnlen, &cn); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error UnBuffering input in step 1"); + return result; + } + /* Get the realm */ + result = _plug_parseuser(params->utils, &user, &realm, params->user_realm, + params->serverFQDN, text->authid); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error getting realm"); + goto cleanup; + } + + /* Generate N and g */ + result = generate_N_and_g(&text->N, &text->g); + if (result) { + params->utils->seterror(text->utils->conn, 0, + "Error calculating N and g"); + return result; + } + + /* Get user secret */ + result = params->utils->prop_request(params->propctx, password_request); + if (result != SASL_OK) goto cleanup; + + /* this will trigger the getting of the aux properties */ + result = params->canon_user(params->utils->conn, + text->authid, 0, SASL_CU_AUTHID, oparams); + if (result != SASL_OK) goto cleanup; + + result = params->canon_user(params->utils->conn, + text->userid, 0, SASL_CU_AUTHZID, oparams); + if (result != SASL_OK) goto cleanup; + + result = params->utils->prop_getnames(params->propctx, password_request, + auxprop_values); + if (result < 0 || + ((!auxprop_values[0].name || !auxprop_values[0].values) && + (!auxprop_values[1].name || !auxprop_values[1].values))) { + /* We didn't find this username */ + params->utils->seterror(params->utils->conn,0, + "no secret in database"); + result = params->transition ? SASL_TRANS : SASL_NOUSER; + goto cleanup; + } + + if (auxprop_values[0].name && auxprop_values[0].values) { + char *mda = NULL; + + /* We have a precomputed verifier */ + result = ParseUserSecret(params->utils, + (char*) auxprop_values[0].values[0], + auxprop_values[0].valsize, + &mda, &text->v, &text->salt, &text->saltlen); + + if (result) { + /* ParseUserSecret sets error, if any */ + if (mda) params->utils->free(mda); + goto cleanup; + } + + /* find mda */ + server_mda = digest_options; + while (server_mda->name) { + if (!strcasecmp(server_mda->name, mda)) + break; + + server_mda++; + } + + if (!server_mda->name) { + params->utils->seterror(params->utils->conn, 0, + "unknown SRP mda '%s'", mda); + params->utils->free(mda); + result = SASL_FAIL; + goto cleanup; + } + params->utils->free(mda); + + } else if (auxprop_values[1].name && auxprop_values[1].values) { + /* We only have the password -- calculate the verifier */ + int len = strlen(auxprop_values[1].values[0]); + + if (len == 0) { + params->utils->seterror(params->utils->conn,0, + "empty secret"); + result = SASL_FAIL; + goto cleanup; + } + + result = CalculateV(text, &text->N, &text->g, text->authid, + auxprop_values[1].values[0], len, + &text->v, &text->salt, &text->saltlen); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error calculating v"); + goto cleanup; + } + } else { + params->utils->seterror(params->utils->conn, 0, + "Have neither type of secret"); + result = SASL_FAIL; + goto cleanup; + } + + /* erase the plaintext password */ + params->utils->prop_erase(params->propctx, password_request[1]); + + /* Calculate B */ + result = CalculateB(text, &text->v, &text->N, &text->g, + &text->b, &text->B); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error calculating B"); + return result; + } + + /* Create L */ + result = CreateServerOptions(params, &text->server_options); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error creating server options"); + goto cleanup; + } + + /* Send out: + * + * N - safe prime modulus + * g - generator + * s - salt + * B - server's public key + * L - server options (available layers etc) + * + * { 0x00 mpi(N) mpi(g) os(s) mpi(B) utf8(L) } + * + */ + result = MakeBuffer(text->utils, &text->out_buf, &text->out_buf_len, + serveroutlen, "%c%m%m%o%m%s", + 0x00, &text->N, &text->g, text->saltlen, text->salt, + &text->B, text->server_options); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error creating SRP buffer from data in step 1"); + goto cleanup; + } + *serverout = text->out_buf; + + text->state = 2; + result = SASL_CONTINUE; + + cleanup: + if (sid) params->utils->free(sid); + if (cn) params->utils->free(cn); + if (user) params->utils->free(user); + if (realm) params->utils->free(realm); + + return result; +} + +static int srp_server_mech_step2(context_t *text, + sasl_server_params_t *params, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + int result; + char *M1 = NULL, *cIV = NULL; /* don't free */ + int M1len, cIVlen; + srp_options_t client_opts; + char myM1[EVP_MAX_MD_SIZE]; + int myM1len; + int i; + char M2[EVP_MAX_MD_SIZE]; + int M2len; + char sIV[SRP_MAXBLOCKSIZE]; + + /* Expect: + * + * A - client's public key + * M1 - client evidence + * o - client option list + * cIV - client's initial vector + * + * { mpi(A) os(M1) utf8(o) os(cIV) } + * + */ + result = UnBuffer(params->utils, clientin, clientinlen, + "%m%-o%s%-o", &text->A, &M1len, &M1, + &text->client_options, &cIVlen, &cIV); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error UnBuffering input in step 2"); + goto cleanup; + } + + /* Per [SRP]: reject A <= 0 */ + if (BigIntCmpWord(&text->A, 0) <= 0) { + SETERROR(params->utils, "Illegal value for 'A'\n"); + result = SASL_BADPROT; + goto cleanup; + } + + /* parse client options */ + result = ParseOptions(params->utils, text->client_options, &client_opts, 1); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error parsing user's options"); + + if (client_opts.confidentiality) { + /* Mark that we attempted confidentiality layer negotiation */ + oparams->mech_ssf = 2; + } + else if (client_opts.integrity || client_opts.replay_detection) { + /* Mark that we attempted integrity layer negotiation */ + oparams->mech_ssf = 1; + } + return result; + } + + result = SetMDA(&client_opts, text); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error setting options"); + return result; + } + + /* Calculate K */ + result = ServerCalculateK(text, &text->v, &text->N, &text->A, + &text->b, &text->B, text->K, &text->Klen); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error calculating K"); + return result; + } + + /* See if M1 is correct */ + result = CalculateM1(text, &text->N, &text->g, text->authid, + text->salt, text->saltlen, &text->A, &text->B, + text->K, text->Klen, text->userid, + text->server_options, myM1, &myM1len); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error calculating M1"); + goto cleanup; + } + + if (myM1len != M1len) { + params->utils->seterror(params->utils->conn, 0, + "SRP M1 lengths do not match"); + result = SASL_BADAUTH; + goto cleanup; + } + + for (i = 0; i < myM1len; i++) { + if (myM1[i] != M1[i]) { + params->utils->seterror(params->utils->conn, 0, + "client evidence does not match what we " + "calculated. Probably a password error"); + result = SASL_BADAUTH; + goto cleanup; + } + } + + /* calculate M2 to send */ + result = CalculateM2(text, &text->A, M1, M1len, text->K, text->Klen, + text->userid, text->client_options, "", 0, + M2, &M2len); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error calculating M2 (server evidence)"); + goto cleanup; + } + + /* Create sIV (server initial vector) */ + text->utils->rand(text->utils->rpool, sIV, sizeof(sIV)); + + /* + * Send out: + * M2 - server evidence + * sIV - server's initial vector + * sid - session id + * ttl - time to live + * + * { os(M2) os(sIV) utf8(sid) uint(ttl) } + */ + result = MakeBuffer(text->utils, &text->out_buf, &text->out_buf_len, + serveroutlen, "%o%o%s%u", M2len, M2, + sizeof(sIV), sIV, "", 0); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error making output buffer in SRP step 3"); + goto cleanup; + } + *serverout = text->out_buf; + + /* configure security layer */ + result = LayerInit(&client_opts, text, oparams, cIV, sIV, + params->props.maxbufsize); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error initializing security layer"); + return result; + } + + /* set oparams */ + oparams->doneflag = 1; + oparams->param_version = 0; + + result = SASL_OK; + + cleanup: + + return result; +} + +static int srp_server_mech_step(void *conn_context, + sasl_server_params_t *sparams, + const char *clientin, + unsigned clientinlen, + const char **serverout, + unsigned *serveroutlen, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *) conn_context; + + if (!sparams + || !serverout + || !serveroutlen + || !oparams) + return SASL_BADPARAM; + + *serverout = NULL; + *serveroutlen = 0; + + if (text == NULL) { + return SASL_BADPROT; + } + + sparams->utils->log(NULL, SASL_LOG_DEBUG, + "SRP server step %d\n", text->state); + + switch (text->state) { + + case 1: + return srp_server_mech_step1(text, sparams, clientin, clientinlen, + serverout, serveroutlen, oparams); + + case 2: + return srp_server_mech_step2(text, sparams, clientin, clientinlen, + serverout, serveroutlen, oparams); + + default: + sparams->utils->seterror(sparams->utils->conn, 0, + "Invalid SRP server step %d", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + +#ifdef DO_SRP_SETPASS +static int srp_setpass(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + const char *userstr, + const char *pass, + unsigned passlen __attribute__((unused)), + const char *oldpass __attribute__((unused)), + unsigned oldpasslen __attribute__((unused)), + unsigned flags) +{ + int r; + char *user = NULL; + char *user_only = NULL; + char *realm = NULL; + sasl_secret_t *sec = NULL; + struct propctx *propctx = NULL; + const char *store_request[] = { "cmusaslsecretSRP", + NULL }; + + /* Do we have a backend that can store properties? */ + if (!sparams->utils->auxprop_store || + sparams->utils->auxprop_store(NULL, NULL, NULL) != SASL_OK) { + SETERROR(sparams->utils, "SRP: auxprop backend can't store properties"); + return SASL_NOMECH; + } + + /* NB: Ideally we need to canonicalize userstr here */ + r = _plug_parseuser(sparams->utils, &user_only, &realm, sparams->user_realm, + sparams->serverFQDN, userstr); + + if (r) { + sparams->utils->seterror(sparams->utils->conn, 0, + "Error parsing user"); + return r; + } + + r = _plug_make_fulluser(sparams->utils, &user, user_only, realm); + + if (r) { + goto end; + } + + if ((flags & SASL_SET_DISABLE) || pass == NULL) { + sec = NULL; + } else { + context_t *text; + BIGNUM N; + BIGNUM g; + BIGNUM v; + char *salt; + int saltlen; + char *buffer = NULL; + int bufferlen, alloclen, encodelen; + + text = sparams->utils->malloc(sizeof(context_t)); + if (text == NULL) { + MEMERROR(sparams->utils); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(context_t)); + + text->utils = sparams->utils; + text->md = EVP_get_digestbyname(server_mda->evp_name); + + r = generate_N_and_g(&N, &g); + if (r) { + sparams->utils->seterror(sparams->utils->conn, 0, + "Error calculating N and g"); + goto end; + } + + /* user is a full username here */ + r = CalculateV(text, &N, &g, user, pass, passlen, &v, &salt, &saltlen); + if (r) { + sparams->utils->seterror(sparams->utils->conn, 0, + "Error calculating v"); + goto end; + } + + /* The secret data is stored as suggested in RFC 2945: + * + * { utf8(mda) mpi(v) os(salt) } (base64 encoded) + */ + + r = MakeBuffer(text->utils, &text->out_buf, &text->out_buf_len, + &bufferlen, "%s%m%o", + server_mda->name, &v, saltlen, salt); + + if (r) { + sparams->utils->seterror(sparams->utils->conn, 0, + "Error making buffer for secret"); + goto end; + } + buffer = text->out_buf; + + /* Put 'buffer' into sasl_secret_t. + * This will be base64 encoded, so make sure its big enough. + */ + alloclen = (bufferlen/3 + 1) * 4 + 1; + sec = sparams->utils->malloc(sizeof(sasl_secret_t)+alloclen); + if (!sec) { + r = SASL_NOMEM; + goto end; + } + sparams->utils->encode64(buffer, bufferlen, sec->data, alloclen, + &encodelen); + sec->len = encodelen; + + /* Clean everything up */ + end: + if (buffer) sparams->utils->free((void *) buffer); + BN_clear_free(&N); + BN_clear_free(&g); + BN_clear_free(&v); + sparams->utils->free(text); + + if (r) return r; + } + + /* do the store */ + propctx = sparams->utils->prop_new(0); + if (!propctx) + r = SASL_FAIL; + if (!r) + r = sparams->utils->prop_request(propctx, store_request); + if (!r) + r = sparams->utils->prop_set(propctx, "cmusaslsecretSRP", + (sec ? sec->data : NULL), + (sec ? sec->len : 0)); + if (!r) + r = sparams->utils->auxprop_store(sparams->utils->conn, propctx, user); + if (propctx) + sparams->utils->prop_dispose(&propctx); + + if (r) { + sparams->utils->seterror(sparams->utils->conn, 0, + "Error putting SRP secret"); + goto cleanup; + } + + sparams->utils->log(NULL, SASL_LOG_DEBUG, "Setpass for SRP successful\n"); + + cleanup: + + if (user) _plug_free_string(sparams->utils, &user); + if (user_only) _plug_free_string(sparams->utils, &user_only); + if (realm) _plug_free_string(sparams->utils, &realm); + if (sec) _plug_free_secret(sparams->utils, &sec); + + return r; +} +#endif /* DO_SRP_SETPASS */ + +static int srp_mech_avail(void *glob_context __attribute__((unused)), + sasl_server_params_t *sparams, + void **conn_context __attribute__((unused))) +{ + /* Do we have access to the selected MDA? */ + if (!server_mda || !server_mda->enabled) { + SETERROR(sparams->utils, + "SRP unavailable due to selected MDA unavailable"); + return SASL_NOMECH; + } + + return SASL_OK; +} + +static sasl_server_plug_t srp_server_plugins[] = +{ + { + "SRP", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS + | SASL_SEC_NOACTIVE + | SASL_SEC_NODICTIONARY + | SASL_SEC_FORWARD_SECRECY + | SASL_SEC_MUTUAL_AUTH, /* security_flags */ + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY, /* features */ + NULL, /* glob_context */ + &srp_server_mech_new, /* mech_new */ + &srp_server_mech_step, /* mech_step */ + &srp_common_mech_dispose, /* mech_dispose */ + &srp_common_mech_free, /* mech_free */ +#ifdef DO_SRP_SETPASS + &srp_setpass, /* setpass */ +#else + NULL, +#endif + NULL, /* user_query */ + NULL, /* idle */ + &srp_mech_avail, /* mech avail */ + NULL /* spare */ + } +}; + +int srp_server_plug_init(const sasl_utils_t *utils, + int maxversion, + int *out_version, + const sasl_server_plug_t **pluglist, + int *plugcount, + const char *plugname __attribute__((unused))) +{ + const char *mda; + unsigned int len; + layer_option_t *opts; + + if (maxversion < SASL_SERVER_PLUG_VERSION) { + SETERROR(utils, "SRP version mismatch"); + return SASL_BADVERS; + } + + utils->getopt(utils->getopt_context, "SRP", "srp_mda", &mda, &len); + if (!mda) mda = DEFAULT_MDA; + + /* Add all digests and ciphers */ + OpenSSL_add_all_algorithms(); + + /* See which digests we have available and set max_ssf accordingly */ + opts = digest_options; + while (opts->name) { + if (EVP_get_digestbyname(opts->evp_name)) { + opts->enabled = 1; + + srp_server_plugins[0].max_ssf = opts->ssf; + } + + /* Locate the server MDA */ + if (!strcasecmp(opts->name, mda) || !strcasecmp(opts->evp_name, mda)) { + server_mda = opts; + } + + opts++; + } + + /* See which ciphers we have available and set max_ssf accordingly */ + opts = cipher_options; + while (opts->name) { + if (EVP_get_cipherbyname(opts->evp_name)) { + opts->enabled = 1; + + if (opts->ssf > srp_server_plugins[0].max_ssf) { + srp_server_plugins[0].max_ssf = opts->ssf; + } + } + + opts++; + } + + *out_version = SASL_SERVER_PLUG_VERSION; + *pluglist = srp_server_plugins; + *plugcount = 1; + + return SASL_OK; +} + +/***************************** Client Section *****************************/ + +/* Check to see if N,g is in the recommended list */ +static int check_N_and_g(const sasl_utils_t *utils, BIGNUM *N, BIGNUM *g) +{ + char *N_prime; + unsigned long g_prime; + unsigned i; + int r = SASL_FAIL; + + N_prime = BN_bn2hex(N); + g_prime = BN_get_word(g); + + for (i = 0; i < NUM_Ng; i++) { + if (!strcasecmp(N_prime, Ng_tab[i].N) && (g_prime == Ng_tab[i].g)) { + r = SASL_OK; + break; + } + } + + if (N_prime) utils->free(N_prime); + + return r; +} + +static int CalculateA(context_t *text __attribute__((unused)), + BIGNUM *N, BIGNUM *g, BIGNUM *a, BIGNUM *A) +{ + BN_CTX *ctx = BN_CTX_new(); + + /* Generate a */ + GetRandBigInt(a); + + /* Per [SRP]: make sure a > log[g](N) -- g is always 2 */ + BN_add_word(a, BN_num_bits(N)); + + /* A = g^a % N */ + BN_init(A); + BN_mod_exp(A, g, a, N, ctx); + + BN_CTX_free(ctx); + + return SASL_OK; +} + +static int ClientCalculateK(context_t *text, char *salt, int saltlen, + char *user, char *pass, int passlen, + BIGNUM *N, BIGNUM *g, BIGNUM *a, BIGNUM *A, + BIGNUM *B, char *K, int *Klen) +{ + int r; + unsigned char hash[EVP_MAX_MD_SIZE]; + int hashlen; + BIGNUM x; + BIGNUM u; + BIGNUM aux; + BIGNUM gx; + BIGNUM gx3; + BIGNUM base; + BIGNUM S; + BN_CTX *ctx = BN_CTX_new(); + + /* u = H(A | B) */ + r = MakeHash(text->md, hash, &hashlen, "%m%m", A, B); + if (r) goto err; + BN_init(&u); + BN_bin2bn(hash, hashlen, &u); + + /* per Tom Wu: make sure u != 0 */ + if (BN_is_zero(&u)) { + SETERROR(text->utils, "SRP: Illegal value for 'u'\n"); + r = SASL_BADPROT; + goto err; + } + + /* S = (B - 3(g^x)) ^ (a + ux) % N */ + + r = CalculateX(text, salt, saltlen, user, pass, passlen, &x); + if (r) return r; + + /* a + ux */ + BN_init(&aux); + BN_mul(&aux, &u, &x, ctx); + BN_add(&aux, &aux, a); + + /* gx3 = 3(g^x) % N */ + BN_init(&gx); + BN_mod_exp(&gx, g, &x, N, ctx); + BN_init(&gx3); + BN_set_word(&gx3, 3); + BN_mod_mul(&gx3, &gx3, &gx, N, ctx); + + /* base = (B - 3(g^x)) % N */ + BN_init(&base); +#if OPENSSL_VERSION_NUMBER >= 0x00907000L + BN_mod_sub(&base, B, &gx3, N, ctx); +#else + BN_sub(&base, B, &gx3); + BN_mod(&base, &base, N, ctx); + if (BigIntCmpWord(&base, 0) < 0) { + BN_add(&base, &base, N); + } +#endif + + /* S = base^aux % N */ + BN_init(&S); + BN_mod_exp(&S, &base, &aux, N, ctx); + + /* K = H(S) */ + r = MakeHash(text->md, K, Klen, "%m", &S); + if (r) goto err; + + r = SASL_OK; + + err: + BN_CTX_free(ctx); + BN_clear_free(&x); + BN_clear_free(&u); + BN_clear_free(&aux); + BN_clear_free(&gx); + BN_clear_free(&gx3); + BN_clear_free(&base); + BN_clear_free(&S); + + return r; +} + +static int CreateClientOpts(sasl_client_params_t *params, + srp_options_t *available, + srp_options_t *out) +{ + layer_option_t *opt; + sasl_ssf_t external; + sasl_ssf_t limit; + sasl_ssf_t musthave; + + /* zero out output */ + memset(out, 0, sizeof(srp_options_t)); + + params->utils->log(NULL, SASL_LOG_DEBUG, + "Available MDA = %d\n", available->mda); + + /* mda */ + opt = FindBest(available->mda, 0, 256, digest_options); + + if (opt) { + out->mda = opt->bit; + } + else { + SETERROR(params->utils, "Can't find an acceptable SRP MDA\n"); + return SASL_BADAUTH; + } + + /* get requested ssf */ + external = params->external_ssf; + + /* what do we _need_? how much is too much? */ + if(params->props.maxbufsize == 0) { + musthave = 0; + limit = 0; + } else { + if (params->props.max_ssf > external) { + limit = params->props.max_ssf - external; + } else { + limit = 0; + } + if (params->props.min_ssf > external) { + musthave = params->props.min_ssf - external; + } else { + musthave = 0; + } + } + + /* we now go searching for an option that gives us at least "musthave" + and at most "limit" bits of ssf. */ + params->utils->log(NULL, SASL_LOG_DEBUG, + "Available confidentiality = %d " + "musthave = %d limit = %d", + available->confidentiality, musthave, limit); + + /* confidentiality */ + if (limit > 1) { + + opt = FindBest(available->confidentiality, musthave, limit, + cipher_options); + + if (opt) { + out->confidentiality = opt->bit; + /* we've already satisfied the SSF with the confidentiality + * layer, but we'll also use an integrity layer if we can + */ + musthave = 0; + } + else if (musthave > 1) { + SETERROR(params->utils, + "Can't find an acceptable SRP confidentiality layer\n"); + return SASL_TOOWEAK; + } + } + + params->utils->log(NULL, SASL_LOG_DEBUG, + "Available integrity = %d " + "musthave = %d limit = %d", + available->integrity, musthave, limit); + + /* integrity */ + if ((limit >= 1) && (musthave <= 1)) { + + opt = FindBest(available->integrity, musthave, limit, + digest_options); + + if (opt) { + out->integrity = opt->bit; + + /* if we set an integrity option we can set replay detection */ + out->replay_detection = available->replay_detection; + } + else if (musthave > 0) { + SETERROR(params->utils, + "Can't find an acceptable SRP integrity layer\n"); + return SASL_TOOWEAK; + } + } + + /* Check to see if we've satisfied all of the servers mandatory layers */ + params->utils->log(NULL, SASL_LOG_DEBUG, + "Mandatory layers = %d\n",available->mandatory); + + if ((!out->replay_detection && + (available->mandatory & BIT_REPLAY_DETECTION)) || + (!out->integrity && + (available->mandatory & BIT_INTEGRITY)) || + (!out->confidentiality && + (available->mandatory & BIT_CONFIDENTIALITY))) { + SETERROR(params->utils, "Mandatory SRP layer not supported\n"); + return SASL_BADAUTH; + } + + /* Add maxbuffersize */ + out->maxbufsize = SRP_MAXBUFFERSIZE; + if (params->props.maxbufsize && params->props.maxbufsize < out->maxbufsize) + out->maxbufsize = params->props.maxbufsize; + + return SASL_OK; +} + +static int srp_client_mech_new(void *glob_context __attribute__((unused)), + sasl_client_params_t *params, + void **conn_context) +{ + context_t *text; + + /* holds state are in */ + text = params->utils->malloc(sizeof(context_t)); + if (text == NULL) { + MEMERROR( params->utils ); + return SASL_NOMEM; + } + + memset(text, 0, sizeof(context_t)); + + text->state = 1; + text->utils = params->utils; + + *conn_context = text; + + return SASL_OK; +} + +static int +srp_client_mech_step1(context_t *text, + sasl_client_params_t *params, + const char *serverin __attribute__((unused)), + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + const char *authid = NULL, *userid = NULL; + int auth_result = SASL_OK; + int pass_result = SASL_OK; + int user_result = SASL_OK; + int result; + + /* Expect: + * absolutely nothing + * + */ + if (serverinlen > 0) { + SETERROR(params->utils, "Invalid input to first step of SRP\n"); + return SASL_BADPROT; + } + + /* try to get the authid */ + if (oparams->authid==NULL) { + auth_result = _plug_get_authid(params->utils, &authid, prompt_need); + + if ((auth_result != SASL_OK) && (auth_result != SASL_INTERACT)) + return auth_result; + } + + /* try to get the userid */ + if (oparams->user == NULL) { + user_result = _plug_get_userid(params->utils, &userid, prompt_need); + + if ((user_result != SASL_OK) && (user_result != SASL_INTERACT)) + return user_result; + } + + /* try to get the password */ + if (text->password == NULL) { + pass_result=_plug_get_password(params->utils, &text->password, + &text->free_password, prompt_need); + + if ((pass_result != SASL_OK) && (pass_result != SASL_INTERACT)) + return pass_result; + } + + /* free prompts we got */ + if (prompt_need && *prompt_need) { + params->utils->free(*prompt_need); + *prompt_need = NULL; + } + + /* if there are prompts not filled in */ + if ((auth_result == SASL_INTERACT) || (user_result == SASL_INTERACT) || + (pass_result == SASL_INTERACT)) { + /* make the prompt list */ + result = + _plug_make_prompts(params->utils, prompt_need, + user_result == SASL_INTERACT ? + "Please enter your authorization name" : NULL, + NULL, + auth_result == SASL_INTERACT ? + "Please enter your authentication name" : NULL, + NULL, + pass_result == SASL_INTERACT ? + "Please enter your password" : NULL, NULL, + NULL, NULL, NULL, + NULL, NULL, NULL); + if (result != SASL_OK) return result; + + return SASL_INTERACT; + } + + if (!userid || !*userid) { + result = params->canon_user(params->utils->conn, authid, 0, + SASL_CU_AUTHID | SASL_CU_AUTHZID, oparams); + } + else { + result = params->canon_user(params->utils->conn, authid, 0, + SASL_CU_AUTHID, oparams); + if (result != SASL_OK) return result; + + result = params->canon_user(params->utils->conn, userid, 0, + SASL_CU_AUTHZID, oparams); + } + if (result != SASL_OK) return result; + + /* Send out: + * + * U - authentication identity + * I - authorization identity + * sid - previous session id + * cn - client nonce + * + * { utf8(U) utf8(I) utf8(sid) os(cn) } + */ + result = MakeBuffer(text->utils, &text->out_buf, &text->out_buf_len, + clientoutlen, "%s%s%s%o", + (char *) oparams->authid, (char *) oparams->user, + "", 0, ""); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n"); + goto cleanup; + } + *clientout = text->out_buf; + + text->state = 2; + + result = SASL_CONTINUE; + + cleanup: + + return result; +} + +static int +srp_client_mech_step2(context_t *text, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need __attribute__((unused)), + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + int result; + char reuse; + srp_options_t server_opts; + + /* Expect: + * + * { 0x00 mpi(N) mpi(g) os(s) mpi(B) utf8(L) } + */ + result = UnBuffer(params->utils, serverin, serverinlen, + "%c%m%m%o%m%s", &reuse, &text->N, &text->g, + &text->saltlen, &text->salt, &text->B, + &text->server_options); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error UnBuffering input in step 2"); + goto cleanup; + } + + /* Check N and g to see if they are one of the recommended pairs */ + result = check_N_and_g(params->utils, &text->N, &text->g); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, + "Values of 'N' and 'g' are not recommended\n"); + goto cleanup; + } + + /* Per [SRP]: reject B <= 0, B >= N */ + if (BigIntCmpWord(&text->B, 0) <= 0 || BN_cmp(&text->B, &text->N) >= 0) { + SETERROR(params->utils, "Illegal value for 'B'\n"); + result = SASL_BADPROT; + goto cleanup; + } + + /* parse server options */ + memset(&server_opts, 0, sizeof(srp_options_t)); + result = ParseOptions(params->utils, text->server_options, &server_opts, 0); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, + "Error parsing SRP server options\n"); + goto cleanup; + } + + /* Create o */ + result = CreateClientOpts(params, &server_opts, &text->client_opts); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, + "Error creating client options\n"); + goto cleanup; + } + + result = OptionsToString(params->utils, &text->client_opts, + &text->client_options); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, + "Error converting client options to an option string\n"); + goto cleanup; + } + + result = SetMDA(&text->client_opts, text); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error setting MDA"); + goto cleanup; + } + + /* Calculate A */ + result = CalculateA(text, &text->N, &text->g, &text->a, &text->A); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error calculating A"); + return result; + } + + /* Calculate shared context key K */ + result = ClientCalculateK(text, text->salt, text->saltlen, + (char *) oparams->authid, + text->password->data, text->password->len, + &text->N, &text->g, &text->a, &text->A, &text->B, + text->K, &text->Klen); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, + "Error creating K\n"); + goto cleanup; + } + + /* Calculate M1 (client evidence) */ + result = CalculateM1(text, &text->N, &text->g, (char *) oparams->authid, + text->salt, text->saltlen, &text->A, &text->B, + text->K, text->Klen, (char *) oparams->user, + text->server_options, text->M1, &text->M1len); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, + "Error creating M1\n"); + goto cleanup; + } + + /* Create cIV (client initial vector) */ + text->utils->rand(text->utils->rpool, text->cIV, sizeof(text->cIV)); + + /* Send out: + * + * A - client's public key + * M1 - client evidence + * o - client option list + * cIV - client initial vector + * + * { mpi(A) os(M1) utf8(o) os(cIV) } + */ + result = MakeBuffer(text->utils, &text->out_buf, &text->out_buf_len, + clientoutlen, "%m%o%s%o", + &text->A, text->M1len, text->M1, text->client_options, + sizeof(text->cIV), text->cIV); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, "Error making output buffer\n"); + goto cleanup; + } + *clientout = text->out_buf; + + text->state = 3; + + result = SASL_CONTINUE; + + cleanup: + + return result; +} + +static int +srp_client_mech_step3(context_t *text, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need __attribute__((unused)), + const char **clientout __attribute__((unused)), + unsigned *clientoutlen __attribute__((unused)), + sasl_out_params_t *oparams) +{ + int result; + char *M2 = NULL, *sIV = NULL; /* don't free */ + char *sid = NULL; + int M2len, sIVlen; + uint32 ttl; + int i; + char myM2[EVP_MAX_MD_SIZE]; + int myM2len; + + /* Expect: + * + * M2 - server evidence + * sIV - server initial vector + * sid - session id + * ttl - time to live + * + * { os(M2) os(sIV) utf8(sid) uint(ttl) } + */ + result = UnBuffer(params->utils, serverin, serverinlen, + "%-o%-o%s%u", &M2len, &M2, &sIVlen, &sIV, + &sid, &ttl); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error UnBuffering input in step 3"); + goto cleanup; + } + + /* calculate our own M2 */ + result = CalculateM2(text, &text->A, text->M1, text->M1len, + text->K, text->Klen, (char *) oparams->user, + text->client_options, "", 0, + myM2, &myM2len); + if (result) { + params->utils->log(NULL, SASL_LOG_ERR, + "Error calculating our own M2 (server evidence)\n"); + goto cleanup; + } + + /* compare to see if is server spoof */ + if (myM2len != M2len) { + SETERROR(params->utils, "SRP Server M2 length wrong\n"); + result = SASL_BADSERV; + goto cleanup; + } + + + for (i = 0; i < myM2len; i++) { + if (M2[i] != myM2[i]) { + SETERROR(params->utils, + "SRP Server spoof detected. M2 incorrect\n"); + result = SASL_BADSERV; + goto cleanup; + } + } + + /* + * Send out: nothing + */ + + /* configure security layer */ + result = LayerInit(&text->client_opts, text, oparams, sIV, text->cIV, + params->props.maxbufsize); + if (result) { + params->utils->seterror(params->utils->conn, 0, + "Error initializing security layer"); + return result; + } + + /* set oparams */ + oparams->doneflag = 1; + oparams->param_version = 0; + + result = SASL_OK; + + cleanup: + if (sid) params->utils->free(sid); + + return result; +} + +static int srp_client_mech_step(void *conn_context, + sasl_client_params_t *params, + const char *serverin, + unsigned serverinlen, + sasl_interact_t **prompt_need, + const char **clientout, + unsigned *clientoutlen, + sasl_out_params_t *oparams) +{ + context_t *text = (context_t *) conn_context; + + params->utils->log(NULL, SASL_LOG_DEBUG, + "SRP client step %d\n", text->state); + + *clientout = NULL; + *clientoutlen = 0; + + switch (text->state) { + + case 1: + return srp_client_mech_step1(text, params, serverin, serverinlen, + prompt_need, clientout, clientoutlen, + oparams); + + case 2: + return srp_client_mech_step2(text, params, serverin, serverinlen, + prompt_need, clientout, clientoutlen, + oparams); + + case 3: + return srp_client_mech_step3(text, params, serverin, serverinlen, + prompt_need, clientout, clientoutlen, + oparams); + + default: + params->utils->log(NULL, SASL_LOG_ERR, + "Invalid SRP client step %d\n", text->state); + return SASL_FAIL; + } + + return SASL_FAIL; /* should never get here */ +} + + +static sasl_client_plug_t srp_client_plugins[] = +{ + { + "SRP", /* mech_name */ + 0, /* max_ssf */ + SASL_SEC_NOPLAINTEXT + | SASL_SEC_NOANONYMOUS + | SASL_SEC_NOACTIVE + | SASL_SEC_NODICTIONARY + | SASL_SEC_FORWARD_SECRECY + | SASL_SEC_MUTUAL_AUTH, /* security_flags */ + SASL_FEAT_WANT_CLIENT_FIRST + | SASL_FEAT_ALLOWS_PROXY, /* features */ + NULL, /* required_prompts */ + NULL, /* glob_context */ + &srp_client_mech_new, /* mech_new */ + &srp_client_mech_step, /* mech_step */ + &srp_common_mech_dispose, /* mech_dispose */ + &srp_common_mech_free, /* mech_free */ + NULL, /* idle */ + NULL, /* spare */ + NULL /* spare */ + } +}; + +int srp_client_plug_init(const sasl_utils_t *utils __attribute__((unused)), + int maxversion, + int *out_version, + const sasl_client_plug_t **pluglist, + int *plugcount, + const char *plugname __attribute__((unused))) +{ + layer_option_t *opts; + + if (maxversion < SASL_CLIENT_PLUG_VERSION) { + SETERROR(utils, "SRP version mismatch"); + return SASL_BADVERS; + } + + /* Add all digests and ciphers */ + OpenSSL_add_all_algorithms(); + + /* See which digests we have available and set max_ssf accordingly */ + opts = digest_options; + while (opts->name) { + if (EVP_get_digestbyname(opts->evp_name)) { + opts->enabled = 1; + + srp_client_plugins[0].max_ssf = opts->ssf; + } + + opts++; + } + + /* See which ciphers we have available and set max_ssf accordingly */ + opts = cipher_options; + while (opts->name) { + if (EVP_get_cipherbyname(opts->evp_name)) { + opts->enabled = 1; + + if (opts->ssf > srp_client_plugins[0].max_ssf) { + srp_client_plugins[0].max_ssf = opts->ssf; + } + } + + opts++; + } + + *out_version = SASL_CLIENT_PLUG_VERSION; + *pluglist = srp_client_plugins; + *plugcount=1; + + return SASL_OK; +} diff --git a/libs/cyrussasl/plugins/srp_init.c b/libs/cyrussasl/plugins/srp_init.c new file mode 100644 index 00000000..305dcb3e --- /dev/null +++ b/libs/cyrussasl/plugins/srp_init.c @@ -0,0 +1,43 @@ + +#include + +#include +#include +#include +#ifndef macintosh +#include +#endif +#include +#include + +#include +#include +#include + +#include "plugin_common.h" + +#ifdef macintosh +#include +#endif + +#ifdef WIN32 +BOOL APIENTRY DllMain( HANDLE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} +#endif + +SASL_CLIENT_PLUG_INIT( srp ) +SASL_SERVER_PLUG_INIT( srp ) + diff --git a/libs/libiconv/AUTHORS b/libs/libiconv/AUTHORS new file mode 100644 index 00000000..8bedd794 --- /dev/null +++ b/libs/libiconv/AUTHORS @@ -0,0 +1 @@ +Bruno Haible diff --git a/libs/libiconv/COPYING b/libs/libiconv/COPYING new file mode 100644 index 00000000..94a9ed02 --- /dev/null +++ b/libs/libiconv/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/libs/libiconv/COPYING.LIB b/libs/libiconv/COPYING.LIB new file mode 100644 index 00000000..778d0bb5 --- /dev/null +++ b/libs/libiconv/COPYING.LIB @@ -0,0 +1,482 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/libs/libiconv/ChangeLog b/libs/libiconv/ChangeLog new file mode 100644 index 00000000..b7113643 --- /dev/null +++ b/libs/libiconv/ChangeLog @@ -0,0 +1,4913 @@ +2011-08-07 Bruno Haible + + * Version 1.14 released. + +2011-08-07 Bruno Haible + + * configure.ac: Bump version number to 1.14. + * README: Likewise. + * include/iconv.h.in (_LIBICONV_VERSION): Likewise. + * windows/iconv.rc: Update. + * lib/Makefile.in (LIBICONV_VERSION_INFO): Bump to 7:1:5. + * src/iconv.c (print_version): Update copyright year. + +2011-08-07 Bruno Haible + + Avoid a test failure on Solaris 2.6 and HP-UX 11.00. + * tests/test-to-wchar.c (main): Skip the test if conversion to wchar_t + is not supported. + +2011-08-07 Bruno Haible + + * tests/check-subst: Add comments about OSF/1. + +2011-08-07 Bruno Haible + + * lib/relocatable.c: Update from gnulib. + +2011-08-06 Bruno Haible + + Upgrade the GB18030 converter to the version from 2005. + * lib/gb18030ext.h (gb18030ext_2uni_pagefe): Change element type to + 'unsigned int'. Change values for 0xFE51..0xFE53, 0xFE59, 0xFE61, + 0xFE66, 0xFE67, 0xFE6C, 0xFE6D, 0xFE76, 0xFE7E, 0xFE90, 0xFE91, 0xFEA0. + (gb18030ext_mbtowc): Change type of wc to 'unsigned int'. Change values + for 0xA6D9..0xA6DF, 0xA6EC..0xA6ED, 0xA6F3, 0xA8BC. + (gb18030ext_page9f, gb18030ext_pagefe): New constant arrays. + (gb18030ext_wctomb): Change values for U+1E3F, U+9FB4..U+9FBB, + U+FE10..U+FE19, U+20087, U+20089, U+200CC, U+215D7, U+2298F, U+241FE. + * tests/GB18030-BMP.TXT: Change values for 0xA6D9..0xA6DF, + 0xA6EC..0xA6ED, 0xA6F3, 0xA8BC, 0xFE51..0xFE53, 0xFE59, 0xFE61, 0xFE66, + 0xFE67, 0xFE6C, 0xFE6D, 0xFE76, 0xFE7E, 0xFE90, 0xFE91, 0xFEA0, to map + to now-assigned Unicode codepoints. + * tests/GB18030.IRREVERSIBLE.TXT: New file. + +2011-08-06 Bruno Haible + + Fix conversion bug in CP1258 converter. + * lib/vietcomb.h (viet_comp_table_data): Remove entry for + U+00A5 U+0301. Fix entry for U+00A8 U+0301. + (viet_decomp_table): Fix entry for U+0385. + * tests/CP1258.IRREVERSIBLE.TXT: Update. + Reported by Gertjan Halkes . + +2011-07-03 Bruno Haible + + Improve interactive behaviour of iconv program. + * src/iconv.c (convert): Flush the output before starting a possibly + blocking safe_read call. + +2011-07-03 Bruno Haible + + Fix interactive behaviour of iconv program. + * Makefile.devel (GNULIB_MODULES): Add safe-read. + * src/iconv.c: Include safe-read.h. + (convert): Take the infile as a file descriptor, not as a FILE stream. + Use safe_read() instead of fread(). + (main): Update. + Reported by Xavier Pucel . + +2011-05-02 Bruno Haible + + Update after gnulib changed. + * autogen.sh (GNULIB_MODULES): Remove exit, add stdlib. + +2011-06-02 Bruno Haible + + Update after gnulib changed. + * gnulib-local/m4/alloca.m4 (gl_FUNC_ALLOCA): Update. + +2011-06-04 Bruno Haible + + Work around bug on OSF/1 5.1. + * lib/loop_wchar.h: Before including , include and + some other includes. + +2011-03-27 KO Myung-Hun + + Fix installation on OS/2. + * src/Makefile.in (all, iconv_no_i18n): Add $(EXEEXT) suffix to + iconv_no_i18n. This is the recommended way to use libtool, see + . + +2011-03-31 Bruno Haible + + gentranslit: Fix buffer overrun. + * lib/gentranslit.c (main): Allocate more room for the suffix strings + of the translit pages. + Reported by Ben Noordhuis . + +2011-02-28 Bruno Haible + + * lib/relocatable.h: Update from gnulib. + * lib/relocatable.c: Likewise. + +2011-01-29 Corinna Vinschen + Bruno Haible + + Simplify "wchar_t" handling on Cygwin 1.7.x. + * lib/iconv.c (iconv_canonicalize): On Cygwin >= 1.7, map + ei_local_wchar_t to ei_utf16le or ei_utf16be, not ei_ucs2internal. + * lib/iconv_open1.h: Likewise. + Rationale: . + +2011-01-29 Bruno Haible + + Adjust the meaning of "wchar_t" on native Windows systems. + * lib/iconv.c (iconv_canonicalize): On native Windows, map + ei_local_wchar_t to ei_utf16le or ei_utf16be, not ei_ucs2internal. + * lib/iconv_open1.h: Likewise. + Reported by Corinna Vinschen + in . + +2010-11-23 Bruno Haible + + Implement newer release of BIG5-HKSCS. + * tools/Makefile (ALL): Add hkscs2008.h. + (hkscs2008.h): New rule. + * tools/cjk_tab_to_h.c (main): Recognize hkscs2008. + * lib/encodings.def: Add BIG5-HKSCS:2008. Change BIG5-HKSCS alias to be + equivalent to BIG5-HKSCS:2008. + * lib/hkscs2008.h: New file, autogenerated. + * lib/big5hkscs2008.h: New file, based on lib/big5hkscs2004.h. + * lib/converters.h: Include the new file. + * README, man/iconv_open.3: Add BIG5-HKSCS:2004. + * tests/BIG5-HKSCS-2008.TXT: New file, based on + tests/BIG5-HKSCS-2004.TXT. + * tests/BIG5-HKSCS-2008.IRREVERSIBLE.TXT: New file, copied from + tests/BIG5-HKSCS-2004.IRREVERSIBLE.TXT + * tests/BIG5-HKSCS-2008-snippet: New file, based on + tests/BIG5-HKSCS-2004-snippet. + * tests/BIG5-HKSCS-2008-snippet.UTF-8: New file, based on + tests/BIG5-HKSCS-2004-snippet.UTF-8. + * tests/Makefile.in (check): Check also BIG5-HKSCS:2008. + Reported by oCameLo . + +2010-11-23 Bruno Haible + + Make cjk_tab_to_h 64-bit clean. + * tools/cjk_tab_to_h.c (do_jisx0213): Add a cast from size_t to int. + (output_title): Update copyright year. + +2010-09-23 Bruno Haible + + Switch to autoconf 2.68. + * autogen.sh: Update comment. + * configure.ac: Fix AC_COMPILE_IFELSE invocation. + * Makefile.devel (AUTOCONF, AUTOHEADER): Switch to version 2.68. + * preload/Makefile.devel (AUTOCONF): Likewise. + +2010-09-23 Bruno Haible + + * m4/libtool.m4: Update from libtool-2.4, with modifications: + 2008-04-06 Bruno Haible + * m4/libtool.m4 (LT_INIT): When setting LIBTOOL, use + CONFIG_SHELL; don't assume that the Makefile.in will set SHELL + to ${CONFIG_SHELL}. + * m4/ltversion.m4: Update from libtool-2.4. + * build-aux/ltmain.sh: Likewise. + +2010-09-23 Bruno Haible + + Simplify use of gnulib-tool now that gnulib-tool --import works better. + * autogen.sh: Don't remove gnulib-cache.m4 before running gnulib-tool. + * Makefile.devel (srclib/Makefile.gnulib): Depend on 'force'. + +2010-07-31 Bruno Haible + + * Makefile.devel (AUTOCONF, AUTOHEADER): Switch to version 2.67. + * preload/Makefile.devel (AUTOCONF): Likewise. + +2010-07-03 Bruno Haible + + * Makefile.devel (AUTOCONF, AUTOHEADER): Switch to version 2.66. + * preload/Makefile.devel (AUTOCONF): Likewise. + +2010-06-04 Bruno Haible + + Addendum to 2009-10-18 commit. + * m4/fcntl-o.m4: New file, from gnulib. + * configure.ac: Invoke gl_FCNTL_O_FLAGS. + * lib/config.h.in (HAVE_WORKING_O_NOFOLLOW): New macro. + +2010-06-04 Bruno Haible + + * m4/libtool.m4: Update from libtool-2.2.8, with modifications: + 2008-04-06 Bruno Haible + * m4/libtool.m4 (LT_INIT): When setting LIBTOOL, use + CONFIG_SHELL; don't assume that the Makefile.in will set SHELL + to ${CONFIG_SHELL}. + * m4/ltoptions.m4: Update from libtool-2.2.8. + * m4/ltversion.m4: Likewise. + * m4/lt~obsolete.m4: Likewise. + * build-aux/ltmain.sh: Likewise. + +2010-04-06 Bruno Haible + + Avoid a compilation error of gnulib's test-iconv-h-c++.cc on mingw. + * include/iconv.h.in: Restrict the extern "C" { ... } scope so that it + doesn't contains #include directives. + +2010-03-30 Bruno Haible + + * README.woe32: Update for Cygwin 1.7.x. + +2009-12-26 Bruno Haible + + * windows/libiconv.rc: Update. + * windows/iconv.rc: Update. + +2009-12-11 Bruno Haible + + * include/iconv.h.in: Untabify. + * gnulib-local/lib/xalloc.h: Untabify. + * woe32dll/export.h: Untabify. + * tests/uniq-u.c: Untabify. + +2009-12-11 Bruno Haible + + * srclib/Makefile.am (MOSTLYCLEANDIRS): New macro. + +2009-12-11 Bruno Haible + + * Makefile.devel (AUTOCONF, AUTOHEADER): Switch to version 2.65. + * preload/Makefile.devel (AUTOCONF): Likewise. + +2009-11-22 Bruno Haible + + * tests/check-subst: Add reference to the Solaris printf bug. + Reported by Dagobert Michelsen . + +2009-09-01 Bruno Haible + + * README.woe32: Put the -mno-cygwin option into CC and CXX. + Recommended by Paolo Bonzini and Eric Blake. + +2009-08-15 Bruno Haible + + * Makefile.devel (AUTOCONF, AUTOHEADER): Switch to version 2.64. + * preload/Makefile.devel (AUTOCONF): Likewise. + +2009-08-15 Bruno Haible + + Use .git/info/exclude, not .gitignore, for imported or generated files. + * Makefile.devel (srclib/Makefile.gnulib): Pass option --no-vc-files to + gnulib-tool. + +2009-07-07 Bruno Haible + + Fix an endless loop. + * lib/loop_wchar.h (wchar_to_loop_convert): Handle the case of + incomplete input correctly. + * tests/test-to-wchar.c: New file. + * tests/Makefile.in (tests-to-wchar, tests-to-wchar.o): New rules. + (check): Depend on and run tests-to-wchar. + (clean): Add tests-to-wchar. + Reported by Tristan Gingold . + +2009-06-30 Bruno Haible + + * Version 1.13.1 released. + +2009-06-30 Bruno Haible + + * configure.ac: Bump version number to 1.13.1. + * README: Likewise. + +2009-06-04 Bruno Haible + + * preload/Makefile.devel (AUTOCONF): Switch to version 2.63. + (ACLOCAL): Switch to version 1.11. + +2009-05-19 Bruno Haible + + * Makefile.devel (AUTOMAKE, ACLOCAL): Switch to version 1.11. + * autogen.sh: Update comments. + +2009-04-24 Bruno Haible + + Fix a compilation error on HP-UX 11.00, introduced on 2008-09-16. + * src/iconv_open2.h: Don't initialize nonexistent field if + !(HAVE_WCRTOMB || HAVE_MBRTOWC). + Patch by Joel Brobecker . + +2009-04-15 Bruno Haible + + * src/Makefile.in (install, uninstall): Append the $(EXEEXT) suffix + explicitly. Needed on Cygwin. + +2009-04-11 Bruno Haible + + * configure.ac: Move the statements for WOE32 and WINDRES. + +2009-03-26 Bruno Haible + + * Version 1.13 released. + +2009-03-26 Bruno Haible + + * src/iconv.c: Update copyright header to GPLv3+. + (print_version): Update license info. + +2009-03-26 Bruno Haible + + * src/iconv.c (print_version): Bump year. + +2009-03-25 Bruno Haible + + * build-aux/config.guess: Update to GNU version 2009-02-03. + * build-aux/config.sub: Likewise. + +2009-03-25 Bruno Haible + + * configure.ac: Bump version number to 1.13. + * README: Likewise. + * include/iconv.h.in (_LIBICONV_VERSION): Likewise. + * windows/iconv.rc: Update. + * lib/Makefile.in (LIBICONV_VERSION_INFO): Bump to 7:0:5. + +2009-03-25 Bruno Haible + + Fix the handling of Windows resources in shared libraries. + * configure.ac: Invoke LT_LANG for 'Windows Resource'. + * lib/Makefile.in (RC): New variable. + (WINDRES): Remove variable. + (OBJECTS_RES_yes): Add .lo suffix. + (libiconv.res.lo): Renamed from libiconv.res. Use libtool --tag=RC. + (clean): Simplify. + Based on a patch by Roumen Petrov . + +2009-03-14 Bruno Haible + + * autogen.sh: Checkout gnulib using 'git' instead of 'cvs'. + +2009-01-24 Bruno Haible + + * tools/Makefile (ALL): Add cp1131.h. + (cp1131.h): New rule. + * lib/encodings.def: Add CP1131. + * lib/cp1131.h: New file. + * lib/converters.h: Include it. + * README, man/iconv_open.3: Add CP1131. + * NOTES: Mention CP1131. + * tests/CP1131.TXT: New file. + * tests/Makefile.in (check): Also test CP1131. + +2009-01-17 Bruno Haible + + Add support for "make install-strip". + * configure.ac: Search for 'strip'. Invoke AM_PROG_INSTALL_STRIP. + * Makefile.in (install-strip): New rule. + * src/Makefile.in (STRIP, INSTALL_STRIP_PROGRAM, install_sh): New + variables. + (install-strip): New rule. + * lib/Makefile.in (install-strip): New target. + * preload/Makefile.in (install-strip): Likewise. + * man/Makefile.in (install-strip): Likewise. + Reported by Alon Bar-Lev . + +2009-01-17 Bruno Haible + + Update after gnulib changed. + * src/Makefile.in (RELOCATABLE_STRIP): New variable. + +2009-01-17 Bruno Haible + + Make --enable-relocatable work on glibc systems. + * src/Makefile.in (host): New variable. + +2009-01-17 Bruno Haible + + * lib/genflags.c: Include . + +2009-01-14 Bruno Haible + + * configure.ac: More consistent m4 quoting. + * preload/configure.ac: Likewise. + +2008-09-28 Bruno Haible + + * build-aux/ltmain.sh (func_emit_cwrapperexe_src): On mingw, + preprocess the argument vector through prepare_spawn. + +2008-09-27 Bruno Haible + + * build-aux/config.guess: Update to GNU version 2008-09-08. + * build-aux/config.sub: Likewise. + +2008-09-26 Bruno Haible + + * tests/test-shiftseq.c (main1, main2): Use ICONV_CONST. + +2008-09-26 Bruno Haible + + * Makefile.devel (GNULIB_MODULES): Add sigpipe, stdio. + * tests/Makefile.in (check, table-from, table-to, test-shiftseq): Link + all programs against libicrt.a. Needed for the stdio function + replacements on mingw. + +2008-09-21 Tadamasa Teranishi + + * lib/encodings_extra.def: Add aliases for EUC-JISX0213, SHIFT_JISX0213, + ISO-2022-JP-3, found on . + +2008-09-20 Bruno Haible + + * man/iconv_open_into.3: New file. + +2008-09-16 Bruno Haible + + New function iconv_open_into. + * include/iconv.h.in: Include and its prerequisites. + (iconv_allocation_t): New type. + (iconv_open_into): New declaration. + * lib/iconv_open1.h: New file, extracted from lib/iconv.c. + * lib/iconv_open2.h: New file, extracted from lib/iconv.c. + * lib/iconv.c (iconv_open): Include iconv_open1.h and iconv_open2.h. + Verify size of iconv_allocation_t. + (iconv_open_into): New function. + * lib/loop_wchar.h (struct wchar_conv_struct): Don't define a state + field if !(HAVE_WCRTOMB || HAVE_MBRTOWC). + * configure.ac: Set and substitute USE_MBSTATE_T, BROKEN_WCHAR_H. + Reported by Roman Rybalko . + +2008-09-16 Bruno Haible + + * Makefile.devel (AUTOCONF, AUTOHEADER): Switch to version 2.63. + +2008-09-16 Bruno Haible + + * include/iconv.h.in: Use Unicode single-quotes in comments. + +2008-09-14 Bruno Haible + + * Makefile.devel (GNULIB_MODULES): Add strerror. + +2008-09-07 Bruno Haible + + Make behaviour when encountering invalid input after a shift sequence + more consistent. + * lib/converters.h (RET_SHIFT_ILSEQ): New macro. + (RET_ILSEQ): Define in terms of RET_SHIFT_ILSEQ. + (RET_TOOFEW): Change to avoid collisions with RET_SHIFT_ILSEQ. + (DECODE_SHIFT_ILSEQ, DECODE_TOOFEW): New macros. + * lib/loop_unicode.h (unicode_loop_convert): Take into account the + shift count contained in the negative return values. + * lib/hz.h (hz_mbtowc): When encountering invalid input, store the + modified state and return RET_SHIFT_ILSEQ. + * lib/iso2022_cn.h (iso2022_cn_mbtowc): Likewise. + * lib/iso2022_cnext.h (iso2022_cn_ext_mbtowc): Likewise. + * lib/iso2022_jp.h (iso2022_jp_mbtowc): Likewise. + * lib/iso2022_jp1.h (iso2022_jp1_mbtowc): Likewise. + * lib/iso2022_jp2.h (iso2022_jp2_mbtowc): Likewise. + * lib/iso2022_jp3.h (iso2022_jp3_mbtowc): Likewise. + * lib/iso2022_kr.h (iso2022_kr_mbtowc): Likewise. + * lib/ucs2.h (ucs2_mbtowc): Likewise. + * lib/ucs4.h (ucs4_mbtowc): Likewise. + * lib/utf16.h (utf16_mbtowc): Likewise. + * lib/utf32.h (utf32_mbtowc): Likewise. + * lib/utf7.h (utf7_mbtowc): Likewise. + * lib/utf16be.h (utf16be_mbtowcutf16be_mbtowc): When encountering + invalid input, return RET_SHIFT_ILSEQ. + * lib/utf16le.h (utf16le_mbtowc): Likewise. + * tests/test-shiftseq.c: New file. + * tests/Makefile.in (check): Run test-shiftseq. + (test-shiftseq, test-shiftseq.@OBJEXT@): New rules. + (clean): Remove test-shiftseq executable. + Reported by Roman Rybalko + at . + +2008-09-07 Bruno Haible + + * man/iconv.3: Clarify the processing of shift-sequences. + +2008-09-07 Bruno Haible + + * m4/libtool.m4: Update from libtool-2.2.6, with modifications: + 2008-04-06 Bruno Haible + * m4/libtool.m4 (LT_INIT): When setting LIBTOOL, use + CONFIG_SHELL; don't assume that the Makefile.in will set SHELL + to ${CONFIG_SHELL}. + * m4/ltoptions.m4: Update from libtool-2.2.6. + * m4/ltsugar.m4: Likewise. + * m4/ltversion.m4: Likewise. + * build-aux/ltmain.sh: Likewise. + +2008-09-06 Bruno Haible + + * lib/gbk.h (gbk_wctomb): Fix an out-of-bounds write. + Reported by Roman Rybalko + at . + +2008-06-30 Bruno Haible + + Fix sed expressions to work with the old sed-3.02 on MSYS. + * windows/windres-options (sed_extract_major, sed_extract_minor, + sed_extract_subminor): Put a semicolon before the closing brace. Use + an i\ command instead of an a\ command. + Reported by Sunil Negi + in + via Keith Marshall . + +2008-05-22 Bruno Haible + + * README.woe32: Update with info from GNU gettext's README.woe32. + +2008-05-18 Bruno Haible + + * m4/libtool.m4: Update from libtool-2.2.4, with modifications: + 2008-04-06 Bruno Haible + * m4/libtool.m4 (LT_INIT): When setting LIBTOOL, use + CONFIG_SHELL; don't assume that the Makefile.in will set SHELL + to ${CONFIG_SHELL}. + * m4/ltoptions.m4: Update from libtool-2.2.4. + * m4/ltversion.m4: Likewise. + * m4/lt~obsolete.m4: Likewise. + * build-aux/ltmain.sh: Likewise. + +2008-04-14 Bruno Haible + + * tests/Makefile.in (check): Remove *.dSYM directories left over by gcc + on MacOS X 10.5. + +2008-04-14 Bruno Haible + + * preload/configure.ac: Invoke AC_USE_SYSTEM_EXTENSIONS instead of + AC_AIX and AC_MINIX. + * Makefile.devel (AUTOCONF, AUTOHEADER): Require autoconf-2.62. + * preload/Makefile.devel (AUTOCONF): Likewise. + * autogen.sh: Likewise. + +2008-04-06 Bruno Haible + + * m4/libtool.m4: Update from libtool-2.2.2, with modifications: + 2008-04-06 Bruno Haible + * m4/libtool.m4 (LT_INIT): When setting LIBTOOL, use + CONFIG_SHELL; don't assume that the Makefile.in will set SHELL + to ${CONFIG_SHELL}. + * m4/ltoptions.m4: New file, from libtool-2.2.2. + * m4/ltsugar.m4: New file, from libtool-2.2.2. + * m4/ltversion.m4: New file, from libtool-2.2.2. + * m4/lt~obsolete.m4: New file, from libtool-2.2.2. + * build-aux/ltmain.sh: New file, from libtool-2.2.2. + * configure.ac: Use LT_INIT instead of AC_PROG_LIBTOOL. + * preload/configure.ac: Likewise. + +2008-04-06 Bruno Haible + + More portable way of building the preloadable library. + * preload/Makefile.devel: New file. + * preload/Makefile.in: New file, based on lib/Makefile.in. + * preload/configure.ac: New file, based on configure.ac. + * Makefile.devel (all): Recurse into preload directory. + * Makefile.in (all, install, installdirs, uninstall, check, + mostlyclean, clean, distclean, maintainer-clean): Recurse into preload + directory. + * configure.ac: Likewise. + (OS, GCC, PLUGLIB): Remove definitions. + * lib/Makefile.in (all): Don't depend on PLUGLIB. + (preloadable_libiconv.so, preloadable_libiconv_linux.so, + preloadable_libiconv_solaris.so, preloadable_libiconv_osf.so): Remove + rules. + (install, uninstall, clean): Don't handle the preloadable library here. + +2008-04-06 Bruno Haible + + Avoid a gcc warning. + * lib/loop_unicode.h (unicode_loop_convert): Add a cast. + +2008-04-06 Bruno Haible + + * src/iconv.c (print_version): Bump year. + +2008-04-06 Bruno Haible + + Support all possible nl_langinfo(CODESET) results on the respective + platforms, according to libcharset/lib/config.charset. + * lib/encodings.def: Add DEFALIAS statements, conditional on + USE_AIX_ALIASES, USE_HPUX_ALIASES, USE_OSF1_ALIASES, + USE_SOLARIS_ALIASES. + * lib/encodings_aix.def: Add DEFALIAS statements, conditional on + USE_AIX_ALIASES. + * lib/encodings_osf1.def: Add DEFALIAS statements, conditional on + USE_OSF1_ALIASES. + * lib/genaliases.c (emit_alias): New function, extracted from + emit_encoding. + (emit_encoding): Use it. + (main): Define DEFALIAS. + * lib/genaliases2.c (counter): New variable, extracted from + emit_encoding. + (emit_alias): New function, extracted from emit_encoding. + (emit_encoding): Use it. + (main): Define DEFALIAS. + * lib/genflags.c (main): Define DEFALIAS. + * lib/iconv.c (all_encodings): Define DEFALIAS. + Include the system dependent variant of aliases.h on the appropriate + systems. + (all_canonical): Include the system dependent variant of canonical.h, + canonical_aix.h, canonical_osf1.h, canonical_local.h on the appropriate + systems. + * lib/aliases2.h: Include the system dependent variant of + aliases_aix.h or aliases_osf1.h on the appropriate systems. + * lib/Makefile.in (iconv.lo): Depend on aliases_sysaix.h, + aliases_syshpux.h, aliases_sysosf1.h, aliases_syssolaris.h, + aliases_aix_sysaix.h, lib/aliases_osf1_sysosf1.h, and also + aliases_extra.h, translit.h. + * Makefile.devel (all): Depend on lib/aliases_sysaix.h, + lib/aliases_syshpux.h, lib/aliases_sysosf1.h, lib/aliases_syssolaris.h, + lib/aliases_aix_sysaix.h, lib/aliases_osf1_sysosf1.h. + (lib/aliases_sysaix.h, lib/aliases_syshpux.h, lib/aliases_sysosf1.h, + lib/aliases_syssolaris.h): New rules. + (lib/aliases_aix_sysaix.h): New rule. + (lib/aliases_osf1_sysosf1.h): New rule. + * autogen.sh: Also remove lib/aliases_sysaix.h, lib/aliases_syshpux.h, + lib/aliases_sysosf1.h, lib/aliases_syssolaris.h, + lib/aliases_aix_sysaix.h, lib/aliases_osf1_sysosf1.h. + +2008-04-06 Bruno Haible + + * build-aux/config.libpath: Remove file, brought in by gnulib-tool. + * build-aux/config.rpath: Remove file, brought in by gnulib-tool. + +2007-11-11 Bruno Haible + + * Version 1.12 released. + +2007-11-11 Bruno Haible + + * Makefile.devel (AUTOCONF, AUTOHEADER): Require version 2.61. + (AUTOMAKE, ACLOCAL): Require version 1.10. + (srclib/Makefile.in): Avoid error from automake. + +2007-10-26 Bruno Haible + + * m4/libtool.m4: Update, based on libtool-1.5.24. + * build-aux/ltmain.sh: Update, based on libtool-1.5.24. + +2007-10-23 Bruno Haible + + * build-aux/config.guess: Update to GNU version 2007-07-22. + * build-aux/config.sub: Likewise. + +2007-10-23 Bruno Haible + + * configure.ac: Bump version number to 1.12. + * README: Likewise. + +2007-10-23 Bruno Haible + + Move relocatability infrastructure to gnulib. + * gnulib-local/lib/relocatable.h: Remove file. + * gnulib-local/lib/relocatable.c: Remove file. + +2007-10-23 Bruno Haible + + Update from GNU gettext. + 2006-11-26 Bruno Haible + * gnulib-local/lib/xalloc.h (xmemdup): Add a typesafe C++ + template variant. + Based on a patch from Paul Eggert in gnulib. + 2006-11-06 Bruno Haible + * gnulib-local/lib/xalloc.h (xcharalloc): New macro. + (xmemdup): New declaration. + * gnulib-local/lib/xstrdup.c (xmemdup): New function. + 2006-11-03 Bruno Haible + * gnulib-local/lib/xalloc.h (XMALLOC, XNMALLOC, XZALLOC, + XCALLOC): New macros. + (xnboundedmalloc): New inline function. + * gnulib-local/lib/xstrdup.c (xstrdup): Use XNMALLOC instead of + xmalloc. + 2006-11-02 Bruno Haible + * lib/xalloc.h (xnmalloc): New declaration. From gnulib + xalloc.h. + * lib/xmalloc.c (fixup_null_alloc): Write NULL, not 0. + (xnmalloc): New function. + +2007-10-23 Bruno Haible + + Moved module xreadlink to gnulib. + * gnulib-local/modules/xreadlink: Remove file. + * gnulib-local/lib/xreadlink.h: Remove file. + * gnulib-local/lib/xreadlink.c: Remove file. + * gnulib-local/m4/xreadlink.m4: Remove file. + +2007-10-07 Bruno Haible + + Update program license to GPLv3. + * COPYING: Replace with GPL 3. + * windows/iconv.rc (Comments): Update. + +2007-10-07 Bruno Haible + + * gnulib-local/lib/alloca.in.h: Renamed from gnulib-local/lib/alloca_.h. + +2007-03-30 Bruno Haible + + * gnulib-local/lib/alloca_.h: Change prefix of double-inclusion guard + macro to _GL_. + +2006-06-19 Paul Eggert + + * gnulib-local/lib/alloca_.h (alloca) [defined alloca]: Don't define or + declare. + +2007-09-29 Bruno Haible + + * autogen.sh (GNULIB_CVS_ROOT): Change to read-only git mirror + valid since 2007-09-19. + +2007-07-07 Bruno Haible + + * autogen.sh: Add an option --skip-gnulib. + +2007-07-07 Bruno Haible + + * gnulib-local/lib/uniwidth.h: Remove file, moved to gnulib. + * gnulib-local/lib/width.c: Remove file, moved to gnulib. + * gnulib-local/lib/cjk.h: Remove file, moved to gnulib. + * gnulib-local/modules/uniwidth: Remove file. + * Makefile.devel (GNULIB_MODULES): Remove uniwidth, add uniwidth/width. + * src/iconv.c: Include uniwidth/cjk.h instead of cjk.h. + +2007-06-30 Bruno Haible + + * src/iconv.c (print_version): Use the standard --version output, see + . + +2007-06-30 Bruno Haible + + * autogen.sh: New file. + * DEPENDENCIES: New file. + * HACKING: New file. + +2007-06-30 Bruno Haible + + * src/iconv.c: Provide translator comments for many messages. + (conversion_error_EILSEQ, conversion_error_EINVAL, + conversion_error_other): New functions, extracted from convert. + (convert): Use them. + Reported by Tim Van Holder . + +2007-06-09 Bruno Haible + + * gnulib-local/lib/relocwrapper.c: Remove file. + +2007-05-27 Bruno Haible + + * windows/libiconv.rc: New file. + * windows/iconv.rc: New file. + * windows/windres-options: New file. + * configure.ac (WOE32): New variable. + (WINDRES) [WOE32]: New variable. + * lib/Makefile.in (WINDRES): New variable. + (PACKAGE_VERSION): New variable. + (OBJECTS_EXP_yes): Renamed from OBJECTS_yes. + (OBJECTS_EXP_no): Renamed from OBJECTS_no. + (OBJECTS_RES_yes, OBJECTS_RES_no): New variables. + (OBJECTS): Add one of them. + (libiconv.res): New rule. + (clean): Remove also libiconv.res. + * src/Makefile.in (WINDRES): New variable. + (PACKAGE_VERSION): New variable. + (OBJECTS_RES_yes, OBJECTS_RES_no): New variables. + (all, iconv_no_i18n, install): Use them. + (iconv.res): New rule. + (clean): Remove also iconv.res. + Suggested and inspired by work by Perry Rapp. + +2007-05-27 Bruno Haible + + Follow broken iconv() prototype in POSIX. + * configure.ac (ICONV_CONST): Set to empty if the system has no iconv. + * lib/config.h.in (ICONV_CONST): Change default value to an empty + comment. + * src/iconv.c (ICONV_CONST): Change default value to empty. + Reported by Andreas Krennmair . + +2007-05-25 Bruno Haible + + * tools/Makefile (ALL): Add rk1048.h. + (rk1048.h): New rule. + * lib/encodings.def: Add RK1048. + * lib/rk1048.h: New file. + * lib/converters.h: Include it. + * README, man/iconv_open.3: Add RK1048. + * NOTES: Mention RK1048. + * tests/RK1048.TXT: New file. + * tests/Makefile.in (check): Also test RK1048. + Suggested by Timur Birsh . + +2007-04-24 Bruno Haible + + * man/iconv_open.3: Tweak explanation of TRANSLIT. + Reported by Perry Rapp. + +2007-04-23 Bruno Haible + + * tests/check-subst: Use the output of 'printf' only if it didn't + crash. Needed to work around a buffer overflow in Solaris /bin/printf. + Reported by Arto C. Nirkko . + +2007-04-23 Bruno Haible + + * lib/iconv.c (iconv_open, iconv_canonicalize): Treat native Woe32 + systems like those which define __STDC_ISO_10646__. + Reported by Keith Marshall . + +2007-03-31 Bruno Haible + + * man/iconv.1: Use HYPHEN-MINUS signs instead of HYPHENs where + appropriate. + * man/iconv_open.3: Likewise. + * man/iconv.3: Likewise. + * man/iconv_close.3: Likewise. + * man/iconvctl.3: Likewise. + +2007-03-31 Bruno Haible + + * man/iconv.1: Mark as POSIX compliant. + * man/iconv_open.3: Likewise. + * man/iconv.3: Likewise. + * man/iconv_close.3: Likewise. + + * man/*.[13]: Syntactic simplifications. + +2007-03-19 Bruno Haible + + Assume that mkinstalldirs also creates the necessary parent directories. + * Makefile.in (install, installdirs): Don't explicitly create the + parent directories. + * lib/Makefile.in (install, installdirs): Likewise. + * src/Makefile.in (install, installdirs): Likewise. + * man/Makefile.in (install, installdirs): Likewise. + Reported by Thomas Klausner . + +2007-03-04 Bruno Haible + + * Makefile.devel (GNULIB_MODULES): Add relocatable-prog. Remove + relocatable, relocwrapper. + * configure.ac: Invoke gl_RELOCATABLE instead of AC_RELOCATABLE. + * gnulib-local/modules/progreloc: Remove file. + * gnulib-local/modules/relocatable: Remove file. + * gnulib-local/modules/relocwrapper: Remove file. + * gnulib-local/m4/relocatable.m4: Remove file. + * gnulib-local/lib/strerror.c.diff: Remove file. + * src/Makefile.in: Remove SET_RELOCATABLE invocation. Instead get + RELOCATABLE_LDFLAGS and INSTALL_PROGRAM_ENV. + +2007-02-19 Bruno Haible + + * gnulib-local/lib/xmalloc.c: Don't include exit.h. + * src/iconv.c: Likewise. + +2007-02-16 Juan Manuel Guerrero + + * djgpp/*: Update. + +2007-02-03 Bruno Haible + + * tools/Makefile (ksc5601.h): Add one extra character. + * lib/ksc5601.h: Regenerated. + * lib/cp949.h (cp949_mbtowc, cp949_wctomb): Exclude the new character. + * tests/EUC-KR.TXT: Add CIRCLED HANGUL IEUNG U. + * tests/JOHAB.TXT: Likewise. + Reported by Jungshik Shin (ì‹ ì •ì‹, 申政湜) . + + * lib/euc_kr.h: Update comments. + * lib/johab.h: Likewise. + +2007-02-03 Bruno Haible + + * tools/cjk_tab_to_h.c (output_title): Bump copyright year. + +2007-01-26 Bruno Haible + + Moved streq.h to gnulib. + * gnulib-local/lib/streq.h: Remove file. + * gnulib-local/modules/uniwidth (Files): Remove lib/streq.h. + (Depends-on): Add streq. + (lib_SOURCES): Remove streq.h. + +2007-01-26 Bruno Haible + + Moved unitypes.h to gnulib. + * gnulib-local/lib/unitypes.h: Remove file. + * gnulib-local/modules/uniwidth (Files): Remove lib/unitypes.h. + (Depends-on): Add unitypes. + (lib_SOURCES): Remove unitypes.h. + +2007-01-26 Bruno Haible + + Moved canonicalize to gnulib. + * gnulib-local/modules/canonicalize: Remove file. + * gnulib-local/lib/canonicalize.h: Remove file. + * gnulib-local/lib/canonicalize.c: Remove file. + * gnulib-local/m4/canonicalize.m4: Remove file. + * gnulib-local/modules/progreloc (Depends-on): Replace 'canonicalize' + with 'canonicalize-lgpl'. + +2006-12-20 Bruno Haible + + * lib/Makefile.in (install): On AIX, add the contents of + /lib/libiconv.a to libiconv.a. + +2006-12-20 Bruno Haible + + * Makefile.devel (all): Depend on srclib/Makefile.gnulib, not + srclib/Makefile.am. + (aclocal.m4): Likewise. Touch the resulting file, since aclocal not + always does it. + (srclib/Makefile.gnulib): Renamed from srclib/Makefile.am. Pass + option --makefile-name. + (srclib/Makefile.in): Depend on srclib/Makefile.gnulib too. + * srclib/Makefile.am: New file that includes srclib/Makefile.gnulib. + +2006-10-31 Bruno Haible + + Update from GNU gettext. + 2006-10-29 Bruno Haible + Make it compile in C++ mode. + * gnulib-local/lib/xalloc.h (xrealloc): Define as template + with appropriate return type. + * gnulib-local/lib/xstrdup.c (xstrdup): Cast xmalloc result. + 2006-10-26 Bruno Haible + * gnulib-local/modules/canonicalize (Makefile.am): Remove + EXTRA_DIST. Now done by gnulib-tool. + * gnulib-local/modules/relocatable (Makefile.am): Likewise. + * gnulib-local/modules/relocwrapper (Makefile.am): Likewise. + 2006-10-25 Bruno Haible + * gnulib-local/m4/relocatable.m4 (AC_RELOCATABLE_BODY): + Renamed from AC_RELOCATABLE, without the AC_LIBOBJ invocation. + (AC_RELOCATABLE): New macro. Invoke AC_LIBOBJ here. + * gnulib-local/modules/relocwrapper (configure.ac): Invoke + AC_RELOCATABLE instead of requiring it. + 2006-10-12 Bruno Haible + * gnulib-local/modules/canonicalize (Makefile.am): Distribute + all files in lib/ through EXTRA_DIST. + * gnulib-local/modules/relocatable (Makefile.am): Likewise. + 2006-09-14 Bruno Haible + * gnulib-local/lib/canonicalize.c: Include + unconditionally. + * gnulib-local/lib/relocatable.c: Likewise. + * lib/relocatable.c: Likewise. + * gnulib-local/lib/relocwrapper.c: Likewise. + * gnulib-local/lib/xmalloc.c: Likewise. + * gnulib-local/lib/xreadlink.c: Likewise. + * gnulib-local/lib/xstrdup.c: Likewise. + 2006-08-02 Bruno Haible + * gnulib-local/modules/canonicalize: Put under LGPL. + * gnulib-local/modules/relocatable: Likewise. + 2006-07-18 Bruno Haible + * gnulib-local/xalloc.h (xzalloc): New declaration. + * gnulib-local/xmalloc.c (xzalloc): New function. + +2006-10-24 Bruno Haible + + * man/Makefile.in (PACKAGE): New variable. Needed for docdir. + Reported by Charles Wilson . + +2006-10-14 Bruno Haible + + * COPYING: New file. + * README: Clarify copyright of the iconv program. + Reported by Charles Wilson . + +2006-08-08 Bruno Haible + + * INSTALL.generic: Add a recommendation for Tru64. + Reported by Gary V. Vaughan . + +2006-07-29 Bruno Haible + + * tests/check-subst: Set CHARSETALIASDIR. + Needed so that "make check" works before "make install" on systems + such as NetBSD. + +2006-07-29 Bruno Haible + + * Makefile.devel (aclocal.m4): Depend on srclib/Makefile.am. + (AUTOCONF_FILES): Add the existing *.m4 files. + +2006-07-29 Bruno Haible + + * gnulib-local/lib/xreadlink.c: Assume exists. + * src/iconv.c: Assume exists. + * configure.ac: Remove tests for , , , + . + +2006-07-29 Bruno Haible + + * configure.ac: Remove obsolete calls AC_PROG_GCC_TRADITIONAL, + AC_ISC_POSIX, AC_HEADER_STDC. + +2006-07-29 Bruno Haible + + * configure.ac: Remove macro invocations that are redundant through + gl_EARLY and gl_INIT. + +2006-07-29 Bruno Haible + + * gnulib-local/m4/alloca.m4 (gl_PREREQ_ALLOCA): Add a dummy statement. + Avoids a sh syntax error. + +2006-07-29 Bruno Haible + + * gnulib-local/m4/relocatable.m4: Add comments. + +2006-07-29 Bruno Haible + + * gnulib-local/modules/libiconv-misc: New file. + * Makefile.devel (GNULIB_MODULES): Add libiconv-misc. + + * Makefile.devel (srclib/Makefile.am): Pass --no-libtool. + +2006-07-29 Bruno Haible + + Note: gnulib macros no longer invoke AC_TYPE_SIZE_T nor + AC_CHECK_TYPE([ptrdiff_t], , [AC_DEFINE([ptrdiff_t], [long], ...)]) + because we now assume that the system defines size_t and ptrdiff_t. + +2006-07-29 Bruno Haible + + Switch to using gnulib. + * configure.ac (AC_PREREQ): Require autoconf-2.60. + Invoke gl_EARLY and gl_INIT. + * Makefile.devel (all): Depend on srclib/Makefile.am. + (aclocal.m4): Pass -I srcm4 to aclocal. Simplify dependencies, assuming + GNU make. + (GNULIB_MODULES): New variable. + (srclib/Makefile.am): New rule. + * gnulib-local: New directory. + * gnulib-local/m4/alloca.m4: Moved here from m4/alloca.m4. + * gnulib-local/m4/canonicalize.m4: Moved here from m4/canonicalize.m4. + * gnulib-local/m4/relocatable.m4: Moved here from m4/relocatable.m4. + * gnulib-local/m4/xreadlink.m4: Moved here from m4/xreadlink.m4. + * gnulib-local/lib/alloca_.h: Moved here from srclib/alloca_.h. + * gnulib-local/lib/canonicalize.h: Moved here from srclib/canonicalize.h. + * gnulib-local/lib/canonicalize.c: Moved here from srclib/canonicalize.c. + * gnulib-local/lib/cjk.h: Moved here from srclib/cjk.h. + * gnulib-local/lib/error.h.diff: New file. + * gnulib-local/lib/progname.h.diff: New file. + * gnulib-local/lib/relocatable.h: Moved here from srclib/relocatable.h. + * gnulib-local/lib/relocatable.c: Moved here from srclib/relocatable.c. + * gnulib-local/lib/relocwrapper.c: Moved here from srclib/relocwrapper.c. + * gnulib-local/lib/streq.h: Moved here from srclib/streq.h. + * gnulib-local/lib/strerror.c.diff: New file. + * gnulib-local/lib/unitypes.h: Moved here from srclib/unitypes.h. + * gnulib-local/lib/uniwidth.h: Moved here from srclib/uniwidth.h. + * gnulib-local/lib/width.c: Moved here from srclib/width.c. + * gnulib-local/lib/xalloc.h: Moved here from srclib/xalloc.h. + * gnulib-local/lib/xmalloc.c: Moved here from srclib/xmalloc.c. + * gnulib-local/lib/xstrdup.c: Moved here from srclib/xstrdup.c. + * gnulib-local/lib/xreadlink.h: Moved here from srclib/xreadlink.h. + * gnulib-local/lib/xreadlink.c: Moved here from srclib/xreadlink.c. + * gnulib-local/modules/canonicalize: New file. + * gnulib-local/modules/progreloc: New file. + * gnulib-local/modules/relocatable: New file. + * gnulib-local/modules/relocwrapper: New file. + * gnulib-local/modules/uniwidth: New file. + * gnulib-local/modules/xalloc: New file. + * gnulib-local/modules/xreadlink: New file. + + * m4/allocsa.m4: Remove file. Now taken from gnulib. + * m4/codeset.m4: Likewise. + * m4/eealloc.m4: Likewise. + * m4/error.m4: Likewise. + * m4/extensions.m4: Likewise. + * m4/full-header-path.m4: Likewise. + * m4/gettext.m4: Likewise. + * m4/glibc21.m4: Likewise. + * m4/iconv.m4: Likewise. + * m4/intmax.m4: Likewise. + * m4/inttypes-h.m4: Likewise. + * m4/inttypes_h.m4: Likewise. + * m4/isc-posix.m4: Likewise. + * m4/lcmessage.m4: Likewise. + * m4/lib-ld.m4: Likewise. + * m4/lib-link.m4: Likewise. + * m4/lib-prefix.m4: Likewise. + * m4/longdouble.m4: Likewise. + * m4/longlong.m4: Likewise. + * m4/mbstate_t.m4: Likewise. + * m4/nls.m4: Likewise. + * m4/onceonly.m4: Likewise. + * m4/pathmax.m4: Likewise. + * m4/po.m4: Likewise. + * m4/printf-posix.m4: Likewise. + * m4/progtest.m4: Likewise. + * m4/readlink.m4: Likewise. + * m4/setenv.m4: Likewise. + * m4/signed.m4: Likewise. + * m4/size_max.m4: Likewise. + * m4/ssize_t.m4: Likewise. + * m4/stdbool.m4: Likewise. + * m4/stdint.m4: Likewise. + * m4/stdint_h.m4: Likewise. + * m4/strerror.m4: Likewise. + * m4/strerror_r.m4: Likewise. + * m4/unistd_h.m4: Likewise. + * m4/unlocked-io.m4: Likewise. + * m4/visibility.m4: Likewise. + * m4/wchar_t.m4: Likewise. + * m4/wint_t.m4: Likewise. + + * srclib/allocsa.h: Remove file. Now taken from gnulib. + * srclib/allocsa.c: Likewise. + * srclib/binary-io.h: Likewise. + * srclib/error.h: Likewise. + * srclib/error.c: Likewise. + * srclib/exit.h: Likewise. + * srclib/gettext.h: Likewise. + * srclib/memmove.c: Likewise. + * srclib/pathmax.h: Likewise. + * srclib/progname.h: Likewise. + * srclib/progname.c: Likewise. + * srclib/progreloc.c: Likewise. + * srclib/readlink.c: Likewise. + * srclib/setenv.h: Likewise. + * srclib/setenv.c: Likewise. + * srclib/stdbool_.h: Likewise. + * srclib/stdint_.h: Likewise. + * srclib/strerror.c: Likewise. + * srclib/unlocked-io.h: Likewise. + * srclib/unsetenv.c: Likewise. + * srclib/Makefile.am: Remove file. + +2006-07-27 Bruno Haible + + Remove OS/2 build support that doesn't assume GNU make and GNU bash. + * README.os2: Remove file. + * Makefile.os2: Remove file. + * lib/Makefile.os2: Remove file. + * src/Makefile.os2: Remove file. + * man/Makefile.os2: Remove file. + * tests/Makefile.os2: Remove file. + * tests/check-stateful.cmd: Remove file. + * tests/check-stateless.cmd: Remove file. + * tests/check-translit.cmd: Remove file. + +2006-07-25 Bruno Haible + + Remove MSVC/nmake build support. + * windows: Remove directory. + * Makefile.msvc: Remove file. + * lib/Makefile.msvc: Remove file. + * srclib/Makefile.msvc: Remove file. + * src/Makefile.msvc: Remove file. + * tests/Makefile.msvc: Remove file. + * man/Makefile.msvc: Remove file. + * po/Rules-msvc: Remove file. + * po/Makefile.msvc.sh: Remove file. + * Makefile.devel (config.h.msvc, lib/config.h.msvc): Remove rules. + (include/iconv.h.msvc-static, include/iconv.h.msvc-shared): Remove + rules. + (po/Makefile.msvc): Remove rule. + (all): Update. + +2006-07-25 Bruno Haible + + Remove VMS support. + * vms: Remove directory. + * Makefile.vms: Remove file. + * lib/Makefile.vms: Remove file. + * srclib/Makefile.vms: Remove file. + * src/Makefile.vms: Remove file. + * tests/Makefile.vms: Remove file. + * man/Makefile.vms: Remove file. + * Makefile.devel (config.h_vms, lib/config.h_vms): Remove rules. + (include/iconv.h_vms): Remove rule. + (all): Update. + +2006-07-23 Bruno Haible + + * lib/Makefile.in (libiconv.la): Use the CFLAGS during linking. + * src/Makefile.in (iconv_no_i18n): Likewise. + (install): Likewise. + * tests/Makefile.in (table-from, table-to): Likewise. + Needed because the CFLAGS can e.g. trigger profiling. + Reported by Russell Aspinwall . + +2006-07-19 Bruno Haible + + * Version 1.11 released. + +2006-07-19 Bruno Haible + + * srclib/Makefile.am (libicrt_a_SOURCES): Remove error.h, error.c. + (LIBADD_SOURCE): Add them here. + +2006-07-19 Bruno Haible + + * build-aux/config.guess: Update to GNU version 2006-07-02. + * build-aux/config.sub: Likewise. + +2006-07-14 Bruno Haible + + * lib/Makefile.in (clean): Remove also *.stackdump. + * src/Makefile.in (clean): Likewise. + * tests/Makefile.in (clean): Likewise. + +2006-07-14 Bruno Haible + + * src/Makefile.in (clean): Remove also iconv_no_i18n. Needed for + cygwin or mingw. + * tests/Makefile.in (clean): Remove also the programs, without + EXEEXT. Needed for cygwin or mingw. + * Makefile.in (mostlyclean, clean, distclean, maintainer-clean): + Remove also bin directory. Needed for cygwin and mingw. + +2006-07-03 Bruno Haible + + * src/iconv.c (check_subst_formatstring): Use ngettext. + (subst_wc_to_mb_fallback, subst_mb_to_mb_fallback): Fix error messages + after 2006-01-22 change. + * configure.ac: Require a gettext version with ngettext. + +2006-06-28 Bruno Haible + + * m4/gettext.m4: Update from GNU gettext. + * m4/po.m4: Update from GNU gettext. + +2006-06-27 Bruno Haible + + * Makefile.devel (AUTOCONF, AUTOHEADER): Use autoconf-2.60. + * Makefile.in (datarootdir): New variable. + (install, installdirs, uninstall): Also pass datarootdir. + * configure.ac (mandir): Remove customization. + * man/Makefile.in (datarootdir): New variable. + (docdir, htmldir): Use autoconf-substituted value. + * src/Makefile.in (datarootdir): New variable. + (localedir): Use autoconf-substituted value. + +2006-06-27 Bruno Haible + + * m4/stdint.m4: Update from gnulib. + * srclib/stdint_.h: Update from gnulib. + * srclib/Makefile.am: Update. + +2006-06-17 Bruno Haible + + * srclib/unsetenv.c: Update from GNU gettext. + * srclib/xreadlink.c: Likewise. + +2006-06-16 Bruno Haible + + * m4/full-header-path.m4: New file, from gnulib. + * m4/size_max.m4: New file, from gnulib. + * m4/stdint.m4: Update from gnulib. + * srclib/stdint_.h: Update from gnulib. + * srclib/Makefile.am (stdint.h): Likewise. + * Makefile.devel (aclocal.m4): Update dependencies. + +2006-06-16 Bruno Haible + + * m4/ssize_t.m4: Update from GNU gettext. + +2006-06-12 Bruno Haible + + * m4/gettext.m4: Update from GNU gettext. + * m4/inttypes-h.m4: New file, from GNU gettext. + * m4/inttypes.m4: Remove file. + * m4/stdint.m4 (gl_STDINT_H): Update. + * Makefile.devel (aclocal.m4): Update dependencies. + +2006-06-10 Bruno Haible + + * src/iconv.c (error) [NO_I18N]: Define here instead of including + error.h. Fixes link failure introduced on 2006-01-22. + +2006-03-28 Ralf Wildenhues + + * m4/libtool.m4 (_LT_SYS_DYNAMIC_LINKER) [ linux ]: Avoid warning when + "parsing" /etc/ld.so.conf and empty /etc/ld.so.conf.d. + +2006-05-20 Bruno Haible + + * tests/BIG5-HKSCS-1999-snippet: New file. + * tests/BIG5-HKSCS-1999-snippet.UTF-8: New file. + * tests/BIG5-HKSCS-2001-snippet: New file. + * tests/BIG5-HKSCS-2001-snippet.UTF-8: New file. + * tests/BIG5-HKSCS-2004-snippet: New file. + * tests/BIG5-HKSCS-2004-snippet.UTF-8: New file. + * tests/Makefile.in (check): Test also the stateful parts of + BIG5-HKSCS:1999, BIG5-HKSCS:2001, BIG5-HKSCS:2004. + +2006-05-17 Bruno Haible + + Implement newer releases of BIG5-HKSCS. + * tools/Makefile (ALL): Remove hkscs.h, add hkscs1999.h, hkscs2001.h, + hkscs2004.h. + (hkscs.h): Remove rule. + (hkscs1999.h, hkscs2001.h, hkscs2004.h): New rules. + * tools/cjk_tab_to_h.c (output_title): Update year. + (main): Recognize hkscs1999, hkscs2001, hkscs2004. + * lib/encodings.def: Rename BIG5-HKSCS to BIG5-HKSCS:1999. Add + BIG5-HKSCS:2001, BIG5-HKSCS:2004. Make all three stateful. + * lib/hkscs.h: Remove file. + * lib/hkscs1999.h: New file. + * lib/hkscs2001.h: New file. + * lib/hkscs2004.h: New file. + * lib/big5hkscs.h: Remove file. + * lib/big5hkscs1999.h: New file. + * lib/big5hkscs2001.h: New file. + * lib/big5hkscs2004.h: New file. + * lib/converters.h: Include the new files. + * README, man/iconv_open.3: Add BIG5-HKSCS:1999, BIG5-HKSCS:2001. + * tests/BIG5-HKSCS.TXT: Remove file. + * tests/BIG5-HKSCS.IRREVERSIBLE.TXT: Remove file. + * tests/BIG5-HKSCS-1999.TXT: New file. + * tests/BIG5-HKSCS-1999.IRREVERSIBLE.TXT: New file. + * tests/BIG5-HKSCS-2001.TXT: New file. + * tests/BIG5-HKSCS-2001.IRREVERSIBLE.TXT: New file. + * tests/BIG5-HKSCS-2004.TXT: New file. + * tests/BIG5-HKSCS-2004.IRREVERSIBLE.TXT: New file. + * tests/check-stateless: Convert colon in the charset name to a dash in + the file name. + * tests/Makefile.in (check): Check BIG5-HKSCS:1999, BIG5-HKSCS:2001, + BIG5-HKSCS:2004 instead of just BIG5-HKSCS. + * tests/Makefile.msvc (check): Don't check BIG5-HKSCS. + * tests/Makefile.os2 (check): Likewise. + +2006-05-17 Bruno Haible + + * srclib/progreloc.c: Update from GNU gettext. + +2006-05-16 Bruno Haible + + * src/Makefile.in (clean): Use EXEEXT. + * tests/Makefile.in (check, clean): Likewise. + +2006-05-15 Bruno Haible + + * configure.ac: Move some checks before AC_RELOCATABLE. + +2006-05-15 Bruno Haible + + Support for building shared libraries on mingw and Cygwin. + * configure.ac (WOE32DLL, DLL_VARIABLE): New variables. + * include/iconv.h.in (_libiconv_version): Mark as DLL_VARIABLE. + * woe32dll/export.h: New file, from GNU gettext. + * woe32dll/iconv-exports.h: New file. + * Makefile.devel (include/iconv.h_vms, include/iconv.h.msvc-static, + include/iconv.h.msvc-shared): Remove the DLL_VARIABLE annotation. + * lib/Makefile.in (INCLUDES): Add -I for parent directory. + (LDFLAGS): Add WOE32DLL dependent flags. + (LDFLAGS_yes, LDFLAGS_no): New variables. + (OBJECTS): Add WOE32DLL dependent objects. + (OBJECTS_yes, OBJECTS_no): New variables. + (iconv-exports.lo): New rule. + +2006-05-15 Bruno Haible + + * srclib/gettext.h: Update from GNU gettext. + * srclib/pathmax.h: Update from GNU gettext. + * srclib/progreloc.c: Update from GNU gettext. + * srclib/unsetenv.c: Update from GNU gettext. + * srclib/Makefile.am: Add snippet for creation of unistd.h. + * m4/extensions.m4: Update from GNU gettext. + * m4/gettext.m4: Update from GNU gettext. + * m4/lib-ld.m4: Update from GNU gettext. + * m4/lib-link.m4: Update from GNU gettext. + * m4/lib-prefix.m4: Update from GNU gettext. + * m4/longdouble.m4: Update from GNU gettext. + * m4/nls.m4: Update from GNU gettext. + * m4/onceonly.m4: Update from GNU gettext. + * m4/po.m4: Update from GNU gettext. + * m4/relocatable.m4: Update from GNU gettext. + * m4/unistd_h.m4: New file, from GNU gettext. + * Makefile.devel (aclocal.m4): Depend on it. + * configure.ac: Invoke gl_HEADER_UNISTD. + +2006-05-14 Bruno Haible , + Ralf Wildenhues + + * m4/libtool.m4 [ linux ] (AC_LIBTOOL_LANG_CXX_CONFIG) + (AC_LIBTOOL_POSTDEP_PREDEP, AC_LIBTOOL_PROG_COMPILER_PIC) + (AC_LIBTOOL_PROG_LD_SHLIBS): Add support for Sun C 5.9, + Sun C++ 5.9, and Sun Fortran 8.3 on Linux. + +2006-05-06 Charles Wilson + + * m4/libtool.m4: On Cygwin, like on mingw, define DLL_EXPORT when + compiling a shared library object. + +2006-05-15 Bruno Haible + + * build-aux/config.rpath: Add support for Sun C 5.9 on Linux. + +2006-03-31 Juan Manuel Guerrero + + * djgpp/*: Update. + +2006-01-23 Bruno Haible + + * configure.ac: Invoke gl_ALLOCSA. + + * Makefile.devel (aclocal.m4): Depend on $(CONFIGURES_IN). + +2006-01-22 Bruno Haible + + * src/iconv.c (xmalloc, xalloc_die) [NO_I18N]: Define to avoid using + gettext(). + +2006-01-22 Bruno Haible + + * lib/Makefile.in (LIBICONV_VERSION_INFO): Bump to 6:0:4. + +2006-01-22 Bruno Haible + + * src/iconv.c: Include error.h, exit.h. + (print_version): Use EXIT_SUCCESS. + (check_subst_formatstring, subst_mb_to_uc_fallback, + subst_uc_to_mb_fallback, subst_mb_to_wc_fallback, + subst_wc_to_mb_fallback, subst_mb_to_mb_fallback, convert, main): Use + error() instead of fprintf to stderr. + +2006-01-22 Bruno Haible + + New feature: character-dependent substitutions. + * include/iconv.h.in (iconv_unicode_mb_to_uc_fallback, + iconv_unicode_uc_to_mb_fallback, iconv_wchar_mb_to_wc_fallback, + iconv_wchar_wc_to_mb_fallback): New types. + (struct iconv_fallbacks): New structure type. + (ICONV_SET_FALLBACKS): New macro. + * configure.ac: Invoke gt_TYPE_WCHAR_T and substitute HAVE_WCHAR_T. + * Makefile.os2 (all): Also substitute @HAVE_WCHAR_T@ in build/iconv.h. + * Makefile.devel (include/iconv.h_vms, include/iconv.h.msvc-static, + include/iconv.h.msvc-shared): Also substitute @HAVE_WCHAR_T@. + * lib/converters.h (struct conv_struct): Add field 'fallbacks'. + * lib/loop_unicode.h (struct uc_to_mb_fallback_locals): New type. + (uc_to_mb_write_replacement): New function. + (struct mb_to_uc_fallback_locals): New type. + (mb_to_uc_write_replacement): New function. + (unicode_loop_convert): Call mb_to_uc_fallback and uc_to_mb_fallback. + (unicode_loop_reset): Call uc_to_mb_fallback. + * lib/loop_wchar.h (struct wc_to_mb_fallback_locals): New type. + (wc_to_mb_write_replacement): New function. + (wchar_from_loop_convert): Call wc_to_mb_fallback. + (struct mb_to_wc_fallback_locals): New type. + (mb_to_wc_write_replacement): New function. + (wchar_to_loop_convert): Call mb_to_wc_fallback. + * lib/iconv.c (iconv_open): Initialize the 'fallbacks' field. + (iconvctl): Handle ICONV_SET_FALLBACKS. + * lib/genflags.c (struct iconv_fallbacks): New dummy definition. + * src/iconv.c: Include limits.h. + (isdigit, c_isprint): New macros. + (usage): Document long options and new options. + (check_subst_formatstring): New function. + (ilseq_byte_subst, ilseq_wchar_subst, ilseq_unicode_subst): New + variables. + (ilseq_byte_subst_size, ilseq_wchar_subst_size, + ilseq_unicode_subst_size): New variables. + (ilseq_byte_subst_buffer, ilseq_wchar_subst_buffer, + ilseq_unicode_subst_buffer): New variables. + (subst_mb_to_uc_cd, subst_mb_to_uc_temp_buffer): New variables. + (subst_mb_to_uc_fallback): New function. + (subst_uc_to_mb_cd, subst_uc_to_mb_temp_buffer): New variables. + (subst_uc_to_mb_fallback): New function. + (subst_mb_to_wc_cd, subst_mb_to_wc_temp_buffer): New variables. + (subst_mb_to_wc_fallback): New function. + (subst_wc_to_mb_cd, subst_wc_to_mb_temp_buffer): New variables. + (subst_wc_to_mb_fallback): New function. + (subst_mb_to_mb_cd, subst_mb_to_mb_temp_buffer): New variables. + (subst_mb_to_mb_fallback): New function. + (convert): Enlarge the outbuf when the conversion failed with E2BIG. + (main): Handle new options --byte-subst, --widechar-subst, + --unicode-subst. + * man/iconv.1: Document --unicode-subst, --byte-subst, --widechar-subst + options. + * tests/check-subst: New file. + * tests/Makefile.in (check): Also invoke check-subst. + Suggested by James Taylor . + +2006-01-21 Bruno Haible + + * src/iconv.c (print_version): Bump copyright year. + (main): Accept long options --from-code, --to-code, --list, --silent. + Accept abbreviated long options, like getopt() does. + * man/iconv.1: Document long options. + +2005-12-29 Bruno Haible + + * src/iconv.c (print_version): Update copyright year. + +2005-12-29 Bruno Haible + + * configure.ac: Renamed from configure.in. + * Makefile.devel (CONFIGURES_IN, configure, config.h.in): Update. + +2005-12-29 Bruno Haible + + * configure.in: Bump version number. + * include/iconv.h.in (_LIBICONV_VERSION): Likewise. + * windows/iconv.rc: Likewise. + * lib/Makefile.in (LIBICONV_VERSION_INFO): Bump to 5:1:3. + +2005-12-29 Bruno Haible + + * build-aux/config.guess: Update to GNU version 2005-12-23. + * build-aux/config.sub: Likewise. + * build-aux/config.libpath: Update from GNU gettext. + * build-aux/install-sh: Upgrade to automake-1.9.5. + * build-aux/missing: Upgrade to automake-1.9.5. + * build-aux/mkinstalldirs: Upgrade to automake-1.9.5. + +2005-12-29 Bruno Haible + + * m4/alloca.m4: Update from GNU gettext. + * m4/allocsa.m4: Update from GNU gettext. + * m4/canonicalize.m4: Update from GNU gettext. + * m4/codeset.m4: Update from GNU gettext. + * m4/eealloc.m4: Update from GNU gettext. + * m4/error.m4: Update from GNU gettext. + * m4/extensions.m4: Update from GNU gettext. + * m4/gettext.m4: Update from GNU gettext. + * m4/glibc21.m4: Update from GNU gettext. + * m4/iconv.m4: Update from GNU gettext. + * m4/intmax.m4: Update from GNU gettext. + * m4/inttypes_h.m4: New file, from GNU gettext. + * m4/isc-posix.m4: Update from GNU gettext. + * m4/lcmessage.m4: Update from GNU gettext. + * m4/longdouble.m4: Update from GNU gettext. + * m4/longlong.m4: Update from GNU gettext. + * m4/mbstate_t.m4: Update from GNU gettext. + * m4/nls.m4: Update from GNU gettext. + * m4/onceonly.m4: Update from GNU gettext. + * m4/pathmax.m4: Update from GNU gettext. + * m4/po.m4: Update from GNU gettext. + * m4/printf-posix.m4: Update from GNU gettext. + * m4/progtest.m4: Update from GNU gettext. + * m4/readlink.m4: Update from GNU gettext. + * m4/relocatable.m4: Update from GNU gettext. + * m4/setenv.m4: Update from GNU gettext. + * m4/signed.m4: Update from GNU gettext. + * m4/ssize_t.m4: Update from GNU gettext. + * m4/stdbool.m4: Update from GNU gettext. + * m4/stdint_h.m4: New file, from GNU gettext. + * m4/strerror.m4: Update from GNU gettext. + * m4/strerror_r.m4: Update from GNU gettext. + * m4/unlocked-io.m4: Update from GNU gettext. + * m4/wchar_t.m4: Update from GNU gettext. + * m4/wint_t.m4: Update from GNU gettext. + * m4/xreadlink.m4: Update from GNU gettext. + * Makefile.devel (aclocal.m4): Depend on m4/inttypes_h.m4 and + m4/stdint_h.m4 as well. + * configure.in: Invoke AC_TYPE_MBSTATE_T instead of AC_MBSTATE_T. + Invoke gl_FUNC_GLIBC_UNLOCKED_IO instead of jm_FUNC_GLIBC_UNLOCKED_IO. + Invoke gl_ERROR instead of gt_FUNC_ERROR_AT_LINE. + Don't invoke AC_AIX and AC_MINIX, done by gl_USE_SYSTEM_EXTENSIONS. + Temporarily redefine AC_LIBOBJ and AC_REPLACE_FUNCS, so as to fill + SRCLIBOBJS instead of LIBOBJS. + * srclib/alloca_.h: Update from GNU gettext. + * srclib/allocsa.h: Update from GNU gettext. + * srclib/canonicalize.c: Update from GNU gettext. + * srclib/error.h: Update from GNU gettext. + * srclib/error.c: Update from GNU gettext. + * srclib/gettext.h: Update from GNU gettext. + * srclib/memmove.c: Update from GNU gettext. + * srclib/progname.h: Update from GNU gettext. + * srclib/progname.c: Update from GNU gettext. + * srclib/progreloc.c: Update from GNU gettext. + * srclib/readlink.c: Update from GNU gettext. + * srclib/relocatable.c: Update from GNU gettext. + * srclib/relocwrapper.c: Update from GNU gettext. + * srclib/setenv.h: Update from GNU gettext. + * srclib/setenv.c: Update from GNU gettext. + * srclib/stdbool_.h: Update from GNU gettext. + * srclib/stdint_.h: Update from gnulib. + * srclib/strerror.c: Update from GNU gettext. + * srclib/unlocked-io.h: Update from GNU gettext. + * srclib/unsetenv.c: Update from GNU gettext. + * srclib/xalloc.h: Update from GNU gettext. + * srclib/xmalloc.c: Update from GNU gettext. + * srclib/xreadlink.c: Update from GNU gettext. + * srclib/xstrdup.c: Update from GNU gettext. + * srclib/Makefile.am (DEFS): Also define EXEEXT. + (libicrt_a_LIBADD): Use SRCLIBOBJS instead of LIBOBJS. + (libicrt_a_DEPENDENCIES): New variable. + * src/Makefile.in (EXEEXT): New variable. + * build-aux/install-reloc: Update from GNU gettext. + * build-aux/reloc-ldflags: Update from GNU gettext. + * build-aux/config.rpath: Update from GNU gettext. + +2005-12-29 Bruno Haible + + * m4/libtool.m4: Update, based on libtool-1.5.22. + * build-aux/ltmain.sh: Update, based on libtool-1.5.22. + +2005-12-24 Bruno Haible + + Check the whole range of GB18030. + * tests/GB18030-BMP.TXT: Renamed from tests/GB18030.TXT. + * tests/gengb18030z.c: New file. + * tests/table-from.c (main): For GB18030, don't stop at U+10000. + * tests/table-to.c (main): Likewise. + * tests/Makefile.in (check): Generate GB18030.TXT on the fly from + GB18030-BMP.TXT. + (clean): Remove also gengb18030z and GB18030.TXT. + * tests/Makefile.msvc (check): Generate GB18030.TXT on the fly from + GB18030-BMP.TXT. + (clean): Remove also GB18030Z.TXT, GB18030TMP.TXT, GB18030.TXT. + * tests/Makefile.os2 (check): Depend on gengb18030z.exe. Generate + GB18030.TXT on the fly from GB18030-BMP.TXT. + (clean): Remove also GB18030Z.TXT, GB18030TMP.TXT, GB18030.TXT. + +2005-12-20 Bruno Haible + + * tests/table-to.c (main): Test the mappings up to U+10FFFF, not only + up to U+2FFFF. Tolerate that Unicode language tags are silently mapped + to nothing. + +2005-12-22 Bruno Haible + + Extend GB18030 converter to cover the entire Unicode PUA. + * lib/gb18030.h: Update comments, based on second printing. + (gb18030_mbtowc): Add mapping for range U+E000..U+E765. + (gb18030_pua2charset): New array. + (gb18030_wctomb): Add mapping for range U+E000..U+E765 and the two-byte + part of range U+E766..U+E864. + * lib/gb18030ext.h (gb18030ext_2uni_pagefe): Add mappings to private + area. + (gb18030ext_mbtowc): Add mapping for the two-byte part of range + U+E766..U+E864. + * lib/gb18030uni.h (gb18030uni_charset2uni_ranges, + gb18030uni_uni2charset_ranges, gb18030uni_ranges): Add 12 more + intervals. + (gb18030uni_mbtowc, gb18030uni_wctomb): Update. + * tests/GB18030.TXT: Complete mappings to private area. + +2005-12-22 Bruno Haible + + * lib/gbk.h: Update comments. + +2005-12-20 Bruno Haible + + Add private area mappings to CP949. + * lib/cp949.h (cp949_mbtowc, cp949_wctomb): Map U+E000..U+E0BB like + many others do it. + * tests/CP949.TXT: Add mappings for U+E000..U+E0BB. + +2005-12-15 Bruno Haible + + Add private area mappings to CP950. + * lib/cp950.h (cp950_mbtowc, cp950_wctomb): Map U+E000..U+F6B0 like + most others do it. + * tests/CP950.TXT: Add mappings for U+E000..U+F6B0. + +2005-12-15 Bruno Haible + + Make CP936 follow what Microsoft does. + In http://www.microsoft.com/globaldev/reference/dbcs/936.mspx they + added a 0x80 - U+20AC mapping to the code chart, but not to the + tooltips and not to the list of mappings. + * lib/cp936.h: New file. + * lib/gbk.h: Update comments. + * lib/ces_gbk.h: Update comments. + * lib/converters.h: Include cp936.h. + * lib/encodings.def (CP936): New encoding. + (GBK): Remove CP936 aliases. + * README, man/iconv_open.3: Add CP936. + * tests/Makefile.in (check): Check CP936. + * tests/Makefile.msvc (check): Likewise. + * tests/Makefile.os2 (check): Likewise. + * tests/CP936.TXT: New file. + +2005-12-14 Bruno Haible + + * lib/cp932.h (cp932_wctomb): Map U+FF5E, U+2225, U+FF0D, U+FFE0, + U+FFE1 like Microsoft does it. + * lib/CP932.IRREVERSIBLE.TXT: Add these mappings. + Reported by Lei Wang . + +2005-12-14 Bruno Haible + + Follow Euro sign addition done in 1999 in + http://www.microsoft.com/globaldev/reference/dbcs/950/950_A3.mspx + * lib/cp950.h (cp950_mbtowc, cp950_wctomb): Add mapping for 0xA3E1. + * tests/CP950.TXT: Add mapping for 0xA3E1. + +2005-11-11 Bruno Haible + + * lib/euc_jp.h (euc_jp_wctomb): When writing a 3-bytes byte sequence + and only two bytes are available in the output buffer, return + RET_TOOSMALL instead of overrunning the output buffer. + * lib/isoir165.h (isoir165_wctomb): When only one byte is available + in the output buffer, don't overrun the output buffer. + Reported by William Bardwell . + +2005-09-18 Bruno Haible + + * m4/libtool.m4: Update, based on libtool-1.5.20. + * build-aux/ltmain.sh: Update, based on libtool-1.5.20. + +2005-08-12 Bruno Haible + + * lib/big5_2003.h: Map 0xF9FA..0xF9FD differently. + * tests/BIG5-2003.TXT: Likewise. + * tests/BIG5-2003.IRREVERSIBLE.TXT: New file. + Reported by Ping Yeh . + +2005-07-24 Bruno Haible + + Tidy up exported symbols. + * m4/visibility.m4: New file. + * include/export.h: New file. + * configure.in: Invoke gl_VISIBILITY. Use AC_CONFIG_FILES. Arrange to + create also include/iconv.h.inst. + * Makefile.devel (all): Depend on include/iconv.h.build.in. + (aclocal.m4): Depend on m4/visibility.m4. + (include/iconv.h.build.in): New rule. + * Makefile.in (install-lib, install): Install include/iconv.h.inst, + not the include/iconv.h that was used for building. + (distclean, maintainer-clean): Remove also include/iconv.h.inst. + * lib/Makefile.in (CFLAGS): Add @CFLAG_VISIBILITY@. + (DEFS): Also define BUILDING_LIBICONV and BUILDING_DLL. + * lib/config.h.in (HAVE_VISIBILITY): New macro. + * lib/relocatable.h (RELOCATABLE_DLL_EXPORTED) [HAVE_VISIBILITY]: + Define to the gcc visibility attribute. + * srclib/relocatable.h (RELOCATABLE_DLL_EXPORTED) [HAVE_VISIBILITY]: + Likewise. + +2005-07-25 Bruno Haible + + 2003-08-24 Bruno Haible + * lib/relocatable.h: Make this file includable in C++ mode: add extern + "C". + +2005-07-08 Bruno Haible + + * Version 1.10 released. + +2005-07-08 Bruno Haible + + * m4/libtool.m4 (postinstall_cmds) [cygwin,mingw,pw32]: Make DLL + executable after installing it. + +2005-07-08 Bruno Haible + + * configure.in: Bump version number. + * include/iconv.h.in (_LIBICONV_VERSION): Likewise. + * windows/iconv.rc: Likewise. + * lib/Makefile.in (LIBICONV_VERSION_INFO): Bump to 5:0:3. + +2005-07-05 Bruno Haible + + * Makefile.devel (ACLOCAL): New variable. + (aclocal.m4): Use it. + +2005-07-05 Bruno Haible + + * m4/relocatable.m4 (AC_RELOCATABLE): On mingw, simply set + SET_RELOCATABLE to a trivial value. + +2004-08-08 Bruno Haible + + * srclib/progreloc.c (xstrdup): Define as strdup if no xmalloc should + be used. + +2004-04-28 Bruno Haible + + * srclib/progreloc.c (ISSLASH, IS_PATH_WITH_DIR, FILESYSTEM_PREFIX_LEN): + Treat Cygwin like Windows, since it now accepts Windows pathnames. + +2005-06-09 Bruno Haible + + * Makefile.in (mkinstalldirs): Use build-aux/ instead of autoconf/. + * lib/Makefile.in (mkinstalldirs): Likewise. + * src/Makefile.in (mkinstalldirs): Likewise. + * man/Makefile.in (mkinstalldirs): Likewise. + +2005-06-08 Bruno Haible + + * srclib/canonicalize.c (__realpath): Avoid gcc warnings on platforms + that don't support symbolic links. + +2005-06-08 Bruno Haible + + * srclib/binary-io.h (fileno): Undefine before defining it. Avoids a + gcc warning on mingw. + +2005-05-22 Bruno Haible + + Implement and document BIG5-2003. + * lib/big5_2003.h: New file. + * lib/converters.h: Include it. + * lib/encodings_extra.def (BIG5-2003): New encoding. + * README, man/iconv_open.3: Add BIG5-2003. + * tests/Makefile.in (check-extra-yes): Check BIG5-2003. + * tests/BIG5-2003.TXT: New file. + +2005-05-21 Bruno Haible + + Add EURO SIGN to EUC-TW converter. + * lib/cns11643_1.h (cns11643_1_2uni_page42): Add entry for 0x14242. + (cns11643_1_mbtowc): Update. + * lib/cns11643_inv.h (cns11643_inv_2charset): Add entry for 0x20AC. + (cns11643_inv_uni2indx_page*): Update. + * lib/dec_hanyu.h (dec_hanyu_mbtowc, dec_hanyu_wctomb): Consider only + part of row 42. + * tests/EUC-TW.TXT: Add entry for 0x20AC. + * tests/EUC-TW.IRREVERSIBLE.TXT: Likewise. + +2005-05-03 Bruno Haible + + * tools/Makefile (ALL): Add pt154.h. + (pt154.h): New rule. + * lib/encodings.def: Add PT154. + * lib/pt154.h: New file. + * lib/converters.h: Include it. + * README, man/iconv_open.3: Add PT154. + * NOTES: Mention PT154. + * tests/PT154.TXT: New file. + * tests/Makefile.in (check): Also test PT154. + * tests/Makefile.msvc (check): Likewise. + * tests/Makefile.os2 (check): Likewise. + +2005-03-29 Bruno Haible + + Rename libiconv_plug.so to preloadable_libiconv.so. + * configure.in (PLUGLIB): Set to preloadable_libiconv.so instead of + libiconv_plug.so. + * lib/Makefile.in (preloadable_libiconv.so): Renamed from + libiconv_plug.so. + (preloadable_libiconv_linux.so): Renamed from libiconv_plug_linux.so. + (preloadable_libiconv_solaris.so): Renamed from + libiconv_plug_solaris.so. + (preloadable_libiconv_osf.so): Renamed from libiconv_plug_osf.so. + (clean): Update. + * README: Update. + +2005-03-29 Bruno Haible + + Implement and document ATARIST. + * tools/Makefile (ALL): Add atarist.h. + (atarist.h): New rule. + * lib/atarist.h: New file. + * lib/converters.h: Include it. + * lib/encodings_extra.def (ATARIST): New encoding. + * README, man/iconv_open.3: Add ATARIST. + * tests/Makefile.in (check-extra-yes): Check ATARIST. + * tests/ATARIST.TXT: New file. + +2005-03-22 Bruno Haible + + * build-aux: New directory, renamed from autoconf. + * configure.in (AC_CONFIG_AUX_DIR): Use build-aux. + +2005-03-16 Bruno Haible + + * m4/stdint.m4 (gl_STDINT_H): Define HAVE_LONG_LONG_64BIT instead of + HAVE_LONGLONG_64BIT. + * srclib/stdint_.h: Use HAVE_LONG_LONG_64BIT instead of + HAVE_LONGLONG_64BIT. + * srclib/Makefile.am (stdint.h): Likewise. + +2005-03-14 Bruno Haible + + * Makefile.devel (aclocal.m4): Depend also on allocsa.m4, eealloc.m4, + extensions.m4, intmax.m4, inttypes.m4, longdouble.m4, longlong.m4, + printf-posix.m4, readlink.m4, signed.m4, ssize_t.m4, stdint.m4, + wchar_t.m4, wint_t.m4. + +2005-03-13 Bruno Haible + + Make stdout error checking reliable, also when writing to a NFS file. + * src/iconv.c (main): Check the return value of fclose(stdout). + * lib/genaliases.c (main): Likewise. + * lib/genaliases2.c (main): Likewise. + * lib/genflags.c (main): Likewise. + * lib/gentranslit.c (main): Likewise. + * tests/genutf8.c (main): Likewise. + * tests/table-from.c (main): Likewise. + * tests/table-to.c (main): Likewise. + +2005-03-13 Bruno Haible + + * src/iconv.c (convert): Before outputting an error message, flush + stdout and output a newline if suitable. + +2005-03-13 Bruno Haible + + Improved error messages. + * srclib/width.c: New file, from GNU clisp. + * srclib/uniwidth.h: New file, from GNU clisp with modifications. + * srclib/unitypes.h: New file, from GNU clisp with modifications. + * srclib/cjk.h: New file, from GNU clisp. + * srclib/streq.h: New file, from GNU clisp. + * srclib/stdint_.h: New file, from gnulib. + * m4/stdint.m4: New file, from gnulib. + * m4/inttypes.m4: New file, from gnulib. + * srclib/Makefile.am: Add gnulib module 'stdint' snippet. + (BUILT_SOURCES): New variable. + (libicrt_a_SOURCES): Add width.c, uniwidth.h, unitypes.h, cjk.h, + streq.h. + * configure.in: Invoke gl_STDINT_H. + * src/iconv.c: Include cjk.h, uniwidth.h. + (line, column, cjkcode): New variables. + (update_line_column): New function. + (convert): Initialize line and column. In all error message, show also + the line and column number. + (main): Initialize cjkcode. Set up hooks to call update_line_column. + +2005-03-13 Bruno Haible + + * include/iconv.h.in (iconv_canonicalize): New declaration. + * lib/genaliases.c (emit_encoding): Take two output streams as + arguments. To the second stream, emit a shell command for extracting + offsets into the gperf generated string pool. + (main): Write the shell commands into file descriptors 3 and 4. + * lib/genaliases2.c (emit_encoding): Take two output streams as + arguments. To the second stream, emit an expression for the offset + into the string pool. + (main): Write the offsets into file descriptor 3. + * Makefile.devel (lib/aliases.gperf): Remove target. + (lib/aliases.h): Generate lib/aliases.gperf temporarily. Generate also + lib/canonical.h and lib/canonical_local.h. + (lib/aliases_aix.h): Generate also lib/canonical_aix.h. + (lib/aliases_osf1.h): Generate also lib/canonical_osf1.h. + (lib/aliases_dos.h): Generate also lib/canonical_dos.h. + (lib/aliases_extra.h): Generate also lib/canonical_extra.h. + * lib/iconv.c (stringpool2): Provide default definition when it doesn't + exist. + (all_canonical): New array. + (iconv_canonicalize): New function. + +2005-03-13 Bruno Haible + + * include/iconv.h.in (iconv_unicode_char_hook, iconv_wide_char_hook, + iconv_hooks): New types. + (ICONV_SET_HOOKS): New macro. + * lib/converters.h (struct conv_struct): Add field 'hooks'. + * lib/iconv.c (iconv_open): Initialize hooks to NULL. + (iconvctl): Handle ICONV_SET_HOOKS. + * lib/loop_unicode.h (unicode_loop_convert, unicode_loop_reset): After + conversion of a character, call the uc_hook. + * lib/loop_wchar.h (wchar_id_loop_convert): After every character, call + the wc_hook. + * lib/genflags.c (iconv_hooks): Provide a dummy definition. + +2005-02-05 Bruno Haible + + * src/iconv.c (main): In case of unsupported encodings, show a hint + towards "iconv -l". + +2005-01-06 Bruno Haible + + * lib/Makefile.msvc (CFLAGS): Define also INSTALLPREFIX. + * lib/Makefile.vms (DEFS): Likewise. + Reported by Troels Walsted Hansen . + +2005-01-05 Bruno Haible + + * autoconf/config.rpath: Update from GNU gettext. + +2005-01-05 Bruno Haible + + Assume automake-1.9. + * Makefile.devel (AUTOMAKE): Assume automake-1.9. + +2005-01-05 Bruno Haible + + * m4/libtool.m4: Update from GNU gettext, based on libtool-1.5.10. + * autoconf/ltmain.sh: Update from GNU gettext, based on libtool-1.5.10. + +2004-11-11 Bruno Haible + + * lib/iconv.c (iconv_open): Accept the suffixes //TRANSLIT and //IGNORE + in arbitrary order. + Reported by Lukas Gebauer . + +2004-09-21 Juan Manuel Guerrero + + * djgpp/config.bat: Update. + * djgpp/config.sed: Update. + * djgpp/config.site: Update. + * djgpp/edtest.bat: Update. + * djgpp/fnchange.in: Update. + * djgpp/Makefile.maint: Update. + * djgpp/makefile.sed: Update. + * djgpp/README.in: Update. + * djgpp/sources.sed: Update. + * djgpp/translit-check.sed: Update. + +2004-08-25 Bruno Haible + + * m4/libtool.m4: Update from GNU gettext, based on libtool-1.5.6. + * autoconf/ltmain.sh: Update from GNU gettext, based on libtool-1.5.6. + +2004-07-31 Bruno Haible + + Update to JISX 0213 plane 1 to 2004 version (ISO-IR-233). + * tools/Makefile (jisx0213.h): Bump version number. + * tools/JISX0213.TXT: Change mappings U+2015 -> U+2014, + U+2299 -> U+29BF, and add 10 new characters. + * tools/cjk_tab_to_h.c (output_title): Bump year. + (do_jisx0213): Update comments. Emit a conditional 'inline'. + * lib/jisx0213.h: Regenerated. + * lib/iso2022_jp3.h (iso2022_jp3_mbtowc): Accept escape sequence + ESC $ ( Q as a synonym of ESC $ ( O. + (iso2022_jp3_wctomb): Emit ESC $ ( Q instead of ESC $ ( O. + * tests/EUC-JISX0213.TXT: Change mappings U+2015 -> U+2014, + U+2299 -> U+29BF, and add 10 new characters. + * tests/SHIFT_JISX0213.TXT: Likewise. + * tests/ISO-2022-JP-3-snippet: Update. + * tests/ISO-2022-JP-3-snippet.UTF-8: Update. + +2004-07-22 Bruno Haible + + * lib/encodings.def (ISO-8859-7): Add alias ISO_8859-7:2003. + * tools/Makefile (iso8859_7.h): Use conversion table from 2003. + * lib/iso8859_7.h: Add mappings for 0xa4, 0xa5, 0xaa. + * tests/ISO-8859-7.TXT: Update to ISO_8859-7:2003. + +2004-07-22 Bruno Haible + + * tools/Makefile (ALL): Add iso8859_11.h. + (iso8859_11.h): New rule. + * lib/encodings.def: Add ISO-8859-11. + * lib/iso8859_11.h: New file. + * lib/converters.h: Include it. + * tests/ISO-8859-11.TXT: New file. + * tests/Makefile.in (check): Also test ISO-8859-11. + * tests/Makefile.msvc (check): Likewise. + * tests/Makefile.os2 (check): Likewise. + +2004-07-17 Bruno Haible + + * src/iconv.c (main): Terminate option parsing when option -- is seen. + Reported by Len Lattanzi . + +2004-03-05 Bruno Haible + + * src/Makefile.in (install): Make DESTDIR work on HP-UX. + Reported by Bob Proulx . + +2004-02-19 Bruno Haible + + * lib/vietcomb.h (viet_comp_table_data): Un-uncomment 0x00D5, 0x00F5, + 0x0168, 0x0169. Needed for TCVN-5712 but not for CP1258. + (viet_comp_table0301_len): Increment by 4. + + * lib/cp1255.h (cp1255_mbtowc): Don't delay the handling of characters + which are not entries in cp1255_comp_table_data. + * lib/cp1258.h (cp1258_comp_bases): New array. + (cp1258_mbtowc): Don't delay the handling of characters which are not + relevant entries in viet_comp_table_data. + * lib/tcvn.h (tcvn_comp_bases): New array. + (tcvn_mbtowc): Don't delay the handling of characters which are not + relevant entries in viet_comp_table_data. + Reported by Alain Bench . + +2004-02-02 Perry Rapp + Bruno Haible + + * man/iconvctl.3: New file. + * man/iconv.3: Refer to it in "See also". + * man/iconv_open.3: Likewise. + +2004-01-24 Bruno Haible + + * srclib/progreloc.c (xstrdup): Define as strdup if no xmalloc should + be used. + +2004-01-20 Bruno Haible + + Upgrade from gettext-0.14. + + * configure.in: Call gl_USE_SYSTEM_EXTENSIONS. Call AM_STDBOOL_H + instead of gt_STDBOOL_H. Provide a definition for DLL_VARIABLE. + * srclib/Makefile.am (libicrt_a_SOURCES): Add allocsa.h, allocsa.c, + xalloc.h. Remove xmalloc.h. + (libicrt_a_LIBADD): Remove @ALLOCA@. + * srclib/Makefile.msvc (OBJECTS): Add allocsa.obj. + (allocsa.obj): New rule. + * srclib/Makefile.vms (OBJECTS): Add allocsa.obj. + (allocsa.obj): New rule. + * Makefile.devel (config.h_vms): Set MALLOC_0_IS_NONNULL to 0. + (config.h.msvc): Set MALLOC_0_IS_NONNULL to 1. + + lib/: + + 2003-10-09 Bruno Haible + * lib/relocatable.c: Include xalloc.h instead of xmalloc.h. + + 2003-08-01 Bruno Haible + * lib/relocatable.c (find_shared_library_fullname): Disable the code on + Linux/libc5. Reported by Alain Guibert . + + 2003-06-22 Bruno Haible + * lib/relocatable.c (compute_curr_prefix): Comment out this function in + the case when it is not used. + Reported by Pavel Roskin . + + m4/: + + * m4/gettext.m4: Upgrade from GNU gettext. Many changes. + * m4/po.m4: Likewise. + + * m4/readlink.m4: New file, from GNU gettext. + + 2003-11-30 Bruno Haible + * m4/allocsa.m4: New file. + * m4/eealloc.m4: New file. + * m4/setenv.m4 (gl_PREREQ_SETENV): Require gl_ALLOCSA instead of + AC_FUNC_ALLOCA. + + 2003-10-21 Bruno Haible + * m4/canonicalize.m4 (gl_PREREQ_CANONICALIZE): Also test for + readlink(). + + 2003-08-24 Bruno Haible + * m4/relocatable.m4 (AC_RELOCATABLE): Use $(host) instead of @host@, + since the substitution of @host@ may occur before the substitution of + @SET_RELOCATABLE@. + + 2003-08-23 Bruno Haible + * stdbool.m4: Replace with the version from gnulib, without + AC_HEADER_STDBOOL. + + 2003-08-08 Paul Eggert + * m4/extensions.m4: New file. + * m4/unlocked-io.m4 (jm_FUNC_GLIBC_UNLOCKED_IO): + Require gl_USE_SYSTEM_EXTENSIONS rather than AC_GNU_SOURCE. + + 2003-07-01 Bruno Haible + * m4/ssize_t.m4 (gt_TYPE_SSIZE_T): Don't include . + should be sufficient. + Reported by Paul Eggert. + + 2003-07-01 Bruno Haible + * m4/lib-prefix.m4 (AC_LIB_ARG_WITH): Avoid "duplicated macro" error + from aclocal-1.4-p4. + Reported by Luke Schierer and + Michael C. Toren . + + 2003-07-01 Paul Eggert + * m4/xreadlink.m4 (gl_XREADLINK): Don't check for sys/types.h, since + xreadlink.c now includes it unconditionally. + + 2003-06-17 Paul Eggert + * m4/lib-ld.m4 (AC_LIB_PROG_LD_GNU, AC_LIB_PROG_LD): Don't use egrep, + for portability to POSIX 1003.1-2001. Backported from libtool-1.5. + + 2003-05-28 Paul Eggert + * m4/pathmax.m4 (gl_PATHMAX): Don't check for limits.h. + * m4/xreadlink.m4 (gl_XREADLINK): Likewise. + + 2002-12-24 Bruno Haible + * m4/setenv.m4 (gt_FUNC_SETENV): New macro. + (gt_CHECK_VAR_DECL): Fix quoting error that led to infinite loop in m4 + when invoked twice. + (gt_PREREQ_SETENV, gt_PREREQ_UNSETENV): New macros, replacing old + gt_FUNC_SETENV. + + srclib/: + + 2003-11-30 Bruno Haible + * srclib/alloca.c: Remove file. + + 2003-11-30 Bruno Haible + Safer stack allocation. + * srclib/allocsa.h: New file. + * srclib/allocsa.c: New file. + * canonicalize.c: Include allocsa.h. + (__realpath): Use allocsa instead of alloca. Don't clobber errno right + before returning NULL. + * srclib/relocwrapper.c: Indirectly depends on allocsa. + * srclib/setenv.c: Include allocsa.h. + (alloca): Remove fallback definition. + (freea): Remove macro. + (__add_to_environ) [!_LIBC]: Use allocsa instead of alloca. Use freesa + instead of freea. + + 2003-11-17 Bruno Haible + * srclib/canonicalize.c: #undef realpath after but before + the system includes, so as to avoid a prototype clash on Solaris 2.5.1. + Reported by Warren L. Dodge . + + 2003-10-21 Bruno Haible + * srclib/canonicalize.c (lstat): Define as an alias to 'stat' on + systems without symbolic links. + + 2003-10-17 Bruno Haible + * srclib/binary-io.h: Avoid warnings on Cygwin. + + 2003-10-09 Bruno Haible + * srclib/xalloc.h: Renamed from xmalloc.h. + * srclib/progreloc.c: Include xalloc.h instead of xmalloc.h. + * srclib/relocatable.c: Likewise. + * srclib/xmalloc.c: Likewise. + * srclib/xreadlink.c: Likewise. + * srclib/xstrdup.c: Likewise. + + 2003-09-12 Paul Eggert + * srclib/progreloc.c (get_full_program_name): Define via prototype. + + 2003-09-12 Paul Eggert + * srclib/setenv.c (clearenv): Define via prototype. + + 2003-09-10 Bruno Haible + * srclib/setenv.c: Include and unconditionally. + * srclib/unsetenv.c: Likewise. + + 2003-08-28 Bruno Haible + * srclib/binary-io.h: Undefine O_BINARY before defining it. This avoids + a warning on QNX, which defines O_BINARY to 000000. + + 2003-08-24 Bruno Haible + * srclib/binary-io.h: Include , to avoid a compilation error + when MSVC7 is included later. + + 2003-08-24 Bruno Haible + * srclib/error.h: Use ANSI C "..." declarations when compiling with + MSVC, even though it doesn't define __STDC__ by default. + * srclib/error.c: Use when compiling with MSVC, even though + it doesn't define __STDC__ by default. + + 2003-08-24 Bruno Haible + Support for building DLLs on Windows. + * srclib/error.h (error_print_progname, error_message_count, + error_one_per_line): Add DLL_VARIABLE attribute. + * srclib/progname.h (program_name): Likewise. + + 2003-08-24 Bruno Haible + * srclib/progname.h: Make this file includable in C++ mode: add extern + "C". + * srclib/relocatable.h: Likewise. + * srclib/xmalloc.h: Likewise. + + 2003-08-22 Bruno Haible + * srclib/progname.h (error_with_progname, maybe_print_progname): Remove + declarations. + * srclib/progname.c (error_with_progname): Remove variable. + (maybe_print_progname): Remove function. + + 2003-08-01 Bruno Haible + * srclib/relocatable.c (find_shared_library_fullname): Disable the code + on Linux/libc5. Reported by Alain Guibert . + + 2003-07-01 Paul Eggert + * srclib/xreadlink.c: Include unconditionally, instead of + having it depend on HAVE_SYS_TYPES_H. + + 2003-06-23 Bruno Haible + Avoid compilation units that are empty after preprocessing. + * srclib/canonicalize.c: Add dummy declaration. + * srclib/strerror.c: Likewise. + * srclib/error.c: Include even if there's nothing to be + compiled. + + 2003-06-22 Bruno Haible + * srclib/relocatable.c (compute_curr_prefix): Comment out this function + in the case when it is not used. + Reported by Pavel Roskin . + + 2003-05-28 Paul Eggert + * srclib/pathmax.h: Include without checking for + HAVE_LIMITS_H. + * srclib/xreadlink.c: Likewise. + +2004-01-20 Bruno Haible + + Assume automake-1.8. + * Makefile.devel (AUTOCONF, AUTOHEADER): Assume autoconf-2.59. + (AUTOMAKE): Assume automake-1.8. + * Makefile.in (am--refresh): New target. + +2004-01-23 Bruno Haible + + * Version 1.9.2 released. + +2004-01-23 Bruno Haible + + * tests/table-from.c: Include binary-io.h. + (main): Switch stdout to binary mode. + * tests/table-to.c: Include binary-io.h. + (main): Switch stdout to binary mode. + * tests/genutf8.c: Include binary-io.h. + (main): Switch stdout to binary mode. + * tests/Makefile.in (INCLUDES): Also look in srclib. + (check): Pass INCLUDES when compiling genutf8.c. + * tests/Makefile.os2 (INCLUDES): Also look in srclib. + (genutf8.exe): Pass INCLUDES when compiling genutf8.c. + * tests/Makefile.msvc (INCLUDES): Also look in srclib. + (check): Pass INCLUDES when compiling genutf8.c. + +2004-01-21 Bruno Haible + + * src/iconv.c (force_binary): Remove variable. + (usage): Don't document --binary any more. + (convert, main): Always switch to binary mode. + * tests/check-stateful.bat: Remove --binary option. + * tests/check-translit.bat: Likewise. + * tests/check-stateful.cmd: Likewise. + * tests/check-translit.cmd: Likewise. + * djgpp/stateful-check.sed: Remove MODE variable. + * djgpp/translit-check.sed: Likewise. + +2004-01-21 Bruno Haible + + * man/iconv.3: Fix description of return value in case of error. + Reported by Jonathan Wakely . + +2003-09-12 Paul Eggert + + * srclib/progreloc.c (get_full_program_name): Define via prototype. + +2003-08-15 Bruno Haible + + * Makefile.devel (lib/translit.h): Add ulimit command so that the + gentranslit program gets the stack it needs. Many Linux distributions + allow only 8 MB of stack by default. + +2003-08-01 Bruno Haible + + * lib/relocatable.c (find_shared_library_fullname): Disable the code on + Linux/libc5. + * srclib/relocatable.c (find_shared_library_fullname): Likewise. + Reported by Alain Guibert . + +2003-07-02 Bruno Haible + + * m4/lib-ld.m4: Update from GNU gettext. + * m4/lib-prefix.m4: Update from GNU gettext. + * m4/gettext.m4: Update from GNU gettext. + * m4/intmax.m4: New file, from GNU gettext. + * m4/longdouble.m4: New file, from GNU gettext. + * m4/longlong.m4: New file, from GNU gettext. + * m4/printf-posix.m4: New file, from GNU gettext. + * m4/signed.m4: New file, from GNU gettext. + * m4/wchar_t.m4: New file, from GNU gettext. + * m4/wint_t.m4: New file, from GNU gettext. + * m4/pathmax.m4: Update from GNU gettext and gnulib. + * m4/ssize_t.m4: Update from GNU gettext and gnulib. + * m4/xreadlink.m4: Update from GNU gettext and gnulib. + * m4/readlink.m4: New file, from gnulib. + * autoconf/install-reloc: Update from GNU gettext. + * srclib/stdbool_.h: Renamed from srclib/stdbool.h.in. + * srclib/readlink.c: New file, from GNU gettext and gnulib. + * srclib/Makefile.am (LIBADD_SOURCE): Add readlink.c. + (EXTRA_DIST, stdbool.h): Use stdbool_.h instead of stdbool.h.in. + * configure.in: Invoke gl_FUNC_READLINK. + +2003-06-22 Bruno Haible + + * src/Makefile.in (install): Link with the already installed library. + This fixes a link error on Solaris. + Reported by Paul Eggert. + +2003-06-08 Bruno Haible + + * srclib/canonicalize.c (__getcwd) [VMS]: Pass 3 arguments to getcwd. + +2003-05-02 Bruno Haible + + Support for libtool-1.5. + * srclib/progname.c (set_program_name): Remove a leading + "/.libs/lt-" or "/.libs/", not only "lt-". + +2003-06-23 Bruno Haible + + Avoid compilation units that are empty after preprocessing. + * srclib/canonicalize.c: Add dummy declaration. + * srclib/strerror.c: Likewise. + * srclib/error.c: Include even if there's nothing to be + compiled. + +2003-06-22 Bruno Haible + + Portability to mingw32. + * m4/ssize_t.m4: New file, from GNU gettext. + * m4/xreadlink.m4 (gl_XREADLINK): Require gt_TYPE_SSIZE_T. + Reported by Jeff Bonggren . + +2003-06-22 Bruno Haible + + Portability to mingw32. + * lib/relocatable.c [WIN32]: Include . + * srclib/relocatable.c: Likewise. + Reported by Jeff Bonggren . + +2003-06-22 Bruno Haible + + * lib/relocatable.c (compute_curr_prefix): Comment out this function in + the case when it is not used. + * srclib/relocatable.c (compute_curr_prefix): Likewise. + Reported by Pavel Roskin . + +2003-06-18 Bruno Haible + + * config/install-sh: Update from automake-1.7.5. + +2003-06-16 Bruno Haible + + * lib/encodings.def (ISO-8859-15): Add alias LATIN-9. + (ISO-8859-16): Add aliases ISO_8859-16:2001, LATIN10, L10. Remove alias + ISO_8859-16:2000. + (GBK): Add aliases MS936, WINDOWS-936. + Reported by Guido Flohr . + +2003-05-09 Bruno Haible + + * srclib/canonicalize.c: Add #ifdef around versioned_symbol. Avoids an + "extraneous semicolon" warning from Tru64 cc. + +2003-06-07 Bruno Haible + + * Makefile.devel (config.h_vms): Don't define HAVE_ENVIRON_DECL. + * Makefile.vms (config.h): New rule. + (all, install): Depend on it. + (all, install, installdirs, uninstall, check): Fix typo. + (mostlyclean, clean, distclean, maintainer-clean): Likewise. Remove + config.h. + * lib/Makefile.vms (DEFS): Fix value of INSTALLDIR. + (OBJECTS): Use libiconv.obj instead of iconv.obj. + (libiconv.obj): Renamed from iconv.obj. + * srclib/Makefile.vms (INCLUDES): Add parent directory. + (OBJECTS): Remove strtoul.obj, setenv.obj, unsetenv.obj. + (strtoul.obj, setenv.obj, unsetenv.obj): Remove rules. + (alloca.h): New rule. + (canonicalize.obj): Depend on it. + (clean): Remove alloca.h. + * src/Makefile.vms (datadir, localedir): New variables. + (DEFS): Also define LOCALEDIR. + (iconv.obj): Add flags for relocatability, + (iconv.exe): Link with libicrt. Use link_options. + * vms/link_options.opt: New file. + Reported by Jouk Jansen . + +2003-06-07 Bruno Haible + + Support for relocatable data files even on Woe32. + * lib/Makefile.msvc (PICFLAGS): Also define PIC. + +2003-05-22 Bruno Haible + + * Version 1.9.1 released. + +2003-05-22 Bruno Haible + + * lib/genaliases.c (main): Emit %pic instead of %null-strings. + Change type of 'name' field to 'int'. + * lib/genaliases2.c (emit_encoding): Add a 'tag' argument. Emit an + invocation of macro S(), including the tag and a counter. + (main): Use the command-line argument as tag. + * Makefile.devel (lib/aliases_aix.h, lib/aliases_osf1.h, + lib/aliases_dos.h, lib/aliases_extra.h): Pass a tag to the program. + * lib/iconv.c (stringpool2_t): New type. + (stringpool2_contents): New data table. + (stringpool2): New macro. + (sysdep_aliases): Make position-independent. Move #includes out to + aliases2.h. + (aliases2_lookup): Update. + (nalias): New type. + (compare_by_index): Use 'struct nalias' instead of 'struct alias'. + (iconvlist): Convert 'struct alias' to 'struct nalias' while copying. + * lib/aliases2.h: New file, extracted from lib/iconv.c. + +2003-05-20 Bruno Haible + + * lib/iconv.c (iconvlist): Test p->name against NULL, not against "". + Reported by Muraoka Taro . + +2003-05-19 Bruno Haible + + * windows/iconv.rc: Include . + Reported by Perry Rapp. + +2003-05-18 Bruno Haible + + * Version 1.9 released. + +2003-05-18 Bruno Haible + + * lib/Makefile.in (libiconv_plug_osf.so): Avoid using LIBTOOL_LINK. + +2003-05-18 Bruno Haible + + * lib/Makefile.msvc (DEBUGFLAGS): New variable. + (iconv.lib): Use it. + * src/Makefile.msvc (DEBUGFLAGS): New variable. + * tests/Makefile.msvc (DEBUGFLAGS): New variable. + +2003-05-17 Bruno Haible + + * src/Makefile.msvc (libdir, datadir, localedir): New variables. + (IIlibdir, IIdatadir, IIlocaledir): New variables. + (CFLAGS): Define LOCALEDIR. + (iconv_no_i18n.exe): New rule. + (all): Depend on it. + * tests/check-stateful.bat: Invoke iconv_no_i18n instead of iconv. + * tests/check-translit.bat: Likewise. + +2003-05-16 Bruno Haible + + * lib/genaliases.c (main): Emit declarations for gperf-3.0. + * Makefile.devel (lib/aliases.h): Remove gperf command line options; + add new option "-m 10" for gperf-3.0. + +2003-05-12 Bruno Haible + + * m4/error.m4: Update from gettext. + +2003-05-12 Bruno Haible + + * configure.in: Invoke AC_GNU_SOURCE and jm_FUNC_GLIBC_UNLOCKED_IO. + +2003-05-12 Bruno Haible + + * lib/Makefile.msvc (PICFLAGS, CFLAGS): Move BUILDING_* macros from + CFLAGS to PICFLAGS. + +2003-05-09 Bruno Haible + + * srclib/error.c: Update from gnulib with modifications. + * srclib/unlocked-io.h: New file, from gnulib. + * m4/strerror_r.m4: New file, from gnulib. + * m4/unlocked-io.m4: New file, from gnulib. + * Makefile.devel (aclocal.m4): Depend on them. + +2003-05-08 Bruno Haible + + * Makefile.msvc (IIPREFIX): New variable. + * srclib/Makefile.msvc (INCLUDES): Add -I..\windows. + * src/Makefile.msvc (IIPREFIX, IIprefix, IIexec_prefix, IIbindir, + IIincludedir): New variables. + (INCLUDES): Add -I..\windows. + (iconv.exe): Define INSTALLPREFIX and INSTALLDIR. Link with + ../srclib/icrt.lib. + Patches by Perry Rapp. + +2003-05-07 Bruno Haible + + * README.woe32: Fix instructions for step 1. + * srclib/Makefile.msvc (OBJECTS): Remove strtoul.obj. + (strtoul.obj): Remove rule. + Reported by Perry Rapp. + +2003-05-07 Bruno Haible + + * Makefile.vms: New file. + * lib/Makefile.vms: New file. + * srclib/Makefile.vms: New file. + * src/Makefile.vms: New file. + * man/Makefile.vms: New file. + * tests/Makefile.vms: New file. + * Makefile.devel (config.h_vms, lib/config.h_vms, include/iconv.h_vms): + New rules. + (all): Depend on them. + +2003-05-07 Bruno Haible + + * srclib/Makefile.msvc (OBJECTS): Remove findprog.obj. + (findprog.obj): Remove rule. + * src/Makefile.msvc (includedir): New variable. + +2003-05-06 Bruno Haible + + * lib/translit.def: Upgrade to Unicode 4.0. + +2003-05-06 Bruno Haible + + * srclib/Makefile.am (DEFS): Fix spelling of DEPENDS_ON_LIBICONV. + * srclib/Makefile.msvc (CFLAGS): Likewise. + + * srclib/Makefile.msvc (INCLUDES): Add -I.. . + Reported by Perry Rapp. + + * Makefile.msvc (config.h): New rule. + (all): Depend on it. + (mostlyclean, clean, distclean, maintainer-clean): Erase config.h. + Reported by Perry Rapp. + +2003-05-06 Bruno Haible + + * autoconf/config.guess: Update to GNU version 2003-02-22. + * autoconf/config.sub: Likewise. + +2003-05-06 Bruno Haible + + * m4/lib-link.m4: Update from GNU gettext. + * autoconf/config.rpath: Update from GNU gettext. + + * m4/libtool.m4: Update from GNU gettext, based on libtool-1.5. + * autoconf/ltmain.sh: Update from GNU gettext, based on libtool-1.5. + + * m4/gettext.m4: Update from GNU gettext. + * m4/nls.m4: Update from GNU gettext. + * m4/po.m4: Update from GNU gettext. + * Makefile.devel (aclocal.m4): Depend on m4/nls.m4 and m4/po.m4. + +2003-04-12 Bruno Haible + + Support for OpenVMS 7.3. + * lib/iconv.c (USE_OSF1): Define also on VMS. + +2003-04-12 Bruno Haible + + Better support for FreeBSD. + * lib/encodings.def (ISO8859-{1,2,3,4,5,6,7,8,9,10,13,14,15,16): New + aliases, for compatibility with earlier FreeBSD iconv implementation + by Konstantin Chuguev. + * lib/iconv.c (iconv_open, iconv, iconv_close) [FreeBSD]: Define as + aliases. + * src/Makefile.in (install) [FreeBSD]: Avoid installation problem. + +2003-04-12 Bruno Haible + + * configure.in (mandir): Change default value. + * Makefile.in (datadir): New variable. + (install, installdirs, uninstall): Pass datadir to po and man + directories. + * Makefile.os2 (datadir): New variable. + (mandir): Use it instead of prefix. + (install, uninstall): Pass datadir to man directory. + * Makefile.msvc (mandir, docdir): Use datadir instead of prefix. + * man/Makefile.in (datadir): New variable. + (docdir): Use it instead of prefix. + (install, installdirs): Update. + * man/Makefile.os2 (datadir): New variable. + (mandir): Use it instead of prefix. + * man/Makefile.msvc (datadir): New variable. + (mandir, docdir): Use it instead of prefix. + (install, installdirs): Update. + +2003-04-06 Bruno Haible + + Make it possible to build with or without libintl support on Woe32. + * Makefile.devel (config.h.msvc): Remove ENABLE_NLS. + * Makefile.msvc (NO_NLS): New variable. + * srclib/Makefile.msvc (NO_NLS): New variable. + (CFLAGS, INCLUDES): Use them. + * src/Makefile.msvc (NO_NLS): New variable. + (NLSFLAGS, INCINTL, LIBINTL): New variables. + (CFLAGS, INCLUDES, iconv.exe): Use them. + +2003-04-12 Bruno Haible + + * lib/loop_unicode.h (unicode_transliterate): When the Hangul or + variants transliteration failed with RET_ILUNI, don't return + RET_TOOSMALL. + Reported by the FreeBSD porters. + +2003-04-06 Bruno Haible + + * srclib/binary-io.h: New file, from GNU gettext. + * src/iconv.c: Include it. + (O_BINARY, O_TEXT, SET_BINARY): Remove definitions. + +2003-04-05 Bruno Haible + + Support for relocatable installation. + * m4/alloca.m4: New file, from GNU gettext. + * m4/canonicalize.m4: New file, from GNU gettext. + * m4/error.m4: New file, from GNU gettext. + * m4/onceonly.m4: New file, from GNU gettext. + * m4/pathmax.m4: New file, from GNU gettext. + * m4/relocatable.m4: New file, from GNU gettext. + * m4/setenv.m4: New file, from GNU gettext. + * m4/stdbool.m4: New file, from GNU gettext. + * m4/strerror.m4: New file, from GNU gettext. + * m4/xreadlink.m4: New file, from GNU gettext. + * autoconf/config.libpath: New file, from GNU gettext. + * autoconf/install-reloc: New file, from GNU gettext. + * autoconf/reloc-ldflags: New file, from GNU gettext. + * autoconf/missing: New file, from GNU automake 1.7.3. + * lib/relocatable.h: New file, from GNU gettext. + * lib/relocatable.c: New file, from GNU gettext. + * srclib/alloca.c: New file, from GNU gettext. + * srclib/alloca_.h: New file, from GNU gettext. + * srclib/canonicalize.c: New file, from GNU gettext. + * srclib/canonicalize.h: New file, from GNU gettext. + * srclib/error.c: New file, from GNU gettext. + * srclib/error.h: New file, from GNU gettext. + * srclib/exit.h: New file, from GNU gettext. + * srclib/gettext.h: New file, from GNU gettext. + * srclib/memmove.c: New file, from GNU gettext. + * srclib/pathmax.h: New file, from GNU gettext. + * srclib/progname.c: New file, from GNU gettext. + * srclib/progname.h: New file, from GNU gettext. + * srclib/progreloc.c: New file, from GNU gettext. + * srclib/relocatable.c: New file, from GNU gettext. + * srclib/relocatable.h: New file, from GNU gettext. + * srclib/relocwrapper.c: New file, from GNU gettext. + * srclib/setenv.c: New file, from GNU gettext. + * srclib/setenv.h: New file, from GNU gettext. + * srclib/stdbool.h.in: New file, from GNU gettext. + * srclib/strerror.c: New file, from GNU gettext. + * srclib/unsetenv.c: New file, from GNU gettext. + * srclib/xmalloc.c: New file, from GNU gettext. + * srclib/xmalloc.h: New file, from GNU gettext. + * srclib/xreadlink.c: New file, from GNU gettext. + * srclib/xreadlink.h: New file, from GNU gettext. + * srclib/xstrdup.c: New file, from GNU gettext. + * srclib/Makefile.am: New file. + * srclib/Makefile.msvc: New file. + * windows/alloca.h: New file, from GNU gettext. + * windows/stdbool.h: New file, from GNU gettext. + * configure.in (AC_CONFIG_HEADERS): Replace src/config.h with config.h. + Add AC_RELOCATABLE, AC_HEADER_STDC, AC_CHECK_HEADERS(stddef.h stdlib.h + string.h), AC_CHECK_FUNCS(getc_unlocked), AC_REPLACE_FUNCS(memmove), + AM_LANGINFO_CODESET, gl_FUNC_ALLOCA, gl_CANONICALIZE, + gt_FUNC_ERROR_AT_LINE, gl_PATHMAX, gt_FUNC_SETENV, gt_STDBOOL_H, + gl_FUNC_STRERROR, gl_XREADLINK, AC_OUTPUT(srclib/Makefile). + * lib/config.h.in: Add HAVE_GETC_UNLOCKED, HAVE_LANGINFO_CODESET, + HAVE_SETLOCALE, HAVE_STDDEF_H, HAVE_STDLIB_H, HAVE_STRING_H, for + localcharset.c. Add ENABLE_RELOCATABLE, INSTALLPREFIX, for + relocatable.c. + * lib/Makefile.in (DEFS): New variable. + (SOURCES): Add localcharset.c and relocatable.c. + (OBJECTS): Add localcharset.lo and relocatable.lo. + (LIBCHARSET_OBJECTS): Remove variable. + (libiconv_plug_linux.so, libiconv_plug_solaris.so, + libiconv_plug_osf.so): Use $(DEFS). Don't use $(LIBCHARSET_OBJECTS). + (iconv.lo): Use $(DEFS). + (localcharset.lo, relocatable.lo): New rules. + * lib/Makefile.msvc (CFLAGS): Define HAVE_CONFIG_H, BUILDING_DLL, + ENABLE_RELOCATABLE, IN_LIBRARY, INSTALLDIR, NO_XMALLOC, + set_relocation_prefix, relocate. Remove $(PICFLAGS). + (INCLUDES): Simplify. + (SOURCES): Remove variable. + (OBJECTS): Add localcharset.obj and relocatable.obj. + (LIBCHARSET_OBJECTS): Remove variable. + (iconv.obj): Add $(PICFLAGS). + (localcharset.obj, relocatable.obj): New rules. + (iconv.lib): Drop $(LIBCHARSET_OBJECTS). + * include/iconv.h.in (libiconv_set_relocation_prefix): New declaration. + * src/gettext.h: Remove file. + * src/iconv.c: Include progname.h and relocatable.h. + (ICONV_CONST): Define to const if the system has no iconv. + (main): Invoke set_program_name. Relocate LOCALEDIR. + * src/Makefile.in (top_srcdir): New variable. + (INCLUDES): Add .. and ../srclib. + (iconv_no_i18n, iconv): Link with ../srclib/libicrt.a. + (iconv_no_i18n.@OBJEXT@, iconv.@OBJEXT@): Define INSTALLDIR. + (RELOCATABLE_LIBRARY_PATH, RELOCATABLE_SRC_DIR, RELOCATABLE_BUILD_DIR, + RELOCATABLE_CONFIG_H_DIR, @SET_RELOCATABLE@, iconv_LDFLAGS): New + variables. + (iconv): Use $(iconv_LDFLAGS). + (install): Use $(INSTALL_PROGRAM_ENV). + (distclean): Drop removing config.h. + * src/Makefile.msvc (INCLUDES): Add .., simplify. + * tests/Makefile.msvc (INCLUDES): Simplify. + * Makefile.devel (AUTOHEADER, AUTOMAKE): New variables. + (config.h.in, srclib/Makefile.in, config.h.msvc): New rules. + (all): Depend on them. + (aclocal.m4) Depend also on m4/alloca.m4, m4/canonicalize.m4, + m4/error.m4, m4/onceonly.m4, m4/pathmax.m4, m4/relocatable.m4, + m4/setenv.m4, m4/stdbool.m4, m4/strerror.m4, m4/xreadlink.m4. + (lib/config.h.msvc): Additional processing. + * Makefile.in (all, install, installdirs, uninstall, check): Recurse + into srclib. + (mostlyclean, clean, distclean, maintainerclean): Likewise. Remove + lib/localcharset.h. + (distclean, maintainerclean): Remove also config.h and some stamps. + * Makefile.msvc (all, install, installdirs, uninstall, check, + mostlyclean, clean, distclean, maintainerclean): Recurse into srclib. + * INSTALL.generic: Document --enable-relocatable and + --with-libintl-prefix. Remove the recommendation to set CPPFLAGS and + LDFLAGS. The lib-link.m4 macros make this unnecessary. + +2003-04-05 Bruno Haible + + * configure.in: Bump version number to 1.9. + * include/iconv.h.in (_LIBICONV_VERSION): Bump. + * windows/iconv.rc: Bump version number. + * lib/Makefile.in (LIBICONV_VERSION_INFO): Bump to 4:0:2. + +2003-04-05 Bruno Haible + + * Makefile.msvc (PREFIX): New variable. + (prefix): Use it. + (distclean, maintainer-clean): Drop Unix specific removals. + * lib/Makefile.msvc (PREFIX, IIPREFIX): New variables. + (prefix): Use it. + (IIprefix, IIexec_prefix, IIbindir, IIlibdir): New variables. + (clean): Drop Unix specific removal. + * src/Makefile.msvc (PREFIX): New variable. + (prefix): Use it. + (clean): Drop Unix specific removal. + (distclean): Likewise. + * tests/Makefile.msvc (clean): Drop Unix specific removal. + (distclean): Likewise. + +2003-04-05 Bruno Haible + + * m4/endian.m4 (CL_WORDS_LITTLEENDIAN): Use 3-argument AC_DEFINE. + +2003-04-05 Bruno Haible + + * m4/general.m4 (CL_CONFIG_SUBDIRS, CL_CANONICAL_HOST, + CL_CANONICAL_HOST_CPU, CL_CANONICAL_HOST_CPU_FOR_FFCALL): Remove + macros. + * m4/gettext.m4: Update from GNU gettext. + * m4/iconv.m4: Update from GNU gettext. + * m4/lcmessage.m4: Update from GNU gettext. + * m4/progtest.m4: Update from GNU gettext. + * m4/libtool.m4: Update from GNU gettext. + 2003-02-16 Bruno Haible + Workaround autoconf >= 2.52 breakage. + * libtool.m4 (AC_LIBTOOL_ARG_WITH): New macro. + (_LT_AC_LTCONFIG_HACK, AC_PROG_LD): Use it. + * autoconf/ltmain.sh: Update from GNU gettext. + 2003-02-18 Bruno Haible + Fix the 2002-09-16 fix. + * ltmain.sh (install): If "ln -s -f" fails (this is the case + with /usr/bin/ln on Solaris 2.7), fall back to "rm && ln -s". + +2003-04-05 Bruno Haible + + Start using automake. + * configure.in: Add AM_INIT_AUTOMAKE invocation. + (PACKAGE, VERSION): Remove. + Use AC_CANONICAL_HOST instead of CL_CANONICAL_HOST. + Use AC_PROG_LN_S instead of CL_PROG_LN_S. + Use AC_PROG_RANLIB instead of CL_PROG_RANLIB. + Reorder so that AC_CANONICAL_HOST comes early but still after + AC_PROG_CC. + * m4/ranlib.m4: Remove file. + * m4/libtool.m4: Undo AC_ -> CL_ substitutions. + * Makefile.devel (CLISP_DIR): Comment out. + (AUTOCONF_FILES): Change to aclocal.m4. + (aclocal.m4): Renamed from autoconf/aclocal.m4. Update dependencies. + (configure.in): Drop --include option. + +2003-03-17 Bruno Haible + + Improved MSVC support. + * Makefile.msvc (prefix): Use less Unixy value. + (local_prefix): Remove variable. + (libdir, includedir, mandir): Use backslashes. + (bindir, datadir, localedir, docdir): New variables. + (INSTALL, INSTALL_PROGRAM, INSTALL_DATA): New variables. + (all): Recurse into po/ and man/. + (install, installdirs, uninstall): Rewritten. + (check, mostlyclean, clean, distclean, maintainer-clean): Recurse + into po/ and man/. + * lib/Makefile.msvc (prefix): Use less Unixy value. + (local_prefix): Remove variable. + (libdir): Use backslashes. + (bindir): New variable. + (INSTALL, INSTALL_PROGRAM, INSTALL_DATA): Set to real values. + (RESOURCES): Enable iconv.res. + (install, installdirs, uninstall): New rules. + (clean): Remove config.h. + (distclean): Don't remove config.h here. + * src/Makefile.msvc (prefix, exec_prefix, bindir): New variables. + (INSTALL, INSTALL_PROGRAM, INSTALL_DATA): New variables. + (install, installdirs, uninstall): New rules. + * man/Makefile.msvc: New file. + * tests/Makefile.msvc (install, installdirs, uninstall): New rules. + * Makefile.devel (all): Depend on po/Makefile.msvc. + (po/Makefile.msvc): New rule. + * windows/iconv.rc: Update. + * README.woe32: Mention automatic installation command. + + Rename libcharset.h to localcharset.h. + * lib/iconv.c: Include localcharset.h, not libcharset.h. + * Makefile.in (lib/localcharset.h): Renamed from lib/libcharset.h. + (all, install): Update dependencies. + (all): Create lib/localcharset.h, not lib/libcharset.h. + (mostlyclean, clean, distclean, maintainer-clean): Remove + lib/localcharset.h, not lib/libcharset.h. + * djgpp/README.in, djgpp/README: Update. + * djgpp/config.bat: Update. + * djgpp/config.sed: Update. + * djgpp/fnchange.in, djgpp/fnchange.lst: Update. + +2003-01-31 Bruno Haible + + * src/Makefile.in (all): Don't do the chmod if it has already been + done. + +2003-01-31 Bruno Haible + + * lib/loop_unicode.h (unicode_transliterate): Enable recursive + transliteration. Idea from Perry Rapp. + * lib/gentranslit.c (main): Change bound from 0x10000 to 0x110000. + Change element type of translit_data to 'unsigned int'. + * lib/translit.def: Many new transliterations, mostly taken from glibc. + * lib/translit.h: Regenerated. + * tests/Translit1.ISO-8859-1, tests/Translit1.ASCII: New files. + * tests/Makefile.in (check): Add Translit1 check. + * tests/Makefile.msvc (check): Likewise. + * tests/Makefile.os2 (check): Likewise. + * tests/TranslitFail1.ISO-8859-1: Choose a sentence which the new + improved transliteration cannot do. + +2003-02-14 Bruno Haible + + * Makefile.devel (AUTOCONF): Switch to autoconf-2.57. + (configure): Update rule. + +2003-01-03 Albert Chin + + * autoconf/ltmain.sh: Don't pass -R flags found in a .la's + dependency_libs variable directly down to the linker. + Reported by Tim Mooney . + +2003-01-01 Bruno Haible + + * src/Makefile.in (install): Use libiconv.la in ../lib, not in + $(libdir), so that installing with DESTDIR works. + Reported by Michael Adams . + +2003-01-01 Bruno Haible + + * Makefile.in (mkinstalldirs): New variable. + (install-lib, install, installdirs): Use it instead of mkdir. + * lib/Makefile.in (mkinstalldirs): New variable. + (install-lib, install, installdirs): Use it instead of mkdir. + * man/Makefile.in (mkinstalldirs): New variable. + (install, installdirs): Use it instead of mkdir. + * src/Makefile.in (mkinstalldirs): New variable. + (install, installdirs): Use it instead of mkdir. + +2002-09-27 Bruno Haible + + * autoconf/mkinstalldirs: Upgrade to automake-1.7.2 version. + +2002-11-07 Bruno Haible + + * m4/libtool.m4: Upgrade to libtool-1.4.3. + * autoconf/ltmain.sh: Upgrade to libtool-1.4.3. + +2002-07-14 Bruno Haible + + * m4/libtool.m4 (_LT_AC_LTCONFIG_HACK): Add support for GNU/FreeBSD. + +2002-06-12 Bruno Haible + + * configure.in: Use new AC_* names of libtool macros. Invoke + AC_LIBTOOL_WIN32_DLL. + +2002-12-19 Bruno Haible + + * lib/Makefile.in (libiconv_plug_solaris.so): Change rule if using gcc. + Reported by Henry Nelson . + +2002-11-07 Bruno Haible + + Make "make install" without prior "make" work. + * Makefile.in (lib/libcharset.h): New rule. + (all, install): Depend on it. + Reported by Martin MokrejÅ¡ . + +2002-10-28 Bruno Haible + + * man/Makefile.in (install): Change directory back to the working + directory, so that install-sh (which may be a relative pathname) is + found in the right place. + +2002-09-16 Bruno Haible + + * autoconf/ltmain.sh (install): Use "ln -s -f" instead of + "rm -f && ln -s" to make a symlink for a shared library. + Reported by Nelson H. F. Beebe . + +2002-09-02 Bruno Haible + + * src/iconv.c (main): Don't call bindtextdomain if !ENABLE_NLS. + +2002-08-16 Bruno Haible + + * src/iconv.c (main): Perform fflush before testing ferror(stdout). + +2002-05-29 Bruno Haible + + * Version 1.8 released. + +2002-05-26 Bruno Haible + + * lib/c99.h: New file. + * lib/converters.h: Include it. + * lib/encodings.def (C99): New encoding. + * README, man/iconv_open.3: Document C99 encoding. + +2002-05-26 Bruno Haible + + * lib/java.h (java_mbtowc): Accept 12-byte sequences for non-BMP + characters. + (java_wctomb): Produce 12-byte sequences for non-BMP characters. + +2002-05-29 Bruno Haible + + Fix installation of iconv program when linked with a libintl that was + built against an earlier libiconv. + * src/iconv.c: Conditionally disable NLS. + * src/iconv_no_i18n.c: New file. + * src/Makefile.in (libdir): New variable. + (all): Depend on iconv_no_i18n, iconv.@OBJEXT@ but not iconv. Make + directory writable, so iconv executable can be created during "make + install". + (iconv): Remove rule. + (iconv_no_i18n, iconv_no_i18n.@OBJEXT@): New rules. + (install): Link iconv now, after the new libiconv.so is installed. + (clean): Also remove iconv_no_i18n. + * tests/Makefile.in: (check, check-extra-yes): Depend on iconv_no_i18n, + not iconv. + * tests/check-stateful: Use iconv_no_i18n, not iconv. + * tests/check-translit: LIkewise. + * tests/check-translitfailure: Likewise. + +2002-05-29 Bruno Haible + + * configure.in: Call AC_PROG_INSTALL instead of CL_PROG_INSTALL. + * m4/install.m4: Remove file. + * Makefile.devel (autoconf/aclocal.m4): Don't depend on m4/install.m4. + +2002-05-24 Bruno Haible + + * lib/jisx0213.h: Use 'inline' only conditionally. + +2002-05-18 Bruno Haible + + * configure.in (AC_INIT), include/iconv.h.in (_LIBICONV_VERSION), + README, windows/iconv.rc, djgpp/README, djgpp/fnchange.lst: + Bump version number. + * lib/Makefile.in (LIBICONV_VERSION_INFO): Define to 3:0:1. + +2002-02-06 Bruno Haible + + * autoconf/ltmain.sh: Upgrade from libtool-1.4 to libtool-1.4.2. + +2002-02-02 Bruno Haible + + * autoconf/ltmain.sh: Add DESTDIR support on ELF systems. + +2001-11-03 Bruno Haible + + * autoconf/ltmain.sh: chmod 777 the .libs directory, so that + "make install" succeeds. + +2002-05-18 Bruno Haible + + * src/Makefile.in (iconv): Remove the -liconv dependency of -lintl + from the command line. Needed to ensure that the new libiconv version + is used on FreeBSD. + +2002-05-14 Bruno Haible + + Implement and document CP853, TDS565, RISCOS-LATIN1. + * tools/Makefile (ALL): Add cp853.h, tds565.h, riscos1.h. + (cp853.h, tds565.h, riscos1.h): New rules. + * lib/cp853.h: New file. + * lib/tds565.h: New file. + * lib/riscos1.h: New file. + * lib/converters.h: Include them. + * lib/encodings_dos.def (CP853): New encoding. + * lib/encodings_extra.def (TDS565, RISCOS-LATIN1): New encodings. + * README, man/iconv_open.3: Add CP853, TDS565, RISCOS-LATIN1. + * tests/Makefile.in (check-extra-yes): Check CP853, TDS565, + RISCOS-LATIN1. + * tests/Makefile.msvc (check): Check CP853. + * tests/CP853.TXT: New file. + * tests/TDS565.TXT: New file. + * tests/RISCOS-LATIN1.TXT: New file. + + * lib/cp860.h (cp860_wctomb): Optimize. + +2002-05-12 Bruno Haible + + * tools/Makefile (ksc5601.h): Add two extra characters. + * lib/ksc5601.h: Regenerated. + * tests/EUC-KR.TXT: Add EURO SIGN and REGISTERED SIGN. + * tests/CP949.TXT: Likewise. + * tests/JOHAB.TXT: Likewise. + +2002-05-12 Bruno Haible + + * README: Mention extra encodings. + * man/iconv_open.3: Likewise. Improve formatting in text and html + output formats. + +2002-05-12 Bruno Haible + + * tests/SHIFT_JIS.TXT: Renamed from tests/SHIFT-JIS.TXT. + +2002-05-12 Bruno Haible + + * Makefile.devel (AUTOCONF): New variable. + (AUTOCONF_FILES): Remove autoconf/autoconf.m4f. + (configure): Use the AUTOCONF variable. + * autoconf/autoconf: Remove file. + * autoconf/autoconf.m4: Remove file. + * autoconf/autoconf.m4f: Remove file. + +2002-05-12 Bruno Haible + + * tools/JISX0213.TXT: New file. + * tools/cjk_tab_to_h.c (do_jisx0213): New function. + (main): Accept "jisx0213". + * tools/Makefile (all): Add jisx0213.h. + (jisx0213.h): New rule. + * lib/jisx0213.h: New file, generated by cjk_tab_to_h. + * lib/euc_jisx0213.h: New file. + * lib/shift_jisx0213.h: New file. + * lib/iso2022_jp3.h: New file. + * lib/converters.h: Include them. + * lib/encodings_extra.def (EUC-JISX0213, SHIFT_JISX0213, + ISO-2022-JP-3): New encodings. + * tests/EUC-JISX0213.TXT: New file. + * tests/SHIFT_JISX0213.TXT: New file. + * tests/ISO-2022-JP-3-snippet: New file. + * tests/ISO-2022-JP-3-snippet.UTF-8: New file. + * tests/Makefile.in (check-extra): Also check EUC-JISX0213, + SHIFT_JISX0213, ISO-2022-JP-3. + * tests/check-stateless: Add support for encodings which contain + precomposed Unicode characters, by eliminating precomposed characters + before the comparison. + * tests/table-from.c (main): Fix usage message. + * tests/table-to.c (main): Make it work for encodings for which the + "to" direction is stateful. + +2002-05-09 Bruno Haible + + New configure option --enable-extra-encodings. + * lib/encodings_extra.def: New file. + * lib/converters.h: Handle USE_EXTRA. + * lib/genaliases2.c (main): Handle USE_EXTRA. + * lib/genflags.c: Define USE_EXTRA. + (main): Include encodings_extra.def. + * lib/iconv.c: Handle ENABLE_EXTRA, conditionally set USE_EXTRA. + Handle USE_EXTRA. + * lib/config.h.in (ENABLE_EXTRA): New macro. + * configure.in: Accept option --enable-extra-encodings. + * Makefile.devel (all): Depend on lib/aliases_extra.h. + (lib/aliases_extra.h): New rule. + (lib/flags.h): Depend on lib/encodings_extra.def. + * tests/Makefile.in (check-extra, check-extra-no, check-extra-yes): + New rules. + (check): Invoke check-extra. + * tests/Makefile.msvc (check): Also check the DOS encodings. + + Support for testing the AIX encodings. + * tests/CP856.TXT: New file. + * tests/CP922.TXT: New file. + * tests/CP1046.TXT: New file. + * tests/CP1124.TXT: New file. + * tests/CP1129.TXT: New file. + * tests/CP1161.TXT, tests/CP1161.IRREVERSIBLE.TXT: New files. + * tests/CP1162.TXT: New file. + * tests/CP1163.TXT, tests/CP1163.IRREVERSIBLE.TXT: New files. + + Support for testing the OSF/1 encodings. + * tests/DEC-KANJI.TXT: New file. + * tests/DEC-HANYU.TXT, tests/DEC-HANYU.IRREVERSIBLE.TXT: New files. + + Support for testing the DOS encodings. + * tests/CP437.TXT: New file. + * tests/CP737.TXT: New file. + * tests/CP775.TXT: New file. + * tests/CP852.TXT: New file. + * tests/CP855.TXT: New file. + * tests/CP857.TXT: New file. + * tests/CP858.TXT: New file. + * tests/CP860.TXT: New file. + * tests/CP861.TXT: New file. + * tests/CP863.TXT: New file. + * tests/CP864.TXT: New file. + * tests/CP865.TXT: New file. + * tests/CP869.TXT: New file. + * tests/CP1125.TXT: New file. + +2002-05-09 Bruno Haible + + Implement more ASCII compatible DOS encodings. + * tools/Makefile (ALL): Add cp737.h, cp858.h, cp860.h, cp863.h. + (cp737.h, cp858.h, cp860.h, cp863.h): New rules. + * lib/cp737.h: New file. + * lib/cp858.h: New file. + * lib/cp860.h: New file. + * lib/cp863.h: New file. + * lib/converters.h: Include them. + * lib/encodings_dos.def (CP737, CP858, CP860, CP863): New encodings. + +2002-05-09 Bruno Haible + + Implement new ASCII compatible encodings from IBM. + * tools/Makefile (ALL): Add cp1161.h, cp1162.h, cp1163.h. + (cp1161.h, cp1162.h, cp1163.h): New rules. + * lib/cp1161.h: New file. + * lib/cp1162.h: New file. + * lib/cp1163.h: New file. + * lib/converters.h: Include them. + * lib/encodings_aix.def (CP1161, CP1162, CP1163): New encodings. + +2002-05-09 Bruno Haible + + Implement and document KOI8-T. + * tools/Makefile (ALL): Add koi8_t.h. + (koi8_t.h): New rule. + * lib/koi8_t.h: New file. + * lib/converters.h: Include it. + * lib/encodings.def (KOI8-T): New encoding. + * README, man/iconv_open.3: Add KOI8-T. + * tests/Makefile.in (tests): Check KOI8-T. + * tests/Makefile.os2 (tests): Likewise. + * tests/Makefile.msvc (tests): Likewise. + * tests/KOI8-T.TXT: New file. + +2002-05-09 Bruno Haible + + * tools/8bit_tab_to_h.c (main): Update copyright year. + * tools/cjk_variants.c (main): Likewise. + +2002-05-08 Bruno Haible + + * README.woe32: Renamed from README.win32. + +2002-05-08 Bruno Haible + + * lib/iconv.c: Enable DOS encodings also when compiling for Woe32, + because the Woe32 consoles use them. + +2002-05-04 Bruno Haible + + * lib/loop_unicode.h (unicode_loop_convert): When quitting the loop + without writing an output character, restore cd->istate to its value + before the xxx_mbtowc call. Otherwise we lose some characters during + CP1255/CP1258/TCVN to Unicode conversion. + (unicode_loop_reset): Likewise for the xxx_flushwc call. + * tests/CP1255-snippet, tests/CP1255-snippet.UTF-8: Make the test + files large enough to test against the bug. + * tests/CP1258-snippet, tests/CP1258-snippet.UTF-8: Likewise. + * tests/TCVN-snippet, tests/TCVN-snippet.UTF-8: Likewise. + +2002-04-28 Bruno Haible + + * tools/Makefile (armscii_8.h): Use table from glibc-2.2.90. + * tests/ARMSCII-8.TXT: Update to glibc-2.2.90 version. + * tests/ARMSCII-8.IRREVERSIBLE.TXT: Remove 0x0027. + * lib/armscii_8.h: Regenerated. + +2002-04-28 Bruno Haible + + * src/iconv.c: Include gettext.h. + (_): New macro. + (usage, print_version, convert, main): Internationalize. + (main): Call setlocale, bindtextdomain, textdomain. + * src/gettext.h: New file, from GNU gettext 0.11.2. + * src/config.h.in: New file, needed for ENABLE_NLS. + * src/Makefile.in (datadir, localedir): New variables. + (iconv): Link with @LTLIBINTL@. + (iconv.@OBJEXT@): Define LOCALEDIR. + (distclean): Remove config.h. + * po: New directory. + * Makefile.in (all, install, installdirs, uninstall, check, + mostlyclean, clean, distclean, maintainer-clean): Recurse into the po + directory. + * autoconf/mkinstalldirs: New file, from automake-1.5. + * ABOUT-NLS: New file, from GNU gettext 0.11.2. + * m4/codeset.m4: New file, from GNU gettext 0.11.2. + * m4/gettext.m4: New file, from GNU gettext 0.11.2. + * m4/glibc21.m4: New file, from GNU gettext 0.11.2. + * m4/isc-posix.m4: New file, from GNU gettext 0.11.2. + * m4/lcmessage.m4: New file, from GNU gettext 0.11.2. + * m4/progtest.m4: New file, from GNU gettext 0.11.2. + * configure.in: Require autoconf-2.52, needed for multiple config.h.in + files. Use new form of AC_INIT. Invoke AM_GNU_GETTEXT. + (PACKAGE, VERSION): Define, needed for po/Makefile.in.in. + * lib/config.h.in (HAVE_LOCALE_H, HAVE_SETLOCALE): Remove. + +2002-04-28 gettextize + + * configure.in (AC_OUTPUT): Add po/Makefile.in. + +2002-04-28 Bruno Haible + + * m4/eilseq.m4: Renamed from autoconf/eilseq.m4. + * m4/mbstate_t.m4: Renamed from autoconf/mbstate_t.m4. + * m4/general.m4: New file, from GNU clisp. + * m4/proto.m4: New file, from GNU clisp. + * m4/ranlib.m4: New file, from GNU clisp. + * m4/install.m4: New file, from GNU clisp. + * m4/cp.m4: New file, from GNU clisp. + * m4/ln.m4: New file, from GNU clisp. + * m4/endian.m4: New file, from GNU clisp. + * m4/iconv.m4: New file, from GNU gettext 0.11.2. + * m4/lib-ld.m4: New file, from GNU gettext 0.11.2. + * m4/lib-link.m4: New file, from GNU gettext 0.11.2. + * m4/lib-prefix.m4: New file, from GNU gettext 0.11.2. + * autoconf/config.rpath: New file, from GNU gettext 0.11.2. + * m4/libtool.m4: New file, based on libtool-1.4.2. + * Makefile.devel (ACLOCAL): Remove variable. + (ACSELECT): Remove variable. + (OTHERMACROS): Remove variable. + (m4/*.m4): New rules. + (autoconf/aclocal.m4): Construct using aclocal instead of acselect. + * configure.in: Invoke AM_ICONV instead of CL_ICONV. + +2002-04-06 Bruno Haible + + Upgrade to Unicode 3.2. + * tools/cjk_tab_to_h.c (output_title): Bump copyright year. + (compact_large_charset2uni): Add an argument. Determine optimal shift. + Copy modified enc->charset2uni table. + (output_charset2uni): Deal with shift other than 8. Copy encoding, so + as to not disturb subsequent output_uni2charset[_sparse] call. + * lib/hkscs.h: Regenerated. + * tests/BIG5-HKSCS.TXT: Update. + * tests/BIG5-HKSCS.IRREVERSIBLE.TXT: Update. + +2002-04-06 Bruno Haible + + Upgrade to Unicode 3.2. + * tools/Makefile (cns11643_1.h, cns11643_2.h, cns11643_3.h, + cns11643_4a.h, cns11643_4b.h, cns11643_5.h, cns11643_6.h, + cns11643_7.h, cns11643_15.h, cns11643_inv.h): Use + CNS11643-Unicode32.TXT instead of CNS11643-Unicode31.TXT. + * lib/cns11643_3.h: Regenerated. + * lib/cns11643_4a.h: Regenerated. + * lib/cns11643_4b.h: Regenerated. + * lib/cns11643_5.h: Regenerated. + * lib/cns11643_6.h: Regenerated. + * lib/cns11643_7.h: Regenerated. + * lib/cns11643_15.h: Regenerated. + * lib/cns11643_inv.h: Regenerated. + * tests/EUC-TW.TXT: Update. + +2002-01-17 Bruno Haible + + * lib/tcvn.h (tcvn_2uni_1): Make it smaller. + (tcvn_mbtowc): Small optimization. + +2002-01-13 Bruno Haible + + New options -l, -c, -s. + * src/iconv.c (discard_unconvertible, silent): New variables. + (usage): Document options -l, -c, -s. + (print_one): New function. + (convert): If silent is true, don't print error messages about the + conversion to stderr. If discard_unconvertible is true, set the + iconv descriptor to DISCARD_ILSEQ the first time, but make sure to + return the same return code as when discard_unconvertible is false. + (main): Accept options -l, -c, -s. Implement option -l. + * man/iconv.1: Document options -l, -c, -s. + +2002-01-13 Bruno Haible + + Support for "iconv -c". + * include/iconv.h.in (ICONV_GET_DISCARD_ILSEQ): New macro. + (ICONV_SET_DISCARD_ILSEQ): Likewise. + * lib/converters.h (struct conv_struct): New field discard_ilseq. + * lib/iconv.c (iconv_open): Set discard_ilseq to true if tocode + has an "//IGNORE" suffix, and to false otherwise. + (iconvctl): Implement ICONV_GET_DISCARD_ILSEQ, ICONV_SET_DISCARD_ILSEQ. + * lib/loop_unicode.h (unicode_loop_convert): If discard_ilseq is + true, skip one input character instead of returning EILSEQ. + (unicode_loop_reset): Likewise. + * lib/loop_wchar.h (wchar_from_loop_convert): Likewise. + (wchar_to_loop_convert): Likewise. + +2002-01-13 Bruno Haible + + Support for "iconv -l". + * include/iconv.h.in (iconvlist): New declaration. + * Makefile.devel (lib/aliases.h): Change gperf options. + * lib/iconv.c (compare_by_index, compare_by_name, iconvlist): New + functions. + +2002-01-06 Bruno Haible + + * lib/loop_unicode.h (unicode_transliterate): If the transliteration + fails due to limited output encoding, return RET_ILUNI, not + RET_TOOSMALL. Reported by Nelson H. F. Beebe . + * tests/check-translitfailure: New file. + * tests/TranslitFail1.ISO-8859-1: New file. + * tests/Makefile.in (check): Call check-translitfailure. + +2001-12-15 Bruno Haible + + * lib/euc_jp.h (euc_jp_wctomb): Add irreversible mappings for + Shift_JIS characters 0x5C and 0x7E. + * tests/EUC-JP.IRREVERSIBLE.TXT: New file. + +2001-12-05 Bruno Haible + + * lib/iconv.c (iconv_open): Recognize the empty encoding name. Avoid + endless loop if locale_charset() returns the empty string. + * README, man/iconv_open.3: Add the empty encoding name. + +2001-11-10 Bruno Haible + + * lib/Makefile.in (libiconv_plug_linux.so): Allow building it with a + non-gcc compiler. + +2001-10-23 Bruno Haible + + * tools/Makefile (cp1125.h): New target. + (ALL): Add it. + * lib/cp1125.h: New file. + * lib/converters.h: Include it. + * lib/encodings_dos.def (CP1125): New encoding. + +2001-09-08 Bruno Haible + + * autoconf/eilseq.m4: New file. + * Makefile.devel (OTHERMACROS): Add it. + * configure.in: Call AC_EILSEQ. + * include/iconv.h.in (EILSEQ): Define to the autoconf determined value. + +2001-08-25 Bruno Haible + + Upgrade to autoconf-2.52. + * autoconf/autoconf: Upgrade to autoconf-2.52. + * autoconf/acgeneral.m4: Remove file. + * autoconf/acspecific.m4: Remove file. + * autoconf/autoconf.m4f: New file, from autoconf-2.52. + * autoconf/aclocal.m4: Require autoconf-2.52. + (CL_CANONICAL_HOST): Call AC_CANONICAL_HOST. Don't cache the result, + AC_CANONICAL_HOST does it itself. Add $SHELL in front of + $ac_config_guess and $ac_config_sub. + * Makefile.devel (AUTOCONF_FILES): Remove acgeneral.m4, acspecific.m4. + Add autoconf.m4f. + (configure): Use autoconf options -A, -l instead of -m. + * configure.in: Use AC_CONFIG_SUBDIRS, not AC_OUTPUT_SUBDIRS. + +2001-08-05 Bruno Haible + + * autoconf/acgeneral.m4 (AC_MSG_RESULTPROTO): Remove macro. + (AC_LANG_EXTERN): Move to aclocal.m4. + * autoconf/aclocal.m4 (AC_LANG_EXTERN): Moved here from acgeneral.m4. + (CL_PROTO): Use AC_MSG_RESULT directly, instead of AC_MSG_RESULTPROTO. + (CL_SILENT): No need to pushdef AC_MSG_RESULTPROTO. + +2001-08-05 Bruno Haible + + Make it possible to build libiconv with CC=gcc CFLAGS="-x c++". + * lib/loop_wchar.h (wchar_to_loop_convert): Rename local variable + 'try' to 'incount'. + * lib/Makefile.in (libiconv_plug_linux.so): Add "-x none" option + between sources and libs. + (libiconv_plug_solaris.so) [GCC]: Likewise. + (libiconv_plug_osf.so) [GCC]: Likewise. + * src/Makefile.in (iconv.@OBJEXT@): New rule. + (iconv): Depend on it. + (clean): Erase *.@OBJEXT@, not *.o. + * tests/Makefile.in (table-from.@OBJEXT@): New rule. + (table-from): Depend on it. + (table-to.@OBJEXT@): New rule. + (table-to): Depend on it. + (clean): Erase *.@OBJEXT@, not *.o. + +2001-07-28 Bruno Haible + + * tools/Makefile (iso8859_16.h): Generate from the unicode.org table. + * lib/iso8859_16.h: Regenerated. + * tests/ISO-8859-16.TXT: Swap the values of 0xA5 and 0xAB. + +2001-07-17 Bruno Haible + + * configure.in (VERSION): Define. Needed by djgpp/Makefile.maint. + +2001-07-03 Bruno Haible + + * configure.in: Also check for mbsinit. + * lib/loop_wchar.h (mbsinit): Define to 1 if not defined. + Needed for SCO 3.2v5.0.2. + +2001-06-27 Bruno Haible + + * Version 1.7 released. + +2001-06-27 Bruno Haible + + * INSTALL.generic (Particular Systems): Generalize section about + /usr/local to "most systems". + + * lib/Makefile.in (all): Build @PLUGLIB@ before libiconv.la, because + Solaris cc destroys iconv.o and iconv.lo while building + libiconv_plug_solaris.so. + (clean): Remove so_locations, left there by the OSF/1 linker. + + * lib/cp1255.h (cp1255_decomp): Use 'signed int' instead of 'int'. + + * lib/vietcomb.h (viet_decomp): Use 'unsigned int' instead of + 'unsigned short'. + + * tests/table-from.c: Include string.h. + * tests/table-to.c: Likewise. + +2001-06-26 Bruno Haible + + * tools/Makefile (jisx0208.h): Replace U+005C with U+FF3C. + (jisx0212.h): Replace U+007E with U+FF5E. + * lib/jisx0208.h: Regenerated. + * lib/jisx0212.h: Regenerated. + * tests/EUC-JP.TXT: Map 0xA1C0 to U+FF3C. Map 0x8FA2B7 to U+FF5E. + * tests/EUC-JP.IRREVERSIBLE.TXT: Remove file. + * tests/SHIFT-JIS.TXT: Map 0x815F to U+FF3C. + * tests/CP932.TXT: Likewise. + * tests/CP932.IRREVERSIBLE.TXT: 0x815F mapping is now reversible. + +2001-06-25 Bruno Haible + + * src/Makefile.in (iconv): Mention $(INCLUDES) before $(CFLAGS) and + $(CPPFLAGS). + * src/Makefile.msvc (iconv.exe): Likewise. + * src/Makefile.os2 (iconv.exe): Likewise. + * lib/Makefile.in (libiconv_plug_linux.so): Likewise. + (libiconv_plug_solaris.so): Likewise. + (libiconv_plug_osf.so): Likewise. + (iconv.lo): Likewise. + * lib/Makefile.msvc (iconv.obj): Likewise. + * lib/Makefile.os2 (iconv.obj): Likewise. + * tests/Makefile.in (table-from, table-to): Likewise. + * tests/Makefile.msvc (table-from.exe, table-to.exe): Likewise. + * tests/Makefile.os2 (table-from.exe, table-to.exe): Likewise. + (genutf8.exe): Don't use $(INCLUDES). + +2001-06-25 Bruno Haible + + * include/iconv.h.in (_LIBICONV_VERSION), README, windows/iconv.rc: + Bump version number. + * lib/Makefile.in (LIBICONV_VERSION_INFO): Define to 2:4:0. + +2001-06-25 Bruno Haible + + * Makefile.devel (OTHERMACROS): Use libtool.m4 in libcharset subdir. + +2001-06-25 Bruno Haible + + * lib/encodings.def: Make SHIFT_JIS the primary name of SJIS. + +2001-06-08 Bruno Haible + + * autoconf/ltmain.sh: Upgrade to libtool-1.4. + * autoconf/ltconfig: Remove file. + +2001-06-08 Bruno Haible + + * autoconf/config.guess: Update to GNU version 2001-05-11. + * autoconf/config.sub: Likewise. + +2001-06-03 Bruno Haible + + * lib/loop_unicode.h (unicode_loop_convert): Ignore Unicode 3.1 tag + characters if they cannot be converted. + (unicode_loop_reset): Likewise. + * lib/iso2022_jp2.h (STATE_TAG_NONE, STATE_TAG_LANGUAGE, + STATE_TAG_LANGUAGE_j, STATE_TAG_LANGUAGE_ja, STATE_TAG_LANGUAGE_k, + STATE_TAG_LANGUAGE_ko, STATE_TAG_LANGUAGE_z, STATE_TAG_LANGUAGE_zh): + New macros. + (SPLIT_STATE, COMBINE_STATE): Different differently for wctomb + direction. + (iso2022_jp2_wctomb): Keep track of Unicode 3.1 language tag. + If "ja", prefer conversion to Japanese character sets. If "zh", + prefer conversion to GB2312. If "ko", prefer conversion to KSC5601. + + * lib/converters.h (RET_ILUNI): Change value from 0 to -1. + (RET_TOOSMALL): Change value from -1 to -2. + * lib/loop_unicode.h (unicode_transliterate): Allow xxx_wctomb to + return 0 written bytes. + +2001-06-06 Bruno Haible + + * lib/encodings.def: Align with IANA character-set registry. + (US-ASCII): Add alias "ANSI_X3.4-1986". + (ISO-8859-14): Add alias "ISO-CELTIC". + (JIS_X0208): Add alias "JIS_C6226-1983". + (BIG5HKSCS): Add alias "BIG5-HKSCS". + * README, man/iconv_open.3: Rename BIG5HKSCS to BIG5-HKSCS. + * tests/Makefile.in (check): Likewise. + * tests/Makefile.os2 (check): Likewise. + * tests/Makefile.msvc (check): Likewise. + * tests/BIG5-HKSCS.TXT: Renamed from BIG5HKSCS.TXT. + * tests/BIG5-HKSCS.IRREVERSIBLE.TXT: Renamed from + BIG5HKSCS.IRREVERSIBLE.TXT. + +2001-06-02 Bruno Haible + + * tools/cjk_tab_to_h.c (Encoding): Add fffd field. + (is_charset2uni_large, compact_large_charset2uni): New functions. + (find_charset2uni_pages): Use enc->fffd instead of 0xfffd. + (output_charset2uni): If mapping to more than the Unicode BMP, + use an extra indirection to keep each value in 16 bits. + (invert): Bump limit from U+10000 to U+30000. + (output_uni2charset_dense): Likewise. + (output_uni2charset_sparse): Likewise. If mapping to more than one + CJK plane, use three bytes per value instead of two bytes. + (byte_row_cns11643): Allow more than 3 CJK planes. + (do_cns11643_only_uni2charset): Increase number of rows, to include + plane 15. Remove plane bits hack. + (main): Accept names cns11643_4a,4b,5,6,7,15 as well. + * tools/Makefile (ALL): Add cns11643_4a.h, cns11643_4b.h, cns11643_5.h, + cns11643_6.h, cns11643_7.h, cns11643_15.h. + (cns11643_1.h, cns11643_2.h, cns11643_3.h): Use new Unicode 3.1 + derived table. + (cns11643_4a.h, cns11643_4b.h, cns11643_5.h, cns11643_6.h, + cns11643_7.h, cns11643_15.h): New rules. + (cns11643_inv.h): Change title. + * lib/cns11643_1.h: Regenerated from Unicode 3.1 derived table. + * lib/cns11643_3.h: Likewise. + * lib/cns11643_4a.h: New file. + * lib/cns11643_4b.h: New file. + * lib/cns11643_4.h: New file. + * lib/cns11643_5.h: New file. + * lib/cns11643_6.h: New file. + * lib/cns11643_7.h: New file. + * lib/cns11643_15.h: New file. + * lib/cns11643_inv.h: Regenerated from Unicode 3.1 derived table. + (cns11643_inv_wctomb): Return 3 bytes now. + * lib/cns11643.h: Include cns11643_4.h, cns11643_5.h, cns11643_6.h, + cns11643_7.h, cns11643_15.h. + (cns11643_wctomb): Now a simple alias to cns11643_inv_wctomb. Return + plane number starting at 1, not 0. + * lib/dec_hanyu.h (dec_hanyu_wctomb): Update for cns11643_wctomb + change. + * lib/euc_tw.h (euc_tw_mbtowc): Accept CNS11643 planes 4,5,6,7,15 as + well. + (euc_tw_wctomb): Update for cns11643_wctomb change. + * lib/iso2022_cn.h (iso2022_cn_wctomb): Likewise. + * lib/iso2022_cnext.h (iso2022_cn_ext_mbtowc): Accept CNS11643 planes + 4,5,6,7 as well. + (iso2022_cn_ext_wctomb): Update for cns11643_wctomb change. + Try CNS11643 planes 4,5,6,7 as well. + * tests/EUC-TW.TXT: Many additions, mostly in planes 3,4,5,6,7,15. + * tests/EUC-TW.IRREVERSIBLE.TXT: Reflect additions to CNS11643 plane 1. + Add U+5344. + +2001-06-01 Bruno Haible + + * tests/table-from.c (bmp_only): New variable. + (ucs4_decode): If bmp_only, don't return characters outside Unicode + plane 0. + (main): When testing UTF-8 or GB18030, set bmp_only to 1. Don't print + a conversion line if ucs4_decode returns NULL. + * tests/table-to.c (main): When testing encodings other than UTF-8 and + GB18030, loop upto U+30000 instead of U+10000. + +2001-05-24 Bruno Haible + + * lib/converters.h (mbtowc_funcs): Add flushwc member function. + * lib/flushwc.h: New file. + * lib/cp1255.h: Include flushwc.h. + (cp1255_comp_table_data, cp1255_comp_table): New arrays. + (cp1255_mbtowc): Compose base and combining characters. + (cp1255_flushwc): New macro. + * lib/vietcomb.h (viet_comp_table_data, viet_comp_table): New arrays. + * lib/cp1258.h: Include flushwc.h. + (cp1258_mbtowc): Compose base and combining characters. + (cp1258_flushwc): New macro. + * lib/tcvn.h: Include flushwc.h. + (tcvn_mbtowc): Compose base and combining characters. + (tcvn_flushwc): New macro. + * lib/loop_unicode.h: (unicode_transliterate): New function, extracted + from unicode_loop_convert. + (unicode_loop_convert): Use unicode_transliterate. + (unicode_loop_reset): Call xxx_flushwc and output the resulting + character. + * lib/encodings.def: Add xxx_flushwc member. + * lib/encodings_aix.def: Likewise. + * lib/encodings_dos.def: Likewise. + * lib/encodings_local.def: Likewise. + * lib/encodings_osf1.def: Likewise. + * lib/genaliases.c: Add an argument to the DEFENCODING macro. + * lib/genaliases2.c: Likewise. + * lib/genflags.c: Likewise. + * lib/iconv.c: Likewise. + * tests/table-from.c (try): Reset the iconv descriptor before the main + call, and flush it afterwards. + (ucs4_decode): New function. + (main): Allow up to 3 Unicode characters output. Call ucs4_decode. + * tests/CP1255-snippet: New file. + * tests/CP1255-snippet.UTF-8: New file. + * tests/CP1258-snippet: New file. + * tests/CP1258-snippet.UTF-8: New file. + * tests/TCVN-snippet: New file. + * tests/TCVN-snippet.UTF-8: New file. + * tests/Makefile.in (check): Check combining behaviour of CP1255, + CP1258, TCVN. + * tests/Makefile.msvc (check): Likewise. + * tests/Makefile.os2 (check): Likewise. + +2001-05-22 Bruno Haible + + * lib/converters.h (RET_ILUNI): New macro. + (RET_ILSEQ): Change value to -1. + (RET_TOOFEW): Change value. + * lib/loop_unicode.h (unicode_loop_convert): Write RET_ILUNI instead + of 0. Update handling of xxx_mbtowc return value. + * lib/genflags.c (emit_encoding): Likewise. + * lib/ascii.h (ascii_wctomb): Use RET_ILUNI instead of RET_ILSEQ. + * lib/armscii_8.h (armscii_8_wctomb): Likewise. + * lib/big5.h (big5_wctomb): Likewise. + * lib/big5hkscs.h (big5hkscs_wctomb): Likewise. + * lib/ces_big5.h (ces_big5_wctomb): Likewise. + * lib/ces_gbk.h (ces_gbk_wctomb): Likewise. + * lib/cns11643.h (cns11643_wctomb): Likewise. + * lib/cns11643_inv.h (cns11643_inv_wctomb): Likewise. + * lib/cp437.h (cp437_wctomb): Likewise. + * lib/cp775.h (cp775_wctomb): Likewise. + * lib/cp850.h (cp850_wctomb): Likewise. + * lib/cp852.h (cp852_wctomb): Likewise. + * lib/cp855.h (cp855_wctomb): Likewise. + * lib/cp856.h (cp856_wctomb): Likewise. + * lib/cp857.h (cp857_wctomb): Likewise. + * lib/cp861.h (cp861_wctomb): Likewise. + * lib/cp862.h (cp862_wctomb): Likewise. + * lib/cp864.h (cp864_wctomb): Likewise. + * lib/cp865.h (cp865_wctomb): Likewise. + * lib/cp866.h (cp866_wctomb): Likewise. + * lib/cp869.h (cp869_wctomb): Likewise. + * lib/cp874.h (cp874_wctomb): Likewise. + * lib/cp922.h (cp922_wctomb): Likewise. + * lib/cp932ext.h (cp932ext_wctomb): Likewise. + * lib/cp932.h (cp932_wctomb): Likewise. + * lib/cp936ext.h (cp936ext_wctomb): Likewise. + * lib/cp949.h (cp949_wctomb): Likewise. + * lib/cp950ext.h (cp950ext_wctomb): Likewise. + * lib/cp950.h (cp950_wctomb): Likewise. + * lib/cp1046.h (cp1046_wctomb): Likewise. + * lib/cp1124.h (cp1124_wctomb): Likewise. + * lib/cp1129.h (cp1129_wctomb): Likewise. + * lib/cp1133.h (cp1133_wctomb): Likewise. + * lib/cp1250.h (cp1250_wctomb): Likewise. + * lib/cp1251.h (cp1251_wctomb): Likewise. + * lib/cp1252.h (cp1252_wctomb): Likewise. + * lib/cp1253.h (cp1253_wctomb): Likewise. + * lib/cp1254.h (cp1254_wctomb): Likewise. + * lib/cp1255.h (cp1255_wctomb): Likewise. + * lib/cp1256.h (cp1256_wctomb): Likewise. + * lib/cp1257.h (cp1257_wctomb): Likewise. + * lib/cp1258.h (cp1258_wctomb): Likewise. + * lib/dec_hanyu.h (dec_hanyu_wctomb): Likewise. + * lib/dec_kanji.h (dec_kanji_wctomb): Likewise. + * lib/euc_cn.h (euc_cn_wctomb): Likewise. + * lib/euc_jp.h (euc_jp_wctomb): Likewise. + * lib/euc_kr.h (euc_kr_wctomb): Likewise. + * lib/euc_tw.h (euc_tw_wctomb): Likewise. + * lib/gb12345ext.h (gb12345ext_wctomb): Likewise. + * lib/gb12345.h (gb12345_wctomb): Likewise. + * lib/gb18030ext.h (gb18030ext_wctomb): Likewise. + * lib/gb18030.h (gb18030_wctomb): Likewise. + * lib/gb18030uni.h (gb18030uni_wctomb): Likewise. + * lib/gb2312.h (gb2312_wctomb): Likewise. + * lib/gbkext_inv.h (gbkext_inv_wctomb): Likewise. + * lib/gbk.h (gbk_wctomb): Likewise. + * lib/georgian_academy.h (georgian_academy_wctomb): Likewise. + * lib/georgian_ps.h (georgian_ps_wctomb): Likewise. + * lib/hkscs.h (hkscs_wctomb): Likewise. + * lib/hp_roman8.h (hp_roman8_wctomb): Likewise. + * lib/hz.h (hz_wctomb): Likewise. + * lib/iso2022_cnext.h (iso2022_cn_ext_wctomb): Likewise. + * lib/iso2022_cn.h (iso2022_cn_wctomb): Likewise. + * lib/iso2022_jp1.h (iso2022_jp1_wctomb): Likewise. + * lib/iso2022_jp2.h (iso2022_jp2_wctomb): Likewise. + * lib/iso2022_jp.h (iso2022_jp_wctomb): Likewise. + * lib/iso2022_kr.h (iso2022_kr_wctomb): Likewise. + * lib/iso646_cn.h (iso646_cn_wctomb): Likewise. + * lib/iso646_jp.h (iso646_jp_wctomb): Likewise. + * lib/iso8859_1.h (iso8859_1_wctomb): Likewise. + * lib/iso8859_2.h (iso8859_2_wctomb): Likewise. + * lib/iso8859_3.h (iso8859_3_wctomb): Likewise. + * lib/iso8859_4.h (iso8859_4_wctomb): Likewise. + * lib/iso8859_5.h (iso8859_5_wctomb): Likewise. + * lib/iso8859_6.h (iso8859_6_wctomb): Likewise. + * lib/iso8859_7.h (iso8859_7_wctomb): Likewise. + * lib/iso8859_8.h (iso8859_8_wctomb): Likewise. + * lib/iso8859_9.h (iso8859_9_wctomb): Likewise. + * lib/iso8859_10.h (iso8859_10_wctomb): Likewise. + * lib/iso8859_13.h (iso8859_13_wctomb): Likewise. + * lib/iso8859_14.h (iso8859_14_wctomb): Likewise. + * lib/iso8859_15.h (iso8859_15_wctomb): Likewise. + * lib/iso8859_16.h (iso8859_16_wctomb): Likewise. + * lib/isoir165ext.h (isoir165ext_wctomb): Likewise. + * lib/isoir165.h (isoir165_wctomb): Likewise. + * lib/jisx0201.h (jisx0201_wctomb): Likewise. + * lib/jisx0208.h (jisx0208_wctomb): Likewise. + * lib/jisx0212.h (jisx0212_wctomb): Likewise. + * lib/johab.h (johab_wctomb): Likewise. + * lib/johab_hangul.h (johab_hangul_wctomb, johab_hangul_decompose): + Likewise. + * lib/koi8_r.h (koi8_r_wctomb): Likewise. + * lib/koi8_ru.h (koi8_ru_wctomb): Likewise. + * lib/koi8_u.h (koi8_u_wctomb): Likewise. + * lib/ksc5601.h (ksc5601_wctomb): Likewise. + * lib/mac_arabic.h (mac_arabic_wctomb): Likewise. + * lib/mac_centraleurope.h (mac_centraleurope_wctomb): Likewise. + * lib/mac_croatian.h (mac_croatian_wctomb): Likewise. + * lib/mac_cyrillic.h (mac_cyrillic_wctomb): Likewise. + * lib/mac_greek.h (mac_greek_wctomb): Likewise. + * lib/mac_hebrew.h (mac_hebrew_wctomb): Likewise. + * lib/mac_iceland.h (mac_iceland_wctomb): Likewise. + * lib/mac_roman.h (mac_roman_wctomb): Likewise. + * lib/mac_romania.h (mac_romania_wctomb): Likewise. + * lib/mac_thai.h (mac_thai_wctomb): Likewise. + * lib/mac_turkish.h (mac_turkish_wctomb): Likewise. + * lib/mac_ukraine.h (mac_ukraine_wctomb): Likewise. + * lib/mulelao.h (mulelao_wctomb): Likewise. + * lib/nextstep.h (nextstep_wctomb): Likewise. + * lib/sjis.h (sjis_wctomb): Likewise. + * lib/tcvn.h (tcvn_wctomb): Likewise. + * lib/tis620.h (tis620_wctomb): Likewise. + * lib/ucs2be.h (ucs2be_wctomb): Likewise. + * lib/ucs2.h (ucs2_wctomb): Likewise. + * lib/ucs2internal.h (ucs2internal_wctomb): Likewise. + * lib/ucs2le.h (ucs2le_wctomb): Likewise. + * lib/ucs2swapped.h (ucs2swapped_wctomb): Likewise. + * lib/ucs4.h (ucs4_wctomb): Likewise. + * lib/uhc_1.h (uhc_1_wctomb): Likewise. + * lib/uhc_2.h (uhc_2_wctomb): Likewise. + * lib/utf16be.h (utf16be_wctomb): Likewise. + * lib/utf16.h (utf16_wctomb): Likewise. + * lib/utf16le.h (utf16le_wctomb): Likewise. + * lib/utf32be.h (utf32be_wctomb): Likewise. + * lib/utf32.h (utf32_wctomb): Likewise. + * lib/utf32le.h (utf32le_wctomb): Likewise. + * lib/utf7.h (utf7_wctomb): Likewise. + * lib/utf8.h (utf8_wctomb): Likewise. + * lib/viscii.h (viscii_wctomb): Likewise. + * tools/8bit_tab_to_h.c (main): Likewise. + * tools/cjk_tab_to_h.c (output_uni2charset_dense, + output_uni2charset_sparse, do_gb18030uni): Likewise. + +2001-05-19 Bruno Haible + + * Makefile.devel (all): Add man/{iconv.1,iconv*.3}.html. + (man/%.html): New rule. + * man/Makefile.in (docdir, htmldir): New variables. + (install, installdirs): Install the HTML formatted man pages in + $(htmldir). + (uninstall): Uninstall them. + +2001-05-20 Bruno Haible + + * lib/cp1255.h (cp1255_decomp_table): New array. + (cp1255_comb_table): New array. + (cp1255_wctomb): Decompose Unicode characters. + * tests/CP1255.IRREVERSIBLE.TXT: New file. + +2001-05-13 Bruno Haible + + * lib/vietcomb.h: New file. + * lib/cp1258.h: Include it. + (cp1258_comb_table): New array. + (cp1258_wctomb): Decompose Unicode characters. + * lib/tcvn.h: Include it. + (tcvn_comb_table): New array. + (tcvn_wctomb): Decompose Unicode characters. + * tests/CP1258.IRREVERSIBLE.TXT: New file. + * tests/TCVN.IRREVERSIBLE.TXT: New file. + +2001-05-06 Bruno Haible + + * lib/Makefile.msvc (config.h): Allow the 'del' command to fail. + (iconv.lib): Likewise. + +2001-05-06 Bruno Haible + + * lib/Makefile.in (CPPFLAGS, LDFLAGS): New variables. + (CPP): Remove variable. + (libiconv.la, libiconv_plug_linux.so, libiconv_plug_solaris.so, + libiconv_plug_osf.so): Use LDFLAGS. + (libiconv_plug_linux.so, libiconv_plug_solaris.so, + libiconv_plug_osf.so, iconv.lo): Use CPPFLAGS. + * lib/Makefile.msvc (CPP): Remove variable. + * src/Makefile.in (CPPFLAGS, LDFLAGS): New variables. + (CPP): Remove variable. + (iconv): Use CPPFLAGS and LDFLAGS. + * src/Makefile.msvc (CPP): Remove variable. + * tests/Makefile.in (CPPFLAGS, LDFLAGS): New variables. + (check, table-from, table-to): Use CPPFLAGS and LDFLAGS. + * tests/Makefile.msvc (CPP): Remove variable. + +2001-05-06 Bruno Haible + + * lib/Makefile.in (libiconv_plug_solaris.so): Change rule if not using + gcc. Reported by Paananen Mikko . + +2001-04-11 Bruno Haible + + Implement and document UTF-32, UTF-32BE, UTF-32LE. + * src/utf32.h, src/utf32be.h, src/utf32le.h: New files. + * src/converters.h: Include them. + * src/encodings.def (UTF-32, UTF-32BE, UTF32LE): New encodings. + * README, man/iconv_open.3: Add UTF-32, UTF-32BE, UTF32LE. + * tests/Makefile.in (check): Check UTF-32, UTF-32BE, UTF32LE. + * tests/Makefile.os2 (check): Likewise. + * tests/Makefile.msvc (check): Likewise. + * tests/UTF-32*snippet*: New files. + + * lib/ucs4.h (ucs4_mbtowc): Fix value of other-endian byte order. + (ucs4_wctomb): Allow any 31-bit codepoint. + +2001-04-11 Bruno Haible + + * tests/GB18030.TXT: Add mappings for all of U+0000..U+FFFF, including + unassigned code points. + * tests/table-from.c (main); When dumping GB18030, don't print code + points larger than U+FFFF. + +2001-03-30 Bruno Haible + + * tools/Makefile (GB18030uni.TXT): Use a table source which includes + the unassigned Unicode code points. + * lib/gb18030uni.h: Update. + (gb18030uni_ranges): Remove bitmap_offset field. + (gb18030uni_bitmap): Remove array. + (gb18030uni_mbtowc): Omit gb18030uni_bitmap access. + (gb18030uni_wctomb): Likewise. + * lib/gb18030.h (gb18030_mbtowc): Handle Unicode characters >= 0x10000. + (gb18030_wctomb): Likewise. + +2001-03-21 Bruno Haible + + * INSTALL.generic (Particular Systems): Add recommendations for AIX 3. + +2001-03-21 Bruno Haible + + * src/iconv.c (print_version): Now called GNU libiconv. + +2001-03-20 Bruno Haible + + * README: This package is now called GNU libiconv. + + * tools/8bit_tab_to_h.c (main): Emit copyright notice to the output + file. + * tools/cjk_tab_to_h.c (output_title): Likewise. + * tools/cjk_variants.c (main): Likewise. + * lib/gentranslit.c (main): Likewise. + +2001-03-19 Bruno Haible + + * autoconf/aclocal.m4 (CL_CANONICAL_HOST): Always define + ac_config_guess and ac_config_sub. Then ignore requests for + AC_CONFIG_AUX_DIR_DEFAULT or AC_CANONICAL_HOST. + +2001-03-10 Bruno Haible + + * INSTALL.generic: New section "Particular Systems". + +2001-03-10 Bruno Haible + + * lib/Makefile.in (libiconv.la): Pass flag -no-undefined. Needed on + platforms like BeOS. + + * lib/loop_wchar.h (mbstate_t): Don't typedef if already #defined in + config.h. + +2001-03-06 Bruno Haible + + * Version 1.6 released. + * include/iconv.h.in (_LIBICONV_VERSION), README, windows/iconv.rc: + Bump version number. + * lib/Makefile.in (LIBICONV_VERSION_INFO): Define to 2:3:0. + +2001-03-05 Bruno Haible + + Provide all encodings used by OSF/1 5.1 locales. + * lib/dec_kanji.h: New file. + * lib/dec_hanyu.h: New file. + * lib/converters.h: Include them if USE_OSF1 is defined. + * lib/encodings_osf1.def: New file. + * lib/genflags.c (main): Include it. Define USE_OSF1. + * lib/genaliases2.c (main): Include it conditionally. + * lib/iconv.c: Define USE_OSF1 on OSF/1. + Include encodings_osf1.def and aliases_osf1.h. + * lib/Makefile.in (iconv.lo): Depend on encodings_osf1.def and + aliases_osf1.h. + * Makefile.devel (lib/aliases_osf1.h): New target. + (all): Depend on lib/aliases_osf1.h. + (lib/flags.h): Depend on lib/encodings_osf1.def. + +2001-03-01 Bruno Haible + + * tools/Makefile (cp775.h): New target. + (ALL): Add it. + * lib/cp775.h: New file. + * lib/converters.h: Include it. + * lib/encodings_dos.def (CP775): New encoding. + +2001-02-25 Bruno Haible + + * lib/iconv.c (iconv_open): locale_charset() doesn't return NULL any + more. + +2001-02-24 Bruno Haible + + * src/iconv.c (convert): Use ICONV_CONST. + * tests/table-from.c: Include config.h. + (try): Use ICONV_CONST. + * tests/table-to.c: Include config.h. + (main): Use ICONV_CONST. + * tests/Makefile.in (INCLUDES): Add -I../lib. + * tests/Makefile.os2 (INCLUDES): Likewise. + * tests/Makefile.msvc (INCLUDES): Add -I..\lib. + +2001-02-24 Bruno Haible + + Provide all encodings used by DOS locales. + * tools/Makefile (cp437.h, cp852.h, cp855.h, cp857.h, cp861.h, + cp864.h, cp865.h, cp869.h): New targets. + (ALL): Add them. + * lib/cp437.h: New file. + * lib/cp852.h: New file. + * lib/cp855.h: New file. + * lib/cp857.h: New file. + * lib/cp861.h: New file. + * lib/cp864.h: New file. + * lib/cp865.h: New file. + * lib/cp869.h: New file. + * lib/converters.h: Include them if USE_DOS is defined. + * lib/encodings_dos.def: New file. + * lib/genflags.c (main): Include it. Define USE_DOS. + * lib/genaliases2.c (main): Include it conditionally. + * lib/iconv.c: Define USE_DOS on DJGPP. + Include encodings_dos.def and aliases_dos.h. + * lib/Makefile.in (iconv.lo): Depend on encodings_dos.def and + aliases_dos.h. + * Makefile.devel (lib/aliases_dos.h): New target. + (all): Depend on lib/aliases_dos.h. + (lib/flags.h): Depend on lib/encodings_dos.def. + +2001-02-23 Bruno Haible + + * src/iconv.c [DJGPP]: Include and . + (SET_BINARY) [O_BINARY]: New macro. + (usage): Mention --binary if available. + (convert): Use SET_BINARY instead of setmode. + (main): Likewise. + Reported by Juan Manuel Guerrero . + +2001-02-25 Bruno Haible + + * autoconf/ltconfig: + sed -e 's/reload object files/produce relocatable object files/'. + +2001-02-20 Bruno Haible + + * src/iconv.c (usage, main): Make -f and -t options optional. + * man/iconv.1: Mark them as optional. + +2001-02-20 Bruno Haible + + * tools/Makefile (GB18030ext.TXT, GB18030uni.TXT): Generate from + glibc-2.2.2 table. + * lib/gb18030uni.h, lib/gb18030ext.h: Add mapping 0xA989 -> U+303E, + 0xFE5E -> U+2E97. Shift the entire four-byte range. + * tests/GB18030.TXT: Regenerated. + +2001-02-20 Bruno Haible + + Better support for DOS/Windows platforms. + * autoconf/ltconfig: Upgrade to libtool-1.3.5. + * autoconf/ltmain.sh: Likewise. + * autoconf/aclocal.m4: Likewise. + * autoconf/install-sh: New file. + * configure.in: Call AC_OBJEXT and AC_EXEEXT. Call AC_CONFIG_AUX_DIR. + +2001-02-20 Bruno Haible + + * Makefile.in (libdir, includedir, mandir): Use the autoconf + determined value, in order to respect the configure arguments. + * lib/Makefile.in (libdir): Likewise. + * src/Makefile.in (bindir): Likewise. + * man/Makefile.in (mandir): Likewise. + +2001-02-04 Bruno Haible + + * lib/translit.def: Add all the neutral transliterations from glibc. + * lib/gentranslit.c (main): Allow UTF-8 replacements which are in + UCS-2 but not in ISO-8859-1. Generate a table of 'unsigned short'. + Avoid accessing data[-1]. + * lib/loop_unicode.h (unicode_loop_convert): Change type of pointer + into translit_data. + +2001-01-05 Bruno Haible + + Implement and document CP862. + * tools/Makefile (ALL): Add cp862.h. + (cp862.h): New target. + * lib/cp862.h: New file. + * lib/converters.h: Include it. + * lib/encodings.def (CP862): New encoding. + * README, man/iconv_open.3: Add CP862. + * tests/Makefile.in (check): Check CP862. + * tests/Makefile.msvc (check): Likewise. + * tests/Makefile.os2 (check): Likewise. + * tests/CP862.TXT: New file. + +2000-12-18 Bruno Haible + + * autoconf/mbstate_t.m4: New file, from textutils-2.0.10. + * Makefile.devel (OTHERMACROS): Add it. + * configure.in: Call AC_MBSTATE_T. + * lib/config.h.in (mbstate_t): New definition. + * lib/loop_wchar.h (mbrtowc): For BeOS, declare and define fallback. + +2000-12-12 Bruno Haible + + * Makefile.in: Use $(MAKE) instead of $(MAKE) -r. Needed with Solaris + "make", which doesn't set MAKE as expected by @SET_MAKE@ if -r is + given. Reported by Toshimitsu Fujiwara. + +2000-12-08 Bruno Haible + + * Makefile.in (exec_prefix): Use configure's --exec-prefix argument. + * lib/Makefile.in (exec_prefix): Likewise. + * src/Makefile.in (exec_prefix): Likewise. + * man/Makefile.in (exec_prefix): Likewise. + +2000-12-02 Bruno Haible + + * Version 1.5 released. + * include/iconv.h.in (_LIBICONV_VERSION), README, windows/iconv.rc: + Bump version number. + * lib/Makefile.in (LIBICONV_VERSION_INFO): Define to 2:2:0. + +2000-12-02 Bruno Haible + + * Makefile.in (mostlyclean, clean, distclean, maintainer-clean): + Remove files installed in lib by libcharset. + * Makefile.msvc (mostlyclean): Likewise. + + * Makefile.in (check): Depend on target 'all'. + * Makefile.os2 (check): Likewise. + * Makefile.msvc (check): Depend on target 'force' as well. + + * src/iconv.c (usage): Take an exitcode argument. + (print_version): New function. + (main): Recognize --help and --version command line options. + +2000-12-02 Bruno Haible + + * Makefile.msvc: Replace STATIC with its opposite flag, DLL. + * lib/Makefile.msvc: Likewise. + * src/Makefile.msvc: Likewise. + * tests/Makefile.msvc: Likewise. + +2000-12-01 Bruno Haible + + * src/iconv.c: Include . Define fallbacks for setmode, fileno. + (force_binary): New variable. + (convert): If requested, set the input O_BINARY. + (main): Accept --binary option. If requested, set the output O_BINARY. + * tests/check-stateful.bat: Pass --binary to iconv. + * tests/check-stateful.cmd: Likewise. + * tests/check-translit.bat: Likewise. + * tests/check-translit.cmd: Likewise. + +2000-12-01 Bruno Haible + + * include/iconv.h.in (_libiconv_version): New declaration. + * lib/iconv.c (_libiconv_version): New variable. + +2000-11-30 Bruno Haible + + * Makefile.msvc (all): File now named lib/libcharset.h. + (clean, distclean, maintainer-clean): Likewise. + +2000-11-23 Bruno Haible + + * lib/*: Move here all files from src/*. + * src/*: Move all files to lib. + * lib/Makefile.in (distclean): No need to remove config.status, + config.log, config.cache. + * configure.in: Require lib/iconv.c, not src/iconv.c. Create + lib/config.h, not src/config.h. Also create lib/Makefile. + * Makefile.in (all): Install libcharset into lib, not src. Recurse + into lib and src. + (install-lib): Recurse into lib, not src. + (install): Recurse into libcharset, lib and src. + (installdirs, uninstall): Likewise. + (check, mostlyclean, clean, distclean, maintainer-clean): Likewise. + * Makefile.msvc (all): Recurse into lib and src. + (install): Recurse into libcharset, lib and src. + (installdirs, uninstall): Likewise. + (check, mostlyclean, clean, distclean, maintainer-clean): Likewise. + * Makefile.os2 (all): Recurse into lib and src. + (install-lib): Recurse into lib, not src. + (install, uninstall): Recurse into lib and src. + (check, mostlyclean, clean, distclean, maintainer-clean): Likewise. + * Makefile.devel (lib/config.h.msvc): Renamed from src/config.h.msvc. + (lib/aliases.h): Renamed from src/aliases.h. + (lib/aliases.gperf): Renamed from src/aliases.gperf. + (lib/aliases_aix.h): Renamed from src/aliases_aix.h. + (lib/flags.h): Renamed from src/flags.h. + (lib/translit.h): Renamed from src/translit.h. + * src/iconv.c: Moved here from tests/iconv.c. + * src/Makefile.in: New file. + * src/Makefile.msvc: New file. + * src/Makefile.os2: New file. + * tests/Makefile.in (iconv): Remove target. + (../lib/libiconv.la): Renamed from ../src/libiconv.la. + (clean): No need to remove iconv. + * tests/Makefile.msvc (iconv.exe): Remove target. + * tests/Makefile.os2 (iconv.exe): Likewise. + * tests/check-stateful: iconv is in ../src. + * tests/check-stateful.bat: Likewise. + * tests/check-stateful.cmd: Likewise. + * tests/check-translit: iconv is in ../src. + * tests/check-translit.bat: Likewise. + * tests/check-translit.cmd: Likewise. + * man/iconv.1: New file. + * man/Makefile.in (install, installdirs, uninstall): Also install *.1 + man pages. + * man/Makefile.os2 (MAN3): Renamed from MAN. + (MAN1): New variable. + (install, uninstall): Also install *.1 man pages. + +2000-11-21 Bruno Haible + + * Makefile.msvc (all, check, mostlyclean, clean, distclean, + maintainer-clean): Recurse into libcharset. + (clean, distclean, maintainer-clean): Remove src\libcharset.h. + * src/Makefile.msvc (LIBCHARSET_OBJECTS): New variable. + (iconv.lib): Link with $(LIBCHARSET_OBJECTS). + +2000-11-18 Bruno Haible + + * src/cp950.h (cp950_mbtowc, cp950_wctomb): Change implementation + so that it agrees with Microsoft's definition of CP950. + * tests/CP950.TXT: Likewise. + * tests/CP950.IRREVERSIBLE.TXT: Add 0xA244, 0xA2CC, 0xA2CE. + +2000-11-18 Bruno Haible + + Add support for locale dependent "char" and "wchar_t" encodings. + * libcharset: New subdirectory. + * src/loop_unicode.h: New file, extracted from src/iconv.c. + * src/loop_wchar.h: New file. + * src/loops.h: New file. Include loop_unicode.h and loop_wchar.h. + * src/encodings_local.def: New file. + * src/genaliases.c: Also create aliases for encodings_local.def. + * src/converters.h (conv_struct): Add lfuncs field. + * src/genflags.c: Add dummy definitions of struct loop_funcs. + * src/iconv.c: Include libcharset.h. + (loop_funcs): New structure. + Treat encodings_local.def like encodings.def. + Include loops.h. + (iconv_open): Move the bulk of the code to loop_unicode.h. + (iconv): Likewise. + (iconvctl): Extend determination of TRIVIALP to wchar_t conversion + descriptors. + * src/Makefile.in (PLUG_SOURCES): Remove variable. + (LIBCHARSET_OBJECTS): New variable. + (libiconv.la): Link in the LIBCHARSET_OBJECTS. + (libiconv_plug_linux.so, libiconv_plug_solaris.so, + libiconv_plug_osf.so): Link in the LIBCHARSET_OBJECTS, using + LIBTOOL_LINK. + (iconv.lo): Depend on encodings_local.def. + * src/Makefile.msvc (iconv.obj): Depend on encodings_local.def. + * src/Makefile.os2 (iconv.obj): Likewise. + * configure.in: Add tests for locale.h, mbrtowc, wcrtomb, setlocale. + Recurse into libcharset. + * src/config.h.in (HAVE_LOCALE_H, HAVE_MBRTOWC, HAVE_WCRTOMB, + HAVE_SETLOCALE): New macros. + * tests/iconv.c: Include config.h and locale.h. + (main): Call setlocale. + * tests/Makefile.in (iconv): Search for config.h in ../src. + * tests/Makefile.os2 (iconv.exe): Likewise. + * tests/Makefile.msvc (iconv.exe): Likewise. + * README, man/iconv_open.3: Document "char" and "wchar_t" encodings. + * Makefile.in: After "cd", use "&&" not ";". + (all, check, mostlyclean, clean, distclean, maintainer-clean): + Recurse into libcharset. + * Makefile.devel (all): Recurse into libcharset. + (src/aliases.gperf): Depend on src/encodings_local.def. + +2000-11-18 Bruno Haible + + * src/converters.h (ucs4_t): New type. + (wchar_t): Remove locally defined override. + (mbtowc_funcs, wctomb_funcs): Use ucs4_t instead of wchar_t. + * src/iconv.c (iconv): Likewise. + * src/genflags.c (emit_encoding): Use ucs4_t instead of wchar_t. + * tools/8bit_tab_to_h.c: Use "ucs4_t" instead of "wchar_t". + * tools/cjk_tab_to_h.c: Likewise. + * src/armscii_8.h: Use ucs4_t instead of wchar_t. + * src/ascii.h: Likewise. + * src/big5.h: Likewise. + * src/big5hkscs.h: Likewise. + * src/ces_big5.h: Likewise. + * src/ces_gbk.h: Likewise. + * src/cns11643.h: Likewise. + * src/cns11643_1.h: Likewise. + * src/cns11643_2.h: Likewise. + * src/cns11643_3.h: Likewise. + * src/cns11643_inv.h: Likewise. + * src/cp1046.h: Likewise. + * src/cp1124.h: Likewise. + * src/cp1129.h: Likewise. + * src/cp1133.h: Likewise. + * src/cp1250.h: Likewise. + * src/cp1251.h: Likewise. + * src/cp1252.h: Likewise. + * src/cp1253.h: Likewise. + * src/cp1254.h: Likewise. + * src/cp1255.h: Likewise. + * src/cp1256.h: Likewise. + * src/cp1257.h: Likewise. + * src/cp1258.h: Likewise. + * src/cp850.h: Likewise. + * src/cp856.h: Likewise. + * src/cp866.h: Likewise. + * src/cp874.h: Likewise. + * src/cp922.h: Likewise. + * src/cp932.h: Likewise. + * src/cp932ext.h: Likewise. + * src/cp936ext.h: Likewise. + * src/cp949.h: Likewise. + * src/cp950.h: Likewise. + * src/cp950ext.h: Likewise. + * src/euc_cn.h: Likewise. + * src/euc_jp.h: Likewise. + * src/euc_kr.h: Likewise. + * src/euc_tw.h: Likewise. + * src/gb12345.h: Likewise. + * src/gb12345ext.h: Likewise. + * src/gb18030.h: Likewise. + * src/gb18030ext.h: Likewise. + * src/gb18030uni.h: Likewise. + * src/gb2312.h: Likewise. + * src/gbk.h: Likewise. + * src/gbkext1.h: Likewise. + * src/gbkext2.h: Likewise. + * src/gbkext_inv.h: Likewise. + * src/georgian_academy.h: Likewise. + * src/georgian_ps.h: Likewise. + * src/hkscs.h: Likewise. + * src/hp_roman8.h: Likewise. + * src/hz.h: Likewise. + * src/iso2022_cn.h: Likewise. + * src/iso2022_cnext.h: Likewise. + * src/iso2022_jp.h: Likewise. + * src/iso2022_jp1.h: Likewise. + * src/iso2022_jp2.h: Likewise. + * src/iso2022_kr.h: Likewise. + * src/iso646_cn.h: Likewise. + * src/iso646_jp.h: Likewise. + * src/iso8859_1.h: Likewise. + * src/iso8859_10.h: Likewise. + * src/iso8859_13.h: Likewise. + * src/iso8859_14.h: Likewise. + * src/iso8859_15.h: Likewise. + * src/iso8859_16.h: Likewise. + * src/iso8859_2.h: Likewise. + * src/iso8859_3.h: Likewise. + * src/iso8859_4.h: Likewise. + * src/iso8859_5.h: Likewise. + * src/iso8859_6.h: Likewise. + * src/iso8859_7.h: Likewise. + * src/iso8859_8.h: Likewise. + * src/iso8859_9.h: Likewise. + * src/isoir165.h: Likewise. + * src/isoir165ext.h: Likewise. + * src/java.h: Likewise. + * src/jisx0201.h: Likewise. + * src/jisx0208.h: Likewise. + * src/jisx0212.h: Likewise. + * src/johab.h: Likewise. + * src/johab_hangul.h: Likewise. + * src/koi8_r.h: Likewise. + * src/koi8_ru.h: Likewise. + * src/koi8_u.h: Likewise. + * src/ksc5601.h: Likewise. + * src/mac_arabic.h: Likewise. + * src/mac_centraleurope.h: Likewise. + * src/mac_croatian.h: Likewise. + * src/mac_cyrillic.h: Likewise. + * src/mac_greek.h: Likewise. + * src/mac_hebrew.h: Likewise. + * src/mac_iceland.h: Likewise. + * src/mac_roman.h: Likewise. + * src/mac_romania.h: Likewise. + * src/mac_thai.h: Likewise. + * src/mac_turkish.h: Likewise. + * src/mac_ukraine.h: Likewise. + * src/mulelao.h: Likewise. + * src/nextstep.h: Likewise. + * src/sjis.h: Likewise. + * src/tcvn.h: Likewise. + * src/tis620.h: Likewise. + * src/ucs2.h: Likewise. + * src/ucs2be.h: Likewise. + * src/ucs2internal.h: Likewise. + * src/ucs2le.h: Likewise. + * src/ucs2swapped.h: Likewise. + * src/ucs4.h: Likewise. + * src/ucs4be.h: Likewise. + * src/ucs4internal.h: Likewise. + * src/ucs4le.h: Likewise. + * src/ucs4swapped.h: Likewise. + * src/uhc_1.h: Likewise. + * src/uhc_2.h: Likewise. + * src/utf16.h: Likewise. + * src/utf16be.h: Likewise. + * src/utf16le.h: Likewise. + * src/utf7.h: Likewise. + * src/utf8.h: Likewise. + * src/viscii.h: Likewise. + +2000-11-18 Bruno Haible + + Make transliteration optional. + * src/iconv.c (iconv_open): Strip off //TRANSLIT suffix from names. + Set transliteration on if and only if tocode ends in //TRANSLIT. + * README, man/iconv_open.3: Document how to enable transliteration. + * tests/check-translit: Add //TRANSLIT to iconv's 't' argument. + * tests/check-translit.bat: Likewise. + * tests/check-translit.cmd: Likewise. + +2000-11-18 Bruno Haible + + * man/iconv.3: Fix typo. + +2000-10-31 Bruno Haible + + * README, man/iconv_open.3: Document JOHAB again. + +2000-11-15 Bruno Haible + + * Makefile.msvc: Add support for MFLAGS and DEBUG parameters. + (STATIC): Change default from 0 to 1. + * src/Makefile.msvc: Likewise. + * tests/Makefile.msvc: Likewise. + * tests/check-stateless.bat: Call 'sort' with no arguments. + +2000-11-12 Bruno Haible + + * autoconf/config.guess, autoconf/config.sub: Upgrade to newest + version from GNU CVS. + +2000-10-24 Bruno Haible + + * Version 1.4 released. + * include/iconv.h.in (_LIBICONV_VERSION), README, windows/iconv.rc: + Bump version number. + * src/Makefile.in (LIBICONV_VERSION_INFO): Define to 2:1:0. + +2000-10-23 Bruno Haible + + Implement and document GB18030 and BIG5HKSCS. + * tools/cjk_tab_to_h.c (row_byte_hkscs, byte_row_hkscs, do_hkscs): New + functions. + (do_gb18030uni): New function. + (main): Accept gb18030ext, gb18030uni, hkscs. + * tools/Makefile (ALL): Add gb18030ext.h, gb18030uni.h, hkscs.h. + (gb18030ext.h, GB18030ext.TXT, gb18030uni.h, GB18030uni.TXT, + hkscs.h): New targets. + * src/gb18030ext.h, src/gb18030uni.h, src/gb18030.h: New files. + * src/hkscs.h, src/big5hkscs.h: New files. + * src/converters.h: Include gb18030.h and big5hkscs.h. + * src/encodings.def (GB18030, BIG5HKSCS): New encodings. + * README, man/iconv_open.3: Add GB18030, BIG5HKSCS. + * tests/Makefile.in (check): Check GB18030, BIG5HKSCS. + * tests/Makefile.msvc (check): Likewise. + * tests/Makefile.os2 (check): Likewise. + * tests/GB18030.TXT: New file. + * tests/BIG5HKSCS.TXT, tests/BIG5HKSCS.IRREVERSIBLE.TXT: New files. + +2000-10-23 Bruno Haible + + * tests/table-from.c (try, main): Use UCS-4-INTERNAL instead of + UCS-2-INTERNAL, to avoid problems with UCS-2 surrogate handling. + * tests/table-to.c (main): Likewise. + +2000-10-22 Bruno Haible + + * src/gentranslit.c (main): Read the input in UTF-8 encoding. + +2000-10-09 Bruno Haible + + CPU recognition on OpenBSD. + * autoconf/aclocal.m4 (CL_WORDS_LITTLEENDIAN): Recognize __m68k__, + __mc68020__, __MIPSEB__, __MIPSEL__, __m88k__ as CPU indicators. + +2000-10-03 Bruno Haible + + * src/gentranslit.c (main): Don't output non-ASCII ISO-8859-1 + character literals, use the numeric value instead. + Reported by Shin-Hsien Yeh . + +2000-09-29 Bruno Haible + + * autoconf/aclocal.m4 (CL_CANONICAL_HOST): Fix bug in 2000-05-23 + change. + +2000-09-25 Bruno Haible + + * autoconf/aclocal.m4 (CL_WORDS_LITTLEENDIAN): Recognize __i386__ + as equivalent to __i386. For OpenBSD. + +2000-09-21 Bruno Haible + + * src/utf16.h (utf16_wctomb): Reject single surrogates. + * src/utf16be.h (utf16be_wctomb): Likewise. + * src/utf16le.h (utf16le_wctomb): Likewise. + * src/ucs2.h (ucs2_mbtowc, ucs2_wctomb): Likewise. + * src/ucs2be.h (ucs2be_mbtowc, ucs2be_wctomb): Likewise. + * src/ucs2le.h (ucs2le_mbtowc, ucs2le_wctomb): Likewise. + * src/ucs2internal.h (ucs2internal_mbtowc, ucs2internal_wctomb): + Likewise. + * src/ucs2swapped.h (ucs2swapped_mbtowc, ucs2swapped_wctomb): + Likewise. + +2000-09-15 Bruno Haible + + * Makefile.in (install, installdirs, uninstall): Support DESTDIR. + * src/Makefile.in (install, installdirs, uninstall): Likewise. + * man/Makefile.in (install, installdirs, uninstall): Likewise. + +2000-09-11 Bruno Haible + + * src/utf7.h (utf7_mbtowc): Fix combining of UTF-16 surrogates. + +2000-08-26 Bruno Haible + + * autoconf/acgeneral.m4 (AC_OUTPUT): Use braces in exec_prefix default + value, not parens. + +2000-07-04 Akira Hatakeyama + Bruno Haible + + * os2/iconv.def, README.os2, Makefile.os2, src/Makefile.os2, + tests/Makefile.os2, man/Makefile.os2, tests/check-stateful.cmd, + tests/check-stateless.cmd, tests/check-translit.cmd: New files. + +2000-06-28 Bruno Haible + + * src/ucs2internal.h (ucs2internal_mbtowc): Avoid gcc warning about + cast. + * src/ucs4internal.h (ucs4internal_mbtowc): Likewise. + * src/ucs2swapped.h (ucs2swapped_mbtowc, ucs2swapped_wctomb): Verify + sizeof(unsigned short). + * src/ucs4swapped.h (ucs4swapped_mbtowc, ucs4swapped_mbtowc): Verify + sizeof(unsigned int). + Reported by François Pinard . + +2000-05-29 Bruno Haible + + * autoconf/aclocal.m4 (CL_PROG_INSTALL): Fix typo. + Reported by Thomas Klausner . + +2000-05-23 Bruno Haible + + * autoconf/aclocal.m4 (CL_CANONICAL_HOST): Determine host_cpu, + host_vendor, host_os correctly if $host has more than two hyphens. + +2000-04-15 Bruno Haible + + * Version 1.3 released. + * include/iconv.h.in (_LIBICONV_VERSION), README, windows/iconv.rc: + Bump version number. + * src/Makefile.in (LIBICONV_VERSION_INFO): Define to 2:0:0. + +2000-04-15 Bruno Haible + + * THANKS: New file. + * INSTALL.generic: New file. + + Implement and document UCS-2BE, UCS-2LE, UCS-4BE, UCS-4LE. + * src/ucs2be.h, src/ucs2le.h, src/ucs4be.h, src/ucs4le.h: New files. + * src/converters.h: Include them. + * src/ucs2swapped.h: Remove #defines for UCS-2-BE, UCS-2-LE. + * src/ucs4swapped.h: Remove #defines for UCS-4-BE, UCS-4-LE. + * src/encodings.def (UCS-2BE): Renamed from UCS-2-BE. + (UCS-2LE): Renamed from UCS-2-LE. + (UCS-4BE): Renamed from UCS-4-BE. + (UCS-4LE): Renamed from UCS-4-LE. + * Makefile.devel (src/aliases.h): Pass option "-i 1" to gperf. + * README, man/iconv_open.3: Add UCS-2BE, UCS-2LE, UCS-4BE, UCS-4LE. + * tests/Makefile.in (check): Check UCS-2BE, UCS-2LE, UCS-4BE, UCS-4LE. + * tests/Makefile.msvc (check): Likewise. + * tests/UCS-*snippet*: New files. + + Allow building as a shared library on Windows. + Allow running the tests on Windows. + * Makefile.devel (include/iconv.h.msvc): Remove rule. + (include/iconv.h.msvc-static, include/iconv.h.msvc-shared): New + rules. + (all): Update. + * windows/dllexport.h: New file. + * include/iconv.h.msvc: Remove file. + * include/iconv.h.msvc-static, include/iconv.h.msvc-shared: New + autogenerated files. + * Makefile.msvc (STATIC, DEBUG): Default to 0. + (all): Choose either include\iconv.h.msvc-static or + include\iconv.h.msvc-shared. + (check): Depend on all. + (all, check, mostlyclean, clean, distclean, maintainer-clean): + Recurse into tests directory. + * src/Makefile.msvc (STATIC, DEBUG): Default to 0. + (WARN_CFLAGS, PICFLAGS, OPTIMFLAGS): New variables. + (CFLAGS): Use them. Add -MD and -DBUILDING_LIBICONV. + (RESOURCES): New variable. + (iconv.lib): Change rule when building DLL. + (clean, distclean): One filename per line. + * tests/Makefile.msvc: New file. + * tests/check-stateful.bat, tests/check-stateless.bat, + tests/check-translit.bat: New files. + * tests/uniq-u.c: New file, taken from GNU textutils. + * README.win32: Update. + Based on patches by Taro Muraoka . + +2000-04-14 Bruno Haible + + Fix an OSF/1 problem. + * configure.in: Define GCC variable for substitution. + * src/Makefile.in (libiconv_plug_osf.so): Change rule if not using + gcc. + +2000-04-13 Bruno Haible + + Fix a SunOS 4 problem. + * include/iconv.h.in: If EILSEQ is not defined by the system, define + it to ENOENT, not EINVAL. + +2000-04-02 Bruno Haible + + Allow building on filesystems lacking symlinks and hard links. + * Makefile.devel (autoconf/aclocal.m4): Replace AC_PROG_LN_S with + CL_PROG_LN_S. + * configure.in: Add CL_PROG_LN, CL_PROG_LN_S. + * src/Makefile.in (LN): Use autoconfigured value @LN@. + (LN_S): Use autoconfigured value @LN_S@. + +2000-03-15 Bruno Haible + + * Version 1.2 released. + * include/iconv.h.in (_LIBICONV_VERSION): Bump version number. + * src/Makefile.in (LIBICONV_VERSION_INFO): Define to 1:1:1. + +2000-03-14 Bruno Haible + + Implement and document UTF-16BE and UTF16LE. + * src/utf16be.h, src/utf16le.h: New files. + * src/converters.h: Include them. + * src/encodings.def (UTF-16BE, UTF16LE): New encodings. + * README, man/iconv_open.3: Add UTF-16BE, UTF16LE. + * tests/Makefile.in (check): Check UTF-16, UTF-16BE, UTF16LE. + * tests/UTF-16*snippet*: New files. + + * src/utf16.h (utf16_wctomb): Output a byte order mark. + +2000-03-13 Bruno Haible + + Provide all encodings used by AIX locales. + * tools/Makefile (all): Add cp856.h, cp922.h, cp1046.h, cp1124.h, + cp1129.h. + (cp856.h, cp922.h, cp1046.h, cp1124.h, cp1129.h): New targets. + * src/cp856.h, src/cp922.h, src/cp943.h, src/cp1046.h, src/cp1124.h, + src/cp1129.h: New files. + * src/converters.h: Include them if USE_AIX is defined. + * src/encodings_aix.def: New file, with CP856, CP922, CP943, CP1046, + CP1124, CP1129. + * src/genflags.c: Define USE_AIX. Include encodings_aix.def. + * src/genaliases2.c: New file. + * src/iconv.c: Define USE_AIX on AIX. + Include encodings_aix.def and aliases_aix.h. + (aliases2_lookup): New function. + (iconv_open): Call aliases2_lookup. + * src/Makefile.in (iconv.lo): Depend on encodings_aix.def and + aliases_aix.h. + * Makefile.devel (all): Add src/aliases_aix.h. + (src/aliases_aix.h): New rule. + (src/flags.h): Depend on src/encodings_aix.def. + +2000-02-24 Bruno Haible + + * src/iconv.c (iconv): Don't write beyond the end of the output buffer. + Reported by Edmund Grimley Evans . + +2000-02-22 Bruno Haible + + * src/utf7.h (direct_tab, xdirect_tab): Treat tab like space. + +2000-02-15 Bruno Haible + + * src/iconv.c (iconv): Add cast in xxx_reset call. + +2000-02-05 Bruno Haible + + * src/tis620.h: Simplify. + +2000-01-27 Bruno Haible + + * Makefile.devel (CLISP_DIR): Change to "..". + +2000-01-24 Bruno Haible + + * Version 1.1 released. + * include/iconv.h.in (_LIBICONV_VERSION): Bump version number. + * src/Makefile.in (LIBICONV_VERSION_INFO): Define to 1:0:1. + +2000-01-23 Bruno Haible + + * src/utf7.h (utf7_wctomb): If base64 encoding is not active, encode + '+' as "+-". + +2000-01-22 Bruno Haible + + * include/iconv.h.in (iconvctl): New declaration. + (ICONV_TRIVIALP, ICONV_GET_TRANSLITERATE, ICONV_SET_TRANSLITERATE): + New macros. + * src/iconv.c (iconvctl): New function. + + * tests/Makefile.in: Add a rule for ../src/libiconv.la. Define $(MAKE). + + Solve a build problem. + * include/iconv.h.in: Renamed from include/libiconv.h.in. + * Makefile.devel: libiconv.h -> iconv.h. + * Makefile.in: Likewise. + * configure.in: Likewise. Remove check for . + * src/iconv.c: Include iconv.h instead of libiconv.h. + * tests/iconv.c, tests/table-from.c, tests/table-to.c: Likewise. + + * README, man/iconv_open.3: Don't document JOHAB any more. + + * man/iconv.3: Clarify return value again. + +2000-01-16 Bruno Haible + + Add aliases. + * src/encodings.def (ISO-8859-14): Add alias ISO-IR-199. + (ISO-8859-15): Add alias ISO-IR-203. + (EUC-CN): Add alias CN-GB, from RFC 1922. + (BIG5): Add alias CN-BIG5, from RFC 1922. + * Makefile.devel (src/aliases.h): Add 8th character to key set. + + Drop X11 aliases. + * src/encodings.def (JIS_X0201): Drop JISX0201.1976-0 alias. + (JIS_X0208): Drop JIS_X0208.1983-0, JIS_X0208.1983-1 aliases. + (KSC_5601): Drop KSC5601.1987-0 alias. + + Improve GB/T 12345 (not used yet). + * tools/Makefile (gb12345ext.h): Use GB12345-more.TXT. + * src/gb12345ext.h: Regenerated. + + Improve and document CP949. + * tools/Makefile (all): Add uhc_1.h and uhc_2.h. + (uhc_1.h, uhc_2.h): New rules. + * tools/cjk_tab_to_h.c (output_charset2uni_noholes_monotonic): New + function. + (output_uni2charset_sparse): Take an additional boolean argument. + All callers changed. + (*_uhc_1, *_uhc_2): New functions. + (main): Treat uhc_1 and uhc_2. + * src/uhc_1.h, src/uhc_2.h: New files. + * src/cp949.h: New file, include them. + * src/converters.h: Include it. + * src/encodings.def (KSC_5601): Remove alias CP949. + (CP949): New encoding. + * README, man/iconv_open.3: Add CP949. + * tests/Makefile.in (check): Check CP949. + * tests/CP949.TXT: New file. + + Document CP932. + * README, man/iconv_open.3: Add CP932. + * tests/Makefile.in (check): Check CP932. + * tests/CP932.TXT, tests/CP932.IRREVERSIBLE.TXT: New files. + + * Makefile.devel (src/flags.h): Depend on src/converters.h. + + * tests/Makefile.in (check): Check JIS_X0201. + * tests/JIS_X0201.TXT: New file. + + * src/euc_kr.h (euc_kr_wctomb): Shrink size of buf. + * src/iso2022_kr.h (iso2022_kr_wctomb): Likewise. + + * src/iso2022_cnext.h (iso2022_cn_ext_mbtowc): Use isoir165_mbtowc. + (iso2022_cn_ext_wctomb): Use isoir165_wctomb. + + Add ISO-IR-165 (undocumented). + * tools/Makefile (all): Add isoir165ext.h. + (isoir165ext.h): New rule. + * tools/cjk_tab_to_h.c (main): Treat isoir165ext like gb2312. + * src/isoir165.h, src/isoir165ext.h: New files. + * src/converters.h: Include it. + * src/encodings.def: Add ISO-IR-165. + * tests/Makefile.in (check): Check ISO-IR-165. + * tests/ISO-IR-165.TXT, tests/ISO-IR-165.IRREVERSIBLE.TXT: New files. + + Add ISO646-CN (undocumented). + * src/iso646_cn.h: New file. + * src/converters.h: Include it. + * src/encodings.def: Add ISO646-CN. + * tests/Makefile.in (check): Check ISO646-CN. + * tests/ISO646-CN.TXT: New file. + + Add ISO646-JP (undocumented). + * src/iso646_jp.h: New file. + * src/converters.h: Include it. + * src/encodings.def: Add ISO646-JP. + * tests/Makefile.in (check): Check ISO646-JP. + * tests/ISO646-JP.TXT: New file. + +2000-01-05 Bruno Haible + + Add ISO-8859-16. + * tools/Makefile (all): Add iso8859_16.h. + (iso8859_16.h): New rule. + * src/iso8859_16.h: New file. + * src/converters.h: Include it. + * src/encodings.def: Add ISO-8859-16. + * README, man/iconv_open.3: Add ISO-8859-16. + * tests/Makefile.in (check): Check ISO-8859-16. + * tests/ISO-8859-16.TXT: New file. + + * man/iconv.3: Clarify what happens *inbuf in case 3. + + * src/iso8859_8.h: Update using newest table from ftp.unicode.org. + * tests/ISO-8859-8.TXT: Likewise. + +2000-01-04 Bruno Haible + + * Version 1.0 released. + * include/libiconv.h.in (_LIBICONV_VERSION): Bump version number. + * src/Makefile.in (LIBICONV_VERSION_INFO): Define to 0:1:0. + (libiconv.la): Use LIBICONV_VERSION_INFO. + +2000-01-03 Bruno Haible + + * tests/Makefile.in: New file. + tests/check-stateless, tests/table-from.c, tests/table-to.c, + tests/*.TXT, tests/genutf8.c: New files, checks for stateless + encodings. + tests/check-stateful, tests/iconv.c, tests/*-snippet*: New files, + checks for stateful encodings. + * Makefile.in (all, check, mostlyclean, clean, distclean, + maintainer-clean): Descend into tests directory. + * configure.in: Add tests/Makefile to AC_OUTPUT duties. + + * src/gentranslit.c: New file. + * Makefile.devel (src/translit.h): New rule. + * src/translit.def, src/translit.h: New files. + * src/iconv.c: Include it. + (iconv): Transliterate using translit.h table. + + * src/genflags.c: New file. + * Makefile.devel (src/flags.h): New rule. + * src/flags.h: New file. + * src/iconv.c: Include it. + (encoding): Add field 'oflags'. + (all_encodings): Initialize the field 'oflags'. + (iconv_open): Copy field 'oflags'. + (iconv): Transliterate quotation marks U+2018, U+2019, U+201A. + * src/Makefile.in (iconv.lo): Update dependencies. + + * src/converters.h: New file, extracted from src/iconv.c. + * src/iconv.c: Include it. + * src/Makefile.in (iconv.lo): Update dependencies. + + * tools/cjk_variants.c: New file. + * tools/Makefile (ALL): Add cjk_variants.h. + (cjk_variants.h, cjk_variants): New rules. + * src/cjk_variants.h: New file. + * src/iconv.c: Include it. + (iconv): Use cjk_variants for transliteration. + + * man/iconv.3: Fix description of return value. + * euc_kr.h (euc_kr_wctomb): Remove Hangul transliteration. + * iso2022_kr.h (iso2022kr_wctomb): Likewise. + * src/iconv.c (iconv): Do Hangul transliteration here and increment + result once for every transliterated character. + * src/johab_hangul.h (johab_hangul_decompose): Change result array + from 'unsigned char*' to 'wchar_t*'. + + * src/cp1258.h (cp1258_mbtowc): Return RET_ILSEQ instead of storing + 0xfffd. + + * src/georgian_ps.h (georgian_ps_wctomb): Accept 0x00e6. + + * src/euc_jp.h (euc_jp_wctomb): Don't treat U+005C and U+007E like + Katakana. + + * src/euc_tw.h (euc_tw_mbtowc): Fix typo. + + * src/cp950.h (cp950_mbtowc, cp950_wctomb): Exclude the range + 0xC6A1..0xC7FE. + + * tools/cjk_tab_to_h.c (read_table_ksc5601): Some Hangul range was + not being excluded. Fix that. + * src/ksc5601.h: Regenerated. + * src/johab.h (johab_mbtowc): Don't accept 0xDA{A1..D3} - this is + valid in KSC5601/KSX1001 but not in JOHAB. + + * src/iconv.c (conv_struct): Add fields iindex, oindex. + (iconv_open): Fill in iindex, oindex. + + * src/encodings.def (UCS-2-BE): Add aliases "UNICODE-1-1" and + "csUnicode11", from IANA charset list. + (MacRoman): Add aliases "MAC" and "csMacintosh" for "MACINTOSH", + from IANA charset list. + (JIS_X0208): Add aliases "X0208", "ISO-IR-87", "csISO87JISX0208", + from IANA charset list. + (GB_2312-80): New encoding, from IANA charset list. + + * README, man/iconv_open.3: Add MacIceland and MacUkraine. + + * Makefile.devel: Add rules for src/aliases.h and src/aliases.gperf. + (all): Depend on src/aliases.h. + * src/Makefile.in: Remove rules for $(srcdir)/aliases.h and + $(srcdir)/aliases.gperf. + (clean): Clean up. + + * src/Makefile.in (libiconv_plug_linux.so): Remove unneeded "-ldl". + +1999-12-31 Bruno Haible + + * Version 0.3 released. + diff --git a/libs/libiconv/DEPENDENCIES b/libs/libiconv/DEPENDENCIES new file mode 100644 index 00000000..64b08a9f --- /dev/null +++ b/libs/libiconv/DEPENDENCIES @@ -0,0 +1 @@ +No packages need to be installed before GNU libiconv is installed. diff --git a/libs/libiconv/DESIGN b/libs/libiconv/DESIGN new file mode 100644 index 00000000..9ff2ad3a --- /dev/null +++ b/libs/libiconv/DESIGN @@ -0,0 +1,64 @@ +While some other iconv(3) implementations - like FreeBSD iconv(3) - choose +the "many small shared libraries" and dlopen(3) approach, this implementation +packs everything into a single shared library. Here is a comparison of the +two designs. + +* Run-time efficiency + 1. A dlopen() based approach needs a cache of loaded shared libraries. + Otherwise, every iconv_open() call will result in a call to dlopen() + and thus to file system related system calls - which is prohibitive + because some applications use the iconv_open/iconv/iconv_close sequence + for every single filename, string, or piece of text. + 2. In terms of virtual memory use, both approaches are on par. Being shared + libraries, the tables are shared between any processes that use them. + And because of the demand loading used by Unix systems (and because libiconv + does not have initialization functions), only those parts of the tables + which are needed (typically very few kilobytes) will be read from disk and + paged into main memory. + 3. Even with a cache of loaded shared libraries, the dlopen() based approach + makes more system calls, because it has to load one or two shared libraries + for every encoding in use. + +* Total size + In the dlopen(3) approach, every shared library has a symbol table and + relocation offset. All together, FreeBSD iconv installs more than 200 shared + libraries with a total size of 2.3 MB. Whereas libiconv installs 0.45 MB. + +* Extensibility + The dlopen(3) approach is good for guaranteeing extensibility if the iconv + implementation is distributed without source. (Or when, as in glibc, you + cannot rebuild iconv without rebuilding your libc, thus possibly + destabilizing your system.) + The libiconv package achieves extensibility through the LGPL license: + Every user has access to the source of the package and can extend and + replace just libiconv.so. + The places which have to be modified when a new encoding is added are as + follows: add an #include statement in iconv.c, add an entry in the table in + iconv.c, and of course, update the README and iconv_open.3 manual page. + +* Use within other packages + If you want to incorporate an iconv implementation into another package + (such as a mail user agent or web browser), the single library approach + is easier, because: + 1. In the shared library approach you have to provide the right directory + prefix which will be used at run time. + 2. Incorporating iconv as a static library into the executable is easy - + it won't need dynamic loading. (This assumes that your package is under + the LGPL or GPL license.) + + +All conversions go through Unicode. This is possible because most of the +world's characters have already been allocated in the Unicode standard. +Therefore we have for each encoding two functions: +- For conversion from the encoding to Unicode, a function called xxx_mbtowc. +- For conversion from Unicode to the encoding, a function called xxx_wctomb, + and for stateful encodings, a function called xxx_reset which returns to + the initial shift state. + + +All our functions operate on a single Unicode character at a time. This is +obviously less efficient than operating on an entire buffer of characters at +a time, but it makes the coding considerably easier and less bug-prone. Those +who wish best performance should install the Real Thing (TM): GNU libc 2.1 +or newer. + diff --git a/libs/libiconv/HACKING b/libs/libiconv/HACKING new file mode 100644 index 00000000..0c291e29 --- /dev/null +++ b/libs/libiconv/HACKING @@ -0,0 +1,64 @@ +All you need to know when hacking (modifying) GNU libiconv or when building +it off the CVS. + + +Requirements +============ + +You will need reasonably recent versions of the build tools: + + * A C compiler. Such as GNU GCC. + + Homepage: + http://gcc.gnu.org/ + + * GNU automake + + Homepage: + http://www.gnu.org/software/automake/ + + * GNU autoconf + + Homepage: + http://www.gnu.org/software/autoconf/ + + * GNU m4 + + Homepage: + http://www.gnu.org/software/m4/ + + * GNU gperf + + Homepage: + http://www.gnu.org/software/gperf/ + + * GNU groff 1.17 or newer + + Homepage: + http://www.gnu.org/software/groff/ + + * Perl + + Homepage: + http://www.perl.org/ + + * Either an internet connection or a recent copy of GNU gnulib. + + Homepage: + http://www.gnu.org/software/gnulib/ + +And, of course, the packages listed in the DEPENDENCIES file. + + +Building off the CVS +==================== + +Access to the CVS is described at http://sourceforge.net/cvs/?group_id=51585 . + +After fetching the sources from the CVS, peek at the comments in autogen.sh, +then run "./autogen.sh"; then you can proceed with "./configure" as usual. + + +Adding new encodings +==================== + +For an indication which encodings are acceptable in the official version of +GNU libiconv, take a look at NOTES. + +For an indication which files need to be modified when adding a new encoding, +look for example at the 2007-05-25 ChangeLog entry for RK1048. The lib/*.h +file for an encoding is usually generated by one of the tools in the tools/ +directory. All you need to provide is the conversion table in the format of +the many *.TXT files. diff --git a/libs/libiconv/INSTALL.generic b/libs/libiconv/INSTALL.generic new file mode 100644 index 00000000..13813e8b --- /dev/null +++ b/libs/libiconv/INSTALL.generic @@ -0,0 +1,273 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.ac' is used to create `configure' by a program +called `autoconf'. You only need `configure.ac' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple '-arch' options to the +compiler but only a single '-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases. You +may have to build one architecture at a time and combine the results +using the 'lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Relocatable Installation +======================== + + By default, `make install' will install a package with hardwired +file names, and the package will not work correctly when copied or +moved to a different location in the filesystem. + + Some packages pay attention to the `--enable-relocatable' option to +`configure'. This option makes the entire installed package +relocatable. This means, it can be moved or copied to a different +location on the filesystem. It is possible to make symlinks to the +installed and moved programs, and invoke them through the symlink. It +is possible to do the same thing with a hard link _only_ if the hard +linked file is in the same directory as the real program. + + For reliability it is best to give together with --enable-relocatable +a `--prefix' option pointing to an otherwise unused (and never used +again) directory, for example, `--prefix=/tmp/inst$$'. This is +recommended because on some OSes the executables remember the location +of shared libraries (and prefer them over LD_LIBRARY_PATH !), therefore +such an executable will look for its shared libraries first in the +original installation directory and only then in the current +installation directory. + + Installation with `--enable-relocatable' will not work for setuid / +setgid executables. (This is because such an executable kills its +LD_LIBRARY_PATH variable when it is launched.) + + The runtime penalty and size penalty are nearly zero on Linux 2.2 or +newer (just one system call more when an executable is launched), and +small on other systems (the wrapper program just sets an environment +variable and execs the real program). + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + For packages that use the GNU libiconv library, you can use the +`configure' option `--with-libiconv-prefix' to specify the prefix you +used while installing GNU libiconv. This option is not necessary if +that other prefix is the same as the one now specified through --prefix. + + For packages that use the GNU libintl library, you can use the +`configure' option `--with-libintl-prefix' to specify the prefix you +used while installing GNU gettext-runtime. This option is not necessary if +that other prefix is the same as the one now specified through --prefix. + +Particular Systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC +is not installed, it is recommended to use the following options in order +to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On AIX 3, the C include files by default don't define some necessary +prototype declarations. If GNU CC is not installed, it is recommended to +use the following options: + + ./configure CC="xlc -D_ALL_SOURCE" + + On BeOS, user installed software goes in /boot/home/config, not +/usr/local. It is recommended to use the following options: + + ./configure --prefix=/boot/home/config + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/libs/libiconv/NEWS b/libs/libiconv/NEWS new file mode 100644 index 00000000..c33d0d12 --- /dev/null +++ b/libs/libiconv/NEWS @@ -0,0 +1,184 @@ +New in 1.14: +* The 'iconv' program now produces its output as soon as it can. It no longer + unnecessarily waits for more input. +* Updated the GB18030 converter to map 25 characters to code points that have + been to Unicode since 2000, rather than to code points in the Private Use + Area. +* Updated the BIG5-HKSCS converter. The old BIG5-HKSCS converter is renamed to + BIG5-HKSCS:2004. A new converter BIG5-HKSCS:2008 is added. BIG5-HKSCS is now + an alias for BIG5-HKSCS:2008. +* Fixed a bug in the conversion to wchar_t. +* Fixed a small bug in the CP1258 converter. + +New in 1.13: +* The library and the iconv program now understand platform dependent aliases, + for better compatibility with the platform's own iconv_open function. + Examples: "646" on Solaris, "iso88591" on HP-UX, "IBM-1252" on AIX. +* For stateful encodings, when the input ends with a shift sequence followed + by invalid input, the iconv function now increments the input pointer past + the shift sequence before returning (size_t)(-1) with errno = EILSEQ. This + is also like GNU libc's iconv() behaves. +* The library exports a new function iconv_open_into() that stores the + conversion descriptor in pre-allocated memory, rather than allocating fresh + memory for it. +* Added CP1131 converter. + +New in 1.12: +* The iconv program is now licensed under the GPL version 3, instead of the + GPL version 2. The libiconv library continues to be licensed under LGPL. +* Added RK1048 converter. +* On AIX, an existing system libiconv no longer causes setlocale() to fail. +* Upgraded EUC-KR, JOHAB to include the Korean postal code sign. + +New in 1.11: +* The iconv program has new options --unicode-subst, --byte-subst, + --widechar-subst that allow to specify substitutions for characters that + cannot be converted. +* The iconv program now understands long options: + long option equivalent to + --from-code -f + --to-code -t + --list -l + --silent -s +* The CP936 converter is now different from the GBK converter: it has changed + to include the Euro sign and private area characters. CP936 is no longer an + alias of GBK. +* Updated GB18030 converter to include all private area characters. +* Updated CP950 converter to include the Euro sign and private area characters. +* Updated CP949 converter to include private area characters. +* Updated the BIG5-HKSCS converter. The old BIG5-HKSCS converter is renamed to + BIG5-HKSCS:1999 and updated to Unicode 4. New converters BIG5-HKSCS:2001 and + BIG5-HKSCS:2004 are added. BIG5-HKSCS is now an alias for BIG5-HKSCS:2004. +* Added a few irreversible mappings to the CP932 converter. +* Tidy up the list of symbols exported from libiconv (assumes gcc >= 4.0). + +New in 1.10: +* Added ISO-8859-11 converter. +* Updated the ISO-8859-7 converter. +* Added ATARIST converter, available through --enable-extra-encodings. +* Added BIG5-2003 converter (experimental), available through + --enable-extra-encodings. +* Updated EUC-TW converter to include the Euro sign. +* The preloadable library has been renamed from libiconv_plug.so to + preloadable_libiconv.so. +* Portability to mingw. + +New in 1.9: +* Many more transliterations. +* New configuration option --enable-relocatable. See the INSTALL.generic file + for details. + +New in 1.8: +* The iconv program has new options -l, -c, -s. +* The iconv program is internationalized. +* Added C99 converter. +* Added KOI8-T converter. +* New configuration option --enable-extra-encodings that enables a bunch of + additional encodings; see the README for details. +* Updated the ISO-8859-16 converter. +* Upgraded BIG5-HKSCS, EUC-TW, ISO-2022-CN, ISO-2022-CN-EXT converters to + Unicode 3.2. +* Upgraded EUC-KR, CP949, JOHAB converters to include the Euro sign. +* Changed the ARMSCII-8 converter. +* Extended the EUC-JP encoder so that YEN SIGN characters don't cause failures + in Shift_JIS to EUC-JP conversion. +* The JAVA converter now handles characters outside the Unicode BMP correctly. +* Fixed a bug in the CP1255, CP1258, TCVN decoders: The base characters of + combining characters could be dropped at the end of the conversion buffer. +* Fixed a bug in the transliteration that could lead to excessive memory + allocations in libintl when transliteration was needed. +* Portability to BSD/OS and SCO 3.2.5. + +New in 1.7: +* Added UTF-32, UTF-32BE, UTF-32LE converters. +* Changed CP1255, CP1258 and TCVN converters to handle combining characters. +* Changed EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP, ISO-2022-JP-2, ISO-2022-JP-1 + converters to use fullwidth Yen sign instead of halfwidth Yen sign, and + fullwidth tilde instead of halfwidth tilde. +* Upgraded EUC-TW, ISO-2022-CN, ISO-2022-CN-EXT converters to Unicode 3.1. +* Changed the GB18030 converter to not reject unassigned and private-use + Unicode characters. +* Fixed a bug in the byte order mark treatment of the UCS-4 decoder. +* The manual pages are now distributed also in HTML format. + +New in 1.6: +* The iconv program's -f and -t options are now optional. +* Many more transliterations. +* Added CP862 converter. +* Changed the GB18030 converter. +* Portability to DOS with DJGPP. + +New in 1.5: +* Added an iconv(1) program. +* New locale dependent encodings "char", "wchar_t". +* Transliteration is now off by default. Use a //TRANSLIT suffix to enable it. +* The JOHAB encoding is documented again. +* Changed a few mappings in the CP950 converter. + +New in 1.4: +* Added GB18030, BIG5HKSCS converters. +* Portability to OS/2 with emx+gcc. + +New in 1.3: +* Added UCS-2BE, UCS-2LE, UCS-4BE, UCS-4LE converters. +* Fixed the definition of EILSEQ on SunOS4. +* Fixed a build problem on OSF/1. +* Support for building as a shared library on Woe32. + +New in 1.2: +* Added UTF-16BE and UTF-16LE converters. +* Changed the UTF-16 encoder. +* Fixed the treatment of tab characters in the UTF-7 converter. +* Fixed an internal error when output buffer was not large enough. + +New in 1.1: +* Added ISO-8859-16 converter. +* Added CP932 converter, a variant of SHIFT_JIS. +* Added CP949 converter, a variant of EUC-KR. +* Improved the ISO-2022-CN-EXT converter: It now covers the ISO-IR-165 range. +* Updated the ISO-8859-8 conversion table. +* The JOHAB encoding is deprecated and not documented any more. +* Fixed two build problems: 1. "make -n check" failed. 2. When libiconv was + already installed, "make" failed. + +New in 1.0: +* Added transliteration facilities. +* Added a test suite. +* Fixed the iconv(3) manual page and function: the return value was not + described correctly. +* Fixed a bug in the CP1258 decoder: invalid bytes now yield EILSEQ instead of + U+FFFD. +* Fixed a bug in the Georgian-PS encoder: accept U+00E6. +* Fixed a bug in the EUC-JP encoder: reject 0x8E5C and 0x8E7E. +* Fixed a bug in the KSC5601 and JOHAB converters: they recognized some Hangul + characters at some invalid code positions. +* Fixed a bug in the EUC-TW decoder; it was severely broken. +* Fixed a bug in the CP950 converter: it recognized a dubious BIG5 range. + +New in 0.3: +* Reduced the size of the tables needed for the JOHAB converter. +* Portability to Woe32. + +New in 0.2: +* Added KOI8-RU, CP850, CP866, CP874, CP950, ISO-2022-CN-EXT, GBK and + ISO-2022-JP-1 converters. +* Added MACINTOSH as an alias for MAC-ROMAN. +* Added ASMO-708 as an alias for ISO-8859-6. +* Added ELOT_928 as an alias for ISO-8859-7. +* Improved the EUC-TW converter: Treat CNS 11643 plane 3. +* Improved the ISO-2022-KR and EUC-KR converters: Hangul characters are + decomposed into Jamo when needed. +* Improved the CP932 converter. +* Updated the CP1133, MULELAO-1 and ARMSCII-8 mappings. +* The EUC-JP and SHIFT_JIS converters now cover the user-defined range. +* Fixed a possible buffer overrun in the JOHAB converter. +* Fixed a bug in the UTF-7, ISO-2022-*, HZ decoders: a shift sequence a the + end of the input no longer gives an error. +* The HZ encoder now always terminates its output in the ASCII state. +* Use a perfect hash table for looking up the aliases. + +New in 0.1: +* Portability to Linux/glibc-2.0.x, Linux/libc5, OSF/1, FreeBSD. +* Fixed a bug in the EUC-JP decoder. Extended the ISO-2022-JP-2 converter. +* Made TIS-620 mapping consistent with glibc-2.1. + diff --git a/libs/libiconv/NOTES b/libs/libiconv/NOTES new file mode 100644 index 00000000..0755a2e1 --- /dev/null +++ b/libs/libiconv/NOTES @@ -0,0 +1,399 @@ +Q: Why does libiconv support encoding XXX? Why does libiconv not support + encoding ZZZ? + +A: libiconv, as an internationalization library, supports those character + sets and encodings which are in wide-spread use in at least one territory + of the world. + + Hint1: On http://www.w3c.org/International/O-charset-lang.html you find a + page "Languages, countries, and the charsets typically used for them". + From this table, we can conclude that the following are in active use: + + ISO-8859-1, CP1252 Afrikaans, Albanian, Basque, Catalan, Danish, Dutch, + English, Faroese, Finnish, French, Galician, German, + Icelandic, Irish, Italian, Norwegian, Portuguese, + Scottish, Spanish, Swedish + ISO-8859-2 Croatian, Czech, Hungarian, Polish, Romanian, Slovak, + Slovenian + ISO-8859-3 Esperanto, Maltese + ISO-8859-5 Bulgarian, Byelorussian, Macedonian, Russian, + Serbian, Ukrainian + ISO-8859-6 Arabic + ISO-8859-7 Greek + ISO-8859-8 Hebrew + ISO-8859-9, CP1254 Turkish + ISO-8859-10 Inuit, Lapp + ISO-8859-13 Latvian, Lithuanian + ISO-8859-15 Estonian + KOI8-R Russian + SHIFT_JIS Japanese + ISO-2022-JP Japanese + EUC-JP Japanese + + Ordered by frequency on the web (1997): + ISO-8859-1, CP1252 96% + SHIFT_JIS 1.6% + ISO-2022-JP 1.2% + EUC-JP 0.4% + CP1250 0.3% + CP1251 0.2% + CP850 0.1% + MACINTOSH 0.1% + ISO-8859-5 0.1% + ISO-8859-2 0.0% + + Hint2: The character sets mentioned in the XFree86 4.0 locale.alias file. + + ISO-8859-1 Afrikaans, Basque, Breton, Catalan, Danish, Dutch, + English, Estonian, Faroese, Finnish, French, + Galician, German, Greenlandic, Icelandic, + Indonesian, Irish, Italian, Lithuanian, Norwegian, + Occitan, Portuguese, Scottish, Spanish, Swedish, + Walloon, Welsh + ISO-8859-2 Albanian, Croatian, Czech, Hungarian, Polish, + Romanian, Serbian, Slovak, Slovenian + ISO-8859-3 Esperanto + ISO-8859-4 Estonian, Latvian, Lithuanian + ISO-8859-5 Bulgarian, Byelorussian, Macedonian, Russian, + Serbian, Ukrainian + ISO-8859-6 Arabic + ISO-8859-7 Greek + ISO-8859-8 Hebrew + ISO-8859-9 Turkish + ISO-8859-14 Breton, Irish, Scottish, Welsh + ISO-8859-15 Basque, Breton, Catalan, Danish, Dutch, Estonian, + Faroese, Finnish, French, Galician, German, + Greenlandic, Icelandic, Irish, Italian, Lithuanian, + Norwegian, Occitan, Portuguese, Scottish, Spanish, + Swedish, Walloon, Welsh + KOI8-R Russian + KOI8-U Russian, Ukrainian + EUC-JP (alias eucJP) Japanese + ISO-2022-JP (alias JIS7) Japanese + SHIFT_JIS (alias SJIS) Japanese + U90 Japanese + S90 Japanese + EUC-CN (alias eucCN) Chinese + EUC-TW (alias eucTW) Chinese + BIG5 Chinese + EUC-KR (alias eucKR) Korean + ARMSCII-8 Armenian + GEORGIAN-ACADEMY Georgian + GEORGIAN-PS Georgian + TIS-620 (alias TACTIS) Thai + MULELAO-1 Laothian + IBM-CP1133 Laothian + VISCII Vietnamese + TCVN Vietnamese + NUNACOM-8 Inuktitut + + Hint3: The character sets supported by Netscape Communicator 4. + + Where is this documented? For the complete picture, I had to use + "strings netscape" and then a lot of guesswork. For a quick take, + look at the "View - Character set" menu of Netscape Communicator 4.6: + + ISO-8859-{1,2,5,7,9,15} + WINDOWS-{1250,1251,1253} + KOI8-R Cyrillic + CP866 Cyrillic + Autodetect Japanese (EUC-JP, ISO-2022-JP, ISO-2022-JP-2, SJIS) + EUC-JP Japanese + SHIFT_JIS Japanese + GB2312 Chinese + BIG5 Chinese + EUC-TW Chinese + Autodetect Korean (EUC-KR, ISO-2022-KR, but not JOHAB) + + UTF-8 + UTF-7 + + Hint4: The character sets supported by Microsoft Internet Explorer 4. + + ISO-8859-{1,2,3,4,5,6,7,8,9} + WINDOWS-{1250,1251,1252,1253,1254,1255,1256,1257} + KOI8-R Cyrillic + KOI8-RU Ukrainian + ASMO-708 Arabic + EUC-JP Japanese + ISO-2022-JP Japanese + SHIFT_JIS Japanese + GB2312 Chinese + HZ-GB-2312 Chinese + BIG5 Chinese + EUC-KR Korean + ISO-2022-KR Korean + WINDOWS-874 Thai + WINDOWS-1258 Vietnamese + + UTF-8 + UTF-7 + UNICODE actually UNICODE-LITTLE + UNICODEFEFF actually UNICODE-BIG + + and various DOS character sets: DOS-720, DOS-862, IBM852, CP866. + + We take the union of all these four sets. The result is: + + European and Semitic languages + * ASCII. + We implement this because it is occasionally useful to know or to + check whether some text is entirely ASCII (i.e. if the conversion + ISO-8859-x -> UTF-8 is trivial). + * ISO-8859-{1,2,3,4,5,6,7,8,9,10} + We implement this because they are widely used. Except ISO-8859-4 + which appears to have been superseded by ISO-8859-13 in the baltic + countries. But it's an ISO standard anyway. + * ISO-8859-13 + We implement this because it's a standard in Lithuania and Latvia. + * ISO-8859-14 + We implement this because it's an ISO standard. + * ISO-8859-15 + We implement this because it's increasingly used in Europe, because + of the Euro symbol. + * ISO-8859-16 + We implement this because it's an ISO standard. + * KOI8-R, KOI8-U + We implement this because it appears to be the predominant encoding + on Unix in Russia and Ukraine, respectively. + * KOI8-RU + We implement this because MSIE4 supports it. + * KOI8-T + We implement this because it is the locale encoding in glibc's Tajik + locale. + * PT154 + We implement this because it is the locale encoding in glibc's Kazakh + locale. + * RK1048 + We implement this because it's a standard in Kazakhstan. + * CP{1250,1251,1252,1253,1254,1255,1256,1257} + We implement these because they are the predominant Windows encodings + in Europe. + * CP850 + We implement this because it is mentioned as occurring in the web + in the aforementioned statistics. + * CP862 + We implement this because Ron Aaron says it is sometimes used in web + pages and emails. + * CP866 + We implement this because Netscape Communicator does. + * CP1131 + We implement this because it is the locale encoding of a Belorusian + locale in FreeBSD and MacOS X. + * Mac{Roman,CentralEurope,Croatian,Romania,Cyrillic,Greek,Turkish} and + Mac{Hebrew,Arabic} + We implement these because the Sun JDK does, and because Mac users + don't deserve to be punished. + * Macintosh + We implement this because it is mentioned as occurring in the web + in the aforementioned statistics. + Japanese + * EUC-JP, SHIFT_JIS, ISO-2022-JP + We implement these because they are widely used. EUC-JP and SHIFT_JIS + are more used for files, whereas ISO-2022-JP is recommended for email. + * CP932 + We implement this because it is the Microsoft variant of SHIFT_JIS, + used on Windows. + * ISO-2022-JP-2 + We implement this because it's the common way to represent mails which + make use of JIS X 0212 characters. + * ISO-2022-JP-1 + We implement this because it's in the RFCs, but I don't think it is + really used. + * U90, S90 + We DON'T implement this because I have no informations about what it + is or who uses it. + Simplified Chinese + * EUC-CN = GB2312 + We implement this because it is the widely used representation + of simplified Chinese. + * GBK + We implement this because it appears to be used on Solaris and Windows. + * GB18030 + We implement this because it is an official requirement in the + People's Republic of China. + * ISO-2022-CN + We implement this because it is in the RFCs, but I have no idea + whether it is really used. + * ISO-2022-CN-EXT + We implement this because it's in the RFCs, but I don't think it is + really used. + * HZ = HZ-GB-2312 + We implement this because the RFCs recommend it for Usenet postings, + and because MSIE4 supports it. + Traditional Chinese + * EUC-TW + We implement it because it appears to be used on Unix. + * BIG5 + We implement it because it is the de-facto standard for traditional + Chinese. + * CP950 + We implement this because it is the Microsoft variant of BIG5, used + on Windows. + * BIG5+ + We DON'T implement this because it doesn't appear to be in wide use. + Only the CWEX fonts use this encoding. Furthermore, the conversion + tables in the big5p package are not coherent: If you convert directly, + you get different results than when you convert via GBK. + * BIG5-HKSCS + We implement it because it is the de-facto standard for traditional + Chinese in Hongkong. + Korean + * EUC-KR + We implement these because they appear to be the widely used + representations for Korean. + * CP949 + We implement this because it is the Microsoft variant of EUC-KR, used + on Windows. + * ISO-2022-KR + We implement it because it is in the RFCs and because MSIE4 supports + it, but I have no idea whether it's really used. + * JOHAB + We implement this because it is apparently used on Windows as a locale + encoding (codepage 1361). + * ISO-646-KR + We DON'T implement this because although an old ASCII variant, its + glyph for 0x7E is not clear: RFC 1345 and unicode.org's JOHAB.TXT + say it's a tilde, but Ken Lunde's "CJKV information processing" says + it's an overline. And it is not ISO-IR registered. + Armenian + * ARMSCII-8 + We implement it because XFree86 supports it. + Georgian + * Georgian-Academy, Georgian-PS + We implement these because they appear to be both used for Georgian; + Xfree86 supports them. + Thai + * ISO-8859-11, TIS-620 + We implement these because it seems to be standard for Thai. + * CP874 + We implement this because MSIE4 supports it. + * MacThai + We implement this because the Sun JDK does, and because Mac users + don't deserve to be punished. + Laotian + * MuleLao-1, CP1133 + We implement these because XFree86 supports them. I have no idea which + one is used more widely. + Vietnamese + * VISCII, TCVN + We implement these because XFree86 supports them. + * CP1258 + We implement this because MSIE4 supports it. + Other languages + * NUNACOM-8 (Inuktitut) + We DON'T implement this because it isn't part of Unicode yet, and + therefore doesn't convert to anything except itself. + Platform specifics + * HP-ROMAN8, NEXTSTEP + We implement these because they were the native character set on HPs + and NeXTs for a long time, and libiconv is intended to be usable on + these old machines. + Full Unicode + * UTF-8, UCS-2, UCS-4 + We implement these. Obviously. + * UCS-2BE, UCS-2LE, UCS-4BE, UCS-4LE + We implement these because they are the preferred internal + representation of strings in Unicode aware applications. These are + non-ambiguous names, known to glibc. (glibc doesn't have + UCS-2-INTERNAL and UCS-4-INTERNAL.) + * UTF-16, UTF-16BE, UTF-16LE + We implement these, because UTF-16 is still the favourite encoding of + the president of the Unicode Consortium (for political reasons), and + because they appear in RFC 2781. + * UTF-32, UTF-32BE, UTF-32LE + We implement these because they are part of Unicode 3.1. + * UTF-7 + We implement this because it is essential functionality for mail + applications. + * C99 + We implement it because it's used for C and C++ programs and because + it's a nice encoding for debugging. + * JAVA + We implement it because it's used for Java programs and because it's + a nice encoding for debugging. + * UNICODE (big endian), UNICODEFEFF (little endian) + We DON'T implement these because they are stupid and not standardized. + Full Unicode, in terms of `uint16_t' or `uint32_t' + (with machine dependent endianness and alignment) + * UCS-2-INTERNAL, UCS-4-INTERNAL + We implement these because they are the preferred internal + representation of strings in Unicode aware applications. + +Q: Support encodings mentioned in RFC 1345 ? +A: No, they are not in use any more. Supporting ISO-646 variants is pointless + since ISO-8859-* have been adopted. + +Q: Support EBCDIC ? +A: No! + +Q: How do I add a new character set? +A: 1. Explain the "why" in this file, above. + 2. You need to have a conversion table from/to Unicode. Transform it into + the format used by the mapping tables found on ftp.unicode.org: each line + contains the character code, in hex, with 0x prefix, then whitespace, + then the Unicode code point, in hex, 4 hex digits, with 0x prefix. '#' + counts as a comment delimiter until end of line. + Please also send your table to Mark Leisher so he + can include it in his collection. + 3. If it's an 8-bit character set, use the '8bit_tab_to_h' program in the + tools directory to generate the C code for the conversion. You may tweak + the resulting C code if you are not satisfied with its quality, but this + is rarely needed. + If it's a two-dimensional character set (with rows and columns), use the + 'cjk_tab_to_h' program in the tools directory to generate the C code for + the conversion. You will need to modify the main() function to recognize + the new character set name, with the proper dimensions, but that shouldn't + be too hard. This yields the CCS. The CES you have to write by hand. + 4. Store the resulting C code file in the lib directory. Add a #include + directive to converters.h, and add an entry to the encodings.def file. + 5. Compile the package, and test your new encoding using a program like + iconv(1) or clisp(1). + 6. Augment the testsuite: Add a line to tests/Makefile.in. For a stateless + encoding, create the complete table as a TXT file. For a stateful encoding, + provide a text snippet encoded using your new encoding and its UTF-8 + equivalent. + 7. Update the README and man/iconv_open.3, to mention the new encoding. + Add a note in the NEWS file. + +Q: What about bidirectional text? Should it be tagged or reversed when + converting from ISO-8859-8 or ISO-8859-6 to Unicode? Qt appears to do + this, see qt-2.0.1/src/tools/qrtlcodec.cpp. +A: After reading RFC 1556: I don't think so. Support for ISO-8859-8-I and + ISO-8859-E remains to be implemented. + On the other hand, a page on www.w3c.org says that ISO-8859-8 in *email* + is visually encoded, ISO-8859-8 in *HTML* is logically encoded, i.e. + the same as ISO-8859-8-I. I'm confused. + +Other character sets not implemented: +"MNEMONIC" = "csMnemonic" +"MNEM" = "csMnem" +"ISO-10646-UCS-Basic" = "csUnicodeASCII" +"ISO-10646-Unicode-Latin1" = "csUnicodeLatin1" = "ISO-10646" +"ISO-10646-J-1" +"UNICODE-1-1" = "csUnicode11" +"csWindows31Latin5" + +Other aliases not implemented (and not implemented in glibc-2.1 either): + From MSIE4: + ISO-8859-1: alias ISO8859-1 + ISO-8859-2: alias ISO8859-2 + KSC_5601: alias KS_C_5601 + UTF-8: aliases UNICODE-1-1-UTF-8 UNICODE-2-0-UTF-8 + + +Q: How can I integrate libiconv into my package? +A: Just copy the entire libiconv package into a subdirectory of your package. + At configuration time, call libiconv's configure script with the + appropriate --srcdir option and maybe --enable-static or --disable-shared. + Then "cd libiconv && make && make install-lib libdir=... includedir=...". + 'install-lib' is a special (not GNU standardized) target which installs + only the include file - in $(includedir) - and the library - in $(libdir) - + and does not use other directory variables. After "installing" libiconv + in your package's build directory, building of your package can proceed. + +Q: Why is the testsuite so big? +A: Because some of the tests are very comprehensive. + If you don't feel like using the testsuite, you can simply remove the + tests/ directory. + diff --git a/libs/libiconv/PORTS b/libs/libiconv/PORTS new file mode 100644 index 00000000..2c4cfa03 --- /dev/null +++ b/libs/libiconv/PORTS @@ -0,0 +1,46 @@ +* Linux with libc6 (glibc-2.1): + OK + +* Linux with libc6 (glibc-2.0.7): + OK + +* Linux with libc5: + OK + +* Solaris 2.7: + OK + +* Solaris 2.6: + OK + +* OSF/1 5.1: + OK + +* OSF/1 4.0d: + OK + +* Irix 6.5: + OK + +* HP-UX 10.20: + OK + +* AIX 4.2: + OK + +* SunOS 4: + OK when configured --enable-static --disable-shared + (gcc cannot create shared libraries without relocations) + +* FreeBSD 3.3: + OK + +* BeOS 5: + OK + +* Woe32 with MSVC 4.0: + OK + +* Woe32 with MSVC 5.0: + OK + diff --git a/libs/libiconv/README b/libs/libiconv/README new file mode 100644 index 00000000..2113ce56 --- /dev/null +++ b/libs/libiconv/README @@ -0,0 +1,171 @@ + GNU LIBICONV - character set conversion library + +This library provides an iconv() implementation, for use on systems which +don't have one, or whose implementation cannot convert from/to Unicode. + +It provides support for the encodings: + + European languages + ASCII, ISO-8859-{1,2,3,4,5,7,9,10,13,14,15,16}, + KOI8-R, KOI8-U, KOI8-RU, + CP{1250,1251,1252,1253,1254,1257}, CP{850,866,1131}, + Mac{Roman,CentralEurope,Iceland,Croatian,Romania}, + Mac{Cyrillic,Ukraine,Greek,Turkish}, + Macintosh + Semitic languages + ISO-8859-{6,8}, CP{1255,1256}, CP862, Mac{Hebrew,Arabic} + Japanese + EUC-JP, SHIFT_JIS, CP932, ISO-2022-JP, ISO-2022-JP-2, ISO-2022-JP-1 + Chinese + EUC-CN, HZ, GBK, CP936, GB18030, EUC-TW, BIG5, CP950, BIG5-HKSCS, + BIG5-HKSCS:2004, BIG5-HKSCS:2001, BIG5-HKSCS:1999, ISO-2022-CN, + ISO-2022-CN-EXT + Korean + EUC-KR, CP949, ISO-2022-KR, JOHAB + Armenian + ARMSCII-8 + Georgian + Georgian-Academy, Georgian-PS + Tajik + KOI8-T + Kazakh + PT154, RK1048 + Thai + ISO-8859-11, TIS-620, CP874, MacThai + Laotian + MuleLao-1, CP1133 + Vietnamese + VISCII, TCVN, CP1258 + Platform specifics + HP-ROMAN8, NEXTSTEP + Full Unicode + UTF-8 + UCS-2, UCS-2BE, UCS-2LE + UCS-4, UCS-4BE, UCS-4LE + UTF-16, UTF-16BE, UTF-16LE + UTF-32, UTF-32BE, UTF-32LE + UTF-7 + C99, JAVA + Full Unicode, in terms of `uint16_t' or `uint32_t' + (with machine dependent endianness and alignment) + UCS-2-INTERNAL, UCS-4-INTERNAL + Locale dependent, in terms of `char' or `wchar_t' + (with machine dependent endianness and alignment, and with OS and + locale dependent semantics) + char, wchar_t + The empty encoding name "" is equivalent to "char": it denotes the + locale dependent character encoding. + +When configured with the option --enable-extra-encodings, it also provides +support for a few extra encodings: + + European languages + CP{437,737,775,852,853,855,857,858,860,861,863,865,869,1125} + Semitic languages + CP864 + Japanese + EUC-JISX0213, Shift_JISX0213, ISO-2022-JP-3 + Chinese + BIG5-2003 (experimental) + Turkmen + TDS565 + Platform specifics + ATARIST, RISCOS-LATIN1 + +It can convert from any of these encodings to any other, through Unicode +conversion. + +It has also some limited support for transliteration, i.e. when a character +cannot be represented in the target character set, it can be approximated +through one or several similarly looking characters. Transliteration is +activated when "//TRANSLIT" is appended to the target encoding name. + +libiconv is for you if your application needs to support multiple character +encodings, but that support lacks from your system. + + +Installation +------------ + +As usual for GNU packages: + + $ ./configure --prefix=/usr/local + $ make + $ make install + +After installing GNU libiconv for the first time, it is recommended to +recompile and reinstall GNU gettext, so that it can take advantage of +libiconv. + +On systems other than GNU/Linux, the iconv program will be internationalized +only if GNU gettext has been built and installed before GNU libiconv. This +means that the first time GNU libiconv is installed, we have a circular +dependency between the GNU libiconv and GNU gettext packages, which can be +resolved by building and installing either + - first libiconv, then gettext, then libiconv again, +or (on systems supporting shared libraries, excluding AIX) + - first gettext, then libiconv, then gettext again. +Recall that before building a package for the second time, you need to erase +the traces of the first build by running "make distclean". + +This library can be built and installed in two variants: + + - The library mode. This works on all systems, and uses a library + `libiconv.so' and a header file `'. (Both are installed + through "make install".) + + To use it, simply #include and use the functions. + + To use it in an autoconfiguring package: + - If you don't use automake, append m4/iconv.m4 to your aclocal.m4 + file. + - If you do use automake, add m4/iconv.m4 to your m4 macro repository. + - Add to the link command line of libraries and executables that use + the functions the placeholder @LIBICONV@ (or, if using libtool for + the link, @LTLIBICONV@). If you use automake, the right place for + these additions are the *_LDADD variables. + Note that 'iconv.m4' is also part of the GNU gettext package, which + installs it in /usr/local/share/aclocal/iconv.m4. + + - The libc plug/override mode. This works on GNU/Linux, Solaris and OSF/1 + systems only. It is a way to get good iconv support without having + glibc-2.1. + It installs a library `preloadable_libiconv.so'. This library can be used + with LD_PRELOAD, to override the iconv* functions present in the C library. + + On GNU/Linux and Solaris: + $ export LD_PRELOAD=/usr/local/lib/preloadable_libiconv.so + + On OSF/1: + $ export _RLD_LIST=/usr/local/lib/preloadable_libiconv.so:DEFAULT + + A program's source need not be modified, the program need not even be + recompiled. Just set the LD_PRELOAD environment variable, that's it! + + +Copyright +--------- + +The libiconv and libcharset _libraries_ and their header files are under LGPL, +see file COPYING.LIB. + +The iconv _program_ and the documentation are under GPL, see file COPYING. + + +Download +-------- + + http://ftp.gnu.org/gnu/libiconv/libiconv-1.14.tar.gz + +Homepage +-------- + + http://www.gnu.org/software/libiconv/ + +Bug reports to +-------------- + + + + +Bruno Haible diff --git a/libs/libiconv/README.djgpp b/libs/libiconv/README.djgpp new file mode 100644 index 00000000..aa8c4209 --- /dev/null +++ b/libs/libiconv/README.djgpp @@ -0,0 +1,3 @@ +Installation on DJGPP: + +See the file djgpp/README. diff --git a/libs/libiconv/README.woe32 b/libs/libiconv/README.woe32 new file mode 100644 index 00000000..ae8320bb --- /dev/null +++ b/libs/libiconv/README.woe32 @@ -0,0 +1,37 @@ +Installation on Woe32 (WinNT/2000/XP/Vista/7, Win95/98/ME): + +Building requires the mingw or cygwin development environment (includes gcc). +MS Visual C/C++ with "nmake" is no longer supported. + +This file explains how to create binaries for the mingw execution environment. +For how to create binaries for the cygwin environment, please see the normal +INSTALL file. MS Visual C/C++ with "nmake" is no longer supported. + +I recommend to use the cygwin environment as the development environment +and mingw only as the target (runtime, deployment) environment. +For this, you need to install + - cygwin, + - the mingw runtime package, also from the cygwin site. + +You must not install cygwin programs directly under /usr/local - +because the mingw compiler and linker would pick up the include files +and libraries from there, thus introducing an undesired dependency to +cygwin. You can for example achieve this by using the +configure option --prefix=/usr/local/cygwin each time you build a +program for cygwin. + +Building for mingw is then achieved through the following preparation +and configure commands: + + PATH=/usr/local/mingw/bin:$PATH + export PATH + ./configure --host=i586-pc-mingw32 --prefix=/usr/local/mingw \ + CC="gcc-3 -mno-cygwin" \ + CXX="g++-3 -mno-cygwin" \ + CPPFLAGS="-Wall -I/usr/local/mingw/include" \ + LDFLAGS="-L/usr/local/mingw/lib" + +The -mno-cygwin tells the cygwin compiler and linker to build for mingw. +The -I and -L option are so that packages previously built for the +same environment are found. The --host option tells the various +tools that you are building for mingw, not cygwin. diff --git a/libs/libiconv/THANKS b/libs/libiconv/THANKS new file mode 100644 index 00000000..a6f02ffb --- /dev/null +++ b/libs/libiconv/THANKS @@ -0,0 +1,15 @@ + Thanks to for + +Edmund Grimley Evans bug reports + +Taro Muraoka Woe32 DLL support + +Akira Hatakeyama OS/2 support + +Juan Manuel Guerrero + DOS/DJGPP support + +Hironori Sakamoto advice on EUC-JP and JISX0213 + +Ken Lunde detailed information about GB18030 + diff --git a/libs/libiconv/config.h b/libs/libiconv/config.h new file mode 100644 index 00000000..1bc39bdd --- /dev/null +++ b/libs/libiconv/config.h @@ -0,0 +1,927 @@ +/* config.h. Generated from config.h.in by configure. */ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to the number of bits in type 'ptrdiff_t'. */ +/* #undef BITSIZEOF_PTRDIFF_T */ + +/* Define to the number of bits in type 'sig_atomic_t'. */ +/* #undef BITSIZEOF_SIG_ATOMIC_T */ + +/* Define to the number of bits in type 'size_t'. */ +/* #undef BITSIZEOF_SIZE_T */ + +/* Define to the number of bits in type 'wchar_t'. */ +/* #undef BITSIZEOF_WCHAR_T */ + +/* Define to the number of bits in type 'wint_t'. */ +/* #undef BITSIZEOF_WINT_T */ + +/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP + systems. This function is required for `alloca.c' support on those systems. + */ +/* #undef CRAY_STACKSEG_END */ + +/* Define to 1 if using `alloca.c'. */ +/* #undef C_ALLOCA */ + +/* Define to 1 if // is a file system root distinct from /. */ +/* #undef DOUBLE_SLASH_IS_DISTINCT_ROOT */ + +/* Define as good substitute value for EILSEQ. */ +/* #undef EILSEQ */ + +/* Define to 1 to enable a few rarely used encodings. */ +/* #undef ENABLE_EXTRA */ + +/* Define to 1 if translation of program messages to the user's native + language is requested. */ +#define ENABLE_NLS 1 + +/* Define to 1 if the package shall run at any location in the file system. */ +/* #undef ENABLE_RELOCATABLE */ + +/* Define to 1 if realpath() can malloc memory, always gives an absolute path, + and handles trailing slash correctly. */ +#define FUNC_REALPATH_WORKS 1 + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module canonicalize-lgpl shall be considered present. */ +#define GNULIB_CANONICALIZE_LGPL 1 + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module sigpipe shall be considered present. */ +#define GNULIB_SIGPIPE 1 + +/* Define to a C preprocessor expression that evaluates to 1 or 0, depending + whether the gnulib module strerror shall be considered present. */ +#define GNULIB_STRERROR 1 + +/* Define to 1 when the gnulib module canonicalize_file_name should be tested. + */ +#define GNULIB_TEST_CANONICALIZE_FILE_NAME 1 + +/* Define to 1 when the gnulib module environ should be tested. */ +#define GNULIB_TEST_ENVIRON 1 + +/* Define to 1 when the gnulib module lstat should be tested. */ +#define GNULIB_TEST_LSTAT 1 + +/* Define to 1 when the gnulib module read should be tested. */ +#define GNULIB_TEST_READ 1 + +/* Define to 1 when the gnulib module readlink should be tested. */ +#define GNULIB_TEST_READLINK 1 + +/* Define to 1 when the gnulib module realpath should be tested. */ +#define GNULIB_TEST_REALPATH 1 + +/* Define to 1 when the gnulib module sigprocmask should be tested. */ +#define GNULIB_TEST_SIGPROCMASK 1 + +/* Define to 1 when the gnulib module stat should be tested. */ +#define GNULIB_TEST_STAT 1 + +/* Define to 1 when the gnulib module strerror should be tested. */ +#define GNULIB_TEST_STRERROR 1 + +/* Define to 1 if you have `alloca', as a function or macro. */ +#define HAVE_ALLOCA 1 + +/* Define to 1 if you have and it should be used (not on Ultrix). + */ +#define HAVE_ALLOCA_H 1 + +/* Define to 1 if you have the `canonicalize_file_name' function. */ +#define HAVE_CANONICALIZE_FILE_NAME 1 + +/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the + CoreFoundation framework. */ +/* #undef HAVE_CFLOCALECOPYCURRENT */ + +/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in + the CoreFoundation framework. */ +/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */ + +/* Define if the GNU dcgettext() function is already present or preinstalled. + */ +#define HAVE_DCGETTEXT 1 + +/* Define to 1 if you have the declaration of `clearerr_unlocked', and to 0 if + you don't. */ +#define HAVE_DECL_CLEARERR_UNLOCKED 1 + +/* Define to 1 if you have the declaration of `feof_unlocked', and to 0 if you + don't. */ +#define HAVE_DECL_FEOF_UNLOCKED 1 + +/* Define to 1 if you have the declaration of `ferror_unlocked', and to 0 if + you don't. */ +#define HAVE_DECL_FERROR_UNLOCKED 1 + +/* Define to 1 if you have the declaration of `fflush_unlocked', and to 0 if + you don't. */ +#define HAVE_DECL_FFLUSH_UNLOCKED 1 + +/* Define to 1 if you have the declaration of `fgets_unlocked', and to 0 if + you don't. */ +#define HAVE_DECL_FGETS_UNLOCKED 1 + +/* Define to 1 if you have the declaration of `fputc_unlocked', and to 0 if + you don't. */ +#define HAVE_DECL_FPUTC_UNLOCKED 1 + +/* Define to 1 if you have the declaration of `fputs_unlocked', and to 0 if + you don't. */ +#define HAVE_DECL_FPUTS_UNLOCKED 1 + +/* Define to 1 if you have the declaration of `fread_unlocked', and to 0 if + you don't. */ +#define HAVE_DECL_FREAD_UNLOCKED 1 + +/* Define to 1 if you have the declaration of `fwrite_unlocked', and to 0 if + you don't. */ +#define HAVE_DECL_FWRITE_UNLOCKED 1 + +/* Define to 1 if you have the declaration of `getchar_unlocked', and to 0 if + you don't. */ +#define HAVE_DECL_GETCHAR_UNLOCKED 1 + +/* Define to 1 if you have the declaration of `getc_unlocked', and to 0 if you + don't. */ +#define HAVE_DECL_GETC_UNLOCKED 1 + +/* Define to 1 if you have the declaration of `program_invocation_name', and + to 0 if you don't. */ +#define HAVE_DECL_PROGRAM_INVOCATION_NAME 1 + +/* Define to 1 if you have the declaration of `program_invocation_short_name', + and to 0 if you don't. */ +#define HAVE_DECL_PROGRAM_INVOCATION_SHORT_NAME 1 + +/* Define to 1 if you have the declaration of `putchar_unlocked', and to 0 if + you don't. */ +#define HAVE_DECL_PUTCHAR_UNLOCKED 1 + +/* Define to 1 if you have the declaration of `putc_unlocked', and to 0 if you + don't. */ +#define HAVE_DECL_PUTC_UNLOCKED 1 + +/* Define to 1 if you have the declaration of `setenv', and to 0 if you don't. + */ +#define HAVE_DECL_SETENV 1 + +/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you + don't. */ +#define HAVE_DECL_STRERROR_R 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define if you have the declaration of environ. */ +#define HAVE_ENVIRON_DECL 1 + +/* Define to 1 if you have the `getcwd' function. */ +#define HAVE_GETCWD 1 + +/* Define to 1 if you have the `getc_unlocked' function. */ +#define HAVE_GETC_UNLOCKED 1 + +/* Define if the GNU gettext() function is already present or preinstalled. */ +#define HAVE_GETTEXT 1 + +/* Define if you have the iconv() function and it works. */ +#define HAVE_ICONV 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define if you have and nl_langinfo(CODESET). */ +#define HAVE_LANGINFO_CODESET 1 + +/* Define to 1 if the system has the type `long long int'. */ +#define HAVE_LONG_LONG_INT 1 + +/* Define to 1 if you have the `lstat' function. */ +#define HAVE_LSTAT 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_MACH_O_DYLD_H */ + +/* Define to 1 if you have the `mbrtowc' function. */ +#define HAVE_MBRTOWC 1 + +/* Define to 1 if you have the `mbsinit' function. */ +#define HAVE_MBSINIT 1 + +/* Define to 1 if declares mbstate_t. */ +#define HAVE_MBSTATE_T 1 + +/* Define to 1 if you have the `memmove' function. */ +#define HAVE_MEMMOVE 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if atoll is declared even after undefining macros. */ +#define HAVE_RAW_DECL_ATOLL 1 + +/* Define to 1 if canonicalize_file_name is declared even after undefining + macros. */ +#define HAVE_RAW_DECL_CANONICALIZE_FILE_NAME 1 + +/* Define to 1 if chown is declared even after undefining macros. */ +#define HAVE_RAW_DECL_CHOWN 1 + +/* Define to 1 if dprintf is declared even after undefining macros. */ +#define HAVE_RAW_DECL_DPRINTF 1 + +/* Define to 1 if dup2 is declared even after undefining macros. */ +#define HAVE_RAW_DECL_DUP2 1 + +/* Define to 1 if dup3 is declared even after undefining macros. */ +#define HAVE_RAW_DECL_DUP3 1 + +/* Define to 1 if endusershell is declared even after undefining macros. */ +#define HAVE_RAW_DECL_ENDUSERSHELL 1 + +/* Define to 1 if environ is declared even after undefining macros. */ +#define HAVE_RAW_DECL_ENVIRON 1 + +/* Define to 1 if euidaccess is declared even after undefining macros. */ +#define HAVE_RAW_DECL_EUIDACCESS 1 + +/* Define to 1 if faccessat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_FACCESSAT 1 + +/* Define to 1 if fchdir is declared even after undefining macros. */ +#define HAVE_RAW_DECL_FCHDIR 1 + +/* Define to 1 if fchmodat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_FCHMODAT 1 + +/* Define to 1 if fchownat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_FCHOWNAT 1 + +/* Define to 1 if fcntl is declared even after undefining macros. */ +#define HAVE_RAW_DECL_FCNTL 1 + +/* Define to 1 if ffsl is declared even after undefining macros. */ +#define HAVE_RAW_DECL_FFSL 1 + +/* Define to 1 if ffsll is declared even after undefining macros. */ +#define HAVE_RAW_DECL_FFSLL 1 + +/* Define to 1 if fpurge is declared even after undefining macros. */ +/* #undef HAVE_RAW_DECL_FPURGE */ + +/* Define to 1 if fseeko is declared even after undefining macros. */ +#define HAVE_RAW_DECL_FSEEKO 1 + +/* Define to 1 if fstatat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_FSTATAT 1 + +/* Define to 1 if fsync is declared even after undefining macros. */ +#define HAVE_RAW_DECL_FSYNC 1 + +/* Define to 1 if ftello is declared even after undefining macros. */ +#define HAVE_RAW_DECL_FTELLO 1 + +/* Define to 1 if ftruncate is declared even after undefining macros. */ +#define HAVE_RAW_DECL_FTRUNCATE 1 + +/* Define to 1 if futimens is declared even after undefining macros. */ +#define HAVE_RAW_DECL_FUTIMENS 1 + +/* Define to 1 if getcwd is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GETCWD 1 + +/* Define to 1 if getdelim is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GETDELIM 1 + +/* Define to 1 if getdomainname is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GETDOMAINNAME 1 + +/* Define to 1 if getdtablesize is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GETDTABLESIZE 1 + +/* Define to 1 if getgroups is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GETGROUPS 1 + +/* Define to 1 if gethostname is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GETHOSTNAME 1 + +/* Define to 1 if getline is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GETLINE 1 + +/* Define to 1 if getloadavg is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GETLOADAVG 1 + +/* Define to 1 if getlogin is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GETLOGIN 1 + +/* Define to 1 if getlogin_r is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GETLOGIN_R 1 + +/* Define to 1 if getpagesize is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GETPAGESIZE 1 + +/* Define to 1 if getsubopt is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GETSUBOPT 1 + +/* Define to 1 if getusershell is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GETUSERSHELL 1 + +/* Define to 1 if grantpt is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GRANTPT 1 + +/* Define to 1 if group_member is declared even after undefining macros. */ +#define HAVE_RAW_DECL_GROUP_MEMBER 1 + +/* Define to 1 if initstat_r is declared even after undefining macros. */ +/* #undef HAVE_RAW_DECL_INITSTAT_R */ + +/* Define to 1 if lchmod is declared even after undefining macros. */ +#define HAVE_RAW_DECL_LCHMOD 1 + +/* Define to 1 if lchown is declared even after undefining macros. */ +#define HAVE_RAW_DECL_LCHOWN 1 + +/* Define to 1 if link is declared even after undefining macros. */ +#define HAVE_RAW_DECL_LINK 1 + +/* Define to 1 if linkat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_LINKAT 1 + +/* Define to 1 if lseek is declared even after undefining macros. */ +#define HAVE_RAW_DECL_LSEEK 1 + +/* Define to 1 if lstat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_LSTAT 1 + +/* Define to 1 if memmem is declared even after undefining macros. */ +#define HAVE_RAW_DECL_MEMMEM 1 + +/* Define to 1 if mempcpy is declared even after undefining macros. */ +#define HAVE_RAW_DECL_MEMPCPY 1 + +/* Define to 1 if memrchr is declared even after undefining macros. */ +#define HAVE_RAW_DECL_MEMRCHR 1 + +/* Define to 1 if mkdirat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_MKDIRAT 1 + +/* Define to 1 if mkdtemp is declared even after undefining macros. */ +#define HAVE_RAW_DECL_MKDTEMP 1 + +/* Define to 1 if mkfifo is declared even after undefining macros. */ +#define HAVE_RAW_DECL_MKFIFO 1 + +/* Define to 1 if mkfifoat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_MKFIFOAT 1 + +/* Define to 1 if mknod is declared even after undefining macros. */ +#define HAVE_RAW_DECL_MKNOD 1 + +/* Define to 1 if mknodat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_MKNODAT 1 + +/* Define to 1 if mkostemp is declared even after undefining macros. */ +#define HAVE_RAW_DECL_MKOSTEMP 1 + +/* Define to 1 if mkostemps is declared even after undefining macros. */ +#define HAVE_RAW_DECL_MKOSTEMPS 1 + +/* Define to 1 if mkstemp is declared even after undefining macros. */ +#define HAVE_RAW_DECL_MKSTEMP 1 + +/* Define to 1 if mkstemps is declared even after undefining macros. */ +#define HAVE_RAW_DECL_MKSTEMPS 1 + +/* Define to 1 if openat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_OPENAT 1 + +/* Define to 1 if pipe is declared even after undefining macros. */ +#define HAVE_RAW_DECL_PIPE 1 + +/* Define to 1 if pipe2 is declared even after undefining macros. */ +#define HAVE_RAW_DECL_PIPE2 1 + +/* Define to 1 if popen is declared even after undefining macros. */ +#define HAVE_RAW_DECL_POPEN 1 + +/* Define to 1 if pread is declared even after undefining macros. */ +#define HAVE_RAW_DECL_PREAD 1 + +/* Define to 1 if pthread_sigmask is declared even after undefining macros. */ +#define HAVE_RAW_DECL_PTHREAD_SIGMASK 1 + +/* Define to 1 if ptsname is declared even after undefining macros. */ +#define HAVE_RAW_DECL_PTSNAME 1 + +/* Define to 1 if pwrite is declared even after undefining macros. */ +#define HAVE_RAW_DECL_PWRITE 1 + +/* Define to 1 if random_r is declared even after undefining macros. */ +#define HAVE_RAW_DECL_RANDOM_R 1 + +/* Define to 1 if rawmemchr is declared even after undefining macros. */ +#define HAVE_RAW_DECL_RAWMEMCHR 1 + +/* Define to 1 if readlink is declared even after undefining macros. */ +#define HAVE_RAW_DECL_READLINK 1 + +/* Define to 1 if readlinkat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_READLINKAT 1 + +/* Define to 1 if realpath is declared even after undefining macros. */ +#define HAVE_RAW_DECL_REALPATH 1 + +/* Define to 1 if renameat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_RENAMEAT 1 + +/* Define to 1 if rmdir is declared even after undefining macros. */ +#define HAVE_RAW_DECL_RMDIR 1 + +/* Define to 1 if rpmatch is declared even after undefining macros. */ +#define HAVE_RAW_DECL_RPMATCH 1 + +/* Define to 1 if setenv is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SETENV 1 + +/* Define to 1 if setstate_r is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SETSTATE_R 1 + +/* Define to 1 if setusershell is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SETUSERSHELL 1 + +/* Define to 1 if sigaction is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SIGACTION 1 + +/* Define to 1 if sigaddset is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SIGADDSET 1 + +/* Define to 1 if sigdelset is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SIGDELSET 1 + +/* Define to 1 if sigemptyset is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SIGEMPTYSET 1 + +/* Define to 1 if sigfillset is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SIGFILLSET 1 + +/* Define to 1 if sigismember is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SIGISMEMBER 1 + +/* Define to 1 if sigpending is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SIGPENDING 1 + +/* Define to 1 if sigprocmask is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SIGPROCMASK 1 + +/* Define to 1 if sleep is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SLEEP 1 + +/* Define to 1 if snprintf is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SNPRINTF 1 + +/* Define to 1 if srandom_r is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SRANDOM_R 1 + +/* Define to 1 if stat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STAT 1 + +/* Define to 1 if stpcpy is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STPCPY 1 + +/* Define to 1 if stpncpy is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STPNCPY 1 + +/* Define to 1 if strcasestr is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRCASESTR 1 + +/* Define to 1 if strchrnul is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRCHRNUL 1 + +/* Define to 1 if strdup is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRDUP 1 + +/* Define to 1 if strerror_r is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRERROR_R 1 + +/* Define to 1 if strncat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRNCAT 1 + +/* Define to 1 if strndup is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRNDUP 1 + +/* Define to 1 if strnlen is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRNLEN 1 + +/* Define to 1 if strpbrk is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRPBRK 1 + +/* Define to 1 if strsep is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRSEP 1 + +/* Define to 1 if strsignal is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRSIGNAL 1 + +/* Define to 1 if strtod is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRTOD 1 + +/* Define to 1 if strtok_r is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRTOK_R 1 + +/* Define to 1 if strtoll is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRTOLL 1 + +/* Define to 1 if strtoull is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRTOULL 1 + +/* Define to 1 if strverscmp is declared even after undefining macros. */ +#define HAVE_RAW_DECL_STRVERSCMP 1 + +/* Define to 1 if symlink is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SYMLINK 1 + +/* Define to 1 if symlinkat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_SYMLINKAT 1 + +/* Define to 1 if tmpfile is declared even after undefining macros. */ +#define HAVE_RAW_DECL_TMPFILE 1 + +/* Define to 1 if ttyname_r is declared even after undefining macros. */ +#define HAVE_RAW_DECL_TTYNAME_R 1 + +/* Define to 1 if unlink is declared even after undefining macros. */ +#define HAVE_RAW_DECL_UNLINK 1 + +/* Define to 1 if unlinkat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_UNLINKAT 1 + +/* Define to 1 if unlockpt is declared even after undefining macros. */ +#define HAVE_RAW_DECL_UNLOCKPT 1 + +/* Define to 1 if unsetenv is declared even after undefining macros. */ +#define HAVE_RAW_DECL_UNSETENV 1 + +/* Define to 1 if usleep is declared even after undefining macros. */ +#define HAVE_RAW_DECL_USLEEP 1 + +/* Define to 1 if utimensat is declared even after undefining macros. */ +#define HAVE_RAW_DECL_UTIMENSAT 1 + +/* Define to 1 if vdprintf is declared even after undefining macros. */ +#define HAVE_RAW_DECL_VDPRINTF 1 + +/* Define to 1 if vsnprintf is declared even after undefining macros. */ +#define HAVE_RAW_DECL_VSNPRINTF 1 + +/* Define to 1 if _Exit is declared even after undefining macros. */ +#define HAVE_RAW_DECL__EXIT 1 + +/* Define to 1 if you have the `readlink' function. */ +#define HAVE_READLINK 1 + +/* Define to 1 if you have the `readlinkat' function. */ +#define HAVE_READLINKAT 1 + +/* Define to 1 if you have the `realpath' function. */ +#define HAVE_REALPATH 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SEARCH_H 1 + +/* Define to 1 if you have the `setenv' function. */ +#define HAVE_SETENV 1 + +/* Define to 1 if you have the `setlocale' function. */ +#define HAVE_SETLOCALE 1 + +/* Define to 1 if 'sig_atomic_t' is a signed integer type. */ +/* #undef HAVE_SIGNED_SIG_ATOMIC_T */ + +/* Define to 1 if 'wchar_t' is a signed integer type. */ +/* #undef HAVE_SIGNED_WCHAR_T */ + +/* Define to 1 if 'wint_t' is a signed integer type. */ +/* #undef HAVE_SIGNED_WINT_T */ + +/* Define to 1 if the system has the type `sigset_t'. */ +#define HAVE_SIGSET_T 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strerror_r' function. */ +#define HAVE_STRERROR_R 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_BITYPES_H */ + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_SYS_INTTYPES_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the `tsearch' function. */ +#define HAVE_TSEARCH 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if the system has the type `unsigned long long int'. */ +#define HAVE_UNSIGNED_LONG_LONG_INT 1 + +/* Define to 1 or 0, depending whether the compiler supports simple visibility + declarations. */ +#define HAVE_VISIBILITY 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_WCHAR_H 1 + +/* Define if you have the 'wchar_t' type. */ +#define HAVE_WCHAR_T 1 + +/* Define to 1 if you have the `wcrtomb' function. */ +#define HAVE_WCRTOMB 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_WINSOCK2_H */ + +/* Define to 1 if O_NOATIME works. */ +#define HAVE_WORKING_O_NOATIME 0 + +/* Define to 1 if O_NOFOLLOW works. */ +#define HAVE_WORKING_O_NOFOLLOW 1 + +/* Define to 1 if the system has the type `_Bool'. */ +#define HAVE__BOOL 1 + +/* Define to 1 if you have the `_NSGetExecutablePath' function. */ +/* #undef HAVE__NSGETEXECUTABLEPATH */ + +/* Define as const if the declaration of iconv() needs const. */ +#define ICONV_CONST + +/* Define to the value of ${prefix}, as a string. */ +#define INSTALLPREFIX "/usr/local" + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing + slash. */ +#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* If malloc(0) is != NULL, define this to 1. Otherwise define this to 0. */ +#define MALLOC_0_IS_NONNULL 1 + +/* Define to 1 if your C compiler doesn't accept -c and -o together. */ +/* #undef NO_MINUS_C_MINUS_O */ + +/* Name of package */ +#define PACKAGE "libiconv" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "" + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'ptrdiff_t'. */ +/* #undef PTRDIFF_T_SUFFIX */ + +/* Define to 1 if readlink fails to recognize a trailing slash. */ +/* #undef READLINK_TRAILING_SLASH_BUG */ + +/* Define to 1 if stat needs help when passed a directory name with a trailing + slash */ +/* #undef REPLACE_FUNC_STAT_DIR */ + +/* Define to 1 if stat needs help when passed a file name with a trailing + slash */ +/* #undef REPLACE_FUNC_STAT_FILE */ + +/* Define to 1 if strerror(0) does not return a message implying success. */ +/* #undef REPLACE_STRERROR_0 */ + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'sig_atomic_t'. */ +/* #undef SIG_ATOMIC_T_SUFFIX */ + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'size_t'. */ +/* #undef SIZE_T_SUFFIX */ + +/* If using the C implementation of alloca, define if you know the + direction of stack growth for your system; otherwise it will be + automatically deduced at runtime. + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ +/* #undef STACK_DIRECTION */ + +/* Define to 1 if the `S_IS*' macros in do not work properly. */ +/* #undef STAT_MACROS_BROKEN */ + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Define to 1 if strerror_r returns char *. */ +#define STRERROR_R_CHAR_P 1 + +/* Define to the prefix of C symbols at the assembler and linker level, either + an underscore or empty. */ +#define USER_LABEL_PREFIX + +/* Define to 1 if you want getc etc. to use unlocked I/O if available. + Unlocked I/O can improve performance in unithreaded apps, but it is not + safe for multithreaded apps. */ +#define USE_UNLOCKED_IO 1 + +/* Version number of package */ +#define VERSION "1.14" + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'wchar_t'. */ +/* #undef WCHAR_T_SUFFIX */ + +/* Define to l, ll, u, ul, ull, etc., as suitable for constants of type + 'wint_t'. */ +/* #undef WINT_T_SUFFIX */ + +/* Define if the machine's byte ordering is little endian. */ +#define WORDS_LITTLEENDIAN 1 + +/* Define to 1 if on MINIX. */ +/* #undef _MINIX */ + +/* The _Noreturn keyword of draft C1X. */ +#ifndef _Noreturn +# if (3 <= __GNUC__ || (__GNUC__ == 2 && 8 <= __GNUC_MINOR__) \ + || 0x5110 <= __SUNPRO_C) +# define _Noreturn __attribute__ ((__noreturn__)) +# elif 1200 <= _MSC_VER +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn +# endif +#endif + + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define to 500 only on HP-UX. */ +/* #undef _XOPEN_SOURCE */ + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# define _ALL_SOURCE 1 +#endif +/* Enable general extensions on MacOS X. */ +#ifndef _DARWIN_C_SOURCE +# define _DARWIN_C_SOURCE 1 +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS 1 +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# define _TANDEM_SOURCE 1 +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# define __EXTENSIONS__ 1 +#endif + + +/* Define to `int' if doesn't define. */ +/* #undef gid_t */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +#ifndef __cplusplus +/* #undef inline */ +#endif + +/* Work around a bug in Apple GCC 4.0.1 build 5465: In C99 mode, it supports + the ISO C 99 semantics of 'extern inline' (unlike the GNU C semantics of + earlier versions), but does not display it by setting __GNUC_STDC_INLINE__. + __APPLE__ && __MACH__ test for MacOS X. + __APPLE_CC__ tests for the Apple compiler and its version. + __STDC_VERSION__ tests for the C99 mode. */ +#if defined __APPLE__ && defined __MACH__ && __APPLE_CC__ >= 5465 && !defined __cplusplus && __STDC_VERSION__ >= 199901L && !defined __GNUC_STDC_INLINE__ +# define __GNUC_STDC_INLINE__ 1 +#endif + +/* Define to a type if does not define. */ +/* #undef mbstate_t */ + +/* Define to the type of st_nlink in struct stat, or a supertype. */ +/* #undef nlink_t */ + +/* Define to the equivalent of the C99 'restrict' keyword, or to + nothing if this is not supported. Do not define if restrict is + supported directly. */ +#define restrict __restrict +/* Work around a bug in Sun C++: it does not support _Restrict or + __restrict__, even though the corresponding Sun C compiler ends up with + "#define restrict _Restrict" or "#define restrict __restrict__" in the + previous line. Perhaps some future version of Sun C++ will work with + restrict; if so, hopefully it defines __RESTRICT like Sun C does. */ +#if defined __SUNPRO_CC && !defined __RESTRICT +# define _Restrict +# define __restrict__ +#endif + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* Define as a signed type of the same size as size_t. */ +/* #undef ssize_t */ + +/* Define to `int' if doesn't define. */ +/* #undef uid_t */ + +/* Define as a marker that can be attached to declarations that might not + be used. This helps to reduce warnings, such as from + GCC -Wunused-parameter. */ +#if __GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) +# define _GL_UNUSED __attribute__ ((__unused__)) +#else +# define _GL_UNUSED +#endif +/* The name _UNUSED_PARAMETER_ is an earlier spelling, although the name + is a misnomer outside of parameter lists. */ +#define _UNUSED_PARAMETER_ _GL_UNUSED + +/* The __pure__ attribute was added in gcc 2.96. */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96) +# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) +#else +# define _GL_ATTRIBUTE_PURE /* empty */ +#endif + +/* The __const__ attribute was added in gcc 2.95. */ +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95) +# define _GL_ATTRIBUTE_CONST __attribute__ ((__const__)) +#else +# define _GL_ATTRIBUTE_CONST /* empty */ +#endif + + + +/* On Windows, variables that may be in a DLL must be marked specially. */ +#if defined _MSC_VER && defined _DLL +# define DLL_VARIABLE __declspec (dllimport) +#else +# define DLL_VARIABLE +#endif + diff --git a/libs/libiconv/include/iconv.h b/libs/libiconv/include/iconv.h new file mode 100644 index 00000000..987a11ec --- /dev/null +++ b/libs/libiconv/include/iconv.h @@ -0,0 +1,248 @@ +/* Copyright (C) 1999-2003, 2005-2006, 2008-2011 Free Software Foundation, Inc. + This file is part of the GNU LIBICONV Library. + + The GNU LIBICONV Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + The GNU LIBICONV Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU LIBICONV Library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* When installed, this file is called "iconv.h". */ + +#ifndef _LIBICONV_H +#define _LIBICONV_H + +#define _LIBICONV_VERSION 0x010E /* version number: (major<<8) + minor */ + +#if 1 && BUILDING_LIBICONV +#define LIBICONV_DLL_EXPORTED __attribute__((__visibility__("default"))) +#else +#define LIBICONV_DLL_EXPORTED +#endif +extern LIBICONV_DLL_EXPORTED int _libiconv_version; /* Likewise */ + +/* We would like to #include any system header file which could define + iconv_t, 1. in order to eliminate the risk that the user gets compilation + errors because some other system header file includes /usr/include/iconv.h + which defines iconv_t or declares iconv after this file, 2. when compiling + for LIBICONV_PLUG, we need the proper iconv_t type in order to produce + binary compatible code. + But gcc's #include_next is not portable. Thus, once libiconv's iconv.h + has been installed in /usr/local/include, there is no way any more to + include the original /usr/include/iconv.h. We simply have to get away + without it. + Ad 1. The risk that a system header file does + #include "iconv.h" or #include_next "iconv.h" + is small. They all do #include . + Ad 2. The iconv_t type is a pointer type in all cases I have seen. (It + has to be a scalar type because (iconv_t)(-1) is a possible return value + from iconv_open().) */ + +/* Define iconv_t ourselves. */ +#undef iconv_t +#define iconv_t libiconv_t +typedef void* iconv_t; + +/* Get size_t declaration. + Get wchar_t declaration if it exists. */ +#include + +/* Get errno declaration and values. */ +#include +/* Some systems, like SunOS 4, don't have EILSEQ. Some systems, like BSD/OS, + have EILSEQ in a different header. On these systems, define EILSEQ + ourselves. */ +#ifndef EILSEQ +#define EILSEQ +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Allocates descriptor for code conversion from encoding ‘fromcode’ to + encoding ‘tocode’. */ +#ifndef LIBICONV_PLUG +#define iconv_open libiconv_open +#endif +extern LIBICONV_DLL_EXPORTED iconv_t iconv_open (const char* tocode, const char* fromcode); + +/* Converts, using conversion descriptor ‘cd’, at most ‘*inbytesleft’ bytes + starting at ‘*inbuf’, writing at most ‘*outbytesleft’ bytes starting at + ‘*outbuf’. + Decrements ‘*inbytesleft’ and increments ‘*inbuf’ by the same amount. + Decrements ‘*outbytesleft’ and increments ‘*outbuf’ by the same amount. */ +#ifndef LIBICONV_PLUG +#define iconv libiconv +#endif +extern LIBICONV_DLL_EXPORTED size_t iconv (iconv_t cd, char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft); + +/* Frees resources allocated for conversion descriptor ‘cd’. */ +#ifndef LIBICONV_PLUG +#define iconv_close libiconv_close +#endif +extern LIBICONV_DLL_EXPORTED int iconv_close (iconv_t cd); + + +#ifdef __cplusplus +} +#endif + + +#ifndef LIBICONV_PLUG + +/* Nonstandard extensions. */ + +#if 1 +#if 0 +/* Tru64 with Desktop Toolkit C has a bug: must be included before + . + BSD/OS 4.0.1 has a bug: , and must be + included before . */ +#include +#include +#include +#endif +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* A type that holds all memory needed by a conversion descriptor. + A pointer to such an object can be used as an iconv_t. */ +typedef struct { + void* dummy1[28]; +#if 1 + mbstate_t dummy2; +#endif +} iconv_allocation_t; + +/* Allocates descriptor for code conversion from encoding ‘fromcode’ to + encoding ‘tocode’ into preallocated memory. Returns an error indicator + (0 or -1 with errno set). */ +#define iconv_open_into libiconv_open_into +extern LIBICONV_DLL_EXPORTED int iconv_open_into (const char* tocode, const char* fromcode, + iconv_allocation_t* resultp); + +/* Control of attributes. */ +#define iconvctl libiconvctl +extern LIBICONV_DLL_EXPORTED int iconvctl (iconv_t cd, int request, void* argument); + +/* Hook performed after every successful conversion of a Unicode character. */ +typedef void (*iconv_unicode_char_hook) (unsigned int uc, void* data); +/* Hook performed after every successful conversion of a wide character. */ +typedef void (*iconv_wide_char_hook) (wchar_t wc, void* data); +/* Set of hooks. */ +struct iconv_hooks { + iconv_unicode_char_hook uc_hook; + iconv_wide_char_hook wc_hook; + void* data; +}; + +/* Fallback function. Invoked when a small number of bytes could not be + converted to a Unicode character. This function should process all + bytes from inbuf and may produce replacement Unicode characters by calling + the write_replacement callback repeatedly. */ +typedef void (*iconv_unicode_mb_to_uc_fallback) + (const char* inbuf, size_t inbufsize, + void (*write_replacement) (const unsigned int *buf, size_t buflen, + void* callback_arg), + void* callback_arg, + void* data); +/* Fallback function. Invoked when a Unicode character could not be converted + to the target encoding. This function should process the character and + may produce replacement bytes (in the target encoding) by calling the + write_replacement callback repeatedly. */ +typedef void (*iconv_unicode_uc_to_mb_fallback) + (unsigned int code, + void (*write_replacement) (const char *buf, size_t buflen, + void* callback_arg), + void* callback_arg, + void* data); +#if 1 +/* Fallback function. Invoked when a number of bytes could not be converted to + a wide character. This function should process all bytes from inbuf and may + produce replacement wide characters by calling the write_replacement + callback repeatedly. */ +typedef void (*iconv_wchar_mb_to_wc_fallback) + (const char* inbuf, size_t inbufsize, + void (*write_replacement) (const wchar_t *buf, size_t buflen, + void* callback_arg), + void* callback_arg, + void* data); +/* Fallback function. Invoked when a wide character could not be converted to + the target encoding. This function should process the character and may + produce replacement bytes (in the target encoding) by calling the + write_replacement callback repeatedly. */ +typedef void (*iconv_wchar_wc_to_mb_fallback) + (wchar_t code, + void (*write_replacement) (const char *buf, size_t buflen, + void* callback_arg), + void* callback_arg, + void* data); +#else +/* If the wchar_t type does not exist, these two fallback functions are never + invoked. Their argument list therefore does not matter. */ +typedef void (*iconv_wchar_mb_to_wc_fallback) (); +typedef void (*iconv_wchar_wc_to_mb_fallback) (); +#endif +/* Set of fallbacks. */ +struct iconv_fallbacks { + iconv_unicode_mb_to_uc_fallback mb_to_uc_fallback; + iconv_unicode_uc_to_mb_fallback uc_to_mb_fallback; + iconv_wchar_mb_to_wc_fallback mb_to_wc_fallback; + iconv_wchar_wc_to_mb_fallback wc_to_mb_fallback; + void* data; +}; + +/* Requests for iconvctl. */ +#define ICONV_TRIVIALP 0 /* int *argument */ +#define ICONV_GET_TRANSLITERATE 1 /* int *argument */ +#define ICONV_SET_TRANSLITERATE 2 /* const int *argument */ +#define ICONV_GET_DISCARD_ILSEQ 3 /* int *argument */ +#define ICONV_SET_DISCARD_ILSEQ 4 /* const int *argument */ +#define ICONV_SET_HOOKS 5 /* const struct iconv_hooks *argument */ +#define ICONV_SET_FALLBACKS 6 /* const struct iconv_fallbacks *argument */ + +/* Listing of locale independent encodings. */ +#define iconvlist libiconvlist +extern LIBICONV_DLL_EXPORTED void iconvlist (int (*do_one) (unsigned int namescount, + const char * const * names, + void* data), + void* data); + +/* Canonicalize an encoding name. + The result is either a canonical encoding name, or name itself. */ +extern LIBICONV_DLL_EXPORTED const char * iconv_canonicalize (const char * name); + +/* Support for relocatable packages. */ + +/* Sets the original and the current installation prefix of the package. + Relocation simply replaces a pathname starting with the original prefix + by the corresponding pathname with the current prefix instead. Both + prefixes should be directory names without trailing slash (i.e. use "" + instead of "/"). */ +extern LIBICONV_DLL_EXPORTED void libiconv_set_relocation_prefix (const char *orig_prefix, + const char *curr_prefix); + +#ifdef __cplusplus +} +#endif + +#endif + + +#endif /* _LIBICONV_H */ diff --git a/libs/libiconv/lib/aliases.gperf b/libs/libiconv/lib/aliases.gperf new file mode 100644 index 00000000..fe647a03 --- /dev/null +++ b/libs/libiconv/lib/aliases.gperf @@ -0,0 +1,358 @@ +struct alias { int name; unsigned int encoding_index; }; +%struct-type +%language=ANSI-C +%define hash-function-name aliases_hash +%define lookup-function-name aliases_lookup +%7bit +%readonly-tables +%global-table +%define word-array-name aliases +%pic +%% +US-ASCII, ei_ascii +ASCII, ei_ascii +ISO646-US, ei_ascii +ISO_646.IRV:1991, ei_ascii +ISO-IR-6, ei_ascii +ANSI_X3.4-1968, ei_ascii +ANSI_X3.4-1986, ei_ascii +CP367, ei_ascii +IBM367, ei_ascii +US, ei_ascii +CSASCII, ei_ascii +UTF-8, ei_utf8 +UCS-2, ei_ucs2 +ISO-10646-UCS-2, ei_ucs2 +CSUNICODE, ei_ucs2 +UCS-2BE, ei_ucs2be +UNICODEBIG, ei_ucs2be +UNICODE-1-1, ei_ucs2be +CSUNICODE11, ei_ucs2be +UCS-2LE, ei_ucs2le +UNICODELITTLE, ei_ucs2le +UCS-4, ei_ucs4 +ISO-10646-UCS-4, ei_ucs4 +CSUCS4, ei_ucs4 +UCS-4BE, ei_ucs4be +UCS-4LE, ei_ucs4le +UTF-16, ei_utf16 +UTF-16BE, ei_utf16be +UTF-16LE, ei_utf16le +UTF-32, ei_utf32 +UTF-32BE, ei_utf32be +UTF-32LE, ei_utf32le +UTF-7, ei_utf7 +UNICODE-1-1-UTF-7, ei_utf7 +CSUNICODE11UTF7, ei_utf7 +UCS-2-INTERNAL, ei_ucs2internal +UCS-2-SWAPPED, ei_ucs2swapped +UCS-4-INTERNAL, ei_ucs4internal +UCS-4-SWAPPED, ei_ucs4swapped +C99, ei_c99 +JAVA, ei_java +ISO-8859-1, ei_iso8859_1 +ISO_8859-1, ei_iso8859_1 +ISO_8859-1:1987, ei_iso8859_1 +ISO-IR-100, ei_iso8859_1 +CP819, ei_iso8859_1 +IBM819, ei_iso8859_1 +LATIN1, ei_iso8859_1 +L1, ei_iso8859_1 +CSISOLATIN1, ei_iso8859_1 +ISO8859-1, ei_iso8859_1 +ISO-8859-2, ei_iso8859_2 +ISO_8859-2, ei_iso8859_2 +ISO_8859-2:1987, ei_iso8859_2 +ISO-IR-101, ei_iso8859_2 +LATIN2, ei_iso8859_2 +L2, ei_iso8859_2 +CSISOLATIN2, ei_iso8859_2 +ISO8859-2, ei_iso8859_2 +ISO-8859-3, ei_iso8859_3 +ISO_8859-3, ei_iso8859_3 +ISO_8859-3:1988, ei_iso8859_3 +ISO-IR-109, ei_iso8859_3 +LATIN3, ei_iso8859_3 +L3, ei_iso8859_3 +CSISOLATIN3, ei_iso8859_3 +ISO8859-3, ei_iso8859_3 +ISO-8859-4, ei_iso8859_4 +ISO_8859-4, ei_iso8859_4 +ISO_8859-4:1988, ei_iso8859_4 +ISO-IR-110, ei_iso8859_4 +LATIN4, ei_iso8859_4 +L4, ei_iso8859_4 +CSISOLATIN4, ei_iso8859_4 +ISO8859-4, ei_iso8859_4 +ISO-8859-5, ei_iso8859_5 +ISO_8859-5, ei_iso8859_5 +ISO_8859-5:1988, ei_iso8859_5 +ISO-IR-144, ei_iso8859_5 +CYRILLIC, ei_iso8859_5 +CSISOLATINCYRILLIC, ei_iso8859_5 +ISO8859-5, ei_iso8859_5 +ISO-8859-6, ei_iso8859_6 +ISO_8859-6, ei_iso8859_6 +ISO_8859-6:1987, ei_iso8859_6 +ISO-IR-127, ei_iso8859_6 +ECMA-114, ei_iso8859_6 +ASMO-708, ei_iso8859_6 +ARABIC, ei_iso8859_6 +CSISOLATINARABIC, ei_iso8859_6 +ISO8859-6, ei_iso8859_6 +ISO-8859-7, ei_iso8859_7 +ISO_8859-7, ei_iso8859_7 +ISO_8859-7:1987, ei_iso8859_7 +ISO_8859-7:2003, ei_iso8859_7 +ISO-IR-126, ei_iso8859_7 +ECMA-118, ei_iso8859_7 +ELOT_928, ei_iso8859_7 +GREEK8, ei_iso8859_7 +GREEK, ei_iso8859_7 +CSISOLATINGREEK, ei_iso8859_7 +ISO8859-7, ei_iso8859_7 +ISO-8859-8, ei_iso8859_8 +ISO_8859-8, ei_iso8859_8 +ISO_8859-8:1988, ei_iso8859_8 +ISO-IR-138, ei_iso8859_8 +HEBREW, ei_iso8859_8 +CSISOLATINHEBREW, ei_iso8859_8 +ISO8859-8, ei_iso8859_8 +ISO-8859-9, ei_iso8859_9 +ISO_8859-9, ei_iso8859_9 +ISO_8859-9:1989, ei_iso8859_9 +ISO-IR-148, ei_iso8859_9 +LATIN5, ei_iso8859_9 +L5, ei_iso8859_9 +CSISOLATIN5, ei_iso8859_9 +ISO8859-9, ei_iso8859_9 +ISO-8859-10, ei_iso8859_10 +ISO_8859-10, ei_iso8859_10 +ISO_8859-10:1992, ei_iso8859_10 +ISO-IR-157, ei_iso8859_10 +LATIN6, ei_iso8859_10 +L6, ei_iso8859_10 +CSISOLATIN6, ei_iso8859_10 +ISO8859-10, ei_iso8859_10 +ISO-8859-11, ei_iso8859_11 +ISO_8859-11, ei_iso8859_11 +ISO8859-11, ei_iso8859_11 +ISO-8859-13, ei_iso8859_13 +ISO_8859-13, ei_iso8859_13 +ISO-IR-179, ei_iso8859_13 +LATIN7, ei_iso8859_13 +L7, ei_iso8859_13 +ISO8859-13, ei_iso8859_13 +ISO-8859-14, ei_iso8859_14 +ISO_8859-14, ei_iso8859_14 +ISO_8859-14:1998, ei_iso8859_14 +ISO-IR-199, ei_iso8859_14 +LATIN8, ei_iso8859_14 +L8, ei_iso8859_14 +ISO-CELTIC, ei_iso8859_14 +ISO8859-14, ei_iso8859_14 +ISO-8859-15, ei_iso8859_15 +ISO_8859-15, ei_iso8859_15 +ISO_8859-15:1998, ei_iso8859_15 +ISO-IR-203, ei_iso8859_15 +LATIN-9, ei_iso8859_15 +ISO8859-15, ei_iso8859_15 +ISO-8859-16, ei_iso8859_16 +ISO_8859-16, ei_iso8859_16 +ISO_8859-16:2001, ei_iso8859_16 +ISO-IR-226, ei_iso8859_16 +LATIN10, ei_iso8859_16 +L10, ei_iso8859_16 +ISO8859-16, ei_iso8859_16 +KOI8-R, ei_koi8_r +CSKOI8R, ei_koi8_r +KOI8-U, ei_koi8_u +KOI8-RU, ei_koi8_ru +CP1250, ei_cp1250 +WINDOWS-1250, ei_cp1250 +MS-EE, ei_cp1250 +CP1251, ei_cp1251 +WINDOWS-1251, ei_cp1251 +MS-CYRL, ei_cp1251 +CP1252, ei_cp1252 +WINDOWS-1252, ei_cp1252 +MS-ANSI, ei_cp1252 +CP1253, ei_cp1253 +WINDOWS-1253, ei_cp1253 +MS-GREEK, ei_cp1253 +CP1254, ei_cp1254 +WINDOWS-1254, ei_cp1254 +MS-TURK, ei_cp1254 +CP1255, ei_cp1255 +WINDOWS-1255, ei_cp1255 +MS-HEBR, ei_cp1255 +CP1256, ei_cp1256 +WINDOWS-1256, ei_cp1256 +MS-ARAB, ei_cp1256 +CP1257, ei_cp1257 +WINDOWS-1257, ei_cp1257 +WINBALTRIM, ei_cp1257 +CP1258, ei_cp1258 +WINDOWS-1258, ei_cp1258 +CP850, ei_cp850 +IBM850, ei_cp850 +850, ei_cp850 +CSPC850MULTILINGUAL, ei_cp850 +CP862, ei_cp862 +IBM862, ei_cp862 +862, ei_cp862 +CSPC862LATINHEBREW, ei_cp862 +CP866, ei_cp866 +IBM866, ei_cp866 +866, ei_cp866 +CSIBM866, ei_cp866 +CP1131, ei_cp1131 +MACROMAN, ei_mac_roman +MACINTOSH, ei_mac_roman +MAC, ei_mac_roman +CSMACINTOSH, ei_mac_roman +MACCENTRALEUROPE, ei_mac_centraleurope +MACICELAND, ei_mac_iceland +MACCROATIAN, ei_mac_croatian +MACROMANIA, ei_mac_romania +MACCYRILLIC, ei_mac_cyrillic +MACUKRAINE, ei_mac_ukraine +MACGREEK, ei_mac_greek +MACTURKISH, ei_mac_turkish +MACHEBREW, ei_mac_hebrew +MACARABIC, ei_mac_arabic +MACTHAI, ei_mac_thai +HP-ROMAN8, ei_hp_roman8 +ROMAN8, ei_hp_roman8 +R8, ei_hp_roman8 +CSHPROMAN8, ei_hp_roman8 +NEXTSTEP, ei_nextstep +ARMSCII-8, ei_armscii_8 +GEORGIAN-ACADEMY, ei_georgian_academy +GEORGIAN-PS, ei_georgian_ps +KOI8-T, ei_koi8_t +PT154, ei_pt154 +PTCP154, ei_pt154 +CP154, ei_pt154 +CYRILLIC-ASIAN, ei_pt154 +CSPTCP154, ei_pt154 +RK1048, ei_rk1048 +STRK1048-2002, ei_rk1048 +KZ-1048, ei_rk1048 +CSKZ1048, ei_rk1048 +MULELAO-1, ei_mulelao +CP1133, ei_cp1133 +IBM-CP1133, ei_cp1133 +TIS-620, ei_tis620 +TIS620, ei_tis620 +TIS620-0, ei_tis620 +TIS620.2529-1, ei_tis620 +TIS620.2533-0, ei_tis620 +TIS620.2533-1, ei_tis620 +ISO-IR-166, ei_tis620 +CP874, ei_cp874 +WINDOWS-874, ei_cp874 +VISCII, ei_viscii +VISCII1.1-1, ei_viscii +CSVISCII, ei_viscii +TCVN, ei_tcvn +TCVN-5712, ei_tcvn +TCVN5712-1, ei_tcvn +TCVN5712-1:1993, ei_tcvn +JIS_C6220-1969-RO, ei_iso646_jp +ISO646-JP, ei_iso646_jp +ISO-IR-14, ei_iso646_jp +JP, ei_iso646_jp +CSISO14JISC6220RO, ei_iso646_jp +JIS_X0201, ei_jisx0201 +JISX0201-1976, ei_jisx0201 +X0201, ei_jisx0201 +CSHALFWIDTHKATAKANA, ei_jisx0201 +JIS_X0208, ei_jisx0208 +JIS_X0208-1983, ei_jisx0208 +JIS_X0208-1990, ei_jisx0208 +JIS0208, ei_jisx0208 +X0208, ei_jisx0208 +ISO-IR-87, ei_jisx0208 +JIS_C6226-1983, ei_jisx0208 +CSISO87JISX0208, ei_jisx0208 +JIS_X0212, ei_jisx0212 +JIS_X0212.1990-0, ei_jisx0212 +JIS_X0212-1990, ei_jisx0212 +X0212, ei_jisx0212 +ISO-IR-159, ei_jisx0212 +CSISO159JISX02121990, ei_jisx0212 +GB_1988-80, ei_iso646_cn +ISO646-CN, ei_iso646_cn +ISO-IR-57, ei_iso646_cn +CN, ei_iso646_cn +CSISO57GB1988, ei_iso646_cn +GB_2312-80, ei_gb2312 +ISO-IR-58, ei_gb2312 +CSISO58GB231280, ei_gb2312 +CHINESE, ei_gb2312 +ISO-IR-165, ei_isoir165 +CN-GB-ISOIR165, ei_isoir165 +KSC_5601, ei_ksc5601 +KS_C_5601-1987, ei_ksc5601 +KS_C_5601-1989, ei_ksc5601 +ISO-IR-149, ei_ksc5601 +CSKSC56011987, ei_ksc5601 +KOREAN, ei_ksc5601 +EUC-JP, ei_euc_jp +EUCJP, ei_euc_jp +EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE, ei_euc_jp +CSEUCPKDFMTJAPANESE, ei_euc_jp +SHIFT_JIS, ei_sjis +SHIFT-JIS, ei_sjis +SJIS, ei_sjis +MS_KANJI, ei_sjis +CSSHIFTJIS, ei_sjis +CP932, ei_cp932 +ISO-2022-JP, ei_iso2022_jp +CSISO2022JP, ei_iso2022_jp +ISO-2022-JP-1, ei_iso2022_jp1 +ISO-2022-JP-2, ei_iso2022_jp2 +CSISO2022JP2, ei_iso2022_jp2 +EUC-CN, ei_euc_cn +EUCCN, ei_euc_cn +GB2312, ei_euc_cn +CN-GB, ei_euc_cn +CSGB2312, ei_euc_cn +GBK, ei_ces_gbk +CP936, ei_cp936 +MS936, ei_cp936 +WINDOWS-936, ei_cp936 +GB18030, ei_gb18030 +ISO-2022-CN, ei_iso2022_cn +CSISO2022CN, ei_iso2022_cn +ISO-2022-CN-EXT, ei_iso2022_cn_ext +HZ, ei_hz +HZ-GB-2312, ei_hz +EUC-TW, ei_euc_tw +EUCTW, ei_euc_tw +CSEUCTW, ei_euc_tw +BIG5, ei_ces_big5 +BIG-5, ei_ces_big5 +BIG-FIVE, ei_ces_big5 +BIGFIVE, ei_ces_big5 +CN-BIG5, ei_ces_big5 +CSBIG5, ei_ces_big5 +CP950, ei_cp950 +BIG5-HKSCS:1999, ei_big5hkscs1999 +BIG5-HKSCS:2001, ei_big5hkscs2001 +BIG5-HKSCS:2004, ei_big5hkscs2004 +BIG5-HKSCS, ei_big5hkscs2008 +BIG5HKSCS, ei_big5hkscs2008 +BIG5-HKSCS:2008, ei_big5hkscs2008 +EUC-KR, ei_euc_kr +EUCKR, ei_euc_kr +CSEUCKR, ei_euc_kr +CP949, ei_cp949 +UHC, ei_cp949 +JOHAB, ei_johab +CP1361, ei_johab +ISO-2022-KR, ei_iso2022_kr +CSISO2022KR, ei_iso2022_kr +CHAR, ei_local_char +WCHAR_T, ei_local_wchar_t diff --git a/libs/libiconv/lib/aliases.h b/libs/libiconv/lib/aliases.h new file mode 100644 index 00000000..b68ea2d1 --- /dev/null +++ b/libs/libiconv/lib/aliases.h @@ -0,0 +1,1719 @@ +/* ANSI-C code produced by gperf version 3.0.4 */ +/* Command-line: gperf -m 10 lib/aliases.gperf */ +/* Computed positions: -k'1,3-11,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "lib/aliases.gperf" +struct alias { int name; unsigned int encoding_index; }; + +#define TOTAL_KEYWORDS 347 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 45 +#define MIN_HASH_VALUE 7 +#define MAX_HASH_VALUE 935 +/* maximum key range = 929, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +aliases_hash (register const char *str, register unsigned int len) +{ + static const unsigned short asso_values[] = + { + 936, 936, 936, 936, 936, 936, 936, 936, 936, 936, + 936, 936, 936, 936, 936, 936, 936, 936, 936, 936, + 936, 936, 936, 936, 936, 936, 936, 936, 936, 936, + 936, 936, 936, 936, 936, 936, 936, 936, 936, 936, + 936, 936, 936, 936, 936, 16, 62, 936, 73, 0, + 5, 2, 47, 4, 1, 168, 8, 12, 357, 936, + 936, 936, 936, 936, 936, 112, 123, 3, 14, 34, + 71, 142, 147, 0, 258, 79, 39, 122, 4, 0, + 109, 936, 76, 1, 54, 147, 114, 180, 102, 3, + 10, 936, 936, 936, 936, 34, 936, 936, 936, 936, + 936, 936, 936, 936, 936, 936, 936, 936, 936, 936, + 936, 936, 936, 936, 936, 936, 936, 936, 936, 936, + 936, 936, 936, 936, 936, 936, 936, 936 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[10]]; + /*FALLTHROUGH*/ + case 10: + hval += asso_values[(unsigned char)str[9]]; + /*FALLTHROUGH*/ + case 9: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +struct stringpool_t + { + char stringpool_str7[sizeof("SJIS")]; + char stringpool_str9[sizeof("CN")]; + char stringpool_str11[sizeof("CP1131")]; + char stringpool_str12[sizeof("CP1361")]; + char stringpool_str13[sizeof("866")]; + char stringpool_str15[sizeof("CP1133")]; + char stringpool_str18[sizeof("CP1251")]; + char stringpool_str19[sizeof("CP866")]; + char stringpool_str20[sizeof("CP1256")]; + char stringpool_str21[sizeof("862")]; + char stringpool_str22[sizeof("CP1253")]; + char stringpool_str24[sizeof("CP936")]; + char stringpool_str26[sizeof("CP1255")]; + char stringpool_str27[sizeof("CP862")]; + char stringpool_str28[sizeof("CP1252")]; + char stringpool_str30[sizeof("C99")]; + char stringpool_str32[sizeof("CP932")]; + char stringpool_str34[sizeof("CP1258")]; + char stringpool_str40[sizeof("CP819")]; + char stringpool_str41[sizeof("L1")]; + char stringpool_str42[sizeof("L6")]; + char stringpool_str43[sizeof("L3")]; + char stringpool_str45[sizeof("L5")]; + char stringpool_str46[sizeof("L2")]; + char stringpool_str49[sizeof("L8")]; + char stringpool_str53[sizeof("EUCCN")]; + char stringpool_str57[sizeof("ISO8859-1")]; + char stringpool_str58[sizeof("ISO8859-11")]; + char stringpool_str59[sizeof("ISO8859-6")]; + char stringpool_str60[sizeof("ISO8859-16")]; + char stringpool_str61[sizeof("ISO8859-3")]; + char stringpool_str62[sizeof("ISO8859-13")]; + char stringpool_str65[sizeof("ISO8859-5")]; + char stringpool_str66[sizeof("ISO8859-15")]; + char stringpool_str67[sizeof("ISO8859-2")]; + char stringpool_str70[sizeof("EUC-CN")]; + char stringpool_str73[sizeof("ISO8859-8")]; + char stringpool_str74[sizeof("ISO-8859-1")]; + char stringpool_str75[sizeof("ISO-8859-11")]; + char stringpool_str76[sizeof("ISO-8859-6")]; + char stringpool_str77[sizeof("ISO-8859-16")]; + char stringpool_str78[sizeof("ISO-8859-3")]; + char stringpool_str79[sizeof("ISO-8859-13")]; + char stringpool_str81[sizeof("ISO8859-9")]; + char stringpool_str82[sizeof("ISO-8859-5")]; + char stringpool_str83[sizeof("ISO-8859-15")]; + char stringpool_str84[sizeof("ISO-8859-2")]; + char stringpool_str85[sizeof("ISO646-CN")]; + char stringpool_str86[sizeof("R8")]; + char stringpool_str88[sizeof("L4")]; + char stringpool_str90[sizeof("ISO-8859-8")]; + char stringpool_str91[sizeof("CP949")]; + char stringpool_str92[sizeof("ISO_8859-1")]; + char stringpool_str93[sizeof("ISO_8859-11")]; + char stringpool_str94[sizeof("ISO_8859-6")]; + char stringpool_str95[sizeof("ISO_8859-16")]; + char stringpool_str96[sizeof("ISO_8859-3")]; + char stringpool_str97[sizeof("ISO_8859-13")]; + char stringpool_str98[sizeof("ISO-8859-9")]; + char stringpool_str99[sizeof("ISO_8859-16:2001")]; + char stringpool_str100[sizeof("ISO_8859-5")]; + char stringpool_str101[sizeof("ISO_8859-15")]; + char stringpool_str102[sizeof("ISO_8859-2")]; + char stringpool_str103[sizeof("LATIN1")]; + char stringpool_str105[sizeof("LATIN6")]; + char stringpool_str106[sizeof("CP154")]; + char stringpool_str107[sizeof("LATIN3")]; + char stringpool_str108[sizeof("ISO_8859-8")]; + char stringpool_str110[sizeof("ISO_8859-15:1998")]; + char stringpool_str111[sizeof("LATIN5")]; + char stringpool_str112[sizeof("CP1254")]; + char stringpool_str113[sizeof("LATIN2")]; + char stringpool_str114[sizeof("CSISO2022CN")]; + char stringpool_str116[sizeof("ISO_8859-9")]; + char stringpool_str117[sizeof("CHINESE")]; + char stringpool_str118[sizeof("ISO-IR-6")]; + char stringpool_str119[sizeof("LATIN8")]; + char stringpool_str120[sizeof("ASCII")]; + char stringpool_str121[sizeof("ISO-IR-166")]; + char stringpool_str122[sizeof("X0212")]; + char stringpool_str124[sizeof("VISCII")]; + char stringpool_str125[sizeof("ISO-IR-126")]; + char stringpool_str126[sizeof("CSASCII")]; + char stringpool_str127[sizeof("ISO-IR-165")]; + char stringpool_str129[sizeof("CSVISCII")]; + char stringpool_str130[sizeof("ISO-IR-226")]; + char stringpool_str131[sizeof("MAC")]; + char stringpool_str136[sizeof("ISO-IR-138")]; + char stringpool_str137[sizeof("ISO-IR-58")]; + char stringpool_str139[sizeof("IBM866")]; + char stringpool_str142[sizeof("ISO-2022-CN")]; + char stringpool_str143[sizeof("MS936")]; + char stringpool_str144[sizeof("LATIN-9")]; + char stringpool_str146[sizeof("ISO-IR-159")]; + char stringpool_str147[sizeof("IBM862")]; + char stringpool_str150[sizeof("US")]; + char stringpool_str151[sizeof("ISO8859-4")]; + char stringpool_str152[sizeof("ISO8859-14")]; + char stringpool_str153[sizeof("ISO_8859-14:1998")]; + char stringpool_str154[sizeof("ISO-IR-199")]; + char stringpool_str156[sizeof("UHC")]; + char stringpool_str157[sizeof("850")]; + char stringpool_str159[sizeof("HZ")]; + char stringpool_str160[sizeof("IBM819")]; + char stringpool_str162[sizeof("ISO-CELTIC")]; + char stringpool_str163[sizeof("ELOT_928")]; + char stringpool_str164[sizeof("CP1250")]; + char stringpool_str165[sizeof("GB2312")]; + char stringpool_str166[sizeof("CP850")]; + char stringpool_str168[sizeof("ISO-8859-4")]; + char stringpool_str169[sizeof("ISO-8859-14")]; + char stringpool_str170[sizeof("CP950")]; + char stringpool_str171[sizeof("CYRILLIC")]; + char stringpool_str176[sizeof("ISO_8859-10:1992")]; + char stringpool_str179[sizeof("UCS-2")]; + char stringpool_str180[sizeof("TCVN")]; + char stringpool_str181[sizeof("ISO-IR-148")]; + char stringpool_str185[sizeof("X0201")]; + char stringpool_str186[sizeof("ISO_8859-4")]; + char stringpool_str187[sizeof("ISO_8859-14")]; + char stringpool_str188[sizeof("L10")]; + char stringpool_str189[sizeof("ISO-IR-149")]; + char stringpool_str191[sizeof("ISO-IR-101")]; + char stringpool_str196[sizeof("ISO-2022-CN-EXT")]; + char stringpool_str197[sizeof("LATIN4")]; + char stringpool_str200[sizeof("ISO-IR-203")]; + char stringpool_str201[sizeof("X0208")]; + char stringpool_str202[sizeof("KSC_5601")]; + char stringpool_str204[sizeof("ISO8859-10")]; + char stringpool_str207[sizeof("VISCII1.1-1")]; + char stringpool_str209[sizeof("L7")]; + char stringpool_str211[sizeof("ISO-IR-14")]; + char stringpool_str212[sizeof("PT154")]; + char stringpool_str213[sizeof("TIS620")]; + char stringpool_str215[sizeof("ISO-IR-109")]; + char stringpool_str216[sizeof("CSUNICODE11")]; + char stringpool_str217[sizeof("KOI8-T")]; + char stringpool_str218[sizeof("RK1048")]; + char stringpool_str221[sizeof("ISO-8859-10")]; + char stringpool_str222[sizeof("TIS620.2533-1")]; + char stringpool_str223[sizeof("ISO646-US")]; + char stringpool_str224[sizeof("CSISOLATIN1")]; + char stringpool_str226[sizeof("CSISOLATIN6")]; + char stringpool_str228[sizeof("CSISOLATIN3")]; + char stringpool_str230[sizeof("TIS-620")]; + char stringpool_str232[sizeof("CSISOLATIN5")]; + char stringpool_str234[sizeof("CSISOLATIN2")]; + char stringpool_str235[sizeof("TIS620.2529-1")]; + char stringpool_str236[sizeof("CSKZ1048")]; + char stringpool_str237[sizeof("CSISOLATINCYRILLIC")]; + char stringpool_str238[sizeof("KZ-1048")]; + char stringpool_str239[sizeof("ISO_8859-10")]; + char stringpool_str241[sizeof("UNICODE-1-1")]; + char stringpool_str242[sizeof("UTF-16")]; + char stringpool_str245[sizeof("MS-EE")]; + char stringpool_str248[sizeof("CSUNICODE")]; + char stringpool_str249[sizeof("CSKOI8R")]; + char stringpool_str250[sizeof("LATIN10")]; + char stringpool_str252[sizeof("UTF-32")]; + char stringpool_str254[sizeof("CSUCS4")]; + char stringpool_str255[sizeof("UTF-8")]; + char stringpool_str259[sizeof("ISO-IR-144")]; + char stringpool_str261[sizeof("KOI8-R")]; + char stringpool_str262[sizeof("MS-ANSI")]; + char stringpool_str263[sizeof("UCS-4")]; + char stringpool_str264[sizeof("ISO-IR-110")]; + char stringpool_str266[sizeof("IBM-CP1133")]; + char stringpool_str267[sizeof("CSIBM866")]; + char stringpool_str270[sizeof("KS_C_5601-1989")]; + char stringpool_str271[sizeof("CHAR")]; + char stringpool_str273[sizeof("EUCKR")]; + char stringpool_str277[sizeof("BIG5")]; + char stringpool_str278[sizeof("CP874")]; + char stringpool_str279[sizeof("ARMSCII-8")]; + char stringpool_str282[sizeof("CSBIG5")]; + char stringpool_str283[sizeof("UCS-2LE")]; + char stringpool_str286[sizeof("IBM850")]; + char stringpool_str287[sizeof("US-ASCII")]; + char stringpool_str290[sizeof("EUC-KR")]; + char stringpool_str293[sizeof("CSGB2312")]; + char stringpool_str294[sizeof("BIG-5")]; + char stringpool_str295[sizeof("TIS620.2533-0")]; + char stringpool_str299[sizeof("CN-BIG5")]; + char stringpool_str302[sizeof("MACCYRILLIC")]; + char stringpool_str303[sizeof("GBK")]; + char stringpool_str304[sizeof("TIS620-0")]; + char stringpool_str305[sizeof("MS-CYRL")]; + char stringpool_str307[sizeof("CYRILLIC-ASIAN")]; + char stringpool_str308[sizeof("ECMA-118")]; + char stringpool_str310[sizeof("ISO-IR-179")]; + char stringpool_str311[sizeof("GREEK8")]; + char stringpool_str315[sizeof("KOREAN")]; + char stringpool_str318[sizeof("CSISOLATIN4")]; + char stringpool_str321[sizeof("ISO-10646-UCS-2")]; + char stringpool_str325[sizeof("UCS-4LE")]; + char stringpool_str326[sizeof("PTCP154")]; + char stringpool_str330[sizeof("CSISO14JISC6220RO")]; + char stringpool_str334[sizeof("CSISO2022KR")]; + char stringpool_str336[sizeof("ROMAN8")]; + char stringpool_str337[sizeof("ISO-IR-100")]; + char stringpool_str340[sizeof("JIS_C6226-1983")]; + char stringpool_str344[sizeof("CSISOLATINARABIC")]; + char stringpool_str347[sizeof("CP367")]; + char stringpool_str350[sizeof("UTF-16LE")]; + char stringpool_str351[sizeof("ISO_646.IRV:1991")]; + char stringpool_str354[sizeof("CP1257")]; + char stringpool_str355[sizeof("MACICELAND")]; + char stringpool_str356[sizeof("UTF-32LE")]; + char stringpool_str357[sizeof("CSKSC56011987")]; + char stringpool_str359[sizeof("ARABIC")]; + char stringpool_str362[sizeof("ISO-2022-KR")]; + char stringpool_str363[sizeof("ISO-10646-UCS-4")]; + char stringpool_str367[sizeof("UCS-2BE")]; + char stringpool_str368[sizeof("GB_2312-80")]; + char stringpool_str369[sizeof("JP")]; + char stringpool_str371[sizeof("MULELAO-1")]; + char stringpool_str372[sizeof("CSISO159JISX02121990")]; + char stringpool_str373[sizeof("GREEK")]; + char stringpool_str375[sizeof("TCVN5712-1")]; + char stringpool_str376[sizeof("CSISO58GB231280")]; + char stringpool_str378[sizeof("GB18030")]; + char stringpool_str379[sizeof("TCVN-5712")]; + char stringpool_str384[sizeof("GB_1988-80")]; + char stringpool_str385[sizeof("CSPTCP154")]; + char stringpool_str386[sizeof("ECMA-114")]; + char stringpool_str388[sizeof("CSUNICODE11UTF7")]; + char stringpool_str391[sizeof("ANSI_X3.4-1986")]; + char stringpool_str392[sizeof("UNICODELITTLE")]; + char stringpool_str393[sizeof("ISO8859-7")]; + char stringpool_str395[sizeof("CN-GB-ISOIR165")]; + char stringpool_str396[sizeof("STRK1048-2002")]; + char stringpool_str398[sizeof("ANSI_X3.4-1968")]; + char stringpool_str403[sizeof("KOI8-U")]; + char stringpool_str406[sizeof("UCS-2-INTERNAL")]; + char stringpool_str409[sizeof("UCS-4BE")]; + char stringpool_str410[sizeof("ISO-8859-7")]; + char stringpool_str411[sizeof("SHIFT-JIS")]; + char stringpool_str412[sizeof("CN-GB")]; + char stringpool_str413[sizeof("JIS_C6220-1969-RO")]; + char stringpool_str415[sizeof("UNICODE-1-1-UTF-7")]; + char stringpool_str416[sizeof("WINDOWS-1251")]; + char stringpool_str417[sizeof("WINDOWS-1256")]; + char stringpool_str418[sizeof("WINDOWS-1253")]; + char stringpool_str420[sizeof("WINDOWS-1255")]; + char stringpool_str421[sizeof("WINDOWS-1252")]; + char stringpool_str422[sizeof("WINDOWS-936")]; + char stringpool_str424[sizeof("WINDOWS-1258")]; + char stringpool_str425[sizeof("CSEUCKR")]; + char stringpool_str426[sizeof("KS_C_5601-1987")]; + char stringpool_str428[sizeof("ISO_8859-7")]; + char stringpool_str429[sizeof("SHIFT_JIS")]; + char stringpool_str433[sizeof("JIS0208")]; + char stringpool_str434[sizeof("UTF-16BE")]; + char stringpool_str439[sizeof("LATIN7")]; + char stringpool_str440[sizeof("UTF-32BE")]; + char stringpool_str445[sizeof("MACTHAI")]; + char stringpool_str448[sizeof("UCS-4-INTERNAL")]; + char stringpool_str449[sizeof("CSISOLATINGREEK")]; + char stringpool_str451[sizeof("MACROMAN")]; + char stringpool_str452[sizeof("EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE")]; + char stringpool_str456[sizeof("EUCTW")]; + char stringpool_str457[sizeof("ISO-IR-57")]; + char stringpool_str458[sizeof("ISO-IR-157")]; + char stringpool_str459[sizeof("ISO-IR-127")]; + char stringpool_str461[sizeof("ISO-IR-87")]; + char stringpool_str463[sizeof("WINDOWS-1254")]; + char stringpool_str464[sizeof("ISO_8859-3:1988")]; + char stringpool_str466[sizeof("ISO_8859-5:1988")]; + char stringpool_str467[sizeof("IBM367")]; + char stringpool_str470[sizeof("ISO_8859-8:1988")]; + char stringpool_str471[sizeof("HZ-GB-2312")]; + char stringpool_str473[sizeof("EUC-TW")]; + char stringpool_str474[sizeof("CSISO57GB1988")]; + char stringpool_str475[sizeof("NEXTSTEP")]; + char stringpool_str476[sizeof("CSISO2022JP2")]; + char stringpool_str478[sizeof("ISO_8859-9:1989")]; + char stringpool_str480[sizeof("KOI8-RU")]; + char stringpool_str487[sizeof("MACINTOSH")]; + char stringpool_str489[sizeof("WINDOWS-1250")]; + char stringpool_str492[sizeof("JIS_X0212")]; + char stringpool_str500[sizeof("ISO-2022-JP-1")]; + char stringpool_str501[sizeof("MACCROATIAN")]; + char stringpool_str502[sizeof("HP-ROMAN8")]; + char stringpool_str505[sizeof("ISO-2022-JP-2")]; + char stringpool_str509[sizeof("ISO_8859-4:1988")]; + char stringpool_str510[sizeof("BIG5HKSCS")]; + char stringpool_str515[sizeof("ASMO-708")]; + char stringpool_str518[sizeof("EUCJP")]; + char stringpool_str525[sizeof("BIGFIVE")]; + char stringpool_str527[sizeof("BIG5-HKSCS")]; + char stringpool_str531[sizeof("MACCENTRALEUROPE")]; + char stringpool_str532[sizeof("CSPC862LATINHEBREW")]; + char stringpool_str535[sizeof("EUC-JP")]; + char stringpool_str542[sizeof("BIG-FIVE")]; + char stringpool_str546[sizeof("CSSHIFTJIS")]; + char stringpool_str550[sizeof("ISO646-JP")]; + char stringpool_str554[sizeof("JISX0201-1976")]; + char stringpool_str555[sizeof("JIS_X0201")]; + char stringpool_str556[sizeof("CSISOLATINHEBREW")]; + char stringpool_str563[sizeof("MACARABIC")]; + char stringpool_str564[sizeof("CSISO87JISX0208")]; + char stringpool_str571[sizeof("JIS_X0208")]; + char stringpool_str575[sizeof("UTF-7")]; + char stringpool_str577[sizeof("MACGREEK")]; + char stringpool_str579[sizeof("CSISO2022JP")]; + char stringpool_str580[sizeof("MS-TURK")]; + char stringpool_str581[sizeof("JIS_X0212-1990")]; + char stringpool_str584[sizeof("WINDOWS-1257")]; + char stringpool_str586[sizeof("JIS_X0208-1983")]; + char stringpool_str590[sizeof("MS-GREEK")]; + char stringpool_str599[sizeof("CSHPROMAN8")]; + char stringpool_str600[sizeof("JAVA")]; + char stringpool_str601[sizeof("MS-HEBR")]; + char stringpool_str604[sizeof("CSMACINTOSH")]; + char stringpool_str607[sizeof("ISO-2022-JP")]; + char stringpool_str608[sizeof("CSEUCTW")]; + char stringpool_str614[sizeof("GEORGIAN-PS")]; + char stringpool_str615[sizeof("UNICODEBIG")]; + char stringpool_str617[sizeof("MS_KANJI")]; + char stringpool_str620[sizeof("CSPC850MULTILINGUAL")]; + char stringpool_str621[sizeof("MACUKRAINE")]; + char stringpool_str622[sizeof("ISO_8859-1:1987")]; + char stringpool_str623[sizeof("ISO_8859-6:1987")]; + char stringpool_str624[sizeof("ISO_8859-7:2003")]; + char stringpool_str626[sizeof("GEORGIAN-ACADEMY")]; + char stringpool_str627[sizeof("ISO_8859-2:1987")]; + char stringpool_str629[sizeof("JIS_X0212.1990-0")]; + char stringpool_str657[sizeof("JIS_X0208-1990")]; + char stringpool_str664[sizeof("WCHAR_T")]; + char stringpool_str673[sizeof("MACROMANIA")]; + char stringpool_str676[sizeof("WINDOWS-874")]; + char stringpool_str689[sizeof("CSEUCPKDFMTJAPANESE")]; + char stringpool_str691[sizeof("MS-ARAB")]; + char stringpool_str723[sizeof("UCS-2-SWAPPED")]; + char stringpool_str739[sizeof("TCVN5712-1:1993")]; + char stringpool_str746[sizeof("HEBREW")]; + char stringpool_str765[sizeof("UCS-4-SWAPPED")]; + char stringpool_str768[sizeof("JOHAB")]; + char stringpool_str786[sizeof("MACTURKISH")]; + char stringpool_str790[sizeof("ISO_8859-7:1987")]; + char stringpool_str842[sizeof("WINBALTRIM")]; + char stringpool_str888[sizeof("BIG5-HKSCS:2001")]; + char stringpool_str896[sizeof("BIG5-HKSCS:2008")]; + char stringpool_str898[sizeof("CSHALFWIDTHKATAKANA")]; + char stringpool_str900[sizeof("BIG5-HKSCS:1999")]; + char stringpool_str908[sizeof("MACHEBREW")]; + char stringpool_str935[sizeof("BIG5-HKSCS:2004")]; + }; +static const struct stringpool_t stringpool_contents = + { + "SJIS", + "CN", + "CP1131", + "CP1361", + "866", + "CP1133", + "CP1251", + "CP866", + "CP1256", + "862", + "CP1253", + "CP936", + "CP1255", + "CP862", + "CP1252", + "C99", + "CP932", + "CP1258", + "CP819", + "L1", + "L6", + "L3", + "L5", + "L2", + "L8", + "EUCCN", + "ISO8859-1", + "ISO8859-11", + "ISO8859-6", + "ISO8859-16", + "ISO8859-3", + "ISO8859-13", + "ISO8859-5", + "ISO8859-15", + "ISO8859-2", + "EUC-CN", + "ISO8859-8", + "ISO-8859-1", + "ISO-8859-11", + "ISO-8859-6", + "ISO-8859-16", + "ISO-8859-3", + "ISO-8859-13", + "ISO8859-9", + "ISO-8859-5", + "ISO-8859-15", + "ISO-8859-2", + "ISO646-CN", + "R8", + "L4", + "ISO-8859-8", + "CP949", + "ISO_8859-1", + "ISO_8859-11", + "ISO_8859-6", + "ISO_8859-16", + "ISO_8859-3", + "ISO_8859-13", + "ISO-8859-9", + "ISO_8859-16:2001", + "ISO_8859-5", + "ISO_8859-15", + "ISO_8859-2", + "LATIN1", + "LATIN6", + "CP154", + "LATIN3", + "ISO_8859-8", + "ISO_8859-15:1998", + "LATIN5", + "CP1254", + "LATIN2", + "CSISO2022CN", + "ISO_8859-9", + "CHINESE", + "ISO-IR-6", + "LATIN8", + "ASCII", + "ISO-IR-166", + "X0212", + "VISCII", + "ISO-IR-126", + "CSASCII", + "ISO-IR-165", + "CSVISCII", + "ISO-IR-226", + "MAC", + "ISO-IR-138", + "ISO-IR-58", + "IBM866", + "ISO-2022-CN", + "MS936", + "LATIN-9", + "ISO-IR-159", + "IBM862", + "US", + "ISO8859-4", + "ISO8859-14", + "ISO_8859-14:1998", + "ISO-IR-199", + "UHC", + "850", + "HZ", + "IBM819", + "ISO-CELTIC", + "ELOT_928", + "CP1250", + "GB2312", + "CP850", + "ISO-8859-4", + "ISO-8859-14", + "CP950", + "CYRILLIC", + "ISO_8859-10:1992", + "UCS-2", + "TCVN", + "ISO-IR-148", + "X0201", + "ISO_8859-4", + "ISO_8859-14", + "L10", + "ISO-IR-149", + "ISO-IR-101", + "ISO-2022-CN-EXT", + "LATIN4", + "ISO-IR-203", + "X0208", + "KSC_5601", + "ISO8859-10", + "VISCII1.1-1", + "L7", + "ISO-IR-14", + "PT154", + "TIS620", + "ISO-IR-109", + "CSUNICODE11", + "KOI8-T", + "RK1048", + "ISO-8859-10", + "TIS620.2533-1", + "ISO646-US", + "CSISOLATIN1", + "CSISOLATIN6", + "CSISOLATIN3", + "TIS-620", + "CSISOLATIN5", + "CSISOLATIN2", + "TIS620.2529-1", + "CSKZ1048", + "CSISOLATINCYRILLIC", + "KZ-1048", + "ISO_8859-10", + "UNICODE-1-1", + "UTF-16", + "MS-EE", + "CSUNICODE", + "CSKOI8R", + "LATIN10", + "UTF-32", + "CSUCS4", + "UTF-8", + "ISO-IR-144", + "KOI8-R", + "MS-ANSI", + "UCS-4", + "ISO-IR-110", + "IBM-CP1133", + "CSIBM866", + "KS_C_5601-1989", + "CHAR", + "EUCKR", + "BIG5", + "CP874", + "ARMSCII-8", + "CSBIG5", + "UCS-2LE", + "IBM850", + "US-ASCII", + "EUC-KR", + "CSGB2312", + "BIG-5", + "TIS620.2533-0", + "CN-BIG5", + "MACCYRILLIC", + "GBK", + "TIS620-0", + "MS-CYRL", + "CYRILLIC-ASIAN", + "ECMA-118", + "ISO-IR-179", + "GREEK8", + "KOREAN", + "CSISOLATIN4", + "ISO-10646-UCS-2", + "UCS-4LE", + "PTCP154", + "CSISO14JISC6220RO", + "CSISO2022KR", + "ROMAN8", + "ISO-IR-100", + "JIS_C6226-1983", + "CSISOLATINARABIC", + "CP367", + "UTF-16LE", + "ISO_646.IRV:1991", + "CP1257", + "MACICELAND", + "UTF-32LE", + "CSKSC56011987", + "ARABIC", + "ISO-2022-KR", + "ISO-10646-UCS-4", + "UCS-2BE", + "GB_2312-80", + "JP", + "MULELAO-1", + "CSISO159JISX02121990", + "GREEK", + "TCVN5712-1", + "CSISO58GB231280", + "GB18030", + "TCVN-5712", + "GB_1988-80", + "CSPTCP154", + "ECMA-114", + "CSUNICODE11UTF7", + "ANSI_X3.4-1986", + "UNICODELITTLE", + "ISO8859-7", + "CN-GB-ISOIR165", + "STRK1048-2002", + "ANSI_X3.4-1968", + "KOI8-U", + "UCS-2-INTERNAL", + "UCS-4BE", + "ISO-8859-7", + "SHIFT-JIS", + "CN-GB", + "JIS_C6220-1969-RO", + "UNICODE-1-1-UTF-7", + "WINDOWS-1251", + "WINDOWS-1256", + "WINDOWS-1253", + "WINDOWS-1255", + "WINDOWS-1252", + "WINDOWS-936", + "WINDOWS-1258", + "CSEUCKR", + "KS_C_5601-1987", + "ISO_8859-7", + "SHIFT_JIS", + "JIS0208", + "UTF-16BE", + "LATIN7", + "UTF-32BE", + "MACTHAI", + "UCS-4-INTERNAL", + "CSISOLATINGREEK", + "MACROMAN", + "EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE", + "EUCTW", + "ISO-IR-57", + "ISO-IR-157", + "ISO-IR-127", + "ISO-IR-87", + "WINDOWS-1254", + "ISO_8859-3:1988", + "ISO_8859-5:1988", + "IBM367", + "ISO_8859-8:1988", + "HZ-GB-2312", + "EUC-TW", + "CSISO57GB1988", + "NEXTSTEP", + "CSISO2022JP2", + "ISO_8859-9:1989", + "KOI8-RU", + "MACINTOSH", + "WINDOWS-1250", + "JIS_X0212", + "ISO-2022-JP-1", + "MACCROATIAN", + "HP-ROMAN8", + "ISO-2022-JP-2", + "ISO_8859-4:1988", + "BIG5HKSCS", + "ASMO-708", + "EUCJP", + "BIGFIVE", + "BIG5-HKSCS", + "MACCENTRALEUROPE", + "CSPC862LATINHEBREW", + "EUC-JP", + "BIG-FIVE", + "CSSHIFTJIS", + "ISO646-JP", + "JISX0201-1976", + "JIS_X0201", + "CSISOLATINHEBREW", + "MACARABIC", + "CSISO87JISX0208", + "JIS_X0208", + "UTF-7", + "MACGREEK", + "CSISO2022JP", + "MS-TURK", + "JIS_X0212-1990", + "WINDOWS-1257", + "JIS_X0208-1983", + "MS-GREEK", + "CSHPROMAN8", + "JAVA", + "MS-HEBR", + "CSMACINTOSH", + "ISO-2022-JP", + "CSEUCTW", + "GEORGIAN-PS", + "UNICODEBIG", + "MS_KANJI", + "CSPC850MULTILINGUAL", + "MACUKRAINE", + "ISO_8859-1:1987", + "ISO_8859-6:1987", + "ISO_8859-7:2003", + "GEORGIAN-ACADEMY", + "ISO_8859-2:1987", + "JIS_X0212.1990-0", + "JIS_X0208-1990", + "WCHAR_T", + "MACROMANIA", + "WINDOWS-874", + "CSEUCPKDFMTJAPANESE", + "MS-ARAB", + "UCS-2-SWAPPED", + "TCVN5712-1:1993", + "HEBREW", + "UCS-4-SWAPPED", + "JOHAB", + "MACTURKISH", + "ISO_8859-7:1987", + "WINBALTRIM", + "BIG5-HKSCS:2001", + "BIG5-HKSCS:2008", + "CSHALFWIDTHKATAKANA", + "BIG5-HKSCS:1999", + "MACHEBREW", + "BIG5-HKSCS:2004" + }; +#define stringpool ((const char *) &stringpool_contents) + +static const struct alias aliases[] = + { + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 308 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str7, ei_sjis}, + {-1}, +#line 288 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str9, ei_iso646_cn}, + {-1}, +#line 209 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str11, ei_cp1131}, +#line 354 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str12, ei_johab}, +#line 207 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str13, ei_cp866}, + {-1}, +#line 244 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str15, ei_cp1133}, + {-1}, {-1}, +#line 174 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str18, ei_cp1251}, +#line 205 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str19, ei_cp866}, +#line 189 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str20, ei_cp1256}, +#line 203 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str21, ei_cp862}, +#line 180 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str22, ei_cp1253}, + {-1}, +#line 323 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str24, ei_cp936}, + {-1}, +#line 186 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str26, ei_cp1255}, +#line 201 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str27, ei_cp862}, +#line 177 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str28, ei_cp1252}, + {-1}, +#line 51 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str30, ei_c99}, + {-1}, +#line 311 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str32, ei_cp932}, + {-1}, +#line 195 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str34, ei_cp1258}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 57 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str40, ei_iso8859_1}, +#line 60 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str41, ei_iso8859_1}, +#line 134 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str42, ei_iso8859_10}, +#line 76 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str43, ei_iso8859_3}, + {-1}, +#line 126 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str45, ei_iso8859_9}, +#line 68 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str46, ei_iso8859_2}, + {-1}, {-1}, +#line 151 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str49, ei_iso8859_14}, + {-1}, {-1}, {-1}, +#line 318 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str53, ei_euc_cn}, + {-1}, {-1}, {-1}, +#line 62 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str57, ei_iso8859_1}, +#line 139 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str58, ei_iso8859_11}, +#line 102 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str59, ei_iso8859_6}, +#line 166 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str60, ei_iso8859_16}, +#line 78 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str61, ei_iso8859_3}, +#line 145 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str62, ei_iso8859_13}, + {-1}, {-1}, +#line 93 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str65, ei_iso8859_5}, +#line 159 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str66, ei_iso8859_15}, +#line 70 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str67, ei_iso8859_2}, + {-1}, {-1}, +#line 317 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str70, ei_euc_cn}, + {-1}, {-1}, +#line 120 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str73, ei_iso8859_8}, +#line 53 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str74, ei_iso8859_1}, +#line 137 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str75, ei_iso8859_11}, +#line 94 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str76, ei_iso8859_6}, +#line 160 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str77, ei_iso8859_16}, +#line 71 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str78, ei_iso8859_3}, +#line 140 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str79, ei_iso8859_13}, + {-1}, +#line 128 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str81, ei_iso8859_9}, +#line 87 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str82, ei_iso8859_5}, +#line 154 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str83, ei_iso8859_15}, +#line 63 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str84, ei_iso8859_2}, +#line 286 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str85, ei_iso646_cn}, +#line 227 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str86, ei_hp_roman8}, + {-1}, +#line 84 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str88, ei_iso8859_4}, + {-1}, +#line 114 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str90, ei_iso8859_8}, +#line 351 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str91, ei_cp949}, +#line 54 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str92, ei_iso8859_1}, +#line 138 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str93, ei_iso8859_11}, +#line 95 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str94, ei_iso8859_6}, +#line 161 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str95, ei_iso8859_16}, +#line 72 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str96, ei_iso8859_3}, +#line 141 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str97, ei_iso8859_13}, +#line 121 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str98, ei_iso8859_9}, +#line 162 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str99, ei_iso8859_16}, +#line 88 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str100, ei_iso8859_5}, +#line 155 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str101, ei_iso8859_15}, +#line 64 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str102, ei_iso8859_2}, +#line 59 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str103, ei_iso8859_1}, + {-1}, +#line 133 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str105, ei_iso8859_10}, +#line 236 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str106, ei_pt154}, +#line 75 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str107, ei_iso8859_3}, +#line 115 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str108, ei_iso8859_8}, + {-1}, +#line 156 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str110, ei_iso8859_15}, +#line 125 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str111, ei_iso8859_9}, +#line 183 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str112, ei_cp1254}, +#line 67 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str113, ei_iso8859_2}, +#line 328 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str114, ei_iso2022_cn}, + {-1}, +#line 122 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str116, ei_iso8859_9}, +#line 293 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str117, ei_gb2312}, +#line 16 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str118, ei_ascii}, +#line 150 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str119, ei_iso8859_14}, +#line 13 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str120, ei_ascii}, +#line 252 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str121, ei_tis620}, +#line 282 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str122, ei_jisx0212}, + {-1}, +#line 255 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str124, ei_viscii}, +#line 107 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str125, ei_iso8859_7}, +#line 22 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str126, ei_ascii}, +#line 294 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str127, ei_isoir165}, + {-1}, +#line 257 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str129, ei_viscii}, +#line 163 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str130, ei_iso8859_16}, +#line 212 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str131, ei_mac_roman}, + {-1}, {-1}, {-1}, {-1}, +#line 117 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str136, ei_iso8859_8}, +#line 291 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str137, ei_gb2312}, + {-1}, +#line 206 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str139, ei_cp866}, + {-1}, {-1}, +#line 327 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str142, ei_iso2022_cn}, +#line 324 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str143, ei_cp936}, +#line 158 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str144, ei_iso8859_15}, + {-1}, +#line 283 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str146, ei_jisx0212}, +#line 202 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str147, ei_cp862}, + {-1}, {-1}, +#line 21 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str150, ei_ascii}, +#line 86 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str151, ei_iso8859_4}, +#line 153 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str152, ei_iso8859_14}, +#line 148 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str153, ei_iso8859_14}, +#line 149 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str154, ei_iso8859_14}, + {-1}, +#line 352 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str156, ei_cp949}, +#line 199 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str157, ei_cp850}, + {-1}, +#line 330 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str159, ei_hz}, +#line 58 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str160, ei_iso8859_1}, + {-1}, +#line 152 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str162, ei_iso8859_14}, +#line 109 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str163, ei_iso8859_7}, +#line 171 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str164, ei_cp1250}, +#line 319 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str165, ei_euc_cn}, +#line 197 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str166, ei_cp850}, + {-1}, +#line 79 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str168, ei_iso8859_4}, +#line 146 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str169, ei_iso8859_14}, +#line 341 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str170, ei_cp950}, +#line 91 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str171, ei_iso8859_5}, + {-1}, {-1}, {-1}, {-1}, +#line 131 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str176, ei_iso8859_10}, + {-1}, {-1}, +#line 24 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str179, ei_ucs2}, +#line 258 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str180, ei_tcvn}, +#line 124 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str181, ei_iso8859_9}, + {-1}, {-1}, {-1}, +#line 269 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str185, ei_jisx0201}, +#line 80 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str186, ei_iso8859_4}, +#line 147 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str187, ei_iso8859_14}, +#line 165 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str188, ei_iso8859_16}, +#line 299 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str189, ei_ksc5601}, + {-1}, +#line 66 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str191, ei_iso8859_2}, + {-1}, {-1}, {-1}, {-1}, +#line 329 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str196, ei_iso2022_cn_ext}, +#line 83 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str197, ei_iso8859_4}, + {-1}, {-1}, +#line 157 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str200, ei_iso8859_15}, +#line 275 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str201, ei_jisx0208}, +#line 296 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str202, ei_ksc5601}, + {-1}, +#line 136 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str204, ei_iso8859_10}, + {-1}, {-1}, +#line 256 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str207, ei_viscii}, + {-1}, +#line 144 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str209, ei_iso8859_13}, + {-1}, +#line 264 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str211, ei_iso646_jp}, +#line 234 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str212, ei_pt154}, +#line 247 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str213, ei_tis620}, + {-1}, +#line 74 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str215, ei_iso8859_3}, +#line 30 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str216, ei_ucs2be}, +#line 233 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str217, ei_koi8_t}, +#line 239 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str218, ei_rk1048}, + {-1}, {-1}, +#line 129 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str221, ei_iso8859_10}, +#line 251 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str222, ei_tis620}, +#line 14 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str223, ei_ascii}, +#line 61 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str224, ei_iso8859_1}, + {-1}, +#line 135 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str226, ei_iso8859_10}, + {-1}, +#line 77 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str228, ei_iso8859_3}, + {-1}, +#line 246 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str230, ei_tis620}, + {-1}, +#line 127 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str232, ei_iso8859_9}, + {-1}, +#line 69 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str234, ei_iso8859_2}, +#line 249 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str235, ei_tis620}, +#line 242 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str236, ei_rk1048}, +#line 92 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str237, ei_iso8859_5}, +#line 241 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str238, ei_rk1048}, +#line 130 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str239, ei_iso8859_10}, + {-1}, +#line 29 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str241, ei_ucs2be}, +#line 38 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str242, ei_utf16}, + {-1}, {-1}, +#line 173 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str245, ei_cp1250}, + {-1}, {-1}, +#line 26 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str248, ei_ucs2}, +#line 168 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str249, ei_koi8_r}, +#line 164 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str250, ei_iso8859_16}, + {-1}, +#line 41 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str252, ei_utf32}, + {-1}, +#line 35 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str254, ei_ucs4}, +#line 23 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str255, ei_utf8}, + {-1}, {-1}, {-1}, +#line 90 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str259, ei_iso8859_5}, + {-1}, +#line 167 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str261, ei_koi8_r}, +#line 179 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str262, ei_cp1252}, +#line 33 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str263, ei_ucs4}, +#line 82 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str264, ei_iso8859_4}, + {-1}, +#line 245 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str266, ei_cp1133}, +#line 208 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str267, ei_cp866}, + {-1}, {-1}, +#line 298 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str270, ei_ksc5601}, +#line 357 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str271, ei_local_char}, + {-1}, +#line 349 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str273, ei_euc_kr}, + {-1}, {-1}, {-1}, +#line 335 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str277, ei_ces_big5}, +#line 253 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str278, ei_cp874}, +#line 230 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str279, ei_armscii_8}, + {-1}, {-1}, +#line 340 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str282, ei_ces_big5}, +#line 31 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str283, ei_ucs2le}, + {-1}, {-1}, +#line 198 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str286, ei_cp850}, +#line 12 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str287, ei_ascii}, + {-1}, {-1}, +#line 348 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str290, ei_euc_kr}, + {-1}, {-1}, +#line 321 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str293, ei_euc_cn}, +#line 336 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str294, ei_ces_big5}, +#line 250 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str295, ei_tis620}, + {-1}, {-1}, {-1}, +#line 339 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str299, ei_ces_big5}, + {-1}, {-1}, +#line 218 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str302, ei_mac_cyrillic}, +#line 322 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str303, ei_ces_gbk}, +#line 248 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str304, ei_tis620}, +#line 176 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str305, ei_cp1251}, + {-1}, +#line 237 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str307, ei_pt154}, +#line 108 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str308, ei_iso8859_7}, + {-1}, +#line 142 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str310, ei_iso8859_13}, +#line 110 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str311, ei_iso8859_7}, + {-1}, {-1}, {-1}, +#line 301 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str315, ei_ksc5601}, + {-1}, {-1}, +#line 85 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str318, ei_iso8859_4}, + {-1}, {-1}, +#line 25 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str321, ei_ucs2}, + {-1}, {-1}, {-1}, +#line 37 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str325, ei_ucs4le}, +#line 235 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str326, ei_pt154}, + {-1}, {-1}, {-1}, +#line 266 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str330, ei_iso646_jp}, + {-1}, {-1}, {-1}, +#line 356 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str334, ei_iso2022_kr}, + {-1}, +#line 226 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str336, ei_hp_roman8}, +#line 56 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str337, ei_iso8859_1}, + {-1}, {-1}, +#line 277 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str340, ei_jisx0208}, + {-1}, {-1}, {-1}, +#line 101 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str344, ei_iso8859_6}, + {-1}, {-1}, +#line 19 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str347, ei_ascii}, + {-1}, {-1}, +#line 40 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str350, ei_utf16le}, +#line 15 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str351, ei_ascii}, + {-1}, {-1}, +#line 192 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str354, ei_cp1257}, +#line 215 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str355, ei_mac_iceland}, +#line 43 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str356, ei_utf32le}, +#line 300 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str357, ei_ksc5601}, + {-1}, +#line 100 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str359, ei_iso8859_6}, + {-1}, {-1}, +#line 355 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str362, ei_iso2022_kr}, +#line 34 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str363, ei_ucs4}, + {-1}, {-1}, {-1}, +#line 27 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str367, ei_ucs2be}, +#line 290 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str368, ei_gb2312}, +#line 265 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str369, ei_iso646_jp}, + {-1}, +#line 243 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str371, ei_mulelao}, +#line 284 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str372, ei_jisx0212}, +#line 111 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str373, ei_iso8859_7}, + {-1}, +#line 260 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str375, ei_tcvn}, +#line 292 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str376, ei_gb2312}, + {-1}, +#line 326 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str378, ei_gb18030}, +#line 259 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str379, ei_tcvn}, + {-1}, {-1}, {-1}, {-1}, +#line 285 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str384, ei_iso646_cn}, +#line 238 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str385, ei_pt154}, +#line 98 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str386, ei_iso8859_6}, + {-1}, +#line 46 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str388, ei_utf7}, + {-1}, {-1}, +#line 18 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str391, ei_ascii}, +#line 32 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str392, ei_ucs2le}, +#line 113 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str393, ei_iso8859_7}, + {-1}, +#line 295 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str395, ei_isoir165}, +#line 240 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str396, ei_rk1048}, + {-1}, +#line 17 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str398, ei_ascii}, + {-1}, {-1}, {-1}, {-1}, +#line 169 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str403, ei_koi8_u}, + {-1}, {-1}, +#line 47 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str406, ei_ucs2internal}, + {-1}, {-1}, +#line 36 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str409, ei_ucs4be}, +#line 103 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str410, ei_iso8859_7}, +#line 307 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str411, ei_sjis}, +#line 320 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str412, ei_euc_cn}, +#line 262 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str413, ei_iso646_jp}, + {-1}, +#line 45 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str415, ei_utf7}, +#line 175 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str416, ei_cp1251}, +#line 190 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str417, ei_cp1256}, +#line 181 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str418, ei_cp1253}, + {-1}, +#line 187 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str420, ei_cp1255}, +#line 178 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str421, ei_cp1252}, +#line 325 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str422, ei_cp936}, + {-1}, +#line 196 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str424, ei_cp1258}, +#line 350 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str425, ei_euc_kr}, +#line 297 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str426, ei_ksc5601}, + {-1}, +#line 104 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str428, ei_iso8859_7}, +#line 306 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str429, ei_sjis}, + {-1}, {-1}, {-1}, +#line 274 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str433, ei_jisx0208}, +#line 39 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str434, ei_utf16be}, + {-1}, {-1}, {-1}, {-1}, +#line 143 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str439, ei_iso8859_13}, +#line 42 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str440, ei_utf32be}, + {-1}, {-1}, {-1}, {-1}, +#line 224 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str445, ei_mac_thai}, + {-1}, {-1}, +#line 49 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str448, ei_ucs4internal}, +#line 112 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str449, ei_iso8859_7}, + {-1}, +#line 210 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str451, ei_mac_roman}, +#line 304 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str452, ei_euc_jp}, + {-1}, {-1}, {-1}, +#line 333 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str456, ei_euc_tw}, +#line 287 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str457, ei_iso646_cn}, +#line 132 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str458, ei_iso8859_10}, +#line 97 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str459, ei_iso8859_6}, + {-1}, +#line 276 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str461, ei_jisx0208}, + {-1}, +#line 184 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str463, ei_cp1254}, +#line 73 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str464, ei_iso8859_3}, + {-1}, +#line 89 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str466, ei_iso8859_5}, +#line 20 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str467, ei_ascii}, + {-1}, {-1}, +#line 116 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str470, ei_iso8859_8}, +#line 331 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str471, ei_hz}, + {-1}, +#line 332 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str473, ei_euc_tw}, +#line 289 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str474, ei_iso646_cn}, +#line 229 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str475, ei_nextstep}, +#line 316 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str476, ei_iso2022_jp2}, + {-1}, +#line 123 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str478, ei_iso8859_9}, + {-1}, +#line 170 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str480, ei_koi8_ru}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 211 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str487, ei_mac_roman}, + {-1}, +#line 172 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str489, ei_cp1250}, + {-1}, {-1}, +#line 279 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str492, ei_jisx0212}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 314 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str500, ei_iso2022_jp1}, +#line 216 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str501, ei_mac_croatian}, +#line 225 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str502, ei_hp_roman8}, + {-1}, {-1}, +#line 315 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str505, ei_iso2022_jp2}, + {-1}, {-1}, {-1}, +#line 81 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str509, ei_iso8859_4}, +#line 346 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str510, ei_big5hkscs2008}, + {-1}, {-1}, {-1}, {-1}, +#line 99 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str515, ei_iso8859_6}, + {-1}, {-1}, +#line 303 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str518, ei_euc_jp}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 338 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str525, ei_ces_big5}, + {-1}, +#line 345 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str527, ei_big5hkscs2008}, + {-1}, {-1}, {-1}, +#line 214 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str531, ei_mac_centraleurope}, +#line 204 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str532, ei_cp862}, + {-1}, {-1}, +#line 302 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str535, ei_euc_jp}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 337 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str542, ei_ces_big5}, + {-1}, {-1}, {-1}, +#line 310 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str546, ei_sjis}, + {-1}, {-1}, {-1}, +#line 263 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str550, ei_iso646_jp}, + {-1}, {-1}, {-1}, +#line 268 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str554, ei_jisx0201}, +#line 267 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str555, ei_jisx0201}, +#line 119 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str556, ei_iso8859_8}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 223 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str563, ei_mac_arabic}, +#line 278 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str564, ei_jisx0208}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 271 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str571, ei_jisx0208}, + {-1}, {-1}, {-1}, +#line 44 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str575, ei_utf7}, + {-1}, +#line 220 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str577, ei_mac_greek}, + {-1}, +#line 313 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str579, ei_iso2022_jp}, +#line 185 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str580, ei_cp1254}, +#line 281 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str581, ei_jisx0212}, + {-1}, {-1}, +#line 193 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str584, ei_cp1257}, + {-1}, +#line 272 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str586, ei_jisx0208}, + {-1}, {-1}, {-1}, +#line 182 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str590, ei_cp1253}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 228 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str599, ei_hp_roman8}, +#line 52 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str600, ei_java}, +#line 188 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str601, ei_cp1255}, + {-1}, {-1}, +#line 213 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str604, ei_mac_roman}, + {-1}, {-1}, +#line 312 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str607, ei_iso2022_jp}, +#line 334 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str608, ei_euc_tw}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 232 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str614, ei_georgian_ps}, +#line 28 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str615, ei_ucs2be}, + {-1}, +#line 309 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str617, ei_sjis}, + {-1}, {-1}, +#line 200 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str620, ei_cp850}, +#line 219 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str621, ei_mac_ukraine}, +#line 55 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str622, ei_iso8859_1}, +#line 96 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str623, ei_iso8859_6}, +#line 106 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str624, ei_iso8859_7}, + {-1}, +#line 231 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str626, ei_georgian_academy}, +#line 65 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str627, ei_iso8859_2}, + {-1}, +#line 280 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str629, ei_jisx0212}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 273 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str657, ei_jisx0208}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 358 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str664, ei_local_wchar_t}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 217 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str673, ei_mac_romania}, + {-1}, {-1}, +#line 254 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str676, ei_cp874}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 305 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str689, ei_euc_jp}, + {-1}, +#line 191 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str691, ei_cp1256}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 48 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str723, ei_ucs2swapped}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 261 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str739, ei_tcvn}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 118 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str746, ei_iso8859_8}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 50 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str765, ei_ucs4swapped}, + {-1}, {-1}, +#line 353 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str768, ei_johab}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 221 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str786, ei_mac_turkish}, + {-1}, {-1}, {-1}, +#line 105 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str790, ei_iso8859_7}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 194 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str842, ei_cp1257}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 343 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str888, ei_big5hkscs2001}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 347 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str896, ei_big5hkscs2008}, + {-1}, +#line 270 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str898, ei_jisx0201}, + {-1}, +#line 342 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str900, ei_big5hkscs1999}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 222 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str908, ei_mac_hebrew}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 344 "lib/aliases.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str935, ei_big5hkscs2004} + }; + +#ifdef __GNUC__ +__inline +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct alias * +aliases_lookup (register const char *str, register unsigned int len) +{ + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = aliases_hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int o = aliases[key].name; + if (o >= 0) + { + register const char *s = o + stringpool; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &aliases[key]; + } + } + } + return 0; +} diff --git a/libs/libiconv/lib/aliases2.h b/libs/libiconv/lib/aliases2.h new file mode 100644 index 00000000..7f2dc449 --- /dev/null +++ b/libs/libiconv/lib/aliases2.h @@ -0,0 +1,40 @@ +/* + * Copyright (C) 1999-2003, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifdef USE_AIX +# if defined _AIX +# include "aliases_aix_sysaix.h" +# else +# include "aliases_aix.h" +# endif +#endif +#ifdef USE_OSF1 +# if defined __osf__ +# include "aliases_osf1_sysosf1.h" +# else +# include "aliases_osf1.h" +# endif +#endif +#ifdef USE_DOS +# include "aliases_dos.h" +#endif +#ifdef USE_EXTRA +# include "aliases_extra.h" +#endif diff --git a/libs/libiconv/lib/aliases_aix.h b/libs/libiconv/lib/aliases_aix.h new file mode 100644 index 00000000..5cbc77fd --- /dev/null +++ b/libs/libiconv/lib/aliases_aix.h @@ -0,0 +1,18 @@ + S(aix_0, "CP856", ei_cp856 ) + S(aix_1, "CP922", ei_cp922 ) + S(aix_2, "CP943", ei_cp943 ) + S(aix_3, "CP1046", ei_cp1046 ) + S(aix_4, "CP1124", ei_cp1124 ) + S(aix_5, "CP1129", ei_cp1129 ) + S(aix_6, "CP1161", ei_cp1161 ) + S(aix_7, "IBM1161", ei_cp1161 ) + S(aix_8, "IBM-1161", ei_cp1161 ) + S(aix_9, "CSIBM1161", ei_cp1161 ) + S(aix_10, "CP1162", ei_cp1162 ) + S(aix_11, "IBM1162", ei_cp1162 ) + S(aix_12, "IBM-1162", ei_cp1162 ) + S(aix_13, "CSIBM1162", ei_cp1162 ) + S(aix_14, "CP1163", ei_cp1163 ) + S(aix_15, "IBM1163", ei_cp1163 ) + S(aix_16, "IBM-1163", ei_cp1163 ) + S(aix_17, "CSIBM1163", ei_cp1163 ) diff --git a/libs/libiconv/lib/aliases_aix_sysaix.h b/libs/libiconv/lib/aliases_aix_sysaix.h new file mode 100644 index 00000000..b7dc5841 --- /dev/null +++ b/libs/libiconv/lib/aliases_aix_sysaix.h @@ -0,0 +1,24 @@ + S(aix_0, "CP856", ei_cp856 ) + S(aix_1, "IBM-856", ei_cp856 ) + S(aix_2, "CP922", ei_cp922 ) + S(aix_3, "IBM-922", ei_cp922 ) + S(aix_4, "CP943", ei_cp943 ) + S(aix_5, "IBM-943", ei_cp943 ) + S(aix_6, "CP1046", ei_cp1046 ) + S(aix_7, "IBM-1046", ei_cp1046 ) + S(aix_8, "CP1124", ei_cp1124 ) + S(aix_9, "IBM-1124", ei_cp1124 ) + S(aix_10, "CP1129", ei_cp1129 ) + S(aix_11, "IBM-1129", ei_cp1129 ) + S(aix_12, "CP1161", ei_cp1161 ) + S(aix_13, "IBM1161", ei_cp1161 ) + S(aix_14, "IBM-1161", ei_cp1161 ) + S(aix_15, "CSIBM1161", ei_cp1161 ) + S(aix_16, "CP1162", ei_cp1162 ) + S(aix_17, "IBM1162", ei_cp1162 ) + S(aix_18, "IBM-1162", ei_cp1162 ) + S(aix_19, "CSIBM1162", ei_cp1162 ) + S(aix_20, "CP1163", ei_cp1163 ) + S(aix_21, "IBM1163", ei_cp1163 ) + S(aix_22, "IBM-1163", ei_cp1163 ) + S(aix_23, "CSIBM1163", ei_cp1163 ) diff --git a/libs/libiconv/lib/aliases_dos.h b/libs/libiconv/lib/aliases_dos.h new file mode 100644 index 00000000..1dd4fcba --- /dev/null +++ b/libs/libiconv/lib/aliases_dos.h @@ -0,0 +1,48 @@ + S(dos_0, "CP437", ei_cp437 ) + S(dos_1, "IBM437", ei_cp437 ) + S(dos_2, "437", ei_cp437 ) + S(dos_3, "CSPC8CODEPAGE437", ei_cp437 ) + S(dos_4, "CP737", ei_cp737 ) + S(dos_5, "CP775", ei_cp775 ) + S(dos_6, "IBM775", ei_cp775 ) + S(dos_7, "CSPC775BALTIC", ei_cp775 ) + S(dos_8, "CP852", ei_cp852 ) + S(dos_9, "IBM852", ei_cp852 ) + S(dos_10, "852", ei_cp852 ) + S(dos_11, "CSPCP852", ei_cp852 ) + S(dos_12, "CP853", ei_cp853 ) + S(dos_13, "CP855", ei_cp855 ) + S(dos_14, "IBM855", ei_cp855 ) + S(dos_15, "855", ei_cp855 ) + S(dos_16, "CSIBM855", ei_cp855 ) + S(dos_17, "CP857", ei_cp857 ) + S(dos_18, "IBM857", ei_cp857 ) + S(dos_19, "857", ei_cp857 ) + S(dos_20, "CSIBM857", ei_cp857 ) + S(dos_21, "CP858", ei_cp858 ) + S(dos_22, "CP860", ei_cp860 ) + S(dos_23, "IBM860", ei_cp860 ) + S(dos_24, "860", ei_cp860 ) + S(dos_25, "CSIBM860", ei_cp860 ) + S(dos_26, "CP861", ei_cp861 ) + S(dos_27, "IBM861", ei_cp861 ) + S(dos_28, "861", ei_cp861 ) + S(dos_29, "CP-IS", ei_cp861 ) + S(dos_30, "CSIBM861", ei_cp861 ) + S(dos_31, "CP863", ei_cp863 ) + S(dos_32, "IBM863", ei_cp863 ) + S(dos_33, "863", ei_cp863 ) + S(dos_34, "CSIBM863", ei_cp863 ) + S(dos_35, "CP864", ei_cp864 ) + S(dos_36, "IBM864", ei_cp864 ) + S(dos_37, "CSIBM864", ei_cp864 ) + S(dos_38, "CP865", ei_cp865 ) + S(dos_39, "IBM865", ei_cp865 ) + S(dos_40, "865", ei_cp865 ) + S(dos_41, "CSIBM865", ei_cp865 ) + S(dos_42, "CP869", ei_cp869 ) + S(dos_43, "IBM869", ei_cp869 ) + S(dos_44, "869", ei_cp869 ) + S(dos_45, "CP-GR", ei_cp869 ) + S(dos_46, "CSIBM869", ei_cp869 ) + S(dos_47, "CP1125", ei_cp1125 ) diff --git a/libs/libiconv/lib/aliases_extra.h b/libs/libiconv/lib/aliases_extra.h new file mode 100644 index 00000000..9a54e16a --- /dev/null +++ b/libs/libiconv/lib/aliases_extra.h @@ -0,0 +1,12 @@ + S(extra_0, "EUC-JISX0213", ei_euc_jisx0213 ) + S(extra_1, "EUC-JIS-2004", ei_euc_jisx0213 ) + S(extra_2, "SHIFT_JISX0213", ei_shift_jisx0213 ) + S(extra_3, "SHIFT_JIS-2004", ei_shift_jisx0213 ) + S(extra_4, "ISO-2022-JP-3", ei_iso2022_jp3 ) + S(extra_5, "ISO-2022-JP-2004", ei_iso2022_jp3 ) + S(extra_6, "BIG5-2003", ei_big5_2003 ) + S(extra_7, "TDS565", ei_tds565 ) + S(extra_8, "ISO-IR-230", ei_tds565 ) + S(extra_9, "ATARIST", ei_atarist ) + S(extra_10, "ATARI", ei_atarist ) + S(extra_11, "RISCOS-LATIN1", ei_riscos1 ) diff --git a/libs/libiconv/lib/aliases_osf1.h b/libs/libiconv/lib/aliases_osf1.h new file mode 100644 index 00000000..9e4f6854 --- /dev/null +++ b/libs/libiconv/lib/aliases_osf1.h @@ -0,0 +1,2 @@ + S(osf1_0, "DEC-KANJI", ei_dec_kanji ) + S(osf1_1, "DEC-HANYU", ei_dec_hanyu ) diff --git a/libs/libiconv/lib/aliases_osf1_sysosf1.h b/libs/libiconv/lib/aliases_osf1_sysosf1.h new file mode 100644 index 00000000..b1f802d2 --- /dev/null +++ b/libs/libiconv/lib/aliases_osf1_sysosf1.h @@ -0,0 +1,4 @@ + S(osf1_0, "DEC-KANJI", ei_dec_kanji ) + S(osf1_1, "DECKANJI", ei_dec_kanji ) + S(osf1_2, "DEC-HANYU", ei_dec_hanyu ) + S(osf1_3, "DECHANYU", ei_dec_hanyu ) diff --git a/libs/libiconv/lib/aliases_sysaix.gperf b/libs/libiconv/lib/aliases_sysaix.gperf new file mode 100644 index 00000000..2e5bc194 --- /dev/null +++ b/libs/libiconv/lib/aliases_sysaix.gperf @@ -0,0 +1,367 @@ +struct alias { int name; unsigned int encoding_index; }; +%struct-type +%language=ANSI-C +%define hash-function-name aliases_hash +%define lookup-function-name aliases_lookup +%7bit +%readonly-tables +%global-table +%define word-array-name aliases +%pic +%% +US-ASCII, ei_ascii +ASCII, ei_ascii +ISO646-US, ei_ascii +ISO_646.IRV:1991, ei_ascii +ISO-IR-6, ei_ascii +ANSI_X3.4-1968, ei_ascii +ANSI_X3.4-1986, ei_ascii +CP367, ei_ascii +IBM367, ei_ascii +US, ei_ascii +CSASCII, ei_ascii +UTF-8, ei_utf8 +UCS-2, ei_ucs2 +ISO-10646-UCS-2, ei_ucs2 +CSUNICODE, ei_ucs2 +UCS-2BE, ei_ucs2be +UNICODEBIG, ei_ucs2be +UNICODE-1-1, ei_ucs2be +CSUNICODE11, ei_ucs2be +UCS-2LE, ei_ucs2le +UNICODELITTLE, ei_ucs2le +UCS-4, ei_ucs4 +ISO-10646-UCS-4, ei_ucs4 +CSUCS4, ei_ucs4 +UCS-4BE, ei_ucs4be +UCS-4LE, ei_ucs4le +UTF-16, ei_utf16 +UTF-16BE, ei_utf16be +UTF-16LE, ei_utf16le +UTF-32, ei_utf32 +UTF-32BE, ei_utf32be +UTF-32LE, ei_utf32le +UTF-7, ei_utf7 +UNICODE-1-1-UTF-7, ei_utf7 +CSUNICODE11UTF7, ei_utf7 +UCS-2-INTERNAL, ei_ucs2internal +UCS-2-SWAPPED, ei_ucs2swapped +UCS-4-INTERNAL, ei_ucs4internal +UCS-4-SWAPPED, ei_ucs4swapped +C99, ei_c99 +JAVA, ei_java +ISO-8859-1, ei_iso8859_1 +ISO_8859-1, ei_iso8859_1 +ISO_8859-1:1987, ei_iso8859_1 +ISO-IR-100, ei_iso8859_1 +CP819, ei_iso8859_1 +IBM819, ei_iso8859_1 +LATIN1, ei_iso8859_1 +L1, ei_iso8859_1 +CSISOLATIN1, ei_iso8859_1 +ISO8859-1, ei_iso8859_1 +ISO-8859-2, ei_iso8859_2 +ISO_8859-2, ei_iso8859_2 +ISO_8859-2:1987, ei_iso8859_2 +ISO-IR-101, ei_iso8859_2 +LATIN2, ei_iso8859_2 +L2, ei_iso8859_2 +CSISOLATIN2, ei_iso8859_2 +ISO8859-2, ei_iso8859_2 +ISO-8859-3, ei_iso8859_3 +ISO_8859-3, ei_iso8859_3 +ISO_8859-3:1988, ei_iso8859_3 +ISO-IR-109, ei_iso8859_3 +LATIN3, ei_iso8859_3 +L3, ei_iso8859_3 +CSISOLATIN3, ei_iso8859_3 +ISO8859-3, ei_iso8859_3 +ISO-8859-4, ei_iso8859_4 +ISO_8859-4, ei_iso8859_4 +ISO_8859-4:1988, ei_iso8859_4 +ISO-IR-110, ei_iso8859_4 +LATIN4, ei_iso8859_4 +L4, ei_iso8859_4 +CSISOLATIN4, ei_iso8859_4 +ISO8859-4, ei_iso8859_4 +ISO-8859-5, ei_iso8859_5 +ISO_8859-5, ei_iso8859_5 +ISO_8859-5:1988, ei_iso8859_5 +ISO-IR-144, ei_iso8859_5 +CYRILLIC, ei_iso8859_5 +CSISOLATINCYRILLIC, ei_iso8859_5 +ISO8859-5, ei_iso8859_5 +ISO-8859-6, ei_iso8859_6 +ISO_8859-6, ei_iso8859_6 +ISO_8859-6:1987, ei_iso8859_6 +ISO-IR-127, ei_iso8859_6 +ECMA-114, ei_iso8859_6 +ASMO-708, ei_iso8859_6 +ARABIC, ei_iso8859_6 +CSISOLATINARABIC, ei_iso8859_6 +ISO8859-6, ei_iso8859_6 +ISO-8859-7, ei_iso8859_7 +ISO_8859-7, ei_iso8859_7 +ISO_8859-7:1987, ei_iso8859_7 +ISO_8859-7:2003, ei_iso8859_7 +ISO-IR-126, ei_iso8859_7 +ECMA-118, ei_iso8859_7 +ELOT_928, ei_iso8859_7 +GREEK8, ei_iso8859_7 +GREEK, ei_iso8859_7 +CSISOLATINGREEK, ei_iso8859_7 +ISO8859-7, ei_iso8859_7 +ISO-8859-8, ei_iso8859_8 +ISO_8859-8, ei_iso8859_8 +ISO_8859-8:1988, ei_iso8859_8 +ISO-IR-138, ei_iso8859_8 +HEBREW, ei_iso8859_8 +CSISOLATINHEBREW, ei_iso8859_8 +ISO8859-8, ei_iso8859_8 +ISO-8859-9, ei_iso8859_9 +ISO_8859-9, ei_iso8859_9 +ISO_8859-9:1989, ei_iso8859_9 +ISO-IR-148, ei_iso8859_9 +LATIN5, ei_iso8859_9 +L5, ei_iso8859_9 +CSISOLATIN5, ei_iso8859_9 +ISO8859-9, ei_iso8859_9 +ISO-8859-10, ei_iso8859_10 +ISO_8859-10, ei_iso8859_10 +ISO_8859-10:1992, ei_iso8859_10 +ISO-IR-157, ei_iso8859_10 +LATIN6, ei_iso8859_10 +L6, ei_iso8859_10 +CSISOLATIN6, ei_iso8859_10 +ISO8859-10, ei_iso8859_10 +ISO-8859-11, ei_iso8859_11 +ISO_8859-11, ei_iso8859_11 +ISO8859-11, ei_iso8859_11 +ISO-8859-13, ei_iso8859_13 +ISO_8859-13, ei_iso8859_13 +ISO-IR-179, ei_iso8859_13 +LATIN7, ei_iso8859_13 +L7, ei_iso8859_13 +ISO8859-13, ei_iso8859_13 +IBM-921, ei_iso8859_13 +ISO-8859-14, ei_iso8859_14 +ISO_8859-14, ei_iso8859_14 +ISO_8859-14:1998, ei_iso8859_14 +ISO-IR-199, ei_iso8859_14 +LATIN8, ei_iso8859_14 +L8, ei_iso8859_14 +ISO-CELTIC, ei_iso8859_14 +ISO8859-14, ei_iso8859_14 +ISO-8859-15, ei_iso8859_15 +ISO_8859-15, ei_iso8859_15 +ISO_8859-15:1998, ei_iso8859_15 +ISO-IR-203, ei_iso8859_15 +LATIN-9, ei_iso8859_15 +ISO8859-15, ei_iso8859_15 +ISO-8859-16, ei_iso8859_16 +ISO_8859-16, ei_iso8859_16 +ISO_8859-16:2001, ei_iso8859_16 +ISO-IR-226, ei_iso8859_16 +LATIN10, ei_iso8859_16 +L10, ei_iso8859_16 +ISO8859-16, ei_iso8859_16 +KOI8-R, ei_koi8_r +CSKOI8R, ei_koi8_r +KOI8-U, ei_koi8_u +KOI8-RU, ei_koi8_ru +CP1250, ei_cp1250 +WINDOWS-1250, ei_cp1250 +MS-EE, ei_cp1250 +CP1251, ei_cp1251 +WINDOWS-1251, ei_cp1251 +MS-CYRL, ei_cp1251 +CP1252, ei_cp1252 +WINDOWS-1252, ei_cp1252 +MS-ANSI, ei_cp1252 +IBM-1252, ei_cp1252 +CP1253, ei_cp1253 +WINDOWS-1253, ei_cp1253 +MS-GREEK, ei_cp1253 +CP1254, ei_cp1254 +WINDOWS-1254, ei_cp1254 +MS-TURK, ei_cp1254 +CP1255, ei_cp1255 +WINDOWS-1255, ei_cp1255 +MS-HEBR, ei_cp1255 +CP1256, ei_cp1256 +WINDOWS-1256, ei_cp1256 +MS-ARAB, ei_cp1256 +CP1257, ei_cp1257 +WINDOWS-1257, ei_cp1257 +WINBALTRIM, ei_cp1257 +CP1258, ei_cp1258 +WINDOWS-1258, ei_cp1258 +CP850, ei_cp850 +IBM850, ei_cp850 +850, ei_cp850 +CSPC850MULTILINGUAL, ei_cp850 +IBM-850, ei_cp850 +CP862, ei_cp862 +IBM862, ei_cp862 +862, ei_cp862 +CSPC862LATINHEBREW, ei_cp862 +CP866, ei_cp866 +IBM866, ei_cp866 +866, ei_cp866 +CSIBM866, ei_cp866 +CP1131, ei_cp1131 +IBM-1131, ei_cp1131 +MACROMAN, ei_mac_roman +MACINTOSH, ei_mac_roman +MAC, ei_mac_roman +CSMACINTOSH, ei_mac_roman +MACCENTRALEUROPE, ei_mac_centraleurope +MACICELAND, ei_mac_iceland +MACCROATIAN, ei_mac_croatian +MACROMANIA, ei_mac_romania +MACCYRILLIC, ei_mac_cyrillic +MACUKRAINE, ei_mac_ukraine +MACGREEK, ei_mac_greek +MACTURKISH, ei_mac_turkish +MACHEBREW, ei_mac_hebrew +MACARABIC, ei_mac_arabic +MACTHAI, ei_mac_thai +HP-ROMAN8, ei_hp_roman8 +ROMAN8, ei_hp_roman8 +R8, ei_hp_roman8 +CSHPROMAN8, ei_hp_roman8 +NEXTSTEP, ei_nextstep +ARMSCII-8, ei_armscii_8 +GEORGIAN-ACADEMY, ei_georgian_academy +GEORGIAN-PS, ei_georgian_ps +KOI8-T, ei_koi8_t +PT154, ei_pt154 +PTCP154, ei_pt154 +CP154, ei_pt154 +CYRILLIC-ASIAN, ei_pt154 +CSPTCP154, ei_pt154 +RK1048, ei_rk1048 +STRK1048-2002, ei_rk1048 +KZ-1048, ei_rk1048 +CSKZ1048, ei_rk1048 +MULELAO-1, ei_mulelao +CP1133, ei_cp1133 +IBM-CP1133, ei_cp1133 +TIS-620, ei_tis620 +TIS620, ei_tis620 +TIS620-0, ei_tis620 +TIS620.2529-1, ei_tis620 +TIS620.2533-0, ei_tis620 +TIS620.2533-1, ei_tis620 +ISO-IR-166, ei_tis620 +CP874, ei_cp874 +WINDOWS-874, ei_cp874 +VISCII, ei_viscii +VISCII1.1-1, ei_viscii +CSVISCII, ei_viscii +TCVN, ei_tcvn +TCVN-5712, ei_tcvn +TCVN5712-1, ei_tcvn +TCVN5712-1:1993, ei_tcvn +JIS_C6220-1969-RO, ei_iso646_jp +ISO646-JP, ei_iso646_jp +ISO-IR-14, ei_iso646_jp +JP, ei_iso646_jp +CSISO14JISC6220RO, ei_iso646_jp +JIS_X0201, ei_jisx0201 +JISX0201-1976, ei_jisx0201 +X0201, ei_jisx0201 +CSHALFWIDTHKATAKANA, ei_jisx0201 +JIS_X0208, ei_jisx0208 +JIS_X0208-1983, ei_jisx0208 +JIS_X0208-1990, ei_jisx0208 +JIS0208, ei_jisx0208 +X0208, ei_jisx0208 +ISO-IR-87, ei_jisx0208 +JIS_C6226-1983, ei_jisx0208 +CSISO87JISX0208, ei_jisx0208 +JIS_X0212, ei_jisx0212 +JIS_X0212.1990-0, ei_jisx0212 +JIS_X0212-1990, ei_jisx0212 +X0212, ei_jisx0212 +ISO-IR-159, ei_jisx0212 +CSISO159JISX02121990, ei_jisx0212 +GB_1988-80, ei_iso646_cn +ISO646-CN, ei_iso646_cn +ISO-IR-57, ei_iso646_cn +CN, ei_iso646_cn +CSISO57GB1988, ei_iso646_cn +GB_2312-80, ei_gb2312 +ISO-IR-58, ei_gb2312 +CSISO58GB231280, ei_gb2312 +CHINESE, ei_gb2312 +ISO-IR-165, ei_isoir165 +CN-GB-ISOIR165, ei_isoir165 +KSC_5601, ei_ksc5601 +KS_C_5601-1987, ei_ksc5601 +KS_C_5601-1989, ei_ksc5601 +ISO-IR-149, ei_ksc5601 +CSKSC56011987, ei_ksc5601 +KOREAN, ei_ksc5601 +EUC-JP, ei_euc_jp +EUCJP, ei_euc_jp +EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE, ei_euc_jp +CSEUCPKDFMTJAPANESE, ei_euc_jp +IBM-EUCJP, ei_euc_jp +SHIFT_JIS, ei_sjis +SHIFT-JIS, ei_sjis +SJIS, ei_sjis +MS_KANJI, ei_sjis +CSSHIFTJIS, ei_sjis +CP932, ei_cp932 +IBM-932, ei_cp932 +ISO-2022-JP, ei_iso2022_jp +CSISO2022JP, ei_iso2022_jp +ISO-2022-JP-1, ei_iso2022_jp1 +ISO-2022-JP-2, ei_iso2022_jp2 +CSISO2022JP2, ei_iso2022_jp2 +EUC-CN, ei_euc_cn +EUCCN, ei_euc_cn +GB2312, ei_euc_cn +CN-GB, ei_euc_cn +CSGB2312, ei_euc_cn +IBM-EUCCN, ei_euc_cn +GBK, ei_ces_gbk +CP936, ei_cp936 +MS936, ei_cp936 +WINDOWS-936, ei_cp936 +GB18030, ei_gb18030 +ISO-2022-CN, ei_iso2022_cn +CSISO2022CN, ei_iso2022_cn +ISO-2022-CN-EXT, ei_iso2022_cn_ext +HZ, ei_hz +HZ-GB-2312, ei_hz +EUC-TW, ei_euc_tw +EUCTW, ei_euc_tw +CSEUCTW, ei_euc_tw +IBM-EUCTW, ei_euc_tw +BIG5, ei_ces_big5 +BIG-5, ei_ces_big5 +BIG-FIVE, ei_ces_big5 +BIGFIVE, ei_ces_big5 +CN-BIG5, ei_ces_big5 +CSBIG5, ei_ces_big5 +CP950, ei_cp950 +BIG5-HKSCS:1999, ei_big5hkscs1999 +BIG5-HKSCS:2001, ei_big5hkscs2001 +BIG5-HKSCS:2004, ei_big5hkscs2004 +BIG5-HKSCS, ei_big5hkscs2008 +BIG5HKSCS, ei_big5hkscs2008 +BIG5-HKSCS:2008, ei_big5hkscs2008 +EUC-KR, ei_euc_kr +EUCKR, ei_euc_kr +CSEUCKR, ei_euc_kr +IBM-EUCKR, ei_euc_kr +CP949, ei_cp949 +UHC, ei_cp949 +JOHAB, ei_johab +CP1361, ei_johab +ISO-2022-KR, ei_iso2022_kr +CSISO2022KR, ei_iso2022_kr +CHAR, ei_local_char +WCHAR_T, ei_local_wchar_t diff --git a/libs/libiconv/lib/aliases_sysaix.h b/libs/libiconv/lib/aliases_sysaix.h new file mode 100644 index 00000000..a5bfa898 --- /dev/null +++ b/libs/libiconv/lib/aliases_sysaix.h @@ -0,0 +1,1769 @@ +/* ANSI-C code produced by gperf version 3.0.4 */ +/* Command-line: gperf -m 10 lib/aliases_sysaix.gperf */ +/* Computed positions: -k'1,3-11,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "lib/aliases_sysaix.gperf" +struct alias { int name; unsigned int encoding_index; }; + +#define TOTAL_KEYWORDS 356 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 45 +#define MIN_HASH_VALUE 13 +#define MAX_HASH_VALUE 989 +/* maximum key range = 977, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +aliases_hash (register const char *str, register unsigned int len) +{ + static const unsigned short asso_values[] = + { + 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, + 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, + 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, + 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, + 990, 990, 990, 990, 990, 13, 112, 990, 73, 4, + 7, 6, 55, 8, 5, 171, 10, 23, 255, 990, + 990, 990, 990, 990, 990, 147, 128, 4, 9, 125, + 130, 5, 75, 4, 402, 69, 7, 125, 18, 4, + 44, 990, 76, 4, 25, 195, 191, 161, 120, 22, + 15, 990, 990, 990, 990, 27, 990, 990, 990, 990, + 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, + 990, 990, 990, 990, 990, 990, 990, 990, 990, 990, + 990, 990, 990, 990, 990, 990, 990, 990 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[10]]; + /*FALLTHROUGH*/ + case 10: + hval += asso_values[(unsigned char)str[9]]; + /*FALLTHROUGH*/ + case 9: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +struct stringpool_t + { + char stringpool_str13[sizeof("L1")]; + char stringpool_str14[sizeof("L6")]; + char stringpool_str15[sizeof("L3")]; + char stringpool_str16[sizeof("L2")]; + char stringpool_str17[sizeof("L5")]; + char stringpool_str19[sizeof("L8")]; + char stringpool_str20[sizeof("SJIS")]; + char stringpool_str23[sizeof("866")]; + char stringpool_str24[sizeof("CN")]; + char stringpool_str27[sizeof("862")]; + char stringpool_str32[sizeof("CP1131")]; + char stringpool_str33[sizeof("CP1361")]; + char stringpool_str34[sizeof("CP866")]; + char stringpool_str36[sizeof("CP1133")]; + char stringpool_str37[sizeof("CP1251")]; + char stringpool_str38[sizeof("CP862")]; + char stringpool_str39[sizeof("CP1256")]; + char stringpool_str41[sizeof("CP1253")]; + char stringpool_str42[sizeof("GB2312")]; + char stringpool_str43[sizeof("CP1252")]; + char stringpool_str45[sizeof("CP1255")]; + char stringpool_str48[sizeof("CP936")]; + char stringpool_str49[sizeof("CP1258")]; + char stringpool_str52[sizeof("CP932")]; + char stringpool_str53[sizeof("C99")]; + char stringpool_str64[sizeof("L4")]; + char stringpool_str68[sizeof("LATIN1")]; + char stringpool_str69[sizeof("CP819")]; + char stringpool_str70[sizeof("LATIN6")]; + char stringpool_str72[sizeof("LATIN3")]; + char stringpool_str74[sizeof("LATIN2")]; + char stringpool_str76[sizeof("LATIN5")]; + char stringpool_str80[sizeof("LATIN8")]; + char stringpool_str88[sizeof("R8")]; + char stringpool_str89[sizeof("ISO8859-1")]; + char stringpool_str91[sizeof("ISO8859-6")]; + char stringpool_str92[sizeof("HZ")]; + char stringpool_str93[sizeof("ISO8859-3")]; + char stringpool_str94[sizeof("ISO8859-11")]; + char stringpool_str95[sizeof("ISO8859-2")]; + char stringpool_str96[sizeof("ISO8859-16")]; + char stringpool_str97[sizeof("ISO8859-5")]; + char stringpool_str98[sizeof("ISO8859-13")]; + char stringpool_str101[sizeof("ISO8859-8")]; + char stringpool_str102[sizeof("ISO8859-15")]; + char stringpool_str103[sizeof("ISO-8859-1")]; + char stringpool_str105[sizeof("ISO-8859-6")]; + char stringpool_str107[sizeof("ISO-8859-3")]; + char stringpool_str108[sizeof("ISO-8859-11")]; + char stringpool_str109[sizeof("ISO-8859-2")]; + char stringpool_str110[sizeof("ISO-8859-16")]; + char stringpool_str111[sizeof("ISO-8859-5")]; + char stringpool_str112[sizeof("ISO-8859-13")]; + char stringpool_str115[sizeof("ISO-8859-8")]; + char stringpool_str116[sizeof("ISO-8859-15")]; + char stringpool_str117[sizeof("ISO_8859-1")]; + char stringpool_str118[sizeof("CYRILLIC")]; + char stringpool_str119[sizeof("ISO_8859-6")]; + char stringpool_str120[sizeof("LATIN-9")]; + char stringpool_str121[sizeof("ISO_8859-3")]; + char stringpool_str122[sizeof("ISO_8859-11")]; + char stringpool_str123[sizeof("ISO_8859-2")]; + char stringpool_str124[sizeof("ISO_8859-16")]; + char stringpool_str125[sizeof("ISO_8859-5")]; + char stringpool_str126[sizeof("ISO_8859-13")]; + char stringpool_str127[sizeof("ISO8859-9")]; + char stringpool_str128[sizeof("ISO_8859-16:2001")]; + char stringpool_str129[sizeof("ISO_8859-8")]; + char stringpool_str130[sizeof("ISO_8859-15")]; + char stringpool_str131[sizeof("CP154")]; + char stringpool_str132[sizeof("ISO-IR-6")]; + char stringpool_str133[sizeof("CP949")]; + char stringpool_str135[sizeof("ISO646-CN")]; + char stringpool_str136[sizeof("MAC")]; + char stringpool_str137[sizeof("ISO_8859-15:1998")]; + char stringpool_str139[sizeof("CP1254")]; + char stringpool_str141[sizeof("ISO-8859-9")]; + char stringpool_str143[sizeof("ISO-IR-166")]; + char stringpool_str145[sizeof("ISO-IR-126")]; + char stringpool_str146[sizeof("GBK")]; + char stringpool_str148[sizeof("ISO-IR-226")]; + char stringpool_str149[sizeof("ISO-IR-165")]; + char stringpool_str150[sizeof("X0212")]; + char stringpool_str151[sizeof("ISO-IR-58")]; + char stringpool_str152[sizeof("KOI8-T")]; + char stringpool_str153[sizeof("BIG5")]; + char stringpool_str154[sizeof("ISO-IR-138")]; + char stringpool_str155[sizeof("ISO_8859-9")]; + char stringpool_str156[sizeof("L10")]; + char stringpool_str159[sizeof("850")]; + char stringpool_str160[sizeof("IBM866")]; + char stringpool_str161[sizeof("CSISO2022CN")]; + char stringpool_str163[sizeof("CSBIG5")]; + char stringpool_str164[sizeof("IBM862")]; + char stringpool_str167[sizeof("BIG-5")]; + char stringpool_str168[sizeof("ASCII")]; + char stringpool_str169[sizeof("MS936")]; + char stringpool_str170[sizeof("LATIN4")]; + char stringpool_str171[sizeof("PT154")]; + char stringpool_str172[sizeof("IBM-1131")]; + char stringpool_str173[sizeof("CP850")]; + char stringpool_str174[sizeof("EUCCN")]; + char stringpool_str175[sizeof("CP1250")]; + char stringpool_str176[sizeof("CSGB2312")]; + char stringpool_str177[sizeof("CN-BIG5")]; + char stringpool_str178[sizeof("CSASCII")]; + char stringpool_str179[sizeof("ISO-2022-CN")]; + char stringpool_str180[sizeof("L7")]; + char stringpool_str182[sizeof("ISO-IR-159")]; + char stringpool_str183[sizeof("IBM-1252")]; + char stringpool_str184[sizeof("ISO_8859-14:1998")]; + char stringpool_str186[sizeof("CP950")]; + char stringpool_str187[sizeof("IBM-921")]; + char stringpool_str188[sizeof("EUC-CN")]; + char stringpool_str190[sizeof("ISO-2022-CN-EXT")]; + char stringpool_str191[sizeof("ISO8859-4")]; + char stringpool_str192[sizeof("IBM-932")]; + char stringpool_str193[sizeof("TIS620")]; + char stringpool_str195[sizeof("IBM819")]; + char stringpool_str196[sizeof("ISO8859-14")]; + char stringpool_str197[sizeof("ISO-IR-199")]; + char stringpool_str199[sizeof("ISO_8859-10:1992")]; + char stringpool_str201[sizeof("US")]; + char stringpool_str202[sizeof("KSC_5601")]; + char stringpool_str203[sizeof("ISO-IR-148")]; + char stringpool_str204[sizeof("ISO-CELTIC")]; + char stringpool_str205[sizeof("ISO-8859-4")]; + char stringpool_str206[sizeof("UHC")]; + char stringpool_str207[sizeof("TIS-620")]; + char stringpool_str209[sizeof("ISO-IR-101")]; + char stringpool_str210[sizeof("ISO-8859-14")]; + char stringpool_str211[sizeof("LATIN10")]; + char stringpool_str213[sizeof("X0201")]; + char stringpool_str216[sizeof("ISO-IR-203")]; + char stringpool_str217[sizeof("VISCII")]; + char stringpool_str219[sizeof("ISO_8859-4")]; + char stringpool_str221[sizeof("PTCP154")]; + char stringpool_str224[sizeof("ISO_8859-14")]; + char stringpool_str225[sizeof("X0208")]; + char stringpool_str226[sizeof("IBM-CP1133")]; + char stringpool_str227[sizeof("CSVISCII")]; + char stringpool_str229[sizeof("ISO-IR-149")]; + char stringpool_str231[sizeof("UCS-2")]; + char stringpool_str232[sizeof("ISO8859-10")]; + char stringpool_str234[sizeof("RK1048")]; + char stringpool_str235[sizeof("GB_2312-80")]; + char stringpool_str236[sizeof("CSISOLATIN1")]; + char stringpool_str237[sizeof("ISO-IR-14")]; + char stringpool_str238[sizeof("CSISOLATIN6")]; + char stringpool_str239[sizeof("ELOT_928")]; + char stringpool_str240[sizeof("CSISOLATIN3")]; + char stringpool_str241[sizeof("KZ-1048")]; + char stringpool_str242[sizeof("CSISOLATIN2")]; + char stringpool_str243[sizeof("CSISOLATINCYRILLIC")]; + char stringpool_str244[sizeof("CSISOLATIN5")]; + char stringpool_str246[sizeof("ISO-8859-10")]; + char stringpool_str247[sizeof("ISO-IR-109")]; + char stringpool_str248[sizeof("CSKZ1048")]; + char stringpool_str250[sizeof("CSKOI8R")]; + char stringpool_str251[sizeof("GB18030")]; + char stringpool_str252[sizeof("CSPTCP154")]; + char stringpool_str254[sizeof("KOI8-R")]; + char stringpool_str256[sizeof("TCVN")]; + char stringpool_str258[sizeof("GB_1988-80")]; + char stringpool_str260[sizeof("ISO_8859-10")]; + char stringpool_str261[sizeof("MS-CYRL")]; + char stringpool_str268[sizeof("CSISO58GB231280")]; + char stringpool_str270[sizeof("TIS620.2533-1")]; + char stringpool_str271[sizeof("KS_C_5601-1989")]; + char stringpool_str272[sizeof("MACCYRILLIC")]; + char stringpool_str275[sizeof("HZ-GB-2312")]; + char stringpool_str277[sizeof("CN-GB-ISOIR165")]; + char stringpool_str278[sizeof("ISO-IR-110")]; + char stringpool_str281[sizeof("TIS620-0")]; + char stringpool_str283[sizeof("CN-GB")]; + char stringpool_str288[sizeof("TIS620.2529-1")]; + char stringpool_str293[sizeof("ISO-IR-144")]; + char stringpool_str294[sizeof("CSIBM866")]; + char stringpool_str298[sizeof("ISO646-US")]; + char stringpool_str299[sizeof("IBM850")]; + char stringpool_str300[sizeof("CP874")]; + char stringpool_str302[sizeof("CYRILLIC-ASIAN")]; + char stringpool_str306[sizeof("CSISOLATINGREEK")]; + char stringpool_str307[sizeof("CHAR")]; + char stringpool_str310[sizeof("BIG5HKSCS")]; + char stringpool_str313[sizeof("IBM-850")]; + char stringpool_str322[sizeof("MS-ANSI")]; + char stringpool_str323[sizeof("CSUCS4")]; + char stringpool_str324[sizeof("BIG5-HKSCS")]; + char stringpool_str327[sizeof("UCS-4")]; + char stringpool_str330[sizeof("ARMSCII-8")]; + char stringpool_str335[sizeof("GEORGIAN-PS")]; + char stringpool_str338[sizeof("CSISOLATIN4")]; + char stringpool_str339[sizeof("TIS620.2533-0")]; + char stringpool_str342[sizeof("CSISO2022KR")]; + char stringpool_str343[sizeof("MACINTOSH")]; + char stringpool_str345[sizeof("ISO-IR-179")]; + char stringpool_str347[sizeof("ISO-IR-100")]; + char stringpool_str350[sizeof("GREEK8")]; + char stringpool_str355[sizeof("EUCKR")]; + char stringpool_str358[sizeof("UTF-16")]; + char stringpool_str359[sizeof("VISCII1.1-1")]; + char stringpool_str360[sizeof("ISO-2022-KR")]; + char stringpool_str362[sizeof("CP367")]; + char stringpool_str363[sizeof("UTF-8")]; + char stringpool_str364[sizeof("UTF-32")]; + char stringpool_str369[sizeof("EUC-KR")]; + char stringpool_str371[sizeof("CP1257")]; + char stringpool_str378[sizeof("CSISO57GB1988")]; + char stringpool_str382[sizeof("CSKSC56011987")]; + char stringpool_str383[sizeof("US-ASCII")]; + char stringpool_str384[sizeof("CSISOLATINARABIC")]; + char stringpool_str385[sizeof("ISO_8859-3:1988")]; + char stringpool_str386[sizeof("CSUNICODE11")]; + char stringpool_str387[sizeof("ISO_8859-5:1988")]; + char stringpool_str389[sizeof("ISO_8859-8:1988")]; + char stringpool_str390[sizeof("UNICODE-1-1")]; + char stringpool_str391[sizeof("MACTHAI")]; + char stringpool_str392[sizeof("ROMAN8")]; + char stringpool_str393[sizeof("ISO-10646-UCS-2")]; + char stringpool_str398[sizeof("GREEK")]; + char stringpool_str402[sizeof("LATIN7")]; + char stringpool_str404[sizeof("STRK1048-2002")]; + char stringpool_str405[sizeof("WINDOWS-1251")]; + char stringpool_str406[sizeof("WINDOWS-1256")]; + char stringpool_str407[sizeof("WINDOWS-1253")]; + char stringpool_str408[sizeof("WINDOWS-1252")]; + char stringpool_str409[sizeof("WINDOWS-1255")]; + char stringpool_str411[sizeof("WINDOWS-1258")]; + char stringpool_str412[sizeof("CHINESE")]; + char stringpool_str413[sizeof("NEXTSTEP")]; + char stringpool_str415[sizeof("ISO_8859-9:1989")]; + char stringpool_str419[sizeof("KS_C_5601-1987")]; + char stringpool_str420[sizeof("WINDOWS-936")]; + char stringpool_str423[sizeof("ISO8859-7")]; + char stringpool_str434[sizeof("ISO_8859-4:1988")]; + char stringpool_str436[sizeof("CSPC862LATINHEBREW")]; + char stringpool_str437[sizeof("ISO-8859-7")]; + char stringpool_str440[sizeof("ARABIC")]; + char stringpool_str441[sizeof("ISO-10646-UCS-4")]; + char stringpool_str445[sizeof("MULELAO-1")]; + char stringpool_str446[sizeof("ECMA-118")]; + char stringpool_str448[sizeof("JP")]; + char stringpool_str451[sizeof("ISO_8859-7")]; + char stringpool_str453[sizeof("TCVN-5712")]; + char stringpool_str455[sizeof("TCVN5712-1")]; + char stringpool_str456[sizeof("WINDOWS-1254")]; + char stringpool_str459[sizeof("KOREAN")]; + char stringpool_str461[sizeof("GEORGIAN-ACADEMY")]; + char stringpool_str462[sizeof("MACICELAND")]; + char stringpool_str469[sizeof("CSISOLATINHEBREW")]; + char stringpool_str473[sizeof("ISO-IR-57")]; + char stringpool_str474[sizeof("WINDOWS-1250")]; + char stringpool_str475[sizeof("ISO-IR-87")]; + char stringpool_str477[sizeof("ISO-IR-127")]; + char stringpool_str478[sizeof("ISO-IR-157")]; + char stringpool_str481[sizeof("EUCTW")]; + char stringpool_str483[sizeof("UCS-2LE")]; + char stringpool_str487[sizeof("HP-ROMAN8")]; + char stringpool_str488[sizeof("IBM367")]; + char stringpool_str492[sizeof("KOI8-U")]; + char stringpool_str493[sizeof("UNICODEBIG")]; + char stringpool_str495[sizeof("EUC-TW")]; + char stringpool_str496[sizeof("CSMACINTOSH")]; + char stringpool_str497[sizeof("CSUNICODE")]; + char stringpool_str498[sizeof("JIS_C6226-1983")]; + char stringpool_str501[sizeof("UCS-2-INTERNAL")]; + char stringpool_str503[sizeof("ISO_646.IRV:1991")]; + char stringpool_str510[sizeof("CSISO14JISC6220RO")]; + char stringpool_str511[sizeof("ANSI_X3.4-1986")]; + char stringpool_str515[sizeof("IBM-EUCCN")]; + char stringpool_str516[sizeof("ANSI_X3.4-1968")]; + char stringpool_str518[sizeof("MS-EE")]; + char stringpool_str521[sizeof("CSPC850MULTILINGUAL")]; + char stringpool_str523[sizeof("CSHPROMAN8")]; + char stringpool_str525[sizeof("MACROMAN")]; + char stringpool_str531[sizeof("UCS-4LE")]; + char stringpool_str536[sizeof("ECMA-114")]; + char stringpool_str540[sizeof("UNICODELITTLE")]; + char stringpool_str543[sizeof("WCHAR_T")]; + char stringpool_str544[sizeof("ISO_8859-1:1987")]; + char stringpool_str545[sizeof("ISO_8859-6:1987")]; + char stringpool_str546[sizeof("ISO_8859-7:2003")]; + char stringpool_str547[sizeof("ISO_8859-2:1987")]; + char stringpool_str549[sizeof("UCS-4-INTERNAL")]; + char stringpool_str554[sizeof("CSISO159JISX02121990")]; + char stringpool_str556[sizeof("CSEUCKR")]; + char stringpool_str557[sizeof("CSUNICODE11UTF7")]; + char stringpool_str561[sizeof("ASMO-708")]; + char stringpool_str563[sizeof("UNICODE-1-1-UTF-7")]; + char stringpool_str567[sizeof("JIS_C6220-1969-RO")]; + char stringpool_str569[sizeof("KOI8-RU")]; + char stringpool_str572[sizeof("WINDOWS-1257")]; + char stringpool_str575[sizeof("CSISO2022JP2")]; + char stringpool_str579[sizeof("MS-TURK")]; + char stringpool_str583[sizeof("MACCROATIAN")]; + char stringpool_str584[sizeof("BIG5-HKSCS:2001")]; + char stringpool_str585[sizeof("ISO646-JP")]; + char stringpool_str586[sizeof("JIS0208")]; + char stringpool_str590[sizeof("BIG5-HKSCS:2008")]; + char stringpool_str591[sizeof("ISO-2022-JP-1")]; + char stringpool_str594[sizeof("ISO-2022-JP-2")]; + char stringpool_str599[sizeof("SHIFT-JIS")]; + char stringpool_str603[sizeof("BIG5-HKSCS:1999")]; + char stringpool_str604[sizeof("UCS-2BE")]; + char stringpool_str606[sizeof("MACGREEK")]; + char stringpool_str611[sizeof("CSISO2022JP")]; + char stringpool_str612[sizeof("UTF-16LE")]; + char stringpool_str613[sizeof("SHIFT_JIS")]; + char stringpool_str615[sizeof("MS-GREEK")]; + char stringpool_str616[sizeof("UTF-32LE")]; + char stringpool_str624[sizeof("EUCJP")]; + char stringpool_str625[sizeof("MS-HEBR")]; + char stringpool_str629[sizeof("ISO-2022-JP")]; + char stringpool_str635[sizeof("BIG5-HKSCS:2004")]; + char stringpool_str638[sizeof("EUC-JP")]; + char stringpool_str648[sizeof("MACARABIC")]; + char stringpool_str652[sizeof("UCS-4BE")]; + char stringpool_str654[sizeof("UCS-2-SWAPPED")]; + char stringpool_str660[sizeof("JIS_X0212")]; + char stringpool_str662[sizeof("MACTURKISH")]; + char stringpool_str666[sizeof("CSSHIFTJIS")]; + char stringpool_str672[sizeof("WINDOWS-874")]; + char stringpool_str682[sizeof("CSEUCTW")]; + char stringpool_str685[sizeof("UTF-7")]; + char stringpool_str696[sizeof("IBM-EUCKR")]; + char stringpool_str702[sizeof("UCS-4-SWAPPED")]; + char stringpool_str711[sizeof("ISO_8859-7:1987")]; + char stringpool_str715[sizeof("BIGFIVE")]; + char stringpool_str717[sizeof("TCVN5712-1:1993")]; + char stringpool_str723[sizeof("JIS_X0201")]; + char stringpool_str729[sizeof("BIG-FIVE")]; + char stringpool_str732[sizeof("HEBREW")]; + char stringpool_str733[sizeof("UTF-16BE")]; + char stringpool_str735[sizeof("JIS_X0208")]; + char stringpool_str737[sizeof("UTF-32BE")]; + char stringpool_str741[sizeof("JISX0201-1976")]; + char stringpool_str748[sizeof("JIS_X0212-1990")]; + char stringpool_str752[sizeof("CSISO87JISX0208")]; + char stringpool_str753[sizeof("JIS_X0208-1983")]; + char stringpool_str771[sizeof("MS-ARAB")]; + char stringpool_str797[sizeof("MACCENTRALEUROPE")]; + char stringpool_str803[sizeof("CSHALFWIDTHKATAKANA")]; + char stringpool_str804[sizeof("MS_KANJI")]; + char stringpool_str807[sizeof("MACROMANIA")]; + char stringpool_str820[sizeof("JIS_X0208-1990")]; + char stringpool_str822[sizeof("IBM-EUCTW")]; + char stringpool_str826[sizeof("WINBALTRIM")]; + char stringpool_str846[sizeof("EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE")]; + char stringpool_str849[sizeof("JIS_X0212.1990-0")]; + char stringpool_str874[sizeof("CSEUCPKDFMTJAPANESE")]; + char stringpool_str885[sizeof("JOHAB")]; + char stringpool_str891[sizeof("JAVA")]; + char stringpool_str898[sizeof("MACUKRAINE")]; + char stringpool_str965[sizeof("IBM-EUCJP")]; + char stringpool_str989[sizeof("MACHEBREW")]; + }; +static const struct stringpool_t stringpool_contents = + { + "L1", + "L6", + "L3", + "L2", + "L5", + "L8", + "SJIS", + "866", + "CN", + "862", + "CP1131", + "CP1361", + "CP866", + "CP1133", + "CP1251", + "CP862", + "CP1256", + "CP1253", + "GB2312", + "CP1252", + "CP1255", + "CP936", + "CP1258", + "CP932", + "C99", + "L4", + "LATIN1", + "CP819", + "LATIN6", + "LATIN3", + "LATIN2", + "LATIN5", + "LATIN8", + "R8", + "ISO8859-1", + "ISO8859-6", + "HZ", + "ISO8859-3", + "ISO8859-11", + "ISO8859-2", + "ISO8859-16", + "ISO8859-5", + "ISO8859-13", + "ISO8859-8", + "ISO8859-15", + "ISO-8859-1", + "ISO-8859-6", + "ISO-8859-3", + "ISO-8859-11", + "ISO-8859-2", + "ISO-8859-16", + "ISO-8859-5", + "ISO-8859-13", + "ISO-8859-8", + "ISO-8859-15", + "ISO_8859-1", + "CYRILLIC", + "ISO_8859-6", + "LATIN-9", + "ISO_8859-3", + "ISO_8859-11", + "ISO_8859-2", + "ISO_8859-16", + "ISO_8859-5", + "ISO_8859-13", + "ISO8859-9", + "ISO_8859-16:2001", + "ISO_8859-8", + "ISO_8859-15", + "CP154", + "ISO-IR-6", + "CP949", + "ISO646-CN", + "MAC", + "ISO_8859-15:1998", + "CP1254", + "ISO-8859-9", + "ISO-IR-166", + "ISO-IR-126", + "GBK", + "ISO-IR-226", + "ISO-IR-165", + "X0212", + "ISO-IR-58", + "KOI8-T", + "BIG5", + "ISO-IR-138", + "ISO_8859-9", + "L10", + "850", + "IBM866", + "CSISO2022CN", + "CSBIG5", + "IBM862", + "BIG-5", + "ASCII", + "MS936", + "LATIN4", + "PT154", + "IBM-1131", + "CP850", + "EUCCN", + "CP1250", + "CSGB2312", + "CN-BIG5", + "CSASCII", + "ISO-2022-CN", + "L7", + "ISO-IR-159", + "IBM-1252", + "ISO_8859-14:1998", + "CP950", + "IBM-921", + "EUC-CN", + "ISO-2022-CN-EXT", + "ISO8859-4", + "IBM-932", + "TIS620", + "IBM819", + "ISO8859-14", + "ISO-IR-199", + "ISO_8859-10:1992", + "US", + "KSC_5601", + "ISO-IR-148", + "ISO-CELTIC", + "ISO-8859-4", + "UHC", + "TIS-620", + "ISO-IR-101", + "ISO-8859-14", + "LATIN10", + "X0201", + "ISO-IR-203", + "VISCII", + "ISO_8859-4", + "PTCP154", + "ISO_8859-14", + "X0208", + "IBM-CP1133", + "CSVISCII", + "ISO-IR-149", + "UCS-2", + "ISO8859-10", + "RK1048", + "GB_2312-80", + "CSISOLATIN1", + "ISO-IR-14", + "CSISOLATIN6", + "ELOT_928", + "CSISOLATIN3", + "KZ-1048", + "CSISOLATIN2", + "CSISOLATINCYRILLIC", + "CSISOLATIN5", + "ISO-8859-10", + "ISO-IR-109", + "CSKZ1048", + "CSKOI8R", + "GB18030", + "CSPTCP154", + "KOI8-R", + "TCVN", + "GB_1988-80", + "ISO_8859-10", + "MS-CYRL", + "CSISO58GB231280", + "TIS620.2533-1", + "KS_C_5601-1989", + "MACCYRILLIC", + "HZ-GB-2312", + "CN-GB-ISOIR165", + "ISO-IR-110", + "TIS620-0", + "CN-GB", + "TIS620.2529-1", + "ISO-IR-144", + "CSIBM866", + "ISO646-US", + "IBM850", + "CP874", + "CYRILLIC-ASIAN", + "CSISOLATINGREEK", + "CHAR", + "BIG5HKSCS", + "IBM-850", + "MS-ANSI", + "CSUCS4", + "BIG5-HKSCS", + "UCS-4", + "ARMSCII-8", + "GEORGIAN-PS", + "CSISOLATIN4", + "TIS620.2533-0", + "CSISO2022KR", + "MACINTOSH", + "ISO-IR-179", + "ISO-IR-100", + "GREEK8", + "EUCKR", + "UTF-16", + "VISCII1.1-1", + "ISO-2022-KR", + "CP367", + "UTF-8", + "UTF-32", + "EUC-KR", + "CP1257", + "CSISO57GB1988", + "CSKSC56011987", + "US-ASCII", + "CSISOLATINARABIC", + "ISO_8859-3:1988", + "CSUNICODE11", + "ISO_8859-5:1988", + "ISO_8859-8:1988", + "UNICODE-1-1", + "MACTHAI", + "ROMAN8", + "ISO-10646-UCS-2", + "GREEK", + "LATIN7", + "STRK1048-2002", + "WINDOWS-1251", + "WINDOWS-1256", + "WINDOWS-1253", + "WINDOWS-1252", + "WINDOWS-1255", + "WINDOWS-1258", + "CHINESE", + "NEXTSTEP", + "ISO_8859-9:1989", + "KS_C_5601-1987", + "WINDOWS-936", + "ISO8859-7", + "ISO_8859-4:1988", + "CSPC862LATINHEBREW", + "ISO-8859-7", + "ARABIC", + "ISO-10646-UCS-4", + "MULELAO-1", + "ECMA-118", + "JP", + "ISO_8859-7", + "TCVN-5712", + "TCVN5712-1", + "WINDOWS-1254", + "KOREAN", + "GEORGIAN-ACADEMY", + "MACICELAND", + "CSISOLATINHEBREW", + "ISO-IR-57", + "WINDOWS-1250", + "ISO-IR-87", + "ISO-IR-127", + "ISO-IR-157", + "EUCTW", + "UCS-2LE", + "HP-ROMAN8", + "IBM367", + "KOI8-U", + "UNICODEBIG", + "EUC-TW", + "CSMACINTOSH", + "CSUNICODE", + "JIS_C6226-1983", + "UCS-2-INTERNAL", + "ISO_646.IRV:1991", + "CSISO14JISC6220RO", + "ANSI_X3.4-1986", + "IBM-EUCCN", + "ANSI_X3.4-1968", + "MS-EE", + "CSPC850MULTILINGUAL", + "CSHPROMAN8", + "MACROMAN", + "UCS-4LE", + "ECMA-114", + "UNICODELITTLE", + "WCHAR_T", + "ISO_8859-1:1987", + "ISO_8859-6:1987", + "ISO_8859-7:2003", + "ISO_8859-2:1987", + "UCS-4-INTERNAL", + "CSISO159JISX02121990", + "CSEUCKR", + "CSUNICODE11UTF7", + "ASMO-708", + "UNICODE-1-1-UTF-7", + "JIS_C6220-1969-RO", + "KOI8-RU", + "WINDOWS-1257", + "CSISO2022JP2", + "MS-TURK", + "MACCROATIAN", + "BIG5-HKSCS:2001", + "ISO646-JP", + "JIS0208", + "BIG5-HKSCS:2008", + "ISO-2022-JP-1", + "ISO-2022-JP-2", + "SHIFT-JIS", + "BIG5-HKSCS:1999", + "UCS-2BE", + "MACGREEK", + "CSISO2022JP", + "UTF-16LE", + "SHIFT_JIS", + "MS-GREEK", + "UTF-32LE", + "EUCJP", + "MS-HEBR", + "ISO-2022-JP", + "BIG5-HKSCS:2004", + "EUC-JP", + "MACARABIC", + "UCS-4BE", + "UCS-2-SWAPPED", + "JIS_X0212", + "MACTURKISH", + "CSSHIFTJIS", + "WINDOWS-874", + "CSEUCTW", + "UTF-7", + "IBM-EUCKR", + "UCS-4-SWAPPED", + "ISO_8859-7:1987", + "BIGFIVE", + "TCVN5712-1:1993", + "JIS_X0201", + "BIG-FIVE", + "HEBREW", + "UTF-16BE", + "JIS_X0208", + "UTF-32BE", + "JISX0201-1976", + "JIS_X0212-1990", + "CSISO87JISX0208", + "JIS_X0208-1983", + "MS-ARAB", + "MACCENTRALEUROPE", + "CSHALFWIDTHKATAKANA", + "MS_KANJI", + "MACROMANIA", + "JIS_X0208-1990", + "IBM-EUCTW", + "WINBALTRIM", + "EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE", + "JIS_X0212.1990-0", + "CSEUCPKDFMTJAPANESE", + "JOHAB", + "JAVA", + "MACUKRAINE", + "IBM-EUCJP", + "MACHEBREW" + }; +#define stringpool ((const char *) &stringpool_contents) + +static const struct alias aliases[] = + { + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 60 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str13, ei_iso8859_1}, +#line 134 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str14, ei_iso8859_10}, +#line 76 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str15, ei_iso8859_3}, +#line 68 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str16, ei_iso8859_2}, +#line 126 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str17, ei_iso8859_9}, + {-1}, +#line 152 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str19, ei_iso8859_14}, +#line 313 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str20, ei_sjis}, + {-1}, {-1}, +#line 210 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str23, ei_cp866}, +#line 292 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str24, ei_iso646_cn}, + {-1}, {-1}, +#line 206 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str27, ei_cp862}, + {-1}, {-1}, {-1}, {-1}, +#line 212 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str32, ei_cp1131}, +#line 363 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str33, ei_johab}, +#line 208 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str34, ei_cp866}, + {-1}, +#line 248 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str36, ei_cp1133}, +#line 175 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str37, ei_cp1251}, +#line 204 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str38, ei_cp862}, +#line 191 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str39, ei_cp1256}, + {-1}, +#line 182 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str41, ei_cp1253}, +#line 325 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str42, ei_euc_cn}, +#line 178 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str43, ei_cp1252}, + {-1}, +#line 188 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str45, ei_cp1255}, + {-1}, {-1}, +#line 330 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str48, ei_cp936}, +#line 197 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str49, ei_cp1258}, + {-1}, {-1}, +#line 316 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str52, ei_cp932}, +#line 51 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str53, ei_c99}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 84 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str64, ei_iso8859_4}, + {-1}, {-1}, {-1}, +#line 59 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str68, ei_iso8859_1}, +#line 57 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str69, ei_iso8859_1}, +#line 133 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str70, ei_iso8859_10}, + {-1}, +#line 75 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str72, ei_iso8859_3}, + {-1}, +#line 67 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str74, ei_iso8859_2}, + {-1}, +#line 125 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str76, ei_iso8859_9}, + {-1}, {-1}, {-1}, +#line 151 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str80, ei_iso8859_14}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 231 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str88, ei_hp_roman8}, +#line 62 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str89, ei_iso8859_1}, + {-1}, +#line 102 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str91, ei_iso8859_6}, +#line 337 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str92, ei_hz}, +#line 78 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str93, ei_iso8859_3}, +#line 139 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str94, ei_iso8859_11}, +#line 70 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str95, ei_iso8859_2}, +#line 167 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str96, ei_iso8859_16}, +#line 93 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str97, ei_iso8859_5}, +#line 145 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str98, ei_iso8859_13}, + {-1}, {-1}, +#line 120 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str101, ei_iso8859_8}, +#line 160 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str102, ei_iso8859_15}, +#line 53 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str103, ei_iso8859_1}, + {-1}, +#line 94 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str105, ei_iso8859_6}, + {-1}, +#line 71 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str107, ei_iso8859_3}, +#line 137 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str108, ei_iso8859_11}, +#line 63 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str109, ei_iso8859_2}, +#line 161 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str110, ei_iso8859_16}, +#line 87 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str111, ei_iso8859_5}, +#line 140 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str112, ei_iso8859_13}, + {-1}, {-1}, +#line 114 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str115, ei_iso8859_8}, +#line 155 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str116, ei_iso8859_15}, +#line 54 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str117, ei_iso8859_1}, +#line 91 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str118, ei_iso8859_5}, +#line 95 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str119, ei_iso8859_6}, +#line 159 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str120, ei_iso8859_15}, +#line 72 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str121, ei_iso8859_3}, +#line 138 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str122, ei_iso8859_11}, +#line 64 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str123, ei_iso8859_2}, +#line 162 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str124, ei_iso8859_16}, +#line 88 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str125, ei_iso8859_5}, +#line 141 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str126, ei_iso8859_13}, +#line 128 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str127, ei_iso8859_9}, +#line 163 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str128, ei_iso8859_16}, +#line 115 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str129, ei_iso8859_8}, +#line 156 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str130, ei_iso8859_15}, +#line 240 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str131, ei_pt154}, +#line 16 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str132, ei_ascii}, +#line 360 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str133, ei_cp949}, + {-1}, +#line 290 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str135, ei_iso646_cn}, +#line 216 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str136, ei_mac_roman}, +#line 157 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str137, ei_iso8859_15}, + {-1}, +#line 185 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str139, ei_cp1254}, + {-1}, +#line 121 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str141, ei_iso8859_9}, + {-1}, +#line 256 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str143, ei_tis620}, + {-1}, +#line 107 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str145, ei_iso8859_7}, +#line 329 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str146, ei_ces_gbk}, + {-1}, +#line 164 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str148, ei_iso8859_16}, +#line 298 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str149, ei_isoir165}, +#line 286 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str150, ei_jisx0212}, +#line 295 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str151, ei_gb2312}, +#line 237 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str152, ei_koi8_t}, +#line 343 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str153, ei_ces_big5}, +#line 117 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str154, ei_iso8859_8}, +#line 122 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str155, ei_iso8859_9}, +#line 166 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str156, ei_iso8859_16}, + {-1}, {-1}, +#line 201 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str159, ei_cp850}, +#line 209 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str160, ei_cp866}, +#line 335 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str161, ei_iso2022_cn}, + {-1}, +#line 348 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str163, ei_ces_big5}, +#line 205 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str164, ei_cp862}, + {-1}, {-1}, +#line 344 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str167, ei_ces_big5}, +#line 13 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str168, ei_ascii}, +#line 331 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str169, ei_cp936}, +#line 83 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str170, ei_iso8859_4}, +#line 238 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str171, ei_pt154}, +#line 213 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str172, ei_cp1131}, +#line 199 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str173, ei_cp850}, +#line 324 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str174, ei_euc_cn}, +#line 172 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str175, ei_cp1250}, +#line 327 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str176, ei_euc_cn}, +#line 347 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str177, ei_ces_big5}, +#line 22 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str178, ei_ascii}, +#line 334 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str179, ei_iso2022_cn}, +#line 144 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str180, ei_iso8859_13}, + {-1}, +#line 287 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str182, ei_jisx0212}, +#line 181 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str183, ei_cp1252}, +#line 149 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str184, ei_iso8859_14}, + {-1}, +#line 349 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str186, ei_cp950}, +#line 146 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str187, ei_iso8859_13}, +#line 323 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str188, ei_euc_cn}, + {-1}, +#line 336 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str190, ei_iso2022_cn_ext}, +#line 86 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str191, ei_iso8859_4}, +#line 317 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str192, ei_cp932}, +#line 251 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str193, ei_tis620}, + {-1}, +#line 58 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str195, ei_iso8859_1}, +#line 154 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str196, ei_iso8859_14}, +#line 150 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str197, ei_iso8859_14}, + {-1}, +#line 131 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str199, ei_iso8859_10}, + {-1}, +#line 21 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str201, ei_ascii}, +#line 300 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str202, ei_ksc5601}, +#line 124 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str203, ei_iso8859_9}, +#line 153 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str204, ei_iso8859_14}, +#line 79 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str205, ei_iso8859_4}, +#line 361 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str206, ei_cp949}, +#line 250 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str207, ei_tis620}, + {-1}, +#line 66 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str209, ei_iso8859_2}, +#line 147 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str210, ei_iso8859_14}, +#line 165 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str211, ei_iso8859_16}, + {-1}, +#line 273 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str213, ei_jisx0201}, + {-1}, {-1}, +#line 158 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str216, ei_iso8859_15}, +#line 259 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str217, ei_viscii}, + {-1}, +#line 80 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str219, ei_iso8859_4}, + {-1}, +#line 239 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str221, ei_pt154}, + {-1}, {-1}, +#line 148 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str224, ei_iso8859_14}, +#line 279 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str225, ei_jisx0208}, +#line 249 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str226, ei_cp1133}, +#line 261 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str227, ei_viscii}, + {-1}, +#line 303 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str229, ei_ksc5601}, + {-1}, +#line 24 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str231, ei_ucs2}, +#line 136 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str232, ei_iso8859_10}, + {-1}, +#line 243 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str234, ei_rk1048}, +#line 294 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str235, ei_gb2312}, +#line 61 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str236, ei_iso8859_1}, +#line 268 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str237, ei_iso646_jp}, +#line 135 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str238, ei_iso8859_10}, +#line 109 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str239, ei_iso8859_7}, +#line 77 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str240, ei_iso8859_3}, +#line 245 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str241, ei_rk1048}, +#line 69 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str242, ei_iso8859_2}, +#line 92 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str243, ei_iso8859_5}, +#line 127 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str244, ei_iso8859_9}, + {-1}, +#line 129 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str246, ei_iso8859_10}, +#line 74 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str247, ei_iso8859_3}, +#line 246 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str248, ei_rk1048}, + {-1}, +#line 169 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str250, ei_koi8_r}, +#line 333 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str251, ei_gb18030}, +#line 242 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str252, ei_pt154}, + {-1}, +#line 168 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str254, ei_koi8_r}, + {-1}, +#line 262 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str256, ei_tcvn}, + {-1}, +#line 289 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str258, ei_iso646_cn}, + {-1}, +#line 130 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str260, ei_iso8859_10}, +#line 177 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str261, ei_cp1251}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 296 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str268, ei_gb2312}, + {-1}, +#line 255 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str270, ei_tis620}, +#line 302 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str271, ei_ksc5601}, +#line 222 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str272, ei_mac_cyrillic}, + {-1}, {-1}, +#line 338 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str275, ei_hz}, + {-1}, +#line 299 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str277, ei_isoir165}, +#line 82 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str278, ei_iso8859_4}, + {-1}, {-1}, +#line 252 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str281, ei_tis620}, + {-1}, +#line 326 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str283, ei_euc_cn}, + {-1}, {-1}, {-1}, {-1}, +#line 253 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str288, ei_tis620}, + {-1}, {-1}, {-1}, {-1}, +#line 90 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str293, ei_iso8859_5}, +#line 211 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str294, ei_cp866}, + {-1}, {-1}, {-1}, +#line 14 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str298, ei_ascii}, +#line 200 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str299, ei_cp850}, +#line 257 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str300, ei_cp874}, + {-1}, +#line 241 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str302, ei_pt154}, + {-1}, {-1}, {-1}, +#line 112 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str306, ei_iso8859_7}, +#line 366 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str307, ei_local_char}, + {-1}, {-1}, +#line 354 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str310, ei_big5hkscs2008}, + {-1}, {-1}, +#line 203 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str313, ei_cp850}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 180 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str322, ei_cp1252}, +#line 35 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str323, ei_ucs4}, +#line 353 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str324, ei_big5hkscs2008}, + {-1}, {-1}, +#line 33 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str327, ei_ucs4}, + {-1}, {-1}, +#line 234 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str330, ei_armscii_8}, + {-1}, {-1}, {-1}, {-1}, +#line 236 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str335, ei_georgian_ps}, + {-1}, {-1}, +#line 85 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str338, ei_iso8859_4}, +#line 254 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str339, ei_tis620}, + {-1}, {-1}, +#line 365 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str342, ei_iso2022_kr}, +#line 215 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str343, ei_mac_roman}, + {-1}, +#line 142 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str345, ei_iso8859_13}, + {-1}, +#line 56 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str347, ei_iso8859_1}, + {-1}, {-1}, +#line 110 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str350, ei_iso8859_7}, + {-1}, {-1}, {-1}, {-1}, +#line 357 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str355, ei_euc_kr}, + {-1}, {-1}, +#line 38 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str358, ei_utf16}, +#line 260 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str359, ei_viscii}, +#line 364 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str360, ei_iso2022_kr}, + {-1}, +#line 19 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str362, ei_ascii}, +#line 23 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str363, ei_utf8}, +#line 41 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str364, ei_utf32}, + {-1}, {-1}, {-1}, {-1}, +#line 356 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str369, ei_euc_kr}, + {-1}, +#line 194 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str371, ei_cp1257}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 293 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str378, ei_iso646_cn}, + {-1}, {-1}, {-1}, +#line 304 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str382, ei_ksc5601}, +#line 12 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str383, ei_ascii}, +#line 101 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str384, ei_iso8859_6}, +#line 73 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str385, ei_iso8859_3}, +#line 30 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str386, ei_ucs2be}, +#line 89 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str387, ei_iso8859_5}, + {-1}, +#line 116 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str389, ei_iso8859_8}, +#line 29 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str390, ei_ucs2be}, +#line 228 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str391, ei_mac_thai}, +#line 230 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str392, ei_hp_roman8}, +#line 25 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str393, ei_ucs2}, + {-1}, {-1}, {-1}, {-1}, +#line 111 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str398, ei_iso8859_7}, + {-1}, {-1}, {-1}, +#line 143 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str402, ei_iso8859_13}, + {-1}, +#line 244 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str404, ei_rk1048}, +#line 176 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str405, ei_cp1251}, +#line 192 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str406, ei_cp1256}, +#line 183 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str407, ei_cp1253}, +#line 179 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str408, ei_cp1252}, +#line 189 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str409, ei_cp1255}, + {-1}, +#line 198 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str411, ei_cp1258}, +#line 297 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str412, ei_gb2312}, +#line 233 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str413, ei_nextstep}, + {-1}, +#line 123 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str415, ei_iso8859_9}, + {-1}, {-1}, {-1}, +#line 301 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str419, ei_ksc5601}, +#line 332 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str420, ei_cp936}, + {-1}, {-1}, +#line 113 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str423, ei_iso8859_7}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 81 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str434, ei_iso8859_4}, + {-1}, +#line 207 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str436, ei_cp862}, +#line 103 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str437, ei_iso8859_7}, + {-1}, {-1}, +#line 100 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str440, ei_iso8859_6}, +#line 34 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str441, ei_ucs4}, + {-1}, {-1}, {-1}, +#line 247 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str445, ei_mulelao}, +#line 108 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str446, ei_iso8859_7}, + {-1}, +#line 269 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str448, ei_iso646_jp}, + {-1}, {-1}, +#line 104 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str451, ei_iso8859_7}, + {-1}, +#line 263 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str453, ei_tcvn}, + {-1}, +#line 264 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str455, ei_tcvn}, +#line 186 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str456, ei_cp1254}, + {-1}, {-1}, +#line 305 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str459, ei_ksc5601}, + {-1}, +#line 235 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str461, ei_georgian_academy}, +#line 219 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str462, ei_mac_iceland}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 119 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str469, ei_iso8859_8}, + {-1}, {-1}, {-1}, +#line 291 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str473, ei_iso646_cn}, +#line 173 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str474, ei_cp1250}, +#line 280 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str475, ei_jisx0208}, + {-1}, +#line 97 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str477, ei_iso8859_6}, +#line 132 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str478, ei_iso8859_10}, + {-1}, {-1}, +#line 340 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str481, ei_euc_tw}, + {-1}, +#line 31 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str483, ei_ucs2le}, + {-1}, {-1}, {-1}, +#line 229 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str487, ei_hp_roman8}, +#line 20 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str488, ei_ascii}, + {-1}, {-1}, {-1}, +#line 170 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str492, ei_koi8_u}, +#line 28 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str493, ei_ucs2be}, + {-1}, +#line 339 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str495, ei_euc_tw}, +#line 217 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str496, ei_mac_roman}, +#line 26 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str497, ei_ucs2}, +#line 281 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str498, ei_jisx0208}, + {-1}, {-1}, +#line 47 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str501, ei_ucs2internal}, + {-1}, +#line 15 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str503, ei_ascii}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 270 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str510, ei_iso646_jp}, +#line 18 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str511, ei_ascii}, + {-1}, {-1}, {-1}, +#line 328 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str515, ei_euc_cn}, +#line 17 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str516, ei_ascii}, + {-1}, +#line 174 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str518, ei_cp1250}, + {-1}, {-1}, +#line 202 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str521, ei_cp850}, + {-1}, +#line 232 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str523, ei_hp_roman8}, + {-1}, +#line 214 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str525, ei_mac_roman}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 37 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str531, ei_ucs4le}, + {-1}, {-1}, {-1}, {-1}, +#line 98 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str536, ei_iso8859_6}, + {-1}, {-1}, {-1}, +#line 32 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str540, ei_ucs2le}, + {-1}, {-1}, +#line 367 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str543, ei_local_wchar_t}, +#line 55 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str544, ei_iso8859_1}, +#line 96 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str545, ei_iso8859_6}, +#line 106 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str546, ei_iso8859_7}, +#line 65 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str547, ei_iso8859_2}, + {-1}, +#line 49 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str549, ei_ucs4internal}, + {-1}, {-1}, {-1}, {-1}, +#line 288 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str554, ei_jisx0212}, + {-1}, +#line 358 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str556, ei_euc_kr}, +#line 46 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str557, ei_utf7}, + {-1}, {-1}, {-1}, +#line 99 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str561, ei_iso8859_6}, + {-1}, +#line 45 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str563, ei_utf7}, + {-1}, {-1}, {-1}, +#line 266 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str567, ei_iso646_jp}, + {-1}, +#line 171 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str569, ei_koi8_ru}, + {-1}, {-1}, +#line 195 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str572, ei_cp1257}, + {-1}, {-1}, +#line 322 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str575, ei_iso2022_jp2}, + {-1}, {-1}, {-1}, +#line 187 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str579, ei_cp1254}, + {-1}, {-1}, {-1}, +#line 220 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str583, ei_mac_croatian}, +#line 351 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str584, ei_big5hkscs2001}, +#line 267 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str585, ei_iso646_jp}, +#line 278 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str586, ei_jisx0208}, + {-1}, {-1}, {-1}, +#line 355 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str590, ei_big5hkscs2008}, +#line 320 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str591, ei_iso2022_jp1}, + {-1}, {-1}, +#line 321 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str594, ei_iso2022_jp2}, + {-1}, {-1}, {-1}, {-1}, +#line 312 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str599, ei_sjis}, + {-1}, {-1}, {-1}, +#line 350 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str603, ei_big5hkscs1999}, +#line 27 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str604, ei_ucs2be}, + {-1}, +#line 224 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str606, ei_mac_greek}, + {-1}, {-1}, {-1}, {-1}, +#line 319 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str611, ei_iso2022_jp}, +#line 40 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str612, ei_utf16le}, +#line 311 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str613, ei_sjis}, + {-1}, +#line 184 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str615, ei_cp1253}, +#line 43 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str616, ei_utf32le}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 307 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str624, ei_euc_jp}, +#line 190 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str625, ei_cp1255}, + {-1}, {-1}, {-1}, +#line 318 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str629, ei_iso2022_jp}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 352 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str635, ei_big5hkscs2004}, + {-1}, {-1}, +#line 306 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str638, ei_euc_jp}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 227 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str648, ei_mac_arabic}, + {-1}, {-1}, {-1}, +#line 36 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str652, ei_ucs4be}, + {-1}, +#line 48 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str654, ei_ucs2swapped}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 283 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str660, ei_jisx0212}, + {-1}, +#line 225 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str662, ei_mac_turkish}, + {-1}, {-1}, {-1}, +#line 315 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str666, ei_sjis}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 258 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str672, ei_cp874}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 341 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str682, ei_euc_tw}, + {-1}, {-1}, +#line 44 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str685, ei_utf7}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 359 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str696, ei_euc_kr}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 50 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str702, ei_ucs4swapped}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 105 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str711, ei_iso8859_7}, + {-1}, {-1}, {-1}, +#line 346 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str715, ei_ces_big5}, + {-1}, +#line 265 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str717, ei_tcvn}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 271 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str723, ei_jisx0201}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 345 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str729, ei_ces_big5}, + {-1}, {-1}, +#line 118 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str732, ei_iso8859_8}, +#line 39 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str733, ei_utf16be}, + {-1}, +#line 275 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str735, ei_jisx0208}, + {-1}, +#line 42 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str737, ei_utf32be}, + {-1}, {-1}, {-1}, +#line 272 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str741, ei_jisx0201}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 285 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str748, ei_jisx0212}, + {-1}, {-1}, {-1}, +#line 282 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str752, ei_jisx0208}, +#line 276 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str753, ei_jisx0208}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 193 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str771, ei_cp1256}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 218 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str797, ei_mac_centraleurope}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 274 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str803, ei_jisx0201}, +#line 314 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str804, ei_sjis}, + {-1}, {-1}, +#line 221 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str807, ei_mac_romania}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 277 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str820, ei_jisx0208}, + {-1}, +#line 342 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str822, ei_euc_tw}, + {-1}, {-1}, {-1}, +#line 196 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str826, ei_cp1257}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 308 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str846, ei_euc_jp}, + {-1}, {-1}, +#line 284 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str849, ei_jisx0212}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 309 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str874, ei_euc_jp}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 362 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str885, ei_johab}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 52 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str891, ei_java}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 223 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str898, ei_mac_ukraine}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 310 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str965, ei_euc_jp}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 226 "lib/aliases_sysaix.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str989, ei_mac_hebrew} + }; + +#ifdef __GNUC__ +__inline +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct alias * +aliases_lookup (register const char *str, register unsigned int len) +{ + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = aliases_hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int o = aliases[key].name; + if (o >= 0) + { + register const char *s = o + stringpool; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &aliases[key]; + } + } + } + return 0; +} diff --git a/libs/libiconv/lib/aliases_syshpux.gperf b/libs/libiconv/lib/aliases_syshpux.gperf new file mode 100644 index 00000000..0f5c214f --- /dev/null +++ b/libs/libiconv/lib/aliases_syshpux.gperf @@ -0,0 +1,368 @@ +struct alias { int name; unsigned int encoding_index; }; +%struct-type +%language=ANSI-C +%define hash-function-name aliases_hash +%define lookup-function-name aliases_lookup +%7bit +%readonly-tables +%global-table +%define word-array-name aliases +%pic +%% +US-ASCII, ei_ascii +ASCII, ei_ascii +ISO646-US, ei_ascii +ISO_646.IRV:1991, ei_ascii +ISO-IR-6, ei_ascii +ANSI_X3.4-1968, ei_ascii +ANSI_X3.4-1986, ei_ascii +CP367, ei_ascii +IBM367, ei_ascii +US, ei_ascii +CSASCII, ei_ascii +UTF-8, ei_utf8 +UTF8, ei_utf8 +UCS-2, ei_ucs2 +ISO-10646-UCS-2, ei_ucs2 +CSUNICODE, ei_ucs2 +UCS-2BE, ei_ucs2be +UNICODEBIG, ei_ucs2be +UNICODE-1-1, ei_ucs2be +CSUNICODE11, ei_ucs2be +UCS-2LE, ei_ucs2le +UNICODELITTLE, ei_ucs2le +UCS-4, ei_ucs4 +ISO-10646-UCS-4, ei_ucs4 +CSUCS4, ei_ucs4 +UCS-4BE, ei_ucs4be +UCS-4LE, ei_ucs4le +UTF-16, ei_utf16 +UTF-16BE, ei_utf16be +UTF-16LE, ei_utf16le +UTF-32, ei_utf32 +UTF-32BE, ei_utf32be +UTF-32LE, ei_utf32le +UTF-7, ei_utf7 +UNICODE-1-1-UTF-7, ei_utf7 +CSUNICODE11UTF7, ei_utf7 +UCS-2-INTERNAL, ei_ucs2internal +UCS-2-SWAPPED, ei_ucs2swapped +UCS-4-INTERNAL, ei_ucs4internal +UCS-4-SWAPPED, ei_ucs4swapped +C99, ei_c99 +JAVA, ei_java +ISO-8859-1, ei_iso8859_1 +ISO_8859-1, ei_iso8859_1 +ISO_8859-1:1987, ei_iso8859_1 +ISO-IR-100, ei_iso8859_1 +CP819, ei_iso8859_1 +IBM819, ei_iso8859_1 +LATIN1, ei_iso8859_1 +L1, ei_iso8859_1 +CSISOLATIN1, ei_iso8859_1 +ISO8859-1, ei_iso8859_1 +ISO88591, ei_iso8859_1 +ISO-8859-2, ei_iso8859_2 +ISO_8859-2, ei_iso8859_2 +ISO_8859-2:1987, ei_iso8859_2 +ISO-IR-101, ei_iso8859_2 +LATIN2, ei_iso8859_2 +L2, ei_iso8859_2 +CSISOLATIN2, ei_iso8859_2 +ISO8859-2, ei_iso8859_2 +ISO88592, ei_iso8859_2 +ISO-8859-3, ei_iso8859_3 +ISO_8859-3, ei_iso8859_3 +ISO_8859-3:1988, ei_iso8859_3 +ISO-IR-109, ei_iso8859_3 +LATIN3, ei_iso8859_3 +L3, ei_iso8859_3 +CSISOLATIN3, ei_iso8859_3 +ISO8859-3, ei_iso8859_3 +ISO-8859-4, ei_iso8859_4 +ISO_8859-4, ei_iso8859_4 +ISO_8859-4:1988, ei_iso8859_4 +ISO-IR-110, ei_iso8859_4 +LATIN4, ei_iso8859_4 +L4, ei_iso8859_4 +CSISOLATIN4, ei_iso8859_4 +ISO8859-4, ei_iso8859_4 +ISO-8859-5, ei_iso8859_5 +ISO_8859-5, ei_iso8859_5 +ISO_8859-5:1988, ei_iso8859_5 +ISO-IR-144, ei_iso8859_5 +CYRILLIC, ei_iso8859_5 +CSISOLATINCYRILLIC, ei_iso8859_5 +ISO8859-5, ei_iso8859_5 +ISO88595, ei_iso8859_5 +ISO-8859-6, ei_iso8859_6 +ISO_8859-6, ei_iso8859_6 +ISO_8859-6:1987, ei_iso8859_6 +ISO-IR-127, ei_iso8859_6 +ECMA-114, ei_iso8859_6 +ASMO-708, ei_iso8859_6 +ARABIC, ei_iso8859_6 +CSISOLATINARABIC, ei_iso8859_6 +ISO8859-6, ei_iso8859_6 +ISO88596, ei_iso8859_6 +ISO-8859-7, ei_iso8859_7 +ISO_8859-7, ei_iso8859_7 +ISO_8859-7:1987, ei_iso8859_7 +ISO_8859-7:2003, ei_iso8859_7 +ISO-IR-126, ei_iso8859_7 +ECMA-118, ei_iso8859_7 +ELOT_928, ei_iso8859_7 +GREEK8, ei_iso8859_7 +GREEK, ei_iso8859_7 +CSISOLATINGREEK, ei_iso8859_7 +ISO8859-7, ei_iso8859_7 +ISO88597, ei_iso8859_7 +ISO-8859-8, ei_iso8859_8 +ISO_8859-8, ei_iso8859_8 +ISO_8859-8:1988, ei_iso8859_8 +ISO-IR-138, ei_iso8859_8 +HEBREW, ei_iso8859_8 +CSISOLATINHEBREW, ei_iso8859_8 +ISO8859-8, ei_iso8859_8 +ISO88598, ei_iso8859_8 +ISO-8859-9, ei_iso8859_9 +ISO_8859-9, ei_iso8859_9 +ISO_8859-9:1989, ei_iso8859_9 +ISO-IR-148, ei_iso8859_9 +LATIN5, ei_iso8859_9 +L5, ei_iso8859_9 +CSISOLATIN5, ei_iso8859_9 +ISO8859-9, ei_iso8859_9 +ISO88599, ei_iso8859_9 +ISO-8859-10, ei_iso8859_10 +ISO_8859-10, ei_iso8859_10 +ISO_8859-10:1992, ei_iso8859_10 +ISO-IR-157, ei_iso8859_10 +LATIN6, ei_iso8859_10 +L6, ei_iso8859_10 +CSISOLATIN6, ei_iso8859_10 +ISO8859-10, ei_iso8859_10 +ISO-8859-11, ei_iso8859_11 +ISO_8859-11, ei_iso8859_11 +ISO8859-11, ei_iso8859_11 +ISO-8859-13, ei_iso8859_13 +ISO_8859-13, ei_iso8859_13 +ISO-IR-179, ei_iso8859_13 +LATIN7, ei_iso8859_13 +L7, ei_iso8859_13 +ISO8859-13, ei_iso8859_13 +ISO-8859-14, ei_iso8859_14 +ISO_8859-14, ei_iso8859_14 +ISO_8859-14:1998, ei_iso8859_14 +ISO-IR-199, ei_iso8859_14 +LATIN8, ei_iso8859_14 +L8, ei_iso8859_14 +ISO-CELTIC, ei_iso8859_14 +ISO8859-14, ei_iso8859_14 +ISO-8859-15, ei_iso8859_15 +ISO_8859-15, ei_iso8859_15 +ISO_8859-15:1998, ei_iso8859_15 +ISO-IR-203, ei_iso8859_15 +LATIN-9, ei_iso8859_15 +ISO8859-15, ei_iso8859_15 +ISO885915, ei_iso8859_15 +ISO-8859-16, ei_iso8859_16 +ISO_8859-16, ei_iso8859_16 +ISO_8859-16:2001, ei_iso8859_16 +ISO-IR-226, ei_iso8859_16 +LATIN10, ei_iso8859_16 +L10, ei_iso8859_16 +ISO8859-16, ei_iso8859_16 +KOI8-R, ei_koi8_r +CSKOI8R, ei_koi8_r +KOI8-U, ei_koi8_u +KOI8-RU, ei_koi8_ru +CP1250, ei_cp1250 +WINDOWS-1250, ei_cp1250 +MS-EE, ei_cp1250 +CP1251, ei_cp1251 +WINDOWS-1251, ei_cp1251 +MS-CYRL, ei_cp1251 +CP1252, ei_cp1252 +WINDOWS-1252, ei_cp1252 +MS-ANSI, ei_cp1252 +CP1253, ei_cp1253 +WINDOWS-1253, ei_cp1253 +MS-GREEK, ei_cp1253 +CP1254, ei_cp1254 +WINDOWS-1254, ei_cp1254 +MS-TURK, ei_cp1254 +CP1255, ei_cp1255 +WINDOWS-1255, ei_cp1255 +MS-HEBR, ei_cp1255 +CP1256, ei_cp1256 +WINDOWS-1256, ei_cp1256 +MS-ARAB, ei_cp1256 +CP1257, ei_cp1257 +WINDOWS-1257, ei_cp1257 +WINBALTRIM, ei_cp1257 +CP1258, ei_cp1258 +WINDOWS-1258, ei_cp1258 +CP850, ei_cp850 +IBM850, ei_cp850 +850, ei_cp850 +CSPC850MULTILINGUAL, ei_cp850 +CP862, ei_cp862 +IBM862, ei_cp862 +862, ei_cp862 +CSPC862LATINHEBREW, ei_cp862 +CP866, ei_cp866 +IBM866, ei_cp866 +866, ei_cp866 +CSIBM866, ei_cp866 +CP1131, ei_cp1131 +MACROMAN, ei_mac_roman +MACINTOSH, ei_mac_roman +MAC, ei_mac_roman +CSMACINTOSH, ei_mac_roman +MACCENTRALEUROPE, ei_mac_centraleurope +MACICELAND, ei_mac_iceland +MACCROATIAN, ei_mac_croatian +MACROMANIA, ei_mac_romania +MACCYRILLIC, ei_mac_cyrillic +MACUKRAINE, ei_mac_ukraine +MACGREEK, ei_mac_greek +MACTURKISH, ei_mac_turkish +MACHEBREW, ei_mac_hebrew +MACARABIC, ei_mac_arabic +MACTHAI, ei_mac_thai +HP-ROMAN8, ei_hp_roman8 +ROMAN8, ei_hp_roman8 +R8, ei_hp_roman8 +CSHPROMAN8, ei_hp_roman8 +NEXTSTEP, ei_nextstep +ARMSCII-8, ei_armscii_8 +GEORGIAN-ACADEMY, ei_georgian_academy +GEORGIAN-PS, ei_georgian_ps +KOI8-T, ei_koi8_t +PT154, ei_pt154 +PTCP154, ei_pt154 +CP154, ei_pt154 +CYRILLIC-ASIAN, ei_pt154 +CSPTCP154, ei_pt154 +RK1048, ei_rk1048 +STRK1048-2002, ei_rk1048 +KZ-1048, ei_rk1048 +CSKZ1048, ei_rk1048 +MULELAO-1, ei_mulelao +CP1133, ei_cp1133 +IBM-CP1133, ei_cp1133 +TIS-620, ei_tis620 +TIS620, ei_tis620 +TIS620-0, ei_tis620 +TIS620.2529-1, ei_tis620 +TIS620.2533-0, ei_tis620 +TIS620.2533-1, ei_tis620 +ISO-IR-166, ei_tis620 +CP874, ei_cp874 +WINDOWS-874, ei_cp874 +VISCII, ei_viscii +VISCII1.1-1, ei_viscii +CSVISCII, ei_viscii +TCVN, ei_tcvn +TCVN-5712, ei_tcvn +TCVN5712-1, ei_tcvn +TCVN5712-1:1993, ei_tcvn +JIS_C6220-1969-RO, ei_iso646_jp +ISO646-JP, ei_iso646_jp +ISO-IR-14, ei_iso646_jp +JP, ei_iso646_jp +CSISO14JISC6220RO, ei_iso646_jp +JIS_X0201, ei_jisx0201 +JISX0201-1976, ei_jisx0201 +X0201, ei_jisx0201 +CSHALFWIDTHKATAKANA, ei_jisx0201 +JIS_X0208, ei_jisx0208 +JIS_X0208-1983, ei_jisx0208 +JIS_X0208-1990, ei_jisx0208 +JIS0208, ei_jisx0208 +X0208, ei_jisx0208 +ISO-IR-87, ei_jisx0208 +JIS_C6226-1983, ei_jisx0208 +CSISO87JISX0208, ei_jisx0208 +JIS_X0212, ei_jisx0212 +JIS_X0212.1990-0, ei_jisx0212 +JIS_X0212-1990, ei_jisx0212 +X0212, ei_jisx0212 +ISO-IR-159, ei_jisx0212 +CSISO159JISX02121990, ei_jisx0212 +GB_1988-80, ei_iso646_cn +ISO646-CN, ei_iso646_cn +ISO-IR-57, ei_iso646_cn +CN, ei_iso646_cn +CSISO57GB1988, ei_iso646_cn +GB_2312-80, ei_gb2312 +ISO-IR-58, ei_gb2312 +CSISO58GB231280, ei_gb2312 +CHINESE, ei_gb2312 +ISO-IR-165, ei_isoir165 +CN-GB-ISOIR165, ei_isoir165 +KSC_5601, ei_ksc5601 +KS_C_5601-1987, ei_ksc5601 +KS_C_5601-1989, ei_ksc5601 +ISO-IR-149, ei_ksc5601 +CSKSC56011987, ei_ksc5601 +KOREAN, ei_ksc5601 +EUC-JP, ei_euc_jp +EUCJP, ei_euc_jp +EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE, ei_euc_jp +CSEUCPKDFMTJAPANESE, ei_euc_jp +SHIFT_JIS, ei_sjis +SHIFT-JIS, ei_sjis +SJIS, ei_sjis +MS_KANJI, ei_sjis +CSSHIFTJIS, ei_sjis +CP932, ei_cp932 +ISO-2022-JP, ei_iso2022_jp +CSISO2022JP, ei_iso2022_jp +ISO-2022-JP-1, ei_iso2022_jp1 +ISO-2022-JP-2, ei_iso2022_jp2 +CSISO2022JP2, ei_iso2022_jp2 +EUC-CN, ei_euc_cn +EUCCN, ei_euc_cn +GB2312, ei_euc_cn +CN-GB, ei_euc_cn +CSGB2312, ei_euc_cn +HP15CN, ei_euc_cn +GBK, ei_ces_gbk +CP936, ei_cp936 +MS936, ei_cp936 +WINDOWS-936, ei_cp936 +GB18030, ei_gb18030 +ISO-2022-CN, ei_iso2022_cn +CSISO2022CN, ei_iso2022_cn +ISO-2022-CN-EXT, ei_iso2022_cn_ext +HZ, ei_hz +HZ-GB-2312, ei_hz +EUC-TW, ei_euc_tw +EUCTW, ei_euc_tw +CSEUCTW, ei_euc_tw +BIG5, ei_ces_big5 +BIG-5, ei_ces_big5 +BIG-FIVE, ei_ces_big5 +BIGFIVE, ei_ces_big5 +CN-BIG5, ei_ces_big5 +CSBIG5, ei_ces_big5 +CP950, ei_cp950 +BIG5-HKSCS:1999, ei_big5hkscs1999 +BIG5-HKSCS:2001, ei_big5hkscs2001 +BIG5-HKSCS:2004, ei_big5hkscs2004 +BIG5-HKSCS, ei_big5hkscs2008 +BIG5HKSCS, ei_big5hkscs2008 +BIG5-HKSCS:2008, ei_big5hkscs2008 +EUC-KR, ei_euc_kr +EUCKR, ei_euc_kr +CSEUCKR, ei_euc_kr +CP949, ei_cp949 +UHC, ei_cp949 +JOHAB, ei_johab +CP1361, ei_johab +ISO-2022-KR, ei_iso2022_kr +CSISO2022KR, ei_iso2022_kr +CHAR, ei_local_char +WCHAR_T, ei_local_wchar_t diff --git a/libs/libiconv/lib/aliases_syshpux.h b/libs/libiconv/lib/aliases_syshpux.h new file mode 100644 index 00000000..57545efa --- /dev/null +++ b/libs/libiconv/lib/aliases_syshpux.h @@ -0,0 +1,1773 @@ +/* ANSI-C code produced by gperf version 3.0.4 */ +/* Command-line: gperf -m 10 lib/aliases_syshpux.gperf */ +/* Computed positions: -k'1,3-11,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "lib/aliases_syshpux.gperf" +struct alias { int name; unsigned int encoding_index; }; + +#define TOTAL_KEYWORDS 357 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 45 +#define MIN_HASH_VALUE 9 +#define MAX_HASH_VALUE 1038 +/* maximum key range = 1030, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +aliases_hash (register const char *str, register unsigned int len) +{ + static const unsigned short asso_values[] = + { + 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, + 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, + 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, + 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, + 1039, 1039, 1039, 1039, 1039, 0, 112, 1039, 57, 2, + 0, 20, 51, 8, 5, 49, 13, 16, 335, 1039, + 1039, 1039, 1039, 1039, 1039, 13, 149, 1, 6, 10, + 55, 139, 10, 0, 328, 86, 210, 147, 6, 0, + 73, 1039, 120, 6, 17, 282, 238, 172, 274, 2, + 0, 1039, 1039, 1039, 1039, 34, 1039, 1039, 1039, 1039, + 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, + 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039, + 1039, 1039, 1039, 1039, 1039, 1039, 1039, 1039 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[10]]; + /*FALLTHROUGH*/ + case 10: + hval += asso_values[(unsigned char)str[9]]; + /*FALLTHROUGH*/ + case 9: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +struct stringpool_t + { + char stringpool_str9[sizeof("CN")]; + char stringpool_str12[sizeof("HZ")]; + char stringpool_str16[sizeof("862")]; + char stringpool_str17[sizeof("CP1252")]; + char stringpool_str19[sizeof("ASCII")]; + char stringpool_str21[sizeof("CP1251")]; + char stringpool_str22[sizeof("SJIS")]; + char stringpool_str24[sizeof("CP862")]; + char stringpool_str26[sizeof("866")]; + char stringpool_str27[sizeof("CP1256")]; + char stringpool_str28[sizeof("CSASCII")]; + char stringpool_str29[sizeof("EUCCN")]; + char stringpool_str30[sizeof("EUC-CN")]; + char stringpool_str33[sizeof("CP1255")]; + char stringpool_str34[sizeof("CP866")]; + char stringpool_str35[sizeof("CP1131")]; + char stringpool_str36[sizeof("C99")]; + char stringpool_str38[sizeof("CP1361")]; + char stringpool_str39[sizeof("HP15CN")]; + char stringpool_str42[sizeof("CP932")]; + char stringpool_str43[sizeof("CP1258")]; + char stringpool_str50[sizeof("CHINESE")]; + char stringpool_str52[sizeof("CP936")]; + char stringpool_str53[sizeof("CP819")]; + char stringpool_str57[sizeof("CP1253")]; + char stringpool_str58[sizeof("ISO88592")]; + char stringpool_str59[sizeof("ISO8859-2")]; + char stringpool_str60[sizeof("ISO-8859-2")]; + char stringpool_str62[sizeof("ISO88591")]; + char stringpool_str63[sizeof("ISO8859-1")]; + char stringpool_str64[sizeof("ISO-8859-1")]; + char stringpool_str66[sizeof("ISO8859-11")]; + char stringpool_str67[sizeof("ISO-8859-11")]; + char stringpool_str68[sizeof("ISO88596")]; + char stringpool_str69[sizeof("ISO8859-6")]; + char stringpool_str70[sizeof("ISO-8859-6")]; + char stringpool_str71[sizeof("CP1133")]; + char stringpool_str72[sizeof("ISO8859-16")]; + char stringpool_str73[sizeof("ISO-8859-16")]; + char stringpool_str74[sizeof("ISO88595")]; + char stringpool_str75[sizeof("ISO8859-5")]; + char stringpool_str76[sizeof("ISO-8859-5")]; + char stringpool_str77[sizeof("ISO885915")]; + char stringpool_str78[sizeof("ISO8859-15")]; + char stringpool_str79[sizeof("ISO-8859-15")]; + char stringpool_str81[sizeof("ISO-2022-CN")]; + char stringpool_str83[sizeof("ISO646-CN")]; + char stringpool_str84[sizeof("ISO88598")]; + char stringpool_str85[sizeof("ISO8859-8")]; + char stringpool_str86[sizeof("ISO-8859-8")]; + char stringpool_str88[sizeof("CSISO2022CN")]; + char stringpool_str90[sizeof("ISO88599")]; + char stringpool_str91[sizeof("ISO8859-9")]; + char stringpool_str92[sizeof("ISO-8859-9")]; + char stringpool_str94[sizeof("ISO_8859-2")]; + char stringpool_str96[sizeof("ISO-2022-CN-EXT")]; + char stringpool_str98[sizeof("ISO_8859-1")]; + char stringpool_str99[sizeof("ISO8859-3")]; + char stringpool_str100[sizeof("ISO-8859-3")]; + char stringpool_str101[sizeof("ISO_8859-11")]; + char stringpool_str102[sizeof("ISO8859-13")]; + char stringpool_str103[sizeof("ISO-8859-13")]; + char stringpool_str104[sizeof("ISO_8859-6")]; + char stringpool_str105[sizeof("CP949")]; + char stringpool_str107[sizeof("ISO_8859-16")]; + char stringpool_str109[sizeof("ISO_8859-16:2001")]; + char stringpool_str110[sizeof("ISO_8859-5")]; + char stringpool_str111[sizeof("ELOT_928")]; + char stringpool_str113[sizeof("ISO_8859-15")]; + char stringpool_str115[sizeof("CP1257")]; + char stringpool_str118[sizeof("CP154")]; + char stringpool_str119[sizeof("CP1254")]; + char stringpool_str120[sizeof("ISO_8859-8")]; + char stringpool_str123[sizeof("ISO_8859-15:1998")]; + char stringpool_str126[sizeof("ISO_8859-9")]; + char stringpool_str129[sizeof("CP367")]; + char stringpool_str130[sizeof("850")]; + char stringpool_str131[sizeof("CP1250")]; + char stringpool_str134[sizeof("ISO_8859-3")]; + char stringpool_str135[sizeof("R8")]; + char stringpool_str137[sizeof("ISO_8859-13")]; + char stringpool_str138[sizeof("ISO-IR-6")]; + char stringpool_str139[sizeof("KOI8-T")]; + char stringpool_str140[sizeof("ISO-IR-226")]; + char stringpool_str141[sizeof("CP850")]; + char stringpool_str142[sizeof("ISO-IR-126")]; + char stringpool_str144[sizeof("CP950")]; + char stringpool_str147[sizeof("ISO-IR-166")]; + char stringpool_str148[sizeof("TIS620")]; + char stringpool_str149[sizeof("TIS-620")]; + char stringpool_str152[sizeof("MAC")]; + char stringpool_str153[sizeof("ISO-IR-165")]; + char stringpool_str156[sizeof("ISO88597")]; + char stringpool_str157[sizeof("ISO8859-7")]; + char stringpool_str158[sizeof("ISO-8859-7")]; + char stringpool_str159[sizeof("ISO_8859-10:1992")]; + char stringpool_str161[sizeof("ISO8859-4")]; + char stringpool_str162[sizeof("ISO-8859-4")]; + char stringpool_str163[sizeof("ISO-IR-58")]; + char stringpool_str164[sizeof("ISO8859-14")]; + char stringpool_str165[sizeof("ISO-8859-14")]; + char stringpool_str166[sizeof("ISO_8859-14:1998")]; + char stringpool_str167[sizeof("GB2312")]; + char stringpool_str170[sizeof("CP874")]; + char stringpool_str171[sizeof("IBM862")]; + char stringpool_str172[sizeof("ISO-IR-159")]; + char stringpool_str176[sizeof("ISO8859-10")]; + char stringpool_str177[sizeof("ISO-8859-10")]; + char stringpool_str178[sizeof("ISO-IR-138")]; + char stringpool_str179[sizeof("MS-ANSI")]; + char stringpool_str180[sizeof("ISO-IR-199")]; + char stringpool_str181[sizeof("IBM866")]; + char stringpool_str182[sizeof("MS-EE")]; + char stringpool_str183[sizeof("ARABIC")]; + char stringpool_str190[sizeof("PT154")]; + char stringpool_str192[sizeof("ISO_8859-7")]; + char stringpool_str193[sizeof("ISO-IR-101")]; + char stringpool_str195[sizeof("MACTHAI")]; + char stringpool_str196[sizeof("ISO_8859-4")]; + char stringpool_str198[sizeof("MS936")]; + char stringpool_str199[sizeof("ISO_8859-14")]; + char stringpool_str200[sizeof("IBM819")]; + char stringpool_str202[sizeof("ARMSCII-8")]; + char stringpool_str203[sizeof("KSC_5601")]; + char stringpool_str206[sizeof("MACINTOSH")]; + char stringpool_str207[sizeof("TIS620-0")]; + char stringpool_str208[sizeof("ECMA-118")]; + char stringpool_str209[sizeof("ISO-IR-148")]; + char stringpool_str211[sizeof("ISO_8859-10")]; + char stringpool_str212[sizeof("L2")]; + char stringpool_str213[sizeof("ISO-IR-179")]; + char stringpool_str214[sizeof("L1")]; + char stringpool_str215[sizeof("ISO-IR-149")]; + char stringpool_str217[sizeof("L6")]; + char stringpool_str220[sizeof("L5")]; + char stringpool_str221[sizeof("ISO-IR-109")]; + char stringpool_str222[sizeof("CSMACINTOSH")]; + char stringpool_str225[sizeof("L8")]; + char stringpool_str227[sizeof("ISO-IR-203")]; + char stringpool_str229[sizeof("KZ-1048")]; + char stringpool_str230[sizeof("ISO-IR-127")]; + char stringpool_str231[sizeof("CSKZ1048")]; + char stringpool_str232[sizeof("L3")]; + char stringpool_str233[sizeof("ISO-IR-14")]; + char stringpool_str235[sizeof("ISO-IR-57")]; + char stringpool_str236[sizeof("TIS620.2529-1")]; + char stringpool_str238[sizeof("ISO-IR-157")]; + char stringpool_str239[sizeof("LATIN2")]; + char stringpool_str240[sizeof("ISO-IR-87")]; + char stringpool_str243[sizeof("LATIN1")]; + char stringpool_str246[sizeof("CSKSC56011987")]; + char stringpool_str247[sizeof("KOREAN")]; + char stringpool_str248[sizeof("ISO-IR-110")]; + char stringpool_str249[sizeof("LATIN6")]; + char stringpool_str250[sizeof("ISO-CELTIC")]; + char stringpool_str251[sizeof("VISCII")]; + char stringpool_str254[sizeof("CSVISCII")]; + char stringpool_str255[sizeof("LATIN5")]; + char stringpool_str258[sizeof("CHAR")]; + char stringpool_str259[sizeof("KS_C_5601-1989")]; + char stringpool_str260[sizeof("TIS620.2533-1")]; + char stringpool_str261[sizeof("L7")]; + char stringpool_str262[sizeof("RK1048")]; + char stringpool_str263[sizeof("L4")]; + char stringpool_str264[sizeof("CSISOLATIN2")]; + char stringpool_str265[sizeof("LATIN8")]; + char stringpool_str266[sizeof("PTCP154")]; + char stringpool_str268[sizeof("CSISOLATIN1")]; + char stringpool_str271[sizeof("TCVN")]; + char stringpool_str272[sizeof("LATIN-9")]; + char stringpool_str273[sizeof("CSISOLATINCYRILLIC")]; + char stringpool_str274[sizeof("CSISOLATIN6")]; + char stringpool_str276[sizeof("IBM367")]; + char stringpool_str277[sizeof("GREEK8")]; + char stringpool_str279[sizeof("LATIN3")]; + char stringpool_str280[sizeof("CSISOLATIN5")]; + char stringpool_str281[sizeof("X0212")]; + char stringpool_str283[sizeof("CSISOLATINARABIC")]; + char stringpool_str284[sizeof("ECMA-114")]; + char stringpool_str285[sizeof("ISO-IR-144")]; + char stringpool_str286[sizeof("CSPTCP154")]; + char stringpool_str287[sizeof("UHC")]; + char stringpool_str288[sizeof("IBM850")]; + char stringpool_str290[sizeof("US")]; + char stringpool_str292[sizeof("KS_C_5601-1987")]; + char stringpool_str293[sizeof("UCS-2")]; + char stringpool_str295[sizeof("IBM-CP1133")]; + char stringpool_str300[sizeof("ASMO-708")]; + char stringpool_str303[sizeof("ISO-IR-100")]; + char stringpool_str304[sizeof("CSISOLATIN3")]; + char stringpool_str308[sizeof("BIG5")]; + char stringpool_str309[sizeof("BIG-5")]; + char stringpool_str310[sizeof("US-ASCII")]; + char stringpool_str311[sizeof("CSBIG5")]; + char stringpool_str312[sizeof("CN-BIG5")]; + char stringpool_str314[sizeof("GBK")]; + char stringpool_str315[sizeof("TIS620.2533-0")]; + char stringpool_str316[sizeof("UNICODE-1-1")]; + char stringpool_str318[sizeof("ROMAN8")]; + char stringpool_str319[sizeof("CSGB2312")]; + char stringpool_str323[sizeof("CSUNICODE11")]; + char stringpool_str325[sizeof("CSUNICODE")]; + char stringpool_str327[sizeof("L10")]; + char stringpool_str329[sizeof("TCVN-5712")]; + char stringpool_str330[sizeof("HZ-GB-2312")]; + char stringpool_str331[sizeof("HP-ROMAN8")]; + char stringpool_str332[sizeof("GB_2312-80")]; + char stringpool_str333[sizeof("CSIBM866")]; + char stringpool_str334[sizeof("TCVN5712-1")]; + char stringpool_str335[sizeof("MACCROATIAN")]; + char stringpool_str336[sizeof("GREEK")]; + char stringpool_str337[sizeof("LATIN7")]; + char stringpool_str340[sizeof("X0201")]; + char stringpool_str341[sizeof("LATIN4")]; + char stringpool_str342[sizeof("EUCKR")]; + char stringpool_str343[sizeof("EUC-KR")]; + char stringpool_str345[sizeof("KOI8-R")]; + char stringpool_str347[sizeof("CSKOI8R")]; + char stringpool_str352[sizeof("GB18030")]; + char stringpool_str354[sizeof("GB_1988-80")]; + char stringpool_str355[sizeof("UTF-16")]; + char stringpool_str356[sizeof("LATIN10")]; + char stringpool_str362[sizeof("X0208")]; + char stringpool_str363[sizeof("UTF-32")]; + char stringpool_str364[sizeof("ISO646-US")]; + char stringpool_str366[sizeof("CSISOLATIN4")]; + char stringpool_str367[sizeof("UTF8")]; + char stringpool_str368[sizeof("UTF-8")]; + char stringpool_str369[sizeof("UNICODE-1-1-UTF-7")]; + char stringpool_str374[sizeof("CSUNICODE11UTF7")]; + char stringpool_str376[sizeof("VISCII1.1-1")]; + char stringpool_str377[sizeof("EUCTW")]; + char stringpool_str378[sizeof("EUC-TW")]; + char stringpool_str384[sizeof("WINDOWS-1252")]; + char stringpool_str386[sizeof("WINDOWS-1251")]; + char stringpool_str389[sizeof("WINDOWS-1256")]; + char stringpool_str390[sizeof("WCHAR_T")]; + char stringpool_str392[sizeof("WINDOWS-1255")]; + char stringpool_str394[sizeof("ISO-2022-KR")]; + char stringpool_str395[sizeof("UCS-4")]; + char stringpool_str396[sizeof("CSISO57GB1988")]; + char stringpool_str397[sizeof("WINDOWS-1258")]; + char stringpool_str398[sizeof("CSUCS4")]; + char stringpool_str401[sizeof("CSISO2022KR")]; + char stringpool_str403[sizeof("JP")]; + char stringpool_str404[sizeof("WINDOWS-1253")]; + char stringpool_str405[sizeof("STRK1048-2002")]; + char stringpool_str406[sizeof("CSHPROMAN8")]; + char stringpool_str408[sizeof("CSISO58GB231280")]; + char stringpool_str410[sizeof("MACICELAND")]; + char stringpool_str412[sizeof("CSISO14JISC6220RO")]; + char stringpool_str415[sizeof("JIS_C6226-1983")]; + char stringpool_str417[sizeof("ISO-10646-UCS-2")]; + char stringpool_str419[sizeof("WINDOWS-936")]; + char stringpool_str420[sizeof("BIG5HKSCS")]; + char stringpool_str421[sizeof("BIG5-HKSCS")]; + char stringpool_str427[sizeof("SHIFT-JIS")]; + char stringpool_str433[sizeof("WINDOWS-1257")]; + char stringpool_str435[sizeof("WINDOWS-1254")]; + char stringpool_str437[sizeof("CN-GB-ISOIR165")]; + char stringpool_str439[sizeof("CSSHIFTJIS")]; + char stringpool_str440[sizeof("UTF-7")]; + char stringpool_str441[sizeof("WINDOWS-1250")]; + char stringpool_str442[sizeof("EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE")]; + char stringpool_str443[sizeof("CN-GB")]; + char stringpool_str444[sizeof("CSISO159JISX02121990")]; + char stringpool_str448[sizeof("MACROMAN")]; + char stringpool_str449[sizeof("GEORGIAN-ACADEMY")]; + char stringpool_str450[sizeof("JIS_C6220-1969-RO")]; + char stringpool_str451[sizeof("CSISOLATINHEBREW")]; + char stringpool_str454[sizeof("MACARABIC")]; + char stringpool_str455[sizeof("ISO_8859-5:1988")]; + char stringpool_str460[sizeof("ISO_8859-8:1988")]; + char stringpool_str461[sizeof("SHIFT_JIS")]; + char stringpool_str464[sizeof("UCS-2BE")]; + char stringpool_str466[sizeof("ISO_8859-9:1989")]; + char stringpool_str467[sizeof("ISO_8859-3:1988")]; + char stringpool_str468[sizeof("ISO-10646-UCS-4")]; + char stringpool_str470[sizeof("MACROMANIA")]; + char stringpool_str471[sizeof("ISO-2022-JP-2")]; + char stringpool_str473[sizeof("ISO-2022-JP-1")]; + char stringpool_str477[sizeof("CSISO2022JP2")]; + char stringpool_str481[sizeof("JIS0208")]; + char stringpool_str483[sizeof("ISO_8859-2:1987")]; + char stringpool_str484[sizeof("NEXTSTEP")]; + char stringpool_str485[sizeof("ISO_8859-1:1987")]; + char stringpool_str488[sizeof("ISO_8859-6:1987")]; + char stringpool_str490[sizeof("EUCJP")]; + char stringpool_str491[sizeof("EUC-JP")]; + char stringpool_str493[sizeof("CSISOLATINGREEK")]; + char stringpool_str498[sizeof("ISO_8859-4:1988")]; + char stringpool_str503[sizeof("ISO_8859-7:2003")]; + char stringpool_str513[sizeof("GEORGIAN-PS")]; + char stringpool_str515[sizeof("UCS-4BE")]; + char stringpool_str521[sizeof("UTF-16BE")]; + char stringpool_str523[sizeof("CSPC862LATINHEBREW")]; + char stringpool_str525[sizeof("UCS-2LE")]; + char stringpool_str526[sizeof("CSHALFWIDTHKATAKANA")]; + char stringpool_str531[sizeof("ANSI_X3.4-1986")]; + char stringpool_str532[sizeof("ISO_8859-7:1987")]; + char stringpool_str534[sizeof("UTF-32BE")]; + char stringpool_str537[sizeof("WINDOWS-874")]; + char stringpool_str539[sizeof("ANSI_X3.4-1968")]; + char stringpool_str542[sizeof("ISO-2022-JP")]; + char stringpool_str544[sizeof("ISO646-JP")]; + char stringpool_str549[sizeof("CSISO2022JP")]; + char stringpool_str551[sizeof("CYRILLIC")]; + char stringpool_str561[sizeof("MACCENTRALEUROPE")]; + char stringpool_str563[sizeof("MS-HEBR")]; + char stringpool_str566[sizeof("UNICODELITTLE")]; + char stringpool_str576[sizeof("UCS-4LE")]; + char stringpool_str581[sizeof("CYRILLIC-ASIAN")]; + char stringpool_str582[sizeof("UTF-16LE")]; + char stringpool_str583[sizeof("ISO_646.IRV:1991")]; + char stringpool_str595[sizeof("UTF-32LE")]; + char stringpool_str596[sizeof("JAVA")]; + char stringpool_str598[sizeof("MS-ARAB")]; + char stringpool_str603[sizeof("MULELAO-1")]; + char stringpool_str606[sizeof("MS-GREEK")]; + char stringpool_str607[sizeof("MACGREEK")]; + char stringpool_str608[sizeof("BIGFIVE")]; + char stringpool_str609[sizeof("BIG-FIVE")]; + char stringpool_str622[sizeof("MS_KANJI")]; + char stringpool_str627[sizeof("CSEUCKR")]; + char stringpool_str639[sizeof("HEBREW")]; + char stringpool_str644[sizeof("UCS-2-SWAPPED")]; + char stringpool_str654[sizeof("JOHAB")]; + char stringpool_str662[sizeof("CSEUCTW")]; + char stringpool_str665[sizeof("UCS-2-INTERNAL")]; + char stringpool_str669[sizeof("KOI8-U")]; + char stringpool_str685[sizeof("MACUKRAINE")]; + char stringpool_str689[sizeof("MACTURKISH")]; + char stringpool_str692[sizeof("TCVN5712-1:1993")]; + char stringpool_str695[sizeof("UCS-4-SWAPPED")]; + char stringpool_str697[sizeof("MS-CYRL")]; + char stringpool_str704[sizeof("MACCYRILLIC")]; + char stringpool_str705[sizeof("CSISO87JISX0208")]; + char stringpool_str707[sizeof("CSEUCPKDFMTJAPANESE")]; + char stringpool_str710[sizeof("JIS_X0212")]; + char stringpool_str716[sizeof("UCS-4-INTERNAL")]; + char stringpool_str736[sizeof("UNICODEBIG")]; + char stringpool_str745[sizeof("MS-TURK")]; + char stringpool_str757[sizeof("BIG5-HKSCS:2001")]; + char stringpool_str760[sizeof("JISX0201-1976")]; + char stringpool_str768[sizeof("BIG5-HKSCS:2008")]; + char stringpool_str769[sizeof("JIS_X0201")]; + char stringpool_str771[sizeof("BIG5-HKSCS:1999")]; + char stringpool_str774[sizeof("JIS_X0212-1990")]; + char stringpool_str790[sizeof("KOI8-RU")]; + char stringpool_str791[sizeof("JIS_X0208")]; + char stringpool_str800[sizeof("MACHEBREW")]; + char stringpool_str805[sizeof("JIS_X0208-1983")]; + char stringpool_str806[sizeof("BIG5-HKSCS:2004")]; + char stringpool_str842[sizeof("JIS_X0208-1990")]; + char stringpool_str888[sizeof("JIS_X0212.1990-0")]; + char stringpool_str991[sizeof("WINBALTRIM")]; + char stringpool_str1038[sizeof("CSPC850MULTILINGUAL")]; + }; +static const struct stringpool_t stringpool_contents = + { + "CN", + "HZ", + "862", + "CP1252", + "ASCII", + "CP1251", + "SJIS", + "CP862", + "866", + "CP1256", + "CSASCII", + "EUCCN", + "EUC-CN", + "CP1255", + "CP866", + "CP1131", + "C99", + "CP1361", + "HP15CN", + "CP932", + "CP1258", + "CHINESE", + "CP936", + "CP819", + "CP1253", + "ISO88592", + "ISO8859-2", + "ISO-8859-2", + "ISO88591", + "ISO8859-1", + "ISO-8859-1", + "ISO8859-11", + "ISO-8859-11", + "ISO88596", + "ISO8859-6", + "ISO-8859-6", + "CP1133", + "ISO8859-16", + "ISO-8859-16", + "ISO88595", + "ISO8859-5", + "ISO-8859-5", + "ISO885915", + "ISO8859-15", + "ISO-8859-15", + "ISO-2022-CN", + "ISO646-CN", + "ISO88598", + "ISO8859-8", + "ISO-8859-8", + "CSISO2022CN", + "ISO88599", + "ISO8859-9", + "ISO-8859-9", + "ISO_8859-2", + "ISO-2022-CN-EXT", + "ISO_8859-1", + "ISO8859-3", + "ISO-8859-3", + "ISO_8859-11", + "ISO8859-13", + "ISO-8859-13", + "ISO_8859-6", + "CP949", + "ISO_8859-16", + "ISO_8859-16:2001", + "ISO_8859-5", + "ELOT_928", + "ISO_8859-15", + "CP1257", + "CP154", + "CP1254", + "ISO_8859-8", + "ISO_8859-15:1998", + "ISO_8859-9", + "CP367", + "850", + "CP1250", + "ISO_8859-3", + "R8", + "ISO_8859-13", + "ISO-IR-6", + "KOI8-T", + "ISO-IR-226", + "CP850", + "ISO-IR-126", + "CP950", + "ISO-IR-166", + "TIS620", + "TIS-620", + "MAC", + "ISO-IR-165", + "ISO88597", + "ISO8859-7", + "ISO-8859-7", + "ISO_8859-10:1992", + "ISO8859-4", + "ISO-8859-4", + "ISO-IR-58", + "ISO8859-14", + "ISO-8859-14", + "ISO_8859-14:1998", + "GB2312", + "CP874", + "IBM862", + "ISO-IR-159", + "ISO8859-10", + "ISO-8859-10", + "ISO-IR-138", + "MS-ANSI", + "ISO-IR-199", + "IBM866", + "MS-EE", + "ARABIC", + "PT154", + "ISO_8859-7", + "ISO-IR-101", + "MACTHAI", + "ISO_8859-4", + "MS936", + "ISO_8859-14", + "IBM819", + "ARMSCII-8", + "KSC_5601", + "MACINTOSH", + "TIS620-0", + "ECMA-118", + "ISO-IR-148", + "ISO_8859-10", + "L2", + "ISO-IR-179", + "L1", + "ISO-IR-149", + "L6", + "L5", + "ISO-IR-109", + "CSMACINTOSH", + "L8", + "ISO-IR-203", + "KZ-1048", + "ISO-IR-127", + "CSKZ1048", + "L3", + "ISO-IR-14", + "ISO-IR-57", + "TIS620.2529-1", + "ISO-IR-157", + "LATIN2", + "ISO-IR-87", + "LATIN1", + "CSKSC56011987", + "KOREAN", + "ISO-IR-110", + "LATIN6", + "ISO-CELTIC", + "VISCII", + "CSVISCII", + "LATIN5", + "CHAR", + "KS_C_5601-1989", + "TIS620.2533-1", + "L7", + "RK1048", + "L4", + "CSISOLATIN2", + "LATIN8", + "PTCP154", + "CSISOLATIN1", + "TCVN", + "LATIN-9", + "CSISOLATINCYRILLIC", + "CSISOLATIN6", + "IBM367", + "GREEK8", + "LATIN3", + "CSISOLATIN5", + "X0212", + "CSISOLATINARABIC", + "ECMA-114", + "ISO-IR-144", + "CSPTCP154", + "UHC", + "IBM850", + "US", + "KS_C_5601-1987", + "UCS-2", + "IBM-CP1133", + "ASMO-708", + "ISO-IR-100", + "CSISOLATIN3", + "BIG5", + "BIG-5", + "US-ASCII", + "CSBIG5", + "CN-BIG5", + "GBK", + "TIS620.2533-0", + "UNICODE-1-1", + "ROMAN8", + "CSGB2312", + "CSUNICODE11", + "CSUNICODE", + "L10", + "TCVN-5712", + "HZ-GB-2312", + "HP-ROMAN8", + "GB_2312-80", + "CSIBM866", + "TCVN5712-1", + "MACCROATIAN", + "GREEK", + "LATIN7", + "X0201", + "LATIN4", + "EUCKR", + "EUC-KR", + "KOI8-R", + "CSKOI8R", + "GB18030", + "GB_1988-80", + "UTF-16", + "LATIN10", + "X0208", + "UTF-32", + "ISO646-US", + "CSISOLATIN4", + "UTF8", + "UTF-8", + "UNICODE-1-1-UTF-7", + "CSUNICODE11UTF7", + "VISCII1.1-1", + "EUCTW", + "EUC-TW", + "WINDOWS-1252", + "WINDOWS-1251", + "WINDOWS-1256", + "WCHAR_T", + "WINDOWS-1255", + "ISO-2022-KR", + "UCS-4", + "CSISO57GB1988", + "WINDOWS-1258", + "CSUCS4", + "CSISO2022KR", + "JP", + "WINDOWS-1253", + "STRK1048-2002", + "CSHPROMAN8", + "CSISO58GB231280", + "MACICELAND", + "CSISO14JISC6220RO", + "JIS_C6226-1983", + "ISO-10646-UCS-2", + "WINDOWS-936", + "BIG5HKSCS", + "BIG5-HKSCS", + "SHIFT-JIS", + "WINDOWS-1257", + "WINDOWS-1254", + "CN-GB-ISOIR165", + "CSSHIFTJIS", + "UTF-7", + "WINDOWS-1250", + "EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE", + "CN-GB", + "CSISO159JISX02121990", + "MACROMAN", + "GEORGIAN-ACADEMY", + "JIS_C6220-1969-RO", + "CSISOLATINHEBREW", + "MACARABIC", + "ISO_8859-5:1988", + "ISO_8859-8:1988", + "SHIFT_JIS", + "UCS-2BE", + "ISO_8859-9:1989", + "ISO_8859-3:1988", + "ISO-10646-UCS-4", + "MACROMANIA", + "ISO-2022-JP-2", + "ISO-2022-JP-1", + "CSISO2022JP2", + "JIS0208", + "ISO_8859-2:1987", + "NEXTSTEP", + "ISO_8859-1:1987", + "ISO_8859-6:1987", + "EUCJP", + "EUC-JP", + "CSISOLATINGREEK", + "ISO_8859-4:1988", + "ISO_8859-7:2003", + "GEORGIAN-PS", + "UCS-4BE", + "UTF-16BE", + "CSPC862LATINHEBREW", + "UCS-2LE", + "CSHALFWIDTHKATAKANA", + "ANSI_X3.4-1986", + "ISO_8859-7:1987", + "UTF-32BE", + "WINDOWS-874", + "ANSI_X3.4-1968", + "ISO-2022-JP", + "ISO646-JP", + "CSISO2022JP", + "CYRILLIC", + "MACCENTRALEUROPE", + "MS-HEBR", + "UNICODELITTLE", + "UCS-4LE", + "CYRILLIC-ASIAN", + "UTF-16LE", + "ISO_646.IRV:1991", + "UTF-32LE", + "JAVA", + "MS-ARAB", + "MULELAO-1", + "MS-GREEK", + "MACGREEK", + "BIGFIVE", + "BIG-FIVE", + "MS_KANJI", + "CSEUCKR", + "HEBREW", + "UCS-2-SWAPPED", + "JOHAB", + "CSEUCTW", + "UCS-2-INTERNAL", + "KOI8-U", + "MACUKRAINE", + "MACTURKISH", + "TCVN5712-1:1993", + "UCS-4-SWAPPED", + "MS-CYRL", + "MACCYRILLIC", + "CSISO87JISX0208", + "CSEUCPKDFMTJAPANESE", + "JIS_X0212", + "UCS-4-INTERNAL", + "UNICODEBIG", + "MS-TURK", + "BIG5-HKSCS:2001", + "JISX0201-1976", + "BIG5-HKSCS:2008", + "JIS_X0201", + "BIG5-HKSCS:1999", + "JIS_X0212-1990", + "KOI8-RU", + "JIS_X0208", + "MACHEBREW", + "JIS_X0208-1983", + "BIG5-HKSCS:2004", + "JIS_X0208-1990", + "JIS_X0212.1990-0", + "WINBALTRIM", + "CSPC850MULTILINGUAL" + }; +#define stringpool ((const char *) &stringpool_contents) + +static const struct alias aliases[] = + { + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 297 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str9, ei_iso646_cn}, + {-1}, {-1}, +#line 340 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str12, ei_hz}, + {-1}, {-1}, {-1}, +#line 212 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str16, ei_cp862}, +#line 186 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str17, ei_cp1252}, + {-1}, +#line 13 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str19, ei_ascii}, + {-1}, +#line 183 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str21, ei_cp1251}, +#line 317 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str22, ei_sjis}, + {-1}, +#line 210 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str24, ei_cp862}, + {-1}, +#line 216 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str26, ei_cp866}, +#line 198 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str27, ei_cp1256}, +#line 22 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str28, ei_ascii}, +#line 327 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str29, ei_euc_cn}, +#line 326 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str30, ei_euc_cn}, + {-1}, {-1}, +#line 195 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str33, ei_cp1255}, +#line 214 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str34, ei_cp866}, +#line 218 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str35, ei_cp1131}, +#line 52 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str36, ei_c99}, + {-1}, +#line 364 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str38, ei_johab}, +#line 331 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str39, ei_euc_cn}, + {-1}, {-1}, +#line 320 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str42, ei_cp932}, +#line 204 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str43, ei_cp1258}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 302 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str50, ei_gb2312}, + {-1}, +#line 333 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str52, ei_cp936}, +#line 58 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str53, ei_iso8859_1}, + {-1}, {-1}, {-1}, +#line 189 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str57, ei_cp1253}, +#line 73 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str58, ei_iso8859_2}, +#line 72 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str59, ei_iso8859_2}, +#line 65 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str60, ei_iso8859_2}, + {-1}, +#line 64 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str62, ei_iso8859_1}, +#line 63 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str63, ei_iso8859_1}, +#line 54 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str64, ei_iso8859_1}, + {-1}, +#line 147 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str66, ei_iso8859_11}, +#line 145 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str67, ei_iso8859_11}, +#line 107 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str68, ei_iso8859_6}, +#line 106 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str69, ei_iso8859_6}, +#line 98 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str70, ei_iso8859_6}, +#line 253 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str71, ei_cp1133}, +#line 175 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str72, ei_iso8859_16}, +#line 169 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str73, ei_iso8859_16}, +#line 97 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str74, ei_iso8859_5}, +#line 96 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str75, ei_iso8859_5}, +#line 90 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str76, ei_iso8859_5}, +#line 168 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str77, ei_iso8859_15}, +#line 167 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str78, ei_iso8859_15}, +#line 162 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str79, ei_iso8859_15}, + {-1}, +#line 337 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str81, ei_iso2022_cn}, + {-1}, +#line 295 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str83, ei_iso646_cn}, +#line 127 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str84, ei_iso8859_8}, +#line 126 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str85, ei_iso8859_8}, +#line 120 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str86, ei_iso8859_8}, + {-1}, +#line 338 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str88, ei_iso2022_cn}, + {-1}, +#line 136 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str90, ei_iso8859_9}, +#line 135 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str91, ei_iso8859_9}, +#line 128 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str92, ei_iso8859_9}, + {-1}, +#line 66 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str94, ei_iso8859_2}, + {-1}, +#line 339 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str96, ei_iso2022_cn_ext}, + {-1}, +#line 55 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str98, ei_iso8859_1}, +#line 81 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str99, ei_iso8859_3}, +#line 74 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str100, ei_iso8859_3}, +#line 146 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str101, ei_iso8859_11}, +#line 153 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str102, ei_iso8859_13}, +#line 148 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str103, ei_iso8859_13}, +#line 99 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str104, ei_iso8859_6}, +#line 361 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str105, ei_cp949}, + {-1}, +#line 170 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str107, ei_iso8859_16}, + {-1}, +#line 171 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str109, ei_iso8859_16}, +#line 91 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str110, ei_iso8859_5}, +#line 114 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str111, ei_iso8859_7}, + {-1}, +#line 163 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str113, ei_iso8859_15}, + {-1}, +#line 201 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str115, ei_cp1257}, + {-1}, {-1}, +#line 245 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str118, ei_pt154}, +#line 192 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str119, ei_cp1254}, +#line 121 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str120, ei_iso8859_8}, + {-1}, {-1}, +#line 164 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str123, ei_iso8859_15}, + {-1}, {-1}, +#line 129 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str126, ei_iso8859_9}, + {-1}, {-1}, +#line 19 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str129, ei_ascii}, +#line 208 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str130, ei_cp850}, +#line 180 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str131, ei_cp1250}, + {-1}, {-1}, +#line 75 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str134, ei_iso8859_3}, +#line 236 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str135, ei_hp_roman8}, + {-1}, +#line 149 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str137, ei_iso8859_13}, +#line 16 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str138, ei_ascii}, +#line 242 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str139, ei_koi8_t}, +#line 172 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str140, ei_iso8859_16}, +#line 206 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str141, ei_cp850}, +#line 112 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str142, ei_iso8859_7}, + {-1}, +#line 351 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str144, ei_cp950}, + {-1}, {-1}, +#line 261 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str147, ei_tis620}, +#line 256 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str148, ei_tis620}, +#line 255 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str149, ei_tis620}, + {-1}, {-1}, +#line 221 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str152, ei_mac_roman}, +#line 303 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str153, ei_isoir165}, + {-1}, {-1}, +#line 119 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str156, ei_iso8859_7}, +#line 118 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str157, ei_iso8859_7}, +#line 108 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str158, ei_iso8859_7}, +#line 139 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str159, ei_iso8859_10}, + {-1}, +#line 89 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str161, ei_iso8859_4}, +#line 82 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str162, ei_iso8859_4}, +#line 300 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str163, ei_gb2312}, +#line 161 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str164, ei_iso8859_14}, +#line 154 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str165, ei_iso8859_14}, +#line 156 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str166, ei_iso8859_14}, +#line 328 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str167, ei_euc_cn}, + {-1}, {-1}, +#line 262 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str170, ei_cp874}, +#line 211 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str171, ei_cp862}, +#line 292 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str172, ei_jisx0212}, + {-1}, {-1}, {-1}, +#line 144 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str176, ei_iso8859_10}, +#line 137 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str177, ei_iso8859_10}, +#line 123 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str178, ei_iso8859_8}, +#line 188 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str179, ei_cp1252}, +#line 157 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str180, ei_iso8859_14}, +#line 215 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str181, ei_cp866}, +#line 182 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str182, ei_cp1250}, +#line 104 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str183, ei_iso8859_6}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 243 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str190, ei_pt154}, + {-1}, +#line 109 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str192, ei_iso8859_7}, +#line 68 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str193, ei_iso8859_2}, + {-1}, +#line 233 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str195, ei_mac_thai}, +#line 83 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str196, ei_iso8859_4}, + {-1}, +#line 334 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str198, ei_cp936}, +#line 155 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str199, ei_iso8859_14}, +#line 59 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str200, ei_iso8859_1}, + {-1}, +#line 239 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str202, ei_armscii_8}, +#line 305 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str203, ei_ksc5601}, + {-1}, {-1}, +#line 220 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str206, ei_mac_roman}, +#line 257 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str207, ei_tis620}, +#line 113 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str208, ei_iso8859_7}, +#line 131 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str209, ei_iso8859_9}, + {-1}, +#line 138 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str211, ei_iso8859_10}, +#line 70 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str212, ei_iso8859_2}, +#line 150 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str213, ei_iso8859_13}, +#line 61 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str214, ei_iso8859_1}, +#line 308 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str215, ei_ksc5601}, + {-1}, +#line 142 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str217, ei_iso8859_10}, + {-1}, {-1}, +#line 133 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str220, ei_iso8859_9}, +#line 77 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str221, ei_iso8859_3}, +#line 222 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str222, ei_mac_roman}, + {-1}, {-1}, +#line 159 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str225, ei_iso8859_14}, + {-1}, +#line 165 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str227, ei_iso8859_15}, + {-1}, +#line 250 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str229, ei_rk1048}, +#line 101 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str230, ei_iso8859_6}, +#line 251 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str231, ei_rk1048}, +#line 79 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str232, ei_iso8859_3}, +#line 273 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str233, ei_iso646_jp}, + {-1}, +#line 296 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str235, ei_iso646_cn}, +#line 258 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str236, ei_tis620}, + {-1}, +#line 140 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str238, ei_iso8859_10}, +#line 69 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str239, ei_iso8859_2}, +#line 285 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str240, ei_jisx0208}, + {-1}, {-1}, +#line 60 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str243, ei_iso8859_1}, + {-1}, {-1}, +#line 309 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str246, ei_ksc5601}, +#line 310 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str247, ei_ksc5601}, +#line 85 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str248, ei_iso8859_4}, +#line 141 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str249, ei_iso8859_10}, +#line 160 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str250, ei_iso8859_14}, +#line 264 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str251, ei_viscii}, + {-1}, {-1}, +#line 266 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str254, ei_viscii}, +#line 132 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str255, ei_iso8859_9}, + {-1}, {-1}, +#line 367 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str258, ei_local_char}, +#line 307 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str259, ei_ksc5601}, +#line 260 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str260, ei_tis620}, +#line 152 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str261, ei_iso8859_13}, +#line 248 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str262, ei_rk1048}, +#line 87 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str263, ei_iso8859_4}, +#line 71 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str264, ei_iso8859_2}, +#line 158 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str265, ei_iso8859_14}, +#line 244 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str266, ei_pt154}, + {-1}, +#line 62 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str268, ei_iso8859_1}, + {-1}, {-1}, +#line 267 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str271, ei_tcvn}, +#line 166 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str272, ei_iso8859_15}, +#line 95 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str273, ei_iso8859_5}, +#line 143 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str274, ei_iso8859_10}, + {-1}, +#line 20 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str276, ei_ascii}, +#line 115 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str277, ei_iso8859_7}, + {-1}, +#line 78 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str279, ei_iso8859_3}, +#line 134 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str280, ei_iso8859_9}, +#line 291 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str281, ei_jisx0212}, + {-1}, +#line 105 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str283, ei_iso8859_6}, +#line 102 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str284, ei_iso8859_6}, +#line 93 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str285, ei_iso8859_5}, +#line 247 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str286, ei_pt154}, +#line 362 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str287, ei_cp949}, +#line 207 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str288, ei_cp850}, + {-1}, +#line 21 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str290, ei_ascii}, + {-1}, +#line 306 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str292, ei_ksc5601}, +#line 25 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str293, ei_ucs2}, + {-1}, +#line 254 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str295, ei_cp1133}, + {-1}, {-1}, {-1}, {-1}, +#line 103 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str300, ei_iso8859_6}, + {-1}, {-1}, +#line 57 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str303, ei_iso8859_1}, +#line 80 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str304, ei_iso8859_3}, + {-1}, {-1}, {-1}, +#line 345 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str308, ei_ces_big5}, +#line 346 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str309, ei_ces_big5}, +#line 12 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str310, ei_ascii}, +#line 350 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str311, ei_ces_big5}, +#line 349 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str312, ei_ces_big5}, + {-1}, +#line 332 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str314, ei_ces_gbk}, +#line 259 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str315, ei_tis620}, +#line 30 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str316, ei_ucs2be}, + {-1}, +#line 235 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str318, ei_hp_roman8}, +#line 330 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str319, ei_euc_cn}, + {-1}, {-1}, {-1}, +#line 31 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str323, ei_ucs2be}, + {-1}, +#line 27 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str325, ei_ucs2}, + {-1}, +#line 174 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str327, ei_iso8859_16}, + {-1}, +#line 268 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str329, ei_tcvn}, +#line 341 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str330, ei_hz}, +#line 234 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str331, ei_hp_roman8}, +#line 299 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str332, ei_gb2312}, +#line 217 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str333, ei_cp866}, +#line 269 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str334, ei_tcvn}, +#line 225 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str335, ei_mac_croatian}, +#line 116 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str336, ei_iso8859_7}, +#line 151 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str337, ei_iso8859_13}, + {-1}, {-1}, +#line 278 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str340, ei_jisx0201}, +#line 86 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str341, ei_iso8859_4}, +#line 359 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str342, ei_euc_kr}, +#line 358 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str343, ei_euc_kr}, + {-1}, +#line 176 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str345, ei_koi8_r}, + {-1}, +#line 177 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str347, ei_koi8_r}, + {-1}, {-1}, {-1}, {-1}, +#line 336 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str352, ei_gb18030}, + {-1}, +#line 294 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str354, ei_iso646_cn}, +#line 39 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str355, ei_utf16}, +#line 173 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str356, ei_iso8859_16}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 284 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str362, ei_jisx0208}, +#line 42 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str363, ei_utf32}, +#line 14 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str364, ei_ascii}, + {-1}, +#line 88 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str366, ei_iso8859_4}, +#line 24 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str367, ei_utf8}, +#line 23 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str368, ei_utf8}, +#line 46 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str369, ei_utf7}, + {-1}, {-1}, {-1}, {-1}, +#line 47 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str374, ei_utf7}, + {-1}, +#line 265 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str376, ei_viscii}, +#line 343 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str377, ei_euc_tw}, +#line 342 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str378, ei_euc_tw}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 187 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str384, ei_cp1252}, + {-1}, +#line 184 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str386, ei_cp1251}, + {-1}, {-1}, +#line 199 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str389, ei_cp1256}, +#line 368 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str390, ei_local_wchar_t}, + {-1}, +#line 196 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str392, ei_cp1255}, + {-1}, +#line 365 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str394, ei_iso2022_kr}, +#line 34 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str395, ei_ucs4}, +#line 298 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str396, ei_iso646_cn}, +#line 205 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str397, ei_cp1258}, +#line 36 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str398, ei_ucs4}, + {-1}, {-1}, +#line 366 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str401, ei_iso2022_kr}, + {-1}, +#line 274 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str403, ei_iso646_jp}, +#line 190 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str404, ei_cp1253}, +#line 249 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str405, ei_rk1048}, +#line 237 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str406, ei_hp_roman8}, + {-1}, +#line 301 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str408, ei_gb2312}, + {-1}, +#line 224 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str410, ei_mac_iceland}, + {-1}, +#line 275 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str412, ei_iso646_jp}, + {-1}, {-1}, +#line 286 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str415, ei_jisx0208}, + {-1}, +#line 26 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str417, ei_ucs2}, + {-1}, +#line 335 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str419, ei_cp936}, +#line 356 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str420, ei_big5hkscs2008}, +#line 355 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str421, ei_big5hkscs2008}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 316 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str427, ei_sjis}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 202 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str433, ei_cp1257}, + {-1}, +#line 193 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str435, ei_cp1254}, + {-1}, +#line 304 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str437, ei_isoir165}, + {-1}, +#line 319 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str439, ei_sjis}, +#line 45 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str440, ei_utf7}, +#line 181 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str441, ei_cp1250}, +#line 313 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str442, ei_euc_jp}, +#line 329 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str443, ei_euc_cn}, +#line 293 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str444, ei_jisx0212}, + {-1}, {-1}, {-1}, +#line 219 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str448, ei_mac_roman}, +#line 240 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str449, ei_georgian_academy}, +#line 271 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str450, ei_iso646_jp}, +#line 125 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str451, ei_iso8859_8}, + {-1}, {-1}, +#line 232 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str454, ei_mac_arabic}, +#line 92 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str455, ei_iso8859_5}, + {-1}, {-1}, {-1}, {-1}, +#line 122 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str460, ei_iso8859_8}, +#line 315 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str461, ei_sjis}, + {-1}, {-1}, +#line 28 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str464, ei_ucs2be}, + {-1}, +#line 130 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str466, ei_iso8859_9}, +#line 76 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str467, ei_iso8859_3}, +#line 35 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str468, ei_ucs4}, + {-1}, +#line 226 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str470, ei_mac_romania}, +#line 324 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str471, ei_iso2022_jp2}, + {-1}, +#line 323 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str473, ei_iso2022_jp1}, + {-1}, {-1}, {-1}, +#line 325 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str477, ei_iso2022_jp2}, + {-1}, {-1}, {-1}, +#line 283 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str481, ei_jisx0208}, + {-1}, +#line 67 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str483, ei_iso8859_2}, +#line 238 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str484, ei_nextstep}, +#line 56 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str485, ei_iso8859_1}, + {-1}, {-1}, +#line 100 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str488, ei_iso8859_6}, + {-1}, +#line 312 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str490, ei_euc_jp}, +#line 311 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str491, ei_euc_jp}, + {-1}, +#line 117 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str493, ei_iso8859_7}, + {-1}, {-1}, {-1}, {-1}, +#line 84 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str498, ei_iso8859_4}, + {-1}, {-1}, {-1}, {-1}, +#line 111 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str503, ei_iso8859_7}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 241 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str513, ei_georgian_ps}, + {-1}, +#line 37 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str515, ei_ucs4be}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 40 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str521, ei_utf16be}, + {-1}, +#line 213 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str523, ei_cp862}, + {-1}, +#line 32 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str525, ei_ucs2le}, +#line 279 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str526, ei_jisx0201}, + {-1}, {-1}, {-1}, {-1}, +#line 18 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str531, ei_ascii}, +#line 110 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str532, ei_iso8859_7}, + {-1}, +#line 43 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str534, ei_utf32be}, + {-1}, {-1}, +#line 263 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str537, ei_cp874}, + {-1}, +#line 17 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str539, ei_ascii}, + {-1}, {-1}, +#line 321 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str542, ei_iso2022_jp}, + {-1}, +#line 272 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str544, ei_iso646_jp}, + {-1}, {-1}, {-1}, {-1}, +#line 322 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str549, ei_iso2022_jp}, + {-1}, +#line 94 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str551, ei_iso8859_5}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 223 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str561, ei_mac_centraleurope}, + {-1}, +#line 197 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str563, ei_cp1255}, + {-1}, {-1}, +#line 33 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str566, ei_ucs2le}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 38 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str576, ei_ucs4le}, + {-1}, {-1}, {-1}, {-1}, +#line 246 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str581, ei_pt154}, +#line 41 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str582, ei_utf16le}, +#line 15 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str583, ei_ascii}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 44 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str595, ei_utf32le}, +#line 53 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str596, ei_java}, + {-1}, +#line 200 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str598, ei_cp1256}, + {-1}, {-1}, {-1}, {-1}, +#line 252 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str603, ei_mulelao}, + {-1}, {-1}, +#line 191 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str606, ei_cp1253}, +#line 229 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str607, ei_mac_greek}, +#line 348 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str608, ei_ces_big5}, +#line 347 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str609, ei_ces_big5}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 318 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str622, ei_sjis}, + {-1}, {-1}, {-1}, {-1}, +#line 360 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str627, ei_euc_kr}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 124 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str639, ei_iso8859_8}, + {-1}, {-1}, {-1}, {-1}, +#line 49 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str644, ei_ucs2swapped}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 363 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str654, ei_johab}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 344 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str662, ei_euc_tw}, + {-1}, {-1}, +#line 48 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str665, ei_ucs2internal}, + {-1}, {-1}, {-1}, +#line 178 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str669, ei_koi8_u}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 228 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str685, ei_mac_ukraine}, + {-1}, {-1}, {-1}, +#line 230 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str689, ei_mac_turkish}, + {-1}, {-1}, +#line 270 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str692, ei_tcvn}, + {-1}, {-1}, +#line 51 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str695, ei_ucs4swapped}, + {-1}, +#line 185 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str697, ei_cp1251}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 227 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str704, ei_mac_cyrillic}, +#line 287 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str705, ei_jisx0208}, + {-1}, +#line 314 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str707, ei_euc_jp}, + {-1}, {-1}, +#line 288 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str710, ei_jisx0212}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 50 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str716, ei_ucs4internal}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 29 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str736, ei_ucs2be}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 194 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str745, ei_cp1254}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 353 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str757, ei_big5hkscs2001}, + {-1}, {-1}, +#line 277 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str760, ei_jisx0201}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 357 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str768, ei_big5hkscs2008}, +#line 276 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str769, ei_jisx0201}, + {-1}, +#line 352 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str771, ei_big5hkscs1999}, + {-1}, {-1}, +#line 290 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str774, ei_jisx0212}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 179 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str790, ei_koi8_ru}, +#line 280 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str791, ei_jisx0208}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 231 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str800, ei_mac_hebrew}, + {-1}, {-1}, {-1}, {-1}, +#line 281 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str805, ei_jisx0208}, +#line 354 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str806, ei_big5hkscs2004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 282 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str842, ei_jisx0208}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 289 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str888, ei_jisx0212}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 203 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str991, ei_cp1257}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 209 "lib/aliases_syshpux.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str1038, ei_cp850} + }; + +#ifdef __GNUC__ +__inline +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct alias * +aliases_lookup (register const char *str, register unsigned int len) +{ + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = aliases_hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int o = aliases[key].name; + if (o >= 0) + { + register const char *s = o + stringpool; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &aliases[key]; + } + } + } + return 0; +} diff --git a/libs/libiconv/lib/aliases_sysosf1.gperf b/libs/libiconv/lib/aliases_sysosf1.gperf new file mode 100644 index 00000000..79030e77 --- /dev/null +++ b/libs/libiconv/lib/aliases_sysosf1.gperf @@ -0,0 +1,363 @@ +struct alias { int name; unsigned int encoding_index; }; +%struct-type +%language=ANSI-C +%define hash-function-name aliases_hash +%define lookup-function-name aliases_lookup +%7bit +%readonly-tables +%global-table +%define word-array-name aliases +%pic +%% +US-ASCII, ei_ascii +ASCII, ei_ascii +ISO646-US, ei_ascii +ISO_646.IRV:1991, ei_ascii +ISO-IR-6, ei_ascii +ANSI_X3.4-1968, ei_ascii +ANSI_X3.4-1986, ei_ascii +CP367, ei_ascii +IBM367, ei_ascii +US, ei_ascii +CSASCII, ei_ascii +UTF-8, ei_utf8 +UCS-2, ei_ucs2 +ISO-10646-UCS-2, ei_ucs2 +CSUNICODE, ei_ucs2 +UCS-2BE, ei_ucs2be +UNICODEBIG, ei_ucs2be +UNICODE-1-1, ei_ucs2be +CSUNICODE11, ei_ucs2be +UCS-2LE, ei_ucs2le +UNICODELITTLE, ei_ucs2le +UCS-4, ei_ucs4 +ISO-10646-UCS-4, ei_ucs4 +CSUCS4, ei_ucs4 +UCS-4BE, ei_ucs4be +UCS-4LE, ei_ucs4le +UTF-16, ei_utf16 +UTF-16BE, ei_utf16be +UTF-16LE, ei_utf16le +UTF-32, ei_utf32 +UTF-32BE, ei_utf32be +UTF-32LE, ei_utf32le +UTF-7, ei_utf7 +UNICODE-1-1-UTF-7, ei_utf7 +CSUNICODE11UTF7, ei_utf7 +UCS-2-INTERNAL, ei_ucs2internal +UCS-2-SWAPPED, ei_ucs2swapped +UCS-4-INTERNAL, ei_ucs4internal +UCS-4-SWAPPED, ei_ucs4swapped +C99, ei_c99 +JAVA, ei_java +ISO-8859-1, ei_iso8859_1 +ISO_8859-1, ei_iso8859_1 +ISO_8859-1:1987, ei_iso8859_1 +ISO-IR-100, ei_iso8859_1 +CP819, ei_iso8859_1 +IBM819, ei_iso8859_1 +LATIN1, ei_iso8859_1 +L1, ei_iso8859_1 +CSISOLATIN1, ei_iso8859_1 +ISO8859-1, ei_iso8859_1 +ISO-8859-2, ei_iso8859_2 +ISO_8859-2, ei_iso8859_2 +ISO_8859-2:1987, ei_iso8859_2 +ISO-IR-101, ei_iso8859_2 +LATIN2, ei_iso8859_2 +L2, ei_iso8859_2 +CSISOLATIN2, ei_iso8859_2 +ISO8859-2, ei_iso8859_2 +ISO-8859-3, ei_iso8859_3 +ISO_8859-3, ei_iso8859_3 +ISO_8859-3:1988, ei_iso8859_3 +ISO-IR-109, ei_iso8859_3 +LATIN3, ei_iso8859_3 +L3, ei_iso8859_3 +CSISOLATIN3, ei_iso8859_3 +ISO8859-3, ei_iso8859_3 +ISO-8859-4, ei_iso8859_4 +ISO_8859-4, ei_iso8859_4 +ISO_8859-4:1988, ei_iso8859_4 +ISO-IR-110, ei_iso8859_4 +LATIN4, ei_iso8859_4 +L4, ei_iso8859_4 +CSISOLATIN4, ei_iso8859_4 +ISO8859-4, ei_iso8859_4 +ISO-8859-5, ei_iso8859_5 +ISO_8859-5, ei_iso8859_5 +ISO_8859-5:1988, ei_iso8859_5 +ISO-IR-144, ei_iso8859_5 +CYRILLIC, ei_iso8859_5 +CSISOLATINCYRILLIC, ei_iso8859_5 +ISO8859-5, ei_iso8859_5 +ISO-8859-6, ei_iso8859_6 +ISO_8859-6, ei_iso8859_6 +ISO_8859-6:1987, ei_iso8859_6 +ISO-IR-127, ei_iso8859_6 +ECMA-114, ei_iso8859_6 +ASMO-708, ei_iso8859_6 +ARABIC, ei_iso8859_6 +CSISOLATINARABIC, ei_iso8859_6 +ISO8859-6, ei_iso8859_6 +ISO-8859-7, ei_iso8859_7 +ISO_8859-7, ei_iso8859_7 +ISO_8859-7:1987, ei_iso8859_7 +ISO_8859-7:2003, ei_iso8859_7 +ISO-IR-126, ei_iso8859_7 +ECMA-118, ei_iso8859_7 +ELOT_928, ei_iso8859_7 +GREEK8, ei_iso8859_7 +GREEK, ei_iso8859_7 +CSISOLATINGREEK, ei_iso8859_7 +ISO8859-7, ei_iso8859_7 +ISO-8859-8, ei_iso8859_8 +ISO_8859-8, ei_iso8859_8 +ISO_8859-8:1988, ei_iso8859_8 +ISO-IR-138, ei_iso8859_8 +HEBREW, ei_iso8859_8 +CSISOLATINHEBREW, ei_iso8859_8 +ISO8859-8, ei_iso8859_8 +ISO-8859-9, ei_iso8859_9 +ISO_8859-9, ei_iso8859_9 +ISO_8859-9:1989, ei_iso8859_9 +ISO-IR-148, ei_iso8859_9 +LATIN5, ei_iso8859_9 +L5, ei_iso8859_9 +CSISOLATIN5, ei_iso8859_9 +ISO8859-9, ei_iso8859_9 +ISO-8859-10, ei_iso8859_10 +ISO_8859-10, ei_iso8859_10 +ISO_8859-10:1992, ei_iso8859_10 +ISO-IR-157, ei_iso8859_10 +LATIN6, ei_iso8859_10 +L6, ei_iso8859_10 +CSISOLATIN6, ei_iso8859_10 +ISO8859-10, ei_iso8859_10 +ISO-8859-11, ei_iso8859_11 +ISO_8859-11, ei_iso8859_11 +ISO8859-11, ei_iso8859_11 +ISO-8859-13, ei_iso8859_13 +ISO_8859-13, ei_iso8859_13 +ISO-IR-179, ei_iso8859_13 +LATIN7, ei_iso8859_13 +L7, ei_iso8859_13 +ISO8859-13, ei_iso8859_13 +ISO-8859-14, ei_iso8859_14 +ISO_8859-14, ei_iso8859_14 +ISO_8859-14:1998, ei_iso8859_14 +ISO-IR-199, ei_iso8859_14 +LATIN8, ei_iso8859_14 +L8, ei_iso8859_14 +ISO-CELTIC, ei_iso8859_14 +ISO8859-14, ei_iso8859_14 +ISO-8859-15, ei_iso8859_15 +ISO_8859-15, ei_iso8859_15 +ISO_8859-15:1998, ei_iso8859_15 +ISO-IR-203, ei_iso8859_15 +LATIN-9, ei_iso8859_15 +ISO8859-15, ei_iso8859_15 +ISO-8859-16, ei_iso8859_16 +ISO_8859-16, ei_iso8859_16 +ISO_8859-16:2001, ei_iso8859_16 +ISO-IR-226, ei_iso8859_16 +LATIN10, ei_iso8859_16 +L10, ei_iso8859_16 +ISO8859-16, ei_iso8859_16 +KOI8-R, ei_koi8_r +CSKOI8R, ei_koi8_r +KOI8-U, ei_koi8_u +KOI8-RU, ei_koi8_ru +CP1250, ei_cp1250 +WINDOWS-1250, ei_cp1250 +MS-EE, ei_cp1250 +CP1251, ei_cp1251 +WINDOWS-1251, ei_cp1251 +MS-CYRL, ei_cp1251 +CP1252, ei_cp1252 +WINDOWS-1252, ei_cp1252 +MS-ANSI, ei_cp1252 +CP1253, ei_cp1253 +WINDOWS-1253, ei_cp1253 +MS-GREEK, ei_cp1253 +CP1254, ei_cp1254 +WINDOWS-1254, ei_cp1254 +MS-TURK, ei_cp1254 +CP1255, ei_cp1255 +WINDOWS-1255, ei_cp1255 +MS-HEBR, ei_cp1255 +CP1256, ei_cp1256 +WINDOWS-1256, ei_cp1256 +MS-ARAB, ei_cp1256 +CP1257, ei_cp1257 +WINDOWS-1257, ei_cp1257 +WINBALTRIM, ei_cp1257 +CP1258, ei_cp1258 +WINDOWS-1258, ei_cp1258 +CP850, ei_cp850 +IBM850, ei_cp850 +850, ei_cp850 +CSPC850MULTILINGUAL, ei_cp850 +CP862, ei_cp862 +IBM862, ei_cp862 +862, ei_cp862 +CSPC862LATINHEBREW, ei_cp862 +CP866, ei_cp866 +IBM866, ei_cp866 +866, ei_cp866 +CSIBM866, ei_cp866 +CP1131, ei_cp1131 +MACROMAN, ei_mac_roman +MACINTOSH, ei_mac_roman +MAC, ei_mac_roman +CSMACINTOSH, ei_mac_roman +MACCENTRALEUROPE, ei_mac_centraleurope +MACICELAND, ei_mac_iceland +MACCROATIAN, ei_mac_croatian +MACROMANIA, ei_mac_romania +MACCYRILLIC, ei_mac_cyrillic +MACUKRAINE, ei_mac_ukraine +MACGREEK, ei_mac_greek +MACTURKISH, ei_mac_turkish +MACHEBREW, ei_mac_hebrew +MACARABIC, ei_mac_arabic +MACTHAI, ei_mac_thai +HP-ROMAN8, ei_hp_roman8 +ROMAN8, ei_hp_roman8 +R8, ei_hp_roman8 +CSHPROMAN8, ei_hp_roman8 +NEXTSTEP, ei_nextstep +ARMSCII-8, ei_armscii_8 +GEORGIAN-ACADEMY, ei_georgian_academy +GEORGIAN-PS, ei_georgian_ps +KOI8-T, ei_koi8_t +PT154, ei_pt154 +PTCP154, ei_pt154 +CP154, ei_pt154 +CYRILLIC-ASIAN, ei_pt154 +CSPTCP154, ei_pt154 +RK1048, ei_rk1048 +STRK1048-2002, ei_rk1048 +KZ-1048, ei_rk1048 +CSKZ1048, ei_rk1048 +MULELAO-1, ei_mulelao +CP1133, ei_cp1133 +IBM-CP1133, ei_cp1133 +TIS-620, ei_tis620 +TIS620, ei_tis620 +TIS620-0, ei_tis620 +TIS620.2529-1, ei_tis620 +TIS620.2533-0, ei_tis620 +TIS620.2533-1, ei_tis620 +ISO-IR-166, ei_tis620 +TACTIS, ei_tis620 +CP874, ei_cp874 +WINDOWS-874, ei_cp874 +VISCII, ei_viscii +VISCII1.1-1, ei_viscii +CSVISCII, ei_viscii +TCVN, ei_tcvn +TCVN-5712, ei_tcvn +TCVN5712-1, ei_tcvn +TCVN5712-1:1993, ei_tcvn +JIS_C6220-1969-RO, ei_iso646_jp +ISO646-JP, ei_iso646_jp +ISO-IR-14, ei_iso646_jp +JP, ei_iso646_jp +CSISO14JISC6220RO, ei_iso646_jp +JIS_X0201, ei_jisx0201 +JISX0201-1976, ei_jisx0201 +X0201, ei_jisx0201 +CSHALFWIDTHKATAKANA, ei_jisx0201 +JIS_X0208, ei_jisx0208 +JIS_X0208-1983, ei_jisx0208 +JIS_X0208-1990, ei_jisx0208 +JIS0208, ei_jisx0208 +X0208, ei_jisx0208 +ISO-IR-87, ei_jisx0208 +JIS_C6226-1983, ei_jisx0208 +CSISO87JISX0208, ei_jisx0208 +JIS_X0212, ei_jisx0212 +JIS_X0212.1990-0, ei_jisx0212 +JIS_X0212-1990, ei_jisx0212 +X0212, ei_jisx0212 +ISO-IR-159, ei_jisx0212 +CSISO159JISX02121990, ei_jisx0212 +GB_1988-80, ei_iso646_cn +ISO646-CN, ei_iso646_cn +ISO-IR-57, ei_iso646_cn +CN, ei_iso646_cn +CSISO57GB1988, ei_iso646_cn +GB_2312-80, ei_gb2312 +ISO-IR-58, ei_gb2312 +CSISO58GB231280, ei_gb2312 +CHINESE, ei_gb2312 +ISO-IR-165, ei_isoir165 +CN-GB-ISOIR165, ei_isoir165 +KSC_5601, ei_ksc5601 +KS_C_5601-1987, ei_ksc5601 +KS_C_5601-1989, ei_ksc5601 +ISO-IR-149, ei_ksc5601 +CSKSC56011987, ei_ksc5601 +KOREAN, ei_ksc5601 +EUC-JP, ei_euc_jp +EUCJP, ei_euc_jp +EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE, ei_euc_jp +CSEUCPKDFMTJAPANESE, ei_euc_jp +SDECKANJI, ei_euc_jp +SHIFT_JIS, ei_sjis +SHIFT-JIS, ei_sjis +SJIS, ei_sjis +MS_KANJI, ei_sjis +CSSHIFTJIS, ei_sjis +CP932, ei_cp932 +ISO-2022-JP, ei_iso2022_jp +CSISO2022JP, ei_iso2022_jp +ISO-2022-JP-1, ei_iso2022_jp1 +ISO-2022-JP-2, ei_iso2022_jp2 +CSISO2022JP2, ei_iso2022_jp2 +EUC-CN, ei_euc_cn +EUCCN, ei_euc_cn +GB2312, ei_euc_cn +CN-GB, ei_euc_cn +CSGB2312, ei_euc_cn +DECHANZI, ei_euc_cn +GBK, ei_ces_gbk +CP936, ei_cp936 +MS936, ei_cp936 +WINDOWS-936, ei_cp936 +GB18030, ei_gb18030 +ISO-2022-CN, ei_iso2022_cn +CSISO2022CN, ei_iso2022_cn +ISO-2022-CN-EXT, ei_iso2022_cn_ext +HZ, ei_hz +HZ-GB-2312, ei_hz +EUC-TW, ei_euc_tw +EUCTW, ei_euc_tw +CSEUCTW, ei_euc_tw +BIG5, ei_ces_big5 +BIG-5, ei_ces_big5 +BIG-FIVE, ei_ces_big5 +BIGFIVE, ei_ces_big5 +CN-BIG5, ei_ces_big5 +CSBIG5, ei_ces_big5 +CP950, ei_cp950 +BIG5-HKSCS:1999, ei_big5hkscs1999 +BIG5-HKSCS:2001, ei_big5hkscs2001 +BIG5-HKSCS:2004, ei_big5hkscs2004 +BIG5-HKSCS, ei_big5hkscs2008 +BIG5HKSCS, ei_big5hkscs2008 +BIG5-HKSCS:2008, ei_big5hkscs2008 +EUC-KR, ei_euc_kr +EUCKR, ei_euc_kr +CSEUCKR, ei_euc_kr +DECKOREAN, ei_euc_kr +CP949, ei_cp949 +UHC, ei_cp949 +KSC5601, ei_cp949 +JOHAB, ei_johab +CP1361, ei_johab +ISO-2022-KR, ei_iso2022_kr +CSISO2022KR, ei_iso2022_kr +CHAR, ei_local_char +WCHAR_T, ei_local_wchar_t diff --git a/libs/libiconv/lib/aliases_sysosf1.h b/libs/libiconv/lib/aliases_sysosf1.h new file mode 100644 index 00000000..18bbb031 --- /dev/null +++ b/libs/libiconv/lib/aliases_sysosf1.h @@ -0,0 +1,1745 @@ +/* ANSI-C code produced by gperf version 3.0.4 */ +/* Command-line: gperf -m 10 lib/aliases_sysosf1.gperf */ +/* Computed positions: -k'1,3-11,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "lib/aliases_sysosf1.gperf" +struct alias { int name; unsigned int encoding_index; }; + +#define TOTAL_KEYWORDS 352 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 45 +#define MIN_HASH_VALUE 13 +#define MAX_HASH_VALUE 939 +/* maximum key range = 927, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +aliases_hash (register const char *str, register unsigned int len) +{ + static const unsigned short asso_values[] = + { + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 13, 100, 940, 73, 4, + 7, 6, 55, 8, 5, 156, 10, 23, 295, 940, + 940, 940, 940, 940, 940, 115, 165, 4, 6, 104, + 115, 13, 53, 4, 304, 95, 7, 150, 18, 4, + 75, 940, 76, 50, 25, 141, 173, 137, 120, 6, + 5, 940, 940, 940, 940, 27, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 940, 940, 940, 940, 940, + 940, 940, 940, 940, 940, 940, 940, 940 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[10]]; + /*FALLTHROUGH*/ + case 10: + hval += asso_values[(unsigned char)str[9]]; + /*FALLTHROUGH*/ + case 9: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +struct stringpool_t + { + char stringpool_str13[sizeof("L1")]; + char stringpool_str14[sizeof("L6")]; + char stringpool_str15[sizeof("L3")]; + char stringpool_str16[sizeof("L2")]; + char stringpool_str17[sizeof("L5")]; + char stringpool_str19[sizeof("L8")]; + char stringpool_str23[sizeof("866")]; + char stringpool_str24[sizeof("CN")]; + char stringpool_str27[sizeof("862")]; + char stringpool_str32[sizeof("CP1131")]; + char stringpool_str33[sizeof("CP1361")]; + char stringpool_str34[sizeof("CP866")]; + char stringpool_str36[sizeof("CP1133")]; + char stringpool_str37[sizeof("CP1251")]; + char stringpool_str38[sizeof("CP862")]; + char stringpool_str39[sizeof("CP1256")]; + char stringpool_str41[sizeof("CP1253")]; + char stringpool_str43[sizeof("CP1252")]; + char stringpool_str45[sizeof("CP1255")]; + char stringpool_str48[sizeof("CP936")]; + char stringpool_str49[sizeof("CP1258")]; + char stringpool_str50[sizeof("GB2312")]; + char stringpool_str52[sizeof("CP932")]; + char stringpool_str53[sizeof("C99")]; + char stringpool_str60[sizeof("HZ")]; + char stringpool_str64[sizeof("L4")]; + char stringpool_str68[sizeof("LATIN1")]; + char stringpool_str69[sizeof("CP819")]; + char stringpool_str70[sizeof("LATIN6")]; + char stringpool_str72[sizeof("LATIN3")]; + char stringpool_str74[sizeof("LATIN2")]; + char stringpool_str76[sizeof("LATIN5")]; + char stringpool_str80[sizeof("LATIN8")]; + char stringpool_str88[sizeof("R8")]; + char stringpool_str89[sizeof("ISO8859-1")]; + char stringpool_str91[sizeof("ISO8859-6")]; + char stringpool_str93[sizeof("ISO8859-3")]; + char stringpool_str94[sizeof("ISO8859-11")]; + char stringpool_str95[sizeof("ISO8859-2")]; + char stringpool_str96[sizeof("ISO8859-16")]; + char stringpool_str97[sizeof("ISO8859-5")]; + char stringpool_str98[sizeof("ISO8859-13")]; + char stringpool_str101[sizeof("ISO8859-8")]; + char stringpool_str102[sizeof("ISO8859-15")]; + char stringpool_str103[sizeof("ISO-8859-1")]; + char stringpool_str105[sizeof("ISO-8859-6")]; + char stringpool_str107[sizeof("ISO-8859-3")]; + char stringpool_str108[sizeof("ISO-8859-11")]; + char stringpool_str109[sizeof("ISO-8859-2")]; + char stringpool_str110[sizeof("ISO-8859-16")]; + char stringpool_str111[sizeof("ISO-8859-5")]; + char stringpool_str112[sizeof("ISO-8859-13")]; + char stringpool_str115[sizeof("ISO-8859-8")]; + char stringpool_str116[sizeof("ISO-8859-15")]; + char stringpool_str117[sizeof("ISO_8859-1")]; + char stringpool_str118[sizeof("CYRILLIC")]; + char stringpool_str119[sizeof("ISO_8859-6")]; + char stringpool_str120[sizeof("LATIN-9")]; + char stringpool_str121[sizeof("ISO_8859-3")]; + char stringpool_str122[sizeof("ISO_8859-11")]; + char stringpool_str123[sizeof("ISO_8859-2")]; + char stringpool_str124[sizeof("ISO_8859-16")]; + char stringpool_str125[sizeof("ISO_8859-5")]; + char stringpool_str126[sizeof("ISO_8859-13")]; + char stringpool_str127[sizeof("ISO8859-9")]; + char stringpool_str128[sizeof("ISO_8859-16:2001")]; + char stringpool_str129[sizeof("ISO_8859-8")]; + char stringpool_str130[sizeof("ISO_8859-15")]; + char stringpool_str131[sizeof("CP154")]; + char stringpool_str132[sizeof("ISO-IR-6")]; + char stringpool_str133[sizeof("CP949")]; + char stringpool_str135[sizeof("ISO646-CN")]; + char stringpool_str136[sizeof("ASCII")]; + char stringpool_str137[sizeof("ISO_8859-15:1998")]; + char stringpool_str139[sizeof("CP1254")]; + char stringpool_str141[sizeof("ISO-8859-9")]; + char stringpool_str143[sizeof("ISO-IR-166")]; + char stringpool_str145[sizeof("ISO-IR-126")]; + char stringpool_str148[sizeof("ISO-IR-226")]; + char stringpool_str149[sizeof("ISO-IR-165")]; + char stringpool_str150[sizeof("X0212")]; + char stringpool_str151[sizeof("ISO-IR-58")]; + char stringpool_str152[sizeof("UHC")]; + char stringpool_str153[sizeof("EUCCN")]; + char stringpool_str154[sizeof("ISO-IR-138")]; + char stringpool_str155[sizeof("ISO_8859-9")]; + char stringpool_str156[sizeof("L10")]; + char stringpool_str158[sizeof("SJIS")]; + char stringpool_str159[sizeof("850")]; + char stringpool_str161[sizeof("MAC")]; + char stringpool_str164[sizeof("TACTIS")]; + char stringpool_str165[sizeof("L7")]; + char stringpool_str167[sizeof("EUC-CN")]; + char stringpool_str170[sizeof("LATIN4")]; + char stringpool_str173[sizeof("CP850")]; + char stringpool_str175[sizeof("CP1250")]; + char stringpool_str178[sizeof("KOI8-T")]; + char stringpool_str179[sizeof("ISO-2022-CN")]; + char stringpool_str182[sizeof("ISO-IR-159")]; + char stringpool_str183[sizeof("ISO-CELTIC")]; + char stringpool_str184[sizeof("ISO_8859-14:1998")]; + char stringpool_str185[sizeof("IBM866")]; + char stringpool_str186[sizeof("CP950")]; + char stringpool_str189[sizeof("IBM862")]; + char stringpool_str190[sizeof("ISO-2022-CN-EXT")]; + char stringpool_str191[sizeof("ISO8859-4")]; + char stringpool_str192[sizeof("CSASCII")]; + char stringpool_str193[sizeof("US")]; + char stringpool_str194[sizeof("MS936")]; + char stringpool_str196[sizeof("ISO8859-14")]; + char stringpool_str197[sizeof("ISO-IR-199")]; + char stringpool_str198[sizeof("BIG5")]; + char stringpool_str199[sizeof("ISO_8859-10:1992")]; + char stringpool_str200[sizeof("KSC5601")]; + char stringpool_str202[sizeof("PT154")]; + char stringpool_str203[sizeof("ISO-IR-148")]; + char stringpool_str205[sizeof("ISO-8859-4")]; + char stringpool_str206[sizeof("GBK")]; + char stringpool_str207[sizeof("CSISO2022CN")]; + char stringpool_str208[sizeof("CSBIG5")]; + char stringpool_str209[sizeof("ISO-IR-101")]; + char stringpool_str210[sizeof("ISO-8859-14")]; + char stringpool_str211[sizeof("LATIN10")]; + char stringpool_str212[sizeof("BIG-5")]; + char stringpool_str213[sizeof("X0201")]; + char stringpool_str216[sizeof("ISO-IR-203")]; + char stringpool_str217[sizeof("DECHANZI")]; + char stringpool_str218[sizeof("ELOT_928")]; + char stringpool_str219[sizeof("ISO_8859-4")]; + char stringpool_str220[sizeof("IBM819")]; + char stringpool_str221[sizeof("CSGB2312")]; + char stringpool_str222[sizeof("CN-BIG5")]; + char stringpool_str223[sizeof("UCS-2")]; + char stringpool_str224[sizeof("ISO_8859-14")]; + char stringpool_str225[sizeof("X0208")]; + char stringpool_str228[sizeof("KSC_5601")]; + char stringpool_str229[sizeof("ISO-IR-149")]; + char stringpool_str232[sizeof("ISO8859-10")]; + char stringpool_str234[sizeof("RK1048")]; + char stringpool_str237[sizeof("ISO-IR-14")]; + char stringpool_str238[sizeof("TCVN")]; + char stringpool_str239[sizeof("TIS620")]; + char stringpool_str243[sizeof("GB_2312-80")]; + char stringpool_str245[sizeof("VISCII")]; + char stringpool_str246[sizeof("ISO-8859-10")]; + char stringpool_str247[sizeof("ISO-IR-109")]; + char stringpool_str250[sizeof("CSISOLATIN1")]; + char stringpool_str252[sizeof("CSISOLATIN6")]; + char stringpool_str253[sizeof("TIS-620")]; + char stringpool_str254[sizeof("CSISOLATIN3")]; + char stringpool_str255[sizeof("CSVISCII")]; + char stringpool_str256[sizeof("CSISOLATIN2")]; + char stringpool_str257[sizeof("CSISOLATINCYRILLIC")]; + char stringpool_str258[sizeof("CSISOLATIN5")]; + char stringpool_str259[sizeof("GB18030")]; + char stringpool_str260[sizeof("ISO_8859-10")]; + char stringpool_str264[sizeof("CSKZ1048")]; + char stringpool_str266[sizeof("GB_1988-80")]; + char stringpool_str267[sizeof("KZ-1048")]; + char stringpool_str270[sizeof("MS-CYRL")]; + char stringpool_str275[sizeof("CHAR")]; + char stringpool_str276[sizeof("CSKOI8R")]; + char stringpool_str278[sizeof("ISO-IR-110")]; + char stringpool_str280[sizeof("KOI8-R")]; + char stringpool_str281[sizeof("MACCYRILLIC")]; + char stringpool_str282[sizeof("IBM-CP1133")]; + char stringpool_str283[sizeof("PTCP154")]; + char stringpool_str285[sizeof("CP874")]; + char stringpool_str289[sizeof("UTF-16")]; + char stringpool_str293[sizeof("ISO-IR-144")]; + char stringpool_str294[sizeof("UTF-8")]; + char stringpool_str295[sizeof("UTF-32")]; + char stringpool_str297[sizeof("KS_C_5601-1989")]; + char stringpool_str298[sizeof("HZ-GB-2312")]; + char stringpool_str304[sizeof("TIS620.2533-1")]; + char stringpool_str308[sizeof("CSUNICODE11")]; + char stringpool_str312[sizeof("UNICODE-1-1")]; + char stringpool_str314[sizeof("CSPTCP154")]; + char stringpool_str315[sizeof("CSUCS4")]; + char stringpool_str316[sizeof("CYRILLIC-ASIAN")]; + char stringpool_str319[sizeof("UCS-4")]; + char stringpool_str322[sizeof("TIS620.2529-1")]; + char stringpool_str324[sizeof("IBM850")]; + char stringpool_str327[sizeof("TIS620-0")]; + char stringpool_str330[sizeof("ISO-IR-179")]; + char stringpool_str332[sizeof("CP367")]; + char stringpool_str336[sizeof("ISO646-US")]; + char stringpool_str339[sizeof("ISO-10646-UCS-2")]; + char stringpool_str341[sizeof("CP1257")]; + char stringpool_str342[sizeof("GREEK8")]; + char stringpool_str343[sizeof("US-ASCII")]; + char stringpool_str347[sizeof("ISO-IR-100")]; + char stringpool_str352[sizeof("CSISOLATIN4")]; + char stringpool_str354[sizeof("CSISOLATINGREEK")]; + char stringpool_str356[sizeof("CSIBM866")]; + char stringpool_str359[sizeof("CSISO58GB231280")]; + char stringpool_str360[sizeof("EUCKR")]; + char stringpool_str361[sizeof("MS-ANSI")]; + char stringpool_str362[sizeof("MACTHAI")]; + char stringpool_str365[sizeof("CN-GB")]; + char stringpool_str366[sizeof("CSISOLATINARABIC")]; + char stringpool_str368[sizeof("CN-GB-ISOIR165")]; + char stringpool_str369[sizeof("ARMSCII-8")]; + char stringpool_str370[sizeof("MACINTOSH")]; + char stringpool_str372[sizeof("LATIN7")]; + char stringpool_str373[sizeof("TIS620.2533-0")]; + char stringpool_str374[sizeof("EUC-KR")]; + char stringpool_str375[sizeof("VISCII1.1-1")]; + char stringpool_str381[sizeof("JP")]; + char stringpool_str385[sizeof("ROMAN8")]; + char stringpool_str386[sizeof("ISO-2022-KR")]; + char stringpool_str387[sizeof("ISO-10646-UCS-4")]; + char stringpool_str393[sizeof("ISO8859-7")]; + char stringpool_str395[sizeof("CHINESE")]; + char stringpool_str397[sizeof("GEORGIAN-ACADEMY")]; + char stringpool_str398[sizeof("CSUNICODE")]; + char stringpool_str400[sizeof("WINDOWS-1251")]; + char stringpool_str401[sizeof("WINDOWS-1256")]; + char stringpool_str402[sizeof("WINDOWS-1253")]; + char stringpool_str403[sizeof("WINDOWS-1252")]; + char stringpool_str404[sizeof("WINDOWS-1255")]; + char stringpool_str406[sizeof("WINDOWS-1258")]; + char stringpool_str407[sizeof("ISO-8859-7")]; + char stringpool_str410[sizeof("KOI8-U")]; + char stringpool_str411[sizeof("CSPC862LATINHEBREW")]; + char stringpool_str412[sizeof("EUCTW")]; + char stringpool_str413[sizeof("ARABIC")]; + char stringpool_str414[sizeof("CSISO2022KR")]; + char stringpool_str415[sizeof("WINDOWS-936")]; + char stringpool_str416[sizeof("GREEK")]; + char stringpool_str417[sizeof("MULELAO-1")]; + char stringpool_str418[sizeof("ECMA-118")]; + char stringpool_str420[sizeof("TCVN-5712")]; + char stringpool_str421[sizeof("ISO_8859-7")]; + char stringpool_str422[sizeof("TCVN5712-1")]; + char stringpool_str425[sizeof("ISO_8859-3:1988")]; + char stringpool_str426[sizeof("EUC-TW")]; + char stringpool_str427[sizeof("ISO_8859-5:1988")]; + char stringpool_str428[sizeof("MACICELAND")]; + char stringpool_str429[sizeof("ISO_8859-8:1988")]; + char stringpool_str430[sizeof("KS_C_5601-1987")]; + char stringpool_str432[sizeof("KOREAN")]; + char stringpool_str433[sizeof("UCS-2LE")]; + char stringpool_str437[sizeof("CSISOLATINHEBREW")]; + char stringpool_str439[sizeof("CSKSC56011987")]; + char stringpool_str441[sizeof("UNICODELITTLE")]; + char stringpool_str442[sizeof("GEORGIAN-PS")]; + char stringpool_str443[sizeof("ISO-IR-57")]; + char stringpool_str445[sizeof("ISO-IR-87")]; + char stringpool_str446[sizeof("JIS_C6226-1983")]; + char stringpool_str447[sizeof("ISO-IR-127")]; + char stringpool_str448[sizeof("ISO-IR-157")]; + char stringpool_str449[sizeof("DECKOREAN")]; + char stringpool_str451[sizeof("WINDOWS-1254")]; + char stringpool_str454[sizeof("CSISO57GB1988")]; + char stringpool_str455[sizeof("ISO_8859-9:1989")]; + char stringpool_str458[sizeof("HP-ROMAN8")]; + char stringpool_str464[sizeof("CSUNICODE11UTF7")]; + char stringpool_str465[sizeof("WCHAR_T")]; + char stringpool_str468[sizeof("UNICODEBIG")]; + char stringpool_str469[sizeof("WINDOWS-1250")]; + char stringpool_str470[sizeof("UNICODE-1-1-UTF-7")]; + char stringpool_str472[sizeof("UCS-2-INTERNAL")]; + char stringpool_str473[sizeof("ISO_646.IRV:1991")]; + char stringpool_str474[sizeof("ISO_8859-4:1988")]; + char stringpool_str476[sizeof("STRK1048-2002")]; + char stringpool_str480[sizeof("MS-EE")]; + char stringpool_str481[sizeof("UCS-4LE")]; + char stringpool_str483[sizeof("IBM367")]; + char stringpool_str487[sizeof("KOI8-RU")]; + char stringpool_str491[sizeof("CSMACINTOSH")]; + char stringpool_str497[sizeof("BIG5HKSCS")]; + char stringpool_str500[sizeof("NEXTSTEP")]; + char stringpool_str501[sizeof("UTF-16LE")]; + char stringpool_str504[sizeof("CSISO14JISC6220RO")]; + char stringpool_str505[sizeof("UTF-32LE")]; + char stringpool_str507[sizeof("CSEUCKR")]; + char stringpool_str508[sizeof("ECMA-114")]; + char stringpool_str511[sizeof("BIG5-HKSCS")]; + char stringpool_str513[sizeof("ANSI_X3.4-1986")]; + char stringpool_str515[sizeof("JIS_C6220-1969-RO")]; + char stringpool_str518[sizeof("ANSI_X3.4-1968")]; + char stringpool_str520[sizeof("UCS-4-INTERNAL")]; + char stringpool_str523[sizeof("CSPC850MULTILINGUAL")]; + char stringpool_str524[sizeof("ISO-2022-JP-1")]; + char stringpool_str525[sizeof("CSHPROMAN8")]; + char stringpool_str527[sizeof("ISO-2022-JP-2")]; + char stringpool_str534[sizeof("JIS0208")]; + char stringpool_str539[sizeof("ASMO-708")]; + char stringpool_str543[sizeof("MACROMAN")]; + char stringpool_str544[sizeof("MACCROATIAN")]; + char stringpool_str548[sizeof("CSISO159JISX02121990")]; + char stringpool_str549[sizeof("ISO646-JP")]; + char stringpool_str552[sizeof("WINDOWS-1257")]; + char stringpool_str554[sizeof("CSISO2022JP2")]; + char stringpool_str559[sizeof("CSEUCTW")]; + char stringpool_str567[sizeof("EUCJP")]; + char stringpool_str569[sizeof("ISO_8859-1:1987")]; + char stringpool_str570[sizeof("ISO_8859-6:1987")]; + char stringpool_str571[sizeof("ISO_8859-7:2003")]; + char stringpool_str572[sizeof("ISO_8859-2:1987")]; + char stringpool_str581[sizeof("EUC-JP")]; + char stringpool_str586[sizeof("UTF-7")]; + char stringpool_str591[sizeof("UCS-2BE")]; + char stringpool_str593[sizeof("ISO-2022-JP")]; + char stringpool_str602[sizeof("MS-TURK")]; + char stringpool_str608[sizeof("JIS_X0212")]; + char stringpool_str621[sizeof("CSISO2022JP")]; + char stringpool_str624[sizeof("SHIFT-JIS")]; + char stringpool_str638[sizeof("SHIFT_JIS")]; + char stringpool_str639[sizeof("UCS-4BE")]; + char stringpool_str644[sizeof("MS-HEBR")]; + char stringpool_str646[sizeof("MACARABIC")]; + char stringpool_str649[sizeof("MACGREEK")]; + char stringpool_str652[sizeof("WINDOWS-874")]; + char stringpool_str653[sizeof("CSHALFWIDTHKATAKANA")]; + char stringpool_str658[sizeof("MS-GREEK")]; + char stringpool_str659[sizeof("UTF-16BE")]; + char stringpool_str661[sizeof("MACTURKISH")]; + char stringpool_str663[sizeof("UTF-32BE")]; + char stringpool_str669[sizeof("CSSHIFTJIS")]; + char stringpool_str671[sizeof("JIS_X0201")]; + char stringpool_str678[sizeof("HEBREW")]; + char stringpool_str683[sizeof("JIS_X0208")]; + char stringpool_str685[sizeof("BIGFIVE")]; + char stringpool_str689[sizeof("JISX0201-1976")]; + char stringpool_str695[sizeof("UCS-2-SWAPPED")]; + char stringpool_str696[sizeof("JIS_X0212-1990")]; + char stringpool_str699[sizeof("BIG-FIVE")]; + char stringpool_str701[sizeof("JIS_X0208-1983")]; + char stringpool_str702[sizeof("EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE")]; + char stringpool_str707[sizeof("SDECKANJI")]; + char stringpool_str711[sizeof("JAVA")]; + char stringpool_str721[sizeof("ISO_8859-7:1987")]; + char stringpool_str724[sizeof("TCVN5712-1:1993")]; + char stringpool_str725[sizeof("MS_KANJI")]; + char stringpool_str727[sizeof("MACCENTRALEUROPE")]; + char stringpool_str731[sizeof("CSISO87JISX0208")]; + char stringpool_str743[sizeof("UCS-4-SWAPPED")]; + char stringpool_str761[sizeof("MACROMANIA")]; + char stringpool_str765[sizeof("BIG5-HKSCS:2001")]; + char stringpool_str768[sizeof("JIS_X0208-1990")]; + char stringpool_str771[sizeof("BIG5-HKSCS:2008")]; + char stringpool_str784[sizeof("BIG5-HKSCS:1999")]; + char stringpool_str785[sizeof("JIS_X0212.1990-0")]; + char stringpool_str806[sizeof("MS-ARAB")]; + char stringpool_str807[sizeof("JOHAB")]; + char stringpool_str816[sizeof("BIG5-HKSCS:2004")]; + char stringpool_str821[sizeof("MACUKRAINE")]; + char stringpool_str842[sizeof("CSEUCPKDFMTJAPANESE")]; + char stringpool_str857[sizeof("WINBALTRIM")]; + char stringpool_str939[sizeof("MACHEBREW")]; + }; +static const struct stringpool_t stringpool_contents = + { + "L1", + "L6", + "L3", + "L2", + "L5", + "L8", + "866", + "CN", + "862", + "CP1131", + "CP1361", + "CP866", + "CP1133", + "CP1251", + "CP862", + "CP1256", + "CP1253", + "CP1252", + "CP1255", + "CP936", + "CP1258", + "GB2312", + "CP932", + "C99", + "HZ", + "L4", + "LATIN1", + "CP819", + "LATIN6", + "LATIN3", + "LATIN2", + "LATIN5", + "LATIN8", + "R8", + "ISO8859-1", + "ISO8859-6", + "ISO8859-3", + "ISO8859-11", + "ISO8859-2", + "ISO8859-16", + "ISO8859-5", + "ISO8859-13", + "ISO8859-8", + "ISO8859-15", + "ISO-8859-1", + "ISO-8859-6", + "ISO-8859-3", + "ISO-8859-11", + "ISO-8859-2", + "ISO-8859-16", + "ISO-8859-5", + "ISO-8859-13", + "ISO-8859-8", + "ISO-8859-15", + "ISO_8859-1", + "CYRILLIC", + "ISO_8859-6", + "LATIN-9", + "ISO_8859-3", + "ISO_8859-11", + "ISO_8859-2", + "ISO_8859-16", + "ISO_8859-5", + "ISO_8859-13", + "ISO8859-9", + "ISO_8859-16:2001", + "ISO_8859-8", + "ISO_8859-15", + "CP154", + "ISO-IR-6", + "CP949", + "ISO646-CN", + "ASCII", + "ISO_8859-15:1998", + "CP1254", + "ISO-8859-9", + "ISO-IR-166", + "ISO-IR-126", + "ISO-IR-226", + "ISO-IR-165", + "X0212", + "ISO-IR-58", + "UHC", + "EUCCN", + "ISO-IR-138", + "ISO_8859-9", + "L10", + "SJIS", + "850", + "MAC", + "TACTIS", + "L7", + "EUC-CN", + "LATIN4", + "CP850", + "CP1250", + "KOI8-T", + "ISO-2022-CN", + "ISO-IR-159", + "ISO-CELTIC", + "ISO_8859-14:1998", + "IBM866", + "CP950", + "IBM862", + "ISO-2022-CN-EXT", + "ISO8859-4", + "CSASCII", + "US", + "MS936", + "ISO8859-14", + "ISO-IR-199", + "BIG5", + "ISO_8859-10:1992", + "KSC5601", + "PT154", + "ISO-IR-148", + "ISO-8859-4", + "GBK", + "CSISO2022CN", + "CSBIG5", + "ISO-IR-101", + "ISO-8859-14", + "LATIN10", + "BIG-5", + "X0201", + "ISO-IR-203", + "DECHANZI", + "ELOT_928", + "ISO_8859-4", + "IBM819", + "CSGB2312", + "CN-BIG5", + "UCS-2", + "ISO_8859-14", + "X0208", + "KSC_5601", + "ISO-IR-149", + "ISO8859-10", + "RK1048", + "ISO-IR-14", + "TCVN", + "TIS620", + "GB_2312-80", + "VISCII", + "ISO-8859-10", + "ISO-IR-109", + "CSISOLATIN1", + "CSISOLATIN6", + "TIS-620", + "CSISOLATIN3", + "CSVISCII", + "CSISOLATIN2", + "CSISOLATINCYRILLIC", + "CSISOLATIN5", + "GB18030", + "ISO_8859-10", + "CSKZ1048", + "GB_1988-80", + "KZ-1048", + "MS-CYRL", + "CHAR", + "CSKOI8R", + "ISO-IR-110", + "KOI8-R", + "MACCYRILLIC", + "IBM-CP1133", + "PTCP154", + "CP874", + "UTF-16", + "ISO-IR-144", + "UTF-8", + "UTF-32", + "KS_C_5601-1989", + "HZ-GB-2312", + "TIS620.2533-1", + "CSUNICODE11", + "UNICODE-1-1", + "CSPTCP154", + "CSUCS4", + "CYRILLIC-ASIAN", + "UCS-4", + "TIS620.2529-1", + "IBM850", + "TIS620-0", + "ISO-IR-179", + "CP367", + "ISO646-US", + "ISO-10646-UCS-2", + "CP1257", + "GREEK8", + "US-ASCII", + "ISO-IR-100", + "CSISOLATIN4", + "CSISOLATINGREEK", + "CSIBM866", + "CSISO58GB231280", + "EUCKR", + "MS-ANSI", + "MACTHAI", + "CN-GB", + "CSISOLATINARABIC", + "CN-GB-ISOIR165", + "ARMSCII-8", + "MACINTOSH", + "LATIN7", + "TIS620.2533-0", + "EUC-KR", + "VISCII1.1-1", + "JP", + "ROMAN8", + "ISO-2022-KR", + "ISO-10646-UCS-4", + "ISO8859-7", + "CHINESE", + "GEORGIAN-ACADEMY", + "CSUNICODE", + "WINDOWS-1251", + "WINDOWS-1256", + "WINDOWS-1253", + "WINDOWS-1252", + "WINDOWS-1255", + "WINDOWS-1258", + "ISO-8859-7", + "KOI8-U", + "CSPC862LATINHEBREW", + "EUCTW", + "ARABIC", + "CSISO2022KR", + "WINDOWS-936", + "GREEK", + "MULELAO-1", + "ECMA-118", + "TCVN-5712", + "ISO_8859-7", + "TCVN5712-1", + "ISO_8859-3:1988", + "EUC-TW", + "ISO_8859-5:1988", + "MACICELAND", + "ISO_8859-8:1988", + "KS_C_5601-1987", + "KOREAN", + "UCS-2LE", + "CSISOLATINHEBREW", + "CSKSC56011987", + "UNICODELITTLE", + "GEORGIAN-PS", + "ISO-IR-57", + "ISO-IR-87", + "JIS_C6226-1983", + "ISO-IR-127", + "ISO-IR-157", + "DECKOREAN", + "WINDOWS-1254", + "CSISO57GB1988", + "ISO_8859-9:1989", + "HP-ROMAN8", + "CSUNICODE11UTF7", + "WCHAR_T", + "UNICODEBIG", + "WINDOWS-1250", + "UNICODE-1-1-UTF-7", + "UCS-2-INTERNAL", + "ISO_646.IRV:1991", + "ISO_8859-4:1988", + "STRK1048-2002", + "MS-EE", + "UCS-4LE", + "IBM367", + "KOI8-RU", + "CSMACINTOSH", + "BIG5HKSCS", + "NEXTSTEP", + "UTF-16LE", + "CSISO14JISC6220RO", + "UTF-32LE", + "CSEUCKR", + "ECMA-114", + "BIG5-HKSCS", + "ANSI_X3.4-1986", + "JIS_C6220-1969-RO", + "ANSI_X3.4-1968", + "UCS-4-INTERNAL", + "CSPC850MULTILINGUAL", + "ISO-2022-JP-1", + "CSHPROMAN8", + "ISO-2022-JP-2", + "JIS0208", + "ASMO-708", + "MACROMAN", + "MACCROATIAN", + "CSISO159JISX02121990", + "ISO646-JP", + "WINDOWS-1257", + "CSISO2022JP2", + "CSEUCTW", + "EUCJP", + "ISO_8859-1:1987", + "ISO_8859-6:1987", + "ISO_8859-7:2003", + "ISO_8859-2:1987", + "EUC-JP", + "UTF-7", + "UCS-2BE", + "ISO-2022-JP", + "MS-TURK", + "JIS_X0212", + "CSISO2022JP", + "SHIFT-JIS", + "SHIFT_JIS", + "UCS-4BE", + "MS-HEBR", + "MACARABIC", + "MACGREEK", + "WINDOWS-874", + "CSHALFWIDTHKATAKANA", + "MS-GREEK", + "UTF-16BE", + "MACTURKISH", + "UTF-32BE", + "CSSHIFTJIS", + "JIS_X0201", + "HEBREW", + "JIS_X0208", + "BIGFIVE", + "JISX0201-1976", + "UCS-2-SWAPPED", + "JIS_X0212-1990", + "BIG-FIVE", + "JIS_X0208-1983", + "EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE", + "SDECKANJI", + "JAVA", + "ISO_8859-7:1987", + "TCVN5712-1:1993", + "MS_KANJI", + "MACCENTRALEUROPE", + "CSISO87JISX0208", + "UCS-4-SWAPPED", + "MACROMANIA", + "BIG5-HKSCS:2001", + "JIS_X0208-1990", + "BIG5-HKSCS:2008", + "BIG5-HKSCS:1999", + "JIS_X0212.1990-0", + "MS-ARAB", + "JOHAB", + "BIG5-HKSCS:2004", + "MACUKRAINE", + "CSEUCPKDFMTJAPANESE", + "WINBALTRIM", + "MACHEBREW" + }; +#define stringpool ((const char *) &stringpool_contents) + +static const struct alias aliases[] = + { + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 60 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str13, ei_iso8859_1}, +#line 134 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str14, ei_iso8859_10}, +#line 76 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str15, ei_iso8859_3}, +#line 68 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str16, ei_iso8859_2}, +#line 126 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str17, ei_iso8859_9}, + {-1}, +#line 151 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str19, ei_iso8859_14}, + {-1}, {-1}, {-1}, +#line 207 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str23, ei_cp866}, +#line 289 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str24, ei_iso646_cn}, + {-1}, {-1}, +#line 203 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str27, ei_cp862}, + {-1}, {-1}, {-1}, {-1}, +#line 209 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str32, ei_cp1131}, +#line 359 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str33, ei_johab}, +#line 205 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str34, ei_cp866}, + {-1}, +#line 244 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str36, ei_cp1133}, +#line 174 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str37, ei_cp1251}, +#line 201 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str38, ei_cp862}, +#line 189 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str39, ei_cp1256}, + {-1}, +#line 180 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str41, ei_cp1253}, + {-1}, +#line 177 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str43, ei_cp1252}, + {-1}, +#line 186 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str45, ei_cp1255}, + {-1}, {-1}, +#line 326 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str48, ei_cp936}, +#line 195 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str49, ei_cp1258}, +#line 321 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str50, ei_euc_cn}, + {-1}, +#line 313 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str52, ei_cp932}, +#line 51 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str53, ei_c99}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 333 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str60, ei_hz}, + {-1}, {-1}, {-1}, +#line 84 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str64, ei_iso8859_4}, + {-1}, {-1}, {-1}, +#line 59 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str68, ei_iso8859_1}, +#line 57 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str69, ei_iso8859_1}, +#line 133 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str70, ei_iso8859_10}, + {-1}, +#line 75 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str72, ei_iso8859_3}, + {-1}, +#line 67 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str74, ei_iso8859_2}, + {-1}, +#line 125 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str76, ei_iso8859_9}, + {-1}, {-1}, {-1}, +#line 150 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str80, ei_iso8859_14}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 227 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str88, ei_hp_roman8}, +#line 62 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str89, ei_iso8859_1}, + {-1}, +#line 102 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str91, ei_iso8859_6}, + {-1}, +#line 78 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str93, ei_iso8859_3}, +#line 139 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str94, ei_iso8859_11}, +#line 70 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str95, ei_iso8859_2}, +#line 166 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str96, ei_iso8859_16}, +#line 93 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str97, ei_iso8859_5}, +#line 145 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str98, ei_iso8859_13}, + {-1}, {-1}, +#line 120 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str101, ei_iso8859_8}, +#line 159 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str102, ei_iso8859_15}, +#line 53 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str103, ei_iso8859_1}, + {-1}, +#line 94 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str105, ei_iso8859_6}, + {-1}, +#line 71 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str107, ei_iso8859_3}, +#line 137 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str108, ei_iso8859_11}, +#line 63 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str109, ei_iso8859_2}, +#line 160 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str110, ei_iso8859_16}, +#line 87 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str111, ei_iso8859_5}, +#line 140 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str112, ei_iso8859_13}, + {-1}, {-1}, +#line 114 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str115, ei_iso8859_8}, +#line 154 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str116, ei_iso8859_15}, +#line 54 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str117, ei_iso8859_1}, +#line 91 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str118, ei_iso8859_5}, +#line 95 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str119, ei_iso8859_6}, +#line 158 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str120, ei_iso8859_15}, +#line 72 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str121, ei_iso8859_3}, +#line 138 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str122, ei_iso8859_11}, +#line 64 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str123, ei_iso8859_2}, +#line 161 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str124, ei_iso8859_16}, +#line 88 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str125, ei_iso8859_5}, +#line 141 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str126, ei_iso8859_13}, +#line 128 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str127, ei_iso8859_9}, +#line 162 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str128, ei_iso8859_16}, +#line 115 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str129, ei_iso8859_8}, +#line 155 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str130, ei_iso8859_15}, +#line 236 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str131, ei_pt154}, +#line 16 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str132, ei_ascii}, +#line 355 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str133, ei_cp949}, + {-1}, +#line 287 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str135, ei_iso646_cn}, +#line 13 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str136, ei_ascii}, +#line 156 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str137, ei_iso8859_15}, + {-1}, +#line 183 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str139, ei_cp1254}, + {-1}, +#line 121 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str141, ei_iso8859_9}, + {-1}, +#line 252 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str143, ei_tis620}, + {-1}, +#line 107 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str145, ei_iso8859_7}, + {-1}, {-1}, +#line 163 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str148, ei_iso8859_16}, +#line 295 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str149, ei_isoir165}, +#line 283 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str150, ei_jisx0212}, +#line 292 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str151, ei_gb2312}, +#line 356 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str152, ei_cp949}, +#line 320 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str153, ei_euc_cn}, +#line 117 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str154, ei_iso8859_8}, +#line 122 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str155, ei_iso8859_9}, +#line 165 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str156, ei_iso8859_16}, + {-1}, +#line 310 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str158, ei_sjis}, +#line 199 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str159, ei_cp850}, + {-1}, +#line 212 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str161, ei_mac_roman}, + {-1}, {-1}, +#line 253 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str164, ei_tis620}, +#line 144 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str165, ei_iso8859_13}, + {-1}, +#line 319 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str167, ei_euc_cn}, + {-1}, {-1}, +#line 83 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str170, ei_iso8859_4}, + {-1}, {-1}, +#line 197 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str173, ei_cp850}, + {-1}, +#line 171 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str175, ei_cp1250}, + {-1}, {-1}, +#line 233 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str178, ei_koi8_t}, +#line 330 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str179, ei_iso2022_cn}, + {-1}, {-1}, +#line 284 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str182, ei_jisx0212}, +#line 152 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str183, ei_iso8859_14}, +#line 148 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str184, ei_iso8859_14}, +#line 206 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str185, ei_cp866}, +#line 344 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str186, ei_cp950}, + {-1}, {-1}, +#line 202 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str189, ei_cp862}, +#line 332 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str190, ei_iso2022_cn_ext}, +#line 86 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str191, ei_iso8859_4}, +#line 22 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str192, ei_ascii}, +#line 21 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str193, ei_ascii}, +#line 327 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str194, ei_cp936}, + {-1}, +#line 153 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str196, ei_iso8859_14}, +#line 149 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str197, ei_iso8859_14}, +#line 338 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str198, ei_ces_big5}, +#line 131 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str199, ei_iso8859_10}, +#line 357 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str200, ei_cp949}, + {-1}, +#line 234 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str202, ei_pt154}, +#line 124 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str203, ei_iso8859_9}, + {-1}, +#line 79 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str205, ei_iso8859_4}, +#line 325 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str206, ei_ces_gbk}, +#line 331 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str207, ei_iso2022_cn}, +#line 343 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str208, ei_ces_big5}, +#line 66 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str209, ei_iso8859_2}, +#line 146 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str210, ei_iso8859_14}, +#line 164 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str211, ei_iso8859_16}, +#line 339 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str212, ei_ces_big5}, +#line 270 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str213, ei_jisx0201}, + {-1}, {-1}, +#line 157 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str216, ei_iso8859_15}, +#line 324 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str217, ei_euc_cn}, +#line 109 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str218, ei_iso8859_7}, +#line 80 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str219, ei_iso8859_4}, +#line 58 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str220, ei_iso8859_1}, +#line 323 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str221, ei_euc_cn}, +#line 342 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str222, ei_ces_big5}, +#line 24 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str223, ei_ucs2}, +#line 147 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str224, ei_iso8859_14}, +#line 276 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str225, ei_jisx0208}, + {-1}, {-1}, +#line 297 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str228, ei_ksc5601}, +#line 300 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str229, ei_ksc5601}, + {-1}, {-1}, +#line 136 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str232, ei_iso8859_10}, + {-1}, +#line 239 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str234, ei_rk1048}, + {-1}, {-1}, +#line 265 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str237, ei_iso646_jp}, +#line 259 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str238, ei_tcvn}, +#line 247 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str239, ei_tis620}, + {-1}, {-1}, {-1}, +#line 291 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str243, ei_gb2312}, + {-1}, +#line 256 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str245, ei_viscii}, +#line 129 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str246, ei_iso8859_10}, +#line 74 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str247, ei_iso8859_3}, + {-1}, {-1}, +#line 61 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str250, ei_iso8859_1}, + {-1}, +#line 135 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str252, ei_iso8859_10}, +#line 246 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str253, ei_tis620}, +#line 77 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str254, ei_iso8859_3}, +#line 258 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str255, ei_viscii}, +#line 69 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str256, ei_iso8859_2}, +#line 92 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str257, ei_iso8859_5}, +#line 127 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str258, ei_iso8859_9}, +#line 329 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str259, ei_gb18030}, +#line 130 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str260, ei_iso8859_10}, + {-1}, {-1}, {-1}, +#line 242 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str264, ei_rk1048}, + {-1}, +#line 286 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str266, ei_iso646_cn}, +#line 241 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str267, ei_rk1048}, + {-1}, {-1}, +#line 176 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str270, ei_cp1251}, + {-1}, {-1}, {-1}, {-1}, +#line 362 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str275, ei_local_char}, +#line 168 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str276, ei_koi8_r}, + {-1}, +#line 82 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str278, ei_iso8859_4}, + {-1}, +#line 167 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str280, ei_koi8_r}, +#line 218 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str281, ei_mac_cyrillic}, +#line 245 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str282, ei_cp1133}, +#line 235 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str283, ei_pt154}, + {-1}, +#line 254 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str285, ei_cp874}, + {-1}, {-1}, {-1}, +#line 38 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str289, ei_utf16}, + {-1}, {-1}, {-1}, +#line 90 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str293, ei_iso8859_5}, +#line 23 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str294, ei_utf8}, +#line 41 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str295, ei_utf32}, + {-1}, +#line 299 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str297, ei_ksc5601}, +#line 334 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str298, ei_hz}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 251 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str304, ei_tis620}, + {-1}, {-1}, {-1}, +#line 30 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str308, ei_ucs2be}, + {-1}, {-1}, {-1}, +#line 29 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str312, ei_ucs2be}, + {-1}, +#line 238 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str314, ei_pt154}, +#line 35 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str315, ei_ucs4}, +#line 237 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str316, ei_pt154}, + {-1}, {-1}, +#line 33 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str319, ei_ucs4}, + {-1}, {-1}, +#line 249 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str322, ei_tis620}, + {-1}, +#line 198 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str324, ei_cp850}, + {-1}, {-1}, +#line 248 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str327, ei_tis620}, + {-1}, {-1}, +#line 142 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str330, ei_iso8859_13}, + {-1}, +#line 19 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str332, ei_ascii}, + {-1}, {-1}, {-1}, +#line 14 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str336, ei_ascii}, + {-1}, {-1}, +#line 25 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str339, ei_ucs2}, + {-1}, +#line 192 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str341, ei_cp1257}, +#line 110 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str342, ei_iso8859_7}, +#line 12 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str343, ei_ascii}, + {-1}, {-1}, {-1}, +#line 56 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str347, ei_iso8859_1}, + {-1}, {-1}, {-1}, {-1}, +#line 85 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str352, ei_iso8859_4}, + {-1}, +#line 112 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str354, ei_iso8859_7}, + {-1}, +#line 208 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str356, ei_cp866}, + {-1}, {-1}, +#line 293 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str359, ei_gb2312}, +#line 352 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str360, ei_euc_kr}, +#line 179 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str361, ei_cp1252}, +#line 224 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str362, ei_mac_thai}, + {-1}, {-1}, +#line 322 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str365, ei_euc_cn}, +#line 101 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str366, ei_iso8859_6}, + {-1}, +#line 296 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str368, ei_isoir165}, +#line 230 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str369, ei_armscii_8}, +#line 211 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str370, ei_mac_roman}, + {-1}, +#line 143 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str372, ei_iso8859_13}, +#line 250 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str373, ei_tis620}, +#line 351 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str374, ei_euc_kr}, +#line 257 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str375, ei_viscii}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 266 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str381, ei_iso646_jp}, + {-1}, {-1}, {-1}, +#line 226 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str385, ei_hp_roman8}, +#line 360 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str386, ei_iso2022_kr}, +#line 34 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str387, ei_ucs4}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 113 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str393, ei_iso8859_7}, + {-1}, +#line 294 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str395, ei_gb2312}, + {-1}, +#line 231 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str397, ei_georgian_academy}, +#line 26 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str398, ei_ucs2}, + {-1}, +#line 175 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str400, ei_cp1251}, +#line 190 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str401, ei_cp1256}, +#line 181 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str402, ei_cp1253}, +#line 178 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str403, ei_cp1252}, +#line 187 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str404, ei_cp1255}, + {-1}, +#line 196 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str406, ei_cp1258}, +#line 103 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str407, ei_iso8859_7}, + {-1}, {-1}, +#line 169 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str410, ei_koi8_u}, +#line 204 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str411, ei_cp862}, +#line 336 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str412, ei_euc_tw}, +#line 100 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str413, ei_iso8859_6}, +#line 361 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str414, ei_iso2022_kr}, +#line 328 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str415, ei_cp936}, +#line 111 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str416, ei_iso8859_7}, +#line 243 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str417, ei_mulelao}, +#line 108 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str418, ei_iso8859_7}, + {-1}, +#line 260 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str420, ei_tcvn}, +#line 104 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str421, ei_iso8859_7}, +#line 261 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str422, ei_tcvn}, + {-1}, {-1}, +#line 73 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str425, ei_iso8859_3}, +#line 335 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str426, ei_euc_tw}, +#line 89 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str427, ei_iso8859_5}, +#line 215 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str428, ei_mac_iceland}, +#line 116 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str429, ei_iso8859_8}, +#line 298 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str430, ei_ksc5601}, + {-1}, +#line 302 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str432, ei_ksc5601}, +#line 31 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str433, ei_ucs2le}, + {-1}, {-1}, {-1}, +#line 119 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str437, ei_iso8859_8}, + {-1}, +#line 301 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str439, ei_ksc5601}, + {-1}, +#line 32 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str441, ei_ucs2le}, +#line 232 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str442, ei_georgian_ps}, +#line 288 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str443, ei_iso646_cn}, + {-1}, +#line 277 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str445, ei_jisx0208}, +#line 278 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str446, ei_jisx0208}, +#line 97 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str447, ei_iso8859_6}, +#line 132 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str448, ei_iso8859_10}, +#line 354 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str449, ei_euc_kr}, + {-1}, +#line 184 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str451, ei_cp1254}, + {-1}, {-1}, +#line 290 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str454, ei_iso646_cn}, +#line 123 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str455, ei_iso8859_9}, + {-1}, {-1}, +#line 225 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str458, ei_hp_roman8}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 46 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str464, ei_utf7}, +#line 363 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str465, ei_local_wchar_t}, + {-1}, {-1}, +#line 28 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str468, ei_ucs2be}, +#line 172 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str469, ei_cp1250}, +#line 45 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str470, ei_utf7}, + {-1}, +#line 47 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str472, ei_ucs2internal}, +#line 15 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str473, ei_ascii}, +#line 81 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str474, ei_iso8859_4}, + {-1}, +#line 240 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str476, ei_rk1048}, + {-1}, {-1}, {-1}, +#line 173 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str480, ei_cp1250}, +#line 37 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str481, ei_ucs4le}, + {-1}, +#line 20 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str483, ei_ascii}, + {-1}, {-1}, {-1}, +#line 170 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str487, ei_koi8_ru}, + {-1}, {-1}, {-1}, +#line 213 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str491, ei_mac_roman}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 349 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str497, ei_big5hkscs2008}, + {-1}, {-1}, +#line 229 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str500, ei_nextstep}, +#line 40 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str501, ei_utf16le}, + {-1}, {-1}, +#line 267 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str504, ei_iso646_jp}, +#line 43 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str505, ei_utf32le}, + {-1}, +#line 353 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str507, ei_euc_kr}, +#line 98 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str508, ei_iso8859_6}, + {-1}, {-1}, +#line 348 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str511, ei_big5hkscs2008}, + {-1}, +#line 18 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str513, ei_ascii}, + {-1}, +#line 263 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str515, ei_iso646_jp}, + {-1}, {-1}, +#line 17 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str518, ei_ascii}, + {-1}, +#line 49 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str520, ei_ucs4internal}, + {-1}, {-1}, +#line 200 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str523, ei_cp850}, +#line 316 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str524, ei_iso2022_jp1}, +#line 228 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str525, ei_hp_roman8}, + {-1}, +#line 317 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str527, ei_iso2022_jp2}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 275 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str534, ei_jisx0208}, + {-1}, {-1}, {-1}, {-1}, +#line 99 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str539, ei_iso8859_6}, + {-1}, {-1}, {-1}, +#line 210 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str543, ei_mac_roman}, +#line 216 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str544, ei_mac_croatian}, + {-1}, {-1}, {-1}, +#line 285 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str548, ei_jisx0212}, +#line 264 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str549, ei_iso646_jp}, + {-1}, {-1}, +#line 193 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str552, ei_cp1257}, + {-1}, +#line 318 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str554, ei_iso2022_jp2}, + {-1}, {-1}, {-1}, {-1}, +#line 337 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str559, ei_euc_tw}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 304 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str567, ei_euc_jp}, + {-1}, +#line 55 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str569, ei_iso8859_1}, +#line 96 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str570, ei_iso8859_6}, +#line 106 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str571, ei_iso8859_7}, +#line 65 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str572, ei_iso8859_2}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 303 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str581, ei_euc_jp}, + {-1}, {-1}, {-1}, {-1}, +#line 44 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str586, ei_utf7}, + {-1}, {-1}, {-1}, {-1}, +#line 27 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str591, ei_ucs2be}, + {-1}, +#line 314 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str593, ei_iso2022_jp}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 185 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str602, ei_cp1254}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 280 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str608, ei_jisx0212}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 315 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str621, ei_iso2022_jp}, + {-1}, {-1}, +#line 309 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str624, ei_sjis}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 308 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str638, ei_sjis}, +#line 36 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str639, ei_ucs4be}, + {-1}, {-1}, {-1}, {-1}, +#line 188 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str644, ei_cp1255}, + {-1}, +#line 223 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str646, ei_mac_arabic}, + {-1}, {-1}, +#line 220 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str649, ei_mac_greek}, + {-1}, {-1}, +#line 255 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str652, ei_cp874}, +#line 271 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str653, ei_jisx0201}, + {-1}, {-1}, {-1}, {-1}, +#line 182 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str658, ei_cp1253}, +#line 39 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str659, ei_utf16be}, + {-1}, +#line 221 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str661, ei_mac_turkish}, + {-1}, +#line 42 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str663, ei_utf32be}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 312 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str669, ei_sjis}, + {-1}, +#line 268 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str671, ei_jisx0201}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 118 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str678, ei_iso8859_8}, + {-1}, {-1}, {-1}, {-1}, +#line 272 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str683, ei_jisx0208}, + {-1}, +#line 341 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str685, ei_ces_big5}, + {-1}, {-1}, {-1}, +#line 269 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str689, ei_jisx0201}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 48 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str695, ei_ucs2swapped}, +#line 282 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str696, ei_jisx0212}, + {-1}, {-1}, +#line 340 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str699, ei_ces_big5}, + {-1}, +#line 273 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str701, ei_jisx0208}, +#line 305 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str702, ei_euc_jp}, + {-1}, {-1}, {-1}, {-1}, +#line 307 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str707, ei_euc_jp}, + {-1}, {-1}, {-1}, +#line 52 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str711, ei_java}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 105 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str721, ei_iso8859_7}, + {-1}, {-1}, +#line 262 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str724, ei_tcvn}, +#line 311 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str725, ei_sjis}, + {-1}, +#line 214 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str727, ei_mac_centraleurope}, + {-1}, {-1}, {-1}, +#line 279 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str731, ei_jisx0208}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 50 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str743, ei_ucs4swapped}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 217 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str761, ei_mac_romania}, + {-1}, {-1}, {-1}, +#line 346 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str765, ei_big5hkscs2001}, + {-1}, {-1}, +#line 274 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str768, ei_jisx0208}, + {-1}, {-1}, +#line 350 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str771, ei_big5hkscs2008}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 345 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str784, ei_big5hkscs1999}, +#line 281 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str785, ei_jisx0212}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 191 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str806, ei_cp1256}, +#line 358 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str807, ei_johab}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 347 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str816, ei_big5hkscs2004}, + {-1}, {-1}, {-1}, {-1}, +#line 219 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str821, ei_mac_ukraine}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 306 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str842, ei_euc_jp}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 194 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str857, ei_cp1257}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 222 "lib/aliases_sysosf1.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str939, ei_mac_hebrew} + }; + +#ifdef __GNUC__ +__inline +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct alias * +aliases_lookup (register const char *str, register unsigned int len) +{ + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = aliases_hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int o = aliases[key].name; + if (o >= 0) + { + register const char *s = o + stringpool; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &aliases[key]; + } + } + } + return 0; +} diff --git a/libs/libiconv/lib/aliases_syssolaris.gperf b/libs/libiconv/lib/aliases_syssolaris.gperf new file mode 100644 index 00000000..fe7aba71 --- /dev/null +++ b/libs/libiconv/lib/aliases_syssolaris.gperf @@ -0,0 +1,365 @@ +struct alias { int name; unsigned int encoding_index; }; +%struct-type +%language=ANSI-C +%define hash-function-name aliases_hash +%define lookup-function-name aliases_lookup +%7bit +%readonly-tables +%global-table +%define word-array-name aliases +%pic +%% +US-ASCII, ei_ascii +ASCII, ei_ascii +ISO646-US, ei_ascii +ISO_646.IRV:1991, ei_ascii +ISO-IR-6, ei_ascii +ANSI_X3.4-1968, ei_ascii +ANSI_X3.4-1986, ei_ascii +CP367, ei_ascii +IBM367, ei_ascii +US, ei_ascii +CSASCII, ei_ascii +646, ei_ascii +UTF-8, ei_utf8 +UCS-2, ei_ucs2 +ISO-10646-UCS-2, ei_ucs2 +CSUNICODE, ei_ucs2 +UCS-2BE, ei_ucs2be +UNICODEBIG, ei_ucs2be +UNICODE-1-1, ei_ucs2be +CSUNICODE11, ei_ucs2be +UCS-2LE, ei_ucs2le +UNICODELITTLE, ei_ucs2le +UCS-4, ei_ucs4 +ISO-10646-UCS-4, ei_ucs4 +CSUCS4, ei_ucs4 +UCS-4BE, ei_ucs4be +UCS-4LE, ei_ucs4le +UTF-16, ei_utf16 +UTF-16BE, ei_utf16be +UTF-16LE, ei_utf16le +UTF-32, ei_utf32 +UTF-32BE, ei_utf32be +UTF-32LE, ei_utf32le +UTF-7, ei_utf7 +UNICODE-1-1-UTF-7, ei_utf7 +CSUNICODE11UTF7, ei_utf7 +UCS-2-INTERNAL, ei_ucs2internal +UCS-2-SWAPPED, ei_ucs2swapped +UCS-4-INTERNAL, ei_ucs4internal +UCS-4-SWAPPED, ei_ucs4swapped +C99, ei_c99 +JAVA, ei_java +ISO-8859-1, ei_iso8859_1 +ISO_8859-1, ei_iso8859_1 +ISO_8859-1:1987, ei_iso8859_1 +ISO-IR-100, ei_iso8859_1 +CP819, ei_iso8859_1 +IBM819, ei_iso8859_1 +LATIN1, ei_iso8859_1 +L1, ei_iso8859_1 +CSISOLATIN1, ei_iso8859_1 +ISO8859-1, ei_iso8859_1 +ISO-8859-2, ei_iso8859_2 +ISO_8859-2, ei_iso8859_2 +ISO_8859-2:1987, ei_iso8859_2 +ISO-IR-101, ei_iso8859_2 +LATIN2, ei_iso8859_2 +L2, ei_iso8859_2 +CSISOLATIN2, ei_iso8859_2 +ISO8859-2, ei_iso8859_2 +ISO-8859-3, ei_iso8859_3 +ISO_8859-3, ei_iso8859_3 +ISO_8859-3:1988, ei_iso8859_3 +ISO-IR-109, ei_iso8859_3 +LATIN3, ei_iso8859_3 +L3, ei_iso8859_3 +CSISOLATIN3, ei_iso8859_3 +ISO8859-3, ei_iso8859_3 +ISO-8859-4, ei_iso8859_4 +ISO_8859-4, ei_iso8859_4 +ISO_8859-4:1988, ei_iso8859_4 +ISO-IR-110, ei_iso8859_4 +LATIN4, ei_iso8859_4 +L4, ei_iso8859_4 +CSISOLATIN4, ei_iso8859_4 +ISO8859-4, ei_iso8859_4 +ISO-8859-5, ei_iso8859_5 +ISO_8859-5, ei_iso8859_5 +ISO_8859-5:1988, ei_iso8859_5 +ISO-IR-144, ei_iso8859_5 +CYRILLIC, ei_iso8859_5 +CSISOLATINCYRILLIC, ei_iso8859_5 +ISO8859-5, ei_iso8859_5 +ISO-8859-6, ei_iso8859_6 +ISO_8859-6, ei_iso8859_6 +ISO_8859-6:1987, ei_iso8859_6 +ISO-IR-127, ei_iso8859_6 +ECMA-114, ei_iso8859_6 +ASMO-708, ei_iso8859_6 +ARABIC, ei_iso8859_6 +CSISOLATINARABIC, ei_iso8859_6 +ISO8859-6, ei_iso8859_6 +ISO-8859-7, ei_iso8859_7 +ISO_8859-7, ei_iso8859_7 +ISO_8859-7:1987, ei_iso8859_7 +ISO_8859-7:2003, ei_iso8859_7 +ISO-IR-126, ei_iso8859_7 +ECMA-118, ei_iso8859_7 +ELOT_928, ei_iso8859_7 +GREEK8, ei_iso8859_7 +GREEK, ei_iso8859_7 +CSISOLATINGREEK, ei_iso8859_7 +ISO8859-7, ei_iso8859_7 +ISO-8859-8, ei_iso8859_8 +ISO_8859-8, ei_iso8859_8 +ISO_8859-8:1988, ei_iso8859_8 +ISO-IR-138, ei_iso8859_8 +HEBREW, ei_iso8859_8 +CSISOLATINHEBREW, ei_iso8859_8 +ISO8859-8, ei_iso8859_8 +ISO-8859-9, ei_iso8859_9 +ISO_8859-9, ei_iso8859_9 +ISO_8859-9:1989, ei_iso8859_9 +ISO-IR-148, ei_iso8859_9 +LATIN5, ei_iso8859_9 +L5, ei_iso8859_9 +CSISOLATIN5, ei_iso8859_9 +ISO8859-9, ei_iso8859_9 +ISO-8859-10, ei_iso8859_10 +ISO_8859-10, ei_iso8859_10 +ISO_8859-10:1992, ei_iso8859_10 +ISO-IR-157, ei_iso8859_10 +LATIN6, ei_iso8859_10 +L6, ei_iso8859_10 +CSISOLATIN6, ei_iso8859_10 +ISO8859-10, ei_iso8859_10 +ISO-8859-11, ei_iso8859_11 +ISO_8859-11, ei_iso8859_11 +ISO8859-11, ei_iso8859_11 +ISO-8859-13, ei_iso8859_13 +ISO_8859-13, ei_iso8859_13 +ISO-IR-179, ei_iso8859_13 +LATIN7, ei_iso8859_13 +L7, ei_iso8859_13 +ISO8859-13, ei_iso8859_13 +ISO-8859-14, ei_iso8859_14 +ISO_8859-14, ei_iso8859_14 +ISO_8859-14:1998, ei_iso8859_14 +ISO-IR-199, ei_iso8859_14 +LATIN8, ei_iso8859_14 +L8, ei_iso8859_14 +ISO-CELTIC, ei_iso8859_14 +ISO8859-14, ei_iso8859_14 +ISO-8859-15, ei_iso8859_15 +ISO_8859-15, ei_iso8859_15 +ISO_8859-15:1998, ei_iso8859_15 +ISO-IR-203, ei_iso8859_15 +LATIN-9, ei_iso8859_15 +ISO8859-15, ei_iso8859_15 +ISO-8859-16, ei_iso8859_16 +ISO_8859-16, ei_iso8859_16 +ISO_8859-16:2001, ei_iso8859_16 +ISO-IR-226, ei_iso8859_16 +LATIN10, ei_iso8859_16 +L10, ei_iso8859_16 +ISO8859-16, ei_iso8859_16 +KOI8-R, ei_koi8_r +CSKOI8R, ei_koi8_r +KOI8-U, ei_koi8_u +KOI8-RU, ei_koi8_ru +CP1250, ei_cp1250 +WINDOWS-1250, ei_cp1250 +MS-EE, ei_cp1250 +CP1251, ei_cp1251 +WINDOWS-1251, ei_cp1251 +MS-CYRL, ei_cp1251 +ANSI-1251, ei_cp1251 +CP1252, ei_cp1252 +WINDOWS-1252, ei_cp1252 +MS-ANSI, ei_cp1252 +CP1253, ei_cp1253 +WINDOWS-1253, ei_cp1253 +MS-GREEK, ei_cp1253 +CP1254, ei_cp1254 +WINDOWS-1254, ei_cp1254 +MS-TURK, ei_cp1254 +CP1255, ei_cp1255 +WINDOWS-1255, ei_cp1255 +MS-HEBR, ei_cp1255 +CP1256, ei_cp1256 +WINDOWS-1256, ei_cp1256 +MS-ARAB, ei_cp1256 +CP1257, ei_cp1257 +WINDOWS-1257, ei_cp1257 +WINBALTRIM, ei_cp1257 +CP1258, ei_cp1258 +WINDOWS-1258, ei_cp1258 +CP850, ei_cp850 +IBM850, ei_cp850 +850, ei_cp850 +CSPC850MULTILINGUAL, ei_cp850 +CP862, ei_cp862 +IBM862, ei_cp862 +862, ei_cp862 +CSPC862LATINHEBREW, ei_cp862 +CP866, ei_cp866 +IBM866, ei_cp866 +866, ei_cp866 +CSIBM866, ei_cp866 +CP1131, ei_cp1131 +MACROMAN, ei_mac_roman +MACINTOSH, ei_mac_roman +MAC, ei_mac_roman +CSMACINTOSH, ei_mac_roman +MACCENTRALEUROPE, ei_mac_centraleurope +MACICELAND, ei_mac_iceland +MACCROATIAN, ei_mac_croatian +MACROMANIA, ei_mac_romania +MACCYRILLIC, ei_mac_cyrillic +MACUKRAINE, ei_mac_ukraine +MACGREEK, ei_mac_greek +MACTURKISH, ei_mac_turkish +MACHEBREW, ei_mac_hebrew +MACARABIC, ei_mac_arabic +MACTHAI, ei_mac_thai +HP-ROMAN8, ei_hp_roman8 +ROMAN8, ei_hp_roman8 +R8, ei_hp_roman8 +CSHPROMAN8, ei_hp_roman8 +NEXTSTEP, ei_nextstep +ARMSCII-8, ei_armscii_8 +GEORGIAN-ACADEMY, ei_georgian_academy +GEORGIAN-PS, ei_georgian_ps +KOI8-T, ei_koi8_t +PT154, ei_pt154 +PTCP154, ei_pt154 +CP154, ei_pt154 +CYRILLIC-ASIAN, ei_pt154 +CSPTCP154, ei_pt154 +RK1048, ei_rk1048 +STRK1048-2002, ei_rk1048 +KZ-1048, ei_rk1048 +CSKZ1048, ei_rk1048 +MULELAO-1, ei_mulelao +CP1133, ei_cp1133 +IBM-CP1133, ei_cp1133 +TIS-620, ei_tis620 +TIS620, ei_tis620 +TIS620-0, ei_tis620 +TIS620.2529-1, ei_tis620 +TIS620.2533-0, ei_tis620 +TIS620.2533-1, ei_tis620 +ISO-IR-166, ei_tis620 +TIS620.2533, ei_tis620 +CP874, ei_cp874 +WINDOWS-874, ei_cp874 +VISCII, ei_viscii +VISCII1.1-1, ei_viscii +CSVISCII, ei_viscii +TCVN, ei_tcvn +TCVN-5712, ei_tcvn +TCVN5712-1, ei_tcvn +TCVN5712-1:1993, ei_tcvn +JIS_C6220-1969-RO, ei_iso646_jp +ISO646-JP, ei_iso646_jp +ISO-IR-14, ei_iso646_jp +JP, ei_iso646_jp +CSISO14JISC6220RO, ei_iso646_jp +JIS_X0201, ei_jisx0201 +JISX0201-1976, ei_jisx0201 +X0201, ei_jisx0201 +CSHALFWIDTHKATAKANA, ei_jisx0201 +JIS_X0208, ei_jisx0208 +JIS_X0208-1983, ei_jisx0208 +JIS_X0208-1990, ei_jisx0208 +JIS0208, ei_jisx0208 +X0208, ei_jisx0208 +ISO-IR-87, ei_jisx0208 +JIS_C6226-1983, ei_jisx0208 +CSISO87JISX0208, ei_jisx0208 +JIS_X0212, ei_jisx0212 +JIS_X0212.1990-0, ei_jisx0212 +JIS_X0212-1990, ei_jisx0212 +X0212, ei_jisx0212 +ISO-IR-159, ei_jisx0212 +CSISO159JISX02121990, ei_jisx0212 +GB_1988-80, ei_iso646_cn +ISO646-CN, ei_iso646_cn +ISO-IR-57, ei_iso646_cn +CN, ei_iso646_cn +CSISO57GB1988, ei_iso646_cn +GB_2312-80, ei_gb2312 +ISO-IR-58, ei_gb2312 +CSISO58GB231280, ei_gb2312 +CHINESE, ei_gb2312 +ISO-IR-165, ei_isoir165 +CN-GB-ISOIR165, ei_isoir165 +KSC_5601, ei_ksc5601 +KS_C_5601-1987, ei_ksc5601 +KS_C_5601-1989, ei_ksc5601 +ISO-IR-149, ei_ksc5601 +CSKSC56011987, ei_ksc5601 +KOREAN, ei_ksc5601 +EUC-JP, ei_euc_jp +EUCJP, ei_euc_jp +EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE, ei_euc_jp +CSEUCPKDFMTJAPANESE, ei_euc_jp +SHIFT_JIS, ei_sjis +SHIFT-JIS, ei_sjis +SJIS, ei_sjis +MS_KANJI, ei_sjis +CSSHIFTJIS, ei_sjis +PCK, ei_sjis +CP932, ei_cp932 +ISO-2022-JP, ei_iso2022_jp +CSISO2022JP, ei_iso2022_jp +ISO-2022-JP-1, ei_iso2022_jp1 +ISO-2022-JP-2, ei_iso2022_jp2 +CSISO2022JP2, ei_iso2022_jp2 +EUC-CN, ei_euc_cn +EUCCN, ei_euc_cn +GB2312, ei_euc_cn +CN-GB, ei_euc_cn +CSGB2312, ei_euc_cn +GBK, ei_ces_gbk +CP936, ei_cp936 +MS936, ei_cp936 +WINDOWS-936, ei_cp936 +GB18030, ei_gb18030 +ISO-2022-CN, ei_iso2022_cn +CSISO2022CN, ei_iso2022_cn +ISO-2022-CN-EXT, ei_iso2022_cn_ext +HZ, ei_hz +HZ-GB-2312, ei_hz +EUC-TW, ei_euc_tw +EUCTW, ei_euc_tw +CSEUCTW, ei_euc_tw +CNS11643, ei_euc_tw +BIG5, ei_ces_big5 +BIG-5, ei_ces_big5 +BIG-FIVE, ei_ces_big5 +BIGFIVE, ei_ces_big5 +CN-BIG5, ei_ces_big5 +CSBIG5, ei_ces_big5 +CP950, ei_cp950 +BIG5-HKSCS:1999, ei_big5hkscs1999 +BIG5-HKSCS:2001, ei_big5hkscs2001 +BIG5-HKSCS:2004, ei_big5hkscs2004 +BIG5-HKSCS, ei_big5hkscs2008 +BIG5HKSCS, ei_big5hkscs2008 +BIG5-HKSCS:2008, ei_big5hkscs2008 +EUC-KR, ei_euc_kr +EUCKR, ei_euc_kr +CSEUCKR, ei_euc_kr +5601, ei_euc_kr +CP949, ei_cp949 +UHC, ei_cp949 +JOHAB, ei_johab +CP1361, ei_johab +KO_KR.JOHAP92, ei_johab +ISO-2022-KR, ei_iso2022_kr +CSISO2022KR, ei_iso2022_kr +CHAR, ei_local_char +WCHAR_T, ei_local_wchar_t diff --git a/libs/libiconv/lib/aliases_syssolaris.h b/libs/libiconv/lib/aliases_syssolaris.h new file mode 100644 index 00000000..c35d4f9b --- /dev/null +++ b/libs/libiconv/lib/aliases_syssolaris.h @@ -0,0 +1,1756 @@ +/* ANSI-C code produced by gperf version 3.0.4 */ +/* Command-line: gperf -m 10 lib/aliases_syssolaris.gperf */ +/* Computed positions: -k'1,3-11,$' */ + +#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \ + && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \ + && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \ + && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \ + && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \ + && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \ + && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \ + && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \ + && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \ + && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \ + && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \ + && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \ + && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \ + && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \ + && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \ + && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \ + && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \ + && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \ + && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \ + && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \ + && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \ + && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \ + && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126)) +/* The character set is not based on ISO-646. */ +#error "gperf generated tables don't work with this execution character set. Please report a bug to ." +#endif + +#line 1 "lib/aliases_syssolaris.gperf" +struct alias { int name; unsigned int encoding_index; }; + +#define TOTAL_KEYWORDS 354 +#define MIN_WORD_LENGTH 2 +#define MAX_WORD_LENGTH 45 +#define MIN_HASH_VALUE 8 +#define MAX_HASH_VALUE 1003 +/* maximum key range = 996, duplicates = 0 */ + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned int +aliases_hash (register const char *str, register unsigned int len) +{ + static const unsigned short asso_values[] = + { + 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, + 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, + 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, + 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, + 1004, 1004, 1004, 1004, 1004, 2, 112, 1004, 27, 4, + 34, 57, 16, 22, 11, 168, 3, 10, 254, 1004, + 1004, 1004, 1004, 1004, 1004, 21, 126, 7, 10, 37, + 40, 119, 81, 62, 332, 197, 9, 169, 4, 2, + 8, 1004, 3, 34, 104, 205, 191, 192, 195, 36, + 16, 1004, 1004, 1004, 1004, 3, 1004, 1004, 1004, 1004, + 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, + 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004, + 1004, 1004, 1004, 1004, 1004, 1004, 1004, 1004 + }; + register int hval = len; + + switch (hval) + { + default: + hval += asso_values[(unsigned char)str[10]]; + /*FALLTHROUGH*/ + case 10: + hval += asso_values[(unsigned char)str[9]]; + /*FALLTHROUGH*/ + case 9: + hval += asso_values[(unsigned char)str[8]]; + /*FALLTHROUGH*/ + case 8: + hval += asso_values[(unsigned char)str[7]]; + /*FALLTHROUGH*/ + case 7: + hval += asso_values[(unsigned char)str[6]]; + /*FALLTHROUGH*/ + case 6: + hval += asso_values[(unsigned char)str[5]]; + /*FALLTHROUGH*/ + case 5: + hval += asso_values[(unsigned char)str[4]]; + /*FALLTHROUGH*/ + case 4: + hval += asso_values[(unsigned char)str[3]]; + /*FALLTHROUGH*/ + case 3: + hval += asso_values[(unsigned char)str[2]]; + /*FALLTHROUGH*/ + case 2: + case 1: + hval += asso_values[(unsigned char)str[0]]; + break; + } + return hval + asso_values[(unsigned char)str[len - 1]]; +} + +struct stringpool_t + { + char stringpool_str8[sizeof("R8")]; + char stringpool_str13[sizeof("CN")]; + char stringpool_str14[sizeof("L8")]; + char stringpool_str15[sizeof("L1")]; + char stringpool_str22[sizeof("L6")]; + char stringpool_str27[sizeof("L4")]; + char stringpool_str28[sizeof("866")]; + char stringpool_str30[sizeof("C99")]; + char stringpool_str33[sizeof("L5")]; + char stringpool_str36[sizeof("646")]; + char stringpool_str38[sizeof("CHAR")]; + char stringpool_str39[sizeof("CP819")]; + char stringpool_str45[sizeof("L2")]; + char stringpool_str48[sizeof("CP866")]; + char stringpool_str58[sizeof("CP949")]; + char stringpool_str60[sizeof("850")]; + char stringpool_str61[sizeof("5601")]; + char stringpool_str62[sizeof("RK1048")]; + char stringpool_str64[sizeof("EUCCN")]; + char stringpool_str66[sizeof("L10")]; + char stringpool_str67[sizeof("EUC-CN")]; + char stringpool_str68[sizeof("L3")]; + char stringpool_str70[sizeof("CP154")]; + char stringpool_str71[sizeof("PT154")]; + char stringpool_str74[sizeof("862")]; + char stringpool_str79[sizeof("CP1258")]; + char stringpool_str81[sizeof("CP1251")]; + char stringpool_str86[sizeof("CP1131")]; + char stringpool_str88[sizeof("PTCP154")]; + char stringpool_str91[sizeof("CP850")]; + char stringpool_str93[sizeof("CP1361")]; + char stringpool_str94[sizeof("CP862")]; + char stringpool_str95[sizeof("CP1256")]; + char stringpool_str98[sizeof("CP950")]; + char stringpool_str99[sizeof("HZ")]; + char stringpool_str101[sizeof("CP936")]; + char stringpool_str105[sizeof("CP1254")]; + char stringpool_str117[sizeof("CP1255")]; + char stringpool_str119[sizeof("ISO8859-8")]; + char stringpool_str121[sizeof("ISO8859-1")]; + char stringpool_str122[sizeof("ISO-8859-8")]; + char stringpool_str123[sizeof("ISO_8859-8")]; + char stringpool_str124[sizeof("ISO-8859-1")]; + char stringpool_str125[sizeof("ISO_8859-1")]; + char stringpool_str126[sizeof("ISO8859-11")]; + char stringpool_str127[sizeof("CP1250")]; + char stringpool_str128[sizeof("ISO646-CN")]; + char stringpool_str129[sizeof("ISO-8859-11")]; + char stringpool_str130[sizeof("ISO_8859-11")]; + char stringpool_str133[sizeof("ISO8859-9")]; + char stringpool_str135[sizeof("ISO8859-6")]; + char stringpool_str136[sizeof("ISO-8859-9")]; + char stringpool_str137[sizeof("ISO_8859-9")]; + char stringpool_str138[sizeof("ISO-8859-6")]; + char stringpool_str139[sizeof("ISO_8859-6")]; + char stringpool_str140[sizeof("ISO8859-16")]; + char stringpool_str141[sizeof("CP1252")]; + char stringpool_str142[sizeof("ISO_8859-16:2001")]; + char stringpool_str143[sizeof("ISO-8859-16")]; + char stringpool_str144[sizeof("ISO_8859-16")]; + char stringpool_str145[sizeof("ISO8859-4")]; + char stringpool_str146[sizeof("ISO_8859-14:1998")]; + char stringpool_str147[sizeof("CP932")]; + char stringpool_str148[sizeof("ISO-8859-4")]; + char stringpool_str149[sizeof("ISO_8859-4")]; + char stringpool_str150[sizeof("ISO8859-14")]; + char stringpool_str152[sizeof("ISO_8859-15:1998")]; + char stringpool_str153[sizeof("ISO-8859-14")]; + char stringpool_str154[sizeof("ISO_8859-14")]; + char stringpool_str157[sizeof("ISO8859-5")]; + char stringpool_str160[sizeof("ISO-8859-5")]; + char stringpool_str161[sizeof("ISO_8859-5")]; + char stringpool_str162[sizeof("ISO8859-15")]; + char stringpool_str163[sizeof("ISO-IR-6")]; + char stringpool_str165[sizeof("ISO-8859-15")]; + char stringpool_str166[sizeof("ISO_8859-15")]; + char stringpool_str168[sizeof("SJIS")]; + char stringpool_str169[sizeof("ISO-IR-148")]; + char stringpool_str170[sizeof("ISO-IR-58")]; + char stringpool_str172[sizeof("ISO8859-10")]; + char stringpool_str174[sizeof("CYRILLIC")]; + char stringpool_str175[sizeof("ISO-8859-10")]; + char stringpool_str176[sizeof("ISO_8859-10")]; + char stringpool_str177[sizeof("ISO-IR-199")]; + char stringpool_str178[sizeof("ISO-IR-14")]; + char stringpool_str179[sizeof("L7")]; + char stringpool_str180[sizeof("ISO-IR-166")]; + char stringpool_str181[sizeof("ISO8859-2")]; + char stringpool_str182[sizeof("ISO-IR-101")]; + char stringpool_str183[sizeof("ISO-IR-149")]; + char stringpool_str184[sizeof("ISO-8859-2")]; + char stringpool_str185[sizeof("ISO_8859-2")]; + char stringpool_str186[sizeof("MAC")]; + char stringpool_str187[sizeof("CP1253")]; + char stringpool_str188[sizeof("ISO_8859-10:1992")]; + char stringpool_str189[sizeof("ISO-IR-159")]; + char stringpool_str191[sizeof("LATIN8")]; + char stringpool_str192[sizeof("CP1133")]; + char stringpool_str193[sizeof("LATIN1")]; + char stringpool_str194[sizeof("ISO-IR-109")]; + char stringpool_str195[sizeof("ISO-IR-144")]; + char stringpool_str196[sizeof("ANSI-1251")]; + char stringpool_str198[sizeof("CNS11643")]; + char stringpool_str201[sizeof("CSPTCP154")]; + char stringpool_str202[sizeof("ISO-IR-165")]; + char stringpool_str203[sizeof("ISO-IR-126")]; + char stringpool_str204[sizeof("ELOT_928")]; + char stringpool_str205[sizeof("ISO-IR-110")]; + char stringpool_str207[sizeof("LATIN6")]; + char stringpool_str208[sizeof("LATIN-9")]; + char stringpool_str209[sizeof("ROMAN8")]; + char stringpool_str210[sizeof("ISO-IR-138")]; + char stringpool_str211[sizeof("GB_1988-80")]; + char stringpool_str215[sizeof("CP874")]; + char stringpool_str217[sizeof("LATIN4")]; + char stringpool_str219[sizeof("ASCII")]; + char stringpool_str222[sizeof("UHC")]; + char stringpool_str223[sizeof("ISO-2022-CN")]; + char stringpool_str225[sizeof("CHINESE")]; + char stringpool_str227[sizeof("ISO8859-3")]; + char stringpool_str228[sizeof("ISO-IR-100")]; + char stringpool_str229[sizeof("LATIN5")]; + char stringpool_str230[sizeof("ISO-8859-3")]; + char stringpool_str231[sizeof("ISO_8859-3")]; + char stringpool_str232[sizeof("ISO8859-13")]; + char stringpool_str233[sizeof("ISO-IR-226")]; + char stringpool_str234[sizeof("CYRILLIC-ASIAN")]; + char stringpool_str235[sizeof("ISO-8859-13")]; + char stringpool_str236[sizeof("ISO_8859-13")]; + char stringpool_str241[sizeof("US")]; + char stringpool_str242[sizeof("MS-CYRL")]; + char stringpool_str243[sizeof("TIS620")]; + char stringpool_str244[sizeof("LATIN10")]; + char stringpool_str246[sizeof("TIS-620")]; + char stringpool_str250[sizeof("ARABIC")]; + char stringpool_str251[sizeof("ECMA-118")]; + char stringpool_str252[sizeof("EUCKR")]; + char stringpool_str253[sizeof("LATIN2")]; + char stringpool_str255[sizeof("EUC-KR")]; + char stringpool_str258[sizeof("UTF-8")]; + char stringpool_str259[sizeof("KZ-1048")]; + char stringpool_str260[sizeof("CSISO2022CN")]; + char stringpool_str262[sizeof("CSASCII")]; + char stringpool_str263[sizeof("MS936")]; + char stringpool_str264[sizeof("IBM819")]; + char stringpool_str266[sizeof("MULELAO-1")]; + char stringpool_str267[sizeof("X0208")]; + char stringpool_str269[sizeof("X0201")]; + char stringpool_str271[sizeof("GB18030")]; + char stringpool_str272[sizeof("KOREAN")]; + char stringpool_str273[sizeof("IBM866")]; + char stringpool_str274[sizeof("TIS620-0")]; + char stringpool_str276[sizeof("KOI8-R")]; + char stringpool_str277[sizeof("ECMA-114")]; + char stringpool_str278[sizeof("UCS-4")]; + char stringpool_str279[sizeof("UTF-16")]; + char stringpool_str281[sizeof("CSKZ1048")]; + char stringpool_str283[sizeof("KSC_5601")]; + char stringpool_str284[sizeof("CSKOI8R")]; + char stringpool_str287[sizeof("MS-EE")]; + char stringpool_str288[sizeof("GB2312")]; + char stringpool_str291[sizeof("CSUCS4")]; + char stringpool_str293[sizeof("BIG5")]; + char stringpool_str296[sizeof("BIG-5")]; + char stringpool_str297[sizeof("HP-ROMAN8")]; + char stringpool_str299[sizeof("LATIN3")]; + char stringpool_str304[sizeof("KS_C_5601-1989")]; + char stringpool_str306[sizeof("X0212")]; + char stringpool_str307[sizeof("TCVN")]; + char stringpool_str309[sizeof("ISO-CELTIC")]; + char stringpool_str311[sizeof("CSHPROMAN8")]; + char stringpool_str314[sizeof("UCS-2")]; + char stringpool_str316[sizeof("IBM850")]; + char stringpool_str318[sizeof("ISO-IR-203")]; + char stringpool_str319[sizeof("IBM862")]; + char stringpool_str320[sizeof("GB_2312-80")]; + char stringpool_str324[sizeof("CSISOLATIN1")]; + char stringpool_str327[sizeof("ISO-2022-CN-EXT")]; + char stringpool_str335[sizeof("ISO-IR-179")]; + char stringpool_str337[sizeof("CSISOLATINCYRILLIC")]; + char stringpool_str338[sizeof("CSISOLATIN6")]; + char stringpool_str342[sizeof("JP")]; + char stringpool_str346[sizeof("MACICELAND")]; + char stringpool_str347[sizeof("UCS-4LE")]; + char stringpool_str348[sizeof("CSISOLATIN4")]; + char stringpool_str349[sizeof("CSISOLATINARABIC")]; + char stringpool_str350[sizeof("UNICODE-1-1")]; + char stringpool_str353[sizeof("UTF-16LE")]; + char stringpool_str357[sizeof("CSUNICODE11")]; + char stringpool_str360[sizeof("CSISOLATIN5")]; + char stringpool_str361[sizeof("MS-ANSI")]; + char stringpool_str364[sizeof("CSBIG5")]; + char stringpool_str365[sizeof("UCS-2LE")]; + char stringpool_str367[sizeof("CN-BIG5")]; + char stringpool_str372[sizeof("ARMSCII-8")]; + char stringpool_str373[sizeof("ISO-10646-UCS-4")]; + char stringpool_str378[sizeof("UTF-32")]; + char stringpool_str380[sizeof("CSUNICODE")]; + char stringpool_str382[sizeof("ISO_8859-8:1988")]; + char stringpool_str384[sizeof("CSISOLATIN2")]; + char stringpool_str385[sizeof("CN-GB")]; + char stringpool_str386[sizeof("ISO646-US")]; + char stringpool_str387[sizeof("MACROMAN")]; + char stringpool_str389[sizeof("MACCYRILLIC")]; + char stringpool_str391[sizeof("ISO-10646-UCS-2")]; + char stringpool_str394[sizeof("STRK1048-2002")]; + char stringpool_str395[sizeof("ISO_8859-4:1988")]; + char stringpool_str396[sizeof("ISO_8859-9:1989")]; + char stringpool_str397[sizeof("EUCJP")]; + char stringpool_str400[sizeof("EUC-JP")]; + char stringpool_str401[sizeof("ISO_8859-5:1988")]; + char stringpool_str402[sizeof("GREEK8")]; + char stringpool_str403[sizeof("ASMO-708")]; + char stringpool_str405[sizeof("PCK")]; + char stringpool_str408[sizeof("CSIBM866")]; + char stringpool_str409[sizeof("CP1257")]; + char stringpool_str411[sizeof("ISO-2022-KR")]; + char stringpool_str412[sizeof("GEORGIAN-ACADEMY")]; + char stringpool_str415[sizeof("MACCROATIAN")]; + char stringpool_str416[sizeof("CP367")]; + char stringpool_str419[sizeof("GEORGIAN-PS")]; + char stringpool_str423[sizeof("CSGB2312")]; + char stringpool_str424[sizeof("VISCII")]; + char stringpool_str428[sizeof("MS-HEBR")]; + char stringpool_str429[sizeof("UTF-32LE")]; + char stringpool_str430[sizeof("CSISOLATIN3")]; + char stringpool_str432[sizeof("MACARABIC")]; + char stringpool_str436[sizeof("ISO_8859-3:1988")]; + char stringpool_str437[sizeof("IBM-CP1133")]; + char stringpool_str439[sizeof("TIS620.2529-1")]; + char stringpool_str448[sizeof("CSISO2022KR")]; + char stringpool_str449[sizeof("ISO8859-7")]; + char stringpool_str451[sizeof("MACCENTRALEUROPE")]; + char stringpool_str452[sizeof("ISO-8859-7")]; + char stringpool_str453[sizeof("ISO_8859-7")]; + char stringpool_str455[sizeof("CN-GB-ISOIR165")]; + char stringpool_str461[sizeof("ISO646-JP")]; + char stringpool_str462[sizeof("KS_C_5601-1987")]; + char stringpool_str463[sizeof("US-ASCII")]; + char stringpool_str464[sizeof("UCS-4BE")]; + char stringpool_str466[sizeof("CSEUCKR")]; + char stringpool_str467[sizeof("JIS0208")]; + char stringpool_str470[sizeof("UTF-16BE")]; + char stringpool_str475[sizeof("MS-ARAB")]; + char stringpool_str476[sizeof("CSPC862LATINHEBREW")]; + char stringpool_str478[sizeof("KOI8-T")]; + char stringpool_str481[sizeof("ISO-IR-87")]; + char stringpool_str482[sizeof("UCS-2BE")]; + char stringpool_str489[sizeof("MACROMANIA")]; + char stringpool_str492[sizeof("UCS-4-INTERNAL")]; + char stringpool_str493[sizeof("ISO_646.IRV:1991")]; + char stringpool_str495[sizeof("CSVISCII")]; + char stringpool_str497[sizeof("VISCII1.1-1")]; + char stringpool_str500[sizeof("ISO-IR-57")]; + char stringpool_str502[sizeof("NEXTSTEP")]; + char stringpool_str503[sizeof("HZ-GB-2312")]; + char stringpool_str504[sizeof("CSKSC56011987")]; + char stringpool_str505[sizeof("ISO-IR-157")]; + char stringpool_str507[sizeof("JIS_C6220-1969-RO")]; + char stringpool_str508[sizeof("CSISO58GB231280")]; + char stringpool_str509[sizeof("TIS620.2533-1")]; + char stringpool_str510[sizeof("UCS-2-INTERNAL")]; + char stringpool_str511[sizeof("WINDOWS-1258")]; + char stringpool_str512[sizeof("WINDOWS-1251")]; + char stringpool_str513[sizeof("MACTHAI")]; + char stringpool_str515[sizeof("WCHAR_T")]; + char stringpool_str516[sizeof("GBK")]; + char stringpool_str517[sizeof("ISO-IR-127")]; + char stringpool_str519[sizeof("WINDOWS-1256")]; + char stringpool_str520[sizeof("UNICODE-1-1-UTF-7")]; + char stringpool_str521[sizeof("LATIN7")]; + char stringpool_str523[sizeof("ANSI_X3.4-1968")]; + char stringpool_str524[sizeof("WINDOWS-1254")]; + char stringpool_str525[sizeof("CSUNICODE11UTF7")]; + char stringpool_str530[sizeof("WINDOWS-1255")]; + char stringpool_str531[sizeof("ANSI_X3.4-1986")]; + char stringpool_str532[sizeof("TIS620.2533-0")]; + char stringpool_str533[sizeof("EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE")]; + char stringpool_str535[sizeof("WINDOWS-1250")]; + char stringpool_str536[sizeof("WINDOWS-936")]; + char stringpool_str537[sizeof("EUCTW")]; + char stringpool_str540[sizeof("EUC-TW")]; + char stringpool_str542[sizeof("WINDOWS-1252")]; + char stringpool_str543[sizeof("JIS_C6226-1983")]; + char stringpool_str545[sizeof("UCS-4-SWAPPED")]; + char stringpool_str546[sizeof("UTF-32BE")]; + char stringpool_str547[sizeof("TCVN5712-1")]; + char stringpool_str548[sizeof("ISO_8859-1:1987")]; + char stringpool_str553[sizeof("MACINTOSH")]; + char stringpool_str554[sizeof("ISO-2022-JP-1")]; + char stringpool_str555[sizeof("ISO_8859-6:1987")]; + char stringpool_str556[sizeof("ISO-2022-JP")]; + char stringpool_str560[sizeof("TIS620.2533")]; + char stringpool_str563[sizeof("UCS-2-SWAPPED")]; + char stringpool_str565[sizeof("WINDOWS-1253")]; + char stringpool_str569[sizeof("JAVA")]; + char stringpool_str570[sizeof("CSISO57GB1988")]; + char stringpool_str572[sizeof("TCVN-5712")]; + char stringpool_str578[sizeof("ISO_8859-2:1987")]; + char stringpool_str579[sizeof("CSISO14JISC6220RO")]; + char stringpool_str583[sizeof("CSMACINTOSH")]; + char stringpool_str584[sizeof("ISO-2022-JP-2")]; + char stringpool_str588[sizeof("UTF-7")]; + char stringpool_str589[sizeof("CSPC850MULTILINGUAL")]; + char stringpool_str592[sizeof("GREEK")]; + char stringpool_str593[sizeof("CSISO2022JP")]; + char stringpool_str594[sizeof("CSISOLATINHEBREW")]; + char stringpool_str601[sizeof("ISO_8859-7:2003")]; + char stringpool_str616[sizeof("CSISO159JISX02121990")]; + char stringpool_str619[sizeof("BIGFIVE")]; + char stringpool_str620[sizeof("CSISO2022JP2")]; + char stringpool_str622[sizeof("BIG-FIVE")]; + char stringpool_str636[sizeof("CSISOLATINGREEK")]; + char stringpool_str637[sizeof("HEBREW")]; + char stringpool_str641[sizeof("IBM367")]; + char stringpool_str647[sizeof("CSHALFWIDTHKATAKANA")]; + char stringpool_str650[sizeof("WINDOWS-874")]; + char stringpool_str652[sizeof("UNICODELITTLE")]; + char stringpool_str663[sizeof("BIG5HKSCS")]; + char stringpool_str666[sizeof("BIG5-HKSCS")]; + char stringpool_str667[sizeof("JIS_X0208")]; + char stringpool_str669[sizeof("JIS_X0201")]; + char stringpool_str676[sizeof("WINDOWS-1257")]; + char stringpool_str680[sizeof("KOI8-U")]; + char stringpool_str684[sizeof("KOI8-RU")]; + char stringpool_str691[sizeof("JOHAB")]; + char stringpool_str693[sizeof("JISX0201-1976")]; + char stringpool_str702[sizeof("JIS_X0208-1990")]; + char stringpool_str706[sizeof("JIS_X0212")]; + char stringpool_str710[sizeof("JIS_X0212-1990")]; + char stringpool_str712[sizeof("ISO_8859-7:1987")]; + char stringpool_str713[sizeof("SHIFT-JIS")]; + char stringpool_str714[sizeof("SHIFT_JIS")]; + char stringpool_str732[sizeof("JIS_X0208-1983")]; + char stringpool_str751[sizeof("CSEUCTW")]; + char stringpool_str752[sizeof("MACUKRAINE")]; + char stringpool_str759[sizeof("UNICODEBIG")]; + char stringpool_str769[sizeof("MS-GREEK")]; + char stringpool_str774[sizeof("MACGREEK")]; + char stringpool_str800[sizeof("CSSHIFTJIS")]; + char stringpool_str822[sizeof("JIS_X0212.1990-0")]; + char stringpool_str840[sizeof("CSEUCPKDFMTJAPANESE")]; + char stringpool_str853[sizeof("MACHEBREW")]; + char stringpool_str858[sizeof("MS_KANJI")]; + char stringpool_str859[sizeof("TCVN5712-1:1993")]; + char stringpool_str869[sizeof("WINBALTRIM")]; + char stringpool_str884[sizeof("MS-TURK")]; + char stringpool_str894[sizeof("BIG5-HKSCS:2008")]; + char stringpool_str895[sizeof("BIG5-HKSCS:2001")]; + char stringpool_str901[sizeof("BIG5-HKSCS:1999")]; + char stringpool_str907[sizeof("BIG5-HKSCS:2004")]; + char stringpool_str917[sizeof("CSISO87JISX0208")]; + char stringpool_str953[sizeof("MACTURKISH")]; + char stringpool_str1003[sizeof("KO_KR.JOHAP92")]; + }; +static const struct stringpool_t stringpool_contents = + { + "R8", + "CN", + "L8", + "L1", + "L6", + "L4", + "866", + "C99", + "L5", + "646", + "CHAR", + "CP819", + "L2", + "CP866", + "CP949", + "850", + "5601", + "RK1048", + "EUCCN", + "L10", + "EUC-CN", + "L3", + "CP154", + "PT154", + "862", + "CP1258", + "CP1251", + "CP1131", + "PTCP154", + "CP850", + "CP1361", + "CP862", + "CP1256", + "CP950", + "HZ", + "CP936", + "CP1254", + "CP1255", + "ISO8859-8", + "ISO8859-1", + "ISO-8859-8", + "ISO_8859-8", + "ISO-8859-1", + "ISO_8859-1", + "ISO8859-11", + "CP1250", + "ISO646-CN", + "ISO-8859-11", + "ISO_8859-11", + "ISO8859-9", + "ISO8859-6", + "ISO-8859-9", + "ISO_8859-9", + "ISO-8859-6", + "ISO_8859-6", + "ISO8859-16", + "CP1252", + "ISO_8859-16:2001", + "ISO-8859-16", + "ISO_8859-16", + "ISO8859-4", + "ISO_8859-14:1998", + "CP932", + "ISO-8859-4", + "ISO_8859-4", + "ISO8859-14", + "ISO_8859-15:1998", + "ISO-8859-14", + "ISO_8859-14", + "ISO8859-5", + "ISO-8859-5", + "ISO_8859-5", + "ISO8859-15", + "ISO-IR-6", + "ISO-8859-15", + "ISO_8859-15", + "SJIS", + "ISO-IR-148", + "ISO-IR-58", + "ISO8859-10", + "CYRILLIC", + "ISO-8859-10", + "ISO_8859-10", + "ISO-IR-199", + "ISO-IR-14", + "L7", + "ISO-IR-166", + "ISO8859-2", + "ISO-IR-101", + "ISO-IR-149", + "ISO-8859-2", + "ISO_8859-2", + "MAC", + "CP1253", + "ISO_8859-10:1992", + "ISO-IR-159", + "LATIN8", + "CP1133", + "LATIN1", + "ISO-IR-109", + "ISO-IR-144", + "ANSI-1251", + "CNS11643", + "CSPTCP154", + "ISO-IR-165", + "ISO-IR-126", + "ELOT_928", + "ISO-IR-110", + "LATIN6", + "LATIN-9", + "ROMAN8", + "ISO-IR-138", + "GB_1988-80", + "CP874", + "LATIN4", + "ASCII", + "UHC", + "ISO-2022-CN", + "CHINESE", + "ISO8859-3", + "ISO-IR-100", + "LATIN5", + "ISO-8859-3", + "ISO_8859-3", + "ISO8859-13", + "ISO-IR-226", + "CYRILLIC-ASIAN", + "ISO-8859-13", + "ISO_8859-13", + "US", + "MS-CYRL", + "TIS620", + "LATIN10", + "TIS-620", + "ARABIC", + "ECMA-118", + "EUCKR", + "LATIN2", + "EUC-KR", + "UTF-8", + "KZ-1048", + "CSISO2022CN", + "CSASCII", + "MS936", + "IBM819", + "MULELAO-1", + "X0208", + "X0201", + "GB18030", + "KOREAN", + "IBM866", + "TIS620-0", + "KOI8-R", + "ECMA-114", + "UCS-4", + "UTF-16", + "CSKZ1048", + "KSC_5601", + "CSKOI8R", + "MS-EE", + "GB2312", + "CSUCS4", + "BIG5", + "BIG-5", + "HP-ROMAN8", + "LATIN3", + "KS_C_5601-1989", + "X0212", + "TCVN", + "ISO-CELTIC", + "CSHPROMAN8", + "UCS-2", + "IBM850", + "ISO-IR-203", + "IBM862", + "GB_2312-80", + "CSISOLATIN1", + "ISO-2022-CN-EXT", + "ISO-IR-179", + "CSISOLATINCYRILLIC", + "CSISOLATIN6", + "JP", + "MACICELAND", + "UCS-4LE", + "CSISOLATIN4", + "CSISOLATINARABIC", + "UNICODE-1-1", + "UTF-16LE", + "CSUNICODE11", + "CSISOLATIN5", + "MS-ANSI", + "CSBIG5", + "UCS-2LE", + "CN-BIG5", + "ARMSCII-8", + "ISO-10646-UCS-4", + "UTF-32", + "CSUNICODE", + "ISO_8859-8:1988", + "CSISOLATIN2", + "CN-GB", + "ISO646-US", + "MACROMAN", + "MACCYRILLIC", + "ISO-10646-UCS-2", + "STRK1048-2002", + "ISO_8859-4:1988", + "ISO_8859-9:1989", + "EUCJP", + "EUC-JP", + "ISO_8859-5:1988", + "GREEK8", + "ASMO-708", + "PCK", + "CSIBM866", + "CP1257", + "ISO-2022-KR", + "GEORGIAN-ACADEMY", + "MACCROATIAN", + "CP367", + "GEORGIAN-PS", + "CSGB2312", + "VISCII", + "MS-HEBR", + "UTF-32LE", + "CSISOLATIN3", + "MACARABIC", + "ISO_8859-3:1988", + "IBM-CP1133", + "TIS620.2529-1", + "CSISO2022KR", + "ISO8859-7", + "MACCENTRALEUROPE", + "ISO-8859-7", + "ISO_8859-7", + "CN-GB-ISOIR165", + "ISO646-JP", + "KS_C_5601-1987", + "US-ASCII", + "UCS-4BE", + "CSEUCKR", + "JIS0208", + "UTF-16BE", + "MS-ARAB", + "CSPC862LATINHEBREW", + "KOI8-T", + "ISO-IR-87", + "UCS-2BE", + "MACROMANIA", + "UCS-4-INTERNAL", + "ISO_646.IRV:1991", + "CSVISCII", + "VISCII1.1-1", + "ISO-IR-57", + "NEXTSTEP", + "HZ-GB-2312", + "CSKSC56011987", + "ISO-IR-157", + "JIS_C6220-1969-RO", + "CSISO58GB231280", + "TIS620.2533-1", + "UCS-2-INTERNAL", + "WINDOWS-1258", + "WINDOWS-1251", + "MACTHAI", + "WCHAR_T", + "GBK", + "ISO-IR-127", + "WINDOWS-1256", + "UNICODE-1-1-UTF-7", + "LATIN7", + "ANSI_X3.4-1968", + "WINDOWS-1254", + "CSUNICODE11UTF7", + "WINDOWS-1255", + "ANSI_X3.4-1986", + "TIS620.2533-0", + "EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE", + "WINDOWS-1250", + "WINDOWS-936", + "EUCTW", + "EUC-TW", + "WINDOWS-1252", + "JIS_C6226-1983", + "UCS-4-SWAPPED", + "UTF-32BE", + "TCVN5712-1", + "ISO_8859-1:1987", + "MACINTOSH", + "ISO-2022-JP-1", + "ISO_8859-6:1987", + "ISO-2022-JP", + "TIS620.2533", + "UCS-2-SWAPPED", + "WINDOWS-1253", + "JAVA", + "CSISO57GB1988", + "TCVN-5712", + "ISO_8859-2:1987", + "CSISO14JISC6220RO", + "CSMACINTOSH", + "ISO-2022-JP-2", + "UTF-7", + "CSPC850MULTILINGUAL", + "GREEK", + "CSISO2022JP", + "CSISOLATINHEBREW", + "ISO_8859-7:2003", + "CSISO159JISX02121990", + "BIGFIVE", + "CSISO2022JP2", + "BIG-FIVE", + "CSISOLATINGREEK", + "HEBREW", + "IBM367", + "CSHALFWIDTHKATAKANA", + "WINDOWS-874", + "UNICODELITTLE", + "BIG5HKSCS", + "BIG5-HKSCS", + "JIS_X0208", + "JIS_X0201", + "WINDOWS-1257", + "KOI8-U", + "KOI8-RU", + "JOHAB", + "JISX0201-1976", + "JIS_X0208-1990", + "JIS_X0212", + "JIS_X0212-1990", + "ISO_8859-7:1987", + "SHIFT-JIS", + "SHIFT_JIS", + "JIS_X0208-1983", + "CSEUCTW", + "MACUKRAINE", + "UNICODEBIG", + "MS-GREEK", + "MACGREEK", + "CSSHIFTJIS", + "JIS_X0212.1990-0", + "CSEUCPKDFMTJAPANESE", + "MACHEBREW", + "MS_KANJI", + "TCVN5712-1:1993", + "WINBALTRIM", + "MS-TURK", + "BIG5-HKSCS:2008", + "BIG5-HKSCS:2001", + "BIG5-HKSCS:1999", + "BIG5-HKSCS:2004", + "CSISO87JISX0208", + "MACTURKISH", + "KO_KR.JOHAP92" + }; +#define stringpool ((const char *) &stringpool_contents) + +static const struct alias aliases[] = + { + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 229 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str8, ei_hp_roman8}, + {-1}, {-1}, {-1}, {-1}, +#line 291 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str13, ei_iso646_cn}, +#line 152 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str14, ei_iso8859_14}, +#line 61 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str15, ei_iso8859_1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 135 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str22, ei_iso8859_10}, + {-1}, {-1}, {-1}, {-1}, +#line 85 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str27, ei_iso8859_4}, +#line 209 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str28, ei_cp866}, + {-1}, +#line 52 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str30, ei_c99}, + {-1}, {-1}, +#line 127 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str33, ei_iso8859_9}, + {-1}, {-1}, +#line 23 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str36, ei_ascii}, + {-1}, +#line 364 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str38, ei_local_char}, +#line 58 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str39, ei_iso8859_1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 69 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str45, ei_iso8859_2}, + {-1}, {-1}, +#line 207 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str48, ei_cp866}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 357 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str58, ei_cp949}, + {-1}, +#line 201 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str60, ei_cp850}, +#line 356 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str61, ei_euc_kr}, +#line 241 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str62, ei_rk1048}, + {-1}, +#line 322 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str64, ei_euc_cn}, + {-1}, +#line 166 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str66, ei_iso8859_16}, +#line 321 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str67, ei_euc_cn}, +#line 77 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str68, ei_iso8859_3}, + {-1}, +#line 238 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str70, ei_pt154}, +#line 236 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str71, ei_pt154}, + {-1}, {-1}, +#line 205 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str74, ei_cp862}, + {-1}, {-1}, {-1}, {-1}, +#line 197 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str79, ei_cp1258}, + {-1}, +#line 175 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str81, ei_cp1251}, + {-1}, {-1}, {-1}, {-1}, +#line 211 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str86, ei_cp1131}, + {-1}, +#line 237 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str88, ei_pt154}, + {-1}, {-1}, +#line 199 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str91, ei_cp850}, + {-1}, +#line 360 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str93, ei_johab}, +#line 203 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str94, ei_cp862}, +#line 191 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str95, ei_cp1256}, + {-1}, {-1}, +#line 346 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str98, ei_cp950}, +#line 334 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str99, ei_hz}, + {-1}, +#line 327 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str101, ei_cp936}, + {-1}, {-1}, {-1}, +#line 185 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str105, ei_cp1254}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, +#line 188 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str117, ei_cp1255}, + {-1}, +#line 121 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str119, ei_iso8859_8}, + {-1}, +#line 63 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str121, ei_iso8859_1}, +#line 115 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str122, ei_iso8859_8}, +#line 116 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str123, ei_iso8859_8}, +#line 54 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str124, ei_iso8859_1}, +#line 55 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str125, ei_iso8859_1}, +#line 140 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str126, ei_iso8859_11}, +#line 172 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str127, ei_cp1250}, +#line 289 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str128, ei_iso646_cn}, +#line 138 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str129, ei_iso8859_11}, +#line 139 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str130, ei_iso8859_11}, + {-1}, {-1}, +#line 129 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str133, ei_iso8859_9}, + {-1}, +#line 103 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str135, ei_iso8859_6}, +#line 122 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str136, ei_iso8859_9}, +#line 123 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str137, ei_iso8859_9}, +#line 95 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str138, ei_iso8859_6}, +#line 96 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str139, ei_iso8859_6}, +#line 167 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str140, ei_iso8859_16}, +#line 179 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str141, ei_cp1252}, +#line 163 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str142, ei_iso8859_16}, +#line 161 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str143, ei_iso8859_16}, +#line 162 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str144, ei_iso8859_16}, +#line 87 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str145, ei_iso8859_4}, +#line 149 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str146, ei_iso8859_14}, +#line 315 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str147, ei_cp932}, +#line 80 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str148, ei_iso8859_4}, +#line 81 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str149, ei_iso8859_4}, +#line 154 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str150, ei_iso8859_14}, + {-1}, +#line 157 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str152, ei_iso8859_15}, +#line 147 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str153, ei_iso8859_14}, +#line 148 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str154, ei_iso8859_14}, + {-1}, {-1}, +#line 94 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str157, ei_iso8859_5}, + {-1}, {-1}, +#line 88 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str160, ei_iso8859_5}, +#line 89 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str161, ei_iso8859_5}, +#line 160 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str162, ei_iso8859_15}, +#line 16 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str163, ei_ascii}, + {-1}, +#line 155 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str165, ei_iso8859_15}, +#line 156 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str166, ei_iso8859_15}, + {-1}, +#line 311 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str168, ei_sjis}, +#line 125 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str169, ei_iso8859_9}, +#line 294 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str170, ei_gb2312}, + {-1}, +#line 137 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str172, ei_iso8859_10}, + {-1}, +#line 92 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str174, ei_iso8859_5}, +#line 130 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str175, ei_iso8859_10}, +#line 131 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str176, ei_iso8859_10}, +#line 150 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str177, ei_iso8859_14}, +#line 267 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str178, ei_iso646_jp}, +#line 145 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str179, ei_iso8859_13}, +#line 254 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str180, ei_tis620}, +#line 71 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str181, ei_iso8859_2}, +#line 67 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str182, ei_iso8859_2}, +#line 302 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str183, ei_ksc5601}, +#line 64 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str184, ei_iso8859_2}, +#line 65 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str185, ei_iso8859_2}, +#line 214 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str186, ei_mac_roman}, +#line 182 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str187, ei_cp1253}, +#line 132 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str188, ei_iso8859_10}, +#line 286 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str189, ei_jisx0212}, + {-1}, +#line 151 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str191, ei_iso8859_14}, +#line 246 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str192, ei_cp1133}, +#line 60 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str193, ei_iso8859_1}, +#line 75 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str194, ei_iso8859_3}, +#line 91 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str195, ei_iso8859_5}, +#line 178 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str196, ei_cp1251}, + {-1}, +#line 339 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str198, ei_euc_tw}, + {-1}, {-1}, +#line 240 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str201, ei_pt154}, +#line 297 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str202, ei_isoir165}, +#line 108 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str203, ei_iso8859_7}, +#line 110 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str204, ei_iso8859_7}, +#line 83 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str205, ei_iso8859_4}, + {-1}, +#line 134 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str207, ei_iso8859_10}, +#line 159 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str208, ei_iso8859_15}, +#line 228 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str209, ei_hp_roman8}, +#line 118 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str210, ei_iso8859_8}, +#line 288 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str211, ei_iso646_cn}, + {-1}, {-1}, {-1}, +#line 256 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str215, ei_cp874}, + {-1}, +#line 84 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str217, ei_iso8859_4}, + {-1}, +#line 13 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str219, ei_ascii}, + {-1}, {-1}, +#line 358 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str222, ei_cp949}, +#line 331 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str223, ei_iso2022_cn}, + {-1}, +#line 296 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str225, ei_gb2312}, + {-1}, +#line 79 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str227, ei_iso8859_3}, +#line 57 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str228, ei_iso8859_1}, +#line 126 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str229, ei_iso8859_9}, +#line 72 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str230, ei_iso8859_3}, +#line 73 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str231, ei_iso8859_3}, +#line 146 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str232, ei_iso8859_13}, +#line 164 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str233, ei_iso8859_16}, +#line 239 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str234, ei_pt154}, +#line 141 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str235, ei_iso8859_13}, +#line 142 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str236, ei_iso8859_13}, + {-1}, {-1}, {-1}, {-1}, +#line 21 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str241, ei_ascii}, +#line 177 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str242, ei_cp1251}, +#line 249 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str243, ei_tis620}, +#line 165 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str244, ei_iso8859_16}, + {-1}, +#line 248 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str246, ei_tis620}, + {-1}, {-1}, {-1}, +#line 101 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str250, ei_iso8859_6}, +#line 109 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str251, ei_iso8859_7}, +#line 354 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str252, ei_euc_kr}, +#line 68 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str253, ei_iso8859_2}, + {-1}, +#line 353 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str255, ei_euc_kr}, + {-1}, {-1}, +#line 24 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str258, ei_utf8}, +#line 243 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str259, ei_rk1048}, +#line 332 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str260, ei_iso2022_cn}, + {-1}, +#line 22 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str262, ei_ascii}, +#line 328 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str263, ei_cp936}, +#line 59 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str264, ei_iso8859_1}, + {-1}, +#line 245 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str266, ei_mulelao}, +#line 278 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str267, ei_jisx0208}, + {-1}, +#line 272 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str269, ei_jisx0201}, + {-1}, +#line 330 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str271, ei_gb18030}, +#line 304 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str272, ei_ksc5601}, +#line 208 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str273, ei_cp866}, +#line 250 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str274, ei_tis620}, + {-1}, +#line 168 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str276, ei_koi8_r}, +#line 99 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str277, ei_iso8859_6}, +#line 34 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str278, ei_ucs4}, +#line 39 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str279, ei_utf16}, + {-1}, +#line 244 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str281, ei_rk1048}, + {-1}, +#line 299 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str283, ei_ksc5601}, +#line 169 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str284, ei_koi8_r}, + {-1}, {-1}, +#line 174 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str287, ei_cp1250}, +#line 323 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str288, ei_euc_cn}, + {-1}, {-1}, +#line 36 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str291, ei_ucs4}, + {-1}, +#line 340 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str293, ei_ces_big5}, + {-1}, {-1}, +#line 341 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str296, ei_ces_big5}, +#line 227 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str297, ei_hp_roman8}, + {-1}, +#line 76 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str299, ei_iso8859_3}, + {-1}, {-1}, {-1}, {-1}, +#line 301 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str304, ei_ksc5601}, + {-1}, +#line 285 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str306, ei_jisx0212}, +#line 261 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str307, ei_tcvn}, + {-1}, +#line 153 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str309, ei_iso8859_14}, + {-1}, +#line 230 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str311, ei_hp_roman8}, + {-1}, {-1}, +#line 25 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str314, ei_ucs2}, + {-1}, +#line 200 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str316, ei_cp850}, + {-1}, +#line 158 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str318, ei_iso8859_15}, +#line 204 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str319, ei_cp862}, +#line 293 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str320, ei_gb2312}, + {-1}, {-1}, {-1}, +#line 62 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str324, ei_iso8859_1}, + {-1}, {-1}, +#line 333 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str327, ei_iso2022_cn_ext}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 143 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str335, ei_iso8859_13}, + {-1}, +#line 93 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str337, ei_iso8859_5}, +#line 136 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str338, ei_iso8859_10}, + {-1}, {-1}, {-1}, +#line 268 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str342, ei_iso646_jp}, + {-1}, {-1}, {-1}, +#line 217 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str346, ei_mac_iceland}, +#line 38 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str347, ei_ucs4le}, +#line 86 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str348, ei_iso8859_4}, +#line 102 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str349, ei_iso8859_6}, +#line 30 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str350, ei_ucs2be}, + {-1}, {-1}, +#line 41 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str353, ei_utf16le}, + {-1}, {-1}, {-1}, +#line 31 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str357, ei_ucs2be}, + {-1}, {-1}, +#line 128 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str360, ei_iso8859_9}, +#line 181 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str361, ei_cp1252}, + {-1}, {-1}, +#line 345 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str364, ei_ces_big5}, +#line 32 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str365, ei_ucs2le}, + {-1}, +#line 344 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str367, ei_ces_big5}, + {-1}, {-1}, {-1}, {-1}, +#line 232 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str372, ei_armscii_8}, +#line 35 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str373, ei_ucs4}, + {-1}, {-1}, {-1}, {-1}, +#line 42 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str378, ei_utf32}, + {-1}, +#line 27 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str380, ei_ucs2}, + {-1}, +#line 117 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str382, ei_iso8859_8}, + {-1}, +#line 70 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str384, ei_iso8859_2}, +#line 324 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str385, ei_euc_cn}, +#line 14 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str386, ei_ascii}, +#line 212 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str387, ei_mac_roman}, + {-1}, +#line 220 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str389, ei_mac_cyrillic}, + {-1}, +#line 26 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str391, ei_ucs2}, + {-1}, {-1}, +#line 242 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str394, ei_rk1048}, +#line 82 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str395, ei_iso8859_4}, +#line 124 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str396, ei_iso8859_9}, +#line 306 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str397, ei_euc_jp}, + {-1}, {-1}, +#line 305 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str400, ei_euc_jp}, +#line 90 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str401, ei_iso8859_5}, +#line 111 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str402, ei_iso8859_7}, +#line 100 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str403, ei_iso8859_6}, + {-1}, +#line 314 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str405, ei_sjis}, + {-1}, {-1}, +#line 210 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str408, ei_cp866}, +#line 194 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str409, ei_cp1257}, + {-1}, +#line 362 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str411, ei_iso2022_kr}, +#line 233 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str412, ei_georgian_academy}, + {-1}, {-1}, +#line 218 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str415, ei_mac_croatian}, +#line 19 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str416, ei_ascii}, + {-1}, {-1}, +#line 234 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str419, ei_georgian_ps}, + {-1}, {-1}, {-1}, +#line 325 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str423, ei_euc_cn}, +#line 258 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str424, ei_viscii}, + {-1}, {-1}, {-1}, +#line 190 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str428, ei_cp1255}, +#line 44 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str429, ei_utf32le}, +#line 78 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str430, ei_iso8859_3}, + {-1}, +#line 225 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str432, ei_mac_arabic}, + {-1}, {-1}, {-1}, +#line 74 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str436, ei_iso8859_3}, +#line 247 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str437, ei_cp1133}, + {-1}, +#line 251 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str439, ei_tis620}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 363 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str448, ei_iso2022_kr}, +#line 114 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str449, ei_iso8859_7}, + {-1}, +#line 216 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str451, ei_mac_centraleurope}, +#line 104 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str452, ei_iso8859_7}, +#line 105 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str453, ei_iso8859_7}, + {-1}, +#line 298 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str455, ei_isoir165}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 266 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str461, ei_iso646_jp}, +#line 300 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str462, ei_ksc5601}, +#line 12 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str463, ei_ascii}, +#line 37 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str464, ei_ucs4be}, + {-1}, +#line 355 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str466, ei_euc_kr}, +#line 277 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str467, ei_jisx0208}, + {-1}, {-1}, +#line 40 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str470, ei_utf16be}, + {-1}, {-1}, {-1}, {-1}, +#line 193 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str475, ei_cp1256}, +#line 206 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str476, ei_cp862}, + {-1}, +#line 235 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str478, ei_koi8_t}, + {-1}, {-1}, +#line 279 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str481, ei_jisx0208}, +#line 28 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str482, ei_ucs2be}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 219 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str489, ei_mac_romania}, + {-1}, {-1}, +#line 50 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str492, ei_ucs4internal}, +#line 15 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str493, ei_ascii}, + {-1}, +#line 260 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str495, ei_viscii}, + {-1}, +#line 259 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str497, ei_viscii}, + {-1}, {-1}, +#line 290 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str500, ei_iso646_cn}, + {-1}, +#line 231 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str502, ei_nextstep}, +#line 335 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str503, ei_hz}, +#line 303 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str504, ei_ksc5601}, +#line 133 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str505, ei_iso8859_10}, + {-1}, +#line 265 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str507, ei_iso646_jp}, +#line 295 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str508, ei_gb2312}, +#line 253 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str509, ei_tis620}, +#line 48 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str510, ei_ucs2internal}, +#line 198 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str511, ei_cp1258}, +#line 176 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str512, ei_cp1251}, +#line 226 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str513, ei_mac_thai}, + {-1}, +#line 365 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str515, ei_local_wchar_t}, +#line 326 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str516, ei_ces_gbk}, +#line 98 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str517, ei_iso8859_6}, + {-1}, +#line 192 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str519, ei_cp1256}, +#line 46 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str520, ei_utf7}, +#line 144 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str521, ei_iso8859_13}, + {-1}, +#line 17 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str523, ei_ascii}, +#line 186 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str524, ei_cp1254}, +#line 47 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str525, ei_utf7}, + {-1}, {-1}, {-1}, {-1}, +#line 189 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str530, ei_cp1255}, +#line 18 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str531, ei_ascii}, +#line 252 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str532, ei_tis620}, +#line 307 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str533, ei_euc_jp}, + {-1}, +#line 173 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str535, ei_cp1250}, +#line 329 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str536, ei_cp936}, +#line 337 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str537, ei_euc_tw}, + {-1}, {-1}, +#line 336 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str540, ei_euc_tw}, + {-1}, +#line 180 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str542, ei_cp1252}, +#line 280 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str543, ei_jisx0208}, + {-1}, +#line 51 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str545, ei_ucs4swapped}, +#line 43 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str546, ei_utf32be}, +#line 263 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str547, ei_tcvn}, +#line 56 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str548, ei_iso8859_1}, + {-1}, {-1}, {-1}, {-1}, +#line 213 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str553, ei_mac_roman}, +#line 318 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str554, ei_iso2022_jp1}, +#line 97 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str555, ei_iso8859_6}, +#line 316 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str556, ei_iso2022_jp}, + {-1}, {-1}, {-1}, +#line 255 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str560, ei_tis620}, + {-1}, {-1}, +#line 49 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str563, ei_ucs2swapped}, + {-1}, +#line 183 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str565, ei_cp1253}, + {-1}, {-1}, {-1}, +#line 53 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str569, ei_java}, +#line 292 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str570, ei_iso646_cn}, + {-1}, +#line 262 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str572, ei_tcvn}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 66 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str578, ei_iso8859_2}, +#line 269 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str579, ei_iso646_jp}, + {-1}, {-1}, {-1}, +#line 215 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str583, ei_mac_roman}, +#line 319 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str584, ei_iso2022_jp2}, + {-1}, {-1}, {-1}, +#line 45 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str588, ei_utf7}, +#line 202 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str589, ei_cp850}, + {-1}, {-1}, +#line 112 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str592, ei_iso8859_7}, +#line 317 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str593, ei_iso2022_jp}, +#line 120 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str594, ei_iso8859_8}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 107 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str601, ei_iso8859_7}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 287 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str616, ei_jisx0212}, + {-1}, {-1}, +#line 343 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str619, ei_ces_big5}, +#line 320 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str620, ei_iso2022_jp2}, + {-1}, +#line 342 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str622, ei_ces_big5}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 113 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str636, ei_iso8859_7}, +#line 119 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str637, ei_iso8859_8}, + {-1}, {-1}, {-1}, +#line 20 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str641, ei_ascii}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 273 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str647, ei_jisx0201}, + {-1}, {-1}, +#line 257 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str650, ei_cp874}, + {-1}, +#line 33 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str652, ei_ucs2le}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, +#line 351 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str663, ei_big5hkscs2008}, + {-1}, {-1}, +#line 350 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str666, ei_big5hkscs2008}, +#line 274 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str667, ei_jisx0208}, + {-1}, +#line 270 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str669, ei_jisx0201}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 195 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str676, ei_cp1257}, + {-1}, {-1}, {-1}, +#line 170 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str680, ei_koi8_u}, + {-1}, {-1}, {-1}, +#line 171 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str684, ei_koi8_ru}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 359 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str691, ei_johab}, + {-1}, +#line 271 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str693, ei_jisx0201}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 276 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str702, ei_jisx0208}, + {-1}, {-1}, {-1}, +#line 282 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str706, ei_jisx0212}, + {-1}, {-1}, {-1}, +#line 284 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str710, ei_jisx0212}, + {-1}, +#line 106 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str712, ei_iso8859_7}, +#line 310 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str713, ei_sjis}, +#line 309 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str714, ei_sjis}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 275 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str732, ei_jisx0208}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 338 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str751, ei_euc_tw}, +#line 221 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str752, ei_mac_ukraine}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 29 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str759, ei_ucs2be}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 184 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str769, ei_cp1253}, + {-1}, {-1}, {-1}, {-1}, +#line 222 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str774, ei_mac_greek}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 313 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str800, ei_sjis}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 283 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str822, ei_jisx0212}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 308 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str840, ei_euc_jp}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, +#line 224 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str853, ei_mac_hebrew}, + {-1}, {-1}, {-1}, {-1}, +#line 312 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str858, ei_sjis}, +#line 264 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str859, ei_tcvn}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 196 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str869, ei_cp1257}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 187 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str884, ei_cp1254}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 352 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str894, ei_big5hkscs2008}, +#line 348 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str895, ei_big5hkscs2001}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 347 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str901, ei_big5hkscs1999}, + {-1}, {-1}, {-1}, {-1}, {-1}, +#line 349 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str907, ei_big5hkscs2004}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 281 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str917, ei_jisx0208}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, +#line 223 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str953, ei_mac_turkish}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, {-1}, + {-1}, {-1}, {-1}, {-1}, +#line 361 "lib/aliases_syssolaris.gperf" + {(int)(long)&((struct stringpool_t *)0)->stringpool_str1003, ei_johab} + }; + +#ifdef __GNUC__ +__inline +#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__ +__attribute__ ((__gnu_inline__)) +#endif +#endif +const struct alias * +aliases_lookup (register const char *str, register unsigned int len) +{ + if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) + { + register int key = aliases_hash (str, len); + + if (key <= MAX_HASH_VALUE && key >= 0) + { + register int o = aliases[key].name; + if (o >= 0) + { + register const char *s = o + stringpool; + + if (*str == *s && !strcmp (str + 1, s + 1)) + return &aliases[key]; + } + } + } + return 0; +} diff --git a/libs/libiconv/lib/armscii_8.h b/libs/libiconv/lib/armscii_8.h new file mode 100644 index 00000000..8d1613ff --- /dev/null +++ b/libs/libiconv/lib/armscii_8.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ARMSCII-8 + */ + +static const unsigned short armscii_8_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0xfffd, 0x0587, 0x0589, 0x0029, 0x0028, 0x00bb, 0x00ab, + 0x2014, 0x002e, 0x055d, 0x002c, 0x002d, 0x058a, 0x2026, 0x055c, + /* 0xb0 */ + 0x055b, 0x055e, 0x0531, 0x0561, 0x0532, 0x0562, 0x0533, 0x0563, + 0x0534, 0x0564, 0x0535, 0x0565, 0x0536, 0x0566, 0x0537, 0x0567, + /* 0xc0 */ + 0x0538, 0x0568, 0x0539, 0x0569, 0x053a, 0x056a, 0x053b, 0x056b, + 0x053c, 0x056c, 0x053d, 0x056d, 0x053e, 0x056e, 0x053f, 0x056f, + /* 0xd0 */ + 0x0540, 0x0570, 0x0541, 0x0571, 0x0542, 0x0572, 0x0543, 0x0573, + 0x0544, 0x0574, 0x0545, 0x0575, 0x0546, 0x0576, 0x0547, 0x0577, + /* 0xe0 */ + 0x0548, 0x0578, 0x0549, 0x0579, 0x054a, 0x057a, 0x054b, 0x057b, + 0x054c, 0x057c, 0x054d, 0x057d, 0x054e, 0x057e, 0x054f, 0x057f, + /* 0xf0 */ + 0x0550, 0x0580, 0x0551, 0x0581, 0x0552, 0x0582, 0x0553, 0x0583, + 0x0554, 0x0584, 0x0555, 0x0585, 0x0556, 0x0586, 0x055a, 0xfffd, +}; + +static int +armscii_8_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = armscii_8_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char armscii_8_page00[8] = { + 0xa5, 0xa4, 0x2a, 0x2b, 0xab, 0xac, 0xa9, 0x2f, /* 0x28-0x2f */ +}; +static const unsigned char armscii_8_page00_1[32] = { + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char armscii_8_page05[96] = { + 0x00, 0xb2, 0xb4, 0xb6, 0xb8, 0xba, 0xbc, 0xbe, /* 0x30-0x37 */ + 0xc0, 0xc2, 0xc4, 0xc6, 0xc8, 0xca, 0xcc, 0xce, /* 0x38-0x3f */ + 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, 0xda, 0xdc, 0xde, /* 0x40-0x47 */ + 0xe0, 0xe2, 0xe4, 0xe6, 0xe8, 0xea, 0xec, 0xee, /* 0x48-0x4f */ + 0xf0, 0xf2, 0xf4, 0xf6, 0xf8, 0xfa, 0xfc, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0xfe, 0xb0, 0xaf, 0xaa, 0xb1, 0x00, /* 0x58-0x5f */ + 0x00, 0xb3, 0xb5, 0xb7, 0xb9, 0xbb, 0xbd, 0xbf, /* 0x60-0x67 */ + 0xc1, 0xc3, 0xc5, 0xc7, 0xc9, 0xcb, 0xcd, 0xcf, /* 0x68-0x6f */ + 0xd1, 0xd3, 0xd5, 0xd7, 0xd9, 0xdb, 0xdd, 0xdf, /* 0x70-0x77 */ + 0xe1, 0xe3, 0xe5, 0xe7, 0xe9, 0xeb, 0xed, 0xef, /* 0x78-0x7f */ + 0xf1, 0xf3, 0xf5, 0xf7, 0xf9, 0xfb, 0xfd, 0xa2, /* 0x80-0x87 */ + 0x00, 0xa3, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ +}; +static const unsigned char armscii_8_page20[24] = { + 0x00, 0x00, 0x00, 0x00, 0xa8, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0x00, /* 0x20-0x27 */ +}; + +static int +armscii_8_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0028) { + *r = wc; + return 1; + } + else if (wc >= 0x0028 && wc < 0x0030) + c = armscii_8_page00[wc-0x0028]; + else if (wc >= 0x0030 && wc < 0x00a0) + c = wc; + else if (wc >= 0x00a0 && wc < 0x00c0) + c = armscii_8_page00_1[wc-0x00a0]; + else if (wc >= 0x0530 && wc < 0x0590) + c = armscii_8_page05[wc-0x0530]; + else if (wc >= 0x2010 && wc < 0x2028) + c = armscii_8_page20[wc-0x2010]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/ascii.h b/libs/libiconv/lib/ascii.h new file mode 100644 index 00000000..fa49e3bf --- /dev/null +++ b/libs/libiconv/lib/ascii.h @@ -0,0 +1,44 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ASCII + */ + +static int +ascii_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + return RET_ILSEQ; +} + +static int +ascii_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x0080) { + *r = wc; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/atarist.h b/libs/libiconv/lib/atarist.h new file mode 100644 index 00000000..90f18cc1 --- /dev/null +++ b/libs/libiconv/lib/atarist.h @@ -0,0 +1,158 @@ +/* + * Copyright (C) 1999-2005 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * Atari ST + */ + +static const unsigned short atarist_2uni[128] = { + /* 0x80 */ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + /* 0x90 */ + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x00df, 0x0192, + /* 0xa0 */ + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + /* 0xb0 */ + 0x00e3, 0x00f5, 0x00d8, 0x00f8, 0x0153, 0x0152, 0x00c0, 0x00c3, + 0x00d5, 0x00a8, 0x00b4, 0x2020, 0x00b6, 0x00a9, 0x00ae, 0x2122, + /* 0xc0 */ + 0x0133, 0x0132, 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, + 0x05d6, 0x05d7, 0x05d8, 0x05d9, 0x05db, 0x05dc, 0x05de, 0x05e0, + /* 0xd0 */ + 0x05e1, 0x05e2, 0x05e4, 0x05e6, 0x05e7, 0x05e8, 0x05e9, 0x05ea, + 0x05df, 0x05da, 0x05dd, 0x05e3, 0x05e5, 0x00a7, 0x2227, 0x221e, + /* 0xe0 */ + 0x03b1, 0x03b2, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x222e, 0x03c6, 0x2208, 0x2229, + /* 0xf0 */ + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x00b3, 0x00af, +}; + +static int +atarist_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) atarist_2uni[c-0x80]; + return 1; +} + +static const unsigned char atarist_page00[96] = { + 0x00, 0xad, 0x9b, 0x9c, 0x00, 0x9d, 0x00, 0xdd, /* 0xa0-0xa7 */ + 0xb9, 0xbd, 0xa6, 0xae, 0xaa, 0x00, 0xbe, 0xff, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0xfe, 0xba, 0xe6, 0xbc, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0x00, 0xa7, 0xaf, 0xac, 0xab, 0x00, 0xa8, /* 0xb8-0xbf */ + 0xb6, 0x00, 0x00, 0xb7, 0x8e, 0x8f, 0x92, 0x80, /* 0xc0-0xc7 */ + 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0xa5, 0x00, 0x00, 0x00, 0xb8, 0x99, 0x00, /* 0xd0-0xd7 */ + 0xb2, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0x9e, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0xb0, 0x84, 0x86, 0x91, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b, /* 0xe8-0xef */ + 0x00, 0xa4, 0x95, 0xa2, 0x93, 0xb1, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0xb3, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0x98, /* 0xf8-0xff */ +}; +static const unsigned char atarist_page01[104] = { + 0x00, 0x00, 0xc1, 0xc0, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0xb5, 0xb4, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char atarist_page03[56] = { + 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe8, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0xe0, 0xe1, 0x00, 0xeb, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */ +}; +static const unsigned char atarist_page05[32] = { + 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, /* 0xd0-0xd7 */ + 0xca, 0xcb, 0xd9, 0xcc, 0xcd, 0xda, 0xce, 0xd8, /* 0xd8-0xdf */ + 0xcf, 0xd0, 0xd1, 0xdb, 0xd2, 0xdc, 0xd3, 0xd4, /* 0xe0-0xe7 */ + 0xd5, 0xd6, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ +}; +static const unsigned char atarist_page22[96] = { + 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xdf, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, /* 0x20-0x27 */ + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0xec, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ +}; +static const unsigned char atarist_page23[24] = { + 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; + +static int +atarist_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = atarist_page00[wc-0x00a0]; + else if (wc >= 0x0130 && wc < 0x0198) + c = atarist_page01[wc-0x0130]; + else if (wc >= 0x0390 && wc < 0x03c8) + c = atarist_page03[wc-0x0390]; + else if (wc >= 0x05d0 && wc < 0x05f0) + c = atarist_page05[wc-0x05d0]; + else if (wc == 0x2020) + c = 0xbb; + else if (wc == 0x207f) + c = 0xfc; + else if (wc == 0x2122) + c = 0xbf; + else if (wc >= 0x2208 && wc < 0x2268) + c = atarist_page22[wc-0x2208]; + else if (wc >= 0x2310 && wc < 0x2328) + c = atarist_page23[wc-0x2310]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/big5.h b/libs/libiconv/lib/big5.h new file mode 100644 index 00000000..de10a99a --- /dev/null +++ b/libs/libiconv/lib/big5.h @@ -0,0 +1,4160 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * BIG5 + */ + +static const unsigned short big5_2uni_pagea1[6121] = { + /* 0xa1 */ + 0x3000, 0xff0c, 0x3001, 0x3002, 0xff0e, 0x2022, 0xff1b, 0xff1a, + 0xff1f, 0xff01, 0xfe30, 0x2026, 0x2025, 0xfe50, 0xff64, 0xfe52, + 0x00b7, 0xfe54, 0xfe55, 0xfe56, 0xfe57, 0xff5c, 0x2013, 0xfe31, + 0x2014, 0xfe33, 0xfffd, 0xfe34, 0xfe4f, 0xff08, 0xff09, 0xfe35, + 0xfe36, 0xff5b, 0xff5d, 0xfe37, 0xfe38, 0x3014, 0x3015, 0xfe39, + 0xfe3a, 0x3010, 0x3011, 0xfe3b, 0xfe3c, 0x300a, 0x300b, 0xfe3d, + 0xfe3e, 0x3008, 0x3009, 0xfe3f, 0xfe40, 0x300c, 0x300d, 0xfe41, + 0xfe42, 0x300e, 0x300f, 0xfe43, 0xfe44, 0xfe59, 0xfe5a, 0xfe5b, + 0xfe5c, 0xfe5d, 0xfe5e, 0x2018, 0x2019, 0x201c, 0x201d, 0x301d, + 0x301e, 0x2035, 0x2032, 0xff03, 0xff06, 0xff0a, 0x203b, 0x00a7, + 0x3003, 0x25cb, 0x25cf, 0x25b3, 0x25b2, 0x25ce, 0x2606, 0x2605, + 0x25c7, 0x25c6, 0x25a1, 0x25a0, 0x25bd, 0x25bc, 0x32a3, 0x2105, + 0x203e, 0xfffd, 0xff3f, 0xfffd, 0xfe49, 0xfe4a, 0xfe4d, 0xfe4e, + 0xfe4b, 0xfe4c, 0xfe5f, 0xfe60, 0xfe61, 0xff0b, 0xff0d, 0x00d7, + 0x00f7, 0x00b1, 0x221a, 0xff1c, 0xff1e, 0xff1d, 0x2266, 0x2267, + 0x2260, 0x221e, 0x2252, 0x2261, 0xfe62, 0xfe63, 0xfe64, 0xfe65, + 0xfe66, 0x223c, 0x2229, 0x222a, 0x22a5, 0x2220, 0x221f, 0x22bf, + 0x33d2, 0x33d1, 0x222b, 0x222e, 0x2235, 0x2234, 0x2640, 0x2642, + 0x2641, 0x2609, 0x2191, 0x2193, 0x2190, 0x2192, 0x2196, 0x2197, + 0x2199, 0x2198, 0x2225, 0x2223, 0xfffd, + /* 0xa2 */ + 0xfffd, 0xff0f, 0xff3c, 0xff04, 0x00a5, 0x3012, 0x00a2, 0x00a3, + 0xff05, 0xff20, 0x2103, 0x2109, 0xfe69, 0xfe6a, 0xfe6b, 0x33d5, + 0x339c, 0x339d, 0x339e, 0x33ce, 0x33a1, 0x338e, 0x338f, 0x33c4, + 0x00b0, 0x5159, 0x515b, 0x515e, 0x515d, 0x5161, 0x5163, 0x55e7, + 0x74e9, 0x7cce, 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586, + 0x2587, 0x2588, 0x258f, 0x258e, 0x258d, 0x258c, 0x258b, 0x258a, + 0x2589, 0x253c, 0x2534, 0x252c, 0x2524, 0x251c, 0x2594, 0x2500, + 0x2502, 0x2595, 0x250c, 0x2510, 0x2514, 0x2518, 0x256d, 0x256e, + 0x2570, 0x256f, 0x2550, 0x255e, 0x256a, 0x2561, 0x25e2, 0x25e3, + 0x25e5, 0x25e4, 0x2571, 0x2572, 0x2573, 0xff10, 0xff11, 0xff12, + 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18, 0xff19, 0x2160, + 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, + 0x2169, 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, 0x3027, + 0x3028, 0x3029, 0xfffd, 0x5344, 0xfffd, 0xff21, 0xff22, 0xff23, + 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, 0xff29, 0xff2a, 0xff2b, + 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, 0xff31, 0xff32, 0xff33, + 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, 0xff39, 0xff3a, 0xff41, + 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, 0xff49, + 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, 0xff51, + 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, + /* 0xa3 */ + 0xff57, 0xff58, 0xff59, 0xff5a, 0x0391, 0x0392, 0x0393, 0x0394, + 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, + 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1, 0x03a3, 0x03a4, 0x03a5, + 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2, 0x03b3, 0x03b4, + 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, + 0x03bd, 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c4, 0x03c5, + 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x3105, 0x3106, 0x3107, 0x3108, + 0x3109, 0x310a, 0x310b, 0x310c, 0x310d, 0x310e, 0x310f, 0x3110, + 0x3111, 0x3112, 0x3113, 0x3114, 0x3115, 0x3116, 0x3117, 0x3118, + 0x3119, 0x311a, 0x311b, 0x311c, 0x311d, 0x311e, 0x311f, 0x3120, + 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 0x3128, + 0x3129, 0x02d9, 0x02c9, 0x02ca, 0x02c7, 0x02cb, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xa4 */ + 0x4e00, 0x4e59, 0x4e01, 0x4e03, 0x4e43, 0x4e5d, 0x4e86, 0x4e8c, + 0x4eba, 0x513f, 0x5165, 0x516b, 0x51e0, 0x5200, 0x5201, 0x529b, + 0x5315, 0x5341, 0x535c, 0x53c8, 0x4e09, 0x4e0b, 0x4e08, 0x4e0a, + 0x4e2b, 0x4e38, 0x51e1, 0x4e45, 0x4e48, 0x4e5f, 0x4e5e, 0x4e8e, + 0x4ea1, 0x5140, 0x5203, 0x52fa, 0x5343, 0x53c9, 0x53e3, 0x571f, + 0x58eb, 0x5915, 0x5927, 0x5973, 0x5b50, 0x5b51, 0x5b53, 0x5bf8, + 0x5c0f, 0x5c22, 0x5c38, 0x5c71, 0x5ddd, 0x5de5, 0x5df1, 0x5df2, + 0x5df3, 0x5dfe, 0x5e72, 0x5efe, 0x5f0b, 0x5f13, 0x624d, 0x4e11, + 0x4e10, 0x4e0d, 0x4e2d, 0x4e30, 0x4e39, 0x4e4b, 0x5c39, 0x4e88, + 0x4e91, 0x4e95, 0x4e92, 0x4e94, 0x4ea2, 0x4ec1, 0x4ec0, 0x4ec3, + 0x4ec6, 0x4ec7, 0x4ecd, 0x4eca, 0x4ecb, 0x4ec4, 0x5143, 0x5141, + 0x5167, 0x516d, 0x516e, 0x516c, 0x5197, 0x51f6, 0x5206, 0x5207, + 0x5208, 0x52fb, 0x52fe, 0x52ff, 0x5316, 0x5339, 0x5348, 0x5347, + 0x5345, 0x535e, 0x5384, 0x53cb, 0x53ca, 0x53cd, 0x58ec, 0x5929, + 0x592b, 0x592a, 0x592d, 0x5b54, 0x5c11, 0x5c24, 0x5c3a, 0x5c6f, + 0x5df4, 0x5e7b, 0x5eff, 0x5f14, 0x5f15, 0x5fc3, 0x6208, 0x6236, + 0x624b, 0x624e, 0x652f, 0x6587, 0x6597, 0x65a4, 0x65b9, 0x65e5, + 0x66f0, 0x6708, 0x6728, 0x6b20, 0x6b62, 0x6b79, 0x6bcb, 0x6bd4, + 0x6bdb, 0x6c0f, 0x6c34, 0x706b, 0x722a, 0x7236, 0x723b, 0x7247, + 0x7259, 0x725b, 0x72ac, 0x738b, 0x4e19, + /* 0xa5 */ + 0x4e16, 0x4e15, 0x4e14, 0x4e18, 0x4e3b, 0x4e4d, 0x4e4f, 0x4e4e, + 0x4ee5, 0x4ed8, 0x4ed4, 0x4ed5, 0x4ed6, 0x4ed7, 0x4ee3, 0x4ee4, + 0x4ed9, 0x4ede, 0x5145, 0x5144, 0x5189, 0x518a, 0x51ac, 0x51f9, + 0x51fa, 0x51f8, 0x520a, 0x52a0, 0x529f, 0x5305, 0x5306, 0x5317, + 0x531d, 0x4edf, 0x534a, 0x5349, 0x5361, 0x5360, 0x536f, 0x536e, + 0x53bb, 0x53ef, 0x53e4, 0x53f3, 0x53ec, 0x53ee, 0x53e9, 0x53e8, + 0x53fc, 0x53f8, 0x53f5, 0x53eb, 0x53e6, 0x53ea, 0x53f2, 0x53f1, + 0x53f0, 0x53e5, 0x53ed, 0x53fb, 0x56db, 0x56da, 0x5916, 0x592e, + 0x5931, 0x5974, 0x5976, 0x5b55, 0x5b83, 0x5c3c, 0x5de8, 0x5de7, + 0x5de6, 0x5e02, 0x5e03, 0x5e73, 0x5e7c, 0x5f01, 0x5f18, 0x5f17, + 0x5fc5, 0x620a, 0x6253, 0x6254, 0x6252, 0x6251, 0x65a5, 0x65e6, + 0x672e, 0x672c, 0x672a, 0x672b, 0x672d, 0x6b63, 0x6bcd, 0x6c11, + 0x6c10, 0x6c38, 0x6c41, 0x6c40, 0x6c3e, 0x72af, 0x7384, 0x7389, + 0x74dc, 0x74e6, 0x7518, 0x751f, 0x7528, 0x7529, 0x7530, 0x7531, + 0x7532, 0x7533, 0x758b, 0x767d, 0x76ae, 0x76bf, 0x76ee, 0x77db, + 0x77e2, 0x77f3, 0x793a, 0x79be, 0x7a74, 0x7acb, 0x4e1e, 0x4e1f, + 0x4e52, 0x4e53, 0x4e69, 0x4e99, 0x4ea4, 0x4ea6, 0x4ea5, 0x4eff, + 0x4f09, 0x4f19, 0x4f0a, 0x4f15, 0x4f0d, 0x4f10, 0x4f11, 0x4f0f, + 0x4ef2, 0x4ef6, 0x4efb, 0x4ef0, 0x4ef3, 0x4efd, 0x4f01, 0x4f0b, + 0x5149, 0x5147, 0x5146, 0x5148, 0x5168, + /* 0xa6 */ + 0x5171, 0x518d, 0x51b0, 0x5217, 0x5211, 0x5212, 0x520e, 0x5216, + 0x52a3, 0x5308, 0x5321, 0x5320, 0x5370, 0x5371, 0x5409, 0x540f, + 0x540c, 0x540a, 0x5410, 0x5401, 0x540b, 0x5404, 0x5411, 0x540d, + 0x5408, 0x5403, 0x540e, 0x5406, 0x5412, 0x56e0, 0x56de, 0x56dd, + 0x5733, 0x5730, 0x5728, 0x572d, 0x572c, 0x572f, 0x5729, 0x5919, + 0x591a, 0x5937, 0x5938, 0x5984, 0x5978, 0x5983, 0x597d, 0x5979, + 0x5982, 0x5981, 0x5b57, 0x5b58, 0x5b87, 0x5b88, 0x5b85, 0x5b89, + 0x5bfa, 0x5c16, 0x5c79, 0x5dde, 0x5e06, 0x5e76, 0x5e74, 0x5f0f, + 0x5f1b, 0x5fd9, 0x5fd6, 0x620e, 0x620c, 0x620d, 0x6210, 0x6263, + 0x625b, 0x6258, 0x6536, 0x65e9, 0x65e8, 0x65ec, 0x65ed, 0x66f2, + 0x66f3, 0x6709, 0x673d, 0x6734, 0x6731, 0x6735, 0x6b21, 0x6b64, + 0x6b7b, 0x6c16, 0x6c5d, 0x6c57, 0x6c59, 0x6c5f, 0x6c60, 0x6c50, + 0x6c55, 0x6c61, 0x6c5b, 0x6c4d, 0x6c4e, 0x7070, 0x725f, 0x725d, + 0x767e, 0x7af9, 0x7c73, 0x7cf8, 0x7f36, 0x7f8a, 0x7fbd, 0x8001, + 0x8003, 0x800c, 0x8012, 0x8033, 0x807f, 0x8089, 0x808b, 0x808c, + 0x81e3, 0x81ea, 0x81f3, 0x81fc, 0x820c, 0x821b, 0x821f, 0x826e, + 0x8272, 0x827e, 0x866b, 0x8840, 0x884c, 0x8863, 0x897f, 0x9621, + 0x4e32, 0x4ea8, 0x4f4d, 0x4f4f, 0x4f47, 0x4f57, 0x4f5e, 0x4f34, + 0x4f5b, 0x4f55, 0x4f30, 0x4f50, 0x4f51, 0x4f3d, 0x4f3a, 0x4f38, + 0x4f43, 0x4f54, 0x4f3c, 0x4f46, 0x4f63, + /* 0xa7 */ + 0x4f5c, 0x4f60, 0x4f2f, 0x4f4e, 0x4f36, 0x4f59, 0x4f5d, 0x4f48, + 0x4f5a, 0x514c, 0x514b, 0x514d, 0x5175, 0x51b6, 0x51b7, 0x5225, + 0x5224, 0x5229, 0x522a, 0x5228, 0x52ab, 0x52a9, 0x52aa, 0x52ac, + 0x5323, 0x5373, 0x5375, 0x541d, 0x542d, 0x541e, 0x543e, 0x5426, + 0x544e, 0x5427, 0x5446, 0x5443, 0x5433, 0x5448, 0x5442, 0x541b, + 0x5429, 0x544a, 0x5439, 0x543b, 0x5438, 0x542e, 0x5435, 0x5436, + 0x5420, 0x543c, 0x5440, 0x5431, 0x542b, 0x541f, 0x542c, 0x56ea, + 0x56f0, 0x56e4, 0x56eb, 0x574a, 0x5751, 0x5740, 0x574d, 0x5747, + 0x574e, 0x573e, 0x5750, 0x574f, 0x573b, 0x58ef, 0x593e, 0x599d, + 0x5992, 0x59a8, 0x599e, 0x59a3, 0x5999, 0x5996, 0x598d, 0x59a4, + 0x5993, 0x598a, 0x59a5, 0x5b5d, 0x5b5c, 0x5b5a, 0x5b5b, 0x5b8c, + 0x5b8b, 0x5b8f, 0x5c2c, 0x5c40, 0x5c41, 0x5c3f, 0x5c3e, 0x5c90, + 0x5c91, 0x5c94, 0x5c8c, 0x5deb, 0x5e0c, 0x5e8f, 0x5e87, 0x5e8a, + 0x5ef7, 0x5f04, 0x5f1f, 0x5f64, 0x5f62, 0x5f77, 0x5f79, 0x5fd8, + 0x5fcc, 0x5fd7, 0x5fcd, 0x5ff1, 0x5feb, 0x5ff8, 0x5fea, 0x6212, + 0x6211, 0x6284, 0x6297, 0x6296, 0x6280, 0x6276, 0x6289, 0x626d, + 0x628a, 0x627c, 0x627e, 0x6279, 0x6273, 0x6292, 0x626f, 0x6298, + 0x626e, 0x6295, 0x6293, 0x6291, 0x6286, 0x6539, 0x653b, 0x6538, + 0x65f1, 0x66f4, 0x675f, 0x674e, 0x674f, 0x6750, 0x6751, 0x675c, + 0x6756, 0x675e, 0x6749, 0x6746, 0x6760, + /* 0xa8 */ + 0x6753, 0x6757, 0x6b65, 0x6bcf, 0x6c42, 0x6c5e, 0x6c99, 0x6c81, + 0x6c88, 0x6c89, 0x6c85, 0x6c9b, 0x6c6a, 0x6c7a, 0x6c90, 0x6c70, + 0x6c8c, 0x6c68, 0x6c96, 0x6c92, 0x6c7d, 0x6c83, 0x6c72, 0x6c7e, + 0x6c74, 0x6c86, 0x6c76, 0x6c8d, 0x6c94, 0x6c98, 0x6c82, 0x7076, + 0x707c, 0x707d, 0x7078, 0x7262, 0x7261, 0x7260, 0x72c4, 0x72c2, + 0x7396, 0x752c, 0x752b, 0x7537, 0x7538, 0x7682, 0x76ef, 0x77e3, + 0x79c1, 0x79c0, 0x79bf, 0x7a76, 0x7cfb, 0x7f55, 0x8096, 0x8093, + 0x809d, 0x8098, 0x809b, 0x809a, 0x80b2, 0x826f, 0x8292, 0x828b, + 0x828d, 0x898b, 0x89d2, 0x8a00, 0x8c37, 0x8c46, 0x8c55, 0x8c9d, + 0x8d64, 0x8d70, 0x8db3, 0x8eab, 0x8eca, 0x8f9b, 0x8fb0, 0x8fc2, + 0x8fc6, 0x8fc5, 0x8fc4, 0x5de1, 0x9091, 0x90a2, 0x90aa, 0x90a6, + 0x90a3, 0x9149, 0x91c6, 0x91cc, 0x9632, 0x962e, 0x9631, 0x962a, + 0x962c, 0x4e26, 0x4e56, 0x4e73, 0x4e8b, 0x4e9b, 0x4e9e, 0x4eab, + 0x4eac, 0x4f6f, 0x4f9d, 0x4f8d, 0x4f73, 0x4f7f, 0x4f6c, 0x4f9b, + 0x4f8b, 0x4f86, 0x4f83, 0x4f70, 0x4f75, 0x4f88, 0x4f69, 0x4f7b, + 0x4f96, 0x4f7e, 0x4f8f, 0x4f91, 0x4f7a, 0x5154, 0x5152, 0x5155, + 0x5169, 0x5177, 0x5176, 0x5178, 0x51bd, 0x51fd, 0x523b, 0x5238, + 0x5237, 0x523a, 0x5230, 0x522e, 0x5236, 0x5241, 0x52be, 0x52bb, + 0x5352, 0x5354, 0x5353, 0x5351, 0x5366, 0x5377, 0x5378, 0x5379, + 0x53d6, 0x53d4, 0x53d7, 0x5473, 0x5475, + /* 0xa9 */ + 0x5496, 0x5478, 0x5495, 0x5480, 0x547b, 0x5477, 0x5484, 0x5492, + 0x5486, 0x547c, 0x5490, 0x5471, 0x5476, 0x548c, 0x549a, 0x5462, + 0x5468, 0x548b, 0x547d, 0x548e, 0x56fa, 0x5783, 0x5777, 0x576a, + 0x5769, 0x5761, 0x5766, 0x5764, 0x577c, 0x591c, 0x5949, 0x5947, + 0x5948, 0x5944, 0x5954, 0x59be, 0x59bb, 0x59d4, 0x59b9, 0x59ae, + 0x59d1, 0x59c6, 0x59d0, 0x59cd, 0x59cb, 0x59d3, 0x59ca, 0x59af, + 0x59b3, 0x59d2, 0x59c5, 0x5b5f, 0x5b64, 0x5b63, 0x5b97, 0x5b9a, + 0x5b98, 0x5b9c, 0x5b99, 0x5b9b, 0x5c1a, 0x5c48, 0x5c45, 0x5c46, + 0x5cb7, 0x5ca1, 0x5cb8, 0x5ca9, 0x5cab, 0x5cb1, 0x5cb3, 0x5e18, + 0x5e1a, 0x5e16, 0x5e15, 0x5e1b, 0x5e11, 0x5e78, 0x5e9a, 0x5e97, + 0x5e9c, 0x5e95, 0x5e96, 0x5ef6, 0x5f26, 0x5f27, 0x5f29, 0x5f80, + 0x5f81, 0x5f7f, 0x5f7c, 0x5fdd, 0x5fe0, 0x5ffd, 0x5ff5, 0x5fff, + 0x600f, 0x6014, 0x602f, 0x6035, 0x6016, 0x602a, 0x6015, 0x6021, + 0x6027, 0x6029, 0x602b, 0x601b, 0x6216, 0x6215, 0x623f, 0x623e, + 0x6240, 0x627f, 0x62c9, 0x62cc, 0x62c4, 0x62bf, 0x62c2, 0x62b9, + 0x62d2, 0x62db, 0x62ab, 0x62d3, 0x62d4, 0x62cb, 0x62c8, 0x62a8, + 0x62bd, 0x62bc, 0x62d0, 0x62d9, 0x62c7, 0x62cd, 0x62b5, 0x62da, + 0x62b1, 0x62d8, 0x62d6, 0x62d7, 0x62c6, 0x62ac, 0x62ce, 0x653e, + 0x65a7, 0x65bc, 0x65fa, 0x6614, 0x6613, 0x660c, 0x6606, 0x6602, + 0x660e, 0x6600, 0x660f, 0x6615, 0x660a, + /* 0xaa */ + 0x6607, 0x670d, 0x670b, 0x676d, 0x678b, 0x6795, 0x6771, 0x679c, + 0x6773, 0x6777, 0x6787, 0x679d, 0x6797, 0x676f, 0x6770, 0x677f, + 0x6789, 0x677e, 0x6790, 0x6775, 0x679a, 0x6793, 0x677c, 0x676a, + 0x6772, 0x6b23, 0x6b66, 0x6b67, 0x6b7f, 0x6c13, 0x6c1b, 0x6ce3, + 0x6ce8, 0x6cf3, 0x6cb1, 0x6ccc, 0x6ce5, 0x6cb3, 0x6cbd, 0x6cbe, + 0x6cbc, 0x6ce2, 0x6cab, 0x6cd5, 0x6cd3, 0x6cb8, 0x6cc4, 0x6cb9, + 0x6cc1, 0x6cae, 0x6cd7, 0x6cc5, 0x6cf1, 0x6cbf, 0x6cbb, 0x6ce1, + 0x6cdb, 0x6cca, 0x6cac, 0x6cef, 0x6cdc, 0x6cd6, 0x6ce0, 0x7095, + 0x708e, 0x7092, 0x708a, 0x7099, 0x722c, 0x722d, 0x7238, 0x7248, + 0x7267, 0x7269, 0x72c0, 0x72ce, 0x72d9, 0x72d7, 0x72d0, 0x73a9, + 0x73a8, 0x739f, 0x73ab, 0x73a5, 0x753d, 0x759d, 0x7599, 0x759a, + 0x7684, 0x76c2, 0x76f2, 0x76f4, 0x77e5, 0x77fd, 0x793e, 0x7940, + 0x7941, 0x79c9, 0x79c8, 0x7a7a, 0x7a79, 0x7afa, 0x7cfe, 0x7f54, + 0x7f8c, 0x7f8b, 0x8005, 0x80ba, 0x80a5, 0x80a2, 0x80b1, 0x80a1, + 0x80ab, 0x80a9, 0x80b4, 0x80aa, 0x80af, 0x81e5, 0x81fe, 0x820d, + 0x82b3, 0x829d, 0x8299, 0x82ad, 0x82bd, 0x829f, 0x82b9, 0x82b1, + 0x82ac, 0x82a5, 0x82af, 0x82b8, 0x82a3, 0x82b0, 0x82be, 0x82b7, + 0x864e, 0x8671, 0x521d, 0x8868, 0x8ecb, 0x8fce, 0x8fd4, 0x8fd1, + 0x90b5, 0x90b8, 0x90b1, 0x90b6, 0x91c7, 0x91d1, 0x9577, 0x9580, + 0x961c, 0x9640, 0x963f, 0x963b, 0x9644, + /* 0xab */ + 0x9642, 0x96b9, 0x96e8, 0x9752, 0x975e, 0x4e9f, 0x4ead, 0x4eae, + 0x4fe1, 0x4fb5, 0x4faf, 0x4fbf, 0x4fe0, 0x4fd1, 0x4fcf, 0x4fdd, + 0x4fc3, 0x4fb6, 0x4fd8, 0x4fdf, 0x4fca, 0x4fd7, 0x4fae, 0x4fd0, + 0x4fc4, 0x4fc2, 0x4fda, 0x4fce, 0x4fde, 0x4fb7, 0x5157, 0x5192, + 0x5191, 0x51a0, 0x524e, 0x5243, 0x524a, 0x524d, 0x524c, 0x524b, + 0x5247, 0x52c7, 0x52c9, 0x52c3, 0x52c1, 0x530d, 0x5357, 0x537b, + 0x539a, 0x53db, 0x54ac, 0x54c0, 0x54a8, 0x54ce, 0x54c9, 0x54b8, + 0x54a6, 0x54b3, 0x54c7, 0x54c2, 0x54bd, 0x54aa, 0x54c1, 0x54c4, + 0x54c8, 0x54af, 0x54ab, 0x54b1, 0x54bb, 0x54a9, 0x54a7, 0x54bf, + 0x56ff, 0x5782, 0x578b, 0x57a0, 0x57a3, 0x57a2, 0x57ce, 0x57ae, + 0x5793, 0x5955, 0x5951, 0x594f, 0x594e, 0x5950, 0x59dc, 0x59d8, + 0x59ff, 0x59e3, 0x59e8, 0x5a03, 0x59e5, 0x59ea, 0x59da, 0x59e6, + 0x5a01, 0x59fb, 0x5b69, 0x5ba3, 0x5ba6, 0x5ba4, 0x5ba2, 0x5ba5, + 0x5c01, 0x5c4e, 0x5c4f, 0x5c4d, 0x5c4b, 0x5cd9, 0x5cd2, 0x5df7, + 0x5e1d, 0x5e25, 0x5e1f, 0x5e7d, 0x5ea0, 0x5ea6, 0x5efa, 0x5f08, + 0x5f2d, 0x5f65, 0x5f88, 0x5f85, 0x5f8a, 0x5f8b, 0x5f87, 0x5f8c, + 0x5f89, 0x6012, 0x601d, 0x6020, 0x6025, 0x600e, 0x6028, 0x604d, + 0x6070, 0x6068, 0x6062, 0x6046, 0x6043, 0x606c, 0x606b, 0x606a, + 0x6064, 0x6241, 0x62dc, 0x6316, 0x6309, 0x62fc, 0x62ed, 0x6301, + 0x62ee, 0x62fd, 0x6307, 0x62f1, 0x62f7, + /* 0xac */ + 0x62ef, 0x62ec, 0x62fe, 0x62f4, 0x6311, 0x6302, 0x653f, 0x6545, + 0x65ab, 0x65bd, 0x65e2, 0x6625, 0x662d, 0x6620, 0x6627, 0x662f, + 0x661f, 0x6628, 0x6631, 0x6624, 0x66f7, 0x67ff, 0x67d3, 0x67f1, + 0x67d4, 0x67d0, 0x67ec, 0x67b6, 0x67af, 0x67f5, 0x67e9, 0x67ef, + 0x67c4, 0x67d1, 0x67b4, 0x67da, 0x67e5, 0x67b8, 0x67cf, 0x67de, + 0x67f3, 0x67b0, 0x67d9, 0x67e2, 0x67dd, 0x67d2, 0x6b6a, 0x6b83, + 0x6b86, 0x6bb5, 0x6bd2, 0x6bd7, 0x6c1f, 0x6cc9, 0x6d0b, 0x6d32, + 0x6d2a, 0x6d41, 0x6d25, 0x6d0c, 0x6d31, 0x6d1e, 0x6d17, 0x6d3b, + 0x6d3d, 0x6d3e, 0x6d36, 0x6d1b, 0x6cf5, 0x6d39, 0x6d27, 0x6d38, + 0x6d29, 0x6d2e, 0x6d35, 0x6d0e, 0x6d2b, 0x70ab, 0x70ba, 0x70b3, + 0x70ac, 0x70af, 0x70ad, 0x70b8, 0x70ae, 0x70a4, 0x7230, 0x7272, + 0x726f, 0x7274, 0x72e9, 0x72e0, 0x72e1, 0x73b7, 0x73ca, 0x73bb, + 0x73b2, 0x73cd, 0x73c0, 0x73b3, 0x751a, 0x752d, 0x754f, 0x754c, + 0x754e, 0x754b, 0x75ab, 0x75a4, 0x75a5, 0x75a2, 0x75a3, 0x7678, + 0x7686, 0x7687, 0x7688, 0x76c8, 0x76c6, 0x76c3, 0x76c5, 0x7701, + 0x76f9, 0x76f8, 0x7709, 0x770b, 0x76fe, 0x76fc, 0x7707, 0x77dc, + 0x7802, 0x7814, 0x780c, 0x780d, 0x7946, 0x7949, 0x7948, 0x7947, + 0x79b9, 0x79ba, 0x79d1, 0x79d2, 0x79cb, 0x7a7f, 0x7a81, 0x7aff, + 0x7afd, 0x7c7d, 0x7d02, 0x7d05, 0x7d00, 0x7d09, 0x7d07, 0x7d04, + 0x7d06, 0x7f38, 0x7f8e, 0x7fbf, 0x8004, + /* 0xad */ + 0x8010, 0x800d, 0x8011, 0x8036, 0x80d6, 0x80e5, 0x80da, 0x80c3, + 0x80c4, 0x80cc, 0x80e1, 0x80db, 0x80ce, 0x80de, 0x80e4, 0x80dd, + 0x81f4, 0x8222, 0x82e7, 0x8303, 0x8305, 0x82e3, 0x82db, 0x82e6, + 0x8304, 0x82e5, 0x8302, 0x8309, 0x82d2, 0x82d7, 0x82f1, 0x8301, + 0x82dc, 0x82d4, 0x82d1, 0x82de, 0x82d3, 0x82df, 0x82ef, 0x8306, + 0x8650, 0x8679, 0x867b, 0x867a, 0x884d, 0x886b, 0x8981, 0x89d4, + 0x8a08, 0x8a02, 0x8a03, 0x8c9e, 0x8ca0, 0x8d74, 0x8d73, 0x8db4, + 0x8ecd, 0x8ecc, 0x8ff0, 0x8fe6, 0x8fe2, 0x8fea, 0x8fe5, 0x8fed, + 0x8feb, 0x8fe4, 0x8fe8, 0x90ca, 0x90ce, 0x90c1, 0x90c3, 0x914b, + 0x914a, 0x91cd, 0x9582, 0x9650, 0x964b, 0x964c, 0x964d, 0x9762, + 0x9769, 0x97cb, 0x97ed, 0x97f3, 0x9801, 0x98a8, 0x98db, 0x98df, + 0x9996, 0x9999, 0x4e58, 0x4eb3, 0x500c, 0x500d, 0x5023, 0x4fef, + 0x5026, 0x5025, 0x4ff8, 0x5029, 0x5016, 0x5006, 0x503c, 0x501f, + 0x501a, 0x5012, 0x5011, 0x4ffa, 0x5000, 0x5014, 0x5028, 0x4ff1, + 0x5021, 0x500b, 0x5019, 0x5018, 0x4ff3, 0x4fee, 0x502d, 0x502a, + 0x4ffe, 0x502b, 0x5009, 0x517c, 0x51a4, 0x51a5, 0x51a2, 0x51cd, + 0x51cc, 0x51c6, 0x51cb, 0x5256, 0x525c, 0x5254, 0x525b, 0x525d, + 0x532a, 0x537f, 0x539f, 0x539d, 0x53df, 0x54e8, 0x5510, 0x5501, + 0x5537, 0x54fc, 0x54e5, 0x54f2, 0x5506, 0x54fa, 0x5514, 0x54e9, + 0x54ed, 0x54e1, 0x5509, 0x54ee, 0x54ea, + /* 0xae */ + 0x54e6, 0x5527, 0x5507, 0x54fd, 0x550f, 0x5703, 0x5704, 0x57c2, + 0x57d4, 0x57cb, 0x57c3, 0x5809, 0x590f, 0x5957, 0x5958, 0x595a, + 0x5a11, 0x5a18, 0x5a1c, 0x5a1f, 0x5a1b, 0x5a13, 0x59ec, 0x5a20, + 0x5a23, 0x5a29, 0x5a25, 0x5a0c, 0x5a09, 0x5b6b, 0x5c58, 0x5bb0, + 0x5bb3, 0x5bb6, 0x5bb4, 0x5bae, 0x5bb5, 0x5bb9, 0x5bb8, 0x5c04, + 0x5c51, 0x5c55, 0x5c50, 0x5ced, 0x5cfd, 0x5cfb, 0x5cea, 0x5ce8, + 0x5cf0, 0x5cf6, 0x5d01, 0x5cf4, 0x5dee, 0x5e2d, 0x5e2b, 0x5eab, + 0x5ead, 0x5ea7, 0x5f31, 0x5f92, 0x5f91, 0x5f90, 0x6059, 0x6063, + 0x6065, 0x6050, 0x6055, 0x606d, 0x6069, 0x606f, 0x6084, 0x609f, + 0x609a, 0x608d, 0x6094, 0x608c, 0x6085, 0x6096, 0x6247, 0x62f3, + 0x6308, 0x62ff, 0x634e, 0x633e, 0x632f, 0x6355, 0x6342, 0x6346, + 0x634f, 0x6349, 0x633a, 0x6350, 0x633d, 0x632a, 0x632b, 0x6328, + 0x634d, 0x634c, 0x6548, 0x6549, 0x6599, 0x65c1, 0x65c5, 0x6642, + 0x6649, 0x664f, 0x6643, 0x6652, 0x664c, 0x6645, 0x6641, 0x66f8, + 0x6714, 0x6715, 0x6717, 0x6821, 0x6838, 0x6848, 0x6846, 0x6853, + 0x6839, 0x6842, 0x6854, 0x6829, 0x68b3, 0x6817, 0x684c, 0x6851, + 0x683d, 0x67f4, 0x6850, 0x6840, 0x683c, 0x6843, 0x682a, 0x6845, + 0x6813, 0x6818, 0x6841, 0x6b8a, 0x6b89, 0x6bb7, 0x6c23, 0x6c27, + 0x6c28, 0x6c26, 0x6c24, 0x6cf0, 0x6d6a, 0x6d95, 0x6d88, 0x6d87, + 0x6d66, 0x6d78, 0x6d77, 0x6d59, 0x6d93, + /* 0xaf */ + 0x6d6c, 0x6d89, 0x6d6e, 0x6d5a, 0x6d74, 0x6d69, 0x6d8c, 0x6d8a, + 0x6d79, 0x6d85, 0x6d65, 0x6d94, 0x70ca, 0x70d8, 0x70e4, 0x70d9, + 0x70c8, 0x70cf, 0x7239, 0x7279, 0x72fc, 0x72f9, 0x72fd, 0x72f8, + 0x72f7, 0x7386, 0x73ed, 0x7409, 0x73ee, 0x73e0, 0x73ea, 0x73de, + 0x7554, 0x755d, 0x755c, 0x755a, 0x7559, 0x75be, 0x75c5, 0x75c7, + 0x75b2, 0x75b3, 0x75bd, 0x75bc, 0x75b9, 0x75c2, 0x75b8, 0x768b, + 0x76b0, 0x76ca, 0x76cd, 0x76ce, 0x7729, 0x771f, 0x7720, 0x7728, + 0x77e9, 0x7830, 0x7827, 0x7838, 0x781d, 0x7834, 0x7837, 0x7825, + 0x782d, 0x7820, 0x781f, 0x7832, 0x7955, 0x7950, 0x7960, 0x795f, + 0x7956, 0x795e, 0x795d, 0x7957, 0x795a, 0x79e4, 0x79e3, 0x79e7, + 0x79df, 0x79e6, 0x79e9, 0x79d8, 0x7a84, 0x7a88, 0x7ad9, 0x7b06, + 0x7b11, 0x7c89, 0x7d21, 0x7d17, 0x7d0b, 0x7d0a, 0x7d20, 0x7d22, + 0x7d14, 0x7d10, 0x7d15, 0x7d1a, 0x7d1c, 0x7d0d, 0x7d19, 0x7d1b, + 0x7f3a, 0x7f5f, 0x7f94, 0x7fc5, 0x7fc1, 0x8006, 0x8018, 0x8015, + 0x8019, 0x8017, 0x803d, 0x803f, 0x80f1, 0x8102, 0x80f0, 0x8105, + 0x80ed, 0x80f4, 0x8106, 0x80f8, 0x80f3, 0x8108, 0x80fd, 0x810a, + 0x80fc, 0x80ef, 0x81ed, 0x81ec, 0x8200, 0x8210, 0x822a, 0x822b, + 0x8228, 0x822c, 0x82bb, 0x832b, 0x8352, 0x8354, 0x834a, 0x8338, + 0x8350, 0x8349, 0x8335, 0x8334, 0x834f, 0x8332, 0x8339, 0x8336, + 0x8317, 0x8340, 0x8331, 0x8328, 0x8343, + /* 0xb0 */ + 0x8654, 0x868a, 0x86aa, 0x8693, 0x86a4, 0x86a9, 0x868c, 0x86a3, + 0x869c, 0x8870, 0x8877, 0x8881, 0x8882, 0x887d, 0x8879, 0x8a18, + 0x8a10, 0x8a0e, 0x8a0c, 0x8a15, 0x8a0a, 0x8a17, 0x8a13, 0x8a16, + 0x8a0f, 0x8a11, 0x8c48, 0x8c7a, 0x8c79, 0x8ca1, 0x8ca2, 0x8d77, + 0x8eac, 0x8ed2, 0x8ed4, 0x8ecf, 0x8fb1, 0x9001, 0x9006, 0x8ff7, + 0x9000, 0x8ffa, 0x8ff4, 0x9003, 0x8ffd, 0x9005, 0x8ff8, 0x9095, + 0x90e1, 0x90dd, 0x90e2, 0x9152, 0x914d, 0x914c, 0x91d8, 0x91dd, + 0x91d7, 0x91dc, 0x91d9, 0x9583, 0x9662, 0x9663, 0x9661, 0x965b, + 0x965d, 0x9664, 0x9658, 0x965e, 0x96bb, 0x98e2, 0x99ac, 0x9aa8, + 0x9ad8, 0x9b25, 0x9b32, 0x9b3c, 0x4e7e, 0x507a, 0x507d, 0x505c, + 0x5047, 0x5043, 0x504c, 0x505a, 0x5049, 0x5065, 0x5076, 0x504e, + 0x5055, 0x5075, 0x5074, 0x5077, 0x504f, 0x500f, 0x506f, 0x506d, + 0x515c, 0x5195, 0x51f0, 0x526a, 0x526f, 0x52d2, 0x52d9, 0x52d8, + 0x52d5, 0x5310, 0x530f, 0x5319, 0x533f, 0x5340, 0x533e, 0x53c3, + 0x66fc, 0x5546, 0x556a, 0x5566, 0x5544, 0x555e, 0x5561, 0x5543, + 0x554a, 0x5531, 0x5556, 0x554f, 0x5555, 0x552f, 0x5564, 0x5538, + 0x552e, 0x555c, 0x552c, 0x5563, 0x5533, 0x5541, 0x5557, 0x5708, + 0x570b, 0x5709, 0x57df, 0x5805, 0x580a, 0x5806, 0x57e0, 0x57e4, + 0x57fa, 0x5802, 0x5835, 0x57f7, 0x57f9, 0x5920, 0x5962, 0x5a36, + 0x5a41, 0x5a49, 0x5a66, 0x5a6a, 0x5a40, + /* 0xb1 */ + 0x5a3c, 0x5a62, 0x5a5a, 0x5a46, 0x5a4a, 0x5b70, 0x5bc7, 0x5bc5, + 0x5bc4, 0x5bc2, 0x5bbf, 0x5bc6, 0x5c09, 0x5c08, 0x5c07, 0x5c60, + 0x5c5c, 0x5c5d, 0x5d07, 0x5d06, 0x5d0e, 0x5d1b, 0x5d16, 0x5d22, + 0x5d11, 0x5d29, 0x5d14, 0x5d19, 0x5d24, 0x5d27, 0x5d17, 0x5de2, + 0x5e38, 0x5e36, 0x5e33, 0x5e37, 0x5eb7, 0x5eb8, 0x5eb6, 0x5eb5, + 0x5ebe, 0x5f35, 0x5f37, 0x5f57, 0x5f6c, 0x5f69, 0x5f6b, 0x5f97, + 0x5f99, 0x5f9e, 0x5f98, 0x5fa1, 0x5fa0, 0x5f9c, 0x607f, 0x60a3, + 0x6089, 0x60a0, 0x60a8, 0x60cb, 0x60b4, 0x60e6, 0x60bd, 0x60c5, + 0x60bb, 0x60b5, 0x60dc, 0x60bc, 0x60d8, 0x60d5, 0x60c6, 0x60df, + 0x60b8, 0x60da, 0x60c7, 0x621a, 0x621b, 0x6248, 0x63a0, 0x63a7, + 0x6372, 0x6396, 0x63a2, 0x63a5, 0x6377, 0x6367, 0x6398, 0x63aa, + 0x6371, 0x63a9, 0x6389, 0x6383, 0x639b, 0x636b, 0x63a8, 0x6384, + 0x6388, 0x6399, 0x63a1, 0x63ac, 0x6392, 0x638f, 0x6380, 0x637b, + 0x6369, 0x6368, 0x637a, 0x655d, 0x6556, 0x6551, 0x6559, 0x6557, + 0x555f, 0x654f, 0x6558, 0x6555, 0x6554, 0x659c, 0x659b, 0x65ac, + 0x65cf, 0x65cb, 0x65cc, 0x65ce, 0x665d, 0x665a, 0x6664, 0x6668, + 0x6666, 0x665e, 0x66f9, 0x52d7, 0x671b, 0x6881, 0x68af, 0x68a2, + 0x6893, 0x68b5, 0x687f, 0x6876, 0x68b1, 0x68a7, 0x6897, 0x68b0, + 0x6883, 0x68c4, 0x68ad, 0x6886, 0x6885, 0x6894, 0x689d, 0x68a8, + 0x689f, 0x68a1, 0x6882, 0x6b32, 0x6bba, + /* 0xb2 */ + 0x6beb, 0x6bec, 0x6c2b, 0x6d8e, 0x6dbc, 0x6df3, 0x6dd9, 0x6db2, + 0x6de1, 0x6dcc, 0x6de4, 0x6dfb, 0x6dfa, 0x6e05, 0x6dc7, 0x6dcb, + 0x6daf, 0x6dd1, 0x6dae, 0x6dde, 0x6df9, 0x6db8, 0x6df7, 0x6df5, + 0x6dc5, 0x6dd2, 0x6e1a, 0x6db5, 0x6dda, 0x6deb, 0x6dd8, 0x6dea, + 0x6df1, 0x6dee, 0x6de8, 0x6dc6, 0x6dc4, 0x6daa, 0x6dec, 0x6dbf, + 0x6de6, 0x70f9, 0x7109, 0x710a, 0x70fd, 0x70ef, 0x723d, 0x727d, + 0x7281, 0x731c, 0x731b, 0x7316, 0x7313, 0x7319, 0x7387, 0x7405, + 0x740a, 0x7403, 0x7406, 0x73fe, 0x740d, 0x74e0, 0x74f6, 0x74f7, + 0x751c, 0x7522, 0x7565, 0x7566, 0x7562, 0x7570, 0x758f, 0x75d4, + 0x75d5, 0x75b5, 0x75ca, 0x75cd, 0x768e, 0x76d4, 0x76d2, 0x76db, + 0x7737, 0x773e, 0x773c, 0x7736, 0x7738, 0x773a, 0x786b, 0x7843, + 0x784e, 0x7965, 0x7968, 0x796d, 0x79fb, 0x7a92, 0x7a95, 0x7b20, + 0x7b28, 0x7b1b, 0x7b2c, 0x7b26, 0x7b19, 0x7b1e, 0x7b2e, 0x7c92, + 0x7c97, 0x7c95, 0x7d46, 0x7d43, 0x7d71, 0x7d2e, 0x7d39, 0x7d3c, + 0x7d40, 0x7d30, 0x7d33, 0x7d44, 0x7d2f, 0x7d42, 0x7d32, 0x7d31, + 0x7f3d, 0x7f9e, 0x7f9a, 0x7fcc, 0x7fce, 0x7fd2, 0x801c, 0x804a, + 0x8046, 0x812f, 0x8116, 0x8123, 0x812b, 0x8129, 0x8130, 0x8124, + 0x8202, 0x8235, 0x8237, 0x8236, 0x8239, 0x838e, 0x839e, 0x8398, + 0x8378, 0x83a2, 0x8396, 0x83bd, 0x83ab, 0x8392, 0x838a, 0x8393, + 0x8389, 0x83a0, 0x8377, 0x837b, 0x837c, + /* 0xb3 */ + 0x8386, 0x83a7, 0x8655, 0x5f6a, 0x86c7, 0x86c0, 0x86b6, 0x86c4, + 0x86b5, 0x86c6, 0x86cb, 0x86b1, 0x86af, 0x86c9, 0x8853, 0x889e, + 0x8888, 0x88ab, 0x8892, 0x8896, 0x888d, 0x888b, 0x8993, 0x898f, + 0x8a2a, 0x8a1d, 0x8a23, 0x8a25, 0x8a31, 0x8a2d, 0x8a1f, 0x8a1b, + 0x8a22, 0x8c49, 0x8c5a, 0x8ca9, 0x8cac, 0x8cab, 0x8ca8, 0x8caa, + 0x8ca7, 0x8d67, 0x8d66, 0x8dbe, 0x8dba, 0x8edb, 0x8edf, 0x9019, + 0x900d, 0x901a, 0x9017, 0x9023, 0x901f, 0x901d, 0x9010, 0x9015, + 0x901e, 0x9020, 0x900f, 0x9022, 0x9016, 0x901b, 0x9014, 0x90e8, + 0x90ed, 0x90fd, 0x9157, 0x91ce, 0x91f5, 0x91e6, 0x91e3, 0x91e7, + 0x91ed, 0x91e9, 0x9589, 0x966a, 0x9675, 0x9673, 0x9678, 0x9670, + 0x9674, 0x9676, 0x9677, 0x966c, 0x96c0, 0x96ea, 0x96e9, 0x7ae0, + 0x7adf, 0x9802, 0x9803, 0x9b5a, 0x9ce5, 0x9e75, 0x9e7f, 0x9ea5, + 0x9ebb, 0x50a2, 0x508d, 0x5085, 0x5099, 0x5091, 0x5080, 0x5096, + 0x5098, 0x509a, 0x6700, 0x51f1, 0x5272, 0x5274, 0x5275, 0x5269, + 0x52de, 0x52dd, 0x52db, 0x535a, 0x53a5, 0x557b, 0x5580, 0x55a7, + 0x557c, 0x558a, 0x559d, 0x5598, 0x5582, 0x559c, 0x55aa, 0x5594, + 0x5587, 0x558b, 0x5583, 0x55b3, 0x55ae, 0x559f, 0x553e, 0x55b2, + 0x559a, 0x55bb, 0x55ac, 0x55b1, 0x557e, 0x5589, 0x55ab, 0x5599, + 0x570d, 0x582f, 0x582a, 0x5834, 0x5824, 0x5830, 0x5831, 0x5821, + 0x581d, 0x5820, 0x58f9, 0x58fa, 0x5960, + /* 0xb4 */ + 0x5a77, 0x5a9a, 0x5a7f, 0x5a92, 0x5a9b, 0x5aa7, 0x5b73, 0x5b71, + 0x5bd2, 0x5bcc, 0x5bd3, 0x5bd0, 0x5c0a, 0x5c0b, 0x5c31, 0x5d4c, + 0x5d50, 0x5d34, 0x5d47, 0x5dfd, 0x5e45, 0x5e3d, 0x5e40, 0x5e43, + 0x5e7e, 0x5eca, 0x5ec1, 0x5ec2, 0x5ec4, 0x5f3c, 0x5f6d, 0x5fa9, + 0x5faa, 0x5fa8, 0x60d1, 0x60e1, 0x60b2, 0x60b6, 0x60e0, 0x611c, + 0x6123, 0x60fa, 0x6115, 0x60f0, 0x60fb, 0x60f4, 0x6168, 0x60f1, + 0x610e, 0x60f6, 0x6109, 0x6100, 0x6112, 0x621f, 0x6249, 0x63a3, + 0x638c, 0x63cf, 0x63c0, 0x63e9, 0x63c9, 0x63c6, 0x63cd, 0x63d2, + 0x63e3, 0x63d0, 0x63e1, 0x63d6, 0x63ed, 0x63ee, 0x6376, 0x63f4, + 0x63ea, 0x63db, 0x6452, 0x63da, 0x63f9, 0x655e, 0x6566, 0x6562, + 0x6563, 0x6591, 0x6590, 0x65af, 0x666e, 0x6670, 0x6674, 0x6676, + 0x666f, 0x6691, 0x667a, 0x667e, 0x6677, 0x66fe, 0x66ff, 0x671f, + 0x671d, 0x68fa, 0x68d5, 0x68e0, 0x68d8, 0x68d7, 0x6905, 0x68df, + 0x68f5, 0x68ee, 0x68e7, 0x68f9, 0x68d2, 0x68f2, 0x68e3, 0x68cb, + 0x68cd, 0x690d, 0x6912, 0x690e, 0x68c9, 0x68da, 0x696e, 0x68fb, + 0x6b3e, 0x6b3a, 0x6b3d, 0x6b98, 0x6b96, 0x6bbc, 0x6bef, 0x6c2e, + 0x6c2f, 0x6c2c, 0x6e2f, 0x6e38, 0x6e54, 0x6e21, 0x6e32, 0x6e67, + 0x6e4a, 0x6e20, 0x6e25, 0x6e23, 0x6e1b, 0x6e5b, 0x6e58, 0x6e24, + 0x6e56, 0x6e6e, 0x6e2d, 0x6e26, 0x6e6f, 0x6e34, 0x6e4d, 0x6e3a, + 0x6e2c, 0x6e43, 0x6e1d, 0x6e3e, 0x6ecb, + /* 0xb5 */ + 0x6e89, 0x6e19, 0x6e4e, 0x6e63, 0x6e44, 0x6e72, 0x6e69, 0x6e5f, + 0x7119, 0x711a, 0x7126, 0x7130, 0x7121, 0x7136, 0x716e, 0x711c, + 0x724c, 0x7284, 0x7280, 0x7336, 0x7325, 0x7334, 0x7329, 0x743a, + 0x742a, 0x7433, 0x7422, 0x7425, 0x7435, 0x7436, 0x7434, 0x742f, + 0x741b, 0x7426, 0x7428, 0x7525, 0x7526, 0x756b, 0x756a, 0x75e2, + 0x75db, 0x75e3, 0x75d9, 0x75d8, 0x75de, 0x75e0, 0x767b, 0x767c, + 0x7696, 0x7693, 0x76b4, 0x76dc, 0x774f, 0x77ed, 0x785d, 0x786c, + 0x786f, 0x7a0d, 0x7a08, 0x7a0b, 0x7a05, 0x7a00, 0x7a98, 0x7a97, + 0x7a96, 0x7ae5, 0x7ae3, 0x7b49, 0x7b56, 0x7b46, 0x7b50, 0x7b52, + 0x7b54, 0x7b4d, 0x7b4b, 0x7b4f, 0x7b51, 0x7c9f, 0x7ca5, 0x7d5e, + 0x7d50, 0x7d68, 0x7d55, 0x7d2b, 0x7d6e, 0x7d72, 0x7d61, 0x7d66, + 0x7d62, 0x7d70, 0x7d73, 0x5584, 0x7fd4, 0x7fd5, 0x800b, 0x8052, + 0x8085, 0x8155, 0x8154, 0x814b, 0x8151, 0x814e, 0x8139, 0x8146, + 0x813e, 0x814c, 0x8153, 0x8174, 0x8212, 0x821c, 0x83e9, 0x8403, + 0x83f8, 0x840d, 0x83e0, 0x83c5, 0x840b, 0x83c1, 0x83ef, 0x83f1, + 0x83f4, 0x8457, 0x840a, 0x83f0, 0x840c, 0x83cc, 0x83fd, 0x83f2, + 0x83ca, 0x8438, 0x840e, 0x8404, 0x83dc, 0x8407, 0x83d4, 0x83df, + 0x865b, 0x86df, 0x86d9, 0x86ed, 0x86d4, 0x86db, 0x86e4, 0x86d0, + 0x86de, 0x8857, 0x88c1, 0x88c2, 0x88b1, 0x8983, 0x8996, 0x8a3b, + 0x8a60, 0x8a55, 0x8a5e, 0x8a3c, 0x8a41, + /* 0xb6 */ + 0x8a54, 0x8a5b, 0x8a50, 0x8a46, 0x8a34, 0x8a3a, 0x8a36, 0x8a56, + 0x8c61, 0x8c82, 0x8caf, 0x8cbc, 0x8cb3, 0x8cbd, 0x8cc1, 0x8cbb, + 0x8cc0, 0x8cb4, 0x8cb7, 0x8cb6, 0x8cbf, 0x8cb8, 0x8d8a, 0x8d85, + 0x8d81, 0x8dce, 0x8ddd, 0x8dcb, 0x8dda, 0x8dd1, 0x8dcc, 0x8ddb, + 0x8dc6, 0x8efb, 0x8ef8, 0x8efc, 0x8f9c, 0x902e, 0x9035, 0x9031, + 0x9038, 0x9032, 0x9036, 0x9102, 0x90f5, 0x9109, 0x90fe, 0x9163, + 0x9165, 0x91cf, 0x9214, 0x9215, 0x9223, 0x9209, 0x921e, 0x920d, + 0x9210, 0x9207, 0x9211, 0x9594, 0x958f, 0x958b, 0x9591, 0x9593, + 0x9592, 0x958e, 0x968a, 0x968e, 0x968b, 0x967d, 0x9685, 0x9686, + 0x968d, 0x9672, 0x9684, 0x96c1, 0x96c5, 0x96c4, 0x96c6, 0x96c7, + 0x96ef, 0x96f2, 0x97cc, 0x9805, 0x9806, 0x9808, 0x98e7, 0x98ea, + 0x98ef, 0x98e9, 0x98f2, 0x98ed, 0x99ae, 0x99ad, 0x9ec3, 0x9ecd, + 0x9ed1, 0x4e82, 0x50ad, 0x50b5, 0x50b2, 0x50b3, 0x50c5, 0x50be, + 0x50ac, 0x50b7, 0x50bb, 0x50af, 0x50c7, 0x527f, 0x5277, 0x527d, + 0x52df, 0x52e6, 0x52e4, 0x52e2, 0x52e3, 0x532f, 0x55df, 0x55e8, + 0x55d3, 0x55e6, 0x55ce, 0x55dc, 0x55c7, 0x55d1, 0x55e3, 0x55e4, + 0x55ef, 0x55da, 0x55e1, 0x55c5, 0x55c6, 0x55e5, 0x55c9, 0x5712, + 0x5713, 0x585e, 0x5851, 0x5858, 0x5857, 0x585a, 0x5854, 0x586b, + 0x584c, 0x586d, 0x584a, 0x5862, 0x5852, 0x584b, 0x5967, 0x5ac1, + 0x5ac9, 0x5acc, 0x5abe, 0x5abd, 0x5abc, + /* 0xb7 */ + 0x5ab3, 0x5ac2, 0x5ab2, 0x5d69, 0x5d6f, 0x5e4c, 0x5e79, 0x5ec9, + 0x5ec8, 0x5f12, 0x5f59, 0x5fac, 0x5fae, 0x611a, 0x610f, 0x6148, + 0x611f, 0x60f3, 0x611b, 0x60f9, 0x6101, 0x6108, 0x614e, 0x614c, + 0x6144, 0x614d, 0x613e, 0x6134, 0x6127, 0x610d, 0x6106, 0x6137, + 0x6221, 0x6222, 0x6413, 0x643e, 0x641e, 0x642a, 0x642d, 0x643d, + 0x642c, 0x640f, 0x641c, 0x6414, 0x640d, 0x6436, 0x6416, 0x6417, + 0x6406, 0x656c, 0x659f, 0x65b0, 0x6697, 0x6689, 0x6687, 0x6688, + 0x6696, 0x6684, 0x6698, 0x668d, 0x6703, 0x6994, 0x696d, 0x695a, + 0x6977, 0x6960, 0x6954, 0x6975, 0x6930, 0x6982, 0x694a, 0x6968, + 0x696b, 0x695e, 0x6953, 0x6979, 0x6986, 0x695d, 0x6963, 0x695b, + 0x6b47, 0x6b72, 0x6bc0, 0x6bbf, 0x6bd3, 0x6bfd, 0x6ea2, 0x6eaf, + 0x6ed3, 0x6eb6, 0x6ec2, 0x6e90, 0x6e9d, 0x6ec7, 0x6ec5, 0x6ea5, + 0x6e98, 0x6ebc, 0x6eba, 0x6eab, 0x6ed1, 0x6e96, 0x6e9c, 0x6ec4, + 0x6ed4, 0x6eaa, 0x6ea7, 0x6eb4, 0x714e, 0x7159, 0x7169, 0x7164, + 0x7149, 0x7167, 0x715c, 0x716c, 0x7166, 0x714c, 0x7165, 0x715e, + 0x7146, 0x7168, 0x7156, 0x723a, 0x7252, 0x7337, 0x7345, 0x733f, + 0x733e, 0x746f, 0x745a, 0x7455, 0x745f, 0x745e, 0x7441, 0x743f, + 0x7459, 0x745b, 0x745c, 0x7576, 0x7578, 0x7600, 0x75f0, 0x7601, + 0x75f2, 0x75f1, 0x75fa, 0x75ff, 0x75f4, 0x75f3, 0x76de, 0x76df, + 0x775b, 0x776b, 0x7766, 0x775e, 0x7763, + /* 0xb8 */ + 0x7779, 0x776a, 0x776c, 0x775c, 0x7765, 0x7768, 0x7762, 0x77ee, + 0x788e, 0x78b0, 0x7897, 0x7898, 0x788c, 0x7889, 0x787c, 0x7891, + 0x7893, 0x787f, 0x797a, 0x797f, 0x7981, 0x842c, 0x79bd, 0x7a1c, + 0x7a1a, 0x7a20, 0x7a14, 0x7a1f, 0x7a1e, 0x7a9f, 0x7aa0, 0x7b77, + 0x7bc0, 0x7b60, 0x7b6e, 0x7b67, 0x7cb1, 0x7cb3, 0x7cb5, 0x7d93, + 0x7d79, 0x7d91, 0x7d81, 0x7d8f, 0x7d5b, 0x7f6e, 0x7f69, 0x7f6a, + 0x7f72, 0x7fa9, 0x7fa8, 0x7fa4, 0x8056, 0x8058, 0x8086, 0x8084, + 0x8171, 0x8170, 0x8178, 0x8165, 0x816e, 0x8173, 0x816b, 0x8179, + 0x817a, 0x8166, 0x8205, 0x8247, 0x8482, 0x8477, 0x843d, 0x8431, + 0x8475, 0x8466, 0x846b, 0x8449, 0x846c, 0x845b, 0x843c, 0x8435, + 0x8461, 0x8463, 0x8469, 0x846d, 0x8446, 0x865e, 0x865c, 0x865f, + 0x86f9, 0x8713, 0x8708, 0x8707, 0x8700, 0x86fe, 0x86fb, 0x8702, + 0x8703, 0x8706, 0x870a, 0x8859, 0x88df, 0x88d4, 0x88d9, 0x88dc, + 0x88d8, 0x88dd, 0x88e1, 0x88ca, 0x88d5, 0x88d2, 0x899c, 0x89e3, + 0x8a6b, 0x8a72, 0x8a73, 0x8a66, 0x8a69, 0x8a70, 0x8a87, 0x8a7c, + 0x8a63, 0x8aa0, 0x8a71, 0x8a85, 0x8a6d, 0x8a62, 0x8a6e, 0x8a6c, + 0x8a79, 0x8a7b, 0x8a3e, 0x8a68, 0x8c62, 0x8c8a, 0x8c89, 0x8cca, + 0x8cc7, 0x8cc8, 0x8cc4, 0x8cb2, 0x8cc3, 0x8cc2, 0x8cc5, 0x8de1, + 0x8ddf, 0x8de8, 0x8def, 0x8df3, 0x8dfa, 0x8dea, 0x8de4, 0x8de6, + 0x8eb2, 0x8f03, 0x8f09, 0x8efe, 0x8f0a, + /* 0xb9 */ + 0x8f9f, 0x8fb2, 0x904b, 0x904a, 0x9053, 0x9042, 0x9054, 0x903c, + 0x9055, 0x9050, 0x9047, 0x904f, 0x904e, 0x904d, 0x9051, 0x903e, + 0x9041, 0x9112, 0x9117, 0x916c, 0x916a, 0x9169, 0x91c9, 0x9237, + 0x9257, 0x9238, 0x923d, 0x9240, 0x923e, 0x925b, 0x924b, 0x9264, + 0x9251, 0x9234, 0x9249, 0x924d, 0x9245, 0x9239, 0x923f, 0x925a, + 0x9598, 0x9698, 0x9694, 0x9695, 0x96cd, 0x96cb, 0x96c9, 0x96ca, + 0x96f7, 0x96fb, 0x96f9, 0x96f6, 0x9756, 0x9774, 0x9776, 0x9810, + 0x9811, 0x9813, 0x980a, 0x9812, 0x980c, 0x98fc, 0x98f4, 0x98fd, + 0x98fe, 0x99b3, 0x99b1, 0x99b4, 0x9ae1, 0x9ce9, 0x9e82, 0x9f0e, + 0x9f13, 0x9f20, 0x50e7, 0x50ee, 0x50e5, 0x50d6, 0x50ed, 0x50da, + 0x50d5, 0x50cf, 0x50d1, 0x50f1, 0x50ce, 0x50e9, 0x5162, 0x51f3, + 0x5283, 0x5282, 0x5331, 0x53ad, 0x55fe, 0x5600, 0x561b, 0x5617, + 0x55fd, 0x5614, 0x5606, 0x5609, 0x560d, 0x560e, 0x55f7, 0x5616, + 0x561f, 0x5608, 0x5610, 0x55f6, 0x5718, 0x5716, 0x5875, 0x587e, + 0x5883, 0x5893, 0x588a, 0x5879, 0x5885, 0x587d, 0x58fd, 0x5925, + 0x5922, 0x5924, 0x596a, 0x5969, 0x5ae1, 0x5ae6, 0x5ae9, 0x5ad7, + 0x5ad6, 0x5ad8, 0x5ae3, 0x5b75, 0x5bde, 0x5be7, 0x5be1, 0x5be5, + 0x5be6, 0x5be8, 0x5be2, 0x5be4, 0x5bdf, 0x5c0d, 0x5c62, 0x5d84, + 0x5d87, 0x5e5b, 0x5e63, 0x5e55, 0x5e57, 0x5e54, 0x5ed3, 0x5ed6, + 0x5f0a, 0x5f46, 0x5f70, 0x5fb9, 0x6147, + /* 0xba */ + 0x613f, 0x614b, 0x6177, 0x6162, 0x6163, 0x615f, 0x615a, 0x6158, + 0x6175, 0x622a, 0x6487, 0x6458, 0x6454, 0x64a4, 0x6478, 0x645f, + 0x647a, 0x6451, 0x6467, 0x6434, 0x646d, 0x647b, 0x6572, 0x65a1, + 0x65d7, 0x65d6, 0x66a2, 0x66a8, 0x669d, 0x699c, 0x69a8, 0x6995, + 0x69c1, 0x69ae, 0x69d3, 0x69cb, 0x699b, 0x69b7, 0x69bb, 0x69ab, + 0x69b4, 0x69d0, 0x69cd, 0x69ad, 0x69cc, 0x69a6, 0x69c3, 0x69a3, + 0x6b49, 0x6b4c, 0x6c33, 0x6f33, 0x6f14, 0x6efe, 0x6f13, 0x6ef4, + 0x6f29, 0x6f3e, 0x6f20, 0x6f2c, 0x6f0f, 0x6f02, 0x6f22, 0x6eff, + 0x6eef, 0x6f06, 0x6f31, 0x6f38, 0x6f32, 0x6f23, 0x6f15, 0x6f2b, + 0x6f2f, 0x6f88, 0x6f2a, 0x6eec, 0x6f01, 0x6ef2, 0x6ecc, 0x6ef7, + 0x7194, 0x7199, 0x717d, 0x718a, 0x7184, 0x7192, 0x723e, 0x7292, + 0x7296, 0x7344, 0x7350, 0x7464, 0x7463, 0x746a, 0x7470, 0x746d, + 0x7504, 0x7591, 0x7627, 0x760d, 0x760b, 0x7609, 0x7613, 0x76e1, + 0x76e3, 0x7784, 0x777d, 0x777f, 0x7761, 0x78c1, 0x789f, 0x78a7, + 0x78b3, 0x78a9, 0x78a3, 0x798e, 0x798f, 0x798d, 0x7a2e, 0x7a31, + 0x7aaa, 0x7aa9, 0x7aed, 0x7aef, 0x7ba1, 0x7b95, 0x7b8b, 0x7b75, + 0x7b97, 0x7b9d, 0x7b94, 0x7b8f, 0x7bb8, 0x7b87, 0x7b84, 0x7cb9, + 0x7cbd, 0x7cbe, 0x7dbb, 0x7db0, 0x7d9c, 0x7dbd, 0x7dbe, 0x7da0, + 0x7dca, 0x7db4, 0x7db2, 0x7db1, 0x7dba, 0x7da2, 0x7dbf, 0x7db5, + 0x7db8, 0x7dad, 0x7dd2, 0x7dc7, 0x7dac, + /* 0xbb */ + 0x7f70, 0x7fe0, 0x7fe1, 0x7fdf, 0x805e, 0x805a, 0x8087, 0x8150, + 0x8180, 0x818f, 0x8188, 0x818a, 0x817f, 0x8182, 0x81e7, 0x81fa, + 0x8207, 0x8214, 0x821e, 0x824b, 0x84c9, 0x84bf, 0x84c6, 0x84c4, + 0x8499, 0x849e, 0x84b2, 0x849c, 0x84cb, 0x84b8, 0x84c0, 0x84d3, + 0x8490, 0x84bc, 0x84d1, 0x84ca, 0x873f, 0x871c, 0x873b, 0x8722, + 0x8725, 0x8734, 0x8718, 0x8755, 0x8737, 0x8729, 0x88f3, 0x8902, + 0x88f4, 0x88f9, 0x88f8, 0x88fd, 0x88e8, 0x891a, 0x88ef, 0x8aa6, + 0x8a8c, 0x8a9e, 0x8aa3, 0x8a8d, 0x8aa1, 0x8a93, 0x8aa4, 0x8aaa, + 0x8aa5, 0x8aa8, 0x8a98, 0x8a91, 0x8a9a, 0x8aa7, 0x8c6a, 0x8c8d, + 0x8c8c, 0x8cd3, 0x8cd1, 0x8cd2, 0x8d6b, 0x8d99, 0x8d95, 0x8dfc, + 0x8f14, 0x8f12, 0x8f15, 0x8f13, 0x8fa3, 0x9060, 0x9058, 0x905c, + 0x9063, 0x9059, 0x905e, 0x9062, 0x905d, 0x905b, 0x9119, 0x9118, + 0x911e, 0x9175, 0x9178, 0x9177, 0x9174, 0x9278, 0x9280, 0x9285, + 0x9298, 0x9296, 0x927b, 0x9293, 0x929c, 0x92a8, 0x927c, 0x9291, + 0x95a1, 0x95a8, 0x95a9, 0x95a3, 0x95a5, 0x95a4, 0x9699, 0x969c, + 0x969b, 0x96cc, 0x96d2, 0x9700, 0x977c, 0x9785, 0x97f6, 0x9817, + 0x9818, 0x98af, 0x98b1, 0x9903, 0x9905, 0x990c, 0x9909, 0x99c1, + 0x9aaf, 0x9ab0, 0x9ae6, 0x9b41, 0x9b42, 0x9cf4, 0x9cf6, 0x9cf3, + 0x9ebc, 0x9f3b, 0x9f4a, 0x5104, 0x5100, 0x50fb, 0x50f5, 0x50f9, + 0x5102, 0x5108, 0x5109, 0x5105, 0x51dc, + /* 0xbc */ + 0x5287, 0x5288, 0x5289, 0x528d, 0x528a, 0x52f0, 0x53b2, 0x562e, + 0x563b, 0x5639, 0x5632, 0x563f, 0x5634, 0x5629, 0x5653, 0x564e, + 0x5657, 0x5674, 0x5636, 0x562f, 0x5630, 0x5880, 0x589f, 0x589e, + 0x58b3, 0x589c, 0x58ae, 0x58a9, 0x58a6, 0x596d, 0x5b09, 0x5afb, + 0x5b0b, 0x5af5, 0x5b0c, 0x5b08, 0x5bee, 0x5bec, 0x5be9, 0x5beb, + 0x5c64, 0x5c65, 0x5d9d, 0x5d94, 0x5e62, 0x5e5f, 0x5e61, 0x5ee2, + 0x5eda, 0x5edf, 0x5edd, 0x5ee3, 0x5ee0, 0x5f48, 0x5f71, 0x5fb7, + 0x5fb5, 0x6176, 0x6167, 0x616e, 0x615d, 0x6155, 0x6182, 0x617c, + 0x6170, 0x616b, 0x617e, 0x61a7, 0x6190, 0x61ab, 0x618e, 0x61ac, + 0x619a, 0x61a4, 0x6194, 0x61ae, 0x622e, 0x6469, 0x646f, 0x6479, + 0x649e, 0x64b2, 0x6488, 0x6490, 0x64b0, 0x64a5, 0x6493, 0x6495, + 0x64a9, 0x6492, 0x64ae, 0x64ad, 0x64ab, 0x649a, 0x64ac, 0x6499, + 0x64a2, 0x64b3, 0x6575, 0x6577, 0x6578, 0x66ae, 0x66ab, 0x66b4, + 0x66b1, 0x6a23, 0x6a1f, 0x69e8, 0x6a01, 0x6a1e, 0x6a19, 0x69fd, + 0x6a21, 0x6a13, 0x6a0a, 0x69f3, 0x6a02, 0x6a05, 0x69ed, 0x6a11, + 0x6b50, 0x6b4e, 0x6ba4, 0x6bc5, 0x6bc6, 0x6f3f, 0x6f7c, 0x6f84, + 0x6f51, 0x6f66, 0x6f54, 0x6f86, 0x6f6d, 0x6f5b, 0x6f78, 0x6f6e, + 0x6f8e, 0x6f7a, 0x6f70, 0x6f64, 0x6f97, 0x6f58, 0x6ed5, 0x6f6f, + 0x6f60, 0x6f5f, 0x719f, 0x71ac, 0x71b1, 0x71a8, 0x7256, 0x729b, + 0x734e, 0x7357, 0x7469, 0x748b, 0x7483, + /* 0xbd */ + 0x747e, 0x7480, 0x757f, 0x7620, 0x7629, 0x761f, 0x7624, 0x7626, + 0x7621, 0x7622, 0x769a, 0x76ba, 0x76e4, 0x778e, 0x7787, 0x778c, + 0x7791, 0x778b, 0x78cb, 0x78c5, 0x78ba, 0x78ca, 0x78be, 0x78d5, + 0x78bc, 0x78d0, 0x7a3f, 0x7a3c, 0x7a40, 0x7a3d, 0x7a37, 0x7a3b, + 0x7aaf, 0x7aae, 0x7bad, 0x7bb1, 0x7bc4, 0x7bb4, 0x7bc6, 0x7bc7, + 0x7bc1, 0x7ba0, 0x7bcc, 0x7cca, 0x7de0, 0x7df4, 0x7def, 0x7dfb, + 0x7dd8, 0x7dec, 0x7ddd, 0x7de8, 0x7de3, 0x7dda, 0x7dde, 0x7de9, + 0x7d9e, 0x7dd9, 0x7df2, 0x7df9, 0x7f75, 0x7f77, 0x7faf, 0x7fe9, + 0x8026, 0x819b, 0x819c, 0x819d, 0x81a0, 0x819a, 0x8198, 0x8517, + 0x853d, 0x851a, 0x84ee, 0x852c, 0x852d, 0x8513, 0x8511, 0x8523, + 0x8521, 0x8514, 0x84ec, 0x8525, 0x84ff, 0x8506, 0x8782, 0x8774, + 0x8776, 0x8760, 0x8766, 0x8778, 0x8768, 0x8759, 0x8757, 0x874c, + 0x8753, 0x885b, 0x885d, 0x8910, 0x8907, 0x8912, 0x8913, 0x8915, + 0x890a, 0x8abc, 0x8ad2, 0x8ac7, 0x8ac4, 0x8a95, 0x8acb, 0x8af8, + 0x8ab2, 0x8ac9, 0x8ac2, 0x8abf, 0x8ab0, 0x8ad6, 0x8acd, 0x8ab6, + 0x8ab9, 0x8adb, 0x8c4c, 0x8c4e, 0x8c6c, 0x8ce0, 0x8cde, 0x8ce6, + 0x8ce4, 0x8cec, 0x8ced, 0x8ce2, 0x8ce3, 0x8cdc, 0x8cea, 0x8ce1, + 0x8d6d, 0x8d9f, 0x8da3, 0x8e2b, 0x8e10, 0x8e1d, 0x8e22, 0x8e0f, + 0x8e29, 0x8e1f, 0x8e21, 0x8e1e, 0x8eba, 0x8f1d, 0x8f1b, 0x8f1f, + 0x8f29, 0x8f26, 0x8f2a, 0x8f1c, 0x8f1e, + /* 0xbe */ + 0x8f25, 0x9069, 0x906e, 0x9068, 0x906d, 0x9077, 0x9130, 0x912d, + 0x9127, 0x9131, 0x9187, 0x9189, 0x918b, 0x9183, 0x92c5, 0x92bb, + 0x92b7, 0x92ea, 0x92ac, 0x92e4, 0x92c1, 0x92b3, 0x92bc, 0x92d2, + 0x92c7, 0x92f0, 0x92b2, 0x95ad, 0x95b1, 0x9704, 0x9706, 0x9707, + 0x9709, 0x9760, 0x978d, 0x978b, 0x978f, 0x9821, 0x982b, 0x981c, + 0x98b3, 0x990a, 0x9913, 0x9912, 0x9918, 0x99dd, 0x99d0, 0x99df, + 0x99db, 0x99d1, 0x99d5, 0x99d2, 0x99d9, 0x9ab7, 0x9aee, 0x9aef, + 0x9b27, 0x9b45, 0x9b44, 0x9b77, 0x9b6f, 0x9d06, 0x9d09, 0x9d03, + 0x9ea9, 0x9ebe, 0x9ece, 0x58a8, 0x9f52, 0x5112, 0x5118, 0x5114, + 0x5110, 0x5115, 0x5180, 0x51aa, 0x51dd, 0x5291, 0x5293, 0x52f3, + 0x5659, 0x566b, 0x5679, 0x5669, 0x5664, 0x5678, 0x566a, 0x5668, + 0x5665, 0x5671, 0x566f, 0x566c, 0x5662, 0x5676, 0x58c1, 0x58be, + 0x58c7, 0x58c5, 0x596e, 0x5b1d, 0x5b34, 0x5b78, 0x5bf0, 0x5c0e, + 0x5f4a, 0x61b2, 0x6191, 0x61a9, 0x618a, 0x61cd, 0x61b6, 0x61be, + 0x61ca, 0x61c8, 0x6230, 0x64c5, 0x64c1, 0x64cb, 0x64bb, 0x64bc, + 0x64da, 0x64c4, 0x64c7, 0x64c2, 0x64cd, 0x64bf, 0x64d2, 0x64d4, + 0x64be, 0x6574, 0x66c6, 0x66c9, 0x66b9, 0x66c4, 0x66c7, 0x66b8, + 0x6a3d, 0x6a38, 0x6a3a, 0x6a59, 0x6a6b, 0x6a58, 0x6a39, 0x6a44, + 0x6a62, 0x6a61, 0x6a4b, 0x6a47, 0x6a35, 0x6a5f, 0x6a48, 0x6b59, + 0x6b77, 0x6c05, 0x6fc2, 0x6fb1, 0x6fa1, + /* 0xbf */ + 0x6fc3, 0x6fa4, 0x6fc1, 0x6fa7, 0x6fb3, 0x6fc0, 0x6fb9, 0x6fb6, + 0x6fa6, 0x6fa0, 0x6fb4, 0x71be, 0x71c9, 0x71d0, 0x71d2, 0x71c8, + 0x71d5, 0x71b9, 0x71ce, 0x71d9, 0x71dc, 0x71c3, 0x71c4, 0x7368, + 0x749c, 0x74a3, 0x7498, 0x749f, 0x749e, 0x74e2, 0x750c, 0x750d, + 0x7634, 0x7638, 0x763a, 0x76e7, 0x76e5, 0x77a0, 0x779e, 0x779f, + 0x77a5, 0x78e8, 0x78da, 0x78ec, 0x78e7, 0x79a6, 0x7a4d, 0x7a4e, + 0x7a46, 0x7a4c, 0x7a4b, 0x7aba, 0x7bd9, 0x7c11, 0x7bc9, 0x7be4, + 0x7bdb, 0x7be1, 0x7be9, 0x7be6, 0x7cd5, 0x7cd6, 0x7e0a, 0x7e11, + 0x7e08, 0x7e1b, 0x7e23, 0x7e1e, 0x7e1d, 0x7e09, 0x7e10, 0x7f79, + 0x7fb2, 0x7ff0, 0x7ff1, 0x7fee, 0x8028, 0x81b3, 0x81a9, 0x81a8, + 0x81fb, 0x8208, 0x8258, 0x8259, 0x854a, 0x8559, 0x8548, 0x8568, + 0x8569, 0x8543, 0x8549, 0x856d, 0x856a, 0x855e, 0x8783, 0x879f, + 0x879e, 0x87a2, 0x878d, 0x8861, 0x892a, 0x8932, 0x8925, 0x892b, + 0x8921, 0x89aa, 0x89a6, 0x8ae6, 0x8afa, 0x8aeb, 0x8af1, 0x8b00, + 0x8adc, 0x8ae7, 0x8aee, 0x8afe, 0x8b01, 0x8b02, 0x8af7, 0x8aed, + 0x8af3, 0x8af6, 0x8afc, 0x8c6b, 0x8c6d, 0x8c93, 0x8cf4, 0x8e44, + 0x8e31, 0x8e34, 0x8e42, 0x8e39, 0x8e35, 0x8f3b, 0x8f2f, 0x8f38, + 0x8f33, 0x8fa8, 0x8fa6, 0x9075, 0x9074, 0x9078, 0x9072, 0x907c, + 0x907a, 0x9134, 0x9192, 0x9320, 0x9336, 0x92f8, 0x9333, 0x932f, + 0x9322, 0x92fc, 0x932b, 0x9304, 0x931a, + /* 0xc0 */ + 0x9310, 0x9326, 0x9321, 0x9315, 0x932e, 0x9319, 0x95bb, 0x96a7, + 0x96a8, 0x96aa, 0x96d5, 0x970e, 0x9711, 0x9716, 0x970d, 0x9713, + 0x970f, 0x975b, 0x975c, 0x9766, 0x9798, 0x9830, 0x9838, 0x983b, + 0x9837, 0x982d, 0x9839, 0x9824, 0x9910, 0x9928, 0x991e, 0x991b, + 0x9921, 0x991a, 0x99ed, 0x99e2, 0x99f1, 0x9ab8, 0x9abc, 0x9afb, + 0x9aed, 0x9b28, 0x9b91, 0x9d15, 0x9d23, 0x9d26, 0x9d28, 0x9d12, + 0x9d1b, 0x9ed8, 0x9ed4, 0x9f8d, 0x9f9c, 0x512a, 0x511f, 0x5121, + 0x5132, 0x52f5, 0x568e, 0x5680, 0x5690, 0x5685, 0x5687, 0x568f, + 0x58d5, 0x58d3, 0x58d1, 0x58ce, 0x5b30, 0x5b2a, 0x5b24, 0x5b7a, + 0x5c37, 0x5c68, 0x5dbc, 0x5dba, 0x5dbd, 0x5db8, 0x5e6b, 0x5f4c, + 0x5fbd, 0x61c9, 0x61c2, 0x61c7, 0x61e6, 0x61cb, 0x6232, 0x6234, + 0x64ce, 0x64ca, 0x64d8, 0x64e0, 0x64f0, 0x64e6, 0x64ec, 0x64f1, + 0x64e2, 0x64ed, 0x6582, 0x6583, 0x66d9, 0x66d6, 0x6a80, 0x6a94, + 0x6a84, 0x6aa2, 0x6a9c, 0x6adb, 0x6aa3, 0x6a7e, 0x6a97, 0x6a90, + 0x6aa0, 0x6b5c, 0x6bae, 0x6bda, 0x6c08, 0x6fd8, 0x6ff1, 0x6fdf, + 0x6fe0, 0x6fdb, 0x6fe4, 0x6feb, 0x6fef, 0x6f80, 0x6fec, 0x6fe1, + 0x6fe9, 0x6fd5, 0x6fee, 0x6ff0, 0x71e7, 0x71df, 0x71ee, 0x71e6, + 0x71e5, 0x71ed, 0x71ec, 0x71f4, 0x71e0, 0x7235, 0x7246, 0x7370, + 0x7372, 0x74a9, 0x74b0, 0x74a6, 0x74a8, 0x7646, 0x7642, 0x764c, + 0x76ea, 0x77b3, 0x77aa, 0x77b0, 0x77ac, + /* 0xc1 */ + 0x77a7, 0x77ad, 0x77ef, 0x78f7, 0x78fa, 0x78f4, 0x78ef, 0x7901, + 0x79a7, 0x79aa, 0x7a57, 0x7abf, 0x7c07, 0x7c0d, 0x7bfe, 0x7bf7, + 0x7c0c, 0x7be0, 0x7ce0, 0x7cdc, 0x7cde, 0x7ce2, 0x7cdf, 0x7cd9, + 0x7cdd, 0x7e2e, 0x7e3e, 0x7e46, 0x7e37, 0x7e32, 0x7e43, 0x7e2b, + 0x7e3d, 0x7e31, 0x7e45, 0x7e41, 0x7e34, 0x7e39, 0x7e48, 0x7e35, + 0x7e3f, 0x7e2f, 0x7f44, 0x7ff3, 0x7ffc, 0x8071, 0x8072, 0x8070, + 0x806f, 0x8073, 0x81c6, 0x81c3, 0x81ba, 0x81c2, 0x81c0, 0x81bf, + 0x81bd, 0x81c9, 0x81be, 0x81e8, 0x8209, 0x8271, 0x85aa, 0x8584, + 0x857e, 0x859c, 0x8591, 0x8594, 0x85af, 0x859b, 0x8587, 0x85a8, + 0x858a, 0x8667, 0x87c0, 0x87d1, 0x87b3, 0x87d2, 0x87c6, 0x87ab, + 0x87bb, 0x87ba, 0x87c8, 0x87cb, 0x893b, 0x8936, 0x8944, 0x8938, + 0x893d, 0x89ac, 0x8b0e, 0x8b17, 0x8b19, 0x8b1b, 0x8b0a, 0x8b20, + 0x8b1d, 0x8b04, 0x8b10, 0x8c41, 0x8c3f, 0x8c73, 0x8cfa, 0x8cfd, + 0x8cfc, 0x8cf8, 0x8cfb, 0x8da8, 0x8e49, 0x8e4b, 0x8e48, 0x8e4a, + 0x8f44, 0x8f3e, 0x8f42, 0x8f45, 0x8f3f, 0x907f, 0x907d, 0x9084, + 0x9081, 0x9082, 0x9080, 0x9139, 0x91a3, 0x919e, 0x919c, 0x934d, + 0x9382, 0x9328, 0x9375, 0x934a, 0x9365, 0x934b, 0x9318, 0x937e, + 0x936c, 0x935b, 0x9370, 0x935a, 0x9354, 0x95ca, 0x95cb, 0x95cc, + 0x95c8, 0x95c6, 0x96b1, 0x96b8, 0x96d6, 0x971c, 0x971e, 0x97a0, + 0x97d3, 0x9846, 0x98b6, 0x9935, 0x9a01, + /* 0xc2 */ + 0x99ff, 0x9bae, 0x9bab, 0x9baa, 0x9bad, 0x9d3b, 0x9d3f, 0x9e8b, + 0x9ecf, 0x9ede, 0x9edc, 0x9edd, 0x9edb, 0x9f3e, 0x9f4b, 0x53e2, + 0x5695, 0x56ae, 0x58d9, 0x58d8, 0x5b38, 0x5f5d, 0x61e3, 0x6233, + 0x64f4, 0x64f2, 0x64fe, 0x6506, 0x64fa, 0x64fb, 0x64f7, 0x65b7, + 0x66dc, 0x6726, 0x6ab3, 0x6aac, 0x6ac3, 0x6abb, 0x6ab8, 0x6ac2, + 0x6aae, 0x6aaf, 0x6b5f, 0x6b78, 0x6baf, 0x7009, 0x700b, 0x6ffe, + 0x7006, 0x6ffa, 0x7011, 0x700f, 0x71fb, 0x71fc, 0x71fe, 0x71f8, + 0x7377, 0x7375, 0x74a7, 0x74bf, 0x7515, 0x7656, 0x7658, 0x7652, + 0x77bd, 0x77bf, 0x77bb, 0x77bc, 0x790e, 0x79ae, 0x7a61, 0x7a62, + 0x7a60, 0x7ac4, 0x7ac5, 0x7c2b, 0x7c27, 0x7c2a, 0x7c1e, 0x7c23, + 0x7c21, 0x7ce7, 0x7e54, 0x7e55, 0x7e5e, 0x7e5a, 0x7e61, 0x7e52, + 0x7e59, 0x7f48, 0x7ff9, 0x7ffb, 0x8077, 0x8076, 0x81cd, 0x81cf, + 0x820a, 0x85cf, 0x85a9, 0x85cd, 0x85d0, 0x85c9, 0x85b0, 0x85ba, + 0x85b9, 0x85a6, 0x87ef, 0x87ec, 0x87f2, 0x87e0, 0x8986, 0x89b2, + 0x89f4, 0x8b28, 0x8b39, 0x8b2c, 0x8b2b, 0x8c50, 0x8d05, 0x8e59, + 0x8e63, 0x8e66, 0x8e64, 0x8e5f, 0x8e55, 0x8ec0, 0x8f49, 0x8f4d, + 0x9087, 0x9083, 0x9088, 0x91ab, 0x91ac, 0x91d0, 0x9394, 0x938a, + 0x9396, 0x93a2, 0x93b3, 0x93ae, 0x93ac, 0x93b0, 0x9398, 0x939a, + 0x9397, 0x95d4, 0x95d6, 0x95d0, 0x95d5, 0x96e2, 0x96dc, 0x96d9, + 0x96db, 0x96de, 0x9724, 0x97a3, 0x97a6, + /* 0xc3 */ + 0x97ad, 0x97f9, 0x984d, 0x984f, 0x984c, 0x984e, 0x9853, 0x98ba, + 0x993e, 0x993f, 0x993d, 0x992e, 0x99a5, 0x9a0e, 0x9ac1, 0x9b03, + 0x9b06, 0x9b4f, 0x9b4e, 0x9b4d, 0x9bca, 0x9bc9, 0x9bfd, 0x9bc8, + 0x9bc0, 0x9d51, 0x9d5d, 0x9d60, 0x9ee0, 0x9f15, 0x9f2c, 0x5133, + 0x56a5, 0x58de, 0x58df, 0x58e2, 0x5bf5, 0x9f90, 0x5eec, 0x61f2, + 0x61f7, 0x61f6, 0x61f5, 0x6500, 0x650f, 0x66e0, 0x66dd, 0x6ae5, + 0x6add, 0x6ada, 0x6ad3, 0x701b, 0x701f, 0x7028, 0x701a, 0x701d, + 0x7015, 0x7018, 0x7206, 0x720d, 0x7258, 0x72a2, 0x7378, 0x737a, + 0x74bd, 0x74ca, 0x74e3, 0x7587, 0x7586, 0x765f, 0x7661, 0x77c7, + 0x7919, 0x79b1, 0x7a6b, 0x7a69, 0x7c3e, 0x7c3f, 0x7c38, 0x7c3d, + 0x7c37, 0x7c40, 0x7e6b, 0x7e6d, 0x7e79, 0x7e69, 0x7e6a, 0x7f85, + 0x7e73, 0x7fb6, 0x7fb9, 0x7fb8, 0x81d8, 0x85e9, 0x85dd, 0x85ea, + 0x85d5, 0x85e4, 0x85e5, 0x85f7, 0x87fb, 0x8805, 0x880d, 0x87f9, + 0x87fe, 0x8960, 0x895f, 0x8956, 0x895e, 0x8b41, 0x8b5c, 0x8b58, + 0x8b49, 0x8b5a, 0x8b4e, 0x8b4f, 0x8b46, 0x8b59, 0x8d08, 0x8d0a, + 0x8e7c, 0x8e72, 0x8e87, 0x8e76, 0x8e6c, 0x8e7a, 0x8e74, 0x8f54, + 0x8f4e, 0x8fad, 0x908a, 0x908b, 0x91b1, 0x91ae, 0x93e1, 0x93d1, + 0x93df, 0x93c3, 0x93c8, 0x93dc, 0x93dd, 0x93d6, 0x93e2, 0x93cd, + 0x93d8, 0x93e4, 0x93d7, 0x93e8, 0x95dc, 0x96b4, 0x96e3, 0x972a, + 0x9727, 0x9761, 0x97dc, 0x97fb, 0x985e, + /* 0xc4 */ + 0x9858, 0x985b, 0x98bc, 0x9945, 0x9949, 0x9a16, 0x9a19, 0x9b0d, + 0x9be8, 0x9be7, 0x9bd6, 0x9bdb, 0x9d89, 0x9d61, 0x9d72, 0x9d6a, + 0x9d6c, 0x9e92, 0x9e97, 0x9e93, 0x9eb4, 0x52f8, 0x56a8, 0x56b7, + 0x56b6, 0x56b4, 0x56bc, 0x58e4, 0x5b40, 0x5b43, 0x5b7d, 0x5bf6, + 0x5dc9, 0x61f8, 0x61fa, 0x6518, 0x6514, 0x6519, 0x66e6, 0x6727, + 0x6aec, 0x703e, 0x7030, 0x7032, 0x7210, 0x737b, 0x74cf, 0x7662, + 0x7665, 0x7926, 0x792a, 0x792c, 0x792b, 0x7ac7, 0x7af6, 0x7c4c, + 0x7c43, 0x7c4d, 0x7cef, 0x7cf0, 0x8fae, 0x7e7d, 0x7e7c, 0x7e82, + 0x7f4c, 0x8000, 0x81da, 0x8266, 0x85fb, 0x85f9, 0x8611, 0x85fa, + 0x8606, 0x860b, 0x8607, 0x860a, 0x8814, 0x8815, 0x8964, 0x89ba, + 0x89f8, 0x8b70, 0x8b6c, 0x8b66, 0x8b6f, 0x8b5f, 0x8b6b, 0x8d0f, + 0x8d0d, 0x8e89, 0x8e81, 0x8e85, 0x8e82, 0x91b4, 0x91cb, 0x9418, + 0x9403, 0x93fd, 0x95e1, 0x9730, 0x98c4, 0x9952, 0x9951, 0x99a8, + 0x9a2b, 0x9a30, 0x9a37, 0x9a35, 0x9c13, 0x9c0d, 0x9e79, 0x9eb5, + 0x9ee8, 0x9f2f, 0x9f5f, 0x9f63, 0x9f61, 0x5137, 0x5138, 0x56c1, + 0x56c0, 0x56c2, 0x5914, 0x5c6c, 0x5dcd, 0x61fc, 0x61fe, 0x651d, + 0x651c, 0x6595, 0x66e9, 0x6afb, 0x6b04, 0x6afa, 0x6bb2, 0x704c, + 0x721b, 0x72a7, 0x74d6, 0x74d4, 0x7669, 0x77d3, 0x7c50, 0x7e8f, + 0x7e8c, 0x7fbc, 0x8617, 0x862d, 0x861a, 0x8823, 0x8822, 0x8821, + 0x881f, 0x896a, 0x896c, 0x89bd, 0x8b74, + /* 0xc5 */ + 0x8b77, 0x8b7d, 0x8d13, 0x8e8a, 0x8e8d, 0x8e8b, 0x8f5f, 0x8faf, + 0x91ba, 0x942e, 0x9433, 0x9435, 0x943a, 0x9438, 0x9432, 0x942b, + 0x95e2, 0x9738, 0x9739, 0x9732, 0x97ff, 0x9867, 0x9865, 0x9957, + 0x9a45, 0x9a43, 0x9a40, 0x9a3e, 0x9acf, 0x9b54, 0x9b51, 0x9c2d, + 0x9c25, 0x9daf, 0x9db4, 0x9dc2, 0x9db8, 0x9e9d, 0x9eef, 0x9f19, + 0x9f5c, 0x9f66, 0x9f67, 0x513c, 0x513b, 0x56c8, 0x56ca, 0x56c9, + 0x5b7f, 0x5dd4, 0x5dd2, 0x5f4e, 0x61ff, 0x6524, 0x6b0a, 0x6b61, + 0x7051, 0x7058, 0x7380, 0x74e4, 0x758a, 0x766e, 0x766c, 0x79b3, + 0x7c60, 0x7c5f, 0x807e, 0x807d, 0x81df, 0x8972, 0x896f, 0x89fc, + 0x8b80, 0x8d16, 0x8d17, 0x8e91, 0x8e93, 0x8f61, 0x9148, 0x9444, + 0x9451, 0x9452, 0x973d, 0x973e, 0x97c3, 0x97c1, 0x986b, 0x9955, + 0x9a55, 0x9a4d, 0x9ad2, 0x9b1a, 0x9c49, 0x9c31, 0x9c3e, 0x9c3b, + 0x9dd3, 0x9dd7, 0x9f34, 0x9f6c, 0x9f6a, 0x9f94, 0x56cc, 0x5dd6, + 0x6200, 0x6523, 0x652b, 0x652a, 0x66ec, 0x6b10, 0x74da, 0x7aca, + 0x7c64, 0x7c63, 0x7c65, 0x7e93, 0x7e96, 0x7e94, 0x81e2, 0x8638, + 0x863f, 0x8831, 0x8b8a, 0x9090, 0x908f, 0x9463, 0x9460, 0x9464, + 0x9768, 0x986f, 0x995c, 0x9a5a, 0x9a5b, 0x9a57, 0x9ad3, 0x9ad4, + 0x9ad1, 0x9c54, 0x9c57, 0x9c56, 0x9de5, 0x9e9f, 0x9ef4, 0x56d1, + 0x58e9, 0x652c, 0x705e, 0x7671, 0x7672, 0x77d7, 0x7f50, 0x7f88, + 0x8836, 0x8839, 0x8862, 0x8b93, 0x8b92, + /* 0xc6 */ + 0x8b96, 0x8277, 0x8d1b, 0x91c0, 0x946a, 0x9742, 0x9748, 0x9744, + 0x97c6, 0x9870, 0x9a5f, 0x9b22, 0x9b58, 0x9c5f, 0x9df9, 0x9dfa, + 0x9e7c, 0x9e7d, 0x9f07, 0x9f77, 0x9f72, 0x5ef3, 0x6b16, 0x7063, + 0x7c6c, 0x7c6e, 0x883b, 0x89c0, 0x8ea1, 0x91c1, 0x9472, 0x9470, + 0x9871, 0x995e, 0x9ad6, 0x9b23, 0x9ecc, 0x7064, 0x77da, 0x8b9a, + 0x9477, 0x97c9, 0x9a62, 0x9a65, 0x7e9c, 0x8b9c, 0x8eaa, 0x91c5, + 0x947d, 0x947e, 0x947c, 0x9c77, 0x9c78, 0x9ef7, 0x8c54, 0x947f, + 0x9e1a, 0x7228, 0x9a6a, 0x9b31, 0x9e1b, 0x9e1e, 0x7c72, 0x30fe, + 0x309d, 0x309e, 0x3005, 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, + 0x3046, 0x3047, 0x3048, 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, + 0x304e, 0x304f, 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, + 0x3056, 0x3057, 0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, + 0x305e, 0x305f, 0x3060, 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, + 0x3066, 0x3067, 0x3068, 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, + 0x306e, 0x306f, 0x3070, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, + 0x3076, 0x3077, 0x3078, 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, + 0x307e, 0x307f, 0x3080, 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, + 0x3086, 0x3087, 0x3088, 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, + 0x308e, 0x308f, 0x3090, 0x3091, 0x3092, 0x3093, 0x30a1, 0x30a2, + 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, + /* 0xc7 */ + 0x30a8, 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, + 0x30b0, 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7, + 0x30b8, 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, + 0x30c0, 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7, + 0x30c8, 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, + 0x30d0, 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7, + 0x30d8, 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, + 0x30e0, 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7, + 0x30e8, 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef, + 0x30f0, 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0x0414, + 0x0415, 0x0401, 0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, + 0x041c, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, 0x0428, 0x0429, + 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, 0x0430, 0x0431, + 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, 0x0437, 0x0438, + 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, 0x0440, + 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, 0x0448, + 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, 0x2460, + 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, + 0x2469, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478, 0x2479, 0x247a, + 0x247b, 0x247c, 0x247d, +}; +static const unsigned short big5_2uni_pagec9[7652] = { + /* 0xc9 */ + 0x4e42, 0x4e5c, 0x51f5, 0x531a, 0x5382, 0x4e07, 0x4e0c, 0x4e47, + 0x4e8d, 0x56d7, 0xfa0c, 0x5c6e, 0x5f73, 0x4e0f, 0x5187, 0x4e0e, + 0x4e2e, 0x4e93, 0x4ec2, 0x4ec9, 0x4ec8, 0x5198, 0x52fc, 0x536c, + 0x53b9, 0x5720, 0x5903, 0x592c, 0x5c10, 0x5dff, 0x65e1, 0x6bb3, + 0x6bcc, 0x6c14, 0x723f, 0x4e31, 0x4e3c, 0x4ee8, 0x4edc, 0x4ee9, + 0x4ee1, 0x4edd, 0x4eda, 0x520c, 0x531c, 0x534c, 0x5722, 0x5723, + 0x5917, 0x592f, 0x5b81, 0x5b84, 0x5c12, 0x5c3b, 0x5c74, 0x5c73, + 0x5e04, 0x5e80, 0x5e82, 0x5fc9, 0x6209, 0x6250, 0x6c15, 0x6c36, + 0x6c43, 0x6c3f, 0x6c3b, 0x72ae, 0x72b0, 0x738a, 0x79b8, 0x808a, + 0x961e, 0x4f0e, 0x4f18, 0x4f2c, 0x4ef5, 0x4f14, 0x4ef1, 0x4f00, + 0x4ef7, 0x4f08, 0x4f1d, 0x4f02, 0x4f05, 0x4f22, 0x4f13, 0x4f04, + 0x4ef4, 0x4f12, 0x51b1, 0x5213, 0x5209, 0x5210, 0x52a6, 0x5322, + 0x531f, 0x534d, 0x538a, 0x5407, 0x56e1, 0x56df, 0x572e, 0x572a, + 0x5734, 0x593c, 0x5980, 0x597c, 0x5985, 0x597b, 0x597e, 0x5977, + 0x597f, 0x5b56, 0x5c15, 0x5c25, 0x5c7c, 0x5c7a, 0x5c7b, 0x5c7e, + 0x5ddf, 0x5e75, 0x5e84, 0x5f02, 0x5f1a, 0x5f74, 0x5fd5, 0x5fd4, + 0x5fcf, 0x625c, 0x625e, 0x6264, 0x6261, 0x6266, 0x6262, 0x6259, + 0x6260, 0x625a, 0x6265, 0x65ef, 0x65ee, 0x673e, 0x6739, 0x6738, + 0x673b, 0x673a, 0x673f, 0x673c, 0x6733, 0x6c18, 0x6c46, 0x6c52, + 0x6c5c, 0x6c4f, 0x6c4a, 0x6c54, 0x6c4b, + /* 0xca */ + 0x6c4c, 0x7071, 0x725e, 0x72b4, 0x72b5, 0x738e, 0x752a, 0x767f, + 0x7a75, 0x7f51, 0x8278, 0x827c, 0x8280, 0x827d, 0x827f, 0x864d, + 0x897e, 0x9099, 0x9097, 0x9098, 0x909b, 0x9094, 0x9622, 0x9624, + 0x9620, 0x9623, 0x4f56, 0x4f3b, 0x4f62, 0x4f49, 0x4f53, 0x4f64, + 0x4f3e, 0x4f67, 0x4f52, 0x4f5f, 0x4f41, 0x4f58, 0x4f2d, 0x4f33, + 0x4f3f, 0x4f61, 0x518f, 0x51b9, 0x521c, 0x521e, 0x5221, 0x52ad, + 0x52ae, 0x5309, 0x5363, 0x5372, 0x538e, 0x538f, 0x5430, 0x5437, + 0x542a, 0x5454, 0x5445, 0x5419, 0x541c, 0x5425, 0x5418, 0x543d, + 0x544f, 0x5441, 0x5428, 0x5424, 0x5447, 0x56ee, 0x56e7, 0x56e5, + 0x5741, 0x5745, 0x574c, 0x5749, 0x574b, 0x5752, 0x5906, 0x5940, + 0x59a6, 0x5998, 0x59a0, 0x5997, 0x598e, 0x59a2, 0x5990, 0x598f, + 0x59a7, 0x59a1, 0x5b8e, 0x5b92, 0x5c28, 0x5c2a, 0x5c8d, 0x5c8f, + 0x5c88, 0x5c8b, 0x5c89, 0x5c92, 0x5c8a, 0x5c86, 0x5c93, 0x5c95, + 0x5de0, 0x5e0a, 0x5e0e, 0x5e8b, 0x5e89, 0x5e8c, 0x5e88, 0x5e8d, + 0x5f05, 0x5f1d, 0x5f78, 0x5f76, 0x5fd2, 0x5fd1, 0x5fd0, 0x5fed, + 0x5fe8, 0x5fee, 0x5ff3, 0x5fe1, 0x5fe4, 0x5fe3, 0x5ffa, 0x5fef, + 0x5ff7, 0x5ffb, 0x6000, 0x5ff4, 0x623a, 0x6283, 0x628c, 0x628e, + 0x628f, 0x6294, 0x6287, 0x6271, 0x627b, 0x627a, 0x6270, 0x6281, + 0x6288, 0x6277, 0x627d, 0x6272, 0x6274, 0x6537, 0x65f0, 0x65f4, + 0x65f3, 0x65f2, 0x65f5, 0x6745, 0x6747, + /* 0xcb */ + 0x6759, 0x6755, 0x674c, 0x6748, 0x675d, 0x674d, 0x675a, 0x674b, + 0x6bd0, 0x6c19, 0x6c1a, 0x6c78, 0x6c67, 0x6c6b, 0x6c84, 0x6c8b, + 0x6c8f, 0x6c71, 0x6c6f, 0x6c69, 0x6c9a, 0x6c6d, 0x6c87, 0x6c95, + 0x6c9c, 0x6c66, 0x6c73, 0x6c65, 0x6c7b, 0x6c8e, 0x7074, 0x707a, + 0x7263, 0x72bf, 0x72bd, 0x72c3, 0x72c6, 0x72c1, 0x72ba, 0x72c5, + 0x7395, 0x7397, 0x7393, 0x7394, 0x7392, 0x753a, 0x7539, 0x7594, + 0x7595, 0x7681, 0x793d, 0x8034, 0x8095, 0x8099, 0x8090, 0x8092, + 0x809c, 0x8290, 0x828f, 0x8285, 0x828e, 0x8291, 0x8293, 0x828a, + 0x8283, 0x8284, 0x8c78, 0x8fc9, 0x8fbf, 0x909f, 0x90a1, 0x90a5, + 0x909e, 0x90a7, 0x90a0, 0x9630, 0x9628, 0x962f, 0x962d, 0x4e33, + 0x4f98, 0x4f7c, 0x4f85, 0x4f7d, 0x4f80, 0x4f87, 0x4f76, 0x4f74, + 0x4f89, 0x4f84, 0x4f77, 0x4f4c, 0x4f97, 0x4f6a, 0x4f9a, 0x4f79, + 0x4f81, 0x4f78, 0x4f90, 0x4f9c, 0x4f94, 0x4f9e, 0x4f92, 0x4f82, + 0x4f95, 0x4f6b, 0x4f6e, 0x519e, 0x51bc, 0x51be, 0x5235, 0x5232, + 0x5233, 0x5246, 0x5231, 0x52bc, 0x530a, 0x530b, 0x533c, 0x5392, + 0x5394, 0x5487, 0x547f, 0x5481, 0x5491, 0x5482, 0x5488, 0x546b, + 0x547a, 0x547e, 0x5465, 0x546c, 0x5474, 0x5466, 0x548d, 0x546f, + 0x5461, 0x5460, 0x5498, 0x5463, 0x5467, 0x5464, 0x56f7, 0x56f9, + 0x576f, 0x5772, 0x576d, 0x576b, 0x5771, 0x5770, 0x5776, 0x5780, + 0x5775, 0x577b, 0x5773, 0x5774, 0x5762, + /* 0xcc */ + 0x5768, 0x577d, 0x590c, 0x5945, 0x59b5, 0x59ba, 0x59cf, 0x59ce, + 0x59b2, 0x59cc, 0x59c1, 0x59b6, 0x59bc, 0x59c3, 0x59d6, 0x59b1, + 0x59bd, 0x59c0, 0x59c8, 0x59b4, 0x59c7, 0x5b62, 0x5b65, 0x5b93, + 0x5b95, 0x5c44, 0x5c47, 0x5cae, 0x5ca4, 0x5ca0, 0x5cb5, 0x5caf, + 0x5ca8, 0x5cac, 0x5c9f, 0x5ca3, 0x5cad, 0x5ca2, 0x5caa, 0x5ca7, + 0x5c9d, 0x5ca5, 0x5cb6, 0x5cb0, 0x5ca6, 0x5e17, 0x5e14, 0x5e19, + 0x5f28, 0x5f22, 0x5f23, 0x5f24, 0x5f54, 0x5f82, 0x5f7e, 0x5f7d, + 0x5fde, 0x5fe5, 0x602d, 0x6026, 0x6019, 0x6032, 0x600b, 0x6034, + 0x600a, 0x6017, 0x6033, 0x601a, 0x601e, 0x602c, 0x6022, 0x600d, + 0x6010, 0x602e, 0x6013, 0x6011, 0x600c, 0x6009, 0x601c, 0x6214, + 0x623d, 0x62ad, 0x62b4, 0x62d1, 0x62be, 0x62aa, 0x62b6, 0x62ca, + 0x62ae, 0x62b3, 0x62af, 0x62bb, 0x62a9, 0x62b0, 0x62b8, 0x653d, + 0x65a8, 0x65bb, 0x6609, 0x65fc, 0x6604, 0x6612, 0x6608, 0x65fb, + 0x6603, 0x660b, 0x660d, 0x6605, 0x65fd, 0x6611, 0x6610, 0x66f6, + 0x670a, 0x6785, 0x676c, 0x678e, 0x6792, 0x6776, 0x677b, 0x6798, + 0x6786, 0x6784, 0x6774, 0x678d, 0x678c, 0x677a, 0x679f, 0x6791, + 0x6799, 0x6783, 0x677d, 0x6781, 0x6778, 0x6779, 0x6794, 0x6b25, + 0x6b80, 0x6b7e, 0x6bde, 0x6c1d, 0x6c93, 0x6cec, 0x6ceb, 0x6cee, + 0x6cd9, 0x6cb6, 0x6cd4, 0x6cad, 0x6ce7, 0x6cb7, 0x6cd0, 0x6cc2, + 0x6cba, 0x6cc3, 0x6cc6, 0x6ced, 0x6cf2, + /* 0xcd */ + 0x6cd2, 0x6cdd, 0x6cb4, 0x6c8a, 0x6c9d, 0x6c80, 0x6cde, 0x6cc0, + 0x6d30, 0x6ccd, 0x6cc7, 0x6cb0, 0x6cf9, 0x6ccf, 0x6ce9, 0x6cd1, + 0x7094, 0x7098, 0x7085, 0x7093, 0x7086, 0x7084, 0x7091, 0x7096, + 0x7082, 0x709a, 0x7083, 0x726a, 0x72d6, 0x72cb, 0x72d8, 0x72c9, + 0x72dc, 0x72d2, 0x72d4, 0x72da, 0x72cc, 0x72d1, 0x73a4, 0x73a1, + 0x73ad, 0x73a6, 0x73a2, 0x73a0, 0x73ac, 0x739d, 0x74dd, 0x74e8, + 0x753f, 0x7540, 0x753e, 0x758c, 0x7598, 0x76af, 0x76f3, 0x76f1, + 0x76f0, 0x76f5, 0x77f8, 0x77fc, 0x77f9, 0x77fb, 0x77fa, 0x77f7, + 0x7942, 0x793f, 0x79c5, 0x7a78, 0x7a7b, 0x7afb, 0x7c75, 0x7cfd, + 0x8035, 0x808f, 0x80ae, 0x80a3, 0x80b8, 0x80b5, 0x80ad, 0x8220, + 0x82a0, 0x82c0, 0x82ab, 0x829a, 0x8298, 0x829b, 0x82b5, 0x82a7, + 0x82ae, 0x82bc, 0x829e, 0x82ba, 0x82b4, 0x82a8, 0x82a1, 0x82a9, + 0x82c2, 0x82a4, 0x82c3, 0x82b6, 0x82a2, 0x8670, 0x866f, 0x866d, + 0x866e, 0x8c56, 0x8fd2, 0x8fcb, 0x8fd3, 0x8fcd, 0x8fd6, 0x8fd5, + 0x8fd7, 0x90b2, 0x90b4, 0x90af, 0x90b3, 0x90b0, 0x9639, 0x963d, + 0x963c, 0x963a, 0x9643, 0x4fcd, 0x4fc5, 0x4fd3, 0x4fb2, 0x4fc9, + 0x4fcb, 0x4fc1, 0x4fd4, 0x4fdc, 0x4fd9, 0x4fbb, 0x4fb3, 0x4fdb, + 0x4fc7, 0x4fd6, 0x4fba, 0x4fc0, 0x4fb9, 0x4fec, 0x5244, 0x5249, + 0x52c0, 0x52c2, 0x533d, 0x537c, 0x5397, 0x5396, 0x5399, 0x5398, + 0x54ba, 0x54a1, 0x54ad, 0x54a5, 0x54cf, + /* 0xce */ + 0x54c3, 0x830d, 0x54b7, 0x54ae, 0x54d6, 0x54b6, 0x54c5, 0x54c6, + 0x54a0, 0x5470, 0x54bc, 0x54a2, 0x54be, 0x5472, 0x54de, 0x54b0, + 0x57b5, 0x579e, 0x579f, 0x57a4, 0x578c, 0x5797, 0x579d, 0x579b, + 0x5794, 0x5798, 0x578f, 0x5799, 0x57a5, 0x579a, 0x5795, 0x58f4, + 0x590d, 0x5953, 0x59e1, 0x59de, 0x59ee, 0x5a00, 0x59f1, 0x59dd, + 0x59fa, 0x59fd, 0x59fc, 0x59f6, 0x59e4, 0x59f2, 0x59f7, 0x59db, + 0x59e9, 0x59f3, 0x59f5, 0x59e0, 0x59fe, 0x59f4, 0x59ed, 0x5ba8, + 0x5c4c, 0x5cd0, 0x5cd8, 0x5ccc, 0x5cd7, 0x5ccb, 0x5cdb, 0x5cde, + 0x5cda, 0x5cc9, 0x5cc7, 0x5cca, 0x5cd6, 0x5cd3, 0x5cd4, 0x5ccf, + 0x5cc8, 0x5cc6, 0x5cce, 0x5cdf, 0x5cf8, 0x5df9, 0x5e21, 0x5e22, + 0x5e23, 0x5e20, 0x5e24, 0x5eb0, 0x5ea4, 0x5ea2, 0x5e9b, 0x5ea3, + 0x5ea5, 0x5f07, 0x5f2e, 0x5f56, 0x5f86, 0x6037, 0x6039, 0x6054, + 0x6072, 0x605e, 0x6045, 0x6053, 0x6047, 0x6049, 0x605b, 0x604c, + 0x6040, 0x6042, 0x605f, 0x6024, 0x6044, 0x6058, 0x6066, 0x606e, + 0x6242, 0x6243, 0x62cf, 0x630d, 0x630b, 0x62f5, 0x630e, 0x6303, + 0x62eb, 0x62f9, 0x630f, 0x630c, 0x62f8, 0x62f6, 0x6300, 0x6313, + 0x6314, 0x62fa, 0x6315, 0x62fb, 0x62f0, 0x6541, 0x6543, 0x65aa, + 0x65bf, 0x6636, 0x6621, 0x6632, 0x6635, 0x661c, 0x6626, 0x6622, + 0x6633, 0x662b, 0x663a, 0x661d, 0x6634, 0x6639, 0x662e, 0x670f, + 0x6710, 0x67c1, 0x67f2, 0x67c8, 0x67ba, + /* 0xcf */ + 0x67dc, 0x67bb, 0x67f8, 0x67d8, 0x67c0, 0x67b7, 0x67c5, 0x67eb, + 0x67e4, 0x67df, 0x67b5, 0x67cd, 0x67b3, 0x67f7, 0x67f6, 0x67ee, + 0x67e3, 0x67c2, 0x67b9, 0x67ce, 0x67e7, 0x67f0, 0x67b2, 0x67fc, + 0x67c6, 0x67ed, 0x67cc, 0x67ae, 0x67e6, 0x67db, 0x67fa, 0x67c9, + 0x67ca, 0x67c3, 0x67ea, 0x67cb, 0x6b28, 0x6b82, 0x6b84, 0x6bb6, + 0x6bd6, 0x6bd8, 0x6be0, 0x6c20, 0x6c21, 0x6d28, 0x6d34, 0x6d2d, + 0x6d1f, 0x6d3c, 0x6d3f, 0x6d12, 0x6d0a, 0x6cda, 0x6d33, 0x6d04, + 0x6d19, 0x6d3a, 0x6d1a, 0x6d11, 0x6d00, 0x6d1d, 0x6d42, 0x6d01, + 0x6d18, 0x6d37, 0x6d03, 0x6d0f, 0x6d40, 0x6d07, 0x6d20, 0x6d2c, + 0x6d08, 0x6d22, 0x6d09, 0x6d10, 0x70b7, 0x709f, 0x70be, 0x70b1, + 0x70b0, 0x70a1, 0x70b4, 0x70b5, 0x70a9, 0x7241, 0x7249, 0x724a, + 0x726c, 0x7270, 0x7273, 0x726e, 0x72ca, 0x72e4, 0x72e8, 0x72eb, + 0x72df, 0x72ea, 0x72e6, 0x72e3, 0x7385, 0x73cc, 0x73c2, 0x73c8, + 0x73c5, 0x73b9, 0x73b6, 0x73b5, 0x73b4, 0x73eb, 0x73bf, 0x73c7, + 0x73be, 0x73c3, 0x73c6, 0x73b8, 0x73cb, 0x74ec, 0x74ee, 0x752e, + 0x7547, 0x7548, 0x75a7, 0x75aa, 0x7679, 0x76c4, 0x7708, 0x7703, + 0x7704, 0x7705, 0x770a, 0x76f7, 0x76fb, 0x76fa, 0x77e7, 0x77e8, + 0x7806, 0x7811, 0x7812, 0x7805, 0x7810, 0x780f, 0x780e, 0x7809, + 0x7803, 0x7813, 0x794a, 0x794c, 0x794b, 0x7945, 0x7944, 0x79d5, + 0x79cd, 0x79cf, 0x79d6, 0x79ce, 0x7a80, + /* 0xd0 */ + 0x7a7e, 0x7ad1, 0x7b00, 0x7b01, 0x7c7a, 0x7c78, 0x7c79, 0x7c7f, + 0x7c80, 0x7c81, 0x7d03, 0x7d08, 0x7d01, 0x7f58, 0x7f91, 0x7f8d, + 0x7fbe, 0x8007, 0x800e, 0x800f, 0x8014, 0x8037, 0x80d8, 0x80c7, + 0x80e0, 0x80d1, 0x80c8, 0x80c2, 0x80d0, 0x80c5, 0x80e3, 0x80d9, + 0x80dc, 0x80ca, 0x80d5, 0x80c9, 0x80cf, 0x80d7, 0x80e6, 0x80cd, + 0x81ff, 0x8221, 0x8294, 0x82d9, 0x82fe, 0x82f9, 0x8307, 0x82e8, + 0x8300, 0x82d5, 0x833a, 0x82eb, 0x82d6, 0x82f4, 0x82ec, 0x82e1, + 0x82f2, 0x82f5, 0x830c, 0x82fb, 0x82f6, 0x82f0, 0x82ea, 0x82e4, + 0x82e0, 0x82fa, 0x82f3, 0x82ed, 0x8677, 0x8674, 0x867c, 0x8673, + 0x8841, 0x884e, 0x8867, 0x886a, 0x8869, 0x89d3, 0x8a04, 0x8a07, + 0x8d72, 0x8fe3, 0x8fe1, 0x8fee, 0x8fe0, 0x90f1, 0x90bd, 0x90bf, + 0x90d5, 0x90c5, 0x90be, 0x90c7, 0x90cb, 0x90c8, 0x91d4, 0x91d3, + 0x9654, 0x964f, 0x9651, 0x9653, 0x964a, 0x964e, 0x501e, 0x5005, + 0x5007, 0x5013, 0x5022, 0x5030, 0x501b, 0x4ff5, 0x4ff4, 0x5033, + 0x5037, 0x502c, 0x4ff6, 0x4ff7, 0x5017, 0x501c, 0x5020, 0x5027, + 0x5035, 0x502f, 0x5031, 0x500e, 0x515a, 0x5194, 0x5193, 0x51ca, + 0x51c4, 0x51c5, 0x51c8, 0x51ce, 0x5261, 0x525a, 0x5252, 0x525e, + 0x525f, 0x5255, 0x5262, 0x52cd, 0x530e, 0x539e, 0x5526, 0x54e2, + 0x5517, 0x5512, 0x54e7, 0x54f3, 0x54e4, 0x551a, 0x54ff, 0x5504, + 0x5508, 0x54eb, 0x5511, 0x5505, 0x54f1, + /* 0xd1 */ + 0x550a, 0x54fb, 0x54f7, 0x54f8, 0x54e0, 0x550e, 0x5503, 0x550b, + 0x5701, 0x5702, 0x57cc, 0x5832, 0x57d5, 0x57d2, 0x57ba, 0x57c6, + 0x57bd, 0x57bc, 0x57b8, 0x57b6, 0x57bf, 0x57c7, 0x57d0, 0x57b9, + 0x57c1, 0x590e, 0x594a, 0x5a19, 0x5a16, 0x5a2d, 0x5a2e, 0x5a15, + 0x5a0f, 0x5a17, 0x5a0a, 0x5a1e, 0x5a33, 0x5b6c, 0x5ba7, 0x5bad, + 0x5bac, 0x5c03, 0x5c56, 0x5c54, 0x5cec, 0x5cff, 0x5cee, 0x5cf1, + 0x5cf7, 0x5d00, 0x5cf9, 0x5e29, 0x5e28, 0x5ea8, 0x5eae, 0x5eaa, + 0x5eac, 0x5f33, 0x5f30, 0x5f67, 0x605d, 0x605a, 0x6067, 0x6041, + 0x60a2, 0x6088, 0x6080, 0x6092, 0x6081, 0x609d, 0x6083, 0x6095, + 0x609b, 0x6097, 0x6087, 0x609c, 0x608e, 0x6219, 0x6246, 0x62f2, + 0x6310, 0x6356, 0x632c, 0x6344, 0x6345, 0x6336, 0x6343, 0x63e4, + 0x6339, 0x634b, 0x634a, 0x633c, 0x6329, 0x6341, 0x6334, 0x6358, + 0x6354, 0x6359, 0x632d, 0x6347, 0x6333, 0x635a, 0x6351, 0x6338, + 0x6357, 0x6340, 0x6348, 0x654a, 0x6546, 0x65c6, 0x65c3, 0x65c4, + 0x65c2, 0x664a, 0x665f, 0x6647, 0x6651, 0x6712, 0x6713, 0x681f, + 0x681a, 0x6849, 0x6832, 0x6833, 0x683b, 0x684b, 0x684f, 0x6816, + 0x6831, 0x681c, 0x6835, 0x682b, 0x682d, 0x682f, 0x684e, 0x6844, + 0x6834, 0x681d, 0x6812, 0x6814, 0x6826, 0x6828, 0x682e, 0x684d, + 0x683a, 0x6825, 0x6820, 0x6b2c, 0x6b2f, 0x6b2d, 0x6b31, 0x6b34, + 0x6b6d, 0x8082, 0x6b88, 0x6be6, 0x6be4, + /* 0xd2 */ + 0x6be8, 0x6be3, 0x6be2, 0x6be7, 0x6c25, 0x6d7a, 0x6d63, 0x6d64, + 0x6d76, 0x6d0d, 0x6d61, 0x6d92, 0x6d58, 0x6d62, 0x6d6d, 0x6d6f, + 0x6d91, 0x6d8d, 0x6def, 0x6d7f, 0x6d86, 0x6d5e, 0x6d67, 0x6d60, + 0x6d97, 0x6d70, 0x6d7c, 0x6d5f, 0x6d82, 0x6d98, 0x6d2f, 0x6d68, + 0x6d8b, 0x6d7e, 0x6d80, 0x6d84, 0x6d16, 0x6d83, 0x6d7b, 0x6d7d, + 0x6d75, 0x6d90, 0x70dc, 0x70d3, 0x70d1, 0x70dd, 0x70cb, 0x7f39, + 0x70e2, 0x70d7, 0x70d2, 0x70de, 0x70e0, 0x70d4, 0x70cd, 0x70c5, + 0x70c6, 0x70c7, 0x70da, 0x70ce, 0x70e1, 0x7242, 0x7278, 0x7277, + 0x7276, 0x7300, 0x72fa, 0x72f4, 0x72fe, 0x72f6, 0x72f3, 0x72fb, + 0x7301, 0x73d3, 0x73d9, 0x73e5, 0x73d6, 0x73bc, 0x73e7, 0x73e3, + 0x73e9, 0x73dc, 0x73d2, 0x73db, 0x73d4, 0x73dd, 0x73da, 0x73d7, + 0x73d8, 0x73e8, 0x74de, 0x74df, 0x74f4, 0x74f5, 0x7521, 0x755b, + 0x755f, 0x75b0, 0x75c1, 0x75bb, 0x75c4, 0x75c0, 0x75bf, 0x75b6, + 0x75ba, 0x768a, 0x76c9, 0x771d, 0x771b, 0x7710, 0x7713, 0x7712, + 0x7723, 0x7711, 0x7715, 0x7719, 0x771a, 0x7722, 0x7727, 0x7823, + 0x782c, 0x7822, 0x7835, 0x782f, 0x7828, 0x782e, 0x782b, 0x7821, + 0x7829, 0x7833, 0x782a, 0x7831, 0x7954, 0x795b, 0x794f, 0x795c, + 0x7953, 0x7952, 0x7951, 0x79eb, 0x79ec, 0x79e0, 0x79ee, 0x79ed, + 0x79ea, 0x79dc, 0x79de, 0x79dd, 0x7a86, 0x7a89, 0x7a85, 0x7a8b, + 0x7a8c, 0x7a8a, 0x7a87, 0x7ad8, 0x7b10, + /* 0xd3 */ + 0x7b04, 0x7b13, 0x7b05, 0x7b0f, 0x7b08, 0x7b0a, 0x7b0e, 0x7b09, + 0x7b12, 0x7c84, 0x7c91, 0x7c8a, 0x7c8c, 0x7c88, 0x7c8d, 0x7c85, + 0x7d1e, 0x7d1d, 0x7d11, 0x7d0e, 0x7d18, 0x7d16, 0x7d13, 0x7d1f, + 0x7d12, 0x7d0f, 0x7d0c, 0x7f5c, 0x7f61, 0x7f5e, 0x7f60, 0x7f5d, + 0x7f5b, 0x7f96, 0x7f92, 0x7fc3, 0x7fc2, 0x7fc0, 0x8016, 0x803e, + 0x8039, 0x80fa, 0x80f2, 0x80f9, 0x80f5, 0x8101, 0x80fb, 0x8100, + 0x8201, 0x822f, 0x8225, 0x8333, 0x832d, 0x8344, 0x8319, 0x8351, + 0x8325, 0x8356, 0x833f, 0x8341, 0x8326, 0x831c, 0x8322, 0x8342, + 0x834e, 0x831b, 0x832a, 0x8308, 0x833c, 0x834d, 0x8316, 0x8324, + 0x8320, 0x8337, 0x832f, 0x8329, 0x8347, 0x8345, 0x834c, 0x8353, + 0x831e, 0x832c, 0x834b, 0x8327, 0x8348, 0x8653, 0x8652, 0x86a2, + 0x86a8, 0x8696, 0x868d, 0x8691, 0x869e, 0x8687, 0x8697, 0x8686, + 0x868b, 0x869a, 0x8685, 0x86a5, 0x8699, 0x86a1, 0x86a7, 0x8695, + 0x8698, 0x868e, 0x869d, 0x8690, 0x8694, 0x8843, 0x8844, 0x886d, + 0x8875, 0x8876, 0x8872, 0x8880, 0x8871, 0x887f, 0x886f, 0x8883, + 0x887e, 0x8874, 0x887c, 0x8a12, 0x8c47, 0x8c57, 0x8c7b, 0x8ca4, + 0x8ca3, 0x8d76, 0x8d78, 0x8db5, 0x8db7, 0x8db6, 0x8ed1, 0x8ed3, + 0x8ffe, 0x8ff5, 0x9002, 0x8fff, 0x8ffb, 0x9004, 0x8ffc, 0x8ff6, + 0x90d6, 0x90e0, 0x90d9, 0x90da, 0x90e3, 0x90df, 0x90e5, 0x90d8, + 0x90db, 0x90d7, 0x90dc, 0x90e4, 0x9150, + /* 0xd4 */ + 0x914e, 0x914f, 0x91d5, 0x91e2, 0x91da, 0x965c, 0x965f, 0x96bc, + 0x98e3, 0x9adf, 0x9b2f, 0x4e7f, 0x5070, 0x506a, 0x5061, 0x505e, + 0x5060, 0x5053, 0x504b, 0x505d, 0x5072, 0x5048, 0x504d, 0x5041, + 0x505b, 0x504a, 0x5062, 0x5015, 0x5045, 0x505f, 0x5069, 0x506b, + 0x5063, 0x5064, 0x5046, 0x5040, 0x506e, 0x5073, 0x5057, 0x5051, + 0x51d0, 0x526b, 0x526d, 0x526c, 0x526e, 0x52d6, 0x52d3, 0x532d, + 0x539c, 0x5575, 0x5576, 0x553c, 0x554d, 0x5550, 0x5534, 0x552a, + 0x5551, 0x5562, 0x5536, 0x5535, 0x5530, 0x5552, 0x5545, 0x550c, + 0x5532, 0x5565, 0x554e, 0x5539, 0x5548, 0x552d, 0x553b, 0x5540, + 0x554b, 0x570a, 0x5707, 0x57fb, 0x5814, 0x57e2, 0x57f6, 0x57dc, + 0x57f4, 0x5800, 0x57ed, 0x57fd, 0x5808, 0x57f8, 0x580b, 0x57f3, + 0x57cf, 0x5807, 0x57ee, 0x57e3, 0x57f2, 0x57e5, 0x57ec, 0x57e1, + 0x580e, 0x57fc, 0x5810, 0x57e7, 0x5801, 0x580c, 0x57f1, 0x57e9, + 0x57f0, 0x580d, 0x5804, 0x595c, 0x5a60, 0x5a58, 0x5a55, 0x5a67, + 0x5a5e, 0x5a38, 0x5a35, 0x5a6d, 0x5a50, 0x5a5f, 0x5a65, 0x5a6c, + 0x5a53, 0x5a64, 0x5a57, 0x5a43, 0x5a5d, 0x5a52, 0x5a44, 0x5a5b, + 0x5a48, 0x5a8e, 0x5a3e, 0x5a4d, 0x5a39, 0x5a4c, 0x5a70, 0x5a69, + 0x5a47, 0x5a51, 0x5a56, 0x5a42, 0x5a5c, 0x5b72, 0x5b6e, 0x5bc1, + 0x5bc0, 0x5c59, 0x5d1e, 0x5d0b, 0x5d1d, 0x5d1a, 0x5d20, 0x5d0c, + 0x5d28, 0x5d0d, 0x5d26, 0x5d25, 0x5d0f, + /* 0xd5 */ + 0x5d30, 0x5d12, 0x5d23, 0x5d1f, 0x5d2e, 0x5e3e, 0x5e34, 0x5eb1, + 0x5eb4, 0x5eb9, 0x5eb2, 0x5eb3, 0x5f36, 0x5f38, 0x5f9b, 0x5f96, + 0x5f9f, 0x608a, 0x6090, 0x6086, 0x60be, 0x60b0, 0x60ba, 0x60d3, + 0x60d4, 0x60cf, 0x60e4, 0x60d9, 0x60dd, 0x60c8, 0x60b1, 0x60db, + 0x60b7, 0x60ca, 0x60bf, 0x60c3, 0x60cd, 0x60c0, 0x6332, 0x6365, + 0x638a, 0x6382, 0x637d, 0x63bd, 0x639e, 0x63ad, 0x639d, 0x6397, + 0x63ab, 0x638e, 0x636f, 0x6387, 0x6390, 0x636e, 0x63af, 0x6375, + 0x639c, 0x636d, 0x63ae, 0x637c, 0x63a4, 0x633b, 0x639f, 0x6378, + 0x6385, 0x6381, 0x6391, 0x638d, 0x6370, 0x6553, 0x65cd, 0x6665, + 0x6661, 0x665b, 0x6659, 0x665c, 0x6662, 0x6718, 0x6879, 0x6887, + 0x6890, 0x689c, 0x686d, 0x686e, 0x68ae, 0x68ab, 0x6956, 0x686f, + 0x68a3, 0x68ac, 0x68a9, 0x6875, 0x6874, 0x68b2, 0x688f, 0x6877, + 0x6892, 0x687c, 0x686b, 0x6872, 0x68aa, 0x6880, 0x6871, 0x687e, + 0x689b, 0x6896, 0x688b, 0x68a0, 0x6889, 0x68a4, 0x6878, 0x687b, + 0x6891, 0x688c, 0x688a, 0x687d, 0x6b36, 0x6b33, 0x6b37, 0x6b38, + 0x6b91, 0x6b8f, 0x6b8d, 0x6b8e, 0x6b8c, 0x6c2a, 0x6dc0, 0x6dab, + 0x6db4, 0x6db3, 0x6e74, 0x6dac, 0x6de9, 0x6de2, 0x6db7, 0x6df6, + 0x6dd4, 0x6e00, 0x6dc8, 0x6de0, 0x6ddf, 0x6dd6, 0x6dbe, 0x6de5, + 0x6ddc, 0x6ddd, 0x6ddb, 0x6df4, 0x6dca, 0x6dbd, 0x6ded, 0x6df0, + 0x6dba, 0x6dd5, 0x6dc2, 0x6dcf, 0x6dc9, + /* 0xd6 */ + 0x6dd0, 0x6df2, 0x6dd3, 0x6dfd, 0x6dd7, 0x6dcd, 0x6de3, 0x6dbb, + 0x70fa, 0x710d, 0x70f7, 0x7117, 0x70f4, 0x710c, 0x70f0, 0x7104, + 0x70f3, 0x7110, 0x70fc, 0x70ff, 0x7106, 0x7113, 0x7100, 0x70f8, + 0x70f6, 0x710b, 0x7102, 0x710e, 0x727e, 0x727b, 0x727c, 0x727f, + 0x731d, 0x7317, 0x7307, 0x7311, 0x7318, 0x730a, 0x7308, 0x72ff, + 0x730f, 0x731e, 0x7388, 0x73f6, 0x73f8, 0x73f5, 0x7404, 0x7401, + 0x73fd, 0x7407, 0x7400, 0x73fa, 0x73fc, 0x73ff, 0x740c, 0x740b, + 0x73f4, 0x7408, 0x7564, 0x7563, 0x75ce, 0x75d2, 0x75cf, 0x75cb, + 0x75cc, 0x75d1, 0x75d0, 0x768f, 0x7689, 0x76d3, 0x7739, 0x772f, + 0x772d, 0x7731, 0x7732, 0x7734, 0x7733, 0x773d, 0x7725, 0x773b, + 0x7735, 0x7848, 0x7852, 0x7849, 0x784d, 0x784a, 0x784c, 0x7826, + 0x7845, 0x7850, 0x7964, 0x7967, 0x7969, 0x796a, 0x7963, 0x796b, + 0x7961, 0x79bb, 0x79fa, 0x79f8, 0x79f6, 0x79f7, 0x7a8f, 0x7a94, + 0x7a90, 0x7b35, 0x7b47, 0x7b34, 0x7b25, 0x7b30, 0x7b22, 0x7b24, + 0x7b33, 0x7b18, 0x7b2a, 0x7b1d, 0x7b31, 0x7b2b, 0x7b2d, 0x7b2f, + 0x7b32, 0x7b38, 0x7b1a, 0x7b23, 0x7c94, 0x7c98, 0x7c96, 0x7ca3, + 0x7d35, 0x7d3d, 0x7d38, 0x7d36, 0x7d3a, 0x7d45, 0x7d2c, 0x7d29, + 0x7d41, 0x7d47, 0x7d3e, 0x7d3f, 0x7d4a, 0x7d3b, 0x7d28, 0x7f63, + 0x7f95, 0x7f9c, 0x7f9d, 0x7f9b, 0x7fca, 0x7fcb, 0x7fcd, 0x7fd0, + 0x7fd1, 0x7fc7, 0x7fcf, 0x7fc9, 0x801f, + /* 0xd7 */ + 0x801e, 0x801b, 0x8047, 0x8043, 0x8048, 0x8118, 0x8125, 0x8119, + 0x811b, 0x812d, 0x811f, 0x812c, 0x811e, 0x8121, 0x8115, 0x8127, + 0x811d, 0x8122, 0x8211, 0x8238, 0x8233, 0x823a, 0x8234, 0x8232, + 0x8274, 0x8390, 0x83a3, 0x83a8, 0x838d, 0x837a, 0x8373, 0x83a4, + 0x8374, 0x838f, 0x8381, 0x8395, 0x8399, 0x8375, 0x8394, 0x83a9, + 0x837d, 0x8383, 0x838c, 0x839d, 0x839b, 0x83aa, 0x838b, 0x837e, + 0x83a5, 0x83af, 0x8388, 0x8397, 0x83b0, 0x837f, 0x83a6, 0x8387, + 0x83ae, 0x8376, 0x839a, 0x8659, 0x8656, 0x86bf, 0x86b7, 0x86c2, + 0x86c1, 0x86c5, 0x86ba, 0x86b0, 0x86c8, 0x86b9, 0x86b3, 0x86b8, + 0x86cc, 0x86b4, 0x86bb, 0x86bc, 0x86c3, 0x86bd, 0x86be, 0x8852, + 0x8889, 0x8895, 0x88a8, 0x88a2, 0x88aa, 0x889a, 0x8891, 0x88a1, + 0x889f, 0x8898, 0x88a7, 0x8899, 0x889b, 0x8897, 0x88a4, 0x88ac, + 0x888c, 0x8893, 0x888e, 0x8982, 0x89d6, 0x89d9, 0x89d5, 0x8a30, + 0x8a27, 0x8a2c, 0x8a1e, 0x8c39, 0x8c3b, 0x8c5c, 0x8c5d, 0x8c7d, + 0x8ca5, 0x8d7d, 0x8d7b, 0x8d79, 0x8dbc, 0x8dc2, 0x8db9, 0x8dbf, + 0x8dc1, 0x8ed8, 0x8ede, 0x8edd, 0x8edc, 0x8ed7, 0x8ee0, 0x8ee1, + 0x9024, 0x900b, 0x9011, 0x901c, 0x900c, 0x9021, 0x90ef, 0x90ea, + 0x90f0, 0x90f4, 0x90f2, 0x90f3, 0x90d4, 0x90eb, 0x90ec, 0x90e9, + 0x9156, 0x9158, 0x915a, 0x9153, 0x9155, 0x91ec, 0x91f4, 0x91f1, + 0x91f3, 0x91f8, 0x91e4, 0x91f9, 0x91ea, + /* 0xd8 */ + 0x91eb, 0x91f7, 0x91e8, 0x91ee, 0x957a, 0x9586, 0x9588, 0x967c, + 0x966d, 0x966b, 0x9671, 0x966f, 0x96bf, 0x976a, 0x9804, 0x98e5, + 0x9997, 0x509b, 0x5095, 0x5094, 0x509e, 0x508b, 0x50a3, 0x5083, + 0x508c, 0x508e, 0x509d, 0x5068, 0x509c, 0x5092, 0x5082, 0x5087, + 0x515f, 0x51d4, 0x5312, 0x5311, 0x53a4, 0x53a7, 0x5591, 0x55a8, + 0x55a5, 0x55ad, 0x5577, 0x5645, 0x55a2, 0x5593, 0x5588, 0x558f, + 0x55b5, 0x5581, 0x55a3, 0x5592, 0x55a4, 0x557d, 0x558c, 0x55a6, + 0x557f, 0x5595, 0x55a1, 0x558e, 0x570c, 0x5829, 0x5837, 0x5819, + 0x581e, 0x5827, 0x5823, 0x5828, 0x57f5, 0x5848, 0x5825, 0x581c, + 0x581b, 0x5833, 0x583f, 0x5836, 0x582e, 0x5839, 0x5838, 0x582d, + 0x582c, 0x583b, 0x5961, 0x5aaf, 0x5a94, 0x5a9f, 0x5a7a, 0x5aa2, + 0x5a9e, 0x5a78, 0x5aa6, 0x5a7c, 0x5aa5, 0x5aac, 0x5a95, 0x5aae, + 0x5a37, 0x5a84, 0x5a8a, 0x5a97, 0x5a83, 0x5a8b, 0x5aa9, 0x5a7b, + 0x5a7d, 0x5a8c, 0x5a9c, 0x5a8f, 0x5a93, 0x5a9d, 0x5bea, 0x5bcd, + 0x5bcb, 0x5bd4, 0x5bd1, 0x5bca, 0x5bce, 0x5c0c, 0x5c30, 0x5d37, + 0x5d43, 0x5d6b, 0x5d41, 0x5d4b, 0x5d3f, 0x5d35, 0x5d51, 0x5d4e, + 0x5d55, 0x5d33, 0x5d3a, 0x5d52, 0x5d3d, 0x5d31, 0x5d59, 0x5d42, + 0x5d39, 0x5d49, 0x5d38, 0x5d3c, 0x5d32, 0x5d36, 0x5d40, 0x5d45, + 0x5e44, 0x5e41, 0x5f58, 0x5fa6, 0x5fa5, 0x5fab, 0x60c9, 0x60b9, + 0x60cc, 0x60e2, 0x60ce, 0x60c4, 0x6114, + /* 0xd9 */ + 0x60f2, 0x610a, 0x6116, 0x6105, 0x60f5, 0x6113, 0x60f8, 0x60fc, + 0x60fe, 0x60c1, 0x6103, 0x6118, 0x611d, 0x6110, 0x60ff, 0x6104, + 0x610b, 0x624a, 0x6394, 0x63b1, 0x63b0, 0x63ce, 0x63e5, 0x63e8, + 0x63ef, 0x63c3, 0x649d, 0x63f3, 0x63ca, 0x63e0, 0x63f6, 0x63d5, + 0x63f2, 0x63f5, 0x6461, 0x63df, 0x63be, 0x63dd, 0x63dc, 0x63c4, + 0x63d8, 0x63d3, 0x63c2, 0x63c7, 0x63cc, 0x63cb, 0x63c8, 0x63f0, + 0x63d7, 0x63d9, 0x6532, 0x6567, 0x656a, 0x6564, 0x655c, 0x6568, + 0x6565, 0x658c, 0x659d, 0x659e, 0x65ae, 0x65d0, 0x65d2, 0x667c, + 0x666c, 0x667b, 0x6680, 0x6671, 0x6679, 0x666a, 0x6672, 0x6701, + 0x690c, 0x68d3, 0x6904, 0x68dc, 0x692a, 0x68ec, 0x68ea, 0x68f1, + 0x690f, 0x68d6, 0x68f7, 0x68eb, 0x68e4, 0x68f6, 0x6913, 0x6910, + 0x68f3, 0x68e1, 0x6907, 0x68cc, 0x6908, 0x6970, 0x68b4, 0x6911, + 0x68ef, 0x68c6, 0x6914, 0x68f8, 0x68d0, 0x68fd, 0x68fc, 0x68e8, + 0x690b, 0x690a, 0x6917, 0x68ce, 0x68c8, 0x68dd, 0x68de, 0x68e6, + 0x68f4, 0x68d1, 0x6906, 0x68d4, 0x68e9, 0x6915, 0x6925, 0x68c7, + 0x6b39, 0x6b3b, 0x6b3f, 0x6b3c, 0x6b94, 0x6b97, 0x6b99, 0x6b95, + 0x6bbd, 0x6bf0, 0x6bf2, 0x6bf3, 0x6c30, 0x6dfc, 0x6e46, 0x6e47, + 0x6e1f, 0x6e49, 0x6e88, 0x6e3c, 0x6e3d, 0x6e45, 0x6e62, 0x6e2b, + 0x6e3f, 0x6e41, 0x6e5d, 0x6e73, 0x6e1c, 0x6e33, 0x6e4b, 0x6e40, + 0x6e51, 0x6e3b, 0x6e03, 0x6e2e, 0x6e5e, + /* 0xda */ + 0x6e68, 0x6e5c, 0x6e61, 0x6e31, 0x6e28, 0x6e60, 0x6e71, 0x6e6b, + 0x6e39, 0x6e22, 0x6e30, 0x6e53, 0x6e65, 0x6e27, 0x6e78, 0x6e64, + 0x6e77, 0x6e55, 0x6e79, 0x6e52, 0x6e66, 0x6e35, 0x6e36, 0x6e5a, + 0x7120, 0x711e, 0x712f, 0x70fb, 0x712e, 0x7131, 0x7123, 0x7125, + 0x7122, 0x7132, 0x711f, 0x7128, 0x713a, 0x711b, 0x724b, 0x725a, + 0x7288, 0x7289, 0x7286, 0x7285, 0x728b, 0x7312, 0x730b, 0x7330, + 0x7322, 0x7331, 0x7333, 0x7327, 0x7332, 0x732d, 0x7326, 0x7323, + 0x7335, 0x730c, 0x742e, 0x742c, 0x7430, 0x742b, 0x7416, 0x741a, + 0x7421, 0x742d, 0x7431, 0x7424, 0x7423, 0x741d, 0x7429, 0x7420, + 0x7432, 0x74fb, 0x752f, 0x756f, 0x756c, 0x75e7, 0x75da, 0x75e1, + 0x75e6, 0x75dd, 0x75df, 0x75e4, 0x75d7, 0x7695, 0x7692, 0x76da, + 0x7746, 0x7747, 0x7744, 0x774d, 0x7745, 0x774a, 0x774e, 0x774b, + 0x774c, 0x77de, 0x77ec, 0x7860, 0x7864, 0x7865, 0x785c, 0x786d, + 0x7871, 0x786a, 0x786e, 0x7870, 0x7869, 0x7868, 0x785e, 0x7862, + 0x7974, 0x7973, 0x7972, 0x7970, 0x7a02, 0x7a0a, 0x7a03, 0x7a0c, + 0x7a04, 0x7a99, 0x7ae6, 0x7ae4, 0x7b4a, 0x7b3b, 0x7b44, 0x7b48, + 0x7b4c, 0x7b4e, 0x7b40, 0x7b58, 0x7b45, 0x7ca2, 0x7c9e, 0x7ca8, + 0x7ca1, 0x7d58, 0x7d6f, 0x7d63, 0x7d53, 0x7d56, 0x7d67, 0x7d6a, + 0x7d4f, 0x7d6d, 0x7d5c, 0x7d6b, 0x7d52, 0x7d54, 0x7d69, 0x7d51, + 0x7d5f, 0x7d4e, 0x7f3e, 0x7f3f, 0x7f65, + /* 0xdb */ + 0x7f66, 0x7fa2, 0x7fa0, 0x7fa1, 0x7fd7, 0x8051, 0x804f, 0x8050, + 0x80fe, 0x80d4, 0x8143, 0x814a, 0x8152, 0x814f, 0x8147, 0x813d, + 0x814d, 0x813a, 0x81e6, 0x81ee, 0x81f7, 0x81f8, 0x81f9, 0x8204, + 0x823c, 0x823d, 0x823f, 0x8275, 0x833b, 0x83cf, 0x83f9, 0x8423, + 0x83c0, 0x83e8, 0x8412, 0x83e7, 0x83e4, 0x83fc, 0x83f6, 0x8410, + 0x83c6, 0x83c8, 0x83eb, 0x83e3, 0x83bf, 0x8401, 0x83dd, 0x83e5, + 0x83d8, 0x83ff, 0x83e1, 0x83cb, 0x83ce, 0x83d6, 0x83f5, 0x83c9, + 0x8409, 0x840f, 0x83de, 0x8411, 0x8406, 0x83c2, 0x83f3, 0x83d5, + 0x83fa, 0x83c7, 0x83d1, 0x83ea, 0x8413, 0x83c3, 0x83ec, 0x83ee, + 0x83c4, 0x83fb, 0x83d7, 0x83e2, 0x841b, 0x83db, 0x83fe, 0x86d8, + 0x86e2, 0x86e6, 0x86d3, 0x86e3, 0x86da, 0x86ea, 0x86dd, 0x86eb, + 0x86dc, 0x86ec, 0x86e9, 0x86d7, 0x86e8, 0x86d1, 0x8848, 0x8856, + 0x8855, 0x88ba, 0x88d7, 0x88b9, 0x88b8, 0x88c0, 0x88be, 0x88b6, + 0x88bc, 0x88b7, 0x88bd, 0x88b2, 0x8901, 0x88c9, 0x8995, 0x8998, + 0x8997, 0x89dd, 0x89da, 0x89db, 0x8a4e, 0x8a4d, 0x8a39, 0x8a59, + 0x8a40, 0x8a57, 0x8a58, 0x8a44, 0x8a45, 0x8a52, 0x8a48, 0x8a51, + 0x8a4a, 0x8a4c, 0x8a4f, 0x8c5f, 0x8c81, 0x8c80, 0x8cba, 0x8cbe, + 0x8cb0, 0x8cb9, 0x8cb5, 0x8d84, 0x8d80, 0x8d89, 0x8dd8, 0x8dd3, + 0x8dcd, 0x8dc7, 0x8dd6, 0x8ddc, 0x8dcf, 0x8dd5, 0x8dd9, 0x8dc8, + 0x8dd7, 0x8dc5, 0x8eef, 0x8ef7, 0x8efa, + /* 0xdc */ + 0x8ef9, 0x8ee6, 0x8eee, 0x8ee5, 0x8ef5, 0x8ee7, 0x8ee8, 0x8ef6, + 0x8eeb, 0x8ef1, 0x8eec, 0x8ef4, 0x8ee9, 0x902d, 0x9034, 0x902f, + 0x9106, 0x912c, 0x9104, 0x90ff, 0x90fc, 0x9108, 0x90f9, 0x90fb, + 0x9101, 0x9100, 0x9107, 0x9105, 0x9103, 0x9161, 0x9164, 0x915f, + 0x9162, 0x9160, 0x9201, 0x920a, 0x9225, 0x9203, 0x921a, 0x9226, + 0x920f, 0x920c, 0x9200, 0x9212, 0x91ff, 0x91fd, 0x9206, 0x9204, + 0x9227, 0x9202, 0x921c, 0x9224, 0x9219, 0x9217, 0x9205, 0x9216, + 0x957b, 0x958d, 0x958c, 0x9590, 0x9687, 0x967e, 0x9688, 0x9689, + 0x9683, 0x9680, 0x96c2, 0x96c8, 0x96c3, 0x96f1, 0x96f0, 0x976c, + 0x9770, 0x976e, 0x9807, 0x98a9, 0x98eb, 0x9ce6, 0x9ef9, 0x4e83, + 0x4e84, 0x4eb6, 0x50bd, 0x50bf, 0x50c6, 0x50ae, 0x50c4, 0x50ca, + 0x50b4, 0x50c8, 0x50c2, 0x50b0, 0x50c1, 0x50ba, 0x50b1, 0x50cb, + 0x50c9, 0x50b6, 0x50b8, 0x51d7, 0x527a, 0x5278, 0x527b, 0x527c, + 0x55c3, 0x55db, 0x55cc, 0x55d0, 0x55cb, 0x55ca, 0x55dd, 0x55c0, + 0x55d4, 0x55c4, 0x55e9, 0x55bf, 0x55d2, 0x558d, 0x55cf, 0x55d5, + 0x55e2, 0x55d6, 0x55c8, 0x55f2, 0x55cd, 0x55d9, 0x55c2, 0x5714, + 0x5853, 0x5868, 0x5864, 0x584f, 0x584d, 0x5849, 0x586f, 0x5855, + 0x584e, 0x585d, 0x5859, 0x5865, 0x585b, 0x583d, 0x5863, 0x5871, + 0x58fc, 0x5ac7, 0x5ac4, 0x5acb, 0x5aba, 0x5ab8, 0x5ab1, 0x5ab5, + 0x5ab0, 0x5abf, 0x5ac8, 0x5abb, 0x5ac6, + /* 0xdd */ + 0x5ab7, 0x5ac0, 0x5aca, 0x5ab4, 0x5ab6, 0x5acd, 0x5ab9, 0x5a90, + 0x5bd6, 0x5bd8, 0x5bd9, 0x5c1f, 0x5c33, 0x5d71, 0x5d63, 0x5d4a, + 0x5d65, 0x5d72, 0x5d6c, 0x5d5e, 0x5d68, 0x5d67, 0x5d62, 0x5df0, + 0x5e4f, 0x5e4e, 0x5e4a, 0x5e4d, 0x5e4b, 0x5ec5, 0x5ecc, 0x5ec6, + 0x5ecb, 0x5ec7, 0x5f40, 0x5faf, 0x5fad, 0x60f7, 0x6149, 0x614a, + 0x612b, 0x6145, 0x6136, 0x6132, 0x612e, 0x6146, 0x612f, 0x614f, + 0x6129, 0x6140, 0x6220, 0x9168, 0x6223, 0x6225, 0x6224, 0x63c5, + 0x63f1, 0x63eb, 0x6410, 0x6412, 0x6409, 0x6420, 0x6424, 0x6433, + 0x6443, 0x641f, 0x6415, 0x6418, 0x6439, 0x6437, 0x6422, 0x6423, + 0x640c, 0x6426, 0x6430, 0x6428, 0x6441, 0x6435, 0x642f, 0x640a, + 0x641a, 0x6440, 0x6425, 0x6427, 0x640b, 0x63e7, 0x641b, 0x642e, + 0x6421, 0x640e, 0x656f, 0x6592, 0x65d3, 0x6686, 0x668c, 0x6695, + 0x6690, 0x668b, 0x668a, 0x6699, 0x6694, 0x6678, 0x6720, 0x6966, + 0x695f, 0x6938, 0x694e, 0x6962, 0x6971, 0x693f, 0x6945, 0x696a, + 0x6939, 0x6942, 0x6957, 0x6959, 0x697a, 0x6948, 0x6949, 0x6935, + 0x696c, 0x6933, 0x693d, 0x6965, 0x68f0, 0x6978, 0x6934, 0x6969, + 0x6940, 0x696f, 0x6944, 0x6976, 0x6958, 0x6941, 0x6974, 0x694c, + 0x693b, 0x694b, 0x6937, 0x695c, 0x694f, 0x6951, 0x6932, 0x6952, + 0x692f, 0x697b, 0x693c, 0x6b46, 0x6b45, 0x6b43, 0x6b42, 0x6b48, + 0x6b41, 0x6b9b, 0xfa0d, 0x6bfb, 0x6bfc, + /* 0xde */ + 0x6bf9, 0x6bf7, 0x6bf8, 0x6e9b, 0x6ed6, 0x6ec8, 0x6e8f, 0x6ec0, + 0x6e9f, 0x6e93, 0x6e94, 0x6ea0, 0x6eb1, 0x6eb9, 0x6ec6, 0x6ed2, + 0x6ebd, 0x6ec1, 0x6e9e, 0x6ec9, 0x6eb7, 0x6eb0, 0x6ecd, 0x6ea6, + 0x6ecf, 0x6eb2, 0x6ebe, 0x6ec3, 0x6edc, 0x6ed8, 0x6e99, 0x6e92, + 0x6e8e, 0x6e8d, 0x6ea4, 0x6ea1, 0x6ebf, 0x6eb3, 0x6ed0, 0x6eca, + 0x6e97, 0x6eae, 0x6ea3, 0x7147, 0x7154, 0x7152, 0x7163, 0x7160, + 0x7141, 0x715d, 0x7162, 0x7172, 0x7178, 0x716a, 0x7161, 0x7142, + 0x7158, 0x7143, 0x714b, 0x7170, 0x715f, 0x7150, 0x7153, 0x7144, + 0x714d, 0x715a, 0x724f, 0x728d, 0x728c, 0x7291, 0x7290, 0x728e, + 0x733c, 0x7342, 0x733b, 0x733a, 0x7340, 0x734a, 0x7349, 0x7444, + 0x744a, 0x744b, 0x7452, 0x7451, 0x7457, 0x7440, 0x744f, 0x7450, + 0x744e, 0x7442, 0x7446, 0x744d, 0x7454, 0x74e1, 0x74ff, 0x74fe, + 0x74fd, 0x751d, 0x7579, 0x7577, 0x6983, 0x75ef, 0x760f, 0x7603, + 0x75f7, 0x75fe, 0x75fc, 0x75f9, 0x75f8, 0x7610, 0x75fb, 0x75f6, + 0x75ed, 0x75f5, 0x75fd, 0x7699, 0x76b5, 0x76dd, 0x7755, 0x775f, + 0x7760, 0x7752, 0x7756, 0x775a, 0x7769, 0x7767, 0x7754, 0x7759, + 0x776d, 0x77e0, 0x7887, 0x789a, 0x7894, 0x788f, 0x7884, 0x7895, + 0x7885, 0x7886, 0x78a1, 0x7883, 0x7879, 0x7899, 0x7880, 0x7896, + 0x787b, 0x797c, 0x7982, 0x797d, 0x7979, 0x7a11, 0x7a18, 0x7a19, + 0x7a12, 0x7a17, 0x7a15, 0x7a22, 0x7a13, + /* 0xdf */ + 0x7a1b, 0x7a10, 0x7aa3, 0x7aa2, 0x7a9e, 0x7aeb, 0x7b66, 0x7b64, + 0x7b6d, 0x7b74, 0x7b69, 0x7b72, 0x7b65, 0x7b73, 0x7b71, 0x7b70, + 0x7b61, 0x7b78, 0x7b76, 0x7b63, 0x7cb2, 0x7cb4, 0x7caf, 0x7d88, + 0x7d86, 0x7d80, 0x7d8d, 0x7d7f, 0x7d85, 0x7d7a, 0x7d8e, 0x7d7b, + 0x7d83, 0x7d7c, 0x7d8c, 0x7d94, 0x7d84, 0x7d7d, 0x7d92, 0x7f6d, + 0x7f6b, 0x7f67, 0x7f68, 0x7f6c, 0x7fa6, 0x7fa5, 0x7fa7, 0x7fdb, + 0x7fdc, 0x8021, 0x8164, 0x8160, 0x8177, 0x815c, 0x8169, 0x815b, + 0x8162, 0x8172, 0x6721, 0x815e, 0x8176, 0x8167, 0x816f, 0x8144, + 0x8161, 0x821d, 0x8249, 0x8244, 0x8240, 0x8242, 0x8245, 0x84f1, + 0x843f, 0x8456, 0x8476, 0x8479, 0x848f, 0x848d, 0x8465, 0x8451, + 0x8440, 0x8486, 0x8467, 0x8430, 0x844d, 0x847d, 0x845a, 0x8459, + 0x8474, 0x8473, 0x845d, 0x8507, 0x845e, 0x8437, 0x843a, 0x8434, + 0x847a, 0x8443, 0x8478, 0x8432, 0x8445, 0x8429, 0x83d9, 0x844b, + 0x842f, 0x8442, 0x842d, 0x845f, 0x8470, 0x8439, 0x844e, 0x844c, + 0x8452, 0x846f, 0x84c5, 0x848e, 0x843b, 0x8447, 0x8436, 0x8433, + 0x8468, 0x847e, 0x8444, 0x842b, 0x8460, 0x8454, 0x846e, 0x8450, + 0x870b, 0x8704, 0x86f7, 0x870c, 0x86fa, 0x86d6, 0x86f5, 0x874d, + 0x86f8, 0x870e, 0x8709, 0x8701, 0x86f6, 0x870d, 0x8705, 0x88d6, + 0x88cb, 0x88cd, 0x88ce, 0x88de, 0x88db, 0x88da, 0x88cc, 0x88d0, + 0x8985, 0x899b, 0x89df, 0x89e5, 0x89e4, + /* 0xe0 */ + 0x89e1, 0x89e0, 0x89e2, 0x89dc, 0x89e6, 0x8a76, 0x8a86, 0x8a7f, + 0x8a61, 0x8a3f, 0x8a77, 0x8a82, 0x8a84, 0x8a75, 0x8a83, 0x8a81, + 0x8a74, 0x8a7a, 0x8c3c, 0x8c4b, 0x8c4a, 0x8c65, 0x8c64, 0x8c66, + 0x8c86, 0x8c84, 0x8c85, 0x8ccc, 0x8d68, 0x8d69, 0x8d91, 0x8d8c, + 0x8d8e, 0x8d8f, 0x8d8d, 0x8d93, 0x8d94, 0x8d90, 0x8d92, 0x8df0, + 0x8de0, 0x8dec, 0x8df1, 0x8dee, 0x8dd0, 0x8de9, 0x8de3, 0x8de2, + 0x8de7, 0x8df2, 0x8deb, 0x8df4, 0x8f06, 0x8eff, 0x8f01, 0x8f00, + 0x8f05, 0x8f07, 0x8f08, 0x8f02, 0x8f0b, 0x9052, 0x903f, 0x9044, + 0x9049, 0x903d, 0x9110, 0x910d, 0x910f, 0x9111, 0x9116, 0x9114, + 0x910b, 0x910e, 0x916e, 0x916f, 0x9248, 0x9252, 0x9230, 0x923a, + 0x9266, 0x9233, 0x9265, 0x925e, 0x9283, 0x922e, 0x924a, 0x9246, + 0x926d, 0x926c, 0x924f, 0x9260, 0x9267, 0x926f, 0x9236, 0x9261, + 0x9270, 0x9231, 0x9254, 0x9263, 0x9250, 0x9272, 0x924e, 0x9253, + 0x924c, 0x9256, 0x9232, 0x959f, 0x959c, 0x959e, 0x959b, 0x9692, + 0x9693, 0x9691, 0x9697, 0x96ce, 0x96fa, 0x96fd, 0x96f8, 0x96f5, + 0x9773, 0x9777, 0x9778, 0x9772, 0x980f, 0x980d, 0x980e, 0x98ac, + 0x98f6, 0x98f9, 0x99af, 0x99b2, 0x99b0, 0x99b5, 0x9aad, 0x9aab, + 0x9b5b, 0x9cea, 0x9ced, 0x9ce7, 0x9e80, 0x9efd, 0x50e6, 0x50d4, + 0x50d7, 0x50e8, 0x50f3, 0x50db, 0x50ea, 0x50dd, 0x50e4, 0x50d3, + 0x50ec, 0x50f0, 0x50ef, 0x50e3, 0x50e0, + /* 0xe1 */ + 0x51d8, 0x5280, 0x5281, 0x52e9, 0x52eb, 0x5330, 0x53ac, 0x5627, + 0x5615, 0x560c, 0x5612, 0x55fc, 0x560f, 0x561c, 0x5601, 0x5613, + 0x5602, 0x55fa, 0x561d, 0x5604, 0x55ff, 0x55f9, 0x5889, 0x587c, + 0x5890, 0x5898, 0x5886, 0x5881, 0x587f, 0x5874, 0x588b, 0x587a, + 0x5887, 0x5891, 0x588e, 0x5876, 0x5882, 0x5888, 0x587b, 0x5894, + 0x588f, 0x58fe, 0x596b, 0x5adc, 0x5aee, 0x5ae5, 0x5ad5, 0x5aea, + 0x5ada, 0x5aed, 0x5aeb, 0x5af3, 0x5ae2, 0x5ae0, 0x5adb, 0x5aec, + 0x5ade, 0x5add, 0x5ad9, 0x5ae8, 0x5adf, 0x5b77, 0x5be0, 0x5be3, + 0x5c63, 0x5d82, 0x5d80, 0x5d7d, 0x5d86, 0x5d7a, 0x5d81, 0x5d77, + 0x5d8a, 0x5d89, 0x5d88, 0x5d7e, 0x5d7c, 0x5d8d, 0x5d79, 0x5d7f, + 0x5e58, 0x5e59, 0x5e53, 0x5ed8, 0x5ed1, 0x5ed7, 0x5ece, 0x5edc, + 0x5ed5, 0x5ed9, 0x5ed2, 0x5ed4, 0x5f44, 0x5f43, 0x5f6f, 0x5fb6, + 0x612c, 0x6128, 0x6141, 0x615e, 0x6171, 0x6173, 0x6152, 0x6153, + 0x6172, 0x616c, 0x6180, 0x6174, 0x6154, 0x617a, 0x615b, 0x6165, + 0x613b, 0x616a, 0x6161, 0x6156, 0x6229, 0x6227, 0x622b, 0x642b, + 0x644d, 0x645b, 0x645d, 0x6474, 0x6476, 0x6472, 0x6473, 0x647d, + 0x6475, 0x6466, 0x64a6, 0x644e, 0x6482, 0x645e, 0x645c, 0x644b, + 0x6453, 0x6460, 0x6450, 0x647f, 0x643f, 0x646c, 0x646b, 0x6459, + 0x6465, 0x6477, 0x6573, 0x65a0, 0x66a1, 0x66a0, 0x669f, 0x6705, + 0x6704, 0x6722, 0x69b1, 0x69b6, 0x69c9, + /* 0xe2 */ + 0x69a0, 0x69ce, 0x6996, 0x69b0, 0x69ac, 0x69bc, 0x6991, 0x6999, + 0x698e, 0x69a7, 0x698d, 0x69a9, 0x69be, 0x69af, 0x69bf, 0x69c4, + 0x69bd, 0x69a4, 0x69d4, 0x69b9, 0x69ca, 0x699a, 0x69cf, 0x69b3, + 0x6993, 0x69aa, 0x69a1, 0x699e, 0x69d9, 0x6997, 0x6990, 0x69c2, + 0x69b5, 0x69a5, 0x69c6, 0x6b4a, 0x6b4d, 0x6b4b, 0x6b9e, 0x6b9f, + 0x6ba0, 0x6bc3, 0x6bc4, 0x6bfe, 0x6ece, 0x6ef5, 0x6ef1, 0x6f03, + 0x6f25, 0x6ef8, 0x6f37, 0x6efb, 0x6f2e, 0x6f09, 0x6f4e, 0x6f19, + 0x6f1a, 0x6f27, 0x6f18, 0x6f3b, 0x6f12, 0x6eed, 0x6f0a, 0x6f36, + 0x6f73, 0x6ef9, 0x6eee, 0x6f2d, 0x6f40, 0x6f30, 0x6f3c, 0x6f35, + 0x6eeb, 0x6f07, 0x6f0e, 0x6f43, 0x6f05, 0x6efd, 0x6ef6, 0x6f39, + 0x6f1c, 0x6efc, 0x6f3a, 0x6f1f, 0x6f0d, 0x6f1e, 0x6f08, 0x6f21, + 0x7187, 0x7190, 0x7189, 0x7180, 0x7185, 0x7182, 0x718f, 0x717b, + 0x7186, 0x7181, 0x7197, 0x7244, 0x7253, 0x7297, 0x7295, 0x7293, + 0x7343, 0x734d, 0x7351, 0x734c, 0x7462, 0x7473, 0x7471, 0x7475, + 0x7472, 0x7467, 0x746e, 0x7500, 0x7502, 0x7503, 0x757d, 0x7590, + 0x7616, 0x7608, 0x760c, 0x7615, 0x7611, 0x760a, 0x7614, 0x76b8, + 0x7781, 0x777c, 0x7785, 0x7782, 0x776e, 0x7780, 0x776f, 0x777e, + 0x7783, 0x78b2, 0x78aa, 0x78b4, 0x78ad, 0x78a8, 0x787e, 0x78ab, + 0x789e, 0x78a5, 0x78a0, 0x78ac, 0x78a2, 0x78a4, 0x7998, 0x798a, + 0x798b, 0x7996, 0x7995, 0x7994, 0x7993, + /* 0xe3 */ + 0x7997, 0x7988, 0x7992, 0x7990, 0x7a2b, 0x7a4a, 0x7a30, 0x7a2f, + 0x7a28, 0x7a26, 0x7aa8, 0x7aab, 0x7aac, 0x7aee, 0x7b88, 0x7b9c, + 0x7b8a, 0x7b91, 0x7b90, 0x7b96, 0x7b8d, 0x7b8c, 0x7b9b, 0x7b8e, + 0x7b85, 0x7b98, 0x5284, 0x7b99, 0x7ba4, 0x7b82, 0x7cbb, 0x7cbf, + 0x7cbc, 0x7cba, 0x7da7, 0x7db7, 0x7dc2, 0x7da3, 0x7daa, 0x7dc1, + 0x7dc0, 0x7dc5, 0x7d9d, 0x7dce, 0x7dc4, 0x7dc6, 0x7dcb, 0x7dcc, + 0x7daf, 0x7db9, 0x7d96, 0x7dbc, 0x7d9f, 0x7da6, 0x7dae, 0x7da9, + 0x7da1, 0x7dc9, 0x7f73, 0x7fe2, 0x7fe3, 0x7fe5, 0x7fde, 0x8024, + 0x805d, 0x805c, 0x8189, 0x8186, 0x8183, 0x8187, 0x818d, 0x818c, + 0x818b, 0x8215, 0x8497, 0x84a4, 0x84a1, 0x849f, 0x84ba, 0x84ce, + 0x84c2, 0x84ac, 0x84ae, 0x84ab, 0x84b9, 0x84b4, 0x84c1, 0x84cd, + 0x84aa, 0x849a, 0x84b1, 0x84d0, 0x849d, 0x84a7, 0x84bb, 0x84a2, + 0x8494, 0x84c7, 0x84cc, 0x849b, 0x84a9, 0x84af, 0x84a8, 0x84d6, + 0x8498, 0x84b6, 0x84cf, 0x84a0, 0x84d7, 0x84d4, 0x84d2, 0x84db, + 0x84b0, 0x8491, 0x8661, 0x8733, 0x8723, 0x8728, 0x876b, 0x8740, + 0x872e, 0x871e, 0x8721, 0x8719, 0x871b, 0x8743, 0x872c, 0x8741, + 0x873e, 0x8746, 0x8720, 0x8732, 0x872a, 0x872d, 0x873c, 0x8712, + 0x873a, 0x8731, 0x8735, 0x8742, 0x8726, 0x8727, 0x8738, 0x8724, + 0x871a, 0x8730, 0x8711, 0x88f7, 0x88e7, 0x88f1, 0x88f2, 0x88fa, + 0x88fe, 0x88ee, 0x88fc, 0x88f6, 0x88fb, + /* 0xe4 */ + 0x88f0, 0x88ec, 0x88eb, 0x899d, 0x89a1, 0x899f, 0x899e, 0x89e9, + 0x89eb, 0x89e8, 0x8aab, 0x8a99, 0x8a8b, 0x8a92, 0x8a8f, 0x8a96, + 0x8c3d, 0x8c68, 0x8c69, 0x8cd5, 0x8ccf, 0x8cd7, 0x8d96, 0x8e09, + 0x8e02, 0x8dff, 0x8e0d, 0x8dfd, 0x8e0a, 0x8e03, 0x8e07, 0x8e06, + 0x8e05, 0x8dfe, 0x8e00, 0x8e04, 0x8f10, 0x8f11, 0x8f0e, 0x8f0d, + 0x9123, 0x911c, 0x9120, 0x9122, 0x911f, 0x911d, 0x911a, 0x9124, + 0x9121, 0x911b, 0x917a, 0x9172, 0x9179, 0x9173, 0x92a5, 0x92a4, + 0x9276, 0x929b, 0x927a, 0x92a0, 0x9294, 0x92aa, 0x928d, 0x92a6, + 0x929a, 0x92ab, 0x9279, 0x9297, 0x927f, 0x92a3, 0x92ee, 0x928e, + 0x9282, 0x9295, 0x92a2, 0x927d, 0x9288, 0x92a1, 0x928a, 0x9286, + 0x928c, 0x9299, 0x92a7, 0x927e, 0x9287, 0x92a9, 0x929d, 0x928b, + 0x922d, 0x969e, 0x96a1, 0x96ff, 0x9758, 0x977d, 0x977a, 0x977e, + 0x9783, 0x9780, 0x9782, 0x977b, 0x9784, 0x9781, 0x977f, 0x97ce, + 0x97cd, 0x9816, 0x98ad, 0x98ae, 0x9902, 0x9900, 0x9907, 0x999d, + 0x999c, 0x99c3, 0x99b9, 0x99bb, 0x99ba, 0x99c2, 0x99bd, 0x99c7, + 0x9ab1, 0x9ae3, 0x9ae7, 0x9b3e, 0x9b3f, 0x9b60, 0x9b61, 0x9b5f, + 0x9cf1, 0x9cf2, 0x9cf5, 0x9ea7, 0x50ff, 0x5103, 0x5130, 0x50f8, + 0x5106, 0x5107, 0x50f6, 0x50fe, 0x510b, 0x510c, 0x50fd, 0x510a, + 0x528b, 0x528c, 0x52f1, 0x52ef, 0x5648, 0x5642, 0x564c, 0x5635, + 0x5641, 0x564a, 0x5649, 0x5646, 0x5658, + /* 0xe5 */ + 0x565a, 0x5640, 0x5633, 0x563d, 0x562c, 0x563e, 0x5638, 0x562a, + 0x563a, 0x571a, 0x58ab, 0x589d, 0x58b1, 0x58a0, 0x58a3, 0x58af, + 0x58ac, 0x58a5, 0x58a1, 0x58ff, 0x5aff, 0x5af4, 0x5afd, 0x5af7, + 0x5af6, 0x5b03, 0x5af8, 0x5b02, 0x5af9, 0x5b01, 0x5b07, 0x5b05, + 0x5b0f, 0x5c67, 0x5d99, 0x5d97, 0x5d9f, 0x5d92, 0x5da2, 0x5d93, + 0x5d95, 0x5da0, 0x5d9c, 0x5da1, 0x5d9a, 0x5d9e, 0x5e69, 0x5e5d, + 0x5e60, 0x5e5c, 0x7df3, 0x5edb, 0x5ede, 0x5ee1, 0x5f49, 0x5fb2, + 0x618b, 0x6183, 0x6179, 0x61b1, 0x61b0, 0x61a2, 0x6189, 0x619b, + 0x6193, 0x61af, 0x61ad, 0x619f, 0x6192, 0x61aa, 0x61a1, 0x618d, + 0x6166, 0x61b3, 0x622d, 0x646e, 0x6470, 0x6496, 0x64a0, 0x6485, + 0x6497, 0x649c, 0x648f, 0x648b, 0x648a, 0x648c, 0x64a3, 0x649f, + 0x6468, 0x64b1, 0x6498, 0x6576, 0x657a, 0x6579, 0x657b, 0x65b2, + 0x65b3, 0x66b5, 0x66b0, 0x66a9, 0x66b2, 0x66b7, 0x66aa, 0x66af, + 0x6a00, 0x6a06, 0x6a17, 0x69e5, 0x69f8, 0x6a15, 0x69f1, 0x69e4, + 0x6a20, 0x69ff, 0x69ec, 0x69e2, 0x6a1b, 0x6a1d, 0x69fe, 0x6a27, + 0x69f2, 0x69ee, 0x6a14, 0x69f7, 0x69e7, 0x6a40, 0x6a08, 0x69e6, + 0x69fb, 0x6a0d, 0x69fc, 0x69eb, 0x6a09, 0x6a04, 0x6a18, 0x6a25, + 0x6a0f, 0x69f6, 0x6a26, 0x6a07, 0x69f4, 0x6a16, 0x6b51, 0x6ba5, + 0x6ba3, 0x6ba2, 0x6ba6, 0x6c01, 0x6c00, 0x6bff, 0x6c02, 0x6f41, + 0x6f26, 0x6f7e, 0x6f87, 0x6fc6, 0x6f92, + /* 0xe6 */ + 0x6f8d, 0x6f89, 0x6f8c, 0x6f62, 0x6f4f, 0x6f85, 0x6f5a, 0x6f96, + 0x6f76, 0x6f6c, 0x6f82, 0x6f55, 0x6f72, 0x6f52, 0x6f50, 0x6f57, + 0x6f94, 0x6f93, 0x6f5d, 0x6f00, 0x6f61, 0x6f6b, 0x6f7d, 0x6f67, + 0x6f90, 0x6f53, 0x6f8b, 0x6f69, 0x6f7f, 0x6f95, 0x6f63, 0x6f77, + 0x6f6a, 0x6f7b, 0x71b2, 0x71af, 0x719b, 0x71b0, 0x71a0, 0x719a, + 0x71a9, 0x71b5, 0x719d, 0x71a5, 0x719e, 0x71a4, 0x71a1, 0x71aa, + 0x719c, 0x71a7, 0x71b3, 0x7298, 0x729a, 0x7358, 0x7352, 0x735e, + 0x735f, 0x7360, 0x735d, 0x735b, 0x7361, 0x735a, 0x7359, 0x7362, + 0x7487, 0x7489, 0x748a, 0x7486, 0x7481, 0x747d, 0x7485, 0x7488, + 0x747c, 0x7479, 0x7508, 0x7507, 0x757e, 0x7625, 0x761e, 0x7619, + 0x761d, 0x761c, 0x7623, 0x761a, 0x7628, 0x761b, 0x769c, 0x769d, + 0x769e, 0x769b, 0x778d, 0x778f, 0x7789, 0x7788, 0x78cd, 0x78bb, + 0x78cf, 0x78cc, 0x78d1, 0x78ce, 0x78d4, 0x78c8, 0x78c3, 0x78c4, + 0x78c9, 0x799a, 0x79a1, 0x79a0, 0x799c, 0x79a2, 0x799b, 0x6b76, + 0x7a39, 0x7ab2, 0x7ab4, 0x7ab3, 0x7bb7, 0x7bcb, 0x7bbe, 0x7bac, + 0x7bce, 0x7baf, 0x7bb9, 0x7bca, 0x7bb5, 0x7cc5, 0x7cc8, 0x7ccc, + 0x7ccb, 0x7df7, 0x7ddb, 0x7dea, 0x7de7, 0x7dd7, 0x7de1, 0x7e03, + 0x7dfa, 0x7de6, 0x7df6, 0x7df1, 0x7df0, 0x7dee, 0x7ddf, 0x7f76, + 0x7fac, 0x7fb0, 0x7fad, 0x7fed, 0x7feb, 0x7fea, 0x7fec, 0x7fe6, + 0x7fe8, 0x8064, 0x8067, 0x81a3, 0x819f, + /* 0xe7 */ + 0x819e, 0x8195, 0x81a2, 0x8199, 0x8197, 0x8216, 0x824f, 0x8253, + 0x8252, 0x8250, 0x824e, 0x8251, 0x8524, 0x853b, 0x850f, 0x8500, + 0x8529, 0x850e, 0x8509, 0x850d, 0x851f, 0x850a, 0x8527, 0x851c, + 0x84fb, 0x852b, 0x84fa, 0x8508, 0x850c, 0x84f4, 0x852a, 0x84f2, + 0x8515, 0x84f7, 0x84eb, 0x84f3, 0x84fc, 0x8512, 0x84ea, 0x84e9, + 0x8516, 0x84fe, 0x8528, 0x851d, 0x852e, 0x8502, 0x84fd, 0x851e, + 0x84f6, 0x8531, 0x8526, 0x84e7, 0x84e8, 0x84f0, 0x84ef, 0x84f9, + 0x8518, 0x8520, 0x8530, 0x850b, 0x8519, 0x852f, 0x8662, 0x8756, + 0x8763, 0x8764, 0x8777, 0x87e1, 0x8773, 0x8758, 0x8754, 0x875b, + 0x8752, 0x8761, 0x875a, 0x8751, 0x875e, 0x876d, 0x876a, 0x8750, + 0x874e, 0x875f, 0x875d, 0x876f, 0x876c, 0x877a, 0x876e, 0x875c, + 0x8765, 0x874f, 0x877b, 0x8775, 0x8762, 0x8767, 0x8769, 0x885a, + 0x8905, 0x890c, 0x8914, 0x890b, 0x8917, 0x8918, 0x8919, 0x8906, + 0x8916, 0x8911, 0x890e, 0x8909, 0x89a2, 0x89a4, 0x89a3, 0x89ed, + 0x89f0, 0x89ec, 0x8acf, 0x8ac6, 0x8ab8, 0x8ad3, 0x8ad1, 0x8ad4, + 0x8ad5, 0x8abb, 0x8ad7, 0x8abe, 0x8ac0, 0x8ac5, 0x8ad8, 0x8ac3, + 0x8aba, 0x8abd, 0x8ad9, 0x8c3e, 0x8c4d, 0x8c8f, 0x8ce5, 0x8cdf, + 0x8cd9, 0x8ce8, 0x8cda, 0x8cdd, 0x8ce7, 0x8da0, 0x8d9c, 0x8da1, + 0x8d9b, 0x8e20, 0x8e23, 0x8e25, 0x8e24, 0x8e2e, 0x8e15, 0x8e1b, + 0x8e16, 0x8e11, 0x8e19, 0x8e26, 0x8e27, + /* 0xe8 */ + 0x8e14, 0x8e12, 0x8e18, 0x8e13, 0x8e1c, 0x8e17, 0x8e1a, 0x8f2c, + 0x8f24, 0x8f18, 0x8f1a, 0x8f20, 0x8f23, 0x8f16, 0x8f17, 0x9073, + 0x9070, 0x906f, 0x9067, 0x906b, 0x912f, 0x912b, 0x9129, 0x912a, + 0x9132, 0x9126, 0x912e, 0x9185, 0x9186, 0x918a, 0x9181, 0x9182, + 0x9184, 0x9180, 0x92d0, 0x92c3, 0x92c4, 0x92c0, 0x92d9, 0x92b6, + 0x92cf, 0x92f1, 0x92df, 0x92d8, 0x92e9, 0x92d7, 0x92dd, 0x92cc, + 0x92ef, 0x92c2, 0x92e8, 0x92ca, 0x92c8, 0x92ce, 0x92e6, 0x92cd, + 0x92d5, 0x92c9, 0x92e0, 0x92de, 0x92e7, 0x92d1, 0x92d3, 0x92b5, + 0x92e1, 0x92c6, 0x92b4, 0x957c, 0x95ac, 0x95ab, 0x95ae, 0x95b0, + 0x96a4, 0x96a2, 0x96d3, 0x9705, 0x9708, 0x9702, 0x975a, 0x978a, + 0x978e, 0x9788, 0x97d0, 0x97cf, 0x981e, 0x981d, 0x9826, 0x9829, + 0x9828, 0x9820, 0x981b, 0x9827, 0x98b2, 0x9908, 0x98fa, 0x9911, + 0x9914, 0x9916, 0x9917, 0x9915, 0x99dc, 0x99cd, 0x99cf, 0x99d3, + 0x99d4, 0x99ce, 0x99c9, 0x99d6, 0x99d8, 0x99cb, 0x99d7, 0x99cc, + 0x9ab3, 0x9aec, 0x9aeb, 0x9af3, 0x9af2, 0x9af1, 0x9b46, 0x9b43, + 0x9b67, 0x9b74, 0x9b71, 0x9b66, 0x9b76, 0x9b75, 0x9b70, 0x9b68, + 0x9b64, 0x9b6c, 0x9cfc, 0x9cfa, 0x9cfd, 0x9cff, 0x9cf7, 0x9d07, + 0x9d00, 0x9cf9, 0x9cfb, 0x9d08, 0x9d05, 0x9d04, 0x9e83, 0x9ed3, + 0x9f0f, 0x9f10, 0x511c, 0x5113, 0x5117, 0x511a, 0x5111, 0x51de, + 0x5334, 0x53e1, 0x5670, 0x5660, 0x566e, + /* 0xe9 */ + 0x5673, 0x5666, 0x5663, 0x566d, 0x5672, 0x565e, 0x5677, 0x571c, + 0x571b, 0x58c8, 0x58bd, 0x58c9, 0x58bf, 0x58ba, 0x58c2, 0x58bc, + 0x58c6, 0x5b17, 0x5b19, 0x5b1b, 0x5b21, 0x5b14, 0x5b13, 0x5b10, + 0x5b16, 0x5b28, 0x5b1a, 0x5b20, 0x5b1e, 0x5bef, 0x5dac, 0x5db1, + 0x5da9, 0x5da7, 0x5db5, 0x5db0, 0x5dae, 0x5daa, 0x5da8, 0x5db2, + 0x5dad, 0x5daf, 0x5db4, 0x5e67, 0x5e68, 0x5e66, 0x5e6f, 0x5ee9, + 0x5ee7, 0x5ee6, 0x5ee8, 0x5ee5, 0x5f4b, 0x5fbc, 0x619d, 0x61a8, + 0x6196, 0x61c5, 0x61b4, 0x61c6, 0x61c1, 0x61cc, 0x61ba, 0x61bf, + 0x61b8, 0x618c, 0x64d7, 0x64d6, 0x64d0, 0x64cf, 0x64c9, 0x64bd, + 0x6489, 0x64c3, 0x64db, 0x64f3, 0x64d9, 0x6533, 0x657f, 0x657c, + 0x65a2, 0x66c8, 0x66be, 0x66c0, 0x66ca, 0x66cb, 0x66cf, 0x66bd, + 0x66bb, 0x66ba, 0x66cc, 0x6723, 0x6a34, 0x6a66, 0x6a49, 0x6a67, + 0x6a32, 0x6a68, 0x6a3e, 0x6a5d, 0x6a6d, 0x6a76, 0x6a5b, 0x6a51, + 0x6a28, 0x6a5a, 0x6a3b, 0x6a3f, 0x6a41, 0x6a6a, 0x6a64, 0x6a50, + 0x6a4f, 0x6a54, 0x6a6f, 0x6a69, 0x6a60, 0x6a3c, 0x6a5e, 0x6a56, + 0x6a55, 0x6a4d, 0x6a4e, 0x6a46, 0x6b55, 0x6b54, 0x6b56, 0x6ba7, + 0x6baa, 0x6bab, 0x6bc8, 0x6bc7, 0x6c04, 0x6c03, 0x6c06, 0x6fad, + 0x6fcb, 0x6fa3, 0x6fc7, 0x6fbc, 0x6fce, 0x6fc8, 0x6f5e, 0x6fc4, + 0x6fbd, 0x6f9e, 0x6fca, 0x6fa8, 0x7004, 0x6fa5, 0x6fae, 0x6fba, + 0x6fac, 0x6faa, 0x6fcf, 0x6fbf, 0x6fb8, + /* 0xea */ + 0x6fa2, 0x6fc9, 0x6fab, 0x6fcd, 0x6faf, 0x6fb2, 0x6fb0, 0x71c5, + 0x71c2, 0x71bf, 0x71b8, 0x71d6, 0x71c0, 0x71c1, 0x71cb, 0x71d4, + 0x71ca, 0x71c7, 0x71cf, 0x71bd, 0x71d8, 0x71bc, 0x71c6, 0x71da, + 0x71db, 0x729d, 0x729e, 0x7369, 0x7366, 0x7367, 0x736c, 0x7365, + 0x736b, 0x736a, 0x747f, 0x749a, 0x74a0, 0x7494, 0x7492, 0x7495, + 0x74a1, 0x750b, 0x7580, 0x762f, 0x762d, 0x7631, 0x763d, 0x7633, + 0x763c, 0x7635, 0x7632, 0x7630, 0x76bb, 0x76e6, 0x779a, 0x779d, + 0x77a1, 0x779c, 0x779b, 0x77a2, 0x77a3, 0x7795, 0x7799, 0x7797, + 0x78dd, 0x78e9, 0x78e5, 0x78ea, 0x78de, 0x78e3, 0x78db, 0x78e1, + 0x78e2, 0x78ed, 0x78df, 0x78e0, 0x79a4, 0x7a44, 0x7a48, 0x7a47, + 0x7ab6, 0x7ab8, 0x7ab5, 0x7ab1, 0x7ab7, 0x7bde, 0x7be3, 0x7be7, + 0x7bdd, 0x7bd5, 0x7be5, 0x7bda, 0x7be8, 0x7bf9, 0x7bd4, 0x7bea, + 0x7be2, 0x7bdc, 0x7beb, 0x7bd8, 0x7bdf, 0x7cd2, 0x7cd4, 0x7cd7, + 0x7cd0, 0x7cd1, 0x7e12, 0x7e21, 0x7e17, 0x7e0c, 0x7e1f, 0x7e20, + 0x7e13, 0x7e0e, 0x7e1c, 0x7e15, 0x7e1a, 0x7e22, 0x7e0b, 0x7e0f, + 0x7e16, 0x7e0d, 0x7e14, 0x7e25, 0x7e24, 0x7f43, 0x7f7b, 0x7f7c, + 0x7f7a, 0x7fb1, 0x7fef, 0x802a, 0x8029, 0x806c, 0x81b1, 0x81a6, + 0x81ae, 0x81b9, 0x81b5, 0x81ab, 0x81b0, 0x81ac, 0x81b4, 0x81b2, + 0x81b7, 0x81a7, 0x81f2, 0x8255, 0x8256, 0x8257, 0x8556, 0x8545, + 0x856b, 0x854d, 0x8553, 0x8561, 0x8558, + /* 0xeb */ + 0x8540, 0x8546, 0x8564, 0x8541, 0x8562, 0x8544, 0x8551, 0x8547, + 0x8563, 0x853e, 0x855b, 0x8571, 0x854e, 0x856e, 0x8575, 0x8555, + 0x8567, 0x8560, 0x858c, 0x8566, 0x855d, 0x8554, 0x8565, 0x856c, + 0x8663, 0x8665, 0x8664, 0x879b, 0x878f, 0x8797, 0x8793, 0x8792, + 0x8788, 0x8781, 0x8796, 0x8798, 0x8779, 0x8787, 0x87a3, 0x8785, + 0x8790, 0x8791, 0x879d, 0x8784, 0x8794, 0x879c, 0x879a, 0x8789, + 0x891e, 0x8926, 0x8930, 0x892d, 0x892e, 0x8927, 0x8931, 0x8922, + 0x8929, 0x8923, 0x892f, 0x892c, 0x891f, 0x89f1, 0x8ae0, 0x8ae2, + 0x8af2, 0x8af4, 0x8af5, 0x8add, 0x8b14, 0x8ae4, 0x8adf, 0x8af0, + 0x8ac8, 0x8ade, 0x8ae1, 0x8ae8, 0x8aff, 0x8aef, 0x8afb, 0x8c91, + 0x8c92, 0x8c90, 0x8cf5, 0x8cee, 0x8cf1, 0x8cf0, 0x8cf3, 0x8d6c, + 0x8d6e, 0x8da5, 0x8da7, 0x8e33, 0x8e3e, 0x8e38, 0x8e40, 0x8e45, + 0x8e36, 0x8e3c, 0x8e3d, 0x8e41, 0x8e30, 0x8e3f, 0x8ebd, 0x8f36, + 0x8f2e, 0x8f35, 0x8f32, 0x8f39, 0x8f37, 0x8f34, 0x9076, 0x9079, + 0x907b, 0x9086, 0x90fa, 0x9133, 0x9135, 0x9136, 0x9193, 0x9190, + 0x9191, 0x918d, 0x918f, 0x9327, 0x931e, 0x9308, 0x931f, 0x9306, + 0x930f, 0x937a, 0x9338, 0x933c, 0x931b, 0x9323, 0x9312, 0x9301, + 0x9346, 0x932d, 0x930e, 0x930d, 0x92cb, 0x931d, 0x92fa, 0x9325, + 0x9313, 0x92f9, 0x92f7, 0x9334, 0x9302, 0x9324, 0x92ff, 0x9329, + 0x9339, 0x9335, 0x932a, 0x9314, 0x930c, + /* 0xec */ + 0x930b, 0x92fe, 0x9309, 0x9300, 0x92fb, 0x9316, 0x95bc, 0x95cd, + 0x95be, 0x95b9, 0x95ba, 0x95b6, 0x95bf, 0x95b5, 0x95bd, 0x96a9, + 0x96d4, 0x970b, 0x9712, 0x9710, 0x9799, 0x9797, 0x9794, 0x97f0, + 0x97f8, 0x9835, 0x982f, 0x9832, 0x9924, 0x991f, 0x9927, 0x9929, + 0x999e, 0x99ee, 0x99ec, 0x99e5, 0x99e4, 0x99f0, 0x99e3, 0x99ea, + 0x99e9, 0x99e7, 0x9ab9, 0x9abf, 0x9ab4, 0x9abb, 0x9af6, 0x9afa, + 0x9af9, 0x9af7, 0x9b33, 0x9b80, 0x9b85, 0x9b87, 0x9b7c, 0x9b7e, + 0x9b7b, 0x9b82, 0x9b93, 0x9b92, 0x9b90, 0x9b7a, 0x9b95, 0x9b7d, + 0x9b88, 0x9d25, 0x9d17, 0x9d20, 0x9d1e, 0x9d14, 0x9d29, 0x9d1d, + 0x9d18, 0x9d22, 0x9d10, 0x9d19, 0x9d1f, 0x9e88, 0x9e86, 0x9e87, + 0x9eae, 0x9ead, 0x9ed5, 0x9ed6, 0x9efa, 0x9f12, 0x9f3d, 0x5126, + 0x5125, 0x5122, 0x5124, 0x5120, 0x5129, 0x52f4, 0x5693, 0x568c, + 0x568d, 0x5686, 0x5684, 0x5683, 0x567e, 0x5682, 0x567f, 0x5681, + 0x58d6, 0x58d4, 0x58cf, 0x58d2, 0x5b2d, 0x5b25, 0x5b32, 0x5b23, + 0x5b2c, 0x5b27, 0x5b26, 0x5b2f, 0x5b2e, 0x5b7b, 0x5bf1, 0x5bf2, + 0x5db7, 0x5e6c, 0x5e6a, 0x5fbe, 0x5fbb, 0x61c3, 0x61b5, 0x61bc, + 0x61e7, 0x61e0, 0x61e5, 0x61e4, 0x61e8, 0x61de, 0x64ef, 0x64e9, + 0x64e3, 0x64eb, 0x64e4, 0x64e8, 0x6581, 0x6580, 0x65b6, 0x65da, + 0x66d2, 0x6a8d, 0x6a96, 0x6a81, 0x6aa5, 0x6a89, 0x6a9f, 0x6a9b, + 0x6aa1, 0x6a9e, 0x6a87, 0x6a93, 0x6a8e, + /* 0xed */ + 0x6a95, 0x6a83, 0x6aa8, 0x6aa4, 0x6a91, 0x6a7f, 0x6aa6, 0x6a9a, + 0x6a85, 0x6a8c, 0x6a92, 0x6b5b, 0x6bad, 0x6c09, 0x6fcc, 0x6fa9, + 0x6ff4, 0x6fd4, 0x6fe3, 0x6fdc, 0x6fed, 0x6fe7, 0x6fe6, 0x6fde, + 0x6ff2, 0x6fdd, 0x6fe2, 0x6fe8, 0x71e1, 0x71f1, 0x71e8, 0x71f2, + 0x71e4, 0x71f0, 0x71e2, 0x7373, 0x736e, 0x736f, 0x7497, 0x74b2, + 0x74ab, 0x7490, 0x74aa, 0x74ad, 0x74b1, 0x74a5, 0x74af, 0x7510, + 0x7511, 0x7512, 0x750f, 0x7584, 0x7643, 0x7648, 0x7649, 0x7647, + 0x76a4, 0x76e9, 0x77b5, 0x77ab, 0x77b2, 0x77b7, 0x77b6, 0x77b4, + 0x77b1, 0x77a8, 0x77f0, 0x78f3, 0x78fd, 0x7902, 0x78fb, 0x78fc, + 0x78f2, 0x7905, 0x78f9, 0x78fe, 0x7904, 0x79ab, 0x79a8, 0x7a5c, + 0x7a5b, 0x7a56, 0x7a58, 0x7a54, 0x7a5a, 0x7abe, 0x7ac0, 0x7ac1, + 0x7c05, 0x7c0f, 0x7bf2, 0x7c00, 0x7bff, 0x7bfb, 0x7c0e, 0x7bf4, + 0x7c0b, 0x7bf3, 0x7c02, 0x7c09, 0x7c03, 0x7c01, 0x7bf8, 0x7bfd, + 0x7c06, 0x7bf0, 0x7bf1, 0x7c10, 0x7c0a, 0x7ce8, 0x7e2d, 0x7e3c, + 0x7e42, 0x7e33, 0x9848, 0x7e38, 0x7e2a, 0x7e49, 0x7e40, 0x7e47, + 0x7e29, 0x7e4c, 0x7e30, 0x7e3b, 0x7e36, 0x7e44, 0x7e3a, 0x7f45, + 0x7f7f, 0x7f7e, 0x7f7d, 0x7ff4, 0x7ff2, 0x802c, 0x81bb, 0x81c4, + 0x81cc, 0x81ca, 0x81c5, 0x81c7, 0x81bc, 0x81e9, 0x825b, 0x825a, + 0x825c, 0x8583, 0x8580, 0x858f, 0x85a7, 0x8595, 0x85a0, 0x858b, + 0x85a3, 0x857b, 0x85a4, 0x859a, 0x859e, + /* 0xee */ + 0x8577, 0x857c, 0x8589, 0x85a1, 0x857a, 0x8578, 0x8557, 0x858e, + 0x8596, 0x8586, 0x858d, 0x8599, 0x859d, 0x8581, 0x85a2, 0x8582, + 0x8588, 0x8585, 0x8579, 0x8576, 0x8598, 0x8590, 0x859f, 0x8668, + 0x87be, 0x87aa, 0x87ad, 0x87c5, 0x87b0, 0x87ac, 0x87b9, 0x87b5, + 0x87bc, 0x87ae, 0x87c9, 0x87c3, 0x87c2, 0x87cc, 0x87b7, 0x87af, + 0x87c4, 0x87ca, 0x87b4, 0x87b6, 0x87bf, 0x87b8, 0x87bd, 0x87de, + 0x87b2, 0x8935, 0x8933, 0x893c, 0x893e, 0x8941, 0x8952, 0x8937, + 0x8942, 0x89ad, 0x89af, 0x89ae, 0x89f2, 0x89f3, 0x8b1e, 0x8b18, + 0x8b16, 0x8b11, 0x8b05, 0x8b0b, 0x8b22, 0x8b0f, 0x8b12, 0x8b15, + 0x8b07, 0x8b0d, 0x8b08, 0x8b06, 0x8b1c, 0x8b13, 0x8b1a, 0x8c4f, + 0x8c70, 0x8c72, 0x8c71, 0x8c6f, 0x8c95, 0x8c94, 0x8cf9, 0x8d6f, + 0x8e4e, 0x8e4d, 0x8e53, 0x8e50, 0x8e4c, 0x8e47, 0x8f43, 0x8f40, + 0x9085, 0x907e, 0x9138, 0x919a, 0x91a2, 0x919b, 0x9199, 0x919f, + 0x91a1, 0x919d, 0x91a0, 0x93a1, 0x9383, 0x93af, 0x9364, 0x9356, + 0x9347, 0x937c, 0x9358, 0x935c, 0x9376, 0x9349, 0x9350, 0x9351, + 0x9360, 0x936d, 0x938f, 0x934c, 0x936a, 0x9379, 0x9357, 0x9355, + 0x9352, 0x934f, 0x9371, 0x9377, 0x937b, 0x9361, 0x935e, 0x9363, + 0x9367, 0x9380, 0x934e, 0x9359, 0x95c7, 0x95c0, 0x95c9, 0x95c3, + 0x95c5, 0x95b7, 0x96ae, 0x96b0, 0x96ac, 0x9720, 0x971f, 0x9718, + 0x971d, 0x9719, 0x979a, 0x97a1, 0x979c, + /* 0xef */ + 0x979e, 0x979d, 0x97d5, 0x97d4, 0x97f1, 0x9841, 0x9844, 0x984a, + 0x9849, 0x9845, 0x9843, 0x9925, 0x992b, 0x992c, 0x992a, 0x9933, + 0x9932, 0x992f, 0x992d, 0x9931, 0x9930, 0x9998, 0x99a3, 0x99a1, + 0x9a02, 0x99fa, 0x99f4, 0x99f7, 0x99f9, 0x99f8, 0x99f6, 0x99fb, + 0x99fd, 0x99fe, 0x99fc, 0x9a03, 0x9abe, 0x9afe, 0x9afd, 0x9b01, + 0x9afc, 0x9b48, 0x9b9a, 0x9ba8, 0x9b9e, 0x9b9b, 0x9ba6, 0x9ba1, + 0x9ba5, 0x9ba4, 0x9b86, 0x9ba2, 0x9ba0, 0x9baf, 0x9d33, 0x9d41, + 0x9d67, 0x9d36, 0x9d2e, 0x9d2f, 0x9d31, 0x9d38, 0x9d30, 0x9d45, + 0x9d42, 0x9d43, 0x9d3e, 0x9d37, 0x9d40, 0x9d3d, 0x7ff5, 0x9d2d, + 0x9e8a, 0x9e89, 0x9e8d, 0x9eb0, 0x9ec8, 0x9eda, 0x9efb, 0x9eff, + 0x9f24, 0x9f23, 0x9f22, 0x9f54, 0x9fa0, 0x5131, 0x512d, 0x512e, + 0x5698, 0x569c, 0x5697, 0x569a, 0x569d, 0x5699, 0x5970, 0x5b3c, + 0x5c69, 0x5c6a, 0x5dc0, 0x5e6d, 0x5e6e, 0x61d8, 0x61df, 0x61ed, + 0x61ee, 0x61f1, 0x61ea, 0x61f0, 0x61eb, 0x61d6, 0x61e9, 0x64ff, + 0x6504, 0x64fd, 0x64f8, 0x6501, 0x6503, 0x64fc, 0x6594, 0x65db, + 0x66da, 0x66db, 0x66d8, 0x6ac5, 0x6ab9, 0x6abd, 0x6ae1, 0x6ac6, + 0x6aba, 0x6ab6, 0x6ab7, 0x6ac7, 0x6ab4, 0x6aad, 0x6b5e, 0x6bc9, + 0x6c0b, 0x7007, 0x700c, 0x700d, 0x7001, 0x7005, 0x7014, 0x700e, + 0x6fff, 0x7000, 0x6ffb, 0x7026, 0x6ffc, 0x6ff7, 0x700a, 0x7201, + 0x71ff, 0x71f9, 0x7203, 0x71fd, 0x7376, + /* 0xf0 */ + 0x74b8, 0x74c0, 0x74b5, 0x74c1, 0x74be, 0x74b6, 0x74bb, 0x74c2, + 0x7514, 0x7513, 0x765c, 0x7664, 0x7659, 0x7650, 0x7653, 0x7657, + 0x765a, 0x76a6, 0x76bd, 0x76ec, 0x77c2, 0x77ba, 0x78ff, 0x790c, + 0x7913, 0x7914, 0x7909, 0x7910, 0x7912, 0x7911, 0x79ad, 0x79ac, + 0x7a5f, 0x7c1c, 0x7c29, 0x7c19, 0x7c20, 0x7c1f, 0x7c2d, 0x7c1d, + 0x7c26, 0x7c28, 0x7c22, 0x7c25, 0x7c30, 0x7e5c, 0x7e50, 0x7e56, + 0x7e63, 0x7e58, 0x7e62, 0x7e5f, 0x7e51, 0x7e60, 0x7e57, 0x7e53, + 0x7fb5, 0x7fb3, 0x7ff7, 0x7ff8, 0x8075, 0x81d1, 0x81d2, 0x81d0, + 0x825f, 0x825e, 0x85b4, 0x85c6, 0x85c0, 0x85c3, 0x85c2, 0x85b3, + 0x85b5, 0x85bd, 0x85c7, 0x85c4, 0x85bf, 0x85cb, 0x85ce, 0x85c8, + 0x85c5, 0x85b1, 0x85b6, 0x85d2, 0x8624, 0x85b8, 0x85b7, 0x85be, + 0x8669, 0x87e7, 0x87e6, 0x87e2, 0x87db, 0x87eb, 0x87ea, 0x87e5, + 0x87df, 0x87f3, 0x87e4, 0x87d4, 0x87dc, 0x87d3, 0x87ed, 0x87d8, + 0x87e3, 0x87a4, 0x87d7, 0x87d9, 0x8801, 0x87f4, 0x87e8, 0x87dd, + 0x8953, 0x894b, 0x894f, 0x894c, 0x8946, 0x8950, 0x8951, 0x8949, + 0x8b2a, 0x8b27, 0x8b23, 0x8b33, 0x8b30, 0x8b35, 0x8b47, 0x8b2f, + 0x8b3c, 0x8b3e, 0x8b31, 0x8b25, 0x8b37, 0x8b26, 0x8b36, 0x8b2e, + 0x8b24, 0x8b3b, 0x8b3d, 0x8b3a, 0x8c42, 0x8c75, 0x8c99, 0x8c98, + 0x8c97, 0x8cfe, 0x8d04, 0x8d02, 0x8d00, 0x8e5c, 0x8e62, 0x8e60, + 0x8e57, 0x8e56, 0x8e5e, 0x8e65, 0x8e67, + /* 0xf1 */ + 0x8e5b, 0x8e5a, 0x8e61, 0x8e5d, 0x8e69, 0x8e54, 0x8f46, 0x8f47, + 0x8f48, 0x8f4b, 0x9128, 0x913a, 0x913b, 0x913e, 0x91a8, 0x91a5, + 0x91a7, 0x91af, 0x91aa, 0x93b5, 0x938c, 0x9392, 0x93b7, 0x939b, + 0x939d, 0x9389, 0x93a7, 0x938e, 0x93aa, 0x939e, 0x93a6, 0x9395, + 0x9388, 0x9399, 0x939f, 0x938d, 0x93b1, 0x9391, 0x93b2, 0x93a4, + 0x93a8, 0x93b4, 0x93a3, 0x93a5, 0x95d2, 0x95d3, 0x95d1, 0x96b3, + 0x96d7, 0x96da, 0x5dc2, 0x96df, 0x96d8, 0x96dd, 0x9723, 0x9722, + 0x9725, 0x97ac, 0x97ae, 0x97a8, 0x97ab, 0x97a4, 0x97aa, 0x97a2, + 0x97a5, 0x97d7, 0x97d9, 0x97d6, 0x97d8, 0x97fa, 0x9850, 0x9851, + 0x9852, 0x98b8, 0x9941, 0x993c, 0x993a, 0x9a0f, 0x9a0b, 0x9a09, + 0x9a0d, 0x9a04, 0x9a11, 0x9a0a, 0x9a05, 0x9a07, 0x9a06, 0x9ac0, + 0x9adc, 0x9b08, 0x9b04, 0x9b05, 0x9b29, 0x9b35, 0x9b4a, 0x9b4c, + 0x9b4b, 0x9bc7, 0x9bc6, 0x9bc3, 0x9bbf, 0x9bc1, 0x9bb5, 0x9bb8, + 0x9bd3, 0x9bb6, 0x9bc4, 0x9bb9, 0x9bbd, 0x9d5c, 0x9d53, 0x9d4f, + 0x9d4a, 0x9d5b, 0x9d4b, 0x9d59, 0x9d56, 0x9d4c, 0x9d57, 0x9d52, + 0x9d54, 0x9d5f, 0x9d58, 0x9d5a, 0x9e8e, 0x9e8c, 0x9edf, 0x9f01, + 0x9f00, 0x9f16, 0x9f25, 0x9f2b, 0x9f2a, 0x9f29, 0x9f28, 0x9f4c, + 0x9f55, 0x5134, 0x5135, 0x5296, 0x52f7, 0x53b4, 0x56ab, 0x56ad, + 0x56a6, 0x56a7, 0x56aa, 0x56ac, 0x58da, 0x58dd, 0x58db, 0x5912, + 0x5b3d, 0x5b3e, 0x5b3f, 0x5dc3, 0x5e70, + /* 0xf2 */ + 0x5fbf, 0x61fb, 0x6507, 0x6510, 0x650d, 0x6509, 0x650c, 0x650e, + 0x6584, 0x65de, 0x65dd, 0x66de, 0x6ae7, 0x6ae0, 0x6acc, 0x6ad1, + 0x6ad9, 0x6acb, 0x6adf, 0x6adc, 0x6ad0, 0x6aeb, 0x6acf, 0x6acd, + 0x6ade, 0x6b60, 0x6bb0, 0x6c0c, 0x7019, 0x7027, 0x7020, 0x7016, + 0x702b, 0x7021, 0x7022, 0x7023, 0x7029, 0x7017, 0x7024, 0x701c, + 0x702a, 0x720c, 0x720a, 0x7207, 0x7202, 0x7205, 0x72a5, 0x72a6, + 0x72a4, 0x72a3, 0x72a1, 0x74cb, 0x74c5, 0x74b7, 0x74c3, 0x7516, + 0x7660, 0x77c9, 0x77ca, 0x77c4, 0x77f1, 0x791d, 0x791b, 0x7921, + 0x791c, 0x7917, 0x791e, 0x79b0, 0x7a67, 0x7a68, 0x7c33, 0x7c3c, + 0x7c39, 0x7c2c, 0x7c3b, 0x7cec, 0x7cea, 0x7e76, 0x7e75, 0x7e78, + 0x7e70, 0x7e77, 0x7e6f, 0x7e7a, 0x7e72, 0x7e74, 0x7e68, 0x7f4b, + 0x7f4a, 0x7f83, 0x7f86, 0x7fb7, 0x7ffd, 0x7ffe, 0x8078, 0x81d7, + 0x81d5, 0x8264, 0x8261, 0x8263, 0x85eb, 0x85f1, 0x85ed, 0x85d9, + 0x85e1, 0x85e8, 0x85da, 0x85d7, 0x85ec, 0x85f2, 0x85f8, 0x85d8, + 0x85df, 0x85e3, 0x85dc, 0x85d1, 0x85f0, 0x85e6, 0x85ef, 0x85de, + 0x85e2, 0x8800, 0x87fa, 0x8803, 0x87f6, 0x87f7, 0x8809, 0x880c, + 0x880b, 0x8806, 0x87fc, 0x8808, 0x87ff, 0x880a, 0x8802, 0x8962, + 0x895a, 0x895b, 0x8957, 0x8961, 0x895c, 0x8958, 0x895d, 0x8959, + 0x8988, 0x89b7, 0x89b6, 0x89f6, 0x8b50, 0x8b48, 0x8b4a, 0x8b40, + 0x8b53, 0x8b56, 0x8b54, 0x8b4b, 0x8b55, + /* 0xf3 */ + 0x8b51, 0x8b42, 0x8b52, 0x8b57, 0x8c43, 0x8c77, 0x8c76, 0x8c9a, + 0x8d06, 0x8d07, 0x8d09, 0x8dac, 0x8daa, 0x8dad, 0x8dab, 0x8e6d, + 0x8e78, 0x8e73, 0x8e6a, 0x8e6f, 0x8e7b, 0x8ec2, 0x8f52, 0x8f51, + 0x8f4f, 0x8f50, 0x8f53, 0x8fb4, 0x9140, 0x913f, 0x91b0, 0x91ad, + 0x93de, 0x93c7, 0x93cf, 0x93c2, 0x93da, 0x93d0, 0x93f9, 0x93ec, + 0x93cc, 0x93d9, 0x93a9, 0x93e6, 0x93ca, 0x93d4, 0x93ee, 0x93e3, + 0x93d5, 0x93c4, 0x93ce, 0x93c0, 0x93d2, 0x93e7, 0x957d, 0x95da, + 0x95db, 0x96e1, 0x9729, 0x972b, 0x972c, 0x9728, 0x9726, 0x97b3, + 0x97b7, 0x97b6, 0x97dd, 0x97de, 0x97df, 0x985c, 0x9859, 0x985d, + 0x9857, 0x98bf, 0x98bd, 0x98bb, 0x98be, 0x9948, 0x9947, 0x9943, + 0x99a6, 0x99a7, 0x9a1a, 0x9a15, 0x9a25, 0x9a1d, 0x9a24, 0x9a1b, + 0x9a22, 0x9a20, 0x9a27, 0x9a23, 0x9a1e, 0x9a1c, 0x9a14, 0x9ac2, + 0x9b0b, 0x9b0a, 0x9b0e, 0x9b0c, 0x9b37, 0x9bea, 0x9beb, 0x9be0, + 0x9bde, 0x9be4, 0x9be6, 0x9be2, 0x9bf0, 0x9bd4, 0x9bd7, 0x9bec, + 0x9bdc, 0x9bd9, 0x9be5, 0x9bd5, 0x9be1, 0x9bda, 0x9d77, 0x9d81, + 0x9d8a, 0x9d84, 0x9d88, 0x9d71, 0x9d80, 0x9d78, 0x9d86, 0x9d8b, + 0x9d8c, 0x9d7d, 0x9d6b, 0x9d74, 0x9d75, 0x9d70, 0x9d69, 0x9d85, + 0x9d73, 0x9d7b, 0x9d82, 0x9d6f, 0x9d79, 0x9d7f, 0x9d87, 0x9d68, + 0x9e94, 0x9e91, 0x9ec0, 0x9efc, 0x9f2d, 0x9f40, 0x9f41, 0x9f4d, + 0x9f56, 0x9f57, 0x9f58, 0x5337, 0x56b2, + /* 0xf4 */ + 0x56b5, 0x56b3, 0x58e3, 0x5b45, 0x5dc6, 0x5dc7, 0x5eee, 0x5eef, + 0x5fc0, 0x5fc1, 0x61f9, 0x6517, 0x6516, 0x6515, 0x6513, 0x65df, + 0x66e8, 0x66e3, 0x66e4, 0x6af3, 0x6af0, 0x6aea, 0x6ae8, 0x6af9, + 0x6af1, 0x6aee, 0x6aef, 0x703c, 0x7035, 0x702f, 0x7037, 0x7034, + 0x7031, 0x7042, 0x7038, 0x703f, 0x703a, 0x7039, 0x7040, 0x703b, + 0x7033, 0x7041, 0x7213, 0x7214, 0x72a8, 0x737d, 0x737c, 0x74ba, + 0x76ab, 0x76aa, 0x76be, 0x76ed, 0x77cc, 0x77ce, 0x77cf, 0x77cd, + 0x77f2, 0x7925, 0x7923, 0x7927, 0x7928, 0x7924, 0x7929, 0x79b2, + 0x7a6e, 0x7a6c, 0x7a6d, 0x7af7, 0x7c49, 0x7c48, 0x7c4a, 0x7c47, + 0x7c45, 0x7cee, 0x7e7b, 0x7e7e, 0x7e81, 0x7e80, 0x7fba, 0x7fff, + 0x8079, 0x81db, 0x81d9, 0x820b, 0x8268, 0x8269, 0x8622, 0x85ff, + 0x8601, 0x85fe, 0x861b, 0x8600, 0x85f6, 0x8604, 0x8609, 0x8605, + 0x860c, 0x85fd, 0x8819, 0x8810, 0x8811, 0x8817, 0x8813, 0x8816, + 0x8963, 0x8966, 0x89b9, 0x89f7, 0x8b60, 0x8b6a, 0x8b5d, 0x8b68, + 0x8b63, 0x8b65, 0x8b67, 0x8b6d, 0x8dae, 0x8e86, 0x8e88, 0x8e84, + 0x8f59, 0x8f56, 0x8f57, 0x8f55, 0x8f58, 0x8f5a, 0x908d, 0x9143, + 0x9141, 0x91b7, 0x91b5, 0x91b2, 0x91b3, 0x940b, 0x9413, 0x93fb, + 0x9420, 0x940f, 0x9414, 0x93fe, 0x9415, 0x9410, 0x9428, 0x9419, + 0x940d, 0x93f5, 0x9400, 0x93f7, 0x9407, 0x940e, 0x9416, 0x9412, + 0x93fa, 0x9409, 0x93f8, 0x940a, 0x93ff, + /* 0xf5 */ + 0x93fc, 0x940c, 0x93f6, 0x9411, 0x9406, 0x95de, 0x95e0, 0x95df, + 0x972e, 0x972f, 0x97b9, 0x97bb, 0x97fd, 0x97fe, 0x9860, 0x9862, + 0x9863, 0x985f, 0x98c1, 0x98c2, 0x9950, 0x994e, 0x9959, 0x994c, + 0x994b, 0x9953, 0x9a32, 0x9a34, 0x9a31, 0x9a2c, 0x9a2a, 0x9a36, + 0x9a29, 0x9a2e, 0x9a38, 0x9a2d, 0x9ac7, 0x9aca, 0x9ac6, 0x9b10, + 0x9b12, 0x9b11, 0x9c0b, 0x9c08, 0x9bf7, 0x9c05, 0x9c12, 0x9bf8, + 0x9c40, 0x9c07, 0x9c0e, 0x9c06, 0x9c17, 0x9c14, 0x9c09, 0x9d9f, + 0x9d99, 0x9da4, 0x9d9d, 0x9d92, 0x9d98, 0x9d90, 0x9d9b, 0x9da0, + 0x9d94, 0x9d9c, 0x9daa, 0x9d97, 0x9da1, 0x9d9a, 0x9da2, 0x9da8, + 0x9d9e, 0x9da3, 0x9dbf, 0x9da9, 0x9d96, 0x9da6, 0x9da7, 0x9e99, + 0x9e9b, 0x9e9a, 0x9ee5, 0x9ee4, 0x9ee7, 0x9ee6, 0x9f30, 0x9f2e, + 0x9f5b, 0x9f60, 0x9f5e, 0x9f5d, 0x9f59, 0x9f91, 0x513a, 0x5139, + 0x5298, 0x5297, 0x56c3, 0x56bd, 0x56be, 0x5b48, 0x5b47, 0x5dcb, + 0x5dcf, 0x5ef1, 0x61fd, 0x651b, 0x6b02, 0x6afc, 0x6b03, 0x6af8, + 0x6b00, 0x7043, 0x7044, 0x704a, 0x7048, 0x7049, 0x7045, 0x7046, + 0x721d, 0x721a, 0x7219, 0x737e, 0x7517, 0x766a, 0x77d0, 0x792d, + 0x7931, 0x792f, 0x7c54, 0x7c53, 0x7cf2, 0x7e8a, 0x7e87, 0x7e88, + 0x7e8b, 0x7e86, 0x7e8d, 0x7f4d, 0x7fbb, 0x8030, 0x81dd, 0x8618, + 0x862a, 0x8626, 0x861f, 0x8623, 0x861c, 0x8619, 0x8627, 0x862e, + 0x8621, 0x8620, 0x8629, 0x861e, 0x8625, + /* 0xf6 */ + 0x8829, 0x881d, 0x881b, 0x8820, 0x8824, 0x881c, 0x882b, 0x884a, + 0x896d, 0x8969, 0x896e, 0x896b, 0x89fa, 0x8b79, 0x8b78, 0x8b45, + 0x8b7a, 0x8b7b, 0x8d10, 0x8d14, 0x8daf, 0x8e8e, 0x8e8c, 0x8f5e, + 0x8f5b, 0x8f5d, 0x9146, 0x9144, 0x9145, 0x91b9, 0x943f, 0x943b, + 0x9436, 0x9429, 0x943d, 0x943c, 0x9430, 0x9439, 0x942a, 0x9437, + 0x942c, 0x9440, 0x9431, 0x95e5, 0x95e4, 0x95e3, 0x9735, 0x973a, + 0x97bf, 0x97e1, 0x9864, 0x98c9, 0x98c6, 0x98c0, 0x9958, 0x9956, + 0x9a39, 0x9a3d, 0x9a46, 0x9a44, 0x9a42, 0x9a41, 0x9a3a, 0x9a3f, + 0x9acd, 0x9b15, 0x9b17, 0x9b18, 0x9b16, 0x9b3a, 0x9b52, 0x9c2b, + 0x9c1d, 0x9c1c, 0x9c2c, 0x9c23, 0x9c28, 0x9c29, 0x9c24, 0x9c21, + 0x9db7, 0x9db6, 0x9dbc, 0x9dc1, 0x9dc7, 0x9dca, 0x9dcf, 0x9dbe, + 0x9dc5, 0x9dc3, 0x9dbb, 0x9db5, 0x9dce, 0x9db9, 0x9dba, 0x9dac, + 0x9dc8, 0x9db1, 0x9dad, 0x9dcc, 0x9db3, 0x9dcd, 0x9db2, 0x9e7a, + 0x9e9c, 0x9eeb, 0x9eee, 0x9eed, 0x9f1b, 0x9f18, 0x9f1a, 0x9f31, + 0x9f4e, 0x9f65, 0x9f64, 0x9f92, 0x4eb9, 0x56c6, 0x56c5, 0x56cb, + 0x5971, 0x5b4b, 0x5b4c, 0x5dd5, 0x5dd1, 0x5ef2, 0x6521, 0x6520, + 0x6526, 0x6522, 0x6b0b, 0x6b08, 0x6b09, 0x6c0d, 0x7055, 0x7056, + 0x7057, 0x7052, 0x721e, 0x721f, 0x72a9, 0x737f, 0x74d8, 0x74d5, + 0x74d9, 0x74d7, 0x766d, 0x76ad, 0x7935, 0x79b4, 0x7a70, 0x7a71, + 0x7c57, 0x7c5c, 0x7c59, 0x7c5b, 0x7c5a, + /* 0xf7 */ + 0x7cf4, 0x7cf1, 0x7e91, 0x7f4f, 0x7f87, 0x81de, 0x826b, 0x8634, + 0x8635, 0x8633, 0x862c, 0x8632, 0x8636, 0x882c, 0x8828, 0x8826, + 0x882a, 0x8825, 0x8971, 0x89bf, 0x89be, 0x89fb, 0x8b7e, 0x8b84, + 0x8b82, 0x8b86, 0x8b85, 0x8b7f, 0x8d15, 0x8e95, 0x8e94, 0x8e9a, + 0x8e92, 0x8e90, 0x8e96, 0x8e97, 0x8f60, 0x8f62, 0x9147, 0x944c, + 0x9450, 0x944a, 0x944b, 0x944f, 0x9447, 0x9445, 0x9448, 0x9449, + 0x9446, 0x973f, 0x97e3, 0x986a, 0x9869, 0x98cb, 0x9954, 0x995b, + 0x9a4e, 0x9a53, 0x9a54, 0x9a4c, 0x9a4f, 0x9a48, 0x9a4a, 0x9a49, + 0x9a52, 0x9a50, 0x9ad0, 0x9b19, 0x9b2b, 0x9b3b, 0x9b56, 0x9b55, + 0x9c46, 0x9c48, 0x9c3f, 0x9c44, 0x9c39, 0x9c33, 0x9c41, 0x9c3c, + 0x9c37, 0x9c34, 0x9c32, 0x9c3d, 0x9c36, 0x9ddb, 0x9dd2, 0x9dde, + 0x9dda, 0x9dcb, 0x9dd0, 0x9ddc, 0x9dd1, 0x9ddf, 0x9de9, 0x9dd9, + 0x9dd8, 0x9dd6, 0x9df5, 0x9dd5, 0x9ddd, 0x9eb6, 0x9ef0, 0x9f35, + 0x9f33, 0x9f32, 0x9f42, 0x9f6b, 0x9f95, 0x9fa2, 0x513d, 0x5299, + 0x58e8, 0x58e7, 0x5972, 0x5b4d, 0x5dd8, 0x882f, 0x5f4f, 0x6201, + 0x6203, 0x6204, 0x6529, 0x6525, 0x6596, 0x66eb, 0x6b11, 0x6b12, + 0x6b0f, 0x6bca, 0x705b, 0x705a, 0x7222, 0x7382, 0x7381, 0x7383, + 0x7670, 0x77d4, 0x7c67, 0x7c66, 0x7e95, 0x826c, 0x863a, 0x8640, + 0x8639, 0x863c, 0x8631, 0x863b, 0x863e, 0x8830, 0x8832, 0x882e, + 0x8833, 0x8976, 0x8974, 0x8973, 0x89fe, + /* 0xf8 */ + 0x8b8c, 0x8b8e, 0x8b8b, 0x8b88, 0x8c45, 0x8d19, 0x8e98, 0x8f64, + 0x8f63, 0x91bc, 0x9462, 0x9455, 0x945d, 0x9457, 0x945e, 0x97c4, + 0x97c5, 0x9800, 0x9a56, 0x9a59, 0x9b1e, 0x9b1f, 0x9b20, 0x9c52, + 0x9c58, 0x9c50, 0x9c4a, 0x9c4d, 0x9c4b, 0x9c55, 0x9c59, 0x9c4c, + 0x9c4e, 0x9dfb, 0x9df7, 0x9def, 0x9de3, 0x9deb, 0x9df8, 0x9de4, + 0x9df6, 0x9de1, 0x9dee, 0x9de6, 0x9df2, 0x9df0, 0x9de2, 0x9dec, + 0x9df4, 0x9df3, 0x9de8, 0x9ded, 0x9ec2, 0x9ed0, 0x9ef2, 0x9ef3, + 0x9f06, 0x9f1c, 0x9f38, 0x9f37, 0x9f36, 0x9f43, 0x9f4f, 0x9f71, + 0x9f70, 0x9f6e, 0x9f6f, 0x56d3, 0x56cd, 0x5b4e, 0x5c6d, 0x652d, + 0x66ed, 0x66ee, 0x6b13, 0x705f, 0x7061, 0x705d, 0x7060, 0x7223, + 0x74db, 0x74e5, 0x77d5, 0x7938, 0x79b7, 0x79b6, 0x7c6a, 0x7e97, + 0x7f89, 0x826d, 0x8643, 0x8838, 0x8837, 0x8835, 0x884b, 0x8b94, + 0x8b95, 0x8e9e, 0x8e9f, 0x8ea0, 0x8e9d, 0x91be, 0x91bd, 0x91c2, + 0x946b, 0x9468, 0x9469, 0x96e5, 0x9746, 0x9743, 0x9747, 0x97c7, + 0x97e5, 0x9a5e, 0x9ad5, 0x9b59, 0x9c63, 0x9c67, 0x9c66, 0x9c62, + 0x9c5e, 0x9c60, 0x9e02, 0x9dfe, 0x9e07, 0x9e03, 0x9e06, 0x9e05, + 0x9e00, 0x9e01, 0x9e09, 0x9dff, 0x9dfd, 0x9e04, 0x9ea0, 0x9f1e, + 0x9f46, 0x9f74, 0x9f75, 0x9f76, 0x56d4, 0x652e, 0x65b8, 0x6b18, + 0x6b19, 0x6b17, 0x6b1a, 0x7062, 0x7226, 0x72aa, 0x77d8, 0x77d9, + 0x7939, 0x7c69, 0x7c6b, 0x7cf6, 0x7e9a, + /* 0xf9 */ + 0x7e98, 0x7e9b, 0x7e99, 0x81e0, 0x81e1, 0x8646, 0x8647, 0x8648, + 0x8979, 0x897a, 0x897c, 0x897b, 0x89ff, 0x8b98, 0x8b99, 0x8ea5, + 0x8ea4, 0x8ea3, 0x946e, 0x946d, 0x946f, 0x9471, 0x9473, 0x9749, + 0x9872, 0x995f, 0x9c68, 0x9c6e, 0x9c6d, 0x9e0b, 0x9e0d, 0x9e10, + 0x9e0f, 0x9e12, 0x9e11, 0x9ea1, 0x9ef5, 0x9f09, 0x9f47, 0x9f78, + 0x9f7b, 0x9f7a, 0x9f79, 0x571e, 0x7066, 0x7c6f, 0x883c, 0x8db2, + 0x8ea6, 0x91c3, 0x9474, 0x9478, 0x9476, 0x9475, 0x9a60, 0x9c74, + 0x9c73, 0x9c71, 0x9c75, 0x9e14, 0x9e13, 0x9ef6, 0x9f0a, 0x9fa4, + 0x7068, 0x7065, 0x7cf7, 0x866a, 0x883e, 0x883d, 0x883f, 0x8b9e, + 0x8c9c, 0x8ea9, 0x8ec9, 0x974b, 0x9873, 0x9874, 0x98cc, 0x9961, + 0x99ab, 0x9a64, 0x9a66, 0x9a67, 0x9b24, 0x9e15, 0x9e17, 0x9f48, + 0x6207, 0x6b1e, 0x7227, 0x864c, 0x8ea8, 0x9482, 0x9480, 0x9481, + 0x9a69, 0x9a68, 0x9b2e, 0x9e19, 0x7229, 0x864b, 0x8b9f, 0x9483, + 0x9c79, 0x9eb7, 0x7675, 0x9a6b, 0x9c7a, 0x9e1d, 0x7069, 0x706a, + 0x9ea4, 0x9f7e, 0x9f49, 0x9f98, +}; + +static int +big5_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0xa1 && c1 <= 0xc7) || (c1 >= 0xc9 && c1 <= 0xf9)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) { + unsigned int i = 157 * (c1 - 0xa1) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); + unsigned short wc = 0xfffd; + if (i < 6280) { + if (i < 6121) + wc = big5_2uni_pagea1[i]; + } else { + if (i < 13932) + wc = big5_2uni_pagec9[i-6280]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short big5_2charset[13703] = { + 0xa246, 0xa247, 0xa244, 0xa1b1, 0xa258, 0xa1d3, 0xa150, 0xa1d1, + 0xa1d2, 0xa3be, 0xa3bc, 0xa3bd, 0xa3bf, 0xa3bb, 0xa344, 0xa345, + 0xa346, 0xa347, 0xa348, 0xa349, 0xa34a, 0xa34b, 0xa34c, 0xa34d, + 0xa34e, 0xa34f, 0xa350, 0xa351, 0xa352, 0xa353, 0xa354, 0xa355, + 0xa356, 0xa357, 0xa358, 0xa359, 0xa35a, 0xa35b, 0xa35c, 0xa35d, + 0xa35e, 0xa35f, 0xa360, 0xa361, 0xa362, 0xa363, 0xa364, 0xa365, + 0xa366, 0xa367, 0xa368, 0xa369, 0xa36a, 0xa36b, 0xa36c, 0xa36d, + 0xa36e, 0xa36f, 0xa370, 0xa371, 0xa372, 0xa373, 0xc7b3, 0xc7b1, + 0xc7b2, 0xc7b4, 0xc7b5, 0xc7b6, 0xc7b7, 0xc7b8, 0xc7b9, 0xc7ba, + 0xc7bb, 0xc7bc, 0xc7bd, 0xc7be, 0xc7bf, 0xc7c0, 0xc7c1, 0xc7c2, + 0xc7c3, 0xc7c4, 0xc7c5, 0xc7c6, 0xc7c7, 0xc7c8, 0xc7c9, 0xc7ca, + 0xc7cb, 0xc7cc, 0xc7cd, 0xc7cf, 0xc7d0, 0xc7d1, 0xc7d2, 0xc7d3, + 0xc7d4, 0xc7d5, 0xc7d6, 0xc7d7, 0xc7d8, 0xc7d9, 0xc7da, 0xc7db, + 0xc7dc, 0xc7dd, 0xc7de, 0xc7df, 0xc7e0, 0xc7e1, 0xc7e2, 0xc7e3, + 0xc7e4, 0xc7e5, 0xc7e6, 0xc7e7, 0xc7e8, 0xc7ce, 0xa156, 0xa158, + 0xa1a5, 0xa1a6, 0xa1a7, 0xa1a8, 0xa145, 0xa14c, 0xa14b, 0xa1ac, + 0xa1ab, 0xa1b0, 0xa1c2, 0xa24a, 0xa1c1, 0xa24b, 0xa2b9, 0xa2ba, + 0xa2bb, 0xa2bc, 0xa2bd, 0xa2be, 0xa2bf, 0xa2c0, 0xa2c1, 0xa2c2, + 0xa1f6, 0xa1f4, 0xa1f7, 0xa1f5, 0xa1f8, 0xa1f9, 0xa1fb, 0xa1fa, + 0xa1d4, 0xa1db, 0xa1e8, 0xa1e7, 0xa1fd, 0xa1fc, 0xa1e4, 0xa1e5, + 0xa1ec, 0xa1ed, 0xa1ef, 0xa1ee, 0xa1e3, 0xa1dc, 0xa1da, 0xa1dd, + 0xa1d8, 0xa1d9, 0xa1e6, 0xa1e9, 0xc7e9, 0xc7ea, 0xc7eb, 0xc7ec, + 0xc7ed, 0xc7ee, 0xc7ef, 0xc7f0, 0xc7f1, 0xc7f2, 0xc7f3, 0xc7f4, + 0xc7f5, 0xc7f6, 0xc7f7, 0xc7f8, 0xc7f9, 0xc7fa, 0xc7fb, 0xc7fc, + 0xa277, 0xa278, 0xa27a, 0xa27b, 0xa27c, 0xa27d, 0xa275, 0xa274, + 0xa273, 0xa272, 0xa271, 0xa2a4, 0xa2a5, 0xa2a7, 0xa2a6, 0xa27e, + 0xa2a1, 0xa2a3, 0xa2a2, 0xa2ac, 0xa2ad, 0xa2ae, 0xa262, 0xa263, + 0xa264, 0xa265, 0xa266, 0xa267, 0xa268, 0xa269, 0xa270, 0xa26f, + 0xa26e, 0xa26d, 0xa26c, 0xa26b, 0xa26a, 0xa276, 0xa279, 0xa1bd, + 0xa1bc, 0xa1b6, 0xa1b5, 0xa1bf, 0xa1be, 0xa1bb, 0xa1ba, 0xa1b3, + 0xa1b7, 0xa1b4, 0xa2a8, 0xa2a9, 0xa2ab, 0xa2aa, 0xa1b9, 0xa1b8, + 0xa1f3, 0xa1f0, 0xa1f2, 0xa1f1, 0xa140, 0xa142, 0xa143, 0xa1b2, + 0xc6a4, 0xa171, 0xa172, 0xa16d, 0xa16e, 0xa175, 0xa176, 0xa179, + 0xa17a, 0xa169, 0xa16a, 0xa245, 0xa165, 0xa166, 0xa1a9, 0xa1aa, + 0xa2c3, 0xa2c4, 0xa2c5, 0xa2c6, 0xa2c7, 0xa2c8, 0xa2c9, 0xa2ca, + 0xa2cb, 0xc6a5, 0xc6a6, 0xc6a7, 0xc6a8, 0xc6a9, 0xc6aa, 0xc6ab, + 0xc6ac, 0xc6ad, 0xc6ae, 0xc6af, 0xc6b0, 0xc6b1, 0xc6b2, 0xc6b3, + 0xc6b4, 0xc6b5, 0xc6b6, 0xc6b7, 0xc6b8, 0xc6b9, 0xc6ba, 0xc6bb, + 0xc6bc, 0xc6bd, 0xc6be, 0xc6bf, 0xc6c0, 0xc6c1, 0xc6c2, 0xc6c3, + 0xc6c4, 0xc6c5, 0xc6c6, 0xc6c7, 0xc6c8, 0xc6c9, 0xc6ca, 0xc6cb, + 0xc6cc, 0xc6cd, 0xc6ce, 0xc6cf, 0xc6d0, 0xc6d1, 0xc6d2, 0xc6d3, + 0xc6d4, 0xc6d5, 0xc6d6, 0xc6d7, 0xc6d8, 0xc6d9, 0xc6da, 0xc6db, + 0xc6dc, 0xc6dd, 0xc6de, 0xc6df, 0xc6e0, 0xc6e1, 0xc6e2, 0xc6e3, + 0xc6e4, 0xc6e5, 0xc6e6, 0xc6e7, 0xc6e8, 0xc6e9, 0xc6ea, 0xc6eb, + 0xc6ec, 0xc6ed, 0xc6ee, 0xc6ef, 0xc6f0, 0xc6f1, 0xc6f2, 0xc6f3, + 0xc6f4, 0xc6f5, 0xc6f6, 0xc6f7, 0xc6a2, 0xc6a3, 0xc6f8, 0xc6f9, + 0xc6fa, 0xc6fb, 0xc6fc, 0xc6fd, 0xc6fe, 0xc740, 0xc741, 0xc742, + 0xc743, 0xc744, 0xc745, 0xc746, 0xc747, 0xc748, 0xc749, 0xc74a, + 0xc74b, 0xc74c, 0xc74d, 0xc74e, 0xc74f, 0xc750, 0xc751, 0xc752, + 0xc753, 0xc754, 0xc755, 0xc756, 0xc757, 0xc758, 0xc759, 0xc75a, + 0xc75b, 0xc75c, 0xc75d, 0xc75e, 0xc75f, 0xc760, 0xc761, 0xc762, + 0xc763, 0xc764, 0xc765, 0xc766, 0xc767, 0xc768, 0xc769, 0xc76a, + 0xc76b, 0xc76c, 0xc76d, 0xc76e, 0xc76f, 0xc770, 0xc771, 0xc772, + 0xc773, 0xc774, 0xc775, 0xc776, 0xc777, 0xc778, 0xc779, 0xc77a, + 0xc77b, 0xc77c, 0xc77d, 0xc77e, 0xc7a1, 0xc7a2, 0xc7a3, 0xc7a4, + 0xc7a5, 0xc7a6, 0xc7a7, 0xc7a8, 0xc7a9, 0xc7aa, 0xc7ab, 0xc7ac, + 0xc7ad, 0xc7ae, 0xc7af, 0xc7b0, 0xc6a1, 0xa374, 0xa375, 0xa376, + 0xa377, 0xa378, 0xa379, 0xa37a, 0xa37b, 0xa37c, 0xa37d, 0xa37e, + 0xa3a1, 0xa3a2, 0xa3a3, 0xa3a4, 0xa3a5, 0xa3a6, 0xa3a7, 0xa3a8, + 0xa3a9, 0xa3aa, 0xa3ab, 0xa3ac, 0xa3ad, 0xa3ae, 0xa3af, 0xa3b0, + 0xa3b1, 0xa3b2, 0xa3b3, 0xa3b4, 0xa3b5, 0xa3b6, 0xa3b7, 0xa3b8, + 0xa3b9, 0xa3ba, 0xa1c0, 0xa255, 0xa256, 0xa250, 0xa251, 0xa252, + 0xa254, 0xa257, 0xa253, 0xa1eb, 0xa1ea, 0xa24f, 0xa440, 0xa442, + 0xa443, 0xc945, 0xa456, 0xa454, 0xa457, 0xa455, 0xc946, 0xa4a3, + 0xc94f, 0xc94d, 0xa4a2, 0xa4a1, 0xa542, 0xa541, 0xa540, 0xa543, + 0xa4fe, 0xa5e0, 0xa5e1, 0xa8c3, 0xa458, 0xa4a4, 0xc950, 0xa4a5, + 0xc963, 0xa6ea, 0xcbb1, 0xa459, 0xa4a6, 0xa544, 0xc964, 0xc940, + 0xa444, 0xa45b, 0xc947, 0xa45c, 0xa4a7, 0xa545, 0xa547, 0xa546, + 0xa5e2, 0xa5e3, 0xa8c4, 0xadbc, 0xa441, 0xc941, 0xa445, 0xa45e, + 0xa45d, 0xa5e4, 0xa8c5, 0xb0ae, 0xd44b, 0xb6c3, 0xdcb1, 0xdcb2, + 0xa446, 0xa4a9, 0xa8c6, 0xa447, 0xc948, 0xa45f, 0xa4aa, 0xa4ac, + 0xc951, 0xa4ad, 0xa4ab, 0xa5e5, 0xa8c7, 0xa8c8, 0xab45, 0xa460, + 0xa4ae, 0xa5e6, 0xa5e8, 0xa5e7, 0xa6eb, 0xa8c9, 0xa8ca, 0xab46, + 0xab47, 0xadbd, 0xdcb3, 0xf6d6, 0xa448, 0xa4b0, 0xa4af, 0xc952, + 0xa4b1, 0xa4b7, 0xa4b2, 0xa4b3, 0xc954, 0xc953, 0xa4b5, 0xa4b6, + 0xa4b4, 0xa54a, 0xa54b, 0xa54c, 0xa54d, 0xa549, 0xa550, 0xc96a, + 0xc966, 0xc969, 0xa551, 0xa561, 0xc968, 0xa54e, 0xa54f, 0xa548, + 0xc965, 0xc967, 0xa5f5, 0xc9b0, 0xa5f2, 0xa5f6, 0xc9ba, 0xc9ae, + 0xa5f3, 0xc9b2, 0xa5f4, 0xa5f7, 0xa5e9, 0xc9b1, 0xa5f8, 0xc9b5, + 0xc9b9, 0xc9b6, 0xc9b3, 0xa5ea, 0xa5ec, 0xa5f9, 0xa5ee, 0xc9ab, + 0xa5f1, 0xa5ef, 0xa5f0, 0xc9bb, 0xc9b8, 0xc9af, 0xa5ed, 0xc9ac, + 0xa5eb, 0xc9b4, 0xc9b7, 0xc9ad, 0xca66, 0xa742, 0xa6f4, 0xca67, + 0xa6f1, 0xa744, 0xa6f9, 0xa6f8, 0xca5b, 0xa6fc, 0xa6f7, 0xca60, + 0xca68, 0xca64, 0xa6fa, 0xa6fd, 0xa6ee, 0xa747, 0xca5d, 0xcbbd, + 0xa6ec, 0xa743, 0xa6ed, 0xa6f5, 0xa6f6, 0xca62, 0xca5e, 0xa6fb, + 0xa6f3, 0xca5a, 0xa6ef, 0xca65, 0xa745, 0xa748, 0xa6f2, 0xa740, + 0xa746, 0xa6f0, 0xca63, 0xa741, 0xca69, 0xca5c, 0xa6fe, 0xca5f, + 0xca61, 0xa8d8, 0xcbbf, 0xcbcb, 0xa8d0, 0xcbcc, 0xa8cb, 0xa8d5, + 0xa8ce, 0xcbb9, 0xa8d6, 0xcbb8, 0xcbbc, 0xcbc3, 0xcbc1, 0xa8de, + 0xa8d9, 0xcbb3, 0xcbb5, 0xa8db, 0xa8cf, 0xcbb6, 0xcbc2, 0xcbc9, + 0xa8d4, 0xcbbb, 0xcbb4, 0xa8d3, 0xcbb7, 0xa8d7, 0xcbba, 0xa8d2, + 0xa8cd, 0xa8dc, 0xcbc4, 0xa8dd, 0xcbc8, 0xcbc6, 0xcbca, 0xa8da, + 0xcbbe, 0xcbb2, 0xcbc0, 0xa8d1, 0xcbc5, 0xa8cc, 0xcbc7, 0xab56, + 0xab4a, 0xcde0, 0xcde8, 0xab49, 0xab51, 0xab5d, 0xcdee, 0xcdec, + 0xcde7, 0xab4b, 0xcded, 0xcde3, 0xab59, 0xab50, 0xab58, 0xcdde, + 0xcdea, 0xcde1, 0xab54, 0xcde2, 0xcddd, 0xab5b, 0xab4e, 0xab57, + 0xab4d, 0xcddf, 0xcde4, 0xcdeb, 0xab55, 0xab52, 0xcde6, 0xab5a, + 0xcde9, 0xcde5, 0xab4f, 0xab5c, 0xab53, 0xab4c, 0xab48, 0xcdef, + 0xadd7, 0xadc1, 0xadd1, 0xadd6, 0xd0d0, 0xd0cf, 0xd0d4, 0xd0d5, + 0xadc4, 0xadcd, 0xadda, 0xadce, 0xd0c9, 0xadc7, 0xd0ca, 0xaddc, + 0xadd3, 0xadbe, 0xadbf, 0xd0dd, 0xb0bf, 0xadcc, 0xadcb, 0xd0cb, + 0xadcf, 0xd45b, 0xadc6, 0xd0d6, 0xadd5, 0xadd4, 0xadca, 0xd0ce, + 0xd0d7, 0xd0c8, 0xadc9, 0xd0d8, 0xadd2, 0xd0cc, 0xadc0, 0xadc3, + 0xadc2, 0xd0d9, 0xadd0, 0xadc5, 0xadd9, 0xaddb, 0xd0d3, 0xadd8, + 0xd0db, 0xd0cd, 0xd0dc, 0xd0d1, 0xd0da, 0xd0d2, 0xadc8, 0xd463, + 0xd457, 0xb0b3, 0xd45c, 0xd462, 0xb0b2, 0xd455, 0xb0b6, 0xd459, + 0xd452, 0xb0b4, 0xd456, 0xb0b9, 0xb0be, 0xd467, 0xd451, 0xb0ba, + 0xd466, 0xb0b5, 0xd458, 0xb0b1, 0xd453, 0xd44f, 0xd45d, 0xd450, + 0xd44e, 0xd45a, 0xd460, 0xd461, 0xb0b7, 0xd85b, 0xd45e, 0xd44d, + 0xd45f, 0xb0c1, 0xd464, 0xb0c0, 0xd44c, 0xd454, 0xd465, 0xb0bc, + 0xb0bb, 0xb0b8, 0xb0bd, 0xb0af, 0xb0b0, 0xb3c8, 0xd85e, 0xd857, + 0xb3c5, 0xd85f, 0xd855, 0xd858, 0xb3c4, 0xd859, 0xb3c7, 0xd85d, + 0xd853, 0xd852, 0xb3c9, 0xb3ca, 0xb3c6, 0xb3cb, 0xd851, 0xd85c, + 0xd85a, 0xd854, 0xb3c3, 0xd856, 0xb6ca, 0xb6c4, 0xdcb7, 0xb6cd, + 0xdcbd, 0xdcc0, 0xb6c6, 0xb6c7, 0xdcba, 0xb6c5, 0xdcc3, 0xb6cb, + 0xdcc4, 0xdcbf, 0xb6cc, 0xdcb4, 0xb6c9, 0xdcb5, 0xdcbe, 0xdcbc, + 0xdcb8, 0xb6c8, 0xdcb6, 0xb6ce, 0xdcbb, 0xdcc2, 0xdcb9, 0xdcc1, + 0xb9b6, 0xb9b3, 0xb9b4, 0xe0f9, 0xe0f1, 0xb9b2, 0xb9af, 0xe0f2, + 0xb9b1, 0xe0f5, 0xe0f7, 0xe0fe, 0xe0fd, 0xe0f8, 0xb9ae, 0xe0f0, + 0xb9ac, 0xe0f3, 0xb9b7, 0xe0f6, 0xe0fa, 0xb9b0, 0xb9ad, 0xe0fc, + 0xe0fb, 0xb9b5, 0xe0f4, 0xbbf8, 0xe4ec, 0xe4e9, 0xbbf9, 0xbbf7, + 0xe4f0, 0xe4ed, 0xe4e6, 0xbbf6, 0xbbfa, 0xe4e7, 0xbbf5, 0xbbfd, + 0xe4ea, 0xe4eb, 0xbbfb, 0xbbfc, 0xe4f1, 0xe4ee, 0xe4ef, 0xbeaa, + 0xe8f8, 0xbea7, 0xe8f5, 0xbea9, 0xbeab, 0xe8f6, 0xbea8, 0xe8f7, + 0xe8f4, 0xc076, 0xecbd, 0xc077, 0xecbb, 0xecbc, 0xecba, 0xecb9, + 0xecbe, 0xc075, 0xefb8, 0xefb9, 0xe4e8, 0xefb7, 0xc078, 0xc35f, + 0xf1eb, 0xf1ec, 0xc4d7, 0xc4d8, 0xf5c1, 0xf5c0, 0xc56c, 0xc56b, + 0xf7d0, 0xa449, 0xa461, 0xa4b9, 0xa4b8, 0xa553, 0xa552, 0xa5fc, + 0xa5fb, 0xa5fd, 0xa5fa, 0xa74a, 0xa749, 0xa74b, 0xa8e0, 0xa8df, + 0xa8e1, 0xab5e, 0xa259, 0xd0de, 0xa25a, 0xb0c2, 0xa25c, 0xa25b, + 0xd860, 0xa25d, 0xb9b8, 0xa25e, 0xa44a, 0xa4ba, 0xa5fe, 0xa8e2, + 0xa44b, 0xa4bd, 0xa4bb, 0xa4bc, 0xa640, 0xa74c, 0xa8e4, 0xa8e3, + 0xa8e5, 0xaddd, 0xbeac, 0xc94e, 0xa554, 0xa555, 0xa641, 0xca6a, + 0xab60, 0xab5f, 0xd0e0, 0xd0df, 0xb0c3, 0xa4be, 0xc955, 0xcbcd, + 0xab61, 0xade0, 0xadde, 0xaddf, 0xbead, 0xa556, 0xa642, 0xc9bc, + 0xa74d, 0xa74e, 0xca6b, 0xcbce, 0xa8e6, 0xcbcf, 0xd0e2, 0xd0e3, + 0xade3, 0xd0e4, 0xd0e1, 0xade4, 0xade2, 0xade1, 0xd0e5, 0xd468, + 0xd861, 0xdcc5, 0xe140, 0xbbfe, 0xbeae, 0xe8f9, 0xa44c, 0xa45a, + 0xb0c4, 0xb3cd, 0xb9b9, 0xc942, 0xa4bf, 0xa559, 0xa557, 0xa558, + 0xa8e7, 0xa44d, 0xa44e, 0xa462, 0xa4c0, 0xa4c1, 0xa4c2, 0xc9be, + 0xa55a, 0xc96b, 0xa646, 0xc9bf, 0xa644, 0xa645, 0xc9bd, 0xa647, + 0xa643, 0xca6c, 0xaaec, 0xca6d, 0xca6e, 0xa750, 0xa74f, 0xa753, + 0xa751, 0xa752, 0xa8ed, 0xa8ec, 0xcbd4, 0xcbd1, 0xcbd2, 0xcbd0, + 0xa8ee, 0xa8ea, 0xa8e9, 0xa8eb, 0xa8e8, 0xa8ef, 0xab63, 0xcdf0, + 0xcbd3, 0xab68, 0xcdf1, 0xab64, 0xab67, 0xab66, 0xab65, 0xab62, + 0xd0e8, 0xade7, 0xd0eb, 0xade5, 0xd0e7, 0xade8, 0xade6, 0xade9, + 0xd0e9, 0xd0ea, 0xd0e6, 0xd0ec, 0xb3d1, 0xb0c5, 0xd469, 0xd46b, + 0xd46a, 0xd46c, 0xb0c6, 0xb3ce, 0xb3cf, 0xb3d0, 0xb6d0, 0xdcc7, + 0xdcc6, 0xdcc8, 0xdcc9, 0xb6d1, 0xb6cf, 0xe141, 0xe142, 0xb9bb, + 0xb9ba, 0xe35a, 0xbc40, 0xbc41, 0xbc42, 0xbc44, 0xe4f2, 0xe4f3, + 0xbc43, 0xbeaf, 0xbeb0, 0xf1ed, 0xf5c3, 0xf5c2, 0xf7d1, 0xa44f, + 0xa55c, 0xa55b, 0xa648, 0xc9c0, 0xa755, 0xa756, 0xa754, 0xa757, + 0xca6f, 0xca70, 0xa8f1, 0xcbd5, 0xa8f0, 0xcdf2, 0xab6c, 0xcdf3, + 0xab6b, 0xab69, 0xab6a, 0xd0ed, 0xb0c7, 0xd46e, 0xb0ca, 0xd46d, + 0xb1e5, 0xb0c9, 0xb0c8, 0xb3d4, 0xb3d3, 0xb3d2, 0xb6d2, 0xb6d5, + 0xb6d6, 0xb6d4, 0xb6d3, 0xe143, 0xe144, 0xe4f5, 0xbc45, 0xe4f4, + 0xbeb1, 0xecbf, 0xc079, 0xf1ee, 0xc455, 0xa463, 0xa4c3, 0xc956, + 0xa4c4, 0xa4c5, 0xa55d, 0xa55e, 0xa649, 0xca71, 0xcbd6, 0xcbd7, + 0xab6d, 0xd0ee, 0xb0cc, 0xb0cb, 0xd863, 0xd862, 0xa450, 0xa4c6, + 0xa55f, 0xb0cd, 0xc943, 0xc96c, 0xa560, 0xc9c2, 0xa64b, 0xa64a, + 0xc9c1, 0xa758, 0xadea, 0xd46f, 0xb6d7, 0xe145, 0xb9bc, 0xe8fa, + 0xf3fd, 0xa4c7, 0xcbd8, 0xcdf4, 0xb0d0, 0xb0ce, 0xb0cf, 0xa451, + 0xa464, 0xa2cd, 0xa4ca, 0xa4c9, 0xa4c8, 0xa563, 0xa562, 0xc96d, + 0xc9c3, 0xa8f5, 0xa8f2, 0xa8f4, 0xa8f3, 0xab6e, 0xb3d5, 0xa452, + 0xa4cb, 0xa565, 0xa564, 0xca72, 0xa8f6, 0xc957, 0xa567, 0xa566, + 0xa64c, 0xa64d, 0xca73, 0xa759, 0xa75a, 0xa8f7, 0xa8f8, 0xa8f9, + 0xab6f, 0xcdf5, 0xadeb, 0xc944, 0xa4cc, 0xc9c4, 0xca74, 0xca75, + 0xcbd9, 0xcbda, 0xcdf7, 0xcdf6, 0xcdf9, 0xcdf8, 0xab70, 0xd470, + 0xaded, 0xd0ef, 0xadec, 0xd864, 0xb3d6, 0xd865, 0xe146, 0xb9bd, + 0xbc46, 0xf1ef, 0xc958, 0xa568, 0xb0d1, 0xa453, 0xa465, 0xa4ce, + 0xa4cd, 0xa4cf, 0xa8fb, 0xa8fa, 0xa8fc, 0xab71, 0xadee, 0xe8fb, + 0xc24f, 0xa466, 0xa56a, 0xa579, 0xa574, 0xa56f, 0xa56e, 0xa575, + 0xa573, 0xa56c, 0xa57a, 0xa56d, 0xa569, 0xa578, 0xa577, 0xa576, + 0xa56b, 0xa572, 0xa571, 0xa57b, 0xa570, 0xa653, 0xa659, 0xa655, + 0xa65b, 0xc9c5, 0xa658, 0xa64e, 0xa651, 0xa654, 0xa650, 0xa657, + 0xa65a, 0xa64f, 0xa652, 0xa656, 0xa65c, 0xca7e, 0xca7b, 0xa767, + 0xca7c, 0xa75b, 0xa75d, 0xa775, 0xa770, 0xcaa5, 0xca7d, 0xa75f, + 0xa761, 0xcaa4, 0xa768, 0xca78, 0xa774, 0xa776, 0xa75c, 0xa76d, + 0xca76, 0xa773, 0xa764, 0xa76e, 0xa76f, 0xca77, 0xa76c, 0xa76a, + 0xa76b, 0xa771, 0xcaa1, 0xa75e, 0xa772, 0xcaa3, 0xa766, 0xa763, + 0xca7a, 0xa762, 0xcaa6, 0xa765, 0xa769, 0xa760, 0xcaa2, 0xca79, + 0xcbeb, 0xcbea, 0xa94f, 0xcbed, 0xcbef, 0xcbe4, 0xcbe7, 0xcbee, + 0xa950, 0xcbe1, 0xcbe5, 0xcbe9, 0xce49, 0xa94b, 0xce4d, 0xa8fd, + 0xcbe6, 0xa8fe, 0xa94c, 0xa945, 0xa941, 0xcbe2, 0xa944, 0xa949, + 0xa952, 0xcbe3, 0xcbdc, 0xa943, 0xcbdd, 0xcbdf, 0xa946, 0xa948, + 0xcbdb, 0xcbe0, 0xa951, 0xa94d, 0xcbe8, 0xa953, 0xa94a, 0xcbde, + 0xa947, 0xa942, 0xa940, 0xcbec, 0xa94e, 0xce48, 0xcdfb, 0xce4b, + 0xcdfd, 0xab78, 0xaba8, 0xab74, 0xaba7, 0xab7d, 0xaba4, 0xab72, + 0xcdfc, 0xce43, 0xaba3, 0xce4f, 0xaba5, 0xab79, 0xce45, 0xce42, + 0xab77, 0xcdfa, 0xaba6, 0xce4a, 0xab7c, 0xce4c, 0xaba9, 0xab73, + 0xab7e, 0xab7b, 0xce40, 0xaba1, 0xce46, 0xce47, 0xab7a, 0xaba2, + 0xab76, 0xab75, 0xcdfe, 0xce44, 0xce4e, 0xd144, 0xadfb, 0xd0f1, + 0xd0f6, 0xadf4, 0xae40, 0xd0f4, 0xadef, 0xadf9, 0xadfe, 0xd0fb, + 0xadfa, 0xadfd, 0xd0fe, 0xadf5, 0xd0f5, 0xd142, 0xd143, 0xadf7, + 0xd141, 0xadf3, 0xae43, 0xd0f8, 0xadf1, 0xd146, 0xd0f9, 0xd0fd, + 0xadf6, 0xae42, 0xd0fa, 0xadfc, 0xd140, 0xd147, 0xd4a1, 0xd145, + 0xae44, 0xadf0, 0xd0fc, 0xd0f3, 0xadf8, 0xd0f2, 0xd0f7, 0xd0f0, + 0xae41, 0xd477, 0xb0e4, 0xd4a7, 0xb0e2, 0xb0df, 0xd47c, 0xb0db, + 0xd4a2, 0xb0e6, 0xd476, 0xd47b, 0xd47a, 0xadf2, 0xb0e1, 0xd4a5, + 0xd4a8, 0xd473, 0xb3e8, 0xd4a9, 0xb0e7, 0xb0d9, 0xb0d6, 0xd47e, + 0xb0d3, 0xd4a6, 0xb0da, 0xd4aa, 0xd474, 0xd4a4, 0xb0dd, 0xd475, + 0xd478, 0xd47d, 0xb0de, 0xb0dc, 0xb0e8, 0xb0e3, 0xb0d7, 0xb1d2, + 0xb0d8, 0xd479, 0xb0e5, 0xb0e0, 0xd4a3, 0xb0d5, 0xb0d4, 0xd471, + 0xd472, 0xd86a, 0xb3d7, 0xb3da, 0xd875, 0xb3ee, 0xd878, 0xb3d8, + 0xd871, 0xb3de, 0xb3e4, 0xb5bd, 0xb3e2, 0xd86e, 0xb3ef, 0xb3db, + 0xb3e3, 0xd876, 0xdcd7, 0xd87b, 0xd86f, 0xd866, 0xd873, 0xd86d, + 0xb3e1, 0xd879, 0xb3dd, 0xb3f1, 0xb3ea, 0xb3df, 0xb3dc, 0xb3e7, + 0xd87a, 0xd86c, 0xd872, 0xd874, 0xd868, 0xd877, 0xb3d9, 0xd867, + 0xb3e0, 0xb3f0, 0xb3ec, 0xd869, 0xb3e6, 0xb3ed, 0xb3e9, 0xb3e5, + 0xd870, 0xb3eb, 0xdcd5, 0xdcd1, 0xdce0, 0xdcca, 0xdcd3, 0xb6e5, + 0xb6e6, 0xb6de, 0xdcdc, 0xb6e8, 0xdccf, 0xdcce, 0xdccc, 0xdcde, + 0xb6dc, 0xdcd8, 0xdccd, 0xb6df, 0xdcd6, 0xb6da, 0xdcd2, 0xdcd9, + 0xdcdb, 0xdcdf, 0xb6e3, 0xdccb, 0xb6dd, 0xdcd0, 0xb6d8, 0xb6e4, + 0xdcda, 0xb6e0, 0xb6e1, 0xb6e7, 0xb6db, 0xa25f, 0xb6d9, 0xdcd4, + 0xb6e2, 0xdcdd, 0xb9cd, 0xb9c8, 0xe155, 0xe151, 0xe14b, 0xb9c2, + 0xb9be, 0xe154, 0xb9bf, 0xe14e, 0xe150, 0xe153, 0xb9c4, 0xb9cb, + 0xb9c5, 0xe149, 0xb9c6, 0xb9c7, 0xe14c, 0xb9cc, 0xe14a, 0xe14f, + 0xb9c3, 0xe148, 0xb9c9, 0xb9c1, 0xb9c0, 0xe14d, 0xe152, 0xb9ca, + 0xe147, 0xbc4d, 0xe547, 0xe544, 0xbc47, 0xbc53, 0xbc54, 0xbc4a, + 0xe542, 0xbc4c, 0xe4f9, 0xbc52, 0xe546, 0xbc49, 0xe548, 0xbc48, + 0xe543, 0xe545, 0xbc4b, 0xe541, 0xe4fa, 0xe4f7, 0xd86b, 0xe4fd, + 0xe4f6, 0xe4fc, 0xe4fb, 0xe4f8, 0xbc4f, 0xbc4e, 0xbc50, 0xe4fe, + 0xbeb2, 0xe540, 0xe945, 0xe8fd, 0xbebe, 0xe942, 0xbeb6, 0xbeba, + 0xe941, 0xbeb9, 0xbeb5, 0xbeb8, 0xbeb3, 0xbebd, 0xe943, 0xe8fe, + 0xbebc, 0xe8fc, 0xbebb, 0xe944, 0xe940, 0xbc51, 0xbebf, 0xe946, + 0xbeb7, 0xbeb4, 0xecc6, 0xecc8, 0xc07b, 0xecc9, 0xecc7, 0xecc5, + 0xecc4, 0xc07d, 0xecc3, 0xc07e, 0xecc1, 0xecc2, 0xc07a, 0xc0a1, + 0xc07c, 0xecc0, 0xc250, 0xefbc, 0xefba, 0xefbf, 0xefbd, 0xefbb, + 0xefbe, 0xc360, 0xf1f2, 0xf1f3, 0xc456, 0xf1f4, 0xf1f0, 0xf1f5, + 0xf1f1, 0xc251, 0xf3fe, 0xf441, 0xc459, 0xf440, 0xc458, 0xc457, + 0xc45a, 0xf5c5, 0xf5c6, 0xc4da, 0xc4d9, 0xc4db, 0xf5c4, 0xf6d8, + 0xf6d7, 0xc56d, 0xc56f, 0xc56e, 0xf6d9, 0xc5c8, 0xf8a6, 0xc5f1, + 0xf8a5, 0xf8ee, 0xc949, 0xa57d, 0xa57c, 0xa65f, 0xa65e, 0xc9c7, + 0xa65d, 0xc9c6, 0xa779, 0xcaa9, 0xcaa8, 0xa777, 0xa77a, 0xcaa7, + 0xa778, 0xcbf0, 0xcbf1, 0xa954, 0xabaa, 0xd148, 0xd149, 0xae45, + 0xae46, 0xd4ac, 0xb0e9, 0xb0eb, 0xd4ab, 0xb0ea, 0xd87c, 0xb3f2, + 0xb6e9, 0xb6ea, 0xdce1, 0xb9cf, 0xb9ce, 0xe549, 0xe948, 0xe947, + 0xf96b, 0xa467, 0xc959, 0xc96e, 0xc96f, 0xa662, 0xa666, 0xc9c9, + 0xa664, 0xa663, 0xc9c8, 0xa665, 0xa661, 0xa660, 0xc9ca, 0xa7a6, + 0xa7a3, 0xa77d, 0xcaaa, 0xcaab, 0xa7a1, 0xcaad, 0xa77b, 0xcaae, + 0xcaac, 0xa77e, 0xa7a2, 0xa7a5, 0xa7a4, 0xa77c, 0xcaaf, 0xa959, + 0xcbfe, 0xa95b, 0xa95a, 0xcc40, 0xa958, 0xa957, 0xcbf5, 0xcbf4, + 0xcbf2, 0xcbf7, 0xcbf6, 0xcbf3, 0xcbfc, 0xcbfd, 0xcbfa, 0xcbf8, + 0xa956, 0xcbfb, 0xa95c, 0xcc41, 0xcbf9, 0xabab, 0xa955, 0xabac, + 0xce54, 0xce5a, 0xabb2, 0xce58, 0xce5e, 0xce55, 0xce59, 0xce5b, + 0xce5d, 0xce57, 0xce56, 0xce51, 0xce52, 0xabad, 0xabaf, 0xabae, + 0xce53, 0xce5c, 0xabb1, 0xce50, 0xd153, 0xd152, 0xd157, 0xd14e, + 0xd151, 0xd150, 0xd154, 0xd158, 0xae47, 0xae4a, 0xd14f, 0xd155, + 0xae49, 0xd14a, 0xabb0, 0xd4ba, 0xd156, 0xd14d, 0xae48, 0xd14c, + 0xd4b1, 0xb0ec, 0xb0f0, 0xd4c1, 0xd4af, 0xd4bd, 0xb0f1, 0xd4bf, + 0xd4c5, 0xd4c9, 0xd4c0, 0xd4b4, 0xd4bc, 0xd4ca, 0xd4c8, 0xd4be, + 0xd4b9, 0xd4b2, 0xd8a6, 0xd4b0, 0xb0f5, 0xd4b7, 0xb0f6, 0xb0f2, + 0xd4ad, 0xd4c3, 0xd4b5, 0xd4b3, 0xd4c6, 0xb0f3, 0xd4cc, 0xb0ed, + 0xb0ef, 0xd4bb, 0xd4b6, 0xae4b, 0xb0ee, 0xd4b8, 0xd4c7, 0xd4cb, + 0xd4c2, 0xd4c4, 0xd4ae, 0xd8a1, 0xd8aa, 0xd8a9, 0xb3fa, 0xd8a2, + 0xb3fb, 0xb3f9, 0xd8a4, 0xb3f6, 0xd8a8, 0xd8a3, 0xd8a5, 0xd87d, + 0xb3f4, 0xd8b2, 0xd8b1, 0xd8ae, 0xb3f3, 0xb3f7, 0xb3f8, 0xd14b, + 0xd8ab, 0xb3f5, 0xb0f4, 0xd8ad, 0xd87e, 0xd8b0, 0xd8af, 0xd8b3, + 0xdcef, 0xd8ac, 0xd8a7, 0xdce7, 0xb6f4, 0xb6f7, 0xb6f2, 0xdce6, + 0xdcea, 0xdce5, 0xb6ec, 0xb6f6, 0xdce2, 0xb6f0, 0xdce9, 0xb6ee, + 0xb6ed, 0xdcec, 0xb6ef, 0xdcee, 0xdceb, 0xb6eb, 0xb6f5, 0xdcf0, + 0xdce4, 0xdced, 0xdce3, 0xb6f1, 0xb6f3, 0xdce8, 0xdcf1, 0xe15d, + 0xb9d0, 0xe163, 0xb9d5, 0xe15f, 0xe166, 0xe157, 0xb9d7, 0xb9d1, + 0xe15c, 0xbc55, 0xe15b, 0xe164, 0xb9d2, 0xb9d6, 0xe15a, 0xe160, + 0xe165, 0xe156, 0xb9d4, 0xe15e, 0xe162, 0xe168, 0xe158, 0xe161, + 0xb9d3, 0xe167, 0xe159, 0xbc59, 0xe54b, 0xbc57, 0xbc56, 0xe54d, + 0xe552, 0xe54e, 0xe551, 0xbc5c, 0xbea5, 0xbc5b, 0xe54a, 0xe550, + 0xbc5a, 0xe54f, 0xe54c, 0xbc58, 0xe94d, 0xe94f, 0xe94a, 0xbec1, + 0xe94c, 0xbec0, 0xe94e, 0xbec3, 0xe950, 0xbec2, 0xe949, 0xe94b, + 0xc0a5, 0xeccc, 0xc0a4, 0xeccd, 0xc0a3, 0xeccb, 0xc0a2, 0xecca, + 0xc253, 0xc252, 0xf1f6, 0xf1f8, 0xf1f7, 0xc361, 0xc362, 0xc363, + 0xf442, 0xc45b, 0xf7d3, 0xf7d2, 0xc5f2, 0xa468, 0xa4d0, 0xa7a7, + 0xce5f, 0xb3fc, 0xb3fd, 0xdcf2, 0xb9d8, 0xe169, 0xe553, 0xc95a, + 0xcab0, 0xcc42, 0xce60, 0xd159, 0xae4c, 0xf1f9, 0xc4dc, 0xa469, + 0xa57e, 0xc970, 0xa667, 0xa668, 0xa95d, 0xb0f7, 0xb9da, 0xb9db, + 0xb9d9, 0xa46a, 0xa4d1, 0xa4d3, 0xa4d2, 0xc95b, 0xa4d4, 0xa5a1, + 0xc971, 0xa5a2, 0xa669, 0xa66a, 0xc9cb, 0xa7a8, 0xcab1, 0xa961, + 0xcc43, 0xa95f, 0xa960, 0xa95e, 0xd15a, 0xabb6, 0xabb5, 0xabb7, + 0xabb4, 0xce61, 0xa962, 0xabb3, 0xae4d, 0xae4e, 0xae4f, 0xd4cd, + 0xb3fe, 0xd8b4, 0xb0f8, 0xb6f8, 0xb9dd, 0xb9dc, 0xe16a, 0xbc5d, + 0xbec4, 0xefc0, 0xf6da, 0xf7d4, 0xa46b, 0xa5a3, 0xa5a4, 0xc9d1, + 0xa66c, 0xa66f, 0xc9cf, 0xc9cd, 0xa66e, 0xc9d0, 0xc9d2, 0xc9cc, + 0xa671, 0xa670, 0xa66d, 0xa66b, 0xc9ce, 0xa7b3, 0xa7b0, 0xcab6, + 0xcab9, 0xcab8, 0xa7aa, 0xa7b2, 0xa7af, 0xcab5, 0xcab3, 0xa7ae, + 0xa7a9, 0xa7ac, 0xcab4, 0xcabb, 0xcab7, 0xa7ad, 0xa7b1, 0xa7b4, + 0xcab2, 0xcaba, 0xa7ab, 0xa967, 0xa96f, 0xcc4f, 0xcc48, 0xa970, + 0xcc53, 0xcc44, 0xcc4b, 0xa966, 0xcc45, 0xa964, 0xcc4c, 0xcc50, + 0xa963, 0xcc51, 0xcc4a, 0xcc4d, 0xa972, 0xa969, 0xcc54, 0xcc52, + 0xa96e, 0xa96c, 0xcc49, 0xa96b, 0xcc47, 0xcc46, 0xa96a, 0xa968, + 0xa971, 0xa96d, 0xa965, 0xcc4e, 0xabb9, 0xabc0, 0xce6f, 0xabb8, + 0xce67, 0xce63, 0xce73, 0xce62, 0xabbb, 0xce6c, 0xabbe, 0xabc1, + 0xabbc, 0xce70, 0xabbf, 0xae56, 0xce76, 0xce64, 0xce66, 0xce6d, + 0xce71, 0xce75, 0xce72, 0xce6b, 0xce6e, 0xce68, 0xabc3, 0xce6a, + 0xce69, 0xce74, 0xabba, 0xce65, 0xabc2, 0xabbd, 0xae5c, 0xd162, + 0xae5b, 0xd160, 0xae50, 0xae55, 0xd15f, 0xd15c, 0xd161, 0xae51, + 0xd15b, 0xae54, 0xae52, 0xd163, 0xae53, 0xae57, 0xae58, 0xae5a, + 0xae59, 0xd15d, 0xd15e, 0xd164, 0xd4d4, 0xb0f9, 0xd8c2, 0xd4d3, + 0xd4e6, 0xb140, 0xd4e4, 0xb0fe, 0xb0fa, 0xd4ed, 0xd4dd, 0xd4e0, + 0xb143, 0xd4ea, 0xd4e2, 0xb0fb, 0xb144, 0xd4e7, 0xd4e5, 0xd4d6, + 0xd4eb, 0xd4df, 0xd4da, 0xd4d0, 0xd4ec, 0xd4dc, 0xd4cf, 0xb142, + 0xd4e1, 0xd4ee, 0xd4de, 0xd4d2, 0xd4d7, 0xd4ce, 0xb141, 0xd4db, + 0xd4d8, 0xb0fc, 0xd4d1, 0xd4e9, 0xb0fd, 0xd4d9, 0xd4d5, 0xd4e8, + 0xb440, 0xd8bb, 0xd8b8, 0xd8c9, 0xd8bd, 0xd8ca, 0xb442, 0xd8c6, + 0xd8c3, 0xd8c4, 0xd8c7, 0xd8cb, 0xd4e3, 0xd8cd, 0xdd47, 0xb443, + 0xd8ce, 0xd8b6, 0xd8c0, 0xd8c5, 0xb441, 0xb444, 0xd8cc, 0xd8cf, + 0xd8ba, 0xd8b7, 0xd8b9, 0xd8be, 0xd8bc, 0xb445, 0xd8c8, 0xd8bf, + 0xd8c1, 0xd8b5, 0xdcfa, 0xdcf8, 0xb742, 0xb740, 0xdd43, 0xdcf9, + 0xdd44, 0xdd40, 0xdcf7, 0xdd46, 0xdcf6, 0xdcfd, 0xb6fe, 0xb6fd, + 0xb6fc, 0xdcfb, 0xdd41, 0xb6f9, 0xb741, 0xdcf4, 0xdcfe, 0xdcf3, + 0xdcfc, 0xb6fa, 0xdd42, 0xdcf5, 0xb6fb, 0xdd45, 0xe16e, 0xb9e2, + 0xb9e1, 0xb9e3, 0xe17a, 0xe170, 0xe176, 0xe16b, 0xe179, 0xe178, + 0xe17c, 0xe175, 0xb9de, 0xe174, 0xb9e4, 0xe16d, 0xb9df, 0xe17b, + 0xb9e0, 0xe16f, 0xe172, 0xe177, 0xe171, 0xe16c, 0xe173, 0xe555, + 0xbc61, 0xe558, 0xe557, 0xe55a, 0xe55c, 0xbc5f, 0xe556, 0xe554, + 0xe55d, 0xe55b, 0xe559, 0xe55f, 0xe55e, 0xbc63, 0xbc5e, 0xbc60, + 0xbc62, 0xe560, 0xe957, 0xe956, 0xe955, 0xe958, 0xe951, 0xe952, + 0xe95a, 0xe953, 0xbec5, 0xe95c, 0xe95b, 0xe954, 0xecd1, 0xc0a8, + 0xeccf, 0xecd4, 0xecd3, 0xe959, 0xc0a7, 0xecd2, 0xecce, 0xecd6, + 0xecd5, 0xc0a6, 0xecd0, 0xbec6, 0xc254, 0xefc1, 0xf1fa, 0xf1fb, + 0xf1fc, 0xc45c, 0xc45d, 0xf443, 0xf5c8, 0xf5c7, 0xf6db, 0xf6dc, + 0xf7d5, 0xf8a7, 0xa46c, 0xa46d, 0xa46e, 0xa4d5, 0xa5a5, 0xc9d3, + 0xa672, 0xa673, 0xa7b7, 0xa7b8, 0xa7b6, 0xa7b5, 0xa973, 0xcc55, + 0xa975, 0xa974, 0xcc56, 0xabc4, 0xae5d, 0xd165, 0xd4f0, 0xb145, + 0xb447, 0xd4ef, 0xb446, 0xb9e5, 0xe17d, 0xbec7, 0xc0a9, 0xecd7, + 0xc45e, 0xc570, 0xc972, 0xa5a6, 0xc973, 0xa676, 0xa674, 0xa675, + 0xa677, 0xa7ba, 0xa7b9, 0xcabc, 0xa7bb, 0xcabd, 0xcc57, 0xcc58, + 0xa976, 0xa978, 0xa97a, 0xa977, 0xa97b, 0xa979, 0xabc8, 0xabc5, + 0xabc7, 0xabc9, 0xabc6, 0xd166, 0xce77, 0xd168, 0xd167, 0xae63, + 0xae5f, 0xae60, 0xae62, 0xae64, 0xae61, 0xae66, 0xae65, 0xb14a, + 0xd4f2, 0xd4f1, 0xb149, 0xb148, 0xb147, 0xb14b, 0xb146, 0xd8d5, + 0xd8d2, 0xb449, 0xd8d1, 0xd8d6, 0xb44b, 0xd8d4, 0xb448, 0xb44a, + 0xd8d3, 0xdd48, 0xdd49, 0xdd4a, 0xb9e6, 0xb9ee, 0xe17e, 0xb9e8, + 0xb9ec, 0xe1a1, 0xb9ed, 0xb9e9, 0xb9ea, 0xb9e7, 0xb9eb, 0xbc66, + 0xd8d0, 0xbc67, 0xbc65, 0xbc64, 0xe95d, 0xbec8, 0xecd8, 0xecd9, + 0xc364, 0xc45f, 0xa46f, 0xa678, 0xabca, 0xd169, 0xae67, 0xb14e, + 0xb14d, 0xb14c, 0xb44c, 0xb44d, 0xd8d7, 0xb9ef, 0xbec9, 0xa470, + 0xc95c, 0xa4d6, 0xc974, 0xc9d4, 0xa679, 0xa97c, 0xdd4b, 0xa471, + 0xa4d7, 0xc9d5, 0xcabe, 0xcabf, 0xa7bc, 0xd8d8, 0xb44e, 0xdd4c, + 0xc0aa, 0xa472, 0xa4a8, 0xa4d8, 0xc975, 0xa5a7, 0xa7c0, 0xa7bf, + 0xa7bd, 0xa7be, 0xcc59, 0xa97e, 0xa9a1, 0xcc5a, 0xa97d, 0xabce, + 0xce78, 0xabcd, 0xabcb, 0xabcc, 0xae6a, 0xae68, 0xd16b, 0xae69, + 0xd16a, 0xae5e, 0xd4f3, 0xb150, 0xb151, 0xb14f, 0xb9f0, 0xe1a2, + 0xbc68, 0xbc69, 0xe561, 0xc0ab, 0xefc2, 0xefc3, 0xc4dd, 0xf8a8, + 0xc94b, 0xa4d9, 0xa473, 0xc977, 0xc976, 0xa67a, 0xc9d7, 0xc9d8, + 0xc9d6, 0xc9d9, 0xcac7, 0xcac2, 0xcac4, 0xcac6, 0xcac3, 0xa7c4, + 0xcac0, 0xcac1, 0xa7c1, 0xa7c2, 0xcac5, 0xcac8, 0xa7c3, 0xcac9, + 0xcc68, 0xcc62, 0xcc5d, 0xa9a3, 0xcc65, 0xcc63, 0xcc5c, 0xcc69, + 0xcc6c, 0xcc67, 0xcc60, 0xa9a5, 0xcc66, 0xa9a6, 0xcc61, 0xcc64, + 0xcc5b, 0xcc5f, 0xcc6b, 0xa9a7, 0xa9a8, 0xcc5e, 0xcc6a, 0xa9a2, + 0xa9a4, 0xceab, 0xcea4, 0xceaa, 0xcea3, 0xcea5, 0xce7d, 0xce7b, + 0xceac, 0xcea9, 0xce79, 0xabd0, 0xcea7, 0xcea8, 0xcea6, 0xce7c, + 0xce7a, 0xabcf, 0xcea2, 0xce7e, 0xcea1, 0xcead, 0xae6f, 0xae6e, + 0xd16c, 0xae6b, 0xd16e, 0xae70, 0xd16f, 0xae73, 0xae71, 0xd170, + 0xceae, 0xd172, 0xae6d, 0xae6c, 0xd16d, 0xd171, 0xae72, 0xb153, + 0xb152, 0xd4f5, 0xd4f9, 0xd4fb, 0xb154, 0xd4fe, 0xb158, 0xd541, + 0xb15a, 0xb156, 0xb15e, 0xb15b, 0xd4f7, 0xb155, 0xd4f6, 0xd4f4, + 0xd543, 0xd4f8, 0xb157, 0xd542, 0xb15c, 0xd4fd, 0xd4fc, 0xb15d, + 0xd4fa, 0xb159, 0xd544, 0xd540, 0xd8e7, 0xd8ee, 0xd8e3, 0xb451, + 0xd8df, 0xd8ef, 0xd8d9, 0xd8ec, 0xd8ea, 0xd8e4, 0xd8ed, 0xd8e6, + 0xd8de, 0xd8f0, 0xd8dc, 0xd8e9, 0xd8da, 0xd8f1, 0xb452, 0xd8eb, + 0xdd4f, 0xd8dd, 0xb44f, 0xd8e1, 0xb450, 0xd8e0, 0xd8e5, 0xd8e2, + 0xd8e8, 0xdd53, 0xdd56, 0xdd4e, 0xdd50, 0xdd55, 0xdd54, 0xb743, + 0xd8db, 0xdd52, 0xb744, 0xdd4d, 0xdd51, 0xe1a9, 0xe1b0, 0xe1a7, + 0xe1ae, 0xe1a5, 0xe1ad, 0xe1b1, 0xe1a4, 0xe1a8, 0xe1a3, 0xb9f1, + 0xe1a6, 0xb9f2, 0xe1ac, 0xe1ab, 0xe1aa, 0xe1af, 0xe565, 0xe567, + 0xbc6b, 0xe568, 0xe563, 0xe562, 0xe56c, 0xe56a, 0xbc6a, 0xe56d, + 0xe564, 0xe569, 0xe56b, 0xe566, 0xe961, 0xe966, 0xe960, 0xe965, + 0xe95e, 0xe968, 0xe964, 0xe969, 0xe963, 0xe95f, 0xe967, 0xe96a, + 0xe962, 0xecda, 0xc0af, 0xc0ad, 0xc0ac, 0xc0ae, 0xefc4, 0xf172, + 0xf1fd, 0xf444, 0xf445, 0xc460, 0xf5c9, 0xc4de, 0xf5ca, 0xf6de, + 0xc572, 0xc571, 0xf6dd, 0xc5c9, 0xf7d6, 0xa474, 0xa67b, 0xc9da, + 0xcaca, 0xa8b5, 0xb15f, 0xa475, 0xa5aa, 0xa5a9, 0xa5a8, 0xa7c5, + 0xae74, 0xdd57, 0xa476, 0xa477, 0xa478, 0xa4da, 0xabd1, 0xceaf, + 0xb453, 0xa479, 0xc95d, 0xa5ab, 0xa5ac, 0xc978, 0xa67c, 0xcacb, + 0xa7c6, 0xcacc, 0xa9ae, 0xcc6e, 0xa9ac, 0xa9ab, 0xcc6d, 0xa9a9, + 0xcc6f, 0xa9aa, 0xa9ad, 0xabd2, 0xabd4, 0xceb3, 0xceb0, 0xceb1, + 0xceb2, 0xceb4, 0xabd3, 0xd174, 0xd173, 0xae76, 0xae75, 0xb162, + 0xd546, 0xb161, 0xb163, 0xb160, 0xb455, 0xd545, 0xb456, 0xd8f3, + 0xb457, 0xd8f2, 0xb454, 0xdd5a, 0xdd5c, 0xb745, 0xdd5b, 0xdd59, + 0xdd58, 0xe1b4, 0xb9f7, 0xb9f5, 0xb9f6, 0xe1b2, 0xe1b3, 0xb9f3, + 0xe571, 0xe56f, 0xbc6d, 0xe570, 0xbc6e, 0xbc6c, 0xb9f4, 0xe96d, + 0xe96b, 0xe96c, 0xe56e, 0xecdc, 0xc0b0, 0xecdb, 0xefc5, 0xefc6, + 0xe96e, 0xf1fe, 0xa47a, 0xa5ad, 0xa67e, 0xc9db, 0xa67d, 0xa9af, + 0xb746, 0xa4db, 0xa5ae, 0xabd5, 0xb458, 0xc979, 0xc97a, 0xc9dc, + 0xa7c8, 0xcad0, 0xcace, 0xa7c9, 0xcacd, 0xcacf, 0xcad1, 0xa7c7, + 0xa9b3, 0xa9b4, 0xa9b1, 0xa9b0, 0xceb8, 0xa9b2, 0xabd6, 0xceb7, + 0xceb9, 0xceb6, 0xceba, 0xabd7, 0xae79, 0xd175, 0xd177, 0xae77, + 0xd178, 0xae78, 0xd176, 0xceb5, 0xd547, 0xd54a, 0xd54b, 0xd548, + 0xb167, 0xb166, 0xb164, 0xb165, 0xd549, 0xb168, 0xb45a, 0xb45b, + 0xb45c, 0xdd5d, 0xdd5f, 0xdd61, 0xb748, 0xb747, 0xb459, 0xdd60, + 0xdd5e, 0xe1b8, 0xe1b6, 0xe1bc, 0xb9f8, 0xe1bd, 0xe1ba, 0xb9f9, + 0xe1b7, 0xe1b5, 0xe1bb, 0xbc70, 0xe573, 0xe1b9, 0xbc72, 0xe574, + 0xbc71, 0xbc74, 0xe575, 0xbc6f, 0xbc73, 0xe973, 0xe971, 0xe970, + 0xe972, 0xe96f, 0xc366, 0xf446, 0xf447, 0xf5cb, 0xf6df, 0xc655, + 0xa9b5, 0xa7ca, 0xabd8, 0xa47b, 0xa4dc, 0xa5af, 0xc9dd, 0xa7cb, + 0xcad2, 0xcebb, 0xabd9, 0xb9fa, 0xa47c, 0xa6a1, 0xb749, 0xa47d, + 0xa4dd, 0xa4de, 0xa5b1, 0xa5b0, 0xc9de, 0xa6a2, 0xcad3, 0xa7cc, + 0xcc71, 0xcc72, 0xcc73, 0xa9b6, 0xa9b7, 0xcc70, 0xa9b8, 0xabda, + 0xcebc, 0xd17a, 0xae7a, 0xd179, 0xb169, 0xd54c, 0xb16a, 0xd54d, + 0xb45d, 0xdd62, 0xe1bf, 0xe1be, 0xb9fb, 0xbc75, 0xe576, 0xbeca, + 0xe974, 0xc0b1, 0xc573, 0xf7d8, 0xcc74, 0xcebd, 0xb16b, 0xd8f4, + 0xb74a, 0xc255, 0xa7ce, 0xa7cd, 0xabdb, 0xd17b, 0xb16d, 0xb343, + 0xb16e, 0xb16c, 0xb45e, 0xe1c0, 0xb9fc, 0xbc76, 0xc94c, 0xc9df, + 0xcad5, 0xa7cf, 0xcad4, 0xa7d0, 0xa9bc, 0xcc77, 0xcc76, 0xa9bb, + 0xa9b9, 0xa9ba, 0xcc75, 0xabdd, 0xcebe, 0xabe0, 0xabdc, 0xabe2, + 0xabde, 0xabdf, 0xabe1, 0xae7d, 0xae7c, 0xae7b, 0xd54f, 0xb16f, + 0xb172, 0xb170, 0xd54e, 0xb175, 0xb171, 0xd550, 0xb174, 0xb173, + 0xd8f6, 0xd8f5, 0xb461, 0xb45f, 0xb460, 0xd8f7, 0xb74b, 0xdd64, + 0xb74c, 0xdd63, 0xe577, 0xbc78, 0xe1c1, 0xbc77, 0xb9fd, 0xecde, + 0xe975, 0xc0b2, 0xecdd, 0xf240, 0xf448, 0xf449, 0xa4df, 0xa5b2, + 0xc97b, 0xa7d2, 0xa7d4, 0xc9e2, 0xcad8, 0xcad7, 0xcad6, 0xc9e1, + 0xc9e0, 0xa6a4, 0xa7d3, 0xa7d1, 0xa6a3, 0xa9bd, 0xcc78, 0xa9be, + 0xcadd, 0xcadf, 0xcade, 0xcc79, 0xcada, 0xa7d8, 0xa7d6, 0xcad9, + 0xcadb, 0xcae1, 0xa7d5, 0xcadc, 0xcae5, 0xa9c0, 0xcae2, 0xa7d7, + 0xcae0, 0xcae3, 0xa9bf, 0xa9c1, 0xcae4, 0xccaf, 0xcca2, 0xcc7e, + 0xccae, 0xcca9, 0xabe7, 0xa9c2, 0xccaa, 0xccad, 0xabe3, 0xccac, + 0xa9c3, 0xa9c8, 0xa9c6, 0xcca3, 0xcc7c, 0xcca5, 0xa9cd, 0xccb0, + 0xabe4, 0xcca6, 0xabe5, 0xa9c9, 0xcca8, 0xcecd, 0xabe6, 0xcc7b, + 0xa9ca, 0xabe8, 0xa9cb, 0xa9c7, 0xa9cc, 0xcca7, 0xcc7a, 0xccab, + 0xa9c4, 0xcc7d, 0xcca4, 0xcca1, 0xa9c5, 0xcebf, 0xcec0, 0xceca, + 0xd1a1, 0xcecb, 0xabee, 0xcece, 0xcec4, 0xabed, 0xcec6, 0xcec7, + 0xcec9, 0xabe9, 0xaea3, 0xcec5, 0xcec1, 0xaea4, 0xcecf, 0xae7e, + 0xd17d, 0xcec8, 0xd17c, 0xcec3, 0xcecc, 0xabec, 0xaea1, 0xabf2, + 0xaea2, 0xced0, 0xd17e, 0xabeb, 0xaea6, 0xabf1, 0xabf0, 0xabef, + 0xaea5, 0xced1, 0xaea7, 0xabea, 0xcec2, 0xb176, 0xd1a4, 0xd1a6, + 0xd1a8, 0xaea8, 0xaeae, 0xd553, 0xd1ac, 0xd1a3, 0xb178, 0xd551, + 0xaead, 0xaeab, 0xd1ae, 0xd552, 0xd1a5, 0xaeac, 0xd1a9, 0xaeaf, + 0xd1ab, 0xaeaa, 0xd1aa, 0xd1ad, 0xd1a7, 0xaea9, 0xb179, 0xd1a2, + 0xb177, 0xb17a, 0xd555, 0xd55e, 0xb464, 0xb17c, 0xb1a3, 0xb465, + 0xd560, 0xb1aa, 0xd8f9, 0xd556, 0xb1a2, 0xb1a5, 0xb17e, 0xd554, + 0xd562, 0xd565, 0xd949, 0xd563, 0xd8fd, 0xb1a1, 0xb1a8, 0xb1ac, + 0xd55d, 0xd8f8, 0xd561, 0xb17b, 0xd8fa, 0xd564, 0xd8fc, 0xd559, + 0xb462, 0xd557, 0xd558, 0xb1a7, 0xb1a6, 0xd55b, 0xb1ab, 0xd55f, + 0xb1a4, 0xd55c, 0xb1a9, 0xb466, 0xb463, 0xd8fb, 0xd55a, 0xb17d, + 0xb46b, 0xb46f, 0xd940, 0xb751, 0xb46d, 0xd944, 0xb471, 0xdd65, + 0xd946, 0xb753, 0xb469, 0xb46c, 0xd947, 0xd948, 0xd94e, 0xb473, + 0xb754, 0xd94a, 0xd94f, 0xd943, 0xb75e, 0xb755, 0xb472, 0xd941, + 0xd950, 0xb75d, 0xb470, 0xb74e, 0xd94d, 0xb474, 0xd945, 0xd8fe, + 0xb46a, 0xd942, 0xd94b, 0xb74d, 0xb752, 0xb467, 0xd94c, 0xb750, + 0xb468, 0xb75c, 0xe1c3, 0xdd70, 0xdd68, 0xe1c2, 0xdd6c, 0xdd6e, + 0xdd6b, 0xb75b, 0xdd6a, 0xb75f, 0xe1d2, 0xb75a, 0xba40, 0xdd71, + 0xe1c4, 0xb758, 0xdd69, 0xdd6d, 0xb9fe, 0xb74f, 0xdd66, 0xdd67, + 0xba41, 0xb757, 0xb759, 0xb756, 0xdd6f, 0xe1c8, 0xe1c9, 0xe1ce, + 0xbc7d, 0xe1d5, 0xba47, 0xba46, 0xe1d0, 0xbc7c, 0xe1c5, 0xba45, + 0xe1d4, 0xba43, 0xba44, 0xe1d1, 0xe5aa, 0xbc7a, 0xb46e, 0xe1d3, + 0xbca3, 0xe1cb, 0xbc7b, 0xbca2, 0xe1c6, 0xe1ca, 0xe1c7, 0xe1cd, + 0xba48, 0xbc79, 0xba42, 0xe57a, 0xe1cf, 0xbca1, 0xbca4, 0xe1cc, + 0xbc7e, 0xe579, 0xe57e, 0xbece, 0xe578, 0xe9a3, 0xe5a9, 0xbca8, + 0xbca6, 0xbecc, 0xe5a6, 0xe5a2, 0xbcac, 0xe978, 0xbcaa, 0xe5a1, + 0xe976, 0xe5a5, 0xe5a8, 0xe57d, 0xbcab, 0xbca5, 0xe977, 0xbecd, + 0xe5a7, 0xbca7, 0xbca9, 0xe5a4, 0xbcad, 0xe5a3, 0xe57c, 0xe57b, + 0xbecb, 0xe5ab, 0xe97a, 0xece0, 0xbed0, 0xe9a2, 0xe97e, 0xece1, + 0xbed1, 0xe9a1, 0xe97c, 0xc0b4, 0xecdf, 0xe979, 0xe97b, 0xc0b5, + 0xbed3, 0xc0b3, 0xbed2, 0xc0b7, 0xe97d, 0xbecf, 0xefcf, 0xefc7, + 0xece7, 0xefc8, 0xece3, 0xc256, 0xece5, 0xece4, 0xc0b6, 0xece2, + 0xece6, 0xefd0, 0xefcc, 0xefce, 0xefc9, 0xefca, 0xefcd, 0xefcb, + 0xc367, 0xc36a, 0xc369, 0xc368, 0xc461, 0xf44a, 0xc462, 0xf241, + 0xc4df, 0xf5cc, 0xc4e0, 0xc574, 0xc5ca, 0xf7d9, 0xf7da, 0xf7db, + 0xf9ba, 0xa4e0, 0xc97c, 0xa5b3, 0xa6a6, 0xa6a7, 0xa6a5, 0xa6a8, + 0xa7da, 0xa7d9, 0xccb1, 0xa9cf, 0xa9ce, 0xd1af, 0xb1ad, 0xb1ae, + 0xb475, 0xdd72, 0xb760, 0xb761, 0xdd74, 0xdd76, 0xdd75, 0xe1d7, + 0xe1d6, 0xba49, 0xe1d8, 0xe5ac, 0xbcae, 0xbed4, 0xc0b8, 0xc257, + 0xc0b9, 0xa4e1, 0xcae6, 0xccb2, 0xa9d1, 0xa9d0, 0xa9d2, 0xabf3, + 0xced2, 0xced3, 0xd1b0, 0xaeb0, 0xb1af, 0xb476, 0xd951, 0xa4e2, + 0xa47e, 0xa4e3, 0xc97d, 0xa5b7, 0xa5b6, 0xa5b4, 0xa5b5, 0xa6ab, + 0xc9e9, 0xc9eb, 0xa6aa, 0xc9e3, 0xc9e4, 0xc9ea, 0xc9e6, 0xc9e8, + 0xa6a9, 0xc9e5, 0xc9ec, 0xc9e7, 0xa7e1, 0xa7ea, 0xa7e8, 0xcaf0, + 0xcaed, 0xcaf5, 0xa7e6, 0xcaf6, 0xa7df, 0xcaf3, 0xa7e5, 0xcaef, + 0xcaee, 0xa7e3, 0xcaf4, 0xa7e4, 0xa9d3, 0xa7de, 0xcaf1, 0xcae7, + 0xa7db, 0xa7ee, 0xcaec, 0xcaf2, 0xa7e0, 0xa7e2, 0xcae8, 0xcae9, + 0xcaea, 0xa7ed, 0xa7e7, 0xa7ec, 0xcaeb, 0xa7eb, 0xa7dd, 0xa7dc, + 0xa7e9, 0xa9e1, 0xccbe, 0xccb7, 0xa9dc, 0xa9ef, 0xccb3, 0xccba, + 0xccbc, 0xccbf, 0xa9ea, 0xccbb, 0xccb4, 0xa9e8, 0xccb8, 0xccc0, + 0xa9d9, 0xccbd, 0xa9e3, 0xa9e2, 0xccb6, 0xa9d7, 0xa9d8, 0xa9d6, + 0xa9ee, 0xa9e6, 0xa9e0, 0xa9d4, 0xccb9, 0xa9df, 0xa9d5, 0xa9e7, + 0xa9f0, 0xced4, 0xa9e4, 0xccb5, 0xa9da, 0xa9dd, 0xa9de, 0xa9ec, + 0xa9ed, 0xa9eb, 0xa9e5, 0xa9e9, 0xa9db, 0xabf4, 0xceda, 0xac41, + 0xabf8, 0xabfa, 0xac40, 0xcee6, 0xabfd, 0xd1b1, 0xaeb1, 0xac43, + 0xced7, 0xcedf, 0xabfe, 0xcede, 0xcedb, 0xcee3, 0xcee5, 0xabf7, + 0xabfb, 0xac42, 0xaeb3, 0xcee0, 0xabf9, 0xac45, 0xced9, 0xabfc, + 0xaeb2, 0xabf6, 0xced6, 0xcedd, 0xced5, 0xced8, 0xcedc, 0xd1b2, + 0xac44, 0xcee1, 0xcee2, 0xcee4, 0xabf5, 0xaec1, 0xd1be, 0xaebf, + 0xaec0, 0xd1b4, 0xd1c4, 0xaeb6, 0xd566, 0xd1c6, 0xd1c0, 0xd1b7, + 0xd1c9, 0xd1ba, 0xaebc, 0xd57d, 0xd1bd, 0xaebe, 0xaeb5, 0xd1cb, + 0xd1bf, 0xaeb8, 0xd1b8, 0xd1b5, 0xd1b6, 0xaeb9, 0xd1c5, 0xd1cc, + 0xaebb, 0xd1bc, 0xd1bb, 0xaec3, 0xaec2, 0xaeb4, 0xaeba, 0xaebd, + 0xd1c8, 0xd1c2, 0xaeb7, 0xd1b3, 0xd1ca, 0xd1c1, 0xd1c3, 0xd1c7, + 0xd567, 0xb1b7, 0xb1cb, 0xb1ca, 0xb1bf, 0xd579, 0xd575, 0xd572, + 0xd5a6, 0xb1ba, 0xb1b2, 0xd577, 0xb4a8, 0xb1b6, 0xd5a1, 0xb1cc, + 0xb1c9, 0xd57b, 0xd56a, 0xb1c8, 0xd5a3, 0xd569, 0xb1bd, 0xb1c1, + 0xd5a2, 0xd573, 0xb1c2, 0xb1bc, 0xd568, 0xb478, 0xd5a5, 0xd571, + 0xb1c7, 0xd574, 0xd5a4, 0xb1c6, 0xd952, 0xb1b3, 0xd56f, 0xb1b8, + 0xb1c3, 0xb1be, 0xd578, 0xd56e, 0xd56c, 0xd57e, 0xb1b0, 0xb1c4, + 0xb1b4, 0xb477, 0xd57c, 0xb1b5, 0xb1b1, 0xb1c0, 0xb1bb, 0xb1b9, + 0xd570, 0xb1c5, 0xd56d, 0xd57a, 0xd576, 0xd954, 0xd953, 0xd56b, + 0xd964, 0xb47a, 0xd96a, 0xd959, 0xd967, 0xdd77, 0xb47d, 0xd96b, + 0xd96e, 0xb47c, 0xd95c, 0xd96d, 0xd96c, 0xb47e, 0xd955, 0xb479, + 0xb4a3, 0xb4a1, 0xd969, 0xd95f, 0xb4a5, 0xd970, 0xd968, 0xd971, + 0xb4ad, 0xb4ab, 0xd966, 0xd965, 0xd963, 0xd95d, 0xb4a4, 0xb4a2, + 0xd1b9, 0xd956, 0xddb7, 0xd957, 0xb47b, 0xb4aa, 0xdd79, 0xb4a6, + 0xb4a7, 0xd958, 0xd96f, 0xdd78, 0xd960, 0xd95b, 0xb4a9, 0xd961, + 0xd95e, 0xb4ae, 0xb770, 0xdd7c, 0xddb1, 0xddb6, 0xddaa, 0xb76c, + 0xddbb, 0xb769, 0xdd7a, 0xdd7b, 0xb762, 0xb76b, 0xdda4, 0xb76e, + 0xb76f, 0xdda5, 0xddb2, 0xddb8, 0xb76a, 0xb764, 0xdda3, 0xdd7d, + 0xddba, 0xdda8, 0xdda9, 0xdd7e, 0xddb4, 0xddab, 0xddb5, 0xddad, + 0xb765, 0xe1d9, 0xb768, 0xb766, 0xddb9, 0xddb0, 0xddac, 0xdda1, + 0xba53, 0xddaf, 0xb76d, 0xdda7, 0xdda6, 0xb767, 0xb763, 0xe1ee, + 0xddb3, 0xddae, 0xdda2, 0xe1e9, 0xe1da, 0xe1e5, 0xe1ec, 0xba51, + 0xb4ac, 0xe1ea, 0xba4c, 0xba4b, 0xe1f1, 0xe1db, 0xe1e8, 0xe1dc, + 0xe1e7, 0xba4f, 0xe1eb, 0xd962, 0xe1f2, 0xe1e3, 0xba52, 0xe5ba, + 0xbcaf, 0xe1f0, 0xe1ef, 0xba54, 0xe5ad, 0xbcb0, 0xe5ae, 0xe1df, + 0xe1e0, 0xe1dd, 0xe1e2, 0xe1de, 0xe1f3, 0xba4e, 0xbcb1, 0xba50, + 0xba55, 0xe1e1, 0xe1ed, 0xe1e6, 0xe5b1, 0xba4a, 0xbcb4, 0xe9aa, + 0xe5b6, 0xe5b5, 0xe5b7, 0xe5b4, 0xbcb5, 0xbcbb, 0xbcb8, 0xbcb9, + 0xe5af, 0xe5b2, 0xe5bc, 0xbcc1, 0xbcbf, 0xe5b3, 0xd95a, 0xbcb2, + 0xe5b9, 0xe5b0, 0xbcc2, 0xe5b8, 0xba4d, 0xbcb7, 0xe1e4, 0xbcba, + 0xbcbe, 0xbcc0, 0xbcbd, 0xbcbc, 0xbcb6, 0xe5bb, 0xbcb3, 0xbcc3, + 0xbed8, 0xbed9, 0xe9a9, 0xbee2, 0xbedf, 0xbed6, 0xbedd, 0xe9ab, + 0xbedb, 0xbed5, 0xbedc, 0xe9a8, 0xc0bb, 0xbed7, 0xbede, 0xc0ba, + 0xe9a7, 0xe9a6, 0xbee0, 0xbee1, 0xe9a5, 0xe9a4, 0xc0bc, 0xe9ae, + 0xbeda, 0xe9ac, 0xc0bd, 0xc0c2, 0xecea, 0xecec, 0xc0bf, 0xeced, + 0xece9, 0xeceb, 0xc0c0, 0xc0c3, 0xece8, 0xc0be, 0xc0c1, 0xc259, + 0xe9ad, 0xc258, 0xc25e, 0xefd4, 0xc25c, 0xc25d, 0xefd7, 0xefd3, + 0xc25a, 0xefd1, 0xc36b, 0xefd5, 0xefd6, 0xefd2, 0xc25b, 0xf242, + 0xf245, 0xf246, 0xf244, 0xf247, 0xc36c, 0xf243, 0xf44e, 0xc464, + 0xf44d, 0xf44c, 0xf44b, 0xc463, 0xc465, 0xf5cd, 0xc4e2, 0xc4e1, + 0xf6e1, 0xf6e0, 0xf6e3, 0xc5cb, 0xc575, 0xf7dd, 0xf6e2, 0xf7dc, + 0xc5cd, 0xc5cc, 0xc5f3, 0xf8a9, 0xf8ef, 0xa4e4, 0xd972, 0xe9af, + 0xa6ac, 0xcaf7, 0xa7f1, 0xa7ef, 0xa7f0, 0xccc1, 0xa9f1, 0xac46, + 0xcee7, 0xcee8, 0xac47, 0xd1ce, 0xaec4, 0xaec5, 0xd1cd, 0xb1d3, + 0xb1cf, 0xd5a7, 0xb1d6, 0xb1d5, 0xb1ce, 0xb1d1, 0xb1d4, 0xb1d0, + 0xd976, 0xb1cd, 0xb4af, 0xb4b1, 0xb4b2, 0xd975, 0xd978, 0xb4b0, + 0xd973, 0xd977, 0xd974, 0xb771, 0xddbc, 0xba56, 0xe1f4, 0xbee3, + 0xbcc4, 0xe5bd, 0xbcc5, 0xbcc6, 0xe5bf, 0xe5be, 0xe5c0, 0xe9b1, + 0xe9b0, 0xecef, 0xecee, 0xc0c4, 0xc0c5, 0xf248, 0xa4e5, 0xd979, + 0xb4b4, 0xb4b3, 0xddbd, 0xefd8, 0xc4e3, 0xf7de, 0xa4e6, 0xaec6, + 0xb1d8, 0xb1d7, 0xd97a, 0xd97b, 0xb772, 0xe1f5, 0xba57, 0xe9b2, + 0xa4e7, 0xa5b8, 0xa9f2, 0xccc2, 0xcee9, 0xac48, 0xb1d9, 0xd97c, + 0xb4b5, 0xb773, 0xe5c1, 0xe5c2, 0xecf0, 0xc25f, 0xf8f0, 0xa4e8, + 0xccc3, 0xa9f3, 0xac49, 0xceea, 0xaec7, 0xd1d2, 0xd1d0, 0xd1d1, + 0xaec8, 0xd1cf, 0xb1db, 0xb1dc, 0xd5a8, 0xb1dd, 0xb1da, 0xd97d, + 0xd97e, 0xddbe, 0xba59, 0xba58, 0xecf1, 0xefd9, 0xf24a, 0xf249, + 0xf44f, 0xc95e, 0xac4a, 0xa4e9, 0xa5b9, 0xa6ae, 0xa6ad, 0xa6af, + 0xa6b0, 0xc9ee, 0xc9ed, 0xcaf8, 0xa7f2, 0xcafb, 0xcafa, 0xcaf9, + 0xcafc, 0xa9f4, 0xccc9, 0xccc5, 0xccce, 0xa9fb, 0xa9f9, 0xccca, + 0xccc6, 0xcccd, 0xa9f8, 0xaa40, 0xccc8, 0xccc4, 0xa9fe, 0xcccb, + 0xa9f7, 0xcccc, 0xa9fa, 0xa9fc, 0xccd0, 0xcccf, 0xccc7, 0xa9f6, + 0xa9f5, 0xa9fd, 0xceef, 0xcef5, 0xac50, 0xac4d, 0xceec, 0xcef1, + 0xac53, 0xac4b, 0xcef0, 0xac4e, 0xac51, 0xcef3, 0xac4c, 0xcef8, + 0xac4f, 0xac52, 0xceed, 0xcef2, 0xcef6, 0xceee, 0xceeb, 0xcef7, + 0xcef4, 0xaed0, 0xaec9, 0xaecc, 0xaecf, 0xd1d5, 0xaeca, 0xd1d3, + 0xaece, 0xaecb, 0xd1d6, 0xaecd, 0xd5ac, 0xb1df, 0xd5ab, 0xd5ad, + 0xb1de, 0xb1e3, 0xd1d4, 0xd5aa, 0xd5ae, 0xb1e0, 0xd5a9, 0xb1e2, + 0xb1e1, 0xd9a7, 0xd9a2, 0xb4b6, 0xb4ba, 0xb4b7, 0xd9a5, 0xd9a8, + 0xb4b8, 0xb4b9, 0xb4be, 0xddc7, 0xd9a6, 0xb4bc, 0xd9a3, 0xd9a1, + 0xb4bd, 0xd9a4, 0xb779, 0xddbf, 0xb776, 0xb777, 0xb775, 0xddc4, + 0xddc3, 0xddc0, 0xb77b, 0xddc2, 0xb4bb, 0xddc6, 0xddc1, 0xb778, + 0xb774, 0xb77a, 0xddc5, 0xba5c, 0xe1f8, 0xe1f7, 0xe1f6, 0xba5a, + 0xba5b, 0xe5c5, 0xe5c8, 0xbcc8, 0xbcc7, 0xe5c9, 0xe5c4, 0xbcca, + 0xe5c6, 0xbcc9, 0xe5c3, 0xe5c7, 0xbee9, 0xbee6, 0xe9bb, 0xe9ba, + 0xe9b9, 0xe9b4, 0xe9b5, 0xbee7, 0xbee4, 0xbee8, 0xe9b3, 0xbee5, + 0xe9b6, 0xe9b7, 0xe9bc, 0xe9b8, 0xecf2, 0xc0c7, 0xefdc, 0xc0c6, + 0xefda, 0xefdb, 0xc260, 0xc36e, 0xf24b, 0xc36d, 0xf451, 0xf452, + 0xc466, 0xf450, 0xc4e4, 0xf7df, 0xc5ce, 0xf8aa, 0xf8ab, 0xa4ea, + 0xa6b1, 0xa6b2, 0xa7f3, 0xccd1, 0xac54, 0xaed1, 0xb1e4, 0xb0d2, + 0xb4bf, 0xb4c0, 0xb3cc, 0xd9a9, 0xb77c, 0xe1fa, 0xe1f9, 0xa4eb, + 0xa6b3, 0xccd2, 0xaa42, 0xaa41, 0xcef9, 0xcefa, 0xd1d7, 0xd1d8, + 0xaed2, 0xaed3, 0xaed4, 0xd5af, 0xb1e6, 0xb4c2, 0xb4c1, 0xddc8, + 0xdf7a, 0xe1fb, 0xe9bd, 0xc261, 0xc467, 0xa4ec, 0xa5bc, 0xa5bd, + 0xa5bb, 0xa5be, 0xa5ba, 0xa6b6, 0xc9f6, 0xa6b5, 0xa6b7, 0xc9f1, + 0xc9f0, 0xc9f3, 0xc9f2, 0xc9f5, 0xa6b4, 0xc9ef, 0xc9f4, 0xcafd, + 0xa7fd, 0xcafe, 0xcb43, 0xa7fc, 0xcb47, 0xcb42, 0xcb45, 0xa7f5, + 0xa7f6, 0xa7f7, 0xa7f8, 0xa840, 0xcb41, 0xa7fa, 0xa841, 0xcb40, + 0xcb46, 0xa7f9, 0xcb44, 0xa7fb, 0xa7f4, 0xa7fe, 0xaa57, 0xccd4, + 0xaa43, 0xaa4d, 0xaa4e, 0xaa46, 0xaa58, 0xaa48, 0xccdc, 0xaa53, + 0xccd7, 0xaa49, 0xcce6, 0xcce7, 0xccdf, 0xccd8, 0xaa56, 0xcce4, + 0xaa51, 0xaa4f, 0xcce5, 0xcce3, 0xccdb, 0xccd3, 0xccda, 0xaa4a, + 0xaa50, 0xaa44, 0xccde, 0xccdd, 0xccd5, 0xaa52, 0xcce1, 0xccd6, + 0xaa55, 0xcce8, 0xaa45, 0xaa4c, 0xccd9, 0xcce2, 0xaa54, 0xaa47, + 0xaa4b, 0xcce0, 0xcf5b, 0xac5c, 0xac69, 0xcf56, 0xcf4c, 0xac62, + 0xcf4a, 0xac5b, 0xcf45, 0xac65, 0xcf52, 0xcefe, 0xcf41, 0xcf44, + 0xcefb, 0xcf51, 0xcf61, 0xac60, 0xcf46, 0xcf58, 0xcefd, 0xcf5f, + 0xcf60, 0xcf63, 0xcf5a, 0xcf4b, 0xcf53, 0xac66, 0xac59, 0xac61, + 0xac6d, 0xac56, 0xac58, 0xcf43, 0xac6a, 0xac63, 0xcf5d, 0xcf40, + 0xac6c, 0xac67, 0xcf49, 0xac6b, 0xcf50, 0xcf48, 0xac64, 0xcf5c, + 0xcf54, 0xac5e, 0xcf62, 0xcf47, 0xac5a, 0xcf59, 0xcf4f, 0xac5f, + 0xcf55, 0xac57, 0xcefc, 0xac68, 0xaee3, 0xac5d, 0xcf4e, 0xcf4d, + 0xcf42, 0xcf5e, 0xcf57, 0xac55, 0xd1ec, 0xaeea, 0xd1ed, 0xd1e1, + 0xaedf, 0xaeeb, 0xd1da, 0xd1e3, 0xd1eb, 0xd1d9, 0xd1f4, 0xaed5, + 0xd1f3, 0xd1ee, 0xd1ef, 0xaedd, 0xaee8, 0xd1e5, 0xd1e6, 0xd1f0, + 0xd1e7, 0xd1e2, 0xd1dc, 0xd1dd, 0xd1ea, 0xd1e4, 0xaed6, 0xaeda, + 0xd1f2, 0xd1de, 0xaee6, 0xaee2, 0xaee5, 0xaeec, 0xaedb, 0xaee7, + 0xd1e9, 0xaee9, 0xaed8, 0xaed7, 0xd1db, 0xd1df, 0xaee0, 0xd1f1, + 0xd1e8, 0xd1e0, 0xaee4, 0xaee1, 0xaed9, 0xaedc, 0xd5c4, 0xd5b4, + 0xd5b5, 0xd5b9, 0xd5c8, 0xd5c5, 0xd5be, 0xd5bd, 0xb1ed, 0xd5c1, + 0xd5d0, 0xd5b0, 0xd5d1, 0xd5c3, 0xd5d5, 0xd5c9, 0xb1ec, 0xd5c7, + 0xb1e7, 0xb1fc, 0xb1f2, 0xb1f6, 0xb1f5, 0xd5b1, 0xd5ce, 0xd5d4, + 0xd5cc, 0xd5d3, 0xd5c0, 0xd5b2, 0xd5d2, 0xd5c2, 0xb1ea, 0xb1f7, + 0xd5cb, 0xb1f0, 0xd5ca, 0xd5b3, 0xb1f8, 0xb1fa, 0xd5cd, 0xb1fb, + 0xb1e9, 0xd5ba, 0xd5cf, 0xb1ef, 0xb1f9, 0xd5bc, 0xd5c6, 0xd5b7, + 0xd5bb, 0xb1f4, 0xd5b6, 0xb1e8, 0xb1f1, 0xb1ee, 0xd5bf, 0xaede, + 0xd9c0, 0xb1eb, 0xb1f3, 0xd9c3, 0xd9d9, 0xd9ce, 0xb4d6, 0xb4d1, + 0xd9bd, 0xb4d2, 0xd9cd, 0xd9c6, 0xd9d3, 0xb4ce, 0xd9ab, 0xd9d5, + 0xb4c4, 0xd9b3, 0xb4c7, 0xb4c6, 0xb4d7, 0xd9ad, 0xd9cf, 0xd9d0, + 0xb4c9, 0xb4c5, 0xd9bb, 0xb4d0, 0xd9b6, 0xd9d1, 0xb4cc, 0xd9c9, + 0xd9d6, 0xd9b0, 0xd9b5, 0xd9af, 0xb4cb, 0xd9c2, 0xddde, 0xd9b1, + 0xb4cf, 0xd9ba, 0xd9d2, 0xb4ca, 0xd9b7, 0xd9b4, 0xd9c5, 0xb4cd, + 0xb4c3, 0xb4d9, 0xd9c8, 0xd9c7, 0xd9ac, 0xb4c8, 0xd9d4, 0xd9bc, + 0xd9be, 0xd9cb, 0xd9ca, 0xd9aa, 0xb4d3, 0xb4d5, 0xd9b2, 0xd9b9, + 0xd9c1, 0xb4d4, 0xd9b8, 0xd9c4, 0xd9d7, 0xd9cc, 0xd9d8, 0xd9ae, + 0xddf2, 0xb7a6, 0xddf0, 0xdddb, 0xdde0, 0xddd9, 0xddec, 0xddcb, + 0xddd2, 0xddea, 0xddf4, 0xdddc, 0xddcf, 0xdde2, 0xdde7, 0xddd3, + 0xdde4, 0xddd0, 0xddd7, 0xddd8, 0xb7a8, 0xddeb, 0xdde9, 0xddcc, + 0xddee, 0xddef, 0xddf1, 0xb7ac, 0xb7a4, 0xd5b8, 0xddd4, 0xdde6, + 0xddd5, 0xb7a1, 0xb7b1, 0xdded, 0xb7af, 0xb7ab, 0xddca, 0xb7a3, + 0xddcd, 0xb7b0, 0xdddd, 0xddc9, 0xb7a9, 0xdde1, 0xddd1, 0xb7aa, + 0xddda, 0xb77e, 0xb4d8, 0xdde3, 0xd9bf, 0xddce, 0xdde8, 0xb7a5, + 0xdde5, 0xb7a2, 0xdddf, 0xb7ad, 0xddd6, 0xddf3, 0xb7a7, 0xdec6, + 0xb7ae, 0xe24a, 0xe248, 0xe25e, 0xe246, 0xe258, 0xb77d, 0xba5f, + 0xe242, 0xe25d, 0xe247, 0xe255, 0xba64, 0xba5d, 0xe25b, 0xe240, + 0xe25a, 0xba6f, 0xe251, 0xe261, 0xba6d, 0xe249, 0xba5e, 0xe24b, + 0xe259, 0xba67, 0xe244, 0xba6b, 0xba61, 0xe24d, 0xe243, 0xe1fc, + 0xe257, 0xba68, 0xe260, 0xe1fd, 0xba65, 0xe253, 0xba66, 0xe245, + 0xe250, 0xe24c, 0xe24e, 0xba60, 0xe25f, 0xba6e, 0xe24f, 0xe262, + 0xe1fe, 0xe254, 0xba63, 0xba6c, 0xba6a, 0xe241, 0xe256, 0xba69, + 0xba62, 0xe252, 0xe25c, 0xe5d5, 0xe5d1, 0xe5cd, 0xe5e1, 0xe5de, + 0xbccd, 0xe5e5, 0xe5d4, 0xbcd8, 0xe5db, 0xe5d0, 0xe5da, 0xbcd5, + 0xe5ee, 0xe5eb, 0xe5dd, 0xe5ce, 0xe5e2, 0xe5e4, 0xbcd1, 0xe5d8, + 0xe5d3, 0xe5ca, 0xbcce, 0xbcd6, 0xe5e7, 0xbcd7, 0xe5cb, 0xe5ed, + 0xe5e0, 0xe5e6, 0xbcd4, 0xe5e3, 0xe5ea, 0xbcd9, 0xbcd3, 0xe5dc, + 0xe5cf, 0xe5ef, 0xe5cc, 0xe5e8, 0xbcd0, 0xe5d6, 0xe5d7, 0xbccf, + 0xbccc, 0xe5d2, 0xbcd2, 0xbccb, 0xe5e9, 0xe5ec, 0xe5d9, 0xe9ca, + 0xe9c2, 0xe9be, 0xbef6, 0xbeeb, 0xbef0, 0xbeec, 0xe9cc, 0xe9d7, + 0xbeea, 0xe9c4, 0xe9cd, 0xe5df, 0xe9ce, 0xbef1, 0xe9dd, 0xbef5, + 0xbef8, 0xe9c0, 0xbef4, 0xe9db, 0xe9dc, 0xe9d2, 0xe9d1, 0xe9c9, + 0xe9d3, 0xe9da, 0xe9d9, 0xbeef, 0xbeed, 0xe9cb, 0xe9c8, 0xe9c5, + 0xe9d8, 0xbef7, 0xe9d6, 0xbef3, 0xbef2, 0xe9d0, 0xe9bf, 0xe9c1, + 0xe9c3, 0xe9d5, 0xe9cf, 0xbeee, 0xe9c6, 0xe9d4, 0xe9c7, 0xc0cf, + 0xed45, 0xc0c8, 0xecf5, 0xed41, 0xc0ca, 0xed48, 0xecfc, 0xecf7, + 0xed49, 0xecf3, 0xecfe, 0xc0d1, 0xed44, 0xed4a, 0xecfd, 0xc0c9, + 0xed40, 0xecf4, 0xc0d0, 0xed47, 0xecf9, 0xc0cc, 0xecfb, 0xecf8, + 0xc0d2, 0xecfa, 0xc0cb, 0xc0ce, 0xed43, 0xecf6, 0xed46, 0xed42, + 0xc263, 0xefe7, 0xc268, 0xc269, 0xc262, 0xefe6, 0xefe3, 0xefe4, + 0xc266, 0xefde, 0xefe2, 0xc265, 0xefdf, 0xc267, 0xc264, 0xefdd, + 0xefe1, 0xefe5, 0xf251, 0xf24e, 0xf257, 0xf256, 0xf254, 0xf24f, + 0xc372, 0xf250, 0xc371, 0xc0cd, 0xf253, 0xc370, 0xf258, 0xf252, + 0xf24d, 0xefe0, 0xc36f, 0xf24c, 0xf456, 0xf455, 0xf255, 0xc468, + 0xf459, 0xf45a, 0xf454, 0xf458, 0xf453, 0xf5d1, 0xf457, 0xc4e7, + 0xc4e5, 0xf5cf, 0xf5d2, 0xf5ce, 0xf5d0, 0xc4e6, 0xf6e5, 0xf6e6, + 0xc576, 0xf6e4, 0xf7e2, 0xc5cf, 0xf7e0, 0xf7e1, 0xf8ac, 0xc656, + 0xf8f3, 0xf8f1, 0xf8f2, 0xf8f4, 0xf9bb, 0xa4ed, 0xa6b8, 0xaa59, + 0xcce9, 0xcf64, 0xd1f5, 0xd1f7, 0xd1f6, 0xd1f8, 0xb1fd, 0xd5d7, + 0xd1f9, 0xd5d6, 0xd5d8, 0xd5d9, 0xd9da, 0xb4db, 0xd9db, 0xd9dd, + 0xb4dc, 0xb4da, 0xd9dc, 0xddfa, 0xddf8, 0xddf7, 0xddf6, 0xddf5, + 0xb7b2, 0xddf9, 0xba70, 0xe263, 0xe265, 0xba71, 0xe264, 0xbcdb, + 0xbcda, 0xe5f0, 0xe9df, 0xe9de, 0xe9e0, 0xbef9, 0xed4b, 0xc0d3, + 0xefe8, 0xc26a, 0xf259, 0xc577, 0xa4ee, 0xa5bf, 0xa6b9, 0xa842, + 0xaa5a, 0xaa5b, 0xac6e, 0xd1fa, 0xb7b3, 0xe6d1, 0xbefa, 0xc26b, + 0xa4ef, 0xa6ba, 0xcceb, 0xaa5c, 0xccea, 0xcf65, 0xac6f, 0xcf66, + 0xac70, 0xd1fc, 0xaeee, 0xaeed, 0xd5de, 0xd5dc, 0xd5dd, 0xd5db, + 0xd5da, 0xd9de, 0xd9e1, 0xb4de, 0xd9df, 0xb4dd, 0xd9e0, 0xddfb, + 0xe266, 0xe267, 0xe268, 0xe5f3, 0xe5f2, 0xbcdc, 0xe5f1, 0xe5f4, + 0xe9e1, 0xe9e2, 0xe9e3, 0xed4c, 0xc0d4, 0xc26c, 0xf25a, 0xc4e8, + 0xc95f, 0xac71, 0xcf67, 0xaeef, 0xb1fe, 0xb4df, 0xd9e2, 0xb7b5, + 0xb7b4, 0xe269, 0xe26a, 0xbcdd, 0xbcde, 0xe9e5, 0xe9e4, 0xefe9, + 0xf7e3, 0xa4f0, 0xc960, 0xa5c0, 0xa843, 0xcb48, 0xac72, 0xb7b6, + 0xa4f1, 0xcf68, 0xac73, 0xcf69, 0xc0d5, 0xa4f2, 0xccec, 0xcf6a, + 0xd242, 0xd241, 0xd1fe, 0xd1fd, 0xd243, 0xd240, 0xb240, 0xb241, + 0xb4e0, 0xd9e3, 0xd9e4, 0xd9e5, 0xde41, 0xde42, 0xde40, 0xddfd, + 0xddfe, 0xb7b7, 0xe26b, 0xe5f7, 0xe5f6, 0xe5f5, 0xe5f8, 0xe9e7, + 0xe9e6, 0xbefb, 0xe9e8, 0xc0d6, 0xed4d, 0xefea, 0xf25b, 0xf6e7, + 0xa4f3, 0xa5c2, 0xa5c1, 0xaa5d, 0xc961, 0xc97e, 0xa6bb, 0xc9f7, + 0xcb49, 0xcb4a, 0xaa5e, 0xcced, 0xac74, 0xcf6b, 0xcf6c, 0xaef0, + 0xaef4, 0xd244, 0xaef3, 0xaef1, 0xaef2, 0xd5df, 0xb242, 0xb4e3, + 0xb4e1, 0xb4e2, 0xd9e6, 0xba72, 0xa4f4, 0xc9a1, 0xa5c3, 0xc9a4, + 0xa5c6, 0xc9a3, 0xa5c5, 0xa5c4, 0xa844, 0xc9a2, 0xc9f8, 0xc9fc, + 0xc9fe, 0xca40, 0xa6c5, 0xa6c6, 0xc9fb, 0xa6c1, 0xc9f9, 0xc9fd, + 0xa6c2, 0xa6bd, 0xa6be, 0xa6c4, 0xc9fa, 0xa6bc, 0xa845, 0xa6bf, + 0xa6c0, 0xa6c3, 0xcb5b, 0xcb59, 0xcb4c, 0xa851, 0xcb53, 0xa84c, + 0xcb4d, 0xcb55, 0xcb52, 0xa84f, 0xcb51, 0xa856, 0xcb5a, 0xa858, + 0xa85a, 0xcb4b, 0xa84d, 0xcb5c, 0xa854, 0xa857, 0xcd45, 0xa847, + 0xa85e, 0xa855, 0xcb4e, 0xa84a, 0xa859, 0xcb56, 0xa848, 0xa849, + 0xcd43, 0xcb4f, 0xa850, 0xa85b, 0xcb5d, 0xcb50, 0xa84e, 0xa853, + 0xccee, 0xa85c, 0xcb57, 0xa852, 0xa85d, 0xa846, 0xcb54, 0xa84b, + 0xcb58, 0xcd44, 0xaa6a, 0xaa7a, 0xccf5, 0xaa71, 0xcd4b, 0xaa62, + 0xaa65, 0xcd42, 0xccf3, 0xccf7, 0xaa6d, 0xaa6f, 0xccfa, 0xaa76, + 0xaa68, 0xaa66, 0xaa67, 0xaa75, 0xcd47, 0xaa70, 0xccf9, 0xccfb, + 0xaa6e, 0xaa73, 0xccfc, 0xcd4a, 0xac75, 0xaa79, 0xaa63, 0xcd49, + 0xcd4d, 0xccf8, 0xcd4f, 0xcd40, 0xaa6c, 0xccf4, 0xaa6b, 0xaa7d, + 0xaa72, 0xccf2, 0xcf75, 0xaa78, 0xaa7c, 0xcd41, 0xcd46, 0xaa7e, + 0xaa77, 0xaa69, 0xaa5f, 0xaa64, 0xccf6, 0xaa60, 0xcd4e, 0xccf0, + 0xccef, 0xccfd, 0xccf1, 0xaa7b, 0xaef5, 0xaa74, 0xccfe, 0xaa61, + 0xaca6, 0xcd4c, 0xcf7c, 0xcfa1, 0xcfa4, 0xcf77, 0xcfa7, 0xcfaa, + 0xcfac, 0xcf74, 0xac76, 0xac7b, 0xd249, 0xacad, 0xcfa5, 0xcfad, + 0xcf7b, 0xcf73, 0xd264, 0xac7e, 0xcfa2, 0xcf78, 0xcf7a, 0xaca5, + 0xcf7d, 0xac7d, 0xcf70, 0xcfa8, 0xcfab, 0xac7a, 0xaca8, 0xcf6d, + 0xacaa, 0xac78, 0xacae, 0xcfa9, 0xcf6f, 0xacab, 0xd25e, 0xcd48, + 0xac7c, 0xac77, 0xcf76, 0xcf6e, 0xacac, 0xaca4, 0xcfa3, 0xaca9, + 0xaca7, 0xcf79, 0xaca1, 0xcf71, 0xaca2, 0xaca3, 0xcf72, 0xcfa6, + 0xac79, 0xcf7e, 0xd24c, 0xaefd, 0xaf43, 0xd255, 0xd25b, 0xd257, + 0xd24a, 0xd24d, 0xd246, 0xd247, 0xaf4a, 0xaefa, 0xd256, 0xd25f, + 0xaf45, 0xaef6, 0xaf40, 0xd24e, 0xaf42, 0xd24f, 0xd259, 0xaf44, + 0xd268, 0xd248, 0xaefc, 0xaefb, 0xaf48, 0xd245, 0xd266, 0xd25a, + 0xd267, 0xd261, 0xd253, 0xd262, 0xd25c, 0xd265, 0xd263, 0xaf49, + 0xd254, 0xaef9, 0xaef8, 0xaf41, 0xaf47, 0xd260, 0xaf46, 0xd251, + 0xb243, 0xd269, 0xd250, 0xd24b, 0xaefe, 0xaf4b, 0xaef7, 0xd258, + 0xd25d, 0xb265, 0xd5e1, 0xd5e5, 0xb252, 0xb250, 0xb247, 0xd5e3, + 0xd5e2, 0xb25b, 0xd5e8, 0xb255, 0xd5fa, 0xd647, 0xb244, 0xd5f7, + 0xd5f0, 0xb267, 0xd5e0, 0xd5fc, 0xb264, 0xb258, 0xb263, 0xb24e, + 0xd5ec, 0xd5fe, 0xd5f6, 0xb24f, 0xb249, 0xd645, 0xd5fd, 0xd640, + 0xb251, 0xb259, 0xd642, 0xd5ea, 0xd5fb, 0xd5ef, 0xd644, 0xb25e, + 0xb246, 0xb25c, 0xd5f4, 0xd5f2, 0xd5f3, 0xb253, 0xd5ee, 0xd5ed, + 0xb248, 0xd5e7, 0xd646, 0xb24a, 0xd5f1, 0xb268, 0xb262, 0xd5e6, + 0xb25f, 0xb25d, 0xb266, 0xd5f8, 0xb261, 0xd252, 0xd5f9, 0xb260, + 0xd641, 0xb245, 0xd5f5, 0xb257, 0xd5e9, 0xb256, 0xb254, 0xb24c, + 0xb24b, 0xd9e7, 0xd643, 0xd5eb, 0xd9fc, 0xb24d, 0xb541, 0xb25a, + 0xb4ee, 0xd9f6, 0xb4fc, 0xd9ea, 0xb4eb, 0xb4e7, 0xda49, 0xb4ed, + 0xb4f1, 0xb4ec, 0xb4f5, 0xda4d, 0xda44, 0xd9f1, 0xb4fa, 0xb4f4, + 0xd9fd, 0xb4e4, 0xda4a, 0xda43, 0xb4e8, 0xd9f7, 0xb4f7, 0xda55, + 0xda56, 0xb4e5, 0xda48, 0xb4f9, 0xd9fb, 0xd9ed, 0xd9ee, 0xb4fd, + 0xd9f2, 0xd9f9, 0xd9f3, 0xb4fb, 0xb544, 0xd9ef, 0xd9e8, 0xd9e9, + 0xd9eb, 0xb4ea, 0xd9f8, 0xb4f8, 0xb542, 0xd9fa, 0xda53, 0xda4b, + 0xb4e6, 0xda51, 0xb4f2, 0xb4f0, 0xda57, 0xb4ef, 0xda41, 0xd9f4, + 0xd9fe, 0xb547, 0xda45, 0xda42, 0xd9f0, 0xb543, 0xda4f, 0xda4c, + 0xda54, 0xb4e9, 0xda40, 0xb546, 0xda47, 0xb4f3, 0xb4f6, 0xda46, + 0xb545, 0xd9f5, 0xd5e4, 0xda50, 0xda4e, 0xda52, 0xd9ec, 0xb540, + 0xde61, 0xde60, 0xde46, 0xb7bd, 0xde5f, 0xde49, 0xde4a, 0xb7c7, + 0xde68, 0xb7c2, 0xde5e, 0xde43, 0xb7c8, 0xb7be, 0xde52, 0xde48, + 0xde4b, 0xde63, 0xb7b8, 0xde6a, 0xde62, 0xb7c1, 0xde57, 0xb7cc, + 0xb7cb, 0xb7c5, 0xde69, 0xb7b9, 0xde55, 0xde4c, 0xde59, 0xde65, + 0xb7cd, 0xb7bb, 0xde54, 0xde4d, 0xb7c4, 0xb7c3, 0xde50, 0xde5a, + 0xde64, 0xde47, 0xde51, 0xb7bc, 0xde5b, 0xb7c9, 0xb7c0, 0xde4e, + 0xb7bf, 0xde45, 0xde53, 0xde67, 0xb4fe, 0xbab0, 0xde56, 0xe26c, + 0xde58, 0xde66, 0xb7c6, 0xde4f, 0xb7ba, 0xb7ca, 0xbcf0, 0xde44, + 0xde5d, 0xde5c, 0xe2aa, 0xbaad, 0xe27d, 0xe2a4, 0xbaa2, 0xe26e, + 0xbaaf, 0xba77, 0xe26d, 0xe2b0, 0xbab1, 0xe271, 0xe2a3, 0xe273, + 0xe2b3, 0xe2af, 0xba75, 0xbaa1, 0xe653, 0xbaae, 0xba7d, 0xe26f, + 0xe2ae, 0xbaa3, 0xe2ab, 0xe2b8, 0xe275, 0xe27e, 0xe2b6, 0xe2ac, + 0xba7c, 0xe27c, 0xba76, 0xba74, 0xbaa8, 0xe27a, 0xe277, 0xe278, + 0xe2b2, 0xe2b7, 0xe2b5, 0xba7a, 0xe2b9, 0xba7e, 0xbaa7, 0xe270, + 0xe5fa, 0xe279, 0xba78, 0xbaac, 0xbaa9, 0xba7b, 0xe2a5, 0xe274, + 0xbaaa, 0xe2a7, 0xbaa4, 0xbaa6, 0xba73, 0xe2a9, 0xe2a1, 0xe272, + 0xbaa5, 0xe2b1, 0xe2b4, 0xe27b, 0xe2a8, 0xba79, 0xbcdf, 0xe2a6, + 0xe5f9, 0xe2ad, 0xe276, 0xe644, 0xe64e, 0xbce2, 0xe64d, 0xe659, + 0xbce4, 0xe64b, 0xe64f, 0xbcef, 0xe646, 0xbce7, 0xe652, 0xe9f0, + 0xbcf3, 0xbcf2, 0xe654, 0xe643, 0xe65e, 0xbced, 0xbce3, 0xe657, + 0xe65b, 0xe660, 0xe655, 0xe649, 0xbce6, 0xbce9, 0xbcf1, 0xbcec, + 0xe64c, 0xe2a2, 0xe648, 0xe65f, 0xbce8, 0xbceb, 0xe661, 0xbce0, + 0xe656, 0xe5fb, 0xe65c, 0xc0df, 0xe64a, 0xbce1, 0xe645, 0xbce5, + 0xe5fc, 0xbaab, 0xe641, 0xe65a, 0xe642, 0xe640, 0xbcea, 0xe658, + 0xe5fe, 0xe651, 0xe650, 0xe65d, 0xe647, 0xbcee, 0xe9f3, 0xbf49, + 0xbefe, 0xea40, 0xe9eb, 0xbf41, 0xe9f7, 0xbf48, 0xbf43, 0xe9f5, + 0xed4f, 0xe9fb, 0xea42, 0xe9fa, 0xe9e9, 0xe9f8, 0xea44, 0xea46, + 0xbefd, 0xea45, 0xbf44, 0xbf4a, 0xbf47, 0xe9fe, 0xbf46, 0xe9f9, + 0xe9ed, 0xe9f2, 0xe9fd, 0xbf45, 0xbf42, 0xbefc, 0xbf40, 0xe9f1, + 0xe5fd, 0xe9ec, 0xe9ef, 0xea41, 0xe9f4, 0xe9ea, 0xed4e, 0xea43, + 0xe9ee, 0xe9fc, 0xed51, 0xc0e3, 0xc0d7, 0xc0db, 0xed53, 0xed59, + 0xed57, 0xc0d9, 0xc0da, 0xc0e1, 0xed5a, 0xed52, 0xc0dc, 0xed56, + 0xed55, 0xed5b, 0xc0e2, 0xc0dd, 0xc0e0, 0xed54, 0xc0e4, 0xc0de, + 0xc0e5, 0xc0d8, 0xed58, 0xed50, 0xeff7, 0xc271, 0xeff4, 0xeff6, + 0xc26f, 0xeff2, 0xeff3, 0xefee, 0xe9f6, 0xefef, 0xc270, 0xefeb, + 0xc26d, 0xeff8, 0xc26e, 0xefec, 0xefed, 0xeff1, 0xc273, 0xc272, + 0xeff0, 0xc378, 0xf25f, 0xf265, 0xc379, 0xf25c, 0xc376, 0xc373, + 0xf267, 0xc377, 0xc374, 0xf25e, 0xf261, 0xf262, 0xf263, 0xf266, + 0xeff5, 0xf25d, 0xc375, 0xf264, 0xf268, 0xf260, 0xf45d, 0xc46a, + 0xf460, 0xc46b, 0xf468, 0xf45f, 0xf45c, 0xf45e, 0xf462, 0xf465, + 0xf464, 0xf467, 0xf45b, 0xc469, 0xf463, 0xf466, 0xf469, 0xf461, + 0xf5d3, 0xf5d4, 0xf5d8, 0xf5d9, 0xf5d6, 0xf5d7, 0xf5d5, 0xc4e9, + 0xc578, 0xf6eb, 0xf6e8, 0xf6e9, 0xf6ea, 0xc579, 0xf7e5, 0xf7e4, + 0xf8af, 0xc5f4, 0xf8ad, 0xf8b0, 0xf8ae, 0xf8f5, 0xc657, 0xc665, + 0xf9a3, 0xf96c, 0xf9a2, 0xf9d0, 0xf9d1, 0xa4f5, 0xa6c7, 0xca41, + 0xcb5e, 0xa85f, 0xa862, 0xcb5f, 0xa860, 0xa861, 0xcd58, 0xcd5a, + 0xcd55, 0xcd52, 0xcd54, 0xaaa4, 0xaaa2, 0xcd56, 0xaaa3, 0xcd53, + 0xcd50, 0xaaa1, 0xcd57, 0xcd51, 0xaaa5, 0xcd59, 0xcfaf, 0xcfb3, + 0xacb7, 0xcfb6, 0xacaf, 0xacb2, 0xacb4, 0xacb6, 0xacb3, 0xcfb2, + 0xcfb1, 0xacb1, 0xcfb4, 0xcfb5, 0xcfae, 0xacb5, 0xacb0, 0xcfb0, + 0xd277, 0xd278, 0xd279, 0xaf50, 0xaf4c, 0xd26e, 0xd276, 0xd27b, + 0xaf51, 0xd26c, 0xd272, 0xd26b, 0xd275, 0xd271, 0xaf4d, 0xaf4f, + 0xd27a, 0xd26a, 0xd26d, 0xd273, 0xd274, 0xd27c, 0xd270, 0xaf4e, + 0xb26d, 0xd64e, 0xd650, 0xd64c, 0xd658, 0xd64a, 0xd657, 0xb269, + 0xd648, 0xda5b, 0xd652, 0xb26c, 0xd653, 0xd656, 0xd65a, 0xd64f, + 0xd654, 0xb26a, 0xb26b, 0xd659, 0xd64d, 0xd649, 0xd65b, 0xd651, + 0xd655, 0xd64b, 0xb548, 0xb549, 0xda65, 0xb54f, 0xda59, 0xda62, + 0xda58, 0xb54c, 0xda60, 0xda5e, 0xda5f, 0xb54a, 0xda63, 0xda5c, + 0xda5a, 0xb54b, 0xda5d, 0xda61, 0xb54d, 0xda64, 0xde70, 0xde77, + 0xde79, 0xdea1, 0xb7da, 0xde6b, 0xb7d2, 0xde7a, 0xb7d7, 0xdea2, + 0xb7ce, 0xde7d, 0xde6d, 0xde7e, 0xde6c, 0xb7dc, 0xde78, 0xb7cf, + 0xdea3, 0xb7d4, 0xde71, 0xb7d9, 0xde7c, 0xde6f, 0xde76, 0xde72, + 0xde6e, 0xb7d1, 0xb7d8, 0xb7d6, 0xb7d3, 0xb7db, 0xb7d0, 0xde75, + 0xb7d5, 0xb54e, 0xde7b, 0xde73, 0xde74, 0xe2c1, 0xbab4, 0xe2bd, + 0xe2c3, 0xe2bf, 0xbab6, 0xe2be, 0xe2c2, 0xe2ba, 0xe2bc, 0xbab5, + 0xe2c0, 0xe2bb, 0xbab7, 0xbab2, 0xe2c4, 0xbab3, 0xe667, 0xe664, + 0xe670, 0xe66a, 0xe66c, 0xbcf4, 0xe666, 0xe66e, 0xe66d, 0xe66b, + 0xe671, 0xbcf7, 0xe668, 0xe66f, 0xbcf5, 0xe663, 0xe665, 0xbcf6, + 0xe662, 0xe672, 0xe669, 0xea4a, 0xbf51, 0xea55, 0xea53, 0xbf4b, + 0xea49, 0xea4c, 0xea4d, 0xea48, 0xbf55, 0xbf56, 0xea47, 0xea56, + 0xea51, 0xbf4f, 0xbf4c, 0xea50, 0xea4e, 0xbf52, 0xea52, 0xbf4d, + 0xbf4e, 0xea4f, 0xbf50, 0xea4b, 0xea54, 0xbf53, 0xea57, 0xea58, + 0xbf54, 0xc0e7, 0xc0ee, 0xed5c, 0xed62, 0xed60, 0xc0ea, 0xc0e9, + 0xc0e6, 0xed5e, 0xc0ec, 0xc0eb, 0xc0e8, 0xed61, 0xed5d, 0xed5f, + 0xc0ed, 0xc277, 0xeffb, 0xc274, 0xc275, 0xeffd, 0xc276, 0xeffa, + 0xeff9, 0xf26c, 0xeffc, 0xf26d, 0xc37a, 0xf26b, 0xf26a, 0xf269, + 0xc37b, 0xc46c, 0xf46a, 0xf46b, 0xf5dc, 0xf5db, 0xc4ea, 0xf5da, + 0xf6ec, 0xf6ed, 0xf7e6, 0xf8b1, 0xf8f6, 0xf9bc, 0xc679, 0xf9c6, + 0xa4f6, 0xaaa6, 0xaaa7, 0xacb8, 0xc0ef, 0xa4f7, 0xaaa8, 0xaf52, + 0xb7dd, 0xa4f8, 0xb26e, 0xbab8, 0xc962, 0xcfb7, 0xd27d, 0xe2c5, + 0xc0f0, 0xa4f9, 0xaaa9, 0xcfb8, 0xcfb9, 0xda66, 0xb550, 0xdea4, + 0xb7de, 0xe2c6, 0xbcf8, 0xc37c, 0xa4fa, 0xda67, 0xa4fb, 0xa6c9, + 0xca42, 0xa6c8, 0xa865, 0xa864, 0xa863, 0xcb60, 0xaaaa, 0xaaab, + 0xcd5b, 0xcfba, 0xcfbd, 0xacba, 0xcfbb, 0xacb9, 0xcfbc, 0xacbb, + 0xd2a2, 0xd2a1, 0xd27e, 0xaf53, 0xd65d, 0xd65e, 0xb26f, 0xd65c, + 0xd65f, 0xb552, 0xb270, 0xb551, 0xda6b, 0xda6a, 0xda68, 0xda69, + 0xda6c, 0xdea6, 0xdea5, 0xdea9, 0xdea8, 0xdea7, 0xbab9, 0xe2c9, + 0xe2c8, 0xbaba, 0xe2c7, 0xe673, 0xe674, 0xbcf9, 0xea59, 0xea5a, + 0xf272, 0xc37d, 0xf271, 0xf270, 0xf26e, 0xf26f, 0xc4eb, 0xf46c, + 0xf6ee, 0xf8f7, 0xa4fc, 0xc9a5, 0xa5c7, 0xc9a6, 0xca43, 0xca44, + 0xcb66, 0xcb62, 0xcb61, 0xaaac, 0xcb65, 0xa867, 0xcb63, 0xa866, + 0xcb67, 0xcb64, 0xcd5f, 0xcfbe, 0xcd5d, 0xcd64, 0xaaad, 0xaab0, + 0xcd65, 0xcd61, 0xcd62, 0xcd5c, 0xaaaf, 0xcd5e, 0xaaae, 0xcd63, + 0xcd60, 0xcfc2, 0xacbd, 0xacbe, 0xcfc5, 0xcfbf, 0xcfc4, 0xcfc0, + 0xacbc, 0xcfc3, 0xcfc1, 0xd2a8, 0xd2a5, 0xd2a7, 0xaf58, 0xaf57, + 0xaf55, 0xd2a4, 0xd2a9, 0xaf54, 0xaf56, 0xd2a6, 0xd667, 0xd2a3, + 0xd2aa, 0xd662, 0xd666, 0xd665, 0xda6e, 0xda79, 0xd668, 0xd663, + 0xda6d, 0xb274, 0xb273, 0xd661, 0xd664, 0xb275, 0xb272, 0xb271, + 0xd660, 0xd669, 0xda70, 0xda77, 0xb554, 0xda76, 0xda73, 0xb556, + 0xda75, 0xda6f, 0xda71, 0xda74, 0xda72, 0xb555, 0xda78, 0xb553, + 0xb7df, 0xdead, 0xdeac, 0xdeaa, 0xb7e2, 0xb7e1, 0xdeae, 0xdeab, + 0xe2ca, 0xbabb, 0xb7e0, 0xdeb0, 0xdeaf, 0xe2cd, 0xe2cb, 0xbcfa, + 0xbabc, 0xe2cc, 0xe676, 0xbcfb, 0xe675, 0xe67e, 0xe67d, 0xe67b, + 0xe67a, 0xe677, 0xe678, 0xe679, 0xe67c, 0xe6a1, 0xea5f, 0xea5c, + 0xea5d, 0xbf57, 0xea5b, 0xea61, 0xea60, 0xea5e, 0xed64, 0xed65, + 0xc0f1, 0xc0f2, 0xed63, 0xc279, 0xeffe, 0xc278, 0xc37e, 0xc3a1, + 0xc46d, 0xf46e, 0xf46d, 0xf5dd, 0xf6ef, 0xc57a, 0xf7e8, 0xf7e7, + 0xf7e9, 0xa5c8, 0xcfc6, 0xaf59, 0xb276, 0xd66a, 0xa5c9, 0xc9a7, + 0xa4fd, 0xca45, 0xcb6c, 0xcb6a, 0xcb6b, 0xcb68, 0xa868, 0xcb69, + 0xcd6d, 0xaab3, 0xcd6b, 0xcd67, 0xcd6a, 0xcd66, 0xaab5, 0xcd69, + 0xaab2, 0xaab1, 0xaab4, 0xcd6c, 0xcd68, 0xacc2, 0xacc5, 0xcfce, + 0xcfcd, 0xcfcc, 0xacbf, 0xcfd5, 0xcfcb, 0xacc1, 0xd2af, 0xcfd2, + 0xcfd0, 0xacc4, 0xcfc8, 0xcfd3, 0xcfca, 0xcfd4, 0xcfd1, 0xcfc9, + 0xacc0, 0xcfd6, 0xcfc7, 0xacc3, 0xd2b4, 0xd2ab, 0xd2b6, 0xd2ae, + 0xd2b9, 0xd2ba, 0xd2ac, 0xd2b8, 0xd2b5, 0xd2b3, 0xd2b7, 0xaf5f, + 0xaf5d, 0xd2b1, 0xd2ad, 0xd2b0, 0xd2bb, 0xd2b2, 0xaf5e, 0xcfcf, + 0xaf5a, 0xaf5c, 0xd678, 0xd66d, 0xd66b, 0xd66c, 0xd673, 0xd674, + 0xd670, 0xb27b, 0xd675, 0xd672, 0xd66f, 0xb279, 0xd66e, 0xb277, + 0xb27a, 0xd671, 0xd679, 0xaf5b, 0xb278, 0xd677, 0xd676, 0xb27c, + 0xda7e, 0xdaa1, 0xb560, 0xdaa7, 0xdaa9, 0xdaa2, 0xb55a, 0xdaa6, + 0xdaa5, 0xb55b, 0xb561, 0xb562, 0xdaa8, 0xb558, 0xda7d, 0xda7b, + 0xdaa3, 0xda7a, 0xb55f, 0xda7c, 0xdaa4, 0xdaaa, 0xb559, 0xb55e, + 0xb55c, 0xb55d, 0xb557, 0xb7e9, 0xdeb7, 0xb7e8, 0xdebb, 0xdeb1, + 0xdebc, 0xdeb2, 0xdeb3, 0xdebd, 0xdeba, 0xdeb8, 0xdeb9, 0xdeb5, + 0xdeb4, 0xdebe, 0xb7e5, 0xdeb6, 0xb7ea, 0xb7e4, 0xb7eb, 0xb7ec, + 0xb7e7, 0xb7e6, 0xe2ce, 0xbabe, 0xbabd, 0xe2d3, 0xbcfc, 0xbabf, + 0xbac1, 0xe2d4, 0xb7e3, 0xbac0, 0xe2d0, 0xe2d2, 0xe2cf, 0xe2d1, + 0xe6ab, 0xe6aa, 0xe6a7, 0xbd40, 0xea62, 0xbd41, 0xe6a6, 0xbcfe, + 0xe6a8, 0xe6a5, 0xe6a2, 0xe6a9, 0xe6a3, 0xe6a4, 0xbcfd, 0xed69, + 0xea66, 0xea65, 0xea67, 0xed66, 0xbf5a, 0xea63, 0xbf58, 0xbf5c, + 0xbf5b, 0xea64, 0xea68, 0xbf59, 0xed6d, 0xc0f5, 0xc27a, 0xc0f6, + 0xc0f3, 0xed6a, 0xed68, 0xed6b, 0xed6e, 0xc0f4, 0xed6c, 0xed67, + 0xf042, 0xf045, 0xf275, 0xf040, 0xf46f, 0xf046, 0xc3a2, 0xf044, + 0xc27b, 0xf041, 0xf043, 0xf047, 0xf276, 0xf274, 0xc3a3, 0xf273, + 0xc46e, 0xc4ed, 0xf6f1, 0xc4ec, 0xf6f3, 0xf6f0, 0xf6f2, 0xc5d0, + 0xf8b2, 0xa5ca, 0xcd6e, 0xd2bc, 0xd2bd, 0xb27d, 0xdebf, 0xbf5d, + 0xc3a4, 0xc57b, 0xf8b3, 0xa5cb, 0xcd6f, 0xa260, 0xcfd7, 0xcfd8, + 0xd2be, 0xd2bf, 0xb27e, 0xb2a1, 0xdaab, 0xdec2, 0xdec1, 0xdec0, + 0xe2d5, 0xe2d6, 0xe2d7, 0xbac2, 0xe6ad, 0xe6ac, 0xea69, 0xbf5e, + 0xbf5f, 0xed72, 0xed6f, 0xed70, 0xed71, 0xf049, 0xf048, 0xc27c, + 0xf277, 0xf5de, 0xa5cc, 0xacc6, 0xb2a2, 0xdec3, 0xa5cd, 0xd2c0, + 0xb2a3, 0xb563, 0xb564, 0xa5ce, 0xa5cf, 0xca46, 0xa86a, 0xa869, + 0xacc7, 0xcfd9, 0xdaac, 0xa5d0, 0xa5d1, 0xa5d2, 0xa5d3, 0xa86b, + 0xa86c, 0xcb6e, 0xcb6d, 0xaab6, 0xcd72, 0xcd70, 0xcd71, 0xcfda, + 0xcfdb, 0xaccb, 0xacc9, 0xacca, 0xacc8, 0xaf60, 0xaf64, 0xaf63, + 0xd2c1, 0xaf62, 0xaf61, 0xd2c2, 0xb2a6, 0xd67b, 0xd67a, 0xb2a4, + 0xb2a5, 0xb566, 0xb565, 0xdaae, 0xdaad, 0xb2a7, 0xb7ed, 0xdec5, + 0xb7ee, 0xdec4, 0xe2d8, 0xe6ae, 0xbd42, 0xea6a, 0xed73, 0xc3a6, + 0xc3a5, 0xc57c, 0xa5d4, 0xcd73, 0xb2a8, 0xe2d9, 0xbac3, 0xcb6f, + 0xcb70, 0xcd74, 0xaab8, 0xaab9, 0xaab7, 0xaccf, 0xacd0, 0xaccd, + 0xacce, 0xcfdc, 0xcfdd, 0xaccc, 0xd2c3, 0xaf68, 0xaf69, 0xb2ab, + 0xd2c9, 0xaf6e, 0xaf6c, 0xd2ca, 0xd2c5, 0xaf6b, 0xaf6a, 0xaf65, + 0xd2c8, 0xd2c7, 0xd2c4, 0xaf6d, 0xd2c6, 0xaf66, 0xaf67, 0xb2ac, + 0xd6a1, 0xd6a2, 0xb2ad, 0xd67c, 0xd67e, 0xd6a4, 0xd6a3, 0xd67d, + 0xb2a9, 0xb2aa, 0xdab6, 0xb56b, 0xb56a, 0xdab0, 0xb568, 0xdab3, + 0xb56c, 0xdab4, 0xb56d, 0xdab1, 0xb567, 0xb569, 0xdab5, 0xdab2, + 0xdaaf, 0xded2, 0xdec7, 0xb7f0, 0xb7f3, 0xb7f2, 0xb7f7, 0xb7f6, + 0xded3, 0xded1, 0xdeca, 0xdece, 0xdecd, 0xb7f4, 0xded0, 0xdecc, + 0xded4, 0xdecb, 0xb7f5, 0xb7ef, 0xb7f1, 0xdec9, 0xe2db, 0xbac7, + 0xe2df, 0xbac6, 0xe2dc, 0xbac5, 0xdec8, 0xdecf, 0xe2de, 0xbac8, + 0xe2e0, 0xe2dd, 0xe2da, 0xe6b1, 0xe6b5, 0xe6b7, 0xe6b3, 0xe6b2, + 0xe6b0, 0xbd45, 0xbd43, 0xbd48, 0xbd49, 0xe6b4, 0xbd46, 0xe6af, + 0xbd47, 0xbac4, 0xe6b6, 0xbd44, 0xea6c, 0xea6b, 0xea73, 0xea6d, + 0xea72, 0xea6f, 0xbf60, 0xea71, 0xbf61, 0xbf62, 0xea70, 0xea6e, + 0xc0f8, 0xed74, 0xc0f7, 0xed77, 0xed75, 0xed76, 0xc0f9, 0xf04d, + 0xc2a1, 0xf04e, 0xc27d, 0xf04f, 0xc27e, 0xf04c, 0xf050, 0xf04a, + 0xc3a7, 0xf278, 0xc3a8, 0xc46f, 0xf04b, 0xc470, 0xc4ee, 0xf5df, + 0xc57e, 0xf6f4, 0xc57d, 0xf7ea, 0xc5f5, 0xc5f6, 0xf9cc, 0xacd1, + 0xcfde, 0xb56e, 0xb56f, 0xa5d5, 0xa6ca, 0xca47, 0xcb71, 0xa86d, + 0xaaba, 0xacd2, 0xacd3, 0xacd4, 0xd6a6, 0xd2cb, 0xaf6f, 0xb2ae, + 0xd6a5, 0xdab8, 0xb571, 0xdab7, 0xb570, 0xded5, 0xbd4a, 0xe6bb, + 0xe6b8, 0xe6b9, 0xe6ba, 0xed78, 0xf051, 0xf471, 0xf470, 0xf6f5, + 0xa5d6, 0xcd75, 0xaf70, 0xb572, 0xded6, 0xe2e1, 0xbd4b, 0xea74, + 0xf052, 0xf472, 0xa5d7, 0xaabb, 0xacd7, 0xcfdf, 0xacd8, 0xacd6, + 0xacd5, 0xd2cc, 0xaf71, 0xaf72, 0xaf73, 0xb2b0, 0xd6a7, 0xb2af, + 0xdab9, 0xb2b1, 0xb573, 0xded7, 0xb7f8, 0xb7f9, 0xbac9, 0xbaca, + 0xbd4c, 0xbf64, 0xea75, 0xbf63, 0xed79, 0xc0fa, 0xf053, 0xf473, + 0xa5d8, 0xa86e, 0xcd78, 0xcd77, 0xaabc, 0xcd76, 0xaabd, 0xcd79, + 0xcfe5, 0xacdb, 0xacda, 0xcfe7, 0xcfe6, 0xacdf, 0xacde, 0xacd9, + 0xcfe1, 0xcfe2, 0xcfe3, 0xace0, 0xcfe0, 0xacdc, 0xcfe4, 0xacdd, + 0xd2cf, 0xd2d3, 0xd2d1, 0xd2d0, 0xd2d4, 0xd2d5, 0xd2d6, 0xd2ce, + 0xd2cd, 0xaf75, 0xaf76, 0xd2d7, 0xd2d2, 0xd6b0, 0xd2d8, 0xaf77, + 0xaf74, 0xd6aa, 0xd6a9, 0xd6ab, 0xd6ac, 0xd6ae, 0xd6ad, 0xd6b2, + 0xb2b5, 0xb2b2, 0xb2b6, 0xd6a8, 0xb2b7, 0xd6b1, 0xb2b4, 0xd6af, + 0xb2b3, 0xdabc, 0xdabe, 0xdaba, 0xdabb, 0xdabf, 0xdac1, 0xdac2, + 0xdabd, 0xdac0, 0xb574, 0xdedb, 0xdee0, 0xded8, 0xdedc, 0xdee1, + 0xdedd, 0xb7fa, 0xb843, 0xb7fd, 0xded9, 0xdeda, 0xbace, 0xb846, + 0xb7fe, 0xb844, 0xb7fc, 0xdedf, 0xb845, 0xdede, 0xb841, 0xb7fb, + 0xb842, 0xdee2, 0xe2e6, 0xe2e8, 0xb840, 0xe2e3, 0xbacc, 0xe2e9, + 0xbacd, 0xe2e7, 0xe2e2, 0xe2e5, 0xe2ea, 0xbacb, 0xe2e4, 0xbd4e, + 0xe6bf, 0xe6be, 0xbd51, 0xbd4f, 0xe6bc, 0xbd4d, 0xe6bd, 0xbd50, + 0xea7d, 0xeaa1, 0xea7e, 0xea76, 0xea7a, 0xea79, 0xea77, 0xbf66, + 0xbf67, 0xbf65, 0xea78, 0xea7b, 0xea7c, 0xbf68, 0xc140, 0xeda3, + 0xc0fc, 0xed7b, 0xc0fe, 0xc141, 0xc0fd, 0xeda2, 0xed7c, 0xc0fb, + 0xeda1, 0xed7a, 0xed7e, 0xed7d, 0xf055, 0xc2a4, 0xc2a5, 0xc2a2, + 0xc2a3, 0xf054, 0xf27b, 0xc3a9, 0xf279, 0xf27a, 0xf474, 0xf477, + 0xf475, 0xf476, 0xf5e0, 0xc4ef, 0xf7eb, 0xf8b4, 0xc5f7, 0xf8f8, + 0xf8f9, 0xc666, 0xa5d9, 0xace1, 0xdac3, 0xdee3, 0xa5da, 0xa86f, + 0xaabe, 0xcfe8, 0xcfe9, 0xaf78, 0xdac4, 0xb575, 0xb847, 0xc142, + 0xeda4, 0xf27c, 0xf478, 0xa5db, 0xcda1, 0xcd7a, 0xcd7c, 0xcd7e, + 0xcd7d, 0xcd7b, 0xaabf, 0xace2, 0xcff2, 0xcfed, 0xcfea, 0xcff1, + 0xace4, 0xace5, 0xcff0, 0xcfef, 0xcfee, 0xcfeb, 0xcfec, 0xcff3, + 0xace3, 0xaf7c, 0xafa4, 0xafa3, 0xd2e1, 0xd2db, 0xd2d9, 0xafa1, + 0xd6b9, 0xaf7a, 0xd2de, 0xd2e2, 0xd2e4, 0xd2e0, 0xd2da, 0xafa2, + 0xd2df, 0xd2dd, 0xaf79, 0xd2e5, 0xafa5, 0xd2e3, 0xaf7d, 0xd2dc, + 0xaf7e, 0xaf7b, 0xb2b9, 0xd6ba, 0xd6b3, 0xd6b5, 0xd6b7, 0xd6b8, + 0xd6b6, 0xb2ba, 0xd6bb, 0xd6b4, 0xdac8, 0xb576, 0xdad0, 0xdac5, + 0xdad1, 0xdac6, 0xdac7, 0xdacf, 0xdace, 0xdacb, 0xb2b8, 0xb577, + 0xdac9, 0xdacc, 0xb578, 0xdacd, 0xdaca, 0xdeee, 0xdef2, 0xb84e, + 0xe2f0, 0xb851, 0xdef0, 0xdeed, 0xdee8, 0xdeea, 0xdeeb, 0xdee4, + 0xb84d, 0xb84c, 0xb848, 0xdee7, 0xb84f, 0xb850, 0xdee6, 0xdee9, + 0xdef1, 0xb84a, 0xb84b, 0xdeef, 0xdee5, 0xe2f2, 0xbad0, 0xe2f4, + 0xdeec, 0xe2f6, 0xbad4, 0xe2f7, 0xe2f3, 0xbad1, 0xe2ef, 0xbad3, + 0xe2ec, 0xe2f1, 0xe2f5, 0xe2ee, 0xb849, 0xe2eb, 0xbad2, 0xe2ed, + 0xbd54, 0xe6c1, 0xbd58, 0xbd56, 0xbacf, 0xe6c8, 0xe6c9, 0xbd53, + 0xe6c7, 0xe6ca, 0xbd55, 0xbd52, 0xe6c3, 0xe6c0, 0xe6c5, 0xe6c2, + 0xbd59, 0xe6c4, 0xe6c6, 0xbd57, 0xbf6a, 0xeaa8, 0xeaa2, 0xeaa6, + 0xeaac, 0xeaad, 0xeaa9, 0xeaaa, 0xeaa7, 0xeaa4, 0xbf6c, 0xbf69, + 0xeaa3, 0xeaa5, 0xbf6b, 0xeaab, 0xc146, 0xedaa, 0xeda5, 0xc145, + 0xc143, 0xedac, 0xc144, 0xeda8, 0xeda9, 0xeda6, 0xedad, 0xf056, + 0xc147, 0xeda7, 0xedae, 0xedab, 0xf05a, 0xf057, 0xc2a6, 0xf05b, + 0xf05d, 0xf05c, 0xf058, 0xf059, 0xf2a3, 0xc3aa, 0xf27e, 0xf2a2, + 0xf27d, 0xf2a4, 0xf2a1, 0xf47a, 0xf47d, 0xf479, 0xc471, 0xf47b, + 0xf47c, 0xf47e, 0xc472, 0xc474, 0xc473, 0xf5e1, 0xf5e3, 0xf5e2, + 0xf6f6, 0xf8b5, 0xf8fa, 0xa5dc, 0xcb72, 0xaac0, 0xcda3, 0xaac1, + 0xaac2, 0xcda2, 0xcff8, 0xcff7, 0xace6, 0xace9, 0xace8, 0xace7, + 0xcff4, 0xcff6, 0xcff5, 0xd2e8, 0xafa7, 0xd2ec, 0xd2eb, 0xd2ea, + 0xd2e6, 0xafa6, 0xafaa, 0xafad, 0xafae, 0xd2e7, 0xd2e9, 0xafac, + 0xafab, 0xafa9, 0xafa8, 0xd6c2, 0xd6c0, 0xd6bc, 0xb2bb, 0xd6bd, + 0xb2bc, 0xd6be, 0xd6bf, 0xd6c1, 0xb2bd, 0xdad5, 0xdad4, 0xdad3, + 0xdad2, 0xdef6, 0xb852, 0xdef3, 0xdef5, 0xb853, 0xb854, 0xdef4, + 0xe341, 0xe2f9, 0xe2fa, 0xbad7, 0xbad5, 0xbad6, 0xe343, 0xe342, + 0xe2fe, 0xe2fd, 0xe2fc, 0xe2fb, 0xe340, 0xe2f8, 0xe6cb, 0xe6d0, + 0xe6ce, 0xe6cd, 0xe6cc, 0xe6cf, 0xeaae, 0xbf6d, 0xc148, 0xedb0, + 0xc149, 0xedaf, 0xf05f, 0xf05e, 0xc2a7, 0xf2a5, 0xc3ab, 0xf4a1, + 0xc5a1, 0xf6f7, 0xf8b7, 0xf8b6, 0xc9a8, 0xacea, 0xaceb, 0xd6c3, + 0xb856, 0xa5dd, 0xa872, 0xa871, 0xa870, 0xcda4, 0xaac4, 0xaac3, + 0xacee, 0xcffa, 0xcffd, 0xcffb, 0xacec, 0xaced, 0xcff9, 0xcffc, + 0xafb5, 0xd2f3, 0xd2f5, 0xd2f4, 0xafb2, 0xd2ef, 0xafb0, 0xafaf, + 0xafb3, 0xafb1, 0xafb4, 0xd2f2, 0xd2ed, 0xd2ee, 0xd2f1, 0xd2f0, + 0xd6c6, 0xd6c7, 0xd6c5, 0xd6c4, 0xb2be, 0xb57d, 0xdad6, 0xdad8, + 0xdada, 0xb57c, 0xb57a, 0xdad7, 0xb57b, 0xdad9, 0xb579, 0xdf41, + 0xdef7, 0xdefa, 0xdefe, 0xb85a, 0xdefc, 0xdefb, 0xdef8, 0xdef9, + 0xb858, 0xdf40, 0xb857, 0xb85c, 0xb85b, 0xb859, 0xdefd, 0xe349, + 0xe348, 0xe344, 0xbad8, 0xe347, 0xe346, 0xbad9, 0xbd5e, 0xe6d2, + 0xbd5f, 0xbd5b, 0xbd5d, 0xbd5a, 0xbd5c, 0xeaaf, 0xbf70, 0xeab1, + 0xeab0, 0xe345, 0xbf72, 0xbf71, 0xbf6e, 0xbf6f, 0xedb5, 0xedb3, + 0xc14a, 0xedb4, 0xedb6, 0xedb2, 0xedb1, 0xf060, 0xc2aa, 0xc2a8, + 0xc2a9, 0xf2a6, 0xf2a7, 0xc3ad, 0xc3ac, 0xf4a3, 0xf4a4, 0xf4a2, + 0xf6f8, 0xf6f9, 0xa5de, 0xca48, 0xa873, 0xcda5, 0xaac6, 0xaac5, + 0xcda6, 0xd040, 0xacef, 0xcffe, 0xacf0, 0xafb6, 0xd2f8, 0xd2f6, + 0xd2fc, 0xafb7, 0xd2f7, 0xd2fb, 0xd2f9, 0xd2fa, 0xd6c8, 0xd6ca, + 0xb2bf, 0xd6c9, 0xb2c0, 0xb5a2, 0xb5a1, 0xb57e, 0xdadb, 0xdf44, + 0xb85d, 0xb85e, 0xdf43, 0xdf42, 0xe34a, 0xbadb, 0xbada, 0xe34b, + 0xe34c, 0xbd61, 0xbd60, 0xeab5, 0xe6d3, 0xe6d5, 0xe6d4, 0xeab4, + 0xeab2, 0xeab6, 0xeab3, 0xbf73, 0xedb7, 0xc14b, 0xedb8, 0xedb9, + 0xc2ab, 0xc2ac, 0xc475, 0xc5d1, 0xa5df, 0xd041, 0xd2fd, 0xafb8, + 0xb3ba, 0xb3b9, 0xb5a4, 0xdadd, 0xb5a3, 0xdadc, 0xdf45, 0xbadc, + 0xe34d, 0xbadd, 0xc476, 0xf4a5, 0xa6cb, 0xaac7, 0xcda7, 0xacf2, + 0xacf1, 0xd042, 0xd043, 0xd340, 0xd342, 0xafb9, 0xd344, 0xd347, + 0xd345, 0xd346, 0xd343, 0xd2fe, 0xafba, 0xd348, 0xd341, 0xd6d3, + 0xb2c6, 0xd6dc, 0xb2c3, 0xd6d5, 0xb2c7, 0xb2c1, 0xd6d0, 0xd6dd, + 0xd6d1, 0xd6ce, 0xb2c5, 0xb2c2, 0xd6d4, 0xd6d7, 0xb2c4, 0xd6d8, + 0xb2c8, 0xd6d9, 0xd6cf, 0xd6d6, 0xd6da, 0xd6d2, 0xd6cd, 0xd6cb, + 0xd6db, 0xdadf, 0xdae4, 0xdae0, 0xdae6, 0xb5a7, 0xd6cc, 0xdae1, + 0xb5a5, 0xdade, 0xb5ac, 0xdae2, 0xb5ab, 0xdae3, 0xb5ad, 0xb5a8, + 0xb5ae, 0xb5a9, 0xb5aa, 0xb5a6, 0xdae5, 0xb861, 0xdf50, 0xdf53, + 0xdf47, 0xdf4c, 0xdf46, 0xb863, 0xdf4a, 0xdf48, 0xb862, 0xdf4f, + 0xdf4e, 0xdf4b, 0xdf4d, 0xdf49, 0xbae1, 0xdf52, 0xb85f, 0xdf51, + 0xe35d, 0xbae8, 0xe358, 0xbae7, 0xe34e, 0xe350, 0xbae0, 0xe355, + 0xe354, 0xe357, 0xbae5, 0xe352, 0xe351, 0xbae4, 0xbadf, 0xe353, + 0xbae2, 0xe359, 0xe35b, 0xe356, 0xe34f, 0xbae3, 0xbd69, 0xbade, + 0xe35c, 0xe6d9, 0xbd62, 0xe6db, 0xbd63, 0xbd65, 0xe6de, 0xe6d6, + 0xbae6, 0xe6dc, 0xe6d8, 0xb860, 0xbd68, 0xbd64, 0xbd66, 0xbd67, + 0xbf76, 0xe6dd, 0xe6d7, 0xbd6a, 0xe6da, 0xeac0, 0xeabb, 0xeac5, + 0xbf74, 0xeabd, 0xbf78, 0xeac3, 0xeaba, 0xeab7, 0xeac6, 0xc151, + 0xbf79, 0xeac2, 0xeab8, 0xbf77, 0xeabc, 0xbf7b, 0xeab9, 0xeabe, + 0xbf7a, 0xeac1, 0xeac4, 0xedcb, 0xedcc, 0xedbc, 0xedc3, 0xedc1, + 0xc14f, 0xedc8, 0xeabf, 0xedbf, 0xedc9, 0xc14e, 0xedbe, 0xedbd, + 0xedc7, 0xedc4, 0xedc6, 0xedba, 0xedca, 0xc14c, 0xedc5, 0xedce, + 0xedc2, 0xc150, 0xc14d, 0xedc0, 0xedbb, 0xedcd, 0xbf75, 0xf063, + 0xf061, 0xf067, 0xc2b0, 0xf065, 0xf064, 0xc2b2, 0xf06a, 0xc2b1, + 0xf06b, 0xf068, 0xc2ae, 0xf069, 0xf062, 0xc2af, 0xc2ad, 0xf2ab, + 0xf066, 0xf06c, 0xf2a8, 0xc3b2, 0xc3b0, 0xf2aa, 0xf2ac, 0xf2a9, + 0xc3b1, 0xc3ae, 0xc3af, 0xc3b3, 0xc478, 0xf4aa, 0xf4a9, 0xf4a7, + 0xf4a6, 0xf4a8, 0xc477, 0xc479, 0xc4f0, 0xf5e5, 0xf5e4, 0xf6fa, + 0xf6fc, 0xf6fe, 0xf6fd, 0xf6fb, 0xc5a3, 0xc5a2, 0xc5d3, 0xc5d2, + 0xc5d4, 0xf7ed, 0xf7ec, 0xf8fb, 0xf8b8, 0xf8fc, 0xc658, 0xc659, + 0xf96d, 0xc67e, 0xa6cc, 0xcda8, 0xd045, 0xd046, 0xd044, 0xacf3, + 0xd047, 0xd048, 0xd049, 0xd349, 0xd34f, 0xd34d, 0xafbb, 0xd34b, + 0xd34c, 0xd34e, 0xd34a, 0xb2c9, 0xd6de, 0xb2cb, 0xd6e0, 0xb2ca, + 0xd6df, 0xdae8, 0xb5af, 0xdaea, 0xdae7, 0xd6e1, 0xb5b0, 0xdae9, + 0xdf56, 0xb864, 0xdf54, 0xb865, 0xdf55, 0xb866, 0xbae9, 0xe361, + 0xe35e, 0xe360, 0xbaea, 0xbaeb, 0xe35f, 0xe6df, 0xe6e0, 0xbd6b, + 0xe6e2, 0xe6e1, 0xa261, 0xeaca, 0xeacb, 0xeac7, 0xeac8, 0xbf7c, + 0xbf7d, 0xeac9, 0xc157, 0xc153, 0xc158, 0xc154, 0xc156, 0xc152, + 0xc155, 0xc2b3, 0xedcf, 0xf2ae, 0xf2ad, 0xf4ab, 0xc47a, 0xc47b, + 0xf741, 0xf5e6, 0xf740, 0xf8fd, 0xf9a4, 0xa6cd, 0xa874, 0xcda9, + 0xaac8, 0xacf6, 0xd04c, 0xacf4, 0xd04a, 0xacf9, 0xacf5, 0xacfa, + 0xacf8, 0xd04b, 0xacf7, 0xafbf, 0xafbe, 0xd35a, 0xafc7, 0xd353, + 0xd359, 0xafc3, 0xd352, 0xd358, 0xd356, 0xafc2, 0xafc4, 0xd355, + 0xafbd, 0xd354, 0xafc8, 0xafc5, 0xafc9, 0xafc6, 0xd351, 0xd350, + 0xd357, 0xafc0, 0xafbc, 0xafc1, 0xd6f0, 0xd6e9, 0xb5b5, 0xd6e8, + 0xb2cf, 0xb2d6, 0xb2d3, 0xb2d9, 0xb2d8, 0xb2d4, 0xd6e2, 0xd6e5, + 0xd6e4, 0xb2d0, 0xd6e6, 0xd6ef, 0xb2d1, 0xd6e3, 0xd6ec, 0xd6ed, + 0xb2d2, 0xd6ea, 0xb2d7, 0xb2cd, 0xb2d5, 0xd6e7, 0xb2cc, 0xd6eb, + 0xd6ee, 0xdafb, 0xdaf2, 0xb5b2, 0xdaf9, 0xdaf6, 0xdaee, 0xdaf7, + 0xb5b4, 0xdaef, 0xdaeb, 0xb86c, 0xdaf4, 0xb5b1, 0xdafa, 0xb5b8, + 0xb5ba, 0xdaed, 0xb5b9, 0xdaf0, 0xb5b3, 0xdaf8, 0xdaf1, 0xdaf5, + 0xdaf3, 0xb5b6, 0xdaec, 0xb5bb, 0xb2ce, 0xb5b7, 0xb5bc, 0xb868, + 0xdf5d, 0xdf5f, 0xdf61, 0xdf65, 0xdf5b, 0xdf59, 0xb86a, 0xdf60, + 0xdf64, 0xdf5c, 0xdf58, 0xdf57, 0xdf62, 0xdf5a, 0xdf5e, 0xb86b, + 0xb869, 0xdf66, 0xb867, 0xdf63, 0xe372, 0xbaee, 0xe36a, 0xbd78, + 0xe374, 0xbaf1, 0xe378, 0xbaf7, 0xe365, 0xe375, 0xe362, 0xe377, + 0xe366, 0xbafe, 0xbafb, 0xe376, 0xe370, 0xbaed, 0xbaf5, 0xbaf4, + 0xbaf3, 0xbaf9, 0xe363, 0xbafa, 0xe371, 0xbaf6, 0xbaec, 0xe373, + 0xbaef, 0xbaf0, 0xbaf8, 0xe368, 0xe367, 0xe364, 0xe36c, 0xe369, + 0xe36d, 0xbafd, 0xe379, 0xbaf2, 0xe36e, 0xe36f, 0xe36b, 0xbafc, + 0xe6e7, 0xbd70, 0xbd79, 0xbd75, 0xe6e4, 0xbd72, 0xbd76, 0xe6f0, + 0xbd6c, 0xe6e8, 0xbd74, 0xe6eb, 0xe6e6, 0xbd73, 0xbd77, 0xe6e5, + 0xbd71, 0xe6ef, 0xbd6e, 0xe6ee, 0xe6ed, 0xbd7a, 0xe572, 0xbd6d, + 0xe6ec, 0xe6e3, 0xbd7b, 0xe6ea, 0xbd6f, 0xe6e9, 0xbfa2, 0xbfa7, + 0xbf7e, 0xead8, 0xeacf, 0xeadb, 0xead3, 0xead9, 0xbfa8, 0xbfa1, + 0xeacc, 0xead2, 0xeadc, 0xead5, 0xeada, 0xeace, 0xead6, 0xbfa3, + 0xead4, 0xbfa6, 0xbfa5, 0xead0, 0xead1, 0xeacd, 0xead7, 0xbfa4, + 0xeade, 0xeadd, 0xedda, 0xedd6, 0xc15f, 0xedd0, 0xc159, 0xc169, + 0xeddc, 0xc161, 0xc15d, 0xedd3, 0xc164, 0xc167, 0xedde, 0xc15c, + 0xedd5, 0xc165, 0xede0, 0xeddd, 0xedd1, 0xc160, 0xc15a, 0xc168, + 0xedd8, 0xc163, 0xedd2, 0xc15e, 0xeddf, 0xc162, 0xc15b, 0xedd9, + 0xc166, 0xedd7, 0xeddb, 0xf06e, 0xf074, 0xc2b9, 0xf077, 0xc2b4, + 0xc2b5, 0xf06f, 0xf076, 0xf071, 0xc2ba, 0xc2b7, 0xf06d, 0xc2b6, + 0xf073, 0xf075, 0xc2b8, 0xf072, 0xf070, 0xf2b8, 0xc3b7, 0xc3b8, + 0xc3b4, 0xc3b5, 0xf2b4, 0xf2b2, 0xf2b6, 0xc3ba, 0xf2b7, 0xf2b0, + 0xf2af, 0xf2b3, 0xf2b1, 0xc3b6, 0xf2b5, 0xf4ac, 0xc47e, 0xc47d, + 0xf4ad, 0xf4af, 0xf4ae, 0xc4a1, 0xf5eb, 0xf5e8, 0xf5e9, 0xf5e7, + 0xf5ea, 0xc4f2, 0xf5ec, 0xc4f1, 0xf742, 0xc5d5, 0xc5d7, 0xf7ee, + 0xc5d6, 0xf8b9, 0xf940, 0xf942, 0xf8fe, 0xf941, 0xc66c, 0xa6ce, + 0xacfb, 0xd26f, 0xafca, 0xb2da, 0xdafc, 0xdafd, 0xeadf, 0xc16a, + 0xede1, 0xc2bb, 0xf2ba, 0xf2b9, 0xc4a2, 0xf5ed, 0xf743, 0xc5f8, + 0xca49, 0xaac9, 0xa875, 0xd04d, 0xd360, 0xd35b, 0xd35f, 0xd35d, + 0xafcb, 0xd35e, 0xd35c, 0xd6f1, 0xdafe, 0xdb40, 0xdf69, 0xdf6a, + 0xb86e, 0xb86f, 0xdf68, 0xdf6b, 0xdf67, 0xb86d, 0xbb40, 0xb870, + 0xe37a, 0xbd7c, 0xe6f1, 0xbd7d, 0xbfa9, 0xeae2, 0xeae0, 0xeae1, + 0xede4, 0xede3, 0xede2, 0xf2bb, 0xc3b9, 0xf2bc, 0xf744, 0xc5f9, + 0xf8ba, 0xa6cf, 0xaacb, 0xaaca, 0xd04f, 0xacfc, 0xd04e, 0xd362, + 0xafcc, 0xd6f2, 0xd361, 0xb2dc, 0xd6f5, 0xd6f3, 0xd6f4, 0xb2db, + 0xdb42, 0xdb43, 0xdb41, 0xb873, 0xdf6d, 0xdf6c, 0xdf6e, 0xb872, + 0xb871, 0xe6f2, 0xe6f4, 0xbd7e, 0xe6f3, 0xeae3, 0xbfaa, 0xf079, + 0xf078, 0xc3bb, 0xf2bd, 0xc3bd, 0xc3bc, 0xf4b0, 0xf5ee, 0xc4f3, + 0xa6d0, 0xd050, 0xacfd, 0xd365, 0xafce, 0xd364, 0xd363, 0xafcd, + 0xd6fb, 0xd6fd, 0xd6f6, 0xd6f7, 0xb2dd, 0xd6f8, 0xb2de, 0xd6fc, + 0xd6f9, 0xd6fa, 0xb2df, 0xb5be, 0xb5bf, 0xdb44, 0xdf6f, 0xdf70, + 0xe37e, 0xbb43, 0xbb41, 0xbb42, 0xe37b, 0xe37c, 0xe37d, 0xe6f9, + 0xe6fa, 0xbda1, 0xe6f7, 0xe6f6, 0xe6f8, 0xe6f5, 0xbfad, 0xeae4, + 0xbfab, 0xbfac, 0xede6, 0xc16b, 0xede5, 0xefa8, 0xf07a, 0xf07b, + 0xc2bc, 0xc2bd, 0xc16c, 0xf2be, 0xf2bf, 0xf4b1, 0xc4a3, 0xa6d1, + 0xa6d2, 0xacfe, 0xaacc, 0xafcf, 0xd051, 0xb5c0, 0xa6d3, 0xad41, + 0xd052, 0xd053, 0xad40, 0xad42, 0xa6d4, 0xd054, 0xafd1, 0xd366, + 0xafd3, 0xafd0, 0xafd2, 0xd741, 0xb2e0, 0xd740, 0xd6fe, 0xdf71, + 0xe3a1, 0xbda2, 0xbfae, 0xeae6, 0xeae5, 0xede7, 0xf5ef, 0xa6d5, + 0xcb73, 0xcdaa, 0xad43, 0xd055, 0xd368, 0xafd4, 0xd367, 0xafd5, + 0xd743, 0xb2e2, 0xd742, 0xd744, 0xb2e1, 0xdb46, 0xdb47, 0xdb45, + 0xb5c1, 0xb874, 0xb875, 0xbb45, 0xe3a3, 0xe3a2, 0xbb44, 0xe6fb, + 0xe6fc, 0xeae7, 0xc170, 0xc16f, 0xc16d, 0xc16e, 0xc171, 0xf07c, + 0xc2bf, 0xc2be, 0xf2c0, 0xf4b2, 0xc5a5, 0xc5a4, 0xa6d6, 0xd1fb, + 0xb877, 0xb5c2, 0xb876, 0xbb46, 0xa6d7, 0xc9a9, 0xa6d8, 0xa6d9, + 0xcdab, 0xcb76, 0xcb77, 0xa877, 0xcb74, 0xa876, 0xa879, 0xcb75, + 0xa87b, 0xa87a, 0xcb78, 0xa878, 0xaad1, 0xaacf, 0xcdad, 0xaace, + 0xaad3, 0xaad5, 0xaad2, 0xcdb0, 0xcdac, 0xaad6, 0xaad0, 0xa87c, + 0xaad4, 0xcdaf, 0xcdae, 0xaacd, 0xd05b, 0xad47, 0xad48, 0xd05d, + 0xd057, 0xd05a, 0xd063, 0xd061, 0xad49, 0xd067, 0xad4c, 0xd064, + 0xd05c, 0xd059, 0xdb49, 0xd062, 0xad44, 0xd065, 0xd056, 0xd05f, + 0xad46, 0xad4b, 0xd060, 0xad4f, 0xad4d, 0xd058, 0xad4a, 0xd05e, + 0xad4e, 0xad45, 0xd066, 0xafda, 0xafe3, 0xafd8, 0xafd6, 0xd36a, + 0xafde, 0xafdb, 0xd36c, 0xafdd, 0xd36b, 0xd369, 0xd36e, 0xafe2, + 0xafe0, 0xdb48, 0xd36f, 0xd36d, 0xafd7, 0xafd9, 0xafdc, 0xafdf, + 0xafe1, 0xd74e, 0xb2e4, 0xd745, 0xd747, 0xd748, 0xd750, 0xd74c, + 0xd74a, 0xd74d, 0xd751, 0xb2e5, 0xb2e9, 0xd746, 0xd74f, 0xb2e7, + 0xb2e6, 0xd74b, 0xd749, 0xb2e3, 0xb2e8, 0xb5c8, 0xdb51, 0xdb4f, + 0xb5ca, 0xdb4a, 0xdfa1, 0xb5c9, 0xdb4e, 0xdb4b, 0xb5c5, 0xb5cb, + 0xdb50, 0xb5c7, 0xdb4d, 0xbb47, 0xb5c6, 0xdb4c, 0xb5cc, 0xb5c4, + 0xb5c3, 0xdf77, 0xdf75, 0xdf7b, 0xdf73, 0xdfa2, 0xdf78, 0xdf72, + 0xb87b, 0xb8a3, 0xdf7d, 0xdf76, 0xb87e, 0xb87c, 0xdf7e, 0xb879, + 0xb878, 0xdf79, 0xb87d, 0xb5cd, 0xdf7c, 0xdf74, 0xb87a, 0xb8a1, + 0xb8a2, 0xbb4c, 0xbb48, 0xbb4d, 0xe3a6, 0xe3a5, 0xe3a7, 0xbb4a, + 0xe3a4, 0xbb4b, 0xe3aa, 0xe3a9, 0xe3a8, 0xbb49, 0xe741, 0xe744, + 0xbda8, 0xe743, 0xbda7, 0xbda3, 0xbda4, 0xbda5, 0xe740, 0xe6fe, + 0xbda6, 0xe742, 0xe6fd, 0xeae9, 0xeaf3, 0xbfb1, 0xbfb0, 0xeaed, + 0xeaef, 0xeaea, 0xeaee, 0xeae8, 0xeaf1, 0xbfaf, 0xeaf0, 0xeaec, + 0xeaf2, 0xeaeb, 0xc174, 0xede8, 0xedee, 0xc178, 0xc17a, 0xc177, + 0xc176, 0xc175, 0xc173, 0xede9, 0xedec, 0xc172, 0xeded, 0xc179, + 0xedeb, 0xedea, 0xc2c0, 0xc2c1, 0xf0a1, 0xf07d, 0xf07e, 0xf2c2, + 0xf2c1, 0xc3be, 0xf4b4, 0xc4a4, 0xf4b3, 0xf5f0, 0xf745, 0xc5a6, + 0xf943, 0xf944, 0xc5d8, 0xa6da, 0xaad7, 0xdb52, 0xbb4e, 0xc17b, + 0xedef, 0xa6db, 0xafe5, 0xafe4, 0xdb53, 0xeaf4, 0xa6dc, 0xad50, + 0xdb54, 0xdb55, 0xdb56, 0xbb4f, 0xbfb2, 0xa6dd, 0xaad8, 0xd068, + 0xafe6, 0xd370, 0xb2ea, 0xdb57, 0xb8a4, 0xbb50, 0xbfb3, 0xc17c, + 0xc2c2, 0xf4b5, 0xa6de, 0xaad9, 0xafe7, 0xd752, 0xb5ce, 0xbb51, + 0xe3ab, 0xe745, 0xa6df, 0xb5cf, 0xdfa3, 0xbb52, 0xa6e0, 0xcdb1, + 0xd069, 0xad51, 0xd372, 0xafea, 0xafe8, 0xafe9, 0xafeb, 0xd371, + 0xd757, 0xd754, 0xd756, 0xb2eb, 0xb2ed, 0xb2ec, 0xd753, 0xb2ee, + 0xd755, 0xdb58, 0xdb59, 0xdb5a, 0xdfa6, 0xdfa7, 0xdfa5, 0xdfa8, + 0xb8a5, 0xdfa4, 0xbb53, 0xe74a, 0xe746, 0xe749, 0xe74b, 0xe748, + 0xe747, 0xeaf5, 0xeaf6, 0xeaf7, 0xbfb4, 0xbfb5, 0xedf1, 0xedf0, + 0xedf2, 0xf0a3, 0xf0a2, 0xf2c4, 0xf2c5, 0xf2c3, 0xc4a5, 0xf4b6, + 0xf4b7, 0xf746, 0xf7ef, 0xf8bb, 0xa6e1, 0xa87d, 0xc17d, 0xa6e2, + 0xd758, 0xdb5b, 0xc641, 0xca4a, 0xca4b, 0xca4d, 0xa6e3, 0xca4e, + 0xca4c, 0xcba2, 0xcba3, 0xcb7b, 0xcba1, 0xa8a1, 0xa8a2, 0xcb7c, + 0xcb7a, 0xcb79, 0xcb7d, 0xa87e, 0xcb7e, 0xd06a, 0xcdb6, 0xaadc, + 0xcdb5, 0xcdb7, 0xaadb, 0xcdbc, 0xaadf, 0xcdb2, 0xcdc0, 0xcdc6, + 0xaae6, 0xcdc3, 0xaae3, 0xcdb9, 0xcdbf, 0xcdc1, 0xcdb4, 0xaae2, + 0xaadd, 0xcdba, 0xaae4, 0xaae7, 0xaae1, 0xaada, 0xcdbe, 0xcdb8, + 0xcdc5, 0xaae9, 0xaae5, 0xaae0, 0xcdbd, 0xafec, 0xcdbb, 0xaade, + 0xaae8, 0xcdb3, 0xcdc2, 0xcdc4, 0xad62, 0xad5c, 0xad64, 0xad61, + 0xd071, 0xd074, 0xad5d, 0xd06b, 0xad56, 0xad60, 0xad63, 0xad65, + 0xd0a2, 0xd077, 0xad55, 0xd0a1, 0xad59, 0xad57, 0xad52, 0xd06f, + 0xd07e, 0xd073, 0xd076, 0xd0a5, 0xad66, 0xd07d, 0xad5e, 0xd078, + 0xd0a4, 0xd075, 0xd079, 0xd07c, 0xd06d, 0xd0a3, 0xd07b, 0xd06c, + 0xd070, 0xad5f, 0xad5a, 0xad53, 0xad58, 0xad54, 0xad67, 0xd06e, + 0xd3a5, 0xad5b, 0xd07a, 0xce41, 0xd3a8, 0xaffa, 0xd376, 0xd3a3, + 0xd37d, 0xd3b2, 0xd3aa, 0xd37e, 0xd3a9, 0xd378, 0xd37c, 0xd3b5, + 0xaffd, 0xd3ad, 0xd3a4, 0xafed, 0xd3b3, 0xd374, 0xd3ac, 0xaffc, + 0xaff7, 0xd373, 0xaff5, 0xaff4, 0xaff9, 0xd3ab, 0xaff1, 0xaff8, + 0xd072, 0xdb5c, 0xd3a6, 0xd37a, 0xaffb, 0xd37b, 0xd3a1, 0xaffe, + 0xd375, 0xd3af, 0xd3ae, 0xd3b6, 0xaff3, 0xaff0, 0xd3b4, 0xd3b0, + 0xd3a7, 0xd3a2, 0xaff6, 0xaff2, 0xd377, 0xafee, 0xd3b1, 0xafef, + 0xd379, 0xd75e, 0xd760, 0xd765, 0xd779, 0xb2fc, 0xb2f2, 0xd75d, + 0xb2fd, 0xb2fe, 0xd768, 0xd76f, 0xd775, 0xd762, 0xd769, 0xb340, + 0xd777, 0xd772, 0xb2fa, 0xb2f8, 0xd76e, 0xd76a, 0xd75c, 0xb2ef, + 0xd761, 0xd759, 0xb2f7, 0xb2f9, 0xd766, 0xd763, 0xb2f4, 0xd773, + 0xb2f1, 0xd764, 0xd77a, 0xd76c, 0xd76b, 0xb2f0, 0xb2fb, 0xb2f3, + 0xd75a, 0xd75f, 0xd770, 0xd776, 0xb341, 0xd75b, 0xd767, 0xd76d, + 0xb2f6, 0xd778, 0xd771, 0xd774, 0xb2f5, 0xdb6c, 0xdb60, 0xb5d7, + 0xdb7d, 0xdba7, 0xdbaa, 0xb5d5, 0xdb68, 0xdba3, 0xdb69, 0xdb77, + 0xb5e2, 0xdb73, 0xb5df, 0xdb74, 0xdb5d, 0xdba4, 0xb5e8, 0xdba1, + 0xdb75, 0xdbac, 0xdb70, 0xdfc8, 0xdbaf, 0xb5e6, 0xdb6e, 0xdb7a, + 0xb5e9, 0xb5d4, 0xdb72, 0xdbad, 0xdb6b, 0xdb64, 0xdb6f, 0xdb63, + 0xdb61, 0xb5d0, 0xdba5, 0xdb6a, 0xdba8, 0xdba9, 0xb5d8, 0xb5dd, + 0xb5d9, 0xb5e1, 0xdb7e, 0xb5da, 0xdb76, 0xdb66, 0xb5d2, 0xdb5e, + 0xdba2, 0xdbab, 0xdb65, 0xb5e0, 0xdbb0, 0xdb71, 0xdb6d, 0xb5d1, + 0xb5e5, 0xdb7c, 0xb5e7, 0xdb78, 0xb5dc, 0xb5d6, 0xb5de, 0xb5d3, + 0xb5e4, 0xdb79, 0xdb67, 0xdb7b, 0xdb62, 0xdba6, 0xdbae, 0xdb5f, + 0xdfc7, 0xdfdd, 0xb855, 0xdfcc, 0xdfca, 0xdfb5, 0xb8a9, 0xdfc5, + 0xdfd9, 0xdfc1, 0xb8b1, 0xdfd8, 0xdfbf, 0xb5e3, 0xdfcf, 0xdfc0, + 0xdfd6, 0xb8b0, 0xb8a8, 0xdfaa, 0xdfb2, 0xdfcb, 0xdfc3, 0xdfdc, + 0xdfc6, 0xb8b6, 0xdfd7, 0xb8ad, 0xdfc9, 0xdfd1, 0xdfb6, 0xdfd0, + 0xdfe1, 0xdfb1, 0xdfd2, 0xdfdf, 0xdfab, 0xb5db, 0xdfb9, 0xdfb8, + 0xb8af, 0xdfbc, 0xdfbe, 0xdfcd, 0xdfde, 0xb8b2, 0xb8b3, 0xdfb0, + 0xb8ab, 0xdfb4, 0xdfda, 0xb8b4, 0xb8ac, 0xb8ae, 0xb8b5, 0xdfe0, + 0xdfd3, 0xdfce, 0xdfbb, 0xdfba, 0xb8aa, 0xdfac, 0xb8a7, 0xdfc4, + 0xdfad, 0xdfc2, 0xdfb7, 0xdfdb, 0xb8a6, 0xdfb3, 0xdfaf, 0xdfd5, + 0xdfae, 0xbb60, 0xe3d3, 0xe3c2, 0xe3ac, 0xe3ca, 0xbb58, 0xe3bb, + 0xe3c5, 0xbb5b, 0xe3be, 0xbb59, 0xe3af, 0xe3cd, 0xe3ae, 0xe3c1, + 0xe3ad, 0xe3bf, 0xe3c8, 0xe3c6, 0xe3ba, 0xe3b5, 0xe3b3, 0xe3b4, + 0xe3c7, 0xe3d2, 0xe3bc, 0xbb5a, 0xe3b7, 0xe3cb, 0xbb5d, 0xe3b6, + 0xe3b0, 0xe3c0, 0xbb61, 0xbb55, 0xbb5e, 0xe3b8, 0xe3b2, 0xbb57, + 0xdfd4, 0xbb56, 0xe3c3, 0xbb54, 0xbb63, 0xbb5c, 0xe3c4, 0xe3b9, + 0xe3b1, 0xe3cc, 0xe3bd, 0xbb62, 0xe3d0, 0xbb5f, 0xe3cf, 0xe3c9, + 0xe3ce, 0xe3d1, 0xe773, 0xe774, 0xe767, 0xe766, 0xe762, 0xbdb4, + 0xbdac, 0xe776, 0xe775, 0xdfa9, 0xe75f, 0xe763, 0xe75d, 0xe770, + 0xe761, 0xe777, 0xe75a, 0xe758, 0xe764, 0xe76e, 0xe769, 0xbdb6, + 0xe74f, 0xe76d, 0xbdb7, 0xdfbd, 0xe75b, 0xe752, 0xe755, 0xe77b, + 0xe75c, 0xe753, 0xe751, 0xe74e, 0xbdb0, 0xe765, 0xbdaf, 0xbdb3, + 0xe760, 0xe768, 0xbda9, 0xe778, 0xe77c, 0xbdab, 0xe757, 0xe76b, + 0xe76f, 0xe754, 0xe779, 0xbdb2, 0xbdb1, 0xe74c, 0xbdb5, 0xe772, + 0xe756, 0xe76a, 0xe750, 0xe75e, 0xe759, 0xbdad, 0xbdae, 0xe76c, + 0xe77d, 0xe77a, 0xe771, 0xe74d, 0xbdaa, 0xeb49, 0xeb40, 0xeb43, + 0xbfbb, 0xeb45, 0xeaf9, 0xeb41, 0xeb47, 0xbfb8, 0xbfbc, 0xbfb6, + 0xeafb, 0xeb4c, 0xeb46, 0xeafc, 0xeb55, 0xeb4f, 0xeaf8, 0xee46, + 0xeafe, 0xbfb7, 0xeb4a, 0xeb54, 0xbfbf, 0xeb51, 0xeafd, 0xeb44, + 0xeb48, 0xeb42, 0xeb56, 0xeb53, 0xeb50, 0xbfb9, 0xbfba, 0xbfbe, + 0xeafa, 0xeb57, 0xbfbd, 0xeb4d, 0xeb4b, 0xeb4e, 0xee53, 0xee40, + 0xee45, 0xee52, 0xee44, 0xedfb, 0xee41, 0xc1a2, 0xedf4, 0xee4d, + 0xee4f, 0xedf3, 0xc1a1, 0xee51, 0xee49, 0xc1a8, 0xee50, 0xee42, + 0xc1aa, 0xedf9, 0xeb52, 0xee4a, 0xee47, 0xedf5, 0xee55, 0xc1a4, + 0xc1a5, 0xedf7, 0xee48, 0xee54, 0xee4b, 0xedfd, 0xc1a7, 0xc1a3, + 0xee4c, 0xedfe, 0xee56, 0xedf8, 0xee43, 0xee4e, 0xedfa, 0xedfc, + 0xc2cb, 0xedf6, 0xc1a9, 0xc2c4, 0xc17e, 0xc1a6, 0xc2c8, 0xf0b3, + 0xf0a9, 0xf0a4, 0xf0aa, 0xf0b4, 0xf0b8, 0xf0b7, 0xc2ca, 0xc2c9, + 0xf0ab, 0xf0b9, 0xf0ae, 0xf0a6, 0xf0a8, 0xf0a7, 0xf0ad, 0xf0b2, + 0xf0a5, 0xf0ac, 0xf0b1, 0xc2c7, 0xf0af, 0xc2c5, 0xf0b0, 0xc2c3, + 0xc2c6, 0xf2d5, 0xf0b5, 0xc3c2, 0xf2cd, 0xf2d1, 0xf2c9, 0xf2cc, + 0xf2d4, 0xc3c0, 0xf2d9, 0xf2d2, 0xf2ca, 0xf2da, 0xf2d3, 0xc3c3, + 0xc3c4, 0xf2d7, 0xf2cb, 0xc3bf, 0xc3c1, 0xf2c6, 0xf2ce, 0xf2c8, + 0xf2d8, 0xf2d6, 0xf2c7, 0xf2cf, 0xf4be, 0xc3c5, 0xf2d0, 0xc4a7, + 0xc4a9, 0xc4a6, 0xf4c3, 0xf4bb, 0xf4b9, 0xf4bd, 0xf4ba, 0xf4bf, + 0xf4c1, 0xc4aa, 0xc4ac, 0xf4c0, 0xc4ad, 0xc4ab, 0xf4c2, 0xc4a8, + 0xc4f4, 0xf5f1, 0xf5f7, 0xc4f6, 0xf4bc, 0xf5f6, 0xf5fd, 0xf5f4, + 0xf5fb, 0xf5fa, 0xf4b8, 0xf5f5, 0xf0b6, 0xf5fe, 0xf5f3, 0xf5f8, + 0xf5fc, 0xf5f2, 0xf74a, 0xc4f5, 0xf5f9, 0xf7f4, 0xf74b, 0xf749, + 0xf747, 0xf748, 0xf74c, 0xc5d9, 0xf7f2, 0xf7f0, 0xf7f5, 0xf7f3, + 0xf7f6, 0xc5da, 0xf7f1, 0xf8bc, 0xf945, 0xf946, 0xf947, 0xf9c7, + 0xf9bd, 0xca4f, 0xaaea, 0xad68, 0xd3b8, 0xd3b7, 0xb040, 0xb342, + 0xd77c, 0xd77b, 0xb5ea, 0xb8b8, 0xb8b7, 0xb8b9, 0xe3d4, 0xe77e, + 0xeb58, 0xeb5a, 0xeb59, 0xc1ab, 0xee57, 0xf0ba, 0xf9a5, 0xa6e4, + 0xcdc9, 0xcdca, 0xcdc8, 0xcdc7, 0xaaeb, 0xd0a9, 0xd0a7, 0xd0a6, + 0xad69, 0xad6b, 0xad6a, 0xd0a8, 0xd3c4, 0xd3c1, 0xd3bf, 0xb041, + 0xd3c2, 0xb046, 0xd3bc, 0xd3cb, 0xd3cd, 0xd3bd, 0xb043, 0xd3ce, + 0xd3c9, 0xd3bb, 0xd3c0, 0xd3ca, 0xd3c6, 0xd3c3, 0xb048, 0xd3cc, + 0xd3be, 0xd3c7, 0xd3b9, 0xb047, 0xb044, 0xd3c5, 0xd3c8, 0xd3ba, + 0xb045, 0xb042, 0xb34c, 0xd7a5, 0xb34b, 0xd7a8, 0xd7ab, 0xb348, + 0xb346, 0xd77e, 0xd7a9, 0xd7a7, 0xd7a4, 0xd7ac, 0xd7ad, 0xd7af, + 0xd7b0, 0xd77d, 0xb345, 0xd7a2, 0xd7a1, 0xd7ae, 0xb347, 0xd7a3, + 0xb349, 0xb344, 0xd7a6, 0xb34d, 0xb34a, 0xd7aa, 0xb5f1, 0xdbbf, + 0xdbb4, 0xb5ee, 0xdfe7, 0xdbbd, 0xdbb1, 0xb5ec, 0xdbb6, 0xb5ef, + 0xdbba, 0xdbb8, 0xb5f2, 0xb5eb, 0xdbb2, 0xdbb5, 0xb5f0, 0xdbb3, + 0xdbbe, 0xdbbc, 0xdbb7, 0xdbb9, 0xdbbb, 0xb5ed, 0xdfe8, 0xdfee, + 0xdfe4, 0xdfea, 0xb8ba, 0xdfe6, 0xb8c0, 0xb8bf, 0xb8be, 0xdfed, + 0xb8c1, 0xb8c2, 0xdfe3, 0xdff0, 0xb8c3, 0xb8bd, 0xb8bc, 0xdfec, + 0xb8c4, 0xdfe2, 0xdfe5, 0xdfef, 0xdfeb, 0xe3f4, 0xe3e9, 0xb8bb, + 0xbb6a, 0xe3dd, 0xe3f2, 0xe3de, 0xbb65, 0xe3db, 0xe3e4, 0xe3dc, + 0xbb67, 0xe3d6, 0xe3f1, 0xbb68, 0xe3ee, 0xe3ef, 0xe3d7, 0xbb6d, + 0xe3e6, 0xe3e0, 0xe3e7, 0xe3da, 0xe3f3, 0xe3eb, 0xe3e5, 0xe3d5, + 0xbb69, 0xe3ec, 0xbb6c, 0xe3f0, 0xe3ea, 0xbb66, 0xe3e8, 0xe3e2, + 0xbb64, 0xe3d9, 0xe3e1, 0xe3ed, 0xe3df, 0xe3e3, 0xbdc1, 0xdfe9, + 0xe7b2, 0xe7bb, 0xe7b1, 0xe7ad, 0xe7aa, 0xbdc2, 0xe7a8, 0xbb6b, + 0xe7a1, 0xbdc0, 0xe7a7, 0xbdbf, 0xe7ac, 0xe7a9, 0xe7b9, 0xe7b4, + 0xe7ae, 0xe7b3, 0xbdbb, 0xe7ab, 0xe7be, 0xe7a2, 0xe7a3, 0xe7ba, + 0xbdbc, 0xe7bf, 0xbdbe, 0xe7c0, 0xe7b0, 0xe3d8, 0xe7b6, 0xe7af, + 0xe7b8, 0xe7b5, 0xe7a6, 0xbdb9, 0xe7bd, 0xbdba, 0xe7a4, 0xbdbd, + 0xeb64, 0xe7b7, 0xe7bc, 0xeb61, 0xbdb8, 0xbfc0, 0xeb6b, 0xeb67, + 0xeb65, 0xeb60, 0xeb6f, 0xbfc4, 0xeb5c, 0xeb68, 0xeb69, 0xeb5f, + 0xeb5e, 0xeb6c, 0xeb62, 0xeb5d, 0xeb63, 0xeb6e, 0xeb5b, 0xeb6d, + 0xeb6a, 0xbfc2, 0xbfc1, 0xbfc3, 0xeb66, 0xf0cb, 0xee59, 0xc1b1, + 0xee5d, 0xee5a, 0xee61, 0xee67, 0xee5c, 0xee70, 0xc1ae, 0xee6a, + 0xee5f, 0xee6b, 0xee66, 0xee6d, 0xee5e, 0xc1b3, 0xc1b2, 0xee60, + 0xee6e, 0xee58, 0xee6c, 0xc1ac, 0xee64, 0xee63, 0xee68, 0xee5b, + 0xc1b0, 0xc1b4, 0xee62, 0xee69, 0xc1b5, 0xee65, 0xc1ad, 0xc1af, + 0xf0c7, 0xf0c5, 0xf0cc, 0xf0c9, 0xf0cd, 0xf0be, 0xf0c6, 0xf0d1, + 0xee6f, 0xf0c2, 0xc2cf, 0xe7a5, 0xf0bd, 0xf0ca, 0xf0c4, 0xf0c1, + 0xf0bc, 0xf0bb, 0xf0d0, 0xf0c0, 0xf0bf, 0xc2cd, 0xf0c8, 0xc2cc, + 0xc2ce, 0xf0c3, 0xf0cf, 0xf2de, 0xf2df, 0xc3c9, 0xf2dc, 0xc3c6, + 0xf2e4, 0xc3ca, 0xf2e6, 0xf2db, 0xf0ce, 0xf2e8, 0xf2dd, 0xc3c7, + 0xf2e3, 0xf2e5, 0xf2e0, 0xf2e7, 0xf2e2, 0xf2e1, 0xc3c8, 0xf4c5, + 0xf4c6, 0xf4c8, 0xc4ae, 0xc4af, 0xf4c9, 0xf4c7, 0xf4c4, 0xf642, + 0xf645, 0xf641, 0xc4fa, 0xf643, 0xc4f9, 0xc4f8, 0xc4f7, 0xf644, + 0xf751, 0xf74f, 0xf74e, 0xf640, 0xf750, 0xf646, 0xf74d, 0xf7f9, + 0xf7d7, 0xf7f7, 0xc5db, 0xf7f8, 0xf7fa, 0xf8bf, 0xc5fa, 0xf8be, + 0xf8bd, 0xc5fb, 0xc65a, 0xf96e, 0xf9a7, 0xf9a6, 0xf9a8, 0xa6e5, + 0xd0aa, 0xd3cf, 0xd3d0, 0xdbc0, 0xf647, 0xf8c0, 0xa6e6, 0xad6c, + 0xd0ab, 0xd7b1, 0xb34e, 0xdbc2, 0xdbc1, 0xb5f3, 0xb8c5, 0xe7c1, + 0xbdc3, 0xbdc4, 0xbfc5, 0xc5fc, 0xa6e7, 0xd0ac, 0xaaed, 0xd0ae, + 0xd0ad, 0xad6d, 0xd3d1, 0xd3d8, 0xb049, 0xd3d6, 0xd3d4, 0xd3db, + 0xd3d2, 0xd3d3, 0xb04a, 0xb04e, 0xd3dc, 0xb04d, 0xd3da, 0xd3d7, + 0xd3d5, 0xb04b, 0xb04c, 0xd3d9, 0xb350, 0xd7b2, 0xb355, 0xd7c2, + 0xb354, 0xd7c4, 0xd7b8, 0xb352, 0xd7c3, 0xd7b3, 0xb353, 0xd7bf, + 0xd7bb, 0xd7bd, 0xd7b7, 0xd7be, 0xb34f, 0xd7ba, 0xd7b9, 0xd7b5, + 0xd7c0, 0xd7bc, 0xd7b4, 0xd7b6, 0xb351, 0xd7c1, 0xb5f6, 0xdbcd, + 0xdbc9, 0xdbcb, 0xdbc6, 0xdbc5, 0xdbc3, 0xdbca, 0xdbcc, 0xdbc8, + 0xdbc7, 0xb5f4, 0xb5f5, 0xdbcf, 0xb8cd, 0xdff2, 0xdff8, 0xdff3, + 0xdff4, 0xdff9, 0xb8cf, 0xb8c7, 0xb8ce, 0xdff1, 0xdbc4, 0xb8ca, + 0xb8c8, 0xdff7, 0xdff6, 0xb8c9, 0xb8cb, 0xdff5, 0xb8c6, 0xb8cc, + 0xe3f6, 0xbb74, 0xe442, 0xe441, 0xe3fb, 0xbb76, 0xe440, 0xe3f7, + 0xe3f8, 0xbb6e, 0xbb70, 0xe3fd, 0xe3f5, 0xbb72, 0xbb71, 0xe3f9, + 0xe3fe, 0xe3fc, 0xbb73, 0xe3fa, 0xdbce, 0xbb6f, 0xe7c2, 0xe7c9, + 0xbdc6, 0xe7cd, 0xbdca, 0xe7c5, 0xe7c3, 0xe7cc, 0xbdc5, 0xe7cb, + 0xbdc7, 0xbdc8, 0xe7c4, 0xbdc9, 0xe7ca, 0xe7c6, 0xe7c7, 0xe7c8, + 0xbb75, 0xeb70, 0xeb7c, 0xbfca, 0xeb77, 0xeb79, 0xbfc8, 0xeb71, + 0xeb75, 0xeb78, 0xbfc6, 0xbfc9, 0xeb7b, 0xeb73, 0xeb74, 0xeb7a, + 0xeb72, 0xeb76, 0xbfc7, 0xee72, 0xee71, 0xc1b7, 0xee77, 0xc1b9, + 0xc1b6, 0xee73, 0xc1ba, 0xee74, 0xee75, 0xee78, 0xc1b8, 0xf0d6, + 0xf0d9, 0xf0d3, 0xf0d5, 0xf0d4, 0xf0d7, 0xf0d8, 0xee76, 0xf0d2, + 0xc3cd, 0xf2ec, 0xf2ef, 0xf2f1, 0xf2ea, 0xf2eb, 0xf2ee, 0xf2f0, + 0xc3ce, 0xc3cc, 0xc3cb, 0xf2ed, 0xf2e9, 0xf4ca, 0xc4b0, 0xf4cb, + 0xf649, 0xc4fb, 0xf64b, 0xc4fc, 0xf648, 0xf64a, 0xc5a8, 0xf752, + 0xc5a7, 0xf7fd, 0xf7fc, 0xf7fb, 0xf948, 0xf949, 0xf94b, 0xf94a, + 0xca50, 0xa6e8, 0xad6e, 0xd7c5, 0xb5f7, 0xdffa, 0xc2d0, 0xf2f2, + 0xa8a3, 0xb357, 0xb356, 0xdbd0, 0xb5f8, 0xdbd2, 0xdbd1, 0xdffb, + 0xb8d0, 0xe443, 0xe446, 0xe445, 0xe444, 0xe7ce, 0xe7d0, 0xe7cf, + 0xbfcc, 0xbfcb, 0xc1bb, 0xee79, 0xee7b, 0xee7a, 0xc2d1, 0xf2f4, + 0xf2f3, 0xf4cc, 0xc4b1, 0xc4fd, 0xf754, 0xf753, 0xc65b, 0xa8a4, + 0xd0af, 0xad6f, 0xd7c8, 0xd7c6, 0xd7c7, 0xdbd4, 0xdbd5, 0xe043, + 0xdbd3, 0xdffc, 0xe041, 0xe040, 0xe042, 0xb8d1, 0xdffe, 0xdffd, + 0xe044, 0xe449, 0xe447, 0xe448, 0xe7d3, 0xe7d1, 0xe7d2, 0xeb7d, + 0xee7c, 0xee7d, 0xc2d2, 0xf2f5, 0xf4cd, 0xc4b2, 0xf64c, 0xf755, + 0xc5a9, 0xf7fe, 0xf94c, 0xa8a5, 0xad71, 0xad72, 0xd0b0, 0xd0b1, + 0xad70, 0xb054, 0xb052, 0xb051, 0xb058, 0xb050, 0xb059, 0xd3dd, + 0xb056, 0xb053, 0xb057, 0xb055, 0xb04f, 0xb35f, 0xb359, 0xd7cc, + 0xb35e, 0xb360, 0xb35a, 0xb35b, 0xd7ca, 0xb358, 0xd7cb, 0xb35d, + 0xd7c9, 0xb35c, 0xb644, 0xb646, 0xdbd8, 0xb645, 0xb5f9, 0xb5fd, + 0xb8e4, 0xe049, 0xdbda, 0xb5fe, 0xdbdd, 0xdbde, 0xb643, 0xdbe0, + 0xdbe2, 0xdbe3, 0xdbd7, 0xdbd6, 0xdbe4, 0xb642, 0xdbe1, 0xdbdf, + 0xb640, 0xb5fb, 0xb647, 0xdbdb, 0xdbdc, 0xdbd9, 0xb641, 0xb5fc, + 0xb5fa, 0xe048, 0xb8df, 0xb8da, 0xb8d5, 0xb8e5, 0xb8d6, 0xb8d2, + 0xb8e1, 0xb8de, 0xb8e0, 0xb8d7, 0xb8dc, 0xb8d3, 0xb8d4, 0xe050, + 0xe04d, 0xe045, 0xe04a, 0xb8e2, 0xe051, 0xb8e3, 0xb8d9, 0xe047, + 0xe04f, 0xe04b, 0xe04e, 0xe04c, 0xb8dd, 0xe046, 0xb8d8, 0xe44c, + 0xbb78, 0xbb7b, 0xe44e, 0xbba5, 0xe44d, 0xbb7d, 0xbdcf, 0xe44f, + 0xbba4, 0xe44b, 0xbba6, 0xbb79, 0xb8db, 0xbb7c, 0xbb7a, 0xbb7e, + 0xbba2, 0xbb77, 0xbba7, 0xbba3, 0xbba1, 0xe44a, 0xbdd6, 0xbdd2, + 0xbdd9, 0xe7d6, 0xbdda, 0xe7e2, 0xe7db, 0xbdcb, 0xe7e3, 0xe7dd, + 0xbdd5, 0xe7de, 0xbdd4, 0xe7e1, 0xbdce, 0xe7df, 0xe7d5, 0xbdcd, + 0xebaa, 0xbdd3, 0xbdd0, 0xbdd8, 0xe7d4, 0xe7d8, 0xbdcc, 0xe7d7, + 0xe7d9, 0xe7da, 0xbdd7, 0xe7dc, 0xe7e0, 0xe7e4, 0xbddb, 0xbfd2, + 0xeba5, 0xebab, 0xeba8, 0xeb7e, 0xebac, 0xeba1, 0xeba7, 0xbfcd, + 0xbfd3, 0xebad, 0xbfcf, 0xbfd9, 0xbfd4, 0xebaf, 0xeba9, 0xbfd0, + 0xeba2, 0xbfda, 0xeba3, 0xeba4, 0xbfdb, 0xbfd8, 0xbdd1, 0xbfce, + 0xebb0, 0xbfdc, 0xbfd5, 0xebae, 0xbfd1, 0xbfd6, 0xbfd7, 0xc1c3, + 0xeea4, 0xeead, 0xeeaa, 0xeeac, 0xc1c0, 0xeea5, 0xeeab, 0xc1bc, + 0xeea7, 0xc1c4, 0xeea3, 0xeea8, 0xeeaf, 0xeba6, 0xeea9, 0xeea2, + 0xc1bd, 0xeea1, 0xc1be, 0xeeb0, 0xc1bf, 0xeeae, 0xc1c2, 0xee7e, + 0xc1c1, 0xeea6, 0xf0dc, 0xf0ea, 0xf0e5, 0xf0e7, 0xf0db, 0xc2d3, + 0xf0da, 0xc2d6, 0xc2d5, 0xf0e9, 0xf0e1, 0xf0de, 0xf0e4, 0xf0dd, + 0xf0df, 0xf0e8, 0xf0e6, 0xc2d4, 0xf0ed, 0xf0eb, 0xf0e2, 0xf0ec, + 0xf0e3, 0xf2f9, 0xc3cf, 0xf341, 0xf64f, 0xc3d6, 0xf0e0, 0xf2f7, + 0xc3d2, 0xf2f8, 0xf2fd, 0xc3d4, 0xc3d5, 0xf2f6, 0xf340, 0xf342, + 0xf2fa, 0xf2fc, 0xf2fe, 0xf2fb, 0xf343, 0xc3d1, 0xc3d7, 0xc3d3, + 0xc3d0, 0xf4d0, 0xc4b7, 0xf4ce, 0xf4d2, 0xf4d3, 0xc4b5, 0xf4d4, + 0xf4d1, 0xf4cf, 0xc4b8, 0xc4b4, 0xf4d5, 0xc4b6, 0xc4b3, 0xc4fe, + 0xc540, 0xf64e, 0xf64d, 0xf650, 0xf651, 0xc541, 0xf756, 0xf75b, + 0xc5aa, 0xf758, 0xf757, 0xf75a, 0xf759, 0xf843, 0xc5dc, 0xf842, + 0xf840, 0xf841, 0xc5fe, 0xc5fd, 0xf8c1, 0xf8c2, 0xc640, 0xf94d, + 0xf94e, 0xc667, 0xc66d, 0xf9a9, 0xf9c8, 0xa8a6, 0xd7cd, 0xd7ce, + 0xe052, 0xe450, 0xe7e5, 0xc1c6, 0xc1c5, 0xf0ee, 0xf344, 0xf844, + 0xa8a7, 0xd3de, 0xb05a, 0xb361, 0xe054, 0xe053, 0xbddc, 0xe7e6, + 0xbddd, 0xeeb1, 0xc2d7, 0xc676, 0xa8a8, 0xcdcb, 0xd3df, 0xb362, + 0xd7cf, 0xd7d0, 0xdbe5, 0xb648, 0xb8e6, 0xe056, 0xe055, 0xe057, + 0xe451, 0xe452, 0xbba8, 0xbfdd, 0xbdde, 0xbfde, 0xeeb5, 0xeeb2, + 0xeeb4, 0xeeb3, 0xc1c7, 0xf0ef, 0xf346, 0xf345, 0xcba4, 0xb05c, + 0xb05b, 0xd3e0, 0xd7d1, 0xdbe7, 0xdbe6, 0xb649, 0xe059, 0xe05a, + 0xe058, 0xb8e8, 0xb8e7, 0xbbaa, 0xbba9, 0xe7e7, 0xebb3, 0xebb1, + 0xebb2, 0xbfdf, 0xeeb7, 0xeeb6, 0xf0f2, 0xf0f1, 0xf0f0, 0xf347, + 0xf9aa, 0xa8a9, 0xad73, 0xad74, 0xb05d, 0xb05e, 0xd3e2, 0xd3e1, + 0xd7d2, 0xb368, 0xb366, 0xb363, 0xb367, 0xb365, 0xb364, 0xb64a, + 0xdbea, 0xb8ed, 0xb64c, 0xb651, 0xdbec, 0xb653, 0xb652, 0xb655, + 0xdbeb, 0xdbe8, 0xb64f, 0xb64b, 0xb64d, 0xdbe9, 0xb654, 0xb650, + 0xb64e, 0xb8ef, 0xb8ee, 0xb8ec, 0xb8f0, 0xb8ea, 0xb8eb, 0xb8e9, + 0xe05b, 0xe454, 0xbbac, 0xbbad, 0xbbab, 0xe453, 0xe455, 0xe7ea, + 0xe7ec, 0xbde7, 0xe7ed, 0xbde0, 0xe7e9, 0xbddf, 0xbde9, 0xbde5, + 0xbde6, 0xbde2, 0xe7e8, 0xbde1, 0xe7ee, 0xe7eb, 0xbde8, 0xbde3, + 0xbde4, 0xebb5, 0xebb7, 0xebb6, 0xebb8, 0xbfe0, 0xebb4, 0xc1cb, + 0xeeb8, 0xc1c8, 0xc1cc, 0xc1ca, 0xc1c9, 0xf0f3, 0xf0f6, 0xf0f5, + 0xf0f4, 0xc2d8, 0xf348, 0xf349, 0xc3d8, 0xf34a, 0xc3d9, 0xc4ba, + 0xc4b9, 0xf652, 0xc542, 0xf653, 0xf75c, 0xc5ab, 0xc5ac, 0xf845, + 0xc642, 0xa8aa, 0xb36a, 0xb369, 0xe05c, 0xe05d, 0xbbae, 0xebb9, + 0xbdea, 0xebba, 0xeeb9, 0xa8ab, 0xd0b2, 0xad76, 0xad75, 0xd3e3, + 0xb05f, 0xd3e4, 0xd7d5, 0xd7d4, 0xd7d3, 0xdbee, 0xb658, 0xdbed, + 0xb657, 0xdbef, 0xb656, 0xe05f, 0xe062, 0xe060, 0xe061, 0xe065, + 0xe05e, 0xe066, 0xe063, 0xe064, 0xbbb0, 0xe456, 0xbbaf, 0xe7f2, + 0xe7f0, 0xbdeb, 0xe7ef, 0xe7f1, 0xbdec, 0xebbb, 0xebbc, 0xc1cd, + 0xf34c, 0xf34e, 0xf34b, 0xf34d, 0xf4d6, 0xf654, 0xf96f, 0xa8ac, + 0xad77, 0xd3e5, 0xd3e7, 0xd3e6, 0xd7d8, 0xb36c, 0xd7d6, 0xb36b, + 0xd7d9, 0xd7da, 0xd7d7, 0xdbfb, 0xb660, 0xdbf3, 0xdbf9, 0xb65b, + 0xb65e, 0xdbf2, 0xb659, 0xdbf6, 0xe06c, 0xb65d, 0xdbf1, 0xdbf7, + 0xdbf4, 0xdbfa, 0xdbf0, 0xdbf8, 0xb65c, 0xb65f, 0xdbf5, 0xb65a, + 0xb8f2, 0xe068, 0xb8f1, 0xe06f, 0xe06e, 0xb8f8, 0xb8f9, 0xe070, + 0xb8f3, 0xe06d, 0xb8f7, 0xe072, 0xe069, 0xe06b, 0xb8f4, 0xe067, + 0xe06a, 0xe071, 0xb8f5, 0xe073, 0xb8f6, 0xbbb1, 0xe45b, 0xe461, + 0xe459, 0xe462, 0xe458, 0xe45d, 0xe463, 0xe460, 0xe45f, 0xe45e, + 0xe457, 0xe45c, 0xe45a, 0xbdf1, 0xbdee, 0xe7fb, 0xe841, 0xe843, + 0xe840, 0xe7f8, 0xe7fa, 0xe845, 0xe842, 0xe7fc, 0xe846, 0xe7f9, + 0xe844, 0xbdef, 0xbdf5, 0xbdf3, 0xe7f3, 0xbdf4, 0xbdf0, 0xe7f4, + 0xe7f6, 0xe7f5, 0xe7fd, 0xe7fe, 0xbdf2, 0xbded, 0xe7f7, 0xebc6, + 0xbfe2, 0xebbd, 0xbfe3, 0xbfe6, 0xebc2, 0xebbf, 0xbfe5, 0xebc3, + 0xebc4, 0xebbe, 0xebc7, 0xebc0, 0xebc5, 0xbfe4, 0xbfe1, 0xebc1, + 0xeebf, 0xc1d0, 0xc1ce, 0xc1d1, 0xc1cf, 0xeebe, 0xeebb, 0xeeba, + 0xeebd, 0xeebc, 0xf145, 0xc2de, 0xf0fb, 0xf0fa, 0xc2d9, 0xf141, + 0xf140, 0xf0f7, 0xf143, 0xf0fc, 0xc2dd, 0xf0f9, 0xf142, 0xf0f8, + 0xc2da, 0xc2dc, 0xf0fd, 0xc2db, 0xf0fe, 0xf144, 0xf352, 0xc3de, + 0xf34f, 0xf353, 0xc3db, 0xf351, 0xc3e0, 0xc3dd, 0xf350, 0xc3df, + 0xf354, 0xc3da, 0xc4bc, 0xc4be, 0xf4d9, 0xc4bd, 0xf4d7, 0xc3dc, + 0xf4d8, 0xc4bb, 0xc543, 0xc545, 0xf656, 0xc544, 0xf655, 0xf761, + 0xc5ad, 0xf760, 0xc5ae, 0xf75e, 0xf75d, 0xf762, 0xf763, 0xf846, + 0xf75f, 0xf8c6, 0xf8c3, 0xf8c4, 0xf8c5, 0xc65c, 0xf951, 0xf950, + 0xf94f, 0xf970, 0xf9be, 0xf9ab, 0xc66e, 0xa8ad, 0xb060, 0xb8fa, + 0xbdf6, 0xebc8, 0xc2df, 0xf355, 0xf9ac, 0xa8ae, 0xaaee, 0xad79, + 0xad78, 0xb063, 0xd3e8, 0xb061, 0xd3e9, 0xb062, 0xd7df, 0xd7db, + 0xb36d, 0xd7de, 0xd7dd, 0xd7dc, 0xb36e, 0xd7e0, 0xd7e1, 0xdc43, + 0xdc41, 0xdc45, 0xdc46, 0xdc4c, 0xdc48, 0xdc4a, 0xdc42, 0xdbfc, + 0xdc49, 0xdc4b, 0xdc44, 0xdc47, 0xdbfd, 0xb662, 0xdc40, 0xdbfe, + 0xb661, 0xb663, 0xb8fd, 0xe075, 0xe077, 0xe076, 0xe07b, 0xb8fb, + 0xe078, 0xe074, 0xe079, 0xe07a, 0xb8fc, 0xb8fe, 0xe07c, 0xe467, + 0xe466, 0xe464, 0xe465, 0xbbb3, 0xbbb5, 0xbbb2, 0xbbb4, 0xe84d, + 0xe84e, 0xe849, 0xe84a, 0xbdf8, 0xbdfd, 0xbdf7, 0xbdfe, 0xbdf9, + 0xe84b, 0xe84c, 0xe848, 0xbe40, 0xbdfb, 0xbdfa, 0xbdfc, 0xe847, + 0xebca, 0xbfe8, 0xebcc, 0xbfea, 0xebcf, 0xebcb, 0xebc9, 0xebce, + 0xbfe9, 0xebcd, 0xbfe7, 0xc1d3, 0xc1d6, 0xeec1, 0xc1d4, 0xeec0, + 0xc1d2, 0xc1d5, 0xf146, 0xf147, 0xf148, 0xc2e0, 0xf149, 0xc2e1, + 0xc3e2, 0xf358, 0xf359, 0xf357, 0xf356, 0xf35a, 0xc3e1, 0xf4dd, + 0xf4db, 0xf4dc, 0xf4de, 0xf4da, 0xf4df, 0xf658, 0xf659, 0xf657, + 0xc546, 0xf764, 0xc5af, 0xf765, 0xf848, 0xf847, 0xa8af, 0xb664, + 0xb940, 0xbbb6, 0xbfec, 0xbfeb, 0xc3e3, 0xc47c, 0xc547, 0xa8b0, + 0xb064, 0xb941, 0xf35b, 0xcba6, 0xa8b1, 0xa8b4, 0xa8b3, 0xa8b2, + 0xcba5, 0xcdcd, 0xcdcf, 0xaaef, 0xaaf1, 0xcdcc, 0xcdce, 0xaaf0, + 0xcdd1, 0xcdd0, 0xcdd2, 0xd0b6, 0xd0b4, 0xad7c, 0xd0b3, 0xada3, + 0xad7e, 0xad7b, 0xada4, 0xad7d, 0xada2, 0xada1, 0xd0b5, 0xad7a, + 0xb06a, 0xd3eb, 0xd3f1, 0xb067, 0xb06e, 0xb069, 0xd3ee, 0xd3f0, + 0xb06c, 0xd3ea, 0xd3ed, 0xb068, 0xb065, 0xd3ec, 0xb06b, 0xd3ef, + 0xb06d, 0xb066, 0xd7e3, 0xd7e6, 0xb370, 0xb37a, 0xb376, 0xd7e4, + 0xb37e, 0xb377, 0xb37c, 0xb372, 0xb36f, 0xb371, 0xb37d, 0xd7e5, + 0xb375, 0xb378, 0xb374, 0xb379, 0xd7e7, 0xb37b, 0xb373, 0xd7e2, + 0xdc4d, 0xb665, 0xdc4f, 0xb667, 0xb669, 0xdc4e, 0xb666, 0xb66a, + 0xb668, 0xb947, 0xe0a3, 0xb94f, 0xe07e, 0xb950, 0xb945, 0xe0a1, + 0xb94a, 0xe0a2, 0xb943, 0xb942, 0xb94d, 0xb94c, 0xb94b, 0xb949, + 0xb94e, 0xe07d, 0xb944, 0xb946, 0xb948, 0xbbb8, 0xbbbb, 0xbbbf, + 0xbbb9, 0xbbbe, 0xbbbc, 0xbbb7, 0xbbbd, 0xbbba, 0xe852, 0xbe43, + 0xbe41, 0xe853, 0xbe44, 0xbe42, 0xe851, 0xe850, 0xbff0, 0xe84f, + 0xbfee, 0xbfed, 0xebd0, 0xbe45, 0xbfef, 0xebd1, 0xbff2, 0xebd2, + 0xbff1, 0xc1d8, 0xeec3, 0xc1d7, 0xc1dc, 0xc1da, 0xc1db, 0xc2e3, + 0xc1d9, 0xeec2, 0xebd3, 0xc2e2, 0xc2e4, 0xc3e4, 0xc3e5, 0xf4e0, + 0xc5de, 0xc5dd, 0xa8b6, 0xca55, 0xb06f, 0xca52, 0xca53, 0xca51, + 0xca54, 0xcbaa, 0xcba7, 0xcbac, 0xcba8, 0xa8b7, 0xa8ba, 0xcba9, + 0xa8b9, 0xcbab, 0xa8b8, 0xcdd5, 0xcdd7, 0xaaf4, 0xcdd3, 0xcdd6, + 0xcdd4, 0xaaf2, 0xaaf5, 0xaaf3, 0xd0b8, 0xd0bc, 0xd0b9, 0xada7, + 0xada8, 0xd0bb, 0xd0bd, 0xd0bf, 0xada5, 0xd0be, 0xada6, 0xd7ee, + 0xd0ba, 0xd3f2, 0xd3fb, 0xd3f9, 0xd3f4, 0xd3f5, 0xd3fa, 0xd3fc, + 0xb071, 0xd3f7, 0xd3f3, 0xb070, 0xb072, 0xd3f6, 0xd3fd, 0xd3f8, + 0xb3a1, 0xd7f1, 0xd7e9, 0xd7ef, 0xd7f0, 0xb3a2, 0xd7e8, 0xd7ea, + 0xd0b7, 0xd7ec, 0xd7ed, 0xd7eb, 0xb66c, 0xdc56, 0xebd4, 0xdc57, + 0xdc54, 0xb3a3, 0xb66e, 0xdc53, 0xdc59, 0xdc58, 0xb66b, 0xdc5c, + 0xdc52, 0xdc5b, 0xdc50, 0xdc5a, 0xdc55, 0xb66d, 0xe0aa, 0xe0a5, + 0xe0ab, 0xe0a6, 0xe0a4, 0xe0a7, 0xb951, 0xe0a9, 0xe0a8, 0xb952, + 0xbbc1, 0xbbc0, 0xe46e, 0xe471, 0xe469, 0xe46d, 0xbbc2, 0xe46c, + 0xe46a, 0xe470, 0xe46b, 0xe468, 0xe46f, 0xe859, 0xbe48, 0xf14a, + 0xe856, 0xe857, 0xe855, 0xdc51, 0xbe47, 0xe85a, 0xe854, 0xbe46, + 0xbe49, 0xe858, 0xebd5, 0xbff3, 0xebd6, 0xebd7, 0xeec4, 0xc1dd, + 0xf14b, 0xf14c, 0xf14d, 0xf35d, 0xf35c, 0xf4e2, 0xf4e1, 0xf65b, + 0xf65c, 0xf65a, 0xf766, 0xc5b0, 0xa8bb, 0xadaa, 0xada9, 0xb075, + 0xb074, 0xd440, 0xd441, 0xd3fe, 0xb073, 0xd7f5, 0xd7f6, 0xd7f2, + 0xb3a4, 0xd7f3, 0xd7f4, 0xdc5f, 0xdc61, 0xdc5d, 0xdc60, 0xb66f, + 0xdc5e, 0xb670, 0xdd73, 0xb955, 0xb954, 0xb953, 0xe0ac, 0xe0ad, + 0xe473, 0xe475, 0xbbc6, 0xbbc3, 0xbbc5, 0xbbc4, 0xe474, 0xe472, + 0xe861, 0xe85e, 0xe85f, 0xbe4d, 0xe860, 0xe85b, 0xe85c, 0xbe4a, + 0xbe4b, 0xe85d, 0xbe4c, 0xebdb, 0xebdc, 0xebd9, 0xebda, 0xbff4, + 0xebd8, 0xeec8, 0xeec5, 0xeec7, 0xc1e0, 0xeecb, 0xc1df, 0xeec9, + 0xeecc, 0xeeca, 0xeec6, 0xc1de, 0xf14f, 0xf150, 0xf14e, 0xf152, + 0xc2e5, 0xc2e6, 0xf35f, 0xc3e7, 0xf151, 0xf35e, 0xc3e6, 0xf4e5, + 0xf4e6, 0xc4bf, 0xf4e4, 0xf4e3, 0xf65d, 0xc548, 0xf849, 0xf8c8, + 0xf8c7, 0xc643, 0xc65d, 0xf8c9, 0xf971, 0xc66f, 0xa8bc, 0xaaf6, + 0xb956, 0xc4c0, 0xa8bd, 0xadab, 0xb3a5, 0xb671, 0xc2e7, 0xaaf7, + 0xd0c1, 0xd0c0, 0xd442, 0xb078, 0xb076, 0xb07a, 0xd444, 0xb079, + 0xb077, 0xd443, 0xb3a8, 0xd7fc, 0xb3a7, 0xb3a9, 0xd842, 0xb3ab, + 0xd7fe, 0xd840, 0xd7f7, 0xb3aa, 0xd843, 0xd7f9, 0xd7fa, 0xd7f8, + 0xb3a6, 0xd841, 0xd7fb, 0xd7fd, 0xdc6d, 0xdc6c, 0xdc6a, 0xdc62, + 0xdc71, 0xdc65, 0xdc6f, 0xdc76, 0xdc6e, 0xb679, 0xb675, 0xdc63, + 0xdc69, 0xb677, 0xdc68, 0xb678, 0xb67a, 0xdc6b, 0xb672, 0xb673, + 0xdc77, 0xdc75, 0xdc74, 0xdc66, 0xdc72, 0xb676, 0xb674, 0xdc73, + 0xdc64, 0xdc67, 0xdc70, 0xe4ba, 0xe0b7, 0xe0b0, 0xe0c3, 0xe0cc, + 0xe0b3, 0xb961, 0xe0c0, 0xb957, 0xb959, 0xb965, 0xe0b1, 0xb95a, + 0xb95c, 0xb966, 0xb95b, 0xb964, 0xe0b9, 0xe0ae, 0xb962, 0xe0b8, + 0xb95e, 0xe0ca, 0xb963, 0xe0c8, 0xe0bc, 0xe0c6, 0xb960, 0xe0af, + 0xe0c9, 0xe0c4, 0xe0cb, 0xb958, 0xb967, 0xb95d, 0xe0b5, 0xe0bd, + 0xe0c1, 0xe0c5, 0xb95f, 0xe0b4, 0xe0b2, 0xe0be, 0xe0bb, 0xe0ba, + 0xe0bf, 0xe0c2, 0xe0c7, 0xe478, 0xbbc7, 0xe4a4, 0xe47a, 0xbbcc, + 0xbbd0, 0xe4ad, 0xe4b5, 0xe4a6, 0xbbc8, 0xe4aa, 0xe0b6, 0xbbc9, + 0xe4b1, 0xe4b6, 0xe4ae, 0xe4b0, 0xe4b9, 0xe4b2, 0xe47e, 0xe4a9, + 0xbbd1, 0xbbcd, 0xe47c, 0xe4ab, 0xbbcb, 0xe4a5, 0xbbca, 0xe4b3, + 0xe4a2, 0xe479, 0xbbce, 0xe4b8, 0xe47b, 0xe4af, 0xe4ac, 0xe4a7, + 0xe477, 0xe476, 0xe4a1, 0xe4b4, 0xbbcf, 0xe4b7, 0xe47d, 0xe4a3, + 0xbe52, 0xbe5a, 0xbe55, 0xe8a4, 0xe8a1, 0xe867, 0xbe50, 0xbe4f, + 0xbe56, 0xe865, 0xbe54, 0xe871, 0xe863, 0xe864, 0xbe4e, 0xe8a3, + 0xbe58, 0xe874, 0xe879, 0xe873, 0xebee, 0xe86f, 0xe877, 0xe875, + 0xe868, 0xe862, 0xe87d, 0xbe57, 0xe87e, 0xe878, 0xe86d, 0xe86b, + 0xe866, 0xe86e, 0xe87b, 0xe86a, 0xe87a, 0xe8a2, 0xbe53, 0xe876, + 0xe87c, 0xe872, 0xe86c, 0xbe51, 0xe4a8, 0xe870, 0xbe59, 0xe869, + 0xebf4, 0xbff7, 0xebf3, 0xebf0, 0xec44, 0xbffb, 0xec41, 0xebf8, + 0xec43, 0xebe9, 0xebf6, 0xbffd, 0xebe1, 0xebdf, 0xec42, 0xec40, + 0xebfe, 0xebed, 0xebec, 0xebe2, 0xc040, 0xebe8, 0xebf2, 0xebfd, + 0xc043, 0xec45, 0xc1e8, 0xc045, 0xbffe, 0xebe6, 0xebef, 0xebde, + 0xebe0, 0xbff5, 0xc042, 0xbffa, 0xebe7, 0xebf7, 0xebf1, 0xc041, + 0xebdd, 0xc1e3, 0xebf9, 0xebfc, 0xbffc, 0xebeb, 0xc044, 0xbff9, + 0xbff8, 0xebf5, 0xebfb, 0xbff6, 0xebe4, 0xebfa, 0xebe5, 0xebea, + 0xeed2, 0xeed7, 0xc1e5, 0xc1e7, 0xeedd, 0xc1e1, 0xeeec, 0xeee3, + 0xeed8, 0xeed9, 0xeee2, 0xc1ee, 0xeee1, 0xeed1, 0xeee0, 0xeed4, + 0xeeed, 0xc1ed, 0xc1eb, 0xeed5, 0xeee8, 0xeeda, 0xeee7, 0xeee9, + 0xeed0, 0xc1e6, 0xeeea, 0xeede, 0xc1ea, 0xeedb, 0xc1ec, 0xeee4, + 0xc1e4, 0xeed6, 0xeee5, 0xeedf, 0xebe3, 0xeee6, 0xeed3, 0xc1e9, + 0xeeeb, 0xc1e2, 0xeece, 0xf160, 0xf159, 0xc2e9, 0xf154, 0xf163, + 0xf15b, 0xeedc, 0xf165, 0xf155, 0xc2e8, 0xf15f, 0xc2ea, 0xc2f2, + 0xc2f0, 0xf161, 0xc2f1, 0xf157, 0xf158, 0xf15d, 0xf162, 0xeecd, + 0xc2eb, 0xf16a, 0xf167, 0xf16b, 0xf15e, 0xf15a, 0xf168, 0xf36a, + 0xf15c, 0xc2ee, 0xc2ed, 0xeecf, 0xc2ef, 0xf164, 0xf166, 0xc2ec, + 0xf169, 0xf153, 0xf156, 0xf373, 0xf363, 0xc3eb, 0xf371, 0xf361, + 0xc3ec, 0xf36c, 0xf368, 0xc3f1, 0xf372, 0xf362, 0xf365, 0xc3e9, + 0xf374, 0xf36d, 0xf370, 0xc3ef, 0xc3f4, 0xc3f2, 0xf369, 0xf364, + 0xc3ed, 0xc3ee, 0xf360, 0xc3ea, 0xc3e8, 0xc3f0, 0xf36f, 0xc3f3, + 0xf36b, 0xf375, 0xc3f5, 0xf367, 0xf36e, 0xf4f3, 0xf542, 0xf4f5, + 0xf4fc, 0xf366, 0xf4fa, 0xf4e9, 0xf540, 0xc4c3, 0xf4ed, 0xf4fe, + 0xf4f4, 0xc4c2, 0xf544, 0xf4f6, 0xf4fb, 0xf4fd, 0xf4e7, 0xf541, + 0xf4f2, 0xf4f7, 0xf4eb, 0xf4ef, 0xf543, 0xf4f9, 0xf4e8, 0xf4ec, + 0xf4ee, 0xf4f8, 0xc4c1, 0xf4f1, 0xf4ea, 0xf4f0, 0xf661, 0xf666, + 0xc54f, 0xf668, 0xc549, 0xf664, 0xf66a, 0xc54e, 0xc54a, 0xc54b, + 0xf660, 0xf667, 0xc54d, 0xf665, 0xc54c, 0xf65f, 0xf663, 0xf662, + 0xf65e, 0xf669, 0xc5b1, 0xf76d, 0xf770, 0xf76c, 0xf76e, 0xf76f, + 0xf769, 0xf76a, 0xf767, 0xf76b, 0xf768, 0xc5b2, 0xc5b3, 0xf84b, + 0xf84d, 0xf84c, 0xf84e, 0xc5e0, 0xf84a, 0xc5df, 0xc5e1, 0xf8cb, + 0xf8cc, 0xc644, 0xf8ca, 0xf953, 0xf952, 0xf954, 0xc65f, 0xf955, + 0xc65e, 0xf956, 0xf972, 0xf975, 0xf974, 0xc668, 0xf973, 0xc672, + 0xc670, 0xc671, 0xc677, 0xf9c0, 0xf9c1, 0xf9bf, 0xf9c9, 0xaaf8, + 0xd844, 0xdc78, 0xe8a5, 0xf376, 0xaaf9, 0xadac, 0xb07b, 0xd845, + 0xd846, 0xb3ac, 0xb67d, 0xdc7a, 0xdc79, 0xb6a3, 0xb67c, 0xdc7b, + 0xb67e, 0xb6a2, 0xb6a1, 0xb67b, 0xb968, 0xe0d0, 0xe0ce, 0xe0cf, + 0xe0cd, 0xbbd2, 0xbbd5, 0xbbd7, 0xbbd6, 0xbbd3, 0xbbd4, 0xe8a7, + 0xe8a6, 0xbe5b, 0xe8a8, 0xe8a9, 0xbe5c, 0xec4d, 0xec4b, 0xeef3, + 0xec49, 0xec4a, 0xc046, 0xec46, 0xec4e, 0xec48, 0xec4c, 0xeeef, + 0xeef1, 0xeef2, 0xc1f3, 0xeeee, 0xc1f2, 0xeef0, 0xc1ef, 0xc1f0, + 0xc1f1, 0xec47, 0xc2f5, 0xf16e, 0xf16c, 0xf16d, 0xc2f3, 0xc2f6, + 0xc2f4, 0xf377, 0xf378, 0xc3f6, 0xf545, 0xf547, 0xf546, 0xc4c4, + 0xc550, 0xf66d, 0xf66c, 0xf66b, 0xaafa, 0xc9aa, 0xca58, 0xa6e9, + 0xca56, 0xca59, 0xca57, 0xcbae, 0xa8c1, 0xa8c2, 0xcbb0, 0xa8bf, + 0xcbaf, 0xcbad, 0xa8c0, 0xa8be, 0xcdd8, 0xcddb, 0xaafd, 0xcdda, + 0xcdd9, 0xaafc, 0xaafb, 0xab40, 0xcddc, 0xaafe, 0xd0c6, 0xadae, + 0xadaf, 0xadb0, 0xd0c7, 0xd0c3, 0xadad, 0xd0c4, 0xd0c5, 0xd0c2, + 0xb0a4, 0xb0a1, 0xd445, 0xb0a2, 0xb0a5, 0xd446, 0xb07e, 0xb07c, + 0xb07d, 0xb0a3, 0xb3ad, 0xd849, 0xb3b5, 0xd848, 0xd84b, 0xb3b1, + 0xd84a, 0xb6ab, 0xb3af, 0xb3b2, 0xb3ae, 0xb3b3, 0xb3b4, 0xb3b0, + 0xd847, 0xb6a7, 0xdc7d, 0xdca3, 0xdca2, 0xb6ac, 0xb6a8, 0xb6a9, + 0xdc7c, 0xdc7e, 0xdca1, 0xb6a4, 0xb6a6, 0xb6aa, 0xb6a5, 0xe0d3, + 0xe0d1, 0xe0d2, 0xb96a, 0xb96b, 0xe0d4, 0xb969, 0xbbd8, 0xbbda, + 0xbbd9, 0xe4bb, 0xe4bc, 0xe8ab, 0xe8aa, 0xc047, 0xc048, 0xec4f, + 0xc049, 0xeef6, 0xeef4, 0xeef5, 0xc1f4, 0xf16f, 0xc3f7, 0xc1f5, + 0xab41, 0xb0a6, 0xd447, 0xd84c, 0xb3b6, 0xb6ad, 0xdca4, 0xdca6, + 0xb6af, 0xb6ae, 0xb6b0, 0xb6b1, 0xdca5, 0xb96e, 0xb96f, 0xb96d, + 0xbbdb, 0xb96c, 0xe0d5, 0xbbdc, 0xe8ac, 0xec50, 0xc04a, 0xc1f6, + 0xf170, 0xf174, 0xc2f9, 0xf171, 0xc2fa, 0xc2f8, 0xf175, 0xc2fb, + 0xf173, 0xf379, 0xc2f7, 0xc3f8, 0xf8cd, 0xab42, 0xb3b8, 0xb3b7, + 0xb6b2, 0xdca8, 0xdca7, 0xb6b3, 0xe0d9, 0xb973, 0xb970, 0xe0d8, + 0xb972, 0xe0d6, 0xb971, 0xe0d7, 0xe4bd, 0xbbdd, 0xe8af, 0xbe5d, + 0xe8ad, 0xbe5e, 0xbe5f, 0xe8ae, 0xbe60, 0xec51, 0xc04e, 0xc04b, + 0xc050, 0xec53, 0xc04c, 0xec52, 0xc04f, 0xc04d, 0xeef9, 0xeefb, + 0xc1f7, 0xeefa, 0xc1f8, 0xeef8, 0xeef7, 0xf177, 0xf176, 0xc2fc, + 0xf178, 0xf37e, 0xc3fa, 0xf37d, 0xf37a, 0xc3f9, 0xf37b, 0xf37c, + 0xf548, 0xf549, 0xc4c5, 0xc553, 0xf66e, 0xc551, 0xc552, 0xf66f, + 0xc5b4, 0xc5b5, 0xf771, 0xc645, 0xf8cf, 0xc647, 0xf8ce, 0xf8d0, + 0xc646, 0xf957, 0xf9ad, 0xab43, 0xb974, 0xe4be, 0xe8b0, 0xc051, + 0xc052, 0xab44, 0xbe61, 0xc3fb, 0xadb1, 0xc053, 0xc5e2, 0xadb2, + 0xd84d, 0xdca9, 0xdcab, 0xdcaa, 0xe0dd, 0xe0da, 0xb975, 0xb976, + 0xe0db, 0xe0dc, 0xe4c0, 0xe4c5, 0xbbde, 0xe4bf, 0xe4c1, 0xe4c8, + 0xe4c3, 0xe4c7, 0xe4c4, 0xe4c2, 0xe4c6, 0xbbdf, 0xe8b3, 0xe8b1, + 0xbe63, 0xbe62, 0xe8b2, 0xbe64, 0xec56, 0xec55, 0xc054, 0xec54, + 0xeefc, 0xeefe, 0xef41, 0xef40, 0xc1f9, 0xeefd, 0xf1a1, 0xc2fd, + 0xf17d, 0xf1a2, 0xc2fe, 0xf17b, 0xf17e, 0xf17c, 0xf179, 0xc340, + 0xf17a, 0xf3a1, 0xf3a3, 0xf3a2, 0xf54a, 0xf54b, 0xf670, 0xc5b7, + 0xc5b6, 0xf84f, 0xf850, 0xc648, 0xf8d1, 0xc669, 0xadb3, 0xb6b4, + 0xe4ca, 0xe4c9, 0xe8b5, 0xe8b4, 0xc1fa, 0xef43, 0xef42, 0xf1a5, + 0xf1a3, 0xf1a6, 0xf1a4, 0xc3fc, 0xf3a4, 0xf3a5, 0xf3a6, 0xf671, + 0xf772, 0xf8d2, 0xadb4, 0xec57, 0xef44, 0xadb5, 0xbbe0, 0xec58, + 0xc341, 0xf1a7, 0xc3fd, 0xf54c, 0xf54d, 0xc554, 0xf851, 0xadb6, + 0xb3bb, 0xb3bc, 0xd84e, 0xb6b5, 0xb6b6, 0xdcac, 0xb6b7, 0xb97a, + 0xb97c, 0xe0df, 0xe0e0, 0xe0de, 0xb977, 0xb978, 0xb97b, 0xb979, + 0xe4cb, 0xbbe1, 0xbbe2, 0xe8bc, 0xbe67, 0xe8b7, 0xe8b6, 0xe8bb, + 0xbe65, 0xc05b, 0xe8b8, 0xe8bd, 0xe8ba, 0xe8b9, 0xbe66, 0xc059, + 0xec5a, 0xc055, 0xec5b, 0xec59, 0xc058, 0xc056, 0xc05a, 0xc057, + 0xef45, 0xef4a, 0xef46, 0xef49, 0xc1fb, 0xedd4, 0xef48, 0xef47, + 0xc344, 0xc342, 0xc345, 0xc343, 0xf1a8, 0xf1a9, 0xf1aa, 0xc346, + 0xf3aa, 0xc440, 0xf3a8, 0xc441, 0xf3a7, 0xf3a9, 0xc3fe, 0xf551, + 0xf54e, 0xf54f, 0xf550, 0xf672, 0xc556, 0xc555, 0xf774, 0xf773, + 0xc5b8, 0xc5e3, 0xc649, 0xc660, 0xf958, 0xf9ae, 0xf9af, 0xadb7, + 0xdcad, 0xe0e1, 0xe4cc, 0xe4cd, 0xbbe3, 0xbbe4, 0xe8be, 0xbe68, + 0xc1fc, 0xf1ab, 0xc347, 0xf3ad, 0xc442, 0xf3ac, 0xf3ae, 0xf3ab, + 0xf675, 0xf552, 0xf553, 0xc4c6, 0xf674, 0xf673, 0xf775, 0xf9b0, + 0xadb8, 0xadb9, 0xb0a7, 0xd448, 0xd84f, 0xb6b8, 0xb6bb, 0xb6b9, + 0xdcae, 0xb6bd, 0xb6ba, 0xb6bc, 0xb97e, 0xe0e2, 0xe0e3, 0xe8c0, + 0xb97d, 0xb9a1, 0xb9a2, 0xe4cf, 0xe4ce, 0xbbe5, 0xbbe6, 0xe4d0, + 0xe8bf, 0xbbe8, 0xbe69, 0xbbe7, 0xc05c, 0xe8c1, 0xbe6b, 0xbe6a, + 0xe8c2, 0xe8c5, 0xe8c3, 0xe8c4, 0xbe6c, 0xc061, 0xc05f, 0xc05e, + 0xec5d, 0xc060, 0xec5c, 0xef4b, 0xec5e, 0xc05d, 0xec5f, 0xef4e, + 0xef4c, 0xef4d, 0xef52, 0xc34b, 0xef51, 0xef54, 0xef53, 0xef50, + 0xef4f, 0xc1fd, 0xf1ae, 0xf1ad, 0xc34a, 0xc348, 0xc349, 0xf1ac, + 0xf3b1, 0xc443, 0xf3b0, 0xf3af, 0xc444, 0xf558, 0xf557, 0xf555, + 0xf554, 0xc4c8, 0xc4c7, 0xf559, 0xf776, 0xc5b9, 0xf677, 0xc557, + 0xf676, 0xf556, 0xf777, 0xc5e4, 0xc661, 0xf959, 0xf9b1, 0xadba, + 0xd850, 0xef55, 0xadbb, 0xe4d2, 0xe4d1, 0xec60, 0xef57, 0xef56, + 0xc34c, 0xf3b2, 0xf3b3, 0xc4c9, 0xf9b2, 0xb0a8, 0xb6bf, 0xb6be, + 0xe0e4, 0xe0e6, 0xb9a4, 0xe0e5, 0xb9a3, 0xb9a5, 0xe0e7, 0xe4d4, + 0xe4d6, 0xe4d5, 0xe4d8, 0xbbe9, 0xe4d7, 0xe4d3, 0xe4d9, 0xe8cc, + 0xe8cf, 0xe8d1, 0xe8c7, 0xe8cb, 0xe8c8, 0xbe6e, 0xbe71, 0xbe73, + 0xe8c9, 0xe8ca, 0xbe72, 0xe8cd, 0xe8d0, 0xe8ce, 0xbe74, 0xbe70, + 0xe8c6, 0xbe6d, 0xbe6f, 0xc063, 0xec66, 0xec64, 0xec63, 0xec69, + 0xec68, 0xec67, 0xec62, 0xc062, 0xec61, 0xec65, 0xc064, 0xef5a, + 0xef5e, 0xef5b, 0xef5d, 0xef5c, 0xef59, 0xef5f, 0xef62, 0xef60, + 0xef61, 0xc240, 0xc1fe, 0xef58, 0xef63, 0xf1b3, 0xf1b6, 0xf1b8, + 0xf1b7, 0xf1b1, 0xf1b5, 0xf1b0, 0xf1b2, 0xc34d, 0xf1af, 0xf1b4, + 0xf3c0, 0xf3b5, 0xc445, 0xc446, 0xf3b4, 0xf3b9, 0xf3bf, 0xf3b7, + 0xf3be, 0xf3bb, 0xf3ba, 0xf3bd, 0xf3b8, 0xf3b6, 0xf3bc, 0xf560, + 0xf55e, 0xc4ca, 0xf55d, 0xf563, 0xf561, 0xc4cb, 0xf55c, 0xf55a, + 0xf55b, 0xc4cd, 0xf55f, 0xc4cc, 0xf562, 0xf678, 0xf67e, 0xf679, + 0xc55b, 0xf6a1, 0xc55a, 0xf67d, 0xf67c, 0xc559, 0xf67b, 0xc558, + 0xf67a, 0xf77d, 0xf7a1, 0xf77e, 0xf77b, 0xc5bb, 0xf778, 0xf77c, + 0xf7a3, 0xf7a2, 0xf779, 0xf77a, 0xc5ba, 0xf852, 0xc5e7, 0xf853, + 0xc5e5, 0xc5e6, 0xf8d3, 0xc64a, 0xf976, 0xc66a, 0xf9b3, 0xc66b, + 0xf9b4, 0xf9b5, 0xf9c3, 0xf9c2, 0xc67a, 0xf9cd, 0xb0a9, 0xe0e9, + 0xe0e8, 0xbbea, 0xbbeb, 0xe4da, 0xe8d2, 0xec6c, 0xbe75, 0xc065, + 0xec6a, 0xec6d, 0xc066, 0xef64, 0xec6b, 0xf1b9, 0xc34e, 0xf3c1, + 0xf566, 0xf564, 0xf565, 0xf6a2, 0xc55c, 0xf7a4, 0xc5ea, 0xc5bc, + 0xc5e8, 0xc5e9, 0xf8d4, 0xc662, 0xb0aa, 0xf1ba, 0xd449, 0xb9a6, + 0xe4db, 0xbbec, 0xe4dc, 0xe8d4, 0xe8d3, 0xc068, 0xbe76, 0xbe77, + 0xe8d7, 0xe8d6, 0xe8d5, 0xec6e, 0xec71, 0xec70, 0xec6f, 0xc067, + 0xef68, 0xef66, 0xef65, 0xef67, 0xc34f, 0xf1bc, 0xf1bd, 0xc350, + 0xf1bb, 0xf3c3, 0xf3c2, 0xf3c5, 0xc447, 0xf3c4, 0xf567, 0xf569, + 0xf568, 0xf6a3, 0xf6a6, 0xf6a4, 0xf6a5, 0xf7a5, 0xc5bd, 0xf854, + 0xf855, 0xf856, 0xc64b, 0xc663, 0xf9b6, 0xb0ab, 0xbe78, 0xc069, + 0xf1be, 0xf7a6, 0xf9c4, 0xd44a, 0xc67b, 0xb0ac, 0xec72, 0xf1bf, + 0xf3c6, 0xf6a7, 0xf7a7, 0xb0ad, 0xe4dd, 0xe4de, 0xbbed, 0xbbee, + 0xe8d9, 0xbe7a, 0xbe79, 0xe8d8, 0xef69, 0xf1c0, 0xf1c2, 0xf1c1, + 0xc353, 0xc352, 0xc351, 0xc55e, 0xf6a8, 0xc55d, 0xf7a9, 0xf7a8, + 0xc64c, 0xf8d5, 0xb3bd, 0xe0ea, 0xe4e1, 0xe4df, 0xe4e0, 0xe8e2, + 0xe8dd, 0xe8da, 0xe8e1, 0xe8e3, 0xbe7c, 0xe8e0, 0xe8dc, 0xe8db, + 0xe8df, 0xe8de, 0xbe7b, 0xec7d, 0xec78, 0xec76, 0xeca1, 0xec77, + 0xec73, 0xec79, 0xec74, 0xef72, 0xec75, 0xeca2, 0xec7c, 0xc06a, + 0xec7b, 0xec7a, 0xec7e, 0xef6a, 0xef6d, 0xef6c, 0xef74, 0xef6f, + 0xef73, 0xef71, 0xef70, 0xef6e, 0xef6b, 0xc243, 0xc242, 0xc244, + 0xc241, 0xef75, 0xf1c8, 0xf1cb, 0xf1c9, 0xf1cd, 0xf1ce, 0xf1c6, + 0xc358, 0xf1c7, 0xf1c5, 0xf1cc, 0xf1c4, 0xf1c3, 0xc357, 0xc355, + 0xc354, 0xf1ca, 0xf3cf, 0xf3d5, 0xc44a, 0xf3d0, 0xf3d3, 0xf3d7, + 0xc44b, 0xf3d2, 0xf3ca, 0xf3c9, 0xf3d6, 0xf3cd, 0xf3cb, 0xf3d4, + 0xf3cc, 0xc449, 0xc448, 0xf3c7, 0xf3c8, 0xf3d1, 0xf3ce, 0xf56c, + 0xf56f, 0xc356, 0xf56d, 0xf573, 0xf571, 0xf56b, 0xf576, 0xf56a, + 0xc4cf, 0xf572, 0xf56e, 0xc4ce, 0xf575, 0xf574, 0xf6ab, 0xf6aa, + 0xf6b1, 0xf6ad, 0xf6b0, 0xc560, 0xf6ae, 0xf6af, 0xf6a9, 0xf6ac, + 0xc55f, 0xc5bf, 0xf7b4, 0xf7af, 0xf7b3, 0xf7b6, 0xf7b2, 0xf7ae, + 0xc5c1, 0xf7b1, 0xf7b5, 0xc5c0, 0xf7ac, 0xf570, 0xf7b0, 0xf7ad, + 0xf7aa, 0xf7ab, 0xc5be, 0xf85a, 0xf85c, 0xf85f, 0xf85b, 0xf860, + 0xf859, 0xf857, 0xc5eb, 0xf85d, 0xc5ed, 0xc5ec, 0xf858, 0xf85e, + 0xf8da, 0xc64d, 0xf8db, 0xf8d9, 0xf8d6, 0xf8d8, 0xf8d7, 0xf95a, + 0xf95c, 0xf95b, 0xf979, 0xf978, 0xf977, 0xf97a, 0xc673, 0xc674, + 0xf9ca, 0xf9ce, 0xb3be, 0xdcaf, 0xe0ed, 0xb9a7, 0xe0eb, 0xe0ec, + 0xe4e2, 0xe4e3, 0xbbf1, 0xbbef, 0xe4e4, 0xbbf0, 0xe8e8, 0xe8eb, + 0xe8e5, 0xe8ec, 0xe8e4, 0xe8e6, 0xe8e7, 0xe8ea, 0xbea1, 0xe8ef, + 0xe8ee, 0xbe7d, 0xe8e9, 0xe8ed, 0xbe7e, 0xecac, 0xc06f, 0xeca7, + 0xc06b, 0xeca4, 0xecaa, 0xecad, 0xc070, 0xeca9, 0xeca6, 0xecae, + 0xeca5, 0xecab, 0xc06c, 0xeca3, 0xc06d, 0xc06e, 0xeca8, 0xefa9, + 0xef7a, 0xef7b, 0xef7e, 0xef7c, 0xef76, 0xef79, 0xefa5, 0xef7d, + 0xc245, 0xefa7, 0xefa4, 0xc246, 0xefa6, 0xef77, 0xefa2, 0xefa3, + 0xefa1, 0xf1d2, 0xf1d4, 0xf1d7, 0xf1d1, 0xc359, 0xf1d9, 0xf1d0, + 0xf1da, 0xf1d6, 0xf1d8, 0xf1dc, 0xf1d5, 0xf1dd, 0xf1d3, 0xf1cf, + 0xc35a, 0xf1db, 0xc35b, 0xc44d, 0xef78, 0xf3f1, 0xf3e8, 0xc44f, + 0xf3e4, 0xc450, 0xf3ed, 0xf3e7, 0xf3dd, 0xc44e, 0xf3ea, 0xf3e5, + 0xf3e6, 0xf3d8, 0xf3df, 0xf3ee, 0xf3eb, 0xf3e3, 0xf3ef, 0xf3de, + 0xf3d9, 0xf3ec, 0xf3db, 0xf3e9, 0xf3e0, 0xf3f0, 0xf3dc, 0xc44c, + 0xf3da, 0xf3e1, 0xf3e2, 0xf57d, 0xf57b, 0xf5a2, 0xf5ae, 0xf5a5, + 0xf57c, 0xf578, 0xf5a7, 0xf57e, 0xf5a3, 0xf57a, 0xf5aa, 0xf577, + 0xf5a1, 0xf5a6, 0xf5a8, 0xf5ab, 0xf579, 0xf5af, 0xf5b0, 0xf5a9, + 0xf5ad, 0xf5a4, 0xf6c1, 0xf6c4, 0xc561, 0xf6c3, 0xf6c8, 0xf6c6, + 0xc562, 0xf6bd, 0xf6b3, 0xf6b2, 0xc564, 0xf6bf, 0xf6c0, 0xf6bc, + 0xf6b4, 0xf6b9, 0xf5ac, 0xf6b5, 0xc563, 0xf6bb, 0xf6ba, 0xf6b6, + 0xf6c2, 0xf6b7, 0xf7bb, 0xf6c5, 0xf6c7, 0xf6be, 0xf6b8, 0xf7bc, + 0xf7be, 0xf7b8, 0xc5c2, 0xf7c5, 0xf7c3, 0xc5c3, 0xf7c2, 0xf7c1, + 0xf7ba, 0xf7b7, 0xf7bd, 0xf7c6, 0xf7b9, 0xf7bf, 0xf869, 0xf86e, + 0xf864, 0xf867, 0xc5ee, 0xf86b, 0xf872, 0xf7c0, 0xf865, 0xf86f, + 0xf873, 0xf86a, 0xf863, 0xf86d, 0xf86c, 0xf871, 0xf870, 0xf7c4, + 0xf868, 0xf862, 0xf866, 0xc64e, 0xc64f, 0xf861, 0xf8e6, 0xf8dd, + 0xf8e5, 0xf8e2, 0xf8e3, 0xf8dc, 0xf8df, 0xf8e7, 0xf8e1, 0xf8e0, + 0xf8de, 0xf8e4, 0xf95d, 0xf95e, 0xf960, 0xf95f, 0xf962, 0xf961, + 0xf97c, 0xf97b, 0xf9b7, 0xf9b8, 0xf9c5, 0xc678, 0xc67c, 0xf9cf, + 0xc67d, 0xb3bf, 0xc4d0, 0xf6c9, 0xc650, 0xc651, 0xb3c0, 0xe0ee, + 0xb9a8, 0xe8f0, 0xecb0, 0xecb1, 0xecaf, 0xefab, 0xefaa, 0xc247, + 0xf1df, 0xefac, 0xf1de, 0xf3f3, 0xc451, 0xc453, 0xf3f2, 0xc452, + 0xf5b1, 0xf5b3, 0xf5b2, 0xf6ca, 0xc565, 0xc5ef, 0xf8e8, 0xf963, + 0xf9d2, 0xb3c1, 0xe4e5, 0xbea2, 0xecb3, 0xecb2, 0xefad, 0xc454, + 0xc4d1, 0xf7c7, 0xf9cb, 0xb3c2, 0xbbf2, 0xbea3, 0xf3f4, 0xf874, + 0xb6c0, 0xefae, 0xc664, 0xb6c1, 0xbea4, 0xc248, 0xf875, 0xb6c2, + 0xe8f1, 0xc072, 0xecb4, 0xecb5, 0xc071, 0xefaf, 0xc24c, 0xc24a, + 0xc24b, 0xc249, 0xf1e0, 0xc35c, 0xf5b5, 0xf5b4, 0xf5b7, 0xf5b6, + 0xc4d2, 0xf6cb, 0xf6cd, 0xf6cc, 0xc566, 0xf7c8, 0xf876, 0xf877, + 0xc5f0, 0xf964, 0xf97d, 0xc675, 0xdcb0, 0xecb6, 0xefb0, 0xf3f5, + 0xe0ef, 0xefb1, 0xf1e2, 0xf1e1, 0xf878, 0xc652, 0xf965, 0xf97e, + 0xb9a9, 0xe8f2, 0xe8f3, 0xecb7, 0xb9aa, 0xc35d, 0xf1e3, 0xf6cf, + 0xc567, 0xf6d0, 0xf6ce, 0xf879, 0xf8e9, 0xb9ab, 0xefb4, 0xefb3, + 0xefb2, 0xf1e4, 0xf1e8, 0xf1e7, 0xf1e6, 0xf1e5, 0xc35e, 0xf3f6, + 0xf5b9, 0xc4d3, 0xf5b8, 0xf6d1, 0xf7cb, 0xf7ca, 0xc5c4, 0xf7c9, + 0xf87c, 0xf87b, 0xf87a, 0xbbf3, 0xecb8, 0xc24d, 0xf3f7, 0xf3f8, + 0xf7cc, 0xf87d, 0xf8ea, 0xf966, 0xf9b9, 0xf9d4, 0xbbf4, 0xc24e, + 0xf1e9, 0xf3f9, 0xf6d2, 0xf87e, 0xbea6, 0xefb5, 0xf1ea, 0xf3fa, + 0xf3fb, 0xf3fc, 0xf5be, 0xf5ba, 0xc568, 0xf5bd, 0xf5bc, 0xc4d4, + 0xf5bb, 0xc4d6, 0xc4d5, 0xf6d4, 0xf6d3, 0xc569, 0xc56a, 0xc5c6, + 0xf7cd, 0xc5c5, 0xf8a3, 0xf8a4, 0xf8a2, 0xf8a1, 0xc654, 0xf8eb, + 0xf8ec, 0xf8ed, 0xc653, 0xf967, 0xf96a, 0xf969, 0xf968, 0xf9d3, + 0xc073, 0xc365, 0xf5bf, 0xf6d5, 0xc5c7, 0xf7ce, 0xf9d5, 0xc074, + 0xefb6, 0xf7cf, 0xf9a1, 0xc94a, 0xddfc, 0xa14a, 0xa157, 0xa159, + 0xa15b, 0xa15f, 0xa160, 0xa163, 0xa164, 0xa167, 0xa168, 0xa16b, + 0xa16c, 0xa16f, 0xa170, 0xa173, 0xa174, 0xa177, 0xa178, 0xa17b, + 0xa17c, 0xa1c6, 0xa1c7, 0xa1ca, 0xa1cb, 0xa1c8, 0xa1c9, 0xa15c, + 0xa14d, 0xa14f, 0xa151, 0xa152, 0xa153, 0xa154, 0xa17d, 0xa17e, + 0xa1a1, 0xa1a2, 0xa1a3, 0xa1a4, 0xa1cc, 0xa1cd, 0xa1ce, 0xa1de, + 0xa1df, 0xa1e0, 0xa1e1, 0xa1e2, 0xa24c, 0xa24d, 0xa24e, 0xa149, + 0xa1ad, 0xa243, 0xa248, 0xa1ae, 0xa15d, 0xa15e, 0xa1af, 0xa1cf, + 0xa141, 0xa1d0, 0xa144, 0xa241, 0xa2af, 0xa2b0, 0xa2b1, 0xa2b2, + 0xa2b3, 0xa2b4, 0xa2b5, 0xa2b6, 0xa2b7, 0xa2b8, 0xa147, 0xa146, + 0xa1d5, 0xa1d7, 0xa1d6, 0xa148, 0xa249, 0xa2cf, 0xa2d0, 0xa2d1, + 0xa2d2, 0xa2d3, 0xa2d4, 0xa2d5, 0xa2d6, 0xa2d7, 0xa2d8, 0xa2d9, + 0xa2da, 0xa2db, 0xa2dc, 0xa2dd, 0xa2de, 0xa2df, 0xa2e0, 0xa2e1, + 0xa2e2, 0xa2e3, 0xa2e4, 0xa2e5, 0xa2e6, 0xa2e7, 0xa2e8, 0xa242, + 0xa1c4, 0xa2e9, 0xa2ea, 0xa2eb, 0xa2ec, 0xa2ed, 0xa2ee, 0xa2ef, + 0xa2f0, 0xa2f1, 0xa2f2, 0xa2f3, 0xa2f4, 0xa2f5, 0xa2f6, 0xa2f7, + 0xa2f8, 0xa2f9, 0xa2fa, 0xa2fb, 0xa2fc, 0xa2fd, 0xa2fe, 0xa340, + 0xa341, 0xa342, 0xa343, 0xa161, 0xa155, 0xa162, 0xa14e, +}; + +static const Summary16 big5_uni2indx_page00[16] = { + /* 0x0000 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x00ac }, { 4, 0x0083 }, + { 7, 0x0000 }, { 7, 0x0080 }, { 8, 0x0000 }, { 8, 0x0080 }, +}; +static const Summary16 big5_uni2indx_page02[38] = { + /* 0x0200 */ + { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, + { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, + { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, + { 9, 0x0e80 }, { 13, 0x0200 }, { 14, 0x0000 }, { 14, 0x0000 }, + /* 0x0300 */ + { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, + { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, + { 14, 0x0000 }, { 14, 0xfffe }, { 29, 0x03fb }, { 38, 0xfffe }, + { 53, 0x03fb }, { 62, 0x0000 }, { 62, 0x0000 }, { 62, 0x0000 }, + /* 0x0400 */ + { 62, 0x0002 }, { 63, 0x1ff0 }, { 72, 0xfff8 }, { 85, 0xffff }, + { 101, 0xffff }, { 117, 0x0002 }, +}; +static const Summary16 big5_uni2indx_page20[44] = { + /* 0x2000 */ + { 118, 0x0000 }, { 118, 0x3318 }, { 124, 0x0064 }, { 127, 0x4824 }, + { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, + { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, + { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, + /* 0x2100 */ + { 131, 0x0228 }, { 134, 0x0000 }, { 134, 0x0000 }, { 134, 0x0000 }, + { 134, 0x0000 }, { 134, 0x0000 }, { 134, 0x03ff }, { 144, 0x0000 }, + { 144, 0x0000 }, { 144, 0x03cf }, { 152, 0x0000 }, { 152, 0x0000 }, + { 152, 0x0000 }, { 152, 0x0000 }, { 152, 0x0000 }, { 152, 0x0000 }, + /* 0x2200 */ + { 152, 0x0000 }, { 152, 0xc400 }, { 155, 0x4e29 }, { 162, 0x1030 }, + { 165, 0x0000 }, { 165, 0x0004 }, { 166, 0x00c3 }, { 170, 0x0000 }, + { 170, 0x0000 }, { 170, 0x0000 }, { 170, 0x0020 }, { 171, 0x8000 }, +}; +static const Summary16 big5_uni2indx_page24[37] = { + /* 0x2400 */ + { 172, 0x0000 }, { 172, 0x0000 }, { 172, 0x0000 }, { 172, 0x0000 }, + { 172, 0x0000 }, { 172, 0x0000 }, { 172, 0x03ff }, { 182, 0x3ff0 }, + { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, + { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, + /* 0x2500 */ + { 192, 0x1005 }, { 195, 0x1111 }, { 199, 0x1010 }, { 201, 0x1010 }, + { 203, 0x0000 }, { 203, 0x4001 }, { 205, 0xe402 }, { 210, 0x000f }, + { 214, 0xfffe }, { 229, 0x0030 }, { 231, 0x0003 }, { 233, 0x300c }, + { 237, 0xc8c0 }, { 242, 0x0000 }, { 242, 0x003c }, { 246, 0x0000 }, + /* 0x2600 */ + { 246, 0x0260 }, { 249, 0x0000 }, { 249, 0x0000 }, { 249, 0x0000 }, + { 249, 0x0007 }, +}; +static const Summary16 big5_uni2indx_page30[62] = { + /* 0x3000 */ + { 252, 0xff2f }, { 265, 0x6037 }, { 272, 0x03fe }, { 281, 0x0000 }, + { 281, 0xfffe }, { 296, 0xffff }, { 312, 0xffff }, { 328, 0xffff }, + { 344, 0xffff }, { 360, 0x600f }, { 366, 0xfffe }, { 381, 0xffff }, + { 397, 0xffff }, { 413, 0xffff }, { 429, 0xffff }, { 445, 0x407f }, + /* 0x3100 */ + { 453, 0xffe0 }, { 464, 0xffff }, { 480, 0x03ff }, { 490, 0x0000 }, + { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, + { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, + { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, + /* 0x3200 */ + { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, + { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0000 }, + { 490, 0x0000 }, { 490, 0x0000 }, { 490, 0x0008 }, { 491, 0x0000 }, + { 491, 0x0000 }, { 491, 0x0000 }, { 491, 0x0000 }, { 491, 0x0000 }, + /* 0x3300 */ + { 491, 0x0000 }, { 491, 0x0000 }, { 491, 0x0000 }, { 491, 0x0000 }, + { 491, 0x0000 }, { 491, 0x0000 }, { 491, 0x0000 }, { 491, 0x0000 }, + { 491, 0xc000 }, { 493, 0x7000 }, { 496, 0x0002 }, { 497, 0x0000 }, + { 497, 0x4010 }, { 499, 0x0026 }, +}; +static const Summary16 big5_uni2indx_page4e[1307] = { + /* 0x4e00 */ + { 502, 0xff8b }, { 514, 0xc373 }, { 523, 0x6840 }, { 527, 0x1b0f }, + { 535, 0xe9ac }, { 544, 0xf34c }, { 553, 0x0200 }, { 554, 0xc008 }, + { 557, 0x795c }, { 566, 0xca3e }, { 575, 0x7976 }, { 585, 0x0648 }, + { 589, 0x2fdf }, { 601, 0xf7f0 }, { 612, 0x033a }, { 618, 0xa8ff }, + /* 0x4f00 */ + { 629, 0xef37 }, { 641, 0x233f }, { 650, 0xb004 }, { 654, 0xfd59 }, + { 665, 0xf3ca }, { 675, 0xffff }, { 691, 0xde9f }, { 703, 0xfff9 }, + { 717, 0xabff }, { 730, 0x7df7 }, { 743, 0xc000 }, { 745, 0x8eec }, + { 754, 0xeebf }, { 767, 0xffdb }, { 781, 0xd003 }, { 786, 0x45fa }, + /* 0x5000 */ + { 795, 0xfae1 }, { 805, 0xdffe }, { 819, 0xbfef }, { 833, 0x10ab }, + { 839, 0xffeb }, { 853, 0xfcaa }, { 863, 0xef3f }, { 876, 0x24fd }, + { 885, 0x78ad }, { 894, 0x7f76 }, { 906, 0xf00c }, { 912, 0xedff }, + { 926, 0xcff6 }, { 938, 0x2cfa }, { 947, 0xf7f9 }, { 960, 0xeb6b }, + /* 0x5100 */ + { 971, 0x1ffd }, { 983, 0x95bf }, { 994, 0x6677 }, { 1004, 0xbfbf }, + { 1018, 0x3bfb }, { 1030, 0xfeb4 }, { 1041, 0x7bae }, { 1052, 0x11e2 }, + { 1058, 0xa681 }, { 1064, 0x41be }, { 1072, 0x1435 }, { 1078, 0x72c3 }, + { 1086, 0x7d70 }, { 1095, 0x7191 }, { 1102, 0x0003 }, { 1104, 0x276b }, + /* 0x5200 */ + { 1113, 0x57cb }, { 1123, 0x70cf }, { 1132, 0x4732 }, { 1139, 0x0def }, + { 1149, 0x7eda }, { 1160, 0xfc74 }, { 1170, 0xfe06 }, { 1179, 0xbdb4 }, + { 1189, 0x3f9f }, { 1201, 0x8bca }, { 1209, 0x7e49 }, { 1218, 0x5800 }, + { 1221, 0x228f }, { 1228, 0xebec }, { 1239, 0x8a5c }, { 1246, 0xddbb }, + /* 0x5300 */ + { 1258, 0xef60 }, { 1267, 0xb6e7 }, { 1278, 0xa40f }, { 1285, 0xf293 }, + { 1294, 0x37bb }, { 1305, 0x549e }, { 1313, 0xd04b }, { 1320, 0x9baf }, + { 1331, 0xc414 }, { 1336, 0xf7d4 }, { 1347, 0x30b0 }, { 1352, 0x0a14 }, + { 1356, 0x2f08 }, { 1362, 0x88d0 }, { 1367, 0xff7e }, { 1381, 0x192f }, + /* 0x5400 */ + { 1389, 0xffda }, { 1402, 0xfb07 }, { 1412, 0x7ff1 }, { 1424, 0x7beb }, + { 1436, 0xc5ef }, { 1447, 0x0010 }, { 1448, 0x99ff }, { 1460, 0xfdff }, + { 1475, 0x79d7 }, { 1486, 0x0567 }, { 1493, 0xffe7 }, { 1507, 0xfdcb }, + { 1519, 0xc3ff }, { 1531, 0x4040 }, { 1533, 0x6ff7 }, { 1546, 0xbd8e }, + /* 0x5500 */ + { 1556, 0xdffa }, { 1569, 0x0497 }, { 1575, 0xf4c0 }, { 1582, 0x5bff }, + { 1595, 0xed7b }, { 1607, 0xd0e7 }, { 1616, 0x047e }, { 1623, 0xf8e0 }, + { 1631, 0xff9f }, { 1645, 0xb73e }, { 1656, 0x7dfe }, { 1669, 0x882e }, + { 1675, 0xfffd }, { 1690, 0xbe7f }, { 1703, 0x83fe }, { 1713, 0xf6c4 }, + /* 0x5600 */ + { 1722, 0xf357 }, { 1733, 0xb8fd }, { 1744, 0xd680 }, { 1750, 0xef7d }, + { 1763, 0x5767 }, { 1773, 0x4788 }, { 1779, 0xff7d }, { 1793, 0xc3df }, + { 1804, 0xf0ff }, { 1816, 0x37a9 }, { 1825, 0x7de0 }, { 1834, 0x70fc }, + { 1843, 0x3f6f }, { 1855, 0xec9a }, { 1864, 0x4cb3 }, { 1872, 0x8681 }, + /* 0x5700 */ + { 1877, 0x3f9e }, { 1888, 0xdd5c }, { 1898, 0xf70d }, { 1908, 0x4819 }, + { 1913, 0xfea3 }, { 1924, 0x0007 }, { 1927, 0xaf56 }, { 1937, 0x38ff }, + { 1948, 0x980d }, { 1954, 0xefb8 }, { 1965, 0x403d }, { 1971, 0xb760 }, + { 1979, 0xd8ce }, { 1988, 0x9035 }, { 1994, 0x72bf }, { 2005, 0x3fff }, + /* 0x5800 */ + { 2019, 0x7ff7 }, { 2033, 0x7a11 }, { 2040, 0xf7bb }, { 2053, 0xabff }, + { 2066, 0xff00 }, { 2074, 0x6fbe }, { 2086, 0xa93c }, { 2094, 0xfe72 }, + { 2105, 0xcfef }, { 2118, 0xf11b }, { 2127, 0xdb6b }, { 2138, 0xf40a }, + { 2145, 0xc3e6 }, { 2154, 0xef7e }, { 2167, 0x9b9c }, { 2176, 0xf610 }, + /* 0x5900 */ + { 2183, 0xf048 }, { 2189, 0x16f4 }, { 2197, 0xfeb5 }, { 2209, 0x5182 }, + { 2214, 0xc7b1 }, { 2223, 0x15bb }, { 2232, 0x6e87 }, { 2241, 0xfbdf }, + { 2255, 0xe43f }, { 2265, 0x63cd }, { 2274, 0xc1ff }, { 2285, 0x7e7e }, + { 2297, 0xfdeb }, { 2310, 0x7d5f }, { 2322, 0x777b }, { 2334, 0xfcfe }, + /* 0x5a00 */ + { 2347, 0x960b }, { 2354, 0xdbea }, { 2365, 0x6229 }, { 2371, 0x53e8 }, + { 2379, 0x37df }, { 2391, 0xfdef }, { 2405, 0x36f5 }, { 2415, 0xbd81 }, + { 2423, 0xdc18 }, { 2430, 0xfcbd }, { 2442, 0xd2e4 }, { 2450, 0xffff }, + { 2466, 0x3fd7 }, { 2478, 0xffe0 }, { 2489, 0x7f6f }, { 2502, 0xabf8 }, + /* 0x5b00 */ + { 2512, 0x9bae }, { 2522, 0x6ed9 }, { 2532, 0xf5fb }, { 2545, 0xf115 }, + { 2553, 0x79a9 }, { 2562, 0xbdfb }, { 2575, 0x5a3c }, { 2583, 0xadaf }, + { 2594, 0xdbba }, { 2605, 0x1fac }, { 2614, 0x71fc }, { 2624, 0x8379 }, + { 2632, 0x7cf7 }, { 2644, 0xc35f }, { 2654, 0xdfff }, { 2669, 0x0567 }, + /* 0x5c00 */ + { 2676, 0xff9a }, { 2688, 0x8467 }, { 2695, 0x1534 }, { 2701, 0xdf8b }, + { 2712, 0xf9f3 }, { 2724, 0x3373 }, { 2733, 0xf7bd }, { 2746, 0x5e1a }, + { 2754, 0xbf40 }, { 2762, 0xa03f }, { 2770, 0xffff }, { 2786, 0x01eb }, + { 2793, 0xdfc0 }, { 2802, 0xcfdd }, { 2814, 0x7500 }, { 2819, 0xabd3 }, + /* 0x5d00 */ + { 2829, 0xf8c3 }, { 2838, 0xeed6 }, { 2849, 0x43fd }, { 2859, 0xb7ff }, + { 2873, 0x5eaf }, { 2884, 0x4227 }, { 2890, 0x9bac }, { 2899, 0xf686 }, + { 2908, 0x27d7 }, { 2918, 0xf6bc }, { 2929, 0xf787 }, { 2940, 0x35b7 }, + { 2950, 0xaacd }, { 2959, 0xe176 }, { 2968, 0x49e7 }, { 2977, 0xe29f }, + /* 0x5e00 */ + { 2987, 0x545c }, { 2994, 0xaff2 }, { 3005, 0x2b3f }, { 3015, 0x61d8 }, + { 3022, 0xfc3b }, { 3033, 0xbbb8 }, { 3043, 0xffcf }, { 3057, 0x7b7d }, + { 3069, 0xbf95 }, { 3080, 0x1ce0 }, { 3086, 0x7dfd }, { 3099, 0x43ff }, + { 3110, 0x5ff6 }, { 3122, 0xfffe }, { 3137, 0xd3ef }, { 3149, 0xc4ce }, + /* 0x5f00 */ + { 3157, 0x8db6 }, { 3166, 0xadbc }, { 3176, 0x63dc }, { 3185, 0x11eb }, + { 3193, 0xdf59 }, { 3204, 0x23d0 }, { 3210, 0xbeb4 }, { 3220, 0xf3db }, + { 3232, 0x1fe7 }, { 3243, 0xdbc7 }, { 3254, 0xff63 }, { 3266, 0xfae4 }, + { 3276, 0xb22b }, { 3284, 0x63f7 }, { 3295, 0xed3b }, { 3306, 0xadba }, + /* 0x6000 */ + { 3316, 0xfe01 }, { 3324, 0x7eff }, { 3338, 0xfff7 }, { 3353, 0x02bc }, + { 3359, 0x32ff }, { 3370, 0xef39 }, { 3381, 0xfffc }, { 3395, 0x8005 }, + { 3398, 0x77fb }, { 3411, 0xbcf5 }, { 3422, 0x010d }, { 3426, 0xfff7 }, + { 3441, 0xfffb }, { 3456, 0xbf3a }, { 3467, 0x0057 }, { 3472, 0xdfff }, + /* 0x6100 */ + { 3487, 0xef7b }, { 3500, 0xbd7d }, { 3512, 0xdb88 }, { 3520, 0xc8d4 }, + { 3527, 0xfff3 }, { 3541, 0xed7c }, { 3552, 0x5dee }, { 3563, 0x56ff }, + { 3575, 0x7e0d }, { 3584, 0xac5f }, { 3594, 0xff96 }, { 3606, 0xd57f }, + { 3618, 0x3fee }, { 3630, 0xc140 }, { 3634, 0x6ff9 }, { 3646, 0xffe7 }, + /* 0x6200 */ + { 3660, 0x779b }, { 3671, 0x8e77 }, { 3681, 0x6ebf }, { 3693, 0xe45d }, + { 3702, 0x6fcf }, { 3714, 0x5f1f }, { 3725, 0xe07f }, { 3735, 0xfedf }, + { 3749, 0xd7db }, { 3761, 0x01fe }, { 3769, 0xff00 }, { 3777, 0xfb7b }, + { 3790, 0xffd4 }, { 3802, 0x1fdf }, { 3814, 0xf800 }, { 3819, 0xffff }, + /* 0x6300 */ + { 3835, 0xfb8f }, { 3847, 0x007b }, { 3853, 0xbf00 }, { 3860, 0x7f5c }, + { 3871, 0xffff }, { 3887, 0x07f3 }, { 3896, 0xeba0 }, { 3904, 0x3de7 }, + { 3915, 0xf7bf }, { 3929, 0xfbd7 }, { 3942, 0xffbf }, { 3957, 0x6003 }, + { 3961, 0xfffd }, { 3976, 0xbfed }, { 3989, 0xefbb }, { 4002, 0x027f }, + /* 0x6400 */ + { 4010, 0xfe40 }, { 4018, 0xddfd }, { 4031, 0xfdff }, { 4046, 0xe2f9 }, + { 4056, 0x680b }, { 4062, 0xfb1f }, { 4074, 0xfbe3 }, { 4086, 0xaffd }, + { 4099, 0x9fa4 }, { 4108, 0xf7ed }, { 4121, 0x7a7d }, { 4132, 0xf80f }, + { 4141, 0xeebe }, { 4153, 0x0fd5 }, { 4162, 0xbb5d }, { 4173, 0xfd9f }, + /* 0x6500 */ + { 4186, 0xf2db }, { 4197, 0x3bf9 }, { 4208, 0xfe7f }, { 4222, 0xebcc }, + { 4232, 0x876a }, { 4240, 0x73fa }, { 4251, 0x95fc }, { 4261, 0x9ffc }, + { 4273, 0x109f }, { 4280, 0xfaf7 }, { 4293, 0xddb7 }, { 4305, 0xbbcd }, + { 4316, 0xf87e }, { 4327, 0xeccd }, { 4337, 0xf366 }, { 4347, 0x3c3f }, + /* 0x6600 */ + { 4357, 0xfffd }, { 4372, 0xb03f }, { 4381, 0xe9f7 }, { 4393, 0x067e }, + { 4401, 0x96ae }, { 4410, 0xfe06 }, { 4419, 0xd576 }, { 4429, 0x5fd7 }, + { 4441, 0x3fd1 }, { 4451, 0xa3f3 }, { 4461, 0xcf07 }, { 4470, 0x6fb7 }, + { 4482, 0x9fd1 }, { 4492, 0x7f44 }, { 4501, 0x7b59 }, { 4511, 0xd3dd }, + /* 0x6700 */ + { 4522, 0xaf3b }, { 4533, 0xa9bd }, { 4543, 0x7dcf }, { 4555, 0xff3a }, + { 4567, 0xfbe0 }, { 4577, 0xf6eb }, { 4589, 0xb401 }, { 4594, 0xffff }, + { 4610, 0x7afa }, { 4621, 0xb7bf }, { 4634, 0xc000 }, { 4636, 0x0ffd }, + { 4647, 0xff7f }, { 4662, 0xff1f }, { 4675, 0xfefc }, { 4688, 0x95ff }, + /* 0x6800 */ + { 4700, 0x0000 }, { 4700, 0xb5dc }, { 4710, 0xef63 }, { 4721, 0x3f3e }, + { 4732, 0xfb7f }, { 4746, 0x001b }, { 4750, 0xe800 }, { 4754, 0xfbf6 }, + { 4767, 0x9eef }, { 4779, 0xb8df }, { 4790, 0xff9f }, { 4804, 0x003f }, + { 4810, 0x7bd0 }, { 4819, 0xf5ff }, { 4833, 0xdfdb }, { 4846, 0x3fff }, + /* 0x6900 */ + { 4860, 0xfdf0 }, { 4871, 0x00bf }, { 4878, 0x8420 }, { 4881, 0xbbbd }, + { 4893, 0xdf37 }, { 4905, 0xffde }, { 4919, 0xff6d }, { 4932, 0x0ff3 }, + { 4942, 0x604c }, { 4947, 0x5efb }, { 4959, 0xfffb }, { 4974, 0xfafb }, + { 4987, 0xfe5e }, { 4999, 0x0219 }, { 5003, 0x79f4 }, { 5013, 0xf9de }, + /* 0x6a00 */ + { 5025, 0xa7f7 }, { 5037, 0xebfa }, { 5049, 0x01eb }, { 5056, 0xff34 }, + { 5067, 0xebd3 }, { 5078, 0xef73 }, { 5090, 0xafd7 }, { 5102, 0xc040 }, + { 5105, 0x72bb }, { 5115, 0xdcff }, { 5128, 0xf17f }, { 5140, 0x2fd8 }, + { 5149, 0xb8ec }, { 5158, 0xfe0b }, { 5168, 0xdda3 }, { 5178, 0x1f0b }, + /* 0x6b00 */ + { 5186, 0x8f1d }, { 5195, 0x47cf }, { 5205, 0xb12b }, { 5213, 0xffde }, + { 5227, 0x7fee }, { 5240, 0xda73 }, { 5250, 0x24ff }, { 5260, 0xcbc4 }, + { 5268, 0xf75d }, { 5280, 0xcbf2 }, { 5290, 0xecfd }, { 5302, 0xb4ed }, + { 5312, 0xbff9 }, { 5325, 0x4ddd }, { 5335, 0x99dd }, { 5345, 0xfb8d }, + /* 0x6c00 */ + { 5356, 0xbb7f }, { 5369, 0xaf7b }, { 5381, 0xddfb }, { 5394, 0xc959 }, + { 5402, 0xfc4f }, { 5413, 0xfab5 }, { 5424, 0xafe3 }, { 5435, 0x6d5f }, + { 5446, 0xffff }, { 5462, 0x3f7d }, { 5474, 0x7800 }, { 5478, 0xffdb }, + { 5492, 0xb6ff }, { 5505, 0x7eff }, { 5519, 0xfbaf }, { 5532, 0x022f }, + /* 0x6d00 */ + { 5538, 0xff9b }, { 5551, 0xefc7 }, { 5563, 0xffa5 }, { 5575, 0xffff }, + { 5591, 0x0007 }, { 5594, 0xc700 }, { 5599, 0xf7ff }, { 5614, 0xfff1 }, + { 5627, 0x7ffd }, { 5641, 0x01bf }, { 5649, 0xdc00 }, { 5654, 0xfdbc }, + { 5666, 0xbff5 }, { 5679, 0xffff }, { 5695, 0xff7f }, { 5710, 0x3eff }, + /* 0x6e00 */ + { 5723, 0x0029 }, { 5726, 0xbe00 }, { 5732, 0xf9ff }, { 5746, 0xff7f }, + { 5761, 0x6efb }, { 5773, 0xfd7e }, { 5786, 0xcbff }, { 5799, 0x039e }, + { 5806, 0xe300 }, { 5811, 0xfbdd }, { 5824, 0xccff }, { 5836, 0xf6df }, + { 5849, 0xffff }, { 5865, 0x117f }, { 5874, 0xf800 }, { 5879, 0xfbf6 }, + /* 0x6f00 */ + { 5892, 0xe7ef }, { 5905, 0xd73c }, { 5915, 0xfeef }, { 5929, 0xdfef }, + { 5943, 0xc00b }, { 5948, 0xedbf }, { 5961, 0xfedf }, { 5975, 0xfdcd }, + { 5987, 0x7bf5 }, { 5999, 0x40fd }, { 6007, 0xffff }, { 6023, 0xb75f }, + { 6035, 0xffdf }, { 6050, 0xf930 }, { 6058, 0xfbdf }, { 6072, 0xdc97 }, + /* 0x7000 */ + { 6082, 0xfef3 }, { 6095, 0xbff2 }, { 6107, 0x8fdf }, { 6119, 0xdfbf }, + { 6133, 0x177f }, { 6144, 0xede6 }, { 6155, 0x0f7f }, { 6166, 0x3553 }, + { 6174, 0x447c }, { 6181, 0x877e }, { 6191, 0xfa12 }, { 6199, 0x45bb }, + { 6208, 0xede0 }, { 6217, 0x779e }, { 6228, 0x8017 }, { 6233, 0xbfd9 }, + /* 0x7100 */ + { 6245, 0x7e55 }, { 6255, 0xde89 }, { 6264, 0xc16f }, { 6273, 0x0447 }, + { 6278, 0x7ade }, { 6289, 0xf75d }, { 6301, 0x57ff }, { 6314, 0x2905 }, + { 6319, 0x86f7 }, { 6329, 0xfe95 }, { 6340, 0x97b3 }, { 6350, 0xf32f }, + { 6361, 0xcfff }, { 6375, 0x9f75 }, { 6386, 0x71f7 }, { 6397, 0xfb17 }, + /* 0x7200 */ + { 6408, 0x34ee }, { 6417, 0xee19 }, { 6426, 0x37cc }, { 6435, 0xef61 }, + { 6445, 0x9fd6 }, { 6456, 0xef4c }, { 6466, 0xd68f }, { 6476, 0xfbdd }, + { 6489, 0x7b73 }, { 6500, 0x6def }, { 6512, 0xd7fe }, { 6525, 0xa431 }, + { 6531, 0x5e7f }, { 6543, 0x97d7 }, { 6554, 0x0f5b }, { 6563, 0xffd8 }, + /* 0x7300 */ + { 6575, 0x9d83 }, { 6583, 0x7bce }, { 6594, 0x22ec }, { 6601, 0xdcff }, + { 6614, 0x763d }, { 6624, 0xef87 }, { 6635, 0xdfe7 }, { 6648, 0xfded }, + { 6661, 0x4fff }, { 6674, 0xa0fc }, { 6682, 0x3b77 }, { 6693, 0xdbfc }, + { 6705, 0x3ded }, { 6716, 0x7fdc }, { 6728, 0x6fa9 }, { 6738, 0xf570 }, + /* 0x7400 */ + { 6747, 0x3ffb }, { 6760, 0x2c40 }, { 6764, 0xff7f }, { 6779, 0x847f }, + { 6788, 0xec57 }, { 6798, 0xdeb7 }, { 6810, 0xe69c }, { 6819, 0xf22f }, + { 6829, 0x0feb }, { 6839, 0xd5b5 }, { 6849, 0xafeb }, { 6861, 0xede7 }, + { 6873, 0x8c2f }, { 6881, 0xfff0 }, { 6893, 0x537f }, { 6904, 0xe8f0 }, + /* 0x7500 */ + { 6912, 0xb99d }, { 6922, 0xb5ff }, { 6935, 0xff66 }, { 6947, 0xe78f }, + { 6958, 0xd981 }, { 6965, 0xbe10 }, { 6972, 0x9c7c }, { 6981, 0xe3c1 }, + { 6989, 0x9cd1 }, { 6997, 0x2733 }, { 7005, 0x0cbc }, { 7012, 0xff6d }, + { 7025, 0xfcb7 }, { 7037, 0xefb7 }, { 7050, 0xa0df }, { 7059, 0xffff }, + /* 0x7600 */ + { 7075, 0xbf0b }, { 7085, 0xfe7b }, { 7098, 0xa3ff }, { 7110, 0x353f }, + { 7120, 0x13cc }, { 7127, 0x97cd }, { 7137, 0x7637 }, { 7147, 0xfb27 }, + { 7158, 0xcfd6 }, { 7169, 0x7e6c }, { 7179, 0xec50 }, { 7186, 0xed31 }, + { 7195, 0x677c }, { 7205, 0xfc1c }, { 7214, 0xf6fa }, { 7226, 0x5fbf }, + /* 0x7700 */ + { 7239, 0x0fba }, { 7248, 0xae2f }, { 7258, 0xa3ad }, { 7267, 0x7ffe }, + { 7281, 0xfcf0 }, { 7291, 0xde74 }, { 7301, 0xffef }, { 7316, 0xf200 }, + { 7321, 0xfbbf }, { 7335, 0xfea2 }, { 7345, 0x3daf }, { 7356, 0xbcff }, + { 7369, 0xf694 }, { 7378, 0x5fb9 }, { 7389, 0xf3ad }, { 7400, 0x3f8f }, + /* 0x7800 */ + { 7411, 0xf26c }, { 7420, 0xa01f }, { 7427, 0xffef }, { 7442, 0x01bf }, + { 7450, 0x7728 }, { 7458, 0x7005 }, { 7463, 0xff35 }, { 7475, 0xda03 }, + { 7482, 0xd2f9 }, { 7492, 0xc7fa }, { 7503, 0x3fbf }, { 7516, 0x5c1d }, + { 7524, 0xff3a }, { 7536, 0xec33 }, { 7545, 0xb7af }, { 7557, 0xfe9c }, + /* 0x7900 */ + { 7568, 0x5236 }, { 7575, 0x7a9f }, { 7586, 0xbffa }, { 7599, 0xe722 }, + { 7607, 0x9ff7 }, { 7620, 0xfcff }, { 7634, 0x2fbb }, { 7645, 0xb61d }, + { 7654, 0xed06 }, { 7662, 0x1dfd }, { 7673, 0x7dd7 }, { 7685, 0xefdf }, + { 7699, 0xeb23 }, { 7708, 0xf166 }, { 7717, 0x7ed9 }, { 7728, 0x0dc0 }, + /* 0x7a00 */ + { 7733, 0x3d3d }, { 7743, 0xdfbf }, { 7757, 0xc945 }, { 7764, 0xba83 }, + { 7772, 0x7dd1 }, { 7782, 0x9dd0 }, { 7790, 0x7b87 }, { 7800, 0xcf73 }, + { 7811, 0x9ff3 }, { 7823, 0xc3f5 }, { 7833, 0xdf0d }, { 7843, 0xc5fe }, + { 7854, 0x0cb3 }, { 7861, 0x8302 }, { 7865, 0xe879 }, { 7874, 0xaec0 }, + /* 0x7b00 */ + { 7881, 0xc773 }, { 7891, 0x6f0f }, { 7901, 0xfd7d }, { 7914, 0x093f }, + { 7922, 0xfff1 }, { 7935, 0x0157 }, { 7941, 0x62fb }, { 7951, 0x01ff }, + { 7960, 0xfdb4 }, { 7971, 0x3bf3 }, { 7982, 0xb013 }, { 7988, 0x43b2 }, + { 7995, 0x5ed3 }, { 8005, 0xff30 }, { 8015, 0x0fff }, { 8027, 0xeb9f }, + /* 0x7c00 */ + { 8039, 0xfeef }, { 8053, 0xf203 }, { 8060, 0x3fef }, { 8073, 0xfb89 }, + { 8083, 0x37a9 }, { 8092, 0x9e99 }, { 8101, 0xdef9 }, { 8113, 0xa72c }, + { 8121, 0x3733 }, { 8130, 0xc1f6 }, { 8139, 0x812e }, { 8145, 0xfe3e }, + { 8157, 0x5d20 }, { 8163, 0xf2f7 }, { 8175, 0xd585 }, { 8183, 0x69d7 }, + /* 0x7d00 */ + { 8193, 0xffff }, { 8209, 0xffff }, { 8225, 0xdb07 }, { 8234, 0xff6f }, + { 8248, 0xc4ff }, { 8259, 0xd97f }, { 8271, 0xefce }, { 8283, 0xbe0f }, + { 8293, 0xf17b }, { 8304, 0xf05e }, { 8313, 0xf6cf }, { 8325, 0xffb7 }, + { 8339, 0x5ef7 }, { 8351, 0xef84 }, { 8360, 0xd7cb }, { 8371, 0x0edf }, + /* 0x7e00 */ + { 8381, 0xff08 }, { 8390, 0xfcff }, { 8404, 0xee3f }, { 8416, 0xffff }, + { 8432, 0x13ff }, { 8443, 0xd7ff }, { 8457, 0xaf0f }, { 8467, 0x7ffd }, + { 8481, 0xbdc7 }, { 8492, 0x1ffa }, { 8503, 0x0000 }, { 8503, 0x0000 }, + { 8503, 0x0000 }, { 8503, 0x0000 }, { 8503, 0x0000 }, { 8503, 0x0000 }, + /* 0x7f00 */ + { 8503, 0x0000 }, { 8503, 0x0000 }, { 8503, 0x0000 }, { 8503, 0xe740 }, + { 8510, 0xbd38 }, { 8519, 0xf933 }, { 8529, 0x7feb }, { 8542, 0xfeed }, + { 8555, 0x7fe8 }, { 8566, 0x7c76 }, { 8576, 0xb3f7 }, { 8588, 0xffef }, + { 8603, 0xfeaf }, { 8616, 0xd8b7 }, { 8626, 0xff6f }, { 8640, 0xfbbf }, + /* 0x8000 */ + { 8654, 0xf8fb }, { 8666, 0xdbf7 }, { 8679, 0x1752 }, { 8686, 0xe2f9 }, + { 8696, 0x85c8 }, { 8702, 0x7547 }, { 8711, 0x9090 }, { 8715, 0xe3ef }, + { 8727, 0x9ef4 }, { 8737, 0x3f6d }, { 8748, 0xee2e }, { 8758, 0x0536 }, + { 8764, 0xf7bc }, { 8776, 0x7ff3 }, { 8789, 0xa07b }, { 8797, 0x7f3f }, + /* 0x8100 */ + { 8810, 0x0567 }, { 8817, 0xeb60 }, { 8825, 0xbabe }, { 8836, 0x6601 }, + { 8841, 0xfcd8 }, { 8851, 0x583f }, { 8860, 0xcaf7 }, { 8871, 0x87df }, + { 8882, 0xbfcd }, { 8894, 0xffa0 }, { 8904, 0x5bcd }, { 8914, 0xfebf }, + { 8928, 0xb6fd }, { 8940, 0xefa7 }, { 8952, 0x77ef }, { 8965, 0xdf9c }, + /* 0x8200 */ + { 8976, 0x3fb7 }, { 8988, 0xf877 }, { 8999, 0x9d27 }, { 9008, 0xb7fc }, + { 9020, 0xcab5 }, { 9029, 0xdfef }, { 9043, 0xfb5a }, { 9054, 0xf1b6 }, + { 9064, 0xec39 }, { 9073, 0xef1f }, { 9085, 0xfbbf }, { 9099, 0x7ffb }, + { 9113, 0x000d }, { 9116, 0xdafe }, { 9128, 0xbdfb }, { 9141, 0x4e7f }, + /* 0x8300 */ + { 9152, 0x33ff }, { 9164, 0x5ac0 }, { 9170, 0xbff5 }, { 9183, 0x9ffe }, + { 9196, 0xffbf }, { 9211, 0x005f }, { 9217, 0x0000 }, { 9217, 0xfdf8 }, + { 9229, 0xffca }, { 9241, 0x6ffd }, { 9254, 0xcffd }, { 9267, 0xa001 }, + { 9270, 0xdfff }, { 9285, 0xfbf2 }, { 9297, 0xdfbf }, { 9311, 0xff7f }, + /* 0x8400 */ + { 9326, 0xfeda }, { 9338, 0x080f }, { 9343, 0xba08 }, { 9349, 0xbfff }, + { 9364, 0x7afd }, { 9376, 0xeed7 }, { 9388, 0xfbeb }, { 9401, 0x67f9 }, + { 9412, 0xe044 }, { 9417, 0xff93 }, { 9429, 0xdf97 }, { 9441, 0x9f57 }, + { 9452, 0xfef7 }, { 9466, 0x08df }, { 9474, 0xdf80 }, { 9482, 0xfedf }, + /* 0x8500 */ + { 9496, 0xffc5 }, { 9508, 0xf7fe }, { 9522, 0xfffb }, { 9537, 0x6803 }, + { 9542, 0x67fb }, { 9554, 0x6bfa }, { 9565, 0x7fff }, { 9580, 0x5fe2 }, + { 9590, 0xffff }, { 9606, 0xff73 }, { 9619, 0x87df }, { 9630, 0xe7fb }, + { 9643, 0xebfd }, { 9656, 0xf7a7 }, { 9668, 0xbf7e }, { 9681, 0xefc7 }, + /* 0x8600 */ + { 9693, 0x1ef3 }, { 9703, 0xdf82 }, { 9712, 0x76ff }, { 9725, 0xdf7e }, + { 9738, 0x79c9 }, { 9747, 0xda7d }, { 9758, 0xefbe }, { 9771, 0x1e9b }, + { 9780, 0x7ce0 }, { 9788, 0x77fb }, { 9801, 0x87be }, { 9811, 0xfffb }, + { 9826, 0x1bff }, { 9838, 0xffdb }, { 9852, 0x3f5c }, { 9862, 0x4fe0 }, + /* 0x8700 */ + { 9870, 0x7fff }, { 9885, 0x5f0e }, { 9894, 0x77ff }, { 9908, 0xddbf }, + { 9921, 0xf04f }, { 9930, 0xffff }, { 9946, 0xffff }, { 9962, 0x0ff8 }, + { 9971, 0xa3be }, { 9981, 0xfddf }, { 9995, 0xfc1c }, { 10004, 0xfffd }, + { 10019, 0x1f7d }, { 10030, 0xfb9e }, { 10042, 0xbdff }, { 10056, 0xdedc }, + /* 0x8800 */ + { 10067, 0x3f6f }, { 10079, 0xbafb }, { 10091, 0xdf7f }, { 10105, 0xfbef }, + { 10119, 0x7d1b }, { 10129, 0x2eec }, { 10138, 0xaf8e }, { 10148, 0xf2f7 }, + { 10160, 0x7b0f }, { 10170, 0xcfee }, { 10182, 0x1d96 }, { 10190, 0x77c6 }, + { 10200, 0x7e07 }, { 10209, 0xfff5 }, { 10223, 0xd982 }, { 10230, 0x7fdf }, + /* 0x8900 */ + { 10244, 0x5ee6 }, { 10254, 0xc7ff }, { 10267, 0xfeee }, { 10280, 0x79ef }, + { 10292, 0x9a56 }, { 10300, 0xffcf }, { 10314, 0xfe5f }, { 10327, 0xde5e }, + { 10338, 0x896e }, { 10346, 0xf9e8 }, { 10356, 0xf45e }, { 10366, 0xe6c4 }, + { 10374, 0x0001 }, { 10375, 0xbe7c }, { 10386, 0x3b7f }, { 10398, 0xdddf }, + /* 0x8a00 */ + { 10411, 0xd59d }, { 10421, 0xe9ef }, { 10433, 0x34ac }, { 10440, 0xde53 }, + { 10450, 0xf573 }, { 10461, 0x4bf7 }, { 10472, 0x7b4f }, { 10483, 0x9eff }, + { 10496, 0xb8fe }, { 10507, 0x476e }, { 10516, 0x0dfb }, { 10526, 0xff45 }, + { 10537, 0xabfd }, { 10549, 0xfbfe }, { 10563, 0xe9d7 }, { 10574, 0xddff }, + /* 0x8b00 */ + { 10588, 0xedf7 }, { 10601, 0x7fff }, { 10616, 0xddfd }, { 10629, 0x7eeb }, + { 10641, 0xcfe7 }, { 10653, 0xb7ff }, { 10667, 0xbde9 }, { 10678, 0xef91 }, + { 10688, 0x5d75 }, { 10698, 0xd77c }, { 10709, 0x0000 }, { 10709, 0x0000 }, + { 10709, 0x0000 }, { 10709, 0x0000 }, { 10709, 0x0000 }, { 10709, 0x0000 }, + /* 0x8c00 */ + { 10709, 0x0000 }, { 10709, 0x0000 }, { 10709, 0x0000 }, { 10709, 0xfa80 }, + { 10716, 0xffee }, { 10730, 0xb4f1 }, { 10739, 0xbf76 }, { 10751, 0x2fef }, + { 10763, 0xb677 }, { 10774, 0x77bf }, { 10787, 0x9fbf }, { 10800, 0xfffd }, + { 10815, 0x95bf }, { 10826, 0xf6ae }, { 10837, 0x75ff }, { 10850, 0x7f3b }, + /* 0x8d00 */ + { 10862, 0xa7f5 }, { 10873, 0x0af9 }, { 10881, 0x0000 }, { 10881, 0x0000 }, + { 10881, 0x0000 }, { 10881, 0x0000 }, { 10881, 0xfbd0 }, { 10891, 0x2bdd }, + { 10901, 0xf633 }, { 10911, 0x9a7f }, { 10922, 0xfdab }, { 10934, 0xd6fc }, + { 10945, 0xf9e6 }, { 10956, 0xbfeb }, { 10969, 0xdfdf }, { 10983, 0xf41f }, + /* 0x8e00 */ + { 10993, 0xa6fd }, { 11004, 0xffff }, { 11020, 0x4aff }, { 11031, 0xf37b }, + { 11043, 0x7fb7 }, { 11056, 0xfef9 }, { 11069, 0xb6ff }, { 11082, 0x1d5c }, + { 11090, 0x7ff6 }, { 11103, 0xe5ff }, { 11116, 0x1f7b }, { 11127, 0x2404 }, + { 11130, 0xbe05 }, { 11138, 0xf99e }, { 11149, 0xdbe3 }, { 11160, 0xdff2 }, + /* 0x8f00 */ + { 11172, 0x6fef }, { 11185, 0xfdff }, { 11200, 0xd679 }, { 11210, 0xcbfc }, + { 11221, 0xebfd }, { 11234, 0xefff }, { 11249, 0x001f }, { 11254, 0x0000 }, + { 11254, 0x0000 }, { 11254, 0x9800 }, { 11257, 0xe148 }, { 11263, 0x8017 }, + { 11268, 0x6a74 }, { 11276, 0x00fe }, { 11283, 0x6d7f }, { 11295, 0xfdf1 }, + /* 0x9000 */ + { 11307, 0xb87f }, { 11318, 0xfef3 }, { 11331, 0xe01f }, { 11339, 0xf176 }, + { 11349, 0xee96 }, { 11359, 0x7b3f }, { 11371, 0xeb8d }, { 11381, 0xfffd }, + { 11396, 0xadff }, { 11409, 0xcbb3 }, { 11419, 0x84ef }, { 11428, 0xe17f }, + { 11439, 0x4daa }, { 11447, 0xbff0 }, { 11458, 0xbf3f }, { 11471, 0xfe3f }, + /* 0x9100 */ + { 11484, 0xebff }, { 11498, 0xffd7 }, { 11512, 0xffdf }, { 11527, 0xcf7f }, + { 11540, 0xfffb }, { 11555, 0x85ed }, { 11564, 0xd73f }, { 11576, 0x07bc }, + { 11584, 0xaeff }, { 11597, 0xfe0f }, { 11608, 0xfdaf }, { 11621, 0x76bf }, + { 11633, 0xfaef }, { 11646, 0x37bb }, { 11657, 0x7fdc }, { 11669, 0xa3ba }, + /* 0x9200 */ + { 11678, 0xb6ff }, { 11691, 0x56f7 }, { 11702, 0x60f8 }, { 11709, 0xe7df }, + { 11722, 0xff61 }, { 11733, 0x4cdf }, { 11743, 0xb0fb }, { 11753, 0xff45 }, + { 11764, 0x7ded }, { 11776, 0x3ffa }, { 11788, 0x1fff }, { 11801, 0x18fc }, + { 11809, 0xffff }, { 11825, 0xe3af }, { 11836, 0xc7d3 }, { 11846, 0xdf83 }, + /* 0x9300 */ + { 11856, 0xfb57 }, { 11868, 0xef7d }, { 11881, 0xefff }, { 11896, 0x1378 }, + { 11903, 0xfec0 }, { 11912, 0x5ff7 }, { 11925, 0x34bb }, { 11934, 0x5ee3 }, + { 11944, 0xf70d }, { 11954, 0xeff6 }, { 11967, 0xd7fe }, { 11980, 0x00bf }, + { 11987, 0xf59d }, { 11998, 0xf7f7 }, { 12012, 0x51de }, { 12021, 0xffe0 }, + /* 0x9400 */ + { 12032, 0xfec9 }, { 12043, 0x037f }, { 12052, 0x5f01 }, { 12059, 0xbfef }, + { 12073, 0x9ff1 }, { 12084, 0x60a7 }, { 12091, 0xef1d }, { 12102, 0xf1ff }, + { 12115, 0x000f }, { 12119, 0x0000 }, { 12119, 0x0000 }, { 12119, 0x0000 }, + { 12119, 0x0000 }, { 12119, 0x0000 }, { 12119, 0x0000 }, { 12119, 0x0000 }, + /* 0x9500 */ + { 12119, 0x0000 }, { 12119, 0x0000 }, { 12119, 0x0000 }, { 12119, 0x0000 }, + { 12119, 0x0000 }, { 12119, 0x0000 }, { 12119, 0x0000 }, { 12119, 0x3c80 }, + { 12124, 0xfb4d }, { 12135, 0xd91f }, { 12145, 0x7b3a }, { 12155, 0xfee3 }, + { 12167, 0x3fe9 }, { 12178, 0xdc7f }, { 12190, 0x003f }, { 12196, 0x0000 }, + /* 0x9600 */ + { 12196, 0x0000 }, { 12196, 0x5000 }, { 12198, 0xf51f }, { 12209, 0xbe07 }, + { 12218, 0xfc1d }, { 12228, 0xf91b }, { 12238, 0xbc1e }, { 12247, 0x71ff }, + { 12259, 0x6ff9 }, { 12271, 0x5bbe }, { 12282, 0x5796 }, { 12291, 0x9b1b }, + { 12300, 0x7fff }, { 12315, 0xfffc }, { 12329, 0x872e }, { 12337, 0xafe7 }, + /* 0x9700 */ + { 12349, 0xebf5 }, { 12361, 0xf34f }, { 12372, 0xdffd }, { 12386, 0xe725 }, + { 12395, 0x0bdc }, { 12403, 0x5d44 }, { 12410, 0x5747 }, { 12419, 0xfddd }, + { 12432, 0xed3f }, { 12444, 0x7790 }, { 12452, 0x7d7f }, { 12465, 0x8ac8 }, + { 12471, 0xfafa }, { 12483, 0xf3f9 }, { 12495, 0x202a }, { 12499, 0xef4b }, + /* 0x9800 */ + { 12510, 0xf5ff }, { 12524, 0x79cf }, { 12535, 0xabd3 }, { 12545, 0x0ba5 }, + { 12552, 0xf77a }, { 12564, 0xfb8f }, { 12576, 0x8ebd }, { 12586, 0x001f }, + { 12591, 0x0000 }, { 12591, 0x0000 }, { 12591, 0xf300 }, { 12597, 0xfd4e }, + { 12608, 0x1a57 }, { 12616, 0x8800 }, { 12618, 0xaeac }, { 12627, 0x7654 }, + /* 0x9900 */ + { 12635, 0x17ad }, { 12644, 0xcdff }, { 12657, 0xffb2 }, { 12669, 0xf42f }, + { 12679, 0x5baa }, { 12688, 0xdbff }, { 12702, 0x0002 }, { 12703, 0x0000 }, + { 12703, 0x0000 }, { 12703, 0x73c0 }, { 12710, 0xf9ea }, { 12721, 0x2e3f }, + { 12731, 0xfa8e }, { 12741, 0xbbff }, { 12755, 0x76bc }, { 12765, 0xffd3 }, + /* 0x9a00 */ + { 12778, 0xeefe }, { 12791, 0x7e72 }, { 12801, 0x7ebd }, { 12813, 0xe7f7 }, + { 12826, 0xf77f }, { 12840, 0xcefd }, { 12852, 0x0ff5 }, { 12862, 0x0000 }, + { 12862, 0x0000 }, { 12862, 0x0000 }, { 12862, 0xa900 }, { 12866, 0xdb9b }, + { 12877, 0xa4c7 }, { 12885, 0x917f }, { 12895, 0xf8ca }, { 12904, 0x7ece }, + /* 0x9b00 */ + { 12915, 0x7d7a }, { 12926, 0xc7e7 }, { 12937, 0xcbbd }, { 12948, 0xdcae }, + { 12958, 0xfd7e }, { 12971, 0x8f76 }, { 12981, 0x91d3 }, { 12989, 0x7cf3 }, + { 13000, 0x01e5 }, { 13006, 0x4c2f }, { 13014, 0xed77 }, { 13026, 0xa360 }, + { 13032, 0x07db }, { 13041, 0x5ef8 }, { 13051, 0x1df7 }, { 13062, 0x2181 }, + /* 0x9c00 */ + { 13066, 0x6be0 }, { 13074, 0x309c }, { 13080, 0x3b3a }, { 13089, 0xfade }, + { 13101, 0x7f53 }, { 13112, 0xc3f5 }, { 13122, 0x61cd }, { 13130, 0x07ba }, + { 13138, 0x0000 }, { 13138, 0x0000 }, { 13138, 0x0000 }, { 13138, 0x0000 }, + { 13138, 0x0000 }, { 13138, 0x0000 }, { 13138, 0x26e0 }, { 13144, 0xbefe }, + /* 0x9d00 */ + { 13157, 0x03f9 }, { 13165, 0xebb5 }, { 13176, 0xe36d }, { 13186, 0xe9cb }, + { 13196, 0x9c2f }, { 13205, 0xbfde }, { 13218, 0x9f83 }, { 13227, 0xabbf }, + { 13239, 0x1ff7 }, { 13251, 0xffd5 }, { 13264, 0xb7df }, { 13277, 0xdffe }, + { 13291, 0xfdae }, { 13303, 0xffef }, { 13318, 0xfb7e }, { 13331, 0xeffd }, + /* 0x9e00 */ + { 13345, 0xaaff }, { 13357, 0x6ebf }, { 13369, 0x0000 }, { 13369, 0x0000 }, + { 13369, 0x0000 }, { 13369, 0x0000 }, { 13369, 0x0000 }, { 13369, 0xb620 }, + { 13375, 0x7fcd }, { 13387, 0xbe9e }, { 13398, 0x62b3 }, { 13406, 0x58f1 }, + { 13414, 0xf10d }, { 13422, 0xfd7b }, { 13435, 0xe9f1 }, { 13445, 0xbefd }, + /* 0x9f00 */ + { 13458, 0xc6c3 }, { 13466, 0x5f6d }, { 13477, 0xff3d }, { 13490, 0x69ff }, + { 13502, 0xffcf }, { 13516, 0xfbf4 }, { 13528, 0xdcfb }, { 13540, 0x4ff7 }, + { 13552, 0x2000 }, { 13553, 0x1137 }, { 13560, 0x0015 }, +}; +static const Summary16 big5_uni2indx_pagefa[1] = { + /* 0xfa00 */ + { 13563, 0x3000 }, +}; +static const Summary16 big5_uni2indx_pagefe[23] = { + /* 0xfe00 */ + { 13565, 0x0000 }, { 13565, 0x0000 }, { 13565, 0x0000 }, { 13565, 0xfffb }, + { 13580, 0xfe1f }, { 13592, 0xfef5 }, { 13605, 0x0e7f }, { 13615, 0x0000 }, + { 13615, 0x0000 }, { 13615, 0x0000 }, { 13615, 0x0000 }, { 13615, 0x0000 }, + { 13615, 0x0000 }, { 13615, 0x0000 }, { 13615, 0x0000 }, { 13615, 0x0000 }, + /* 0xff00 */ + { 13615, 0xff7a }, { 13628, 0xffff }, { 13644, 0xffff }, { 13660, 0x97ff }, + { 13673, 0xfffe }, { 13688, 0x3fff }, { 13702, 0x0010 }, +}; + +static int +big5_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc >= 0x0000 && wc < 0x0100) + summary = &big5_uni2indx_page00[(wc>>4)]; + else if (wc >= 0x0200 && wc < 0x0460) + summary = &big5_uni2indx_page02[(wc>>4)-0x020]; + else if (wc >= 0x2000 && wc < 0x22c0) + summary = &big5_uni2indx_page20[(wc>>4)-0x200]; + else if (wc >= 0x2400 && wc < 0x2650) + summary = &big5_uni2indx_page24[(wc>>4)-0x240]; + else if (wc >= 0x3000 && wc < 0x33e0) + summary = &big5_uni2indx_page30[(wc>>4)-0x300]; + else if (wc >= 0x4e00 && wc < 0x9fb0) + summary = &big5_uni2indx_page4e[(wc>>4)-0x4e0]; + else if (wc >= 0xfa00 && wc < 0xfa10) + summary = &big5_uni2indx_pagefa[(wc>>4)-0xfa0]; + else if (wc >= 0xfe00 && wc < 0xff70) + summary = &big5_uni2indx_pagefe[(wc>>4)-0xfe0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = big5_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/big5_2003.h b/libs/libiconv/lib/big5_2003.h new file mode 100644 index 00000000..b532ce6e --- /dev/null +++ b/libs/libiconv/lib/big5_2003.h @@ -0,0 +1,476 @@ +/* + * Copyright (C) 1999-2001, 2005 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * BIG5-2003 + */ + +/* + * BIG5-2003 is a slightly extended and slightly modified version of BIG5. + * It is actually nearer to Microsoft CP950 than to BIG5. The differences + * between EASTASIA/OTHER/BIG5.TXT found on ftp.unicode.org and BIG5-2003.TXT + * are as follows: + * + * 1. Some characters in the symbols area (0xA140..0xA2CE) are defined + * differently: + * + * code BIG5.TXT BIG5-2003.TXT + * 0xA145 0x2022 # BULLET 0x2027 # HYPHENATION POINT + * 0xA14E 0xFF64 # HALFWIDTH IDEOGRAPHIC COMMA + * 0xFE51 # SMALL IDEOGRAPHIC COMMA + * 0xA156 0x2013 # EN DASH 0x2015 # HORIZONTAL BAR + * 0xA15A --- 0x2574 # BOX DRAWINGS LIGHT LEFT + * 0xA1C3 --- 0xFFE3 # FULLWIDTH MACRON + * 0xA1C5 --- 0x02CD # MODIFIER LETTER LOW MACRON + * 0xA1E3 0x223C # TILDE OPERATOR 0xFF5E # FULLWIDTH TILDE + * 0xA1F2 0x2641 # EARTH 0x2295 # CIRCLED PLUS + * 0xA1F3 0x2609 # SUN 0x2299 # CIRCLED DOT OPERATOR + * 0xA1FE --- 0xFF0F # FULLWIDTH SOLIDUS + * 0xA240 --- 0xFF3C # FULLWIDTH REVERSE SOLIDUS + * 0xA241 0xFF0F # FULLWIDTH SOLIDUS 0x2215 # DIVISION SLASH + * 0xA242 0xFF3C # FULLWIDTH REVERSE SOLIDUS + * 0xFE68 # SMALL REVERSE SOLIDUS + * 0xA244 0x00A5 # YEN SIGN 0xFFE5 # FULLWIDTH YEN SIGN + * 0xA246 0x00A2 # CENT SIGN 0xFFE0 # FULLWIDTH CENT SIGN + * 0xA247 0x00A3 # POUND SIGN 0xFFE1 # FULLWIDTH POUND SIGN + * 0xA2A4 0x2550 # BOX DRAWINGS DOUBLE HORIZONTAL + * 0x2501 # BOX DRAWINGS HEAVY HORIZONTAL + * 0xA2A5 0x255E # BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE + * 0x251D # BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY + * 0xA2A6 0x256A # BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE + * 0x253F # BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY + * 0xA2A7 0x2561 # BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE + * 0x2525 # BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY + * 0xA2CC --- 0x3038 # HANGZHOU NUMERAL TEN + * 0xA2CD 0x5344 0x3039 # HANGZHOU NUMERAL TWENTY + * 0xA2CE --- 0x303A # HANGZHOU NUMERAL THIRTY + * + * 2. A control symbols area is added: + * + * code + * 0xA3C0..0xA3E0 U+2400..U+2421 + * + * 3. The Euro sign is added: + * + * code + * 0xA3E1 0x20AC # EURO SIGN + * + * 4. Some characters in the main area are defined differently: + * + * code BIG5.TXT BIG5-2003.TXT + * 0xC255 0x5F5D 0x5F5E + * + * 5. The area 0xC6A1..0xC7FE is organized differently: + * + * code + * 0xC6A1..0xC6BE numerals (was in BIG5.TXT at 0xC7E9..0xC7FC) + * 0xC6BF..0xC6D7 radicals + * 0xC6D8..0xC6E6 rarely used symbols + * 0xC6E7..0xC77A hiragana (U+3041..U+3093, was in BIG5.TXT at 0xC6A5..0xC6F7) + * 0xC77B..0xC7F2 katakana (U+30A1..U+30F6, was in BIG5.TXT at 0xC6F8..0xC7B0) + * + * 6. Some characters are added at 0xF9D6..0xF9DC. + * + * 7. Box drawing characters are added at 0xF9DD..0xF9FE. + * + * Note: 4 of these characters are mapped in a non-inversible way, because + * Unicode does not yet include the corresponding characters: + * + * code Unicode approximation + * 0xF9FA BOX DRAWINGS DOUBLE ARC DOWN AND RIGHT 0x2554 + * 0xF9FB BOX DRAWINGS DOUBLE ARC DOWN AND LEFT 0x2557 + * 0xF9FC BOX DRAWINGS DOUBLE ARC UP AND RIGHT 0x255A + * 0xF9FD BOX DRAWINGS DOUBLE ARC UP AND LEFT 0x255D + * + * 8. Private area mappings are added: + * + * code Unicode + * 0x{81..8D}{40..7E,A1..FE} U+EEB8..U+F6B0 + * 0x{8E..A0}{40..7E,A1..FE} U+E311..U+EEB7 + * 0x{FA..FE}{40..7E,A1..FE} U+E000..U+E310 + * + * These mappings are not contained in the BSMI Big5-2003 standard. However, + * they were contained in a draft of it. + */ + +static const unsigned short big5_2003_2uni_pagea1[314] = { + /* 0xa1 */ + 0x3000, 0xff0c, 0x3001, 0x3002, 0xff0e, 0x2027, 0xff1b, 0xff1a, + 0xff1f, 0xff01, 0xfe30, 0x2026, 0x2025, 0xfe50, 0xfe51, 0xfe52, + 0x00b7, 0xfe54, 0xfe55, 0xfe56, 0xfe57, 0xff5c, 0x2015, 0xfe31, + 0x2014, 0xfe33, 0x2574, 0xfe34, 0xfe4f, 0xff08, 0xff09, 0xfe35, + 0xfe36, 0xff5b, 0xff5d, 0xfe37, 0xfe38, 0x3014, 0x3015, 0xfe39, + 0xfe3a, 0x3010, 0x3011, 0xfe3b, 0xfe3c, 0x300a, 0x300b, 0xfe3d, + 0xfe3e, 0x3008, 0x3009, 0xfe3f, 0xfe40, 0x300c, 0x300d, 0xfe41, + 0xfe42, 0x300e, 0x300f, 0xfe43, 0xfe44, 0xfe59, 0xfe5a, 0xfe5b, + 0xfe5c, 0xfe5d, 0xfe5e, 0x2018, 0x2019, 0x201c, 0x201d, 0x301d, + 0x301e, 0x2035, 0x2032, 0xff03, 0xff06, 0xff0a, 0x203b, 0x00a7, + 0x3003, 0x25cb, 0x25cf, 0x25b3, 0x25b2, 0x25ce, 0x2606, 0x2605, + 0x25c7, 0x25c6, 0x25a1, 0x25a0, 0x25bd, 0x25bc, 0x32a3, 0x2105, + 0x203e, 0xffe3, 0xff3f, 0x02cd, 0xfe49, 0xfe4a, 0xfe4d, 0xfe4e, + 0xfe4b, 0xfe4c, 0xfe5f, 0xfe60, 0xfe61, 0xff0b, 0xff0d, 0x00d7, + 0x00f7, 0x00b1, 0x221a, 0xff1c, 0xff1e, 0xff1d, 0x2266, 0x2267, + 0x2260, 0x221e, 0x2252, 0x2261, 0xfe62, 0xfe63, 0xfe64, 0xfe65, + 0xfe66, 0xff5e, 0x2229, 0x222a, 0x22a5, 0x2220, 0x221f, 0x22bf, + 0x33d2, 0x33d1, 0x222b, 0x222e, 0x2235, 0x2234, 0x2640, 0x2642, + 0x2295, 0x2299, 0x2191, 0x2193, 0x2190, 0x2192, 0x2196, 0x2197, + 0x2199, 0x2198, 0x2225, 0x2223, 0xff0f, + /* 0xa2 */ + 0xff3c, 0x2215, 0xfe68, 0xff04, 0xffe5, 0x3012, 0xffe0, 0xffe1, + 0xff05, 0xff20, 0x2103, 0x2109, 0xfe69, 0xfe6a, 0xfe6b, 0x33d5, + 0x339c, 0x339d, 0x339e, 0x33ce, 0x33a1, 0x338e, 0x338f, 0x33c4, + 0x00b0, 0x5159, 0x515b, 0x515e, 0x515d, 0x5161, 0x5163, 0x55e7, + 0x74e9, 0x7cce, 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586, + 0x2587, 0x2588, 0x258f, 0x258e, 0x258d, 0x258c, 0x258b, 0x258a, + 0x2589, 0x253c, 0x2534, 0x252c, 0x2524, 0x251c, 0x2594, 0x2500, + 0x2502, 0x2595, 0x250c, 0x2510, 0x2514, 0x2518, 0x256d, 0x256e, + 0x2570, 0x256f, 0x2501, 0x251d, 0x253f, 0x2525, 0x25e2, 0x25e3, + 0x25e5, 0x25e4, 0x2571, 0x2572, 0x2573, 0xff10, 0xff11, 0xff12, + 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18, 0xff19, 0x2160, + 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, + 0x2169, 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, 0x3027, + 0x3028, 0x3029, 0x3038, 0x3039, 0x303a, 0xff21, 0xff22, 0xff23, + 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, 0xff29, 0xff2a, 0xff2b, + 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, 0xff31, 0xff32, 0xff33, + 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, 0xff39, 0xff3a, 0xff41, + 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, 0xff49, + 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, 0xff51, + 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, +}; + +static const unsigned short big5_2003_2uni_pagec6[70] = { + /* 0xc6a1 */ + 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, + 0x2468, 0x2469, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478, 0x2479, + 0x247a, 0x247b, 0x247c, 0x247d, 0x2170, 0x2171, 0x2172, 0x2173, + 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, 0x2f02, 0x2f03, + 0x2f05, 0x2f07, 0x2f0c, 0x2f0d, 0x2f0e, 0x2f13, 0x2f16, 0x2f19, + 0x2f1b, 0x2f22, 0x2f27, 0x2f2e, 0x2f33, 0x2f34, 0x2f35, 0x2f39, + 0x2f3a, 0x2f41, 0x2f46, 0x2f67, 0x2f68, 0x2fa1, 0x2faa, 0x00a8, + 0xff3e, 0x30fd, 0x30fe, 0x309d, 0x309e, 0xfffd, 0xfffd, 0x3005, + 0x3006, 0x3007, 0x30fc, 0xff3b, 0xff3d, 0x273d, +}; + +static const unsigned short big5_2003_2uni_pagef9[41] = { + /* 0xf9d6 */ + 0x7881, 0x92b9, 0x88cf, 0x58bb, 0x6052, 0x7ca7, 0x5afa, + /* 0xf9dd */ + 0x2554, 0x2566, 0x2557, 0x2560, 0x256c, 0x2563, 0x255a, 0x2569, + 0x255d, 0x2552, 0x2564, 0x2555, 0x255e, 0x256a, 0x2561, 0x2558, + 0x2567, 0x255b, 0x2553, 0x2565, 0x2556, 0x255f, 0x256b, 0x2562, + 0x2559, 0x2568, 0x255c, 0x2551, 0x2550, + 0x2554, 0x2557, 0x255a, 0x255d, /* not invertible */ + 0x2593, +}; + +static int +big5_2003_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + /* Code set 0 (ASCII) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* Code set 1 (BIG5 extended) */ + if (c >= 0x81 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) { + if (c >= 0xa1) { + if (c < 0xa3) { + unsigned int i = 157 * (c - 0xa1) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); + unsigned short wc = big5_2003_2uni_pagea1[i]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + if (!((c == 0xc6 && c2 >= 0xa1) || c == 0xc7)) { + if (!(c == 0xc2 && c2 == 0x55)) { + int ret = big5_mbtowc(conv,pwc,s,2); + if (ret != RET_ILSEQ) + return ret; + if (c == 0xa3) { + if (c2 >= 0xc0 && c2 <= 0xe1) { + *pwc = (c2 == 0xe1 ? 0x20ac : c2 == 0xe0 ? 0x2421 : 0x2340 + c2); + return 2; + } + } else if (c == 0xf9) { + if (c2 >= 0xd6) { + *pwc = big5_2003_2uni_pagef9[c2-0xd6]; + return 2; + } + } else if (c >= 0xfa) { + *pwc = 0xe000 + 157 * (c - 0xfa) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); + return 2; + } + } else { + /* c == 0xc2 && c2 == 0x55. */ + *pwc = 0x5f5e; + return 2; + } + } else { + /* (c == 0xc6 && c2 >= 0xa1) || c == 0xc7. */ + unsigned int i = 157 * (c - 0xc6) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); + if (i < 133) { + /* 63 <= i < 133. */ + unsigned short wc = big5_2003_2uni_pagec6[i-63]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } else if (i < 216) { + /* 133 <= i < 216. Hiragana. */ + *pwc = 0x3041 - 133 + i; + return 2; + } else if (i < 302) { + /* 216 <= i < 302. Katakana. */ + *pwc = 0x30a1 - 216 + i; + return 2; + } + } + } else { + /* 0x81 <= c < 0xa1. */ + *pwc = (c >= 0x8e ? 0xdb18 : 0xeeb8) + 157 * (c - 0x81) + + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); + return 2; + } + } + } + } + return RET_ILSEQ; +} + +static const unsigned char big5_2003_2charset_page25[29] = { + /* 0x2550 */ + 0xf9, 0xf8, 0xe6, 0xef, 0xdd, 0xe8, 0xf1, 0xdf, + 0xec, 0xf5, 0xe3, 0xee, 0xf7, 0xe5, 0xe9, 0xf2, + 0xe0, 0xeb, 0xf4, 0xe2, 0xe7, 0xf0, 0xde, 0xed, + 0xf6, 0xe4, 0xea, 0xf3, 0xe1, +}; + +static int +big5_2003_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[2]; + int ret; + + /* Code set 0 (ASCII) */ + ret = ascii_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + /* Code set 1 (BIG5 extended) */ + switch (wc >> 8) { + case 0x00: + if (wc == 0x00a8) { buf[0] = 0xc6; buf[1] = 0xd8; ret = 2; break; } + if (wc == 0x00a2 || wc == 0x00a3 || wc == 0x00a5) + return RET_ILUNI; + break; + case 0x02: + if (wc == 0x02cd) { buf[0] = 0xa1; buf[1] = 0xc5; ret = 2; break; } + break; + case 0x04: + return RET_ILUNI; + case 0x20: + if (wc == 0x2015) { buf[0] = 0xa1; buf[1] = 0x56; ret = 2; break; } + if (wc == 0x2027) { buf[0] = 0xa1; buf[1] = 0x45; ret = 2; break; } + if (wc == 0x20ac) { buf[0] = 0xa3; buf[1] = 0xe1; ret = 2; break; } + if (wc == 0x2013 || wc == 0x2022) + return RET_ILUNI; + break; + case 0x21: + if (wc >= 0x2170 && wc <= 0x2179) { + buf[0] = 0xc6; buf[1] = wc - 0x20bb; ret = 2; + break; + } + break; + case 0x22: + if (wc == 0x2215) { buf[0] = 0xa2; buf[1] = 0x41; ret = 2; break; } + if (wc == 0x2295) { buf[0] = 0xa1; buf[1] = 0xf2; ret = 2; break; } + if (wc == 0x2299) { buf[0] = 0xa1; buf[1] = 0xf3; ret = 2; break; } + if (wc == 0x223c) + return RET_ILUNI; + break; + case 0x24: + if (wc <= 0x241f) { buf[0] = 0xa3; buf[1] = wc - 0x2340; ret = 2; break; } + if (wc == 0x2421) { buf[0] = 0xa3; buf[1] = 0xe0; ret = 2; break; } + if (wc >= 0x2460 && wc <= 0x2469) { + buf[0] = 0xc6; buf[1] = wc - 0x23bf; ret = 2; + break; + } + if (wc >= 0x2474 && wc <= 0x247d) { + buf[0] = 0xc6; buf[1] = wc - 0x23c9; ret = 2; + break; + } + break; + case 0x25: + if (wc == 0x2501) { buf[0] = 0xa2; buf[1] = 0xa4; ret = 2; break; } + if (wc == 0x251d) { buf[0] = 0xa2; buf[1] = 0xa5; ret = 2; break; } + if (wc == 0x2525) { buf[0] = 0xa2; buf[1] = 0xa7; ret = 2; break; } + if (wc == 0x253f) { buf[0] = 0xa2; buf[1] = 0xa6; ret = 2; break; } + if (wc >= 0x2550 && wc <= 0x256c) { + buf[0] = 0xf9; buf[1] = big5_2003_2charset_page25[wc-0x2550]; ret = 2; + break; + } + if (wc == 0x2574) { buf[0] = 0xa1; buf[1] = 0x5a; ret = 2; break; } + if (wc == 0x2593) { buf[0] = 0xf9; buf[1] = 0xfe; ret = 2; break; } + break; + case 0x26: + if (wc == 0x2609 || wc == 0x2641) + return RET_ILUNI; + break; + case 0x27: + if (wc == 0x273d) { buf[0] = 0xc6; buf[1] = 0xe6; ret = 2; break; } + break; + case 0x2f: + if (wc == 0x2f02) { buf[0] = 0xc6; buf[1] = 0xbf; ret = 2; break; } + if (wc == 0x2f03) { buf[0] = 0xc6; buf[1] = 0xc0; ret = 2; break; } + if (wc == 0x2f05) { buf[0] = 0xc6; buf[1] = 0xc1; ret = 2; break; } + if (wc == 0x2f07) { buf[0] = 0xc6; buf[1] = 0xc2; ret = 2; break; } + if (wc == 0x2f0c) { buf[0] = 0xc6; buf[1] = 0xc3; ret = 2; break; } + if (wc == 0x2f0d) { buf[0] = 0xc6; buf[1] = 0xc4; ret = 2; break; } + if (wc == 0x2f0e) { buf[0] = 0xc6; buf[1] = 0xc5; ret = 2; break; } + if (wc == 0x2f13) { buf[0] = 0xc6; buf[1] = 0xc6; ret = 2; break; } + if (wc == 0x2f16) { buf[0] = 0xc6; buf[1] = 0xc7; ret = 2; break; } + if (wc == 0x2f19) { buf[0] = 0xc6; buf[1] = 0xc8; ret = 2; break; } + if (wc == 0x2f1b) { buf[0] = 0xc6; buf[1] = 0xc9; ret = 2; break; } + if (wc == 0x2f22) { buf[0] = 0xc6; buf[1] = 0xca; ret = 2; break; } + if (wc == 0x2f27) { buf[0] = 0xc6; buf[1] = 0xcb; ret = 2; break; } + if (wc == 0x2f2e) { buf[0] = 0xc6; buf[1] = 0xcc; ret = 2; break; } + if (wc == 0x2f33) { buf[0] = 0xc6; buf[1] = 0xcd; ret = 2; break; } + if (wc == 0x2f34) { buf[0] = 0xc6; buf[1] = 0xce; ret = 2; break; } + if (wc == 0x2f35) { buf[0] = 0xc6; buf[1] = 0xcf; ret = 2; break; } + if (wc == 0x2f39) { buf[0] = 0xc6; buf[1] = 0xd0; ret = 2; break; } + if (wc == 0x2f3a) { buf[0] = 0xc6; buf[1] = 0xd1; ret = 2; break; } + if (wc == 0x2f41) { buf[0] = 0xc6; buf[1] = 0xd2; ret = 2; break; } + if (wc == 0x2f46) { buf[0] = 0xc6; buf[1] = 0xd3; ret = 2; break; } + if (wc == 0x2f67) { buf[0] = 0xc6; buf[1] = 0xd4; ret = 2; break; } + if (wc == 0x2f68) { buf[0] = 0xc6; buf[1] = 0xd5; ret = 2; break; } + if (wc == 0x2fa1) { buf[0] = 0xc6; buf[1] = 0xd6; ret = 2; break; } + if (wc == 0x2faa) { buf[0] = 0xc6; buf[1] = 0xd7; ret = 2; break; } + break; + case 0x30: + if (wc >= 0x3005 && wc <= 0x3007) { + buf[0] = 0xc6; buf[1] = wc - 0x2f25; ret = 2; + break; + } + if (wc >= 0x3038 && wc <= 0x303a) { + buf[0] = 0xa2; buf[1] = wc - 0x2f6c; ret = 2; + break; + } + if (wc >= 0x3041 && wc <= 0x3093) { + if (wc < 0x3059) { + buf[0] = 0xc6; buf[1] = wc - 0x2f5a; + } else { + buf[0] = 0xc7; buf[1] = wc - 0x3019; + } + ret = 2; + break; + } + if (wc == 0x309d) { buf[0] = 0xc6; buf[1] = 0xdc; ret = 2; break; } + if (wc == 0x309e) { buf[0] = 0xc6; buf[1] = 0xdd; ret = 2; break; } + if (wc >= 0x30a1 && wc <= 0x30f6) { + buf[0] = 0xc7; buf[1] = wc - (wc < 0x30a5 ? 0x3026 : 0x3004); ret = 2; + break; + } + if (wc == 0x30fc) { buf[0] = 0xc6; buf[1] = 0xe3; ret = 2; break; } + if (wc == 0x30fd) { buf[0] = 0xc6; buf[1] = 0xda; ret = 2; break; } + if (wc == 0x30fe) { buf[0] = 0xc6; buf[1] = 0xdb; ret = 2; break; } + break; + case 0x53: + if (wc == 0x5344) + return RET_ILUNI; + break; + case 0x58: + if (wc == 0x58bb) { buf[0] = 0xf9; buf[1] = 0xd9; ret = 2; break; } + break; + case 0x5a: + if (wc == 0x5afa) { buf[0] = 0xf9; buf[1] = 0xdc; ret = 2; break; } + break; + case 0x5f: + if (wc == 0x5f5e) { buf[0] = 0xc2; buf[1] = 0x55; ret = 2; break; } + if (wc == 0x5f5d) + return RET_ILUNI; + break; + case 0x60: + if (wc == 0x6052) { buf[0] = 0xf9; buf[1] = 0xda; ret = 2; break; } + break; + case 0x78: + if (wc == 0x7881) { buf[0] = 0xf9; buf[1] = 0xd6; ret = 2; break; } + break; + case 0x7c: + if (wc == 0x7ca7) { buf[0] = 0xf9; buf[1] = 0xdb; ret = 2; break; } + break; + case 0x88: + if (wc == 0x88cf) { buf[0] = 0xf9; buf[1] = 0xd8; ret = 2; break; } + break; + case 0x92: + if (wc == 0x92b9) { buf[0] = 0xf9; buf[1] = 0xd7; ret = 2; break; } + break; + case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: + case 0xe6: case 0xe7: case 0xe8: case 0xe9: case 0xea: case 0xeb: + case 0xec: case 0xed: case 0xee: case 0xef: case 0xf0: case 0xf1: + case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: + { + unsigned int i = wc - 0xe000; + if (i < 5809) { + unsigned int c1 = i / 157; + unsigned int c2 = i % 157; + buf[0] = c1 + (c1 < 5 ? 0xfa : c1 < 24 ? 0x89 : 0x69); + buf[1] = c2 + (c2 < 0x3f ? 0x40 : 0x62); + ret = 2; + break; + } + } + break; + case 0xfe: + if (wc == 0xfe51) { buf[0] = 0xa1; buf[1] = 0x4e; ret = 2; break; } + if (wc == 0xfe68) { buf[0] = 0xa2; buf[1] = 0x42; ret = 2; break; } + break; + case 0xff: + if (wc == 0xff0f) { buf[0] = 0xa1; buf[1] = 0xfe; ret = 2; break; } + if (wc == 0xff3b) { buf[0] = 0xc6; buf[1] = 0xe4; ret = 2; break; } + if (wc == 0xff3c) { buf[0] = 0xa2; buf[1] = 0x40; ret = 2; break; } + if (wc == 0xff3d) { buf[0] = 0xc6; buf[1] = 0xe5; ret = 2; break; } + if (wc == 0xff3e) { buf[0] = 0xc6; buf[1] = 0xd9; ret = 2; break; } + if (wc == 0xff5e) { buf[0] = 0xa1; buf[1] = 0xe3; ret = 2; break; } + if (wc == 0xffe0) { buf[0] = 0xa2; buf[1] = 0x46; ret = 2; break; } + if (wc == 0xffe1) { buf[0] = 0xa2; buf[1] = 0x47; ret = 2; break; } + if (wc == 0xffe3) { buf[0] = 0xa1; buf[1] = 0xc3; ret = 2; break; } + if (wc == 0xffe5) { buf[0] = 0xa2; buf[1] = 0x44; ret = 2; break; } + if (wc == 0xff64) + return RET_ILUNI; + break; + } + if (ret == RET_ILUNI) + ret = big5_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]; + r[1] = buf[1]; + return 2; + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/big5hkscs1999.h b/libs/libiconv/lib/big5hkscs1999.h new file mode 100644 index 00000000..9e0d1b0c --- /dev/null +++ b/libs/libiconv/lib/big5hkscs1999.h @@ -0,0 +1,197 @@ +/* + * Copyright (C) 1999-2002, 2006 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * BIG5-HKSCS:1999 + */ + +/* + * BIG5-HKSCS:1999 can be downloaded from + * http://www.info.gov.hk/digital21/eng/hkscs/download.html + * http://www.info.gov.hk/digital21/eng/hkscs/index.html + * + * It extends BIG5 (without the rows 0xC6..0xC7) through the ranges + * + * 0x{88..8D}{40..7E,A1..FE} 641 characters + * 0x{8E..A0}{40..7E,A1..FE} 2898 characters + * 0x{C6..C8}{40..7E,A1..FE} 359 characters + * 0xF9{D6..FE} 41 characters + * 0x{FA..FE}{40..7E,A1..FE} 763 characters + * + * Note that some HKSCS characters are not contained in Unicode 3.2 + * and are therefore best represented as sequences of Unicode characters: + * 0x8862 U+00CA U+0304 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND MACRON + * 0x8864 U+00CA U+030C LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND CARON + * 0x88A3 U+00EA U+0304 LATIN SMALL LETTER E WITH CIRCUMFLEX AND MACRON + * 0x88A5 U+00EA U+030C LATIN SMALL LETTER E WITH CIRCUMFLEX AND CARON + */ + +#include "hkscs1999.h" +#include "flushwc.h" + +static int +big5hkscs1999_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + ucs4_t last_wc = conv->istate; + if (last_wc) { + /* Output the buffered character. */ + conv->istate = 0; + *pwc = last_wc; + return 0; /* Don't advance the input pointer. */ + } else { + unsigned char c = *s; + /* Code set 0 (ASCII) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* Code set 1 (BIG5 extended) */ + if (c >= 0xa1 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) { + if (!((c == 0xc6 && c2 >= 0xa1) || c == 0xc7)) { + int ret = big5_mbtowc(conv,pwc,s,2); + if (ret != RET_ILSEQ) + return ret; + } + } + } + } + { + int ret = hkscs1999_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + } + if (c == 0x88) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if (c2 == 0x62 || c2 == 0x64 || c2 == 0xa3 || c2 == 0xa5) { + /* It's a composed character. */ + ucs4_t wc1 = ((c2 >> 3) << 2) + 0x009a; /* = 0x00ca or 0x00ea */ + ucs4_t wc2 = ((c2 & 6) << 2) + 0x02fc; /* = 0x0304 or 0x030c */ + /* We cannot output two Unicode characters at once. So, + output the first character and buffer the second one. */ + *pwc = wc1; + conv->istate = wc2; + return 2; + } + } + } + return RET_ILSEQ; + } +} + +#define big5hkscs1999_flushwc normal_flushwc + +static int +big5hkscs1999_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + int count = 0; + unsigned char last = conv->ostate; + + if (last) { + /* last is = 0x66 or = 0xa7. */ + if (wc == 0x0304 || wc == 0x030c) { + /* Output the combined character. */ + if (n >= 2) { + r[0] = 0x88; + r[1] = last + ((wc & 24) >> 2) - 4; /* = 0x62 or 0x64 or 0xa3 or 0xa5 */ + conv->ostate = 0; + return 2; + } else + return RET_TOOSMALL; + } + + /* Output the buffered character. */ + if (n < 2) + return RET_TOOSMALL; + r[0] = 0x88; + r[1] = last; + r += 2; + count = 2; + } + + /* Code set 0 (ASCII) */ + if (wc < 0x0080) { + /* Plain ASCII character. */ + if (n > count) { + r[0] = (unsigned char) wc; + conv->ostate = 0; + return count+1; + } else + return RET_TOOSMALL; + } else { + unsigned char buf[2]; + int ret; + + /* Code set 1 (BIG5 extended) */ + ret = big5_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (!((buf[0] == 0xc6 && buf[1] >= 0xa1) || buf[0] == 0xc7)) { + if (n >= count+2) { + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + } + ret = hkscs1999_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if ((wc & ~0x0020) == 0x00ca) { + /* A possible first character of a multi-character sequence. We have to + buffer it. */ + if (!(buf[0] == 0x88 && (buf[1] == 0x66 || buf[1] == 0xa7))) abort(); + conv->ostate = buf[1]; /* = 0x66 or = 0xa7 */ + return count+0; + } + if (n >= count+2) { + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + return RET_ILUNI; + } +} + +static int +big5hkscs1999_reset (conv_t conv, unsigned char *r, int n) +{ + unsigned char last = conv->ostate; + + if (last) { + if (n < 2) + return RET_TOOSMALL; + r[0] = 0x88; + r[1] = last; + /* conv->ostate = 0; will be done by the caller */ + return 2; + } else + return 0; +} diff --git a/libs/libiconv/lib/big5hkscs2001.h b/libs/libiconv/lib/big5hkscs2001.h new file mode 100644 index 00000000..2d378c48 --- /dev/null +++ b/libs/libiconv/lib/big5hkscs2001.h @@ -0,0 +1,215 @@ +/* + * Copyright (C) 1999-2002, 2006 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * BIG5-HKSCS:2001 + */ + +/* + * BIG5-HKSCS:2001 can be downloaded from + * http://www.info.gov.hk/digital21/eng/hkscs/download.html + * http://www.info.gov.hk/digital21/eng/hkscs/index.html + * + * It extends BIG5-HKSCS:1999 through 116 characters. + * + * It extends BIG5 (without the rows 0xC6..0xC7) through the ranges + * + * 0x{88..8D}{40..7E,A1..FE} 757 characters + * 0x{8E..A0}{40..7E,A1..FE} 2898 characters + * 0x{C6..C8}{40..7E,A1..FE} 359 characters + * 0xF9{D6..FE} 41 characters + * 0x{FA..FE}{40..7E,A1..FE} 763 characters + * + * Note that some HKSCS characters are not contained in Unicode 3.2 + * and are therefore best represented as sequences of Unicode characters: + * 0x8862 U+00CA U+0304 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND MACRON + * 0x8864 U+00CA U+030C LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND CARON + * 0x88A3 U+00EA U+0304 LATIN SMALL LETTER E WITH CIRCUMFLEX AND MACRON + * 0x88A5 U+00EA U+030C LATIN SMALL LETTER E WITH CIRCUMFLEX AND CARON + */ + +#include "hkscs2001.h" +#include "flushwc.h" + +static int +big5hkscs2001_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + ucs4_t last_wc = conv->istate; + if (last_wc) { + /* Output the buffered character. */ + conv->istate = 0; + *pwc = last_wc; + return 0; /* Don't advance the input pointer. */ + } else { + unsigned char c = *s; + /* Code set 0 (ASCII) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* Code set 1 (BIG5 extended) */ + if (c >= 0xa1 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) { + if (!((c == 0xc6 && c2 >= 0xa1) || c == 0xc7)) { + int ret = big5_mbtowc(conv,pwc,s,2); + if (ret != RET_ILSEQ) + return ret; + } + } + } + } + { + int ret = hkscs1999_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + } + { + int ret = hkscs2001_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + } + if (c == 0x88) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if (c2 == 0x62 || c2 == 0x64 || c2 == 0xa3 || c2 == 0xa5) { + /* It's a composed character. */ + ucs4_t wc1 = ((c2 >> 3) << 2) + 0x009a; /* = 0x00ca or 0x00ea */ + ucs4_t wc2 = ((c2 & 6) << 2) + 0x02fc; /* = 0x0304 or 0x030c */ + /* We cannot output two Unicode characters at once. So, + output the first character and buffer the second one. */ + *pwc = wc1; + conv->istate = wc2; + return 2; + } + } + } + return RET_ILSEQ; + } +} + +#define big5hkscs2001_flushwc normal_flushwc + +static int +big5hkscs2001_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + int count = 0; + unsigned char last = conv->ostate; + + if (last) { + /* last is = 0x66 or = 0xa7. */ + if (wc == 0x0304 || wc == 0x030c) { + /* Output the combined character. */ + if (n >= 2) { + r[0] = 0x88; + r[1] = last + ((wc & 24) >> 2) - 4; /* = 0x62 or 0x64 or 0xa3 or 0xa5 */ + conv->ostate = 0; + return 2; + } else + return RET_TOOSMALL; + } + + /* Output the buffered character. */ + if (n < 2) + return RET_TOOSMALL; + r[0] = 0x88; + r[1] = last; + r += 2; + count = 2; + } + + /* Code set 0 (ASCII) */ + if (wc < 0x0080) { + /* Plain ASCII character. */ + if (n > count) { + r[0] = (unsigned char) wc; + conv->ostate = 0; + return count+1; + } else + return RET_TOOSMALL; + } else { + unsigned char buf[2]; + int ret; + + /* Code set 1 (BIG5 extended) */ + ret = big5_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (!((buf[0] == 0xc6 && buf[1] >= 0xa1) || buf[0] == 0xc7)) { + if (n >= count+2) { + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + } + ret = hkscs1999_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if ((wc & ~0x0020) == 0x00ca) { + /* A possible first character of a multi-character sequence. We have to + buffer it. */ + if (!(buf[0] == 0x88 && (buf[1] == 0x66 || buf[1] == 0xa7))) abort(); + conv->ostate = buf[1]; /* = 0x66 or = 0xa7 */ + return count+0; + } + if (n >= count+2) { + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + ret = hkscs2001_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n >= count+2) { + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + return RET_ILUNI; + } +} + +static int +big5hkscs2001_reset (conv_t conv, unsigned char *r, int n) +{ + unsigned char last = conv->ostate; + + if (last) { + if (n < 2) + return RET_TOOSMALL; + r[0] = 0x88; + r[1] = last; + /* conv->ostate = 0; will be done by the caller */ + return 2; + } else + return 0; +} diff --git a/libs/libiconv/lib/big5hkscs2004.h b/libs/libiconv/lib/big5hkscs2004.h new file mode 100644 index 00000000..3c57f66b --- /dev/null +++ b/libs/libiconv/lib/big5hkscs2004.h @@ -0,0 +1,231 @@ +/* + * Copyright (C) 1999-2002, 2006 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * BIG5-HKSCS:2004 + */ + +/* + * BIG5-HKSCS:2004 can be downloaded from + * http://www.info.gov.hk/digital21/eng/hkscs/download.html + * http://www.info.gov.hk/digital21/eng/hkscs/index.html + * + * It extends BIG5-HKSCS:2001 through 123 characters. + * + * It extends BIG5 (without the rows 0xC6..0xC7) through the ranges + * + * 0x{87..8D}{40..7E,A1..FE} 880 characters + * 0x{8E..A0}{40..7E,A1..FE} 2898 characters + * 0x{C6..C8}{40..7E,A1..FE} 359 characters + * 0xF9{D6..FE} 41 characters + * 0x{FA..FE}{40..7E,A1..FE} 763 characters + * + * Note that some HKSCS characters are not contained in Unicode 3.2 + * and are therefore best represented as sequences of Unicode characters: + * 0x8862 U+00CA U+0304 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND MACRON + * 0x8864 U+00CA U+030C LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND CARON + * 0x88A3 U+00EA U+0304 LATIN SMALL LETTER E WITH CIRCUMFLEX AND MACRON + * 0x88A5 U+00EA U+030C LATIN SMALL LETTER E WITH CIRCUMFLEX AND CARON + */ + +#include "hkscs2004.h" +#include "flushwc.h" + +static int +big5hkscs2004_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + ucs4_t last_wc = conv->istate; + if (last_wc) { + /* Output the buffered character. */ + conv->istate = 0; + *pwc = last_wc; + return 0; /* Don't advance the input pointer. */ + } else { + unsigned char c = *s; + /* Code set 0 (ASCII) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* Code set 1 (BIG5 extended) */ + if (c >= 0xa1 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) { + if (!((c == 0xc6 && c2 >= 0xa1) || c == 0xc7)) { + int ret = big5_mbtowc(conv,pwc,s,2); + if (ret != RET_ILSEQ) + return ret; + } + } + } + } + { + int ret = hkscs1999_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + } + { + int ret = hkscs2001_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + } + { + int ret = hkscs2004_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + } + if (c == 0x88) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if (c2 == 0x62 || c2 == 0x64 || c2 == 0xa3 || c2 == 0xa5) { + /* It's a composed character. */ + ucs4_t wc1 = ((c2 >> 3) << 2) + 0x009a; /* = 0x00ca or 0x00ea */ + ucs4_t wc2 = ((c2 & 6) << 2) + 0x02fc; /* = 0x0304 or 0x030c */ + /* We cannot output two Unicode characters at once. So, + output the first character and buffer the second one. */ + *pwc = wc1; + conv->istate = wc2; + return 2; + } + } + } + return RET_ILSEQ; + } +} + +#define big5hkscs2004_flushwc normal_flushwc + +static int +big5hkscs2004_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + int count = 0; + unsigned char last = conv->ostate; + + if (last) { + /* last is = 0x66 or = 0xa7. */ + if (wc == 0x0304 || wc == 0x030c) { + /* Output the combined character. */ + if (n >= 2) { + r[0] = 0x88; + r[1] = last + ((wc & 24) >> 2) - 4; /* = 0x62 or 0x64 or 0xa3 or 0xa5 */ + conv->ostate = 0; + return 2; + } else + return RET_TOOSMALL; + } + + /* Output the buffered character. */ + if (n < 2) + return RET_TOOSMALL; + r[0] = 0x88; + r[1] = last; + r += 2; + count = 2; + } + + /* Code set 0 (ASCII) */ + if (wc < 0x0080) { + /* Plain ASCII character. */ + if (n > count) { + r[0] = (unsigned char) wc; + conv->ostate = 0; + return count+1; + } else + return RET_TOOSMALL; + } else { + unsigned char buf[2]; + int ret; + + /* Code set 1 (BIG5 extended) */ + ret = big5_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (!((buf[0] == 0xc6 && buf[1] >= 0xa1) || buf[0] == 0xc7)) { + if (n >= count+2) { + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + } + ret = hkscs1999_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if ((wc & ~0x0020) == 0x00ca) { + /* A possible first character of a multi-character sequence. We have to + buffer it. */ + if (!(buf[0] == 0x88 && (buf[1] == 0x66 || buf[1] == 0xa7))) abort(); + conv->ostate = buf[1]; /* = 0x66 or = 0xa7 */ + return count+0; + } + if (n >= count+2) { + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + ret = hkscs2001_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n >= count+2) { + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + ret = hkscs2004_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n >= count+2) { + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + return RET_ILUNI; + } +} + +static int +big5hkscs2004_reset (conv_t conv, unsigned char *r, int n) +{ + unsigned char last = conv->ostate; + + if (last) { + if (n < 2) + return RET_TOOSMALL; + r[0] = 0x88; + r[1] = last; + /* conv->ostate = 0; will be done by the caller */ + return 2; + } else + return 0; +} diff --git a/libs/libiconv/lib/big5hkscs2008.h b/libs/libiconv/lib/big5hkscs2008.h new file mode 100644 index 00000000..8759f4d0 --- /dev/null +++ b/libs/libiconv/lib/big5hkscs2008.h @@ -0,0 +1,247 @@ +/* + * Copyright (C) 1999-2002, 2006, 2010 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * BIG5-HKSCS:2008 + */ + +/* + * BIG5-HKSCS:2008 can be downloaded from + * http://www.ogcio.gov.hk/ccli/eng/hkscs/download.html + * http://www.ogcio.gov.hk/ccli/eng/hkscs/introduction.html + * + * It extends BIG5-HKSCS:2004 through 68 characters. + * + * It extends BIG5 (without the rows 0xC6..0xC7) through the ranges + * + * 0x{87..8D}{40..7E,A1..FE} 880 characters + * 0x{8E..A0}{40..7E,A1..FE} 2898 characters + * 0x{C6..C8}{40..7E,A1..FE} 359 characters + * 0xF9{D6..FE} 41 characters + * 0x{FA..FE}{40..7E,A1..FE} 763 characters + * + * Note that some HKSCS characters are not contained in Unicode 3.2 + * and are therefore best represented as sequences of Unicode characters: + * 0x8862 U+00CA U+0304 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND MACRON + * 0x8864 U+00CA U+030C LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND CARON + * 0x88A3 U+00EA U+0304 LATIN SMALL LETTER E WITH CIRCUMFLEX AND MACRON + * 0x88A5 U+00EA U+030C LATIN SMALL LETTER E WITH CIRCUMFLEX AND CARON + */ + +#include "hkscs2008.h" +#include "flushwc.h" + +static int +big5hkscs2008_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + ucs4_t last_wc = conv->istate; + if (last_wc) { + /* Output the buffered character. */ + conv->istate = 0; + *pwc = last_wc; + return 0; /* Don't advance the input pointer. */ + } else { + unsigned char c = *s; + /* Code set 0 (ASCII) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* Code set 1 (BIG5 extended) */ + if (c >= 0xa1 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) { + if (!((c == 0xc6 && c2 >= 0xa1) || c == 0xc7)) { + int ret = big5_mbtowc(conv,pwc,s,2); + if (ret != RET_ILSEQ) + return ret; + } + } + } + } + { + int ret = hkscs1999_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + } + { + int ret = hkscs2001_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + } + { + int ret = hkscs2004_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + } + { + int ret = hkscs2008_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + } + if (c == 0x88) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if (c2 == 0x62 || c2 == 0x64 || c2 == 0xa3 || c2 == 0xa5) { + /* It's a composed character. */ + ucs4_t wc1 = ((c2 >> 3) << 2) + 0x009a; /* = 0x00ca or 0x00ea */ + ucs4_t wc2 = ((c2 & 6) << 2) + 0x02fc; /* = 0x0304 or 0x030c */ + /* We cannot output two Unicode characters at once. So, + output the first character and buffer the second one. */ + *pwc = wc1; + conv->istate = wc2; + return 2; + } + } + } + return RET_ILSEQ; + } +} + +#define big5hkscs2008_flushwc normal_flushwc + +static int +big5hkscs2008_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + int count = 0; + unsigned char last = conv->ostate; + + if (last) { + /* last is = 0x66 or = 0xa7. */ + if (wc == 0x0304 || wc == 0x030c) { + /* Output the combined character. */ + if (n >= 2) { + r[0] = 0x88; + r[1] = last + ((wc & 24) >> 2) - 4; /* = 0x62 or 0x64 or 0xa3 or 0xa5 */ + conv->ostate = 0; + return 2; + } else + return RET_TOOSMALL; + } + + /* Output the buffered character. */ + if (n < 2) + return RET_TOOSMALL; + r[0] = 0x88; + r[1] = last; + r += 2; + count = 2; + } + + /* Code set 0 (ASCII) */ + if (wc < 0x0080) { + /* Plain ASCII character. */ + if (n > count) { + r[0] = (unsigned char) wc; + conv->ostate = 0; + return count+1; + } else + return RET_TOOSMALL; + } else { + unsigned char buf[2]; + int ret; + + /* Code set 1 (BIG5 extended) */ + ret = big5_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (!((buf[0] == 0xc6 && buf[1] >= 0xa1) || buf[0] == 0xc7)) { + if (n >= count+2) { + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + } + ret = hkscs1999_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if ((wc & ~0x0020) == 0x00ca) { + /* A possible first character of a multi-character sequence. We have to + buffer it. */ + if (!(buf[0] == 0x88 && (buf[1] == 0x66 || buf[1] == 0xa7))) abort(); + conv->ostate = buf[1]; /* = 0x66 or = 0xa7 */ + return count+0; + } + if (n >= count+2) { + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + ret = hkscs2001_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n >= count+2) { + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + ret = hkscs2004_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n >= count+2) { + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + ret = hkscs2008_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n >= count+2) { + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + return RET_ILUNI; + } +} + +static int +big5hkscs2008_reset (conv_t conv, unsigned char *r, int n) +{ + unsigned char last = conv->ostate; + + if (last) { + if (n < 2) + return RET_TOOSMALL; + r[0] = 0x88; + r[1] = last; + /* conv->ostate = 0; will be done by the caller */ + return 2; + } else + return 0; +} diff --git a/libs/libiconv/lib/c99.h b/libs/libiconv/lib/c99.h new file mode 100644 index 00000000..52a73c35 --- /dev/null +++ b/libs/libiconv/lib/c99.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * C99 + * This is ASCII with \uXXXX and \UXXXXXXXX escape sequences, denoting Unicode + * characters. See ISO/IEC 9899:1999, section 6.4.3. + * The treatment of control characters in the range U+0080..U+009F is not + * specified; we pass them through unmodified. + */ + +static int +c99_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c; + ucs4_t wc; + int i; + + c = s[0]; + if (c < 0xa0) { + if (c != '\\') { + *pwc = c; + return 1; + } + if (n < 2) + return RET_TOOFEW(0); + c = s[1]; + if (c == 'u') { + wc = 0; + for (i = 2; i < 6; i++) { + if (n <= i) + return RET_TOOFEW(0); + c = s[i]; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A'-10; + else if (c >= 'a' && c <= 'z') + c -= 'a'-10; + else + goto simply_backslash; + wc |= (ucs4_t) c << (4 * (5-i)); + } + if ((wc >= 0x00a0 && !(wc >= 0xd800 && wc < 0xe000)) + || wc == 0x0024 || wc == 0x0040 || wc == 0x0060) { + *pwc = wc; + return 6; + } + } else if (c == 'U') { + wc = 0; + for (i = 2; i < 10; i++) { + if (n <= i) + return RET_TOOFEW(0); + c = s[i]; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A'-10; + else if (c >= 'a' && c <= 'z') + c -= 'a'-10; + else + goto simply_backslash; + wc |= (ucs4_t) c << (4 * (9-i)); + } + if ((wc >= 0x00a0 && !(wc >= 0xd800 && wc < 0xe000)) + || wc == 0x0024 || wc == 0x0040 || wc == 0x0060) { + *pwc = wc; + return 10; + } + } else + goto simply_backslash; + } + return RET_ILSEQ; +simply_backslash: + *pwc = '\\'; + return 1; +} + +static int +c99_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0xa0) { + *r = wc; + return 1; + } else { + int result; + unsigned char u; + if (wc < 0x10000) { + result = 6; + u = 'u'; + } else { + result = 10; + u = 'U'; + } + if (n >= result) { + int count; + r[0] = '\\'; + r[1] = u; + r += 2; + for (count = result-3; count >= 0; count--) { + unsigned int i = (wc >> (4*count)) & 0x0f; + *r++ = (i < 10 ? '0'+i : 'a'-10+i); + } + return result; + } else + return RET_TOOSMALL; + } +} diff --git a/libs/libiconv/lib/canonical.h b/libs/libiconv/lib/canonical.h new file mode 100644 index 00000000..550cc64f --- /dev/null +++ b/libs/libiconv/lib/canonical.h @@ -0,0 +1,110 @@ + (int)(long)&((struct stringpool_t *)0)->stringpool_str287, + (int)(long)&((struct stringpool_t *)0)->stringpool_str255, + (int)(long)&((struct stringpool_t *)0)->stringpool_str179, + (int)(long)&((struct stringpool_t *)0)->stringpool_str367, + (int)(long)&((struct stringpool_t *)0)->stringpool_str283, + (int)(long)&((struct stringpool_t *)0)->stringpool_str263, + (int)(long)&((struct stringpool_t *)0)->stringpool_str409, + (int)(long)&((struct stringpool_t *)0)->stringpool_str325, + (int)(long)&((struct stringpool_t *)0)->stringpool_str242, + (int)(long)&((struct stringpool_t *)0)->stringpool_str434, + (int)(long)&((struct stringpool_t *)0)->stringpool_str350, + (int)(long)&((struct stringpool_t *)0)->stringpool_str252, + (int)(long)&((struct stringpool_t *)0)->stringpool_str440, + (int)(long)&((struct stringpool_t *)0)->stringpool_str356, + (int)(long)&((struct stringpool_t *)0)->stringpool_str575, + (int)(long)&((struct stringpool_t *)0)->stringpool_str406, + (int)(long)&((struct stringpool_t *)0)->stringpool_str723, + (int)(long)&((struct stringpool_t *)0)->stringpool_str448, + (int)(long)&((struct stringpool_t *)0)->stringpool_str765, + (int)(long)&((struct stringpool_t *)0)->stringpool_str30, + (int)(long)&((struct stringpool_t *)0)->stringpool_str600, + (int)(long)&((struct stringpool_t *)0)->stringpool_str74, + (int)(long)&((struct stringpool_t *)0)->stringpool_str84, + (int)(long)&((struct stringpool_t *)0)->stringpool_str78, + (int)(long)&((struct stringpool_t *)0)->stringpool_str168, + (int)(long)&((struct stringpool_t *)0)->stringpool_str82, + (int)(long)&((struct stringpool_t *)0)->stringpool_str76, + (int)(long)&((struct stringpool_t *)0)->stringpool_str410, + (int)(long)&((struct stringpool_t *)0)->stringpool_str90, + (int)(long)&((struct stringpool_t *)0)->stringpool_str98, + (int)(long)&((struct stringpool_t *)0)->stringpool_str221, + (int)(long)&((struct stringpool_t *)0)->stringpool_str75, + (int)(long)&((struct stringpool_t *)0)->stringpool_str79, + (int)(long)&((struct stringpool_t *)0)->stringpool_str169, + (int)(long)&((struct stringpool_t *)0)->stringpool_str83, + (int)(long)&((struct stringpool_t *)0)->stringpool_str77, + (int)(long)&((struct stringpool_t *)0)->stringpool_str261, + (int)(long)&((struct stringpool_t *)0)->stringpool_str403, + (int)(long)&((struct stringpool_t *)0)->stringpool_str480, + (int)(long)&((struct stringpool_t *)0)->stringpool_str164, + (int)(long)&((struct stringpool_t *)0)->stringpool_str18, + (int)(long)&((struct stringpool_t *)0)->stringpool_str28, + (int)(long)&((struct stringpool_t *)0)->stringpool_str22, + (int)(long)&((struct stringpool_t *)0)->stringpool_str112, + (int)(long)&((struct stringpool_t *)0)->stringpool_str26, + (int)(long)&((struct stringpool_t *)0)->stringpool_str20, + (int)(long)&((struct stringpool_t *)0)->stringpool_str354, + (int)(long)&((struct stringpool_t *)0)->stringpool_str34, + (int)(long)&((struct stringpool_t *)0)->stringpool_str166, + (int)(long)&((struct stringpool_t *)0)->stringpool_str27, + (int)(long)&((struct stringpool_t *)0)->stringpool_str19, + (int)(long)&((struct stringpool_t *)0)->stringpool_str11, + (int)(long)&((struct stringpool_t *)0)->stringpool_str451, + (int)(long)&((struct stringpool_t *)0)->stringpool_str531, + (int)(long)&((struct stringpool_t *)0)->stringpool_str355, + (int)(long)&((struct stringpool_t *)0)->stringpool_str501, + (int)(long)&((struct stringpool_t *)0)->stringpool_str673, + (int)(long)&((struct stringpool_t *)0)->stringpool_str302, + (int)(long)&((struct stringpool_t *)0)->stringpool_str621, + (int)(long)&((struct stringpool_t *)0)->stringpool_str577, + (int)(long)&((struct stringpool_t *)0)->stringpool_str786, + (int)(long)&((struct stringpool_t *)0)->stringpool_str908, + (int)(long)&((struct stringpool_t *)0)->stringpool_str563, + (int)(long)&((struct stringpool_t *)0)->stringpool_str445, + (int)(long)&((struct stringpool_t *)0)->stringpool_str502, + (int)(long)&((struct stringpool_t *)0)->stringpool_str475, + (int)(long)&((struct stringpool_t *)0)->stringpool_str279, + (int)(long)&((struct stringpool_t *)0)->stringpool_str626, + (int)(long)&((struct stringpool_t *)0)->stringpool_str614, + (int)(long)&((struct stringpool_t *)0)->stringpool_str217, + (int)(long)&((struct stringpool_t *)0)->stringpool_str212, + (int)(long)&((struct stringpool_t *)0)->stringpool_str218, + (int)(long)&((struct stringpool_t *)0)->stringpool_str371, + (int)(long)&((struct stringpool_t *)0)->stringpool_str15, + (int)(long)&((struct stringpool_t *)0)->stringpool_str230, + (int)(long)&((struct stringpool_t *)0)->stringpool_str278, + (int)(long)&((struct stringpool_t *)0)->stringpool_str124, + (int)(long)&((struct stringpool_t *)0)->stringpool_str180, + (int)(long)&((struct stringpool_t *)0)->stringpool_str413, + (int)(long)&((struct stringpool_t *)0)->stringpool_str555, + (int)(long)&((struct stringpool_t *)0)->stringpool_str571, + (int)(long)&((struct stringpool_t *)0)->stringpool_str492, + (int)(long)&((struct stringpool_t *)0)->stringpool_str384, + (int)(long)&((struct stringpool_t *)0)->stringpool_str368, + (int)(long)&((struct stringpool_t *)0)->stringpool_str127, + (int)(long)&((struct stringpool_t *)0)->stringpool_str202, + (int)(long)&((struct stringpool_t *)0)->stringpool_str535, + (int)(long)&((struct stringpool_t *)0)->stringpool_str429, + (int)(long)&((struct stringpool_t *)0)->stringpool_str32, + (int)(long)&((struct stringpool_t *)0)->stringpool_str607, + (int)(long)&((struct stringpool_t *)0)->stringpool_str500, + (int)(long)&((struct stringpool_t *)0)->stringpool_str505, + (int)(long)&((struct stringpool_t *)0)->stringpool_str70, + (int)(long)&((struct stringpool_t *)0)->stringpool_str303, + (int)(long)&((struct stringpool_t *)0)->stringpool_str24, + (int)(long)&((struct stringpool_t *)0)->stringpool_str378, + (int)(long)&((struct stringpool_t *)0)->stringpool_str142, + (int)(long)&((struct stringpool_t *)0)->stringpool_str196, + (int)(long)&((struct stringpool_t *)0)->stringpool_str159, + (int)(long)&((struct stringpool_t *)0)->stringpool_str473, + (int)(long)&((struct stringpool_t *)0)->stringpool_str277, + (int)(long)&((struct stringpool_t *)0)->stringpool_str170, + (int)(long)&((struct stringpool_t *)0)->stringpool_str900, + (int)(long)&((struct stringpool_t *)0)->stringpool_str888, + (int)(long)&((struct stringpool_t *)0)->stringpool_str935, + (int)(long)&((struct stringpool_t *)0)->stringpool_str527, + (int)(long)&((struct stringpool_t *)0)->stringpool_str290, + (int)(long)&((struct stringpool_t *)0)->stringpool_str91, + (int)(long)&((struct stringpool_t *)0)->stringpool_str768, + (int)(long)&((struct stringpool_t *)0)->stringpool_str362, diff --git a/libs/libiconv/lib/canonical_aix.h b/libs/libiconv/lib/canonical_aix.h new file mode 100644 index 00000000..6149bc1b --- /dev/null +++ b/libs/libiconv/lib/canonical_aix.h @@ -0,0 +1,9 @@ + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_0, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_1, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_2, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_3, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_4, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_5, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_6, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_10, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_14, diff --git a/libs/libiconv/lib/canonical_aix_sysaix.h b/libs/libiconv/lib/canonical_aix_sysaix.h new file mode 100644 index 00000000..8b58d1fa --- /dev/null +++ b/libs/libiconv/lib/canonical_aix_sysaix.h @@ -0,0 +1,9 @@ + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_0, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_2, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_4, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_6, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_8, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_10, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_12, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_16, + (int)(long)&((struct stringpool2_t *)0)->stringpool_aix_20, diff --git a/libs/libiconv/lib/canonical_dos.h b/libs/libiconv/lib/canonical_dos.h new file mode 100644 index 00000000..aa82651c --- /dev/null +++ b/libs/libiconv/lib/canonical_dos.h @@ -0,0 +1,15 @@ + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_0, + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_4, + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_5, + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_8, + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_12, + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_13, + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_17, + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_21, + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_22, + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_26, + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_31, + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_35, + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_38, + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_42, + (int)(long)&((struct stringpool2_t *)0)->stringpool_dos_47, diff --git a/libs/libiconv/lib/canonical_extra.h b/libs/libiconv/lib/canonical_extra.h new file mode 100644 index 00000000..29678a08 --- /dev/null +++ b/libs/libiconv/lib/canonical_extra.h @@ -0,0 +1,7 @@ + (int)(long)&((struct stringpool2_t *)0)->stringpool_extra_0, + (int)(long)&((struct stringpool2_t *)0)->stringpool_extra_2, + (int)(long)&((struct stringpool2_t *)0)->stringpool_extra_4, + (int)(long)&((struct stringpool2_t *)0)->stringpool_extra_6, + (int)(long)&((struct stringpool2_t *)0)->stringpool_extra_7, + (int)(long)&((struct stringpool2_t *)0)->stringpool_extra_9, + (int)(long)&((struct stringpool2_t *)0)->stringpool_extra_11, diff --git a/libs/libiconv/lib/canonical_local.h b/libs/libiconv/lib/canonical_local.h new file mode 100644 index 00000000..a2209a82 --- /dev/null +++ b/libs/libiconv/lib/canonical_local.h @@ -0,0 +1,2 @@ + (int)(long)&((struct stringpool_t *)0)->stringpool_str271, + (int)(long)&((struct stringpool_t *)0)->stringpool_str664, diff --git a/libs/libiconv/lib/canonical_local_sysaix.h b/libs/libiconv/lib/canonical_local_sysaix.h new file mode 100644 index 00000000..0d4b27ba --- /dev/null +++ b/libs/libiconv/lib/canonical_local_sysaix.h @@ -0,0 +1,2 @@ + (int)(long)&((struct stringpool_t *)0)->stringpool_str307, + (int)(long)&((struct stringpool_t *)0)->stringpool_str543, diff --git a/libs/libiconv/lib/canonical_local_syshpux.h b/libs/libiconv/lib/canonical_local_syshpux.h new file mode 100644 index 00000000..8e969231 --- /dev/null +++ b/libs/libiconv/lib/canonical_local_syshpux.h @@ -0,0 +1,2 @@ + (int)(long)&((struct stringpool_t *)0)->stringpool_str258, + (int)(long)&((struct stringpool_t *)0)->stringpool_str390, diff --git a/libs/libiconv/lib/canonical_local_sysosf1.h b/libs/libiconv/lib/canonical_local_sysosf1.h new file mode 100644 index 00000000..e1f886c0 --- /dev/null +++ b/libs/libiconv/lib/canonical_local_sysosf1.h @@ -0,0 +1,2 @@ + (int)(long)&((struct stringpool_t *)0)->stringpool_str275, + (int)(long)&((struct stringpool_t *)0)->stringpool_str465, diff --git a/libs/libiconv/lib/canonical_local_syssolaris.h b/libs/libiconv/lib/canonical_local_syssolaris.h new file mode 100644 index 00000000..ce73d706 --- /dev/null +++ b/libs/libiconv/lib/canonical_local_syssolaris.h @@ -0,0 +1,2 @@ + (int)(long)&((struct stringpool_t *)0)->stringpool_str38, + (int)(long)&((struct stringpool_t *)0)->stringpool_str515, diff --git a/libs/libiconv/lib/canonical_osf1.h b/libs/libiconv/lib/canonical_osf1.h new file mode 100644 index 00000000..0e134ac3 --- /dev/null +++ b/libs/libiconv/lib/canonical_osf1.h @@ -0,0 +1,2 @@ + (int)(long)&((struct stringpool2_t *)0)->stringpool_osf1_0, + (int)(long)&((struct stringpool2_t *)0)->stringpool_osf1_1, diff --git a/libs/libiconv/lib/canonical_osf1_sysosf1.h b/libs/libiconv/lib/canonical_osf1_sysosf1.h new file mode 100644 index 00000000..15c27690 --- /dev/null +++ b/libs/libiconv/lib/canonical_osf1_sysosf1.h @@ -0,0 +1,2 @@ + (int)(long)&((struct stringpool2_t *)0)->stringpool_osf1_0, + (int)(long)&((struct stringpool2_t *)0)->stringpool_osf1_2, diff --git a/libs/libiconv/lib/canonical_sysaix.h b/libs/libiconv/lib/canonical_sysaix.h new file mode 100644 index 00000000..00a71f6b --- /dev/null +++ b/libs/libiconv/lib/canonical_sysaix.h @@ -0,0 +1,110 @@ + (int)(long)&((struct stringpool_t *)0)->stringpool_str383, + (int)(long)&((struct stringpool_t *)0)->stringpool_str363, + (int)(long)&((struct stringpool_t *)0)->stringpool_str231, + (int)(long)&((struct stringpool_t *)0)->stringpool_str604, + (int)(long)&((struct stringpool_t *)0)->stringpool_str483, + (int)(long)&((struct stringpool_t *)0)->stringpool_str327, + (int)(long)&((struct stringpool_t *)0)->stringpool_str652, + (int)(long)&((struct stringpool_t *)0)->stringpool_str531, + (int)(long)&((struct stringpool_t *)0)->stringpool_str358, + (int)(long)&((struct stringpool_t *)0)->stringpool_str733, + (int)(long)&((struct stringpool_t *)0)->stringpool_str612, + (int)(long)&((struct stringpool_t *)0)->stringpool_str364, + (int)(long)&((struct stringpool_t *)0)->stringpool_str737, + (int)(long)&((struct stringpool_t *)0)->stringpool_str616, + (int)(long)&((struct stringpool_t *)0)->stringpool_str685, + (int)(long)&((struct stringpool_t *)0)->stringpool_str501, + (int)(long)&((struct stringpool_t *)0)->stringpool_str654, + (int)(long)&((struct stringpool_t *)0)->stringpool_str549, + (int)(long)&((struct stringpool_t *)0)->stringpool_str702, + (int)(long)&((struct stringpool_t *)0)->stringpool_str53, + (int)(long)&((struct stringpool_t *)0)->stringpool_str891, + (int)(long)&((struct stringpool_t *)0)->stringpool_str103, + (int)(long)&((struct stringpool_t *)0)->stringpool_str109, + (int)(long)&((struct stringpool_t *)0)->stringpool_str107, + (int)(long)&((struct stringpool_t *)0)->stringpool_str205, + (int)(long)&((struct stringpool_t *)0)->stringpool_str111, + (int)(long)&((struct stringpool_t *)0)->stringpool_str105, + (int)(long)&((struct stringpool_t *)0)->stringpool_str437, + (int)(long)&((struct stringpool_t *)0)->stringpool_str115, + (int)(long)&((struct stringpool_t *)0)->stringpool_str141, + (int)(long)&((struct stringpool_t *)0)->stringpool_str246, + (int)(long)&((struct stringpool_t *)0)->stringpool_str108, + (int)(long)&((struct stringpool_t *)0)->stringpool_str112, + (int)(long)&((struct stringpool_t *)0)->stringpool_str210, + (int)(long)&((struct stringpool_t *)0)->stringpool_str116, + (int)(long)&((struct stringpool_t *)0)->stringpool_str110, + (int)(long)&((struct stringpool_t *)0)->stringpool_str254, + (int)(long)&((struct stringpool_t *)0)->stringpool_str492, + (int)(long)&((struct stringpool_t *)0)->stringpool_str569, + (int)(long)&((struct stringpool_t *)0)->stringpool_str175, + (int)(long)&((struct stringpool_t *)0)->stringpool_str37, + (int)(long)&((struct stringpool_t *)0)->stringpool_str43, + (int)(long)&((struct stringpool_t *)0)->stringpool_str41, + (int)(long)&((struct stringpool_t *)0)->stringpool_str139, + (int)(long)&((struct stringpool_t *)0)->stringpool_str45, + (int)(long)&((struct stringpool_t *)0)->stringpool_str39, + (int)(long)&((struct stringpool_t *)0)->stringpool_str371, + (int)(long)&((struct stringpool_t *)0)->stringpool_str49, + (int)(long)&((struct stringpool_t *)0)->stringpool_str173, + (int)(long)&((struct stringpool_t *)0)->stringpool_str38, + (int)(long)&((struct stringpool_t *)0)->stringpool_str34, + (int)(long)&((struct stringpool_t *)0)->stringpool_str32, + (int)(long)&((struct stringpool_t *)0)->stringpool_str525, + (int)(long)&((struct stringpool_t *)0)->stringpool_str797, + (int)(long)&((struct stringpool_t *)0)->stringpool_str462, + (int)(long)&((struct stringpool_t *)0)->stringpool_str583, + (int)(long)&((struct stringpool_t *)0)->stringpool_str807, + (int)(long)&((struct stringpool_t *)0)->stringpool_str272, + (int)(long)&((struct stringpool_t *)0)->stringpool_str898, + (int)(long)&((struct stringpool_t *)0)->stringpool_str606, + (int)(long)&((struct stringpool_t *)0)->stringpool_str662, + (int)(long)&((struct stringpool_t *)0)->stringpool_str989, + (int)(long)&((struct stringpool_t *)0)->stringpool_str648, + (int)(long)&((struct stringpool_t *)0)->stringpool_str391, + (int)(long)&((struct stringpool_t *)0)->stringpool_str487, + (int)(long)&((struct stringpool_t *)0)->stringpool_str413, + (int)(long)&((struct stringpool_t *)0)->stringpool_str330, + (int)(long)&((struct stringpool_t *)0)->stringpool_str461, + (int)(long)&((struct stringpool_t *)0)->stringpool_str335, + (int)(long)&((struct stringpool_t *)0)->stringpool_str152, + (int)(long)&((struct stringpool_t *)0)->stringpool_str171, + (int)(long)&((struct stringpool_t *)0)->stringpool_str234, + (int)(long)&((struct stringpool_t *)0)->stringpool_str445, + (int)(long)&((struct stringpool_t *)0)->stringpool_str36, + (int)(long)&((struct stringpool_t *)0)->stringpool_str207, + (int)(long)&((struct stringpool_t *)0)->stringpool_str300, + (int)(long)&((struct stringpool_t *)0)->stringpool_str217, + (int)(long)&((struct stringpool_t *)0)->stringpool_str256, + (int)(long)&((struct stringpool_t *)0)->stringpool_str567, + (int)(long)&((struct stringpool_t *)0)->stringpool_str723, + (int)(long)&((struct stringpool_t *)0)->stringpool_str735, + (int)(long)&((struct stringpool_t *)0)->stringpool_str660, + (int)(long)&((struct stringpool_t *)0)->stringpool_str258, + (int)(long)&((struct stringpool_t *)0)->stringpool_str235, + (int)(long)&((struct stringpool_t *)0)->stringpool_str149, + (int)(long)&((struct stringpool_t *)0)->stringpool_str202, + (int)(long)&((struct stringpool_t *)0)->stringpool_str638, + (int)(long)&((struct stringpool_t *)0)->stringpool_str613, + (int)(long)&((struct stringpool_t *)0)->stringpool_str52, + (int)(long)&((struct stringpool_t *)0)->stringpool_str629, + (int)(long)&((struct stringpool_t *)0)->stringpool_str591, + (int)(long)&((struct stringpool_t *)0)->stringpool_str594, + (int)(long)&((struct stringpool_t *)0)->stringpool_str188, + (int)(long)&((struct stringpool_t *)0)->stringpool_str146, + (int)(long)&((struct stringpool_t *)0)->stringpool_str48, + (int)(long)&((struct stringpool_t *)0)->stringpool_str251, + (int)(long)&((struct stringpool_t *)0)->stringpool_str179, + (int)(long)&((struct stringpool_t *)0)->stringpool_str190, + (int)(long)&((struct stringpool_t *)0)->stringpool_str92, + (int)(long)&((struct stringpool_t *)0)->stringpool_str495, + (int)(long)&((struct stringpool_t *)0)->stringpool_str153, + (int)(long)&((struct stringpool_t *)0)->stringpool_str186, + (int)(long)&((struct stringpool_t *)0)->stringpool_str603, + (int)(long)&((struct stringpool_t *)0)->stringpool_str584, + (int)(long)&((struct stringpool_t *)0)->stringpool_str635, + (int)(long)&((struct stringpool_t *)0)->stringpool_str324, + (int)(long)&((struct stringpool_t *)0)->stringpool_str369, + (int)(long)&((struct stringpool_t *)0)->stringpool_str133, + (int)(long)&((struct stringpool_t *)0)->stringpool_str885, + (int)(long)&((struct stringpool_t *)0)->stringpool_str360, diff --git a/libs/libiconv/lib/canonical_syshpux.h b/libs/libiconv/lib/canonical_syshpux.h new file mode 100644 index 00000000..390355b7 --- /dev/null +++ b/libs/libiconv/lib/canonical_syshpux.h @@ -0,0 +1,110 @@ + (int)(long)&((struct stringpool_t *)0)->stringpool_str310, + (int)(long)&((struct stringpool_t *)0)->stringpool_str368, + (int)(long)&((struct stringpool_t *)0)->stringpool_str293, + (int)(long)&((struct stringpool_t *)0)->stringpool_str464, + (int)(long)&((struct stringpool_t *)0)->stringpool_str525, + (int)(long)&((struct stringpool_t *)0)->stringpool_str395, + (int)(long)&((struct stringpool_t *)0)->stringpool_str515, + (int)(long)&((struct stringpool_t *)0)->stringpool_str576, + (int)(long)&((struct stringpool_t *)0)->stringpool_str355, + (int)(long)&((struct stringpool_t *)0)->stringpool_str521, + (int)(long)&((struct stringpool_t *)0)->stringpool_str582, + (int)(long)&((struct stringpool_t *)0)->stringpool_str363, + (int)(long)&((struct stringpool_t *)0)->stringpool_str534, + (int)(long)&((struct stringpool_t *)0)->stringpool_str595, + (int)(long)&((struct stringpool_t *)0)->stringpool_str440, + (int)(long)&((struct stringpool_t *)0)->stringpool_str665, + (int)(long)&((struct stringpool_t *)0)->stringpool_str644, + (int)(long)&((struct stringpool_t *)0)->stringpool_str716, + (int)(long)&((struct stringpool_t *)0)->stringpool_str695, + (int)(long)&((struct stringpool_t *)0)->stringpool_str36, + (int)(long)&((struct stringpool_t *)0)->stringpool_str596, + (int)(long)&((struct stringpool_t *)0)->stringpool_str64, + (int)(long)&((struct stringpool_t *)0)->stringpool_str60, + (int)(long)&((struct stringpool_t *)0)->stringpool_str100, + (int)(long)&((struct stringpool_t *)0)->stringpool_str162, + (int)(long)&((struct stringpool_t *)0)->stringpool_str76, + (int)(long)&((struct stringpool_t *)0)->stringpool_str70, + (int)(long)&((struct stringpool_t *)0)->stringpool_str158, + (int)(long)&((struct stringpool_t *)0)->stringpool_str86, + (int)(long)&((struct stringpool_t *)0)->stringpool_str92, + (int)(long)&((struct stringpool_t *)0)->stringpool_str177, + (int)(long)&((struct stringpool_t *)0)->stringpool_str67, + (int)(long)&((struct stringpool_t *)0)->stringpool_str103, + (int)(long)&((struct stringpool_t *)0)->stringpool_str165, + (int)(long)&((struct stringpool_t *)0)->stringpool_str79, + (int)(long)&((struct stringpool_t *)0)->stringpool_str73, + (int)(long)&((struct stringpool_t *)0)->stringpool_str345, + (int)(long)&((struct stringpool_t *)0)->stringpool_str669, + (int)(long)&((struct stringpool_t *)0)->stringpool_str790, + (int)(long)&((struct stringpool_t *)0)->stringpool_str131, + (int)(long)&((struct stringpool_t *)0)->stringpool_str21, + (int)(long)&((struct stringpool_t *)0)->stringpool_str17, + (int)(long)&((struct stringpool_t *)0)->stringpool_str57, + (int)(long)&((struct stringpool_t *)0)->stringpool_str119, + (int)(long)&((struct stringpool_t *)0)->stringpool_str33, + (int)(long)&((struct stringpool_t *)0)->stringpool_str27, + (int)(long)&((struct stringpool_t *)0)->stringpool_str115, + (int)(long)&((struct stringpool_t *)0)->stringpool_str43, + (int)(long)&((struct stringpool_t *)0)->stringpool_str141, + (int)(long)&((struct stringpool_t *)0)->stringpool_str24, + (int)(long)&((struct stringpool_t *)0)->stringpool_str34, + (int)(long)&((struct stringpool_t *)0)->stringpool_str35, + (int)(long)&((struct stringpool_t *)0)->stringpool_str448, + (int)(long)&((struct stringpool_t *)0)->stringpool_str561, + (int)(long)&((struct stringpool_t *)0)->stringpool_str410, + (int)(long)&((struct stringpool_t *)0)->stringpool_str335, + (int)(long)&((struct stringpool_t *)0)->stringpool_str470, + (int)(long)&((struct stringpool_t *)0)->stringpool_str704, + (int)(long)&((struct stringpool_t *)0)->stringpool_str685, + (int)(long)&((struct stringpool_t *)0)->stringpool_str607, + (int)(long)&((struct stringpool_t *)0)->stringpool_str689, + (int)(long)&((struct stringpool_t *)0)->stringpool_str800, + (int)(long)&((struct stringpool_t *)0)->stringpool_str454, + (int)(long)&((struct stringpool_t *)0)->stringpool_str195, + (int)(long)&((struct stringpool_t *)0)->stringpool_str331, + (int)(long)&((struct stringpool_t *)0)->stringpool_str484, + (int)(long)&((struct stringpool_t *)0)->stringpool_str202, + (int)(long)&((struct stringpool_t *)0)->stringpool_str449, + (int)(long)&((struct stringpool_t *)0)->stringpool_str513, + (int)(long)&((struct stringpool_t *)0)->stringpool_str139, + (int)(long)&((struct stringpool_t *)0)->stringpool_str190, + (int)(long)&((struct stringpool_t *)0)->stringpool_str262, + (int)(long)&((struct stringpool_t *)0)->stringpool_str603, + (int)(long)&((struct stringpool_t *)0)->stringpool_str71, + (int)(long)&((struct stringpool_t *)0)->stringpool_str149, + (int)(long)&((struct stringpool_t *)0)->stringpool_str170, + (int)(long)&((struct stringpool_t *)0)->stringpool_str251, + (int)(long)&((struct stringpool_t *)0)->stringpool_str271, + (int)(long)&((struct stringpool_t *)0)->stringpool_str450, + (int)(long)&((struct stringpool_t *)0)->stringpool_str769, + (int)(long)&((struct stringpool_t *)0)->stringpool_str791, + (int)(long)&((struct stringpool_t *)0)->stringpool_str710, + (int)(long)&((struct stringpool_t *)0)->stringpool_str354, + (int)(long)&((struct stringpool_t *)0)->stringpool_str332, + (int)(long)&((struct stringpool_t *)0)->stringpool_str153, + (int)(long)&((struct stringpool_t *)0)->stringpool_str203, + (int)(long)&((struct stringpool_t *)0)->stringpool_str491, + (int)(long)&((struct stringpool_t *)0)->stringpool_str461, + (int)(long)&((struct stringpool_t *)0)->stringpool_str42, + (int)(long)&((struct stringpool_t *)0)->stringpool_str542, + (int)(long)&((struct stringpool_t *)0)->stringpool_str473, + (int)(long)&((struct stringpool_t *)0)->stringpool_str471, + (int)(long)&((struct stringpool_t *)0)->stringpool_str30, + (int)(long)&((struct stringpool_t *)0)->stringpool_str314, + (int)(long)&((struct stringpool_t *)0)->stringpool_str52, + (int)(long)&((struct stringpool_t *)0)->stringpool_str352, + (int)(long)&((struct stringpool_t *)0)->stringpool_str81, + (int)(long)&((struct stringpool_t *)0)->stringpool_str96, + (int)(long)&((struct stringpool_t *)0)->stringpool_str12, + (int)(long)&((struct stringpool_t *)0)->stringpool_str378, + (int)(long)&((struct stringpool_t *)0)->stringpool_str308, + (int)(long)&((struct stringpool_t *)0)->stringpool_str144, + (int)(long)&((struct stringpool_t *)0)->stringpool_str771, + (int)(long)&((struct stringpool_t *)0)->stringpool_str757, + (int)(long)&((struct stringpool_t *)0)->stringpool_str806, + (int)(long)&((struct stringpool_t *)0)->stringpool_str421, + (int)(long)&((struct stringpool_t *)0)->stringpool_str343, + (int)(long)&((struct stringpool_t *)0)->stringpool_str105, + (int)(long)&((struct stringpool_t *)0)->stringpool_str654, + (int)(long)&((struct stringpool_t *)0)->stringpool_str394, diff --git a/libs/libiconv/lib/canonical_sysosf1.h b/libs/libiconv/lib/canonical_sysosf1.h new file mode 100644 index 00000000..659a516a --- /dev/null +++ b/libs/libiconv/lib/canonical_sysosf1.h @@ -0,0 +1,110 @@ + (int)(long)&((struct stringpool_t *)0)->stringpool_str343, + (int)(long)&((struct stringpool_t *)0)->stringpool_str294, + (int)(long)&((struct stringpool_t *)0)->stringpool_str223, + (int)(long)&((struct stringpool_t *)0)->stringpool_str591, + (int)(long)&((struct stringpool_t *)0)->stringpool_str433, + (int)(long)&((struct stringpool_t *)0)->stringpool_str319, + (int)(long)&((struct stringpool_t *)0)->stringpool_str639, + (int)(long)&((struct stringpool_t *)0)->stringpool_str481, + (int)(long)&((struct stringpool_t *)0)->stringpool_str289, + (int)(long)&((struct stringpool_t *)0)->stringpool_str659, + (int)(long)&((struct stringpool_t *)0)->stringpool_str501, + (int)(long)&((struct stringpool_t *)0)->stringpool_str295, + (int)(long)&((struct stringpool_t *)0)->stringpool_str663, + (int)(long)&((struct stringpool_t *)0)->stringpool_str505, + (int)(long)&((struct stringpool_t *)0)->stringpool_str586, + (int)(long)&((struct stringpool_t *)0)->stringpool_str472, + (int)(long)&((struct stringpool_t *)0)->stringpool_str695, + (int)(long)&((struct stringpool_t *)0)->stringpool_str520, + (int)(long)&((struct stringpool_t *)0)->stringpool_str743, + (int)(long)&((struct stringpool_t *)0)->stringpool_str53, + (int)(long)&((struct stringpool_t *)0)->stringpool_str711, + (int)(long)&((struct stringpool_t *)0)->stringpool_str103, + (int)(long)&((struct stringpool_t *)0)->stringpool_str109, + (int)(long)&((struct stringpool_t *)0)->stringpool_str107, + (int)(long)&((struct stringpool_t *)0)->stringpool_str205, + (int)(long)&((struct stringpool_t *)0)->stringpool_str111, + (int)(long)&((struct stringpool_t *)0)->stringpool_str105, + (int)(long)&((struct stringpool_t *)0)->stringpool_str407, + (int)(long)&((struct stringpool_t *)0)->stringpool_str115, + (int)(long)&((struct stringpool_t *)0)->stringpool_str141, + (int)(long)&((struct stringpool_t *)0)->stringpool_str246, + (int)(long)&((struct stringpool_t *)0)->stringpool_str108, + (int)(long)&((struct stringpool_t *)0)->stringpool_str112, + (int)(long)&((struct stringpool_t *)0)->stringpool_str210, + (int)(long)&((struct stringpool_t *)0)->stringpool_str116, + (int)(long)&((struct stringpool_t *)0)->stringpool_str110, + (int)(long)&((struct stringpool_t *)0)->stringpool_str280, + (int)(long)&((struct stringpool_t *)0)->stringpool_str410, + (int)(long)&((struct stringpool_t *)0)->stringpool_str487, + (int)(long)&((struct stringpool_t *)0)->stringpool_str175, + (int)(long)&((struct stringpool_t *)0)->stringpool_str37, + (int)(long)&((struct stringpool_t *)0)->stringpool_str43, + (int)(long)&((struct stringpool_t *)0)->stringpool_str41, + (int)(long)&((struct stringpool_t *)0)->stringpool_str139, + (int)(long)&((struct stringpool_t *)0)->stringpool_str45, + (int)(long)&((struct stringpool_t *)0)->stringpool_str39, + (int)(long)&((struct stringpool_t *)0)->stringpool_str341, + (int)(long)&((struct stringpool_t *)0)->stringpool_str49, + (int)(long)&((struct stringpool_t *)0)->stringpool_str173, + (int)(long)&((struct stringpool_t *)0)->stringpool_str38, + (int)(long)&((struct stringpool_t *)0)->stringpool_str34, + (int)(long)&((struct stringpool_t *)0)->stringpool_str32, + (int)(long)&((struct stringpool_t *)0)->stringpool_str543, + (int)(long)&((struct stringpool_t *)0)->stringpool_str727, + (int)(long)&((struct stringpool_t *)0)->stringpool_str428, + (int)(long)&((struct stringpool_t *)0)->stringpool_str544, + (int)(long)&((struct stringpool_t *)0)->stringpool_str761, + (int)(long)&((struct stringpool_t *)0)->stringpool_str281, + (int)(long)&((struct stringpool_t *)0)->stringpool_str821, + (int)(long)&((struct stringpool_t *)0)->stringpool_str649, + (int)(long)&((struct stringpool_t *)0)->stringpool_str661, + (int)(long)&((struct stringpool_t *)0)->stringpool_str939, + (int)(long)&((struct stringpool_t *)0)->stringpool_str646, + (int)(long)&((struct stringpool_t *)0)->stringpool_str362, + (int)(long)&((struct stringpool_t *)0)->stringpool_str458, + (int)(long)&((struct stringpool_t *)0)->stringpool_str500, + (int)(long)&((struct stringpool_t *)0)->stringpool_str369, + (int)(long)&((struct stringpool_t *)0)->stringpool_str397, + (int)(long)&((struct stringpool_t *)0)->stringpool_str442, + (int)(long)&((struct stringpool_t *)0)->stringpool_str178, + (int)(long)&((struct stringpool_t *)0)->stringpool_str202, + (int)(long)&((struct stringpool_t *)0)->stringpool_str234, + (int)(long)&((struct stringpool_t *)0)->stringpool_str417, + (int)(long)&((struct stringpool_t *)0)->stringpool_str36, + (int)(long)&((struct stringpool_t *)0)->stringpool_str253, + (int)(long)&((struct stringpool_t *)0)->stringpool_str285, + (int)(long)&((struct stringpool_t *)0)->stringpool_str245, + (int)(long)&((struct stringpool_t *)0)->stringpool_str238, + (int)(long)&((struct stringpool_t *)0)->stringpool_str515, + (int)(long)&((struct stringpool_t *)0)->stringpool_str671, + (int)(long)&((struct stringpool_t *)0)->stringpool_str683, + (int)(long)&((struct stringpool_t *)0)->stringpool_str608, + (int)(long)&((struct stringpool_t *)0)->stringpool_str266, + (int)(long)&((struct stringpool_t *)0)->stringpool_str243, + (int)(long)&((struct stringpool_t *)0)->stringpool_str149, + (int)(long)&((struct stringpool_t *)0)->stringpool_str228, + (int)(long)&((struct stringpool_t *)0)->stringpool_str581, + (int)(long)&((struct stringpool_t *)0)->stringpool_str638, + (int)(long)&((struct stringpool_t *)0)->stringpool_str52, + (int)(long)&((struct stringpool_t *)0)->stringpool_str593, + (int)(long)&((struct stringpool_t *)0)->stringpool_str524, + (int)(long)&((struct stringpool_t *)0)->stringpool_str527, + (int)(long)&((struct stringpool_t *)0)->stringpool_str167, + (int)(long)&((struct stringpool_t *)0)->stringpool_str206, + (int)(long)&((struct stringpool_t *)0)->stringpool_str48, + (int)(long)&((struct stringpool_t *)0)->stringpool_str259, + (int)(long)&((struct stringpool_t *)0)->stringpool_str179, + (int)(long)&((struct stringpool_t *)0)->stringpool_str190, + (int)(long)&((struct stringpool_t *)0)->stringpool_str60, + (int)(long)&((struct stringpool_t *)0)->stringpool_str426, + (int)(long)&((struct stringpool_t *)0)->stringpool_str198, + (int)(long)&((struct stringpool_t *)0)->stringpool_str186, + (int)(long)&((struct stringpool_t *)0)->stringpool_str784, + (int)(long)&((struct stringpool_t *)0)->stringpool_str765, + (int)(long)&((struct stringpool_t *)0)->stringpool_str816, + (int)(long)&((struct stringpool_t *)0)->stringpool_str511, + (int)(long)&((struct stringpool_t *)0)->stringpool_str374, + (int)(long)&((struct stringpool_t *)0)->stringpool_str133, + (int)(long)&((struct stringpool_t *)0)->stringpool_str807, + (int)(long)&((struct stringpool_t *)0)->stringpool_str386, diff --git a/libs/libiconv/lib/canonical_syssolaris.h b/libs/libiconv/lib/canonical_syssolaris.h new file mode 100644 index 00000000..72ad33a5 --- /dev/null +++ b/libs/libiconv/lib/canonical_syssolaris.h @@ -0,0 +1,110 @@ + (int)(long)&((struct stringpool_t *)0)->stringpool_str463, + (int)(long)&((struct stringpool_t *)0)->stringpool_str258, + (int)(long)&((struct stringpool_t *)0)->stringpool_str314, + (int)(long)&((struct stringpool_t *)0)->stringpool_str482, + (int)(long)&((struct stringpool_t *)0)->stringpool_str365, + (int)(long)&((struct stringpool_t *)0)->stringpool_str278, + (int)(long)&((struct stringpool_t *)0)->stringpool_str464, + (int)(long)&((struct stringpool_t *)0)->stringpool_str347, + (int)(long)&((struct stringpool_t *)0)->stringpool_str279, + (int)(long)&((struct stringpool_t *)0)->stringpool_str470, + (int)(long)&((struct stringpool_t *)0)->stringpool_str353, + (int)(long)&((struct stringpool_t *)0)->stringpool_str378, + (int)(long)&((struct stringpool_t *)0)->stringpool_str546, + (int)(long)&((struct stringpool_t *)0)->stringpool_str429, + (int)(long)&((struct stringpool_t *)0)->stringpool_str588, + (int)(long)&((struct stringpool_t *)0)->stringpool_str510, + (int)(long)&((struct stringpool_t *)0)->stringpool_str563, + (int)(long)&((struct stringpool_t *)0)->stringpool_str492, + (int)(long)&((struct stringpool_t *)0)->stringpool_str545, + (int)(long)&((struct stringpool_t *)0)->stringpool_str30, + (int)(long)&((struct stringpool_t *)0)->stringpool_str569, + (int)(long)&((struct stringpool_t *)0)->stringpool_str124, + (int)(long)&((struct stringpool_t *)0)->stringpool_str184, + (int)(long)&((struct stringpool_t *)0)->stringpool_str230, + (int)(long)&((struct stringpool_t *)0)->stringpool_str148, + (int)(long)&((struct stringpool_t *)0)->stringpool_str160, + (int)(long)&((struct stringpool_t *)0)->stringpool_str138, + (int)(long)&((struct stringpool_t *)0)->stringpool_str452, + (int)(long)&((struct stringpool_t *)0)->stringpool_str122, + (int)(long)&((struct stringpool_t *)0)->stringpool_str136, + (int)(long)&((struct stringpool_t *)0)->stringpool_str175, + (int)(long)&((struct stringpool_t *)0)->stringpool_str129, + (int)(long)&((struct stringpool_t *)0)->stringpool_str235, + (int)(long)&((struct stringpool_t *)0)->stringpool_str153, + (int)(long)&((struct stringpool_t *)0)->stringpool_str165, + (int)(long)&((struct stringpool_t *)0)->stringpool_str143, + (int)(long)&((struct stringpool_t *)0)->stringpool_str276, + (int)(long)&((struct stringpool_t *)0)->stringpool_str680, + (int)(long)&((struct stringpool_t *)0)->stringpool_str684, + (int)(long)&((struct stringpool_t *)0)->stringpool_str127, + (int)(long)&((struct stringpool_t *)0)->stringpool_str81, + (int)(long)&((struct stringpool_t *)0)->stringpool_str141, + (int)(long)&((struct stringpool_t *)0)->stringpool_str187, + (int)(long)&((struct stringpool_t *)0)->stringpool_str105, + (int)(long)&((struct stringpool_t *)0)->stringpool_str117, + (int)(long)&((struct stringpool_t *)0)->stringpool_str95, + (int)(long)&((struct stringpool_t *)0)->stringpool_str409, + (int)(long)&((struct stringpool_t *)0)->stringpool_str79, + (int)(long)&((struct stringpool_t *)0)->stringpool_str91, + (int)(long)&((struct stringpool_t *)0)->stringpool_str94, + (int)(long)&((struct stringpool_t *)0)->stringpool_str48, + (int)(long)&((struct stringpool_t *)0)->stringpool_str86, + (int)(long)&((struct stringpool_t *)0)->stringpool_str387, + (int)(long)&((struct stringpool_t *)0)->stringpool_str451, + (int)(long)&((struct stringpool_t *)0)->stringpool_str346, + (int)(long)&((struct stringpool_t *)0)->stringpool_str415, + (int)(long)&((struct stringpool_t *)0)->stringpool_str489, + (int)(long)&((struct stringpool_t *)0)->stringpool_str389, + (int)(long)&((struct stringpool_t *)0)->stringpool_str752, + (int)(long)&((struct stringpool_t *)0)->stringpool_str774, + (int)(long)&((struct stringpool_t *)0)->stringpool_str953, + (int)(long)&((struct stringpool_t *)0)->stringpool_str853, + (int)(long)&((struct stringpool_t *)0)->stringpool_str432, + (int)(long)&((struct stringpool_t *)0)->stringpool_str513, + (int)(long)&((struct stringpool_t *)0)->stringpool_str297, + (int)(long)&((struct stringpool_t *)0)->stringpool_str502, + (int)(long)&((struct stringpool_t *)0)->stringpool_str372, + (int)(long)&((struct stringpool_t *)0)->stringpool_str412, + (int)(long)&((struct stringpool_t *)0)->stringpool_str419, + (int)(long)&((struct stringpool_t *)0)->stringpool_str478, + (int)(long)&((struct stringpool_t *)0)->stringpool_str71, + (int)(long)&((struct stringpool_t *)0)->stringpool_str62, + (int)(long)&((struct stringpool_t *)0)->stringpool_str266, + (int)(long)&((struct stringpool_t *)0)->stringpool_str192, + (int)(long)&((struct stringpool_t *)0)->stringpool_str246, + (int)(long)&((struct stringpool_t *)0)->stringpool_str215, + (int)(long)&((struct stringpool_t *)0)->stringpool_str424, + (int)(long)&((struct stringpool_t *)0)->stringpool_str307, + (int)(long)&((struct stringpool_t *)0)->stringpool_str507, + (int)(long)&((struct stringpool_t *)0)->stringpool_str669, + (int)(long)&((struct stringpool_t *)0)->stringpool_str667, + (int)(long)&((struct stringpool_t *)0)->stringpool_str706, + (int)(long)&((struct stringpool_t *)0)->stringpool_str211, + (int)(long)&((struct stringpool_t *)0)->stringpool_str320, + (int)(long)&((struct stringpool_t *)0)->stringpool_str202, + (int)(long)&((struct stringpool_t *)0)->stringpool_str283, + (int)(long)&((struct stringpool_t *)0)->stringpool_str400, + (int)(long)&((struct stringpool_t *)0)->stringpool_str714, + (int)(long)&((struct stringpool_t *)0)->stringpool_str147, + (int)(long)&((struct stringpool_t *)0)->stringpool_str556, + (int)(long)&((struct stringpool_t *)0)->stringpool_str554, + (int)(long)&((struct stringpool_t *)0)->stringpool_str584, + (int)(long)&((struct stringpool_t *)0)->stringpool_str67, + (int)(long)&((struct stringpool_t *)0)->stringpool_str516, + (int)(long)&((struct stringpool_t *)0)->stringpool_str101, + (int)(long)&((struct stringpool_t *)0)->stringpool_str271, + (int)(long)&((struct stringpool_t *)0)->stringpool_str223, + (int)(long)&((struct stringpool_t *)0)->stringpool_str327, + (int)(long)&((struct stringpool_t *)0)->stringpool_str99, + (int)(long)&((struct stringpool_t *)0)->stringpool_str540, + (int)(long)&((struct stringpool_t *)0)->stringpool_str293, + (int)(long)&((struct stringpool_t *)0)->stringpool_str98, + (int)(long)&((struct stringpool_t *)0)->stringpool_str901, + (int)(long)&((struct stringpool_t *)0)->stringpool_str895, + (int)(long)&((struct stringpool_t *)0)->stringpool_str907, + (int)(long)&((struct stringpool_t *)0)->stringpool_str666, + (int)(long)&((struct stringpool_t *)0)->stringpool_str255, + (int)(long)&((struct stringpool_t *)0)->stringpool_str58, + (int)(long)&((struct stringpool_t *)0)->stringpool_str691, + (int)(long)&((struct stringpool_t *)0)->stringpool_str411, diff --git a/libs/libiconv/lib/ces_big5.h b/libs/libiconv/lib/ces_big5.h new file mode 100644 index 00000000..2f87735b --- /dev/null +++ b/libs/libiconv/lib/ces_big5.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * BIG-5 + */ + +static int +ces_big5_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + /* Code set 0 (ASCII) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* Code set 1 (BIG5) */ + if (c >= 0xa1 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) + return big5_mbtowc(conv,pwc,s,2); + else + return RET_ILSEQ; + } + } + return RET_ILSEQ; +} + +static int +ces_big5_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[2]; + int ret; + + /* Code set 0 (ASCII) */ + ret = ascii_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + /* Code set 1 (BIG5) */ + ret = big5_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]; + r[1] = buf[1]; + return 2; + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/ces_gbk.h b/libs/libiconv/lib/ces_gbk.h new file mode 100644 index 00000000..69e61f7d --- /dev/null +++ b/libs/libiconv/lib/ces_gbk.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 1999-2001, 2005 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * GBK + */ + +static int +ces_gbk_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + + /* Code set 0 (ASCII or GB 1988-89) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* Code set 1 (GBK) */ + if (c >= 0x81 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + return gbk_mbtowc(conv,pwc,s,2); + } + return RET_ILSEQ; +} + +static int +ces_gbk_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[2]; + int ret; + + /* Code set 0 (ASCII or GB 1988-89) */ + ret = ascii_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + /* Code set 1 (GBK) */ + ret = gbk_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]; + r[1] = buf[1]; + return 2; + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cjk_variants.h b/libs/libiconv/lib/cjk_variants.h new file mode 100644 index 00000000..23cb4b32 --- /dev/null +++ b/libs/libiconv/lib/cjk_variants.h @@ -0,0 +1,4241 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CJK variants table + */ + +static const unsigned short cjk_variants[12038] = { + 0x9e44, 0x1e2a, 0x200b, 0xcb87, 0xaf0c, 0x9e0a, 0x9e0b, 0xd42c, + 0x23c1, 0xaf0e, 0x9e04, 0x9e05, 0xa176, 0xd207, 0x2303, 0xa304, + 0x1e12, 0x619c, 0xeb57, 0x9e11, 0x2c02, 0xac08, 0x1e17, 0xa34b, + 0x1e16, 0xa34b, 0x1e20, 0xa775, 0xb96d, 0x23e2, 0x3a37, 0x3b09, + 0xd5c2, 0xb771, 0x4cf8, 0xcd72, 0x1e22, 0xa3be, 0x1e18, 0xa775, + 0x1e24, 0xa169, 0x1e1f, 0xa3be, 0xe149, 0x1e21, 0xa169, 0x23b3, + 0xa6b4, 0x20a1, 0x2e76, 0xcadd, 0xa5aa, 0x00f6, 0x200b, 0xcb87, + 0x3792, 0x3860, 0xb90f, 0xc23f, 0x5c4a, 0x5c50, 0x673b, 0x674a, + 0x68a8, 0xe8ce, 0x9e33, 0x9e32, 0xd1e8, 0x40ba, 0xc232, 0x2a6f, + 0xee97, 0x3319, 0x34e7, 0xd209, 0xa3ca, 0x2208, 0xd2c5, 0x2efc, + 0xdffa, 0x0006, 0x9e94, 0x1e46, 0xe579, 0x1e45, 0xe579, 0x2c1b, + 0x2e7a, 0x2e85, 0x6ebc, 0xeebd, 0xcfa9, 0xc0cf, 0x397d, 0xba02, + 0x1f17, 0x3500, 0x473e, 0xd846, 0xa5ac, 0x564e, 0xd65d, 0x1e58, + 0xb909, 0x1e57, 0xb909, 0x6690, 0x66a0, 0xe6b1, 0xcfd2, 0x60f7, + 0x6109, 0x610a, 0xe115, 0xb6f8, 0x2158, 0xa9cb, 0xdcb7, 0x1e82, + 0xe1e0, 0x1e7e, 0x1e81, 0xbf27, 0x1e79, 0x1e81, 0x2e72, 0xbf27, + 0x6f9c, 0xef9f, 0x1e79, 0x1e7e, 0xbf27, 0x1e71, 0xe1e0, 0x36b8, + 0xc7ad, 0xdc6b, 0xc22d, 0x1e8b, 0xa3d3, 0x1e8a, 0xa3d3, 0xaf0d, + 0x1e8f, 0x1e90, 0xb5bc, 0x1e8e, 0x1e90, 0x35bc, 0xd667, 0x1e8e, + 0x9e8f, 0x1f1d, 0xe6f2, 0x9e44, 0xa6db, 0x2c81, 0x2d57, 0x3b72, + 0xbb73, 0x9e99, 0x9e98, 0x1e9c, 0x9e9e, 0x1e9a, 0x9e9e, 0x3589, + 0x358a, 0x6f4a, 0xef50, 0x1e9a, 0x9e9c, 0xc10f, 0x1ebe, 0xa166, + 0x4522, 0xc523, 0x4546, 0x4552, 0x455d, 0xc55e, 0x9eaf, 0x9eb0, + 0x9eab, 0x9eac, 0xa91c, 0xd9aa, 0xd93b, 0xa6b2, 0x9ebb, 0x9eba, + 0x1ea1, 0xa166, 0xa104, 0xafce, 0x20cd, 0x22a8, 0xa2d5, 0x1ed8, + 0xa0c5, 0xa0d5, 0xdb8e, 0xa0df, 0x21ab, 0x21b0, 0xbc37, 0x2f93, + 0xaf9e, 0x9f5b, 0x1f1e, 0xa098, 0x1f96, 0x2d18, 0xad19, 0x1efa, + 0xa009, 0x9ec5, 0x20ca, 0xa0f2, 0xa40c, 0x9eed, 0xaf74, 0x214f, + 0x6577, 0x6578, 0xe57f, 0xa100, 0xa011, 0x9ede, 0x2047, 0xa3cd, + 0x1fa1, 0xa0f9, 0x1ed3, 0xa009, 0x9fc7, 0x2f6c, 0xb58c, 0x9f4e, + 0x2023, 0x2f77, 0x2fac, 0x4706, 0xeae3, 0x20a0, 0xc26b, 0xae11, + 0x1e51, 0x473e, 0xd846, 0xa12a, 0xa925, 0xb703, 0xa0b4, 0xa005, + 0x1e91, 0x1f20, 0xa0b3, 0x1ed0, 0x2098, 0xce56, 0xa049, 0x1f1d, + 0xa0b3, 0x9fe5, 0x9fd4, 0xa0b7, 0xa000, 0xa02b, 0xa096, 0x207d, + 0xa0de, 0x1f47, 0xcada, 0xa2aa, 0x1f32, 0x1f60, 0xa11e, 0x1f31, + 0x1f60, 0xa11e, 0x9f90, 0xd0c4, 0x9f40, 0x9f3c, 0xb014, 0x9f2b, + 0xae03, 0x9efe, 0x4b28, 0x5eb0, 0x5ec6, 0x6ab5, 0xead4, 0xa360, + 0x6918, 0xe980, 0x1ecf, 0x2f7f, 0xeaf4, 0xa05a, 0x9fab, 0x1f31, + 0x1f32, 0x211e, 0xa9b3, 0xa0ad, 0xa0c9, 0xaf8a, 0x3cd5, 0xc04b, + 0x2002, 0xae76, 0xaf88, 0xa058, 0x29b7, 0xa9ea, 0xb765, 0x6625, + 0x6634, 0x6670, 0xe682, 0xb549, 0x9f35, 0x9ed1, 0x5350, 0xd5a6, + 0x9fe0, 0x1ef7, 0xa0f9, 0x9fb6, 0xa0e5, 0x2075, 0xe049, 0xa074, + 0xa0d1, 0xa108, 0xa115, 0x9f5e, 0xa102, 0x2118, 0xac3d, 0xc7e6, + 0x9fa3, 0xac40, 0xc537, 0x9fe3, 0xccfb, 0x9efc, 0xa101, 0xdf14, + 0xc23c, 0x1f23, 0xb093, 0xa16a, 0xcae2, 0x9fa0, 0xda2b, 0x9fee, + 0x9fc1, 0x9f21, 0xa114, 0xa13c, 0xa006, 0xa137, 0xa008, 0x2039, + 0xa109, 0x1fe2, 0xd129, 0xa036, 0x209a, 0xb548, 0x2079, 0x2099, + 0x20c3, 0xa907, 0x4ca5, 0xeb3b, 0x30de, 0xbb23, 0x9f25, 0x1f75, + 0xae76, 0x207a, 0x24b1, 0xa592, 0x9f1c, 0x9fe9, 0x9feb, 0x1ed3, + 0x9efa, 0xa06c, 0x00f6, 0x1e2a, 0xcb87, 0xd146, 0xa010, 0xa00f, + 0x9eec, 0xae78, 0xa0b9, 0x2fa3, 0xd5c9, 0x1eff, 0xc706, 0xa03c, + 0x22b5, 0xa2cc, 0x9f26, 0xa25a, 0x9ff1, 0x1fed, 0xa109, 0xa0b5, + 0xa024, 0xa0be, 0xd2f1, 0xdcf0, 0x9eee, 0x9f1f, 0x5d0b, 0x5d17, + 0xdd5d, 0x9f83, 0xa0c0, 0x9f5c, 0xafa4, 0xe03c, 0x200a, 0xa0af, + 0x9fa7, 0x1fa6, 0xe049, 0xa078, 0xa077, 0x1ffb, 0x2099, 0x20c3, + 0xa907, 0x2003, 0x24b1, 0xa592, 0xa0c2, 0x1f2a, 0xa0de, 0xa0e8, + 0xa11f, 0x4f75, 0x69e1, 0xea82, 0xafac, 0xb770, 0x9f27, 0x1ed0, + 0x1f1e, 0xce56, 0x1ffb, 0x2079, 0x20c3, 0xa907, 0x1ff2, 0xb548, + 0xafad, 0x1f10, 0xc26b, 0x1e26, 0x2e76, 0xcadd, 0xabb6, 0xa10e, + 0xa13b, 0xa110, 0xa132, 0xa13a, 0x9f63, 0xa06c, 0x1f1d, 0x9f20, + 0x9f1b, 0xa03a, 0x9f24, 0xa01e, 0xa03e, 0xa059, 0xa07b, 0x1ffb, + 0x2079, 0x2099, 0xa907, 0xafb1, 0x9ec5, 0x9f65, 0x9ed9, 0x1ec2, + 0x22a8, 0xa2d5, 0x9fa8, 0x9ec6, 0xb55e, 0xc67b, 0x1f2a, 0xa07d, + 0x9ec9, 0xa0ed, 0x9fa5, 0xa07e, 0xa0f4, 0x3076, 0x30aa, 0xb0e1, + 0xa0e3, 0xe6c7, 0x9ed9, 0xa0e9, 0x1ef7, 0x9fa1, 0x9eea, 0x9fca, + 0x9fac, 0x9ebf, 0x9fa9, 0x1fed, 0xa039, 0xa0a4, 0xa0a7, 0x9fe6, + 0x9faa, 0x1fad, 0xac3d, 0x1f31, 0x1f32, 0x9f60, 0xa07f, 0xa139, + 0x9f18, 0xa0a8, 0x9fea, 0xa127, 0xa0a9, 0xa0a5, 0x9fe8, 0x2150, + 0xa152, 0xcc2a, 0xa1f6, 0x406e, 0xc097, 0x214c, 0xa151, 0x224b, + 0x22ca, 0xac05, 0x214a, 0xa151, 0xa154, 0x1ee7, 0x6577, 0x6578, + 0xe57f, 0x213f, 0xa152, 0x214a, 0xa14c, 0x213f, 0xa150, 0xa14e, + 0xa157, 0xa156, 0x1e68, 0xa9cb, 0xeee8, 0xa160, 0xa15c, 0xb5f7, + 0x1ea1, 0x9ebe, 0xa185, 0x1e21, 0x9e24, 0x9fde, 0xd62d, 0x2929, + 0x6754, 0xe75d, 0x24b2, 0x4b11, 0x65a2, 0x65d7, 0xe5dc, 0xd208, + 0x9e0c, 0x530a, 0xd332, 0x4faa, 0xe90a, 0x4363, 0xc378, 0xa180, + 0xa17e, 0xa6c5, 0xa18b, 0xae3d, 0xa189, 0xa167, 0x2706, 0x270e, + 0xa713, 0xaca1, 0xa184, 0x218c, 0xcb27, 0xa182, 0x218a, 0xcb27, + 0x226e, 0xa3e7, 0xa6e7, 0xa192, 0xd0c4, 0xa190, 0xab82, 0x21a9, + 0xabeb, 0xdecd, 0xdfb2, 0x2b90, 0xab9c, 0xa85a, 0xb700, 0xabc3, + 0x2bbc, 0xabc7, 0xabcc, 0x2199, 0xabeb, 0x2e42, 0xcf83, 0x1ecc, + 0x21b0, 0xbc37, 0x3638, 0xef15, 0xe9ae, 0x1ecc, 0x21ab, 0xbc37, + 0xa1b4, 0x3c96, 0xd85d, 0xbc7a, 0xa1b1, 0xbcc1, 0xbcef, 0xa1cd, + 0xbd0c, 0x21c8, 0xbde8, 0xbd7c, 0xbd82, 0x3053, 0x30bd, 0xbdd2, + 0xbdb8, 0x21d6, 0xbe96, 0xa1c0, 0xbdbc, 0xa1bb, 0xbe1b, 0xbe4a, + 0xc69a, 0xb817, 0x21c6, 0xbe96, 0x21dc, 0xbf9f, 0x21db, 0xbf9f, + 0x4108, 0x4155, 0x4188, 0xc199, 0x2e7e, 0xb73a, 0x21e2, 0xa1e3, + 0x21e1, 0xa1e3, 0x21e1, 0xa1e2, 0xecf3, 0xac45, 0x2904, 0xd655, + 0x21ec, 0x21ee, 0x68a8, 0x68cc, 0xe8ce, 0xece7, 0x21e8, 0x21ee, + 0x68a8, 0x68cc, 0xe8ce, 0x21f4, 0x317f, 0xb191, 0x21e8, 0x21ec, + 0x68a8, 0x68cc, 0xe8ce, 0xa1f1, 0xa1ef, 0x2c32, 0x2c34, 0x2c36, + 0x2c37, 0xeb50, 0xbac8, 0x21ed, 0x317f, 0xb191, 0xa147, 0x2757, + 0x284a, 0xa8a4, 0x2c80, 0xef63, 0x3483, 0xb4ca, 0xa1fe, 0xa1fd, + 0xe47f, 0x2202, 0xe1d6, 0x2200, 0xe1d6, 0xa204, 0xa203, 0x221b, + 0xa275, 0x1e42, 0xd2c5, 0xb81e, 0xd2bb, 0x2283, 0x2290, 0xc53b, + 0xa6ed, 0xb289, 0xa289, 0xa247, 0xa25b, 0x2205, 0x2231, 0x224f, + 0x2259, 0xa275, 0xa22a, 0xa22b, 0x2227, 0x223c, 0xa2ab, 0x2226, + 0x223c, 0xa2ab, 0x624b, 0x6464, 0xe4c7, 0xa220, 0x2225, 0xaf46, + 0x2257, 0x2277, 0x63df, 0xe4f2, 0xa244, 0xe8b3, 0x221b, 0x224f, + 0x2259, 0xa275, 0xa241, 0xd8fd, 0xa24e, 0xa23e, 0x2226, 0x2227, + 0xa2ab, 0xa28a, 0xa23a, 0xa28c, 0xa274, 0xa234, 0x2264, 0xa291, + 0xeb00, 0xa22d, 0xa219, 0x214b, 0x22ca, 0xac05, 0xbe82, 0xbb6c, + 0xa239, 0x221b, 0x2231, 0x2259, 0xa275, 0x226e, 0xa3e7, 0x2263, + 0x2271, 0x228d, 0x228e, 0x2292, 0x2294, 0x61f0, 0xe1fc, 0x222c, + 0x2277, 0x63df, 0xe4f2, 0x221b, 0x2231, 0x224f, 0xa275, 0xa033, + 0xa21a, 0xa265, 0x2251, 0x2271, 0x228d, 0x228e, 0x2292, 0x2294, + 0x61f0, 0xe1fc, 0x2242, 0xa291, 0xa25d, 0x65b9, 0xe609, 0xa287, + 0xa270, 0x218e, 0x2250, 0xa3e7, 0xa269, 0x2251, 0x2263, 0x228d, + 0x228e, 0x2292, 0x2294, 0x61f0, 0xe1fc, 0xb72d, 0xa240, 0x2205, + 0x221b, 0x2231, 0x224f, 0xa259, 0x222c, 0x2257, 0x63df, 0xe4f2, + 0xb22e, 0xa2e6, 0x2212, 0x2290, 0xc53b, 0xcb9a, 0xa267, 0xa218, + 0xa23d, 0xa23f, 0x2251, 0x2263, 0x2271, 0x228e, 0x2292, 0x2294, + 0x61f0, 0xe1fc, 0x2251, 0x2263, 0x2271, 0x228d, 0x2292, 0x2294, + 0x61f0, 0xe1fc, 0x2212, 0x2283, 0xc53b, 0x2242, 0xa264, 0x2251, + 0x2263, 0x2271, 0x228d, 0x228e, 0x2294, 0x61f0, 0xe1fc, 0x2251, + 0x2263, 0x2271, 0x228d, 0x228e, 0x2292, 0x61f0, 0xe1fc, 0x5cad, + 0xdcea, 0x22e7, 0xa2f8, 0xdfa6, 0x4cfc, 0xccff, 0xa2d9, 0xa2f1, + 0x1ec2, 0x20cd, 0xa2d5, 0x9f2e, 0x2226, 0x2227, 0xa23c, 0xa2f5, + 0xa2c1, 0x22b4, 0x22de, 0xb1a5, 0x22b3, 0x22de, 0xb1a5, 0x2026, + 0xa2cc, 0xb548, 0xa2e2, 0xa2b2, 0xb54f, 0x22d1, 0xb555, 0xa2c8, + 0xa2c7, 0x214b, 0x224b, 0xac05, 0x22db, 0x22f2, 0xa2f3, 0x2026, + 0xa2b5, 0x22c5, 0x2f95, 0x2fa0, 0xb555, 0x1ec2, 0x20cd, 0xa2a8, + 0x22d7, 0xb702, 0x22d6, 0xb702, 0xa2a1, 0xa2e9, 0x22cb, 0x22f2, + 0xa2f3, 0xd0dc, 0x22b3, 0x22b4, 0xb1a5, 0xb22e, 0xa2bf, 0xb1c3, + 0xa27f, 0x229d, 0xa2f8, 0xa2da, 0xa2a2, 0x22cb, 0x22db, 0xa2f3, + 0x22cb, 0x22db, 0xa2f2, 0xa2b1, 0x229d, 0xa2e7, 0xa300, 0xa2fb, + 0x1e10, 0xa304, 0x1e10, 0xa303, 0xeead, 0x2fe9, 0x3031, 0xb0a4, + 0xb3ac, 0x5133, 0xd166, 0xa338, 0x37e9, 0xb7fe, 0x2e00, 0xdfca, + 0xa320, 0xa31e, 0xa329, 0xa32d, 0xcbcb, 0x5535, 0xd5cf, 0xa321, + 0xa326, 0xa331, 0x3c47, 0xbed9, 0xa32e, 0x2333, 0x2941, 0xa969, + 0x2332, 0x2941, 0xa969, 0xa31a, 0xa340, 0x3bc9, 0xe1ab, 0xa33a, + 0xe7c6, 0xa352, 0x3607, 0x36fb, 0x6629, 0xe65e, 0xd294, 0x1e16, + 0x9e17, 0xa350, 0x2d0b, 0x53ef, 0xd550, 0x2354, 0x23f6, 0xb5ea, + 0xa34d, 0xa346, 0x384c, 0xb9d5, 0x234f, 0x23f6, 0xb5ea, 0x2358, + 0xa5ae, 0x28f2, 0xdce3, 0x2355, 0xa5ae, 0xb13d, 0xc387, 0x53d4, + 0xd514, 0x9f54, 0xc6e7, 0x2365, 0x2877, 0x3ef7, 0x3f9b, 0x4002, + 0x597f, 0xee75, 0x2364, 0xd97f, 0xd1e5, 0x585b, 0xd85e, 0xadf5, + 0x2918, 0xb23c, 0xae01, 0x237d, 0xc68d, 0xa37b, 0x2dfb, 0xb372, + 0xcf37, 0x3064, 0xdcc9, 0xa374, 0x2373, 0xc68d, 0x2388, 0x23b0, + 0xaee0, 0xb239, 0x2ef0, 0xaef3, 0x23a4, 0x23af, 0x36a6, 0x36c6, + 0x3b74, 0xbb77, 0xc8d4, 0xa382, 0xa3b2, 0x2727, 0xa8d3, 0xa3ad, + 0xa399, 0xc825, 0xef8e, 0xad16, 0x23a0, 0xaec1, 0x28e5, 0x2edb, + 0x613d, 0xe1d0, 0xa38d, 0xa795, 0xaef3, 0xa3a1, 0x2395, 0xaec1, + 0xa39f, 0xaec2, 0xa3b4, 0x2386, 0xb6c6, 0xaec8, 0xaeda, 0x2ecf, + 0xaed0, 0xa38c, 0xaedd, 0x2386, 0x36a6, 0x36c6, 0x3b74, 0xbb77, + 0x2382, 0xaee0, 0xa389, 0x1e25, 0xa6b4, 0xa3a3, 0xbe90, 0xc9c1, + 0xd0b1, 0x60bb, 0x6130, 0xe6a3, 0xa3bb, 0xa3ba, 0x1e1f, 0x9e22, + 0x470c, 0xce23, 0x1e09, 0xaf0e, 0x23c3, 0x23c4, 0xa3c5, 0x23c2, + 0x23c4, 0xa3c5, 0x23c2, 0x23c3, 0xa3c5, 0x23c2, 0x23c3, 0xa3c4, + 0xe749, 0xe746, 0xa3f9, 0xb268, 0x9e41, 0xe6d9, 0x1eee, 0x23db, + 0xc08d, 0xb536, 0xa92c, 0xc2ae, 0x467a, 0x467c, 0x6aea, 0xeaee, + 0x1e8a, 0x9e8b, 0xcdb4, 0x2909, 0xdb8a, 0x354d, 0xb558, 0x23cd, + 0xc08d, 0xac09, 0x4573, 0x4582, 0x4589, 0xc58a, 0x28e1, 0xc77f, + 0x1e1b, 0x3a37, 0x3b09, 0xd5c2, 0x218e, 0x2250, 0xa26e, 0x49d6, + 0x5879, 0xe6bb, 0xa44c, 0x276e, 0x37b1, 0x3aaf, 0x51fa, 0xe8b1, + 0x234f, 0x2354, 0x35ea, 0xd449, 0xd65f, 0x23c8, 0x2606, 0xbb4e, + 0xa630, 0x24a9, 0xa4f6, 0x4c72, 0xefa5, 0x25ab, 0xa644, 0xe5a4, + 0xaf14, 0x1edd, 0xd855, 0xaf8c, 0x26ae, 0xb6cf, 0xa687, 0xa442, + 0xa5ce, 0xb061, 0xa451, 0x252b, 0x2656, 0xda21, 0xa678, 0x5074, + 0xd07d, 0x2518, 0x2553, 0x2554, 0x255f, 0x5aec, 0xe5d9, 0x2434, + 0xa449, 0x2433, 0xa449, 0xa450, 0xd117, 0xa44d, 0xa44a, 0xa415, + 0x3282, 0xc2c2, 0x2433, 0xa434, 0xa43f, 0xa3eb, 0xa43d, 0xa436, + 0xa41e, 0xa638, 0xa6c8, 0xa614, 0xa6a6, 0xa504, 0x24e1, 0x5c9f, + 0xdd20, 0x24bc, 0xa58e, 0xa4fa, 0xa5c6, 0xa5da, 0xda46, 0xe031, + 0xa5dc, 0x2492, 0xda4b, 0xda4d, 0x2611, 0x5656, 0xdb3c, 0xa4e3, + 0x248c, 0x30d2, 0xefa2, 0x248a, 0x30d2, 0xefa2, 0xda60, 0x246a, + 0xda4b, 0xa6a8, 0xa680, 0xa4a4, 0xa65d, 0xa49c, 0x2400, 0xa4f6, + 0xef69, 0x2580, 0xd849, 0x2003, 0x207a, 0xa592, 0x2173, 0xcb11, + 0x618e, 0xee79, 0x2459, 0xa58e, 0xa6a5, 0x65a7, 0xeb28, 0xe7ff, + 0x2516, 0x255e, 0x45d6, 0xc602, 0xa660, 0xa635, 0xa5f6, 0xa666, + 0x2629, 0xdb41, 0xa672, 0xa68c, 0xa665, 0xa5b2, 0x2458, 0x5c9f, + 0xdd20, 0xa485, 0xda36, 0x2560, 0x2586, 0x269e, 0x27d1, 0xb08a, + 0x2400, 0xa4a9, 0xa45a, 0x5a98, 0xdbf1, 0xa457, 0xd123, 0xd39e, + 0xa57a, 0xa523, 0x24d1, 0x255e, 0x45d6, 0xc602, 0x242f, 0x2553, + 0x2554, 0x255f, 0x5aec, 0xe5d9, 0xa61c, 0xa5ca, 0xa62e, 0xa5e9, + 0xa515, 0xa59a, 0xa59e, 0xa41f, 0xdaaf, 0xaff5, 0xa60a, 0xdb2a, + 0xe5ee, 0x242f, 0x2518, 0x2554, 0x255f, 0x5aec, 0xe5d9, 0x242f, + 0x2518, 0x2553, 0x255f, 0x5aec, 0xe5d9, 0xa649, 0xa649, 0x24d1, + 0x2516, 0x45d6, 0xc602, 0x242f, 0x2518, 0x2553, 0x2554, 0x5aec, + 0xe5d9, 0x24f2, 0x2586, 0x269e, 0x27d1, 0xb08a, 0x5854, 0x5858, + 0xe29c, 0xa616, 0xa5c7, 0xa6c0, 0x265b, 0x2699, 0x26d3, 0xef67, + 0xa613, 0x26c9, 0xcf57, 0xa63d, 0xa62f, 0xa510, 0x24af, 0xd849, + 0x6927, 0xe935, 0xdb71, 0x24f2, 0x2560, 0x269e, 0x27d1, 0xb08a, + 0x2459, 0xa4bc, 0x267e, 0xc616, 0x2003, 0x207a, 0xa4b1, 0xa524, + 0x3198, 0x3199, 0xbb56, 0xa527, 0xa5bb, 0x9e27, 0x2403, 0xa644, + 0x9e54, 0x2355, 0xa358, 0x25b7, 0xa674, 0x68df, 0x68e0, 0xe963, + 0xa4df, 0x41df, 0xd425, 0x25af, 0xa674, 0xa5a9, 0xa60d, 0xa6b3, + 0xef45, 0xa45b, 0xa56c, 0xa51d, 0xa417, 0xa45c, 0xa469, 0xe16a, + 0xab60, 0xa637, 0xa522, 0xa6c1, 0xa66f, 0xa4d4, 0xdb30, 0x23f9, + 0xbb4e, 0xa540, 0xa5bd, 0x247c, 0xdb3c, 0xa56f, 0xa455, 0xa567, + 0x2690, 0x2c1d, 0xc51e, 0xa653, 0xa51b, 0xa6b6, 0xa62f, 0x24d7, + 0xdb41, 0xa520, 0x2578, 0xa628, 0xa3fd, 0xa6d1, 0xa4d3, 0xa5e5, + 0xa452, 0xa574, 0xb076, 0xdb50, 0x2403, 0xa5ab, 0xa655, 0x2556, + 0xa557, 0xa668, 0xa618, 0xa645, 0x241f, 0xda21, 0x256e, 0xa699, + 0xa695, 0xa49d, 0xa4d2, 0xdb6b, 0xa4dd, 0xa4d5, 0xa650, 0xdb5f, + 0xa5f3, 0xa4d9, 0x25af, 0xa5b7, 0x585c, 0x585f, 0xe053, 0xa428, + 0xaf53, 0xa591, 0xa49b, 0xa413, 0xa4dc, 0xa694, 0x2617, 0x2c1d, + 0xc51e, 0xa68f, 0xa65c, 0x256e, 0x265b, 0x26d3, 0xef67, 0x24f2, + 0x2560, 0x2586, 0x27d1, 0xb08a, 0xbd4f, 0xa6ca, 0xa6c2, 0xa4bd, + 0xa456, 0xa499, 0xa411, 0x9eb8, 0xa5be, 0x1e25, 0xa3b3, 0xa624, + 0xa6c2, 0xa56d, 0xa5eb, 0x26a3, 0xa6bb, 0xa181, 0xa453, 0x2570, + 0xcf57, 0xa6a2, 0xd2cf, 0xd271, 0xa631, 0x256e, 0x2699, 0xef67, + 0x26f2, 0x26f4, 0xa70d, 0x26de, 0x26ec, 0x2efb, 0x2efd, 0x5ff4, + 0xe025, 0xa6e0, 0x9e96, 0x26d8, 0x26ec, 0x2efb, 0x2efd, 0x5ff4, + 0xe025, 0xe856, 0xa6d9, 0x26e3, 0x2718, 0xccf0, 0x26e2, 0x2718, + 0xccf0, 0x3df5, 0x3e0a, 0xbe15, 0xa18f, 0xa6f1, 0x26d8, 0x26de, + 0x2efb, 0x2efd, 0x5ff4, 0xe025, 0x2213, 0x2712, 0xd597, 0x26f6, + 0x26fb, 0x26fd, 0x2700, 0xa70b, 0xc74f, 0xa6ea, 0x26d7, 0x26f4, + 0xa70d, 0x26fe, 0x2716, 0xa717, 0x26d7, 0x26f2, 0xa70d, 0xa707, + 0x26ef, 0x26fb, 0x26fd, 0x2700, 0xa70b, 0xb5e5, 0x26ef, 0x26f6, + 0x26fd, 0x2700, 0xa70b, 0x26ef, 0x26f6, 0x26fb, 0x2700, 0xa70b, + 0x26f3, 0x2716, 0xa717, 0x26ef, 0x26f6, 0x26fb, 0x26fd, 0xa70b, + 0xa711, 0x2186, 0x270e, 0xa713, 0xa6f5, 0xa70f, 0x26ef, 0x26f6, + 0x26fb, 0x26fd, 0xa700, 0x26d7, 0x26f2, 0xa6f4, 0x2186, 0x2706, + 0xa713, 0xa708, 0xa703, 0x26ed, 0xd597, 0x2186, 0x2706, 0xa70e, + 0x26f3, 0x26fe, 0xa717, 0x26f3, 0x26fe, 0xa716, 0x26e2, 0xa6e3, + 0x383e, 0xbb12, 0xa721, 0xa71f, 0x453a, 0xc53c, 0xd056, 0x238b, + 0xa8d3, 0xb257, 0xb747, 0xc3ea, 0x2754, 0x27ca, 0xadb3, 0xa8d9, + 0x2834, 0xa872, 0x3b7e, 0x3b7f, 0x3b81, 0xbca1, 0xe62f, 0x2c85, + 0xe62a, 0x276f, 0x28ca, 0x28de, 0xe62b, 0xaea7, 0xe62c, 0xa78b, + 0x2730, 0x27ca, 0xadb3, 0x21f7, 0x284a, 0xa8a4, 0xade0, 0xa805, + 0x28b0, 0x28b5, 0x28c7, 0x28dc, 0x4f48, 0xcf4e, 0xa8e2, 0x27bb, + 0xa8e9, 0x2862, 0xe696, 0x28b3, 0xe6ab, 0x289c, 0xc908, 0xa802, + 0xa803, 0xb1bb, 0xa88c, 0x6640, 0xe641, 0xbce5, 0x23f0, 0xd1fa, + 0x274f, 0xe62b, 0xa7a7, 0xa787, 0x1e18, 0x9e20, 0xa7a2, 0xa8a2, + 0xa7c0, 0xa8df, 0xa8e0, 0xa8da, 0xa773, 0xa753, 0x2841, 0xa8d8, + 0xc561, 0xe67b, 0xa39a, 0xa806, 0x282f, 0x2c27, 0xac2d, 0xa79c, + 0xa79b, 0xa8a2, 0xa778, 0xa8be, 0xa770, 0xab88, 0x280a, 0xd056, + 0xa88a, 0xa7e1, 0xa8b6, 0xa8cb, 0xa84f, 0xa816, 0x275d, 0xa8e9, + 0xa782, 0xc86e, 0xe656, 0x2730, 0x2754, 0xadb3, 0x24f2, 0x2560, + 0x2586, 0x269e, 0xb08a, 0xa7d3, 0xa7d2, 0xa852, 0x2864, 0xa8ce, + 0xa81d, 0x28c4, 0xe1ce, 0x2824, 0xe684, 0xa7ad, 0xc897, 0xb267, + 0x2d0e, 0x2d5c, 0xc895, 0xb383, 0xa763, 0xa764, 0xa75a, 0xa796, + 0xd3eb, 0xa7a9, 0xa879, 0x28ae, 0xa8af, 0xa7b4, 0xe67b, 0xa7da, + 0x27de, 0xe684, 0x6636, 0xe68e, 0x279a, 0x2c27, 0xac2d, 0x2895, + 0xe681, 0xb2a5, 0x273a, 0xa872, 0x454c, 0xc54d, 0x2792, 0xa8d8, + 0xa8ea, 0x21f7, 0x2757, 0xa8a4, 0xd314, 0xc57b, 0xa7b2, 0xa851, + 0xa850, 0xa7d8, 0xa896, 0xbd82, 0xa8a7, 0xa1a2, 0xd46c, 0xa86b, + 0xa75e, 0x27d9, 0xa8ce, 0xe663, 0x46d0, 0xee7d, 0xa861, 0x273a, + 0xa834, 0xac18, 0x2364, 0xee75, 0x2811, 0xa8cd, 0x450e, 0x4816, + 0xc8da, 0xc245, 0xa7ab, 0xa767, 0x2830, 0xe681, 0xa854, 0xa89e, + 0x28bb, 0xc246, 0x2760, 0xc908, 0xa897, 0x277a, 0xa7a1, 0x21f7, + 0x2757, 0xa84a, 0xa859, 0x2815, 0xa8af, 0x2815, 0xa8ae, 0x275b, + 0x28b5, 0x28dc, 0x4f48, 0xcf4e, 0x275f, 0xe6ab, 0x275b, 0x28b0, + 0x28dc, 0x4f48, 0xcf4e, 0xa7af, 0xde87, 0xa899, 0xa7a6, 0x27dc, + 0xe1ce, 0xa75b, 0x274f, 0xa8de, 0xa7b1, 0xa8e4, 0xa879, 0x27d9, + 0xa864, 0xc4bd, 0x238b, 0xa727, 0x2792, 0xa841, 0xa739, 0xa786, + 0x275b, 0x28b0, 0x28b5, 0x4f48, 0xcf4e, 0x274f, 0xa8ca, 0xa784, + 0xa785, 0x23e1, 0xc77f, 0xa75c, 0xa8cc, 0x2398, 0x2edb, 0xe13d, + 0x275d, 0xa7bb, 0xa846, 0x28ef, 0xa8f5, 0x28ee, 0xa8f5, 0xd072, + 0xa8f9, 0x2356, 0xdce3, 0x3bbb, 0xbbbc, 0x28ee, 0xa8ef, 0x28f7, + 0xa8fa, 0x28f6, 0xa8fa, 0xa8fc, 0xa8f1, 0x28f6, 0xa8f7, 0x2a7f, + 0xd05f, 0xa8f8, 0x2900, 0xabff, 0x28fd, 0xabff, 0xa90a, 0x21e6, + 0xd655, 0xe64d, 0x1ffb, 0x2079, 0x2099, 0xa0c3, 0x23d8, 0xdb8a, + 0xa902, 0x2fa9, 0x5907, 0xd986, 0xa913, 0xa90f, 0xd641, 0x236f, + 0xb23c, 0xa91b, 0xa91a, 0x9eb1, 0xa920, 0xa91f, 0x2923, 0xb8a6, + 0x2922, 0xb8a6, 0x9f19, 0x2172, 0x6754, 0xe75d, 0xa3cf, 0xbb80, + 0x372c, 0xb94d, 0xbcf0, 0xe82d, 0xbbd4, 0xda87, 0xa93e, 0xa96a, + 0xa939, 0x2332, 0x2333, 0xa969, 0xa950, 0xcad2, 0xb7f0, 0xa96e, + 0xeede, 0xa942, 0x4287, 0xe029, 0x2968, 0x296c, 0xc34e, 0xaf09, + 0xc55a, 0x2967, 0xadb4, 0x2965, 0xadb4, 0x2956, 0x296c, 0xc34e, + 0x2332, 0x2333, 0xa941, 0xa93a, 0x2956, 0x2968, 0xc34e, 0xa94b, + 0x29b3, 0xab2d, 0x29e6, 0xa9e7, 0x299d, 0x2a24, 0x4ca7, 0xccda, + 0x2a66, 0xaa8d, 0xaabd, 0xa9d9, 0x29f8, 0xd505, 0xa9ac, 0xc945, + 0xc385, 0xaab8, 0x2986, 0x2a24, 0x4ca7, 0xccda, 0xaaf5, 0xaad7, + 0x2aaf, 0xab00, 0xa992, 0x1f60, 0x2976, 0xab2d, 0x1f84, 0xa9ea, + 0x2a3f, 0xaa40, 0xaa12, 0xa9ca, 0xa9c9, 0x1e68, 0xa158, 0xa9d7, + 0xaa8e, 0xaa30, 0xa9cd, 0xa98a, 0xd591, 0xaa1f, 0x2978, 0xa9e7, + 0x2978, 0xa9e6, 0x1f84, 0xa9b7, 0xa9ec, 0xa9eb, 0xaae6, 0x298d, + 0xd505, 0xaa63, 0xaa41, 0xaa6d, 0xab08, 0xab0c, 0xab4c, 0xa9c6, + 0x2b22, 0xab43, 0x2a2f, 0xaa31, 0xa9e2, 0x2986, 0x299d, 0x4ca7, + 0xccda, 0xab2a, 0xab09, 0x2a1b, 0xaa31, 0xa9d2, 0x2a1b, 0xaa2f, + 0xaaa7, 0x2afa, 0xaafb, 0x29b8, 0xaa40, 0x29b8, 0x2a3f, 0xaa50, + 0xaa04, 0xaa40, 0xa9fb, 0x2987, 0xaa8d, 0xbdeb, 0xaa05, 0x1e3d, + 0xee97, 0xaaff, 0x2b30, 0x2b46, 0xab7e, 0xab0b, 0xab38, 0x28fb, + 0xd05f, 0x2987, 0xaa66, 0xa9d0, 0xaa32, 0xaabc, 0xab03, 0x29ab, + 0xab00, 0xa99b, 0xaaaa, 0xa988, 0x3127, 0xd06d, 0x2b1d, 0xd885, + 0xab32, 0xab21, 0xab2a, 0xa9aa, 0xa9ee, 0xab19, 0xa9a9, 0x3194, + 0xc644, 0x2a34, 0xaafb, 0x2a34, 0xaafa, 0xaa73, 0x29ab, 0xaaaf, + 0xaaad, 0xaa06, 0xaa2d, 0xaa75, 0xaa07, 0xaaf1, 0x2acb, 0xd885, + 0xaad2, 0x2a18, 0xab43, 0xab37, 0x2a26, 0xaad4, 0x2976, 0xa9b3, + 0x2a74, 0x2b46, 0xab7e, 0xaad0, 0xab24, 0xaa76, 0xb1d2, 0x2a18, + 0xab22, 0x2a74, 0x2b30, 0xab7e, 0xaa08, 0xab53, 0xab52, 0xab6b, + 0xa5e3, 0x2b78, 0x3569, 0x3585, 0x3586, 0xb588, 0xab7f, 0xab59, + 0x2b66, 0x3569, 0x3585, 0x3586, 0xb588, 0xab7d, 0xab7c, 0x2a74, + 0x2b30, 0xab46, 0xab6a, 0x2bcd, 0x2bd5, 0x2bd7, 0x2bdc, 0x2be7, + 0xc52f, 0xa197, 0x4260, 0x5675, 0xd6c7, 0xca79, 0xa7a8, 0xca81, + 0xd089, 0x219d, 0xab9c, 0x219d, 0xab90, 0x2bda, 0x2bf3, 0x2bf6, + 0xc3e4, 0x2b9f, 0xabe6, 0x2b9e, 0xabe6, 0xabf5, 0x2bb7, 0xabe9, + 0xac4e, 0xb1b2, 0xabae, 0xabab, 0x5b8c, 0xe1bc, 0xa0a2, 0x2ba1, + 0xabe9, 0xabc6, 0x21a6, 0xabc7, 0x2bdb, 0xabec, 0x5cd3, 0xdcd4, + 0xe1c7, 0xa1a4, 0xabbb, 0x21a6, 0xabbc, 0x6751, 0xe752, 0x66ba, + 0x674d, 0x674e, 0x674f, 0x6db4, 0x6e16, 0xee64, 0xa1a8, 0x2b81, + 0x2bd5, 0x2bd7, 0x2bdc, 0x2be7, 0xc52f, 0xaebd, 0x2b81, 0x2bcd, + 0x2bd7, 0x2bdc, 0x2be7, 0xc52f, 0x2b81, 0x2bcd, 0x2bd5, 0x2bdc, + 0x2be7, 0xc52f, 0x2b9d, 0x2bf3, 0x2bf6, 0xc3e4, 0x2bbd, 0xabec, + 0x2b81, 0x2bcd, 0x2bd5, 0x2bd7, 0x2be7, 0xc52f, 0xabe2, 0xda67, + 0x4aad, 0xcab6, 0xabdd, 0x2b9e, 0xab9f, 0x2b81, 0x2bcd, 0x2bd5, + 0x2bd7, 0x2bdc, 0xc52f, 0x2ba1, 0xabb7, 0x2199, 0xa1a9, 0x2bbd, + 0xabdb, 0x2b9d, 0x2bda, 0x2bf6, 0xc3e4, 0xaba0, 0x2b9d, 0x2bda, + 0x2bf3, 0xc3e4, 0x2bfe, 0xac0d, 0xac0b, 0xac0e, 0x2bf9, 0xac0d, + 0x28fd, 0xa900, 0x1e13, 0xac08, 0x214b, 0x224b, 0xa2ca, 0xac07, + 0xac06, 0x1e13, 0xac02, 0xa3de, 0xabfb, 0x2bf9, 0xabfe, 0xabfc, + 0x2c13, 0x2c14, 0xc23e, 0x2c12, 0x2c14, 0xc23e, 0x2c12, 0x2c13, + 0xc23e, 0xa875, 0xac1a, 0xac19, 0x1e48, 0x2e85, 0x6ebc, 0xeebd, + 0x2617, 0x2690, 0xc51e, 0xc1ce, 0x2c20, 0x5d7b, 0x6bae, 0x6c7b, + 0xec9c, 0x2c1f, 0x5d7b, 0x6bae, 0x6c7b, 0xec9c, 0x2c23, 0x2c24, + 0xb023, 0xac22, 0x2c22, 0xb023, 0xac26, 0xac25, 0x279a, 0x282f, + 0xac2d, 0xac2b, 0xac29, 0xeb40, 0x279a, 0x282f, 0xac27, 0x21f2, + 0x2c34, 0x2c36, 0x2c37, 0xeb50, 0x21f2, 0x2c32, 0x2c36, 0x2c37, + 0xeb50, 0x21f2, 0x2c32, 0x2c34, 0x2c37, 0xeb50, 0x21f2, 0x2c32, + 0x2c34, 0x2c36, 0xeb50, 0xac4d, 0x1fad, 0x2118, 0xc6e1, 0x1fb7, + 0xddfc, 0xac64, 0xac53, 0xa1e5, 0xac4a, 0xac46, 0x6ce5, 0xee1f, + 0xac38, 0xaba9, 0x2c5b, 0xae48, 0xac43, 0x2c4f, 0xae48, 0xac6c, + 0xac62, 0xac61, 0xac42, 0xac68, 0xac66, 0xac5e, 0xadbc, 0xa1fa, + 0x1e97, 0x2d57, 0x3b72, 0xbb73, 0xdc48, 0x2742, 0xe62a, 0xdc3a, + 0xad87, 0xad17, 0xacf4, 0xad50, 0x2cf6, 0x2d8b, 0x2d8c, 0x2db9, + 0x6666, 0x669d, 0xe6af, 0xa188, 0x2d52, 0x2d53, 0x2dcc, 0x2dd6, + 0x2dd7, 0xc89e, 0xadba, 0xadbd, 0xad87, 0xad2c, 0xadcb, 0xada8, + 0xada7, 0xacdd, 0xacd2, 0xacfd, 0xada2, 0xada0, 0xad22, 0xadd2, + 0xace9, 0xace8, 0xacf0, 0xacef, 0xac98, 0x2d58, 0x2db8, 0xadc6, + 0x2c9b, 0x2d8b, 0x2d8c, 0x2db9, 0x6666, 0x669d, 0xe6af, 0xace1, + 0xad97, 0xad0d, 0xadae, 0xad08, 0xad07, 0x234e, 0xd3ef, 0xad03, + 0x27fc, 0x2d5c, 0xc895, 0xa393, 0xac97, 0x1ed1, 0xad19, 0x1ed1, + 0xad18, 0xace5, 0xacbd, 0x2d83, 0xad84, 0xcbcf, 0xac9a, 0x2ca9, + 0x2d53, 0xc89e, 0x2ca9, 0x2d52, 0xc89e, 0x1e97, 0x2c81, 0x3b72, + 0xbb73, 0x2cf5, 0x2db8, 0xadc6, 0xad94, 0x27fc, 0x2d0e, 0xc895, + 0xad81, 0x3e13, 0xbeaa, 0xad73, 0xad6f, 0xad5d, 0xad2d, 0xad2d, + 0x2c96, 0xacb4, 0x2c9b, 0x2cf6, 0x2d8c, 0x2db9, 0x6666, 0x669d, + 0xe6af, 0x2c9b, 0x2cf6, 0x2d8b, 0x2db9, 0x6666, 0x669d, 0xe6af, + 0xad5a, 0xad02, 0xace4, 0xace3, 0xacc4, 0xacc3, 0xad04, 0xe6df, + 0x2730, 0x2754, 0xa7ca, 0x2965, 0xa967, 0x2cf5, 0x2d58, 0xadc6, + 0x2c9b, 0x2cf6, 0x2d8b, 0x2d8c, 0x6666, 0x669d, 0xe6af, 0xacad, + 0xac7f, 0xacb3, 0x2dd3, 0xadd4, 0x2cf5, 0x2d58, 0xadb8, 0xacbf, + 0x2ca9, 0x2dd6, 0xadd7, 0xace6, 0xadc5, 0xadc5, 0x2ca9, 0x2dcc, + 0xadd7, 0x2ca9, 0x2dcc, 0xadd6, 0xaddd, 0xaddb, 0xa759, 0xade3, + 0xade2, 0xe78f, 0xadf0, 0xadef, 0xa36e, 0xd856, 0xadfd, 0x2377, + 0xb372, 0xadfa, 0x67cd, 0xe7e8, 0x231d, 0xdfca, 0x2370, 0x2e63, + 0xae64, 0x9f48, 0xae25, 0xae2b, 0xcd19, 0xae43, 0xae33, 0x9f16, + 0xd88b, 0xcd48, 0xcc3e, 0xcb92, 0x2e5f, 0xb5d8, 0xae05, 0x2e2f, + 0xae36, 0xae40, 0xae08, 0xd4c6, 0x2e47, 0x2e5a, 0xae6b, 0x2e26, + 0xae36, 0x2f52, 0x3b78, 0xc688, 0xae6c, 0xae10, 0x2e26, 0xae2f, + 0xae58, 0xae57, 0xa183, 0xae27, 0x21aa, 0xcf83, 0xae0f, 0x2e2e, + 0x2e5a, 0xae6b, 0x2c4f, 0xac5b, 0xce28, 0xae3c, 0xae3b, 0x2e2e, + 0x2e47, 0xae6b, 0x2e1c, 0xb5d8, 0xb5d9, 0x2e01, 0xae64, 0x2e01, + 0xae63, 0x2e2e, 0x2e47, 0xae5a, 0xae31, 0x1e7e, 0x2e79, 0xb9a6, + 0xc9ca, 0x1e26, 0x1f75, 0x2002, 0x20a1, 0x2e77, 0xcadd, 0xae76, + 0xa016, 0x2e72, 0xb9a6, 0x9e48, 0xa1e0, 0x2e83, 0x2eb5, 0xaee3, + 0x2ef0, 0xaef3, 0x2e7f, 0xaee3, 0x5358, 0xd38a, 0x1e48, 0x2c1b, + 0x6ebc, 0xeebd, 0xb176, 0xc240, 0xaeec, 0xaee1, 0xaeab, 0x2fdc, + 0xb1c9, 0xaedf, 0xef90, 0x2ec3, 0xaee2, 0xa750, 0xae93, 0x2e7f, + 0x53f4, 0x544a, 0xd4ed, 0xaebb, 0x377e, 0x3780, 0x37a9, 0x37d7, + 0xb8a5, 0xaeb6, 0xaece, 0xabd3, 0xaedf, 0x2395, 0xa3a0, 0xa3a2, + 0x2e9f, 0xaee2, 0xa3a6, 0xaebc, 0x23a9, 0xaed0, 0x23a9, 0xaecf, + 0xa3a8, 0x2398, 0x28e5, 0xe13d, 0xa3ae, 0x2e99, 0xaebf, 0x2382, + 0xa3b0, 0xae91, 0x2e9f, 0xaec3, 0x2e7f, 0xae83, 0xaeea, 0xaee9, + 0xae90, 0x2385, 0x2e81, 0xaef3, 0x2385, 0x239b, 0x2e81, 0xaef0, + 0xdfea, 0x26d8, 0x26de, 0x26ec, 0x2efd, 0x5ff4, 0xe025, 0x1e43, + 0xdffa, 0x26d8, 0x26de, 0x26ec, 0x2efb, 0x5ff4, 0xe025, 0xe58b, + 0x44e3, 0x598d, 0x5fa1, 0x5fa7, 0x5fa8, 0x5fa9, 0xdfaf, 0xc570, + 0xb8c4, 0x330a, 0xb335, 0xa958, 0x9e00, 0x9e8c, 0x1e09, 0xa3c1, + 0x5cae, 0x5cb3, 0xdd30, 0xaf12, 0xaf11, 0xa40a, 0xaf35, 0x2f4c, + 0xc030, 0xcd43, 0xaf33, 0xaf4e, 0xaf2a, 0xaf20, 0xaf3a, 0x2f3e, + 0xaf48, 0xaf37, 0xaf3c, 0xaf3b, 0x2f39, 0xaf48, 0xa22b, 0x2f39, + 0xaf3e, 0xaf25, 0xaf2f, 0xaf51, 0xaf50, 0x2e30, 0x3b78, 0xc688, + 0x2679, 0xc576, 0xaf55, 0x2f54, 0x6304, 0xe332, 0xcbf2, 0x2f5a, + 0xbc47, 0x2f59, 0xbc47, 0x2f5c, 0x2f5d, 0xaf5e, 0x2f5b, 0x2f5d, + 0xaf5e, 0x2f5b, 0x2f5c, 0xaf5e, 0x2f5b, 0x2f5c, 0xaf5d, 0xaf60, + 0x2f5f, 0xd4a6, 0xaf66, 0xaf65, 0xaf72, 0xcdb5, 0xe6d5, 0x1efd, + 0xb58c, 0xaf68, 0x9ee2, 0x1eff, 0x2fac, 0xeae3, 0xafb9, 0x1f5b, + 0xeaf4, 0x2f83, 0xdfec, 0x2fb0, 0x2fb4, 0xafb5, 0xaf80, 0x2f91, + 0x5ff3, 0xe015, 0xc2e5, 0x9f77, 0x9f6a, 0xa40e, 0xe65f, 0x2f84, + 0x5ff3, 0xe015, 0x1ece, 0xaf9e, 0x22d1, 0xafa0, 0x1ece, 0xaf93, + 0x22d1, 0xaf95, 0xc9a6, 0x201f, 0xd5c9, 0xa065, 0x290d, 0xd986, + 0x1eff, 0x208d, 0xaf77, 0xa09c, 0xaf81, 0xa0c4, 0x2fb7, 0x3074, + 0xb0b3, 0x2f81, 0xafb5, 0x2f81, 0xafb4, 0x2fb3, 0x3074, 0xb0b3, + 0xaf7b, 0xafc4, 0xafc3, 0xb1b6, 0x9ec1, 0x31f4, 0xb1fa, 0xda8c, + 0xb07e, 0x2e94, 0xb1c9, 0xb09f, 0xb025, 0xb182, 0x2306, 0x3031, + 0xb0a4, 0xb0b4, 0xa538, 0xb13e, 0x31d0, 0xb1f7, 0xb14b, 0xb16b, + 0xb1ae, 0xb16a, 0xb0b5, 0xb134, 0x9f42, 0xb091, 0xb190, 0xb056, + 0x2c22, 0xac24, 0xafe3, 0xb060, 0x2306, 0x2fe9, 0xb0a4, 0x30e3, + 0x3374, 0x4dcf, 0x4deb, 0xce3d, 0xb1df, 0xb1cc, 0xb052, 0xb200, + 0xb046, 0x21c4, 0xb0bd, 0xb01d, 0xb02a, 0x241d, 0xb08b, 0x2379, + 0xdcc9, 0xd03b, 0xb119, 0x3085, 0xb0a6, 0xb1c7, 0x2fb3, 0x2fb7, + 0xb0b3, 0xb0e0, 0x20eb, 0x2641, 0x30aa, 0xb0e1, 0xb15f, 0xb1e8, + 0xb137, 0xb0fb, 0x30a9, 0xb0f1, 0xb0f2, 0xafd9, 0x30e5, 0xb142, + 0x3111, 0xb139, 0x3071, 0xb0a6, 0x24f2, 0x2560, 0x2586, 0x269e, + 0xa7d1, 0xb061, 0xc302, 0xb016, 0x9fd4, 0x3102, 0xda96, 0xdbef, + 0xafe2, 0xb0ca, 0x2306, 0x2fe9, 0xb031, 0x3071, 0xb085, 0x307c, + 0xb0f1, 0x20eb, 0x3076, 0xb0e1, 0xb164, 0xb1f8, 0xb173, 0xb1ab, + 0x2fb3, 0x2fb7, 0xb074, 0xaff0, 0xb005, 0xe5f7, 0x21c4, 0xb053, + 0x30a2, 0xea5a, 0x248a, 0x248c, 0xefa2, 0x1ffd, 0xbb23, 0xb075, + 0x20eb, 0x3076, 0xb0aa, 0xb03b, 0x307f, 0xb142, 0xb1fc, 0xb158, + 0xb1f2, 0xb18a, 0xb11c, 0x3159, 0xb15a, 0xb19a, 0xb163, 0x307c, + 0xb0a9, 0xb07d, 0xd822, 0xb07b, 0xd90a, 0x3096, 0xda96, 0x4609, + 0xc652, 0x3080, 0xb139, 0xb06a, 0xc231, 0xb0ec, 0xb14d, 0xb181, + 0xb1a4, 0xb192, 0x2abf, 0xd06d, 0xb1fc, 0xb006, 0xb07a, 0x3080, + 0xb111, 0xb14e, 0xa35a, 0xaffe, 0xe858, 0x307f, 0xb0e5, 0xb817, + 0xbbb7, 0xb001, 0xb120, 0x313c, 0x361a, 0xc718, 0x3174, 0xb1fe, + 0xb0e8, 0x30ed, 0xb15a, 0x30ed, 0xb159, 0x3078, 0xb185, 0xb0ef, + 0xb0ab, 0xb004, 0xb002, 0xb196, 0xd651, 0xb0ad, 0xb151, 0xae86, + 0x317d, 0xb21a, 0x317c, 0xb21a, 0xbb32, 0x21ed, 0x21f4, 0xb191, + 0xb121, 0xafe7, 0xb15f, 0xb1a9, 0xb0eb, 0xb01c, 0x21ed, 0x21f4, + 0xb17f, 0xb126, 0x2af6, 0xc644, 0x316d, 0xb197, 0xb196, 0x259c, + 0x3199, 0xbb56, 0x259c, 0x3198, 0xbb56, 0xb0ee, 0xb124, 0x22b3, + 0x22b4, 0xa2de, 0xb187, 0xb0af, 0xb003, 0xabaa, 0xafc6, 0xa766, + 0xa2e4, 0xb073, 0x2e94, 0xafdc, 0xb03f, 0xb1d4, 0x3000, 0xb1f7, + 0xb1e3, 0x2b3e, 0xb1f6, 0xb1cd, 0xb1f5, 0xd499, 0xb03c, 0xb1d1, + 0xb1e7, 0xb1e6, 0xb079, 0xb0e9, 0x2fcf, 0xb1ff, 0xb1dc, 0xb1d2, + 0x3000, 0xb1d0, 0xb0ac, 0xafcf, 0x30e7, 0xb133, 0xbb22, 0xb151, + 0xb1f4, 0xb04b, 0xb207, 0xb206, 0xb214, 0x322f, 0xb232, 0xb20b, + 0xb227, 0x3226, 0xb230, 0x317c, 0xb17d, 0xb21e, 0x5ca1, 0xdd22, + 0xb21b, 0x3218, 0xb230, 0xb217, 0xb22c, 0xb229, 0x2279, 0xa2e0, + 0x320f, 0xb232, 0x3218, 0xb226, 0x320f, 0xb22f, 0x3237, 0xb238, + 0x3236, 0xb238, 0x3236, 0xb237, 0xa384, 0xb23e, 0x236f, 0xa918, + 0xb23b, 0xb24c, 0xb24b, 0xce94, 0x33e0, 0xcd2e, 0x34b2, 0xb4c8, + 0xb2c2, 0xa728, 0x5a17, 0xdbac, 0xb34d, 0xb268, 0xe1e6, 0xa7f7, + 0x23c9, 0xb260, 0x32e1, 0xb4f4, 0xb36b, 0xb383, 0xb3da, 0xb4a6, + 0xb4fe, 0xb5bc, 0x2448, 0xc2c2, 0xa214, 0xb4ab, 0xb2cb, 0xb2d4, + 0xb2d7, 0x32e9, 0xb4c7, 0xb476, 0xb473, 0xb384, 0xb436, 0xdb77, + 0xa831, 0xb4e1, 0x32de, 0x4274, 0xd9dd, 0xb255, 0xb4d4, 0xb49a, + 0xb29b, 0xb2ff, 0x37b4, 0xb7fa, 0xb428, 0xb29c, 0xb2d6, 0xb2d5, + 0xb29d, 0xb2dd, 0xb2dc, 0xb2b5, 0xb4ec, 0x336e, 0xb4da, 0x3269, + 0x3304, 0xb4f4, 0xb50f, 0xb3c0, 0xb4c1, 0xb514, 0xb4f0, 0x34a5, + 0xc67a, 0x329e, 0xb4c7, 0xb2cf, 0xb39b, 0x32e1, 0xb4f4, 0x2f04, + 0xb335, 0x1e3e, 0x34e7, 0xd209, 0xb46f, 0xb523, 0xb397, 0xb4be, + 0xb4bb, 0xb33e, 0xb493, 0xb4cb, 0xb49f, 0xb399, 0xb4e0, 0xb3ee, + 0xb48f, 0x2f04, 0xb30a, 0xb412, 0xdf13, 0xb31f, 0xb3d2, 0x3405, + 0x34b9, 0xb52a, 0x38b1, 0x4975, 0xcd91, 0xb25e, 0xb3d1, 0xd379, + 0xb41c, 0xb488, 0xb40d, 0xb4bf, 0xb3db, 0x3417, 0xb4e3, 0xd20d, + 0xb26a, 0x32e0, 0xb4da, 0x2377, 0xadfb, 0xb03b, 0x3816, 0xb8f2, + 0x27fd, 0xb26b, 0xb2a1, 0xb31c, 0xb323, 0xb302, 0xe1c7, 0xb4d1, + 0xa30a, 0xb3ed, 0xb4c4, 0xb451, 0xb4f2, 0xb4a3, 0xb47b, 0xb414, + 0xb45c, 0xc8b0, 0xb2e3, 0xb34f, 0xb33f, 0xb26c, 0xb362, 0xb24e, + 0xb3b2, 0xb325, 0xd0cc, 0x3416, 0xb447, 0xb52c, 0xb4b3, 0xb519, + 0xb4f1, 0xb45f, 0xce3d, 0x3341, 0x34b9, 0xb52a, 0xb784, 0xb35f, + 0xb337, 0xb3bb, 0x33fa, 0xb447, 0xb363, 0x335c, 0xd490, 0xb2d3, + 0xb498, 0xb528, 0xb2a2, 0x34d5, 0xb51c, 0xb9a8, 0x3444, 0xb51d, + 0x3442, 0xb51d, 0xb504, 0x34fa, 0xd96c, 0x33fa, 0xb416, 0xb4ef, + 0xb524, 0xb3b4, 0xb3bc, 0xb402, 0x4dcf, 0x4deb, 0xce3d, 0xb4f5, + 0xb31a, 0xb2a0, 0xb29f, 0xb3ba, 0x21fb, 0xb4ca, 0xb516, 0xb35e, + 0xb326, 0xb491, 0xb490, 0xb320, 0xb42d, 0xb2c8, 0xb322, 0xb4cd, + 0xb3b8, 0x32e8, 0xc67a, 0xb26f, 0x4d55, 0x4d76, 0xcedd, 0xb29a, + 0x3251, 0xb4c8, 0xb3ff, 0xb506, 0xb4f7, 0xb4fc, 0x3341, 0x3405, + 0xb52a, 0xb51b, 0xb31e, 0xb31d, 0xb361, 0xb2e5, 0xb3b3, 0x329e, + 0xb2e9, 0x3251, 0xb4b2, 0x21fb, 0xb483, 0xb321, 0xb4a1, 0xb3a5, + 0xb2c5, 0x343a, 0xb51c, 0x32e0, 0xb36e, 0xb4fb, 0xb324, 0xb2ac, + 0xb363, 0xb52c, 0x1e3e, 0x3319, 0xd209, 0xb2df, 0xb448, 0xb2e7, + 0xb401, 0xb3b7, 0x3269, 0x32e1, 0xb304, 0xb469, 0x34b7, 0xd96d, + 0xb446, 0xb4de, 0xb4b8, 0xb50a, 0xb270, 0x9e51, 0xb445, 0xb522, + 0xb4b5, 0xb51f, 0xb4fd, 0xb2e2, 0xb522, 0xb2e6, 0xb484, 0xb400, + 0xb4ba, 0x343a, 0xb4d5, 0x3442, 0xb444, 0xb508, 0x3505, 0xb512, + 0xb31b, 0xb44a, 0xb432, 0x3341, 0x3405, 0xb4b9, 0xc234, 0x33fd, + 0xb4e5, 0xb535, 0xb534, 0xa3ce, 0xd003, 0x4b27, 0x4b56, 0x4b5e, + 0xcba3, 0x1ff2, 0x209a, 0xa2b9, 0x9f8e, 0xb575, 0x23d9, 0xb558, + 0xb559, 0xa2c4, 0x22c5, 0xa2d1, 0x5d01, 0xdd25, 0x23d9, 0xb54d, + 0xb54e, 0x3582, 0xbb5b, 0xa0d8, 0x2b66, 0x2b78, 0x3585, 0x3586, + 0xb588, 0xb578, 0xb54c, 0xb5c9, 0xb570, 0x69c6, 0x69c8, 0x6a45, + 0xea71, 0xbb5d, 0x355b, 0xbb5b, 0xbbd9, 0x2b66, 0x2b78, 0x3569, + 0x3586, 0xb588, 0x2b66, 0x2b78, 0x3569, 0x3585, 0xb588, 0x2b66, + 0x2b78, 0x3569, 0x3585, 0xb586, 0x1e9d, 0x358a, 0x6f4a, 0xef50, + 0x1e9d, 0x3589, 0x6f4a, 0xef50, 0x358e, 0xef4b, 0x1efd, 0xaf6c, + 0xd9ba, 0x358b, 0xef4b, 0xb595, 0x359e, 0xd7a4, 0xb593, 0x65d8, + 0x6b25, 0x6b26, 0x6b2a, 0xeb2d, 0x3594, 0xd7a4, 0xe159, 0xb5ac, + 0xb5a9, 0xb5b7, 0xb5b5, 0xb5b2, 0xb5ad, 0x1e8e, 0x1e8f, 0xb275, + 0xb5d2, 0xb577, 0xb5c8, 0x4c31, 0xcc4f, 0x2e1c, 0xae5f, 0x2e61, + 0xb5db, 0xb5d9, 0xc121, 0xa6f8, 0xd20a, 0x234f, 0x2354, 0xa3f6, + 0x35f9, 0xb642, 0x2164, 0x363f, 0xb6e0, 0xb698, 0x35f6, 0xb642, + 0xb680, 0xb625, 0xb664, 0xb63b, 0x2347, 0xb6fb, 0xb626, 0xb719, + 0xb62c, 0xb6c7, 0xb14e, 0xc6a8, 0xb5fe, 0xb60a, 0xb60f, 0xc0a4, + 0xb630, 0xb62f, 0xa1ac, 0xb602, 0x365d, 0xb6f8, 0xb6e8, 0x6855, + 0xe86f, 0x35f7, 0xb6e0, 0x35f6, 0xb5f9, 0xb644, 0xb643, 0xb64b, + 0xb649, 0xb6ec, 0x3681, 0xb6c9, 0xb6c4, 0xb688, 0xb689, 0xb669, + 0x363c, 0xb6f8, 0xb660, 0xb65f, 0xb5ff, 0xb6df, 0xb65a, 0xb69c, + 0x3692, 0xc520, 0xb697, 0xb5fa, 0x3653, 0xb6c9, 0xb6ab, 0x4f6a, + 0xdfa0, 0xb655, 0xb656, 0xb674, 0x4156, 0xc157, 0x367b, 0x5af3, + 0x5c19, 0x65c7, 0xe68c, 0xb5f8, 0xb66e, 0xc545, 0x36ad, 0x36cd, + 0xc6a5, 0x2386, 0x23af, 0xb6c6, 0xb6d6, 0xb6c1, 0xb682, 0x36a4, + 0xc6a5, 0x1e86, 0xc7ad, 0xb6a8, 0xb654, 0x2386, 0x23a4, 0x23af, + 0xb6a6, 0xb619, 0x3653, 0xb681, 0x40a4, 0x4167, 0x41f3, 0xc7be, + 0xb6a4, 0xa411, 0xb6a7, 0xb668, 0x35f7, 0xb63f, 0xb63d, 0xb652, + 0x3d40, 0x4cac, 0x6eaf, 0x6eb4, 0xeeb9, 0xb6f5, 0xb6f3, 0x1e66, + 0x363c, 0xb65d, 0xb6fa, 0xb6f9, 0x2347, 0xb607, 0xb6fe, 0xb6fd, + 0xa1a3, 0x22d6, 0xa2d7, 0x9f1a, 0xd8e8, 0xb717, 0xb716, 0xb60e, + 0xb722, 0xb71f, 0xb71e, 0xb71b, 0xd0e7, 0x2932, 0xb94d, 0xa273, + 0xb72f, 0x372e, 0xd853, 0xc843, 0x3a38, 0xba8f, 0xb736, 0xb735, + 0x21e0, 0xba5f, 0xbbba, 0x594d, 0x66d1, 0xe6dc, 0x3a29, 0xbb0a, + 0xb87f, 0xa72c, 0x3766, 0x3919, 0xba86, 0xe0a8, 0xb9d3, 0xb89d, + 0xb803, 0x9f86, 0xb749, 0xb94a, 0xb9aa, 0x386e, 0xc6c3, 0xa091, + 0x9e1c, 0x2eba, 0x3780, 0x37a9, 0x37d7, 0x38a5, 0xeb06, 0xe5c6, + 0x2eba, 0x377e, 0x37a9, 0x37d7, 0xb8a5, 0xb975, 0x3406, 0xb9cb, + 0xb960, 0x1e2b, 0x3860, 0x390f, 0xb930, 0x5edb, 0x5ef6, 0xdf6d, + 0xd3d3, 0xba05, 0xb85d, 0xba1e, 0xb8d7, 0xbaea, 0xb80c, 0xb898, + 0xb8d6, 0x2eba, 0x377e, 0x3780, 0x37d7, 0xb8a5, 0x39cd, 0x6397, + 0xe453, 0xb953, 0xb89f, 0x23f0, 0x3aaf, 0xd01c, 0x32d0, 0xb7fa, + 0xb827, 0xd235, 0xb822, 0xb959, 0x2eba, 0x377e, 0x3780, 0x37a9, + 0xb8a5, 0xbac3, 0xbab8, 0xb7fb, 0x231b, 0xb7fe, 0xa948, 0x3801, + 0x387a, 0xba6e, 0xb805, 0xb7ff, 0x32d0, 0xb7b4, 0xb7e5, 0xba89, + 0x231b, 0xb7e9, 0xb7f9, 0xb894, 0x37f3, 0x387a, 0xba6e, 0x3764, + 0xbad4, 0x39ae, 0xd363, 0xb7f5, 0xba19, 0x385f, 0xb8e7, 0xbadb, + 0x39de, 0xbaf3, 0xb8df, 0x37a6, 0xbae8, 0x3aaa, 0xbadf, 0x3b04, + 0xbb17, 0xba39, 0x337f, 0xb8f2, 0x21d3, 0xb144, 0xa20a, 0xb7cf, + 0xb7bb, 0x3a43, 0xcb4f, 0x39d8, 0xba23, 0xd988, 0x271d, 0xbb12, + 0xb97f, 0x2353, 0xb9d5, 0xb852, 0xb851, 0xb90e, 0x3a31, 0xbafb, + 0xb7a1, 0x3808, 0xb8e7, 0x1e2b, 0x3792, 0xb90f, 0xba48, 0xb968, + 0xba94, 0xb9bf, 0x39d7, 0xba4b, 0xba3a, 0xba9c, 0xb9f3, 0xba01, + 0xba33, 0x376f, 0xc6c3, 0xba03, 0x37f3, 0x3801, 0xba6e, 0xbf06, + 0xb746, 0x3a11, 0xcc17, 0xb9f1, 0x3973, 0xb9d1, 0x4681, 0xc682, + 0xb800, 0xb7a7, 0xb761, 0xb7ad, 0x2eba, 0x377e, 0x3780, 0x37a9, + 0xb7d7, 0x2922, 0xa923, 0x3346, 0xcd91, 0xbaae, 0xb8f6, 0xb9e4, + 0x391c, 0xbaa2, 0xbb1e, 0xaf03, 0x38cb, 0x3ab1, 0x3ac0, 0xc881, + 0x38ca, 0x3ab1, 0x3ac0, 0xc881, 0xb936, 0xb7a8, 0xb7a3, 0xb80b, + 0xba0a, 0x3808, 0xb85f, 0xca1c, 0x337f, 0xb816, 0xb8be, 0xbac2, + 0xc897, 0xb9e8, 0x1e57, 0x9e58, 0xb858, 0x1e2b, 0x3792, 0xb860, + 0x47f4, 0xc887, 0xb95a, 0xb749, 0x38c0, 0xbaa2, 0xbadd, 0xb9e7, + 0xb9f6, 0xbb0f, 0xba3f, 0xba62, 0xb792, 0xd46e, 0xb8d5, 0xd45a, + 0xb768, 0x2932, 0xb72c, 0xb7ab, 0xba62, 0xb7d5, 0xb918, 0xb78f, + 0xb986, 0xb966, 0xb965, 0xb862, 0xc243, 0xba9d, 0x9e1a, 0x3885, + 0xb9d1, 0xb781, 0xba13, 0x1e50, 0xba02, 0xb842, 0xbb16, 0xb9b2, + 0xb961, 0xbaec, 0xbada, 0x3af8, 0xbb05, 0xc253, 0x2e72, 0xae79, + 0xb43e, 0xb769, 0x3804, 0xd363, 0xb985, 0xba4a, 0xe198, 0xb864, + 0xb9d9, 0x5028, 0xe392, 0xb784, 0xb7aa, 0x3885, 0xb973, 0xb760, + 0x39f9, 0xba70, 0x2353, 0xb84c, 0x3865, 0xba4b, 0x3837, 0xba23, + 0xb9c7, 0xba9f, 0x3abb, 0xce7f, 0xb80a, 0xbab3, 0xbae7, 0xb8bf, + 0xb920, 0xb901, 0xb884, 0xb868, 0xb922, 0xb9d4, 0xb869, 0x1e50, + 0xb97d, 0xb879, 0xb79e, 0xb8e5, 0xbad3, 0x3881, 0xcc17, 0xbac1, + 0xb97c, 0xb807, 0xb7a2, 0x3837, 0xb9d8, 0x3743, 0xbb0a, 0x3a6b, + 0xbace, 0x3aa3, 0xd262, 0x385c, 0xbafb, 0xb86a, 0x1e1b, 0x23e2, + 0x3b09, 0xd5c2, 0x3734, 0xba8f, 0xb811, 0xb866, 0xcf47, 0xb92b, + 0x3830, 0xcb4f, 0xb861, 0xb9b4, 0x3865, 0xb9d7, 0xb73a, 0x392d, + 0xb955, 0x3a2a, 0xbace, 0x37f3, 0x3801, 0xb87a, 0xb9d4, 0xbae5, + 0x3ad3, 0x5263, 0xd26a, 0xbade, 0xbaa9, 0xbafd, 0xb749, 0xb7fd, + 0x3734, 0xba38, 0xcc37, 0xb863, 0x3a98, 0xd617, 0xba97, 0xb867, + 0xb96b, 0xb9da, 0x38c0, 0xb91c, 0xba2f, 0xba81, 0x380e, 0xbadf, + 0xb8bc, 0x23f0, 0xb7b1, 0x38ca, 0x38cb, 0x3ac0, 0xc881, 0xb9df, + 0xb7e0, 0xb9db, 0x38ca, 0x38cb, 0x3ab1, 0xc881, 0xba12, 0xb8f9, + 0xb7dc, 0xa1f3, 0xd030, 0x3a2a, 0xba6b, 0x3a10, 0xba79, 0xb803, + 0xbb11, 0xb988, 0xb809, 0xb91f, 0xba7c, 0x380e, 0xbaaa, 0xba71, + 0xb9e0, 0xb80c, 0xb7a5, 0xb987, 0xb80a, 0xb989, 0xbb1e, 0x385c, + 0xba31, 0xba83, 0x380f, 0xbb17, 0xb989, 0x1e1b, 0x23e2, 0x3a37, + 0xd5c2, 0x3743, 0xba29, 0xb924, 0xbad5, 0x271d, 0xb83e, 0xb984, + 0x380f, 0xbb04, 0x60c1, 0x6b30, 0xeb31, 0x38c2, 0xbafa, 0x4f3a, + 0xcf3c, 0x31fd, 0x3b53, 0x3b61, 0xea69, 0x1ffd, 0x30de, 0xda22, + 0xbb5f, 0xbb50, 0xb17e, 0xbb3e, 0xbb58, 0xe4a6, 0xbb35, 0xdb0c, + 0x23f9, 0xa606, 0xbb27, 0x3b22, 0xbb61, 0x259c, 0x3198, 0xb199, + 0xbb3b, 0x355b, 0xb582, 0xb581, 0xbb24, 0x3b22, 0xbb53, 0x3b68, + 0xbb69, 0x3b65, 0xbb69, 0x3b65, 0xbb68, 0xa24d, 0x3e0b, 0x3f80, + 0xbf81, 0x6f52, 0xef7f, 0x1e97, 0x2c81, 0x2d57, 0xbb73, 0x1e97, + 0x2c81, 0x2d57, 0xbb72, 0x2386, 0x23af, 0xbb77, 0x2386, 0x23af, + 0xbb74, 0x2e30, 0x2f52, 0xc688, 0xbb7a, 0xbb79, 0x3bb1, 0xbbb2, + 0x273d, 0x3b7f, 0x3b81, 0xbca1, 0x273d, 0x3b7e, 0x3b81, 0xbca1, + 0xa92d, 0x273d, 0x3b7e, 0x3b7f, 0xbca1, 0xbba4, 0xbb98, 0xbb9e, + 0xbbae, 0xbb8b, 0xbbab, 0xbb92, 0xbbaf, 0xbb87, 0xbb9a, 0xbb93, + 0xbba1, 0x3b7c, 0xbbb2, 0x3b7c, 0xbbb1, 0xbbc6, 0xb147, 0xb740, + 0x28f3, 0xbbbc, 0x28f3, 0xbbbb, 0xbbc1, 0x3bc0, 0x41ec, 0xdb6d, + 0xdf42, 0xbbb4, 0x233b, 0xe1ab, 0xbbcf, 0xbbce, 0x50b2, 0xd8ac, + 0xa936, 0xc562, 0xbbd8, 0xbbd7, 0xb583, 0xbbee, 0xbc08, 0xc403, + 0xbbdf, 0xbbff, 0xbbf5, 0x4266, 0xc29b, 0xbc0c, 0x3be1, 0xbc0a, + 0xbc08, 0xbc07, 0x3c17, 0x3c23, 0xc081, 0x3c14, 0x3c23, 0xc081, + 0xe6f0, 0xbc2b, 0x3c14, 0x3c17, 0xc081, 0xbc2c, 0xbc22, 0xbc29, + 0xbc33, 0xbc32, 0x3c35, 0xbc3a, 0x3c34, 0xbc3a, 0x1ecc, 0x21ab, + 0xa1b0, 0x3c34, 0xbc35, 0x232f, 0x2f59, 0x2f5a, 0xbed9, 0xbf22, + 0xbcdb, 0x3c5a, 0xbc61, 0x3c59, 0xbc61, 0x3c59, 0xbc5a, 0xbe6f, + 0xbc74, 0xbc73, 0xbd36, 0xa1b3, 0xbef8, 0x3c89, 0xc00b, 0xbc88, + 0xbca1, 0xa1b2, 0xbdfb, 0xbe9d, 0x273d, 0x3b7e, 0x3b7f, 0x3b81, + 0xbc92, 0x3cfd, 0xbfa4, 0xc043, 0xbf1a, 0xc01d, 0xbdea, 0xbec4, + 0xbe22, 0xbf59, 0x3eec, 0xcc04, 0xe63b, 0xbcb2, 0xbcb1, 0xbfd4, + 0xe711, 0xa1b5, 0x1f71, 0xc04b, 0xbc4e, 0xbeaf, 0xbfd8, 0xa76d, + 0xda3b, 0x3d99, 0xbdda, 0xa1ba, 0xa933, 0xbfa9, 0x3edd, 0xc027, + 0xc018, 0xbffc, 0xc009, 0x3e8c, 0x3f51, 0xc67a, 0x3ca2, 0xbfa4, + 0xbd87, 0xbf54, 0xa1bd, 0xc051, 0xbf54, 0xbc79, 0xcaaa, 0xb6f2, + 0xbd79, 0xbde8, 0xbdfa, 0xbf3f, 0xbf86, 0xbe5e, 0xbeae, 0xbfc1, + 0xbe2c, 0xbfae, 0x3e08, 0xbfdf, 0x26a0, 0xc00f, 0xbefb, 0xbe3e, + 0xbef8, 0xbfc3, 0xbf6f, 0xbfdc, 0x3ee8, 0x3ff1, 0xbff5, 0xbfa3, + 0x3f82, 0x3f84, 0xc013, 0xbf94, 0xbd43, 0xa1c2, 0x21c3, 0xa857, + 0xbe7c, 0xbcfe, 0xbe09, 0xbe67, 0x5385, 0xd49e, 0x3cea, 0xbdda, + 0xbfe4, 0x3e0e, 0xc006, 0xbf87, 0xbdf6, 0xbf23, 0xbf7f, 0xbe26, + 0xbeb3, 0xbe19, 0xbecc, 0xbf64, 0x3f97, 0xc900, 0xbf32, 0x3e0b, + 0x3f80, 0x3f81, 0xbfc7, 0xbf04, 0xa1c5, 0xa1c9, 0xbfb1, 0xbe7d, + 0xc5f3, 0xa1c4, 0x3cea, 0xbd99, 0xbe0c, 0x21c0, 0xbd44, 0xbca6, + 0x2a6c, 0xbedb, 0xbe7b, 0x26e6, 0x3e0a, 0xbe15, 0xbd9e, 0xbe05, + 0xbd45, 0xbc97, 0xbdf8, 0xbe34, 0x3d4e, 0xbfdf, 0xbd89, 0x26e6, + 0x3df5, 0xbe15, 0x3b6e, 0x3da9, 0x3f80, 0xbf81, 0xbde5, 0xbf2c, + 0x3d9c, 0xc006, 0xbf38, 0xbfa0, 0x2d60, 0x3eaa, 0x5c3f, 0xdc40, + 0xbf01, 0x26e6, 0x3df5, 0xbe0a, 0xc00b, 0xbef2, 0xbda3, 0xa1cf, + 0xbca8, 0xbda1, 0xbeab, 0xbd4b, 0xbe07, 0x6030, 0xe04a, 0xbd51, + 0xa1d1, 0xbd48, 0xbd8c, 0xbc64, 0xbdf3, 0xbd85, 0xbdc4, 0xc063, + 0x3ebc, 0xbfd5, 0x3ee1, 0xbeff, 0xbfda, 0xa24c, 0xbf70, 0xbffa, + 0xbf0a, 0xbf11, 0x3cfc, 0x3f51, 0xc67a, 0xa3b5, 0x3fdb, 0xd499, + 0x21c6, 0xa1d6, 0xbf91, 0xbc9f, 0x2d60, 0x3e13, 0x5c3f, 0xdc40, + 0xbe29, 0xbd49, 0x3cdd, 0xe061, 0xbda2, 0x4194, 0xe394, 0x3e7f, + 0xbfd5, 0xbca7, 0xc06d, 0xbda4, 0xd365, 0xbf77, 0x232f, 0xbc47, + 0xbefe, 0xbdeb, 0x3cf7, 0xc027, 0xbeef, 0x404e, 0x4054, 0xc067, + 0xc044, 0x3e80, 0xbeff, 0xc005, 0xbffe, 0xbfeb, 0xc064, 0x3d5c, + 0x3ff1, 0xbff5, 0xc058, 0xbfa6, 0x3caa, 0xcc04, 0xbede, 0xbe17, + 0x2364, 0x3f9b, 0xc002, 0x3c7b, 0xbd52, 0xbd50, 0xbeda, 0x3e80, + 0xbee1, 0xbe14, 0xbdaf, 0xb87c, 0xbe87, 0xbe89, 0xc055, 0xbca4, + 0xbc49, 0xbd9f, 0x1e79, 0x1e7e, 0x9e81, 0xc1b3, 0xbe0d, 0xbf44, + 0xbda8, 0xbe10, 0xbd46, 0xe88d, 0xbf31, 0xc04c, 0xc020, 0xc01f, + 0xc032, 0xbff0, 0x3cfc, 0x3e8c, 0xc67a, 0x3d01, 0xbd2f, 0xbca9, + 0x3f5c, 0xbff3, 0x3f5b, 0xbff3, 0xbda6, 0xbd54, 0xbe83, 0xc026, + 0xbed7, 0xbda0, 0x3b6e, 0x3da9, 0x3e0b, 0xbf81, 0x3b6e, 0x3da9, + 0x3e0b, 0xbf80, 0x3d67, 0x3f84, 0xc013, 0x3d67, 0x3f82, 0xc013, + 0xbd47, 0xbd9d, 0xbe9c, 0xbd69, 0xbda7, 0xbfb3, 0x2364, 0x3ef7, + 0xc002, 0xc03e, 0x21db, 0xa1dc, 0xbe11, 0xbd63, 0x3ca2, 0xbcfd, + 0xbeea, 0xbcf6, 0xbd4d, 0xc032, 0xbdc0, 0xbf9a, 0xbd4a, 0xbd53, + 0xbda9, 0x4028, 0xc02c, 0xc015, 0xbcb5, 0x3e7f, 0xbebc, 0xbcde, + 0x3e81, 0xc02f, 0x3e95, 0xd499, 0xbd55, 0x3d4e, 0xbe08, 0xbd9b, + 0xbee5, 0xbf4d, 0x3d5c, 0x3ee8, 0xbff5, 0x3f5b, 0xbf5c, 0x3d5c, + 0x3ee8, 0xbff1, 0x65ca, 0xe614, 0xbe85, 0xbcfa, 0xbee4, 0x2364, + 0x3ef7, 0xbf9b, 0xbee2, 0x3d9c, 0xbe0e, 0xbcfb, 0x3c88, 0xbe16, + 0xbd4f, 0x3d67, 0x3f82, 0xbf84, 0xbfd2, 0xbcf8, 0xbca5, 0xbf47, + 0xbf46, 0xbf74, 0x3cf7, 0xbedd, 0x3fd1, 0xc02c, 0x3fd1, 0xc028, + 0xbfda, 0xaf25, 0x3f4b, 0xbfb0, 0xbf9c, 0xbca3, 0xbee0, 0x1f71, + 0xbcd5, 0xbf45, 0x3edf, 0xc054, 0xc05d, 0xbd12, 0x3edf, 0xc04e, + 0xbf13, 0xbee9, 0xc04f, 0xbe7e, 0xbee6, 0xbedf, 0xbec5, 0x2149, + 0xc097, 0xc1c8, 0x670a, 0x671b, 0xe748, 0x4ac3, 0xcac8, 0x40fe, + 0xdd64, 0x407e, 0xc0d6, 0x407d, 0xc0d6, 0xc1e6, 0xc16c, 0x3c14, + 0x3c17, 0xbc23, 0x4210, 0x6229, 0xe46a, 0x23cd, 0xa3db, 0xc08f, + 0xc08e, 0x2149, 0xc06e, 0xc152, 0xc197, 0x362d, 0x36cc, 0x4167, + 0x41f3, 0xc7be, 0x4832, 0x491f, 0xc92e, 0xc0f1, 0xcf39, 0xeede, + 0x1e3a, 0xc232, 0x4149, 0x632c, 0xe34a, 0xc1be, 0xc20d, 0x41d7, + 0x421b, 0xc224, 0xc0f4, 0xc16c, 0x9e4c, 0x407d, 0xc07e, 0xc1ed, + 0xc159, 0xc169, 0x413c, 0xc1d2, 0x41c1, 0xc217, 0xc1f4, 0xc1d9, + 0xc1fc, 0xc1b1, 0xc0af, 0xc0c3, 0xc1a2, 0x407b, 0xdd64, 0xe2b7, + 0x21de, 0x4155, 0x4188, 0xc199, 0xe2b2, 0x9e9f, 0x4130, 0xc1c4, + 0xc165, 0xc1dc, 0xc1fe, 0x41cc, 0xc1d3, 0xb5e0, 0xc133, 0xc162, + 0x4114, 0xc1c4, 0xc126, 0x40e7, 0xc1d2, 0xe35b, 0x40bc, 0x632c, + 0xe34a, 0xc16e, 0xc09c, 0x21de, 0x4108, 0x4188, 0xc199, 0xb696, + 0xb696, 0xc0df, 0x412d, 0xd315, 0xc115, 0x36cc, 0x40a4, 0x41f3, + 0xc7be, 0xc0e6, 0x4080, 0xc0ca, 0xc151, 0x417e, 0xc185, 0x4174, + 0xc185, 0x4174, 0xc17e, 0x21de, 0x4108, 0x4155, 0xc199, 0xc1fb, + 0xd367, 0x3eb6, 0xe394, 0xc09d, 0x21de, 0x4108, 0x4155, 0xc188, + 0xc0fd, 0xc0ed, 0xe88e, 0xbf2b, 0xc1ba, 0xc1b9, 0xc0bd, 0x40e8, + 0xc217, 0x4114, 0xc130, 0xc06f, 0x411a, 0xc1d3, 0xac1e, 0x48f7, + 0xcca6, 0x40e7, 0xc13c, 0x411a, 0xc1cc, 0xedf0, 0x40c2, 0x421b, + 0xc224, 0xc0eb, 0xc116, 0x25b6, 0xd425, 0xc07f, 0xbbc1, 0xc0db, + 0x36cc, 0x40a4, 0x4167, 0xc7be, 0xc0e9, 0xc18f, 0xc0ec, 0xc118, + 0xd000, 0xc0c1, 0xc089, 0x40e8, 0xc1c1, 0x40c2, 0x41d7, 0xc224, + 0x40c2, 0x41d7, 0xc21b, 0x9e89, 0xb11b, 0x1e3a, 0xc0ba, 0xb52b, + 0xc23a, 0xc237, 0x9fce, 0x2c12, 0x2c13, 0xac14, 0x9e2c, 0xae8a, + 0xb96a, 0xa889, 0xa899, 0xcb3a, 0xc258, 0x4255, 0x4a93, 0x4a97, + 0xcabb, 0xb99c, 0x424e, 0x4a93, 0x4a97, 0xcabb, 0xc24d, 0xc25c, + 0xc25b, 0xab83, 0x3c02, 0xc29b, 0x1f10, 0xa0a0, 0xb2b5, 0xc27d, + 0x42a0, 0xc2a7, 0xc275, 0xc282, 0xc281, 0xa954, 0xc2a2, 0xd366, + 0x3c02, 0xc266, 0x427a, 0xc2a7, 0xc28a, 0x427a, 0xc2a0, 0xc2ad, + 0xc2ac, 0xa3d0, 0xdc7a, 0x5c7b, 0xdc8b, 0xc2c0, 0xc377, 0xc341, + 0xc336, 0xc2b6, 0x2448, 0xb282, 0xc2fd, 0xdc7e, 0xc329, 0xc36e, + 0xc370, 0xdc89, 0xaf87, 0xc368, 0xc2f9, 0xc345, 0xc36a, 0xc319, + 0xc344, 0xc33b, 0x430d, 0xdc8d, 0xc2ed, 0xc2c8, 0xc318, 0xb08d, + 0xc36b, 0xd653, 0xdc8e, 0x42f8, 0xdc8d, 0x431f, 0xc375, 0xc37c, + 0xc2fe, 0xc2f0, 0x430e, 0xc375, 0xc380, 0xc33f, 0xc2cc, 0xdc6c, + 0xdc93, 0xd75f, 0xc37b, 0xdc92, 0xc366, 0xc371, 0xc2b9, 0xc2f2, + 0x4328, 0xd76f, 0xc2b8, 0xc2f1, 0xc2ee, 0xe3e1, 0x2956, 0x2968, + 0xa96c, 0xdc98, 0xee9e, 0xc359, 0xc358, 0x217d, 0xc378, 0xc332, + 0xc2ec, 0xc2ef, 0x4303, 0xc381, 0xc37a, 0xc2dd, 0xc2de, 0xc335, + 0xd3b7, 0x430e, 0xc31f, 0xc2b7, 0x217d, 0xc363, 0xc36d, 0xc32e, + 0xc315, 0xdc9b, 0xc321, 0xc36b, 0x583c, 0xdc9c, 0xa999, 0xa35b, + 0xc4a3, 0xc4b5, 0xc452, 0xc46a, 0x43cf, 0xc474, 0xcfeb, 0xc44b, + 0xc4b0, 0xc3fe, 0xc472, 0xc447, 0xc4bd, 0x4409, 0x4460, 0xc4a2, + 0xc3ce, 0xc3cd, 0x43a8, 0xc474, 0xc43a, 0xc4cf, 0x4434, 0xc439, + 0x2b9d, 0x2bda, 0x2bf3, 0xabf6, 0xa72d, 0xc4ab, 0x448e, 0xc4d4, + 0xc43f, 0xc894, 0xc3b0, 0xbbec, 0xc46f, 0x43cb, 0x4460, 0xc4a2, + 0x4483, 0xc4c8, 0xc4a1, 0xc489, 0x4411, 0xc463, 0x4410, 0xc463, + 0xe6d5, 0x43e1, 0xc439, 0x43e1, 0xc434, 0xc3d0, 0xc4ca, 0xc3f2, + 0xc3b3, 0xc3ae, 0xc39a, 0xc8af, 0x43cb, 0x4409, 0xc4a2, 0x4410, + 0xc411, 0xc476, 0xc4a1, 0xd3b9, 0xc39b, 0xc405, 0xc4cc, 0xc3b1, + 0x43a8, 0xc3cf, 0xc464, 0xc4a6, 0xc4b8, 0x440d, 0xc4c8, 0xc4bf, + 0xc40f, 0x43f1, 0xc4d4, 0x440e, 0xc468, 0x43cb, 0x4409, 0xc460, + 0xc391, 0xc477, 0xc3f0, 0xc3af, 0xc399, 0xc478, 0x28d0, 0xc3ba, + 0xc487, 0x440d, 0xc483, 0xc4da, 0xc43c, 0xc470, 0xc3d1, 0xc4da, + 0x43f1, 0xc48e, 0x44c9, 0xc4d2, 0xaf01, 0xcf38, 0xc515, 0xc50c, + 0x4501, 0xcf3e, 0xc506, 0x44f6, 0xcf3e, 0xc4f7, 0xc4ef, 0x287c, + 0x4816, 0xc8da, 0xc4ee, 0x4f42, 0xcf4c, 0x2617, 0x2690, 0xac1d, + 0xb674, 0x1ea7, 0xc523, 0x1ea7, 0xc522, 0x4a4c, 0x52cf, 0xd607, + 0x2b81, 0x2bcd, 0x2bd5, 0x2bd7, 0x2bdc, 0xabe7, 0xe6fb, 0x9fbd, + 0x2722, 0xc53c, 0x2212, 0x2283, 0x2290, 0x456b, 0xc575, 0x2722, + 0xc53a, 0xc54e, 0xc55d, 0x4559, 0xc571, 0xb6a2, 0x1ea9, 0x4552, + 0x455d, 0xc55e, 0xd015, 0x283a, 0xc54d, 0x283a, 0xc54c, 0xc53d, + 0xc560, 0x1ea9, 0x4546, 0x455d, 0xc55e, 0x4544, 0xc571, 0xa959, + 0x1ea9, 0x4542, 0x4546, 0x4552, 0xc55e, 0x1ea9, 0x4546, 0x4552, + 0xc55d, 0xc551, 0xa793, 0xbbd5, 0xc567, 0xc565, 0xc56a, 0xc568, + 0x453b, 0xc575, 0xaf02, 0x4544, 0xc559, 0x23e0, 0x4582, 0x4589, + 0xc58a, 0xc587, 0x453b, 0xc56b, 0xaf53, 0xc585, 0xa84d, 0x23e0, + 0x4573, 0x4589, 0xc58a, 0x457a, 0xc586, 0xc585, 0xc574, 0x23e0, + 0x4573, 0x4582, 0xc58a, 0x23e0, 0x4573, 0x4582, 0xc589, 0x458f, + 0xde08, 0x458e, 0xde08, 0xc664, 0xc642, 0xc627, 0xc658, 0xc60d, + 0xd0ac, 0xc667, 0xc632, 0xc621, 0xc60b, 0x46b0, 0xe764, 0xc5fe, + 0xc665, 0xc670, 0xc5d9, 0xc662, 0x24d1, 0x2516, 0x255e, 0xc602, + 0xc5c9, 0xc646, 0xc626, 0xc613, 0xc647, 0xd139, 0x45f3, 0xeebb, + 0x3dcb, 0x45f2, 0xeebb, 0xc661, 0xc5fa, 0xc5f9, 0xc5b4, 0x24d1, + 0x2516, 0x255e, 0xc5d6, 0xc649, 0xc62e, 0x3108, 0xc652, 0xc5af, + 0xc5a1, 0xc5ea, 0xa591, 0xc61e, 0xc63b, 0xc617, 0xc5ae, 0xc645, + 0xc5e9, 0xc59f, 0xc65f, 0xc671, 0xc606, 0xc5ad, 0xc63b, 0x4618, + 0xc63a, 0xc66e, 0xc66d, 0xc597, 0x2af6, 0xb194, 0xc624, 0xc5e8, + 0xc5eb, 0xc605, 0x3108, 0xc609, 0x4670, 0xd1c3, 0xc5a0, 0xc669, + 0xc62a, 0xc5f4, 0xc5d2, 0xc66c, 0xc596, 0xc5c7, 0xc5ac, 0xc65e, + 0xc672, 0xc663, 0xc63f, 0xc63e, 0xd1de, 0x45c8, 0x4655, 0xd1c3, + 0xc62b, 0xc66b, 0xc675, 0xc674, 0x23d1, 0x32e8, 0x34a5, 0x3cfc, + 0x3e8c, 0x3f51, 0x467c, 0x6166, 0x6197, 0xe1b1, 0xa0dc, 0x23d1, + 0xc67a, 0x388d, 0xc682, 0x388d, 0xc681, 0xdc8c, 0x2e30, 0x2f52, + 0xbb78, 0xc690, 0x2373, 0xa37d, 0xdccb, 0xc68b, 0xc69a, 0x21d2, + 0xc691, 0xc6a1, 0xc69e, 0x36a4, 0xb6ad, 0xb61f, 0x45b1, 0xe764, + 0xc6ba, 0x46b8, 0xc6b9, 0xef13, 0x46b2, 0xc6b9, 0x46b2, 0xc6b8, + 0xc6b1, 0xef13, 0xc6c8, 0x376f, 0xb86e, 0xc6cd, 0xc6c1, 0x4f3d, + 0x6262, 0xe4b5, 0xc897, 0xc6c7, 0xc6de, 0x2869, 0xee7d, 0x46e3, + 0xdb7c, 0x5462, 0xd4cb, 0xc6dc, 0xc6e4, 0xcc20, 0xc6d7, 0xc6cf, + 0xac3d, 0x46d1, 0xdb7c, 0xc6d8, 0xa362, 0x5361, 0xd62f, 0x1eff, + 0xa023, 0xc742, 0x23bf, 0xce23, 0xc798, 0x5996, 0xd9c6, 0xb14e, + 0xc71f, 0xc71e, 0xc726, 0xc725, 0xc72f, 0xc7d3, 0x472b, 0xc787, + 0xc760, 0x1e51, 0x1f17, 0xd846, 0xd457, 0xc75c, 0xc709, 0xa6f0, + 0xc75e, 0xc7bc, 0xc741, 0xc750, 0xc737, 0xc765, 0xc764, 0xd9a9, + 0x23e1, 0xa8e1, 0xc7c1, 0xc7b6, 0xc72f, 0xc79e, 0xcff3, 0xc70d, + 0xc792, 0xc7aa, 0xc7d2, 0xc7da, 0xc7a0, 0x1e86, 0xb6b8, 0xc7d9, + 0xc786, 0xc751, 0x36cc, 0x40a4, 0x4167, 0xc1f3, 0xc785, 0xd499, + 0xc7a2, 0xc72c, 0xc7b0, 0xc7a9, 0xcb36, 0x47e7, 0xda20, 0x9faf, + 0x47e4, 0xda20, 0xc7ef, 0xc7eb, 0x3917, 0x4887, 0xc8f8, 0xc8ef, + 0xc92c, 0x483f, 0x4926, 0x6271, 0x62db, 0xe45b, 0xc8ad, 0xc8bc, + 0xc8c7, 0xc88e, 0x287c, 0x450e, 0xc8da, 0xc868, 0xc86f, 0xc8b8, + 0xa38e, 0xc8aa, 0xc8d6, 0x40ae, 0x491f, 0xc92e, 0xc92a, 0xc931, + 0xc92b, 0x47ff, 0x4926, 0x6271, 0x62db, 0xe45b, 0xc90e, 0xc85c, + 0xb731, 0xc8a9, 0xc864, 0xc8fd, 0xc8d1, 0xc904, 0xc841, 0xc856, + 0xc817, 0xc912, 0x27c6, 0x48ba, 0xc8bb, 0xc81a, 0xc8e0, 0x6e78, + 0x6e7b, 0xee7c, 0x38ca, 0x38cb, 0x3ab1, 0xbac0, 0x3917, 0xc7f4, + 0xc919, 0xc815, 0xc3f7, 0x27fc, 0x2d0e, 0xad5c, 0x27e6, 0x3900, + 0xc6cc, 0xc8e7, 0xc8e3, 0x2ca9, 0x2d52, 0xad53, 0xe7a8, 0xc855, + 0xc827, 0xc800, 0xc459, 0x33bd, 0xde2b, 0x6e78, 0xee7c, 0xc81c, + 0x486e, 0xc8bb, 0x486e, 0xc8ba, 0xc801, 0xc920, 0xc812, 0xc859, + 0xe695, 0xa387, 0xc82c, 0x287c, 0x450e, 0xc816, 0xc875, 0xc89c, + 0xc89b, 0xc7f6, 0xc1d0, 0xc7f4, 0xeec4, 0xc857, 0xbda7, 0xc85a, + 0x6669, 0x667a, 0xe6aa, 0x2760, 0xa89c, 0xc840, 0xc86a, 0xc88d, + 0x40ae, 0x4832, 0xc92e, 0xc8c1, 0x47ff, 0x483f, 0x6271, 0x62db, + 0xe45b, 0xc83a, 0xc83e, 0xc7fe, 0x40ae, 0x4832, 0xc91f, 0xc83b, + 0xc93b, 0xc93a, 0xc9ae, 0xc9b4, 0xc9a9, 0xc9a1, 0xa996, 0xc995, + 0xc9d8, 0xc9b0, 0xc98e, 0xb346, 0xc9b1, 0xc98d, 0xc984, 0xca1f, + 0xc97f, 0xc9aa, 0xc978, 0xc96f, 0xc94e, 0xc943, 0xafa1, 0xc940, + 0xc985, 0xc93c, 0xc962, 0xc977, 0xc93f, 0xe6e2, 0xc9c3, 0xa3b6, + 0xc9bf, 0xca08, 0x527a, 0x52b8, 0x541f, 0x54fa, 0xd5dd, 0xcc7c, + 0xae74, 0x49cc, 0x4a50, 0x67a6, 0x67a7, 0xef9d, 0x49cb, 0x4a50, + 0xef9d, 0xca2e, 0xd018, 0x4a09, 0xccb3, 0xcc83, 0xa3ea, 0xe8eb, + 0xc955, 0xca4d, 0x4a31, 0xca6a, 0xca2d, 0xca62, 0xca60, 0x4a3e, + 0x4a3f, 0x55c1, 0xd5f3, 0xca0e, 0x4a5e, 0xca6d, 0xc9c6, 0x49d4, + 0xccb3, 0xca05, 0x4cba, 0xd5ad, 0x4a3a, 0xca49, 0xb8f1, 0xc980, + 0xca4c, 0xc9f8, 0xc9cd, 0x49f0, 0xca6a, 0xca3b, 0x4a4f, 0xca69, + 0x4a1a, 0xca49, 0xca32, 0x4a01, 0x4a3f, 0x55c1, 0xd5f3, 0x4a01, + 0x4a3e, 0x55c1, 0xd5f3, 0x4cd3, 0xdc37, 0xca57, 0x4c87, 0xcce0, + 0x4a1a, 0xca3a, 0x4526, 0x4a23, 0x52cf, 0xd607, 0xc9ef, 0x6834, + 0xe896, 0x4a33, 0xca69, 0x49cb, 0x49cc, 0xef9d, 0xca61, 0xca42, + 0x4a06, 0xca6d, 0xc9fe, 0xca51, 0xc9fd, 0xca70, 0x6839, 0x683a, + 0x683d, 0xe893, 0x4a33, 0xca4f, 0x49f0, 0xca31, 0xd3b7, 0x4a06, + 0xca5e, 0xca63, 0x4aae, 0xcac6, 0xab86, 0xe631, 0xab8a, 0xcaca, + 0xcab3, 0xcac5, 0xcab5, 0x4aaf, 0xcab0, 0x424e, 0x4255, 0x4a97, + 0xcabb, 0x424e, 0x4255, 0x4a93, 0xcabb, 0xcac4, 0xcaa9, 0xcaba, + 0xcac7, 0xca9d, 0xbd3c, 0xde30, 0x2be0, 0xcab6, 0x4a77, 0xcac6, + 0x4a91, 0xcab0, 0x4a91, 0xcaaf, 0xca8a, 0xca8e, 0x2be0, 0xcaad, + 0xcaa5, 0x424e, 0x4255, 0x4a93, 0xca97, 0x4076, 0xcac8, 0xca9c, + 0xca8d, 0x4a77, 0xcaae, 0xcaa6, 0x4076, 0xcac3, 0xca83, 0xa947, + 0x4aea, 0xdc4e, 0x9f2b, 0x6f8d, 0xef92, 0x1e26, 0x20a1, 0xae76, + 0x4af6, 0xcaf8, 0x9fdf, 0x5abc, 0xdc0a, 0x4ad6, 0xdc4e, 0x4ade, + 0xcaf8, 0x4ade, 0xcaf6, 0xcbea, 0xcbe4, 0x4b4d, 0xcbb0, 0x2173, + 0xa4b2, 0xcb46, 0xcb67, 0xcb8d, 0x218a, 0x218c, 0x3547, 0x4b56, + 0x4b5e, 0xcba3, 0x9f53, 0x4bc4, 0xd303, 0xc7e2, 0x424b, 0xcb8b, + 0x4bed, 0xcc60, 0xcc69, 0xcbb2, 0xcb14, 0xd9d4, 0x4b0b, 0xcbb0, + 0x3830, 0xba43, 0xcb7a, 0xcbc9, 0x3547, 0x4b27, 0x4b5e, 0xcba3, + 0xcc06, 0xcb82, 0xcbf3, 0xcbe9, 0xcc39, 0xcb8f, 0x3547, 0x4b27, + 0x4b56, 0xcba3, 0xcb15, 0xcbe0, 0xcc4c, 0xcb50, 0xcbd4, 0x4c3d, + 0x4c56, 0xcc64, 0xcbe0, 0xcc21, 0xcb59, 0xcbe6, 0x00f6, 0x1e2a, + 0xa00b, 0xcb3a, 0xcb1f, 0xcb5d, 0xae1a, 0xcc59, 0xa284, 0x3547, + 0x4b27, 0x4b56, 0xcb5e, 0x4c00, 0xd536, 0xcbcb, 0xcc5c, 0xcc6e, + 0xcc1e, 0xcc2b, 0xcbdb, 0x4b0b, 0xcb4d, 0xcb45, 0xd282, 0x4b35, + 0xd303, 0xd483, 0xcb51, 0x2327, 0xcba7, 0xad4c, 0xcc23, 0xcc0d, + 0xcb7c, 0xcc46, 0xcbac, 0x4b71, 0xcb7f, 0xcc12, 0xcb03, 0xcb86, + 0x4b5b, 0x4c01, 0xcc6d, 0xcafe, 0x4b3c, 0xcc60, 0xcc43, 0xcc5b, + 0xcc6c, 0xaf57, 0xcb5a, 0x4ba6, 0xd536, 0x4be9, 0xcc6d, 0x3caa, + 0xbeec, 0xcb58, 0xcbd3, 0x4c14, 0xd4d1, 0xcbe1, 0x4c11, 0xd4d1, + 0xcc6a, 0x3881, 0xba11, 0xcc2b, 0xcbaa, 0xc6d9, 0xcb80, 0xcbd1, + 0xa142, 0x4bab, 0xcc18, 0x35d7, 0xcc4f, 0xba90, 0xcb5c, 0xcb7e, + 0xae18, 0x4c52, 0xcc55, 0xcc5f, 0xcbee, 0xcbd7, 0xcb79, 0x35d7, + 0xcc31, 0xcc58, 0xcc40, 0x55ae, 0xd5ea, 0xcc40, 0x4b7e, 0xcc64, + 0x4c50, 0xd5e4, 0xcb93, 0xcbef, 0xcba8, 0xcc41, 0x4b3c, 0xcbed, + 0x4b7e, 0xcc56, 0xcb3e, 0xcc16, 0xcbf1, 0x4be9, 0xcc01, 0xcba9, + 0x2401, 0xefa5, 0xccf4, 0xe85e, 0xc9c8, 0xc9d5, 0x4a45, 0xcce0, + 0xccb9, 0xeea4, 0xeecf, 0x5083, 0xd085, 0xccf6, 0xccf2, 0xccb5, + 0x1ffc, 0xeb3b, 0xc1d0, 0x2986, 0x299d, 0x2a24, 0xccda, 0xccde, + 0x36f2, 0x6eaf, 0x6eb4, 0xeeb9, 0xcce7, 0x49d4, 0xca09, 0xcca4, + 0xcc8b, 0xca17, 0xccc9, 0xccdd, 0x6762, 0x6eaa, 0x6eab, 0x6eb5, + 0xeeba, 0xe931, 0xccbd, 0xe92c, 0x4a40, 0xdc37, 0xe93b, 0x2986, + 0x299d, 0x2a24, 0xcca7, 0xccc1, 0xccaa, 0x4a45, 0xcc87, 0xe94e, + 0xccae, 0x26e2, 0xa6e3, 0xcc9d, 0xcc74, 0xcc9c, 0x1e1d, 0x4cf9, + 0x4d72, 0xce9f, 0x4cf8, 0xce9f, 0xccfe, 0x1fc2, 0x4e18, 0x4e4b, + 0xce6b, 0x229f, 0xccff, 0x4cfa, 0xcea0, 0x229f, 0xccfc, 0xceaa, + 0xcea3, 0xcea6, 0xcea2, 0xcea1, 0xcea5, 0xcea8, 0xceab, 0xceb9, + 0xceb3, 0xcebd, 0xcebe, 0xceaf, 0xceb0, 0xcebc, 0xceb1, 0x4d8b, + 0xceae, 0x2e0b, 0xceb8, 0xcea7, 0xceb7, 0xcead, 0x4d4d, 0xceb4, + 0xceba, 0xcdb7, 0xcd2e, 0xcdca, 0x4da2, 0xcef8, 0x324e, 0xcd25, + 0x4e32, 0x4e8d, 0x4e9d, 0xcf27, 0xcec6, 0xcec2, 0xcec1, 0xcec5, + 0xcebb, 0xcecd, 0xcec0, 0xcecb, 0xced0, 0xcecc, 0xcec8, 0xaf26, + 0xcec4, 0xcd97, 0x4eca, 0xe77d, 0xae15, 0xcea9, 0x4d93, 0xcecf, + 0xcd1d, 0xced7, 0xcec1, 0xced3, 0x34a7, 0x4d76, 0xcedd, 0xce8a, + 0xcdea, 0x4e27, 0xcee6, 0x4ed4, 0xd8b4, 0xcede, 0xcedc, 0xceda, + 0x4dab, 0x4dda, 0x4ebf, 0xcf10, 0xd32f, 0xced9, 0xced2, 0xced6, + 0x4d82, 0xcedf, 0x1e1d, 0xccf8, 0xcedb, 0x4e6a, 0xced8, 0x34a7, + 0x4d55, 0xcedd, 0xce36, 0x4e6d, 0xd812, 0xcee2, 0xced1, 0x4d71, + 0xcedf, 0xcee1, 0xcee0, 0xcee8, 0xcee3, 0xcd18, 0xcee4, 0xcee5, + 0x3346, 0xb8b1, 0x4d4c, 0xcecf, 0xcd45, 0x4e7c, 0xcee7, 0x4e8c, + 0x4eed, 0xdce1, 0xcefc, 0xcf0d, 0x4dd1, 0xceff, 0x4d2c, 0xcef8, + 0xcefb, 0x4d64, 0x4dda, 0x4ebf, 0xcf10, 0xcef6, 0xcef4, 0xcef9, + 0xcefe, 0xceb2, 0xcf51, 0x4e43, 0xcef7, 0x23d5, 0xcf00, 0xaf69, + 0xcd23, 0xceb6, 0xcefa, 0xceee, 0xcefd, 0x4e5b, 0xcef0, 0xceeb, + 0xcef5, 0xcef2, 0xcf01, 0xcd27, 0xceef, 0xcde1, 0x303b, 0x3460, + 0x4deb, 0xce3d, 0xce41, 0x4da0, 0xceff, 0x4dd6, 0xceea, 0xcef1, + 0xce83, 0x4dd2, 0xceea, 0xcf03, 0xcf04, 0xcf02, 0x4d64, 0x4dab, + 0x4ebf, 0xcf10, 0xcef5, 0xcf09, 0xcf0e, 0xcf14, 0x4dcd, 0xcf17, + 0x4e01, 0xcf18, 0xd913, 0xcf0c, 0xcf16, 0xcf13, 0xcd5a, 0x303b, + 0x3460, 0x4dcf, 0xce3d, 0xcf05, 0xceac, 0xcf11, 0xcf08, 0xcec3, + 0xcf0f, 0xcf07, 0xd1f4, 0x4e15, 0xcf0a, 0x4de3, 0xcf18, 0x4e69, + 0xcef3, 0xd426, 0xcf19, 0xcf22, 0xcf12, 0xcec9, 0xcf23, 0x4dfc, + 0xcf0a, 0xcf1e, 0x4cfb, 0x4e4b, 0xce6b, 0xcf1a, 0xcf1c, 0xcf1f, + 0xcf1b, 0x23bf, 0xc70c, 0x4e31, 0xceb5, 0x4d5b, 0xcee6, 0xae4c, + 0xcf1d, 0xcf21, 0xcf29, 0x4e26, 0xceb5, 0x4d2f, 0x4e9d, 0xcf27, + 0xcea4, 0xcf26, 0x4d77, 0xe9bd, 0xcf15, 0xcf25, 0x303b, 0x3403, + 0x3460, 0x4dcf, 0xcdeb, 0xcee9, 0xcdd0, 0x4db3, 0xcef7, 0x4e70, + 0xcf2b, 0xcf2a, 0xce66, 0x4e8e, 0x4e96, 0xcea4, 0x4cfb, 0x4e18, + 0xce6b, 0x4e61, 0xcee3, 0xcf2f, 0xcec7, 0xcf2e, 0x1f1e, 0xa098, + 0xcffb, 0xcf2d, 0xcdbd, 0xced5, 0x4e4d, 0xcee3, 0xcf0b, 0xce82, + 0xce48, 0x4e04, 0xcef3, 0x4d75, 0xced8, 0x4cfb, 0x4e18, 0xce4b, + 0x4d78, 0x5327, 0xd812, 0x4f30, 0xe7c1, 0xcf33, 0x4e45, 0x4f2b, + 0xcf32, 0xcf34, 0xcece, 0x4d99, 0xcee7, 0xcf24, 0xcf31, 0xb9db, + 0xce64, 0xcdd5, 0xe8a3, 0xcf2c, 0x4e98, 0xcf35, 0x4d56, 0xcea9, + 0x4d9a, 0x4eed, 0xdce1, 0xcd2f, 0x4e4a, 0x4e96, 0xcea4, 0x4e92, + 0xcf20, 0x4e8f, 0xcf20, 0xcf28, 0xb24d, 0x4e4a, 0x4e8e, 0xcea4, + 0x4e89, 0xcf35, 0xcf06, 0x4d2f, 0x4e32, 0xcf27, 0x4cf8, 0xccf9, + 0xccfe, 0xcd06, 0xcd05, 0xcd02, 0x4e34, 0x4e4a, 0x4e8e, 0xce96, + 0xcd07, 0xcd04, 0xcd1a, 0xcd08, 0x4d4b, 0xce8a, 0xcd00, 0xcd09, + 0xcdef, 0xcd1c, 0xcd18, 0xcd14, 0xcd15, 0xcd17, 0xcdb1, 0xcd0d, + 0xcd1d, 0x4e26, 0xce31, 0xcdb8, 0xcd1b, 0xcd19, 0xcd0b, 0xcd21, + 0xcd35, 0xcd16, 0xcd10, 0xcd13, 0x4d64, 0x4dab, 0x4dda, 0xcf10, + 0xcd3a, 0x4d32, 0xcd4f, 0xcd31, 0xcdf4, 0xcd44, 0xcd33, 0xcd30, + 0xce54, 0xcd42, 0xce10, 0xcd46, 0xcd3c, 0xcd40, 0xcd39, 0xce79, + 0x4d4c, 0xcd93, 0xcd3f, 0xcd81, 0xcd68, 0xcd50, 0xcd5d, 0x4e5e, + 0xe076, 0xcd70, 0xcd4e, 0x4d75, 0xce6a, 0xcd66, 0xcd62, 0xcd73, + 0xcd61, 0x34a7, 0x4d55, 0xcd76, 0xcd5e, 0x4d71, 0xcd82, 0xcd86, + 0xcd83, 0xcd79, 0x4d89, 0x4e4d, 0xce61, 0xcd8c, 0xcd8f, 0x4d5b, + 0xce27, 0x4d99, 0xce7c, 0xcd88, 0xce3e, 0x4dd2, 0xcdd6, 0xcdbe, + 0x4d9a, 0xce8c, 0xcdba, 0xcdcb, 0xcdbd, 0xcdd4, 0xcdc4, 0x4e04, + 0xce69, 0xcdad, 0x4dbf, 0xcddc, 0xcdac, 0x4db3, 0xce43, 0x4d2c, + 0xcda2, 0xcdaf, 0xcdb9, 0xcda3, 0xcd9c, 0xcdbb, 0xcdb0, 0x4da0, + 0xcdd1, 0xcdb4, 0xcdc7, 0xcdd9, 0xcdd7, 0xcdd8, 0xcdec, 0xce9c, + 0xcdf9, 0xcdf2, 0xcddd, 0x4dfc, 0xce15, 0xce62, 0xcde6, 0xcd9e, + 0xcdde, 0xcdf6, 0x4d64, 0x4dab, 0x4dda, 0xcebf, 0xcdf1, 0xce0b, + 0xcde9, 0xcde0, 0xce37, 0xcde8, 0xcde1, 0x4de3, 0xce01, 0xce09, + 0xce1b, 0xce1f, 0xce1d, 0xce2b, 0xce17, 0xce1e, 0x4e8f, 0xce92, + 0xce2d, 0xce0a, 0xce11, 0xce7d, 0xce39, 0xce35, 0x4d2f, 0x4e32, + 0xce9d, 0xce93, 0xce2e, 0xce46, 0x4e45, 0xce70, 0xce88, 0xce5a, + 0xce55, 0xce52, 0x4e6e, 0xe7c1, 0xce7e, 0xce70, 0xce6f, 0xce73, + 0x4e89, 0xce98, 0x4f3b, 0x4f50, 0xe475, 0xa378, 0xc4e8, 0xc0b0, + 0x3b20, 0xcf3c, 0xcf36, 0x3b20, 0xcf3a, 0x46cb, 0x6262, 0xe4b5, + 0x44f6, 0xc501, 0x4516, 0xcf4c, 0xba3d, 0x275b, 0x28b0, 0x28b5, + 0x28dc, 0xcf4e, 0x4516, 0xcf42, 0x275b, 0x28b0, 0x28b5, 0x28dc, + 0xcf48, 0x4f36, 0xe475, 0x4db2, 0x4f52, 0xcf53, 0x4f51, 0xcf53, + 0x4f51, 0xcf52, 0x2570, 0x26c9, 0xcf85, 0x4f70, 0xcf78, 0xcf77, + 0x3683, 0xdfa0, 0x4f5a, 0xcf78, 0xcf86, 0x208c, 0x69e1, 0xea82, + 0xcf80, 0xcf62, 0x4f5a, 0xcf70, 0xcf76, 0x4f88, 0xd98a, 0x21aa, + 0xae42, 0xcf57, 0xcf74, 0x4f88, 0x5989, 0xd98a, 0x4f81, 0x4f87, + 0x5989, 0xd98a, 0xd288, 0xd288, 0xcf97, 0xcf91, 0xcf90, 0xcf8c, + 0xcfa5, 0xcfa8, 0xcfa4, 0xcfa3, 0xcf9f, 0xcfa1, 0x9e49, 0x217b, + 0xe90a, 0xcfb9, 0x4fb6, 0xd1bb, 0x4fb4, 0xd1bb, 0xcfae, 0x4fc5, + 0xcfe4, 0x4fc4, 0xcfe4, 0xcfe0, 0x9e60, 0xcff9, 0xcffd, 0xcfec, + 0xcfc6, 0x4fc4, 0xcfc5, 0xc3a9, 0xcfda, 0xcffa, 0xc796, 0xcfd8, + 0xcff1, 0x4e59, 0xe8dc, 0xcfd9, 0xc1ff, 0xb537, 0xd008, 0xd007, + 0xd00b, 0xd00a, 0xc54a, 0xc9d0, 0xb7b1, 0xe504, 0xd02e, 0xd5c9, + 0xd02c, 0x39c8, 0xe392, 0xd027, 0xd022, 0xbacc, 0xd073, 0xb065, + 0xd043, 0xdead, 0x504c, 0x5077, 0xdec4, 0xd076, 0xd03c, 0xd07e, + 0x5040, 0x5077, 0xdec4, 0xd079, 0x5068, 0xd06f, 0x2723, 0xa7a9, + 0xe5fb, 0x28fb, 0xaa7f, 0x5066, 0x506a, 0xd070, 0x5061, 0x506a, + 0xd070, 0x5054, 0xd06f, 0xd075, 0x5061, 0x5066, 0xd070, 0xd06f, + 0x2abf, 0xb127, 0xd06f, 0x5054, 0x5068, 0x506b, 0xd06e, 0x5061, + 0x5066, 0xd06a, 0xa8f0, 0xd038, 0x242c, 0xd07d, 0xd069, 0xd042, + 0x5040, 0x504c, 0xdec4, 0xd04d, 0x242c, 0xd074, 0xd04b, 0x4c9b, + 0xd085, 0x4c9b, 0xd083, 0xd088, 0xd087, 0xab8d, 0xd0af, 0x5178, + 0xd193, 0xd135, 0xd19a, 0xd0da, 0xc5a3, 0xeaaf, 0x508e, 0xd0bb, + 0xa3b7, 0x3bd3, 0xd8ac, 0xe91a, 0xd0af, 0xd14e, 0xd16b, 0xd139, + 0x5105, 0x5107, 0xd10b, 0x1f37, 0xa191, 0x51bb, 0xd1bd, 0xb3f9, + 0xd0a7, 0xa2dd, 0x585a, 0xeb0d, 0xb727, 0xd156, 0xd1da, 0x511b, + 0xde01, 0xd1d9, 0xd1a0, 0x5106, 0xd13a, 0x50c1, 0xd10b, 0x5103, + 0xd13a, 0xd0c1, 0xd109, 0xd108, 0x50c1, 0xd105, 0xd1be, 0x51d3, + 0x51df, 0xead2, 0xd1cd, 0x5133, 0xd166, 0xd1bf, 0xd1e0, 0xa43b, + 0x5173, 0xde0b, 0x50eb, 0xde01, 0xa507, 0x9fee, 0xd131, 0xd12b, + 0x2318, 0x5111, 0xd166, 0xd0a1, 0xd161, 0xd1c9, 0x45ee, 0xd0c0, + 0x5103, 0xd106, 0xd157, 0xa00e, 0x51c8, 0xd1d8, 0xe183, 0xd0be, + 0xd0e8, 0xd13e, 0xd195, 0xd1a3, 0xd136, 0x2318, 0x5111, 0xd133, + 0xd0bf, 0xef76, 0xe84b, 0x511a, 0xde0b, 0x50a0, 0xd193, 0xd1a9, + 0xd183, 0xea30, 0xeac8, 0xd190, 0xd17d, 0xd182, 0xd1cf, 0x50a0, + 0xd178, 0xd158, 0xd0a4, 0xd0f6, 0xd15f, 0xecd5, 0xd17b, 0xe94d, + 0x6ac4, 0xead3, 0x4fb4, 0x4fb6, 0x50c6, 0xd1bd, 0x50c6, 0xd1bb, + 0xd10d, 0xd113, 0xd1cb, 0x4655, 0xc670, 0x514a, 0xd1d8, 0xd138, + 0xd1c0, 0xd110, 0x5191, 0xead5, 0x510f, 0xd1df, 0x514a, 0xd1c8, + 0xd0ed, 0xd0ea, 0xd1e2, 0xc66f, 0x510f, 0xd1d3, 0xd114, 0xd1dc, + 0xa367, 0x9e34, 0xd1f0, 0xd1ed, 0xcdfb, 0x23f0, 0xa76e, 0xdf3f, + 0x9e0e, 0xa174, 0x1e3e, 0x3319, 0xb4e7, 0xb5e7, 0x3368, 0xd20e, + 0xd20d, 0xd213, 0xd210, 0x5217, 0x62ea, 0xe4fa, 0x5216, 0x62ea, + 0xe4fa, 0xe928, 0xd264, 0xd239, 0x523b, 0xd26b, 0xd266, 0xd259, + 0xb7c1, 0xd24a, 0xd229, 0x522e, 0xd26b, 0xd236, 0xd231, 0xba2f, + 0x3a79, 0xd26a, 0xd223, 0xd230, 0x3a79, 0xd263, 0x522e, 0xd23b, + 0xd271, 0x26cf, 0xd270, 0x5276, 0x5277, 0x5c53, 0xdc54, 0x5273, + 0x5277, 0x5c53, 0xdc54, 0x5273, 0x5276, 0x5c53, 0xdc54, 0xd279, + 0xd278, 0x49c7, 0x52b8, 0x541f, 0x54fa, 0xd5dd, 0xcbc0, 0x4f8a, + 0xcf8b, 0xd28c, 0xd28b, 0xa349, 0xd58c, 0xd56a, 0xd606, 0xd2b2, + 0xd2b1, 0x49c7, 0x527a, 0x541f, 0x54b7, 0x54fa, 0x5553, 0xd5dd, + 0xa20d, 0xd4ef, 0x1e42, 0xa208, 0xd466, 0xd5f6, 0xd3a7, 0xd407, + 0xd4bc, 0xd2e7, 0x26cc, 0x4526, 0x4a4c, 0x5607, 0xd613, 0xd351, + 0xd2e2, 0xd2e1, 0xd2ce, 0xa040, 0x55b2, 0xd60b, 0xd393, 0xd3f0, + 0x4b35, 0xcbc4, 0x2179, 0xd332, 0xd396, 0xd622, 0xd526, 0xa84b, + 0xc162, 0xd354, 0x4e6d, 0xd812, 0xcd65, 0xd438, 0x2179, 0xd30a, + 0xd34a, 0xd395, 0xd346, 0x1f9f, 0xd5a6, 0xd2d0, 0xd318, 0x2e84, + 0xd38a, 0xd598, 0xd3a2, 0xd558, 0xd4fd, 0xd434, 0xd54e, 0xd588, + 0x5415, 0xd5ba, 0x46ea, 0x5569, 0xd62f, 0x3804, 0xb9ae, 0xd477, + 0xbece, 0xc296, 0xc192, 0xd541, 0xd5ce, 0xd4c0, 0xd52d, 0xd552, + 0xd452, 0xd464, 0x546f, 0x55ac, 0xd5e5, 0xdc46, 0xb357, 0xd510, + 0x3d96, 0xd49e, 0x2e84, 0xd358, 0xd2fa, 0xd347, 0xd30e, 0xa50d, + 0xd35a, 0xd2cb, 0xd40a, 0xd4ee, 0xd494, 0xd435, 0xd3df, 0xd59f, + 0x4372, 0xca6b, 0xd555, 0xc469, 0x6d2c, 0x6daf, 0xee0e, 0x5493, + 0xd4f4, 0xd3be, 0xd3bd, 0xd458, 0xb79c, 0x235c, 0xd514, 0xd3b5, + 0xa807, 0x234e, 0x2d0b, 0xd550, 0xd2fd, 0xd506, 0x2eb5, 0x544a, + 0xd4ed, 0xd445, 0xd2cc, 0xd3b1, 0xd420, 0xd4f1, 0x5360, 0xd5ba, + 0xd600, 0xd63f, 0x49c7, 0x527a, 0x52b8, 0x54fa, 0xd5dd, 0xd40c, + 0x56cd, 0xd7a2, 0x25b6, 0xc1df, 0xce08, 0xd56d, 0xd5a9, 0x9e07, + 0x557f, 0x55fc, 0xd610, 0xd35d, 0xd3b4, 0xd330, 0xd55a, 0xd3f9, + 0xa3f6, 0x2eb5, 0x53f4, 0xd4ed, 0xd36d, 0xc740, 0xd3d1, 0xb939, + 0xd593, 0x46d6, 0xd4cb, 0xd36e, 0xd2c7, 0xd58a, 0xa85f, 0xb934, + 0xd36f, 0xd525, 0xd364, 0xd515, 0xcbc6, 0xd546, 0xd562, 0xd523, + 0xd51e, 0xb41c, 0x53bc, 0xd4f4, 0xd3b3, 0x31de, 0x3e95, 0x3fdb, + 0xc7c7, 0x3d96, 0xd385, 0xaf60, 0xd533, 0xd2b8, 0xd2cd, 0xd36a, + 0xae2d, 0x46d6, 0xd462, 0x4c11, 0xcc14, 0xd5cd, 0xd58a, 0xd63a, + 0xd577, 0xe3a3, 0xea40, 0x2eb5, 0x53f4, 0xd44a, 0xd3b2, 0xd2c1, + 0xd40d, 0x53bc, 0xd493, 0x49c7, 0x527a, 0x52b8, 0x541f, 0xd5dd, + 0xd35c, 0x298d, 0xa9f8, 0xd3f1, 0xd37b, 0xd84a, 0x235c, 0xd3d4, + 0xd482, 0xd48c, 0xd48b, 0xd471, 0xd311, 0xd36b, 0xd5bc, 0xd53b, + 0xd4a8, 0xeebb, 0x2328, 0xd5cf, 0x4ba6, 0xcc00, 0xd594, 0xd61e, + 0xd5fa, 0xd532, 0x55f9, 0xdb6a, 0xd368, 0xd487, 0x554b, 0xd602, + 0x554a, 0xd602, 0xd35e, 0x234e, 0xd3ef, 0xd36c, 0xd2b8, 0xd3b8, + 0xd35b, 0xd43c, 0xd489, 0xd361, 0xd29c, 0xd427, 0xd580, 0xd604, + 0x55f4, 0xd60a, 0xd4e3, 0x5431, 0x55fc, 0xd610, 0xd570, 0xd35f, + 0x546a, 0xd4df, 0xd297, 0xa9dc, 0xd460, 0xd537, 0x26ed, 0xa712, + 0xd359, 0xd3b6, 0x1f9f, 0xd350, 0xd428, 0x55b0, 0xd60d, 0x536f, + 0xd5e5, 0xca17, 0x4c54, 0xd5ea, 0xd5f7, 0x55ab, 0xd60d, 0x52f9, + 0xd60b, 0x5360, 0xd415, 0xd52f, 0x4a01, 0x4a3e, 0x4a3f, 0xd5f3, + 0x1e1b, 0x23e2, 0x3a37, 0xbb09, 0x201f, 0x2fa3, 0xd024, 0xd4dd, + 0xd369, 0x2328, 0xd535, 0xd61a, 0x49c7, 0x527a, 0x52b8, 0x541f, + 0xd4fa, 0x563d, 0xd646, 0xcc58, 0x536f, 0xd5ac, 0x4c54, 0xd5ae, + 0x4a01, 0x4a3e, 0x4a3f, 0xd5c1, 0x5574, 0xd60a, 0xd2c8, 0xd5af, + 0x553c, 0xdb6a, 0xd53a, 0x5431, 0x557f, 0xd610, 0xd41a, 0x554a, + 0xd54b, 0xd572, 0xd2a6, 0x4526, 0x4a4c, 0x52cf, 0xd613, 0x5574, + 0xd5f4, 0x52f9, 0xd5b2, 0x55ab, 0xd5b0, 0x6a65, 0xeaa5, 0x5431, + 0x557f, 0xd5fc, 0x52cf, 0xd607, 0xba97, 0xd5d3, 0xd539, 0xd30f, + 0xa170, 0x46ea, 0xd361, 0xd4e0, 0x55df, 0xd646, 0xd41d, 0xa914, + 0x55df, 0xd63d, 0x1e55, 0xd65d, 0xd65c, 0xb16e, 0xc307, 0x21e6, + 0xa904, 0xa47c, 0x565a, 0xd65b, 0x5657, 0xd65b, 0x5657, 0xd65a, + 0xd64f, 0x1e55, 0xd64e, 0xa3f7, 0xd666, 0xd665, 0x9e8f, 0x567a, + 0xd7f2, 0xd66f, 0xd7e3, 0xd66c, 0xd768, 0x2b83, 0xd6c7, 0xd66b, + 0xd771, 0xe6d6, 0xd766, 0xd806, 0xd755, 0xd7fb, 0xd79e, 0xd801, + 0x57a1, 0xd7c1, 0xd739, 0xd72f, 0x5745, 0x5836, 0xd83a, 0xd788, + 0xd6d4, 0xd814, 0xd6ba, 0xec8d, 0xd706, 0xd6d4, 0xd6a6, 0x2b83, + 0xd675, 0xd831, 0x5424, 0xd7a2, 0x5807, 0xd823, 0xd7f6, 0x5698, + 0x56b4, 0xd716, 0xef03, 0xd83b, 0xd7a7, 0xd7c4, 0xd6fa, 0xd7ef, + 0xd784, 0xd810, 0xd6f1, 0xd715, 0x5c9d, 0xdd1d, 0xd82d, 0xd6ac, + 0xd782, 0xd6fb, 0xd6d4, 0xd778, 0x574b, 0xd81f, 0xd68c, 0xd68b, + 0xeb4e, 0x5695, 0x5836, 0xd83a, 0x577f, 0xd805, 0xd7c8, 0xd7ec, + 0x5721, 0xd81f, 0xd80d, 0xd680, 0xc32c, 0xd815, 0xd67e, 0xd671, + 0xc33f, 0xd67b, 0xd717, 0xd7bb, 0xd811, 0x5747, 0xd805, 0xd7bf, + 0xd70b, 0xd6f3, 0xd696, 0xd78e, 0xd78d, 0xd7fb, 0x5827, 0xd839, + 0xd682, 0xd68a, 0x5424, 0xd6cd, 0x3594, 0xb59e, 0xd6ef, 0xd7ce, + 0xd77c, 0xd780, 0xd68a, 0xd6f0, 0xd7c7, 0xd7c6, 0xd748, 0xd7a8, + 0xd828, 0xd80e, 0xd66e, 0xd749, 0xd6f2, 0xd66b, 0xd6cf, 0xd821, + 0xd80f, 0x5681, 0xd798, 0xd683, 0x5747, 0xd77f, 0xd67f, 0x56ce, + 0xd823, 0xd74e, 0xd7d2, 0xd7f9, 0xd6f4, 0xd77e, 0x4d78, 0x4e6d, + 0xd327, 0xd69d, 0xd761, 0x5721, 0xd74b, 0xd7f8, 0xb0f7, 0x56ce, + 0xd807, 0x5799, 0xd839, 0xd7cf, 0xd702, 0xd6ca, 0x5695, 0x5745, + 0xd83a, 0x5799, 0xd827, 0x5695, 0x5745, 0xd836, 0xd6ee, 0x4383, + 0xdc9c, 0xd844, 0xd842, 0xe1c1, 0x1e51, 0x1f17, 0xc73e, 0x24af, + 0xa580, 0xd511, 0xb72f, 0x2563, 0x5858, 0xe29c, 0xa40c, 0xadf7, + 0x2563, 0x5854, 0xe29c, 0xd0e1, 0x236b, 0xd85e, 0x2675, 0x585f, + 0xe053, 0xa1b2, 0x236b, 0xd85b, 0x2675, 0x585c, 0xe053, 0xd864, + 0xd863, 0xd8dc, 0xe336, 0xd96f, 0xd89e, 0xa3ea, 0xd8b5, 0xd956, + 0x2acb, 0x2b1d, 0xd8ca, 0xd918, 0xae12, 0x596a, 0x67c8, 0xe7e4, + 0xd86e, 0x3bd3, 0xd0b2, 0xd972, 0xeef9, 0xd94f, 0x4d5d, 0xd8e4, + 0xd87d, 0xd8cc, 0xd8dd, 0xd960, 0xd90c, 0xd885, 0xd8b7, 0x58e1, + 0xe1cc, 0xd8e0, 0xd865, 0xd8c5, 0xd8d9, 0x58cf, 0xe1cc, 0xd933, + 0xd95d, 0x58b4, 0xd932, 0xd947, 0x5912, 0xd943, 0xb707, 0xd92b, + 0xd8f5, 0xd8f4, 0xa236, 0xa90d, 0xb0fc, 0xd8c8, 0xd90f, 0xd90e, + 0x58e6, 0xd943, 0xcde5, 0xd886, 0xd938, 0xd94c, 0xd8ed, 0xd8e4, + 0xd8e2, 0xd964, 0xd91b, 0x9eb5, 0x58e6, 0xd912, 0xd8e5, 0xd91d, + 0xb742, 0xd8af, 0xd974, 0xd884, 0xd8e3, 0xd8c6, 0xd934, 0xd89c, + 0xb446, 0xb4f7, 0xd86c, 0xd8ad, 0x5955, 0xd97d, 0xd974, 0x2364, + 0xa365, 0x290d, 0xafa9, 0xe738, 0xb838, 0x4f87, 0x4f88, 0xd98a, + 0x4f81, 0x4f87, 0x4f88, 0xd989, 0xd9c1, 0xaf01, 0xd9c3, 0xd9c4, + 0x599a, 0x59ba, 0xd9c9, 0x5994, 0xd9c5, 0x5993, 0xd9c5, 0x470e, + 0xd9c6, 0xd9c7, 0x5990, 0x59ba, 0xd9c9, 0xd9cb, 0xd9cd, 0xd9ce, + 0x59bd, 0xd9c8, 0xc779, 0x9eb2, 0xd9ca, 0xd9cf, 0xd9b7, 0xd9d0, + 0x59c0, 0xd9c2, 0xd9bc, 0x59b0, 0xd9d1, 0x358d, 0x5990, 0x599a, + 0xd9c9, 0xd9b6, 0x59a7, 0xd9c8, 0xd9cc, 0x59b3, 0xd9c2, 0xd98b, + 0x59b3, 0xd9c0, 0xd98e, 0xd98f, 0x5993, 0xd994, 0x470e, 0xd996, + 0xd998, 0x59a7, 0xd9bd, 0x5990, 0x599a, 0xd9ba, 0xd9ac, 0xd9a1, + 0xd9bf, 0xd9a5, 0xd9a6, 0xd9af, 0xd9b2, 0xd9b7, 0xcb4b, 0x59ef, + 0xd9f6, 0xb2b5, 0xd9f4, 0xd9e7, 0xd9f8, 0xd9e3, 0x59d7, 0xd9f6, + 0xd9de, 0x59d7, 0xd9ef, 0xd9e6, 0x59fd, 0xd9ff, 0x59f9, 0xd9ff, + 0x59f9, 0xd9fd, 0x5a01, 0xdba0, 0x5a00, 0xdba0, 0xdba2, 0xdba3, + 0xdba1, 0xdbaf, 0xdba7, 0xdba8, 0xdba6, 0xdbb1, 0xdbad, 0xdbaa, + 0xdbab, 0x3258, 0xdbac, 0xdbb0, 0xdabe, 0xdbb9, 0xdbb6, 0xdbbc, + 0x47e4, 0xc7e7, 0x241f, 0xa656, 0xbb23, 0xdbc0, 0xdbb7, 0xdbbb, + 0xdbbf, 0x9fe1, 0xdbbe, 0xdbb8, 0x5b6f, 0xdbd1, 0xdbc9, 0x24ec, + 0xdbc3, 0xdbca, 0xbce8, 0x5b49, 0xdbc1, 0xda6c, 0xdbc2, 0x2467, + 0xdbcb, 0x246a, 0xa492, 0xa46d, 0xdbb5, 0xdbc8, 0xdbd2, 0xdbcf, + 0xdbc4, 0xdbd0, 0xdbc7, 0xdbce, 0xdbc5, 0xdbcd, 0xdb8b, 0xa48f, + 0xdbe9, 0xdbe2, 0xdbe3, 0xdbd5, 0xabdf, 0xdbd7, 0xdbe7, 0x5a3d, + 0xdbdf, 0xdbe1, 0xdbe0, 0xdbd8, 0x5b6e, 0xdbdd, 0xdbe5, 0xdbe6, + 0xdbdc, 0xdbd9, 0xdbd6, 0xdbd4, 0xdbdb, 0xdbd3, 0xa938, 0xdb7d, + 0xdb04, 0xafd7, 0xdba4, 0xdbf3, 0xdbf6, 0xdbde, 0x3096, 0xb102, + 0x2500, 0xdbf1, 0xdbee, 0xdbed, 0xdbda, 0xdbeb, 0xdbec, 0xdbef, + 0xdbf0, 0xdbf5, 0xdbf2, 0x5aac, 0xdbf4, 0x5aaa, 0xdbf4, 0x5b80, + 0xdbfb, 0xa531, 0xdc01, 0xdbfe, 0xdc07, 0xdbfd, 0x4ae9, 0xdc0a, + 0xda1a, 0xdc03, 0xdc04, 0xdc06, 0xdc08, 0xdbff, 0xdbf7, 0x5aeb, + 0xdc0f, 0xdbe4, 0xdbf9, 0xdbfc, 0xdc05, 0xdbba, 0xdc02, 0xdc00, + 0xdc0d, 0xdc1e, 0xdc1d, 0x5afc, 0xdc16, 0x5b1a, 0xdc25, 0xdbe8, + 0x5b8d, 0xdc14, 0xdc1b, 0xdc10, 0xdb5c, 0x5acc, 0xdc0f, 0x242f, + 0x2518, 0x2553, 0x2554, 0x255f, 0xe5d9, 0xdc15, 0xdc18, 0xdbb3, + 0x3697, 0xdc19, 0xdc0c, 0x5bbd, 0xe8a8, 0xdbf8, 0xdc1a, 0x5ae0, + 0xdc16, 0xdbfa, 0xdc0b, 0xdc12, 0xdc13, 0xda8a, 0xdbcc, 0xdc0e, + 0xbb4c, 0xdc1c, 0xdc27, 0xdc11, 0xdc21, 0xdc24, 0xdc26, 0x5ae1, + 0xdc25, 0xdbb2, 0xdc22, 0x5b21, 0xdc23, 0x5b20, 0xdc23, 0xdc1f, + 0xa546, 0x5b81, 0xdc2a, 0xdc2c, 0x5b7e, 0xdc2b, 0xa5f9, 0xdbb4, + 0xdc28, 0x247c, 0xa611, 0xdc29, 0x24d7, 0xa629, 0x5a3c, 0xdbc1, + 0xdbb9, 0xdc32, 0xdba5, 0xa642, 0x5b5b, 0xdc2e, 0xdbc6, 0xdc2f, + 0xdc2d, 0x5b56, 0xdc2e, 0x5ae9, 0xdc31, 0xa66a, 0x553c, 0xd5f9, + 0x2661, 0xdc35, 0xbbc1, 0x5a71, 0xdbdd, 0x5a33, 0xdbd1, 0xdbae, + 0xa584, 0x5b93, 0xdba9, 0xdc34, 0xb2a4, 0xdbea, 0x46d1, 0xc6e3, + 0xda89, 0x5b2d, 0xdc2b, 0x5aad, 0xdbfb, 0x5b2b, 0xdc2a, 0x5b9a, + 0xdd5e, 0xdc09, 0x23d8, 0xa909, 0xda5f, 0x2bb4, 0xe1bc, 0x5ae4, + 0xdc14, 0x1ec7, 0x5b90, 0xe6e0, 0x5b8e, 0xe6e0, 0xdc17, 0x5b72, + 0xdba9, 0xdc30, 0xdc36, 0x5b83, 0xdd5e, 0xdc20, 0xdc33, 0x5a00, + 0xda01, 0xda08, 0xda02, 0xda03, 0xda8d, 0xdb4f, 0xda10, 0xda0c, + 0xda0e, 0x5b72, 0xdb93, 0xda15, 0xda16, 0x3258, 0xda17, 0xda13, + 0xdb70, 0xda0a, 0xda18, 0xda12, 0xdb1b, 0xdaf1, 0xdb33, 0xda4e, + 0xda1d, 0xda25, 0xda31, 0x5a1b, 0xdb4c, 0xdad6, 0xda29, 0xda1f, + 0x5af7, 0xe8a8, 0xda2d, 0xda2a, 0xda23, 0x5a3c, 0xdb49, 0xda41, + 0xda36, 0xda55, 0xda5b, 0xdb58, 0xda57, 0xda50, 0xda34, 0xda3a, + 0xda46, 0xdb05, 0xda5e, 0xda58, 0xda54, 0xda56, 0x5a33, 0xdb6f, + 0xda52, 0xda86, 0xda84, 0xda66, 0xda7f, 0xda69, 0xda70, 0xda7c, + 0xdaa0, 0xda85, 0xda75, 0x5a71, 0xdb6e, 0xda95, 0xda6c, 0xda6e, + 0xda6d, 0xda62, 0xda63, 0xdacd, 0xda72, 0xda73, 0xda6b, 0xdae2, + 0xda61, 0xdb78, 0xdaa1, 0xdaa3, 0xda9e, 0xda9a, 0x309e, 0xdaa4, + 0xdaa5, 0x2500, 0xda98, 0xdaa8, 0xda91, 0x5aaa, 0xdaac, 0xdaa6, + 0xda92, 0xdacb, 0xdaf8, 0xdacf, 0xdafe, 0x5aad, 0xdb80, 0xdad1, + 0xdab9, 0xdab2, 0xdac9, 0xdadb, 0xdab0, 0xdad7, 0xdabf, 0xdac2, + 0xdad2, 0xdac4, 0xdab6, 0xdac7, 0xdb85, 0x4ae9, 0xdabc, 0xdb00, + 0xdaf6, 0xdadc, 0xdb0a, 0x5acc, 0xdaeb, 0xdae7, 0xdb14, 0xdb01, + 0xdb02, 0x5ae4, 0xdb8d, 0xdaed, 0x5ae0, 0xdafc, 0xdb92, 0xdaee, + 0x3697, 0xdaf3, 0xdafa, 0xdae6, 0xdb0e, 0xdade, 0xdadd, 0xdb28, + 0xdb9c, 0xdb16, 0xdb1d, 0x5b20, 0xdb21, 0xdb17, 0x5ae1, 0xdb1a, + 0xdb19, 0xdb10, 0xdb39, 0xdb3e, 0x5b2b, 0xdb81, 0x5b2d, 0xdb7e, + 0xdb2c, 0xdb5a, 0x5b56, 0xdb5b, 0xdb59, 0xdb95, 0xdb5c, 0xdb4e, + 0xdb9e, 0xdb74, 0xdb6b, 0xdb96, 0x4a40, 0xccd3, 0xac88, 0x3e13, + 0x3eaa, 0xdc40, 0x3e13, 0x3eaa, 0xdc3f, 0xd373, 0xac82, 0x1e30, + 0x5c50, 0x673b, 0xe74a, 0x4ad6, 0xcaea, 0x1e30, 0x5c4a, 0x673b, + 0xe74a, 0x5273, 0x5276, 0x5277, 0xdc54, 0x5273, 0x5276, 0x5277, + 0xdc53, 0xdc5a, 0xdc58, 0xdc87, 0x9e88, 0xc32a, 0xdc76, 0xdc6e, + 0xc2b2, 0xc2b4, 0xdc94, 0xc2c9, 0xef26, 0xdc64, 0xc2e2, 0xc2b4, + 0xc683, 0x42f8, 0xc30d, 0xc30a, 0xc32f, 0xc32b, 0xdc7c, 0xc34f, + 0xc37e, 0x4383, 0xd83c, 0x56fd, 0xdd1d, 0xdd1e, 0x2458, 0x24e1, + 0xdd20, 0xdd1f, 0x321d, 0xdd22, 0xdd21, 0xdd2b, 0xdd27, 0xdd29, + 0xdd2a, 0xdd2f, 0xdd23, 0x2295, 0x5cea, 0xdd28, 0x2f10, 0x5cb3, + 0xdd30, 0xdd2e, 0xdd33, 0xdd40, 0x2f10, 0x5cae, 0xdd30, 0xdd35, + 0xdd2c, 0x9e70, 0xdd37, 0xdd36, 0xdd39, 0xdd34, 0xdd3b, 0xdd38, + 0xdd3a, 0xdd32, 0xdd42, 0xdd41, 0xdd3f, 0xdd45, 0xdd44, 0xdd3e, + 0x2379, 0xb064, 0xdd3c, 0xc68e, 0x5d13, 0xdd43, 0x5ce4, 0xdd31, + 0xdd48, 0xdd4a, 0x2bbe, 0xdcd4, 0x2bbe, 0xdcd3, 0xdd47, 0xdd4a, + 0xdd52, 0xdd49, 0x5d0a, 0xdd5e, 0xdd50, 0xdd4f, 0xdd54, 0x4d9a, + 0x4e8c, 0xdd53, 0x5d12, 0xdd24, 0x2356, 0xa8f2, 0x5cce, 0xdd31, + 0xdd4b, 0xdd55, 0x2295, 0x5cad, 0xdd28, 0xdd4d, 0xdd26, 0xdd4c, + 0xa046, 0x5d56, 0xe83c, 0xdd57, 0x5d4d, 0xef4e, 0xdd5a, 0xdd59, + 0xdd2d, 0xdd5b, 0xdd5c, 0x3557, 0xdd25, 0xdd3d, 0xdd58, 0xdd5f, + 0xdd60, 0x5cdb, 0xdd5e, 0x2050, 0x5d17, 0xdd5d, 0xdd61, 0xdd62, + 0xdd46, 0x5ce2, 0xdd24, 0x5ccd, 0xdd43, 0xdd51, 0xdd4e, 0x2050, + 0x5d0b, 0xdd5d, 0xdd63, 0xdd43, 0x56fd, 0xdc9d, 0xdc9e, 0xdca0, + 0x2458, 0x24e1, 0xdc9f, 0xdca2, 0x321d, 0xdca1, 0xdcac, 0x5ce2, + 0xdd12, 0x3557, 0xdd01, 0xdcec, 0xdca8, 0x5cad, 0xdcea, 0xdca9, + 0xdcaa, 0xdca7, 0xdcb6, 0xdcfc, 0xdcaf, 0xdcab, 0x2f10, 0x5cae, + 0xdcb3, 0x5cce, 0xdce4, 0xdcc1, 0xdcb0, 0xdcbc, 0xdcb4, 0xdcba, + 0xdcb8, 0xdcbf, 0xdcbb, 0xdcc0, 0xdcbd, 0xdcca, 0xdd04, 0xdcc8, + 0xdcc4, 0xdcb2, 0xdcc3, 0xdcc2, 0x5ccd, 0x5d13, 0xdd1c, 0xdcc7, + 0xdcc5, 0xdd10, 0xdcd5, 0xdcd1, 0xdcda, 0x5cd2, 0xdcd6, 0xdce6, + 0xdced, 0x5ceb, 0x5cf7, 0xef4e, 0xdd16, 0xdcde, 0xdcdc, 0xdd14, + 0xdcd9, 0xdce1, 0xdce0, 0xdce7, 0x5cf4, 0xe83c, 0xdcf5, 0xdd05, + 0xdcfb, 0xdcfa, 0xdcfd, 0xdcfe, 0x2050, 0x5d0b, 0xdd17, 0x5b83, + 0x5b9a, 0x5cdb, 0xdd0a, 0xdd07, 0xdd08, 0xdd0d, 0xdd0f, 0xdd1b, + 0x407b, 0xc0fe, 0xdd6c, 0xdd6a, 0xdd71, 0xdd70, 0xdd99, 0xdd95, + 0x2c1f, 0x2c20, 0x6bae, 0x6c7b, 0xec9c, 0xdfdf, 0xdd82, 0xdd81, + 0xdda8, 0xdda6, 0xdd76, 0xdd75, 0xdd91, 0xdd8b, 0xde7a, 0x5dc3, + 0xde8d, 0xddb2, 0xddb1, 0xde89, 0xde38, 0x5daf, 0xde8d, 0xde4c, + 0xde92, 0xdff9, 0xddfa, 0xde29, 0xde10, 0xde82, 0xde7a, 0xde55, + 0xde9a, 0xdde5, 0xde8b, 0xac40, 0x50eb, 0xd11b, 0x458e, 0xc58f, + 0xde34, 0x511a, 0xd173, 0xde8a, 0xddf5, 0xde64, 0xddf4, 0xde64, + 0xc8b0, 0xde93, 0xde91, 0xcaac, 0xde0a, 0xddbb, 0xde4f, 0x5e79, + 0xdea2, 0xddc4, 0xde44, 0xdea1, 0xde63, 0xddf8, 0xdff9, 0xde52, + 0x5e28, 0xde2a, 0x5e8a, 0xde95, 0x5e4b, 0xdea2, 0x5dac, 0xddf7, + 0xdea5, 0xddf6, 0xde84, 0xde83, 0xa8b8, 0xddb8, 0x5e0c, 0x5e70, + 0xde95, 0x5dfb, 0xe6ae, 0x5daf, 0xddc3, 0xdeaa, 0xde2f, 0xddde, + 0xde2c, 0x5e70, 0xde8a, 0xdeaa, 0xddf9, 0xdea6, 0xde51, 0x5e4b, + 0xde79, 0xde7f, 0xde9c, 0x5e8f, 0xde99, 0xdeb3, 0xd03d, 0xdec0, + 0x1f53, 0x5ec6, 0x6ab5, 0xead4, 0xdeb2, 0xdeb1, 0xdeac, 0xdeaf, + 0x5040, 0x504c, 0xd077, 0x1f53, 0x5eb0, 0x6ab5, 0xead4, 0xdf66, + 0xdf67, 0xdf68, 0xa19b, 0xdf6a, 0xdf69, 0xdf6b, 0x3799, 0x5ef6, + 0xdf6d, 0xdf6f, 0x5f49, 0xdf6c, 0x5f5f, 0xdf70, 0xdf77, 0xdf78, + 0x5f29, 0xdf88, 0xdf71, 0x3799, 0x5edb, 0xdf6d, 0xdf74, 0xdf75, + 0xdf7a, 0xdf72, 0xdf76, 0x5f15, 0xdf7b, 0xdf7c, 0xdf5c, 0xdf83, + 0xdf82, 0xdf81, 0xdf80, 0xdf7d, 0xdf7e, 0x5f1b, 0xdf86, 0xdf36, + 0x5f19, 0xdf84, 0xb33d, 0x1fcc, 0xdf85, 0x5efd, 0xdf7b, 0x5f12, + 0xdf84, 0x5f0c, 0xdf86, 0x5f3a, 0xdf8e, 0xdf89, 0xdf8b, 0xdf8d, + 0xdf57, 0xdf8a, 0xdf87, 0x5ef0, 0xdf88, 0xdf6e, 0xdf8c, 0xdf6f, + 0xdf91, 0xdf8f, 0xdf0f, 0xdf93, 0x5f1c, 0xdf8e, 0xdf90, 0xdf92, + 0xdf97, 0xd206, 0x67b1, 0x67dc, 0xe7ec, 0xbbc2, 0x5f96, 0xe38b, + 0xdf95, 0xdf98, 0x5ee2, 0xdf6c, 0xdf99, 0xdf7f, 0xdf9a, 0xdf21, + 0xdf00, 0x5ee3, 0xdf70, 0xdf94, 0xdf79, 0xdf73, 0xdeca, 0xdecb, + 0xdecc, 0xded2, 0xded1, 0xded4, 0x5ee2, 0xdf49, 0x3799, 0x5edb, + 0xdef6, 0xdf2a, 0x5edf, 0xdf2d, 0x5ee3, 0xdf5f, 0xdef2, 0xdefb, + 0xdf64, 0xdef8, 0xdef9, 0xdefc, 0xdee4, 0xdeeb, 0xdf62, 0xdefa, + 0x5efd, 0xdf15, 0xdefe, 0xdf09, 0xdf0a, 0xdf4e, 0xdf08, 0xdf07, + 0xdf05, 0xdf03, 0x5f12, 0xdf19, 0xdf14, 0x5f0c, 0xdf1b, 0xdf26, + 0x5ef0, 0xdf29, 0xdf1d, 0xdf25, 0xdf1e, 0xdf2c, 0xdf1f, 0x5f1c, + 0xdf3a, 0xdf33, 0xdf3b, 0xdf2f, 0xdf3c, 0xdf38, 0xdf61, 0xdf45, + 0xdf44, 0xdf3e, 0xdf46, 0xdf4d, 0xdf54, 0x5f9e, 0x5fa4, 0xdfad, + 0x5f9d, 0x5fa4, 0xdfad, 0xe5e2, 0x3683, 0xcf6a, 0x2f01, 0x5fa9, + 0xdfaf, 0x5f9d, 0x5f9e, 0xdfad, 0xa29e, 0x2f01, 0xdfa8, 0x2f01, + 0xdfa7, 0x2f01, 0x5fa1, 0xdfaf, 0xdfae, 0x5f9d, 0x5f9e, 0xdfa4, + 0xdfab, 0x2f01, 0x5fa1, 0xdfa9, 0xa19c, 0xdfb6, 0xdfb5, 0x5fba, + 0x6089, 0xe08a, 0x5fb9, 0x6089, 0xe08a, 0xe07c, 0x6039, 0xe054, + 0xe077, 0xdfc3, 0xdfc2, 0xdfe4, 0xe04e, 0xe081, 0x231d, 0xae00, + 0xe04b, 0xe084, 0xe019, 0xe032, 0xe060, 0xe055, 0xe023, 0x5d7f, + 0x6045, 0xe072, 0xdfc6, 0xe008, 0xe087, 0xaef8, 0xaf80, 0xe003, + 0x2f84, 0x2f91, 0xe015, 0x26d8, 0x26de, 0x26ec, 0x2efb, 0x2efd, + 0xe025, 0x5de1, 0xde5f, 0x1e43, 0xaefc, 0xe069, 0xdfef, 0xdfe5, + 0xe078, 0xe05c, 0xe052, 0x6013, 0xe05e, 0x6012, 0xe05e, 0x2f84, + 0x2f91, 0xdff3, 0xdfd9, 0xdfde, 0x26d8, 0x26de, 0x26ec, 0x2efb, + 0x2efd, 0xdff4, 0xe090, 0xa954, 0x3e38, 0xe04a, 0xa468, 0xdfdb, + 0x5fbe, 0xe054, 0xe060, 0xe08f, 0xa06a, 0xe06f, 0x5fdf, 0xe072, + 0x1fa6, 0xa075, 0x3e38, 0xe030, 0xdfd0, 0xdfc7, 0xe00e, 0x2675, + 0x585c, 0xd85f, 0x5fbe, 0xe039, 0xdfdd, 0xe07a, 0xe065, 0xe00a, + 0x6012, 0xe013, 0x5fdc, 0xe03a, 0xbeaf, 0xe059, 0xe002, 0xe041, + 0x5fdf, 0xe045, 0xced5, 0xdfc1, 0xe009, 0xe057, 0xdfbd, 0xdfc8, + 0xdfd8, 0xdfe9, 0x5fb9, 0x5fba, 0xe08a, 0x5fb9, 0x5fba, 0xe089, + 0xe03b, 0xe026, 0xe61d, 0xe127, 0xe13a, 0xe0ab, 0xb751, 0xe0a6, + 0xe114, 0xe0f5, 0xe112, 0xe134, 0x23b8, 0x6130, 0xe6a3, 0xe0cc, + 0x3b1d, 0x6b30, 0xeb31, 0xe0bd, 0x60d2, 0xe0de, 0xe0df, 0xe136, + 0xe12d, 0x60ce, 0xe0de, 0xe106, 0x60ce, 0xe0d2, 0xe0cf, 0xe148, + 0xe116, 0xe0f6, 0xe0ae, 0xe0e8, 0x1e61, 0x6109, 0x610a, 0xe115, + 0xe132, 0xe0d3, 0x1e61, 0x60f7, 0x610a, 0xe115, 0x1e61, 0x60f7, + 0x6109, 0xe115, 0xe0b9, 0xe0ac, 0x1e61, 0x60f7, 0x6109, 0xe10a, + 0xe0e7, 0xe093, 0xe0d1, 0x23b8, 0x60bb, 0xe6a3, 0xe0f8, 0xe0ba, + 0xe0d0, 0xe146, 0xe09d, 0xe147, 0x2398, 0x28e5, 0xaedb, 0xe147, + 0xe137, 0x613c, 0xe142, 0xe0e6, 0x9e23, 0xe194, 0xe189, 0xb59f, + 0x6196, 0xe19e, 0xe18b, 0x467a, 0x6197, 0xe1b1, 0x616c, 0xe1bb, + 0xa5e0, 0x6167, 0xe1bb, 0x61a4, 0xe1ac, 0xe1c5, 0xe1c3, 0x61b8, + 0xe1c0, 0xd14c, 0xe195, 0xe154, 0xe91f, 0xe162, 0x24b8, 0xee79, + 0xe14b, 0xe187, 0x615d, 0xe19e, 0x467a, 0x6166, 0xe1b1, 0xb9bc, + 0x1e11, 0xeb57, 0x615d, 0xe196, 0x6171, 0xe1ac, 0x233b, 0xbbc9, + 0x6171, 0xe1a4, 0x467a, 0x6166, 0xe197, 0x617f, 0xe1c0, 0x6167, + 0xe16c, 0x2bb4, 0xdb8c, 0x617f, 0xe1b8, 0xd845, 0xe17e, 0xe17d, + 0x2bc0, 0xb3a1, 0x61ca, 0xe1cb, 0x61c8, 0xe1cb, 0x61c8, 0xe1ca, + 0x58cf, 0xd8e1, 0x27dc, 0xa8c4, 0xa398, 0x61d2, 0xe485, 0x61d1, + 0xe485, 0x61da, 0x61fb, 0xe486, 0xe487, 0xe48c, 0x2200, 0xa202, + 0xe48a, 0xe489, 0xe48b, 0x61d3, 0xe1fb, 0xe1e1, 0xe488, 0x1e71, + 0x9e82, 0xe1dc, 0x621f, 0xe493, 0xe490, 0xb263, 0xe48f, 0xe492, + 0xe2e9, 0x2251, 0x2263, 0x2271, 0x228d, 0x228e, 0x2292, 0x2294, + 0xe1fc, 0xe497, 0xe48d, 0xe495, 0xe48e, 0x61d3, 0x61da, 0xe486, + 0x2251, 0x2263, 0x2271, 0x228d, 0x228e, 0x2292, 0x2294, 0xe1f0, + 0xe4af, 0xe4ab, 0xe498, 0xe4ad, 0xe4a5, 0x625b, 0xe4c5, 0xe49a, + 0xe4a0, 0xe49d, 0x6264, 0xe4a9, 0xe4a4, 0xe4a3, 0xe491, 0xe49e, + 0xe4ae, 0x629e, 0xe4a7, 0xe1e3, 0xe49f, 0xe499, 0xe4ac, 0xe49b, + 0xe4aa, 0xe3ba, 0x4089, 0xe46a, 0x6438, 0xe4ce, 0x6268, 0xe4cc, + 0xe4c8, 0xe4b6, 0xe4c3, 0xe4b4, 0xe4b9, 0xe4cd, 0xe4b0, 0xe4b8, + 0xe4c0, 0xe4bf, 0xe4be, 0x6295, 0x62e8, 0x6421, 0x6435, 0xe4c1, + 0xe49c, 0xe4bb, 0xe4ca, 0xe4ca, 0xe4c9, 0x2228, 0xe4c7, 0xe4cb, + 0xe4c2, 0xe4b7, 0xe4b3, 0xe4c6, 0x6206, 0xe4c5, 0xe4ba, 0xe348, + 0x46cb, 0x4f3d, 0xe4b5, 0x620e, 0xe4a9, 0xe4b2, 0x622e, 0xe4cc, + 0xe4bc, 0xe4bd, 0x47ff, 0x483f, 0x4926, 0x62db, 0xe45b, 0x6373, + 0x6451, 0x6452, 0xe46c, 0xe4cf, 0xe4f0, 0xe4d2, 0xe4ec, 0xe4ea, + 0xe4f6, 0xe4f3, 0xe4dc, 0xe4da, 0xe4e3, 0xe4e8, 0x6244, 0x62e8, + 0x6421, 0xe435, 0xe4e2, 0xe4ed, 0x6443, 0xe4eb, 0x62bd, 0xe4e6, + 0x2563, 0x5854, 0xd858, 0xe21e, 0xe4d1, 0xe4f7, 0xe4f1, 0xe4df, + 0xe4f5, 0xe4e5, 0xe4d5, 0xe4ef, 0xe4d0, 0x6322, 0xe4b1, 0xe47e, + 0xe4de, 0xc10a, 0x62ed, 0xe510, 0x4107, 0xe500, 0xe508, 0xe511, + 0xe509, 0xe29b, 0xe4dd, 0xe512, 0xe50c, 0xe4a1, 0xe4e4, 0xe4d7, + 0xe50b, 0xe4fb, 0x47ff, 0x483f, 0x4926, 0x6271, 0xe45b, 0xe50a, + 0x646f, 0xe513, 0x6381, 0xe4d8, 0xe504, 0xe503, 0xe514, 0x6244, + 0x6295, 0x6421, 0x6435, 0xe507, 0x61ef, 0xe4d3, 0x5216, 0x5217, + 0xe4fa, 0x62b3, 0xe510, 0xe4d6, 0xe506, 0xe502, 0xe4fd, 0x6444, + 0xe4f8, 0xe50d, 0xe52f, 0xe4a2, 0xe51e, 0x2f55, 0xe332, 0xe516, + 0xe52b, 0xe529, 0x641a, 0xe4d4, 0xe525, 0xe515, 0xe51f, 0xe524, + 0x637f, 0xe531, 0xe4ee, 0xe51b, 0xe52c, 0xe52d, 0xe51c, 0x62ad, + 0xe4b1, 0xe526, 0xe51a, 0xe520, 0xe521, 0x40bc, 0x4149, 0xe34a, + 0xe522, 0xe519, 0x2f55, 0xe304, 0xe530, 0xd868, 0xe486, 0xe4fc, + 0xe3e8, 0xe51d, 0xe528, 0xe52a, 0xe494, 0xe534, 0x6260, 0xe533, + 0x40bc, 0x4149, 0xe32c, 0xe505, 0xe540, 0xe537, 0xe4e1, 0xe496, + 0x4145, 0xe53b, 0xe4ff, 0x6445, 0xe53d, 0xe538, 0xe532, 0xe518, + 0xe539, 0x63d3, 0xe52a, 0xe53e, 0x6274, 0x6451, 0x6452, 0xe46c, + 0xe52e, 0xe536, 0xe517, 0x649f, 0xe53a, 0xe319, 0xe2e3, 0xe541, + 0xe53f, 0xe545, 0xe551, 0xdf44, 0x642e, 0xe570, 0x39c8, 0xd028, + 0x3eb6, 0xc194, 0x63c1, 0xe501, 0xb7aa, 0xe549, 0xe524, 0xe548, + 0x6543, 0xef12, 0xe4a8, 0xd4e5, 0x6402, 0xe54f, 0xe4e0, 0xe4e9, + 0xe53c, 0xe550, 0x63ae, 0xe547, 0x63ad, 0xe547, 0xe552, 0xe54d, + 0xe553, 0xe54c, 0xe228, 0xe54e, 0xe396, 0xe55e, 0xe55f, 0xe4fe, + 0xe546, 0xe559, 0xe560, 0xe55d, 0xe36f, 0xe4ff, 0xe535, 0xe557, + 0xe558, 0xe55b, 0x222c, 0x2257, 0x2277, 0xe4f2, 0x434d, 0xe55c, + 0xe556, 0xe542, 0x63fd, 0xe508, 0xe33e, 0xe55a, 0xe4e7, 0xe564, + 0xe56a, 0x63e5, 0xe508, 0x63a6, 0xe54f, 0xe4d9, 0xe4f4, 0xe563, + 0xe4f9, 0xe566, 0xe561, 0xe50f, 0xe49f, 0xe56b, 0x630f, 0xe4d4, + 0x6481, 0xe562, 0xe568, 0x6244, 0x6295, 0x62e8, 0x6435, 0xe4c1, + 0xe50e, 0xe50f, 0xe544, 0xe54c, 0x638c, 0xe570, 0xe56f, 0xe56d, + 0x6244, 0x6295, 0x62e8, 0x6421, 0xe4c1, 0xe56e, 0x622c, 0xe4ce, + 0xe4db, 0xe571, 0x629a, 0xe4eb, 0x62f3, 0xe4f8, 0xe360, 0xe56c, + 0xe554, 0x6274, 0x6373, 0x6452, 0xe46c, 0x6274, 0x6373, 0x6451, + 0xe46c, 0xb7aa, 0xe572, 0xe527, 0x647d, 0xe4bb, 0x47ff, 0x483f, + 0x4926, 0x6271, 0xe2db, 0x6909, 0xe95f, 0xe574, 0xe4c4, 0xe573, + 0xa228, 0xe565, 0x4089, 0xe229, 0x6274, 0x6373, 0x6451, 0xe452, + 0xe567, 0xe2df, 0xe4a5, 0xe575, 0xe576, 0x4f36, 0xcf50, 0xe54a, + 0xe569, 0xe523, 0x645a, 0xe4bb, 0xe2ae, 0xa1ff, 0x641d, 0xe562, + 0xe54b, 0x61d1, 0xe1d2, 0x61d3, 0x61fb, 0xe337, 0xe1d4, 0xe1dd, + 0xe1d8, 0xe1d7, 0xe1d9, 0xe1d5, 0xe1f7, 0xe1fa, 0xe1e7, 0xe1e4, + 0xe212, 0xe1e9, 0xe1e3, 0xe346, 0xe1f9, 0xe35a, 0xe1f5, 0xe203, + 0xe223, 0xe208, 0xe226, 0xe245, 0xe20d, 0xe214, 0x6221, 0x637e, + 0x6418, 0xe53a, 0xe209, 0xe2c7, 0xe2fc, 0xe211, 0xe210, 0x6205, + 0xe470, 0xbb3d, 0xe21e, 0xe3a2, 0x620e, 0xe264, 0xe227, 0xe201, + 0xe225, 0xe204, 0xe215, 0xe200, 0xe23a, 0x62ad, 0xe322, 0xe266, + 0xe257, 0xe237, 0x46cb, 0x4f3d, 0xe262, 0xe233, 0xe255, 0xe23d, + 0xe238, 0xe25e, 0x6246, 0x645a, 0xe47d, 0xe26c, 0xe26d, 0xe240, + 0xe23f, 0xe23e, 0x6244, 0x6421, 0xe435, 0xe251, 0xe234, 0xe460, + 0x6206, 0xe25b, 0xe25a, 0x2228, 0xe24b, 0xe230, 0xe249, 0x6247, + 0xe248, 0xe24d, 0x622e, 0xe268, 0xe239, 0x622c, 0xe438, 0xe276, + 0xe2ac, 0xe2a0, 0xe27a, 0xe2e9, 0x630f, 0xe41a, 0xe2aa, 0xe2ee, + 0xe2cf, 0xe2e3, 0xe403, 0xe28d, 0xe43a, 0xe285, 0xe2c1, 0xe2b1, + 0xe2a6, 0xe3a7, 0xe358, 0xe296, 0xe291, 0xe2cc, 0xe2a9, 0xe29b, + 0xe3f5, 0xe293, 0xe3a9, 0xe27f, 0x629a, 0xe443, 0xe27b, 0xe298, + 0xe31a, 0xe2ab, 0xe278, 0xe2a5, 0x222c, 0x2257, 0x2277, 0xe3df, + 0xe283, 0xe40b, 0xe2a8, 0xe280, 0xe2a3, 0x62f3, 0xe444, 0xe412, + 0x5216, 0x5217, 0xe2ea, 0xe2d9, 0xe338, 0xe2f1, 0xe3c8, 0x635e, + 0xe3d7, 0xe2b7, 0xe396, 0xe2f0, 0xe2e5, 0x5021, 0xe2e4, 0xe34b, + 0xe2ef, 0xe2e8, 0x62b9, 0x63e5, 0xe3fd, 0xe2bc, 0xe2dd, 0xe2d2, + 0xe2c5, 0xe2f6, 0xe426, 0x6417, 0xe427, 0x62b3, 0xe2ed, 0xe2bb, + 0xe2c3, 0xe2df, 0xe2e6, 0xe312, 0xe306, 0xe37a, 0xe369, 0xe32f, + 0xe328, 0xe31b, 0xe321, 0xe340, 0xe301, 0xe315, 0xe329, 0xe32b, + 0xe32e, 0xe47c, 0x6318, 0xe39a, 0xe310, 0xe326, 0xe455, 0xe341, + 0xe308, 0x6343, 0xe36f, 0xe307, 0xe31f, 0xe320, 0xe375, 0xe2f8, + 0xe333, 0xe319, 0xe365, 0xe348, 0xe347, 0xe3d8, 0xe376, 0xe354, + 0xe364, 0xe36c, 0x637e, 0xe49f, 0xe35b, 0xe3aa, 0xe360, 0xe370, + 0xe384, 0xe34d, 0xe382, 0xe3e4, 0xe3a1, 0xe428, 0xe387, 0xe3cc, + 0x63ad, 0xe3ae, 0xe39b, 0xe398, 0xe477, 0xe482, 0x63b8, 0xe42b, + 0xe3b3, 0xe3bf, 0x63a6, 0xe402, 0xe3ac, 0xe38a, 0xe3b0, 0xe3b5, + 0xe44c, 0xe3e2, 0xe3dc, 0xe3dd, 0xe3cd, 0xe3f0, 0xe3de, 0xe3e1, + 0xe3d1, 0xe3c3, 0xe3c7, 0xe3d0, 0xe414, 0x641d, 0xe481, 0xe410, + 0xe3f7, 0xe465, 0xe413, 0xe46d, 0xe420, 0xe479, 0xe3f9, 0xe419, + 0xe44a, 0xe433, 0xe436, 0xe432, 0x638c, 0xe42e, 0xe43f, 0xe454, + 0xe463, 0xe45e, 0xe471, 0xe472, 0x1ee7, 0x214f, 0x6578, 0xe57f, + 0x1ee7, 0x214f, 0x6577, 0xe57f, 0x1e45, 0x9e46, 0x1ee7, 0x214f, + 0x6577, 0xe578, 0xe5e8, 0xe5e9, 0xe5ea, 0xe5eb, 0x6589, 0xe5ed, + 0xe5ec, 0x6587, 0xe5ed, 0xaf00, 0xe5f6, 0xe5f3, 0x65a0, 0xe5f0, + 0x6592, 0xe5f2, 0x6591, 0xe5f2, 0xe5f4, 0xe5f5, 0xe5f8, 0x65f9, + 0xeb27, 0x658f, 0xe5f0, 0xe602, 0x2173, 0x65d7, 0xe5dc, 0xe601, + 0xa408, 0xe600, 0xa4c4, 0xe5fa, 0xe5fd, 0xe603, 0xe606, 0xe5fe, + 0x65b2, 0xe605, 0x65b1, 0xe605, 0x65c3, 0xe612, 0xe60a, 0x2266, + 0xe609, 0xe60e, 0xe60f, 0xe60d, 0xe608, 0xe60c, 0x65b4, 0xe612, + 0xb77f, 0xb697, 0xe5f1, 0x3ff6, 0xe614, 0xe615, 0xe611, 0xe607, + 0xe617, 0xe618, 0xe5ff, 0xe616, 0xe619, 0xe5ef, 0x2173, 0x65a2, + 0xe5dc, 0x3597, 0x6b25, 0x6b26, 0x6b2a, 0xeb2d, 0x242f, 0x2518, + 0x2553, 0x2554, 0x255f, 0xdaec, 0x2173, 0x65a2, 0xe5d7, 0xe61a, + 0xe613, 0xe610, 0xdf9f, 0xe61b, 0xe5fc, 0xe580, 0xe582, 0xe583, + 0xe586, 0xe588, 0x6587, 0xe589, 0xa54f, 0xe5d6, 0x658f, 0xe5a0, + 0xe5c8, 0x6591, 0xe592, 0xe58e, 0xe593, 0xe594, 0xe58c, 0xb0b6, + 0xe598, 0x6599, 0xeb27, 0xe5a8, 0xd05e, 0xe5e5, 0xe5a9, 0xe5ad, + 0xe5d3, 0xe5a5, 0xe5a3, 0xe5a1, 0xe5ab, 0xeb2e, 0x65b1, 0xe5b2, + 0xe5ac, 0xe5cd, 0xe5be, 0x2266, 0xe5b9, 0xe5b6, 0xeb29, 0xe5bf, + 0xe5bd, 0xe5bb, 0xe5bc, 0xe5e1, 0xe5cc, 0x65b4, 0xe5c3, 0xe5e0, + 0x3ff6, 0xe5ca, 0xe5cb, 0xe5d4, 0xe5d0, 0xe5d2, 0xe5d5, 0x65de, + 0xeb2b, 0xe5e4, 0xe61d, 0x6091, 0xe61c, 0xe68a, 0x1f8c, 0x6634, + 0x6670, 0xe682, 0x6633, 0xe67d, 0xe638, 0x2347, 0xe65e, 0x2742, + 0xac85, 0x274f, 0xa76f, 0xa751, 0xa740, 0xca7d, 0x6626, 0xe67d, + 0x1f8c, 0x6625, 0x6670, 0xe682, 0xe663, 0x2826, 0xe68e, 0xe628, + 0xbcae, 0x2768, 0xe641, 0x2768, 0xe640, 0xe69b, 0xe678, 0xe6b4, + 0xe673, 0xe658, 0xa905, 0x665c, 0x665d, 0xe67f, 0xa7c8, 0xe649, + 0x6655, 0xe67f, 0xe655, 0x2347, 0xe629, 0xaf8f, 0x2866, 0xe635, + 0xe677, 0x2c9b, 0x2cf6, 0x2d8b, 0x2d8c, 0x2db9, 0x669d, 0xe6af, + 0xe695, 0x4906, 0x667a, 0xe6aa, 0x1f8c, 0x6625, 0x6634, 0xe682, + 0xe648, 0xe665, 0xe646, 0x4906, 0x6669, 0xe6aa, 0x2794, 0xa819, + 0x6626, 0xe633, 0x6655, 0xe65c, 0x2830, 0xa895, 0x1f8c, 0x6625, + 0x6634, 0xe670, 0x27de, 0xa824, 0xe61f, 0xb697, 0x2826, 0xe636, + 0xe6a8, 0x1e5a, 0x66a0, 0xe6b1, 0x48d2, 0xe668, 0xa75e, 0xe69f, + 0xe645, 0x2c9b, 0x2cf6, 0x2d8b, 0x2d8c, 0x2db9, 0x6666, 0xe6af, + 0xe699, 0x1e5a, 0x6690, 0xe6b1, 0x23b8, 0x60bb, 0xe130, 0xe68f, + 0x4906, 0x6669, 0xe67a, 0x275f, 0xa8b3, 0xde8b, 0x2c9b, 0x2cf6, + 0x2d8b, 0x2d8c, 0x2db9, 0x6666, 0xe69d, 0x1e5a, 0x6690, 0xe6a0, + 0xea98, 0xe647, 0x66b7, 0xe6b8, 0x66b6, 0xe6b8, 0x66b6, 0xe6b7, + 0x2bc9, 0x674d, 0x674e, 0x674f, 0x6db4, 0x6e16, 0xee64, 0xa3ea, + 0xe6cb, 0xe6e3, 0x6ceb, 0xed08, 0x20f1, 0xecf8, 0xe6bd, 0xe6dd, + 0xe6db, 0x3742, 0xe6dc, 0x2f6b, 0x4431, 0xed70, 0xd67d, 0xa3cc, + 0xee1b, 0x66cf, 0xedb5, 0x3742, 0xe6d1, 0xe6cd, 0x6d8f, 0x6dc4, + 0xee21, 0xadb2, 0x5b8e, 0xdb90, 0xc9bb, 0xe6be, 0xbc1b, 0x9e91, + 0xe742, 0xe717, 0xe741, 0x671a, 0xe727, 0xc535, 0x671a, 0xe727, + 0xe73d, 0xeef4, 0x4075, 0x671b, 0xe748, 0xbcbe, 0xe6f6, 0x66fa, + 0x66fe, 0xe727, 0x4075, 0x670a, 0xe748, 0xe722, 0xe721, 0x66fa, + 0x66fe, 0xe71a, 0xe744, 0xd987, 0x1e30, 0x5c4a, 0x5c50, 0xe74a, + 0xe701, 0xe6f7, 0xe6f3, 0xe72d, 0xa3c7, 0x4075, 0x670a, 0xe71b, + 0xa3c6, 0x1e30, 0x5c4a, 0x5c50, 0xe73b, 0x2bc9, 0x66ba, 0x674e, + 0x674f, 0x6db4, 0x6e16, 0xee64, 0x2bc9, 0x66ba, 0x674d, 0x674f, + 0x6db4, 0x6e16, 0xee64, 0x2bc9, 0x66ba, 0x674d, 0x674e, 0x6db4, + 0x6e16, 0xee64, 0x2bc8, 0xe752, 0x2bc8, 0xe751, 0xe75a, 0x2172, + 0x2929, 0xe75d, 0xe75c, 0xe753, 0xe759, 0x2172, 0x2929, 0xe754, + 0x4cc6, 0x6763, 0x6eaa, 0x6eab, 0x6eb5, 0xeeba, 0xe762, 0x45b1, + 0xc6b0, 0xe768, 0xe82e, 0xe765, 0x676d, 0xe771, 0x676b, 0x6771, + 0xe7e7, 0x676b, 0x676d, 0xe7e7, 0xe7be, 0xcd46, 0x6789, 0xef17, + 0x6780, 0xef17, 0xe7b5, 0xe78d, 0xe78c, 0xade9, 0xe7c3, 0xe7bd, + 0xe7b9, 0x49cb, 0xe7a7, 0x49cb, 0xe7a6, 0xc89f, 0xe7c9, 0x5f41, + 0xe7dc, 0xe7dd, 0xe78b, 0xe79f, 0xe792, 0xe774, 0x4e6e, 0xcf30, + 0xe791, 0xa343, 0x589c, 0xe7e4, 0xe7af, 0xe7e6, 0xe7e7, 0x2dff, + 0xe7e8, 0xe7e9, 0xe7ea, 0x5f41, 0x67b1, 0xe7ec, 0xe7b2, 0xe7eb, + 0x589c, 0xe7c8, 0xe7cb, 0x676d, 0x6771, 0xe7cc, 0x2dff, 0xe7cd, + 0xe7d3, 0xe7d9, 0xe7de, 0x5f41, 0xe7dc, 0xe7ee, 0xe7ed, 0xe7f1, + 0xe7ef, 0x6f4f, 0xef51, 0xe7fb, 0xe7f5, 0xa4cd, 0xe875, 0xe876, + 0xe877, 0xe879, 0xe87a, 0xe878, 0xe87b, 0xe87c, 0xe882, 0xe880, + 0xe883, 0xe884, 0xe87d, 0xe881, 0xe87f, 0xe887, 0xe886, 0x6838, + 0xe888, 0xe88c, 0xe889, 0x6825, 0xe890, 0x6824, 0xe890, 0xe88f, + 0x6830, 0xe88a, 0xa934, 0x6767, 0xe892, 0x682c, 0xe88a, 0xe88b, + 0x4a4e, 0xe896, 0xe894, 0x681a, 0xe888, 0x4a68, 0x683a, 0x683d, + 0xe893, 0x4a68, 0x6839, 0x683d, 0xe893, 0xe891, 0x5cf4, 0xdd56, + 0x4a68, 0x6839, 0x683a, 0xe893, 0xeaed, 0xe897, 0xd16e, 0xe898, + 0xe89d, 0xe89a, 0x6854, 0xe89c, 0xe899, 0xe89b, 0x684f, 0xe89c, + 0x363e, 0xe86f, 0xa6df, 0xb13f, 0xe8a1, 0x685b, 0xe8a0, 0x685a, + 0xe8a0, 0xcc7b, 0xe89f, 0xe8a2, 0xe87e, 0xe8a4, 0xe8a5, 0x363e, + 0xe855, 0xe8a6, 0x6885, 0x6ad7, 0xee15, 0xe89e, 0xe8a7, 0xe801, + 0xe802, 0xe803, 0xe807, 0xe805, 0xe806, 0x6808, 0xeb1a, 0xe80a, + 0xe811, 0xe867, 0xe813, 0xe80e, 0xe812, 0xe80c, 0xe80f, 0xe810, + 0x6871, 0xead7, 0xe818, 0xe817, 0x681a, 0xe838, 0xe821, 0x682c, + 0xe830, 0xe832, 0xe81c, 0xbf41, 0xc1b2, 0xe826, 0x6824, 0xe825, + 0xe83b, 0xe82e, 0x4a68, 0x6839, 0x683a, 0xe83d, 0xe837, 0x4a4e, + 0xe834, 0xe846, 0xe84c, 0xe852, 0xe84e, 0xe853, 0x684f, 0xe854, + 0xe84d, 0xe873, 0xe862, 0x685a, 0xe85b, 0xe859, 0xe865, 0xce87, + 0xe86b, 0xe86c, 0xe870, 0xe874, 0x1e30, 0x21e8, 0x21ec, 0x21ee, + 0x5af7, 0x5bbd, 0x68cc, 0xe8ce, 0xe8d0, 0x68b7, 0x68c6, 0x68c8, + 0xe8d1, 0xe8d2, 0xa3f0, 0xa22e, 0xe8d3, 0x68ae, 0x68c6, 0xe8c8, + 0xe8d4, 0xe8cf, 0xe8d6, 0xe8d5, 0xe8d7, 0x68c4, 0xe8d8, 0x68c3, + 0xe8d8, 0x68ae, 0x68b7, 0x68c7, 0x68c8, 0xe8d9, 0xe8c6, 0x68ae, + 0x68b7, 0x68c6, 0xe8da, 0x21e8, 0x21ec, 0x21ee, 0x68a8, 0xe8ce, + 0x1e30, 0x21e8, 0x21ec, 0x21ee, 0x68a8, 0xe8cc, 0xe8ba, 0xe8ad, + 0xe8ae, 0xe8af, 0xe8b6, 0xe8b8, 0xe8bc, 0xe8bb, 0xe8c0, 0x68c3, + 0xe8c4, 0xe8c6, 0xe8c8, 0xe8de, 0xcffb, 0xe8db, 0x25b0, 0x68e0, + 0xe963, 0x25b0, 0x68df, 0xe963, 0xe910, 0xe965, 0xe964, 0xe966, + 0xe957, 0xe968, 0xe96a, 0x49d7, 0xe96b, 0xe90a, 0xe96c, 0x68f2, + 0xe96e, 0x68f0, 0xe96d, 0xe8ef, 0x68ee, 0xe96e, 0xe974, 0xe99d, + 0xe972, 0xe971, 0xe970, 0xe973, 0xe97a, 0xe978, 0x6920, 0xe97c, + 0x645c, 0x695f, 0xe977, 0x217b, 0x4faa, 0xe8ec, 0xe975, 0xe95c, + 0xe979, 0xe97b, 0xe8e1, 0xe97d, 0x6927, 0xe981, 0xe97f, 0xe982, + 0xe97e, 0x1f59, 0xe980, 0xd0b4, 0xe984, 0xe983, 0xe96f, 0xe18a, + 0x6905, 0xe97c, 0xe985, 0x2582, 0x6912, 0x6935, 0xe981, 0x5218, + 0xe986, 0xccca, 0xccc7, 0xe967, 0xe959, 0x2582, 0xe927, 0xe989, + 0xe987, 0xe967, 0xe98e, 0xccd5, 0xe969, 0xe988, 0xe98f, 0xe98a, + 0xe98c, 0xe98d, 0xe992, 0xe990, 0xe991, 0xe993, 0xe988, 0xe994, + 0xd1b3, 0xcce6, 0xe965, 0xe976, 0xe8e8, 0xe934, 0xe90d, 0xe98b, + 0x645c, 0x6909, 0xe977, 0xe995, 0x25b0, 0x68df, 0xe8e0, 0xe8e3, + 0x68e2, 0xe951, 0xe8e5, 0x6933, 0xe939, 0xe8e9, 0xe93c, 0xe8ea, + 0xe8eb, 0xe8ed, 0xe8ef, 0x68ee, 0xe8f2, 0xe91e, 0xe8fe, 0xe8fd, + 0xe8fc, 0xe8ff, 0xe8f4, 0xe90c, 0xe952, 0x6909, 0xe95f, 0xe904, + 0xe90e, 0xe903, 0xe90f, 0x6905, 0xe920, 0xe911, 0xe916, 0xe913, + 0x1f59, 0xe918, 0x6912, 0xe927, 0xe915, 0xe91c, 0xe91b, 0xe921, + 0xe928, 0xe937, 0x693d, 0xe94b, 0xe936, 0xe93f, 0xe95e, 0xe941, + 0xe943, 0xe93a, 0xe93e, 0xe948, 0xe949, 0xe945, 0xe94a, 0xe94c, + 0xe962, 0xe8f6, 0xe99f, 0xe99e, 0xea6c, 0xea6d, 0xa1af, 0x69c4, + 0xea6e, 0xea5d, 0xea70, 0xea6f, 0xea72, 0xce36, 0x6a62, 0xea74, + 0xea73, 0x69b1, 0xea6e, 0x6a5b, 0xea7f, 0x357a, 0x69c8, 0x6a45, + 0xea71, 0x357a, 0x69c6, 0x6a45, 0xea71, 0xea7b, 0xea7d, 0xea79, + 0xea75, 0xea7e, 0xea80, 0xea78, 0xea76, 0x69de, 0xea7c, 0x69dd, + 0xea7c, 0xea77, 0x208c, 0x4f75, 0xea82, 0xea88, 0xea87, 0xea73, + 0xea83, 0xea86, 0x6a2e, 0xea51, 0xea8e, 0xea8f, 0xea8b, 0xea8d, + 0xea93, 0xea92, 0xea91, 0xea90, 0x6a13, 0x6a57, 0xea8c, 0x6a37, + 0xea9a, 0x6a10, 0x6a57, 0xea8c, 0xea9b, 0xea97, 0xea99, 0xea52, + 0xea9e, 0xea98, 0x69f5, 0x6a51, 0xea9d, 0xd17e, 0xea7a, 0x6a12, + 0xea9a, 0xea9f, 0xea47, 0xeaa1, 0xd4e6, 0xea9c, 0xea96, 0xeaa0, + 0xeaa2, 0x357a, 0x69c6, 0x69c8, 0xea71, 0xea3a, 0xea85, 0xea95, + 0xea81, 0xeaa3, 0x69f5, 0x6a2e, 0xea9d, 0xea28, 0xea84, 0x6a10, + 0x6a13, 0xea8c, 0xb0ca, 0x69c5, 0xea7f, 0xe9b2, 0xeaa4, 0x69bf, + 0xea74, 0xeaa7, 0x560e, 0xeaa5, 0xeaa6, 0xbb22, 0xea8a, 0xea89, + 0xe9ac, 0xe9ad, 0x69b1, 0xe9c4, 0xe9b4, 0xe9b3, 0x357a, 0x69c6, + 0x69c8, 0xea45, 0xe9b9, 0x69c1, 0xe9ee, 0x69bf, 0xea62, 0xe9d4, + 0xe9db, 0xe9df, 0xe9d9, 0xe9d2, 0xea36, 0xe9d0, 0x69dd, 0xe9de, + 0xe9d1, 0xe9d5, 0x69c5, 0xea5b, 0xe9d8, 0xea4d, 0x208c, 0x4f75, + 0xe9e1, 0xe9f0, 0xea55, 0xea4a, 0xe9f1, 0xe9ed, 0xe9e2, 0xea6b, + 0xea6a, 0xea01, 0x6a10, 0x6a13, 0xea57, 0xea02, 0xe9f8, 0xe9ff, + 0xea0f, 0xea0e, 0xea0d, 0xea05, 0xea4c, 0xea42, 0xea19, 0x66b2, + 0xea2d, 0xea24, 0x6a12, 0xea37, 0xea16, 0xea41, 0x6a2e, 0xea51, + 0xea2b, 0xea38, 0xea43, 0xea3e, 0xea44, 0xea4f, 0xea5f, 0x560e, + 0xea65, 0xea66, 0xea64, 0xd0ae, 0x1f53, 0x5eb0, 0x5ec6, 0xead4, + 0xeca0, 0x51b8, 0xead3, 0xeacf, 0xd180, 0xead6, 0xead5, 0xeac5, + 0xd10f, 0x51b8, 0xeac4, 0x1f53, 0x5eb0, 0x5ec6, 0xeab5, 0x51cf, + 0xeacc, 0xeacb, 0x6871, 0x6885, 0xee15, 0xead9, 0xead8, 0x1eff, + 0xaf77, 0xeaf9, 0xeaef, 0x6b02, 0xeb22, 0x23d1, 0xeaee, 0xe83e, + 0x23d1, 0xeaea, 0xeae5, 0x1f5b, 0xaf7f, 0xeae4, 0xa243, 0x6ae9, + 0x6b13, 0xeb22, 0xb77e, 0xd0e1, 0x6b02, 0xeb22, 0xe87b, 0xeb23, + 0x6ae9, 0x6b02, 0xeb13, 0xeb1b, 0x3597, 0x65d8, 0x6b26, 0x6b2a, + 0xeb2d, 0x3597, 0x65d8, 0x6b25, 0x6b2a, 0xeb2d, 0x6599, 0xe5f9, + 0xa4c4, 0xe60b, 0x3597, 0x65d8, 0x6b25, 0x6b26, 0xeb2d, 0xe61a, + 0x3597, 0x65d8, 0x6b25, 0x6b26, 0xeb2a, 0xe604, 0x3b1d, 0x60c1, + 0xeb31, 0x3b1d, 0x60c1, 0xeb30, 0xeb39, 0xeb36, 0x1ffc, 0xcca5, + 0xac2c, 0xeb58, 0xeb4e, 0x573d, 0xeb49, 0x21f2, 0x2c32, 0x2c34, + 0x2c36, 0xac37, 0x1e11, 0xe19c, 0xeb47, 0xec7c, 0xec7d, 0xec7e, + 0xec6e, 0xebbb, 0xec80, 0xeeff, 0xec81, 0x6c78, 0xec88, 0xec24, + 0xec82, 0xec7f, 0xec84, 0xec85, 0xec86, 0x6bdb, 0xecb7, 0xec8c, + 0xec89, 0xec8f, 0xec87, 0xebf9, 0xec90, 0xec8d, 0xec8b, 0xec8a, + 0xec92, 0xec98, 0x6bd7, 0x6c76, 0xec9e, 0xec95, 0xec96, 0x6bb7, + 0xebf7, 0xec94, 0xec9b, 0xec91, 0x2c1f, 0x2c20, 0x5d7b, 0x6c7b, + 0xec9c, 0xec93, 0xecaa, 0x6ba7, 0xebf7, 0xec9d, 0xeb66, 0xebd8, + 0xeca7, 0xeca0, 0x6c00, 0xeca9, 0xeca4, 0x6bcb, 0xeca8, 0xebca, + 0xecac, 0xecbb, 0xecaf, 0xecad, 0x6b9d, 0xec76, 0xebbe, 0x6b89, + 0xecb7, 0xecb4, 0xecb1, 0xecb5, 0xecb2, 0xecb3, 0xecb8, 0xecae, + 0xecb0, 0xecb6, 0xecba, 0xec3a, 0x6ba7, 0x6bb7, 0xecc0, 0xeb8f, + 0xecab, 0xecca, 0x6bc7, 0xeca9, 0xecc8, 0xec97, 0xecc2, 0x6c28, + 0xecbd, 0xecc7, 0x6c0d, 0xecc5, 0x6c0c, 0xecc5, 0xecbe, 0x6c77, + 0xecc4, 0xecc6, 0xecc3, 0x6c2e, 0xecc1, 0xecd2, 0xecd1, 0xeccb, + 0xeca5, 0xeb73, 0x6c5e, 0xeccf, 0x6c08, 0xecce, 0xecd0, 0xeccd, + 0xec1b, 0xeca2, 0x6ccc, 0xef07, 0xecd3, 0xecd8, 0xeca6, 0xeca3, + 0x6bf5, 0xecb9, 0xecd7, 0xecdb, 0xecd4, 0xecc9, 0xecd9, 0xecd5, + 0x6cd6, 0x6f08, 0xef9e, 0xecdf, 0xecdd, 0xecdd, 0xecdc, 0xecde, + 0xec9f, 0xecbc, 0xec25, 0xec8e, 0xec99, 0xece3, 0xece1, 0xece2, + 0xecbf, 0xec9a, 0xeb63, 0xece0, 0x6b9d, 0x6bd7, 0xec9e, 0x6c10, + 0xecc4, 0x6b72, 0xec88, 0xeca1, 0x2c1f, 0x2c20, 0x5d7b, 0x6bae, + 0xec9c, 0xeb5a, 0xeb5b, 0xeb62, 0xeb77, 0xeb68, 0xeb6f, 0xeb74, + 0xeb7a, 0xeb81, 0xeb83, 0xeb8e, 0x6b72, 0xec78, 0xeb8b, 0xeb93, + 0xeb92, 0xeb8a, 0x56ab, 0xeb91, 0xec5f, 0xeb8d, 0xeb90, 0xebad, + 0xeb9a, 0xebb3, 0xebaa, 0xeb9e, 0xeba6, 0xec02, 0xeb9c, 0xec60, + 0xec6d, 0xebab, 0x2c1f, 0x2c20, 0x5d7b, 0x6bae, 0xec7b, 0xebba, + 0x6b9d, 0xec76, 0xec58, 0x6abe, 0xebc1, 0xec7a, 0xec31, 0xec39, + 0xebc9, 0xec23, 0xec37, 0xebc0, 0xebca, 0x6bc7, 0xec00, 0xebb6, + 0xebfd, 0xebd2, 0xebd6, 0xebea, 0xebd5, 0xebeb, 0xebe1, 0xebe4, + 0xebe7, 0xebdd, 0xebe2, 0xebf0, 0x6b89, 0xebdb, 0xebe8, 0xec3a, + 0xebf4, 0xebd4, 0xec5d, 0xec08, 0xec0f, 0xec68, 0xebf7, 0xec1b, + 0xec03, 0xec13, 0x6c10, 0xec77, 0x6c0c, 0xec0d, 0xec12, 0xec09, + 0xec01, 0xec42, 0xebff, 0xec20, 0x6c32, 0xef07, 0xec2d, 0xec28, + 0xec25, 0xec29, 0xec1f, 0xec1c, 0xec33, 0xec3e, 0x51a4, 0xec48, + 0x6c49, 0xef08, 0xec3b, 0xec35, 0xec45, 0xec3c, 0xec56, 0x6c53, + 0xec54, 0xec57, 0xec52, 0xec6f, 0xec64, 0xec67, 0xec63, 0x2c4c, + 0xee1f, 0x21eb, 0xecec, 0xee20, 0x66c1, 0xed08, 0xece7, 0xee24, + 0xa1e4, 0xee23, 0xee22, 0xe6c7, 0xee29, 0xee28, 0x66c1, 0xeceb, + 0x6d76, 0xee26, 0x6dd7, 0xee25, 0xee30, 0xee35, 0xee33, 0x6e1c, + 0xee32, 0xee2e, 0x6d44, 0xee31, 0xee2a, 0xee2f, 0xee2d, 0x53ba, + 0xedaf, 0xee38, 0xee39, 0xedc3, 0xee3b, 0xee3f, 0xedfa, 0xee3d, + 0xee3a, 0xee3c, 0xed1f, 0xee40, 0xee43, 0xee46, 0xee41, 0xedaa, + 0xee48, 0x6d5e, 0xee45, 0x6d5d, 0xee45, 0xee44, 0xee49, 0xee4c, + 0xee4f, 0xee50, 0xee4e, 0xe6d5, 0xee4a, 0x6d09, 0xee26, 0xee53, + 0x6da4, 0xee4d, 0x6dab, 0xee2b, 0xee51, 0xee52, 0x66de, 0x6dc4, + 0xee21, 0xee4b, 0xee59, 0xee55, 0xee57, 0xee56, 0xed7e, 0xee5b, + 0xee5c, 0xed59, 0x6d87, 0xee2b, 0xee27, 0x53ba, 0xed2c, 0xee5f, + 0x2bc9, 0x66ba, 0x674d, 0x674e, 0x674f, 0x6e16, 0xee64, 0xe6db, + 0xee60, 0xee61, 0xee58, 0xee63, 0xee5a, 0xee5a, 0xee62, 0xee5e, + 0xed33, 0x66de, 0x6d8f, 0xee21, 0xedcf, 0xedc9, 0xedc8, 0xee5d, + 0xedc6, 0xee67, 0xee65, 0x6d0e, 0xee25, 0xee37, 0xee68, 0xee36, + 0xee6a, 0xee54, 0xee69, 0xc1d5, 0xee6b, 0x6df4, 0xee47, 0x6df3, + 0xee47, 0xee6c, 0xee70, 0x6d3c, 0xee6d, 0xee34, 0xee0a, 0xee6f, + 0xedff, 0xee71, 0xd3ba, 0xee72, 0x6871, 0x6ad7, 0xee2c, 0x2bc9, + 0x66ba, 0x674d, 0x674e, 0x674f, 0x6db4, 0xee64, 0xee74, 0xee66, + 0x66da, 0xee73, 0xed1d, 0xee42, 0xee3e, 0x2c4c, 0xece5, 0xece9, + 0x66de, 0x6d8f, 0xedc4, 0xecf6, 0xecf4, 0xecf2, 0x6d0e, 0xedd7, + 0x6d09, 0xed76, 0xedac, 0xed07, 0xed06, 0xed23, 0x6d87, 0xedab, + 0xee15, 0xed28, 0xed1e, 0xed26, 0xed12, 0xed1f, 0xed1d, 0xed1b, + 0xedfd, 0xed15, 0xede5, 0xedd9, 0xed2f, 0xed30, 0xed42, 0xed34, + 0xed43, 0xed3f, 0xee1e, 0xed3b, 0xed50, 0xed53, 0xee1d, 0xed51, + 0xed60, 0x6d5d, 0xed5e, 0xed52, 0x6df3, 0xedf4, 0xed5c, 0xed61, + 0xed72, 0xed93, 0xed6a, 0xed7e, 0xed6f, 0xed6c, 0xed6e, 0xed89, + 0xed8a, 0xed77, 0xedeb, 0xed98, 0xeda1, 0xed9a, 0xedbb, 0xed96, + 0x6dbf, 0xedc0, 0xeda5, 0xeda9, 0xedca, 0xedc2, 0xedb2, 0xedb9, + 0xedba, 0xedc1, 0xedbc, 0x2bc9, 0x66ba, 0x674d, 0x674e, 0x674f, + 0x6db4, 0xee16, 0xedd6, 0xee1a, 0xedd3, 0xedda, 0xedef, 0xede6, + 0xedf2, 0xedf8, 0xedfa, 0xee07, 0xedf9, 0xee0c, 0xee0f, 0xee1b, + 0xee18, 0x2364, 0xa877, 0x4877, 0x48b1, 0xee7c, 0x24b8, 0xe18e, + 0xee7e, 0xc877, 0x4877, 0x48b1, 0xee78, 0x2869, 0xc6d0, 0xee7a, + 0xee85, 0xeea4, 0xee83, 0xee8f, 0xee87, 0x1e3d, 0xaa6f, 0xc350, + 0x4c97, 0xee84, 0xeea6, 0xeea5, 0x6eac, 0xeeb8, 0x4cc6, 0x6762, + 0x6eab, 0x6eb5, 0xeeba, 0x4cc6, 0x6762, 0x6eaa, 0x6eb5, 0xeeba, + 0x6ea9, 0xeeb8, 0xa305, 0x36f2, 0x4cac, 0x6eb4, 0xeeb9, 0x36f2, + 0x4cac, 0x6eaf, 0xeeb9, 0x4cc6, 0x6762, 0x6eaa, 0x6eab, 0xeeba, + 0x6ea9, 0xeeac, 0x36f2, 0x4cac, 0x6eaf, 0xeeb4, 0x4cc6, 0x6762, + 0x6eaa, 0x6eab, 0xeeb5, 0x45f2, 0x45f3, 0xd534, 0x1e48, 0x2c1b, + 0x2e85, 0xeebd, 0x1e48, 0x2c1b, 0x2e85, 0xeebc, 0xeec4, 0x48fa, + 0xeec3, 0xeecc, 0xeec9, 0xcc98, 0xeed2, 0xeed1, 0xeed9, 0xeed8, + 0xeef1, 0x294c, 0xc0b9, 0xeef6, 0xeeed, 0xa15a, 0xeef7, 0xeef2, + 0xeee4, 0xeedb, 0xeeea, 0xe709, 0xeee1, 0xeee9, 0xd8ae, 0xeefe, + 0xeefd, 0x6b6d, 0xef0b, 0xef0c, 0xd6d9, 0x6c32, 0xeccc, 0x6c49, + 0x6cd6, 0xef9e, 0xef0d, 0xeeff, 0xef02, 0xef09, 0xef11, 0xef0e, + 0xe3a1, 0x46b7, 0xc6bc, 0xa1ac, 0x6780, 0xe789, 0xef21, 0xef20, + 0xdc82, 0xef39, 0xef34, 0xa5c5, 0x1e9d, 0x3589, 0x358a, 0xef50, + 0x358b, 0xb58e, 0x5cf7, 0xdd4d, 0x67f2, 0xef51, 0x1e9d, 0x3589, + 0x358a, 0xef4a, 0x67f2, 0xef4f, 0x3b6f, 0xef7f, 0xef54, 0x6f53, + 0xef80, 0xef81, 0xef82, 0xef85, 0xef70, 0xef87, 0xef83, 0xef86, + 0x6f62, 0xef84, 0x6f61, 0xef84, 0xa1fa, 0xef88, 0x256e, 0x2699, + 0xa6d3, 0xa4ac, 0x6f71, 0xef8a, 0xef89, 0xef5a, 0xef6a, 0xef8b, + 0xd16d, 0xef8c, 0x3b6f, 0xef52, 0xef54, 0xef55, 0xef57, 0xef5f, + 0x6f61, 0xef62, 0xef59, 0xef60, 0xef5c, 0xef66, 0xef6c, 0xef6a, + 0xef72, 0xef77, 0x4adc, 0x6f92, 0xef99, 0xa390, 0xae9e, 0x4adc, + 0x6f8d, 0xef99, 0xef9a, 0xef9b, 0x6f8d, 0xef92, 0xef94, 0xef95, + 0x1e80, 0xef9f, 0x49cb, 0x49cc, 0xca50, 0x6c49, 0xef08, 0x1e80, + 0xef9c, 0x248a, 0x248c, 0xb0d2, 0x2401, 0xcc72, +}; + +static const short cjk_variants_indx[0x5200] = { + /* 0x4e00 */ + 4, -1, -1, -1, 5, 6, -1, 7, + -1, 8, 10, 11, 12, -1, 13, -1, + 14, 16, 19, 20, -1, -1, 22, 24, + 26, -1, 28, 29, 33, 34, -1, 36, + 38, 40, 42, 44, 45, 47, 49, 52, + -1, -1, 53, 56, 59, -1, -1, -1, + 60, -1, 66, 67, 68, -1, -1, -1, + -1, -1, 69, -1, -1, 71, 73, -1, + -1, 76, 77, 79, 81, 83, 85, -1, + 87, 92, -1, -1, 93, -1, -1, -1, + 94, 96, -1, -1, 100, 101, -1, 103, + 105, -1, 107, -1, -1, -1, -1, -1, + 110, 111, -1, -1, -1, -1, 115, -1, + 116, -1, -1, -1, -1, -1, -1, -1, + 118, 119, -1, -1, -1, -1, -1, -1, + -1, 121, -1, -1, -1, -1, 124, -1, + 128, 130, 133, -1, -1, -1, 135, -1, + 137, 138, 139, 141, 143, -1, 144, 147, + 151, 153, -1, -1, 155, -1, 156, 157, + 161, 162, 163, -1, 165, 167, 171, 173, + -1, 174, -1, -1, -1, -1, -1, 176, + -1, 178, -1, 182, 183, -1, -1, 184, + 185, 186, 187, -1, -1, 188, -1, -1, + 189, -1, 190, 191, -1, -1, 192, 194, + -1, 195, 196, -1, -1, 199, 201, 202, + -1, 203, -1, -1, 204, -1, 207, 209, + 210, 212, -1, 215, -1, -1, -1, -1, + 217, 218, -1, -1, -1, 220, 221, -1, + -1, -1, 222, -1, -1, -1, -1, 223, + -1, -1, 227, -1, 228, 229, 230, -1, + -1, -1, -1, -1, -1, -1, -1, 232, + -1, -1, 234, -1, 236, 237, 239, 240, + /* 0x4f00 */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 245, -1, -1, -1, -1, -1, 247, 248, + 251, 252, 253, 254, 255, 256, 259, 262, + 263, 265, -1, 266, 267, 268, 269, 270, + -1, -1, 271, 273, -1, -1, 275, -1, + -1, 276, 279, -1, -1, 282, -1, 283, + -1, -1, -1, -1, 284, -1, -1, -1, + 285, -1, 286, -1, -1, -1, -1, 287, + 288, -1, -1, -1, -1, -1, 289, -1, + -1, -1, -1, 290, 295, -1, -1, -1, + -1, 296, -1, 298, 301, -1, 302, -1, + 303, -1, -1, 307, -1, 308, -1, -1, + -1, -1, 309, -1, -1, -1, -1, -1, + -1, 310, -1, -1, -1, 312, -1, 314, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 315, 316, -1, 318, -1, + -1, -1, -1, -1, 319, -1, 323, -1, + 324, -1, -1, -1, -1, -1, 325, -1, + -1, -1, -1, -1, -1, -1, -1, 326, + 328, 329, -1, 331, -1, 332, 333, 335, + 336, 337, 338, 339, 340, 341, -1, 343, + -1, -1, -1, -1, -1, -1, 344, 345, + -1, -1, -1, -1, -1, 346, -1, -1, + -1, 347, 348, -1, -1, -1, -1, 349, + -1, -1, 350, -1, 351, -1, 352, -1, + -1, -1, -1, -1, 353, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 355, 356, + 357, 358, 359, 360, -1, 361, 362, -1, + 363, 364, 365, 366, -1, 367, 369, -1, + -1, 371, 372, -1, -1, -1, -1, -1, + -1, -1, -1, 374, 378, 380, -1, -1, + /* 0x5000 */ + 382, -1, 383, 385, -1, 388, 389, -1, + 390, 391, 393, 394, -1, -1, 397, 398, + 399, 400, -1, -1, -1, -1, 401, -1, + -1, -1, -1, -1, -1, -1, 402, 403, + -1, -1, -1, 405, 407, -1, 408, -1, + -1, -1, -1, 410, -1, -1, -1, -1, + -1, -1, -1, 411, -1, -1, 412, -1, + -1, 413, 415, -1, 416, -1, 417, -1, + 418, -1, -1, -1, -1, -1, 419, 420, + -1, 421, -1, -1, -1, -1, -1, -1, + 422, -1, -1, -1, -1, -1, -1, -1, + 425, 426, 427, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 428, -1, -1, + -1, -1, 429, -1, 430, -1, -1, -1, + -1, -1, -1, -1, 432, 433, -1, 435, + 436, 437, 441, 444, -1, 445, 447, 448, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 449, 452, -1, -1, + -1, 453, -1, -1, -1, -1, 454, -1, + 455, 458, 462, -1, 464, -1, -1, -1, + 465, 467, 470, -1, 471, 472, -1, 473, + 474, 475, -1, -1, -1, 476, -1, 477, + -1, -1, -1, 478, 480, 481, -1, 482, + -1, 483, -1, -1, -1, -1, 484, -1, + 485, -1, 486, 487, 491, 492, -1, -1, + -1, 493, 494, -1, -1, 495, -1, -1, + -1, 498, -1, -1, -1, 499, -1, -1, + 500, -1, -1, -1, 501, -1, 502, 504, + -1, -1, -1, 505, -1, 506, -1, -1, + 507, 508, -1, 509, -1, 512, -1, -1, + -1, 513, 514, -1, 515, -1, -1, -1, + -1, 516, -1, -1, -1, -1, -1, -1, + /* 0x5100 */ + 518, 519, 520, -1, 521, -1, -1, -1, + 522, 523, -1, -1, -1, -1, 525, -1, + 526, -1, -1, -1, 527, 528, -1, -1, + 529, -1, -1, -1, -1, -1, 531, 534, + -1, -1, -1, -1, -1, -1, -1, 535, + -1, -1, 536, -1, -1, -1, -1, -1, + -1, -1, 537, -1, -1, -1, -1, 538, + -1, 539, 540, 541, 542, -1, -1, 543, + -1, -1, 545, -1, -1, -1, -1, 546, + -1, 547, 549, 551, 554, -1, 556, 557, + 561, 563, 565, -1, 567, -1, 568, 569, + 570, -1, 572, -1, 573, -1, -1, -1, + 574, -1, -1, -1, 575, -1, 576, 578, + -1, 579, 581, -1, -1, -1, -1, -1, + 582, -1, 583, 586, 591, -1, 592, -1, + -1, 593, -1, 595, -1, 597, 599, -1, + 600, 601, 602, 603, 604, 605, 606, -1, + 609, 610, 611, 613, 614, -1, 616, 618, + 619, 620, 621, -1, -1, -1, -1, 622, + -1, 623, -1, 625, 626, 627, -1, -1, + -1, -1, 629, 630, 631, -1, 632, -1, + 634, 635, 637, 639, 642, -1, -1, 644, + 645, 648, 649, 651, 652, 653, -1, -1, + -1, -1, 654, 655, -1, 656, -1, -1, + 657, -1, 659, 660, 661, 664, 665, -1, + 667, 668, -1, -1, -1, 669, -1, 670, + -1, 671, 672, 673, -1, -1, 674, -1, + -1, -1, -1, 676, 678, -1, 680, -1, + 684, 686, 688, 690, 692, 693, 694, -1, + 696, -1, -1, 701, 702, 707, 710, 715, + -1, 716, 717, 722, 723, -1, 726, 727, + -1, -1, 730, 732, -1, 734, 735, 736, + /* 0x5200 */ + 737, -1, 739, 741, 742, 743, -1, -1, + 745, -1, 747, -1, -1, 748, -1, -1, + -1, -1, 749, 752, 753, -1, -1, -1, + 754, 755, 756, 757, -1, -1, -1, -1, + 762, -1, -1, -1, -1, 763, 764, 767, + 770, -1, 773, 774, 776, 780, 781, -1, + -1, 782, -1, -1, 786, -1, 787, -1, + -1, 788, 789, -1, 790, 793, 794, 795, + 796, 797, 798, 800, 801, -1, -1, 802, + -1, -1, -1, 803, 806, 807, 808, 809, + 813, 815, -1, -1, -1, -1, -1, 823, + -1, 827, 831, 832, -1, 833, -1, -1, + -1, -1, -1, 834, 842, 844, 845, 847, + -1, 848, -1, -1, -1, -1, 849, -1, + 852, 853, -1, 861, 862, 863, -1, 868, + -1, 872, -1, -1, -1, -1, -1, 873, + -1, -1, -1, 874, 877, -1, -1, 878, + -1, 879, 880, -1, 881, 882, 890, -1, + 898, 901, 903, -1, 911, 919, -1, -1, + -1, -1, -1, -1, -1, 921, 923, 924, + -1, 926, 927, -1, -1, -1, -1, -1, + 928, -1, 931, 932, -1, -1, -1, -1, + -1, 935, 936, 937, 940, 943, -1, -1, + -1, 945, -1, -1, -1, -1, -1, 946, + -1, 947, -1, -1, 948, 949, -1, 951, + 952, -1, 953, 956, 959, -1, -1, -1, + -1, 961, -1, -1, -1, 965, 968, 970, + -1, 972, 973, 974, -1, 977, 978, -1, + 981, -1, 982, -1, 983, -1, 984, 985, + -1, 987, -1, -1, -1, -1, -1, -1, + -1, 988, 989, 992, -1, 995, -1, -1, + 996, -1, -1, 998, -1, -1, -1, -1, + /* 0x5300 */ + 999, -1, -1, 1000, 1002, 1004, 1005, -1, + -1, -1, 1008, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 1009, -1, 1011, 1012, -1, 1014, 1016, -1, + 1017, 1018, -1, -1, -1, -1, 1019, 1020, + 1021, 1023, -1, -1, -1, 1024, 1025, 1026, + -1, 1028, 1029, 1032, -1, -1, -1, -1, + 1035, -1, 1036, 1037, -1, -1, -1, -1, + 1039, -1, -1, 1040, -1, -1, 1041, 1042, + -1, 1046, -1, 1047, -1, 1049, 1050, 1053, + 1056, -1, 1057, 1058, 1060, 1063, 1065, -1, + 1067, -1, 1069, 1070, 1071, -1, -1, -1, + 1073, -1, 1074, -1, 1075, 1082, -1, 1084, + -1, -1, -1, 1085, -1, -1, 1087, 1088, + 1090, -1, -1, 1091, 1093, -1, -1, 1094, + 1096, 1097, -1, 1099, -1, 1100, -1, -1, + -1, -1, 1102, -1, 1105, 1106, 1108, 1114, + 1115, 1116, -1, 1117, 1119, 1120, 1121, -1, + 1122, -1, -1, 1123, -1, 1124, -1, -1, + 1126, 1130, 1131, 1132, -1, -1, -1, 1133, + 1134, 1136, 1137, 1138, 1139, -1, 1141, -1, + 1142, 1143, -1, -1, -1, 1145, 1146, 1147, + 1152, -1, 1154, 1155, 1157, 1158, 1159, 1160, + 1161, -1, 1164, 1165, -1, -1, 1166, 1168, + -1, 1170, 1172, 1175, 1178, 1181, 1184, 1185, + 1186, 1187, 1188, -1, 1189, 1190, 1193, 1194, + 1195, 1196, -1, 1200, -1, 1202, -1, -1, + 1203, 1205, -1, 1207, -1, -1, 1209, -1, + 1210, 1214, 1216, -1, -1, -1, -1, 1220, + -1, -1, 1223, 1226, -1, -1, -1, -1, + 1227, -1, -1, -1, -1, -1, 1232, 1236, + -1, 1237, -1, -1, -1, 1240, -1, -1, + /* 0x5400 */ + 1241, 1243, -1, 1245, -1, -1, -1, -1, + 1247, -1, 1248, -1, 1249, -1, 1251, -1, + -1, 1252, -1, 1254, -1, 1255, -1, 1256, + -1, -1, -1, -1, -1, 1257, 1258, 1259, + -1, -1, -1, -1, -1, -1, -1, -1, + 1262, -1, -1, -1, 1263, -1, -1, 1265, + -1, -1, -1, 1271, 1273, -1, 1275, -1, + -1, -1, -1, 1276, -1, 1277, -1, 1278, + -1, -1, 1279, -1, -1, -1, -1, -1, + 1280, 1282, 1284, -1, 1285, 1286, -1, -1, + 1287, 1288, 1289, 1290, -1, 1291, 1292, 1293, + 1294, 1297, 1299, 1300, 1301, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 1302, + 1303, 1304, 1305, -1, -1, 1307, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 1308, -1, -1, -1, + -1, -1, -1, -1, -1, 1311, -1, -1, + -1, -1, 1312, -1, 1315, -1, -1, 1318, + -1, -1, 1319, -1, -1, -1, -1, -1, + -1, 1321, -1, 1322, 1323, 1324, -1, -1, + -1, -1, -1, -1, 1325, -1, -1, -1, + -1, 1326, -1, -1, 1328, -1, -1, 1329, + -1, 1331, 1334, -1, -1, -1, -1, -1, + 1336, -1, -1, -1, 1338, 1340, -1, -1, + -1, -1, -1, -1, 1341, -1, -1, -1, + -1, -1, -1, -1, -1, 1343, -1, -1, + -1, 1344, 1348, 1349, 1350, 1351, -1, 1352, + -1, 1354, -1, -1, 1355, 1356, -1, 1357, + -1, 1358, -1, 1361, -1, -1, -1, -1, + -1, -1, -1, -1, 1362, -1, -1, -1, + -1, -1, 1363, -1, -1, -1, 1368, -1, + -1, -1, 1370, -1, -1, -1, -1, -1, + /* 0x5500 */ + 1371, -1, -1, -1, 1373, -1, -1, 1374, + -1, -1, -1, -1, -1, 1375, -1, -1, + 1376, -1, -1, -1, -1, 1377, 1378, -1, + 1382, -1, -1, 1388, -1, 1389, -1, -1, + 1390, -1, 1391, 1392, 1393, -1, -1, 1394, + -1, -1, -1, 1395, -1, -1, -1, -1, + -1, 1396, -1, -1, -1, -1, -1, -1, + 1397, -1, -1, -1, -1, -1, -1, -1, + 1398, -1, -1, -1, -1, -1, 1399, -1, + -1, -1, -1, -1, -1, -1, -1, 1400, + -1, -1, -1, 1401, 1407, -1, 1413, 1414, + -1, -1, -1, -1, -1, -1, 1415, 1419, + 1425, -1, -1, 1430, -1, -1, -1, 1433, + -1, -1, -1, -1, 1434, 1435, 1436, 1440, + 1441, -1, -1, -1, 1443, -1, -1, -1, + 1444, -1, 1445, -1, -1, -1, -1, -1, + 1446, -1, 1448, -1, 1450, -1, 1451, -1, + -1, -1, -1, -1, -1, -1, 1456, -1, + -1, 1458, 1460, -1, -1, -1, -1, -1, + -1, -1, 1463, -1, 1464, -1, 1467, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1468, 1469, 1470, 1472, -1, 1473, 1475, + 1477, -1, 1480, -1, -1, -1, 1481, 1483, + -1, -1, -1, 1485, -1, 1486, 1487, -1, + -1, -1, -1, -1, -1, 1488, 1489, 1490, + -1, -1, 1491, -1, -1, -1, 1492, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 1493, -1, 1494, -1, -1, -1, + 1495, -1, -1, 1496, -1, 1497, -1, -1, + -1, 1498, -1, 1499, -1, -1, -1, -1, + -1, -1, -1, 1500, -1, -1, 1501, -1, + -1, 1502, -1, -1, -1, -1, -1, -1, + /* 0x5600 */ + -1, -1, -1, -1, -1, -1, 1503, -1, + -1, -1, 1505, -1, -1, 1506, -1, -1, + -1, 1507, -1, 1509, 1510, -1, 1511, 1512, + 1515, -1, -1, -1, 1516, -1, -1, -1, + -1, -1, -1, -1, 1517, -1, -1, -1, + 1518, 1519, -1, -1, -1, -1, 1521, 1522, + 1524, 1525, -1, -1, -1, 1526, -1, 1527, + 1528, -1, -1, -1, -1, 1529, -1, -1, + -1, 1530, 1531, -1, 1532, 1534, -1, -1, + -1, 1535, -1, -1, -1, -1, -1, -1, + 1537, -1, -1, 1538, -1, 1539, 1540, -1, + -1, -1, -1, 1542, 1544, 1545, -1, -1, + 1546, 1547, -1, -1, -1, 1548, 1549, -1, + 1550, -1, 1551, -1, -1, -1, -1, 1552, + -1, -1, 1553, -1, 1554, 1556, -1, -1, + 1559, 1560, -1, -1, -1, -1, 1561, -1, + 1562, -1, -1, -1, -1, -1, -1, 1563, + -1, -1, -1, -1, 1564, -1, -1, 1565, + 1566, -1, -1, -1, 1569, 1570, -1, -1, + -1, 1571, -1, -1, -1, -1, 1575, -1, + 1580, -1, 1581, 1582, -1, 1583, 1584, -1, + 1585, -1, -1, -1, -1, -1, 1586, -1, + -1, -1, 1587, 1588, 1589, -1, 1591, -1, + -1, -1, -1, 1592, -1, -1, -1, -1, + 1593, 1594, 1595, -1, -1, 1597, -1, -1, + 1598, 1599, 1601, -1, 1602, -1, -1, 1603, + -1, 1604, -1, 1605, -1, -1, -1, 1608, + 1611, 1617, -1, 1618, -1, -1, 1619, 1625, + 1626, -1, 1627, 1630, -1, -1, 1633, 1636, + -1, -1, 1637, -1, 1638, 1644, -1, 1647, + 1652, 1653, 1654, 1657, 1660, 1663, 1664, -1, + 1669, -1, -1, 1670, -1, 1675, 1680, -1, + /* 0x5700 */ + 1683, -1, -1, 1688, -1, -1, 1689, 1692, + 1693, -1, -1, 1694, -1, 1699, 1702, 1705, + -1, 1706, 1707, 1709, -1, -1, 1712, 1715, + 1718, -1, -1, -1, -1, 1720, -1, 1722, + -1, 1723, 1724, 1726, -1, -1, -1, 1727, + 1729, -1, -1, -1, 1730, 1731, -1, -1, + 1732, -1, -1, -1, -1, -1, -1, -1, + -1, 1735, 1736, -1, -1, 1738, -1, -1, + 1742, -1, 1743, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 1745, + 1749, 1750, -1, 1751, 1752, -1, -1, 1755, + -1, 1758, 1759, 1760, 1766, 1767, 1769, 1771, + 1773, -1, -1, 1775, 1776, -1, 1777, 1778, + 1779, -1, -1, -1, -1, 1781, 1782, 1784, + 1786, -1, -1, 1787, -1, 1788, -1, -1, + 1790, -1, 1791, -1, -1, -1, -1, -1, + -1, -1, 1792, -1, 1793, 1794, 1795, 1796, + -1, -1, -1, 1797, -1, -1, -1, -1, + -1, -1, 1798, 1800, 1801, 1802, 1803, -1, + -1, -1, 1804, 1807, 1808, -1, -1, -1, + -1, 1809, 1810, -1, -1, -1, 1811, 1812, + 1813, 1814, -1, 1816, -1, 1817, -1, 1818, + -1, 1819, 1820, -1, 1821, -1, -1, -1, + -1, -1, -1, 1822, -1, -1, -1, -1, + 1824, -1, -1, -1, -1, -1, 1825, -1, + 1826, -1, 1827, -1, -1, -1, -1, -1, + -1, 1830, 1835, 1836, -1, -1, -1, -1, + 1837, 1838, 1840, -1, 1841, -1, 1843, -1, + -1, 1845, -1, -1, -1, -1, 1846, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 1847, + -1, -1, -1, -1, 1848, 1851, -1, -1, + /* 0x5800 */ + -1, -1, 1852, 1853, -1, 1854, 1855, 1856, + -1, -1, 1857, -1, -1, -1, -1, -1, + -1, 1858, -1, -1, -1, 1859, 1861, -1, + -1, 1862, -1, -1, -1, 1863, -1, -1, + -1, -1, -1, -1, 1864, -1, 1866, -1, + -1, -1, -1, -1, -1, -1, -1, 1868, + 1871, 1873, -1, -1, 1874, -1, -1, -1, + -1, -1, 1876, -1, -1, -1, -1, -1, + -1, 1878, -1, -1, -1, -1, 1880, -1, + -1, -1, 1881, 1884, -1, 1885, -1, 1886, + 1887, 1888, 1889, -1, 1890, -1, -1, 1891, + -1, 1892, 1893, -1, -1, -1, -1, 1894, + -1, 1895, 1896, -1, 1897, -1, 1899, -1, + -1, 1900, -1, 1902, -1, -1, -1, -1, + -1, -1, 1903, -1, -1, 1905, -1, 1906, + -1, 1908, -1, -1, 1910, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 1913, 1914, -1, 1915, -1, -1, -1, + -1, -1, -1, -1, -1, 1916, 1918, 1919, + -1, 1920, -1, -1, 1922, -1, 1924, -1, + -1, -1, 1925, -1, 1927, -1, -1, 1930, + -1, -1, -1, -1, -1, -1, 1931, 1933, + 1935, -1, -1, 1940, -1, 1942, 1947, -1, + 1948, -1, -1, 1949, -1, -1, 1950, -1, + -1, -1, -1, -1, 1951, -1, -1, 1953, + -1, -1, 1954, 1956, 1957, 1958, 1959, -1, + 1961, -1, -1, 1962, -1, -1, -1, -1, + 1964, 1966, 1967, -1, 1968, -1, 1973, 1975, + 1976, 1977, 1979, -1, 1980, 1981, -1, -1, + -1, 1984, 1986, -1, -1, -1, 1987, 1989, + 1991, 1992, 1993, 1995, -1, 1997, 1999, 2001, + 2003, 2004, 2005, 2007, 2009, 2010, -1, -1, + /* 0x5900 */ + 2012, -1, 2014, -1, 2015, 2017, -1, 2018, + -1, 2022, 2024, -1, -1, 2025, -1, 2028, + -1, -1, -1, 2029, 2030, -1, -1, -1, + 2031, -1, 2033, 2034, 2035, -1, -1, 2036, + 2037, -1, 2038, 2040, -1, 2042, -1, -1, + -1, 2043, -1, -1, 2046, 2047, -1, -1, + -1, -1, 2048, 2050, 2051, -1, 2052, -1, + 2053, 2054, 2055, -1, -1, -1, 2056, -1, + -1, 2057, 2060, -1, -1, -1, -1, 2061, + 2062, -1, -1, 2063, 2064, -1, -1, -1, + 2065, -1, -1, -1, 2066, -1, 2068, -1, + 2071, 2072, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 2073, -1, 2075, + 2077, 2080, 2083, -1, 2084, -1, 2087, -1, + -1, -1, -1, -1, -1, -1, 2088, -1, + 2090, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 2092, 2096, + 2098, -1, 2099, -1, -1, 2100, -1, -1, + -1, -1, 2102, -1, -1, -1, 2103, -1, + -1, 2104, -1, 2105, -1, 2106, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 2110, 2111, 2112, 2114, -1, -1, -1, + -1, -1, -1, 2115, -1, -1, -1, 2118, + 2120, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 2122, -1, + -1, 2123, 2124, 2125, -1, 2127, -1, -1, + 2128, -1, 2129, -1, -1, -1, -1, 2130, + -1, 2131, -1, -1, 2132, -1, -1, -1, + -1, -1, 2133, -1, -1, -1, 2134, 2136, + -1, -1, 2138, 2140, 2141, -1, 2142, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 2143, -1, -1, 2145, -1, -1, -1, -1, + /* 0x5a00 */ + -1, -1, -1, -1, 2146, 2147, 2148, 2149, + 2150, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 2151, -1, -1, -1, -1, -1, + 2152, -1, -1, 2154, -1, -1, -1, 2156, + -1, -1, -1, -1, 2157, -1, 2161, -1, + -1, -1, -1, -1, -1, 2162, -1, 2163, + 2165, 2166, 2168, -1, 2169, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 2171, + 2173, 2176, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 2177, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 2178, -1, -1, 2179, -1, + -1, -1, -1, -1, 2181, 2182, -1, 2183, + -1, -1, -1, 2185, 2186, 2189, 2190, -1, + -1, -1, -1, -1, -1, -1, -1, 2191, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 2193, 2195, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 2196, + -1, -1, 2197, -1, -1, 2198, -1, 2199, + -1, -1, -1, -1, -1, -1, -1, -1, + 2201, -1, -1, -1, 2202, 2203, -1, 2204, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 2206, -1, -1, -1, -1, + 2208, -1, 2209, -1, 2210, -1, -1, 2211, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 2212, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 2213, -1, -1, -1, 2214, 2215, -1, + -1, -1, 2217, 2219, -1, -1, -1, 2221, + /* 0x5b00 */ + 2222, -1, -1, 2224, -1, -1, -1, -1, + 2225, 2226, -1, 2227, 2228, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 2229, -1, -1, -1, 2230, -1, -1, + -1, 2232, 2233, -1, 2235, -1, -1, -1, + -1, -1, 2236, -1, -1, 2238, -1, -1, + 2240, -1, 2243, -1, -1, -1, -1, 2244, + 2245, -1, -1, -1, -1, -1, 2246, -1, + -1, -1, -1, 2247, -1, -1, 2249, -1, + -1, -1, -1, -1, 2252, -1, -1, -1, + -1, -1, 2253, 2254, -1, -1, -1, -1, + -1, 2255, -1, -1, -1, -1, -1, -1, + 2256, -1, -1, -1, -1, -1, 2257, -1, + -1, -1, 2262, 2263, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 2264, -1, -1, -1, 2269, 2270, 2271, 2274, + -1, 2275, 2281, 2282, -1, -1, 2285, -1, + 2286, -1, 2287, -1, -1, 2288, -1, -1, + 2289, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 2291, 2293, 2297, 2299, + 2301, 2302, -1, -1, -1, -1, -1, -1, + -1, 2304, 2305, 2306, -1, -1, 2307, -1, + -1, -1, -1, -1, 2308, -1, 2310, 2311, + -1, -1, -1, 2313, 2314, 2316, 2318, -1, + 2320, -1, -1, 2321, -1, -1, 2322, 2323, + 2325, 2327, -1, -1, 2334, 2335, -1, -1, + -1, -1, -1, 2341, -1, 2342, -1, 2348, + -1, -1, 2354, 2358, 2360, 2366, -1, 2367, + 2368, -1, 2370, -1, -1, -1, 2371, 2373, + -1, 2379, -1, 2381, 2383, -1, -1, -1, + -1, -1, -1, 2385, -1, 2389, 2390, -1, + -1, 2394, -1, 2396, 2397, -1, 2398, 2400, + /* 0x5c00 */ + -1, -1, 2402, -1, -1, 2404, 2407, 2408, + 2409, 2411, -1, 2412, -1, 2413, 2415, -1, + -1, -1, 2416, 2419, 2422, -1, -1, -1, + 2425, 2426, 2427, 2428, -1, 2432, 2435, 2436, + 2441, -1, 2446, 2449, 2450, 2452, 2453, 2454, + -1, 2457, -1, 2458, 2459, 2460, -1, -1, + -1, -1, 2463, -1, 2468, -1, 2473, 2478, + 2483, -1, -1, -1, -1, 2484, -1, -1, + 2487, -1, 2489, 2490, -1, 2491, 2492, -1, + -1, -1, 2493, -1, 2494, 2496, 2497, 2498, + -1, -1, -1, 2500, -1, -1, -1, -1, + -1, -1, -1, 2501, -1, -1, 2503, -1, + -1, 2504, 2505, -1, 2506, -1, 2507, -1, + 2508, -1, -1, -1, 2509, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 2510, + 2511, 2512, 2516, -1, -1, 2517, -1, -1, + 2519, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 2520, 2521, + 2522, -1, 2523, 2524, -1, -1, -1, -1, + -1, 2531, -1, -1, -1, -1, -1, -1, + -1, 2532, -1, -1, -1, 2538, -1, -1, + -1, -1, -1, 2539, 2540, -1, -1, -1, + -1, -1, -1, -1, -1, 2541, -1, 2542, + -1, -1, -1, 2543, 2544, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 2545, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 2546, -1, -1, + -1, 2547, -1, 2548, 2549, 2550, 2551, -1, + 2552, 2553, -1, -1, -1, -1, -1, 2554, + 2555, -1, -1, -1, 2556, 2557, 2560, -1, + -1, -1, -1, -1, -1, 2567, -1, -1, + /* 0x5d00 */ + -1, -1, 2568, 2569, 2570, -1, -1, 2571, + 2572, -1, -1, 2573, -1, 2575, 2576, -1, + -1, -1, -1, -1, -1, -1, 2579, 2580, + 2581, 2583, -1, -1, -1, -1, -1, -1, + -1, -1, 2585, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 2586, 2587, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 2589, -1, -1, -1, + 2590, -1, 2591, 2594, -1, -1, -1, 2597, + 2601, -1, 2604, -1, 2605, 2608, -1, -1, + 2609, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 2611, + -1, -1, -1, 2612, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 2613, -1, 2614, 2615, -1, -1, 2616, + -1, -1, -1, 2618, 2625, -1, -1, -1, + -1, -1, -1, -1, 2632, -1, -1, 2633, + -1, -1, -1, -1, -1, -1, -1, -1, + 2634, -1, 2635, -1, -1, -1, -1, 2636, + 2637, -1, -1, -1, -1, -1, 2638, -1, + -1, -1, 2639, 2640, 2643, -1, -1, -1, + 2645, 2648, 2655, -1, 2656, 2657, -1, -1, + -1, -1, -1, -1, -1, 2658, 2660, -1, + -1, -1, -1, 2663, 2664, -1, -1, -1, + -1, -1, 2667, 2668, 2669, -1, 2670, 2673, + -1, -1, -1, 2676, -1, 2677, -1, -1, + 2678, -1, 2679, 2680, -1, -1, -1, -1, + -1, 2681, -1, -1, -1, -1, -1, 2682, + 2683, -1, -1, -1, -1, 2684, -1, 2685, + -1, -1, 2686, 2687, -1, 2689, -1, 2690, + /* 0x5e00 */ + 2692, 2694, -1, 2697, -1, 2698, -1, -1, + 2699, -1, -1, 2700, -1, -1, -1, 2701, + 2702, 2703, 2704, -1, -1, 2705, -1, -1, + 2706, -1, 2707, -1, 2708, -1, -1, -1, + -1, -1, -1, -1, -1, 2710, 2711, 2713, + -1, -1, -1, 2714, -1, 2715, 2716, 2719, + 2721, 2724, -1, 2725, -1, -1, 2726, -1, + -1, -1, -1, 2728, 2729, 2730, -1, -1, + 2731, -1, 2732, 2734, -1, -1, -1, 2735, + 2738, -1, -1, -1, 2740, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 2741, + 2742, -1, 2743, -1, -1, -1, -1, 2746, + -1, 2748, -1, 2749, 2751, -1, -1, -1, + -1, -1, -1, 2753, 2756, -1, -1, -1, + -1, -1, 2757, -1, 2760, -1, 2761, 2767, + 2768, 2769, 2771, -1, -1, -1, 2772, 2773, + -1, 2776, -1, 2778, 2780, 2782, 2786, -1, + -1, -1, 2787, -1, -1, -1, -1, -1, + 2788, 2789, -1, 2790, 2791, -1, -1, -1, + -1, 2793, -1, -1, -1, -1, 2794, 2795, + -1, -1, -1, -1, -1, -1, -1, 2797, + -1, -1, -1, 2798, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 2799, 2803, -1, + -1, -1, 2804, 2809, 2810, 2811, -1, 2812, + -1, 2813, 2815, 2816, -1, -1, -1, -1, + 2818, -1, -1, -1, -1, -1, 2819, 2820, + 2822, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 2824, 2825, -1, 2828, -1, 2829, + 2831, 2833, 2834, 2836, -1, -1, -1, -1, + -1, 2838, 2839, -1, 2840, -1, -1, -1, + 2841, -1, -1, 2844, -1, -1, -1, -1, + 2848, -1, -1, 2849, 2855, 2857, -1, -1, + /* 0x5f00 */ + 2863, 2864, 2871, 2872, 2873, -1, -1, -1, + -1, 2875, -1, -1, 2876, 2877, 2878, -1, + 2880, 2883, 2884, -1, 2885, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 2886, -1, -1, -1, -1, 2887, 2889, -1, + -1, -1, 2890, -1, -1, -1, -1, 2891, + -1, -1, -1, 2892, -1, 2893, -1, 2894, + -1, 2895, 2897, 2898, 2899, -1, 2900, -1, + -1, -1, -1, -1, -1, -1, 2902, -1, + 2903, -1, -1, -1, 2905, -1, 2906, -1, + 2907, 2908, 2909, 2912, 2914, 2915, -1, 2918, + -1, 2919, 2921, 2923, 2926, 2929, 2932, 2935, + 2936, -1, -1, -1, -1, 2938, 2939, -1, + 2940, 2941, -1, 2942, 2943, -1, -1, -1, + -1, -1, 2945, -1, 2946, -1, -1, 2947, + -1, -1, -1, 2950, -1, -1, -1, 2951, + 2953, 2955, -1, 2958, 2959, -1, -1, 2962, + 2963, -1, 2964, -1, 2965, -1, -1, 2966, + -1, 2967, -1, 2970, -1, 2972, -1, -1, + -1, -1, -1, -1, -1, -1, 2974, -1, + 2976, 2978, -1, 2979, 2981, -1, -1, -1, + -1, 2982, -1, -1, 2984, 2987, -1, -1, + 2988, 2989, -1, 2990, 2993, 2995, -1, 2997, + -1, 3000, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 3001, 3002, -1, 3003, -1, + -1, -1, -1, -1, -1, -1, 3004, 3005, + -1, -1, -1, -1, -1, -1, -1, 3007, + -1, 3008, -1, -1, 3009, -1, -1, -1, + -1, -1, 3011, 3012, -1, -1, -1, 3013, + -1, 3014, -1, -1, -1, -1, -1, -1, + 3017, -1, -1, -1, -1, 3018, -1, -1, + -1, -1, -1, -1, -1, -1, 3019, -1, + /* 0x6000 */ + 3020, 3022, 3023, 3024, 3025, 3026, 3027, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 3028, -1, 3029, -1, + -1, -1, -1, -1, 3030, 3031, -1, -1, + -1, -1, -1, 3032, -1, 3034, -1, -1, + -1, -1, 3035, -1, -1, -1, -1, -1, + -1, 3036, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 3039, 3044, -1, -1, 3045, + -1, -1, -1, -1, -1, -1, 3046, -1, + -1, -1, -1, 3047, -1, -1, -1, -1, + -1, -1, 3048, 3049, -1, -1, 3051, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 3052, 3053, -1, -1, 3055, 3057, -1, -1, + -1, -1, 3058, -1, -1, -1, -1, -1, + -1, 3059, -1, 3061, 3062, 3065, 3066, -1, + 3070, 3071, 3072, 3073, 3074, 3076, 3077, 3078, + 3080, -1, -1, -1, -1, 3082, -1, -1, + -1, -1, 3084, 3089, -1, 3090, -1, -1, + -1, 3091, -1, 3092, -1, -1, 3093, -1, + -1, -1, -1, -1, -1, -1, 3095, 3096, + -1, -1, 3097, -1, 3098, -1, 3101, -1, + -1, 3103, 3105, 3108, 3109, 3110, -1, 3111, + -1, -1, -1, 3112, 3115, 3116, 3117, -1, + -1, -1, -1, -1, -1, 3118, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 3120, -1, -1, -1, -1, -1, + -1, -1, 3122, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 3125, -1, + 3127, 3128, -1, 3131, -1, 3132, -1, 3134, + 3135, 3136, -1, 3137, 3138, 3139, 3141, 3142, + -1, 3143, 3145, -1, -1, -1, -1, 3146, + -1, -1, -1, 3147, 3148, -1, -1, -1, + /* 0x6100 */ + -1, -1, 3149, -1, -1, -1, -1, -1, + 3151, -1, -1, -1, -1, -1, -1, -1, + -1, 3153, -1, -1, -1, -1, -1, -1, + -1, 3155, -1, 3156, 3157, -1, -1, -1, + 3158, 3159, -1, -1, 3160, -1, 3161, 3162, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 3164, 3165, -1, -1, 3166, + -1, 3167, -1, -1, 3169, 3170, 3171, 3172, + -1, -1, 3173, -1, 3175, -1, -1, 3176, + -1, -1, -1, 3177, -1, 3178, 3179, -1, + -1, 3182, -1, -1, -1, -1, -1, -1, + 3184, 3185, 3187, -1, -1, -1, -1, 3189, + -1, -1, -1, 3191, 3192, -1, -1, -1, + -1, -1, 3193, 3194, -1, 3195, 3196, -1, + -1, -1, -1, 3197, 3198, -1, 3199, -1, + -1, -1, -1, -1, 3200, 3202, 3204, 3205, + -1, 3208, 3209, -1, -1, 3210, -1, 3211, + -1, -1, 3212, -1, -1, -1, -1, -1, + 3213, 3214, 3217, -1, 3218, -1, 3220, 3222, + 3223, 3226, 3229, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 3230, 3231, -1, -1, + -1, 3234, -1, 3235, -1, -1, 3236, -1, + -1, -1, 3237, -1, -1, -1, 3238, -1, + -1, -1, -1, 3239, -1, -1, -1, -1, + -1, -1, -1, 3240, -1, -1, -1, 3241, + -1, 3242, -1, -1, 3244, 3245, -1, -1, + 3246, 3248, 3249, -1, 3251, -1, -1, -1, + -1, -1, -1, -1, 3252, -1, 3253, 3254, + -1, -1, -1, 3255, -1, -1, 3256, 3257, + 3258, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 3259, -1, 3260, 3262, 3263, 3264, + 3266, -1, 3267, -1, 3268, 3270, 3271, 3272, + /* 0x6200 */ + 3273, -1, -1, -1, -1, -1, 3274, 3275, + -1, -1, -1, 3276, -1, -1, -1, 3277, + -1, -1, -1, -1, 3279, -1, -1, 3280, + 3281, -1, 3283, 3285, -1, 3286, 3288, -1, + -1, -1, -1, -1, -1, -1, 3289, 3291, + -1, 3292, -1, -1, 3293, -1, 3294, 3296, + 3298, -1, 3300, -1, -1, -1, 3302, 3304, + 3306, 3308, -1, 3309, 3310, -1, 3312, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 3313, 3314, 3315, 3316, -1, + -1, 3318, -1, -1, -1, 3320, -1, 3321, + 3322, -1, -1, -1, -1, -1, 3324, -1, + 3325, -1, -1, 3326, -1, -1, -1, 3327, + 3328, 3330, 3332, 3333, 3334, -1, -1, 3335, + 3336, -1, -1, -1, -1, 3337, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 3338, -1, -1, -1, -1, -1, + -1, 3340, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 3341, 3342, 3343, 3344, 3345, 3347, + 3348, 3349, 3350, -1, 3351, 3352, -1, -1, + -1, -1, -1, -1, 3353, -1, -1, -1, + -1, -1, -1, -1, -1, 3354, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 3357, -1, -1, 3358, -1, -1, + 3359, -1, -1, 3360, -1, -1, -1, 3361, + 3362, -1, -1, 3364, 3365, 3366, 3367, 3368, + -1, -1, -1, -1, 3369, 3370, 3371, 3372, + 3373, 3375, 3378, 3379, -1, 3380, 3381, 3382, + 3383, 3385, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 3387, + /* 0x6300 */ + -1, -1, 3388, -1, 3389, -1, -1, -1, + -1, -1, 3391, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 3393, 3396, 3397, 3398, 3399, 3400, 3401, + 3402, 3403, 3404, 3405, 3406, 3407, 3408, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 3409, -1, 3411, + -1, -1, -1, -1, -1, 3412, 3413, 3414, + -1, 3415, -1, -1, -1, -1, 3418, -1, + -1, -1, -1, -1, -1, 3421, -1, 3422, + -1, -1, -1, -1, -1, -1, -1, 3423, + -1, -1, -1, -1, 3424, -1, 3425, 3426, + -1, 3427, 3428, 3429, -1, -1, -1, -1, + 3431, -1, -1, 3432, -1, -1, 3433, -1, + -1, -1, 3435, -1, 3437, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 3438, + -1, -1, -1, 3440, 3442, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 3443, + -1, 3444, -1, 3445, -1, -1, -1, -1, + -1, 3446, -1, -1, -1, 3447, -1, -1, + -1, -1, -1, -1, 3448, -1, -1, -1, + -1, -1, 3449, 3450, 3451, -1, -1, 3452, + 3453, -1, 3454, 3455, 3456, 3457, -1, -1, + 3458, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 3459, 3460, -1, -1, -1, -1, -1, + -1, -1, 3461, 3462, -1, -1, -1, -1, + 3463, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 3464, 3465, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 3466, 3467, -1, -1, 3469, -1, 3470, + /* 0x6400 */ + 3471, 3472, 3473, 3474, -1, 3475, 3478, -1, + -1, -1, -1, -1, -1, 3479, -1, -1, + -1, -1, 3480, -1, 3481, -1, 3482, 3484, + -1, -1, -1, -1, 3485, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 3487, -1, -1, -1, -1, 3488, -1, -1, + -1, -1, 3489, -1, -1, -1, 3490, -1, + -1, -1, 3491, -1, -1, -1, 3493, -1, + -1, -1, 3494, -1, 3496, 3498, 3499, 3501, + 3503, -1, 3504, -1, -1, -1, -1, -1, + -1, 3505, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 3506, -1, -1, 3507, + 3508, -1, -1, -1, -1, -1, -1, -1, + -1, 3511, -1, -1, -1, -1, -1, 3512, + -1, -1, -1, 3513, -1, -1, 3514, -1, + -1, -1, -1, 3515, -1, -1, -1, -1, + -1, -1, -1, 3516, 3518, -1, -1, -1, + 3519, -1, -1, -1, -1, -1, -1, 3520, + 3521, 3522, -1, 3523, -1, -1, -1, -1, + 3524, -1, 3525, -1, -1, -1, -1, 3526, + -1, 3527, -1, 3528, -1, 3529, 3531, 3532, + -1, -1, -1, 3535, -1, -1, -1, -1, + -1, -1, 3536, 3538, -1, 3539, -1, 3540, + 3541, 3542, 3545, 3546, -1, -1, 3547, 3548, + -1, 3549, -1, -1, 3550, -1, -1, 3551, + 3553, -1, 3555, 3557, -1, 3558, -1, -1, + -1, 3559, -1, -1, 3560, 3561, -1, -1, + -1, -1, 3563, -1, -1, -1, 3565, -1, + 3566, 3567, -1, 3568, -1, 3569, -1, 3570, + -1, -1, -1, -1, 3573, -1, -1, 3574, + 3575, 3576, 3577, -1, 3578, 3581, -1, 3582, + -1, -1, 3584, 3585, 3586, 3587, 3588, -1, + /* 0x6500 */ + 3589, -1, -1, -1, 3590, 3591, 3592, -1, + 3593, -1, 3594, -1, -1, -1, -1, 3595, + -1, -1, 3596, -1, 3597, -1, 3598, -1, + -1, 3599, -1, 3600, 3601, 3603, -1, 3605, + -1, -1, 3606, 3608, 3609, -1, -1, -1, + 3610, -1, 3611, 3614, 3615, -1, -1, -1, + -1, -1, -1, -1, 3617, 3618, 3619, 3620, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 3621, + 3625, 3628, -1, -1, 3629, 3630, 3632, 3633, + -1, -1, -1, -1, -1, 3634, -1, 3636, + 3638, 3640, -1, 3641, -1, -1, 3643, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 3644, -1, -1, -1, -1, -1, -1, + 3649, -1, -1, -1, -1, 3650, -1, 3651, + 3652, -1, 3653, -1, -1, -1, -1, -1, + -1, 3657, 3658, 3660, -1, 3661, 3666, -1, + 3671, 3676, 3680, 3684, 3686, 3688, 3689, -1, + -1, -1, -1, 3691, 3692, 3694, -1, 3695, + -1, -1, -1, -1, -1, -1, 3700, 3702, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 3703, -1, -1, 3704, 3705, -1, -1, + -1, -1, 3706, -1, -1, 3707, -1, 3708, + -1, -1, -1, -1, 3709, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 3712, 3713, -1, -1, -1, -1, -1, -1, + -1, -1, 3714, -1, -1, -1, -1, 3715, + 3717, 3719, -1, 3721, -1, -1, -1, -1, + 3722, -1, -1, -1, -1, 3723, -1, 3724, + -1, -1, 3725, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 3728, 3730, + 3733, 3734, 3736, -1, -1, -1, 3737, 3738, + /* 0x6600 */ + -1, -1, 3739, -1, -1, -1, -1, 3740, + -1, -1, 3742, -1, -1, -1, 3743, 3744, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 3745, 3746, -1, -1, -1, -1, 3747, + -1, -1, -1, -1, -1, 3748, 3749, -1, + -1, -1, -1, -1, 3750, 3751, -1, 3752, + 3753, -1, -1, -1, -1, -1, -1, -1, + 3754, -1, -1, 3755, 3756, 3758, 3759, 3761, + -1, -1, 3763, 3765, 3766, -1, -1, -1, + -1, 3767, -1, 3768, -1, -1, -1, -1, + -1, -1, 3769, 3770, 3772, 3773, 3774, -1, + -1, -1, 3775, -1, -1, 3776, -1, 3778, + 3779, -1, -1, -1, 3780, -1, -1, -1, + 3781, 3782, -1, -1, -1, -1, 3783, -1, + -1, -1, -1, -1, 3784, -1, -1, -1, + -1, -1, -1, 3786, -1, -1, -1, -1, + 3787, 3788, 3790, 3791, -1, -1, -1, -1, + 3793, 3794, -1, -1, -1, -1, -1, -1, + -1, -1, 3795, -1, -1, -1, 3796, 3798, + 3803, -1, -1, -1, 3804, -1, -1, -1, + -1, -1, 3805, -1, 3806, -1, 3809, 3812, + 3813, -1, -1, 3814, -1, 3815, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 3817, -1, -1, -1, -1, -1, -1, -1, + -1, 3819, -1, -1, 3820, -1, 3821, 3825, + -1, 3826, -1, -1, 3828, 3832, -1, 3833, + -1, -1, -1, -1, -1, -1, 3834, -1, + -1, -1, -1, -1, -1, -1, -1, 3835, + 3836, -1, -1, -1, -1, -1, -1, -1, + 3838, -1, -1, -1, 3839, -1, -1, -1, + -1, -1, 3840, 3845, -1, 3846, -1, -1, + 3847, 3850, 3851, 3852, -1, 3854, 3855, -1, + /* 0x6700 */ + 3856, -1, 3857, 3859, -1, -1, -1, 3860, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 3861, 3862, + -1, 3863, -1, 3864, -1, -1, 3865, 3866, + -1, -1, 3867, -1, -1, -1, -1, 3868, + -1, -1, -1, -1, 3869, 3871, 3872, 3873, + -1, 3875, -1, -1, 3876, 3878, 3879, -1, + -1, -1, 3880, -1, -1, -1, -1, -1, + 3882, -1, 3883, 3886, -1, -1, 3888, 3889, + -1, 3890, -1, -1, -1, -1, -1, -1, + -1, 3893, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 3894, 3895, -1, -1, 3896, 3897, 3898, -1, + 3899, 3900, -1, -1, -1, -1, -1, 3901, + 3903, 3904, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 3905, 3911, + 3912, 3917, -1, -1, 3918, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 3920, + -1, -1, 3921, -1, -1, -1, -1, -1, + -1, 3925, -1, -1, 3928, -1, 3929, -1, + -1, 3930, 3931, 3932, -1, 3933, 3934, 3935, + 3936, 3937, 3942, 3945, -1, 3946, -1, -1, + -1, 3947, -1, -1, 3950, -1, -1, -1, + -1, -1, -1, 3952, -1, -1, -1, -1, + -1, 3953, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 3954, + -1, -1, -1, -1, -1, 3955, -1, 3956, + -1, -1, -1, -1, 3961, -1, -1, -1, + 3962, -1, -1, -1, -1, 3963, -1, -1, + -1, 3964, -1, -1, -1, -1, -1, -1, + 3966, -1, -1, 3967, -1, 3970, -1, -1, + -1, 3971, 3972, 3974, -1, 3975, 3976, 3978, + /* 0x6800 */ + 3979, 3980, -1, 3983, 3985, 3987, -1, 3988, + 3989, 3991, 3992, 3994, 3995, -1, 3997, 3999, + -1, 4001, -1, -1, -1, -1, 4002, 4004, + -1, -1, -1, -1, -1, -1, 4006, -1, + -1, -1, 4007, -1, -1, -1, -1, 4008, + -1, -1, -1, -1, -1, -1, -1, -1, + 4009, -1, -1, -1, -1, -1, -1, 4011, + 4013, -1, -1, -1, -1, -1, 4014, -1, + -1, -1, 4016, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 4017, -1, -1, -1, + -1, 4019, 4020, -1, -1, -1, -1, -1, + 4021, -1, -1, -1, 4022, 4024, -1, 4025, + 4027, 4030, 4031, 4032, 4033, 4034, 4036, 4037, + 4038, 4039, 4040, -1, -1, -1, 4041, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4043, 4044, -1, 4047, -1, -1, 4048, + -1, 4049, -1, -1, 4051, 4052, -1, -1, + -1, -1, -1, -1, -1, 4054, -1, -1, + -1, -1, -1, -1, 4056, -1, -1, -1, + 4057, -1, -1, -1, -1, 4058, -1, 4059, + -1, -1, -1, -1, -1, 4060, 4065, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4067, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 4069, -1, 4070, 4071, + 4072, -1, 4074, -1, 4075, -1, -1, -1, + -1, -1, 4076, 4080, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 4084, 4085, 4086, + -1, -1, -1, -1, -1, -1, -1, 4087, + -1, -1, -1, -1, -1, 4088, -1, 4089, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4091, 4092, -1, -1, -1, 4094, -1, + -1, 4095, -1, -1, -1, -1, -1, -1, + /* 0x6900 */ + 4096, 4097, -1, -1, -1, -1, -1, -1, + -1, 4098, -1, -1, -1, -1, 4100, 4101, + -1, -1, -1, -1, -1, -1, -1, 4104, + 4106, 4107, -1, -1, 4108, -1, -1, 4110, + 4111, -1, 4112, -1, 4113, -1, -1, -1, + -1, -1, -1, 4114, -1, 4115, -1, -1, + 4116, -1, -1, -1, 4117, -1, 4118, -1, + -1, 4119, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 4120, -1, -1, 4121, -1, -1, + -1, -1, -1, 4123, -1, 4124, -1, -1, + -1, 4125, 4126, -1, -1, -1, -1, -1, + 4127, 4128, -1, -1, -1, 4129, 4130, -1, + 4131, -1, 4132, 4133, -1, 4134, -1, -1, + -1, -1, -1, 4135, -1, 4137, -1, -1, + -1, -1, -1, -1, 4138, 4139, -1, 4141, + -1, -1, -1, -1, 4142, 4143, 4144, 4145, + 4146, 4147, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 4149, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 4150, -1, + 4152, -1, 4153, -1, -1, -1, 4154, -1, + -1, -1, 4156, -1, 4157, -1, -1, -1, + -1, -1, -1, -1, 4158, -1, -1, 4159, + -1, -1, -1, -1, -1, -1, -1, 4160, + 4161, -1, -1, 4163, -1, 4164, -1, -1, + -1, 4165, -1, 4167, 4168, 4170, -1, 4172, + 4174, 4176, 4177, 4178, -1, -1, 4180, 4181, + 4182, -1, -1, -1, 4183, -1, -1, 4184, + 4185, -1, -1, -1, -1, -1, -1, -1, + -1, 4186, -1, 4187, -1, -1, 4188, -1, + -1, 4189, -1, -1, -1, -1, -1, -1, + /* 0x6a00 */ + -1, 4190, 4191, 4193, -1, 4194, -1, -1, + -1, -1, 4195, -1, -1, -1, -1, -1, + 4196, 4197, 4199, 4200, -1, -1, -1, -1, + -1, 4201, -1, -1, -1, -1, 4202, -1, + -1, -1, -1, 4203, -1, -1, -1, -1, + -1, 4205, 4207, -1, -1, -1, -1, 4209, + -1, 4211, -1, 4213, -1, -1, -1, 4214, + 4218, 4220, 4221, -1, -1, 4222, -1, 4223, + -1, -1, -1, 4224, -1, -1, -1, -1, + 4226, -1, 4227, 4228, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 4230, + -1, -1, 4231, -1, -1, -1, -1, -1, + -1, -1, -1, 4233, -1, -1, 4235, -1, + 4238, 4239, -1, -1, -1, -1, -1, -1, + -1, 4240, -1, -1, 4243, -1, -1, -1, + -1, 4244, -1, 4245, -1, -1, 4246, -1, + -1, 4247, -1, -1, -1, -1, -1, 4248, + 4250, -1, -1, -1, 4251, -1, -1, 4252, + 4254, -1, -1, -1, 4255, 4256, -1, 4257, + -1, -1, 4258, 4260, -1, -1, -1, -1, + -1, 4261, 4262, -1, -1, -1, 4264, 4265, + -1, 4267, -1, 4271, -1, -1, -1, -1, + 4272, -1, -1, 4273, -1, -1, -1, -1, + 4274, 4278, 4279, 4280, -1, -1, -1, -1, + 4281, -1, -1, -1, 4282, -1, 4283, -1, + -1, -1, -1, 4285, 4287, 4288, -1, -1, + -1, -1, 4289, 4290, -1, 4291, 4292, 4293, + -1, -1, -1, -1, -1, 4295, -1, 4296, + 4297, -1, 4298, -1, 4299, -1, -1, -1, + -1, -1, -1, 4300, -1, -1, -1, -1, + 4301, -1, 4302, 4303, -1, 4305, -1, -1, + /* 0x6b00 */ + -1, -1, -1, -1, 4306, 4308, -1, -1, + -1, 4309, 4313, -1, -1, -1, -1, 4315, + -1, 4316, 4317, -1, -1, -1, 4319, 4320, + -1, -1, -1, -1, -1, 4322, 4325, -1, + 4327, -1, 4329, 4333, 4336, -1, -1, 4337, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 4338, -1, -1, 4339, -1, -1, + -1, -1, -1, 4340, -1, 4341, 4342, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 4343, -1, 4344, -1, + 4346, -1, -1, 4347, -1, -1, 4349, -1, + 4352, -1, -1, 4353, -1, 4355, -1, 4356, + -1, 4357, -1, -1, -1, 4359, -1, -1, + 4361, 4363, -1, -1, 4365, -1, 4366, 4369, + -1, -1, 4371, 4375, 4379, -1, -1, 4382, + 4385, 4388, 4389, -1, 4390, -1, 4392, 4396, + 4400, 4401, -1, -1, -1, -1, -1, 4405, + -1, -1, -1, 4406, -1, -1, -1, -1, + -1, -1, 4407, 4408, -1, -1, -1, -1, + 4409, -1, 4410, -1, -1, -1, 4411, -1, + -1, 4412, -1, -1, 4413, -1, -1, -1, + -1, -1, -1, 4414, -1, -1, 4415, 4416, + -1, 4417, 4419, -1, 4421, -1, -1, 4422, + -1, -1, 4423, 4424, 4426, -1, -1, -1, + 4428, 4429, 4432, -1, -1, -1, 4433, -1, + -1, 4434, -1, -1, -1, -1, 4436, 4437, + -1, -1, -1, 4438, 4440, 4441, -1, 4442, + 4443, 4444, -1, -1, -1, -1, -1, 4445, + -1, 4446, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 4447, -1, 4448, -1, + -1, -1, -1, -1, -1, 4449, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 4450, + /* 0x6c00 */ + -1, -1, 4451, -1, -1, -1, -1, 4453, + 4454, -1, 4456, -1, 4457, -1, -1, -1, + -1, -1, -1, -1, 4458, -1, -1, 4461, + -1, -1, -1, 4464, -1, -1, -1, -1, + -1, -1, 4465, 4466, -1, -1, -1, -1, + -1, 4469, -1, 4470, 4471, -1, -1, -1, + -1, -1, 4472, 4473, 4474, 4476, -1, 4478, + -1, -1, 4481, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 4483, + -1, 4487, -1, -1, -1, -1, 4488, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4489, 4491, -1, -1, -1, -1, -1, + -1, 4493, -1, -1, 4495, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 4496, 4497, -1, -1, -1, + -1, 4498, 4499, 4500, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 4501, 4503, -1, -1, -1, -1, -1, -1, + -1, -1, 4504, -1, -1, -1, 4505, 4506, + -1, -1, -1, -1, -1, -1, -1, 4507, + -1, 4508, 4513, 4515, 4516, 4517, 4518, 4519, + 4520, 4521, 4522, -1, -1, -1, 4524, -1, + -1, 4525, 4526, -1, -1, 4527, -1, -1, + -1, -1, -1, -1, -1, -1, 4528, -1, + -1, 4529, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 4530, -1, -1, + -1, -1, -1, 4532, -1, 4533, 4534, -1, + -1, -1, -1, -1, -1, 4535, -1, -1, + 4536, -1, 4537, -1, -1, -1, -1, 4539, + 4540, -1, -1, -1, -1, -1, 4541, 4542, + 4544, -1, 4545, 4546, 4547, 4550, 4552, -1, + /* 0x6d00 */ + -1, 4553, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 4554, -1, -1, -1, + -1, -1, 4555, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 4556, + -1, -1, -1, -1, -1, -1, 4557, -1, + -1, -1, -1, -1, 4558, -1, -1, -1, + 4559, -1, -1, 4560, 4561, 4562, 4563, 4564, + 4565, 4566, 4567, 4568, -1, 4569, 4570, 4572, + 4574, 4575, 4576, 4577, 4578, 4579, -1, -1, + -1, -1, -1, -1, 4580, -1, -1, -1, + -1, -1, -1, 4583, -1, -1, -1, 4584, + -1, 4587, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4588, -1, -1, 4589, -1, -1, -1, + -1, -1, 4590, -1, -1, 4592, -1, 4593, + -1, 4594, -1, -1, 4595, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 4596, -1, + -1, 4598, -1, 4600, 4601, 4603, 4604, 4605, + 4606, 4607, 4608, 4609, 4610, -1, 4611, 4612, + 4614, 4615, -1, -1, -1, -1, -1, 4619, + -1, -1, -1, -1, -1, -1, -1, -1, + 4620, -1, -1, -1, 4621, -1, -1, -1, + 4622, -1, -1, -1, 4623, -1, -1, -1, + -1, -1, -1, 4624, -1, -1, -1, -1, + -1, -1, 4625, -1, -1, -1, -1, -1, + -1, -1, 4626, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 4628, -1, -1, + 4629, -1, 4631, 4632, -1, -1, -1, -1, + -1, -1, -1, 4634, -1, 4635, 4638, -1, + 4639, -1, 4640, 4641, -1, -1, -1, -1, + /* 0x6e00 */ + -1, -1, -1, -1, -1, 4642, -1, 4643, + 4644, 4646, 4647, 4650, 4654, 4655, 4656, -1, + 4658, 4659, -1, 4660, 4664, 4665, 4668, 4669, + -1, 4670, -1, 4671, -1, -1, -1, -1, + -1, -1, 4672, -1, -1, -1, 4673, -1, + -1, 4674, -1, -1, 4675, -1, -1, -1, + -1, -1, -1, -1, 4676, -1, -1, -1, + 4677, -1, -1, -1, -1, -1, 4679, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 4680, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 4681, -1, + -1, -1, -1, -1, -1, -1, -1, 4682, + -1, -1, -1, -1, -1, -1, -1, 4683, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 4684, 4685, 4686, 4687, 4688, + 4690, 4692, 4693, 4694, -1, 4695, -1, 4696, + -1, 4697, -1, -1, 4698, -1, -1, -1, + 4701, -1, -1, -1, -1, 4702, 4704, -1, + -1, -1, -1, -1, 4706, 4707, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 4708, 4712, -1, -1, 4713, 4714, + -1, -1, -1, 4716, -1, -1, 4717, -1, + -1, -1, -1, -1, 4719, -1, -1, -1, + -1, -1, -1, -1, 4721, 4722, -1, -1, + -1, -1, -1, -1, 4723, -1, 4724, -1, + -1, -1, -1, -1, -1, -1, -1, 4725, + -1, 4726, 4728, 4729, -1, 4730, 4732, 4733, + 4736, 4737, 4739, -1, 4740, 4741, 4742, -1, + 4743, 4746, 4747, -1, 4748, -1, -1, 4750, + -1, -1, 4751, -1, -1, -1, -1, 4752, + 4755, -1, -1, 4757, -1, -1, 4758, 4759, + /* 0x6f00 */ + -1, 4761, -1, -1, 4762, -1, 4763, -1, + -1, -1, 4764, -1, -1, -1, -1, -1, + -1, 4765, -1, 4766, -1, -1, -1, -1, + -1, -1, 4767, -1, -1, -1, -1, -1, + -1, -1, 4768, 4769, -1, -1, -1, 4770, + -1, -1, -1, 4773, 4774, -1, -1, -1, + -1, 4775, 4776, -1, -1, -1, -1, -1, + 4777, -1, -1, -1, -1, -1, -1, 4778, + -1, 4779, -1, -1, 4780, 4781, 4782, 4783, + -1, -1, -1, 4784, -1, 4785, -1, -1, + -1, 4786, -1, -1, 4789, -1, -1, -1, + -1, 4791, -1, 4792, 4794, -1, -1, -1, + -1, -1, -1, -1, 4796, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 4797, + 4798, -1, -1, -1, 4799, -1, -1, 4800, + -1, -1, -1, -1, -1, -1, -1, 4801, + 4802, 4806, 4810, -1, 4813, -1, 4816, 4817, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4818, -1, -1, 4819, -1, -1, 4820, + -1, -1, 4821, 4822, 4825, -1, -1, 4826, + 4828, -1, -1, 4829, 4830, -1, 4832, -1, + -1, 4833, -1, -1, -1, -1, 4834, -1, + 4835, 4836, -1, 4837, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4838, -1, 4839, -1, -1, -1, 4840, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 4841, 4843, -1, 4844, 4845, -1, -1, + 4847, -1, 4848, 4850, 4852, -1, -1, 4853, + -1, -1, -1, -1, 4855, -1, -1, -1, + -1, -1, -1, 4856, -1, -1, -1, -1, + 4857, 4858, -1, 4861, -1, 4863, 4866, -1, + -1, -1, 4868, -1, 4869, -1, 4870, -1, + /* 0x7000 */ + -1, -1, 4871, -1, -1, 4874, 4875, -1, + -1, 4877, -1, 4878, -1, -1, -1, 4880, + -1, -1, -1, 4881, -1, 4884, -1, -1, + 4885, -1, -1, -1, -1, 4886, -1, 4887, + 4888, -1, -1, -1, -1, -1, 4889, 4890, + 4892, -1, -1, -1, 4894, -1, -1, 4896, + 4897, -1, 4898, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 4900, -1, + -1, -1, -1, 4901, 4902, -1, -1, -1, + -1, -1, -1, 4903, 4905, -1, 4906, 4908, + -1, 4909, -1, -1, 4910, 4912, -1, -1, + 4913, -1, -1, -1, -1, 4914, -1, -1, + -1, -1, -1, 4915, 4916, -1, -1, 4917, + -1, -1, -1, -1, -1, 4918, 4919, 4921, + -1, -1, -1, -1, -1, 4922, 4925, -1, + -1, -1, -1, 4927, -1, 4929, 4931, 4933, + 4934, 4935, -1, -1, -1, -1, -1, -1, + -1, 4938, -1, -1, -1, 4941, 4943, 4944, + -1, -1, -1, -1, -1, -1, -1, 4945, + -1, -1, -1, -1, 4947, 4948, -1, -1, + -1, -1, -1, -1, 4949, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 4954, 4957, + 4958, -1, -1, -1, -1, -1, -1, -1, + -1, 4959, 4960, -1, 4962, 4965, -1, -1, + -1, 4966, 4967, 4970, -1, -1, -1, -1, + -1, -1, 4971, -1, -1, -1, -1, 4972, + -1, -1, -1, -1, -1, -1, 4973, -1, + -1, -1, -1, 4975, -1, -1, -1, 4976, + -1, -1, -1, -1, -1, -1, 4977, 4978, + 4980, 4982, -1, 4983, 4984, 4985, -1, -1, + -1, 4986, -1, -1, 4987, -1, -1, -1, + -1, -1, -1, -1, -1, 4988, 4989, -1, + /* 0x7100 */ + -1, -1, -1, -1, -1, -1, -1, 4991, + 4992, -1, 4996, -1, -1, -1, -1, 4997, + -1, -1, -1, -1, 4998, 5000, 5001, -1, + 5002, -1, 5003, -1, -1, -1, -1, -1, + -1, 5005, -1, -1, -1, -1, 5006, -1, + -1, -1, -1, -1, -1, 5007, -1, -1, + 5008, -1, -1, 5010, -1, -1, -1, -1, + -1, -1, -1, -1, 5011, -1, -1, -1, + -1, -1, -1, -1, -1, 5013, -1, -1, + -1, 5014, -1, -1, -1, -1, -1, -1, + -1, 5017, 5018, -1, -1, 5019, 5023, 5024, + -1, 5025, -1, -1, -1, -1, -1, -1, + -1, -1, 5026, -1, -1, 5028, -1, 5029, + -1, 5033, -1, -1, 5034, -1, 5036, -1, + -1, -1, -1, -1, 5037, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 5039, -1, + -1, -1, -1, -1, -1, 5041, -1, -1, + 5043, -1, -1, -1, -1, -1, -1, 5047, + -1, -1, 5048, -1, 5049, -1, -1, 5051, + -1, 5052, -1, -1, -1, -1, -1, -1, + -1, -1, 5056, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 5057, 5058, 5059, -1, -1, -1, -1, + -1, 5060, 5061, -1, -1, -1, 5062, -1, + -1, 5063, -1, -1, 5065, -1, -1, -1, + 5067, -1, -1, -1, 5068, -1, 5070, -1, + 5071, -1, 5073, 5075, -1, 5077, -1, 5078, + -1, 5081, -1, -1, 5082, -1, -1, 5083, + -1, -1, -1, -1, -1, -1, 5085, -1, + -1, -1, -1, -1, 5086, 5087, -1, -1, + -1, -1, -1, 5088, 5092, -1, -1, -1, + -1, -1, -1, 5093, 5094, -1, 5095, 5096, + /* 0x7200 */ + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 5097, -1, -1, + 5098, -1, -1, -1, -1, -1, -1, 5099, + -1, -1, -1, 5101, -1, -1, -1, -1, + -1, -1, -1, -1, 5104, -1, -1, -1, + -1, -1, -1, -1, -1, 5107, -1, -1, + -1, 5108, 5109, -1, 5111, -1, -1, 5112, + -1, -1, 5113, -1, 5114, -1, 5115, 5118, + 5119, -1, -1, 5120, -1, 5121, 5122, -1, + -1, -1, -1, 5123, -1, 5124, 5125, -1, + -1, -1, -1, 5129, -1, 5130, -1, -1, + 5134, -1, -1, 5135, 5136, -1, -1, -1, + 5137, -1, -1, -1, -1, -1, 5138, -1, + -1, -1, -1, 5140, -1, -1, -1, -1, + -1, -1, -1, -1, 5142, 5143, -1, -1, + -1, -1, 5144, -1, -1, 5146, -1, -1, + -1, 5147, 5148, -1, -1, -1, -1, 5149, + -1, -1, 5150, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 5151, -1, + -1, -1, -1, 5152, -1, -1, -1, -1, + 5154, -1, 5156, -1, -1, -1, -1, 5157, + -1, -1, -1, -1, 5159, 5160, 5161, -1, + -1, -1, 5162, -1, 5163, -1, 5165, 5166, + 5167, 5168, -1, -1, -1, -1, -1, -1, + 5169, -1, 5170, -1, -1, -1, -1, -1, + 5172, 5173, -1, -1, 5174, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 5175, 5176, -1, + -1, -1, 5177, -1, -1, 5178, -1, -1, + -1, -1, -1, -1, 5179, 5180, 5181, 5182, + 5183, 5184, 5185, -1, -1, -1, -1, -1, + 5186, 5188, -1, -1, -1, 5189, 5190, -1, + /* 0x7300 */ + -1, -1, 5191, 5192, -1, -1, -1, 5193, + -1, -1, 5194, -1, -1, 5195, 5197, -1, + -1, -1, -1, -1, -1, 5199, -1, -1, + 5200, 5201, -1, -1, -1, -1, -1, 5202, + -1, 5204, -1, -1, -1, -1, -1, -1, + 5205, 5206, 5207, 5208, 5209, -1, 5210, 5211, + -1, -1, 5212, -1, -1, 5213, 5214, -1, + -1, -1, -1, 5215, -1, -1, -1, 5216, + -1, 5218, -1, -1, 5219, 5220, -1, -1, + -1, -1, -1, -1, -1, 5221, 5222, 5225, + 5226, -1, -1, -1, -1, -1, -1, -1, + 5227, 5228, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 5229, -1, -1, 5231, -1, + 5232, -1, 5233, 5234, -1, 5236, 5237, -1, + 5238, 5239, 5240, -1, -1, 5241, -1, 5243, + 5244, -1, 5246, 5247, 5248, -1, 5249, -1, + 5250, 5251, -1, 5252, -1, 5254, -1, 5255, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 5256, -1, -1, -1, -1, -1, -1, + -1, 5257, 5258, 5259, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 5260, 5262, -1, -1, -1, -1, 5263, 5264, + 5265, 5266, -1, 5267, -1, -1, -1, -1, + -1, -1, 5268, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 5269, -1, 5272, 5273, 5274, + 5276, 5277, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 5278, -1, -1, 5280, -1, -1, -1, + -1, -1, 5284, -1, -1, -1, -1, -1, + 5285, 5286, 5288, -1, -1, -1, -1, 5289, + -1, -1, -1, -1, -1, -1, 5290, -1, + /* 0x7400 */ + -1, -1, -1, 5291, -1, 5292, -1, -1, + -1, 5293, -1, -1, -1, 5296, 5298, 5299, + 5300, 5302, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 5304, -1, -1, 5305, -1, -1, -1, + -1, 5307, 5309, -1, 5310, -1, -1, 5311, + -1, -1, -1, -1, -1, -1, -1, 5312, + -1, -1, -1, 5313, -1, -1, -1, -1, + -1, -1, 5314, -1, -1, -1, -1, -1, + -1, 5315, -1, -1, -1, -1, -1, -1, + 5316, -1, -1, 5319, 5321, -1, -1, -1, + 5322, 5323, 5324, -1, -1, -1, -1, 5325, + 5326, -1, 5327, -1, 5328, -1, 5330, 5331, + 5332, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 5333, -1, -1, -1, 5335, + -1, 5336, -1, -1, -1, -1, 5337, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 5339, 5341, 5344, -1, -1, 5345, -1, + -1, -1, -1, 5346, -1, -1, -1, -1, + 5347, -1, -1, -1, -1, 5348, -1, -1, + 5349, -1, -1, -1, -1, 5350, -1, 5352, + -1, -1, -1, -1, -1, -1, -1, -1, + 5353, 5355, 5356, -1, 5357, -1, -1, 5358, + -1, -1, 5359, -1, 5360, -1, -1, -1, + -1, -1, 5362, -1, -1, -1, -1, -1, + -1, -1, -1, 5364, -1, -1, -1, -1, + 5365, -1, -1, -1, -1, -1, 5366, 5367, + -1, -1, -1, -1, -1, -1, 5368, 5370, + -1, -1, -1, -1, -1, -1, -1, -1, + /* 0x7500 */ + -1, 5371, -1, -1, -1, -1, 5373, -1, + -1, -1, -1, -1, 5374, -1, 5375, -1, + -1, -1, -1, -1, -1, 5378, 5379, -1, + -1, -1, -1, -1, -1, -1, 5381, -1, + 5384, -1, 5385, 5387, -1, -1, 5389, -1, + -1, -1, -1, -1, -1, -1, -1, 5392, + -1, -1, -1, -1, -1, 5398, -1, 5399, + -1, -1, 5400, 5402, 5407, 5409, -1, -1, + -1, -1, 5410, -1, 5411, 5413, 5414, -1, + -1, -1, 5418, -1, 5419, 5421, 5423, -1, + -1, 5424, 5425, -1, -1, -1, -1, -1, + -1, 5429, 5431, -1, -1, 5432, 5437, -1, + 5441, 5442, 5443, -1, -1, 5444, -1, 5445, + 5446, -1, 5447, 5448, -1, -1, -1, -1, + 5450, 5451, -1, 5453, 5457, 5458, 5460, -1, + -1, -1, 5461, 5462, -1, -1, -1, -1, + -1, -1, 5463, -1, -1, 5467, 5469, 5470, + -1, 5471, 5475, -1, -1, -1, 5479, 5481, + -1, -1, -1, -1, -1, -1, 5483, 5484, + -1, -1, -1, -1, -1, -1, -1, 5485, + 5486, 5487, -1, 5488, -1, -1, -1, -1, + -1, -1, -1, -1, 5489, 5490, 5491, 5492, + -1, 5493, -1, -1, 5495, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 5496, + 5497, 5498, -1, -1, -1, -1, -1, -1, + -1, -1, 5499, -1, -1, -1, 5500, -1, + -1, 5504, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 5505, 5506, 5507, 5508, -1, -1, 5509, -1, + -1, -1, 5510, 5512, 5515, -1, -1, -1, + -1, 5516, 5517, -1, -1, -1, 5518, -1, + /* 0x7600 */ + -1, -1, 5519, -1, -1, 5523, 5524, -1, + -1, 5525, -1, 5527, -1, 5528, -1, -1, + -1, -1, -1, 5529, -1, -1, 5530, 5531, + 5532, -1, -1, -1, -1, -1, 5533, -1, + -1, 5534, -1, -1, 5535, -1, 5536, 5537, + -1, -1, 5538, 5539, -1, -1, 5540, -1, + -1, -1, 5541, -1, -1, -1, -1, -1, + -1, -1, 5542, 5543, -1, -1, 5545, 5546, + -1, -1, 5547, -1, 5548, 5550, 5551, 5552, + -1, 5553, -1, -1, -1, -1, -1, -1, + -1, -1, 5554, -1, -1, 5556, -1, -1, + 5558, -1, -1, -1, -1, -1, 5559, 5560, + -1, 5561, 5562, 5563, 5564, 5565, -1, 5566, + -1, 5567, -1, 5568, 5569, 5570, 5571, 5572, + 5573, 5576, 5577, -1, 5578, 5579, -1, -1, + -1, -1, 5580, 5590, 5591, -1, -1, -1, + -1, 5593, 5595, 5597, -1, -1, -1, -1, + 5598, -1, -1, 5601, -1, 5602, 5604, -1, + 5605, 5606, -1, -1, -1, -1, -1, -1, + -1, -1, 5607, -1, -1, -1, 5609, -1, + -1, 5610, -1, -1, -1, 5611, -1, -1, + 5613, -1, -1, -1, -1, -1, -1, -1, + 5614, 5616, 5617, -1, -1, -1, -1, 5619, + 5620, 5622, 5624, -1, 5625, -1, -1, -1, + -1, 5626, -1, 5627, -1, -1, -1, 5629, + 5630, -1, -1, 5631, 5634, 5635, -1, 5636, + 5637, 5639, -1, -1, -1, -1, 5641, 5643, + 5644, 5645, -1, -1, 5646, -1, 5647, -1, + -1, 5648, -1, 5649, 5651, -1, -1, 5652, + -1, -1, 5653, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + /* 0x7700 */ + -1, -1, -1, -1, -1, -1, 5655, -1, + -1, 5657, -1, -1, 5658, 5660, 5661, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 5663, -1, -1, -1, -1, -1, 5664, 5665, + -1, -1, -1, -1, -1, 5666, 5667, -1, + -1, -1, -1, 5668, 5669, -1, -1, 5670, + -1, -1, -1, -1, -1, -1, -1, 5672, + -1, -1, -1, -1, -1, -1, 5673, -1, + 5676, 5677, 5678, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 5679, + 5680, 5681, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 5682, -1, 5683, -1, + 5684, -1, -1, -1, 5685, 5686, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 5687, -1, -1, -1, -1, -1, 5688, + -1, -1, -1, -1, -1, 5690, 5691, 5692, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 5693, -1, -1, -1, 5694, -1, + 5695, -1, -1, -1, -1, -1, 5696, -1, + 5697, -1, 5698, -1, -1, -1, -1, -1, + -1, 5699, 5700, -1, -1, 5701, -1, -1, + 5703, -1, -1, -1, -1, -1, 5704, -1, + -1, -1, -1, -1, 5705, -1, 5706, -1, + -1, 5710, -1, -1, -1, -1, -1, 5711, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 5712, 5713, -1, -1, -1, -1, + -1, 5714, 5715, -1, -1, -1, -1, -1, + -1, -1, 5716, -1, 5717, -1, 5719, 5720, + -1, -1, -1, 5722, -1, -1, -1, 5723, + -1, -1, -1, -1, 5724, -1, 5727, -1, + -1, -1, -1, -1, -1, -1, 5728, 5729, + /* 0x7800 */ + 5734, 5735, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 5736, -1, -1, 5737, 5738, 5741, + -1, -1, 5742, -1, 5743, -1, -1, -1, + -1, -1, -1, -1, -1, 5744, -1, 5745, + -1, -1, -1, -1, 5746, -1, -1, -1, + -1, -1, 5747, -1, -1, -1, -1, -1, + -1, -1, 5750, 5751, -1, -1, 5752, 5753, + 5758, 5759, -1, 5760, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 5761, 5762, 5763, + -1, 5764, 5765, -1, 5766, -1, -1, -1, + -1, -1, -1, -1, 5767, -1, -1, -1, + 5768, -1, 5769, -1, -1, -1, 5770, 5773, + -1, -1, -1, -1, -1, 5774, -1, 5775, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 5778, -1, -1, -1, -1, -1, 5782, + -1, -1, -1, -1, -1, 5784, 5785, -1, + -1, -1, -1, -1, 5786, 5787, -1, 5790, + -1, -1, -1, 5793, 5794, -1, 5795, 5798, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 5799, 5800, -1, -1, 5801, -1, 5802, + 5803, 5805, -1, -1, -1, -1, -1, -1, + 5807, -1, 5808, 5810, 5812, -1, -1, -1, + -1, 5813, -1, -1, -1, -1, -1, 5814, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 5815, 5816, -1, 5817, -1, 5818, -1, + -1, -1, 5819, -1, -1, -1, -1, -1, + 5822, -1, -1, 5823, -1, -1, -1, 5824, + -1, -1, -1, -1, -1, -1, -1, 5825, + -1, -1, -1, -1, -1, -1, -1, 5826, + 5827, -1, 5828, -1, -1, 5829, -1, -1, + /* 0x7900 */ + 5830, -1, -1, -1, 5831, -1, 5832, -1, + 5835, -1, -1, -1, -1, -1, 5837, -1, + -1, -1, 5838, -1, -1, -1, -1, -1, + -1, 5839, -1, -1, -1, -1, -1, 5840, + 5843, -1, -1, -1, -1, -1, 5844, -1, + -1, -1, 5849, 5850, 5851, -1, 5852, -1, + -1, 5855, -1, -1, -1, -1, -1, -1, + -1, -1, 5856, 5857, 5858, -1, -1, 5859, + 5860, -1, -1, 5861, -1, 5862, -1, -1, + -1, -1, -1, -1, -1, -1, 5863, -1, + -1, -1, -1, -1, -1, 5864, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 5865, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 5866, + -1, -1, -1, -1, -1, 5867, -1, 5868, + 5869, -1, -1, -1, -1, -1, -1, 5870, + 5871, -1, -1, -1, 5872, 5873, -1, -1, + -1, -1, -1, -1, -1, 5874, 5875, -1, + -1, -1, -1, -1, -1, 5876, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 5877, -1, -1, -1, -1, 5878, -1, + -1, 5879, 5880, -1, -1, -1, 5881, -1, + 5882, 5883, -1, -1, 5884, -1, -1, -1, + -1, -1, -1, 5885, -1, -1, -1, 5886, + -1, 5887, -1, 5888, -1, -1, 5889, 5890, + 5895, -1, 5896, 5897, 5902, 5905, -1, -1, + 5906, -1, -1, -1, 5907, 5909, 5910, 5911, + 5912, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 5913, + 5914, -1, -1, -1, -1, -1, -1, -1, + 5916, -1, -1, -1, -1, 5917, 5918, -1, + /* 0x7a00 */ + -1, 5919, -1, -1, -1, 5923, 5924, -1, + 5926, 5927, -1, -1, -1, -1, 5929, -1, + -1, -1, -1, -1, -1, -1, -1, 5930, + -1, -1, 5932, -1, 5934, -1, -1, 5935, + -1, -1, -1, 5936, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 5937, 5938, -1, + -1, 5939, 5941, 5942, -1, -1, -1, -1, + -1, -1, 5944, 5946, -1, -1, 5947, 5951, + 5955, -1, 5957, -1, -1, 5958, -1, -1, + -1, 5960, -1, -1, 5962, 5966, 5967, 5969, + 5971, 5974, -1, -1, -1, -1, -1, 5975, + -1, -1, -1, -1, -1, -1, 5976, -1, + 5978, 5979, 5980, 5981, -1, -1, -1, -1, + 5982, 5986, 5988, 5990, -1, 5991, -1, -1, + 5993, -1, -1, -1, -1, -1, -1, 5994, + -1, 5996, -1, -1, -1, 5997, -1, -1, + -1, 5998, -1, 5999, -1, -1, -1, -1, + -1, -1, 6000, -1, -1, 6001, 6002, -1, + -1, 6003, -1, 6005, -1, -1, -1, 6009, + -1, -1, -1, -1, 6013, 6014, -1, -1, + -1, -1, -1, -1, -1, 6015, 6016, -1, + -1, 6017, 6018, -1, 6019, 6020, 6022, 6024, + 6026, -1, -1, 6028, -1, 6029, 6030, -1, + -1, -1, 6032, 6033, -1, -1, -1, -1, + -1, -1, -1, 6037, 6039, 6040, 6041, 6043, + 6044, -1, 6046, -1, -1, -1, -1, -1, + -1, -1, 6047, -1, -1, -1, 6048, -1, + -1, -1, 6050, -1, 6051, 6053, 6056, -1, + -1, -1, 6058, -1, -1, -1, -1, -1, + -1, 6059, 6061, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 6063, -1, + 6065, -1, -1, -1, -1, -1, 6067, -1, + /* 0x7b00 */ + -1, -1, -1, 6068, -1, -1, -1, -1, + -1, -1, -1, 6069, -1, -1, -1, -1, + -1, 6071, -1, -1, 6073, 6074, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 6075, + -1, -1, -1, -1, -1, -1, -1, 6076, + 6082, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 6083, 6085, -1, + -1, -1, 6086, -1, 6088, -1, 6090, -1, + -1, -1, -1, -1, -1, 6091, 6092, -1, + -1, -1, -1, 6093, -1, 6094, -1, 6096, + 6098, 6099, -1, -1, -1, -1, 6100, -1, + 6104, 6105, 6106, 6107, 6108, 6109, 6110, -1, + -1, -1, -1, -1, -1, -1, -1, 6114, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 6115, -1, -1, -1, -1, -1, -1, + -1, 6116, 6117, -1, 6118, -1, 6119, 6122, + 6123, -1, 6124, -1, -1, -1, 6125, 6126, + -1, -1, -1, 6129, -1, 6130, -1, 6131, + -1, -1, 6132, 6133, -1, -1, -1, -1, + -1, -1, 6134, -1, -1, -1, -1, -1, + -1, -1, -1, 6135, -1, -1, 6139, 6141, + 6142, 6143, 6144, 6145, 6146, -1, -1, -1, + 6147, -1, 6149, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 6150, -1, -1, -1, 6151, -1, 6153, -1, + -1, 6154, -1, 6155, -1, -1, -1, 6157, + -1, 6158, -1, 6159, 6160, -1, -1, 6161, + -1, -1, -1, 6162, -1, -1, -1, -1, + 6163, 6165, -1, -1, 6166, -1, 6167, -1, + -1, 6168, 6171, -1, -1, 6172, 6174, 6175, + -1, 6176, 6177, 6178, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + /* 0x7c00 */ + 6179, 6181, -1, -1, 6183, -1, 6185, -1, + -1, -1, -1, -1, -1, 6186, -1, -1, + -1, 6187, 6189, -1, 6190, -1, 6192, 6193, + 6195, -1, -1, -1, -1, -1, 6196, -1, + 6197, 6198, -1, 6199, -1, -1, -1, -1, + -1, -1, 6200, 6201, -1, -1, -1, -1, + -1, 6203, -1, -1, -1, -1, -1, 6205, + -1, 6206, -1, -1, -1, 6207, 6208, -1, + 6209, 6211, -1, 6212, -1, -1, 6213, -1, + -1, -1, -1, -1, 6214, -1, -1, 6215, + 6217, -1, 6218, -1, 6219, 6221, 6222, -1, + 6224, 6226, -1, 6227, 6228, -1, -1, 6229, + 6230, -1, -1, -1, 6232, -1, -1, -1, + -1, 6234, 6235, -1, 6236, 6237, 6239, -1, + -1, -1, 6240, -1, 6242, -1, -1, -1, + -1, -1, -1, 6243, 6244, -1, -1, -1, + -1, -1, -1, 6245, -1, -1, -1, 6246, + -1, -1, -1, 6248, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 6249, + 6250, -1, -1, 6251, 6253, 6254, -1, -1, + -1, -1, -1, -1, 6255, 6256, 6258, 6259, + -1, -1, 6263, -1, 6264, -1, 6268, -1, + -1, -1, -1, 6269, -1, 6271, -1, -1, + -1, 6272, 6273, -1, -1, 6274, -1, -1, + -1, 6275, -1, -1, -1, -1, 6276, 6281, + -1, 6282, 6283, -1, -1, -1, -1, -1, + -1, -1, -1, 6284, -1, 6286, -1, -1, + -1, -1, 6287, -1, -1, 6291, 6292, -1, + 6293, -1, -1, -1, -1, -1, 6295, 6296, + -1, -1, -1, -1, -1, -1, -1, -1, + 6297, -1, 6299, -1, 6300, -1, 6301, -1, + 6302, 6306, 6308, 6309, 6313, -1, 6315, 6317, + /* 0x7d00 */ + 6319, -1, 6320, -1, 6321, 6322, 6323, 6324, + 6325, 6326, -1, 6327, -1, 6328, -1, -1, + 6329, -1, -1, 6330, 6331, 6332, 6333, 6334, + 6335, 6337, 6339, 6340, 6341, 6342, -1, -1, + -1, 6344, -1, 6345, -1, 6346, -1, 6347, + -1, -1, -1, -1, 6348, -1, 6350, 6352, + 6356, 6357, 6358, 6359, -1, 6360, -1, -1, + -1, 6361, 6362, -1, 6363, -1, -1, 6364, + 6365, -1, 6366, 6367, 6368, 6369, 6370, -1, + 6372, -1, -1, 6373, 6374, 6376, 6377, 6378, + 6379, -1, -1, -1, -1, 6380, 6383, -1, + -1, -1, 6384, 6385, -1, 6387, 6389, -1, + -1, 6390, 6391, -1, 6392, 6396, 6397, -1, + 6398, -1, -1, -1, -1, -1, -1, -1, + 6399, 6400, 6402, 6404, -1, 6405, 6407, 6410, + 6411, 6413, -1, -1, -1, -1, -1, -1, + -1, 6414, 6415, 6417, -1, -1, 6418, -1, + 6419, 6420, -1, 6421, 6422, -1, -1, 6423, + -1, 6424, -1, 6426, -1, -1, -1, 6428, + -1, 6429, 6431, -1, 6434, -1, 6435, -1, + 6436, -1, 6438, 6440, -1, -1, -1, -1, + -1, -1, -1, 6441, 6445, 6446, -1, 6447, + 6448, 6449, 6450, 6451, 6453, 6455, -1, 6456, + 6457, 6458, 6459, 6460, -1, 6461, 6463, 6464, + -1, -1, -1, -1, 6465, -1, -1, 6466, + -1, -1, 6467, 6468, -1, 6469, -1, 6470, + 6474, 6475, 6477, -1, 6479, 6480, 6481, 6483, + 6484, 6485, 6486, -1, 6490, 6491, 6492, -1, + 6493, 6494, -1, 6496, -1, 6498, 6499, -1, + 6500, 6501, 6502, 6503, 6507, -1, -1, 6508, + -1, 6509, 6510, -1, 6511, -1, 6512, -1, + -1, 6513, -1, 6514, 6515, -1, -1, -1, + /* 0x7e00 */ + -1, 6517, -1, -1, 6519, -1, -1, -1, + 6521, 6522, 6523, 6524, -1, -1, -1, -1, + 6525, 6526, -1, -1, -1, 6527, -1, 6529, + 6530, -1, -1, 6533, -1, 6534, 6535, 6536, + -1, -1, -1, 6537, -1, -1, 6539, 6541, + 6543, -1, -1, 6544, -1, 6545, 6546, -1, + -1, 6547, 6549, -1, 6552, 6553, 6554, 6556, + -1, 6557, -1, -1, -1, 6558, 6563, -1, + -1, 6564, -1, 6565, -1, 6567, 6569, -1, + 6570, -1, 6571, 6574, -1, 6577, -1, -1, + -1, -1, 6579, -1, 6580, 6581, 6582, -1, + -1, 6584, 6585, 6586, -1, -1, 6587, -1, + -1, 6588, 6590, -1, 6591, -1, 6592, -1, + -1, 6593, 6595, 6597, -1, 6600, 6603, 6605, + 6606, -1, -1, 6609, -1, -1, -1, -1, + -1, 6610, -1, -1, 6611, 6613, 6614, 6615, + -1, -1, 6616, 6617, -1, -1, -1, 6618, + 6619, 6620, 6622, -1, 6624, 6627, 6628, 6631, + -1, -1, 6633, 6635, 6636, -1, 6637, -1, + 6640, -1, -1, -1, 6642, 6643, -1, 6646, + 6648, 6649, 6650, 6651, 6652, 6656, 6657, 6658, + 6659, 6660, 6662, 6663, 6664, 6665, 6666, 6667, + 6668, 6669, 6670, 6671, 6672, 6673, 6675, 6676, + 6677, 6678, 6679, 6680, 6681, 6682, 6683, 6684, + 6688, 6689, 6691, 6692, 6693, 6694, 6695, 6696, + 6697, 6698, 6699, 6700, 6701, 6702, 6703, 6704, + 6706, 6707, 6708, 6709, 6710, 6711, 6713, 6714, + 6715, 6717, 6718, 6719, 6720, 6721, 6724, 6725, + 6727, 6728, 6729, 6730, 6733, 6734, 6735, 6737, + 6739, 6740, 6741, 6743, -1, 6744, 6746, 6747, + 6748, 6749, 6750, 6751, 6753, 6754, 6756, 6757, + 6759, 6761, 6762, 6763, 6764, 6765, 6766, 6767, + /* 0x7f00 */ + 6769, 6770, 6771, 6772, 6773, 6774, 6775, 6776, + 6777, 6778, 6779, 6781, 6782, 6783, 6784, 6785, + 6786, 6790, 6791, 6792, 6793, 6794, 6795, 6796, + 6797, 6799, 6800, 6801, 6802, 6803, 6804, 6805, + 6806, 6808, 6809, 6810, 6811, 6812, 6813, 6814, + 6817, 6818, 6819, 6820, 6822, 6823, 6824, 6825, + 6826, 6828, 6829, 6830, 6831, 6832, 6834, 6837, + 6838, 6839, 6840, 6842, 6843, 6845, 6848, -1, + -1, -1, 6850, -1, -1, -1, -1, 6852, + 6853, -1, -1, -1, 6858, -1, 6860, -1, + 6865, 6867, 6870, 6872, -1, -1, -1, 6874, + -1, -1, 6877, -1, -1, -1, -1, -1, + -1, -1, 6879, -1, -1, -1, -1, -1, + -1, -1, 6880, -1, -1, -1, -1, -1, + 6882, -1, -1, -1, 6884, 6885, 6888, 6889, + 6890, -1, -1, -1, -1, -1, -1, -1, + 6892, 6893, -1, 6895, -1, 6897, 6898, 6899, + 6902, -1, 6906, 6907, 6908, -1, -1, -1, + 6909, 6910, -1, -1, -1, -1, -1, 6911, + -1, -1, -1, -1, -1, -1, -1, 6912, + -1, 6913, -1, 6914, 6915, 6916, -1, -1, + 6917, 6918, 6919, -1, -1, -1, 6921, -1, + -1, -1, -1, -1, 6922, -1, 6924, -1, + -1, 6926, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 6927, 6929, 6931, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 6932, -1, -1, -1, -1, -1, + 6933, 6934, 6935, -1, -1, -1, -1, -1, + 6936, -1, -1, -1, 6937, -1, -1, -1, + -1, -1, -1, 6939, 6940, -1, -1, -1, + -1, 6941, -1, 6942, -1, -1, -1, -1, + -1, 6943, 6944, 6945, -1, 6947, -1, -1, + /* 0x8000 */ + 6948, -1, -1, 6949, -1, -1, -1, 6950, + 6951, -1, 6952, 6953, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 6954, -1, -1, + 6955, -1, -1, -1, 6956, -1, -1, -1, + -1, 6957, 6958, -1, 6959, -1, -1, 6960, + 6961, -1, -1, -1, 6963, -1, 6964, -1, + 6965, -1, -1, -1, -1, -1, -1, -1, + 6966, -1, -1, 6967, 6968, 6969, -1, -1, + 6970, -1, 6973, 6974, -1, -1, -1, -1, + -1, -1, -1, 6975, 6976, 6979, -1, -1, + -1, -1, -1, -1, 6980, -1, 6982, -1, + -1, -1, -1, -1, -1, -1, 6984, 6985, + -1, 6987, -1, -1, -1, -1, 6990, -1, + 6993, 6995, 6996, 6999, -1, 7000, 7002, 7003, + 7007, -1, 7010, 7011, 7012, 7014, 7015, 7016, + -1, 7019, -1, -1, -1, 7020, 7022, -1, + -1, -1, -1, 7023, -1, 7025, -1, 7027, + 7028, 7029, -1, -1, -1, -1, 7030, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 7031, 7033, -1, -1, 7034, -1, -1, 7035, + -1, -1, -1, -1, 7036, -1, 7037, 7038, + -1, 7040, 7041, -1, 7043, -1, -1, -1, + -1, -1, -1, 7044, -1, -1, 7045, 7046, + 7047, 7048, -1, -1, 7051, -1, 7053, -1, + -1, -1, -1, -1, 7055, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7056, -1, 7057, -1, -1, -1, + -1, 7058, -1, -1, -1, -1, -1, 7060, + 7061, -1, 7062, 7063, -1, 7065, -1, -1, + -1, -1, -1, -1, -1, -1, 7066, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + /* 0x8100 */ + -1, -1, -1, 7067, -1, 7069, 7071, 7073, + 7074, 7075, -1, 7076, -1, 7078, -1, 7079, + 7082, 7083, -1, 7085, 7086, -1, -1, 7087, + -1, -1, 7088, 7090, -1, -1, -1, -1, + -1, -1, -1, 7092, -1, -1, -1, -1, + -1, 7093, -1, 7094, -1, -1, -1, -1, + -1, 7095, -1, 7096, -1, 7099, 7100, -1, + 7101, 7102, 7104, -1, -1, -1, 7106, -1, + -1, -1, -1, -1, -1, -1, 7107, -1, + -1, -1, 7108, -1, 7110, -1, 7111, -1, + -1, -1, -1, -1, -1, -1, 7112, 7113, + 7114, -1, -1, -1, -1, -1, -1, 7115, + -1, 7116, -1, -1, -1, -1, 7117, -1, + -1, -1, -1, 7120, -1, 7121, 7122, -1, + -1, -1, -1, 7123, -1, -1, -1, -1, + 7125, -1, -1, 7127, -1, 7128, 7129, -1, + 7130, -1, 7131, 7132, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 7133, 7134, -1, 7135, -1, 7137, -1, -1, + -1, -1, 7138, -1, -1, -1, -1, -1, + 7139, -1, -1, 7140, 7141, -1, -1, -1, + -1, 7142, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7143, -1, -1, -1, -1, + 7144, -1, -1, 7146, -1, 7150, 7152, 7153, + 7154, -1, -1, 7155, -1, -1, -1, -1, + 7157, 7159, -1, 7160, -1, 7161, -1, 7162, + -1, -1, -1, 7164, -1, -1, -1, -1, + 7166, 7168, 7169, -1, 7170, -1, 7171, 7172, + 7174, -1, 7175, -1, -1, 7176, -1, -1, + 7177, -1, -1, -1, -1, 7178, -1, -1, + 7179, -1, -1, -1, 7180, -1, -1, -1, + -1, -1, 7181, -1, -1, -1, -1, -1, + /* 0x8200 */ + -1, -1, -1, -1, -1, -1, 7183, 7184, + 7185, 7186, 7189, -1, -1, 7190, 7192, -1, + 7193, -1, -1, 7194, -1, -1, 7195, 7198, + 7201, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7202, -1, -1, -1, -1, + -1, 7203, -1, -1, -1, -1, 7204, -1, + 7206, 7207, -1, -1, -1, 7208, 7209, -1, + -1, 7210, -1, 7211, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7213, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7214, -1, -1, -1, -1, -1, -1, + -1, -1, 7215, 7216, 7218, -1, 7219, -1, + -1, -1, 7220, 7222, -1, -1, -1, -1, + 7224, 7225, -1, 7227, -1, -1, 7231, 7235, + 7239, 7240, 7241, -1, -1, -1, -1, -1, + -1, -1, 7246, -1, -1, -1, -1, -1, + 7247, -1, -1, 7249, 7250, -1, -1, -1, + -1, -1, -1, -1, 7251, -1, -1, 7252, + -1, -1, -1, -1, 7253, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7254, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7255, 7256, -1, -1, -1, -1, -1, + 7257, -1, -1, 7264, -1, -1, -1, -1, + -1, 7265, -1, -1, -1, 7266, -1, 7268, + 7269, -1, -1, 7270, 7271, 7272, 7273, 7274, + 7279, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7280, 7281, -1, -1, -1, -1, 7282, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7283, -1, -1, -1, -1, -1, -1, + -1, 7284, 7286, -1, -1, 7287, -1, -1, + /* 0x8300 */ + -1, -1, -1, 7288, -1, -1, -1, -1, + -1, -1, 7290, -1, -1, -1, 7292, 7293, + -1, 7294, -1, -1, 7295, 7296, -1, -1, + 7297, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7298, + -1, -1, -1, -1, -1, -1, -1, 7300, + 7301, -1, 7302, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7304, 7305, + -1, -1, 7306, -1, -1, -1, -1, -1, + 7307, 7309, -1, -1, 7310, -1, -1, -1, + 7311, 7313, 7314, 7315, 7316, 7317, 7318, 7319, + 7320, 7322, -1, 7325, 7327, 7328, 7329, 7330, + 7331, 7332, 7333, 7334, 7335, 7336, 7337, 7338, + -1, -1, -1, 7341, -1, -1, -1, -1, + -1, 7342, -1, 7343, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7344, -1, -1, + -1, -1, 7346, -1, -1, -1, -1, -1, + -1, -1, -1, 7348, -1, 7349, 7350, -1, + -1, -1, -1, -1, -1, -1, 7351, -1, + -1, -1, 7352, -1, -1, -1, -1, 7353, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7354, 7355, 7356, 7357, 7358, 7359, 7360, + 7362, 7363, 7364, -1, 7367, 7369, 7370, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7371, -1, 7372, 7373, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7375, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7376, -1, -1, -1, 7377, + 7380, 7381, -1, -1, 7382, -1, -1, -1, + -1, 7385, -1, -1, -1, -1, -1, -1, + /* 0x8400 */ + -1, -1, -1, -1, -1, -1, -1, 7386, + -1, -1, 7387, -1, 7388, 7389, -1, -1, + -1, -1, -1, -1, -1, 7390, -1, -1, + -1, -1, 7392, -1, -1, 7393, -1, 7394, + 7399, -1, -1, -1, 7400, 7402, 7404, 7405, + 7406, -1, -1, -1, 7407, -1, -1, -1, + -1, 7408, -1, -1, 7411, 7412, -1, -1, + 7413, -1, -1, -1, 7414, -1, -1, -1, + -1, -1, -1, -1, -1, 7415, -1, -1, + -1, 7416, 7417, -1, -1, -1, -1, -1, + -1, -1, 7420, -1, -1, -1, -1, 7421, + 7422, -1, 7423, -1, -1, -1, -1, -1, + 7424, -1, 7425, -1, 7427, -1, 7428, -1, + -1, -1, 7429, -1, 7430, -1, 7431, 7432, + -1, 7433, -1, -1, -1, -1, -1, 7434, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7435, 7436, -1, -1, -1, 7437, + -1, 7438, -1, 7439, 7440, -1, -1, -1, + 7441, -1, -1, 7442, 7444, -1, -1, -1, + -1, 7445, -1, -1, -1, -1, 7449, -1, + -1, -1, -1, -1, -1, -1, 7451, -1, + 7452, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7453, + -1, -1, -1, -1, 7454, -1, -1, -1, + 7455, -1, -1, -1, -1, -1, 7456, -1, + -1, -1, -1, 7457, -1, -1, -1, -1, + -1, 7459, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7461, -1, 7462, + 7463, -1, -1, 7464, -1, 7465, 7466, -1, + -1, -1, -1, -1, -1, 7467, 7470, 7471, + -1, 7472, -1, -1, 7473, -1, -1, -1, + -1, -1, 7475, -1, -1, 7480, -1, -1, + /* 0x8500 */ + -1, -1, -1, -1, -1, 7481, 7483, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 7484, 7485, -1, -1, 7486, 7488, -1, -1, + -1, -1, -1, -1, -1, -1, 7489, -1, + -1, -1, -1, 7490, -1, 7491, 7492, -1, + -1, -1, -1, -1, -1, 7493, -1, 7494, + -1, -1, 7495, 7496, 7497, 7498, 7500, 7502, + -1, 7503, 7504, 7505, 7506, -1, -1, -1, + -1, 7508, -1, -1, -1, -1, 7509, -1, + -1, -1, 7510, 7512, -1, -1, 7514, -1, + 7515, -1, 7517, 7518, -1, 7519, -1, -1, + 7520, -1, 7521, -1, -1, -1, -1, -1, + -1, -1, 7522, -1, -1, -1, -1, -1, + -1, 7523, 7524, -1, -1, 7525, -1, -1, + 7526, -1, 7527, -1, 7528, -1, -1, 7530, + -1, -1, -1, -1, -1, -1, -1, 7531, + 7534, -1, -1, -1, -1, -1, -1, -1, + 7535, -1, 7536, -1, 7538, -1, -1, -1, + -1, 7539, -1, 7540, 7541, -1, -1, 7542, + 7544, -1, -1, -1, -1, -1, -1, 7545, + -1, -1, -1, -1, -1, -1, 7546, -1, + -1, 7548, -1, 7549, 7551, 7553, 7554, 7556, + 7557, -1, 7559, -1, -1, -1, -1, -1, + -1, -1, 7561, -1, 7563, -1, -1, -1, + -1, 7564, 7568, -1, -1, -1, -1, -1, + -1, 7572, -1, -1, -1, 7575, 7576, 7577, + -1, -1, -1, 7579, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7580, -1, 7585, + -1, -1, -1, -1, 7587, 7588, -1, -1, + -1, -1, 7590, -1, -1, -1, -1, -1, + -1, -1, -1, 7592, 7596, -1, 7598, 7599, + -1, 7600, 7602, -1, 7603, -1, -1, -1, + /* 0x8600 */ + 7606, -1, 7607, -1, 7609, -1, 7610, 7611, + -1, -1, 7615, 7617, -1, 7619, 7621, -1, + 7623, -1, -1, 7626, -1, -1, -1, 7628, + -1, -1, 7629, -1, -1, -1, 7630, -1, + -1, -1, 7631, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7632, -1, 7633, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 7635, -1, -1, 7636, -1, 7638, + -1, 7639, -1, -1, -1, -1, 7640, -1, + -1, -1, -1, -1, -1, -1, 7642, 7644, + -1, 7645, -1, 7646, -1, 7647, 7649, 7650, + -1, -1, 7652, 7654, 7656, 7657, -1, 7659, + -1, -1, -1, -1, -1, 7660, 7661, 7662, + -1, -1, -1, 7663, 7665, -1, 7666, 7667, + -1, 7668, -1, -1, -1, 7669, -1, -1, + -1, -1, 7671, 7672, -1, 7673, 7674, 7675, + 7676, 7677, 7678, 7679, -1, -1, -1, -1, + -1, -1, 7680, 7682, 7683, -1, -1, -1, + -1, -1, -1, -1, -1, 7684, 7687, -1, + 7688, -1, -1, -1, -1, 7689, -1, -1, + -1, -1, -1, -1, -1, -1, 7690, -1, + -1, -1, -1, 7691, 7692, -1, -1, -1, + -1, -1, -1, -1, 7693, -1, -1, -1, + -1, -1, 7694, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7695, + -1, -1, 7697, -1, -1, 7698, 7700, 7702, + -1, -1, -1, -1, 7703, -1, -1, -1, + -1, 7706, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 7707, 7708, + 7709, 7710, 7711, 7712, 7713, -1, -1, -1, + -1, -1, 7714, 7715, -1, 7716, -1, -1, + /* 0x8700 */ + -1, -1, 7718, -1, -1, -1, 7719, -1, + -1, -1, -1, 7720, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7721, 7722, 7723, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7724, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7726, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7727, -1, -1, -1, 7728, -1, -1, + -1, -1, -1, -1, -1, 7729, -1, 7732, + 7734, 7735, -1, 7736, -1, -1, 7738, -1, + -1, -1, -1, -1, -1, 7739, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7740, + -1, 7741, -1, -1, -1, -1, 7742, -1, + 7743, -1, -1, -1, -1, -1, -1, 7744, + -1, 7745, -1, -1, -1, -1, -1, -1, + 7746, -1, -1, -1, 7747, -1, 7748, 7749, + 7751, -1, 7752, -1, 7753, -1, -1, -1, + 7754, -1, -1, -1, -1, 7755, 7756, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 7757, 7758, -1, -1, -1, -1, 7760, -1, + -1, 7761, 7762, -1, 7764, -1, -1, 7766, + 7767, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7768, -1, -1, -1, 7769, + -1, 7770, -1, -1, 7771, -1, 7772, 7773, + 7774, -1, -1, -1, -1, -1, 7775, 7776, + -1, -1, 7777, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7778, -1, -1, -1, -1, + -1, -1, -1, -1, 7779, -1, -1, 7780, + -1, -1, 7781, -1, -1, -1, 7782, -1, + 7783, 7784, -1, 7785, -1, -1, -1, -1, + /* 0x8800 */ + -1, 7787, -1, -1, -1, 7788, 7790, 7791, + -1, -1, -1, -1, -1, 7793, 7794, 7795, + 7796, 7797, 7798, -1, 7801, 7802, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 7803, + -1, 7805, 7806, 7807, -1, -1, -1, 7809, + 7811, -1, -1, -1, -1, 7812, -1, -1, + -1, 7813, -1, -1, -1, -1, 7814, -1, + -1, 7817, 7819, 7822, 7823, -1, -1, -1, + -1, -1, 7825, -1, 7826, 7827, 7828, -1, + -1, 7831, 7833, -1, -1, -1, -1, -1, + -1, -1, -1, 7834, 7835, 7838, 7839, -1, + 7840, -1, 7843, 7844, 7846, 7849, 7850, 7852, + -1, -1, -1, 7855, 7856, 7857, -1, -1, + 7858, -1, -1, -1, 7859, -1, 7860, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7861, -1, -1, -1, 7862, -1, -1, + -1, -1, -1, -1, 7863, 7864, 7867, -1, + -1, -1, -1, 7868, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 7869, -1, 7872, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 7873, 7875, 7876, 7877, + -1, -1, -1, -1, 7878, 7880, -1, 7881, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 7882, 7883, -1, + 7884, -1, 7885, -1, 7886, -1, -1, 7887, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 7889, -1, -1, 7890, 7891, -1, -1, + 7892, 7893, 7895, 7896, 7897, 7899, 7900, -1, + 7902, -1, -1, -1, -1, 7903, -1, -1, + -1, -1, -1, -1, 7904, 7905, -1, -1, + -1, -1, -1, -1, -1, 7906, -1, -1, + /* 0x8900 */ + -1, -1, -1, -1, -1, -1, -1, 7907, + -1, -1, 7908, -1, 7909, -1, 7910, 7911, + -1, -1, 7912, 7914, -1, -1, -1, -1, + 7915, -1, -1, 7916, -1, 7917, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 7918, -1, -1, -1, -1, + -1, -1, 7919, 7920, 7921, -1, -1, -1, + 7922, -1, -1, 7923, -1, -1, -1, -1, + -1, -1, -1, 7924, -1, -1, -1, 7926, + -1, -1, -1, -1, 7927, 7928, -1, 7929, + -1, -1, -1, -1, -1, 7930, 7931, -1, + -1, -1, -1, -1, -1, 7932, -1, -1, + 7933, -1, -1, -1, 7934, -1, -1, -1, + -1, -1, 7935, -1, 7936, 7937, -1, 7938, + -1, -1, 7939, -1, 7940, -1, -1, -1, + -1, -1, -1, -1, -1, 7942, -1, 7943, + -1, -1, -1, -1, -1, -1, 7945, 7947, + 7948, 7949, 7952, 7956, -1, 7957, 7958, 7959, + 7960, -1, -1, 7963, 7965, -1, 7967, -1, + 7969, -1, 7970, -1, -1, -1, -1, -1, + -1, 7973, -1, -1, -1, 7974, 7975, 7976, + -1, 7978, 7979, -1, 7980, -1, -1, 7981, + 7982, -1, 7983, 7984, -1, -1, 7986, 7987, + -1, -1, 7989, -1, 7993, 7994, -1, 7996, + 7997, 7999, 8000, 8002, 8003, 8004, 8006, 8008, + 8009, 8011, 8014, 8015, 8016, 8017, 8018, 8019, + 8020, 8021, -1, -1, 8022, -1, -1, 8023, + -1, -1, -1, -1, -1, 8025, 8026, -1, + -1, -1, -1, 8027, -1, -1, 8028, 8029, + -1, -1, -1, -1, -1, -1, -1, 8030, + -1, -1, -1, -1, 8032, -1, 8033, -1, + 8035, 8036, -1, -1, -1, 8038, -1, 8040, + /* 0x8a00 */ + 8042, 8044, 8046, 8047, -1, -1, -1, -1, + 8048, -1, 8049, -1, 8050, -1, 8051, -1, + 8052, -1, 8053, 8054, -1, 8055, 8056, 8057, + 8059, -1, 8060, 8061, -1, 8062, -1, 8063, + 8064, 8066, 8068, 8069, -1, 8070, -1, -1, + -1, 8071, 8072, 8073, -1, 8074, -1, -1, + -1, 8075, -1, 8076, 8078, -1, 8079, -1, + -1, -1, 8081, 8082, 8083, 8085, -1, -1, + -1, 8086, -1, -1, -1, -1, 8087, -1, + -1, -1, -1, 8089, -1, 8091, 8092, -1, + 8093, -1, 8094, -1, 8095, 8096, 8097, 8098, + 8099, -1, -1, 8100, -1, -1, 8101, 8102, + 8103, 8104, 8105, 8106, -1, -1, 8107, 8108, + -1, 8109, -1, 8110, 8111, 8113, 8114, -1, + 8115, 8116, 8118, 8119, -1, 8120, -1, -1, + -1, -1, -1, -1, 8121, -1, -1, 8122, + -1, -1, -1, -1, 8123, 8124, 8125, 8126, + -1, 8127, 8128, -1, 8129, 8130, -1, -1, + -1, 8131, 8132, -1, -1, 8133, 8134, -1, + 8136, -1, 8138, -1, -1, -1, 8139, -1, + 8140, 8141, -1, 8142, 8143, 8144, 8145, -1, + 8146, -1, 8147, -1, 8149, 8151, -1, 8153, + 8154, -1, 8155, -1, -1, -1, 8156, -1, + -1, 8157, -1, -1, 8158, -1, 8160, 8161, + -1, -1, 8162, -1, 8163, -1, -1, 8164, + -1, 8165, -1, 8166, 8167, 8169, -1, 8170, + -1, 8171, 8172, -1, -1, -1, 8173, 8174, + -1, -1, -1, 8175, 8176, 8177, 8178, -1, + 8179, 8181, 8183, -1, 8184, -1, 8186, 8187, + -1, 8188, -1, 8189, 8191, 8197, 8198, -1, + -1, 8199, -1, 8200, -1, -1, 8202, 8203, + 8205, -1, 8206, -1, 8207, -1, 8209, -1, + /* 0x8b00 */ + 8210, 8211, 8212, -1, 8213, 8214, -1, -1, + -1, -1, 8215, -1, 8216, -1, 8217, -1, + 8218, -1, -1, -1, 8219, -1, 8220, 8221, + -1, 8222, 8223, 8225, -1, 8226, -1, -1, + 8227, 8229, -1, -1, -1, -1, -1, -1, + 8231, -1, 8232, 8233, 8235, 8236, -1, -1, + 8238, -1, -1, 8239, -1, -1, -1, -1, + -1, 8240, -1, -1, 8241, -1, 8243, -1, + -1, 8244, -1, -1, -1, -1, -1, -1, + -1, 8246, -1, -1, 8248, -1, 8249, 8250, + 8251, -1, -1, -1, -1, -1, 8252, -1, + 8254, 8255, 8256, 8257, 8259, -1, -1, 8261, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 8262, 8264, -1, 8266, 8267, 8269, + 8271, 8272, 8273, -1, 8275, -1, -1, 8276, + 8277, -1, -1, -1, 8278, 8280, 8281, -1, + 8283, 8285, -1, 8287, -1, 8289, -1, -1, + -1, -1, 8290, 8292, 8293, 8295, 8297, -1, + 8300, -1, 8302, 8303, -1, 8305, 8306, -1, + -1, -1, 8307, -1, 8309, -1, 8310, -1, + 8311, 8313, 8314, 8315, 8316, 8317, 8318, 8319, + 8320, 8321, 8323, 8324, 8325, 8327, 8328, 8329, + 8330, 8331, 8332, 8333, 8334, 8335, 8336, 8337, + 8338, 8339, 8341, 8342, 8343, 8344, 8346, 8347, + 8348, 8349, 8351, 8352, 8353, 8354, 8355, 8356, + 8357, 8358, 8359, 8360, 8361, 8362, 8363, 8364, + 8365, 8366, 8368, 8369, 8370, 8371, 8372, 8373, + 8374, 8375, 8376, 8377, 8378, 8379, 8381, 8382, + 8383, 8384, 8385, 8386, 8387, 8388, 8389, 8390, + 8391, 8392, 8393, 8394, 8395, 8396, 8397, 8398, + 8400, 8401, 8403, 8404, 8405, 8407, 8408, 8409, + 8410, 8411, 8412, 8413, 8415, 8416, 8417, 8418, + /* 0x8c00 */ + 8419, 8420, 8421, 8422, 8423, 8424, 8425, 8426, + 8427, 8428, 8429, 8431, 8432, 8433, 8434, 8435, + 8437, 8438, 8439, 8440, 8441, 8443, 8444, 8446, + 8447, 8448, 8450, 8451, 8452, 8453, 8454, 8455, + 8456, 8457, 8458, 8459, 8461, 8462, 8464, 8465, + 8466, 8467, 8468, 8470, 8472, 8473, 8474, 8476, + 8477, 8478, 8479, 8480, 8481, 8482, 8483, 8484, + -1, -1, 8486, -1, -1, -1, -1, 8487, + 8490, -1, -1, -1, -1, -1, 8493, -1, + 8494, -1, 8495, -1, -1, -1, 8499, -1, + 8501, -1, -1, 8505, 8509, -1, -1, -1, + 8513, -1, 8514, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8515, -1, -1, -1, + -1, -1, -1, 8516, 8517, -1, 8518, -1, + -1, -1, -1, -1, -1, -1, 8519, -1, + -1, -1, 8520, 8521, 8522, -1, 8523, -1, + -1, -1, 8524, -1, -1, -1, -1, 8525, + -1, 8526, -1, 8527, 8528, 8529, 8531, -1, + -1, -1, 8532, 8533, 8534, -1, -1, -1, + 8535, -1, -1, 8536, 8537, 8539, 8541, 8542, + 8545, 8546, 8548, -1, -1, -1, -1, 8549, + 8550, 8551, 8552, 8553, 8554, 8555, 8558, 8561, + 8562, -1, 8563, 8564, 8567, -1, 8568, 8569, + 8570, -1, 8571, 8572, 8573, 8574, -1, 8575, + 8576, 8577, 8578, 8579, 8580, 8581, -1, 8582, + 8583, 8584, 8586, 8587, -1, 8588, 8590, -1, + -1, 8592, 8593, 8594, 8596, 8598, 8599, -1, + -1, 8600, 8601, 8602, 8604, -1, 8605, -1, + 8606, 8607, 8610, 8612, 8614, -1, 8616, 8617, + -1, -1, 8618, 8621, 8622, 8623, -1, -1, + 8624, -1, -1, -1, 8625, 8627, -1, 8628, + -1, -1, 8630, 8631, 8632, 8633, 8634, -1, + /* 0x8d00 */ + -1, 8635, -1, -1, 8637, 8638, -1, 8639, + 8640, -1, 8641, 8643, -1, 8646, -1, 8647, + 8648, -1, 8649, 8651, 8653, -1, 8654, 8655, + -1, -1, -1, 8658, 8659, 8660, 8662, 8663, + 8664, 8667, 8668, 8670, 8671, 8673, 8675, 8676, + 8677, 8679, 8680, 8681, 8682, 8683, 8684, 8685, + 8686, 8689, 8691, 8692, 8693, 8694, 8695, 8696, + 8697, 8698, 8699, 8700, 8701, 8702, 8703, 8704, + 8705, 8706, 8707, 8708, 8711, 8712, 8713, 8714, + 8715, 8716, 8717, 8719, 8720, 8721, 8724, 8725, + 8726, 8727, 8728, 8729, 8730, 8731, 8732, 8734, + 8735, 8736, 8737, 8738, 8739, 8740, 8743, 8747, + 8748, 8749, 8750, 8751, 8752, -1, -1, -1, + -1, -1, 8754, -1, 8755, -1, -1, -1, + 8756, 8757, -1, -1, -1, 8758, 8759, -1, + -1, -1, -1, 8760, -1, -1, -1, 8765, + -1, 8766, 8767, -1, -1, -1, -1, -1, + -1, -1, -1, 8768, -1, -1, -1, -1, + -1, 8769, -1, -1, -1, 8770, -1, -1, + -1, 8771, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 8772, -1, + 8773, -1, -1, -1, 8774, -1, -1, 8775, + -1, 8777, 8778, -1, -1, -1, -1, -1, + 8779, -1, -1, 8780, -1, -1, -1, -1, + -1, -1, -1, 8781, 8783, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 8784, -1, + -1, 8785, -1, -1, -1, 8786, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8787, 8788, 8789, 8790, + 8791, 8792, 8793, 8794, 8795, -1, -1, -1, + /* 0x8e00 */ + -1, 8796, -1, -1, -1, -1, -1, -1, + 8798, -1, 8800, 8801, 8803, -1, -1, -1, + 8804, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8805, 8806, 8807, 8808, 8809, -1, -1, 8810, + 8811, -1, -1, -1, 8812, -1, -1, -1, + 8813, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 8814, -1, -1, -1, + -1, -1, -1, 8815, 8817, -1, -1, 8818, + -1, 8819, 8820, -1, -1, 8821, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 8822, + -1, -1, -1, 8823, 8824, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8826, -1, -1, -1, -1, -1, -1, -1, + -1, 8828, 8830, -1, -1, -1, -1, 8832, + -1, -1, 8833, 8834, 8835, -1, -1, 8836, + -1, 8837, 8838, 8841, -1, 8843, -1, 8845, + -1, 8846, 8847, 8848, -1, 8849, -1, -1, + -1, 8851, 8852, -1, 8853, -1, -1, -1, + -1, 8854, 8855, -1, -1, 8857, 8858, -1, + -1, -1, 8859, -1, 8861, 8862, -1, 8863, + 8864, 8868, 8869, 8870, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 8871, -1, -1, -1, 8872, -1, 8875, -1, + -1, -1, 8879, 8880, 8881, 8882, -1, -1, + -1, 8883, 8884, -1, 8885, -1, -1, -1, + -1, -1, -1, 8886, -1, -1, -1, 8889, + -1, -1, 8890, 8892, 8894, -1, -1, -1, + -1, -1, -1, 8895, -1, -1, -1, -1, + 8896, -1, 8898, -1, -1, -1, 8899, -1, + 8902, 8903, 8904, 8905, 8906, 8907, 8909, -1, + /* 0x8f00 */ + 8910, -1, -1, 8911, -1, 8912, -1, 8913, + 8914, 8915, 8916, -1, 8917, -1, -1, 8919, + -1, -1, 8920, 8922, 8923, 8925, -1, -1, + -1, 8927, -1, 8929, 8931, 8933, 8934, 8935, + -1, 8936, -1, -1, -1, 8937, 8938, -1, + -1, 8939, 8941, -1, 8942, 8943, -1, 8944, + -1, -1, -1, 8945, -1, -1, 8946, -1, + 8947, -1, 8948, 8950, 8951, -1, 8952, 8953, + -1, 8954, 8957, -1, 8958, 8960, 8961, -1, + -1, 8962, -1, -1, -1, 8964, 8965, -1, + -1, -1, -1, -1, 8966, -1, -1, 8967, + -1, -1, -1, -1, 8968, -1, -1, 8969, + -1, 8971, 8972, -1, 8973, -1, 8974, 8975, + 8976, 8977, 8978, 8979, 8980, 8982, 8985, 8986, + 8988, 8990, 8991, 8992, 8993, 8994, 8995, 8996, + 8997, 8998, 8999, 9000, 9002, 9003, 9004, 9005, + 9006, 9007, 9008, 9009, 9010, 9012, 9013, 9015, + 9016, 9018, 9019, 9020, 9021, 9022, 9023, 9025, + 9026, 9027, 9028, 9029, 9030, 9031, 9032, 9033, + 9034, 9035, 9036, -1, -1, 9037, 9040, 9043, + 9044, 9046, -1, -1, 9049, -1, 9052, 9053, + 9055, 9057, -1, 9060, -1, 9061, 9064, 9065, + -1, -1, 9068, -1, -1, 9069, 9070, -1, + -1, 9071, 9074, -1, -1, 9077, 9078, -1, + -1, 9080, 9081, 9082, -1, -1, 9083, 9084, + 9085, -1, 9086, -1, -1, -1, -1, -1, + 9088, -1, -1, -1, -1, -1, -1, -1, + 9089, 9090, -1, 9091, 9092, 9093, 9094, 9095, + -1, -1, -1, -1, 9098, 9099, -1, -1, + -1, 9100, 9101, -1, 9102, -1, -1, 9103, + -1, -1, -1, 9104, 9107, -1, -1, -1, + -1, 9113, 9115, -1, -1, -1, -1, -1, + /* 0x9000 */ + -1, -1, 9117, 9118, -1, -1, -1, -1, + 9119, 9120, 9121, -1, -1, -1, 9122, -1, + -1, -1, 9123, 9125, -1, 9127, -1, -1, + -1, 9130, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 9131, -1, 9132, 9138, -1, + -1, 9139, -1, -1, -1, -1, -1, -1, + 9140, 9142, 9143, -1, -1, -1, -1, -1, + -1, 9144, 9146, 9147, 9148, -1, -1, -1, + -1, 9149, -1, -1, -1, 9150, -1, -1, + -1, 9152, 9154, 9156, -1, -1, 9157, -1, + -1, -1, 9158, 9159, 9162, 9164, -1, 9165, + -1, 9166, -1, -1, 9167, -1, 9168, -1, + 9170, 9172, -1, -1, -1, 9173, -1, -1, + -1, 9174, -1, -1, -1, -1, -1, 9175, + -1, -1, 9176, -1, -1, -1, 9178, 9179, + 9180, -1, 9181, -1, 9182, -1, -1, -1, + -1, 9183, -1, -1, 9184, -1, -1, 9185, + -1, 9186, 9189, -1, -1, -1, -1, 9192, + 9193, 9194, -1, 9195, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 9196, -1, -1, + -1, -1, -1, -1, -1, -1, 9197, -1, + 9198, -1, -1, 9199, 9200, -1, 9201, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 9202, 9203, 9204, -1, 9207, -1, -1, + -1, 9208, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 9211, -1, 9212, 9214, + 9215, 9216, 9217, 9219, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 9220, 9222, + -1, -1, -1, -1, -1, -1, 9223, 9224, + 9225, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 9226, 9227, 9228, + 9232, -1, -1, -1, -1, -1, -1, -1, + /* 0x9100 */ + -1, -1, -1, -1, -1, -1, 9233, -1, + -1, 9234, 9238, -1, -1, -1, -1, -1, + -1, -1, 9242, -1, 9243, 9244, 9248, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 9249, + -1, -1, -1, -1, -1, 9250, -1, -1, + 9251, -1, 9254, -1, 9255, -1, 9256, 9257, + -1, -1, 9258, -1, 9259, 9260, -1, -1, + -1, -1, 9263, -1, -1, -1, 9264, 9265, + 9267, 9268, -1, 9269, -1, -1, -1, -1, + -1, -1, -1, -1, 9270, -1, -1, -1, + -1, 9271, -1, -1, -1, 9272, -1, -1, + -1, -1, 9274, -1, -1, -1, 9275, 9278, + -1, -1, 9280, -1, 9281, -1, -1, -1, + -1, 9283, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 9285, 9286, 9287, + -1, -1, -1, 9289, -1, -1, -1, 9290, + -1, 9291, 9292, 9293, -1, -1, 9294, -1, + -1, -1, -1, -1, 9296, 9297, 9298, 9300, + 9303, -1, -1, -1, 9304, -1, 9306, -1, + -1, -1, -1, -1, 9308, -1, -1, -1, + -1, -1, -1, 9310, 9312, -1, -1, -1, + -1, 9314, -1, -1, -1, -1, -1, -1, + 9317, -1, -1, 9319, 9321, -1, -1, -1, + 9323, 9325, -1, 9326, -1, 9327, -1, 9328, + 9330, -1, 9332, 9334, 9336, -1, 9338, -1, + 9340, 9341, 9343, 9345, 9348, 9349, 9350, 9352, + 9353, 9354, 9355, -1, 9357, 9358, -1, -1, + 9359, 9361, -1, 9362, 9364, -1, 9365, 9366, + -1, 9367, -1, -1, -1, -1, -1, 9368, + 9369, -1, -1, -1, -1, 9377, -1, 9378, + -1, 9379, 9380, 9381, 9384, -1, -1, -1, + /* 0x9200 */ + 9392, 9393, -1, 9394, 9395, 9396, 9397, -1, + 9399, 9400, -1, -1, -1, 9401, 9402, -1, + 9404, 9405, 9406, -1, 9407, 9408, -1, -1, + -1, -1, -1, -1, -1, -1, 9409, 9411, + -1, 9412, -1, 9413, -1, 9414, 9415, 9416, + 9417, 9418, -1, -1, 9420, -1, 9422, -1, + 9424, -1, -1, 9425, 9426, -1, -1, 9427, + 9428, 9429, 9430, -1, -1, 9431, 9432, 9433, + 9434, -1, -1, -1, 9435, 9440, 9441, 9442, + 9443, 9444, -1, 9445, -1, 9447, -1, -1, + -1, 9448, -1, -1, -1, 9449, -1, 9450, + -1, -1, 9451, 9452, -1, -1, 9454, -1, + 9455, -1, 9456, -1, 9459, -1, 9461, -1, + 9462, -1, -1, -1, 9464, 9465, -1, -1, + -1, 9466, -1, -1, 9471, -1, 9475, -1, + 9476, -1, 9477, 9478, -1, -1, -1, 9479, + 9480, -1, -1, 9481, -1, 9482, -1, -1, + -1, -1, -1, -1, -1, 9483, -1, -1, + -1, 9484, -1, 9485, -1, 9486, 9490, -1, + 9491, -1, 9492, 9494, 9496, -1, 9499, -1, + 9500, -1, -1, 9501, -1, 9502, 9503, -1, + 9504, 9505, 9506, 9507, 9508, 9509, 9511, -1, + -1, 9512, 9513, 9514, -1, -1, -1, 9516, + -1, 9518, -1, 9519, 9520, 9521, -1, -1, + -1, 9522, -1, 9523, -1, 9524, -1, 9525, + -1, -1, -1, -1, 9526, -1, -1, 9527, + -1, -1, 9528, -1, -1, -1, -1, -1, + -1, 9529, -1, 9530, -1, 9535, -1, 9536, + -1, -1, -1, 9538, 9540, 9541, 9542, -1, + 9543, 9548, 9550, -1, -1, 9553, 9555, 9556, + 9557, 9558, -1, 9559, -1, -1, 9561, -1, + 9562, -1, -1, -1, 9563, -1, -1, -1, + /* 0x9300 */ + -1, 9564, -1, -1, 9565, -1, 9567, 9568, + 9569, -1, -1, -1, -1, -1, -1, 9570, + 9572, -1, 9573, -1, -1, 9574, -1, -1, + 9575, 9576, 9578, 9579, -1, -1, -1, 9580, + 9581, 9582, 9583, -1, -1, -1, 9585, -1, + 9586, 9587, -1, 9588, 9589, -1, 9592, 9593, + -1, -1, 9594, 9596, -1, -1, 9597, 9598, + 9599, -1, -1, -1, -1, -1, 9600, -1, + 9601, 9602, -1, 9603, -1, -1, 9604, 9605, + 9606, -1, 9608, 9611, -1, 9612, -1, -1, + -1, -1, -1, -1, 9613, -1, -1, -1, + 9614, -1, 9615, 9616, -1, -1, 9618, -1, + 9619, -1, -1, -1, 9621, 9622, -1, -1, + -1, 9623, -1, -1, 9624, -1, -1, 9625, + 9627, -1, -1, 9628, -1, 9632, 9633, -1, + -1, -1, 9634, -1, -1, -1, 9635, 9637, + -1, 9638, 9639, -1, 9640, -1, -1, 9641, + -1, -1, 9642, 9643, 9644, -1, -1, -1, + -1, -1, 9646, -1, 9648, -1, 9650, 9652, + 9653, -1, 9654, 9655, -1, -1, -1, -1, + -1, 9656, 9658, 9659, -1, -1, 9660, 9662, + -1, 9663, 9664, -1, 9665, 9666, 9668, -1, + 9670, -1, -1, 9671, -1, 9672, -1, -1, + 9673, -1, 9674, -1, -1, -1, -1, 9675, + -1, 9676, -1, 9677, -1, -1, -1, 9678, + 9679, -1, -1, -1, 9680, 9681, -1, -1, + 9682, 9683, -1, 9684, -1, -1, -1, 9685, + 9686, -1, -1, -1, 9687, 9688, 9689, 9690, + -1, 9694, 9696, -1, 9697, 9698, -1, -1, + 9700, -1, -1, -1, -1, -1, -1, -1, + 9701, -1, -1, -1, -1, 9702, -1, 9703, + -1, 9704, -1, -1, -1, 9705, -1, -1, + /* 0x9400 */ + -1, -1, 9707, 9709, -1, -1, -1, -1, + -1, -1, -1, 9710, -1, -1, -1, -1, + 9711, -1, 9712, 9713, 9714, -1, -1, 9715, + 9716, 9717, 9718, -1, -1, 9720, -1, -1, + 9722, 9723, -1, -1, -1, -1, 9728, 9729, + 9730, -1, -1, 9731, -1, -1, 9732, -1, + -1, -1, 9734, 9735, -1, 9736, 9741, -1, + 9742, -1, 9744, -1, -1, -1, -1, 9745, + -1, -1, -1, 9746, 9748, 9750, -1, -1, + -1, -1, 9751, -1, 9752, -1, -1, -1, + -1, 9753, 9757, 9761, 9762, 9763, -1, -1, + -1, -1, 9764, 9766, 9771, -1, 9773, -1, + 9774, -1, -1, 9775, 9776, 9777, -1, -1, + -1, -1, 9778, -1, 9780, 9784, -1, 9785, + 9786, 9787, 9788, -1, -1, 9789, -1, 9791, + -1, 9792, -1, -1, 9793, 9794, 9796, 9797, + -1, 9798, 9800, -1, -1, 9801, 9803, 9806, + 9807, 9808, 9809, 9810, 9811, 9812, 9813, 9814, + 9815, 9816, 9817, 9818, 9819, 9820, 9821, 9822, + 9823, 9824, 9825, 9826, 9827, 9828, 9829, 9830, + 9834, 9835, 9836, 9837, 9838, 9839, 9841, 9842, + 9843, 9844, 9846, 9847, 9848, 9849, 9850, 9851, + 9852, 9853, 9855, 9856, 9857, 9858, 9861, 9862, + 9863, 9864, 9865, 9866, 9869, 9870, 9871, 9872, + 9873, 9874, 9877, 9878, 9879, 9880, 9882, 9883, + 9885, 9886, 9887, 9889, 9890, 9892, 9893, 9895, + 9896, 9897, 9898, 9899, 9900, 9902, 9903, 9904, + 9905, 9906, 9907, 9908, 9909, 9910, 9911, 9912, + 9913, 9914, 9915, 9916, 9917, 9918, 9919, 9920, + 9921, 9922, 9923, 9924, 9926, 9927, 9928, 9929, + 9930, 9931, 9932, 9936, 9937, 9938, 9939, 9940, + 9941, 9943, 9944, 9947, 9948, 9949, 9950, 9951, + /* 0x9500 */ + 9953, 9954, 9955, 9956, 9957, 9959, 9960, 9961, + 9962, 9965, 9966, 9967, 9968, 9969, 9970, 9971, + 9973, 9975, 9976, 9977, 9978, 9979, 9980, 9981, + 9982, 9983, 9984, 9985, 9986, 9987, 9988, 9989, + 9990, 9991, 9992, 9993, 9994, 9996, 9997, 9998, + 9999, 10000, 10001, 10003, 10004, 10005, 10006, 10007, + 10008, 10009, 10010, 10011, 10012, 10013, 10014, 10015, + 10016, 10017, 10018, 10020, 10021, 10022, 10023, 10024, + 10025, 10026, 10027, 10028, 10029, 10030, 10031, 10032, + 10034, 10035, 10036, 10037, 10038, 10040, 10041, 10042, + 10044, 10045, 10046, 10047, 10048, -1, 10049, 10050, + 10051, 10052, 10053, 10054, 10055, 10056, 10057, 10058, + 10059, 10060, 10061, 10063, 10064, 10065, 10066, 10067, + 10068, 10069, 10070, 10071, 10072, 10073, 10074, 10075, + 10076, 10078, 10079, 10080, 10081, 10082, 10083, 10084, + 10088, 10092, -1, -1, -1, -1, -1, 10094, + 10098, -1, 10099, 10100, -1, -1, 10101, 10102, + 10104, 10105, -1, 10107, 10108, -1, 10109, 10110, + -1, 10112, 10114, 10116, 10117, -1, -1, -1, + 10118, 10119, -1, -1, -1, -1, -1, -1, + 10121, 10123, 10124, 10127, 10128, 10129, -1, 10130, + 10131, 10132, -1, 10133, 10134, 10135, -1, -1, + -1, 10136, 10138, -1, 10140, -1, 10142, -1, + -1, 10143, -1, 10145, 10146, 10147, 10148, 10149, + -1, -1, -1, 10150, -1, -1, 10152, 10153, + 10154, -1, 10155, 10157, 10158, 10159, -1, -1, + 10160, -1, 10161, 10162, 10163, 10164, 10165, 10166, + 10169, 10174, -1, -1, 10180, -1, 10183, -1, + 10184, 10185, 10186, -1, 10187, 10188, -1, -1, + 10189, 10190, 10191, 10192, 10193, 10194, 10196, 10197, + 10198, 10200, 10201, 10203, 10204, 10205, 10206, 10207, + 10208, 10209, 10211, 10212, 10213, 10214, 10215, 10216, + /* 0x9600 */ + 10217, 10218, 10219, 10220, 10221, 10222, 10224, 10225, + 10226, 10227, 10229, 10230, 10231, 10232, 10233, 10234, + 10235, 10236, 10237, 10239, 10240, 10242, 10243, 10244, + 10245, 10246, 10247, 10249, 10250, 10251, -1, 10253, + -1, -1, -1, -1, -1, 10254, 10258, -1, + 10260, 10261, 10263, 10265, 10267, -1, -1, 10268, + -1, 10269, -1, 10270, 10272, 10276, 10277, -1, + 10279, -1, -1, 10280, -1, -1, -1, -1, + 10281, 10283, -1, -1, -1, 10285, 10286, 10287, + 10288, 10289, -1, -1, -1, 10290, -1, -1, + -1, -1, -1, -1, -1, 10291, 10294, -1, + 10295, -1, -1, -1, 10296, 10298, 10299, 10301, + -1, -1, -1, 10302, -1, 10304, 10305, -1, + 10312, 10313, -1, -1, -1, -1, -1, -1, + 10316, -1, -1, 10320, -1, -1, -1, 10321, + 10322, -1, 10323, 10326, -1, 10328, -1, 10330, + -1, 10332, 10334, -1, 10338, -1, -1, -1, + -1, -1, 10340, -1, 10341, -1, 10342, 10344, + 10345, -1, -1, -1, -1, 10348, 10350, -1, + -1, 10351, -1, 10352, -1, 10353, -1, 10360, + 10361, -1, -1, 10364, -1, -1, -1, -1, + 10367, -1, 10368, 10371, -1, -1, 10373, 10374, + -1, 10381, 10384, -1, 10385, -1, 10386, 10388, + 10390, -1, 10392, 10399, -1, 10400, 10401, -1, + -1, 10402, -1, -1, -1, -1, -1, 10404, + -1, -1, -1, 10406, -1, 10407, -1, 10408, + -1, 10409, -1, -1, -1, 10411, 10414, -1, + -1, 10415, 10416, 10417, 10419, 10421, 10422, 10425, + 10426, -1, 10428, 10429, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 10430, -1, 10431, 10432, -1, -1, 10433, 10434, + -1, -1, 10435, 10437, -1, -1, 10438, -1, + /* 0x9700 */ + -1, 10440, -1, -1, -1, -1, -1, -1, + -1, 10441, 10442, -1, -1, -1, -1, -1, + -1, 10445, -1, -1, -1, -1, -1, 10446, + -1, -1, 10447, 10450, -1, -1, -1, -1, + -1, 10453, 10454, -1, -1, -1, -1, 10455, + -1, -1, -1, -1, -1, 10458, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 10459, -1, -1, 10460, -1, 10464, -1, -1, + -1, 10465, 10466, -1, 10467, -1, 10468, -1, + 10469, 10472, 10473, -1, -1, 10477, 10484, 10491, + -1, 10498, 10500, 10502, 10503, -1, -1, -1, + -1, 10506, 10507, -1, 10508, 10509, -1, -1, + -1, -1, 10512, 10518, 10519, 10521, -1, 10522, + 10523, -1, -1, 10524, -1, 10526, -1, -1, + -1, 10529, -1, -1, 10532, -1, -1, -1, + -1, -1, -1, -1, -1, 10533, -1, -1, + 10534, -1, -1, -1, -1, -1, -1, -1, + -1, 10536, -1, 10538, 10539, 10540, -1, 10541, + -1, 10542, 10543, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 10544, + -1, -1, -1, -1, -1, -1, 10545, 10547, + 10549, -1, -1, -1, -1, -1, -1, 10550, + -1, 10551, 10553, -1, -1, 10554, -1, -1, + -1, 10555, -1, -1, -1, 10556, 10557, -1, + -1, 10558, -1, 10560, -1, -1, 10561, -1, + 10562, 10564, -1, 10565, 10566, 10567, -1, -1, + -1, -1, -1, 10569, -1, -1, -1, -1, + -1, 10570, -1, -1, 10571, 10574, 10575, -1, + -1, -1, -1, -1, 10576, -1, 10578, 10579, + 10582, 10584, 10585, 10586, 10587, 10589, 10590, 10591, + -1, 10592, 10593, -1, -1, 10595, -1, -1, + -1, -1, -1, 10596, -1, -1, -1, 10597, + /* 0x9800 */ + -1, 10598, 10599, 10600, -1, 10601, 10602, 10603, + 10604, -1, 10605, -1, 10606, -1, 10607, 10608, + 10609, 10610, 10611, 10612, -1, -1, -1, 10613, + 10614, -1, 10615, -1, 10617, -1, -1, -1, + -1, 10618, -1, -1, 10619, 10621, 10623, -1, + -1, -1, -1, -1, 10624, 10626, 10627, -1, + 10629, -1, 10631, -1, 10632, -1, -1, 10634, + 10635, 10637, 10641, 10645, 10646, 10648, 10652, -1, + -1, -1, -1, -1, -1, -1, 10653, -1, + -1, -1, -1, 10654, 10655, 10656, 10657, 10658, + -1, -1, 10660, 10661, 10662, 10664, 10666, -1, + 10667, 10668, 10669, 10671, -1, -1, 10673, -1, + -1, -1, 10674, -1, -1, 10675, -1, 10676, + -1, -1, -1, 10677, 10678, -1, -1, 10679, + 10681, 10682, -1, 10685, 10686, 10687, 10688, 10689, + 10690, 10691, 10692, 10693, 10695, 10696, 10697, 10698, + 10699, 10700, 10701, 10702, 10703, 10704, 10706, 10707, + 10708, 10710, 10711, 10713, 10714, 10715, 10716, 10717, + 10718, 10720, 10721, 10722, 10726, -1, 10727, 10729, + 10730, 10731, 10732, 10733, 10734, 10736, 10737, 10738, + 10739, 10741, 10742, 10743, 10744, 10745, 10746, 10747, + 10748, -1, -1, -1, -1, 10756, 10757, 10761, + -1, 10762, -1, 10763, -1, -1, 10764, 10765, + 10768, -1, 10769, 10770, 10771, -1, -1, -1, + 10772, -1, -1, 10773, 10775, -1, 10777, 10782, + 10783, -1, -1, -1, 10787, -1, 10792, 10798, + 10799, 10800, 10801, 10802, 10803, 10804, 10805, 10806, + 10807, 10809, 10810, 10811, 10812, -1, 10813, 10814, + 10817, 10820, 10821, 10822, -1, 10823, -1, -1, + 10824, 10825, 10826, 10827, 10829, 10830, 10831, 10833, + 10835, -1, 10836, -1, 10838, -1, 10839, -1, + -1, -1, -1, -1, 10840, 10841, 10842, 10843, + /* 0x9900 */ + -1, -1, -1, 10844, 10845, 10846, -1, -1, + -1, 10848, 10851, -1, 10854, 10855, 10856, 10857, + 10858, 10859, 10860, 10862, -1, 10863, 10864, -1, + 10865, -1, 10867, 10868, 10869, -1, 10870, 10871, + 10872, 10874, -1, -1, -1, -1, -1, 10875, + 10879, -1, -1, -1, 10881, -1, -1, -1, + -1, 10882, -1, 10883, 10884, 10885, 10887, 10888, + -1, 10889, 10890, 10891, 10892, 10893, 10894, 10895, + -1, 10896, -1, 10897, -1, 10898, -1, -1, + 10899, 10900, 10901, 10902, 10903, 10904, 10905, -1, + -1, 10906, 10907, -1, -1, -1, -1, 10908, + -1, 10909, -1, -1, 10910, -1, 10911, 10912, + -1, -1, 10915, 10916, 10919, 10920, 10922, 10923, + 10925, 10926, 10927, 10928, 10929, 10930, 10931, 10933, + 10934, 10935, 10936, 10937, 10938, 10939, 10940, 10941, + 10943, 10944, 10945, 10946, 10947, 10949, 10950, 10951, + 10952, 10954, 10956, 10957, 10958, 10959, 10960, 10961, + 10962, 10964, 10965, 10966, 10967, 10968, 10969, 10970, + 10971, 10972, 10973, 10974, 10975, 10976, -1, -1, + -1, -1, -1, -1, -1, 10977, 10978, 10979, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 10980, 10981, 10982, -1, + -1, 10983, 10985, 10986, 10987, -1, -1, -1, + -1, 10988, -1, -1, -1, 10989, -1, 10990, + -1, 10992, -1, -1, 10993, 10995, 10997, -1, + 11001, -1, -1, -1, -1, -1, -1, -1, + 11005, 11006, 11007, -1, 11008, 11009, -1, -1, + 11010, 11011, -1, 11012, -1, 11013, 11015, 11017, + -1, 11018, 11021, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 11022, 11023, -1, + 11024, 11025, -1, -1, -1, 11026, -1, -1, + 11028, -1, -1, -1, -1, -1, -1, 11029, + /* 0x9a00 */ + -1, 11030, 11031, -1, -1, 11032, -1, -1, + -1, -1, -1, -1, -1, 11033, 11034, 11035, + 11036, -1, 11039, 11041, -1, -1, 11044, -1, + -1, 11045, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 11046, -1, -1, -1, + 11047, -1, -1, 11048, -1, 11049, 11050, -1, + 11053, -1, -1, -1, -1, -1, 11054, 11055, + 11057, -1, 11058, -1, -1, -1, 11059, -1, + 11060, 11061, 11062, 11063, 11064, 11065, -1, 11069, + -1, -1, 11070, -1, 11071, 11072, -1, 11073, + -1, 11074, 11077, -1, -1, 11078, -1, 11079, + -1, -1, 11082, 11083, -1, 11085, -1, 11086, + -1, -1, 11087, -1, 11089, 11090, 11092, -1, + -1, 11093, 11094, 11095, 11096, 11097, 11098, 11100, + 11101, 11102, 11106, 11107, 11109, 11111, 11112, 11113, + 11114, 11115, 11116, 11117, 11118, 11120, 11121, 11122, + 11124, 11125, 11126, 11129, 11130, 11131, 11132, 11133, + 11134, 11135, 11136, 11137, 11138, 11141, 11142, 11143, + 11144, 11145, 11146, 11147, -1, 11148, 11149, 11150, + 11151, 11153, 11154, 11156, 11157, 11158, 11160, 11161, + 11162, 11163, 11164, 11165, 11166, 11167, 11169, 11170, + -1, -1, -1, -1, -1, -1, -1, 11171, + -1, -1, -1, -1, -1, 11172, -1, -1, + -1, -1, -1, -1, -1, -1, 11176, -1, + -1, -1, -1, -1, 11177, 11179, -1, -1, + 11180, -1, -1, 11181, 11182, -1, -1, 11183, + -1, -1, 11184, 11185, 11187, 11191, 11193, 11194, + 11197, 11198, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 11199, 11201, 11202, -1, -1, + -1, 11203, 11205, -1, -1, 11207, 11208, 11210, + -1, -1, -1, -1, 11211, -1, -1, -1, + -1, 11213, -1, -1, -1, -1, -1, -1, + /* 0x9b00 */ + 11214, -1, 11215, -1, -1, -1, 11218, -1, + -1, -1, -1, -1, -1, 11219, -1, -1, + -1, -1, -1, 11220, -1, -1, -1, -1, + -1, -1, 11222, 11223, -1, -1, -1, -1, + -1, -1, 11224, 11227, -1, 11228, 11233, 11238, + 11240, 11241, 11242, 11247, -1, 11248, 11253, -1, + 11254, 11257, -1, -1, -1, -1, 11260, -1, + -1, 11261, -1, 11262, -1, -1, -1, -1, + 11264, -1, -1, -1, -1, -1, -1, 11265, + -1, 11266, -1, -1, -1, -1, 11267, -1, + 11269, -1, -1, -1, -1, -1, -1, 11274, + 11276, -1, 11277, 11278, -1, -1, -1, -1, + -1, -1, 11279, 11280, -1, -1, 11281, -1, + 11282, -1, -1, -1, -1, 11283, -1, 11284, + -1, -1, 11285, 11287, 11288, -1, -1, 11289, + -1, -1, 11290, -1, -1, -1, -1, -1, + -1, 11291, -1, 11292, -1, -1, -1, -1, + -1, 11293, 11295, 11296, -1, 11297, 11298, 11299, + 11300, 11301, 11302, 11303, -1, -1, -1, -1, + -1, -1, 11304, -1, 11305, 11306, 11309, -1, + -1, -1, -1, -1, -1, -1, 11310, 11311, + -1, -1, 11313, 11314, -1, 11315, 11316, -1, + -1, -1, -1, 11321, -1, -1, 11322, 11323, + -1, -1, 11325, 11326, -1, -1, 11327, -1, + 11328, 11329, -1, -1, -1, -1, -1, 11330, + -1, 11332, 11333, 11335, -1, -1, -1, -1, + -1, -1, 11336, -1, 11337, 11338, 11339, 11340, + 11342, -1, -1, 11343, -1, 11345, -1, -1, + -1, 11346, 11347, -1, 11348, -1, -1, 11349, + 11350, -1, 11351, 11352, -1, -1, -1, -1, + 11353, -1, -1, -1, 11354, 11355, -1, 11356, + -1, 11359, -1, -1, -1, 11360, -1, 11361, + /* 0x9c00 */ + 11362, 11364, 11365, 11366, -1, -1, -1, -1, + 11367, 11369, -1, -1, 11370, 11372, -1, 11374, + 11375, -1, 11377, 11378, -1, -1, -1, -1, + -1, -1, -1, 11379, 11381, -1, -1, 11382, + 11383, -1, -1, 11384, 11385, 11386, -1, -1, + 11388, 11390, -1, -1, -1, 11391, 11392, -1, + -1, 11393, 11394, 11396, -1, 11397, -1, 11398, + -1, 11399, 11400, 11402, 11403, -1, 11404, -1, + -1, -1, 11405, -1, -1, 11406, -1, -1, + 11407, 11408, -1, -1, -1, -1, -1, -1, + -1, -1, 11411, 11412, 11413, -1, 11414, 11415, + 11416, -1, -1, -1, -1, 11417, 11418, 11419, + 11420, -1, -1, 11421, 11422, -1, -1, 11423, + 11424, -1, -1, -1, -1, 11425, 11426, 11427, + -1, -1, -1, -1, -1, -1, 11428, 11431, + 11433, -1, 11435, 11436, 11441, 11442, 11443, 11444, + 11445, 11446, 11447, -1, 11448, 11449, 11450, 11451, + 11452, 11454, 11455, 11456, 11457, 11458, 11460, 11461, + 11462, 11463, 11464, 11465, 11466, 11467, 11468, 11469, + 11470, 11471, 11472, 11473, 11474, 11479, 11480, 11482, + 11483, 11485, 11486, 11487, 11488, 11489, 11490, 11491, + 11492, 11493, 11495, 11496, 11497, 11498, 11499, 11500, + 11501, 11502, 11503, 11504, 11505, 11506, 11507, 11508, + 11510, 11511, 11512, 11513, 11514, 11515, 11516, 11517, + 11518, 11519, 11520, 11521, 11522, 11524, 11526, 11527, + 11528, 11529, 11530, 11531, 11532, 11534, 11535, 11536, + 11537, 11538, 11539, 11540, 11541, 11542, 11544, 11546, + 11547, 11548, -1, 11549, 11550, 11551, 11553, 11554, + 11555, 11556, 11557, 11558, -1, 11559, -1, 11561, + -1, 11563, -1, 11564, 11566, -1, -1, -1, + -1, -1, 11567, 11568, 11569, -1, 11570, -1, + 11571, -1, -1, -1, -1, -1, -1, -1, + /* 0x9d00 */ + -1, -1, -1, -1, -1, -1, 11572, 11573, + 11574, 11576, -1, -1, -1, -1, 11578, -1, + -1, -1, 11580, -1, -1, 11581, -1, -1, + -1, -1, -1, 11582, -1, 11583, 11585, 11586, + -1, -1, -1, 11588, -1, -1, 11589, -1, + 11590, -1, -1, -1, 11591, -1, -1, 11593, + 11594, -1, -1, 11595, 11596, -1, -1, -1, + -1, -1, -1, 11597, 11598, -1, -1, 11599, + -1, -1, 11600, 11601, 11602, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 11603, 11604, 11605, 11606, -1, -1, -1, -1, + -1, 11607, -1, -1, 11608, 11609, 11611, -1, + 11613, 11614, -1, -1, -1, -1, -1, -1, + -1, -1, 11615, -1, 11616, -1, 11617, 11618, + 11619, -1, 11620, -1, -1, -1, 11621, 11623, + -1, -1, -1, -1, -1, -1, 11624, -1, + -1, -1, -1, -1, -1, -1, -1, 11626, + -1, 11628, 11629, -1, -1, -1, -1, 11630, + -1, -1, -1, 11633, -1, -1, 11634, -1, + 11635, -1, 11636, -1, -1, -1, -1, -1, + -1, 11637, -1, -1, 11638, 11639, -1, -1, + -1, 11640, 11641, 11642, 11644, -1, -1, 11645, + -1, -1, 11647, -1, 11648, 11655, -1, -1, + -1, 11656, 11657, 11658, 11659, -1, -1, 11660, + 11661, 11662, 11663, 11664, 11665, -1, 11668, -1, + 11669, 11670, 11671, -1, -1, -1, -1, 11672, + -1, -1, -1, 11673, -1, -1, 11674, 11675, + -1, 11677, 11678, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 11679, 11680, -1, + -1, -1, -1, 11681, -1, -1, -1, 11682, + 11683, -1, 11684, 11685, 11687, -1, -1, -1, + 11689, 11690, 11691, -1, -1, 11693, -1, 11694, + /* 0x9e00 */ + -1, -1, -1, -1, -1, -1, -1, 11695, + -1, -1, 11696, -1, 11697, -1, 11698, 11699, + -1, -1, -1, -1, -1, 11700, 11703, -1, + 11710, -1, 11711, 11712, 11714, 11715, 11716, 11717, + 11719, 11720, 11723, 11724, 11725, 11726, 11728, 11730, + 11731, 11732, 11733, 11734, 11736, 11737, 11738, 11739, + 11740, 11741, 11742, 11743, 11744, 11745, 11746, 11747, + 11748, 11749, 11750, 11751, 11752, 11753, 11754, 11755, + 11756, 11757, 11758, 11759, 11760, 11761, 11763, 11764, + 11766, 11767, 11768, 11769, 11770, 11771, 11772, 11773, + 11774, 11775, 11776, 11777, 11778, 11779, 11780, 11781, + 11782, 11783, 11784, 11786, 11787, 11788, 11789, 11790, + 11791, 11792, 11793, 11794, 11795, 11802, 11803, 11804, + 11805, 11806, 11807, 11808, 11809, 11810, -1, 11811, + 11812, 11813, 11814, 11815, 11816, 11817, -1, -1, + 11819, 11822, 11824, 11825, 11826, 11829, 11831, -1, + -1, -1, -1, 11832, 11833, 11834, -1, 11835, + -1, -1, -1, -1, -1, -1, -1, 11836, + -1, -1, -1, -1, -1, -1, -1, 11837, + -1, -1, -1, -1, -1, -1, 11839, -1, + -1, -1, -1, -1, 11840, 11842, 11843, -1, + -1, 11844, 11846, 11851, 11856, 11858, -1, 11859, + -1, -1, -1, -1, 11863, 11867, -1, -1, + 11872, 11874, 11878, 11883, 11886, 11890, -1, -1, + -1, -1, -1, 11894, 11895, -1, -1, -1, + -1, 11897, -1, -1, 11898, -1, -1, 11899, + -1, 11900, 11901, -1, -1, -1, -1, -1, + 11902, 11903, -1, 11904, -1, -1, 11905, -1, + -1, 11907, -1, -1, 11908, -1, -1, -1, + 11909, 11910, 11911, -1, -1, 11912, -1, -1, + -1, 11913, 11914, -1, 11915, -1, 11916, 11917, + -1, 11918, -1, -1, -1, 11919, 11920, 11921, + /* 0x9f00 */ + -1, -1, 11923, 11924, -1, -1, -1, 11925, + 11927, 11930, -1, 11931, 11932, 11933, 11934, -1, + -1, 11935, 11936, 11937, -1, 11939, -1, 11940, + -1, -1, -1, -1, -1, -1, -1, -1, + 11942, 11943, -1, -1, -1, -1, 11944, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 11945, -1, -1, -1, + -1, 11946, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 11947, -1, -1, + -1, -1, 11948, 11952, -1, -1, 11954, 11956, + 11958, 11962, 11964, 11966, 11967, 11969, -1, 11970, + -1, 11971, 11972, -1, 11973, -1, -1, 11974, + 11975, 11976, 11978, 11980, -1, -1, 11981, 11982, + -1, 11985, 11986, -1, 11988, -1, -1, -1, + 11989, 11990, 11991, -1, -1, -1, 11992, 11993, + -1, -1, -1, -1, -1, -1, -1, 11994, + 11996, 11997, 11998, 11999, 12000, 12002, 12003, 12004, + 12005, 12006, 12007, 12008, 12009, 12010, 12013, -1, + 12014, -1, 12015, -1, 12018, 12019, -1, -1, + -1, 12020, 12022, 12023, 12024, 12026, 12029, 12031, + -1, -1, 12033, -1, -1, 12036, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, +}; + diff --git a/libs/libiconv/lib/cns11643.h b/libs/libiconv/lib/cns11643.h new file mode 100644 index 00000000..5b166412 --- /dev/null +++ b/libs/libiconv/lib/cns11643.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CNS 11643-1992 + */ + +/* ISO-2022-CN and EUC-TW use CNS 11643-1992 planes 1 to 7. We also + * have a table for the older plane 15. We use a trick to keep the + * Unicode -> CNS 11643 table as small as possible (see cns11643_inv.h). + */ + +#include "cns11643_1.h" +#include "cns11643_2.h" +#include "cns11643_3.h" +#include "cns11643_4.h" +#include "cns11643_5.h" +#include "cns11643_6.h" +#include "cns11643_7.h" +#include "cns11643_15.h" +#include "cns11643_inv.h" + +/* Returns the plane number (1,...,7,15) in r[0], the two bytes in r[1],r[2]. */ +#define cns11643_wctomb cns11643_inv_wctomb diff --git a/libs/libiconv/lib/cns11643_1.h b/libs/libiconv/lib/cns11643_1.h new file mode 100644 index 00000000..24abb5cc --- /dev/null +++ b/libs/libiconv/lib/cns11643_1.h @@ -0,0 +1,893 @@ +/* + * Copyright (C) 1999-2005 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CNS 11643-1992 plane 1 + */ + +static const unsigned short cns11643_1_2uni_page21[500] = { + /* 0x21 */ + 0x3000, 0xff0c, 0x3001, 0x3002, 0xff0e, 0x30fb, 0xff1b, 0xff1a, + 0xff1f, 0xff01, 0xfe30, 0x2026, 0x2025, 0xfe50, 0xfe51, 0xfe52, + 0x00b7, 0xfe54, 0xfe55, 0xfe56, 0xfe57, 0xfe31, 0x2014, 0xfe32, + 0x2013, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xff08, 0xff09, 0xfe35, + 0xfe36, 0xff5b, 0xff5d, 0xfe37, 0xfe38, 0x3014, 0x3015, 0xfe39, + 0xfe3a, 0x3010, 0x3011, 0xfe3b, 0xfe3c, 0x300a, 0x300b, 0xfe3d, + 0xfe3e, 0x3008, 0x3009, 0xfe3f, 0xfe40, 0x300c, 0x300d, 0xfe41, + 0xfe42, 0x300e, 0x300f, 0xfe43, 0xfe44, 0xfe59, 0xfe5a, 0xfe5b, + 0xfe5c, 0xfe5d, 0xfe5e, 0x2018, 0x2019, 0x201c, 0x201d, 0x301d, + 0x301e, 0x2032, 0x2035, 0xff03, 0xff06, 0xff0a, 0x203b, 0x00a7, + 0x3003, 0x25cb, 0x25cf, 0x25b3, 0x25b2, 0x25ce, 0x2606, 0x2605, + 0x25c7, 0x25c6, 0x25a1, 0x25a0, 0x25bd, 0x25bc, + /* 0x22 */ + 0x32a3, 0x2105, 0x203e, 0xfffd, 0xff3f, 0xfffd, 0xfe49, 0xfe4a, + 0xfe4d, 0xfe4e, 0xfe4b, 0xfe4c, 0xfe5f, 0xfe60, 0xfe61, 0xff0b, + 0xff0d, 0x00d7, 0x00f7, 0x00b1, 0x221a, 0xff1c, 0xff1e, 0xff1d, + 0x2266, 0x2267, 0x2260, 0x221e, 0x2252, 0x2261, 0xfe62, 0xfe63, + 0xfe64, 0xfe66, 0xfe65, 0x223c, 0x2229, 0x222a, 0x22a5, 0x2220, + 0x221f, 0x22bf, 0x33d2, 0x33d1, 0x222b, 0x222e, 0x2235, 0x2234, + 0x2640, 0x2642, 0x2641, 0x2609, 0x2191, 0x2193, 0x2192, 0x2190, + 0x2196, 0x2197, 0x2199, 0x2198, 0x2016, 0xff5c, 0xff0f, 0xff3c, + 0x2215, 0xfe68, 0xff04, 0xffe5, 0x3012, 0xffe0, 0xffe1, 0xff05, + 0xff20, 0x2103, 0x2109, 0xfe69, 0xfe6a, 0xfe6b, 0x33d5, 0x339c, + 0x339d, 0x339e, 0x33ce, 0x33a1, 0x338e, 0x338f, 0x33c4, 0x00b0, + 0x5159, 0x515b, 0x515e, 0x515d, 0x5161, 0x5163, + /* 0x23 */ + 0x55e7, 0x74e9, 0x7cce, 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, + 0x2586, 0x2587, 0x2588, 0x258f, 0x258e, 0x258d, 0x258c, 0x258b, + 0x258a, 0x2589, 0x253c, 0x2534, 0x252c, 0x2524, 0x251c, 0x2594, + 0x2500, 0x2502, 0x2595, 0x250c, 0x2510, 0x2514, 0x2518, 0x256d, + 0x256e, 0x2570, 0x256f, 0x2550, 0x255e, 0x256a, 0x2561, 0x25e2, + 0x25e3, 0x25e5, 0x25e4, 0x2571, 0x2572, 0x2573, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x24 */ + 0xff10, 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, + 0xff18, 0xff19, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, + 0x2166, 0x2167, 0x2168, 0x2169, 0x3021, 0x3022, 0x3023, 0x3024, + 0x3025, 0x3026, 0x3027, 0x3028, 0x3029, 0xfffd, 0x5344, 0xfffd, + 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, + 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, + 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, + 0xff39, 0xff3a, 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, + 0xff47, 0xff48, 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, + 0xff4f, 0xff50, 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, + 0xff57, 0xff58, 0xff59, 0xff5a, 0x0391, 0x0392, 0x0393, 0x0394, + 0x0395, 0x0396, 0x0397, 0x0398, 0x0399, 0x039a, + /* 0x25 */ + 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, 0x03a1, 0x03a3, + 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2, + 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, + 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, + 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 0x3105, 0x3106, + 0x3107, 0x3108, 0x3109, 0x310a, 0x310b, 0x310c, 0x310d, 0x310e, + 0x310f, 0x3110, 0x3111, 0x3112, 0x3113, 0x3114, 0x3115, 0x3116, + 0x3117, 0x3118, 0x3119, 0x311a, 0x311b, 0x311c, 0x311d, 0x311e, + 0x311f, 0x3120, 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, + 0x3127, 0x3128, 0x3129, 0x02d9, 0x02c9, 0x02ca, 0x02c7, 0x02cb, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x26 */ + 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, + 0x2468, 0x2469, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478, 0x2479, + 0x247a, 0x247b, 0x247c, 0x247d, 0x2170, 0x2171, 0x2172, 0x2173, + 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, +}; +static const unsigned short cns11643_1_2uni_page42[34] = { + /* 0x42 */ + 0x2400, 0x2401, 0x2402, 0x2403, 0x2404, 0x2405, 0x2406, 0x2407, + 0x2408, 0x2409, 0x240a, 0x240b, 0x240c, 0x240d, 0x240e, 0x240f, + 0x2410, 0x2411, 0x2412, 0x2413, 0x2414, 0x2415, 0x2416, 0x2417, + 0x2418, 0x2419, 0x241a, 0x241b, 0x241c, 0x241d, 0x241e, 0x241f, + 0x2421, 0x20ac, +}; +static const unsigned short cns11643_1_2uni_page44[5401] = { + /* 0x44 */ + 0x4e00, 0x4e59, 0x4e01, 0x4e03, 0x4e43, 0x4e5d, 0x4e86, 0x4e8c, + 0x4eba, 0x513f, 0x5165, 0x516b, 0x51e0, 0x5200, 0x5201, 0x529b, + 0x5315, 0x5341, 0x535c, 0x53c8, 0x4e09, 0x4e0b, 0x4e08, 0x4e0a, + 0x4e2b, 0x4e38, 0x51e1, 0x4e45, 0x4e48, 0x4e5f, 0x4e5e, 0x4e8e, + 0x4ea1, 0x5140, 0x5203, 0x52fa, 0x5343, 0x53c9, 0x53e3, 0x571f, + 0x58eb, 0x5915, 0x5927, 0x5973, 0x5b50, 0x5b51, 0x5b53, 0x5bf8, + 0x5c0f, 0x5c22, 0x5c38, 0x5c71, 0x5ddd, 0x5de5, 0x5df1, 0x5df2, + 0x5df3, 0x5dfe, 0x5e72, 0x5efe, 0x5f0b, 0x5f13, 0x624d, 0x4e11, + 0x4e10, 0x4e0d, 0x4e2d, 0x4e30, 0x4e39, 0x4e4b, 0x5c39, 0x4e88, + 0x4e91, 0x4e95, 0x4e92, 0x4e94, 0x4ea2, 0x4ec1, 0x4ec0, 0x4ec3, + 0x4ec6, 0x4ec7, 0x4ecd, 0x4eca, 0x4ecb, 0x4ec4, 0x5143, 0x5141, + 0x5167, 0x516d, 0x516e, 0x516c, 0x5197, 0x51f6, + /* 0x45 */ + 0x5206, 0x5207, 0x5208, 0x52fb, 0x52fe, 0x52ff, 0x5316, 0x5339, + 0x5348, 0x5347, 0x5345, 0x535e, 0x5384, 0x53cb, 0x53ca, 0x53cd, + 0x58ec, 0x5929, 0x592b, 0x592a, 0x592d, 0x5b54, 0x5c11, 0x5c24, + 0x5c3a, 0x5c6f, 0x5df4, 0x5e7b, 0x5eff, 0x5f14, 0x5f15, 0x5fc3, + 0x6208, 0x6236, 0x624b, 0x624e, 0x652f, 0x6587, 0x6597, 0x65a4, + 0x65b9, 0x65e5, 0x66f0, 0x6708, 0x6728, 0x6b20, 0x6b62, 0x6b79, + 0x6bcb, 0x6bd4, 0x6bdb, 0x6c0f, 0x6c34, 0x706b, 0x722a, 0x7236, + 0x723b, 0x7247, 0x7259, 0x725b, 0x72ac, 0x738b, 0x4e19, 0x4e16, + 0x4e15, 0x4e14, 0x4e18, 0x4e3b, 0x4e4d, 0x4e4f, 0x4e4e, 0x4ee5, + 0x4ed8, 0x4ed4, 0x4ed5, 0x4ed6, 0x4ed7, 0x4ee3, 0x4ee4, 0x4ed9, + 0x4ede, 0x5145, 0x5144, 0x5189, 0x518a, 0x51ac, 0x51f9, 0x51fa, + 0x51f8, 0x520a, 0x52a0, 0x529f, 0x5305, 0x5306, + /* 0x46 */ + 0x5317, 0x531d, 0x4edf, 0x534a, 0x5349, 0x5361, 0x5360, 0x536f, + 0x536e, 0x53bb, 0x53ef, 0x53e4, 0x53f3, 0x53ec, 0x53ee, 0x53e9, + 0x53e8, 0x53fc, 0x53f8, 0x53f5, 0x53eb, 0x53e6, 0x53ea, 0x53f2, + 0x53f1, 0x53f0, 0x53e5, 0x53ed, 0x53fb, 0x56db, 0x56da, 0x5916, + 0x592e, 0x5931, 0x5974, 0x5976, 0x5b55, 0x5b83, 0x5c3c, 0x5de8, + 0x5de7, 0x5de6, 0x5e02, 0x5e03, 0x5e73, 0x5e7c, 0x5f01, 0x5f18, + 0x5f17, 0x5fc5, 0x620a, 0x6253, 0x6254, 0x6252, 0x6251, 0x65a5, + 0x65e6, 0x672e, 0x672c, 0x672a, 0x672b, 0x672d, 0x6b63, 0x6bcd, + 0x6c11, 0x6c10, 0x6c38, 0x6c41, 0x6c40, 0x6c3e, 0x72af, 0x7384, + 0x7389, 0x74dc, 0x74e6, 0x7518, 0x751f, 0x7528, 0x7529, 0x7530, + 0x7531, 0x7532, 0x7533, 0x758b, 0x767d, 0x76ae, 0x76bf, 0x76ee, + 0x77db, 0x77e2, 0x77f3, 0x793a, 0x79be, 0x7a74, + /* 0x47 */ + 0x7acb, 0x4e1e, 0x4e1f, 0x4e52, 0x4e53, 0x4e69, 0x4e99, 0x4ea4, + 0x4ea6, 0x4ea5, 0x4eff, 0x4f09, 0x4f19, 0x4f0a, 0x4f15, 0x4f0d, + 0x4f10, 0x4f11, 0x4f0f, 0x4ef2, 0x4ef6, 0x4efb, 0x4ef0, 0x4ef3, + 0x4efd, 0x4f01, 0x4f0b, 0x5149, 0x5147, 0x5146, 0x5148, 0x5168, + 0x5171, 0x518d, 0x51b0, 0x5217, 0x5211, 0x5212, 0x520e, 0x5216, + 0x52a3, 0x5308, 0x5321, 0x5320, 0x5370, 0x5371, 0x5409, 0x540f, + 0x540c, 0x540a, 0x5410, 0x5401, 0x540b, 0x5404, 0x5411, 0x540d, + 0x5408, 0x5403, 0x540e, 0x5406, 0x5412, 0x56e0, 0x56de, 0x56dd, + 0x5733, 0x5730, 0x5728, 0x572d, 0x572c, 0x572f, 0x5729, 0x5919, + 0x591a, 0x5937, 0x5938, 0x5984, 0x5978, 0x5983, 0x597d, 0x5979, + 0x5982, 0x5981, 0x5b57, 0x5b58, 0x5b87, 0x5b88, 0x5b85, 0x5b89, + 0x5bfa, 0x5c16, 0x5c79, 0x5dde, 0x5e06, 0x5e76, + /* 0x48 */ + 0x5e74, 0x5f0f, 0x5f1b, 0x5fd9, 0x5fd6, 0x620e, 0x620c, 0x620d, + 0x6210, 0x6263, 0x625b, 0x6258, 0x6536, 0x65e9, 0x65e8, 0x65ec, + 0x65ed, 0x66f2, 0x66f3, 0x6709, 0x673d, 0x6734, 0x6731, 0x6735, + 0x6b21, 0x6b64, 0x6b7b, 0x6c16, 0x6c5d, 0x6c57, 0x6c59, 0x6c5f, + 0x6c60, 0x6c50, 0x6c55, 0x6c61, 0x6c5b, 0x6c4d, 0x6c4e, 0x7070, + 0x725f, 0x725d, 0x767e, 0x7af9, 0x7c73, 0x7cf8, 0x7f36, 0x7f8a, + 0x7fbd, 0x8001, 0x8003, 0x800c, 0x8012, 0x8033, 0x807f, 0x8089, + 0x808b, 0x808c, 0x81e3, 0x81ea, 0x81f3, 0x81fc, 0x820c, 0x821b, + 0x821f, 0x826e, 0x8272, 0x827e, 0x866b, 0x8840, 0x884c, 0x8863, + 0x897f, 0x9621, 0x4e32, 0x4ea8, 0x4f4d, 0x4f4f, 0x4f47, 0x4f57, + 0x4f5e, 0x4f34, 0x4f5b, 0x4f55, 0x4f30, 0x4f50, 0x4f51, 0x4f3d, + 0x4f3a, 0x4f38, 0x4f43, 0x4f54, 0x4f3c, 0x4f46, + /* 0x49 */ + 0x4f63, 0x4f5c, 0x4f60, 0x4f2f, 0x4f4e, 0x4f36, 0x4f59, 0x4f5d, + 0x4f48, 0x4f5a, 0x514c, 0x514b, 0x514d, 0x5175, 0x51b6, 0x51b7, + 0x5225, 0x5224, 0x5229, 0x522a, 0x5228, 0x52ab, 0x52a9, 0x52aa, + 0x52ac, 0x5323, 0x5373, 0x5375, 0x541d, 0x542d, 0x541e, 0x543e, + 0x5426, 0x544e, 0x5427, 0x5446, 0x5443, 0x5433, 0x5448, 0x5442, + 0x541b, 0x5429, 0x544a, 0x5439, 0x543b, 0x5438, 0x542e, 0x5435, + 0x5436, 0x5420, 0x543c, 0x5440, 0x5431, 0x542b, 0x541f, 0x542c, + 0x56ea, 0x56f0, 0x56e4, 0x56eb, 0x574a, 0x5751, 0x5740, 0x574d, + 0x5747, 0x574e, 0x573e, 0x5750, 0x574f, 0x573b, 0x58ef, 0x593e, + 0x599d, 0x5992, 0x59a8, 0x599e, 0x59a3, 0x5999, 0x5996, 0x598d, + 0x59a4, 0x5993, 0x598a, 0x59a5, 0x5b5d, 0x5b5c, 0x5b5a, 0x5b5b, + 0x5b8c, 0x5b8b, 0x5b8f, 0x5c2c, 0x5c40, 0x5c41, + /* 0x4a */ + 0x5c3f, 0x5c3e, 0x5c90, 0x5c91, 0x5c94, 0x5c8c, 0x5deb, 0x5e0c, + 0x5e8f, 0x5e87, 0x5e8a, 0x5ef7, 0x5f04, 0x5f1f, 0x5f64, 0x5f62, + 0x5f77, 0x5f79, 0x5fd8, 0x5fcc, 0x5fd7, 0x5fcd, 0x5ff1, 0x5feb, + 0x5ff8, 0x5fea, 0x6212, 0x6211, 0x6284, 0x6297, 0x6296, 0x6280, + 0x6276, 0x6289, 0x626d, 0x628a, 0x627c, 0x627e, 0x6279, 0x6273, + 0x6292, 0x626f, 0x6298, 0x626e, 0x6295, 0x6293, 0x6291, 0x6286, + 0x6539, 0x653b, 0x6538, 0x65f1, 0x66f4, 0x675f, 0x674e, 0x674f, + 0x6750, 0x6751, 0x675c, 0x6756, 0x675e, 0x6749, 0x6746, 0x6760, + 0x6753, 0x6757, 0x6b65, 0x6bcf, 0x6c42, 0x6c5e, 0x6c99, 0x6c81, + 0x6c88, 0x6c89, 0x6c85, 0x6c9b, 0x6c6a, 0x6c7a, 0x6c90, 0x6c70, + 0x6c8c, 0x6c68, 0x6c96, 0x6c92, 0x6c7d, 0x6c83, 0x6c72, 0x6c7e, + 0x6c74, 0x6c86, 0x6c76, 0x6c8d, 0x6c94, 0x6c98, + /* 0x4b */ + 0x6c82, 0x7076, 0x707c, 0x707d, 0x7078, 0x7262, 0x7261, 0x7260, + 0x72c4, 0x72c2, 0x7396, 0x752c, 0x752b, 0x7537, 0x7538, 0x7682, + 0x76ef, 0x77e3, 0x79c1, 0x79c0, 0x79bf, 0x7a76, 0x7cfb, 0x7f55, + 0x8096, 0x8093, 0x809d, 0x8098, 0x809b, 0x809a, 0x80b2, 0x826f, + 0x8292, 0x828b, 0x828d, 0x898b, 0x89d2, 0x8a00, 0x8c37, 0x8c46, + 0x8c55, 0x8c9d, 0x8d64, 0x8d70, 0x8db3, 0x8eab, 0x8eca, 0x8f9b, + 0x8fb0, 0x8fc2, 0x8fc6, 0x8fc5, 0x8fc4, 0x5de1, 0x9091, 0x90a2, + 0x90aa, 0x90a6, 0x90a3, 0x9149, 0x91c6, 0x91cc, 0x9632, 0x962e, + 0x9631, 0x962a, 0x962c, 0x4e26, 0x4e56, 0x4e73, 0x4e8b, 0x4e9b, + 0x4e9e, 0x4eab, 0x4eac, 0x4f6f, 0x4f9d, 0x4f8d, 0x4f73, 0x4f7f, + 0x4f6c, 0x4f9b, 0x4f8b, 0x4f86, 0x4f83, 0x4f70, 0x4f75, 0x4f88, + 0x4f69, 0x4f7b, 0x4f96, 0x4f7e, 0x4f8f, 0x4f91, + /* 0x4c */ + 0x4f7a, 0x5154, 0x5152, 0x5155, 0x5169, 0x5177, 0x5176, 0x5178, + 0x51bd, 0x51fd, 0x523b, 0x5238, 0x5237, 0x523a, 0x5230, 0x522e, + 0x5236, 0x5241, 0x52be, 0x52bb, 0x5352, 0x5354, 0x5353, 0x5351, + 0x5366, 0x5377, 0x5378, 0x5379, 0x53d6, 0x53d4, 0x53d7, 0x5473, + 0x5475, 0x5496, 0x5478, 0x5495, 0x5480, 0x547b, 0x5477, 0x5484, + 0x5492, 0x5486, 0x547c, 0x5490, 0x5471, 0x5476, 0x548c, 0x549a, + 0x5462, 0x5468, 0x548b, 0x547d, 0x548e, 0x56fa, 0x5783, 0x5777, + 0x576a, 0x5769, 0x5761, 0x5766, 0x5764, 0x577c, 0x591c, 0x5949, + 0x5947, 0x5948, 0x5944, 0x5954, 0x59be, 0x59bb, 0x59d4, 0x59b9, + 0x59ae, 0x59d1, 0x59c6, 0x59d0, 0x59cd, 0x59cb, 0x59d3, 0x59ca, + 0x59af, 0x59b3, 0x59d2, 0x59c5, 0x5b5f, 0x5b64, 0x5b63, 0x5b97, + 0x5b9a, 0x5b98, 0x5b9c, 0x5b99, 0x5b9b, 0x5c1a, + /* 0x4d */ + 0x5c48, 0x5c45, 0x5c46, 0x5cb7, 0x5ca1, 0x5cb8, 0x5ca9, 0x5cab, + 0x5cb1, 0x5cb3, 0x5e18, 0x5e1a, 0x5e16, 0x5e15, 0x5e1b, 0x5e11, + 0x5e78, 0x5e9a, 0x5e97, 0x5e9c, 0x5e95, 0x5e96, 0x5ef6, 0x5f26, + 0x5f27, 0x5f29, 0x5f80, 0x5f81, 0x5f7f, 0x5f7c, 0x5fdd, 0x5fe0, + 0x5ffd, 0x5ff5, 0x5fff, 0x600f, 0x6014, 0x602f, 0x6035, 0x6016, + 0x602a, 0x6015, 0x6021, 0x6027, 0x6029, 0x602b, 0x601b, 0x6216, + 0x6215, 0x623f, 0x623e, 0x6240, 0x627f, 0x62c9, 0x62cc, 0x62c4, + 0x62bf, 0x62c2, 0x62b9, 0x62d2, 0x62db, 0x62ab, 0x62d3, 0x62d4, + 0x62cb, 0x62c8, 0x62a8, 0x62bd, 0x62bc, 0x62d0, 0x62d9, 0x62c7, + 0x62cd, 0x62b5, 0x62da, 0x62b1, 0x62d8, 0x62d6, 0x62d7, 0x62c6, + 0x62ac, 0x62ce, 0x653e, 0x65a7, 0x65bc, 0x65fa, 0x6614, 0x6613, + 0x660c, 0x6606, 0x6602, 0x660e, 0x6600, 0x660f, + /* 0x4e */ + 0x6615, 0x660a, 0x6607, 0x670d, 0x670b, 0x676d, 0x678b, 0x6795, + 0x6771, 0x679c, 0x6773, 0x6777, 0x6787, 0x679d, 0x6797, 0x676f, + 0x6770, 0x677f, 0x6789, 0x677e, 0x6790, 0x6775, 0x679a, 0x6793, + 0x677c, 0x676a, 0x6772, 0x6b23, 0x6b66, 0x6b67, 0x6b7f, 0x6c13, + 0x6c1b, 0x6ce3, 0x6ce8, 0x6cf3, 0x6cb1, 0x6ccc, 0x6ce5, 0x6cb3, + 0x6cbd, 0x6cbe, 0x6cbc, 0x6ce2, 0x6cab, 0x6cd5, 0x6cd3, 0x6cb8, + 0x6cc4, 0x6cb9, 0x6cc1, 0x6cae, 0x6cd7, 0x6cc5, 0x6cf1, 0x6cbf, + 0x6cbb, 0x6ce1, 0x6cdb, 0x6cca, 0x6cac, 0x6cef, 0x6cdc, 0x6cd6, + 0x6ce0, 0x7095, 0x708e, 0x7092, 0x708a, 0x7099, 0x722c, 0x722d, + 0x7238, 0x7248, 0x7267, 0x7269, 0x72c0, 0x72ce, 0x72d9, 0x72d7, + 0x72d0, 0x73a9, 0x73a8, 0x739f, 0x73ab, 0x73a5, 0x753d, 0x759d, + 0x7599, 0x759a, 0x7684, 0x76c2, 0x76f2, 0x76f4, + /* 0x4f */ + 0x77e5, 0x77fd, 0x793e, 0x7940, 0x7941, 0x79c9, 0x79c8, 0x7a7a, + 0x7a79, 0x7afa, 0x7cfe, 0x7f54, 0x7f8c, 0x7f8b, 0x8005, 0x80ba, + 0x80a5, 0x80a2, 0x80b1, 0x80a1, 0x80ab, 0x80a9, 0x80b4, 0x80aa, + 0x80af, 0x81e5, 0x81fe, 0x820d, 0x82b3, 0x829d, 0x8299, 0x82ad, + 0x82bd, 0x829f, 0x82b9, 0x82b1, 0x82ac, 0x82a5, 0x82af, 0x82b8, + 0x82a3, 0x82b0, 0x82be, 0x82b7, 0x864e, 0x8671, 0x521d, 0x8868, + 0x8ecb, 0x8fce, 0x8fd4, 0x8fd1, 0x90b5, 0x90b8, 0x90b1, 0x90b6, + 0x91c7, 0x91d1, 0x9577, 0x9580, 0x961c, 0x9640, 0x963f, 0x963b, + 0x9644, 0x9642, 0x96b9, 0x96e8, 0x9752, 0x975e, 0x4e9f, 0x4ead, + 0x4eae, 0x4fe1, 0x4fb5, 0x4faf, 0x4fbf, 0x4fe0, 0x4fd1, 0x4fcf, + 0x4fdd, 0x4fc3, 0x4fb6, 0x4fd8, 0x4fdf, 0x4fca, 0x4fd7, 0x4fae, + 0x4fd0, 0x4fc4, 0x4fc2, 0x4fda, 0x4fce, 0x4fde, + /* 0x50 */ + 0x4fb7, 0x5157, 0x5192, 0x5191, 0x51a0, 0x524e, 0x5243, 0x524a, + 0x524d, 0x524c, 0x524b, 0x5247, 0x52c7, 0x52c9, 0x52c3, 0x52c1, + 0x530d, 0x5357, 0x537b, 0x539a, 0x53db, 0x54ac, 0x54c0, 0x54a8, + 0x54ce, 0x54c9, 0x54b8, 0x54a6, 0x54b3, 0x54c7, 0x54c2, 0x54bd, + 0x54aa, 0x54c1, 0x54c4, 0x54c8, 0x54af, 0x54ab, 0x54b1, 0x54bb, + 0x54a9, 0x54a7, 0x54bf, 0x56ff, 0x5782, 0x578b, 0x57a0, 0x57a3, + 0x57a2, 0x57ce, 0x57ae, 0x5793, 0x5955, 0x5951, 0x594f, 0x594e, + 0x5950, 0x59dc, 0x59d8, 0x59ff, 0x59e3, 0x59e8, 0x5a03, 0x59e5, + 0x59ea, 0x59da, 0x59e6, 0x5a01, 0x59fb, 0x5b69, 0x5ba3, 0x5ba6, + 0x5ba4, 0x5ba2, 0x5ba5, 0x5c01, 0x5c4e, 0x5c4f, 0x5c4d, 0x5c4b, + 0x5cd9, 0x5cd2, 0x5df7, 0x5e1d, 0x5e25, 0x5e1f, 0x5e7d, 0x5ea0, + 0x5ea6, 0x5efa, 0x5f08, 0x5f2d, 0x5f65, 0x5f88, + /* 0x51 */ + 0x5f85, 0x5f8a, 0x5f8b, 0x5f87, 0x5f8c, 0x5f89, 0x6012, 0x601d, + 0x6020, 0x6025, 0x600e, 0x6028, 0x604d, 0x6070, 0x6068, 0x6062, + 0x6046, 0x6043, 0x606c, 0x606b, 0x606a, 0x6064, 0x6241, 0x62dc, + 0x6316, 0x6309, 0x62fc, 0x62ed, 0x6301, 0x62ee, 0x62fd, 0x6307, + 0x62f1, 0x62f7, 0x62ef, 0x62ec, 0x62fe, 0x62f4, 0x6311, 0x6302, + 0x653f, 0x6545, 0x65ab, 0x65bd, 0x65e2, 0x6625, 0x662d, 0x6620, + 0x6627, 0x662f, 0x661f, 0x6628, 0x6631, 0x6624, 0x66f7, 0x67ff, + 0x67d3, 0x67f1, 0x67d4, 0x67d0, 0x67ec, 0x67b6, 0x67af, 0x67f5, + 0x67e9, 0x67ef, 0x67c4, 0x67d1, 0x67b4, 0x67da, 0x67e5, 0x67b8, + 0x67cf, 0x67de, 0x67f3, 0x67b0, 0x67d9, 0x67e2, 0x67dd, 0x67d2, + 0x6b6a, 0x6b83, 0x6b86, 0x6bb5, 0x6bd2, 0x6bd7, 0x6c1f, 0x6cc9, + 0x6d0b, 0x6d32, 0x6d2a, 0x6d41, 0x6d25, 0x6d0c, + /* 0x52 */ + 0x6d31, 0x6d1e, 0x6d17, 0x6d3b, 0x6d3d, 0x6d3e, 0x6d36, 0x6d1b, + 0x6cf5, 0x6d39, 0x6d27, 0x6d38, 0x6d29, 0x6d2e, 0x6d35, 0x6d0e, + 0x6d2b, 0x70ab, 0x70ba, 0x70b3, 0x70ac, 0x70af, 0x70ad, 0x70b8, + 0x70ae, 0x70a4, 0x7230, 0x7272, 0x726f, 0x7274, 0x72e9, 0x72e0, + 0x72e1, 0x73b7, 0x73ca, 0x73bb, 0x73b2, 0x73cd, 0x73c0, 0x73b3, + 0x751a, 0x752d, 0x754f, 0x754c, 0x754e, 0x754b, 0x75ab, 0x75a4, + 0x75a5, 0x75a2, 0x75a3, 0x7678, 0x7686, 0x7687, 0x7688, 0x76c8, + 0x76c6, 0x76c3, 0x76c5, 0x7701, 0x76f9, 0x76f8, 0x7709, 0x770b, + 0x76fe, 0x76fc, 0x7707, 0x77dc, 0x7802, 0x7814, 0x780c, 0x780d, + 0x7946, 0x7949, 0x7948, 0x7947, 0x79b9, 0x79ba, 0x79d1, 0x79d2, + 0x79cb, 0x7a7f, 0x7a81, 0x7aff, 0x7afd, 0x7c7d, 0x7d02, 0x7d05, + 0x7d00, 0x7d09, 0x7d07, 0x7d04, 0x7d06, 0x7f38, + /* 0x53 */ + 0x7f8e, 0x7fbf, 0x8010, 0x800d, 0x8011, 0x8036, 0x80d6, 0x80e5, + 0x80da, 0x80c3, 0x80c4, 0x80cc, 0x80e1, 0x80db, 0x80ce, 0x80de, + 0x80e4, 0x80dd, 0x81f4, 0x8222, 0x82e7, 0x8303, 0x8305, 0x82e3, + 0x82db, 0x82e6, 0x8304, 0x82e5, 0x8302, 0x8309, 0x82d2, 0x82d7, + 0x82f1, 0x8301, 0x82dc, 0x82d4, 0x82d1, 0x82de, 0x82d3, 0x82df, + 0x82ef, 0x8306, 0x8650, 0x8679, 0x867b, 0x867a, 0x884d, 0x886b, + 0x8981, 0x89d4, 0x8a08, 0x8a02, 0x8a03, 0x8c9e, 0x8ca0, 0x8d74, + 0x8d73, 0x8db4, 0x8ecd, 0x8ecc, 0x8ff0, 0x8fe6, 0x8fe2, 0x8fea, + 0x8fe5, 0x8fed, 0x8feb, 0x8fe4, 0x8fe8, 0x90ca, 0x90ce, 0x90c1, + 0x90c3, 0x914b, 0x914a, 0x91cd, 0x9582, 0x9650, 0x964b, 0x964c, + 0x964d, 0x9762, 0x9769, 0x97cb, 0x97ed, 0x97f3, 0x9801, 0x98a8, + 0x98db, 0x98df, 0x9996, 0x9999, 0x4e58, 0x4eb3, + /* 0x54 */ + 0x500c, 0x500d, 0x5023, 0x4fef, 0x5026, 0x5025, 0x4ff8, 0x5029, + 0x5016, 0x5006, 0x503c, 0x501f, 0x501a, 0x5012, 0x5011, 0x4ffa, + 0x5000, 0x5014, 0x5028, 0x4ff1, 0x5021, 0x500b, 0x5019, 0x5018, + 0x4ff3, 0x4fee, 0x502d, 0x502a, 0x4ffe, 0x502b, 0x5009, 0x517c, + 0x51a4, 0x51a5, 0x51a2, 0x51cd, 0x51cc, 0x51c6, 0x51cb, 0x5256, + 0x525c, 0x5254, 0x525b, 0x525d, 0x532a, 0x537f, 0x539f, 0x539d, + 0x53df, 0x54e8, 0x5510, 0x5501, 0x5537, 0x54fc, 0x54e5, 0x54f2, + 0x5506, 0x54fa, 0x5514, 0x54e9, 0x54ed, 0x54e1, 0x5509, 0x54ee, + 0x54ea, 0x54e6, 0x5527, 0x5507, 0x54fd, 0x550f, 0x5703, 0x5704, + 0x57c2, 0x57d4, 0x57cb, 0x57c3, 0x5809, 0x590f, 0x5957, 0x5958, + 0x595a, 0x5a11, 0x5a18, 0x5a1c, 0x5a1f, 0x5a1b, 0x5a13, 0x59ec, + 0x5a20, 0x5a23, 0x5a29, 0x5a25, 0x5a0c, 0x5a09, + /* 0x55 */ + 0x5b6b, 0x5c58, 0x5bb0, 0x5bb3, 0x5bb6, 0x5bb4, 0x5bae, 0x5bb5, + 0x5bb9, 0x5bb8, 0x5c04, 0x5c51, 0x5c55, 0x5c50, 0x5ced, 0x5cfd, + 0x5cfb, 0x5cea, 0x5ce8, 0x5cf0, 0x5cf6, 0x5d01, 0x5cf4, 0x5dee, + 0x5e2d, 0x5e2b, 0x5eab, 0x5ead, 0x5ea7, 0x5f31, 0x5f92, 0x5f91, + 0x5f90, 0x6059, 0x6063, 0x6065, 0x6050, 0x6055, 0x606d, 0x6069, + 0x606f, 0x6084, 0x609f, 0x609a, 0x608d, 0x6094, 0x608c, 0x6085, + 0x6096, 0x6247, 0x62f3, 0x6308, 0x62ff, 0x634e, 0x633e, 0x632f, + 0x6355, 0x6342, 0x6346, 0x634f, 0x6349, 0x633a, 0x6350, 0x633d, + 0x632a, 0x632b, 0x6328, 0x634d, 0x634c, 0x6548, 0x6549, 0x6599, + 0x65c1, 0x65c5, 0x6642, 0x6649, 0x664f, 0x6643, 0x6652, 0x664c, + 0x6645, 0x6641, 0x66f8, 0x6714, 0x6715, 0x6717, 0x6821, 0x6838, + 0x6848, 0x6846, 0x6853, 0x6839, 0x6842, 0x6854, + /* 0x56 */ + 0x6829, 0x68b3, 0x6817, 0x684c, 0x6851, 0x683d, 0x67f4, 0x6850, + 0x6840, 0x683c, 0x6843, 0x682a, 0x6845, 0x6813, 0x6818, 0x6841, + 0x6b8a, 0x6b89, 0x6bb7, 0x6c23, 0x6c27, 0x6c28, 0x6c26, 0x6c24, + 0x6cf0, 0x6d6a, 0x6d95, 0x6d88, 0x6d87, 0x6d66, 0x6d78, 0x6d77, + 0x6d59, 0x6d93, 0x6d6c, 0x6d89, 0x6d6e, 0x6d5a, 0x6d74, 0x6d69, + 0x6d8c, 0x6d8a, 0x6d79, 0x6d85, 0x6d65, 0x6d94, 0x70ca, 0x70d8, + 0x70e4, 0x70d9, 0x70c8, 0x70cf, 0x7239, 0x7279, 0x72fc, 0x72f9, + 0x72fd, 0x72f8, 0x72f7, 0x7386, 0x73ed, 0x7409, 0x73ee, 0x73e0, + 0x73ea, 0x73de, 0x7554, 0x755d, 0x755c, 0x755a, 0x7559, 0x75be, + 0x75c5, 0x75c7, 0x75b2, 0x75b3, 0x75bd, 0x75bc, 0x75b9, 0x75c2, + 0x75b8, 0x768b, 0x76b0, 0x76ca, 0x76cd, 0x76ce, 0x7729, 0x771f, + 0x7720, 0x7728, 0x77e9, 0x7830, 0x7827, 0x7838, + /* 0x57 */ + 0x781d, 0x7834, 0x7837, 0x7825, 0x782d, 0x7820, 0x781f, 0x7832, + 0x7955, 0x7950, 0x7960, 0x795f, 0x7956, 0x795e, 0x795d, 0x7957, + 0x795a, 0x79e4, 0x79e3, 0x79e7, 0x79df, 0x79e6, 0x79e9, 0x79d8, + 0x7a84, 0x7a88, 0x7ad9, 0x7b06, 0x7b11, 0x7c89, 0x7d21, 0x7d17, + 0x7d0b, 0x7d0a, 0x7d20, 0x7d22, 0x7d14, 0x7d10, 0x7d15, 0x7d1a, + 0x7d1c, 0x7d0d, 0x7d19, 0x7d1b, 0x7f3a, 0x7f5f, 0x7f94, 0x7fc5, + 0x7fc1, 0x8006, 0x8004, 0x8018, 0x8015, 0x8019, 0x8017, 0x803d, + 0x803f, 0x80f1, 0x8102, 0x80f0, 0x8105, 0x80ed, 0x80f4, 0x8106, + 0x80f8, 0x80f3, 0x8108, 0x80fd, 0x810a, 0x80fc, 0x80ef, 0x81ed, + 0x81ec, 0x8200, 0x8210, 0x822a, 0x822b, 0x8228, 0x822c, 0x82bb, + 0x832b, 0x8352, 0x8354, 0x834a, 0x8338, 0x8350, 0x8349, 0x8335, + 0x8334, 0x834f, 0x8332, 0x8339, 0x8336, 0x8317, + /* 0x58 */ + 0x8340, 0x8331, 0x8328, 0x8343, 0x8654, 0x868a, 0x86aa, 0x8693, + 0x86a4, 0x86a9, 0x868c, 0x86a3, 0x869c, 0x8870, 0x8877, 0x8881, + 0x8882, 0x887d, 0x8879, 0x8a18, 0x8a10, 0x8a0e, 0x8a0c, 0x8a15, + 0x8a0a, 0x8a17, 0x8a13, 0x8a16, 0x8a0f, 0x8a11, 0x8c48, 0x8c7a, + 0x8c79, 0x8ca1, 0x8ca2, 0x8d77, 0x8eac, 0x8ed2, 0x8ed4, 0x8ecf, + 0x8fb1, 0x9001, 0x9006, 0x8ff7, 0x9000, 0x8ffa, 0x8ff4, 0x9003, + 0x8ffd, 0x9005, 0x8ff8, 0x9095, 0x90e1, 0x90dd, 0x90e2, 0x9152, + 0x914d, 0x914c, 0x91d8, 0x91dd, 0x91d7, 0x91dc, 0x91d9, 0x9583, + 0x9662, 0x9663, 0x9661, 0x965b, 0x965d, 0x9664, 0x9658, 0x965e, + 0x96bb, 0x98e2, 0x99ac, 0x9aa8, 0x9ad8, 0x9b25, 0x9b32, 0x9b3c, + 0x4e7e, 0x507a, 0x507d, 0x505c, 0x5047, 0x5043, 0x504c, 0x505a, + 0x5049, 0x5065, 0x5076, 0x504e, 0x5055, 0x5075, + /* 0x59 */ + 0x5074, 0x5077, 0x504f, 0x500f, 0x506f, 0x506d, 0x515c, 0x5195, + 0x51f0, 0x526a, 0x526f, 0x52d2, 0x52d9, 0x52d8, 0x52d5, 0x5310, + 0x530f, 0x5319, 0x533f, 0x5340, 0x533e, 0x53c3, 0x66fc, 0x5546, + 0x556a, 0x5566, 0x5544, 0x555e, 0x5561, 0x5543, 0x554a, 0x5531, + 0x5556, 0x554f, 0x5555, 0x552f, 0x5564, 0x5538, 0x552e, 0x555c, + 0x552c, 0x5563, 0x5533, 0x5541, 0x5557, 0x5708, 0x570b, 0x5709, + 0x57df, 0x5805, 0x580a, 0x5806, 0x57e0, 0x57e4, 0x57fa, 0x5802, + 0x5835, 0x57f7, 0x57f9, 0x5920, 0x5962, 0x5a36, 0x5a41, 0x5a49, + 0x5a66, 0x5a6a, 0x5a40, 0x5a3c, 0x5a62, 0x5a5a, 0x5a46, 0x5a4a, + 0x5b70, 0x5bc7, 0x5bc5, 0x5bc4, 0x5bc2, 0x5bbf, 0x5bc6, 0x5c09, + 0x5c08, 0x5c07, 0x5c60, 0x5c5c, 0x5c5d, 0x5d07, 0x5d06, 0x5d0e, + 0x5d1b, 0x5d16, 0x5d22, 0x5d11, 0x5d29, 0x5d14, + /* 0x5a */ + 0x5d19, 0x5d24, 0x5d27, 0x5d17, 0x5de2, 0x5e38, 0x5e36, 0x5e33, + 0x5e37, 0x5eb7, 0x5eb8, 0x5eb6, 0x5eb5, 0x5ebe, 0x5f35, 0x5f37, + 0x5f57, 0x5f6c, 0x5f69, 0x5f6b, 0x5f97, 0x5f99, 0x5f9e, 0x5f98, + 0x5fa1, 0x5fa0, 0x5f9c, 0x607f, 0x60a3, 0x6089, 0x60a0, 0x60a8, + 0x60cb, 0x60b4, 0x60e6, 0x60bd, 0x60c5, 0x60bb, 0x60b5, 0x60dc, + 0x60bc, 0x60d8, 0x60d5, 0x60c6, 0x60df, 0x60b8, 0x60da, 0x60c7, + 0x621a, 0x621b, 0x6248, 0x63a0, 0x63a7, 0x6372, 0x6396, 0x63a2, + 0x63a5, 0x6377, 0x6367, 0x6398, 0x63aa, 0x6371, 0x63a9, 0x6389, + 0x6383, 0x639b, 0x636b, 0x63a8, 0x6384, 0x6388, 0x6399, 0x63a1, + 0x63ac, 0x6392, 0x638f, 0x6380, 0x637b, 0x6369, 0x6368, 0x637a, + 0x655d, 0x6556, 0x6551, 0x6559, 0x6557, 0x555f, 0x654f, 0x6558, + 0x6555, 0x6554, 0x659c, 0x659b, 0x65ac, 0x65cf, + /* 0x5b */ + 0x65cb, 0x65cc, 0x65ce, 0x665d, 0x665a, 0x6664, 0x6668, 0x6666, + 0x665e, 0x66f9, 0x52d7, 0x671b, 0x6881, 0x68af, 0x68a2, 0x6893, + 0x68b5, 0x687f, 0x6876, 0x68b1, 0x68a7, 0x6897, 0x68b0, 0x6883, + 0x68c4, 0x68ad, 0x6886, 0x6885, 0x6894, 0x689d, 0x68a8, 0x689f, + 0x68a1, 0x6882, 0x6b32, 0x6bba, 0x6beb, 0x6bec, 0x6c2b, 0x6d8e, + 0x6dbc, 0x6df3, 0x6dd9, 0x6db2, 0x6de1, 0x6dcc, 0x6de4, 0x6dfb, + 0x6dfa, 0x6e05, 0x6dc7, 0x6dcb, 0x6daf, 0x6dd1, 0x6dae, 0x6dde, + 0x6df9, 0x6db8, 0x6df7, 0x6df5, 0x6dc5, 0x6dd2, 0x6e1a, 0x6db5, + 0x6dda, 0x6deb, 0x6dd8, 0x6dea, 0x6df1, 0x6dee, 0x6de8, 0x6dc6, + 0x6dc4, 0x6daa, 0x6dec, 0x6dbf, 0x6de6, 0x70f9, 0x7109, 0x710a, + 0x70fd, 0x70ef, 0x723d, 0x727d, 0x7281, 0x731c, 0x731b, 0x7316, + 0x7313, 0x7319, 0x7387, 0x7405, 0x740a, 0x7403, + /* 0x5c */ + 0x7406, 0x73fe, 0x740d, 0x74e0, 0x74f6, 0x74f7, 0x751c, 0x7522, + 0x7565, 0x7566, 0x7562, 0x7570, 0x758f, 0x75d4, 0x75d5, 0x75b5, + 0x75ca, 0x75cd, 0x768e, 0x76d4, 0x76d2, 0x76db, 0x7737, 0x773e, + 0x773c, 0x7736, 0x7738, 0x773a, 0x786b, 0x7843, 0x784e, 0x7965, + 0x7968, 0x796d, 0x79fb, 0x7a92, 0x7a95, 0x7b20, 0x7b28, 0x7b1b, + 0x7b2c, 0x7b26, 0x7b19, 0x7b1e, 0x7b2e, 0x7c92, 0x7c97, 0x7c95, + 0x7d46, 0x7d43, 0x7d71, 0x7d2e, 0x7d39, 0x7d3c, 0x7d40, 0x7d30, + 0x7d33, 0x7d44, 0x7d2f, 0x7d42, 0x7d32, 0x7d31, 0x7f3d, 0x7f9e, + 0x7f9a, 0x7fcc, 0x7fce, 0x7fd2, 0x801c, 0x804a, 0x8046, 0x812f, + 0x8116, 0x8123, 0x812b, 0x8129, 0x8130, 0x8124, 0x8202, 0x8235, + 0x8237, 0x8236, 0x8239, 0x838e, 0x839e, 0x8398, 0x8378, 0x83a2, + 0x8396, 0x83bd, 0x83ab, 0x8392, 0x838a, 0x8393, + /* 0x5d */ + 0x8389, 0x83a0, 0x8377, 0x837b, 0x837c, 0x8386, 0x83a7, 0x8655, + 0x5f6a, 0x86c7, 0x86c0, 0x86b6, 0x86c4, 0x86b5, 0x86c6, 0x86cb, + 0x86b1, 0x86af, 0x86c9, 0x8853, 0x889e, 0x8888, 0x88ab, 0x8892, + 0x8896, 0x888d, 0x888b, 0x8993, 0x898f, 0x8a2a, 0x8a1d, 0x8a23, + 0x8a25, 0x8a31, 0x8a2d, 0x8a1f, 0x8a1b, 0x8a22, 0x8c49, 0x8c5a, + 0x8ca9, 0x8cac, 0x8cab, 0x8ca8, 0x8caa, 0x8ca7, 0x8d67, 0x8d66, + 0x8dbe, 0x8dba, 0x8edb, 0x8edf, 0x9019, 0x900d, 0x901a, 0x9017, + 0x9023, 0x901f, 0x901d, 0x9010, 0x9015, 0x901e, 0x9020, 0x900f, + 0x9022, 0x9016, 0x901b, 0x9014, 0x90e8, 0x90ed, 0x90fd, 0x9157, + 0x91ce, 0x91f5, 0x91e6, 0x91e3, 0x91e7, 0x91ed, 0x91e9, 0x9589, + 0x966a, 0x9675, 0x9673, 0x9678, 0x9670, 0x9674, 0x9676, 0x9677, + 0x966c, 0x96c0, 0x96ea, 0x96e9, 0x7ae0, 0x7adf, + /* 0x5e */ + 0x9802, 0x9803, 0x9b5a, 0x9ce5, 0x9e75, 0x9e7f, 0x9ea5, 0x9ebb, + 0x50a2, 0x508d, 0x5085, 0x5099, 0x5091, 0x5080, 0x5096, 0x5098, + 0x509a, 0x6700, 0x51f1, 0x5272, 0x5274, 0x5275, 0x5269, 0x52de, + 0x52dd, 0x52db, 0x535a, 0x53a5, 0x557b, 0x5580, 0x55a7, 0x557c, + 0x558a, 0x559d, 0x5598, 0x5582, 0x559c, 0x55aa, 0x5594, 0x5587, + 0x558b, 0x5583, 0x55b3, 0x55ae, 0x559f, 0x553e, 0x55b2, 0x559a, + 0x55bb, 0x55ac, 0x55b1, 0x557e, 0x5589, 0x55ab, 0x5599, 0x570d, + 0x582f, 0x582a, 0x5834, 0x5824, 0x5830, 0x5831, 0x5821, 0x581d, + 0x5820, 0x58f9, 0x58fa, 0x5960, 0x5a77, 0x5a9a, 0x5a7f, 0x5a92, + 0x5a9b, 0x5aa7, 0x5b73, 0x5b71, 0x5bd2, 0x5bcc, 0x5bd3, 0x5bd0, + 0x5c0a, 0x5c0b, 0x5c31, 0x5d4c, 0x5d50, 0x5d34, 0x5d47, 0x5dfd, + 0x5e45, 0x5e3d, 0x5e40, 0x5e43, 0x5e7e, 0x5eca, + /* 0x5f */ + 0x5ec1, 0x5ec2, 0x5ec4, 0x5f3c, 0x5f6d, 0x5fa9, 0x5faa, 0x5fa8, + 0x60d1, 0x60e1, 0x60b2, 0x60b6, 0x60e0, 0x611c, 0x6123, 0x60fa, + 0x6115, 0x60f0, 0x60fb, 0x60f4, 0x6168, 0x60f1, 0x610e, 0x60f6, + 0x6109, 0x6100, 0x6112, 0x621f, 0x6249, 0x63a3, 0x638c, 0x63cf, + 0x63c0, 0x63e9, 0x63c9, 0x63c6, 0x63cd, 0x63d2, 0x63e3, 0x63d0, + 0x63e1, 0x63d6, 0x63ed, 0x63ee, 0x6376, 0x63f4, 0x63ea, 0x63db, + 0x6452, 0x63da, 0x63f9, 0x655e, 0x6566, 0x6562, 0x6563, 0x6591, + 0x6590, 0x65af, 0x666e, 0x6670, 0x6674, 0x6676, 0x666f, 0x6691, + 0x667a, 0x667e, 0x6677, 0x66fe, 0x66ff, 0x671f, 0x671d, 0x68fa, + 0x68d5, 0x68e0, 0x68d8, 0x68d7, 0x6905, 0x68df, 0x68f5, 0x68ee, + 0x68e7, 0x68f9, 0x68d2, 0x68f2, 0x68e3, 0x68cb, 0x68cd, 0x690d, + 0x6912, 0x690e, 0x68c9, 0x68da, 0x696e, 0x68fb, + /* 0x60 */ + 0x6b3e, 0x6b3a, 0x6b3d, 0x6b98, 0x6b96, 0x6bbc, 0x6bef, 0x6c2e, + 0x6c2f, 0x6c2c, 0x6e2f, 0x6e38, 0x6e54, 0x6e21, 0x6e32, 0x6e67, + 0x6e4a, 0x6e20, 0x6e25, 0x6e23, 0x6e1b, 0x6e5b, 0x6e58, 0x6e24, + 0x6e56, 0x6e6e, 0x6e2d, 0x6e26, 0x6e6f, 0x6e34, 0x6e4d, 0x6e3a, + 0x6e2c, 0x6e43, 0x6e1d, 0x6e3e, 0x6ecb, 0x6e89, 0x6e19, 0x6e4e, + 0x6e63, 0x6e44, 0x6e72, 0x6e69, 0x6e5f, 0x7119, 0x711a, 0x7126, + 0x7130, 0x7121, 0x7136, 0x716e, 0x711c, 0x724c, 0x7284, 0x7280, + 0x7336, 0x7325, 0x7334, 0x7329, 0x743a, 0x742a, 0x7433, 0x7422, + 0x7425, 0x7435, 0x7436, 0x7434, 0x742f, 0x741b, 0x7426, 0x7428, + 0x7525, 0x7526, 0x756b, 0x756a, 0x75e2, 0x75db, 0x75e3, 0x75d9, + 0x75d8, 0x75de, 0x75e0, 0x767b, 0x767c, 0x7696, 0x7693, 0x76b4, + 0x76dc, 0x774f, 0x77ed, 0x785d, 0x786c, 0x786f, + /* 0x61 */ + 0x7a0d, 0x7a08, 0x7a0b, 0x7a05, 0x7a00, 0x7a98, 0x7a97, 0x7a96, + 0x7ae5, 0x7ae3, 0x7b49, 0x7b56, 0x7b46, 0x7b50, 0x7b52, 0x7b54, + 0x7b4d, 0x7b4b, 0x7b4f, 0x7b51, 0x7c9f, 0x7ca5, 0x7d5e, 0x7d50, + 0x7d68, 0x7d55, 0x7d2b, 0x7d6e, 0x7d72, 0x7d61, 0x7d66, 0x7d62, + 0x7d70, 0x7d73, 0x5584, 0x7fd4, 0x7fd5, 0x800b, 0x8052, 0x8085, + 0x8155, 0x8154, 0x814b, 0x8151, 0x814e, 0x8139, 0x8146, 0x813e, + 0x814c, 0x8153, 0x8174, 0x8212, 0x821c, 0x83e9, 0x8403, 0x83f8, + 0x840d, 0x83e0, 0x83c5, 0x840b, 0x83c1, 0x83ef, 0x83f1, 0x83f4, + 0x8457, 0x840a, 0x83f0, 0x840c, 0x83cc, 0x83fd, 0x83f2, 0x83ca, + 0x8438, 0x840e, 0x8404, 0x83dc, 0x8407, 0x83d4, 0x83df, 0x865b, + 0x86df, 0x86d9, 0x86ed, 0x86d4, 0x86db, 0x86e4, 0x86d0, 0x86de, + 0x8857, 0x88c1, 0x88c2, 0x88b1, 0x8983, 0x8996, + /* 0x62 */ + 0x8a3b, 0x8a60, 0x8a55, 0x8a5e, 0x8a3c, 0x8a41, 0x8a54, 0x8a5b, + 0x8a50, 0x8a46, 0x8a34, 0x8a3a, 0x8a36, 0x8a56, 0x8c61, 0x8c82, + 0x8caf, 0x8cbc, 0x8cb3, 0x8cbd, 0x8cc1, 0x8cbb, 0x8cc0, 0x8cb4, + 0x8cb7, 0x8cb6, 0x8cbf, 0x8cb8, 0x8d8a, 0x8d85, 0x8d81, 0x8dce, + 0x8ddd, 0x8dcb, 0x8dda, 0x8dd1, 0x8dcc, 0x8ddb, 0x8dc6, 0x8efb, + 0x8ef8, 0x8efc, 0x8f9c, 0x902e, 0x9035, 0x9031, 0x9038, 0x9032, + 0x9036, 0x9102, 0x90f5, 0x9109, 0x90fe, 0x9163, 0x9165, 0x91cf, + 0x9214, 0x9215, 0x9223, 0x9209, 0x921e, 0x920d, 0x9210, 0x9207, + 0x9211, 0x9594, 0x958f, 0x958b, 0x9591, 0x9593, 0x9592, 0x958e, + 0x968a, 0x968e, 0x968b, 0x967d, 0x9685, 0x9686, 0x968d, 0x9672, + 0x9684, 0x96c1, 0x96c5, 0x96c4, 0x96c6, 0x96c7, 0x96ef, 0x96f2, + 0x97cc, 0x9805, 0x9806, 0x9808, 0x98e7, 0x98ea, + /* 0x63 */ + 0x98ef, 0x98e9, 0x98f2, 0x98ed, 0x99ae, 0x99ad, 0x9ec3, 0x9ecd, + 0x9ed1, 0x4e82, 0x50ad, 0x50b5, 0x50b2, 0x50b3, 0x50c5, 0x50be, + 0x50ac, 0x50b7, 0x50bb, 0x50af, 0x50c7, 0x527f, 0x5277, 0x527d, + 0x52df, 0x52e6, 0x52e4, 0x52e2, 0x52e3, 0x532f, 0x55df, 0x55e8, + 0x55d3, 0x55e6, 0x55ce, 0x55dc, 0x55c7, 0x55d1, 0x55e3, 0x55e4, + 0x55ef, 0x55da, 0x55e1, 0x55c5, 0x55c6, 0x55e5, 0x55c9, 0x5712, + 0x5713, 0x585e, 0x5851, 0x5858, 0x5857, 0x585a, 0x5854, 0x586b, + 0x584c, 0x586d, 0x584a, 0x5862, 0x5852, 0x584b, 0x5967, 0x5ac1, + 0x5ac9, 0x5acc, 0x5abe, 0x5abd, 0x5abc, 0x5ab3, 0x5ac2, 0x5ab2, + 0x5d69, 0x5d6f, 0x5e4c, 0x5e79, 0x5ec9, 0x5ec8, 0x5f12, 0x5f59, + 0x5fac, 0x5fae, 0x611a, 0x610f, 0x6148, 0x611f, 0x60f3, 0x611b, + 0x60f9, 0x6101, 0x6108, 0x614e, 0x614c, 0x6144, + /* 0x64 */ + 0x614d, 0x613e, 0x6134, 0x6127, 0x610d, 0x6106, 0x6137, 0x6221, + 0x6222, 0x6413, 0x643e, 0x641e, 0x642a, 0x642d, 0x643d, 0x642c, + 0x640f, 0x641c, 0x6414, 0x640d, 0x6436, 0x6416, 0x6417, 0x6406, + 0x656c, 0x659f, 0x65b0, 0x6697, 0x6689, 0x6687, 0x6688, 0x6696, + 0x6684, 0x6698, 0x668d, 0x6703, 0x6994, 0x696d, 0x695a, 0x6977, + 0x6960, 0x6954, 0x6975, 0x6930, 0x6982, 0x694a, 0x6968, 0x696b, + 0x695e, 0x6953, 0x6979, 0x6986, 0x695d, 0x6963, 0x695b, 0x6b47, + 0x6b72, 0x6bc0, 0x6bbf, 0x6bd3, 0x6bfd, 0x6ea2, 0x6eaf, 0x6ed3, + 0x6eb6, 0x6ec2, 0x6e90, 0x6e9d, 0x6ec7, 0x6ec5, 0x6ea5, 0x6e98, + 0x6ebc, 0x6eba, 0x6eab, 0x6ed1, 0x6e96, 0x6e9c, 0x6ec4, 0x6ed4, + 0x6eaa, 0x6ea7, 0x6eb4, 0x714e, 0x7159, 0x7169, 0x7164, 0x7149, + 0x7167, 0x715c, 0x716c, 0x7166, 0x714c, 0x7165, + /* 0x65 */ + 0x715e, 0x7146, 0x7168, 0x7156, 0x723a, 0x7252, 0x7337, 0x7345, + 0x733f, 0x733e, 0x746f, 0x745a, 0x7455, 0x745f, 0x745e, 0x7441, + 0x743f, 0x7459, 0x745b, 0x745c, 0x7576, 0x7578, 0x7600, 0x75f0, + 0x7601, 0x75f2, 0x75f1, 0x75fa, 0x75ff, 0x75f4, 0x75f3, 0x76de, + 0x76df, 0x775b, 0x776b, 0x7766, 0x775e, 0x7763, 0x7779, 0x776a, + 0x776c, 0x775c, 0x7765, 0x7768, 0x7762, 0x77ee, 0x788e, 0x78b0, + 0x7897, 0x7898, 0x788c, 0x7889, 0x787c, 0x7891, 0x7893, 0x787f, + 0x797a, 0x797f, 0x7981, 0x842c, 0x79bd, 0x7a1c, 0x7a1a, 0x7a20, + 0x7a14, 0x7a1f, 0x7a1e, 0x7a9f, 0x7aa0, 0x7b77, 0x7bc0, 0x7b60, + 0x7b6e, 0x7b67, 0x7cb1, 0x7cb3, 0x7cb5, 0x7d93, 0x7d79, 0x7d91, + 0x7d81, 0x7d8f, 0x7d5b, 0x7f6e, 0x7f69, 0x7f6a, 0x7f72, 0x7fa9, + 0x7fa8, 0x7fa4, 0x8056, 0x8058, 0x8086, 0x8084, + /* 0x66 */ + 0x8171, 0x8170, 0x8178, 0x8165, 0x816e, 0x8173, 0x816b, 0x8179, + 0x817a, 0x8166, 0x8205, 0x8247, 0x8482, 0x8477, 0x843d, 0x8431, + 0x8475, 0x8466, 0x846b, 0x8449, 0x846c, 0x845b, 0x843c, 0x8435, + 0x8461, 0x8463, 0x8469, 0x846d, 0x8446, 0x865e, 0x865c, 0x865f, + 0x86f9, 0x8713, 0x8708, 0x8707, 0x8700, 0x86fe, 0x86fb, 0x8702, + 0x8703, 0x8706, 0x870a, 0x8859, 0x88df, 0x88d4, 0x88d9, 0x88dc, + 0x88d8, 0x88dd, 0x88e1, 0x88ca, 0x88d5, 0x88d2, 0x899c, 0x89e3, + 0x8a6b, 0x8a72, 0x8a73, 0x8a66, 0x8a69, 0x8a70, 0x8a87, 0x8a7c, + 0x8a63, 0x8aa0, 0x8a71, 0x8a85, 0x8a6d, 0x8a62, 0x8a6e, 0x8a6c, + 0x8a79, 0x8a7b, 0x8a3e, 0x8a68, 0x8c62, 0x8c8a, 0x8c89, 0x8cca, + 0x8cc7, 0x8cc8, 0x8cc4, 0x8cb2, 0x8cc3, 0x8cc2, 0x8cc5, 0x8de1, + 0x8ddf, 0x8de8, 0x8def, 0x8df3, 0x8dfa, 0x8dea, + /* 0x67 */ + 0x8de4, 0x8de6, 0x8eb2, 0x8f03, 0x8f09, 0x8efe, 0x8f0a, 0x8f9f, + 0x8fb2, 0x904b, 0x904a, 0x9053, 0x9042, 0x9054, 0x903c, 0x9055, + 0x9050, 0x9047, 0x904f, 0x904e, 0x904d, 0x9051, 0x903e, 0x9041, + 0x9112, 0x9117, 0x916c, 0x916a, 0x9169, 0x91c9, 0x9237, 0x9257, + 0x9238, 0x923d, 0x9240, 0x923e, 0x925b, 0x924b, 0x9264, 0x9251, + 0x9234, 0x9249, 0x924d, 0x9245, 0x9239, 0x923f, 0x925a, 0x9598, + 0x9698, 0x9694, 0x9695, 0x96cd, 0x96cb, 0x96c9, 0x96ca, 0x96f7, + 0x96fb, 0x96f9, 0x96f6, 0x9756, 0x9774, 0x9776, 0x9810, 0x9811, + 0x9813, 0x980a, 0x9812, 0x980c, 0x98fc, 0x98f4, 0x98fd, 0x98fe, + 0x99b3, 0x99b1, 0x99b4, 0x9ae1, 0x9ce9, 0x9e82, 0x9f0e, 0x9f13, + 0x9f20, 0x50e7, 0x50ee, 0x50e5, 0x50d6, 0x50ed, 0x50da, 0x50d5, + 0x50cf, 0x50d1, 0x50f1, 0x50ce, 0x50e9, 0x5162, + /* 0x68 */ + 0x51f3, 0x5283, 0x5282, 0x5331, 0x53ad, 0x55fe, 0x5600, 0x561b, + 0x5617, 0x55fd, 0x5614, 0x5606, 0x5609, 0x560d, 0x560e, 0x55f7, + 0x5616, 0x561f, 0x5608, 0x5610, 0x55f6, 0x5718, 0x5716, 0x5875, + 0x587e, 0x5883, 0x5893, 0x588a, 0x5879, 0x5885, 0x587d, 0x58fd, + 0x5925, 0x5922, 0x5924, 0x596a, 0x5969, 0x5ae1, 0x5ae6, 0x5ae9, + 0x5ad7, 0x5ad6, 0x5ad8, 0x5ae3, 0x5b75, 0x5bde, 0x5be7, 0x5be1, + 0x5be5, 0x5be6, 0x5be8, 0x5be2, 0x5be4, 0x5bdf, 0x5c0d, 0x5c62, + 0x5d84, 0x5d87, 0x5e5b, 0x5e63, 0x5e55, 0x5e57, 0x5e54, 0x5ed3, + 0x5ed6, 0x5f0a, 0x5f46, 0x5f70, 0x5fb9, 0x6147, 0x613f, 0x614b, + 0x6177, 0x6162, 0x6163, 0x615f, 0x615a, 0x6158, 0x6175, 0x622a, + 0x6487, 0x6458, 0x6454, 0x64a4, 0x6478, 0x645f, 0x647a, 0x6451, + 0x6467, 0x6434, 0x646d, 0x647b, 0x6572, 0x65a1, + /* 0x69 */ + 0x65d7, 0x65d6, 0x66a2, 0x66a8, 0x669d, 0x699c, 0x69a8, 0x6995, + 0x69c1, 0x69ae, 0x69d3, 0x69cb, 0x699b, 0x69b7, 0x69bb, 0x69ab, + 0x69b4, 0x69d0, 0x69cd, 0x69ad, 0x69cc, 0x69a6, 0x69c3, 0x69a3, + 0x6b49, 0x6b4c, 0x6c33, 0x6f33, 0x6f14, 0x6efe, 0x6f13, 0x6ef4, + 0x6f29, 0x6f3e, 0x6f20, 0x6f2c, 0x6f0f, 0x6f02, 0x6f22, 0x6eff, + 0x6eef, 0x6f06, 0x6f31, 0x6f38, 0x6f32, 0x6f23, 0x6f15, 0x6f2b, + 0x6f2f, 0x6f88, 0x6f2a, 0x6eec, 0x6f01, 0x6ef2, 0x6ecc, 0x6ef7, + 0x7194, 0x7199, 0x717d, 0x718a, 0x7184, 0x7192, 0x723e, 0x7292, + 0x7296, 0x7344, 0x7350, 0x7464, 0x7463, 0x746a, 0x7470, 0x746d, + 0x7504, 0x7591, 0x7627, 0x760d, 0x760b, 0x7609, 0x7613, 0x76e1, + 0x76e3, 0x7784, 0x777d, 0x777f, 0x7761, 0x78c1, 0x789f, 0x78a7, + 0x78b3, 0x78a9, 0x78a3, 0x798e, 0x798f, 0x798d, + /* 0x6a */ + 0x7a2e, 0x7a31, 0x7aaa, 0x7aa9, 0x7aed, 0x7aef, 0x7ba1, 0x7b95, + 0x7b8b, 0x7b75, 0x7b97, 0x7b9d, 0x7b94, 0x7b8f, 0x7bb8, 0x7b87, + 0x7b84, 0x7cb9, 0x7cbd, 0x7cbe, 0x7dbb, 0x7db0, 0x7d9c, 0x7dbd, + 0x7dbe, 0x7da0, 0x7dca, 0x7db4, 0x7db2, 0x7db1, 0x7dba, 0x7da2, + 0x7dbf, 0x7db5, 0x7db8, 0x7dad, 0x7dd2, 0x7dc7, 0x7dac, 0x7f70, + 0x7fe0, 0x7fe1, 0x7fdf, 0x805e, 0x805a, 0x8087, 0x8150, 0x8180, + 0x818f, 0x8188, 0x818a, 0x817f, 0x8182, 0x81e7, 0x81fa, 0x8207, + 0x8214, 0x821e, 0x824b, 0x84c9, 0x84bf, 0x84c6, 0x84c4, 0x8499, + 0x849e, 0x84b2, 0x849c, 0x84cb, 0x84b8, 0x84c0, 0x84d3, 0x8490, + 0x84bc, 0x84d1, 0x84ca, 0x873f, 0x871c, 0x873b, 0x8722, 0x8725, + 0x8734, 0x8718, 0x8755, 0x8737, 0x8729, 0x88f3, 0x8902, 0x88f4, + 0x88f9, 0x88f8, 0x88fd, 0x88e8, 0x891a, 0x88ef, + /* 0x6b */ + 0x8aa6, 0x8a8c, 0x8a9e, 0x8aa3, 0x8a8d, 0x8aa1, 0x8a93, 0x8aa4, + 0x8aaa, 0x8aa5, 0x8aa8, 0x8a98, 0x8a91, 0x8a9a, 0x8aa7, 0x8c6a, + 0x8c8d, 0x8c8c, 0x8cd3, 0x8cd1, 0x8cd2, 0x8d6b, 0x8d99, 0x8d95, + 0x8dfc, 0x8f14, 0x8f12, 0x8f15, 0x8f13, 0x8fa3, 0x9060, 0x9058, + 0x905c, 0x9063, 0x9059, 0x905e, 0x9062, 0x905d, 0x905b, 0x9119, + 0x9118, 0x911e, 0x9175, 0x9178, 0x9177, 0x9174, 0x9278, 0x92ac, + 0x9280, 0x9285, 0x9298, 0x9296, 0x927b, 0x9293, 0x929c, 0x92a8, + 0x927c, 0x9291, 0x95a1, 0x95a8, 0x95a9, 0x95a3, 0x95a5, 0x95a4, + 0x9699, 0x969c, 0x969b, 0x96cc, 0x96d2, 0x9700, 0x977c, 0x9785, + 0x97f6, 0x9817, 0x9818, 0x98af, 0x98b1, 0x9903, 0x9905, 0x990c, + 0x9909, 0x99c1, 0x9aaf, 0x9ab0, 0x9ae6, 0x9b41, 0x9b42, 0x9cf4, + 0x9cf6, 0x9cf3, 0x9ebc, 0x9f3b, 0x9f4a, 0x5104, + /* 0x6c */ + 0x5100, 0x50fb, 0x50f5, 0x50f9, 0x5102, 0x5108, 0x5109, 0x5105, + 0x51dc, 0x5287, 0x5288, 0x5289, 0x528d, 0x528a, 0x52f0, 0x53b2, + 0x562e, 0x563b, 0x5639, 0x5632, 0x563f, 0x5634, 0x5629, 0x5653, + 0x564e, 0x5657, 0x5674, 0x5636, 0x562f, 0x5630, 0x5880, 0x589f, + 0x589e, 0x58b3, 0x589c, 0x58ae, 0x58a9, 0x58a6, 0x596d, 0x5b09, + 0x5afb, 0x5b0b, 0x5af5, 0x5b0c, 0x5b08, 0x5bee, 0x5bec, 0x5be9, + 0x5beb, 0x5c64, 0x5c65, 0x5d9d, 0x5d94, 0x5e62, 0x5e5f, 0x5e61, + 0x5ee2, 0x5eda, 0x5edf, 0x5edd, 0x5ee3, 0x5ee0, 0x5f48, 0x5f71, + 0x5fb7, 0x5fb5, 0x6176, 0x6167, 0x616e, 0x615d, 0x6155, 0x6182, + 0x617c, 0x6170, 0x616b, 0x617e, 0x61a7, 0x6190, 0x61ab, 0x618e, + 0x61ac, 0x619a, 0x61a4, 0x6194, 0x61ae, 0x622e, 0x6469, 0x646f, + 0x6479, 0x649e, 0x64b2, 0x6488, 0x6490, 0x64b0, + /* 0x6d */ + 0x64a5, 0x6493, 0x6495, 0x64a9, 0x6492, 0x64ae, 0x64ad, 0x64ab, + 0x649a, 0x64ac, 0x6499, 0x64a2, 0x64b3, 0x6575, 0x6577, 0x6578, + 0x66ae, 0x66ab, 0x66b4, 0x66b1, 0x6a23, 0x6a1f, 0x69e8, 0x6a01, + 0x6a1e, 0x6a19, 0x69fd, 0x6a21, 0x6a13, 0x6a0a, 0x69f3, 0x6a02, + 0x6a05, 0x69ed, 0x6a11, 0x6b50, 0x6b4e, 0x6ba4, 0x6bc5, 0x6bc6, + 0x6f3f, 0x6f7c, 0x6f84, 0x6f51, 0x6f66, 0x6f54, 0x6f86, 0x6f6d, + 0x6f5b, 0x6f78, 0x6f6e, 0x6f8e, 0x6f7a, 0x6f70, 0x6f64, 0x6f97, + 0x6f58, 0x6ed5, 0x6f6f, 0x6f60, 0x6f5f, 0x719f, 0x71ac, 0x71b1, + 0x71a8, 0x7256, 0x729b, 0x734e, 0x7357, 0x7469, 0x748b, 0x7483, + 0x747e, 0x7480, 0x757f, 0x7620, 0x7629, 0x761f, 0x7624, 0x7626, + 0x7621, 0x7622, 0x769a, 0x76ba, 0x76e4, 0x778e, 0x7787, 0x778c, + 0x7791, 0x778b, 0x78cb, 0x78c5, 0x78ba, 0x78ca, + /* 0x6e */ + 0x78be, 0x78d5, 0x78bc, 0x78d0, 0x7a3f, 0x7a3c, 0x7a40, 0x7a3d, + 0x7a37, 0x7a3b, 0x7aaf, 0x7aae, 0x7bad, 0x7bb1, 0x7bc4, 0x7bb4, + 0x7bc6, 0x7bc7, 0x7bc1, 0x7ba0, 0x7bcc, 0x7cca, 0x7de0, 0x7df4, + 0x7def, 0x7dfb, 0x7dd8, 0x7dec, 0x7ddd, 0x7de8, 0x7de3, 0x7dda, + 0x7dde, 0x7de9, 0x7d9e, 0x7dd9, 0x7df2, 0x7df9, 0x7f75, 0x7f77, + 0x7faf, 0x7fe9, 0x8026, 0x819b, 0x819c, 0x819d, 0x81a0, 0x819a, + 0x8198, 0x8517, 0x853d, 0x851a, 0x84ee, 0x852c, 0x852d, 0x8513, + 0x8511, 0x8523, 0x8521, 0x8514, 0x84ec, 0x8525, 0x84ff, 0x8506, + 0x8782, 0x8774, 0x8776, 0x8760, 0x8766, 0x8778, 0x8768, 0x8759, + 0x8757, 0x874c, 0x8753, 0x885b, 0x885d, 0x8910, 0x8907, 0x8912, + 0x8913, 0x8915, 0x890a, 0x8abc, 0x8ad2, 0x8ac7, 0x8ac4, 0x8a95, + 0x8acb, 0x8af8, 0x8ab2, 0x8ac9, 0x8ac2, 0x8abf, + /* 0x6f */ + 0x8ab0, 0x8ad6, 0x8acd, 0x8ab6, 0x8ab9, 0x8adb, 0x8c4c, 0x8c4e, + 0x8c6c, 0x8ce0, 0x8cde, 0x8ce6, 0x8ce4, 0x8cec, 0x8ced, 0x8ce2, + 0x8ce3, 0x8cdc, 0x8cea, 0x8ce1, 0x8d6d, 0x8d9f, 0x8da3, 0x8e2b, + 0x8e10, 0x8e1d, 0x8e22, 0x8e0f, 0x8e29, 0x8e1f, 0x8e21, 0x8e1e, + 0x8eba, 0x8f1d, 0x8f1b, 0x8f1f, 0x8f29, 0x8f26, 0x8f2a, 0x8f1c, + 0x8f1e, 0x8f25, 0x9069, 0x906e, 0x9068, 0x906d, 0x9077, 0x9130, + 0x912d, 0x9127, 0x9131, 0x9187, 0x9189, 0x918b, 0x9183, 0x92c5, + 0x92bb, 0x92b7, 0x92ea, 0x92e4, 0x92c1, 0x92b3, 0x92bc, 0x92d2, + 0x92c7, 0x92f0, 0x92b2, 0x95ad, 0x95b1, 0x9704, 0x9706, 0x9707, + 0x9709, 0x9760, 0x978d, 0x978b, 0x978f, 0x9821, 0x982b, 0x981c, + 0x98b3, 0x990a, 0x9913, 0x9912, 0x9918, 0x99dd, 0x99d0, 0x99df, + 0x99db, 0x99d1, 0x99d5, 0x99d2, 0x99d9, 0x9ab7, + /* 0x70 */ + 0x9aee, 0x9aef, 0x9b27, 0x9b45, 0x9b44, 0x9b77, 0x9b6f, 0x9d06, + 0x9d09, 0x9d03, 0x9ea9, 0x9ebe, 0x9ece, 0x58a8, 0x9f52, 0x5112, + 0x5118, 0x5114, 0x5110, 0x5115, 0x5180, 0x51aa, 0x51dd, 0x5291, + 0x5293, 0x52f3, 0x5659, 0x566b, 0x5679, 0x5669, 0x5664, 0x5678, + 0x566a, 0x5668, 0x5665, 0x5671, 0x566f, 0x566c, 0x5662, 0x5676, + 0x58c1, 0x58be, 0x58c7, 0x58c5, 0x596e, 0x5b1d, 0x5b34, 0x5b78, + 0x5bf0, 0x5c0e, 0x5f4a, 0x61b2, 0x6191, 0x61a9, 0x618a, 0x61cd, + 0x61b6, 0x61be, 0x61ca, 0x61c8, 0x6230, 0x64c5, 0x64c1, 0x64cb, + 0x64bb, 0x64bc, 0x64da, 0x64c4, 0x64c7, 0x64c2, 0x64cd, 0x64bf, + 0x64d2, 0x64d4, 0x64be, 0x6574, 0x66c6, 0x66c9, 0x66b9, 0x66c4, + 0x66c7, 0x66b8, 0x6a3d, 0x6a38, 0x6a3a, 0x6a59, 0x6a6b, 0x6a58, + 0x6a39, 0x6a44, 0x6a62, 0x6a61, 0x6a4b, 0x6a47, + /* 0x71 */ + 0x6a35, 0x6a5f, 0x6a48, 0x6b59, 0x6b77, 0x6c05, 0x6fc2, 0x6fb1, + 0x6fa1, 0x6fc3, 0x6fa4, 0x6fc1, 0x6fa7, 0x6fb3, 0x6fc0, 0x6fb9, + 0x6fb6, 0x6fa6, 0x6fa0, 0x6fb4, 0x71be, 0x71c9, 0x71d0, 0x71d2, + 0x71c8, 0x71d5, 0x71b9, 0x71ce, 0x71d9, 0x71dc, 0x71c3, 0x71c4, + 0x7368, 0x749c, 0x74a3, 0x7498, 0x749f, 0x749e, 0x74e2, 0x750c, + 0x750d, 0x7634, 0x7638, 0x763a, 0x76e7, 0x76e5, 0x77a0, 0x779e, + 0x779f, 0x77a5, 0x78e8, 0x78da, 0x78ec, 0x78e7, 0x79a6, 0x7a4d, + 0x7a4e, 0x7a46, 0x7a4c, 0x7a4b, 0x7aba, 0x7bd9, 0x7c11, 0x7bc9, + 0x7be4, 0x7bdb, 0x7be1, 0x7be9, 0x7be6, 0x7cd5, 0x7cd6, 0x7e0a, + 0x7e11, 0x7e08, 0x7e1b, 0x7e23, 0x7e1e, 0x7e1d, 0x7e09, 0x7e10, + 0x7f79, 0x7fb2, 0x7ff0, 0x7ff1, 0x7fee, 0x8028, 0x81b3, 0x81a9, + 0x81a8, 0x81fb, 0x8208, 0x8258, 0x8259, 0x854a, + /* 0x72 */ + 0x8559, 0x8548, 0x8568, 0x8569, 0x8543, 0x8549, 0x856d, 0x856a, + 0x855e, 0x8783, 0x879f, 0x879e, 0x87a2, 0x878d, 0x8861, 0x892a, + 0x8932, 0x8925, 0x892b, 0x8921, 0x89aa, 0x89a6, 0x8ae6, 0x8afa, + 0x8aeb, 0x8af1, 0x8b00, 0x8adc, 0x8ae7, 0x8aee, 0x8afe, 0x8b01, + 0x8b02, 0x8af7, 0x8aed, 0x8af3, 0x8af6, 0x8afc, 0x8c6b, 0x8c6d, + 0x8c93, 0x8cf4, 0x8e44, 0x8e31, 0x8e34, 0x8e42, 0x8e39, 0x8e35, + 0x8f3b, 0x8f2f, 0x8f38, 0x8f33, 0x8fa8, 0x8fa6, 0x9075, 0x9074, + 0x9078, 0x9072, 0x907c, 0x907a, 0x9134, 0x9192, 0x9320, 0x9336, + 0x92f8, 0x9333, 0x932f, 0x9322, 0x92fc, 0x932b, 0x9304, 0x931a, + 0x9310, 0x9326, 0x9321, 0x9315, 0x932e, 0x9319, 0x95bb, 0x96a7, + 0x96a8, 0x96aa, 0x96d5, 0x970e, 0x9711, 0x9716, 0x970d, 0x9713, + 0x970f, 0x975b, 0x975c, 0x9766, 0x9798, 0x9830, + /* 0x73 */ + 0x9838, 0x983b, 0x9837, 0x982d, 0x9839, 0x9824, 0x9910, 0x9928, + 0x991e, 0x991b, 0x9921, 0x991a, 0x99ed, 0x99e2, 0x99f1, 0x9ab8, + 0x9abc, 0x9afb, 0x9aed, 0x9b28, 0x9b91, 0x9d15, 0x9d23, 0x9d26, + 0x9d28, 0x9d12, 0x9d1b, 0x9ed8, 0x9ed4, 0x9f8d, 0x9f9c, 0x512a, + 0x511f, 0x5121, 0x5132, 0x52f5, 0x568e, 0x5680, 0x5690, 0x5685, + 0x5687, 0x568f, 0x58d5, 0x58d3, 0x58d1, 0x58ce, 0x5b30, 0x5b2a, + 0x5b24, 0x5b7a, 0x5c37, 0x5c68, 0x5dbc, 0x5dba, 0x5dbd, 0x5db8, + 0x5e6b, 0x5f4c, 0x5fbd, 0x61c9, 0x61c2, 0x61c7, 0x61e6, 0x61cb, + 0x6232, 0x6234, 0x64ce, 0x64ca, 0x64d8, 0x64e0, 0x64f0, 0x64e6, + 0x64ec, 0x64f1, 0x64e2, 0x64ed, 0x6582, 0x6583, 0x66d9, 0x66d6, + 0x6a80, 0x6a94, 0x6a84, 0x6aa2, 0x6a9c, 0x6adb, 0x6aa3, 0x6a7e, + 0x6a97, 0x6a90, 0x6aa0, 0x6b5c, 0x6bae, 0x6bda, + /* 0x74 */ + 0x6c08, 0x6fd8, 0x6ff1, 0x6fdf, 0x6fe0, 0x6fdb, 0x6fe4, 0x6feb, + 0x6fef, 0x6f80, 0x6fec, 0x6fe1, 0x6fe9, 0x6fd5, 0x6fee, 0x6ff0, + 0x71e7, 0x71df, 0x71ee, 0x71e6, 0x71e5, 0x71ed, 0x71ec, 0x71f4, + 0x71e0, 0x7235, 0x7246, 0x7370, 0x7372, 0x74a9, 0x74b0, 0x74a6, + 0x74a8, 0x7646, 0x7642, 0x764c, 0x76ea, 0x77b3, 0x77aa, 0x77b0, + 0x77ac, 0x77a7, 0x77ad, 0x77ef, 0x78f7, 0x78fa, 0x78f4, 0x78ef, + 0x7901, 0x79a7, 0x79aa, 0x7a57, 0x7abf, 0x7c07, 0x7c0d, 0x7bfe, + 0x7bf7, 0x7c0c, 0x7be0, 0x7ce0, 0x7cdc, 0x7cde, 0x7ce2, 0x7cdf, + 0x7cd9, 0x7cdd, 0x7e2e, 0x7e3e, 0x7e46, 0x7e37, 0x7e32, 0x7e43, + 0x7e2b, 0x7e3d, 0x7e31, 0x7e45, 0x7e41, 0x7e34, 0x7e39, 0x7e48, + 0x7e35, 0x7e3f, 0x7e2f, 0x7f44, 0x7ff3, 0x7ffc, 0x8071, 0x8072, + 0x8070, 0x806f, 0x8073, 0x81c6, 0x81c3, 0x81ba, + /* 0x75 */ + 0x81c2, 0x81c0, 0x81bf, 0x81bd, 0x81c9, 0x81be, 0x81e8, 0x8209, + 0x8271, 0x85aa, 0x8584, 0x857e, 0x859c, 0x8591, 0x8594, 0x85af, + 0x859b, 0x8587, 0x85a8, 0x858a, 0x85a6, 0x8667, 0x87c0, 0x87d1, + 0x87b3, 0x87d2, 0x87c6, 0x87ab, 0x87bb, 0x87ba, 0x87c8, 0x87cb, + 0x893b, 0x8936, 0x8944, 0x8938, 0x893d, 0x89ac, 0x8b0e, 0x8b17, + 0x8b19, 0x8b1b, 0x8b0a, 0x8b20, 0x8b1d, 0x8b04, 0x8b10, 0x8c41, + 0x8c3f, 0x8c73, 0x8cfa, 0x8cfd, 0x8cfc, 0x8cf8, 0x8cfb, 0x8da8, + 0x8e49, 0x8e4b, 0x8e48, 0x8e4a, 0x8f44, 0x8f3e, 0x8f42, 0x8f45, + 0x8f3f, 0x907f, 0x907d, 0x9084, 0x9081, 0x9082, 0x9080, 0x9139, + 0x91a3, 0x919e, 0x919c, 0x934d, 0x9382, 0x9328, 0x9375, 0x934a, + 0x9365, 0x934b, 0x9318, 0x937e, 0x936c, 0x935b, 0x9370, 0x935a, + 0x9354, 0x95ca, 0x95cb, 0x95cc, 0x95c8, 0x95c6, + /* 0x76 */ + 0x96b1, 0x96b8, 0x96d6, 0x971c, 0x971e, 0x97a0, 0x97d3, 0x9846, + 0x98b6, 0x9935, 0x9a01, 0x99ff, 0x9bae, 0x9bab, 0x9baa, 0x9bad, + 0x9d3b, 0x9d3f, 0x9e8b, 0x9ecf, 0x9ede, 0x9edc, 0x9edd, 0x9edb, + 0x9f3e, 0x9f4b, 0x53e2, 0x5695, 0x56ae, 0x58d9, 0x58d8, 0x5b38, + 0x5f5e, 0x61e3, 0x6233, 0x64f4, 0x64f2, 0x64fe, 0x6506, 0x64fa, + 0x64fb, 0x64f7, 0x65b7, 0x66dc, 0x6726, 0x6ab3, 0x6aac, 0x6ac3, + 0x6abb, 0x6ab8, 0x6ac2, 0x6aae, 0x6aaf, 0x6b5f, 0x6b78, 0x6baf, + 0x7009, 0x700b, 0x6ffe, 0x7006, 0x6ffa, 0x7011, 0x700f, 0x71fb, + 0x71fc, 0x71fe, 0x71f8, 0x7377, 0x7375, 0x74a7, 0x74bf, 0x7515, + 0x7656, 0x7658, 0x7652, 0x77bd, 0x77bf, 0x77bb, 0x77bc, 0x790e, + 0x79ae, 0x7a61, 0x7a62, 0x7a60, 0x7ac4, 0x7ac5, 0x7c2b, 0x7c27, + 0x7c2a, 0x7c1e, 0x7c23, 0x7c21, 0x7ce7, 0x7e54, + /* 0x77 */ + 0x7e55, 0x7e5e, 0x7e5a, 0x7e61, 0x7e52, 0x7e59, 0x7f48, 0x7ff9, + 0x7ffb, 0x8077, 0x8076, 0x81cd, 0x81cf, 0x820a, 0x85cf, 0x85a9, + 0x85cd, 0x85d0, 0x85c9, 0x85b0, 0x85ba, 0x85b9, 0x87ef, 0x87ec, + 0x87f2, 0x87e0, 0x8986, 0x89b2, 0x89f4, 0x8b28, 0x8b39, 0x8b2c, + 0x8b2b, 0x8c50, 0x8d05, 0x8e59, 0x8e63, 0x8e66, 0x8e64, 0x8e5f, + 0x8e55, 0x8ec0, 0x8f49, 0x8f4d, 0x9087, 0x9083, 0x9088, 0x91ab, + 0x91ac, 0x91d0, 0x9394, 0x938a, 0x9396, 0x93a2, 0x93b3, 0x93ae, + 0x93ac, 0x93b0, 0x9398, 0x939a, 0x9397, 0x95d4, 0x95d6, 0x95d0, + 0x95d5, 0x96e2, 0x96dc, 0x96d9, 0x96db, 0x96de, 0x9724, 0x97a3, + 0x97a6, 0x97ad, 0x97f9, 0x984d, 0x984f, 0x984c, 0x984e, 0x9853, + 0x98ba, 0x993e, 0x993f, 0x993d, 0x992e, 0x99a5, 0x9a0e, 0x9ac1, + 0x9b03, 0x9b06, 0x9b4f, 0x9b4e, 0x9b4d, 0x9bca, + /* 0x78 */ + 0x9bc9, 0x9bfd, 0x9bc8, 0x9bc0, 0x9d51, 0x9d5d, 0x9d60, 0x9ee0, + 0x9f15, 0x9f2c, 0x5133, 0x56a5, 0x56a8, 0x58de, 0x58df, 0x58e2, + 0x5bf5, 0x9f90, 0x5eec, 0x61f2, 0x61f7, 0x61f6, 0x61f5, 0x6500, + 0x650f, 0x66e0, 0x66dd, 0x6ae5, 0x6add, 0x6ada, 0x6ad3, 0x701b, + 0x701f, 0x7028, 0x701a, 0x701d, 0x7015, 0x7018, 0x7206, 0x720d, + 0x7258, 0x72a2, 0x7378, 0x737a, 0x74bd, 0x74ca, 0x74e3, 0x7587, + 0x7586, 0x765f, 0x7661, 0x77c7, 0x7919, 0x79b1, 0x7a6b, 0x7a69, + 0x7c3e, 0x7c3f, 0x7c38, 0x7c3d, 0x7c37, 0x7c40, 0x7e6b, 0x7e6d, + 0x7e79, 0x7e69, 0x7e6a, 0x7e73, 0x7f85, 0x7fb6, 0x7fb9, 0x7fb8, + 0x81d8, 0x85e9, 0x85dd, 0x85ea, 0x85d5, 0x85e4, 0x85e5, 0x85f7, + 0x87fb, 0x8805, 0x880d, 0x87f9, 0x87fe, 0x8960, 0x895f, 0x8956, + 0x895e, 0x8b41, 0x8b5c, 0x8b58, 0x8b49, 0x8b5a, + /* 0x79 */ + 0x8b4e, 0x8b4f, 0x8b46, 0x8b59, 0x8d08, 0x8d0a, 0x8e7c, 0x8e72, + 0x8e87, 0x8e76, 0x8e6c, 0x8e7a, 0x8e74, 0x8f54, 0x8f4e, 0x8fad, + 0x908a, 0x908b, 0x91b1, 0x91ae, 0x93e1, 0x93d1, 0x93df, 0x93c3, + 0x93c8, 0x93dc, 0x93dd, 0x93d6, 0x93e2, 0x93cd, 0x93d8, 0x93e4, + 0x93d7, 0x93e8, 0x95dc, 0x96b4, 0x96e3, 0x972a, 0x9727, 0x9761, + 0x97dc, 0x97fb, 0x985e, 0x9858, 0x985b, 0x98bc, 0x9945, 0x9949, + 0x9a16, 0x9a19, 0x9b0d, 0x9be8, 0x9be7, 0x9bd6, 0x9bdb, 0x9d89, + 0x9d61, 0x9d72, 0x9d6a, 0x9d6c, 0x9e92, 0x9e97, 0x9e93, 0x9eb4, + 0x52f8, 0x56b7, 0x56b6, 0x56b4, 0x56bc, 0x58e4, 0x5b40, 0x5b43, + 0x5b7d, 0x5bf6, 0x5dc9, 0x61f8, 0x61fa, 0x6518, 0x6514, 0x6519, + 0x66e6, 0x6727, 0x6aec, 0x703e, 0x7030, 0x7032, 0x7210, 0x737b, + 0x74cf, 0x7662, 0x7665, 0x7926, 0x792a, 0x792c, + /* 0x7a */ + 0x792b, 0x7ac7, 0x7af6, 0x7c4c, 0x7c43, 0x7c4d, 0x7cef, 0x7cf0, + 0x8fae, 0x7e7d, 0x7e7c, 0x7e82, 0x7f4c, 0x8000, 0x81da, 0x8266, + 0x85fb, 0x85f9, 0x8611, 0x85fa, 0x8606, 0x860b, 0x8607, 0x860a, + 0x8814, 0x8815, 0x8964, 0x89ba, 0x89f8, 0x8b70, 0x8b6c, 0x8b66, + 0x8b6f, 0x8b5f, 0x8b6b, 0x8d0f, 0x8d0d, 0x8e89, 0x8e81, 0x8e85, + 0x8e82, 0x91b4, 0x91cb, 0x9418, 0x9403, 0x93fd, 0x95e1, 0x9730, + 0x98c4, 0x9952, 0x9951, 0x99a8, 0x9a2b, 0x9a30, 0x9a37, 0x9a35, + 0x9c13, 0x9c0d, 0x9e79, 0x9eb5, 0x9ee8, 0x9f2f, 0x9f5f, 0x9f63, + 0x9f61, 0x5137, 0x5138, 0x56c1, 0x56c0, 0x56c2, 0x5914, 0x5c6c, + 0x5dcd, 0x61fc, 0x61fe, 0x651d, 0x651c, 0x6595, 0x66e9, 0x6afb, + 0x6b04, 0x6afa, 0x6bb2, 0x704c, 0x721b, 0x72a7, 0x74d6, 0x74d4, + 0x7669, 0x77d3, 0x7c50, 0x7e8f, 0x7e8c, 0x7fbc, + /* 0x7b */ + 0x8617, 0x862d, 0x861a, 0x8823, 0x8822, 0x8821, 0x881f, 0x896a, + 0x896c, 0x89bd, 0x8b74, 0x8b77, 0x8b7d, 0x8d13, 0x8e8a, 0x8e8d, + 0x8e8b, 0x8f5f, 0x8faf, 0x91ba, 0x942e, 0x9433, 0x9435, 0x943a, + 0x9438, 0x9432, 0x942b, 0x95e2, 0x9738, 0x9739, 0x9732, 0x97ff, + 0x9867, 0x9865, 0x9957, 0x9a45, 0x9a43, 0x9a40, 0x9a3e, 0x9acf, + 0x9b54, 0x9b51, 0x9c2d, 0x9c25, 0x9daf, 0x9db4, 0x9dc2, 0x9db8, + 0x9e9d, 0x9eef, 0x9f19, 0x9f5c, 0x9f66, 0x9f67, 0x513c, 0x513b, + 0x56c8, 0x56ca, 0x56c9, 0x5b7f, 0x5dd4, 0x5dd2, 0x5f4e, 0x61ff, + 0x6524, 0x6b0a, 0x6b61, 0x7051, 0x7058, 0x7380, 0x74e4, 0x758a, + 0x766e, 0x766c, 0x79b3, 0x7c60, 0x7c5f, 0x807e, 0x807d, 0x81df, + 0x8972, 0x896f, 0x89fc, 0x8b80, 0x8d16, 0x8d17, 0x8e91, 0x8e93, + 0x8f61, 0x9148, 0x9444, 0x9451, 0x9452, 0x973d, + /* 0x7c */ + 0x973e, 0x97c3, 0x97c1, 0x986b, 0x9955, 0x9a55, 0x9a4d, 0x9ad2, + 0x9b1a, 0x9c49, 0x9c31, 0x9c3e, 0x9c3b, 0x9dd3, 0x9dd7, 0x9f34, + 0x9f6c, 0x9f6a, 0x9f94, 0x56cc, 0x5dd6, 0x6200, 0x6523, 0x652b, + 0x652a, 0x66ec, 0x6b10, 0x74da, 0x7aca, 0x7c64, 0x7c63, 0x7c65, + 0x7e93, 0x7e96, 0x7e94, 0x81e2, 0x8638, 0x863f, 0x8831, 0x8b8a, + 0x9090, 0x908f, 0x9463, 0x9460, 0x9464, 0x9768, 0x986f, 0x995c, + 0x9a5a, 0x9a5b, 0x9a57, 0x9ad3, 0x9ad4, 0x9ad1, 0x9c54, 0x9c57, + 0x9c56, 0x9de5, 0x9e9f, 0x9ef4, 0x56d1, 0x58e9, 0x652c, 0x705e, + 0x7671, 0x7672, 0x77d7, 0x7f50, 0x7f88, 0x8836, 0x8839, 0x8862, + 0x8b93, 0x8b92, 0x8b96, 0x8277, 0x8d1b, 0x91c0, 0x946a, 0x9742, + 0x9748, 0x9744, 0x97c6, 0x9870, 0x9a5f, 0x9b22, 0x9b58, 0x9c5f, + 0x9df9, 0x9dfa, 0x9e7c, 0x9e7d, 0x9f07, 0x9f77, + /* 0x7d */ + 0x9f72, 0x5ef3, 0x6b16, 0x7063, 0x7c6c, 0x7c6e, 0x883b, 0x89c0, + 0x8ea1, 0x91c1, 0x9472, 0x9470, 0x9871, 0x995e, 0x9ad6, 0x9b23, + 0x9ecc, 0x7064, 0x77da, 0x8b9a, 0x9477, 0x97c9, 0x9a62, 0x9a65, + 0x7e9c, 0x8b9c, 0x8eaa, 0x91c5, 0x947d, 0x947e, 0x947c, 0x9c77, + 0x9c78, 0x9ef7, 0x8c54, 0x947f, 0x9e1a, 0x7228, 0x9a6a, 0x9b31, + 0x9e1b, 0x9e1e, 0x7c72, +}; + +static int +cns11643_1_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x21 && c1 <= 0x27) || (c1 == 0x42) || (c1 >= 0x44 && c1 <= 0x7d)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + unsigned short wc = 0xfffd; + if (i < 3102) { + if (i < 500) + wc = cns11643_1_2uni_page21[i]; + else if (i == 571) + wc = 0x4ea0; + else if (i == 578) + wc = 0x51ab; + else if (i == 583) + wc = 0x52f9; + } else if (i < 3290) { + if (i < 3136) + wc = cns11643_1_2uni_page42[i-3102]; + } else { + if (i < 8691) + wc = cns11643_1_2uni_page44[i-3290]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + diff --git a/libs/libiconv/lib/cns11643_15.h b/libs/libiconv/lib/cns11643_15.h new file mode 100644 index 00000000..cfe0ba69 --- /dev/null +++ b/libs/libiconv/lib/cns11643_15.h @@ -0,0 +1,1083 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CNS 11643-1992 plane 15 + */ + +static const unsigned short cns11643_15_2uni_page21[7169] = { + /* 0x21 */ + 0x5302, 0x538c, 0x53d4, 0x54a5, 0x5392, 0x5393, 0x53d8, 0x53d9, + 0x54a7, 0x592b, 0x592c, 0x592d, 0x5930, 0x592e, 0x59ab, 0x1a01, + 0x5c2d, 0x5c6d, 0xfa34, 0x5d0f, 0x52fd, 0x5e9d, 0x64a2, 0x68d4, + 0x6e56, 0x6ec3, 0x7314, 0x52fd, 0x9a1a, 0x530f, 0x5310, 0x539a, + 0x539b, 0x52fd, 0x54ac, 0x0036, 0x5397, 0x5846, 0x0e4f, 0x5876, + 0x5877, 0x58ae, 0x593a, 0x597d, 0x6ec5, 0x5ea8, 0x52fd, 0x1afa, + 0x6541, 0x6542, 0x68d8, 0x68d9, 0x69aa, 0x69ab, 0x6c42, 0x6c41, + 0x5099, 0x6ec6, 0x52fd, 0x7035, 0x7036, 0x7037, 0xfa83, 0xb64d, + 0x52fd, 0x74b5, 0x7617, 0x7782, 0x86b6, 0x2d49, 0x8f72, 0x985c, + 0x98a8, 0x45b7, 0x68e3, 0x0006, 0x52fd, 0x53e6, 0x5444, 0x5445, + 0x1729, 0x003e, 0x54c4, 0x54c5, 0x54c6, 0x54c7, 0x54c8, 0x54c9, + 0x54ca, 0x54d4, 0x587d, 0xb572, 0x58b2, 0x58b4, + /* 0x22 */ + 0x5982, 0x59c7, 0x59c8, 0x52fd, 0x5b3c, 0x5b3d, 0x5b3e, 0x5b3f, + 0xfa24, 0x5bd3, 0x5447, 0x1a4e, 0x5d3d, 0x5de2, 0x5eb8, 0x5eb9, + 0x5ec2, 0x5eba, 0x5ec6, 0x5ebb, 0x64ad, 0x654c, 0x654d, 0x52fd, + 0x69b2, 0x69b3, 0x69b4, 0x69b5, 0x6cc3, 0x6cc4, 0x6cc5, 0x6cc6, + 0x6cc7, 0x52fd, 0x6ece, 0x6f30, 0x7047, 0x7048, 0x2281, 0x735c, + 0x52fd, 0x735f, 0x7618, 0x7619, 0x767e, 0x2410, 0x78b0, 0x7d75, + 0x2568, 0x7d76, 0x8341, 0x8442, 0x52fd, 0x86bd, 0x2842, 0x2840, + 0x18ea, 0x8e1e, 0x8e1f, 0x8f87, 0x2d62, 0x8f78, 0x9488, 0x9489, + 0x948a, 0x9917, 0x9915, 0x52fd, 0x52fd, 0x3291, 0xa3e5, 0xa909, + 0xaa3b, 0xaa4f, 0x52fd, 0xb92e, 0xb92f, 0xbdff, 0xbdfd, 0xbdfe, + 0x45bb, 0x45bc, 0x52fd, 0x5323, 0x53ea, 0x542a, 0x5449, 0x544a, + 0x544b, 0x54df, 0x54e0, 0x54e1, 0x54e2, 0x58c1, + /* 0x23 */ + 0x54e3, 0x54e4, 0x54e5, 0x58c0, 0x54e6, 0x54f7, 0x52fd, 0x54e7, + 0x54e8, 0x54e9, 0x54ea, 0x54eb, 0x580e, 0x5880, 0x5881, 0x58ba, + 0x58bb, 0x58bc, 0x58bd, 0x593f, 0x5940, 0x5988, 0xfa1f, 0x5b46, + 0x52fd, 0x5b47, 0x5b48, 0x5c36, 0x5c72, 0x5c96, 0x5d47, 0x5de7, + 0x5e34, 0x5e35, 0x5e36, 0x5e37, 0x5ee3, 0x5ee4, 0x5ee5, 0x5eeb, + 0x0175, 0x5ee6, 0x5ee7, 0x5ee8, 0x52fd, 0x52fd, 0x64b9, 0x1de8, + 0x64ba, 0x1e5b, 0x6563, 0x6564, 0x52fd, 0x6565, 0x52fd, 0x6566, + 0x657c, 0x6567, 0xfa5a, 0x6859, 0x68e9, 0x68ea, 0x68eb, 0x68ec, + 0x68ed, 0x68ee, 0x68ef, 0x69bf, 0x69cb, 0x69c3, 0x69d5, 0x69c4, + 0x69c5, 0x69d3, 0x69c6, 0x69c7, 0x69c8, 0x69c9, 0x69ca, 0x6c4a, + 0x52fd, 0x6cd1, 0x6e61, 0x6f37, 0x52fd, 0x7064, 0x7066, 0x2299, + 0x7067, 0x7068, 0x7069, 0x2297, 0x7073, 0x706a, + /* 0x24 */ + 0x706b, 0x2862, 0x52fd, 0x7372, 0x043c, 0x74b9, 0x761c, 0x7636, + 0x76bc, 0x76be, 0x76bf, 0x76c0, 0x7787, 0x78dc, 0x78dd, 0x78f5, + 0x78de, 0x78df, 0xfa9e, 0x78e0, 0x78e1, 0x78e2, 0x7d2c, 0x7d2d, + 0x25a4, 0x7da9, 0x7d9c, 0x7d9d, 0x7d9e, 0x7d9f, 0x7da0, 0x7da1, + 0x7da2, 0x52fd, 0x7da3, 0x7da4, 0x7da7, 0x8342, 0x8393, 0x8451, + 0x52fd, 0x8452, 0x8444, 0x8453, 0x8622, 0x86c6, 0x86c7, 0x86c9, + 0xfadd, 0x86ca, 0x2866, 0x86c8, 0x8e24, 0x8e25, 0x8e26, 0x52fd, + 0x8e27, 0x8e28, 0x52fd, 0x8f58, 0xfafb, 0x8fa7, 0x8f88, 0x8f89, + 0x8fa5, 0x8fa8, 0x8fa9, 0x8faa, 0x8fab, 0x8fac, 0x8fad, 0x2da3, + 0x8f79, 0x52fd, 0x9494, 0x9495, 0x9496, 0x09a5, 0x52fd, 0x9497, + 0x307f, 0x9498, 0x984e, 0x984f, 0x9919, 0x52fd, 0x9a41, 0xfb2a, + 0x9bf7, 0x9f04, 0x9f19, 0x9f17, 0xa340, 0xa3ec, + /* 0x25 */ + 0xa71b, 0xa71c, 0x36f6, 0xa90e, 0xaa52, 0xadd8, 0xb126, 0xb574, + 0x52fd, 0xb575, 0xbcc6, 0xbe0b, 0xbe0c, 0xbe0d, 0xbe0e, 0xbe0f, + 0xbe10, 0x45c8, 0xd759, 0xd75a, 0xd983, 0xd984, 0xd985, 0x52fd, + 0x4af5, 0xe120, 0xe121, 0xe122, 0xe123, 0xe124, 0xe129, 0x53f4, + 0x52fd, 0x688f, 0x5451, 0x17ab, 0x5517, 0x5518, 0x555b, 0x5519, + 0x551a, 0x0053, 0x551b, 0x551c, 0x551d, 0x551e, 0x551f, 0x5520, + 0x5521, 0x578b, 0x5788, 0x222d, 0x5885, 0xb587, 0x58c7, 0x594c, + 0x594d, 0x59fc, 0x59fd, 0x59fe, 0x59ff, 0x52fd, 0x52fd, 0x5b56, + 0x5b57, 0x5b58, 0x5b59, 0x5bdc, 0x5bdd, 0x5c73, 0x5c9d, 0x5ca1, + 0x5c9e, 0x5c9f, 0x5ca0, 0x5ce6, 0x5d51, 0x5d52, 0x5e3d, 0x5f22, + 0x1b9c, 0x5f23, 0x5f24, 0x5f25, 0x5f26, 0x5f27, 0x5f28, 0x5f29, + 0x5f2a, 0x5f2b, 0x52fd, 0x5f40, 0x5f2c, 0x5f2d, + /* 0x26 */ + 0x5f2e, 0x5f2f, 0x5f30, 0x64d0, 0x65a8, 0x6594, 0x6595, 0x6596, + 0x6597, 0x6598, 0x659c, 0x659b, 0x52fd, 0x65a1, 0x65a0, 0x6599, + 0x659a, 0x65a7, 0x1e88, 0x6864, 0x52fd, 0x6900, 0x6901, 0x52fd, + 0x52fd, 0x69e5, 0x69e9, 0x69fb, 0x69fc, 0x69ea, 0x69eb, 0x69ec, + 0x69ed, 0x69ee, 0x69ef, 0x69fa, 0x69f0, 0x69f1, 0x69f2, 0x69f3, + 0x69f4, 0x6c52, 0x6c53, 0x6c54, 0x6c55, 0x6c58, 0x6c56, 0x52fd, + 0x6cdd, 0x6cde, 0x6ce3, 0x6cdf, 0x6ce0, 0x6e22, 0x6e23, 0x6e68, + 0x6edf, 0x00ac, 0x6f44, 0x7094, 0x7095, 0x7096, 0x7097, 0x7098, + 0x7099, 0xfa79, 0x709a, 0x709b, 0x709d, 0x709e, 0x709f, 0x70a0, + 0x72f3, 0x72f2, 0x731f, 0x7388, 0x748f, 0x7490, 0x52fd, 0x74fd, + 0x74fe, 0x74ff, 0x7500, 0x7501, 0x791a, 0x52fd, 0x78e3, 0x78e4, + 0x78e5, 0x78e6, 0x78e7, 0x78eb, 0x78e8, 0x78e9, + /* 0x27 */ + 0x78ea, 0x791d, 0x7ca4, 0x7ca3, 0x7dd4, 0x7dc6, 0x7dc7, 0x7dc8, + 0x7dc9, 0x7dca, 0x7dcb, 0x7dcc, 0x7dcd, 0x05de, 0x7dce, 0x25c3, + 0x81b8, 0x81b9, 0x81ba, 0x836e, 0x83db, 0x83dc, 0x8468, 0x8469, + 0x846a, 0x846b, 0x846c, 0x846d, 0x846e, 0x2719, 0x8624, 0x8625, + 0x52fd, 0x8700, 0x86e5, 0x86f9, 0x86e7, 0x86e8, 0x86e9, 0x86fe, + 0x86ea, 0x86eb, 0x86ec, 0x0749, 0x86ed, 0x28a1, 0x86ee, 0x28a6, + 0x86ef, 0x52fd, 0x8717, 0x86f0, 0x86f1, 0x8b94, 0x8c5b, 0x8c5c, + 0x8c5d, 0x8e2f, 0x0891, 0x8e30, 0x8e31, 0x8e32, 0x8e33, 0x8fcc, + 0x8fcd, 0x8fce, 0x8fae, 0x8faf, 0x8fb0, 0x08d3, 0x8fcf, 0x8fd0, + 0x8fd1, 0x8fd2, 0x8fd3, 0x52fd, 0x8fd4, 0x09a9, 0x94a6, 0x94a7, + 0x94a8, 0x94b0, 0x94a9, 0x94aa, 0x94ab, 0x94ac, 0x94ad, 0x97fb, + 0x97fc, 0x52fd, 0x992d, 0x992e, 0x9950, 0x992f, + /* 0x28 */ + 0x9930, 0x9a65, 0x9be6, 0x9c0c, 0x9c02, 0x9c03, 0x9c04, 0x9c05, + 0x9c06, 0x52fd, 0x9ec0, 0x9f24, 0x9f25, 0xa016, 0xa032, 0xa720, + 0xa721, 0xa722, 0xa723, 0x36fe, 0xa725, 0xa919, 0xa924, 0xa91a, + 0xa91b, 0xa91c, 0xa91d, 0xfb52, 0xa91e, 0xaa5a, 0xaa5b, 0xaa5c, + 0xaa5d, 0xaa5e, 0xac31, 0x52fd, 0xb129, 0x52fd, 0xb288, 0xb289, + 0xb589, 0x3d57, 0xb656, 0xb7d1, 0xb7e6, 0xb832, 0xb833, 0xb952, + 0xb953, 0x0ed5, 0xb954, 0xb955, 0x52fd, 0x52fd, 0xbe29, 0xbe2a, + 0xbe2b, 0xbe2c, 0xbe2d, 0xfb92, 0xbe2e, 0xbe2f, 0xbe30, 0xbe31, + 0xbe32, 0xbe33, 0x3ec5, 0xbe34, 0xc49b, 0xc523, 0xc524, 0x52fd, + 0xc525, 0xc527, 0xc916, 0xcfa0, 0xd76f, 0x45df, 0xd770, 0xd771, + 0x45dc, 0x138c, 0xd772, 0xd773, 0xd774, 0xd99c, 0xd9aa, 0xd99d, + 0xd99e, 0x0c99, 0xd9ab, 0xd99f, 0xe135, 0xe138, + /* 0x29 */ + 0xf68d, 0x5335, 0x5336, 0xadee, 0x53b4, 0xf9c9, 0x5432, 0x5455, + 0x5544, 0x5545, 0x5546, 0x5547, 0x17e4, 0x5548, 0x5549, 0x52fd, + 0x554a, 0x554b, 0x554c, 0x554d, 0x554e, 0x554f, 0x5550, 0x5551, + 0xb599, 0x58d1, 0x52fd, 0x58d2, 0x58d3, 0x58d4, 0x58d5, 0x5a21, + 0x5a22, 0x5a23, 0x5b68, 0x5b69, 0x5b6a, 0x5be2, 0x5c45, 0x5cec, + 0x5ced, 0x5cee, 0x5cef, 0x52fd, 0x5d62, 0x5d63, 0x5df4, 0x536f, + 0x5e44, 0x5e45, 0x5f79, 0x1c1b, 0x5f7a, 0x5f7b, 0x5f7c, 0x5f7d, + 0x5f7e, 0x5f7f, 0x5f80, 0x0188, 0x52fd, 0x5f81, 0x5f82, 0x5f83, + 0x5f84, 0x5f85, 0x5f86, 0x5f87, 0x5f8f, 0x5f88, 0x5f89, 0x65c5, + 0x65c6, 0x1eaa, 0x65c7, 0x65c8, 0x65c9, 0x65ca, 0x65cb, 0x65cc, + 0x1eab, 0x65cd, 0x65ce, 0x65e3, 0x65cf, 0x65d0, 0x65d1, 0x65d2, + 0x65d3, 0x65c4, 0x65d4, 0x65d5, 0x65d6, 0x6820, + /* 0x2a */ + 0x6821, 0x691a, 0x6912, 0x6914, 0x6915, 0x6916, 0x6919, 0x6917, + 0x6918, 0x02c9, 0xfa61, 0x52fd, 0x6a12, 0x6a13, 0x6a14, 0x6a15, + 0x6a16, 0x6a17, 0x6a18, 0x6a19, 0x6c61, 0x6c62, 0x6c63, 0x6cf5, + 0x21a9, 0x6cf6, 0x6cf7, 0x6cf8, 0x6e29, 0x0517, 0x6f5d, 0x6f57, + 0x6f58, 0x6f59, 0x6f5a, 0x6f5b, 0x70bb, 0x70d1, 0x70bc, 0x70bd, + 0xbbdf, 0x70d0, 0x70be, 0x70bf, 0x70c0, 0x70c1, 0x70c2, 0x70c3, + 0x70c4, 0xbe6c, 0x73a1, 0x73a2, 0x73a3, 0x7493, 0x750d, 0x750f, + 0x750e, 0x7510, 0x7511, 0x7512, 0xfa95, 0x77e5, 0x792f, 0x52fd, + 0x7957, 0x7930, 0x7968, 0x792b, 0x7931, 0x7958, 0xfaa2, 0x7932, + 0x7959, 0x52fd, 0x795a, 0x7933, 0x795b, 0x795c, 0x795d, 0x791e, + 0x7cae, 0x7caf, 0x7d3b, 0x7d3c, 0x7d3d, 0x7e07, 0x7e08, 0x7e09, + 0x7e0a, 0x7e0b, 0x7e0c, 0x7e0d, 0x7e0e, 0x7e0f, + /* 0x2b */ + 0x7e10, 0x7e22, 0x7e11, 0x7e12, 0x7e13, 0x7e14, 0x7e15, 0x7e16, + 0x7e17, 0x7e18, 0xfab8, 0x52fd, 0x8346, 0x8347, 0x8348, 0x83e1, + 0x8481, 0x8483, 0x5f75, 0x52fd, 0x8485, 0x8486, 0x862a, 0xfad1, + 0x862b, 0x866b, 0x8718, 0x8719, 0x871a, 0x52fd, 0x871b, 0x871c, + 0x871d, 0x871e, 0x871f, 0x8720, 0x8721, 0x8722, 0x8723, 0x2911, + 0x8724, 0x8725, 0x8726, 0x8727, 0x8728, 0x8729, 0x872a, 0x8cef, + 0x8e49, 0x8e4a, 0x8e4b, 0x8e4c, 0x8e4d, 0x8e4e, 0x8e4f, 0x8e50, + 0x8e51, 0x8e52, 0x8e53, 0x8e54, 0x8e5a, 0x8e55, 0x8f5f, 0x9002, + 0x9003, 0x9004, 0x9005, 0x8fd5, 0x9006, 0x9007, 0x8fd6, 0x9008, + 0x9009, 0x900a, 0x900b, 0x8fd7, 0x900c, 0x900d, 0x94c8, 0x94c9, + 0x94ca, 0x94cb, 0x94cc, 0x94cd, 0x94ce, 0x94cf, 0x94d0, 0x94d1, + 0x94d2, 0x3451, 0x94d3, 0x94d4, 0x94d5, 0x94d6, + /* 0x2c */ + 0x94d7, 0x94e2, 0x94d8, 0x9804, 0x9805, 0x9806, 0x52fd, 0x9943, + 0x9944, 0x9a84, 0x9a8f, 0x9a85, 0x9a86, 0x9c2f, 0x9c1a, 0x9c1b, + 0x9c1c, 0x0abd, 0x9c1d, 0x9c1e, 0x9c1f, 0x9c20, 0x9c21, 0x9c22, + 0xfb2c, 0x9c23, 0x9c24, 0x9c0e, 0x9c25, 0x9c2b, 0x9c2c, 0x9c0b, + 0x9dee, 0x52fd, 0x9ec3, 0x9ed8, 0x9ed9, 0x9f38, 0x9f39, 0x9f3a, + 0x9f3b, 0x3453, 0x9f3c, 0x9f3d, 0x9f3e, 0x9f3f, 0x9f40, 0xa048, + 0xa04c, 0xa228, 0xa251, 0xa252, 0xa34c, 0xa423, 0xfb45, 0xa424, + 0xa731, 0xa732, 0xa733, 0x3718, 0xa734, 0xa735, 0xa736, 0xa740, + 0xa737, 0x52fd, 0xa738, 0xa73d, 0xa938, 0xa939, 0xa93a, 0xa93b, + 0xa93c, 0xa94c, 0xaa73, 0xaa74, 0x0d33, 0xaa75, 0xaa76, 0xaa79, + 0xac41, 0xac42, 0xac43, 0xad5b, 0x52fd, 0x39d7, 0x8ba6, 0xad5c, + 0xade5, 0xade6, 0xade7, 0xade8, 0xaded, 0xb130, + /* 0x2d */ + 0x3b7e, 0xb131, 0xb294, 0xb651, 0xb6fd, 0xb6fe, 0xb7e9, 0x52fd, + 0xb9b3, 0xb984, 0xb994, 0x52fd, 0xb99c, 0x52fd, 0xb985, 0xbc00, + 0xbc37, 0xbc57, 0xbe54, 0xbe68, 0xbe55, 0xbe5c, 0xbe56, 0xbe57, + 0xbe58, 0xbe59, 0xbe5a, 0xbe5b, 0xc534, 0x407e, 0xc535, 0x52fd, + 0xc539, 0xc536, 0xc537, 0xc538, 0xc8e5, 0xc959, 0x52fd, 0xc93a, + 0xc93b, 0xd028, 0xd189, 0x52fd, 0xd18a, 0xd18b, 0xd18c, 0xd18d, + 0xd2bc, 0xd5a3, 0x1344, 0xd5a4, 0xd793, 0xd794, 0xd795, 0xd796, + 0xd797, 0xd9b9, 0xe14f, 0xe150, 0xe151, 0xe376, 0x52fd, 0x53fb, + 0x5383, 0x5438, 0x545d, 0x5571, 0x52fd, 0x5577, 0x5578, 0xfa07, + 0x55c3, 0x5579, 0x557a, 0x557b, 0x557c, 0x5572, 0x557d, 0x55a0, + 0x557e, 0x557f, 0x5580, 0x5581, 0x5582, 0x5583, 0x559e, 0x5584, + 0x5585, 0x5586, 0x5587, 0x5588, 0x5793, 0x5794, + /* 0x2e */ + 0x5795, 0x57ef, 0x57f0, 0x52fd, 0x588d, 0x588f, 0x5890, 0x5891, + 0x5892, 0x58de, 0x58e1, 0x5953, 0x1966, 0x5a4a, 0x5a4b, 0x5a4c, + 0x5a51, 0x5a4d, 0x5a48, 0x5b74, 0x5b75, 0x5c20, 0x5c21, 0x5ca5, + 0x5ca6, 0x5d73, 0x5d74, 0x5e50, 0x5e51, 0x5e52, 0x5e53, 0x5fdb, + 0x5fdc, 0x1c20, 0x5fdd, 0x5fde, 0x5fff, 0x52fd, 0x52fd, 0x5fdf, + 0x5fe0, 0x1c21, 0x5fe1, 0x5fe2, 0x5fe3, 0x5fe4, 0x5fe5, 0x5fe6, + 0x5fe7, 0x5fe8, 0x5fe9, 0x5fea, 0x6607, 0x6608, 0x6609, 0x660a, + 0x660b, 0x660c, 0x660d, 0x1ed7, 0x661a, 0x660e, 0x660f, 0x6610, + 0x661c, 0x6827, 0x6866, 0x6898, 0x6899, 0x6933, 0x6924, 0x6925, + 0x6926, 0x52fd, 0x02e1, 0x6a3e, 0xfa64, 0x6a3f, 0x6a57, 0x6a40, + 0x6a41, 0x6a58, 0x6a42, 0x6a43, 0x6a44, 0x6a45, 0x6a46, 0x02e2, + 0x6a47, 0x6c6b, 0x6c6c, 0x6d10, 0x6d11, 0x21be, + /* 0x2f */ + 0x6e75, 0x6eef, 0x6f6a, 0x6f6b, 0x52fd, 0x6f6c, 0x6f6d, 0x6f6e, + 0x70ef, 0x70f0, 0x70f1, 0x70f2, 0x70f3, 0x70f4, 0x70f5, 0x70ff, + 0x70f6, 0x7102, 0x70f7, 0x7322, 0x73c4, 0x73c3, 0x7528, 0x047c, + 0x7620, 0x7625, 0x7622, 0x7623, 0x76eb, 0x04e3, 0x77f9, 0x77fa, + 0x7999, 0x799a, 0x799b, 0x7963, 0x52fd, 0x795e, 0x795f, 0x7960, + 0x799c, 0x7961, 0x799d, 0x7e54, 0x7e55, 0x7e56, 0x7e57, 0x7e58, + 0x7e59, 0x7e5a, 0x7e19, 0x7e6a, 0x7e5b, 0x7e5c, 0x7e5d, 0x7e66, + 0x52fd, 0x7e5e, 0x7e5f, 0x7e1a, 0x7e60, 0x7e61, 0x52fd, 0x7e62, + 0x7e1b, 0x7e63, 0xb710, 0xb711, 0x834c, 0x839b, 0x83eb, 0x83ec, + 0x83ed, 0x83ee, 0x84a3, 0x84a8, 0x84a6, 0x06ec, 0x862f, 0x8630, + 0x8631, 0x8632, 0x8633, 0x874f, 0x8751, 0x8752, 0x877d, 0x8753, + 0x8754, 0x8755, 0x8756, 0x8757, 0x8758, 0x8759, + /* 0x30 */ + 0x875a, 0x875b, 0x875c, 0x2957, 0x875d, 0x875e, 0x875f, 0x876f, + 0x8760, 0x8761, 0x8762, 0x8763, 0x8772, 0x8764, 0x52fd, 0x876e, + 0x8bb5, 0x8e65, 0x8e66, 0x8e67, 0x8e68, 0x8e69, 0x8e6a, 0x8e6b, + 0x8e6c, 0x900e, 0x9043, 0x52fd, 0x900f, 0x9044, 0x9045, 0x9046, + 0x9047, 0x9048, 0x9049, 0x9010, 0x904a, 0x904b, 0x904c, 0x904d, + 0x08df, 0x904e, 0x904f, 0x9050, 0x9051, 0x9052, 0x9053, 0x9054, + 0x9055, 0x9056, 0x9057, 0x9058, 0x9059, 0x905a, 0x901d, 0x905b, + 0x905c, 0x905d, 0xfb06, 0x52fd, 0x94fe, 0x94ff, 0x9500, 0x9501, + 0x9502, 0x9503, 0x9504, 0x9505, 0x9506, 0x9507, 0x9518, 0x9508, + 0x9509, 0x94f3, 0x950a, 0x950b, 0x951b, 0x950c, 0x950d, 0x950e, + 0x950f, 0x9510, 0x980f, 0x9861, 0x9879, 0x9ac1, 0x9aac, 0x9aad, + 0x9c43, 0x9c44, 0x9c45, 0x9c46, 0x9c47, 0x9c48, + /* 0x31 */ + 0x9c49, 0x9c64, 0x9c4a, 0x9c4b, 0x9c4c, 0x9c4d, 0x0ac7, 0xfb2d, + 0x9e39, 0x9f57, 0x9f58, 0x9f59, 0x9f5f, 0x9f5a, 0xa06a, 0xa22b, + 0xa25d, 0xa25e, 0xa25f, 0x52fd, 0xa260, 0xa261, 0xa358, 0xa359, + 0xa44a, 0xa44b, 0xa44c, 0xa44d, 0xa44e, 0xa757, 0xa6b3, 0xa6b4, + 0xa76e, 0xa75b, 0xa75c, 0x52fd, 0xa75d, 0xa75e, 0x52fd, 0xa76c, + 0xa93d, 0xa954, 0xa93e, 0xa955, 0xa956, 0xa93f, 0xa957, 0xa958, + 0xa959, 0xa95a, 0xa95b, 0xa95c, 0xaa88, 0xaa89, 0x52fd, 0xac58, + 0xac59, 0xac5a, 0x52fd, 0xad67, 0xad68, 0xad69, 0xad6a, 0x52fd, + 0xad6b, 0xad6c, 0xadfe, 0xadff, 0xae00, 0xae01, 0xae02, 0xae03, + 0xae04, 0xae05, 0xb139, 0xb13a, 0xb13b, 0xb13c, 0x52fd, 0x52fd, + 0xb2b2, 0xb2b3, 0xb2b4, 0xb2b5, 0xb2b6, 0xb2b7, 0xb2b8, 0x3d3c, + 0xb5a2, 0xb661, 0xb662, 0xb714, 0x52fd, 0xb7eb, + /* 0x32 */ + 0xb842, 0xb848, 0x52fd, 0xb843, 0xb84e, 0xb844, 0xb845, 0xb9b4, + 0xb9b5, 0x52fd, 0x52fd, 0x52fd, 0xb9b6, 0x52fd, 0xbbe1, 0xbc05, + 0x52fd, 0x3e73, 0xbe9a, 0x52fd, 0xbe9b, 0xbe9c, 0xbe9d, 0xbe9e, + 0xbe9f, 0xfb9a, 0xbea0, 0xbea1, 0xbea2, 0xbeb5, 0xbea3, 0xbea4, + 0x52fd, 0xbea5, 0xbea6, 0xbea7, 0xbea8, 0xbeaf, 0xbea9, 0xbeaa, + 0xbeab, 0xbeac, 0xbead, 0xbeb3, 0x52fd, 0xc4a0, 0xc556, 0xc934, + 0x1127, 0xc93c, 0xcb0c, 0x52fd, 0xcf3e, 0xcfa3, 0xd030, 0xd031, + 0xd197, 0xd198, 0xd199, 0xd19a, 0xd19b, 0xd5b2, 0xd5ab, 0xd5ac, + 0xd9fc, 0xd9e8, 0xd9e9, 0xd9ea, 0xdaf1, 0xdc3f, 0xdfce, 0xe16d, + 0xe16e, 0xe16f, 0xe170, 0xe171, 0xe172, 0xe173, 0x4bbe, 0xe378, + 0xeb3a, 0x5467, 0x27fa, 0x5464, 0x5465, 0x5607, 0x55c4, 0x55c5, + 0x55c6, 0x55c7, 0x55c8, 0x55c9, 0x55e5, 0x55ca, + /* 0x33 */ + 0x55cb, 0x52fd, 0x55cc, 0x55cd, 0x55ce, 0x55cf, 0x55d0, 0x5797, + 0x579a, 0x579b, 0x58ea, 0x58ec, 0x58ed, 0x58f7, 0x58ee, 0x58ef, + 0x595b, 0x595c, 0x595d, 0x5a6d, 0x5a6e, 0x52fd, 0x5a6f, 0x5b81, + 0x5b82, 0x5c4f, 0x5cad, 0xda0a, 0x5d7e, 0x5e69, 0x6054, 0x6055, + 0x6056, 0x6057, 0x01ab, 0x6058, 0x6059, 0x605a, 0x605b, 0x605c, + 0x605d, 0x52fd, 0x52fd, 0x605e, 0x605f, 0x663b, 0x6636, 0x663c, + 0x663d, 0x663e, 0x663f, 0x6640, 0x6641, 0x6642, 0x024b, 0x6643, + 0x6644, 0x6645, 0x6637, 0x52fd, 0x52fd, 0x6646, 0x6647, 0x6648, + 0x6649, 0x682d, 0x68a5, 0x693d, 0x693f, 0x6c6e, 0x6ae7, 0x6a75, + 0x6a76, 0x6a77, 0x6a78, 0x6a79, 0x6a7a, 0x6a7b, 0x6a7c, 0x6a8e, + 0x6a7d, 0x6a7e, 0x2072, 0x6a7f, 0x6a80, 0x6a81, 0x6a82, 0x6a83, + 0x6a84, 0x6a85, 0x6a86, 0x6a87, 0x6a88, 0x6a89, + /* 0x34 */ + 0x6a8a, 0x6a8b, 0x6a8c, 0x6c6f, 0x6c70, 0x6c71, 0x6c72, 0x6d2a, + 0x6d2b, 0x6d2c, 0x6d2d, 0x6d2e, 0x6d2f, 0x6d30, 0x6d31, 0x6e83, + 0x6f84, 0x6f85, 0x6f93, 0x52fd, 0x6f86, 0x6f87, 0x6f88, 0x6f89, + 0x6f8a, 0x6f8b, 0x7136, 0x7138, 0x7139, 0x713a, 0x03e2, 0x713b, + 0x713c, 0x713d, 0x713e, 0x713f, 0x52fd, 0x7140, 0x7141, 0x7142, + 0x73de, 0x73df, 0x73e0, 0x73e1, 0x754a, 0x754b, 0x754c, 0x754d, + 0x754e, 0x754f, 0x7550, 0x7627, 0x76f9, 0x76fa, 0x76fb, 0x7798, + 0x7799, 0x779a, 0x52fd, 0x781e, 0x799e, 0x79f7, 0x799f, 0x79a0, + 0x79f0, 0x79f8, 0x79f9, 0x79a1, 0x79a2, 0x79a3, 0x79a4, 0x79a5, + 0x79fa, 0x79fb, 0x79fc, 0x79fd, 0x79fe, 0x7a1f, 0x79ff, 0x7a00, + 0x7a8c, 0x7a01, 0x7cc2, 0x7cc3, 0x52fd, 0x7cd3, 0x7d4e, 0x7eaf, + 0x7eb0, 0x7eb1, 0x7eb2, 0x7eb3, 0x7ec6, 0x7eb4, + /* 0x35 */ + 0x52fd, 0x7eb5, 0x7eb6, 0x7eb7, 0x7eb8, 0x7eb9, 0x7eba, 0x7ebb, + 0x7ebc, 0x7ebd, 0x7ebe, 0x7ebf, 0x7ec1, 0x7ec0, 0x7ec2, 0x7ec3, + 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, 0x835a, 0x8350, 0x8351, + 0x8378, 0x83f8, 0x83f9, 0x84c6, 0x84cb, 0x84cc, 0x84cd, 0x84ce, + 0x84cf, 0x84d0, 0x84d1, 0x84d2, 0x84d3, 0x84d4, 0x84d5, 0x52fd, + 0x8637, 0x8638, 0x8673, 0x8790, 0x8791, 0x87bf, 0x8792, 0x8793, + 0x8794, 0x8795, 0x8796, 0x8797, 0x8798, 0x8799, 0x29bd, 0x879a, + 0x879b, 0x879c, 0x879d, 0x879e, 0x879f, 0x87a0, 0x87a1, 0x87a2, + 0x87a3, 0x87a4, 0x87a5, 0x52fd, 0x87a6, 0x87a7, 0x8bbf, 0x8bc0, + 0x8bc1, 0x8bc2, 0x8bc3, 0x8bc4, 0x8bc5, 0x8bc6, 0x8c75, 0x8d43, + 0x8d12, 0x8d9f, 0x8d91, 0xfaf6, 0x8d92, 0x8d93, 0x8d94, 0x8e7e, + 0x8e7f, 0x8e80, 0x8e81, 0x8e82, 0x8f4c, 0x8f63, + /* 0x36 */ + 0x90c0, 0x90c1, 0x90c2, 0x953a, 0x90c3, 0x90c4, 0x90c5, 0x90c6, + 0x2e15, 0x90c7, 0x52fd, 0x90c8, 0x9073, 0x90c9, 0x90ca, 0x90cb, + 0x90cc, 0x90cd, 0x090e, 0x52fd, 0x52fd, 0x90ce, 0x90cf, 0x90d0, + 0x90d1, 0x90d2, 0x90d3, 0x90d4, 0x90d5, 0x953b, 0x953c, 0x953d, + 0x953e, 0x52fd, 0x953f, 0x9540, 0x9541, 0x9542, 0x9543, 0x09c1, + 0x9544, 0x9545, 0x9559, 0x9546, 0x9547, 0x9548, 0x52fd, 0x9549, + 0x9813, 0x9882, 0x9883, 0x9966, 0x9967, 0x9c65, 0x3313, 0x9c66, + 0x0ad9, 0x9c75, 0x9c74, 0x9c67, 0x9c6d, 0x9c76, 0x9c68, 0x9c69, + 0x9c6a, 0x9c6b, 0x9c4f, 0x9c6c, 0x9df8, 0x9e45, 0x33f8, 0x9e46, + 0x9ee4, 0x9f85, 0x9f6f, 0x9f70, 0xa082, 0xa083, 0xa084, 0xa08b, + 0xa22d, 0xa268, 0xa269, 0xa277, 0xa264, 0xa26a, 0x52fd, 0xa2f2, + 0xa2e2, 0xa363, 0xa364, 0xa365, 0xa366, 0x3a3d, + /* 0x37 */ + 0xa367, 0xa368, 0x35d8, 0x52fd, 0xa472, 0xa47d, 0xa669, 0xa784, + 0xa786, 0xa787, 0xa788, 0xa79e, 0x52fd, 0xa789, 0xa78a, 0xa796, + 0xa78b, 0xa78c, 0xa78d, 0xa979, 0xa983, 0xa97a, 0xa95d, 0xa97b, + 0x52fd, 0xaa9f, 0x0d48, 0xaaa0, 0xaaa1, 0xaaa2, 0x38fc, 0xac6a, + 0xac6b, 0xac6c, 0xac6d, 0xac6e, 0xad78, 0x52fd, 0xad79, 0xad7c, + 0xae21, 0xae22, 0xae23, 0xae24, 0x3a39, 0xae25, 0xae26, 0xb151, + 0xb152, 0xb156, 0x52fd, 0x3c4b, 0xb2e1, 0x52fd, 0x52fd, 0xb2d6, + 0xb2d7, 0xb2d8, 0xb2d9, 0xb5b5, 0xb66c, 0xb66f, 0xb670, 0xb7bc, + 0xb7bd, 0xb7ed, 0xb85b, 0xb85c, 0xb85d, 0xb85e, 0xb986, 0xb987, + 0xb9ed, 0x52fd, 0xb9ee, 0x52fd, 0xbc0e, 0xbc0f, 0x52fd, 0xbd2d, + 0xbd2a, 0xbd2e, 0xbdcc, 0xbef9, 0xbefa, 0xbefb, 0xbefc, 0x3fb9, + 0xbefd, 0xbf1b, 0xbefe, 0xbeff, 0xbf00, 0xbf01, + /* 0x38 */ + 0xbf02, 0xbf03, 0xbf21, 0xbf04, 0xbf05, 0xbf06, 0xbf07, 0xbf08, + 0xbf09, 0xbf0a, 0xbf0b, 0xbf0c, 0xbf0d, 0xbf0e, 0xbf0f, 0xbf10, + 0xbf11, 0xbf12, 0xbf13, 0xbf14, 0xbf15, 0xc57b, 0xc57c, 0xc57d, + 0xc57e, 0x40cf, 0xc57f, 0xc580, 0xc566, 0xc581, 0xc582, 0xc583, + 0xc8b2, 0x52fd, 0xc97f, 0xc972, 0xc95a, 0xcaeb, 0xcb15, 0x52fd, + 0xcb16, 0xfbca, 0xcb17, 0x52fd, 0xcbc5, 0xcbc6, 0xcbc7, 0xcc88, + 0xcc89, 0x52fd, 0xcc8a, 0xcc8b, 0xcc8c, 0xcc8d, 0xcedf, 0x52fd, + 0xd03b, 0xd03c, 0xd03d, 0xd03e, 0xd03f, 0xd040, 0xd041, 0xd042, + 0xd15c, 0xd1af, 0xd1a9, 0xd1aa, 0xd1ab, 0xd1ac, 0xd1b5, 0xd1ad, + 0xd1ae, 0xd2e2, 0xd524, 0x44ae, 0xd5c4, 0x52fd, 0xd7ea, 0xd7d3, + 0xd7d4, 0xd7d5, 0xd986, 0x52fd, 0xd987, 0xd9fd, 0xdb05, 0xdc49, + 0xdf5f, 0xdfd3, 0xdfd5, 0xe18a, 0xe18b, 0xe18c, + /* 0x39 */ + 0xe18d, 0xe18e, 0xe18f, 0xe190, 0xe191, 0xe192, 0xe193, 0xe37d, + 0xe37e, 0x4beb, 0x52fd, 0x52fd, 0xe4ec, 0xe55b, 0xef87, 0xef86, + 0x52fd, 0x5346, 0x5347, 0x5402, 0x546d, 0x546e, 0x546f, 0x560d, + 0x560e, 0x560f, 0x5610, 0x5611, 0x5612, 0x5613, 0x5614, 0x579f, + 0x57a0, 0x57a1, 0x57a3, 0x5821, 0x5822, 0x867c, 0x5895, 0x5896, + 0x5961, 0x5967, 0x5a91, 0x5a92, 0x5a93, 0x5a94, 0x5b8a, 0x5b8b, + 0x5bf7, 0x5c24, 0x5cb0, 0x5cb1, 0x5d8e, 0x5e04, 0x5e6a, 0x5e6b, + 0x5e6c, 0x5e6d, 0x60e8, 0x610c, 0x60e9, 0x60ea, 0x610d, 0x52fd, + 0x60eb, 0x60ec, 0x60ed, 0x60ee, 0x60ef, 0x60f0, 0x60f1, 0x60f2, + 0x6116, 0x60f3, 0x6104, 0x611d, 0x60f4, 0x60f5, 0x60f6, 0x60f7, + 0x1cb0, 0x6502, 0x6503, 0x6504, 0x669a, 0x667c, 0x66c5, 0x667d, + 0x667e, 0x667f, 0x6680, 0x6681, 0x1f40, 0x1f42, + /* 0x3a */ + 0x6682, 0x6683, 0x6684, 0x6685, 0x6686, 0x6687, 0x68ae, 0x694d, + 0x6ab0, 0x6adc, 0x6ab6, 0x6ab7, 0x6ab8, 0x6ab9, 0x6aba, 0x6abb, + 0x6adb, 0x6abc, 0x6abd, 0x6abe, 0x52fd, 0x6abf, 0x6ac0, 0x6ac1, + 0x6ac2, 0x6ac3, 0x6ace, 0x0301, 0x6ad9, 0x6ac4, 0x6ac5, 0x6ada, + 0x6ac6, 0x6ac7, 0x6ac8, 0x6ac9, 0x6aca, 0x6c7e, 0x6c7b, 0x6d4e, + 0x6d4f, 0x6d50, 0x6d51, 0x6d52, 0x6d53, 0x6d54, 0x6d55, 0x6e8f, + 0x6efc, 0x6fa6, 0x6fa7, 0x6fa8, 0x7023, 0x718b, 0x52fd, 0x718c, + 0x718d, 0x718e, 0x718f, 0x71a4, 0x5899, 0x7324, 0x7346, 0x7347, + 0x7348, 0x73fd, 0x73fe, 0x52fd, 0x756e, 0x757c, 0x756f, 0x7570, + 0x7571, 0x7572, 0x7629, 0x762a, 0x765f, 0x77a2, 0x7830, 0x782b, + 0x7a61, 0x7a02, 0x7a03, 0x7a04, 0x7a05, 0x7a06, 0x7a07, 0x52fd, + 0x7a08, 0x7a09, 0x7a62, 0x7a0a, 0x7a0b, 0x7a0c, + /* 0x3b */ + 0x7a0d, 0x7a0e, 0x7a63, 0x7a27, 0x7a0f, 0x52fd, 0x7a1b, 0x7a64, + 0x7a10, 0x7a11, 0x7a81, 0x7a12, 0x7a65, 0x7a13, 0x7cce, 0x7f29, + 0x7ec4, 0x7f2a, 0x52fd, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2e, 0x7f2f, + 0x7f30, 0x7f31, 0x7f32, 0x7f33, 0x7f34, 0x52fd, 0x7f35, 0x7f36, + 0x7ee3, 0x7f37, 0x7f38, 0x7f39, 0x7f3a, 0x7f3b, 0x7f4d, 0x7f3c, + 0x7f3d, 0x7f3e, 0x52fd, 0x81d0, 0x81d1, 0x8355, 0x8402, 0x8404, + 0x84fc, 0x8507, 0x84fd, 0x84fe, 0x52fd, 0x84ff, 0x8500, 0x8508, + 0x8501, 0x8502, 0x8535, 0x8503, 0x8504, 0x52fd, 0x863b, 0x8689, + 0x8681, 0x8682, 0xba33, 0x87eb, 0x87ec, 0x52fd, 0x87ed, 0x87ee, + 0x87ef, 0x52fd, 0x87f0, 0x87f1, 0x87f2, 0x2a2b, 0x87f3, 0x2a16, + 0x87f4, 0x87f5, 0x534b, 0x87f6, 0x87f7, 0x87f8, 0x87f9, 0x87fa, + 0x87fb, 0x87fc, 0x87fd, 0x87fe, 0x87ff, 0x8800, + /* 0x3c */ + 0x2a1b, 0x8801, 0x8802, 0x8803, 0x8804, 0x8805, 0x8806, 0x8807, + 0x2a27, 0x8808, 0x8809, 0x880a, 0x880b, 0x880c, 0x880d, 0x8bd7, + 0x8bd8, 0x8d29, 0x8d9c, 0x8df8, 0x8e98, 0x8ea4, 0x8e99, 0x8e9a, + 0x8e9b, 0x8e97, 0x8e9c, 0x2cf5, 0x8e9d, 0x52fd, 0x8e9e, 0x8e9f, + 0x8f65, 0x90d6, 0x0920, 0x9132, 0x9133, 0x9134, 0x2e82, 0x9135, + 0x9136, 0x9137, 0x90d7, 0x52fd, 0x90d8, 0x9138, 0x9139, 0x913a, + 0x913b, 0x913c, 0x913d, 0x913e, 0x913f, 0x9140, 0x90d9, 0x9141, + 0x9142, 0x0921, 0x9143, 0x9144, 0x2e7a, 0x957c, 0x957d, 0x957e, + 0x957f, 0x9580, 0x9581, 0x9582, 0x52fd, 0x9583, 0x9584, 0x9585, + 0x9586, 0x95a5, 0x9587, 0x9588, 0x9589, 0x958a, 0x958b, 0x958c, + 0x958d, 0x958e, 0x52fd, 0x52fd, 0x958f, 0x52fd, 0x9590, 0x9591, + 0x9592, 0x9593, 0x9594, 0x9595, 0x52fd, 0x3129, + /* 0x3d */ + 0x9596, 0x9856, 0x9857, 0x98e1, 0x990e, 0x990f, 0x997a, 0x997b, + 0x998b, 0x9af2, 0x9af3, 0x9c93, 0x9c94, 0x9c95, 0x9c96, 0x9c97, + 0x9cad, 0x9c98, 0x9cab, 0x9c7b, 0x9c99, 0x9c9a, 0x9c9b, 0x9c85, + 0x9c9c, 0x9c9d, 0x0ada, 0x52fd, 0x9cac, 0x9c79, 0x9c9e, 0x9ca4, + 0x9dfd, 0x9eeb, 0x9eea, 0x9f8f, 0x9f90, 0x9f86, 0x9f87, 0x9f88, + 0xa0ac, 0xa0ad, 0xa2ec, 0xa373, 0xa374, 0x52fd, 0xa4aa, 0xa4ab, + 0xa4ac, 0xa6d1, 0xa6d7, 0xa7b9, 0xa7ba, 0xa7bb, 0xa7bc, 0xa98e, + 0xa98f, 0xa990, 0xa97c, 0xa991, 0xa992, 0xa993, 0xa994, 0xfb54, + 0xa99a, 0xa995, 0xa996, 0xa997, 0xaabd, 0xaac7, 0xaabe, 0x52fd, + 0xaabf, 0x52fd, 0xac93, 0x6d5e, 0xad86, 0xad87, 0xad88, 0xad89, + 0xae41, 0xae42, 0xae43, 0xae44, 0xae45, 0xae46, 0xae4a, 0xae47, + 0xae48, 0xae49, 0xb16b, 0xb166, 0x52fd, 0xb167, + /* 0x3e */ + 0x3bab, 0xb168, 0x3bac, 0x52fd, 0xb2fd, 0xb2fe, 0xb2ff, 0xb300, + 0xb301, 0xb302, 0xb303, 0xb304, 0xb305, 0xb306, 0xb533, 0xb5c2, + 0xb5d0, 0xfb74, 0xb695, 0xb696, 0xb735, 0xb736, 0xb867, 0xb868, + 0xb869, 0xb86a, 0xb872, 0xb86b, 0xb86c, 0xb86d, 0xb86e, 0xb86f, + 0xba22, 0x52fd, 0x52fd, 0xba23, 0xba41, 0xba24, 0xba25, 0xba26, + 0xba27, 0xba28, 0xba29, 0xb9b7, 0x52fd, 0x52fd, 0x52fd, 0xbcda, + 0xbdcf, 0xbdda, 0xbf89, 0xbfb7, 0xbf8a, 0xbf8b, 0xc05e, 0xbf8c, + 0x52fd, 0xbf8d, 0xbf8e, 0xbf8f, 0xbf90, 0xbf91, 0xbf92, 0xbf93, + 0xbf94, 0xbfb6, 0xbf95, 0xbf96, 0xbf97, 0x3ff7, 0x52fd, 0xbf98, + 0xbf99, 0xbf9a, 0x0fea, 0x52fd, 0xbf9b, 0xbfbd, 0xbf9c, 0xbf9d, + 0xbf9e, 0xbf9f, 0xbfc0, 0xbfa0, 0xbfa1, 0xbfa2, 0xbfa3, 0xbfa4, + 0xbfa5, 0xbfa6, 0xbfa7, 0xbfa8, 0xbfa9, 0xbfaa, + /* 0x3f */ + 0x52fd, 0xc4b4, 0xc4b5, 0xc4b6, 0xc5b9, 0xc5ba, 0xc5bb, 0xc591, + 0xc5bc, 0xc8ee, 0xc8ef, 0xc996, 0xc997, 0xc973, 0xc998, 0xc999, + 0xcaed, 0xcaee, 0xcbde, 0xccb0, 0xccb1, 0xccb2, 0xccb3, 0xccb4, + 0xccb5, 0xccb6, 0xfbce, 0xccb7, 0xcee3, 0xcfb9, 0xd055, 0xd07e, + 0xd056, 0xd057, 0xd058, 0xd059, 0xd05a, 0x52fd, 0xd1c4, 0xd1c5, + 0xd1c6, 0xd1c7, 0xd1c8, 0xd1c9, 0xd1ee, 0xd1cf, 0xd1ca, 0xd1cb, + 0xd1cc, 0xd309, 0xfbda, 0xd303, 0xd52f, 0xd530, 0xd531, 0xd532, + 0xd80e, 0xd80f, 0xd810, 0xd811, 0xd812, 0x52fd, 0xd813, 0xd814, + 0xd815, 0xd7ff, 0xda1f, 0xda20, 0xda21, 0xda2d, 0x52fd, 0xdb1b, + 0xdb1c, 0xdb1d, 0xdb1e, 0xdc53, 0xdc54, 0xdc55, 0xdc56, 0xdc64, + 0xdc59, 0xdc57, 0x52fd, 0xdc58, 0xdf6b, 0x1489, 0x52fd, 0xdfe7, + 0xdfe8, 0xdfe9, 0xdfea, 0xdfeb, 0xdfec, 0x4a96, + /* 0x40 */ + 0xdfed, 0xe1b1, 0xe1b4, 0x52fd, 0xe38a, 0xe38d, 0xe38c, 0xe4f2, + 0xe4f3, 0x52fd, 0x7408, 0xe717, 0x15b2, 0xe89f, 0xe9a0, 0x52fd, + 0xeb6d, 0x837d, 0xf290, 0xf8c4, 0x534c, 0x5474, 0x5475, 0x5476, + 0x5649, 0x564a, 0x564b, 0x564c, 0x564d, 0x564e, 0x564f, 0x5650, + 0x5651, 0x5652, 0x5653, 0x5654, 0x5655, 0x5656, 0x57a4, 0x57a9, + 0x582a, 0x582b, 0x5ab3, 0x5ac1, 0x5b98, 0x5bfb, 0x5bfc, 0x5cbc, + 0x5d96, 0x5e0a, 0x52fd, 0x61a2, 0x52fd, 0x6181, 0x6182, 0x6183, + 0x6184, 0x6185, 0x6186, 0x6187, 0x6188, 0x6189, 0x618a, 0x618b, + 0x618c, 0x1cf1, 0x618d, 0x61d1, 0x6514, 0x66c9, 0x66ca, 0x66cb, + 0xedfd, 0x66cc, 0x66cd, 0x66ce, 0x66cf, 0x66d0, 0x66d1, 0x66d2, + 0x66d3, 0x66d4, 0x66d5, 0x6871, 0x534d, 0x6962, 0x6b0e, 0x6afe, + 0x6aff, 0x6b00, 0x52fd, 0x6b01, 0x6b02, 0x6b03, + /* 0x41 */ + 0x6b15, 0x6b04, 0x6b05, 0x52fd, 0x6c87, 0x6c89, 0x6d6e, 0x6d6f, + 0x6d70, 0x6d71, 0xfa6e, 0x6d72, 0x6d73, 0x6d74, 0x6e9d, 0x6fb8, + 0x6fb9, 0x6fba, 0x71c2, 0x71c3, 0x71d5, 0x71c4, 0x71c0, 0x71c5, + 0x71c6, 0x758a, 0x758b, 0x758c, 0x7664, 0xae8c, 0x2441, 0x770d, + 0x77a8, 0x783b, 0x783c, 0x783d, 0x783e, 0x783f, 0x7840, 0x7a66, + 0x7acb, 0x7ab7, 0x7ab8, 0x7ab9, 0x7aba, 0x7a67, 0x7abb, 0x7a68, + 0x7a69, 0x7a6a, 0x7abc, 0x52fd, 0x7cdb, 0x7f81, 0x7f82, 0x7f83, + 0x7f84, 0x7f85, 0x7f86, 0x7f87, 0x7f88, 0x7f89, 0xfabf, 0x7f8a, + 0x7f8b, 0x52fd, 0x7f8c, 0x7f8d, 0x7f8e, 0x7f8f, 0x7f90, 0x7fa1, + 0x7f91, 0x81d6, 0x829f, 0x8358, 0x8385, 0x840b, 0x840c, 0x8537, + 0x8538, 0xface, 0x8539, 0x853a, 0x853b, 0x853c, 0x853d, 0x853e, + 0x8540, 0x8541, 0x8542, 0x52fd, 0x8543, 0x868a, + /* 0x42 */ + 0x868b, 0x8890, 0x8859, 0x885b, 0x885c, 0x885d, 0x885e, 0x2a8a, + 0x885f, 0x8860, 0x8861, 0x8862, 0x8863, 0x8864, 0x8893, 0x8865, + 0x8866, 0x8867, 0x8868, 0x8869, 0x886a, 0x886b, 0x8895, 0x886c, + 0x886d, 0x886e, 0x886f, 0x2a8c, 0x8870, 0x8871, 0x8872, 0x8873, + 0x8874, 0x8875, 0x8876, 0x8877, 0x8878, 0x8879, 0x2a80, 0x887a, + 0x2a7f, 0x887b, 0x88a9, 0x887c, 0x8bf1, 0x8beb, 0x8c8a, 0x8d3d, + 0x8da6, 0x8da7, 0x8eba, 0x52fd, 0x8ebb, 0x8ebc, 0x8ebd, 0x9191, + 0x9192, 0x9193, 0x9194, 0x9195, 0x9196, 0x9197, 0x90da, 0x9198, + 0x9199, 0x919a, 0x52fd, 0x52fd, 0x919b, 0x919c, 0x919d, 0x919e, + 0x919f, 0x91a0, 0x91bf, 0x91a1, 0x91a2, 0x91a3, 0x91a4, 0x91a5, + 0x91a6, 0x91a7, 0x915b, 0xfb0d, 0x91a8, 0x95cb, 0x52fd, 0x09da, + 0x95cc, 0x964f, 0x95cd, 0x95ce, 0x95cf, 0x964e, + /* 0x43 */ + 0x95d0, 0x95d1, 0x95d2, 0x52fd, 0x95d3, 0x95d4, 0x95d5, 0x95d6, + 0x95d7, 0x95d8, 0x95d9, 0x95fa, 0x95da, 0x95db, 0xfb1c, 0x95dc, + 0x52fd, 0x52fd, 0x95dd, 0x95de, 0x95df, 0x95e0, 0x95e1, 0x95e2, + 0x95e3, 0x95e4, 0x95e5, 0x09db, 0x95e6, 0x95e7, 0x988e, 0x9998, + 0x9999, 0x52fd, 0x9b0a, 0x52fd, 0x9b26, 0x9b27, 0x9cbd, 0x9cdf, + 0x0ae2, 0x9cbe, 0x9cde, 0x9cbf, 0x9cc0, 0x9cc1, 0x9cc2, 0x9c9f, + 0x9cc3, 0x9cc4, 0x9cc5, 0x9cc6, 0x9cc7, 0x0ae3, 0x9cc8, 0x9cc9, + 0x9ce3, 0x9cca, 0x9ccb, 0x9ccc, 0x9ccd, 0x9cce, 0x9ccf, 0x9cd0, + 0x9cd1, 0x9cd2, 0x9cd3, 0xfb2f, 0x9cd4, 0x9e04, 0x9e65, 0x9eee, + 0x9fa0, 0x9fa1, 0xa0dd, 0xa0de, 0xa283, 0xa2fa, 0xa37f, 0xa380, + 0xa4e8, 0xa4e9, 0xa4ea, 0x88a6, 0xa6e1, 0x52fd, 0xa7db, 0xa7dc, + 0xa7dd, 0xa7de, 0xa7df, 0xa7e0, 0xa7e1, 0xa7e2, + /* 0x44 */ + 0xa7e3, 0xa7e4, 0xa7e5, 0xa7e6, 0x379c, 0xa7e7, 0xa9b0, 0xa998, + 0xa9b1, 0xa999, 0xa9b2, 0xa9b3, 0xa9b4, 0xa9b5, 0xa9b6, 0xa9b7, + 0xa9b8, 0xa9b9, 0xaae2, 0xaae3, 0xaae4, 0xaae5, 0xaae6, 0xaae7, + 0xaae8, 0xaae9, 0xacad, 0xaccf, 0xacae, 0xacaf, 0xacb0, 0xacb1, + 0xad92, 0xad93, 0xad94, 0xae79, 0x3a7b, 0xae7a, 0xae7b, 0xae7c, + 0xae7d, 0xae7e, 0xae7f, 0xae80, 0xae81, 0xae82, 0xae83, 0xae84, + 0xb197, 0xb184, 0xb185, 0xb189, 0xb186, 0xb187, 0xb32c, 0xb32d, + 0xb32e, 0xb32f, 0xb330, 0xb331, 0xb332, 0xb333, 0xb334, 0xb335, + 0xb336, 0xb337, 0xb5d2, 0xb744, 0xb800, 0xb883, 0xb884, 0xfb86, + 0xba7a, 0xba7b, 0xba7c, 0xba7d, 0xba7e, 0x52fd, 0xba7f, 0xba87, + 0xba80, 0xbd43, 0xc034, 0x1249, 0xc035, 0xc036, 0xc037, 0xc038, + 0xc039, 0xc03a, 0xc03b, 0xc03c, 0xc03d, 0xc03e, + /* 0x45 */ + 0xc03f, 0xc040, 0xc041, 0xc042, 0xc043, 0xc044, 0xc045, 0xc046, + 0xc047, 0xc048, 0xc049, 0xc04a, 0x52fd, 0xc04b, 0xc04c, 0xc04d, + 0xc04e, 0xc5e7, 0xc5e8, 0xc5e9, 0xc5ea, 0xc5eb, 0xc5ec, 0xc5ed, + 0xc5ee, 0xc8f7, 0xc99a, 0xc9cd, 0xfbc8, 0xc9a3, 0xc9ce, 0xcb31, + 0xcb32, 0xcb33, 0xcce4, 0x52fd, 0xcce5, 0xcce6, 0xcfc8, 0xd074, + 0xd075, 0xd076, 0xd077, 0xd078, 0xd079, 0xd07a, 0xd161, 0xd1df, + 0xd1e0, 0xd1e1, 0xd1e2, 0xd1e3, 0xd1e4, 0xd1e5, 0xd1e6, 0x12f3, + 0xd331, 0xd53d, 0xd53e, 0xd53f, 0xd5f4, 0xd5f5, 0xd5f6, 0x52fd, + 0xd717, 0xd841, 0xd842, 0xd843, 0xd844, 0xd845, 0xd846, 0xd847, + 0xd848, 0xd849, 0xd84a, 0xd84b, 0x46d2, 0xd9ba, 0xda44, 0xdc2a, + 0xdc6d, 0x4774, 0xfbe7, 0xdc7e, 0xdc6e, 0xdc6f, 0xdc70, 0xdc71, + 0xdc76, 0xdf79, 0x4aa0, 0x52fd, 0xe004, 0xdff8, + /* 0x46 */ + 0xe005, 0xe1da, 0xe1db, 0xe1dc, 0xe1dd, 0xe1de, 0xe1df, 0xe1e0, + 0xe1e1, 0xe3c5, 0xe39a, 0xe39b, 0xe39c, 0xe4d8, 0xe4d9, 0xe4da, + 0xe56e, 0x1557, 0xe76b, 0xd083, 0x52fd, 0xe9d6, 0xe9bd, 0x52fd, + 0x852e, 0xedfc, 0xf053, 0xf0b7, 0xf58c, 0xf68e, 0xf5ff, 0x5376, + 0x5406, 0x547e, 0x5684, 0x5685, 0x5686, 0x5687, 0x5688, 0x56a7, + 0x5689, 0x568a, 0x568b, 0x568c, 0x568d, 0x568e, 0x568f, 0x56a3, + 0x5690, 0x5691, 0x5692, 0x5693, 0x56ac, 0x5694, 0x5695, 0x5696, + 0x57aa, 0x57ab, 0x589e, 0x18a9, 0x5908, 0x5909, 0x5968, 0x5969, + 0x596a, 0x599a, 0x5ad9, 0x5ada, 0x5adb, 0x5ba8, 0x5c01, 0x5c28, + 0x5c77, 0x5cbd, 0x5cbe, 0x6260, 0x5da0, 0x5da2, 0x5e0f, 0x5e85, + 0x61fe, 0x61ff, 0x6200, 0x6201, 0x6216, 0x6202, 0x6203, 0x6204, + 0x6205, 0x6206, 0x6207, 0x6208, 0x6222, 0x6209, + /* 0x47 */ + 0x620a, 0x620b, 0x620c, 0x6214, 0x6229, 0x616e, 0x620d, 0x620e, + 0x620f, 0x6210, 0x6211, 0x6212, 0x6213, 0x651b, 0x651c, 0x651d, + 0x6713, 0x66ff, 0x6700, 0x6701, 0x6702, 0x6703, 0x6704, 0x670a, + 0x6705, 0x6706, 0x6707, 0x6708, 0x683a, 0x6873, 0x696f, 0x6970, + 0x6971, 0x5352, 0x52fd, 0x6d9a, 0x6b60, 0xfa69, 0x6b2b, 0x6b24, + 0x6b2c, 0x6b2d, 0x6b2e, 0x6b2f, 0x6b30, 0x6b31, 0x6b32, 0x6b33, + 0x6b34, 0x6b35, 0x6b45, 0x6b36, 0x6c92, 0x6c93, 0x6d88, 0x6d89, + 0x6d8a, 0x6d8b, 0x6e3f, 0x52fd, 0x6fca, 0x71f6, 0x71f7, 0x71f8, + 0x71f9, 0x742b, 0x52fd, 0x74a4, 0x74ce, 0x52fd, 0x759e, 0x759f, + 0x75a0, 0x75a1, 0x75a2, 0x75a3, 0x75a4, 0x75a5, 0x75a6, 0x7718, + 0x7860, 0x7861, 0x7862, 0x7863, 0x7864, 0x7abd, 0x7abe, 0x7b0b, + 0x7abf, 0x7ac0, 0x52fd, 0x7b0c, 0x7a8d, 0x7b0d, + /* 0x48 */ + 0x7b0e, 0x7b5e, 0x7b0f, 0x7b10, 0x7ac1, 0x7b11, 0x52fd, 0x7ac2, + 0x7cea, 0x7ceb, 0x7fe3, 0x7fe4, 0x7fe5, 0x7fe6, 0x7fe7, 0x7f92, + 0x804a, 0x52fd, 0x7fe8, 0x7fe9, 0x7fea, 0x8001, 0x7feb, 0x7fec, + 0x7fef, 0x7fed, 0x7fee, 0x7ff0, 0x7ff1, 0x7ff2, 0x7ff3, 0x7ff4, + 0x7ff5, 0x7ff6, 0x7ff7, 0x7ff8, 0x7ff9, 0x7ffe, 0x7ffa, 0x7ffb, + 0x7ffc, 0x8563, 0x8564, 0x8565, 0x8566, 0x8567, 0x8568, 0x890b, + 0x890d, 0x07bc, 0x890e, 0x890f, 0x07a4, 0x8914, 0x88d4, 0x88d5, + 0x88d6, 0x88d7, 0x88d8, 0x88d9, 0x88da, 0x88db, 0x88dc, 0x88dd, + 0x88de, 0x88df, 0x88e0, 0x88e1, 0x88e2, 0x88e3, 0x88e4, 0x88e5, + 0x88e6, 0x88e7, 0x88e8, 0x88e9, 0x88ea, 0x88eb, 0x88ec, 0x89ec, + 0x88ed, 0x88ee, 0x88ef, 0x8900, 0x88f0, 0x8c04, 0x52fd, 0x8c05, + 0xfaf3, 0x8db5, 0xfaf9, 0x8ed6, 0x8ed7, 0x8ed8, + /* 0x49 */ + 0x8ed9, 0x91a9, 0x9200, 0x9201, 0x9202, 0x9203, 0x9204, 0x9205, + 0x9206, 0x923f, 0x9207, 0x9208, 0x9209, 0x920a, 0x91b6, 0x920b, + 0x920c, 0x52fd, 0x52fd, 0x920d, 0x52fd, 0x920e, 0x920f, 0x9210, + 0x9211, 0x9212, 0x9235, 0x9213, 0x9214, 0x91aa, 0x52fd, 0x92c1, + 0x9215, 0x9216, 0x9217, 0x961e, 0x961f, 0x9620, 0x9621, 0x52fd, + 0x9622, 0x9623, 0x3195, 0x9624, 0x9625, 0x9626, 0x9627, 0x9628, + 0x9629, 0x962a, 0x962b, 0x9607, 0x962c, 0x962d, 0x962e, 0x09e8, + 0x52fd, 0x962f, 0x9630, 0x9648, 0x9631, 0x9632, 0x3198, 0x9633, + 0x52fd, 0x9634, 0x9635, 0x9636, 0x9859, 0x9891, 0x98e7, 0x99b8, + 0x99b9, 0x99ba, 0x99bb, 0x99c8, 0x9b4d, 0x9b89, 0x9b50, 0x9b28, + 0x9cfb, 0x9cfc, 0x9cfd, 0x9cfe, 0x9cff, 0x3378, 0x9d00, 0x9d01, + 0x9d02, 0x9ce4, 0x9ce5, 0x9d03, 0x9d04, 0x9d05, + /* 0x4a */ + 0x9d06, 0x9d07, 0x9d13, 0x9d08, 0x9d09, 0x9ce6, 0x9d0a, 0x9d0b, + 0x9d0c, 0x9e0b, 0x9ef4, 0x9f0a, 0x9fb1, 0xa11d, 0xfb3b, 0xa28b, + 0xa28c, 0xa28f, 0xa28d, 0xa28e, 0xa306, 0xa386, 0xa522, 0xa523, + 0xa524, 0xa525, 0xa526, 0xa527, 0xa528, 0xa6f1, 0x37b9, 0xa823, + 0xa812, 0x52fd, 0xa813, 0xa814, 0xa815, 0xa816, 0xa817, 0xa818, + 0xa819, 0xa84b, 0xa81a, 0xa81b, 0xa81c, 0x52fd, 0xa81d, 0xa81e, + 0xa81f, 0xa820, 0xa9ca, 0x75ac, 0xa9cb, 0xa9cc, 0xa9cd, 0xa9ce, + 0x52fd, 0xa9cf, 0xab10, 0xab11, 0xab12, 0xab13, 0xab14, 0xab0f, + 0xab15, 0xab16, 0xab17, 0x3933, 0xab18, 0xacc6, 0xad9f, 0xada0, + 0xada4, 0xada1, 0xaeb5, 0xaeb6, 0xaeb7, 0xaeb8, 0xaeb9, 0xaeba, + 0xaed0, 0xaec6, 0xaebb, 0xaebc, 0xaebd, 0xaebe, 0xaebf, 0xaec0, + 0xaec1, 0xaec2, 0xfb60, 0xb1a7, 0xb1a8, 0xb1a9, + /* 0x4b */ + 0xb1aa, 0xb1ab, 0xb1ac, 0xb1bc, 0xb1ad, 0xb1ae, 0x3bc0, 0xb1af, + 0xb1b0, 0xb1b1, 0x3bc1, 0xb1b4, 0xb1b2, 0xb366, 0xb367, 0xb368, + 0xb369, 0xb36a, 0xb36b, 0xb36c, 0xb36d, 0xb36e, 0xb36f, 0x52fd, + 0xb53e, 0xb53f, 0xb540, 0xb5e8, 0xb752, 0xb753, 0xb754, 0xb755, + 0xb891, 0xb892, 0xb893, 0xb894, 0xb895, 0xb896, 0xb897, 0xb898, + 0x52fd, 0xb899, 0xb89a, 0xb89b, 0xbab7, 0xbab8, 0xbab9, 0x52fd, + 0xbaba, 0xbabb, 0xbabd, 0x52fd, 0xbabc, 0xfb88, 0xfb87, 0xbbeb, + 0xbbec, 0xbc16, 0xbc44, 0xbce3, 0xbd58, 0xbd53, 0xbd54, 0xbde0, + 0xc0b1, 0xc0b2, 0xc0b3, 0xc0ea, 0x52fd, 0xc0b4, 0xc0f0, 0xc0b5, + 0xc0b6, 0xc0b7, 0xc0b8, 0xc0b9, 0xc0ba, 0xc0bb, 0xc0bc, 0xc0bd, + 0xc0be, 0xc0bf, 0xc0c0, 0xc0c1, 0xc0c2, 0xc0c3, 0x52fd, 0xc0c4, + 0xc0c5, 0xc0c6, 0xc0fc, 0xc0c7, 0xc0c8, 0xc0c9, + /* 0x4c */ + 0xc0ca, 0xc0cb, 0xc0cc, 0xc184, 0xc0cd, 0xc0ce, 0xc0cf, 0xc0d0, + 0xc0d1, 0xc0d2, 0xc4ca, 0xc4cb, 0xc636, 0xc637, 0xc69f, 0xc638, + 0xc639, 0xc63a, 0x4144, 0xc9be, 0xc9f0, 0xc9bf, 0xc9c0, 0xcaf7, + 0xcaf8, 0xcafa, 0xcb43, 0xcb44, 0xcd0f, 0xcd10, 0xcd11, 0xcd12, + 0x43ad, 0xcd13, 0xcd14, 0xcd15, 0xcd16, 0x52fd, 0x52fd, 0xcfd3, + 0xcfd7, 0x52fd, 0xd0b0, 0xd098, 0xd090, 0xd091, 0xd092, 0xd097, + 0xd093, 0xd164, 0xd201, 0xd202, 0xd203, 0xd204, 0xd205, 0xd206, + 0xd207, 0xd35a, 0xd35b, 0xd54e, 0xd54f, 0xd550, 0xd619, 0xd61a, + 0xd61b, 0x52fd, 0xd61c, 0x52fd, 0xd719, 0xd71a, 0x1386, 0xdc8a, + 0xd86e, 0xd86f, 0x4664, 0xd870, 0xd871, 0xd872, 0xd873, 0xd874, + 0xd875, 0xd876, 0xdb3a, 0xdb3b, 0xdb3c, 0xdb5a, 0xdb3d, 0xdb42, + 0xdc8b, 0xdca0, 0xdc8c, 0xdc8d, 0xdc8e, 0xdcab, + /* 0x4d */ + 0xdc8f, 0x4777, 0xdc90, 0xdc91, 0xdc92, 0xdcaa, 0x47af, 0xdc93, + 0xdc94, 0xdc9e, 0xdca8, 0x52fd, 0x52fd, 0xe200, 0xe201, 0xe202, + 0xe203, 0xe204, 0xe205, 0xe2c4, 0xe2c5, 0x52fd, 0xe3ae, 0xe3b2, + 0x52fd, 0x52fd, 0xe4f7, 0xe513, 0xe69e, 0xe785, 0xa680, 0xe7c8, + 0xeb41, 0xeb81, 0xeb82, 0xeb83, 0xeb84, 0xedc4, 0xedc5, 0xedc6, + 0xef95, 0xef96, 0xef97, 0xf058, 0xf059, 0x52fd, 0xf2a9, 0xf2aa, + 0xf2ab, 0xf58e, 0xf603, 0xf6b3, 0x5e82, 0x5353, 0x5483, 0x5484, + 0x5485, 0x56cc, 0x56cd, 0x56ce, 0x56cf, 0x56d0, 0x52fd, 0x56d1, + 0x56d2, 0x56da, 0x57b3, 0x57b4, 0x52fd, 0x5913, 0x590e, 0x596b, + 0x5c03, 0x5c61, 0x5cc1, 0x5cc2, 0x5db5, 0x5440, 0x6298, 0x6299, + 0x629a, 0x629b, 0x629c, 0x629d, 0x629e, 0x629f, 0x62ee, 0x62a0, + 0x62a1, 0x6286, 0x6525, 0x6734, 0x6735, 0x6751, + /* 0x4e */ + 0x672d, 0x9662, 0x6754, 0x6752, 0x026d, 0x6736, 0x6737, 0x6738, + 0x6739, 0x673a, 0x673b, 0x6768, 0x673c, 0x026e, 0x6877, 0x8596, + 0x697e, 0x697f, 0x6b69, 0x6b6a, 0x6b6b, 0x6b6c, 0x6b6d, 0x6b6e, + 0x6b6f, 0x6b5d, 0x6b70, 0x6b85, 0x6b71, 0x6b72, 0x6b73, 0x6b74, + 0x6b75, 0x6b76, 0x6b84, 0x6b77, 0x6b83, 0x6c9a, 0x6da7, 0x6da8, + 0x6da9, 0x6daa, 0x6dab, 0x6dac, 0x6db7, 0x6dad, 0x6dae, 0x52fd, + 0x6e45, 0x6fd3, 0x6fd4, 0x6fd5, 0x6fd6, 0x6fd7, 0x7226, 0x7227, + 0x7228, 0x52fd, 0x7229, 0x722a, 0x7305, 0x2364, 0x74d0, 0x75b7, + 0x52fd, 0x75b8, 0x75b9, 0x7722, 0x7723, 0x7873, 0x7874, 0x7b8f, + 0x7b12, 0x7b13, 0x7b14, 0x7b15, 0x7b16, 0x7b17, 0x7b18, 0x7b61, + 0x7b66, 0x7b67, 0x7b19, 0x7b68, 0x7b1a, 0x7b69, 0x7d04, 0x7d05, + 0x52fd, 0x7d06, 0x7cfd, 0x8050, 0x8051, 0x8052, + /* 0x4f */ + 0x8053, 0x8054, 0x8055, 0x8063, 0xfac4, 0x8056, 0x8057, 0x8058, + 0x8059, 0x805a, 0x805b, 0x52fd, 0x805c, 0x805d, 0x805e, 0x805f, + 0x82d7, 0x52fd, 0x8360, 0x8361, 0x8417, 0x8439, 0x858f, 0x85c8, + 0x8590, 0x8591, 0x8698, 0x8699, 0x8944, 0x8945, 0x8946, 0x8959, + 0x89ee, 0x2b2b, 0x8947, 0x8948, 0x52fd, 0x8949, 0x894a, 0x894b, + 0x894c, 0x894d, 0x894e, 0x894f, 0x8950, 0x8951, 0x8952, 0x8953, + 0x8954, 0x8955, 0x8956, 0x8c15, 0x8c9a, 0x8d58, 0x8dfc, 0x8dfd, + 0x9286, 0x9287, 0x9288, 0x9289, 0x928a, 0x928b, 0x928c, 0x52fd, + 0x931f, 0x928d, 0x928e, 0x928f, 0x9290, 0x9291, 0x9292, 0x9293, + 0xfb11, 0x9294, 0x9295, 0x91ca, 0x9218, 0x52fd, 0x9296, 0x9297, + 0x9298, 0x9299, 0x929a, 0x929b, 0x929c, 0x929d, 0x929e, 0x929f, + 0x2f46, 0x52fd, 0x92a0, 0x92a1, 0x2f9a, 0x92b7, + /* 0x50 */ + 0x52fd, 0x9696, 0x9668, 0x9669, 0x968c, 0x966a, 0x966b, 0x966c, + 0x966d, 0x966e, 0x966f, 0x967f, 0x9684, 0x9670, 0x9671, 0x9685, + 0x9672, 0x9673, 0x9674, 0x9675, 0x9676, 0x52fd, 0x9677, 0x9678, + 0x9679, 0x967a, 0x967b, 0x967c, 0xfb1e, 0x9894, 0x99d5, 0x9b29, + 0x9d2b, 0x9d2c, 0x9d2d, 0x9d2e, 0x9d2f, 0x9d30, 0x9d3e, 0x9d31, + 0x9d32, 0x9d33, 0x9d34, 0x9d35, 0x9e11, 0x0b53, 0x9fc0, 0xa142, + 0xa143, 0xa144, 0xa145, 0xa146, 0xa38c, 0xa38d, 0xa38e, 0xa38f, + 0xa390, 0xa391, 0xa563, 0xa564, 0xa565, 0x52fd, 0xfb4a, 0x52fd, + 0xa6f6, 0xa836, 0xa837, 0xa82c, 0xa838, 0xa839, 0x52fd, 0xa83a, + 0xa9e3, 0xa9e2, 0xa9f5, 0xab47, 0x52fd, 0xab48, 0xab49, 0xab4a, + 0xab4b, 0xab4c, 0xada8, 0xada9, 0xadaa, 0x52fd, 0xaf0b, 0xaf06, + 0xaf73, 0xaf0c, 0xaf0d, 0xaf0e, 0xaf0f, 0xaf10, + /* 0x51 */ + 0x52fd, 0xaf11, 0xfb62, 0xaf12, 0xaf14, 0xaf15, 0xaf16, 0x52fd, + 0xaf13, 0xaf17, 0xb1d9, 0xb1da, 0xb1db, 0x52fd, 0xb1dc, 0xb3a6, + 0xb3a7, 0xb3a8, 0xb3a9, 0xb3aa, 0xb3ab, 0x52fd, 0xfb6d, 0xb3ac, + 0xb3ad, 0xb3ae, 0x52fd, 0x52fd, 0xb3af, 0xb3b0, 0xb3b1, 0xb544, + 0xb545, 0xb5f7, 0xb5f8, 0xb76b, 0xb76c, 0xb761, 0xb812, 0xb8af, + 0xb8b0, 0xb8b1, 0xb8b2, 0xb8b3, 0xb8b4, 0xb8b5, 0xb8b6, 0xb922, + 0xbaea, 0xbaeb, 0xbaec, 0xbaed, 0x0f3d, 0xbbed, 0xbc1b, 0xbc47, + 0xbce8, 0xbdd0, 0xbde7, 0xbde8, 0xbde9, 0xc14e, 0xc14f, 0xc150, + 0xc172, 0xc151, 0xc152, 0xfba7, 0x1026, 0xc153, 0xc154, 0xc155, + 0xc156, 0xc157, 0xc177, 0xc158, 0xc159, 0xc15a, 0xc15b, 0xc15c, + 0xc16e, 0xc15d, 0x1027, 0x52fd, 0xc15e, 0x1028, 0xc15f, 0x52fd, + 0xc4d7, 0xc689, 0xc68a, 0x52fd, 0xfbbe, 0xc68b, + /* 0x52 */ + 0xc68c, 0xc68d, 0xc68e, 0xfbbc, 0xc68f, 0x52fd, 0xc69a, 0xc690, + 0xc691, 0xc692, 0xc693, 0xca12, 0xc9f1, 0x52fd, 0xcafe, 0xcafb, + 0xcb57, 0xcd49, 0xcd4a, 0xcd4b, 0xcd4c, 0x52fd, 0xcd4d, 0xcd59, + 0xcd4e, 0xcd4f, 0xcef4, 0xcf65, 0xd0a6, 0xd0a7, 0xd0a8, 0xd222, + 0xd223, 0xd38b, 0xd38c, 0xd38d, 0xd38e, 0xd558, 0x52fd, 0xd559, + 0xd63b, 0xd63c, 0xd63d, 0xd63e, 0xd748, 0xd894, 0xd895, 0xd896, + 0xd897, 0xd898, 0xda7d, 0xd9fe, 0xda7e, 0xda7f, 0x52fd, 0xdb5b, + 0xdb5c, 0xdce4, 0xdcc1, 0xdcfd, 0xdcc2, 0xdcd6, 0xdcc3, 0xdcc4, + 0x52fd, 0xdcdc, 0xdcc5, 0xdcc6, 0xdcc7, 0xdce1, 0xdcc8, 0xdcc9, + 0xdcca, 0xdccb, 0x47f2, 0xdccc, 0xdccd, 0xe035, 0xe036, 0xe047, + 0xe037, 0xe21b, 0xe21c, 0xe21d, 0xe21e, 0xe21f, 0xe220, 0xe27b, + 0xe27a, 0xe2fe, 0xe3c6, 0xe3c7, 0xe3c8, 0xe3c9, + /* 0x53 */ + 0xe3ca, 0x52fd, 0xe7a0, 0xe7a1, 0xe8cc, 0xe8cd, 0xe9f1, 0xe9d7, + 0xeb42, 0xeb46, 0xeba3, 0xeba5, 0xeba6, 0xedcb, 0xedcc, 0xee26, + 0xee27, 0xee28, 0xee29, 0xefae, 0xefaf, 0xefb0, 0xf073, 0x52fd, + 0xf07c, 0xf074, 0x52fd, 0xf280, 0xf075, 0x4c79, 0x52fd, 0xf2cf, + 0x52fd, 0xf68f, 0x5970, 0x5385, 0x5697, 0x56f6, 0x56f7, 0x56f8, + 0x56fa, 0x56fb, 0x57ba, 0x57bb, 0x57bc, 0x57bd, 0x5834, 0x5835, + 0x58a2, 0x5914, 0x5911, 0x596e, 0x596f, 0x5b08, 0x5bb8, 0x5d09, + 0x5dbd, 0x5dbe, 0x5e88, 0x62fe, 0x1d7a, 0x62ff, 0x6300, 0x6301, + 0x6302, 0x6303, 0x6304, 0x6305, 0x6306, 0x52fd, 0x6307, 0x6308, + 0x6309, 0x630a, 0x630b, 0x630c, 0x630d, 0x630e, 0x630f, 0x52fd, + 0x52fd, 0x52fd, 0x652c, 0x676b, 0x52fd, 0x676c, 0x6787, 0x676d, + 0x6878, 0x698b, 0x6ba4, 0x6ba5, 0x6ba6, 0x6ba7, + /* 0x54 */ + 0x6bbe, 0x6ba8, 0x6ba9, 0x6baa, 0x6b8d, 0x6bab, 0x6bac, 0x6bbf, + 0x52fd, 0x032c, 0x6bad, 0x6bae, 0x6ca4, 0x6ca5, 0x6dc7, 0x6dc8, + 0x6dc9, 0xd0bc, 0x6dca, 0x6dcb, 0x6dcc, 0x6dcd, 0x6dce, 0x6f19, + 0x6fe6, 0x724c, 0x724d, 0x724e, 0x7306, 0x52fd, 0x75cd, 0x75ce, + 0x75cf, 0x75d0, 0x245c, 0x7881, 0x7882, 0x5833, 0x7b6a, 0x7b6b, + 0x7bb2, 0x7b6c, 0x7b6d, 0x7bcc, 0x7bae, 0x7bb3, 0x7b91, 0x52fd, + 0x7b6e, 0x7bb4, 0x7b6f, 0x80c9, 0x80a7, 0x80a8, 0x80a9, 0x80aa, + 0x80ab, 0x80ac, 0x80ad, 0x80ae, 0x80af, 0x80b0, 0x8060, 0x80b1, + 0x81e1, 0x82e3, 0x82f6, 0x26d9, 0x85af, 0x85b0, 0x85b1, 0x85ba, + 0x85b2, 0x85b3, 0x864c, 0x52fd, 0x86a0, 0x86a1, 0x89b0, 0x89b1, + 0x89b2, 0x89b3, 0x89b4, 0xfaeb, 0x89b5, 0x89b6, 0x89b7, 0x89b8, + 0x89b9, 0x89ba, 0x2b72, 0x89bb, 0x89bc, 0x89bd, + /* 0x55 */ + 0x89be, 0x89bf, 0x89df, 0x89c0, 0x89c1, 0x89c2, 0x89c3, 0x89c4, + 0x2b78, 0x52fd, 0x89c5, 0x89c6, 0x89c7, 0x89c8, 0x89c9, 0x89ca, + 0x8a3c, 0x89cb, 0x89cc, 0x89cd, 0x89ce, 0x89cf, 0x89d0, 0x89d1, + 0x2c5a, 0x8c1d, 0x8c1e, 0x8d64, 0x8d65, 0x8dc5, 0x8dc6, 0x8dc7, + 0x8dff, 0x8eff, 0x8f00, 0x8f01, 0x8f02, 0x92f5, 0x935c, 0x92f6, + 0x92f7, 0x92b0, 0x92f8, 0x92f9, 0x935d, 0x9350, 0x92fa, 0x92fb, + 0x92a2, 0x92fc, 0x92fd, 0x92fe, 0x92ff, 0xfb13, 0x9300, 0xfb1f, + 0x96c1, 0x96c2, 0x96c3, 0x96c4, 0x96c5, 0x96c6, 0x96c7, 0x96c8, + 0x96c9, 0x96ca, 0x96cb, 0xe3ef, 0x96d7, 0x96cc, 0x96cd, 0x96ce, + 0x9722, 0x96cf, 0x96d0, 0x52fd, 0x96d1, 0x96d2, 0x96e9, 0x96d3, + 0x96d4, 0x96d5, 0x9838, 0x633b, 0x9b7d, 0x586f, 0x9ba1, 0x9d53, + 0x9d54, 0x0afb, 0x9d55, 0x9d3c, 0x9d56, 0x52fd, + /* 0x56 */ + 0x9d66, 0x0afc, 0x9d57, 0x9d58, 0x9d59, 0x9d5a, 0x9d5b, 0x9d67, + 0x9d5c, 0x52fd, 0x52fd, 0x9d6a, 0x9d5d, 0x9d3d, 0x9d5e, 0x9d65, + 0x9fe1, 0x9fcd, 0xf311, 0xa16f, 0xa170, 0xa31a, 0xa39a, 0xa39b, + 0xa39c, 0xa39e, 0xa39f, 0xfb3f, 0xa58e, 0x52fd, 0xa6fd, 0x52fd, + 0xa85e, 0xa85f, 0xa860, 0xa865, 0xa867, 0xa868, 0xa869, 0x52fd, + 0xa86a, 0xa88f, 0xa86b, 0xa86c, 0xa86d, 0xa9f7, 0xa9f8, 0xa9f9, + 0xa9e4, 0xa9fa, 0xabb1, 0xab75, 0xab76, 0xacff, 0xad00, 0xad01, + 0xad02, 0xad03, 0xadae, 0xadad, 0xaf51, 0xaf52, 0x52fd, 0xaf53, + 0xaf54, 0xaf55, 0xaf56, 0xaf57, 0xaf58, 0xaf59, 0xaf5a, 0xaf5b, + 0xaf5c, 0xaf5d, 0xaf5e, 0xaf5f, 0xaf60, 0xaf61, 0xaf62, 0xaf63, + 0xaf64, 0xaf4c, 0xaf66, 0xb1f1, 0xb1f2, 0xb3f2, 0xb3f3, 0xb3f4, + 0xb3f5, 0xb3f6, 0xb3f7, 0xb3f8, 0xb3f9, 0xb3fa, + /* 0x57 */ + 0xb54c, 0xb54b, 0xb61b, 0xb6ce, 0xb6b3, 0xb77f, 0xfb79, 0xfb7c, + 0xb81a, 0xb8c4, 0xb8c5, 0xb8c6, 0xb8c7, 0xb8c8, 0xb8c9, 0x52fd, + 0xbb19, 0xbb1c, 0xbb1a, 0xbc4c, 0xbc8e, 0xbd7e, 0xc1eb, 0xc1ec, + 0xc1ed, 0xc1ee, 0xc1ef, 0xc1f0, 0xc1f1, 0xc1d8, 0xc1d9, 0xc1da, + 0xc1db, 0xc1f2, 0xc1f3, 0xc1f4, 0xc207, 0x52fd, 0xfbac, 0x52fd, + 0xc1f5, 0xc215, 0x52fd, 0xc1f6, 0xc1f7, 0xc1f8, 0xc1f9, 0xc1fa, + 0xc1fb, 0xc1fc, 0xc1fd, 0xc1fe, 0xc2a7, 0xc1ff, 0xc200, 0xc201, + 0xc202, 0xc203, 0xc204, 0xc205, 0xc4e9, 0xc4ea, 0xc4eb, 0xc6de, + 0xc6df, 0x52fd, 0xc6e0, 0xc6e1, 0xc6e2, 0xc6e3, 0xca3e, 0xca3f, + 0xca40, 0xca41, 0xcb71, 0xcb72, 0xcb73, 0xcd88, 0xcd89, 0xcd8a, + 0xcd8b, 0xcd8c, 0xcd8d, 0xcd8e, 0xcd8f, 0xcd90, 0xcd91, 0xcd92, + 0x52fd, 0xcff1, 0xd0be, 0xd0bf, 0xd0c0, 0xd0c1, + /* 0x58 */ + 0xd0c2, 0xd0c3, 0xd16e, 0xd237, 0xd257, 0xd238, 0xd239, 0xd23a, + 0xd23b, 0xd23c, 0xd23d, 0xd23e, 0xd227, 0xd23f, 0x52fd, 0x52fd, + 0xd3c0, 0xd3c1, 0x44be, 0xd567, 0x52fd, 0xd568, 0xd658, 0xd665, + 0xd659, 0xd65a, 0xd724, 0xd8cd, 0xd8ce, 0xd8cf, 0xd8d2, 0xda9f, + 0xda22, 0xdb7d, 0xdb7e, 0xdcff, 0xdd25, 0xdd00, 0xdd01, 0x483b, + 0xdd02, 0xdd03, 0xdd04, 0x5128, 0xdd05, 0xdd06, 0xdd07, 0xdd16, + 0xdd08, 0xdd17, 0xdd09, 0xdd0a, 0x4840, 0xdd0b, 0xdd0c, 0xdd29, + 0x483a, 0xdd0d, 0x52fd, 0xdd0e, 0xdd10, 0xdd11, 0xdd1d, 0xdd12, + 0xdd13, 0x52fd, 0xdd14, 0xdd15, 0xdf8d, 0xe054, 0xe055, 0xe056, + 0xe233, 0xe234, 0xe235, 0xe236, 0xe2fa, 0xe3e3, 0xe3e6, 0xe3ed, + 0xe3e7, 0xe3e8, 0xe3e9, 0xe3ea, 0xe3eb, 0xe527, 0xe520, 0xfbf8, + 0xe72a, 0xe7c9, 0x52fd, 0xe7ca, 0xe7cb, 0xe7d9, + /* 0x59 */ + 0xe7cc, 0xe7cd, 0xe7ce, 0x52fd, 0xe8e1, 0xea1b, 0xea1c, 0xea1d, + 0xea1e, 0xeb47, 0xebd1, 0xebc9, 0xedd0, 0xedd1, 0xee3f, 0xee40, + 0xee41, 0xfc09, 0xee42, 0xefc4, 0xf09b, 0xf092, 0xf093, 0x4c96, + 0xf094, 0xf095, 0x52fd, 0x52fd, 0xf2f3, 0xf2f4, 0xf2f5, 0xf2f6, + 0xf560, 0xf59e, 0xf5a0, 0xf5a1, 0xf61c, 0xf69f, 0x5356, 0x5712, + 0x571f, 0x5715, 0x5716, 0x5717, 0xfa0c, 0x5718, 0x57c2, 0x57c3, + 0x57c4, 0x58a1, 0x591b, 0x591c, 0x5971, 0x5b13, 0x5e17, 0x5e8f, + 0x635f, 0x6360, 0x63ac, 0x52fd, 0x52fd, 0x6361, 0x6362, 0x6363, + 0x6364, 0x6365, 0x52fd, 0x6799, 0x679a, 0x679b, 0x679c, 0x679d, + 0x679e, 0x679f, 0x67a0, 0x6bda, 0x6bdb, 0x6bdc, 0x6bdd, 0x6bde, + 0x6bdf, 0x6dd5, 0x6dd6, 0x6dd7, 0x6dd8, 0x6de0, 0x6eb4, 0x52fd, + 0x726e, 0x726f, 0x7270, 0x7463, 0x52fd, 0x75d5, + /* 0x5a */ + 0x75d6, 0x75d7, 0x75d8, 0x7730, 0x7bb5, 0x7bb6, 0x7bc1, 0x7bf7, + 0x05a0, 0x7bcb, 0x7be8, 0x52fd, 0x7be9, 0x7bb7, 0x7d15, 0x80e6, + 0x80e7, 0x80e8, 0x80e9, 0x80ea, 0x80eb, 0xfaca, 0x830b, 0x830c, + 0x8364, 0x85d4, 0x85d5, 0x85d6, 0x85d8, 0x86a5, 0x535b, 0x8a0f, + 0x8a10, 0x52fd, 0x8a11, 0x8a12, 0x8a13, 0x8a14, 0x8a15, 0x8a16, + 0x8a17, 0x8a18, 0x8a19, 0x8a1a, 0x8a2f, 0x8a1b, 0x8a1c, 0x8a3f, + 0x8a1d, 0x8a1e, 0x8a2c, 0x8a1f, 0x8c24, 0x8ca4, 0x8ca5, 0xb551, + 0x8dfe, 0x8f11, 0x8f12, 0x8f13, 0x8f54, 0x935e, 0x9321, 0x933f, + 0x9340, 0x9341, 0x9342, 0x9343, 0x9344, 0x9320, 0x9345, 0x52fd, + 0x9346, 0x93b0, 0x9347, 0x9357, 0x9301, 0x93b1, 0x935a, 0x9348, + 0x9704, 0x9705, 0x31f5, 0x974f, 0x9750, 0x9706, 0x9707, 0x9708, + 0x9709, 0x970a, 0x970b, 0x970c, 0x970d, 0x970e, + /* 0x5b */ + 0x970f, 0x9710, 0x9711, 0x9833, 0x9834, 0x9835, 0x98fc, 0x98fd, + 0x9bb0, 0x9bb1, 0x9bb2, 0x9bb3, 0x0b01, 0x9d7b, 0x9d7c, 0x9d7d, + 0x9d7e, 0x9d7f, 0x9d80, 0x9d81, 0x9d82, 0x9ef9, 0x9fda, 0xa1a1, + 0x52fd, 0x52fd, 0xa3ad, 0xa3ae, 0x52fd, 0xa5c8, 0xa5c9, 0xa5ca, + 0xa882, 0xa883, 0xa884, 0xa885, 0xa886, 0xa887, 0xa888, 0xa889, + 0xa88a, 0x52fd, 0xaa07, 0xaa08, 0xaa01, 0xaa09, 0xaa02, 0xaa0a, + 0xaa0b, 0xaa0c, 0xaba7, 0xab98, 0xab99, 0xab9a, 0xab9b, 0xab9c, + 0x3950, 0xab9d, 0xad1a, 0xadb2, 0xafb0, 0xafb1, 0x3b14, 0xafb2, + 0xafb3, 0xafb4, 0xafb5, 0xafb6, 0xafc0, 0xafb7, 0xafb8, 0xafb9, + 0xafba, 0xb01d, 0xb20c, 0xb20d, 0xb20e, 0xb235, 0xb20f, 0xb210, + 0xb211, 0xb212, 0xb422, 0xb423, 0xb424, 0x52fd, 0xb425, 0xb426, + 0xb427, 0xb428, 0xb429, 0xb42a, 0xb42b, 0xb42c, + /* 0x5c */ + 0xb42d, 0xb42e, 0xb552, 0xb553, 0xb619, 0xb6bf, 0xb78b, 0xb78c, + 0xb823, 0xb824, 0xb8f1, 0xb8d8, 0xfb7f, 0xbb4e, 0xbb4f, 0xbb55, + 0xbb50, 0xbb51, 0xbb52, 0xbb53, 0xbb02, 0xbb54, 0xbbf1, 0xbc24, + 0xbdd1, 0xc27c, 0xc27d, 0xc27e, 0xc27f, 0xc280, 0xc29f, 0xc281, + 0xc282, 0xc283, 0xc284, 0xc285, 0xc286, 0xc287, 0xc288, 0xc29b, + 0xc289, 0xc28a, 0xc28b, 0xc28c, 0x52fd, 0xc2a1, 0xc28d, 0xc28e, + 0xc4f3, 0xc4f4, 0xc4f5, 0xc724, 0xc725, 0xc726, 0xc727, 0xc728, + 0xc729, 0xc72a, 0x52fd, 0xc72b, 0xc8cd, 0xc901, 0x788d, 0xca70, + 0xcb80, 0xcb81, 0xcdc0, 0xcdc1, 0xcdc2, 0xcdc3, 0xcdc4, 0xcdc5, + 0xcdc6, 0xcdc7, 0xcdc8, 0xcffe, 0x52fd, 0xd0d9, 0xd0dc, 0xd0da, + 0xd175, 0xd258, 0xd259, 0xd25a, 0xd25b, 0xd25c, 0xd3ec, 0x131a, + 0xd3f3, 0xd572, 0xd573, 0xd682, 0xd683, 0xd72a, + /* 0x5d */ + 0xd72b, 0xd72c, 0xd72d, 0xd8f6, 0xd900, 0xd8f7, 0xd8f8, 0xd8f9, + 0x52fd, 0xdb94, 0xdb95, 0xdb96, 0xdc1b, 0xdd86, 0xdd4c, 0xdd4d, + 0xdd83, 0x52fd, 0xdd82, 0xdd4e, 0xdd4f, 0xdd50, 0xdd51, 0xdd81, + 0x4887, 0xdd52, 0xdd53, 0xdd54, 0xdd55, 0x52fd, 0xdd56, 0xdd57, + 0x4885, 0xdd58, 0xdd5b, 0xdd5c, 0xdd5d, 0xdd5e, 0xdd5f, 0xdd60, + 0xdd61, 0xdd7c, 0xdd62, 0x143c, 0x52fd, 0xdd63, 0xdd64, 0xe073, + 0xe245, 0xe246, 0xe247, 0xe24c, 0xe312, 0x52fd, 0xe313, 0xe439, + 0xe403, 0xe40d, 0xe530, 0xe5d5, 0xe6c0, 0xe7f2, 0xe7f3, 0xe7f4, + 0xe7f5, 0xe7f6, 0xe7f7, 0xe8fa, 0xe8fb, 0xea45, 0xea46, 0xeb49, + 0xebe7, 0xebe8, 0xedd8, 0xedd9, 0xee55, 0xee56, 0xee57, 0xefda, + 0xefdb, 0xefdc, 0xf0b8, 0xf0b9, 0xf0ba, 0x4cb1, 0xf0bb, 0xf289, + 0xf0bc, 0xf330, 0xf331, 0xf332, 0xf333, 0x52fd, + /* 0x5e */ + 0xf334, 0xf335, 0xf336, 0x4e47, 0xf337, 0xf5b2, 0xf690, 0xf626, + 0xf6a2, 0xf738, 0x52fd, 0x572e, 0x52fd, 0x572f, 0x5730, 0x572a, + 0x572b, 0x57c9, 0x5837, 0x5920, 0x5972, 0x5b1f, 0x5c65, 0x5cca, + 0x5dc0, 0x5dc1, 0x5dc2, 0x63b7, 0x63b8, 0x63b9, 0x63ba, 0x63bb, + 0x52fd, 0x52fd, 0x63bc, 0x63bd, 0x63be, 0x63f2, 0x67b5, 0x67b7, + 0x67b8, 0x63df, 0x67b9, 0x67d5, 0x67ba, 0x67bb, 0x684a, 0x6bf2, + 0x6bf3, 0x6bf4, 0x6bfa, 0x6bf5, 0x6c02, 0x6de2, 0x6de3, 0x728e, + 0x728b, 0x75e4, 0x75eb, 0x75e5, 0x7735, 0x7893, 0x7bea, 0x7beb, + 0x52fd, 0x7bec, 0x7bed, 0x7c17, 0x7bee, 0x7bef, 0x7bf0, 0x810e, + 0x810f, 0x8110, 0x8119, 0x8118, 0x8111, 0x8112, 0x8113, 0xfac7, + 0x8114, 0x8115, 0x066b, 0x8116, 0x8365, 0x85ea, 0x85eb, 0x85ec, + 0x85ed, 0x52fd, 0x85ee, 0x86ac, 0x8ac2, 0x8a69, + /* 0x5f */ + 0x8a81, 0x8a6a, 0x8a6b, 0x8a6c, 0x8a6d, 0x8a6e, 0x8a6f, 0x8a70, + 0x07f4, 0x8a71, 0x8a72, 0x8a73, 0x8a8c, 0x8a74, 0x8a75, 0x8a76, + 0x8f24, 0x8f2a, 0x938e, 0x93af, 0x938f, 0x9390, 0x9391, 0x52fd, + 0x9392, 0x9393, 0x9394, 0x9395, 0x9396, 0x9397, 0x9398, 0x9399, + 0x939a, 0x939b, 0x939c, 0x9739, 0x973b, 0x973a, 0x973c, 0x973d, + 0x973e, 0x973f, 0x9770, 0x9740, 0x9741, 0x9bc0, 0x9bc1, 0x9da4, + 0x9d97, 0x9da5, 0x9d98, 0x9d99, 0x9d9a, 0x52fd, 0x9d9b, 0x9da6, + 0x9d9c, 0x9d9d, 0x9d9e, 0x9d9f, 0xddce, 0x9dc8, 0x9da0, 0x9e19, + 0x9f0d, 0xa3bf, 0xa5e9, 0xa5ea, 0xa8a2, 0xa8a3, 0xa8a4, 0xa8a5, + 0xa8a6, 0xaa15, 0xaa17, 0xabbf, 0xabc0, 0xabc1, 0xabc2, 0xabc3, + 0xabc4, 0xabc5, 0x6c0d, 0xad23, 0xadbe, 0xb003, 0xb004, 0xb005, + 0xb006, 0xb007, 0xb008, 0xb009, 0xb00a, 0xb00b, + /* 0x60 */ + 0xb00c, 0xb020, 0xb00d, 0xb00e, 0xb00f, 0x52fd, 0xb226, 0xb227, + 0xb228, 0xb45d, 0xb45e, 0xb45f, 0xb460, 0xb461, 0xb462, 0xb463, + 0xb464, 0xb465, 0xb557, 0xb6cf, 0xb6d0, 0xb799, 0xb79a, 0xb8ea, + 0xb8eb, 0xb8ec, 0xbb7e, 0xbb7f, 0xbb80, 0x52fd, 0x52fd, 0xbb81, + 0xbb82, 0xbbf3, 0xbc25, 0xbc9f, 0xbca0, 0xbcf3, 0xbd00, 0xc2eb, + 0xc2ec, 0xc2ed, 0xc2ee, 0xc2ef, 0x52fd, 0x105c, 0xc2f0, 0xc2f1, + 0xc2f2, 0xc2f3, 0xc2f4, 0xc2f5, 0xc2f9, 0xc2fa, 0xc2fb, 0xc2fc, + 0xc2fd, 0xc2fe, 0xc2ff, 0xc300, 0xfbae, 0xc301, 0xc302, 0xc503, + 0xc786, 0xc779, 0x52fd, 0xc77a, 0xc77b, 0xc77c, 0xc784, 0xc77d, + 0xc77e, 0xc77f, 0xca86, 0xca87, 0xcb00, 0xcb01, 0xcb88, 0xcb89, + 0xcb8a, 0xcdf5, 0x52fd, 0xce25, 0xcdf6, 0xd0eb, 0xd0ec, 0xd0ed, + 0xd0ee, 0x1287, 0xd0ef, 0xd0f0, 0xd26c, 0xd421, + /* 0x61 */ + 0xd422, 0xd423, 0xd424, 0xd425, 0xd426, 0xd57b, 0xd57c, 0xd691, + 0xd692, 0xd693, 0xd90e, 0xd90f, 0xd910, 0xdbb3, 0xdc36, 0xddc6, + 0xdda1, 0xdda2, 0x48b9, 0xdda3, 0xddcc, 0xdda4, 0xdda5, 0xdda6, + 0xddcb, 0xdda7, 0x52fd, 0xdda8, 0xdda9, 0xddaa, 0x52fd, 0xddab, + 0xddac, 0xddad, 0x48bf, 0xddae, 0xddaf, 0xddb0, 0xe08c, 0xe08d, + 0xe08e, 0xfbf1, 0xe092, 0xe08f, 0xe252, 0xe253, 0xe254, 0xe255, + 0xe429, 0x52fd, 0xe5f3, 0xe5f4, 0xe80d, 0xe80e, 0xe80f, 0xe810, + 0xe914, 0xea71, 0xea72, 0xec0f, 0xec04, 0xec06, 0x52fd, 0xec07, + 0xeddc, 0xeddd, 0xee6d, 0xee79, 0xee6e, 0x52fd, 0xefec, 0xf0dd, + 0xf0de, 0xf0df, 0xf0e0, 0xf0e1, 0xf0e2, 0xf0e3, 0xf0e4, 0xf13a, + 0xf0e5, 0x4ccf, 0xf0e6, 0xf36b, 0xf36c, 0x974e, 0x4e64, 0xf5bd, + 0xf5be, 0xf5bf, 0xf634, 0x4fbf, 0xf812, 0x5740, + /* 0x62 */ + 0x5741, 0x6402, 0x6403, 0x6404, 0x6405, 0x6406, 0x67d7, 0x67cc, + 0x6998, 0x6c06, 0x6c07, 0x6caf, 0x6cb0, 0x6dea, 0x6df2, 0x72a2, + 0x72a3, 0x72a4, 0x7476, 0x75f5, 0x75f6, 0x75f7, 0x52fd, 0x7c3b, + 0x7c25, 0x7c3a, 0x7c3c, 0x7c3d, 0x7c3e, 0x8137, 0x8138, 0x8139, + 0x813a, 0x813b, 0x813c, 0x813d, 0x813e, 0x813f, 0x814b, 0x52fd, + 0x8140, 0x8322, 0x8367, 0x83d3, 0x85fa, 0x52fd, 0x8abc, 0x52fd, + 0x52fd, 0x8aa5, 0x0807, 0x8ab6, 0x52fd, 0x8aa6, 0x8abb, 0x8aa7, + 0x8aa8, 0x8aa9, 0x8aaa, 0x8aab, 0x8aac, 0x8abf, 0x8aad, 0x8aae, + 0x8aaf, 0x8c2e, 0x8e00, 0x939d, 0x939e, 0x93cb, 0x93cc, 0x93cd, + 0x93ce, 0x93cf, 0x52fd, 0x939f, 0x93d0, 0x93d1, 0x93d2, 0x93d3, + 0x93d4, 0x52fd, 0x52fd, 0x975d, 0x975e, 0x975f, 0x9760, 0x0b05, + 0x9dba, 0x9dbc, 0x0b06, 0x9db5, 0x9dbd, 0x9db6, + /* 0x63 */ + 0x9db7, 0x9db8, 0x9da8, 0xfb32, 0x9efe, 0x9efc, 0xa1e1, 0xa3c4, + 0xa3c5, 0xa614, 0xa8ae, 0xa8af, 0xa8b0, 0xa8b1, 0xa8b9, 0xabe7, + 0xb046, 0x52fd, 0xb047, 0xb048, 0xb049, 0xb01e, 0xb01f, 0xb04a, + 0xb04b, 0xb04c, 0xb04d, 0xb04e, 0x52fd, 0xb246, 0xb24b, 0xb490, + 0xb491, 0x52fd, 0xb492, 0xb493, 0xb494, 0xb55b, 0xb8f2, 0xb8f8, + 0xb8f9, 0xbb94, 0xbba4, 0xbb97, 0xbb98, 0xbc29, 0xbcae, 0xbdaf, + 0xc359, 0xc35a, 0x52fd, 0xc35b, 0xc35c, 0xc35d, 0xc35e, 0xc35f, + 0xc360, 0xc361, 0xc2aa, 0xc362, 0xc363, 0xc364, 0xc365, 0xc366, + 0xc367, 0xc368, 0xc369, 0xc36a, 0xc36b, 0xc36c, 0xc36d, 0xc36e, + 0xc36f, 0x52fd, 0xc7b2, 0xc7b3, 0xc7b4, 0x10f9, 0xc7b5, 0xc7b6, + 0xc7b7, 0xc7b8, 0xc7b9, 0xc7ba, 0xc7bb, 0xca88, 0x42b8, 0xce19, + 0xce1a, 0xce1b, 0xcf16, 0xd10c, 0xd10d, 0xd10e, + /* 0x64 */ + 0xd10f, 0x52fd, 0xd283, 0xd284, 0xd285, 0xd583, 0xd584, 0xd6b0, + 0x52fd, 0xd926, 0xd927, 0xd936, 0xd928, 0xd929, 0x52fd, 0x52fd, + 0xdde7, 0xdde8, 0xdde9, 0x1453, 0xddea, 0xddeb, 0x52fd, 0xddec, + 0xdded, 0xddee, 0xddef, 0xddf0, 0xddf1, 0xde0c, 0xddf2, 0xddf3, + 0xddf4, 0xddf5, 0xddf6, 0xddf7, 0xddf8, 0xe0a3, 0xe0a4, 0xe0a5, + 0xe0a6, 0xe0a7, 0x52fd, 0xe25c, 0x52fd, 0xe44b, 0xe4e1, 0xe615, + 0x52fd, 0xe616, 0xe617, 0xe82c, 0xe82d, 0xe922, 0xe923, 0xea96, + 0xea97, 0x52fd, 0xec2e, 0xec30, 0xec31, 0x52fd, 0xeddf, 0xee8b, + 0xee8c, 0x52fd, 0xee8d, 0xeffc, 0xeffd, 0xeffe, 0xefff, 0xf117, + 0xf12d, 0xf118, 0x4cf3, 0xf119, 0x52fd, 0xf112, 0xf11a, 0xf11b, + 0xf11c, 0x1669, 0x52fd, 0xf397, 0x16e5, 0xf398, 0xf399, 0x52fd, + 0xf6c4, 0x574f, 0x57cd, 0x5dc7, 0x641c, 0x641d, + /* 0x65 */ + 0x641e, 0x67e7, 0x67e9, 0x67ea, 0x67eb, 0x6c15, 0x6ff1, 0x6ff2, + 0x72b6, 0x78a0, 0x7c4a, 0x7d20, 0x8160, 0x8161, 0x8141, 0x8162, + 0x8603, 0x8604, 0x8ad9, 0x8ada, 0x8adb, 0x8adc, 0x8add, 0x52fd, + 0x8ade, 0x8adf, 0x8ae0, 0x8ae1, 0x8ae2, 0x0812, 0x8ae3, 0x52fd, + 0x8f31, 0x9405, 0x9406, 0x9407, 0x9772, 0x978a, 0x978b, 0x9788, + 0x52fd, 0x978c, 0x978d, 0x978e, 0x978f, 0x9790, 0x9842, 0x9843, + 0x52fd, 0x9dc1, 0x9dc2, 0x9dc3, 0x9dc4, 0xa3cb, 0xa622, 0x52fd, + 0x52fd, 0xa8c3, 0xa8c4, 0xa8c5, 0xa8c6, 0xaa1e, 0xaa25, 0xabf3, + 0xabf4, 0x52fd, 0xabf5, 0xad38, 0xad48, 0xadca, 0x3b4f, 0xb07a, + 0xb07b, 0xb255, 0xb256, 0xb4b1, 0xb4b2, 0xb4b3, 0x52fd, 0xb4b4, + 0xb4b5, 0xb7a4, 0xb900, 0xb901, 0xb902, 0xbbac, 0x52fd, 0xbcb3, + 0xc3b6, 0xc3b7, 0xc3b8, 0xc3b9, 0xc3ba, 0xc3bb, + /* 0x66 */ + 0xc3bc, 0xc3bd, 0xc3be, 0xc3bf, 0xc3c0, 0xc3c1, 0xc3c2, 0xc3c3, + 0xc3c4, 0xc3c5, 0xc3c6, 0xc3c7, 0xc7e3, 0xc7e4, 0xc7e5, 0xc7e6, + 0xc7e7, 0x52fd, 0xcab5, 0xcaa1, 0xcb95, 0xce3b, 0xce3c, 0xce3d, + 0xce3e, 0xcf14, 0xd120, 0xd121, 0xd122, 0xd123, 0xd124, 0xd296, + 0xd297, 0xd298, 0xd494, 0xd495, 0xd496, 0xd497, 0xd498, 0xd58f, + 0xd590, 0xd6bc, 0xd73b, 0xd93d, 0x52fd, 0xdbdf, 0xdc1e, 0xde23, + 0xde24, 0xde49, 0xde25, 0xde26, 0xde27, 0xde28, 0x4925, 0xde29, + 0xde2a, 0xde2e, 0xde2f, 0xde4e, 0xde30, 0xfbeb, 0xde31, 0xde32, + 0xde33, 0xde34, 0xde35, 0xde36, 0x52fd, 0xde37, 0xde50, 0xde38, + 0x52fd, 0xde39, 0xde3a, 0xde3b, 0xde3c, 0xde3d, 0xde3e, 0xe0b8, + 0xe0b9, 0xe262, 0xe263, 0xe341, 0xe46d, 0x52fd, 0xe652, 0xe637, + 0xe6db, 0xe83f, 0xe934, 0xeb5b, 0xec46, 0xec5a, + /* 0x67 */ + 0xec5b, 0xede1, 0xede2, 0xede3, 0xede4, 0xeea7, 0xeea8, 0xeea9, + 0xf00f, 0xf02b, 0xf156, 0xf157, 0xf158, 0xf15e, 0xf159, 0xf15a, + 0xf15b, 0xf15c, 0x52fd, 0xf168, 0x52fd, 0xf42c, 0xf3e2, 0xf3f3, + 0xf5d2, 0xf656, 0xf6ce, 0xf761, 0xf99b, 0xf9b4, 0x575c, 0xfa10, + 0x57d2, 0x5871, 0x5973, 0x5b2c, 0x5e94, 0x52fd, 0x643f, 0x6440, + 0x67f9, 0x67fa, 0x67fd, 0x67fb, 0x6c1c, 0x6c1d, 0x6dff, 0x6e00, + 0x6ff7, 0x9ffe, 0x52fd, 0x77b6, 0x7c54, 0x8177, 0x8179, 0x817a, + 0x817b, 0x8369, 0x8b02, 0x8b03, 0x8b04, 0x8b05, 0x8b06, 0x8b07, + 0x8b08, 0x8b09, 0x8b0a, 0x8b0b, 0x8b35, 0x52fd, 0x8f39, 0x941e, + 0x941f, 0x9420, 0x9421, 0x52fd, 0x9422, 0x9423, 0x9424, 0x942c, + 0x97b3, 0x97b5, 0x97b6, 0x97b7, 0x97b8, 0x9dd0, 0x9ffa, 0xa207, + 0xa2bd, 0xa3d7, 0xa3d2, 0xa8db, 0xa8d6, 0x575d, + /* 0x68 */ + 0xad43, 0xadcf, 0xb0a3, 0xb0a4, 0xb0a5, 0xb0a6, 0xb0a7, 0xb0a8, + 0xb0a9, 0xb25d, 0xb25e, 0xb4c9, 0xb4ca, 0xb4cb, 0xb4cc, 0xb906, + 0xb907, 0x52fd, 0xbbc5, 0xbbf5, 0xbcb4, 0xbcb8, 0xbcb5, 0xc3fd, + 0x1077, 0xc3fe, 0xc3ff, 0xc400, 0xc401, 0xc402, 0xc403, 0xc409, + 0xc404, 0xc405, 0xc406, 0xc407, 0xc811, 0xc812, 0xc813, 0xc814, + 0xc815, 0x4277, 0xcb98, 0xcb99, 0xd13c, 0xd12d, 0xd12e, 0x52fd, + 0xd4bb, 0xd4bc, 0x1378, 0xd73d, 0xd947, 0xd948, 0xd949, 0xd94a, + 0xdae1, 0xdae7, 0xdbeb, 0xdc20, 0xdc38, 0xde62, 0xde67, 0xde68, + 0xde69, 0xde6a, 0xde6b, 0xde6d, 0xde6e, 0xde6f, 0xde70, 0xde71, + 0xde72, 0xde8f, 0xde73, 0xde74, 0xde75, 0xde76, 0xde77, 0xe0c9, + 0xe0ca, 0x4ae6, 0xe0cb, 0xe0cc, 0xe0cd, 0xe351, 0x52fd, 0x52fd, + 0xe545, 0xe859, 0xe85a, 0xe85b, 0xe940, 0xeacf, + /* 0x69 */ + 0xeb5e, 0xec7b, 0xed93, 0xeebc, 0xf016, 0xf030, 0x52fd, 0xf18d, + 0xf18e, 0x4d2f, 0xf18f, 0xf190, 0xf191, 0xf192, 0xf193, 0xf194, + 0xf195, 0xf196, 0xf423, 0xf414, 0xf5db, 0xf70a, 0xf8ce, 0x5766, + 0x5768, 0x5767, 0x57d3, 0x6463, 0x6804, 0x699e, 0x6c26, 0x6c2a, + 0x7c6c, 0x7c64, 0x818f, 0x8190, 0x8334, 0x860e, 0x8b25, 0x8b26, + 0x8b27, 0x52fd, 0x8b28, 0x2c0c, 0x52fd, 0x8b29, 0x8b2a, 0x8b2b, + 0x8b2c, 0x8f3e, 0x9442, 0x9443, 0x9433, 0x97c1, 0x97c2, 0x97c3, + 0x9dd6, 0x9dd7, 0xa8e1, 0xa8e2, 0xaa2b, 0xadd1, 0xb0cc, 0xb0cd, + 0xb0ce, 0xb0cf, 0xb4de, 0xb4df, 0xb4e0, 0xb4e1, 0xbbf6, 0xc42c, + 0x52fd, 0xc454, 0xc42d, 0xc42e, 0xc841, 0xc842, 0xcac7, 0xcba0, + 0xcba1, 0xce70, 0xce71, 0xce72, 0x52fd, 0xd134, 0xd135, 0xd136, + 0xd2a6, 0xd4cc, 0x52fd, 0xd599, 0xdbf4, 0xde9b, + /* 0x6a */ + 0xde9e, 0xde9f, 0xdea0, 0xdea1, 0xdea2, 0xdea3, 0xdea4, 0xdea5, + 0xdea6, 0xdea7, 0xdea8, 0xe0db, 0xe0dc, 0xe0dd, 0xe0d7, 0xe0de, + 0xe0df, 0xe359, 0xe746, 0xe865, 0xe949, 0x52fd, 0xeadd, 0xec95, + 0xec96, 0xec97, 0xeed4, 0xeed6, 0xf026, 0x4d47, 0x1688, 0xf1c8, + 0xf1c5, 0xf1c6, 0xf1c7, 0xf451, 0xf452, 0xf453, 0xf454, 0xf455, + 0xf5de, 0x52fd, 0x576d, 0x57d5, 0x6472, 0x74ae, 0x760f, 0x7c6b, + 0x7c6d, 0x7c6e, 0x7c78, 0x8198, 0x8199, 0x819a, 0x8b44, 0x8b5c, + 0x8b45, 0x8e01, 0x9458, 0x9459, 0x945a, 0x52fd, 0x97d9, 0x97d6, + 0x9dda, 0x9ddf, 0x9ddb, 0xa003, 0xa8ef, 0x3836, 0xaa33, 0xadd2, + 0xb0e1, 0xb26f, 0xb564, 0xb90e, 0xc450, 0xc451, 0xc452, 0xc856, + 0xc857, 0xc858, 0x52fd, 0xce81, 0xce82, 0xcf1d, 0xcf1e, 0xd143, + 0xd2aa, 0xdbfd, 0x52fd, 0xdec6, 0xdec7, 0xded9, + /* 0x6b */ + 0xded7, 0x52fd, 0xdec8, 0xdec9, 0xdeca, 0xdecb, 0xdeda, 0x52fd, + 0xdecc, 0xdecd, 0xdece, 0xdecf, 0xded0, 0xded1, 0xdebc, 0xe0e1, + 0xe0e2, 0xe0e3, 0xe4a9, 0xe54e, 0xe877, 0x52fd, 0x52fd, 0xecac, + 0xecad, 0xedb6, 0xeee5, 0xf1f8, 0xf1ea, 0xf28d, 0xf1eb, 0xf495, + 0x576e, 0x57d8, 0x6483, 0x69a3, 0x6c30, 0x6e0f, 0x7c79, 0x7c7a, + 0x81a7, 0x81a8, 0x81a9, 0x81aa, 0x8619, 0x8b50, 0x8b51, 0x8b52, + 0x2c15, 0x8b68, 0x8b53, 0x8b54, 0x9be2, 0x9ddc, 0xac15, 0xac16, + 0xad4f, 0xb0f5, 0xb0f6, 0xb0f7, 0xb4f4, 0xb7cc, 0xb90f, 0xc466, + 0xc467, 0x52fd, 0xc468, 0xcba4, 0xce8b, 0xce8c, 0xd4fa, 0xdee6, + 0xdeed, 0xdeee, 0xdeef, 0xdef0, 0xdefe, 0xe0e7, 0xe0e8, 0xe4b3, + 0xe4e4, 0xe883, 0xedec, 0x52fd, 0xf216, 0x52fd, 0x52fd, 0xf217, + 0xf4c3, 0xf4ac, 0xf5ed, 0x52fd, 0x52fd, 0xf8b4, + /* 0x6c */ + 0x52fd, 0x648a, 0x648b, 0x6c34, 0x6e14, 0x72df, 0x77bb, 0x7c7f, + 0x7c81, 0x81ad, 0x81ae, 0x8b62, 0x8b6e, 0x52fd, 0x946e, 0x52fd, + 0x9a17, 0x9de6, 0x9f10, 0xac19, 0x52fd, 0xb910, 0xbdf2, 0xc476, + 0xc477, 0xce95, 0xce96, 0xdf00, 0xdf01, 0xdf31, 0xfbed, 0xdf1c, + 0xe36d, 0xeef4, 0xeef5, 0xf03d, 0xf232, 0xf233, 0xf5f4, 0x52fd, + 0x5773, 0x6c37, 0x52fd, 0x8b71, 0xb10f, 0x52fd, 0xb10e, 0xb911, + 0xc485, 0xdf14, 0xdf15, 0xdf16, 0xdf17, 0xdf18, 0xdf19, 0xdf1a, + 0xe4c3, 0xf242, 0xf243, 0xf244, 0xf248, 0xf4fb, 0x69a5, 0x6cb8, + 0x81b2, 0x833d, 0x8b72, 0x97e7, 0x97e8, 0xa659, 0xaa3a, 0xb114, + 0xb4ff, 0xbcc0, 0xc48d, 0x1084, 0xc48e, 0x52fd, 0xdf22, 0x52fd, + 0x52fd, 0xef04, 0xef29, 0xf251, 0xf266, 0xf50e, 0xfc13, 0x52fd, + 0x649b, 0x649c, 0x7616, 0x7c86, 0x7c87, 0x52fd, + /* 0x6d */ + 0xdf2c, 0xdf30, 0xdf28, 0xe95f, 0x52fd, 0x947e, 0xb119, 0xd50a, + 0xdf36, 0xe0fc, 0xf26d, 0xf26e, 0xf9c6, 0x1ab5, 0x8b7b, 0xb506, + 0xc89f, 0xf532, 0xd50d, 0x7c8b, 0xdf3b, 0x52fd, 0xf53d, 0xdf3c, + 0xdf3d, +}; + +static const ucs4_t cns11643_15_2uni_upages[253] = { + 0x03400, 0x03500, 0x03600, 0x03700, 0x03800, 0x03900, 0x03a00, 0x03b00, + 0x03c00, 0x03d00, 0x03e00, 0x03f00, 0x04000, 0x04100, 0x04300, 0x04400, + 0x04500, 0x04600, 0x04700, 0x04800, 0x04900, 0x04a00, 0x04c00, 0x04f00, + 0x05100, 0x05200, 0x05300, 0x05400, 0x05500, 0x05600, 0x05700, 0x05800, + 0x05a00, 0x05b00, 0x05c00, 0x05e00, 0x05f00, 0x06200, 0x06500, 0x06600, + 0x06700, 0x06800, 0x06900, 0x06a00, 0x06b00, 0x06c00, 0x06e00, 0x06f00, + 0x07000, 0x07100, 0x07300, 0x07400, 0x07500, 0x07600, 0x07700, 0x07800, + 0x07900, 0x07a00, 0x07b00, 0x07c00, 0x07d00, 0x07f00, 0x08200, 0x08300, + 0x08600, 0x08700, 0x08900, 0x08a00, 0x08e00, 0x08f00, 0x09000, 0x09200, + 0x09300, 0x09400, 0x09500, 0x09600, 0x09b00, 0x09c00, 0x09d00, 0x09e00, + 0x09f00, 0x0fa00, 0x0ff00, 0x20000, 0x20100, 0x20200, 0x20300, 0x20400, + 0x20500, 0x20600, 0x20700, 0x20800, 0x20900, 0x20a00, 0x20b00, 0x20c00, + 0x20d00, 0x20e00, 0x20f00, 0x21000, 0x21100, 0x21200, 0x21300, 0x21400, + 0x21500, 0x21600, 0x21700, 0x21800, 0x21900, 0x21a00, 0x21b00, 0x21c00, + 0x21d00, 0x21e00, 0x21f00, 0x22000, 0x22100, 0x22200, 0x22300, 0x22400, + 0x22500, 0x22600, 0x22700, 0x22800, 0x22900, 0x22a00, 0x22b00, 0x22c00, + 0x22d00, 0x22e00, 0x22f00, 0x23000, 0x23100, 0x23200, 0x23300, 0x23400, + 0x23500, 0x23600, 0x23700, 0x23800, 0x23900, 0x23a00, 0x23b00, 0x23c00, + 0x23d00, 0x23e00, 0x23f00, 0x24000, 0x24100, 0x24200, 0x24300, 0x24400, + 0x24500, 0x24600, 0x24700, 0x24800, 0x24900, 0x24a00, 0x24b00, 0x24c00, + 0x24d00, 0x24e00, 0x24f00, 0x25000, 0x25100, 0x25200, 0x25300, 0x25400, + 0x25500, 0x25600, 0x25700, 0x25800, 0x25900, 0x25a00, 0x25b00, 0x25c00, + 0x25d00, 0x25e00, 0x25f00, 0x26000, 0x26100, 0x26200, 0x26300, 0x26400, + 0x26500, 0x26600, 0x26700, 0x26800, 0x26900, 0x26a00, 0x26b00, 0x26c00, + 0x26d00, 0x26e00, 0x26f00, 0x27000, 0x27100, 0x27200, 0x27300, 0x27400, + 0x27500, 0x27600, 0x27700, 0x27800, 0x27900, 0x27a00, 0x27b00, 0x27c00, + 0x27d00, 0x27e00, 0x27f00, 0x28000, 0x28100, 0x28200, 0x28300, 0x28400, + 0x28500, 0x28600, 0x28700, 0x28800, 0x28900, 0x28a00, 0x28b00, 0x28c00, + 0x28d00, 0x28e00, 0x28f00, 0x29000, 0x29100, 0x29200, 0x29300, 0x29400, + 0x29500, 0x29600, 0x29700, 0x29800, 0x29900, 0x29a00, 0x29b00, 0x29c00, + 0x29d00, 0x29e00, 0x29f00, 0x2a000, 0x2a100, 0x2a200, 0x2a300, 0x2a400, + 0x2a500, 0x2a600, 0x2f800, 0x2f900, 0x2fa00, +}; + +static int +cns11643_15_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x21 && c1 <= 0x6d)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + ucs4_t wc = 0xfffd; + unsigned short swc; + { + if (i < 7169) + swc = cns11643_15_2uni_page21[i], + wc = cns11643_15_2uni_upages[swc>>8] | (swc & 0xff); + } + if (wc != 0xfffd) { + *pwc = wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + diff --git a/libs/libiconv/lib/cns11643_2.h b/libs/libiconv/lib/cns11643_2.h new file mode 100644 index 00000000..7a73c60f --- /dev/null +++ b/libs/libiconv/lib/cns11643_2.h @@ -0,0 +1,1112 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CNS 11643-1992 plane 2 + */ + +static const unsigned short cns11643_2_2uni_page21[7650] = { + /* 0x21 */ + 0x4e42, 0x4e5c, 0x51f5, 0x531a, 0x5382, 0x4e07, 0x4e0c, 0x4e47, + 0x4e8d, 0x56d7, 0x5c6e, 0x5f73, 0x4e0f, 0x5187, 0x4e0e, 0x4e2e, + 0x4e93, 0x4ec2, 0x4ec9, 0x4ec8, 0x5198, 0x52fc, 0x536c, 0x53b9, + 0x5720, 0x5903, 0x592c, 0x5c10, 0x5dff, 0x65e1, 0x6bb3, 0x6bcc, + 0x6c14, 0x723f, 0x4e31, 0x4e3c, 0x4ee8, 0x4edc, 0x4ee9, 0x4ee1, + 0x4edd, 0x4eda, 0x520c, 0x5209, 0x531c, 0x534c, 0x5722, 0x5723, + 0x5917, 0x592f, 0x5b81, 0x5b84, 0x5c12, 0x5c3b, 0x5c74, 0x5c73, + 0x5e04, 0x5e80, 0x5e82, 0x5fc9, 0x6209, 0x6250, 0x6c15, 0x6c36, + 0x6c43, 0x6c3f, 0x6c3b, 0x72ae, 0x72b0, 0x738a, 0x79b8, 0x808a, + 0x961e, 0x4f0e, 0x4f18, 0x4f2c, 0x4ef5, 0x4f14, 0x4ef1, 0x4f00, + 0x4ef7, 0x4f08, 0x4f1d, 0x4f02, 0x4f05, 0x4f22, 0x4f13, 0x4f04, + 0x4ef4, 0x4f12, 0x51b1, 0x5213, 0x5210, 0x52a6, + /* 0x22 */ + 0x5322, 0x531f, 0x534d, 0x538a, 0x5407, 0x56e1, 0x56df, 0x572e, + 0x572a, 0x5734, 0x593c, 0x5980, 0x597c, 0x5985, 0x597b, 0x597e, + 0x5977, 0x597f, 0x5b56, 0x5c15, 0x5c25, 0x5c7c, 0x5c7a, 0x5c7b, + 0x5c7e, 0x5ddf, 0x5e75, 0x5e84, 0x5f02, 0x5f1a, 0x5f74, 0x5fd5, + 0x5fd4, 0x5fcf, 0x625c, 0x625e, 0x6264, 0x6261, 0x6266, 0x6262, + 0x6259, 0x6260, 0x625a, 0x6265, 0x6537, 0x65ef, 0x65ee, 0x673e, + 0x6739, 0x6738, 0x673b, 0x673a, 0x673f, 0x673c, 0x6733, 0x6c18, + 0x6c46, 0x6c52, 0x6c5c, 0x6c4f, 0x6c4a, 0x6c54, 0x6c4b, 0x6c4c, + 0x7071, 0x725e, 0x72b4, 0x72b5, 0x738e, 0x752a, 0x767f, 0x7a75, + 0x7f51, 0x8278, 0x827c, 0x8280, 0x827d, 0x827f, 0x864d, 0x897e, + 0x9099, 0x9097, 0x9098, 0x909b, 0x9094, 0x9622, 0x9624, 0x9620, + 0x9623, 0x4f56, 0x4f3b, 0x4f62, 0x4f49, 0x4f53, + /* 0x23 */ + 0x4f64, 0x4f3e, 0x4f67, 0x4f52, 0x4f5f, 0x4f41, 0x4f58, 0x4f2d, + 0x4f33, 0x4f3f, 0x4f61, 0x518f, 0x51b9, 0x521c, 0x521e, 0x5221, + 0x52ad, 0x52ae, 0x5309, 0x5363, 0x5372, 0x538e, 0x538f, 0x5430, + 0x5437, 0x542a, 0x5454, 0x5445, 0x5419, 0x541c, 0x5425, 0x5418, + 0x543d, 0x544f, 0x5441, 0x5428, 0x5424, 0x5447, 0x56ee, 0x56e7, + 0x56e5, 0x5741, 0x5745, 0x574c, 0x5749, 0x574b, 0x5752, 0x5906, + 0x5940, 0x59a6, 0x5998, 0x59a0, 0x5997, 0x598e, 0x59a2, 0x5990, + 0x598f, 0x59a7, 0x59a1, 0x5b8e, 0x5b92, 0x5c28, 0x5c2a, 0x5c8d, + 0x5c8f, 0x5c88, 0x5c8b, 0x5c89, 0x5c92, 0x5c8a, 0x5c86, 0x5c93, + 0x5c95, 0x5de0, 0x5e0a, 0x5e0e, 0x5e8b, 0x5e89, 0x5e8c, 0x5e88, + 0x5e8d, 0x5f05, 0x5f1d, 0x5f78, 0x5f76, 0x5fd2, 0x5fd1, 0x5fd0, + 0x5fed, 0x5fe8, 0x5fee, 0x5ff3, 0x5fe1, 0x5fe4, + /* 0x24 */ + 0x5fe3, 0x5ffa, 0x5fef, 0x5ff7, 0x5ffb, 0x6000, 0x5ff4, 0x623a, + 0x6283, 0x628c, 0x628e, 0x628f, 0x6294, 0x6287, 0x6271, 0x627b, + 0x627a, 0x6270, 0x6281, 0x6288, 0x6277, 0x627d, 0x6272, 0x6274, + 0x65f0, 0x65f4, 0x65f3, 0x65f2, 0x65f5, 0x6745, 0x6747, 0x6759, + 0x6755, 0x674c, 0x6748, 0x675d, 0x674d, 0x675a, 0x674b, 0x6bd0, + 0x6c19, 0x6c1a, 0x6c78, 0x6c67, 0x6c6b, 0x6c84, 0x6c8b, 0x6c8f, + 0x6c71, 0x6c6f, 0x6c69, 0x6c9a, 0x6c6d, 0x6c87, 0x6c95, 0x6c9c, + 0x6c66, 0x6c73, 0x6c65, 0x6c7b, 0x6c8e, 0x7074, 0x707a, 0x7263, + 0x72bf, 0x72bd, 0x72c3, 0x72c6, 0x72c1, 0x72ba, 0x72c5, 0x7395, + 0x7397, 0x7393, 0x7394, 0x7392, 0x753a, 0x7539, 0x7594, 0x7595, + 0x7681, 0x793d, 0x8034, 0x8095, 0x8099, 0x8090, 0x8092, 0x809c, + 0x8290, 0x828f, 0x8285, 0x828e, 0x8291, 0x8293, + /* 0x25 */ + 0x828a, 0x8283, 0x8284, 0x8c78, 0x8fc9, 0x8fbf, 0x909f, 0x90a1, + 0x90a5, 0x909e, 0x90a7, 0x90a0, 0x9630, 0x9628, 0x962f, 0x962d, + 0x4e33, 0x4f98, 0x4f7c, 0x4f85, 0x4f7d, 0x4f80, 0x4f87, 0x4f76, + 0x4f74, 0x4f89, 0x4f84, 0x4f77, 0x4f4c, 0x4f97, 0x4f6a, 0x4f9a, + 0x4f79, 0x4f81, 0x4f78, 0x4f90, 0x4f9c, 0x4f94, 0x4f9e, 0x4f92, + 0x4f82, 0x4f95, 0x4f6b, 0x4f6e, 0x519e, 0x51bc, 0x51be, 0x5235, + 0x5232, 0x5233, 0x5246, 0x5231, 0x52bc, 0x530a, 0x530b, 0x533c, + 0x5392, 0x5394, 0x5487, 0x547f, 0x5481, 0x5491, 0x5482, 0x5488, + 0x546b, 0x547a, 0x547e, 0x5465, 0x546c, 0x5474, 0x5466, 0x548d, + 0x546f, 0x5461, 0x5460, 0x5498, 0x5463, 0x5467, 0x5464, 0x56f7, + 0x56f9, 0x576f, 0x5772, 0x576d, 0x576b, 0x5771, 0x5770, 0x5776, + 0x5780, 0x5775, 0x577b, 0x5773, 0x5774, 0x5762, + /* 0x26 */ + 0x5768, 0x577d, 0x590c, 0x5945, 0x59b5, 0x59ba, 0x59cf, 0x59ce, + 0x59b2, 0x59cc, 0x59c1, 0x59b6, 0x59bc, 0x59c3, 0x59d6, 0x59b1, + 0x59bd, 0x59c0, 0x59c8, 0x59b4, 0x59c7, 0x5b62, 0x5b65, 0x5b93, + 0x5b95, 0x5c44, 0x5c47, 0x5cae, 0x5ca4, 0x5ca0, 0x5cb5, 0x5caf, + 0x5ca8, 0x5cac, 0x5c9f, 0x5ca3, 0x5cad, 0x5ca2, 0x5caa, 0x5ca7, + 0x5c9d, 0x5ca5, 0x5cb6, 0x5cb0, 0x5ca6, 0x5e17, 0x5e14, 0x5e19, + 0x5f28, 0x5f22, 0x5f23, 0x5f24, 0x5f54, 0x5f82, 0x5f7e, 0x5f7d, + 0x5fde, 0x5fe5, 0x602d, 0x6026, 0x6019, 0x6032, 0x600b, 0x6034, + 0x600a, 0x6017, 0x6033, 0x601a, 0x601e, 0x602c, 0x6022, 0x600d, + 0x6010, 0x602e, 0x6013, 0x6011, 0x600c, 0x6009, 0x601c, 0x6214, + 0x623d, 0x62ad, 0x62b4, 0x62d1, 0x62be, 0x62aa, 0x62b6, 0x62ca, + 0x62ae, 0x62b3, 0x62af, 0x62bb, 0x62a9, 0x62b0, + /* 0x27 */ + 0x62b8, 0x653d, 0x65a8, 0x65bb, 0x6609, 0x65fc, 0x6604, 0x6612, + 0x6608, 0x65fb, 0x6603, 0x660b, 0x660d, 0x6605, 0x65fd, 0x6611, + 0x6610, 0x66f6, 0x670a, 0x6785, 0x676c, 0x678e, 0x6792, 0x6776, + 0x677b, 0x6798, 0x6786, 0x6784, 0x6774, 0x678d, 0x678c, 0x677a, + 0x679f, 0x6791, 0x6799, 0x6783, 0x677d, 0x6781, 0x6778, 0x6779, + 0x6794, 0x6b25, 0x6b80, 0x6b7e, 0x6bde, 0x6c1d, 0x6c93, 0x6cec, + 0x6ceb, 0x6cee, 0x6cd9, 0x6cb6, 0x6cd4, 0x6cad, 0x6ce7, 0x6cb7, + 0x6cd0, 0x6cc2, 0x6cba, 0x6cc3, 0x6cc6, 0x6ced, 0x6cf2, 0x6cd2, + 0x6cdd, 0x6cb4, 0x6c8a, 0x6c9d, 0x6c80, 0x6cde, 0x6cc0, 0x6d30, + 0x6ccd, 0x6cc7, 0x6cb0, 0x6cf9, 0x6ccf, 0x6ce9, 0x6cd1, 0x7094, + 0x7098, 0x7085, 0x7093, 0x7086, 0x7084, 0x7091, 0x7096, 0x7082, + 0x709a, 0x7083, 0x726a, 0x72d6, 0x72cb, 0x72d8, + /* 0x28 */ + 0x72c9, 0x72dc, 0x72d2, 0x72d4, 0x72da, 0x72cc, 0x72d1, 0x73a4, + 0x73a1, 0x73ad, 0x73a6, 0x73a2, 0x73a0, 0x73ac, 0x739d, 0x74dd, + 0x74e8, 0x753f, 0x7540, 0x753e, 0x758c, 0x7598, 0x76af, 0x76f3, + 0x76f1, 0x76f0, 0x76f5, 0x77f8, 0x77fc, 0x77f9, 0x77fb, 0x77fa, + 0x77f7, 0x7942, 0x793f, 0x79c5, 0x7a78, 0x7a7b, 0x7afb, 0x7c75, + 0x7cfd, 0x8035, 0x808f, 0x80ae, 0x80a3, 0x80b8, 0x80b5, 0x80ad, + 0x8220, 0x82a0, 0x82c0, 0x82ab, 0x829a, 0x8298, 0x829b, 0x82b5, + 0x82a7, 0x82ae, 0x82bc, 0x829e, 0x82ba, 0x82b4, 0x82a8, 0x82a1, + 0x82a9, 0x82c2, 0x82a4, 0x82c3, 0x82b6, 0x82a2, 0x8670, 0x866f, + 0x866d, 0x866e, 0x8c56, 0x8fd2, 0x8fcb, 0x8fd3, 0x8fcd, 0x8fd6, + 0x8fd5, 0x8fd7, 0x90b2, 0x90b4, 0x90af, 0x90b3, 0x90b0, 0x9639, + 0x963d, 0x963c, 0x963a, 0x9643, 0x4fcd, 0x4fc5, + /* 0x29 */ + 0x4fd3, 0x4fb2, 0x4fc9, 0x4fcb, 0x4fc1, 0x4fd4, 0x4fdc, 0x4fd9, + 0x4fbb, 0x4fb3, 0x4fdb, 0x4fc7, 0x4fd6, 0x4fba, 0x4fc0, 0x4fb9, + 0x4fec, 0x5244, 0x5249, 0x52c0, 0x52c2, 0x533d, 0x537c, 0x5397, + 0x5396, 0x5399, 0x5398, 0x54ba, 0x54a1, 0x54ad, 0x54a5, 0x54cf, + 0x54c3, 0x830d, 0x54b7, 0x54ae, 0x54d6, 0x54b6, 0x54c5, 0x54c6, + 0x54a0, 0x5470, 0x54bc, 0x54a2, 0x54be, 0x5472, 0x54de, 0x54b0, + 0x57b5, 0x579e, 0x579f, 0x57a4, 0x578c, 0x5797, 0x579d, 0x579b, + 0x5794, 0x5798, 0x578f, 0x5799, 0x57a5, 0x579a, 0x5795, 0x58f4, + 0x590d, 0x5953, 0x59e1, 0x59de, 0x59ee, 0x5a00, 0x59f1, 0x59dd, + 0x59fa, 0x59fd, 0x59fc, 0x59f6, 0x59e4, 0x59f2, 0x59f7, 0x59db, + 0x59e9, 0x59f3, 0x59f5, 0x59e0, 0x59fe, 0x59f4, 0x59ed, 0x5ba8, + 0x5c4c, 0x5cd0, 0x5cd8, 0x5ccc, 0x5cd7, 0x5ccb, + /* 0x2a */ + 0x5cdb, 0x5cde, 0x5cda, 0x5cc9, 0x5cc7, 0x5cca, 0x5cd6, 0x5cd3, + 0x5cd4, 0x5ccf, 0x5cc8, 0x5cc6, 0x5cce, 0x5cdf, 0x5cf8, 0x5df9, + 0x5e21, 0x5e22, 0x5e23, 0x5e20, 0x5e24, 0x5eb0, 0x5ea4, 0x5ea2, + 0x5e9b, 0x5ea3, 0x5ea5, 0x5f07, 0x5f2e, 0x5f56, 0x5f86, 0x6037, + 0x6039, 0x6054, 0x6072, 0x605e, 0x6045, 0x6053, 0x6047, 0x6049, + 0x605b, 0x604c, 0x6040, 0x6042, 0x605f, 0x6024, 0x6044, 0x6058, + 0x6066, 0x606e, 0x6242, 0x6243, 0x62cf, 0x630d, 0x630b, 0x62f5, + 0x630e, 0x6303, 0x62eb, 0x62f9, 0x630f, 0x630c, 0x62f8, 0x62f6, + 0x6300, 0x6313, 0x6314, 0x62fa, 0x6315, 0x62fb, 0x62f0, 0x6541, + 0x6543, 0x65aa, 0x65bf, 0x6636, 0x6621, 0x6632, 0x6635, 0x661c, + 0x6626, 0x6622, 0x6633, 0x662b, 0x663a, 0x661d, 0x6634, 0x6639, + 0x662e, 0x670f, 0x6710, 0x67c1, 0x67f2, 0x67c8, + /* 0x2b */ + 0x67ba, 0x67dc, 0x67bb, 0x67f8, 0x67d8, 0x67c0, 0x67b7, 0x67c5, + 0x67eb, 0x67e4, 0x67df, 0x67b5, 0x67cd, 0x67b3, 0x67f7, 0x67f6, + 0x67ee, 0x67e3, 0x67c2, 0x67b9, 0x67ce, 0x67e7, 0x67f0, 0x67b2, + 0x67fc, 0x67c6, 0x67ed, 0x67cc, 0x67ae, 0x67e6, 0x67db, 0x67fa, + 0x67c9, 0x67ca, 0x67c3, 0x67ea, 0x67cb, 0x6b28, 0x6b82, 0x6b84, + 0x6bb6, 0x6bd6, 0x6bd8, 0x6be0, 0x6c20, 0x6c21, 0x6d28, 0x6d34, + 0x6d2d, 0x6d1f, 0x6d3c, 0x6d3f, 0x6d12, 0x6d0a, 0x6cda, 0x6d33, + 0x6d04, 0x6d19, 0x6d3a, 0x6d1a, 0x6d11, 0x6d00, 0x6d1d, 0x6d42, + 0x6d01, 0x6d18, 0x6d37, 0x6d03, 0x6d0f, 0x6d40, 0x6d07, 0x6d20, + 0x6d2c, 0x6d08, 0x6d22, 0x6d09, 0x6d10, 0x70b7, 0x709f, 0x70be, + 0x70b1, 0x70b0, 0x70a1, 0x70b4, 0x70b5, 0x70a9, 0x7241, 0x7249, + 0x724a, 0x726c, 0x7270, 0x7273, 0x726e, 0x72ca, + /* 0x2c */ + 0x72e4, 0x72e8, 0x72eb, 0x72df, 0x72ea, 0x72e6, 0x72e3, 0x7385, + 0x73cc, 0x73c2, 0x73c8, 0x73c5, 0x73b9, 0x73b6, 0x73b5, 0x73b4, + 0x73eb, 0x73bf, 0x73c7, 0x73be, 0x73c3, 0x73c6, 0x73b8, 0x73cb, + 0x74ec, 0x74ee, 0x752e, 0x7547, 0x7548, 0x75a7, 0x75aa, 0x7679, + 0x76c4, 0x7708, 0x7703, 0x7704, 0x7705, 0x770a, 0x76f7, 0x76fb, + 0x76fa, 0x77e7, 0x77e8, 0x7806, 0x7811, 0x7812, 0x7805, 0x7810, + 0x780f, 0x780e, 0x7809, 0x7803, 0x7813, 0x794a, 0x794c, 0x794b, + 0x7945, 0x7944, 0x79d5, 0x79cd, 0x79cf, 0x79d6, 0x79ce, 0x7a80, + 0x7a7e, 0x7ad1, 0x7b00, 0x7b01, 0x7c7a, 0x7c78, 0x7c79, 0x7c7f, + 0x7c80, 0x7c81, 0x7d03, 0x7d08, 0x7d01, 0x7f58, 0x7f91, 0x7f8d, + 0x7fbe, 0x8007, 0x800e, 0x800f, 0x8014, 0x8037, 0x80d8, 0x80c7, + 0x80e0, 0x80d1, 0x80c8, 0x80c2, 0x80d0, 0x80c5, + /* 0x2d */ + 0x80e3, 0x80d9, 0x80dc, 0x80ca, 0x80d5, 0x80c9, 0x80cf, 0x80d7, + 0x80e6, 0x80cd, 0x81ff, 0x8221, 0x8294, 0x82d9, 0x82fe, 0x82f9, + 0x8307, 0x82e8, 0x8300, 0x82d5, 0x833a, 0x82eb, 0x82d6, 0x82f4, + 0x82ec, 0x82e1, 0x82f2, 0x82f5, 0x830c, 0x82fb, 0x82f6, 0x82f0, + 0x82ea, 0x82e4, 0x82e0, 0x82fa, 0x82f3, 0x82ed, 0x8677, 0x8674, + 0x867c, 0x8673, 0x8841, 0x884e, 0x8867, 0x886a, 0x8869, 0x89d3, + 0x8a04, 0x8a07, 0x8d72, 0x8fe3, 0x8fe1, 0x8fee, 0x8fe0, 0x90f1, + 0x90bd, 0x90bf, 0x90d5, 0x90c5, 0x90be, 0x90c7, 0x90cb, 0x90c8, + 0x91d4, 0x91d3, 0x9654, 0x964f, 0x9651, 0x9653, 0x964a, 0x964e, + 0x501e, 0x5005, 0x5007, 0x5013, 0x5022, 0x5030, 0x501b, 0x4ff5, + 0x4ff4, 0x5033, 0x5037, 0x502c, 0x4ff6, 0x4ff7, 0x5017, 0x501c, + 0x5020, 0x5027, 0x5035, 0x502f, 0x5031, 0x500e, + /* 0x2e */ + 0x515a, 0x5194, 0x5193, 0x51ca, 0x51c4, 0x51c5, 0x51c8, 0x51ce, + 0x5261, 0x525a, 0x5252, 0x525e, 0x525f, 0x5255, 0x5262, 0x52cd, + 0x530e, 0x539e, 0x5526, 0x54e2, 0x5517, 0x5512, 0x54e7, 0x54f3, + 0x54e4, 0x551a, 0x54ff, 0x5504, 0x5508, 0x54eb, 0x5511, 0x5505, + 0x54f1, 0x550a, 0x54fb, 0x54f7, 0x54f8, 0x54e0, 0x550e, 0x5503, + 0x550b, 0x5701, 0x5702, 0x57cc, 0x5832, 0x57d5, 0x57d2, 0x57ba, + 0x57c6, 0x57bd, 0x57bc, 0x57b8, 0x57b6, 0x57bf, 0x57c7, 0x57d0, + 0x57b9, 0x57c1, 0x590e, 0x594a, 0x5a19, 0x5a16, 0x5a2d, 0x5a2e, + 0x5a15, 0x5a0f, 0x5a17, 0x5a0a, 0x5a1e, 0x5a33, 0x5b6c, 0x5ba7, + 0x5bad, 0x5bac, 0x5c03, 0x5c56, 0x5c54, 0x5cec, 0x5cff, 0x5cee, + 0x5cf1, 0x5cf7, 0x5d00, 0x5cf9, 0x5e29, 0x5e28, 0x5ea8, 0x5eae, + 0x5eaa, 0x5eac, 0x5f33, 0x5f30, 0x5f67, 0x605d, + /* 0x2f */ + 0x605a, 0x6067, 0x6041, 0x60a2, 0x6088, 0x6080, 0x6092, 0x6081, + 0x609d, 0x6083, 0x6095, 0x609b, 0x6097, 0x6087, 0x609c, 0x608e, + 0x6219, 0x6246, 0x62f2, 0x6310, 0x6356, 0x632c, 0x6344, 0x6345, + 0x6336, 0x6343, 0x63e4, 0x6339, 0x634b, 0x634a, 0x633c, 0x6329, + 0x6341, 0x6334, 0x6358, 0x6354, 0x6359, 0x632d, 0x6347, 0x6333, + 0x635a, 0x6351, 0x6338, 0x6357, 0x6340, 0x6348, 0x654a, 0x6546, + 0x65c6, 0x65c3, 0x65c4, 0x65c2, 0x664a, 0x665f, 0x6647, 0x6651, + 0x6712, 0x6713, 0x681f, 0x681a, 0x6849, 0x6832, 0x6833, 0x683b, + 0x684b, 0x684f, 0x6816, 0x6831, 0x681c, 0x6835, 0x682b, 0x682d, + 0x682f, 0x684e, 0x6844, 0x6834, 0x681d, 0x6812, 0x6814, 0x6826, + 0x6828, 0x682e, 0x684d, 0x683a, 0x6825, 0x6820, 0x6b2c, 0x6b2f, + 0x6b2d, 0x6b31, 0x6b34, 0x6b6d, 0x8082, 0x6b88, + /* 0x30 */ + 0x6be6, 0x6be4, 0x6be8, 0x6be3, 0x6be2, 0x6be7, 0x6c25, 0x6d7a, + 0x6d63, 0x6d64, 0x6d76, 0x6d0d, 0x6d61, 0x6d92, 0x6d58, 0x6d62, + 0x6d6d, 0x6d6f, 0x6d91, 0x6d8d, 0x6def, 0x6d7f, 0x6d86, 0x6d5e, + 0x6d67, 0x6d60, 0x6d97, 0x6d70, 0x6d7c, 0x6d5f, 0x6d82, 0x6d98, + 0x6d2f, 0x6d68, 0x6d8b, 0x6d7e, 0x6d80, 0x6d84, 0x6d16, 0x6d83, + 0x6d7b, 0x6d7d, 0x6d75, 0x6d90, 0x70dc, 0x70d3, 0x70d1, 0x70dd, + 0x70cb, 0x7f39, 0x70e2, 0x70d7, 0x70d2, 0x70de, 0x70e0, 0x70d4, + 0x70cd, 0x70c5, 0x70c6, 0x70c7, 0x70da, 0x70ce, 0x70e1, 0x7242, + 0x7278, 0x7277, 0x7276, 0x7300, 0x72fa, 0x72f4, 0x72fe, 0x72f6, + 0x72f3, 0x72fb, 0x7301, 0x73d3, 0x73d9, 0x73e5, 0x73d6, 0x73bc, + 0x73e7, 0x73e3, 0x73e9, 0x73dc, 0x73d2, 0x73db, 0x73d4, 0x73dd, + 0x73da, 0x73d7, 0x73d8, 0x73e8, 0x74de, 0x74df, + /* 0x31 */ + 0x74f4, 0x74f5, 0x7521, 0x755b, 0x755f, 0x75b0, 0x75c1, 0x75bb, + 0x75c4, 0x75c0, 0x75bf, 0x75b6, 0x75ba, 0x768a, 0x76c9, 0x771d, + 0x771b, 0x7710, 0x7713, 0x7712, 0x7723, 0x7711, 0x7715, 0x7719, + 0x771a, 0x7722, 0x7727, 0x7823, 0x782c, 0x7822, 0x7835, 0x782f, + 0x7828, 0x782e, 0x782b, 0x7821, 0x7829, 0x7833, 0x782a, 0x7831, + 0x7954, 0x795b, 0x794f, 0x795c, 0x7953, 0x7952, 0x7951, 0x79eb, + 0x79ec, 0x79e0, 0x79ee, 0x79ed, 0x79ea, 0x79dc, 0x79de, 0x79dd, + 0x7a86, 0x7a89, 0x7a85, 0x7a8b, 0x7a8c, 0x7a8a, 0x7a87, 0x7ad8, + 0x7b10, 0x7b04, 0x7b13, 0x7b05, 0x7b0f, 0x7b08, 0x7b0a, 0x7b0e, + 0x7b09, 0x7b12, 0x7c84, 0x7c91, 0x7c8a, 0x7c8c, 0x7c88, 0x7c8d, + 0x7c85, 0x7d1e, 0x7d1d, 0x7d11, 0x7d0e, 0x7d18, 0x7d16, 0x7d13, + 0x7d1f, 0x7d12, 0x7d0f, 0x7d0c, 0x7f5c, 0x7f61, + /* 0x32 */ + 0x7f5e, 0x7f60, 0x7f5d, 0x7f5b, 0x7f96, 0x7f92, 0x7fc3, 0x7fc2, + 0x7fc0, 0x8016, 0x803e, 0x8039, 0x80fa, 0x80f2, 0x80f9, 0x80f5, + 0x8101, 0x80fb, 0x8100, 0x8201, 0x822f, 0x8225, 0x8333, 0x832d, + 0x8344, 0x8319, 0x8351, 0x8325, 0x8356, 0x833f, 0x8341, 0x8326, + 0x831c, 0x8322, 0x8342, 0x834e, 0x831b, 0x832a, 0x8308, 0x833c, + 0x834d, 0x8316, 0x8324, 0x8320, 0x8337, 0x832f, 0x8329, 0x8347, + 0x8345, 0x834c, 0x8353, 0x831e, 0x832c, 0x834b, 0x8327, 0x8348, + 0x8653, 0x8652, 0x86a2, 0x86a8, 0x8696, 0x868d, 0x8691, 0x869e, + 0x8687, 0x8697, 0x8686, 0x868b, 0x869a, 0x8685, 0x86a5, 0x8699, + 0x86a1, 0x86a7, 0x8695, 0x8698, 0x868e, 0x869d, 0x8690, 0x8694, + 0x8843, 0x8844, 0x886d, 0x8875, 0x8876, 0x8872, 0x8880, 0x8871, + 0x887f, 0x886f, 0x8883, 0x887e, 0x8874, 0x887c, + /* 0x33 */ + 0x8a12, 0x8c47, 0x8c57, 0x8c7b, 0x8ca4, 0x8ca3, 0x8d76, 0x8d78, + 0x8db5, 0x8db7, 0x8db6, 0x8ed1, 0x8ed3, 0x8ffe, 0x8ff5, 0x9002, + 0x8fff, 0x8ffb, 0x9004, 0x8ffc, 0x8ff6, 0x90d6, 0x90e0, 0x90d9, + 0x90da, 0x90e3, 0x90df, 0x90e5, 0x90d8, 0x90db, 0x90d7, 0x90dc, + 0x90e4, 0x9150, 0x914e, 0x914f, 0x91d5, 0x91e2, 0x91da, 0x965c, + 0x965f, 0x96bc, 0x98e3, 0x9adf, 0x9b2f, 0x4e7f, 0x5070, 0x506a, + 0x5061, 0x505e, 0x5060, 0x5053, 0x504b, 0x505d, 0x5072, 0x5048, + 0x504d, 0x5041, 0x505b, 0x504a, 0x5062, 0x5015, 0x5045, 0x505f, + 0x5069, 0x506b, 0x5063, 0x5064, 0x5046, 0x5040, 0x506e, 0x5073, + 0x5057, 0x5051, 0x51d0, 0x526b, 0x526d, 0x526c, 0x526e, 0x52d6, + 0x52d3, 0x532d, 0x539c, 0x5575, 0x5576, 0x553c, 0x554d, 0x5550, + 0x5534, 0x552a, 0x5551, 0x5562, 0x5536, 0x5535, + /* 0x34 */ + 0x5530, 0x5552, 0x5545, 0x550c, 0x5532, 0x5565, 0x554e, 0x5539, + 0x5548, 0x552d, 0x553b, 0x5540, 0x554b, 0x570a, 0x5707, 0x57fb, + 0x5814, 0x57e2, 0x57f6, 0x57dc, 0x57f4, 0x5800, 0x57ed, 0x57fd, + 0x5808, 0x57f8, 0x580b, 0x57f3, 0x57cf, 0x5807, 0x57ee, 0x57e3, + 0x57f2, 0x57e5, 0x57ec, 0x57e1, 0x580e, 0x57fc, 0x5810, 0x57e7, + 0x5801, 0x580c, 0x57f1, 0x57e9, 0x57f0, 0x580d, 0x5804, 0x595c, + 0x5a60, 0x5a58, 0x5a55, 0x5a67, 0x5a5e, 0x5a38, 0x5a35, 0x5a6d, + 0x5a50, 0x5a5f, 0x5a65, 0x5a6c, 0x5a53, 0x5a64, 0x5a57, 0x5a43, + 0x5a5d, 0x5a52, 0x5a44, 0x5a5b, 0x5a48, 0x5a8e, 0x5a3e, 0x5a4d, + 0x5a39, 0x5a4c, 0x5a70, 0x5a69, 0x5a47, 0x5a51, 0x5a56, 0x5a42, + 0x5a5c, 0x5b72, 0x5b6e, 0x5bc1, 0x5bc0, 0x5c59, 0x5d1e, 0x5d0b, + 0x5d1d, 0x5d1a, 0x5d20, 0x5d0c, 0x5d28, 0x5d0d, + /* 0x35 */ + 0x5d26, 0x5d25, 0x5d0f, 0x5d30, 0x5d12, 0x5d23, 0x5d1f, 0x5d2e, + 0x5e3e, 0x5e34, 0x5eb1, 0x5eb4, 0x5eb9, 0x5eb2, 0x5eb3, 0x5f36, + 0x5f38, 0x5f9b, 0x5f96, 0x5f9f, 0x608a, 0x6090, 0x6086, 0x60be, + 0x60b0, 0x60ba, 0x60d3, 0x60d4, 0x60cf, 0x60e4, 0x60d9, 0x60dd, + 0x60c8, 0x60b1, 0x60db, 0x60b7, 0x60ca, 0x60bf, 0x60c3, 0x60cd, + 0x60c0, 0x6332, 0x6365, 0x638a, 0x6382, 0x637d, 0x63bd, 0x639e, + 0x63ad, 0x639d, 0x6397, 0x63ab, 0x638e, 0x636f, 0x6387, 0x6390, + 0x636e, 0x63af, 0x6375, 0x639c, 0x636d, 0x63ae, 0x637c, 0x63a4, + 0x633b, 0x639f, 0x6378, 0x6385, 0x6381, 0x6391, 0x638d, 0x6370, + 0x6553, 0x65cd, 0x6665, 0x6661, 0x665b, 0x6659, 0x665c, 0x6662, + 0x6718, 0x6879, 0x6887, 0x6890, 0x689c, 0x686d, 0x686e, 0x68ae, + 0x68ab, 0x6956, 0x686f, 0x68a3, 0x68ac, 0x68a9, + /* 0x36 */ + 0x6875, 0x6874, 0x68b2, 0x688f, 0x6877, 0x6892, 0x687c, 0x686b, + 0x6872, 0x68aa, 0x6880, 0x6871, 0x687e, 0x689b, 0x6896, 0x688b, + 0x68a0, 0x6889, 0x68a4, 0x6878, 0x687b, 0x6891, 0x688c, 0x688a, + 0x687d, 0x6b36, 0x6b33, 0x6b37, 0x6b38, 0x6b91, 0x6b8f, 0x6b8d, + 0x6b8e, 0x6b8c, 0x6c2a, 0x6dc0, 0x6dab, 0x6db4, 0x6db3, 0x6e74, + 0x6dac, 0x6de9, 0x6de2, 0x6db7, 0x6df6, 0x6dd4, 0x6e00, 0x6dc8, + 0x6de0, 0x6ddf, 0x6dd6, 0x6dbe, 0x6de5, 0x6ddc, 0x6ddd, 0x6ddb, + 0x6df4, 0x6dca, 0x6dbd, 0x6ded, 0x6df0, 0x6dba, 0x6dd5, 0x6dc2, + 0x6dcf, 0x6dc9, 0x6dd0, 0x6df2, 0x6dd3, 0x6dfd, 0x6dd7, 0x6dcd, + 0x6de3, 0x6dbb, 0x70fa, 0x710d, 0x70f7, 0x7117, 0x70f4, 0x710c, + 0x70f0, 0x7104, 0x70f3, 0x7110, 0x70fc, 0x70ff, 0x7106, 0x7113, + 0x7100, 0x70f8, 0x70f6, 0x710b, 0x7102, 0x710e, + /* 0x37 */ + 0x727e, 0x727b, 0x727c, 0x727f, 0x731d, 0x7317, 0x7307, 0x7311, + 0x7318, 0x730a, 0x7308, 0x72ff, 0x730f, 0x731e, 0x7388, 0x73f6, + 0x73f8, 0x73f5, 0x7404, 0x7401, 0x73fd, 0x7407, 0x7400, 0x73fa, + 0x73fc, 0x73ff, 0x740c, 0x740b, 0x73f4, 0x7408, 0x7564, 0x7563, + 0x75ce, 0x75d2, 0x75cf, 0x75cb, 0x75cc, 0x75d1, 0x75d0, 0x768f, + 0x7689, 0x76d3, 0x7739, 0x772f, 0x772d, 0x7731, 0x7732, 0x7734, + 0x7733, 0x773d, 0x7725, 0x773b, 0x7735, 0x7848, 0x7852, 0x7849, + 0x784d, 0x784a, 0x784c, 0x7826, 0x7845, 0x7850, 0x7964, 0x7967, + 0x7969, 0x796a, 0x7963, 0x796b, 0x7961, 0x79bb, 0x79fa, 0x79f8, + 0x79f6, 0x79f7, 0x7a8f, 0x7a94, 0x7a90, 0x7b35, 0x7b3b, 0x7b34, + 0x7b25, 0x7b30, 0x7b22, 0x7b24, 0x7b33, 0x7b18, 0x7b2a, 0x7b1d, + 0x7b31, 0x7b2b, 0x7b2d, 0x7b2f, 0x7b32, 0x7b38, + /* 0x38 */ + 0x7b1a, 0x7b23, 0x7c94, 0x7c98, 0x7c96, 0x7ca3, 0x7d35, 0x7d3d, + 0x7d38, 0x7d36, 0x7d3a, 0x7d45, 0x7d2c, 0x7d29, 0x7d41, 0x7d47, + 0x7d3e, 0x7d3f, 0x7d4a, 0x7d3b, 0x7d28, 0x7f63, 0x7f95, 0x7f9c, + 0x7f9d, 0x7f9b, 0x7fca, 0x7fcb, 0x7fcd, 0x7fd0, 0x7fd1, 0x7fc7, + 0x7fcf, 0x7fc9, 0x801f, 0x801e, 0x801b, 0x8047, 0x8043, 0x8048, + 0x8118, 0x8125, 0x8119, 0x811b, 0x812d, 0x811f, 0x812c, 0x811e, + 0x8121, 0x8115, 0x8127, 0x811d, 0x8122, 0x8211, 0x8238, 0x8233, + 0x823a, 0x8234, 0x8232, 0x8274, 0x8390, 0x83a3, 0x83a8, 0x838d, + 0x837a, 0x8373, 0x83a4, 0x8374, 0x838f, 0x8381, 0x8395, 0x8399, + 0x8375, 0x8394, 0x83a9, 0x837d, 0x8383, 0x838c, 0x839d, 0x839b, + 0x83aa, 0x838b, 0x837e, 0x83a5, 0x83af, 0x8388, 0x8397, 0x83b0, + 0x837f, 0x83a6, 0x8387, 0x83ae, 0x8376, 0x8659, + /* 0x39 */ + 0x8656, 0x86bf, 0x86b7, 0x86c2, 0x86c1, 0x86c5, 0x86ba, 0x86b0, + 0x86c8, 0x86b9, 0x86b3, 0x86b8, 0x86cc, 0x86b4, 0x86bb, 0x86bc, + 0x86c3, 0x86bd, 0x86be, 0x8852, 0x8889, 0x8895, 0x88a8, 0x88a2, + 0x88aa, 0x889a, 0x8891, 0x88a1, 0x889f, 0x8898, 0x88a7, 0x8899, + 0x889b, 0x8897, 0x88a4, 0x88ac, 0x888c, 0x8893, 0x888e, 0x8982, + 0x89d6, 0x89d9, 0x89d5, 0x8a30, 0x8a27, 0x8a2c, 0x8a1e, 0x8c39, + 0x8c3b, 0x8c5c, 0x8c5d, 0x8c7d, 0x8ca5, 0x8d7d, 0x8d7b, 0x8d79, + 0x8dbc, 0x8dc2, 0x8db9, 0x8dbf, 0x8dc1, 0x8ed8, 0x8ede, 0x8edd, + 0x8edc, 0x8ed7, 0x8ee0, 0x8ee1, 0x9024, 0x900b, 0x9011, 0x901c, + 0x900c, 0x9021, 0x90ef, 0x90ea, 0x90f0, 0x90f4, 0x90f2, 0x90f3, + 0x90d4, 0x90eb, 0x90ec, 0x90e9, 0x9156, 0x9158, 0x915a, 0x9153, + 0x9155, 0x91ec, 0x91f4, 0x91f1, 0x91f3, 0x91f8, + /* 0x3a */ + 0x91e4, 0x91f9, 0x91ea, 0x91eb, 0x91f7, 0x91e8, 0x91ee, 0x957a, + 0x9586, 0x9588, 0x967c, 0x966d, 0x966b, 0x9671, 0x966f, 0x96bf, + 0x976a, 0x9804, 0x98e5, 0x9997, 0x509b, 0x5095, 0x5094, 0x509e, + 0x508b, 0x50a3, 0x5083, 0x508c, 0x508e, 0x509d, 0x5068, 0x509c, + 0x5092, 0x5082, 0x5087, 0x515f, 0x51d4, 0x5312, 0x5311, 0x53a4, + 0x53a7, 0x5591, 0x55a8, 0x55a5, 0x55ad, 0x5577, 0x5645, 0x55a2, + 0x5593, 0x5588, 0x558f, 0x55b5, 0x5581, 0x55a3, 0x5592, 0x55a4, + 0x557d, 0x558c, 0x55a6, 0x557f, 0x5595, 0x55a1, 0x558e, 0x570c, + 0x5829, 0x5837, 0x5819, 0x581e, 0x5827, 0x5823, 0x5828, 0x57f5, + 0x5848, 0x5825, 0x581c, 0x581b, 0x5833, 0x583f, 0x5836, 0x582e, + 0x5839, 0x5838, 0x582d, 0x582c, 0x583b, 0x5961, 0x5aaf, 0x5a94, + 0x5a9f, 0x5a7a, 0x5aa2, 0x5a9e, 0x5a78, 0x5aa6, + /* 0x3b */ + 0x5a7c, 0x5aa5, 0x5aac, 0x5a95, 0x5aae, 0x5a37, 0x5a84, 0x5a8a, + 0x5a97, 0x5a83, 0x5a8b, 0x5aa9, 0x5a7b, 0x5a7d, 0x5a8c, 0x5a9c, + 0x5a8f, 0x5a93, 0x5a9d, 0x5bea, 0x5bcd, 0x5bcb, 0x5bd4, 0x5bd1, + 0x5bca, 0x5bce, 0x5c0c, 0x5c30, 0x5d37, 0x5d43, 0x5d6b, 0x5d41, + 0x5d4b, 0x5d3f, 0x5d35, 0x5d51, 0x5d4e, 0x5d55, 0x5d33, 0x5d3a, + 0x5d52, 0x5d3d, 0x5d31, 0x5d59, 0x5d42, 0x5d39, 0x5d49, 0x5d38, + 0x5d3c, 0x5d32, 0x5d36, 0x5d40, 0x5d45, 0x5e44, 0x5e41, 0x5f58, + 0x5fa6, 0x5fa5, 0x5fab, 0x60c9, 0x60b9, 0x60cc, 0x60e2, 0x60ce, + 0x60c4, 0x6114, 0x60f2, 0x610a, 0x6116, 0x6105, 0x60f5, 0x6113, + 0x60f8, 0x60fc, 0x60fe, 0x60c1, 0x6103, 0x6118, 0x611d, 0x6110, + 0x60ff, 0x6104, 0x610b, 0x624a, 0x6394, 0x63b1, 0x63b0, 0x63ce, + 0x63e5, 0x63e8, 0x63ef, 0x63c3, 0x649d, 0x63f3, + /* 0x3c */ + 0x63ca, 0x63e0, 0x63f6, 0x63d5, 0x63f2, 0x63f5, 0x6461, 0x63df, + 0x63be, 0x63dd, 0x63dc, 0x63c4, 0x63d8, 0x63d3, 0x63c2, 0x63c7, + 0x63cc, 0x63cb, 0x63c8, 0x63f0, 0x63d7, 0x63d9, 0x6532, 0x6567, + 0x656a, 0x6564, 0x655c, 0x6568, 0x6565, 0x658c, 0x659d, 0x659e, + 0x65ae, 0x65d0, 0x65d2, 0x667c, 0x666c, 0x667b, 0x6680, 0x6671, + 0x6679, 0x666a, 0x6672, 0x6701, 0x690c, 0x68d3, 0x6904, 0x68dc, + 0x692a, 0x68ec, 0x68ea, 0x68f1, 0x690f, 0x68d6, 0x68f7, 0x68eb, + 0x68e4, 0x68f6, 0x6913, 0x6910, 0x68f3, 0x68e1, 0x6907, 0x68cc, + 0x6908, 0x6970, 0x68b4, 0x6911, 0x68ef, 0x68c6, 0x6914, 0x68f8, + 0x68d0, 0x68fd, 0x68fc, 0x68e8, 0x690b, 0x690a, 0x6917, 0x68ce, + 0x68c8, 0x68dd, 0x68de, 0x68e6, 0x68f4, 0x68d1, 0x6906, 0x68d4, + 0x68e9, 0x6915, 0x6925, 0x68c7, 0x6b39, 0x6b3b, + /* 0x3d */ + 0x6b3f, 0x6b3c, 0x6b94, 0x6b97, 0x6b99, 0x6b95, 0x6bbd, 0x6bf0, + 0x6bf2, 0x6bf3, 0x6c30, 0x6dfc, 0x6e46, 0x6e47, 0x6e1f, 0x6e49, + 0x6e88, 0x6e3c, 0x6e3d, 0x6e45, 0x6e62, 0x6e2b, 0x6e3f, 0x6e41, + 0x6e5d, 0x6e73, 0x6e1c, 0x6e33, 0x6e4b, 0x6e40, 0x6e51, 0x6e3b, + 0x6e03, 0x6e2e, 0x6e5e, 0x6e68, 0x6e5c, 0x6e61, 0x6e31, 0x6e28, + 0x6e60, 0x6e71, 0x6e6b, 0x6e39, 0x6e22, 0x6e30, 0x6e53, 0x6e65, + 0x6e27, 0x6e78, 0x6e64, 0x6e77, 0x6e55, 0x6e79, 0x6e52, 0x6e66, + 0x6e35, 0x6e36, 0x6e5a, 0x7120, 0x711e, 0x712f, 0x70fb, 0x712e, + 0x7131, 0x7123, 0x7125, 0x7122, 0x7132, 0x711f, 0x7128, 0x713a, + 0x711b, 0x724b, 0x725a, 0x7288, 0x7289, 0x7286, 0x7285, 0x728b, + 0x7312, 0x730b, 0x7330, 0x7322, 0x7331, 0x7333, 0x7327, 0x7332, + 0x732d, 0x7326, 0x7323, 0x7335, 0x730c, 0x742e, + /* 0x3e */ + 0x742c, 0x7430, 0x742b, 0x7416, 0x741a, 0x7421, 0x742d, 0x7431, + 0x7424, 0x7423, 0x741d, 0x7429, 0x7420, 0x7432, 0x74fb, 0x752f, + 0x756f, 0x756c, 0x75e7, 0x75da, 0x75e1, 0x75e6, 0x75dd, 0x75df, + 0x75e4, 0x75d7, 0x7695, 0x7692, 0x76da, 0x7746, 0x7747, 0x7744, + 0x774d, 0x7745, 0x774a, 0x774e, 0x774b, 0x774c, 0x77de, 0x77ec, + 0x7860, 0x7864, 0x7865, 0x785c, 0x786d, 0x7871, 0x786a, 0x786e, + 0x7870, 0x7869, 0x7868, 0x785e, 0x7862, 0x7974, 0x7973, 0x7972, + 0x7970, 0x7a02, 0x7a0a, 0x7a03, 0x7a0c, 0x7a04, 0x7a99, 0x7ae6, + 0x7ae4, 0x7b4a, 0x7b47, 0x7b44, 0x7b48, 0x7b4c, 0x7b4e, 0x7b40, + 0x7b58, 0x7b45, 0x7ca2, 0x7c9e, 0x7ca8, 0x7ca1, 0x7d58, 0x7d6f, + 0x7d63, 0x7d53, 0x7d56, 0x7d67, 0x7d6a, 0x7d4f, 0x7d6d, 0x7d5c, + 0x7d6b, 0x7d52, 0x7d54, 0x7d69, 0x7d51, 0x7d5f, + /* 0x3f */ + 0x7d4e, 0x7f3e, 0x7f3f, 0x7f65, 0x7f66, 0x7fa2, 0x7fa0, 0x7fa1, + 0x7fd7, 0x8051, 0x804f, 0x8050, 0x80fe, 0x80d4, 0x8143, 0x814a, + 0x8152, 0x814f, 0x8147, 0x813d, 0x814d, 0x813a, 0x81e6, 0x81ee, + 0x81f7, 0x81f8, 0x81f9, 0x8204, 0x823c, 0x823d, 0x823f, 0x8275, + 0x833b, 0x83cf, 0x83f9, 0x8423, 0x83c0, 0x83e8, 0x8412, 0x83e7, + 0x83e4, 0x83fc, 0x83f6, 0x8410, 0x83c6, 0x83c8, 0x83eb, 0x83e3, + 0x83bf, 0x8401, 0x83dd, 0x83e5, 0x83d8, 0x83ff, 0x83e1, 0x83cb, + 0x83ce, 0x83d6, 0x83f5, 0x83c9, 0x8409, 0x840f, 0x83de, 0x8411, + 0x8406, 0x83c2, 0x83f3, 0x83d5, 0x83fa, 0x83c7, 0x83d1, 0x83ea, + 0x8413, 0x839a, 0x83c3, 0x83ec, 0x83ee, 0x83c4, 0x83fb, 0x83d7, + 0x83e2, 0x841b, 0x83db, 0x83fe, 0x86d8, 0x86e2, 0x86e6, 0x86d3, + 0x86e3, 0x86da, 0x86ea, 0x86dd, 0x86eb, 0x86dc, + /* 0x40 */ + 0x86ec, 0x86e9, 0x86d7, 0x86e8, 0x86d1, 0x8848, 0x8856, 0x8855, + 0x88ba, 0x88d7, 0x88b9, 0x88b8, 0x88c0, 0x88be, 0x88b6, 0x88bc, + 0x88b7, 0x88bd, 0x88b2, 0x8901, 0x88c9, 0x8995, 0x8998, 0x8997, + 0x89dd, 0x89da, 0x89db, 0x8a4e, 0x8a4d, 0x8a39, 0x8a59, 0x8a40, + 0x8a57, 0x8a58, 0x8a44, 0x8a45, 0x8a52, 0x8a48, 0x8a51, 0x8a4a, + 0x8a4c, 0x8a4f, 0x8c5f, 0x8c81, 0x8c80, 0x8cba, 0x8cbe, 0x8cb0, + 0x8cb9, 0x8cb5, 0x8d84, 0x8d80, 0x8d89, 0x8dd8, 0x8dd3, 0x8dcd, + 0x8dc7, 0x8dd6, 0x8ddc, 0x8dcf, 0x8dd5, 0x8dd9, 0x8dc8, 0x8dd7, + 0x8dc5, 0x8eef, 0x8ef7, 0x8efa, 0x8ef9, 0x8ee6, 0x8eee, 0x8ee5, + 0x8ef5, 0x8ee7, 0x8ee8, 0x8ef6, 0x8eeb, 0x8ef1, 0x8eec, 0x8ef4, + 0x8ee9, 0x902d, 0x9034, 0x902f, 0x9106, 0x912c, 0x9104, 0x90ff, + 0x90fc, 0x9108, 0x90f9, 0x90fb, 0x9101, 0x9100, + /* 0x41 */ + 0x9107, 0x9105, 0x9103, 0x9161, 0x9164, 0x915f, 0x9162, 0x9160, + 0x9201, 0x920a, 0x9225, 0x9203, 0x921a, 0x9226, 0x920f, 0x920c, + 0x9200, 0x9212, 0x91ff, 0x91fd, 0x9206, 0x9204, 0x9227, 0x9202, + 0x921c, 0x9224, 0x9219, 0x9217, 0x9205, 0x9216, 0x957b, 0x958d, + 0x958c, 0x9590, 0x9687, 0x967e, 0x9688, 0x9689, 0x9683, 0x9680, + 0x96c2, 0x96c8, 0x96c3, 0x96f1, 0x96f0, 0x976c, 0x9770, 0x976e, + 0x9807, 0x98a9, 0x98eb, 0x9ce6, 0x9ef9, 0x4e83, 0x4e84, 0x4eb6, + 0x50bd, 0x50bf, 0x50c6, 0x50ae, 0x50c4, 0x50ca, 0x50b4, 0x50c8, + 0x50c2, 0x50b0, 0x50c1, 0x50ba, 0x50b1, 0x50cb, 0x50c9, 0x50b6, + 0x50b8, 0x51d7, 0x527a, 0x5278, 0x527b, 0x527c, 0x55c3, 0x55db, + 0x55cc, 0x55d0, 0x55cb, 0x55ca, 0x55dd, 0x55c0, 0x55d4, 0x55c4, + 0x55e9, 0x55bf, 0x55d2, 0x558d, 0x55cf, 0x55d5, + /* 0x42 */ + 0x55e2, 0x55d6, 0x55c8, 0x55f2, 0x55cd, 0x55d9, 0x55c2, 0x5714, + 0x5853, 0x5868, 0x5864, 0x584f, 0x584d, 0x5849, 0x586f, 0x5855, + 0x584e, 0x585d, 0x5859, 0x5865, 0x585b, 0x583d, 0x5863, 0x5871, + 0x58fc, 0x5ac7, 0x5ac4, 0x5acb, 0x5aba, 0x5ab8, 0x5ab1, 0x5ab5, + 0x5ab0, 0x5abf, 0x5ac8, 0x5abb, 0x5ac6, 0x5ab7, 0x5ac0, 0x5aca, + 0x5ab4, 0x5ab6, 0x5acd, 0x5ab9, 0x5a90, 0x5bd6, 0x5bd8, 0x5bd9, + 0x5c1f, 0x5c33, 0x5d71, 0x5d63, 0x5d4a, 0x5d65, 0x5d72, 0x5d6c, + 0x5d5e, 0x5d68, 0x5d67, 0x5d62, 0x5df0, 0x5e4f, 0x5e4e, 0x5e4a, + 0x5e4d, 0x5e4b, 0x5ec5, 0x5ecc, 0x5ec6, 0x5ecb, 0x5ec7, 0x5f40, + 0x5faf, 0x5fad, 0x60f7, 0x6149, 0x614a, 0x612b, 0x6145, 0x6136, + 0x6132, 0x612e, 0x6146, 0x612f, 0x614f, 0x6129, 0x6140, 0x6220, + 0x9168, 0x6223, 0x6225, 0x6224, 0x63c5, 0x63f1, + /* 0x43 */ + 0x63eb, 0x6410, 0x6412, 0x6409, 0x6420, 0x6424, 0x6433, 0x6443, + 0x641f, 0x6415, 0x6418, 0x6439, 0x6437, 0x6422, 0x6423, 0x640c, + 0x6426, 0x6430, 0x6428, 0x6441, 0x6435, 0x642f, 0x640a, 0x641a, + 0x6440, 0x6425, 0x6427, 0x640b, 0x63e7, 0x641b, 0x642e, 0x6421, + 0x640e, 0x656f, 0x6592, 0x65d3, 0x6686, 0x668c, 0x6695, 0x6690, + 0x668b, 0x668a, 0x6699, 0x6694, 0x6678, 0x6720, 0x6966, 0x695f, + 0x6938, 0x694e, 0x6962, 0x6971, 0x693f, 0x6945, 0x696a, 0x6939, + 0x6942, 0x6957, 0x6959, 0x697a, 0x6948, 0x6949, 0x6935, 0x696c, + 0x6933, 0x693d, 0x6965, 0x68f0, 0x6978, 0x6934, 0x6969, 0x6940, + 0x696f, 0x6944, 0x6976, 0x6958, 0x6941, 0x6974, 0x694c, 0x693b, + 0x694b, 0x6937, 0x695c, 0x694f, 0x6951, 0x6932, 0x6952, 0x692f, + 0x697b, 0x693c, 0x6b46, 0x6b45, 0x6b43, 0x6b42, + /* 0x44 */ + 0x6b48, 0x6b41, 0x6b9b, 0x6bfb, 0x6bfc, 0x6bf9, 0x6bf7, 0x6bf8, + 0x6e9b, 0x6ed6, 0x6ec8, 0x6e8f, 0x6ec0, 0x6e9f, 0x6e93, 0x6e94, + 0x6ea0, 0x6eb1, 0x6eb9, 0x6ec6, 0x6ed2, 0x6ebd, 0x6ec1, 0x6e9e, + 0x6ec9, 0x6eb7, 0x6eb0, 0x6ecd, 0x6ea6, 0x6ecf, 0x6eb2, 0x6ebe, + 0x6ec3, 0x6edc, 0x6ed8, 0x6e99, 0x6e92, 0x6e8e, 0x6e8d, 0x6ea4, + 0x6ea1, 0x6ebf, 0x6eb3, 0x6ed0, 0x6eca, 0x6e97, 0x6eae, 0x6ea3, + 0x7147, 0x7154, 0x7152, 0x7163, 0x7160, 0x7141, 0x715d, 0x7162, + 0x7172, 0x7178, 0x716a, 0x7161, 0x7142, 0x7158, 0x7143, 0x714b, + 0x7170, 0x715f, 0x7150, 0x7153, 0x7144, 0x714d, 0x715a, 0x724f, + 0x728d, 0x728c, 0x7291, 0x7290, 0x728e, 0x733c, 0x7342, 0x733b, + 0x733a, 0x7340, 0x734a, 0x7349, 0x7444, 0x744a, 0x744b, 0x7452, + 0x7451, 0x7457, 0x7440, 0x744f, 0x7450, 0x744e, + /* 0x45 */ + 0x7442, 0x7446, 0x744d, 0x7454, 0x74e1, 0x74ff, 0x74fe, 0x74fd, + 0x751d, 0x7579, 0x7577, 0x6983, 0x75ef, 0x760f, 0x7603, 0x75f7, + 0x75fe, 0x75fc, 0x75f9, 0x75f8, 0x7610, 0x75fb, 0x75f6, 0x75ed, + 0x75f5, 0x75fd, 0x7699, 0x76b5, 0x76dd, 0x7755, 0x775f, 0x7760, + 0x7752, 0x7756, 0x775a, 0x7769, 0x7767, 0x7754, 0x7759, 0x776d, + 0x77e0, 0x7887, 0x789a, 0x7894, 0x788f, 0x7884, 0x7895, 0x7885, + 0x7886, 0x78a1, 0x7883, 0x7879, 0x7899, 0x7880, 0x7896, 0x787b, + 0x797c, 0x7982, 0x797d, 0x7979, 0x7a11, 0x7a18, 0x7a19, 0x7a12, + 0x7a17, 0x7a15, 0x7a22, 0x7a13, 0x7a1b, 0x7a10, 0x7aa3, 0x7aa2, + 0x7a9e, 0x7aeb, 0x7b66, 0x7b64, 0x7b6d, 0x7b74, 0x7b69, 0x7b72, + 0x7b65, 0x7b73, 0x7b71, 0x7b70, 0x7b61, 0x7b78, 0x7b76, 0x7b63, + 0x7cb2, 0x7cb4, 0x7caf, 0x7d88, 0x7d86, 0x7d80, + /* 0x46 */ + 0x7d8d, 0x7d7f, 0x7d85, 0x7d7a, 0x7d8e, 0x7d7b, 0x7d83, 0x7d7c, + 0x7d8c, 0x7d94, 0x7d84, 0x7d7d, 0x7d92, 0x7f6d, 0x7f6b, 0x7f67, + 0x7f68, 0x7f6c, 0x7fa6, 0x7fa5, 0x7fa7, 0x7fdb, 0x7fdc, 0x8021, + 0x8164, 0x8160, 0x8177, 0x815c, 0x8169, 0x815b, 0x8162, 0x8172, + 0x6721, 0x815e, 0x8176, 0x8167, 0x816f, 0x8144, 0x8161, 0x821d, + 0x8249, 0x8244, 0x8240, 0x8242, 0x8245, 0x84f1, 0x843f, 0x8456, + 0x8476, 0x8479, 0x848f, 0x848d, 0x8465, 0x8451, 0x8440, 0x8486, + 0x8467, 0x8430, 0x844d, 0x847d, 0x845a, 0x8459, 0x8474, 0x8473, + 0x845d, 0x8507, 0x845e, 0x8437, 0x843a, 0x8434, 0x847a, 0x8443, + 0x8478, 0x8432, 0x8445, 0x8429, 0x83d9, 0x844b, 0x842f, 0x8442, + 0x842d, 0x845f, 0x8470, 0x8439, 0x844e, 0x844c, 0x8452, 0x846f, + 0x84c5, 0x848e, 0x843b, 0x8447, 0x8436, 0x8433, + /* 0x47 */ + 0x8468, 0x847e, 0x8444, 0x842b, 0x8460, 0x8454, 0x846e, 0x8450, + 0x870b, 0x8704, 0x86f7, 0x870c, 0x86fa, 0x86d6, 0x86f5, 0x874d, + 0x86f8, 0x870e, 0x8709, 0x8701, 0x86f6, 0x870d, 0x8705, 0x88d6, + 0x88cb, 0x88cd, 0x88ce, 0x88de, 0x88db, 0x88da, 0x88cc, 0x88d0, + 0x8985, 0x899b, 0x89df, 0x89e5, 0x89e4, 0x89e1, 0x89e0, 0x89e2, + 0x89dc, 0x89e6, 0x8a76, 0x8a86, 0x8a7f, 0x8a61, 0x8a3f, 0x8a77, + 0x8a82, 0x8a84, 0x8a75, 0x8a83, 0x8a81, 0x8a74, 0x8a7a, 0x8c3c, + 0x8c4b, 0x8c4a, 0x8c65, 0x8c64, 0x8c66, 0x8c86, 0x8c84, 0x8c85, + 0x8ccc, 0x8d68, 0x8d69, 0x8d91, 0x8d8c, 0x8d8e, 0x8d8f, 0x8d8d, + 0x8d93, 0x8d94, 0x8d90, 0x8d92, 0x8df0, 0x8de0, 0x8dec, 0x8df1, + 0x8dee, 0x8dd0, 0x8de9, 0x8de3, 0x8de2, 0x8de7, 0x8df2, 0x8deb, + 0x8df4, 0x8f06, 0x8eff, 0x8f01, 0x8f00, 0x8f05, + /* 0x48 */ + 0x8f07, 0x8f08, 0x8f02, 0x8f0b, 0x9052, 0x903f, 0x9044, 0x9049, + 0x903d, 0x9110, 0x910d, 0x910f, 0x9111, 0x9116, 0x9114, 0x910b, + 0x910e, 0x916e, 0x916f, 0x9248, 0x9252, 0x9230, 0x923a, 0x9266, + 0x9233, 0x9265, 0x925e, 0x9283, 0x922e, 0x924a, 0x9246, 0x926d, + 0x926c, 0x924f, 0x9260, 0x9267, 0x926f, 0x9236, 0x9261, 0x9270, + 0x9231, 0x9254, 0x9263, 0x9250, 0x9272, 0x924e, 0x9253, 0x924c, + 0x9256, 0x9232, 0x959f, 0x959c, 0x959e, 0x959b, 0x9692, 0x9693, + 0x9691, 0x9697, 0x96ce, 0x96fa, 0x96fd, 0x96f8, 0x96f5, 0x9773, + 0x9777, 0x9778, 0x9772, 0x980f, 0x980d, 0x980e, 0x98ac, 0x98f6, + 0x98f9, 0x99af, 0x99b2, 0x99b0, 0x99b5, 0x9aad, 0x9aab, 0x9b5b, + 0x9cea, 0x9ced, 0x9ce7, 0x9e80, 0x9efd, 0x50e6, 0x50d4, 0x50d7, + 0x50e8, 0x50f3, 0x50db, 0x50ea, 0x50dd, 0x50e4, + /* 0x49 */ + 0x50d3, 0x50ec, 0x50f0, 0x50ef, 0x50e3, 0x50e0, 0x51d8, 0x5280, + 0x5281, 0x52e9, 0x52eb, 0x5330, 0x53ac, 0x5627, 0x5615, 0x560c, + 0x5612, 0x55fc, 0x560f, 0x561c, 0x5601, 0x5613, 0x5602, 0x55fa, + 0x561d, 0x5604, 0x55ff, 0x55f9, 0x5889, 0x587c, 0x5890, 0x5898, + 0x5886, 0x5881, 0x587f, 0x5874, 0x588b, 0x587a, 0x5887, 0x5891, + 0x588e, 0x5876, 0x5882, 0x5888, 0x587b, 0x5894, 0x588f, 0x58fe, + 0x596b, 0x5adc, 0x5aee, 0x5ae5, 0x5ad5, 0x5aea, 0x5ada, 0x5aed, + 0x5aeb, 0x5af3, 0x5ae2, 0x5ae0, 0x5adb, 0x5aec, 0x5ade, 0x5add, + 0x5ad9, 0x5ae8, 0x5adf, 0x5b77, 0x5be0, 0x5be3, 0x5c63, 0x5d82, + 0x5d80, 0x5d7d, 0x5d86, 0x5d7a, 0x5d81, 0x5d77, 0x5d8a, 0x5d89, + 0x5d88, 0x5d7e, 0x5d7c, 0x5d8d, 0x5d79, 0x5d7f, 0x5e58, 0x5e59, + 0x5e53, 0x5ed8, 0x5ed1, 0x5ed7, 0x5ece, 0x5edc, + /* 0x4a */ + 0x5ed5, 0x5ed9, 0x5ed2, 0x5ed4, 0x5f44, 0x5f43, 0x5f6f, 0x5fb6, + 0x612c, 0x6128, 0x6141, 0x615e, 0x6171, 0x6173, 0x6152, 0x6153, + 0x6172, 0x616c, 0x6180, 0x6174, 0x6154, 0x617a, 0x615b, 0x6165, + 0x613b, 0x616a, 0x6161, 0x6156, 0x6229, 0x6227, 0x622b, 0x642b, + 0x644d, 0x645b, 0x645d, 0x6474, 0x6476, 0x6472, 0x6473, 0x647d, + 0x6475, 0x6466, 0x64a6, 0x644e, 0x6482, 0x645e, 0x645c, 0x644b, + 0x6453, 0x6460, 0x6450, 0x647f, 0x643f, 0x646c, 0x646b, 0x6459, + 0x6465, 0x6477, 0x6573, 0x65a0, 0x66a1, 0x66a0, 0x669f, 0x6705, + 0x6704, 0x6722, 0x69b1, 0x69b6, 0x69c9, 0x69a0, 0x69ce, 0x6996, + 0x69b0, 0x69ac, 0x69bc, 0x6991, 0x6999, 0x698e, 0x69a7, 0x698d, + 0x69a9, 0x69be, 0x69af, 0x69bf, 0x69c4, 0x69bd, 0x69a4, 0x69d4, + 0x69b9, 0x69ca, 0x699a, 0x69cf, 0x69b3, 0x6993, + /* 0x4b */ + 0x69aa, 0x69a1, 0x699e, 0x69d9, 0x6997, 0x6990, 0x69c2, 0x69b5, + 0x69a5, 0x69c6, 0x6b4a, 0x6b4d, 0x6b4b, 0x6b9e, 0x6b9f, 0x6ba0, + 0x6bc3, 0x6bc4, 0x6bfe, 0x6ece, 0x6ef5, 0x6ef1, 0x6f03, 0x6f25, + 0x6ef8, 0x6f37, 0x6efb, 0x6f2e, 0x6f09, 0x6f4e, 0x6f19, 0x6f1a, + 0x6f27, 0x6f18, 0x6f3b, 0x6f12, 0x6eed, 0x6f0a, 0x6f36, 0x6f73, + 0x6ef9, 0x6eee, 0x6f2d, 0x6f40, 0x6f30, 0x6f3c, 0x6f35, 0x6eeb, + 0x6f07, 0x6f0e, 0x6f43, 0x6f05, 0x6efd, 0x6ef6, 0x6f39, 0x6f1c, + 0x6efc, 0x6f3a, 0x6f1f, 0x6f0d, 0x6f1e, 0x6f08, 0x6f21, 0x7187, + 0x7190, 0x7189, 0x7180, 0x7185, 0x7182, 0x718f, 0x717b, 0x7186, + 0x7181, 0x7197, 0x7244, 0x7253, 0x7297, 0x7295, 0x7293, 0x7343, + 0x734d, 0x7351, 0x734c, 0x7462, 0x7473, 0x7471, 0x7475, 0x7472, + 0x7467, 0x746e, 0x7500, 0x7502, 0x7503, 0x757d, + /* 0x4c */ + 0x7590, 0x7616, 0x7608, 0x760c, 0x7615, 0x7611, 0x760a, 0x7614, + 0x76b8, 0x7781, 0x777c, 0x7785, 0x7782, 0x776e, 0x7780, 0x776f, + 0x777e, 0x7783, 0x78b2, 0x78aa, 0x78b4, 0x78ad, 0x78a8, 0x787e, + 0x78ab, 0x789e, 0x78a5, 0x78a0, 0x78ac, 0x78a2, 0x78a4, 0x7998, + 0x798a, 0x798b, 0x7996, 0x7995, 0x7994, 0x7993, 0x7997, 0x7988, + 0x7992, 0x7990, 0x7a2b, 0x7a4a, 0x7a30, 0x7a2f, 0x7a28, 0x7a26, + 0x7aa8, 0x7aab, 0x7aac, 0x7aee, 0x7b88, 0x7b9c, 0x7b8a, 0x7b91, + 0x7b90, 0x7b96, 0x7b8d, 0x7b8c, 0x7b9b, 0x7b8e, 0x7b85, 0x7b98, + 0x5284, 0x7b99, 0x7ba4, 0x7b82, 0x7cbb, 0x7cbf, 0x7cbc, 0x7cba, + 0x7da7, 0x7db7, 0x7dc2, 0x7da3, 0x7daa, 0x7dc1, 0x7dc0, 0x7dc5, + 0x7d9d, 0x7dce, 0x7dc4, 0x7dc6, 0x7dcb, 0x7dcc, 0x7daf, 0x7db9, + 0x7d96, 0x7dbc, 0x7d9f, 0x7da6, 0x7dae, 0x7da9, + /* 0x4d */ + 0x7da1, 0x7dc9, 0x7f73, 0x7fe2, 0x7fe3, 0x7fe5, 0x7fde, 0x8024, + 0x805d, 0x805c, 0x8189, 0x8186, 0x8183, 0x8187, 0x818d, 0x818c, + 0x818b, 0x8215, 0x8497, 0x84a4, 0x84a1, 0x849f, 0x84ba, 0x84ce, + 0x84c2, 0x84ac, 0x84ae, 0x84ab, 0x84b9, 0x84b4, 0x84c1, 0x84cd, + 0x84aa, 0x849a, 0x84b1, 0x84d0, 0x849d, 0x84a7, 0x84bb, 0x84a2, + 0x8494, 0x84c7, 0x84cc, 0x849b, 0x84a9, 0x84af, 0x84a8, 0x84d6, + 0x8498, 0x84b6, 0x84cf, 0x84a0, 0x84d7, 0x84d4, 0x84d2, 0x84db, + 0x84b0, 0x8491, 0x8661, 0x8733, 0x8723, 0x8728, 0x876b, 0x8740, + 0x872e, 0x871e, 0x8721, 0x8719, 0x871b, 0x8743, 0x872c, 0x8741, + 0x873e, 0x8746, 0x8720, 0x8732, 0x872a, 0x872d, 0x873c, 0x8712, + 0x873a, 0x8731, 0x8735, 0x8742, 0x8726, 0x8727, 0x8738, 0x8724, + 0x871a, 0x8730, 0x8711, 0x88f7, 0x88e7, 0x88f1, + /* 0x4e */ + 0x88f2, 0x88fa, 0x88fe, 0x88ee, 0x88fc, 0x88f6, 0x88fb, 0x88f0, + 0x88ec, 0x88eb, 0x899d, 0x89a1, 0x899f, 0x899e, 0x89e9, 0x89eb, + 0x89e8, 0x8aab, 0x8a99, 0x8a8b, 0x8a92, 0x8a8f, 0x8a96, 0x8c3d, + 0x8c68, 0x8c69, 0x8cd5, 0x8ccf, 0x8cd7, 0x8d96, 0x8e09, 0x8e02, + 0x8dff, 0x8e0d, 0x8dfd, 0x8e0a, 0x8e03, 0x8e07, 0x8e06, 0x8e05, + 0x8dfe, 0x8e00, 0x8e04, 0x8f10, 0x8f11, 0x8f0e, 0x8f0d, 0x9123, + 0x911c, 0x9120, 0x9122, 0x911f, 0x911d, 0x911a, 0x9124, 0x9121, + 0x911b, 0x917a, 0x9172, 0x9179, 0x9173, 0x92a5, 0x92a4, 0x9276, + 0x929b, 0x927a, 0x92a0, 0x9294, 0x92aa, 0x928d, 0x92a6, 0x929a, + 0x92ab, 0x9279, 0x9297, 0x927f, 0x92a3, 0x92ee, 0x928e, 0x9282, + 0x9295, 0x92a2, 0x927d, 0x9288, 0x92a1, 0x928a, 0x9286, 0x928c, + 0x9299, 0x92a7, 0x927e, 0x9287, 0x92a9, 0x929d, + /* 0x4f */ + 0x928b, 0x922d, 0x969e, 0x96a1, 0x96ff, 0x9758, 0x977d, 0x977a, + 0x977e, 0x9783, 0x9780, 0x9782, 0x977b, 0x9784, 0x9781, 0x977f, + 0x97ce, 0x97cd, 0x9816, 0x98ad, 0x98ae, 0x9902, 0x9900, 0x9907, + 0x999d, 0x999c, 0x99c3, 0x99b9, 0x99bb, 0x99ba, 0x99c2, 0x99bd, + 0x99c7, 0x9ab1, 0x9ae3, 0x9ae7, 0x9b3e, 0x9b3f, 0x9b60, 0x9b61, + 0x9b5f, 0x9cf1, 0x9cf2, 0x9cf5, 0x9ea7, 0x50ff, 0x5103, 0x5130, + 0x50f8, 0x5106, 0x5107, 0x50f6, 0x50fe, 0x510b, 0x510c, 0x50fd, + 0x510a, 0x528b, 0x528c, 0x52f1, 0x52ef, 0x5648, 0x5642, 0x564c, + 0x5635, 0x5641, 0x564a, 0x5649, 0x5646, 0x5658, 0x565a, 0x5640, + 0x5633, 0x563d, 0x562c, 0x563e, 0x5638, 0x562a, 0x563a, 0x571a, + 0x58ab, 0x589d, 0x58b1, 0x58a0, 0x58a3, 0x58af, 0x58ac, 0x58a5, + 0x58a1, 0x58ff, 0x5aff, 0x5af4, 0x5afd, 0x5af7, + /* 0x50 */ + 0x5af6, 0x5b03, 0x5af8, 0x5b02, 0x5af9, 0x5b01, 0x5b07, 0x5b05, + 0x5b0f, 0x5c67, 0x5d99, 0x5d97, 0x5d9f, 0x5d92, 0x5da2, 0x5d93, + 0x5d95, 0x5da0, 0x5d9c, 0x5da1, 0x5d9a, 0x5d9e, 0x5e69, 0x5e5d, + 0x5e60, 0x5e5c, 0x7df3, 0x5edb, 0x5ede, 0x5ee1, 0x5f49, 0x5fb2, + 0x618b, 0x6183, 0x6179, 0x61b1, 0x61b0, 0x61a2, 0x6189, 0x619b, + 0x6193, 0x61af, 0x61ad, 0x619f, 0x6192, 0x61aa, 0x61a1, 0x618d, + 0x6166, 0x61b3, 0x622d, 0x646e, 0x6470, 0x6496, 0x64a0, 0x6485, + 0x6497, 0x649c, 0x648f, 0x648b, 0x648a, 0x648c, 0x64a3, 0x649f, + 0x6468, 0x64b1, 0x6498, 0x6576, 0x657a, 0x6579, 0x657b, 0x65b2, + 0x65b3, 0x66b5, 0x66b0, 0x66a9, 0x66b2, 0x66b7, 0x66aa, 0x66af, + 0x6a00, 0x6a06, 0x6a17, 0x69e5, 0x69f8, 0x6a15, 0x69f1, 0x69e4, + 0x6a20, 0x69ff, 0x69ec, 0x69e2, 0x6a1b, 0x6a1d, + /* 0x51 */ + 0x69fe, 0x6a27, 0x69f2, 0x69ee, 0x6a14, 0x69f7, 0x69e7, 0x6a40, + 0x6a08, 0x69e6, 0x69fb, 0x6a0d, 0x69fc, 0x69eb, 0x6a09, 0x6a04, + 0x6a18, 0x6a25, 0x6a0f, 0x69f6, 0x6a26, 0x6a07, 0x69f4, 0x6a16, + 0x6b51, 0x6ba5, 0x6ba3, 0x6ba2, 0x6ba6, 0x6c01, 0x6c00, 0x6bff, + 0x6c02, 0x6f41, 0x6f26, 0x6f7e, 0x6f87, 0x6fc6, 0x6f92, 0x6f8d, + 0x6f89, 0x6f8c, 0x6f62, 0x6f4f, 0x6f85, 0x6f5a, 0x6f96, 0x6f76, + 0x6f6c, 0x6f82, 0x6f55, 0x6f72, 0x6f52, 0x6f50, 0x6f57, 0x6f94, + 0x6f93, 0x6f5d, 0x6f00, 0x6f61, 0x6f6b, 0x6f7d, 0x6f67, 0x6f90, + 0x6f53, 0x6f8b, 0x6f69, 0x6f7f, 0x6f95, 0x6f63, 0x6f77, 0x6f6a, + 0x6f7b, 0x71b2, 0x71af, 0x719b, 0x71b0, 0x71a0, 0x719a, 0x71a9, + 0x71b5, 0x719d, 0x71a5, 0x719e, 0x71a4, 0x71a1, 0x71aa, 0x719c, + 0x71a7, 0x71b3, 0x7298, 0x729a, 0x7358, 0x7352, + /* 0x52 */ + 0x735e, 0x735f, 0x7360, 0x735d, 0x735b, 0x7361, 0x735a, 0x7359, + 0x7362, 0x7487, 0x7489, 0x748a, 0x7486, 0x7481, 0x747d, 0x7485, + 0x7488, 0x747c, 0x7479, 0x7508, 0x7507, 0x757e, 0x7625, 0x761e, + 0x7619, 0x761d, 0x761c, 0x7623, 0x761a, 0x7628, 0x761b, 0x769c, + 0x769d, 0x769e, 0x769b, 0x778d, 0x778f, 0x7789, 0x7788, 0x78cd, + 0x78bb, 0x78cf, 0x78cc, 0x78d1, 0x78ce, 0x78d4, 0x78c8, 0x78c3, + 0x78c4, 0x78c9, 0x799a, 0x79a1, 0x79a0, 0x799c, 0x79a2, 0x799b, + 0x6b76, 0x7a39, 0x7ab2, 0x7ab4, 0x7ab3, 0x7bb7, 0x7bcb, 0x7bbe, + 0x7bac, 0x7bce, 0x7baf, 0x7bb9, 0x7bca, 0x7bb5, 0x7cc5, 0x7cc8, + 0x7ccc, 0x7ccb, 0x7df7, 0x7ddb, 0x7dea, 0x7de7, 0x7dd7, 0x7de1, + 0x7e03, 0x7dfa, 0x7de6, 0x7df6, 0x7df1, 0x7df0, 0x7dee, 0x7ddf, + 0x7f76, 0x7fac, 0x7fb0, 0x7fad, 0x7fed, 0x7feb, + /* 0x53 */ + 0x7fea, 0x7fec, 0x7fe6, 0x7fe8, 0x8064, 0x8067, 0x81a3, 0x819f, + 0x819e, 0x8195, 0x81a2, 0x8199, 0x8197, 0x8216, 0x824f, 0x8253, + 0x8252, 0x8250, 0x824e, 0x8251, 0x8524, 0x853b, 0x850f, 0x8500, + 0x8529, 0x850e, 0x8509, 0x850d, 0x851f, 0x850a, 0x8527, 0x851c, + 0x84fb, 0x852b, 0x84fa, 0x8508, 0x850c, 0x84f4, 0x852a, 0x84f2, + 0x8515, 0x84f7, 0x84eb, 0x84f3, 0x84fc, 0x8512, 0x84ea, 0x84e9, + 0x8516, 0x84fe, 0x8528, 0x851d, 0x852e, 0x8502, 0x84fd, 0x851e, + 0x84f6, 0x8531, 0x8526, 0x84e7, 0x84e8, 0x84f0, 0x84ef, 0x84f9, + 0x8518, 0x8520, 0x8530, 0x850b, 0x8519, 0x852f, 0x8662, 0x8756, + 0x8763, 0x8764, 0x8777, 0x87e1, 0x8773, 0x8758, 0x8754, 0x875b, + 0x8752, 0x8761, 0x875a, 0x8751, 0x875e, 0x876d, 0x876a, 0x8750, + 0x874e, 0x875f, 0x875d, 0x876f, 0x876c, 0x877a, + /* 0x54 */ + 0x876e, 0x875c, 0x8765, 0x874f, 0x877b, 0x8775, 0x8762, 0x8767, + 0x8769, 0x885a, 0x8905, 0x890c, 0x8914, 0x890b, 0x8917, 0x8918, + 0x8919, 0x8906, 0x8916, 0x8911, 0x890e, 0x8909, 0x89a2, 0x89a4, + 0x89a3, 0x89ed, 0x89f0, 0x89ec, 0x8acf, 0x8ac6, 0x8ab8, 0x8ad3, + 0x8ad1, 0x8ad4, 0x8ad5, 0x8abb, 0x8ad7, 0x8abe, 0x8ac0, 0x8ac5, + 0x8ad8, 0x8ac3, 0x8aba, 0x8abd, 0x8ad9, 0x8c3e, 0x8c4d, 0x8c8f, + 0x8ce5, 0x8cdf, 0x8cd9, 0x8ce8, 0x8cda, 0x8cdd, 0x8ce7, 0x8da0, + 0x8d9c, 0x8da1, 0x8d9b, 0x8e20, 0x8e23, 0x8e25, 0x8e24, 0x8e2e, + 0x8e15, 0x8e1b, 0x8e16, 0x8e11, 0x8e19, 0x8e26, 0x8e27, 0x8e14, + 0x8e12, 0x8e18, 0x8e13, 0x8e1c, 0x8e17, 0x8e1a, 0x8f2c, 0x8f24, + 0x8f18, 0x8f1a, 0x8f20, 0x8f23, 0x8f16, 0x8f17, 0x9073, 0x9070, + 0x906f, 0x9067, 0x906b, 0x912f, 0x912b, 0x9129, + /* 0x55 */ + 0x912a, 0x9132, 0x9126, 0x912e, 0x9185, 0x9186, 0x918a, 0x9181, + 0x9182, 0x9184, 0x9180, 0x92d0, 0x92c3, 0x92c4, 0x92c0, 0x92d9, + 0x92b6, 0x92cf, 0x92f1, 0x92df, 0x92d8, 0x92e9, 0x92d7, 0x92dd, + 0x92cc, 0x92ef, 0x92c2, 0x92e8, 0x92ca, 0x92c8, 0x92ce, 0x92e6, + 0x92cd, 0x92d5, 0x92c9, 0x92e0, 0x92de, 0x92e7, 0x92d1, 0x92d3, + 0x92b5, 0x92e1, 0x9325, 0x92c6, 0x92b4, 0x957c, 0x95ac, 0x95ab, + 0x95ae, 0x95b0, 0x96a4, 0x96a2, 0x96d3, 0x9705, 0x9708, 0x9702, + 0x975a, 0x978a, 0x978e, 0x9788, 0x97d0, 0x97cf, 0x981e, 0x981d, + 0x9826, 0x9829, 0x9828, 0x9820, 0x981b, 0x9827, 0x98b2, 0x9908, + 0x98fa, 0x9911, 0x9914, 0x9916, 0x9917, 0x9915, 0x99dc, 0x99cd, + 0x99cf, 0x99d3, 0x99d4, 0x99ce, 0x99c9, 0x99d6, 0x99d8, 0x99cb, + 0x99d7, 0x99cc, 0x9ab3, 0x9aec, 0x9aeb, 0x9af3, + /* 0x56 */ + 0x9af2, 0x9af1, 0x9b46, 0x9b43, 0x9b67, 0x9b74, 0x9b71, 0x9b66, + 0x9b76, 0x9b75, 0x9b70, 0x9b68, 0x9b64, 0x9b6c, 0x9cfc, 0x9cfa, + 0x9cfd, 0x9cff, 0x9cf7, 0x9d07, 0x9d00, 0x9cf9, 0x9cfb, 0x9d08, + 0x9d05, 0x9d04, 0x9e83, 0x9ed3, 0x9f0f, 0x9f10, 0x511c, 0x5113, + 0x5117, 0x511a, 0x5111, 0x51de, 0x5334, 0x53e1, 0x5670, 0x5660, + 0x566e, 0x5673, 0x5666, 0x5663, 0x566d, 0x5672, 0x565e, 0x5677, + 0x571c, 0x571b, 0x58c8, 0x58bd, 0x58c9, 0x58bf, 0x58ba, 0x58c2, + 0x58bc, 0x58c6, 0x5b17, 0x5b19, 0x5b1b, 0x5b21, 0x5b14, 0x5b13, + 0x5b10, 0x5b16, 0x5b28, 0x5b1a, 0x5b20, 0x5b1e, 0x5bef, 0x5dac, + 0x5db1, 0x5da9, 0x5da7, 0x5db5, 0x5db0, 0x5dae, 0x5daa, 0x5da8, + 0x5db2, 0x5dad, 0x5daf, 0x5db4, 0x5e67, 0x5e68, 0x5e66, 0x5e6f, + 0x5ee9, 0x5ee7, 0x5ee6, 0x5ee8, 0x5ee5, 0x5f4b, + /* 0x57 */ + 0x5fbc, 0x5fbb, 0x619d, 0x61a8, 0x6196, 0x61c5, 0x61b4, 0x61c6, + 0x61c1, 0x61cc, 0x61ba, 0x61bf, 0x61b8, 0x618c, 0x64d7, 0x64d6, + 0x64d0, 0x64cf, 0x64c9, 0x64bd, 0x6489, 0x64c3, 0x64db, 0x64f3, + 0x64d9, 0x6533, 0x657f, 0x657c, 0x65a2, 0x66c8, 0x66be, 0x66c0, + 0x66ca, 0x66cb, 0x66cf, 0x66bd, 0x66bb, 0x66ba, 0x66cc, 0x6723, + 0x6a34, 0x6a66, 0x6a49, 0x6a67, 0x6a32, 0x6a68, 0x6a3e, 0x6a5d, + 0x6a6d, 0x6a76, 0x6a5b, 0x6a51, 0x6a28, 0x6a5a, 0x6a3b, 0x6a3f, + 0x6a41, 0x6a6a, 0x6a64, 0x6a50, 0x6a4f, 0x6a54, 0x6a6f, 0x6a69, + 0x6a60, 0x6a3c, 0x6a5e, 0x6a56, 0x6a55, 0x6a4d, 0x6a4e, 0x6a46, + 0x6b55, 0x6b54, 0x6b56, 0x6ba7, 0x6baa, 0x6bab, 0x6bc8, 0x6bc7, + 0x6c04, 0x6c03, 0x6c06, 0x6fad, 0x6fcb, 0x6fa3, 0x6fc7, 0x6fbc, + 0x6fce, 0x6fc8, 0x6f5e, 0x6fc4, 0x6fbd, 0x6f9e, + /* 0x58 */ + 0x6fca, 0x6fa8, 0x7004, 0x6fa5, 0x6fae, 0x6fba, 0x6fac, 0x6faa, + 0x6fcf, 0x6fbf, 0x6fb8, 0x6fa2, 0x6fc9, 0x6fab, 0x6fcd, 0x6faf, + 0x6fb2, 0x6fb0, 0x71c5, 0x71c2, 0x71bf, 0x71b8, 0x71d6, 0x71c0, + 0x71c1, 0x71cb, 0x71d4, 0x71ca, 0x71c7, 0x71cf, 0x71bd, 0x71d8, + 0x71bc, 0x71c6, 0x71da, 0x71db, 0x729d, 0x729e, 0x7369, 0x7366, + 0x7367, 0x736c, 0x7365, 0x736b, 0x736a, 0x747f, 0x749a, 0x74a0, + 0x7494, 0x7492, 0x7495, 0x74a1, 0x750b, 0x7580, 0x762f, 0x762d, + 0x7631, 0x763d, 0x7633, 0x763c, 0x7635, 0x7632, 0x7630, 0x76bb, + 0x76e6, 0x779a, 0x779d, 0x77a1, 0x779c, 0x779b, 0x77a2, 0x77a3, + 0x7795, 0x7799, 0x7797, 0x78dd, 0x78e9, 0x78e5, 0x78ea, 0x78de, + 0x78e3, 0x78db, 0x78e1, 0x78e2, 0x78ed, 0x78df, 0x78e0, 0x79a4, + 0x7a44, 0x7a48, 0x7a47, 0x7ab6, 0x7ab8, 0x7ab5, + /* 0x59 */ + 0x7ab1, 0x7ab7, 0x7bde, 0x7be3, 0x7be7, 0x7bdd, 0x7bd5, 0x7be5, + 0x7bda, 0x7be8, 0x7bf9, 0x7bd4, 0x7bea, 0x7be2, 0x7bdc, 0x7beb, + 0x7bd8, 0x7bdf, 0x7cd2, 0x7cd4, 0x7cd7, 0x7cd0, 0x7cd1, 0x7e12, + 0x7e21, 0x7e17, 0x7e0c, 0x7e1f, 0x7e20, 0x7e13, 0x7e0e, 0x7e1c, + 0x7e15, 0x7e1a, 0x7e22, 0x7e0b, 0x7e0f, 0x7e16, 0x7e0d, 0x7e14, + 0x7e25, 0x7e24, 0x7f43, 0x7f7b, 0x7f7c, 0x7f7a, 0x7fb1, 0x7fef, + 0x802a, 0x8029, 0x806c, 0x81b1, 0x81a6, 0x81ae, 0x81b9, 0x81b5, + 0x81ab, 0x81b0, 0x81ac, 0x81b4, 0x81b2, 0x81b7, 0x81a7, 0x81f2, + 0x8255, 0x8256, 0x8257, 0x8556, 0x8545, 0x856b, 0x854d, 0x8553, + 0x8561, 0x8558, 0x8540, 0x8546, 0x8564, 0x8541, 0x8562, 0x8544, + 0x8551, 0x8547, 0x8563, 0x853e, 0x855b, 0x8571, 0x854e, 0x856e, + 0x8575, 0x8555, 0x8567, 0x8560, 0x858c, 0x8566, + /* 0x5a */ + 0x855d, 0x8554, 0x8565, 0x856c, 0x8663, 0x8665, 0x8664, 0x87a4, + 0x879b, 0x878f, 0x8797, 0x8793, 0x8792, 0x8788, 0x8781, 0x8796, + 0x8798, 0x8779, 0x8787, 0x87a3, 0x8785, 0x8790, 0x8791, 0x879d, + 0x8784, 0x8794, 0x879c, 0x879a, 0x8789, 0x891e, 0x8926, 0x8930, + 0x892d, 0x892e, 0x8927, 0x8931, 0x8922, 0x8929, 0x8923, 0x892f, + 0x892c, 0x891f, 0x89f1, 0x8ae0, 0x8ae2, 0x8af2, 0x8af4, 0x8af5, + 0x8add, 0x8b14, 0x8ae4, 0x8adf, 0x8af0, 0x8ac8, 0x8ade, 0x8ae1, + 0x8ae8, 0x8aff, 0x8aef, 0x8afb, 0x8c91, 0x8c92, 0x8c90, 0x8cf5, + 0x8cee, 0x8cf1, 0x8cf0, 0x8cf3, 0x8d6c, 0x8d6e, 0x8da5, 0x8da7, + 0x8e33, 0x8e3e, 0x8e38, 0x8e40, 0x8e45, 0x8e36, 0x8e3c, 0x8e3d, + 0x8e41, 0x8e30, 0x8e3f, 0x8ebd, 0x8f36, 0x8f2e, 0x8f35, 0x8f32, + 0x8f39, 0x8f37, 0x8f34, 0x9076, 0x9079, 0x907b, + /* 0x5b */ + 0x9086, 0x90fa, 0x9133, 0x9135, 0x9136, 0x9193, 0x9190, 0x9191, + 0x918d, 0x918f, 0x9327, 0x931e, 0x9308, 0x931f, 0x9306, 0x930f, + 0x937a, 0x9338, 0x933c, 0x931b, 0x9323, 0x9312, 0x9301, 0x9346, + 0x932d, 0x930e, 0x930d, 0x92cb, 0x931d, 0x92fa, 0x9313, 0x92f9, + 0x92f7, 0x9334, 0x9302, 0x9324, 0x92ff, 0x9329, 0x9339, 0x9335, + 0x932a, 0x9314, 0x930c, 0x930b, 0x92fe, 0x9309, 0x9300, 0x92fb, + 0x9316, 0x95bc, 0x95cd, 0x95be, 0x95b9, 0x95ba, 0x95b6, 0x95bf, + 0x95b5, 0x95bd, 0x96a9, 0x96d4, 0x970b, 0x9712, 0x9710, 0x9799, + 0x9797, 0x9794, 0x97f0, 0x97f8, 0x9835, 0x982f, 0x9832, 0x9924, + 0x991f, 0x9927, 0x9929, 0x999e, 0x99ee, 0x99ec, 0x99e5, 0x99e4, + 0x99f0, 0x99e3, 0x99ea, 0x99e9, 0x99e7, 0x9ab9, 0x9abf, 0x9ab4, + 0x9abb, 0x9af6, 0x9afa, 0x9af9, 0x9af7, 0x9b33, + /* 0x5c */ + 0x9b80, 0x9b85, 0x9b87, 0x9b7c, 0x9b7e, 0x9b7b, 0x9b82, 0x9b93, + 0x9b92, 0x9b90, 0x9b7a, 0x9b95, 0x9b7d, 0x9b88, 0x9d25, 0x9d17, + 0x9d20, 0x9d1e, 0x9d14, 0x9d29, 0x9d1d, 0x9d18, 0x9d22, 0x9d10, + 0x9d19, 0x9d1f, 0x9e88, 0x9e86, 0x9e87, 0x9eae, 0x9ead, 0x9ed5, + 0x9ed6, 0x9efa, 0x9f12, 0x9f3d, 0x5126, 0x5125, 0x5122, 0x5124, + 0x5120, 0x5129, 0x52f4, 0x5693, 0x568c, 0x568d, 0x5686, 0x5684, + 0x5683, 0x567e, 0x5682, 0x567f, 0x5681, 0x58d6, 0x58d4, 0x58cf, + 0x58d2, 0x5b2d, 0x5b25, 0x5b32, 0x5b23, 0x5b2c, 0x5b27, 0x5b26, + 0x5b2f, 0x5b2e, 0x5b7b, 0x5bf1, 0x5bf2, 0x5db7, 0x5e6c, 0x5e6a, + 0x5fbe, 0x61c3, 0x61b5, 0x61bc, 0x61e7, 0x61e0, 0x61e5, 0x61e4, + 0x61e8, 0x61de, 0x64ef, 0x64e9, 0x64e3, 0x64eb, 0x64e4, 0x64e8, + 0x6581, 0x6580, 0x65b6, 0x65da, 0x66d2, 0x6a8d, + /* 0x5d */ + 0x6a96, 0x6a81, 0x6aa5, 0x6a89, 0x6a9f, 0x6a9b, 0x6aa1, 0x6a9e, + 0x6a87, 0x6a93, 0x6a8e, 0x6a95, 0x6a83, 0x6aa8, 0x6aa4, 0x6a91, + 0x6a7f, 0x6aa6, 0x6a9a, 0x6a85, 0x6a8c, 0x6a92, 0x6b5b, 0x6bad, + 0x6c09, 0x6fcc, 0x6fa9, 0x6ff4, 0x6fd4, 0x6fe3, 0x6fdc, 0x6fed, + 0x6fe7, 0x6fe6, 0x6fde, 0x6ff2, 0x6fdd, 0x6fe2, 0x6fe8, 0x71e1, + 0x71f1, 0x71e8, 0x71f2, 0x71e4, 0x71f0, 0x71e2, 0x7373, 0x736e, + 0x736f, 0x7497, 0x74b2, 0x74ab, 0x7490, 0x74aa, 0x74ad, 0x74b1, + 0x74a5, 0x74af, 0x7510, 0x7511, 0x7512, 0x750f, 0x7584, 0x7643, + 0x7648, 0x7649, 0x7647, 0x76a4, 0x76e9, 0x77b5, 0x77ab, 0x77b2, + 0x77b7, 0x77b6, 0x77b4, 0x77b1, 0x77a8, 0x77f0, 0x78f3, 0x78fd, + 0x7902, 0x78fb, 0x78fc, 0x78ff, 0x78f2, 0x7905, 0x78f9, 0x78fe, + 0x7904, 0x79ab, 0x79a8, 0x7a5c, 0x7a5b, 0x7a56, + /* 0x5e */ + 0x7a58, 0x7a54, 0x7a5a, 0x7abe, 0x7ac0, 0x7ac1, 0x7c05, 0x7c0f, + 0x7bf2, 0x7c00, 0x7bff, 0x7bfb, 0x7c0e, 0x7bf4, 0x7c0b, 0x7bf3, + 0x7c02, 0x7c09, 0x7c03, 0x7c01, 0x7bf8, 0x7bfd, 0x7c06, 0x7bf0, + 0x7bf1, 0x7c10, 0x7c0a, 0x7ce8, 0x7e2d, 0x7e3c, 0x7e42, 0x7e33, + 0x9848, 0x7e38, 0x7e2a, 0x7e49, 0x7e40, 0x7e47, 0x7e29, 0x7e4c, + 0x7e30, 0x7e3b, 0x7e36, 0x7e44, 0x7e3a, 0x7f45, 0x7f7f, 0x7f7e, + 0x7f7d, 0x7ff4, 0x7ff2, 0x802c, 0x81bb, 0x81c4, 0x81cc, 0x81ca, + 0x81c5, 0x81c7, 0x81bc, 0x81e9, 0x825b, 0x825a, 0x825c, 0x8583, + 0x8580, 0x858f, 0x85a7, 0x8595, 0x85a0, 0x858b, 0x85a3, 0x857b, + 0x85a4, 0x859a, 0x859e, 0x8577, 0x857c, 0x8589, 0x85a1, 0x857a, + 0x8578, 0x8557, 0x858e, 0x8596, 0x8586, 0x858d, 0x8599, 0x859d, + 0x8581, 0x85a2, 0x8582, 0x8588, 0x8585, 0x8579, + /* 0x5f */ + 0x8576, 0x8598, 0x8590, 0x859f, 0x8668, 0x87be, 0x87aa, 0x87ad, + 0x87c5, 0x87b0, 0x87ac, 0x87b9, 0x87b5, 0x87bc, 0x87ae, 0x87c9, + 0x87c3, 0x87c2, 0x87cc, 0x87b7, 0x87af, 0x87c4, 0x87ca, 0x87b4, + 0x87b6, 0x87bf, 0x87b8, 0x87bd, 0x87de, 0x87b2, 0x8935, 0x8933, + 0x893c, 0x893e, 0x8941, 0x8952, 0x8937, 0x8942, 0x89ad, 0x89af, + 0x89ae, 0x89f2, 0x89f3, 0x8b1e, 0x8b18, 0x8b16, 0x8b11, 0x8b05, + 0x8b0b, 0x8b22, 0x8b0f, 0x8b12, 0x8b15, 0x8b07, 0x8b0d, 0x8b08, + 0x8b06, 0x8b1c, 0x8b13, 0x8b1a, 0x8c4f, 0x8c70, 0x8c72, 0x8c71, + 0x8c6f, 0x8c95, 0x8c94, 0x8cf9, 0x8d6f, 0x8e4e, 0x8e4d, 0x8e53, + 0x8e50, 0x8e4c, 0x8e47, 0x8f43, 0x8f40, 0x9085, 0x907e, 0x9138, + 0x919a, 0x91a2, 0x919b, 0x9199, 0x919f, 0x91a1, 0x919d, 0x91a0, + 0x93a1, 0x9383, 0x93af, 0x9364, 0x9356, 0x9347, + /* 0x60 */ + 0x937c, 0x9358, 0x935c, 0x9376, 0x9349, 0x9350, 0x9351, 0x9360, + 0x936d, 0x938f, 0x934c, 0x936a, 0x9379, 0x9357, 0x9355, 0x9352, + 0x934f, 0x9371, 0x9377, 0x937b, 0x9361, 0x935e, 0x9363, 0x9367, + 0x934e, 0x9359, 0x95c7, 0x95c0, 0x95c9, 0x95c3, 0x95c5, 0x95b7, + 0x96ae, 0x96b0, 0x96ac, 0x9720, 0x971f, 0x9718, 0x971d, 0x9719, + 0x979a, 0x97a1, 0x979c, 0x979e, 0x979d, 0x97d5, 0x97d4, 0x97f1, + 0x9841, 0x9844, 0x984a, 0x9849, 0x9845, 0x9843, 0x9925, 0x992b, + 0x992c, 0x992a, 0x9933, 0x9932, 0x992f, 0x992d, 0x9931, 0x9930, + 0x9998, 0x99a3, 0x99a1, 0x9a02, 0x99fa, 0x99f4, 0x99f7, 0x99f9, + 0x99f8, 0x99f6, 0x99fb, 0x99fd, 0x99fe, 0x99fc, 0x9a03, 0x9abe, + 0x9afe, 0x9afd, 0x9b01, 0x9afc, 0x9b48, 0x9b9a, 0x9ba8, 0x9b9e, + 0x9b9b, 0x9ba6, 0x9ba1, 0x9ba5, 0x9ba4, 0x9b86, + /* 0x61 */ + 0x9ba2, 0x9ba0, 0x9baf, 0x9d33, 0x9d41, 0x9d67, 0x9d36, 0x9d2e, + 0x9d2f, 0x9d31, 0x9d38, 0x9d30, 0x9d45, 0x9d42, 0x9d43, 0x9d3e, + 0x9d37, 0x9d40, 0x9d3d, 0x7ff5, 0x9d2d, 0x9e8a, 0x9e89, 0x9e8d, + 0x9eb0, 0x9ec8, 0x9eda, 0x9efb, 0x9eff, 0x9f24, 0x9f23, 0x9f22, + 0x9f54, 0x9fa0, 0x5131, 0x512d, 0x512e, 0x5698, 0x569c, 0x5697, + 0x569a, 0x569d, 0x5699, 0x5970, 0x5b3c, 0x5c69, 0x5c6a, 0x5dc0, + 0x5e6d, 0x5e6e, 0x61d8, 0x61df, 0x61ed, 0x61ee, 0x61f1, 0x61ea, + 0x61f0, 0x61eb, 0x61d6, 0x61e9, 0x64ff, 0x6504, 0x64fd, 0x64f8, + 0x6501, 0x6503, 0x64fc, 0x6594, 0x65db, 0x66da, 0x66db, 0x66d8, + 0x6ac5, 0x6ab9, 0x6abd, 0x6ae1, 0x6ac6, 0x6aba, 0x6ab6, 0x6ab7, + 0x6ac7, 0x6ab4, 0x6aad, 0x6b5e, 0x6bc9, 0x6c0b, 0x7007, 0x700c, + 0x700d, 0x7001, 0x7005, 0x7014, 0x700e, 0x6fff, + /* 0x62 */ + 0x7000, 0x6ffb, 0x7026, 0x6ffc, 0x6ff7, 0x700a, 0x7201, 0x71ff, + 0x71f9, 0x7203, 0x71fd, 0x7376, 0x74b8, 0x74c0, 0x74b5, 0x74c1, + 0x74be, 0x74b6, 0x74bb, 0x74c2, 0x7514, 0x7513, 0x765c, 0x7664, + 0x7659, 0x7650, 0x7653, 0x7657, 0x765a, 0x76a6, 0x76bd, 0x76ec, + 0x77c2, 0x77ba, 0x790c, 0x7913, 0x7914, 0x7909, 0x7910, 0x7912, + 0x7911, 0x79ad, 0x79ac, 0x7a5f, 0x7c1c, 0x7c29, 0x7c19, 0x7c20, + 0x7c1f, 0x7c2d, 0x7c1d, 0x7c26, 0x7c28, 0x7c22, 0x7c25, 0x7c30, + 0x7e5c, 0x7e50, 0x7e56, 0x7e63, 0x7e58, 0x7e62, 0x7e5f, 0x7e51, + 0x7e60, 0x7e57, 0x7e53, 0x7fb5, 0x7fb3, 0x7ff7, 0x7ff8, 0x8075, + 0x81d1, 0x81d2, 0x81d0, 0x825f, 0x825e, 0x85b4, 0x85c6, 0x85c0, + 0x85c3, 0x85c2, 0x85b3, 0x85b5, 0x85bd, 0x85c7, 0x85c4, 0x85bf, + 0x85cb, 0x85ce, 0x85c8, 0x85c5, 0x85b1, 0x85b6, + /* 0x63 */ + 0x85d2, 0x8624, 0x85b8, 0x85b7, 0x85be, 0x8669, 0x87e7, 0x87e6, + 0x87e2, 0x87db, 0x87eb, 0x87ea, 0x87e5, 0x87df, 0x87f3, 0x87e4, + 0x87d4, 0x87dc, 0x87d3, 0x87ed, 0x87d8, 0x87e3, 0x87d7, 0x87d9, + 0x8801, 0x87f4, 0x87e8, 0x87dd, 0x8953, 0x894b, 0x894f, 0x894c, + 0x8946, 0x8950, 0x8951, 0x8949, 0x8b2a, 0x8b27, 0x8b23, 0x8b33, + 0x8b30, 0x8b35, 0x8b47, 0x8b2f, 0x8b3c, 0x8b3e, 0x8b31, 0x8b25, + 0x8b37, 0x8b26, 0x8b36, 0x8b2e, 0x8b24, 0x8b3b, 0x8b3d, 0x8b3a, + 0x8c42, 0x8c75, 0x8c99, 0x8c98, 0x8c97, 0x8cfe, 0x8d04, 0x8d02, + 0x8d00, 0x8e5c, 0x8e62, 0x8e60, 0x8e57, 0x8e56, 0x8e5e, 0x8e65, + 0x8e67, 0x8e5b, 0x8e5a, 0x8e61, 0x8e5d, 0x8e69, 0x8e54, 0x8f46, + 0x8f47, 0x8f48, 0x8f4b, 0x9128, 0x913a, 0x913b, 0x913e, 0x91a8, + 0x91a5, 0x91a7, 0x91af, 0x91aa, 0x93b5, 0x938c, + /* 0x64 */ + 0x9392, 0x93b7, 0x939b, 0x939d, 0x9389, 0x93a7, 0x938e, 0x93aa, + 0x939e, 0x93a6, 0x9395, 0x9388, 0x9399, 0x939f, 0x9380, 0x938d, + 0x93b1, 0x9391, 0x93b2, 0x93a4, 0x93a8, 0x93b4, 0x93a3, 0x95d2, + 0x95d3, 0x95d1, 0x96b3, 0x96d7, 0x96da, 0x5dc2, 0x96df, 0x96d8, + 0x96dd, 0x9723, 0x9722, 0x9725, 0x97ac, 0x97ae, 0x97a8, 0x97ab, + 0x97a4, 0x97aa, 0x97a2, 0x97a5, 0x97d7, 0x97d9, 0x97d6, 0x97d8, + 0x97fa, 0x9850, 0x9851, 0x9852, 0x98b8, 0x9941, 0x993c, 0x993a, + 0x9a0f, 0x9a0b, 0x9a09, 0x9a0d, 0x9a04, 0x9a11, 0x9a0a, 0x9a05, + 0x9a07, 0x9a06, 0x9ac0, 0x9adc, 0x9b08, 0x9b04, 0x9b05, 0x9b29, + 0x9b35, 0x9b4a, 0x9b4c, 0x9b4b, 0x9bc7, 0x9bc6, 0x9bc3, 0x9bbf, + 0x9bc1, 0x9bb5, 0x9bb8, 0x9bd3, 0x9bb6, 0x9bc4, 0x9bb9, 0x9bbd, + 0x9d5c, 0x9d53, 0x9d4f, 0x9d4a, 0x9d5b, 0x9d4b, + /* 0x65 */ + 0x9d59, 0x9d56, 0x9d4c, 0x9d57, 0x9d52, 0x9d54, 0x9d5f, 0x9d58, + 0x9d5a, 0x9e8e, 0x9e8c, 0x9edf, 0x9f01, 0x9f00, 0x9f16, 0x9f25, + 0x9f2b, 0x9f2a, 0x9f29, 0x9f28, 0x9f4c, 0x9f55, 0x5134, 0x5135, + 0x5296, 0x52f7, 0x53b4, 0x56ab, 0x56ad, 0x56a6, 0x56a7, 0x56aa, + 0x56ac, 0x58da, 0x58dd, 0x58db, 0x5912, 0x5b3d, 0x5b3e, 0x5b3f, + 0x5dc3, 0x5e70, 0x5fbf, 0x61fb, 0x6507, 0x6510, 0x650d, 0x6509, + 0x650c, 0x650e, 0x6584, 0x65de, 0x65dd, 0x66de, 0x6ae7, 0x6ae0, + 0x6acc, 0x6ad1, 0x6ad9, 0x6acb, 0x6adf, 0x6adc, 0x6ad0, 0x6aeb, + 0x6acf, 0x6acd, 0x6ade, 0x6b60, 0x6bb0, 0x6c0c, 0x7019, 0x7027, + 0x7020, 0x7016, 0x702b, 0x7021, 0x7022, 0x7023, 0x7029, 0x7017, + 0x7024, 0x701c, 0x720c, 0x720a, 0x7207, 0x7202, 0x7205, 0x72a5, + 0x72a6, 0x72a4, 0x72a3, 0x72a1, 0x74cb, 0x74c5, + /* 0x66 */ + 0x74b7, 0x74c3, 0x7516, 0x7660, 0x77c9, 0x77ca, 0x77c4, 0x77f1, + 0x791d, 0x791b, 0x7921, 0x791c, 0x7917, 0x791e, 0x79b0, 0x7a67, + 0x7a68, 0x7c33, 0x7c3c, 0x7c39, 0x7c2c, 0x7c3b, 0x7cec, 0x7cea, + 0x7e76, 0x7e75, 0x7e78, 0x7e70, 0x7e77, 0x7e6f, 0x7e7a, 0x7e72, + 0x7e74, 0x7e68, 0x7f4b, 0x7f4a, 0x7f83, 0x7f86, 0x7fb7, 0x7ffd, + 0x7ffe, 0x8078, 0x81d7, 0x81d5, 0x820b, 0x8264, 0x8261, 0x8263, + 0x85eb, 0x85f1, 0x85ed, 0x85d9, 0x85e1, 0x85e8, 0x85da, 0x85d7, + 0x85ec, 0x85f2, 0x85f8, 0x85d8, 0x85df, 0x85e3, 0x85dc, 0x85d1, + 0x85f0, 0x85e6, 0x85ef, 0x85de, 0x85e2, 0x8800, 0x87fa, 0x8803, + 0x87f6, 0x87f7, 0x8809, 0x880c, 0x880b, 0x8806, 0x87fc, 0x8808, + 0x87ff, 0x880a, 0x8802, 0x8962, 0x895a, 0x895b, 0x8957, 0x8961, + 0x895c, 0x8958, 0x895d, 0x8959, 0x8988, 0x89b7, + /* 0x67 */ + 0x89b6, 0x89f6, 0x8b50, 0x8b48, 0x8b4a, 0x8b40, 0x8b53, 0x8b56, + 0x8b54, 0x8b4b, 0x8b55, 0x8b51, 0x8b42, 0x8b52, 0x8b57, 0x8c43, + 0x8c77, 0x8c76, 0x8c9a, 0x8d06, 0x8d07, 0x8d09, 0x8dac, 0x8daa, + 0x8dad, 0x8dab, 0x8e6d, 0x8e78, 0x8e73, 0x8e6a, 0x8e6f, 0x8e7b, + 0x8ec2, 0x8f52, 0x8f51, 0x8f4f, 0x8f50, 0x8f53, 0x8fb4, 0x9140, + 0x913f, 0x91b0, 0x91ad, 0x93de, 0x93c7, 0x93cf, 0x93c2, 0x93da, + 0x93d0, 0x93f9, 0x93ec, 0x93cc, 0x93d9, 0x93a9, 0x93e6, 0x93ca, + 0x93d4, 0x93ee, 0x93e3, 0x93d5, 0x93c4, 0x93ce, 0x93c0, 0x93d2, + 0x93a5, 0x93e7, 0x957d, 0x95da, 0x95db, 0x96e1, 0x9729, 0x972b, + 0x972c, 0x9728, 0x9726, 0x97b3, 0x97b7, 0x97b6, 0x97dd, 0x97de, + 0x97df, 0x985c, 0x9859, 0x985d, 0x9857, 0x98bf, 0x98bd, 0x98bb, + 0x98be, 0x9948, 0x9947, 0x9943, 0x99a6, 0x99a7, + /* 0x68 */ + 0x9a1a, 0x9a15, 0x9a25, 0x9a1d, 0x9a24, 0x9a1b, 0x9a22, 0x9a20, + 0x9a27, 0x9a23, 0x9a1e, 0x9a1c, 0x9a14, 0x9ac2, 0x9b0b, 0x9b0a, + 0x9b0e, 0x9b0c, 0x9b37, 0x9bea, 0x9beb, 0x9be0, 0x9bde, 0x9be4, + 0x9be6, 0x9be2, 0x9bf0, 0x9bd4, 0x9bd7, 0x9bec, 0x9bdc, 0x9bd9, + 0x9be5, 0x9bd5, 0x9be1, 0x9bda, 0x9d77, 0x9d81, 0x9d8a, 0x9d84, + 0x9d88, 0x9d71, 0x9d80, 0x9d78, 0x9d86, 0x9d8b, 0x9d8c, 0x9d7d, + 0x9d6b, 0x9d74, 0x9d75, 0x9d70, 0x9d69, 0x9d85, 0x9d73, 0x9d7b, + 0x9d82, 0x9d6f, 0x9d79, 0x9d7f, 0x9d87, 0x9d68, 0x9e94, 0x9e91, + 0x9ec0, 0x9efc, 0x9f2d, 0x9f40, 0x9f41, 0x9f4d, 0x9f56, 0x9f57, + 0x9f58, 0x5337, 0x56b2, 0x56b5, 0x56b3, 0x58e3, 0x5b45, 0x5dc6, + 0x5dc7, 0x5eee, 0x5eef, 0x5fc0, 0x5fc1, 0x61f9, 0x6517, 0x6516, + 0x6515, 0x6513, 0x65df, 0x66e8, 0x66e3, 0x66e4, + /* 0x69 */ + 0x6af3, 0x6af0, 0x6aea, 0x6ae8, 0x6af9, 0x6af1, 0x6aee, 0x6aef, + 0x703c, 0x7035, 0x702f, 0x7037, 0x7034, 0x7031, 0x7042, 0x7038, + 0x703f, 0x703a, 0x7039, 0x702a, 0x7040, 0x703b, 0x7033, 0x7041, + 0x7213, 0x7214, 0x72a8, 0x737d, 0x737c, 0x74ba, 0x76ab, 0x76aa, + 0x76be, 0x76ed, 0x77cc, 0x77ce, 0x77cf, 0x77cd, 0x77f2, 0x7925, + 0x7923, 0x7927, 0x7928, 0x7924, 0x7929, 0x79b2, 0x7a6e, 0x7a6c, + 0x7a6d, 0x7af7, 0x7c49, 0x7c48, 0x7c4a, 0x7c47, 0x7c45, 0x7cee, + 0x7e7b, 0x7e7e, 0x7e81, 0x7e80, 0x7fba, 0x7fff, 0x8079, 0x81db, + 0x81d9, 0x8268, 0x8269, 0x8622, 0x85ff, 0x8601, 0x85fe, 0x861b, + 0x8600, 0x85f6, 0x8604, 0x8609, 0x8605, 0x860c, 0x85fd, 0x8819, + 0x8810, 0x8811, 0x8817, 0x8813, 0x8816, 0x8963, 0x8966, 0x89b9, + 0x89f7, 0x8b60, 0x8b6a, 0x8b5d, 0x8b68, 0x8b63, + /* 0x6a */ + 0x8b65, 0x8b67, 0x8b6d, 0x8dae, 0x8e86, 0x8e88, 0x8e84, 0x8f59, + 0x8f56, 0x8f57, 0x8f55, 0x8f58, 0x8f5a, 0x908d, 0x9143, 0x9141, + 0x91b7, 0x91b5, 0x91b2, 0x91b3, 0x940b, 0x9413, 0x93fb, 0x9420, + 0x940f, 0x9414, 0x93fe, 0x9415, 0x9410, 0x9428, 0x9419, 0x940d, + 0x93f5, 0x9400, 0x93f7, 0x9407, 0x940e, 0x9416, 0x9412, 0x93fa, + 0x9409, 0x93f8, 0x943c, 0x940a, 0x93ff, 0x93fc, 0x940c, 0x93f6, + 0x9411, 0x9406, 0x95de, 0x95e0, 0x95df, 0x972e, 0x972f, 0x97b9, + 0x97bb, 0x97fd, 0x97fe, 0x9860, 0x9862, 0x9863, 0x985f, 0x98c1, + 0x98c2, 0x9950, 0x994e, 0x9959, 0x994c, 0x994b, 0x9953, 0x9a32, + 0x9a34, 0x9a31, 0x9a2c, 0x9a2a, 0x9a36, 0x9a29, 0x9a2e, 0x9a38, + 0x9a2d, 0x9ac7, 0x9aca, 0x9ac6, 0x9b10, 0x9b12, 0x9b11, 0x9c0b, + 0x9c08, 0x9bf7, 0x9c05, 0x9c12, 0x9bf8, 0x9c40, + /* 0x6b */ + 0x9c07, 0x9c0e, 0x9c06, 0x9c17, 0x9c14, 0x9c09, 0x9d9f, 0x9d99, + 0x9da4, 0x9d9d, 0x9d92, 0x9d98, 0x9d90, 0x9d9b, 0x9da0, 0x9d94, + 0x9d9c, 0x9daa, 0x9d97, 0x9da1, 0x9d9a, 0x9da2, 0x9da8, 0x9d9e, + 0x9da3, 0x9dbf, 0x9da9, 0x9d96, 0x9da6, 0x9da7, 0x9e99, 0x9e9b, + 0x9e9a, 0x9ee5, 0x9ee4, 0x9ee7, 0x9ee6, 0x9f30, 0x9f2e, 0x9f5b, + 0x9f60, 0x9f5e, 0x9f5d, 0x9f59, 0x9f91, 0x513a, 0x5139, 0x5298, + 0x5297, 0x56c3, 0x56bd, 0x56be, 0x5b48, 0x5b47, 0x5dcb, 0x5dcf, + 0x5ef1, 0x61fd, 0x651b, 0x6b02, 0x6afc, 0x6b03, 0x6af8, 0x6b00, + 0x7043, 0x7044, 0x704a, 0x7048, 0x7049, 0x7045, 0x7046, 0x721d, + 0x721a, 0x7219, 0x737e, 0x7517, 0x766a, 0x77d0, 0x792d, 0x7931, + 0x792f, 0x7c54, 0x7c53, 0x7cf2, 0x7e8a, 0x7e87, 0x7e88, 0x7e8b, + 0x7e86, 0x7e8d, 0x7f4d, 0x7fbb, 0x8030, 0x81dd, + /* 0x6c */ + 0x8618, 0x862a, 0x8626, 0x861f, 0x8623, 0x861c, 0x8619, 0x8627, + 0x862e, 0x8621, 0x8620, 0x8629, 0x861e, 0x8625, 0x8829, 0x881d, + 0x881b, 0x8820, 0x8824, 0x881c, 0x882b, 0x884a, 0x896d, 0x8969, + 0x896e, 0x896b, 0x89fa, 0x8b79, 0x8b78, 0x8b45, 0x8b7a, 0x8b7b, + 0x8d10, 0x8d14, 0x8daf, 0x8e8e, 0x8e8c, 0x8f5e, 0x8f5b, 0x8f5d, + 0x9146, 0x9144, 0x9145, 0x91b9, 0x943f, 0x943b, 0x9436, 0x9429, + 0x943d, 0x9430, 0x9439, 0x942a, 0x9437, 0x942c, 0x9440, 0x9431, + 0x95e5, 0x95e4, 0x95e3, 0x9735, 0x973a, 0x97bf, 0x97e1, 0x9864, + 0x98c9, 0x98c6, 0x98c0, 0x9958, 0x9956, 0x9a39, 0x9a3d, 0x9a46, + 0x9a44, 0x9a42, 0x9a41, 0x9a3a, 0x9a3f, 0x9acd, 0x9b15, 0x9b17, + 0x9b18, 0x9b16, 0x9b3a, 0x9b52, 0x9c2b, 0x9c1d, 0x9c1c, 0x9c2c, + 0x9c23, 0x9c28, 0x9c29, 0x9c24, 0x9c21, 0x9db7, + /* 0x6d */ + 0x9db6, 0x9dbc, 0x9dc1, 0x9dc7, 0x9dca, 0x9dcf, 0x9dbe, 0x9dc5, + 0x9dc3, 0x9dbb, 0x9db5, 0x9dce, 0x9db9, 0x9dba, 0x9dac, 0x9dc8, + 0x9db1, 0x9dad, 0x9dcc, 0x9db3, 0x9dcd, 0x9db2, 0x9e7a, 0x9e9c, + 0x9eeb, 0x9eee, 0x9eed, 0x9f1b, 0x9f18, 0x9f1a, 0x9f31, 0x9f4e, + 0x9f65, 0x9f64, 0x9f92, 0x4eb9, 0x56c6, 0x56c5, 0x56cb, 0x5971, + 0x5b4b, 0x5b4c, 0x5dd5, 0x5dd1, 0x5ef2, 0x6521, 0x6520, 0x6526, + 0x6522, 0x6b0b, 0x6b08, 0x6b09, 0x6c0d, 0x7055, 0x7056, 0x7057, + 0x7052, 0x721e, 0x721f, 0x72a9, 0x737f, 0x74d8, 0x74d5, 0x74d9, + 0x74d7, 0x766d, 0x76ad, 0x7935, 0x79b4, 0x7a70, 0x7a71, 0x7c57, + 0x7c5c, 0x7c59, 0x7c5b, 0x7c5a, 0x7cf4, 0x7cf1, 0x7e91, 0x7f4f, + 0x7f87, 0x81de, 0x826b, 0x8634, 0x8635, 0x8633, 0x862c, 0x8632, + 0x8636, 0x882c, 0x8828, 0x8826, 0x882a, 0x8825, + /* 0x6e */ + 0x8971, 0x89bf, 0x89be, 0x89fb, 0x8b7e, 0x8b84, 0x8b82, 0x8b86, + 0x8b85, 0x8b7f, 0x8d15, 0x8e95, 0x8e94, 0x8e9a, 0x8e92, 0x8e90, + 0x8e96, 0x8e97, 0x8f60, 0x8f62, 0x9147, 0x944c, 0x9450, 0x944a, + 0x944b, 0x944f, 0x9447, 0x9445, 0x9448, 0x9449, 0x9446, 0x973f, + 0x97e3, 0x986a, 0x9869, 0x98cb, 0x9954, 0x995b, 0x9a4e, 0x9a53, + 0x9a54, 0x9a4c, 0x9a4f, 0x9a48, 0x9a4a, 0x9a49, 0x9a52, 0x9a50, + 0x9ad0, 0x9b19, 0x9b2b, 0x9b3b, 0x9b56, 0x9b55, 0x9c46, 0x9c48, + 0x9c3f, 0x9c44, 0x9c39, 0x9c33, 0x9c41, 0x9c3c, 0x9c37, 0x9c34, + 0x9c32, 0x9c3d, 0x9c36, 0x9ddb, 0x9dd2, 0x9dde, 0x9dda, 0x9dcb, + 0x9dd0, 0x9ddc, 0x9dd1, 0x9ddf, 0x9de9, 0x9dd9, 0x9dd8, 0x9dd6, + 0x9df5, 0x9dd5, 0x9ddd, 0x9eb6, 0x9ef0, 0x9f35, 0x9f33, 0x9f32, + 0x9f42, 0x9f6b, 0x9f95, 0x9fa2, 0x513d, 0x5299, + /* 0x6f */ + 0x58e8, 0x58e7, 0x5972, 0x5b4d, 0x5dd8, 0x882f, 0x5f4f, 0x6201, + 0x6203, 0x6204, 0x6529, 0x6525, 0x6596, 0x66eb, 0x6b11, 0x6b12, + 0x6b0f, 0x6bca, 0x705b, 0x705a, 0x7222, 0x7382, 0x7381, 0x7383, + 0x7670, 0x77d4, 0x7c67, 0x7c66, 0x7e95, 0x826c, 0x863a, 0x8640, + 0x8639, 0x863c, 0x8631, 0x863b, 0x863e, 0x8830, 0x8832, 0x882e, + 0x8833, 0x8976, 0x8974, 0x8973, 0x89fe, 0x8b8c, 0x8b8e, 0x8b8b, + 0x8b88, 0x8c45, 0x8d19, 0x8e98, 0x8f64, 0x8f63, 0x91bc, 0x9462, + 0x9455, 0x945d, 0x9457, 0x945e, 0x97c4, 0x97c5, 0x9800, 0x9a56, + 0x9a59, 0x9b1e, 0x9b1f, 0x9b20, 0x9c52, 0x9c58, 0x9c50, 0x9c4a, + 0x9c4d, 0x9c4b, 0x9c55, 0x9c59, 0x9c4c, 0x9c4e, 0x9dfb, 0x9df7, + 0x9def, 0x9de3, 0x9deb, 0x9df8, 0x9de4, 0x9df6, 0x9de1, 0x9dee, + 0x9de6, 0x9df2, 0x9df0, 0x9de2, 0x9dec, 0x9df4, + /* 0x70 */ + 0x9df3, 0x9de8, 0x9ded, 0x9ec2, 0x9ed0, 0x9ef2, 0x9ef3, 0x9f06, + 0x9f1c, 0x9f38, 0x9f37, 0x9f36, 0x9f43, 0x9f4f, 0x9f71, 0x9f70, + 0x9f6e, 0x9f6f, 0x56d3, 0x56cd, 0x5b4e, 0x5c6d, 0x652d, 0x66ed, + 0x66ee, 0x6b13, 0x705f, 0x7061, 0x705d, 0x7060, 0x7223, 0x74db, + 0x74e5, 0x77d5, 0x7938, 0x79b7, 0x79b6, 0x7c6a, 0x7e97, 0x7f89, + 0x826d, 0x8643, 0x8838, 0x8837, 0x8835, 0x884b, 0x8b94, 0x8b95, + 0x8e9e, 0x8e9f, 0x8ea0, 0x8e9d, 0x91be, 0x91bd, 0x91c2, 0x946b, + 0x9468, 0x9469, 0x96e5, 0x9746, 0x9743, 0x9747, 0x97c7, 0x97e5, + 0x9a5e, 0x9ad5, 0x9b59, 0x9c63, 0x9c67, 0x9c66, 0x9c62, 0x9c5e, + 0x9c60, 0x9e02, 0x9dfe, 0x9e07, 0x9e03, 0x9e06, 0x9e05, 0x9e00, + 0x9e01, 0x9e09, 0x9dff, 0x9dfd, 0x9e04, 0x9ea0, 0x9f1e, 0x9f46, + 0x9f74, 0x9f75, 0x9f76, 0x56d4, 0x652e, 0x65b8, + /* 0x71 */ + 0x6b18, 0x6b19, 0x6b17, 0x6b1a, 0x7062, 0x7226, 0x72aa, 0x77d8, + 0x77d9, 0x7939, 0x7c69, 0x7c6b, 0x7cf6, 0x7e9a, 0x7e98, 0x7e9b, + 0x7e99, 0x81e0, 0x81e1, 0x8646, 0x8647, 0x8648, 0x8979, 0x897a, + 0x897c, 0x897b, 0x89ff, 0x8b98, 0x8b99, 0x8ea5, 0x8ea4, 0x8ea3, + 0x946e, 0x946d, 0x946f, 0x9471, 0x9473, 0x9749, 0x9872, 0x995f, + 0x9c68, 0x9c6e, 0x9c6d, 0x9e0b, 0x9e0d, 0x9e10, 0x9e0f, 0x9e12, + 0x9e11, 0x9ea1, 0x9ef5, 0x9f09, 0x9f47, 0x9f78, 0x9f7b, 0x9f7a, + 0x9f79, 0x571e, 0x7066, 0x7c6f, 0x883c, 0x8db2, 0x8ea6, 0x91c3, + 0x9474, 0x9478, 0x9476, 0x9475, 0x9a60, 0x9b2e, 0x9c74, 0x9c73, + 0x9c71, 0x9c75, 0x9e14, 0x9e13, 0x9ef6, 0x9f0a, 0x9fa4, 0x7068, + 0x7065, 0x7cf7, 0x866a, 0x883e, 0x883d, 0x883f, 0x8b9e, 0x8c9c, + 0x8ea9, 0x8ec9, 0x974b, 0x9873, 0x9874, 0x98cc, + /* 0x72 */ + 0x9961, 0x99ab, 0x9a64, 0x9a66, 0x9a67, 0x9b24, 0x9e15, 0x9e17, + 0x9f48, 0x6207, 0x6b1e, 0x7227, 0x864c, 0x8ea8, 0x9482, 0x9480, + 0x9481, 0x9a69, 0x9a68, 0x9e19, 0x864b, 0x8b9f, 0x9483, 0x9c79, + 0x9eb7, 0x7675, 0x9a6b, 0x9c7a, 0x9e1d, 0x7069, 0x706a, 0x7229, + 0x9ea4, 0x9f7e, 0x9f49, 0x9f98, +}; + +static int +cns11643_2_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x21 && c1 <= 0x72)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + unsigned short wc = 0xfffd; + { + if (i < 7650) + wc = cns11643_2_2uni_page21[i]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + diff --git a/libs/libiconv/lib/cns11643_3.h b/libs/libiconv/lib/cns11643_3.h new file mode 100644 index 00000000..e2630131 --- /dev/null +++ b/libs/libiconv/lib/cns11643_3.h @@ -0,0 +1,974 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CNS 11643-1992 plane 3 + */ + +static const unsigned short cns11643_3_2uni_page21[6148] = { + /* 0x21 */ + 0x1a28, 0x1a36, 0x1a3f, 0x1a85, 0x1a05, 0x1a04, 0x1d82, 0x1d96, + 0x1f38, 0x1f69, 0x1fb6, 0x1a2a, 0x1a87, 0x1a49, 0x1de2, 0x1a46, + 0x1a8f, 0x1abc, 0x1abe, 0x1d66, 0x1de3, 0x1e04, 0x1e9c, 0x1f44, + 0x2502, 0x250a, 0x2780, 0x29db, 0x2a7a, 0x2a7f, 0x2af4, 0x2b50, + 0x2b51, 0x2b61, 0x621d, 0x6d0b, 0x1a63, 0x1a62, 0x1aa3, 0x1d85, + 0x1ac5, 0x1acf, 0x1ace, 0x1acc, 0x1d84, 0x1d86, 0x8517, 0x00c5, + 0x1de4, 0x1e05, 0x1e9e, 0x1e9d, 0x1efd, 0x1f00, 0x1f3a, 0x0139, + 0x1f46, 0x1f5d, 0x1f86, 0x1fb7, 0x0155, 0x1fcc, 0x015b, 0x1fce, + 0x2321, 0x03a2, 0x2a00, 0x2b0c, 0x2e37, 0x2e38, 0x3134, 0x3135, + 0x31e0, 0x0a26, 0x3f8d, 0x1a97, 0x1ae0, 0x0032, 0x6ea9, 0x1ae7, + 0x0033, 0x1ae6, 0x0034, 0x02a2, 0x0031, 0x00b0, 0x22d8, 0x1d8b, + 0x1d8c, 0x1d99, 0x1de5, 0x8550, 0x1e0b, 0x00dc, + /* 0x22 */ + 0x021e, 0x1f04, 0x1f03, 0x1f07, 0x852a, 0x1f1e, 0x1f5f, 0x1f6d, + 0x1f89, 0x1fba, 0x1fd0, 0x0165, 0x1ff6, 0x1ff7, 0x1ff9, 0x0164, + 0x1ff4, 0x021d, 0x0226, 0x2324, 0x2504, 0x2518, 0x2532, 0x2530, + 0x2534, 0x028e, 0x2575, 0x034a, 0x2782, 0x27f9, 0x2814, 0x038b, + 0x03a6, 0x03a4, 0x03a5, 0x03a7, 0x042f, 0x0432, 0x2a81, 0x2a83, + 0x2b0d, 0x2b52, 0x04d4, 0x2bca, 0x2bc7, 0x2e39, 0x05c5, 0x2e4f, + 0x31e7, 0x332f, 0x377a, 0x3839, 0x08ba, 0x08b9, 0x3837, 0x3844, + 0x3845, 0x3f8c, 0x4192, 0x4276, 0x5c93, 0x5c92, 0x14b3, 0x15ba, + 0x1a21, 0x1a20, 0x1a22, 0x1a68, 0x1a89, 0x1a98, 0x1af9, 0x1aef, + 0x003b, 0x003c, 0x1af8, 0x1b06, 0x1b03, 0x1afc, 0x1aee, 0x1b16, + 0x0039, 0x1b28, 0x1b1c, 0x1b07, 0x1b1a, 0x1afa, 0x1b17, 0x1d4a, + 0x00b2, 0x1d72, 0x8515, 0x1db4, 0x1db3, 0x1db2, + /* 0x23 */ + 0x00c7, 0x1de8, 0x002b, 0x1e14, 0x1e0f, 0x1e15, 0x1e18, 0x1ea8, + 0x852c, 0x1f4b, 0x1f4f, 0x013b, 0x1f50, 0x0144, 0x1f8b, 0x0142, + 0x1fbe, 0x015c, 0x1fd2, 0x2016, 0x1fff, 0x0167, 0x2000, 0x0166, + 0x2005, 0x2013, 0x2015, 0x853b, 0x021f, 0x22e3, 0x2335, 0x2336, + 0x2331, 0x2332, 0x24ee, 0x2505, 0x1a54, 0x028f, 0x2536, 0x0290, + 0x02a8, 0x02a4, 0x257a, 0x02a3, 0x2586, 0x033d, 0x034c, 0x2786, + 0x2b53, 0x2818, 0x038c, 0x283d, 0x2878, 0x03a8, 0x03ad, 0x03af, + 0x7746, 0x2880, 0x0429, 0x2a08, 0x0436, 0x0471, 0x0470, 0x046f, + 0x2af5, 0x2b0e, 0x04a9, 0x04aa, 0x04fb, 0x2bd3, 0x2bda, 0x04fc, + 0x2bdb, 0x05ae, 0x2e0f, 0x2e5d, 0x2e5f, 0x2e67, 0x2e57, 0x6b50, + 0x06c3, 0x31eb, 0x31ea, 0x0730, 0x3337, 0x0741, 0x3332, 0x3336, + 0x3722, 0x37ce, 0x088c, 0x3858, 0x3851, 0x3877, + /* 0x24 */ + 0x383c, 0x08bb, 0x385a, 0x7c86, 0x3853, 0x3c6f, 0x3c72, 0x3c6e, + 0x8535, 0x09a1, 0x3c73, 0x3eb1, 0x3eb2, 0x0aa8, 0x3f8f, 0x0aaa, + 0x0aab, 0x0c96, 0x453c, 0x0dc2, 0x4c8d, 0x4c8e, 0x1093, 0x4e7b, + 0x1094, 0x5971, 0x5bb9, 0x5c96, 0x5c9a, 0x15bb, 0x1a24, 0x1a71, + 0x851b, 0x1a9c, 0x1b45, 0x1b4a, 0x1b39, 0x1b37, 0x0043, 0x1b32, + 0x1b42, 0x0042, 0x1b44, 0x1b4b, 0x0044, 0x1b40, 0x1b35, 0x1b31, + 0x1d51, 0x850e, 0x1d50, 0x1d4e, 0x00b3, 0x00b7, 0x1d9d, 0x00c8, + 0x1db5, 0x1db8, 0x1dec, 0x1e23, 0x1e27, 0x1e26, 0x1e1f, 0x1e2b, + 0x1e20, 0x1eb4, 0x1eb3, 0x0118, 0x1f25, 0x1f3b, 0x1f74, 0x0147, + 0x0146, 0x0145, 0x016b, 0x0169, 0x204d, 0x0172, 0x0171, 0x203a, + 0x016c, 0x016f, 0x2044, 0x204c, 0x2023, 0x201a, 0x2032, 0x204b, + 0x2021, 0x0173, 0x2034, 0x2049, 0x2050, 0x2022, + /* 0x25 */ + 0x203f, 0x2051, 0x205a, 0x202f, 0x0176, 0x22e9, 0x22f2, 0x22f3, + 0x22ef, 0x22ed, 0x22ec, 0x22e6, 0x2348, 0x0227, 0x2344, 0x233f, + 0x233c, 0x2353, 0x2356, 0x0230, 0x235f, 0x2343, 0x2358, 0x2357, + 0x0229, 0x022a, 0x022f, 0x2346, 0x022c, 0x233d, 0x022d, 0x2342, + 0x2354, 0x2355, 0x24f1, 0x24f2, 0x24f0, 0x250b, 0x6aa6, 0x22f1, + 0x253d, 0x0293, 0x2594, 0x258c, 0x02ad, 0x259c, 0x02ac, 0x02ab, + 0x259f, 0x02a9, 0x259b, 0x02ae, 0x2589, 0x259a, 0x02aa, 0x3188, + 0x034e, 0x278d, 0x0350, 0x27fe, 0x27ff, 0x27fd, 0x282b, 0x03b2, + 0x2884, 0x288e, 0x289c, 0x03b5, 0x03b6, 0x2885, 0x29f5, 0x2a09, + 0x0439, 0x043b, 0x2a0b, 0x0472, 0x2a92, 0x2a90, 0x2b03, 0x04ac, + 0x2b1e, 0x2b63, 0x0508, 0x2be7, 0x2bfe, 0x2be6, 0x2bdc, 0x2bce, + 0x0503, 0x2bfc, 0x2bdf, 0x2bec, 0x2bf6, 0x79d7, + /* 0x26 */ + 0x2bf2, 0x2bf0, 0x2bf9, 0x050b, 0x2e13, 0x05af, 0x85b2, 0x2e3b, + 0x2e3c, 0x2e82, 0x05ce, 0x05cb, 0x05cc, 0x2e78, 0x2e8b, 0x05cd, + 0x2e9e, 0x2ea5, 0x2e9b, 0x2e9c, 0x2e99, 0x2e8d, 0x2e85, 0x2e9d, + 0x2e75, 0x0680, 0x06af, 0x06d3, 0x31f6, 0x06d5, 0x06d4, 0x06d7, + 0x32f5, 0x335b, 0x0742, 0x3354, 0x3352, 0x0744, 0x3358, 0x3344, + 0x334a, 0x3361, 0x08c6, 0x387f, 0x3891, 0x389e, 0x08c0, 0x386e, + 0x387c, 0x389f, 0x3875, 0x08be, 0x3856, 0x38a2, 0x3879, 0x08ca, + 0x38a1, 0x08c4, 0x38aa, 0x38a0, 0x08c2, 0x3c79, 0x3c77, 0x3c7e, + 0x09a4, 0x3c75, 0x3c7b, 0x3e64, 0x0a29, 0x3ebb, 0x3ebc, 0x3ec7, + 0x3eb9, 0x3ebe, 0x3eb6, 0x0a60, 0x0a5e, 0x3f98, 0x0aad, 0x0aae, + 0x0aac, 0x0b57, 0x4193, 0x4280, 0x0bdd, 0x4283, 0x42c0, 0x42c1, + 0x0c0e, 0x0c97, 0x43f4, 0x43f5, 0x0d27, 0x46cc, + /* 0x27 */ + 0x46cd, 0x48fa, 0x4c9f, 0x4c91, 0x4c97, 0x4c94, 0x1095, 0x4e86, + 0x4e8c, 0x868f, 0x4e95, 0x1098, 0x526c, 0x119d, 0x5bb5, 0x5bbe, + 0x5bc7, 0x148a, 0x5bc1, 0x5ca9, 0x5ca4, 0x14b5, 0x14b6, 0x14b7, + 0x5ca8, 0x6227, 0x6226, 0x622b, 0x6233, 0x6234, 0x6229, 0x1a3d, + 0x0028, 0x1a9d, 0x1b93, 0x1b8a, 0x004d, 0x0049, 0x1b6d, 0x1b8e, + 0x1ba0, 0x1ba2, 0x1ba1, 0x1b9f, 0x1ba3, 0x6f09, 0x1b72, 0x0051, + 0x1b8c, 0x1d56, 0x850f, 0x8511, 0x1d90, 0x00cb, 0x00ca, 0x00cc, + 0x1ded, 0x1dfe, 0x1e2f, 0x71ec, 0x1e3c, 0x1e34, 0x1e39, 0x1eb9, + 0x1eb5, 0x1ebf, 0x1f55, 0x013d, 0x1f76, 0x1f7a, 0x1f93, 0x0148, + 0x1fc1, 0x1fc2, 0x1fd5, 0x2085, 0x0178, 0x205f, 0x2093, 0x2089, + 0x2079, 0x6afe, 0x208f, 0x2069, 0x206d, 0x017a, 0x2094, 0x206a, + 0x208a, 0x0177, 0x22fd, 0x22fb, 0x22f8, 0x0221, + /* 0x28 */ + 0x22fc, 0x22f6, 0x2365, 0x2381, 0x2363, 0x2367, 0x0231, 0x236e, + 0x2378, 0x237f, 0x0233, 0x0234, 0x24f3, 0x254b, 0x254c, 0x02c1, + 0x02b0, 0x02b4, 0x25ad, 0x02b8, 0x25c4, 0x02bc, 0x25c2, 0x25b0, + 0x02bf, 0x02b5, 0x02b1, 0x02bd, 0x25bf, 0x02bb, 0x25c9, 0x25b8, + 0x25ac, 0x02b3, 0x02b6, 0x02ba, 0x25b7, 0x25d7, 0x02b7, 0x2760, + 0x0340, 0x2796, 0x279e, 0x2794, 0x279f, 0x279d, 0x0352, 0x2800, + 0x2819, 0x0390, 0x0391, 0x2849, 0x284a, 0x03be, 0x28bb, 0x28c1, + 0x03c0, 0x03c1, 0x03b9, 0x28b9, 0x289e, 0x28b4, 0x28ba, 0x29f6, + 0x2a13, 0x2a12, 0x2a77, 0x0479, 0x2a98, 0x047b, 0x2a99, 0x2a9d, + 0x2af8, 0x04a0, 0x2af9, 0x0029, 0x2b06, 0x2b21, 0x04ae, 0x2b25, + 0x2b55, 0x04cd, 0x04cb, 0x04d9, 0x2b84, 0x2b83, 0x2c30, 0x2c07, + 0x050c, 0x2c36, 0x0501, 0x0505, 0x0502, 0x2be9, + /* 0x29 */ + 0x2c3d, 0x2c08, 0x0513, 0x0511, 0x2eba, 0x2eb2, 0x05e4, 0x2eb7, + 0x2ee4, 0x2ea7, 0x05da, 0x05d5, 0x05d3, 0x2ed5, 0x2ee1, 0x2edd, + 0x2ea6, 0x2ec1, 0x2ec5, 0x2ec0, 0x2edf, 0x2ee0, 0x2ede, 0x05d6, + 0x3189, 0x06b4, 0x31a6, 0x31ba, 0x06d9, 0x31ff, 0x06d8, 0x3217, + 0x3218, 0x3201, 0x31fe, 0x0733, 0x330c, 0x0748, 0x336b, 0x3396, + 0x3382, 0x338a, 0x0747, 0x33a3, 0x074b, 0x33a2, 0x338f, 0x074a, + 0x33f9, 0x3380, 0x3726, 0x3727, 0x3768, 0x3769, 0x085a, 0x3781, + 0x37b4, 0x37d1, 0x088e, 0x08b4, 0x381c, 0x08cd, 0x08cc, 0x08cf, + 0x08cb, 0x08ce, 0x3897, 0x386c, 0x38df, 0x08d2, 0x38ea, 0x08d1, + 0x38e4, 0x38d8, 0x38b2, 0x38ce, 0x38c8, 0x09a6, 0x3c8b, 0x3c88, + 0x3c90, 0x3c8f, 0x09aa, 0x3c87, 0x3c89, 0x3c8d, 0x3c81, 0x09a8, + 0x3c8c, 0x0a13, 0x0a1a, 0x3e40, 0x0a1d, 0x0a1e, + /* 0x2a */ + 0x3e65, 0x3e66, 0x3e68, 0x0a65, 0x0a66, 0x3ecd, 0x3ed3, 0x3edb, + 0x0a64, 0x3ecf, 0x3fa7, 0x3fa3, 0x3f9e, 0x0ab0, 0x3faf, 0x0ab3, + 0x0ab5, 0x3faa, 0x3f9c, 0x0b19, 0x4142, 0x4144, 0x413b, 0x4141, + 0x783f, 0x419b, 0x419e, 0x0b75, 0x45c4, 0x45c3, 0x45c6, 0x0d2b, + 0x0d2c, 0x45c7, 0x0d2d, 0x45ca, 0x802e, 0x0dc3, 0x46cf, 0x4876, + 0x4874, 0x48ff, 0x48fc, 0x00ba, 0x0f50, 0x4b59, 0x4ca8, 0x0fd3, + 0x0fd0, 0x4cb0, 0x0fdc, 0x4cb3, 0x0fd2, 0x4ca4, 0x4cb6, 0x4ca7, + 0x4cac, 0x0fdb, 0x4ca6, 0x1f67, 0x4e0e, 0x4ec4, 0x4f3e, 0x4e9c, + 0x10a5, 0x109f, 0x109a, 0x109c, 0x10a2, 0x4eaa, 0x109b, 0x4ec9, + 0x10a3, 0x109d, 0x4ea6, 0x4eb2, 0x1188, 0x121a, 0x148d, 0x5bcc, + 0x5bd9, 0x5bca, 0x5bd8, 0x5bcf, 0x5cb7, 0x14b8, 0x5cad, 0x5cb9, + 0x6237, 0x15c3, 0x6241, 0x623e, 0x62b6, 0x6351, + /* 0x2b */ + 0x6363, 0x1a57, 0x1a79, 0x1ab2, 0x1ab0, 0x1aaf, 0x1ab1, 0x1bd2, + 0x1bd5, 0x005d, 0x1bbe, 0x1bb8, 0x1bb0, 0x1bb1, 0x1bc8, 0x005a, + 0x0057, 0x1bc6, 0x1bcc, 0x1be5, 0x1be3, 0x1bb4, 0x1d6a, 0x00b8, + 0x1d9f, 0x00c2, 0x1dc1, 0x00cf, 0x1dc2, 0x1dc3, 0x1e45, 0x1e48, + 0x00e7, 0x00e9, 0x1e4f, 0x1052, 0x00e8, 0x1ec5, 0x1eca, 0x1ec4, + 0x1f27, 0x1f58, 0x1f7d, 0x014a, 0x1fdd, 0x1fdc, 0x1fda, 0x1fd9, + 0x20b9, 0x0180, 0x20d0, 0x20b4, 0x20ca, 0x0187, 0x20a3, 0x20da, + 0x20a4, 0x0184, 0x20b2, 0x209e, 0x209f, 0x20b5, 0x0182, 0x0181, + 0x20cd, 0x0183, 0x20cc, 0x0222, 0x2300, 0x23ac, 0x2391, 0x238e, + 0x238d, 0x2392, 0x23a1, 0x2390, 0x23a6, 0x23a8, 0x023b, 0x239c, + 0x2396, 0x23a7, 0x023a, 0x0238, 0x0239, 0x0236, 0x24f5, 0x0285, + 0x2509, 0x2508, 0x0854, 0x2552, 0x029a, 0x02c4, + /* 0x2c */ + 0x25df, 0x02c5, 0x25eb, 0x25ef, 0x25f0, 0x25d5, 0x260d, 0x2604, + 0x25f9, 0x2602, 0x25f8, 0x25e2, 0x25d9, 0x25e7, 0x276a, 0x0354, + 0x0355, 0x27ab, 0x0356, 0x281b, 0x282f, 0x0396, 0x323c, 0x0395, + 0x0394, 0x03c4, 0x28d1, 0x28dc, 0x28e6, 0x28e1, 0x28cd, 0x857a, + 0x28e2, 0x28dd, 0x28e5, 0x29fb, 0x29fa, 0x2a1e, 0x0444, 0x2aa1, + 0x047d, 0x047e, 0x2afc, 0x2afb, 0x2b2f, 0x04b2, 0x04b6, 0x2b66, + 0x8599, 0x04dc, 0x04df, 0x2c5c, 0x0528, 0x2c4e, 0x2c51, 0x0519, + 0x0510, 0x2c23, 0x2c31, 0x2c7c, 0x2c52, 0x052c, 0x2c60, 0x2c4a, + 0x2c61, 0x051b, 0x2e18, 0x05c2, 0x05ef, 0x05e3, 0x05e5, 0x05ea, + 0x05e6, 0x05ee, 0x2f1f, 0x2f17, 0x2eea, 0x2f21, 0x2f04, 0x2f05, + 0x05e8, 0x3131, 0x3144, 0x3140, 0x0685, 0x3142, 0x31be, 0x06e0, + 0x3229, 0x321b, 0x06dd, 0x3223, 0x322c, 0x321a, + /* 0x2d */ + 0x3230, 0x323b, 0x321e, 0x3237, 0x3238, 0x06e1, 0x330e, 0x0751, + 0x0755, 0x33e8, 0x33d6, 0x0752, 0x33c7, 0x33bc, 0x3452, 0x33bf, + 0x33d5, 0x33fe, 0x4f63, 0x33fb, 0x85df, 0x33b1, 0x3401, 0x3405, + 0x3400, 0x33d7, 0x0c9e, 0x372a, 0x376b, 0x0852, 0x085e, 0x0860, + 0x085f, 0x37e1, 0x0892, 0x08d6, 0x3923, 0x38ff, 0x3914, 0x3905, + 0x3913, 0x3906, 0x3921, 0x08de, 0x3915, 0x38af, 0x38f4, 0x3902, + 0x3945, 0x85fe, 0x3926, 0x08d9, 0x3944, 0x08dd, 0x3924, 0x3ca5, + 0x09ac, 0x3ca3, 0x09b0, 0x3ca2, 0x3cbb, 0x3ca0, 0x3caa, 0x09af, + 0x09ae, 0x3ca8, 0x3cb6, 0x3cb2, 0x3ca7, 0x09ad, 0x09ab, 0x3cb9, + 0x3e2e, 0x0a16, 0x3e3c, 0x0a30, 0x3e6d, 0x0a33, 0x0a31, 0x3ee7, + 0x3eed, 0x0a6e, 0x3eec, 0x3ee5, 0x3ee2, 0x0ab1, 0x3fc4, 0x3fbd, + 0x3fcf, 0x3fc9, 0x3fc1, 0x3fd0, 0x0ab7, 0x3fce, + /* 0x2e */ + 0x40ed, 0x40eb, 0x0b1a, 0x40ef, 0x4149, 0x4150, 0x4146, 0x414a, + 0x0b59, 0x414d, 0x41a6, 0x0b7a, 0x0b78, 0x0b7b, 0x41a8, 0x0bde, + 0x0bec, 0x42c7, 0x42ff, 0x0c1e, 0x42fd, 0x43e6, 0x440a, 0x0c9b, + 0x4404, 0x440b, 0x4407, 0x0c9d, 0x4415, 0x4408, 0x0cfd, 0x45d3, + 0x45d4, 0x45d0, 0x45d7, 0x467c, 0x0d94, 0x0d93, 0x467d, 0x4683, + 0x4682, 0x0dc6, 0x46d4, 0x46d5, 0x46d3, 0x46d0, 0x46d2, 0x46fe, + 0x46fc, 0x4877, 0x487c, 0x487b, 0x0eb8, 0x866a, 0x0eb7, 0x0eb9, + 0x0f53, 0x7f33, 0x0f52, 0x0f51, 0x4b8f, 0x4cd3, 0x0fe3, 0x4ccb, + 0x4cd2, 0x0fe2, 0x4d09, 0x4ce2, 0x4cdf, 0x4cc6, 0x1063, 0x4e24, + 0x4ef7, 0x4ed8, 0x4edd, 0x10aa, 0x10a6, 0x4ef8, 0x4efc, 0x10a8, + 0x10a9, 0x4ee9, 0x10ab, 0x4eee, 0x10ac, 0x4ed0, 0x4f0e, 0x4ee2, + 0x4f0b, 0x4efd, 0x1d79, 0x5276, 0x119e, 0x5278, + /* 0x2f */ + 0x119f, 0x11a0, 0x5275, 0x527d, 0x120f, 0x5442, 0x5466, 0x121c, + 0x558c, 0x5605, 0x12ae, 0x5606, 0x12b0, 0x589f, 0x13d4, 0x5bf1, + 0x5be7, 0x5be9, 0x5bef, 0x5cc2, 0x5cbc, 0x14bb, 0x5cc6, 0x5cc0, + 0x14c1, 0x14c2, 0x5ccd, 0x5cc9, 0x14be, 0x5cc4, 0x14e5, 0x6181, + 0x15c6, 0x68ec, 0x1c32, 0x1bf9, 0x1c1d, 0x1bff, 0x1c04, 0x1bf0, + 0x1c03, 0x122e, 0x1c02, 0x1bfc, 0x1bf2, 0x1c24, 0x1c08, 0x1c36, + 0x1c2e, 0x0065, 0x1c10, 0x1c38, 0x1c39, 0x1bfd, 0x1c56, 0x1bfb, + 0x1da3, 0x1da6, 0x1da1, 0x00d1, 0x00d0, 0x1dc7, 0x1dc9, 0x1e60, + 0x1e64, 0x1e59, 0x1e65, 0x1e67, 0x1e57, 0x1e63, 0x00ee, 0x1e53, + 0x00ef, 0x1ecf, 0x011e, 0x1ece, 0x1ed0, 0x1ed1, 0x1ecc, 0x014b, + 0x014d, 0x0156, 0x210d, 0x20f4, 0x0192, 0x2113, 0x20ef, 0x20f5, + 0x20f9, 0x2102, 0x2100, 0x0193, 0x0190, 0x2118, + /* 0x30 */ + 0x20f0, 0x20f6, 0x8541, 0x0197, 0x2119, 0x0223, 0x2305, 0x23c9, + 0x023f, 0x23b7, 0x23cd, 0x0243, 0x0242, 0x0244, 0x23be, 0x23bb, + 0x0245, 0x23db, 0x23c8, 0x23c4, 0x23c5, 0x23d1, 0x23ca, 0x23c0, + 0x02d9, 0x02de, 0x2621, 0x262a, 0x02cf, 0x261d, 0x02cd, 0x260b, + 0x02dd, 0x02ce, 0x02d3, 0x02d6, 0x2622, 0x02dc, 0x02d1, 0x2624, + 0x02d0, 0x2614, 0x2631, 0x02d5, 0x262f, 0x261a, 0x2612, 0x02d4, + 0x02db, 0x2626, 0x762e, 0x0343, 0x27bc, 0x27bb, 0x27b7, 0x2805, + 0x2806, 0x2852, 0x2853, 0x03cd, 0x03d1, 0x28fa, 0x28eb, 0x03ca, + 0x28f3, 0x28f5, 0x28e9, 0x28ef, 0x03d4, 0x2a2a, 0x2a30, 0x2a2e, + 0x2a2c, 0x2a2f, 0x2aaf, 0x2aa9, 0x0486, 0x2afd, 0x2b32, 0x2b8e, + 0x2b93, 0x2b8f, 0x2c4f, 0x2c99, 0x0533, 0x2c7e, 0x0537, 0x2c74, + 0x2c4b, 0x2c73, 0x2c75, 0x052a, 0x051f, 0x2c56, + /* 0x31 */ + 0x2ca9, 0x2c8b, 0x2ca6, 0x0539, 0x2c93, 0x2cae, 0x2c9e, 0x2ca7, + 0x2e45, 0x05f2, 0x05f8, 0x2f2e, 0x05f7, 0x2f52, 0x2f30, 0x2f5b, + 0x05f4, 0x2f19, 0x2f1b, 0x05f1, 0x2f31, 0x2f5d, 0x2f37, 0x2f35, + 0x2f53, 0x05f5, 0x2f5c, 0x2f3f, 0x314b, 0x0687, 0x0f69, 0x318b, + 0x06b6, 0x319a, 0x3250, 0x3246, 0x324e, 0x3240, 0x06e9, 0x324b, + 0x3248, 0x06eb, 0x3260, 0x3244, 0x324d, 0x0734, 0x3437, 0x3424, + 0x0762, 0x075c, 0x341b, 0x3436, 0x0760, 0x342c, 0x3419, 0x3456, + 0x3447, 0x343e, 0x341e, 0x85e1, 0x3415, 0x3422, 0x3427, 0x3459, + 0x3458, 0x3455, 0x3430, 0x3423, 0x372e, 0x372b, 0x3730, 0x376c, + 0x0861, 0x378b, 0x087f, 0x37e9, 0x37ea, 0x37e5, 0x396b, 0x08e5, + 0x08e6, 0x3973, 0x3957, 0x08e9, 0x08f3, 0x395d, 0x3956, 0x398f, + 0x395b, 0x391c, 0x399a, 0x399b, 0x3999, 0x08ee, + /* 0x32 */ + 0x3981, 0x3971, 0x08ed, 0x08ec, 0x3972, 0x395c, 0x3996, 0x3cc4, + 0x3cdb, 0x3ccc, 0x3cd0, 0x3ce3, 0x3cdf, 0x09b3, 0x3cd6, 0x3cee, + 0x3cd5, 0x09b5, 0x0a27, 0x0a35, 0x0a36, 0x3e7a, 0x0a71, 0x3ef5, + 0x3f02, 0x0ab8, 0x0ac2, 0x3fe2, 0x3fec, 0x3fd5, 0x3ff9, 0x3fdf, + 0x3fe6, 0x0ac8, 0x0ac0, 0x0ac1, 0x0ac4, 0x3fe4, 0x3fe1, 0x40f3, + 0x0b1f, 0x0b1c, 0x0b1d, 0x0b4d, 0x4156, 0x4155, 0x4158, 0x4157, + 0x415e, 0x41c3, 0x0b87, 0x0b82, 0x41b4, 0x0b7d, 0x41b1, 0x0bdf, + 0x0c00, 0x42cb, 0x42cc, 0x432a, 0x0c20, 0x4316, 0x430f, 0x0c22, + 0x0c24, 0x433f, 0x432b, 0x430e, 0x4324, 0x0c21, 0x4321, 0x4318, + 0x43dd, 0x0ca4, 0x0ca5, 0x4424, 0x4436, 0x0d01, 0x4558, 0x4559, + 0x0d03, 0x4562, 0x45da, 0x45d9, 0x0d37, 0x45e1, 0x45e5, 0x45e8, + 0x45db, 0x0d38, 0x45e2, 0x45f0, 0x0d99, 0x0d98, + /* 0x33 */ + 0x0d97, 0x0dc9, 0x46da, 0x46dd, 0x0dc7, 0x46db, 0x46dc, 0x0dd9, + 0x0ddb, 0x470d, 0x470b, 0x4714, 0x488e, 0x4886, 0x0e7b, 0x4887, + 0x4883, 0x488b, 0x0e7c, 0x0ebd, 0x0ebc, 0x0ec3, 0x4924, 0x0ec1, + 0x0ebf, 0x0ec4, 0x4925, 0x4b62, 0x4b93, 0x4b99, 0x4b97, 0x0f7e, + 0x0f7f, 0x4bc4, 0x4bc6, 0x4c0a, 0x0fb4, 0x0fb3, 0x4c40, 0x4c3c, + 0x4c3b, 0x4cf6, 0x4cff, 0x4cee, 0x4d04, 0x4d03, 0x4d07, 0x8683, + 0x0fe6, 0x4cf7, 0x1059, 0x105a, 0x4e2d, 0x1064, 0x4e27, 0x4e29, + 0x4f1f, 0x4f57, 0x10b4, 0x10b9, 0x10b7, 0x10b5, 0x4f21, 0x10c1, + 0x10b1, 0x4f18, 0x4f58, 0x10b3, 0x10ba, 0x118c, 0x118b, 0x118d, + 0x5284, 0x529f, 0x529b, 0x5289, 0x52a6, 0x5292, 0x528f, 0x52a0, + 0x544f, 0x5478, 0x547a, 0x546e, 0x547b, 0x5484, 0x5473, 0x1278, + 0x1277, 0x560d, 0x560b, 0x5619, 0x12b2, 0x13d6, + /* 0x34 */ + 0x5ad0, 0x1445, 0x1492, 0x1495, 0x5bf9, 0x5c09, 0x5c08, 0x14c6, + 0x5cde, 0x5d51, 0x14e7, 0x14e8, 0x5ddb, 0x5ddf, 0x5dde, 0x5dd6, + 0x5de0, 0x6185, 0x6260, 0x6259, 0x15cb, 0x6256, 0x15cd, 0x15f1, + 0x62bd, 0x1722, 0x0021, 0x1c42, 0x1c59, 0x006f, 0x1c44, 0x1c66, + 0x1c52, 0x1c54, 0x1c71, 0x1c50, 0x1c7b, 0x1c7c, 0x1c58, 0x0070, + 0x0064, 0x1c79, 0x1c6c, 0x1c78, 0x1da8, 0x1dd1, 0x1dcf, 0x1e68, + 0x1e76, 0x1ed4, 0x012d, 0x1fa0, 0x1fc4, 0x0158, 0x2158, 0x214c, + 0x2168, 0x01a6, 0x2149, 0x01a4, 0x019f, 0x215d, 0x2129, 0x73ae, + 0x2154, 0x2153, 0x01a3, 0x215a, 0x01a0, 0x213a, 0x213f, 0x212b, + 0x23ea, 0x024a, 0x23ef, 0x0247, 0x0248, 0x23dd, 0x23fe, 0x8555, + 0x23de, 0x23e6, 0x0249, 0x23e8, 0x23ff, 0x2403, 0x24f7, 0x34a6, + 0x251f, 0x029e, 0x255b, 0x255d, 0x255e, 0x7537, + /* 0x35 */ + 0x02e8, 0x262b, 0x02ec, 0x263b, 0x02ed, 0x02e6, 0x2661, 0x263a, + 0x266e, 0x264b, 0x266b, 0x02eb, 0x02e7, 0x2645, 0x264e, 0x2668, + 0x263d, 0x2671, 0x263f, 0x266f, 0x2675, 0x02e9, 0x2673, 0x262c, + 0x2659, 0x2654, 0x264f, 0x2663, 0x035c, 0x035d, 0x27c8, 0x0360, + 0x27c3, 0x035b, 0x285b, 0x2861, 0x0399, 0x2921, 0x290a, 0x2909, + 0x03d8, 0x292c, 0x2908, 0x03da, 0x03dd, 0x292a, 0x2915, 0x03e0, + 0x2910, 0x2913, 0x03e5, 0x292f, 0x2918, 0x03d7, 0x29e3, 0x2a39, + 0x2a35, 0x2a3a, 0x2a32, 0x044e, 0x048c, 0x0488, 0x858d, 0x2abb, + 0x2aba, 0x2b34, 0x2b39, 0x04ce, 0x859c, 0x04e5, 0x04e6, 0x2c98, + 0x0532, 0x2cd0, 0x0540, 0x0547, 0x054c, 0x2cd7, 0x2caa, 0x0535, + 0x2ca1, 0x2ca4, 0x0530, 0x2cee, 0x0543, 0x2ce7, 0x054d, 0x2ce8, + 0x2cde, 0x05b7, 0x05f3, 0x2f7e, 0x2f8b, 0x0602, + /* 0x36 */ + 0x060b, 0x2f79, 0x2f86, 0x2f93, 0x0604, 0x2f73, 0x2f6a, 0x85ba, + 0x2f6c, 0x0608, 0x2f7f, 0x05fc, 0x2fb2, 0x2fba, 0x05ff, 0x0600, + 0x2f66, 0x2f74, 0x068b, 0x315a, 0x068d, 0x314e, 0x314d, 0x318d, + 0x318e, 0x31ad, 0x06ca, 0x31c7, 0x31ca, 0x06cb, 0x31c9, 0x85cb, + 0x31e3, 0x3257, 0x06f3, 0x3263, 0x3267, 0x331a, 0x3319, 0x3316, + 0x0736, 0x076a, 0x349e, 0x34b6, 0x3498, 0x3473, 0x076b, 0x349a, + 0x348e, 0x34b7, 0x34db, 0x34a5, 0x346c, 0x34c1, 0x3484, 0x0771, + 0x0768, 0x3495, 0x347a, 0x3499, 0x0772, 0x34b8, 0x34b9, 0x3470, + 0x082e, 0x3735, 0x0862, 0x3790, 0x37bb, 0x37ed, 0x0898, 0x08b5, + 0x08eb, 0x39c1, 0x39c3, 0x39ce, 0x08fb, 0x08f8, 0x39ad, 0x3a04, + 0x08f5, 0x39b9, 0x0908, 0x39e7, 0x8607, 0x3a08, 0x3a06, 0x090a, + 0x3a0a, 0x39b0, 0x0906, 0x39f8, 0x3a0c, 0x08fd, + /* 0x37 */ + 0x39b1, 0x08fa, 0x3a02, 0x3a07, 0x3a09, 0x3a01, 0x3a17, 0x39ff, + 0x3a12, 0x09ba, 0x09b9, 0x3d03, 0x3d07, 0x3d01, 0x3cf5, 0x3cf1, + 0x3d08, 0x3cf2, 0x3d0f, 0x09bb, 0x3cfe, 0x0a18, 0x0a40, 0x0a3d, + 0x3f1a, 0x3f10, 0x3f0e, 0x4002, 0x3ff3, 0x0acd, 0x0ac9, 0x3ffb, + 0x0acb, 0x0aca, 0x0ace, 0x411b, 0x4123, 0x4161, 0x4168, 0x0b5e, + 0x4167, 0x41d3, 0x0b91, 0x0b8c, 0x4290, 0x0be1, 0x0c02, 0x42d5, + 0x42d7, 0x42d6, 0x4330, 0x0c2b, 0x4326, 0x0c2a, 0x4340, 0x0a14, + 0x431e, 0x0cad, 0x0ca3, 0x0cab, 0x4447, 0x0caf, 0x444b, 0x4451, + 0x444f, 0x4442, 0x4446, 0x0d04, 0x456e, 0x456c, 0x45f2, 0x0d44, + 0x45f1, 0x45f5, 0x45f3, 0x45f9, 0x0d3d, 0x0d47, 0x0d9c, 0x469a, + 0x4693, 0x4691, 0x46e1, 0x0de0, 0x0de4, 0x4721, 0x471c, 0x4716, + 0x4717, 0x4736, 0x471f, 0x0e80, 0x4893, 0x4899, + /* 0x38 */ + 0x489a, 0x489c, 0x0eca, 0x4949, 0x0ed4, 0x4934, 0x4937, 0x0ed2, + 0x492d, 0x0ecb, 0x494c, 0x0ece, 0x0ed3, 0x4948, 0x0f44, 0x0f48, + 0x4b3b, 0x0f45, 0x0f81, 0x0f86, 0x0f85, 0x4c08, 0x4c1a, 0x0fa3, + 0x4c1d, 0x0fb5, 0x4c49, 0x4c45, 0x4c44, 0x489b, 0x0ffa, 0x0ff9, + 0x4d2a, 0x4d2e, 0x0ffb, 0x0ff2, 0x4d31, 0x0fef, 0x4d1a, 0x4d34, + 0x4d17, 0x105b, 0x1066, 0x10ce, 0x4f1d, 0x4f71, 0x4f84, 0x4f80, + 0x4f72, 0x4fa1, 0x01b4, 0x4f79, 0x4f91, 0x10c8, 0x4f9f, 0x4fad, + 0x10d1, 0x10c5, 0x4f23, 0x10d2, 0x4f85, 0x4f9c, 0x4fb7, 0x5258, + 0x525a, 0x118f, 0x5257, 0x52b2, 0x11a7, 0x52ae, 0x11a5, 0x11a4, + 0x1211, 0x5445, 0x549c, 0x5494, 0x54a3, 0x548f, 0x54a5, 0x54a9, + 0x54a6, 0x548a, 0x54a0, 0x5490, 0x5592, 0x5591, 0x5594, 0x12b5, + 0x5626, 0x5632, 0x5628, 0x12b4, 0x12bd, 0x561c, + /* 0x39 */ + 0x12bb, 0x562b, 0x5620, 0x12b9, 0x5629, 0x12c2, 0x12be, 0x12ba, + 0x5621, 0x583a, 0x06b7, 0x585b, 0x5858, 0x587c, 0x1358, 0x58a6, + 0x58ae, 0x58ad, 0x5965, 0x139b, 0x597e, 0x139c, 0x597c, 0x597f, + 0x597a, 0x59bd, 0x13da, 0x13de, 0x59c0, 0x59bb, 0x5aad, 0x5aaf, + 0x5ad6, 0x144d, 0x1446, 0x1447, 0x144b, 0x144c, 0x5ad9, 0x1448, + 0x1499, 0x5c12, 0x5c0e, 0x5c25, 0x149b, 0x5c13, 0x5cee, 0x14ce, + 0x5cab, 0x5cf7, 0x14eb, 0x5d59, 0x5d54, 0x5df2, 0x5df0, 0x5de5, + 0x5df6, 0x151c, 0x158c, 0x6187, 0x15d1, 0x625a, 0x15d6, 0x15d3, + 0x626e, 0x15d4, 0x15d0, 0x15d5, 0x6279, 0x160b, 0x64e1, 0x64e6, + 0x17c6, 0x6ac4, 0x6ad2, 0x1a80, 0x0024, 0x1a81, 0x1c8f, 0x1c97, + 0x1c88, 0x1c89, 0x0074, 0x007a, 0x1c81, 0x1d60, 0x7064, 0x00c3, + 0x2a42, 0x1dd3, 0x00d4, 0x00d5, 0x1dd2, 0x1dd6, + /* 0x3a */ + 0x1e73, 0x00fb, 0x1e70, 0x00f7, 0x0132, 0x8533, 0x1fa8, 0x1fa6, + 0x1fc5, 0x2197, 0x21de, 0x01ba, 0x01bf, 0x2196, 0x21b4, 0x01c7, + 0x2185, 0x01b7, 0x219b, 0x21a0, 0x01b9, 0x2159, 0x01c3, 0x2186, + 0x01bd, 0x01d0, 0x21af, 0x217a, 0x01c1, 0x01be, 0x01cd, 0x219e, + 0x01cb, 0x21a9, 0x230f, 0x230e, 0x241a, 0x024f, 0x241f, 0x0253, + 0x243c, 0x2418, 0x243e, 0x2426, 0x0255, 0x243a, 0x7464, 0x2422, + 0x0251, 0x24fb, 0x2563, 0x2564, 0x029f, 0x26a8, 0x26a3, 0x2682, + 0x2688, 0x26a1, 0x2685, 0x2698, 0x02fe, 0x2699, 0x02fb, 0x2689, + 0x2681, 0x2696, 0x2680, 0x02f1, 0x02f5, 0x2691, 0x02ef, 0x0304, + 0x0303, 0x02f4, 0x26cf, 0x02f3, 0x0302, 0x02f7, 0x02fa, 0x02fd, + 0x02ee, 0x2687, 0x26a0, 0x02f0, 0x2679, 0x02f2, 0x2686, 0x26ab, + 0x26aa, 0x26a4, 0x268d, 0x267e, 0x0344, 0x27d5, + /* 0x3b */ + 0x0362, 0x0377, 0x09c9, 0x281e, 0x285f, 0x285e, 0x2944, 0x293e, + 0x03e8, 0x2948, 0x291c, 0x03ef, 0x295b, 0x294d, 0x03e6, 0x03ed, + 0x2957, 0x03e7, 0x2953, 0x294f, 0x03eb, 0x293b, 0x2946, 0x042d, + 0x0455, 0x2a46, 0x2a47, 0x0453, 0x2a48, 0x2ac0, 0x2abd, 0x2abf, + 0x0490, 0x2b11, 0x04be, 0x2b3e, 0x2b3b, 0x04bd, 0x2b3a, 0x04cf, + 0x04d0, 0x04ec, 0x2ba7, 0x054b, 0x2cea, 0x0548, 0x2d07, 0x2d22, + 0x2d0c, 0x0555, 0x0551, 0x2cb3, 0x2cd6, 0x2cd2, 0x054e, 0x2ce3, + 0x2ce5, 0x2ce9, 0x056b, 0x055e, 0x2d11, 0x2cfd, 0x0560, 0x0567, + 0x2d1e, 0x2d20, 0x2d21, 0x2e1e, 0x05b8, 0x2fe2, 0x2fde, 0x2fe6, + 0x0614, 0x060f, 0x0607, 0x0613, 0x2ff8, 0x0617, 0x2ffe, 0x2fc1, + 0x2fbf, 0x2ff7, 0x2fd1, 0x315f, 0x3160, 0x3161, 0x069a, 0x06b8, + 0x31d1, 0x06f7, 0x06f8, 0x327d, 0x326b, 0x327f, + /* 0x3c */ + 0x06fd, 0x06f5, 0x3273, 0x3281, 0x326d, 0x3269, 0x06fa, 0x0738, + 0x331e, 0x34ed, 0x0787, 0x0780, 0x0788, 0x0779, 0x3503, 0x077c, + 0x34fe, 0x34e5, 0x351e, 0x3502, 0x0783, 0x0785, 0x3509, 0x34ca, + 0x3500, 0x85e5, 0x3501, 0x3518, 0x34e2, 0x34cf, 0x077b, 0x352e, + 0x34c5, 0x34ff, 0x0786, 0x351c, 0x34c3, 0x0834, 0x376f, 0x0855, + 0x376e, 0x0868, 0x37be, 0x089c, 0x37f4, 0x382d, 0x08fc, 0x39b6, + 0x3a75, 0x3a1e, 0x091a, 0x3a18, 0x0917, 0x3a48, 0x091b, 0x3a4f, + 0x0913, 0x3a42, 0x3a6a, 0x3a70, 0x39fe, 0x0905, 0x0907, 0x3a6d, + 0x091c, 0x3a7b, 0x3a7e, 0x3a59, 0x0911, 0x3a57, 0x0916, 0x3a80, + 0x3a50, 0x0915, 0x3a29, 0x3a76, 0x3a2a, 0x3a4c, 0x3d2a, 0x09cb, + 0x3d35, 0x3d2c, 0x3d37, 0x3d1d, 0x09c5, 0x09c2, 0x3d38, 0x09cd, + 0x3d34, 0x3d2b, 0x3d33, 0x3d27, 0x3d24, 0x09ca, + /* 0x3d */ + 0x3d2d, 0x3e32, 0x3e83, 0x3e82, 0x3e87, 0x3f06, 0x3f24, 0x3f38, + 0x3f2a, 0x3f2c, 0x3f2b, 0x0a83, 0x3f2f, 0x3f28, 0x4017, 0x0ad6, + 0x0ad5, 0x4019, 0x4038, 0x0ad1, 0x401f, 0x4014, 0x403c, 0x3ff7, + 0x401c, 0x4015, 0x4018, 0x4039, 0x40f9, 0x4124, 0x8634, 0x0b52, + 0x0b5f, 0x416e, 0x416d, 0x4171, 0x418e, 0x0b95, 0x41e5, 0x0b9d, + 0x0b98, 0x0b9e, 0x0b96, 0x4294, 0x42b3, 0x0c03, 0x42d9, 0x0c2f, + 0x4348, 0x4349, 0x4343, 0x0c31, 0x0c33, 0x4342, 0x43df, 0x0cb4, + 0x4463, 0x4476, 0x0cb0, 0x445f, 0x4466, 0x4566, 0x4571, 0x0d08, + 0x0d07, 0x4576, 0x4584, 0x4575, 0x45ff, 0x4607, 0x0d4e, 0x460e, + 0x4609, 0x0d50, 0x0d52, 0x0da1, 0x0da3, 0x0da5, 0x0dcc, 0x46e7, + 0x46e2, 0x4755, 0x0def, 0x0dea, 0x4743, 0x4757, 0x476c, 0x4742, + 0x4753, 0x0ded, 0x4741, 0x0e85, 0x0e84, 0x48a7, + /* 0x3e */ + 0x48a0, 0x48a6, 0x48a4, 0x4974, 0x0edb, 0x4959, 0x0ed9, 0x4960, + 0x4957, 0x496c, 0x497e, 0x4964, 0x0ed7, 0x495a, 0x495d, 0x0eda, + 0x0ede, 0x0ed8, 0x4976, 0x494d, 0x4975, 0x0ed5, 0x4bd3, 0x4bd6, + 0x0f9c, 0x0f9d, 0x4c60, 0x4c4e, 0x4d45, 0x4d3b, 0x0ffe, 0x4d48, + 0x4d42, 0x4d49, 0x4d40, 0x4d14, 0x4d41, 0x1007, 0x4def, 0x4df6, + 0x4e03, 0x106a, 0x4fed, 0x10e7, 0x4fda, 0x5018, 0x4fd2, 0x5008, + 0x10e2, 0x5000, 0x10df, 0x10e1, 0x10e5, 0x5017, 0x4f46, 0x5014, + 0x4fd3, 0x5005, 0x501f, 0x5002, 0x5016, 0x4fcd, 0x4fe6, 0x1191, + 0x525d, 0x52d5, 0x52e1, 0x11b4, 0x11b0, 0x11b5, 0x11ae, 0x52ee, + 0x5447, 0x5446, 0x122d, 0x122c, 0x54bb, 0x122b, 0x54bf, 0x54b4, + 0x1229, 0x54b5, 0x127f, 0x559a, 0x5643, 0x12c9, 0x12cb, 0x565a, + 0x12c5, 0x12c6, 0x12ca, 0x5635, 0x5638, 0x5642, + /* 0x3f */ + 0x5649, 0x565d, 0x564b, 0x563d, 0x12d2, 0x12d0, 0x132d, 0x1335, + 0x5860, 0x585e, 0x587f, 0x587e, 0x5883, 0x136c, 0x58b1, 0x5987, + 0x139d, 0x13a0, 0x5988, 0x5983, 0x13a2, 0x139f, 0x5986, 0x598b, + 0x5982, 0x59ca, 0x59d2, 0x13eb, 0x13e2, 0x59d4, 0x59c9, 0x5ab0, + 0x1436, 0x1432, 0x1450, 0x5af2, 0x5ae4, 0x5af3, 0x5aea, 0x144f, + 0x5afd, 0x1452, 0x5b9d, 0x5c2b, 0x5c2a, 0x149e, 0x5c28, 0x5c29, + 0x5c2c, 0x14a0, 0x149c, 0x5c3a, 0x5c30, 0x5c37, 0x5c3b, 0x14d1, + 0x5d0a, 0x14ef, 0x14f0, 0x14f1, 0x5dfe, 0x5e20, 0x151d, 0x5e0b, + 0x151f, 0x5e18, 0x5e22, 0x151e, 0x5e1b, 0x5e08, 0x1520, 0x5e0e, + 0x5e13, 0x158e, 0x1591, 0x6195, 0x83dd, 0x1590, 0x15d7, 0x628c, + 0x627b, 0x627f, 0x6281, 0x15d9, 0x6282, 0x15f4, 0x15f6, 0x0160, + 0x15f5, 0x15f3, 0x62ee, 0x62ed, 0x160c, 0x62ec, + /* 0x40 */ + 0x635f, 0x636f, 0x1651, 0x636d, 0x16a6, 0x16a7, 0x16a8, 0x1727, + 0x1724, 0x1725, 0x64f0, 0x172a, 0x1774, 0x17c7, 0x66a9, 0x17e7, + 0x17ed, 0x66e0, 0x1ab7, 0x002e, 0x007b, 0x1ccc, 0x1cbc, 0x007c, + 0x1caa, 0x1cb9, 0x007d, 0x1cab, 0x1cc3, 0x1ccd, 0x1d7e, 0x1e7e, + 0x1e79, 0x00fd, 0x8523, 0x1ee1, 0x1ee0, 0x1ee7, 0x1f80, 0x1fab, + 0x1faa, 0x1fa9, 0x1fe0, 0x21ea, 0x01da, 0x21d7, 0x01d6, 0x01db, + 0x21c1, 0x2315, 0x025b, 0x246c, 0x025c, 0x245c, 0x2450, 0x2461, + 0x246a, 0x2469, 0x2456, 0x2460, 0x2466, 0x245f, 0x2523, 0x2566, + 0x2568, 0x0306, 0x030b, 0x26ce, 0x030d, 0x26c5, 0x26c3, 0x030a, + 0x0313, 0x26d0, 0x0310, 0x0312, 0x0309, 0x0308, 0x0311, 0x030f, + 0x2774, 0x2776, 0x27dc, 0x27d7, 0x27da, 0x27db, 0x0367, 0x2820, + 0x296d, 0x2966, 0x03f6, 0x2964, 0x296e, 0x857e, + /* 0x41 */ + 0x2960, 0x2b42, 0x2b5a, 0x2b6e, 0x0564, 0x056c, 0x2d30, 0x2d3a, + 0x2d2a, 0x2d43, 0x2d19, 0x2d31, 0x056d, 0x2d3d, 0x057a, 0x0575, + 0x060d, 0x3008, 0x3032, 0x3038, 0x061e, 0x3031, 0x061b, 0x3019, + 0x062a, 0x3011, 0x061f, 0x0622, 0x3029, 0x301d, 0x0625, 0x0627, + 0x0629, 0x303c, 0x0624, 0x3046, 0x3047, 0x0628, 0x0626, 0x303a, + 0x3007, 0x0623, 0x316b, 0x069f, 0x3170, 0x316d, 0x06b1, 0x31e4, + 0x3293, 0x0703, 0x0707, 0x070c, 0x0706, 0x328f, 0x0704, 0x0709, + 0x3292, 0x0705, 0x328e, 0x0708, 0x3546, 0x0796, 0x079c, 0x079f, + 0x079b, 0x0798, 0x0799, 0x0794, 0x3531, 0x078d, 0x07a3, 0x353e, + 0x0793, 0x357c, 0x3543, 0x0792, 0x3573, 0x85e8, 0x3555, 0x078e, + 0x078c, 0x3585, 0x354d, 0x3550, 0x3547, 0x3567, 0x3536, 0x3564, + 0x3561, 0x079a, 0x357d, 0x3744, 0x3740, 0x3771, + /* 0x42 */ + 0x3773, 0x379c, 0x086a, 0x086d, 0x0884, 0x37c1, 0x08a0, 0x37fa, + 0x3831, 0x3832, 0x091d, 0x0926, 0x3ab8, 0x3aa8, 0x0933, 0x3a91, + 0x3abb, 0x0938, 0x3a9a, 0x0930, 0x0928, 0x3aa9, 0x0927, 0x092a, + 0x3ab5, 0x3a6c, 0x3ae8, 0x0931, 0x3add, 0x3ada, 0x3ae6, 0x3aac, + 0x0934, 0x092e, 0x093b, 0x3ad9, 0x3ae3, 0x3ae9, 0x3adb, 0x0929, + 0x3d6f, 0x09d2, 0x09d8, 0x3d48, 0x09cf, 0x3d4a, 0x3d6b, 0x09d9, + 0x3d4f, 0x3d57, 0x3d74, 0x09ce, 0x09d3, 0x09d0, 0x3d45, 0x3d51, + 0x3d6d, 0x07a1, 0x3e51, 0x3e50, 0x3e4e, 0x0a47, 0x3f41, 0x0a8b, + 0x3f2e, 0x3f46, 0x0ad4, 0x4027, 0x0ade, 0x4048, 0x4053, 0x403d, + 0x0adf, 0x405d, 0x4056, 0x0ad7, 0x401e, 0x4047, 0x4043, 0x4058, + 0x4049, 0x0ae1, 0x404c, 0x4045, 0x403e, 0x0b2f, 0x4101, 0x411e, + 0x0b62, 0x0b63, 0x417a, 0x41ee, 0x4202, 0x4297, + /* 0x43 */ + 0x4298, 0x0be2, 0x0c04, 0x0c43, 0x435d, 0x4364, 0x4353, 0x4358, + 0x4482, 0x4490, 0x448a, 0x0cbe, 0x447a, 0x447d, 0x0cba, 0x448b, + 0x4478, 0x0cbc, 0x864e, 0x448d, 0x4488, 0x4492, 0x4481, 0x457e, + 0x4583, 0x0d0d, 0x0d0e, 0x0d11, 0x4580, 0x0d0f, 0x0d12, 0x0d55, + 0x460f, 0x0d59, 0x0d5b, 0x461d, 0x0d57, 0x46a1, 0x46a4, 0x0dce, + 0x46e9, 0x46ea, 0x0dfe, 0x4762, 0x476b, 0x0dfc, 0x475e, 0x0df5, + 0x4779, 0x0df9, 0x0dfa, 0x476f, 0x4768, 0x0e88, 0x0e89, 0x48ae, + 0x0e8a, 0x0e87, 0x0e8b, 0x48b0, 0x0ee6, 0x4990, 0x0eed, 0x498a, + 0x0ee5, 0x498b, 0x4999, 0x4995, 0x0ee0, 0x4987, 0x4978, 0x4997, + 0x4989, 0x4998, 0x0ee1, 0x0f5b, 0x0f5c, 0x4ba3, 0x0f8f, 0x0f8b, + 0x0f8d, 0x4bdd, 0x4c57, 0x0fb9, 0x4d63, 0x4d6a, 0x4d6c, 0x100f, + 0x1019, 0x1013, 0x4d5d, 0x4d75, 0x1018, 0x4d5f, + /* 0x44 */ + 0x1016, 0x4d7d, 0x4d6d, 0x1053, 0x868d, 0x4e41, 0x504f, 0x5084, + 0x10f6, 0x507f, 0x10f5, 0x5048, 0x502a, 0x507b, 0x5072, 0x5064, + 0x502e, 0x505c, 0x5053, 0x10f7, 0x5041, 0x50c8, 0x10f0, 0x5062, + 0x5080, 0x503e, 0x5083, 0x5071, 0x10f9, 0x504a, 0x5055, 0x5058, + 0x1192, 0x1195, 0x1196, 0x52fc, 0x52fd, 0x5315, 0x11b9, 0x5316, + 0x52ff, 0x11bd, 0x11b8, 0x1212, 0x5458, 0x54cf, 0x54e0, 0x1280, + 0x1281, 0x129a, 0x1298, 0x55e7, 0x566a, 0x5680, 0x12d4, 0x566f, + 0x5665, 0x12da, 0x5678, 0x567d, 0x5688, 0x12d6, 0x12db, 0x5664, + 0x567e, 0x12dc, 0x5667, 0x5863, 0x5888, 0x1371, 0x58cd, 0x1372, + 0x58c9, 0x13a8, 0x59ed, 0x13f0, 0x86db, 0x13f1, 0x13fd, 0x1438, + 0x1437, 0x1439, 0x5ab1, 0x1455, 0x1453, 0x5b04, 0x5b9e, 0x5ba0, + 0x5c43, 0x5c46, 0x5c48, 0x5c45, 0x5c40, 0x5c4c, + /* 0x45 */ + 0x14d5, 0x14bd, 0x5d0c, 0x5d13, 0x5d15, 0x14f5, 0x5d6b, 0x5d67, + 0x5e5d, 0x5e55, 0x5e35, 0x1521, 0x5e59, 0x5e2f, 0x5e3c, 0x5e8f, + 0x5e5c, 0x5e6a, 0x5e62, 0x5e5f, 0x5e6b, 0x5e6e, 0x5e3b, 0x5e44, + 0x5e41, 0x619a, 0x1592, 0x6199, 0x15de, 0x15db, 0x15da, 0x628f, + 0x15df, 0x6296, 0x15f9, 0x15f8, 0x15fa, 0x62f4, 0x62fc, 0x160e, + 0x6355, 0x1643, 0x6379, 0x1656, 0x1653, 0x169e, 0x63ee, 0x63f5, + 0x16a9, 0x640b, 0x16fa, 0x64f3, 0x1731, 0x1730, 0x64f7, 0x64ff, + 0x64f5, 0x1732, 0x64ec, 0x64f1, 0x1729, 0x172e, 0x659a, 0x1776, + 0x66e2, 0x673d, 0x675d, 0x68e8, 0x18a5, 0x68eb, 0x68ef, 0x68ee, + 0x6a81, 0x6b14, 0x1cd0, 0x1cd9, 0x1cdc, 0x1cd8, 0x008c, 0x1ce1, + 0x1ceb, 0x008b, 0x0089, 0x1cf4, 0x1ce2, 0x1cde, 0x008d, 0x0086, + 0x00d7, 0x1df4, 0x0104, 0x0107, 0x0103, 0x1eed, + /* 0x46 */ + 0x1eea, 0x0122, 0x1f32, 0x0151, 0x1fae, 0x1fb0, 0x0161, 0x21fb, + 0x2203, 0x220b, 0x01e9, 0x2207, 0x01e5, 0x21f8, 0x01e4, 0x2228, + 0x221e, 0x01e3, 0x2218, 0x2211, 0x2251, 0x2205, 0x2317, 0x2492, + 0x0265, 0x248c, 0x0263, 0x2478, 0x2484, 0x2473, 0x24ad, 0x2497, + 0x2495, 0x2477, 0x2472, 0x2496, 0x248d, 0x2510, 0x028c, 0x256c, + 0x031a, 0x26e7, 0x0315, 0x26e4, 0x0320, 0x0321, 0x26ef, 0x2226, + 0x031c, 0x031b, 0x26f0, 0x297b, 0x03fe, 0x2983, 0x0404, 0x0401, + 0x298b, 0x298c, 0x0400, 0x2978, 0x2a52, 0x046d, 0x0493, 0x2ad0, + 0x2acf, 0x04a1, 0x2bb3, 0x2bb4, 0x0576, 0x0579, 0x0572, 0x2d7b, + 0x0583, 0x2d6f, 0x2d81, 0x2d3c, 0x2d42, 0x2d38, 0x2d33, 0x85a6, + 0x2d60, 0x2d69, 0x2d7d, 0x2d86, 0x2e2c, 0x2e28, 0x0638, 0x304c, + 0x0630, 0x3057, 0x307c, 0x0634, 0x063a, 0x3055, + /* 0x47 */ + 0x3062, 0x3071, 0x306a, 0x3056, 0x303b, 0x3081, 0x0635, 0x304f, + 0x307e, 0x3064, 0x063f, 0x0640, 0x0632, 0x0631, 0x0636, 0x3171, + 0x7aba, 0x070f, 0x32a5, 0x329a, 0x329c, 0x0710, 0x32a6, 0x070d, + 0x32a4, 0x358f, 0x35c5, 0x35c8, 0x3592, 0x35b2, 0x07a9, 0x07b4, + 0x07ac, 0x35e3, 0x35c0, 0x35d6, 0x35d1, 0x359f, 0x35a2, 0x35d2, + 0x07b8, 0x07ae, 0x7bf3, 0x35e1, 0x35d5, 0x359d, 0x07b3, 0x07ba, + 0x3598, 0x083f, 0x3774, 0x37a1, 0x093c, 0x3af0, 0x3af3, 0x0942, + 0x0940, 0x3b1b, 0x3b0c, 0x3b1d, 0x3b34, 0x3b28, 0x3b17, 0x093e, + 0x3b44, 0x3b42, 0x3b04, 0x3b11, 0x3afa, 0x3b4a, 0x3d91, 0x3d8e, + 0x09e1, 0x3d8b, 0x3d8d, 0x3d7f, 0x3d8c, 0x3d7e, 0x3d7c, 0x3d83, + 0x09e6, 0x3d88, 0x09e0, 0x0a15, 0x3e94, 0x0a93, 0x3f55, 0x3f53, + 0x3f4f, 0x3f54, 0x406c, 0x4065, 0x4066, 0x4061, + /* 0x48 */ + 0x406b, 0x4068, 0x4076, 0x0ae7, 0x4060, 0x7e0f, 0x4074, 0x4106, + 0x420e, 0x0bad, 0x4207, 0x0bae, 0x0be3, 0x42b9, 0x0bf5, 0x42b7, + 0x42e2, 0x0c06, 0x4374, 0x4377, 0x4376, 0x4375, 0x0c4f, 0x4378, + 0x4371, 0x0c54, 0x437a, 0x3d5b, 0x437b, 0x44a6, 0x44ae, 0x44b8, + 0x0ccb, 0x0ce3, 0x0cc9, 0x44b1, 0x44af, 0x0d13, 0x4589, 0x4587, + 0x0d15, 0x0d61, 0x4629, 0x0d66, 0x462a, 0x0d64, 0x462d, 0x462c, + 0x0d60, 0x4632, 0x0d63, 0x46ec, 0x46f0, 0x4781, 0x479e, 0x4783, + 0x0e0a, 0x4792, 0x0e04, 0x47a3, 0x479f, 0x4793, 0x0e07, 0x4786, + 0x48b8, 0x48b7, 0x0e8d, 0x0e8f, 0x0e90, 0x0e92, 0x0eec, 0x49c8, + 0x49b6, 0x866c, 0x49d1, 0x0ee7, 0x49a8, 0x49ab, 0x0ef2, 0x49b3, + 0x49cd, 0x0eee, 0x49cf, 0x49a4, 0x0eef, 0x0f4c, 0x4b41, 0x4b6f, + 0x4b71, 0x0f5e, 0x0f5f, 0x0f76, 0x0f74, 0x0f72, + /* 0x49 */ + 0x0f90, 0x4c23, 0x4c5b, 0x0fbe, 0x4c61, 0x4c5f, 0x4d81, 0x1026, + 0x1025, 0x4d84, 0x4e13, 0x1074, 0x4e4a, 0x4e4c, 0x10fd, 0x1105, + 0x1101, 0x50bd, 0x5095, 0x1109, 0x5092, 0x50c3, 0x110c, 0x5096, + 0x50a5, 0x50b5, 0x50b3, 0x50a3, 0x50e4, 0x50d8, 0x50d5, 0x110d, + 0x50b7, 0x50ad, 0x50da, 0x5093, 0x5336, 0x11c0, 0x11c5, 0x11c9, + 0x533d, 0x532b, 0x5347, 0x5339, 0x11d5, 0x5345, 0x531d, 0x1241, + 0x54ff, 0x54ea, 0x1233, 0x54f5, 0x123a, 0x5500, 0x54ed, 0x5503, + 0x54e9, 0x1240, 0x1242, 0x55ea, 0x12e8, 0x569b, 0x568e, 0x56a2, + 0x12e4, 0x569c, 0x5694, 0x5690, 0x56a9, 0x56ac, 0x12e7, 0x569f, + 0x12e6, 0x12e1, 0x569d, 0x1339, 0x5867, 0x135c, 0x1375, 0x58d0, + 0x58d6, 0x58d4, 0x5998, 0x599a, 0x5997, 0x13ae, 0x13b0, 0x13fa, + 0x5a0b, 0x5a08, 0x5a01, 0x5ab4, 0x5ab3, 0x145b, + /* 0x4a */ + 0x5ba1, 0x5ba2, 0x14a5, 0x5c5a, 0x14a2, 0x5c61, 0x5c5f, 0x14db, + 0x14da, 0x5d25, 0x5d7b, 0x5d76, 0x5d7c, 0x1524, 0x5e89, 0x5ef6, + 0x5eb1, 0x5ead, 0x5e92, 0x5e81, 0x5e84, 0x1526, 0x5eae, 0x5e90, + 0x5e9e, 0x1598, 0x1596, 0x159a, 0x61a2, 0x61a7, 0x1597, 0x15e1, + 0x15e0, 0x15e3, 0x15e2, 0x62a0, 0x629d, 0x629f, 0x62d0, 0x15fb, + 0x62d1, 0x1612, 0x1614, 0x6359, 0x1645, 0x6364, 0x165c, 0x165d, + 0x16b8, 0x6419, 0x16ba, 0x6414, 0x6415, 0x641a, 0x1703, 0x1735, + 0x1736, 0x1739, 0x6506, 0x172d, 0x64f8, 0x6501, 0x177a, 0x65be, + 0x65bc, 0x65b7, 0x65b6, 0x65c0, 0x1778, 0x65b8, 0x177b, 0x177c, + 0x177e, 0x65c4, 0x177d, 0x65bf, 0x17c9, 0x66da, 0x66e4, 0x66e9, + 0x66e8, 0x66ea, 0x66e5, 0x17f3, 0x6726, 0x181a, 0x1819, 0x6740, + 0x181f, 0x18a6, 0x18a7, 0x18a8, 0x18ab, 0x18a9, + /* 0x4b */ + 0x192e, 0x6abd, 0x195e, 0x0095, 0x0093, 0x0092, 0x1d0e, 0x0096, + 0x1cf7, 0x0097, 0x1cfc, 0x1d0d, 0x1d01, 0x1dda, 0x1dd9, 0x1ddb, + 0x1e86, 0x1e8e, 0x1eee, 0x1f33, 0x1fb1, 0x01f5, 0x2247, 0x222d, + 0x2254, 0x01ea, 0x224b, 0x2252, 0x2231, 0x2244, 0x2256, 0x2250, + 0x222b, 0x01f3, 0x224d, 0x2237, 0x224f, 0x24a2, 0x24b7, 0x0269, + 0x24b2, 0x026b, 0x24aa, 0x24b5, 0x24b0, 0x026c, 0x24b4, 0x24a4, + 0x24a7, 0x0268, 0x2526, 0x26fe, 0x0328, 0x2704, 0x0326, 0x26fc, + 0x0325, 0x2706, 0x270a, 0x26fa, 0x270d, 0x2700, 0x270e, 0x036b, + 0x040f, 0x0408, 0x2991, 0x040c, 0x298f, 0x2990, 0x2998, 0x29a4, + 0x299b, 0x29a3, 0x2996, 0x29e4, 0x2a5a, 0x0460, 0x0462, 0x2a5e, + 0x0498, 0x2bb8, 0x2d57, 0x2d5c, 0x2da6, 0x2d95, 0x2d88, 0x058a, + 0x2da3, 0x2d8f, 0x0584, 0x2d64, 0x057f, 0x2d59, + /* 0x4c */ + 0x2d78, 0x0582, 0x2d85, 0x2d87, 0x2d9e, 0x0596, 0x0589, 0x2d98, + 0x2d9c, 0x058d, 0x05bc, 0x2e2f, 0x3080, 0x309b, 0x308e, 0x308d, + 0x3094, 0x30c6, 0x0644, 0x30a8, 0x3083, 0x063c, 0x30b9, 0x3086, + 0x30b4, 0x30af, 0x3091, 0x064e, 0x30aa, 0x30a1, 0x30a7, 0x32b6, + 0x32b3, 0x0714, 0x32bc, 0x32ac, 0x0715, 0x32ad, 0x360e, 0x07ce, + 0x361c, 0x361a, 0x07e0, 0x07c2, 0x360b, 0x07bf, 0x35ef, 0x360c, + 0x35f0, 0x3622, 0x07c4, 0x35d8, 0x07cf, 0x3612, 0x35fa, 0x07c8, + 0x362a, 0x07cc, 0x3610, 0x07cd, 0x07c7, 0x3629, 0x35f9, 0x35ea, + 0x362c, 0x3624, 0x18b7, 0x35e9, 0x3752, 0x374f, 0x3753, 0x0843, + 0x08b6, 0x3b10, 0x3b65, 0x3b75, 0x0951, 0x094a, 0x094d, 0x0956, + 0x3bd0, 0x0953, 0x3b5c, 0x3b3d, 0x3b71, 0x0959, 0x3b91, 0x3b0b, + 0x3b79, 0x3b81, 0x3b8f, 0x094e, 0x3b59, 0x3b74, + /* 0x4d */ + 0x09ee, 0x3dae, 0x09ec, 0x3da3, 0x3dad, 0x09eb, 0x09ef, 0x3dab, + 0x3da6, 0x3da2, 0x09ed, 0x1ef2, 0x3e57, 0x3e55, 0x3e99, 0x3f4b, + 0x407a, 0x0af2, 0x0aef, 0x0af1, 0x408c, 0x4084, 0x0aed, 0x0af0, + 0x4082, 0x4093, 0x407b, 0x0aee, 0x4109, 0x181b, 0x0b50, 0x0b66, + 0x0284, 0x0bb8, 0x0bf6, 0x438a, 0x0c57, 0x4390, 0x0c5e, 0x44c6, + 0x44d3, 0x44c0, 0x44d2, 0x44c7, 0x44c2, 0x0d19, 0x459f, 0x459d, + 0x459e, 0x0d70, 0x4641, 0x0d6e, 0x4638, 0x463a, 0x4642, 0x0d72, + 0x0d76, 0x463e, 0x46b0, 0x47ae, 0x47b3, 0x0e12, 0x0e1f, 0x47bf, + 0x0e11, 0x0e16, 0x47cd, 0x0e19, 0x47b2, 0x0e24, 0x0e14, 0x0e25, + 0x0e95, 0x0e96, 0x0e93, 0x0e94, 0x48c4, 0x48cd, 0x48c2, 0x48c6, + 0x48c3, 0x48c9, 0x48c7, 0x0ea0, 0x49f8, 0x0efb, 0x49ed, 0x49e2, + 0x0efc, 0x0f00, 0x0ef8, 0x49dc, 0x4a02, 0x4a01, + /* 0x4e */ + 0x0ef9, 0x49d6, 0x0f04, 0x49e4, 0x49fe, 0x0f03, 0x4a00, 0x49fc, + 0x49fd, 0x0ef3, 0x49f5, 0x49ff, 0x0efa, 0x49eb, 0x49e5, 0x4b78, + 0x4bae, 0x4be7, 0x0fbf, 0x4c65, 0x4c6a, 0x4c66, 0x4c68, 0x4c6b, + 0x4d94, 0x4da1, 0x4d92, 0x4d96, 0x4d93, 0x1079, 0x1110, 0x5101, + 0x1114, 0x50f8, 0x110e, 0x50f5, 0x111a, 0x5104, 0x1119, 0x1121, + 0x1123, 0x111f, 0x511b, 0x5103, 0x5133, 0x5134, 0x50ed, 0x1125, + 0x112b, 0x5135, 0x1116, 0x5105, 0x1122, 0x111b, 0x11ce, 0x11cf, + 0x537d, 0x11cb, 0x11d1, 0x11cc, 0x5371, 0x1217, 0x545c, 0x54e6, + 0x550f, 0x551b, 0x1251, 0x55a9, 0x55a5, 0x55ee, 0x56b1, 0x12ed, + 0x56cc, 0x56ce, 0x12f4, 0x56b7, 0x12f1, 0x56b5, 0x56e9, 0x56b4, + 0x12f8, 0x56b3, 0x56c1, 0x56af, 0x56ca, 0x56d0, 0x132f, 0x135e, + 0x135d, 0x588e, 0x1376, 0x1377, 0x58e9, 0x58db, + /* 0x4f */ + 0x137e, 0x58eb, 0x59a4, 0x13b6, 0x59a2, 0x599d, 0x13b3, 0x13fc, + 0x1403, 0x1400, 0x5a2a, 0x5a28, 0x140a, 0x1402, 0x5ab8, 0x5ab6, + 0x5ab9, 0x5ab7, 0x5b22, 0x5b2b, 0x5b27, 0x5b19, 0x5ba4, 0x1487, + 0x5bb3, 0x14a6, 0x5c71, 0x5c6a, 0x14a9, 0x14de, 0x5d88, 0x5d8c, + 0x5ebf, 0x5eb8, 0x5ebe, 0x5edc, 0x5ee5, 0x152e, 0x152d, 0x5ed4, + 0x5ed6, 0x1530, 0x5eda, 0x5eed, 0x5ef3, 0x5edb, 0x152b, 0x5eb9, + 0x5ee2, 0x5eeb, 0x61af, 0x159e, 0x61b2, 0x61b3, 0x159f, 0x15e5, + 0x15e4, 0x62a3, 0x62a5, 0x15fd, 0x15fc, 0x1617, 0x1619, 0x630a, + 0x1618, 0x6387, 0x6389, 0x638c, 0x63ef, 0x642a, 0x6422, 0x16bf, + 0x641f, 0x173c, 0x6519, 0x176b, 0x65ca, 0x65da, 0x1783, 0x1781, + 0x1780, 0x65de, 0x65c8, 0x65e0, 0x17ca, 0x66b6, 0x66b5, 0x17ce, + 0x66f4, 0x17f6, 0x676b, 0x6769, 0x6772, 0x6763, + /* 0x50 */ + 0x1839, 0x690d, 0x18ae, 0x6901, 0x690c, 0x18b5, 0x68f8, 0x18b3, + 0x18b4, 0x68fe, 0x6902, 0x6a84, 0x1922, 0x6aab, 0x6aaa, 0x1d1d, + 0x1d16, 0x0099, 0x1d2b, 0x1d1e, 0x1d1b, 0x1e90, 0x1e94, 0x1f14, + 0x7289, 0x0202, 0x2267, 0x0201, 0x227b, 0x02a1, 0x225f, 0x2261, + 0x01fd, 0x0273, 0x0274, 0x0270, 0x0276, 0x0275, 0x0272, 0x24c3, + 0x24ca, 0x24bb, 0x24c0, 0x24c4, 0x2501, 0x271f, 0x2718, 0x2711, + 0x2715, 0x0329, 0x2712, 0x271c, 0x032a, 0x2722, 0x2779, 0x29a6, + 0x0416, 0x29b3, 0x29ab, 0x2aea, 0x0499, 0x2b5b, 0x04d3, 0x04f5, + 0x2db7, 0x2dce, 0x2db9, 0x2dbd, 0x2dcf, 0x2dc0, 0x2d99, 0x2d97, + 0x0594, 0x2dbb, 0x2dd0, 0x2dc4, 0x2e31, 0x0656, 0x30d3, 0x30c0, + 0x0659, 0x0658, 0x0655, 0x0652, 0x30dc, 0x30d1, 0x30c8, 0x0657, + 0x30d5, 0x32c3, 0x071b, 0x071c, 0x32bf, 0x32c5, + /* 0x51 */ + 0x0719, 0x32cd, 0x32c1, 0x3306, 0x073f, 0x3324, 0x3663, 0x3642, + 0x3652, 0x07db, 0x3643, 0x3633, 0x07e2, 0x366c, 0x3657, 0x07d7, + 0x364c, 0x366e, 0x07de, 0x07e5, 0x07e4, 0x07e6, 0x07d6, 0x3637, + 0x07df, 0x3671, 0x364a, 0x3636, 0x07dc, 0x3653, 0x07da, 0x3645, + 0x3670, 0x07d3, 0x07d0, 0x365c, 0x3758, 0x3757, 0x0886, 0x0887, + 0x08ad, 0x08b7, 0x0958, 0x096a, 0x3bbb, 0x0962, 0x0961, 0x3bbe, + 0x0969, 0x096c, 0x0965, 0x3bb5, 0x3bd3, 0x3b9f, 0x0966, 0x3bb7, + 0x3bf5, 0x3db7, 0x09f5, 0x3dbb, 0x09f4, 0x3dd1, 0x09f7, 0x3dba, + 0x09f8, 0x3db6, 0x3dcc, 0x09fb, 0x09fc, 0x3dd3, 0x409b, 0x0af5, + 0x0af8, 0x4096, 0x40a2, 0x409d, 0x410a, 0x410e, 0x0b3c, 0x4181, + 0x422c, 0x4237, 0x4236, 0x423b, 0x0bc5, 0x42a1, 0x0c62, 0x0c63, + 0x4398, 0x0c67, 0x4396, 0x0c66, 0x0cd9, 0x0cdb, + /* 0x52 */ + 0x44d6, 0x44eb, 0x0cd8, 0x44dc, 0x0d1b, 0x45a5, 0x45a9, 0x6434, + 0x4653, 0x4645, 0x0d79, 0x464f, 0x0d7d, 0x46bd, 0x46bb, 0x46f1, + 0x0e2c, 0x0e37, 0x47ec, 0x47ed, 0x0e30, 0x0e9a, 0x48d3, 0x1600, + 0x48e1, 0x0f05, 0x4a19, 0x0f07, 0x0f09, 0x0f0a, 0x4a27, 0x4a26, + 0x0f79, 0x0fc2, 0x4c6e, 0x4daf, 0x1038, 0x1037, 0x4dad, 0x1021, + 0x4daa, 0x4e18, 0x105e, 0x113d, 0x1137, 0x1140, 0x516f, 0x514c, + 0x111d, 0x5142, 0x1133, 0x515c, 0x5170, 0x515f, 0x1135, 0x515a, + 0x514b, 0x513f, 0x538a, 0x11d8, 0x538b, 0x53a1, 0x538e, 0x11dc, + 0x11de, 0x5399, 0x545e, 0x545f, 0x5524, 0x55a7, 0x56ea, 0x56fd, + 0x56f9, 0x56e3, 0x56e5, 0x12fa, 0x12fb, 0x56ec, 0x133d, 0x133b, + 0x133f, 0x135f, 0x58f2, 0x137f, 0x58ef, 0x1384, 0x59a6, 0x13bc, + 0x1414, 0x140f, 0x5a3b, 0x5a43, 0x140e, 0x5a32, + /* 0x53 */ + 0x5b31, 0x5b30, 0x1460, 0x5b2d, 0x5b3c, 0x5ba7, 0x5ba5, 0x14ab, + 0x14ac, 0x14aa, 0x5d37, 0x5d95, 0x5d8e, 0x1504, 0x5d96, 0x1508, + 0x5f45, 0x5f0a, 0x1533, 0x1534, 0x5efd, 0x5f17, 0x5f1c, 0x5f07, + 0x5f31, 0x5f32, 0x5f2c, 0x5f30, 0x5f03, 0x5f05, 0x15a2, 0x61c2, + 0x15a4, 0x61b8, 0x15a5, 0x61c1, 0x15a7, 0x15a6, 0x15e7, 0x62ab, + 0x62b7, 0x15ff, 0x15fe, 0x6315, 0x6314, 0x161d, 0x161c, 0x630c, + 0x6317, 0x1667, 0x6393, 0x1694, 0x63d2, 0x16c5, 0x16c8, 0x6436, + 0x6431, 0x6433, 0x643c, 0x642e, 0x643a, 0x16c9, 0x643d, 0x16c7, + 0x64b5, 0x6522, 0x6523, 0x6520, 0x651c, 0x651d, 0x176c, 0x65a0, + 0x178a, 0x65ef, 0x65e8, 0x65eb, 0x1788, 0x1787, 0x1786, 0x65e1, + 0x65e6, 0x17cf, 0x17d0, 0x66f8, 0x66f5, 0x181c, 0x1823, 0x6783, + 0x6794, 0x6784, 0x1849, 0x678b, 0x678f, 0x1843, + /* 0x54 */ + 0x678c, 0x1848, 0x6789, 0x1847, 0x678e, 0x1846, 0x183f, 0x1844, + 0x6924, 0x690f, 0x18be, 0x6913, 0x690a, 0x18c2, 0x18ba, 0x18bc, + 0x18c6, 0x692a, 0x691a, 0x18c8, 0x6927, 0x6916, 0x6921, 0x1923, + 0x6a85, 0x6aac, 0x6ac6, 0x6ac5, 0x6ad7, 0x6b53, 0x009d, 0x1d28, + 0x1d27, 0x1ddf, 0x0124, 0x1f35, 0x1fb3, 0x0207, 0x228a, 0x227d, + 0x2289, 0x0279, 0x24cd, 0x24d0, 0x0278, 0x272b, 0x2733, 0x2729, + 0x2735, 0x2731, 0x2737, 0x2836, 0x29be, 0x0419, 0x29b9, 0x041c, + 0x29bb, 0x0418, 0x2de2, 0x2ddb, 0x2ddd, 0x2ddc, 0x2dda, 0x85af, + 0x2dd9, 0x05bd, 0x065d, 0x30df, 0x065a, 0x065e, 0x30e1, 0x065c, + 0x30ee, 0x065b, 0x31b5, 0x32d4, 0x32d5, 0x0721, 0x32d0, 0x32d1, + 0x32ce, 0x32d7, 0x0720, 0x0732, 0x367d, 0x368a, 0x07f2, 0x36a7, + 0x07f5, 0x3699, 0x3682, 0x3688, 0x07ee, 0x07ec, + /* 0x55 */ + 0x3686, 0x07ea, 0x3698, 0x369d, 0x07ed, 0x07f3, 0x368f, 0x07f6, + 0x36aa, 0x0848, 0x375d, 0x0849, 0x380a, 0x0975, 0x3bd7, 0x3bd6, + 0x3be5, 0x096f, 0x097b, 0x0973, 0x3bd9, 0x3bda, 0x3bea, 0x0970, + 0x3bf6, 0x7d39, 0x0978, 0x3de3, 0x09fe, 0x3de9, 0x0a00, 0x3deb, + 0x3def, 0x3df3, 0x3dea, 0x0a01, 0x8621, 0x0a55, 0x0a56, 0x0a9d, + 0x3f71, 0x0af9, 0x40ae, 0x0aff, 0x40b3, 0x0afd, 0x40ac, 0x0b43, + 0x0b41, 0x4183, 0x4245, 0x424e, 0x4244, 0x42a3, 0x42a5, 0x43a6, + 0x43a4, 0x0c6f, 0x43a9, 0x43af, 0x0c8a, 0x0ce5, 0x0ce6, 0x44f0, + 0x44f8, 0x44f1, 0x0d7f, 0x4649, 0x0db5, 0x0db6, 0x0dbb, 0x46c2, + 0x46f2, 0x46f3, 0x47fa, 0x0e40, 0x47f6, 0x47fc, 0x4818, 0x4808, + 0x4812, 0x0e9d, 0x0e9c, 0x48db, 0x48da, 0x0f0f, 0x0f11, 0x0f0d, + 0x4a2c, 0x4a4d, 0x0f14, 0x0f13, 0x4b46, 0x4bf6, + /* 0x56 */ + 0x4c2b, 0x4c74, 0x4db8, 0x4dc8, 0x1082, 0x1083, 0x114d, 0x5192, + 0x5193, 0x114f, 0x517f, 0x51ab, 0x5197, 0x114c, 0x1151, 0x51ac, + 0x11ee, 0x11e8, 0x18cb, 0x53ce, 0x11eb, 0x53cd, 0x11e2, 0x11e6, + 0x53c1, 0x53b1, 0x53c7, 0x11ec, 0x5540, 0x1259, 0x553f, 0x5539, + 0x125d, 0x5543, 0x1257, 0x125b, 0x1256, 0x55ab, 0x12fe, 0x571f, + 0x5709, 0x570c, 0x1300, 0x1301, 0x5840, 0x1342, 0x5896, 0x1360, + 0x58f6, 0x58f7, 0x141d, 0x5a46, 0x5a4f, 0x143e, 0x1469, 0x1465, + 0x5b3d, 0x5b41, 0x5f66, 0x5f78, 0x5f5d, 0x5f69, 0x5f74, 0x5f7d, + 0x5f6e, 0x5f72, 0x5f73, 0x5f62, 0x5f48, 0x5f53, 0x5f5f, 0x5f68, + 0x1538, 0x5f7f, 0x5f6b, 0x15ae, 0x61c4, 0x15ad, 0x62af, 0x62ad, + 0x62b2, 0x1602, 0x161f, 0x631a, 0x631b, 0x1622, 0x1620, 0x86f5, + 0x166c, 0x639b, 0x639f, 0x1668, 0x166d, 0x166e, + /* 0x57 */ + 0x16a0, 0x16ce, 0x16d0, 0x16d1, 0x16cb, 0x6440, 0x16d2, 0x6447, + 0x16d3, 0x64b7, 0x1720, 0x174e, 0x174b, 0x1772, 0x1770, 0x65a2, + 0x1792, 0x178f, 0x6600, 0x65f3, 0x1790, 0x8437, 0x65f5, 0x17d9, + 0x17d5, 0x66bd, 0x6700, 0x6702, 0x17fa, 0x6734, 0x6749, 0x679f, + 0x184b, 0x67a3, 0x67cd, 0x6799, 0x679d, 0x18d0, 0x18ce, 0x6939, + 0x18cf, 0x6944, 0x18c4, 0x18cc, 0x6935, 0x18d2, 0x1935, 0x6aaf, + 0x0a03, 0x1d2f, 0x009e, 0x00af, 0x6b8e, 0x020c, 0x229f, 0x229b, + 0x229e, 0x2296, 0x2294, 0x22a0, 0x027c, 0x273b, 0x0330, 0x0331, + 0x273a, 0x29c1, 0x2b4d, 0x2b5d, 0x2df3, 0x05a1, 0x059e, 0x0668, + 0x0661, 0x30f6, 0x30e5, 0x30ea, 0x30e7, 0x3105, 0x0665, 0x30f9, + 0x0666, 0x066a, 0x06ab, 0x36ab, 0x36ed, 0x36b2, 0x36b0, 0x36b5, + 0x36be, 0x36c1, 0x36c8, 0x07f9, 0x36c0, 0x36bc, + /* 0x58 */ + 0x36b1, 0x36c4, 0x36bf, 0x0858, 0x088a, 0x3c08, 0x3c03, 0x3bfd, + 0x3c10, 0x3c02, 0x3c13, 0x0a04, 0x3dfa, 0x3e00, 0x40b9, 0x40bc, + 0x0b02, 0x425b, 0x4251, 0x424f, 0x42eb, 0x43b8, 0x0c79, 0x43b9, + 0x43c1, 0x43c0, 0x43be, 0x450b, 0x0ceb, 0x4507, 0x450a, 0x4508, + 0x0ce9, 0x450d, 0x4506, 0x4515, 0x45af, 0x0d20, 0x0d21, 0x0d81, + 0x46f5, 0x0e4d, 0x0e59, 0x482e, 0x0e58, 0x481b, 0x81d1, 0x481a, + 0x4824, 0x0ea5, 0x0ea9, 0x48e6, 0x48e3, 0x0f1a, 0x0f19, 0x4a5d, + 0x4a4f, 0x4a66, 0x4a5b, 0x4b47, 0x4bb4, 0x0f96, 0x0f98, 0x0f97, + 0x4bfa, 0x4c2e, 0x82df, 0x0fc8, 0x4dce, 0x1043, 0x1045, 0x4e19, + 0x1152, 0x1157, 0x51cc, 0x51b2, 0x1155, 0x51bb, 0x51c1, 0x1156, + 0x1158, 0x11f2, 0x53e9, 0x53ee, 0x53f0, 0x53d6, 0x540e, 0x53da, + 0x5548, 0x554a, 0x554e, 0x554d, 0x55b1, 0x55b0, + /* 0x59 */ + 0x55b3, 0x1307, 0x5738, 0x5732, 0x1308, 0x572d, 0x130a, 0x5734, + 0x0f1b, 0x5729, 0x5874, 0x1361, 0x1362, 0x5903, 0x13c2, 0x13c6, + 0x59a9, 0x5a58, 0x141e, 0x1425, 0x5abf, 0x5ac1, 0x5b4a, 0x5bac, + 0x14b0, 0x5c89, 0x5d3d, 0x5d3c, 0x5da9, 0x5fa0, 0x153d, 0x5f90, + 0x153e, 0x5f93, 0x5f8b, 0x5fad, 0x5fbb, 0x5fb8, 0x1546, 0x1545, + 0x5f9c, 0x61d8, 0x61d7, 0x1603, 0x1626, 0x1627, 0x635d, 0x63a9, + 0x63da, 0x1698, 0x16ad, 0x16d5, 0x16da, 0x6454, 0x16d9, 0x6455, + 0x644b, 0x16dd, 0x643f, 0x64b9, 0x1715, 0x1716, 0x1717, 0x1721, + 0x6538, 0x6536, 0x6540, 0x174c, 0x653b, 0x6539, 0x65a4, 0x1796, + 0x1798, 0x6608, 0x660c, 0x179b, 0x6610, 0x17ff, 0x6707, 0x1825, + 0x67d2, 0x184f, 0x67c2, 0x67bb, 0x67cc, 0x67cb, 0x1856, 0x1854, + 0x694d, 0x6963, 0x694e, 0x18d8, 0x6950, 0x6955, + /* 0x5a */ + 0x18d7, 0x695e, 0x1926, 0x6a90, 0x6ab2, 0x6ab1, 0x1938, 0x6aca, + 0x6b02, 0x6b27, 0x6b26, 0x198a, 0x22af, 0x24e0, 0x24dc, 0x0334, + 0x2739, 0x0335, 0x856a, 0x277c, 0x27f3, 0x8570, 0x03a1, 0x286b, + 0x29c4, 0x310b, 0x3108, 0x310a, 0x066c, 0x066d, 0x31dc, 0x0729, + 0x072a, 0x32e1, 0x32df, 0x36ce, 0x36d4, 0x36e3, 0x36d7, 0x36e2, + 0x0800, 0x0808, 0x0806, 0x0805, 0x36d8, 0x36d5, 0x36d2, 0x08b1, + 0x0988, 0x3c1e, 0x3c2c, 0x3c25, 0x3bf3, 0x3e04, 0x3e08, 0x3e15, + 0x0a09, 0x40c4, 0x40c9, 0x40c7, 0x40c8, 0x42a9, 0x43c6, 0x43c5, + 0x4518, 0x451a, 0x4520, 0x0d22, 0x4666, 0x4664, 0x466a, 0x0dd5, + 0x0e61, 0x0e5d, 0x0e62, 0x0e4f, 0x0e60, 0x4835, 0x4834, 0x0eaa, + 0x0f22, 0x4a6c, 0x0f21, 0x4a6e, 0x4a71, 0x1046, 0x4dd4, 0x4dd6, + 0x4e1a, 0x4e62, 0x4e65, 0x4e76, 0x51db, 0x51d6, + /* 0x5b */ + 0x1162, 0x51e7, 0x1160, 0x1164, 0x51f4, 0x86b6, 0x53fd, 0x53d5, + 0x5407, 0x11f6, 0x540f, 0x53f8, 0x86c1, 0x1219, 0x5587, 0x1291, + 0x55b5, 0x55f5, 0x130d, 0x573f, 0x5743, 0x574c, 0x1365, 0x590b, + 0x5a6b, 0x5a68, 0x5a70, 0x5a75, 0x5a77, 0x143f, 0x5ac3, 0x154b, + 0x5fe9, 0x5fea, 0x5fcb, 0x5fc5, 0x5fc6, 0x1548, 0x5fed, 0x5fd3, + 0x1552, 0x5fe5, 0x154a, 0x1551, 0x5fdb, 0x5feb, 0x5fe0, 0x5fc1, + 0x1550, 0x154c, 0x61dd, 0x15ee, 0x1604, 0x1606, 0x162d, 0x162e, + 0x162f, 0x167b, 0x1678, 0x1677, 0x63b2, 0x63b4, 0x63b1, 0x63b5, + 0x63f2, 0x16a2, 0x16a1, 0x16e3, 0x6456, 0x171a, 0x1719, 0x1757, + 0x6544, 0x179e, 0x6626, 0x661f, 0x6618, 0x6621, 0x6617, 0x17dd, + 0x6709, 0x1805, 0x1828, 0x67c5, 0x67df, 0x1860, 0x67e3, 0x1866, + 0x67e9, 0x67ee, 0x1867, 0x1868, 0x6966, 0x697a, + /* 0x5c */ + 0x18de, 0x696e, 0x6991, 0x6983, 0x6976, 0x697e, 0x696d, 0x18e1, + 0x6a95, 0x6ae3, 0x1969, 0x1977, 0x6b03, 0x6b04, 0x8719, 0x6b17, + 0x00a6, 0x1d36, 0x00a5, 0x1f36, 0x0214, 0x2742, 0x0336, 0x0338, + 0x2744, 0x2746, 0x277e, 0x29ca, 0x29c8, 0x29cc, 0x2af0, 0x0670, + 0x3185, 0x32e5, 0x32e7, 0x072b, 0x0811, 0x080a, 0x36f4, 0x080d, + 0x36e9, 0x0816, 0x0810, 0x0809, 0x080e, 0x087a, 0x3c3d, 0x098c, + 0x3c36, 0x0991, 0x3e16, 0x0a0a, 0x3e12, 0x3e0f, 0x3e17, 0x3e11, + 0x3e0b, 0x0a08, 0x0a0b, 0x40cd, 0x40d0, 0x40cc, 0x40ce, 0x40d1, + 0x0b07, 0x4189, 0x0cf2, 0x466f, 0x484b, 0x4844, 0x4855, 0x0eae, + 0x0f24, 0x0f26, 0x0f27, 0x4a7f, 0x5771, 0x0f99, 0x4c2f, 0x4c7a, + 0x4c7b, 0x4c7c, 0x115f, 0x116a, 0x1171, 0x51fc, 0x5210, 0x5202, + 0x116c, 0x116f, 0x51ee, 0x5203, 0x1168, 0x520d, + /* 0x5d */ + 0x5213, 0x5208, 0x520f, 0x5418, 0x5412, 0x1201, 0x1268, 0x5567, + 0x5565, 0x55bb, 0x5769, 0x5762, 0x1313, 0x576e, 0x1316, 0x5761, + 0x1318, 0x5764, 0x574d, 0x5851, 0x1389, 0x13c8, 0x5a83, 0x5ac6, + 0x1484, 0x601f, 0x1554, 0x6004, 0x6017, 0x6008, 0x6005, 0x1556, + 0x5ff3, 0x601e, 0x6002, 0x601a, 0x601b, 0x6027, 0x601c, 0x155a, + 0x62b5, 0x1605, 0x1607, 0x6333, 0x1631, 0x6334, 0x6331, 0x63b8, + 0x63ba, 0x16a3, 0x63fc, 0x16eb, 0x171c, 0x64c3, 0x175a, 0x654d, + 0x175b, 0x662f, 0x17a6, 0x17aa, 0x17a5, 0x66c9, 0x17e1, 0x66c8, + 0x66c4, 0x672a, 0x6738, 0x6750, 0x182a, 0x680a, 0x67fb, 0x6804, + 0x67fc, 0x67fe, 0x1872, 0x186f, 0x1873, 0x6802, 0x67f6, 0x681b, + 0x67f9, 0x6815, 0x6810, 0x67ff, 0x6800, 0x680c, 0x186b, 0x18e6, + 0x6995, 0x69a5, 0x18e9, 0x18ec, 0x18e8, 0x18f0, + /* 0x5e */ + 0x6a98, 0x6ac1, 0x198c, 0x6b5a, 0x1d64, 0x22bb, 0x0215, 0x24e6, + 0x2749, 0x27f7, 0x0371, 0x0426, 0x29d0, 0x04c6, 0x2bc2, 0x05a8, + 0x3111, 0x0673, 0x36ff, 0x36fe, 0x36fd, 0x0815, 0x3701, 0x0998, + 0x0997, 0x3c4b, 0x3c4d, 0x3c47, 0x40d3, 0x4268, 0x4267, 0x0bd7, + 0x0c80, 0x43d1, 0x4530, 0x4532, 0x452e, 0x0d88, 0x6b9d, 0x46c9, + 0x46c8, 0x0e69, 0x4856, 0x4851, 0x0e6b, 0x0f29, 0x0f28, 0x4a85, + 0x4a89, 0x4a8e, 0x4a84, 0x105f, 0x4e6a, 0x522b, 0x522f, 0x5228, + 0x1174, 0x5216, 0x5215, 0x521d, 0x541a, 0x1202, 0x126a, 0x1294, + 0x55bc, 0x5775, 0x577c, 0x138a, 0x5911, 0x5912, 0x5b5c, 0x5dbb, + 0x1564, 0x5ff4, 0x155e, 0x1561, 0x602d, 0x1565, 0x1566, 0x62e4, + 0x6337, 0x6336, 0x6367, 0x63be, 0x63bd, 0x63e2, 0x6468, 0x6466, + 0x64c8, 0x64ca, 0x64c7, 0x64dc, 0x175f, 0x654f, + /* 0x5f */ + 0x65a9, 0x663c, 0x17af, 0x663b, 0x66ce, 0x180d, 0x6714, 0x6753, + 0x187c, 0x682e, 0x187a, 0x681f, 0x1876, 0x1879, 0x187d, 0x1877, + 0x69b0, 0x69bd, 0x18f6, 0x18f1, 0x69ae, 0x69c4, 0x6a7b, 0x0c0b, + 0x1929, 0x6a9e, 0x196f, 0x6b05, 0x199a, 0x6b69, 0x6ba1, 0x22c7, + 0x231d, 0x274a, 0x29d3, 0x0469, 0x2b72, 0x2e02, 0x05ab, 0x2e35, + 0x3127, 0x311e, 0x311f, 0x072c, 0x072d, 0x3707, 0x3706, 0x0817, + 0x099a, 0x3c54, 0x3e1c, 0x3e20, 0x46f8, 0x0e6e, 0x485d, 0x4858, + 0x0f2c, 0x4a92, 0x4b4e, 0x0fca, 0x1178, 0x1206, 0x5427, 0x1207, + 0x5781, 0x5783, 0x1320, 0x5844, 0x1353, 0x13ce, 0x147a, 0x1479, + 0x6042, 0x604d, 0x6054, 0x604e, 0x156b, 0x6043, 0x1567, 0x156d, + 0x633c, 0x6340, 0x63c0, 0x1685, 0x16b0, 0x16f3, 0x1763, 0x655a, + 0x6651, 0x17b6, 0x66dd, 0x1882, 0x187f, 0x6838, + /* 0x60 */ + 0x1886, 0x6845, 0x683a, 0x1884, 0x6835, 0x18fc, 0x18fd, 0x18fa, + 0x6af1, 0x1987, 0x6b93, 0x1e9a, 0x021a, 0x0219, 0x5241, 0x29d7, + 0x0675, 0x3128, 0x081a, 0x081b, 0x0819, 0x3c53, 0x3c59, 0x099c, + 0x3e21, 0x0a10, 0x426f, 0x4537, 0x45b5, 0x4862, 0x485e, 0x48f5, + 0x117b, 0x117c, 0x523d, 0x1208, 0x542d, 0x5589, 0x578d, 0x5787, + 0x5790, 0x591a, 0x5a99, 0x1441, 0x14e3, 0x1572, 0x605f, 0x1573, + 0x1568, 0x6056, 0x6061, 0x605b, 0x605a, 0x605c, 0x6065, 0x1635, + 0x6341, 0x1688, 0x169d, 0x646e, 0x646c, 0x646d, 0x0e75, 0x65aa, + 0x665c, 0x6658, 0x66de, 0x188f, 0x684f, 0x6851, 0x188e, 0x6853, + 0x1905, 0x1904, 0x18ff, 0x69fc, 0x6b39, 0x199e, 0x1d3e, 0x0154, + 0x22d2, 0x0281, 0x274f, 0x3714, 0x0cfa, 0x4672, 0x4673, 0x0f32, + 0x1270, 0x126e, 0x5791, 0x86d6, 0x147c, 0x5dbf, + /* 0x61 */ + 0x1575, 0x606c, 0x1574, 0x1577, 0x62e6, 0x6345, 0x1637, 0x63c8, + 0x63e4, 0x655d, 0x17ba, 0x6721, 0x1811, 0x672c, 0x6757, 0x1892, + 0x1899, 0x685d, 0x6861, 0x6865, 0x6a08, 0x190a, 0x192a, 0x192b, + 0x1944, 0x1979, 0x6b45, 0x00aa, 0x0348, 0x2e05, 0x32ef, 0x371b, + 0x371d, 0x3e25, 0x3e24, 0x486d, 0x0eb4, 0x5242, 0x5249, 0x120d, + 0x5578, 0x558a, 0x5797, 0x1354, 0x589b, 0x591c, 0x1430, 0x5aa2, + 0x1609, 0x1638, 0x1636, 0x168b, 0x16f7, 0x1766, 0x17bd, 0x181e, + 0x686c, 0x1896, 0x686f, 0x190d, 0x6a0e, 0x1973, 0x6b08, 0x6b1d, + 0x6ba3, 0x033b, 0x033c, 0x2b60, 0x371c, 0x09a0, 0x0cfb, 0x6cfd, + 0x48f3, 0x1181, 0x579b, 0x5aa7, 0x5dc4, 0x1578, 0x607a, 0x168d, + 0x1773, 0x6661, 0x6663, 0x66d7, 0x6876, 0x19a6, 0x6ba5, 0x05ad, + 0x3c67, 0x0a11, 0x3eab, 0x524a, 0x557d, 0x579d, + /* 0x62 */ + 0x5853, 0x5b65, 0x607b, 0x1639, 0x64cd, 0x64dd, 0x17bf, 0x6730, + 0x6a16, 0x190f, 0x19a7, 0x19b5, 0x0bdc, 0x1431, 0x62e7, 0x6a18, + 0x6aa2, 0x19a8, 0x6b7c, 0x0d25, 0x4a9e, 0x6084, 0x17c1, 0x6a1c, + 0x0d90, 0x4871, 0x63ca, 0x1296, 0x147f, 0x1910, 0x6aa3, 0x160a, + 0x687b, 0x6b97, 0x1912, 0x163a, 0x6350, 0x163b, +}; +static const unsigned short cns11643_3_2uni_page64[292] = { + /* 0x64 */ + 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, + 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, + 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, + 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, + 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x6cfd, 0x1b66, + 0x1b68, 0x1be7, 0x1c3f, 0x6cfd, 0x1ca6, 0x1d0f, 0x1e3e, 0x1f24, + 0x1f65, 0x1f9b, 0x1d7f, 0x20cb, 0x2173, 0x2171, 0x216b, 0x21f4, + 0x2222, 0x2220, 0x2292, 0x22ba, 0x2291, 0x22b0, 0x2359, 0x238a, + 0x240f, 0x2412, 0x2413, 0x2447, 0x249b, 0x2500, 0x254d, 0x26d1, + 0x26d3, 0x2767, 0x2857, 0x2877, 0x28d5, 0x2975, 0x298e, 0x29a5, + 0x29b6, 0x29bf, 0x2a65, 0x2acd, 0x2aed, 0x2b94, 0x2b9a, 0x2bba, + 0x2d25, 0x2d50, 0x2ea3, 0x2f60, 0x2f64, 0x2fb6, + /* 0x65 */ + 0x3003, 0x30b6, 0x311a, 0x4625, 0x2821, 0x32e2, 0x3302, 0x33a4, + 0x33ac, 0x3410, 0x3406, 0x345e, 0x345a, 0x352c, 0x3529, 0x362d, + 0x3677, 0x367a, 0x36ca, 0x36e6, 0x36f5, 0x370d, 0x370e, 0x37dc, + 0x37dd, 0x37f6, 0x381e, 0x3863, 0x39a5, 0x3a0f, 0x3a8a, 0x3a84, + 0x3a8b, 0x3a7c, 0x3b4c, 0x3b48, 0x3b49, 0x3b9d, 0x3b99, 0x3bf8, + 0x3c2e, 0x3c2d, 0x3c5c, 0x45cc, 0x3cbf, 0x3cea, 0x3ce5, 0x3d11, + 0x3d12, 0x3d3f, 0x3d39, 0x3d3b, 0x3d3d, 0x3d77, 0x3d75, 0x3d76, + 0x3d71, 0x3d96, 0x3d93, 0x3db4, 0x3ddd, 0x3dde, 0x3e0e, 0x2511, + 0x3e18, 0x3f47, 0x3f48, 0x3fef, 0x4012, 0x403b, 0x40a4, 0x408d, + 0x40b4, 0x4273, 0x4277, 0x42bc, 0x4419, 0x441b, 0x443d, 0x4453, + 0x4454, 0x4458, 0x44b7, 0x44d8, 0x44ee, 0x4522, 0x454d, 0x4586, + 0x4599, 0x45a3, 0x45bc, 0x46a7, 0x4737, 0x4759, + /* 0x66 */ + 0x47d0, 0x482f, 0x4832, 0x4842, 0x484e, 0x4868, 0x48a9, 0x48ed, + 0x49d0, 0x4a07, 0x49d3, 0x4a64, 0x4b40, 0x6cfd, 0x4c41, 0x4c63, + 0x4cbb, 0x3311, 0x3325, 0x4e48, 0x4f10, 0x4f62, 0x4f12, 0x5021, + 0x501e, 0x50e2, 0x50de, 0x50e1, 0x5173, 0x51d4, 0x51f5, 0x5237, + 0x5245, 0x5272, 0x534a, 0x53a9, 0x53a5, 0x53f5, 0x5434, 0x5450, + 0x5487, 0x5554, 0x5584, 0x5703, 0x5852, 0x58d8, 0x590c, 0x5918, + 0x59b0, 0x5abc, 0x5ad5, 0x5baa, 0x5c9c, 0x6cfd, 0x5d5c, 0x5e2b, + 0x5e21, 0x5e73, 0x5ef4, 0x5ef5, 0x5f3f, 0x5f42, 0x5f86, 0x5fbe, + 0x5fbc, 0x5fbd, 0x5ff1, 0x5ff2, 0x5fef, 0x6022, 0x6023, 0x6024, + 0x6067, 0x6066, 0x6197, 0x61ce, 0x61e7, 0x633b, 0x634d, 0x64e4, + 0x6542, 0x671d, 0x6798, 0x6cfd, 0x6949, 0x3049, 0x2a71, 0x2a85, + 0x2dd3, 0x650e, 0x4c02, 0x441e, 0x6cfd, 0x6cfd, + /* 0x67 */ + 0x2128, 0x2172, 0x21ba, 0x21f0, 0x21ee, 0x22b8, 0x22b9, 0x22c4, + 0x4c53, 0x5eb0, +}; + +static const ucs4_t cns11643_3_2uni_upages[136] = { + 0x03400, 0x03500, 0x03600, 0x03700, 0x03800, 0x03900, 0x03a00, 0x03b00, + 0x03c00, 0x03d00, 0x03e00, 0x03f00, 0x04000, 0x04100, 0x04200, 0x04300, + 0x04400, 0x04500, 0x04600, 0x04700, 0x04800, 0x04900, 0x04a00, 0x04b00, + 0x04c00, 0x04d00, 0x04e00, 0x04f00, 0x05000, 0x05100, 0x05200, 0x05300, + 0x05400, 0x05500, 0x05600, 0x05700, 0x05800, 0x05900, 0x05a00, 0x05b00, + 0x05c00, 0x05d00, 0x05e00, 0x05f00, 0x06000, 0x06100, 0x06200, 0x06300, + 0x06400, 0x06500, 0x06600, 0x06700, 0x06800, 0x06900, 0x06a00, 0x06b00, + 0x06c00, 0x06d00, 0x06e00, 0x06f00, 0x07000, 0x07100, 0x07200, 0x07300, + 0x07400, 0x07500, 0x07600, 0x07700, 0x07800, 0x07900, 0x07a00, 0x07b00, + 0x07c00, 0x07d00, 0x07e00, 0x07f00, 0x08000, 0x08100, 0x08200, 0x08300, + 0x08400, 0x08500, 0x08600, 0x08700, 0x08800, 0x08900, 0x08a00, 0x08b00, + 0x08c00, 0x08d00, 0x08e00, 0x08f00, 0x09000, 0x09100, 0x09200, 0x09300, + 0x09400, 0x09500, 0x09600, 0x09700, 0x09800, 0x09900, 0x09a00, 0x09b00, + 0x09c00, 0x09d00, 0x09e00, 0x09f00, 0x0ff00, 0x20000, 0x20100, 0x20200, + 0x20500, 0x20600, 0x20b00, 0x20d00, 0x21300, 0x21600, 0x21700, 0x21d00, + 0x22300, 0x22500, 0x23000, 0x23500, 0x23c00, 0x24000, 0x24a00, 0x25100, + 0x25900, 0x25c00, 0x26500, 0x28c00, 0x29900, 0x2f800, 0x2f900, 0x2fa00, +}; + +static int +cns11643_3_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x21 && c1 <= 0x62) || (c1 >= 0x64 && c1 <= 0x67)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + ucs4_t wc = 0xfffd; + unsigned short swc; + if (i < 6298) { + if (i < 6148) + swc = cns11643_3_2uni_page21[i], + wc = cns11643_3_2uni_upages[swc>>8] | (swc & 0xff); + } else { + if (i < 6590) + swc = cns11643_3_2uni_page64[i-6298], + wc = cns11643_3_2uni_upages[swc>>8] | (swc & 0xff); + } + if (wc != 0xfffd) { + *pwc = wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + diff --git a/libs/libiconv/lib/cns11643_4.h b/libs/libiconv/lib/cns11643_4.h new file mode 100644 index 00000000..e7259920 --- /dev/null +++ b/libs/libiconv/lib/cns11643_4.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CNS 11643-1992 plane 4 + */ + +/* + * The table has been split into two parts. Each part's entries fit it 16 bits. + * But the combined table would need 17 bits per entry. + */ +#include "cns11643_4a.h" +#include "cns11643_4b.h" + +static int +cns11643_4_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x21 && c1 <= 0x6e)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + ucs4_t wc = 0xfffd; + unsigned short swc; + { + if (i < 2914) + swc = cns11643_4a_2uni_page21[i], + wc = cns11643_4a_2uni_upages[swc>>8] | (swc & 0xff); + else if (i < 7298) + swc = cns11643_4b_2uni_page40[i-2914], + wc = cns11643_4b_2uni_upages[swc>>8] | (swc & 0xff); + } + if (wc != 0xfffd) { + *pwc = wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} diff --git a/libs/libiconv/lib/cns11643_4a.h b/libs/libiconv/lib/cns11643_4a.h new file mode 100644 index 00000000..ee81576a --- /dev/null +++ b/libs/libiconv/lib/cns11643_4a.h @@ -0,0 +1,460 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CNS 11643-1992 plane 4 part a + */ + +static const unsigned short cns11643_4a_2uni_page21[2914] = { + /* 0x21 */ + 0x5a86, 0x1840, 0x1841, 0x185a, 0x75e8, 0x1802, 0x1829, 0x5b0e, + 0x6027, 0x1c02, 0x013e, 0x27dc, 0x5f3c, 0x6075, 0xd128, 0x1d42, + 0x1d6a, 0x2552, 0x6f3c, 0xd175, 0xd178, 0x29c4, 0x2c4c, 0x39ad, + 0x1812, 0x182f, 0x1896, 0x18d0, 0x1b42, 0x1b83, 0xd119, 0x60a5, + 0x60aa, 0x630f, 0x640e, 0x1d83, 0x1db8, 0x659c, 0x659b, 0x6a3c, + 0x2328, 0x71c2, 0x2623, 0x2801, 0x2900, 0x87b4, 0x08b8, 0x376c, + 0x392b, 0x1b88, 0x4879, 0x51b6, 0x1817, 0x5a65, 0x000c, 0x5bb2, + 0x0030, 0x18e2, 0x18db, 0x5e77, 0x5f42, 0x1bad, 0x6033, 0x1bf7, + 0x00da, 0x60af, 0x6236, 0x0113, 0x1d1b, 0x1d88, 0x1d87, 0x6522, + 0x1dcf, 0x1dfd, 0x0163, 0x1de7, 0x20dc, 0x69a3, 0x20d9, 0x2125, + 0x2127, 0x2333, 0x2613, 0x7225, 0x7224, 0x2675, 0x7652, 0x7789, + 0x7abf, 0x05c4, 0x05c3, 0x2ff1, 0x87b5, 0xa24c, + /* 0x22 */ + 0x4552, 0xc714, 0xc712, 0x0001, 0x5aa3, 0x5aa2, 0x1851, 0x186a, + 0x5bb6, 0x190c, 0x5bb5, 0x5bb4, 0x18fe, 0x191b, 0x5bc2, 0x5bb8, + 0x003a, 0x5e79, 0x00ab, 0x1b73, 0x5f08, 0x1b8e, 0x5f7a, 0x5fb6, + 0x60bd, 0x60b7, 0x60bc, 0x00dd, 0x60c4, 0x60c9, 0x1ca5, 0x0115, + 0x1ca7, 0x1ca4, 0x6330, 0x6383, 0x6385, 0x6412, 0x6434, 0x1dbd, + 0x64e4, 0x64de, 0x652a, 0x1e02, 0x65af, 0x65b4, 0x65b3, 0x65b1, + 0x212b, 0x231b, 0x2335, 0x6cde, 0x02a7, 0x02a5, 0x6db8, 0x6db0, + 0x02a6, 0x6fc2, 0x59fd, 0x2617, 0x037c, 0x722a, 0x2670, 0x267d, + 0x03a9, 0x75e9, 0x27e9, 0x7657, 0x0434, 0x0435, 0x77b6, 0x77d7, + 0x77de, 0x04a8, 0x2919, 0x291c, 0x2975, 0x7ac2, 0x7bab, 0x04ff, + 0x29c8, 0x7e8f, 0x05c7, 0x05c6, 0x05c8, 0x7f6d, 0x82b5, 0x06d0, + 0x06d1, 0x87c0, 0x87bf, 0x0859, 0x8bb9, 0x8d1c, + /* 0x23 */ + 0x3412, 0x08bd, 0x8e80, 0x9184, 0x9185, 0x0a28, 0x39b3, 0x9524, + 0x0aa9, 0x3a90, 0x3c36, 0xaa4c, 0x0fcc, 0xb1f6, 0x4881, 0x51b8, + 0xc370, 0x14b4, 0xc375, 0xc717, 0x1823, 0x0016, 0x002c, 0x5bf1, + 0x192e, 0x5bda, 0x1b4f, 0x5fb9, 0x1bba, 0x00df, 0x00e0, 0x1c22, + 0x60ce, 0x60d2, 0x60d0, 0x0117, 0x6243, 0x1caf, 0x1cb0, 0x1cb1, + 0x624d, 0x6334, 0x012f, 0x63d9, 0x1d64, 0x6418, 0x1dd3, 0x6538, + 0x016a, 0x65d7, 0x0170, 0x016d, 0x65dc, 0x65cb, 0x65d6, 0x65d8, + 0x016e, 0x65d1, 0xd13e, 0xd13c, 0x65d2, 0x022b, 0x0228, 0x6a59, + 0x59fd, 0x233f, 0x6ce5, 0x6ce6, 0x0292, 0x6ce8, 0x238b, 0x6dbd, + 0x2391, 0x2395, 0x6dbe, 0x6f49, 0x033f, 0x6fcd, 0x258a, 0x034f, + 0x0374, 0x715e, 0x71d0, 0x037d, 0x7306, 0x03b7, 0x03a3, 0x03b0, + 0x03b1, 0x2687, 0x03ab, 0x737c, 0x7371, 0x75ef, + /* 0x24 */ + 0x043a, 0x0437, 0x280d, 0x0438, 0x0440, 0x778d, 0x77b7, 0x288e, + 0x049f, 0x7933, 0x797f, 0x297a, 0x7bf2, 0x0504, 0x0509, 0x0506, + 0x04fd, 0x050a, 0x0507, 0x7f2a, 0x7f8b, 0x05ca, 0x7f83, 0x7f8a, + 0x2c90, 0x05c9, 0x7f8e, 0x2c9a, 0x82b6, 0x2e3c, 0x2e3a, 0x067f, + 0x2e98, 0x84d8, 0x06d2, 0x8556, 0x87d2, 0x3065, 0xd1db, 0x0743, + 0x87c2, 0x8a87, 0x8a81, 0x8bc2, 0x8bbc, 0x8d23, 0x08c1, 0x8e93, + 0x08c5, 0x09a3, 0x918d, 0x918e, 0x0a2a, 0x0a5f, 0x953b, 0x954d, + 0x0a5d, 0x9534, 0x9531, 0x96f2, 0x96f0, 0x0b17, 0x9a15, 0x9b28, + 0x0b71, 0x0b72, 0x9c25, 0x9de7, 0x0c0f, 0x9de9, 0xa017, 0x40c2, + 0x0d91, 0xa96c, 0xa980, 0xaa4b, 0x0fb2, 0x0fcf, 0x0fce, 0x469e, + 0xafde, 0xaffb, 0x47eb, 0xb051, 0x4889, 0x1096, 0xb201, 0xb202, + 0x4896, 0xb205, 0x4887, 0xb203, 0x1097, 0xc151, + /* 0x25 */ + 0x51c0, 0x148b, 0x51c3, 0xc153, 0xc37a, 0xc378, 0xc376, 0xc379, + 0xc38f, 0xc37c, 0x5578, 0xc71b, 0xc71c, 0x5625, 0x8f92, 0x1875, + 0x1874, 0x5b2e, 0x5b2c, 0x002d, 0x5c0c, 0x1999, 0x5c0b, 0x0050, + 0x004b, 0x5c05, 0x004f, 0x004c, 0xd105, 0x1971, 0x1b53, 0x1bbf, + 0x5fc2, 0x5fc3, 0x1bc0, 0x6048, 0x1bee, 0x6046, 0x00e4, 0x00e3, + 0x60ea, 0x00e1, 0x60eb, 0x00e2, 0x60ee, 0x1c3d, 0x0119, 0x1cbd, + 0x1d0c, 0x62d8, 0x9a1e, 0x63df, 0x63de, 0x0141, 0x4537, 0x644f, + 0x1dc0, 0x015e, 0x660d, 0x6608, 0x0179, 0x6609, 0x1e6e, 0x1e83, + 0x6612, 0x6665, 0x1e5e, 0x1e5d, 0x217e, 0x2179, 0x6a89, 0x217a, + 0x216c, 0x6a84, 0x6a9e, 0x6a8b, 0x0232, 0x2187, 0x6c62, 0x231d, + 0x0294, 0x2346, 0x0297, 0x6cf9, 0x2343, 0x6cf7, 0x0296, 0x0298, + 0x6d06, 0x6ddd, 0x02b2, 0x6dd9, 0x6ddf, 0x6de2, + /* 0x26 */ + 0x02b9, 0x2561, 0x2566, 0x5af1, 0x2590, 0x0375, 0x037f, 0x037e, + 0x2629, 0x038f, 0x723f, 0x723e, 0x730b, 0x03bd, 0x26b2, 0x7383, + 0x03bb, 0x03bc, 0x7386, 0x26c0, 0x767c, 0x043d, 0x043e, 0x0474, + 0x77f7, 0x047a, 0x0476, 0x0478, 0x0475, 0x77fb, 0x793b, 0x04af, + 0x04b0, 0x04c7, 0x04cc, 0x7bf9, 0x7bca, 0x0516, 0x7bff, 0x0512, + 0x051d, 0x7c09, 0x7c03, 0x0515, 0x050f, 0x0514, 0x2a1f, 0x29e2, + 0x7c10, 0x7e9a, 0x7e9f, 0x05b0, 0x05bf, 0x05c0, 0x7f87, 0x05d2, + 0x05d9, 0x82b7, 0x067a, 0x8308, 0x82f9, 0x0681, 0x0682, 0x82f4, + 0x2f16, 0x2ef9, 0x06da, 0xad57, 0x3088, 0x87d6, 0x309b, 0xd1de, + 0x306e, 0x309e, 0x87d4, 0x0822, 0x081f, 0x8a90, 0x8a8d, 0x0821, + 0x3324, 0x8b60, 0x8bce, 0x8bcf, 0x085c, 0x337d, 0x8bd1, 0x087d, + 0x088d, 0x088f, 0x34e6, 0x8eca, 0x34cb, 0x08d0, + /* 0x27 */ + 0x8eb7, 0x08d8, 0x8eb2, 0x8ebb, 0x8eb9, 0x34b5, 0x09a7, 0x919e, + 0x3797, 0x91b2, 0x379b, 0x0a12, 0x936f, 0x93ac, 0x0a2f, 0x9423, + 0x396b, 0x0a2e, 0x0a2c, 0x0a5c, 0x956c, 0x39d5, 0x9532, 0x955e, + 0x0a62, 0x0a67, 0x0ab4, 0x96fb, 0x9929, 0x99bd, 0x9a1f, 0x3c43, + 0x7941, 0x9a1d, 0x3c9c, 0x9b31, 0x9b2f, 0x0bea, 0x9d43, 0x0bfb, + 0x9d41, 0x0c14, 0x9df5, 0x0c13, 0x0c12, 0x0c10, 0x0c11, 0x9df2, + 0x0c86, 0x3ee4, 0x0c98, 0xa01e, 0xa254, 0x0d2a, 0xa256, 0xa329, + 0xa327, 0xa328, 0x41ce, 0x0eb5, 0xa979, 0xa97e, 0xabb6, 0xabb7, + 0x4613, 0x0fd6, 0x0fd8, 0x46b7, 0x0fd9, 0x0fd4, 0x0fd7, 0xd281, + 0x46b9, 0x59fd, 0xad4d, 0x47e4, 0x47fd, 0x480f, 0x1060, 0xb109, + 0xb108, 0x109e, 0x10a1, 0xb21e, 0xb21a, 0xb223, 0xb215, 0xb219, + 0xb216, 0x48bf, 0x48ca, 0xb214, 0xb218, 0x48c1, + /* 0x28 */ + 0x10a0, 0xb51f, 0xb6dd, 0xb6df, 0xc169, 0x51d0, 0x59fd, 0xc16c, + 0x14b9, 0xc393, 0x52ae, 0xc395, 0xc394, 0xc391, 0xc397, 0xc730, + 0x15c1, 0x15c2, 0x5638, 0xd318, 0x001c, 0x5c31, 0x005e, 0x19bc, + 0x0059, 0x005c, 0x5c36, 0x005f, 0x19e9, 0x19bd, 0x19e2, 0x1b58, + 0x5fc9, 0x5fca, 0x00ce, 0x6118, 0x6112, 0x6119, 0x6110, 0x6116, + 0x1cc6, 0x625f, 0x1cc8, 0x62df, 0x6317, 0x1d28, 0x633c, 0x1d29, + 0x63ea, 0x63e9, 0x641c, 0x6458, 0x6464, 0x64f3, 0x015f, 0x6697, + 0x0185, 0x665a, 0x6659, 0x0186, 0x668e, 0x21b4, 0x6abc, 0x21a9, + 0x0287, 0x6d0d, 0x6cfc, 0x6d0c, 0x6e07, 0x6e0a, 0x02ca, 0x6e02, + 0x02c3, 0x6e26, 0x6e08, 0x6e1d, 0x02c2, 0x2568, 0x6f4e, 0x0341, + 0x6fed, 0x6fee, 0x6fef, 0x0380, 0x0381, 0x7250, 0x724c, 0x0393, + 0x0392, 0x724f, 0x03c5, 0x73d4, 0x59fd, 0x73b0, + /* 0x29 */ + 0x0446, 0x0441, 0x0445, 0x0442, 0x043f, 0x76a5, 0x7809, 0x0482, + 0x0481, 0x047f, 0x04a5, 0x292b, 0x04b3, 0x04b5, 0x79f3, 0x79d7, + 0x298d, 0x04da, 0x7adc, 0x04db, 0x050d, 0x2a18, 0x050e, 0x7c0b, + 0x051e, 0x0525, 0x0526, 0x051c, 0x0521, 0x2a57, 0x2a48, 0x0527, + 0x051a, 0x7c3a, 0x7c0d, 0x7c11, 0x2a38, 0x7c20, 0x7c01, 0x0524, + 0x7c37, 0xd1a3, 0x2a71, 0x7eaa, 0x05c1, 0x05e1, 0x7fe7, 0x7fe8, + 0x2d12, 0x05eb, 0x7ff5, 0x05e2, 0x05d7, 0x05e9, 0x8035, 0x7fe6, + 0x2d0a, 0x7ff8, 0x2d23, 0x7ff1, 0x0684, 0x8314, 0x8315, 0x8309, + 0x06b5, 0x06bc, 0x06dc, 0x06de, 0x06df, 0x857b, 0x2f2a, 0x857e, + 0x8766, 0x8767, 0x880a, 0x0754, 0x30e0, 0x30be, 0x0753, 0x0824, + 0x0825, 0x3329, 0x0828, 0x0827, 0x8a9c, 0x8b62, 0x8be1, 0x8bde, + 0x8bdf, 0x8be9, 0x088b, 0x8ee4, 0x8ef7, 0x08dc, + /* 0x2a */ + 0x3543, 0x8eea, 0x8ef6, 0x8f12, 0xd201, 0x37a6, 0x09b2, 0x37c0, + 0x91d9, 0x392f, 0x935f, 0x0a1b, 0x9373, 0x0a32, 0x3971, 0x943f, + 0x9578, 0x0a6b, 0x957d, 0x0a6c, 0x0a6d, 0x9712, 0x0ab9, 0x0aba, + 0x0b09, 0x0b0a, 0x992f, 0x3bea, 0x0b1b, 0x9930, 0x99db, 0x3c20, + 0x0b58, 0x9a29, 0x0b5a, 0xd236, 0x9b40, 0x0b77, 0x9b3d, 0x9b3e, + 0x0b79, 0x3ca9, 0x9b38, 0x3d85, 0x9c48, 0x0beb, 0x9cd0, 0x0bfd, + 0x0bfc, 0x3e06, 0x0c15, 0x0c18, 0x3df6, 0x0c16, 0x0c17, 0x0c19, + 0x3e00, 0x0c1b, 0x9e0e, 0x9e09, 0x3e02, 0x9e07, 0x0c87, 0x9f5f, + 0x9f60, 0x0c9c, 0xa02a, 0x0c9a, 0xa029, 0x0cff, 0x0cfe, 0xa14d, + 0x0d31, 0x0d2e, 0x0d30, 0x0d32, 0xa26c, 0x59fd, 0x0d2f, 0xa267, + 0x0d95, 0x0d96, 0xa339, 0xa334, 0xa459, 0x0dc5, 0x0e7a, 0xa923, + 0x0f42, 0xa982, 0x0f54, 0xa983, 0xa9a8, 0xaa55, + /* 0x2b */ + 0xaaf9, 0xaaf8, 0xaafc, 0xaafa, 0x4609, 0xd27a, 0x0f9f, 0x0fa0, + 0x0fa2, 0x0fe0, 0xad74, 0x0fe1, 0xad6b, 0xad71, 0x0fdf, 0xad76, + 0xb10e, 0x1062, 0x1061, 0xb110, 0xb10f, 0x10a7, 0xb238, 0xb239, + 0xb23a, 0x48da, 0xb237, 0xb23e, 0x490a, 0x1189, 0xb49c, 0xb52a, + 0xb53a, 0xb52b, 0xb528, 0xb6aa, 0xb70f, 0x121d, 0xb710, 0xb8e6, + 0x132a, 0xbd25, 0xbe8e, 0x13d3, 0x1442, 0x1443, 0xc18b, 0x1491, + 0xc18c, 0xc19a, 0x1490, 0x14bf, 0xc3b3, 0x14bc, 0xc3b2, 0x14c0, + 0x15c7, 0x15c5, 0x5655, 0xc744, 0x5652, 0x1835, 0x5b58, 0x5ca7, + 0x1a34, 0x1a01, 0x5c63, 0x1a0a, 0x0066, 0x5c6a, 0x5c65, 0x5c6b, + 0x00ad, 0x5eed, 0x5fd9, 0x613b, 0x6132, 0x1c58, 0x6135, 0x6131, + 0x613e, 0x6143, 0x6136, 0x626d, 0x011d, 0x62e4, 0x0131, 0x1d2b, + 0x63f4, 0x014c, 0x6469, 0x646b, 0x0195, 0x0191, + /* 0x2c */ + 0x0194, 0x66bf, 0x66c3, 0x66ae, 0x018f, 0x1eec, 0x66b1, 0x1f15, + 0x1efe, 0x66bb, 0x66af, 0x66b0, 0x1ee3, 0x1f16, 0x0240, 0x6aef, + 0x0241, 0x6aed, 0x21d3, 0x6af0, 0x6c93, 0x6d34, 0x6d2b, 0x2359, + 0x2427, 0x02d8, 0x02d2, 0x02da, 0x2428, 0x2410, 0x02d7, 0x240e, + 0x0342, 0x0357, 0x7004, 0x7003, 0x7002, 0x25af, 0x7005, 0x25ba, + 0x25b1, 0x7000, 0x7174, 0x0378, 0x0382, 0x0397, 0x7265, 0x7263, + 0x03c9, 0x73d7, 0x03c8, 0x03d6, 0x03cc, 0x73e8, 0x03d0, 0x73db, + 0x73d8, 0x03ce, 0x03c7, 0x26fc, 0x7409, 0x03cf, 0x03cb, 0x26f2, + 0x26fe, 0x73e5, 0x73e7, 0x27f8, 0x763f, 0x0447, 0x76c0, 0x0448, + 0x76b9, 0x76ba, 0x0483, 0x0485, 0x0484, 0x7820, 0x794f, 0x292c, + 0x04b8, 0x04bc, 0x7a91, 0x7a90, 0x7aee, 0x7af3, 0x7aec, 0x7af1, + 0x7aeb, 0x7af2, 0x7af4, 0x7aed, 0x7c41, 0x7c48, + /* 0x2d */ + 0x7c45, 0x0531, 0x0534, 0x0536, 0x2a82, 0x7c7f, 0x7c8b, 0x0523, + 0x7c3b, 0x7c4e, 0x053a, 0x2a91, 0x2a8f, 0x7c7c, 0x05b4, 0x05b5, + 0x05ed, 0x05ec, 0x05d8, 0x7ff0, 0x8036, 0x803f, 0x8043, 0x8031, + 0x8034, 0x8046, 0x05f6, 0x05e7, 0x802f, 0x82c3, 0x067c, 0x067b, + 0x8336, 0x0688, 0x2e47, 0x2e4c, 0x8321, 0xd1c8, 0x2e8a, 0x8473, + 0x06be, 0x84e6, 0x06e7, 0x06e5, 0x06ee, 0x30e1, 0x314a, 0x883f, + 0x0759, 0x075e, 0x886b, 0x075a, 0x313f, 0x0761, 0x0758, 0x075b, + 0x30bd, 0x8871, 0x075f, 0xd1e2, 0x082a, 0x082d, 0x8ab0, 0x0823, + 0x082b, 0x082c, 0x8bf3, 0x087e, 0xd1f5, 0x0893, 0x0899, 0x8d61, + 0x8d5f, 0x08b3, 0x08e7, 0x08ea, 0x8f28, 0x8f1e, 0x8f29, 0xd202, + 0x8eeb, 0x8f66, 0x09b4, 0x91f6, 0x37c9, 0x0a17, 0x9360, 0x9377, + 0x93bb, 0x0a21, 0x93bc, 0x0a38, 0x0a37, 0x0a74, + /* 0x2e */ + 0x0a73, 0x0a75, 0x95a2, 0x95b2, 0x959e, 0x0a76, 0x0a78, 0x973a, + 0x9738, 0x3aba, 0x0b0c, 0x0b20, 0x0b1e, 0x9a4d, 0x0b5b, 0x9a5e, + 0x0b5c, 0x9b17, 0x0b83, 0x3cc6, 0x0b80, 0x0b81, 0x0b7e, 0x0b88, + 0x0b85, 0x0b89, 0x0b7f, 0x0b8e, 0x9b64, 0x9b67, 0x0b84, 0x3cb7, + 0x3d8c, 0x9c59, 0x3d8d, 0x9cda, 0x0bee, 0x0bed, 0x0bfe, 0x9d51, + 0x0bff, 0x9d55, 0x9e3b, 0x9e34, 0x0c23, 0x9e37, 0x3e17, 0x9e31, + 0x3e1c, 0x0c1f, 0x9e3f, 0x9e59, 0x3e14, 0x9f61, 0x0c8f, 0x0c90, + 0xa058, 0xa062, 0xa050, 0x0ca0, 0xa051, 0x0ca6, 0x0c9f, 0xa046, + 0x0ca7, 0x0ca1, 0xa12d, 0x0d02, 0x0d36, 0xa348, 0xa351, 0xa34a, + 0xa34f, 0xa350, 0xa349, 0xa463, 0x0dc8, 0xa466, 0xa460, 0x0dd8, + 0x420c, 0x0ddd, 0x0ddc, 0xa4f1, 0x0dd7, 0xa507, 0x0dda, 0x0eba, + 0xa79b, 0xa7a3, 0xa79d, 0x0ebe, 0x0ec2, 0x0ebb, + /* 0x2f */ + 0x0ec0, 0xa7a9, 0xa7a7, 0xa7a4, 0x4423, 0xa7ba, 0x77c1, 0xa926, + 0x0f43, 0x0f55, 0xa994, 0xa993, 0x0f57, 0x0f68, 0x4598, 0x4590, + 0xab07, 0xab0d, 0xab02, 0xab0c, 0xab09, 0xab08, 0xab13, 0x0fa1, + 0xabd2, 0x463a, 0xac3e, 0xac3c, 0xad67, 0xad9e, 0x0fea, 0xadad, + 0x0fe7, 0xadd9, 0xad42, 0xada3, 0xada0, 0x0fe8, 0x0fe9, 0xad7c, + 0xb004, 0x1054, 0xb058, 0xb060, 0xb0c9, 0xb0c8, 0x4826, 0x1065, + 0xb11c, 0xb11a, 0x108a, 0xb274, 0x10b0, 0xb26e, 0xb26f, 0xb279, + 0x10bc, 0x492e, 0xb277, 0x4955, 0x491a, 0x10b8, 0x493d, 0xb27c, + 0x10b2, 0xb270, 0x4930, 0x10bd, 0xb27a, 0xb282, 0x118a, 0x4b51, + 0x11a1, 0xb544, 0x11a2, 0xb543, 0x4b88, 0xb545, 0x1215, 0xb725, + 0xb71f, 0x1220, 0x1273, 0xb8e8, 0x4d8e, 0x4d8d, 0xb909, 0xb9b7, + 0xb9b9, 0xba64, 0xba63, 0x4e09, 0x4e14, 0x12b1, + /* 0x30 */ + 0xba62, 0xba65, 0x132b, 0xbbac, 0x1345, 0xbd2a, 0x1397, 0x1398, + 0xbe96, 0x13d5, 0xbfc2, 0xd2de, 0x1493, 0x1496, 0x5207, 0x1494, + 0xc1aa, 0xc1b0, 0x14c7, 0x14c5, 0xc3d4, 0xc3cd, 0xc3d6, 0x14c4, + 0xc4f0, 0x5579, 0x5584, 0x15ce, 0x15ca, 0x15cc, 0x5657, 0x15c9, + 0x56ba, 0x59fd, 0xd04b, 0x5b62, 0x006e, 0x5cb7, 0x1a67, 0x5cac, + 0x5cab, 0x0071, 0x5cc1, 0x00bb, 0x00d3, 0x5fe8, 0x6169, 0x615d, + 0x615f, 0x00f3, 0x00ed, 0x00f5, 0x6164, 0x6162, 0x00f1, 0x00f2, + 0x00f6, 0x0120, 0x62f9, 0x0128, 0x62ee, 0x1d18, 0x1d2c, 0x1d59, + 0x63ab, 0x63ac, 0x63aa, 0x1d68, 0x1d7e, 0x6486, 0x647a, 0x1da1, + 0x6728, 0x01a1, 0x1f5b, 0x01aa, 0x01a9, 0x6731, 0x01b5, 0x01a5, + 0x01a8, 0x1f42, 0x01a7, 0x1f47, 0x672d, 0xd143, 0x1f3d, 0x672b, + 0x6732, 0x1f60, 0x21eb, 0x6b29, 0x6b26, 0x6b53, + /* 0x31 */ + 0x024d, 0x6b33, 0x6b34, 0x6c9d, 0x029c, 0x235f, 0x6d41, 0x02ea, + 0x02e5, 0x6e91, 0x6e69, 0x256f, 0x7022, 0x035e, 0x7034, 0xd16d, + 0x712e, 0x0386, 0x0384, 0x71f4, 0x265a, 0x7428, 0x03d9, 0x741c, + 0x03de, 0x7411, 0x7424, 0x7415, 0x03db, 0x7416, 0x7454, 0x7423, + 0x75ff, 0x0431, 0x76cf, 0x76d0, 0x044b, 0x76ce, 0x0449, 0x044a, + 0x044c, 0x77c7, 0x785c, 0x048a, 0x7836, 0x0489, 0x048b, 0x7843, + 0x04bb, 0x29a2, 0x299d, 0x04e4, 0x7b2a, 0x7b01, 0x29a3, 0x7b0b, + 0x7b0f, 0x053b, 0x052e, 0x053e, 0x0546, 0x0553, 0x7cdf, 0x0544, + 0x7cd2, 0x053f, 0x0542, 0x054f, 0x7ccd, 0x0552, 0x054a, 0x2ac2, + 0x7cdb, 0x055a, 0x2aa5, 0x0549, 0x7ccf, 0x2c1c, 0x7ec0, 0x2c1d, + 0x0603, 0x8081, 0x8082, 0x808a, 0x80a8, 0x808c, 0x2d95, 0x2d9a, + 0x0601, 0x0606, 0x05fb, 0x05f9, 0x808e, 0x0605, + /* 0x32 */ + 0x05fa, 0x808b, 0x2da6, 0x8096, 0x05fe, 0x80cc, 0x067d, 0x068c, + 0x834f, 0x834a, 0x2e50, 0x068e, 0x834b, 0x833d, 0x2e52, 0x8344, + 0x8349, 0x849e, 0x84f3, 0x2ec8, 0x84f5, 0x06f0, 0x06f2, 0x85b3, + 0x2f58, 0x06f1, 0x06e6, 0x85e5, 0x85b6, 0xd1d8, 0x3188, 0x8886, + 0x076f, 0x076d, 0x0769, 0x88b6, 0x8885, 0x076e, 0x88ab, 0x082f, + 0x0830, 0x0863, 0x8c0d, 0x8c8b, 0x8c8c, 0x33b8, 0x0880, 0x33b9, + 0x089a, 0x0894, 0x0896, 0x0895, 0x0897, 0x8d72, 0x08f4, 0x08fe, + 0x8f8f, 0x0901, 0x8f79, 0x0902, 0x8f77, 0x08f9, 0x8f90, 0x8f88, + 0x8f80, 0x8f9e, 0x08f6, 0x08f7, 0x8f82, 0x8f34, 0x8f89, 0x08ff, + 0x8f85, 0x8f7e, 0x8f7a, 0x8fa6, 0x360b, 0x8fb5, 0x91f4, 0x09bf, + 0x09bc, 0x3805, 0x9229, 0x9226, 0x922a, 0x09be, 0x09c0, 0x937e, + 0x0a3b, 0x0a39, 0x945b, 0x9461, 0x9460, 0x0a3c, + /* 0x33 */ + 0x959b, 0x3a14, 0x3a04, 0x95c3, 0x0a7d, 0x95cd, 0x0a7f, 0x0a7a, + 0x0a7c, 0x3a05, 0x0a7e, 0x3a15, 0x3a0d, 0x0a80, 0x0abf, 0x0ac3, + 0x9754, 0x9759, 0x0acc, 0x0b0e, 0x0b0d, 0x98f5, 0x0b26, 0x0b24, + 0x0b25, 0x0b23, 0x0b21, 0x0b29, 0x9a69, 0x9a65, 0x0b8f, 0x0b8d, + 0x9b7c, 0x0b8b, 0x0b92, 0x9b80, 0x0b90, 0x9c65, 0x0bef, 0x0bf0, + 0x9cdf, 0x9d60, 0x0c01, 0x9d5e, 0x0c2e, 0x0c2d, 0x3e2e, 0x0c28, + 0x0c29, 0x0c2c, 0x9e8f, 0x9e61, 0x9e5a, 0x3e41, 0x0c88, 0x9f67, + 0x0c92, 0x0c91, 0x3eea, 0x9fbb, 0x3f44, 0x0ca9, 0x0cac, 0x0cae, + 0x0caa, 0x0d06, 0x0d05, 0x0d4a, 0x0d3e, 0x0d3c, 0x0d3b, 0xa29b, + 0x0d42, 0x0d41, 0x0d43, 0xa2a9, 0x0d45, 0xa366, 0x0d9a, 0x0d9b, + 0x0d9f, 0x0d9e, 0xa472, 0xa476, 0xa514, 0x0dde, 0x0de2, 0x0de6, + 0xa50f, 0x4229, 0x0de3, 0x4227, 0x0ddf, 0xa641, + /* 0x34 */ + 0xa646, 0x439d, 0xa64b, 0xa643, 0x0e7e, 0x0ec9, 0x0ecc, 0xa7c6, + 0x0ed1, 0xa7c7, 0x0ed0, 0xa7ce, 0x0ecf, 0x0ec8, 0xa7c9, 0x0ecd, + 0xa7cb, 0xa7c5, 0x0f49, 0x0f47, 0x0f58, 0x0f6b, 0x0f6c, 0x0f6a, + 0xaa69, 0x0f80, 0x0f82, 0x0f84, 0x45c8, 0x0f83, 0xab1e, 0xabba, + 0x0fb6, 0xac52, 0xac51, 0xac53, 0xad9f, 0xaddb, 0x4726, 0x0ff1, + 0xade3, 0x0ff6, 0x0ff3, 0x0ff0, 0x471c, 0xadd7, 0xade9, 0x4728, + 0x0ff5, 0x0ff4, 0x0ff7, 0xadde, 0xaddc, 0xb03c, 0xd28b, 0x1055, + 0xb122, 0xb132, 0xb123, 0x108b, 0x10cb, 0x10c2, 0xb2d4, 0xb2c8, + 0xb2bc, 0x10ca, 0x10cc, 0xb2cd, 0x10c7, 0x10c9, 0x4970, 0xb2be, + 0x10c6, 0xb340, 0xb2d6, 0x10c3, 0x4982, 0xb2bd, 0x49ac, 0xb2ba, + 0x10c4, 0xb2c0, 0xd29b, 0xd29d, 0xb2c1, 0xb4a6, 0xb4a5, 0xb4a8, + 0x11a9, 0x4bad, 0x11a8, 0x11a6, 0xb55f, 0xb570, + /* 0x35 */ + 0xb56a, 0xb565, 0xb567, 0xb56f, 0xb587, 0x4bca, 0x4c51, 0xb73d, + 0xb743, 0x1222, 0xb740, 0x1226, 0x1224, 0x1225, 0x4c9d, 0x122a, + 0x1274, 0xb918, 0x1279, 0x4d90, 0x127a, 0xb919, 0xb9c1, 0x4dd8, + 0x4dd7, 0x1297, 0xb9bc, 0xb9c8, 0x4e2e, 0xba71, 0x12bc, 0xba6e, + 0x12b3, 0xba78, 0x12bf, 0x12b7, 0xd2cd, 0xba7a, 0xbbb1, 0xbbaf, + 0xbbb0, 0x1334, 0x1346, 0x1348, 0x4f59, 0xbca8, 0xbca6, 0x1356, + 0x1367, 0xbd48, 0xbd45, 0x1368, 0x1399, 0x139a, 0xbea0, 0xbea4, + 0x13d8, 0xbfd4, 0x13db, 0x13dc, 0x13dd, 0x13d7, 0xbfd2, 0xc022, + 0x1449, 0x144a, 0x50da, 0xc0b7, 0xc0cc, 0x5233, 0xc1e6, 0x5218, + 0x149a, 0xc1c8, 0x14cd, 0x14ca, 0xc3f4, 0x14cb, 0xc3ed, 0x14cf, + 0xc37e, 0xd2e3, 0x14cc, 0x14ea, 0x14ed, 0xc4f9, 0xc4fd, 0x14e9, + 0xc507, 0x151a, 0x53ef, 0x158d, 0x15d2, 0xc778, + /* 0x36 */ + 0xc77a, 0xc779, 0xc88a, 0x15f2, 0xc97b, 0xcad5, 0xcae9, 0x163d, + 0xcaeb, 0x163e, 0x16f8, 0x1723, 0x58d9, 0x18b4, 0x5b6c, 0x1aa0, + 0x1a90, 0x0075, 0x1a86, 0x1a84, 0x5cfa, 0x1a8a, 0x0076, 0x0073, + 0x1a9f, 0x1aa1, 0x5d18, 0x1a93, 0x00bd, 0x5ff6, 0x1bd5, 0x618a, + 0x6189, 0x00f9, 0x617f, 0x6188, 0x00fa, 0x6183, 0x6184, 0x6198, + 0x6163, 0x6187, 0x0121, 0xd127, 0x0129, 0x62f5, 0x6350, 0x0138, + 0x014e, 0x6487, 0x648a, 0x6565, 0x67b7, 0x67c1, 0x67c7, 0x01c8, + 0x01bc, 0x67c5, 0x67cb, 0x1f90, 0x67d1, 0x01bb, 0x01c2, 0x01c0, + 0x67b8, 0x67ca, 0x01ca, 0x67de, 0x01c9, 0x67ce, 0x01b8, 0x2110, + 0x2217, 0x6b68, 0x024e, 0x6b6b, 0x2244, 0x0250, 0x222b, 0x6b6a, + 0x2245, 0x6b66, 0x6b77, 0x6b96, 0x6b6e, 0xd156, 0x028a, 0x6d57, + 0x2365, 0x6d56, 0x6e9c, 0x6e9e, 0x02fc, 0x02f9, + /* 0x37 */ + 0x6ea1, 0x0363, 0x7042, 0x25cf, 0x7046, 0x703e, 0x7133, 0x0387, + 0x0388, 0x71fa, 0x039a, 0x7297, 0x729b, 0x72aa, 0x2756, 0x7473, + 0x747c, 0x03e9, 0x7486, 0x03ea, 0x2754, 0x0450, 0x76f3, 0x76f0, + 0x0456, 0x0452, 0x044f, 0x0454, 0x0451, 0x76ec, 0x78af, 0x048e, + 0x048f, 0x7864, 0x7868, 0x795a, 0x293d, 0x7b1f, 0x7b25, 0x04ed, + 0x04eb, 0x29a4, 0x7cc6, 0x7cd6, 0x7cc3, 0x0562, 0x7d2c, 0x055d, + 0x7d2e, 0x7d5e, 0x7d33, 0x0561, 0x0565, 0x055c, 0x7d2d, 0x7d46, + 0x055f, 0x7cc1, 0x7d3a, 0x7ecc, 0x809d, 0x8083, 0x80f6, 0x2dec, + 0x0616, 0x060a, 0x80f8, 0x060e, 0x0612, 0x80fe, 0x80f3, 0x0611, + 0x80eb, 0x80fa, 0x0610, 0x8107, 0x80fc, 0x0609, 0x2dfa, 0x0615, + 0x2dd4, 0x8372, 0x8373, 0x8374, 0x0691, 0x0695, 0x0693, 0x0692, + 0x068f, 0x835f, 0x8360, 0x84aa, 0x8534, 0x06f6, + /* 0x38 */ + 0x85b4, 0x06fb, 0x85f0, 0x2f75, 0x06f9, 0x860d, 0x85f3, 0x860f, + 0x301c, 0x077d, 0x88c9, 0x077a, 0x077f, 0x88c5, 0x0778, 0x88d7, + 0x88cc, 0x31d9, 0x88e7, 0x0770, 0x0782, 0x88c1, 0x0784, 0x88e8, + 0x0833, 0x8acb, 0x0832, 0x0836, 0x8ac8, 0x8b7a, 0x0856, 0x8b79, + 0x8b7e, 0x0867, 0x8c1b, 0x0865, 0x0864, 0x0866, 0x8c1f, 0x8c19, + 0x0881, 0x0882, 0x0883, 0x089e, 0x8d89, 0x33f1, 0x089d, 0x8d8b, + 0x090f, 0x0912, 0x9009, 0x8ffe, 0x9000, 0x0910, 0x0918, 0x900b, + 0x0914, 0x0919, 0x3637, 0x59fd, 0x904a, 0x367d, 0x3686, 0x09c8, + 0x09c4, 0x09c6, 0x9279, 0x09c7, 0x09c3, 0x926c, 0x9299, 0xd21b, + 0x9262, 0x9314, 0x0a19, 0x0a1c, 0x93c8, 0x93d7, 0x940c, 0x0a41, + 0x9470, 0x0a42, 0x0a43, 0x9471, 0x95df, 0x95e4, 0x0a82, 0x95e7, + 0x0a81, 0x0a94, 0x0a84, 0x9790, 0x0ad2, 0x0b0f, + /* 0x39 */ + 0x0b22, 0x994c, 0x0b27, 0x0b2a, 0x3bfa, 0x0b28, 0x994f, 0x0b60, + 0x9a7d, 0x9a7e, 0x9a7c, 0x3c72, 0x9a8d, 0x9b19, 0x0b9b, 0x0b9c, + 0x9bc0, 0x0b93, 0x0b94, 0x3cdc, 0x0ba0, 0x0b99, 0x9bb6, 0x0ba1, + 0x9ba8, 0x0bf1, 0x9ceb, 0x9ce7, 0x9d6f, 0x9ec7, 0x0c36, 0x9e9f, + 0x0c37, 0x0c3f, 0x0c3c, 0x9ec4, 0x0c34, 0x0c39, 0x0c3b, 0x0c35, + 0x0c30, 0x0c32, 0x0c38, 0x0c3e, 0x0c3a, 0x9e9b, 0x9e97, 0x9ec5, + 0x9f6b, 0x9fce, 0x0cb6, 0x3f67, 0xa0b1, 0xa0ae, 0xa0b0, 0x0cb3, + 0x0d09, 0x4077, 0xa23e, 0xa2b5, 0xa2ba, 0x0d4c, 0xa2b2, 0xa2b4, + 0x0d53, 0x0d4d, 0x0d51, 0x0d4f, 0x419b, 0xa377, 0x0da2, 0xa386, + 0xa37b, 0x0dcd, 0xa47e, 0xa52e, 0x0de7, 0xa52f, 0x0df0, 0xa537, + 0x0de9, 0x0dec, 0xa532, 0x0de8, 0x0dee, 0x0e02, 0xa536, 0xa539, + 0xa535, 0xa65c, 0x0e82, 0x0e83, 0x0e86, 0xa67b, + /* 0x3a */ + 0xa661, 0xa7ee, 0xa7eb, 0xa7ef, 0xa820, 0x442a, 0x4465, 0x0f4a, + 0xa930, 0x0f5a, 0x4564, 0xa9be, 0x0f6e, 0xaa67, 0xaa7c, 0x0f70, + 0x0f6f, 0xab24, 0x0f8a, 0x0f87, 0x0f88, 0xab29, 0xabef, 0x4620, + 0x0fb7, 0x0ffd, 0x4720, 0xae0d, 0x1005, 0x473c, 0x1008, 0x1003, + 0x1002, 0x1004, 0x0739, 0x1009, 0x0fff, 0xae64, 0x473f, 0xae15, + 0x0ffc, 0x1001, 0x100a, 0x47f0, 0x47f5, 0x106b, 0x106c, 0xb135, + 0xb136, 0xb134, 0xb137, 0xb347, 0xb32b, 0x10de, 0xb341, 0xb343, + 0x10db, 0xb342, 0x10dd, 0x10e3, 0xb332, 0x10e0, 0x10d9, 0x10d8, + 0x10e4, 0xb344, 0xb34a, 0x10da, 0x10ef, 0xd2a0, 0x4a15, 0x49be, + 0xb354, 0xb36e, 0xb352, 0x10d7, 0x11b3, 0x11bb, 0x4be5, 0x11b2, + 0x4bd2, 0x11ad, 0xb592, 0x11af, 0xd2b8, 0x4be0, 0xb5bf, 0x1216, + 0x1228, 0x1223, 0x4cb3, 0xb741, 0xb769, 0xb765, + /* 0x3b */ + 0x1275, 0x127e, 0x127c, 0xb922, 0xb91d, 0xb9d2, 0xb9da, 0xb9db, + 0x12ce, 0x12cd, 0x12cf, 0x4e53, 0xbaa4, 0xba9e, 0x4e37, 0x4e47, + 0x4e5c, 0xba9d, 0x12c4, 0x12cc, 0x12c8, 0x12c7, 0xbaad, 0xbaa6, + 0xbaa7, 0xbbb3, 0xbbe0, 0xbc35, 0xbc37, 0x135a, 0x136a, 0xbd4a, + 0x136b, 0x136d, 0x136f, 0xbe5e, 0x139e, 0xbec0, 0x13a4, 0x13a3, + 0x13e4, 0x13e8, 0x13e9, 0x13e0, 0x13e3, 0xbff9, 0x13ea, 0x13e1, + 0x13ed, 0x1434, 0x1435, 0x1451, 0x50f0, 0xc1f0, 0x149d, 0xc1f3, + 0xc21b, 0xc1f2, 0xc1fb, 0xc41c, 0xc413, 0x14d0, 0xc40f, 0x14ee, + 0xc516, 0xc511, 0xc512, 0x14f2, 0xc50e, 0x541d, 0x1588, 0xc667, + 0xc6f2, 0xc6da, 0x158f, 0xc6dc, 0x15d8, 0xc894, 0xc89b, 0xc892, + 0xc89a, 0xc988, 0xc986, 0x163f, 0xcaef, 0x1652, 0x576b, 0xcb5e, + 0x1650, 0xcc58, 0x16b1, 0xcc56, 0xcc54, 0x16f9, + /* 0x3c */ + 0xcd9b, 0xce96, 0xcea4, 0x1726, 0x1728, 0xce9a, 0xcf12, 0x0080, + 0x1ac0, 0x0081, 0x5d6b, 0x007e, 0x007f, 0x5d37, 0x5d3c, 0xd10a, + 0x5ef7, 0x00be, 0x5f66, 0x00d6, 0x61a9, 0x61ae, 0x61ad, 0x61c8, + 0x61a5, 0x61b0, 0x6295, 0x1ce5, 0x6325, 0x0134, 0x6499, 0x1daf, + 0x6574, 0x6570, 0x656f, 0x6841, 0x6854, 0x01d5, 0x01d8, 0x6840, + 0x6838, 0x01d4, 0x1fd8, 0x01d9, 0x6852, 0x683a, 0x6857, 0xd14a, + 0x6859, 0x2111, 0x2267, 0x6bb4, 0x6bc0, 0x025d, 0x2243, 0x025e, + 0x0259, 0x6b75, 0x025a, 0x02a0, 0x6d60, 0x6d47, 0x0305, 0x6ef0, + 0x0307, 0x6eef, 0x030e, 0x030c, 0x6eec, 0x6f83, 0x0345, 0x6f84, + 0x6f8f, 0x0364, 0x7061, 0x0365, 0x7069, 0x25dd, 0x0366, 0x7062, + 0x0389, 0x03ec, 0x03f1, 0x2770, 0x276a, 0x03f0, 0x03f8, 0x2774, + 0x275f, 0x74ae, 0x2761, 0x2773, 0x74b2, 0x03f2, + /* 0x3d */ + 0x03f4, 0x770b, 0x0458, 0x7710, 0x770d, 0x045a, 0x0459, 0x0457, + 0x045b, 0x2850, 0x787f, 0x7881, 0x04a6, 0x04c2, 0x04c1, 0x293f, + 0x7a0b, 0x7b4e, 0x04ef, 0x29b0, 0x7dea, 0x7d45, 0x0568, 0x2b35, + 0x2b2d, 0x0573, 0x056e, 0x0574, 0x2b02, 0x0566, 0x7d28, 0x7d5d, + 0x7edc, 0x05b9, 0x2c26, 0x7ed4, 0x060c, 0x8164, 0x8168, 0x0620, + 0x8162, 0x061d, 0x8161, 0x061c, 0x8166, 0x0621, 0x061a, 0x0619, + 0x80f2, 0x8169, 0x8167, 0x067e, 0x839a, 0x839b, 0x8385, 0x839c, + 0x069d, 0x83a4, 0x069e, 0x069c, 0x2e6e, 0x8399, 0x8386, 0x8390, + 0x8481, 0x84ae, 0x2eb1, 0x2ed4, 0x06cd, 0x8538, 0x070b, 0x070a, + 0x2f85, 0x893b, 0x078f, 0x3272, 0x0795, 0x0790, 0x0791, 0x894c, + 0x323a, 0x07b9, 0x8947, 0x8935, 0x0797, 0x079e, 0x8933, 0x078b, + 0x8982, 0x8940, 0x083b, 0x083a, 0x083c, 0x083d, + /* 0x3e */ + 0x0839, 0x083e, 0x086b, 0x086c, 0x8c36, 0x8d0e, 0x08a2, 0x08a1, + 0x089f, 0x8dad, 0x8daa, 0x9017, 0x092d, 0x9067, 0x0936, 0x092b, + 0x9072, 0x0937, 0xd20a, 0x9061, 0x90b0, 0x36ad, 0x0925, 0x092f, + 0x092c, 0x906e, 0x9064, 0x0932, 0x908c, 0x9066, 0x3695, 0x906b, + 0x905f, 0x9074, 0x9065, 0x92bb, 0x92be, 0x09d5, 0x92b9, 0x09d4, + 0x09d6, 0x92ef, 0x09d1, 0x3943, 0x93da, 0x0a46, 0x398f, 0x9490, + 0x95e9, 0x0a8c, 0x0a8a, 0x0a88, 0x9611, 0x960d, 0x95ed, 0x9621, + 0x0add, 0x9781, 0x97b1, 0x9901, 0x0b2d, 0x995e, 0x9962, 0x0b2e, + 0x0b2c, 0x0b2b, 0x0b30, 0x995b, 0x0b4e, 0x9a96, 0x9a93, 0x0b64, + 0x0b61, 0x9a92, 0x3c75, 0xd239, 0x0b70, 0x0ba6, 0x0ba4, 0x9bc4, + 0x9bc7, 0x9bc3, 0x0ba8, 0x0ba2, 0x9bc8, 0x0ba7, 0x3cec, 0x0ba5, + 0x9bca, 0x0ba9, 0x9bc5, 0x9bcf, 0x9bdc, 0x9c7c, + /* 0x3f */ + 0x9d01, 0x0c3d, 0x9ed3, 0x9edc, 0x0c44, 0x0c45, 0x0c46, 0x9ed4, + 0x3e57, 0x9ecc, 0x0c47, 0x0c48, 0x0c42, 0x9ed6, 0x9edb, 0x0c41, + 0x9ed5, 0x9fd9, 0x0c94, 0x9fdd, 0x9fdc, 0x9fe0, 0xa0cc, 0x0cc0, + 0x0cb8, 0x0cc1, 0x0cc2, 0x0cbb, 0x0cbd, 0x0cbf, 0x0cb9, 0x0cb7, + 0xa0d2, 0x0cc7, 0xa0d3, 0x0d0c, 0x0d0b, 0x407b, 0x0d10, 0xa18d, + 0x0d5d, 0x4121, 0x0d5a, 0x0d58, 0x0d56, 0xa2d8, 0x0d54, 0x4116, + 0xa2bc, 0x0da8, 0x0da7, 0x0dcf, 0x0dd0, 0xa48a, 0x41e8, 0xa48b, + 0xa48d, 0x0dd1, 0x0deb, 0xa553, 0x0dfb, 0x426a, 0xa559, 0x0dfd, + 0x0df8, 0x0df7, 0x0e00, 0xa556, 0xa557, 0x0df6, 0x425f, 0xa673, + 0xa81b, 0x0edf, 0xa821, 0xa816, 0xa818, 0x0ee2, 0x0ee4, 0xa844, + 0x4482, 0xa826, 0x0ee3, 0xa936, 0x0f59, 0x0f71, 0x0f8e, 0x0f8c, + 0xab3a, 0x0fa4, 0xabf4, 0x4655, 0x1014, 0xae62, +}; + +static const ucs4_t cns11643_4a_2uni_upages[212] = { + 0x03400, 0x03500, 0x03600, 0x03700, 0x03800, 0x03900, 0x03a00, 0x03b00, + 0x03c00, 0x03d00, 0x03e00, 0x03f00, 0x04000, 0x04100, 0x04200, 0x04300, + 0x04400, 0x04500, 0x04600, 0x04700, 0x04800, 0x04900, 0x04a00, 0x04b00, + 0x04e00, 0x04f00, 0x05000, 0x05100, 0x05200, 0x05300, 0x05400, 0x05500, + 0x05600, 0x05700, 0x05800, 0x05900, 0x05a00, 0x05b00, 0x05c00, 0x05d00, + 0x05e00, 0x05f00, 0x06000, 0x06100, 0x06200, 0x06300, 0x06500, 0x06600, + 0x06700, 0x06800, 0x06900, 0x06b00, 0x06c00, 0x06d00, 0x06e00, 0x07000, + 0x07100, 0x07200, 0x07300, 0x07400, 0x07500, 0x07600, 0x07700, 0x07800, + 0x07900, 0x07a00, 0x07b00, 0x07c00, 0x07d00, 0x07f00, 0x08000, 0x08100, + 0x08200, 0x08300, 0x08400, 0x08600, 0x08800, 0x08900, 0x08a00, 0x08c00, + 0x08e00, 0x08f00, 0x09000, 0x09100, 0x09200, 0x09500, 0x09600, 0x09700, + 0x09a00, 0x0ff00, 0x20000, 0x20100, 0x20200, 0x20300, 0x20400, 0x20500, + 0x20600, 0x20700, 0x20800, 0x20900, 0x20a00, 0x20b00, 0x20c00, 0x20d00, + 0x20e00, 0x21100, 0x21200, 0x21300, 0x21500, 0x21600, 0x21700, 0x21900, + 0x21a00, 0x21b00, 0x21c00, 0x21d00, 0x21e00, 0x21f00, 0x22000, 0x22100, + 0x22200, 0x22300, 0x22400, 0x22500, 0x22600, 0x22700, 0x22900, 0x22a00, + 0x22b00, 0x22c00, 0x22e00, 0x22f00, 0x23000, 0x23100, 0x23200, 0x23300, + 0x23400, 0x23500, 0x23800, 0x23900, 0x23a00, 0x23b00, 0x23c00, 0x23d00, + 0x23e00, 0x24100, 0x24200, 0x24500, 0x24600, 0x24700, 0x24800, 0x24900, + 0x24a00, 0x24b00, 0x24c00, 0x24d00, 0x24f00, 0x25000, 0x25100, 0x25300, + 0x25400, 0x25600, 0x25700, 0x25900, 0x25a00, 0x25b00, 0x25e00, 0x25f00, + 0x26000, 0x26200, 0x26300, 0x26400, 0x26500, 0x26600, 0x26700, 0x26800, + 0x26900, 0x26a00, 0x26b00, 0x26c00, 0x27100, 0x27200, 0x27500, 0x27600, + 0x27700, 0x27800, 0x27900, 0x27b00, 0x27c00, 0x27d00, 0x27e00, 0x27f00, + 0x28200, 0x28400, 0x28500, 0x28600, 0x28700, 0x28800, 0x28c00, 0x28e00, + 0x28f00, 0x29000, 0x29100, 0x29200, 0x29400, 0x29500, 0x29600, 0x29a00, + 0x29d00, 0x2f800, 0x2f900, 0x2fa00, +}; + diff --git a/libs/libiconv/lib/cns11643_4b.h b/libs/libiconv/lib/cns11643_4b.h new file mode 100644 index 00000000..6a9823e1 --- /dev/null +++ b/libs/libiconv/lib/cns11643_4b.h @@ -0,0 +1,668 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CNS 11643-1992 plane 4 part b + */ + +static const unsigned short cns11643_4b_2uni_page40[4384] = { + /* 0x40 */ + 0xb65b, 0xb66a, 0x1011, 0xb668, 0x101b, 0x1012, 0x100e, 0x1015, + 0x3f68, 0x1010, 0xb681, 0x1017, 0x4046, 0x4043, 0x1070, 0x10ed, + 0xbae7, 0x10ee, 0xbae6, 0xbad1, 0xbb11, 0x4181, 0xbad0, 0xbad9, + 0xbb0a, 0x10f4, 0xbada, 0xbadd, 0xbac8, 0xbae2, 0xbae9, 0xbacb, + 0x417c, 0xbacc, 0xbac1, 0x416a, 0xbade, 0x4188, 0x10f2, 0x10f8, + 0x10f3, 0xbb51, 0xbb12, 0x10fa, 0xbae0, 0xbb2b, 0xf6b4, 0xc0d8, + 0xc0d1, 0x4410, 0xc0d2, 0xc0cd, 0x441f, 0x11b6, 0x11b7, 0xc13d, + 0x440f, 0xc0ca, 0x11ba, 0xc0cb, 0x11bc, 0xc0d7, 0xc3f4, 0x123b, + 0x45d3, 0x122f, 0xc487, 0xc48b, 0xc483, 0x1237, 0x1299, 0xc7c5, + 0xc7d2, 0xc7c6, 0xc7d3, 0x12d9, 0x12d8, 0x12d7, 0xc7f0, 0xc7cd, + 0xc7cc, 0xc7dc, 0xc7d6, 0x1336, 0xc9e6, 0xca41, 0xca3f, 0x4987, + 0xcac5, 0xcac0, 0xcac6, 0xcabe, 0xcabf, 0x49c6, + /* 0x41 */ + 0x1370, 0xcb63, 0xccd3, 0xccda, 0xccd5, 0x13a5, 0x13a6, 0x13a9, + 0x13ee, 0x1454, 0xd0ee, 0x1457, 0xd0fc, 0xd214, 0x14a1, 0xd323, + 0xd322, 0xd330, 0xd4b5, 0x14d3, 0xd538, 0x14d4, 0xd53f, 0x14d7, + 0x4dcc, 0x4e6d, 0x4e70, 0x14f7, 0x14f6, 0x14f9, 0x14f8, 0x4f58, + 0x4f42, 0x4f68, 0x4f69, 0xd768, 0xd767, 0x4f43, 0xd765, 0x4f47, + 0x158a, 0xda75, 0xdaf7, 0xdaf3, 0xdaf6, 0x1594, 0xdb00, 0x1593, + 0xdaff, 0xdaf5, 0x529d, 0x15dd, 0x15dc, 0x15f7, 0x53cf, 0xde92, + 0xe006, 0x1642, 0xe007, 0xe06b, 0x1654, 0xe06c, 0x1655, 0xe193, + 0x168f, 0xe194, 0x54f4, 0x16b4, 0x16b3, 0xe262, 0xe263, 0x5509, + 0xe25f, 0xe264, 0xe25b, 0xe259, 0x16fb, 0x16fd, 0xe3a4, 0xe3ac, + 0x55ab, 0x16fc, 0xe4b5, 0x172c, 0x172f, 0xe4ae, 0x172b, 0xe4c5, + 0x1733, 0x1734, 0x55fb, 0xe63b, 0x57ac, 0x57ae, + /* 0x42 */ + 0x57aa, 0x17e8, 0xe8bf, 0xea2b, 0xea84, 0xea80, 0xeb4d, 0xeb4f, + 0x585c, 0xeb4c, 0xed92, 0x195d, 0x1ad2, 0x0085, 0x0088, 0x5fae, + 0x5f79, 0x008e, 0x0084, 0x5f71, 0x1adf, 0x5fb3, 0x0083, 0x5f2c, + 0x5f77, 0x612f, 0x63c3, 0x0102, 0x63cd, 0x0106, 0x0105, 0x63c9, + 0x00fe, 0x0101, 0x0100, 0x63ce, 0x64a5, 0x64a0, 0x64fe, 0x6559, + 0x669a, 0x01e7, 0x1e19, 0x68e4, 0x68d7, 0x68dc, 0x01e6, 0x68e7, + 0x01ed, 0x01e2, 0x01eb, 0x68e5, 0x01e8, 0x01ec, 0x1e0a, 0x0224, + 0x1f9a, 0x6e14, 0x0262, 0x6df1, 0x0261, 0x0260, 0x0264, 0x028b, + 0x6fb6, 0x706e, 0x706c, 0x7081, 0x7142, 0x0319, 0x0316, 0x0318, + 0x0322, 0x711a, 0x031d, 0x0317, 0x031e, 0x7127, 0x7125, 0x7117, + 0x711c, 0x713d, 0x7120, 0x0369, 0x036a, 0x7381, 0x036c, 0x037a, + 0x038a, 0x7509, 0x75c6, 0x75c4, 0x039c, 0x75c5, + /* 0x43 */ + 0x03fd, 0x03f9, 0x76ef, 0x03ff, 0x76df, 0x76de, 0x76ee, 0x76f5, + 0x76ec, 0x03fc, 0x76dd, 0x2385, 0x03fb, 0x0402, 0x045f, 0x2456, + 0x045e, 0x045d, 0x045c, 0x7822, 0x2451, 0x0492, 0x7997, 0x7995, + 0x0494, 0x0495, 0x04d1, 0x7ba9, 0x04f1, 0x7c53, 0x25b1, 0x7c56, + 0x7c55, 0x0577, 0x056f, 0x7de3, 0x7de2, 0x0587, 0x057d, 0x057c, + 0x057e, 0x0585, 0x058b, 0x0586, 0x0580, 0x5dfd, 0x7da9, 0x0578, + 0xf5ab, 0x7e33, 0x7e0a, 0x05ba, 0x8059, 0x0633, 0x81bc, 0x062d, + 0x81c4, 0x81c7, 0x81c6, 0x0637, 0x275a, 0x2763, 0x81b8, 0x81da, + 0x062e, 0x81b7, 0x81c0, 0x063d, 0x81cd, 0x06a0, 0x84bc, 0x84ab, + 0x06a3, 0x8586, 0x299b, 0x875a, 0x29a3, 0x070e, 0x299e, 0x8843, + 0x07b6, 0x89ac, 0x07ab, 0x07ad, 0x07a6, 0x89be, 0x2ab8, 0x07aa, + 0x2aba, 0x07b1, 0x89ab, 0x07a8, 0x07af, 0x07b0, + /* 0x44 */ + 0x07a7, 0x07b2, 0x079d, 0x07a5, 0x07b5, 0x743e, 0x2ac7, 0x2ad7, + 0x8cf9, 0x0841, 0x8cf3, 0x8cf7, 0x2c70, 0x8e45, 0x8e48, 0x0872, + 0x2c9d, 0x086f, 0x0871, 0x8e44, 0x0885, 0x8eaf, 0x8eb1, 0x08a4, + 0x08a5, 0x08a6, 0x8fcf, 0x08a8, 0x8fcb, 0x8fcd, 0x08a3, 0x9050, + 0x91ec, 0x921a, 0x2d16, 0x2d24, 0x91d8, 0x0943, 0x91d0, 0x91d1, + 0x093d, 0x0945, 0x917b, 0x91d2, 0x0944, 0x91d4, 0x91e7, 0x91df, + 0x91de, 0x2d45, 0x91d9, 0x91cf, 0x950d, 0x09e3, 0x2f79, 0x5dfd, + 0x09df, 0x09e4, 0x2f7a, 0x09e5, 0x9538, 0x3054, 0x0a22, 0x0a4a, + 0x98a9, 0x0a49, 0x0a44, 0x0a4b, 0x0a87, 0x0a89, 0x0a92, 0x0a91, + 0x0a90, 0x0a8e, 0x993e, 0x9946, 0x9aed, 0xf630, 0x0b12, 0x0b10, + 0x0b11, 0x9c6c, 0x0b32, 0x0b34, 0x0b37, 0x0b33, 0x0b36, 0x0b35, + 0x0b65, 0x9dac, 0x337c, 0x337b, 0x9ec9, 0x3412, + /* 0x45 */ + 0x0bb0, 0x9f12, 0x0baf, 0x0baa, 0x9efd, 0x9f01, 0x9f11, 0x0bab, + 0x9f89, 0x9f05, 0x9efe, 0x9f0b, 0x9f20, 0x9f04, 0xa088, 0x0bf3, + 0xa102, 0x0bf4, 0xa103, 0x34b6, 0x34e0, 0x0c08, 0x0c4e, 0x0c55, + 0x0c4b, 0xa229, 0xa23b, 0x0c4d, 0x3573, 0xa206, 0x0c52, 0x3572, + 0x0c4c, 0x3570, 0x0c50, 0x0c53, 0xa203, 0x0c51, 0xa378, 0xa379, + 0xa37d, 0x0c89, 0xa37f, 0x0c95, 0x0ccc, 0x0cc8, 0x0cce, 0xa432, + 0x0cca, 0xa400, 0x369d, 0xa422, 0x0ccd, 0xa5a9, 0x0d5c, 0x0d67, + 0x0d69, 0x0d65, 0x0d62, 0xa704, 0x3827, 0x3835, 0xf659, 0x0daa, + 0xa8b8, 0xa99b, 0x0dd2, 0x39a2, 0x0e03, 0x0e0c, 0xaa92, 0x0e09, + 0x0e06, 0x0e05, 0x3989, 0xaa8f, 0x0e0b, 0x0e08, 0xaa98, 0x39a5, + 0xaaae, 0x0e8e, 0xad9d, 0x3ab6, 0x0ee8, 0xaf49, 0xaf50, 0xaf46, + 0x0eea, 0xaf4e, 0x3ba5, 0x3bc3, 0xaf55, 0x0ee9, + /* 0x46 */ + 0x0eeb, 0xaf64, 0x0ef0, 0xb138, 0x0f4b, 0x3dab, 0x0f73, 0x0f75, + 0x0f92, 0x0f91, 0x0f93, 0x3e25, 0x0fa7, 0x0fa6, 0x0fa8, 0x0faa, + 0xb3fe, 0x0fa9, 0x3e59, 0x0fbb, 0x0fbc, 0x0fba, 0x0fbd, 0x1027, + 0x3f85, 0xb6a6, 0x1024, 0x101e, 0x101f, 0x101d, 0x1020, 0x1023, + 0x1029, 0x1022, 0xb69c, 0xb699, 0x101c, 0x3f8e, 0x1028, 0xb6b5, + 0xb6a3, 0xb6a0, 0xb6a7, 0xb69b, 0xb8df, 0xb8e1, 0x1071, 0x1073, + 0x1072, 0xb94d, 0x1102, 0xbbf3, 0xbb6f, 0xbb69, 0x10fe, 0x41be, + 0xbb6b, 0xbb78, 0xbb87, 0x1108, 0xbb85, 0xbb82, 0xbb90, 0x1107, + 0x1104, 0xbb80, 0xbb67, 0x1100, 0x10fc, 0xbb61, 0x1144, 0xbb93, + 0x10f1, 0xbbf2, 0xbb86, 0x41a6, 0x1106, 0xbfcd, 0xbfc4, 0x11c6, + 0x11c3, 0x11c1, 0x11c2, 0xc10f, 0x11c4, 0x11c7, 0xc10d, 0x11bf, + 0x11d2, 0xc173, 0x11ca, 0xf6ba, 0xc10a, 0x442f, + /* 0x47 */ + 0xc108, 0xc113, 0x1213, 0xc3f8, 0x1230, 0x123e, 0x1239, 0xc4ab, + 0xc4a8, 0x123c, 0x123f, 0xc4a5, 0x1234, 0x123d, 0xc4c3, 0xc4a4, + 0x1238, 0xc4d4, 0xc4ba, 0xc5f1, 0x46a0, 0x1282, 0xc63f, 0x1283, + 0xc6ea, 0x129b, 0xc7f7, 0x12e0, 0x12dd, 0xc7fa, 0xc7f5, 0x12de, + 0xc7fe, 0x12e3, 0x12e5, 0xc800, 0x4797, 0x12e2, 0xc802, 0xc7fb, + 0xc807, 0x12df, 0xc81a, 0x132e, 0xc9b8, 0x1337, 0x1338, 0xc9e9, + 0xc9eb, 0xca50, 0xca4f, 0x498b, 0xcb86, 0x0162, 0xcb8e, 0x1394, + 0x1393, 0x13ab, 0x13ad, 0xccf0, 0xccfb, 0x13f5, 0x13f7, 0xce42, + 0x13f6, 0x13f8, 0xce85, 0x13fb, 0x13f9, 0x1458, 0x145a, 0xd105, + 0x1459, 0x4c0f, 0x1485, 0x14a4, 0x14d8, 0x14d9, 0xd54b, 0x14dd, + 0x14c8, 0xd563, 0x14fa, 0x14fb, 0x4f75, 0x1527, 0x4f9f, 0x152a, + 0x1525, 0xd799, 0x1528, 0xda81, 0xdb17, 0xdb10, + /* 0x48 */ + 0xdb12, 0x52a6, 0x1595, 0x539a, 0xdcfa, 0xdcf3, 0xdcf2, 0xdcf5, + 0xdcf6, 0xddbb, 0xddc2, 0xdea7, 0x160f, 0x1611, 0xdea8, 0xdea3, + 0x1610, 0xdeaa, 0x1615, 0x1613, 0x5457, 0xdfdc, 0x1647, 0x1646, + 0xe00f, 0x1659, 0x165b, 0xe079, 0x165e, 0xe07f, 0xe085, 0x165a, + 0x1691, 0x1692, 0x1690, 0x1693, 0xe21b, 0x54f7, 0x16be, 0xe277, + 0xe276, 0xe298, 0x16bc, 0x16bb, 0x16b7, 0x16b9, 0xe27a, 0x1701, + 0x16fe, 0xe3bc, 0xe3ba, 0x1702, 0xe3b6, 0x16ff, 0x55b0, 0xe3b4, + 0x1700, 0xe4cf, 0x1737, 0x173a, 0x176f, 0x1777, 0x1779, 0x56c6, + 0xe67b, 0x17c8, 0xe81c, 0xe821, 0xe81d, 0xe8c0, 0x17f2, 0xe8ff, + 0x17f1, 0x17f0, 0x5862, 0xeb56, 0x1834, 0xeda1, 0xeda2, 0xeda6, + 0xf056, 0xf057, 0x192c, 0x192d, 0xf101, 0xf1ed, 0xf71c, 0xf3f2, + 0x1afa, 0x5fb8, 0x0091, 0x5fc0, 0x0094, 0x5fb7, + /* 0x49 */ + 0x5fe1, 0x00c4, 0x010a, 0x63e8, 0x1c85, 0x64b2, 0x0152, 0x66ae, + 0x0159, 0x026f, 0x697e, 0x01f2, 0x01f4, 0x1e43, 0x6976, 0x01f1, + 0x1e3c, 0x6996, 0x026a, 0x6e20, 0x6e21, 0x6e23, 0x6e29, 0x7077, + 0x7151, 0x0324, 0x7156, 0x0323, 0x7188, 0x7159, 0x7155, 0x0327, + 0x7297, 0x7298, 0x036d, 0x21ed, 0x036e, 0x036f, 0x73a1, 0x73a3, + 0x2235, 0x039f, 0x040a, 0x0406, 0x040e, 0x770a, 0x040d, 0x0405, + 0x773d, 0x770c, 0x040b, 0x0410, 0x042e, 0x783d, 0x7839, 0x79b0, + 0x79b2, 0x79ae, 0x0496, 0x0497, 0x04c4, 0x2547, 0x04c5, 0x7b20, + 0x04d2, 0x7c6e, 0x7c6d, 0x7c6a, 0x0581, 0x7e32, 0x058e, 0x0590, + 0x058f, 0x7e39, 0x0591, 0x0595, 0x0593, 0x7da3, 0x266d, 0x7e7f, + 0x7e35, 0x7e3d, 0x7ff4, 0x7ff5, 0x063b, 0x0648, 0x8248, 0x8228, + 0x0646, 0x0647, 0x8227, 0x8232, 0x822c, 0x064c, + /* 0x4a */ + 0x822e, 0x064a, 0x0650, 0x0643, 0x8223, 0x8231, 0xf5c5, 0x0649, + 0x06a6, 0x06a5, 0x06a4, 0x84c9, 0x8589, 0x06b9, 0x85bb, 0x06ce, + 0x06cf, 0x0713, 0x8897, 0x8893, 0x8a28, 0x07c6, 0x07c5, 0x07ca, + 0x07d9, 0x07c1, 0x8a18, 0x8a3b, 0x2af5, 0x8a27, 0x8a24, 0x8a1b, + 0x8a31, 0x07cb, 0x8a26, 0x8aa3, 0x8a3f, 0x8a22, 0x8a19, 0x2b03, + 0x8a41, 0x8a2b, 0x2b65, 0x0842, 0x8d0c, 0x2c75, 0x0874, 0x0873, + 0x8e4e, 0x8eb9, 0x8efa, 0x8fe9, 0x8fe8, 0x8fe4, 0x2d8a, 0x2d56, + 0x0952, 0x925f, 0x925d, 0x9252, 0x0950, 0x9274, 0x094b, 0x9246, + 0x094c, 0x096d, 0x92aa, 0x2d98, 0x924a, 0x9259, 0x924b, 0x094f, + 0x2d68, 0x09f0, 0x9550, 0x3034, 0x3045, 0x0a4d, 0x0a4c, 0x98d0, + 0x0a4f, 0x0a4e, 0x0a50, 0x98cc, 0x315c, 0x0a96, 0x3156, 0x9964, + 0x9965, 0x0a97, 0x0a95, 0x0a98, 0x995c, 0x9b15, + /* 0x4b */ + 0x0aec, 0x0aeb, 0x0b13, 0x0b14, 0x0b38, 0x0b3a, 0x0b39, 0x9c79, + 0x0b68, 0x0b67, 0x9dc5, 0x9db8, 0x9f2c, 0x0bbe, 0x0bbc, 0x9f37, + 0x9f35, 0x9f31, 0x0bbb, 0x9f2f, 0x0bba, 0x9f2b, 0x0bb9, 0x0bb7, + 0x9f2d, 0x9f2a, 0x0bc1, 0xa095, 0x0bf7, 0xa23e, 0x0c60, 0xa247, + 0xa245, 0x0c59, 0x0c5c, 0x0c5a, 0x0c58, 0xa252, 0x0c5b, 0xa270, + 0xa250, 0xa258, 0xa251, 0xa23d, 0x0c5d, 0xa241, 0xa20c, 0xa23c, + 0xa386, 0xa383, 0xa389, 0xa3f3, 0x0cd4, 0x0cd3, 0x36bf, 0x0cd2, + 0x36bd, 0xa42d, 0x0cd7, 0x0cd1, 0x36e4, 0x0cd5, 0xa5c5, 0xf655, + 0x0d6d, 0x0d6f, 0x3834, 0x0d75, 0x0d6c, 0x0d74, 0xa743, 0x0d73, + 0xa737, 0xa745, 0x3836, 0x0dac, 0xa8e5, 0xa9a6, 0xaadb, 0x0e10, + 0xaada, 0xaae6, 0x39ba, 0x39bc, 0x0e0f, 0x39c8, 0x0e23, 0x39c3, + 0x0e1d, 0x39b6, 0x0e0e, 0xaaf8, 0xaae9, 0x0e15, + /* 0x4c */ + 0x39c2, 0x0e13, 0xaae8, 0xaaf6, 0x0e1b, 0x39c5, 0x0e22, 0x0e26, + 0xaae7, 0x39bd, 0x39b0, 0x0e21, 0x0e1c, 0x0e17, 0xaad5, 0x0e1a, + 0x39bb, 0xadd3, 0xadc7, 0xadd1, 0x0e99, 0xadc3, 0x0e97, 0xaf80, + 0xaf98, 0x0efd, 0xaf84, 0x0ef6, 0x0efe, 0x0ef5, 0x0eff, 0x0ef7, + 0xaf97, 0xaf83, 0xaf81, 0x0f01, 0x3c04, 0xaf8c, 0xb142, 0xb2ab, + 0x0f77, 0xb2a3, 0xb2a6, 0xb35c, 0xb369, 0xb367, 0x0fab, 0xb48b, + 0xb4a8, 0x0fc0, 0xb6d8, 0x1031, 0x102e, 0xf689, 0xb6dc, 0x102c, + 0xb6e0, 0xb6e5, 0x1032, 0x102f, 0x102b, 0x102d, 0x1033, 0xb818, + 0xb819, 0x3ff1, 0x1057, 0x105c, 0x107b, 0xb95f, 0xb95e, 0x107a, + 0xbc02, 0x4222, 0x1113, 0x111e, 0x1117, 0x1120, 0x112a, 0x1111, + 0x1115, 0x110f, 0x1118, 0x4238, 0xbc12, 0xbc36, 0x112c, 0x4232, + 0xf6a8, 0x4210, 0xbc23, 0xbc03, 0x111c, 0xbc00, + /* 0x4d */ + 0x1129, 0xbc46, 0xbc61, 0x1112, 0x424f, 0x1197, 0xc184, 0x4472, + 0xc16b, 0xc162, 0xc156, 0xc16a, 0xc152, 0xc155, 0x11d4, 0x11d0, + 0x447c, 0xc161, 0xf6bb, 0xc158, 0xc177, 0x11d3, 0x1214, 0xc4d7, + 0x1246, 0x1245, 0xc4de, 0x1243, 0xc4df, 0x460d, 0x1244, 0x1248, + 0xc4d1, 0x1247, 0xc4e2, 0xc4e1, 0xc4dd, 0x4608, 0x1249, 0x1285, + 0xc64b, 0x1284, 0xc64e, 0x129d, 0xc6fc, 0x129e, 0x12a0, 0xc6fa, + 0x129c, 0xc6fb, 0x129f, 0xc6fe, 0x12f7, 0x12ea, 0xc831, 0x12ef, + 0x12e9, 0x12f3, 0x12f0, 0x12eb, 0xc838, 0x12ec, 0x12f2, 0x12f5, + 0x12ee, 0xc83a, 0xc9bb, 0x133a, 0x134b, 0xca59, 0x134a, 0x134c, + 0xcadb, 0xcadf, 0xcae2, 0x1379, 0x137b, 0x1378, 0xcb9e, 0xcba1, + 0x13b5, 0xcd10, 0x13b4, 0x13b7, 0x4a9e, 0x1409, 0x13fe, 0x1408, + 0x1407, 0xce76, 0xce7f, 0xce7d, 0x1406, 0x1404, + /* 0x4e */ + 0x1405, 0x13ff, 0x140b, 0xce82, 0xd057, 0x143b, 0x145d, 0x145c, + 0x145f, 0x145e, 0x4c28, 0xd12e, 0x4c21, 0x1483, 0xd38b, 0xd38d, + 0x14a7, 0x4d66, 0x4d6c, 0xd390, 0x14a8, 0xd4ec, 0xd56f, 0xd56b, + 0xd571, 0xd578, 0x4df6, 0x14e0, 0x14df, 0x14fe, 0x14fc, 0x14ff, + 0x14fd, 0xd7ad, 0x152c, 0x4fec, 0x4fba, 0x4fe3, 0x4fbd, 0x159d, + 0xdb2f, 0x52b4, 0xdd78, 0x1640, 0xdff8, 0xe019, 0x165f, 0xe09b, + 0xe094, 0xe097, 0xe099, 0xe1a6, 0xe1a4, 0xe1a7, 0x54d1, 0xe295, + 0x16c0, 0x5523, 0xe290, 0x16c1, 0x16c6, 0xe29b, 0xe3c4, 0x1704, + 0x1705, 0xe3c6, 0x560b, 0x173e, 0x173d, 0x1740, 0x173f, 0xe4e3, + 0x1742, 0xe4df, 0xe4dd, 0xe4e7, 0x1784, 0x1782, 0x177f, 0x1785, + 0xe82d, 0xe82c, 0x17cc, 0x57b2, 0x17cb, 0x17cd, 0xe834, 0xe838, + 0x57db, 0xe91d, 0x17f5, 0xe91a, 0xe91b, 0xe914, + /* 0x4f */ + 0x57f0, 0xe917, 0xea21, 0x1820, 0x1821, 0xeaaa, 0xeaa1, 0x1837, + 0x183e, 0x5873, 0x183d, 0x586e, 0xeb63, 0xeb79, 0xeb60, 0x5865, + 0xeb62, 0x183c, 0xeb61, 0x1838, 0x586a, 0xeb70, 0x586d, 0xeb6a, + 0x183b, 0xedc8, 0x18b0, 0xedc5, 0xedbe, 0xedc2, 0x18ad, 0x18b2, + 0x18b8, 0x5a0b, 0xedc7, 0x18af, 0xedb0, 0xedca, 0x191a, 0x5b76, + 0x1920, 0x1921, 0x1930, 0x5ba8, 0x192f, 0xf10d, 0xf107, 0xf196, + 0xf1ef, 0x195f, 0x1960, 0xf21e, 0xf21d, 0x5c11, 0xf390, 0x5feb, + 0x008a, 0x1b19, 0x009c, 0x5fee, 0x009a, 0x5fef, 0x5fec, 0x63fa, + 0x010c, 0x010b, 0x010d, 0x1c92, 0x6504, 0x69d3, 0x01fe, 0x69d1, + 0x69fa, 0x01ff, 0x01fb, 0x01fc, 0x0209, 0x69c8, 0x0200, 0x69d5, + 0x1e75, 0x69cd, 0x69d2, 0x69fb, 0x6c2a, 0x6e88, 0x6e61, 0x0271, + 0x6e63, 0x6e62, 0x206f, 0x5e57, 0x71c8, 0x7198, + /* 0x50 */ + 0x032b, 0x73c1, 0x773f, 0x7741, 0x0414, 0x0411, 0x0412, 0x7852, + 0x0463, 0x785e, 0x046e, 0x049a, 0x79c7, 0x049b, 0x7a70, 0x7b27, + 0x04c8, 0x7b71, 0x7bb0, 0x04f6, 0x7e42, 0x7e43, 0x26a5, 0x058c, + 0x0597, 0x05a2, 0x26a0, 0x7e57, 0x7e9d, 0x8289, 0x828d, 0x828b, + 0x8280, 0x8292, 0x828a, 0x82c8, 0x0654, 0x828f, 0x8293, 0x8291, + 0x06a8, 0x84f2, 0x84de, 0x06a9, 0x85c8, 0x28b4, 0x28d8, 0x29c2, + 0x0718, 0x0717, 0x071d, 0x87a7, 0x87a1, 0x0731, 0x8a8c, 0x8a7f, + 0x07d8, 0x07d5, 0x8a7b, 0x8a95, 0x8a99, 0x07e1, 0x8a8e, 0x07d4, + 0x8ada, 0x8a8a, 0x8a9c, 0x07e3, 0x8a7e, 0x0844, 0x0845, 0x8d1a, + 0x8e55, 0x0876, 0x0875, 0x8e60, 0x2ca8, 0x0888, 0x08aa, 0x8ffb, + 0x08ab, 0x08ac, 0x8ffd, 0x0957, 0x2d83, 0x0960, 0x095d, 0x096b, + 0x92d0, 0x0963, 0x0967, 0x92c5, 0x095e, 0x92d2, + /* 0x51 */ + 0x9311, 0x2dc5, 0x2fcd, 0x09f9, 0x09f3, 0x95ad, 0x95a4, 0x95a9, + 0x95b0, 0x959d, 0x09f6, 0x9798, 0x309c, 0x0a51, 0x0a53, 0x0a52, + 0x9992, 0x0a9b, 0x998a, 0x0a9c, 0x998d, 0x9996, 0x0af7, 0x3299, + 0x328f, 0x3291, 0x9b45, 0x9b4b, 0x9c0f, 0x9c16, 0x0b3b, 0x9c8a, + 0x0b3e, 0x0b3d, 0x9dc9, 0x0b69, 0x9dc8, 0x9dca, 0x9f64, 0x0bc3, + 0x0bc4, 0x0bc7, 0x9f5d, 0x9f63, 0x3439, 0x0bc6, 0x342e, 0x0bc8, + 0x9f88, 0xa03a, 0xa039, 0x349f, 0x34a0, 0x0be6, 0x0bf8, 0xa117, + 0xa193, 0x0c07, 0xa195, 0x0c64, 0x0c68, 0xa276, 0x3594, 0x0c65, + 0x35ae, 0xa280, 0xa27b, 0x0c69, 0xa248, 0xa2a8, 0xa288, 0xa38b, + 0xa38a, 0xa38c, 0xa3fc, 0x0cda, 0x0ce0, 0x36e6, 0xa458, 0x0cde, + 0xa451, 0xa455, 0xa453, 0x0d1c, 0x0d1d, 0x0d1a, 0xa5dc, 0x0d7b, + 0x0d7a, 0x0d7c, 0xa75c, 0x0d78, 0x0d77, 0xa765, + /* 0x52 */ + 0xf65a, 0x0db1, 0xa8ee, 0x0db2, 0x0db0, 0xa8f0, 0x38bc, 0xa8f2, + 0x0e36, 0xab35, 0x0e2e, 0xab22, 0x39d6, 0xab20, 0x0e34, 0xab2d, + 0xab28, 0xab26, 0xab3c, 0x0e2a, 0xab38, 0x0e33, 0x0e2d, 0x0e2f, + 0x0e31, 0x0e2b, 0x0e32, 0xab2a, 0x0e35, 0xab1a, 0xab30, 0xaae3, + 0xab19, 0xade9, 0xade7, 0x3acf, 0xafd6, 0xafc4, 0x0f08, 0xaf87, + 0x0f06, 0xafc7, 0xafd9, 0x3c18, 0xafdf, 0x0f4d, 0x0f61, 0xb20a, + 0xb201, 0xb2b1, 0x0f78, 0xb2c1, 0x0f94, 0x0f95, 0xb376, 0xb40d, + 0xb40e, 0x0fc1, 0x0fc3, 0x3e6d, 0xb707, 0x1039, 0xb709, 0xb716, + 0x103a, 0x103b, 0x1035, 0x1036, 0xb70e, 0x103c, 0x3f90, 0xb706, + 0xb81e, 0xb84a, 0x1058, 0x107c, 0x107d, 0x108d, 0x108c, 0xbca6, + 0xbc91, 0x113b, 0x113f, 0xbcb8, 0xbc96, 0x1132, 0x112d, 0xbcc5, + 0x112f, 0x1139, 0x112e, 0x113a, 0xbd0a, 0x1136, + /* 0x53 */ + 0x1131, 0x113e, 0x1138, 0x4252, 0x1134, 0xbcb2, 0x1141, 0xbcb7, + 0xbcb4, 0xbc89, 0xbc8d, 0x1130, 0xbc87, 0xbcc2, 0xbc9c, 0xbc92, + 0x1143, 0xbcca, 0x4250, 0xbc8a, 0xbfe0, 0x1198, 0xbfe6, 0xbfe5, + 0x44a0, 0xc1a5, 0xc1b3, 0x4486, 0x11da, 0x11d7, 0xc1b5, 0xc1af, + 0x4495, 0xc1b0, 0xc1cc, 0x448c, 0xc1a2, 0xc1be, 0xc1c6, 0xc1ac, + 0xc1ae, 0x1218, 0x4560, 0xf6c3, 0xc508, 0xc505, 0x1252, 0x4628, + 0xc4fe, 0x124e, 0x4620, 0xc500, 0x124f, 0x1250, 0xc664, 0xc668, + 0x46a8, 0x1286, 0x1287, 0x1289, 0xc66a, 0xc669, 0xc70d, 0xc712, + 0x12a2, 0x12a3, 0xc70f, 0x12a1, 0xc867, 0xc879, 0xc872, 0xc866, + 0xc87c, 0x12f9, 0x12fd, 0xc868, 0xc885, 0xc876, 0xc874, 0xc871, + 0xc864, 0x133e, 0x133c, 0xc9f8, 0x134d, 0xca6c, 0x134e, 0xcaeb, + 0x1381, 0x1383, 0x1382, 0xcbb8, 0x1380, 0x1388, + /* 0x54 */ + 0xcd2d, 0xcd2e, 0xcd28, 0xcd29, 0xcd31, 0x13b9, 0xcd2f, 0xcd2a, + 0x4b3a, 0xcea4, 0xceb7, 0xcebf, 0x1411, 0x140d, 0x1410, 0x1413, + 0xd063, 0x143c, 0x1462, 0x1463, 0xd167, 0xd3be, 0xf6e0, 0xd595, + 0xd59c, 0x1503, 0x1506, 0x1502, 0x1501, 0xd671, 0xd672, 0x1505, + 0xd66f, 0x4e94, 0x5011, 0xd7f1, 0x5037, 0x1536, 0xd7e8, 0x1535, + 0x5043, 0xf6ea, 0x15a1, 0x15a3, 0xdb49, 0xdb64, 0x15a0, 0xdb48, + 0x15ea, 0x53a6, 0x15e8, 0xdd2c, 0xdde1, 0xddef, 0xdec0, 0x1621, + 0x161b, 0xded7, 0xded4, 0x1649, 0x1648, 0xe0ad, 0x5495, 0x1662, + 0x1661, 0x1664, 0x1660, 0x1663, 0xe0ae, 0xe0ac, 0x5496, 0x1666, + 0x16ac, 0x16ab, 0xe227, 0xe2ae, 0x16c3, 0xe2b0, 0x16c4, 0x5525, + 0xe2c0, 0xe2c4, 0x1708, 0x1709, 0x170a, 0x1706, 0x1707, 0x1741, + 0xe507, 0x1745, 0xe4fd, 0x1743, 0x1744, 0x5626, + /* 0x55 */ + 0x5634, 0x1747, 0xf704, 0xe61b, 0xe61c, 0x1771, 0xe6b2, 0xe6b4, + 0xe6b7, 0xe6b1, 0xe6b3, 0xe6ae, 0x178b, 0x17d4, 0x17d3, 0x17d1, + 0x57ba, 0x17d2, 0xe83f, 0xe936, 0x17f7, 0x17f8, 0xe931, 0xe93b, + 0xe935, 0xe93a, 0xe937, 0xea22, 0xea36, 0xea32, 0x1822, 0xeac0, + 0x1845, 0x1841, 0x5881, 0x1840, 0x588a, 0xeb85, 0x587f, 0x1842, + 0xeb89, 0x18c1, 0x18c5, 0xede1, 0x18bb, 0x18b9, 0x18bd, 0x18c9, + 0xee0a, 0x5a11, 0xee09, 0x18bf, 0x18c7, 0xede8, 0x18c3, 0x1924, + 0x1931, 0x1933, 0xf118, 0x1932, 0x1934, 0x1952, 0x1961, 0x5bd9, + 0x197a, 0x1982, 0x5c3c, 0xf3c5, 0x1b23, 0x600d, 0x600c, 0x6021, + 0x1b2c, 0x6216, 0x640e, 0x010f, 0x1c95, 0x6417, 0x0123, 0x0125, + 0x6a48, 0x0206, 0x0208, 0x1e88, 0x6a55, 0x6a49, 0x6a4c, 0x1e8b, + 0x6a4f, 0x6a3d, 0x027a, 0x0277, 0x6e8a, 0x6ea8, + /* 0x56 */ + 0x708a, 0x032e, 0x71cb, 0x032f, 0x71d5, 0x78d4, 0x041b, 0x0413, + 0x775c, 0x7775, 0x0466, 0x7861, 0x0465, 0x7096, 0x04f7, 0x7c8a, + 0x7ed0, 0x26e1, 0x26d7, 0x7e49, 0x7ecf, 0x059c, 0x82d6, 0x827f, + 0x0653, 0x82d2, 0x82cf, 0x8506, 0x8509, 0x06ba, 0x28a3, 0x0722, + 0x29d3, 0x8b06, 0x8af1, 0x8b04, 0x2b8b, 0x8afa, 0x8af4, 0x07eb, + 0x07dd, 0x8af9, 0x07ef, 0x8a8b, 0x8b03, 0x0847, 0x0846, 0x8da2, + 0x0878, 0x2cac, 0x0889, 0x900c, 0x900b, 0x0968, 0x0976, 0x0974, + 0x0979, 0x9324, 0x097a, 0x0977, 0xf614, 0x0971, 0x9325, 0x0972, + 0x95f6, 0x09ff, 0x95fb, 0x0a05, 0x9732, 0x97fb, 0x0a54, 0x98f2, + 0x98f3, 0x0a9e, 0x0a9f, 0x3174, 0x999c, 0x9b72, 0x0afa, 0x9b74, + 0x0b44, 0x0b3f, 0x0b40, 0x9c86, 0x0b42, 0x9c8e, 0x9c90, 0x0b51, + 0x9ccd, 0x9cf7, 0x9dd6, 0x9f84, 0x9f95, 0x9f8a, + /* 0x57 */ + 0x3440, 0x0bca, 0x9f97, 0x3441, 0x0bce, 0x0bc9, 0xa0a0, 0xa0a1, + 0xa122, 0xa1a6, 0xa1a4, 0x0c09, 0x34e8, 0x0c6c, 0x0c6e, 0x0c70, + 0x0c6d, 0x0c6b, 0x0c71, 0x0c72, 0xa2af, 0xa2b0, 0xa2bd, 0x0c8c, + 0x0ce4, 0xa476, 0x0ce1, 0xa47b, 0xa479, 0x36f6, 0x0ce7, 0x3700, + 0x0ce2, 0x0d1f, 0xa5ee, 0xa5f1, 0x0d7e, 0xa794, 0x0d80, 0x3859, + 0x3855, 0xa791, 0x0db9, 0x0db7, 0x0db8, 0xa910, 0x0dba, 0x38f4, + 0xa9af, 0x0dd3, 0x0e3f, 0x3a04, 0x0e45, 0x0e41, 0x3a15, 0x0e42, + 0x0e43, 0x0e3b, 0x0e38, 0xab7b, 0xab77, 0x0e3a, 0x39f5, 0xab80, + 0xabc6, 0x0e3c, 0xab7c, 0xab90, 0x0e3e, 0xaba3, 0xab7d, 0xabbd, + 0x0e9e, 0x0e9f, 0x0ea1, 0xae13, 0x0e9b, 0x0f12, 0xb011, 0xb044, + 0xb00d, 0x0f18, 0x0f0c, 0xb214, 0x0f62, 0xb2b8, 0x0f7a, 0xb2b7, + 0xb383, 0x0fae, 0x0faf, 0xb414, 0x0fad, 0xb41c, + /* 0x58 */ + 0x0fc4, 0x0fc7, 0x0fc6, 0x0fc5, 0xb4d4, 0xb4d5, 0x3fc1, 0x1040, + 0xb743, 0xb742, 0x103f, 0x1041, 0xf68a, 0xb741, 0xb84e, 0x107f, + 0xb987, 0x1086, 0x1081, 0x1080, 0x108e, 0x114a, 0xbd39, 0x1147, + 0xbd8f, 0xbd2a, 0x114b, 0x1146, 0x114e, 0x427d, 0xbd2b, 0x42a5, + 0xbd50, 0x1148, 0xbd6e, 0x1145, 0xbd3b, 0xbd53, 0xbd5f, 0xbd2f, + 0xbd30, 0xbd38, 0xbd4c, 0xbff1, 0x11db, 0x11e7, 0x11e4, 0xc207, + 0xc216, 0x11e1, 0xc214, 0x11e9, 0xc1fb, 0x11e5, 0x11e0, 0x11e3, + 0xc1f8, 0xc210, 0xc21d, 0xc1ff, 0xc20b, 0xc204, 0x11ea, 0xc1fe, + 0xc3ff, 0x463a, 0x1254, 0x1258, 0x125c, 0xc523, 0x1255, 0x128b, + 0x128c, 0x12a6, 0x12a5, 0xc72a, 0xc8a0, 0xc898, 0xc89c, 0x12ff, + 0xc89e, 0xc8a6, 0xc8b5, 0xc8b0, 0x1330, 0x1340, 0x1341, 0xcaf9, + 0xcaf5, 0x1386, 0xcbd2, 0x13bf, 0x13bd, 0xcd50, + /* 0x59 */ + 0xcd4e, 0xcd4b, 0xcd52, 0xcd4d, 0x13be, 0x1419, 0xcee4, 0x141c, + 0xceda, 0x141b, 0x1417, 0x1418, 0x4b51, 0xcedf, 0xcee8, 0x143d, + 0x146a, 0x1466, 0xd170, 0xd172, 0x1467, 0xd177, 0x1468, 0x14ad, + 0x14ae, 0xd3e6, 0xd5aa, 0x14d6, 0x1509, 0xd68c, 0x4e98, 0xd689, + 0x150c, 0x150a, 0xd832, 0x153b, 0x153a, 0x5084, 0x5081, 0xd87a, + 0x506f, 0xda9e, 0xdaa0, 0xdb70, 0x15af, 0x15aa, 0x15ab, 0xdb6e, + 0xdb66, 0x15b1, 0xdb65, 0x15ac, 0x15ec, 0xdd7f, 0xdde0, 0x1601, + 0xddff, 0xdef6, 0xdef7, 0xdef5, 0x1623, 0xdefc, 0x1624, 0x161e, + 0xdef9, 0x164a, 0x1665, 0x166a, 0xe0ca, 0xe0c3, 0xe0c6, 0x1669, + 0xe1b8, 0xe1bd, 0x1695, 0xe1bc, 0xe205, 0xe2e0, 0xe2e9, 0x5542, + 0xe2df, 0xe2ec, 0x16cc, 0xe2e5, 0xe2de, 0xf700, 0x16cf, 0xe2f0, + 0xe2e3, 0x170f, 0xe3ec, 0x170e, 0x170b, 0x1710, + /* 0x5a */ + 0x170d, 0x170c, 0xe3f2, 0xe3ef, 0xe3e9, 0xe4fb, 0x1746, 0x1748, + 0x5637, 0x1749, 0xe537, 0xe6de, 0x1791, 0x178e, 0xe6da, 0x17d8, + 0x17d6, 0xe84b, 0x17da, 0xe849, 0x17d7, 0xe8d5, 0x57ff, 0x17f9, + 0xe952, 0xe947, 0x17fc, 0xe948, 0xeacc, 0xead0, 0x58a9, 0x184a, + 0x58a7, 0x184e, 0x58b3, 0x58ac, 0x58b0, 0xeb86, 0xeba7, 0xeba3, + 0x589c, 0xebb6, 0xebad, 0xee13, 0x5a3c, 0x5a1c, 0x5a3a, 0x18d3, + 0x18cd, 0x18d1, 0xee17, 0xee22, 0x5a32, 0x5a34, 0xee49, 0xee26, + 0xf70c, 0xee3c, 0xee28, 0xf0a8, 0x5bc7, 0xf1fb, 0x1962, 0xf232, + 0xf2d6, 0xf348, 0x1983, 0x5c3f, 0xf3c6, 0x1992, 0x009f, 0x00a0, + 0x6025, 0x6026, 0x6024, 0x6033, 0x6170, 0x0127, 0x6790, 0x020b, + 0x6a95, 0x6aa1, 0x6a92, 0x6a8f, 0x6a9f, 0x6a96, 0x6a98, 0x6a9d, + 0x6aa0, 0x028d, 0x7097, 0x71eb, 0x0370, 0x7787, + /* 0x5b */ + 0x24eb, 0x7b32, 0x059a, 0x059f, 0x059d, 0x7ed8, 0x7efb, 0x7f06, + 0x059b, 0x7ed1, 0x26d5, 0xf5b0, 0x0660, 0x0664, 0x0669, 0x0663, + 0x0667, 0x0662, 0x82f6, 0x8304, 0x82fe, 0x2802, 0x82ff, 0x82f7, + 0x8518, 0x06ac, 0x8514, 0x85cd, 0x8620, 0x87de, 0x0726, 0x0723, + 0x0725, 0x8b45, 0x8b53, 0x07f8, 0x8b4b, 0x8b55, 0x8b41, 0x07f7, + 0x07fb, 0x07fa, 0x8b5c, 0x8b54, 0x8e71, 0x8ed0, 0x08b0, 0x08af, + 0x9053, 0x9329, 0x937e, 0x097e, 0x9379, 0x097d, 0x0980, 0x9370, + 0x936a, 0x097f, 0x0986, 0x9385, 0x9364, 0x2e12, 0x9378, 0x0981, + 0x9632, 0x9627, 0x962f, 0x0a24, 0x0a58, 0x0a57, 0x0aa0, 0x99ba, + 0x0afe, 0x9b71, 0x9b8c, 0x0b15, 0x9c1a, 0x0b47, 0x0b46, 0x9c98, + 0x9de4, 0x0b6b, 0x0b6c, 0x3385, 0x3454, 0x9fc2, 0x0bcc, 0x9fba, + 0x3455, 0x9fc8, 0x0bcb, 0x34a7, 0x34a8, 0x0bf9, + /* 0x5c */ + 0xa1b9, 0xa1b8, 0xa1a5, 0xa2e2, 0x0c78, 0x0c7a, 0x0c75, 0xa2d9, + 0x0c76, 0x0c77, 0xa2ac, 0xa2dd, 0x0cea, 0x0cee, 0x0ced, 0xa49d, + 0x0cec, 0x370f, 0xa611, 0xa603, 0x0d84, 0x0d85, 0x0d83, 0xa7ee, + 0x0dbc, 0x0dbd, 0x0dd4, 0xaba4, 0xabd8, 0xabdd, 0xabde, 0x0e55, + 0xabe7, 0x0e50, 0x0e4c, 0x0e48, 0xabd4, 0x0e53, 0xabce, 0x0e57, + 0x0e54, 0x0e4e, 0x0e4a, 0x0e51, 0xabf1, 0xabd3, 0x0e49, 0x0e4b, + 0x0e63, 0xabca, 0xabe9, 0x0ea7, 0x0ea6, 0x0ea4, 0xae1a, 0xae41, + 0xf668, 0x3ae4, 0x3ae5, 0xb03d, 0xb040, 0x3c65, 0x3c4e, 0x0f17, + 0xb043, 0x0f16, 0xb03f, 0xb03c, 0x0f63, 0xb221, 0xb220, 0x3d82, + 0xb2c6, 0x0f7b, 0x0f7c, 0xb2d1, 0xb2ca, 0xb38e, 0xb391, 0x0fb0, + 0x3e2d, 0xb4e3, 0xb788, 0x1042, 0xb770, 0x1044, 0xb89d, 0xb99d, + 0xb991, 0xb998, 0xb999, 0x1088, 0x108f, 0x1153, + /* 0x5d */ + 0x115b, 0xbdbf, 0x1159, 0xbdae, 0xbdb1, 0xbdcc, 0xbe04, 0x42ca, + 0xbe16, 0xbdcd, 0x1154, 0x42bc, 0xbde0, 0xbdcb, 0xbdd4, 0xbdc9, + 0xbfff, 0x1199, 0xbffd, 0xc257, 0xc252, 0xc250, 0xc245, 0xc24d, + 0x11f1, 0xc253, 0x11ef, 0xc282, 0xc244, 0xc3ce, 0xc3cf, 0xc3d2, + 0xc402, 0xc54f, 0xc558, 0x1262, 0xc543, 0x1263, 0xc552, 0x1260, + 0x1261, 0x125f, 0xc549, 0xc553, 0xc54d, 0x128d, 0xc684, 0x128e, + 0xc683, 0xc732, 0xc8e2, 0x1309, 0xc8e4, 0xc8d3, 0x1305, 0xc8d5, + 0xc8dd, 0x1303, 0x1306, 0xc8ec, 0xc8e6, 0xc8d2, 0xc8fa, 0xc8da, + 0x1331, 0xca06, 0xca04, 0x134f, 0xca7b, 0xcb04, 0xcb02, 0x1366, + 0x49ff, 0x13c4, 0xcd60, 0x13c3, 0x13c1, 0x13c5, 0xcf07, 0xcf05, + 0xcf0c, 0x1421, 0xcf5a, 0x141f, 0x1422, 0xcf1a, 0x1427, 0x1420, + 0xd18a, 0x146d, 0x146c, 0x146b, 0x146f, 0x1470, + /* 0x5e */ + 0xd18c, 0xd409, 0xd6a6, 0x4ea6, 0xd6ac, 0xd6a9, 0x1542, 0xd88b, + 0x50b6, 0xd88c, 0x1544, 0x1540, 0xd888, 0xd889, 0x153f, 0xd893, + 0x50ab, 0x158b, 0xdb83, 0xdd4f, 0x1625, 0x1628, 0xdf20, 0x5421, + 0xe036, 0xe0e2, 0x1675, 0x1672, 0xe0ee, 0x166f, 0xe0e7, 0xe0e9, + 0x1676, 0x1671, 0x54a7, 0xe0df, 0x1697, 0xe1c7, 0x16d7, 0xe309, + 0x16d6, 0xe301, 0x16d8, 0x16dc, 0x16db, 0x16d4, 0x553e, 0x1713, + 0x1711, 0x1714, 0xe405, 0xe40c, 0xe578, 0xe55d, 0x1751, 0x1750, + 0x1753, 0x1754, 0x1752, 0xe55e, 0xe560, 0xe567, 0x176d, 0xf705, + 0xe6f4, 0x1795, 0x1799, 0xe6f1, 0x179a, 0xe6fa, 0x1793, 0x1797, + 0xe6f8, 0xe6f9, 0xe709, 0xe6fd, 0xe6f7, 0x17dc, 0xe859, 0x17fd, + 0xe960, 0xe968, 0x17fe, 0x1800, 0x1802, 0x1801, 0x1803, 0xe96a, + 0xea14, 0xea3e, 0xeae4, 0x1827, 0x1826, 0x1824, + /* 0x5f */ + 0x184c, 0x58bc, 0x1850, 0x1855, 0x1853, 0x58b7, 0x1852, 0xebd2, + 0x1857, 0x58be, 0x1858, 0x18d6, 0xee58, 0xee50, 0x18d4, 0xee5c, + 0x18da, 0x18d9, 0xcf19, 0x5a62, 0x18d5, 0x18e4, 0xf70e, 0x18dc, + 0x191b, 0x5b8f, 0x1937, 0x1936, 0x194b, 0x5bcb, 0x1966, 0x1976, + 0xf2df, 0x197e, 0x197d, 0x197f, 0x1984, 0x198b, 0xf3d9, 0x1994, + 0x00a1, 0x0111, 0x6566, 0x0210, 0x1ea9, 0x6ae1, 0x6aef, 0x6ae8, + 0x6c33, 0x2013, 0x71fe, 0x0332, 0x21f4, 0x73ef, 0x73ec, 0x75ec, + 0x779c, 0x0420, 0x7799, 0x7870, 0x786e, 0x049d, 0x7b41, 0x26ec, + 0x26ef, 0x7f02, 0x7f01, 0x05a5, 0x801b, 0x8323, 0x8325, 0x8324, + 0x8326, 0x8333, 0x832f, 0x858f, 0x8856, 0x0802, 0x07fe, 0x0801, + 0x2bd6, 0x0803, 0x07ff, 0x8b99, 0x0804, 0xf5ed, 0x084a, 0x8ed9, + 0x0987, 0x93b7, 0x0984, 0x93b6, 0x0985, 0x3009, + /* 0x60 */ + 0x9654, 0x9657, 0x967a, 0x0a59, 0x3179, 0x9b8e, 0x32c6, 0x9b90, + 0x9bb9, 0x0b04, 0x0b49, 0x0b48, 0x9def, 0x0b6d, 0x0bd2, 0x0bd3, + 0x9fe2, 0x0bd1, 0x9fd6, 0x9fd8, 0x9fda, 0x9fde, 0x0be7, 0x0c0a, + 0x35c3, 0xa308, 0xa304, 0xa30a, 0xa30b, 0xa302, 0x0cf0, 0xa4aa, + 0xa4c1, 0x371f, 0xa7d7, 0xa7d9, 0x3865, 0xa7de, 0xa7da, 0x0dbe, + 0x0dbf, 0xa92a, 0x38c6, 0x3a3a, 0xac31, 0x3a36, 0xac2b, 0xac2c, + 0xac29, 0xac2e, 0x0e5e, 0xac27, 0xac28, 0x0e5b, 0xac5f, 0xac30, + 0xac24, 0x3aeb, 0x0eab, 0xae3a, 0x0eac, 0xae39, 0xae40, 0xb080, + 0xb084, 0x0f1f, 0x0f1d, 0xb075, 0xb076, 0x0f1c, 0xb07c, 0x0f1e, + 0xb078, 0xb09b, 0xb07e, 0xb15a, 0x0f64, 0xb22c, 0x3d84, 0xb39c, + 0xb747, 0xb78a, 0x1048, 0x1047, 0xb827, 0xbe4a, 0x115e, 0x1161, + 0xbe27, 0x42e0, 0x42f3, 0xbe2e, 0xbe26, 0xc008, + /* 0x61 */ + 0x11f7, 0xc2bd, 0xc296, 0x11f4, 0x11f8, 0x451e, 0xc2be, 0xc28e, + 0xc574, 0x1264, 0xc580, 0x1292, 0x128f, 0x1290, 0x46b4, 0x1293, + 0x12a8, 0xc73c, 0xc73d, 0x12a9, 0xc73a, 0xc742, 0x46f9, 0xc924, + 0xc906, 0x4844, 0x130e, 0xc915, 0x130f, 0xc902, 0xc90c, 0x130b, + 0xc908, 0xc90a, 0xc905, 0xc91c, 0x1310, 0x1351, 0xca82, 0x1350, + 0xca86, 0x1363, 0xcc03, 0xcd7b, 0x13c7, 0xcd7a, 0x4b71, 0x1424, + 0x1426, 0x4b6e, 0xcf80, 0x4b79, 0xcf58, 0x4bc4, 0x1474, 0x1473, + 0x1472, 0xd1aa, 0xd1ab, 0xd236, 0xd24a, 0x14b1, 0x4d8c, 0xd5d6, + 0x150e, 0x1511, 0x1510, 0x150f, 0x1512, 0x1549, 0x50c9, 0x154f, + 0x154d, 0xd903, 0xd8cf, 0x1555, 0xdb9f, 0xdba2, 0xde2a, 0xde2f, + 0xdf44, 0xdf40, 0x162c, 0x162b, 0xe111, 0xe10f, 0x1679, 0xe10d, + 0xe107, 0xe103, 0x167a, 0x54b0, 0x1699, 0x169a, + /* 0x62 */ + 0xe235, 0x16ae, 0x16af, 0xe304, 0x16e4, 0x16e1, 0x16de, 0x16e6, + 0x16df, 0xe326, 0x16e7, 0x16e2, 0x16e0, 0xe31e, 0x16e5, 0x555a, + 0xe40e, 0x1718, 0xe41d, 0xe41e, 0xe41f, 0x1756, 0xe588, 0x5646, + 0xe58d, 0xe591, 0xe580, 0x176e, 0xe654, 0xe655, 0x179d, 0x17a0, + 0x179c, 0xe725, 0xe71a, 0x17a1, 0x17a2, 0x179f, 0x17df, 0x17de, + 0x57c3, 0x17ea, 0xe988, 0x1806, 0xe97a, 0x1804, 0x580f, 0xe980, + 0xeb1e, 0xebfc, 0xec25, 0x185f, 0x58f4, 0x58fa, 0x185c, 0xec0b, + 0x185e, 0xec06, 0xec04, 0x58dd, 0x1859, 0xebf9, 0xec00, 0x1864, + 0x185d, 0x1862, 0xec02, 0x1865, 0xec07, 0x58ed, 0x185b, 0x58ef, + 0xeeb5, 0x18dd, 0xee87, 0x18df, 0xee93, 0xf70f, 0x18e2, 0xeebe, + 0xf066, 0x1927, 0xf0c7, 0xf0cf, 0x5b96, 0x193a, 0x193c, 0xf13d, + 0x1939, 0xf13c, 0xf147, 0x193d, 0x193b, 0x5bb3, + /* 0x63 */ + 0x194c, 0xf1c3, 0x1968, 0x5be2, 0xf31b, 0x1980, 0x1985, 0xf3c9, + 0x1995, 0xf3dd, 0x1996, 0xf493, 0x5c8f, 0x603d, 0x00a4, 0x0112, + 0x1eb1, 0x0225, 0x6ee6, 0x2141, 0x0337, 0x73f7, 0x77b0, 0x77ae, + 0x5dfd, 0x0468, 0x0467, 0x049e, 0x7c9f, 0x7c9e, 0x7f30, 0x05aa, + 0x7f4f, 0x05a9, 0x05a4, 0x7f27, 0x7f51, 0x0671, 0x066f, 0x8351, + 0x8354, 0x8356, 0x8527, 0x06ad, 0x8524, 0x2bf6, 0x080c, 0x2bf2, + 0x080b, 0x8bec, 0x8bc4, 0x080f, 0x0879, 0x93f8, 0x93f6, 0x93f7, + 0x93ed, 0x098d, 0x098f, 0x93f4, 0x93ef, 0x098e, 0x0a0c, 0x967f, + 0x96a2, 0x967e, 0x0aa6, 0x99c5, 0x0aa3, 0x0aa4, 0x0aa5, 0x3388, + 0x0b6e, 0x9ff1, 0x9ff2, 0x0bfa, 0xa12f, 0x0c7c, 0x0c7e, 0x0c7b, + 0x0c7d, 0xa323, 0xa329, 0x0c8d, 0x0cf4, 0x0cf3, 0xa61b, 0xa7eb, + 0x0d89, 0xa7ea, 0xa933, 0x0dc0, 0xac63, 0x0e65, + /* 0x64 */ + 0xac92, 0xac65, 0x0ead, 0x0f25, 0xb0a0, 0xf670, 0xb15e, 0x0fc9, + 0xb7aa, 0x104a, 0xb7a9, 0x4067, 0x1089, 0xbe9c, 0x1166, 0x1170, + 0xbe92, 0x116d, 0x1169, 0x1167, 0xbe86, 0x1172, 0x430e, 0x116e, + 0xbe83, 0x119c, 0x11fc, 0x11fd, 0x1204, 0x11ff, 0xf6c2, 0x11fe, + 0x1200, 0xc2ce, 0x1266, 0x1269, 0xc593, 0x12aa, 0x12ab, 0x1317, + 0xc92e, 0xc927, 0xc928, 0x1315, 0x485e, 0x1312, 0x4a0e, 0xcc18, + 0xcc16, 0xcd8d, 0x13ca, 0xcd8e, 0x13c9, 0x13cb, 0xcd90, 0xcd8f, + 0xcf81, 0x1429, 0x1428, 0xcf8a, 0xcf8c, 0xd08d, 0x1440, 0x1475, + 0x1476, 0xd1b2, 0x1488, 0xd5d9, 0x4eb6, 0x1557, 0x5101, 0xd90d, + 0x155f, 0xd913, 0x511d, 0x1558, 0x155b, 0xd91b, 0x512f, 0xdbac, + 0x15b3, 0xdbb3, 0x15ef, 0xdf5e, 0x1630, 0xdf60, 0xdf68, 0xdf63, + 0xdf69, 0xdf67, 0x1641, 0x164b, 0xe128, 0x167d, + /* 0x65 */ + 0xe12e, 0xe130, 0x167c, 0xe126, 0xe131, 0xe141, 0x54e0, 0xe1da, + 0x54db, 0xf6fa, 0xe20b, 0x5561, 0xe334, 0xe333, 0x16e8, 0x16ea, + 0x16e9, 0xe339, 0xe33b, 0xe340, 0xe430, 0x171b, 0xe432, 0xe437, + 0x1755, 0x564a, 0x1759, 0x1758, 0xe581, 0xe59f, 0xe5a7, 0x17a4, + 0x17a3, 0xe744, 0xe747, 0xe748, 0xe73d, 0x5733, 0x17a7, 0xe749, + 0x17e0, 0xe880, 0xe9a0, 0xe99d, 0x1808, 0x180a, 0x1809, 0xe99c, + 0xea47, 0xeb07, 0x1871, 0x590f, 0x186c, 0xec49, 0x5911, 0xec44, + 0x5903, 0x5901, 0x186e, 0xecdf, 0x5916, 0xec4c, 0x5dfd, 0xec4f, + 0x18e0, 0x18ee, 0xeec1, 0x18eb, 0xeeb9, 0xeecb, 0xeecf, 0xeec4, + 0x5a93, 0x18ea, 0x18ef, 0x18e7, 0xeeca, 0xeec3, 0xf0d0, 0xf151, + 0x1948, 0x1949, 0xf1a8, 0xf1c7, 0xf1c6, 0x194d, 0xf1ca, 0xf202, + 0x1955, 0xf25d, 0xf25a, 0x196a, 0x196c, 0xf259, + /* 0x66 */ + 0x196b, 0xf2cc, 0xf31c, 0xf3cc, 0x1998, 0x1999, 0x1997, 0xf3e8, + 0xf3ec, 0xf3ea, 0xf4ad, 0xf4b0, 0x605f, 0x6058, 0x6057, 0x1d5b, + 0x6793, 0x0216, 0x6b3b, 0x1ebf, 0x6b34, 0x6ef2, 0x0339, 0x73fd, + 0x751d, 0x0425, 0x23ce, 0x7a04, 0x7b48, 0x7f58, 0x834f, 0x0674, + 0x836e, 0x8372, 0x06ae, 0x852e, 0x8bfc, 0x8bf4, 0x9036, 0x940e, + 0x0992, 0x0994, 0x9414, 0x0995, 0x9419, 0x0a0d, 0x96a6, 0x0a25, + 0x9bc9, 0x9bc0, 0x9bcc, 0x9c1b, 0x9caa, 0x9ca8, 0xa003, 0x0bd5, + 0x0bd6, 0x34ac, 0x0be8, 0xa135, 0x0c7f, 0x35d2, 0x0cf5, 0x0cf6, + 0x0cf7, 0xa4d9, 0x0d24, 0x0d8d, 0x0d8a, 0xa93f, 0xa93d, 0x0e6c, + 0x0e66, 0x0e6a, 0xac8b, 0x0e67, 0x0e6d, 0x0e68, 0x3a52, 0xac68, + 0xac8a, 0xae58, 0xae57, 0xb0ce, 0xb0bc, 0xb0c0, 0xb0c1, 0xb0bf, + 0xb0ab, 0xb15f, 0x0f65, 0xb3a6, 0x0f9a, 0xb429, + /* 0x67 */ + 0x0fb1, 0x104b, 0x104d, 0x104c, 0x104e, 0xb7b8, 0x1173, 0x1175, + 0xbedd, 0xbed6, 0xf6b1, 0xbed5, 0xbee7, 0xbed8, 0xc2ec, 0x1203, + 0xc300, 0xc307, 0xc2fd, 0xc2f1, 0xc2ff, 0xc5aa, 0xc5b0, 0xc948, + 0x131e, 0xc953, 0x4873, 0xc94d, 0x1319, 0x131c, 0x131a, 0x131d, + 0x4876, 0xc943, 0xc950, 0x1343, 0x1352, 0xca8c, 0xcc27, 0x1395, + 0xcd99, 0x13cc, 0xcfb1, 0x142b, 0xcfb0, 0xcfaa, 0xcfac, 0x142a, + 0x4bc7, 0x1477, 0xd1c8, 0xd1ca, 0xd442, 0xd5e0, 0xd6e7, 0xd6e8, + 0xd6e6, 0x1513, 0x1514, 0x5134, 0xd95b, 0xd956, 0x155d, 0xd95a, + 0x1560, 0x513e, 0x1562, 0xdab8, 0xdbc5, 0x15b2, 0x15f0, 0xde48, + 0xdf7d, 0xdf7c, 0xdf81, 0xdf82, 0xdf62, 0x164c, 0xe145, 0x1682, + 0x54bc, 0x1681, 0x169b, 0xe1e3, 0x16a4, 0x16ee, 0x16ec, 0xe350, + 0x16ed, 0xe34f, 0x16f0, 0x16ef, 0xe439, 0x171d, + /* 0x68 */ + 0xe43a, 0x1760, 0x175e, 0x175d, 0xe5c1, 0xe74e, 0xe76e, 0x17b1, + 0x17ab, 0x17ac, 0x17ad, 0xe771, 0x17ae, 0xe88c, 0xe889, 0x17e2, + 0xe8e5, 0xe9b3, 0xe9b6, 0xe9b4, 0xea4d, 0x5839, 0xeb13, 0xec78, + 0x592a, 0x187b, 0x5926, 0x1878, 0x1875, 0x5927, 0xec72, 0x18f2, + 0x18f4, 0x18f3, 0x5ac0, 0x5ac9, 0xf075, 0xf0da, 0xf0d7, 0x193f, + 0x193e, 0x1940, 0x194e, 0x1957, 0x1959, 0x1958, 0xf716, 0xf269, + 0xf267, 0x196e, 0xf266, 0xf26f, 0xf271, 0x5bec, 0xf2cf, 0xf323, + 0x1981, 0x1986, 0xf3a5, 0x198f, 0xf3fe, 0xf3fb, 0xf3fd, 0x5c68, + 0x199b, 0x19b1, 0x19b3, 0x6b6d, 0x033a, 0x7405, 0x7520, 0x0427, + 0x77c8, 0x77c9, 0x046a, 0x05ac, 0x8627, 0x0818, 0x8c1e, 0x8d36, + 0x084c, 0x943d, 0x0996, 0x99d7, 0x0b4a, 0x9cad, 0x9e00, 0x0c81, + 0xa33a, 0x0c83, 0x0cf9, 0x0cf8, 0xa626, 0x0d8e, + /* 0x69 */ + 0x0d8f, 0x0dc1, 0xacb7, 0xacb6, 0xacc0, 0x0e70, 0xac9b, 0x0e71, + 0xb0d8, 0x0f2a, 0x0f2d, 0x0f7d, 0x3e32, 0x3e31, 0xb7c0, 0x104f, + 0xb7bf, 0xb9bf, 0x1090, 0xbf20, 0xbed0, 0xbf0e, 0x1179, 0xbf1d, + 0xbf1e, 0xbf15, 0xbf14, 0xc31e, 0xc32c, 0x1205, 0xc5b9, 0xc5b8, + 0xc5b6, 0xc69e, 0xc69c, 0xc74d, 0x46fd, 0xc96e, 0xc960, 0x1321, + 0xc964, 0xc962, 0xb0e5, 0x1332, 0xcda3, 0x13cd, 0x13cf, 0xd1d2, + 0xd1d5, 0x4d8e, 0x1516, 0x1515, 0x15b5, 0x1608, 0xde55, 0x1632, + 0xdf93, 0x1633, 0x1634, 0x163c, 0xe156, 0x54c2, 0xe1e9, 0x169c, + 0xe245, 0x16f4, 0x16f2, 0xe47c, 0x1762, 0xe5d3, 0x1761, 0x1764, + 0x17b5, 0x574b, 0x17b4, 0xe78e, 0xe897, 0x17e3, 0xe89b, 0xe899, + 0x581c, 0x180e, 0xe9cf, 0x581b, 0xea59, 0x182c, 0x182b, 0xeb20, + 0xeb23, 0xeb2a, 0x1885, 0x1881, 0x187e, 0x1883, + /* 0x6a */ + 0x1880, 0xecb0, 0x5942, 0xef2f, 0x5ad4, 0x18fb, 0x18f7, 0xef32, + 0xef43, 0xef3f, 0xef39, 0x18f8, 0xef30, 0xf0dd, 0xf1da, 0xf1db, + 0x195a, 0xf284, 0xf27f, 0xf272, 0xf280, 0xf2ee, 0x1978, 0xf32a, + 0xf322, 0xf371, 0xf3cd, 0x199d, 0x199c, 0xf40f, 0xf418, 0x606a, + 0x00a9, 0x00bf, 0x1ed0, 0x1ecf, 0x740c, 0x23da, 0x7ca6, 0x0677, + 0x0676, 0x8537, 0x06bb, 0x29ea, 0x8ee2, 0x099b, 0x96bc, 0x0a0f, + 0x0a5b, 0x9bd5, 0x0b4c, 0x0b6f, 0x0bd9, 0xa012, 0x0c82, 0xa34b, + 0xa341, 0xa3a1, 0xa4ec, 0x0e74, 0x0e72, 0xacd4, 0xacd8, 0xacd9, + 0x0e73, 0xacda, 0xae6c, 0xae6d, 0x0eb1, 0x0f2e, 0xb0e7, 0xb0eb, + 0xb0ec, 0xb162, 0x0f4e, 0xb42b, 0xb50d, 0xb7cd, 0xb9c3, 0xbf3f, + 0xbf3c, 0xbf3e, 0xbf3d, 0xbf3a, 0xbf38, 0xc344, 0xc345, 0x120b, + 0xc348, 0xc350, 0x126c, 0x4889, 0xc978, 0xc979, + /* 0x6b */ + 0x138b, 0xcc3e, 0x13d0, 0x142d, 0xd454, 0x14e4, 0x1571, 0xd9b9, + 0x5158, 0x156f, 0xde5f, 0x1687, 0x16a5, 0xe372, 0xe375, 0x171e, + 0x1765, 0x17b9, 0x17b7, 0x17b8, 0x17e4, 0xe8a3, 0xe8a5, 0xe9dc, + 0xe9dd, 0xea5a, 0x188c, 0x1889, 0x188a, 0xecdb, 0xecdc, 0x188b, + 0xefab, 0xef84, 0xef76, 0x1901, 0x18fe, 0x5ae7, 0x1903, 0x1906, + 0xef83, 0x5aea, 0x5af1, 0xf07f, 0x191d, 0x1943, 0xf173, 0xf1ad, + 0xf1b0, 0x194f, 0xf20f, 0xf20c, 0x195b, 0x1970, 0xf379, 0x1988, + 0xf377, 0xf37a, 0x1989, 0x5c44, 0xf432, 0xf427, 0xf42a, 0xf42c, + 0x5c6d, 0xf428, 0xf429, 0xf438, 0x642f, 0x6b7b, 0x740d, 0x23d9, + 0x77d6, 0x77d5, 0x83a1, 0x8c4c, 0x099e, 0x099f, 0x0aa7, 0x0b4b, + 0x0bdb, 0x0bda, 0xa0c0, 0x35d6, 0x0c8e, 0x0e76, 0xacf4, 0x0f30, + 0x0f2f, 0xb0f0, 0x0f66, 0xb23f, 0x117e, 0xc35d, + /* 0x6c */ + 0xc372, 0xc362, 0x453a, 0xc366, 0x4675, 0x126f, 0xc988, 0x13d1, + 0x142f, 0xcfe8, 0xcfe4, 0x14b2, 0x1518, 0x1517, 0xd6ff, 0x1576, + 0xdfaf, 0xdfae, 0x164f, 0x1689, 0xe1f2, 0xe248, 0xe381, 0xe37e, + 0x16f5, 0x171f, 0xe452, 0xe5ef, 0x575d, 0x17e5, 0xe8ad, 0xe9e6, + 0x1810, 0xe9ed, 0x180f, 0xe9e9, 0xea61, 0xea60, 0xeb33, 0x182f, + 0x1830, 0x5964, 0xed0b, 0xed08, 0x1893, 0x1894, 0xed07, 0x1907, + 0x1909, 0x1908, 0xefca, 0x190b, 0xefc6, 0x5b0a, 0xf084, 0xf0eb, + 0xf17d, 0x1950, 0x1971, 0xf29b, 0xf2a2, 0xf2a1, 0xf2a0, 0xf29c, + 0x197b, 0x197c, 0xf380, 0x5c73, 0xf440, 0x19a1, 0xf439, 0xf43c, + 0x19a0, 0x19a2, 0x64ca, 0x021b, 0x6b89, 0x0282, 0x853c, 0x8d40, + 0x9463, 0x9469, 0x0be9, 0xa353, 0x0c84, 0x35e1, 0xa817, 0xa81a, + 0xad00, 0x0eb3, 0x0f34, 0x0f33, 0x1180, 0xc36f, + /* 0x6d */ + 0xc6ab, 0x12ad, 0xc991, 0x1344, 0x1355, 0xcdb1, 0x13d2, 0xcfef, + 0xdbf1, 0xdbf2, 0xdfb7, 0xdfb5, 0x168a, 0xe386, 0xe45a, 0x1767, + 0xe7c6, 0xe7cb, 0x17e6, 0xe8b2, 0x1813, 0xe9f3, 0x582d, 0xed27, + 0x1897, 0x5b0c, 0xefd5, 0xefd8, 0x190c, 0xefec, 0xf087, 0xf0f2, + 0x1946, 0x195c, 0x1974, 0x1972, 0xf2ad, 0xf2b0, 0xf2fd, 0x5c1f, + 0xf387, 0xf44a, 0x19a4, 0x19a3, 0xf44e, 0xf449, 0xf451, 0xf44d, + 0x19b4, 0x6072, 0x0136, 0x7416, 0x8c6d, 0x8d41, 0x08b2, 0x9471, + 0x9474, 0x0b16, 0x3a70, 0x0e77, 0xae7c, 0x117f, 0xbf8a, 0xc756, + 0x147d, 0x5179, 0xd9fa, 0x544a, 0x168c, 0xe45b, 0x1768, 0x17be, + 0x1815, 0xeff5, 0xeff0, 0xf0f3, 0xf17f, 0xf213, 0x1975, 0x19a5, + 0x7419, 0x7f85, 0x83b0, 0x9477, 0xa4ff, 0x0e78, 0x0f35, 0x3c9d, + 0x1182, 0xbf87, 0x1183, 0xbf8b, 0x1271, 0xc99e, + /* 0x6e */ + 0x147e, 0x168e, 0xe38f, 0x5660, 0x1769, 0xe639, 0xe7d4, 0xe8f1, + 0xea02, 0xea6b, 0xeb40, 0x189a, 0x189b, 0xf010, 0xf2be, 0xf2b9, + 0x1990, 0xf464, 0x5c9e, 0x9be9, 0xbf90, 0x1186, 0x1185, 0xc01c, + 0x120e, 0xc392, 0xc6ae, 0xc9a3, 0x1519, 0xdfc9, 0x17c0, 0xe7d8, + 0xeb44, 0xf024, 0x5bf8, 0x5c3a, 0x5c7d, 0xf470, 0xf4d3, 0x0c0d, + 0x1816, 0xf2c3, 0x19a9, 0x19aa, 0x0c85, 0xad21, 0xb9ca, 0xc39c, + 0xea73, 0xf186, 0xf3c1, 0xea09, 0x5c96, 0xf4d5, 0x17c2, 0x1831, + 0x1911, 0x19ab, 0x189c, 0xdfd4, +}; + +static const ucs4_t cns11643_4b_2uni_upages[248] = { + 0x03400, 0x03500, 0x03600, 0x03700, 0x03800, 0x03900, 0x03a00, 0x03b00, + 0x03c00, 0x03d00, 0x03e00, 0x03f00, 0x04000, 0x04100, 0x04200, 0x04300, + 0x04400, 0x04500, 0x04600, 0x04700, 0x04800, 0x04900, 0x04a00, 0x04b00, + 0x04c00, 0x04d00, 0x05000, 0x05100, 0x05200, 0x05300, 0x05600, 0x05800, + 0x05900, 0x05b00, 0x05c00, 0x05d00, 0x05e00, 0x05f00, 0x06100, 0x06400, + 0x06500, 0x06600, 0x06900, 0x06a00, 0x06b00, 0x06f00, 0x07000, 0x07100, + 0x07200, 0x07300, 0x07400, 0x07500, 0x07600, 0x07700, 0x07800, 0x07900, + 0x07a00, 0x07b00, 0x07c00, 0x07d00, 0x07e00, 0x07f00, 0x08000, 0x08100, + 0x08200, 0x08400, 0x08500, 0x08600, 0x08700, 0x08800, 0x08900, 0x08a00, + 0x08b00, 0x08c00, 0x08d00, 0x08e00, 0x08f00, 0x09000, 0x09100, 0x09200, + 0x09300, 0x09400, 0x09500, 0x09600, 0x09700, 0x09800, 0x09900, 0x09a00, + 0x09b00, 0x09c00, 0x09d00, 0x09e00, 0x09f00, 0x0ff00, 0x20000, 0x20300, + 0x20400, 0x20500, 0x20600, 0x20700, 0x20800, 0x20900, 0x20a00, 0x20b00, + 0x20e00, 0x20f00, 0x21000, 0x21100, 0x21200, 0x21300, 0x21400, 0x21500, + 0x21600, 0x21800, 0x21900, 0x21a00, 0x21b00, 0x21c00, 0x21e00, 0x21f00, + 0x22100, 0x22200, 0x22300, 0x22400, 0x22500, 0x22700, 0x22800, 0x22900, + 0x22a00, 0x22c00, 0x22d00, 0x22e00, 0x22f00, 0x23000, 0x23100, 0x23200, + 0x23300, 0x23500, 0x23600, 0x23700, 0x23800, 0x23900, 0x23a00, 0x23b00, + 0x23c00, 0x23e00, 0x23f00, 0x24000, 0x24100, 0x24300, 0x24400, 0x24500, + 0x24600, 0x24800, 0x24900, 0x24a00, 0x24b00, 0x24c00, 0x24d00, 0x24e00, + 0x24f00, 0x25000, 0x25200, 0x25300, 0x25500, 0x25600, 0x25700, 0x25800, + 0x25900, 0x25a00, 0x25b00, 0x25c00, 0x25d00, 0x25e00, 0x25f00, 0x26000, + 0x26100, 0x26200, 0x26300, 0x26400, 0x26500, 0x26600, 0x26700, 0x26800, + 0x26900, 0x26a00, 0x26c00, 0x26d00, 0x26e00, 0x26f00, 0x27000, 0x27100, + 0x27200, 0x27300, 0x27400, 0x27500, 0x27600, 0x27700, 0x27800, 0x27900, + 0x27a00, 0x27b00, 0x27c00, 0x27d00, 0x27e00, 0x27f00, 0x28000, 0x28100, + 0x28200, 0x28300, 0x28400, 0x28500, 0x28600, 0x28700, 0x28800, 0x28900, + 0x28a00, 0x28b00, 0x28c00, 0x28d00, 0x28e00, 0x28f00, 0x29000, 0x29100, + 0x29200, 0x29300, 0x29400, 0x29500, 0x29600, 0x29700, 0x29800, 0x29900, + 0x29a00, 0x29b00, 0x29c00, 0x29d00, 0x29e00, 0x29f00, 0x2a000, 0x2a100, + 0x2a200, 0x2a300, 0x2a400, 0x2a500, 0x2a600, 0x2f800, 0x2f900, 0x2fa00, +}; + diff --git a/libs/libiconv/lib/cns11643_5.h b/libs/libiconv/lib/cns11643_5.h new file mode 100644 index 00000000..f0e5ebea --- /dev/null +++ b/libs/libiconv/lib/cns11643_5.h @@ -0,0 +1,1278 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CNS 11643-1992 plane 5 + */ + +static const unsigned short cns11643_5_2uni_page21[8603] = { + /* 0x21 */ + 0x3bd1, 0x3bcb, 0x3bc9, 0x3c0c, 0x3b00, 0x3b87, 0x3c0d, 0x3c0f, + 0xe21d, 0x5e98, 0x3bd2, 0x3c11, 0x3b7e, 0x45d3, 0x5052, 0x57fe, + 0x60a9, 0x7442, 0x3b09, 0x3bd6, 0x3fdd, 0x3fdc, 0x4002, 0x4073, + 0x4176, 0x41a7, 0x41a8, 0x4333, 0x43cc, 0x450d, 0x452c, 0x461b, + 0x015a, 0x461d, 0x4699, 0x4d3e, 0x582d, 0x582f, 0x5e99, 0x6eb3, + 0x74b6, 0x761b, 0x7fef, 0x83e9, 0x3b14, 0x3b94, 0x3be1, 0x4006, + 0x404a, 0x4044, 0x4131, 0x417a, 0x41ad, 0x41ae, 0x41b1, 0x4338, + 0x4337, 0x447d, 0x447e, 0x452d, 0x4532, 0x4623, 0x4626, 0xe23a, + 0x46a0, 0x51a8, 0x543f, 0x54bc, 0x56c4, 0x583b, 0x5b19, 0x5b18, + 0x5cb3, 0x5eaa, 0x5fbe, 0x60ac, 0x6525, 0x6566, 0x656b, 0x7443, + 0x74b5, 0x75ec, 0x7776, 0x08bc, 0x8114, 0x50dc, 0x821c, 0x821d, + 0x9fd0, 0xa112, 0xa5f3, 0xc169, 0x15b9, 0xc911, + /* 0x22 */ + 0xc915, 0xc910, 0xc913, 0x3ba4, 0x3ba5, 0x3cd0, 0x3cba, 0x3ccb, + 0x407b, 0x4186, 0x41bb, 0x41ba, 0x41c3, 0x41b9, 0x41c0, 0x00de, + 0x4339, 0x433b, 0x4341, 0x43d1, 0x43cf, 0x43d2, 0x442e, 0x446e, + 0x448c, 0x4488, 0x4535, 0x0143, 0x453a, 0x453b, 0x4538, 0x4539, + 0x462e, 0x462c, 0x46c8, 0x46b5, 0x46ad, 0x46b0, 0x46ab, 0x4cb3, + 0x4ca9, 0x51bb, 0x51b9, 0x565a, 0x56cd, 0x572b, 0x5805, 0x03ac, + 0x03aa, 0x5851, 0x584b, 0x5aea, 0x5aed, 0x5b36, 0x5b62, 0x5b56, + 0x5b55, 0x5b64, 0x5b58, 0x1c07, 0x5cda, 0x5cd8, 0x5ead, 0x5eab, + 0x5fc0, 0x5fc3, 0x60b3, 0x60b7, 0x60ba, 0x1dcb, 0x04fe, 0x60c7, + 0x60b5, 0x648e, 0x6573, 0x656c, 0x6574, 0xe2b4, 0x6572, 0x6571, + 0x6582, 0x6570, 0x6c3f, 0x6eba, 0x6eb8, 0x74b7, 0x8223, 0x8221, + 0x822b, 0x8226, 0x8222, 0x8825, 0x8be4, 0x8f15, + /* 0x23 */ + 0x9fe4, 0xa133, 0xa12a, 0xa132, 0xa129, 0xa5fb, 0xb45b, 0xb45c, + 0xb728, 0xc16f, 0xc16d, 0xc16b, 0xc16e, 0xc916, 0x3b22, 0x3c16, + 0x3c48, 0x3cd8, 0x3d00, 0x0041, 0x3f80, 0x3fe4, 0x00b4, 0x3fe7, + 0x400c, 0x4053, 0x40b7, 0x45e8, 0x41d1, 0x41e5, 0x41d8, 0x41d6, + 0x41da, 0x41d9, 0x41d5, 0x41e6, 0x41d4, 0x41d3, 0x4344, 0x43d6, + 0x43d7, 0x4413, 0x3afd, 0x4470, 0x4492, 0x44db, 0x44da, 0x4541, + 0x4543, 0x4633, 0x46f6, 0x46d4, 0x46dd, 0x46d0, 0x4704, 0x46d9, + 0x46db, 0x4705, 0x46d3, 0x46e1, 0x4d80, 0x4d77, 0x4d81, 0x4d82, + 0x4d83, 0xe25c, 0x5061, 0x5060, 0x51d8, 0x51d6, 0x51d7, 0x8105, + 0x544d, 0x5448, 0x56d6, 0x56cf, 0x56d9, 0x56d8, 0x573d, 0x03b3, + 0x5854, 0x585b, 0x585c, 0x03b4, 0x5859, 0x5858, 0x585a, 0x5855, + 0x5856, 0x5882, 0x5af0, 0x5b1c, 0x5b6a, 0x5b69, + /* 0x24 */ + 0x5b71, 0x5b67, 0x5b6c, 0x5b6e, 0x5b79, 0x5c8b, 0x5cb8, 0x5ce7, + 0x5ce8, 0x5ce4, 0x5ce6, 0x5ce5, 0x5cf0, 0x5e83, 0x5eb7, 0x5ebb, + 0x5eb9, 0x5ec5, 0x5f53, 0x5fc4, 0x5fc6, 0x5fcb, 0x60c8, 0xe29f, + 0x60c9, 0x60db, 0x6494, 0x6595, 0x6588, 0x658d, 0x69ec, 0x69ee, + 0x69f1, 0x6c2e, 0x6c49, 0x6e5f, 0x6ed1, 0x6ecb, 0x7385, 0x081d, + 0x744a, 0x7447, 0x744b, 0x74bb, 0x74c4, 0x087c, 0x7602, 0x7782, + 0x7791, 0x778f, 0x7792, 0x7c8f, 0x7c91, 0x7cb4, 0x7c92, 0x7ff4, + 0x80aa, 0x8235, 0x8237, 0x823d, 0x823c, 0x822f, 0x8230, 0x83f8, + 0x83ef, 0x8626, 0x0b55, 0x8826, 0x8827, 0x8a41, 0x8ac6, 0x8ac7, + 0x8beb, 0x8be8, 0x8bea, 0x8f1a, 0x8f19, 0x0d26, 0x9423, 0x9424, + 0x9925, 0xa135, 0xa134, 0xa507, 0xad1d, 0xb2e1, 0xb6ab, 0xbf60, + 0xc177, 0xc17d, 0x15bc, 0xc91e, 0xc91a, 0xc91d, + /* 0x25 */ + 0x3b6b, 0x3c2d, 0x3c4c, 0x3d2a, 0x004a, 0x3d15, 0x3d2c, 0x3d06, + 0x3d08, 0x3d0a, 0x004e, 0x4056, 0x4084, 0x00c9, 0x40c6, 0x41f5, + 0x4209, 0x41f8, 0x41e8, 0x41fb, 0x41e9, 0x41f6, 0x1ab7, 0x1ab8, + 0x4352, 0x1ab6, 0x1aba, 0x4354, 0x4351, 0x4439, 0x443a, 0x4498, + 0x454e, 0x017b, 0x4736, 0x470c, 0x4710, 0x4732, 0x4711, 0x4718, + 0x471c, 0x471a, 0x4719, 0x470b, 0x470f, 0x471d, 0x4721, 0x4713, + 0x471b, 0x4715, 0x0220, 0x4cd1, 0x4cc8, 0x4d8d, 0x4db5, 0x0289, + 0x0295, 0x50f8, 0x51e0, 0x51e1, 0x02be, 0x51de, 0x51fe, 0x51dc, + 0x5201, 0x51fd, 0x5200, 0x54d7, 0x54d6, 0x54d9, 0x5665, 0x56d2, + 0x56dc, 0x56e1, 0x56de, 0x5742, 0x574b, 0x03c3, 0x588e, 0x5891, + 0x588b, 0x5890, 0x5888, 0x5889, 0x5884, 0x58aa, 0x5b8d, 0x5b8f, + 0x5b7d, 0x5b7f, 0x5b7b, 0x5b80, 0x5b7e, 0x5b83, + /* 0x26 */ + 0x5b81, 0x5b86, 0x5b8a, 0x5cbd, 0x5cbe, 0x0477, 0x5cf4, 0x5cf3, + 0x5d02, 0x5cf6, 0x5cf5, 0x5cf2, 0x5d04, 0x5e3d, 0x5ec6, 0x5f89, + 0x5fd4, 0x5fd6, 0x5fd2, 0x60fa, 0x6106, 0x610c, 0x610a, 0x610f, + 0x652f, 0x05d4, 0x65b7, 0x65be, 0x65bc, 0x65e2, 0x6a06, 0x69f7, + 0x6a07, 0x69f6, 0x7635, 0x6c5f, 0x6c65, 0x6c64, 0x6c61, 0x6c5a, + 0x6c5d, 0xe2d7, 0x6ed7, 0x6ed5, 0x6ede, 0x6ee1, 0x6ee0, 0x6ed9, + 0x074c, 0x6eda, 0x6edf, 0x6ef6, 0x6f03, 0x0820, 0x7393, 0x738b, + 0x7391, 0x7392, 0x738a, 0x7389, 0x738f, 0x7456, 0x7459, 0x74ca, + 0x74cc, 0x085b, 0x74d0, 0x74cd, 0x74d6, 0x74cb, 0x7583, 0x7582, + 0x7606, 0x762a, 0x762c, 0x762b, 0x7629, 0x77bd, 0x77b3, 0x77be, + 0x77c0, 0x77b5, 0x77b6, 0x7c9d, 0x7c9f, 0x8120, 0x0a2d, 0x811e, + 0x811c, 0x8132, 0x811f, 0x812b, 0x8121, 0x8126, + /* 0x27 */ + 0x8124, 0x811d, 0x8127, 0x825b, 0x8259, 0x8280, 0x8255, 0x8250, + 0x825a, 0x8256, 0x8263, 0x8252, 0x8258, 0x0a63, 0x8239, 0x83f9, + 0x8628, 0x0b18, 0x86bc, 0x86d6, 0x8705, 0x8720, 0x0b74, 0x8833, + 0x8a46, 0x8a42, 0x8a43, 0x8a47, 0x8acb, 0x8b42, 0x8b45, 0x8bfd, + 0x8bf4, 0x8bf9, 0x8bfa, 0x8e5e, 0x8f1d, 0x0d28, 0x9258, 0x9255, + 0x9557, 0x9558, 0x95d9, 0x95dc, 0x95db, 0x9927, 0x9a85, 0x9a87, + 0x9a8a, 0x9d8b, 0x9e4f, 0xa030, 0xa02f, 0xa168, 0xa149, 0x0fda, + 0xa148, 0xa13f, 0xa14b, 0xa15c, 0xa146, 0xa140, 0xa50d, 0xa61b, + 0xa61d, 0xa617, 0x10a4, 0xa622, 0xb0a7, 0xb108, 0xb306, 0xbf7d, + 0x148e, 0xbf63, 0xbf64, 0xbf7f, 0xbf6b, 0xbf7c, 0xbf68, 0xbf65, + 0xbf6a, 0xc198, 0xc199, 0xc1ae, 0xc92b, 0xc92d, 0xc931, 0xc92e, + 0xc92f, 0x3b6d, 0x3c31, 0x3d2d, 0x3d39, 0x3d38, + /* 0x28 */ + 0x005b, 0x3d3a, 0x3d35, 0x3d62, 0x3fea, 0x3feb, 0x4015, 0x40cc, + 0x40c8, 0x40cd, 0x40db, 0x40cb, 0x4211, 0x4226, 0x4362, 0x435e, + 0x4361, 0x4441, 0x443f, 0x4475, 0x7465, 0x4649, 0x44eb, 0x451a, + 0x4557, 0x476b, 0x47a9, 0x4754, 0x4762, 0x47aa, 0x4758, 0x4772, + 0x4763, 0x4773, 0x478b, 0x478c, 0x475c, 0x4751, 0x4716, 0x4760, + 0x4761, 0x475e, 0x475d, 0x4764, 0x4753, 0x475f, 0x475b, 0x476e, + 0x4755, 0x4752, 0x4768, 0x4cd2, 0x4cd6, 0x4cd3, 0x4db8, 0x4dbb, + 0x4deb, 0x4de8, 0x4db6, 0x4dea, 0x4de7, 0x4de9, 0x5091, 0x5110, + 0x510e, 0x510f, 0x520b, 0x5203, 0x522b, 0x5209, 0x5228, 0x522c, + 0x5225, 0x5227, 0x520f, 0x54e9, 0x54ec, 0x0353, 0x5627, 0x5673, + 0x56e2, 0x56e6, 0xe276, 0x5761, 0x5751, 0x5812, 0x580e, 0x58ad, + 0x58af, 0x58b1, 0x58d3, 0x5b94, 0x5b92, 0x5b90, + /* 0x29 */ + 0x5b9d, 0x5b93, 0x5b95, 0x5b98, 0x5b97, 0x0480, 0xe28a, 0x5d07, + 0x5d0b, 0x5d08, 0x5ed9, 0x5ed5, 0x5fd7, 0x5fdf, 0x04dd, 0x5fde, + 0x5fe3, 0x5fe2, 0x04de, 0x6147, 0x0522, 0x613d, 0x6138, 0x6544, + 0x653a, 0x65b8, 0x662a, 0x6600, 0x65f3, 0x65f2, 0x65eb, 0x65fa, + 0x65ed, 0x65ec, 0x65ff, 0x65fb, 0x1f06, 0x664e, 0x65ef, 0x65f7, + 0x6a10, 0x6a11, 0x6a0c, 0x6a0b, 0x6bdd, 0x6c30, 0x06db, 0x6c7a, + 0x6c77, 0x6e28, 0x6e27, 0x6e65, 0x6f0e, 0x6f0b, 0x6f41, 0x6f13, + 0x6f0f, 0x6f12, 0x6f30, 0x73a0, 0x73a3, 0x739e, 0x7397, 0x73a1, + 0x739d, 0x739b, 0x7463, 0x74e3, 0x74e4, 0x74e6, 0x74e7, 0x74dd, + 0x2185, 0x74ec, 0x74e5, 0x74f1, 0x763b, 0x7639, 0x763a, 0x763c, + 0x763d, 0x7647, 0x763f, 0x7644, 0x7748, 0x7749, 0x7760, 0x77e3, + 0x77e9, 0x77f0, 0x08da, 0x08db, 0x77f2, 0x77ed, + /* 0x2a */ + 0x77ec, 0x77e6, 0x7816, 0x08d7, 0x7cbc, 0x7cbe, 0x7cc0, 0x7ce0, + 0x8000, 0x8002, 0x7ffe, 0x805e, 0x80b3, 0x80b7, 0x813a, 0x8139, + 0x813e, 0x8138, 0x813d, 0x814f, 0x826e, 0x825f, 0x8281, 0x8282, + 0x8271, 0x827b, 0x8279, 0x8277, 0x8273, 0x826f, 0x8297, 0x827e, + 0x83fc, 0x8411, 0x8432, 0x8431, 0x8410, 0x85ec, 0x85eb, 0x862c, + 0x862d, 0x86da, 0x872e, 0x872c, 0x872a, 0x8733, 0x874b, 0x8818, + 0x8842, 0x883b, 0x883f, 0x8841, 0x8843, 0x883c, 0x8a4c, 0x8a4a, + 0x8a49, 0x8a56, 0x8acf, 0x8b47, 0x8b48, 0x8b46, 0x8c1b, 0x8c11, + 0x8c14, 0x8c1d, 0x8c17, 0x8c1e, 0x8c0b, 0x8c1c, 0x8c12, 0x8c16, + 0x8c0d, 0x8c15, 0x8c13, 0x8c18, 0x0c1a, 0x8eac, 0x8f44, 0x8f2c, + 0x8f45, 0x9266, 0x926e, 0x9265, 0x9268, 0x9284, 0x9438, 0x943b, + 0x943a, 0x943f, 0x95df, 0x95dd, 0x95de, 0x95e2, + /* 0x2b */ + 0x0dd6, 0x992c, 0x992f, 0x9a8f, 0x9a90, 0x9a8c, 0x9a93, 0x9d25, + 0x9d88, 0x9da7, 0x9ef7, 0x9fbb, 0xa038, 0xa039, 0xa037, 0xa114, + 0xa16e, 0xa17b, 0x0fde, 0xa16c, 0xa17f, 0xa178, 0xa17a, 0xa16f, + 0x0fe5, 0xa3fe, 0xa648, 0xa64b, 0xa641, 0xa649, 0xa63b, 0xad2d, + 0xb0e3, 0xb11a, 0xb10d, 0xb113, 0xb111, 0xb11c, 0x1272, 0xb3b5, + 0x12af, 0xb729, 0xb7a1, 0xb824, 0xbabb, 0xbda1, 0xbf83, 0xbf8d, + 0xbf87, 0xbf85, 0xbf8a, 0xbfa3, 0xbf89, 0xbf84, 0xbfa2, 0xc1b1, + 0xc1b0, 0xc1af, 0xc1b6, 0xc1c9, 0xc1ca, 0xc1c8, 0xc1b4, 0xc759, + 0xc7c9, 0xc941, 0xc94c, 0x15c4, 0xc945, 0xc95a, 0x3bb9, 0x3d94, + 0x3d6e, 0x3da2, 0x3d67, 0x0063, 0x3da3, 0x3d76, 0x3d6c, 0x3d64, + 0x3da5, 0x3d30, 0x3da6, 0x3d69, 0x3da4, 0x3f90, 0x405f, 0x4060, + 0x40da, 0x40d8, 0x40dd, 0x00ec, 0x4259, 0x425b, + /* 0x2c */ + 0x425a, 0x4239, 0x4234, 0x4244, 0x4233, 0x423c, 0x4258, 0x426a, + 0x436f, 0x4372, 0x4370, 0x4371, 0x436e, 0x43f0, 0x43eb, 0x4449, + 0x444c, 0x44f5, 0x4520, 0x456a, 0x4572, 0x464b, 0x465d, 0x4750, + 0x47f9, 0x47fa, 0x47fb, 0x4823, 0x47b7, 0x4822, 0x47b5, 0x47c4, + 0x47b4, 0x47ef, 0x0198, 0x47cd, 0x47f0, 0x47b8, 0x47cb, 0x47f1, + 0x47ba, 0x4803, 0x47f8, 0x47b6, 0x47bc, 0x47b3, 0x4821, 0x47f7, + 0x47c2, 0x47be, 0x47c9, 0x47bd, 0x47ce, 0x47b9, 0x47c7, 0x47ca, + 0x47cc, 0x4826, 0x4ce4, 0x4ce0, 0x4cf0, 0x4dec, 0x4e24, 0x4e18, + 0x4e2f, 0x4e25, 0x5028, 0x5022, 0x506a, 0x3c57, 0x5094, 0x5092, + 0x509c, 0x5122, 0x5130, 0x511d, 0x5123, 0x5235, 0x5233, 0x522f, + 0x524d, 0x5231, 0x525b, 0x525a, 0x5232, 0x525c, 0x5259, 0x525d, + 0x5469, 0x546d, 0x5d32, 0x0358, 0x550a, 0x5520, + /* 0x2d */ + 0x551f, 0x550d, 0x56e8, 0x56ec, 0x5777, 0x5770, 0x5771, 0x58f8, + 0x58d6, 0x58d9, 0x58de, 0x58d5, 0x58e1, 0x03d3, 0x58e2, 0x58dd, + 0x58e0, 0x590e, 0x5908, 0x58dc, 0x590a, 0x590c, 0x5bb4, 0x5bb1, + 0x5bb6, 0x5bbc, 0x5d1d, 0x5d24, 0x5d19, 0x5d1b, 0x5d22, 0x5d1a, + 0x5d1c, 0x5d21, 0x5ee6, 0x5ee4, 0x5ee7, 0x5eea, 0x04e2, 0xe29b, + 0x5ff0, 0x5ff5, 0x5fef, 0x6142, 0x616e, 0x613c, 0x6197, 0x618c, + 0x6181, 0x6171, 0x61ce, 0x61ba, 0x617a, 0x617e, 0x0554, 0x6172, + 0x61bb, 0x052f, 0x6173, 0x6182, 0x05b6, 0x64ba, 0x64b8, 0x654b, + 0x6548, 0x662b, 0x65f4, 0x662c, 0x6642, 0x6648, 0x6644, 0x6645, + 0x663c, 0x6637, 0x6633, 0x6641, 0x6632, 0x6687, 0x6a27, 0x6a23, + 0x6a2d, 0x6a1f, 0x6a2c, 0x6a28, 0x6b75, 0x6b74, 0x6be7, 0x6c32, + 0x6c31, 0x6c99, 0x6c96, 0x6c98, 0x6c9d, 0x6c92, + /* 0x2e */ + 0x6c94, 0x6c95, 0x6c97, 0xa1b9, 0x0735, 0x6f11, 0x6f3b, 0x6f79, + 0x6f42, 0x6f43, 0x075d, 0x6f78, 0x73ac, 0x0829, 0x73b1, 0x73b4, + 0x73b3, 0x73af, 0x73aa, 0x73b2, 0x7468, 0x74f2, 0x74fe, 0x74f8, + 0x74f9, 0x74ff, 0x74f5, 0x74f7, 0x74fd, 0x7500, 0x7588, 0x766e, + 0x765d, 0x7663, 0x7660, 0x7761, 0x7837, 0x7871, 0x7823, 0x7822, + 0x781f, 0x7825, 0x7cfd, 0x7d11, 0x7d23, 0x7cf0, 0x7cef, 0x800e, + 0x800c, 0x80ba, 0x0a1f, 0x8152, 0x8155, 0x8153, 0x8154, 0x8151, + 0x8158, 0x82b0, 0x829f, 0x0a72, 0x82a1, 0x829a, 0x82be, 0x82a0, + 0x8437, 0x0b0b, 0x85f1, 0x85f2, 0x8634, 0x8637, 0x8635, 0x5e8c, + 0x86df, 0x874c, 0x874e, 0x8764, 0x8763, 0x8736, 0x8858, 0x8868, + 0x885b, 0x885f, 0x8859, 0x8865, 0x8860, 0x885e, 0x8ad5, 0x8ad6, + 0x8b4e, 0x8b52, 0x8c35, 0x8c39, 0x8c58, 0x8c41, + /* 0x2f */ + 0x8c57, 0x8c38, 0x8c3d, 0x8c32, 0x8c44, 0xe344, 0x8e63, 0x8e62, + 0x8eb8, 0x8eb0, 0x8eb1, 0x8f4d, 0x8f63, 0x8f70, 0x8f4b, 0x8f4f, + 0x8f4e, 0x8f53, 0x8f47, 0x0ca2, 0x8f54, 0x8f52, 0x8f59, 0x8f7e, + 0x912b, 0x912e, 0x927f, 0x927e, 0x9281, 0x9283, 0x9447, 0x9454, + 0x944d, 0x944c, 0x944b, 0x9457, 0x9565, 0x9564, 0x9561, 0x9562, + 0x95f0, 0x95f3, 0x95f9, 0x95f4, 0x95f5, 0x95ef, 0x95f8, 0x95fc, + 0x95f7, 0x95fd, 0x9617, 0x9934, 0x9936, 0x9938, 0x9aaf, 0x9aae, + 0x9aac, 0x9aa2, 0x9d28, 0x69c2, 0x9d9c, 0x9db3, 0x9d90, 0x9f06, + 0x9f04, 0x9f0b, 0x9f05, 0xa040, 0xa04f, 0xa1ab, 0xa19d, 0xa1b8, + 0xa1b2, 0xa1d2, 0xa1cf, 0xa1a2, 0x0fec, 0xa1a5, 0xa1a9, 0xa1a7, + 0xa1d0, 0xa402, 0xa4cf, 0xa4d0, 0xa516, 0xa519, 0xa675, 0xa671, + 0xa691, 0xa672, 0xa68e, 0xa66d, 0xa688, 0xa673, + /* 0x30 */ + 0x10bb, 0xa681, 0xa676, 0xa67b, 0xa67f, 0xa690, 0xa678, 0xad4b, + 0xad48, 0xad5b, 0xad51, 0xad3d, 0xad40, 0xad46, 0xad4d, 0xad3b, + 0xad4a, 0xad41, 0xad3e, 0xad4e, 0xb0ac, 0xb0e6, 0xb0e9, 0xb129, + 0x1221, 0xb133, 0xb12e, 0xb11e, 0x121f, 0xe3c5, 0xb122, 0xb127, + 0xb2e7, 0xb30b, 0xb466, 0xb6ad, 0xb6ae, 0x3038, 0xb72b, 0xb72a, + 0xb82c, 0xb82d, 0x1391, 0x1396, 0xb98f, 0xb993, 0xbac6, 0xbac5, + 0xbd15, 0xbd13, 0xbdb1, 0xbda9, 0x31ce, 0xbfa8, 0xbfab, 0xbfbe, + 0xbfac, 0xbfa9, 0xbfa6, 0xbfc1, 0xc1cc, 0xc1d1, 0xc1d3, 0xc1e4, + 0xc1cb, 0xc1e1, 0xc1d2, 0xc1e3, 0xc1cf, 0xc1d0, 0xc1e5, 0xc20e, + 0xc7cc, 0xc7ca, 0xc7cb, 0xc95c, 0xc961, 0xc95d, 0xc959, 0xcb77, + 0xd184, 0x3b41, 0x3bfd, 0x3c1a, 0x3c63, 0x3db6, 0x3db2, 0x3de9, + 0x3de7, 0x3dd6, 0x3e30, 0x3dec, 0x3ddd, 0x3de8, + /* 0x31 */ + 0x3db0, 0x3db5, 0x3de1, 0x3f98, 0x3f99, 0x00bc, 0x4093, 0x40e5, + 0x00d8, 0x4260, 0x425e, 0x00f4, 0x437b, 0x43f1, 0x43f3, 0x457f, + 0xe238, 0x4657, 0x4658, 0x4839, 0x48a7, 0x4835, 0x4860, 0x4851, + 0x4862, 0x4842, 0x483c, 0x4843, 0x48ab, 0x48a9, 0x48b4, 0x4879, + 0x486a, 0x483b, 0x48aa, 0x4833, 0x4837, 0x4827, 0x48a8, 0x4870, + 0x482f, 0x4836, 0x48b5, 0x4830, 0x483a, 0x4838, 0x48b1, 0x48ac, + 0x482e, 0x4875, 0x48b0, 0x4cf7, 0x4d00, 0x4cf1, 0x4cf3, 0x4e60, + 0x4e61, 0x4e32, 0x4e2d, 0x4e4a, 0x4e2a, 0x5067, 0x50a2, 0x50a3, + 0x509e, 0x50a4, 0x5144, 0x5132, 0x529b, 0x5298, 0x5299, 0x529a, + 0x5266, 0x5262, 0x526b, 0x8062, 0x5267, 0x553b, 0x5523, 0x5529, + 0x567e, 0x56f3, 0x0385, 0x56f5, 0x0383, 0x5780, 0x577e, 0x577c, + 0x577f, 0x577d, 0x5781, 0x5925, 0x5929, 0x5917, + /* 0x32 */ + 0x5963, 0x5967, 0x5965, 0x592a, 0x5968, 0x5926, 0x5964, 0x591b, + 0x5962, 0x5969, 0x5afe, 0x5b44, 0x5b42, 0x5bb7, 0x5bd2, 0x5bd4, + 0x5bd7, 0x5bdc, 0x5bd1, 0x5bd5, 0x5bcd, 0x5bd8, 0x5c9a, 0x5d42, + 0x5d35, 0x5d58, 0x5d34, 0x5d3c, 0x5d3b, 0x5d3e, 0x5d3d, 0x5d5a, + 0x5d41, 0x5d38, 0x5d45, 0x5d33, 0x5e26, 0x04ba, 0x5ef7, 0x5eef, + 0x5ef0, 0x5eee, 0x5f9d, 0x6006, 0x6011, 0x6008, 0x6002, 0x600a, + 0x6007, 0x6191, 0x618e, 0x6185, 0x61e8, 0x6217, 0x61d4, 0x0569, + 0x61c4, 0x61d5, 0x0545, 0x61d8, 0x6180, 0x61de, 0x6242, 0x64c7, + 0x64bf, 0x668d, 0x6689, 0x6690, 0x669a, 0x66c8, 0x6692, 0x66a1, + 0x6684, 0x6a57, 0x6a47, 0x6a77, 0x6a3a, 0x6a50, 0x6a42, 0x6a43, + 0x6aa3, 0x6b77, 0x6cb2, 0x6ce2, 0x6cbd, 0x6e74, 0x6f82, 0x6fb8, + 0x076c, 0x6fba, 0x6fb9, 0x6fbb, 0x6f87, 0xe2e4, + /* 0x33 */ + 0x6f83, 0x6fb7, 0x3b43, 0x73ce, 0x73ba, 0x7473, 0x7509, 0x750a, + 0x750b, 0x7507, 0x7505, 0x750e, 0x7597, 0x7677, 0x767b, 0x767a, + 0x7674, 0x7679, 0x7886, 0x78f5, 0x78a5, 0x789d, 0x78be, 0x7896, + 0x78e1, 0x78a4, 0x78a1, 0x78f6, 0x0904, 0x788d, 0x788b, 0x7878, + 0x7898, 0x790a, 0x7d5d, 0x7d27, 0x7d5f, 0x80c0, 0x80c1, 0x816d, + 0x815e, 0x818a, 0x8162, 0x8164, 0x0a3a, 0x82c0, 0x82ca, 0x82d1, + 0x0a79, 0x82c7, 0x82ce, 0x2309, 0x82c5, 0x8436, 0x8457, 0x8477, + 0x85f6, 0x85f7, 0x8655, 0x8644, 0x863e, 0x8642, 0x8652, 0x86e1, + 0x8708, 0x8768, 0x8767, 0x0b5d, 0xe337, 0x887e, 0x8893, 0x8879, + 0x8881, 0x887d, 0x887b, 0x8894, 0x0b8a, 0x8a66, 0x8ad9, 0x8ae0, + 0xe33e, 0x8b5f, 0x8c5f, 0x8c5e, 0x8c68, 0x0c27, 0x8c88, 0x8c6a, + 0x8c6c, 0x8c66, 0x8c67, 0x8c89, 0x8c60, 0x8c85, + /* 0x34 */ + 0x3e2a, 0x8e68, 0x8eb9, 0x8eba, 0x8ebe, 0x8f6f, 0x8f80, 0x8f74, + 0x8f81, 0x8f7a, 0x8f9c, 0x8f73, 0x8f82, 0x8f7f, 0x8fa7, 0x8f79, + 0x8f78, 0x8f7d, 0x8fa8, 0x8f7c, 0x9168, 0x914e, 0x929e, 0x0d46, + 0x0d40, 0x9298, 0x0d3f, 0x9285, 0x929c, 0x92c5, 0x929a, 0x9468, + 0x9465, 0x9467, 0x9461, 0x9460, 0x0d9d, 0x0dcb, 0x957b, 0x0de1, + 0x9619, 0x960e, 0x9631, 0x9612, 0x9610, 0x9615, 0x963f, 0x961d, + 0x961e, 0x994d, 0x9948, 0x9945, 0x9942, 0x9949, 0x994a, 0x9947, + 0x0e7f, 0x994c, 0x9acd, 0x9ad5, 0x9ac4, 0x9aca, 0x9ac3, 0x0f46, + 0x9d29, 0x9db4, 0x9e6d, 0x9e66, 0x9e6a, 0x9f15, 0x9fd3, 0x9fec, + 0xa055, 0x101a, 0xa1d6, 0xa1d8, 0xa251, 0xa1e0, 0xa203, 0xa204, + 0xa1da, 0xa1ea, 0xa202, 0xa1d3, 0xa1e4, 0xa1e5, 0xa43b, 0xa466, + 0xa52c, 0xa521, 0xa526, 0xa5d4, 0xa5d5, 0xa5d9, + /* 0x35 */ + 0xa6d5, 0xa6eb, 0xa6c5, 0x10d3, 0xa727, 0xa6f0, 0xa6b9, 0xa718, + 0xa6ee, 0x10d0, 0xa6b7, 0xa6bb, 0xa6ef, 0xa6b8, 0xa6df, 0xa6da, + 0xa6e3, 0xa6c9, 0xa6ec, 0xaca4, 0x118e, 0xaca3, 0xad5e, 0xad61, + 0xad62, 0xad63, 0xad8e, 0xad69, 0xad6b, 0xad85, 0xad8d, 0xad64, + 0xad6d, 0xb14c, 0xb149, 0xb147, 0xb148, 0xb142, 0xb145, 0xb15b, + 0xb15d, 0xb146, 0xb313, 0xb31a, 0xb30e, 0xb30f, 0xb31b, 0xb312, + 0xb3c3, 0xb3be, 0xb3bd, 0xb479, 0xb47c, 0x12c3, 0x12b6, 0xb480, + 0xb475, 0xb49b, 0x2f2f, 0xb474, 0x12c0, 0x12b8, 0x5b41, 0x5f94, + 0xb730, 0xb7a7, 0xb7a5, 0xb7a4, 0xb83a, 0xb95b, 0xb99f, 0xb9a8, + 0xb9b3, 0xb9a1, 0xb9a7, 0xb9b2, 0xb99d, 0xb9a3, 0xb9a2, 0xbaef, + 0xbad9, 0x13d9, 0xbad5, 0xbadd, 0xbada, 0xbaee, 0xbad7, 0xbd1a, + 0xbd19, 0xbd18, 0xbdb3, 0xbdbf, 0xbdbb, 0xbdc0, + /* 0x36 */ + 0xbdb9, 0xbdb8, 0xbdd5, 0xbf11, 0xbf10, 0xbfc3, 0xbfc2, 0xbfe9, + 0xbfcd, 0xbfe5, 0xbfca, 0xbfc7, 0xbfe8, 0xc1f1, 0xc20c, 0xc1ef, + 0xc1ee, 0xc1f3, 0xc20d, 0xc1f6, 0xc1f0, 0x14ec, 0xc2f5, 0xc2f4, + 0xc2f8, 0xc2fe, 0xc411, 0xc422, 0xc442, 0xc75c, 0xc75a, 0xc75d, + 0xc7d1, 0xc7d0, 0xc975, 0xc97b, 0xca89, 0xcf4d, 0xd189, 0xd192, + 0xd18c, 0xd188, 0xd367, 0xd368, 0x3e21, 0x3df2, 0x3e09, 0x3df8, + 0x3df0, 0x3df3, 0x3df5, 0x3dfb, 0x3df7, 0x3def, 0x3e0b, 0x3fa2, + 0x40f5, 0x40f3, 0x40f4, 0x40f2, 0x4198, 0x4268, 0x4280, 0x4285, + 0x428e, 0x428f, 0x3df4, 0x4286, 0x42a4, 0x4386, 0x4389, 0x4387, + 0x4385, 0x1adc, 0x4388, 0x45ff, 0x4666, 0x01cc, 0x48c3, 0x01a2, + 0x48c4, 0x493b, 0x48e7, 0x48f8, 0x48fb, 0x01b6, 0x48be, 0x48c6, + 0x01c5, 0x01c6, 0x48fc, 0x48c0, 0x4933, 0x48c9, + /* 0x37 */ + 0x48fe, 0x48da, 0x48cc, 0x48bb, 0x48fd, 0x48df, 0x48cd, 0x48c2, + 0x48c8, 0x4932, 0x492d, 0x48d2, 0x4931, 0x48d3, 0x492e, 0x48cf, + 0x4cff, 0x4d09, 0x4cfc, 0x4e72, 0x4eaa, 0x4eab, 0x4ea7, 0x4e7b, + 0x4e76, 0x4ea8, 0x4eac, 0x0283, 0x1b21, 0x50aa, 0x4503, 0x50ac, + 0x50ad, 0x50ab, 0x5150, 0x5158, 0x52dd, 0x02f8, 0x52ae, 0x52a2, + 0x52ab, 0x52e3, 0x52af, 0x52e0, 0x52e4, 0x02f6, 0x52a7, 0x52aa, + 0x52e2, 0x52e1, 0x52df, 0x52ad, 0x52e5, 0x52d1, 0x52ac, 0x52d5, + 0x52a3, 0x529f, 0x5479, 0x5476, 0x5543, 0x553d, 0x5547, 0x5544, + 0x553f, 0x555b, 0x567f, 0x579a, 0x579c, 0x039b, 0x581e, 0x5988, + 0x596a, 0x5976, 0x5972, 0x5970, 0x597e, 0x596c, 0x596f, 0x5975, + 0x5977, 0x5978, 0x598a, 0x5979, 0x5994, 0x5b01, 0x5c05, 0x5bf1, + 0x5bee, 0x5bef, 0x5c04, 0x1c3f, 0x5bfa, 0x5c07, + /* 0x38 */ + 0x5bf4, 0x5bf5, 0x5c9c, 0x5d6d, 0x5d69, 0x5d66, 0x5d62, 0x5d46, + 0x048d, 0x5d65, 0x5d5d, 0x5d5e, 0x5d5f, 0x5e8e, 0x5f02, 0x5f06, + 0x5f04, 0x5f03, 0x5f62, 0x6027, 0x6021, 0x6020, 0x6024, 0x6029, + 0x6031, 0x6023, 0x6022, 0x61dc, 0x624d, 0x61e5, 0x61d3, 0x61ee, + 0x61e6, 0x0556, 0x6236, 0x6240, 0x633f, 0x623d, 0x6244, 0x055b, + 0x625f, 0x6229, 0x6249, 0x628a, 0x622a, 0x6287, 0x624c, 0x6231, + 0x6248, 0x622b, 0x623b, 0x6241, 0x61c9, 0x6234, 0x6253, 0x6235, + 0x6247, 0x6238, 0x64d1, 0x64d2, 0x6551, 0x6555, 0x6552, 0x6553, + 0x668f, 0x66f4, 0x6747, 0x670d, 0x671c, 0x66fb, 0x6719, 0x66f7, + 0x66f9, 0x66f5, 0x66e9, 0x670a, 0x66ee, 0x670b, 0x66fd, 0x6706, + 0x6702, 0x6716, 0x6718, 0x66f0, 0x69d4, 0x6a66, 0x6a6a, 0x6a75, + 0x6a76, 0x6a80, 0x6a6d, 0x0696, 0x6a69, 0x6a67, + /* 0x39 */ + 0x6a68, 0x6a5d, 0x6ba4, 0x6bfe, 0x6bfd, 0x6cec, 0x6ce9, 0x6d21, + 0x6ceb, 0x6ce7, 0x6cf2, 0x6d20, 0x6e7a, 0x702d, 0x702e, 0x6fca, + 0x702f, 0x6fc8, 0x077e, 0x6fcb, 0x6fc3, 0x6f84, 0x6fd2, 0x6fc6, + 0x0781, 0x6fcf, 0x6fd5, 0x6fd4, 0x6fdd, 0x702b, 0x70a3, 0x6fdb, + 0x702c, 0x7013, 0x0835, 0x73d1, 0x73cc, 0x73d5, 0x73c9, 0x73cf, + 0x73d2, 0x747b, 0x747c, 0x7523, 0x751d, 0x751c, 0x751e, 0x7522, + 0x7524, 0x7520, 0x7518, 0x7521, 0x7688, 0x768a, 0x7694, 0x768f, + 0x768e, 0x7690, 0x089b, 0x76a7, 0x7764, 0x0900, 0x7918, 0x7914, + 0x791d, 0x7905, 0x78ff, 0x791b, 0x791a, 0x7919, 0x7903, 0x790e, + 0x7947, 0x7904, 0x795a, 0x7907, 0x7920, 0x7d6a, 0x7d66, 0x7d7a, + 0x7d65, 0x7daf, 0x80cd, 0x80cf, 0x80d1, 0x80ce, 0x815f, 0x8177, + 0x8174, 0x8188, 0x8175, 0x8189, 0x8172, 0x82c6, + /* 0x3a */ + 0x82ea, 0x82e0, 0x8307, 0x82e6, 0x82e5, 0x82dd, 0x82e3, 0x82da, + 0x84ae, 0x847e, 0x847d, 0x847f, 0x0ad3, 0x84d9, 0x85fa, 0x85fb, + 0x864d, 0x8654, 0x8651, 0x8650, 0x8898, 0x8895, 0x889d, 0x88c1, + 0x889a, 0x889b, 0x0b9f, 0x889c, 0x88d7, 0x88a4, 0x8896, 0x88a0, + 0x8a31, 0x8ae9, 0x8b6e, 0x8c9a, 0x8ca5, 0x8c94, 0x8ca6, 0x8c99, + 0x8c8b, 0x8c98, 0x8c91, 0x8c8c, 0x8ca1, 0x8ca3, 0x8cc6, 0x8e6f, + 0x8e6d, 0x8e6a, 0x8e6c, 0x8e71, 0x8e6e, 0x8edf, 0x8fac, 0x8faa, + 0x0cb1, 0x8fb5, 0x8fad, 0x8fb2, 0x8fb3, 0x8fab, 0x8fb6, 0x8fc7, + 0x8fc6, 0x916c, 0x9170, 0x92b3, 0x0d4b, 0x948c, 0x9481, 0x9483, + 0x947d, 0x9485, 0x9490, 0x94a2, 0x948d, 0x948f, 0x947e, 0x948a, + 0x947f, 0x9476, 0x9487, 0x9478, 0x9580, 0x9582, 0x9581, 0x9583, + 0x965a, 0x9634, 0x962c, 0x962a, 0x9640, 0x962d, + /* 0x3b */ + 0x9633, 0x962b, 0x964b, 0x283f, 0x963c, 0x995a, 0x9977, 0x9960, + 0x9afa, 0x9af9, 0x9afc, 0x0ed6, 0x9af5, 0x9ae8, 0x9b09, 0x9ae7, + 0x9ae6, 0x9ae9, 0x9d32, 0x9d2c, 0x9dbd, 0x9dbc, 0x9e7a, 0x9e7e, + 0x9e79, 0x0f89, 0x9f23, 0x9f30, 0x9f28, 0x9fd4, 0xa5ce, 0x9ff1, + 0x9ff0, 0xa060, 0xa065, 0xa1a8, 0xa20a, 0xa21b, 0xa212, 0xa207, + 0xa24f, 0xa20e, 0xa252, 0xa216, 0x1000, 0xa253, 0xa254, 0xe384, + 0xa256, 0xa46d, 0xa472, 0xa52f, 0xa72a, 0x10dc, 0xa763, 0xa784, + 0xa7af, 0xa745, 0xa770, 0xa756, 0xa716, 0xa73d, 0xa738, 0xa76f, + 0xa777, 0xa72e, 0xa731, 0xa74c, 0xa75f, 0xa775, 0xa739, 0xa73a, + 0xa72c, 0xa72d, 0xa73f, 0xa72f, 0xa730, 0xa73e, 0x2ad0, 0x1190, + 0xacb2, 0xadb7, 0xad8f, 0x11b1, 0xad96, 0xad9e, 0xad97, 0xad95, + 0xada5, 0xad98, 0x2be7, 0xada3, 0xad9a, 0xadad, + /* 0x3c */ + 0xada6, 0xadb6, 0xad99, 0xadaf, 0xadac, 0x11aa, 0xad9f, 0xad94, + 0xb0eb, 0xb16f, 0xb16d, 0xb17e, 0xb16c, 0xb161, 0xb163, 0xb16b, + 0xb15e, 0xb13e, 0xb164, 0xb1ad, 0x127d, 0xb320, 0xb3d1, 0xb3d5, + 0xb4ae, 0xb4af, 0xb49f, 0xb4a8, 0xb4ca, 0xb6e1, 0xb739, 0xb738, + 0xb73b, 0xb7ad, 0xb7b5, 0xb7af, 0xb7b1, 0xb7ae, 0xb7b4, 0xb7b0, + 0xb84b, 0xb851, 0xb84c, 0x1369, 0xb860, 0xb9be, 0xb9b9, 0xb9b7, + 0xb9b6, 0x13a1, 0xb9bd, 0xb9b8, 0xb9c1, 0xbaf7, 0xbaf3, 0xbaf4, + 0xbafb, 0xbafd, 0xbaf5, 0x13e7, 0xbafa, 0xbb14, 0x13ec, 0xbaf2, + 0xbafc, 0xbb00, 0x13df, 0xbd2b, 0xbd29, 0xbd2e, 0x1433, 0xbdd7, + 0xbddb, 0xbdd9, 0xbdd8, 0xbde6, 0xbdd6, 0xbdd1, 0xbde7, 0xbdd0, + 0xbddc, 0xbfed, 0xc01a, 0xc019, 0xc016, 0xbfec, 0xbfef, 0xbfee, + 0xbff4, 0xc02f, 0xc230, 0xc219, 0xc218, 0xc211, + /* 0x3d */ + 0xc216, 0xc212, 0xc210, 0xc214, 0xc30c, 0xc30d, 0xc410, 0xc429, + 0xc428, 0xc765, 0xc766, 0xc7de, 0xc7df, 0xc7e0, 0xc7d9, 0xc7db, + 0xc7d8, 0xc7e3, 0xc7d7, 0xc9a6, 0xc9a7, 0xc9bf, 0xc9a8, 0xc99f, + 0xc9a1, 0xc9a2, 0xc9ad, 0xc9a3, 0xc9a0, 0xcb83, 0xcb85, 0xcb82, + 0xcb84, 0xccee, 0xcd5d, 0xce92, 0xcf55, 0xcf53, 0xe3fc, 0xcf51, + 0xcf52, 0xcf50, 0xd09d, 0xd187, 0xd197, 0xd19b, 0xd19d, 0xd369, + 0xd511, 0x17ee, 0xd77a, 0x1832, 0x6d44, 0x3bc6, 0x3e40, 0x3e2e, + 0x3e68, 0x3e2d, 0x3e34, 0x3e32, 0x3e69, 0x3e31, 0x3e6a, 0x3e3e, + 0x3e6f, 0x3e75, 0x3ff6, 0x4020, 0x4028, 0x4067, 0x40fb, 0x40fe, + 0x40fc, 0x40fd, 0x40ff, 0x40fa, 0x42ac, 0x42af, 0x42b1, 0x00fc, + 0x42bf, 0x42be, 0x42a7, 0x42aa, 0x4394, 0x4393, 0x4399, 0x012a, + 0x43fa, 0x4456, 0x4522, 0x4591, 0x4592, 0x4608, + /* 0x3e */ + 0x4606, 0x48d6, 0x4937, 0x494b, 0x49ce, 0x49d0, 0x4939, 0x4964, + 0x49cf, 0x4946, 0x4966, 0x4956, 0x4943, 0x494a, 0x4958, 0x4965, + 0x495a, 0x495b, 0x4955, 0x4950, 0x494c, 0x49cd, 0x4951, 0x4947, + 0x01d3, 0x4953, 0x4962, 0x49cc, 0x01d7, 0x497f, 0x494d, 0x4d0a, + 0x4d0c, 0x4d0f, 0x4ebb, 0x4eb9, 0x4eeb, 0x4eae, 0x4ec1, 0x4eea, + 0x4ebe, 0x4ebf, 0x4eba, 0x4eb7, 0x4eb3, 0x4ee9, 0x506e, 0x50af, + 0x50b3, 0x50b2, 0x5168, 0x5169, 0x516a, 0x52de, 0x52eb, 0x5311, + 0x52ed, 0x52e9, 0x52f7, 0x52f4, 0x52ea, 0x5312, 0x52e8, 0x5313, + 0x548e, 0x5486, 0x5563, 0x5565, 0x5699, 0x57c2, 0x57ae, 0x57b0, + 0x57ad, 0x59b4, 0x59d1, 0x59ad, 0x03f3, 0x59bd, 0x59b7, 0x59ab, + 0x59af, 0x59c1, 0x59b5, 0x5c0f, 0x5c0e, 0x5c1c, 0x5c13, 0x5c0a, + 0x5c1e, 0x5c14, 0x5c1a, 0x5ccb, 0x5d87, 0x5d93, + /* 0x3f */ + 0x0491, 0x5d84, 0x5d85, 0x5d92, 0x5d80, 0x5e2b, 0x5e63, 0x5f0a, + 0x04c0, 0x5f66, 0x6034, 0x6033, 0x604d, 0x6289, 0x6257, 0x1e17, + 0x624a, 0x0563, 0x6239, 0x623f, 0x6290, 0x628f, 0x62b2, 0x629f, + 0x6295, 0x62a1, 0x629c, 0x628e, 0x62a0, 0x62ae, 0x6296, 0x62ca, + 0x62ac, 0x0570, 0x62a6, 0x6297, 0x6293, 0x3eb6, 0x64d6, 0x64e0, + 0x64d8, 0x6556, 0x676e, 0x677e, 0x6774, 0x6777, 0x6780, 0x677a, + 0x676b, 0x675f, 0x6776, 0x67b0, 0x6763, 0x6a92, 0x6a82, 0x6a9d, + 0x6a94, 0x6a83, 0x6a8b, 0x6a84, 0x6b57, 0x6b84, 0x6bb5, 0x6c09, + 0x6ce6, 0x0702, 0x6d25, 0x6d51, 0x6e3e, 0xe2da, 0x6e85, 0x703f, + 0x7042, 0x7038, 0x703a, 0x704e, 0x7045, 0x7039, 0x7037, 0x7044, + 0xe2e7, 0x70a4, 0x703d, 0x7041, 0x73df, 0x73de, 0x73ca, 0x73e9, + 0x73e2, 0x73e0, 0x7489, 0x7487, 0x7532, 0x7533, + /* 0x40 */ + 0x75ac, 0x75f9, 0x760d, 0x76b9, 0x795e, 0x796a, 0x0935, 0x7981, + 0x7969, 0x79ac, 0x7980, 0x7975, 0x7971, 0x7976, 0x796f, 0x7db6, + 0x7e03, 0x7dbf, 0x7e01, 0x7db2, 0x7dc4, 0x80db, 0x80dc, 0x80d8, + 0xd172, 0x81b5, 0x81a8, 0x818f, 0x819e, 0x818e, 0x82de, 0x82e2, + 0x8320, 0x831d, 0x831a, 0x8319, 0x832b, 0x8318, 0x8310, 0x830e, + 0x8324, 0x831f, 0x8313, 0x8335, 0x8483, 0x0ae0, 0x84d7, 0x8602, + 0x8603, 0x865c, 0x865f, 0x86c7, 0x879a, 0x8797, 0x87a3, 0x88f7, + 0x88c6, 0x88cc, 0x88d6, 0x88cd, 0x88f9, 0x88d9, 0x88d8, 0x0b9a, + 0x88d1, 0x88ce, 0x88d5, 0x0ba3, 0x88d4, 0x88f8, 0x8a7a, 0x8a79, + 0x8a7f, 0x8af3, 0x8af5, 0x8af6, 0x8af4, 0x8af7, 0x0c05, 0x8b79, + 0x8c9c, 0x8cdf, 0x8cf5, 0x8cff, 0x8cd1, 0x8cda, 0x8ccf, 0x8ccd, + 0x8cde, 0x8cd8, 0x75ad, 0x8ce0, 0x8cfe, 0x8c9e, + /* 0x41 */ + 0x8e75, 0x8e73, 0x8e72, 0x8ed8, 0x8fd0, 0x8fd6, 0x8fd7, 0x8fca, + 0x8fcd, 0x918a, 0x9189, 0x918b, 0x92d3, 0x92da, 0x92ce, 0x92d2, + 0x0d5e, 0x92d4, 0x92d7, 0x92d5, 0x92fb, 0x92cd, 0x92fa, 0x92d6, + 0x0da6, 0x949b, 0x949e, 0x949d, 0x94a4, 0x949f, 0x94a5, 0x94a8, + 0x958f, 0x958c, 0x9595, 0x9660, 0x9655, 0x965c, 0x966f, 0x9651, + 0x9661, 0x96a7, 0x965e, 0x9662, 0x9654, 0x966e, 0x9652, 0x9658, + 0x966d, 0x965f, 0x966c, 0x9650, 0x965d, 0x968e, 0x9972, 0x9978, + 0x9975, 0x9976, 0x997c, 0x997e, 0x997d, 0x9b15, 0x9b14, 0x9b1d, + 0x9b1c, 0x9b23, 0x9b57, 0x9dc8, 0x0f5d, 0x9dc9, 0x9dc5, 0x9e87, + 0x9e8a, 0x9e94, 0x9f39, 0x9f40, 0x9f3e, 0x9f38, 0x9fd6, 0x0fb8, + 0xa077, 0xa078, 0xa07d, 0xa1dd, 0xa25e, 0xa277, 0xa2d4, 0xa266, + 0xa25f, 0xa273, 0xa272, 0xa297, 0xa25a, 0xa296, + /* 0x42 */ + 0xa25d, 0xa265, 0xa270, 0xa275, 0xa274, 0xa25c, 0xa260, 0x1034, + 0xa26d, 0xa441, 0xa53c, 0xa53e, 0x106f, 0xa549, 0xa6e4, 0xa80c, + 0xa815, 0xa80e, 0xa7d4, 0xa7c7, 0xa814, 0xa7db, 0xa85f, 0xa7ed, + 0xa809, 0xa7cf, 0xa7ff, 0xa81a, 0xa7f5, 0xa7ee, 0xa7e5, 0xa80d, + 0xa7df, 0xa7ec, 0xa7d7, 0xa82c, 0xa7cd, 0xa7e3, 0xa800, 0xa7eb, + 0xa7fd, 0xa80f, 0xa82d, 0xa850, 0xa7fe, 0xa7c4, 0xa7e1, 0xa7f9, + 0xacbb, 0xacbc, 0x1194, 0x1193, 0xacba, 0xadd0, 0xadd6, 0xadce, + 0xade1, 0xadd5, 0xadcf, 0xadd3, 0x2c14, 0xadd4, 0xb0b5, 0xb190, + 0xb1a1, 0xb181, 0xb185, 0xb16e, 0xb188, 0xb182, 0xb186, 0xb18f, + 0xb189, 0xb180, 0xb184, 0x2dd1, 0xb329, 0xb32b, 0xb32a, 0xb330, + 0xb3e2, 0xb3e3, 0xb3e1, 0xb4d5, 0xb4c4, 0xb4c9, 0xb4e0, 0xb4df, + 0xb4cb, 0xb4dd, 0xb4e8, 0xb4d4, 0xb51c, 0xb6b5, + /* 0x43 */ + 0xb6b6, 0xb6e5, 0xb745, 0xb749, 0xb740, 0xb746, 0xb744, 0xb74a, + 0xb7c9, 0xb7c4, 0xb7c2, 0xb868, 0x30cb, 0xb882, 0xb86b, 0xb867, + 0xb86c, 0xb86d, 0xb871, 0x1392, 0xb9d7, 0xb9d2, 0xb9d9, 0x13aa, + 0xb9bc, 0xb9dd, 0xb9d6, 0x13a7, 0xb9d8, 0xbb20, 0xbb16, 0xbb18, + 0xbb15, 0xbb19, 0xbb27, 0xbb50, 0xbb1d, 0xbb2c, 0xbb1c, 0xbb29, + 0xbb2b, 0xbb24, 0x13ef, 0xbb28, 0xbd39, 0xbdf2, 0xbdf0, 0x31ed, + 0xbded, 0xbdef, 0xbdea, 0xbe01, 0xbfbc, 0xc05c, 0xc05b, 0xc05a, + 0xc026, 0xc243, 0xc233, 0xc23a, 0xc237, 0xc236, 0xc23c, 0xc234, + 0xc24a, 0xc23b, 0xc235, 0xc23d, 0xc240, 0xc23e, 0xc217, 0xc326, + 0xc324, 0xc310, 0xc336, 0xc325, 0x1522, 0xc466, 0xc77f, 0xc77a, + 0xc7fb, 0xc7fd, 0xc7fc, 0xc7fa, 0xc9d6, 0xc9d2, 0xc9c8, 0xc9c2, + 0xc9c7, 0xc9cd, 0xc9c1, 0xc9c6, 0xc9cc, 0xcaa1, + /* 0x44 */ + 0xcb95, 0xcb94, 0xcb97, 0xcb96, 0xcb93, 0xcba1, 0xcd09, 0xcd08, + 0xcd67, 0xcd65, 0xcd62, 0xcd61, 0xce97, 0xcf01, 0xcf19, 0xcf18, + 0xcf5c, 0xcf67, 0xcf6c, 0x16b5, 0xe3fd, 0xcf66, 0xcf61, 0xcf6e, + 0xcf5d, 0xcf5a, 0xd0a2, 0xd0a9, 0xd0a5, 0xd0a6, 0xd0b2, 0xd0a3, + 0xd1ac, 0xd1aa, 0xd1af, 0xd1ab, 0xd1b1, 0xd1c6, 0xd1ad, 0xd1b9, + 0xd370, 0x1775, 0xd70c, 0xd781, 0xd783, 0xd77e, 0xd851, 0xda99, + 0xda94, 0xda95, 0xddfe, 0xdf18, 0x3c05, 0x3e72, 0x0082, 0x3e99, + 0x3fad, 0x4106, 0x42c2, 0x42cb, 0x42d5, 0x42d2, 0x42cc, 0x42d7, + 0x42c5, 0x42ca, 0x1aec, 0x43a2, 0x43a3, 0x43a1, 0x1ae8, 0x43a6, + 0x43a4, 0x43ff, 0x4400, 0x0135, 0x4506, 0x4525, 0x459f, 0x467f, + 0x49ea, 0x49eb, 0x49de, 0x4a18, 0x49e0, 0x49e8, 0x49df, 0x49f1, + 0x49ec, 0x4a1a, 0x49e6, 0x49e1, 0x4a5d, 0x3b77, + /* 0x45 */ + 0x4a1e, 0x01f0, 0x4a80, 0x4d17, 0x4f1d, 0x4ef7, 0x4eef, 0x4eee, + 0x4eed, 0x4ef5, 0x4f1e, 0x50bd, 0x92ff, 0x50be, 0x516d, 0x5176, + 0x534c, 0x5319, 0x5348, 0x531e, 0x534a, 0x5349, 0x5326, 0x5495, + 0x5585, 0x557e, 0x5597, 0x557d, 0x5642, 0x569e, 0x570c, 0x570b, + 0x570e, 0x57cf, 0x59d8, 0x59e0, 0x59e8, 0x59e9, 0x59e2, 0x59e1, + 0x59da, 0x59e3, 0x59d9, 0x59f0, 0x59e7, 0x59e4, 0x5c23, 0x5c31, + 0x5c33, 0x5c0c, 0xa4e0, 0x5c26, 0x5c24, 0x5c32, 0x5c27, 0x5c21, + 0x5c30, 0x5ca2, 0x5ccc, 0x5d96, 0xe28f, 0x5d98, 0x5d9c, 0x5d9b, + 0x5e6b, 0x5f12, 0x5f14, 0x605a, 0x6054, 0x6051, 0x605e, 0x6058, + 0x04f0, 0x6059, 0x629a, 0x62f2, 0x62ad, 0x6320, 0x62f1, 0x62f0, + 0x62f3, 0x62f4, 0x62e9, 0x62fe, 0x632e, 0x62e8, 0x62e7, 0x62ff, + 0x62f5, 0x64e5, 0x64e7, 0x64e6, 0x64e9, 0x6558, + /* 0x46 */ + 0x676c, 0x67d9, 0x063e, 0x67cb, 0x0639, 0x67be, 0x67b5, 0x67d1, + 0x67c2, 0x67b6, 0x67d3, 0xe2c2, 0x69da, 0x06a2, 0x6aae, 0x06a1, + 0x6aac, 0x6aa9, 0x6aba, 0x6aa7, 0x6ab3, 0x6abd, 0x6ab1, 0x6c0e, + 0x6c11, 0x6c0f, 0x6d52, 0x6d6a, 0x6d54, 0x6d55, 0x6d53, 0x6d57, + 0xe2d0, 0x6d5b, 0x6d58, 0x6d59, 0x073b, 0x70b8, 0x70b5, 0x70bf, + 0x70c1, 0x70bb, 0x07b7, 0x70c3, 0x70ad, 0x70a8, 0x70ae, 0x70aa, + 0x70d0, 0x70b1, 0x70bc, 0x70b7, 0x70b0, 0x70fa, 0x70fb, 0x70b9, + 0x7407, 0x73fc, 0x73ff, 0x73f2, 0x73f8, 0x73f4, 0x0857, 0x0870, + 0x75ae, 0x760f, 0x7610, 0xd5c1, 0x76c7, 0x76c6, 0x76ce, 0x08a7, + 0x76dc, 0x79d5, 0x79d3, 0x7a20, 0x79e2, 0x79f1, 0x79db, 0x79ea, + 0x79eb, 0x79e1, 0x79ff, 0x79d6, 0x79e0, 0x79d7, 0x79e5, 0x0954, + 0x7e1b, 0x7e10, 0x7e0f, 0x7e0e, 0x7e39, 0x7e0a, + /* 0x47 */ + 0x7e14, 0x7e0c, 0x8023, 0x805a, 0x80e2, 0x8193, 0x81b0, 0x81ab, + 0x81bd, 0x81b1, 0x818d, 0x81ad, 0x81aa, 0x81ac, 0x81bc, 0x81c9, + 0x8347, 0x8362, 0x8340, 0x8344, 0x833f, 0x8343, 0x833d, 0x8360, + 0x835f, 0x833a, 0x8342, 0x835e, 0x835d, 0x84bc, 0x84e0, 0x84ee, + 0x84eb, 0x850d, 0x8609, 0x860c, 0x8669, 0x8674, 0x8667, 0x0b31, + 0x2427, 0x87ad, 0x88ff, 0x8916, 0x8908, 0x8909, 0x8900, 0x88fc, + 0x8913, 0x8914, 0x890a, 0xd33e, 0x8929, 0x8917, 0x893b, 0x88fb, + 0x0bbf, 0x890e, 0x0be4, 0x8b08, 0x8d1b, 0x8d1a, 0x8d19, 0x8d02, + 0x0c4a, 0x8d17, 0x8d07, 0x8d13, 0x8d09, 0x8d0a, 0x8d12, 0x8daa, + 0x8d38, 0x8e7b, 0x8e7c, 0x8e7a, 0x8eea, 0x8eeb, 0x8eef, 0x8ef0, + 0x9009, 0x9002, 0x9001, 0x902b, 0x9007, 0x0ccf, 0x9028, 0x8ffb, + 0x902a, 0x8ffe, 0x9004, 0x9029, 0x900a, 0x268c, + /* 0x48 */ + 0x91c2, 0x2691, 0x91a6, 0x0d14, 0x6ac6, 0x5707, 0x930a, 0x92fd, + 0x9306, 0x930d, 0x9309, 0x930b, 0x9300, 0x9305, 0x933d, 0x94d5, + 0x94bf, 0x94ba, 0x94c7, 0x9598, 0x959a, 0x0e0d, 0x96a4, 0x969c, + 0x969d, 0x96a2, 0x9696, 0x9695, 0x96a5, 0x96aa, 0x96ad, 0x969a, + 0x96a3, 0x9697, 0x9690, 0x96af, 0x968d, 0x0e01, 0x96a8, 0x96ee, + 0x99a3, 0x9999, 0x99a1, 0x999c, 0x99a4, 0x99cb, 0x9b56, 0x9b48, + 0x9b59, 0x9b4a, 0x9b5c, 0x0ef1, 0x9b4f, 0x9b4d, 0x9b5d, 0x9d3a, + 0x9de3, 0x9de1, 0x9dde, 0x9e97, 0x9e9a, 0x9f48, 0x9f4a, 0x9f4c, + 0x9f4e, 0x9f4f, 0x9f4b, 0x9f4d, 0x9f47, 0x9f51, 0x9fda, 0x9ff9, + 0x9ffc, 0x9ffb, 0x9ffd, 0x9ff8, 0x9ffa, 0xa08a, 0xa08e, 0xa088, + 0xa089, 0xa08d, 0xa090, 0xe37e, 0xa21c, 0xa2ab, 0xa2a4, 0xa2a8, + 0xa2ad, 0xa29f, 0xa29a, 0xa2b0, 0xa2a5, 0xa2d5, + /* 0x49 */ + 0xa2a2, 0xa2b2, 0xa29d, 0xa2a1, 0xa415, 0xa442, 0xa473, 0xa484, + 0xa4dd, 0xa55c, 0xa54c, 0x1076, 0xa54b, 0xa767, 0xa8a8, 0xa87f, + 0xa88d, 0xa88b, 0xa8f7, 0xa8a9, 0xa8f4, 0xa89a, 0xa88c, 0xa895, + 0xa87e, 0xa877, 0x110a, 0x1103, 0xa871, 0xa8fd, 0xa888, 0xa899, + 0xa86d, 0xa8d4, 0xa891, 0xa87d, 0xa863, 0xa875, 0xa8f9, 0xa88e, + 0xa874, 0xa8d9, 0xa866, 0xa8fa, 0xa8f5, 0x2b60, 0xacc1, 0xacc9, + 0xae03, 0xae2c, 0xae34, 0xae17, 0xae09, 0xae04, 0xae06, 0xae1a, + 0xae0e, 0xae27, 0xae05, 0xae07, 0xae19, 0xae14, 0xae0c, 0xae1d, + 0xae22, 0xae23, 0xb0bb, 0xb0bc, 0xb0ba, 0xb1a9, 0xb1b5, 0xb1ac, + 0xb1aa, 0xb1af, 0xb1b7, 0x1235, 0x1236, 0xb33d, 0xb345, 0xb348, + 0xb33c, 0xb33e, 0xb3ec, 0xb3ed, 0xb3e9, 0xb50a, 0xb50b, 0xb4f8, + 0xb504, 0xb4f6, 0xb4f9, 0xb753, 0xb752, 0xb760, + /* 0x4a */ + 0xb763, 0xb7ce, 0xb7cd, 0xb7d0, 0xb7cc, 0xb887, 0xb88d, 0xb89d, + 0x1373, 0xb963, 0xb9f4, 0xb9f1, 0xb9ff, 0xb9f5, 0xb9fc, 0xb9f2, + 0xb9f6, 0x13b1, 0xb9fa, 0x13af, 0xbb2e, 0xbb45, 0xbb43, 0xbb51, + 0xbb4c, 0xbb73, 0xbb47, 0xbb4b, 0xbb4f, 0x13f4, 0xbb44, 0xbb4d, + 0xbb4e, 0xbb4a, 0xbb41, 0xbb52, 0xbb9f, 0xbb54, 0xbb59, 0xbba2, + 0xbd4b, 0xbd48, 0xbe0d, 0xbe1f, 0xbe08, 0xbe0e, 0xbe1d, 0xbe04, + 0xbf18, 0xbf1b, 0xc066, 0xc062, 0xc083, 0xc067, 0xc262, 0xc24f, + 0xc24e, 0xc267, 0xc253, 0xc24d, 0xc24c, 0xc268, 0xc251, 0x14dc, + 0xc258, 0xc25b, 0xc250, 0xc26a, 0xc339, 0xc338, 0xc482, 0xc484, + 0xc486, 0xc780, 0xc786, 0xc825, 0xc811, 0x1599, 0xc80e, 0xc815, + 0xc80f, 0xc818, 0xc80d, 0xc813, 0xc816, 0xc819, 0xca08, 0xc9f7, + 0xc9fb, 0xc9fc, 0xcab4, 0xcabe, 0xcac1, 0xcba6, + /* 0x4b */ + 0xcba5, 0xcba2, 0xcba4, 0xcd12, 0xcd0e, 0xcd7a, 0xcd78, 0xcd7d, + 0xcd7e, 0xcd81, 0xcd83, 0xcd80, 0xcd82, 0xce9b, 0xce99, 0xce9c, + 0xce9a, 0xcea1, 0xcf1a, 0xcf1c, 0xcf8a, 0xcf79, 0xcf73, 0xcf75, + 0xcf7c, 0xcf78, 0xcf60, 0xcf83, 0xcf70, 0x16b6, 0x16bd, 0xcf87, + 0xcf84, 0xcf7b, 0xcf7e, 0xcf74, 0xd0b9, 0xd0b8, 0xd0b7, 0xd0b5, + 0xd1cc, 0xd1ce, 0xd1d1, 0x3504, 0xd1cb, 0x359b, 0xd37e, 0xd37a, + 0xd377, 0xd38c, 0xd3e1, 0xd520, 0xd51e, 0xd5c2, 0xd60f, 0xd600, + 0x17f4, 0xd610, 0xd70d, 0xd70e, 0xd78e, 0xd78d, 0xd78a, 0xd78b, + 0xd78c, 0xd78f, 0xd857, 0x1835, 0xd855, 0xd85b, 0xdaac, 0xdaa7, + 0xdaa0, 0xda9e, 0x18aa, 0xdd8d, 0x191f, 0xde93, 0xde94, 0xde92, + 0x3c81, 0x3ed6, 0x3ec3, 0x3ee4, 0x3ee2, 0x3f09, 0x3ebf, 0x3ec8, + 0x3ec7, 0x3fb5, 0x3fb2, 0x410c, 0x410b, 0x410a, + /* 0x4c */ + 0x4105, 0x42d3, 0x42e6, 0x42e9, 0x42f0, 0x42ea, 0x42e7, 0x43b1, + 0x43b3, 0x43b4, 0x43b0, 0x445c, 0x445d, 0x445e, 0x44c0, 0x45af, + 0x0150, 0x4686, 0x4683, 0x4684, 0x4a5c, 0x4a70, 0x4a8c, 0x4a7b, + 0x4a66, 0x4a79, 0x4a63, 0x4ac5, 0x4a6b, 0x4a6d, 0x4a72, 0x4a69, + 0x4a75, 0x4a89, 0x4ac6, 0x4aa5, 0x3ee7, 0x4a6a, 0x4a97, 0x4f5a, + 0x4f5c, 0x4f59, 0x4f24, 0x4f25, 0x4f30, 0x4f58, 0x4f31, 0x5076, + 0x50c1, 0x5185, 0x517d, 0x5365, 0x5387, 0x5352, 0x5354, 0x538a, + 0x5350, 0x5386, 0x534f, 0x5368, 0x549d, 0x55a0, 0x55ba, 0x55bd, + 0x55b8, 0x56a6, 0x037b, 0x57de, 0x57d8, 0x57d1, 0x5a13, 0x0409, + 0x5a0e, 0x5a1b, 0x5a3a, 0x0407, 0x5a1c, 0x5a12, 0x5a16, 0x5a1a, + 0x4f48, 0x5c4b, 0x5c37, 0x5c36, 0x5c38, 0x5c3a, 0x5c49, 0x5c3c, + 0x5c4a, 0x5db1, 0x5dc2, 0x5db5, 0x5dc4, 0x5db6, + /* 0x4d */ + 0x5f1e, 0x5f1f, 0x5faf, 0x606b, 0x606f, 0x6292, 0x62e4, 0x632c, + 0x62ef, 0x1e84, 0x634f, 0x6352, 0x6350, 0x633a, 0x6337, 0x6347, + 0x6364, 0x6340, 0x633c, 0x6345, 0x6341, 0x64f3, 0x05bb, 0x67c1, + 0x67b4, 0x064b, 0x682a, 0x6822, 0x6829, 0x064d, 0x683e, 0x683c, + 0x6830, 0x6ac7, 0x6ad5, 0x6ad6, 0x6ad3, 0x6ace, 0x6ac8, 0x6b5c, + 0x6b5f, 0x6b62, 0x06c2, 0x6bbd, 0x6bbf, 0x6d5c, 0x6db6, 0x071a, + 0x6d9d, 0x6d7f, 0x0712, 0x6d94, 0x6d81, 0x6e47, 0x6e46, 0x073c, + 0x6e94, 0x7175, 0x711a, 0x712a, 0x7132, 0x7117, 0x7123, 0x7174, + 0x07c3, 0x7176, 0x712e, 0x7125, 0x7120, 0x7171, 0x7116, 0x7170, + 0x712c, 0x712f, 0x711f, 0x7164, 0x07c0, 0x7408, 0x7414, 0x740a, + 0x740b, 0x754f, 0x7559, 0x7554, 0x7551, 0x75b6, 0x76ec, 0x76ed, + 0x76ea, 0x79ee, 0x7a5a, 0x7a73, 0x7a65, 0x7a61, + /* 0x4e */ + 0x7a55, 0x7a6b, 0x7a64, 0x7a5b, 0x7a4c, 0x7a6f, 0x7a84, 0x7a70, + 0x7e5d, 0x7e57, 0x7e66, 0x7e53, 0x7e98, 0x7e97, 0x8028, 0x80eb, + 0x80ea, 0x80e8, 0x80ec, 0x80ef, 0x81d1, 0x81ca, 0x229f, 0x81cf, + 0x81cd, 0x81ce, 0x8370, 0x8367, 0x8373, 0x836d, 0x8376, 0x8379, + 0x836a, 0x838b, 0x8372, 0x8371, 0x836e, 0x837a, 0x8516, 0x8539, + 0x853b, 0x8610, 0x8696, 0x867b, 0x867c, 0x867d, 0x87be, 0x895c, + 0x8938, 0x8939, 0x892e, 0x8934, 0x8932, 0x895b, 0x8933, 0x893c, + 0x0be5, 0x8b0e, 0x8b0f, 0x8b10, 0x8b87, 0x8d5b, 0x8d53, 0x0c5f, + 0x8d5c, 0x8d3f, 0x8d59, 0x8d4a, 0x8d44, 0x8d4c, 0x8d40, 0x8d5f, + 0x8d5e, 0x8d4e, 0x8d54, 0x8d43, 0x8d87, 0x8e82, 0x8e85, 0x9031, + 0x9047, 0x902e, 0x902f, 0x9048, 0x9034, 0x0d18, 0x409f, 0x9332, + 0x9336, 0x9333, 0x9331, 0x9340, 0x9341, 0x94dd, + /* 0x4f */ + 0x94d2, 0x94d9, 0x0dad, 0x94df, 0x94db, 0x94d8, 0x94d3, 0x94de, + 0x94e0, 0x94d4, 0x94d7, 0x94da, 0x95a7, 0x96fe, 0x96dd, 0x9740, + 0x96e2, 0x0e1e, 0x96d6, 0x96de, 0x96ef, 0x0e27, 0x96eb, 0x96ea, + 0x96e4, 0x96d1, 0x0e18, 0x96ec, 0x96fa, 0x96d9, 0x96f3, 0x96e1, + 0x96dc, 0x96e5, 0x96df, 0x96d4, 0x0e20, 0x9705, 0x99d6, 0x99d5, + 0x99d0, 0x99c8, 0x99c4, 0x99c9, 0x99cd, 0x99d2, 0x99cc, 0x99ca, + 0x9ba0, 0x9b92, 0x0ef4, 0x0f02, 0x9b8b, 0x9ba1, 0x9b95, 0x9b88, + 0x9b86, 0x9b8d, 0x9b85, 0x9b91, 0x9b89, 0x9ba2, 0x9df0, 0x9df3, + 0x9df4, 0x9def, 0x9e06, 0x9ea2, 0x9f5e, 0x9f63, 0x9f60, 0x9f5b, + 0x9f7b, 0x9f58, 0x9f59, 0x9f5d, 0xa005, 0xa006, 0xa002, 0xa003, + 0xa004, 0xa0a2, 0xa0a7, 0xa0a6, 0xa0a4, 0xa0ac, 0xa0a9, 0xa2e7, + 0xa301, 0xa2df, 0xa2d9, 0xa2e3, 0xa30f, 0xa41a, + /* 0x50 */ + 0xa445, 0xa448, 0xa47b, 0xa485, 0xa486, 0xa4fe, 0xa4ff, 0xa564, + 0xa571, 0xa572, 0xa561, 0xa562, 0xa56c, 0xa560, 0xa55d, 0xa563, + 0xa567, 0xa901, 0xa92a, 0xa930, 0xa906, 0xa97d, 0xa922, 0xa9b9, + 0xa90a, 0xa910, 0xa88f, 0xa980, 0xa913, 0xa92e, 0xa918, 0xa917, + 0xa91a, 0xa914, 0xa947, 0xa963, 0xa938, 0x1124, 0xa97f, 0xa921, + 0xa937, 0xa931, 0xa91b, 0xa9a5, 0xaa6c, 0xacd3, 0xae88, 0xae6e, + 0xae5c, 0xae74, 0xae54, 0xae83, 0x2c70, 0xae65, 0xae60, 0xae70, + 0xae6f, 0xae6d, 0xae72, 0xae6c, 0xae76, 0xae75, 0xae59, 0xaec7, + 0xb0c1, 0xb0f9, 0xb1e3, 0xb1e7, 0xb1d6, 0xb1cf, 0xb1da, 0xb1e9, + 0xb1d2, 0xb355, 0xb34f, 0xb34d, 0xb351, 0xb356, 0xb3f9, 0xb3f8, + 0xb406, 0xb403, 0xb409, 0xb3f7, 0xb3f5, 0xb547, 0xb545, 0xb53e, + 0xb546, 0xb529, 0xb534, 0xb53f, 0xb544, 0xb535, + /* 0x51 */ + 0xb55a, 0xb52a, 0xb533, 0xb537, 0xb543, 0xb539, 0xb530, 0xb55d, + 0xb532, 0xb527, 0xb6bd, 0xb6ba, 0xb6bc, 0xb6f1, 0xb6f0, 0xb761, + 0xb75c, 0xb758, 0xb75d, 0xb7da, 0xb7d9, 0xb7dd, 0xb7dc, 0xb7de, + 0x137d, 0xb8a0, 0xb8a2, 0xba0f, 0xba13, 0xba12, 0xba11, 0xba14, + 0xba19, 0xba0e, 0xba17, 0xba21, 0xba20, 0xba16, 0xbb78, 0x3137, + 0xbb87, 0xbb79, 0xbb80, 0xbb77, 0xbb81, 0xbb46, 0xbb7a, 0xbb9c, + 0xbb83, 0xbb84, 0xbbad, 0xbb9d, 0xbb9e, 0xbd55, 0xbe36, 0xbe2b, + 0xbe27, 0xbe46, 0xbe2c, 0xbe45, 0xbe33, 0xbe2d, 0xbe34, 0xbe22, + 0x1464, 0xbf1f, 0xc0b3, 0xc08c, 0xc08f, 0xc0af, 0xc0ad, 0xc08e, + 0xc0ac, 0xc0b0, 0xc0b1, 0xc0ae, 0xc099, 0xc1eb, 0xc274, 0xc275, + 0xc28e, 0xc26d, 0xc270, 0xc28c, 0xc34f, 0xc351, 0xc358, 0xc34c, + 0xc34e, 0xc415, 0xc4be, 0xc4db, 0xc4b3, 0xc4ae, + /* 0x52 */ + 0xc787, 0xc78a, 0xc788, 0xc78b, 0xc78c, 0xc844, 0xc82d, 0xc82a, + 0xc831, 0xc82c, 0xc845, 0xc830, 0xc829, 0xc846, 0xc9f4, 0xca14, + 0xca10, 0xca0f, 0xca12, 0xca0b, 0xca0c, 0xca0a, 0xca13, 0xca0e, + 0xcad9, 0xcad0, 0x3403, 0xcbc1, 0xcbbf, 0xcbbd, 0xcbbc, 0xcbba, + 0xcbbb, 0xcbd1, 0xcbbe, 0xcbd0, 0xcbb9, 0xcd1a, 0xcd1c, 0xcd1b, + 0xcd91, 0xcd96, 0xcd9f, 0xcd9c, 0xcd9a, 0xcd9d, 0xcead, 0xcea5, + 0xceae, 0xcf03, 0xcf26, 0xcf20, 0xcf23, 0xcf24, 0xcf21, 0xcf28, + 0xcf25, 0xcf1e, 0xcf94, 0xcf93, 0xcf8f, 0xcf9a, 0xcfad, 0x16c2, + 0xd0ca, 0xd0c5, 0xd1bb, 0xd1e1, 0xd1ea, 0xd1e4, 0xd1ed, 0xd1e6, + 0xd1e0, 0xd1e8, 0xd1e5, 0xd31a, 0xd394, 0xd396, 0xd39e, 0xd395, + 0xd3a1, 0xd38e, 0xd39b, 0xd392, 0xd397, 0xd399, 0xd393, 0xd532, + 0xd52f, 0xd52e, 0xd533, 0xd61c, 0xd61e, 0xd611, + /* 0x53 */ + 0xd620, 0xd61f, 0xd619, 0xd616, 0xd7ac, 0xd7b9, 0xd7b3, 0xd7a6, + 0xd7a2, 0xd7a9, 0xd7a7, 0xd86c, 0xd86d, 0xd869, 0xd880, 0xd866, + 0xd865, 0xd871, 0xd86b, 0xdabd, 0xdac1, 0xdad3, 0xdab6, 0x18ac, + 0xdab9, 0xdad4, 0xdab7, 0xdadb, 0xdab8, 0xdac0, 0xdabc, 0xdad5, + 0xdabf, 0xdac3, 0xdac9, 0xdd58, 0xdd90, 0xdd95, 0xdd97, 0xde09, + 0xde08, 0xde06, 0xde05, 0xde10, 0xde97, 0xde95, 0xdeee, 0xdf1f, + 0xe41a, 0x564b, 0x3c8e, 0x3ee8, 0x3ef0, 0x3ef4, 0x3f06, 0x3eed, + 0x009b, 0x3ee9, 0x3f00, 0x3fb8, 0x406d, 0x4304, 0x4301, 0x4303, + 0x4302, 0x1af6, 0x0126, 0x4462, 0x45ba, 0x4613, 0x4ade, 0x4ad7, + 0x4ae4, 0x4ace, 0x4ae3, 0x4add, 0x4b3a, 0x4adb, 0x4ad6, 0x4ae0, + 0x4ad4, 0x4acb, 0x4ae1, 0x4ac9, 0x4adf, 0x4b3c, 0x4afc, 0x4acf, + 0x4f79, 0x4f76, 0x4f78, 0x5187, 0x539c, 0x53b1, + /* 0x54 */ + 0x53c1, 0x539a, 0x5392, 0x0daf, 0x53c2, 0x5396, 0x53c0, 0x5391, + 0x5395, 0x54a2, 0x55c3, 0x55c0, 0x55c2, 0x468a, 0x56b0, 0x5716, + 0x5a46, 0x5a4a, 0x5a3e, 0x5a45, 0x5a42, 0x0415, 0x5a5b, 0x5a44, + 0x5b04, 0x7b22, 0x5c55, 0x5c57, 0x5c51, 0x5c4e, 0x5c5a, 0x5dc6, + 0x5dc3, 0x049c, 0x5dc5, 0x5dcc, 0x5e71, 0x5f26, 0x5fb2, 0x607a, + 0x6084, 0x607b, 0x6374, 0x638c, 0x6351, 0x6348, 0x638d, 0x6392, + 0x6398, 0x6393, 0x63b0, 0x634e, 0x6396, 0x6397, 0x639c, 0x63ca, + 0x6833, 0x6883, 0x6884, 0x689a, 0x688c, 0x20cc, 0x6899, 0x69e0, + 0x6ae4, 0x6af8, 0x6aed, 0x6af3, 0x6af4, 0x6af5, 0x6afd, 0x6c19, + 0x6d9e, 0x6dc4, 0x6d9f, 0x6e9b, 0x6e9f, 0x6e9a, 0x71aa, 0x719d, + 0x7192, 0x71a2, 0x71af, 0x71eb, 0x71a0, 0x71a1, 0x7194, 0x7198, + 0x718f, 0x7187, 0x7184, 0x71a9, 0x717c, 0x7418, + /* 0x55 */ + 0x755f, 0x7562, 0x7561, 0x75c0, 0x7615, 0x76fc, 0x76f9, 0x7ac8, + 0x7ac9, 0x7ade, 0x7aca, 0x7ae2, 0x0964, 0x096e, 0x7b04, 0x7acc, + 0x7add, 0x7ae4, 0x7ad3, 0x7ac7, 0x7ac6, 0x095f, 0x7b37, 0x7ed8, + 0x7eee, 0x7eb2, 0x7ea3, 0x7eb3, 0x7eed, 0x7ef8, 0x8031, 0x805b, + 0x8066, 0x8069, 0x8096, 0x809b, 0x80f7, 0x80f3, 0x80f4, 0x80f5, + 0x81e2, 0x81e7, 0x81e5, 0x81e9, 0x81e6, 0x81e3, 0x8374, 0x837f, + 0x838f, 0x8390, 0x8397, 0x83a3, 0x838e, 0x8398, 0x838c, 0x8542, + 0x8544, 0x8569, 0x8543, 0x8568, 0x0af6, 0x868d, 0x8688, 0x868b, + 0x8689, 0x87cc, 0x881f, 0x8980, 0x895e, 0x8967, 0x8968, 0x8965, + 0x254a, 0x8974, 0x8969, 0x8961, 0x8962, 0x896c, 0x8993, 0x8986, + 0x8a9d, 0x8a9b, 0x8b1b, 0x8b16, 0x8b19, 0x8b14, 0x8b18, 0x8b15, + 0x8b99, 0x8b98, 0x8d5d, 0x8d89, 0x8d7a, 0x8d7d, + /* 0x56 */ + 0x8d4b, 0x0c73, 0x8d78, 0x8d7f, 0x8d77, 0x8d7e, 0x8d79, 0x8dab, + 0x8d7c, 0x8d74, 0x8d75, 0x8da7, 0x8e8d, 0x904e, 0x9066, 0x9061, + 0x904d, 0x904f, 0x0cdd, 0x9054, 0x907c, 0x91da, 0x91de, 0x91d8, + 0x91dd, 0x91df, 0x9366, 0x9362, 0x935f, 0x9364, 0x9363, 0x9360, + 0x9388, 0x936a, 0x9367, 0x9387, 0x933f, 0x936c, 0x936e, 0x93ad, + 0x94f1, 0x94f4, 0x94f6, 0x94f5, 0x94f8, 0x94fb, 0x94ec, 0x94ef, + 0x94ed, 0x27b9, 0x94f7, 0x94f9, 0x94fd, 0x95b1, 0x9736, 0x971b, + 0x9732, 0x9742, 0x974d, 0x971f, 0x9721, 0x971c, 0x9731, 0x972e, + 0x9747, 0x973b, 0x9741, 0x9718, 0x9739, 0x971d, 0x9727, 0x9723, + 0x28d7, 0x99ee, 0x99e8, 0x99e5, 0x99ef, 0x99e4, 0x99ec, 0x99f0, + 0x9bd7, 0x9bd8, 0x9bd4, 0x9bca, 0x9bd2, 0x9bcb, 0x9bd3, 0x9be6, + 0x9be2, 0x9d49, 0x9d48, 0x9dff, 0x9e09, 0x9eb0, + /* 0x57 */ + 0x9eaf, 0x9f7c, 0x9f78, 0x9f7a, 0x9f72, 0x9f79, 0x9f7e, 0xa00c, + 0xa00b, 0xa0cd, 0xa0be, 0xa0bc, 0xa0bf, 0xa0c0, 0xa0bd, 0xa338, + 0xa308, 0xa305, 0xa33b, 0xa310, 0xa30c, 0xa30d, 0xa304, 0xa33a, + 0xa313, 0xa337, 0xa339, 0xa41f, 0xa44b, 0xa4ee, 0xa575, 0xa578, + 0xa57c, 0xa574, 0xa576, 0xa5ea, 0xa5eb, 0xa8fb, 0xa919, 0xa9a7, + 0xa98c, 0xa9dc, 0xa998, 0xa9be, 0xa99e, 0xaa0f, 0xa99f, 0xa9dd, + 0xa993, 0xa9bb, 0xa9b6, 0xa990, 0xa9a1, 0xa9bd, 0xa9de, 0xa93a, + 0xaa22, 0xa997, 0xa994, 0xa9c3, 0xa98e, 0xa9a8, 0xa999, 0xa9ad, + 0xa99b, 0xa9a2, 0xaa21, 0xa9ac, 0xaa0e, 0xaa31, 0xace1, 0xacde, + 0xacdf, 0xacdc, 0xacdd, 0xacec, 0xace7, 0xae69, 0xaeb8, 0xaea1, + 0xaea8, 0xaeba, 0xaec2, 0xaea6, 0xaea4, 0xaea3, 0xaeab, 0xaebc, + 0xaeb7, 0xaebf, 0xaead, 0xaeb1, 0xaeca, 0xaec4, + /* 0x58 */ + 0xaeb9, 0xb0c8, 0xb0c6, 0xb0c7, 0xb20a, 0xb20d, 0xb1fb, 0xb203, + 0xb202, 0xb1fc, 0xb1f9, 0xb1f8, 0xb36e, 0xb363, 0xb362, 0xb361, + 0xb36b, 0x1288, 0xb36f, 0xb366, 0xb36c, 0xb40e, 0xb415, 0xb416, + 0xb410, 0xb417, 0xb411, 0xb56e, 0xb56c, 0xb587, 0xb583, 0xb563, + 0xb5dc, 0xb6c0, 0xb6f7, 0xb6fa, 0xb770, 0xb76a, 0xb768, 0xb769, + 0xb784, 0xb7ec, 0xb7e7, 0xb7ee, 0xb8ba, 0xb8b2, 0xb8b5, 0xb8cb, + 0x430b, 0xb8d0, 0xb96d, 0xb96c, 0x13bb, 0xba45, 0xba46, 0xba34, + 0xba2c, 0xba35, 0xba44, 0x13ba, 0xba76, 0xbbb1, 0xbbaa, 0xbba1, + 0xbbb2, 0x1412, 0xbba6, 0xbbb5, 0xbbb4, 0xbbb8, 0xbbaf, 0xbbb0, + 0xbba3, 0xbd62, 0xbd64, 0xbe56, 0xbe51, 0xbe4f, 0xbe68, 0xbe4c, + 0xbe50, 0x1461, 0xbe48, 0xbe4a, 0xbf21, 0xc0e3, 0xc0b9, 0xc0de, + 0xc0b7, 0xc0e1, 0xc0b6, 0xc0b5, 0xc0df, 0x14e1, + /* 0x59 */ + 0xc297, 0xc29a, 0xc29b, 0xc298, 0xc292, 0xc293, 0xc2d7, 0xc273, + 0xc36b, 0xc374, 0xc378, 0xc36d, 0xc418, 0xc4e9, 0xc4f5, 0xc4ea, + 0xc52e, 0xc4e7, 0xc4fe, 0xc4e5, 0xc536, 0xc4f0, 0xc4e6, 0xc52c, + 0xc789, 0xc795, 0xc793, 0xc84d, 0xc84a, 0xc84f, 0xc850, 0xc84b, + 0xca2a, 0xca2b, 0xca2f, 0xca2e, 0xca7c, 0xcaed, 0xcae2, 0xcbe0, + 0xcbdc, 0xcbda, 0xcbd6, 0xcbf4, 0xcbd9, 0xcbd5, 0xcd22, 0xcd21, + 0xcd24, 0xcd25, 0xcd26, 0xcd23, 0xcdaa, 0xcdaf, 0xcdb0, 0xcdab, + 0xceaf, 0xceb7, 0xceb5, 0xceb2, 0xceb3, 0xcf2b, 0xcfd8, 0xcfc2, + 0xcfaf, 0xcfbc, 0xcfb8, 0xcfbe, 0xcfb7, 0xcfb4, 0xcfbf, 0xcfb3, + 0xcfb1, 0xcfbb, 0xcfbd, 0xcfd6, 0xcfdd, 0xd0d8, 0xd0d3, 0xd0d5, + 0xd0e3, 0xd0e2, 0xd0d9, 0xd0de, 0xd0df, 0xd0da, 0xd0d4, 0xd1f3, + 0xd1e2, 0xd20d, 0xd201, 0xd205, 0xd21a, 0xd203, + /* 0x5a */ + 0xd21f, 0xd216, 0xd1fa, 0xd1fc, 0xd20a, 0x359f, 0xd3bc, 0xd3ca, + 0xd3b6, 0xd3c7, 0xd3bf, 0x1789, 0xd3b9, 0x178c, 0xd3b0, 0xd3b8, + 0xd3bd, 0xd391, 0xd3bb, 0xd3be, 0xd53e, 0xd53d, 0xd638, 0xd63d, + 0xd639, 0xd633, 0xd733, 0xd7bb, 0xd7c6, 0xd7c5, 0xd7c7, 0xd7cb, + 0xd7a8, 0xd7c8, 0xd7be, 0xd7c1, 0xd7bd, 0xd882, 0xd89e, 0xd881, + 0xd884, 0x368d, 0xd896, 0xd88e, 0xd888, 0xd887, 0xdae0, 0xdb0d, + 0xdadf, 0xdae4, 0xdae2, 0xdadd, 0xdaec, 0xdade, 0xdae7, 0xdaea, + 0xdae3, 0xdd5c, 0x3977, 0xdd5d, 0xdd9c, 0xde1d, 0xde9d, 0xde9e, + 0xde9b, 0xdeb5, 0xdeb9, 0xdeb6, 0xdef3, 0xdef2, 0xdef4, 0xdf26, + 0xdf27, 0xdf25, 0xe006, 0xe00b, 0xe03a, 0xe03c, 0x3f0a, 0x3f0b, + 0x3fbf, 0x3ffd, 0x4118, 0xccdf, 0x8e90, 0x419e, 0x42fc, 0x4310, + 0x430f, 0x430d, 0x43b9, 0x43b7, 0x43ba, 0x440a, + /* 0x5b */ + 0x4b41, 0x4b8b, 0x4b46, 0x4b53, 0x4be2, 0x4b3f, 0x4a7c, 0x4b4b, + 0x4b4e, 0x4b8a, 0x4b47, 0x4f93, 0xb8ce, 0x4f8c, 0x4faf, 0x4fc9, + 0x50c6, 0x50c8, 0x5191, 0x53cf, 0x53d4, 0x53ce, 0x55dd, 0x55d4, + 0x5a49, 0x5a63, 0x5a5d, 0x041a, 0x5a67, 0x5abb, 0x5a60, 0x5a80, + 0x5c5f, 0x5c60, 0x5dda, 0x5dd2, 0x5ddd, 0x608e, 0x6088, 0x606c, + 0x639e, 0x63c9, 0x63a4, 0x0598, 0x63d9, 0x63d2, 0x63da, 0x63dd, + 0x63ce, 0x63fc, 0x6514, 0x6560, 0x68d7, 0x68cb, 0x68cd, 0x68d5, + 0x69e7, 0x6b00, 0x6b0a, 0x6b0f, 0x6b02, 0x6b01, 0x6c1d, 0x6dca, + 0x6dcb, 0x6dcd, 0x6e4f, 0x6e9c, 0x7180, 0x720d, 0x7202, 0x07f1, + 0x7207, 0x71f7, 0x71f8, 0x71fd, 0x7224, 0x71fb, 0x7239, 0x723a, + 0x7422, 0x21a9, 0x756a, 0x756d, 0x7574, 0x770e, 0x7adf, 0x7b2b, + 0x7ae3, 0x7b26, 0x7b2a, 0x7b23, 0x7b35, 0x7b4a, + /* 0x5c */ + 0x7efd, 0x7f00, 0x7f1e, 0x7eff, 0x809e, 0x80fa, 0x81f1, 0x8395, + 0x83a8, 0x83a6, 0x856e, 0x8583, 0x856d, 0x868f, 0x0b6a, 0x87df, + 0x87d5, 0x87e0, 0x87d3, 0x87d8, 0x898c, 0x254b, 0x8994, 0x8996, + 0x8985, 0x898f, 0x89a9, 0x898e, 0x8990, 0x89b8, 0x89c3, 0x89bb, + 0x8aa5, 0x8aa2, 0x25a2, 0x8aa3, 0x8bb5, 0x8bac, 0x8ba8, 0x8dad, + 0x8db8, 0x8db4, 0x8dae, 0x8db6, 0x1085, 0x8dc1, 0x8dbf, 0x8e92, + 0x8f00, 0x8f01, 0x9075, 0x9072, 0x9078, 0x9070, 0x907e, 0x907d, + 0x907f, 0x91ef, 0x936d, 0x938e, 0x938f, 0x938a, 0x938d, 0x9395, + 0x938b, 0x938c, 0x93b0, 0x9393, 0x94fc, 0x9515, 0x950e, 0x9518, + 0x9511, 0x950d, 0x95bb, 0x95b3, 0x0e39, 0x97a1, 0x979a, 0x9784, + 0x97a0, 0x9786, 0x979d, 0x97aa, 0x9778, 0x978d, 0x978a, 0x97a6, + 0x977a, 0x9797, 0x9788, 0x978e, 0x0e3d, 0x0e44, + /* 0x5d */ + 0x9776, 0x9781, 0x9785, 0x9775, 0x97a8, 0x978f, 0x9791, 0x97a2, + 0x979c, 0x9789, 0x977f, 0x9796, 0x9779, 0x979f, 0x97a7, 0x0e46, + 0x9787, 0x979b, 0x97a5, 0x978b, 0x97c9, 0x99ff, 0x9a03, 0x9a00, + 0x9a02, 0x9a04, 0x9a05, 0x99e6, 0x9a1f, 0x9c14, 0x0f0e, 0x9c0c, + 0x9c0f, 0x9c19, 0x9c0b, 0x9c13, 0x9bd5, 0x0f10, 0x9c1c, 0x9d50, + 0x9d4e, 0x9e12, 0x9eb9, 0x9f85, 0x9f88, 0x9f90, 0xa013, 0xa0d0, + 0xa0d1, 0xa0d2, 0xa0d7, 0xa0d6, 0xa0e5, 0xa346, 0xa36b, 0xa345, + 0xa33f, 0xa33e, 0x103e, 0xa36a, 0xa368, 0xa34c, 0xa423, 0xa422, + 0xa497, 0xa491, 0x95b5, 0xa498, 0xa49c, 0xa589, 0x1084, 0xa58b, + 0xa58a, 0xa58d, 0xa58e, 0xa588, 0xaa4e, 0xaa44, 0xaa37, 0xaa75, + 0xaa54, 0xaa76, 0xaa34, 0xaa6b, 0xaa32, 0xaa57, 0xaa52, 0xaa45, + 0x1149, 0xa9b1, 0xaa4b, 0xaa47, 0xaa33, 0xaa40, + /* 0x5e */ + 0xaa3c, 0xaa43, 0xaa4f, 0xaa55, 0xaa41, 0xaab2, 0xaac0, 0xaf34, + 0xaef9, 0xaf19, 0xaf0d, 0xaefa, 0xaf1e, 0xaf1f, 0xaf0e, 0xaf40, + 0xaf08, 0x11df, 0xaf13, 0xaf4c, 0x11f0, 0xb0cc, 0xb0cb, 0xb224, + 0xb225, 0xb23d, 0xb220, 0xb227, 0xb226, 0xb21d, 0xb21e, 0xb232, + 0xb26c, 0xb259, 0x128a, 0xb37a, 0xb379, 0xb41b, 0xb42e, 0xb423, + 0xb420, 0xb41f, 0xb5b6, 0xb5b9, 0xb5a1, 0xb5a3, 0xb5a8, 0xb5af, + 0xb59a, 0xb599, 0xb5a2, 0xb59d, 0x1302, 0xb5ab, 0xb6c9, 0xb6fe, + 0xb700, 0xb6fc, 0xb707, 0xb775, 0xb772, 0xb773, 0xb774, 0xb7fa, + 0xb7fc, 0xb7f8, 0xb7f6, 0xb7fb, 0xb8cd, 0xb8d1, 0xb8cf, 0xb974, + 0xb972, 0xb973, 0xba54, 0xba51, 0x13c0, 0xba53, 0xba49, 0xba4c, + 0xba4a, 0xba4f, 0xba56, 0xbc00, 0xbbd5, 0xbbd7, 0xbbff, 0xbbd9, + 0xbbe3, 0xbbd3, 0x1415, 0xbbd8, 0xbbd4, 0xbbde, + /* 0x5f */ + 0xbd71, 0xbe74, 0xbe88, 0xbe7f, 0xbe6b, 0xbe87, 0xbe79, 0xbe78, + 0xbe89, 0xbe80, 0xbe76, 0xbf29, 0xbf28, 0xbf2f, 0xc0e5, 0xc104, + 0xc103, 0xc0f0, 0xc0e8, 0xc0ea, 0xc0f1, 0xc101, 0xc102, 0xc2a9, + 0xc2ab, 0xc2b7, 0xc2b6, 0x14e2, 0xc3a0, 0xc38e, 0xc386, 0xc387, + 0xc385, 0xc38b, 0xc388, 0xc390, 0xc41a, 0xc434, 0xc537, 0xc52f, + 0xc530, 0xc539, 0xc534, 0xc533, 0xc585, 0xc584, 0xc53a, 0xc79f, + 0xc869, 0xc86c, 0xc86a, 0xc867, 0xc86b, 0xca3f, 0xca40, 0xcb0b, + 0xcbd2, 0xcbf8, 0xcc01, 0xcbfa, 0xcc16, 0xe3f6, 0xcd2c, 0xcd2d, + 0xcd2f, 0xcd2e, 0xcdc1, 0xcdf5, 0xcdc4, 0xcdde, 0xcdcc, 0xcdd2, + 0xcdc2, 0xcdcd, 0xcdcf, 0xcddd, 0xcdc8, 0xceba, 0xcebe, 0xcebf, + 0xcf2e, 0xcf30, 0xcfe7, 0xcfee, 0xcfe8, 0xcfe6, 0xcfe2, 0xcfe4, + 0xcffb, 0xcffc, 0xcfea, 0xd0ed, 0xd0f6, 0xd0f3, + /* 0x60 */ + 0xd0f4, 0xd0f1, 0xd0f7, 0xd0f5, 0xd0ea, 0xd0eb, 0xd200, 0xd22c, + 0xd212, 0xd23d, 0xd233, 0x174d, 0xd230, 0xd240, 0xd231, 0xd257, + 0x174a, 0xd235, 0xd232, 0xd22d, 0xd236, 0xd238, 0xd262, 0xd25f, + 0xd28a, 0xd3d6, 0xd3d8, 0xd3dd, 0xd3e4, 0xd3e3, 0xd54d, 0xd5d7, + 0xd64a, 0xd64c, 0xd650, 0xd64b, 0xd64e, 0xd64f, 0xd739, 0xd7d2, + 0xd7cd, 0xd7d3, 0xd7e1, 0xd7ce, 0xd7d5, 0xd7dd, 0xd7d4, 0xd7cf, + 0xd8cb, 0xd8a6, 0xd8c2, 0xd8a5, 0xd8a9, 0xd8a2, 0xd8a4, 0xd8b0, + 0xd8cc, 0xd8af, 0xd8bf, 0xdb24, 0xdb1a, 0xdb14, 0xdb3a, 0xdb20, + 0xdb1b, 0xdb21, 0xdb25, 0xdb1e, 0xdb3f, 0xdb40, 0xdb18, 0xdb2c, + 0xdb15, 0xdb2d, 0xdb1f, 0xdb29, 0xdb4b, 0xddb3, 0xdda5, 0xdda7, + 0xddab, 0xdda6, 0xddaa, 0xde22, 0xde23, 0xdea1, 0xdea3, 0xdea0, + 0xdebd, 0xdeba, 0xdefa, 0xdef8, 0xdefc, 0xdef6, + /* 0x61 */ + 0xdf34, 0xdf43, 0x1963, 0xdfd4, 0xe00d, 0xe043, 0xe041, 0xe03d, + 0xe040, 0xe03e, 0xe03f, 0xe046, 0x1993, 0xe0d4, 0x3f35, 0x3f36, + 0x3f32, 0x3f3a, 0x3fc8, 0x4036, 0x411e, 0x411d, 0x411f, 0x431c, + 0x431d, 0x4320, 0x010e, 0x43c0, 0x4b9a, 0x4b93, 0x4bdd, 0x020a, + 0x4ba3, 0x4ba9, 0x4b9c, 0x4b9b, 0x020d, 0x4b97, 0x4fb1, 0x4fca, + 0x4fb3, 0x4fcd, 0x53ea, 0x53ee, 0x53ef, 0x55df, 0x5650, 0x56bb, + 0x5a88, 0x5a89, 0x5a8c, 0x5a85, 0x5a5e, 0x5a94, 0x5a95, 0x5c6b, + 0x5c6a, 0x5c69, 0x5de3, 0x5df1, 0x5f37, 0x5f33, 0x6091, 0x608f, + 0x6097, 0x63d4, 0x63de, 0x63d3, 0x63e0, 0x6443, 0x640b, 0x63ff, + 0x6404, 0x6407, 0x68f9, 0x68fa, 0x68fb, 0x68f8, 0x6b12, 0x6b10, + 0x6c1f, 0x6ddf, 0x6de3, 0x6e52, 0x6ea9, 0x7265, 0x7287, 0x7242, + 0x7252, 0x724c, 0x719f, 0x7201, 0x7248, 0x724f, + /* 0x62 */ + 0x727e, 0x724d, 0x7258, 0x7247, 0x725e, 0x7249, 0x724e, 0x725d, + 0x725a, 0x7286, 0x7251, 0x7429, 0x74a6, 0x74a7, 0x7570, 0x756f, + 0x75d3, 0x75d2, 0x7728, 0x771b, 0x771a, 0x771c, 0x7721, 0x7b32, + 0x7b66, 0x7b7d, 0x7b73, 0x7b7f, 0x7b65, 0x7b80, 0x7b61, 0x7b75, + 0x7b6e, 0x7b67, 0x7b71, 0x7b6c, 0x7b63, 0x7b62, 0x7b83, 0x7bb2, + 0x7b81, 0x7b6f, 0x7b6b, 0x7b82, 0x7b8a, 0x7f29, 0x7f30, 0x7f31, + 0x8097, 0x8100, 0x80ff, 0x83b6, 0x83b5, 0x83c3, 0x858d, 0x8618, + 0x869c, 0x869a, 0x8699, 0x89b7, 0x89c4, 0x89c6, 0x89c7, 0x89bc, + 0x89c0, 0x89c5, 0x89cd, 0x89c1, 0x89be, 0x8aa7, 0x8ab8, 0x8b23, + 0x0c74, 0x8de8, 0x8dde, 0x8de3, 0x8def, 0x8ddc, 0x8de4, 0x8de1, + 0x8de5, 0x8e95, 0x8e94, 0x8e93, 0x8e8e, 0x9098, 0x909c, 0x9099, + 0x90a0, 0x909e, 0x9204, 0x93d3, 0x93b4, 0x93bb, + /* 0x63 */ + 0x93b7, 0x93b8, 0x93bd, 0x93b6, 0x93b9, 0x93b5, 0x9522, 0x9521, + 0x95c3, 0x95bc, 0x97ff, 0x97e5, 0x97f7, 0x97d2, 0x9800, 0x97db, + 0x97f0, 0x97e2, 0x97cd, 0x0e56, 0x97e1, 0x97f2, 0x97dc, 0x97cc, + 0x97d6, 0x97f3, 0x97fa, 0x97f6, 0x97ec, 0x97ea, 0x97e3, 0x97d0, + 0x0e5a, 0x9795, 0x97d5, 0x97f4, 0x97cb, 0x97da, 0x97c8, 0x97df, + 0x97f5, 0x97cf, 0x97c7, 0x97d7, 0x9a24, 0x0ea3, 0x9a1c, 0x9a21, + 0x9a1e, 0x9a18, 0x9a1b, 0x0ea8, 0x9c46, 0x9c4b, 0x9c48, 0x9c47, + 0x9c67, 0x9c54, 0x9e15, 0x9e22, 0x9ec5, 0x9e29, 0x9ec7, 0x9f8d, + 0xa01b, 0xa020, 0xa0e2, 0xa0e7, 0xa0e8, 0xa0e1, 0xa372, 0xa37b, + 0xa374, 0xa371, 0xa379, 0xa375, 0xa390, 0xa377, 0xa37d, 0xa44f, + 0xa450, 0xa4a3, 0xa4a2, 0xa4f4, 0xa594, 0xa59a, 0xa59b, 0xa5a7, + 0xa597, 0xa595, 0xa592, 0xa59c, 0xa596, 0xaab6, + /* 0x64 */ + 0xaab8, 0xaab0, 0xab18, 0xaac5, 0xaab5, 0xaac2, 0xab06, 0xab19, + 0xaab9, 0xab15, 0xaad6, 0xaaac, 0x113c, 0xaac6, 0xaab3, 0xaac3, + 0xaaca, 0xaacf, 0xaabd, 0xaace, 0xab14, 0xaaba, 0xab1a, 0xaac1, + 0xaabb, 0x119b, 0x119a, 0xad01, 0xacfc, 0xaf5a, 0xaf54, 0xaf61, + 0xaf5c, 0xaf55, 0xaf4a, 0xaf4b, 0xaf51, 0xaf69, 0xaf6b, 0x2cf1, + 0xaf66, 0xaf58, 0xaf5d, 0xaf67, 0xaf56, 0xaf88, 0xaf64, 0xaf4e, + 0xb257, 0xb25a, 0xb251, 0xb24a, 0xb24b, 0x125e, 0xb247, 0xb26f, + 0xb26a, 0xb26b, 0xb246, 0xb26d, 0xb254, 0xb26e, 0xb24c, 0xb378, + 0xb386, 0xb382, 0x12a7, 0xb5e1, 0xb5e5, 0xb5db, 0xb5de, 0xb5d7, + 0xb703, 0xb77c, 0xb77e, 0xb805, 0xb807, 0xb8e6, 0xb8e1, 0xb8fb, + 0xb8e5, 0xb8e7, 0xb8df, 0xb8ff, 0xb976, 0xba63, 0xba66, 0xba65, + 0xba5e, 0xba64, 0xba6b, 0xba5f, 0xba67, 0xba68, + /* 0x65 */ + 0xbc08, 0xbc09, 0xbc17, 0xbc15, 0xbc1b, 0xbc0b, 0xbc28, 0xbc0e, + 0xbc18, 0xbc53, 0xbc45, 0xbc0d, 0xbc0a, 0xbc13, 0xbc4a, 0xbd79, + 0xbea1, 0xbe8d, 0xbea2, 0xbe90, 0x146e, 0xbf31, 0xbf30, 0xc11f, + 0xc119, 0xc10c, 0xc11e, 0xc11d, 0xc107, 0xc266, 0xc2c5, 0xc2ba, + 0xc2bd, 0xc2c2, 0xc2c3, 0xc2bf, 0x150d, 0xc3a1, 0xc3a2, 0xc3a8, + 0xc3a3, 0xc3aa, 0xc3af, 0xc3b9, 0xc437, 0xc58f, 0x1543, 0xc58e, + 0xc587, 0xc58a, 0xc592, 0xc597, 0xc59f, 0xc605, 0xc7a9, 0xc7a7, + 0xc88a, 0xc882, 0xc885, 0xc88b, 0xc889, 0xc881, 0xc880, 0xc887, + 0xc886, 0xca4d, 0xcb1c, 0xcb1f, 0xcc21, 0xcc1d, 0xcc22, 0xcbfe, + 0xcc1b, 0xcc3a, 0xcc37, 0xcc17, 0xcc38, 0xcc26, 0xcc18, 0xcd34, + 0xcd35, 0xcd32, 0x1673, 0xcde1, 0xcdfd, 0xcde3, 0xcde8, 0xcdf9, + 0xcdff, 0xcdfe, 0x1674, 0xcde0, 0xce00, 0x1670, + /* 0x66 */ + 0xcdec, 0xcde4, 0xcdef, 0xcdfa, 0xceca, 0xcf31, 0xcf32, 0xcf34, + 0xcf41, 0xd000, 0xd006, 0xd008, 0xd005, 0xd003, 0xd00b, 0xd002, + 0xd00a, 0xd0f0, 0xd113, 0xd10a, 0xd10f, 0xd111, 0xd108, 0xd10b, + 0xd112, 0xd10d, 0xd25b, 0xd263, 0xd261, 0xd268, 0xd25a, 0xd34e, + 0xd34d, 0xd350, 0xd3fc, 0xd412, 0xd3f5, 0xd41e, 0xd3f0, 0xd3f3, + 0xd3f2, 0xd401, 0xd3ef, 0xd3ee, 0xd416, 0xd3f6, 0xd3fb, 0xd41c, + 0x17db, 0xd55d, 0xd560, 0xd566, 0xd55f, 0xd561, 0xd55b, 0xd562, + 0xd557, 0xd669, 0xd66b, 0xd661, 0xd677, 0xd65f, 0xd663, 0xd662, + 0xd665, 0xd7ef, 0xd7e2, 0xd800, 0xd7e8, 0xd7f2, 0xd7e7, 0x1829, + 0xd7e5, 0xd8d5, 0xd8d0, 0xd8da, 0xd8d3, 0x1851, 0xd8d9, 0xd8cf, + 0xd8d6, 0xd8d8, 0xd8f5, 0xd8ce, 0xd8d7, 0xd8f4, 0xd8cd, 0xd901, + 0x36ba, 0xdb52, 0xdb55, 0xdb5a, 0xdb4d, 0xdb54, + /* 0x67 */ + 0xdb53, 0xdb5e, 0xdb67, 0xdb65, 0xdb4e, 0x18db, 0xdb4f, 0xdb61, + 0xdb6e, 0xdb51, 0xdb5b, 0xdd63, 0xddb7, 0xddb6, 0xddc3, 0xddbb, + 0xddb5, 0xde2e, 0xde30, 0xde33, 0xde31, 0xdea4, 0xdec1, 0xdebb, + 0xdebe, 0xdf00, 0xdeff, 0xdf40, 0x1965, 0xdf3f, 0xdf44, 0x1964, + 0x1967, 0xdfdb, 0xe00f, 0xe011, 0xe04e, 0xe04d, 0xe04b, 0xe04c, + 0xe095, 0x3f3b, 0x3f45, 0x3f44, 0x3f3e, 0x3f3c, 0x3f3f, 0x3fcc, + 0x3fce, 0x4122, 0x4123, 0x419f, 0x43c5, 0x43c4, 0x4be9, 0x4b99, + 0x0211, 0x4be6, 0x4be7, 0x4bf7, 0x4fd2, 0x0333, 0x53fd, 0x540c, + 0x540b, 0x57ed, 0x0421, 0x0422, 0x5a9b, 0x5b0a, 0x5c6f, 0x5c75, + 0x5df2, 0x5df8, 0x5f3e, 0x6424, 0x640e, 0x6416, 0x6418, 0x6410, + 0x6431, 0x6444, 0x05a6, 0x6429, 0x642f, 0x644b, 0x6436, 0x05a3, + 0x6934, 0x6900, 0x692b, 0x6b20, 0x6b21, 0x6b1e, + /* 0x68 */ + 0x6b1d, 0x6df5, 0x6df2, 0x6df6, 0x7290, 0x729d, 0x729c, 0x7292, + 0x7294, 0x72d1, 0x7293, 0x72b7, 0x7297, 0x72b0, 0x729f, 0x72c9, + 0x742d, 0x742c, 0x7577, 0x772c, 0x7bc0, 0x7bb9, 0x7f53, 0x8040, + 0x8202, 0x81fb, 0x0aa1, 0x858b, 0x85ae, 0x85ab, 0x86a1, 0xddcd, + 0x87ea, 0x89dd, 0x89dc, 0x89d9, 0x8aab, 0x8aac, 0x8aad, 0x8ab2, + 0x8b2c, 0x8b2b, 0x8bc2, 0x8e00, 0x8e0d, 0x8e06, 0x8dff, 0x8e03, + 0x8e01, 0x8e10, 0x8e0f, 0x8e05, 0x8e98, 0x8e97, 0x8e96, 0x8e99, + 0x90ac, 0x90ab, 0x9212, 0x93d8, 0x93df, 0x93d6, 0x952d, 0x9532, + 0x983f, 0x982f, 0x9826, 0x983a, 0x9839, 0x0e5f, 0x983b, 0x9835, + 0x982a, 0x9821, 0x9838, 0x9837, 0x9834, 0x0e5c, 0x9822, 0x9836, + 0x9844, 0x9a45, 0x9a3b, 0x9a36, 0x9a42, 0x9c7a, 0x9c86, 0x9c8b, + 0x9c7f, 0x9c81, 0x9e2a, 0x9ed5, 0x9f9f, 0x9f9d, + /* 0x69 */ + 0xa026, 0xa0f4, 0xa0f5, 0xa315, 0xa38e, 0xa38f, 0xa426, 0xa4a7, + 0xa4af, 0xa5ad, 0xa5ac, 0xa5ab, 0xa5aa, 0xab2f, 0xab21, 0xab23, + 0xaba3, 0xab49, 0xab3a, 0xab48, 0xab2d, 0xab25, 0xab29, 0xab32, + 0xab34, 0xab24, 0xab2c, 0xab4b, 0xab3b, 0xab20, 0xab28, 0xaf98, + 0x11f5, 0xaf97, 0x2d04, 0xaf9d, 0xafa8, 0xb0d5, 0xb277, 0xb278, + 0xb272, 0xb273, 0xb302, 0xb43b, 0xb5fe, 0xb60b, 0xb5ff, 0xb607, + 0x1311, 0x130c, 0xb630, 0xb6cd, 0xb6cf, 0xb710, 0xb70a, 0xb783, + 0xb815, 0xb80e, 0xb80c, 0xb902, 0xb8fe, 0xb905, 0xb915, 0xb908, + 0xba7f, 0xba77, 0xba7c, 0xba82, 0xba7e, 0xba78, 0xba7d, 0xba79, + 0xba81, 0xbc4b, 0xbc63, 0xbc64, 0xbc56, 0xbc54, 0xbc4e, 0xbc10, + 0xbc4f, 0xbc57, 0xbc5e, 0xbc51, 0xbc6a, 0xbc69, 0xbead, 0xbea4, + 0xbeac, 0xbea9, 0xbeae, 0x3f4c, 0xc150, 0xc135, + /* 0x6a */ + 0xc132, 0xc2d8, 0xc2d1, 0xc2cf, 0xc2be, 0xc3d5, 0xc3c1, 0xc3c6, + 0xc3c3, 0xc3c2, 0xc3c0, 0xc3c5, 0xc3c7, 0xc3bf, 0xc3c4, 0xc3d4, + 0xc590, 0xc5d2, 0x154e, 0xc5d4, 0xc7af, 0xc7ae, 0xc7b2, 0xc7ad, + 0xc89c, 0xc8a0, 0xc8b6, 0xca3d, 0xca56, 0xca82, 0xcb28, 0xcb2b, + 0xcc3c, 0xcc3e, 0xcc3f, 0xcc42, 0xcc3d, 0xcc41, 0xcc3b, 0xcc49, + 0xcc43, 0xcd39, 0xcd38, 0xce22, 0xce08, 0xce0c, 0xce06, 0xce13, + 0xce04, 0xce20, 0xce1d, 0xce05, 0xce0a, 0xced6, 0xced7, 0xcf36, + 0xcf37, 0xd023, 0xd022, 0xd020, 0xd01a, 0xd01d, 0xd11c, 0xd120, + 0xd177, 0xd27f, 0xd28b, 0xd27d, 0xd299, 0xd284, 0xd289, 0xd285, + 0xd283, 0xd286, 0xd29e, 0xd353, 0xd417, 0x1794, 0xd419, 0xd420, + 0xd41f, 0xd423, 0xd418, 0xd421, 0xd429, 0xd424, 0xd426, 0xd55e, + 0xd56f, 0xd56e, 0xd574, 0xd572, 0xd573, 0xd67d, + /* 0x6b */ + 0xd67e, 0xd685, 0xd67f, 0xd684, 0xd744, 0xd7f5, 0xd7f8, 0xd803, + 0xd7f6, 0xd928, 0x1863, 0xd939, 0xd8fb, 0xd90e, 0xd8fd, 0xd91f, + 0x1861, 0xd903, 0x36d8, 0xd910, 0x185a, 0xd90d, 0xd927, 0xd941, + 0xdb72, 0xdb78, 0xdb80, 0x18e3, 0xdb85, 0xdb7b, 0x387c, 0xdb7d, + 0xdb91, 0xdb88, 0xdbaa, 0xdb8d, 0xdb89, 0xdb95, 0xdb9b, 0xdb8c, + 0xdb9e, 0xdb7c, 0xdb86, 0xdb84, 0xdd68, 0xddc5, 0xddc4, 0xddc9, + 0xddc6, 0xde42, 0xde45, 0xde41, 0xde44, 0xdea6, 0xdec2, 0xdf42, + 0xdf49, 0xdf48, 0xdf4a, 0xdf4c, 0xdf4b, 0xe017, 0xe018, 0xe015, + 0xe052, 0xe054, 0xe053, 0xe09a, 0xe09b, 0xe0dc, 0xe0e4, 0xe191, + 0x19af, 0xe1ba, 0x3f51, 0x3f5b, 0x3fcf, 0x6e05, 0x4c13, 0x4c15, + 0x4c14, 0x4c23, 0x0213, 0x4c11, 0x4c12, 0x0280, 0x4ff0, 0x519b, + 0x5412, 0x5416, 0x5417, 0x54b5, 0x57f4, 0x5ab1, + /* 0x6c */ + 0x5c79, 0x5dff, 0x5dfc, 0x5dfb, 0x5f3f, 0x5f44, 0x609d, 0x6432, + 0x644c, 0x642b, 0x645a, 0x651f, 0x6901, 0x692d, 0x6927, 0x6959, + 0x695a, 0x694d, 0x6958, 0x6b23, 0x6b25, 0x6b2b, 0x6dff, 0x6eae, + 0x72cb, 0x72ca, 0x72d0, 0x72ce, 0x72cc, 0x72d8, 0x72c6, 0x72d2, + 0x72cf, 0x72c8, 0x7617, 0x19b0, 0x7bc4, 0xcd40, 0x7be9, 0x7bf2, + 0x7bfc, 0x7bea, 0x7beb, 0x7bfd, 0x7f78, 0x7f77, 0x7f73, 0x7f9e, + 0x7f79, 0x80a2, 0x8103, 0x8204, 0x8205, 0x83ce, 0x85bf, 0x89f6, + 0x89f7, 0x8b31, 0x8b30, 0x8bc9, 0x8bc7, 0x8e1c, 0x8e28, 0x8e1a, + 0x8e1e, 0x8e1b, 0x8e1f, 0x90bf, 0x90bb, 0x90bc, 0x90c0, 0x921a, + 0x93ef, 0x93ec, 0x93e9, 0x93f0, 0x93fe, 0x9534, 0x986a, 0x9895, + 0x986c, 0x9872, 0x9867, 0x9860, 0x986b, 0x985e, 0x986f, 0x9866, + 0x2946, 0x9862, 0x985d, 0x985c, 0xe365, 0x9a50, + /* 0x6d */ + 0x9c9f, 0x0f23, 0x9c9e, 0x9ca6, 0x9e35, 0x9e38, 0x9e36, 0x9e3a, + 0x9edc, 0xa37c, 0xa3ab, 0x1049, 0xa3a8, 0xa3a7, 0xa42b, 0xa42c, + 0xa428, 0x442b, 0xa4a9, 0xa4aa, 0xa4ab, 0xa4f8, 0xa5b1, 0xa5f0, + 0xa5ef, 0xaba8, 0xab8b, 0xab94, 0xab9e, 0xab8f, 0xab88, 0xab7e, + 0xab81, 0xab30, 0xab9b, 0xab82, 0xab90, 0xab85, 0xab7f, 0xaba9, + 0xabde, 0xad0d, 0x11fa, 0xafcf, 0xafcb, 0xafd8, 0xafdd, 0xafd3, + 0xafd0, 0xafd5, 0xafd6, 0xb0d6, 0xb292, 0xb295, 0xe0cb, 0xb28d, + 0xb29b, 0xb29d, 0xb28f, 0xb29e, 0xb2a6, 0xb396, 0xb392, 0xb616, + 0xb62a, 0xb629, 0xb62c, 0xb715, 0xb712, 0xb711, 0xb713, 0xb788, + 0xb78b, 0xb78a, 0xb787, 0xb817, 0xb816, 0xb81a, 0xb919, 0xb917, + 0xba91, 0xba94, 0xbc8b, 0xbc90, 0xbc8f, 0xbc86, 0xbc83, 0xbc8e, + 0xbc87, 0xbca8, 0xbc85, 0xbca6, 0xbc82, 0xbca7, + /* 0x6e */ + 0xbeb9, 0xbeb7, 0xbeb4, 0xbeb6, 0xbeb3, 0xbec6, 0xc13c, 0xc140, + 0xc138, 0xc291, 0xc2a6, 0xc2da, 0xc3da, 0xc3d8, 0xc3d9, 0xc3db, + 0xc3d7, 0xc616, 0xc612, 0xc61f, 0x1559, 0xc614, 0xc61a, 0xc610, + 0xc7b3, 0xc8ae, 0xc8c1, 0xc8b0, 0xc8af, 0xc8b1, 0xc8ad, 0xc8b2, + 0xc8c4, 0xcb3c, 0xcb3f, 0xcc61, 0xcc66, 0xcd3c, 0xcd3b, 0xce2c, + 0x167e, 0xce2a, 0xce3e, 0xce2f, 0xce32, 0xce27, 0xce29, 0xce40, + 0xcedf, 0xcede, 0xcf3c, 0xcf3b, 0xcf3e, 0xd021, 0xd046, 0xd03c, + 0xd036, 0xd038, 0xd035, 0xd131, 0xd136, 0xd12d, 0xd133, 0xd12f, + 0xd12e, 0xd135, 0xd2ac, 0xd2a9, 0xd2a6, 0x17a8, 0xd44c, 0xd443, + 0xd441, 0xd44f, 0xd442, 0xd451, 0x17a9, 0xd440, 0xd450, 0xd445, + 0xd44a, 0xd44b, 0xd583, 0xd582, 0xd581, 0xd5e0, 0xd698, 0xd69f, + 0xd69b, 0xd69a, 0xd699, 0xd696, 0xd6ae, 0xd69e, + /* 0x6f */ + 0xd809, 0xd80d, 0xd94e, 0xd94a, 0xd94d, 0xd940, 0xd93e, 0xd948, + 0xd942, 0xd962, 0xd945, 0xd951, 0xdbc6, 0xdbd0, 0xdbc0, 0xdbb7, + 0xdbc2, 0xdbbc, 0xdbc5, 0xdbdc, 0xdbdb, 0xdbd2, 0xdbc7, 0xdbb6, + 0xdbc9, 0xdbcc, 0xdbd1, 0xdbcd, 0xdbda, 0xdbba, 0xdbd3, 0xdbce, + 0xdbf6, 0xdbbd, 0xdbdd, 0xdbc8, 0xdc0d, 0xdc35, 0xdd71, 0xdd6e, + 0xdd6f, 0xddd6, 0xde4c, 0xde4f, 0xde54, 0xde53, 0xdec9, 0xdec8, + 0xdf03, 0x1954, 0xdf04, 0x1956, 0xdf57, 0xdf52, 0xdf53, 0x196d, + 0xdf56, 0xdf5c, 0xdf55, 0xe064, 0xe05d, 0xe05e, 0xe0a2, 0xe0a3, + 0x198e, 0xe0e7, 0xe0e6, 0xe198, 0xe1ac, 0xe1af, 0xe1ae, 0x3f59, + 0x40a9, 0x432a, 0x43c7, 0x4c41, 0x4c37, 0x4c35, 0x4c33, 0x4c39, + 0x4c32, 0x4fff, 0x5001, 0x4ff8, 0x541b, 0x5419, 0x56bf, 0x5abc, + 0x5abe, 0x5abd, 0x5c7d, 0x5f46, 0x5f47, 0x60a4, + /* 0x70 */ + 0x6521, 0x6562, 0x6986, 0x0672, 0x6b2f, 0x6b31, 0x0814, 0x72f8, + 0x72f5, 0x72f9, 0x72f2, 0x72fa, 0x72f3, 0x7314, 0x72fd, 0x730f, + 0x730e, 0x7301, 0x7437, 0x7435, 0x7434, 0x7431, 0x757a, 0x757b, + 0x7737, 0x7c2b, 0x7bfb, 0x7c16, 0x7c13, 0x0993, 0x7c11, 0x7c0f, + 0x7c1b, 0x7c38, 0x7fa4, 0x8209, 0x8207, 0x820b, 0x83d3, 0x83d1, + 0x83d8, 0x861d, 0x86a9, 0x86d0, 0xad15, 0x8a02, 0x8a05, 0x8a01, + 0x8a00, 0x8e2e, 0x8e30, 0x8e2f, 0x8e31, 0x90d2, 0x90d3, 0x9402, + 0x9540, 0x9542, 0x953b, 0x95ce, 0x9898, 0x988f, 0x9894, 0x9891, + 0x0e6f, 0x98ba, 0x9890, 0x9886, 0x989a, 0x988c, 0x9893, 0x9887, + 0x9888, 0x9897, 0x988d, 0x989c, 0x98bd, 0x9a3c, 0x9a59, 0x0eb0, + 0x9cd1, 0x9cbb, 0x9cbe, 0x9d5d, 0x9ee2, 0xa105, 0xa3ba, 0x012e, + 0xa3f4, 0xa4b2, 0xa4f9, 0xa5b7, 0xa5b6, 0xab89, + /* 0x71 */ + 0xabf9, 0xabd9, 0xabe8, 0xabd4, 0xabdb, 0xabe2, 0xabdf, 0xabd1, + 0xabe9, 0xabea, 0xad13, 0xad11, 0xaffa, 0xaff8, 0xaff4, 0xaffb, + 0xb00e, 0xb002, 0xb00f, 0xb290, 0xb2ad, 0xb2a9, 0xb448, 0xb65a, + 0xb64f, 0xb64e, 0xb655, 0xb654, 0xb64a, 0xb6d5, 0xb718, 0xb78d, + 0xb81d, 0xb819, 0xb926, 0xb928, 0xb92b, 0xb97d, 0xbaa0, 0xba9a, + 0xba9b, 0xbcb5, 0xbcad, 0xbcb2, 0xbd94, 0xbec9, 0xc14e, 0xc14f, + 0xc144, 0xc152, 0xc3e9, 0xc439, 0x1569, 0x337e, 0xc8c7, 0xc8d3, + 0xc8c6, 0xc8c3, 0x15b4, 0xc8d2, 0xca66, 0xcc7f, 0xcc80, 0xcc84, + 0xcc85, 0xcce3, 0x164d, 0xcd41, 0xcd44, 0xcd43, 0xce4e, 0xce4f, + 0x1683, 0xce49, 0xce4a, 0xce4b, 0xce43, 0xcee0, 0xcee5, 0xcee1, + 0xcee6, 0xcee2, 0xcf0c, 0xcf40, 0xd049, 0xd04a, 0xd054, 0xd04c, + 0xd055, 0xd056, 0xd13b, 0xd13d, 0xd2a4, 0xd2a8, + /* 0x72 */ + 0xd2c3, 0xd2bf, 0xd2c8, 0xd2c2, 0xd2ca, 0xd2cc, 0xd2c9, 0xd2be, + 0xd2cd, 0xd2c7, 0xd2c5, 0xd35d, 0x17b0, 0xd46c, 0xd46b, 0xd470, + 0xd46d, 0xd46f, 0xd489, 0xd484, 0xd58d, 0xd58a, 0xd58e, 0xd591, + 0xd6b5, 0xd6b1, 0xd6af, 0xd6b9, 0xd6b7, 0xd6b0, 0x180c, 0xd717, + 0x1818, 0xd74f, 0xd819, 0xd810, 0xd818, 0xd811, 0xd81c, 0xd812, + 0xd976, 0xd971, 0x3720, 0xd97a, 0xd97f, 0x3722, 0xd973, 0xd9ab, + 0x371e, 0xd977, 0xd974, 0xd97e, 0xd99b, 0xd984, 0xd97c, 0xdc29, + 0xdc2b, 0xdc0e, 0xdc00, 0xdc0b, 0xdbfe, 0xdbfa, 0xdc17, 0xdbff, + 0xdc0c, 0xdc0f, 0x18f5, 0xdc02, 0xdc01, 0xdbfc, 0xdc49, 0xdc06, + 0xdc12, 0xdc13, 0xdd78, 0xde5b, 0xde62, 0xde5f, 0xde5d, 0xdeab, + 0xded5, 0xded4, 0xded3, 0xdf07, 0xdf6c, 0xdf70, 0xdf6e, 0xdf68, + 0xdf6d, 0xdf77, 0xdf6a, 0xdfce, 0xdfec, 0xe069, + /* 0x73 */ + 0xe068, 0xe0a6, 0xe0a9, 0xe0aa, 0xe100, 0xe10d, 0xe0f8, 0xe0fc, + 0xe10a, 0xe0f7, 0xe101, 0xe1b6, 0xe1bb, 0xe1b7, 0xe1b9, 0xe1ca, + 0x3f69, 0x4125, 0x4c59, 0x5007, 0x5009, 0x5422, 0x5607, 0x5604, + 0x6e0f, 0x57f8, 0x5ac7, 0x5ad1, 0x5c7e, 0x5e08, 0x5f4a, 0xe298, + 0x5fb9, 0x6988, 0x6991, 0x6984, 0x6973, 0x6989, 0x6985, 0x6b33, + 0x6e13, 0x731d, 0x731f, 0x731c, 0x7320, 0x731a, 0x731b, 0x7439, + 0x74af, 0x75e5, 0x773c, 0x7c37, 0x7c3a, 0x7fbb, 0x0a0e, 0x8210, + 0x820d, 0x86af, 0x8711, 0x0bd8, 0x8a0d, 0x8a0c, 0x8a0b, 0x8bd4, + 0x8e3d, 0x8e3e, 0x8e3b, 0x8e43, 0x8e40, 0x8e46, 0x8f11, 0x90dd, + 0x90df, 0x90ea, 0x924a, 0x9406, 0x98c1, 0x98b9, 0x98c6, 0x98b8, + 0x98bb, 0x98c8, 0x98c5, 0x98bf, 0x98c7, 0x98c4, 0x9a65, 0x9a67, + 0x9cd7, 0x9cdb, 0x9cd4, 0x9cd6, 0x9ee8, 0xa10a, + /* 0x74 */ + 0xa5bd, 0xa5be, 0xac1a, 0xac0d, 0xac0f, 0xac1b, 0xac10, 0xac11, + 0xac13, 0xad18, 0xb020, 0xb01f, 0xb023, 0xb01d, 0xb037, 0xb025, + 0xb024, 0xb02a, 0xb027, 0xb033, 0xb028, 0xb034, 0xb2ba, 0x2e70, + 0xb39d, 0xb44c, 0xb65c, 0xb66a, 0xb65d, 0xb665, 0xb663, 0xb65e, + 0xb719, 0xb797, 0xb93f, 0xb933, 0xb932, 0xbaa1, 0xbaa5, 0xbaa4, + 0xbaa2, 0xbcc1, 0x142c, 0xbcc7, 0xbcc4, 0xbcc6, 0xbcc5, 0xbcd4, + 0xbcca, 0xc153, 0xc3f1, 0xc421, 0x156e, 0xc6b7, 0xc692, 0xc8d4, + 0xca44, 0xcc98, 0xcc9b, 0xcc91, 0xcc95, 0xcc9a, 0xcc92, 0xce53, + 0xce57, 0x1686, 0xce5c, 0xce5d, 0xce64, 0xceea, 0xceed, 0xcf42, + 0xcf43, 0xd064, 0xd061, 0xd060, 0xd17d, 0xd2d4, 0xd2d5, 0xd2d9, + 0xd487, 0xd499, 0xd48c, 0xd48a, 0xd48f, 0x17b3, 0xd48b, 0xd482, + 0xd49b, 0x17eb, 0xd6c8, 0xd6c4, 0xd6cc, 0xd6c7, + /* 0x75 */ + 0xd6c3, 0xd6c6, 0xd6cb, 0xd6ca, 0xd6c9, 0xd6cd, 0xd753, 0xd821, + 0xd829, 0xd81d, 0xd824, 0xd828, 0x3743, 0xd9b1, 0xd9b2, 0xd9b5, + 0xd9d6, 0xd9af, 0xd9ca, 0xd9b8, 0xe412, 0xe411, 0xdc45, 0xdc47, + 0xdc34, 0xdc6e, 0xdc42, 0xdc31, 0xdc2e, 0xdc56, 0xdc38, 0xdc37, + 0xdc4b, 0xdc2d, 0xdc33, 0xdc36, 0x38e0, 0xdc48, 0xdddc, 0x1942, + 0xde66, 0xde6d, 0xde63, 0xde64, 0x1941, 0xde67, 0xded9, 0xdf0b, + 0xdf7e, 0xdf8b, 0xe026, 0xe02c, 0xe029, 0xe06f, 0xe06b, 0xe06d, + 0xe06e, 0xe11c, 0xe111, 0xe110, 0xe124, 0xe112, 0xe115, 0xe117, + 0x19ac, 0x3f6f, 0x40ab, 0x432e, 0x43c9, 0x4696, 0x4c85, 0x51a0, + 0x542b, 0x5e0d, 0x6b36, 0x3afd, 0x072f, 0x072e, 0x6eb1, 0x734a, + 0x7337, 0x733c, 0x7338, 0x733a, 0x733e, 0x7349, 0x084d, 0x087b, + 0x7580, 0x757f, 0x75e3, 0x773f, 0x7c52, 0x7c4e, + /* 0x76 */ + 0x7c4a, 0x7c4b, 0x7fd5, 0x85d8, 0x8620, 0x86b3, 0x86b1, 0x86b0, + 0x8a17, 0x8bd9, 0x8e49, 0x8f13, 0x90ed, 0x90eb, 0x90ee, 0x940a, + 0x940b, 0x954a, 0x98d5, 0x98d7, 0x98de, 0x98dc, 0x98ee, 0x9a70, + 0x0eb2, 0x9cd9, 0x9ed7, 0xa3cb, 0xa3c7, 0xa4fc, 0xac3b, 0xac39, + 0xac4b, 0xac43, 0xac40, 0xac46, 0xb04d, 0xb043, 0xb047, 0xb04b, + 0xb055, 0xb052, 0xb65f, 0x1322, 0xb67c, 0xb67b, 0xbaa8, 0xbaa9, + 0xbcde, 0xbcd7, 0xbcdd, 0xbcd6, 0xbcd8, 0xbd9b, 0xbee0, 0xbee8, + 0xbee6, 0xc3f8, 0xc3fb, 0xc6bb, 0x3259, 0xc6b8, 0x1570, 0xc7c1, + 0xc7c0, 0xcca4, 0xccab, 0xcd4d, 0xce65, 0xce67, 0xce6a, 0xce66, + 0xce69, 0xd073, 0xd080, 0xd06f, 0xd071, 0xd2e4, 0xd2e6, 0xd2e7, + 0xd4a0, 0xd4a4, 0xd5a2, 0xd5a7, 0xd5a4, 0xd6de, 0xd6db, 0xd758, + 0xd75c, 0xd82f, 0xd82e, 0xd9dd, 0xd9e4, 0xd9d8, + /* 0x77 */ + 0xd9e7, 0xd9da, 0xd975, 0x1895, 0xdc79, 0xdc80, 0xdc7f, 0xdc7c, + 0xdc75, 0xdc7b, 0xdc82, 0x1900, 0xdc89, 0xdc74, 0xdc7d, 0xdc7a, + 0xdc86, 0xdca8, 0xdc72, 0x1902, 0xdc8b, 0xdc91, 0xdcb3, 0xdc81, + 0xdd82, 0xdde1, 0xdde3, 0xdde2, 0xde76, 0xde74, 0xde72, 0xde75, + 0xdf0e, 0xdf0d, 0xdf94, 0xdf92, 0xdf93, 0xdf91, 0xdf8f, 0xdf95, + 0xdfd0, 0xdff7, 0xe076, 0xe0af, 0x199f, 0xe126, 0xe125, 0xe12d, + 0xe1a0, 0xe1c3, 0x3fd7, 0x45cc, 0x4c79, 0x4c7a, 0x5015, 0x5adb, + 0x5c85, 0x6470, 0x647b, 0x69a5, 0x699f, 0x6e17, 0x6eb2, 0x7339, + 0x7340, 0x734e, 0x743e, 0x75e8, 0x75e7, 0x7c66, 0x7c61, 0x7fda, + 0x8214, 0x83df, 0x8a18, 0x8b39, 0x8b3a, 0x9230, 0x9232, 0x940e, + 0x954c, 0x98e8, 0x98f1, 0x98eb, 0x98ec, 0x9a74, 0x9a73, 0x9cf1, + 0x9e42, 0x9e3e, 0x9e41, 0xa02c, 0xa3d2, 0xa4bb, + /* 0x78 */ + 0xac58, 0xac57, 0xac56, 0xac5a, 0x117d, 0xb061, 0xb068, 0xb065, + 0xb05f, 0xb064, 0xb05e, 0xb05b, 0xb067, 0xb2c3, 0xb3a2, 0xb453, + 0xb67d, 0xb720, 0xbaae, 0xbaaf, 0xbab0, 0xbce7, 0xbce6, 0xbce9, + 0xbef1, 0xbeeb, 0xbeea, 0xbee9, 0xc163, 0xc402, 0xc3fe, 0xc6de, + 0xc7c2, 0xc8e6, 0xca5d, 0xccad, 0xce75, 0xce72, 0xce77, 0x16f6, + 0xd151, 0xd2e8, 0xd2ed, 0xd2ee, 0xd4b9, 0xd4a1, 0xd4b6, 0xd5ae, + 0xd6e8, 0x1812, 0xd71e, 0xd831, 0xd832, 0x1891, 0xda0e, 0xda12, + 0xda09, 0xda05, 0x1890, 0xda03, 0xda1f, 0xda0d, 0xda0c, 0xda04, + 0xda0a, 0xdcc2, 0xdcbf, 0xdcc9, 0xdcb2, 0xdcc1, 0xdcaf, 0xdcb4, + 0xdcb0, 0xdcb6, 0xdcb7, 0xdcbb, 0xdcb1, 0xddf0, 0xde78, 0xde7a, + 0xde79, 0xdee4, 0xdee6, 0xdf9f, 0xdf9d, 0xdf98, 0xdf99, 0xdff9, + 0xe030, 0xe082, 0xe081, 0xe0b3, 0xe07f, 0xe13a, + /* 0x79 */ + 0xe13e, 0xe148, 0x4c86, 0x5436, 0x5613, 0x5722, 0x5add, 0x60a7, + 0x647d, 0x0679, 0x6e1c, 0x7365, 0x7360, 0x7367, 0x084e, 0x761a, + 0x85e3, 0x9234, 0x9418, 0x9552, 0x98fc, 0x9a79, 0x9a78, 0x9a76, + 0x9cfa, 0x9cf8, 0xa02d, 0xa3d6, 0xa4bd, 0xa4bf, 0xa4be, 0xac44, + 0xac70, 0xac62, 0xac6e, 0xb06e, 0xb07c, 0xb074, 0xb078, 0xb070, + 0xb079, 0xb071, 0xb2cc, 0xb3a7, 0xb3a6, 0xb693, 0xb721, 0xb79c, + 0xbd9d, 0xbef4, 0xbef3, 0xc8f0, 0xccb8, 0xccb6, 0xccbd, 0xce73, + 0xce82, 0xd087, 0xd156, 0xd159, 0xd2f6, 0xd4c9, 0xd4c5, 0xd4c7, + 0xd4ca, 0xd4c2, 0xd4c4, 0xd6f2, 0xd6f0, 0xd83b, 0xd83a, 0xda26, + 0xda28, 0xda34, 0xda2d, 0xdcd7, 0xdcd2, 0xdcd6, 0xdcdc, 0xdcd3, + 0xdcd1, 0xdd86, 0x191e, 0xddef, 0xddee, 0xdee8, 0xdfac, 0xdfa9, + 0xdfaa, 0xdfab, 0xdffb, 0xe033, 0xe088, 0xe0b6, + /* 0x7a */ + 0xe0b7, 0xe0d0, 0xe0cf, 0xe14f, 0xe159, 0xe14c, 0x5618, 0x5ae0, + 0x7369, 0x7c73, 0x7c72, 0x85e8, 0x90fb, 0x941c, 0x9909, 0x990a, + 0x9908, 0x9a7d, 0x9a7f, 0x9d67, 0xac7a, 0xac7b, 0xb2d1, 0xe3cb, + 0xb69d, 0xb79d, 0xbcfc, 0xbcfb, 0xbcfd, 0xbef5, 0xbef6, 0xc70f, + 0xc71d, 0xccc7, 0xccc1, 0xccbf, 0xcd54, 0xce7f, 0xcef5, 0xd08a, + 0xd08c, 0xd15c, 0xd365, 0xd4cf, 0xd4d0, 0xd5b8, 0xd6fa, 0xd766, + 0xda40, 0xda41, 0x3772, 0xdcf7, 0xdcf3, 0xdcef, 0xdcf4, 0xdced, + 0xdcf2, 0xdcf1, 0xdcf9, 0xdfb4, 0xdffc, 0xe0bc, 0xe15e, 0xe15b, + 0xe15f, 0xe15d, 0xe1cf, 0xe1ce, 0x543a, 0x5ae1, 0x5e15, 0x5e14, + 0x7c78, 0x7c79, 0x7fe6, 0x86b8, 0x8a22, 0x90fe, 0xa3db, 0xa506, + 0xa5c8, 0xac89, 0xb086, 0xb3ad, 0xb699, 0xb6d8, 0xb723, 0xb823, + 0xbab5, 0xbef9, 0xc407, 0xc71e, 0xc8fb, 0xca72, + /* 0x7b */ + 0xca73, 0xce87, 0xcf49, 0xd15d, 0xd2f8, 0xd703, 0xda4e, 0xda4d, + 0xda50, 0xda55, 0xdd09, 0xdd07, 0xdd0c, 0xdd03, 0xdd06, 0xdd0b, + 0xdd0a, 0xdd89, 0xdfbb, 0xdfff, 0xe036, 0xe08b, 0xe166, 0xe169, + 0xe167, 0xe1c2, 0xe1d2, 0x5ae2, 0x0428, 0x6488, 0x6e5b, 0x7376, + 0x7c7d, 0x80a6, 0x8e5a, 0x9917, 0xa3dc, 0xac8f, 0xb094, 0xb095, + 0xbab6, 0xbd04, 0xc2ee, 0xce8a, 0xcef9, 0xd707, 0xd71f, 0xd72a, + 0xd845, 0xda5c, 0xda5b, 0xda61, 0xda5d, 0xdd18, 0xdd1f, 0xde83, + 0xdf16, 0xdf14, 0xdfbf, 0xdfc0, 0xe173, 0xe1c0, 0x5017, 0x6489, + 0x941e, 0x941f, 0x9554, 0x9918, 0x9d05, 0xac95, 0xb098, 0xb09b, + 0xb459, 0xbd08, 0xbf01, 0xccce, 0xcefa, 0xd5be, 0xd847, 0xda6a, + 0xda69, 0xda68, 0xda67, 0xdd25, 0xdd28, 0xdfc4, 0xe037, 0xe08d, + 0xe08c, 0x1991, 0xe320, 0x9922, 0x9a82, 0xb2d9, + /* 0x7c */ + 0xc738, 0xcefb, 0xd4e1, 0xd772, 0xd848, 0xda6c, 0xda70, 0xdd31, + 0xdd30, 0xe179, 0x9923, 0xa3f8, 0xd774, 0xda73, 0xdd34, 0xde87, + 0xdeb2, 0xe0c2, 0xe17d, 0x5ae5, 0xce8c, 0xda77, 0xda75, 0xdd38, + 0xdd3a, 0xe183, 0xe181, 0x7c80, 0xac99, 0x1187, 0xcf4a, 0xd84a, + 0xdd3c, 0xe1c8, 0x9104, 0xb3af, 0xe189, 0xddfa, 0xd161, 0xdd3f, + 0xac93, 0xdfc9, 0xb2de, 0xce91, 0xe18e, 0xe18d, 0xac98, 0xa4c5, + 0xe1a5, +}; + +static const ucs4_t cns11643_5_2uni_upages[229] = { + 0x03400, 0x03500, 0x03600, 0x03700, 0x03800, 0x03900, 0x03a00, 0x03b00, + 0x03c00, 0x03d00, 0x03e00, 0x03f00, 0x04000, 0x04100, 0x04200, 0x04300, + 0x04400, 0x04500, 0x04600, 0x04700, 0x04800, 0x04900, 0x04a00, 0x04b00, + 0x04c00, 0x04d00, 0x05200, 0x05900, 0x05e00, 0x05f00, 0x06100, 0x06300, + 0x06400, 0x06b00, 0x07200, 0x07300, 0x07500, 0x07600, 0x07900, 0x07a00, + 0x07b00, 0x07c00, 0x08300, 0x08600, 0x08700, 0x08800, 0x08900, 0x08a00, + 0x08c00, 0x08e00, 0x09400, 0x09500, 0x09700, 0x09900, 0x09b00, 0x09c00, + 0x09d00, 0x09e00, 0x0ff00, 0x20000, 0x20100, 0x20200, 0x20300, 0x20400, + 0x20500, 0x20600, 0x20700, 0x20800, 0x20900, 0x20a00, 0x20b00, 0x20c00, + 0x20d00, 0x20e00, 0x20f00, 0x21000, 0x21100, 0x21200, 0x21300, 0x21400, + 0x21500, 0x21600, 0x21700, 0x21800, 0x21900, 0x21a00, 0x21b00, 0x21c00, + 0x21d00, 0x21e00, 0x21f00, 0x22000, 0x22100, 0x22200, 0x22300, 0x22400, + 0x22500, 0x22600, 0x22700, 0x22800, 0x22900, 0x22a00, 0x22b00, 0x22c00, + 0x22d00, 0x22e00, 0x22f00, 0x23000, 0x23100, 0x23200, 0x23300, 0x23400, + 0x23500, 0x23600, 0x23700, 0x23800, 0x23900, 0x23a00, 0x23b00, 0x23c00, + 0x23d00, 0x23e00, 0x23f00, 0x24000, 0x24100, 0x24200, 0x24300, 0x24400, + 0x24500, 0x24600, 0x24700, 0x24800, 0x24900, 0x24a00, 0x24b00, 0x24c00, + 0x24d00, 0x24e00, 0x24f00, 0x25000, 0x25100, 0x25200, 0x25300, 0x25400, + 0x25500, 0x25600, 0x25700, 0x25800, 0x25900, 0x25a00, 0x25b00, 0x25c00, + 0x25d00, 0x25e00, 0x25f00, 0x26000, 0x26100, 0x26200, 0x26300, 0x26400, + 0x26500, 0x26600, 0x26700, 0x26800, 0x26900, 0x26a00, 0x26b00, 0x26c00, + 0x26d00, 0x26e00, 0x26f00, 0x27000, 0x27100, 0x27200, 0x27300, 0x27400, + 0x27500, 0x27600, 0x27700, 0x27800, 0x27900, 0x27a00, 0x27b00, 0x27c00, + 0x27d00, 0x27e00, 0x27f00, 0x28000, 0x28100, 0x28200, 0x28300, 0x28400, + 0x28500, 0x28600, 0x28700, 0x28800, 0x28900, 0x28a00, 0x28b00, 0x28c00, + 0x28d00, 0x28e00, 0x28f00, 0x29000, 0x29100, 0x29200, 0x29300, 0x29400, + 0x29500, 0x29600, 0x29700, 0x29800, 0x29900, 0x29a00, 0x29b00, 0x29c00, + 0x29d00, 0x29e00, 0x29f00, 0x2a000, 0x2a100, 0x2a200, 0x2a300, 0x2a400, + 0x2a500, 0x2a600, 0x2f800, 0x2f900, 0x2fa00, +}; + +static int +cns11643_5_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x21 && c1 <= 0x7c)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + ucs4_t wc = 0xfffd; + unsigned short swc; + { + if (i < 8603) + swc = cns11643_5_2uni_page21[i], + wc = cns11643_5_2uni_upages[swc>>8] | (swc & 0xff); + } + if (wc != 0xfffd) { + *pwc = wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + diff --git a/libs/libiconv/lib/cns11643_6.h b/libs/libiconv/lib/cns11643_6.h new file mode 100644 index 00000000..84939843 --- /dev/null +++ b/libs/libiconv/lib/cns11643_6.h @@ -0,0 +1,968 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CNS 11643-1992 plane 6 + */ + +static const unsigned short cns11643_6_2uni_page21[6388] = { + /* 0x21 */ + 0xc902, 0x3362, 0x0005, 0x3388, 0x33d0, 0x33cf, 0x341e, 0x341f, + 0x3420, 0x3c0e, 0x3c2c, 0x3361, 0x3304, 0x3305, 0x3303, 0x0004, + 0xc901, 0x337d, 0x338d, 0x34a3, 0x34a4, 0x37db, 0x3800, 0xc91e, + 0x39a3, 0x3b32, 0x013f, 0x3dd4, 0x3dd5, 0x4e23, 0x552c, 0x557a, + 0x3803, 0x3307, 0x3308, 0x338f, 0x339c, 0x33d5, 0x3412, 0x3413, + 0x3414, 0x3421, 0x34a8, 0x34a6, 0x3776, 0x3801, 0x383d, 0xc914, + 0x383e, 0x3929, 0x3977, 0x3978, 0x39a6, 0x39a9, 0x39ac, 0x3b34, + 0x3804, 0x3c7b, 0x3d10, 0x392f, 0x3dd7, 0x3e1c, 0x3e1f, 0x3e1a, + 0xc936, 0x3e1e, 0x3e9e, 0x3e9a, 0x43a0, 0x43a1, 0x47d2, 0x47d3, + 0x4bb9, 0x4d1d, 0x4d55, 0x4eff, 0x51e7, 0x042a, 0x5211, 0x5213, + 0x5212, 0x53af, 0x53b1, 0xc990, 0x552d, 0x557b, 0x559d, 0x559a, + 0x04a7, 0x559f, 0x55a0, 0x559c, 0x56bd, 0x04fa, + /* 0x22 */ + 0x57aa, 0x626c, 0x6291, 0x6d74, 0x756a, 0xca29, 0x8605, 0x8f6b, + 0x8f6a, 0x33e0, 0x3312, 0x0000, 0x337f, 0x33a0, 0x3399, 0x3395, + 0x339e, 0x33df, 0x33de, 0x34af, 0x34ad, 0x34b0, 0x37df, 0x3843, + 0x3841, 0x3848, 0x3875, 0xc91a, 0x3932, 0x397b, 0x3979, 0x39b3, + 0x00db, 0x3ea7, 0x39b2, 0x39b0, 0x39b4, 0xc929, 0x3bcd, 0x3bce, + 0xc92b, 0x3c10, 0x3c80, 0x3cd3, 0x3d30, 0x3398, 0x3d2f, 0x3d31, + 0x3dda, 0x3dd9, 0x3e27, 0x3e28, 0x3e21, 0x3e25, 0x3ea6, 0x3ea2, + 0x3ea1, 0x3ea4, 0xc939, 0x3eaa, 0x3ea5, 0x3ea3, 0x3364, 0x443f, + 0x4444, 0x471b, 0x4753, 0x4784, 0x4786, 0x47d5, 0xc960, 0x4b3e, + 0x4b40, 0x4dca, 0x4dc9, 0x4e26, 0x4f00, 0x4f31, 0x4f3c, 0x4f30, + 0x4f33, 0x4f32, 0x4f38, 0x5234, 0x5253, 0x5254, 0x53b4, 0x53b2, + 0x552f, 0x55a5, 0x55a7, 0x55a4, 0x55a8, 0x55a9, + /* 0x23 */ + 0x55a2, 0x55a3, 0x55a6, 0x5681, 0x5680, 0x57ad, 0x5c24, 0x5c65, + 0x5c68, 0x5c69, 0x633c, 0x633b, 0x655d, 0x6a44, 0x7182, 0x74f1, + 0x756b, 0x771b, 0x78eb, 0x7bba, 0x7bd3, 0x7d13, 0x8922, 0x97f4, + 0xab0f, 0xab10, 0x3807, 0xc10b, 0xc10a, 0x3319, 0x331a, 0x3318, + 0x3366, 0x3382, 0x33a8, 0x33e5, 0x33e7, 0x33e4, 0x3415, 0x3423, + 0x3424, 0x3443, 0x34c3, 0x34bc, 0x34bb, 0x0038, 0x34b7, 0x34b9, + 0x34cf, 0xc90d, 0x377a, 0x377b, 0x37e1, 0x37e0, 0x3809, 0x384d, + 0xc916, 0x384b, 0x3879, 0x38b1, 0x3936, 0x3935, 0x3937, 0x3938, + 0x397f, 0x3980, 0x3981, 0x9653, 0x397e, 0x39cd, 0x39bf, 0x39be, + 0x39c2, 0x39b8, 0x39c1, 0x2030, 0x3c31, 0x3c2f, 0x3c6f, 0x3c82, + 0x013a, 0x3c87, 0x3c86, 0x3c8d, 0x3c94, 0x3cd7, 0x3cd4, 0x3cd8, + 0x3d16, 0x3d14, 0x3d2e, 0x3d36, 0x3d37, 0x51ee, + /* 0x24 */ + 0x3de0, 0x3de5, 0x3ddf, 0x3e2b, 0x3e29, 0x3e2d, 0x3e2f, 0x3eb7, + 0x3ec9, 0x3ec1, 0x3eca, 0x3eb2, 0x3eac, 0x3eae, 0x43b2, 0x43a8, + 0x43b0, 0x43a7, 0xc951, 0x4452, 0x444a, 0x4756, 0x4755, 0x475f, + 0x475e, 0x4788, 0xc95d, 0x47dd, 0x47e2, 0x47e1, 0x47df, 0x47e0, + 0x48af, 0x48b1, 0x48ba, 0x4b45, 0x4b43, 0x4bbd, 0x4bc8, 0xc96c, + 0x4bbe, 0x4bbf, 0xc974, 0x4d59, 0x4e29, 0x4e2c, 0x4e2f, 0x4e2d, + 0x4e2e, 0x4f04, 0x4f02, 0x4f01, 0x4f40, 0x4f4a, 0x4f3f, 0x4f4f, + 0x4f41, 0x4f4e, 0x51eb, 0x51ec, 0x33ac, 0x525b, 0x5263, 0x525a, + 0x5259, 0x53dc, 0x53db, 0x53d9, 0x53e0, 0x53dd, 0x3320, 0x55b0, + 0x55b1, 0x55b2, 0x55b6, 0x5651, 0x5652, 0x5650, 0x5684, 0x04c9, + 0x5683, 0x57c3, 0x57b8, 0x57b9, 0x57b2, 0x5b90, 0x5c26, 0x5c29, + 0x5c6e, 0x6340, 0x633e, 0x6341, 0x655e, 0x65bb, + /* 0x25 */ + 0x65bc, 0x65b9, 0xc9ef, 0x6980, 0x084f, 0x6a45, 0x6aba, 0x6abd, + 0x6d56, 0x6d55, 0x6d75, 0x6d77, 0x6d81, 0xc9fa, 0x6d83, 0x6d8b, + 0x6d84, 0x7186, 0x7183, 0x718b, 0x756d, 0x7616, 0x7728, 0x78ea, + 0x7bd4, 0x7c03, 0x7d15, 0x7f3d, 0x7f3e, 0x8416, 0xca4c, 0x8606, + 0x874d, 0x8f22, 0x8f73, 0x8f6d, 0x8f6e, 0x91b1, 0x384e, 0x932d, + 0x0fcd, 0x95f9, 0x9652, 0x9800, 0x97fc, 0x97fa, 0x1092, 0x97f7, + 0x97f8, 0xca90, 0xcac4, 0xa627, 0xab11, 0x33ae, 0xad50, 0xad4f, + 0xad4d, 0xaf71, 0xcae2, 0xaf72, 0xb518, 0x3d44, 0x3321, 0x3367, + 0x33af, 0x33b0, 0x3329, 0x3417, 0x3422, 0xc903, 0x3325, 0x3428, + 0x34ff, 0x34d9, 0x34db, 0x34de, 0x34f2, 0x34fe, 0x34f4, 0x34dd, + 0x0045, 0xc904, 0x3501, 0x34dc, 0x377d, 0x3781, 0x377e, 0x377f, + 0x37e5, 0x380f, 0x00b5, 0x380a, 0x00b6, 0x380b, + /* 0x26 */ + 0x3851, 0x3852, 0x3850, 0x38b8, 0x393d, 0x393e, 0x393c, 0x3987, + 0x39d7, 0x39db, 0x39cf, 0x39e0, 0x3b4c, 0x3b42, 0x3bd4, 0x3c11, + 0x3c14, 0x3c15, 0x3c12, 0x3c33, 0x3c35, 0x0137, 0x3c71, 0x0130, + 0x3c91, 0x3c93, 0x3c95, 0x3cdc, 0x3d42, 0x3d40, 0x83a6, 0x3de6, + 0x448f, 0x3e32, 0xc937, 0x3e31, 0x3ef5, 0x3ecd, 0x3ede, 0x3ed5, + 0x3eda, 0x3eee, 0x3eec, 0x3ecf, 0x3ece, 0xc93d, 0x3ecc, 0x3ef3, + 0x43c1, 0x43c4, 0x43c6, 0x43b4, 0x43c3, 0x43b8, 0x43bb, 0x43b7, + 0x43bc, 0x43bf, 0x43c7, 0x43be, 0x4460, 0x445d, 0x4476, 0x446c, + 0x4475, 0x445b, 0x4471, 0x4473, 0x4461, 0x445a, 0x4462, 0x4472, + 0x445f, 0x4458, 0x471e, 0x4758, 0x478b, 0x478a, 0x47f4, 0x47f0, + 0x48d2, 0x48cd, 0x48ce, 0x48bc, 0x48d0, 0x4b46, 0x4b47, 0x033e, + 0x034d, 0x0351, 0x4bce, 0x4bcf, 0x4bcc, 0x4bcb, + /* 0x27 */ + 0xc972, 0x4d60, 0x4d5f, 0x4d5d, 0x4dd4, 0x4e3a, 0x4e38, 0x4e3c, + 0x4e36, 0x4f08, 0x4f7e, 0x4f5e, 0x4f6e, 0x4f53, 0x4f70, 0x4f57, + 0x4f5d, 0x4f63, 0x4f7a, 0x4f79, 0x4f93, 0xc981, 0x521d, 0x5268, + 0x5273, 0x5274, 0x5266, 0x526f, 0x5275, 0x527a, 0x5270, 0x526d, + 0x5265, 0x538a, 0x53ed, 0x53e9, 0x53e3, 0x53ef, 0x0473, 0x53ea, + 0x5531, 0xc991, 0x5538, 0x9820, 0x5535, 0x553a, 0x5581, 0x5580, + 0x55b8, 0x55c1, 0x55ba, 0x5688, 0x56cf, 0x56ca, 0x56c7, 0x56c5, + 0x56c8, 0x56d0, 0x56c9, 0x57bb, 0x57b6, 0x57bd, 0xc99d, 0x57b4, + 0x57c1, 0x57d1, 0x57d2, 0x57cc, 0x57d4, 0x57cb, 0x57ce, 0x57d5, + 0x57d8, 0x5b95, 0x5b93, 0x5b99, 0x5b96, 0x05be, 0x5c89, 0x5c94, + 0x5c91, 0x5c8f, 0x5c84, 0x5c97, 0x5c86, 0x5c85, 0x5c8c, 0x60f2, + 0x60ed, 0x60ef, 0x62d9, 0x6346, 0x6347, 0x634b, + /* 0x28 */ + 0x6350, 0x634a, 0x634e, 0x634c, 0x6348, 0x6563, 0x6561, 0x6562, + 0x6560, 0x65c3, 0x65c5, 0x65c1, 0x65d0, 0xc9dc, 0x6982, 0x081e, + 0x6986, 0x6984, 0x6a4c, 0x6a48, 0x6ab8, 0x6abf, 0x6ac1, 0x6ac6, + 0x6ac5, 0x6ac7, 0x6ac0, 0x6ac3, 0x6bed, 0x6c03, 0x6c22, 0x6c21, + 0x6d9f, 0x6d90, 0x6d9e, 0x08c8, 0x6da0, 0x6d94, 0x6d95, 0x6da1, + 0x08c3, 0x08c7, 0x719a, 0x7190, 0x74f2, 0x74f3, 0x756e, 0x75ab, + 0x75a9, 0x761a, 0x7618, 0x761b, 0x7760, 0x774c, 0x7742, 0x7733, + 0x773f, 0x773e, 0x7738, 0x7743, 0x7746, 0x7736, 0x78ee, 0x78f5, + 0x78f4, 0x0b56, 0x7c1b, 0x0140, 0x7d2b, 0x7d29, 0x7d2a, 0x7d2e, + 0x803f, 0x80e6, 0x83a7, 0x83a8, 0x8418, 0x8608, 0x8750, 0x8753, + 0x8a56, 0x8a55, 0x8f6f, 0x8f7f, 0x91b3, 0x933a, 0x9338, 0x9337, + 0x9336, 0x3854, 0xca80, 0x95dd, 0x95fc, 0x95fa, + /* 0x29 */ + 0x9633, 0x9804, 0x9807, 0x9808, 0x9806, 0x9809, 0xca91, 0xca93, + 0x9d1e, 0xcad2, 0xad0b, 0xad43, 0xad52, 0xad58, 0xad5e, 0xaf68, + 0xaf8d, 0xaf82, 0xaf7b, 0xb358, 0x15bd, 0xc900, 0x332c, 0x332e, + 0x480b, 0x332d, 0x3369, 0x33b2, 0x33b6, 0x33a9, 0x33ed, 0x3419, + 0x344f, 0x3516, 0x3503, 0x350e, 0x3504, 0x3507, 0x3510, 0x3527, + 0x3528, 0x350d, 0x3529, 0x350f, 0x3522, 0x3511, 0x3785, 0x3784, + 0x3783, 0x378a, 0x3786, 0x3810, 0x3858, 0x385a, 0x3a0c, 0x38c4, + 0x38c5, 0x3947, 0x3949, 0x394a, 0x394b, 0x53bb, 0x398d, 0x398b, + 0x3a07, 0x3a06, 0xc920, 0x39ef, 0x39f0, 0x39ed, 0x39f9, 0x3a02, + 0x39e7, 0x39f4, 0x39f7, 0x39f1, 0x3b53, 0x3b55, 0x011a, 0x3bda, + 0x3bd9, 0x012c, 0x3c38, 0x3c99, 0x3ca2, 0x3c9c, 0x3c9a, 0x3c9b, + 0x3ce5, 0x3ce3, 0x3ce1, 0x3ce0, 0x3ce2, 0x3ce4, + /* 0x2a */ + 0x32fd, 0x3ce8, 0xc92f, 0x3d13, 0x3d56, 0x3d4b, 0x3d4a, 0x3d4d, + 0x3d4c, 0x0149, 0x3dea, 0x3de9, 0x3deb, 0x3dec, 0x3e3a, 0x3e3c, + 0x3e39, 0x3e3b, 0x3f14, 0x3f0e, 0x3f35, 0x3f0a, 0x3f3f, 0x3f38, + 0x017c, 0x3f4e, 0x3f17, 0xc93f, 0x3f1e, 0x43b6, 0x43ce, 0x43ca, + 0x43cb, 0x43cc, 0x43c9, 0x44b4, 0x44ac, 0x4488, 0x4486, 0x448c, + 0x4493, 0x448a, 0x44a4, 0x4487, 0x44a5, 0x44a6, 0x4485, 0x44a3, + 0x448e, 0x471f, 0x4763, 0x478d, 0x47fa, 0x47fb, 0x4809, 0x47fe, + 0x47ff, 0x4802, 0x4804, 0x47fd, 0x4805, 0x48f9, 0x48f7, 0x48db, + 0x48da, 0x4b51, 0x4b50, 0x4b57, 0x4be2, 0x4bd8, 0x4bda, 0x4bdc, + 0x4d20, 0x4d1f, 0x4d69, 0x4ddd, 0x4e40, 0x4e41, 0x4e43, 0x4f0d, + 0x4f0c, 0x4f87, 0x4fa9, 0x4f92, 0x4f85, 0x03bf, 0x4f8c, 0x4fa2, + 0x4f8f, 0x4f8a, 0x03ba, 0x4f8d, 0x51f1, 0x5237, + /* 0x2b */ + 0x528b, 0x5287, 0x5282, 0x538e, 0x53bc, 0x53f8, 0x53fa, 0x53eb, + 0x53f9, 0x53fc, 0x5405, 0x551b, 0x551d, 0x551e, 0xc992, 0x553c, + 0x553e, 0x5584, 0x55c8, 0x55c9, 0x55d3, 0x55c7, 0x55d2, 0x5655, + 0xc996, 0x568c, 0x568a, 0x56d5, 0x56d3, 0x04d8, 0x56d8, 0x57d0, + 0x57ee, 0x57f1, 0x57fb, 0x57d3, 0x57ec, 0x57cd, 0x5815, 0x5826, + 0x580e, 0x5827, 0x582a, 0x5800, 0x5804, 0x5828, 0x5808, 0x5814, + 0x5b9b, 0x05b2, 0x5ba1, 0x5b9d, 0x5ba0, 0x5b9e, 0x5ba2, 0x5b9c, + 0x5c32, 0x5c34, 0x5c93, 0x5c96, 0x5c90, 0x5cb4, 0x5cb5, 0xc9b6, + 0x5cb6, 0x5cc2, 0xc9b5, 0x5cba, 0x5c92, 0x60fb, 0x6105, 0x60f3, + 0x60fe, 0x60fd, 0x755d, 0x60fa, 0x6243, 0x6295, 0x6294, 0x06c4, + 0x636f, 0x6373, 0x635c, 0x635b, 0x6366, 0x6374, 0x6363, 0x6367, + 0x6360, 0x6362, 0x6371, 0x6372, 0x635e, 0x6523, + /* 0x2c */ + 0x6526, 0x6564, 0xc9d6, 0x65f2, 0x6601, 0x65dd, 0x65dc, 0x65db, + 0x65f3, 0x65fd, 0x65d8, 0x65f8, 0x65fb, 0x6983, 0x698c, 0x698e, + 0x6a49, 0x6a54, 0x6a52, 0x6a4e, 0x6a58, 0x6a51, 0x6a55, 0x6a53, + 0x6a57, 0x6a50, 0x6a4f, 0x6a4d, 0x6ad2, 0x6ad3, 0x6ac9, 0x6ad4, + 0x6bef, 0xc9f8, 0x33b1, 0x6c05, 0x6c04, 0x6c2e, 0x6c2d, 0x6d45, + 0x6d5b, 0x6d5a, 0x6d59, 0x6d9d, 0x6d8e, 0x6dbc, 0x6ddd, 0x6dba, + 0xc9fd, 0x6dd8, 0x6dcb, 0x6dd9, 0x6dda, 0x6dc4, 0x6db8, 0x6dbf, + 0x6ddb, 0x6dc1, 0xc9fc, 0x6dc5, 0xca19, 0x71b1, 0x71af, 0xca18, + 0x74f7, 0x74f6, 0x74f8, 0x7550, 0x7551, 0x7571, 0x7570, 0x75b0, + 0x75af, 0x75ae, 0x75ad, 0x7625, 0x762c, 0x7622, 0x7633, 0x7634, + 0x0a2b, 0x773a, 0x7740, 0x7768, 0x0a61, 0x7764, 0x775c, 0x7757, + 0x7753, 0x774f, 0x7751, 0x7754, 0x7766, 0x23dd, + /* 0x2d */ + 0x0ab2, 0x790d, 0x7908, 0xca2b, 0x78fa, 0x7aea, 0x7b2a, 0x7bbb, + 0x7bd5, 0x7bd7, 0x4fa4, 0x33f0, 0x33b5, 0x7c06, 0x7c28, 0x7c22, + 0x7c21, 0x5656, 0x7c23, 0x43cd, 0x7d30, 0x7d34, 0x7fc9, 0x7fca, + 0x7fc8, 0xca3d, 0x8044, 0x80f3, 0xca41, 0x80f8, 0x80fc, 0x80f6, + 0x80fb, 0x80f7, 0x8100, 0x8102, 0xca40, 0xca4d, 0x8424, 0x860d, + 0x0d29, 0x8762, 0x8930, 0x892b, 0x892a, 0x0d92, 0x892d, 0x8ada, + 0x8c28, 0x8d86, 0x8f77, 0x8f7c, 0x9050, 0x904e, 0x90f2, 0x91b2, + 0x91ce, 0x91cf, 0x91e5, 0x6607, 0x9235, 0x9231, 0x9313, 0x932b, + 0x932c, 0x9345, 0x9360, 0x9341, 0x9358, 0x9347, 0x935b, 0x9350, + 0xca82, 0x935f, 0x934a, 0x9356, 0x9343, 0x9344, 0x9351, 0x95fd, + 0x9634, 0x9635, 0x9654, 0x9655, 0x970c, 0x970b, 0x970a, 0x97f9, + 0x9835, 0x9824, 0x9813, 0x981c, 0x9869, 0x9825, + /* 0x2e */ + 0x9821, 0xca95, 0xca96, 0xca98, 0x9d20, 0x9fa9, 0x9fa8, 0x9fde, + 0xa009, 0xa00a, 0xa00b, 0xa1e3, 0xa207, 0xa2b2, 0xa2b3, 0xa35d, + 0xa858, 0xa886, 0xa887, 0xa9b9, 0xa9b8, 0xad0c, 0xad44, 0xad66, + 0xad80, 0xad75, 0xad6d, 0xad7e, 0xad67, 0xad81, 0xad77, 0xafa8, + 0xafa2, 0xafa5, 0xaf9b, 0xb357, 0xb50f, 0xb532, 0xb52c, 0xb533, + 0xb8e7, 0x336e, 0x33b7, 0x33f6, 0x33f2, 0x33f3, 0x3817, 0x3430, + 0x3454, 0x3453, 0x3552, 0x353d, 0x353c, 0x3534, 0x3533, 0x3554, + 0x352f, 0x0058, 0x3555, 0x353f, 0x3537, 0x3556, 0x3561, 0x3558, + 0xc906, 0x353b, 0x3532, 0x352e, 0x353e, 0x333b, 0x378c, 0x378d, + 0x3813, 0x3816, 0x3812, 0x385b, 0x388a, 0x38d7, 0x38ce, 0x3950, + 0x3951, 0x394f, 0x398e, 0x398f, 0x39f2, 0xc921, 0x3a28, 0x3a1a, + 0x3a25, 0x3a1d, 0x3a14, 0x3a20, 0x3a1f, 0x3a1b, + /* 0x2f */ + 0x3a17, 0x3a15, 0x3a1c, 0x3a13, 0xc925, 0x3b60, 0x011c, 0x3b66, + 0x3be3, 0x3bde, 0x3be0, 0x3be1, 0x3c1a, 0x3c1b, 0x3c18, 0x3c1c, + 0x3c19, 0x3c42, 0x3c40, 0x3c3e, 0x3c44, 0x3c74, 0x3c43, 0xc92d, + 0x3cf2, 0x3d1b, 0x3d19, 0x3d1e, 0xc930, 0x3d5e, 0x3d66, 0x3d5d, + 0x3d5a, 0x3d5f, 0x3d60, 0x3d5b, 0x3d5c, 0x3d59, 0x3df0, 0x3df1, + 0x3e43, 0x3e40, 0x3e42, 0x3e41, 0x3e3f, 0x3f57, 0x3f69, 0x3f6f, + 0x3fab, 0x3f71, 0x3f93, 0x3f56, 0x3f90, 0x3f6d, 0x3f6c, 0x3f70, + 0x3f66, 0x3f67, 0x43d7, 0x43b5, 0x43db, 0x43d8, 0x43d5, 0x43d4, + 0x44ba, 0x44b7, 0x44be, 0x44b9, 0x0237, 0x44e0, 0x44dd, 0x44de, + 0x7918, 0x44d8, 0x44bd, 0x44db, 0x471d, 0x4725, 0x4921, 0x490c, + 0x4929, 0x492d, 0x491b, 0x490e, 0x491f, 0x4904, 0x491c, 0x4905, + 0x4906, 0x4920, 0x490d, 0x492a, 0x4923, 0x4911, + /* 0x30 */ + 0x4b5c, 0x4b66, 0x4b5b, 0x4b4f, 0x4b5e, 0x4b5d, 0x4bf1, 0x4bea, + 0x4bf4, 0x4beb, 0x4bf0, 0x4bfa, 0x4bfb, 0x4d28, 0x4d2c, 0x4d6b, + 0x4d2a, 0x4d6a, 0x4d6f, 0x4ddb, 0x4de0, 0x7fd1, 0x4de3, 0x4de5, + 0x4de7, 0x4e4d, 0x4e55, 0x4e54, 0x4e53, 0x4e52, 0x4e4e, 0x4e60, + 0x53c0, 0x4f0f, 0x4f11, 0x4f13, 0x4fc6, 0x4fb3, 0x4fc7, 0x4fd2, + 0x4fb8, 0x4fac, 0x4fae, 0x4fcf, 0x4fc5, 0xc97b, 0x4fcc, 0x4fab, + 0x4fc9, 0x4fb9, 0x51fb, 0x51f8, 0x51f7, 0x51f9, 0x5220, 0x523b, + 0x5239, 0x529e, 0x529a, 0x52aa, 0x52ab, 0x52af, 0x5296, 0x52a9, + 0x52a6, 0x5291, 0x0443, 0x52ae, 0x529f, 0x52ac, 0x52a0, 0x5392, + 0x5391, 0x53bf, 0x5417, 0x540a, 0x540c, 0x554a, 0x5546, 0x5534, + 0x5545, 0x5543, 0x5544, 0xc993, 0x5587, 0x5586, 0x558a, 0x55da, + 0x55d8, 0x04b4, 0x3818, 0x3434, 0x55d6, 0x55d4, + /* 0x31 */ + 0x5654, 0x5659, 0x565a, 0x5657, 0x04e0, 0x56dd, 0x56e9, 0x56e0, + 0x5805, 0x5812, 0x5813, 0x5807, 0x5816, 0x5823, 0x5802, 0xc9a1, + 0x584a, 0x5836, 0x5840, 0x5856, 0x5843, 0xc9a0, 0x584b, 0x5846, + 0x583e, 0x5849, 0x5ba7, 0x5bb6, 0x5ba6, 0x5ba8, 0x5bac, 0x5ba9, + 0x5bab, 0x5c38, 0x5c37, 0x5c39, 0x5c41, 0x5c3e, 0x5cc0, 0x5cbb, + 0x5cbf, 0x5cbd, 0x5cfe, 0x5d1e, 0x5cee, 0x5cfc, 0xc9b7, 0x5cf9, + 0x5d06, 0x5ce4, 0x5ce9, 0x5ce5, 0x5d03, 0x5cfd, 0x5d49, 0x60be, + 0x610a, 0x8626, 0x6118, 0x610d, 0x610f, 0x610e, 0x6120, 0x6271, + 0x6299, 0x62e2, 0x62df, 0x62de, 0x6378, 0x6379, 0x06e4, 0x637c, + 0x637d, 0x6384, 0x638b, 0x638a, 0xc9d2, 0x6389, 0x652c, 0x6529, + 0x656c, 0x2104, 0x6609, 0x6608, 0x660c, 0x660d, 0x6610, 0x0826, + 0x699f, 0x6998, 0x69a2, 0x699a, 0x6ad5, 0x6ae2, + /* 0x32 */ + 0x6af0, 0x6aea, 0x6aeb, 0x6aed, 0x6ae8, 0x6ae0, 0x6b85, 0x6b86, + 0x6bf0, 0x5046, 0x6c45, 0x6c38, 0x6c3e, 0x6c42, 0x6c40, 0x6d47, + 0x6d5c, 0x6d5e, 0x6db4, 0x6dc2, 0x6e14, 0x6de5, 0x6e15, 0x6e11, + 0xc9ff, 0x6dee, 0x6de7, 0x6df5, 0x6df4, 0x6de8, 0x6e01, 0x6def, + 0x6df1, 0xca00, 0x71db, 0x71bf, 0x71da, 0x71c7, 0x71dd, 0xca1a, + 0x71eb, 0x71e1, 0x71c1, 0x71bd, 0x7507, 0x74fd, 0x7501, 0x750a, + 0x7503, 0x7572, 0x7574, 0x7575, 0x75b2, 0x75b1, 0x75b4, 0x764c, + 0x7642, 0x7640, 0x7649, 0x763c, 0x764d, 0x764a, 0x763b, 0x7761, + 0x7774, 0xca26, 0x777f, 0x777a, 0x7788, 0x777c, 0x0a6f, 0x7770, + 0x790f, 0x7928, 0x7913, 0x792a, 0x7aed, 0x7aef, 0x7b2e, 0x7bc1, + 0x7bdd, 0x3e47, 0x7c2d, 0x7c2b, 0x7c35, 0x7c2f, 0x7c31, 0x7c34, + 0xca35, 0x7c30, 0x7d3a, 0x7d39, 0x7d37, 0x7d4b, + /* 0x33 */ + 0x7d54, 0x7d4d, 0x7d51, 0x7d47, 0x7f27, 0x7f50, 0x7f4d, 0x7f4e, + 0x7f54, 0x7fd2, 0x7fce, 0x804b, 0x8049, 0x8105, 0x810f, 0x8119, + 0xca43, 0x8106, 0x810c, 0x8129, 0x8104, 0x8108, 0x8125, 0x0c1c, + 0x8103, 0x8127, 0x8110, 0x810a, 0xca42, 0x985d, 0x83aa, 0x83ab, + 0x83a9, 0x8441, 0x843a, 0x843c, 0x842b, 0x8449, 0x8615, 0x0d00, + 0x8616, 0xca53, 0x8631, 0x6d4a, 0x873c, 0x877c, 0x876d, 0x876a, + 0x8763, 0x876b, 0x877b, 0x8764, 0x877a, 0x8769, 0x876f, 0x8937, + 0x8935, 0x893c, 0x8936, 0x893d, 0x893e, 0x8ae1, 0x8ae0, 0x8c2d, + 0x8c2b, 0x8d8d, 0x8d92, 0x0eb6, 0x8d8e, 0xca6b, 0x8d91, 0x8d96, + 0x8f7b, 0x8f78, 0x8f81, 0x8f96, 0x8fa3, 0x8f95, 0x8f97, 0x9054, + 0x9052, 0x90f5, 0x9100, 0x90fb, 0x90f4, 0x90f6, 0x91e8, 0x91ea, + 0x933e, 0x933d, 0x933b, 0x9380, 0x0fe4, 0x9388, + /* 0x34 */ + 0x9381, 0x9382, 0x93ce, 0x9383, 0x9377, 0x9379, 0x9373, 0x936d, + 0x9370, 0x938d, 0x9375, 0x938c, 0x936a, 0x9391, 0x9389, 0x938e, + 0x44dc, 0x95ff, 0x9659, 0x96c7, 0x9712, 0x9714, 0x9713, 0x97cb, + 0x9842, 0x10ad, 0x983d, 0x2aff, 0x9840, 0x9844, 0x9862, 0x9843, + 0x983f, 0x9845, 0x983c, 0xca97, 0x9846, 0x9847, 0xcab3, 0x9c9e, + 0x9c9d, 0x9d2c, 0x9d29, 0x9d2f, 0x9d2e, 0x9d30, 0x9fe1, 0x9fe2, + 0xa00e, 0xa019, 0xa012, 0xa2b4, 0xa5da, 0xa726, 0xa859, 0xa85a, + 0xa888, 0xa9c0, 0xa9ba, 0xaba0, 0xcadd, 0xaba2, 0xad86, 0x2fec, + 0xad9d, 0xad88, 0xad8f, 0xad8e, 0xad9b, 0xafc1, 0xafc3, 0xafc4, + 0xaf96, 0xafc7, 0xafc6, 0xafbf, 0x14c3, 0xb20f, 0xb555, 0xb542, + 0xb546, 0xb54b, 0xb543, 0xb553, 0xb548, 0xb549, 0xb54a, 0xb54e, + 0x7bde, 0x3991, 0xbb4b, 0xbd80, 0xbd81, 0xbd83, + /* 0x35 */ + 0x358a, 0xbd82, 0x5542, 0x3c22, 0x3370, 0x3371, 0x33bc, 0x4f18, + 0x33be, 0x33ba, 0x33f8, 0x3437, 0x3435, 0x3dfc, 0x3456, 0x3459, + 0x345e, 0x356d, 0x3591, 0x3592, 0x3568, 0x3566, 0x3573, 0x0067, + 0x3596, 0x358b, 0x358c, 0x3796, 0x37ee, 0x381c, 0x381a, 0x3819, + 0x381b, 0x385d, 0x385e, 0xc918, 0x38dc, 0x38e2, 0x3952, 0x3992, + 0x3a30, 0x3a52, 0x3a42, 0x3a41, 0x3a45, 0x3a37, 0x3a40, 0x3a3f, + 0x3a3d, 0x3a38, 0x3a3a, 0x3a49, 0x3b6b, 0x3b78, 0x3b79, 0xc926, + 0x3b6c, 0x3be9, 0x3be6, 0x3be5, 0x3bea, 0x3be7, 0x3be8, 0x3c1f, + 0x3c4b, 0x3c4a, 0x3c53, 0x3c76, 0x3ca3, 0x3ca4, 0x3cf6, 0x3cf3, + 0x3cf9, 0x3cf7, 0x3cfc, 0x3d1d, 0x3d6d, 0x3d71, 0x3d6c, 0x3d6e, + 0x3d70, 0x3d6f, 0x3d67, 0x3d68, 0x3dfa, 0x3df9, 0x3e4e, 0x19de, + 0x3e4d, 0x3e4f, 0x3e4a, 0x3e4c, 0x0196, 0xc942, + /* 0x36 */ + 0x3fee, 0x3fb2, 0x3fc0, 0x3fc1, 0x3ff4, 0x3fc8, 0x3fc5, 0x3fc6, + 0x3fad, 0x43e2, 0x43ea, 0x43e3, 0x43e1, 0x44f7, 0x4501, 0x4512, + 0x44f6, 0x44f1, 0x451f, 0x44ee, 0xc952, 0x44f3, 0x4515, 0x4516, + 0x4517, 0x44f8, 0x4519, 0x44f2, 0x44f4, 0x44f5, 0x4513, 0x4506, + 0x4726, 0x4724, 0x475a, 0x60c8, 0x4797, 0x4795, 0x479a, 0x481f, + 0x3dfb, 0x4829, 0x4820, 0xc962, 0xc963, 0x494c, 0x4930, 0x4938, + 0x493d, 0x4951, 0x494f, 0x494a, 0x4934, 0x4936, 0x1b30, 0x4b6a, + 0x4b68, 0x4c1c, 0x4c0e, 0x4c1e, 0x0359, 0x4c09, 0x4c08, 0x4c13, + 0x4c01, 0x4c0f, 0x4c14, 0x4c06, 0x4c07, 0x1cb2, 0xc973, 0x0376, + 0x4d79, 0x4dea, 0x4ded, 0x4de9, 0x4dee, 0x4e68, 0x4e64, 0x4e67, + 0x4e72, 0x4e62, 0x4e74, 0x4e79, 0x4f19, 0x4f17, 0x4f15, 0x4f16, + 0x4fe6, 0x8fa4, 0x4fee, 0x03d2, 0x4fdf, 0x4fe4, + /* 0x37 */ + 0x4fda, 0x4fea, 0x4fed, 0x4fe3, 0x4fe9, 0x51fd, 0x3957, 0x5221, + 0x52c6, 0x52b8, 0x52cb, 0xc985, 0x52bd, 0x52b5, 0x52bb, 0x52bf, + 0x52be, 0x52b2, 0x52c1, 0x52c2, 0x5399, 0x53c6, 0x542c, 0x542d, + 0x5425, 0x541e, 0x541f, 0x5423, 0x5550, 0x554e, 0x554d, 0x5552, + 0x55e9, 0x55ec, 0x55e8, 0x5658, 0x565c, 0x565b, 0x568f, 0x6a72, + 0x56f6, 0x5700, 0x56fc, 0x56f8, 0x56ea, 0x56fe, 0x56f7, 0x56fd, + 0x5870, 0x5862, 0x5844, 0x0520, 0x584d, 0x584c, 0x583f, 0x5866, + 0x5835, 0x0529, 0x5834, 0x588d, 0x5884, 0x0538, 0x5886, 0x5889, + 0x5887, 0x5883, 0x5875, 0x5879, 0x58af, 0x58b0, 0x5bb7, 0x5bbb, + 0x5bb9, 0x5c46, 0x5c47, 0x5c45, 0x5cea, 0x5cf6, 0x5d68, 0x5d39, + 0xc9b9, 0x5d3d, 0x5d3b, 0x5d4d, 0x5d30, 0x5d4a, 0x5d3e, 0x5d40, + 0x5d4c, 0x5d47, 0x5d38, 0x5d52, 0x5d3a, 0x5d53, + /* 0x38 */ + 0x60c4, 0x60c1, 0x611c, 0x611d, 0x612a, 0x611e, 0x612f, 0x6122, + 0x612e, 0x6125, 0x0689, 0x06b0, 0x624a, 0x624b, 0x6276, 0x06bf, + 0x62e8, 0x62ef, 0x62e9, 0x06c5, 0x62ea, 0xc9cc, 0x06ea, 0x639b, + 0x639e, 0x6393, 0x63a7, 0x639c, 0x63a0, 0x639a, 0x63ab, 0x63be, + 0x63a9, 0x652d, 0x656e, 0x6644, 0x663d, 0x663a, 0x6668, 0x663c, + 0x666a, 0xc9e0, 0x6638, 0x6665, 0x6639, 0x666d, 0x6636, 0xc9e3, + 0x663e, 0x667e, 0x6637, 0x6999, 0x69a9, 0x69ad, 0x69a7, 0x69a8, + 0x6a66, 0x6a69, 0x6a6d, 0x6a67, 0x6a6b, 0x6a6a, 0x6aee, 0x6b01, + 0x6b03, 0x6af4, 0x6afb, 0x0837, 0x6af6, 0x6afc, 0x6bf4, 0x6c08, + 0x6c0a, 0x6c09, 0x6c6d, 0x6c62, 0x6c41, 0x6c5e, 0x6c5c, 0x6df3, + 0x6e26, 0x08e4, 0x6e39, 0xca04, 0x6e6c, 0x6e2b, 0x6e2e, 0x6e3b, + 0x6e5e, 0x6efb, 0x6e27, 0x6e24, 0x6e69, 0x6e30, + /* 0x39 */ + 0xca05, 0x6e62, 0x6e38, 0x6e35, 0x6e2a, 0x6e2c, 0x6e68, 0x6e31, + 0x6e2f, 0x6e2d, 0x6e3a, 0x6e36, 0xca03, 0x6e21, 0x6e3c, 0x6e20, + 0x6e64, 0x6e3e, 0x08e8, 0x71f7, 0x7212, 0x71f1, 0x71f5, 0x7222, + 0x71f2, 0x71df, 0x7215, 0x7216, 0x757a, 0x7576, 0x75be, 0x0a20, + 0x75bd, 0x7609, 0x7608, 0x7657, 0x77a3, 0x77bf, 0x77b8, 0x77af, + 0x779c, 0x77a5, 0x7772, 0x7775, 0x779d, 0x7799, 0x77b9, 0x794e, + 0x7939, 0x793b, 0x7935, 0x793c, 0x7955, 0x7af0, 0x7af3, 0x7af4, + 0x7b3b, 0x7b3c, 0x7b3a, 0x7b36, 0x7c07, 0x3feb, 0x7c55, 0x7c50, + 0x7c4f, 0x7c52, 0x7c56, 0x33bd, 0x7c32, 0x7d63, 0x7d6b, 0x7d66, + 0x7d57, 0x7d5d, 0x0b86, 0x7d6d, 0x7d61, 0x7d69, 0x7d5a, 0x7d5c, + 0x7d62, 0x7f2a, 0x7f29, 0x7f58, 0x7f5a, 0x7fd7, 0x7fdb, 0x7fdc, + 0x7fdd, 0x7fd8, 0x8054, 0x805b, 0x805c, 0x8053, + /* 0x3a */ + 0x804f, 0x8056, 0x8050, 0x805a, 0x806b, 0x8136, 0x8153, 0x813a, + 0x813c, 0x813e, 0x8149, 0x8140, 0xca46, 0xca47, 0x8364, 0x8365, + 0x83b5, 0x83b6, 0x83b2, 0x8448, 0x844a, 0x8472, 0x8469, 0x845a, + 0x844c, 0x862c, 0x8630, 0x864b, 0x8649, 0x8642, 0x8644, 0x864a, + 0x864f, 0x8792, 0xca57, 0x8797, 0x8780, 0x8782, 0x8786, 0x8953, + 0x895e, 0x8952, 0x895b, 0x894e, 0x8a6d, 0x8a6e, 0x8afa, 0x8af6, + 0x8afb, 0x8c33, 0x8c3d, 0x8c37, 0x8c3e, 0x8c35, 0x8d9a, 0x8dab, + 0x8da6, 0x8db0, 0x8d99, 0x8da0, 0x8d9e, 0x8da8, 0x8da1, 0x8daa, + 0x8dad, 0x8dbb, 0x8d9c, 0x8da5, 0x33b3, 0x8f27, 0x8f8d, 0x8f8e, + 0x8f8f, 0x8f92, 0x0f56, 0x8f91, 0x8fad, 0x9057, 0x9058, 0x905e, + 0x905d, 0x905c, 0x905b, 0x0f67, 0x910a, 0x9103, 0x910e, 0x91b8, + 0x924d, 0x923f, 0x9247, 0x924b, 0x924a, 0x923d, + /* 0x3b */ + 0x2838, 0x9241, 0x924c, 0x2881, 0x9362, 0x9369, 0x9361, 0x0fd1, + 0x93aa, 0x93a6, 0x93ac, 0x93bd, 0x93bb, 0x93a4, 0x93ba, 0x939a, + 0x0feb, 0x93a1, 0x93c1, 0x95e0, 0x960a, 0x9603, 0x9606, 0x9639, + 0x963a, 0x9636, 0x965b, 0x965f, 0x965e, 0x9667, 0x9661, 0x9662, + 0x965d, 0x96ca, 0x96cc, 0x96ce, 0x9718, 0x971d, 0x971f, 0x9720, + 0x9717, 0x9715, 0x981f, 0x9827, 0x9826, 0x5010, 0x988b, 0x98ae, + 0x988a, 0xca99, 0x9892, 0x9889, 0x9887, 0x10b6, 0x988f, 0x9884, + 0x9883, 0x988c, 0x9893, 0x988d, 0x9898, 0x987d, 0x987e, 0x98d2, + 0x9880, 0x9899, 0x9cac, 0x9d50, 0x9d55, 0x9d42, 0x9d3f, 0x9d3c, + 0x11a3, 0x9d4c, 0x9d49, 0x9d57, 0x9d58, 0x9d4f, 0x9d5c, 0x9d47, + 0xcab7, 0x9fab, 0x1210, 0x9faf, 0x9fad, 0x9fe8, 0x9fe7, 0xa030, + 0xa026, 0xa02f, 0xa028, 0xa02b, 0xa01d, 0xa02d, + /* 0x3c */ + 0xa020, 0xa02a, 0xa02c, 0xa035, 0xa021, 0xa023, 0xa024, 0xa036, + 0xa037, 0xa1e9, 0xa2ba, 0xa2b8, 0xcacc, 0xa36d, 0xa36a, 0xa368, + 0xa369, 0xa36b, 0xa361, 0xa5dc, 0xa5db, 0xa62d, 0xa62c, 0xa6a2, + 0xa72b, 0xa732, 0xcad7, 0xa894, 0xa892, 0xa890, 0xa9c9, 0xa9c4, + 0xa9c1, 0xa9c3, 0xa9cd, 0xab14, 0xaba7, 0xabaf, 0xabaa, 0xad0d, + 0xad54, 0xad5b, 0xad61, 0xadae, 0xadb3, 0xadc0, 0xadc4, 0xadbf, + 0xadcb, 0xadad, 0xada7, 0xada4, 0xadbd, 0xadaf, 0xadb2, 0xada5, + 0xafe7, 0xafe0, 0xafce, 0xafde, 0xafd5, 0xafdf, 0xafd9, 0xb0f2, + 0xb223, 0xb240, 0x151b, 0xb23e, 0x1587, 0xb3cf, 0x3e54, 0xb55b, + 0xb558, 0xb562, 0xb55f, 0xb567, 0xb563, 0xb55e, 0xb560, 0xb685, + 0xb686, 0xb687, 0xb8e8, 0xb8e6, 0xbd71, 0xbd85, 0xcb02, 0xbd86, + 0xbe10, 0x3cf8, 0x33bf, 0x3e61, 0x33fe, 0x33fc, + /* 0x3d */ + 0x3439, 0x3461, 0x3460, 0x35e2, 0x35ea, 0x35e3, 0x35b4, 0x35ae, + 0x35be, 0x35b8, 0x35a8, 0x35aa, 0x35a9, 0x35b3, 0x35d5, 0x35ad, + 0x35b9, 0x35bb, 0x35b1, 0x35c2, 0xc908, 0x35eb, 0x35ba, 0x35d2, + 0x35d4, 0x37f1, 0x381d, 0xc912, 0x3862, 0x388c, 0x38e6, 0x38e7, + 0x395a, 0x3958, 0x3959, 0x3996, 0x3997, 0x3a61, 0x3a67, 0x3a71, + 0x3a65, 0x3a7d, 0x3a7e, 0x3b7d, 0x3b84, 0x3b7c, 0x3b7e, 0x3b7f, + 0x3b80, 0x3bef, 0x3bf4, 0x3c1e, 0x3c4e, 0x3cfb, 0x3cfa, 0x3cfd, + 0xc931, 0xc932, 0x3d79, 0x3d7c, 0x3d7d, 0x3d84, 0x3d7b, 0x3d78, + 0x0157, 0x3e5e, 0x3e5a, 0x3e5c, 0x3e59, 0x3e55, 0x3e63, 0x3e56, + 0x3e5f, 0x3e60, 0x3e5b, 0x404a, 0x4065, 0x40b3, 0x402c, 0x4077, + 0x403d, 0x4052, 0x4061, 0x402a, 0x403e, 0x4034, 0x4029, 0x40b2, + 0x40ad, 0x4040, 0x4053, 0xc944, 0x403f, 0x4041, + /* 0x3e */ + 0x4072, 0x43f6, 0x43f5, 0x43f4, 0x43f2, 0x43f9, 0x4527, 0x4554, + 0x4555, 0x452e, 0xc954, 0xc953, 0x452c, 0x4538, 0x4539, 0x4531, + 0x454f, 0x4573, 0x4530, 0x452b, 0x4551, 0x472c, 0x475b, 0x475c, + 0x4768, 0x476c, 0x476b, 0x4769, 0x479f, 0x4838, 0x483c, 0x483a, + 0x4835, 0x029d, 0x4839, 0x4836, 0x483b, 0x4960, 0x4961, 0x4963, + 0x4964, 0x4994, 0x4993, 0x495e, 0x4968, 0x496a, 0x4965, 0xc966, + 0x4990, 0x495f, 0x4972, 0xc965, 0x4c3c, 0x4c27, 0x4c24, 0x4c26, + 0x4c25, 0x035f, 0x4c28, 0x4c36, 0x4d31, 0x4d30, 0x4d34, 0x4d81, + 0x4d7d, 0x4d82, 0x4d80, 0x0379, 0x35d3, 0x4df2, 0x4e66, 0x4e8c, + 0x4e7b, 0x4e83, 0x0398, 0x4e8e, 0x4e7a, 0x4e92, 0x4e91, 0x4e82, + 0x4f1b, 0x4f1c, 0x5027, 0x5021, 0x03dc, 0x1d2b, 0x5043, 0x03df, + 0x5018, 0x507b, 0x501a, 0x504b, 0x504a, 0x504d, + /* 0x3f */ + 0x504f, 0x5019, 0x5035, 0x5013, 0x5052, 0x5014, 0x501e, 0x502c, + 0x5020, 0x5022, 0x5012, 0x501f, 0x5200, 0x5223, 0x5240, 0x5243, + 0x52e4, 0x52db, 0x52ea, 0x52dd, 0x52cc, 0x52d9, 0x52e8, 0x52f6, + 0x52e3, 0x52d3, 0x52da, 0x52d6, 0x52e7, 0x543a, 0x543f, 0x5440, + 0x5448, 0x5459, 0x5437, 0x5444, 0xc98c, 0xc98b, 0x5455, 0x5439, + 0x5554, 0x5555, 0x5556, 0x5557, 0x5558, 0x5559, 0x558d, 0x55f2, + 0x55f8, 0x55f5, 0x55f6, 0x55fc, 0x55fe, 0x55f1, 0x55fd, 0x565e, + 0x5696, 0x5697, 0x569c, 0x569b, 0x5695, 0xc99a, 0x571a, 0x5709, + 0x5704, 0x570e, 0x571c, 0x5718, 0x570d, 0x5710, 0x570c, 0x5703, + 0x587b, 0x58a6, 0x5877, 0x5888, 0x5874, 0x58da, 0x5876, 0x5878, + 0x588a, 0x588f, 0x587d, 0x5890, 0x58ed, 0x58d9, 0x58d0, 0x591a, + 0x58d7, 0x58e2, 0x58e1, 0x58c5, 0x58e0, 0x58ca, + /* 0x40 */ + 0x5925, 0x58cc, 0xc9b3, 0x5bc6, 0x5bc1, 0x5c4d, 0x5d4b, 0x5d64, + 0x5d95, 0x5d99, 0xc9bc, 0x5d94, 0x5da2, 0x5dae, 0x5d9e, 0x5da7, + 0x5d86, 0x05fd, 0x5da4, 0x5d91, 0x5d93, 0xc9bb, 0x5d88, 0x60cd, + 0x60ca, 0x613f, 0x6140, 0x6146, 0x6141, 0x6145, 0x6158, 0x613b, + 0x6148, 0x624e, 0x6252, 0x624f, 0x627b, 0x627a, 0x62a0, 0x629f, + 0x62fb, 0x62f7, 0x63b8, 0x63b9, 0x63bb, 0x63b7, 0x06f4, 0x63ba, + 0x06ef, 0x63da, 0x63b5, 0x63bf, 0x63bc, 0x63c0, 0xc9d3, 0xc9d9, + 0x6575, 0x6579, 0x6576, 0x6635, 0x6640, 0x66c0, 0x6681, 0x66ad, + 0x66af, 0x66ac, 0x668f, 0x66a8, 0x66aa, 0x66a9, 0x6688, 0x667f, + 0x6680, 0x66bc, 0x69ae, 0x69bb, 0x69bd, 0x0831, 0x6a78, 0x6a74, + 0x6b0c, 0x6b11, 0x6b08, 0x6b06, 0x6b10, 0x6b8f, 0x6b90, 0x6b8d, + 0x6b8e, 0x6b96, 0x6b95, 0x6c0b, 0x6c0c, 0x6c7c, + /* 0x41 */ + 0x6c73, 0x6c75, 0x6c76, 0x6c7d, 0x6c78, 0x6c71, 0x6d4b, 0x6d4e, + 0x6e33, 0x6e32, 0x0903, 0x6e91, 0x6ee7, 0x6ee9, 0x6ea2, 0x6e94, + 0x6e87, 0x6ea3, 0x6edd, 0x6e7b, 0x6e83, 0x6e81, 0x6edf, 0x6e7c, + 0x6ee4, 0x6ee2, 0x6e93, 0x6e7d, 0x6ebf, 0x6e9b, 0x6e8e, 0x6e9f, + 0x0909, 0x6e8c, 0x6e7f, 0x6e9c, 0x6e84, 0x6e42, 0x6ee6, 0x7251, + 0x724a, 0x7264, 0x7225, 0x722f, 0x722e, 0x722b, 0x7228, 0x7232, + 0x722d, 0x7231, 0x7239, 0x722c, 0x7261, 0x7511, 0x7510, 0x7512, + 0x7553, 0x7555, 0x757b, 0x7581, 0x757d, 0x757c, 0x75c2, 0x75c5, + 0xca22, 0x75c4, 0xca23, 0x766b, 0x7668, 0x0a3e, 0x765c, 0x765d, + 0x766a, 0xca24, 0x7c76, 0x7776, 0x0a77, 0x77c4, 0x77cb, 0x77c8, + 0x77d4, 0x77d5, 0x77c9, 0x77d7, 0x0a7b, 0x7978, 0x795a, 0x795b, + 0x795c, 0x7956, 0x7958, 0x7971, 0x96d4, 0x7b40, + /* 0x42 */ + 0xca33, 0x7b3f, 0x7b43, 0x7b41, 0x7be2, 0x7be0, 0x7be3, 0x7c66, + 0x7c73, 0x7c6c, 0x7c71, 0x7c6a, 0x7c6d, 0x7c6e, 0x7c6b, 0x7d8c, + 0x7d77, 0xca3a, 0x7d7f, 0x7d89, 0x7d7a, 0x7d85, 0x7d78, 0x7d8a, + 0x7d86, 0x7f2c, 0x7f67, 0x7f5b, 0x7fe5, 0x7fe1, 0x8061, 0x8069, + 0x806a, 0x8165, 0x816d, 0x8163, 0x8186, 0x815c, 0x8162, 0xca48, + 0x8179, 0x8169, 0x8170, 0x8176, 0x815d, 0x8187, 0x816e, 0x8171, + 0x817c, 0x8173, 0x815b, 0x816b, 0x83bf, 0x83c1, 0x83bd, 0x83c9, + 0x83bc, 0x83c2, 0x83c0, 0x8492, 0x84a9, 0x848f, 0x8476, 0x847b, + 0x8475, 0x84a4, 0x8664, 0x873d, 0x87af, 0x0d3a, 0xca58, 0x879d, + 0x8799, 0x87b1, 0x8963, 0x8962, 0x8964, 0x8969, 0x0da0, 0x8a75, + 0x8a73, 0x8a71, 0x8a74, 0x8b0c, 0x8b16, 0x0de5, 0x8b11, 0x8b1f, + 0x8b1a, 0x8b0d, 0x8b1b, 0x8b13, 0x8c4e, 0x8c55, + /* 0x43 */ + 0x8c50, 0x0e7d, 0x8dd2, 0x8dd3, 0x8dd1, 0x8df1, 0x8ddc, 0x8dc8, + 0x8dcc, 0x8dd0, 0x8dcf, 0x8ddf, 0x8f2b, 0x8f2e, 0x8f2d, 0x8f9d, + 0x8f9e, 0x8f9f, 0x8fa9, 0x8fa0, 0x8f98, 0x8fa1, 0x8fab, 0x8faf, + 0x906e, 0x905f, 0x905a, 0x0f6d, 0x9065, 0x9068, 0x9072, 0x9117, + 0x9116, 0x9118, 0x9119, 0x911a, 0x9122, 0x911b, 0x911c, 0x91be, + 0x91ee, 0x925a, 0x9250, 0x9258, 0x9254, 0x9257, 0x9256, 0x9315, + 0x939b, 0x9393, 0x9392, 0x9372, 0x9398, 0x9399, 0x93df, 0x0ff8, + 0x93d5, 0x2958, 0x93d4, 0x93f3, 0x93f4, 0x93e7, 0x93e1, 0x93e6, + 0x93eb, 0x93ec, 0x35db, 0x1050, 0x960d, 0x960c, 0x4d2f, 0x9668, + 0x9665, 0x966b, 0x9669, 0x96d1, 0x96d3, 0x9727, 0x9728, 0x1068, + 0x1067, 0x9724, 0x97d7, 0x98ca, 0x98c7, 0xca9e, 0x98d8, 0x98e1, + 0x98c6, 0x98f8, 0x98c3, 0x98f4, 0x9917, 0x98ea, + /* 0x44 */ + 0x98cb, 0x9886, 0x98c4, 0x98d9, 0x9919, 0x98c2, 0x98e2, 0x10cf, + 0x98de, 0x98ed, 0xca9c, 0x10cd, 0x991d, 0x98dd, 0x98db, 0x98e8, + 0x98e9, 0x98bf, 0x98e0, 0x98d1, 0x98dc, 0x98ce, 0x991e, 0x98cc, + 0x98f2, 0x98f3, 0xca9f, 0xcaa2, 0xcaa3, 0xcaa1, 0x9cab, 0x9caa, + 0x9ca7, 0x9ca9, 0x9d88, 0x9d75, 0x9d60, 0x9d6c, 0x9d73, 0x11ab, + 0x9d6e, 0x9d74, 0x9d76, 0x9d68, 0x9d77, 0x9d86, 0x9fea, 0xa051, + 0xa050, 0xa058, 0xa04d, 0xa04f, 0xa04e, 0xa05c, 0xa052, 0xa044, + 0xa04a, 0xa04b, 0xa1ea, 0xa210, 0xa211, 0xa2cd, 0xa2bf, 0xa2c4, + 0xa2d0, 0xa2ce, 0xa2c0, 0xa2c2, 0xa2cf, 0xa2c9, 0xa2bb, 0xa397, + 0xa392, 0xa36f, 0xa37e, 0xa39a, 0x12c1, 0xa386, 0xa373, 0x2d24, + 0xa377, 0xa38f, 0xa370, 0xa381, 0xa382, 0xa399, 0xa37d, 0xa37f, + 0xa37b, 0xa387, 0xa5b2, 0xa62f, 0xa634, 0xa62e, + /* 0x45 */ + 0xa632, 0x1347, 0xa6aa, 0x1357, 0xa6a9, 0xa738, 0xa736, 0xa737, + 0xa747, 0xa733, 0xa739, 0xa735, 0xa744, 0xa8a5, 0xa8a6, 0xa89e, + 0xa9e3, 0xa9df, 0xa9d3, 0xa9f1, 0xa9e4, 0xa9e0, 0xa9d6, 0x2ec3, + 0xa9e6, 0xa9d8, 0xa9de, 0xa9db, 0xa9dc, 0xab1b, 0xab1f, 0xab1d, + 0xab1c, 0xab1e, 0xab20, 0xab21, 0x144e, 0xabb6, 0xabbc, 0xabc6, + 0xabc7, 0xabba, 0xabbe, 0xabbd, 0xabb5, 0xabb4, 0xad0f, 0xad62, + 0xadeb, 0xadd9, 0xade4, 0xadd7, 0xadd8, 0xadd6, 0xadce, 0xaddd, + 0xade7, 0xadd2, 0xadc5, 0xadc9, 0xaddb, 0xaf92, 0xaf8a, 0xaf8b, + 0xaf89, 0xb008, 0xb003, 0xb006, 0xb005, 0xaff5, 0xb00b, 0xaffb, + 0xb0fc, 0xb101, 0xb102, 0xb0fa, 0xb108, 0xb0f7, 0xb100, 0xb0ff, + 0xb106, 0xb0f6, 0xb0fb, 0xb10a, 0xb225, 0xb243, 0xb244, 0xb364, + 0xb362, 0xb35e, 0xb35b, 0xb3d6, 0x3372, 0x33c2, + /* 0x46 */ + 0xb577, 0xb582, 0xb57c, 0xb57d, 0xb586, 0xb581, 0xb584, 0xb576, + 0xb583, 0xb57f, 0xb57e, 0xb688, 0xb68d, 0xb68b, 0xb691, 0xb68f, + 0xb77c, 0xb779, 0xb77a, 0xb8ea, 0xbb4c, 0xbc99, 0x35d1, 0xbd8b, + 0xbd8d, 0xbd8a, 0xbd8e, 0xbe11, 0x5456, 0xcb15, 0x3374, 0x33c3, + 0x33c4, 0x341b, 0x345f, 0x346a, 0x3469, 0x346b, 0x360c, 0x35f6, + 0x35ed, 0x3629, 0x35fe, 0x35f1, 0x3617, 0x35ff, 0x35ee, 0x35fd, + 0x361c, 0x35fc, 0x3600, 0x3620, 0x0077, 0x35f9, 0x3667, 0x3608, + 0x379e, 0x37f3, 0x3825, 0x3827, 0x381f, 0x3865, 0x3863, 0x3894, + 0x3897, 0x38f1, 0x395f, 0x3962, 0x18f2, 0x3960, 0xc922, 0x3a8c, + 0x3a82, 0x3a90, 0x3a8b, 0x3a8d, 0x3a81, 0x3a9d, 0x3b8e, 0x3b8f, + 0x3b92, 0x3c23, 0x3c52, 0xc92e, 0x3d00, 0x3d01, 0x3d02, 0x3d1f, + 0x3d8c, 0x3d89, 0x3d8b, 0x3d88, 0x3d8d, 0x3d8f, + /* 0x47 */ + 0x9085, 0x3e00, 0x3e05, 0x3e01, 0x3e68, 0x3e6e, 0x3e67, 0x3e75, + 0x1ab6, 0xc945, 0x40d7, 0xc946, 0x3348, 0x40d4, 0x40d8, 0xc947, + 0xc948, 0x40ba, 0xc949, 0x40db, 0x40bf, 0x4135, 0x40bc, 0x40d9, + 0x01c4, 0x40dd, 0x4100, 0x40d5, 0x4130, 0x40bd, 0x40dc, 0x43fd, + 0x43fe, 0x4407, 0x7517, 0x456f, 0x4569, 0x4570, 0x4567, 0x45a9, + 0x4595, 0x4590, 0x456c, 0x4597, 0x4571, 0x0252, 0x4574, 0x456d, + 0x458e, 0x472f, 0xc61b, 0x47a9, 0x484e, 0xc95f, 0x485a, 0x4848, + 0x4855, 0x484c, 0x4849, 0x484f, 0x484a, 0x49d6, 0x49a0, 0x49a9, + 0xc967, 0x499d, 0x49d4, 0x49a4, 0x49a8, 0x49a6, 0x49e6, 0x4b7d, + 0x4b77, 0x4b7a, 0x4c41, 0x4c49, 0x4c59, 0x4c45, 0x4c48, 0x4c40, + 0x4d8e, 0x4d95, 0x4d90, 0x4df7, 0x4df8, 0x4df6, 0x4dfb, 0x4e9e, + 0x4e9d, 0x4e99, 0xc977, 0x4ea3, 0x4ea9, 0x4e98, + /* 0x48 */ + 0x4ea0, 0x4e96, 0x4e94, 0x4e95, 0x4e9f, 0x4ea1, 0x4f21, 0x4f1d, + 0x4f1f, 0x506d, 0xc97c, 0x509a, 0x5092, 0x507a, 0x507d, 0x50a1, + 0x509d, 0x5099, 0x506b, 0x506e, 0xc97d, 0x5245, 0xc984, 0x52fb, + 0x52eb, 0x52f2, 0x52f9, 0xc986, 0x52f8, 0x52ed, 0x5301, 0x52f7, + 0x5306, 0x539b, 0x53ca, 0x046b, 0x1ec3, 0x546b, 0x546c, 0x5474, + 0x5467, 0x545b, 0x5460, 0x5476, 0x5463, 0x5461, 0x5528, 0x555b, + 0x555e, 0x5560, 0x555d, 0x555c, 0x55f4, 0x5600, 0x5608, 0x5607, + 0x5601, 0x5605, 0x5664, 0x5663, 0x569e, 0x56a0, 0x56a1, 0x569f, + 0x5726, 0x572d, 0x5728, 0x571d, 0x58ec, 0x58e3, 0x58eb, 0x5916, + 0x58c8, 0x931b, 0x58e9, 0x58e4, 0x5924, 0x58d1, 0x0541, 0x58dd, + 0x58c2, 0x58cb, 0x58c7, 0x58e7, 0x0550, 0x58ea, 0x594b, 0xc9a5, + 0x5960, 0x597d, 0x593e, 0xc9a4, 0x5952, 0x594e, + /* 0x49 */ + 0x593c, 0x5932, 0x5930, 0x5923, 0x5bca, 0x5bcb, 0x5bc9, 0x5bc8, + 0x5bcd, 0x5d98, 0x5da0, 0x5d9f, 0x5d9c, 0x5da3, 0x5d97, 0xc9be, + 0x5df1, 0x5e09, 0x5e03, 0x5dea, 0x5e45, 0x5ded, 0x5e05, 0x5e1a, + 0x5e15, 0x5e01, 0x5dec, 0x5e0e, 0x5e17, 0x5e42, 0x5e12, 0x5e10, + 0x5def, 0x5dff, 0x5e00, 0x5e0c, 0x5e0f, 0x5e04, 0x5e08, 0x5e14, + 0x5e43, 0xc9bd, 0x5e1b, 0x5e11, 0x5e13, 0x60cf, 0x60ce, 0x616f, + 0x616e, 0x617a, 0x6170, 0x6164, 0x615e, 0x616c, 0xc9c9, 0x615b, + 0x6161, 0x6165, 0x627f, 0x6280, 0x627c, 0x62a7, 0x62a6, 0x62a1, + 0x06c0, 0x62a8, 0x62a3, 0x62a2, 0x62ad, 0x62a5, 0x6301, 0x62ff, + 0x62fc, 0x6300, 0x6335, 0x63ee, 0x63ef, 0x63f6, 0x63e8, 0x63ea, + 0x63e3, 0x641f, 0x06fc, 0x63e4, 0x63fa, 0x63f1, 0x63fb, 0xc9d4, + 0x653d, 0x653c, 0x0079, 0x6578, 0x6577, 0x100b, + /* 0x4a */ + 0x66d1, 0x66c7, 0x66df, 0x66d0, 0x66e0, 0x66d6, 0x66d8, 0x6716, + 0x670e, 0x66d9, 0x670f, 0x6711, 0x66cd, 0x6689, 0x66ce, 0x6714, + 0x66da, 0x6712, 0x66d3, 0x66c2, 0x66e1, 0x66e9, 0x66ea, 0x66de, + 0x6715, 0x69d9, 0x69d6, 0x69cd, 0x69d0, 0x69d3, 0xc9f0, 0x6a82, + 0x6a85, 0x6a7f, 0x6a7d, 0x6a81, 0x6a83, 0x6a84, 0xada0, 0x6b28, + 0x6b0f, 0x6b17, 0x6b1a, 0x6b25, 0xc9f7, 0x6b9b, 0x6b99, 0x6c92, + 0x6c8c, 0x6c95, 0x6c8d, 0x6ca3, 0x6c93, 0x6c91, 0x6edb, 0x6e99, + 0x6e9a, 0x6f08, 0x6f4c, 0x6f0d, 0x6f01, 0x6f4e, 0x6f02, 0x6f4d, + 0x6f21, 0x6efc, 0xca09, 0x6e8a, 0xca08, 0x6e95, 0x6f11, 0x6f12, + 0x6f46, 0x6f1c, 0x6f49, 0x6f0c, 0x091e, 0x6f13, 0x6f16, 0x6efd, + 0x6f0f, 0x6f1f, 0x7230, 0x726e, 0x726b, 0x729b, 0x727b, 0x7263, + 0x7297, 0x726d, 0x729c, 0x7298, 0x726f, 0x7267, + /* 0x4b */ + 0x7269, 0x7515, 0x7563, 0x7586, 0x758a, 0x7587, 0x7588, 0x7585, + 0x7589, 0x75ca, 0x75c7, 0x75cb, 0x75cc, 0x75c9, 0x760d, 0x7683, + 0x7684, 0x7678, 0x7682, 0x7673, 0x7679, 0x768c, 0x77d0, 0x77cf, + 0x77d2, 0x77d9, 0x77cc, 0x77eb, 0x77fd, 0x77ec, 0x77e8, 0x77f8, + 0x77fa, 0xca27, 0x0a85, 0x77e1, 0x77fb, 0x78e7, 0xca2e, 0x79a5, + 0x7991, 0x79a6, 0x797c, 0x7992, 0x79a2, 0x79a0, 0x7afc, 0x7afe, + 0x7b57, 0x7b53, 0x7b58, 0x7be7, 0x7c8e, 0xca38, 0x7c83, 0x7c8b, + 0x7c84, 0x0b97, 0x7da2, 0x7db7, 0x7da9, 0x7da5, 0x7d9f, 0x7daa, + 0x7d97, 0x7da1, 0x7d9e, 0x7dab, 0x7d99, 0x7da3, 0x7f30, 0x7f32, + 0x7f2f, 0x7f70, 0x7f6c, 0x7f6f, 0x7fe8, 0x7fee, 0x7fea, 0x806d, + 0x8076, 0x8070, 0x8071, 0x806c, 0x81eb, 0x81b5, 0x8196, 0x8190, + 0x818d, 0xca49, 0x81a2, 0x81b0, 0x8192, 0x81a0, + /* 0x4c */ + 0x8193, 0x81c3, 0x818e, 0x81b6, 0x819d, 0x8195, 0x81b3, 0x81a4, + 0x8370, 0x83d4, 0x0c93, 0x83cf, 0x3470, 0x8494, 0x2561, 0x84c0, + 0x84b4, 0x84c1, 0x0cb2, 0x84bd, 0x84af, 0x8677, 0x8678, 0x866b, + 0x866d, 0x866e, 0x8672, 0x866f, 0x8671, 0x62ab, 0x868c, 0x873f, + 0x87b6, 0x87b7, 0x2606, 0x87bb, 0x87b8, 0x3a9c, 0x87b9, 0x2601, + 0x898b, 0x897a, 0x8984, 0x8988, 0x8991, 0x8979, 0x898e, 0x8980, + 0x8982, 0x897c, 0x0da4, 0x8a84, 0x8a7f, 0x0df2, 0x8b3b, 0x8b71, + 0x8b3d, 0x8b30, 0x0df1, 0x8b3e, 0x8b38, 0x8c5e, 0x8c64, 0x0e81, + 0x8c5d, 0x8c6d, 0x8c4f, 0x8c62, 0x8c5f, 0x8dec, 0x8df2, 0x8df4, + 0x8df7, 0x8df6, 0x8e07, 0x8ded, 0x8dea, 0x8df0, 0x8df8, 0x8df3, + 0x0edc, 0xca72, 0x8f31, 0x8f2f, 0x8fb6, 0x8fae, 0x8faa, 0x8fbf, + 0x8fcc, 0x8fc7, 0x9983, 0x9080, 0x907b, 0x907f, + /* 0x4d */ + 0x907d, 0x9083, 0xca78, 0x9146, 0x912d, 0x9125, 0x9126, 0x912c, + 0x9137, 0x9131, 0x9133, 0x9132, 0x9127, 0x912a, 0x912e, 0x912f, + 0x91c0, 0x9271, 0x9261, 0x9262, 0x9266, 0x9318, 0x93c5, 0x93c3, + 0x93c4, 0x93c2, 0x93ae, 0x9410, 0x9408, 0x941f, 0x943a, 0x943b, + 0x9436, 0x940c, 0x9406, 0x942a, 0x9457, 0x9450, 0x9420, 0xca85, + 0x942c, 0x9421, 0x940b, 0x9419, 0x9435, 0x9418, 0x940f, 0x9413, + 0x9455, 0x9439, 0x941a, 0x100c, 0x9417, 0x95e4, 0x95e9, 0x758b, + 0x9610, 0x9612, 0x963f, 0x966e, 0x7518, 0xca8c, 0x96d6, 0x96d5, + 0x96d7, 0x3e02, 0x106d, 0x9731, 0x9730, 0x973a, 0x9885, 0x986b, + 0x9948, 0x994b, 0x9937, 0x997b, 0x996c, 0x9985, 0x9965, 0x9936, + 0x9986, 0x9934, 0x9968, 0x995a, 0x9958, 0x9972, 0x996a, 0x98d3, + 0x993c, 0x9933, 0x993b, 0x994d, 0x994f, 0x997c, + /* 0x4e */ + 0x99b0, 0x995b, 0x9955, 0x9964, 0x996b, 0x9953, 0x10e6, 0x9957, + 0x995e, 0x996d, 0x9935, 0x9969, 0x9959, 0x9966, 0x9950, 0x9951, + 0x995c, 0x9a5d, 0x9987, 0x9978, 0x9949, 0x994e, 0x98f1, 0x9973, + 0x9988, 0x98cf, 0xcaa4, 0x9cb1, 0x9cb3, 0x9d9c, 0x9da4, 0x9d90, + 0x9db8, 0x9da0, 0x9d9d, 0x9da8, 0x9da9, 0xcab9, 0x9db1, 0x9d93, + 0x9d9b, 0x9da2, 0x9da1, 0x9db0, 0x9da7, 0x9fb3, 0x2b49, 0x9fb4, + 0x9ff1, 0x9fed, 0x9fec, 0xa068, 0xa075, 0xa06a, 0xa062, 0xa067, + 0xa060, 0xa077, 0xa05f, 0xa079, 0xa223, 0xa221, 0xa21c, 0x2c99, + 0xa21f, 0xa21e, 0xa2d6, 0xa2d3, 0xa2d9, 0xa2d7, 0xa2d4, 0xa2dc, + 0xa2d8, 0xa3a3, 0x12d1, 0xa3be, 0xa3a9, 0xa3a1, 0xa3a0, 0xa3ab, + 0xa3a2, 0xa3ba, 0xa3c2, 0xa39c, 0xa3bb, 0xa3aa, 0xa3ac, 0xa3a5, + 0xa3c1, 0x132c, 0xa5e2, 0xa636, 0xa63d, 0xa63a, + /* 0x4f */ + 0x5661, 0xa648, 0xa63c, 0xa6b7, 0xa6ac, 0xa6b3, 0xa6b6, 0xa6b2, + 0x136e, 0xa75d, 0xa749, 0xa74e, 0xa74f, 0xa74d, 0xa75c, 0xa85d, + 0xa8bb, 0xa8ce, 0xa8bf, 0xa8ba, 0xa8c3, 0x13e5, 0xaa06, 0xa9f8, + 0xa9fe, 0xaa13, 0xa9f6, 0x13e6, 0xab34, 0xab2d, 0xab2a, 0xab35, + 0xab2c, 0xabd4, 0xabda, 0xabd3, 0xabd2, 0xabce, 0xabcf, 0x149f, + 0xadfd, 0xae0b, 0xadfe, 0xadf8, 0xadf7, 0xae17, 0xadfa, 0xadf9, + 0xae00, 0xadf5, 0xadf1, 0xae03, 0xae05, 0xae1c, 0xafac, 0xaf9a, + 0xafad, 0xafa0, 0xb01b, 0xb025, 0xb024, 0xb026, 0xb027, 0xb028, + 0xb02a, 0xb01a, 0xb02e, 0xb015, 0xb115, 0xb114, 0xb117, 0xb118, + 0xb10f, 0xb113, 0xb10b, 0xb122, 0x457a, 0xb226, 0x301f, 0xb251, + 0xb24d, 0xb24e, 0xb24a, 0xb24b, 0xb24c, 0xb250, 0xb262, 0xb24f, + 0xb252, 0xb368, 0xb369, 0xb3e5, 0xb3f0, 0xb3e1, + /* 0x50 */ + 0xb3e2, 0xcaf2, 0xb5a5, 0xb5a9, 0xb5a4, 0xb5af, 0xb5ac, 0xb5ae, + 0xb5aa, 0xb695, 0xb699, 0xb693, 0xb69d, 0xb698, 0xb69c, 0xb697, + 0x160d, 0xb789, 0xb787, 0xb8d7, 0xb8ed, 0xb8f1, 0xb8f0, 0xb905, + 0xb903, 0xb904, 0xb95f, 0xbb57, 0xbc9c, 0xbca1, 0xbc9a, 0xbd8f, + 0xbd93, 0xbd9e, 0xbda3, 0xbd98, 0xbd99, 0xbd95, 0xbe6e, 0xbe6a, + 0xbff4, 0xbff7, 0xc179, 0xc38f, 0xc391, 0xc40b, 0xc802, 0x3384, + 0x3404, 0x3480, 0x362f, 0x363f, 0x363b, 0x3662, 0x3644, 0x3633, + 0x365f, 0x362b, 0xc909, 0x3639, 0x3636, 0x3648, 0x3635, 0x366c, + 0x3658, 0x363a, 0x37a8, 0x37f4, 0x3829, 0x389a, 0x3900, 0x3abb, + 0x3abd, 0x3ab7, 0x3ab2, 0x00f8, 0x3aa8, 0x3aab, 0x3aa6, 0x3abc, + 0x3b97, 0x3b96, 0x3bf8, 0x1913, 0x3c51, 0x0133, 0x3cb5, 0x3cb4, + 0x3cb6, 0x013c, 0x3cb7, 0x3d05, 0x3d23, 0x3d95, + /* 0x51 */ + 0x3d98, 0x014f, 0x3d94, 0x3d93, 0x3e07, 0x3e73, 0x3e71, 0x3e72, + 0x3e78, 0x415f, 0x416a, 0x4167, 0x416b, 0x4169, 0x418e, 0x4149, + 0x4180, 0x01dc, 0x4144, 0x418f, 0x4145, 0xc94c, 0x414f, 0x4163, + 0x4136, 0x4148, 0x415c, 0x4193, 0x4161, 0x4160, 0x414e, 0x415e, + 0x413f, 0x41a4, 0x1ae0, 0x4168, 0x440b, 0x4411, 0x440d, 0x440e, + 0x45c2, 0xc957, 0x45b0, 0x45c3, 0x45c8, 0x4565, 0x45d7, 0x45bd, + 0x45b8, 0x45b6, 0x45c7, 0x45bc, 0x45b1, 0x45af, 0xc95b, 0x4735, + 0x4730, 0x475d, 0x3e76, 0x476f, 0x47b0, 0xc95e, 0x47b4, 0x485c, + 0x485d, 0x4a08, 0x49ee, 0x4a0b, 0x49f2, 0x49fd, 0x49f1, 0x4a10, + 0xc968, 0x4a14, 0x4b8b, 0x4b8c, 0x4b85, 0x4c7a, 0x4c6c, 0x4c60, + 0x4c67, 0x4c66, 0x4c6a, 0x4c5f, 0x4c6d, 0x4c68, 0x4c64, 0x4d3a, + 0x4d3b, 0x4d39, 0x4e02, 0x4e04, 0x4e03, 0x4eb4, + /* 0x52 */ + 0x4eb3, 0x4ebb, 0x4eac, 0x4eb6, 0x4eb1, 0x4eaf, 0x4eb5, 0x4ebe, + 0x4eb2, 0x4f24, 0x50b6, 0x50b9, 0x50ac, 0x50b0, 0x50d7, 0x50bb, + 0x50fe, 0x50cb, 0xc97f, 0x03f5, 0x50b3, 0x50be, 0x50cd, 0x50bc, + 0x50ba, 0x50c7, 0x5316, 0x531b, 0x5317, 0x5315, 0x539f, 0xc98e, + 0x5482, 0x5483, 0x548e, 0x546a, 0x5489, 0x5494, 0x5486, 0x5490, + 0x5562, 0x5590, 0x560c, 0x560f, 0x04c3, 0x56a5, 0x56a7, 0x56a6, + 0x56a4, 0x5735, 0x5738, 0x5736, 0x5743, 0x5747, 0x5737, 0x5943, + 0x59a2, 0x5951, 0x5972, 0x596d, 0x592f, 0x5954, 0x596e, 0x5955, + 0x5937, 0x594f, 0x5950, 0x1f39, 0x599e, 0xc9a8, 0x59b3, 0x59a7, + 0x0571, 0x59f9, 0x5991, 0xc9a7, 0x59b6, 0x59dd, 0x5999, 0x5bdf, + 0x5bd5, 0x77f5, 0x5e28, 0x5e40, 0x5e71, 0x5e98, 0x5e95, 0x5e65, + 0x5e78, 0x5e7f, 0x5e60, 0x5e7c, 0x5e96, 0x5e6a, + /* 0x53 */ + 0x5e79, 0x5e73, 0x5e72, 0x5e7b, 0x5e70, 0x60d5, 0x60d7, 0x618f, + 0x6189, 0x619e, 0x6187, 0x61a0, 0x618d, 0x6188, 0x617f, 0x618c, + 0x6193, 0x6259, 0xbcb0, 0x62b1, 0x81f4, 0x62af, 0x62b2, 0x6308, + 0x630a, 0x6336, 0x6337, 0xc9cf, 0x0701, 0x6436, 0x6429, 0x644a, + 0x6426, 0x6428, 0x6424, 0x642a, 0x6448, 0x6544, 0x6584, 0x658c, + 0x66c4, 0x66dc, 0x6787, 0x6753, 0x677f, 0x6731, 0x6751, 0x674b, + 0x6752, 0x6780, 0x67a5, 0x6781, 0x6743, 0x6734, 0x6736, 0x6732, + 0x6748, 0x6749, 0x673c, 0x674d, 0x674a, 0xc9e6, 0x678a, 0x6746, + 0x673e, 0x6783, 0x6750, 0x67b4, 0x69f0, 0x69e4, 0x69e3, 0x69e5, + 0x69e6, 0x69e7, 0x69e1, 0x69ef, 0x69e8, 0x69dd, 0x6a03, 0x6a88, + 0x6b26, 0x6b16, 0x6b3b, 0x6b2f, 0x6b39, 0x6b34, 0xc9f4, 0x6b35, + 0x6b31, 0x6b38, 0x3e81, 0x6baa, 0x6ba3, 0x6ba4, + /* 0x54 */ + 0x6ba0, 0x6ba1, 0x6ba9, 0x6ba5, 0x6caf, 0x6cb1, 0x6cab, 0x6cae, + 0x6cb0, 0x6cb3, 0x6cac, 0x6ca9, 0x6cb2, 0x6ca8, 0x6cb4, 0x6cc2, + 0x6d4f, 0x6d66, 0x6f1e, 0x6f15, 0x6f10, 0x6f7f, 0x6f7e, 0x6f60, + 0x6fcc, 0x6fb2, 0x6f62, 0x6f8d, 0x6f8e, 0x6f77, 0x6f7c, 0x6f8f, + 0x6f5d, 0x6f6d, 0x6f63, 0x6faf, 0x6f90, 0x6f7d, 0x6f7a, 0x6f06, + 0xca0b, 0x6f68, 0x6fb4, 0x6f78, 0x6fb1, 0x22d7, 0xca0c, 0x0941, + 0x72e8, 0x72e9, 0x72c0, 0x09d7, 0x72ea, 0x72b7, 0x72ba, 0x72b5, + 0xca1d, 0x72b4, 0x72bc, 0x72c6, 0x72b8, 0x72bd, 0x72c2, 0x734d, + 0x72f0, 0x72c7, 0x72c1, 0x72c3, 0x72f1, 0x72ec, 0x09e2, 0x751c, + 0x7520, 0x7558, 0x7565, 0x7564, 0x758c, 0x758d, 0x75d9, 0x75e0, + 0x7610, 0x7694, 0x7692, 0x7696, 0x7695, 0x76bf, 0x76a0, 0x0a45, + 0x77f4, 0x77f6, 0x77dc, 0x243d, 0x7816, 0x7815, + /* 0x55 */ + 0x781c, 0x780f, 0x782c, 0x7814, 0x7825, 0x7817, 0x7812, 0x781e, + 0x7980, 0x79a8, 0x79af, 0x79d6, 0x79e2, 0x79b4, 0x79b3, 0x79b0, + 0x79b2, 0x79a1, 0x7b60, 0x7b66, 0x7b61, 0x7b4e, 0x7b5d, 0x7b63, + 0x7be6, 0x7bef, 0x7bec, 0x7c98, 0x7ca7, 0x7c94, 0x7c95, 0x7c91, + 0x7c9d, 0x7c99, 0x7c9b, 0x7c9c, 0x7d1d, 0x7d1c, 0x7dd0, 0x7de0, + 0x7dcb, 0x7ddb, 0x7dda, 0x7dc2, 0x7dd3, 0x7de5, 0x7f7d, 0x7f7b, + 0x7fff, 0x0bf2, 0x7ff9, 0x8077, 0x807c, 0x8078, 0x807b, 0x807a, + 0x81d2, 0x81cb, 0x81c9, 0x81ce, 0x81e4, 0x81ca, 0x81d0, 0x61a5, + 0x0c49, 0x81d9, 0x81ee, 0x81dd, 0x8200, 0x81e1, 0x83de, 0x83e2, + 0x83da, 0x84ce, 0xca4f, 0x84cf, 0x84da, 0x84d1, 0x84d4, 0x84ed, + 0x84cb, 0x84d5, 0x84f1, 0x869c, 0x8688, 0x8741, 0x87d0, 0x87f7, + 0x87cf, 0x87d1, 0x87db, 0x87de, 0x87f8, 0x87dc, + /* 0x56 */ + 0x87d9, 0x89a0, 0x89b2, 0x89a1, 0x89aa, 0x89a9, 0x0da9, 0x89a6, + 0x899c, 0x89b5, 0x89a7, 0x8a8e, 0x8a90, 0x8a91, 0x8b85, 0x8b5b, + 0x8b70, 0x8b64, 0x8b67, 0x8b63, 0x8b77, 0x8b68, 0x8b65, 0x8b6a, + 0x8b78, 0x8b66, 0x8c88, 0x8c9e, 0x8c74, 0x8c7a, 0x8c79, 0x8c8b, + 0x8c7f, 0x8e13, 0x8e1e, 0x8e17, 0x8e1a, 0x8e22, 0x8e43, 0x8e19, + 0x8e1f, 0x8e27, 0x8e12, 0x8e24, 0x8e25, 0x365e, 0x8f35, 0x8f34, + 0x8fd1, 0x8fc4, 0x8fca, 0x8fc6, 0x8fcb, 0x8fcd, 0x8fe2, 0x9089, + 0x908b, 0x9086, 0x9088, 0x908d, 0x913b, 0x913c, 0x913d, 0x91f5, + 0x9279, 0x9275, 0x9282, 0x927f, 0x9285, 0x9276, 0x927c, 0x927e, + 0x927b, 0x9280, 0x927a, 0x5748, 0x0fcb, 0x931d, 0x93f6, 0x93f7, + 0x93f9, 0x9463, 0x946c, 0x946e, 0x9414, 0x100d, 0x9467, 0x946f, + 0x9469, 0x9476, 0x9495, 0x9471, 0x9461, 0x9478, + /* 0x57 */ + 0x946b, 0x9485, 0x9484, 0x9614, 0x9676, 0x89b6, 0x9675, 0x9674, + 0x96e2, 0x973f, 0x9744, 0x973d, 0x9747, 0x9748, 0x97db, 0x97dc, + 0x97dd, 0x98e5, 0x98e6, 0x99c2, 0x9a2e, 0x9a1d, 0x99f8, 0x99f0, + 0x99f6, 0x99c5, 0x99c6, 0x99fc, 0x9a52, 0x9a2f, 0x9a10, 0x99f3, + 0x99d2, 0x99ea, 0x99dc, 0x9a1b, 0x99fb, 0x99c3, 0x9a16, 0x9a07, + 0x99c9, 0x99d8, 0x9a30, 0x9a13, 0x9a31, 0x99fa, 0x99f2, 0x9ae3, + 0x99d5, 0x9a01, 0x99f1, 0x9a1c, 0x99d6, 0x9a08, 0x9a0b, 0x9a17, + 0x9a20, 0x99ca, 0x9a32, 0x9a05, 0x99e4, 0x99ce, 0x9a33, 0x9a02, + 0x9a19, 0x9a1e, 0x99d3, 0x99f7, 0x99e8, 0x9a1f, 0x99f4, 0x9ad8, + 0x9cbf, 0x9cbe, 0x9cbd, 0x9ddc, 0x9ddd, 0x9dab, 0x9dc9, 0x9dc8, + 0x9ddf, 0x9dd9, 0x9ddb, 0x9dcc, 0x9de0, 0x9def, 0x9df3, 0x9dae, + 0x9e01, 0x9fb7, 0x9fb9, 0x9fb6, 0x9fb8, 0x9ff6, + /* 0x58 */ + 0x9ff3, 0x9ff5, 0x9ff2, 0xa091, 0xa09d, 0xa09b, 0xa092, 0xa08d, + 0xa09e, 0xa08c, 0x1231, 0xcac7, 0xa095, 0xcac6, 0xa08a, 0xa08e, + 0xa09c, 0xa1ef, 0xa22d, 0xa252, 0xa235, 0xa228, 0xa22e, 0xa2e5, + 0xa3ea, 0xa3f1, 0xa3eb, 0xa3d8, 0xa3d0, 0xa3f3, 0xa3db, 0xa3ce, + 0x12d5, 0xa3da, 0xa3d7, 0xa3e1, 0xa3f2, 0xa3c8, 0xa3d9, 0xa3de, + 0xa3d1, 0xa3e7, 0xa3cf, 0xa5b7, 0xa647, 0xa642, 0xa643, 0xcad3, + 0xa6c3, 0xa6c1, 0xa6c7, 0xa764, 0xa76a, 0xa766, 0xa750, 0xa76e, + 0xa765, 0x69ec, 0xa77f, 0xcad5, 0xa79a, 0xa769, 0xa772, 0xa76f, + 0xa77d, 0xa770, 0xa860, 0xa8c2, 0xa8e7, 0xa8d1, 0xa8eb, 0xa8d4, + 0xa8dc, 0xa8db, 0xaa37, 0xaa25, 0xaa1f, 0xaa1e, 0xaa21, 0xaa1b, + 0xaa17, 0xaa22, 0xaa2a, 0xaa1a, 0xaa2d, 0xaa23, 0xaa26, 0xaa36, + 0xa9ff, 0xab3a, 0xab40, 0xab42, 0xab38, 0xab3b, + /* 0x59 */ + 0xab3c, 0xab43, 0xabe8, 0x1456, 0xabf9, 0xabeb, 0xabf1, 0xabe9, + 0xabec, 0xad15, 0xad47, 0xad46, 0xad45, 0xae24, 0xae56, 0xae21, + 0xae27, 0xae4d, 0xae31, 0xae1e, 0xae2c, 0xae4f, 0xae2b, 0xae53, + 0xae51, 0xae54, 0xae29, 0xae50, 0xae1f, 0xae32, 0xae2a, 0xae1d, + 0xae28, 0xae2e, 0xae2d, 0xafbc, 0xafbb, 0xafbd, 0xcae4, 0xb047, + 0xb041, 0xcae5, 0xb049, 0x14f4, 0xb12e, 0xb127, 0xb26a, 0xb27b, + 0xb273, 0xb275, 0xb269, 0xb279, 0xb272, 0xb376, 0xb377, 0xb374, + 0xb373, 0xb402, 0xb3fe, 0xb401, 0xb3f9, 0xb3f4, 0xb5d3, 0xb5d5, + 0xb5d8, 0xb5c3, 0xb5ca, 0xb5d0, 0xb5cb, 0xb5ce, 0xb5c5, 0xb5e6, + 0xb5c4, 0xb5c0, 0xb5d4, 0xb5e8, 0xb676, 0xb6a2, 0xb6ae, 0xb6a8, + 0xb6a3, 0xb6a7, 0xb696, 0xb6a9, 0xb6a5, 0xb6af, 0xb6a4, 0xb6ab, + 0xb6aa, 0xb6a6, 0xb6a0, 0xb798, 0xb8db, 0xb8f6, + /* 0x5a */ + 0xb8f5, 0xb90c, 0xb90a, 0x3175, 0xb968, 0xb963, 0xb966, 0x1658, + 0xb964, 0xb96a, 0xb969, 0xba95, 0xbb02, 0xbb6a, 0xbb5e, 0xbb68, + 0xbb69, 0xbb65, 0xcafe, 0xbca7, 0xbcae, 0xbca8, 0xbcb3, 0xbd9c, + 0xbda9, 0xbdb6, 0xbdb3, 0xbdb2, 0xcb03, 0xbdb8, 0xbdc0, 0xbdbf, + 0xbdba, 0xbda8, 0xbe3c, 0xbe72, 0xbe71, 0xbe75, 0xbe73, 0xbf17, + 0xbf15, 0xbf16, 0xbf1b, 0xbffa, 0xbff9, 0xc12c, 0xc185, 0xc182, + 0xc17f, 0xc17d, 0xc188, 0x72f3, 0xc24e, 0xc250, 0xc393, 0xc397, + 0xc398, 0xc39b, 0xc39c, 0xc396, 0xc58b, 0xc5fd, 0xc5fc, 0xcb17, + 0x6a8b, 0x3408, 0x3407, 0x3673, 0x36a2, 0x36af, 0x3682, 0x367b, + 0x3674, 0x36b0, 0x3676, 0x36b9, 0x369e, 0x36b1, 0x36a1, 0x36b2, + 0x366e, 0xc90b, 0x0087, 0x3678, 0x367a, 0x3683, 0x369a, 0x37f8, + 0x3831, 0x3869, 0x3868, 0x389c, 0x3904, 0x3999, + /* 0x5b */ + 0x3ac7, 0x3ac6, 0x3adc, 0x3ac4, 0x3ad8, 0x3ad4, 0x3adf, 0x3ad1, + 0x3ad0, 0x3ad6, 0x3acf, 0x3bad, 0x3baf, 0x3ba7, 0x3bfd, 0x3c5b, + 0x3c5a, 0x3d07, 0x3d9d, 0x3d9b, 0x3dab, 0x3da4, 0x3d9c, 0x3d9e, + 0x3da5, 0x3daa, 0x3da6, 0x3e0e, 0x3e7e, 0x3e7c, 0x41ee, 0x41d5, + 0x41e9, 0x4142, 0x41e2, 0x4223, 0x41d9, 0x41d4, 0x41e3, 0x4215, + 0x41ef, 0x41f0, 0x41d6, 0x41dd, 0x41f6, 0x421c, 0x41d8, 0x41db, + 0x41da, 0x41ed, 0x4611, 0x4415, 0x4418, 0x441a, 0x441f, 0x4416, + 0xc94d, 0x4419, 0xc94b, 0x45f0, 0x4609, 0x461b, 0xa5e7, 0x45f6, + 0x45f4, 0x45b5, 0x4610, 0x45f2, 0x4615, 0x45f3, 0x45f8, 0x4739, + 0x473b, 0x4736, 0x460e, 0x4772, 0x4774, 0x47b9, 0x47b7, 0x47b8, + 0x4872, 0x486b, 0x4a1d, 0x4a37, 0x4a22, 0x4a43, 0x4a4d, 0x4a38, + 0x4a5b, 0x4a79, 0x4a1b, 0x49f3, 0x4b91, 0x4c7b, + /* 0x5c */ + 0x4c94, 0xc96f, 0x4c96, 0x4c7f, 0x4c8f, 0x4c84, 0x4c7c, 0x4c8e, + 0x4c90, 0x4c98, 0x4c83, 0x4c80, 0x4c93, 0x4c82, 0x32fd, 0x4d3d, + 0x4d41, 0x4da1, 0x4d9f, 0x4e0a, 0x4e0d, 0x4ec8, 0x4ec9, 0x4ec7, + 0x4ecd, 0x4f25, 0x50b1, 0x50dc, 0xc980, 0x50e5, 0x50f4, 0x50bf, + 0x50db, 0x50ea, 0x50f2, 0x03fa, 0x50f1, 0x50ed, 0x50e6, 0x5202, + 0xc982, 0x5325, 0x5318, 0x531f, 0x5320, 0x53cf, 0x549d, 0x5499, + 0x54a8, 0x5568, 0x5566, 0x5567, 0x5591, 0x5613, 0x5615, 0x561d, + 0x5616, 0x5619, 0x566b, 0x5668, 0x566a, 0x566d, 0x5669, 0x56aa, + 0x5757, 0x5752, 0x5750, 0x575f, 0x5767, 0x574f, 0x04f2, 0x575b, + 0x575c, 0x575d, 0x5a1f, 0x599d, 0x59b1, 0x59b0, 0x5994, 0x59c3, + 0x59af, 0x59a8, 0x59dc, 0x5998, 0x59c4, 0x59a4, 0x59ab, 0x59aa, + 0x59a5, 0x5a21, 0x59eb, 0x59e6, 0x59f7, 0x59f8, + /* 0x5d */ + 0x59fc, 0x59fa, 0x59e0, 0xc9aa, 0x59f6, 0xc9a9, 0x59e1, 0x5bec, + 0x5be2, 0x5be4, 0x5bf9, 0x5e6f, 0x6b4c, 0x5ebb, 0x5ee1, 0x5f00, + 0x5ed8, 0x062f, 0x5ed6, 0x5ee2, 0x5ec3, 0x5eb3, 0x5ed2, 0xc9c1, + 0x5ece, 0x5ed0, 0x5ed5, 0x5eb9, 0x5eba, 0x5ecf, 0x5ebd, 0x60db, + 0x61aa, 0x61ad, 0x61b8, 0x61b6, 0x61b5, 0x61af, 0x61b4, 0x61b7, + 0x61a8, 0x61b9, 0x61be, 0x6282, 0x62bc, 0x62b8, 0x62b6, 0x62b9, + 0x06c1, 0x6310, 0x6427, 0x6469, 0x6470, 0x6456, 0x646b, 0x647a, + 0x646c, 0x646d, 0xc9d5, 0x94c1, 0x658d, 0x6590, 0x67b6, 0x6810, + 0x6812, 0x67ba, 0x67bd, 0x6805, 0x67c2, 0x6807, 0x67f5, 0xc9e9, + 0x67af, 0x67f4, 0x67f7, 0x67f8, 0x6811, 0x69f6, 0x69f5, 0x69fb, + 0x6a01, 0x6a00, 0x6a02, 0x69fe, 0x69fa, 0x69fd, 0x0840, 0x6b37, + 0x6b49, 0x6b4b, 0x6b46, 0x6b47, 0x6bb3, 0x6bb2, + /* 0x5e */ + 0x6bb0, 0x6bb7, 0x6c11, 0x6ccc, 0x6cdf, 0x6cd3, 0x6cd5, 0x6cdb, + 0x6cc5, 0x6cc8, 0x6cc9, 0x6ce2, 0x6cca, 0x6cd1, 0x6cd2, 0x6cdd, + 0x6f6c, 0x6f73, 0x7021, 0x6ff0, 0x701f, 0x703b, 0x7022, 0x7023, + 0x6fe8, 0x6fdd, 0x093f, 0x701b, 0x6fed, 0xca0e, 0x6ff2, 0x0946, + 0x6fdc, 0x6fe9, 0x701d, 0x6fda, 0x6fe6, 0x7313, 0x7315, 0x7316, + 0x733c, 0x730b, 0x731c, 0x733a, 0x733d, 0x739a, 0x731d, 0x7309, + 0x7308, 0x733b, 0x7522, 0x7526, 0x7525, 0x7524, 0x369b, 0x758f, + 0x7590, 0x75e6, 0x75e3, 0x75e5, 0x7611, 0xca25, 0x76ae, 0x76be, + 0x76b4, 0x76b3, 0x76af, 0x7691, 0x76c2, 0x76b6, 0x76b2, 0x7857, + 0x783b, 0x7858, 0x7851, 0x7841, 0x7839, 0x0a8f, 0x7859, 0x7845, + 0x7861, 0x78e8, 0x79fa, 0x79ea, 0x79ef, 0x79f2, 0x79f0, 0x7b08, + 0x7b70, 0x7b6a, 0x7b73, 0x7b68, 0x7bc8, 0x7bf2, + /* 0x5f */ + 0x3e7b, 0x7cae, 0x7cab, 0x7cb5, 0x7caf, 0x7cb2, 0x7cb6, 0x7cb0, + 0x7d1e, 0x7e03, 0x7e06, 0x7e1f, 0x0bac, 0x7e0f, 0x7e02, 0x7e19, + 0x7e18, 0x7e22, 0x7e15, 0x7e07, 0x7e0d, 0x7e24, 0x7e0c, 0x7e1e, + 0x7f89, 0x7f8a, 0x800a, 0x800b, 0x8007, 0x8004, 0x8009, 0x8084, + 0x8083, 0x8218, 0x8214, 0x8205, 0x8216, 0x820e, 0x8211, 0x8208, + 0x820b, 0x8215, 0x8085, 0x8237, 0x822a, 0x820d, 0x820f, 0x837e, + 0x8376, 0x8377, 0x83ec, 0x84fc, 0x8508, 0x84ff, 0x8503, 0x8510, + 0x8505, 0x8506, 0x84fa, 0x86c7, 0x86c0, 0x86c3, 0x86a7, 0x86a8, + 0x86ab, 0x86c1, 0x86aa, 0x86c8, 0x8743, 0x8802, 0x880e, 0x8801, + 0x87fe, 0x8803, 0x0d68, 0x8822, 0x8821, 0x8807, 0x8808, 0x880c, + 0x89ca, 0x89bc, 0x89be, 0x89bd, 0xca5c, 0x89bb, 0x89b9, 0x0dab, + 0x89c5, 0x8a99, 0x8b6b, 0x8b93, 0x8b94, 0x8ba9, + /* 0x60 */ + 0x8ba0, 0x8ba6, 0xca61, 0x8bab, 0x8b9e, 0x8b9b, 0x8b91, 0x8b99, + 0x8cb6, 0x8cb8, 0x8c9a, 0x0e91, 0x8c98, 0x8c9b, 0x8cb3, 0x8ca2, + 0x54aa, 0x8ca0, 0x8c9f, 0x8e5b, 0x8e70, 0x8e54, 0x8e71, 0x8e65, + 0x8e51, 0x8e9d, 0x8e61, 0x8e5a, 0x8e74, 0x8e4c, 0x8e4b, 0x8e5e, + 0x8e58, 0x8e53, 0x8e52, 0x8f3b, 0x8f39, 0x8fd6, 0x8fe7, 0x8fd7, + 0x8fd8, 0x8fd9, 0x8fda, 0x8fdb, 0x8fdc, 0x8fe0, 0x8fe4, 0x8fdd, + 0x8ff5, 0x8ff1, 0x9098, 0x909d, 0x9099, 0x9150, 0x9149, 0x27e4, + 0x9162, 0x91d7, 0x9201, 0x91f7, 0xca7d, 0x928c, 0x929c, 0x2888, + 0x931f, 0x931e, 0x943d, 0x943f, 0x9411, 0x9459, 0x943e, 0x9458, + 0x9500, 0x949e, 0x94b6, 0x94aa, 0x94af, 0x94ac, 0x1030, 0x94c0, + 0x94a9, 0x3e10, 0x95ee, 0x9677, 0x9679, 0x967a, 0x967d, 0x967f, + 0x9683, 0x9678, 0x967e, 0x96e4, 0x96e6, 0x96e5, + /* 0x61 */ + 0x105d, 0x974e, 0x9759, 0x1075, 0xca8e, 0x974f, 0x974a, 0x97e3, + 0x97de, 0x97e2, 0x9974, 0x99ac, 0x9961, 0x9962, 0x9976, 0x997a, + 0x9979, 0x9960, 0x9a64, 0x9b81, 0x9adf, 0x9a84, 0x9a8a, 0x9a92, + 0x9a79, 0x9ade, 0x9a98, 0x9a6c, 0x9ae1, 0xcaa5, 0x9a7c, 0x9a72, + 0x9a81, 0x9ae0, 0x9a65, 0x10ff, 0x9a6a, 0x9a97, 0x9aaa, 0x9ad3, + 0x9aab, 0x9a6e, 0x9aac, 0x9a76, 0x9a7b, 0x9aad, 0xcaa6, 0x9a94, + 0x9ad7, 0x9a70, 0x9ad5, 0x9af1, 0x9a7a, 0x9a68, 0x9a96, 0x110b, + 0x9a73, 0x9aae, 0x9add, 0x9ada, 0x9aaf, 0x9ab0, 0x9adb, 0x9a62, + 0x9af8, 0x9cc2, 0x9cc7, 0x9cc8, 0x9cc5, 0x9cc3, 0x9cc6, 0x9dde, + 0x11c8, 0x9e11, 0x9e15, 0x9e28, 0x9e21, 0x9e2d, 0x9e51, 0x9e2b, + 0x9e16, 0x9e24, 0x9e35, 0x9e1f, 0x9e12, 0x9e10, 0x9e80, 0x9e3b, + 0x9e29, 0x9e2a, 0x9e1b, 0x9e18, 0x9e20, 0x9e3f, + /* 0x62 */ + 0x9e1c, 0x9e26, 0x9e0b, 0x9fbe, 0x9fc4, 0x9fbd, 0x9ffa, 0x9ffb, + 0xa0b1, 0xa0b2, 0xa0b0, 0xa0b9, 0xa0a6, 0xa0bd, 0xa0b6, 0xa0b8, + 0xa0b4, 0xa0b3, 0xa0a7, 0xa0ae, 0xa0bc, 0xa1f2, 0xa1f3, 0xa1f4, + 0xa23b, 0xa240, 0xa246, 0xa2f0, 0xa2ee, 0xa2e8, 0xa2f1, 0xa2eb, + 0xa2ef, 0xa3fc, 0xa420, 0xa409, 0xa406, 0xa403, 0xcacf, 0xa419, + 0xa424, 0xa41b, 0xa41d, 0xa3fd, 0xa41e, 0xa3f4, 0xa401, 0xa408, + 0xa405, 0xa423, 0xa3ff, 0xa5ea, 0xa64d, 0xa64e, 0xa656, 0xa657, + 0xa651, 0xa655, 0xa654, 0xa6cb, 0xa6d4, 0xa6d1, 0xa6cf, 0xa6d2, + 0xa6ca, 0xa6d6, 0xa78b, 0xa788, 0xa785, 0xa789, 0x4c9b, 0xa7bb, + 0xa78c, 0x1374, 0xa799, 0xa78a, 0xa8ec, 0xa8ef, 0xa8f9, 0xa909, + 0xa8f8, 0xa8f3, 0xa900, 0xa91d, 0x13ac, 0xa8fd, 0xaa48, 0xaa5c, + 0xaa55, 0xaa5e, 0xaa49, 0xaa63, 0xaa60, 0xaa53, + /* 0x63 */ + 0xaa62, 0xaa40, 0xab49, 0xab4a, 0xab4c, 0xab4d, 0xac0a, 0xac06, + 0xac2f, 0xac21, 0xac07, 0xac09, 0xac02, 0xac16, 0xac03, 0xac0b, + 0xac0f, 0xae60, 0xae68, 0xae5e, 0xae5d, 0xae63, 0xae5f, 0xae64, + 0xae78, 0xae61, 0xae69, 0xae65, 0xafda, 0xafe6, 0xafdb, 0xafdc, + 0xb039, 0xb057, 0xb055, 0xb065, 0xb061, 0xb054, 0xb145, 0xb141, + 0xb13e, 0xb137, 0xb212, 0xb213, 0xb22c, 0xb296, 0xcae9, 0xb29c, + 0xb29d, 0xb285, 0xcae8, 0xb29f, 0xb2a3, 0xb382, 0xb383, 0xcaee, + 0xb41d, 0xb414, 0xb41f, 0xb420, 0xb547, 0xb580, 0xb5c9, 0xb5f9, + 0xb606, 0xb5f0, 0xb5f8, 0xb5ef, 0xb5fd, 0xb5f1, 0xb5fe, 0xb6b8, + 0xb6c0, 0xb6c3, 0xb6b5, 0xb6b6, 0xb6c9, 0xcaf3, 0xb6bd, 0xb6ba, + 0xb6bf, 0xb6b3, 0xb6c6, 0xb6b2, 0xb6bc, 0xb6b7, 0xb6b9, 0xb6c8, + 0xb7b5, 0xb7b3, 0x1616, 0xb7ac, 0xb7a9, 0xb7ad, + /* 0x64 */ + 0xb911, 0xb90d, 0xb916, 0xb989, 0xb97c, 0xb98b, 0xb97b, 0xb988, + 0xb984, 0xba9d, 0xba98, 0xbb88, 0xbb86, 0xbb82, 0xbb8b, 0xcaff, + 0xbb71, 0xbb72, 0xbb81, 0xbb8c, 0xbb80, 0xbb89, 0xbcbb, 0xbcc1, + 0xbcbe, 0xcb01, 0xbcbd, 0xbdc1, 0xbdb4, 0xbdb7, 0xbdc8, 0x173b, + 0xbdd3, 0xbdd0, 0xbdb0, 0xbdca, 0xbdcd, 0xbe15, 0xbe19, 0xbe17, + 0xbe3f, 0xbe40, 0xbe44, 0xbe7c, 0xbe78, 0xbe79, 0xbe88, 0xcb06, + 0xbe89, 0xbe7d, 0xbf23, 0xbf24, 0xbf26, 0xbf22, 0xbf27, 0xbf1f, + 0xbfc9, 0xbfc3, 0xc00a, 0xc00b, 0xc004, 0x17ef, 0xc003, 0xc001, + 0xc009, 0xc10f, 0xc12e, 0xc12d, 0xc191, 0xc199, 0xc19e, 0xc190, + 0xc194, 0xc19d, 0xc198, 0xc19b, 0xc19c, 0xc19a, 0xc254, 0xc39d, + 0xc39f, 0xc3a3, 0xc3a4, 0xc3a5, 0xc602, 0xc717, 0xc71b, 0xc719, + 0xc7d1, 0x4737, +}; + +static const ucs4_t cns11643_6_2uni_upages[204] = { + 0x03400, 0x03500, 0x03600, 0x03700, 0x03800, 0x03900, 0x03a00, 0x03b00, + 0x03c00, 0x03d00, 0x03e00, 0x03f00, 0x04000, 0x04100, 0x04200, 0x04300, + 0x04400, 0x04500, 0x04600, 0x04700, 0x04800, 0x04900, 0x04a00, 0x04b00, + 0x05100, 0x05300, 0x05500, 0x05a00, 0x05b00, 0x05d00, 0x05e00, 0x06100, + 0x06500, 0x06800, 0x06e00, 0x07200, 0x07300, 0x07800, 0x07a00, 0x07f00, + 0x08000, 0x08100, 0x08200, 0x08800, 0x08900, 0x08a00, 0x08d00, 0x08f00, + 0x09200, 0x09700, 0x0ff00, 0x20000, 0x20100, 0x20200, 0x20300, 0x20400, + 0x20500, 0x20600, 0x20700, 0x20800, 0x20900, 0x20a00, 0x20b00, 0x20c00, + 0x20d00, 0x20e00, 0x20f00, 0x21100, 0x21200, 0x21300, 0x21400, 0x21500, + 0x21600, 0x21700, 0x21800, 0x21900, 0x21a00, 0x21b00, 0x21c00, 0x21d00, + 0x21e00, 0x21f00, 0x22000, 0x22100, 0x22200, 0x22300, 0x22400, 0x22500, + 0x22600, 0x22700, 0x22800, 0x22900, 0x22a00, 0x22b00, 0x22c00, 0x22d00, + 0x22e00, 0x22f00, 0x23000, 0x23100, 0x23200, 0x23300, 0x23400, 0x23500, + 0x23600, 0x23800, 0x23900, 0x23a00, 0x23b00, 0x23c00, 0x23d00, 0x23e00, + 0x23f00, 0x24100, 0x24200, 0x24300, 0x24400, 0x24500, 0x24600, 0x24700, + 0x24800, 0x24900, 0x24a00, 0x24b00, 0x24c00, 0x24d00, 0x24e00, 0x24f00, + 0x25000, 0x25100, 0x25200, 0x25300, 0x25400, 0x25500, 0x25600, 0x25700, + 0x25800, 0x25900, 0x25a00, 0x25b00, 0x25e00, 0x25f00, 0x26000, 0x26200, + 0x26300, 0x26400, 0x26500, 0x26600, 0x26700, 0x26800, 0x26900, 0x26a00, + 0x26b00, 0x26c00, 0x26d00, 0x26e00, 0x27100, 0x27200, 0x27300, 0x27500, + 0x27600, 0x27700, 0x27800, 0x27900, 0x27a00, 0x27b00, 0x27c00, 0x27d00, + 0x27e00, 0x27f00, 0x28000, 0x28200, 0x28300, 0x28400, 0x28500, 0x28600, + 0x28700, 0x28800, 0x28900, 0x28c00, 0x28d00, 0x28e00, 0x28f00, 0x29000, + 0x29100, 0x29200, 0x29300, 0x29400, 0x29500, 0x29600, 0x29800, 0x29a00, + 0x29b00, 0x29c00, 0x29d00, 0x29f00, 0x2a000, 0x2a200, 0x2a300, 0x2a400, + 0x2a500, 0x2f800, 0x2f900, 0x2fa00, +}; + +static int +cns11643_6_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x21 && c1 <= 0x64)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + ucs4_t wc = 0xfffd; + unsigned short swc; + { + if (i < 6388) + swc = cns11643_6_2uni_page21[i], + wc = cns11643_6_2uni_upages[swc>>8] | (swc & 0xff); + } + if (wc != 0xfffd) { + *pwc = wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + diff --git a/libs/libiconv/lib/cns11643_7.h b/libs/libiconv/lib/cns11643_7.h new file mode 100644 index 00000000..44532bc4 --- /dev/null +++ b/libs/libiconv/lib/cns11643_7.h @@ -0,0 +1,988 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CNS 11643-1992 plane 7 + */ + +static const unsigned short cns11643_7_2uni_page21[6539] = { + /* 0x21 */ + 0x2b55, 0x2c82, 0x2c89, 0x2c87, 0x2dbe, 0x2dbd, 0x2dca, 0x2dd4, + 0x2dbc, 0x2dc4, 0x2dc1, 0x2dc2, 0x2dd7, 0x2d70, 0x2dba, 0x2de3, + 0x2dbb, 0x2eb1, 0x2eb6, 0x2eb0, 0x2f6c, 0x300d, 0x3007, 0x31f1, + 0x31f5, 0x31ed, 0x31ef, 0x31eb, 0x31ec, 0x31ee, 0x3207, 0x33c4, + 0x3408, 0x34b3, 0x34ad, 0x34b0, 0x3511, 0x2c8a, 0x3683, 0x367a, + 0x3682, 0x3668, 0x3671, 0x36b0, 0x36af, 0x01f6, 0x366c, 0x366f, + 0x3662, 0x3665, 0x3681, 0x367f, 0x3664, 0x3673, 0x366e, 0x3667, + 0x3674, 0x367d, 0x3678, 0x3685, 0x36aa, 0x3688, 0x36a6, 0xc34e, + 0x368a, 0x3684, 0x1a55, 0x3924, 0x3922, 0x3923, 0x3a32, 0x3a5b, + 0x3a4f, 0x0267, 0x3a26, 0x3a3e, 0x3a42, 0x3a47, 0x3a22, 0x309b, + 0x3a4a, 0x3a1f, 0x3a49, 0x3a2b, 0x3a33, 0xc358, 0x3a2a, 0x3a28, + 0x3b3d, 0x3b3c, 0x3bbf, 0x3c79, 0x3c80, 0x3c7c, + /* 0x22 */ + 0x3c7a, 0x3c78, 0x3d82, 0x3d5c, 0x3d5a, 0x3d4b, 0x3d7c, 0x3d7f, + 0x3d1f, 0x3d89, 0x3d8b, 0x3d57, 0x3d7e, 0x3d7d, 0x3d53, 0x3f9f, + 0x3fbc, 0x3fa5, 0x3f86, 0x3fdc, 0x3fa4, 0x3fb6, 0x3fa2, 0x3fb4, + 0x4048, 0x4046, 0x40a7, 0x4114, 0x4112, 0x4111, 0x41e1, 0x41d0, + 0x4226, 0x4228, 0x4229, 0x432f, 0x430d, 0x4325, 0x4314, 0x433c, + 0x430b, 0x4311, 0x4330, 0x4318, 0x4319, 0x4336, 0x4317, 0x4310, + 0x4315, 0x4403, 0x4429, 0x444c, 0x453f, 0x453e, 0x4534, 0x4542, + 0x4535, 0x31f3, 0x45cd, 0x45d1, 0x45d2, 0x46ad, 0x46ba, 0x46c1, + 0x46bb, 0x46b4, 0x46bc, 0x476c, 0x4792, 0x4821, 0x4824, 0x5f19, + 0x48ad, 0x48ae, 0x48ab, 0x48ac, 0x4970, 0x4976, 0x4971, 0x4977, + 0x1c7f, 0x4aec, 0x4b1c, 0x4afb, 0x4aee, 0x4be2, 0x4afd, 0x4b1e, + 0x4b3b, 0x4b4a, 0xc3ae, 0x0592, 0x4b7d, 0x4b56, + /* 0x23 */ + 0x4b44, 0x4b4b, 0x4cfa, 0x4ce8, 0x4cf8, 0x4cff, 0x4cf7, 0x4cf6, + 0x4cfe, 0x4d07, 0x4d5d, 0x4ed4, 0xc3c3, 0x4ec8, 0x4ec5, 0xc3c0, + 0x4ec9, 0x4f4d, 0x4f20, 0x4f36, 0x4f35, 0x4f88, 0x4f25, 0x4f21, + 0x4f26, 0x0645, 0x4f3f, 0x4f3b, 0x4f24, 0x4f43, 0x4f4e, 0x4f4f, + 0x4f44, 0x4f40, 0x4f41, 0x4f39, 0x4f2b, 0x50dd, 0x50de, 0x51cd, + 0x51cb, 0x51db, 0x51d8, 0x51d9, 0x51d2, 0x51ca, 0x51d1, 0x51d4, + 0x51f9, 0x51d0, 0x525e, 0x525d, 0x528a, 0x5314, 0x5483, 0x5484, + 0x549b, 0x5482, 0x547d, 0x547c, 0x5499, 0x547e, 0x549a, 0x5495, + 0x547b, 0x5486, 0x5548, 0x5592, 0x56b2, 0x5742, 0x5772, 0x5715, + 0x5730, 0x5743, 0x575b, 0x571d, 0x5773, 0x572d, 0x07c9, 0x5721, + 0x571c, 0xc3ea, 0x5729, 0x571e, 0x5733, 0x5a10, 0x5a0e, 0xc3f1, + 0x5a0d, 0x5a11, 0x5a12, 0x5a17, 0x5a09, 0x5a0f, + /* 0x24 */ + 0x5a98, 0x5a94, 0x5a96, 0x5a99, 0x5a95, 0x5a97, 0x5b50, 0x5b52, + 0x5b4d, 0x5b57, 0x5b53, 0x5b56, 0x5bb8, 0x5c12, 0x5cf1, 0x5cf0, + 0x5cee, 0x5cef, 0x5ce5, 0x5ceb, 0x5ce7, 0x5cf2, 0x5ce6, 0x5cf7, + 0x5d09, 0x5d6b, 0x5d6a, 0x5e79, 0x5ecd, 0x5eef, 0x5ee4, 0x5ee3, + 0x5f6c, 0x5f67, 0x5f62, 0x5f58, 0x5f69, 0x5fab, 0x5f57, 0x5fad, + 0x5f54, 0x5fae, 0x5f76, 0x5f49, 0x5f45, 0x5f4f, 0xc40f, 0x5f50, + 0x5f7d, 0x5f44, 0x5f66, 0x5f48, 0x5fa3, 0x5f51, 0x5f53, 0xc410, + 0x5f60, 0x5f47, 0x5f5e, 0x5f85, 0x5fac, 0x5f6d, 0x5f75, 0x5fa8, + 0x0955, 0x5f43, 0x5f4e, 0x5f5c, 0x5f56, 0x5f6e, 0x5f63, 0x5f6a, + 0x6256, 0x6212, 0x625c, 0x6258, 0x6255, 0x627e, 0x62a8, 0x6211, + 0x6259, 0x625a, 0x6267, 0x6254, 0x625b, 0x62f0, 0x6429, 0x642c, + 0x642a, 0x6427, 0x6467, 0x6468, 0x6493, 0x6495, + /* 0x25 */ + 0x649a, 0x64ee, 0x64f1, 0x64ed, 0x64e9, 0x65cb, 0x65df, 0x65db, + 0x673c, 0x674e, 0x676c, 0x677b, 0x677c, 0x6783, 0x676b, 0x6766, + 0x6763, 0x67a0, 0x6785, 0x6768, 0x67a2, 0x68ec, 0x0ae8, 0x68e7, + 0x6910, 0x6918, 0x693a, 0x691a, 0x6938, 0x6941, 0x691b, 0x6914, + 0x691c, 0x691d, 0x6a12, 0x6a0d, 0x6a07, 0x6a7e, 0x6a7f, 0x34b9, + 0x6a80, 0x6a7a, 0x6af3, 0x6bb9, 0x6bbb, 0x6bba, 0x6bbd, 0x6bb7, + 0x6bbf, 0x6c21, 0x6d3a, 0x6d3d, 0x6d36, 0x6d49, 0x6d81, 0x0bb6, + 0x6d3f, 0x6d4d, 0x6d3e, 0x0bbd, 0x6d30, 0x6d4f, 0x6e37, 0x6e98, + 0x6e99, 0x6f11, 0x6f0d, 0x6f88, 0x6f8a, 0x701c, 0x7055, 0x7056, + 0x7062, 0x7057, 0x7042, 0x7010, 0x704d, 0x705a, 0x7066, 0x7046, + 0x4b7e, 0x704f, 0x80f9, 0x7187, 0x7184, 0x71f4, 0x71f5, 0x71f2, + 0x71f7, 0x7345, 0xc450, 0x7349, 0x7335, 0x72fd, + /* 0x26 */ + 0x7330, 0x7343, 0x7346, 0x0cd6, 0x7333, 0x74c6, 0xc456, 0x74d4, + 0x8dd8, 0x74e0, 0x36a7, 0x7544, 0x2d98, 0x7654, 0x763e, 0x7635, + 0x763a, 0x0d71, 0x7634, 0x7639, 0x7646, 0x765a, 0x765b, 0x763c, + 0x77dc, 0x77d6, 0x77d0, 0xc45e, 0x78ac, 0xc45d, 0x78a5, 0x79f4, + 0x7a24, 0x79e0, 0x79fd, 0x79f2, 0x79fc, 0x7a02, 0x79f1, 0x79ff, + 0x79d2, 0x79d8, 0x79d3, 0x79f9, 0xc463, 0x79ed, 0x79f7, 0x79f0, + 0x79d7, 0x7a09, 0x79f5, 0x7cc2, 0x7cc5, 0x7ccf, 0x0e98, 0x7cc1, + 0x7cc6, 0x7cd4, 0x7cce, 0x7e9b, 0x7e99, 0x7e8f, 0x7eb7, 0x7e82, + 0x7e93, 0x7eb4, 0x7ec1, 0x7e90, 0x7e9a, 0x7e94, 0x7e9c, 0x7eb5, + 0xc46f, 0xc46e, 0x7e9f, 0x7e8e, 0x7e9e, 0x803c, 0x8047, 0x8041, + 0x80eb, 0x80ec, 0x80ed, 0x80ee, 0x80df, 0x80f2, 0x810d, 0x810e, + 0x2c86, 0x81a9, 0x81a4, 0x81a5, 0x825f, 0x825a, + /* 0x27 */ + 0x8266, 0x8268, 0x826a, 0x8264, 0x8265, 0x82c1, 0x82d8, 0xc47b, + 0x82d9, 0x8309, 0x83aa, 0x83a3, 0x83b9, 0x77e2, 0x83a5, 0x83ab, + 0x8420, 0x8589, 0x858b, 0x85db, 0x85e4, 0x85ef, 0x85e2, 0x85e9, + 0x85f0, 0x85f3, 0x85dd, 0x861e, 0x871d, 0x8746, 0x877c, 0x8780, + 0x8781, 0x8782, 0x8787, 0x8788, 0x878a, 0x878c, 0x87e7, 0x87eb, + 0x87ea, 0x8868, 0x886b, 0x8869, 0x8866, 0x886a, 0x8865, 0x88e5, + 0x88e4, 0x88e6, 0x8918, 0x8a24, 0x8a48, 0x8a2f, 0x8a7e, 0x8989, + 0x8a1e, 0x8a49, 0x8a26, 0x8a09, 0x8a34, 0x8a2d, 0x8a4a, 0x8a15, + 0xc4a9, 0x8a33, 0x8a28, 0x8a27, 0x8a20, 0x8a2b, 0x8a29, 0x8a6a, + 0x8a0b, 0x8a0e, 0x8a1c, 0x89ff, 0xc4aa, 0x8a35, 0x8a11, 0x8a4b, + 0x8a4c, 0x8a1f, 0x8a0f, 0x8a39, 0x8a68, 0x8a1d, 0x8a08, 0x8a0c, + 0x8a0d, 0x8a62, 0x8aaf, 0x8a32, 0x8a2c, 0x8a64, + /* 0x28 */ + 0x8a04, 0x8a16, 0x8a4d, 0x8a07, 0x8aae, 0x8dd4, 0x8dd1, 0x8dd5, + 0x8dd0, 0x8f71, 0x8f5d, 0x8f5b, 0x8f7a, 0xc4bd, 0x8f7f, 0x8f79, + 0x8f67, 0x8f9e, 0x8f94, 0x8f64, 0x8f5e, 0x8f81, 0x8f5a, 0x8f57, + 0x8f7c, 0x8f98, 0x8f66, 0x8f7e, 0x8f82, 0x8f68, 0x8f5f, 0x8f63, + 0x8f97, 0x11cd, 0x8f53, 0x8f7b, 0x8f7d, 0x8f78, 0x9006, 0x91c0, + 0x91c2, 0x91c3, 0x92dc, 0x92e6, 0x92ec, 0x92f2, 0x92e8, 0x92eb, + 0x92ea, 0x92e5, 0x92e0, 0x92d0, 0x92d8, 0x92d5, 0x92d3, 0x92e4, + 0x92f3, 0x92db, 0x932f, 0x93f9, 0x945d, 0x945b, 0x944c, 0x9458, + 0x9460, 0x9453, 0x9450, 0x9507, 0x9508, 0x94f4, 0x94f6, 0x9504, + 0x94fd, 0x9505, 0x9628, 0x9656, 0x9642, 0x965c, 0x963d, 0x962f, + 0x962b, 0x9658, 0x9661, 0x962c, 0x9651, 0x9650, 0x963c, 0x9636, + 0x12f6, 0x9660, 0x965b, 0x962e, 0x9640, 0x965f, + /* 0x29 */ + 0x9626, 0x962d, 0x965e, 0x963b, 0x97ef, 0x97f3, 0x97ee, 0x97ed, + 0x985a, 0x9862, 0x985b, 0x985f, 0x985e, 0x9864, 0x98e0, 0x98e1, + 0x98e5, 0x99a5, 0x999b, 0x999f, 0x999c, 0x137a, 0x99aa, 0x99a4, + 0x99a3, 0x9a67, 0x9b26, 0x9b1a, 0x13b8, 0x9b1c, 0x9b15, 0x9b1b, + 0x9b18, 0x9b1e, 0x9b25, 0xc4dc, 0x9c7b, 0x9c75, 0x9c93, 0x9c8f, + 0x9c7c, 0x9c9b, 0x9c88, 0x9c91, 0x9c7e, 0x1401, 0x9c86, 0x9e5b, + 0x9e54, 0x9f35, 0x9f40, 0x9f37, 0x9f29, 0x9f26, 0x9f23, 0x9f30, + 0x9f20, 0x9f28, 0x9f32, 0x9f2a, 0x9f31, 0x9f24, 0x9f41, 0x9f42, + 0x9f43, 0x9f25, 0x9f38, 0xa01c, 0xa01d, 0xa01e, 0xa0f6, 0xa1a5, + 0xa189, 0xa19d, 0xa18a, 0xa187, 0xa1ab, 0xa186, 0xa19e, 0xa193, + 0xa1a1, 0xa188, 0xa1a3, 0xa19f, 0xa1a0, 0xa2ff, 0xa300, 0xa302, + 0xa2f8, 0xa2f7, 0xa301, 0xa387, 0xa389, 0xa376, + /* 0x2a */ + 0xa36e, 0xa377, 0xa382, 0xa385, 0xa383, 0xa384, 0xa457, 0xa44b, + 0xa456, 0xa45d, 0xa460, 0xa44d, 0xa455, 0xa454, 0xa453, 0xa450, + 0xa463, 0xa462, 0xa517, 0xa516, 0xa52d, 0xa5d9, 0xa5bf, 0x152f, + 0xa5b2, 0xa5ac, 0xa5b0, 0xa5cf, 0xa5b8, 0x1531, 0xa5d3, 0xa5b1, + 0xa5af, 0xa5ce, 0xa5b4, 0xa5b7, 0xa5d5, 0x159c, 0xa938, 0xa928, + 0xa93f, 0xa940, 0xa941, 0xa933, 0xa92b, 0xa92e, 0xab11, 0xab18, + 0xab17, 0xab19, 0xab16, 0x15e6, 0xab0d, 0xab26, 0xab79, 0xabd8, + 0xabf3, 0xabd7, 0xabcc, 0xabcf, 0xabcb, 0xabd1, 0xabce, 0xabd4, + 0xabd5, 0xabd3, 0xabd6, 0xabcd, 0xabda, 0xabd2, 0xabde, 0xaccc, + 0xacb8, 0xacb7, 0xacc2, 0xacc3, 0xadfa, 0xadf9, 0xae1f, 0xae1d, + 0x6282, 0xaea6, 0xae90, 0xae9e, 0xae98, 0xae93, 0xae92, 0xaea5, + 0xae95, 0xafa9, 0xafa8, 0xafaa, 0xafab, 0xafac, + /* 0x2b */ + 0xb01f, 0xb022, 0xb0aa, 0xb096, 0xb091, 0xb0ab, 0xb0a2, 0xb0a4, + 0xb09d, 0xb097, 0xb07d, 0xb09f, 0xb09c, 0xb099, 0xb0a6, 0xb092, + 0xb0a7, 0xb1c9, 0xb1c8, 0xb1c7, 0xb1cb, 0xb274, 0xb2c9, 0x1738, + 0xb2d2, 0xb2db, 0xb2eb, 0xb2e9, 0xb2ef, 0xb2ee, 0xb2f9, 0xb2de, + 0xb416, 0xb445, 0xb47f, 0xb498, 0xb49f, 0xb486, 0xb490, 0xb49a, + 0xb49d, 0xb48d, 0xb49c, 0xb4a0, 0xb4a7, 0xb48f, 0xb641, 0xb635, + 0xb637, 0xb630, 0xb63a, 0xb636, 0xc508, 0xb6ca, 0xb712, 0xb715, + 0xb722, 0xb713, 0xb718, 0xb721, 0xb810, 0xb820, 0xb82f, 0xb8a5, + 0xb8a3, 0xb8b6, 0xb8ab, 0xb968, 0xb967, 0xb96f, 0xb977, 0xb964, + 0xb978, 0x183a, 0xb976, 0xb96e, 0x18b1, 0xbbd0, 0xbbb3, 0xbbcb, + 0xbbd6, 0xbbb1, 0xbbb4, 0xbbd7, 0xbbc6, 0xbbba, 0xbbd1, 0xbbd2, + 0xbbb5, 0xbbc4, 0xbbcc, 0xbbbb, 0xbbb2, 0xbe5b, + /* 0x2c */ + 0xbe5a, 0xbe59, 0xbe99, 0xbe94, 0xbe96, 0xbe93, 0xbe91, 0xbe8f, + 0xbe98, 0xbf0c, 0xbf0a, 0xbf0e, 0xbf12, 0xbf11, 0xbf0b, 0xbf9a, + 0x1947, 0xbfb4, 0x1951, 0xc01c, 0xc020, 0xc021, 0xc0d3, 0xc0d2, + 0xc138, 0x2afd, 0x6bcf, 0x2c1d, 0x2c92, 0x2c8f, 0x2c8c, 0x2dea, + 0x2eb9, 0x2f6e, 0x2fa0, 0xaddd, 0x3012, 0x3017, 0x306d, 0x3205, + 0x31fb, 0x31fd, 0x3206, 0x3200, 0x31ff, 0x31fe, 0x32b6, 0x3305, + 0x3307, 0x34bc, 0x34bb, 0x358b, 0x3587, 0x97fb, 0x36e7, 0x36e6, + 0x36e2, 0xa1d3, 0x36d9, 0x36ca, 0x3712, 0x3710, 0x36dc, 0x36d0, + 0x368b, 0x3713, 0x4d10, 0x36da, 0xc34f, 0x36fd, 0x36e5, 0x36cc, + 0x3739, 0x36c7, 0x36d8, 0x3a60, 0x3a64, 0x3a86, 0x3a5e, 0x3a66, + 0x3a5f, 0x3a77, 0x3a82, 0x3a96, 0x3b3e, 0x3b79, 0x3b7a, 0x3c88, + 0x3c89, 0x3c8c, 0x62e0, 0x3c7b, 0x3c86, 0x3d94, + /* 0x2d */ + 0x3d97, 0x3db7, 0x3db5, 0x3db8, 0x3d93, 0x3db2, 0x3db4, 0x3d99, + 0x3dc3, 0x3d9d, 0x3d9b, 0x3da3, 0x0347, 0x3e9f, 0x3e9e, 0x3ea3, + 0x3ea0, 0x3ea1, 0x3fc5, 0x3fc6, 0x3fbe, 0x3fc4, 0x3fbf, 0x404c, + 0x404a, 0x40b1, 0x4115, 0x4117, 0x4110, 0x4118, 0x41e0, 0x41df, + 0x4227, 0x4343, 0x4348, 0x431d, 0x4350, 0x4358, 0x4347, 0x4354, + 0x4353, 0x4340, 0x4355, 0x0417, 0x435a, 0x4870, 0x455b, 0x454d, + 0x4556, 0x454f, 0xc387, 0x4559, 0xc388, 0x4554, 0x4553, 0x4550, + 0x46b3, 0x476e, 0x04a3, 0x476f, 0x4793, 0x4829, 0x4825, 0x4828, + 0x486f, 0x54b8, 0xc397, 0x48b3, 0x4979, 0x497e, 0x497c, 0x4983, + 0xc3ac, 0x4b00, 0x4b34, 0x4b65, 0x4b36, 0x4ba7, 0x4b59, 0x4b58, + 0x4b31, 0x4b62, 0x4b38, 0x4b73, 0x4b3e, 0x4b55, 0x4b54, 0x4b95, + 0xc3ad, 0x4ba5, 0x4b94, 0x4b9a, 0x4b9b, 0x4b99, + /* 0x2e */ + 0x4b9f, 0x4b53, 0x4d12, 0x4d0a, 0x4d09, 0x4d0c, 0x4d0b, 0x4d0e, + 0x4d0d, 0x4d08, 0x4f38, 0x4f3a, 0x4f37, 0x4f3d, 0x4f2d, 0x4f82, + 0x4f95, 0x4f87, 0x4f9d, 0x4fb5, 0x4f81, 0x4fc7, 0x4f9b, 0x4f98, + 0x4f94, 0x4f86, 0x4f90, 0x4f34, 0x4f8e, 0x4f85, 0x4fa6, 0x4f96, + 0x51ea, 0x51df, 0x54bd, 0x51f7, 0x51eb, 0x51e0, 0x51e8, 0x51e1, + 0x51e9, 0x51ee, 0x51e5, 0x51ec, 0x5263, 0x52c6, 0x52c2, 0x52c1, + 0x52c0, 0x52c3, 0x5318, 0x54ae, 0x54a3, 0x54c5, 0x54a0, 0x54b4, + 0x54a5, 0x071e, 0x54a4, 0x54a8, 0x54a6, 0x57a8, 0x578d, 0x5782, + 0x579e, 0x5789, 0x5783, 0x5791, 0x57a6, 0x579a, 0x5790, 0x5785, + 0x577d, 0xc3ec, 0x579b, 0x57a5, 0x57f0, 0x5796, 0x5788, 0x57d6, + 0x57d8, 0x5786, 0x57a4, 0x5797, 0x5a1c, 0x5a19, 0x5a9e, 0x5a9f, + 0x5a9d, 0x5a9c, 0x5b5d, 0x5b5e, 0x5b73, 0x5b63, + /* 0x2f */ + 0x5bbe, 0x5bc1, 0x5bbc, 0x5bbf, 0x5bbb, 0x5bbd, 0x5c13, 0x5c14, + 0x5cf8, 0x5cfa, 0x5d06, 0x5cfe, 0x5d51, 0x600b, 0x5ff1, 0x5fa9, + 0x5fd5, 0x5fdc, 0x5fcb, 0x5ff2, 0x605f, 0x5fdb, 0x5fd6, 0x5fd9, + 0x5fd1, 0x5fcf, 0x5fd8, 0x5fe0, 0x5fd4, 0x5ff3, 0x6005, 0x5fce, + 0x5ff4, 0xc412, 0x5fda, 0x600e, 0x6006, 0x5fd7, 0x5fcd, 0x6007, + 0x5fe1, 0x6008, 0x62be, 0x62ef, 0x62d9, 0x62da, 0x1fd7, 0x62a0, + 0x62df, 0x629e, 0x62bf, 0x62af, 0x62a7, 0x62aa, 0x62f4, 0x62ae, + 0x62b5, 0x62b8, 0x62db, 0x62c0, 0x62b7, 0x62a2, 0x62dd, 0x62a1, + 0x62a5, 0x62b4, 0x62a6, 0x62ab, 0x62ac, 0x629f, 0x62b1, 0x62fc, + 0x642e, 0x6430, 0x6499, 0x64f8, 0x64f6, 0x65f4, 0x65eb, 0x65e1, + 0x65e4, 0x6775, 0x6769, 0x0a9a, 0x6799, 0x679e, 0x6794, 0x6793, + 0x6791, 0x6919, 0x6917, 0x6949, 0x6947, 0x6948, + /* 0x30 */ + 0x6952, 0x6940, 0x6963, 0x6946, 0x695f, 0x6a0e, 0x6a85, 0x6a87, + 0x6acb, 0x6acc, 0x6ac9, 0x6bcb, 0x41e7, 0x6c20, 0x6d5f, 0x6d60, + 0x6d6a, 0x6d76, 0x6d73, 0x6d71, 0x6d66, 0x0bc2, 0x6d6b, 0x6d79, + 0x6d7b, 0x6e3c, 0x6e9e, 0x6e9c, 0x6f1c, 0x6f1e, 0x6f21, 0x6f96, + 0x6fa1, 0x6fb6, 0x6fa0, 0x6f94, 0x6f97, 0x7081, 0x7086, 0x70c0, + 0x708a, 0xc44b, 0x7085, 0x7095, 0x7049, 0x7082, 0x7084, 0x4b78, + 0x7090, 0x70b1, 0x71fe, 0x71fb, 0x7350, 0x7356, 0x735a, 0x734c, + 0x0cdc, 0x7357, 0x74e1, 0x74d9, 0x74db, 0x74f4, 0x7545, 0x7547, + 0x7674, 0x766b, 0x7668, 0x7669, 0x7679, 0xc45b, 0x7680, 0x7681, + 0x7661, 0x7670, 0x766f, 0x7673, 0x765d, 0x77fa, 0x0db3, 0x77f3, + 0x780a, 0x7817, 0xc45f, 0x78b0, 0x7a3e, 0x7a46, 0x7a4f, 0x7a44, + 0x7a69, 0x7a33, 0x7a2f, 0x7a4e, 0x7a3a, 0x7a2b, + /* 0x31 */ + 0x7aa9, 0x7a50, 0x7a45, 0x7a37, 0x7a25, 0x7a2c, 0x7a3f, 0x7a34, + 0x7a29, 0x7a1e, 0x7a3d, 0x7ced, 0xc466, 0x7cf3, 0x7cea, 0x7ceb, + 0x7ecc, 0x7ece, 0x7ed0, 0x7ee3, 0x7ee0, 0x7ed1, 0x7edc, 0x7edd, + 0x7ef0, 0x7edb, 0x7ee5, 0x7ef1, 0x7ec9, 0x7ee8, 0x7ee7, 0x7ec8, + 0x7ede, 0x7ecd, 0x7ec5, 0x7ec6, 0x7ee4, 0x7ec3, 0x80fb, 0x80fc, + 0x80fe, 0x8103, 0x8100, 0x80fd, 0x8105, 0x8113, 0x81a7, 0x81b4, + 0x8270, 0x8274, 0x8271, 0x8275, 0x827d, 0x8273, 0x82c4, 0x82c3, + 0x82de, 0x82dd, 0x8311, 0x830f, 0x8310, 0x83c3, 0x83c2, 0x83ca, + 0x83c1, 0x8423, 0x85b1, 0x8624, 0x8611, 0x8625, 0x860a, 0x861f, + 0x8620, 0x8614, 0x8628, 0x8603, 0x8612, 0x860b, 0x8617, 0x4d11, + 0x8749, 0x8789, 0x8790, 0x878f, 0x8796, 0x8795, 0x8793, 0x87ed, + 0x87f0, 0x62de, 0x8885, 0x8877, 0x887a, 0x8884, + /* 0x32 */ + 0x8879, 0x887d, 0x887b, 0x88ed, 0x88ec, 0x89f6, 0x899b, 0x8a9d, + 0x8b11, 0x8ac4, 0x8ac8, 0x8adf, 0x8abf, 0x8ab3, 0x8aba, 0x8b10, + 0x8b06, 0x8a88, 0x8a9a, 0x8ae0, 0x8acc, 0x8ab5, 0x8ae1, 0x8abc, + 0x8ac6, 0x8b0b, 0x8aa4, 0x8a95, 0x8aa3, 0x8ae2, 0x8acd, 0x8ae3, + 0x8aab, 0x8acb, 0x8a8f, 0xc4ab, 0x8aa9, 0x8b24, 0x8ae4, 0x8b12, + 0x8ae5, 0x8b67, 0x8aaa, 0x8aa0, 0x8ae6, 0x8ac1, 0x8ae7, 0x8b0d, + 0x8a86, 0x8ab0, 0x8a8b, 0x8ae8, 0x8ac9, 0x8b19, 0x8ac0, 0x8b0c, + 0x8ae9, 0x8aea, 0x8ded, 0x8de3, 0x8de4, 0x8de8, 0x8dd2, 0x8de2, + 0x2466, 0x8fcf, 0x8fd1, 0x8fc3, 0x8fc9, 0x8fea, 0x8fb4, 0x8fdc, + 0x8fbd, 0x8fe6, 0x8fc8, 0x8fec, 0x8fb2, 0x8fa9, 0x8fd3, 0x8fc0, + 0x8fe9, 0x8fd5, 0x11d9, 0x8fc5, 0x11dd, 0x8fcb, 0x8fd0, 0x8fd2, + 0x8fe4, 0x8fe8, 0x8fcd, 0x8fb6, 0x8faa, 0x8fd4, + /* 0x33 */ + 0xa049, 0x8fc1, 0x8fdd, 0x8fce, 0x91c9, 0x91ca, 0x92fd, 0x92d9, + 0x92ff, 0x9304, 0x92fa, 0x9306, 0x9315, 0x9311, 0x9307, 0x930b, + 0x93fc, 0x93fd, 0x946d, 0x9465, 0x9514, 0x9513, 0x950c, 0x950b, + 0x9518, 0x9522, 0x967d, 0x966f, 0x9675, 0x967b, 0x9680, 0x967f, + 0x9696, 0x966d, 0x966b, 0x9686, 0x9673, 0x9662, 0x9677, 0x9681, + 0x9669, 0x9682, 0x9697, 0x9684, 0x12fc, 0x9678, 0xc4d0, 0x967a, + 0x966a, 0x9665, 0x967e, 0x9694, 0x97c2, 0x97c1, 0x97f9, 0x9871, + 0x986b, 0x986d, 0x986f, 0x986e, 0x98f2, 0x98e8, 0x98ef, 0x98e9, + 0x98ea, 0x98ed, 0x98f3, 0x98e6, 0x99c9, 0x99b4, 0x99b3, 0x99b9, + 0x99ca, 0x99b1, 0x99b6, 0x99c7, 0x99c4, 0x99b7, 0x9a6f, 0x9b33, + 0x9b32, 0x9b1f, 0xc4d9, 0x9b2b, 0x9b30, 0x9b36, 0x9b42, 0x9b41, + 0xc4d8, 0x9ca5, 0x9cab, 0x9ca9, 0x9cb3, 0x9ca7, + /* 0x34 */ + 0x9ca0, 0x9cd2, 0x9ca8, 0x9cb6, 0x9cac, 0x9cae, 0x9ce6, 0x9e65, + 0x9f47, 0x9f63, 0x9f4d, 0x9f5f, 0x9f4b, 0x9f60, 0x9f49, 0x9f53, + 0xc4df, 0x263a, 0x9f57, 0x9f4e, 0x9f52, 0x9f54, 0xa020, 0xa022, + 0xa1c1, 0xa1d7, 0xa1d5, 0xa1c4, 0xa1d0, 0xa1bb, 0xa1e2, 0xa1cb, + 0xa1b8, 0xa1bf, 0xa1d8, 0xa1c0, 0xa1ba, 0xa1b4, 0xa1bc, 0xa1d4, + 0xa1ed, 0xa1c2, 0xa1d9, 0xa1cc, 0xa32f, 0xa323, 0xa396, 0xa38d, + 0xa39e, 0xa399, 0xa483, 0x1507, 0xa46a, 0xa469, 0xa475, 0xa46c, + 0xa480, 0xa46e, 0xa481, 0xa477, 0xa476, 0xa473, 0xa470, 0xa484, + 0xa519, 0xa5f2, 0x273d, 0xa5ec, 0xa5eb, 0xa5f6, 0xa5ef, 0xa5f4, + 0xa5ee, 0xa5f3, 0xa5ed, 0xa89b, 0xa898, 0xa894, 0x3a7a, 0xa89a, + 0xc4f0, 0xa94c, 0x15a8, 0xa957, 0xa951, 0xa962, 0xa952, 0xa95c, + 0xa953, 0xc4ef, 0xaa85, 0xab2d, 0xab3e, 0xab30, + /* 0x35 */ + 0xab7d, 0xabe6, 0xabf6, 0xabe4, 0xabe9, 0xabec, 0xabf2, 0xabe8, + 0xabe3, 0xabeb, 0xabf0, 0xabea, 0xabe7, 0xabfd, 0xabe5, 0xabee, + 0xabf5, 0xabf9, 0xabf1, 0xabf4, 0xc4f4, 0xac11, 0xacde, 0xacd8, + 0xacdd, 0xacdb, 0xacd3, 0xace1, 0xadde, 0xadfc, 0xae28, 0xaeb7, + 0xaeb8, 0xaec7, 0xaeb2, 0xaea9, 0xaeb9, 0xaebc, 0xaeb3, 0xaed1, + 0xafb0, 0xafb1, 0xafb6, 0xb004, 0xb02c, 0xb0c1, 0xb09e, 0xb0ba, + 0x16ca, 0xb0d1, 0xb0d3, 0xb0d4, 0xb0d5, 0xb0c5, 0xb0b6, 0xb0b2, + 0xb0b5, 0xb0c3, 0xb0b9, 0xb0c6, 0xb1d6, 0xb1e0, 0xb1db, 0xb1d7, + 0xb1dd, 0xb315, 0xb30c, 0xb30f, 0xb30e, 0xb2fe, 0xb304, 0xb30b, + 0xb302, 0xb2ff, 0xb308, 0xb310, 0xb317, 0xb313, 0xb306, 0xb309, + 0xb424, 0xb426, 0xb425, 0xb448, 0xb4b5, 0xb4d2, 0xb4d5, 0xb4c4, + 0xb4af, 0xb4ad, 0xb4c1, 0xb4c0, 0xb4cc, 0xb4cd, + /* 0x36 */ + 0xb4c3, 0xb4c8, 0xb4c5, 0xb4ba, 0xb4d0, 0xb4c2, 0xb4ce, 0x178d, + 0xb643, 0xb642, 0xb640, 0xb631, 0xb6cf, 0xb6ce, 0xb730, 0xb734, + 0xb732, 0xb743, 0xb73c, 0xb811, 0xb835, 0xb834, 0xb837, 0xb831, + 0xb8bf, 0xb8bc, 0xb8c2, 0xb8c9, 0xb983, 0xb98b, 0xb9a0, 0xb98d, + 0xb98c, 0xb99a, 0xb98a, 0xb991, 0xbbf1, 0xbc0f, 0xbc01, 0xbc07, + 0xbc0c, 0x18c0, 0xbbdc, 0xbbee, 0xbbf7, 0xbbf2, 0xbbf8, 0xbbeb, + 0x18ca, 0xbbe6, 0xbbed, 0xbbe9, 0xbc08, 0xbc00, 0xbbe5, 0xbbfc, + 0xbe61, 0xbe5e, 0xbe5f, 0x1925, 0xbe9b, 0xbf16, 0xbf15, 0xbf20, + 0xbf14, 0xbf1a, 0xbf17, 0xbf9c, 0x194a, 0xbff1, 0x1953, 0xbff0, + 0xc028, 0xc024, 0xc02a, 0xc02b, 0xc0d5, 0xc104, 0xc105, 0xc191, + 0xc192, 0xc2a6, 0x2c09, 0x2e22, 0x2e1a, 0x2e0e, 0x2e1b, 0x2e08, + 0x6fb3, 0xc31c, 0x309d, 0x3212, 0x321e, 0x32bb, + /* 0x37 */ + 0x32bf, 0x32bc, 0x3308, 0x3309, 0x3363, 0x33c8, 0x5828, 0x358e, + 0x358d, 0x3743, 0x374d, 0x376d, 0x3742, 0x3752, 0x3751, 0x3769, + 0x3750, 0x3756, 0x376c, 0x3744, 0x3745, 0x376b, 0x0205, 0x3768, + 0x3757, 0x392e, 0x3931, 0x392d, 0x3a8b, 0x3ab2, 0x3a8d, 0x3aa3, + 0x3aa4, 0x3a90, 0x3a89, 0x3a8e, 0x3a92, 0x3b7b, 0x3c90, 0x3c8f, + 0x3de9, 0x3dcd, 0x3dc5, 0x3dd0, 0x3dc9, 0x3dd1, 0x3dc7, 0x3dd2, + 0x3d5f, 0x3de1, 0x3dcc, 0x3dc6, 0x3de4, 0x3ea9, 0x3fd3, 0x3fda, + 0x3fd2, 0x3fdb, 0x404d, 0x404e, 0x411c, 0x41e8, 0x436c, 0x435f, + 0x4366, 0x4364, 0x4378, 0x4365, 0x436d, 0x4361, 0x437a, 0x4407, + 0x4566, 0x4568, 0x4562, 0x46d3, 0x46d4, 0x46d1, 0x46dc, 0x4773, + 0x4772, 0x482d, 0x482c, 0x482f, 0x4872, 0x48b4, 0x4989, 0x4bcd, + 0x4ba6, 0x4ba2, 0x4ba0, 0x4b46, 0x4ba1, 0x8657, + /* 0x38 */ + 0x4ba3, 0x4bb1, 0x4bdb, 0x4bf6, 0x4bdc, 0x4bd6, 0x4d13, 0x4f9c, + 0x4f97, 0x4fd8, 0x4fe4, 0x4fd4, 0x4fe5, 0x4fdb, 0x4fd0, 0x4fda, + 0x4fcc, 0x4fdc, 0x4fed, 0x4fd3, 0x4fd1, 0x4fce, 0x4fd9, 0x4fdd, + 0xc3c6, 0x50e6, 0x50e5, 0x50e9, 0x51ff, 0x51fe, 0x520e, 0x528c, + 0x52ca, 0x52cb, 0x531a, 0x54d7, 0x54cf, 0x54d0, 0x54c9, 0x54cc, + 0x54d3, 0x55a4, 0x55a3, 0x5781, 0x5826, 0x57f3, 0x5827, 0x57f2, + 0x57ff, 0x57f5, 0x57fc, 0x580e, 0x07f0, 0x57f6, 0x5800, 0x5823, + 0x5805, 0x5825, 0x5808, 0x5850, 0x5a25, 0x5a20, 0x5a23, 0x5a21, + 0x5aa1, 0x5b69, 0x5b6c, 0x5b68, 0x5b6b, 0x5bcc, 0x5bcd, 0x5d10, + 0x5d0d, 0x5d0a, 0x5d16, 0x5d14, 0x5d52, 0x6028, 0x602e, 0x602c, + 0x604d, 0x6049, 0x6031, 0x6030, 0x6033, 0x602d, 0x6036, 0x603e, + 0x602f, 0x6027, 0x6034, 0x604c, 0x62fe, 0x6312, + /* 0x39 */ + 0x631f, 0x6317, 0x62f5, 0x6315, 0x62f7, 0x0a02, 0x437d, 0x62fa, + 0x62f9, 0x634b, 0x649c, 0x649d, 0x0a23, 0x65f0, 0x65f6, 0x65ef, + 0x679d, 0x679a, 0x67a7, 0x67af, 0x67aa, 0x6964, 0x6986, 0x6975, + 0x6970, 0x6984, 0x696b, 0x6985, 0x696c, 0x6a17, 0x6a94, 0x6a93, + 0x6bd2, 0x6bd7, 0x6bd4, 0x6da6, 0x6da7, 0x6d9c, 0x6d8b, 0x6d8d, + 0x6d98, 0x6db9, 0x6d9b, 0x6d9d, 0x6d99, 0x6da8, 0x6d91, 0x6d87, + 0x6d9a, 0x6ea6, 0x6f1f, 0x6fa7, 0x6fb1, 0x6fb2, 0x6fb7, 0x70d0, + 0x70b3, 0x70b5, 0x70c4, 0x70c3, 0x70bc, 0x70b2, 0x70ba, 0x70bb, + 0x70c2, 0x70cd, 0x70be, 0x70b7, 0x718f, 0x7203, 0x7204, 0x7371, + 0x7377, 0x7374, 0x738b, 0x737a, 0xc451, 0x738c, 0x7373, 0x74ff, + 0x74fb, 0x74fd, 0x74f0, 0x74f3, 0x74fc, 0x74f2, 0x7692, 0x769e, + 0x76ae, 0x7696, 0x7814, 0x7812, 0x7813, 0x7816, + /* 0x3a */ + 0x780f, 0x78b6, 0x78bd, 0x7a8c, 0x7aae, 0x7aac, 0x7aab, 0x7a99, + 0x7a92, 0x7abb, 0x7a9e, 0x7a7e, 0x7aaf, 0x7abc, 0x7a98, 0x7d01, + 0x7d09, 0x7d06, 0xc467, 0x7d07, 0x7d08, 0x7ecf, 0x7f0e, 0x7f32, + 0x0f15, 0x7f12, 0x7f16, 0x7f17, 0x7f1b, 0x7f15, 0x7f31, 0x7f18, + 0x7f1a, 0x7f10, 0x7f0a, 0x7f09, 0x804f, 0xc473, 0x810f, 0x8110, + 0xc475, 0x8128, 0x8111, 0x8116, 0x8117, 0x8102, 0x81bb, 0x81ba, + 0x81c3, 0x81bc, 0x828a, 0x8284, 0x8286, 0x82e0, 0x8317, 0x8318, + 0x831e, 0x8315, 0x83d3, 0x83da, 0x83d9, 0x85e6, 0x85f4, 0x85e1, + 0x8669, 0x8640, 0x8658, 0x866c, 0x864d, 0x8721, 0x8799, 0x87f1, + 0x5f68, 0x8886, 0x8b5b, 0x8b5c, 0x8b77, 0x8b2c, 0xc4ad, 0x8b58, + 0x8b64, 0x8b61, 0x8b48, 0x8b97, 0x8b59, 0x8b29, 0x8b62, 0x8b2e, + 0x8b68, 0x8b90, 0x8b3a, 0x8b3d, 0x8b5e, 0x8b46, + /* 0x3b */ + 0x8b69, 0x8b65, 0x8b3e, 0x8b49, 0x8b56, 0x8be1, 0x8b78, 0x8b79, + 0x8b66, 0x8b4a, 0x8b35, 0x8b7a, 0x8b92, 0x8b60, 0x8b36, 0x8b51, + 0x8b42, 0x115d, 0x8b3f, 0x8b7b, 0x8b5d, 0x8b94, 0x8b6a, 0xc4b5, + 0x8df2, 0x8fbb, 0x901b, 0x901a, 0x9033, 0x9017, 0x900a, 0x9015, + 0x9012, 0x9001, 0x902d, 0x8ffd, 0x9023, 0x9005, 0x9011, 0x9000, + 0x901c, 0x9035, 0x902e, 0x9036, 0x34bf, 0x902f, 0x900c, 0x9009, + 0x9031, 0x8ffc, 0x900f, 0x9018, 0x9002, 0x9200, 0x931f, 0x9337, + 0x125a, 0x9338, 0x932b, 0x932e, 0x9321, 0x9330, 0x9329, 0x9331, + 0xc4c9, 0x9301, 0x932c, 0x9322, 0x93ff, 0x9477, 0x9467, 0x947f, + 0x947d, 0x947b, 0x947e, 0x951e, 0x951c, 0x9521, 0x9526, 0x9527, + 0x9529, 0x952c, 0x951d, 0x952b, 0x96bf, 0x96a4, 0x96aa, 0x96ae, + 0x969f, 0x96d0, 0x96b1, 0x96ad, 0x969b, 0x96b2, + /* 0x3c */ + 0x96a9, 0x96b3, 0x96b4, 0x96ba, 0x96a5, 0x96b7, 0x96ac, 0x96cb, + 0x96cf, 0x97c6, 0x9801, 0x97ff, 0x97fd, 0x9877, 0x9878, 0x9876, + 0x98f7, 0x99cc, 0x1385, 0x99d4, 0x99d7, 0x99d5, 0x99d6, 0x99d3, + 0x9b5d, 0x9b55, 0x9ce0, 0x9d48, 0x9cee, 0x9cdb, 0x9ce7, 0x9cd6, + 0x9ce5, 0x9ce1, 0x9cdd, 0x9ce2, 0x9e70, 0x9e66, 0x9e6f, 0x9e6e, + 0x9f81, 0x9f69, 0x9f6e, 0x9f6d, 0x9f6c, 0x9f84, 0x9f85, 0x9f71, + 0x9f73, 0x9f6a, 0x9f6f, 0x9f7b, 0xa16a, 0xa17c, 0xa17d, 0xa181, + 0xa1fa, 0xa205, 0xa1eb, 0xa1fb, 0xa1e9, 0xa1ef, 0xa1fc, 0xa1e7, + 0xc4e1, 0xa1ee, 0xa1fd, 0xa332, 0xa3a7, 0xa3b5, 0xa3b1, 0xa3b9, + 0xa3a8, 0xa3b3, 0xc4e6, 0xa48a, 0xa491, 0xa48d, 0xa499, 0x150b, + 0xa49a, 0xa49b, 0xa492, 0xa48f, 0xa4ab, 0x6bdb, 0x1539, 0xa675, + 0xa631, 0xa638, 0x1537, 0xa635, 0xa669, 0xa63b, + /* 0x3d */ + 0xa63d, 0xa66c, 0xa679, 0xa63c, 0xa63e, 0xa897, 0xa8a5, 0xa8a2, + 0xa89d, 0xa8a1, 0xa968, 0xa96f, 0xa96d, 0xa972, 0xa975, 0xa977, + 0xa979, 0xaab5, 0xaaea, 0xaaab, 0xab43, 0xab41, 0xab42, 0xac09, + 0xac08, 0xac06, 0xac01, 0xac03, 0xac00, 0xac04, 0xac0a, 0xac0e, + 0xac0d, 0xac07, 0xac0f, 0xac14, 0xac02, 0xac15, 0xac0c, 0xac10, + 0xac05, 0xacfd, 0xacff, 0xad04, 0xad00, 0xad09, 0xae2b, 0xc4f7, + 0xae31, 0xaedb, 0xaec5, 0xaed3, 0xaece, 0x166b, 0xaec9, 0xaebf, + 0xaecb, 0xaec0, 0xaed0, 0xaed4, 0xafc1, 0xafb9, 0xafbb, 0xafc3, + 0xafc9, 0xb007, 0xb02d, 0xb0f8, 0xb0e1, 0xb0fa, 0xb0ef, 0xb0fd, + 0x16cd, 0xb0eb, 0xb0f1, 0xb0ed, 0xb0fe, 0xb1f8, 0xb203, 0xb1ee, + 0xb1e8, 0xb201, 0xb2ec, 0xb322, 0xb314, 0xb334, 0xb32f, 0xb339, + 0xb341, 0xb33c, 0xb349, 0xb358, 0xb33a, 0xb342, + /* 0x3e */ + 0xb33f, 0xb422, 0xb423, 0xb44a, 0xb4dc, 0xb4d9, 0xb4db, 0xb4e2, + 0xc507, 0xb4df, 0xb4e0, 0xb4d7, 0xb64f, 0xb646, 0xb653, 0xb655, + 0xb64e, 0xb64a, 0xb64c, 0xb663, 0xb751, 0xb753, 0xb758, 0xb74d, + 0xb75a, 0xb749, 0xb75d, 0xb812, 0xb83c, 0xb8d1, 0xb8df, 0xb8d6, + 0xb8d8, 0xb8e0, 0xb8d9, 0xb9b1, 0xb9ac, 0xb9aa, 0xb9ee, 0xb9bd, + 0x184d, 0xb9c3, 0xb9a8, 0xb9ae, 0xb9ab, 0xbc1d, 0xbc27, 0xbc38, + 0xbc12, 0xbc48, 0xbc2b, 0xbc16, 0xbc19, 0xbc3d, 0xbc23, 0xbc2a, + 0xbe64, 0xbead, 0xbeac, 0xc514, 0xbeb1, 0xbeaf, 0xbf2c, 0xbf24, + 0xbf25, 0xbf28, 0xbff9, 0xbff7, 0xbffd, 0xbffe, 0xc039, 0xc033, + 0xc0d7, 0xc0d8, 0xc0e4, 0x3aa1, 0xc10e, 0xc13b, 0xc144, 0xc142, + 0xc194, 0xc193, 0xc1d5, 0xc2a7, 0x2e31, 0x2e23, 0x2e28, 0x2e27, + 0x2ec6, 0x2fa3, 0x3021, 0x321b, 0x0110, 0x32c1, + /* 0x3f */ + 0x32c3, 0x332a, 0x3369, 0x3427, 0x37b6, 0x37a7, 0x37a4, 0x37a6, + 0x3790, 0x379e, 0x3794, 0x37a8, 0x37a5, 0x37a2, 0x3791, 0x027b, + 0x3abc, 0x3abd, 0x3ab4, 0x3ab0, 0x3ae4, 0x3b45, 0x3b4b, 0x3b7e, + 0x3b7f, 0x3b7d, 0x3bc3, 0x3dfc, 0x3df7, 0x3df0, 0x3ded, 0x3df1, + 0x3df8, 0x3fe9, 0x41eb, 0x041d, 0x4390, 0x438d, 0x4386, 0x4391, + 0x438a, 0x4408, 0x4450, 0x46ea, 0x46e6, 0x46e2, 0x46e7, 0x46ed, + 0x46e1, 0x4834, 0x4876, 0x4875, 0x4873, 0x48b5, 0x4990, 0x4992, + 0x4be1, 0x4bdf, 0x4bd5, 0x4bf2, 0x4bfe, 0x4c13, 0x4c2e, 0x4d19, + 0x5008, 0x1df5, 0x5005, 0x5009, 0x5006, 0x5003, 0x4ffd, 0x4ffc, + 0x5002, 0x5042, 0x521a, 0x5211, 0x5215, 0x5216, 0x52cc, 0x52cf, + 0x52d0, 0x5322, 0x531e, 0x5321, 0x54e5, 0x0727, 0x5554, 0x54ef, + 0x5553, 0x5551, 0x55ad, 0x5867, 0x5868, 0x58a4, + /* 0x40 */ + 0x5877, 0x5889, 0x5844, 0x588b, 0x5879, 0x585b, 0x5843, 0x5857, + 0x584a, 0x587c, 0x5846, 0x587b, 0x5856, 0x5aa8, 0x5b76, 0x5b72, + 0x5bd6, 0x5bd8, 0x5bd1, 0x5d22, 0x5d20, 0x5d23, 0x5d1e, 0x5d6e, + 0x60a3, 0x6077, 0x60a6, 0x606d, 0x60a2, 0x607c, 0x6084, 0x6068, + 0x6074, 0x6086, 0x60a5, 0x607b, 0x607a, 0x6069, 0x6072, 0x6076, + 0x634a, 0x6337, 0x632a, 0x632d, 0x6346, 0x6328, 0x6326, 0x6342, + 0x632c, 0x6338, 0x632b, 0x6333, 0x6345, 0x6439, 0x65f9, 0x65fa, + 0x67b8, 0x67b7, 0x67bb, 0x67b9, 0x67b4, 0x696f, 0x6987, 0x698f, + 0x69a2, 0x69a3, 0xc431, 0x6a9b, 0x6a9d, 0x6ace, 0x0bcf, 0x6dbd, + 0x6dbf, 0x6d92, 0x0bcd, 0x6def, 0x6dc9, 0x6ea4, 0x6ea8, 0x6eaa, + 0x6f28, 0x6f24, 0x6f25, 0x6f26, 0x6fa9, 0x6fba, 0x6fbe, 0x6fbc, + 0x6fc0, 0x70f0, 0x70df, 0x70e0, 0x70ed, 0x70db, + /* 0x41 */ + 0x70fb, 0x70b9, 0x70da, 0x70eb, 0x70ec, 0x739a, 0x739f, 0x739b, + 0x7397, 0x73a1, 0x750f, 0x7505, 0x7548, 0x0d82, 0x76bc, 0x76ba, + 0x78bf, 0x7b01, 0x7ae8, 0x7aef, 0x7ae4, 0x7ae6, 0x7b02, 0x7aeb, + 0x7ae0, 0x7aed, 0x7ad9, 0xc464, 0x7b14, 0x7aee, 0x0e52, 0x7b13, + 0x7af9, 0x7af8, 0x7d25, 0xc469, 0x7d19, 0x7d20, 0x7d43, 0x7d3f, + 0x7f45, 0x7f4c, 0x7f49, 0x7f4f, 0x7f41, 0x7f3e, 0x7f4d, 0x7f52, + 0x7f4a, 0x7f4e, 0x7f73, 0x7f42, 0x7f51, 0x7f55, 0x7f50, 0x7f6c, + 0x2afd, 0x7f6a, 0x7f53, 0x7f68, 0x8055, 0x8056, 0x811c, 0x811d, + 0x2280, 0x811e, 0x8123, 0x811f, 0x81e1, 0x81cd, 0x81cb, 0x81cc, + 0x81c8, 0x81c9, 0x829b, 0x8294, 0x8292, 0x8296, 0x8293, 0x8295, + 0x828f, 0x831d, 0x8322, 0x8321, 0x83e9, 0x83ef, 0x83e0, 0x83e6, + 0x83e4, 0x8629, 0x862c, 0x8676, 0x8683, 0x8678, + /* 0x42 */ + 0x863c, 0x6343, 0x867a, 0x1051, 0x86f2, 0x879e, 0x879b, 0x879a, + 0x87f6, 0x87f5, 0x88a5, 0x8893, 0x88a4, 0x8a82, 0x8ac7, 0x8bb7, + 0x8c1d, 0x8be2, 0x8bd7, 0x8be3, 0x8be4, 0x8bbc, 0x8bd3, 0x115a, + 0x8b5a, 0x8bd2, 0x8b2d, 0xc4af, 0x8bc4, 0x8bd0, 0x8be5, 0x8c05, + 0x8c07, 0x8be6, 0x8c1b, 0x8be7, 0x8bd8, 0x8bbe, 0x8c17, 0x8bb4, + 0x8bd9, 0x8be8, 0x8bad, 0x8baf, 0x8bc8, 0x8be9, 0x8bea, 0x8dfe, + 0x8dfb, 0x8e00, 0x9072, 0x9070, 0x9046, 0x9059, 0x905e, 0x9048, + 0x904f, 0x9071, 0x9060, 0x905f, 0x906e, 0x9073, 0xc4c0, 0xc4bf, + 0x9047, 0x906d, 0x906f, 0x9081, 0x906c, 0x9078, 0x9083, 0x9049, + 0x9068, 0x9074, 0x9063, 0x906a, 0x8685, 0x9065, 0x9062, 0x90c8, + 0x91d0, 0x91d4, 0x91d1, 0x9203, 0x9342, 0x9363, 0x9356, 0x935b, + 0x9355, 0x9350, 0x932d, 0x9344, 0x9348, 0x9345, + /* 0x43 */ + 0x9382, 0x1265, 0x9362, 0x9485, 0x948d, 0x9536, 0x952f, 0x9531, + 0x9537, 0x96a7, 0x96d9, 0x96f0, 0x96f2, 0x96fd, 0x96e8, 0x96eb, + 0x96ee, 0x96e0, 0x96e9, 0x96ed, 0x96d6, 0x96f8, 0x96d4, 0x96df, + 0x96e7, 0x96d8, 0x96e3, 0x96ef, 0x970f, 0x97ca, 0x3b46, 0x9805, + 0x980c, 0x980d, 0x987f, 0x9880, 0x9881, 0x9901, 0x9903, 0x99f2, + 0x99e2, 0x99e3, 0x99de, 0x99e9, 0x99e8, 0x99e0, 0x9a01, 0x99f5, + 0x99e4, 0x2501, 0x9a77, 0x9b74, 0x9b6f, 0x9b62, 0x9b61, 0x9b6d, + 0x9b73, 0x9b6a, 0x9b69, 0x9d12, 0x9d2d, 0x9d14, 0x9d0f, 0x9d29, + 0x9d16, 0x9d03, 0x9d46, 0x9d5c, 0x9d11, 0x9d06, 0x9cdc, 0x9d2b, + 0x9d2a, 0x9d2c, 0x9d27, 0x9e7a, 0x9f9c, 0x9f99, 0x9f95, 0x9f8b, + 0x9f98, 0x9f96, 0xa032, 0xa1a4, 0xa1aa, 0xa21b, 0x14af, 0xa20d, + 0xa21c, 0xa20a, 0xa220, 0xa208, 0xa21a, 0xa213, + /* 0x44 */ + 0xa211, 0xa35d, 0xa35f, 0xa35e, 0xa360, 0xa3bb, 0xa3bc, 0xa3c1, + 0xa3c0, 0xa3c8, 0xa3ce, 0xa4a7, 0xa4b2, 0xa4b6, 0xa4a5, 0xa4ba, + 0xa4b5, 0xa4ad, 0xa4a4, 0xa4d3, 0xa4b0, 0xa4b1, 0xa51d, 0xa68d, + 0x1541, 0xa691, 0xa6b6, 0xa6b7, 0xa6bd, 0xa6bc, 0xa696, 0xa694, + 0xa6a0, 0xa8a8, 0xa8a6, 0xa984, 0xa996, 0xa988, 0xa99a, 0xaad1, + 0xaacf, 0xab50, 0xab51, 0xab4e, 0xab80, 0xab81, 0xac1b, 0xac17, + 0xac20, 0xac19, 0xac1a, 0xac21, 0xac1e, 0xac18, 0xac1d, 0x1629, + 0xad2d, 0xad24, 0xad27, 0xad2e, 0xad25, 0xad1c, 0xad19, 0x162a, + 0xad23, 0xad1f, 0xad1a, 0xad2b, 0xad1e, 0xade0, 0xae33, 0xaee6, + 0xaefc, 0xaee5, 0xaef8, 0xaef6, 0xaeea, 0xaef2, 0xaeed, 0xaeeb, + 0xaef0, 0xaef1, 0xafc6, 0xafc8, 0xafce, 0xafc5, 0x1696, 0xafcb, + 0xb113, 0xb114, 0xb107, 0xb10c, 0xb21a, 0x1712, + /* 0x45 */ + 0xb217, 0xb206, 0xb216, 0xb207, 0xb210, 0xb209, 0xb219, 0xb215, + 0xb36e, 0xb33b, 0xb33e, 0xb36c, 0xb365, 0xb364, 0xb359, 0xb37c, + 0xb370, 0xb379, 0xb42c, 0xb452, 0xb451, 0xb44c, 0xb500, 0xb510, + 0xb513, 0xb4ff, 0xb4fe, 0xb4ed, 0xb65a, 0xb658, 0xb65c, 0xb6da, + 0xb778, 0xb75e, 0xb767, 0xb764, 0xb813, 0xb823, 0xb841, 0xb83f, + 0xb840, 0xb8ed, 0xb8e3, 0xb8ea, 0xb8f0, 0xb8e6, 0xb8e9, 0xb8f1, + 0xb8ee, 0xb9d4, 0xb9d1, 0xb9dc, 0xb9ec, 0xbc69, 0xbc6d, 0xbc57, + 0xbc66, 0xbcf9, 0xbc4a, 0xbc60, 0xbc56, 0xbc59, 0xbc4c, 0xbc6a, + 0xbc62, 0xbc63, 0xbc70, 0xbc5f, 0xc50d, 0xbc64, 0xbc5d, 0xbc68, + 0xbc9f, 0xbeba, 0xbeb8, 0xbebc, 0xbeb9, 0xbeb4, 0xbf3b, 0xbf2d, + 0xbf38, 0xbf2f, 0xbf32, 0xc041, 0xc0cb, 0xc0de, 0xc0dd, 0xc0da, + 0xc0dc, 0xc110, 0xc14f, 0xc149, 0xc198, 0xc196, + /* 0x46 */ + 0xc197, 0xc1c7, 0x2c9c, 0xc1da, 0xc1d8, 0xc2a8, 0x2c0a, 0x2c9d, + 0x2ecb, 0x2f38, 0x2f39, 0x2fa6, 0x3223, 0x3222, 0x3221, 0x33ce, + 0x3592, 0x3591, 0x37ec, 0x37e0, 0x37ed, 0x3808, 0x37e5, 0x37ee, + 0x37e4, 0x37eb, 0x37e3, 0x37ea, 0x380a, 0xc359, 0x3ad1, 0x3ae3, + 0x3ad4, 0x3ad0, 0x3ad9, 0x027e, 0x1be1, 0x3ada, 0x3ad3, 0x3b4c, + 0x3b4d, 0x3b7c, 0x3b80, 0x3bcc, 0x3dff, 0x3e08, 0xc108, 0x3e01, + 0xc36b, 0x3e00, 0x3fed, 0x3ff3, 0x3fee, 0x3ff1, 0x3ff0, 0x3fde, + 0x4051, 0x4382, 0x43a9, 0x4398, 0x439d, 0x439a, 0x439e, 0x439f, + 0x43a6, 0x43a7, 0x4409, 0x442f, 0x4571, 0x456d, 0x4572, 0x46ef, + 0x46f0, 0x483b, 0x4839, 0x483c, 0x4838, 0x6afd, 0x483a, 0x4878, + 0x4879, 0x4877, 0x4998, 0x499c, 0x4999, 0x499a, 0x4c11, 0x4c0a, + 0x4bfd, 0x4c0f, 0x4c19, 0x4c03, 0x4c15, 0x4c0c, + /* 0x47 */ + 0x4c09, 0x4c12, 0x4c34, 0x4c2a, 0x4c08, 0x4c2d, 0x4c28, 0xc3b1, + 0x4c2c, 0x4c26, 0x4c33, 0x05a7, 0x4d1a, 0x4d1e, 0x5007, 0x502c, + 0x5032, 0x5028, 0x5031, 0x5029, 0x5030, 0x502a, 0x5044, 0x502e, + 0x52d1, 0x5324, 0x54f7, 0x54f4, 0x54f3, 0x54f8, 0x58b5, 0x5896, + 0x5898, 0x5895, 0x5891, 0x58b2, 0x589e, 0x5859, 0x58a3, 0x589a, + 0x589b, 0x0f20, 0x7f83, 0x5bda, 0x5bdf, 0x5c16, 0x5d1f, 0x5d2d, + 0x5d2e, 0x5d2b, 0x60b8, 0x60bb, 0x60bf, 0x60ba, 0x60d5, 0x60e3, + 0x60c1, 0x60be, 0x60bd, 0x60b4, 0x60c2, 0x60a1, 0x6087, 0x60d7, + 0x60ca, 0x60b5, 0x60da, 0x60d9, 0x60b3, 0x60d8, 0x6367, 0x6371, + 0x6362, 0x635c, 0x6368, 0x6352, 0x6356, 0x3809, 0x2e42, 0x64a0, + 0x6600, 0x65fe, 0x65ff, 0x67cb, 0xc428, 0x67ca, 0x67a9, 0x67c8, + 0x69b4, 0x69ac, 0x69aa, 0x69a9, 0x6b0e, 0x6be9, + /* 0x48 */ + 0x6bed, 0x6bf2, 0x6beb, 0x6bee, 0x6de8, 0x6ddb, 0x6dd7, 0x6de3, + 0x6de5, 0x6dee, 0x6dd5, 0x6eb3, 0x6f2d, 0x6fc1, 0x6fc3, 0x710c, + 0x710e, 0x7107, 0x7117, 0x7109, 0x7116, 0x719a, 0x719c, 0x73b4, + 0x73b7, 0x73b3, 0x3b4e, 0x7513, 0x7514, 0x76e6, 0x76dc, 0x76e8, + 0x76e5, 0x782e, 0x782c, 0x782b, 0x78cd, 0x7b3d, 0x7b32, 0x7b2d, + 0x7b45, 0x7b3e, 0x7b50, 0x7b25, 0x7b53, 0x7b23, 0x7d37, 0x7d38, + 0x7d47, 0x7d3d, 0x7d3e, 0x7d49, 0x7d4a, 0x7d1d, 0x21e9, 0x7fa5, + 0x7f8c, 0x7f8d, 0x7f89, 0x7f96, 0x7f85, 0x7f8f, 0x7f77, 0x7f8e, + 0x7f82, 0x7f8a, 0x7f88, 0x7f7b, 0x7f97, 0x7f7d, 0x7f79, 0x8059, + 0x8124, 0x812d, 0x812e, 0x812b, 0xc476, 0x81da, 0x81d8, 0x81d6, + 0x8287, 0x82a0, 0x8328, 0x8325, 0x831f, 0x83f3, 0x83f7, 0x83f6, + 0x862b, 0x865b, 0x8648, 0x23cb, 0x865c, 0x866d, + /* 0x49 */ + 0x869d, 0x8699, 0x868c, 0x8691, 0x869b, 0x869a, 0x869c, 0x8695, + 0x868d, 0x8696, 0x86a5, 0x872a, 0x87a1, 0x87a4, 0x87ad, 0x88a9, + 0x88ae, 0x88b0, 0x8c0d, 0x8b63, 0x8b71, 0x8c51, 0x8c54, 0x8c2a, + 0x8c44, 0x8c55, 0x8c99, 0x8c39, 0x8c3f, 0x8c3e, 0x8c4f, 0x8c4d, + 0x8c35, 0x8c40, 0x8c31, 0x8bd5, 0x8c2b, 0x8c33, 0x8c41, 0x8c56, + 0x8c4c, 0x8c46, 0x8c3c, 0x8c45, 0x8c43, 0x8c3d, 0x8c70, 0x8c57, + 0x8c38, 0x8c58, 0x1165, 0x8c37, 0x8e07, 0x8e06, 0x8e09, 0x90ab, + 0x9090, 0x9093, 0x90bc, 0x90a9, 0x909e, 0x90bf, 0x90aa, 0x9091, + 0x90a4, 0x909a, 0x90a7, 0x90a1, 0x909c, 0x90a2, 0x909b, 0x909f, + 0x9094, 0x908f, 0x8ef0, 0x9092, 0x9095, 0x90a5, 0x90a6, 0x9204, + 0x939c, 0x9379, 0x937a, 0x937e, 0x937b, 0x9371, 0x9381, 0x937f, + 0x937c, 0x937d, 0x9375, 0x9376, 0x948e, 0x948f, + /* 0x4a */ + 0x953e, 0x953f, 0x9540, 0x9541, 0x1304, 0x970d, 0x9717, 0x9710, + 0x970e, 0x96ea, 0x971d, 0x9703, 0x9722, 0x9704, 0x9700, 0x9720, + 0x9721, 0x9723, 0x9713, 0x9709, 0x9711, 0x97cb, 0x97ce, 0x97d0, + 0x97cc, 0x97d4, 0x3adb, 0x9809, 0x980b, 0x9885, 0x9906, 0x990d, + 0x1364, 0x9914, 0x990f, 0x9a09, 0x9a14, 0x9a0b, 0x99fc, 0x9a04, + 0x9a0a, 0x9a00, 0x99fd, 0x9a07, 0x9a06, 0x9a11, 0x9a79, 0x9a78, + 0x9b88, 0x9b80, 0x9b8b, 0x9d59, 0x9d61, 0x9d75, 0x1423, 0x9d55, + 0x9d5b, 0x9d5f, 0x9d52, 0x9d62, 0x9d72, 0x9d5d, 0x9d68, 0x9d71, + 0x9d65, 0x9d66, 0x9d67, 0x9d76, 0x9d4c, 0x9d60, 0x9d74, 0x9d50, + 0x9e8a, 0x9e81, 0x9e86, 0x9e7f, 0x9e80, 0x9fa5, 0x9fa7, 0x9fa8, + 0x9fa6, 0x9faf, 0x7f95, 0x9fb1, 0xa035, 0xa039, 0xa1c3, 0xa230, + 0xa22a, 0xa22b, 0xa22d, 0xa22e, 0xa22c, 0xa223, + /* 0x4b */ + 0xa221, 0xa222, 0xa36c, 0xa381, 0xa38f, 0xa380, 0xa3d0, 0xa3cd, + 0xa3d5, 0xa3d4, 0xa4d1, 0xa4be, 0xa4cb, 0xa4ce, 0xa4bd, 0xa4d0, + 0xa704, 0xa6d5, 0xa6d0, 0xa6d3, 0xa6fb, 0xa6d8, 0xa6d1, 0xa6fd, + 0xa6d9, 0xa6d6, 0xa6e6, 0xa6f9, 0xa9a1, 0xa99d, 0xa99e, 0x28d9, + 0xaaff, 0xab5f, 0xab57, 0xab60, 0xab59, 0xac2c, 0xac25, 0xac27, + 0xac30, 0xac24, 0xac26, 0xac2d, 0xac2e, 0xac29, 0xac31, 0xad45, + 0xad47, 0xad52, 0xad4a, 0xad50, 0xad46, 0xad4f, 0xad4e, 0xad53, + 0xaf21, 0xaf09, 0xaf1a, 0xaf1b, 0x7115, 0xaf10, 0xc4f9, 0xaf14, + 0xaf0e, 0xaf12, 0xaf0b, 0xafcf, 0xafd2, 0xafd0, 0xafd4, 0xafd3, + 0xafd1, 0x3518, 0xc4fb, 0xb009, 0xb11c, 0xb127, 0xb125, 0xb11b, + 0xb129, 0xb11f, 0xb130, 0xb124, 0xb128, 0xb119, 0xb12f, 0xb224, + 0xb221, 0xb225, 0xb226, 0xb227, 0xb276, 0xb366, + /* 0x4c */ + 0xb375, 0xb369, 0xb37e, 0xb38f, 0xb374, 0x8e10, 0xb3ad, 0xb42b, + 0xb42a, 0xb458, 0xb522, 0xb51d, 0xb52b, 0xb52c, 0xb52d, 0xb533, + 0xb51b, 0xb527, 0xb52a, 0xb528, 0xb53b, 0xb67e, 0xb671, 0xb679, + 0xb678, 0xb670, 0xb66d, 0xb67d, 0xb675, 0xb676, 0xb6de, 0xb766, + 0xb783, 0xb787, 0xb77b, 0xb789, 0xb786, 0xb782, 0xb77c, 0xb781, + 0xb843, 0xb845, 0xb8f7, 0xb8f9, 0xb8fa, 0xba05, 0xb9fe, 0xba0f, + 0xb9ff, 0xb9fa, 0xba09, 0xba20, 0xba0c, 0xba3c, 0xba22, 0xb9f8, + 0xba0a, 0xba08, 0xb9f7, 0xbc8e, 0xbc77, 0xbc8b, 0xbcb4, 0xbc8a, + 0xbc9a, 0xbc79, 0xbc83, 0xbc7f, 0xbca1, 0xbc8f, 0xbca3, 0xbc81, + 0xbc94, 0xbc7e, 0xbc82, 0xbc90, 0xbca5, 0xbcad, 0xbc9d, 0xbe67, + 0xbe69, 0xbecb, 0xbec8, 0xbed1, 0xbf40, 0xbf4b, 0xbf49, 0xbf46, + 0xbf3e, 0xbf43, 0xbf3f, 0xbfa5, 0xbfa7, 0xc04e, + /* 0x4d */ + 0xc04d, 0x499b, 0xc0e5, 0xc0e1, 0xc0e2, 0xc116, 0xc114, 0xc51b, + 0xc159, 0xc151, 0xc15f, 0xc14a, 0xc157, 0xc158, 0xc1ca, 0xc1db, + 0xc1de, 0xc1e0, 0xc1e1, 0xc1df, 0xc1e2, 0xc1e3, 0xc292, 0xc2bf, + 0xc2be, 0x2c0b, 0x2e52, 0x2e4e, 0x00b9, 0xc313, 0x2fa7, 0x3226, + 0x3227, 0x32c6, 0x330b, 0x336a, 0x3378, 0x381a, 0x3816, 0x3819, + 0x3817, 0x381b, 0x3818, 0x3820, 0x3937, 0x3aec, 0x3b81, 0xae3d, + 0x3e0f, 0x3ead, 0x3ffb, 0x4052, 0x43af, 0x43b7, 0x43b2, 0x4578, + 0x45ac, 0x4700, 0x46fe, 0x4702, 0x46fd, 0x4703, 0x4840, 0x4843, + 0x4842, 0x48b7, 0x49a2, 0x4c00, 0x4c35, 0x4c41, 0x4c05, 0x2e53, + 0x4c50, 0x4c4e, 0x4c53, 0x5053, 0x5050, 0x5057, 0x505f, 0x5055, + 0x50ea, 0x5226, 0xb430, 0x522a, 0x5228, 0x522c, 0x522d, 0x52d4, + 0x5507, 0x5558, 0x5559, 0x58c5, 0x58cd, 0x58c7, + /* 0x4e */ + 0x58e8, 0x084b, 0x5a32, 0xc297, 0x5bde, 0x5d32, 0x34c8, 0xc415, + 0x60f1, 0x60f0, 0x60ec, 0x6109, 0x60f9, 0x60f5, 0x60fe, 0x6374, + 0x6381, 0x637c, 0x6375, 0x6389, 0x6382, 0x6397, 0x6386, 0x637d, + 0x6393, 0x639c, 0x6376, 0x6380, 0x6445, 0x30a1, 0x6603, 0x67c9, + 0x67cd, 0x67d0, 0x69ad, 0x69c5, 0x6aa2, 0x6bec, 0x6bf6, 0x6bf3, + 0x6df3, 0x6dfa, 0x6df9, 0x6df5, 0x6df4, 0x6df8, 0x6eb6, 0x6eb4, + 0x6f32, 0x6fcd, 0x6fc8, 0x6fce, 0x6fca, 0x712a, 0x7121, 0x711d, + 0x73bd, 0x73be, 0x73c2, 0x0cf1, 0x73c9, 0x751f, 0x76f1, 0x76ed, + 0x76f2, 0x76e0, 0x76f7, 0x7830, 0x7837, 0x7831, 0x7836, 0x78c8, + 0x7b6d, 0x7b69, 0x7b7d, 0x7b61, 0x7b70, 0x7b71, 0x7b73, 0x7b76, + 0x7b75, 0x7b78, 0x7b79, 0x7b64, 0x7b6e, 0x7d51, 0x7d4f, 0x7d22, + 0x7faf, 0x7faa, 0x7fa3, 0x7f9d, 0x7f9c, 0x7fa1, + /* 0x4f */ + 0x7fb6, 0x7fac, 0x7fa2, 0x7fa7, 0x7fb0, 0x7fa9, 0x7fc3, 0x8131, + 0x8132, 0x8133, 0x8134, 0x8137, 0x813c, 0x81d9, 0x81dd, 0x81de, + 0x81df, 0x81e0, 0x82a5, 0x82aa, 0x82a2, 0x82a3, 0x8404, 0x8403, + 0x83fe, 0x8428, 0x86af, 0x86ad, 0x86a6, 0x87ac, 0x87a5, 0x87b0, + 0x87b1, 0x8801, 0x88b2, 0x88d2, 0x88f1, 0x8bd1, 0x8c47, 0x8cc9, + 0x8ca7, 0x8cc8, 0x8c95, 0x8c8e, 0x8c91, 0x8c7d, 0x8cee, 0x8c8d, + 0x8c8c, 0x8cb0, 0x8c96, 0x8c42, 0x8c7c, 0x8cb1, 0x8cb2, 0x8c84, + 0x8c9d, 0x8ca1, 0x8c98, 0x8cb3, 0x8c22, 0x8c7b, 0x8c8a, 0x8cce, + 0x8c80, 0x8c97, 0x8cb4, 0x8cb5, 0x8c9a, 0x8c9f, 0x8c93, 0x8e12, + 0x8e0b, 0x8e0e, 0x90a3, 0x90cc, 0x90dc, 0x90e1, 0x90de, 0x90d2, + 0x90db, 0x90d9, 0x90d7, 0x90d4, 0x90c9, 0x90eb, 0x90da, 0x90d1, + 0x9104, 0x90ca, 0x90e2, 0x91d7, 0x938c, 0x9399, + /* 0x50 */ + 0x93a2, 0x9396, 0x9394, 0x939f, 0x1267, 0x938e, 0x9403, 0x9494, + 0x9493, 0x9544, 0x972f, 0x9735, 0x972b, 0x9732, 0x972d, 0x9736, + 0x1314, 0x9731, 0x9712, 0x9733, 0x971f, 0x9734, 0x9740, 0x973f, + 0x9741, 0x97d3, 0x9889, 0x9918, 0x9910, 0x9a1a, 0x9a25, 0x9a1e, + 0x9b92, 0x9b95, 0x9b93, 0x9d84, 0x9d9a, 0x9d89, 0x9d8d, 0x9d88, + 0x9d91, 0x9d9b, 0x9d9c, 0xb148, 0x9e8e, 0x9e92, 0x9fc5, 0x9fc1, + 0x9fb8, 0x9fbe, 0x9fb5, 0x9fc7, 0xa03c, 0x1489, 0xa1ec, 0xa23f, + 0xa239, 0xa237, 0xa3a1, 0xa394, 0xa3a0, 0xa3de, 0xa3db, 0xa3df, + 0xa3dc, 0xa4d6, 0xa4dc, 0xa4dd, 0xa4e0, 0xa4e3, 0xa4e1, 0xa718, + 0xa719, 0xa753, 0xc4ec, 0xa744, 0xa70e, 0xa70f, 0xa747, 0xa717, + 0xa71d, 0xa711, 0xa8b4, 0xa8b6, 0xa9b7, 0xa9be, 0xa9c2, 0xa9b4, + 0xab31, 0xab15, 0xab83, 0xac3b, 0xac36, 0xac42, + /* 0x51 */ + 0xac50, 0xac40, 0xac34, 0xac38, 0xac3d, 0xac3e, 0xac35, 0xac3a, + 0xac46, 0xac37, 0xac39, 0xac45, 0xad77, 0xad5d, 0xad6a, 0xad76, + 0xad6b, 0xad6c, 0xad65, 0xad64, 0xad71, 0xad5f, 0xad72, 0xadfe, + 0xadff, 0xae3e, 0xaf2b, 0xaf36, 0xaf2d, 0xaf39, 0xaf3f, 0xaf3b, + 0xaf33, 0xaf42, 0xaf3a, 0xafd5, 0xafd8, 0xafd9, 0xb00d, 0xb00a, + 0xb039, 0xb03a, 0xb13d, 0xb145, 0xb13a, 0xb137, 0xb13e, 0xb142, + 0xb387, 0xb38c, 0xb382, 0xb36b, 0xb3a0, 0xb39a, 0xb390, 0xb38e, + 0xb3a1, 0xb3bd, 0xb3b2, 0xb3b5, 0xb3b7, 0xb3aa, 0xb3a2, 0xb3a5, + 0xb3ae, 0xb3ab, 0xb3bc, 0xb432, 0xb45a, 0xb564, 0xb55c, 0xb54d, + 0xb53f, 0xb53e, 0xb552, 0xb558, 0xb557, 0xb55e, 0xb553, 0xb554, + 0xb556, 0xab65, 0xb684, 0xb685, 0xb686, 0xb797, 0xb7a1, 0xb7a2, + 0x180b, 0xc50a, 0xb7a3, 0xb7a6, 0x1817, 0xb815, + /* 0x52 */ + 0xb824, 0xb84a, 0xb849, 0xb848, 0xb84b, 0xb90e, 0xb562, 0xb90b, + 0xb90a, 0xb908, 0xb906, 0xba43, 0xba47, 0xba3f, 0xba46, 0xba50, + 0x186d, 0xba4b, 0x1870, 0xba52, 0xbcd7, 0xbcbf, 0xbcd8, 0xbce0, + 0xbce7, 0xbcb8, 0xbcd5, 0xbcef, 0xbce6, 0xbce4, 0xbcd4, 0xbcd6, + 0xbcea, 0x18ed, 0xbcbb, 0xbce9, 0xc510, 0xbe6d, 0xbe70, 0xbe73, + 0xbe72, 0xbed4, 0xbece, 0xbed5, 0xbf5a, 0xbf58, 0xbf52, 0xbf50, + 0xbf55, 0xbf4e, 0xbf4d, 0xbfcb, 0xbfcc, 0xbfcd, 0xbfd1, 0xc058, + 0xc063, 0xc05e, 0xc054, 0xc05b, 0xc0e9, 0xc0e7, 0xc0e8, 0xc11d, + 0xc167, 0xc15a, 0xc15c, 0xc15b, 0xc161, 0xc1a1, 0x198d, 0xc1a4, + 0xc1e9, 0xc1ef, 0xc1e5, 0xc1f5, 0xc1eb, 0xc1ed, 0xc296, 0xc295, + 0xc2b3, 0xc2b5, 0xc2b1, 0x00a7, 0x2e4d, 0x3024, 0x322b, 0x33cf, + 0x34c9, 0x3836, 0x3831, 0x3854, 0x383a, 0x3838, + /* 0x53 */ + 0x3939, 0x3938, 0x3af4, 0x3af3, 0x3af6, 0x3afc, 0x3af5, 0x3af1, + 0x3c9c, 0x3e18, 0x3e1a, 0x3ffc, 0x3ffe, 0x4003, 0x4053, 0x422b, + 0x43c6, 0x43c1, 0x457b, 0x4706, 0x4849, 0x48b8, 0x49a3, 0x4c52, + 0x4c4d, 0x4c5f, 0x4c5e, 0x4c61, 0x4d23, 0x508c, 0x506f, 0x5075, + 0x5074, 0x5071, 0x5070, 0x506c, 0x5326, 0x5508, 0x1e07, 0x58f0, + 0x58ef, 0x58fb, 0x5910, 0x590c, 0x58f6, 0x58fe, 0x5b7c, 0x5be1, + 0x5d38, 0x5d6f, 0x6118, 0x6115, 0x611c, 0x6110, 0x6135, 0xc417, + 0x6117, 0x611d, 0x6126, 0x6128, 0x6129, 0x612a, 0x611a, 0xc416, + 0x4707, 0x63ab, 0x63ac, 0x63a1, 0x63ae, 0x63a3, 0x63a7, 0x6448, + 0x6504, 0x65fd, 0x0a5a, 0x6608, 0x67d2, 0x69c6, 0x69be, 0x6a1c, + 0x6aa6, 0x6aa7, 0x6aab, 0x6b00, 0x6bfb, 0x6bfc, 0x6bf9, 0x6c01, + 0x6e06, 0x6e04, 0xc43c, 0x6f34, 0x7136, 0x7132, + /* 0x54 */ + 0x7142, 0x712d, 0x7135, 0x73d8, 0x7523, 0x7520, 0x7701, 0x7700, + 0x7703, 0xc2bc, 0x783c, 0x7841, 0x7835, 0x78c9, 0x7b8e, 0x7b9e, + 0x7b99, 0x7bb4, 0x7baa, 0x7b9f, 0x7b96, 0x7b9d, 0x7bc3, 0x7b74, + 0x7bab, 0x0eaf, 0x7d63, 0x7d5b, 0x7d5a, 0x7fc5, 0x7fc4, 0x7fcf, + 0x7fc8, 0x7fa4, 0x7fbd, 0x7fd3, 0x8060, 0x813b, 0x81e3, 0x81e7, + 0x82a8, 0x82ac, 0x82a9, 0x832a, 0x8408, 0x8409, 0x86b9, 0x88c1, + 0x88c2, 0x88b8, 0x8ce1, 0x8ceb, 0x8ce5, 0x8cfa, 0x8ce4, 0x8d0b, + 0x8cd7, 0x8cef, 0x8ce0, 0x8cec, 0x8cfb, 0xc4b0, 0x8cd3, 0x8ce6, + 0x8cfc, 0x8ce3, 0x8ccf, 0x8cda, 0x8cdc, 0x8cd2, 0x8ca4, 0x116b, + 0x8e17, 0x8e16, 0x90f2, 0x90fc, 0x9118, 0x90f6, 0x90fe, 0x90f3, + 0x90f7, 0x9101, 0x90f9, 0x9106, 0x90f5, 0x9110, 0x90df, 0x9103, + 0x9108, 0x91d8, 0x9205, 0x9397, 0x93b3, 0x93ae, + /* 0x55 */ + 0x93af, 0x93a7, 0x93b1, 0x93a8, 0x93ac, 0x93ab, 0x9404, 0x949a, + 0x954a, 0x9742, 0x9758, 0x974b, 0x9745, 0x9749, 0x974c, 0x9759, + 0x9756, 0x131b, 0x9746, 0x9744, 0x975b, 0x9769, 0x988e, 0x988f, + 0x991e, 0x86bc, 0x9a2f, 0x9b9e, 0x9b9d, 0x9b9f, 0x9b9c, 0x9db4, + 0x9dae, 0x9dab, 0x9db3, 0x9daf, 0x9dc2, 0x9e93, 0x9e95, 0x9e96, + 0x9e97, 0x9fcf, 0x9fce, 0x9fcb, 0xa04b, 0xa246, 0xa243, 0xa245, + 0xa251, 0xa3ae, 0xa3af, 0xa3b0, 0xa3b8, 0xa3e2, 0xa3e3, 0xa3e6, + 0xa4ed, 0xa4ea, 0xa53a, 0xa759, 0xa784, 0xa75f, 0xa77c, 0xa75c, + 0xa758, 0xa755, 0xa75d, 0xa77e, 0xa780, 0xa783, 0xa757, 0x1563, + 0xa75e, 0xa8ba, 0xa9d5, 0xab58, 0xab68, 0xab67, 0xac4a, 0xac4c, + 0xac52, 0xac49, 0xac4e, 0xac47, 0xac4d, 0xac4b, 0xac4f, 0xad7e, + 0xad87, 0xad83, 0xad89, 0x69ca, 0xad86, 0xad88, + /* 0x56 */ + 0xae47, 0xae42, 0xae49, 0xae48, 0x1680, 0x1684, 0x167f, 0xaf44, + 0xaf51, 0xaf46, 0xaf47, 0xafe4, 0xb00f, 0xb03f, 0xb14b, 0xb157, + 0xb152, 0x16f1, 0xb151, 0xb158, 0xb15e, 0xb153, 0xb15d, 0xb14d, + 0xb23c, 0xb23f, 0xb246, 0xb23e, 0xb244, 0xb245, 0xb241, 0xb238, + 0xb242, 0xb243, 0xb27a, 0xb3a3, 0xb3ba, 0xb3c0, 0xb3c4, 0xb3c6, + 0xb3cb, 0xb461, 0xb57a, 0xb573, 0xb572, 0xb574, 0xb580, 0xb581, + 0x2947, 0xb695, 0xb68f, 0xb690, 0xb692, 0xb694, 0xb68b, 0xb6e6, + 0xb7b2, 0xb7b8, 0xb7bd, 0xb7be, 0xb7ce, 0xb7ba, 0xb816, 0xb826, + 0xb825, 0xb84c, 0xb850, 0xb84e, 0xb851, 0xb852, 0xb914, 0xb915, + 0xb91b, 0xba82, 0xba99, 0xba9a, 0xba7d, 0xba85, 0xba86, 0xba9c, + 0xba79, 0xba7b, 0xba80, 0xba83, 0xba81, 0xbd1e, 0xbd1b, 0xbd2a, + 0xbcfb, 0xbd05, 0xbd20, 0xbd11, 0xbd04, 0xbcfd, + /* 0x57 */ + 0xbd03, 0xbd10, 0xbd18, 0xbd0a, 0xbd4e, 0xbd09, 0xbd07, 0xbd1c, + 0x191c, 0xbe77, 0xbe76, 0xbed8, 0xbed9, 0xbf61, 0xbf5c, 0xbf5e, + 0xbf60, 0xbfaa, 0xbfd6, 0xbfd8, 0xc009, 0xc008, 0xc06b, 0xc065, + 0xc073, 0xc074, 0xc0ed, 0xc124, 0xc125, 0xc16a, 0xc1a7, 0xc1a8, + 0xc20b, 0xc1fa, 0xc1f9, 0xc1ff, 0xc204, 0xc1f6, 0xc205, 0xc299, + 0xc2ab, 0xc2bd, 0xc2b8, 0x00a8, 0x2e64, 0x2e5a, 0x2f72, 0x337a, + 0x3595, 0x385f, 0x3861, 0x385e, 0x385a, 0x385c, 0x385d, 0x386e, + 0x3857, 0x3858, 0x3b02, 0x3b0b, 0x3b08, 0x3b51, 0x3e25, 0x3e28, + 0x3e23, 0x3e21, 0x3e24, 0x3e29, 0x4006, 0x400a, 0x43ca, 0x43cc, + 0x43cb, 0x43cf, 0x457f, 0x457c, 0x45d6, 0x4709, 0x470b, 0x4776, + 0x487d, 0x49a5, 0x4c5b, 0x4c5c, 0x4c5d, 0x4c65, 0x506d, 0x5082, + 0x5083, 0x5087, 0x5095, 0x508a, 0x52d6, 0x5328, + /* 0x58 */ + 0x550d, 0x592e, 0xc3ee, 0x592d, 0x5921, 0x5919, 0x5a3b, 0x5a3c, + 0x5a3a, 0x5b7e, 0x5d3b, 0x6147, 0x6139, 0x6134, 0x6136, 0x6146, + 0x613b, 0x6141, 0x6145, 0x63c0, 0x63c4, 0x63ba, 0x63bd, 0x63be, + 0x64a3, 0x660c, 0x67d9, 0x69cd, 0x6aae, 0x6bff, 0x6c24, 0x6ebb, + 0x6ebc, 0x6f36, 0x6fd5, 0x6fd3, 0x6fd6, 0x713c, 0x713f, 0x73de, + 0x73e3, 0x7527, 0x7529, 0x0d8b, 0x7705, 0x7707, 0x770c, 0x78d0, + 0x7bbe, 0x7bbc, 0x7bd0, 0x7bc2, 0x7bb5, 0x7bc9, 0x7d66, 0x0f2b, + 0x7fd5, 0x7fe2, 0x7fdc, 0x7fe3, 0x7fda, 0x7fc2, 0x7fe8, 0x81e9, + 0x82af, 0x82ad, 0x82ae, 0x840b, 0x86c1, 0x87b6, 0x87b9, 0x88c0, + 0x8ca5, 0x8d28, 0x8d22, 0x8d29, 0x8d18, 0x8d1f, 0x8d1c, 0x8d12, + 0x8d2a, 0x117a, 0x8d21, 0x8d2b, 0x8d17, 0x8cf0, 0x8d16, 0x8d23, + 0x912b, 0x9126, 0x913d, 0x9122, 0x913a, 0x9131, + /* 0x59 */ + 0x9132, 0x9154, 0x9121, 0x9135, 0x1209, 0x912e, 0x9130, 0x912f, + 0x9136, 0x91da, 0x91d9, 0x93bb, 0x93bc, 0x93b7, 0x93c2, 0x93bd, + 0x93b2, 0x126d, 0x7144, 0x7bd1, 0x9752, 0x976b, 0x9767, 0x131f, + 0x9761, 0x976c, 0x9751, 0x9774, 0x9777, 0x976f, 0x976d, 0x9768, + 0xc4d1, 0x9784, 0x9890, 0x9892, 0x9893, 0x991f, 0x9a31, 0x9a38, + 0x9a39, 0x9a37, 0x9bab, 0x9dc3, 0x9dc8, 0x9dcb, 0x9dcf, 0x9e98, + 0x9fd4, 0x9fd3, 0x9fd8, 0x9fd9, 0x9fdd, 0x9fd1, 0x9fd6, 0xa03e, + 0xa258, 0xa257, 0xa255, 0xa3c4, 0xa3e4, 0xa4ee, 0xa4ef, 0xa4f3, + 0xa4f2, 0xa4f0, 0xa7ab, 0xa79a, 0xa7af, 0xa797, 0x156a, 0x156c, + 0xa7bf, 0xa794, 0xa793, 0xa8be, 0xa8bb, 0xa8bc, 0xa9d9, 0xab6c, + 0xac53, 0xac54, 0xac5b, 0xac58, 0xac56, 0xac57, 0xad9f, 0xad94, + 0xad96, 0xad97, 0xae4a, 0xae4b, 0xaf55, 0xaf5a, + /* 0x5a */ + 0xaf5e, 0xaf5f, 0xaf59, 0xaf5b, 0xaf58, 0xaf54, 0xafe8, 0xafeb, + 0xafec, 0xb013, 0xb166, 0xb16b, 0xb162, 0xb169, 0xb163, 0xb15f, + 0xb14e, 0xb248, 0xb24a, 0xb3e3, 0xb3db, 0xb3d8, 0xb3d6, 0xb586, + 0xb590, 0xb591, 0xb588, 0xb594, 0xb583, 0x17b2, 0xb59c, 0xb58d, + 0xb585, 0xb698, 0xb69a, 0xb69c, 0xb6e7, 0xb7c5, 0xb7d0, 0xb7d1, + 0xb819, 0xb827, 0x181d, 0xb854, 0xb92d, 0xb922, 0x182d, 0xb91f, + 0xbabd, 0xbaae, 0xbabb, 0xbaad, 0xbabc, 0xbab9, 0xbab4, 0xbacb, + 0xbab7, 0xbab3, 0xbaba, 0xbab6, 0xbacd, 0xbabe, 0xbac9, 0xc50b, + 0xbd5f, 0xbd3b, 0xbd61, 0xbd5c, 0xbd8a, 0xbd5a, 0xbd4d, 0xbd46, + 0xbd44, 0xbd3d, 0xbd40, 0xbd3c, 0xbd8c, 0xbd41, 0xbd4c, 0xbd3e, + 0xbd4a, 0xbe7c, 0xbe7a, 0xbf65, 0xbf6e, 0xbf69, 0xbf6a, 0xbf6f, + 0xbf6c, 0xbf70, 0xbf68, 0xbf6b, 0x1945, 0xbfac, + /* 0x5b */ + 0xbfde, 0xbfdd, 0xbfdc, 0x63c5, 0xc08c, 0xc083, 0xc082, 0xc088, + 0xc085, 0xc081, 0xc0f5, 0xc0ef, 0xc0f4, 0xc0f2, 0xc0f6, 0xc0f3, + 0xc0f0, 0xc0f1, 0xc12b, 0xc127, 0xc128, 0xc16c, 0xc1ae, 0xc20e, + 0xc21b, 0xc216, 0xc21f, 0xc222, 0xc220, 0xc221, 0xc214, 0xc213, + 0xc29d, 0xc29c, 0xc29e, 0xc29f, 0x2e6b, 0x32c8, 0x3878, 0x3876, + 0x3870, 0x3871, 0x3b0a, 0x3e2c, 0x4711, 0x487e, 0x4c57, 0x4c66, + 0x4c69, 0x4c67, 0x4c68, 0x4c71, 0x4c6f, 0xbfae, 0x508b, 0x5096, + 0x5235, 0x523a, 0x526b, 0x5516, 0x5943, 0x5946, 0x593f, 0x593b, + 0x593d, 0x5ab1, 0x5ab2, 0x5be4, 0x5d40, 0x615d, 0x6151, 0x614d, + 0x614c, 0x615b, 0x63d4, 0x63d2, 0x63ca, 0x63c8, 0x63d0, 0x63c9, + 0x6449, 0x64a4, 0x6612, 0x660f, 0x6611, 0x67db, 0x67dd, 0x67dc, + 0x69d4, 0x6a21, 0x6ab2, 0x6c04, 0x6c02, 0x6e11, + /* 0x5c */ + 0x6e16, 0x6e10, 0x6ebe, 0x8e1a, 0x714c, 0x714a, 0x73f2, 0x73f1, + 0x752a, 0x752c, 0x752f, 0x7531, 0x7711, 0x7712, 0x784b, 0x7bdb, + 0x7bd6, 0x7bdd, 0x7be2, 0x7be4, 0x7be0, 0x7bdf, 0x7be3, 0x7d6e, + 0x7d71, 0x7fe9, 0x7fea, 0x8063, 0x81eb, 0x81ea, 0x86bd, 0x86bb, + 0x86c6, 0x86cc, 0x86c8, 0x63cf, 0x86c9, 0x86ca, 0x86cf, 0x86d0, + 0x87ba, 0x87fb, 0x8803, 0x88c4, 0x8d49, 0x8d53, 0x8d36, 0x8d4a, + 0x8d41, 0x8d4e, 0x8d19, 0x8d4d, 0x8d45, 0x8d4c, 0x8d47, 0x8d48, + 0x8d4f, 0x8d37, 0x8d42, 0x914a, 0x9146, 0x120a, 0x9149, 0x914f, + 0x9151, 0x914c, 0x120c, 0x9206, 0x9551, 0x977a, 0x9783, 0x977e, + 0x977f, 0x9780, 0x6ab5, 0x9891, 0x9894, 0x9895, 0x9921, 0x9920, + 0x9a3d, 0x9a40, 0x9a46, 0x9a84, 0x9bac, 0x9bad, 0x142e, 0x9dda, + 0x9dd9, 0x9fe2, 0x9fe1, 0x9fe3, 0x9fe4, 0x9fde, + /* 0x5d */ + 0x9fdf, 0xa241, 0xa259, 0xa25c, 0xa25a, 0xa3e8, 0xa4f6, 0xa4fc, + 0xa4f7, 0xa4fa, 0xa4f9, 0xa7c4, 0xa7be, 0xa7d2, 0xa7bd, 0xa795, + 0xa7d4, 0xa9e4, 0xac61, 0xac62, 0xac63, 0xac64, 0xac60, 0xac5c, + 0xac5d, 0xac5e, 0xada5, 0xada6, 0xae4c, 0xaf68, 0xaf6e, 0xaf71, + 0xaf6b, 0xaf6f, 0xafee, 0xaff1, 0xaff0, 0xafef, 0xb015, 0xb014, + 0xab6e, 0xb047, 0xb17c, 0xb17a, 0xb174, 0xb176, 0xb16e, 0xb178, + 0xb16d, 0xb16c, 0xb24e, 0xb3d7, 0xb3ea, 0xb3e5, 0xb464, 0xb5b3, + 0xb5a3, 0xb5a5, 0xb5a7, 0xb5a2, 0xb59f, 0xb5a6, 0xb59e, 0xb5a8, + 0xb6a9, 0xb6a6, 0xb6aa, 0xb6ab, 0xb6a0, 0xb6a1, 0xb6a8, 0xb6e8, + 0xb6e9, 0xb6ea, 0xb7e4, 0xb7df, 0xb7e0, 0xb828, 0xb85d, 0xb85b, + 0xb856, 0xb857, 0xb85f, 0xb862, 0xbae1, 0xbae3, 0xbade, 0xbad9, + 0xbae8, 0xbaf2, 0xbaf6, 0xbae6, 0xbaf4, 0xbaf5, + /* 0x5e */ + 0xbae5, 0xbae2, 0x188d, 0xbd96, 0xbdaa, 0xbd97, 0xbd70, 0xbda1, + 0xbd9d, 0xbda9, 0xbd6f, 0xbd7e, 0xbd94, 0xbd9a, 0xbd73, 0xbd87, + 0xbd71, 0xbd77, 0xbd88, 0xbd8d, 0xbd85, 0xbd78, 0xbdad, 0xbe80, + 0xbe81, 0xbee5, 0xbee7, 0xbf7c, 0xbfaf, 0xbfe1, 0xc096, 0xc0a3, + 0xc090, 0xc0f8, 0xc12e, 0xc175, 0xc17e, 0xc17d, 0xc17b, 0xc178, + 0xc1b0, 0xc234, 0xc236, 0xc230, 0xc51d, 0xc22e, 0xc237, 0x34ce, + 0x3597, 0x3598, 0x387c, 0x387e, 0x387d, 0x387f, 0x3b0f, 0x3ca4, + 0x3e31, 0x3e2e, 0x3e2f, 0x3e32, 0x422c, 0x43d4, 0x43dc, 0x43d8, + 0x440e, 0x4583, 0x4584, 0x4712, 0x4c72, 0x4c7c, 0x4c7e, 0x50a6, + 0x50a0, 0x509e, 0x50a2, 0x532a, 0x5518, 0x594d, 0x5958, 0x595b, + 0x7714, 0xc3f2, 0x5be6, 0x6164, 0x6168, 0x6160, 0x6162, 0x63d7, + 0x644b, 0x67e0, 0x6a22, 0x6c05, 0x6e19, 0x6e1a, + /* 0x5f */ + 0x6ec3, 0x6fd8, 0x6fdc, 0x714f, 0x73f7, 0x73f4, 0x73f8, 0x7713, + 0x7850, 0x7bf0, 0x7be9, 0x7bef, 0x7bed, 0x7bea, 0x7bf8, 0x7c05, + 0x7bf2, 0x7d72, 0x0f31, 0x7ff9, 0x7ff3, 0x7ff6, 0x7ff2, 0x7ff7, + 0x8066, 0x8065, 0x8140, 0xc477, 0x86d1, 0x86d3, 0x8804, 0x8d59, + 0x8d60, 0x8d5b, 0x8d5d, 0x8d5e, 0x8d69, 0x8d5c, 0x8d61, 0x8d6a, + 0x8d5f, 0x914e, 0x915c, 0x9160, 0x9163, 0x91db, 0x93ca, 0x93c9, + 0x93c8, 0x94a5, 0x94a3, 0x978e, 0x9787, 0x9789, 0x9785, 0x9786, + 0x978f, 0x978a, 0x9790, 0x9898, 0x989b, 0x9a47, 0x9a49, 0x9a48, + 0x9de5, 0x9dea, 0x9ded, 0x9ff0, 0x9fef, 0x9ff2, 0x9fec, 0xa040, + 0xa260, 0xa25f, 0xa3eb, 0xa3ec, 0xa500, 0xa501, 0xa7e2, 0xa7df, + 0xa7e0, 0xa7e1, 0xa7e3, 0xa8c3, 0xa9eb, 0xa9ea, 0xab61, 0xab71, + 0xac6b, 0xac68, 0xac69, 0xac67, 0xadb0, 0xadb1, + /* 0x60 */ + 0xadb2, 0xae51, 0xaf74, 0xb17f, 0xb184, 0xb253, 0xb254, 0xb3f0, + 0xb3f4, 0xb3f1, 0xb437, 0xb5bf, 0x17bc, 0x17bb, 0xb5bd, 0xb5be, + 0xb5b7, 0xb5c0, 0xb5ba, 0xb5b8, 0xb5bc, 0xb5bb, 0xb6eb, 0xb7e7, + 0xb81d, 0xb81c, 0xb863, 0x484b, 0xb938, 0xb936, 0xb934, 0xb937, + 0xbb06, 0xbb1c, 0xbb02, 0xbb1d, 0xbb1e, 0xbae0, 0xbb11, 0xbb18, + 0xbb21, 0xbb20, 0xbb10, 0xbdbd, 0xbdae, 0xbdb5, 0xbdb8, 0xbdb9, + 0xbdbe, 0xbdc4, 0xbdbc, 0xbdba, 0xbe83, 0xbeea, 0xbeec, 0xbf7e, + 0xbf7b, 0xbfe5, 0xc0a7, 0xc09e, 0xc09a, 0xc12f, 0xc131, 0xc183, + 0xc1b5, 0xc246, 0xc241, 0xc243, 0xc23d, 0xc242, 0xc23b, 0xc247, + 0x336b, 0x33d0, 0x388e, 0x4011, 0xc371, 0xc389, 0x484c, 0x532b, + 0x594f, 0x595e, 0x5963, 0x596b, 0x5a3f, 0x5be9, 0x616d, 0x616b, + 0x616a, 0xbb2a, 0x63e0, 0x63dd, 0x63e1, 0x63de, + /* 0x61 */ + 0x63dc, 0x644d, 0x6616, 0x67e3, 0x69e5, 0x69e4, 0x6e1d, 0x754b, + 0xc2c1, 0x784e, 0x78d6, 0x7bfd, 0x7c07, 0x7bfe, 0x7c03, 0x7c0b, + 0x7bff, 0x7d7a, 0x7d77, 0x7ffb, 0x8143, 0x81ed, 0x87bc, 0x63df, + 0x8805, 0x88c6, 0x88c5, 0x8d74, 0x8d73, 0x8d72, 0x8d78, 0x9173, + 0x917a, 0x6e1c, 0x9176, 0x9175, 0x9177, 0x93cf, 0x93ce, 0x93cd, + 0x94a8, 0x9798, 0x9792, 0x9794, 0x989a, 0x9bb4, 0x9deb, 0x9df4, + 0x9df3, 0x9dee, 0x9df2, 0x9df0, 0xa264, 0xa805, 0xa7fb, 0xa7fc, + 0xa9f3, 0xac6c, 0xadba, 0xaf79, 0xaf7e, 0xaf78, 0xaff4, 0xb016, + 0xb257, 0xb5c8, 0xb5c3, 0xb5ce, 0xb6b3, 0xb6ed, 0xb6ee, 0xb7f1, + 0xb7f8, 0x1814, 0xb864, 0xb865, 0xbb35, 0xbb29, 0xbb2c, 0xbb31, + 0xbb2b, 0xbb2e, 0xbb25, 0xbdda, 0xbde0, 0xbdd4, 0xbde1, 0xbddd, + 0xbfe7, 0xc012, 0xc0ae, 0xc0af, 0xc186, 0xc185, + /* 0x62 */ + 0xc1d1, 0xc258, 0xc23f, 0xc252, 0xc24b, 0xc253, 0xc250, 0xc256, + 0xc257, 0xc2cd, 0xc2cb, 0x3231, 0x3230, 0x33d1, 0x021c, 0x3892, + 0x3890, 0x388f, 0x3893, 0x3891, 0x0372, 0x4713, 0x487f, 0x50ac, + 0x6170, 0x63e5, 0x6a23, 0x6a24, 0x6c08, 0x6c07, 0x6e1f, 0x6e20, + 0x6e21, 0x6fe1, 0x7154, 0x7157, 0x7155, 0x73fa, 0x7538, 0x8d86, + 0x7537, 0x7853, 0x7d7e, 0x7d7b, 0xc471, 0x7ffd, 0x7ffc, 0x8146, + 0x8732, 0x88c7, 0x8d71, 0x8d83, 0x8d6f, 0x8d7e, 0x8d7d, 0x8d81, + 0x8d7c, 0x918a, 0x917e, 0x9180, 0x917d, 0x917f, 0x9182, 0x93d4, + 0x93d0, 0x93d2, 0x9555, 0x979b, 0x979a, 0x9a4e, 0x9df1, 0x9ff8, + 0x9ffd, 0xa25e, 0xa266, 0xa505, 0xa80a, 0xa80b, 0xa80e, 0xa80d, + 0xa811, 0xa809, 0xa810, 0xa80c, 0xa812, 0xa8c4, 0xa9f7, 0xa9f8, + 0xab6a, 0xab6b, 0xadc0, 0xadc2, 0xaf85, 0xaf80, + /* 0x63 */ + 0xaf84, 0xaf81, 0xadc4, 0xb18b, 0xb18d, 0xb18e, 0xb6b7, 0xb6b9, + 0xb6ef, 0xb7fb, 0xb7ff, 0xb867, 0xb868, 0xb869, 0xb93f, 0xbb3c, + 0xbb4c, 0xbb3d, 0xbb3e, 0xbb3f, 0xbb3b, 0xbdff, 0x190e, 0xbdf6, + 0xbdee, 0xbdfc, 0xbdf8, 0xbe01, 0xbdfa, 0xbe88, 0xbf80, 0xc011, + 0xc0fe, 0xc100, 0xc135, 0x6f3c, 0xc1bd, 0xc1bb, 0xc25c, 0xc25a, + 0xc2d1, 0xc2d0, 0x340b, 0x5973, 0x3e39, 0x401a, 0x43e3, 0x4587, + 0x4777, 0x4778, 0x50b1, 0x596a, 0x5974, 0x5beb, 0x617b, 0x64a5, + 0x67e4, 0x6c0b, 0x6c0e, 0x6c0c, 0x7539, 0x7c10, 0x7c11, 0x7c16, + 0x7d81, 0x7d80, 0x7ffe, 0x8001, 0x8000, 0x8147, 0x81ef, 0x8d88, + 0x918b, 0x918d, 0x9187, 0x9185, 0x918f, 0x9184, 0x9188, 0x918e, + 0x918c, 0x93d7, 0x93d6, 0x979f, 0x4588, 0x9e03, 0x9ffe, 0xa3ef, + 0xa509, 0xa508, 0xa820, 0xa824, 0xa81f, 0xac70, + /* 0x64 */ + 0xae56, 0xaff7, 0xaff8, 0xaff6, 0xb190, 0xb25e, 0xb3f7, 0xb5d6, + 0xb5d5, 0xb6bb, 0xb6f0, 0xb801, 0xb86c, 0xb941, 0xb942, 0xbb4f, + 0xbb53, 0xbb58, 0xbe12, 0xbe04, 0xbe13, 0xbe05, 0xbe0d, 0xbf82, + 0xbf81, 0xc0b5, 0xc0ba, 0xc1be, 0xc265, 0xc263, 0xc26e, 0xc26a, + 0xc26c, 0xc2c4, 0x336c, 0x97a5, 0x4012, 0x484d, 0x551f, 0x5977, + 0x5978, 0x5d44, 0x617c, 0x63eb, 0x63ea, 0x63ec, 0x64a7, 0x6619, + 0x6e23, 0x2074, 0x7401, 0x7c1c, 0x8003, 0x8148, 0x86da, 0x8d91, + 0x8d92, 0x9196, 0x9197, 0x9191, 0x9193, 0x93d8, 0x93d5, 0x9557, + 0x9558, 0x97a2, 0x9e05, 0x9ffa, 0xa50c, 0xa50a, 0xa82e, 0xa829, + 0xa82f, 0xa8c5, 0xac72, 0xadc8, 0xae5a, 0xae59, 0xaf89, 0xaf88, + 0xb5db, 0xb5d9, 0xb5da, 0xb6bc, 0x17ec, 0xb806, 0xb805, 0xb86f, + 0xb86d, 0xb870, 0xbb60, 0xbb5e, 0xbb63, 0xbb5a, + /* 0x65 */ + 0xbb5f, 0xbe19, 0xbe1d, 0xbe1b, 0xbe22, 0xbe1c, 0xbe1e, 0xbef7, + 0xbf84, 0xc015, 0xc0b8, 0xc0c1, 0xc101, 0xc10a, 0xc1d2, 0xc275, + 0xc274, 0xc272, 0x34d0, 0x401b, 0x4410, 0x4779, 0x63ed, 0x6ab9, + 0x6e24, 0x6ec5, 0x7403, 0x814a, 0x86f7, 0x87c1, 0x87c2, 0x8d94, + 0x9199, 0x919a, 0x955a, 0x97a8, 0x9825, 0x989e, 0xa041, 0xa832, + 0xa833, 0xadcb, 0xadca, 0xadcc, 0xb193, 0xb5e0, 0xb871, 0xbb6b, + 0xbe2b, 0xbe29, 0xbe1a, 0xbe26, 0xbe27, 0xbe2a, 0xbef8, 0x6f3d, + 0xc276, 0x3b18, 0x597a, 0x617f, 0x0e79, 0x81f0, 0x8d9a, 0x8d96, + 0x919e, 0x919d, 0x91dc, 0x93da, 0x9e0b, 0xa002, 0xa042, 0xa267, + 0xaf8b, 0xb5e2, 0xbb71, 0xbe2f, 0xbe2e, 0xc0c6, 0xc18e, 0xc27b, + 0xc277, 0xc278, 0xc27c, 0x597c, 0x8007, 0x8d97, 0x97d9, 0xa50d, + 0xa50e, 0xb5e3, 0xb5e4, 0xb6f3, 0xb875, 0xbe37, + /* 0x66 */ + 0xbe35, 0xc18f, 0xc280, 0xc27f, 0xc2d4, 0x50b4, 0xbfec, 0xab75, + 0x6c10, 0x8069, 0x91a4, 0x93db, 0xadd1, 0xaf8d, 0xbb76, 0xbe39, + 0xc284, 0xc282, 0x34d2, 0x63ee, 0x6c11, 0x7d84, 0xab74, 0xaf8f, + 0xaf8e, 0xbe3b, 0x32cb, 0xc288, 0xc286, 0x555c, 0x71a4, 0xac75, + 0xc28b, 0x3b19, 0x989f, 0xb5e5, 0xbe40, 0x6c12, 0xbefb, 0xc28c, + 0x71a5, 0xb877, 0xb878, 0xc2d6, 0x93df, 0xadd2, 0x3b1a, 0x97a9, + 0xadd3, 0xc0ca, 0x87c4, 0x94b1, 0xb264, +}; + +static const ucs4_t cns11643_7_2uni_upages[198] = { + 0x03400, 0x03500, 0x03600, 0x03700, 0x03800, 0x03900, 0x03a00, 0x03b00, + 0x03c00, 0x03d00, 0x03e00, 0x03f00, 0x04000, 0x04100, 0x04200, 0x04300, + 0x04400, 0x04500, 0x04600, 0x04700, 0x04800, 0x04900, 0x04a00, 0x04b00, + 0x04c00, 0x04d00, 0x05600, 0x05800, 0x06100, 0x06400, 0x06700, 0x07100, + 0x07600, 0x07c00, 0x07f00, 0x08100, 0x08600, 0x08d00, 0x08f00, 0x09300, + 0x09500, 0x09a00, 0x0ff00, 0x20000, 0x20100, 0x20300, 0x20400, 0x20500, + 0x20600, 0x20700, 0x20800, 0x20900, 0x20a00, 0x20b00, 0x20f00, 0x21000, + 0x21100, 0x21200, 0x21400, 0x21500, 0x21600, 0x21800, 0x21900, 0x21a00, + 0x21b00, 0x21c00, 0x21d00, 0x21f00, 0x22000, 0x22100, 0x22200, 0x22300, + 0x22400, 0x22500, 0x22700, 0x22800, 0x22900, 0x22a00, 0x22c00, 0x22d00, + 0x22e00, 0x22f00, 0x23000, 0x23100, 0x23200, 0x23300, 0x23500, 0x23600, + 0x23700, 0x23800, 0x23900, 0x23a00, 0x23b00, 0x23c00, 0x23e00, 0x23f00, + 0x24000, 0x24100, 0x24300, 0x24400, 0x24500, 0x24600, 0x24700, 0x24800, + 0x24900, 0x24a00, 0x24b00, 0x24c00, 0x24d00, 0x24e00, 0x24f00, 0x25000, + 0x25200, 0x25300, 0x25400, 0x25500, 0x25600, 0x25700, 0x25800, 0x25900, + 0x25a00, 0x25b00, 0x25c00, 0x25d00, 0x25e00, 0x25f00, 0x26000, 0x26100, + 0x26200, 0x26300, 0x26400, 0x26500, 0x26600, 0x26700, 0x26800, 0x26900, + 0x26a00, 0x26d00, 0x26e00, 0x26f00, 0x27000, 0x27100, 0x27200, 0x27300, + 0x27400, 0x27500, 0x27600, 0x27700, 0x27800, 0x27900, 0x27a00, 0x27b00, + 0x27c00, 0x27d00, 0x27e00, 0x27f00, 0x28000, 0x28100, 0x28200, 0x28300, + 0x28400, 0x28500, 0x28600, 0x28700, 0x28800, 0x28900, 0x28a00, 0x28b00, + 0x28c00, 0x28d00, 0x28e00, 0x28f00, 0x29000, 0x29100, 0x29200, 0x29300, + 0x29400, 0x29500, 0x29600, 0x29700, 0x29800, 0x29900, 0x29a00, 0x29b00, + 0x29c00, 0x29d00, 0x29e00, 0x29f00, 0x2a000, 0x2a100, 0x2a200, 0x2a300, + 0x2a400, 0x2a500, 0x2a600, 0x2f800, 0x2f900, 0x2fa00, +}; + +static int +cns11643_7_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x21 && c1 <= 0x66)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + ucs4_t wc = 0xfffd; + unsigned short swc; + { + if (i < 6539) + swc = cns11643_7_2uni_page21[i], + wc = cns11643_7_2uni_upages[swc>>8] | (swc & 0xff); + } + if (wc != 0xfffd) { + *pwc = wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + diff --git a/libs/libiconv/lib/cns11643_inv.h b/libs/libiconv/lib/cns11643_inv.h new file mode 100644 index 00000000..3a7c379a --- /dev/null +++ b/libs/libiconv/lib/cns11643_inv.h @@ -0,0 +1,15412 @@ +/* + * Copyright (C) 1999-2005 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CNS 11643-1992 planes 1-7, CNS 11643-1986 plane 15 + */ + +static const unsigned char cns11643_inv_2charset[3*55442] = { + 0x1,0x21,0x70, 0x1,0x22,0x78, 0x1,0x22,0x34, 0x1,0x21,0x31, + 0x1,0x22,0x32, 0x1,0x22,0x33, 0x1,0x25,0x6f, 0x1,0x25,0x6d, + 0x1,0x25,0x6e, 0x1,0x25,0x70, 0x1,0x25,0x6c, 0x1,0x24,0x75, + 0x1,0x24,0x76, 0x1,0x24,0x77, 0x1,0x24,0x78, 0x1,0x24,0x79, + 0x1,0x24,0x7a, 0x1,0x24,0x7b, 0x1,0x24,0x7c, 0x1,0x24,0x7d, + 0x1,0x24,0x7e, 0x1,0x25,0x21, 0x1,0x25,0x22, 0x1,0x25,0x23, + 0x1,0x25,0x24, 0x1,0x25,0x25, 0x1,0x25,0x26, 0x1,0x25,0x27, + 0x1,0x25,0x28, 0x1,0x25,0x29, 0x1,0x25,0x2a, 0x1,0x25,0x2b, + 0x1,0x25,0x2c, 0x1,0x25,0x2d, 0x1,0x25,0x2e, 0x1,0x25,0x2f, + 0x1,0x25,0x30, 0x1,0x25,0x31, 0x1,0x25,0x32, 0x1,0x25,0x33, + 0x1,0x25,0x34, 0x1,0x25,0x35, 0x1,0x25,0x36, 0x1,0x25,0x37, + 0x1,0x25,0x38, 0x1,0x25,0x39, 0x1,0x25,0x3a, 0x1,0x25,0x3b, + 0x1,0x25,0x3c, 0x1,0x25,0x3d, 0x1,0x25,0x3e, 0x1,0x25,0x3f, + 0x1,0x25,0x40, 0x1,0x25,0x41, 0x1,0x25,0x42, 0x1,0x25,0x43, + 0x1,0x25,0x44, 0x1,0x25,0x45, 0x1,0x25,0x46, 0x1,0x21,0x39, + 0x1,0x21,0x37, 0x1,0x22,0x5d, 0x1,0x21,0x64, 0x1,0x21,0x65, + 0x1,0x21,0x66, 0x1,0x21,0x67, 0x1,0x21,0x2d, 0x1,0x21,0x2c, + 0x1,0x21,0x6a, 0x1,0x21,0x6b, 0x1,0x21,0x6f, 0x1,0x22,0x23, + 0x1,0x42,0x42, 0x1,0x22,0x6a, 0x1,0x22,0x22, 0x1,0x22,0x6b, + 0x1,0x24,0x2b, 0x1,0x24,0x2c, 0x1,0x24,0x2d, 0x1,0x24,0x2e, + 0x1,0x24,0x2f, 0x1,0x24,0x30, 0x1,0x24,0x31, 0x1,0x24,0x32, + 0x1,0x24,0x33, 0x1,0x24,0x34, 0x1,0x26,0x35, 0x1,0x26,0x36, + 0x1,0x26,0x37, 0x1,0x26,0x38, 0x1,0x26,0x39, 0x1,0x26,0x3a, + 0x1,0x26,0x3b, 0x1,0x26,0x3c, 0x1,0x26,0x3d, 0x1,0x26,0x3e, + 0x1,0x22,0x58, 0x1,0x22,0x55, 0x1,0x22,0x57, 0x1,0x22,0x56, + 0x1,0x22,0x59, 0x1,0x22,0x5a, 0x1,0x22,0x5c, 0x1,0x22,0x5b, + 0x1,0x22,0x61, 0x1,0x22,0x35, 0x1,0x22,0x3c, 0x1,0x22,0x49, + 0x1,0x22,0x48, 0x1,0x22,0x45, 0x1,0x22,0x46, 0x1,0x22,0x4d, + 0x1,0x22,0x4e, 0x1,0x22,0x50, 0x1,0x22,0x4f, 0x1,0x22,0x44, + 0x1,0x22,0x3d, 0x1,0x22,0x3b, 0x1,0x22,0x3e, 0x1,0x22,0x39, + 0x1,0x22,0x3a, 0x1,0x22,0x47, 0x1,0x22,0x4a, 0x1,0x42,0x21, + 0x1,0x42,0x22, 0x1,0x42,0x23, 0x1,0x42,0x24, 0x1,0x42,0x25, + 0x1,0x42,0x26, 0x1,0x42,0x27, 0x1,0x42,0x28, 0x1,0x42,0x29, + 0x1,0x42,0x2a, 0x1,0x42,0x2b, 0x1,0x42,0x2c, 0x1,0x42,0x2d, + 0x1,0x42,0x2e, 0x1,0x42,0x2f, 0x1,0x42,0x30, 0x1,0x42,0x31, + 0x1,0x42,0x32, 0x1,0x42,0x33, 0x1,0x42,0x34, 0x1,0x42,0x35, + 0x1,0x42,0x36, 0x1,0x42,0x37, 0x1,0x42,0x38, 0x1,0x42,0x39, + 0x1,0x42,0x3a, 0x1,0x42,0x3b, 0x1,0x42,0x3c, 0x1,0x42,0x3d, + 0x1,0x42,0x3e, 0x1,0x42,0x3f, 0x1,0x42,0x40, 0x1,0x42,0x41, + 0x1,0x26,0x21, 0x1,0x26,0x22, 0x1,0x26,0x23, 0x1,0x26,0x24, + 0x1,0x26,0x25, 0x1,0x26,0x26, 0x1,0x26,0x27, 0x1,0x26,0x28, + 0x1,0x26,0x29, 0x1,0x26,0x2a, 0x1,0x26,0x2b, 0x1,0x26,0x2c, + 0x1,0x26,0x2d, 0x1,0x26,0x2e, 0x1,0x26,0x2f, 0x1,0x26,0x30, + 0x1,0x26,0x31, 0x1,0x26,0x32, 0x1,0x26,0x33, 0x1,0x26,0x34, + 0x1,0x23,0x39, 0x1,0x23,0x3a, 0x1,0x23,0x3c, 0x1,0x23,0x3d, + 0x1,0x23,0x3e, 0x1,0x23,0x3f, 0x1,0x23,0x37, 0x1,0x23,0x36, + 0x1,0x23,0x35, 0x1,0x23,0x34, 0x1,0x23,0x33, 0x1,0x23,0x44, + 0x1,0x23,0x45, 0x1,0x23,0x47, 0x1,0x23,0x46, 0x1,0x23,0x40, + 0x1,0x23,0x41, 0x1,0x23,0x43, 0x1,0x23,0x42, 0x1,0x23,0x4c, + 0x1,0x23,0x4d, 0x1,0x23,0x4e, 0x1,0x23,0x24, 0x1,0x23,0x25, + 0x1,0x23,0x26, 0x1,0x23,0x27, 0x1,0x23,0x28, 0x1,0x23,0x29, + 0x1,0x23,0x2a, 0x1,0x23,0x2b, 0x1,0x23,0x32, 0x1,0x23,0x31, + 0x1,0x23,0x30, 0x1,0x23,0x2f, 0x1,0x23,0x2e, 0x1,0x23,0x2d, + 0x1,0x23,0x2c, 0x1,0x23,0x38, 0x1,0x23,0x3b, 0x1,0x21,0x7c, + 0x1,0x21,0x7b, 0x1,0x21,0x75, 0x1,0x21,0x74, 0x1,0x21,0x7e, + 0x1,0x21,0x7d, 0x1,0x21,0x7a, 0x1,0x21,0x79, 0x1,0x21,0x72, + 0x1,0x21,0x76, 0x1,0x21,0x73, 0x1,0x23,0x48, 0x1,0x23,0x49, + 0x1,0x23,0x4b, 0x1,0x23,0x4a, 0x1,0x21,0x78, 0x1,0x21,0x77, + 0x1,0x22,0x54, 0x1,0x22,0x51, 0x1,0x22,0x53, 0x1,0x22,0x52, + 0x1,0x21,0x21, 0x1,0x21,0x23, 0x1,0x21,0x24, 0x1,0x21,0x71, + 0x1,0x21,0x52, 0x1,0x21,0x53, 0x1,0x21,0x4e, 0x1,0x21,0x4f, + 0x1,0x21,0x56, 0x1,0x21,0x57, 0x1,0x21,0x5a, 0x1,0x21,0x5b, + 0x1,0x21,0x4a, 0x1,0x21,0x4b, 0x1,0x22,0x65, 0x1,0x21,0x46, + 0x1,0x21,0x47, 0x1,0x21,0x68, 0x1,0x21,0x69, 0x1,0x24,0x35, + 0x1,0x24,0x36, 0x1,0x24,0x37, 0x1,0x24,0x38, 0x1,0x24,0x39, + 0x1,0x24,0x3a, 0x1,0x24,0x3b, 0x1,0x24,0x3c, 0x1,0x24,0x3d, + 0x1,0x21,0x26, 0x1,0x25,0x47, 0x1,0x25,0x48, 0x1,0x25,0x49, + 0x1,0x25,0x4a, 0x1,0x25,0x4b, 0x1,0x25,0x4c, 0x1,0x25,0x4d, + 0x1,0x25,0x4e, 0x1,0x25,0x4f, 0x1,0x25,0x50, 0x1,0x25,0x51, + 0x1,0x25,0x52, 0x1,0x25,0x53, 0x1,0x25,0x54, 0x1,0x25,0x55, + 0x1,0x25,0x56, 0x1,0x25,0x57, 0x1,0x25,0x58, 0x1,0x25,0x59, + 0x1,0x25,0x5a, 0x1,0x25,0x5b, 0x1,0x25,0x5c, 0x1,0x25,0x5d, + 0x1,0x25,0x5e, 0x1,0x25,0x5f, 0x1,0x25,0x60, 0x1,0x25,0x61, + 0x1,0x25,0x62, 0x1,0x25,0x63, 0x1,0x25,0x64, 0x1,0x25,0x65, + 0x1,0x25,0x66, 0x1,0x25,0x67, 0x1,0x25,0x68, 0x1,0x25,0x69, + 0x1,0x25,0x6a, 0x1,0x25,0x6b, 0x1,0x22,0x21, 0x1,0x22,0x75, + 0x1,0x22,0x76, 0x1,0x22,0x70, 0x1,0x22,0x71, 0x1,0x22,0x72, + 0x1,0x22,0x74, 0x1,0x22,0x77, 0x1,0x22,0x73, 0x1,0x22,0x4c, + 0x1,0x22,0x4b, 0x1,0x22,0x6f, 0x6,0x22,0x2c, 0x4,0x22,0x24, + 0x6,0x21,0x30, 0x6,0x21,0x23, 0xf,0x21,0x6c, 0x4,0x21,0x57, + 0x4,0x23,0x36, 0x4,0x28,0x35, 0x3,0x34,0x3b, 0x3,0x39,0x6d, + 0x3,0x27,0x41, 0x3,0x28,0x6c, 0x3,0x23,0x23, 0x4,0x23,0x37, + 0x4,0x25,0x34, 0x3,0x40,0x34, 0x4,0x21,0x59, 0x3,0x21,0x75, + 0x3,0x21,0x6e, 0x3,0x21,0x71, 0x3,0x21,0x73, 0xf,0x21,0x44, + 0x6,0x23,0x4e, 0x3,0x22,0x71, 0x4,0x22,0x31, 0x3,0x22,0x69, + 0x3,0x22,0x6a, 0xf,0x21,0x72, 0x5,0x23,0x34, 0x3,0x24,0x4a, + 0x3,0x24,0x47, 0x3,0x24,0x4d, 0x6,0x25,0x71, 0x3,0x27,0x46, + 0x5,0x25,0x25, 0x4,0x25,0x39, 0x4,0x25,0x3c, 0x3,0x27,0x45, + 0x5,0x25,0x2b, 0x4,0x25,0x3b, 0x4,0x25,0x38, 0x3,0x27,0x50, + 0xf,0x25,0x4a, 0x3,0x2b,0x31, 0x6,0x2e,0x5a, 0x4,0x28,0x39, + 0x3,0x2b,0x30, 0x5,0x28,0x21, 0x4,0x28,0x3a, 0x3,0x2b,0x2a, + 0x4,0x28,0x37, 0x4,0x28,0x3c, 0x5,0x2b,0x6c, 0x3,0x34,0x49, + 0x3,0x2f,0x52, 0x4,0x2b,0x65, 0x6,0x35,0x38, 0x4,0x30,0x45, + 0x3,0x34,0x3e, 0x3,0x34,0x48, 0x4,0x30,0x4a, 0x4,0x36,0x38, + 0x3,0x39,0x73, 0x4,0x36,0x32, 0x4,0x36,0x37, 0x6,0x46,0x55, + 0x6,0x49,0x7b, 0x3,0x39,0x74, 0x3,0x40,0x35, 0x3,0x40,0x38, + 0x3,0x40,0x3b, 0x4,0x3c,0x2c, 0x4,0x3c,0x2d, 0x4,0x3c,0x28, + 0x4,0x3c,0x2a, 0x5,0x44,0x57, 0x4,0x42,0x37, 0x4,0x42,0x33, + 0x4,0x42,0x2e, 0x3,0x45,0x78, 0x6,0x5a,0x73, 0x4,0x42,0x2f, + 0x3,0x45,0x73, 0x4,0x4f,0x59, 0x3,0x45,0x72, 0x3,0x45,0x6f, + 0x3,0x45,0x77, 0x4,0x42,0x32, 0x4,0x48,0x7b, 0x3,0x4b,0x26, + 0x3,0x4b,0x25, 0x4,0x48,0x7d, 0x3,0x4b,0x24, 0x3,0x4b,0x28, + 0x3,0x4b,0x2a, 0x3,0x50,0x32, 0x4,0x4f,0x5d, 0x5,0x53,0x59, + 0x4,0x4f,0x5b, 0x3,0x54,0x3f, 0x3,0x57,0x53, 0x4,0x5a,0x67, + 0x4,0x5a,0x68, 0x4,0x5f,0x49, 0x4,0x63,0x2f, 0x3,0x5c,0x33, + 0x3,0x5c,0x31, 0x7,0x52,0x74, 0x7,0x57,0x4c, 0x4,0x6a,0x41, + 0x3,0x61,0x3c, 0x4,0x22,0x33, 0xf,0x26,0x5a, 0x4,0x2b,0x69, + 0x3,0x57,0x54, 0x3,0x21,0x76, 0x3,0x22,0x79, 0x3,0x24,0x55, + 0x5,0x23,0x37, 0x6,0x25,0x7b, 0x6,0x25,0x7d, 0x3,0x24,0x56, + 0x3,0x2b,0x38, 0x7,0x4d,0x3d, 0x3,0x2a,0x4c, 0x4,0x30,0x4c, + 0x5,0x31,0x26, 0x4,0x36,0x3d, 0x4,0x3c,0x32, 0x4,0x6a,0x42, + 0x3,0x2b,0x3a, 0x3,0x39,0x78, 0x4,0x49,0x22, 0x3,0x21,0x50, + 0x3,0x23,0x21, 0x3,0x24,0x58, 0x5,0x25,0x2e, 0x3,0x27,0x57, + 0x3,0x27,0x56, 0x3,0x27,0x58, 0x4,0x28,0x43, 0x3,0x2b,0x3c, + 0x3,0x2f,0x5d, 0x3,0x2f,0x5c, 0x4,0x30,0x4d, 0x3,0x39,0x7b, + 0x3,0x39,0x7c, 0x4,0x3c,0x34, 0x3,0x45,0x79, 0x5,0x31,0x29, + 0x4,0x21,0x61, 0x6,0x22,0x41, 0x3,0x21,0x7e, 0x4,0x22,0x3c, + 0x5,0x22,0x30, 0x4,0x23,0x3e, 0x4,0x23,0x3f, 0x4,0x25,0x4a, + 0x4,0x25,0x4c, 0x4,0x25,0x48, 0x4,0x25,0x47, 0x3,0x2b,0x41, + 0x3,0x2b,0x45, 0x3,0x2b,0x42, 0x5,0x2b,0x7c, 0x4,0x30,0x53, + 0x3,0x2f,0x67, 0x3,0x2f,0x69, 0x4,0x30,0x57, 0x4,0x30,0x58, + 0x4,0x30,0x52, 0x5,0x31,0x2c, 0x4,0x30,0x54, 0x4,0x30,0x59, + 0x3,0x3a,0x24, 0x6,0x50,0x6c, 0x4,0x36,0x42, 0x4,0x36,0x45, + 0x3,0x3a,0x22, 0x5,0x3d,0x70, 0x3,0x40,0x42, 0x4,0x42,0x41, + 0x4,0x42,0x43, 0x4,0x42,0x42, 0x4,0x42,0x3c, 0x3,0x45,0x7d, + 0x3,0x45,0x7b, 0x4,0x42,0x3f, 0x4,0x42,0x3e, 0x3,0x45,0x7c, + 0x4,0x49,0x23, 0x4,0x4f,0x62, 0x4,0x4f,0x61, 0x4,0x4f,0x63, + 0x5,0x61,0x3b, 0x4,0x55,0x6c, 0x7,0x3e,0x7d, 0x4,0x5f,0x4a, + 0x4,0x63,0x30, 0x4,0x21,0x64, 0x4,0x22,0x40, 0x4,0x23,0x44, + 0x3,0x24,0x64, 0x4,0x25,0x4f, 0x6,0x29,0x6f, 0x6,0x2f,0x27, + 0x4,0x2b,0x75, 0x3,0x2f,0x6b, 0x4,0x30,0x5a, 0x4,0x36,0x4b, + 0x3,0x46,0x22, 0x4,0x55,0x6f, 0x3,0x54,0x43, 0x4,0x55,0x70, + 0x5,0x53,0x63, 0x4,0x5a,0x6e, 0x4,0x30,0x5c, 0x4,0x36,0x4d, + 0x5,0x3d,0x78, 0x6,0x29,0x72, 0x3,0x34,0x53, 0x5,0x70,0x78, + 0x4,0x23,0x4b, 0x6,0x26,0x38, 0x4,0x2b,0x77, 0x3,0x3a,0x25, + 0x6,0x50,0x76, 0x4,0x3c,0x3e, 0x5,0x44,0x6c, 0x4,0x6d,0x53, + 0x6,0x26,0x36, 0x4,0x36,0x50, 0x3,0x21,0x58, 0x6,0x23,0x71, + 0x3,0x23,0x2c, 0x6,0x50,0x7a, 0x3,0x27,0x64, 0x4,0x21,0x2b, + 0x6,0x21,0x3b, 0x6,0x28,0x64, 0x4,0x25,0x56, 0x3,0x23,0x30, + 0x5,0x22,0x3c, 0x3,0x23,0x2e, 0x3,0x24,0x6a, 0x3,0x24,0x69, + 0x3,0x24,0x68, 0x3,0x27,0x68, 0x6,0x2a,0x2a, 0x3,0x2b,0x4c, + 0x3,0x2f,0x70, 0x4,0x2b,0x7a, 0x3,0x2f,0x71, 0x4,0x36,0x51, + 0x6,0x51,0x22, 0x5,0x4c,0x31, 0x3,0x46,0x24, 0x4,0x49,0x27, + 0x3,0x60,0x70, 0x3,0x21,0x5d, 0x3,0x2f,0x72, 0x6,0x3d,0x61, + 0x3,0x34,0x56, 0x4,0x49,0x29, 0x5,0x21,0x41, 0x3,0x21,0x5f, + 0x3,0x23,0x32, 0x4,0x25,0x5a, 0x4,0x28,0x57, 0x3,0x3f,0x78, + 0x3,0x46,0x27, 0x4,0x47,0x56, 0x4,0x21,0x6b, 0x3,0x22,0x30, + 0x3,0x22,0x2c, 0x3,0x23,0x38, 0x3,0x23,0x36, 0x3,0x24,0x6c, + 0x4,0x23,0x51, 0x3,0x24,0x6b, 0x3,0x24,0x71, 0x4,0x23,0x54, + 0x4,0x23,0x59, 0x3,0x24,0x72, 0x4,0x23,0x53, 0x3,0x24,0x6f, + 0x3,0x24,0x6e, 0x3,0x24,0x7a, 0xf,0x23,0x49, 0x3,0x25,0x25, + 0x3,0x27,0x7a, 0x3,0x27,0x6d, 0x4,0x25,0x5d, 0x3,0x27,0x76, + 0x5,0x25,0x42, 0x6,0x2a,0x39, 0x3,0x2b,0x52, 0x3,0x2b,0x60, + 0x3,0x2b,0x5f, 0x3,0x2b,0x62, 0x3,0x2b,0x5a, 0x4,0x28,0x59, + 0x4,0x28,0x5c, 0x3,0x2b,0x56, 0xf,0x29,0x5c, 0x4,0x2c,0x25, + 0x3,0x2f,0x7d, 0x4,0x2b,0x7e, 0x3,0x2f,0x75, 0x3,0x2f,0x7c, + 0x4,0x2c,0x21, 0x4,0x2b,0x7d, 0x6,0x35,0x7d, 0x3,0x30,0x24, + 0x5,0x2c,0x43, 0x3,0x34,0x5d, 0x3,0x34,0x65, 0x4,0x30,0x6a, + 0x5,0x36,0x70, 0x3,0x34,0x63, 0x3,0x34,0x5c, 0x4,0x30,0x70, + 0x3,0x34,0x5a, 0x4,0x30,0x73, 0x4,0x30,0x71, 0x4,0x30,0x6d, + 0x4,0x30,0x6c, 0xf,0x33,0x43, 0x3,0x38,0x53, 0x4,0x30,0x6f, + 0x5,0x36,0x76, 0x3,0x3a,0x32, 0x4,0x36,0x67, 0x3,0x3a,0x35, + 0x3,0x3a,0x2c, 0x4,0x36,0x5e, 0x4,0x36,0x59, 0x3,0x3a,0x39, + 0x3,0x3a,0x3e, 0x3,0x3a,0x2d, 0x4,0x36,0x60, 0x3,0x3a,0x3d, + 0x4,0x36,0x5f, 0x3,0x3a,0x37, 0x6,0x47,0x39, 0x5,0x36,0x79, + 0x5,0x36,0x7a, 0x3,0x3a,0x30, 0x4,0x36,0x58, 0x4,0x36,0x65, + 0x4,0x36,0x63, 0x3,0x3a,0x41, 0x5,0x36,0x6e, 0x3,0x3a,0x3f, + 0x3,0x3a,0x3a, 0x5,0x3e,0x39, 0x4,0x3c,0x4a, 0x4,0x3c,0x46, + 0x3,0x40,0x4f, 0x5,0x3e,0x3d, 0x4,0x3c,0x47, 0x4,0x3c,0x4c, + 0x3,0x40,0x4d, 0x3,0x40,0x50, 0x6,0x51,0x32, 0x4,0x42,0x52, + 0x3,0x46,0x32, 0x3,0x46,0x2f, 0x3,0x46,0x2d, 0x4,0x42,0x4f, + 0x4,0x42,0x4a, 0x4,0x42,0x55, 0x3,0x46,0x2b, 0x3,0x4b,0x3a, + 0x4,0x42,0x53, 0x4,0x42,0x56, 0x4,0x42,0x51, 0x5,0x45,0x22, + 0x4,0x49,0x30, 0x4,0x49,0x2c, 0x3,0x4b,0x42, 0x4,0x49,0x2d, + 0x3,0x4b,0x36, 0x7,0x21,0x4e, 0x4,0x4f,0x6b, 0x4,0x4f,0x6c, + 0x3,0x50,0x41, 0x4,0x4f,0x67, 0x4,0x4f,0x6a, 0x4,0x4f,0x6f, + 0x3,0x50,0x3c, 0x3,0x50,0x3a, 0x7,0x37,0x37, 0x4,0x55,0x72, + 0x3,0x54,0x46, 0x4,0x55,0x73, 0x4,0x4f,0x6d, 0x5,0x61,0x40, + 0x4,0x5a,0x70, 0x3,0x57,0x56, 0x5,0x61,0x45, 0x4,0x5f,0x4c, + 0x5,0x67,0x59, 0x5,0x6b,0x73, 0x3,0x5c,0x35, 0x3,0x5e,0x27, + 0x4,0x66,0x32, 0x3,0x60,0x2e, 0x3,0x60,0x2d, 0x4,0x6c,0x6c, + 0x7,0x62,0x2f, 0x3,0x22,0x32, 0x3,0x22,0x21, 0x3,0x23,0x3d, + 0x5,0x25,0x53, 0x3,0x27,0x7e, 0x3,0x2b,0x64, 0x3,0x30,0x26, + 0x4,0x42,0x58, 0x4,0x63,0x32, 0x3,0x22,0x33, 0x3,0x25,0x2e, + 0x4,0x23,0x5f, 0x3,0x25,0x39, 0x3,0x25,0x3a, 0x4,0x23,0x5e, + 0x3,0x25,0x3d, 0x3,0x25,0x3f, 0x3,0x25,0x3b, 0x3,0x25,0x34, + 0x3,0x28,0x27, 0x4,0x25,0x6d, 0x3,0x28,0x2b, 0x3,0x28,0x2c, + 0x3,0x2b,0x76, 0x6,0x2f,0x65, 0x3,0x2b,0x74, 0x3,0x2b,0x75, + 0x3,0x2b,0x73, 0x3,0x2b,0x6f, 0x3,0x30,0x29, 0x4,0x2c,0x2f, + 0x4,0x2c,0x31, 0x3,0x30,0x2d, 0x3,0x30,0x2c, 0x3,0x30,0x2e, + 0x3,0x30,0x31, 0x3,0x34,0x6c, 0x3,0x34,0x6d, 0x3,0x34,0x73, + 0x3,0x34,0x6a, 0xf,0x33,0x57, 0x4,0x31,0x21, 0x4,0x36,0x6b, + 0x3,0x3a,0x46, 0x4,0x36,0x6e, 0x3,0x3a,0x51, 0x6,0x47,0x4e, + 0x3,0x3a,0x48, 0x3,0x3a,0x4d, 0x4,0x3c,0x59, 0x4,0x3c,0x5b, + 0x3,0x40,0x53, 0x3,0x40,0x55, 0x4,0x3c,0x56, 0x4,0x3c,0x58, + 0x4,0x42,0x5e, 0x4,0x42,0x5d, 0x4,0x42,0x5b, 0x3,0x46,0x3b, + 0x4,0x42,0x5f, 0x3,0x46,0x39, 0x7,0x21,0x6a, 0x3,0x4b,0x52, + 0x3,0x4b,0x48, 0x4,0x49,0x33, 0x3,0x4b,0x4a, 0x3,0x4b,0x4e, + 0xf,0x4e,0x25, 0xf,0x4e,0x2e, 0x4,0x49,0x2a, 0x3,0x50,0x44, + 0x4,0x4f,0x78, 0x3,0x50,0x47, 0x3,0x50,0x42, 0x3,0x50,0x43, + 0x3,0x50,0x46, 0x3,0x50,0x45, 0x4,0x55,0x7c, 0x3,0x54,0x4d, + 0x3,0x54,0x4a, 0x4,0x55,0x7b, 0x7,0x3f,0x30, 0x3,0x57,0x5d, + 0x7,0x46,0x44, 0x5,0x6b,0x76, 0x3,0x60,0x72, 0x4,0x6c,0x6e, + 0x5,0x37,0x3c, 0x3,0x4d,0x41, 0x3,0x2b,0x78, 0x4,0x28,0x61, + 0x5,0x25,0x58, 0x4,0x36,0x77, 0x4,0x42,0x60, 0x3,0x46,0x47, + 0x4,0x5a,0x7a, 0x3,0x22,0x3a, 0x3,0x23,0x46, 0x3,0x23,0x48, + 0x4,0x23,0x65, 0x3,0x25,0x4a, 0x4,0x25,0x71, 0x5,0x25,0x59, + 0x4,0x25,0x77, 0x4,0x25,0x73, 0x4,0x25,0x78, 0x3,0x2b,0x7d, + 0x4,0x31,0x25, 0x6,0x3e,0x42, 0x3,0x34,0x7a, 0x3,0x3a,0x55, + 0x4,0x3c,0x5c, 0x3,0x50,0x3e, 0x3,0x21,0x74, 0x3,0x23,0x4c, + 0x3,0x23,0x4a, 0x4,0x22,0x56, 0x4,0x22,0x59, 0x4,0x22,0x55, + 0x3,0x23,0x49, 0x3,0x25,0x52, 0x3,0x25,0x57, 0x3,0x25,0x50, + 0x3,0x25,0x4f, 0x3,0x25,0x4d, 0x3,0x25,0x54, 0x3,0x28,0x31, + 0x3,0x28,0x3b, 0x4,0x25,0x7b, 0x3,0x28,0x42, 0x3,0x28,0x32, + 0x3,0x28,0x3a, 0x3,0x28,0x43, 0x3,0x28,0x47, 0x3,0x28,0x34, + 0x4,0x26,0x21, 0x3,0x28,0x44, 0x3,0x28,0x3e, 0x3,0x28,0x36, + 0x3,0x28,0x3c, 0x5,0x25,0x5d, 0x3,0x28,0x39, 0x3,0x28,0x30, + 0x4,0x28,0x6d, 0x4,0x28,0x69, 0x3,0x2b,0x7e, 0x3,0x2c,0x22, + 0xf,0x2a,0x2a, 0x4,0x28,0x67, 0x3,0x30,0x3f, 0x3,0x30,0x42, + 0x3,0x30,0x3d, 0x3,0x30,0x49, 0x3,0x30,0x47, 0x4,0x2c,0x3b, + 0x3,0x30,0x43, 0x3,0x30,0x50, 0x3,0x30,0x4c, 0x3,0x30,0x44, + 0x4,0x2c,0x3f, 0x4,0x2c,0x3a, 0x3,0x30,0x39, 0x4,0x2c,0x3c, + 0x3,0x30,0x51, 0x3,0x30,0x46, 0x3,0x30,0x41, 0x3,0x30,0x3a, + 0xf,0x2e,0x6b, 0xf,0x2e,0x78, 0x4,0x31,0x29, 0x3,0x35,0x26, + 0x3,0x35,0x2d, 0x3,0x35,0x21, 0x3,0x35,0x36, 0x4,0x31,0x28, + 0x3,0x35,0x2c, 0x3,0x35,0x23, 0x3,0x35,0x25, 0x3,0x3a,0x71, + 0x3,0x3a,0x67, 0x3,0x3a,0x74, 0x3,0x3a,0x64, 0x3,0x3a,0x76, + 0x3,0x3a,0x6c, 0x3,0x3a,0x6a, 0x3,0x3a,0x65, 0x5,0x37,0x4e, + 0x3,0x3a,0x6e, 0x5,0x37,0x46, 0x4,0x36,0x7e, 0x3,0x3a,0x6f, + 0x3,0x3a,0x5f, 0x4,0x36,0x7d, 0x3,0x3a,0x70, 0x3,0x3a,0x5d, + 0xf,0x3a,0x3c, 0x3,0x3a,0x6d, 0x3,0x3a,0x69, 0x3,0x3a,0x68, + 0x4,0x3c,0x5f, 0x3,0x40,0x62, 0x4,0x3c,0x61, 0x3,0x40,0x6e, + 0x3,0x40,0x6d, 0x3,0x40,0x68, 0x3,0x40,0x63, 0x4,0x3c,0x64, + 0x3,0x40,0x65, 0x4,0x3c,0x63, 0x3,0x40,0x70, 0x3,0x40,0x6b, + 0x3,0x40,0x6f, 0x3,0x40,0x6c, 0x3,0x40,0x69, 0x3,0x46,0x4b, + 0x4,0x42,0x67, 0x4,0x42,0x6c, 0x4,0x42,0x68, 0x4,0x42,0x66, + 0x3,0x46,0x49, 0x3,0x46,0x52, 0x3,0x46,0x51, 0x4,0x42,0x6b, + 0x4,0x42,0x6d, 0x3,0x46,0x4d, 0x3,0x46,0x4e, 0x4,0x42,0x69, + 0x4,0x49,0x3c, 0x4,0x49,0x3a, 0x3,0x4b,0x59, 0x3,0x4b,0x57, + 0x4,0x49,0x40, 0x3,0x4b,0x55, 0x3,0x50,0x52, 0x3,0x50,0x55, + 0x4,0x50,0x21, 0xf,0x54,0x2a, 0x4,0x56,0x22, 0x4,0x56,0x24, + 0x3,0x57,0x5f, 0x3,0x57,0x60, 0x4,0x5f,0x54, 0x5,0x67,0x5e, + 0x3,0x5a,0x30, 0x3,0x5a,0x32, 0x3,0x5c,0x37, 0x4,0x63,0x35, + 0x3,0x5c,0x38, 0x4,0x66,0x37, 0x4,0x68,0x65, 0x3,0x61,0x62, + 0x3,0x61,0x63, 0x3,0x23,0x4e, 0x6,0x26,0x78, 0x4,0x23,0x6d, + 0x3,0x28,0x49, 0x4,0x28,0x70, 0x4,0x2c,0x41, 0x3,0x30,0x54, + 0x3,0x3a,0x7d, 0x4,0x3c,0x67, 0x7,0x2d,0x2d, 0x3,0x61,0x3d, + 0x3,0x22,0x3c, 0x3,0x23,0x4f, 0x6,0x26,0x79, 0x3,0x25,0x59, + 0x4,0x23,0x70, 0x3,0x25,0x5b, 0x6,0x26,0x7a, 0x3,0x28,0x4f, + 0x5,0x28,0x6e, 0x3,0x2c,0x30, 0x3,0x2c,0x31, 0x3,0x2c,0x33, + 0x4,0x2c,0x42, 0x5,0x2c,0x7c, 0x6,0x36,0x5d, 0x3,0x35,0x42, + 0x3,0x35,0x3d, 0x3,0x35,0x3e, 0x4,0x31,0x2e, 0x6,0x3e,0x5a, + 0x3,0x35,0x40, 0x3,0x3b,0x21, 0x4,0x37,0x22, 0x4,0x3c,0x6a, + 0x4,0x3c,0x6c, 0x4,0x3c,0x6f, 0x3,0x40,0x77, 0x4,0x42,0x74, + 0x4,0x42,0x75, 0x3,0x4b,0x60, 0x4,0x42,0x77, 0x4,0x49,0x43, + 0x4,0x49,0x45, 0x4,0x49,0x46, 0x4,0x5a,0x7d, 0x3,0x5e,0x2b, + 0x7,0x62,0x35, 0x4,0x23,0x71, 0x4,0x26,0x26, 0x6,0x36,0x68, + 0x3,0x3b,0x22, 0x4,0x2c,0x4c, 0x6,0x3e,0x64, 0x4,0x42,0x78, + 0x5,0x4c,0x63, 0x4,0x22,0x5d, 0x4,0x23,0x74, 0x4,0x26,0x28, + 0x4,0x26,0x27, 0x4,0x28,0x74, 0x4,0x28,0x75, 0x4,0x2c,0x4d, + 0x5,0x31,0x75, 0x4,0x31,0x33, 0x5,0x31,0x73, 0x4,0x31,0x32, + 0x4,0x37,0x28, 0x4,0x37,0x29, 0x4,0x3c,0x71, 0x4,0x42,0x79, + 0x3,0x22,0x40, 0x3,0x23,0x53, 0x4,0x26,0x2a, 0x3,0x28,0x52, + 0x3,0x28,0x53, 0x4,0x28,0x79, 0x4,0x28,0x78, 0x3,0x2c,0x39, + 0x3,0x2c,0x38, 0x3,0x2c,0x36, 0x4,0x2c,0x4e, 0x6,0x3e,0x6b, + 0x3,0x35,0x45, 0x4,0x37,0x2b, 0x5,0x37,0x66, 0x4,0x42,0x7d, + 0x4,0x49,0x4a, 0x3,0x5a,0x37, 0x3,0x21,0x62, 0x4,0x23,0x77, + 0x3,0x22,0x42, 0x3,0x22,0x43, 0x3,0x22,0x41, 0x3,0x22,0x44, + 0x3,0x23,0x56, 0x4,0x22,0x61, 0x5,0x22,0x51, 0x4,0x23,0x7b, + 0x5,0x22,0x50, 0x3,0x23,0x57, 0x3,0x23,0x58, 0x4,0x23,0x78, + 0x4,0x23,0x79, 0x3,0x25,0x60, 0x5,0x23,0x70, 0x5,0x23,0x74, + 0x3,0x25,0x64, 0x3,0x25,0x65, 0x4,0x23,0x76, 0x3,0x28,0x5b, + 0x6,0x2a,0x7b, 0x4,0x26,0x31, 0x4,0x26,0x32, 0x4,0x26,0x2e, + 0x3,0x28,0x56, 0x6,0x2a,0x76, 0x3,0x28,0x59, 0x3,0x28,0x5a, + 0x5,0x25,0x6e, 0x3,0x2c,0x3a, 0x4,0x28,0x7b, 0x4,0x2c,0x5b, + 0x4,0x2c,0x53, 0x4,0x2c,0x51, 0x3,0x30,0x60, 0x4,0x2c,0x5f, + 0x4,0x2c,0x55, 0x3,0x30,0x5c, 0x4,0x2c,0x5a, 0x4,0x2c,0x5e, + 0x4,0x2c,0x57, 0x3,0x30,0x5d, 0x6,0x36,0x7c, 0x5,0x2d,0x2e, + 0x3,0x30,0x65, 0x4,0x2c,0x54, 0x3,0x35,0x56, 0x3,0x35,0x49, + 0x4,0x31,0x37, 0x3,0x35,0x4c, 0x4,0x31,0x3d, 0x6,0x3e,0x75, + 0x3,0x35,0x4d, 0x4,0x31,0x39, 0x6,0x3e,0x78, 0x3,0x35,0x50, + 0xf,0x34,0x3f, 0x3,0x35,0x53, 0x3,0x3b,0x2f, 0x3,0x3b,0x32, + 0x3,0x3b,0x29, 0x4,0x37,0x32, 0x4,0x37,0x34, 0x3,0x3b,0x35, + 0x4,0x3c,0x72, 0x3,0x3b,0x30, 0x3,0x3b,0x2c, 0x4,0x3c,0x76, + 0x4,0x3c,0x73, 0x4,0x3c,0x7e, 0x5,0x3e,0x6d, 0x4,0x3d,0x21, + 0x6,0x52,0x34, 0x3,0x40,0x7b, 0x4,0x3c,0x77, 0x4,0x43,0x22, + 0x6,0x5c,0x44, 0x4,0x43,0x2d, 0x4,0x43,0x2a, 0x4,0x43,0x21, + 0x3,0x46,0x55, 0x4,0x43,0x24, 0x3,0x46,0x5b, 0x3,0x46,0x58, + 0x4,0x43,0x2e, 0x3,0x46,0x57, 0x4,0x49,0x50, 0x4,0x49,0x4c, + 0x5,0x4c,0x6c, 0x3,0x4b,0x62, 0x5,0x4c,0x68, 0x4,0x49,0x4b, + 0x4,0x49,0x53, 0x3,0x4b,0x64, 0x4,0x49,0x4f, 0x4,0x49,0x4d, + 0x3,0x4b,0x61, 0x4,0x49,0x54, 0x4,0x50,0x26, 0x4,0x50,0x27, + 0x4,0x56,0x28, 0x4,0x50,0x25, 0x5,0x54,0x36, 0x3,0x50,0x59, + 0x7,0x2d,0x4c, 0x3,0x54,0x5a, 0x3,0x54,0x56, 0x5,0x5b,0x3c, + 0x4,0x56,0x27, 0x3,0x54,0x58, 0x7,0x3f,0x44, 0x4,0x5f,0x5a, + 0x5,0x67,0x63, 0x5,0x67,0x64, 0x4,0x66,0x3a, 0x3,0x5e,0x2c, + 0x4,0x68,0x68, 0x5,0x7b,0x3d, 0x3,0x23,0x5b, 0x6,0x21,0x6e, + 0x3,0x3b,0x38, 0x4,0x49,0x55, 0x3,0x22,0x45, 0x4,0x31,0x42, + 0x3,0x22,0x46, 0x4,0x22,0x65, 0x4,0x22,0x66, 0x3,0x23,0x5d, + 0x4,0x24,0x22, 0x4,0x24,0x24, 0x3,0x25,0x69, 0x4,0x24,0x21, + 0x3,0x25,0x6a, 0xf,0x24,0x25, 0x4,0x26,0x36, 0x4,0x26,0x37, + 0x4,0x29,0x25, 0x4,0x24,0x25, 0x4,0x29,0x22, 0x4,0x29,0x24, + 0x6,0x30,0x63, 0x3,0x2c,0x47, 0x4,0x29,0x23, 0x4,0x29,0x21, + 0x4,0x2c,0x66, 0x4,0x2c,0x68, 0x4,0x31,0x47, 0x4,0x31,0x48, + 0x4,0x31,0x45, 0x4,0x31,0x49, 0x3,0x35,0x5c, 0x4,0x37,0x3b, + 0x4,0x37,0x36, 0x4,0x37,0x3d, 0x4,0x37,0x3a, 0x3,0x3b,0x3c, + 0x4,0x37,0x3c, 0x3,0x3b,0x39, 0x4,0x37,0x39, 0x4,0x3d,0x28, + 0x4,0x3d,0x23, 0x4,0x3d,0x27, 0x4,0x3d,0x26, 0x4,0x3d,0x29, + 0x4,0x43,0x33, 0x4,0x43,0x32, 0x4,0x43,0x31, 0x4,0x43,0x2f, + 0x3,0x4b,0x6e, 0x3,0x4b,0x6f, 0x4,0x50,0x29, 0x4,0x56,0x2d, + 0x4,0x56,0x2b, 0x4,0x63,0x3b, 0x4,0x63,0x3a, 0x3,0x5f,0x44, + 0x4,0x68,0x6b, 0x6,0x48,0x44, 0x3,0x46,0x5e, 0x4,0x50,0x2b, + 0x3,0x23,0x60, 0x3,0x23,0x5f, 0x3,0x23,0x5e, 0x3,0x25,0x6c, + 0x6,0x27,0x47, 0x4,0x26,0x38, 0x4,0x26,0x3d, 0x4,0x26,0x3b, + 0x5,0x26,0x26, 0x4,0x26,0x3c, 0x3,0x28,0x64, 0x4,0x26,0x3a, + 0x3,0x28,0x66, 0xf,0x2f,0x38, 0x3,0x2c,0x49, 0x3,0x2c,0x4a, + 0x4,0x29,0x2a, 0x5,0x29,0x26, 0x4,0x29,0x29, 0x4,0x29,0x28, + 0x4,0x2c,0x6b, 0x4,0x2c,0x6d, 0x4,0x2c,0x6c, 0x3,0x30,0x6d, + 0x3,0x35,0x5e, 0x4,0x31,0x4e, 0x4,0x31,0x4c, 0x4,0x31,0x4f, + 0x3,0x35,0x5d, 0x5,0x38,0x29, 0x4,0x37,0x40, 0x4,0x37,0x41, + 0x3,0x3b,0x41, 0x5,0x3f,0x21, 0x4,0x43,0x36, 0x3,0x46,0x5f, + 0x4,0x43,0x39, 0x4,0x43,0x3a, 0x4,0x49,0x5b, 0x4,0x49,0x5c, + 0x3,0x4b,0x71, 0x3,0x50,0x5d, 0x4,0x50,0x2c, 0x4,0x50,0x2e, + 0x5,0x54,0x42, 0x4,0x5f,0x5e, 0x4,0x63,0x3c, 0x4,0x24,0x29, + 0x3,0x28,0x6a, 0x3,0x46,0x62, 0x7,0x2d,0x5b, 0x4,0x29,0x2b, + 0x4,0x3d,0x2d, 0x6,0x21,0x79, 0x4,0x22,0x6a, 0x3,0x23,0x63, + 0x3,0x23,0x64, 0x3,0x25,0x70, 0x3,0x28,0x6f, 0x4,0x26,0x40, + 0x4,0x26,0x41, 0x3,0x2c,0x4e, 0x4,0x29,0x2d, 0x6,0x30,0x7a, + 0x4,0x29,0x2e, 0x3,0x2c,0x4f, 0x4,0x2c,0x71, 0x5,0x32,0x46, + 0x4,0x31,0x51, 0x4,0x2c,0x72, 0x3,0x3b,0x46, 0x3,0x3b,0x43, + 0x5,0x3f,0x29, 0x4,0x3d,0x2f, 0x4,0x3d,0x2e, 0x6,0x52,0x4d, + 0x4,0x49,0x5d, 0x4,0x49,0x5f, 0x3,0x5e,0x2e, 0x4,0x26,0x42, + 0x4,0x50,0x31, 0x6,0x24,0x70, 0x3,0x28,0x73, 0x4,0x26,0x43, + 0x3,0x28,0x72, 0x3,0x35,0x64, 0x3,0x3b,0x48, 0x3,0x3b,0x49, + 0x4,0x43,0x3b, 0x4,0x49,0x61, 0x3,0x50,0x5f, 0x3,0x22,0x4b, + 0x6,0x2b,0x3e, 0x3,0x28,0x74, 0x4,0x29,0x32, 0x4,0x29,0x34, + 0x3,0x2c,0x52, 0x5,0x29,0x2f, 0x5,0x29,0x33, 0x3,0x2c,0x53, + 0x6,0x31,0x25, 0x5,0x2d,0x47, 0xf,0x2f,0x3e, 0x4,0x31,0x54, + 0x3,0x35,0x66, 0x3,0x35,0x67, 0x4,0x37,0x49, 0x3,0x3b,0x4a, + 0x4,0x37,0x48, 0x4,0x3d,0x33, 0x5,0x45,0x69, 0x4,0x43,0x3d, + 0x6,0x5c,0x67, 0x3,0x50,0x60, 0x4,0x50,0x34, 0x4,0x56,0x2f, + 0x6,0x21,0x7e, 0x3,0x23,0x65, 0x3,0x23,0x68, 0x4,0x24,0x31, + 0x5,0x22,0x67, 0x4,0x22,0x70, 0x3,0x28,0x7b, 0x3,0x28,0x7d, + 0x3,0x25,0x79, 0x4,0x24,0x2e, 0x3,0x28,0x7c, 0x4,0x24,0x30, + 0x4,0x24,0x33, 0x3,0x25,0x73, 0x4,0x24,0x2f, 0x4,0x24,0x32, + 0x3,0x26,0x24, 0x3,0x28,0x79, 0x4,0x29,0x35, 0x4,0x29,0x37, + 0x4,0x26,0x4d, 0x3,0x2c,0x59, 0x3,0x29,0x24, 0x4,0x26,0x48, + 0x3,0x29,0x23, 0x4,0x26,0x4e, 0x4,0x26,0x4c, 0x4,0x26,0x46, + 0xf,0x2a,0x3e, 0x3,0x2c,0x58, 0x4,0x29,0x41, 0x3,0x2c,0x62, + 0x4,0x29,0x3c, 0x4,0x26,0x49, 0x4,0x29,0x39, 0x3,0x30,0x7d, + 0x6,0x37,0x54, 0x4,0x29,0x3d, 0x5,0x29,0x35, 0x4,0x2d,0x28, + 0x4,0x29,0x48, 0x4,0x29,0x3a, 0x4,0x29,0x3b, 0x4,0x29,0x40, + 0x3,0x2c,0x55, 0x6,0x37,0x5a, 0x3,0x30,0x7c, 0x3,0x2c,0x5e, + 0x4,0x31,0x5b, 0x5,0x2d,0x5a, 0x3,0x35,0x73, 0x4,0x2d,0x22, + 0x3,0x35,0x69, 0x3,0x30,0x75, 0x4,0x2d,0x23, 0x3,0x35,0x70, + 0x4,0x2d,0x24, 0x3,0x30,0x77, 0x6,0x37,0x5e, 0x3,0x31,0x24, + 0x4,0x2d,0x2b, 0x4,0x31,0x5a, 0x4,0x31,0x5c, 0x4,0x31,0x62, + 0x3,0x35,0x6b, 0x6,0x48,0x6f, 0x4,0x31,0x63, 0x3,0x35,0x75, + 0x4,0x31,0x60, 0x5,0x32,0x5b, 0x4,0x31,0x5d, 0x3,0x35,0x6c, + 0x3,0x3b,0x4e, 0x4,0x31,0x6c, 0x4,0x31,0x67, 0x3,0x3b,0x4c, + 0x3,0x35,0x6d, 0x3,0x35,0x77, 0x3,0x3b,0x57, 0x4,0x31,0x64, + 0x6,0x48,0x75, 0x3,0x3b,0x53, 0x4,0x31,0x66, 0x4,0x31,0x5e, + 0x5,0x2d,0x57, 0x3,0x3b,0x52, 0x5,0x38,0x42, 0x4,0x31,0x6a, + 0x5,0x38,0x48, 0x4,0x37,0x56, 0x4,0x37,0x50, 0x3,0x3b,0x5c, + 0x4,0x37,0x59, 0x3,0x3b,0x5f, 0x4,0x37,0x54, 0x4,0x37,0x4e, + 0x5,0x3f,0x32, 0x3,0x41,0x25, 0x4,0x37,0x55, 0x4,0x3d,0x3e, + 0x3,0x3b,0x60, 0x4,0x3d,0x37, 0x5,0x32,0x58, 0x3,0x3b,0x5b, + 0x3,0x41,0x26, 0x3,0x41,0x2d, 0x4,0x3d,0x3b, 0x4,0x43,0x43, + 0x5,0x3f,0x42, 0x6,0x52,0x69, 0x3,0x46,0x67, 0x4,0x3d,0x3a, + 0x4,0x3d,0x3c, 0x3,0x41,0x30, 0x3,0x46,0x65, 0x4,0x43,0x42, + 0x4,0x43,0x50, 0x3,0x46,0x66, 0x3,0x41,0x2f, 0x4,0x43,0x48, + 0x4,0x43,0x47, 0x4,0x43,0x49, 0x3,0x4b,0x7d, 0x4,0x43,0x4d, + 0x4,0x49,0x65, 0x3,0x4c,0x22, 0x3,0x46,0x69, 0x3,0x4b,0x7b, + 0x4,0x43,0x4a, 0x4,0x43,0x4c, 0x4,0x43,0x46, 0x3,0x4c,0x27, + 0x3,0x4b,0x78, 0x4,0x43,0x4b, 0x4,0x50,0x38, 0x3,0x4c,0x2a, + 0x4,0x49,0x67, 0x4,0x49,0x69, 0x4,0x49,0x68, 0x4,0x49,0x6b, + 0x7,0x22,0x7c, 0x4,0x49,0x6d, 0x3,0x50,0x69, 0x4,0x49,0x6c, + 0x3,0x4c,0x26, 0x4,0x50,0x39, 0x5,0x5b,0x4c, 0x4,0x5b,0x23, + 0x4,0x5b,0x29, 0x4,0x56,0x36, 0x4,0x5b,0x25, 0x3,0x57,0x67, + 0x4,0x5b,0x24, 0xf,0x5a,0x29, 0x3,0x57,0x66, 0x4,0x50,0x3a, + 0x5,0x67,0x78, 0x4,0x63,0x43, 0x4,0x5f,0x64, 0x5,0x67,0x73, + 0x7,0x47,0x2c, 0x3,0x5e,0x30, 0x4,0x63,0x42, 0x4,0x63,0x40, + 0x3,0x5f,0x47, 0x4,0x68,0x6c, 0x3,0x61,0x78, 0x3,0x23,0x6a, + 0x3,0x26,0x26, 0x4,0x26,0x54, 0x6,0x2b,0x52, 0x4,0x2d,0x2f, + 0x4,0x2d,0x30, 0x5,0x2d,0x5d, 0x3,0x35,0x7a, 0x3,0x3b,0x65, + 0x4,0x3d,0x42, 0x4,0x43,0x54, 0x5,0x4d,0x37, 0x3,0x4c,0x2b, + 0x3,0x54,0x62, 0x6,0x27,0x6e, 0x4,0x26,0x55, 0x4,0x26,0x56, + 0x4,0x29,0x4d, 0x3,0x2c,0x64, 0x4,0x21,0x7b, 0x4,0x21,0x7a, + 0x3,0x22,0x4f, 0x4,0x22,0x74, 0x4,0x22,0x73, 0x4,0x22,0x75, + 0x4,0x24,0x3a, 0x4,0x24,0x36, 0x3,0x26,0x2c, 0x3,0x26,0x2d, + 0x3,0x26,0x30, 0x3,0x26,0x2b, 0x4,0x26,0x58, 0x3,0x29,0x2d, + 0x5,0x26,0x3a, 0x3,0x29,0x2c, 0x3,0x29,0x38, 0x4,0x29,0x55, + 0x4,0x2d,0x33, 0x4,0x26,0x59, 0x3,0x29,0x2b, 0xf,0x27,0x2e, + 0x4,0x29,0x4e, 0x4,0x29,0x54, 0x3,0x2c,0x66, 0x3,0x29,0x27, + 0x3,0x2c,0x67, 0x3,0x2c,0x69, 0x4,0x2d,0x3c, 0x3,0x2c,0x71, + 0x4,0x29,0x56, 0x3,0x2c,0x68, 0x4,0x29,0x52, 0x4,0x2d,0x32, + 0x4,0x2d,0x31, 0x3,0x2c,0x6a, 0x3,0x2c,0x65, 0x3,0x31,0x34, + 0x3,0x31,0x2a, 0x3,0x35,0x7b, 0x3,0x31,0x31, 0x3,0x31,0x3a, + 0x4,0x2d,0x3b, 0x3,0x31,0x2d, 0x3,0x31,0x2b, 0x4,0x31,0x7c, + 0x4,0x32,0x21, 0x4,0x31,0x7b, 0x3,0x36,0x2c, 0x6,0x40,0x32, + 0x4,0x32,0x25, 0x3,0x36,0x2f, 0x3,0x36,0x30, 0x4,0x31,0x79, + 0x3,0x35,0x7e, 0x4,0x31,0x71, 0x3,0x36,0x25, 0x4,0x31,0x7e, + 0x4,0x31,0x7a, 0x3,0x3b,0x6b, 0x3,0x36,0x2a, 0x4,0x37,0x6e, + 0x4,0x37,0x62, 0x3,0x36,0x21, 0x4,0x3d,0x45, 0x3,0x41,0x31, + 0x4,0x37,0x64, 0x3,0x3b,0x6a, 0x4,0x37,0x6b, 0x4,0x37,0x68, + 0x4,0x37,0x65, 0x3,0x3b,0x6c, 0x3,0x3b,0x69, 0x4,0x37,0x70, + 0x4,0x37,0x61, 0x3,0x3b,0x6e, 0x4,0x3d,0x50, 0x4,0x3d,0x4f, + 0x3,0x41,0x37, 0x4,0x3d,0x4c, 0x4,0x3d,0x4a, 0x3,0x41,0x35, + 0x3,0x41,0x3b, 0x4,0x3d,0x48, 0x4,0x3d,0x4e, 0x3,0x41,0x3c, + 0x3,0x41,0x4a, 0x3,0x41,0x43, 0x3,0x41,0x3f, 0x3,0x41,0x47, + 0x3,0x41,0x40, 0x3,0x41,0x46, 0x3,0x41,0x41, 0x3,0x41,0x39, + 0x4,0x43,0x58, 0x4,0x43,0x61, 0x6,0x5d,0x32, 0x3,0x46,0x79, + 0x3,0x47,0x2e, 0x3,0x47,0x2d, 0x4,0x43,0x56, 0x3,0x46,0x7c, + 0x3,0x47,0x27, 0x3,0x47,0x2f, 0x4,0x43,0x5c, 0x3,0x46,0x77, + 0x5,0x46,0x25, 0x3,0x46,0x7d, 0x4,0x49,0x75, 0x3,0x4c,0x36, + 0x4,0x43,0x64, 0x5,0x46,0x23, 0x3,0x47,0x2b, 0x3,0x47,0x2c, + 0x4,0x4a,0x24, 0x3,0x4c,0x33, 0x7,0x23,0x3a, 0x4,0x49,0x79, + 0x4,0x49,0x7a, 0x4,0x49,0x76, 0x4,0x4a,0x28, 0x4,0x4a,0x22, + 0x5,0x4d,0x3a, 0x4,0x49,0x7e, 0x5,0x4d,0x3e, 0x3,0x4c,0x3c, + 0x4,0x4a,0x23, 0x3,0x50,0x74, 0x4,0x56,0x39, 0x4,0x50,0x45, + 0x3,0x50,0x73, 0x3,0x50,0x6e, 0x3,0x50,0x78, 0x3,0x50,0x72, + 0x3,0x50,0x71, 0x3,0x54,0x65, 0x3,0x54,0x6a, 0x3,0x54,0x68, + 0x3,0x54,0x63, 0x3,0x54,0x66, 0x4,0x5b,0x2d, 0x3,0x57,0x69, + 0x4,0x5b,0x32, 0x4,0x5b,0x30, 0x4,0x5b,0x2e, 0x3,0x57,0x6f, + 0x3,0x57,0x71, 0x4,0x5b,0x31, 0x3,0x57,0x68, 0x4,0x5b,0x2f, + 0x3,0x57,0x72, 0xf,0x5e,0x73, 0x3,0x5a,0x3d, 0x3,0x5a,0x3e, + 0x4,0x63,0x47, 0x3,0x5c,0x40, 0x4,0x63,0x46, 0x5,0x70,0x24, + 0x3,0x5e,0x32, 0x4,0x66,0x40, 0x3,0x60,0x31, 0x4,0x6a,0x49, + 0x4,0x6a,0x48, 0x5,0x79,0x2a, 0x4,0x26,0x5b, 0x4,0x2d,0x40, + 0x4,0x2d,0x3f, 0x4,0x32,0x27, 0x4,0x3d,0x54, 0x4,0x24,0x40, + 0x3,0x26,0x3a, 0x4,0x26,0x5e, 0x4,0x26,0x5f, 0x4,0x29,0x5d, + 0x3,0x2c,0x75, 0x3,0x31,0x3e, 0x4,0x2d,0x42, 0x6,0x38,0x2b, + 0x3,0x36,0x33, 0x4,0x32,0x28, 0x3,0x36,0x35, 0x4,0x32,0x2c, + 0x4,0x37,0x79, 0x4,0x37,0x75, 0x4,0x37,0x78, 0x4,0x37,0x77, + 0x4,0x37,0x76, 0x5,0x38,0x7c, 0x3,0x3b,0x77, 0x4,0x3d,0x5c, + 0x4,0x3d,0x59, 0x4,0x3d,0x5b, 0x3,0x41,0x4c, 0x4,0x43,0x66, + 0x5,0x46,0x30, 0x5,0x46,0x2e, 0x4,0x43,0x69, 0x4,0x4a,0x2b, + 0x4,0x4a,0x2a, 0x4,0x4a,0x29, 0x4,0x50,0x49, 0x4,0x50,0x4c, + 0x3,0x57,0x73, 0x4,0x5b,0x3a, 0x4,0x63,0x4c, 0x4,0x66,0x43, + 0x3,0x26,0x3b, 0x6,0x38,0x2c, 0x3,0x41,0x4f, 0x3,0x29,0x3a, + 0x4,0x29,0x61, 0x3,0x31,0x41, 0x3,0x39,0x2b, 0x3,0x3b,0x78, + 0x4,0x4a,0x2e, 0x4,0x56,0x3e, 0x4,0x6a,0x4b, 0x4,0x29,0x62, + 0x4,0x2d,0x49, 0x6,0x38,0x30, 0x6,0x49,0x61, 0x6,0x5d,0x51, + 0x5,0x4d,0x4b, 0x3,0x23,0x71, 0x6,0x2b,0x70, 0x6,0x38,0x34, + 0x3,0x36,0x3b, 0x3,0x36,0x3e, 0x4,0x3d,0x65, 0x4,0x4a,0x30, + 0x4,0x4a,0x31, 0x4,0x22,0x78, 0x4,0x22,0x79, 0x4,0x24,0x43, + 0x3,0x26,0x3c, 0x3,0x26,0x3f, 0x3,0x26,0x3e, 0x3,0x26,0x40, + 0x3,0x29,0x3f, 0x3,0x29,0x3d, 0x4,0x26,0x63, 0x5,0x29,0x4f, + 0x4,0x29,0x63, 0x3,0x2c,0x7b, 0x4,0x29,0x64, 0x4,0x29,0x65, + 0x3,0x2c,0x78, 0x3,0x2d,0x26, 0x6,0x31,0x67, 0x4,0x2d,0x4c, + 0x4,0x32,0x3b, 0x4,0x2d,0x4b, 0x3,0x31,0x47, 0x6,0x38,0x37, + 0x3,0x31,0x4a, 0xf,0x2f,0x6e, 0x4,0x2d,0x4d, 0x6,0x40,0x51, + 0x4,0x32,0x36, 0x4,0x32,0x3a, 0x4,0x32,0x37, 0x3,0x36,0x43, + 0x6,0x40,0x4f, 0x3,0x3c,0x22, 0x4,0x37,0x7e, 0x3,0x3b,0x7a, + 0x3,0x3b,0x7b, 0x4,0x38,0x25, 0x3,0x3c,0x27, 0x4,0x38,0x22, + 0x6,0x49,0x73, 0x3,0x3c,0x21, 0x6,0x53,0x3d, 0x5,0x3f,0x62, + 0x3,0x41,0x52, 0x3,0x41,0x57, 0x3,0x41,0x5a, 0x3,0x41,0x55, + 0x3,0x41,0x53, 0x3,0x41,0x5c, 0x3,0x41,0x58, 0x4,0x3d,0x68, + 0x4,0x3d,0x67, 0x3,0x41,0x54, 0x3,0x47,0x38, 0x4,0x43,0x6e, + 0x3,0x47,0x32, 0x3,0x47,0x36, 0x5,0x4d,0x53, 0x4,0x4a,0x32, + 0x3,0x4c,0x42, 0x3,0x4c,0x45, 0x4,0x50,0x52, 0x4,0x50,0x51, + 0x3,0x51,0x21, 0x5,0x4d,0x50, 0x3,0x50,0x7b, 0x3,0x50,0x7c, + 0x4,0x50,0x53, 0x7,0x2e,0x5a, 0x3,0x54,0x73, 0x3,0x54,0x6e, + 0x4,0x56,0x40, 0x4,0x5b,0x40, 0x4,0x5b,0x41, 0x4,0x5b,0x3f, + 0x7,0x3f,0x76, 0x3,0x5a,0x40, 0x3,0x5a,0x41, 0x3,0x5c,0x44, + 0x3,0x5f,0x4c, 0x3,0x5f,0x4d, 0x5,0x75,0x6e, 0x5,0x75,0x6d, + 0x3,0x23,0x74, 0x4,0x50,0x56, 0x3,0x54,0x74, 0x3,0x29,0x44, + 0x3,0x31,0x4e, 0x5,0x2e,0x25, 0x3,0x36,0x49, 0x3,0x3c,0x28, + 0x4,0x3a,0x43, 0x5,0x46,0x45, 0x5,0x4d,0x58, 0x3,0x51,0x25, + 0x3,0x23,0x76, 0x3,0x26,0x43, 0x4,0x24,0x48, 0x3,0x26,0x46, + 0x3,0x29,0x4b, 0x3,0x29,0x46, 0xf,0x27,0x4c, 0x3,0x29,0x50, + 0x3,0x29,0x4d, 0x5,0x26,0x51, 0x3,0x2d,0x28, 0x3,0x2d,0x2c, + 0x4,0x29,0x6f, 0x4,0x29,0x6c, 0x3,0x2d,0x29, 0x4,0x2d,0x57, + 0x4,0x2d,0x51, 0x4,0x2d,0x54, 0x4,0x2d,0x58, 0x3,0x31,0x52, + 0x5,0x2e,0x2b, 0x4,0x2d,0x52, 0x4,0x2d,0x5b, 0x3,0x31,0x55, + 0x4,0x2d,0x56, 0x3,0x31,0x51, 0x3,0x36,0x59, 0x4,0x32,0x43, + 0x3,0x36,0x4a, 0x3,0x36,0x4f, 0x5,0x32,0x79, 0x4,0x32,0x42, + 0x4,0x32,0x46, 0x4,0x32,0x41, 0x4,0x38,0x34, 0x3,0x36,0x58, + 0x3,0x36,0x5d, 0x4,0x38,0x2f, 0x3,0x3c,0x2e, 0x4,0x38,0x2c, + 0x3,0x3c,0x3f, 0x3,0x3c,0x30, 0x4,0x38,0x2a, 0x5,0x39,0x33, + 0x4,0x38,0x2d, 0x3,0x3c,0x2c, 0x5,0x39,0x39, 0x4,0x38,0x35, + 0x3,0x3c,0x35, 0x4,0x38,0x37, 0x3,0x3c,0x36, 0x3,0x3c,0x43, + 0x3,0x3c,0x2b, 0x3,0x3c,0x2d, 0x4,0x3d,0x78, 0x3,0x41,0x71, + 0x3,0x41,0x66, 0x3,0x41,0x70, 0x4,0x3d,0x6b, 0x4,0x3d,0x6e, + 0x4,0x3d,0x6f, 0x3,0x41,0x6c, 0x3,0x41,0x69, 0x3,0x41,0x64, + 0x4,0x3d,0x6d, 0x3,0x41,0x5e, 0x4,0x3d,0x75, 0x3,0x41,0x62, + 0x3,0x41,0x63, 0x3,0x41,0x7a, 0x3,0x41,0x61, 0x3,0x41,0x5f, + 0x4,0x44,0x23, 0x4,0x3d,0x76, 0x3,0x41,0x60, 0x3,0x42,0x5a, + 0x3,0x41,0x67, 0xf,0x48,0x55, 0x4,0x44,0x24, 0x4,0x43,0x75, + 0x4,0x44,0x21, 0x4,0x43,0x7c, 0x3,0x47,0x3f, 0x4,0x43,0x78, + 0x4,0x43,0x73, 0x3,0x47,0x41, 0x4,0x43,0x74, 0x3,0x47,0x4a, + 0x4,0x43,0x7d, 0x4,0x43,0x7e, 0x4,0x43,0x7a, 0x4,0x44,0x22, + 0x3,0x47,0x4f, 0x3,0x47,0x40, 0x4,0x44,0x25, 0x4,0x43,0x71, + 0x5,0x46,0x4b, 0x3,0x47,0x49, 0x4,0x3d,0x72, 0x3,0x47,0x50, + 0xf,0x48,0x52, 0x3,0x4c,0x4e, 0x5,0x4d,0x6d, 0x4,0x4a,0x3a, + 0x3,0x4c,0x4c, 0x5,0x4d,0x61, 0x3,0x4c,0x53, 0x4,0x4a,0x37, + 0x4,0x4a,0x36, 0x3,0x4c,0x5d, 0x3,0x4c,0x58, 0x7,0x23,0x6f, + 0x4,0x4a,0x38, 0x4,0x4a,0x42, 0x3,0x4c,0x5a, 0x3,0x4c,0x5c, + 0x3,0x4c,0x48, 0x3,0x4c,0x55, 0x3,0x51,0x43, 0x3,0x51,0x42, + 0x4,0x50,0x60, 0x4,0x50,0x5a, 0x3,0x51,0x37, 0x3,0x51,0x30, + 0x4,0x50,0x59, 0x4,0x4a,0x39, 0x3,0x51,0x3f, 0x3,0x51,0x2a, + 0x3,0x51,0x3d, 0x4,0x56,0x49, 0x3,0x51,0x33, 0x3,0x51,0x39, + 0x3,0x4c,0x4b, 0x4,0x50,0x5e, 0x3,0x51,0x2d, 0x4,0x50,0x64, + 0x3,0x51,0x35, 0x3,0x51,0x34, 0x3,0x51,0x36, 0x3,0x55,0x22, + 0x4,0x56,0x48, 0x3,0x54,0x7e, 0x3,0x55,0x25, 0x3,0x54,0x7d, + 0x4,0x56,0x4b, 0x7,0x38,0x55, 0x5,0x5b,0x68, 0x3,0x54,0x77, + 0x3,0x55,0x26, 0xf,0x5f,0x29, 0x3,0x54,0x79, 0x3,0x55,0x28, + 0x4,0x5b,0x48, 0x4,0x5b,0x44, 0x3,0x57,0x7c, 0x4,0x5b,0x4a, + 0x4,0x5b,0x49, 0x4,0x5f,0x6f, 0x4,0x5f,0x73, 0x3,0x5a,0x49, + 0x4,0x5f,0x70, 0x4,0x5f,0x6e, 0x4,0x5f,0x72, 0x4,0x5f,0x75, + 0x3,0x5a,0x4c, 0x3,0x5a,0x4b, 0xf,0x62,0x53, 0x3,0x5a,0x4a, + 0x3,0x5c,0x4c, 0x3,0x5c,0x46, 0x4,0x63,0x51, 0x4,0x63,0x4f, + 0x3,0x5c,0x48, 0x3,0x5c,0x4d, 0x4,0x63,0x54, 0x3,0x5c,0x4b, + 0x3,0x5c,0x45, 0xf,0x65,0x3e, 0x5,0x70,0x27, 0x3,0x5e,0x36, + 0x3,0x5c,0x4a, 0x3,0x5f,0x50, 0x4,0x68,0x6e, 0x3,0x60,0x35, + 0x3,0x60,0x33, 0x3,0x60,0x34, 0x5,0x24,0x48, 0x6,0x28,0x30, + 0x4,0x26,0x6d, 0x5,0x26,0x56, 0x4,0x26,0x70, 0x4,0x26,0x6c, + 0x4,0x2d,0x60, 0x4,0x29,0x70, 0x4,0x29,0x71, 0x6,0x31,0x78, + 0x4,0x29,0x74, 0x4,0x29,0x73, 0x5,0x2e,0x2e, 0x4,0x2d,0x5d, + 0x4,0x2d,0x61, 0x4,0x2d,0x62, 0x4,0x2d,0x5e, 0x3,0x36,0x61, + 0x4,0x32,0x48, 0x4,0x32,0x49, 0x6,0x40,0x6e, 0x4,0x38,0x3b, + 0x4,0x38,0x39, 0x3,0x3c,0x46, 0x5,0x39,0x43, 0x4,0x38,0x3c, + 0x6,0x38,0x64, 0x4,0x3e,0x21, 0x4,0x3d,0x7c, 0x4,0x3d,0x7b, + 0x4,0x3d,0x7d, 0x4,0x3d,0x7e, 0x4,0x3e,0x22, 0x3,0x47,0x52, + 0x6,0x5d,0x77, 0x4,0x44,0x2a, 0x4,0x4a,0x4c, 0x3,0x4c,0x68, + 0x4,0x50,0x66, 0x4,0x50,0x67, 0x4,0x56,0x4f, 0x4,0x56,0x4e, + 0x3,0x55,0x2a, 0x3,0x55,0x2c, 0x4,0x5f,0x77, 0x7,0x4e,0x22, + 0x4,0x68,0x71, 0x5,0x75,0x77, 0x5,0x79,0x2f, 0x6,0x25,0x25, + 0x3,0x2d,0x3e, 0x3,0x2b,0x7b, 0x3,0x3c,0x48, 0x4,0x38,0x3f, + 0x5,0x46,0x5f, 0x3,0x58,0x24, 0x4,0x22,0x7c, 0x3,0x29,0x57, + 0x5,0x26,0x62, 0x4,0x26,0x75, 0x3,0x2d,0x3f, 0x3,0x2d,0x41, + 0x3,0x2d,0x40, 0x3,0x31,0x69, 0x3,0x36,0x63, 0x4,0x32,0x4a, + 0x4,0x38,0x45, 0x4,0x38,0x44, 0x4,0x38,0x46, 0x4,0x38,0x42, + 0x3,0x3c,0x4a, 0x3,0x42,0x23, 0x4,0x3e,0x23, 0x4,0x3e,0x24, + 0x3,0x42,0x24, 0x4,0x44,0x32, 0x5,0x46,0x60, 0x4,0x44,0x33, + 0x4,0x44,0x30, 0x4,0x4a,0x50, 0x4,0x4a,0x4f, 0x4,0x50,0x6b, + 0x4,0x50,0x6a, 0x4,0x56,0x51, 0x4,0x63,0x55, 0x3,0x5c,0x4e, + 0x5,0x75,0x78, 0x5,0x24,0x4e, 0x4,0x26,0x78, 0x4,0x2d,0x64, + 0x3,0x31,0x6b, 0x4,0x32,0x4f, 0x4,0x38,0x49, 0x4,0x38,0x4a, + 0x4,0x38,0x4b, 0x3,0x42,0x25, 0x4,0x44,0x35, 0x3,0x51,0x47, + 0x3,0x51,0x48, 0x4,0x50,0x6e, 0x4,0x56,0x53, 0x3,0x58,0x25, + 0x4,0x29,0x7b, 0x3,0x23,0x7b, 0x4,0x26,0x79, 0x3,0x29,0x5b, + 0x4,0x26,0x7a, 0xf,0x27,0x5b, 0x3,0x2d,0x43, 0x4,0x2d,0x66, + 0x4,0x32,0x52, 0x4,0x32,0x54, 0x4,0x32,0x53, 0x4,0x32,0x55, + 0x3,0x36,0x67, 0x4,0x2d,0x67, 0x4,0x32,0x51, 0x5,0x39,0x5b, + 0x3,0x3c,0x4c, 0x4,0x38,0x4f, 0x4,0x38,0x4c, 0x4,0x3e,0x29, + 0x3,0x42,0x27, 0x4,0x3e,0x28, 0x4,0x3e,0x27, 0x4,0x44,0x3f, + 0x4,0x44,0x38, 0x4,0x44,0x39, 0x4,0x44,0x3a, 0x5,0x46,0x68, + 0x4,0x44,0x3c, 0x4,0x50,0x6f, 0x4,0x50,0x71, 0x4,0x50,0x72, + 0x3,0x51,0x49, 0x4,0x5b,0x50, 0x4,0x5b,0x4f, 0x3,0x5a,0x50, + 0x4,0x6d,0x57, 0x4,0x2d,0x6a, 0x3,0x29,0x5c, 0x3,0x36,0x68, + 0x3,0x4c,0x69, 0x3,0x51,0x4a, 0x4,0x21,0x4f, 0x3,0x22,0x56, + 0x3,0x22,0x55, 0x3,0x24,0x22, 0x5,0x21,0x74, 0x4,0x23,0x22, + 0x3,0x26,0x54, 0x3,0x26,0x4f, 0x4,0x24,0x4f, 0x3,0x26,0x5d, + 0x6,0x28,0x49, 0x3,0x26,0x5a, 0x4,0x24,0x51, 0x3,0x26,0x4b, + 0x6,0x28,0x4a, 0x6,0x28,0x44, 0x3,0x26,0x58, 0x3,0x29,0x61, + 0x3,0x29,0x5f, 0x3,0x29,0x5e, 0x3,0x29,0x62, 0x3,0x29,0x60, + 0x4,0x26,0x7e, 0x3,0x29,0x68, 0x3,0x29,0x66, 0xf,0x27,0x66, + 0x3,0x2d,0x44, 0x5,0x2a,0x24, 0x4,0x27,0x22, 0x3,0x2d,0x54, + 0x5,0x29,0x7b, 0x5,0x29,0x7c, 0x4,0x29,0x7e, 0x3,0x2d,0x56, + 0x3,0x2d,0x4c, 0xf,0x30,0x49, 0x6,0x38,0x72, 0x3,0x31,0x70, + 0x3,0x31,0x71, 0x4,0x2d,0x6b, 0x6,0x39,0x33, 0x3,0x31,0x74, + 0x4,0x2d,0x6c, 0x3,0x36,0x69, 0x3,0x32,0x24, 0x3,0x32,0x23, + 0x3,0x31,0x7e, 0x3,0x31,0x75, 0x4,0x32,0x57, 0x3,0x36,0x71, + 0x4,0x32,0x63, 0x4,0x32,0x64, 0x3,0x36,0x6e, 0x4,0x32,0x5e, + 0x3,0x37,0x22, 0x3,0x36,0x6d, 0x3,0x3c,0x4f, 0x3,0x36,0x7e, + 0x4,0x32,0x58, 0x4,0x32,0x68, 0x5,0x39,0x5e, 0x4,0x32,0x5a, + 0x4,0x32,0x5c, 0x6,0x41,0x2b, 0x5,0x33,0x3d, 0x3,0x3c,0x5e, + 0x3,0x36,0x7b, 0x3,0x3c,0x5f, 0x3,0x36,0x73, 0x6,0x41,0x41, + 0x3,0x36,0x78, 0xf,0x36,0x33, 0x4,0x38,0x51, 0x4,0x38,0x56, + 0x3,0x3c,0x65, 0x4,0x38,0x52, 0x3,0x3c,0x59, 0x4,0x38,0x59, + 0x3,0x3c,0x6a, 0x3,0x3c,0x67, 0x3,0x3c,0x55, 0x4,0x38,0x57, + 0x4,0x38,0x5a, 0x3,0x3c,0x53, 0x3,0x3c,0x57, 0x3,0x3c,0x61, + 0x3,0x42,0x2b, 0x6,0x4a,0x6d, 0xf,0x3c,0x43, 0xf,0x3c,0x5a, + 0x4,0x3e,0x37, 0x3,0x42,0x2c, 0x3,0x42,0x37, 0x3,0x42,0x35, + 0x3,0x42,0x48, 0x3,0x42,0x38, 0x4,0x3e,0x30, 0x4,0x3e,0x39, + 0x4,0x3e,0x2d, 0x3,0x42,0x42, 0x4,0x3e,0x38, 0x3,0x42,0x34, + 0x3,0x42,0x3c, 0x4,0x3e,0x3c, 0x3,0x42,0x2f, 0x3,0x42,0x41, + 0x5,0x40,0x27, 0x4,0x3e,0x2f, 0x4,0x3e,0x32, 0x3,0x42,0x32, + 0x3,0x42,0x43, 0x3,0x47,0x55, 0x4,0x44,0x49, 0x3,0x47,0x60, + 0x6,0x5e,0x3b, 0x3,0x47,0x59, 0x6,0x54,0x50, 0x3,0x47,0x58, + 0x4,0x44,0x46, 0x4,0x44,0x4d, 0x4,0x44,0x4a, 0x6,0x5e,0x40, + 0x3,0x4c,0x6e, 0x4,0x4a,0x5f, 0x4,0x4a,0x61, 0x3,0x4c,0x6f, + 0x3,0x4c,0x7c, 0x4,0x4a,0x68, 0x4,0x4a,0x5d, 0x3,0x4c,0x6d, + 0x4,0x4a,0x59, 0x3,0x4c,0x72, 0x5,0x46,0x78, 0x7,0x24,0x61, + 0x3,0x4c,0x70, 0x4,0x50,0x74, 0x3,0x51,0x4b, 0x3,0x4c,0x76, + 0x4,0x50,0x77, 0x4,0x50,0x7d, 0x5,0x55,0x36, 0x4,0x50,0x76, + 0x3,0x51,0x4f, 0x3,0x51,0x4e, 0x4,0x50,0x7a, 0x5,0x55,0x2d, + 0x3,0x51,0x53, 0x3,0x51,0x57, 0x4,0x50,0x7b, 0x4,0x56,0x56, + 0x3,0x51,0x51, 0x3,0x51,0x4c, 0x4,0x50,0x78, 0x3,0x51,0x52, + 0x4,0x4a,0x62, 0x5,0x55,0x2e, 0x3,0x55,0x32, 0x3,0x55,0x38, + 0x4,0x56,0x5e, 0x4,0x56,0x60, 0x3,0x55,0x34, 0x4,0x56,0x58, + 0x3,0x55,0x2e, 0x4,0x56,0x57, 0x4,0x56,0x5c, 0x3,0x55,0x3b, + 0x4,0x56,0x59, 0x4,0x56,0x5b, 0x3,0x55,0x33, 0x4,0x5b,0x56, + 0x4,0x5b,0x54, 0x4,0x5b,0x5a, 0x4,0x5b,0x57, 0x4,0x5b,0x60, + 0x4,0x5f,0x7b, 0x4,0x5f,0x7d, 0x4,0x5b,0x5b, 0x4,0x5f,0x79, + 0x3,0x5a,0x51, 0x3,0x5c,0x50, 0x4,0x63,0x5a, 0x4,0x63,0x5e, + 0x4,0x63,0x5b, 0x3,0x5c,0x52, 0x4,0x66,0x49, 0x5,0x70,0x3e, + 0x4,0x66,0x4a, 0x4,0x66,0x4c, 0x4,0x68,0x73, 0x3,0x5e,0x39, + 0x3,0x5e,0x38, 0x3,0x5f,0x51, 0x4,0x6a,0x4e, 0x3,0x60,0x38, + 0x4,0x6b,0x6d, 0x4,0x6b,0x6e, 0x3,0x61,0x66, 0x3,0x24,0x2a, + 0x4,0x24,0x52, 0x3,0x26,0x61, 0xf,0x24,0x6e, 0x3,0x29,0x6e, + 0x4,0x27,0x27, 0x3,0x29,0x78, 0xf,0x27,0x6e, 0x3,0x29,0x73, + 0x3,0x2d,0x67, 0x3,0x2d,0x59, 0x3,0x2d,0x66, 0x3,0x2d,0x61, + 0x3,0x2d,0x60, 0x3,0x2d,0x5b, 0x4,0x2a,0x27, 0x3,0x32,0x2e, + 0x4,0x2d,0x73, 0x3,0x32,0x32, 0x3,0x37,0x2b, 0x3,0x37,0x2a, + 0x3,0x37,0x34, 0x4,0x32,0x71, 0x4,0x32,0x76, 0x4,0x32,0x70, + 0x4,0x32,0x77, 0xf,0x36,0x48, 0x3,0x3c,0x76, 0x4,0x38,0x65, + 0x4,0x38,0x61, 0x3,0x3c,0x75, 0x4,0x38,0x62, 0x4,0x38,0x64, + 0x4,0x38,0x60, 0x3,0x3b,0x23, 0x3,0x3c,0x7e, 0x3,0x3c,0x70, + 0x3,0x3c,0x78, 0x3,0x42,0x54, 0x3,0x42,0x4d, 0x3,0x42,0x56, + 0x4,0x3e,0x4b, 0x3,0x42,0x4a, 0x3,0x42,0x55, 0x4,0x3e,0x48, + 0x4,0x3e,0x46, 0x4,0x3e,0x49, 0x6,0x54,0x54, 0x3,0x42,0x4b, + 0x3,0x42,0x50, 0xf,0x42,0x78, 0xf,0x43,0x3c, 0x4,0x44,0x59, + 0x3,0x47,0x73, 0x3,0x47,0x69, 0x6,0x54,0x67, 0x4,0x44,0x56, + 0x4,0x44,0x5a, 0x4,0x44,0x5c, 0x3,0x47,0x71, 0xf,0x49,0x58, + 0x3,0x4d,0x26, 0x3,0x4d,0x23, 0x3,0x4d,0x2b, 0x3,0x4d,0x21, + 0x3,0x4d,0x27, 0x4,0x4a,0x6a, 0x4,0x51,0x25, 0x3,0x51,0x5d, + 0x3,0x51,0x5b, 0x4,0x51,0x2b, 0x3,0x51,0x5f, 0x3,0x51,0x61, + 0x4,0x51,0x24, 0x3,0x51,0x64, 0x3,0x51,0x65, 0x3,0x55,0x3d, + 0x4,0x56,0x62, 0x3,0x55,0x3f, 0x3,0x55,0x44, 0x7,0x39,0x26, + 0x3,0x57,0x51, 0x3,0x58,0x2c, 0x4,0x56,0x64, 0x3,0x5c,0x5a, + 0x3,0x5a,0x59, 0x3,0x5c,0x54, 0x3,0x5c,0x5b, 0x4,0x63,0x5f, + 0x4,0x66,0x4e, 0x5,0x73,0x57, 0x4,0x6a,0x50, 0x3,0x60,0x3a, + 0x3,0x61,0x7a, 0x4,0x27,0x2c, 0x3,0x29,0x7a, 0x3,0x37,0x58, + 0x3,0x47,0x74, 0x3,0x2d,0x6a, 0x4,0x2d,0x76, 0x3,0x37,0x36, + 0x4,0x38,0x6b, 0x3,0x29,0x7b, 0x4,0x2a,0x2c, 0x4,0x38,0x6c, + 0x3,0x29,0x7d, 0x3,0x29,0x7e, 0x5,0x2e,0x53, 0x6,0x39,0x40, + 0x4,0x2d,0x7a, 0x4,0x44,0x5f, 0x7,0x39,0x2d, 0x4,0x5b,0x64, + 0x4,0x66,0x50, 0x3,0x21,0x6a, 0x3,0x32,0x33, 0x4,0x23,0x26, + 0x3,0x26,0x65, 0x4,0x24,0x55, 0x6,0x2c,0x71, 0x4,0x27,0x33, + 0x5,0x26,0x77, 0x4,0x27,0x32, 0x4,0x27,0x2f, 0x3,0x2d,0x6c, + 0x3,0x2d,0x6f, 0x4,0x2a,0x2e, 0x3,0x2d,0x6e, 0x3,0x32,0x34, + 0x3,0x32,0x35, 0x4,0x2d,0x7d, 0x4,0x2d,0x7c, 0x4,0x32,0x7a, + 0x5,0x33,0x4d, 0x4,0x32,0x79, 0x4,0x32,0x7e, 0x3,0x37,0x38, + 0x6,0x41,0x66, 0x3,0x37,0x37, 0x4,0x38,0x70, 0x4,0x38,0x72, + 0x4,0x38,0x73, 0x4,0x44,0x63, 0x6,0x54,0x78, 0x4,0x3e,0x4e, + 0x3,0x42,0x5e, 0x4,0x44,0x62, 0x4,0x44,0x60, 0x4,0x44,0x64, + 0x4,0x4a,0x6f, 0x4,0x4a,0x6e, 0x4,0x4a,0x72, 0x4,0x4a,0x71, + 0x4,0x4a,0x73, 0x4,0x51,0x2e, 0x4,0x51,0x30, 0x4,0x51,0x2f, + 0x4,0x56,0x67, 0x3,0x55,0x46, 0x3,0x55,0x47, 0x4,0x5b,0x66, + 0x4,0x5b,0x65, 0x4,0x60,0x24, 0x7,0x53,0x6b, 0x4,0x6a,0x51, + 0x4,0x27,0x34, 0x4,0x24,0x59, 0x3,0x26,0x6d, 0x4,0x24,0x56, + 0x3,0x26,0x6c, 0x6,0x2c,0x75, 0x4,0x27,0x39, 0x5,0x27,0x2e, + 0x3,0x2a,0x29, 0x3,0x2a,0x24, 0x3,0x2a,0x25, 0x4,0x27,0x3a, + 0x4,0x2a,0x32, 0x4,0x2a,0x34, 0x4,0x2a,0x35, 0x3,0x2d,0x72, + 0x6,0x32,0x67, 0x3,0x32,0x37, 0x5,0x2e,0x5c, 0x4,0x2e,0x21, + 0x4,0x2d,0x7e, 0x4,0x2e,0x22, 0x4,0x2e,0x26, 0x6,0x41,0x6d, + 0x4,0x2e,0x27, 0x5,0x33,0x51, 0x4,0x33,0x28, 0x6,0x41,0x75, + 0x4,0x33,0x29, 0x4,0x33,0x25, 0x4,0x33,0x2b, 0x4,0x33,0x27, + 0x4,0x33,0x2e, 0x4,0x38,0x79, 0x4,0x38,0x77, 0x3,0x3d,0x2c, + 0x4,0x38,0x7b, 0x6,0x4b,0x43, 0x4,0x44,0x65, 0x4,0x3e,0x54, + 0x4,0x44,0x66, 0x4,0x3e,0x53, 0x3,0x42,0x60, 0x4,0x3e,0x52, + 0x4,0x44,0x6a, 0x6,0x5e,0x6e, 0x4,0x44,0x69, 0x4,0x44,0x68, + 0x4,0x44,0x67, 0x3,0x47,0x76, 0x4,0x38,0x7a, 0x4,0x4a,0x7b, + 0x4,0x4a,0x76, 0x4,0x4a,0x7a, 0x4,0x4a,0x7c, 0x7,0x2f,0x74, + 0x4,0x51,0x32, 0x4,0x51,0x34, 0x3,0x55,0x48, 0x4,0x56,0x6a, + 0x4,0x56,0x6b, 0x4,0x5b,0x67, 0x5,0x68,0x3b, 0x4,0x63,0x65, + 0x4,0x63,0x66, 0x4,0x63,0x67, 0x4,0x63,0x63, 0x4,0x6b,0x6f, + 0x3,0x24,0x2e, 0x4,0x23,0x29, 0x3,0x24,0x30, 0x3,0x24,0x31, + 0x3,0x26,0x71, 0x3,0x26,0x6f, 0x3,0x26,0x70, 0x3,0x2a,0x2e, + 0x3,0x2d,0x76, 0x6,0x2d,0x21, 0x3,0x2a,0x30, 0x4,0x27,0x3b, + 0x3,0x2a,0x31, 0x3,0x2d,0x7d, 0x3,0x32,0x3a, 0x4,0x2a,0x37, + 0x4,0x2a,0x38, 0xf,0x2c,0x32, 0x4,0x33,0x2f, 0x3,0x32,0x43, + 0x3,0x32,0x44, 0x3,0x32,0x3b, 0x4,0x33,0x30, 0x3,0x32,0x45, + 0xf,0x31,0x27, 0x3,0x32,0x42, 0x3,0x37,0x3f, 0x3,0x37,0x42, + 0x3,0x37,0x41, 0x4,0x33,0x33, 0x3,0x37,0x3e, 0x3,0x37,0x43, + 0x3,0x3d,0x34, 0x4,0x38,0x7d, 0x5,0x3a,0x2d, 0x3,0x42,0x63, + 0x3,0x3d,0x31, 0x3,0x3d,0x30, 0x3,0x42,0x6c, 0xf,0x36,0x59, + 0xf,0x3d,0x3b, 0x4,0x3e,0x59, 0x3,0x42,0x65, 0x3,0x42,0x69, + 0x5,0x40,0x4e, 0x3,0x42,0x72, 0xf,0x43,0x49, 0xf,0x43,0x56, + 0x3,0x48,0x24, 0x7,0x25,0x37, 0x4,0x4b,0x22, 0x4,0x4b,0x21, + 0x3,0x4d,0x37, 0x3,0x4d,0x3c, 0x3,0x4d,0x33, 0x3,0x4d,0x38, + 0x3,0x4d,0x34, 0x3,0x4d,0x32, 0x3,0x51,0x68, 0x5,0x55,0x5d, + 0x4,0x51,0x37, 0x3,0x51,0x69, 0x3,0x55,0x4a, 0x4,0x56,0x6f, + 0xf,0x55,0x7a, 0xf,0x56,0x22, 0x3,0x55,0x4e, 0x4,0x5b,0x69, + 0x3,0x55,0x4c, 0xf,0x5b,0x2d, 0x3,0x58,0x31, 0x4,0x60,0x2a, + 0xf,0x62,0x78, 0xf,0x62,0x7b, 0x3,0x5c,0x61, 0x4,0x2a,0x39, + 0x4,0x2a,0x3a, 0x5,0x2e,0x62, 0x4,0x2e,0x2b, 0x4,0x33,0x35, + 0x4,0x33,0x34, 0x4,0x38,0x7e, 0x4,0x44,0x70, 0x4,0x44,0x71, + 0x4,0x44,0x6f, 0x4,0x4b,0x23, 0x4,0x4b,0x24, 0x4,0x5b,0x6c, + 0x4,0x6d,0x5a, 0x4,0x24,0x5e, 0x5,0x27,0x32, 0x3,0x2a,0x34, + 0x3,0x2e,0x23, 0x4,0x2a,0x3d, 0x3,0x32,0x4a, 0x3,0x32,0x4b, + 0x4,0x2e,0x2d, 0x3,0x32,0x49, 0x4,0x2e,0x2c, 0x4,0x33,0x3b, + 0x4,0x39,0x21, 0x4,0x33,0x3a, 0x4,0x33,0x38, 0x4,0x33,0x39, + 0x4,0x33,0x37, 0x4,0x39,0x23, 0x4,0x39,0x26, 0x4,0x33,0x3c, + 0x4,0x39,0x24, 0x4,0x3e,0x62, 0x4,0x3e,0x61, 0x4,0x3e,0x5d, + 0x4,0x3e,0x60, 0x3,0x42,0x76, 0x4,0x3e,0x63, 0x5,0x47,0x48, + 0x4,0x44,0x73, 0x4,0x44,0x76, 0x4,0x44,0x74, 0x4,0x44,0x78, + 0x4,0x44,0x77, 0x4,0x44,0x75, 0x4,0x4b,0x25, 0x4,0x4b,0x27, + 0x4,0x4b,0x26, 0x4,0x51,0x3f, 0x3,0x51,0x6f, 0x4,0x51,0x42, + 0x4,0x51,0x41, 0x4,0x56,0x72, 0x4,0x56,0x73, 0x3,0x55,0x51, + 0x4,0x56,0x75, 0x3,0x55,0x50, 0x4,0x56,0x71, 0x4,0x5b,0x6f, + 0x4,0x5b,0x6e, 0x4,0x60,0x2c, 0x4,0x60,0x2b, 0x4,0x68,0x75, + 0x4,0x6b,0x70, 0x4,0x6a,0x53, 0x3,0x32,0x4c, 0x4,0x3e,0x65, + 0x3,0x4d,0x3f, 0x4,0x56,0x78, 0x3,0x3d,0x40, 0xf,0x50,0x4e, + 0x5,0x24,0x63, 0x6,0x28,0x62, 0x3,0x26,0x72, 0x4,0x2a,0x41, + 0x3,0x2e,0x29, 0x4,0x2a,0x43, 0x4,0x2e,0x2f, 0x4,0x2e,0x31, + 0x5,0x33,0x64, 0x3,0x37,0x48, 0x3,0x3d,0x41, 0x4,0x39,0x28, + 0x4,0x3e,0x69, 0x3,0x42,0x79, 0x3,0x42,0x7a, 0x4,0x3e,0x68, + 0x4,0x44,0x79, 0x3,0x4d,0x40, 0x4,0x4b,0x2a, 0x4,0x4b,0x29, + 0x4,0x51,0x44, 0x5,0x5c,0x2f, 0x4,0x5b,0x72, 0x4,0x5b,0x73, + 0x4,0x60,0x2e, 0x4,0x63,0x69, 0x4,0x6a,0x54, 0x4,0x3e,0x6d, + 0x4,0x24,0x61, 0x4,0x24,0x62, 0x5,0x27,0x37, 0x3,0x2a,0x3c, + 0x4,0x2a,0x46, 0x3,0x2e,0x2d, 0x4,0x2a,0x49, 0x3,0x2e,0x2c, + 0x3,0x2e,0x2e, 0x3,0x32,0x56, 0x4,0x2e,0x37, 0x4,0x2e,0x3b, + 0x4,0x2e,0x35, 0x4,0x2e,0x36, 0x3,0x32,0x54, 0x4,0x2e,0x33, + 0x4,0x2e,0x3f, 0x4,0x2e,0x39, 0x6,0x39,0x6b, 0x3,0x32,0x53, + 0x4,0x2e,0x38, 0x4,0x2e,0x3a, 0x5,0x33,0x6d, 0x4,0x33,0x42, + 0x3,0x37,0x4c, 0x4,0x33,0x40, 0x4,0x2e,0x3c, 0x4,0x33,0x3f, + 0x4,0x33,0x45, 0x3,0x37,0x4b, 0x4,0x33,0x43, 0x4,0x39,0x32, + 0x4,0x39,0x33, 0x3,0x3d,0x46, 0x3,0x3d,0x4b, 0x6,0x4b,0x5a, + 0x3,0x3d,0x49, 0x4,0x39,0x36, 0x5,0x40,0x60, 0x4,0x39,0x2f, + 0x4,0x39,0x30, 0x3,0x3d,0x48, 0x3,0x3d,0x4a, 0x5,0x3a,0x3b, + 0x4,0x39,0x35, 0x4,0x39,0x38, 0x4,0x3e,0x74, 0x5,0x40,0x64, + 0x4,0x3e,0x6f, 0x4,0x3e,0x78, 0x4,0x3e,0x6e, 0x4,0x3e,0x76, + 0x4,0x3e,0x73, 0x4,0x3e,0x7a, 0x4,0x45,0x24, 0x4,0x45,0x28, + 0x6,0x5f,0x2d, 0x3,0x48,0x2a, 0x3,0x48,0x2c, 0x4,0x45,0x23, + 0x4,0x45,0x21, 0x7,0x25,0x58, 0x4,0x4b,0x38, 0x3,0x4d,0x42, + 0x4,0x4b,0x37, 0x4,0x4b,0x35, 0x4,0x4b,0x33, 0x4,0x4b,0x2f, + 0x7,0x25,0x5c, 0x4,0x4b,0x2e, 0x5,0x47,0x59, 0x4,0x4b,0x3b, + 0x7,0x30,0x36, 0x4,0x51,0x48, 0x4,0x51,0x49, 0x3,0x51,0x75, + 0x4,0x51,0x4e, 0x4,0x51,0x4a, 0x4,0x51,0x50, 0x4,0x57,0x26, + 0x4,0x57,0x22, 0x4,0x5b,0x7b, 0x4,0x5b,0x77, 0x7,0x40,0x6b, + 0x4,0x57,0x25, 0x7,0x40,0x67, 0x4,0x60,0x32, 0x4,0x60,0x2f, + 0x4,0x60,0x30, 0x4,0x66,0x58, 0x4,0x66,0x59, 0x3,0x5e,0x40, + 0x5,0x73,0x5c, 0x4,0x6a,0x55, 0x4,0x6b,0x72, 0x4,0x6b,0x71, + 0x3,0x62,0x2d, 0x3,0x26,0x75, 0x3,0x2e,0x30, 0x3,0x32,0x58, + 0x3,0x37,0x4e, 0x3,0x43,0x22, 0x3,0x48,0x2d, 0x5,0x47,0x5b, + 0x5,0x4e,0x59, 0x4,0x51,0x56, 0x4,0x60,0x37, 0x4,0x66,0x5b, + 0x4,0x6c,0x73, 0x4,0x27,0x46, 0x4,0x2a,0x4e, 0x3,0x2e,0x31, + 0x4,0x2e,0x46, 0x4,0x2e,0x45, 0x4,0x33,0x47, 0x4,0x33,0x48, + 0x4,0x39,0x3a, 0x6,0x55,0x52, 0x4,0x45,0x30, 0x4,0x45,0x32, + 0x3,0x48,0x2f, 0x3,0x4d,0x43, 0x4,0x4b,0x3d, 0x4,0x51,0x57, + 0x4,0x5b,0x7e, 0x4,0x63,0x6c, 0x4,0x27,0x48, 0x4,0x2a,0x51, + 0x4,0x2a,0x50, 0x4,0x2e,0x47, 0x4,0x2e,0x49, 0x3,0x32,0x59, + 0x4,0x33,0x4b, 0x3,0x37,0x4f, 0x3,0x3d,0x4e, 0x3,0x43,0x23, + 0x5,0x40,0x6f, 0x3,0x48,0x32, 0x4,0x51,0x5a, 0x4,0x45,0x36, + 0x4,0x57,0x2c, 0x4,0x60,0x38, 0x3,0x5f,0x38, 0x4,0x6e,0x48, + 0x3,0x26,0x79, 0x4,0x24,0x65, 0x4,0x27,0x4e, 0x4,0x27,0x4f, + 0x4,0x27,0x4d, 0x4,0x27,0x4c, 0x4,0x27,0x4a, 0x4,0x2a,0x53, + 0x4,0x2a,0x56, 0x4,0x2a,0x57, 0x4,0x2a,0x54, 0x4,0x2a,0x58, + 0x5,0x2a,0x6d, 0x4,0x2a,0x5a, 0x6,0x33,0x38, 0x3,0x2e,0x34, + 0x4,0x2e,0x52, 0x3,0x32,0x5d, 0x3,0x32,0x66, 0x3,0x32,0x60, + 0x4,0x2e,0x4d, 0x3,0x32,0x61, 0x5,0x33,0x76, 0x4,0x33,0x50, + 0x4,0x33,0x51, 0x3,0x37,0x56, 0x3,0x37,0x54, 0x4,0x33,0x52, + 0x4,0x33,0x4e, 0x4,0x33,0x4d, 0x3,0x3d,0x50, 0x4,0x39,0x49, + 0x3,0x3d,0x54, 0x4,0x39,0x4a, 0x3,0x3d,0x55, 0x4,0x39,0x45, + 0x4,0x39,0x48, 0x4,0x39,0x3f, 0x4,0x39,0x41, 0x4,0x39,0x4b, + 0x4,0x39,0x46, 0x4,0x39,0x4d, 0x4,0x39,0x47, 0x4,0x39,0x43, + 0x4,0x3f,0x22, 0x4,0x39,0x4c, 0x4,0x39,0x42, 0x4,0x3f,0x30, + 0x4,0x3f,0x2d, 0x3,0x43,0x24, 0x4,0x3f,0x25, 0x4,0x3f,0x26, + 0x4,0x3f,0x27, 0x4,0x3f,0x2b, 0x4,0x3f,0x2c, 0x6,0x55,0x61, + 0x5,0x47,0x61, 0x4,0x45,0x39, 0x4,0x45,0x41, 0x4,0x45,0x3c, + 0x4,0x45,0x37, 0x3,0x48,0x37, 0x4,0x45,0x43, 0x4,0x45,0x46, + 0x4,0x45,0x3f, 0x4,0x45,0x44, 0x3,0x48,0x3a, 0x4,0x45,0x38, + 0x3,0x4d,0x45, 0x4,0x4b,0x45, 0x4,0x4b,0x42, 0x4,0x4b,0x44, + 0x4,0x4b,0x47, 0x4,0x4b,0x43, 0x4,0x4b,0x4d, 0x3,0x4d,0x47, + 0x5,0x4e,0x60, 0x4,0x4b,0x3f, 0x3,0x51,0x77, 0x3,0x51,0x78, + 0x4,0x51,0x5c, 0x4,0x51,0x60, 0x3,0x51,0x7c, 0x3,0x51,0x7a, + 0x4,0x51,0x5d, 0x4,0x51,0x64, 0x4,0x57,0x32, 0x4,0x57,0x2e, + 0x4,0x57,0x31, 0x4,0x57,0x2f, 0x3,0x55,0x5a, 0x4,0x57,0x30, + 0x4,0x57,0x33, 0x4,0x57,0x34, 0x5,0x56,0x22, 0x5,0x62,0x69, + 0x4,0x5c,0x27, 0x4,0x5c,0x29, 0x4,0x5c,0x2a, 0x4,0x5c,0x25, + 0x3,0x58,0x37, 0x4,0x5c,0x26, 0x4,0x63,0x70, 0x4,0x63,0x6e, + 0x4,0x63,0x71, 0x4,0x63,0x6f, 0x4,0x66,0x5d, 0x3,0x5e,0x41, + 0x4,0x68,0x78, 0x4,0x6a,0x57, 0x4,0x68,0x7a, 0x4,0x6c,0x75, + 0x4,0x6e,0x4d, 0x4,0x27,0x51, 0x4,0x2a,0x5f, 0x4,0x33,0x57, + 0x4,0x45,0x4a, 0x3,0x55,0x5d, 0x4,0x57,0x38, 0x4,0x63,0x74, + 0x4,0x6b,0x75, 0x4,0x2e,0x57, 0x4,0x2e,0x58, 0x4,0x33,0x5a, + 0x4,0x33,0x59, 0x6,0x4c,0x2b, 0x4,0x3f,0x33, 0x4,0x45,0x4c, + 0x3,0x24,0x32, 0x3,0x26,0x7a, 0x4,0x27,0x53, 0xf,0x28,0x7a, + 0x4,0x2a,0x64, 0x3,0x2e,0x38, 0x4,0x2a,0x62, 0x3,0x2e,0x3c, + 0x3,0x2d,0x3b, 0x4,0x2e,0x5f, 0x4,0x2e,0x5c, 0x4,0x2e,0x62, + 0x5,0x2f,0x34, 0x3,0x37,0x5b, 0x3,0x32,0x6a, 0x3,0x32,0x6b, + 0x4,0x2e,0x5e, 0x4,0x2e,0x61, 0x4,0x33,0x5e, 0x4,0x33,0x61, + 0x3,0x37,0x5c, 0x4,0x33,0x5f, 0x3,0x37,0x5a, 0x4,0x33,0x60, + 0x3,0x37,0x5e, 0x3,0x3d,0x5b, 0x5,0x3a,0x59, 0x6,0x4c,0x33, + 0x4,0x39,0x58, 0x3,0x3d,0x58, 0x4,0x39,0x53, 0x4,0x3f,0x40, + 0x4,0x3f,0x39, 0x4,0x3f,0x3f, 0x3,0x43,0x2f, 0x4,0x3f,0x3c, + 0x3,0x43,0x32, 0x4,0x3f,0x3d, 0x3,0x43,0x2c, 0x4,0x3f,0x3e, + 0x4,0x3f,0x38, 0x4,0x3f,0x3a, 0x4,0x3f,0x3b, 0x4,0x3f,0x42, + 0x4,0x45,0x4e, 0x3,0x48,0x43, 0x4,0x45,0x51, 0x3,0x48,0x41, + 0x4,0x45,0x4d, 0x4,0x45,0x55, 0x4,0x45,0x4f, 0x5,0x47,0x76, + 0x4,0x4b,0x5c, 0x4,0x4b,0x58, 0x4,0x4b,0x56, 0x4,0x4b,0x55, + 0x4,0x4b,0x5e, 0x7,0x26,0x24, 0x4,0x4b,0x5b, 0x3,0x52,0x23, + 0x3,0x51,0x7d, 0x4,0x51,0x6c, 0x3,0x51,0x7e, 0x7,0x30,0x59, + 0x5,0x56,0x33, 0x4,0x51,0x70, 0x4,0x51,0x6d, 0x4,0x57,0x3b, + 0x4,0x57,0x41, 0x3,0x48,0x42, 0x4,0x57,0x39, 0x3,0x55,0x5e, + 0x3,0x55,0x5f, 0x4,0x57,0x3f, 0x3,0x58,0x41, 0x4,0x5c,0x2d, + 0x3,0x58,0x3d, 0x4,0x5c,0x31, 0x4,0x5c,0x2f, 0x4,0x5c,0x2e, + 0x4,0x60,0x3f, 0x7,0x4e,0x5c, 0x3,0x5c,0x63, 0x4,0x63,0x76, + 0x4,0x63,0x75, 0x4,0x66,0x5f, 0x4,0x66,0x60, 0x4,0x66,0x61, + 0x4,0x68,0x7c, 0x4,0x68,0x7b, 0x3,0x60,0x75, 0x3,0x61,0x67, + 0x3,0x2e,0x3f, 0x4,0x2a,0x67, 0x4,0x2a,0x66, 0x6,0x33,0x48, + 0x3,0x32,0x6e, 0x4,0x2e,0x64, 0x3,0x32,0x71, 0x3,0x37,0x64, + 0x4,0x33,0x63, 0x4,0x33,0x62, 0x3,0x3d,0x61, 0x3,0x3d,0x60, + 0x4,0x39,0x59, 0x4,0x3f,0x45, 0x4,0x3f,0x44, 0x3,0x43,0x3a, + 0x3,0x43,0x3b, 0x3,0x43,0x3e, 0x4,0x3f,0x47, 0x3,0x43,0x3c, + 0x3,0x43,0x3f, 0x3,0x48,0x46, 0x5,0x48,0x24, 0x3,0x48,0x49, + 0x5,0x4e,0x76, 0x3,0x4d,0x4e, 0x4,0x51,0x76, 0x3,0x52,0x25, + 0x4,0x51,0x74, 0x4,0x51,0x75, 0x4,0x57,0x42, 0x3,0x58,0x46, + 0x3,0x58,0x47, 0x3,0x5a,0x64, 0x4,0x66,0x63, 0x3,0x62,0x34, + 0x5,0x24,0x6e, 0x3,0x26,0x7d, 0x5,0x27,0x46, 0x6,0x2d,0x49, + 0x4,0x27,0x56, 0x3,0x2a,0x40, 0x3,0x2a,0x41, 0x3,0x2a,0x43, + 0x4,0x2a,0x6a, 0x4,0x2a,0x6f, 0x4,0x2a,0x6b, 0x4,0x2a,0x69, + 0x4,0x2a,0x6c, 0xf,0x2c,0x6d, 0x4,0x2e,0x65, 0x3,0x32,0x75, + 0x3,0x32,0x7a, 0x6,0x42,0x66, 0x4,0x33,0x67, 0x4,0x33,0x66, + 0x3,0x37,0x6d, 0x4,0x33,0x65, 0x5,0x34,0x3b, 0x5,0x34,0x39, + 0x4,0x33,0x6a, 0x4,0x33,0x69, 0x4,0x33,0x6b, 0x3,0x37,0x68, + 0x4,0x33,0x6d, 0x5,0x34,0x38, 0x3,0x37,0x6e, 0xf,0x37,0x3b, + 0x4,0x33,0x64, 0x5,0x3a,0x65, 0x4,0x39,0x5e, 0x4,0x39,0x62, + 0x3,0x3d,0x67, 0x4,0x39,0x64, 0x3,0x3d,0x6a, 0x4,0x39,0x63, + 0x3,0x3d,0x6b, 0x4,0x39,0x61, 0x4,0x3f,0x4f, 0x3,0x43,0x40, + 0x4,0x3f,0x4d, 0x3,0x43,0x45, 0x4,0x3f,0x4c, 0x3,0x43,0x42, + 0x4,0x3f,0x4b, 0x3,0x43,0x43, 0x4,0x45,0x57, 0x4,0x3f,0x49, + 0x5,0x41,0x31, 0x3,0x48,0x51, 0x3,0x48,0x4a, 0x4,0x45,0x5b, + 0x3,0x48,0x53, 0x3,0x48,0x4e, 0x4,0x45,0x5a, 0x3,0x48,0x4c, + 0x4,0x45,0x58, 0x6,0x5f,0x6b, 0x4,0x45,0x59, 0x4,0x4b,0x65, + 0x4,0x4b,0x61, 0x3,0x4d,0x54, 0x4,0x4b,0x62, 0x3,0x4d,0x52, + 0x7,0x26,0x32, 0x3,0x4d,0x58, 0x4,0x4b,0x68, 0x4,0x4b,0x66, + 0x4,0x4b,0x64, 0x3,0x4d,0x59, 0x4,0x51,0x7d, 0x4,0x51,0x7c, + 0x3,0x52,0x2b, 0x4,0x51,0x79, 0x4,0x51,0x78, 0x4,0x51,0x7a, + 0x3,0x52,0x2d, 0x4,0x57,0x45, 0x3,0x55,0x63, 0x4,0x57,0x47, + 0x3,0x58,0x48, 0x7,0x41,0x2e, 0x4,0x5c,0x37, 0x4,0x5c,0x35, + 0x4,0x5c,0x36, 0x3,0x5e,0x46, 0x4,0x63,0x79, 0x4,0x66,0x65, + 0x7,0x58,0x4c, 0x4,0x66,0x64, 0x4,0x68,0x7e, 0x4,0x69,0x21, + 0x3,0x62,0x39, 0x4,0x24,0x69, 0x6,0x2d,0x4e, 0x3,0x2e,0x46, + 0x3,0x2e,0x45, 0x4,0x2a,0x71, 0x4,0x2a,0x72, 0x3,0x33,0x21, + 0x3,0x32,0x7e, 0x3,0x32,0x7d, 0x4,0x33,0x6f, 0x4,0x33,0x70, + 0x3,0x37,0x6f, 0x5,0x34,0x45, 0x4,0x33,0x72, 0x4,0x33,0x71, + 0x6,0x42,0x6f, 0x3,0x3d,0x6c, 0x4,0x39,0x67, 0x3,0x3d,0x6d, + 0x6,0x4c,0x53, 0x3,0x3d,0x6e, 0x5,0x41,0x39, 0x4,0x3f,0x53, + 0x4,0x3f,0x52, 0x6,0x56,0x27, 0x4,0x45,0x60, 0x6,0x5f,0x78, + 0x4,0x4b,0x6c, 0x5,0x4f,0x23, 0x5,0x54,0x24, 0x4,0x52,0x25, + 0x4,0x52,0x22, 0x4,0x52,0x24, 0x7,0x30,0x6f, 0x3,0x55,0x65, + 0x3,0x55,0x66, 0x4,0x57,0x4c, 0x4,0x57,0x4d, 0x4,0x57,0x4b, + 0x4,0x57,0x4f, 0x3,0x55,0x67, 0x4,0x5c,0x39, 0x4,0x5c,0x3a, + 0x4,0x60,0x48, 0x4,0x60,0x49, 0x4,0x63,0x7c, 0x4,0x69,0x22, + 0x3,0x24,0x34, 0x3,0x2a,0x46, 0x4,0x2a,0x76, 0x3,0x2e,0x4a, + 0x3,0x33,0x25, 0x4,0x2e,0x6d, 0x3,0x33,0x22, 0x5,0x34,0x46, + 0x3,0x3d,0x6f, 0x4,0x39,0x6a, 0x3,0x43,0x48, 0x4,0x3f,0x54, + 0x4,0x3f,0x55, 0x4,0x3f,0x5a, 0x4,0x45,0x63, 0x4,0x57,0x52, + 0x4,0x5c,0x3b, 0x3,0x5a,0x68, 0x5,0x2b,0x21, 0x4,0x2e,0x75, + 0x4,0x2e,0x70, 0x3,0x33,0x28, 0x4,0x2e,0x77, 0x3,0x33,0x29, + 0x4,0x2e,0x73, 0x4,0x2e,0x72, 0x4,0x33,0x76, 0x4,0x33,0x7d, + 0x3,0x37,0x74, 0x5,0x34,0x48, 0x4,0x33,0x77, 0x4,0x33,0x7b, + 0x3,0x37,0x75, 0x6,0x42,0x76, 0x4,0x33,0x78, 0x4,0x39,0x6d, + 0x4,0x39,0x74, 0x4,0x39,0x71, 0x3,0x3d,0x74, 0x4,0x3f,0x5b, + 0x4,0x39,0x72, 0x3,0x3d,0x7a, 0x4,0x39,0x75, 0x3,0x3d,0x73, + 0x4,0x39,0x6f, 0x6,0x4c,0x5b, 0x6,0x4c,0x56, 0x3,0x43,0x50, + 0x4,0x3f,0x66, 0x4,0x3f,0x62, 0x4,0x3f,0x61, 0x3,0x43,0x52, + 0x3,0x43,0x53, 0x4,0x3f,0x5d, 0x3,0x43,0x4e, 0x4,0x3f,0x60, + 0x3,0x43,0x4b, 0x4,0x3f,0x63, 0x5,0x48,0x46, 0x4,0x39,0x76, + 0x4,0x45,0x65, 0x3,0x48,0x5b, 0x4,0x45,0x6a, 0x4,0x45,0x69, + 0x3,0x48,0x5f, 0x4,0x45,0x6e, 0x4,0x45,0x68, 0x3,0x48,0x59, + 0x4,0x45,0x6d, 0x4,0x45,0x66, 0x5,0x48,0x36, 0x4,0x4b,0x7b, + 0x4,0x4b,0x75, 0x4,0x4b,0x70, 0x3,0x4d,0x61, 0x3,0x4d,0x5e, + 0x4,0x4c,0x22, 0x3,0x4d,0x67, 0x4,0x4b,0x7e, 0x3,0x4d,0x62, + 0x4,0x4c,0x2e, 0x5,0x4f,0x3b, 0x3,0x4d,0x64, 0x4,0x4c,0x30, + 0x4,0x4c,0x25, 0x4,0x4c,0x2d, 0x4,0x4b,0x79, 0x5,0x4f,0x32, + 0x3,0x4d,0x5f, 0x5,0x4f,0x45, 0x4,0x4c,0x2c, 0x4,0x4c,0x27, + 0x4,0x4b,0x77, 0x3,0x4d,0x66, 0x3,0x4d,0x68, 0x4,0x4c,0x28, + 0x5,0x4f,0x36, 0x4,0x52,0x34, 0x4,0x52,0x3a, 0x3,0x52,0x31, + 0x4,0x52,0x37, 0x4,0x52,0x2b, 0x4,0x52,0x38, 0x3,0x52,0x35, + 0x4,0x52,0x39, 0x4,0x52,0x3b, 0x4,0x52,0x36, 0x4,0x52,0x2f, + 0x4,0x52,0x3d, 0x4,0x52,0x29, 0x3,0x52,0x32, 0x4,0x57,0x5b, + 0x5,0x5c,0x6d, 0x4,0x57,0x5e, 0x4,0x57,0x5a, 0x4,0x57,0x62, + 0x5,0x5c,0x7d, 0x4,0x57,0x65, 0x4,0x57,0x53, 0x3,0x55,0x6c, + 0x4,0x57,0x56, 0x4,0x57,0x58, 0x4,0x57,0x59, 0x5,0x5c,0x7e, + 0x4,0x57,0x55, 0x5,0x5d,0x30, 0x4,0x5c,0x44, 0x4,0x5c,0x4f, + 0x4,0x5c,0x4b, 0x4,0x5c,0x50, 0x4,0x5c,0x43, 0x3,0x58,0x4a, + 0x4,0x5c,0x4a, 0x3,0x5a,0x6c, 0x4,0x5c,0x42, 0x4,0x5c,0x4c, + 0x7,0x41,0x3f, 0x4,0x5c,0x46, 0x4,0x5c,0x49, 0x4,0x5c,0x40, + 0x5,0x63,0x34, 0x4,0x5c,0x48, 0x3,0x58,0x4d, 0x3,0x58,0x4b, + 0x5,0x63,0x41, 0x4,0x60,0x56, 0x5,0x68,0x6e, 0x3,0x5a,0x6a, + 0x4,0x60,0x53, 0x5,0x68,0x66, 0x3,0x5a,0x6d, 0x3,0x5a,0x69, + 0x3,0x5a,0x6b, 0x4,0x5c,0x51, 0x4,0x63,0x7e, 0x4,0x66,0x69, + 0x4,0x66,0x6c, 0x4,0x66,0x6e, 0x3,0x5e,0x4a, 0x4,0x66,0x6a, + 0x3,0x5e,0x4d, 0x4,0x66,0x68, 0x4,0x66,0x6d, 0x3,0x5f,0x56, + 0x5,0x70,0x61, 0x4,0x69,0x26, 0x4,0x69,0x28, 0x4,0x6a,0x5d, + 0x4,0x6a,0x61, 0x4,0x6a,0x5c, 0x3,0x60,0x5f, 0x4,0x6b,0x76, + 0x4,0x6d,0x5c, 0x4,0x6d,0x76, 0x7,0x65,0x5d, 0x4,0x2a,0x77, + 0x3,0x33,0x2f, 0x3,0x33,0x33, 0x6,0x43,0x22, 0x4,0x34,0x25, + 0x5,0x34,0x59, 0x3,0x37,0x7c, 0x6,0x4c,0x60, 0x4,0x39,0x7b, + 0x4,0x39,0x7c, 0x3,0x3d,0x7d, 0x3,0x3d,0x7c, 0x4,0x39,0x7d, + 0x3,0x43,0x5a, 0x3,0x43,0x56, 0x3,0x43,0x57, 0x3,0x43,0x59, + 0x3,0x43,0x5b, 0x3,0x48,0x63, 0x4,0x45,0x72, 0x3,0x48,0x64, + 0x3,0x48,0x65, 0x6,0x60,0x2c, 0x3,0x48,0x66, 0x3,0x4d,0x6b, + 0x3,0x4d,0x6c, 0x3,0x4d,0x69, 0x3,0x4d,0x6a, 0x4,0x4c,0x37, + 0x7,0x26,0x57, 0x4,0x4c,0x35, 0x3,0x52,0x36, 0x4,0x57,0x6d, + 0x3,0x55,0x73, 0x3,0x55,0x72, 0x4,0x57,0x69, 0x4,0x57,0x6a, + 0x3,0x4d,0x74, 0x4,0x57,0x6b, 0x5,0x63,0x4e, 0x4,0x5c,0x56, + 0x3,0x58,0x52, 0x4,0x5c,0x55, 0x4,0x5c,0x54, 0x5,0x63,0x54, + 0x3,0x58,0x53, 0x3,0x5a,0x70, 0x4,0x60,0x5b, 0x4,0x60,0x5d, + 0x4,0x64,0x23, 0x3,0x5c,0x68, 0x7,0x54,0x3a, 0x5,0x70,0x70, + 0x4,0x6a,0x65, 0x5,0x76,0x39, 0x4,0x6c,0x7a, 0x3,0x61,0x45, + 0x4,0x27,0x5c, 0x6,0x33,0x64, 0x3,0x2e,0x57, 0x3,0x2e,0x55, + 0x3,0x2e,0x58, 0x4,0x2e,0x78, 0x4,0x2e,0x7e, 0x3,0x33,0x35, + 0x3,0x33,0x34, 0x4,0x2e,0x7c, 0x3,0x33,0x39, 0x4,0x2f,0x21, + 0x3,0x33,0x38, 0x4,0x2e,0x7d, 0x3,0x33,0x36, 0x3,0x33,0x3a, + 0x4,0x34,0x2e, 0x4,0x34,0x26, 0x3,0x38,0x23, 0x3,0x38,0x2a, + 0x4,0x34,0x27, 0x4,0x34,0x30, 0x3,0x38,0x2c, 0x4,0x34,0x2d, + 0x4,0x34,0x2b, 0x4,0x34,0x29, 0x3,0x38,0x28, 0x3,0x38,0x2d, + 0x3,0x38,0x25, 0x3,0x3e,0x36, 0x5,0x3b,0x2c, 0x3,0x3e,0x2d, + 0x3,0x3e,0x32, 0x3,0x3e,0x27, 0x3,0x3e,0x30, 0x3,0x3e,0x25, + 0x6,0x4c,0x71, 0x3,0x3e,0x31, 0x4,0x3f,0x6a, 0x3,0x43,0x65, + 0x3,0x43,0x6b, 0x4,0x3f,0x6e, 0x4,0x3f,0x73, 0x4,0x3f,0x6f, + 0x3,0x43,0x61, 0x3,0x43,0x5d, 0x3,0x48,0x6c, 0x4,0x45,0x75, + 0x4,0x45,0x7e, 0x4,0x45,0x79, 0x4,0x46,0x21, 0x3,0x48,0x67, + 0x3,0x43,0x5f, 0x3,0x48,0x72, 0x3,0x48,0x75, 0x4,0x46,0x23, + 0x5,0x48,0x54, 0x3,0x48,0x6f, 0x3,0x4e,0x2a, 0x5,0x4f,0x53, + 0x4,0x4c,0x3e, 0x4,0x4c,0x3c, 0x4,0x4c,0x40, 0x3,0x4d,0x7b, + 0x3,0x4e,0x21, 0x3,0x4e,0x2d, 0x3,0x4d,0x76, 0x3,0x4d,0x79, + 0x4,0x4c,0x3a, 0x4,0x4c,0x3d, 0x4,0x4c,0x3f, 0x3,0x4d,0x7a, + 0x4,0x4c,0x44, 0x5,0x4f,0x54, 0x3,0x4e,0x26, 0x3,0x4e,0x23, + 0x3,0x52,0x3a, 0x4,0x52,0x49, 0x3,0x52,0x3c, 0x4,0x52,0x47, + 0x3,0x52,0x3d, 0x3,0x52,0x3e, 0x4,0x57,0x73, 0x3,0x55,0x78, + 0x5,0x5d,0x3f, 0x3,0x55,0x76, 0x5,0x5d,0x46, 0x3,0x55,0x77, + 0x4,0x57,0x6e, 0x3,0x55,0x7c, 0x3,0x55,0x7b, 0x7,0x3a,0x39, + 0x4,0x5c,0x62, 0x4,0x5c,0x60, 0x4,0x57,0x72, 0x3,0x58,0x57, + 0x3,0x58,0x56, 0x3,0x59,0x29, 0x4,0x60,0x66, 0x4,0x60,0x63, + 0x4,0x60,0x68, 0x4,0x60,0x62, 0x7,0x47,0x4a, 0x3,0x5a,0x73, + 0x3,0x5a,0x71, 0x5,0x6d,0x22, 0x3,0x5c,0x69, 0x4,0x64,0x24, + 0x3,0x5c,0x6a, 0x3,0x5c,0x6b, 0x3,0x5e,0x4f, 0x3,0x5e,0x4e, + 0x4,0x69,0x2a, 0x7,0x58,0x58, 0x3,0x5f,0x59, 0x4,0x69,0x2b, + 0x4,0x6a,0x66, 0x4,0x6b,0x79, 0x4,0x6b,0x78, 0x7,0x5f,0x33, + 0x3,0x60,0x78, 0x4,0x6c,0x7c, 0x4,0x6c,0x7b, 0x4,0x6d,0x77, + 0x4,0x2a,0x79, 0x4,0x2f,0x29, 0x3,0x38,0x2f, 0x3,0x38,0x32, + 0x5,0x34,0x60, 0x4,0x34,0x34, 0x3,0x38,0x30, 0x4,0x34,0x33, + 0x4,0x3a,0x28, 0x4,0x46,0x25, 0x3,0x48,0x76, 0x4,0x52,0x4e, + 0x4,0x6a,0x6b, 0xf,0x21,0x47, 0x3,0x2a,0x4d, 0x3,0x2e,0x5c, + 0x3,0x2e,0x5b, 0x3,0x2e,0x59, 0x4,0x2a,0x7b, 0x4,0x2f,0x2a, + 0x6,0x3a,0x6b, 0x4,0x2f,0x2d, 0x4,0x34,0x35, 0x4,0x3f,0x75, + 0x4,0x3a,0x2a, 0x3,0x43,0x6c, 0x3,0x43,0x6d, 0x5,0x41,0x65, + 0x3,0x48,0x7a, 0x3,0x48,0x7b, 0x4,0x52,0x4f, 0x4,0x57,0x75, + 0x4,0x5c,0x65, 0x4,0x60,0x6d, 0x4,0x66,0x7b, 0x4,0x6b,0x7b, + 0x6,0x3a,0x74, 0x4,0x2f,0x2e, 0x3,0x31,0x3f, 0x4,0x34,0x38, + 0x4,0x34,0x36, 0x4,0x34,0x37, 0x6,0x43,0x3c, 0x4,0x3a,0x2d, + 0x4,0x3a,0x31, 0x4,0x3a,0x30, 0x4,0x3f,0x76, 0x3,0x48,0x7e, + 0x4,0x46,0x27, 0x3,0x48,0x7d, 0x4,0x46,0x28, 0x3,0x48,0x7c, + 0x4,0x4c,0x49, 0x4,0x52,0x53, 0x3,0x52,0x41, 0x4,0x57,0x77, + 0x4,0x5c,0x6a, 0x4,0x5c,0x6b, 0x4,0x69,0x2c, 0x3,0x33,0x40, + 0x3,0x33,0x41, 0x4,0x34,0x3a, 0x3,0x38,0x33, 0x4,0x34,0x3b, + 0x4,0x34,0x3e, 0x4,0x34,0x3c, 0x3,0x38,0x35, 0x3,0x38,0x34, + 0x4,0x3a,0x34, 0x4,0x3a,0x35, 0x5,0x3b,0x3a, 0x4,0x3a,0x33, + 0x3,0x43,0x70, 0x4,0x3f,0x78, 0x3,0x43,0x71, 0x4,0x3f,0x77, + 0x3,0x43,0x6f, 0x3,0x49,0x21, 0x4,0x46,0x2a, 0x4,0x46,0x29, + 0x4,0x46,0x2b, 0x4,0x52,0x55, 0x4,0x52,0x56, 0x3,0x58,0x5e, + 0x3,0x58,0x60, 0x3,0x58,0x5f, 0x3,0x5c,0x6e, 0x4,0x66,0x7d, + 0x3,0x3e,0x39, 0x3,0x3e,0x3a, 0x4,0x2b,0x27, 0x4,0x2b,0x28, + 0x4,0x2f,0x38, 0x4,0x2b,0x29, 0x3,0x38,0x38, 0x4,0x3f,0x7a, + 0x4,0x46,0x2e, 0x4,0x46,0x2d, 0x4,0x46,0x2f, 0x4,0x46,0x32, + 0x4,0x46,0x30, 0x4,0x4c,0x4f, 0x4,0x57,0x7d, 0x4,0x57,0x7a, + 0x4,0x57,0x7b, 0x4,0x5c,0x70, 0x4,0x67,0x21, 0x4,0x24,0x6d, + 0x3,0x33,0x46, 0x3,0x33,0x45, 0x3,0x38,0x3a, 0x4,0x34,0x41, + 0x4,0x3a,0x39, 0x5,0x41,0x70, 0x3,0x43,0x74, 0x4,0x46,0x36, + 0x4,0x46,0x34, 0x4,0x46,0x35, 0x4,0x46,0x37, 0x3,0x49,0x24, + 0x3,0x4e,0x33, 0x4,0x4c,0x52, 0x4,0x52,0x5a, 0x3,0x52,0x42, + 0x4,0x52,0x5b, 0x4,0x58,0x21, 0x4,0x58,0x24, 0x4,0x58,0x23, + 0x4,0x58,0x22, 0x3,0x58,0x64, 0x4,0x64,0x28, 0x3,0x5f,0x5c, + 0x6,0x56,0x6d, 0x4,0x23,0x2d, 0x6,0x25,0x49, 0x4,0x24,0x6f, + 0x4,0x24,0x6e, 0x3,0x2a,0x51, 0x6,0x3b,0x28, 0x3,0x2a,0x55, + 0x3,0x2a,0x50, 0x4,0x27,0x66, 0xf,0x28,0x52, 0x4,0x27,0x62, + 0x4,0x27,0x67, 0x4,0x27,0x63, 0x4,0x27,0x65, 0x5,0x27,0x58, + 0x3,0x2a,0x5a, 0x3,0x2a,0x53, 0x5,0x2b,0x33, 0x4,0x2b,0x2f, + 0x4,0x2b,0x2a, 0x4,0x2b,0x2c, 0x3,0x2e,0x62, 0x3,0x2e,0x5f, + 0x6,0x33,0x7d, 0x5,0x2b,0x39, 0x3,0x33,0x51, 0x4,0x2f,0x41, + 0x4,0x2f,0x46, 0x4,0x2f,0x47, 0x4,0x2f,0x3f, 0x6,0x3b,0x31, + 0x5,0x2f,0x6d, 0x3,0x38,0x46, 0x4,0x34,0x4c, 0x4,0x34,0x48, + 0x3,0x38,0x44, 0x4,0x34,0x4b, 0x4,0x34,0x52, 0x4,0x34,0x51, + 0x4,0x34,0x4a, 0x4,0x34,0x53, 0x6,0x43,0x58, 0x3,0x38,0x40, + 0x3,0x38,0x3f, 0x3,0x38,0x43, 0x4,0x3a,0x49, 0x4,0x3a,0x3a, + 0x3,0x3e,0x3f, 0x4,0x3a,0x45, 0x5,0x3b,0x4d, 0x4,0x3a,0x4a, + 0x4,0x3a,0x41, 0x4,0x3a,0x40, 0x4,0x3a,0x42, 0x4,0x3a,0x3d, + 0x3,0x3e,0x46, 0x4,0x3a,0x3f, 0x4,0x3a,0x44, 0x4,0x3a,0x4b, + 0x6,0x49,0x7e, 0x6,0x4d,0x54, 0x6,0x56,0x76, 0x4,0x40,0x27, + 0x3,0x43,0x78, 0x4,0x40,0x2a, 0x4,0x40,0x23, 0x4,0x40,0x26, + 0x3,0x43,0x7a, 0x4,0x3f,0x7d, 0x4,0x40,0x28, 0x3,0x44,0x21, + 0x4,0x40,0x2c, 0x3,0x43,0x7d, 0x3,0x43,0x79, 0x5,0x34,0x6a, + 0x4,0x40,0x25, 0x4,0x46,0x45, 0x4,0x46,0x3e, 0x4,0x46,0x3c, + 0x4,0x46,0x3d, 0x4,0x46,0x3f, 0x3,0x52,0x48, 0x4,0x46,0x42, + 0x4,0x46,0x40, 0x4,0x46,0x3b, 0x3,0x49,0x29, 0x3,0x49,0x28, + 0x4,0x46,0x38, 0x4,0x46,0x47, 0x4,0x46,0x41, 0x4,0x4c,0x5d, + 0x4,0x4c,0x58, 0x4,0x4c,0x5e, 0x4,0x4c,0x55, 0x4,0x4c,0x5c, + 0x6,0x60,0x6f, 0x4,0x4c,0x54, 0x4,0x4c,0x5b, 0x4,0x4c,0x5f, + 0x5,0x42,0x28, 0x4,0x52,0x63, 0x4,0x52,0x64, 0x3,0x52,0x46, + 0x3,0x52,0x45, 0x4,0x52,0x5e, 0x4,0x52,0x61, 0x4,0x52,0x62, + 0x4,0x52,0x66, 0xf,0x51,0x55, 0x5,0x5d,0x5b, 0x4,0x58,0x2b, + 0x4,0x58,0x28, 0x4,0x58,0x2c, 0x4,0x5c,0x74, 0x3,0x58,0x66, + 0x4,0x5c,0x76, 0x3,0x58,0x67, 0x3,0x5a,0x76, 0x4,0x60,0x74, + 0x4,0x60,0x73, 0x5,0x6d,0x2c, 0x4,0x64,0x2a, 0x4,0x67,0x22, + 0x4,0x67,0x24, 0x4,0x67,0x23, 0x4,0x67,0x25, 0x4,0x69,0x30, + 0x6,0x43,0x64, 0x7,0x42,0x24, 0x3,0x2b,0x44, 0x3,0x44,0x24, + 0x4,0x2f,0x4a, 0x4,0x34,0x58, 0x4,0x4c,0x63, 0x4,0x52,0x6b, + 0x3,0x33,0x53, 0x3,0x33,0x54, 0x3,0x38,0x4a, 0x4,0x4c,0x64, + 0x6,0x61,0x21, 0x3,0x52,0x4b, 0x3,0x5e,0x54, 0x4,0x27,0x6f, + 0x4,0x2b,0x33, 0x4,0x2b,0x32, 0x3,0x2e,0x67, 0x3,0x33,0x56, + 0x4,0x2f,0x50, 0x3,0x38,0x4b, 0x6,0x43,0x71, 0x6,0x43,0x70, + 0x3,0x3e,0x4a, 0x4,0x3a,0x4e, 0x4,0x3a,0x4f, 0x6,0x4d,0x63, + 0x5,0x42,0x2d, 0x4,0x40,0x2f, 0x4,0x46,0x4f, 0x4,0x46,0x51, + 0x4,0x46,0x50, 0x3,0x49,0x2c, 0x6,0x61,0x24, 0x5,0x49,0x2c, + 0x3,0x4e,0x3e, 0x4,0x4c,0x68, 0x4,0x4c,0x65, 0x4,0x52,0x6c, + 0x4,0x52,0x6d, 0x4,0x58,0x30, 0x4,0x58,0x34, 0x4,0x58,0x33, + 0x3,0x56,0x25, 0x3,0x56,0x26, 0x5,0x5d,0x67, 0x5,0x5c,0x4d, + 0x4,0x58,0x32, 0x4,0x5c,0x7c, 0x4,0x64,0x2d, 0x4,0x2f,0x53, + 0x4,0x34,0x5c, 0x4,0x52,0x6f, 0x4,0x52,0x6e, 0x4,0x58,0x35, + 0x4,0x5c,0x7d, 0x4,0x69,0x33, 0x6,0x25,0x4f, 0x3,0x24,0x37, + 0x3,0x24,0x39, 0x3,0x27,0x27, 0x4,0x24,0x76, 0x4,0x24,0x7d, + 0x3,0x27,0x2c, 0x3,0x2a,0x63, 0x3,0x2a,0x67, 0x3,0x2a,0x64, + 0x3,0x2a,0x6a, 0x4,0x27,0x72, 0x3,0x2a,0x62, 0x4,0x28,0x21, + 0x4,0x27,0x73, 0x3,0x2a,0x65, 0x3,0x2a,0x69, 0x5,0x27,0x63, + 0x3,0x2a,0x61, 0x3,0x2e,0x6d, 0x4,0x2b,0x36, 0x3,0x2e,0x70, + 0x3,0x2e,0x71, 0x3,0x2e,0x6c, 0x3,0x2e,0x73, 0x3,0x2e,0x75, + 0x6,0x34,0x3a, 0x4,0x2f,0x55, 0x3,0x33,0x61, 0x4,0x2f,0x61, + 0x3,0x33,0x64, 0x3,0x33,0x5b, 0x3,0x33,0x5e, 0x6,0x3b,0x56, + 0x3,0x33,0x5d, 0x4,0x2f,0x5e, 0x3,0x33,0x5c, 0x3,0x33,0x65, + 0x5,0x30,0x21, 0x4,0x2f,0x59, 0x4,0x2f,0x64, 0x3,0x33,0x60, + 0x4,0x34,0x5e, 0x4,0x34,0x6c, 0x4,0x34,0x71, 0x3,0x38,0x5a, + 0x4,0x34,0x69, 0x4,0x34,0x65, 0x3,0x38,0x56, 0x4,0x34,0x66, + 0x4,0x34,0x62, 0x4,0x34,0x5d, 0x4,0x34,0x63, 0x6,0x44,0x2c, + 0x3,0x38,0x4c, 0x6,0x44,0x28, 0x5,0x35,0x2a, 0x3,0x38,0x59, + 0x3,0x38,0x5c, 0x5,0x35,0x24, 0x4,0x3a,0x6c, 0x4,0x3a,0x60, + 0x4,0x3a,0x5f, 0x4,0x3a,0x64, 0x4,0x3a,0x59, 0x5,0x3b,0x56, + 0x4,0x3a,0x5b, 0x4,0x3a,0x56, 0x3,0x3e,0x53, 0x4,0x3a,0x5e, + 0x3,0x3e,0x54, 0x3,0x3e,0x51, 0x4,0x3a,0x5c, 0x4,0x3a,0x61, + 0x3,0x3e,0x55, 0x6,0x4e,0x27, 0x3,0x3e,0x4c, 0xf,0x3e,0x6b, + 0x4,0x40,0x30, 0x4,0x40,0x32, 0x4,0x3a,0x65, 0x3,0x44,0x37, + 0x4,0x46,0x69, 0x4,0x40,0x47, 0x4,0x40,0x49, 0x4,0x40,0x3a, + 0x3,0x44,0x2b, 0x3,0x44,0x29, 0x3,0x44,0x34, 0x4,0x40,0x48, + 0x3,0x44,0x3d, 0x4,0x40,0x4c, 0x4,0x46,0x65, 0x3,0x49,0x2f, + 0x4,0x46,0x57, 0x6,0x61,0x44, 0x4,0x46,0x64, 0x3,0x49,0x31, + 0x4,0x46,0x53, 0x5,0x49,0x3c, 0x4,0x46,0x61, 0x3,0x49,0x30, + 0x4,0x46,0x6d, 0x4,0x46,0x60, 0x4,0x46,0x5c, 0x3,0x49,0x34, + 0x5,0x49,0x3b, 0x6,0x61,0x58, 0x3,0x49,0x37, 0x3,0x49,0x40, + 0x3,0x4e,0x43, 0x4,0x4c,0x72, 0x3,0x4e,0x3f, 0x4,0x4c,0x70, + 0x4,0x4d,0x24, 0x4,0x4c,0x6b, 0x3,0x4e,0x41, 0x4,0x4c,0x71, + 0x3,0x4e,0x53, 0x4,0x4c,0x6d, 0x4,0x4c,0x73, 0x3,0x4e,0x47, + 0x3,0x4e,0x45, 0x3,0x4e,0x56, 0x4,0x4c,0x7d, 0x3,0x52,0x51, + 0x4,0x4c,0x6c, 0x3,0x4e,0x4a, 0x4,0x4c,0x6e, 0x3,0x4e,0x48, + 0x3,0x4e,0x55, 0x3,0x4e,0x49, 0x5,0x50,0x46, 0x3,0x4e,0x50, + 0xf,0x51,0x65, 0xf,0x51,0x73, 0xf,0x51,0x76, 0x4,0x4d,0x21, + 0x4,0x4c,0x6f, 0x3,0x4e,0x51, 0x4,0x4c,0x77, 0x4,0x52,0x77, + 0x4,0x52,0x7b, 0x4,0x52,0x79, 0x4,0x53,0x2c, 0x4,0x53,0x21, + 0x4,0x52,0x76, 0x3,0x52,0x53, 0x4,0x53,0x25, 0x3,0x52,0x57, + 0x4,0x52,0x7e, 0x3,0x52,0x4d, 0x4,0x53,0x23, 0x4,0x52,0x7a, + 0x4,0x52,0x7c, 0x4,0x52,0x72, 0x5,0x64,0x2d, 0x3,0x52,0x4c, + 0x4,0x53,0x22, 0x4,0x52,0x73, 0x3,0x52,0x4e, 0x4,0x53,0x27, + 0x4,0x53,0x31, 0x4,0x46,0x67, 0x4,0x58,0x44, 0x4,0x58,0x3c, + 0x4,0x58,0x38, 0x4,0x58,0x42, 0x5,0x5d,0x79, 0x4,0x58,0x36, + 0x4,0x58,0x3b, 0x3,0x56,0x2e, 0x3,0x56,0x27, 0x4,0x58,0x3d, + 0x3,0x56,0x2a, 0x3,0x56,0x2f, 0x3,0x58,0x69, 0x4,0x5c,0x7e, + 0x4,0x5d,0x2b, 0x3,0x58,0x6d, 0x3,0x58,0x70, 0x3,0x58,0x6a, + 0x3,0x58,0x71, 0x4,0x5d,0x23, 0x7,0x42,0x38, 0x4,0x5d,0x21, + 0xf,0x60,0x4e, 0x7,0x3b,0x32, 0x4,0x60,0x77, 0x3,0x5c,0x73, + 0x3,0x5b,0x23, 0x4,0x60,0x78, 0x3,0x5b,0x21, 0x3,0x5b,0x24, + 0x7,0x49,0x53, 0x4,0x64,0x2f, 0x4,0x64,0x34, 0x3,0x5c,0x7d, + 0x4,0x64,0x33, 0x3,0x5c,0x74, 0x7,0x54,0x68, 0x3,0x5c,0x79, + 0x4,0x64,0x32, 0x4,0x64,0x38, 0x3,0x5c,0x7a, 0x4,0x64,0x30, + 0x3,0x5c,0x75, 0x4,0x64,0x36, 0x4,0x67,0x27, 0x3,0x5e,0x59, + 0x4,0x67,0x28, 0xf,0x68,0x39, 0x3,0x5f,0x5d, 0x4,0x69,0x37, + 0x7,0x58,0x72, 0x3,0x60,0x41, 0x3,0x60,0x42, 0x5,0x78,0x25, + 0x4,0x6b,0x7d, 0x4,0x6d,0x5e, 0x4,0x6c,0x7d, 0x3,0x61,0x6a, + 0x4,0x6d,0x79, 0x4,0x6d,0x7b, 0xf,0x6c,0x6c, 0x4,0x6e,0x37, + 0x4,0x6e,0x36, 0x5,0x7c,0x3e, 0x3,0x2a,0x6d, 0x4,0x2b,0x3e, + 0x4,0x2f,0x67, 0x3,0x33,0x67, 0x3,0x33,0x66, 0x3,0x33,0x68, + 0x5,0x35,0x35, 0x3,0x38,0x62, 0x5,0x3b,0x70, 0x3,0x3e,0x60, + 0x3,0x44,0x41, 0x5,0x42,0x54, 0x5,0x42,0x53, 0x3,0x44,0x42, + 0x3,0x44,0x43, 0x4,0x4d,0x26, 0x4,0x53,0x36, 0x4,0x5d,0x32, + 0x5,0x64,0x3b, 0x5,0x64,0x3a, 0x4,0x64,0x3a, 0x3,0x27,0x2e, + 0x3,0x2e,0x7d, 0x3,0x2f,0x21, 0x3,0x2f,0x22, 0x4,0x2f,0x69, + 0x4,0x2f,0x6b, 0x6,0x3b,0x69, 0x3,0x38,0x68, 0x3,0x38,0x67, + 0x4,0x34,0x7c, 0x3,0x38,0x65, 0x4,0x34,0x7b, 0x4,0x34,0x79, + 0x5,0x3c,0x26, 0x6,0x44,0x48, 0x4,0x3a,0x72, 0x3,0x3e,0x67, + 0x4,0x3a,0x74, 0x3,0x3e,0x65, 0x5,0x3b,0x74, 0x4,0x3a,0x70, + 0x4,0x3a,0x6d, 0x3,0x3e,0x64, 0x3,0x3e,0x66, 0x4,0x40,0x56, + 0x4,0x40,0x57, 0x3,0x44,0x4b, 0x3,0x44,0x47, 0x4,0x40,0x5b, + 0x4,0x3a,0x6e, 0x4,0x40,0x5d, 0x3,0x44,0x4a, 0x4,0x46,0x78, + 0x3,0x49,0x46, 0x4,0x46,0x72, 0x4,0x46,0x73, 0x4,0x46,0x71, + 0x4,0x46,0x75, 0x3,0x49,0x47, 0x4,0x46,0x70, 0x4,0x46,0x76, + 0x6,0x61,0x69, 0x3,0x49,0x48, 0x4,0x46,0x7b, 0x3,0x4e,0x5a, + 0x3,0x4e,0x5c, 0x7,0x28,0x42, 0x3,0x4e,0x57, 0x3,0x4e,0x58, + 0x4,0x4d,0x30, 0x3,0x4e,0x5b, 0x4,0x46,0x79, 0x4,0x4d,0x36, + 0x4,0x4d,0x2f, 0x3,0x49,0x4d, 0x4,0x53,0x3e, 0x3,0x52,0x5c, + 0x7,0x32,0x73, 0x4,0x53,0x3d, 0x4,0x58,0x4d, 0x3,0x52,0x60, + 0x7,0x32,0x75, 0x3,0x52,0x61, 0x5,0x5e,0x32, 0x4,0x58,0x57, + 0x4,0x58,0x52, 0x3,0x56,0x37, 0x4,0x58,0x58, 0x4,0x58,0x4f, + 0x4,0x58,0x56, 0x3,0x56,0x38, 0x4,0x58,0x4e, 0x3,0x56,0x32, + 0x4,0x58,0x54, 0x4,0x58,0x5f, 0x3,0x56,0x35, 0x3,0x56,0x3c, + 0x3,0x56,0x31, 0x4,0x5d,0x3b, 0x5,0x5e,0x35, 0x4,0x5d,0x39, + 0x3,0x58,0x72, 0x4,0x61,0x24, 0x5,0x69,0x41, 0x3,0x5b,0x2a, + 0x4,0x61,0x21, 0x4,0x61,0x25, 0xf,0x63,0x6e, 0x5,0x6d,0x4b, + 0x4,0x64,0x3b, 0x4,0x64,0x3c, 0x4,0x64,0x40, 0x4,0x64,0x3e, + 0x4,0x64,0x41, 0x3,0x5d,0x26, 0x3,0x5e,0x5e, 0x4,0x67,0x30, + 0x4,0x64,0x3d, 0x4,0x69,0x3e, 0x3,0x5f,0x5e, 0x3,0x5f,0x60, + 0x3,0x60,0x44, 0x7,0x59,0x25, 0x7,0x5c,0x5e, 0x4,0x6a,0x78, + 0x7,0x5c,0x63, 0x3,0x61,0x48, 0x4,0x6e,0x39, 0x3,0x2f,0x25, + 0x6,0x3b,0x73, 0x3,0x38,0x69, 0x3,0x44,0x4c, 0x4,0x47,0x23, + 0x4,0x4d,0x37, 0x4,0x2f,0x6f, 0x4,0x3a,0x78, 0x3,0x4e,0x5e, + 0x4,0x53,0x4a, 0x3,0x5b,0x2e, 0x3,0x2a,0x6e, 0x3,0x2f,0x28, + 0x4,0x2b,0x46, 0x5,0x30,0x3d, 0x4,0x2f,0x72, 0x5,0x30,0x39, + 0x4,0x35,0x2a, 0x4,0x3a,0x7a, 0x4,0x35,0x2d, 0x4,0x35,0x2e, + 0x4,0x35,0x2c, 0xf,0x32,0x51, 0x4,0x3a,0x79, 0x3,0x3e,0x71, + 0x4,0x35,0x30, 0x3,0x3e,0x6e, 0x3,0x3e,0x6c, 0x3,0x3e,0x6b, + 0x3,0x2f,0x4a, 0x4,0x40,0x62, 0x4,0x47,0x25, 0x6,0x58,0x2b, + 0x3,0x49,0x53, 0x4,0x47,0x2d, 0x5,0x49,0x6c, 0x5,0x49,0x6d, + 0x4,0x40,0x66, 0x4,0x47,0x31, 0x4,0x47,0x27, 0x3,0x49,0x55, + 0x4,0x40,0x60, 0x4,0x47,0x2a, 0x4,0x47,0x2e, 0x4,0x47,0x26, + 0x4,0x47,0x2b, 0x3,0x49,0x5a, 0x3,0x49,0x50, 0x3,0x49,0x5b, + 0x4,0x4d,0x3c, 0x4,0x4d,0x3f, 0x4,0x4d,0x3a, 0x4,0x4d,0x39, + 0x4,0x4d,0x42, 0x4,0x4d,0x40, 0x4,0x4d,0x47, 0x4,0x53,0x52, + 0x4,0x53,0x55, 0x4,0x53,0x56, 0x3,0x4e,0x63, 0x4,0x53,0x4f, + 0x4,0x58,0x63, 0x4,0x58,0x67, 0x3,0x56,0x45, 0x3,0x56,0x43, + 0x4,0x58,0x64, 0x3,0x56,0x3e, 0x7,0x3b,0x59, 0x3,0x56,0x44, + 0x4,0x58,0x65, 0x3,0x56,0x41, 0x5,0x64,0x56, 0x4,0x5d,0x4a, + 0x4,0x5d,0x48, 0x4,0x5d,0x49, 0x4,0x5d,0x44, 0x4,0x5d,0x46, + 0x4,0x61,0x2a, 0x7,0x43,0x22, 0x4,0x64,0x43, 0x7,0x50,0x25, + 0x3,0x5d,0x27, 0x4,0x64,0x44, 0x3,0x5e,0x5f, 0x4,0x6a,0x7b, + 0x7,0x59,0x32, 0x3,0x60,0x7a, 0x4,0x6c,0x26, 0x3,0x60,0x79, + 0x4,0x6d,0x7d, 0x5,0x2b,0x47, 0x4,0x2f,0x73, 0x4,0x35,0x31, + 0x4,0x3b,0x21, 0x3,0x33,0x79, 0x3,0x33,0x78, 0x4,0x35,0x33, + 0x4,0x35,0x35, 0x4,0x3b,0x23, 0x5,0x3c,0x35, 0x4,0x3b,0x22, + 0x3,0x3e,0x73, 0x3,0x44,0x50, 0x3,0x44,0x51, 0x4,0x47,0x36, + 0x4,0x47,0x38, 0x4,0x4d,0x4a, 0x4,0x4d,0x48, 0x4,0x53,0x5a, + 0x4,0x53,0x5b, 0x5,0x58,0x32, 0x4,0x53,0x5c, 0x5,0x5e,0x43, + 0x4,0x58,0x68, 0x4,0x58,0x69, 0x4,0x5d,0x4e, 0x4,0x5d,0x50, + 0x4,0x61,0x2d, 0x4,0x61,0x2e, 0x3,0x5b,0x30, 0x4,0x61,0x2c, + 0x4,0x61,0x30, 0x3,0x5e,0x60, 0x3,0x62,0x3c, 0x4,0x35,0x3a, + 0x3,0x44,0x53, 0x4,0x40,0x67, 0x3,0x44,0x52, 0x4,0x47,0x3a, + 0x4,0x4d,0x51, 0x4,0x4d,0x4c, 0x4,0x4d,0x4e, 0x4,0x4d,0x53, + 0x4,0x4d,0x4f, 0x4,0x53,0x64, 0x4,0x53,0x61, 0x4,0x53,0x62, + 0x4,0x58,0x6b, 0x4,0x58,0x6a, 0x5,0x64,0x63, 0x4,0x61,0x31, + 0x4,0x61,0x34, 0x4,0x64,0x46, 0x4,0x64,0x47, 0x4,0x6d,0x22, + 0x3,0x2f,0x2b, 0x5,0x2b,0x49, 0x3,0x2f,0x2d, 0x4,0x2f,0x7e, + 0x3,0x33,0x7d, 0x4,0x35,0x41, 0x3,0x38,0x7c, 0x3,0x38,0x78, + 0x5,0x35,0x57, 0x4,0x35,0x44, 0x5,0x35,0x5e, 0x3,0x39,0x24, + 0x3,0x39,0x28, 0x3,0x39,0x21, 0x4,0x35,0x3f, 0x3,0x38,0x7d, + 0x3,0x39,0x27, 0x4,0x35,0x43, 0x5,0x35,0x5d, 0x6,0x44,0x6d, + 0x3,0x39,0x26, 0x5,0x35,0x56, 0x4,0x3b,0x33, 0x3,0x3e,0x79, + 0x3,0x3e,0x7a, 0x4,0x3b,0x36, 0x4,0x3b,0x35, 0x3,0x3e,0x76, + 0x3,0x3e,0x7b, 0x3,0x3e,0x77, 0x4,0x3b,0x34, 0x4,0x3b,0x2a, + 0x4,0x3b,0x29, 0x4,0x3b,0x2b, 0x3,0x3f,0x26, 0x6,0x4e,0x6b, + 0x3,0x3f,0x25, 0x3,0x44,0x57, 0x6,0x58,0x41, 0x3,0x44,0x5e, + 0x4,0x40,0x6e, 0x4,0x40,0x6d, 0x4,0x40,0x6c, 0x3,0x44,0x5a, + 0x3,0x44,0x5f, 0x3,0x44,0x62, 0x4,0x47,0x3d, 0x4,0x47,0x40, + 0x4,0x47,0x4a, 0x4,0x47,0x3c, 0x3,0x49,0x6a, 0x4,0x47,0x46, + 0x4,0x47,0x42, 0x3,0x49,0x61, 0x4,0x47,0x43, 0x3,0x49,0x69, + 0x3,0x49,0x67, 0x3,0x49,0x5d, 0x4,0x4d,0x59, 0x4,0x4d,0x56, + 0x4,0x4d,0x5c, 0x4,0x4d,0x5e, 0x3,0x4e,0x68, 0x4,0x4d,0x61, + 0x4,0x4d,0x58, 0x4,0x4d,0x5b, 0x3,0x4e,0x6d, 0x4,0x4d,0x5f, + 0x4,0x4d,0x5a, 0x3,0x4e,0x6b, 0x4,0x4d,0x60, 0x7,0x28,0x79, + 0x4,0x4d,0x55, 0x3,0x4e,0x71, 0x4,0x53,0x6a, 0x3,0x52,0x6c, + 0x3,0x52,0x6d, 0x7,0x33,0x4d, 0x4,0x53,0x6b, 0x3,0x56,0x47, + 0x4,0x58,0x70, 0x3,0x56,0x4b, 0x3,0x56,0x4c, 0x5,0x5e,0x55, + 0x4,0x5d,0x5a, 0x7,0x4a,0x25, 0x4,0x5d,0x57, 0x4,0x5d,0x5b, + 0x3,0x59,0x22, 0x3,0x59,0x25, 0x4,0x5d,0x54, 0x3,0x59,0x27, + 0x4,0x61,0x40, 0x5,0x69,0x52, 0x3,0x5b,0x33, 0x4,0x61,0x3b, + 0x4,0x61,0x3d, 0x4,0x61,0x45, 0x5,0x69,0x51, 0x4,0x64,0x4e, + 0x3,0x5d,0x2d, 0x7,0x50,0x31, 0x4,0x64,0x4c, 0x3,0x5d,0x2f, + 0x4,0x64,0x48, 0x3,0x5d,0x31, 0x4,0x67,0x3d, 0x4,0x67,0x3f, + 0x7,0x55,0x32, 0x4,0x67,0x3e, 0x4,0x67,0x40, 0x4,0x67,0x39, + 0x7,0x59,0x38, 0x3,0x5f,0x63, 0x4,0x69,0x48, 0x5,0x76,0x4c, + 0x4,0x2b,0x49, 0x4,0x30,0x23, 0x6,0x4e,0x7a, 0x3,0x3f,0x27, + 0x4,0x47,0x4c, 0x3,0x4e,0x77, 0x4,0x58,0x75, 0x4,0x5d,0x61, + 0x4,0x69,0x4c, 0x4,0x35,0x4a, 0x3,0x3f,0x28, 0x4,0x40,0x74, + 0x4,0x47,0x4e, 0x4,0x47,0x4f, 0x3,0x49,0x6c, 0x4,0x4d,0x64, + 0x3,0x52,0x70, 0x4,0x53,0x73, 0x3,0x52,0x6f, 0x4,0x53,0x72, + 0x3,0x52,0x71, 0x4,0x58,0x76, 0x4,0x58,0x77, 0x3,0x56,0x4e, + 0x4,0x67,0x44, 0x4,0x6d,0x24, 0x4,0x30,0x25, 0x4,0x35,0x4b, + 0x6,0x45,0x22, 0x4,0x35,0x4c, 0xf,0x44,0x74, 0x4,0x4d,0x67, + 0x4,0x4d,0x65, 0x4,0x4d,0x68, 0x4,0x53,0x75, 0x4,0x53,0x77, + 0x4,0x5d,0x64, 0x4,0x61,0x48, 0x4,0x61,0x46, 0x4,0x67,0x45, + 0x3,0x5f,0x65, 0x3,0x61,0x4c, 0x4,0x6d,0x25, 0x4,0x35,0x50, + 0x6,0x45,0x24, 0x3,0x39,0x2f, 0x4,0x3b,0x3e, 0x3,0x49,0x6e, + 0x3,0x4e,0x79, 0x3,0x4e,0x78, 0x3,0x52,0x72, 0x3,0x56,0x50, + 0x3,0x59,0x2c, 0x3,0x59,0x2d, 0x4,0x61,0x4a, 0x7,0x4a,0x41, + 0x3,0x5b,0x37, 0x4,0x5d,0x68, 0x4,0x35,0x51, 0x4,0x35,0x54, + 0x5,0x3c,0x4c, 0x4,0x3b,0x3f, 0x4,0x3b,0x41, 0x3,0x3f,0x2e, + 0x4,0x3b,0x42, 0x6,0x4f,0x29, 0x4,0x3b,0x43, 0x4,0x41,0x21, + 0x3,0x44,0x66, 0x3,0x44,0x68, 0x5,0x4a,0x29, 0x6,0x62,0x6a, + 0x3,0x49,0x6f, 0x3,0x4e,0x7b, 0x3,0x4e,0x7c, 0x4,0x4d,0x6e, + 0x4,0x4d,0x6c, 0x7,0x29,0x36, 0x4,0x4d,0x6d, 0x5,0x51,0x39, + 0x3,0x4f,0x21, 0x3,0x52,0x74, 0x4,0x53,0x7d, 0x4,0x53,0x79, + 0x4,0x53,0x7b, 0x4,0x53,0x7a, 0x3,0x52,0x76, 0x7,0x3c,0x33, + 0x4,0x58,0x7a, 0xf,0x60,0x7a, 0x4,0x53,0x7e, 0x3,0x5d,0x35, + 0x3,0x5e,0x64, 0x4,0x6b,0x21, 0x5,0x30,0x4b, 0x5,0x43,0x34, + 0x4,0x47,0x59, 0x4,0x47,0x58, 0x4,0x67,0x48, 0x5,0x30,0x4c, + 0x4,0x30,0x27, 0x4,0x30,0x28, 0x4,0x35,0x55, 0x4,0x35,0x56, + 0x3,0x39,0x34, 0x3,0x39,0x36, 0x3,0x3f,0x31, 0x4,0x3b,0x45, + 0x3,0x3f,0x36, 0x3,0x3f,0x32, 0x5,0x3c,0x52, 0x3,0x3f,0x35, + 0x4,0x3b,0x48, 0x4,0x3b,0x47, 0x4,0x41,0x26, 0x4,0x41,0x27, + 0x5,0x43,0x3c, 0x3,0x44,0x6a, 0x4,0x41,0x28, 0x5,0x43,0x38, + 0x4,0x47,0x5a, 0x6,0x62,0x75, 0x4,0x47,0x5b, 0x3,0x49,0x76, + 0x5,0x4a,0x34, 0x3,0x49,0x77, 0x5,0x4a,0x32, 0x3,0x4f,0x27, + 0x4,0x4d,0x73, 0x4,0x4d,0x71, 0x3,0x4f,0x24, 0x4,0x4d,0x74, + 0x7,0x29,0x3d, 0x4,0x54,0x26, 0x5,0x58,0x5c, 0x5,0x58,0x55, + 0x3,0x52,0x78, 0x4,0x58,0x7d, 0x4,0x59,0x25, 0x4,0x58,0x7c, + 0x5,0x5e,0x6d, 0x4,0x5d,0x6d, 0x3,0x59,0x2f, 0x4,0x5d,0x6c, + 0x4,0x5d,0x6a, 0x4,0x5d,0x6e, 0x3,0x59,0x30, 0x4,0x61,0x4d, + 0x3,0x5d,0x36, 0x4,0x64,0x55, 0x4,0x64,0x53, 0x4,0x64,0x56, + 0x4,0x67,0x4a, 0x4,0x69,0x4e, 0x3,0x5f,0x66, 0x4,0x69,0x4f, + 0x4,0x6b,0x23, 0x4,0x6c,0x28, 0x4,0x6d,0x27, 0x4,0x2b,0x4c, + 0x3,0x2f,0x2f, 0x4,0x30,0x2a, 0x3,0x33,0x7e, 0x4,0x35,0x5e, + 0x4,0x35,0x59, 0x5,0x35,0x72, 0x3,0x39,0x3b, 0x4,0x35,0x5b, + 0x4,0x35,0x5c, 0x4,0x35,0x5d, 0x3,0x39,0x3c, 0x5,0x3c,0x63, + 0x4,0x3b,0x4c, 0x4,0x3b,0x50, 0x3,0x3f,0x3d, 0x4,0x3b,0x4d, + 0x4,0x3b,0x49, 0x6,0x4f,0x36, 0x6,0x4f,0x3c, 0x5,0x3c,0x5c, + 0x4,0x3b,0x4a, 0x4,0x3b,0x4b, 0x4,0x3b,0x4f, 0x3,0x3f,0x3c, + 0x5,0x3c,0x5f, 0x4,0x3b,0x51, 0x4,0x41,0x29, 0x5,0x43,0x4b, + 0x3,0x44,0x6c, 0x3,0x44,0x6e, 0xf,0x45,0x58, 0x5,0x4a,0x3e, + 0x4,0x47,0x5e, 0x4,0x47,0x61, 0x4,0x47,0x5f, 0x4,0x47,0x62, + 0x4,0x47,0x65, 0x3,0x49,0x78, 0x4,0x47,0x64, 0x3,0x4f,0x28, + 0x3,0x44,0x6f, 0x4,0x4d,0x77, 0x4,0x4e,0x22, 0x3,0x4f,0x2a, + 0x7,0x29,0x4e, 0x3,0x4f,0x2e, 0x3,0x4f,0x29, 0x4,0x4d,0x7e, + 0x4,0x4e,0x21, 0x4,0x4d,0x7d, 0x4,0x4d,0x79, 0x4,0x4d,0x78, + 0x4,0x4d,0x76, 0x3,0x4f,0x2d, 0x4,0x4e,0x23, 0x4,0x54,0x2e, + 0x3,0x52,0x7d, 0x3,0x52,0x7a, 0x4,0x54,0x2f, 0x4,0x54,0x2d, + 0x5,0x58,0x62, 0x4,0x54,0x30, 0x3,0x52,0x79, 0x5,0x5e,0x7b, + 0x4,0x59,0x2b, 0x4,0x59,0x2c, 0x4,0x59,0x26, 0xf,0x5c,0x78, + 0x4,0x59,0x2a, 0x4,0x59,0x28, 0x3,0x56,0x53, 0x3,0x59,0x33, + 0x4,0x5d,0x74, 0x4,0x5d,0x78, 0x4,0x5d,0x72, 0x4,0x5d,0x75, + 0x7,0x4a,0x57, 0x4,0x61,0x50, 0x3,0x59,0x34, 0x4,0x61,0x51, + 0x4,0x5d,0x77, 0x4,0x64,0x5b, 0x4,0x64,0x5a, 0x4,0x67,0x50, + 0x4,0x67,0x4c, 0x5,0x74,0x4b, 0x4,0x6b,0x24, 0x7,0x5c,0x77, + 0x4,0x6c,0x29, 0x3,0x61,0x4f, 0x3,0x62,0x2e, 0x3,0x3f,0x42, + 0x5,0x3c,0x67, 0x4,0x3b,0x52, 0x4,0x3b,0x53, 0x3,0x3f,0x41, + 0x3,0x44,0x71, 0x3,0x44,0x70, 0x3,0x44,0x72, 0x4,0x4e,0x26, + 0x4,0x54,0x32, 0x4,0x59,0x30, 0x3,0x56,0x56, 0x3,0x5b,0x3e, + 0x4,0x64,0x5f, 0x3,0x60,0x4c, 0x4,0x2b,0x4d, 0x4,0x2b,0x4e, + 0xf,0x2d,0x53, 0x3,0x34,0x22, 0x3,0x39,0x43, 0x3,0x39,0x44, + 0x3,0x39,0x48, 0x4,0x35,0x61, 0x4,0x35,0x62, 0x3,0x39,0x45, + 0x3,0x39,0x46, 0x3,0x39,0x42, 0x6,0x45,0x45, 0x3,0x3f,0x48, + 0x3,0x3f,0x43, 0x4,0x3b,0x54, 0x3,0x3f,0x4a, 0x3,0x44,0x75, + 0x4,0x41,0x2a, 0x3,0x44,0x74, 0x6,0x59,0x24, 0x4,0x41,0x2c, + 0x4,0x47,0x66, 0x4,0x47,0x69, 0x4,0x47,0x67, 0x3,0x49,0x7e, + 0x4,0x4e,0x28, 0x4,0x4e,0x27, 0x4,0x4e,0x2a, 0x4,0x4e,0x29, + 0x3,0x53,0x23, 0x5,0x58,0x72, 0x4,0x54,0x33, 0x4,0x54,0x34, + 0x5,0x51,0x61, 0x3,0x56,0x58, 0x4,0x59,0x32, 0x4,0x59,0x35, + 0x4,0x59,0x37, 0x3,0x56,0x57, 0x4,0x59,0x31, 0x4,0x5d,0x7c, + 0x4,0x5d,0x7b, 0x4,0x5d,0x7a, 0x5,0x65,0x35, 0x4,0x5d,0x7d, + 0x4,0x5d,0x7e, 0x4,0x61,0x59, 0x4,0x61,0x58, 0x4,0x61,0x57, + 0x4,0x64,0x60, 0x4,0x64,0x61, 0x4,0x67,0x52, 0xf,0x68,0x53, + 0x3,0x5f,0x68, 0x3,0x5f,0x67, 0x3,0x60,0x7d, 0x4,0x6d,0x61, + 0x4,0x6e,0x21, 0x3,0x62,0x3d, 0x4,0x4e,0x2e, 0x3,0x5d,0x39, + 0x4,0x47,0x6b, 0xf,0x4c,0x67, 0x3,0x4f,0x38, 0x4,0x64,0x63, + 0x7,0x50,0x56, 0x3,0x27,0x32, 0x4,0x25,0x22, 0xf,0x28,0x72, + 0x3,0x2a,0x6f, 0x5,0x27,0x69, 0x4,0x2b,0x53, 0x4,0x2b,0x50, + 0x3,0x34,0x23, 0x4,0x30,0x2d, 0x4,0x30,0x30, 0x3,0x34,0x24, + 0x4,0x30,0x2e, 0x3,0x39,0x49, 0x4,0x35,0x69, 0x3,0x39,0x4d, + 0x3,0x3f,0x53, 0x4,0x3b,0x57, 0x3,0x3f,0x4e, 0x6,0x4f,0x48, + 0x3,0x3f,0x52, 0x4,0x41,0x2f, 0x3,0x4a,0x25, 0x4,0x47,0x6c, + 0x3,0x4a,0x23, 0x3,0x4f,0x3a, 0x4,0x4e,0x31, 0x4,0x4e,0x35, + 0x3,0x4f,0x3d, 0x3,0x53,0x2a, 0x3,0x53,0x28, 0x3,0x53,0x29, + 0x4,0x59,0x38, 0x4,0x59,0x39, 0x7,0x43,0x77, 0x3,0x59,0x39, + 0x4,0x61,0x5e, 0x4,0x6c,0x2c, 0x3,0x22,0x5f, 0x4,0x23,0x32, + 0x3,0x27,0x36, 0x3,0x27,0x37, 0x3,0x27,0x38, 0x3,0x2a,0x76, + 0x4,0x28,0x29, 0x3,0x2f,0x36, 0x4,0x2b,0x56, 0x3,0x45,0x22, + 0x3,0x2f,0x3d, 0x4,0x2b,0x54, 0x4,0x2b,0x58, 0x3,0x2f,0x39, + 0x3,0x2f,0x3a, 0x6,0x34,0x6d, 0x4,0x30,0x38, 0x4,0x30,0x34, + 0x3,0x34,0x28, 0x4,0x30,0x33, 0x4,0x47,0x71, 0x4,0x35,0x6c, + 0x4,0x35,0x6e, 0x4,0x35,0x73, 0x4,0x35,0x6b, 0x3,0x39,0x50, + 0x4,0x35,0x70, 0x4,0x3b,0x5e, 0x3,0x3f,0x58, 0x4,0x41,0x34, + 0x4,0x41,0x36, 0x3,0x45,0x21, 0x4,0x59,0x3c, 0x4,0x41,0x38, + 0x4,0x47,0x6d, 0x4,0x47,0x6e, 0x3,0x4a,0x29, 0x3,0x4a,0x28, + 0x5,0x4a,0x60, 0x4,0x47,0x70, 0x3,0x4f,0x3e, 0x4,0x4e,0x3d, + 0x4,0x4e,0x3c, 0x5,0x58,0x7e, 0x5,0x5f,0x3c, 0x3,0x60,0x4d, + 0x4,0x6b,0x26, 0x3,0x2f,0x3f, 0x3,0x34,0x2b, 0x3,0x34,0x2c, + 0x4,0x35,0x78, 0x4,0x35,0x74, 0x3,0x39,0x53, 0x5,0x36,0x36, + 0x4,0x35,0x75, 0x4,0x3b,0x60, 0x3,0x3f,0x5a, 0x3,0x3f,0x5b, + 0x3,0x3f,0x5c, 0x4,0x3b,0x64, 0x6,0x59,0x4c, 0x3,0x45,0x26, + 0x4,0x41,0x3d, 0x4,0x41,0x3c, 0x4,0x41,0x3f, 0x4,0x41,0x3e, + 0x4,0x47,0x73, 0x4,0x47,0x74, 0x4,0x4e,0x3f, 0x4,0x4e,0x41, + 0x4,0x4e,0x3e, 0x4,0x4e,0x40, 0x4,0x54,0x3d, 0x4,0x54,0x3c, + 0x4,0x54,0x3a, 0x3,0x53,0x2e, 0x4,0x54,0x40, 0x4,0x54,0x3b, + 0x7,0x34,0x54, 0x3,0x53,0x30, 0x4,0x59,0x3d, 0x4,0x59,0x42, + 0x7,0x3c,0x70, 0x4,0x59,0x41, 0x5,0x65,0x45, 0x4,0x61,0x61, + 0x4,0x61,0x64, 0x4,0x61,0x63, 0x4,0x61,0x62, 0x4,0x61,0x65, + 0x4,0x67,0x5a, 0x4,0x67,0x5b, 0x4,0x69,0x54, 0x4,0x69,0x53, + 0x4,0x6c,0x2e, 0x4,0x6c,0x2d, 0x4,0x6e,0x3d, 0x4,0x35,0x7a, + 0x6,0x3c,0x63, 0x3,0x39,0x5a, 0x3,0x3f,0x5f, 0x3,0x3f,0x64, + 0x3,0x3f,0x61, 0x3,0x3f,0x67, 0x3,0x45,0x2c, 0x5,0x43,0x6d, + 0x3,0x4a,0x2e, 0x4,0x47,0x79, 0x3,0x4a,0x36, 0x4,0x47,0x76, + 0x4,0x47,0x7b, 0x4,0x47,0x78, 0x3,0x4f,0x4f, 0x4,0x4e,0x43, + 0x3,0x4f,0x47, 0x3,0x4f,0x46, 0x7,0x2a,0x38, 0x3,0x4f,0x4a, + 0x7,0x2a,0x3e, 0x3,0x53,0x33, 0x3,0x53,0x34, 0x4,0x54,0x48, + 0x4,0x54,0x46, 0x7,0x3c,0x7b, 0x3,0x56,0x69, 0x7,0x3c,0x77, + 0x4,0x59,0x45, 0x4,0x59,0x44, 0xf,0x5d,0x4c, 0x3,0x59,0x3f, + 0x3,0x59,0x41, 0x4,0x5e,0x2f, 0x4,0x5e,0x2c, 0x7,0x44,0x39, + 0x4,0x5e,0x27, 0x5,0x65,0x4f, 0x4,0x5e,0x2b, 0x3,0x59,0x48, + 0x3,0x59,0x47, 0x3,0x5b,0x46, 0x4,0x61,0x66, 0x3,0x5b,0x4b, + 0x3,0x5b,0x40, 0x3,0x5b,0x52, 0x4,0x61,0x69, 0x5,0x6a,0x33, + 0x4,0x61,0x68, 0x3,0x5b,0x51, 0x3,0x5b,0x4c, 0x3,0x5b,0x49, + 0xf,0x64,0x34, 0x3,0x5d,0x3b, 0x4,0x61,0x6c, 0x3,0x5d,0x40, + 0x4,0x64,0x66, 0x4,0x64,0x6c, 0x5,0x6e,0x35, 0x3,0x5d,0x48, + 0x4,0x64,0x6d, 0x4,0x67,0x5f, 0x3,0x5e,0x6b, 0x4,0x64,0x69, + 0x4,0x67,0x61, 0x3,0x5e,0x6c, 0x4,0x67,0x63, 0x7,0x55,0x68, + 0x3,0x5e,0x69, 0x3,0x5e,0x6e, 0x3,0x5e,0x6f, 0x3,0x5f,0x6f, + 0x3,0x60,0x51, 0x5,0x71,0x55, 0x7,0x59,0x67, 0x3,0x5f,0x6d, + 0x7,0x59,0x68, 0x3,0x5f,0x70, 0x5,0x74,0x55, 0x4,0x6b,0x2a, + 0x5,0x76,0x5f, 0x4,0x6b,0x27, 0x3,0x60,0x4e, 0x3,0x60,0x50, + 0x3,0x61,0x23, 0x3,0x61,0x21, 0x4,0x6c,0x30, 0x3,0x61,0x24, + 0x3,0x61,0x6e, 0x6,0x3c,0x65, 0x4,0x3b,0x67, 0xf,0x3f,0x76, + 0x4,0x41,0x49, 0x4,0x5e,0x32, 0x3,0x39,0x5b, 0x4,0x35,0x7c, + 0x3,0x3f,0x6a, 0x4,0x3b,0x6b, 0x3,0x3f,0x6e, 0x3,0x3f,0x6b, + 0x3,0x45,0x3b, 0x4,0x41,0x50, 0x4,0x41,0x4e, 0x4,0x48,0x23, + 0x3,0x4a,0x3b, 0x3,0x4a,0x3f, 0x3,0x4a,0x3a, 0x5,0x4a,0x6e, + 0x3,0x4a,0x3c, 0x7,0x2a,0x46, 0x4,0x4e,0x48, 0x3,0x4f,0x54, + 0x3,0x4f,0x57, 0x4,0x54,0x4f, 0x4,0x54,0x4b, 0x3,0x53,0x3f, + 0x4,0x54,0x4c, 0x3,0x53,0x41, 0x3,0x53,0x43, 0x3,0x53,0x46, + 0x3,0x53,0x45, 0x7,0x34,0x73, 0x4,0x59,0x4e, 0x4,0x59,0x4f, + 0x4,0x59,0x54, 0x3,0x56,0x6e, 0x3,0x56,0x6c, 0x4,0x59,0x4d, + 0x4,0x59,0x52, 0x4,0x67,0x66, 0x4,0x64,0x71, 0x5,0x71,0x5b, + 0x4,0x69,0x55, 0x5,0x21,0x7d, 0x3,0x22,0x60, 0x3,0x24,0x3e, + 0x5,0x24,0x7b, 0x6,0x29,0x35, 0x4,0x28,0x31, 0x4,0x28,0x32, + 0x3,0x2a,0x7a, 0x5,0x2b,0x64, 0x4,0x2b,0x5a, 0x3,0x2f,0x41, + 0x4,0x2b,0x59, 0x4,0x30,0x40, 0x4,0x30,0x3d, 0x3,0x34,0x35, + 0x4,0x30,0x3e, 0x3,0x34,0x37, 0x4,0x30,0x3c, 0x3,0x39,0x63, + 0x3,0x39,0x5d, 0x4,0x35,0x7d, 0x3,0x39,0x60, 0x3,0x39,0x62, + 0x3,0x39,0x64, 0x3,0x39,0x5f, 0x3,0x3f,0x6f, 0x4,0x3b,0x6d, + 0x3,0x3f,0x74, 0x3,0x45,0x3f, 0x3,0x45,0x3e, 0x4,0x41,0x55, + 0x4,0x41,0x54, 0x3,0x45,0x3d, 0x3,0x45,0x41, 0x3,0x4a,0x41, + 0x3,0x4a,0x40, 0x3,0x4a,0x43, 0x3,0x4a,0x42, 0x3,0x4f,0x59, + 0x3,0x4f,0x58, 0x7,0x2a,0x54, 0x3,0x53,0x47, 0x4,0x54,0x53, + 0x4,0x54,0x51, 0x4,0x59,0x55, 0x3,0x5b,0x54, 0x4,0x64,0x73, + 0x4,0x67,0x67, 0x3,0x34,0x38, 0x4,0x36,0x24, 0x3,0x3f,0x7a, + 0x3,0x3f,0x76, 0x3,0x3f,0x79, 0x3,0x3f,0x77, 0x4,0x41,0x56, + 0x3,0x45,0x44, 0x3,0x45,0x43, 0x3,0x45,0x45, 0x3,0x4a,0x48, + 0x3,0x4f,0x5d, 0x3,0x4f,0x5c, 0x3,0x53,0x4b, 0x3,0x53,0x4a, + 0x3,0x52,0x38, 0x4,0x59,0x58, 0x3,0x56,0x72, 0x3,0x59,0x4c, + 0x3,0x5b,0x55, 0x3,0x5d,0x4a, 0x3,0x5b,0x56, 0x3,0x5d,0x4b, + 0x4,0x69,0x56, 0x3,0x61,0x51, 0x3,0x62,0x40, 0x3,0x39,0x66, + 0x3,0x3f,0x7d, 0x6,0x50,0x31, 0x3,0x45,0x48, 0x4,0x48,0x2d, + 0x4,0x48,0x31, 0x4,0x48,0x2e, 0x3,0x4a,0x4a, 0x4,0x48,0x34, + 0x3,0x4a,0x4b, 0x4,0x48,0x33, 0x6,0x63,0x7b, 0x3,0x4f,0x5e, + 0x3,0x4f,0x61, 0x3,0x4f,0x5f, 0x4,0x54,0x59, 0x3,0x53,0x4f, + 0x3,0x53,0x4e, 0x4,0x59,0x60, 0x3,0x56,0x73, 0x3,0x56,0x77, + 0x4,0x54,0x58, 0x3,0x56,0x76, 0x4,0x59,0x5d, 0x4,0x59,0x5f, + 0x4,0x5e,0x35, 0x3,0x59,0x4d, 0x3,0x59,0x4e, 0x4,0x5e,0x36, + 0x7,0x44,0x58, 0x7,0x44,0x60, 0x4,0x61,0x74, 0x4,0x61,0x73, + 0x3,0x5b,0x57, 0x3,0x5b,0x58, 0x3,0x5b,0x59, 0x4,0x64,0x75, + 0x3,0x5d,0x4d, 0x4,0x69,0x58, 0x4,0x69,0x5a, 0x4,0x69,0x5b, + 0x3,0x60,0x58, 0x3,0x61,0x53, 0x3,0x61,0x27, 0x3,0x61,0x52, + 0x3,0x62,0x24, 0x3,0x62,0x44, 0x3,0x62,0x46, 0x4,0x69,0x5c, + 0x4,0x36,0x28, 0x4,0x36,0x2a, 0x4,0x3b,0x74, 0x4,0x4e,0x4c, + 0x4,0x64,0x7b, 0x4,0x41,0x5a, 0x3,0x45,0x4a, 0x3,0x4a,0x4d, + 0x4,0x48,0x38, 0x4,0x48,0x37, 0x4,0x54,0x5d, 0x4,0x54,0x5c, + 0x4,0x59,0x62, 0x4,0x64,0x7c, 0x4,0x67,0x6e, 0x5,0x71,0x63, + 0x4,0x6c,0x33, 0x4,0x3b,0x79, 0x3,0x40,0x23, 0x4,0x3b,0x76, + 0x3,0x45,0x4d, 0x4,0x41,0x5d, 0x4,0x41,0x5f, 0x3,0x45,0x4c, + 0xf,0x46,0x32, 0x6,0x5a,0x28, 0x4,0x48,0x3a, 0x4,0x48,0x40, + 0x4,0x48,0x3b, 0x3,0x4a,0x4f, 0x3,0x4a,0x50, 0x4,0x48,0x3d, + 0x4,0x4e,0x4f, 0x4,0x54,0x63, 0x4,0x54,0x61, 0x4,0x54,0x60, + 0x4,0x54,0x64, 0x4,0x54,0x62, 0x4,0x59,0x63, 0x4,0x54,0x68, + 0x3,0x53,0x52, 0x3,0x56,0x7c, 0x4,0x59,0x68, 0x4,0x59,0x64, + 0x7,0x3d,0x56, 0x3,0x56,0x79, 0x3,0x56,0x7d, 0x3,0x56,0x7e, + 0x4,0x5e,0x3e, 0x5,0x65,0x7e, 0x4,0x5e,0x42, 0x4,0x5e,0x3c, + 0x5,0x65,0x73, 0x5,0x65,0x7b, 0x4,0x5e,0x3b, 0x4,0x5e,0x41, + 0x3,0x5b,0x5c, 0x3,0x5b,0x5b, 0x4,0x61,0x77, 0x4,0x61,0x7b, + 0x3,0x5b,0x5a, 0x4,0x65,0x23, 0x4,0x64,0x7e, 0x5,0x6e,0x49, + 0x7,0x56,0x27, 0x7,0x56,0x25, 0x4,0x67,0x72, 0x4,0x67,0x70, + 0x5,0x71,0x69, 0x7,0x56,0x26, 0x3,0x5f,0x74, 0x5,0x74,0x62, + 0x4,0x6b,0x2c, 0x3,0x60,0x5a, 0x4,0x6c,0x34, 0x4,0x6d,0x2d, + 0x3,0x61,0x54, 0x4,0x6d,0x65, 0x3,0x61,0x70, 0x4,0x6e,0x22, + 0x4,0x41,0x61, 0x4,0x48,0x43, 0x4,0x48,0x41, 0x4,0x48,0x42, + 0x4,0x48,0x44, 0x3,0x53,0x54, 0x4,0x59,0x6b, 0x7,0x44,0x77, + 0x4,0x5e,0x45, 0x3,0x59,0x52, 0x4,0x61,0x7d, 0x4,0x61,0x7e, + 0x4,0x67,0x73, 0x4,0x69,0x60, 0x3,0x60,0x5b, 0x3,0x45,0x4e, + 0x3,0x57,0x21, 0x3,0x5b,0x63, 0x3,0x5b,0x62, 0x3,0x5d,0x52, + 0x4,0x67,0x75, 0x4,0x6b,0x2d, 0x3,0x40,0x25, 0x3,0x40,0x26, + 0x3,0x40,0x27, 0x3,0x45,0x51, 0x4,0x54,0x6a, 0x4,0x54,0x69, + 0x3,0x59,0x53, 0x4,0x62,0x22, 0x4,0x62,0x23, 0x3,0x5f,0x75, + 0x4,0x3b,0x7b, 0xf,0x40,0x2d, 0x4,0x41,0x65, 0x4,0x41,0x64, + 0x5,0x44,0x34, 0x5,0x4b,0x3e, 0x4,0x48,0x4d, 0x3,0x4a,0x51, + 0x4,0x48,0x4e, 0x3,0x4a,0x53, 0x4,0x48,0x4c, 0x4,0x48,0x4b, + 0x5,0x4b,0x3f, 0x4,0x48,0x47, 0x3,0x4f,0x68, 0x4,0x4e,0x59, + 0x4,0x4e,0x5c, 0x5,0x52,0x60, 0x4,0x54,0x6d, 0x4,0x54,0x6f, + 0x3,0x53,0x56, 0x4,0x4e,0x5d, 0x3,0x53,0x60, 0x3,0x53,0x57, + 0x3,0x53,0x5e, 0x7,0x35,0x51, 0x3,0x57,0x25, 0x4,0x59,0x73, + 0x7,0x3d,0x69, 0x3,0x57,0x22, 0x4,0x59,0x77, 0x3,0x57,0x23, + 0x3,0x57,0x24, 0x3,0x57,0x27, 0x3,0x57,0x29, 0x4,0x5e,0x4e, + 0x3,0x59,0x54, 0x4,0x5e,0x49, 0x4,0x5e,0x47, 0x4,0x5e,0x4b, + 0x3,0x59,0x57, 0x3,0x59,0x55, 0x4,0x5e,0x4d, 0x4,0x5e,0x4c, + 0x3,0x59,0x5a, 0x4,0x62,0x27, 0x4,0x62,0x29, 0x4,0x62,0x2d, + 0x4,0x62,0x26, 0x4,0x62,0x2c, 0x3,0x5b,0x64, 0x4,0x62,0x25, + 0x4,0x62,0x2f, 0x4,0x62,0x28, 0x4,0x62,0x2b, 0x4,0x65,0x2f, + 0x4,0x65,0x31, 0x4,0x65,0x30, 0x3,0x5d,0x54, 0x4,0x67,0x77, + 0x4,0x67,0x79, 0x4,0x67,0x76, 0x4,0x67,0x7c, 0x4,0x67,0x7b, + 0x7,0x56,0x32, 0x4,0x69,0x63, 0x3,0x5f,0x76, 0x4,0x69,0x62, + 0x4,0x6c,0x39, 0x5,0x78,0x48, 0x3,0x61,0x55, 0x4,0x36,0x2b, + 0x4,0x3b,0x7e, 0x3,0x45,0x53, 0x4,0x41,0x6d, 0x4,0x41,0x72, + 0x4,0x41,0x6e, 0x4,0x48,0x51, 0x4,0x48,0x56, 0x4,0x48,0x59, + 0x4,0x48,0x50, 0x4,0x48,0x54, 0x3,0x4a,0x57, 0x4,0x4e,0x60, + 0x4,0x4e,0x61, 0x4,0x54,0x76, 0x4,0x54,0x77, 0x4,0x54,0x73, + 0x4,0x54,0x74, 0x4,0x54,0x75, 0x4,0x59,0x7d, 0x4,0x5a,0x22, + 0x4,0x5a,0x21, 0x4,0x59,0x7c, 0x4,0x59,0x7a, 0x4,0x59,0x7e, + 0x4,0x5e,0x51, 0x7,0x44,0x7e, 0x4,0x5e,0x50, 0x4,0x5e,0x52, + 0x3,0x59,0x5d, 0x3,0x59,0x5e, 0x3,0x59,0x5f, 0x4,0x62,0x32, + 0x3,0x5b,0x67, 0x3,0x5b,0x66, 0x4,0x65,0x36, 0x3,0x5d,0x55, + 0x4,0x67,0x7e, 0x4,0x6b,0x30, 0x4,0x6c,0x3a, 0x3,0x57,0x2b, + 0x3,0x59,0x60, 0x3,0x34,0x3a, 0x4,0x36,0x2c, 0x3,0x40,0x29, + 0x3,0x40,0x2a, 0x4,0x3c,0x24, 0x3,0x40,0x28, 0x4,0x3c,0x25, + 0x3,0x45,0x5d, 0x3,0x40,0x2c, 0x4,0x41,0x77, 0x4,0x41,0x74, + 0x3,0x4a,0x5c, 0x3,0x45,0x5e, 0x4,0x41,0x75, 0x3,0x45,0x56, + 0x3,0x45,0x55, 0x3,0x45,0x5a, 0x4,0x41,0x79, 0x4,0x41,0x7a, + 0x3,0x4a,0x58, 0x3,0x4a,0x59, 0x4,0x48,0x5b, 0x7,0x2b,0x38, + 0x3,0x4a,0x5a, 0x4,0x48,0x5c, 0x6,0x64,0x40, 0x3,0x4f,0x6a, + 0x4,0x4e,0x65, 0x4,0x4e,0x64, 0x4,0x4e,0x67, 0x4,0x4e,0x66, + 0x4,0x54,0x78, 0x4,0x4e,0x69, 0x4,0x54,0x7c, 0x4,0x54,0x7d, + 0x4,0x54,0x7a, 0x4,0x5a,0x27, 0x4,0x55,0x22, 0x4,0x5a,0x28, + 0x4,0x5a,0x2a, 0x5,0x60,0x31, 0x3,0x57,0x2d, 0x3,0x59,0x64, + 0x5,0x60,0x2c, 0x3,0x57,0x2c, 0x4,0x5e,0x58, 0x4,0x5e,0x57, + 0x4,0x5e,0x5b, 0x4,0x5e,0x59, 0x4,0x5e,0x5a, 0x4,0x65,0x39, + 0x4,0x62,0x36, 0x3,0x5b,0x68, 0x4,0x65,0x3c, 0x4,0x65,0x3b, + 0x3,0x5d,0x57, 0x3,0x5d,0x59, 0x4,0x68,0x24, 0x4,0x68,0x23, + 0x3,0x5e,0x7d, 0x4,0x68,0x22, 0x4,0x69,0x67, 0x4,0x69,0x65, + 0x3,0x5f,0x77, 0x4,0x69,0x68, 0x4,0x6b,0x31, 0x3,0x61,0x56, + 0x4,0x6d,0x30, 0x4,0x6d,0x67, 0x4,0x6e,0x25, 0x3,0x4f,0x6c, + 0x3,0x53,0x67, 0x4,0x5e,0x5f, 0x4,0x62,0x3c, 0x4,0x48,0x5d, + 0x3,0x57,0x2f, 0x4,0x55,0x26, 0x3,0x57,0x2e, 0x3,0x61,0x71, + 0x3,0x40,0x2d, 0x5,0x44,0x4a, 0x3,0x45,0x60, 0x4,0x48,0x5e, + 0x3,0x4a,0x65, 0x4,0x48,0x5f, 0x3,0x4a,0x5f, 0x3,0x4a,0x67, + 0x3,0x4a,0x68, 0x3,0x4a,0x6b, 0x3,0x4a,0x69, 0x4,0x4e,0x6f, + 0x3,0x4f,0x71, 0x3,0x4f,0x70, 0x4,0x4e,0x6e, 0x3,0x4f,0x6f, + 0x4,0x4e,0x6d, 0x4,0x4e,0x70, 0x3,0x53,0x6f, 0x3,0x53,0x6e, + 0x3,0x53,0x6d, 0x5,0x5a,0x2c, 0x3,0x53,0x69, 0x4,0x55,0x2d, + 0x5,0x5a,0x2e, 0x7,0x36,0x28, 0x4,0x5a,0x2e, 0x3,0x57,0x32, + 0x3,0x57,0x35, 0x4,0x5a,0x2d, 0x3,0x57,0x31, 0x4,0x5e,0x67, + 0x5,0x6a,0x6e, 0x4,0x5e,0x62, 0x3,0x59,0x68, 0x4,0x5e,0x68, + 0x3,0x59,0x69, 0x4,0x5e,0x63, 0x4,0x5e,0x65, 0x3,0x59,0x6c, + 0x4,0x62,0x41, 0x4,0x62,0x3f, 0x3,0x5b,0x6a, 0x4,0x62,0x46, + 0x4,0x62,0x40, 0x4,0x62,0x44, 0x4,0x62,0x45, 0x4,0x65,0x41, + 0x4,0x65,0x40, 0x3,0x5d,0x5d, 0x3,0x5d,0x5b, 0x4,0x65,0x47, + 0x5,0x6e,0x66, 0x5,0x6e,0x6d, 0x3,0x5d,0x5c, 0x4,0x68,0x29, + 0x4,0x68,0x2a, 0x4,0x68,0x2b, 0x4,0x68,0x2d, 0x3,0x5f,0x23, + 0x5,0x72,0x2d, 0x4,0x68,0x28, 0x7,0x5a,0x3e, 0x5,0x74,0x76, + 0x4,0x69,0x6b, 0x4,0x69,0x69, 0x3,0x5f,0x7a, 0x4,0x6b,0x33, + 0x4,0x6b,0x34, 0x4,0x6b,0x32, 0x3,0x61,0x2b, 0x7,0x60,0x2e, + 0x7,0x60,0x2d, 0x3,0x61,0x57, 0x4,0x6d,0x68, 0x3,0x62,0x27, + 0x4,0x6e,0x3f, 0x3,0x62,0x37, 0x4,0x6e,0x57, 0x3,0x39,0x69, + 0x3,0x40,0x2e, 0x4,0x48,0x62, 0x3,0x4a,0x6d, 0x3,0x4f,0x75, + 0x4,0x4e,0x75, 0x4,0x4e,0x73, 0x4,0x4e,0x76, 0x3,0x4f,0x78, + 0x3,0x53,0x72, 0x3,0x53,0x73, 0x4,0x55,0x30, 0x4,0x55,0x32, + 0x4,0x55,0x2f, 0x4,0x55,0x2e, 0x3,0x57,0x39, 0x4,0x5a,0x31, + 0x4,0x5a,0x35, 0x4,0x5a,0x30, 0x3,0x57,0x38, 0x4,0x5a,0x33, + 0x5,0x66,0x51, 0x4,0x5e,0x6e, 0x3,0x5b,0x70, 0x4,0x62,0x48, + 0x4,0x62,0x47, 0x4,0x65,0x49, 0x3,0x5d,0x5f, 0x4,0x68,0x30, + 0x4,0x69,0x6e, 0x4,0x6b,0x35, 0x4,0x6c,0x3e, 0x4,0x6d,0x33, + 0x3,0x40,0x30, 0x4,0x42,0x22, 0x4,0x62,0x4a, 0x5,0x74,0x7a, + 0x7,0x64,0x75, 0x3,0x40,0x31, 0x5,0x3d,0x52, 0x6,0x64,0x5e, + 0x4,0x48,0x6a, 0x4,0x48,0x69, 0x4,0x48,0x67, 0x3,0x4a,0x74, + 0x5,0x4b,0x59, 0x4,0x4e,0x7b, 0x3,0x4f,0x7a, 0x4,0x55,0x35, + 0x4,0x55,0x36, 0x4,0x5a,0x38, 0x3,0x57,0x3d, 0x4,0x5a,0x3b, + 0x4,0x5e,0x70, 0x4,0x5e,0x73, 0x3,0x59,0x6e, 0x4,0x5e,0x74, + 0x4,0x5e,0x76, 0x4,0x5e,0x75, 0x4,0x5e,0x77, 0x4,0x62,0x4e, + 0x3,0x5b,0x72, 0x4,0x62,0x4c, 0x4,0x65,0x4d, 0x4,0x65,0x4f, + 0x4,0x65,0x4e, 0x7,0x51,0x79, 0x5,0x72,0x3f, 0x3,0x5f,0x26, + 0x4,0x69,0x72, 0x4,0x6c,0x43, 0x4,0x6c,0x41, 0x3,0x61,0x2d, + 0x5,0x78,0x52, 0x4,0x6d,0x35, 0x7,0x61,0x6a, 0x4,0x6d,0x69, + 0x4,0x6e,0x49, 0x7,0x51,0x7d, 0x5,0x72,0x41, 0x3,0x4a,0x77, + 0x3,0x4a,0x76, 0x3,0x4d,0x3e, 0x3,0x53,0x76, 0x7,0x5a,0x4b, + 0x3,0x61,0x58, 0x3,0x4a,0x79, 0x4,0x4f,0x24, 0x4,0x4f,0x25, + 0x4,0x55,0x3f, 0x3,0x53,0x77, 0x4,0x5e,0x7e, 0x3,0x59,0x70, + 0x4,0x5e,0x7d, 0x4,0x5e,0x7c, 0x3,0x5b,0x73, 0x5,0x66,0x68, + 0x3,0x5d,0x65, 0x4,0x69,0x77, 0x4,0x69,0x76, 0x7,0x5a,0x4f, + 0x4,0x6c,0x48, 0x4,0x6c,0x49, 0x4,0x6e,0x58, 0x5,0x3d,0x54, + 0x4,0x48,0x6d, 0x5,0x4b,0x64, 0x4,0x4f,0x28, 0x4,0x4f,0x34, + 0x3,0x50,0x21, 0x7,0x2b,0x6a, 0x4,0x4f,0x39, 0x4,0x4f,0x32, + 0x4,0x4f,0x2b, 0x4,0x4f,0x29, 0x3,0x54,0x27, 0x4,0x55,0x44, + 0x4,0x55,0x42, 0x4,0x55,0x48, 0x3,0x53,0x7e, 0x3,0x54,0x28, + 0x4,0x55,0x41, 0x3,0x54,0x26, 0x3,0x54,0x24, 0x3,0x54,0x22, + 0x3,0x53,0x7b, 0x4,0x5a,0x40, 0x3,0x57,0x41, 0x4,0x5f,0x21, + 0x7,0x3e,0x49, 0x4,0x5a,0x42, 0x3,0x59,0x72, 0x4,0x5f,0x23, + 0x5,0x66,0x6e, 0x4,0x5f,0x27, 0x4,0x5f,0x25, 0x3,0x59,0x78, + 0x4,0x5f,0x24, 0x3,0x59,0x77, 0x4,0x5f,0x29, 0x4,0x5f,0x2b, + 0x4,0x62,0x5d, 0x5,0x6b,0x35, 0x4,0x62,0x67, 0x4,0x62,0x57, + 0x4,0x62,0x61, 0x4,0x62,0x59, 0x4,0x62,0x54, 0x3,0x5b,0x76, + 0x5,0x6b,0x31, 0x4,0x62,0x62, 0x5,0x6b,0x2b, 0x4,0x62,0x60, + 0x4,0x62,0x64, 0x3,0x5b,0x78, 0x3,0x5b,0x7b, 0x3,0x5b,0x7c, + 0xf,0x64,0x72, 0x3,0x5d,0x77, 0x4,0x65,0x55, 0x7,0x52,0x31, + 0x4,0x65,0x5b, 0x3,0x5d,0x6c, 0x7,0x52,0x33, 0x4,0x65,0x53, + 0x3,0x5d,0x6b, 0x3,0x5d,0x6d, 0x4,0x68,0x3d, 0x3,0x5f,0x2d, + 0x3,0x5f,0x30, 0x4,0x68,0x3c, 0x3,0x5f,0x2e, 0x3,0x5f,0x2b, + 0x4,0x68,0x3a, 0x3,0x5f,0x29, 0x3,0x5f,0x2f, 0x4,0x69,0x7d, + 0x3,0x5f,0x7d, 0x4,0x6a,0x21, 0x4,0x69,0x7c, 0x3,0x5f,0x7c, + 0x4,0x69,0x7e, 0x3,0x60,0x24, 0x4,0x69,0x7b, 0x3,0x60,0x21, + 0xf,0x6a,0x3f, 0x4,0x6b,0x3c, 0x4,0x6b,0x3d, 0x4,0x6b,0x40, + 0x4,0x6b,0x3b, 0x7,0x5e,0x23, 0x3,0x60,0x67, 0x3,0x60,0x64, + 0x5,0x78,0x5b, 0x5,0x78,0x56, 0x3,0x61,0x30, 0x4,0x6c,0x4d, + 0x4,0x6c,0x4e, 0x5,0x77,0x24, 0x3,0x61,0x5a, 0x4,0x6d,0x39, + 0x3,0x61,0x31, 0x4,0x6e,0x2c, 0x4,0x6e,0x2d, 0x4,0x6e,0x5b, + 0x3,0x45,0x65, 0x3,0x4a,0x7a, 0x3,0x4a,0x7b, 0x3,0x4a,0x7c, + 0x3,0x4a,0x7e, 0x5,0x4b,0x6b, 0x3,0x4a,0x7d, 0x5,0x53,0x38, + 0x4,0x4f,0x3f, 0x3,0x50,0x23, 0x4,0x4f,0x44, 0x4,0x4f,0x3b, + 0x7,0x2b,0x6d, 0x4,0x4f,0x40, 0x3,0x50,0x28, 0x3,0x50,0x29, + 0x3,0x50,0x26, 0x3,0x4c,0x63, 0x4,0x4f,0x41, 0x4,0x55,0x4e, + 0x3,0x54,0x2f, 0x4,0x55,0x4d, 0x3,0x54,0x30, 0x4,0x55,0x4f, + 0x3,0x54,0x2b, 0x4,0x55,0x54, 0x7,0x36,0x4a, 0x4,0x55,0x4a, + 0x3,0x54,0x2e, 0x4,0x55,0x57, 0x3,0x57,0x4b, 0x4,0x55,0x4b, + 0x3,0x54,0x31, 0x4,0x55,0x55, 0x3,0x54,0x34, 0x4,0x55,0x50, + 0x7,0x36,0x51, 0x3,0x56,0x33, 0x3,0x57,0x4c, 0x4,0x5a,0x51, + 0x3,0x57,0x47, 0x3,0x57,0x49, 0x3,0x57,0x46, 0x4,0x5a,0x52, + 0x3,0x57,0x4e, 0x4,0x5a,0x50, 0x4,0x5f,0x2f, 0x4,0x5f,0x35, + 0x4,0x5f,0x2c, 0x3,0x5a,0x21, 0x3,0x59,0x7c, 0x4,0x5f,0x32, + 0x4,0x5f,0x31, 0x5,0x67,0x26, 0x4,0x5f,0x38, 0x4,0x62,0x6a, + 0x3,0x5c,0x21, 0x4,0x62,0x6c, 0x4,0x65,0x61, 0x3,0x5c,0x28, + 0x4,0x62,0x6f, 0x5,0x6b,0x3c, 0x4,0x5f,0x36, 0xf,0x64,0x75, + 0x3,0x5d,0x78, 0x4,0x65,0x6c, 0x3,0x5d,0x7d, 0x3,0x5d,0x7b, + 0x4,0x65,0x6a, 0x4,0x65,0x64, 0x3,0x5d,0x7c, 0x7,0x52,0x42, + 0x4,0x65,0x62, 0x4,0x65,0x6b, 0x3,0x5d,0x7e, 0x3,0x5f,0x34, + 0x4,0x68,0x40, 0x4,0x68,0x42, 0x4,0x68,0x41, 0x5,0x72,0x63, + 0x3,0x5f,0x33, 0x4,0x6a,0x27, 0x4,0x6a,0x2c, 0x3,0x60,0x28, + 0x4,0x6a,0x26, 0x3,0x60,0x26, 0x3,0x60,0x27, 0x4,0x6b,0x45, + 0x3,0x60,0x6b, 0x5,0x77,0x2c, 0x4,0x6b,0x44, 0x5,0x77,0x34, + 0x4,0x6b,0x47, 0x3,0x60,0x6a, 0x3,0x60,0x69, 0x4,0x6b,0x48, + 0x4,0x6c,0x50, 0x4,0x6c,0x52, 0x4,0x6c,0x51, 0x3,0x61,0x36, + 0x4,0x6c,0x54, 0x4,0x6d,0x3d, 0x3,0x61,0x5c, 0x7,0x63,0x37, + 0x3,0x62,0x2a, 0x3,0x62,0x3e, 0x4,0x6e,0x59, 0x3,0x62,0x43, + 0x4,0x4f,0x47, 0x4,0x5f,0x39, 0x7,0x57,0x29, 0x4,0x6b,0x4d, + 0x5,0x79,0x73, 0x5,0x4b,0x6d, 0x4,0x4f,0x49, 0x4,0x4f,0x4a, + 0x3,0x50,0x2d, 0x3,0x54,0x38, 0x4,0x55,0x58, 0x7,0x36,0x5c, + 0x3,0x5a,0x23, 0x4,0x62,0x72, 0x3,0x5f,0x39, 0x3,0x61,0x37, + 0x3,0x61,0x38, 0x4,0x48,0x73, 0x4,0x48,0x74, 0x3,0x4b,0x21, + 0x4,0x4f,0x4d, 0x4,0x4f,0x4b, 0x4,0x55,0x59, 0x4,0x55,0x5c, + 0x4,0x55,0x5a, 0x4,0x55,0x5d, 0x3,0x57,0x4f, 0x4,0x5f,0x3c, + 0x4,0x5f,0x3b, 0x3,0x5a,0x27, 0x4,0x62,0x79, 0x4,0x62,0x76, + 0x4,0x62,0x7d, 0x4,0x62,0x77, 0x4,0x62,0x7c, 0x4,0x68,0x49, + 0x4,0x68,0x48, 0x4,0x68,0x4a, 0x5,0x75,0x4d, 0x5,0x75,0x48, + 0x4,0x6b,0x4e, 0x3,0x61,0x39, 0x7,0x5a,0x7d, 0x4,0x6d,0x41, + 0x7,0x2c,0x31, 0x4,0x65,0x71, 0x4,0x65,0x72, 0x7,0x36,0x65, + 0x4,0x5f,0x3d, 0x4,0x63,0x21, 0x4,0x65,0x76, 0x4,0x68,0x4b, + 0x4,0x6b,0x52, 0x4,0x6c,0x5a, 0x7,0x2c,0x33, 0x4,0x55,0x5e, + 0x7,0x36,0x67, 0x5,0x6f,0x52, 0x4,0x65,0x79, 0x5,0x6f,0x54, + 0x4,0x68,0x4c, 0x4,0x68,0x4e, 0x4,0x68,0x4d, 0x4,0x6a,0x31, + 0x4,0x6b,0x55, 0x4,0x6d,0x42, 0x4,0x42,0x2c, 0x3,0x4b,0x23, + 0x4,0x4f,0x52, 0x4,0x4f,0x53, 0x4,0x55,0x5f, 0x4,0x5a,0x5f, + 0x5,0x61,0x23, 0x5,0x67,0x40, 0x5,0x67,0x3d, 0x4,0x5f,0x3f, + 0x5,0x67,0x41, 0x4,0x63,0x23, 0x3,0x5c,0x2b, 0x4,0x65,0x7c, + 0x4,0x66,0x21, 0x4,0x65,0x7d, 0x5,0x6f,0x58, 0x4,0x68,0x52, + 0x3,0x5f,0x3b, 0x4,0x6b,0x56, 0x4,0x6c,0x5b, 0x4,0x6d,0x44, + 0x3,0x61,0x5e, 0x4,0x6d,0x43, 0x4,0x6d,0x6f, 0x4,0x5f,0x40, + 0x3,0x5c,0x2c, 0x4,0x6a,0x37, 0x3,0x61,0x3a, 0x4,0x55,0x61, + 0x4,0x6c,0x61, 0x4,0x6c,0x62, 0x4,0x5f,0x43, 0x4,0x5f,0x42, + 0x4,0x5f,0x44, 0x4,0x63,0x26, 0x4,0x68,0x59, 0x4,0x55,0x62, + 0x4,0x5a,0x63, 0x4,0x5f,0x45, 0x4,0x63,0x27, 0x4,0x68,0x5a, + 0x3,0x60,0x2a, 0x4,0x6b,0x58, 0x4,0x6b,0x5b, 0x3,0x5a,0x2c, + 0x4,0x5f,0x46, 0x3,0x5e,0x23, 0x7,0x52,0x67, 0x5,0x6f,0x61, + 0x4,0x68,0x5c, 0x4,0x6e,0x31, 0x5,0x7b,0x7a, 0x4,0x5a,0x66, + 0x5,0x61,0x2d, 0x4,0x5f,0x48, 0x4,0x63,0x29, 0x4,0x63,0x2b, + 0x4,0x66,0x27, 0x4,0x66,0x25, 0x4,0x66,0x26, 0x3,0x5f,0x3d, + 0x4,0x68,0x61, 0x4,0x6a,0x3d, 0x4,0x6a,0x3c, 0x3,0x60,0x6e, + 0x5,0x77,0x4d, 0x4,0x6c,0x69, 0x4,0x6c,0x66, 0x4,0x6c,0x6a, + 0x4,0x6d,0x4c, 0x4,0x6d,0x4b, 0x4,0x6d,0x70, 0x3,0x61,0x76, + 0x3,0x62,0x2b, 0x3,0x62,0x32, 0x4,0x6e,0x4b, 0x4,0x6e,0x4c, + 0x4,0x6e,0x5a, 0x5,0x75,0x61, 0x5,0x6b,0x69, 0x5,0x6c,0x44, + 0x4,0x68,0x62, 0x4,0x68,0x63, 0x4,0x6d,0x51, 0x3,0x62,0x2c, + 0x1,0x44,0x21, 0x1,0x44,0x23, 0x4,0x21,0x26, 0x1,0x44,0x24, + 0x3,0x21,0x26, 0x3,0x21,0x25, 0x2,0x21,0x26, 0x1,0x44,0x37, + 0x1,0x44,0x35, 0x1,0x44,0x38, 0x1,0x44,0x36, 0x2,0x21,0x27, + 0x1,0x44,0x62, 0x2,0x21,0x2f, 0x2,0x21,0x2d, 0x1,0x44,0x61, + 0x1,0x44,0x60, 0x4,0x21,0x39, 0x1,0x45,0x62, 0x1,0x45,0x61, + 0x1,0x45,0x60, 0x4,0x21,0x55, 0x1,0x45,0x63, 0x1,0x45,0x5f, + 0x1,0x47,0x22, 0x1,0x47,0x23, 0x3,0x22,0x62, 0x3,0x22,0x61, + 0x3,0x22,0x63, 0x4,0x23,0x35, 0x3,0x24,0x3f, 0x1,0x4b,0x64, + 0x3,0x21,0x21, 0x4,0x21,0x27, 0x3,0x21,0x2c, 0x1,0x44,0x39, + 0x1,0x44,0x63, 0x2,0x21,0x30, 0x4,0x21,0x3a, 0x1,0x44,0x64, + 0x2,0x21,0x43, 0x1,0x48,0x6b, 0x2,0x25,0x31, 0x4,0x2b,0x5e, + 0x3,0x21,0x22, 0x1,0x44,0x3a, 0x1,0x44,0x65, 0x1,0x45,0x64, + 0x2,0x21,0x44, 0x3,0x27,0x40, 0x3,0x21,0x23, 0x4,0x21,0x22, + 0x4,0x21,0x23, 0x2,0x21,0x21, 0x1,0x44,0x25, 0x1,0x44,0x3c, + 0x3,0x21,0x30, 0x2,0x21,0x28, 0x1,0x44,0x3d, 0x3,0x21,0x2e, + 0x1,0x44,0x66, 0x1,0x45,0x65, 0x1,0x45,0x67, 0x1,0x45,0x66, + 0x4,0x22,0x27, 0x1,0x47,0x24, 0x1,0x47,0x25, 0x3,0x23,0x45, + 0x1,0x4b,0x65, 0x3,0x2b,0x22, 0x1,0x53,0x7d, 0x1,0x44,0x22, + 0x4,0x21,0x24, 0x2,0x21,0x22, 0x1,0x44,0x26, 0x1,0x44,0x3f, + 0x1,0x44,0x3e, 0x3,0x21,0x46, 0x3,0x21,0x45, 0x3,0x22,0x64, + 0x1,0x47,0x26, 0x4,0x22,0x28, 0x3,0x24,0x40, 0x1,0x4b,0x66, + 0x4,0x25,0x31, 0x4,0x25,0x30, 0x3,0x2b,0x23, 0x1,0x58,0x71, + 0x2,0x33,0x4e, 0x3,0x39,0x6c, 0x3,0x39,0x6e, 0x1,0x63,0x2a, + 0x2,0x41,0x56, 0x2,0x41,0x57, 0x3,0x21,0x24, 0x1,0x44,0x27, + 0x3,0x21,0x2d, 0x1,0x44,0x68, 0x3,0x22,0x65, 0x1,0x4b,0x67, + 0x1,0x44,0x28, 0x2,0x21,0x29, 0x1,0x44,0x40, 0x3,0x21,0x31, + 0x1,0x44,0x69, 0x1,0x44,0x6b, 0x2,0x21,0x31, 0x1,0x44,0x6c, + 0x1,0x44,0x6a, 0x4,0x21,0x3b, 0x3,0x21,0x6c, 0x3,0x22,0x66, + 0x1,0x47,0x27, 0x1,0x4b,0x68, 0x3,0x24,0x42, 0x3,0x27,0x42, + 0x1,0x4b,0x69, 0x1,0x4f,0x67, 0x1,0x27,0x28, 0x1,0x44,0x41, + 0x1,0x44,0x6d, 0x3,0x21,0x47, 0x1,0x47,0x28, 0x1,0x47,0x2a, + 0x1,0x47,0x29, 0x1,0x48,0x6c, 0x1,0x4b,0x6a, 0x1,0x4b,0x6b, + 0x1,0x4f,0x68, 0x1,0x4f,0x69, 0x3,0x2b,0x26, 0x3,0x2b,0x25, + 0x3,0x2b,0x27, 0x3,0x2b,0x24, 0x1,0x53,0x7e, 0x4,0x36,0x2e, + 0x2,0x41,0x58, 0x3,0x40,0x33, 0x2,0x6d,0x44, 0x1,0x44,0x29, + 0x3,0x21,0x32, 0x3,0x21,0x33, 0x1,0x44,0x6f, 0x1,0x44,0x6e, + 0x2,0x21,0x32, 0x1,0x44,0x70, 0x1,0x44,0x76, 0x3,0x21,0x49, + 0x1,0x44,0x71, 0x1,0x44,0x72, 0x2,0x21,0x34, 0x2,0x21,0x33, + 0x1,0x44,0x74, 0x1,0x44,0x75, 0x3,0x21,0x4c, 0x1,0x44,0x73, + 0x3,0x21,0x4b, 0x3,0x21,0x4a, 0x4,0x21,0x3c, 0x1,0x45,0x6a, + 0x1,0x45,0x6b, 0x1,0x45,0x6c, 0x1,0x45,0x6d, 0x1,0x45,0x69, + 0x1,0x45,0x70, 0x2,0x21,0x4a, 0x4,0x21,0x5b, 0x2,0x21,0x46, + 0x2,0x21,0x49, 0x1,0x45,0x71, 0x1,0x46,0x23, 0x3,0x21,0x6d, + 0x2,0x21,0x48, 0x4,0x21,0x5a, 0x1,0x45,0x6e, 0x1,0x45,0x6f, + 0x1,0x45,0x68, 0x3,0x21,0x72, 0x3,0x21,0x70, 0x2,0x21,0x45, + 0x2,0x21,0x47, 0x3,0x22,0x6f, 0x3,0x22,0x68, 0x1,0x47,0x37, + 0x2,0x21,0x6f, 0x1,0x47,0x34, 0x1,0x47,0x38, 0x2,0x21,0x79, + 0x2,0x21,0x6d, 0x1,0x47,0x35, 0x2,0x21,0x71, 0x3,0x22,0x6b, + 0x3,0x22,0x67, 0x3,0x22,0x76, 0x1,0x47,0x36, 0x3,0x22,0x6e, + 0x1,0x47,0x39, 0x4,0x22,0x2d, 0x1,0x47,0x2b, 0x2,0x21,0x70, + 0x1,0x47,0x3a, 0x2,0x21,0x74, 0x3,0x22,0x6d, 0x2,0x21,0x78, + 0x2,0x21,0x75, 0x3,0x22,0x6c, 0x3,0x22,0x74, 0x2,0x21,0x72, + 0x1,0x47,0x2c, 0x1,0x47,0x2e, 0x1,0x47,0x3b, 0x4,0x22,0x2a, + 0x1,0x47,0x30, 0x2,0x21,0x6a, 0x1,0x47,0x33, 0x1,0x47,0x31, + 0x1,0x47,0x32, 0x2,0x21,0x7a, 0x2,0x21,0x77, 0x2,0x21,0x6e, + 0x1,0x47,0x2f, 0x3,0x22,0x70, 0x3,0x22,0x77, 0x2,0x21,0x6b, + 0x1,0x47,0x2d, 0x3,0x22,0x75, 0x4,0x22,0x2e, 0x3,0x22,0x73, + 0x2,0x21,0x73, 0x2,0x21,0x76, 0x3,0x22,0x72, 0xf,0x21,0x71, + 0x2,0x21,0x6c, 0x2,0x23,0x28, 0x4,0x23,0x39, 0x1,0x49,0x24, + 0x1,0x48,0x75, 0x3,0x24,0x50, 0x3,0x24,0x48, 0x2,0x23,0x29, + 0x1,0x48,0x72, 0x3,0x24,0x4f, 0x1,0x49,0x26, 0x3,0x24,0x46, + 0x1,0x48,0x7a, 0x3,0x24,0x45, 0x1,0x48,0x79, 0x2,0x22,0x7b, + 0x1,0x48,0x7d, 0x1,0x48,0x78, 0x2,0x23,0x22, 0x2,0x23,0x2a, + 0x3,0x24,0x4e, 0x2,0x23,0x26, 0x3,0x24,0x49, 0x1,0x48,0x7b, + 0x3,0x24,0x4b, 0x3,0x24,0x43, 0x1,0x48,0x7e, 0x1,0x48,0x6f, + 0x1,0x49,0x29, 0x2,0x22,0x7d, 0x3,0x24,0x44, 0x3,0x24,0x4c, + 0x2,0x25,0x3d, 0x1,0x48,0x6d, 0x1,0x49,0x25, 0x1,0x48,0x6e, + 0x1,0x48,0x76, 0x1,0x48,0x77, 0x2,0x23,0x24, 0x2,0x22,0x7e, + 0x1,0x48,0x7c, 0x1,0x48,0x74, 0x2,0x22,0x7a, 0x1,0x48,0x70, + 0x2,0x23,0x27, 0x1,0x49,0x27, 0x1,0x49,0x2a, 0x1,0x48,0x73, + 0x1,0x49,0x22, 0x1,0x49,0x28, 0x1,0x48,0x71, 0x2,0x23,0x25, + 0x1,0x49,0x23, 0x2,0x23,0x2b, 0x2,0x22,0x7c, 0x1,0x49,0x21, + 0x2,0x23,0x21, 0x3,0x64,0x48, 0x2,0x23,0x23, 0x3,0x64,0x49, + 0x1,0x4b,0x79, 0x2,0x25,0x3f, 0x2,0x25,0x4b, 0x1,0x4b,0x71, + 0x3,0x27,0x47, 0x2,0x25,0x4c, 0x1,0x4b,0x6c, 0x1,0x4b,0x76, + 0x4,0x25,0x3e, 0x3,0x27,0x4f, 0x1,0x4b,0x6f, 0x2,0x25,0x39, + 0x1,0x4b,0x77, 0x2,0x25,0x38, 0x2,0x25,0x3c, 0x2,0x25,0x43, + 0x2,0x25,0x41, 0x1,0x4c,0x21, 0x1,0x4b,0x7a, 0x2,0x25,0x33, + 0x2,0x25,0x35, 0x1,0x4b,0x7c, 0x1,0x4b,0x70, 0x2,0x25,0x36, + 0x2,0x25,0x42, 0x2,0x25,0x49, 0x1,0x4b,0x75, 0x2,0x25,0x3b, + 0x2,0x25,0x34, 0x1,0x4b,0x74, 0x2,0x25,0x37, 0x1,0x4b,0x78, + 0x2,0x25,0x3a, 0x3,0x27,0x44, 0x1,0x4b,0x73, 0x3,0x27,0x51, + 0x1,0x4b,0x6e, 0x3,0x27,0x48, 0x1,0x4b,0x7d, 0x2,0x25,0x44, + 0x1,0x4b,0x7e, 0x2,0x25,0x48, 0x3,0x27,0x43, 0x2,0x25,0x46, + 0x2,0x25,0x4a, 0x1,0x4b,0x7b, 0x2,0x25,0x3e, 0x2,0x25,0x32, + 0x4,0x25,0x36, 0x2,0x25,0x40, 0x1,0x4b,0x72, 0x2,0x25,0x45, + 0x1,0x4b,0x6d, 0x2,0x25,0x47, 0x3,0x27,0x4c, 0x3,0x27,0x49, + 0x3,0x27,0x4b, 0x3,0x27,0x4a, 0x3,0x27,0x4d, 0xf,0x25,0x44, + 0x1,0x4f,0x78, 0x1,0x4f,0x6c, 0x3,0x2b,0x2d, 0x3,0x2b,0x2e, + 0x2,0x29,0x22, 0x2,0x29,0x2a, 0x3,0x2b,0x36, 0x1,0x4f,0x6b, + 0x1,0x4f,0x73, 0x1,0x50,0x21, 0x3,0x2b,0x2c, 0x2,0x29,0x30, + 0x2,0x29,0x2e, 0x2,0x29,0x29, 0x4,0x28,0x38, 0x4,0x28,0x3e, + 0x3,0x2b,0x2b, 0x1,0x4f,0x6d, 0x2,0x29,0x2f, 0x2,0x29,0x25, + 0x1,0x4f,0x7b, 0x1,0x4f,0x72, 0x1,0x4f,0x7a, 0x2,0x28,0x7e, + 0x3,0x2b,0x32, 0x2,0x29,0x2c, 0x3,0x2b,0x2f, 0x2,0x29,0x23, + 0x1,0x4f,0x76, 0x2,0x29,0x24, 0x3,0x2b,0x33, 0x2,0x28,0x7d, + 0x1,0x4f,0x7d, 0x1,0x4f,0x70, 0x1,0x4f,0x79, 0x1,0x4f,0x6f, + 0x3,0x2b,0x28, 0x2,0x29,0x21, 0x2,0x29,0x26, 0x3,0x2b,0x29, + 0x2,0x29,0x2d, 0x1,0x4f,0x77, 0x1,0x4f,0x74, 0x2,0x29,0x28, + 0x1,0x4f,0x7c, 0x2,0x29,0x2b, 0x2,0x29,0x27, 0x1,0x4f,0x71, + 0x1,0x4f,0x7e, 0x1,0x4f,0x75, 0x1,0x4f,0x6e, 0x1,0x4f,0x6a, + 0x4,0x28,0x3f, 0x3,0x2b,0x35, 0xf,0x29,0x2d, 0x3,0x2b,0x34, + 0x3,0x64,0x4a, 0x4,0x28,0x3d, 0x2,0x29,0x31, 0x1,0x54,0x3a, + 0x1,0x54,0x24, 0x3,0x2f,0x48, 0x1,0x54,0x34, 0x3,0x2f,0x4d, + 0x1,0x54,0x39, 0x2,0x2d,0x71, 0x2,0x2d,0x70, 0x2,0x2d,0x75, + 0x2,0x2d,0x76, 0x1,0x54,0x27, 0x3,0x2f,0x44, 0x1,0x54,0x30, + 0x3,0x2f,0x58, 0x3,0x2f,0x4c, 0x3,0x2f,0x56, 0x1,0x54,0x3d, + 0x3,0x2f,0x46, 0x1,0x54,0x31, 0x4,0x2b,0x62, 0x3,0x2f,0x4b, + 0x3,0x2f,0x49, 0x3,0x2f,0x47, 0x2,0x2d,0x6a, 0x1,0x54,0x2a, + 0x2,0x2d,0x6b, 0x3,0x2f,0x4f, 0x1,0x54,0x3f, 0x4,0x2b,0x64, + 0x1,0x54,0x36, 0x1,0x54,0x21, 0x1,0x54,0x22, 0x2,0x2d,0x7e, + 0x1,0x59,0x24, 0x3,0x2f,0x53, 0x1,0x54,0x2f, 0x1,0x54,0x2e, + 0x2,0x2d,0x6c, 0x1,0x54,0x32, 0x2,0x33,0x5e, 0x1,0x54,0x29, + 0x2,0x2d,0x77, 0x1,0x54,0x38, 0x1,0x54,0x37, 0x1,0x54,0x2d, + 0x2,0x2d,0x6f, 0x2,0x2d,0x78, 0x3,0x2f,0x45, 0x2,0x2d,0x69, + 0x1,0x54,0x2c, 0x2,0x2d,0x79, 0x1,0x54,0x35, 0x2,0x2d,0x6d, + 0x1,0x54,0x23, 0x3,0x2f,0x4e, 0x1,0x54,0x26, 0x1,0x54,0x25, + 0x2,0x2d,0x7a, 0x1,0x54,0x33, 0x1,0x54,0x28, 0x1,0x54,0x3c, + 0x1,0x54,0x3e, 0x2,0x2d,0x74, 0x1,0x54,0x3b, 0x3,0x2f,0x51, + 0x2,0x2d,0x7c, 0x2,0x2d,0x6e, 0x2,0x2d,0x7d, 0x3,0x2f,0x43, + 0x2,0x2d,0x72, 0x4,0x2b,0x61, 0x2,0x2d,0x7b, 0x3,0x2f,0x50, + 0x2,0x2d,0x73, 0x3,0x2f,0x54, 0x3,0x2f,0x55, 0x1,0x54,0x2b, + 0x3,0x64,0x4b, 0x2,0x33,0x66, 0x2,0x33,0x5a, 0x3,0x34,0x3c, + 0x1,0x58,0x76, 0x3,0x34,0x3f, 0x2,0x33,0x5f, 0x2,0x33,0x65, + 0x1,0x58,0x75, 0x2,0x33,0x58, 0x1,0x58,0x79, 0x2,0x33,0x5c, + 0x2,0x33,0x55, 0x1,0x58,0x77, 0x2,0x33,0x59, 0x1,0x58,0x7c, + 0x1,0x59,0x23, 0x3,0x34,0x44, 0x2,0x33,0x6a, 0x3,0x34,0x41, + 0x2,0x33,0x54, 0x3,0x34,0x42, 0x1,0x58,0x7d, 0x3,0x2f,0x57, + 0x2,0x33,0x69, 0x3,0x34,0x47, 0x3,0x34,0x3d, 0x1,0x58,0x78, + 0x2,0x33,0x5b, 0x1,0x58,0x74, 0x2,0x33,0x56, 0x2,0x33,0x52, + 0x2,0x33,0x60, 0x2,0x33,0x53, 0x2,0x33,0x51, 0x2,0x33,0x5d, + 0x2,0x33,0x63, 0x2,0x33,0x64, 0x1,0x58,0x7a, 0x3,0x34,0x40, + 0x4,0x30,0x47, 0x2,0x3a,0x3f, 0x2,0x33,0x61, 0x2,0x33,0x50, + 0x2,0x33,0x62, 0x3,0x34,0x4b, 0x1,0x59,0x26, 0x2,0x33,0x67, + 0x1,0x59,0x25, 0x2,0x33,0x4f, 0x3,0x34,0x43, 0x2,0x33,0x57, + 0x2,0x33,0x68, 0x1,0x59,0x21, 0x1,0x58,0x7e, 0x1,0x58,0x7b, + 0x1,0x59,0x22, 0x3,0x34,0x4c, 0x3,0x34,0x4a, 0x1,0x58,0x72, + 0x3,0x34,0x45, 0x3,0x34,0x46, 0x1,0x58,0x73, 0x1,0x5e,0x2e, + 0x3,0x39,0x75, 0x2,0x3a,0x42, 0x2,0x3a,0x3b, 0x4,0x36,0x34, + 0x1,0x5e,0x2b, 0x4,0x36,0x33, 0x2,0x3a,0x43, 0x3,0x39,0x71, + 0x3,0x39,0x72, 0x4,0x36,0x36, 0x2,0x3a,0x39, 0x2,0x3a,0x3c, + 0x1,0x5e,0x2a, 0x2,0x3a,0x3d, 0x3,0x39,0x6f, 0x4,0x36,0x31, + 0x1,0x5e,0x2d, 0x2,0x3a,0x41, 0x4,0x36,0x3c, 0x2,0x3a,0x37, + 0x2,0x3a,0x36, 0x1,0x5e,0x2f, 0x3,0x39,0x70, 0x1,0x5e,0x30, + 0x1,0x5e,0x2c, 0x1,0x5e,0x31, 0x2,0x3a,0x35, 0x2,0x3a,0x40, + 0x2,0x3a,0x3e, 0x2,0x3a,0x38, 0x4,0x36,0x39, 0x4,0x36,0x30, + 0x4,0x36,0x3a, 0x1,0x5e,0x29, 0x2,0x3a,0x3a, 0x3,0x64,0x4d, + 0x3,0x40,0x39, 0x3,0x40,0x3c, 0x1,0x63,0x31, 0x1,0x63,0x2b, + 0x2,0x41,0x5c, 0x1,0x63,0x34, 0x2,0x41,0x62, 0x2,0x41,0x65, + 0x1,0x63,0x2d, 0x1,0x63,0x2e, 0x2,0x41,0x5f, 0x1,0x63,0x2c, + 0x2,0x41,0x68, 0x1,0x63,0x32, 0x2,0x41,0x69, 0x3,0x40,0x3a, + 0x2,0x41,0x64, 0x1,0x63,0x33, 0x3,0x40,0x37, 0x2,0x41,0x59, + 0x1,0x63,0x30, 0x2,0x41,0x5a, 0x4,0x3c,0x29, 0x2,0x41,0x63, + 0x2,0x41,0x61, 0x3,0x40,0x3d, 0x2,0x41,0x5d, 0x1,0x63,0x2f, + 0x2,0x41,0x5b, 0x1,0x63,0x35, 0x2,0x41,0x60, 0x2,0x41,0x67, + 0x2,0x41,0x5e, 0x2,0x41,0x66, 0x3,0x40,0x36, 0x3,0x40,0x3e, + 0x1,0x67,0x7c, 0x1,0x67,0x79, 0x3,0x45,0x6b, 0x1,0x67,0x7a, + 0x4,0x42,0x2d, 0x2,0x49,0x21, 0x2,0x48,0x77, 0x1,0x67,0x78, + 0x1,0x67,0x75, 0x2,0x48,0x78, 0x3,0x45,0x6e, 0x3,0x45,0x6c, + 0x1,0x67,0x77, 0x2,0x48,0x7b, 0x3,0x45,0x6d, 0x2,0x48,0x7d, + 0x3,0x45,0x76, 0x4,0x42,0x35, 0x2,0x49,0x26, 0x3,0x45,0x70, + 0x3,0x45,0x75, 0x2,0x49,0x25, 0x2,0x48,0x7e, 0x1,0x67,0x74, + 0x2,0x48,0x76, 0x1,0x67,0x72, 0x2,0x48,0x79, 0x1,0x67,0x7d, + 0x2,0x48,0x7c, 0x3,0x45,0x71, 0x2,0x49,0x22, 0x1,0x67,0x76, + 0x1,0x67,0x73, 0x2,0x49,0x24, 0x2,0x49,0x23, 0x1,0x67,0x7b, + 0x2,0x48,0x7a, 0x3,0x45,0x74, 0x1,0x6c,0x23, 0x2,0x4f,0x54, + 0x3,0x4b,0x29, 0x2,0x4f,0x51, 0x1,0x6c,0x24, 0x4,0x48,0x79, + 0x1,0x6c,0x22, 0x3,0x4b,0x2b, 0x2,0x4f,0x58, 0x2,0x4f,0x55, + 0x2,0x4f,0x4e, 0x1,0x6c,0x21, 0x3,0x4b,0x2d, 0x1,0x6c,0x25, + 0x2,0x4f,0x4f, 0x1,0x6b,0x7e, 0x1,0x6c,0x28, 0x2,0x4f,0x52, + 0x2,0x4f,0x53, 0x1,0x6c,0x26, 0x1,0x6c,0x27, 0x2,0x4f,0x59, + 0x2,0x4f,0x56, 0x2,0x4f,0x57, 0x3,0x4b,0x2c, 0x3,0x4b,0x27, + 0x3,0x64,0x4e, 0x1,0x70,0x33, 0x2,0x56,0x43, 0x1,0x70,0x30, + 0x2,0x56,0x40, 0x1,0x70,0x32, 0x1,0x70,0x34, 0x3,0x50,0x31, + 0x2,0x56,0x41, 0x1,0x70,0x31, 0x4,0x4f,0x5a, 0x2,0x56,0x42, + 0x3,0x50,0x35, 0x2,0x56,0x3f, 0x3,0x50,0x30, 0x3,0x50,0x34, + 0x1,0x73,0x41, 0x2,0x5c,0x49, 0x1,0x73,0x42, 0x2,0x5c,0x47, + 0x4,0x55,0x65, 0x2,0x5c,0x48, 0x2,0x5c,0x46, 0x2,0x5c,0x45, + 0x3,0x54,0x41, 0x3,0x54,0x40, 0x2,0x5c,0x4a, 0x1,0x73,0x40, + 0x3,0x50,0x33, 0x4,0x55,0x69, 0x2,0x61,0x44, 0x2,0x61,0x45, + 0x3,0x57,0x52, 0x2,0x4f,0x50, 0x2,0x61,0x43, 0x1,0x73,0x43, + 0x1,0x78,0x2b, 0x2,0x65,0x37, 0x2,0x65,0x38, 0x3,0x5c,0x32, + 0x1,0x7a,0x62, 0x1,0x7a,0x63, 0x2,0x6b,0x4f, 0x2,0x6b,0x4e, + 0x1,0x7b,0x58, 0x1,0x7b,0x57, 0x2,0x6e,0x7d, 0x3,0x60,0x6f, + 0x1,0x44,0x2a, 0x1,0x44,0x42, 0x1,0x44,0x78, 0x4,0x21,0x3d, + 0x1,0x44,0x77, 0x1,0x45,0x73, 0x1,0x45,0x72, 0x1,0x47,0x3e, + 0x1,0x47,0x3d, 0x1,0x47,0x3f, 0x1,0x47,0x3c, 0x3,0x22,0x78, + 0x1,0x49,0x2c, 0x1,0x49,0x2b, 0x1,0x49,0x2d, 0x3,0x24,0x54, + 0x4,0x23,0x3b, 0x3,0x24,0x53, 0x3,0x24,0x51, 0x1,0x4c,0x23, + 0x4,0x25,0x3f, 0x1,0x4c,0x22, 0x1,0x4c,0x24, 0x3,0x27,0x52, + 0x1,0x50,0x22, 0x4,0x28,0x40, 0x1,0x22,0x79, 0x2,0x2e,0x21, + 0x1,0x22,0x7a, 0x1,0x59,0x27, 0x1,0x22,0x7c, 0x1,0x22,0x7b, + 0x2,0x3a,0x44, 0x3,0x39,0x76, 0x1,0x22,0x7d, 0x1,0x67,0x7e, + 0x1,0x22,0x7e, 0x3,0x5e,0x25, 0x1,0x44,0x2b, 0x3,0x21,0x34, + 0x1,0x44,0x79, 0x1,0x47,0x40, 0x1,0x4c,0x25, 0x3,0x2b,0x37, + 0x1,0x44,0x2c, 0x1,0x44,0x7c, 0x1,0x44,0x7a, 0x1,0x44,0x7b, + 0x1,0x47,0x41, 0x3,0x22,0x7a, 0x4,0x22,0x34, 0x1,0x49,0x2e, + 0x1,0x4c,0x27, 0x1,0x4c,0x26, 0x1,0x4c,0x28, 0x3,0x2e,0x7b, + 0x1,0x54,0x40, 0x3,0x40,0x3f, 0x3,0x64,0x53, 0x1,0x70,0x35, + 0x3,0x21,0x27, 0x4,0x21,0x3e, 0x3,0x21,0x4d, 0x3,0x21,0x48, + 0x3,0x21,0x4e, 0x2,0x21,0x2e, 0x4,0x21,0x52, 0x1,0x45,0x74, + 0x1,0x45,0x75, 0x3,0x21,0x78, 0x3,0x21,0x79, 0x1,0x47,0x42, + 0x4,0x22,0x36, 0x2,0x23,0x2c, 0x3,0x27,0x55, 0x1,0x50,0x24, + 0x1,0x50,0x23, 0x2,0x2e,0x23, 0x2,0x2e,0x22, 0x1,0x59,0x28, + 0x3,0x21,0x28, 0x1,0x44,0x7d, 0x2,0x21,0x35, 0x3,0x21,0x7a, + 0x3,0x24,0x57, 0x2,0x25,0x4d, 0x3,0x2b,0x39, 0x1,0x50,0x25, + 0x3,0x2f,0x5b, 0x1,0x54,0x43, 0x3,0x2f,0x59, 0x1,0x54,0x41, + 0x1,0x54,0x42, 0x3,0x2f,0x5a, 0x3,0x34,0x4d, 0xf,0x46,0x5c, + 0x1,0x70,0x36, 0x1,0x27,0x2f, 0x1,0x45,0x76, 0x4,0x21,0x5e, + 0x1,0x47,0x43, 0x2,0x21,0x7b, 0x3,0x22,0x7e, 0x3,0x22,0x7d, + 0x3,0x22,0x7c, 0x3,0x24,0x59, 0x1,0x49,0x2f, 0x1,0x49,0x30, + 0x3,0x24,0x5a, 0x2,0x23,0x2d, 0x4,0x23,0x3d, 0x2,0x25,0x4e, + 0x1,0x4c,0x29, 0x2,0x25,0x4f, 0x4,0x25,0x40, 0x4,0x25,0x43, + 0x3,0x2b,0x3b, 0x3,0x2b,0x3d, 0x3,0x2b,0x3e, 0x2,0x2e,0x25, + 0x2,0x2e,0x26, 0x1,0x54,0x46, 0x3,0x2f,0x5e, 0x2,0x2e,0x27, + 0x3,0x2f,0x5f, 0x2,0x2e,0x24, 0x1,0x54,0x47, 0x1,0x54,0x45, + 0x1,0x54,0x44, 0x2,0x2e,0x28, 0x3,0x34,0x4f, 0x2,0x33,0x6b, + 0x3,0x34,0x4e, 0x3,0x39,0x7d, 0x3,0x39,0x7a, 0x2,0x3a,0x45, + 0x4,0x36,0x3f, 0x3,0x39,0x7e, 0x2,0x41,0x6a, 0x2,0x49,0x27, + 0x3,0x4b,0x2f, 0x3,0x4b,0x2e, 0x3,0x4b,0x30, 0x1,0x6c,0x29, + 0x1,0x70,0x37, 0x2,0x56,0x44, 0x3,0x54,0x42, 0x1,0x44,0x2d, + 0x1,0x44,0x3b, 0x3,0x21,0x2f, 0x3,0x21,0x35, 0x3,0x21,0x51, + 0x3,0x21,0x7b, 0x3,0x23,0x22, 0xf,0x22,0x59, 0x3,0x24,0x5b, + 0x3,0x27,0x59, 0x4,0x25,0x45, 0x1,0x59,0x29, 0x1,0x5e,0x33, + 0x6,0x46,0x65, 0x1,0x68,0x21, 0x3,0x45,0x7a, 0x2,0x21,0x23, + 0x1,0x44,0x7e, 0x4,0x21,0x60, 0x1,0x45,0x79, 0x1,0x45,0x77, + 0x1,0x45,0x78, 0x1,0x4c,0x2a, 0x3,0x27,0x5a, 0x1,0x44,0x2e, + 0x1,0x44,0x2f, 0x4,0x21,0x2a, 0x1,0x44,0x43, 0x3,0x21,0x36, + 0x3,0x21,0x52, 0x1,0x45,0x21, 0x1,0x45,0x22, 0x1,0x45,0x23, + 0x2,0x21,0x4c, 0x1,0x45,0x7a, 0x3,0x21,0x7d, 0x2,0x21,0x4b, + 0x1,0x47,0x47, 0x3,0x23,0x25, 0x2,0x21,0x7d, 0x1,0x47,0x45, + 0x1,0x47,0x46, 0x2,0x21,0x7c, 0x3,0x23,0x24, 0x3,0x23,0x26, + 0x1,0x47,0x48, 0x1,0x47,0x44, 0x3,0x23,0x27, 0x2,0x23,0x2e, + 0x1,0x4f,0x4f, 0x2,0x23,0x2f, 0x3,0x24,0x5f, 0x3,0x24,0x61, + 0x2,0x23,0x30, 0x4,0x23,0x40, 0x3,0x24,0x5c, 0x1,0x49,0x32, + 0x1,0x49,0x31, 0x3,0x24,0x5e, 0x3,0x24,0x5d, 0x1,0x49,0x35, + 0x1,0x49,0x33, 0x1,0x49,0x34, 0x3,0x24,0x60, 0x1,0x4c,0x30, + 0x3,0x27,0x5b, 0x1,0x4c,0x2f, 0x2,0x25,0x54, 0x2,0x25,0x51, + 0x2,0x25,0x52, 0x3,0x27,0x5e, 0x2,0x25,0x50, 0x1,0x4c,0x31, + 0x1,0x4c,0x2d, 0x1,0x4c,0x2c, 0x3,0x27,0x5f, 0x1,0x4c,0x2e, + 0x1,0x4c,0x2b, 0x3,0x27,0x5d, 0x4,0x25,0x4e, 0x3,0x64,0x4f, + 0x1,0x4c,0x32, 0x1,0x50,0x27, 0x2,0x29,0x32, 0x3,0x2b,0x3f, + 0x2,0x25,0x53, 0x1,0x50,0x2c, 0x3,0x2b,0x40, 0x2,0x29,0x33, + 0x1,0x50,0x28, 0x1,0x50,0x2b, 0x1,0x50,0x2a, 0x1,0x50,0x29, + 0x1,0x50,0x26, 0x3,0x2b,0x43, 0x2,0x2e,0x2b, 0x3,0x2f,0x68, + 0x1,0x54,0x4a, 0x2,0x2e,0x2e, 0x1,0x54,0x48, 0x3,0x2f,0x65, + 0x4,0x2b,0x6e, 0x3,0x2f,0x62, 0x2,0x2e,0x2a, 0x1,0x54,0x4b, + 0x1,0x54,0x49, 0x1,0x54,0x4c, 0x2,0x2e,0x2c, 0x2,0x2e,0x2d, + 0x3,0x2f,0x60, 0x2,0x2e,0x29, 0x2,0x2e,0x2f, 0x3,0x2f,0x66, + 0x3,0x2f,0x61, 0x3,0x2f,0x63, 0xf,0x2e,0x2d, 0x3,0x2f,0x64, + 0x3,0x34,0x50, 0x1,0x5e,0x37, 0x1,0x59,0x2a, 0x2,0x33,0x6c, + 0x2,0x33,0x6e, 0x2,0x33,0x6d, 0x2,0x33,0x6f, 0x1,0x59,0x2b, + 0x3,0x3a,0x23, 0x1,0x5e,0x34, 0x3,0x3a,0x21, 0x1,0x5e,0x35, + 0x1,0x5e,0x36, 0x3,0x34,0x51, 0x1,0x63,0x37, 0x2,0x41,0x6c, + 0x3,0x40,0x41, 0x2,0x41,0x6b, 0x2,0x41,0x6d, 0x2,0x41,0x6e, + 0x1,0x63,0x38, 0x3,0x40,0x40, 0x1,0x63,0x36, 0x2,0x49,0x28, + 0x2,0x49,0x29, 0x1,0x68,0x23, 0x1,0x68,0x22, 0x2,0x4c,0x61, + 0x4,0x49,0x25, 0x3,0x4b,0x31, 0x1,0x6c,0x2a, 0x1,0x6c,0x2b, + 0x1,0x6c,0x2c, 0x1,0x6c,0x2e, 0x2,0x4f,0x5a, 0x2,0x4f,0x5b, + 0x1,0x6c,0x2d, 0x3,0x4b,0x32, 0x3,0x50,0x36, 0x1,0x70,0x38, + 0x4,0x4f,0x64, 0x1,0x70,0x39, 0x3,0x50,0x37, 0x4,0x55,0x6d, + 0x2,0x65,0x39, 0x2,0x6b,0x51, 0x2,0x6b,0x50, 0x2,0x6e,0x7e, + 0x3,0x60,0x2c, 0x1,0x44,0x30, 0x3,0x21,0x37, 0x3,0x21,0x54, + 0x3,0x21,0x53, 0x1,0x45,0x7c, 0x1,0x45,0x7b, 0x1,0x47,0x49, + 0x4,0x22,0x42, 0x4,0x22,0x3f, 0x2,0x21,0x7e, 0x4,0x22,0x41, + 0x3,0x23,0x28, 0x1,0x49,0x37, 0x1,0x49,0x38, 0x1,0x49,0x36, + 0x1,0x49,0x39, 0x2,0x23,0x31, 0x2,0x23,0x32, 0x4,0x23,0x46, + 0x4,0x23,0x47, 0x4,0x23,0x48, 0x3,0x24,0x63, 0x3,0x24,0x62, + 0x3,0x27,0x61, 0x5,0x25,0x3a, 0x5,0x25,0x37, 0x5,0x25,0x38, + 0x3,0x27,0x60, 0x5,0x25,0x3b, 0x1,0x4c,0x34, 0x2,0x25,0x55, + 0x4,0x25,0x50, 0x1,0x4c,0x33, 0x3,0x27,0x62, 0x2,0x29,0x34, + 0x1,0x50,0x30, 0x2,0x29,0x35, 0x1,0x50,0x2f, 0x3,0x2b,0x48, + 0x3,0x2b,0x46, 0x4,0x28,0x49, 0x1,0x50,0x2d, 0x4,0x28,0x4b, + 0x1,0x50,0x2e, 0x3,0x2b,0x47, 0x3,0x2f,0x6f, 0x2,0x2e,0x30, + 0x3,0x2f,0x6c, 0x3,0x2f,0x6a, 0x3,0x2f,0x6d, 0x3,0x2f,0x6e, + 0x1,0x59,0x2c, 0x2,0x33,0x71, 0x3,0x34,0x52, 0x1,0x59,0x2f, + 0x2,0x33,0x70, 0x1,0x5b,0x2b, 0x1,0x59,0x2e, 0x1,0x59,0x2d, + 0x1,0x5e,0x3a, 0x5,0x36,0x6a, 0x1,0x5e,0x39, 0x1,0x5e,0x38, + 0x1,0x63,0x39, 0x3,0x40,0x45, 0x3,0x40,0x44, 0x1,0x63,0x3c, + 0x1,0x63,0x3d, 0x1,0x63,0x3b, 0x4,0x3c,0x3c, 0x1,0x63,0x3a, + 0x3,0x40,0x46, 0x5,0x44,0x67, 0x2,0x49,0x2a, 0x3,0x46,0x21, + 0x2,0x49,0x2b, 0x5,0x44,0x63, 0x3,0x45,0x7e, 0x3,0x4b,0x33, + 0x2,0x4f,0x5d, 0x1,0x6c,0x2f, 0x2,0x4f,0x5c, 0x3,0x4d,0x2c, + 0x1,0x70,0x3a, 0x2,0x5c,0x4b, 0x1,0x73,0x44, 0x5,0x53,0x62, + 0x2,0x65,0x3a, 0x1,0x79,0x61, 0x1,0x27,0x34, 0x1,0x44,0x44, + 0x1,0x45,0x24, 0x2,0x21,0x36, 0x3,0x21,0x55, 0x1,0x45,0x25, + 0x1,0x45,0x26, 0x3,0x21,0x56, 0xf,0x21,0x30, 0x3,0x22,0x23, + 0x3,0x22,0x22, 0x1,0x45,0x7d, 0x1,0x45,0x7e, 0x3,0x22,0x24, + 0x1,0x47,0x4a, 0x2,0x23,0x33, 0x2,0x25,0x56, 0x2,0x25,0x57, + 0x4,0x25,0x51, 0x1,0x50,0x31, 0x2,0x2e,0x31, 0x1,0x59,0x31, + 0x1,0x59,0x30, 0x2,0x3a,0x47, 0x2,0x3a,0x46, 0x6,0x50,0x74, + 0x3,0x50,0x38, 0x1,0x44,0x31, 0x1,0x45,0x27, 0x1,0x46,0x21, + 0x4,0x30,0x5e, 0x1,0x59,0x32, 0x2,0x21,0x24, 0x4,0x21,0x65, + 0x2,0x21,0x4d, 0x1,0x46,0x22, 0x3,0x22,0x26, 0x2,0x22,0x22, + 0x1,0x47,0x4c, 0x1,0x47,0x4b, 0x2,0x22,0x21, 0x1,0x49,0x3a, + 0x3,0x64,0x50, 0x3,0x24,0x65, 0x3,0x2b,0x49, 0x4,0x28,0x4e, + 0x4,0x28,0x50, 0x1,0x54,0x4d, 0x4,0x2b,0x78, 0x4,0x30,0x5f, + 0x2,0x33,0x72, 0x1,0x63,0x3e, 0x2,0x49,0x2c, 0x1,0x68,0x24, + 0x3,0x46,0x23, 0x3,0x4b,0x34, 0x2,0x56,0x45, 0x3,0x54,0x44, + 0x3,0x5c,0x34, 0x2,0x68,0x6a, 0x3,0x21,0x29, 0x1,0x45,0x28, + 0x3,0x21,0x57, 0x3,0x24,0x66, 0x2,0x25,0x58, 0x2,0x29,0x36, + 0x1,0x59,0x35, 0x1,0x59,0x33, 0x1,0x59,0x34, 0x1,0x44,0x32, + 0x4,0x21,0x30, 0x1,0x44,0x45, 0x1,0x24,0x3f, 0x1,0x45,0x2b, + 0x3,0x21,0x59, 0x1,0x45,0x2a, 0x1,0x45,0x29, 0x1,0x46,0x25, + 0x1,0x46,0x24, 0x3,0x23,0x2a, 0x2,0x21,0x4e, 0x2,0x22,0x23, + 0xf,0x22,0x2c, 0x3,0x23,0x2b, 0x3,0x23,0x2d, 0x1,0x4c,0x38, + 0x1,0x4c,0x35, 0x1,0x4c,0x37, 0x1,0x4c,0x36, 0x3,0x27,0x63, + 0x1,0x50,0x32, 0x3,0x2b,0x4a, 0x4,0x30,0x60, 0x1,0x5e,0x3b, + 0x4,0x66,0x30, 0x1,0x44,0x33, 0x3,0x21,0x5a, 0x1,0x45,0x2c, + 0x3,0x22,0x27, 0x1,0x46,0x27, 0x1,0x46,0x26, 0x2,0x23,0x34, + 0x4,0x23,0x4d, 0x3,0x64,0x51, 0x1,0x4c,0x39, 0x3,0x2a,0x5c, + 0x4,0x30,0x64, 0x3,0x21,0x2a, 0x4,0x21,0x31, 0x2,0x21,0x37, + 0x3,0x22,0x28, 0x1,0x46,0x29, 0x1,0x46,0x28, 0x1,0x47,0x4d, + 0x1,0x47,0x4e, 0x2,0x23,0x35, 0x1,0x49,0x3b, 0x3,0x24,0x67, + 0x1,0x49,0x3c, 0x3,0x27,0x65, 0x1,0x4c,0x3a, 0x1,0x4c,0x3b, + 0x1,0x4c,0x3c, 0x3,0x27,0x66, 0x1,0x50,0x33, 0x2,0x29,0x37, + 0x3,0x2b,0x4b, 0x4,0x30,0x65, 0x1,0x54,0x4e, 0x3,0x40,0x47, + 0x2,0x21,0x25, 0x4,0x21,0x44, 0x1,0x45,0x2d, 0x3,0x21,0x5b, + 0x4,0x21,0x67, 0x4,0x21,0x66, 0x3,0x22,0x29, 0x2,0x22,0x24, + 0x3,0x23,0x2f, 0x2,0x23,0x36, 0x2,0x23,0x37, 0x2,0x25,0x59, + 0x3,0x27,0x67, 0x2,0x25,0x5a, 0x2,0x29,0x39, 0x2,0x29,0x38, + 0x2,0x29,0x3b, 0x2,0x29,0x3a, 0x1,0x50,0x34, 0x3,0x64,0x52, + 0x2,0x33,0x73, 0x1,0x54,0x50, 0x2,0x2e,0x32, 0x1,0x54,0x4f, + 0x3,0x34,0x54, 0x4,0x30,0x68, 0x2,0x3a,0x48, 0x1,0x5e,0x3c, + 0x3,0x3a,0x28, 0x2,0x3a,0x49, 0x3,0x3a,0x27, 0x3,0x40,0x4a, + 0x3,0x40,0x49, 0x3,0x40,0x48, 0x2,0x49,0x2d, 0x1,0x68,0x25, + 0x3,0x46,0x25, 0x4,0x3c,0x40, 0x3,0x46,0x26, 0x3,0x4b,0x35, + 0x1,0x6c,0x30, 0x3,0x54,0x45, 0x2,0x65,0x3b, 0xf,0x6d,0x2e, + 0x3,0x21,0x2b, 0x3,0x21,0x5c, 0x4,0x21,0x45, 0x2,0x21,0x38, + 0x3,0x22,0x2a, 0x1,0x46,0x2a, 0x4,0x22,0x48, 0x3,0x23,0x31, + 0x4,0x25,0x59, 0x3,0x27,0x69, 0x3,0x27,0x6a, 0x1,0x59,0x36, + 0x3,0x34,0x55, 0x3,0x3a,0x29, 0x1,0x44,0x34, 0x1,0x44,0x46, + 0x1,0x45,0x2f, 0x1,0x45,0x2e, 0x3,0x21,0x5e, 0x1,0x45,0x30, + 0x3,0x21,0x60, 0x4,0x21,0x69, 0x3,0x22,0x2b, 0x3,0x23,0x33, + 0x4,0x23,0x4f, 0x1,0x4c,0x3e, 0x3,0x27,0x6b, 0x1,0x4c,0x3d, + 0x1,0x4c,0x3f, 0x3,0x2b,0x50, 0x3,0x2b,0x4f, 0x1,0x50,0x35, + 0x3,0x2b,0x4e, 0x3,0x2b,0x4d, 0x6,0x35,0x78, 0x1,0x54,0x51, + 0x3,0x40,0x4b, 0x2,0x56,0x46, 0x1,0x76,0x3b, 0x1,0x44,0x47, + 0x1,0x46,0x2c, 0x1,0x46,0x3b, 0x1,0x46,0x36, 0x4,0x21,0x6c, + 0x1,0x46,0x31, 0x1,0x46,0x30, 0x1,0x46,0x37, 0x1,0x46,0x35, + 0x1,0x46,0x2e, 0x1,0x46,0x3c, 0x1,0x46,0x2f, 0x1,0x46,0x2b, + 0x1,0x46,0x3a, 0x1,0x46,0x39, 0x1,0x46,0x38, 0x1,0x46,0x2d, + 0x3,0x22,0x31, 0x1,0x46,0x34, 0x3,0x22,0x2d, 0x3,0x22,0x2e, + 0x1,0x46,0x33, 0x3,0x22,0x2f, 0xf,0x21,0x50, 0x1,0x46,0x3d, + 0x1,0x46,0x32, 0x4,0x21,0x6a, 0x3,0x23,0x35, 0x3,0x23,0x37, + 0x1,0x47,0x54, 0x4,0x22,0x4c, 0x1,0x47,0x5a, 0x1,0x47,0x56, + 0x3,0x23,0x39, 0x1,0x47,0x5c, 0x2,0x22,0x25, 0x1,0x47,0x59, + 0x1,0x47,0x4f, 0x1,0x47,0x52, 0x1,0x47,0x55, 0x1,0x47,0x51, + 0x1,0x47,0x58, 0x1,0x47,0x5b, 0x1,0x47,0x50, 0x1,0x47,0x53, + 0x1,0x47,0x57, 0x1,0x47,0x5d, 0x3,0x23,0x3a, 0x3,0x23,0x3b, + 0x3,0x23,0x34, 0x2,0x23,0x40, 0x2,0x23,0x3d, 0x3,0x24,0x76, + 0x1,0x49,0x49, 0x2,0x23,0x3e, 0x1,0x49,0x3d, 0x1,0x49,0x3f, + 0x1,0x49,0x57, 0x1,0x49,0x52, 0x3,0x24,0x79, 0x3,0x24,0x7e, + 0x3,0x24,0x75, 0x2,0x23,0x45, 0x2,0x23,0x3f, 0x1,0x49,0x41, + 0x1,0x49,0x43, 0x2,0x23,0x44, 0x1,0x49,0x4a, 0x2,0x23,0x3a, + 0x1,0x49,0x56, 0x1,0x49,0x58, 0x1,0x49,0x3e, 0x1,0x49,0x4f, + 0x3,0x25,0x24, 0x2,0x23,0x38, 0x1,0x49,0x55, 0x3,0x24,0x77, + 0x1,0x49,0x46, 0x3,0x24,0x7b, 0x1,0x49,0x50, 0x1,0x49,0x51, + 0x2,0x23,0x39, 0x1,0x49,0x4e, 0x1,0x49,0x4c, 0x3,0x24,0x70, + 0x1,0x49,0x4d, 0x1,0x49,0x53, 0x2,0x23,0x41, 0x1,0x49,0x40, + 0x3,0x25,0x21, 0x1,0x49,0x54, 0x2,0x23,0x43, 0x1,0x49,0x48, + 0x1,0x49,0x45, 0x3,0x24,0x73, 0x2,0x23,0x3c, 0x1,0x49,0x44, + 0x2,0x23,0x46, 0x1,0x49,0x47, 0x3,0x24,0x7c, 0x1,0x49,0x4b, + 0x3,0x24,0x78, 0x3,0x24,0x74, 0x3,0x24,0x6d, 0x1,0x49,0x42, + 0x2,0x23,0x42, 0x3,0x24,0x7d, 0x3,0x25,0x22, 0x2,0x23,0x3b, + 0x3,0x25,0x23, 0x4,0x25,0x64, 0x4,0x25,0x63, 0x3,0x27,0x6e, + 0x2,0x25,0x6b, 0x2,0x25,0x6a, 0x1,0x4c,0x51, 0x2,0x25,0x6d, + 0x2,0x25,0x6f, 0x2,0x25,0x64, 0x2,0x25,0x67, 0x2,0x25,0x6e, + 0x1,0x4c,0x52, 0x3,0x27,0x74, 0x3,0x27,0x78, 0x2,0x25,0x61, + 0x2,0x25,0x65, 0x3,0x27,0x75, 0x4,0x25,0x5f, 0x2,0x25,0x69, + 0x2,0x29,0x4a, 0x1,0x4c,0x4d, 0x2,0x29,0x4e, 0x1,0x4c,0x40, + 0x2,0x25,0x66, 0x1,0x4c,0x41, 0x1,0x4c,0x4e, 0x1,0x4c,0x47, + 0x1,0x4c,0x43, 0x3,0x27,0x71, 0x2,0x25,0x62, 0x1,0x4c,0x46, + 0x1,0x4c,0x4b, 0x1,0x4c,0x54, 0x2,0x25,0x63, 0x2,0x25,0x5c, + 0x1,0x4c,0x45, 0x2,0x25,0x5d, 0x2,0x25,0x5f, 0x4,0x25,0x60, + 0x1,0x4c,0x48, 0x3,0x27,0x6c, 0x1,0x4c,0x4a, 0x2,0x25,0x5b, + 0x2,0x25,0x60, 0x3,0x27,0x70, 0x3,0x27,0x79, 0x1,0x4c,0x53, + 0x1,0x4c,0x4f, 0x2,0x25,0x68, 0x1,0x4c,0x55, 0x3,0x27,0x73, + 0x1,0x4c,0x4c, 0x2,0x25,0x5e, 0x1,0x4c,0x49, 0x3,0x27,0x6f, + 0x3,0x27,0x77, 0x1,0x4c,0x44, 0x1,0x4c,0x42, 0x2,0x25,0x6c, + 0x1,0x4c,0x50, 0xf,0x25,0x71, 0x3,0x2b,0x5c, 0x3,0x2b,0x5d, + 0x2,0x29,0x49, 0x2,0x29,0x3d, 0x2,0x29,0x4c, 0x3,0x2b,0x57, + 0x3,0x2b,0x59, 0x2,0x29,0x3f, 0x1,0x50,0x3c, 0x1,0x50,0x4a, + 0x1,0x50,0x38, 0x1,0x50,0x49, 0x1,0x50,0x41, 0x1,0x50,0x46, + 0x1,0x50,0x36, 0x2,0x29,0x3e, 0x2,0x29,0x44, 0x1,0x50,0x45, + 0x2,0x29,0x50, 0x1,0x50,0x47, 0x3,0x2b,0x5b, 0x1,0x50,0x3d, + 0x3,0x2b,0x54, 0x3,0x2b,0x5e, 0x2,0x29,0x46, 0x2,0x29,0x43, + 0x1,0x50,0x3b, 0x3,0x2b,0x51, 0x2,0x29,0x3c, 0x1,0x50,0x48, + 0x2,0x29,0x4b, 0x1,0x50,0x40, 0x2,0x29,0x4d, 0x1,0x50,0x4b, + 0x1,0x50,0x37, 0x1,0x50,0x42, 0x1,0x50,0x3f, 0x2,0x29,0x41, + 0x1,0x50,0x43, 0x2,0x29,0x47, 0x2,0x29,0x48, 0x1,0x50,0x3e, + 0x1,0x50,0x44, 0x1,0x50,0x3a, 0x3,0x2b,0x55, 0x3,0x64,0x54, + 0x3,0x2b,0x63, 0x3,0x2b,0x61, 0x1,0x50,0x39, 0x2,0x29,0x40, + 0x3,0x2b,0x53, 0x2,0x29,0x45, 0x3,0x2b,0x58, 0x2,0x29,0x4f, + 0x2,0x2e,0x46, 0x1,0x54,0x5e, 0x2,0x2e,0x34, 0x4,0x2c,0x2d, + 0x2,0x2e,0x39, 0x1,0x54,0x57, 0x1,0x54,0x62, 0x2,0x2e,0x37, + 0x1,0x54,0x52, 0x1,0x54,0x5c, 0x1,0x54,0x61, 0x2,0x2e,0x3e, + 0x4,0x2c,0x26, 0x1,0x54,0x5d, 0x1,0x54,0x60, 0x3,0x2f,0x77, + 0x3,0x30,0x21, 0x2,0x2e,0x41, 0x1,0x54,0x58, 0x2,0x2e,0x38, + 0x3,0x2f,0x74, 0x3,0x2f,0x78, 0x3,0x30,0x22, 0x2,0x2e,0x44, + 0x2,0x2e,0x45, 0x3,0x2f,0x79, 0x1,0x54,0x5a, 0x2,0x2e,0x43, + 0x1,0x54,0x56, 0x1,0x54,0x65, 0x4,0x2c,0x29, 0x2,0x2e,0x3b, + 0x3,0x2f,0x7b, 0x1,0x54,0x54, 0x3,0x2f,0x7a, 0x2,0x2e,0x48, + 0x2,0x2e,0x3c, 0x2,0x2e,0x40, 0x1,0x54,0x59, 0x1,0x54,0x64, + 0x2,0x2e,0x3d, 0x1,0x54,0x5f, 0x2,0x2e,0x42, 0x2,0x2e,0x49, + 0x2,0x34,0x24, 0x3,0x2f,0x73, 0x2,0x2e,0x47, 0x1,0x54,0x66, + 0x1,0x54,0x53, 0x2,0x2e,0x3f, 0x2,0x2e,0x36, 0x3,0x2f,0x76, + 0x1,0x54,0x5b, 0x4,0x2c,0x28, 0x4,0x2c,0x2e, 0x2,0x2e,0x35, + 0x3,0x2f,0x7e, 0x3,0x30,0x25, 0x2,0x2e,0x3a, 0xf,0x29,0x54, + 0xf,0x2e,0x42, 0xf,0x2e,0x4a, 0x2,0x2e,0x33, 0x1,0x54,0x63, + 0x3,0x67,0x21, 0x3,0x34,0x5f, 0x2,0x33,0x7a, 0x3,0x34,0x68, + 0x1,0x59,0x49, 0x2,0x34,0x2a, 0x1,0x59,0x47, 0x1,0x59,0x44, + 0x2,0x34,0x21, 0x1,0x59,0x40, 0x2,0x34,0x25, 0x1,0x59,0x4b, + 0x2,0x33,0x79, 0x2,0x33,0x7e, 0x2,0x33,0x7d, 0x1,0x54,0x55, + 0x1,0x59,0x46, 0x2,0x34,0x28, 0x3,0x34,0x66, 0x2,0x34,0x2b, + 0x2,0x33,0x76, 0x4,0x30,0x77, 0x1,0x5e,0x4e, 0x3,0x34,0x67, + 0x2,0x34,0x2c, 0x1,0x59,0x4c, 0x4,0x30,0x72, 0x1,0x59,0x3e, + 0x1,0x59,0x3b, 0x2,0x34,0x23, 0x1,0x59,0x38, 0x4,0x30,0x74, + 0x2,0x34,0x29, 0x3,0x34,0x5b, 0x1,0x59,0x3f, 0x2,0x34,0x2d, + 0x3,0x34,0x58, 0x2,0x33,0x77, 0x2,0x34,0x27, 0x1,0x59,0x42, + 0x2,0x33,0x78, 0x2,0x33,0x7b, 0x2,0x34,0x22, 0x3,0x34,0x62, + 0x3,0x34,0x61, 0x1,0x59,0x43, 0x1,0x59,0x41, 0x1,0x59,0x4d, + 0x3,0x34,0x57, 0x3,0x3a,0x36, 0x3,0x34,0x64, 0x4,0x30,0x6b, + 0x1,0x59,0x48, 0x3,0x34,0x5e, 0x1,0x59,0x3c, 0x1,0x5a,0x76, + 0x4,0x30,0x7a, 0x1,0x59,0x3d, 0x2,0x33,0x7c, 0x1,0x59,0x4a, + 0x1,0x59,0x45, 0x2,0x34,0x26, 0x1,0x59,0x3a, 0x3,0x34,0x59, + 0x1,0x59,0x39, 0x3,0x64,0x57, 0x3,0x64,0x56, 0x3,0x67,0x22, + 0x3,0x64,0x55, 0x2,0x33,0x74, 0x2,0x33,0x75, 0x2,0x3a,0x4e, + 0x3,0x3a,0x3c, 0x1,0x5e,0x3d, 0x1,0x5e,0x40, 0x2,0x3a,0x59, + 0x1,0x5e,0x54, 0x2,0x3a,0x5c, 0x1,0x5e,0x3e, 0x2,0x3a,0x55, + 0x1,0x5e,0x44, 0x1,0x5e,0x4a, 0x1,0x61,0x43, 0x3,0x3a,0x31, + 0x3,0x3a,0x38, 0x1,0x5e,0x48, 0x2,0x3a,0x52, 0x1,0x5e,0x55, + 0x1,0x5e,0x41, 0x1,0x5e,0x49, 0x2,0x3a,0x5a, 0x2,0x41,0x7c, + 0x2,0x3a,0x5f, 0x2,0x3a,0x53, 0x4,0x36,0x5c, 0x2,0x3a,0x4a, + 0x2,0x3a,0x57, 0x2,0x3a,0x51, 0x1,0x5e,0x47, 0x2,0x3a,0x5d, + 0x3,0x3a,0x2e, 0x3,0x3a,0x2a, 0x1,0x5e,0x43, 0x1,0x5e,0x57, + 0x1,0x5e,0x50, 0x3,0x3a,0x33, 0x1,0x5e,0x45, 0x1,0x5e,0x42, + 0x3,0x3a,0x40, 0x1,0x5e,0x4d, 0x3,0x3a,0x34, 0x2,0x3a,0x5e, + 0x2,0x3a,0x50, 0x2,0x3a,0x56, 0x2,0x3a,0x58, 0x2,0x3a,0x4c, + 0x2,0x3a,0x5b, 0x1,0x5e,0x3f, 0x2,0x3a,0x4b, 0x3,0x3a,0x42, + 0x1,0x5e,0x46, 0x1,0x5e,0x56, 0x1,0x5e,0x52, 0x2,0x3a,0x4d, + 0x1,0x5e,0x4c, 0x3,0x3a,0x3b, 0xf,0x39,0x71, 0x1,0x5e,0x53, + 0x1,0x5e,0x4f, 0x1,0x5e,0x4b, 0x3,0x3a,0x2f, 0x2,0x3a,0x54, + 0x6,0x47,0x29, 0x3,0x67,0x23, 0x1,0x5e,0x51, 0x2,0x41,0x7a, + 0x2,0x41,0x76, 0x3,0x40,0x51, 0x2,0x42,0x27, 0x2,0x41,0x6f, + 0x2,0x41,0x78, 0x1,0x63,0x4c, 0x1,0x63,0x4d, 0x1,0x63,0x45, + 0x2,0x42,0x23, 0x1,0x63,0x4f, 0x2,0x41,0x74, 0x2,0x41,0x73, + 0x2,0x41,0x71, 0x2,0x42,0x25, 0x1,0x63,0x43, 0x2,0x41,0x7d, + 0x2,0x41,0x72, 0x1,0x63,0x46, 0x2,0x41,0x7b, 0x1,0x63,0x41, + 0x2,0x41,0x77, 0x2,0x41,0x7e, 0x2,0x42,0x22, 0x3,0x40,0x4e, + 0x4,0x3c,0x4b, 0x2,0x42,0x26, 0x1,0x63,0x4a, 0x2,0x41,0x70, + 0x1,0x63,0x44, 0x2,0x41,0x75, 0x3,0x3a,0x2b, 0x1,0x63,0x3f, + 0x6,0x51,0x43, 0x1,0x63,0x4b, 0x2,0x42,0x21, 0x1,0x63,0x47, + 0x1,0x63,0x48, 0x1,0x63,0x4e, 0x1,0x63,0x42, 0x1,0x23,0x21, + 0x1,0x63,0x40, 0x2,0x41,0x79, 0x3,0x40,0x4c, 0x3,0x67,0x25, + 0x1,0x63,0x49, 0x3,0x67,0x24, 0xf,0x40,0x62, 0x2,0x42,0x24, + 0x3,0x64,0x58, 0x1,0x68,0x35, 0x1,0x68,0x30, 0x3,0x46,0x2e, + 0x2,0x49,0x3c, 0x2,0x49,0x38, 0x3,0x46,0x28, 0x2,0x49,0x32, + 0x1,0x68,0x2a, 0x1,0x68,0x26, 0x2,0x49,0x3b, 0x1,0x68,0x27, + 0x2,0x49,0x35, 0x2,0x49,0x37, 0x3,0x46,0x29, 0x2,0x49,0x3a, + 0x3,0x46,0x36, 0x1,0x68,0x2c, 0x3,0x46,0x2c, 0x1,0x68,0x33, + 0x1,0x68,0x2d, 0x4,0x42,0x57, 0x3,0x46,0x2a, 0x2,0x49,0x30, + 0x1,0x68,0x2e, 0x1,0x68,0x2f, 0x2,0x49,0x33, 0x1,0x68,0x34, + 0x3,0x46,0x34, 0x2,0x49,0x31, 0x2,0x49,0x36, 0x1,0x68,0x2b, + 0x2,0x49,0x2f, 0x1,0x68,0x31, 0x1,0x68,0x29, 0x3,0x46,0x33, + 0x4,0x42,0x4b, 0x1,0x68,0x28, 0x2,0x49,0x34, 0x2,0x49,0x39, + 0x3,0x46,0x31, 0x1,0x68,0x32, 0x3,0x64,0x5a, 0x3,0x64,0x59, + 0x3,0x46,0x50, 0x2,0x49,0x2e, 0x3,0x46,0x30, 0x1,0x6c,0x37, + 0x2,0x4f,0x6e, 0x3,0x4b,0x41, 0x2,0x4f,0x6b, 0x3,0x4b,0x38, + 0x1,0x6c,0x31, 0x1,0x6c,0x3d, 0x1,0x6c,0x3e, 0x3,0x4b,0x3d, + 0x1,0x6c,0x34, 0x2,0x4f,0x69, 0x1,0x6c,0x36, 0x2,0x4f,0x61, + 0x1,0x6c,0x3c, 0x3,0x4b,0x44, 0x2,0x4f,0x6d, 0x1,0x6c,0x33, + 0x2,0x4f,0x6f, 0x1,0x6c,0x32, 0x4,0x49,0x31, 0x2,0x4f,0x6a, + 0x2,0x4f,0x6c, 0x1,0x6c,0x35, 0x2,0x4f,0x68, 0x2,0x4f,0x62, + 0x2,0x4f,0x5f, 0x4,0x49,0x2e, 0x3,0x4b,0x3e, 0x2,0x3a,0x4f, + 0x2,0x4f,0x65, 0x3,0x4b,0x37, 0x2,0x4f,0x5e, 0x2,0x4f,0x64, + 0x2,0x4f,0x63, 0x3,0x4b,0x3b, 0x2,0x4f,0x60, 0x3,0x4b,0x43, + 0x1,0x6c,0x39, 0x3,0x4b,0x45, 0x3,0x4b,0x40, 0x3,0x46,0x35, + 0x3,0x4b,0x3c, 0x1,0x6c,0x38, 0x3,0x4b,0x39, 0x7,0x21,0x63, + 0x3,0x4b,0x3f, 0x1,0x6c,0x3a, 0x2,0x4f,0x66, 0x1,0x70,0x3b, + 0x2,0x4f,0x67, 0x2,0x56,0x4f, 0x3,0x50,0x3f, 0x2,0x56,0x48, + 0x3,0x50,0x40, 0x1,0x70,0x47, 0x2,0x56,0x4c, 0x1,0x70,0x3f, + 0x1,0x70,0x43, 0x2,0x56,0x4b, 0x3,0x50,0x3b, 0x1,0x70,0x42, + 0x1,0x70,0x3e, 0x1,0x70,0x41, 0x1,0x70,0x3c, 0x1,0x70,0x46, + 0x2,0x56,0x4d, 0x2,0x56,0x49, 0x1,0x70,0x45, 0x2,0x56,0x47, + 0x1,0x70,0x44, 0x2,0x56,0x4e, 0x2,0x56,0x4a, 0x1,0x6c,0x3b, + 0x4,0x4f,0x71, 0x1,0x70,0x48, 0x2,0x56,0x50, 0x1,0x70,0x40, + 0x1,0x70,0x3d, 0xf,0x53,0x5d, 0x3,0x50,0x3d, 0x3,0x54,0x48, + 0x2,0x5c,0x52, 0x2,0x5c,0x54, 0x1,0x73,0x46, 0x2,0x5c,0x55, + 0x2,0x5c,0x53, 0x2,0x5c,0x51, 0x2,0x5c,0x50, 0x1,0x73,0x48, + 0x2,0x5c,0x4f, 0x1,0x73,0x49, 0x4,0x55,0x74, 0x3,0x54,0x49, + 0x3,0x54,0x47, 0x4,0x55,0x78, 0x2,0x5c,0x4d, 0x2,0x5c,0x4e, + 0x1,0x73,0x45, 0x1,0x73,0x4a, 0x1,0x73,0x47, 0x3,0x64,0x5d, + 0x3,0x64,0x5b, 0x2,0x5c,0x4c, 0x3,0x57,0x5b, 0x1,0x76,0x3c, + 0x3,0x57,0x5a, 0x2,0x61,0x48, 0x2,0x61,0x46, 0x2,0x61,0x4b, + 0x2,0x61,0x49, 0x3,0x57,0x58, 0x2,0x61,0x47, 0x2,0x61,0x4a, + 0x3,0x57,0x59, 0x3,0x57,0x57, 0x3,0x57,0x5c, 0x1,0x78,0x2c, + 0x2,0x65,0x3e, 0x2,0x65,0x3f, 0x1,0x78,0x2d, 0x4,0x5f,0x4d, + 0x2,0x65,0x40, 0x2,0x65,0x3c, 0x2,0x65,0x41, 0x2,0x65,0x3d, + 0x1,0x76,0x3d, 0x3,0x5a,0x2d, 0x3,0x64,0x5e, 0x4,0x63,0x31, + 0x2,0x68,0x6b, 0x2,0x68,0x6d, 0x1,0x79,0x64, 0x2,0x68,0x6c, + 0x1,0x79,0x63, 0x1,0x79,0x62, 0x3,0x67,0x26, 0x3,0x67,0x27, + 0x3,0x64,0x5c, 0x3,0x5e,0x26, 0x1,0x79,0x65, 0x2,0x6b,0x53, + 0x2,0x6b,0x54, 0x4,0x66,0x34, 0x1,0x7a,0x65, 0x1,0x7a,0x64, + 0x1,0x7a,0x66, 0x2,0x6b,0x52, 0x3,0x67,0x28, 0x2,0x6d,0x46, + 0x2,0x6d,0x45, 0x3,0x5f,0x40, 0x1,0x7b,0x59, 0x1,0x7b,0x5b, + 0x1,0x7b,0x5a, 0x2,0x6d,0x47, 0x1,0x7c,0x34, 0x2,0x70,0x34, + 0x4,0x6a,0x44, 0x4,0x6a,0x43, 0x1,0x7c,0x5d, 0x3,0x60,0x71, + 0x2,0x70,0x33, 0x2,0x70,0x7c, 0x2,0x21,0x2a, 0x3,0x21,0x77, + 0x4,0x21,0x6f, 0x1,0x46,0x3f, 0x1,0x46,0x3e, 0x4,0x21,0x6d, + 0x1,0x47,0x60, 0x1,0x47,0x5f, 0x2,0x22,0x27, 0x1,0x47,0x5e, + 0x2,0x22,0x26, 0x3,0x23,0x3e, 0x1,0x49,0x5b, 0x2,0x23,0x49, + 0x3,0x25,0x2c, 0x2,0x23,0x48, 0xf,0x23,0x50, 0x3,0x25,0x26, + 0x1,0x49,0x59, 0x1,0x49,0x5c, 0x3,0x25,0x2b, 0x3,0x25,0x2a, + 0x2,0x23,0x47, 0x3,0x25,0x29, 0x1,0x49,0x5a, 0x3,0x25,0x48, + 0x3,0x25,0x27, 0x3,0x25,0x28, 0x3,0x28,0x22, 0x2,0x25,0x70, + 0x3,0x27,0x7d, 0x2,0x25,0x71, 0x1,0x4c,0x56, 0x3,0x27,0x7c, + 0x3,0x28,0x21, 0x3,0x27,0x7b, 0x1,0x50,0x4c, 0x3,0x2b,0x65, + 0x2,0x2e,0x4a, 0x2,0x2e,0x4b, 0x1,0x54,0x67, 0x1,0x54,0x68, + 0x3,0x30,0x27, 0x2,0x34,0x2f, 0x1,0x59,0x4e, 0x1,0x59,0x50, + 0x2,0x34,0x2e, 0x1,0x59,0x4f, 0x2,0x3a,0x60, 0x1,0x5e,0x58, + 0x3,0x3a,0x44, 0x3,0x3a,0x43, 0x4,0x36,0x68, 0x4,0x3c,0x52, + 0x1,0x63,0x50, 0x1,0x63,0x51, 0x2,0x42,0x28, 0x3,0x40,0x52, + 0x1,0x68,0x37, 0x3,0x46,0x37, 0x1,0x68,0x36, 0x2,0x4f,0x70, + 0x2,0x56,0x52, 0x2,0x56,0x51, 0x3,0x5f,0x41, 0x2,0x71,0x5a, + 0x1,0x44,0x48, 0x2,0x21,0x39, 0x3,0x21,0x61, 0x2,0x21,0x4f, + 0x2,0x21,0x50, 0x3,0x22,0x34, 0x4,0x21,0x70, 0x4,0x21,0x71, + 0x1,0x47,0x63, 0x1,0x47,0x67, 0x2,0x22,0x29, 0x4,0x22,0x51, + 0x1,0x47,0x65, 0x1,0x47,0x64, 0x2,0x22,0x28, 0x1,0x47,0x66, + 0x1,0x47,0x62, 0x3,0x23,0x41, 0x3,0x23,0x42, 0x1,0x47,0x61, + 0x2,0x22,0x2a, 0x3,0x23,0x3f, 0x3,0x23,0x40, 0x1,0x49,0x66, + 0x3,0x25,0x31, 0x3,0x25,0x3e, 0x1,0x49,0x63, 0x3,0x25,0x30, + 0x1,0x49,0x5f, 0x2,0x23,0x4a, 0x3,0x25,0x40, 0x3,0x25,0x36, + 0x3,0x25,0x2f, 0x2,0x23,0x4b, 0x3,0x25,0x3c, 0x1,0x49,0x61, + 0x3,0x25,0x2d, 0x2,0x23,0x4d, 0x1,0x49,0x5d, 0x2,0x23,0x4e, + 0x2,0x23,0x4c, 0x1,0x49,0x60, 0x1,0x49,0x62, 0x1,0x49,0x65, + 0x1,0x49,0x64, 0x1,0x49,0x5e, 0x2,0x23,0x4f, 0x3,0x25,0x32, + 0x3,0x25,0x41, 0x3,0x25,0x42, 0x3,0x25,0x33, 0x3,0x25,0x38, + 0x3,0x25,0x37, 0x3,0x64,0x5f, 0xf,0x23,0x52, 0x3,0x25,0x35, + 0x1,0x4c,0x5b, 0x2,0x25,0x7e, 0x3,0x28,0x25, 0x1,0x4c,0x5d, + 0x3,0x28,0x23, 0x1,0x4c,0x5c, 0x3,0x28,0x26, 0x2,0x26,0x21, + 0x1,0x4c,0x5a, 0x1,0x4c,0x59, 0x2,0x25,0x75, 0x4,0x25,0x69, + 0x2,0x25,0x74, 0x3,0x28,0x28, 0x2,0x25,0x72, 0x2,0x25,0x77, + 0x2,0x25,0x76, 0x2,0x25,0x73, 0x2,0x25,0x7c, 0x2,0x25,0x7d, + 0x2,0x25,0x7a, 0x2,0x25,0x78, 0x1,0x4c,0x58, 0x3,0x28,0x29, + 0x4,0x25,0x66, 0x4,0x25,0x68, 0x2,0x25,0x7b, 0x1,0x4c,0x5e, + 0x2,0x26,0x22, 0x4,0x25,0x65, 0x3,0x28,0x2a, 0x2,0x25,0x79, + 0x3,0x28,0x24, 0x1,0x50,0x4d, 0x1,0x4c,0x57, 0x4,0x25,0x6e, + 0xf,0x26,0x33, 0x3,0x64,0x60, 0x1,0x50,0x4e, 0x2,0x29,0x55, + 0x3,0x2b,0x69, 0x3,0x2b,0x68, 0x2,0x29,0x5b, 0x3,0x2b,0x6c, + 0x3,0x2b,0x67, 0x3,0x2b,0x6a, 0x1,0x50,0x54, 0x2,0x29,0x59, + 0x2,0x29,0x5f, 0x3,0x2b,0x71, 0x2,0x29,0x56, 0x2,0x29,0x5a, + 0x2,0x29,0x5c, 0x2,0x29,0x5e, 0x2,0x29,0x58, 0x3,0x2b,0x70, + 0x2,0x29,0x57, 0x2,0x29,0x52, 0x2,0x29,0x53, 0x1,0x50,0x4f, + 0x3,0x2b,0x6b, 0x1,0x50,0x51, 0x1,0x50,0x50, 0x2,0x29,0x54, + 0x2,0x29,0x5d, 0x3,0x2b,0x6d, 0x3,0x2b,0x72, 0x3,0x2b,0x6e, + 0x4,0x28,0x60, 0xf,0x29,0x6a, 0xf,0x29,0x71, 0x3,0x2b,0x66, + 0x1,0x50,0x53, 0x4,0x28,0x5e, 0x2,0x29,0x51, 0x2,0x2e,0x55, + 0x3,0x30,0x2a, 0x2,0x2e,0x54, 0x2,0x2e,0x59, 0x2,0x2e,0x50, + 0x3,0x30,0x30, 0x2,0x2e,0x53, 0x2,0x2e,0x52, 0x3,0x30,0x2f, + 0x2,0x2e,0x56, 0x3,0x30,0x38, 0x2,0x2e,0x5a, 0x1,0x54,0x69, + 0x1,0x54,0x6c, 0x3,0x30,0x34, 0x3,0x30,0x35, 0x2,0x2e,0x51, + 0x2,0x2e,0x57, 0x3,0x30,0x33, 0x3,0x30,0x28, 0x3,0x30,0x37, + 0x1,0x54,0x6b, 0x2,0x2e,0x4c, 0x3,0x30,0x2b, 0x1,0x50,0x52, + 0x2,0x34,0x3d, 0x2,0x2e,0x58, 0x3,0x30,0x36, 0x2,0x2e,0x4f, + 0x4,0x2c,0x33, 0x1,0x54,0x6a, 0x2,0x2e,0x4e, 0xf,0x2e,0x5c, + 0x3,0x30,0x32, 0x2,0x34,0x34, 0x3,0x34,0x6e, 0x3,0x34,0x71, + 0x1,0x59,0x51, 0x1,0x59,0x55, 0x2,0x34,0x44, 0x2,0x34,0x32, + 0x2,0x34,0x40, 0x1,0x59,0x56, 0x2,0x34,0x42, 0x3,0x34,0x72, + 0x2,0x34,0x48, 0x3,0x34,0x74, 0x2,0x34,0x4c, 0x3,0x34,0x69, + 0x4,0x30,0x7b, 0x2,0x34,0x43, 0x2,0x34,0x37, 0x2,0x34,0x3f, + 0x3,0x34,0x6b, 0x2,0x34,0x4d, 0x2,0x34,0x4b, 0x2,0x34,0x41, + 0x2,0x34,0x3c, 0x2,0x34,0x35, 0x2,0x3a,0x68, 0x2,0x34,0x33, + 0x1,0x59,0x5a, 0x2,0x34,0x3a, 0x1,0x59,0x5b, 0x1,0x59,0x57, + 0x2,0x34,0x30, 0x2,0x34,0x46, 0x2,0x34,0x38, 0x3,0x34,0x6f, + 0x3,0x34,0x75, 0x2,0x34,0x36, 0x2,0x34,0x49, 0x1,0x59,0x58, + 0x3,0x34,0x76, 0x2,0x34,0x4f, 0x1,0x59,0x52, 0x1,0x59,0x54, + 0x2,0x34,0x3e, 0x2,0x34,0x39, 0x1,0x54,0x6d, 0x1,0x59,0x53, + 0x2,0x34,0x3b, 0x2,0x34,0x4a, 0x2,0x34,0x4e, 0x2,0x34,0x45, + 0x3,0x64,0x61, 0x2,0x34,0x47, 0x3,0x64,0x62, 0x3,0x64,0x63, + 0x2,0x34,0x31, 0x4,0x36,0x69, 0x3,0x3a,0x4a, 0x2,0x3a,0x63, + 0x3,0x3a,0x45, 0x2,0x3a,0x6c, 0x2,0x3a,0x6b, 0x1,0x5e,0x60, + 0x2,0x3a,0x64, 0x3,0x3a,0x47, 0x1,0x5e,0x61, 0x1,0x5e,0x5f, + 0x3,0x3a,0x50, 0x2,0x3a,0x66, 0x1,0x5e,0x5c, 0x2,0x3a,0x6a, + 0x3,0x3a,0x4c, 0x2,0x3a,0x65, 0x2,0x3a,0x67, 0x2,0x3a,0x61, + 0x1,0x5e,0x5a, 0x4,0x36,0x6f, 0x2,0x3a,0x74, 0x2,0x3a,0x73, + 0x2,0x3a,0x70, 0x1,0x5e,0x59, 0x1,0x5e,0x5d, 0x1,0x5e,0x5e, + 0x2,0x2e,0x4d, 0x2,0x3a,0x6d, 0x1,0x5e,0x5b, 0x1,0x59,0x59, + 0x2,0x3a,0x6f, 0x2,0x3a,0x62, 0x2,0x3a,0x72, 0x2,0x3a,0x71, + 0x3,0x3a,0x4e, 0x2,0x3a,0x75, 0x3,0x3a,0x49, 0x2,0x42,0x36, + 0x3,0x3a,0x4b, 0x2,0x3a,0x6e, 0xf,0x39,0x7d, 0xf,0x39,0x7e, + 0x4,0x3c,0x57, 0x4,0x36,0x6d, 0x4,0x36,0x71, 0x3,0x64,0x64, + 0x2,0x3a,0x69, 0x2,0x42,0x2e, 0x1,0x63,0x5b, 0x1,0x63,0x5e, + 0x1,0x63,0x59, 0x2,0x42,0x2d, 0x2,0x42,0x31, 0x2,0x42,0x2c, + 0x3,0x40,0x57, 0x1,0x63,0x53, 0x1,0x63,0x5d, 0x2,0x42,0x29, + 0x1,0x63,0x57, 0x2,0x42,0x30, 0x3,0x40,0x5b, 0x1,0x63,0x55, + 0x1,0x63,0x54, 0x2,0x42,0x33, 0x1,0x63,0x56, 0x2,0x42,0x35, + 0x3,0x40,0x56, 0x2,0x42,0x32, 0x1,0x63,0x52, 0x3,0x40,0x5e, + 0x3,0x40,0x5c, 0x3,0x40,0x58, 0x1,0x63,0x5c, 0x2,0x42,0x37, + 0x2,0x42,0x2b, 0x2,0x42,0x34, 0x3,0x40,0x5d, 0x4,0x3c,0x53, + 0x2,0x42,0x2a, 0x3,0x40,0x5a, 0x3,0x40,0x59, 0x1,0x63,0x58, + 0x3,0x40,0x54, 0x1,0x63,0x5a, 0x2,0x42,0x2f, 0x2,0x42,0x38, + 0x3,0x46,0x43, 0x3,0x46,0x3e, 0x2,0x49,0x44, 0x1,0x68,0x38, + 0x2,0x49,0x4a, 0x3,0x46,0x42, 0x3,0x46,0x3c, 0x1,0x68,0x3d, + 0x2,0x49,0x46, 0x2,0x49,0x4d, 0x2,0x49,0x3e, 0x1,0x68,0x3f, + 0x1,0x68,0x39, 0x2,0x49,0x43, 0x1,0x6c,0x3f, 0x2,0x49,0x42, + 0x2,0x49,0x4b, 0x1,0x68,0x3a, 0x3,0x46,0x3d, 0x1,0x68,0x3e, + 0x2,0x49,0x41, 0x2,0x49,0x47, 0x2,0x49,0x4c, 0x2,0x49,0x3d, + 0x1,0x68,0x3c, 0x2,0x49,0x45, 0x3,0x46,0x3a, 0x3,0x46,0x45, + 0x2,0x49,0x49, 0x2,0x49,0x4f, 0x2,0x49,0x3f, 0x2,0x49,0x48, + 0x3,0x46,0x38, 0x1,0x68,0x3b, 0x2,0x49,0x4e, 0x3,0x46,0x41, + 0x3,0x46,0x44, 0x3,0x46,0x40, 0x2,0x49,0x40, 0x4,0x42,0x59, + 0x3,0x64,0x65, 0x1,0x6c,0x43, 0x2,0x4f,0x72, 0x1,0x6c,0x41, + 0x1,0x6c,0x40, 0x2,0x4f,0x74, 0x2,0x4f,0x79, 0x3,0x4b,0x46, + 0x2,0x4f,0x75, 0x3,0x4b,0x50, 0x2,0x4f,0x78, 0x1,0x6c,0x46, + 0x3,0x4b,0x51, 0x1,0x70,0x2e, 0x1,0x6c,0x45, 0x3,0x4b,0x4b, + 0x2,0x4f,0x71, 0x2,0x4f,0x77, 0x3,0x46,0x3f, 0x1,0x6c,0x44, + 0x2,0x4f,0x76, 0x3,0x4b,0x4d, 0x2,0x4f,0x73, 0x3,0x4b,0x49, + 0x1,0x6c,0x42, 0x3,0x4b,0x4f, 0x3,0x4b,0x4c, 0x3,0x4b,0x47, + 0x2,0x56,0x57, 0x3,0x50,0x4a, 0x2,0x56,0x59, 0x2,0x56,0x54, + 0x1,0x70,0x4a, 0x2,0x56,0x56, 0x3,0x50,0x4b, 0x1,0x70,0x49, + 0x2,0x56,0x58, 0x3,0x50,0x48, 0x3,0x50,0x4c, 0x1,0x70,0x4c, + 0x2,0x56,0x5a, 0x1,0x70,0x4b, 0x2,0x56,0x53, 0x2,0x56,0x55, + 0x3,0x50,0x49, 0x3,0x54,0x4b, 0x1,0x73,0x4e, 0x2,0x5c,0x58, + 0x3,0x54,0x4c, 0x1,0x73,0x4d, 0x2,0x5c,0x59, 0x1,0x73,0x4c, + 0x2,0x5c,0x57, 0x1,0x73,0x4b, 0x2,0x5c,0x56, 0x1,0x76,0x3f, + 0x1,0x76,0x3e, 0x2,0x65,0x42, 0x2,0x65,0x44, 0x3,0x5a,0x2f, + 0x2,0x65,0x43, 0x1,0x78,0x2e, 0x1,0x78,0x2f, 0x3,0x5a,0x2e, + 0x7,0x46,0x45, 0x1,0x78,0x30, 0x2,0x68,0x6e, 0x1,0x79,0x66, + 0x3,0x5e,0x28, 0x2,0x6f,0x22, 0x2,0x6f,0x21, 0x1,0x7c,0x5e, + 0x1,0x44,0x49, 0x1,0x45,0x31, 0x3,0x23,0x43, 0x1,0x49,0x67, + 0x3,0x25,0x45, 0x3,0x25,0x43, 0x3,0x25,0x44, 0x3,0x28,0x2d, + 0x2,0x29,0x60, 0x3,0x2b,0x77, 0x3,0x34,0x77, 0x1,0x5e,0x62, + 0x1,0x5e,0x63, 0x3,0x3a,0x52, 0x2,0x42,0x39, 0x1,0x68,0x40, + 0x2,0x49,0x50, 0x2,0x4f,0x7a, 0x3,0x64,0x66, 0x3,0x50,0x4d, + 0x3,0x21,0x39, 0x2,0x21,0x3a, 0x3,0x22,0x35, 0x3,0x23,0x44, + 0x2,0x23,0x50, 0x3,0x2b,0x7a, 0x3,0x2b,0x79, 0x3,0x21,0x3a, + 0x3,0x25,0x46, 0x2,0x26,0x23, 0x2,0x29,0x61, 0x2,0x2e,0x5b, + 0x1,0x54,0x6e, 0x3,0x46,0x46, 0x3,0x65,0x60, 0x2,0x65,0x45, + 0x4,0x5f,0x52, 0x1,0x7a,0x67, 0x1,0x44,0x4a, 0x1,0x46,0x40, + 0x2,0x21,0x51, 0x3,0x22,0x36, 0x1,0x47,0x68, 0x1,0x47,0x69, + 0x4,0x22,0x52, 0x1,0x4c,0x5f, 0x4,0x25,0x70, 0x3,0x34,0x79, + 0x1,0x59,0x5c, 0x5,0x37,0x3d, 0x1,0x68,0x42, 0x3,0x40,0x5f, + 0x1,0x68,0x43, 0x1,0x68,0x41, 0x3,0x4b,0x53, 0x1,0x44,0x4b, + 0x4,0x21,0x49, 0x1,0x45,0x32, 0x1,0x45,0x34, 0x1,0x45,0x33, + 0x2,0x21,0x3b, 0x1,0x45,0x35, 0x1,0x46,0x41, 0x2,0x21,0x52, + 0x3,0x22,0x38, 0x1,0x46,0x42, 0x3,0x22,0x37, 0x4,0x21,0x72, + 0x3,0x22,0x39, 0x4,0x22,0x53, 0x3,0x23,0x47, 0x1,0x47,0x6a, + 0x1,0x47,0x6b, 0x2,0x22,0x2b, 0x3,0x25,0x49, 0x1,0x49,0x68, + 0x4,0x23,0x62, 0x2,0x23,0x51, 0x4,0x25,0x75, 0x1,0x4c,0x63, + 0x2,0x26,0x24, 0x4,0x25,0x72, 0x1,0x4c,0x61, 0x1,0x4c,0x62, + 0x1,0x4c,0x60, 0x2,0x2e,0x5c, 0x3,0x28,0x2e, 0x3,0x28,0x2f, + 0x3,0x64,0x67, 0x1,0x50,0x58, 0x1,0x50,0x57, 0x1,0x50,0x59, + 0x1,0x50,0x56, 0x3,0x2b,0x7c, 0x2,0x29,0x62, 0x1,0x4c,0x64, + 0x1,0x50,0x55, 0x1,0x54,0x6f, 0x1,0x54,0x70, 0x4,0x2c,0x38, + 0x1,0x54,0x71, 0x3,0x34,0x7b, 0x2,0x34,0x50, 0x3,0x34,0x7c, + 0x3,0x34,0x7d, 0x4,0x31,0x26, 0x1,0x5e,0x64, 0x2,0x3a,0x76, + 0x1,0x59,0x5d, 0x3,0x3a,0x53, 0x3,0x3a,0x54, 0x4,0x36,0x79, + 0x3,0x40,0x60, 0x1,0x63,0x5f, 0x3,0x40,0x61, 0x1,0x68,0x45, + 0x1,0x68,0x44, 0x2,0x49,0x51, 0x3,0x46,0x48, 0x1,0x6c,0x47, + 0x1,0x70,0x4d, 0x4,0x4f,0x7b, 0x2,0x61,0x4c, 0x2,0x6d,0x48, + 0x2,0x6f,0x23, 0x1,0x44,0x4c, 0x1,0x46,0x43, 0x3,0x22,0x3b, + 0x1,0x46,0x44, 0x2,0x22,0x31, 0x1,0x47,0x6d, 0x1,0x47,0x70, + 0x3,0x23,0x4b, 0x2,0x22,0x2f, 0x2,0x22,0x2d, 0x1,0x47,0x6f, + 0x2,0x22,0x30, 0x2,0x22,0x32, 0x2,0x22,0x2c, 0x1,0x47,0x72, + 0x1,0x47,0x71, 0x1,0x47,0x6e, 0x1,0x47,0x6c, 0x2,0x22,0x2e, + 0x3,0x23,0x4d, 0x3,0x25,0x55, 0x1,0x49,0x73, 0x4,0x23,0x67, + 0x3,0x25,0x4c, 0x1,0x49,0x70, 0x2,0x23,0x56, 0x2,0x23,0x59, + 0x2,0x23,0x58, 0x4,0x23,0x69, 0x1,0x49,0x6a, 0x1,0x49,0x72, + 0x3,0x25,0x4b, 0x4,0x23,0x6a, 0x1,0x49,0x6f, 0x2,0x23,0x55, + 0x2,0x23,0x53, 0x1,0x49,0x6e, 0x3,0x25,0x56, 0x3,0x25,0x53, + 0x3,0x25,0x4e, 0x1,0x49,0x69, 0x1,0x49,0x6c, 0x3,0x25,0x51, + 0x2,0x23,0x54, 0x2,0x23,0x5b, 0x2,0x23,0x57, 0x1,0x49,0x6d, + 0x1,0x49,0x71, 0x1,0x49,0x74, 0x2,0x23,0x52, 0x2,0x23,0x5a, + 0x1,0x49,0x6b, 0x3,0x28,0x41, 0x3,0x28,0x33, 0x1,0x4c,0x69, + 0x1,0x4c,0x71, 0x3,0x28,0x38, 0x2,0x26,0x30, 0x2,0x26,0x29, + 0x1,0x4c,0x72, 0x2,0x26,0x34, 0x2,0x26,0x25, 0x2,0x26,0x2c, + 0x3,0x28,0x45, 0x3,0x28,0x40, 0x1,0x4c,0x68, 0x2,0x26,0x26, + 0x1,0x4c,0x66, 0x2,0x26,0x2d, 0x2,0x26,0x31, 0x1,0x4c,0x65, + 0x3,0x28,0x3d, 0x2,0x26,0x32, 0x2,0x26,0x2b, 0x3,0x28,0x37, + 0x2,0x26,0x2e, 0x3,0x28,0x35, 0x1,0x4c,0x74, 0x1,0x4c,0x6b, + 0x2,0x26,0x35, 0x2,0x26,0x33, 0x3,0x28,0x3f, 0x1,0x4c,0x70, + 0x1,0x4c,0x6e, 0x2,0x26,0x2a, 0x1,0x4c,0x6d, 0x2,0x26,0x28, + 0x2,0x26,0x27, 0x1,0x4c,0x6c, 0x1,0x4c,0x6a, 0x1,0x4c,0x73, + 0x1,0x4c,0x6f, 0x1,0x4c,0x67, 0x3,0x2c,0x26, 0x2,0x26,0x2f, + 0x3,0x28,0x46, 0x1,0x50,0x5b, 0x3,0x2c,0x2d, 0x1,0x50,0x62, + 0x2,0x29,0x70, 0x1,0x50,0x5a, 0x2,0x29,0x68, 0x2,0x29,0x64, + 0x3,0x2c,0x21, 0x2,0x29,0x74, 0x2,0x29,0x63, 0x3,0x2c,0x2c, + 0x1,0x50,0x5d, 0x2,0x29,0x6d, 0x1,0x50,0x60, 0x1,0x50,0x63, + 0x3,0x2c,0x2e, 0x1,0x50,0x5e, 0x2,0x29,0x71, 0x1,0x50,0x61, + 0x3,0x2c,0x23, 0x1,0x54,0x78, 0x2,0x29,0x77, 0x2,0x29,0x65, + 0x3,0x2c,0x24, 0x3,0x2c,0x25, 0x2,0x29,0x67, 0x2,0x29,0x6e, + 0x2,0x29,0x72, 0x2,0x29,0x76, 0x2,0x29,0x73, 0x2,0x29,0x6c, + 0x2,0x29,0x6f, 0x3,0x2c,0x2b, 0x3,0x2c,0x29, 0x2,0x29,0x69, + 0x1,0x50,0x65, 0x2,0x29,0x6b, 0x2,0x29,0x6a, 0x2,0x29,0x75, + 0x1,0x50,0x5c, 0x2,0x29,0x66, 0x1,0x50,0x64, 0x3,0x2c,0x2a, + 0x1,0x50,0x5f, 0x3,0x2c,0x28, 0x1,0x54,0x7e, 0x2,0x2e,0x64, + 0x3,0x30,0x40, 0x1,0x54,0x7d, 0x3,0x2c,0x27, 0x4,0x2c,0x40, + 0x2,0x2e,0x62, 0x4,0x2c,0x3e, 0x1,0x54,0x72, 0x3,0x30,0x4f, + 0x1,0x54,0x77, 0x3,0x30,0x4a, 0x2,0x2e,0x61, 0x2,0x2e,0x5e, + 0x2,0x2e,0x63, 0x1,0x54,0x73, 0x2,0x2e,0x5d, 0x3,0x30,0x4e, + 0x1,0x54,0x76, 0x1,0x54,0x74, 0x3,0x30,0x3e, 0x2,0x2e,0x65, + 0x1,0x54,0x75, 0x1,0x54,0x79, 0x3,0x30,0x3b, 0x3,0x30,0x45, + 0x1,0x54,0x7a, 0x3,0x30,0x48, 0x1,0x54,0x7c, 0x3,0x30,0x52, + 0x4,0x2c,0x39, 0x4,0x2c,0x3d, 0x1,0x54,0x7b, 0x3,0x30,0x3c, + 0x3,0x35,0x22, 0x3,0x35,0x38, 0x2,0x2e,0x5f, 0x2,0x2e,0x60, + 0x3,0x30,0x4d, 0x6,0x36,0x57, 0x3,0x30,0x4b, 0x2,0x2e,0x66, + 0x2,0x34,0x57, 0x1,0x59,0x5e, 0x2,0x3b,0x26, 0x2,0x34,0x56, + 0x2,0x34,0x69, 0x3,0x35,0x28, 0x3,0x35,0x24, 0x1,0x59,0x64, + 0x3,0x35,0x31, 0x2,0x34,0x67, 0x3,0x35,0x33, 0x1,0x59,0x63, + 0x1,0x59,0x5f, 0x2,0x34,0x70, 0x2,0x34,0x60, 0x2,0x34,0x63, + 0x3,0x35,0x2e, 0x1,0x59,0x67, 0x2,0x34,0x6d, 0x2,0x34,0x65, + 0x1,0x59,0x60, 0x1,0x59,0x68, 0x3,0x35,0x2a, 0x2,0x34,0x6a, + 0x2,0x34,0x68, 0x3,0x35,0x2f, 0x3,0x35,0x3b, 0x2,0x34,0x59, + 0x2,0x34,0x6e, 0x2,0x34,0x62, 0x2,0x34,0x5d, 0x3,0x35,0x3a, + 0x2,0x34,0x53, 0x2,0x34,0x6f, 0x2,0x34,0x5f, 0x2,0x34,0x52, + 0x3,0x35,0x39, 0x1,0x59,0x66, 0x2,0x34,0x64, 0x2,0x34,0x71, + 0x2,0x34,0x61, 0x2,0x34,0x55, 0x2,0x34,0x5a, 0x2,0x34,0x51, + 0x3,0x35,0x27, 0x1,0x59,0x65, 0x3,0x35,0x3c, 0x2,0x34,0x5e, + 0x2,0x34,0x5b, 0x1,0x59,0x61, 0x2,0x34,0x54, 0x3,0x35,0x30, + 0x2,0x34,0x6c, 0x1,0x59,0x62, 0x3,0x35,0x2b, 0x2,0x34,0x5c, + 0x2,0x34,0x58, 0x3,0x35,0x29, 0x3,0x35,0x34, 0x2,0x34,0x6b, + 0x3,0x35,0x32, 0xf,0x33,0x73, 0x3,0x35,0x37, 0x3,0x35,0x35, + 0x1,0x5e,0x65, 0x2,0x3a,0x7d, 0x3,0x3a,0x75, 0x2,0x3a,0x7a, + 0x2,0x3b,0x2d, 0x2,0x3b,0x21, 0x2,0x3b,0x2e, 0x3,0x3a,0x7c, + 0x1,0x5e,0x67, 0x3,0x3a,0x63, 0x3,0x3a,0x61, 0x3,0x3a,0x58, + 0x2,0x3b,0x2a, 0x2,0x3b,0x27, 0x3,0x3a,0x5b, 0x3,0x3a,0x77, + 0x3,0x3a,0x72, 0x3,0x3a,0x59, 0x3,0x3a,0x60, 0x2,0x3b,0x28, + 0x2,0x3b,0x2b, 0x2,0x3b,0x2f, 0x3,0x3a,0x7b, 0x2,0x34,0x66, + 0x2,0x3b,0x31, 0x2,0x42,0x4d, 0x3,0x3a,0x66, 0x1,0x5e,0x68, + 0x2,0x3b,0x32, 0x2,0x3a,0x78, 0x2,0x3b,0x24, 0x3,0x3a,0x62, + 0x2,0x3b,0x29, 0x3,0x3a,0x5c, 0x3,0x3a,0x5e, 0x1,0x5e,0x66, + 0x1,0x5e,0x69, 0x2,0x3b,0x30, 0x2,0x3b,0x33, 0x2,0x3a,0x7c, + 0x2,0x3a,0x79, 0x3,0x3a,0x73, 0x3,0x3a,0x5a, 0x2,0x3a,0x7b, + 0x3,0x3a,0x57, 0x3,0x3a,0x7a, 0x2,0x3b,0x22, 0x2,0x3a,0x7e, + 0x1,0x5e,0x6a, 0x3,0x3a,0x56, 0x2,0x3b,0x2c, 0x3,0x3a,0x79, + 0x3,0x3a,0x78, 0x2,0x3b,0x23, 0x2,0x3b,0x25, 0x2,0x3a,0x77, + 0x2,0x42,0x41, 0x2,0x42,0x3f, 0x1,0x63,0x68, 0x1,0x63,0x66, + 0x2,0x42,0x49, 0x2,0x42,0x40, 0x2,0x42,0x4a, 0x2,0x42,0x46, + 0x2,0x42,0x3e, 0x2,0x42,0x4c, 0x2,0x42,0x3d, 0x2,0x42,0x44, + 0x1,0x63,0x65, 0x1,0x63,0x64, 0x1,0x63,0x63, 0x2,0x42,0x42, + 0x2,0x42,0x47, 0x1,0x63,0x60, 0x1,0x63,0x67, 0x3,0x40,0x67, + 0x2,0x42,0x3b, 0x3,0x40,0x66, 0x2,0x42,0x45, 0x2,0x42,0x3a, + 0x2,0x42,0x43, 0x1,0x63,0x61, 0x2,0x42,0x48, 0x2,0x42,0x3c, + 0x1,0x63,0x62, 0x2,0x42,0x4b, 0x3,0x40,0x64, 0x3,0x3a,0x6b, + 0x3,0x40,0x6a, 0x3,0x64,0x68, 0x3,0x64,0x69, 0x2,0x49,0x55, + 0x1,0x68,0x4a, 0x1,0x68,0x49, 0x1,0x68,0x4b, 0x2,0x49,0x61, + 0x2,0x49,0x57, 0x2,0x49,0x5d, 0x2,0x49,0x52, 0x2,0x49,0x60, + 0x2,0x49,0x5f, 0x2,0x49,0x63, 0x2,0x49,0x5c, 0x1,0x68,0x46, + 0x2,0x49,0x5b, 0x1,0x68,0x4c, 0x3,0x46,0x4c, 0x2,0x49,0x54, + 0x1,0x68,0x47, 0x3,0x46,0x4a, 0x2,0x49,0x62, 0x1,0x68,0x48, + 0x2,0x49,0x56, 0x2,0x49,0x59, 0x2,0x49,0x5e, 0x2,0x49,0x58, + 0x2,0x49,0x53, 0x3,0x46,0x4f, 0x3,0x46,0x53, 0x2,0x49,0x5a, + 0x2,0x4f,0x7c, 0x1,0x6c,0x4b, 0x2,0x50,0x21, 0x2,0x4f,0x7e, + 0x2,0x50,0x23, 0x2,0x50,0x25, 0x3,0x4b,0x5c, 0x1,0x6c,0x49, + 0x3,0x4b,0x58, 0x2,0x4f,0x7d, 0x3,0x4b,0x54, 0x2,0x4f,0x7b, + 0x3,0x4b,0x5e, 0x2,0x50,0x26, 0x2,0x50,0x24, 0x2,0x50,0x22, + 0x3,0x4b,0x56, 0x2,0x50,0x28, 0x3,0x4b,0x5a, 0x2,0x50,0x27, + 0x1,0x6c,0x4d, 0x1,0x6c,0x48, 0x3,0x4b,0x5b, 0x1,0x6c,0x4a, + 0x1,0x6c,0x4c, 0x3,0x4b,0x5d, 0x3,0x4b,0x5f, 0x2,0x50,0x29, + 0x2,0x56,0x61, 0x3,0x50,0x50, 0x3,0x50,0x53, 0x2,0x56,0x60, + 0x2,0x56,0x5f, 0x3,0x50,0x51, 0x2,0x56,0x62, 0x2,0x56,0x5b, + 0x3,0x50,0x4f, 0x2,0x56,0x5c, 0x2,0x56,0x64, 0x2,0x56,0x5d, + 0x3,0x50,0x54, 0x1,0x70,0x4e, 0x2,0x56,0x66, 0x3,0x50,0x4e, + 0x2,0x56,0x65, 0x2,0x56,0x5e, 0x3,0x50,0x56, 0x2,0x5c,0x5d, + 0x1,0x73,0x51, 0x2,0x5c,0x5b, 0x2,0x5c,0x60, 0x2,0x5c,0x5f, + 0x2,0x56,0x63, 0x3,0x54,0x50, 0x1,0x73,0x50, 0x3,0x54,0x4e, + 0x2,0x5c,0x5e, 0x2,0x5c,0x5a, 0x2,0x5c,0x62, 0x2,0x5c,0x61, + 0x1,0x73,0x4f, 0x3,0x54,0x52, 0x2,0x5c,0x5c, 0x3,0x54,0x4f, + 0x1,0x70,0x4f, 0x3,0x54,0x51, 0x3,0x54,0x53, 0x1,0x76,0x40, + 0x3,0x5a,0x31, 0x3,0x57,0x61, 0x3,0x57,0x5e, 0x2,0x61,0x4d, + 0x2,0x65,0x46, 0x2,0x65,0x47, 0x2,0x65,0x48, 0x1,0x79,0x67, + 0x4,0x63,0x34, 0x3,0x5c,0x36, 0x1,0x79,0x68, 0x3,0x5c,0x39, + 0x2,0x68,0x6f, 0x3,0x5c,0x3a, 0x2,0x6b,0x56, 0x2,0x6b,0x55, + 0x3,0x5e,0x29, 0x3,0x5f,0x42, 0x2,0x6d,0x49, 0x2,0x6d,0x4a, + 0x2,0x6f,0x24, 0x2,0x70,0x35, 0x3,0x60,0x73, 0x1,0x44,0x4d, + 0x1,0x44,0x4e, 0x4,0x21,0x32, 0x1,0x44,0x4f, 0x1,0x45,0x36, + 0x1,0x46,0x45, 0x2,0x22,0x33, 0x1,0x47,0x73, 0x1,0x47,0x74, + 0x1,0x49,0x77, 0x1,0x49,0x78, 0x1,0x49,0x76, 0x1,0x49,0x75, + 0x1,0x4c,0x75, 0x3,0x28,0x48, 0x4,0x26,0x22, 0x2,0x26,0x36, + 0x1,0x4c,0x77, 0x1,0x4c,0x76, 0x2,0x26,0x37, 0x4,0x26,0x23, + 0x3,0x64,0x6a, 0x4,0x28,0x6e, 0x1,0x50,0x66, 0x3,0x2c,0x2f, + 0x1,0x55,0x21, 0x2,0x2e,0x67, 0x2,0x34,0x73, 0x4,0x31,0x2c, + 0x1,0x59,0x69, 0x1,0x5e,0x6c, 0x2,0x34,0x72, 0x1,0x5e,0x6b, + 0x3,0x40,0x71, 0x1,0x68,0x4d, 0x3,0x40,0x72, 0x2,0x49,0x64, + 0x1,0x70,0x50, 0x3,0x50,0x57, 0x1,0x73,0x52, 0x2,0x5c,0x63, + 0x3,0x5a,0x34, 0x1,0x79,0x69, 0x3,0x5c,0x3b, 0x1,0x7b,0x5c, + 0x3,0x21,0x3b, 0x2,0x21,0x53, 0x3,0x22,0x3d, 0x1,0x46,0x46, + 0x2,0x21,0x54, 0x1,0x47,0x77, 0x3,0x23,0x50, 0x1,0x47,0x75, + 0x1,0x47,0x76, 0x1,0x47,0x78, 0x4,0x23,0x6f, 0x1,0x49,0x7a, + 0x1,0x49,0x79, 0x3,0x25,0x5a, 0x2,0x23,0x5c, 0x1,0x49,0x7b, + 0x4,0x26,0x25, 0x2,0x23,0x5d, 0x2,0x26,0x38, 0x3,0x28,0x4c, + 0x2,0x26,0x39, 0x3,0x28,0x4a, 0x1,0x4c,0x78, 0x1,0x4c,0x7a, + 0x1,0x4c,0x7c, 0x1,0x4c,0x79, 0x1,0x4c,0x7d, 0x1,0x4c,0x7b, + 0x3,0x28,0x4e, 0x3,0x28,0x4b, 0x3,0x28,0x4d, 0x1,0x50,0x6a, + 0x1,0x50,0x67, 0x1,0x50,0x69, 0x1,0x50,0x6b, 0x1,0x50,0x68, + 0x2,0x2e,0x68, 0x2,0x29,0x78, 0xf,0x2a,0x39, 0x3,0x2c,0x32, + 0x2,0x2e,0x6a, 0x2,0x2e,0x69, 0x1,0x55,0x27, 0x4,0x2c,0x46, + 0x1,0x55,0x23, 0x4,0x2c,0x49, 0x6,0x36,0x66, 0x1,0x55,0x24, + 0x1,0x55,0x26, 0x1,0x55,0x28, 0x1,0x55,0x25, 0x3,0x30,0x57, + 0x1,0x55,0x2a, 0x1,0x55,0x29, 0x4,0x2c,0x48, 0x3,0x30,0x56, + 0x3,0x30,0x55, 0xf,0x2e,0x7e, 0x1,0x59,0x6e, 0x2,0x34,0x75, + 0x2,0x34,0x74, 0x1,0x59,0x6d, 0x3,0x35,0x41, 0x1,0x59,0x6c, + 0x1,0x59,0x6b, 0x1,0x59,0x6f, 0x1,0x59,0x6a, 0x3,0x35,0x3f, + 0x2,0x3b,0x39, 0x2,0x3b,0x36, 0x1,0x5e,0x6e, 0x2,0x3b,0x35, + 0x2,0x3b,0x3a, 0x4,0x37,0x24, 0x1,0x5e,0x70, 0x2,0x3b,0x38, + 0x1,0x5e,0x6d, 0x1,0x5e,0x6f, 0x2,0x3b,0x37, 0x3,0x3a,0x7e, + 0x2,0x42,0x4e, 0x3,0x40,0x74, 0x2,0x42,0x4f, 0x2,0x42,0x50, + 0x3,0x40,0x75, 0x3,0x40,0x76, 0x3,0x40,0x73, 0x4,0x3c,0x6e, + 0x1,0x68,0x4e, 0x1,0x68,0x56, 0x2,0x49,0x65, 0x1,0x68,0x50, + 0x1,0x68,0x54, 0x2,0x49,0x66, 0x1,0x68,0x55, 0x1,0x68,0x51, + 0x1,0x68,0x52, 0x1,0x68,0x4f, 0x1,0x68,0x53, 0x1,0x6c,0x50, + 0x2,0x3b,0x34, 0x1,0x6c,0x51, 0x1,0x6c,0x4f, 0x4,0x49,0x44, + 0x1,0x6c,0x4e, 0x2,0x56,0x67, 0x1,0x70,0x51, 0x2,0x5c,0x64, + 0x2,0x5c,0x65, 0x3,0x5a,0x35, 0x4,0x5f,0x55, 0x1,0x78,0x31, + 0x1,0x79,0x6a, 0x3,0x5e,0x2a, 0x1,0x44,0x50, 0x3,0x22,0x3e, + 0x1,0x47,0x79, 0x3,0x25,0x5e, 0x3,0x25,0x5c, 0x3,0x25,0x5d, + 0x3,0x28,0x50, 0x1,0x50,0x6c, 0x2,0x2e,0x6b, 0x1,0x55,0x2b, + 0x3,0x30,0x58, 0x3,0x30,0x59, 0x1,0x59,0x72, 0x1,0x59,0x71, + 0x1,0x59,0x70, 0x1,0x5e,0x71, 0x1,0x5e,0x72, 0x2,0x3b,0x3b, + 0x1,0x68,0x57, 0x1,0x70,0x52, 0x1,0x44,0x51, 0x2,0x21,0x3c, + 0x1,0x45,0x37, 0x2,0x21,0x55, 0x4,0x21,0x73, 0x3,0x22,0x3f, + 0x2,0x22,0x34, 0x1,0x47,0x7a, 0x4,0x22,0x5c, 0x3,0x23,0x52, + 0x3,0x28,0x51, 0x1,0x4c,0x7e, 0x3,0x2c,0x34, 0x3,0x3b,0x24, + 0x2,0x42,0x51, 0x3,0x40,0x78, 0x3,0x65,0x25, 0x1,0x44,0x52, + 0x4,0x21,0x4b, 0x1,0x45,0x38, 0x2,0x22,0x35, 0x2,0x23,0x5e, + 0x4,0x26,0x29, 0x2,0x23,0x5f, 0x3,0x25,0x5f, 0x1,0x49,0x7c, + 0xf,0x25,0x54, 0x3,0x2c,0x35, 0x2,0x3b,0x3c, 0x1,0x5e,0x73, + 0x2,0x42,0x52, 0x4,0x49,0x49, 0x3,0x54,0x54, 0x1,0x73,0x53, + 0x1,0x44,0x53, 0x1,0x44,0x67, 0x1,0x45,0x39, 0x2,0x21,0x56, + 0x1,0x46,0x47, 0x3,0x23,0x54, 0x1,0x4a,0x22, 0x1,0x4a,0x21, + 0x1,0x49,0x7d, 0x1,0x49,0x7e, 0x2,0x26,0x3a, 0x1,0x4d,0x22, + 0x1,0x4d,0x23, 0x2,0x26,0x3b, 0x1,0x4d,0x21, 0x3,0x28,0x54, + 0x3,0x28,0x55, 0x1,0x50,0x70, 0x2,0x29,0x79, 0x1,0x50,0x6f, + 0x1,0x50,0x6d, 0x1,0x50,0x6e, 0x1,0x55,0x2e, 0x1,0x55,0x2c, + 0x3,0x30,0x5a, 0x3,0x30,0x5b, 0x2,0x2e,0x6d, 0x1,0x55,0x2d, + 0x2,0x2e,0x6c, 0x3,0x64,0x6b, 0x1,0x55,0x22, 0x2,0x34,0x76, + 0x4,0x31,0x35, 0x3,0x35,0x43, 0x1,0x59,0x74, 0x1,0x59,0x75, + 0x3,0x3b,0x26, 0x3,0x3b,0x25, 0x1,0x59,0x73, 0x3,0x35,0x44, + 0x1,0x68,0x58, 0x2,0x49,0x67, 0x1,0x6c,0x52, 0x1,0x6c,0x53, + 0x2,0x50,0x2a, 0x1,0x73,0x54, 0x2,0x61,0x4e, 0x2,0x61,0x4f, + 0x3,0x5a,0x38, 0x1,0x7a,0x68, 0x2,0x70,0x36, 0x2,0x21,0x2b, + 0x1,0x45,0x3a, 0x4,0x22,0x5f, 0x1,0x44,0x54, 0x2,0x21,0x58, + 0x2,0x21,0x57, 0x4,0x21,0x76, 0x3,0x64,0x6c, 0x3,0x23,0x55, + 0x1,0x47,0x7b, 0x2,0x22,0x37, 0x2,0x22,0x38, 0x2,0x22,0x36, + 0x4,0x22,0x60, 0x2,0x22,0x39, 0x3,0x23,0x5a, 0xf,0x22,0x47, + 0x3,0x25,0x61, 0x3,0x25,0x66, 0x2,0x23,0x67, 0x4,0x23,0x7a, + 0x2,0x23,0x62, 0x2,0x23,0x64, 0x2,0x23,0x66, 0x2,0x23,0x63, + 0x1,0x4a,0x26, 0x2,0x23,0x60, 0x3,0x25,0x62, 0x2,0x23,0x61, + 0x1,0x4a,0x23, 0x1,0x4a,0x24, 0x2,0x23,0x65, 0x2,0x23,0x68, + 0x1,0x4a,0x25, 0x2,0x23,0x69, 0xf,0x23,0x7c, 0xf,0x23,0x78, + 0x3,0x25,0x63, 0x2,0x26,0x49, 0x3,0x28,0x5d, 0x2,0x26,0x43, + 0x2,0x26,0x3e, 0x1,0x4d,0x25, 0x2,0x26,0x46, 0x2,0x26,0x44, + 0x2,0x26,0x3d, 0x2,0x26,0x4a, 0x2,0x26,0x4d, 0x2,0x26,0x48, + 0x2,0x26,0x41, 0x1,0x4d,0x27, 0x2,0x26,0x47, 0x1,0x4d,0x28, + 0x2,0x26,0x42, 0x2,0x26,0x45, 0x2,0x26,0x3c, 0x2,0x26,0x40, + 0x2,0x26,0x4c, 0x1,0x4d,0x29, 0x4,0x26,0x2f, 0x1,0x4d,0x2a, + 0x3,0x28,0x5e, 0x2,0x26,0x3f, 0x2,0x26,0x4b, 0x1,0x4d,0x24, + 0x1,0x4d,0x26, 0x3,0x28,0x5c, 0x3,0x28,0x5f, 0x3,0x28,0x57, + 0x4,0x26,0x34, 0x3,0x28,0x58, 0x2,0x2a,0x2c, 0x2,0x2a,0x25, + 0x2,0x2a,0x2b, 0x2,0x2a,0x24, 0x2,0x2a,0x26, 0x2,0x29,0x7e, + 0x2,0x29,0x7c, 0x3,0x2c,0x3f, 0x2,0x2a,0x2d, 0x2,0x2a,0x2a, + 0x2,0x29,0x7a, 0x3,0x2c,0x3b, 0x1,0x50,0x72, 0x2,0x2a,0x28, + 0x2,0x2a,0x29, 0x3,0x64,0x6d, 0x2,0x2a,0x27, 0x2,0x29,0x7d, + 0x2,0x29,0x7b, 0x1,0x50,0x71, 0x2,0x2a,0x23, 0x2,0x2a,0x21, + 0x3,0x2c,0x3c, 0x3,0x2c,0x42, 0x2,0x2a,0x22, 0x2,0x2a,0x2e, + 0x3,0x2c,0x3e, 0x3,0x2c,0x41, 0x3,0x2c,0x43, 0x3,0x2c,0x3d, + 0x1,0x55,0x33, 0x3,0x30,0x63, 0x1,0x55,0x32, 0x3,0x30,0x5f, + 0x2,0x2e,0x6e, 0x1,0x55,0x2f, 0x2,0x2e,0x70, 0x3,0x30,0x64, + 0x1,0x55,0x34, 0x2,0x2e,0x71, 0x4,0x2c,0x60, 0x3,0x30,0x61, + 0x1,0x55,0x37, 0x3,0x30,0x62, 0x1,0x55,0x35, 0x2,0x2e,0x72, + 0x2,0x2a,0x2f, 0x2,0x2e,0x74, 0x3,0x30,0x5e, 0x1,0x55,0x31, + 0x4,0x2c,0x5c, 0x1,0x55,0x30, 0x4,0x2c,0x61, 0x2,0x2e,0x6f, + 0x2,0x2e,0x73, 0x1,0x55,0x36, 0x1,0x59,0x77, 0x1,0x59,0x76, + 0x3,0x35,0x4b, 0x3,0x35,0x48, 0x3,0x35,0x47, 0x2,0x34,0x78, + 0x2,0x34,0x7c, 0x2,0x34,0x7e, 0x1,0x59,0x78, 0x2,0x35,0x23, + 0x3,0x35,0x51, 0x1,0x59,0x7c, 0x2,0x35,0x25, 0x3,0x35,0x52, + 0x1,0x59,0x7e, 0x3,0x35,0x4f, 0x1,0x59,0x7a, 0x1,0x5a,0x24, + 0x3,0x35,0x55, 0x1,0x5a,0x21, 0x2,0x34,0x7a, 0x1,0x59,0x79, + 0x3,0x3b,0x2b, 0x2,0x34,0x79, 0x2,0x34,0x77, 0x2,0x35,0x27, + 0x2,0x34,0x7b, 0x3,0x35,0x46, 0x1,0x59,0x7b, 0x2,0x35,0x26, + 0x1,0x5a,0x22, 0x2,0x35,0x22, 0x2,0x35,0x21, 0x1,0x5a,0x23, + 0x2,0x34,0x7d, 0x1,0x59,0x7d, 0x3,0x35,0x4e, 0x6,0x3e,0x76, + 0x3,0x35,0x4a, 0x2,0x35,0x28, 0x3,0x35,0x54, 0x2,0x35,0x24, + 0x2,0x3b,0x4b, 0x2,0x3b,0x52, 0x2,0x3b,0x47, 0x1,0x5e,0x76, + 0x2,0x3b,0x43, 0x2,0x3b,0x53, 0x2,0x3b,0x3d, 0x2,0x3b,0x50, + 0x2,0x3b,0x4e, 0x2,0x3b,0x48, 0x3,0x3b,0x36, 0x2,0x3b,0x51, + 0x2,0x3b,0x4a, 0x3,0x3b,0x28, 0x2,0x3b,0x42, 0x2,0x3b,0x54, + 0x2,0x3b,0x40, 0x2,0x3b,0x4d, 0x2,0x3b,0x3e, 0x3,0x3b,0x27, + 0x2,0x3b,0x55, 0x3,0x3b,0x37, 0x1,0x5e,0x77, 0x3,0x3b,0x2a, + 0x2,0x3b,0x4f, 0x2,0x42,0x55, 0x2,0x3b,0x41, 0x1,0x5e,0x74, + 0x3,0x3b,0x2e, 0x2,0x3b,0x45, 0x3,0x3b,0x34, 0x1,0x5e,0x75, + 0x2,0x3b,0x44, 0x2,0x3b,0x49, 0x3,0x3b,0x33, 0x4,0x37,0x35, + 0x2,0x3b,0x46, 0x4,0x37,0x2f, 0x3,0x3b,0x31, 0x2,0x3b,0x4c, + 0x3,0x3b,0x2d, 0x2,0x42,0x59, 0x4,0x3c,0x79, 0x3,0x41,0x21, + 0x4,0x3c,0x7b, 0x2,0x42,0x5c, 0x2,0x42,0x54, 0x3,0x40,0x7c, + 0x2,0x42,0x56, 0x3,0x40,0x7a, 0x2,0x42,0x5b, 0x2,0x42,0x5a, + 0x1,0x63,0x69, 0x4,0x3c,0x75, 0x2,0x3b,0x3f, 0x2,0x42,0x58, + 0x3,0x40,0x79, 0x3,0x40,0x7d, 0x1,0x63,0x6a, 0x4,0x3c,0x74, + 0x2,0x42,0x53, 0x2,0x42,0x57, 0x4,0x3c,0x7c, 0x4,0x3c,0x78, + 0x3,0x64,0x6e, 0x2,0x49,0x6e, 0x3,0x46,0x5c, 0x2,0x49,0x75, + 0x2,0x49,0x6c, 0x3,0x46,0x54, 0x2,0x49,0x73, 0x2,0x49,0x6a, + 0x2,0x49,0x72, 0x2,0x49,0x76, 0x2,0x49,0x69, 0x2,0x49,0x6d, + 0x2,0x49,0x68, 0x3,0x46,0x56, 0x1,0x68,0x59, 0x4,0x43,0x2c, + 0x2,0x49,0x6b, 0x1,0x68,0x5a, 0x2,0x49,0x71, 0x2,0x49,0x70, + 0x2,0x49,0x6f, 0x3,0x46,0x59, 0x3,0x46,0x5a, 0x2,0x49,0x74, + 0x3,0x64,0x6f, 0x3,0x4b,0x65, 0x3,0x4b,0x66, 0x3,0x4b,0x63, + 0x2,0x50,0x2e, 0x2,0x50,0x30, 0x1,0x6c,0x55, 0x2,0x50,0x31, + 0x3,0x4b,0x6b, 0x2,0x50,0x2c, 0x3,0x4b,0x67, 0x2,0x50,0x2b, + 0x2,0x50,0x35, 0x3,0x4b,0x69, 0x2,0x50,0x33, 0x1,0x6c,0x54, + 0x2,0x50,0x36, 0x2,0x50,0x2d, 0x2,0x50,0x32, 0x2,0x50,0x34, + 0x2,0x50,0x2f, 0x3,0x4b,0x6a, 0x3,0x4b,0x68, 0x3,0x64,0x70, + 0x3,0x50,0x58, 0x2,0x56,0x6b, 0x2,0x56,0x70, 0x2,0x56,0x6a, + 0x2,0x56,0x6f, 0x3,0x50,0x5b, 0x2,0x56,0x68, 0x2,0x56,0x72, + 0x2,0x56,0x6e, 0x2,0x56,0x73, 0x2,0x56,0x6d, 0x2,0x56,0x69, + 0x2,0x56,0x71, 0x3,0x50,0x5a, 0x2,0x56,0x74, 0x2,0x56,0x6c, + 0x3,0x64,0x71, 0x2,0x5c,0x66, 0x1,0x73,0x58, 0x3,0x54,0x57, + 0x1,0x73,0x56, 0x3,0x54,0x59, 0x1,0x73,0x55, 0x1,0x73,0x57, + 0x3,0x54,0x55, 0x3,0x64,0x72, 0x2,0x61,0x50, 0x3,0x57,0x62, + 0x2,0x64,0x3e, 0x2,0x65,0x49, 0x3,0x5a,0x39, 0x2,0x68,0x70, + 0x2,0x68,0x71, 0x3,0x5c,0x3d, 0x1,0x79,0x6b, 0x3,0x5c,0x3c, + 0x2,0x6b,0x57, 0x3,0x5c,0x3e, 0x1,0x7a,0x69, 0x4,0x66,0x3b, + 0x2,0x6b,0x58, 0x3,0x5e,0x2d, 0x2,0x6d,0x4c, 0x1,0x7b,0x5e, + 0x3,0x5f,0x43, 0x1,0x7b,0x5d, 0x2,0x6d,0x4b, 0x1,0x7c,0x35, + 0x3,0x60,0x30, 0x2,0x6f,0x25, 0x4,0x6b,0x68, 0x4,0x6a,0x46, + 0x3,0x21,0x3c, 0x4,0x21,0x2c, 0x1,0x44,0x55, 0x1,0x47,0x7c, + 0x2,0x22,0x3a, 0x2,0x23,0x6a, 0x1,0x4b,0x56, 0x1,0x5a,0x25, + 0x3,0x35,0x57, 0x3,0x4b,0x6c, 0x1,0x44,0x56, 0x1,0x46,0x4a, + 0x1,0x46,0x49, 0x1,0x46,0x48, 0x4,0x22,0x63, 0x1,0x4a,0x27, + 0x1,0x55,0x38, 0x2,0x42,0x5d, 0x1,0x44,0x57, 0x1,0x44,0x58, + 0x1,0x44,0x59, 0x1,0x45,0x3b, 0x3,0x25,0x67, 0x3,0x28,0x60, + 0x1,0x50,0x73, 0x4,0x2c,0x64, 0x2,0x2a,0x30, 0x3,0x2c,0x45, + 0x3,0x2c,0x44, 0x1,0x5e,0x78, 0x1,0x44,0x5a, 0x2,0x21,0x3d, + 0x3,0x21,0x63, 0x4,0x21,0x4c, 0x1,0x46,0x4b, 0x1,0x46,0x4c, + 0x2,0x21,0x59, 0x1,0x47,0x7d, 0x5,0x22,0x5c, 0x3,0x23,0x5c, + 0x3,0x25,0x68, 0x2,0x23,0x6b, 0x3,0x25,0x6b, 0x1,0x4a,0x28, + 0x4,0x24,0x23, 0x2,0x23,0x6c, 0x1,0x4d,0x30, 0x3,0x28,0x62, + 0x3,0x28,0x61, 0x2,0x26,0x4f, 0x1,0x4d,0x2e, 0x1,0x4d,0x2d, + 0x2,0x26,0x4e, 0x1,0x4d,0x2b, 0x2,0x26,0x50, 0x1,0x4d,0x2c, + 0x1,0x4d,0x2f, 0x1,0x50,0x74, 0x3,0x2c,0x46, 0x1,0x50,0x76, + 0x2,0x2a,0x34, 0x2,0x2a,0x31, 0x2,0x2a,0x32, 0x2,0x2a,0x33, + 0x2,0x2a,0x35, 0x1,0x50,0x75, 0x2,0x2e,0x76, 0x2,0x2e,0x75, + 0x3,0x30,0x66, 0x1,0x55,0x3a, 0x3,0x30,0x69, 0x1,0x55,0x39, + 0x3,0x30,0x68, 0x3,0x30,0x6a, 0x3,0x30,0x67, 0x3,0x35,0x5b, + 0x1,0x5a,0x28, 0x2,0x35,0x2a, 0x3,0x35,0x59, 0x1,0x5a,0x27, + 0x1,0x5a,0x29, 0x1,0x5a,0x26, 0x3,0x35,0x58, 0x3,0x35,0x5a, + 0x1,0x5e,0x7a, 0x2,0x35,0x29, 0x5,0x37,0x7c, 0x1,0x5e,0x7b, + 0x2,0x3b,0x57, 0x3,0x39,0x79, 0x1,0x5e,0x7c, 0x2,0x3b,0x56, + 0x1,0x5e,0x79, 0x3,0x3b,0x3a, 0x3,0x3b,0x3b, 0x3,0x3b,0x3d, + 0x2,0x42,0x60, 0x2,0x42,0x62, 0x1,0x63,0x6b, 0x2,0x42,0x61, + 0x2,0x42,0x5f, 0x2,0x42,0x5e, 0x4,0x3d,0x2a, 0x4,0x43,0x35, + 0x3,0x46,0x5d, 0x2,0x49,0x79, 0x1,0x68,0x5f, 0x1,0x68,0x5d, + 0x4,0x43,0x30, 0x1,0x68,0x5e, 0x2,0x49,0x77, 0x2,0x49,0x78, + 0x3,0x4b,0x6d, 0x1,0x68,0x5b, 0x2,0x50,0x3a, 0x2,0x50,0x38, + 0x3,0x4b,0x70, 0x1,0x6c,0x57, 0x2,0x50,0x39, 0x1,0x6c,0x58, + 0x1,0x6c,0x56, 0x1,0x68,0x5c, 0xf,0x4e,0x5e, 0x3,0x64,0x73, + 0x2,0x56,0x77, 0x2,0x56,0x75, 0x2,0x56,0x76, 0x2,0x50,0x37, + 0x2,0x5c,0x68, 0x1,0x73,0x59, 0x2,0x5c,0x67, 0x2,0x61,0x51, + 0x2,0x61,0x52, 0x2,0x56,0x78, 0x2,0x65,0x4a, 0x3,0x66,0x77, + 0x1,0x44,0x5b, 0x1,0x46,0x4d, 0x1,0x48,0x21, 0x2,0x22,0x3b, + 0x1,0x47,0x7e, 0x3,0x28,0x63, 0x1,0x4d,0x31, 0x1,0x63,0x6c, + 0x3,0x21,0x3d, 0x1,0x45,0x3c, 0x1,0x46,0x4e, 0x1,0x50,0x77, + 0x1,0x5e,0x7d, 0x3,0x21,0x3e, 0x2,0x21,0x5a, 0x3,0x22,0x47, + 0x2,0x21,0x5b, 0x3,0x22,0x48, 0x2,0x22,0x3c, 0x3,0x66,0x78, + 0x1,0x4a,0x2a, 0x2,0x23,0x70, 0x2,0x23,0x6e, 0x1,0x4a,0x2b, + 0x2,0x23,0x6d, 0x2,0x23,0x6f, 0x2,0x23,0x71, 0x4,0x24,0x28, + 0x1,0x4a,0x29, 0x3,0x25,0x6e, 0x3,0x25,0x6d, 0x1,0x4d,0x35, + 0x1,0x4d,0x36, 0x1,0x4d,0x33, 0x3,0x28,0x65, 0x3,0x28,0x67, + 0x1,0x4d,0x32, 0x2,0x2a,0x39, 0x1,0x4d,0x34, 0x3,0x28,0x68, + 0x1,0x50,0x78, 0x3,0x2c,0x48, 0x2,0x2a,0x38, 0x2,0x2a,0x3a, + 0x2,0x2a,0x37, 0x2,0x2a,0x3b, 0x1,0x50,0x79, 0x1,0x55,0x3d, + 0x2,0x2e,0x77, 0x3,0x30,0x6c, 0x2,0x2e,0x79, 0x1,0x55,0x3b, + 0x2,0x2e,0x7a, 0x1,0x55,0x3c, 0x2,0x2e,0x78, 0x3,0x30,0x6b, + 0x2,0x2a,0x36, 0x2,0x35,0x2b, 0x2,0x35,0x2e, 0x2,0x35,0x2f, + 0x2,0x35,0x2c, 0x1,0x5a,0x2d, 0x1,0x5a,0x2c, 0x1,0x5a,0x2a, + 0x1,0x5a,0x2b, 0x2,0x35,0x2d, 0x3,0x35,0x61, 0x3,0x35,0x60, + 0x3,0x3b,0x3f, 0x1,0x5a,0x2e, 0x3,0x3b,0x40, 0x3,0x3b,0x3e, + 0x1,0x5f,0x21, 0x1,0x5f,0x22, 0x6,0x48,0x45, 0x1,0x5f,0x23, + 0x2,0x42,0x63, 0x2,0x42,0x65, 0x2,0x42,0x67, 0x1,0x63,0x6e, + 0x1,0x63,0x6d, 0x1,0x5e,0x7e, 0x2,0x42,0x66, 0x2,0x42,0x64, + 0x3,0x64,0x74, 0x2,0x49,0x7d, 0x3,0x46,0x61, 0x3,0x46,0x60, + 0x2,0x49,0x7b, 0x2,0x4a,0x23, 0x1,0x68,0x60, 0x2,0x4a,0x24, + 0x2,0x4a,0x21, 0x1,0x68,0x61, 0x2,0x49,0x7c, 0x2,0x49,0x7a, + 0x2,0x4a,0x22, 0x1,0x6c,0x5a, 0x2,0x50,0x3c, 0x2,0x49,0x7e, + 0x1,0x6c,0x5c, 0x2,0x50,0x3d, 0x1,0x6c,0x5b, 0x1,0x6c,0x5e, + 0x2,0x50,0x3e, 0x1,0x6c,0x59, 0x1,0x6c,0x5d, 0x2,0x56,0x7d, + 0x2,0x56,0x7b, 0x2,0x56,0x7a, 0x2,0x56,0x7c, 0x2,0x56,0x79, + 0x3,0x50,0x5c, 0x4,0x5b,0x21, 0x1,0x78,0x33, 0x3,0x64,0x75, + 0x2,0x68,0x72, 0x2,0x68,0x73, 0x3,0x5c,0x3f, 0x2,0x6b,0x59, + 0x2,0x6d,0x4d, 0x1,0x7d,0x22, 0x3,0x21,0x3f, 0x3,0x23,0x61, + 0x1,0x4d,0x37, 0x1,0x4a,0x2c, 0x3,0x28,0x69, 0x3,0x28,0x6b, + 0x1,0x50,0x7a, 0x3,0x2c,0x4c, 0x3,0x2c,0x4b, 0x3,0x30,0x6e, + 0x1,0x44,0x5c, 0x1,0x45,0x3d, 0x4,0x21,0x4d, 0x1,0x46,0x4f, + 0x2,0x22,0x3d, 0x3,0x25,0x6f, 0x1,0x4a,0x2d, 0x2,0x23,0x72, + 0x3,0x28,0x6d, 0x2,0x2a,0x3c, 0x1,0x50,0x7b, 0x1,0x68,0x62, + 0x1,0x44,0x5d, 0x3,0x21,0x64, 0x3,0x22,0x49, 0x3,0x23,0x62, + 0x1,0x48,0x22, 0xf,0x22,0x4e, 0x3,0x3b,0x42, 0x1,0x63,0x6f, + 0x1,0x44,0x5e, 0x1,0x45,0x3e, 0x1,0x45,0x3f, 0x1,0x46,0x51, + 0x1,0x46,0x50, 0x4,0x22,0x6b, 0x2,0x22,0x3e, 0x1,0x48,0x23, + 0x4,0x22,0x6c, 0x2,0x23,0x73, 0x3,0x25,0x71, 0x1,0x4a,0x2e, + 0x3,0x28,0x6e, 0x2,0x26,0x52, 0x2,0x26,0x53, 0x2,0x26,0x54, + 0x3,0x28,0x70, 0x1,0x4d,0x38, 0x1,0x4d,0x39, 0x2,0x26,0x51, + 0x1,0x4d,0x3a, 0x4,0x29,0x2c, 0x4,0x2c,0x70, 0x1,0x50,0x7c, + 0x2,0x2a,0x3d, 0x3,0x2c,0x4d, 0x2,0x2e,0x7c, 0x1,0x55,0x3e, + 0x3,0x30,0x6f, 0x2,0x2e,0x7b, 0x3,0x35,0x62, 0x1,0x5a,0x2f, + 0x2,0x35,0x30, 0x1,0x5a,0x30, 0x2,0x35,0x31, 0x3,0x35,0x63, + 0x3,0x3b,0x47, 0x3,0x3b,0x45, 0x1,0x5f,0x24, 0x4,0x37,0x45, + 0x3,0x3b,0x44, 0x4,0x3d,0x30, 0x2,0x42,0x68, 0xf,0x41,0x3f, + 0x3,0x41,0x22, 0x2,0x4a,0x26, 0x2,0x4a,0x25, 0x1,0x68,0x63, + 0x4,0x49,0x5e, 0x1,0x6c,0x5f, 0x2,0x50,0x3f, 0x1,0x70,0x53, + 0x2,0x56,0x7e, 0x1,0x73,0x5a, 0x3,0x57,0x63, 0x1,0x7b,0x5f, + 0x2,0x6f,0x27, 0x3,0x21,0x40, 0x3,0x21,0x41, 0x3,0x22,0x4a, + 0x3,0x23,0x51, 0x2,0x26,0x55, 0x3,0x28,0x71, 0x2,0x2a,0x3e, + 0x1,0x5a,0x31, 0x2,0x3b,0x58, 0x1,0x63,0x70, 0x3,0x41,0x23, + 0x3,0x50,0x5e, 0xf,0x54,0x43, 0x3,0x57,0x64, 0x1,0x76,0x41, + 0x3,0x61,0x64, 0x3,0x21,0x42, 0x1,0x4a,0x30, 0x3,0x25,0x72, + 0x1,0x4a,0x2f, 0x1,0x50,0x7d, 0x3,0x2c,0x50, 0x2,0x2e,0x7d, + 0x1,0x5a,0x33, 0x1,0x5d,0x29, 0x1,0x5a,0x34, 0x1,0x5a,0x32, + 0x1,0x5f,0x25, 0x3,0x41,0x24, 0x2,0x4a,0x27, 0x1,0x68,0x64, + 0x1,0x6c,0x60, 0x3,0x5f,0x45, 0x2,0x21,0x2c, 0x2,0x22,0x3f, + 0x4,0x22,0x6d, 0x2,0x23,0x75, 0x1,0x4a,0x31, 0x2,0x23,0x74, + 0x1,0x4a,0x32, 0x4,0x24,0x2c, 0x1,0x4d,0x3e, 0x2,0x26,0x58, + 0x2,0x26,0x57, 0x1,0x4d,0x3d, 0x1,0x4d,0x3b, 0x1,0x4d,0x3c, + 0x2,0x26,0x56, 0x3,0x28,0x76, 0x3,0x28,0x75, 0x1,0x51,0x21, + 0x2,0x2a,0x3f, 0x1,0x51,0x24, 0x1,0x50,0x7e, 0x1,0x51,0x26, + 0x1,0x51,0x22, 0x1,0x51,0x23, 0x1,0x51,0x25, 0x4,0x29,0x31, + 0x3,0x30,0x70, 0x3,0x30,0x72, 0x1,0x55,0x41, 0x1,0x55,0x40, + 0x1,0x55,0x3f, 0x3,0x30,0x71, 0x3,0x64,0x76, 0x2,0x35,0x33, + 0x1,0x5a,0x35, 0x1,0x5a,0x38, 0x1,0x5a,0x36, 0x3,0x64,0x77, + 0x2,0x35,0x32, 0x1,0x5a,0x3b, 0x4,0x31,0x53, 0x1,0x5a,0x37, + 0x2,0x35,0x34, 0x1,0x5a,0x3a, 0x1,0x5a,0x39, 0x4,0x31,0x52, + 0x4,0x31,0x57, 0x4,0x37,0x4a, 0x2,0x3b,0x5a, 0x2,0x3b,0x59, + 0x3,0x3b,0x4b, 0x1,0x5f,0x28, 0x1,0x5f,0x26, 0x1,0x5f,0x27, + 0x2,0x3b,0x5b, 0x1,0x63,0x71, 0x2,0x42,0x6a, 0x1,0x63,0x72, + 0x2,0x42,0x69, 0x4,0x3d,0x34, 0x4,0x43,0x3f, 0x2,0x50,0x40, + 0x3,0x46,0x63, 0x3,0x46,0x64, 0x1,0x6c,0x62, 0x2,0x4a,0x28, + 0x1,0x6c,0x61, 0x3,0x4b,0x72, 0x1,0x68,0x65, 0x3,0x64,0x78, + 0x2,0x57,0x22, 0x2,0x57,0x21, 0x1,0x73,0x5b, 0x2,0x5c,0x69, + 0x2,0x65,0x4b, 0x2,0x68,0x74, 0x2,0x68,0x75, 0x3,0x5e,0x2f, + 0x1,0x45,0x40, 0x4,0x21,0x36, 0x1,0x46,0x52, 0x3,0x22,0x4d, + 0x4,0x22,0x71, 0x2,0x21,0x5c, 0x3,0x22,0x4c, 0x5,0x22,0x66, + 0x1,0x4a,0x34, 0x1,0x4a,0x36, 0x3,0x25,0x78, 0x2,0x22,0x42, + 0x2,0x23,0x78, 0x2,0x23,0x77, 0x2,0x23,0x76, 0x3,0x23,0x66, + 0x2,0x22,0x41, 0x2,0x22,0x40, 0x1,0x48,0x25, 0x1,0x4a,0x35, + 0x1,0x4a,0x33, 0x1,0x48,0x24, 0x3,0x23,0x67, 0x3,0x23,0x69, + 0x3,0x25,0x77, 0x1,0x4d,0x3f, 0x2,0x26,0x59, 0x3,0x25,0x7b, + 0x1,0x4d,0x40, 0x2,0x23,0x7d, 0x4,0x26,0x50, 0x2,0x24,0x21, + 0x2,0x23,0x7e, 0x2,0x26,0x5a, 0x3,0x25,0x76, 0x3,0x25,0x74, + 0x2,0x23,0x7a, 0x3,0x28,0x7e, 0x1,0x4a,0x3a, 0x1,0x4a,0x38, + 0x3,0x25,0x7c, 0x2,0x23,0x79, 0x2,0x23,0x7b, 0x2,0x24,0x23, + 0x3,0x26,0x22, 0x1,0x4a,0x37, 0x3,0x26,0x21, 0x2,0x23,0x7c, + 0x2,0x24,0x27, 0x1,0x4d,0x42, 0x3,0x25,0x7d, 0x2,0x24,0x24, + 0x1,0x4a,0x39, 0x3,0x26,0x23, 0x2,0x24,0x22, 0x2,0x24,0x25, + 0x3,0x25,0x7a, 0x1,0x4d,0x41, 0x3,0x25,0x75, 0x1,0x4d,0x43, + 0x2,0x24,0x26, 0x3,0x28,0x78, 0x3,0x29,0x22, 0x2,0x26,0x6e, + 0x2,0x26,0x61, 0x2,0x26,0x5f, 0x2,0x26,0x6d, 0x2,0x26,0x68, + 0x1,0x51,0x2b, 0x1,0x4d,0x44, 0x2,0x26,0x69, 0x2,0x26,0x6c, + 0x1,0x51,0x27, 0x2,0x26,0x6b, 0x1,0x4d,0x45, 0x1,0x4d,0x4a, + 0x1,0x4d,0x48, 0x2,0x26,0x62, 0x4,0x29,0x36, 0x2,0x26,0x5d, + 0x2,0x26,0x64, 0x1,0x4d,0x4f, 0x2,0x26,0x6f, 0x1,0x51,0x28, + 0x2,0x26,0x65, 0x4,0x26,0x4f, 0x1,0x51,0x29, 0x1,0x4d,0x4b, + 0x2,0x26,0x67, 0x3,0x2c,0x5a, 0x2,0x2a,0x4e, 0x1,0x51,0x2a, + 0x2,0x26,0x5c, 0x1,0x4d,0x4c, 0x1,0x51,0x2c, 0x1,0x4d,0x4d, + 0x1,0x4d,0x49, 0x1,0x4d,0x4e, 0x2,0x26,0x66, 0x2,0x26,0x5b, + 0x2,0x26,0x6a, 0x1,0x4d,0x46, 0x3,0x28,0x77, 0x3,0x2c,0x5b, + 0x2,0x26,0x5e, 0x2,0x26,0x63, 0x2,0x26,0x60, 0x1,0x4d,0x47, + 0x3,0x28,0x7a, 0x2,0x2a,0x40, 0x4,0x29,0x45, 0x2,0x2a,0x41, + 0x3,0x29,0x21, 0x2,0x2a,0x4b, 0x2,0x2f,0x23, 0x2,0x2a,0x4c, + 0x1,0x51,0x32, 0x2,0x2a,0x4f, 0x2,0x2a,0x45, 0x1,0x51,0x31, + 0x2,0x2a,0x47, 0x4,0x29,0x3f, 0x2,0x2a,0x48, 0x3,0x2c,0x60, + 0x3,0x30,0x79, 0x2,0x2a,0x4a, 0x1,0x51,0x2d, 0x3,0x2c,0x56, + 0x3,0x30,0x73, 0x1,0x55,0x45, 0x3,0x2c,0x57, 0x3,0x2c,0x5d, + 0x2,0x2a,0x46, 0x2,0x2a,0x42, 0x1,0x55,0x46, 0x3,0x30,0x7e, + 0x4,0x29,0x3e, 0x2,0x2a,0x50, 0x1,0x55,0x42, 0x2,0x2f,0x21, + 0x2,0x2a,0x49, 0x3,0x2c,0x54, 0x2,0x2e,0x7e, 0x2,0x2a,0x44, + 0x2,0x2a,0x4d, 0x3,0x2c,0x5f, 0x3,0x2c,0x61, 0x1,0x51,0x30, + 0x1,0x55,0x43, 0x1,0x51,0x36, 0x1,0x55,0x44, 0x2,0x2a,0x51, + 0x2,0x2f,0x22, 0x1,0x51,0x2f, 0x1,0x55,0x48, 0x1,0x51,0x35, + 0x1,0x51,0x34, 0x1,0x51,0x33, 0x1,0x55,0x47, 0x2,0x2a,0x52, + 0x1,0x55,0x49, 0x1,0x51,0x2e, 0x4,0x29,0x4b, 0x2,0x2a,0x43, + 0x3,0x30,0x7a, 0x3,0x30,0x78, 0x3,0x30,0x7b, 0x3,0x2c,0x5c, + 0x3,0x30,0x76, 0x1,0x5a,0x3c, 0x2,0x2f,0x26, 0x2,0x2f,0x28, + 0x4,0x2d,0x25, 0x2,0x2f,0x2a, 0x1,0x55,0x4a, 0x1,0x55,0x50, + 0x2,0x35,0x37, 0x2,0x2f,0x2e, 0x2,0x2f,0x25, 0x1,0x5a,0x3e, + 0x2,0x35,0x35, 0x3,0x31,0x22, 0x1,0x55,0x4f, 0x1,0x55,0x4d, + 0x2,0x2f,0x30, 0x4,0x2d,0x2d, 0x2,0x35,0x36, 0x4,0x2d,0x2c, + 0x2,0x2f,0x27, 0x3,0x31,0x25, 0x1,0x55,0x4e, 0x2,0x2f,0x2b, + 0x1,0x55,0x51, 0x2,0x2f,0x2d, 0x3,0x35,0x68, 0x3,0x30,0x74, + 0x1,0x55,0x4c, 0x2,0x2f,0x2c, 0x2,0x2f,0x2f, 0x2,0x2f,0x29, + 0x3,0x31,0x27, 0x1,0x55,0x4b, 0x1,0x5a,0x3f, 0x3,0x35,0x71, + 0x2,0x2f,0x24, 0x1,0x5a,0x3d, 0x3,0x35,0x72, 0x4,0x31,0x6b, + 0x3,0x31,0x23, 0x3,0x31,0x28, 0x1,0x5a,0x40, 0x3,0x31,0x21, + 0x3,0x35,0x6f, 0x3,0x31,0x26, 0x2,0x35,0x39, 0x2,0x35,0x42, + 0x1,0x5f,0x2b, 0x3,0x3b,0x54, 0x1,0x5a,0x42, 0x1,0x5a,0x47, + 0x1,0x5f,0x2c, 0x2,0x35,0x44, 0x1,0x5a,0x4e, 0x2,0x3b,0x5d, + 0x2,0x35,0x3a, 0x1,0x5a,0x46, 0x1,0x5a,0x49, 0x1,0x5a,0x44, + 0x2,0x35,0x38, 0x2,0x35,0x46, 0x2,0x35,0x49, 0x2,0x3b,0x6c, + 0x4,0x31,0x68, 0x2,0x35,0x47, 0x2,0x3b,0x61, 0x1,0x5a,0x45, + 0x1,0x5a,0x4c, 0x1,0x5a,0x50, 0x2,0x35,0x41, 0x2,0x3b,0x5c, + 0x2,0x35,0x45, 0x1,0x5a,0x41, 0x2,0x3b,0x5e, 0x2,0x35,0x48, + 0x2,0x3b,0x60, 0x2,0x35,0x3d, 0x3,0x35,0x6a, 0x1,0x5f,0x29, + 0x3,0x3b,0x56, 0x2,0x35,0x3b, 0x2,0x35,0x3c, 0x1,0x5a,0x4b, + 0x3,0x3b,0x55, 0x3,0x35,0x6e, 0x1,0x5a,0x4a, 0x2,0x35,0x3f, + 0x1,0x5a,0x4f, 0x2,0x35,0x43, 0x1,0x5a,0x48, 0x2,0x35,0x40, + 0x3,0x35,0x79, 0x1,0x5a,0x4d, 0x1,0x5f,0x2d, 0x1,0x5f,0x2a, + 0x2,0x3b,0x5f, 0x3,0x3b,0x58, 0x2,0x35,0x3e, 0x3,0x3b,0x59, + 0x1,0x5a,0x43, 0x3,0x35,0x76, 0x3,0x35,0x78, 0x3,0x3b,0x5a, + 0x3,0x3b,0x4d, 0x3,0x35,0x74, 0x1,0x5f,0x32, 0x1,0x5f,0x36, + 0x2,0x3b,0x63, 0x1,0x63,0x77, 0x1,0x5f,0x34, 0x2,0x3b,0x67, + 0x1,0x5f,0x38, 0x2,0x42,0x6b, 0x2,0x3b,0x69, 0x1,0x63,0x79, + 0x1,0x5f,0x30, 0x1,0x5f,0x33, 0x2,0x3b,0x6a, 0x3,0x3b,0x5e, + 0x2,0x3b,0x6b, 0x2,0x3b,0x71, 0x1,0x5f,0x3a, 0x1,0x63,0x7a, + 0x4,0x3d,0x3d, 0x2,0x3b,0x6d, 0x2,0x3b,0x72, 0x2,0x3b,0x66, + 0x1,0x64,0x26, 0x3,0x3b,0x4f, 0x1,0x63,0x7b, 0x1,0x5f,0x39, + 0x2,0x3b,0x64, 0x2,0x3b,0x73, 0x3,0x3b,0x51, 0x1,0x64,0x25, + 0x1,0x5f,0x37, 0x1,0x63,0x74, 0x2,0x3b,0x70, 0x3,0x3b,0x5d, + 0x1,0x5f,0x3b, 0x2,0x3b,0x68, 0x2,0x3b,0x62, 0x1,0x5f,0x31, + 0x2,0x3b,0x65, 0x5,0x3f,0x30, 0x2,0x3b,0x6e, 0x3,0x41,0x2b, + 0x1,0x63,0x73, 0x1,0x63,0x78, 0x1,0x5f,0x2e, 0x2,0x3b,0x6f, + 0x3,0x3b,0x61, 0x1,0x63,0x76, 0x3,0x3b,0x62, 0x3,0x3b,0x63, + 0x3,0x3b,0x50, 0x1,0x5f,0x2f, 0x3,0x64,0x79, 0x1,0x64,0x24, + 0x2,0x4a,0x2a, 0x2,0x42,0x76, 0x3,0x41,0x29, 0x2,0x42,0x6e, + 0x2,0x4a,0x29, 0x4,0x3d,0x39, 0x2,0x42,0x72, 0x2,0x42,0x74, + 0x3,0x41,0x27, 0x3,0x41,0x2c, 0x2,0x42,0x71, 0x3,0x46,0x6f, + 0x1,0x64,0x23, 0x4,0x3d,0x38, 0x2,0x42,0x70, 0x1,0x64,0x27, + 0x3,0x46,0x6e, 0x6,0x52,0x64, 0x3,0x41,0x28, 0x2,0x4a,0x39, + 0x3,0x46,0x6c, 0x3,0x41,0x2e, 0x1,0x64,0x22, 0x1,0x68,0x67, + 0x2,0x42,0x77, 0x2,0x4a,0x2b, 0x3,0x46,0x6d, 0x3,0x41,0x2a, + 0x1,0x63,0x7e, 0x2,0x42,0x6f, 0x2,0x42,0x73, 0x1,0x68,0x66, + 0x1,0x63,0x75, 0x2,0x42,0x6c, 0x2,0x42,0x6d, 0x1,0x68,0x68, + 0x1,0x63,0x7d, 0x1,0x64,0x21, 0x1,0x63,0x7c, 0x2,0x42,0x75, + 0x3,0x64,0x7a, 0x2,0x4a,0x2f, 0x2,0x4a,0x30, 0x2,0x4a,0x35, + 0x1,0x6c,0x67, 0x2,0x4a,0x3c, 0x3,0x4b,0x73, 0x1,0x68,0x6e, + 0x3,0x4b,0x7e, 0x1,0x68,0x6d, 0x2,0x4a,0x37, 0x3,0x4b,0x74, + 0x1,0x6c,0x66, 0x2,0x4a,0x2c, 0x1,0x68,0x6c, 0x3,0x46,0x71, + 0x2,0x4a,0x3b, 0x1,0x68,0x6a, 0x1,0x68,0x6b, 0x3,0x4b,0x7c, + 0x2,0x4a,0x38, 0x2,0x50,0x51, 0x1,0x6c,0x64, 0x1,0x5f,0x35, + 0x3,0x46,0x72, 0x2,0x4a,0x3a, 0x1,0x6c,0x6b, 0x2,0x4a,0x32, + 0x4,0x49,0x6f, 0x1,0x6c,0x65, 0x3,0x46,0x6a, 0x1,0x6c,0x6a, + 0x2,0x4a,0x2d, 0x2,0x4a,0x31, 0x2,0x4a,0x2e, 0x2,0x4a,0x34, + 0x1,0x68,0x6f, 0x1,0x6c,0x63, 0x1,0x68,0x69, 0x3,0x4c,0x21, + 0x2,0x50,0x43, 0x2,0x4a,0x36, 0x3,0x46,0x68, 0x1,0x6c,0x69, + 0x3,0x46,0x73, 0x1,0x6c,0x6c, 0x7,0x22,0x71, 0x2,0x4a,0x33, + 0x3,0x46,0x6b, 0x1,0x6c,0x68, 0x2,0x50,0x42, 0x5,0x4d,0x2a, + 0x3,0x4c,0x23, 0x3,0x46,0x74, 0x3,0x4c,0x24, 0x3,0x4b,0x77, + 0x2,0x50,0x47, 0x1,0x70,0x57, 0x2,0x50,0x41, 0x2,0x57,0x2e, + 0x2,0x50,0x50, 0x1,0x6c,0x70, 0x3,0x4b,0x7a, 0x1,0x6c,0x6e, + 0x1,0x70,0x55, 0x2,0x50,0x4d, 0x2,0x50,0x49, 0x1,0x6c,0x74, + 0x3,0x4b,0x76, 0x2,0x57,0x25, 0x3,0x50,0x68, 0x3,0x4c,0x28, + 0x3,0x50,0x67, 0x1,0x6c,0x72, 0x2,0x50,0x48, 0x3,0x4c,0x29, + 0x2,0x57,0x23, 0x3,0x4c,0x25, 0x2,0x50,0x4c, 0x4,0x50,0x3b, + 0x2,0x50,0x4f, 0x2,0x50,0x46, 0x3,0x4b,0x79, 0x1,0x6c,0x73, + 0x4,0x50,0x37, 0x3,0x4b,0x75, 0x1,0x6c,0x6d, 0x2,0x57,0x24, + 0x1,0x70,0x56, 0x2,0x50,0x4e, 0x1,0x6c,0x6f, 0x1,0x6c,0x71, + 0x2,0x50,0x4b, 0x1,0x6c,0x75, 0x2,0x50,0x4a, 0x2,0x50,0x45, + 0x2,0x50,0x44, 0x1,0x70,0x54, 0x2,0x50,0x52, 0x2,0x57,0x27, + 0x2,0x5c,0x6b, 0x1,0x70,0x59, 0x3,0x50,0x61, 0x2,0x57,0x2d, + 0x3,0x50,0x63, 0x2,0x57,0x2b, 0x3,0x50,0x6a, 0x2,0x5c,0x6c, + 0x3,0x50,0x64, 0x1,0x70,0x5a, 0x2,0x57,0x2c, 0x3,0x50,0x66, + 0x2,0x57,0x29, 0x1,0x73,0x5d, 0x2,0x5c,0x6a, 0x3,0x50,0x6c, + 0x2,0x57,0x26, 0x2,0x57,0x28, 0x1,0x73,0x5e, 0x1,0x70,0x5c, + 0x1,0x73,0x5c, 0x1,0x70,0x5b, 0x1,0x73,0x60, 0x2,0x57,0x2a, + 0x1,0x70,0x58, 0x3,0x50,0x62, 0x3,0x50,0x65, 0x3,0x50,0x6b, + 0x3,0x66,0x79, 0x4,0x5b,0x2b, 0x2,0x61,0x5b, 0x4,0x56,0x33, + 0x2,0x61,0x53, 0x3,0x54,0x61, 0x3,0x54,0x5f, 0x3,0x54,0x5c, + 0x3,0x54,0x5e, 0x3,0x54,0x5d, 0x2,0x5c,0x72, 0x2,0x61,0x54, + 0x2,0x5c,0x6e, 0x4,0x56,0x32, 0x3,0x54,0x5b, 0x1,0x76,0x42, + 0x2,0x5c,0x70, 0x2,0x5c,0x6f, 0x1,0x73,0x5f, 0x2,0x5c,0x6d, + 0x2,0x5c,0x71, 0x2,0x61,0x5c, 0x2,0x61,0x58, 0x2,0x61,0x5a, + 0x4,0x5f,0x60, 0x2,0x61,0x55, 0x2,0x61,0x56, 0x4,0x5f,0x61, + 0x2,0x61,0x59, 0x2,0x61,0x57, 0x1,0x78,0x34, 0x3,0x57,0x65, + 0x1,0x78,0x37, 0x1,0x78,0x36, 0x1,0x78,0x35, 0x1,0x79,0x6c, + 0x2,0x68,0x76, 0x1,0x79,0x6d, 0x2,0x65,0x4c, 0x1,0x7a,0x6a, + 0x2,0x6b,0x5a, 0x1,0x7a,0x6b, 0x1,0x7b,0x60, 0x1,0x7c,0x36, + 0x2,0x6f,0x28, 0x3,0x5f,0x46, 0x2,0x6f,0x29, 0x2,0x6f,0x2a, + 0x3,0x61,0x3e, 0x2,0x72,0x2a, 0x1,0x45,0x41, 0x2,0x21,0x5d, + 0x1,0x46,0x53, 0x1,0x48,0x27, 0x1,0x48,0x28, 0x1,0x48,0x26, + 0x3,0x23,0x6b, 0x1,0x48,0x29, 0x1,0x4a,0x3c, 0x1,0x4a,0x3b, + 0x3,0x26,0x25, 0x2,0x26,0x70, 0x1,0x4d,0x51, 0x1,0x4d,0x50, + 0x3,0x2c,0x63, 0x2,0x2f,0x31, 0x1,0x5a,0x51, 0x1,0x5a,0x52, + 0x4,0x31,0x6e, 0x4,0x31,0x70, 0x3,0x3b,0x64, 0x1,0x5f,0x3c, + 0x2,0x42,0x78, 0x1,0x64,0x28, 0x1,0x64,0x29, 0x2,0x42,0x7a, + 0x2,0x42,0x7c, 0x2,0x42,0x7b, 0x4,0x3d,0x43, 0x2,0x4a,0x3e, + 0x3,0x46,0x76, 0x2,0x4a,0x3d, 0x1,0x68,0x70, 0x2,0x4a,0x3f, + 0x3,0x46,0x75, 0x2,0x50,0x53, 0x1,0x6c,0x76, 0x3,0x4c,0x2c, + 0x1,0x70,0x5d, 0x3,0x50,0x6d, 0x1,0x73,0x61, 0x1,0x76,0x43, + 0x1,0x73,0x62, 0x3,0x5f,0x48, 0x1,0x45,0x42, 0x3,0x21,0x65, + 0x3,0x21,0x66, 0x3,0x22,0x4e, 0x2,0x24,0x28, 0x3,0x26,0x28, + 0x3,0x26,0x29, 0x2,0x26,0x71, 0x1,0x4d,0x53, 0x1,0x4d,0x52, + 0x1,0x4d,0x54, 0x1,0x51,0x37, 0x2,0x2a,0x53, 0x2,0x2a,0x54, + 0x3,0x31,0x29, 0x2,0x2f,0x32, 0x1,0x55,0x52, 0x1,0x5a,0x53, + 0x1,0x5f,0x3d, 0x2,0x3b,0x74, 0x1,0x45,0x43, 0x4,0x21,0x37, + 0x1,0x44,0x5f, 0x1,0x45,0x44, 0x3,0x22,0x50, 0x2,0x21,0x5e, + 0x1,0x46,0x57, 0x1,0x46,0x56, 0x1,0x46,0x54, 0x1,0x46,0x55, + 0x3,0x23,0x6f, 0x1,0x48,0x2c, 0x2,0x22,0x49, 0x2,0x22,0x4b, + 0x1,0x48,0x2b, 0x2,0x22,0x43, 0x3,0x23,0x6c, 0x2,0x22,0x44, + 0x3,0x23,0x6d, 0x2,0x22,0x4a, 0x2,0x22,0x46, 0x2,0x22,0x48, + 0x1,0x48,0x2a, 0x2,0x22,0x45, 0x2,0x22,0x4c, 0x2,0x22,0x47, + 0x3,0x23,0x6e, 0xf,0x22,0x51, 0x1,0x4a,0x43, 0x1,0x4a,0x4c, + 0x1,0x4a,0x4a, 0x2,0x24,0x32, 0x2,0x24,0x2f, 0x2,0x24,0x37, + 0x1,0x4a,0x48, 0x2,0x24,0x38, 0x3,0x26,0x39, 0x1,0x4a,0x41, + 0x2,0x24,0x35, 0x3,0x26,0x2e, 0x1,0x4a,0x47, 0x2,0x24,0x31, + 0x2,0x24,0x30, 0x1,0x4a,0x45, 0x2,0x24,0x36, 0x1,0x4a,0x46, + 0x1,0x4d,0x55, 0x1,0x4a,0x40, 0x2,0x24,0x33, 0x3,0x26,0x2a, + 0x2,0x24,0x29, 0x1,0x4a,0x3d, 0x3,0x26,0x37, 0x1,0x4a,0x50, + 0x2,0x24,0x2e, 0x2,0x24,0x34, 0x1,0x4a,0x42, 0x1,0x4a,0x44, + 0x3,0x26,0x2f, 0x2,0x24,0x2a, 0x3,0x26,0x36, 0x2,0x24,0x2b, + 0x2,0x24,0x2c, 0x4,0x24,0x39, 0x1,0x4a,0x4f, 0x1,0x4a,0x49, + 0x1,0x4a,0x4e, 0x2,0x24,0x2d, 0x1,0x4a,0x4d, 0x1,0x4a,0x3f, + 0x1,0x4a,0x3e, 0x1,0x4a,0x4b, 0x3,0x26,0x35, 0x4,0x24,0x3c, + 0x3,0x26,0x33, 0x3,0x26,0x34, 0x3,0x26,0x38, 0x3,0x26,0x31, + 0x3,0x64,0x7b, 0xf,0x24,0x39, 0x3,0x26,0x32, 0x3,0x29,0x31, + 0x3,0x29,0x2a, 0x1,0x4d,0x63, 0x2,0x26,0x7d, 0x2,0x26,0x76, + 0x1,0x4d,0x5e, 0x1,0x4d,0x71, 0x2,0x26,0x72, 0x2,0x26,0x79, + 0x2,0x26,0x7b, 0x2,0x26,0x7e, 0x1,0x4d,0x6c, 0x3,0x29,0x26, + 0x2,0x26,0x7a, 0x2,0x26,0x73, 0x1,0x4d,0x6a, 0x2,0x26,0x77, + 0x3,0x29,0x28, 0x2,0x27,0x21, 0x1,0x4d,0x5b, 0x3,0x29,0x25, + 0x2,0x26,0x7c, 0x1,0x4d,0x65, 0x1,0x4d,0x64, 0x2,0x26,0x75, + 0x1,0x4d,0x59, 0x3,0x29,0x34, 0x3,0x29,0x32, 0x1,0x4d,0x5a, + 0xf,0x27,0x30, 0x1,0x4d,0x58, 0x3,0x29,0x33, 0x1,0x4d,0x70, + 0x1,0x4d,0x68, 0x1,0x4d,0x62, 0x1,0x4d,0x56, 0x2,0x26,0x78, + 0x1,0x4d,0x61, 0x1,0x4d,0x57, 0x1,0x4d,0x69, 0x1,0x4d,0x72, + 0x2,0x2a,0x55, 0x1,0x4d,0x66, 0x2,0x26,0x74, 0x1,0x4d,0x5c, + 0x1,0x4d,0x5f, 0x1,0x4d,0x60, 0x3,0x29,0x2e, 0x1,0x4d,0x6e, + 0x1,0x4d,0x6f, 0x1,0x4d,0x6d, 0x1,0x4d,0x67, 0x1,0x4d,0x6b, + 0x1,0x4d,0x5d, 0x1,0x51,0x38, 0x3,0x29,0x30, 0x3,0x29,0x37, + 0x3,0x29,0x35, 0x3,0x29,0x36, 0x3,0x29,0x2f, 0x3,0x29,0x29, + 0x3,0x2c,0x6d, 0x2,0x2a,0x5b, 0x1,0x51,0x44, 0x1,0x51,0x3c, + 0x1,0x51,0x3e, 0x1,0x51,0x43, 0x2,0x2a,0x67, 0x1,0x51,0x41, + 0x2,0x2f,0x33, 0x1,0x55,0x53, 0x1,0x51,0x46, 0x2,0x2a,0x58, + 0x2,0x2a,0x60, 0x1,0x51,0x42, 0x2,0x2a,0x5f, 0x2,0x2a,0x5c, + 0x2,0x2a,0x64, 0x2,0x2a,0x66, 0x1,0x51,0x3b, 0x1,0x51,0x3f, + 0x1,0x51,0x45, 0x1,0x55,0x55, 0x2,0x2a,0x61, 0x1,0x51,0x3d, + 0x1,0x51,0x48, 0x2,0x2a,0x5a, 0x3,0x2c,0x6f, 0x3,0x2c,0x70, + 0x5,0x29,0x45, 0x1,0x51,0x40, 0x1,0x55,0x54, 0x1,0x51,0x3a, + 0x4,0x29,0x59, 0x2,0x2a,0x57, 0x2,0x2a,0x5e, 0x2,0x2a,0x56, + 0x2,0x2a,0x59, 0x2,0x2a,0x5d, 0x2,0x2f,0x34, 0x1,0x51,0x47, + 0x4,0x29,0x51, 0x2,0x2a,0x62, 0x2,0x2a,0x63, 0x2,0x2a,0x65, + 0x1,0x51,0x39, 0x3,0x2c,0x6c, 0x3,0x31,0x32, 0x3,0x31,0x33, + 0x3,0x2c,0x6b, 0x3,0x2c,0x6e, 0x4,0x29,0x5b, 0x1,0x55,0x63, + 0x2,0x2f,0x40, 0x1,0x55,0x61, 0x1,0x55,0x62, 0x2,0x2f,0x36, + 0x2,0x2f,0x46, 0x3,0x31,0x2c, 0x1,0x55,0x58, 0x3,0x31,0x2f, + 0x3,0x31,0x35, 0x2,0x35,0x4a, 0x2,0x2f,0x48, 0x2,0x2f,0x42, + 0x3,0x31,0x38, 0x2,0x2f,0x39, 0x3,0x31,0x37, 0x2,0x2f,0x4b, + 0x2,0x2f,0x3c, 0x1,0x55,0x5e, 0x2,0x35,0x61, 0x2,0x2f,0x3f, + 0x1,0x55,0x60, 0x1,0x55,0x57, 0x3,0x31,0x3c, 0x2,0x2f,0x4d, + 0x2,0x2f,0x41, 0x1,0x55,0x5a, 0x2,0x2f,0x3a, 0x2,0x2f,0x37, + 0x2,0x2f,0x38, 0x1,0x55,0x5b, 0x2,0x2f,0x47, 0x2,0x2f,0x4e, + 0x1,0x55,0x5d, 0x2,0x2f,0x3e, 0x2,0x2f,0x3d, 0x1,0x55,0x65, + 0x1,0x55,0x64, 0x1,0x55,0x56, 0x1,0x55,0x5c, 0x1,0x55,0x5f, + 0x2,0x2f,0x4a, 0x3,0x31,0x2e, 0x3,0x31,0x39, 0x2,0x2f,0x44, + 0x1,0x55,0x59, 0x2,0x2f,0x35, 0x2,0x2f,0x4c, 0x2,0x2f,0x43, + 0x2,0x2f,0x45, 0x2,0x2f,0x49, 0x3,0x31,0x30, 0x3,0x31,0x3b, + 0x3,0x31,0x36, 0x3,0x64,0x7c, 0x3,0x64,0x7d, 0x2,0x35,0x4b, + 0x3,0x36,0x31, 0x1,0x5a,0x5b, 0x1,0x5a,0x6f, 0x1,0x5a,0x6e, + 0x3,0x36,0x27, 0x1,0x5a,0x63, 0x3,0x36,0x29, 0x2,0x35,0x5d, + 0x2,0x35,0x59, 0x2,0x35,0x56, 0x2,0x35,0x68, 0x1,0x5a,0x5e, + 0x1,0x5a,0x56, 0x3,0x36,0x26, 0x3,0x36,0x32, 0x2,0x35,0x5b, + 0x1,0x5f,0x4d, 0x1,0x5a,0x5a, 0x2,0x35,0x63, 0x3,0x36,0x22, + 0x1,0x5a,0x70, 0x1,0x5a,0x6d, 0x2,0x35,0x5f, 0x2,0x35,0x4e, + 0x3,0x35,0x7c, 0x3,0x36,0x2b, 0x1,0x5a,0x6c, 0x2,0x35,0x65, + 0x2,0x35,0x4d, 0x1,0x5a,0x61, 0x1,0x5a,0x65, 0x2,0x35,0x64, + 0x3,0x36,0x23, 0x2,0x35,0x57, 0x1,0x5a,0x66, 0x1,0x5a,0x60, + 0x2,0x35,0x4c, 0x3,0x35,0x7d, 0x1,0x5f,0x3f, 0x2,0x35,0x67, + 0x2,0x35,0x55, 0x1,0x5a,0x6b, 0x2,0x35,0x58, 0x2,0x35,0x66, + 0x1,0x5a,0x6a, 0x3,0x36,0x24, 0x2,0x3b,0x75, 0x4,0x31,0x77, + 0x1,0x5a,0x57, 0x2,0x35,0x53, 0x1,0x5a,0x5c, 0x1,0x5a,0x67, + 0x4,0x31,0x78, 0x1,0x5a,0x62, 0x2,0x35,0x5c, 0x2,0x35,0x52, + 0x2,0x35,0x50, 0x2,0x35,0x62, 0x1,0x5a,0x54, 0x1,0x5a,0x68, + 0x1,0x5a,0x58, 0x1,0x5f,0x3e, 0x2,0x35,0x60, 0x1,0x5a,0x59, + 0x4,0x32,0x23, 0x1,0x5a,0x55, 0x1,0x5a,0x64, 0x1,0x5a,0x5f, + 0x1,0x5a,0x5d, 0x2,0x35,0x54, 0x1,0x5a,0x69, 0x2,0x35,0x51, + 0x2,0x35,0x5e, 0x2,0x35,0x5a, 0x2,0x3b,0x77, 0x2,0x3b,0x76, + 0x3,0x36,0x2d, 0x3,0x64,0x7e, 0x3,0x36,0x2e, 0x2,0x35,0x4f, + 0x2,0x3c,0x29, 0x3,0x3b,0x71, 0x1,0x5f,0x41, 0x3,0x3b,0x70, + 0x2,0x3c,0x2f, 0x2,0x3b,0x7c, 0x2,0x3c,0x2c, 0x2,0x42,0x7d, + 0x1,0x5f,0x44, 0x2,0x3c,0x30, 0x2,0x3c,0x33, 0x1,0x5f,0x43, + 0x2,0x3c,0x21, 0x2,0x3c,0x32, 0x2,0x3c,0x31, 0x1,0x5f,0x45, + 0x2,0x3b,0x78, 0x1,0x5f,0x40, 0x1,0x5f,0x48, 0x3,0x3b,0x73, + 0x1,0x5f,0x46, 0x2,0x3c,0x2e, 0x4,0x37,0x71, 0x2,0x3c,0x24, + 0x1,0x5f,0x4a, 0x2,0x3c,0x35, 0x2,0x3c,0x2d, 0x2,0x3c,0x36, + 0x1,0x5f,0x52, 0x1,0x5f,0x50, 0x2,0x3c,0x2b, 0x2,0x3c,0x2a, + 0x3,0x3b,0x67, 0x2,0x3c,0x28, 0x2,0x3c,0x22, 0x1,0x5f,0x49, + 0x3,0x3b,0x66, 0x1,0x5f,0x47, 0x2,0x2f,0x3b, 0x2,0x3b,0x79, + 0x3,0x3b,0x68, 0x2,0x43,0x3d, 0x2,0x3b,0x7a, 0x1,0x5f,0x42, + 0x1,0x5f,0x4f, 0x2,0x43,0x21, 0x4,0x37,0x60, 0x1,0x5f,0x4b, + 0x1,0x5f,0x4c, 0x2,0x3b,0x7b, 0x2,0x3c,0x34, 0x2,0x42,0x7e, + 0x2,0x3c,0x25, 0x2,0x3b,0x7e, 0x1,0x5f,0x4e, 0x2,0x3c,0x26, + 0x2,0x3c,0x23, 0x3,0x3b,0x72, 0x3,0x3b,0x6d, 0x1,0x5f,0x53, + 0x4,0x37,0x6f, 0x3,0x3b,0x6f, 0x3,0x65,0x21, 0x1,0x64,0x38, + 0x3,0x41,0x49, 0x3,0x41,0x32, 0x2,0x43,0x24, 0x2,0x43,0x37, + 0x2,0x43,0x3c, 0x2,0x43,0x30, 0x1,0x64,0x34, 0x2,0x43,0x41, + 0x1,0x64,0x31, 0x2,0x43,0x22, 0x3,0x41,0x3a, 0x2,0x43,0x23, + 0x1,0x64,0x2a, 0x1,0x64,0x33, 0x2,0x43,0x2a, 0x1,0x64,0x36, + 0x1,0x64,0x37, 0x2,0x43,0x2b, 0x3,0x41,0x38, 0x2,0x43,0x38, + 0x2,0x43,0x3e, 0x1,0x64,0x32, 0x3,0x41,0x3e, 0x1,0x64,0x2c, + 0x2,0x43,0x29, 0x2,0x43,0x25, 0x2,0x43,0x40, 0x2,0x43,0x2e, + 0x2,0x43,0x2f, 0x2,0x43,0x26, 0x2,0x43,0x3a, 0x2,0x43,0x31, + 0x2,0x43,0x3b, 0x2,0x43,0x33, 0x3,0x41,0x3d, 0x1,0x64,0x2d, + 0x2,0x4a,0x40, 0x1,0x64,0x30, 0x1,0x64,0x2e, 0x2,0x43,0x3f, + 0x2,0x43,0x36, 0x2,0x43,0x32, 0x3,0x41,0x36, 0x3,0x41,0x33, + 0x2,0x43,0x27, 0x1,0x68,0x7a, 0x2,0x43,0x35, 0x1,0x64,0x35, + 0x2,0x43,0x2d, 0x3,0x41,0x34, 0x2,0x43,0x2c, 0x3,0x41,0x48, + 0x3,0x47,0x25, 0x3,0x41,0x42, 0x1,0x64,0x2f, 0x1,0x64,0x2b, + 0x2,0x4a,0x55, 0x2,0x43,0x39, 0x2,0x43,0x34, 0x2,0x43,0x28, + 0x3,0x41,0x44, 0x3,0x41,0x45, 0x3,0x66,0x76, 0x2,0x4a,0x50, + 0x3,0x46,0x78, 0x2,0x4a,0x41, 0x2,0x4a,0x4c, 0x3,0x47,0x28, + 0x2,0x4a,0x53, 0x1,0x68,0x78, 0x1,0x5f,0x51, 0x2,0x4a,0x51, + 0x1,0x68,0x73, 0x3,0x46,0x7e, 0x3,0x47,0x24, 0x3,0x46,0x7a, + 0x1,0x68,0x72, 0x2,0x4a,0x58, 0x4,0x43,0x5d, 0x2,0x4a,0x42, + 0x2,0x4a,0x4f, 0x2,0x4a,0x43, 0x2,0x4a,0x4e, 0x1,0x68,0x76, + 0x2,0x4a,0x52, 0x2,0x3c,0x27, 0x3,0x47,0x21, 0x4,0x43,0x5e, + 0x3,0x47,0x2a, 0x2,0x4a,0x59, 0x2,0x4a,0x4a, 0x1,0x68,0x79, + 0x2,0x50,0x61, 0x1,0x6c,0x77, 0x3,0x47,0x23, 0x2,0x4a,0x57, + 0x2,0x4a,0x56, 0x1,0x68,0x7b, 0x2,0x50,0x54, 0x1,0x6c,0x78, + 0x2,0x50,0x55, 0x3,0x47,0x22, 0x2,0x4a,0x46, 0x2,0x4a,0x47, + 0x2,0x4a,0x44, 0x2,0x4a,0x49, 0x2,0x4a,0x45, 0x2,0x4a,0x5a, + 0x1,0x68,0x75, 0x1,0x6c,0x79, 0x1,0x68,0x77, 0x1,0x68,0x7c, + 0x3,0x46,0x7b, 0x2,0x4a,0x48, 0x3,0x47,0x29, 0x2,0x4a,0x54, + 0x3,0x4c,0x2d, 0x3,0x47,0x26, 0x2,0x4a,0x4d, 0x3,0x4c,0x35, + 0x2,0x50,0x58, 0x3,0x4c,0x38, 0x1,0x68,0x71, 0x1,0x6c,0x7c, + 0x2,0x57,0x35, 0x2,0x50,0x5d, 0x2,0x50,0x5c, 0x2,0x50,0x5e, + 0x3,0x4c,0x30, 0x3,0x4c,0x2f, 0x2,0x50,0x5b, 0x1,0x6c,0x7d, + 0x3,0x4c,0x3b, 0x1,0x6d,0x25, 0x1,0x6d,0x22, 0x3,0x4c,0x31, + 0x1,0x6d,0x23, 0x2,0x50,0x56, 0x2,0x50,0x59, 0x2,0x50,0x63, + 0x1,0x6d,0x2b, 0x1,0x6d,0x29, 0x3,0x4c,0x2e, 0x2,0x50,0x5a, + 0x2,0x3b,0x7d, 0x1,0x6c,0x7a, 0x2,0x50,0x60, 0x2,0x50,0x57, + 0x3,0x4c,0x3e, 0x1,0x6d,0x2c, 0x2,0x50,0x5f, 0x1,0x68,0x74, + 0x1,0x6d,0x21, 0x2,0x4a,0x4b, 0x3,0x4c,0x3f, 0x3,0x4c,0x34, + 0x1,0x6d,0x24, 0x3,0x4c,0x3d, 0x1,0x6d,0x28, 0x1,0x6d,0x2a, + 0x1,0x6d,0x27, 0x1,0x6d,0x26, 0x3,0x4c,0x3a, 0x1,0x6c,0x7e, + 0x2,0x50,0x62, 0x1,0x6c,0x7b, 0x1,0x6d,0x2d, 0x3,0x4c,0x39, + 0x3,0x65,0x22, 0x3,0x4c,0x37, 0x1,0x70,0x61, 0x1,0x70,0x62, + 0x2,0x57,0x34, 0x1,0x70,0x6b, 0x1,0x70,0x68, 0x3,0x50,0x70, + 0x1,0x70,0x5f, 0x1,0x70,0x66, 0x2,0x57,0x36, 0x1,0x70,0x64, + 0x1,0x70,0x5e, 0x3,0x4c,0x32, 0x1,0x70,0x65, 0x3,0x50,0x77, + 0x2,0x57,0x33, 0x1,0x73,0x64, 0x1,0x70,0x60, 0x5,0x54,0x5e, + 0x1,0x70,0x67, 0x1,0x73,0x63, 0x2,0x57,0x32, 0x2,0x57,0x31, + 0x3,0x50,0x76, 0x1,0x70,0x69, 0x3,0x50,0x6f, 0x1,0x70,0x6a, + 0x3,0x50,0x79, 0x2,0x57,0x30, 0x2,0x57,0x2f, 0x1,0x73,0x65, + 0x2,0x57,0x39, 0x1,0x70,0x63, 0x2,0x57,0x37, 0x3,0x50,0x75, + 0x3,0x54,0x64, 0x1,0x73,0x66, 0x3,0x54,0x67, 0x1,0x73,0x6b, + 0x2,0x5c,0x75, 0x2,0x5c,0x77, 0x3,0x57,0x6b, 0x1,0x73,0x68, + 0x3,0x57,0x6d, 0x2,0x5c,0x78, 0x2,0x5c,0x74, 0x3,0x57,0x6c, + 0x2,0x5c,0x76, 0x1,0x73,0x69, 0x1,0x73,0x6c, 0x3,0x54,0x69, + 0x2,0x5c,0x73, 0x1,0x73,0x67, 0x1,0x73,0x6a, 0x1,0x76,0x45, + 0x2,0x57,0x38, 0x1,0x76,0x44, 0x7,0x3f,0x62, 0x3,0x57,0x6a, + 0x1,0x76,0x4a, 0x2,0x61,0x60, 0x3,0x57,0x70, 0x1,0x76,0x48, + 0x1,0x76,0x49, 0x2,0x61,0x63, 0x2,0x61,0x5f, 0x1,0x76,0x46, + 0x2,0x61,0x5d, 0x1,0x78,0x38, 0x2,0x61,0x61, 0x4,0x5b,0x36, + 0x2,0x61,0x62, 0x2,0x61,0x5e, 0x3,0x57,0x6e, 0x1,0x76,0x47, + 0x2,0x65,0x4d, 0x3,0x5a,0x3b, 0x2,0x65,0x50, 0x3,0x5a,0x3c, + 0x3,0x5a,0x3a, 0x2,0x65,0x51, 0x2,0x65,0x4f, 0x2,0x65,0x52, + 0x1,0x78,0x39, 0x2,0x65,0x4e, 0x3,0x5e,0x31, 0x2,0x68,0x7a, + 0x1,0x79,0x6f, 0x2,0x68,0x79, 0x2,0x68,0x78, 0x2,0x68,0x77, + 0x1,0x79,0x6e, 0x1,0x79,0x70, 0x3,0x65,0x23, 0x2,0x6b,0x5b, + 0x1,0x7a,0x6d, 0x1,0x7a,0x6c, 0x3,0x5f,0x4a, 0x3,0x5f,0x4b, + 0x2,0x6d,0x4f, 0x2,0x6d,0x4e, 0x2,0x6d,0x51, 0x1,0x7c,0x37, + 0x1,0x7b,0x61, 0x2,0x6f,0x2c, 0x2,0x6d,0x50, 0x3,0x5f,0x49, + 0x3,0x60,0x32, 0x2,0x6f,0x2b, 0x1,0x7c,0x39, 0x1,0x7c,0x38, + 0x1,0x7c,0x5f, 0x2,0x70,0x37, 0x2,0x70,0x7d, 0x1,0x45,0x45, + 0x6,0x23,0x6c, 0x3,0x2c,0x72, 0x2,0x3c,0x37, 0x2,0x57,0x3a, + 0x3,0x21,0x67, 0x3,0x21,0x68, 0x1,0x48,0x2d, 0x2,0x22,0x4d, + 0x1,0x4a,0x53, 0x1,0x4a,0x51, 0x4,0x24,0x3f, 0x1,0x4a,0x52, + 0x4,0x24,0x3e, 0x2,0x27,0x22, 0x1,0x4d,0x73, 0x1,0x51,0x49, + 0x3,0x2c,0x74, 0x2,0x2a,0x68, 0x3,0x2c,0x76, 0x2,0x2a,0x69, + 0x3,0x2c,0x73, 0x1,0x51,0x4a, 0x2,0x2f,0x50, 0x4,0x2d,0x43, + 0x1,0x55,0x66, 0x1,0x55,0x67, 0x2,0x2f,0x4f, 0x3,0x31,0x3d, + 0x4,0x2d,0x44, 0x3,0x36,0x37, 0x3,0x36,0x36, 0x1,0x5a,0x77, + 0x4,0x32,0x2b, 0x1,0x5a,0x73, 0x4,0x32,0x2f, 0x2,0x35,0x69, + 0x1,0x5a,0x7a, 0x1,0x5a,0x79, 0x1,0x5a,0x72, 0x1,0x5a,0x75, + 0x1,0x5a,0x78, 0x1,0x5a,0x74, 0x3,0x36,0x34, 0x2,0x3c,0x3b, + 0x1,0x5a,0x71, 0x1,0x5f,0x54, 0x3,0x3b,0x74, 0x3,0x3b,0x75, + 0x3,0x3b,0x76, 0x1,0x5f,0x56, 0x1,0x5f,0x57, 0x2,0x3c,0x3a, + 0x2,0x3c,0x3d, 0x1,0x5f,0x55, 0x2,0x3c,0x38, 0x2,0x3c,0x3c, + 0x2,0x3c,0x39, 0x3,0x41,0x4b, 0x1,0x64,0x39, 0x3,0x41,0x4e, + 0x4,0x3d,0x5d, 0x2,0x43,0x42, 0x3,0x41,0x4d, 0x3,0x47,0x30, + 0x1,0x68,0x7d, 0x2,0x4a,0x5b, 0x1,0x70,0x6c, 0x1,0x6d,0x2e, + 0x2,0x50,0x64, 0x1,0x6d,0x2f, 0x1,0x6d,0x30, 0x2,0x50,0x66, + 0x2,0x50,0x65, 0x2,0x50,0x67, 0x2,0x57,0x3c, 0x2,0x57,0x3b, + 0x2,0x5c,0x7a, 0x2,0x5c,0x79, 0x1,0x73,0x6d, 0x1,0x73,0x6e, + 0x2,0x65,0x53, 0x3,0x5c,0x41, 0x1,0x45,0x46, 0x3,0x25,0x58, + 0x3,0x29,0x39, 0x4,0x2d,0x47, 0x3,0x31,0x40, 0x2,0x3c,0x3e, + 0x3,0x36,0x38, 0x3,0x36,0x39, 0x1,0x5f,0x59, 0x1,0x5f,0x58, + 0x2,0x43,0x43, 0x2,0x61,0x64, 0x1,0x7a,0x6e, 0x2,0x6f,0x2d, + 0x1,0x45,0x47, 0x4,0x24,0x41, 0x1,0x55,0x68, 0x3,0x31,0x42, + 0x1,0x5a,0x7c, 0x1,0x5a,0x7b, 0x2,0x3c,0x3f, 0x2,0x3c,0x40, + 0x1,0x64,0x3a, 0x2,0x4a,0x5c, 0x1,0x68,0x7e, 0x2,0x57,0x3d, + 0x4,0x56,0x3f, 0x1,0x45,0x48, 0x1,0x46,0x58, 0x3,0x29,0x3b, + 0x1,0x4d,0x74, 0x2,0x27,0x23, 0x2,0x2a,0x6a, 0x1,0x51,0x4b, + 0x1,0x5a,0x7d, 0x3,0x36,0x3a, 0x2,0x3c,0x41, 0x1,0x5f,0x5a, + 0x1,0x64,0x3b, 0x4,0x3d,0x63, 0x2,0x50,0x68, 0x2,0x50,0x69, + 0x4,0x50,0x4e, 0x3,0x54,0x6b, 0x2,0x5c,0x7b, 0x1,0x76,0x4b, + 0x2,0x70,0x7e, 0x1,0x45,0x49, 0x3,0x29,0x3c, 0x2,0x27,0x24, + 0x1,0x4d,0x75, 0x1,0x51,0x4c, 0x3,0x2c,0x77, 0x2,0x2a,0x6b, + 0x1,0x55,0x69, 0x2,0x2f,0x54, 0x2,0x2f,0x52, 0x2,0x2f,0x53, + 0x1,0x55,0x6a, 0x2,0x2f,0x51, 0x3,0x36,0x3c, 0x4,0x32,0x34, + 0x3,0x36,0x3f, 0x3,0x36,0x3d, 0x1,0x5b,0x21, 0x1,0x5b,0x22, + 0x2,0x35,0x6a, 0x1,0x5b,0x23, 0x1,0x5a,0x7e, 0x2,0x3c,0x42, + 0x3,0x3b,0x79, 0x2,0x3c,0x43, 0x2,0x43,0x44, 0x4,0x3d,0x64, + 0x1,0x69,0x22, 0x1,0x69,0x21, 0x4,0x50,0x4f, 0xf,0x54,0x64, + 0x2,0x5c,0x7c, 0x2,0x61,0x65, 0x3,0x5a,0x3f, 0x2,0x65,0x55, + 0x2,0x65,0x54, 0x2,0x68,0x7b, 0x3,0x21,0x69, 0x2,0x21,0x3e, + 0x1,0x51,0x4d, 0x3,0x36,0x41, 0x3,0x41,0x50, 0x1,0x45,0x4a, + 0x1,0x46,0x59, 0x3,0x22,0x51, 0x1,0x48,0x2f, 0x1,0x48,0x2e, + 0x3,0x23,0x73, 0x3,0x23,0x72, 0x1,0x48,0x30, 0x1,0x48,0x31, + 0x2,0x22,0x4f, 0x2,0x22,0x4e, 0x2,0x24,0x39, 0x1,0x4a,0x54, + 0x2,0x24,0x3c, 0x2,0x24,0x3b, 0x2,0x24,0x3a, 0x2,0x24,0x3d, + 0x3,0x26,0x3d, 0x4,0x26,0x62, 0x1,0x4d,0x76, 0x2,0x27,0x2a, + 0x2,0x27,0x26, 0x2,0x27,0x2f, 0x3,0x29,0x43, 0x3,0x29,0x3e, + 0x1,0x4d,0x7d, 0x3,0x29,0x42, 0x1,0x4d,0x7b, 0x2,0x27,0x2b, + 0x2,0x27,0x27, 0x2,0x27,0x2e, 0x1,0x4d,0x7a, 0x1,0x4e,0x23, + 0x2,0x27,0x29, 0x2,0x27,0x25, 0x1,0x4e,0x22, 0x2,0x27,0x2c, + 0x1,0x4d,0x79, 0x2,0x27,0x2d, 0x1,0x4d,0x7c, 0x1,0x4d,0x7e, + 0x2,0x27,0x31, 0x2,0x27,0x30, 0x2,0x27,0x28, 0x1,0x4d,0x78, + 0x1,0x4d,0x77, 0x1,0x4e,0x21, 0x4,0x26,0x61, 0x3,0x29,0x40, + 0x3,0x29,0x41, 0xf,0x27,0x3e, 0x3,0x2c,0x7e, 0x3,0x2c,0x7a, + 0x2,0x2a,0x70, 0x2,0x2a,0x76, 0x3,0x2d,0x23, 0x1,0x51,0x53, + 0x1,0x51,0x50, 0x2,0x2a,0x6d, 0x2,0x2a,0x72, 0x3,0x2c,0x7c, + 0x1,0x51,0x56, 0x1,0x51,0x4e, 0x2,0x2a,0x71, 0x1,0x51,0x51, + 0x1,0x51,0x54, 0x3,0x2c,0x79, 0x4,0x29,0x67, 0x2,0x2a,0x74, + 0x3,0x2c,0x7d, 0x1,0x51,0x4f, 0x2,0x2a,0x79, 0x1,0x51,0x52, + 0x3,0x2d,0x21, 0x1,0x51,0x55, 0x2,0x2a,0x6e, 0x2,0x2a,0x73, + 0x2,0x2a,0x77, 0x2,0x2a,0x6f, 0x2,0x2a,0x6c, 0x3,0x2d,0x24, + 0x3,0x2d,0x25, 0x2,0x2a,0x78, 0x2,0x2a,0x75, 0x3,0x2d,0x22, + 0x3,0x2c,0x37, 0x3,0x31,0x46, 0x1,0x55,0x72, 0x1,0x55,0x6b, + 0x1,0x55,0x6e, 0x3,0x31,0x4c, 0x1,0x55,0x71, 0x3,0x31,0x44, + 0x2,0x2f,0x57, 0x3,0x31,0x49, 0x1,0x55,0x6c, 0x2,0x2f,0x55, + 0x3,0x31,0x48, 0x1,0x55,0x70, 0x3,0x31,0x4d, 0x3,0x31,0x45, + 0x1,0x55,0x6d, 0x3,0x31,0x43, 0x2,0x2f,0x58, 0x1,0x55,0x6f, + 0x3,0x36,0x42, 0x4,0x32,0x39, 0x2,0x35,0x6e, 0x1,0x5b,0x25, + 0x2,0x35,0x6d, 0x2,0x35,0x6f, 0x1,0x5b,0x24, 0x1,0x5b,0x29, + 0x2,0x2f,0x56, 0x3,0x31,0x4b, 0x2,0x35,0x6c, 0x2,0x35,0x70, + 0x3,0x36,0x44, 0x1,0x5b,0x26, 0x2,0x35,0x6b, 0x1,0x5b,0x28, + 0x3,0x36,0x45, 0x1,0x5b,0x27, 0x3,0x3c,0x26, 0x2,0x3c,0x4a, + 0x3,0x3b,0x7d, 0x2,0x3c,0x45, 0x3,0x3c,0x25, 0x1,0x5f,0x5b, + 0x1,0x5f,0x5f, 0x1,0x5f,0x5c, 0x2,0x3c,0x48, 0x2,0x3c,0x4b, + 0x3,0x3c,0x23, 0x1,0x5f,0x5d, 0x4,0x38,0x24, 0x1,0x5f,0x5e, + 0x1,0x5f,0x63, 0x2,0x43,0x4d, 0x2,0x3c,0x49, 0x1,0x5f,0x61, + 0x2,0x3c,0x46, 0x2,0x3c,0x44, 0x3,0x3b,0x7c, 0x1,0x5f,0x62, + 0x3,0x3b,0x7e, 0x2,0x3c,0x47, 0x3,0x3c,0x24, 0x1,0x64,0x41, + 0x4,0x3d,0x69, 0x2,0x43,0x45, 0x1,0x64,0x3e, 0x1,0x64,0x3f, + 0x1,0x64,0x3d, 0x2,0x43,0x4a, 0x2,0x43,0x49, 0x2,0x43,0x46, + 0x1,0x64,0x43, 0x3,0x41,0x5b, 0x3,0x41,0x56, 0x2,0x43,0x48, + 0x1,0x5f,0x60, 0x3,0x41,0x59, 0x3,0x41,0x51, 0x2,0x43,0x4c, + 0x2,0x43,0x47, 0x1,0x64,0x40, 0x1,0x64,0x3c, 0x1,0x64,0x42, + 0x2,0x43,0x4b, 0x3,0x47,0x34, 0x4,0x43,0x6b, 0x3,0x47,0x35, + 0x1,0x69,0x25, 0x4,0x43,0x6f, 0x2,0x4a,0x5f, 0x2,0x4a,0x5e, + 0x2,0x4a,0x5d, 0x1,0x69,0x23, 0x4,0x43,0x6d, 0x3,0x47,0x39, + 0x3,0x47,0x33, 0x3,0x47,0x37, 0x1,0x69,0x24, 0x2,0x50,0x6c, + 0x2,0x50,0x6f, 0x1,0x6d,0x32, 0x3,0x4c,0x44, 0x3,0x4c,0x46, + 0x1,0x6d,0x31, 0x2,0x50,0x70, 0x2,0x50,0x6b, 0x1,0x6d,0x34, + 0x2,0x50,0x6d, 0x3,0x4c,0x41, 0x1,0x6d,0x33, 0x2,0x50,0x6a, + 0x3,0x4c,0x40, 0x2,0x50,0x6e, 0x1,0x70,0x72, 0x1,0x70,0x6f, + 0x2,0x57,0x46, 0x2,0x57,0x45, 0x3,0x4c,0x43, 0x2,0x57,0x44, + 0x2,0x57,0x3f, 0x3,0x50,0x7d, 0x2,0x57,0x40, 0x3,0x51,0x23, + 0x4,0x50,0x50, 0x3,0x50,0x7a, 0x1,0x70,0x70, 0x3,0x50,0x7e, + 0x1,0x70,0x6d, 0x1,0x70,0x71, 0x2,0x57,0x3e, 0x1,0x70,0x6e, + 0x2,0x57,0x41, 0x2,0x57,0x42, 0x2,0x57,0x47, 0x3,0x51,0x22, + 0x3,0x54,0x71, 0x2,0x57,0x43, 0x3,0x54,0x6f, 0x3,0x54,0x70, + 0x2,0x5c,0x7d, 0x4,0x56,0x41, 0x3,0x54,0x6c, 0x3,0x54,0x6d, + 0x1,0x73,0x70, 0x3,0x54,0x72, 0x2,0x61,0x68, 0x1,0x73,0x6f, + 0x2,0x61,0x66, 0x2,0x61,0x67, 0x1,0x76,0x4c, 0x1,0x78,0x3b, + 0x2,0x65,0x56, 0x3,0x5a,0x43, 0x1,0x78,0x3a, 0x3,0x5a,0x42, + 0x3,0x65,0x26, 0x2,0x68,0x7d, 0x2,0x68,0x7e, 0x3,0x5c,0x42, + 0x1,0x79,0x71, 0x3,0x5c,0x43, 0x2,0x68,0x7c, 0x1,0x7a,0x6f, + 0x4,0x6a,0x4c, 0x2,0x6f,0x2e, 0x1,0x7c,0x3a, 0x2,0x70,0x38, + 0x2,0x70,0x39, 0x3,0x61,0x3f, 0x1,0x45,0x4b, 0x4,0x21,0x7c, + 0x1,0x48,0x32, 0x1,0x48,0x33, 0x1,0x4a,0x55, 0x3,0x26,0x41, + 0x2,0x27,0x32, 0x1,0x51,0x57, 0x1,0x55,0x73, 0x1,0x5b,0x2a, + 0xf,0x32,0x73, 0x1,0x59,0x37, 0x1,0x5f,0x64, 0x1,0x5f,0x65, + 0x1,0x5e,0x32, 0x2,0x3c,0x4c, 0x3,0x65,0x27, 0x1,0x64,0x44, + 0x2,0x4a,0x61, 0x2,0x4a,0x60, 0x3,0x51,0x24, 0x7,0x53,0x47, + 0x1,0x45,0x4c, 0x1,0x48,0x34, 0x2,0x27,0x33, 0x1,0x4e,0x25, + 0x3,0x29,0x45, 0x1,0x4e,0x24, 0x3,0x2d,0x27, 0x2,0x2a,0x7a, + 0x2,0x2a,0x7b, 0x3,0x66,0x32, 0x2,0x2f,0x59, 0x2,0x2f,0x5a, + 0x1,0x55,0x74, 0x1,0x55,0x75, 0x3,0x36,0x48, 0x1,0x55,0x76, + 0x2,0x35,0x71, 0x3,0x36,0x47, 0x3,0x36,0x46, 0x1,0x5b,0x2c, + 0x4,0x38,0x29, 0x1,0x5f,0x67, 0x3,0x3c,0x29, 0x1,0x5f,0x66, + 0x2,0x43,0x4e, 0x2,0x46,0x41, 0x2,0x4a,0x62, 0x2,0x57,0x48, + 0x3,0x51,0x26, 0x3,0x66,0x33, 0x1,0x76,0x4d, 0x1,0x79,0x72, + 0x1,0x45,0x4d, 0x1,0x46,0x5c, 0x1,0x46,0x5d, 0x1,0x46,0x5b, + 0x1,0x46,0x5e, 0x1,0x46,0x5a, 0x3,0x22,0x52, 0x1,0x48,0x37, + 0x3,0x23,0x77, 0x2,0x22,0x57, 0x1,0x48,0x36, 0x1,0x48,0x38, + 0x3,0x23,0x78, 0x3,0x23,0x75, 0x2,0x22,0x52, 0x2,0x22,0x51, + 0x2,0x22,0x54, 0x2,0x22,0x53, 0x2,0x22,0x56, 0x1,0x48,0x35, + 0x2,0x22,0x50, 0x2,0x22,0x55, 0xf,0x22,0x58, 0xf,0x22,0x57, + 0x3,0x26,0x48, 0x2,0x24,0x3e, 0x1,0x4a,0x5f, 0x2,0x24,0x3f, + 0x2,0x24,0x43, 0x1,0x4a,0x5e, 0x3,0x26,0x49, 0x2,0x24,0x47, + 0x2,0x24,0x42, 0x2,0x24,0x45, 0x1,0x4a,0x57, 0x1,0x4a,0x58, + 0x1,0x4a,0x59, 0x1,0x4a,0x5a, 0x3,0x26,0x45, 0x1,0x4a,0x61, + 0x3,0x26,0x44, 0x2,0x24,0x41, 0x1,0x4a,0x5c, 0x1,0x4a,0x62, + 0x3,0x26,0x47, 0x2,0x24,0x40, 0x2,0x24,0x46, 0x3,0x26,0x42, + 0x1,0x4a,0x5b, 0x2,0x24,0x44, 0x1,0x4a,0x5d, 0x1,0x4a,0x56, + 0x1,0x4a,0x60, 0x3,0x26,0x4a, 0xf,0x24,0x22, 0x4,0x24,0x46, + 0xf,0x24,0x53, 0x1,0x4e,0x3a, 0x3,0x29,0x47, 0x2,0x27,0x35, + 0x1,0x4e,0x26, 0x4,0x26,0x69, 0x1,0x4e,0x30, 0x1,0x4e,0x31, + 0x1,0x4e,0x29, 0x1,0x4e,0x3b, 0x1,0x4e,0x2b, 0x2,0x27,0x3d, + 0x1,0x4e,0x36, 0x2,0x27,0x38, 0x1,0x4e,0x2c, 0x2,0x27,0x47, + 0x2,0x27,0x48, 0x2,0x27,0x40, 0x2,0x27,0x39, 0x1,0x4e,0x39, + 0x2,0x27,0x45, 0x1,0x4e,0x34, 0x1,0x4e,0x32, 0x3,0x29,0x52, + 0x2,0x27,0x46, 0x3,0x29,0x49, 0x2,0x27,0x44, 0x2,0x27,0x3c, + 0x2,0x27,0x34, 0x2,0x27,0x3b, 0x1,0x4e,0x2d, 0x4,0x26,0x65, + 0x1,0x4e,0x33, 0x3,0x29,0x4a, 0x1,0x4e,0x27, 0x2,0x27,0x3f, + 0x2,0x27,0x3e, 0x2,0x27,0x36, 0x3,0x29,0x4f, 0x1,0x4e,0x35, + 0x2,0x27,0x42, 0x2,0x27,0x37, 0x1,0x4e,0x38, 0x2,0x27,0x49, + 0x1,0x4e,0x28, 0x3,0x29,0x48, 0x1,0x4e,0x2f, 0x2,0x27,0x3a, + 0x2,0x27,0x43, 0x1,0x4e,0x37, 0x4,0x26,0x67, 0x1,0x4e,0x2a, + 0x1,0x4e,0x2e, 0x4,0x26,0x6a, 0x2,0x27,0x41, 0xf,0x27,0x4e, + 0x3,0x29,0x4e, 0x3,0x29,0x4c, 0x3,0x65,0x28, 0xf,0x27,0x50, + 0x3,0x65,0x29, 0x2,0x2b,0x3d, 0x1,0x51,0x5f, 0x1,0x51,0x6c, + 0x3,0x2d,0x36, 0x2,0x2b,0x38, 0x2,0x2b,0x2e, 0x1,0x51,0x65, + 0x2,0x2b,0x2c, 0x1,0x51,0x5e, 0x2,0x2b,0x27, 0x1,0x51,0x68, + 0x2,0x2b,0x34, 0x2,0x2b,0x21, 0x2,0x2b,0x23, 0x3,0x2d,0x2e, + 0x4,0x2d,0x59, 0x4,0x29,0x6e, 0x3,0x2d,0x30, 0x2,0x2b,0x26, + 0x2,0x2a,0x7c, 0x2,0x2b,0x33, 0x2,0x2b,0x43, 0x1,0x51,0x63, + 0x2,0x2b,0x28, 0x2,0x2b,0x3a, 0x3,0x2d,0x2d, 0x2,0x2a,0x7e, + 0x2,0x2b,0x41, 0x2,0x2b,0x42, 0x2,0x2b,0x45, 0x2,0x2b,0x3c, + 0x2,0x2b,0x2d, 0x2,0x2b,0x35, 0x1,0x51,0x69, 0x1,0x51,0x5c, + 0x1,0x51,0x64, 0x1,0x51,0x70, 0x1,0x51,0x59, 0x1,0x51,0x5b, + 0x3,0x2d,0x31, 0x3,0x2d,0x2b, 0x3,0x2d,0x3a, 0x2,0x2b,0x25, + 0x1,0x51,0x6d, 0x1,0x51,0x66, 0x2,0x2b,0x3f, 0x2,0x2b,0x22, + 0x1,0x51,0x6f, 0x1,0x51,0x6a, 0x2,0x2b,0x2b, 0x4,0x29,0x6d, + 0x4,0x2d,0x4e, 0x1,0x51,0x6e, 0x2,0x2b,0x32, 0x2,0x2b,0x2a, + 0x1,0x51,0x67, 0x2,0x2b,0x3e, 0x2,0x2b,0x36, 0x3,0x2d,0x2a, + 0x1,0x51,0x61, 0x2,0x2b,0x44, 0x2,0x2b,0x29, 0x1,0x51,0x5d, + 0x2,0x2b,0x3b, 0x2,0x2b,0x31, 0x1,0x51,0x62, 0x2,0x2b,0x37, + 0x1,0x51,0x5a, 0x2,0x2a,0x7d, 0x1,0x51,0x6b, 0x1,0x56,0x27, + 0x1,0x51,0x60, 0x2,0x2b,0x30, 0x2,0x2b,0x2f, 0x2,0x2b,0x24, + 0x3,0x29,0x51, 0x2,0x2b,0x40, 0x3,0x2d,0x34, 0x2,0x2b,0x39, + 0x3,0x2d,0x32, 0x1,0x51,0x58, 0x3,0x2d,0x39, 0x3,0x2d,0x37, + 0x6,0x31,0x72, 0x3,0x2d,0x38, 0x3,0x65,0x2b, 0x3,0x65,0x2a, + 0xf,0x2b,0x48, 0x2,0x2f,0x6e, 0x1,0x56,0x2e, 0x2,0x2f,0x6f, + 0x3,0x31,0x5d, 0x2,0x2f,0x63, 0x1,0x56,0x23, 0x1,0x56,0x2f, + 0x3,0x31,0x57, 0x2,0x2f,0x5c, 0x3,0x31,0x53, 0x2,0x2f,0x65, + 0x2,0x2f,0x6d, 0x3,0x31,0x5b, 0x2,0x2f,0x5b, 0x2,0x2f,0x76, + 0x1,0x55,0x77, 0x3,0x31,0x5e, 0x3,0x31,0x64, 0x3,0x31,0x50, + 0x2,0x2f,0x75, 0x2,0x2f,0x70, 0x3,0x31,0x5f, 0x2,0x2f,0x71, + 0x1,0x56,0x21, 0x1,0x56,0x2c, 0x2,0x2f,0x67, 0x3,0x31,0x56, + 0x2,0x2f,0x68, 0x2,0x2f,0x72, 0x2,0x2f,0x69, 0x3,0x31,0x63, + 0x2,0x2f,0x64, 0x2,0x2f,0x5e, 0x2,0x2f,0x5f, 0x2,0x2f,0x6c, + 0x2,0x2f,0x66, 0x3,0x31,0x54, 0x3,0x31,0x4f, 0x1,0x55,0x78, + 0x1,0x55,0x7c, 0x2,0x2f,0x74, 0x2,0x2f,0x60, 0x1,0x56,0x2a, + 0x1,0x56,0x26, 0x3,0x31,0x5a, 0x4,0x2d,0x55, 0x1,0x56,0x29, + 0x1,0x56,0x30, 0x1,0x55,0x7d, 0x1,0x56,0x2b, 0x2,0x2f,0x6b, + 0x1,0x56,0x2d, 0x1,0x55,0x7a, 0x3,0x31,0x59, 0x1,0x55,0x79, + 0x2,0x2f,0x5d, 0x4,0x2d,0x4f, 0x2,0x2f,0x61, 0x1,0x56,0x24, + 0x2,0x2f,0x73, 0x2,0x2f,0x6a, 0x2,0x2f,0x62, 0x1,0x56,0x28, + 0x1,0x56,0x25, 0x3,0x2d,0x2f, 0x1,0x55,0x7b, 0x1,0x55,0x7e, + 0x3,0x31,0x62, 0x3,0x31,0x58, 0xf,0x30,0x24, 0x3,0x31,0x61, + 0x3,0x31,0x60, 0x3,0x65,0x2d, 0x3,0x65,0x2c, 0x2,0x36,0x28, + 0x3,0x36,0x55, 0x2,0x35,0x76, 0x2,0x35,0x77, 0x2,0x35,0x7b, + 0x3,0x36,0x60, 0x2,0x36,0x2c, 0x2,0x36,0x29, 0x3,0x36,0x4e, + 0x2,0x36,0x22, 0x2,0x36,0x21, 0x1,0x5b,0x33, 0x2,0x36,0x25, + 0x2,0x36,0x34, 0x2,0x35,0x72, 0x3,0x36,0x5b, 0x2,0x36,0x35, + 0x2,0x36,0x27, 0x2,0x36,0x39, 0x2,0x36,0x2d, 0x1,0x5b,0x32, + 0x2,0x36,0x2b, 0x1,0x5b,0x2d, 0x1,0x5b,0x42, 0x1,0x5b,0x38, + 0x3,0x36,0x57, 0x1,0x5b,0x3c, 0x1,0x5b,0x3b, 0x2,0x35,0x73, + 0x4,0x32,0x3f, 0x2,0x36,0x32, 0x2,0x36,0x38, 0x2,0x36,0x30, + 0x2,0x36,0x37, 0x3,0x36,0x51, 0x2,0x36,0x24, 0x2,0x35,0x74, + 0x2,0x36,0x36, 0x2,0x36,0x26, 0x1,0x5b,0x30, 0x1,0x5b,0x3d, + 0x3,0x36,0x5a, 0x2,0x36,0x2f, 0x1,0x5b,0x36, 0x3,0x36,0x4d, + 0x3,0x36,0x5c, 0x3,0x36,0x50, 0x2,0x36,0x2e, 0x2,0x35,0x75, + 0x1,0x5b,0x3e, 0x3,0x36,0x4b, 0x1,0x5b,0x40, 0x2,0x36,0x31, + 0x1,0x5b,0x41, 0x1,0x5b,0x2f, 0x2,0x35,0x7c, 0x2,0x36,0x33, + 0x3,0x36,0x54, 0x3,0x34,0x78, 0x1,0x5b,0x35, 0x1,0x5b,0x3f, + 0x2,0x35,0x7e, 0x2,0x36,0x2a, 0x2,0x35,0x79, 0x2,0x35,0x7d, + 0x1,0x5b,0x3a, 0x2,0x35,0x78, 0x1,0x5b,0x2e, 0x1,0x5b,0x37, + 0x1,0x5b,0x34, 0x2,0x36,0x23, 0x1,0x56,0x22, 0x2,0x3c,0x63, + 0x1,0x5b,0x31, 0x3,0x36,0x4c, 0x3,0x36,0x52, 0x3,0x36,0x5e, + 0x3,0x36,0x5f, 0xf,0x35,0x57, 0x3,0x36,0x56, 0x3,0x3c,0x45, + 0x1,0x5b,0x39, 0x3,0x3c,0x41, 0x2,0x3c,0x66, 0x2,0x3c,0x7c, + 0x2,0x3c,0x71, 0x1,0x5f,0x7b, 0x3,0x3c,0x38, 0x1,0x5f,0x76, + 0x2,0x3c,0x60, 0x1,0x5f,0x77, 0x2,0x3c,0x70, 0x3,0x3c,0x3e, + 0x2,0x3c,0x69, 0x2,0x3c,0x76, 0x1,0x5f,0x73, 0x2,0x3c,0x4e, + 0x2,0x3c,0x78, 0x1,0x5f,0x69, 0x2,0x3c,0x56, 0x1,0x5f,0x6c, + 0x1,0x5f,0x6b, 0x4,0x38,0x32, 0x1,0x5f,0x7c, 0x3,0x36,0x53, + 0x2,0x3c,0x50, 0x2,0x3c,0x72, 0x2,0x3c,0x73, 0x1,0x5f,0x6e, + 0x1,0x5f,0x6a, 0x2,0x3c,0x5e, 0x3,0x3c,0x3d, 0x1,0x5f,0x75, + 0x2,0x3c,0x59, 0x3,0x3c,0x32, 0x2,0x3c,0x74, 0x1,0x5f,0x71, + 0x2,0x3c,0x6c, 0x2,0x3c,0x79, 0x2,0x3c,0x53, 0x2,0x3c,0x58, + 0x2,0x3c,0x52, 0x3,0x3c,0x2a, 0x1,0x5f,0x70, 0x2,0x3c,0x65, + 0x2,0x43,0x64, 0x2,0x3c,0x54, 0x1,0x5f,0x74, 0x2,0x3c,0x5d, + 0x2,0x3c,0x75, 0x1,0x5f,0x6f, 0x2,0x3c,0x5a, 0x2,0x3c,0x57, + 0x2,0x3c,0x68, 0x1,0x5f,0x72, 0x1,0x5f,0x68, 0x1,0x5f,0x7e, + 0x2,0x3c,0x6b, 0x2,0x3c,0x6a, 0x3,0x3c,0x31, 0x3,0x3c,0x42, + 0x3,0x3c,0x39, 0x3,0x3c,0x3b, 0x3,0x3c,0x34, 0x3,0x3c,0x2f, + 0x2,0x3c,0x4f, 0x1,0x5f,0x6d, 0x2,0x3c,0x77, 0x2,0x3c,0x5f, + 0x2,0x3c,0x61, 0x3,0x3c,0x37, 0x2,0x3c,0x6e, 0x2,0x3c,0x6d, + 0x2,0x3c,0x4d, 0x1,0x5f,0x78, 0x1,0x5f,0x7a, 0x2,0x3c,0x55, + 0x2,0x3c,0x5c, 0x2,0x3c,0x64, 0x1,0x5f,0x79, 0x2,0x3c,0x5b, + 0x2,0x3c,0x67, 0x2,0x3c,0x7a, 0xf,0x3b,0x70, 0x2,0x3c,0x6f, + 0x3,0x3c,0x3c, 0xf,0x3c,0x21, 0x3,0x3c,0x44, 0x3,0x3c,0x33, + 0x2,0x3c,0x7b, 0xf,0x3c,0x29, 0x3,0x65,0x2f, 0x2,0x3c,0x51, + 0xf,0x3b,0x6e, 0x3,0x65,0x2e, 0x3,0x3c,0x40, 0x2,0x43,0x78, + 0x1,0x64,0x4c, 0x3,0x41,0x65, 0x2,0x43,0x76, 0x2,0x43,0x61, + 0x2,0x43,0x66, 0x2,0x43,0x5f, 0x3,0x41,0x77, 0x2,0x43,0x72, + 0x2,0x43,0x51, 0x2,0x43,0x58, 0x4,0x3d,0x71, 0x2,0x43,0x70, + 0x2,0x43,0x7a, 0x2,0x43,0x62, 0x3,0x41,0x68, 0x2,0x43,0x55, + 0x2,0x43,0x68, 0x2,0x43,0x6d, 0x2,0x43,0x59, 0x3,0x41,0x6b, + 0x2,0x43,0x6a, 0x2,0x43,0x56, 0x3,0x41,0x5d, 0x3,0x41,0x75, + 0x2,0x43,0x5d, 0x2,0x43,0x5e, 0x1,0x64,0x4e, 0x2,0x43,0x71, + 0x2,0x43,0x6f, 0x3,0x41,0x73, 0x2,0x43,0x52, 0x2,0x43,0x74, + 0x3,0x41,0x74, 0x2,0x43,0x75, 0x2,0x43,0x77, 0x1,0x64,0x52, + 0x1,0x64,0x4a, 0x3,0x41,0x6f, 0x2,0x35,0x7a, 0x2,0x43,0x5a, + 0x2,0x43,0x6c, 0x2,0x43,0x5b, 0x1,0x64,0x47, 0x1,0x64,0x57, + 0x2,0x43,0x73, 0x1,0x64,0x55, 0x1,0x64,0x51, 0x2,0x43,0x50, + 0x1,0x64,0x49, 0x3,0x41,0x79, 0x2,0x43,0x53, 0x1,0x64,0x56, + 0x3,0x41,0x78, 0x2,0x43,0x63, 0x2,0x43,0x4f, 0x3,0x41,0x76, + 0x1,0x64,0x4f, 0x2,0x43,0x67, 0x2,0x43,0x57, 0x1,0x64,0x50, + 0x2,0x43,0x60, 0x1,0x64,0x46, 0x1,0x5f,0x7d, 0x2,0x43,0x69, + 0x2,0x3c,0x62, 0x2,0x43,0x54, 0x4,0x3d,0x6c, 0x3,0x41,0x6d, + 0x2,0x43,0x6e, 0x1,0x64,0x4b, 0x2,0x43,0x6b, 0x1,0x64,0x48, + 0x2,0x43,0x65, 0x1,0x64,0x53, 0x2,0x43,0x5c, 0x2,0x43,0x79, + 0x3,0x41,0x6a, 0x3,0x41,0x7b, 0xf,0x42,0x49, 0xf,0x42,0x47, + 0x1,0x64,0x4d, 0x2,0x45,0x2c, 0x3,0x41,0x72, 0x1,0x64,0x54, + 0xf,0x42,0x28, 0xf,0x42,0x3c, 0x2,0x4a,0x70, 0x2,0x4a,0x6e, + 0x3,0x47,0x3a, 0x2,0x4b,0x26, 0x2,0x4a,0x6c, 0x3,0x47,0x3d, + 0x2,0x4a,0x7e, 0x1,0x64,0x45, 0x1,0x69,0x28, 0x2,0x4a,0x68, + 0x2,0x4b,0x25, 0x3,0x47,0x51, 0x2,0x4a,0x6d, 0x2,0x4a,0x7b, + 0x1,0x69,0x2d, 0x1,0x69,0x26, 0x3,0x47,0x4e, 0x2,0x4b,0x23, + 0x3,0x47,0x46, 0x2,0x4a,0x66, 0x2,0x4b,0x22, 0x3,0x47,0x47, + 0x1,0x69,0x38, 0x2,0x4a,0x77, 0x2,0x4b,0x29, 0x1,0x69,0x36, + 0x2,0x4a,0x6f, 0x1,0x69,0x27, 0x2,0x4a,0x71, 0x2,0x4b,0x21, + 0x1,0x69,0x30, 0x2,0x4a,0x6a, 0x1,0x69,0x34, 0x1,0x69,0x2a, + 0x2,0x4a,0x73, 0x2,0x4a,0x69, 0x2,0x4a,0x63, 0x3,0x47,0x3e, + 0x2,0x4a,0x7d, 0x1,0x69,0x31, 0x2,0x4b,0x28, 0x2,0x4a,0x64, + 0x1,0x69,0x2e, 0x4,0x43,0x77, 0x2,0x4a,0x79, 0x4,0x43,0x79, + 0x1,0x69,0x2f, 0x2,0x4a,0x6b, 0x2,0x4a,0x76, 0x2,0x4a,0x72, + 0x2,0x4a,0x74, 0x3,0x47,0x43, 0x1,0x69,0x29, 0x2,0x4b,0x27, + 0x1,0x69,0x37, 0x2,0x4a,0x75, 0x3,0x47,0x3b, 0x2,0x4b,0x2a, + 0x4,0x44,0x27, 0x3,0x47,0x3c, 0x2,0x4a,0x65, 0x2,0x4a,0x7a, + 0x1,0x69,0x2c, 0x1,0x69,0x35, 0x1,0x69,0x33, 0x2,0x4a,0x67, + 0x2,0x4a,0x7c, 0x1,0x69,0x32, 0x3,0x47,0x45, 0x3,0x47,0x48, + 0x1,0x69,0x2b, 0x2,0x4a,0x78, 0x3,0x47,0x4d, 0x3,0x47,0x44, + 0x4,0x44,0x28, 0x3,0x4c,0x54, 0x2,0x4b,0x24, 0x3,0x47,0x4c, + 0x2,0x50,0x7c, 0x3,0x47,0x42, 0x2,0x50,0x78, 0x2,0x50,0x74, + 0x2,0x51,0x2a, 0x2,0x51,0x27, 0x1,0x6d,0x37, 0x3,0x4c,0x64, + 0x3,0x4c,0x60, 0x2,0x51,0x2e, 0x2,0x50,0x7b, 0x1,0x6d,0x42, + 0x2,0x51,0x24, 0x3,0x4c,0x4f, 0x3,0x4c,0x51, 0x2,0x50,0x77, + 0x2,0x51,0x23, 0x1,0x6d,0x3f, 0x2,0x51,0x37, 0x4,0x4a,0x3d, + 0x2,0x51,0x34, 0x2,0x51,0x26, 0x2,0x50,0x75, 0x3,0x4c,0x5f, + 0x3,0x4c,0x57, 0x2,0x51,0x2b, 0x2,0x51,0x2d, 0x1,0x6d,0x3b, + 0x2,0x51,0x21, 0x2,0x50,0x7a, 0x2,0x50,0x71, 0x1,0x6d,0x38, + 0x1,0x6d,0x40, 0x4,0x4a,0x48, 0x2,0x51,0x30, 0x1,0x6d,0x41, + 0x2,0x50,0x72, 0x2,0x51,0x36, 0x2,0x51,0x29, 0x2,0x51,0x2f, + 0x1,0x6d,0x3e, 0x3,0x4c,0x4d, 0x3,0x4c,0x50, 0x2,0x51,0x2c, + 0x3,0x4c,0x47, 0x2,0x51,0x33, 0x3,0x4c,0x5b, 0x1,0x6d,0x43, + 0x3,0x4c,0x56, 0x1,0x6d,0x3d, 0x2,0x51,0x25, 0x2,0x50,0x76, + 0x2,0x51,0x38, 0x2,0x50,0x73, 0x2,0x51,0x31, 0x1,0x6d,0x3a, + 0x3,0x4c,0x4a, 0x2,0x50,0x7d, 0x3,0x4c,0x49, 0x2,0x50,0x7e, + 0x1,0x6d,0x39, 0x1,0x6d,0x36, 0x2,0x50,0x79, 0x1,0x6d,0x3c, + 0x3,0x4c,0x52, 0x1,0x6d,0x35, 0x3,0x4c,0x62, 0x2,0x51,0x32, + 0x2,0x51,0x35, 0x2,0x51,0x22, 0x2,0x57,0x55, 0x3,0x4c,0x5e, + 0x3,0x4c,0x59, 0xf,0x4f,0x42, 0x3,0x4c,0x61, 0x3,0x65,0x30, + 0x2,0x57,0x4d, 0x3,0x51,0x2c, 0x2,0x57,0x49, 0x1,0x71,0x21, + 0x3,0x51,0x3c, 0x3,0x51,0x38, 0x1,0x70,0x74, 0x1,0x70,0x79, + 0x1,0x70,0x75, 0x2,0x57,0x57, 0x2,0x57,0x62, 0x1,0x70,0x73, + 0x2,0x57,0x4f, 0x2,0x57,0x58, 0x2,0x51,0x28, 0x2,0x57,0x59, + 0x3,0x51,0x28, 0x3,0x51,0x2b, 0x1,0x70,0x7a, 0x3,0x51,0x40, + 0x2,0x57,0x68, 0x1,0x70,0x7e, 0x1,0x71,0x23, 0x2,0x57,0x4b, + 0x3,0x51,0x3b, 0x1,0x70,0x7d, 0x3,0x51,0x31, 0x2,0x57,0x66, + 0x2,0x57,0x67, 0x2,0x57,0x5d, 0x2,0x57,0x5c, 0x2,0x57,0x54, + 0x3,0x51,0x29, 0x3,0x51,0x3e, 0x2,0x57,0x5e, 0x2,0x57,0x65, + 0x2,0x57,0x64, 0x3,0x51,0x2f, 0x1,0x70,0x78, 0x1,0x70,0x76, + 0x2,0x57,0x56, 0x2,0x57,0x53, 0x3,0x51,0x44, 0x2,0x57,0x50, + 0x2,0x57,0x63, 0x1,0x71,0x22, 0x2,0x57,0x61, 0x1,0x70,0x7c, + 0x1,0x70,0x7b, 0x3,0x51,0x27, 0x2,0x57,0x5b, 0x4,0x4a,0x4b, + 0x2,0x57,0x4a, 0x2,0x57,0x4c, 0x2,0x57,0x4e, 0x2,0x57,0x60, + 0x2,0x57,0x5a, 0x1,0x70,0x77, 0x3,0x51,0x2e, 0x2,0x57,0x51, + 0x3,0x51,0x32, 0x2,0x57,0x5f, 0x3,0x51,0x41, 0x3,0x51,0x3a, + 0xf,0x54,0x7b, 0x2,0x57,0x52, 0x3,0x65,0x31, 0xf,0x55,0x29, + 0x3,0x65,0x32, 0x3,0x54,0x75, 0x1,0x73,0x78, 0x2,0x5d,0x31, + 0x1,0x73,0x71, 0x2,0x5d,0x22, 0x3,0x54,0x7b, 0x2,0x5d,0x2d, + 0x1,0x73,0x73, 0x2,0x5d,0x34, 0x3,0x55,0x21, 0x2,0x5d,0x29, + 0x3,0x54,0x7c, 0x2,0x5d,0x24, 0x3,0x54,0x76, 0x4,0x56,0x45, + 0x2,0x5d,0x35, 0x2,0x5c,0x7e, 0x2,0x5d,0x2b, 0x3,0x55,0x27, + 0x1,0x73,0x7a, 0x2,0x5d,0x30, 0x2,0x5d,0x36, 0x2,0x5d,0x2a, + 0x1,0x73,0x72, 0x2,0x5d,0x2c, 0x2,0x5d,0x21, 0x1,0x73,0x79, + 0x3,0x55,0x23, 0x3,0x54,0x7a, 0x2,0x5d,0x33, 0x2,0x5d,0x26, + 0x1,0x73,0x75, 0x3,0x55,0x24, 0x2,0x5d,0x28, 0x2,0x5d,0x25, + 0x1,0x73,0x7b, 0x2,0x5d,0x27, 0x1,0x73,0x74, 0x1,0x73,0x77, + 0x2,0x5d,0x2f, 0x2,0x5d,0x23, 0x2,0x5d,0x32, 0x3,0x54,0x78, + 0x2,0x5d,0x2e, 0x3,0x55,0x29, 0x3,0x57,0x74, 0x1,0x76,0x4f, + 0x2,0x61,0x73, 0x1,0x76,0x54, 0x1,0x76,0x55, 0x3,0x57,0x77, + 0x3,0x58,0x21, 0x3,0x57,0x76, 0x1,0x76,0x4e, 0x2,0x61,0x72, + 0x3,0x57,0x78, 0x2,0x61,0x6f, 0x2,0x61,0x70, 0x1,0x76,0x52, + 0x2,0x61,0x6a, 0x2,0x61,0x6e, 0x1,0x76,0x51, 0x3,0x57,0x7e, + 0x2,0x61,0x6b, 0x3,0x57,0x79, 0x3,0x58,0x23, 0x3,0x57,0x7d, + 0x3,0x57,0x7a, 0x1,0x76,0x53, 0x1,0x76,0x50, 0x3,0x58,0x22, + 0x2,0x61,0x69, 0x2,0x61,0x6d, 0x2,0x61,0x71, 0x3,0x57,0x7b, + 0x3,0x65,0x33, 0x2,0x65,0x5c, 0x2,0x65,0x59, 0x2,0x65,0x62, + 0x3,0x5a,0x44, 0x2,0x65,0x61, 0x2,0x65,0x5f, 0x2,0x65,0x5a, + 0x3,0x5a,0x4f, 0x1,0x78,0x3f, 0x3,0x5a,0x45, 0x3,0x5a,0x4e, + 0x4,0x5f,0x71, 0x3,0x5a,0x47, 0x3,0x5a,0x4d, 0x2,0x65,0x5b, + 0x1,0x78,0x3e, 0x1,0x73,0x76, 0x2,0x65,0x5e, 0x1,0x78,0x3d, + 0x2,0x65,0x63, 0x2,0x65,0x5d, 0x2,0x65,0x58, 0x2,0x61,0x6c, + 0x3,0x5a,0x48, 0x3,0x5a,0x46, 0x1,0x78,0x3c, 0x3,0x65,0x34, + 0x2,0x65,0x57, 0x2,0x69,0x24, 0x3,0x5c,0x49, 0x2,0x69,0x23, + 0x2,0x65,0x60, 0x1,0x79,0x73, 0x3,0x57,0x75, 0x2,0x69,0x27, + 0x2,0x69,0x28, 0x2,0x69,0x22, 0x2,0x69,0x26, 0x4,0x63,0x50, + 0x2,0x69,0x21, 0x3,0x5c,0x47, 0x3,0x65,0x35, 0x4,0x63,0x4e, + 0x2,0x6b,0x5f, 0x2,0x69,0x25, 0x1,0x7a,0x72, 0x1,0x7a,0x70, + 0x2,0x6b,0x5d, 0x3,0x5e,0x35, 0x3,0x5e,0x34, 0x3,0x5e,0x33, + 0x2,0x6b,0x60, 0x3,0x5e,0x37, 0x2,0x6b,0x5c, 0x2,0x6b,0x5e, + 0x1,0x7a,0x71, 0x3,0x5f,0x4f, 0x3,0x5f,0x4e, 0x2,0x6d,0x53, + 0x2,0x6d,0x54, 0x1,0x7b,0x62, 0x2,0x6d,0x52, 0xf,0x69,0x4c, + 0x3,0x65,0x36, 0x3,0x65,0x37, 0x2,0x6f,0x31, 0x1,0x7c,0x3b, + 0x2,0x6f,0x2f, 0x2,0x6f,0x30, 0x2,0x70,0x3a, 0x3,0x60,0x74, + 0xf,0x6b,0x51, 0x1,0x7d,0x23, 0x2,0x71,0x23, 0x2,0x71,0x21, + 0x2,0x71,0x22, 0x2,0x71,0x24, 0x3,0x61,0x40, 0x3,0x61,0x65, + 0x3,0x61,0x41, 0x2,0x72,0x2b, 0x1,0x45,0x4e, 0x1,0x48,0x39, + 0x3,0x23,0x79, 0x1,0x4e,0x3c, 0x4,0x26,0x71, 0x2,0x27,0x4a, + 0x3,0x29,0x53, 0x3,0x29,0x54, 0x2,0x2b,0x46, 0x4,0x29,0x72, + 0x3,0x2d,0x3c, 0x3,0x31,0x66, 0x2,0x2f,0x77, 0x2,0x2f,0x79, + 0x3,0x31,0x65, 0x2,0x2f,0x78, 0x3,0x31,0x67, 0x2,0x2f,0x7a, + 0x1,0x5b,0x43, 0x2,0x36,0x3b, 0x2,0x2f,0x7b, 0x3,0x36,0x62, + 0x2,0x36,0x3a, 0x2,0x36,0x3c, 0x2,0x36,0x3d, 0x2,0x3c,0x7d, + 0x1,0x60,0x22, 0x2,0x3c,0x7e, 0x2,0x3d,0x22, 0x1,0x60,0x23, + 0x1,0x60,0x21, 0x2,0x3d,0x21, 0x3,0x41,0x7d, 0x2,0x44,0x22, + 0x2,0x43,0x7e, 0x2,0x43,0x7d, 0x3,0x41,0x7c, 0x2,0x43,0x7c, + 0x2,0x43,0x7b, 0x1,0x64,0x58, 0x2,0x44,0x21, 0x1,0x69,0x39, + 0x2,0x4b,0x2b, 0x2,0x4b,0x2d, 0x1,0x69,0x3a, 0x2,0x4b,0x2c, + 0x1,0x6d,0x45, 0x3,0x4c,0x66, 0x1,0x6d,0x44, 0x2,0x51,0x39, + 0x3,0x4c,0x65, 0x3,0x4c,0x67, 0x2,0x57,0x6a, 0x2,0x57,0x69, + 0x2,0x57,0x6b, 0x3,0x51,0x46, 0x3,0x51,0x45, 0x1,0x71,0x24, + 0xf,0x55,0x39, 0x2,0x5d,0x37, 0x1,0x73,0x7c, 0x3,0x55,0x2b, + 0x2,0x61,0x74, 0x1,0x76,0x56, 0x2,0x65,0x64, 0x1,0x7b,0x63, + 0x1,0x45,0x4f, 0x1,0x46,0x5f, 0x1,0x48,0x3a, 0x1,0x4a,0x63, + 0x1,0x4e,0x3d, 0x1,0x4e,0x3e, 0x3,0x29,0x55, 0x3,0x29,0x56, + 0x1,0x51,0x71, 0x3,0x2d,0x3d, 0x3,0x31,0x68, 0x2,0x2f,0x7c, + 0x3,0x3c,0x49, 0x3,0x3c,0x47, 0x4,0x44,0x2d, 0x3,0x41,0x7e, + 0x1,0x64,0x59, 0x3,0x42,0x21, 0x3,0x47,0x53, 0x4,0x4a,0x4e, + 0x2,0x52,0x59, 0x1,0x71,0x25, 0x1,0x76,0x57, 0x1,0x45,0x50, + 0x3,0x22,0x53, 0x1,0x48,0x3b, 0x4,0x26,0x76, 0x2,0x27,0x4c, + 0x1,0x4e,0x3f, 0x2,0x27,0x4b, 0x3,0x29,0x58, 0x2,0x2b,0x47, + 0x1,0x51,0x72, 0x2,0x2b,0x48, 0x5,0x29,0x69, 0x1,0x51,0x73, + 0x2,0x2f,0x7e, 0x1,0x56,0x32, 0x1,0x56,0x31, 0x3,0x31,0x6a, + 0x2,0x36,0x42, 0x2,0x36,0x40, 0x2,0x36,0x41, 0x2,0x36,0x3f, + 0x3,0x36,0x64, 0x2,0x36,0x3e, 0x2,0x3d,0x23, 0x2,0x3d,0x26, + 0x1,0x60,0x25, 0x2,0x3d,0x24, 0x1,0x60,0x24, 0x2,0x3d,0x25, + 0x2,0x44,0x23, 0x3,0x42,0x22, 0x4,0x44,0x31, 0x2,0x4b,0x2e, + 0x2,0x4b,0x2f, 0x2,0x4b,0x30, 0x3,0x47,0x54, 0x2,0x51,0x3c, + 0x2,0x51,0x3b, 0x1,0x6d,0x46, 0x2,0x51,0x3a, 0x2,0x51,0x3d, + 0x2,0x57,0x6c, 0x4,0x50,0x6d, 0x5,0x5b,0x72, 0x2,0x57,0x6d, + 0x2,0x57,0x6e, 0x4,0x56,0x52, 0x2,0x5d,0x38, 0x1,0x73,0x7d, + 0x1,0x76,0x58, 0x2,0x65,0x65, 0x1,0x7a,0x73, 0x2,0x21,0x3f, + 0x3,0x29,0x59, 0x1,0x51,0x74, 0x2,0x2b,0x49, 0x1,0x56,0x33, + 0x4,0x32,0x4e, 0x4,0x32,0x50, 0x1,0x5b,0x44, 0x3,0x36,0x65, + 0x1,0x60,0x26, 0x2,0x3d,0x27, 0x3,0x3c,0x4b, 0x1,0x64,0x5b, + 0x1,0x64,0x5a, 0x3,0x42,0x26, 0x2,0x4b,0x31, 0x2,0x4b,0x32, + 0x1,0x6d,0x47, 0x1,0x6d,0x48, 0x2,0x57,0x70, 0x2,0x57,0x6f, + 0x2,0x61,0x75, 0x2,0x6f,0x32, 0x1,0x45,0x51, 0x2,0x21,0x40, + 0x1,0x46,0x60, 0x3,0x23,0x7a, 0x1,0x4a,0x64, 0x2,0x24,0x48, + 0x3,0x29,0x5a, 0x1,0x51,0x75, 0x1,0x64,0x5c, 0x1,0x45,0x52, + 0x2,0x2b,0x4a, 0x1,0x51,0x76, 0x2,0x2b,0x4b, 0x1,0x73,0x7e, + 0x1,0x45,0x53, 0x3,0x65,0x38, 0x3,0x65,0x39, 0x2,0x27,0x4d, + 0x2,0x2b,0x4c, 0x3,0x2d,0x42, 0x2,0x30,0x25, 0x2,0x30,0x24, + 0x2,0x30,0x22, 0x3,0x31,0x6e, 0x2,0x30,0x21, 0x2,0x30,0x26, + 0x2,0x30,0x23, 0x3,0x31,0x6c, 0x3,0x31,0x6d, 0x1,0x5b,0x45, + 0x1,0x5b,0x46, 0x3,0x36,0x66, 0x1,0x60,0x27, 0x2,0x3d,0x28, + 0x4,0x38,0x4e, 0x2,0x3d,0x29, 0x2,0x3d,0x2a, 0x3,0x3c,0x4d, + 0xf,0x3c,0x3c, 0x3,0x65,0x3a, 0x2,0x44,0x27, 0x2,0x44,0x28, + 0x2,0x44,0x26, 0x3,0x42,0x28, 0x2,0x44,0x24, 0x2,0x44,0x25, + 0x1,0x64,0x5d, 0x2,0x4b,0x33, 0x2,0x51,0x40, 0x2,0x51,0x3f, + 0x2,0x51,0x3e, 0x2,0x51,0x41, 0x2,0x57,0x72, 0x2,0x57,0x71, + 0x1,0x71,0x26, 0x2,0x57,0x73, 0x1,0x74,0x21, 0x2,0x5d,0x39, + 0x3,0x55,0x2d, 0x2,0x61,0x76, 0x2,0x65,0x66, 0x2,0x6d,0x55, + 0x1,0x45,0x54, 0x1,0x46,0x62, 0x1,0x46,0x61, 0x4,0x23,0x21, + 0x1,0x4e,0x40, 0x2,0x21,0x41, 0x2,0x21,0x5f, 0x1,0x48,0x3c, + 0x2,0x22,0x58, 0x2,0x24,0x49, 0x2,0x24,0x4a, 0x1,0x4e,0x41, + 0x3,0x29,0x5d, 0x2,0x27,0x4e, 0x3,0x65,0x3b, 0x1,0x51,0x77, + 0x2,0x2b,0x4d, 0x2,0x2b,0x4e, 0x1,0x56,0x34, 0x1,0x56,0x38, + 0x2,0x30,0x27, 0x1,0x56,0x37, 0x1,0x56,0x35, 0x1,0x56,0x36, + 0x2,0x36,0x43, 0x1,0x5b,0x47, 0x1,0x60,0x2a, 0x3,0x3c,0x4e, + 0x1,0x60,0x28, 0x1,0x60,0x29, 0x2,0x3d,0x2b, 0x3,0x42,0x29, + 0x3,0x42,0x2a, 0x1,0x69,0x3b, 0x1,0x45,0x55, 0x2,0x21,0x60, + 0x3,0x22,0x57, 0x1,0x46,0x63, 0x3,0x22,0x54, 0x2,0x21,0x63, + 0x3,0x24,0x21, 0x1,0x46,0x66, 0x2,0x21,0x62, 0x1,0x46,0x65, + 0x1,0x46,0x64, 0x1,0x4a,0x65, 0x2,0x21,0x61, 0x3,0x22,0x58, + 0x3,0x22,0x59, 0x2,0x22,0x59, 0xf,0x21,0x66, 0x2,0x22,0x5d, + 0x2,0x22,0x5f, 0x2,0x22,0x60, 0x1,0x48,0x46, 0x1,0x48,0x47, + 0x2,0x22,0x5c, 0x1,0x48,0x42, 0x3,0x23,0x7d, 0x2,0x22,0x5a, + 0x3,0x24,0x25, 0x2,0x22,0x5e, 0x1,0x48,0x43, 0x3,0x26,0x55, + 0x1,0x48,0x3e, 0x3,0x23,0x7c, 0x1,0x48,0x3f, 0x3,0x24,0x23, + 0x1,0x48,0x45, 0x2,0x22,0x5b, 0x1,0x48,0x3d, 0x1,0x4a,0x66, + 0x1,0x48,0x40, 0x1,0x48,0x41, 0x1,0x48,0x44, 0xf,0x22,0x5d, + 0x3,0x65,0x3c, 0x2,0x24,0x5b, 0x2,0x24,0x59, 0x2,0x24,0x4c, + 0x1,0x4a,0x72, 0x2,0x24,0x53, 0x1,0x4a,0x6d, 0x2,0x24,0x4d, + 0x3,0x29,0x64, 0x2,0x24,0x55, 0x3,0x26,0x50, 0x2,0x24,0x52, + 0x1,0x4a,0x70, 0x2,0x24,0x51, 0x1,0x4a,0x77, 0x2,0x24,0x5a, + 0x1,0x4a,0x79, 0x3,0x26,0x53, 0x1,0x4a,0x7b, 0x3,0x23,0x7e, + 0x2,0x24,0x4b, 0x3,0x26,0x57, 0x1,0x4a,0x6e, 0x2,0x24,0x5c, + 0x3,0x26,0x51, 0x1,0x4a,0x75, 0x1,0x4a,0x78, 0x3,0x26,0x4c, + 0x2,0x27,0x65, 0x1,0x4a,0x68, 0x1,0x4b,0x21, 0x1,0x4a,0x76, + 0x2,0x24,0x4e, 0x1,0x4a,0x6b, 0x1,0x4a,0x7a, 0x2,0x24,0x56, + 0x1,0x4a,0x69, 0x1,0x4a,0x6a, 0x2,0x27,0x63, 0x2,0x24,0x4f, + 0x1,0x4a,0x71, 0x1,0x4a,0x7c, 0x2,0x24,0x5d, 0x2,0x24,0x50, + 0x1,0x4a,0x6f, 0x3,0x26,0x4d, 0x1,0x4a,0x74, 0x2,0x27,0x4f, + 0x1,0x4a,0x7d, 0x2,0x24,0x57, 0x1,0x4a,0x73, 0x3,0x29,0x63, + 0x1,0x4a,0x7e, 0x1,0x4a,0x67, 0x2,0x24,0x54, 0x1,0x4a,0x6c, + 0x2,0x24,0x58, 0x2,0x27,0x64, 0x3,0x26,0x4e, 0x3,0x26,0x52, + 0x3,0x26,0x5c, 0x3,0x26,0x59, 0x3,0x26,0x56, 0xf,0x24,0x68, + 0x3,0x26,0x5b, 0x1,0x4e,0x4d, 0x1,0x4e,0x5d, 0x2,0x27,0x56, + 0x1,0x4e,0x54, 0x3,0x2d,0x4e, 0x2,0x27,0x6b, 0x1,0x4e,0x45, + 0x3,0x29,0x6b, 0x1,0x4e,0x48, 0x2,0x27,0x62, 0x4,0x27,0x26, + 0x2,0x27,0x54, 0x2,0x27,0x58, 0x1,0x4e,0x50, 0x1,0x4e,0x52, + 0x2,0x27,0x5b, 0x1,0x4e,0x59, 0x1,0x4e,0x4b, 0x1,0x4e,0x49, + 0x1,0x4e,0x4a, 0x1,0x4e,0x58, 0x2,0x27,0x67, 0x1,0x4e,0x53, + 0x2,0x27,0x5a, 0x2,0x27,0x5c, 0x1,0x4e,0x51, 0x1,0x4e,0x56, + 0x2,0x27,0x5d, 0x2,0x27,0x6a, 0x3,0x29,0x6d, 0x1,0x51,0x78, + 0x1,0x4e,0x5c, 0x4,0x26,0x7d, 0x1,0x4e,0x46, 0x2,0x27,0x69, + 0x3,0x29,0x6c, 0x2,0x27,0x6d, 0x2,0x27,0x59, 0x2,0x27,0x6f, + 0x2,0x27,0x60, 0x1,0x4e,0x4f, 0x2,0x27,0x55, 0x1,0x4e,0x4e, + 0x1,0x4e,0x60, 0x1,0x4e,0x55, 0x3,0x29,0x6a, 0x2,0x27,0x53, + 0x2,0x2b,0x57, 0x1,0x4e,0x5b, 0x1,0x4e,0x5f, 0x2,0x27,0x61, + 0x2,0x27,0x66, 0x3,0x29,0x65, 0x1,0x4e,0x61, 0x1,0x4e,0x5a, + 0x1,0x4e,0x4c, 0x1,0x4e,0x42, 0x3,0x29,0x69, 0x1,0x4e,0x47, + 0x4,0x26,0x7b, 0x2,0x27,0x57, 0x1,0x4e,0x43, 0x2,0x27,0x6e, + 0x3,0x29,0x67, 0x2,0x27,0x51, 0x2,0x27,0x50, 0x2,0x27,0x5e, + 0x2,0x27,0x52, 0x1,0x4e,0x5e, 0x1,0x56,0x39, 0x1,0x4e,0x57, + 0x2,0x27,0x5f, 0x1,0x4e,0x44, 0x3,0x2d,0x4f, 0x1,0x52,0x29, + 0x2,0x27,0x6c, 0x3,0x2d,0x46, 0x2,0x2b,0x5e, 0x2,0x2b,0x61, + 0x3,0x2d,0x50, 0x2,0x2b,0x64, 0x2,0x2b,0x59, 0x3,0x2d,0x48, + 0x3,0x2d,0x4a, 0x2,0x2b,0x67, 0x2,0x2b,0x6a, 0x2,0x2b,0x6c, + 0x2,0x2b,0x56, 0x1,0x51,0x79, 0x1,0x51,0x7e, 0x2,0x30,0x2c, + 0x1,0x52,0x30, 0x2,0x2b,0x65, 0x2,0x2b,0x6d, 0x2,0x2b,0x5d, + 0x2,0x2b,0x55, 0x3,0x2d,0x49, 0x3,0x2d,0x47, 0x3,0x2d,0x4d, + 0x2,0x30,0x47, 0x1,0x52,0x23, 0x2,0x2b,0x62, 0x2,0x2b,0x5a, + 0x2,0x2b,0x5c, 0x1,0x52,0x28, 0x3,0x31,0x7a, 0x2,0x2b,0x5f, + 0x1,0x52,0x22, 0x2,0x2b,0x52, 0x2,0x2b,0x68, 0x3,0x2d,0x4b, + 0x2,0x2b,0x6b, 0x3,0x2d,0x45, 0x3,0x2d,0x57, 0x1,0x51,0x7d, + 0x3,0x2d,0x53, 0x1,0x52,0x2b, 0x2,0x2b,0x4f, 0x1,0x52,0x2d, + 0x1,0x51,0x7b, 0x1,0x52,0x31, 0x2,0x2b,0x69, 0x2,0x2b,0x51, + 0x1,0x52,0x2e, 0x2,0x30,0x41, 0x2,0x27,0x68, 0x1,0x52,0x21, + 0x1,0x51,0x7a, 0x2,0x2b,0x58, 0x2,0x2b,0x50, 0x1,0x52,0x2f, + 0x1,0x52,0x27, 0x2,0x2b,0x63, 0x1,0x52,0x2c, 0x1,0x52,0x2a, + 0x2,0x2b,0x5b, 0x1,0x52,0x24, 0x2,0x2b,0x53, 0x1,0x52,0x25, + 0x1,0x52,0x26, 0x2,0x2b,0x54, 0x2,0x2b,0x66, 0x1,0x51,0x7c, + 0x2,0x2b,0x60, 0x4,0x2a,0x21, 0x3,0x2d,0x55, 0x3,0x2d,0x51, + 0x3,0x31,0x77, 0x3,0x31,0x73, 0x2,0x30,0x2f, 0x1,0x56,0x41, + 0x1,0x56,0x46, 0x3,0x31,0x79, 0x3,0x32,0x26, 0x3,0x31,0x76, + 0x2,0x30,0x38, 0x2,0x30,0x3e, 0x2,0x30,0x3a, 0x2,0x30,0x2d, + 0x2,0x30,0x30, 0x2,0x30,0x29, 0x2,0x30,0x2a, 0x1,0x56,0x4d, + 0x1,0x56,0x3e, 0x2,0x30,0x39, 0x2,0x30,0x42, 0x1,0x56,0x48, + 0x1,0x56,0x3a, 0x3,0x31,0x6f, 0x1,0x56,0x43, 0x2,0x30,0x31, + 0x1,0x56,0x45, 0x2,0x30,0x32, 0x2,0x30,0x3c, 0x3,0x32,0x22, + 0x3,0x32,0x25, 0x3,0x31,0x72, 0x1,0x56,0x47, 0x2,0x30,0x4b, + 0x2,0x30,0x2b, 0x1,0x56,0x40, 0x1,0x56,0x3f, 0x1,0x56,0x4b, + 0x2,0x30,0x28, 0x2,0x30,0x49, 0x2,0x30,0x3d, 0x2,0x30,0x4a, + 0x2,0x30,0x44, 0x2,0x30,0x36, 0x2,0x30,0x45, 0x3,0x32,0x21, + 0x2,0x30,0x3f, 0x2,0x30,0x48, 0x2,0x30,0x46, 0x1,0x56,0x4c, + 0x2,0x30,0x37, 0x1,0x56,0x3d, 0x1,0x56,0x3c, 0x1,0x56,0x44, + 0x1,0x56,0x4a, 0x2,0x30,0x43, 0x1,0x56,0x49, 0x2,0x30,0x34, + 0x1,0x5b,0x48, 0x3,0x31,0x78, 0x2,0x30,0x4c, 0x2,0x30,0x33, + 0x2,0x30,0x2e, 0x1,0x56,0x42, 0x1,0x56,0x4e, 0x1,0x56,0x3b, + 0x3,0x32,0x27, 0x2,0x30,0x3b, 0x2,0x30,0x40, 0x3,0x31,0x7d, + 0x3,0x31,0x7b, 0x3,0x31,0x7c, 0x3,0x65,0x3d, 0x1,0x5b,0x6a, + 0x2,0x36,0x45, 0x2,0x36,0x49, 0x3,0x36,0x6f, 0x1,0x5b,0x57, + 0x1,0x5b,0x55, 0x3,0x36,0x7a, 0x3,0x37,0x21, 0x1,0x5b,0x4c, + 0x2,0x36,0x47, 0x2,0x36,0x46, 0x1,0x5b,0x60, 0x3,0x3c,0x50, + 0x2,0x36,0x4c, 0x1,0x5b,0x5a, 0x3,0x36,0x72, 0x2,0x36,0x5e, + 0x2,0x36,0x6a, 0x1,0x5b,0x49, 0x2,0x36,0x5b, 0x2,0x36,0x54, + 0x1,0x5b,0x6c, 0x2,0x36,0x44, 0x3,0x36,0x6a, 0x2,0x36,0x60, + 0x3,0x36,0x6b, 0x1,0x5b,0x69, 0x1,0x5b,0x5d, 0x1,0x5b,0x68, + 0x1,0x5b,0x53, 0x2,0x36,0x50, 0x2,0x36,0x62, 0x2,0x36,0x5a, + 0x1,0x5b,0x54, 0x1,0x5b,0x4e, 0x2,0x36,0x68, 0x3,0x36,0x6c, + 0x2,0x36,0x61, 0x2,0x36,0x63, 0x1,0x5b,0x56, 0x1,0x5b,0x5e, + 0x2,0x36,0x65, 0x2,0x36,0x4e, 0x2,0x36,0x5f, 0x2,0x36,0x53, + 0x2,0x36,0x67, 0x1,0x5b,0x63, 0x1,0x5b,0x4b, 0x1,0x5b,0x61, + 0x2,0x36,0x58, 0x2,0x36,0x56, 0x2,0x36,0x57, 0x1,0x5b,0x58, + 0x2,0x36,0x52, 0x2,0x36,0x51, 0x1,0x5b,0x4d, 0x2,0x36,0x4b, + 0x2,0x36,0x69, 0x1,0x5b,0x4f, 0x2,0x36,0x55, 0x1,0x5b,0x6d, + 0x3,0x36,0x74, 0x1,0x5b,0x67, 0x2,0x36,0x4a, 0x1,0x5b,0x64, + 0x1,0x5b,0x62, 0x1,0x5b,0x6b, 0x2,0x36,0x5c, 0x1,0x5b,0x66, + 0x2,0x30,0x35, 0x2,0x36,0x5d, 0x1,0x5b,0x65, 0x2,0x36,0x64, + 0x1,0x5b,0x4a, 0x2,0x36,0x59, 0x1,0x5b,0x5c, 0x2,0x36,0x4d, + 0x1,0x5b,0x5b, 0x3,0x36,0x7c, 0x1,0x5b,0x59, 0x1,0x5b,0x51, + 0x1,0x5b,0x50, 0x2,0x3d,0x2c, 0x2,0x36,0x66, 0x3,0x3c,0x5d, + 0x3,0x37,0x28, 0x2,0x36,0x4f, 0x3,0x37,0x26, 0x3,0x37,0x23, + 0x2,0x3d,0x41, 0x3,0x36,0x70, 0x1,0x5b,0x52, 0x3,0x36,0x77, + 0x3,0x37,0x24, 0x3,0x36,0x76, 0x3,0x37,0x25, 0x3,0x36,0x79, + 0x4,0x32,0x6d, 0x3,0x36,0x7d, 0x3,0x65,0x3e, 0x3,0x37,0x29, + 0xf,0x36,0x29, 0x3,0x37,0x27, 0x3,0x3c,0x54, 0x1,0x60,0x47, + 0x1,0x5b,0x5f, 0x1,0x60,0x35, 0x2,0x3d,0x3b, 0x1,0x60,0x43, + 0x3,0x3c,0x52, 0x2,0x3d,0x2f, 0x1,0x60,0x32, 0x1,0x60,0x2e, + 0x2,0x3d,0x4d, 0x1,0x60,0x34, 0x1,0x60,0x38, 0x1,0x60,0x33, + 0x1,0x60,0x3c, 0x2,0x3d,0x51, 0x2,0x3d,0x48, 0x3,0x3c,0x6b, + 0x3,0x3c,0x6d, 0x2,0x3d,0x36, 0x1,0x60,0x41, 0x1,0x60,0x3b, + 0x2,0x3d,0x42, 0x1,0x60,0x2b, 0x2,0x3d,0x4e, 0x2,0x3d,0x47, + 0x1,0x60,0x2f, 0x2,0x3d,0x3c, 0x1,0x60,0x3e, 0x2,0x3d,0x59, + 0x2,0x3d,0x5a, 0x4,0x38,0x5b, 0x1,0x60,0x2c, 0x2,0x3d,0x4c, + 0x1,0x60,0x40, 0x2,0x3d,0x40, 0x2,0x3d,0x32, 0x2,0x3d,0x33, + 0x1,0x60,0x44, 0x2,0x3d,0x37, 0x2,0x3d,0x3e, 0x2,0x3d,0x38, + 0x3,0x3c,0x5a, 0x1,0x60,0x42, 0x1,0x60,0x4a, 0x2,0x3d,0x34, + 0x2,0x3d,0x2d, 0x2,0x3d,0x2e, 0x3,0x3c,0x56, 0x2,0x3d,0x30, + 0x1,0x60,0x31, 0x2,0x3d,0x3d, 0x3,0x3c,0x6e, 0x1,0x60,0x3f, + 0x1,0x60,0x48, 0x3,0x3c,0x58, 0x3,0x3c,0x69, 0x2,0x3d,0x3f, + 0x2,0x3d,0x57, 0x2,0x3d,0x4f, 0x1,0x60,0x2d, 0x2,0x3d,0x55, + 0x1,0x60,0x39, 0x3,0x3c,0x66, 0x1,0x60,0x37, 0x3,0x3c,0x64, + 0x2,0x3d,0x5b, 0x1,0x60,0x36, 0x2,0x3d,0x45, 0x2,0x3d,0x39, + 0x2,0x3d,0x43, 0x1,0x60,0x4d, 0x2,0x3d,0x49, 0x2,0x3d,0x46, + 0x2,0x3d,0x35, 0x1,0x60,0x49, 0x2,0x3d,0x53, 0x2,0x3d,0x50, + 0x2,0x3d,0x58, 0x1,0x60,0x30, 0x2,0x3d,0x44, 0x1,0x60,0x4c, + 0x3,0x3c,0x5b, 0x2,0x3d,0x4b, 0x3,0x42,0x3a, 0x3,0x3c,0x60, + 0x1,0x60,0x3a, 0x1,0x60,0x3d, 0x3,0x3c,0x5c, 0x2,0x3d,0x4a, + 0x1,0x60,0x4b, 0x2,0x3d,0x3a, 0x2,0x36,0x48, 0x3,0x3c,0x51, + 0x3,0x3c,0x6c, 0x2,0x3d,0x54, 0x2,0x3d,0x52, 0x2,0x3d,0x56, + 0xf,0x3c,0x5d, 0x3,0x3c,0x62, 0x3,0x65,0x42, 0x4,0x38,0x5e, + 0x3,0x3c,0x63, 0x3,0x3c,0x68, 0xf,0x3c,0x47, 0x3,0x65,0x40, + 0x4,0x38,0x5f, 0x2,0x3d,0x31, 0x1,0x60,0x46, 0x3,0x65,0x3f, + 0x3,0x65,0x41, 0x2,0x44,0x47, 0x2,0x44,0x46, 0x2,0x44,0x2c, + 0x1,0x64,0x63, 0x3,0x42,0x30, 0x2,0x44,0x45, 0x2,0x44,0x2f, + 0x2,0x44,0x30, 0x4,0x3e,0x3f, 0x1,0x64,0x6d, 0x2,0x44,0x4e, + 0x1,0x64,0x68, 0x2,0x44,0x44, 0x3,0x42,0x33, 0x2,0x44,0x29, + 0x1,0x64,0x6e, 0x1,0x64,0x64, 0x2,0x44,0x38, 0x2,0x44,0x2e, + 0x2,0x44,0x31, 0x2,0x44,0x49, 0x1,0x64,0x5e, 0x2,0x44,0x50, + 0x2,0x44,0x48, 0x1,0x64,0x67, 0x2,0x44,0x3d, 0x1,0x64,0x72, + 0x3,0x42,0x2e, 0x3,0x42,0x36, 0x1,0x64,0x71, 0x1,0x64,0x6b, + 0x3,0x42,0x40, 0x4,0x3e,0x36, 0x2,0x44,0x4f, 0x1,0x64,0x5f, + 0x2,0x44,0x3b, 0x2,0x44,0x32, 0x2,0x44,0x3f, 0x2,0x44,0x4b, + 0x1,0x64,0x73, 0x3,0x42,0x39, 0x1,0x64,0x61, 0x2,0x44,0x3a, + 0x3,0x42,0x2d, 0x2,0x44,0x33, 0x1,0x64,0x6a, 0x3,0x42,0x31, + 0x1,0x64,0x69, 0x2,0x44,0x36, 0x2,0x44,0x40, 0x2,0x44,0x4a, + 0x2,0x44,0x2d, 0x2,0x44,0x37, 0x1,0x64,0x62, 0x2,0x44,0x41, + 0x1,0x64,0x6f, 0x1,0x64,0x66, 0x2,0x44,0x34, 0x1,0x64,0x65, + 0x2,0x44,0x2b, 0x2,0x44,0x39, 0x2,0x44,0x4d, 0x1,0x60,0x45, + 0x1,0x69,0x57, 0x2,0x44,0x3c, 0x2,0x4b,0x34, 0x2,0x44,0x3e, + 0x2,0x44,0x4c, 0x1,0x64,0x6c, 0x2,0x44,0x35, 0x1,0x64,0x60, + 0x1,0x64,0x70, 0x1,0x6d,0x5a, 0x2,0x44,0x2a, 0x6,0x54,0x4e, + 0x2,0x44,0x43, 0x3,0x42,0x44, 0x3,0x42,0x3e, 0x3,0x42,0x47, + 0x2,0x44,0x42, 0x3,0x42,0x3d, 0x3,0x42,0x45, 0x3,0x42,0x3f, + 0x3,0x42,0x3b, 0x3,0x42,0x46, 0x2,0x4b,0x50, 0x1,0x69,0x54, + 0x2,0x4b,0x45, 0x2,0x4b,0x4a, 0x1,0x69,0x49, 0x3,0x47,0x56, + 0x2,0x4b,0x36, 0x1,0x69,0x56, 0x3,0x47,0x57, 0x1,0x69,0x40, + 0x2,0x4b,0x35, 0x2,0x4b,0x56, 0x1,0x69,0x58, 0x2,0x4b,0x39, + 0x2,0x4b,0x49, 0x3,0x47,0x65, 0x2,0x4b,0x3b, 0x2,0x4b,0x59, + 0x2,0x4b,0x55, 0x1,0x69,0x3e, 0x1,0x69,0x48, 0x2,0x51,0x5b, + 0x1,0x69,0x55, 0x1,0x69,0x46, 0x2,0x4b,0x37, 0x3,0x47,0x63, + 0x2,0x4b,0x54, 0x1,0x69,0x4a, 0x2,0x4b,0x51, 0x2,0x4b,0x5e, + 0x2,0x4b,0x3d, 0x2,0x4b,0x46, 0x3,0x4c,0x78, 0x3,0x47,0x5b, + 0x2,0x4b,0x5c, 0x2,0x4b,0x52, 0x1,0x69,0x45, 0x3,0x4c,0x6a, + 0x3,0x47,0x64, 0x2,0x4b,0x44, 0x1,0x69,0x3f, 0x1,0x69,0x3d, + 0x1,0x69,0x4f, 0x4,0x44,0x43, 0x3,0x47,0x5f, 0x2,0x4b,0x42, + 0x2,0x4b,0x3f, 0x2,0x4b,0x40, 0x3,0x47,0x5a, 0x2,0x4b,0x58, + 0x3,0x47,0x5c, 0x2,0x4b,0x5d, 0x2,0x4b,0x5b, 0x1,0x69,0x43, + 0x2,0x4b,0x5f, 0x1,0x69,0x47, 0x1,0x69,0x4e, 0x4,0x44,0x44, + 0x2,0x4b,0x38, 0x2,0x51,0x43, 0x2,0x4b,0x41, 0x3,0x47,0x5e, + 0x1,0x69,0x41, 0x1,0x69,0x53, 0x1,0x69,0x50, 0x1,0x69,0x44, + 0x2,0x4b,0x4b, 0x2,0x4b,0x3c, 0x1,0x69,0x51, 0x2,0x4b,0x4d, + 0x1,0x69,0x4b, 0x1,0x69,0x4d, 0x1,0x69,0x3c, 0x3,0x47,0x5d, + 0x2,0x4b,0x4f, 0x2,0x4b,0x47, 0x2,0x4b,0x3a, 0x1,0x69,0x4c, + 0x2,0x4b,0x57, 0x2,0x4b,0x5a, 0x2,0x4b,0x43, 0x2,0x4b,0x4e, + 0x3,0x4c,0x74, 0x1,0x69,0x42, 0x1,0x6d,0x49, 0x2,0x4b,0x4c, + 0x2,0x51,0x42, 0x3,0x47,0x62, 0x2,0x4b,0x53, 0x3,0x47,0x61, + 0x4,0x44,0x52, 0xf,0x4f,0x79, 0x3,0x65,0x44, 0x3,0x65,0x45, + 0x3,0x47,0x66, 0x3,0x65,0x43, 0x2,0x4b,0x3e, 0x2,0x51,0x4c, + 0x2,0x51,0x56, 0x1,0x6d,0x4c, 0x2,0x51,0x55, 0x2,0x51,0x61, + 0x1,0x6d,0x4e, 0x2,0x51,0x53, 0x4,0x4a,0x58, 0x2,0x51,0x57, + 0x1,0x6d,0x59, 0x3,0x4c,0x7d, 0x2,0x51,0x4e, 0x1,0x6d,0x51, + 0x3,0x4c,0x73, 0x2,0x51,0x5a, 0x2,0x57,0x7b, 0x1,0x6d,0x5d, + 0x1,0x6d,0x5c, 0x2,0x51,0x5c, 0x2,0x51,0x4b, 0x2,0x51,0x66, + 0x1,0x6d,0x57, 0x3,0x4c,0x6b, 0x1,0x6d,0x4d, 0x2,0x51,0x5f, + 0x4,0x4a,0x69, 0x2,0x51,0x63, 0x2,0x51,0x68, 0x2,0x51,0x5d, + 0x2,0x51,0x51, 0x1,0x6d,0x50, 0x1,0x6d,0x53, 0x1,0x6d,0x5b, + 0x1,0x6d,0x56, 0x3,0x4c,0x75, 0x2,0x51,0x54, 0x2,0x4b,0x48, + 0x3,0x4c,0x7e, 0x3,0x4c,0x6c, 0x2,0x51,0x50, 0x2,0x51,0x67, + 0x1,0x6d,0x52, 0x3,0x4c,0x79, 0x1,0x6d,0x55, 0x2,0x51,0x69, + 0x1,0x6d,0x4a, 0x2,0x51,0x5e, 0x2,0x51,0x44, 0x2,0x51,0x64, + 0x1,0x74,0x2a, 0x3,0x4c,0x7a, 0x2,0x51,0x52, 0x4,0x50,0x75, + 0x1,0x6d,0x4b, 0x2,0x51,0x4d, 0x1,0x6d,0x4f, 0x2,0x51,0x45, + 0x1,0x69,0x52, 0x2,0x51,0x49, 0x4,0x4a,0x57, 0x2,0x51,0x62, + 0x2,0x51,0x4a, 0x2,0x51,0x48, 0x1,0x6d,0x54, 0x3,0x4c,0x7b, + 0x2,0x51,0x60, 0x3,0x4c,0x77, 0x2,0x51,0x47, 0x2,0x51,0x59, + 0x2,0x51,0x58, 0x2,0x51,0x65, 0x2,0x51,0x4f, 0x1,0x6d,0x58, + 0x4,0x4a,0x64, 0x3,0x65,0x47, 0xf,0x4f,0x7d, 0x3,0x65,0x46, + 0x2,0x57,0x7e, 0x3,0x51,0x56, 0x1,0x71,0x33, 0x1,0x71,0x29, + 0x2,0x58,0x2c, 0x2,0x57,0x76, 0x1,0x71,0x2b, 0x2,0x58,0x24, + 0x1,0x71,0x32, 0x1,0x71,0x2d, 0x2,0x58,0x22, 0x2,0x5d,0x3b, + 0x2,0x58,0x28, 0x2,0x58,0x2e, 0x2,0x58,0x27, 0x2,0x57,0x74, + 0x2,0x58,0x25, 0x2,0x58,0x30, 0x2,0x58,0x32, 0x1,0x71,0x28, + 0x2,0x58,0x31, 0x1,0x71,0x2e, 0x1,0x71,0x34, 0x3,0x51,0x54, + 0x1,0x71,0x31, 0x3,0x51,0x58, 0x2,0x58,0x2b, 0x1,0x71,0x30, + 0x2,0x58,0x26, 0x3,0x51,0x4d, 0x2,0x57,0x78, 0x2,0x57,0x7d, + 0x3,0x51,0x50, 0x2,0x58,0x2a, 0x1,0x71,0x2f, 0x1,0x71,0x2c, + 0x1,0x71,0x27, 0x1,0x71,0x2a, 0x2,0x57,0x7c, 0x4,0x51,0x22, + 0x2,0x51,0x46, 0x2,0x57,0x77, 0x2,0x57,0x7a, 0x2,0x58,0x2d, + 0x2,0x58,0x21, 0x2,0x57,0x75, 0x2,0x5d,0x3a, 0x2,0x58,0x2f, + 0x2,0x57,0x79, 0x2,0x58,0x29, 0x3,0x4c,0x71, 0x3,0x51,0x55, + 0x2,0x5d,0x3d, 0x1,0x74,0x2e, 0x3,0x55,0x30, 0x3,0x55,0x2f, + 0x1,0x74,0x22, 0x3,0x55,0x35, 0x3,0x55,0x36, 0x1,0x74,0x26, + 0x2,0x5d,0x3f, 0x2,0x5d,0x45, 0x2,0x5d,0x43, 0x1,0x74,0x24, + 0x1,0x74,0x25, 0x1,0x74,0x2c, 0x2,0x5d,0x46, 0x2,0x5d,0x3e, + 0x1,0x74,0x27, 0x3,0x55,0x31, 0x2,0x5d,0x42, 0x2,0x5d,0x41, + 0x2,0x5d,0x47, 0x1,0x74,0x2d, 0x3,0x55,0x37, 0x1,0x74,0x28, + 0x1,0x74,0x2b, 0x2,0x5d,0x40, 0x1,0x74,0x2f, 0x1,0x74,0x29, + 0x1,0x74,0x30, 0x1,0x74,0x23, 0x2,0x5d,0x44, 0x3,0x5a,0x55, + 0x2,0x5d,0x3c, 0x3,0x51,0x59, 0x3,0x55,0x39, 0x2,0x62,0x25, + 0x3,0x65,0x48, 0x1,0x76,0x5d, 0x2,0x62,0x22, 0x2,0x62,0x24, + 0x3,0x58,0x28, 0x1,0x76,0x5b, 0x2,0x61,0x7e, 0x2,0x62,0x21, + 0x2,0x61,0x7a, 0x3,0x58,0x2a, 0x3,0x58,0x27, 0x2,0x58,0x23, + 0x2,0x61,0x7b, 0x1,0x76,0x5c, 0x2,0x61,0x77, 0x3,0x58,0x26, + 0x1,0x76,0x59, 0x2,0x62,0x26, 0x1,0x76,0x5a, 0x2,0x61,0x78, + 0x2,0x61,0x79, 0x2,0x61,0x7d, 0x1,0x76,0x5f, 0x3,0x58,0x29, + 0x1,0x76,0x5e, 0x4,0x5b,0x5e, 0x3,0x58,0x2b, 0x2,0x61,0x7c, + 0x1,0x78,0x45, 0x2,0x65,0x6a, 0x2,0x65,0x70, 0x1,0x78,0x46, + 0x2,0x65,0x67, 0x1,0x78,0x43, 0x1,0x78,0x40, 0x2,0x65,0x72, + 0x1,0x78,0x44, 0x3,0x5a,0x52, 0x1,0x78,0x41, 0x2,0x65,0x69, + 0x2,0x65,0x6c, 0x2,0x65,0x6d, 0x2,0x65,0x6e, 0x2,0x65,0x71, + 0x3,0x5a,0x54, 0x2,0x62,0x23, 0x2,0x65,0x68, 0x1,0x78,0x42, + 0x2,0x65,0x6f, 0x2,0x69,0x34, 0x2,0x65,0x6b, 0x3,0x5a,0x53, + 0x3,0x65,0x4a, 0x3,0x65,0x49, 0x2,0x69,0x2b, 0x1,0x79,0x75, + 0x2,0x69,0x2e, 0x1,0x79,0x76, 0x2,0x69,0x37, 0x2,0x69,0x2d, + 0x2,0x69,0x2a, 0x3,0x5c,0x51, 0x2,0x69,0x2c, 0x2,0x69,0x30, + 0x2,0x69,0x33, 0x2,0x69,0x32, 0x2,0x69,0x36, 0x2,0x69,0x29, + 0x3,0x5c,0x4f, 0x1,0x79,0x74, 0x2,0x69,0x31, 0x2,0x69,0x35, + 0x2,0x69,0x38, 0x2,0x69,0x2f, 0x2,0x6b,0x61, 0x2,0x6b,0x62, + 0x2,0x6b,0x66, 0x2,0x6b,0x67, 0x3,0x5e,0x3c, 0x2,0x6b,0x64, + 0x2,0x6b,0x65, 0x2,0x6b,0x63, 0x3,0x5e,0x3a, 0x1,0x7a,0x74, + 0x3,0x5e,0x3b, 0x1,0x7b,0x64, 0x2,0x6d,0x59, 0x3,0x60,0x36, + 0x3,0x5f,0x52, 0x2,0x6d,0x56, 0x2,0x6d,0x57, 0x2,0x6d,0x58, + 0x1,0x7b,0x65, 0x3,0x60,0x37, 0x2,0x6f,0x34, 0x2,0x6f,0x33, + 0x3,0x65,0x4b, 0x2,0x70,0x3d, 0x1,0x7c,0x60, 0x2,0x70,0x3b, + 0x2,0x70,0x3e, 0x2,0x70,0x3c, 0x2,0x71,0x25, 0x1,0x7d,0x24, + 0x1,0x7d,0x32, 0x2,0x71,0x71, 0x2,0x71,0x5b, 0x3,0x61,0x79, + 0x2,0x71,0x70, 0x2,0x72,0x3e, 0x2,0x72,0x3f, 0x1,0x45,0x56, + 0x4,0x21,0x50, 0x3,0x24,0x28, 0x3,0x24,0x26, 0x1,0x48,0x48, + 0x2,0x22,0x61, 0x3,0x24,0x27, 0x3,0x24,0x2b, 0x2,0x24,0x5e, + 0x3,0x26,0x62, 0x1,0x4b,0x22, 0x3,0x26,0x5f, 0x1,0x4b,0x25, + 0x3,0x26,0x5e, 0x2,0x24,0x5f, 0x3,0x26,0x63, 0x1,0x4b,0x23, + 0x1,0x4b,0x24, 0x3,0x26,0x60, 0xf,0x24,0x71, 0x3,0x29,0x77, + 0x2,0x27,0x78, 0x2,0x27,0x7a, 0x2,0x27,0x75, 0x2,0x27,0x72, + 0x2,0x27,0x74, 0x3,0x29,0x74, 0x3,0x29,0x70, 0x3,0x29,0x75, + 0x1,0x4e,0x65, 0x3,0x29,0x6f, 0x3,0x29,0x79, 0x3,0x29,0x76, + 0x1,0x4e,0x63, 0x3,0x29,0x72, 0x3,0x29,0x71, 0x2,0x27,0x76, + 0x1,0x4e,0x64, 0x2,0x27,0x73, 0x2,0x27,0x70, 0x1,0x4e,0x62, + 0x2,0x27,0x77, 0x4,0x27,0x29, 0x2,0x27,0x71, 0x1,0x4e,0x66, + 0x2,0x27,0x79, 0x4,0x27,0x2b, 0x2,0x2b,0x6f, 0x3,0x2d,0x5e, + 0x2,0x2b,0x73, 0x3,0x2d,0x5c, 0x3,0x2d,0x5a, 0x1,0x52,0x3a, + 0x3,0x2d,0x58, 0x4,0x2a,0x26, 0x3,0x2d,0x65, 0x3,0x2d,0x62, + 0x2,0x2b,0x76, 0x3,0x2d,0x5f, 0x1,0x52,0x32, 0x1,0x52,0x35, + 0x1,0x52,0x37, 0x1,0x52,0x39, 0x1,0x52,0x36, 0x2,0x2b,0x72, + 0x2,0x2b,0x71, 0x3,0x2d,0x64, 0x1,0x52,0x34, 0x2,0x2b,0x74, + 0x2,0x2b,0x75, 0x3,0x2d,0x63, 0x2,0x2b,0x6e, 0x1,0x52,0x38, + 0x3,0x2d,0x68, 0x1,0x52,0x33, 0x3,0x2d,0x5d, 0x2,0x2b,0x70, + 0x3,0x65,0x4d, 0x4,0x2a,0x28, 0x3,0x32,0x28, 0x2,0x30,0x5a, + 0x2,0x30,0x5b, 0x2,0x30,0x5c, 0x1,0x56,0x53, 0x4,0x2d,0x75, + 0x1,0x56,0x4f, 0x2,0x30,0x51, 0x3,0x32,0x2a, 0x2,0x30,0x59, + 0x2,0x30,0x5e, 0x1,0x56,0x54, 0x3,0x32,0x2b, 0x2,0x30,0x4f, + 0x2,0x30,0x55, 0x2,0x30,0x4e, 0x2,0x30,0x58, 0x3,0x32,0x31, + 0x3,0x32,0x2f, 0x2,0x30,0x54, 0x1,0x56,0x50, 0x1,0x56,0x52, + 0x2,0x30,0x5d, 0x3,0x32,0x29, 0x2,0x30,0x4d, 0x2,0x30,0x50, + 0x2,0x30,0x56, 0x3,0x32,0x2d, 0x2,0x30,0x57, 0x2,0x30,0x5f, + 0x2,0x30,0x53, 0x3,0x32,0x2c, 0x1,0x56,0x51, 0x3,0x65,0x4f, + 0x3,0x65,0x4e, 0x3,0x32,0x30, 0x1,0x5b,0x72, 0x2,0x36,0x71, + 0x3,0x37,0x30, 0x3,0x37,0x32, 0x2,0x36,0x73, 0x2,0x36,0x6f, + 0x3,0x37,0x2f, 0x2,0x36,0x7b, 0x2,0x36,0x6d, 0x2,0x36,0x7a, + 0x1,0x5b,0x6e, 0x2,0x36,0x6b, 0x2,0x3d,0x5f, 0x2,0x36,0x75, + 0x1,0x5b,0x71, 0x3,0x37,0x35, 0x2,0x36,0x76, 0x2,0x36,0x79, + 0x3,0x37,0x2e, 0x2,0x36,0x7d, 0x3,0x37,0x2c, 0x2,0x36,0x72, + 0x4,0x32,0x72, 0x2,0x36,0x77, 0x3,0x37,0x2d, 0x3,0x37,0x31, + 0x1,0x5b,0x6f, 0x1,0x5b,0x70, 0x2,0x36,0x7c, 0x2,0x36,0x70, + 0x2,0x36,0x6c, 0x2,0x36,0x7e, 0x3,0x37,0x33, 0x2,0x36,0x74, + 0x3,0x65,0x50, 0x3,0x65,0x51, 0x2,0x36,0x78, 0x2,0x36,0x6e, + 0x1,0x60,0x4e, 0x1,0x60,0x4f, 0x2,0x3d,0x69, 0x1,0x60,0x55, + 0x3,0x3c,0x74, 0x2,0x3d,0x5d, 0x2,0x3d,0x66, 0x2,0x3d,0x5c, + 0x1,0x60,0x52, 0x2,0x3d,0x64, 0x2,0x3d,0x62, 0x3,0x3c,0x7d, + 0x2,0x3d,0x63, 0x1,0x60,0x50, 0x3,0x3c,0x7c, 0x2,0x3d,0x67, + 0xf,0x3c,0x7e, 0x3,0x3c,0x6f, 0x3,0x3c,0x7a, 0x3,0x3c,0x72, + 0x3,0x3d,0x21, 0x2,0x3d,0x60, 0x2,0x3d,0x5e, 0x1,0x60,0x51, + 0x2,0x3d,0x61, 0x2,0x3d,0x65, 0x3,0x3c,0x7b, 0x3,0x3c,0x79, + 0x3,0x3c,0x71, 0x1,0x60,0x53, 0x3,0x3c,0x73, 0x3,0x3c,0x77, + 0x3,0x65,0x53, 0x2,0x3d,0x68, 0x3,0x65,0x54, 0x3,0x65,0x55, + 0x3,0x65,0x52, 0x2,0x44,0x56, 0x2,0x44,0x5d, 0x2,0x44,0x5f, + 0x2,0x44,0x65, 0x3,0x42,0x57, 0x1,0x65,0x22, 0x2,0x44,0x51, + 0x3,0x42,0x4c, 0x1,0x64,0x78, 0x3,0x42,0x4e, 0x2,0x44,0x60, + 0x1,0x64,0x7d, 0x2,0x44,0x66, 0x1,0x64,0x74, 0x3,0x42,0x51, + 0x2,0x44,0x63, 0x3,0x42,0x58, 0x2,0x44,0x53, 0x2,0x44,0x64, + 0x2,0x44,0x52, 0x1,0x65,0x24, 0x3,0x42,0x52, 0x2,0x44,0x5e, + 0x1,0x64,0x75, 0x2,0x44,0x67, 0x3,0x48,0x3c, 0x1,0x64,0x7a, + 0x2,0x44,0x57, 0x1,0x65,0x21, 0x2,0x44,0x62, 0x2,0x44,0x55, + 0x2,0x44,0x5c, 0x2,0x44,0x58, 0x2,0x44,0x54, 0x1,0x64,0x77, + 0x1,0x64,0x7e, 0x1,0x64,0x7c, 0x1,0x64,0x79, 0x1,0x65,0x23, + 0x1,0x64,0x76, 0x2,0x44,0x5b, 0x3,0x42,0x4f, 0x1,0x64,0x7b, + 0x3,0x42,0x59, 0x1,0x60,0x54, 0x3,0x42,0x49, 0x2,0x44,0x61, + 0x3,0x65,0x59, 0x2,0x44,0x59, 0x3,0x42,0x53, 0x3,0x65,0x57, + 0x3,0x65,0x58, 0x3,0x65,0x56, 0x2,0x44,0x5a, 0x4,0x44,0x57, + 0x4,0x44,0x5b, 0x2,0x4b,0x67, 0x3,0x47,0x6f, 0x1,0x69,0x5b, + 0x3,0x47,0x6e, 0x3,0x47,0x6c, 0x2,0x4b,0x63, 0x2,0x4b,0x69, + 0x2,0x4b,0x65, 0x3,0x47,0x70, 0x1,0x69,0x5d, 0x2,0x4b,0x64, + 0x2,0x4b,0x68, 0x2,0x4b,0x60, 0x3,0x47,0x72, 0x2,0x4b,0x62, + 0x1,0x69,0x5c, 0x3,0x47,0x6a, 0x3,0x47,0x6d, 0x3,0x47,0x6b, + 0x3,0x47,0x68, 0x2,0x4b,0x66, 0x2,0x4b,0x61, 0x3,0x47,0x67, + 0x1,0x69,0x5e, 0x3,0x65,0x5b, 0x1,0x69,0x59, 0xf,0x49,0x4b, + 0x3,0x65,0x5a, 0x2,0x4b,0x6a, 0xf,0x49,0x5f, 0x1,0x69,0x5a, + 0x2,0x51,0x6f, 0x2,0x51,0x6c, 0x2,0x51,0x78, 0x2,0x51,0x72, + 0x2,0x51,0x74, 0x1,0x6d,0x5e, 0x2,0x51,0x6e, 0x2,0x51,0x76, + 0x3,0x4d,0x2a, 0x3,0x4d,0x24, 0x2,0x51,0x75, 0x2,0x51,0x73, + 0x3,0x4d,0x29, 0x2,0x51,0x79, 0x1,0x6d,0x61, 0x2,0x51,0x70, + 0x2,0x51,0x77, 0x3,0x4d,0x28, 0x1,0x6d,0x5f, 0x3,0x4d,0x25, + 0x3,0x4d,0x22, 0x2,0x51,0x6b, 0x2,0x51,0x6d, 0x1,0x6d,0x60, + 0x2,0x51,0x6a, 0x2,0x51,0x7a, 0x3,0x65,0x5c, 0x2,0x51,0x71, + 0x3,0x51,0x62, 0x3,0x51,0x5a, 0x2,0x58,0x36, 0x1,0x71,0x3b, + 0x3,0x51,0x60, 0x3,0x51,0x5c, 0x2,0x58,0x41, 0x2,0x58,0x3f, + 0x1,0x71,0x35, 0x2,0x58,0x35, 0x2,0x58,0x38, 0x2,0x58,0x39, + 0x2,0x58,0x34, 0x1,0x71,0x3f, 0x1,0x71,0x40, 0x2,0x58,0x33, + 0x2,0x58,0x42, 0x2,0x58,0x3d, 0x1,0x71,0x39, 0x1,0x71,0x36, + 0x2,0x58,0x3c, 0x2,0x58,0x3a, 0x3,0x51,0x63, 0x4,0x51,0x23, + 0x1,0x71,0x3c, 0x2,0x58,0x3e, 0x1,0x71,0x37, 0x3,0x51,0x5e, + 0x1,0x71,0x38, 0x3,0x51,0x66, 0x2,0x58,0x3b, 0x1,0x71,0x3a, + 0x2,0x58,0x37, 0x7,0x2f,0x4f, 0x2,0x58,0x40, 0x1,0x71,0x3d, + 0x2,0x58,0x43, 0x2,0x58,0x44, 0x1,0x71,0x3e, 0x3,0x65,0x5d, + 0x3,0x65,0x5e, 0x1,0x74,0x32, 0x1,0x74,0x39, 0x2,0x5d,0x48, + 0x2,0x5d,0x4e, 0x3,0x55,0x3c, 0x2,0x5d,0x4c, 0x1,0x74,0x35, + 0x1,0x74,0x34, 0x1,0x74,0x31, 0x2,0x5d,0x4a, 0x3,0x55,0x3e, + 0x3,0x55,0x43, 0x3,0x55,0x40, 0x1,0x74,0x37, 0x1,0x74,0x36, + 0x1,0x74,0x33, 0x3,0x55,0x41, 0x2,0x5d,0x4d, 0x2,0x5d,0x49, + 0x2,0x5d,0x4b, 0x3,0x55,0x42, 0x1,0x74,0x38, 0xf,0x5a,0x73, + 0x1,0x76,0x63, 0x2,0x62,0x29, 0x3,0x58,0x2d, 0x1,0x76,0x60, + 0x1,0x76,0x61, 0x2,0x62,0x2b, 0x1,0x76,0x62, 0x2,0x62,0x28, + 0x3,0x58,0x2e, 0x2,0x62,0x27, 0x2,0x65,0x76, 0x2,0x62,0x2a, + 0x3,0x5a,0x56, 0x2,0x65,0x77, 0x1,0x78,0x47, 0x2,0x65,0x75, + 0x3,0x5a,0x57, 0x4,0x5f,0x7e, 0x2,0x65,0x74, 0x3,0x5c,0x59, + 0x2,0x65,0x73, 0x1,0x78,0x48, 0x3,0x65,0x5f, 0x3,0x5c,0x56, + 0x1,0x79,0x77, 0x3,0x5c,0x58, 0x3,0x5c,0x55, 0x2,0x69,0x39, + 0x2,0x69,0x3a, 0x3,0x5a,0x58, 0x3,0x5c,0x53, 0x3,0x5c,0x57, + 0x3,0x65,0x61, 0x2,0x6b,0x6a, 0x2,0x6b,0x69, 0x1,0x7a,0x75, + 0x3,0x5f,0x53, 0x2,0x6b,0x68, 0x2,0x6d,0x5a, 0x2,0x6d,0x5b, + 0x3,0x5f,0x54, 0x3,0x60,0x39, 0x2,0x6f,0x35, 0x2,0x70,0x3f, + 0x3,0x61,0x43, 0x3,0x61,0x42, 0x2,0x71,0x26, 0x2,0x72,0x2c, + 0x1,0x7d,0x46, 0x2,0x72,0x40, 0x1,0x45,0x57, 0x4,0x21,0x51, + 0x1,0x4e,0x67, 0x1,0x4e,0x68, 0x3,0x2d,0x69, 0x4,0x2a,0x2a, + 0x1,0x52,0x3b, 0x3,0x3d,0x22, 0x4,0x4a,0x6c, 0x1,0x74,0x3a, + 0x1,0x45,0x58, 0x1,0x4e,0x69, 0x1,0x56,0x55, 0x1,0x65,0x25, + 0x1,0x45,0x59, 0x3,0x2d,0x6b, 0x1,0x5b,0x73, 0x1,0x69,0x5f, + 0x2,0x21,0x42, 0x3,0x29,0x7c, 0x2,0x2b,0x77, 0x2,0x30,0x60, + 0x4,0x3e,0x4c, 0x2,0x4b,0x6b, 0x4,0x4a,0x6d, 0x1,0x74,0x3b, + 0x1,0x45,0x5a, 0x1,0x4e,0x6a, 0x2,0x2b,0x78, 0x2,0x2b,0x79, + 0x2,0x3d,0x6a, 0x1,0x60,0x56, 0x3,0x42,0x5d, 0x2,0x44,0x68, + 0x3,0x42,0x5c, 0x3,0x42,0x5b, 0x1,0x65,0x26, 0x2,0x4b,0x6c, + 0x4,0x44,0x5e, 0x3,0x4d,0x2e, 0x1,0x6d,0x62, 0x3,0x4d,0x2d, + 0x1,0x78,0x49, 0x1,0x45,0x5b, 0x2,0x3d,0x6b, 0x1,0x45,0x5c, + 0x1,0x48,0x4a, 0x2,0x22,0x62, 0x1,0x48,0x49, 0x1,0x4b,0x28, + 0x1,0x4b,0x27, 0x1,0x4b,0x26, 0x2,0x24,0x60, 0x3,0x26,0x64, + 0x3,0x2a,0x21, 0x3,0x2a,0x22, 0x1,0x4e,0x6b, 0x3,0x2a,0x23, + 0x1,0x4e,0x6c, 0x2,0x27,0x7b, 0x4,0x27,0x31, 0x2,0x2b,0x7a, + 0x3,0x2d,0x6d, 0x2,0x2b,0x7d, 0x1,0x52,0x3d, 0x2,0x2b,0x7b, + 0x4,0x2a,0x2f, 0x1,0x52,0x3c, 0x2,0x2b,0x7c, 0x1,0x52,0x3e, + 0x2,0x30,0x63, 0x2,0x30,0x62, 0x2,0x30,0x61, 0x1,0x56,0x56, + 0x3,0x32,0x36, 0x2,0x37,0x22, 0x2,0x37,0x23, 0x1,0x5b,0x74, + 0x2,0x37,0x21, 0x2,0x37,0x24, 0x1,0x60,0x58, 0x1,0x5b,0x75, + 0x3,0x3d,0x24, 0x3,0x3d,0x23, 0x1,0x60,0x57, 0x2,0x3d,0x6f, + 0x2,0x3d,0x6e, 0x3,0x3d,0x25, 0x2,0x3d,0x6c, 0x2,0x3d,0x6d, + 0x2,0x3d,0x70, 0x2,0x44,0x6a, 0x2,0x44,0x69, 0x2,0x44,0x6d, + 0x4,0x3e,0x4f, 0x2,0x44,0x6c, 0x2,0x44,0x6b, 0x1,0x69,0x60, + 0x2,0x4b,0x6f, 0x3,0x47,0x75, 0x2,0x4b,0x6e, 0x1,0x69,0x61, + 0x2,0x4b,0x6d, 0x2,0x51,0x7b, 0x3,0x4d,0x2f, 0x2,0x51,0x7c, + 0x1,0x6d,0x63, 0x4,0x51,0x2d, 0x2,0x58,0x45, 0x2,0x58,0x46, + 0x5,0x4e,0x37, 0x2,0x65,0x7c, 0x1,0x78,0x4a, 0x2,0x65,0x7b, + 0x2,0x65,0x7a, 0x2,0x65,0x78, 0x2,0x65,0x79, 0x1,0x7a,0x76, + 0x2,0x69,0x3b, 0x2,0x6d,0x5c, 0x2,0x71,0x27, 0x3,0x61,0x7b, + 0x1,0x45,0x5d, 0x4,0x21,0x38, 0x2,0x21,0x64, 0x1,0x46,0x67, + 0x2,0x21,0x65, 0x3,0x24,0x2c, 0x3,0x24,0x2d, 0x4,0x23,0x27, + 0x2,0x22,0x63, 0x2,0x22,0x64, 0x3,0x26,0x6b, 0x3,0x26,0x69, + 0x2,0x24,0x66, 0x3,0x26,0x66, 0x3,0x26,0x67, 0x2,0x24,0x62, + 0x3,0x26,0x6a, 0x2,0x24,0x61, 0x1,0x4e,0x6d, 0x2,0x24,0x65, + 0x1,0x4b,0x2a, 0x2,0x24,0x63, 0x1,0x4b,0x29, 0x2,0x24,0x67, + 0x2,0x24,0x64, 0x3,0x26,0x68, 0x2,0x28,0x21, 0x2,0x2b,0x7e, + 0x2,0x27,0x7d, 0x2,0x28,0x26, 0x3,0x2a,0x26, 0x1,0x4e,0x6e, + 0x3,0x2a,0x2a, 0x1,0x4e,0x71, 0x2,0x28,0x27, 0x2,0x28,0x23, + 0x3,0x2a,0x27, 0x2,0x28,0x24, 0x4,0x27,0x36, 0x2,0x27,0x7c, + 0x1,0x4e,0x70, 0x2,0x27,0x7e, 0x1,0x4e,0x6f, 0x2,0x28,0x25, + 0x3,0x2a,0x28, 0x2,0x28,0x22, 0x6,0x2c,0x7e, 0x2,0x2c,0x24, + 0x1,0x52,0x40, 0x1,0x52,0x41, 0x3,0x2d,0x75, 0x2,0x2c,0x27, + 0x2,0x2c,0x21, 0x3,0x2d,0x74, 0x2,0x2c,0x26, 0x3,0x2d,0x70, + 0x2,0x2c,0x22, 0x1,0x52,0x3f, 0x2,0x2c,0x25, 0x2,0x2c,0x23, + 0x3,0x2d,0x73, 0x3,0x2d,0x71, 0x2,0x30,0x69, 0x2,0x30,0x66, + 0x3,0x32,0x38, 0x2,0x30,0x68, 0x1,0x56,0x5b, 0x1,0x56,0x5a, + 0x1,0x56,0x58, 0x2,0x30,0x65, 0x2,0x30,0x6a, 0x1,0x56,0x57, + 0x1,0x56,0x59, 0x2,0x30,0x67, 0x2,0x37,0x2c, 0x2,0x30,0x64, + 0x2,0x30,0x6b, 0x3,0x32,0x39, 0x4,0x33,0x23, 0x4,0x33,0x2a, + 0x3,0x3d,0x26, 0x2,0x37,0x27, 0x2,0x37,0x2b, 0x5,0x33,0x54, + 0x2,0x37,0x2a, 0x2,0x3d,0x72, 0x2,0x3d,0x7d, 0x4,0x33,0x2d, + 0x3,0x37,0x3b, 0x2,0x37,0x2d, 0x3,0x37,0x3a, 0x2,0x37,0x28, + 0x2,0x3d,0x71, 0x1,0x5b,0x79, 0x4,0x33,0x22, 0x4,0x33,0x2c, + 0x1,0x5b,0x78, 0x2,0x37,0x26, 0x2,0x37,0x29, 0x1,0x5b,0x7a, + 0x3,0x37,0x39, 0x1,0x5b,0x77, 0x1,0x5b,0x76, 0x2,0x37,0x25, + 0x2,0x37,0x2e, 0x2,0x3d,0x74, 0x2,0x3d,0x7b, 0x3,0x3d,0x27, + 0x1,0x60,0x5a, 0x2,0x3d,0x7a, 0x2,0x3d,0x77, 0x3,0x3d,0x2e, + 0x1,0x60,0x5c, 0x3,0x3d,0x29, 0x3,0x3d,0x2b, 0x3,0x3d,0x2a, + 0x2,0x3d,0x79, 0x3,0x42,0x61, 0x3,0x3d,0x2d, 0x2,0x3d,0x73, + 0x2,0x3d,0x75, 0x2,0x3d,0x78, 0x2,0x3d,0x76, 0x1,0x60,0x5b, + 0x2,0x3d,0x7c, 0x1,0x60,0x59, 0x1,0x65,0x27, 0x3,0x3d,0x28, + 0x2,0x44,0x71, 0x2,0x44,0x70, 0x2,0x44,0x6e, 0x6,0x54,0x7c, + 0x1,0x65,0x2a, 0x1,0x65,0x29, 0x2,0x44,0x72, 0x3,0x42,0x5f, + 0x2,0x44,0x6f, 0x2,0x4b,0x70, 0x1,0x69,0x62, 0x1,0x65,0x28, + 0x3,0x42,0x62, 0x3,0x65,0x62, 0x3,0x65,0x63, 0x2,0x44,0x74, + 0x2,0x44,0x73, 0x3,0x4d,0x30, 0x2,0x4b,0x73, 0x2,0x4b,0x71, + 0x1,0x6d,0x64, 0x3,0x47,0x79, 0x1,0x69,0x63, 0x2,0x4b,0x72, + 0x2,0x51,0x7e, 0x3,0x47,0x78, 0x3,0x47,0x7a, 0x3,0x47,0x77, + 0x4,0x4a,0x77, 0x1,0x6d,0x65, 0x2,0x51,0x7d, 0x2,0x52,0x28, + 0x2,0x52,0x27, 0x2,0x52,0x25, 0x4,0x4a,0x75, 0x2,0x52,0x24, + 0x2,0x52,0x21, 0x2,0x52,0x22, 0x2,0x52,0x23, 0x2,0x52,0x26, + 0x2,0x52,0x29, 0x2,0x58,0x4b, 0x2,0x58,0x48, 0x2,0x58,0x49, + 0x1,0x71,0x41, 0x2,0x58,0x47, 0x2,0x58,0x4d, 0x2,0x58,0x4c, + 0x2,0x58,0x4a, 0x2,0x5d,0x50, 0x2,0x5d,0x51, 0x1,0x74,0x3c, + 0x3,0x55,0x49, 0x1,0x74,0x3d, 0x2,0x5d,0x4f, 0x4,0x56,0x6c, + 0x1,0x76,0x65, 0x2,0x62,0x2c, 0x1,0x76,0x64, 0x1,0x78,0x4b, + 0x4,0x60,0x25, 0x1,0x78,0x4c, 0x1,0x79,0x78, 0x2,0x69,0x3d, + 0x2,0x69,0x3c, 0x2,0x6b,0x6b, 0x2,0x6d,0x5d, 0x1,0x7b,0x66, + 0x2,0x6f,0x37, 0x2,0x6f,0x36, 0x2,0x6f,0x38, 0x1,0x46,0x68, + 0x2,0x2c,0x28, 0x1,0x56,0x5c, 0x1,0x5b,0x7b, 0x2,0x37,0x2f, + 0x1,0x46,0x69, 0x2,0x21,0x66, 0x1,0x45,0x5e, 0x3,0x22,0x5a, + 0x3,0x21,0x6b, 0x2,0x22,0x65, 0x3,0x24,0x2f, 0x4,0x23,0x2a, + 0xf,0x22,0x66, 0x2,0x24,0x6c, 0x2,0x24,0x6a, 0x2,0x24,0x6b, + 0x2,0x24,0x68, 0x1,0x4b,0x2b, 0x2,0x24,0x69, 0x3,0x26,0x6e, + 0x3,0x2a,0x33, 0x2,0x28,0x2f, 0x3,0x2a,0x2d, 0x1,0x4e,0x74, + 0x2,0x28,0x2d, 0x2,0x28,0x29, 0x2,0x28,0x2c, 0x3,0x2a,0x2c, + 0x2,0x28,0x28, 0x1,0x4e,0x76, 0x2,0x28,0x2b, 0x3,0x2a,0x2b, + 0x1,0x4e,0x73, 0x1,0x4e,0x72, 0x3,0x2a,0x32, 0x1,0x4e,0x75, + 0x2,0x28,0x2e, 0x2,0x28,0x2a, 0x3,0x2a,0x2f, 0x1,0x52,0x45, + 0x1,0x52,0x48, 0x2,0x2c,0x30, 0x2,0x2c,0x2f, 0x2,0x2c,0x2e, + 0x1,0x52,0x42, 0x2,0x2c,0x37, 0x2,0x2c,0x2d, 0x4,0x2e,0x2a, + 0x1,0x52,0x44, 0x2,0x30,0x70, 0x3,0x2d,0x78, 0x2,0x2c,0x34, + 0x2,0x2c,0x32, 0x1,0x52,0x47, 0x3,0x2d,0x7b, 0x2,0x2c,0x2a, + 0x2,0x2c,0x35, 0x3,0x2d,0x77, 0x2,0x2c,0x2c, 0x2,0x2c,0x36, + 0x2,0x2c,0x33, 0x2,0x2c,0x2b, 0x3,0x2d,0x7a, 0x1,0x52,0x43, + 0x2,0x2c,0x38, 0x2,0x2c,0x29, 0x1,0x52,0x46, 0x3,0x2d,0x7e, + 0x3,0x2d,0x79, 0x3,0x2d,0x7c, 0x2,0x30,0x75, 0x2,0x30,0x6c, + 0x2,0x30,0x77, 0x3,0x32,0x3e, 0x2,0x30,0x6f, 0x2,0x30,0x7a, + 0x2,0x30,0x7b, 0x2,0x30,0x6d, 0x2,0x30,0x79, 0x2,0x30,0x76, + 0x2,0x30,0x74, 0x2,0x30,0x78, 0x1,0x56,0x62, 0x3,0x32,0x40, + 0x1,0x56,0x60, 0x3,0x32,0x47, 0x3,0x32,0x3c, 0x2,0x30,0x72, + 0x3,0x32,0x46, 0x2,0x30,0x6e, 0x3,0x32,0x41, 0x2,0x30,0x71, + 0x2,0x30,0x7c, 0x2,0x30,0x73, 0x1,0x56,0x61, 0x2,0x2c,0x31, + 0x3,0x32,0x3d, 0x1,0x56,0x5d, 0x1,0x56,0x5f, 0x3,0x65,0x64, + 0x3,0x37,0x3d, 0x2,0x37,0x3d, 0x2,0x37,0x32, 0x2,0x37,0x30, + 0x3,0x3d,0x38, 0x2,0x37,0x31, 0x3,0x32,0x3f, 0x2,0x37,0x38, + 0x3,0x37,0x40, 0x2,0x37,0x39, 0x2,0x37,0x35, 0x1,0x5c,0x22, + 0x2,0x37,0x3a, 0x2,0x37,0x37, 0x2,0x37,0x34, 0x3,0x37,0x3c, + 0x1,0x5b,0x7e, 0x2,0x37,0x33, 0x1,0x5b,0x7c, 0x1,0x5c,0x21, + 0x2,0x37,0x36, 0x2,0x37,0x3e, 0x1,0x56,0x5e, 0x1,0x5b,0x7d, + 0x2,0x37,0x3c, 0x2,0x37,0x3b, 0x1,0x5c,0x23, 0x3,0x65,0x65, + 0xf,0x36,0x57, 0x3,0x3d,0x36, 0x3,0x3d,0x3a, 0x2,0x3e,0x24, + 0x3,0x3d,0x2f, 0x3,0x3d,0x3b, 0x3,0x3d,0x32, 0x2,0x3e,0x25, + 0x1,0x60,0x66, 0x3,0x3d,0x39, 0x2,0x3e,0x2b, 0x3,0x42,0x6d, + 0x3,0x3d,0x35, 0x2,0x3e,0x2d, 0x2,0x3e,0x26, 0x1,0x60,0x60, + 0x2,0x3e,0x2a, 0x2,0x3e,0x29, 0x1,0x60,0x61, 0x1,0x60,0x67, + 0x3,0x42,0x64, 0x1,0x60,0x68, 0x2,0x3e,0x2c, 0x1,0x60,0x5e, + 0x2,0x3e,0x23, 0x2,0x3e,0x21, 0x2,0x3e,0x27, 0x2,0x3d,0x7e, + 0x1,0x60,0x65, 0x2,0x3e,0x22, 0x2,0x3e,0x28, 0x2,0x3e,0x2e, + 0x1,0x60,0x5f, 0x1,0x60,0x64, 0x1,0x60,0x62, 0x1,0x60,0x63, + 0x3,0x3d,0x33, 0x3,0x3d,0x3c, 0x1,0x60,0x5d, 0x3,0x65,0x66, + 0x3,0x3d,0x37, 0x3,0x42,0x68, 0x3,0x42,0x75, 0x1,0x65,0x31, + 0x2,0x44,0x7b, 0x1,0x65,0x30, 0x2,0x45,0x21, 0x3,0x42,0x6f, + 0x2,0x44,0x75, 0x3,0x42,0x74, 0x2,0x45,0x22, 0x3,0x42,0x6e, + 0x3,0x42,0x66, 0x3,0x42,0x71, 0x2,0x44,0x76, 0x2,0x44,0x77, + 0x3,0x42,0x73, 0x2,0x45,0x23, 0x2,0x44,0x7e, 0x2,0x44,0x7c, + 0x2,0x44,0x7d, 0x2,0x44,0x79, 0x2,0x44,0x78, 0x3,0x42,0x67, + 0x2,0x45,0x24, 0x1,0x65,0x2d, 0x3,0x42,0x6b, 0x2,0x44,0x7a, + 0x3,0x42,0x70, 0x1,0x65,0x32, 0x1,0x65,0x2c, 0x1,0x65,0x33, + 0x1,0x65,0x34, 0x3,0x42,0x6a, 0x1,0x65,0x2f, 0x1,0x65,0x2e, + 0x3,0x48,0x25, 0x3,0x47,0x7e, 0x2,0x4b,0x74, 0x1,0x69,0x65, + 0x1,0x69,0x64, 0x3,0x47,0x7c, 0x3,0x47,0x7d, 0x2,0x4b,0x79, + 0x3,0x48,0x22, 0x1,0x6d,0x66, 0x1,0x69,0x66, 0x3,0x48,0x21, + 0x3,0x47,0x7b, 0x1,0x69,0x68, 0x2,0x4b,0x7a, 0x1,0x65,0x2b, + 0x1,0x69,0x67, 0x2,0x4b,0x76, 0x2,0x4b,0x78, 0x2,0x4b,0x75, + 0x3,0x48,0x27, 0x2,0x4b,0x77, 0x3,0x48,0x23, 0xf,0x49,0x76, + 0x2,0x52,0x33, 0x3,0x4d,0x31, 0x3,0x4d,0x3b, 0x2,0x52,0x32, + 0x2,0x52,0x2f, 0x1,0x6d,0x69, 0x2,0x58,0x4e, 0x1,0x6d,0x6a, + 0x2,0x52,0x2e, 0x3,0x4d,0x39, 0x1,0x6d,0x68, 0x3,0x4d,0x36, + 0x2,0x52,0x30, 0x2,0x52,0x2d, 0x2,0x52,0x2a, 0x2,0x52,0x31, + 0x2,0x52,0x2b, 0x2,0x52,0x2c, 0x1,0x6d,0x67, 0x3,0x4d,0x35, + 0x3,0x65,0x68, 0x4,0x51,0x39, 0x2,0x5d,0x55, 0x4,0x51,0x3a, + 0x2,0x58,0x52, 0x3,0x4d,0x3a, 0x2,0x58,0x51, 0x2,0x58,0x53, + 0x3,0x51,0x6a, 0x2,0x5d,0x52, 0x1,0x71,0x44, 0x4,0x51,0x38, + 0x2,0x58,0x4f, 0x3,0x51,0x67, 0x1,0x71,0x42, 0x3,0x51,0x6c, + 0x1,0x71,0x46, 0x1,0x71,0x45, 0x2,0x58,0x50, 0x2,0x58,0x54, + 0x3,0x51,0x6b, 0x1,0x71,0x43, 0x3,0x65,0x67, 0x2,0x5d,0x59, + 0x1,0x74,0x40, 0x1,0x76,0x66, 0x1,0x74,0x41, 0x1,0x74,0x3e, + 0x2,0x5d,0x56, 0x2,0x5d,0x54, 0x3,0x55,0x4f, 0x2,0x5d,0x57, + 0x3,0x55,0x4b, 0x2,0x5d,0x5a, 0x1,0x74,0x3f, 0x2,0x5d,0x58, + 0x2,0x5d,0x53, 0x3,0x55,0x4d, 0x3,0x65,0x69, 0x2,0x62,0x2f, + 0x2,0x62,0x32, 0x2,0x66,0x21, 0x2,0x62,0x2d, 0x3,0x58,0x2f, + 0x2,0x69,0x3e, 0x2,0x62,0x33, 0x3,0x58,0x30, 0x1,0x78,0x4d, + 0x2,0x62,0x31, 0x1,0x76,0x67, 0x2,0x62,0x2e, 0x2,0x62,0x30, + 0x2,0x62,0x34, 0x2,0x66,0x22, 0x3,0x5a,0x5a, 0x2,0x65,0x7e, + 0x4,0x60,0x27, 0x3,0x5a,0x5c, 0x3,0x5a,0x5d, 0x3,0x5a,0x5b, + 0x1,0x78,0x4e, 0x2,0x65,0x7d, 0x3,0x5c,0x5e, 0x3,0x5c,0x5c, + 0x3,0x5c,0x5f, 0x1,0x79,0x79, 0x3,0x5c,0x5d, 0x3,0x5c,0x60, + 0x3,0x5e,0x3d, 0x1,0x7a,0x78, 0x2,0x6d,0x5f, 0x1,0x7a,0x77, + 0x2,0x6d,0x61, 0x2,0x6d,0x5e, 0x2,0x6d,0x60, 0x1,0x7c,0x3c, + 0x2,0x70,0x40, 0x1,0x46,0x6a, 0x2,0x28,0x30, 0x2,0x30,0x7d, + 0x2,0x30,0x7e, 0x1,0x5c,0x24, 0x2,0x45,0x25, 0x1,0x71,0x47, + 0x1,0x78,0x4f, 0x1,0x7b,0x67, 0x2,0x70,0x41, 0x1,0x46,0x6b, + 0x2,0x28,0x31, 0x1,0x23,0x22, 0x4,0x2a,0x3c, 0x3,0x2e,0x22, + 0x2,0x2c,0x39, 0x3,0x2e,0x21, 0x2,0x2c,0x3a, 0x3,0x2e,0x24, + 0x3,0x32,0x48, 0x2,0x31,0x21, 0x2,0x31,0x22, 0x1,0x5c,0x25, + 0x1,0x5c,0x26, 0xf,0x36,0x67, 0x3,0x3d,0x3d, 0x4,0x39,0x25, + 0x2,0x3e,0x2f, 0x2,0x45,0x28, 0x2,0x45,0x27, 0x2,0x45,0x26, + 0x2,0x4b,0x7b, 0x3,0x42,0x77, 0x2,0x4b,0x7c, 0x2,0x4b,0x7d, + 0x1,0x69,0x69, 0x3,0x48,0x28, 0x2,0x52,0x35, 0x2,0x52,0x34, + 0x3,0x4d,0x3d, 0x3,0x51,0x6d, 0x2,0x58,0x55, 0x1,0x71,0x48, + 0x1,0x71,0x49, 0x3,0x51,0x6e, 0x2,0x5d,0x5e, 0x2,0x5d,0x5b, + 0x2,0x5d,0x5c, 0x2,0x5d,0x5d, 0x2,0x62,0x36, 0x2,0x62,0x35, + 0x1,0x76,0x68, 0x2,0x66,0x23, 0x2,0x6b,0x6c, 0x1,0x46,0x6c, + 0x1,0x52,0x49, 0x3,0x37,0x44, 0x1,0x5c,0x27, 0x2,0x45,0x29, + 0x3,0x42,0x78, 0x1,0x46,0x6d, 0x4,0x2a,0x40, 0x2,0x31,0x23, + 0x1,0x5c,0x28, 0x3,0x37,0x45, 0x3,0x3d,0x3e, 0x1,0x60,0x69, + 0x1,0x60,0x6a, 0x5,0x47,0x49, 0x1,0x46,0x6e, 0x1,0x46,0x6f, + 0x2,0x22,0x66, 0x1,0x4b,0x2d, 0x1,0x4b,0x2c, 0x1,0x52,0x4a, + 0x2,0x2c,0x3b, 0x2,0x3e,0x30, 0x1,0x46,0x70, 0x1,0x46,0x71, + 0x1,0x46,0x72, 0x1,0x46,0x73, 0x4,0x23,0x2b, 0x1,0x4b,0x2e, + 0x1,0x4b,0x2f, 0x2,0x24,0x6e, 0x2,0x24,0x6d, 0x3,0x2a,0x37, + 0x1,0x4e,0x77, 0x2,0x28,0x34, 0x2,0x28,0x32, 0x2,0x28,0x33, + 0x3,0x2a,0x38, 0x3,0x2a,0x35, 0x4,0x27,0x40, 0x3,0x2a,0x36, + 0x3,0x2e,0x27, 0x2,0x2c,0x3c, 0x2,0x2c,0x3d, 0x3,0x2e,0x25, + 0x3,0x2e,0x28, 0x1,0x52,0x4e, 0x1,0x52,0x4c, 0x3,0x2e,0x2a, + 0x1,0x52,0x4d, 0x1,0x52,0x4b, 0x3,0x2e,0x26, 0xf,0x2b,0x7a, + 0xf,0x2c,0x4a, 0x1,0x56,0x63, 0x3,0x32,0x4e, 0x3,0x32,0x4d, + 0x3,0x32,0x50, 0x3,0x32,0x4f, 0x1,0x56,0x67, 0x1,0x56,0x66, + 0x2,0x31,0x24, 0x1,0x56,0x65, 0x1,0x56,0x64, 0x3,0x32,0x51, + 0x2,0x31,0x25, 0x3,0x37,0x46, 0x1,0x5c,0x2b, 0x2,0x37,0x40, + 0x2,0x37,0x3f, 0x1,0x5c,0x29, 0x1,0x5c,0x2a, 0x3,0x37,0x49, + 0x3,0x37,0x47, 0x1,0x60,0x6c, 0x1,0x60,0x6b, 0x2,0x3e,0x32, + 0x3,0x3d,0x43, 0x3,0x3d,0x42, 0x2,0x3e,0x31, 0x1,0x5c,0x2c, + 0x3,0x3d,0x44, 0x4,0x39,0x2c, 0x4,0x3e,0x6b, 0x1,0x65,0x35, + 0x2,0x45,0x2b, 0x1,0x65,0x36, 0x2,0x45,0x2a, 0x3,0x42,0x7b, + 0x4,0x44,0x7c, 0x4,0x44,0x7b, 0x2,0x4b,0x7e, 0x2,0x52,0x36, + 0x1,0x6d,0x6b, 0x2,0x58,0x56, 0x3,0x51,0x70, 0x3,0x55,0x52, + 0x2,0x5d,0x5f, 0x4,0x5b,0x74, 0x1,0x78,0x51, 0x1,0x78,0x50, + 0x4,0x63,0x68, 0x3,0x5c,0x62, 0x1,0x7b,0x68, 0x1,0x46,0x74, + 0x2,0x28,0x35, 0x3,0x3d,0x45, 0x1,0x5c,0x2d, 0x2,0x4c,0x21, + 0x1,0x69,0x6a, 0x3,0x22,0x5b, 0x3,0x26,0x73, 0x2,0x24,0x6f, + 0x2,0x24,0x70, 0x2,0x28,0x36, 0x1,0x4e,0x79, 0x1,0x4e,0x7a, + 0x3,0x2a,0x3a, 0x4,0x27,0x43, 0x1,0x4e,0x78, 0x3,0x2a,0x3b, + 0x1,0x52,0x52, 0x1,0x52,0x53, 0x1,0x52,0x50, 0x1,0x52,0x51, + 0x3,0x2e,0x2b, 0x2,0x2c,0x3e, 0x3,0x2e,0x2f, 0x4,0x2a,0x4a, + 0x2,0x2c,0x3f, 0x1,0x52,0x4f, 0x2,0x31,0x26, 0x3,0x32,0x57, + 0x1,0x56,0x6b, 0x1,0x56,0x6c, 0x3,0x32,0x55, 0x1,0x5c,0x30, + 0x2,0x31,0x2c, 0x4,0x2e,0x40, 0x1,0x56,0x71, 0x1,0x56,0x6f, + 0x2,0x31,0x2d, 0x2,0x31,0x28, 0x1,0x56,0x6e, 0x1,0x56,0x6d, + 0x1,0x56,0x68, 0x2,0x31,0x2b, 0x2,0x31,0x2a, 0x2,0x31,0x27, + 0x1,0x56,0x70, 0x3,0x32,0x52, 0x2,0x31,0x29, 0x1,0x56,0x69, + 0x4,0x2e,0x34, 0x1,0x56,0x6a, 0x1,0x5c,0x31, 0x2,0x37,0x44, + 0x2,0x37,0x45, 0x1,0x5c,0x32, 0x2,0x37,0x41, 0x2,0x37,0x43, + 0x2,0x37,0x47, 0x2,0x37,0x46, 0x2,0x37,0x42, 0x3,0x37,0x4a, + 0x1,0x5c,0x2e, 0x1,0x5c,0x2f, 0x2,0x3e,0x3a, 0x1,0x60,0x71, + 0x1,0x60,0x70, 0x2,0x3e,0x34, 0x1,0x60,0x6e, 0x4,0x39,0x34, + 0x2,0x3e,0x37, 0x1,0x60,0x72, 0x2,0x3e,0x38, 0x1,0x60,0x73, + 0x2,0x3e,0x35, 0x1,0x60,0x6d, 0x1,0x60,0x6f, 0x2,0x3e,0x39, + 0x3,0x3d,0x47, 0x2,0x3e,0x36, 0x2,0x3e,0x33, 0x4,0x3e,0x77, + 0x2,0x45,0x38, 0x3,0x42,0x7c, 0x2,0x45,0x2d, 0x1,0x65,0x38, + 0x1,0x65,0x3b, 0x1,0x65,0x3a, 0x1,0x65,0x3f, 0x1,0x65,0x3e, + 0x2,0x45,0x39, 0x2,0x45,0x37, 0x2,0x45,0x30, 0x2,0x45,0x34, + 0x2,0x45,0x33, 0x1,0x65,0x3c, 0x2,0x45,0x36, 0x2,0x45,0x32, + 0x2,0x45,0x3a, 0x2,0x45,0x31, 0x1,0x65,0x3d, 0x1,0x65,0x37, + 0x1,0x65,0x39, 0x3,0x42,0x7d, 0x2,0x45,0x2f, 0x3,0x48,0x2b, + 0x2,0x4c,0x23, 0x1,0x69,0x6e, 0x2,0x4c,0x27, 0x1,0x69,0x6d, + 0x2,0x4c,0x24, 0x1,0x69,0x6c, 0x3,0x48,0x29, 0x2,0x45,0x2e, + 0x2,0x45,0x35, 0x2,0x4c,0x26, 0x4,0x44,0x7e, 0x1,0x69,0x6f, + 0x2,0x4c,0x28, 0x2,0x4c,0x25, 0x2,0x4c,0x22, 0x2,0x52,0x39, + 0x2,0x52,0x3d, 0x2,0x52,0x3f, 0x2,0x52,0x3b, 0x2,0x52,0x3a, + 0x2,0x52,0x38, 0x1,0x6d,0x6e, 0x1,0x6d,0x6c, 0x1,0x6d,0x71, + 0x1,0x6d,0x72, 0x2,0x52,0x3c, 0x1,0x6d,0x6f, 0x2,0x52,0x37, + 0x1,0x6d,0x70, 0x1,0x69,0x6b, 0x2,0x52,0x3e, 0x1,0x6d,0x6d, + 0x3,0x51,0x71, 0x2,0x58,0x58, 0x4,0x51,0x4f, 0x2,0x58,0x57, + 0x2,0x58,0x5f, 0x2,0x58,0x59, 0x2,0x58,0x5e, 0x2,0x58,0x5b, + 0x1,0x71,0x4a, 0x2,0x58,0x5d, 0x3,0x51,0x73, 0x3,0x51,0x72, + 0x1,0x71,0x4b, 0x4,0x51,0x4d, 0x1,0x71,0x4c, 0x3,0x51,0x74, + 0x2,0x58,0x5c, 0x2,0x58,0x5a, 0x4,0x57,0x21, 0x4,0x57,0x24, + 0x1,0x74,0x43, 0x2,0x5d,0x60, 0x3,0x55,0x55, 0x3,0x55,0x53, + 0x1,0x74,0x42, 0x2,0x5d,0x63, 0x2,0x5d,0x61, 0x2,0x5d,0x62, + 0x5,0x55,0x69, 0x5,0x5c,0x36, 0x1,0x74,0x44, 0x3,0x55,0x54, + 0x3,0x58,0x34, 0x2,0x62,0x3a, 0x3,0x58,0x33, 0x1,0x76,0x6b, + 0x2,0x62,0x3b, 0x4,0x5b,0x75, 0x4,0x5b,0x79, 0x1,0x76,0x69, + 0x2,0x62,0x3c, 0x1,0x76,0x6a, 0x2,0x62,0x39, 0x2,0x62,0x3d, + 0x3,0x58,0x32, 0x2,0x62,0x37, 0x1,0x78,0x52, 0x2,0x66,0x24, + 0x1,0x78,0x53, 0x1,0x79,0x7a, 0x2,0x62,0x38, 0x1,0x79,0x7b, + 0x3,0x5e,0x3f, 0x3,0x5e,0x3e, 0x1,0x7a,0x79, 0x2,0x6b,0x6d, + 0x1,0x7b,0x6a, 0x2,0x6d,0x62, 0x1,0x7b,0x69, 0x3,0x60,0x3b, + 0x2,0x6f,0x39, 0x1,0x7c,0x61, 0x1,0x7c,0x62, 0x3,0x65,0x6a, + 0x7,0x64,0x52, 0x2,0x72,0x3a, 0x3,0x22,0x5c, 0x3,0x65,0x6b, + 0x1,0x52,0x54, 0x2,0x2c,0x40, 0x1,0x60,0x74, 0x1,0x60,0x75, + 0x1,0x46,0x75, 0x1,0x48,0x4b, 0x2,0x22,0x67, 0x3,0x26,0x74, + 0x2,0x24,0x71, 0x1,0x4b,0x30, 0x3,0x26,0x76, 0x1,0x4e,0x7b, + 0x4,0x2a,0x4c, 0x1,0x52,0x55, 0x1,0x52,0x56, 0x1,0x52,0x57, + 0x2,0x37,0x49, 0x2,0x31,0x2e, 0x1,0x56,0x72, 0x4,0x2e,0x41, + 0x4,0x2e,0x43, 0x1,0x5c,0x33, 0x2,0x37,0x48, 0x3,0x37,0x4d, + 0x2,0x3e,0x3c, 0x1,0x60,0x77, 0x3,0x3d,0x4c, 0x2,0x3e,0x3b, + 0x1,0x60,0x76, 0x3,0x42,0x7e, 0x3,0x43,0x21, 0x2,0x45,0x3b, + 0x1,0x6d,0x73, 0x2,0x52,0x43, 0x2,0x52,0x40, 0x2,0x52,0x41, + 0x2,0x52,0x42, 0x4,0x51,0x54, 0x4,0x51,0x55, 0x3,0x51,0x76, + 0x5,0x5c,0x43, 0x3,0x55,0x56, 0x2,0x5d,0x64, 0x3,0x55,0x57, + 0x2,0x62,0x3e, 0x4,0x5b,0x7c, 0x4,0x5b,0x7d, 0x3,0x5a,0x5e, + 0x2,0x69,0x40, 0x2,0x69,0x3f, 0x4,0x66,0x5a, 0x2,0x6d,0x63, + 0x1,0x46,0x76, 0x2,0x28,0x37, 0x1,0x56,0x73, 0x3,0x3d,0x4d, + 0x1,0x60,0x78, 0x2,0x45,0x3c, 0x4,0x45,0x34, 0x3,0x48,0x30, + 0x2,0x4c,0x29, 0x3,0x48,0x2e, 0x1,0x6d,0x74, 0x2,0x58,0x60, + 0x3,0x65,0x6c, 0x2,0x62,0x3f, 0x2,0x69,0x41, 0x1,0x46,0x77, + 0x3,0x26,0x77, 0x3,0x26,0x78, 0x1,0x4e,0x7c, 0x1,0x52,0x5a, + 0x2,0x2c,0x41, 0x1,0x52,0x5b, 0x1,0x52,0x59, 0x3,0x2e,0x32, + 0x1,0x52,0x58, 0x2,0x31,0x2f, 0x1,0x56,0x74, 0x3,0x32,0x5a, + 0x3,0x32,0x5b, 0x1,0x56,0x75, 0x1,0x56,0x76, 0x1,0x5c,0x35, + 0x2,0x37,0x4a, 0x1,0x5c,0x34, 0x3,0x37,0x50, 0x3,0x37,0x52, + 0x3,0x37,0x51, 0xf,0x37,0x23, 0x3,0x3d,0x4f, 0x2,0x3e,0x3d, + 0x1,0x5c,0x36, 0x1,0x60,0x79, 0x2,0x45,0x3d, 0x1,0x65,0x40, + 0x1,0x65,0x41, 0x4,0x45,0x35, 0x1,0x69,0x70, 0x3,0x48,0x31, + 0x1,0x69,0x71, 0x1,0x6d,0x75, 0x1,0x71,0x4e, 0x2,0x58,0x61, + 0x1,0x71,0x4d, 0x4,0x57,0x2d, 0x2,0x5d,0x65, 0x1,0x74,0x45, + 0x3,0x58,0x35, 0x2,0x62,0x40, 0x2,0x69,0x42, 0x1,0x46,0x78, + 0x1,0x4b,0x31, 0x2,0x28,0x3a, 0x2,0x28,0x39, 0x1,0x4e,0x7d, + 0x2,0x28,0x38, 0x1,0x4e,0x7e, 0x2,0x28,0x3b, 0x4,0x2a,0x55, + 0x2,0x2c,0x47, 0x1,0x52,0x5e, 0x1,0x52,0x5d, 0x2,0x2c,0x49, + 0x2,0x2c,0x48, 0x1,0x52,0x62, 0x3,0x2e,0x35, 0x1,0x52,0x61, + 0x3,0x2e,0x33, 0x4,0x2a,0x59, 0x1,0x52,0x5c, 0x4,0x2a,0x5d, + 0x2,0x2c,0x43, 0x2,0x2c,0x44, 0x2,0x2c,0x45, 0x4,0x2a,0x52, + 0x1,0x52,0x63, 0x2,0x2c,0x42, 0x1,0x52,0x5f, 0x2,0x2c,0x46, + 0x1,0x52,0x60, 0x3,0x32,0x64, 0x3,0x32,0x5f, 0x2,0x31,0x32, + 0x2,0x31,0x36, 0x2,0x31,0x34, 0x2,0x31,0x33, 0x4,0x2e,0x55, + 0x2,0x31,0x37, 0x3,0x32,0x5e, 0x4,0x2e,0x4f, 0x3,0x32,0x68, + 0x2,0x31,0x38, 0x2,0x31,0x39, 0x2,0x31,0x31, 0x4,0x2e,0x51, + 0x2,0x31,0x30, 0x3,0x37,0x59, 0x1,0x56,0x78, 0x1,0x56,0x79, + 0x3,0x32,0x67, 0x2,0x31,0x3a, 0x2,0x31,0x35, 0x3,0x32,0x65, + 0x2,0x37,0x53, 0x3,0x37,0x55, 0x2,0x31,0x3b, 0x1,0x56,0x7a, + 0x1,0x56,0x77, 0x3,0x32,0x5c, 0x3,0x32,0x63, 0x2,0x37,0x4d, + 0x4,0x33,0x4f, 0x2,0x37,0x4c, 0x3,0x37,0x53, 0x2,0x37,0x4e, + 0x2,0x37,0x4f, 0x2,0x37,0x51, 0x2,0x37,0x50, 0x2,0x37,0x55, + 0x1,0x5c,0x3a, 0x1,0x5c,0x37, 0x1,0x5c,0x3b, 0x2,0x37,0x4b, + 0x1,0x5c,0x3c, 0x2,0x37,0x54, 0x1,0x5c,0x39, 0x2,0x37,0x52, + 0x1,0x5c,0x38, 0x3,0x32,0x62, 0x3,0x37,0x57, 0x4,0x33,0x56, + 0x3,0x3d,0x56, 0x3,0x3d,0x53, 0x2,0x3e,0x40, 0x2,0x3e,0x42, + 0x2,0x3e,0x3e, 0x2,0x3e,0x3f, 0x3,0x3d,0x51, 0x3,0x3d,0x52, + 0x2,0x3e,0x43, 0x2,0x3e,0x45, 0x2,0x3e,0x46, 0x2,0x3e,0x41, + 0x2,0x3e,0x44, 0x1,0x60,0x7a, 0x2,0x45,0x41, 0x3,0x43,0x27, + 0x2,0x45,0x46, 0x2,0x45,0x3e, 0x2,0x45,0x42, 0x4,0x3f,0x29, + 0x3,0x43,0x28, 0x2,0x45,0x47, 0x2,0x45,0x43, 0x1,0x65,0x42, + 0x1,0x65,0x4a, 0x3,0x43,0x25, 0x1,0x65,0x45, 0x2,0x45,0x3f, + 0x2,0x45,0x40, 0x1,0x69,0x75, 0x1,0x65,0x4d, 0x1,0x65,0x46, + 0x3,0x43,0x26, 0x1,0x65,0x4b, 0x1,0x65,0x44, 0x2,0x45,0x45, + 0x1,0x65,0x4c, 0x2,0x45,0x44, 0x1,0x65,0x48, 0x1,0x65,0x43, + 0x1,0x65,0x49, 0x2,0x45,0x48, 0x2,0x4c,0x2e, 0x2,0x4c,0x30, + 0x4,0x45,0x42, 0x3,0x48,0x39, 0x4,0x45,0x40, 0x4,0x45,0x3d, + 0x3,0x48,0x33, 0x3,0x48,0x36, 0x3,0x48,0x35, 0x3,0x48,0x34, + 0x3,0x48,0x38, 0x1,0x65,0x47, 0x3,0x48,0x3b, 0x3,0x48,0x3d, + 0x2,0x4c,0x2b, 0x1,0x69,0x73, 0x2,0x4c,0x31, 0x1,0x69,0x74, + 0x2,0x4c,0x2f, 0x2,0x4c,0x2a, 0x2,0x4c,0x2d, 0x2,0x4c,0x32, + 0x1,0x69,0x72, 0x2,0x4c,0x2c, 0x1,0x6d,0x77, 0x2,0x52,0x47, + 0x2,0x52,0x46, 0x3,0x4d,0x44, 0x1,0x6d,0x7a, 0x1,0x6d,0x78, + 0x2,0x52,0x44, 0x1,0x6d,0x76, 0x2,0x52,0x45, 0x3,0x4d,0x46, + 0x1,0x6d,0x79, 0x4,0x51,0x5f, 0x2,0x58,0x69, 0x3,0x51,0x7b, + 0x2,0x58,0x6b, 0x3,0x51,0x79, 0x2,0x58,0x6a, 0x2,0x58,0x62, + 0x2,0x58,0x66, 0x2,0x58,0x65, 0x2,0x58,0x63, 0x1,0x71,0x50, + 0x1,0x71,0x51, 0x1,0x71,0x4f, 0x2,0x58,0x64, 0x2,0x58,0x67, + 0x2,0x58,0x68, 0x3,0x55,0x59, 0x1,0x71,0x52, 0x3,0x55,0x58, + 0x1,0x74,0x4a, 0x2,0x5d,0x6d, 0x3,0x55,0x5b, 0x1,0x74,0x47, + 0x2,0x5d,0x67, 0x1,0x74,0x49, 0x1,0x74,0x4b, 0x4,0x51,0x61, + 0x3,0x55,0x5c, 0x1,0x74,0x48, 0x2,0x5d,0x6c, 0x2,0x5d,0x68, + 0x1,0x74,0x46, 0x2,0x5d,0x6b, 0x2,0x5d,0x66, 0x2,0x5d,0x6a, + 0x2,0x5d,0x69, 0x3,0x58,0x36, 0x3,0x58,0x38, 0x2,0x62,0x42, + 0x1,0x76,0x6e, 0x1,0x76,0x6f, 0x1,0x76,0x6c, 0x3,0x58,0x3b, + 0x1,0x76,0x6d, 0x3,0x58,0x3a, 0x3,0x58,0x39, 0x2,0x62,0x41, + 0x4,0x60,0x39, 0x2,0x66,0x27, 0x3,0x5a,0x60, 0x3,0x5a,0x5f, + 0x1,0x78,0x54, 0x2,0x66,0x25, 0x2,0x66,0x26, 0x2,0x69,0x43, + 0x2,0x69,0x46, 0x2,0x69,0x44, 0x2,0x69,0x45, 0x2,0x6b,0x6e, + 0x3,0x5e,0x42, 0x4,0x66,0x5e, 0x1,0x7a,0x7a, 0x2,0x6f,0x3a, + 0x2,0x70,0x42, 0x4,0x6b,0x74, 0x1,0x7c,0x63, 0x2,0x71,0x28, + 0x2,0x71,0x29, 0x1,0x7d,0x33, 0x1,0x46,0x79, 0x1,0x52,0x64, + 0x3,0x32,0x69, 0x2,0x3e,0x47, 0x3,0x3d,0x57, 0x2,0x45,0x49, + 0x4,0x6c,0x76, 0x1,0x46,0x7a, 0x1,0x4b,0x32, 0x4,0x27,0x52, + 0x1,0x4f,0x21, 0x3,0x2e,0x36, 0x2,0x2c,0x4a, 0x2,0x2c,0x4b, + 0x1,0x56,0x7b, 0x4,0x33,0x5b, 0x2,0x3e,0x48, 0x1,0x60,0x7b, + 0x1,0x65,0x4e, 0x1,0x74,0x4c, 0x2,0x5d,0x6e, 0x2,0x66,0x28, + 0x2,0x69,0x47, 0x1,0x46,0x7b, 0x3,0x26,0x7b, 0x3,0x26,0x7c, + 0xf,0x25,0x23, 0x2,0x28,0x41, 0x2,0x28,0x3c, 0x2,0x28,0x3e, + 0x2,0x28,0x40, 0x2,0x28,0x3f, 0x2,0x28,0x3d, 0x1,0x4f,0x22, + 0xf,0x28,0x34, 0x1,0x52,0x65, 0x2,0x2c,0x54, 0x3,0x2e,0x39, + 0x2,0x2c,0x4f, 0x2,0x2c,0x4c, 0x3,0x2e,0x3b, 0x3,0x2e,0x3e, + 0x2,0x2c,0x53, 0x3,0x2e,0x37, 0x3,0x2e,0x3a, 0x1,0x52,0x67, + 0x1,0x52,0x68, 0x2,0x2c,0x52, 0x2,0x2c,0x51, 0x2,0x2c,0x50, + 0x2,0x2c,0x4d, 0x2,0x2c,0x4e, 0x2,0x2c,0x55, 0x1,0x52,0x66, + 0x3,0x2e,0x3d, 0xf,0x2c,0x5c, 0x3,0x65,0x6d, 0x3,0x65,0x6e, + 0x1,0x57,0x21, 0x3,0x66,0x7c, 0x1,0x57,0x27, 0x1,0x57,0x26, + 0x2,0x31,0x44, 0x2,0x31,0x3e, 0x2,0x31,0x3c, 0x3,0x32,0x6c, + 0x1,0x57,0x24, 0x2,0x37,0x5c, 0x1,0x56,0x7d, 0x2,0x31,0x41, + 0x2,0x31,0x45, 0x2,0x31,0x47, 0x2,0x31,0x43, 0x2,0x31,0x3d, + 0x1,0x57,0x25, 0x2,0x31,0x42, 0x2,0x31,0x40, 0x1,0x56,0x7c, + 0x2,0x31,0x48, 0x1,0x57,0x28, 0x2,0x31,0x46, 0x1,0x57,0x22, + 0x2,0x31,0x3f, 0x3,0x32,0x6d, 0x1,0x57,0x23, 0x1,0x56,0x7e, + 0x3,0x65,0x6f, 0x3,0x37,0x62, 0x1,0x5c,0x3e, 0x4,0x33,0x5d, + 0x2,0x37,0x5d, 0x3,0x37,0x63, 0x3,0x37,0x5d, 0x2,0x37,0x56, + 0x2,0x37,0x58, 0x2,0x37,0x5a, 0x3,0x37,0x5f, 0x2,0x37,0x5b, + 0x2,0x37,0x59, 0x1,0x5c,0x3f, 0x3,0x37,0x61, 0x2,0x37,0x5e, + 0x3,0x37,0x60, 0x2,0x37,0x57, 0x3,0x65,0x70, 0x3,0x65,0x71, + 0x3,0x65,0x72, 0x2,0x3e,0x4c, 0x1,0x60,0x7c, 0x2,0x3e,0x54, + 0x3,0x3d,0x5c, 0x2,0x3e,0x49, 0x6,0x4c,0x2f, 0x2,0x3e,0x55, + 0x3,0x3d,0x59, 0x2,0x3e,0x4a, 0x2,0x3e,0x4b, 0x3,0x3d,0x5d, + 0x4,0x39,0x54, 0x2,0x3e,0x53, 0x2,0x3e,0x52, 0x2,0x3e,0x4f, + 0x1,0x5c,0x3d, 0x1,0x60,0x7d, 0x2,0x3e,0x4d, 0x2,0x3e,0x50, + 0x1,0x60,0x7e, 0x2,0x3e,0x51, 0x2,0x3e,0x4e, 0x3,0x3d,0x5a, + 0x3,0x43,0x31, 0x2,0x45,0x54, 0x3,0x43,0x2d, 0x2,0x45,0x58, + 0x1,0x65,0x55, 0x3,0x43,0x2e, 0x2,0x4c,0x38, 0x1,0x65,0x58, + 0x2,0x45,0x56, 0x3,0x43,0x37, 0x3,0x43,0x29, 0x2,0x45,0x53, + 0x2,0x45,0x4e, 0x2,0x45,0x50, 0x2,0x45,0x51, 0x2,0x45,0x4a, + 0x3,0x43,0x35, 0x1,0x65,0x54, 0x3,0x43,0x2b, 0x3,0x43,0x30, + 0x1,0x65,0x53, 0x3,0x43,0x34, 0x1,0x65,0x4f, 0x2,0x45,0x4d, + 0x3,0x43,0x2a, 0x1,0x65,0x56, 0x3,0x43,0x36, 0x1,0x65,0x57, + 0x2,0x45,0x4c, 0x2,0x45,0x4f, 0x2,0x45,0x57, 0x1,0x65,0x51, + 0x1,0x65,0x52, 0x2,0x45,0x55, 0x2,0x45,0x4b, 0xf,0x44,0x25, + 0x4,0x45,0x53, 0x2,0x4c,0x3a, 0x1,0x69,0x77, 0x2,0x4c,0x3c, + 0x2,0x45,0x52, 0x2,0x4c,0x3e, 0x1,0x69,0x7b, 0x2,0x4c,0x3f, + 0x2,0x4c,0x3b, 0x3,0x48,0x3e, 0x1,0x69,0x78, 0x2,0x4c,0x37, + 0x1,0x69,0x7a, 0x2,0x4c,0x34, 0x2,0x4c,0x39, 0x2,0x4c,0x3d, + 0x2,0x4c,0x36, 0x3,0x48,0x3f, 0x3,0x48,0x45, 0x1,0x65,0x50, + 0x3,0x48,0x44, 0x2,0x4c,0x33, 0x1,0x69,0x79, 0x2,0x4c,0x35, + 0x3,0x65,0x73, 0x3,0x48,0x40, 0xf,0x4a,0x3f, 0x1,0x6d,0x7d, + 0x2,0x52,0x49, 0x1,0x6e,0x23, 0x4,0x4b,0x59, 0x1,0x6e,0x21, + 0x4,0x4b,0x57, 0x3,0x4d,0x4a, 0x1,0x69,0x76, 0x3,0x4d,0x4d, + 0x2,0x52,0x50, 0x2,0x52,0x51, 0x1,0x6d,0x7c, 0x3,0x4d,0x48, + 0x3,0x4d,0x4c, 0x2,0x52,0x4f, 0x2,0x52,0x52, 0x1,0x6d,0x7e, + 0x1,0x6d,0x7b, 0x2,0x52,0x4b, 0x2,0x52,0x48, 0x2,0x52,0x4d, + 0x2,0x52,0x4a, 0x1,0x6e,0x24, 0x2,0x52,0x4c, 0x3,0x4d,0x4b, + 0x3,0x4d,0x49, 0x2,0x52,0x4e, 0x1,0x6e,0x22, 0x3,0x52,0x21, + 0x3,0x65,0x74, 0x1,0x71,0x54, 0x2,0x58,0x72, 0x3,0x52,0x24, + 0x2,0x58,0x6c, 0x2,0x58,0x70, 0x2,0x58,0x76, 0x2,0x58,0x77, + 0x2,0x58,0x73, 0x2,0x58,0x74, 0x2,0x58,0x71, 0x4,0x4b,0x5d, + 0x2,0x58,0x6e, 0x4,0x51,0x6e, 0x1,0x71,0x56, 0x1,0x71,0x53, + 0x2,0x58,0x6d, 0x2,0x58,0x6f, 0x3,0x52,0x22, 0x1,0x71,0x55, + 0x2,0x58,0x75, 0x3,0x65,0x75, 0x1,0x74,0x50, 0x3,0x55,0x60, + 0x3,0x55,0x62, 0x2,0x5d,0x75, 0x2,0x5d,0x6f, 0x1,0x74,0x4f, + 0x4,0x57,0x3e, 0x1,0x74,0x4d, 0x3,0x55,0x61, 0x2,0x5d,0x77, + 0x1,0x74,0x4e, 0x2,0x5d,0x72, 0x2,0x5d,0x73, 0x2,0x5d,0x70, + 0x2,0x5d,0x78, 0x2,0x5d,0x74, 0x4,0x57,0x40, 0x1,0x74,0x51, + 0x2,0x5d,0x71, 0x2,0x5d,0x79, 0x2,0x5d,0x76, 0x3,0x58,0x43, + 0x3,0x58,0x3e, 0x3,0x58,0x40, 0x2,0x62,0x46, 0x3,0x58,0x3f, + 0x3,0x58,0x3c, 0x2,0x62,0x43, 0x3,0x58,0x42, 0x1,0x76,0x70, + 0x4,0x5c,0x32, 0x2,0x62,0x47, 0x2,0x62,0x49, 0x2,0x62,0x48, + 0x2,0x62,0x44, 0x2,0x62,0x45, 0x3,0x58,0x44, 0x2,0x66,0x2d, + 0x3,0x5a,0x61, 0x1,0x78,0x55, 0x3,0x5a,0x62, 0x2,0x66,0x2a, + 0x2,0x66,0x2c, 0x2,0x66,0x29, 0x2,0x66,0x2e, 0x4,0x60,0x42, + 0x3,0x5a,0x63, 0x2,0x66,0x2b, 0x3,0x65,0x76, 0x2,0x69,0x49, + 0x2,0x69,0x4c, 0x2,0x69,0x48, 0x1,0x79,0x7c, 0x2,0x69,0x4a, + 0x2,0x69,0x4b, 0x2,0x69,0x4d, 0x1,0x79,0x7d, 0x1,0x7a,0x21, + 0x1,0x79,0x7e, 0x2,0x6b,0x6f, 0x3,0x5e,0x45, 0x2,0x6b,0x71, + 0x3,0x5e,0x43, 0x2,0x6b,0x70, 0x3,0x5e,0x44, 0x2,0x6d,0x64, + 0xf,0x6a,0x66, 0x3,0x60,0x3c, 0x2,0x70,0x43, 0x2,0x71,0x2a, + 0x1,0x46,0x7c, 0x3,0x24,0x33, 0x2,0x24,0x72, 0x1,0x4f,0x23, + 0x2,0x28,0x43, 0x1,0x4f,0x24, 0x1,0x4f,0x25, 0x2,0x28,0x42, + 0x2,0x2c,0x5a, 0x2,0x2c,0x59, 0x1,0x52,0x69, 0x1,0x52,0x6c, + 0x1,0x52,0x6b, 0x1,0x52,0x6a, 0x2,0x2c,0x56, 0x2,0x2c,0x58, + 0x2,0x2c,0x57, 0x3,0x65,0x77, 0x2,0x31,0x4b, 0x1,0x57,0x2a, + 0x2,0x31,0x4f, 0x2,0x31,0x4e, 0x2,0x31,0x4d, 0x2,0x31,0x49, + 0x1,0x57,0x29, 0x1,0x57,0x2d, 0x1,0x57,0x30, 0x3,0x32,0x6f, + 0x3,0x32,0x70, 0x1,0x57,0x31, 0x2,0x31,0x4a, 0x2,0x31,0x4c, + 0x1,0x57,0x2f, 0x1,0x57,0x2e, 0x1,0x57,0x2c, 0x1,0x57,0x2b, + 0x2,0x37,0x65, 0x3,0x32,0x72, 0x2,0x37,0x63, 0x2,0x37,0x5f, + 0x1,0x5c,0x40, 0x3,0x3d,0x5e, 0x2,0x37,0x60, 0x1,0x5c,0x41, + 0x2,0x37,0x61, 0x2,0x37,0x62, 0x2,0x37,0x64, 0x3,0x37,0x66, + 0x1,0x5c,0x42, 0x3,0x37,0x65, 0x2,0x3e,0x59, 0x3,0x3d,0x5f, + 0x2,0x3e,0x58, 0x2,0x3e,0x57, 0x2,0x3e,0x56, 0x3,0x3d,0x64, + 0x3,0x3d,0x62, 0x4,0x39,0x5a, 0x2,0x45,0x5c, 0x1,0x65,0x59, + 0x4,0x3f,0x46, 0x2,0x45,0x59, 0x2,0x45,0x5b, 0x3,0x43,0x38, + 0x1,0x65,0x5a, 0x3,0x43,0x3d, 0x1,0x65,0x5b, 0x2,0x45,0x5a, + 0x3,0x43,0x39, 0x3,0x3d,0x63, 0x3,0x65,0x78, 0x3,0x48,0x48, + 0x2,0x4c,0x48, 0x3,0x48,0x47, 0x2,0x4c,0x41, 0x2,0x4c,0x42, + 0x5,0x47,0x7e, 0x1,0x69,0x7e, 0x1,0x69,0x7c, 0x1,0x69,0x7d, + 0x2,0x4c,0x4a, 0x5,0x48,0x22, 0x2,0x4c,0x49, 0x2,0x4c,0x46, + 0x2,0x4c,0x45, 0x2,0x4c,0x44, 0x2,0x4c,0x43, 0x2,0x4c,0x47, + 0x2,0x4c,0x40, 0x3,0x65,0x79, 0x2,0x52,0x53, 0x2,0x52,0x58, + 0x2,0x52,0x56, 0x3,0x4d,0x50, 0x3,0x4d,0x51, 0x3,0x4d,0x4f, + 0x2,0x52,0x55, 0x2,0x52,0x54, 0x2,0x52,0x57, 0x3,0x65,0x7a, + 0x2,0x58,0x78, 0x3,0x52,0x26, 0x1,0x71,0x57, 0x1,0x74,0x52, + 0x2,0x5d,0x7b, 0x3,0x52,0x27, 0x1,0x74,0x53, 0x2,0x5d,0x7a, + 0x2,0x62,0x4b, 0x2,0x62,0x4a, 0x1,0x76,0x71, 0x3,0x58,0x45, + 0x2,0x66,0x2f, 0x1,0x78,0x56, 0x2,0x69,0x4e, 0x1,0x7b,0x6b, + 0x2,0x6d,0x65, 0x3,0x60,0x3d, 0x2,0x70,0x45, 0x2,0x70,0x44, + 0x2,0x21,0x67, 0x1,0x52,0x6d, 0x1,0x52,0x6e, 0x2,0x37,0x66, + 0x3,0x65,0x7b, 0x1,0x65,0x5d, 0x1,0x46,0x7d, 0x1,0x4b,0x35, + 0x1,0x4b,0x34, 0x1,0x4b,0x33, 0x4,0x24,0x68, 0x3,0x2a,0x3e, + 0x3,0x2a,0x3d, 0x2,0x28,0x44, 0x3,0x2a,0x3f, 0x3,0x2a,0x42, + 0x1,0x4f,0x27, 0x1,0x4f,0x26, 0x3,0x2a,0x44, 0x1,0x52,0x71, + 0x3,0x65,0x4c, 0x2,0x2c,0x5c, 0x2,0x2c,0x5f, 0x2,0x2c,0x5d, + 0x3,0x2e,0x42, 0x1,0x52,0x6f, 0x1,0x52,0x70, 0x3,0x2e,0x40, + 0x3,0x2e,0x41, 0x2,0x2c,0x5b, 0x2,0x2c,0x5e, 0x3,0x2e,0x43, + 0x1,0x57,0x38, 0x3,0x32,0x74, 0x3,0x32,0x73, 0x3,0x32,0x79, + 0x2,0x31,0x56, 0x2,0x31,0x58, 0x2,0x31,0x57, 0x1,0x57,0x35, + 0x2,0x31,0x52, 0x3,0x32,0x76, 0x3,0x32,0x7b, 0x1,0x57,0x33, + 0x1,0x57,0x32, 0x3,0x32,0x77, 0x1,0x57,0x36, 0x1,0x57,0x34, + 0x3,0x32,0x78, 0x1,0x57,0x37, 0x2,0x31,0x55, 0x2,0x31,0x50, + 0x2,0x31,0x51, 0x2,0x31,0x54, 0x2,0x31,0x53, 0x3,0x32,0x7c, + 0x3,0x37,0x69, 0x3,0x37,0x67, 0x3,0x37,0x6b, 0x3,0x37,0x6a, + 0x2,0x37,0x69, 0x2,0x37,0x6a, 0x2,0x37,0x68, 0x3,0x37,0x6c, + 0x2,0x37,0x67, 0x1,0x5c,0x43, 0xf,0x37,0x3f, 0x3,0x3d,0x65, + 0x1,0x61,0x25, 0x6,0x4c,0x48, 0x2,0x3e,0x5a, 0x2,0x3e,0x5c, + 0x2,0x3e,0x5e, 0x1,0x61,0x24, 0x6,0x4c,0x43, 0x3,0x3d,0x66, + 0x1,0x61,0x22, 0x3,0x3d,0x69, 0x2,0x3e,0x5b, 0x1,0x61,0x23, + 0x2,0x3e,0x5d, 0x1,0x61,0x21, 0x3,0x3d,0x68, 0x3,0x43,0x41, + 0x2,0x45,0x66, 0x2,0x45,0x5d, 0x2,0x45,0x60, 0x2,0x45,0x64, + 0x1,0x65,0x61, 0x2,0x45,0x62, 0x4,0x3f,0x50, 0x2,0x45,0x61, + 0x2,0x45,0x5e, 0x2,0x45,0x5f, 0x1,0x65,0x5f, 0x2,0x45,0x65, + 0x1,0x65,0x5e, 0x3,0x43,0x44, 0x1,0x65,0x63, 0x1,0x65,0x62, + 0x1,0x65,0x60, 0x4,0x3f,0x4a, 0x2,0x45,0x63, 0x3,0x65,0x24, + 0x2,0x4c,0x50, 0x4,0x45,0x5d, 0x2,0x4c,0x4f, 0x3,0x48,0x4b, + 0x3,0x48,0x4d, 0x2,0x4c,0x4b, 0x3,0x48,0x50, 0x3,0x48,0x4f, + 0x1,0x6a,0x21, 0x2,0x4c,0x4e, 0x2,0x4c,0x4d, 0x1,0x6a,0x22, + 0x3,0x48,0x52, 0xf,0x4a,0x64, 0x4,0x4b,0x63, 0x4,0x45,0x5e, + 0x4,0x4b,0x6b, 0x1,0x6e,0x29, 0x3,0x4d,0x55, 0x2,0x52,0x5a, + 0x3,0x4d,0x56, 0x1,0x6e,0x2a, 0x1,0x6e,0x26, 0x1,0x6e,0x28, + 0x3,0x4d,0x5a, 0x1,0x6e,0x25, 0x1,0x6e,0x27, 0x3,0x4d,0x53, + 0x3,0x4d,0x57, 0x2,0x58,0x79, 0x3,0x52,0x2a, 0x1,0x71,0x5a, + 0x2,0x58,0x7b, 0x2,0x58,0x7a, 0x3,0x55,0x64, 0x2,0x4c,0x4c, + 0x1,0x71,0x5c, 0x1,0x71,0x5b, 0x1,0x71,0x58, 0x1,0x71,0x59, + 0x3,0x52,0x2c, 0xf,0x5b,0x59, 0x3,0x52,0x29, 0x2,0x5e,0x22, + 0x4,0x57,0x49, 0x2,0x5d,0x7e, 0x1,0x74,0x54, 0x2,0x5e,0x21, + 0x4,0x57,0x48, 0x2,0x5e,0x23, 0x2,0x5d,0x7d, 0x2,0x5d,0x7c, + 0x2,0x62,0x4c, 0x1,0x76,0x74, 0x1,0x76,0x72, 0x1,0x76,0x73, + 0x3,0x5a,0x66, 0x4,0x60,0x45, 0x3,0x5a,0x65, 0x2,0x66,0x30, + 0x2,0x66,0x31, 0x1,0x78,0x58, 0x3,0x5a,0x67, 0x1,0x78,0x57, + 0x2,0x69,0x50, 0x2,0x69,0x51, 0x2,0x69,0x4f, 0x3,0x5c,0x64, + 0x2,0x6d,0x66, 0x2,0x6d,0x67, 0x3,0x60,0x76, 0x3,0x60,0x77, + 0x1,0x46,0x7e, 0x2,0x22,0x68, 0x1,0x4b,0x36, 0x2,0x28,0x45, + 0x1,0x4f,0x29, 0x1,0x4f,0x28, 0x2,0x28,0x46, 0x3,0x2e,0x44, + 0x3,0x2e,0x47, 0x2,0x2c,0x61, 0x1,0x52,0x72, 0x2,0x2c,0x60, + 0x1,0x52,0x73, 0x3,0x2e,0x49, 0x3,0x2e,0x48, 0x1,0x57,0x39, + 0x2,0x31,0x5b, 0x2,0x31,0x59, 0x2,0x31,0x5f, 0x1,0x57,0x3a, + 0x2,0x31,0x5a, 0x2,0x31,0x5e, 0x2,0x31,0x5c, 0x2,0x31,0x5d, + 0x2,0x37,0x6b, 0x2,0x37,0x6d, 0x3,0x37,0x72, 0x1,0x5c,0x44, + 0x3,0x37,0x71, 0x2,0x37,0x6c, 0x1,0x5c,0x45, 0x1,0x61,0x28, + 0x1,0x61,0x27, 0x1,0x61,0x26, 0x2,0x3e,0x5f, 0x3,0x37,0x70, + 0x4,0x39,0x65, 0x2,0x45,0x69, 0x1,0x65,0x64, 0x1,0x65,0x65, + 0x3,0x43,0x46, 0x2,0x45,0x68, 0x2,0x45,0x67, 0x3,0x43,0x47, + 0x3,0x65,0x7c, 0x2,0x4c,0x51, 0x1,0x6a,0x24, 0x1,0x6a,0x23, + 0x2,0x4c,0x52, 0x2,0x4c,0x53, 0x1,0x6e,0x2c, 0x1,0x6e,0x2b, + 0x3,0x4d,0x5b, 0x2,0x59,0x21, 0x2,0x52,0x5b, 0x2,0x52,0x5d, + 0x2,0x52,0x5c, 0x2,0x58,0x7e, 0x2,0x58,0x7c, 0x2,0x59,0x22, + 0x2,0x58,0x7d, 0x5,0x56,0x52, 0x1,0x71,0x5d, 0x3,0x52,0x2f, + 0x4,0x52,0x27, 0x3,0x52,0x2e, 0x2,0x5e,0x24, 0x1,0x74,0x55, + 0x2,0x5e,0x25, 0x2,0x5e,0x26, 0x3,0x55,0x68, 0x1,0x76,0x75, + 0x1,0x76,0x76, 0x4,0x60,0x4b, 0x1,0x7a,0x22, 0x3,0x5e,0x49, + 0x3,0x5e,0x48, 0x1,0x7c,0x3d, 0x1,0x47,0x21, 0x3,0x26,0x7e, + 0x3,0x27,0x21, 0x4,0x27,0x5b, 0x3,0x2a,0x47, 0x3,0x2e,0x4e, + 0x2,0x2c,0x62, 0x3,0x2e,0x4f, 0x3,0x2e,0x4d, 0x3,0x2e,0x4b, + 0x3,0x2e,0x4c, 0xf,0x2c,0x76, 0x2,0x31,0x60, 0x1,0x57,0x3b, + 0x3,0x33,0x23, 0x3,0x33,0x26, 0x3,0x33,0x27, 0x3,0x33,0x24, + 0x1,0x5d,0x7e, 0x1,0x5d,0x7d, 0x3,0x37,0x73, 0x3,0x3d,0x71, + 0x1,0x61,0x2a, 0x2,0x3e,0x61, 0x1,0x61,0x29, 0x2,0x3e,0x60, + 0x3,0x3d,0x70, 0x4,0x3f,0x57, 0x3,0x43,0x49, 0x3,0x43,0x4a, + 0x2,0x45,0x6a, 0x3,0x48,0x54, 0x1,0x6a,0x25, 0x2,0x4c,0x54, + 0x1,0x6a,0x26, 0x3,0x48,0x55, 0x3,0x52,0x30, 0x3,0x55,0x69, + 0x3,0x55,0x6a, 0x4,0x57,0x50, 0x3,0x58,0x49, 0x1,0x7a,0x23, + 0x2,0x69,0x52, 0x3,0x5f,0x55, 0x1,0x48,0x4c, 0x1,0x4f,0x2a, + 0x2,0x28,0x47, 0x3,0x2e,0x51, 0x1,0x52,0x75, 0x3,0x2e,0x50, + 0x1,0x52,0x74, 0x2,0x2c,0x63, 0x2,0x2c,0x64, 0x2,0x31,0x62, + 0x2,0x31,0x64, 0x1,0x57,0x3c, 0x2,0x31,0x66, 0x2,0x31,0x69, + 0x2,0x31,0x67, 0x3,0x33,0x2b, 0x4,0x2e,0x71, 0x3,0x33,0x2a, + 0x2,0x31,0x68, 0x2,0x31,0x65, 0x2,0x31,0x61, 0x1,0x57,0x3d, + 0x2,0x31,0x6a, 0x2,0x31,0x63, 0x3,0x33,0x2c, 0x3,0x37,0x78, + 0x3,0x37,0x79, 0x2,0x37,0x76, 0x1,0x5c,0x4b, 0x2,0x38,0x21, + 0x1,0x5c,0x48, 0x3,0x37,0x77, 0x2,0x37,0x78, 0x1,0x5c,0x4c, + 0x3,0x37,0x7b, 0x1,0x5c,0x46, 0x3,0x37,0x76, 0x2,0x37,0x73, + 0x2,0x38,0x22, 0x2,0x37,0x74, 0x2,0x37,0x71, 0x1,0x5c,0x4a, + 0x4,0x33,0x7c, 0x1,0x5c,0x47, 0x4,0x33,0x7a, 0x2,0x37,0x77, + 0x2,0x37,0x7a, 0x1,0x5c,0x49, 0x2,0x37,0x7b, 0x1,0x5c,0x4d, + 0x2,0x37,0x7c, 0x2,0x37,0x72, 0x2,0x37,0x79, 0x2,0x37,0x7d, + 0x2,0x37,0x75, 0x2,0x37,0x70, 0x2,0x37,0x6e, 0x3,0x37,0x7a, + 0x3,0x65,0x7d, 0x2,0x37,0x7e, 0xf,0x37,0x4d, 0x2,0x37,0x6f, + 0xf,0x36,0x7e, 0x5,0x3b,0x24, 0x2,0x3e,0x68, 0x3,0x3d,0x7b, + 0x3,0x3d,0x78, 0x3,0x3d,0x75, 0x2,0x3e,0x64, 0x2,0x3e,0x6a, + 0x1,0x61,0x2d, 0x2,0x3e,0x63, 0x2,0x3e,0x65, 0x1,0x61,0x2b, + 0x2,0x3e,0x62, 0x1,0x61,0x32, 0x2,0x3e,0x66, 0x1,0x61,0x31, + 0x2,0x3e,0x67, 0x1,0x61,0x33, 0x1,0x61,0x2e, 0x1,0x61,0x34, + 0x1,0x61,0x2f, 0x3,0x3d,0x79, 0x1,0x61,0x30, 0x3,0x3d,0x72, + 0x1,0x61,0x2c, 0x3,0x3d,0x76, 0x2,0x3e,0x69, 0x3,0x65,0x7e, + 0x3,0x43,0x4f, 0x4,0x3f,0x67, 0x1,0x65,0x68, 0x2,0x45,0x75, + 0x3,0x43,0x4c, 0x2,0x45,0x78, 0x2,0x45,0x6c, 0x2,0x45,0x71, + 0x2,0x45,0x6b, 0x1,0x65,0x6a, 0x3,0x43,0x55, 0x2,0x45,0x6f, + 0x4,0x3f,0x5e, 0x3,0x43,0x4d, 0x3,0x3d,0x77, 0x2,0x45,0x6d, + 0x1,0x65,0x69, 0x3,0x43,0x54, 0x2,0x45,0x74, 0x2,0x45,0x73, + 0x2,0x45,0x70, 0x2,0x45,0x72, 0x2,0x45,0x6e, 0x1,0x6a,0x2a, + 0x2,0x45,0x77, 0x1,0x65,0x66, 0x2,0x45,0x76, 0x3,0x43,0x51, + 0xf,0x44,0x45, 0x3,0x48,0x56, 0x2,0x4c,0x64, 0x3,0x48,0x58, + 0x1,0x6a,0x31, 0x2,0x4c,0x5f, 0x3,0x48,0x60, 0x1,0x6a,0x30, + 0x2,0x4c,0x55, 0x4,0x45,0x6b, 0x2,0x4c,0x57, 0x1,0x6a,0x29, + 0x2,0x4c,0x5c, 0x2,0x4c,0x5b, 0x2,0x4c,0x5e, 0x1,0x6a,0x2e, + 0x2,0x4c,0x59, 0x2,0x4c,0x58, 0x3,0x48,0x5a, 0x3,0x48,0x5e, + 0x1,0x6a,0x2d, 0x1,0x6a,0x28, 0x2,0x4c,0x5a, 0x1,0x6a,0x2b, + 0x2,0x4c,0x60, 0x2,0x4c,0x62, 0x2,0x4c,0x5d, 0x2,0x4c,0x56, + 0x1,0x6a,0x2c, 0x3,0x48,0x57, 0x3,0x48,0x5d, 0x1,0x6e,0x34, + 0x1,0x6a,0x27, 0x4,0x45,0x64, 0x3,0x48,0x5c, 0x2,0x4c,0x63, + 0x4,0x45,0x70, 0x2,0x52,0x61, 0x1,0x6e,0x2d, 0x3,0x4d,0x5c, + 0x2,0x52,0x63, 0x4,0x4c,0x2b, 0x1,0x6e,0x2e, 0x3,0x4d,0x65, + 0x3,0x4d,0x5d, 0x1,0x6e,0x30, 0x2,0x52,0x66, 0x4,0x4b,0x7a, + 0x2,0x52,0x5e, 0x1,0x6a,0x2f, 0x2,0x52,0x64, 0x4,0x4b,0x73, + 0x4,0x4c,0x31, 0x4,0x4b,0x74, 0x4,0x4c,0x2a, 0x2,0x52,0x60, + 0x3,0x4d,0x60, 0x1,0x65,0x67, 0x1,0x6e,0x33, 0x4,0x4c,0x21, + 0x4,0x4b,0x78, 0x1,0x6e,0x2f, 0x4,0x4c,0x26, 0x1,0x6e,0x31, + 0x1,0x6e,0x32, 0x4,0x4b,0x76, 0x1,0x71,0x60, 0x2,0x52,0x65, + 0x2,0x52,0x5f, 0x1,0x6e,0x35, 0x3,0x4d,0x63, 0x2,0x52,0x62, + 0x3,0x66,0x21, 0x2,0x59,0x2c, 0x2,0x59,0x27, 0x4,0x52,0x2d, + 0x5,0x56,0x69, 0x2,0x59,0x31, 0x1,0x71,0x5e, 0x2,0x59,0x29, + 0x1,0x71,0x62, 0x2,0x59,0x2f, 0x2,0x59,0x26, 0x2,0x59,0x23, + 0x2,0x59,0x32, 0x1,0x74,0x5b, 0x1,0x71,0x63, 0x2,0x59,0x2e, + 0x2,0x59,0x24, 0x1,0x71,0x61, 0x2,0x59,0x28, 0x1,0x71,0x65, + 0x2,0x59,0x25, 0x2,0x59,0x2a, 0x1,0x71,0x64, 0x2,0x59,0x2d, + 0x2,0x59,0x30, 0x3,0x52,0x33, 0x3,0x52,0x34, 0x2,0x5e,0x38, + 0x2,0x5e,0x39, 0x2,0x5e,0x29, 0x2,0x5e,0x30, 0x2,0x5e,0x2e, + 0x4,0x57,0x5f, 0x3,0x55,0x6d, 0x1,0x74,0x59, 0x2,0x5e,0x35, + 0x2,0x59,0x2b, 0x3,0x55,0x6b, 0x2,0x5e,0x2c, 0x3,0x55,0x6e, + 0x2,0x5e,0x36, 0x1,0x74,0x58, 0x2,0x5e,0x2b, 0x2,0x5e,0x2a, + 0x2,0x5e,0x34, 0x2,0x5e,0x31, 0x2,0x5e,0x33, 0x4,0x57,0x54, + 0x2,0x5e,0x27, 0x2,0x5e,0x37, 0x1,0x74,0x56, 0x3,0x55,0x70, + 0x2,0x5e,0x32, 0x2,0x5e,0x3b, 0x2,0x5e,0x2f, 0x1,0x74,0x5a, + 0x1,0x74,0x57, 0x2,0x5e,0x2d, 0x2,0x5e,0x28, 0x2,0x5e,0x3a, + 0x1,0x71,0x5f, 0x3,0x55,0x71, 0xf,0x5b,0x5f, 0x4,0x57,0x57, + 0x3,0x55,0x6f, 0x2,0x62,0x4f, 0x3,0x58,0x50, 0x3,0x58,0x4e, + 0x2,0x62,0x4d, 0x2,0x62,0x53, 0x1,0x76,0x7a, 0x2,0x62,0x51, + 0x2,0x62,0x50, 0x1,0x76,0x7c, 0x2,0x62,0x56, 0x1,0x76,0x7b, + 0x3,0x58,0x51, 0x2,0x62,0x57, 0x2,0x62,0x54, 0x1,0x76,0x78, + 0x2,0x62,0x55, 0x2,0x62,0x4e, 0x1,0x76,0x79, 0x1,0x76,0x77, + 0x2,0x66,0x35, 0x2,0x62,0x52, 0x3,0x58,0x4c, 0x3,0x66,0x22, + 0x2,0x62,0x58, 0x3,0x66,0x23, 0x2,0x66,0x32, 0x3,0x5a,0x6f, + 0x3,0x5a,0x6e, 0x4,0x60,0x4e, 0x1,0x78,0x5d, 0x1,0x78,0x5b, + 0x2,0x66,0x34, 0x4,0x60,0x4c, 0x2,0x66,0x36, 0x2,0x66,0x33, + 0x1,0x78,0x5c, 0x1,0x78,0x59, 0x1,0x78,0x5a, 0x1,0x78,0x5e, + 0x3,0x66,0x24, 0x1,0x7a,0x25, 0x3,0x5c,0x66, 0x2,0x69,0x57, + 0x5,0x6c,0x79, 0x2,0x69,0x56, 0x2,0x69,0x54, 0x2,0x69,0x53, + 0x2,0x69,0x55, 0x3,0x5c,0x65, 0x1,0x7a,0x24, 0x1,0x7a,0x26, + 0x3,0x66,0x25, 0xf,0x65,0x67, 0x1,0x7a,0x7b, 0x3,0x5e,0x4c, + 0x4,0x66,0x6f, 0x2,0x6b,0x73, 0x2,0x6b,0x72, 0x3,0x5c,0x67, + 0x3,0x5e,0x4b, 0x2,0x6d,0x68, 0x3,0x5f,0x58, 0x2,0x6d,0x6a, + 0x2,0x6d,0x6c, 0x2,0x6d,0x6b, 0x2,0x6d,0x69, 0x3,0x5f,0x57, + 0x3,0x60,0x3f, 0x1,0x7b,0x6d, 0x1,0x7b,0x6c, 0x3,0x60,0x3e, + 0x1,0x7c,0x3f, 0x1,0x7c,0x3e, 0x1,0x7c,0x40, 0x2,0x6f,0x3c, + 0x2,0x6f,0x3b, 0x3,0x66,0x26, 0x2,0x71,0x2b, 0x2,0x70,0x46, + 0x2,0x71,0x2c, 0x1,0x7d,0x25, 0x3,0x61,0x44, 0x1,0x7d,0x26, + 0x2,0x71,0x5c, 0x4,0x6d,0x5b, 0x3,0x62,0x3a, 0x1,0x7d,0x4b, + 0x1,0x48,0x4d, 0x3,0x2a,0x49, 0x2,0x28,0x48, 0x3,0x2a,0x48, + 0x3,0x2e,0x52, 0x2,0x2c,0x66, 0x2,0x2c,0x67, 0x2,0x2c,0x65, + 0x3,0x2e,0x54, 0x3,0x2e,0x53, 0x1,0x52,0x76, 0xf,0x2d,0x21, + 0x2,0x2c,0x68, 0x2,0x2c,0x69, 0x2,0x2c,0x6a, 0x3,0x33,0x31, + 0x2,0x31,0x6b, 0x2,0x31,0x71, 0x3,0x33,0x2e, 0x3,0x33,0x30, + 0x2,0x31,0x6f, 0x1,0x57,0x3e, 0x2,0x31,0x6d, 0x3,0x33,0x32, + 0x2,0x31,0x6e, 0x2,0x31,0x70, 0x3,0x33,0x2d, 0x2,0x31,0x6c, + 0x1,0x5c,0x4e, 0x3,0x37,0x7d, 0x2,0x38,0x23, 0x1,0x5c,0x50, + 0x2,0x38,0x25, 0x1,0x5c,0x4f, 0x2,0x38,0x24, 0x3,0x37,0x7e, + 0x3,0x38,0x21, 0x3,0x38,0x3e, 0x3,0x38,0x22, 0x4,0x34,0x22, + 0x2,0x3e,0x6c, 0x1,0x61,0x35, 0x3,0x3e,0x21, 0x2,0x3e,0x6e, + 0x2,0x3e,0x6b, 0x2,0x38,0x26, 0x3,0x3e,0x23, 0x1,0x61,0x36, + 0x3,0x3e,0x22, 0x3,0x3d,0x7e, 0x2,0x3e,0x6d, 0x3,0x66,0x27, + 0xf,0x3e,0x21, 0xf,0x3e,0x23, 0x3,0x43,0x58, 0x2,0x45,0x7b, + 0x3,0x43,0x5c, 0x1,0x65,0x6b, 0x2,0x45,0x79, 0x1,0x65,0x6c, + 0x2,0x45,0x7a, 0x1,0x65,0x6d, 0x4,0x45,0x74, 0x3,0x48,0x62, + 0x3,0x48,0x61, 0x1,0x6a,0x32, 0x2,0x4c,0x68, 0x2,0x4c,0x65, + 0x2,0x4c,0x67, 0x1,0x6a,0x33, 0x1,0x6a,0x34, 0x2,0x4c,0x66, + 0xf,0x4b,0x27, 0xf,0x4b,0x2b, 0x3,0x4d,0x6f, 0x3,0x4d,0x71, + 0x3,0x4d,0x6d, 0x2,0x52,0x67, 0x3,0x4d,0x70, 0x3,0x4d,0x73, + 0x2,0x52,0x68, 0x3,0x4d,0x72, 0x1,0x6e,0x36, 0x2,0x52,0x6a, + 0x2,0x52,0x69, 0x3,0x4d,0x6e, 0x1,0x23,0x23, 0x4,0x52,0x44, + 0x2,0x59,0x36, 0x2,0x59,0x37, 0x2,0x59,0x33, 0x3,0x52,0x37, + 0x2,0x59,0x34, 0x1,0x71,0x66, 0x1,0x71,0x67, 0x2,0x59,0x35, + 0x1,0x74,0x61, 0x3,0x55,0x75, 0x3,0x55,0x74, 0x1,0x74,0x5d, + 0x1,0x74,0x62, 0x1,0x74,0x5e, 0x1,0x74,0x60, 0x1,0x74,0x5c, + 0x3,0x52,0x39, 0x1,0x74,0x5f, 0x3,0x58,0x55, 0x4,0x5c,0x5a, + 0x4,0x5c,0x5b, 0x3,0x58,0x54, 0x1,0x76,0x7d, 0x2,0x5e,0x3c, + 0x7,0x48,0x57, 0x2,0x66,0x38, 0x4,0x60,0x5a, 0x2,0x66,0x37, + 0x3,0x66,0x28, 0x2,0x69,0x58, 0x1,0x7a,0x27, 0x1,0x7a,0x28, + 0x2,0x6d,0x6e, 0x2,0x6b,0x74, 0x3,0x61,0x69, 0x2,0x6d,0x6d, + 0x3,0x60,0x40, 0x2,0x71,0x2d, 0x2,0x71,0x72, 0x1,0x48,0x4e, + 0x3,0x27,0x22, 0x1,0x4b,0x37, 0x3,0x2a,0x4b, 0x2,0x28,0x49, + 0x1,0x4f,0x2b, 0x3,0x2a,0x4a, 0x1,0x52,0x79, 0x2,0x2c,0x6d, + 0x1,0x52,0x77, 0x2,0x2c,0x6b, 0x1,0x52,0x7c, 0x1,0x52,0x78, + 0x1,0x52,0x7d, 0x1,0x52,0x7b, 0x2,0x2c,0x6c, 0x1,0x52,0x7a, + 0x1,0x57,0x42, 0x1,0x57,0x41, 0x2,0x31,0x7c, 0x1,0x57,0x4a, + 0x2,0x31,0x75, 0x2,0x31,0x7b, 0x1,0x57,0x46, 0x2,0x31,0x74, + 0x2,0x31,0x7a, 0x2,0x31,0x78, 0x1,0x57,0x45, 0x1,0x57,0x47, + 0x2,0x31,0x77, 0x1,0x57,0x40, 0x2,0x31,0x76, 0x1,0x57,0x4b, + 0x1,0x57,0x48, 0x1,0x57,0x4c, 0x1,0x57,0x49, 0x2,0x31,0x73, + 0x2,0x31,0x72, 0x2,0x31,0x79, 0x1,0x57,0x43, 0x1,0x57,0x3f, + 0x1,0x57,0x44, 0x4,0x2f,0x25, 0x3,0x33,0x37, 0x3,0x33,0x3b, + 0x2,0x38,0x35, 0x2,0x38,0x2e, 0x4,0x3a,0x26, 0x1,0x61,0x3b, + 0x2,0x38,0x2d, 0x3,0x38,0x29, 0x1,0x5c,0x54, 0x1,0x5c,0x5b, + 0x1,0x5c,0x58, 0x1,0x5c,0x5e, 0x1,0x5c,0x5d, 0x1,0x5c,0x59, + 0x3,0x38,0x26, 0x2,0x38,0x27, 0x2,0x38,0x2a, 0x3,0x38,0x27, + 0x2,0x38,0x29, 0x1,0x5c,0x55, 0x2,0x38,0x2b, 0x2,0x38,0x34, + 0x1,0x5c,0x56, 0x2,0x38,0x28, 0x2,0x38,0x31, 0x2,0x38,0x32, + 0x1,0x5c,0x57, 0x2,0x38,0x2f, 0x1,0x5c,0x5c, 0x1,0x5c,0x52, + 0x1,0x5c,0x5a, 0x2,0x38,0x2c, 0x1,0x5c,0x51, 0x2,0x38,0x30, + 0x3,0x38,0x2e, 0x3,0x38,0x24, 0x2,0x38,0x33, 0xf,0x37,0x54, + 0x3,0x38,0x2b, 0x3,0x3e,0x34, 0x2,0x3f,0x21, 0x2,0x3e,0x76, + 0x1,0x61,0x38, 0x2,0x3e,0x7d, 0x2,0x3e,0x7a, 0x2,0x3e,0x72, + 0x2,0x3e,0x7b, 0x1,0x61,0x3a, 0x2,0x3e,0x73, 0x3,0x3e,0x29, + 0x2,0x3e,0x6f, 0x3,0x3e,0x26, 0x3,0x3e,0x2e, 0x1,0x65,0x73, + 0x2,0x3e,0x78, 0x3,0x3e,0x2f, 0x1,0x61,0x37, 0x2,0x3e,0x7e, + 0x3,0x3e,0x28, 0x1,0x61,0x3e, 0x1,0x61,0x40, 0x2,0x3e,0x71, + 0x3,0x3e,0x2c, 0x4,0x3a,0x27, 0x1,0x61,0x3f, 0x2,0x3e,0x74, + 0x1,0x61,0x39, 0x2,0x3e,0x7c, 0x2,0x3e,0x75, 0x2,0x3e,0x79, + 0x3,0x3e,0x2a, 0x2,0x3e,0x77, 0x1,0x61,0x3c, 0x2,0x3e,0x70, + 0x1,0x61,0x41, 0x1,0x5c,0x53, 0x1,0x61,0x3d, 0x1,0x61,0x42, + 0x3,0x3e,0x24, 0x3,0x3e,0x35, 0x3,0x3e,0x33, 0x3,0x43,0x67, + 0x1,0x65,0x6f, 0x2,0x46,0x24, 0x2,0x46,0x26, 0x2,0x46,0x28, + 0x2,0x46,0x2c, 0x3,0x3e,0x2b, 0x2,0x46,0x22, 0x2,0x45,0x7e, + 0x1,0x65,0x71, 0x4,0x3f,0x71, 0x2,0x46,0x27, 0x2,0x46,0x2b, + 0x2,0x46,0x23, 0x2,0x45,0x7d, 0x3,0x43,0x66, 0x2,0x45,0x7c, + 0x3,0x43,0x69, 0x3,0x43,0x60, 0x3,0x43,0x62, 0x2,0x46,0x29, + 0x2,0x46,0x21, 0x2,0x46,0x25, 0x1,0x65,0x72, 0x3,0x43,0x5e, + 0x1,0x65,0x70, 0x2,0x46,0x2d, 0x1,0x65,0x6e, 0x2,0x46,0x2a, + 0x3,0x43,0x64, 0x2,0x4c,0x79, 0x3,0x43,0x68, 0x3,0x43,0x6a, + 0x3,0x43,0x63, 0x1,0x6a,0x37, 0x2,0x4c,0x71, 0x1,0x6e,0x43, + 0x2,0x4c,0x7b, 0x1,0x6a,0x3a, 0x2,0x4d,0x21, 0x1,0x6a,0x40, + 0x2,0x4c,0x6c, 0x3,0x48,0x74, 0x4,0x45,0x7b, 0x2,0x4c,0x7c, + 0x2,0x4c,0x69, 0x3,0x48,0x6d, 0x2,0x4c,0x7e, 0x2,0x4c,0x6d, + 0x3,0x48,0x6e, 0x1,0x6a,0x47, 0x1,0x6a,0x44, 0x2,0x4c,0x7d, + 0x2,0x4c,0x77, 0x1,0x6a,0x36, 0x1,0x6a,0x3e, 0x1,0x6a,0x3d, + 0x3,0x48,0x70, 0x1,0x6a,0x3c, 0x1,0x6a,0x42, 0x3,0x48,0x69, + 0x2,0x4c,0x6a, 0x1,0x6a,0x43, 0x2,0x4c,0x78, 0x1,0x6a,0x3f, + 0x1,0x6a,0x35, 0x2,0x4c,0x7a, 0x1,0x6a,0x38, 0x1,0x6a,0x39, + 0x1,0x6a,0x41, 0x2,0x4c,0x6f, 0x2,0x4c,0x6e, 0x2,0x4c,0x6b, + 0x4,0x45,0x7c, 0x2,0x4c,0x73, 0x2,0x4c,0x70, 0x2,0x4c,0x74, + 0x1,0x6a,0x46, 0x3,0x48,0x68, 0x2,0x4d,0x22, 0x1,0x6a,0x3b, + 0x2,0x4c,0x75, 0x2,0x4c,0x76, 0x3,0x48,0x71, 0x2,0x4c,0x72, + 0x3,0x48,0x73, 0x3,0x66,0x29, 0x3,0x48,0x6b, 0x1,0x6a,0x45, + 0x3,0x66,0x2b, 0x3,0x4e,0x22, 0x2,0x52,0x6f, 0x1,0x6e,0x3b, + 0x1,0x6e,0x44, 0x1,0x6e,0x40, 0x2,0x52,0x6c, 0x3,0x4d,0x7c, + 0x1,0x6e,0x3d, 0x1,0x6e,0x41, 0x2,0x52,0x78, 0x1,0x6e,0x37, + 0x2,0x52,0x70, 0x3,0x4d,0x78, 0x1,0x6e,0x3f, 0x3,0x4e,0x24, + 0x3,0x4e,0x2f, 0x2,0x52,0x73, 0x2,0x52,0x6e, 0x1,0x6e,0x3e, + 0x1,0x6e,0x42, 0x2,0x52,0x6d, 0x3,0x4e,0x2e, 0x1,0x6e,0x3c, + 0x3,0x4d,0x77, 0x2,0x52,0x77, 0x1,0x6e,0x39, 0x2,0x52,0x76, + 0x2,0x52,0x75, 0x1,0x6e,0x45, 0x2,0x50,0x3b, 0x1,0x6e,0x38, + 0x3,0x4e,0x2b, 0x2,0x52,0x74, 0x2,0x52,0x6b, 0x3,0x4d,0x75, + 0x1,0x6e,0x46, 0x2,0x52,0x72, 0x1,0x6e,0x3a, 0x3,0x4e,0x28, + 0x3,0x4e,0x29, 0x3,0x4e,0x25, 0x3,0x4e,0x2c, 0x3,0x4e,0x27, + 0x3,0x4d,0x7e, 0x3,0x4d,0x7d, 0x2,0x52,0x71, 0x4,0x4c,0x45, + 0x3,0x66,0x2a, 0x1,0x71,0x6a, 0x1,0x71,0x6f, 0x1,0x71,0x68, + 0x2,0x59,0x44, 0x2,0x59,0x3b, 0x2,0x59,0x47, 0x2,0x59,0x3f, + 0x2,0x59,0x45, 0x1,0x71,0x70, 0x1,0x71,0x69, 0x2,0x59,0x38, + 0x2,0x59,0x3e, 0x2,0x59,0x48, 0x2,0x59,0x41, 0x2,0x59,0x46, + 0x2,0x59,0x3a, 0x4,0x52,0x4c, 0x3,0x52,0x3b, 0x2,0x59,0x42, + 0x1,0x71,0x6b, 0x2,0x59,0x40, 0x1,0x71,0x6e, 0x1,0x71,0x6d, + 0x2,0x59,0x3c, 0x2,0x59,0x3d, 0x2,0x59,0x39, 0x2,0x59,0x43, + 0x1,0x71,0x6c, 0x2,0x59,0x4a, 0x2,0x59,0x49, 0x3,0x52,0x40, + 0x3,0x52,0x3f, 0x2,0x5e,0x47, 0x2,0x5e,0x43, 0x1,0x74,0x69, + 0x3,0x55,0x79, 0x2,0x5e,0x3d, 0x1,0x74,0x63, 0x1,0x74,0x73, + 0x2,0x5e,0x49, 0x1,0x74,0x6b, 0x1,0x74,0x67, 0x2,0x5e,0x40, + 0x1,0x74,0x6e, 0x1,0x74,0x71, 0x2,0x5e,0x4b, 0x1,0x74,0x66, + 0x2,0x5e,0x42, 0x1,0x74,0x6f, 0x2,0x5e,0x4d, 0x2,0x5e,0x4a, + 0x2,0x5e,0x3e, 0x1,0x74,0x6a, 0x1,0x74,0x64, 0x1,0x74,0x72, + 0x2,0x5e,0x45, 0x1,0x74,0x6d, 0x2,0x5e,0x3f, 0x1,0x74,0x68, + 0x2,0x5e,0x4c, 0x1,0x74,0x6c, 0x1,0x74,0x65, 0x2,0x5e,0x46, + 0x1,0x74,0x70, 0x2,0x5e,0x44, 0x2,0x5e,0x48, 0x3,0x55,0x7a, + 0x4,0x5c,0x5f, 0x3,0x58,0x59, 0x2,0x62,0x5a, 0x2,0x62,0x60, + 0x1,0x77,0x25, 0x2,0x62,0x63, 0x1,0x76,0x7e, 0x1,0x77,0x21, + 0x2,0x62,0x5b, 0x2,0x62,0x62, 0x2,0x62,0x5d, 0x1,0x77,0x26, + 0x1,0x77,0x23, 0x3,0x58,0x5b, 0x2,0x62,0x59, 0x3,0x58,0x58, + 0x1,0x77,0x22, 0x2,0x62,0x5f, 0x2,0x62,0x61, 0x1,0x77,0x24, + 0x2,0x62,0x5e, 0x2,0x62,0x5c, 0x3,0x66,0x2c, 0x4,0x5c,0x5e, + 0x3,0x58,0x5a, 0x2,0x66,0x42, 0x1,0x78,0x62, 0x1,0x78,0x63, + 0x1,0x78,0x5f, 0x3,0x5a,0x72, 0x1,0x78,0x60, 0x3,0x5a,0x74, + 0x2,0x66,0x3e, 0x2,0x66,0x3c, 0x3,0x5a,0x75, 0x2,0x66,0x40, + 0x1,0x78,0x64, 0x2,0x66,0x41, 0x2,0x66,0x3a, 0x2,0x66,0x39, + 0x2,0x66,0x3d, 0x2,0x66,0x3b, 0x1,0x78,0x61, 0x2,0x66,0x3f, + 0x2,0x69,0x59, 0x1,0x7a,0x2b, 0x1,0x7a,0x2a, 0x2,0x69,0x5a, + 0x3,0x5c,0x6c, 0x2,0x69,0x5c, 0x2,0x69,0x5b, 0x1,0x7a,0x2c, + 0x3,0x5e,0x53, 0x3,0x5e,0x50, 0x2,0x6b,0x79, 0x2,0x6b,0x76, + 0x2,0x6b,0x77, 0x3,0x5e,0x51, 0x2,0x6b,0x75, 0x2,0x6b,0x78, + 0x1,0x7a,0x7d, 0x2,0x6b,0x7a, 0x3,0x5e,0x52, 0x1,0x7a,0x7c, + 0x2,0x6d,0x6f, 0x3,0x5f,0x5a, 0x1,0x7c,0x41, 0x1,0x7c,0x43, + 0x2,0x6f,0x3d, 0x1,0x7c,0x42, 0x2,0x70,0x47, 0x2,0x71,0x2f, + 0x2,0x71,0x31, 0x2,0x71,0x2e, 0x2,0x71,0x30, 0x1,0x7d,0x39, + 0x4,0x6d,0x78, 0x3,0x62,0x35, 0x1,0x48,0x4f, 0x4,0x25,0x57, + 0x1,0x52,0x7e, 0x2,0x30,0x52, 0x1,0x57,0x4d, 0x3,0x38,0x31, + 0xf,0x31,0x78, 0x1,0x5c,0x5f, 0x2,0x3f,0x22, 0x2,0x3f,0x23, + 0x3,0x66,0x2d, 0x3,0x48,0x77, 0x2,0x59,0x4b, 0x1,0x74,0x74, + 0x2,0x5e,0x4e, 0x3,0x55,0x7d, 0x3,0x58,0x5c, 0x1,0x77,0x27, + 0x2,0x66,0x44, 0x2,0x66,0x43, 0x1,0x7a,0x2d, 0x2,0x6b,0x7b, + 0x3,0x5f,0x5b, 0x2,0x6d,0x70, 0x1,0x7c,0x64, 0x2,0x22,0x69, + 0x4,0x22,0x21, 0x1,0x4f,0x2c, 0x1,0x4b,0x38, 0xf,0x28,0x4a, + 0x2,0x2c,0x6e, 0x3,0x2a,0x4e, 0x2,0x32,0x24, 0x2,0x31,0x7d, + 0x2,0x32,0x23, 0x2,0x32,0x21, 0x1,0x57,0x4e, 0x2,0x32,0x22, + 0x2,0x31,0x7e, 0x3,0x33,0x3c, 0x2,0x38,0x36, 0x4,0x3a,0x2b, + 0x2,0x3f,0x24, 0x2,0x3f,0x25, 0x2,0x46,0x30, 0x2,0x46,0x31, + 0x1,0x65,0x75, 0x1,0x65,0x76, 0x2,0x46,0x2f, 0x2,0x46,0x32, + 0x2,0x46,0x2e, 0x1,0x65,0x74, 0x3,0x48,0x78, 0x1,0x6a,0x48, + 0x3,0x48,0x79, 0x1,0x65,0x77, 0x2,0x4d,0x23, 0x1,0x6e,0x47, + 0x2,0x52,0x79, 0x1,0x6e,0x48, 0x3,0x4e,0x30, 0x1,0x71,0x71, + 0x2,0x59,0x4e, 0x2,0x59,0x4c, 0x2,0x59,0x4d, 0x2,0x5e,0x51, + 0x2,0x5e,0x50, 0x2,0x5e,0x4f, 0x7,0x41,0x61, 0x4,0x5c,0x68, + 0x2,0x66,0x45, 0x4,0x60,0x6f, 0x1,0x78,0x65, 0x2,0x66,0x46, + 0x2,0x6d,0x71, 0x1,0x7c,0x65, 0x2,0x70,0x48, 0x1,0x48,0x50, + 0x1,0x4f,0x2e, 0x1,0x4f,0x2d, 0x2,0x2c,0x70, 0x1,0x53,0x21, + 0x3,0x2e,0x5d, 0x4,0x2f,0x30, 0x2,0x2c,0x6f, 0x2,0x32,0x26, + 0x3,0x33,0x3d, 0x1,0x57,0x4f, 0x2,0x38,0x37, 0x2,0x32,0x25, + 0x3,0x33,0x3f, 0x4,0x2f,0x2f, 0x3,0x33,0x3e, 0x1,0x5c,0x61, + 0x2,0x38,0x3a, 0x2,0x38,0x38, 0x2,0x38,0x39, 0x1,0x5c,0x60, + 0x2,0x3f,0x27, 0x2,0x3f,0x28, 0x2,0x3f,0x26, 0x3,0x43,0x6e, + 0x1,0x65,0x7a, 0x2,0x46,0x34, 0x2,0x46,0x33, 0x2,0x46,0x35, + 0x1,0x65,0x79, 0x1,0x65,0x78, 0x4,0x46,0x26, 0x2,0x52,0x7a, + 0x2,0x52,0x7c, 0x3,0x4e,0x31, 0x1,0x6e,0x49, 0x2,0x52,0x7b, + 0x2,0x59,0x4f, 0x1,0x71,0x72, 0x2,0x62,0x65, 0x3,0x58,0x5d, + 0x2,0x62,0x64, 0x1,0x78,0x66, 0x2,0x66,0x47, 0x1,0x78,0x68, + 0x1,0x78,0x67, 0x2,0x69,0x5d, 0x2,0x6b,0x7c, 0x1,0x7a,0x7e, + 0x1,0x48,0x51, 0x2,0x2c,0x71, 0x1,0x53,0x22, 0x2,0x32,0x29, + 0x1,0x57,0x51, 0x2,0x32,0x28, 0x2,0x32,0x27, 0x3,0x33,0x42, + 0x1,0x57,0x50, 0x3,0x33,0x43, 0x2,0x38,0x40, 0x4,0x34,0x3d, + 0x2,0x38,0x42, 0x2,0x38,0x3b, 0x2,0x38,0x3c, 0x1,0x5c,0x62, + 0x2,0x38,0x3d, 0x1,0x5c,0x63, 0x2,0x38,0x41, 0x2,0x38,0x3e, + 0x2,0x38,0x3f, 0x1,0x5c,0x64, 0x3,0x3e,0x37, 0x1,0x61,0x44, + 0x1,0x61,0x45, 0x3,0x3e,0x38, 0x2,0x3f,0x29, 0x2,0x46,0x36, + 0x2,0x46,0x37, 0x3,0x43,0x72, 0x2,0x4d,0x27, 0x1,0x6a,0x4b, + 0x1,0x6a,0x49, 0x1,0x6a,0x4a, 0x2,0x4d,0x24, 0x2,0x4d,0x25, + 0x6,0x60,0x58, 0x2,0x4d,0x26, 0x2,0x53,0x23, 0x3,0x4e,0x32, + 0x2,0x53,0x24, 0x1,0x6e,0x4a, 0x2,0x53,0x21, 0x2,0x52,0x7e, + 0x2,0x53,0x22, 0x2,0x52,0x7d, 0x1,0x71,0x75, 0x2,0x59,0x50, + 0x1,0x71,0x73, 0x1,0x71,0x74, 0x2,0x5e,0x53, 0x1,0x74,0x75, + 0x2,0x5e,0x52, 0x2,0x61,0x34, 0x3,0x55,0x7e, 0x2,0x62,0x66, + 0x2,0x62,0x67, 0x1,0x77,0x28, 0x3,0x58,0x61, 0x1,0x77,0x29, + 0x1,0x74,0x76, 0x2,0x66,0x48, 0x2,0x66,0x49, 0x2,0x69,0x5e, + 0x1,0x7a,0x2e, 0x1,0x48,0x52, 0x3,0x66,0x7b, 0x1,0x48,0x53, + 0x1,0x57,0x53, 0x1,0x4f,0x2f, 0x1,0x57,0x52, 0x2,0x2c,0x72, + 0x3,0x38,0x36, 0x4,0x2b,0x25, 0x3,0x33,0x44, 0x1,0x61,0x46, + 0x1,0x48,0x54, 0x1,0x53,0x24, 0x2,0x2c,0x73, 0x2,0x2c,0x74, + 0x1,0x53,0x23, 0x1,0x53,0x25, 0x1,0x48,0x55, 0x4,0x27,0x61, + 0x2,0x2c,0x75, 0x1,0x57,0x55, 0x2,0x32,0x2a, 0x1,0x57,0x57, + 0x1,0x57,0x54, 0x1,0x57,0x56, 0x3,0x38,0x37, 0x2,0x38,0x45, + 0x1,0x5c,0x65, 0x3,0x38,0x39, 0x2,0x38,0x44, 0x2,0x38,0x43, + 0x4,0x3a,0x38, 0x2,0x46,0x38, 0x3,0x49,0x22, 0x2,0x4d,0x28, + 0x4,0x46,0x2c, 0x1,0x6e,0x4b, 0x1,0x71,0x76, 0x2,0x59,0x52, + 0x2,0x59,0x51, 0x3,0x56,0x21, 0x2,0x5e,0x54, 0x4,0x5c,0x71, + 0x3,0x58,0x62, 0x3,0x5c,0x6f, 0x2,0x6b,0x7d, 0x4,0x69,0x2e, + 0x4,0x69,0x2d, 0x1,0x48,0x56, 0x2,0x24,0x73, 0x2,0x28,0x4a, + 0x1,0x53,0x26, 0x2,0x2c,0x76, 0x6,0x3b,0x21, 0x2,0x32,0x2c, + 0x4,0x2f,0x3a, 0x3,0x33,0x49, 0x3,0x33,0x48, 0x1,0x57,0x58, + 0x2,0x32,0x2b, 0x1,0x57,0x59, 0x3,0x33,0x47, 0x3,0x66,0x2f, + 0x2,0x38,0x47, 0x3,0x38,0x3d, 0x3,0x38,0x3c, 0x1,0x5c,0x67, + 0x2,0x38,0x46, 0x2,0x38,0x48, 0x3,0x38,0x3b, 0x1,0x5c,0x66, + 0x3,0x3e,0x3c, 0x2,0x3f,0x2b, 0x2,0x3f,0x2c, 0x2,0x3f,0x2a, + 0x1,0x61,0x47, 0x3,0x67,0x29, 0x4,0x3f,0x7c, 0x1,0x65,0x7b, + 0x3,0x43,0x73, 0x1,0x65,0x7c, 0x4,0x46,0x33, 0x1,0x6a,0x4d, + 0x3,0x49,0x23, 0x2,0x4d,0x2a, 0x2,0x4d,0x29, 0x1,0x6a,0x4c, + 0x3,0x49,0x26, 0x3,0x3e,0x3b, 0x3,0x49,0x25, 0x3,0x66,0x30, + 0x2,0x53,0x25, 0x3,0x4e,0x34, 0x3,0x4e,0x36, 0x2,0x53,0x26, + 0x3,0x4e,0x37, 0x3,0x4e,0x35, 0x3,0x4e,0x38, 0x2,0x59,0x53, + 0x4,0x52,0x5c, 0x3,0x52,0x43, 0x1,0x74,0x7a, 0x1,0x74,0x79, + 0x1,0x74,0x77, 0x1,0x74,0x78, 0x1,0x74,0x7b, 0x3,0x56,0x22, + 0x2,0x62,0x68, 0x1,0x77,0x2b, 0x1,0x77,0x2a, 0x2,0x66,0x4a, + 0x2,0x69,0x5f, 0x3,0x5c,0x70, 0x3,0x5c,0x71, 0x3,0x5c,0x72, + 0x1,0x7b,0x6f, 0x1,0x7b,0x6e, 0x1,0x48,0x57, 0x6,0x3b,0x24, + 0x2,0x2f,0x7d, 0x1,0x65,0x7e, 0x1,0x61,0x48, 0x1,0x65,0x7d, + 0x1,0x6a,0x4e, 0x6,0x60,0x60, 0x1,0x48,0x58, 0x2,0x21,0x68, + 0x1,0x48,0x59, 0x1,0x48,0x5a, 0x3,0x24,0x35, 0x3,0x24,0x36, + 0x2,0x28,0x4b, 0x2,0x24,0x76, 0x3,0x27,0x24, 0x2,0x24,0x77, + 0x1,0x4b,0x3a, 0x3,0x27,0x26, 0x2,0x24,0x74, 0x1,0x4b,0x39, + 0x3,0x27,0x25, 0x1,0x4b,0x3c, 0x2,0x24,0x75, 0x1,0x4b,0x3e, + 0x1,0x4b,0x3d, 0x2,0x24,0x78, 0x1,0x4b,0x3b, 0x4,0x24,0x70, + 0x3,0x27,0x23, 0x1,0x4f,0x34, 0x1,0x4f,0x32, 0x2,0x28,0x4d, + 0x3,0x2a,0x56, 0x1,0x4f,0x31, 0x3,0x2a,0x5b, 0x3,0x2a,0x58, + 0x3,0x2a,0x4f, 0x1,0x4f,0x36, 0x1,0x4f,0x38, 0x1,0x4f,0x35, + 0x3,0x2a,0x59, 0x2,0x28,0x50, 0x2,0x28,0x4c, 0x1,0x4f,0x39, + 0x3,0x2a,0x52, 0x1,0x4f,0x33, 0x1,0x4b,0x3f, 0x3,0x2a,0x54, + 0x1,0x4f,0x37, 0x2,0x28,0x4f, 0x3,0x2a,0x57, 0x4,0x27,0x64, + 0x2,0x28,0x4e, 0x4,0x27,0x69, 0x1,0x4f,0x30, 0x3,0x66,0x31, + 0x2,0x2c,0x7c, 0x1,0x53,0x2a, 0x1,0x53,0x2b, 0x2,0x2c,0x7e, + 0x3,0x2e,0x66, 0x2,0x2c,0x78, 0x2,0x2c,0x7b, 0x2,0x2d,0x26, + 0x2,0x2d,0x24, 0x3,0x2e,0x60, 0x1,0x53,0x2c, 0x2,0x2d,0x2a, + 0x1,0x53,0x2f, 0x2,0x2d,0x27, 0x2,0x2c,0x7d, 0x2,0x2c,0x7a, + 0x3,0x2e,0x61, 0x3,0x2e,0x5e, 0x2,0x3f,0x2e, 0x2,0x2d,0x25, + 0x1,0x53,0x27, 0x2,0x2d,0x28, 0x2,0x2c,0x77, 0x2,0x2d,0x22, + 0x1,0x53,0x29, 0x1,0x53,0x2e, 0x2,0x2d,0x23, 0x1,0x53,0x32, + 0x1,0x53,0x30, 0x3,0x2e,0x65, 0x2,0x2c,0x79, 0x1,0x53,0x2d, + 0x3,0x2e,0x64, 0x2,0x2d,0x21, 0x1,0x53,0x31, 0x1,0x53,0x28, + 0x2,0x2d,0x29, 0x1,0x57,0x5e, 0x3,0x33,0x4c, 0x1,0x57,0x67, + 0x1,0x57,0x5c, 0x1,0x57,0x5a, 0x2,0x32,0x2e, 0x1,0x57,0x62, + 0x1,0x57,0x5f, 0x2,0x32,0x30, 0x3,0x33,0x4a, 0x3,0x33,0x52, + 0x1,0x57,0x61, 0x2,0x32,0x2f, 0x2,0x32,0x2d, 0x2,0x32,0x32, + 0x1,0x57,0x66, 0x1,0x57,0x64, 0x2,0x3f,0x2d, 0x3,0x33,0x4b, + 0x2,0x32,0x33, 0x2,0x32,0x31, 0x1,0x57,0x5b, 0x3,0x33,0x4e, + 0x3,0x33,0x4d, 0x1,0x57,0x5d, 0x1,0x57,0x60, 0x3,0x33,0x4f, + 0x1,0x57,0x63, 0x3,0x2e,0x63, 0x1,0x57,0x65, 0x3,0x3e,0x44, + 0x2,0x38,0x52, 0x1,0x5c,0x69, 0x3,0x38,0x49, 0x2,0x38,0x49, + 0x2,0x38,0x4b, 0x3,0x38,0x47, 0x2,0x38,0x4c, 0x4,0x34,0x4d, + 0x2,0x38,0x54, 0x2,0x38,0x50, 0x2,0x38,0x4e, 0x4,0x3a,0x3b, + 0x2,0x38,0x51, 0x2,0x38,0x55, 0x1,0x5c,0x6a, 0x1,0x5c,0x6e, + 0x2,0x38,0x4a, 0x4,0x34,0x47, 0x2,0x38,0x53, 0x4,0x34,0x50, + 0x1,0x5c,0x6c, 0x3,0x38,0x41, 0x1,0x5c,0x6b, 0x2,0x38,0x4f, + 0x2,0x38,0x4d, 0x3,0x38,0x42, 0x1,0x5c,0x68, 0x1,0x5c,0x6d, + 0x3,0x38,0x45, 0x3,0x38,0x48, 0x1,0x61,0x4e, 0x2,0x3f,0x36, + 0x3,0x3e,0x3e, 0x4,0x3a,0x3e, 0x2,0x3f,0x34, 0x1,0x61,0x50, + 0x4,0x3a,0x47, 0x3,0x3e,0x43, 0x3,0x3e,0x45, 0x3,0x3e,0x41, + 0x2,0x3f,0x2f, 0x2,0x46,0x46, 0x3,0x3e,0x3d, 0x1,0x61,0x4f, + 0x2,0x3f,0x33, 0x3,0x3e,0x40, 0x3,0x3e,0x42, 0x2,0x3f,0x30, + 0x1,0x61,0x4b, 0x1,0x61,0x51, 0x2,0x3f,0x35, 0x1,0x61,0x4d, + 0x2,0x3f,0x32, 0x1,0x6a,0x4f, 0x1,0x61,0x4c, 0x2,0x3f,0x31, + 0x1,0x61,0x52, 0x1,0x61,0x4a, 0x1,0x61,0x49, 0x6,0x43,0x5a, + 0x2,0x46,0x3e, 0x2,0x46,0x3c, 0x3,0x43,0x7b, 0x2,0x46,0x42, + 0x3,0x43,0x7e, 0x2,0x46,0x3a, 0x2,0x46,0x47, 0x2,0x46,0x3f, + 0x3,0x43,0x75, 0x2,0x46,0x39, 0x1,0x66,0x24, 0x1,0x66,0x2a, + 0x2,0x46,0x44, 0x4,0x40,0x29, 0x2,0x46,0x3d, 0x3,0x43,0x76, + 0x1,0x66,0x27, 0x3,0x43,0x77, 0x3,0x44,0x23, 0x1,0x66,0x25, + 0x2,0x46,0x45, 0x1,0x66,0x22, 0x1,0x66,0x21, 0x2,0x46,0x40, + 0x1,0x66,0x26, 0x1,0x61,0x53, 0x3,0x43,0x7c, 0x2,0x46,0x43, + 0x2,0x46,0x3b, 0x1,0x66,0x23, 0x1,0x66,0x28, 0x1,0x66,0x29, + 0x3,0x44,0x22, 0x1,0x6a,0x54, 0x1,0x6a,0x50, 0x3,0x49,0x27, + 0x1,0x6a,0x55, 0x2,0x4d,0x2d, 0x3,0x49,0x2a, 0x4,0x46,0x39, + 0x2,0x4d,0x2c, 0x2,0x4d,0x2e, 0x1,0x6a,0x52, 0x2,0x4d,0x2b, + 0x1,0x6a,0x53, 0x2,0x4d,0x31, 0x2,0x4d,0x30, 0x2,0x4d,0x2f, + 0x4,0x46,0x46, 0x1,0x6a,0x51, 0x4,0x52,0x67, 0x3,0x4e,0x3b, + 0x3,0x4e,0x3d, 0x3,0x4e,0x39, 0x2,0x53,0x2a, 0x3,0x4e,0x3c, + 0x2,0x53,0x2d, 0x1,0x6e,0x51, 0x2,0x53,0x2c, 0x1,0x6e,0x50, + 0x1,0x6e,0x4c, 0x1,0x6e,0x4d, 0x1,0x6e,0x4e, 0x2,0x53,0x29, + 0x2,0x53,0x28, 0x1,0x6e,0x4f, 0x3,0x4e,0x3a, 0x2,0x53,0x2b, + 0x2,0x53,0x27, 0x2,0x59,0x55, 0x2,0x59,0x5f, 0x1,0x71,0x79, + 0x1,0x71,0x78, 0x3,0x52,0x49, 0x2,0x59,0x59, 0x2,0x59,0x5b, + 0x3,0x52,0x47, 0x2,0x59,0x56, 0x3,0x52,0x44, 0x2,0x59,0x5a, + 0x2,0x59,0x54, 0x2,0x59,0x5d, 0x1,0x71,0x77, 0x2,0x59,0x5c, + 0x2,0x59,0x58, 0x2,0x59,0x5e, 0x3,0x56,0x23, 0x2,0x59,0x57, + 0x1,0x74,0x7e, 0x2,0x5e,0x55, 0x2,0x5e,0x5b, 0x1,0x75,0x24, + 0x1,0x75,0x26, 0x1,0x75,0x23, 0x1,0x75,0x22, 0x4,0x58,0x27, + 0x1,0x75,0x21, 0x1,0x74,0x7d, 0x2,0x5e,0x56, 0x2,0x5e,0x59, + 0x1,0x74,0x7c, 0x2,0x5e,0x5a, 0x3,0x56,0x24, 0x1,0x75,0x25, + 0x2,0x5e,0x58, 0x7,0x48,0x7c, 0x2,0x5e,0x57, 0x1,0x77,0x2c, + 0x3,0x58,0x65, 0x1,0x77,0x2d, 0x2,0x62,0x6b, 0x2,0x62,0x69, + 0x2,0x62,0x6a, 0x3,0x5a,0x77, 0x2,0x66,0x4c, 0x3,0x5a,0x78, + 0x2,0x66,0x4b, 0x1,0x78,0x69, 0x2,0x69,0x61, 0x1,0x7a,0x2f, + 0x2,0x69,0x60, 0x2,0x6b,0x7e, 0x2,0x6d,0x72, 0x1,0x7b,0x70, + 0x2,0x71,0x32, 0x2,0x71,0x33, 0x1,0x7c,0x44, 0x1,0x48,0x5b, + 0x4,0x27,0x6c, 0x1,0x4f,0x3a, 0x2,0x3f,0x37, 0x1,0x6a,0x56, + 0x1,0x75,0x27, 0x2,0x5e,0x5c, 0x1,0x48,0x5c, 0x4,0x24,0x73, + 0x1,0x57,0x69, 0x1,0x57,0x68, 0x2,0x3f,0x38, 0x3,0x3e,0x47, + 0x4,0x3a,0x4c, 0x4,0x4c,0x62, 0x2,0x59,0x60, 0x1,0x48,0x5d, + 0x1,0x53,0x33, 0x4,0x3a,0x4d, 0x3,0x3e,0x48, 0x2,0x3f,0x39, + 0x2,0x3f,0x3a, 0x2,0x3f,0x3b, 0x1,0x6a,0x57, 0x1,0x71,0x7a, + 0x1,0x48,0x5e, 0x4,0x27,0x6d, 0x1,0x4f,0x3b, 0x2,0x2d,0x2b, + 0x1,0x57,0x6a, 0x2,0x32,0x34, 0x1,0x5c,0x6f, 0x3,0x3e,0x49, + 0x2,0x3f,0x3c, 0x1,0x66,0x2b, 0x1,0x6a,0x58, 0x1,0x71,0x7b, + 0x1,0x75,0x28, 0x1,0x77,0x2e, 0x2,0x66,0x4d, 0x1,0x48,0x5f, + 0x1,0x4f,0x3c, 0x3,0x2a,0x5d, 0x4,0x27,0x6e, 0x1,0x57,0x6b, + 0x2,0x38,0x56, 0x1,0x61,0x54, 0x3,0x49,0x2b, 0x1,0x6a,0x59, + 0x2,0x4d,0x32, 0x2,0x53,0x2e, 0x3,0x52,0x4a, 0x3,0x58,0x68, + 0x3,0x5a,0x79, 0x1,0x48,0x60, 0x1,0x61,0x55, 0x2,0x46,0x48, + 0x1,0x6a,0x5a, 0x1,0x48,0x61, 0x2,0x28,0x51, 0x2,0x2d,0x2c, + 0x1,0x53,0x34, 0x3,0x2e,0x68, 0x2,0x32,0x36, 0x4,0x2f,0x4f, + 0x3,0x33,0x57, 0x1,0x57,0x6e, 0x3,0x33,0x58, 0x1,0x57,0x6c, + 0x1,0x57,0x6d, 0x1,0x57,0x6f, 0x3,0x33,0x55, 0x2,0x32,0x35, + 0x2,0x38,0x5b, 0x2,0x38,0x58, 0x2,0x38,0x5a, 0x1,0x5c,0x70, + 0x1,0x5c,0x72, 0x1,0x5c,0x71, 0x2,0x38,0x57, 0x1,0x5c,0x73, + 0x2,0x38,0x59, 0x2,0x3f,0x3d, 0x2,0x3f,0x3e, 0x2,0x3f,0x3f, + 0x2,0x46,0x4b, 0x3,0x44,0x26, 0x2,0x46,0x4c, 0x4,0x40,0x2e, + 0x2,0x46,0x4a, 0x2,0x46,0x4d, 0x4,0x40,0x2d, 0x1,0x66,0x2c, + 0x3,0x66,0x34, 0x2,0x46,0x49, 0x3,0x49,0x2d, 0x1,0x6a,0x5b, + 0x3,0x49,0x2e, 0x2,0x53,0x33, 0x2,0x53,0x2f, 0x2,0x53,0x32, + 0x2,0x53,0x34, 0x2,0x53,0x31, 0x2,0x53,0x30, 0x2,0x59,0x61, + 0x2,0x59,0x62, 0x2,0x59,0x63, 0x1,0x71,0x7c, 0x1,0x71,0x7d, + 0x2,0x5e,0x5e, 0x2,0x5e,0x5d, 0x2,0x5e,0x5f, 0x2,0x62,0x6d, + 0x2,0x62,0x6c, 0x2,0x66,0x4f, 0x3,0x5a,0x7a, 0x2,0x66,0x50, + 0x2,0x66,0x4e, 0x3,0x5a,0x7b, 0x1,0x7a,0x30, 0x4,0x64,0x2c, + 0x2,0x69,0x62, 0x2,0x69,0x63, 0x3,0x5e,0x55, 0x2,0x6d,0x73, + 0x2,0x6f,0x3e, 0x2,0x70,0x49, 0x1,0x48,0x62, 0x1,0x4b,0x40, + 0x1,0x75,0x29, 0x1,0x48,0x63, 0xf,0x32,0x32, 0x2,0x38,0x5c, + 0x2,0x3f,0x40, 0x3,0x5a,0x7c, 0x1,0x7c,0x6c, 0x2,0x22,0x6a, + 0x4,0x21,0x53, 0x3,0x24,0x38, 0x2,0x22,0x6b, 0x2,0x22,0x6d, + 0x1,0x48,0x64, 0x2,0x22,0x6e, 0x2,0x22,0x6c, 0x4,0x23,0x2f, + 0x2,0x25,0x22, 0x2,0x25,0x23, 0x2,0x24,0x7b, 0x3,0x27,0x28, + 0x4,0x24,0x7b, 0x4,0x24,0x75, 0x2,0x25,0x21, 0x1,0x4b,0x42, + 0x3,0x27,0x29, 0x1,0x4b,0x43, 0x2,0x24,0x7c, 0x2,0x24,0x7a, + 0x2,0x24,0x79, 0x2,0x24,0x7d, 0x1,0x4b,0x41, 0x2,0x24,0x7e, + 0x2,0x2d,0x2d, 0x3,0x27,0x2b, 0x4,0x24,0x79, 0x2,0x28,0x56, + 0x1,0x4f,0x3f, 0x2,0x28,0x55, 0x2,0x28,0x57, 0x3,0x2a,0x60, + 0x1,0x4f,0x3e, 0x2,0x28,0x5c, 0x1,0x4f,0x42, 0x2,0x28,0x52, + 0x2,0x28,0x60, 0x2,0x28,0x66, 0x1,0x4f,0x49, 0x2,0x28,0x63, + 0x1,0x4f,0x46, 0x3,0x2a,0x6b, 0x2,0x28,0x59, 0x2,0x28,0x5f, + 0x2,0x28,0x61, 0x3,0x2a,0x66, 0x2,0x28,0x54, 0x1,0x4f,0x45, + 0x1,0x4f,0x40, 0x2,0x28,0x5a, 0x1,0x4f,0x47, 0x1,0x4f,0x4a, + 0x1,0x4f,0x44, 0x3,0x2a,0x6c, 0x1,0x4f,0x3d, 0x2,0x28,0x5e, + 0x2,0x28,0x58, 0x2,0x28,0x65, 0x1,0x4f,0x4c, 0x1,0x4f,0x48, + 0x1,0x4f,0x43, 0x2,0x28,0x5d, 0x1,0x57,0x70, 0x2,0x28,0x5b, + 0x1,0x4f,0x41, 0x1,0x4f,0x4b, 0x4,0x27,0x7a, 0x2,0x28,0x53, + 0x4,0x27,0x7e, 0x2,0x28,0x62, 0x2,0x28,0x64, 0x3,0x2a,0x5e, + 0xf,0x28,0x63, 0x3,0x2a,0x68, 0x4,0x27,0x7b, 0x3,0x2e,0x76, + 0x1,0x53,0x45, 0x1,0x53,0x3f, 0x1,0x53,0x47, 0x1,0x53,0x44, + 0x2,0x2d,0x34, 0x2,0x2d,0x37, 0x1,0x53,0x40, 0x3,0x2e,0x6a, + 0x2,0x2d,0x2e, 0x4,0x2b,0x3a, 0x1,0x53,0x39, 0x1,0x53,0x43, + 0x3,0x2e,0x6b, 0x1,0x53,0x46, 0x1,0x53,0x48, 0x2,0x2d,0x43, + 0x2,0x2d,0x3a, 0x3,0x2e,0x78, 0x1,0x53,0x38, 0x2,0x2d,0x42, + 0x1,0x53,0x3c, 0x1,0x53,0x3a, 0x1,0x53,0x35, 0x2,0x2d,0x32, + 0x3,0x2e,0x72, 0x2,0x2d,0x41, 0x2,0x2d,0x36, 0x2,0x2d,0x39, + 0x2,0x2d,0x46, 0x3,0x2e,0x74, 0x1,0x53,0x49, 0x2,0x2d,0x40, + 0x1,0x53,0x41, 0x2,0x2d,0x3b, 0x2,0x2d,0x45, 0x2,0x2d,0x38, + 0x2,0x2d,0x3c, 0x2,0x2d,0x3f, 0x3,0x2e,0x69, 0x3,0x2e,0x6e, + 0x2,0x2d,0x30, 0x2,0x2d,0x44, 0x2,0x2d,0x3e, 0x3,0x2e,0x6f, + 0x3,0x2e,0x7a, 0x2,0x2d,0x2f, 0x6,0x34,0x3c, 0x2,0x2d,0x33, + 0x1,0x53,0x42, 0x1,0x53,0x3d, 0x1,0x53,0x36, 0x1,0x53,0x3b, + 0x1,0x53,0x37, 0x1,0x53,0x4a, 0x2,0x2d,0x31, 0x2,0x32,0x47, + 0x1,0x53,0x3e, 0x4,0x2b,0x3d, 0x3,0x2e,0x79, 0x2,0x2d,0x3d, + 0x2,0x29,0x42, 0x3,0x2e,0x77, 0x3,0x66,0x35, 0x3,0x66,0x37, + 0x2,0x32,0x4a, 0x1,0x57,0x7e, 0x3,0x33,0x62, 0x2,0x32,0x3a, + 0x4,0x2f,0x5d, 0x2,0x32,0x45, 0x2,0x32,0x41, 0x3,0x38,0x4d, + 0x2,0x32,0x54, 0x3,0x33,0x59, 0x2,0x32,0x4c, 0x3,0x33,0x5f, + 0x2,0x32,0x42, 0x3,0x38,0x5b, 0x2,0x32,0x4b, 0x2,0x32,0x3c, + 0x2,0x32,0x40, 0x2,0x32,0x57, 0x1,0x58,0x23, 0x2,0x32,0x4f, + 0x2,0x32,0x46, 0x1,0x57,0x71, 0x2,0x32,0x55, 0x2,0x32,0x38, + 0x4,0x2f,0x5a, 0x2,0x32,0x4e, 0x4,0x2f,0x63, 0x1,0x58,0x22, + 0x1,0x57,0x7b, 0x2,0x32,0x37, 0x1,0x57,0x79, 0x1,0x57,0x78, + 0x1,0x57,0x7d, 0x2,0x32,0x4d, 0x1,0x57,0x75, 0x1,0x57,0x7c, + 0x2,0x2d,0x35, 0x2,0x3f,0x41, 0x2,0x32,0x48, 0x4,0x2f,0x5f, + 0x3,0x2a,0x5f, 0x2,0x32,0x3e, 0x1,0x58,0x21, 0x2,0x32,0x3f, + 0x2,0x32,0x43, 0x1,0x58,0x24, 0x2,0x32,0x39, 0x2,0x32,0x51, + 0x3,0x3e,0x57, 0x2,0x32,0x50, 0x2,0x32,0x58, 0x1,0x57,0x77, + 0x1,0x57,0x74, 0x2,0x32,0x56, 0x2,0x32,0x52, 0x2,0x32,0x49, + 0x2,0x32,0x44, 0x1,0x57,0x7a, 0x1,0x57,0x76, 0x2,0x32,0x3b, + 0x1,0x57,0x72, 0x2,0x32,0x53, 0x1,0x57,0x73, 0x4,0x2f,0x5c, + 0x2,0x32,0x3d, 0x3,0x33,0x5a, 0x3,0x33,0x63, 0x3,0x66,0x36, + 0x3,0x2d,0x33, 0x4,0x34,0x67, 0x3,0x38,0x4e, 0x3,0x38,0x51, + 0x2,0x38,0x62, 0x2,0x38,0x64, 0x2,0x38,0x69, 0x2,0x38,0x7d, + 0x1,0x5d,0x23, 0x1,0x5c,0x77, 0x3,0x38,0x54, 0x2,0x38,0x61, + 0x1,0x5d,0x24, 0x1,0x5d,0x25, 0x2,0x38,0x6c, 0x2,0x38,0x73, + 0x2,0x38,0x79, 0x3,0x38,0x50, 0x2,0x38,0x66, 0x4,0x34,0x6d, + 0x2,0x38,0x6d, 0x3,0x38,0x4f, 0x3,0x38,0x5d, 0x1,0x5d,0x26, + 0x2,0x38,0x7b, 0x2,0x38,0x76, 0x1,0x5d,0x21, 0x1,0x5c,0x7d, + 0x2,0x38,0x72, 0x2,0x38,0x6e, 0x2,0x38,0x60, 0x1,0x5c,0x74, + 0x2,0x38,0x65, 0x2,0x38,0x5d, 0x3,0x38,0x55, 0x1,0x5c,0x7c, + 0x1,0x5c,0x7e, 0x2,0x38,0x6a, 0x2,0x38,0x67, 0x1,0x5c,0x79, + 0x2,0x38,0x77, 0x1,0x5c,0x76, 0x2,0x38,0x68, 0x2,0x3f,0x6a, + 0x2,0x38,0x70, 0x3,0x38,0x5e, 0x2,0x38,0x6f, 0x1,0x5c,0x75, + 0x3,0x38,0x57, 0x1,0x5d,0x22, 0x3,0x38,0x52, 0x1,0x5c,0x78, + 0x2,0x38,0x5e, 0x2,0x38,0x63, 0x2,0x38,0x74, 0x2,0x38,0x7a, + 0x1,0x5d,0x27, 0x2,0x38,0x5f, 0x2,0x38,0x6b, 0x2,0x38,0x71, + 0x1,0x5c,0x7b, 0x4,0x34,0x6f, 0x3,0x38,0x58, 0x2,0x38,0x7c, + 0x2,0x38,0x75, 0x2,0x38,0x78, 0x3,0x38,0x5f, 0xf,0x37,0x78, + 0x1,0x5c,0x7a, 0x4,0x3a,0x68, 0x2,0x3f,0x51, 0x2,0x3f,0x45, + 0x1,0x61,0x5d, 0x2,0x3f,0x62, 0x2,0x3f,0x6b, 0x2,0x3f,0x6e, + 0x1,0x61,0x5b, 0x2,0x3f,0x4d, 0x2,0x3f,0x66, 0x2,0x3f,0x4e, + 0x2,0x3f,0x5c, 0x1,0x61,0x68, 0x2,0x3f,0x58, 0x1,0x61,0x65, + 0x3,0x3e,0x5e, 0x2,0x3f,0x59, 0x2,0x3f,0x42, 0x5,0x3b,0x6f, + 0x2,0x3f,0x67, 0x3,0x3e,0x4f, 0x3,0x3e,0x59, 0x1,0x61,0x6e, + 0x2,0x3f,0x64, 0x2,0x3f,0x5a, 0x2,0x3f,0x70, 0x2,0x3f,0x55, + 0x2,0x46,0x6d, 0x3,0x3e,0x4d, 0x2,0x3f,0x73, 0x1,0x61,0x6c, + 0x2,0x3f,0x53, 0x2,0x3f,0x5f, 0x1,0x61,0x6f, 0x1,0x61,0x5a, + 0x2,0x3f,0x57, 0x2,0x3f,0x71, 0x2,0x3f,0x50, 0x2,0x3f,0x49, + 0x2,0x3f,0x54, 0x3,0x3e,0x5f, 0x2,0x3f,0x48, 0x2,0x3f,0x46, + 0x1,0x61,0x56, 0x2,0x3f,0x68, 0x2,0x3f,0x4f, 0x2,0x3f,0x6c, + 0x3,0x3e,0x4b, 0x2,0x3f,0x6d, 0x1,0x61,0x5e, 0x1,0x61,0x63, + 0x1,0x61,0x5f, 0x1,0x61,0x67, 0x2,0x3f,0x63, 0x1,0x61,0x60, + 0x2,0x3f,0x5b, 0x2,0x3f,0x4b, 0xf,0x3e,0x66, 0x1,0x61,0x58, + 0x2,0x3f,0x43, 0x2,0x3f,0x65, 0x2,0x3f,0x6f, 0x2,0x3f,0x4a, + 0x1,0x61,0x66, 0x2,0x3f,0x74, 0x2,0x3f,0x56, 0x3,0x3e,0x52, + 0x2,0x3f,0x52, 0x3,0x3e,0x5c, 0x1,0x61,0x57, 0x1,0x61,0x6b, + 0x3,0x3e,0x5a, 0x2,0x3f,0x61, 0x1,0x61,0x6d, 0x3,0x3e,0x50, + 0x2,0x3f,0x5d, 0x1,0x61,0x62, 0x1,0x61,0x5c, 0x1,0x61,0x64, + 0x1,0x61,0x59, 0x1,0x61,0x6a, 0x2,0x3f,0x5e, 0x2,0x3f,0x4c, + 0x2,0x3f,0x60, 0x2,0x3f,0x47, 0x2,0x3f,0x69, 0x3,0x3e,0x58, + 0x4,0x3a,0x67, 0x3,0x3e,0x5d, 0x3,0x3e,0x56, 0x3,0x3e,0x4e, + 0x2,0x3f,0x72, 0x3,0x66,0x39, 0x3,0x3e,0x5b, 0x3,0x66,0x38, + 0x2,0x3f,0x44, 0x2,0x46,0x6c, 0x3,0x44,0x2d, 0x2,0x47,0x24, + 0x1,0x65,0x5c, 0x2,0x46,0x71, 0x3,0x44,0x31, 0x2,0x46,0x6f, + 0x2,0x46,0x5a, 0x1,0x66,0x30, 0x2,0x46,0x6a, 0x2,0x46,0x7e, + 0x2,0x46,0x66, 0x1,0x66,0x38, 0x2,0x46,0x7d, 0x2,0x46,0x64, + 0x1,0x61,0x69, 0x2,0x46,0x74, 0x2,0x46,0x65, 0x2,0x46,0x7b, + 0x1,0x66,0x37, 0x1,0x66,0x2f, 0x3,0x44,0x3a, 0x2,0x46,0x4f, + 0x2,0x46,0x57, 0x3,0x44,0x35, 0x2,0x46,0x70, 0x2,0x46,0x68, + 0x2,0x47,0x23, 0x2,0x46,0x6b, 0x1,0x66,0x3d, 0x2,0x46,0x7c, + 0x3,0x44,0x2c, 0x1,0x66,0x34, 0x3,0x44,0x3e, 0x2,0x46,0x6e, + 0x2,0x46,0x76, 0x2,0x46,0x5b, 0x2,0x46,0x75, 0x3,0x44,0x27, + 0x2,0x47,0x28, 0x2,0x46,0x56, 0x2,0x46,0x77, 0x3,0x44,0x33, + 0x2,0x47,0x26, 0x3,0x44,0x3f, 0x2,0x46,0x50, 0x1,0x61,0x61, + 0x3,0x44,0x40, 0x2,0x46,0x5e, 0x2,0x46,0x5d, 0x1,0x66,0x36, + 0x3,0x44,0x32, 0x2,0x46,0x61, 0x2,0x46,0x63, 0x2,0x46,0x72, + 0x2,0x47,0x25, 0x1,0x66,0x39, 0x3,0x44,0x38, 0x1,0x66,0x3a, + 0x3,0x44,0x30, 0x2,0x46,0x55, 0x1,0x66,0x32, 0x2,0x46,0x59, + 0x2,0x47,0x21, 0x1,0x66,0x3b, 0x4,0x40,0x44, 0x1,0x66,0x33, + 0x1,0x66,0x35, 0x1,0x66,0x3c, 0x2,0x47,0x27, 0x2,0x46,0x78, + 0x2,0x46,0x73, 0x3,0x44,0x3c, 0x3,0x44,0x2f, 0x2,0x46,0x60, + 0x2,0x46,0x5f, 0x1,0x66,0x31, 0x2,0x46,0x51, 0x1,0x66,0x2e, + 0x2,0x46,0x69, 0x2,0x46,0x52, 0x2,0x46,0x67, 0x3,0x44,0x2e, + 0x4,0x40,0x41, 0x2,0x46,0x5c, 0x2,0x47,0x22, 0x3,0x44,0x2a, + 0x3,0x44,0x39, 0x4,0x40,0x36, 0x1,0x66,0x2d, 0x3,0x44,0x3b, + 0x3,0x44,0x28, 0x2,0x46,0x58, 0x4,0x40,0x46, 0x2,0x46,0x54, + 0x2,0x46,0x7a, 0x2,0x46,0x53, 0x1,0x6a,0x68, 0x2,0x4d,0x5a, + 0x3,0x49,0x35, 0x3,0x49,0x44, 0x2,0x4d,0x49, 0x3,0x49,0x33, + 0x3,0x49,0x38, 0x2,0x4d,0x33, 0x2,0x4d,0x51, 0x1,0x6a,0x60, + 0x2,0x4d,0x42, 0x2,0x4d,0x4c, 0x1,0x6a,0x63, 0x2,0x4d,0x45, + 0x1,0x6a,0x61, 0x2,0x4d,0x36, 0x2,0x4d,0x54, 0x2,0x4d,0x35, + 0x2,0x4d,0x48, 0x3,0x49,0x3c, 0x2,0x4d,0x34, 0x3,0x49,0x39, + 0x4,0x46,0x6c, 0x2,0x4d,0x46, 0x2,0x4d,0x4f, 0x2,0x4d,0x4d, + 0x2,0x4d,0x41, 0x2,0x4d,0x3c, 0x2,0x4d,0x3a, 0x3,0x49,0x42, + 0x2,0x4d,0x3b, 0x2,0x4d,0x4e, 0x2,0x4d,0x59, 0x2,0x4d,0x43, + 0x1,0x6a,0x62, 0x3,0x49,0x3b, 0x2,0x4d,0x3e, 0x3,0x49,0x3a, + 0x2,0x4d,0x52, 0x3,0x49,0x41, 0x1,0x6a,0x65, 0x2,0x4d,0x3d, + 0x2,0x4d,0x37, 0x2,0x4d,0x47, 0x1,0x6a,0x69, 0x3,0x49,0x32, + 0x4,0x46,0x58, 0x1,0x6a,0x5d, 0x1,0x6a,0x66, 0x2,0x4d,0x3f, + 0x2,0x4d,0x39, 0x3,0x49,0x36, 0x1,0x6a,0x5f, 0x2,0x46,0x79, + 0x1,0x6a,0x5e, 0x2,0x4d,0x4a, 0x3,0x44,0x36, 0x1,0x6a,0x5c, + 0x1,0x6a,0x6b, 0x1,0x6a,0x64, 0x2,0x4d,0x4b, 0x2,0x4d,0x40, + 0x2,0x4d,0x38, 0x2,0x4d,0x53, 0x2,0x4d,0x44, 0x1,0x6a,0x6a, + 0x2,0x4d,0x57, 0x1,0x6a,0x67, 0x2,0x4d,0x56, 0x3,0x49,0x3f, + 0x2,0x4d,0x50, 0x2,0x4d,0x55, 0x3,0x49,0x3e, 0x3,0x49,0x43, + 0x2,0x4d,0x58, 0x3,0x66,0x3b, 0x3,0x66,0x3c, 0x3,0x66,0x3a, + 0x3,0x49,0x3d, 0x2,0x53,0x5c, 0x2,0x53,0x5d, 0x2,0x53,0x50, + 0x2,0x53,0x4f, 0x2,0x53,0x4b, 0x1,0x6e,0x5d, 0x3,0x4e,0x4f, + 0x1,0x6e,0x55, 0x2,0x53,0x5f, 0x2,0x53,0x5e, 0x2,0x46,0x4e, + 0x2,0x53,0x48, 0x2,0x53,0x4c, 0x2,0x53,0x46, 0x3,0x4e,0x44, + 0x2,0x53,0x59, 0x2,0x53,0x4a, 0x3,0x4e,0x42, 0x2,0x53,0x60, + 0x2,0x53,0x43, 0x2,0x53,0x41, 0x2,0x53,0x4d, 0x2,0x53,0x57, + 0x2,0x53,0x52, 0x1,0x6e,0x5f, 0x2,0x53,0x38, 0x3,0x4e,0x40, + 0x2,0x53,0x56, 0x3,0x4e,0x4c, 0x3,0x4e,0x46, 0x3,0x4e,0x54, + 0x1,0x6e,0x60, 0x2,0x46,0x62, 0x2,0x53,0x44, 0x2,0x53,0x3b, + 0x2,0x53,0x3e, 0x2,0x53,0x64, 0x2,0x53,0x45, 0x2,0x53,0x3c, + 0x2,0x53,0x3a, 0x2,0x53,0x37, 0x4,0x4c,0x7a, 0x1,0x6e,0x59, + 0x2,0x53,0x4e, 0x1,0x6e,0x58, 0x1,0x6e,0x5c, 0x2,0x53,0x49, + 0x2,0x53,0x51, 0x1,0x6e,0x52, 0x2,0x53,0x61, 0x2,0x53,0x65, + 0x1,0x6e,0x54, 0x3,0x4e,0x4b, 0x2,0x53,0x40, 0x2,0x53,0x54, + 0x2,0x53,0x58, 0x2,0x53,0x3d, 0x2,0x53,0x62, 0x1,0x6e,0x5b, + 0x4,0x4c,0x6a, 0x1,0x6e,0x5a, 0x2,0x53,0x35, 0x1,0x6e,0x5e, + 0x2,0x53,0x5b, 0x2,0x53,0x3f, 0x2,0x53,0x53, 0x2,0x53,0x39, + 0x2,0x53,0x47, 0x2,0x53,0x42, 0x1,0x6e,0x56, 0x1,0x6e,0x57, + 0x2,0x53,0x55, 0x2,0x53,0x66, 0x2,0x53,0x63, 0x2,0x53,0x5a, + 0x4,0x4c,0x78, 0x3,0x4e,0x4d, 0x3,0x4e,0x4e, 0x3,0x4e,0x52, + 0x4,0x4c,0x74, 0x2,0x53,0x36, 0x1,0x6e,0x53, 0x2,0x59,0x74, + 0x3,0x52,0x5a, 0x2,0x59,0x6b, 0x2,0x59,0x6e, 0x3,0x52,0x52, + 0x1,0x72,0x25, 0x2,0x59,0x70, 0x2,0x59,0x65, 0x2,0x59,0x6c, + 0x2,0x59,0x72, 0x1,0x72,0x22, 0x1,0x72,0x26, 0x1,0x71,0x7e, + 0x3,0x52,0x59, 0x3,0x52,0x50, 0x2,0x59,0x67, 0x2,0x59,0x77, + 0x4,0x4d,0x25, 0x4,0x53,0x33, 0x2,0x59,0x71, 0x4,0x53,0x24, + 0x2,0x59,0x68, 0x2,0x5a,0x22, 0x2,0x59,0x7a, 0x2,0x59,0x64, + 0x2,0x5e,0x72, 0x2,0x59,0x6a, 0x1,0x72,0x21, 0x3,0x52,0x58, + 0x2,0x59,0x75, 0x3,0x52,0x54, 0x2,0x5a,0x21, 0x1,0x72,0x29, + 0x3,0x52,0x56, 0x2,0x59,0x7c, 0x2,0x59,0x69, 0x2,0x59,0x6f, + 0x2,0x59,0x73, 0x2,0x59,0x6d, 0x2,0x5a,0x23, 0x2,0x59,0x7e, + 0x2,0x59,0x7b, 0x1,0x72,0x23, 0x1,0x72,0x24, 0x1,0x72,0x28, + 0x2,0x59,0x66, 0x2,0x5a,0x24, 0x1,0x72,0x27, 0x2,0x59,0x78, + 0x3,0x52,0x4f, 0x3,0x52,0x55, 0x2,0x59,0x76, 0x3,0x66,0x3d, + 0x2,0x59,0x79, 0x2,0x5f,0x21, 0x2,0x5e,0x6c, 0x2,0x5e,0x71, + 0x2,0x5e,0x7e, 0x2,0x5e,0x70, 0x2,0x5e,0x68, 0x2,0x5e,0x6d, + 0x4,0x58,0x3e, 0x1,0x75,0x2c, 0x3,0x56,0x2b, 0x2,0x5e,0x61, + 0x2,0x5e,0x79, 0x2,0x5e,0x7b, 0x2,0x5e,0x60, 0x1,0x75,0x2b, + 0x2,0x5e,0x7d, 0x2,0x5e,0x75, 0x1,0x75,0x32, 0x2,0x5e,0x7c, + 0x2,0x5e,0x6e, 0x1,0x75,0x34, 0x2,0x5e,0x66, 0x2,0x59,0x7d, + 0x2,0x5e,0x76, 0x2,0x5e,0x73, 0x2,0x5e,0x62, 0x2,0x5f,0x23, + 0x1,0x75,0x2e, 0x3,0x56,0x28, 0x3,0x56,0x29, 0x1,0x75,0x2f, + 0x2,0x5e,0x64, 0x2,0x5e,0x74, 0x3,0x56,0x2d, 0x2,0x5f,0x22, + 0x2,0x5e,0x77, 0x2,0x5e,0x6a, 0x1,0x75,0x31, 0x1,0x75,0x2d, + 0x2,0x5e,0x78, 0x2,0x5e,0x6b, 0x2,0x5f,0x24, 0x2,0x5e,0x65, + 0x2,0x5e,0x6f, 0x2,0x5e,0x7a, 0x2,0x5e,0x67, 0x2,0x5e,0x69, + 0x4,0x58,0x40, 0x1,0x75,0x35, 0x2,0x5e,0x63, 0x1,0x75,0x33, + 0x1,0x77,0x30, 0x1,0x75,0x2a, 0x3,0x56,0x2c, 0x3,0x56,0x30, + 0x1,0x75,0x30, 0x1,0x77,0x34, 0x2,0x62,0x7d, 0x3,0x58,0x6c, + 0x2,0x62,0x73, 0x2,0x62,0x6e, 0x2,0x62,0x74, 0x2,0x62,0x7e, + 0x2,0x63,0x24, 0x2,0x63,0x23, 0x1,0x77,0x36, 0x1,0x77,0x35, + 0x3,0x58,0x6e, 0x4,0x5d,0x2c, 0x2,0x62,0x75, 0x2,0x63,0x25, + 0x2,0x62,0x78, 0x2,0x62,0x70, 0x3,0x58,0x6f, 0x2,0x62,0x72, + 0x2,0x62,0x71, 0x2,0x62,0x77, 0x2,0x62,0x7c, 0x2,0x62,0x6f, + 0x2,0x62,0x76, 0x2,0x62,0x7b, 0x1,0x77,0x33, 0x4,0x5d,0x28, + 0x2,0x62,0x79, 0x3,0x58,0x6b, 0x1,0x77,0x31, 0x2,0x62,0x7a, + 0x1,0x77,0x2f, 0x1,0x77,0x32, 0x2,0x66,0x60, 0x2,0x63,0x21, + 0x3,0x66,0x3e, 0x1,0x78,0x6d, 0x3,0x5a,0x7e, 0x2,0x66,0x58, + 0x2,0x66,0x5c, 0x2,0x66,0x54, 0x2,0x66,0x57, 0x3,0x5a,0x7d, + 0x2,0x66,0x5f, 0x1,0x78,0x6b, 0x2,0x66,0x64, 0x2,0x66,0x5d, + 0x4,0x60,0x7a, 0x2,0x66,0x55, 0x2,0x66,0x65, 0x2,0x66,0x5e, + 0x1,0x78,0x6e, 0x1,0x78,0x6f, 0x2,0x66,0x62, 0x3,0x5b,0x22, + 0x2,0x66,0x56, 0x1,0x78,0x6a, 0x1,0x78,0x6c, 0x2,0x66,0x51, + 0x2,0x66,0x59, 0x2,0x66,0x53, 0x3,0x5c,0x7b, 0x2,0x66,0x63, + 0x2,0x66,0x61, 0x2,0x66,0x52, 0x2,0x66,0x5a, 0x4,0x60,0x7b, + 0x3,0x5b,0x25, 0x3,0x66,0x3f, 0x2,0x69,0x6a, 0x1,0x78,0x70, + 0x2,0x66,0x5b, 0x1,0x7a,0x32, 0x1,0x7a,0x34, 0x1,0x7a,0x31, + 0x3,0x5c,0x76, 0x2,0x69,0x6f, 0x2,0x69,0x67, 0x2,0x69,0x65, + 0x2,0x69,0x69, 0x2,0x69,0x66, 0x3,0x5c,0x78, 0x3,0x5c,0x7c, + 0x2,0x69,0x6b, 0x2,0x69,0x6d, 0x1,0x7a,0x35, 0x1,0x7a,0x37, + 0x3,0x5d,0x22, 0x2,0x69,0x6c, 0x1,0x7a,0x38, 0x1,0x7a,0x36, + 0x2,0x69,0x6e, 0x3,0x5c,0x7e, 0x4,0x64,0x37, 0x3,0x5d,0x23, + 0x3,0x5c,0x77, 0x1,0x7a,0x33, 0x3,0x5d,0x21, 0x3,0x5e,0x5b, + 0x3,0x5e,0x5a, 0x1,0x7b,0x21, 0x2,0x6c,0x21, 0x2,0x6c,0x27, + 0x1,0x7b,0x23, 0x2,0x69,0x68, 0x2,0x6c,0x26, 0x3,0x5e,0x5c, + 0x2,0x6c,0x2d, 0x2,0x6c,0x24, 0x2,0x6c,0x2b, 0x2,0x6c,0x2a, + 0x2,0x69,0x64, 0x2,0x6c,0x25, 0x2,0x63,0x22, 0x2,0x6c,0x2e, + 0x2,0x6c,0x23, 0x2,0x6c,0x28, 0x3,0x5e,0x58, 0x2,0x6c,0x2c, + 0x2,0x6c,0x22, 0x3,0x5e,0x56, 0x2,0x6d,0x77, 0x1,0x7b,0x22, + 0x2,0x6c,0x29, 0x3,0x5e,0x57, 0x2,0x6f,0x43, 0x2,0x6d,0x78, + 0x2,0x6d,0x76, 0x2,0x6d,0x74, 0x2,0x6d,0x75, 0x2,0x6d,0x79, + 0x3,0x66,0x40, 0x1,0x7c,0x45, 0x2,0x6f,0x41, 0x2,0x6f,0x3f, + 0x2,0x6f,0x44, 0x2,0x6f,0x42, 0x3,0x60,0x43, 0x2,0x6f,0x45, + 0x1,0x7c,0x46, 0x2,0x6f,0x40, 0x3,0x60,0x2f, 0x3,0x61,0x46, + 0x2,0x70,0x4a, 0x3,0x66,0x41, 0x2,0x71,0x34, 0x2,0x71,0x35, + 0x2,0x71,0x36, 0x3,0x61,0x47, 0x3,0x61,0x7c, 0x2,0x72,0x35, + 0x2,0x72,0x2d, 0x2,0x22,0x6f, 0x1,0x4f,0x4d, 0x1,0x53,0x4b, + 0x4,0x2f,0x68, 0x2,0x32,0x5a, 0x2,0x32,0x59, 0x1,0x58,0x25, + 0x1,0x5d,0x28, 0x2,0x39,0x21, 0x3,0x38,0x63, 0x3,0x38,0x60, + 0x2,0x38,0x7e, 0x3,0x38,0x61, 0x1,0x61,0x70, 0x1,0x66,0x3f, + 0x3,0x3e,0x61, 0x1,0x66,0x3e, 0x1,0x66,0x40, 0x5,0x49,0x4e, + 0x2,0x4d,0x5b, 0x2,0x53,0x67, 0x2,0x5a,0x25, 0x2,0x5a,0x27, + 0x2,0x5a,0x26, 0x7,0x32,0x61, 0x1,0x75,0x36, 0x2,0x5f,0x25, + 0x2,0x63,0x26, 0x2,0x71,0x73, 0x1,0x48,0x65, 0x3,0x27,0x2d, + 0x2,0x28,0x69, 0x2,0x28,0x6a, 0x2,0x28,0x68, 0x2,0x28,0x67, + 0x1,0x4f,0x4e, 0x3,0x66,0x42, 0x2,0x2d,0x4a, 0x2,0x2d,0x48, + 0x3,0x2f,0x23, 0x3,0x2e,0x7c, 0x2,0x2d,0x47, 0x3,0x2e,0x7e, + 0x1,0x53,0x4c, 0x1,0x53,0x4e, 0x1,0x53,0x4d, 0x2,0x2d,0x49, + 0x3,0x2f,0x24, 0xf,0x2d,0x3e, 0x3,0x33,0x69, 0x2,0x32,0x66, + 0x2,0x32,0x63, 0x2,0x32,0x61, 0x4,0x2f,0x6d, 0x3,0x33,0x6c, + 0x1,0x58,0x26, 0x2,0x32,0x64, 0x1,0x58,0x2b, 0x2,0x32,0x5e, + 0x2,0x32,0x6d, 0x3,0x33,0x6f, 0x2,0x32,0x6f, 0x2,0x32,0x5f, + 0x3,0x33,0x6e, 0x1,0x58,0x28, 0x2,0x32,0x70, 0x2,0x32,0x6b, + 0x2,0x32,0x5d, 0x2,0x32,0x62, 0x2,0x32,0x6c, 0x2,0x32,0x68, + 0x2,0x32,0x65, 0x3,0x33,0x6b, 0x1,0x58,0x2d, 0x2,0x32,0x6e, + 0x2,0x32,0x60, 0x3,0x33,0x6a, 0x3,0x33,0x70, 0x2,0x32,0x69, + 0x2,0x32,0x5b, 0x1,0x58,0x2c, 0x1,0x58,0x29, 0x2,0x32,0x67, + 0x3,0x33,0x6d, 0x2,0x32,0x6a, 0x2,0x32,0x5c, 0x1,0x58,0x2a, + 0x1,0x58,0x27, 0x4,0x34,0x7a, 0x3,0x38,0x66, 0x1,0x5d,0x32, + 0x2,0x39,0x28, 0x1,0x5d,0x31, 0x3,0x38,0x64, 0x2,0x39,0x2b, + 0x2,0x39,0x2e, 0x1,0x5d,0x2e, 0x1,0x5d,0x2c, 0x2,0x39,0x23, + 0x2,0x39,0x2c, 0x2,0x39,0x2a, 0x2,0x39,0x27, 0x2,0x39,0x2f, + 0x2,0x39,0x30, 0x2,0x39,0x32, 0x2,0x39,0x33, 0x2,0x39,0x22, + 0x1,0x5d,0x2b, 0x2,0x39,0x25, 0x2,0x39,0x24, 0x2,0x39,0x31, + 0x1,0x5d,0x2d, 0x2,0x39,0x26, 0x1,0x5d,0x2f, 0x1,0x5d,0x2a, + 0x2,0x39,0x29, 0x1,0x5d,0x33, 0x4,0x35,0x26, 0x1,0x5d,0x30, + 0x2,0x39,0x2d, 0xf,0x38,0x3a, 0x1,0x61,0x77, 0x2,0x40,0x25, + 0x4,0x3a,0x71, 0x2,0x3f,0x78, 0x1,0x61,0x74, 0x3,0x3e,0x62, + 0x2,0x47,0x2e, 0x2,0x40,0x23, 0x2,0x3f,0x75, 0x1,0x61,0x72, + 0x2,0x3f,0x7a, 0x1,0x61,0x75, 0x2,0x3f,0x7e, 0x2,0x3f,0x7c, + 0x1,0x61,0x78, 0x1,0x61,0x71, 0x4,0x3a,0x76, 0x3,0x3e,0x63, + 0x2,0x3f,0x76, 0x2,0x3f,0x79, 0x1,0x61,0x76, 0x4,0x3a,0x6f, + 0x2,0x3f,0x77, 0x5,0x3b,0x7b, 0x2,0x40,0x24, 0x2,0x40,0x22, + 0x2,0x3f,0x7b, 0x2,0x3f,0x7d, 0x2,0x40,0x21, 0x1,0x61,0x73, + 0x3,0x3e,0x68, 0x2,0x47,0x2f, 0x2,0x47,0x35, 0x2,0x47,0x2b, + 0x2,0x47,0x31, 0x1,0x66,0x41, 0x2,0x47,0x2d, 0x1,0x66,0x47, + 0x3,0x44,0x44, 0x3,0x44,0x45, 0x1,0x66,0x46, 0x3,0x44,0x49, + 0x1,0x66,0x45, 0x2,0x47,0x34, 0x1,0x66,0x48, 0x1,0x66,0x49, + 0x2,0x47,0x2a, 0x2,0x47,0x37, 0x1,0x66,0x4a, 0x1,0x66,0x44, + 0x1,0x66,0x43, 0x2,0x47,0x33, 0x1,0x66,0x4b, 0x2,0x47,0x29, + 0x2,0x47,0x2c, 0x2,0x47,0x36, 0x2,0x47,0x32, 0x4,0x40,0x59, + 0x4,0x40,0x52, 0x2,0x4d,0x7b, 0x2,0x4d,0x70, 0x1,0x66,0x42, + 0x5,0x42,0x5d, 0x3,0x44,0x46, 0x3,0x44,0x48, 0x1,0x6a,0x72, + 0x2,0x4d,0x64, 0x2,0x4d,0x79, 0x2,0x4d,0x65, 0x1,0x6a,0x6d, + 0x3,0x49,0x4f, 0x2,0x4d,0x62, 0x4,0x40,0x55, 0x2,0x4d,0x6b, + 0x2,0x4d,0x63, 0x1,0x6a,0x6f, 0x2,0x4d,0x5d, 0x2,0x4d,0x78, + 0x1,0x6a,0x70, 0x2,0x4d,0x75, 0x2,0x4d,0x76, 0x2,0x4d,0x5e, + 0x1,0x6a,0x75, 0x2,0x4d,0x6d, 0x3,0x49,0x4a, 0x2,0x4d,0x67, + 0x2,0x4d,0x6e, 0x2,0x4d,0x61, 0x4,0x46,0x7e, 0x2,0x4d,0x7a, + 0x2,0x4d,0x72, 0x2,0x4d,0x6c, 0x2,0x4d,0x5c, 0x1,0x6a,0x71, + 0x2,0x4d,0x73, 0x3,0x49,0x45, 0x1,0x6a,0x74, 0x2,0x4d,0x77, + 0x3,0x49,0x4c, 0x2,0x4d,0x71, 0x1,0x6a,0x6e, 0x2,0x4d,0x6f, + 0x3,0x49,0x49, 0x2,0x4d,0x69, 0x1,0x6a,0x6c, 0x2,0x4d,0x60, + 0x2,0x4d,0x68, 0x2,0x4d,0x74, 0x2,0x4d,0x66, 0xf,0x4c,0x33, + 0x3,0x49,0x4e, 0x2,0x4d,0x6a, 0x3,0x49,0x4b, 0x3,0x66,0x43, + 0x1,0x6e,0x6a, 0x2,0x47,0x30, 0x2,0x53,0x79, 0x2,0x54,0x24, + 0x2,0x53,0x78, 0x2,0x53,0x74, 0x2,0x53,0x71, 0x1,0x6e,0x6b, + 0x2,0x53,0x6f, 0x1,0x6a,0x73, 0x2,0x53,0x68, 0x1,0x6e,0x69, + 0x2,0x53,0x6e, 0x1,0x6e,0x68, 0x2,0x53,0x73, 0x2,0x53,0x70, + 0x2,0x54,0x22, 0x2,0x53,0x7b, 0x2,0x53,0x75, 0x2,0x53,0x7a, + 0x1,0x6e,0x64, 0x2,0x53,0x72, 0x2,0x54,0x27, 0x2,0x53,0x69, + 0x2,0x53,0x6a, 0x2,0x54,0x23, 0x1,0x6e,0x65, 0x2,0x54,0x28, + 0x1,0x6e,0x67, 0x2,0x54,0x29, 0x2,0x53,0x77, 0x2,0x4d,0x5f, + 0x2,0x53,0x7d, 0x2,0x53,0x76, 0x2,0x54,0x21, 0x2,0x53,0x7c, + 0x5,0x50,0x55, 0x3,0x4e,0x5d, 0x4,0x4d,0x28, 0x2,0x53,0x6d, + 0x1,0x6e,0x62, 0x2,0x54,0x26, 0x1,0x6e,0x63, 0x2,0x53,0x6b, + 0x1,0x6e,0x66, 0x2,0x5a,0x32, 0x2,0x53,0x7e, 0x2,0x54,0x25, + 0x4,0x4d,0x31, 0x3,0x4e,0x59, 0x2,0x5a,0x2f, 0x1,0x6e,0x61, + 0x1,0x72,0x2a, 0x2,0x5a,0x39, 0x2,0x5a,0x35, 0x4,0x53,0x3c, + 0x2,0x5a,0x33, 0x2,0x5a,0x2e, 0x2,0x5a,0x3d, 0x3,0x52,0x5b, + 0x3,0x52,0x5d, 0x4,0x53,0x44, 0x1,0x72,0x2e, 0x3,0x52,0x5f, + 0x2,0x5a,0x2a, 0x2,0x5a,0x36, 0x2,0x5a,0x37, 0x2,0x5a,0x2d, + 0x2,0x5a,0x2c, 0x2,0x5a,0x3a, 0x4,0x53,0x41, 0x2,0x5a,0x30, + 0x2,0x5a,0x2b, 0x2,0x5a,0x31, 0x3,0x52,0x62, 0x2,0x5a,0x3c, + 0x2,0x5a,0x29, 0x2,0x5a,0x3b, 0x2,0x5a,0x38, 0x1,0x72,0x2c, + 0x1,0x72,0x2b, 0x4,0x53,0x39, 0x3,0x52,0x5e, 0x1,0x72,0x2d, + 0x2,0x5a,0x34, 0x2,0x5a,0x28, 0x3,0x66,0x45, 0x3,0x66,0x44, + 0x2,0x5f,0x27, 0x1,0x75,0x3c, 0x2,0x5f,0x2b, 0x2,0x5f,0x28, + 0x2,0x5f,0x2f, 0x2,0x5f,0x35, 0x2,0x5f,0x2a, 0x3,0x56,0x3a, + 0x2,0x5f,0x3e, 0x1,0x75,0x39, 0x2,0x5f,0x38, 0x2,0x5f,0x2d, + 0x2,0x5f,0x39, 0x2,0x5f,0x34, 0x2,0x5f,0x3b, 0x2,0x5f,0x2c, + 0x1,0x75,0x3e, 0x1,0x75,0x3d, 0x2,0x5f,0x2e, 0x2,0x5f,0x3c, + 0x2,0x5f,0x26, 0x2,0x5f,0x3a, 0x1,0x75,0x37, 0x3,0x56,0x39, + 0x2,0x5f,0x32, 0x2,0x5f,0x31, 0x2,0x5f,0x36, 0x2,0x5f,0x29, + 0x1,0x75,0x3b, 0x3,0x56,0x3b, 0x1,0x75,0x3f, 0x2,0x5f,0x30, + 0x2,0x5f,0x37, 0x1,0x75,0x40, 0x2,0x5f,0x33, 0x3,0x56,0x36, + 0x3,0x56,0x34, 0x1,0x75,0x38, 0x1,0x75,0x3a, 0x2,0x63,0x33, + 0x2,0x63,0x31, 0x3,0x5b,0x28, 0x3,0x58,0x76, 0x2,0x63,0x37, + 0x2,0x63,0x35, 0x2,0x63,0x38, 0x3,0x58,0x78, 0x2,0x63,0x2a, + 0x2,0x63,0x32, 0x2,0x63,0x3c, 0x2,0x5f,0x3d, 0x2,0x63,0x2e, + 0x1,0x77,0x3a, 0x2,0x53,0x6c, 0x2,0x63,0x29, 0x2,0x63,0x36, + 0x2,0x63,0x30, 0x2,0x63,0x2d, 0x2,0x63,0x28, 0x2,0x63,0x27, + 0x2,0x63,0x3b, 0x3,0x58,0x73, 0x2,0x63,0x2c, 0x2,0x63,0x2b, + 0x1,0x77,0x38, 0x2,0x63,0x34, 0x3,0x58,0x74, 0x1,0x77,0x37, + 0x3,0x58,0x75, 0x5,0x64,0x48, 0x1,0x77,0x39, 0x2,0x63,0x2f, + 0x2,0x63,0x3a, 0x3,0x66,0x46, 0x2,0x66,0x69, 0x2,0x66,0x6a, + 0x3,0x5b,0x2c, 0x1,0x78,0x74, 0x2,0x66,0x67, 0x1,0x78,0x71, + 0x2,0x66,0x6f, 0x3,0x5b,0x27, 0x1,0x78,0x75, 0x2,0x66,0x71, + 0x2,0x66,0x66, 0x2,0x63,0x39, 0x2,0x66,0x73, 0x2,0x66,0x68, + 0x5,0x69,0x43, 0x1,0x78,0x72, 0x2,0x66,0x6e, 0x3,0x5b,0x29, + 0x2,0x66,0x70, 0x2,0x66,0x6b, 0x2,0x66,0x72, 0x2,0x66,0x6d, + 0x2,0x66,0x6c, 0x1,0x78,0x73, 0x3,0x58,0x77, 0x3,0x5b,0x2b, + 0x2,0x69,0x71, 0x2,0x69,0x72, 0x3,0x5d,0x25, 0x2,0x69,0x74, + 0x1,0x7a,0x39, 0x1,0x7a,0x3a, 0x2,0x69,0x75, 0x2,0x69,0x73, + 0x3,0x5d,0x24, 0x2,0x69,0x70, 0x3,0x5e,0x5d, 0x2,0x6c,0x31, + 0x2,0x6c,0x34, 0x2,0x6c,0x30, 0x4,0x61,0x26, 0x1,0x7b,0x27, + 0x2,0x6c,0x32, 0x1,0x7b,0x26, 0x1,0x7b,0x25, 0x1,0x7b,0x24, + 0x2,0x6c,0x33, 0x2,0x6d,0x7e, 0x2,0x6d,0x7c, 0x3,0x5f,0x5f, + 0x2,0x6d,0x7b, 0x2,0x6c,0x2f, 0x2,0x6d,0x7d, 0x2,0x6c,0x35, + 0x2,0x6d,0x7a, 0x3,0x60,0x45, 0x2,0x6f,0x48, 0x2,0x6f,0x26, + 0x2,0x6f,0x46, 0x1,0x7c,0x47, 0x2,0x6f,0x47, 0x2,0x6f,0x49, + 0x3,0x66,0x47, 0x2,0x70,0x4d, 0x1,0x7c,0x66, 0x2,0x70,0x4c, + 0x2,0x70,0x4b, 0x1,0x7c,0x67, 0x4,0x6c,0x23, 0x1,0x7d,0x27, + 0x2,0x71,0x5d, 0x2,0x71,0x75, 0x2,0x71,0x74, 0x2,0x71,0x76, + 0x1,0x48,0x66, 0x2,0x2d,0x4b, 0x3,0x2f,0x26, 0x2,0x32,0x71, + 0x2,0x32,0x72, 0x3,0x38,0x6a, 0x3,0x3e,0x6a, 0x3,0x3e,0x69, + 0x2,0x40,0x26, 0x6,0x4e,0x4f, 0x2,0x6c,0x36, 0x2,0x70,0x4e, + 0x1,0x48,0x67, 0x1,0x53,0x4f, 0x2,0x2d,0x4c, 0x3,0x33,0x71, + 0x3,0x66,0x48, 0x4,0x35,0x27, 0x2,0x39,0x34, 0x1,0x5d,0x34, + 0x2,0x40,0x28, 0x2,0x40,0x27, 0x1,0x61,0x79, 0x3,0x44,0x4d, + 0x1,0x66,0x4c, 0x2,0x54,0x2a, 0x1,0x6e,0x6c, 0x3,0x4e,0x5f, + 0x1,0x6e,0x6d, 0x3,0x52,0x63, 0x3,0x52,0x64, 0x4,0x53,0x4b, + 0x1,0x72,0x2f, 0x1,0x7c,0x68, 0x1,0x48,0x68, 0x3,0x2f,0x27, + 0x2,0x2d,0x4d, 0x1,0x4f,0x50, 0x2,0x2d,0x4f, 0x2,0x2d,0x4e, + 0x1,0x53,0x50, 0x2,0x32,0x73, 0x3,0x33,0x74, 0x2,0x32,0x7a, + 0x1,0x58,0x2e, 0x2,0x32,0x78, 0x2,0x32,0x76, 0x3,0x33,0x77, + 0x2,0x32,0x7d, 0x2,0x32,0x74, 0x2,0x32,0x75, 0x1,0x58,0x2f, + 0x3,0x33,0x72, 0x1,0x58,0x33, 0x3,0x33,0x73, 0x3,0x33,0x75, + 0x2,0x32,0x7e, 0x1,0x58,0x32, 0x2,0x32,0x7c, 0x2,0x32,0x79, + 0x2,0x32,0x77, 0x1,0x58,0x30, 0x1,0x58,0x31, 0x2,0x32,0x7b, + 0x3,0x33,0x76, 0x3,0x66,0x49, 0x1,0x5d,0x36, 0x2,0x39,0x35, + 0x3,0x38,0x72, 0x1,0x5d,0x3b, 0x2,0x39,0x45, 0x1,0x5d,0x3a, + 0x2,0x39,0x47, 0x3,0x38,0x6e, 0x3,0x38,0x74, 0x2,0x39,0x3b, + 0x1,0x5d,0x38, 0x2,0x39,0x46, 0x3,0x38,0x6c, 0x2,0x39,0x36, + 0x1,0x5d,0x39, 0x2,0x39,0x42, 0x2,0x39,0x3e, 0x2,0x39,0x40, + 0x2,0x39,0x3a, 0x2,0x39,0x41, 0x3,0x38,0x6b, 0x4,0x35,0x2f, + 0x1,0x5d,0x35, 0x2,0x39,0x3d, 0x3,0x38,0x73, 0x2,0x39,0x3c, + 0x2,0x39,0x38, 0x3,0x38,0x6d, 0x2,0x39,0x43, 0x3,0x38,0x6f, + 0x3,0x38,0x71, 0x2,0x39,0x3f, 0x2,0x39,0x37, 0x3,0x38,0x70, + 0x2,0x39,0x39, 0x1,0x5d,0x37, 0x2,0x39,0x44, 0x1,0x61,0x7c, + 0x2,0x40,0x33, 0x4,0x3a,0x7b, 0x3,0x3e,0x70, 0x3,0x3e,0x72, + 0x2,0x40,0x2f, 0x2,0x40,0x31, 0x2,0x40,0x2c, 0x2,0x40,0x2b, + 0x2,0x40,0x29, 0x3,0x3e,0x6d, 0x2,0x40,0x30, 0x2,0x40,0x32, + 0x2,0x40,0x2e, 0x3,0x3e,0x6f, 0x2,0x40,0x2d, 0x1,0x61,0x7a, + 0x1,0x61,0x7b, 0x2,0x40,0x35, 0x1,0x66,0x54, 0x2,0x47,0x39, + 0x2,0x47,0x3f, 0x2,0x47,0x3a, 0x2,0x47,0x3b, 0x3,0x44,0x4e, + 0x2,0x47,0x40, 0x5,0x42,0x6c, 0x1,0x66,0x56, 0x4,0x40,0x61, + 0x1,0x66,0x4e, 0x1,0x66,0x55, 0x2,0x47,0x38, 0x2,0x40,0x2a, + 0x1,0x66,0x51, 0x1,0x66,0x4f, 0x2,0x47,0x3e, 0x2,0x47,0x3d, + 0x1,0x66,0x50, 0x1,0x66,0x52, 0x2,0x47,0x3c, 0x1,0x66,0x4d, + 0x3,0x44,0x4f, 0x1,0x66,0x53, 0x3,0x4e,0x60, 0x2,0x4d,0x7d, + 0x1,0x6a,0x7c, 0x3,0x49,0x59, 0x3,0x49,0x52, 0x2,0x4e,0x2a, + 0x2,0x4e,0x29, 0x3,0x49,0x57, 0x2,0x4e,0x24, 0x1,0x6a,0x7e, + 0x2,0x4e,0x28, 0x2,0x4d,0x7e, 0x2,0x4e,0x21, 0x1,0x6a,0x76, + 0x1,0x6a,0x78, 0x3,0x49,0x54, 0x2,0x4e,0x26, 0x2,0x4d,0x7c, + 0x1,0x6a,0x7a, 0x1,0x6a,0x79, 0x2,0x4e,0x22, 0x2,0x4e,0x27, + 0x2,0x4e,0x25, 0x1,0x6a,0x7b, 0x2,0x4e,0x23, 0x3,0x49,0x51, + 0x3,0x49,0x56, 0x2,0x40,0x34, 0x1,0x6a,0x77, 0x3,0x49,0x58, + 0x2,0x54,0x2b, 0x2,0x54,0x32, 0x1,0x6e,0x6f, 0x4,0x4d,0x46, + 0x2,0x54,0x36, 0x1,0x6e,0x73, 0x2,0x54,0x2e, 0x2,0x54,0x2c, + 0x4,0x4d,0x3e, 0x2,0x54,0x35, 0x3,0x4e,0x61, 0x1,0x6e,0x6e, + 0x2,0x54,0x34, 0x1,0x6e,0x70, 0x1,0x6e,0x71, 0x2,0x54,0x2d, + 0x1,0x6e,0x72, 0x2,0x54,0x33, 0x2,0x54,0x2f, 0x2,0x54,0x30, + 0x2,0x54,0x31, 0x1,0x6a,0x7d, 0x3,0x4e,0x62, 0x2,0x5a,0x3e, + 0x2,0x5a,0x4a, 0x4,0x53,0x53, 0x1,0x72,0x34, 0x2,0x5a,0x45, + 0x2,0x5a,0x47, 0x3,0x52,0x65, 0x1,0x72,0x32, 0x2,0x5a,0x3f, + 0x2,0x5a,0x43, 0x4,0x53,0x50, 0x2,0x5a,0x46, 0x1,0x72,0x30, + 0x1,0x72,0x33, 0x2,0x5a,0x49, 0x2,0x5a,0x41, 0x2,0x5a,0x42, + 0x2,0x5a,0x48, 0x2,0x5a,0x40, 0x2,0x5a,0x44, 0x1,0x72,0x31, + 0x2,0x5f,0x40, 0x2,0x5f,0x3f, 0x1,0x75,0x42, 0x2,0x5f,0x45, + 0x1,0x75,0x44, 0x3,0x56,0x40, 0x4,0x58,0x62, 0x1,0x75,0x41, + 0x2,0x5f,0x41, 0x1,0x75,0x45, 0x2,0x5f,0x42, 0x3,0x56,0x3f, + 0x3,0x56,0x3d, 0x2,0x5f,0x43, 0x2,0x5f,0x46, 0x3,0x56,0x42, + 0x1,0x75,0x43, 0x2,0x63,0x41, 0x3,0x58,0x79, 0x2,0x63,0x44, + 0x3,0x58,0x7a, 0x2,0x63,0x3e, 0x2,0x63,0x40, 0x3,0x58,0x7c, + 0x3,0x58,0x7b, 0x2,0x63,0x3f, 0x2,0x63,0x42, 0x2,0x63,0x43, + 0x2,0x5f,0x44, 0x2,0x63,0x3d, 0x3,0x66,0x4a, 0x1,0x78,0x78, + 0x2,0x66,0x77, 0x2,0x66,0x7a, 0x2,0x66,0x7c, 0x2,0x66,0x75, + 0x2,0x66,0x76, 0x2,0x66,0x79, 0x2,0x66,0x7b, 0x1,0x78,0x79, + 0x1,0x78,0x77, 0x1,0x78,0x76, 0x2,0x66,0x78, 0x2,0x66,0x74, + 0x2,0x69,0x76, 0x1,0x7a,0x3b, 0x3,0x5d,0x29, 0x2,0x69,0x77, + 0x3,0x5d,0x28, 0x2,0x6c,0x38, 0x1,0x7b,0x28, 0x2,0x6c,0x3a, + 0x1,0x7b,0x29, 0x2,0x6c,0x37, 0x2,0x6c,0x39, 0x1,0x7b,0x72, + 0x5,0x74,0x38, 0x2,0x6e,0x21, 0x1,0x7b,0x71, 0x2,0x6f,0x4c, + 0x2,0x6f,0x4b, 0x4,0x6c,0x25, 0x2,0x6f,0x4a, 0xf,0x68,0x4a, + 0x3,0x61,0x49, 0x2,0x71,0x37, 0x2,0x71,0x38, 0x2,0x71,0x3a, + 0x2,0x71,0x39, 0x3,0x61,0x7d, 0x2,0x22,0x70, 0x1,0x48,0x69, + 0x1,0x53,0x51, 0x2,0x39,0x48, 0x1,0x61,0x7d, 0x3,0x66,0x4b, + 0x2,0x47,0x41, 0x1,0x77,0x3b, 0x3,0x5b,0x2f, 0x2,0x66,0x7d, + 0x3,0x60,0x46, 0x3,0x61,0x4a, 0x1,0x4b,0x44, 0x3,0x2f,0x29, + 0x4,0x2f,0x76, 0x4,0x2f,0x75, 0x1,0x5d,0x3d, 0x4,0x35,0x34, + 0x3,0x38,0x76, 0x3,0x38,0x75, 0x1,0x5d,0x3c, 0x3,0x38,0x77, + 0x2,0x40,0x36, 0x1,0x61,0x7e, 0x2,0x40,0x38, 0x2,0x40,0x37, + 0x6,0x4e,0x60, 0x3,0x3e,0x74, 0x2,0x47,0x42, 0x1,0x66,0x57, + 0x2,0x4e,0x2b, 0x2,0x4e,0x2e, 0x2,0x4e,0x2d, 0x4,0x47,0x35, + 0x2,0x4e,0x2c, 0x2,0x54,0x37, 0x2,0x54,0x39, 0x2,0x54,0x38, + 0x3,0x4e,0x65, 0x1,0x72,0x36, 0x3,0x52,0x66, 0x4,0x53,0x59, + 0x3,0x4e,0x64, 0x1,0x72,0x35, 0x3,0x56,0x46, 0x1,0x75,0x46, + 0x2,0x5f,0x47, 0x2,0x5f,0x49, 0x2,0x5f,0x48, 0x3,0x58,0x7e, + 0x3,0x58,0x7d, 0x1,0x77,0x3c, 0x3,0x59,0x21, 0x4,0x61,0x2f, + 0x3,0x5b,0x31, 0x2,0x67,0x21, 0x2,0x66,0x7e, 0xf,0x63,0x77, + 0x2,0x69,0x78, 0x1,0x7a,0x3c, 0x3,0x5d,0x2a, 0x3,0x5e,0x61, + 0x1,0x7b,0x2a, 0x2,0x6e,0x23, 0x2,0x6e,0x22, 0x1,0x7d,0x28, + 0x1,0x4b,0x45, 0x2,0x2d,0x50, 0x1,0x53,0x52, 0x2,0x39,0x4b, + 0x2,0x39,0x49, 0x4,0x35,0x39, 0x4,0x35,0x38, 0x2,0x39,0x4a, + 0x2,0x40,0x3a, 0x2,0x40,0x3b, 0x2,0x47,0x49, 0x2,0x40,0x39, + 0x2,0x47,0x43, 0x2,0x47,0x47, 0x2,0x47,0x46, 0x2,0x47,0x48, + 0x1,0x66,0x58, 0x2,0x47,0x45, 0x2,0x47,0x44, 0x2,0x47,0x4a, + 0x3,0x44,0x54, 0x2,0x4e,0x31, 0x2,0x4e,0x2f, 0x3,0x49,0x5c, + 0x2,0x4e,0x30, 0x2,0x54,0x3c, 0x2,0x54,0x3a, 0x3,0x4e,0x66, + 0x2,0x54,0x3b, 0x2,0x5a,0x4b, 0x2,0x5f,0x4a, 0x2,0x5f,0x4b, + 0x1,0x77,0x3d, 0x3,0x5b,0x32, 0x2,0x67,0x22, 0x2,0x69,0x79, + 0x1,0x7a,0x3d, 0x4,0x61,0x37, 0x2,0x6c,0x3b, 0x2,0x6e,0x24, + 0x1,0x7b,0x73, 0x4,0x69,0x45, 0x2,0x6f,0x4d, 0x2,0x71,0x3b, + 0x1,0x4b,0x46, 0x1,0x53,0x54, 0x1,0x53,0x55, 0x2,0x2d,0x51, + 0x3,0x2f,0x2a, 0x3,0x2f,0x2c, 0x2,0x2d,0x52, 0x1,0x53,0x53, + 0x4,0x2f,0x7c, 0x1,0x58,0x39, 0x3,0x33,0x7b, 0x1,0x58,0x37, + 0x3,0x33,0x7a, 0x1,0x58,0x36, 0x1,0x58,0x3d, 0x1,0x58,0x35, + 0x1,0x58,0x3e, 0x2,0x33,0x21, 0x1,0x58,0x3b, 0x4,0x2f,0x7d, + 0x1,0x58,0x38, 0x1,0x58,0x3c, 0x1,0x58,0x3a, 0x1,0x58,0x34, + 0x3,0x33,0x7c, 0x1,0x5d,0x45, 0x3,0x38,0x7e, 0x1,0x5d,0x3f, + 0x2,0x39,0x4f, 0x1,0x5d,0x44, 0x3,0x39,0x23, 0x3,0x39,0x29, + 0x1,0x5d,0x46, 0x1,0x5d,0x40, 0x6,0x44,0x70, 0x1,0x5d,0x41, + 0x3,0x38,0x79, 0x2,0x39,0x4d, 0x3,0x38,0x7b, 0x3,0x39,0x25, + 0x1,0x5d,0x3e, 0x3,0x39,0x22, 0x2,0x39,0x4e, 0x1,0x5d,0x43, + 0x4,0x35,0x3d, 0x5,0x35,0x5b, 0x2,0x39,0x4c, 0x1,0x5d,0x42, + 0x3,0x38,0x7a, 0x1,0x62,0x2b, 0x3,0x3e,0x7c, 0x1,0x62,0x2d, + 0x4,0x3b,0x2f, 0x3,0x3e,0x7d, 0x2,0x40,0x3e, 0x1,0x62,0x2c, + 0x1,0x62,0x21, 0x1,0x62,0x25, 0x3,0x3f,0x24, 0x1,0x66,0x6b, + 0x2,0x47,0x4f, 0x2,0x40,0x40, 0x1,0x62,0x26, 0x3,0x3e,0x7e, + 0x3,0x3e,0x75, 0x2,0x40,0x43, 0x2,0x40,0x44, 0x1,0x62,0x2a, + 0x4,0x3b,0x30, 0x2,0x40,0x46, 0x3,0x3f,0x21, 0x2,0x40,0x48, + 0x3,0x3f,0x23, 0x2,0x40,0x49, 0x2,0x40,0x3d, 0x2,0x40,0x3c, + 0x2,0x40,0x4a, 0x1,0x62,0x29, 0x2,0x40,0x47, 0x2,0x40,0x45, + 0x4,0x3b,0x2c, 0x1,0x62,0x27, 0x1,0x62,0x23, 0x1,0x62,0x2e, + 0x2,0x40,0x41, 0x2,0x40,0x42, 0x2,0x40,0x3f, 0x3,0x3e,0x78, + 0x1,0x62,0x28, 0x4,0x3b,0x31, 0x3,0x3f,0x22, 0x1,0x62,0x24, + 0x1,0x62,0x22, 0x2,0x47,0x4e, 0x1,0x66,0x66, 0x1,0x66,0x61, + 0x3,0x44,0x60, 0x3,0x44,0x59, 0x1,0x66,0x5c, 0x3,0x44,0x63, + 0x1,0x66,0x6c, 0x1,0x66,0x5d, 0x3,0x44,0x55, 0x1,0x66,0x59, + 0x1,0x66,0x68, 0x1,0x66,0x65, 0x1,0x66,0x67, 0x3,0x44,0x58, + 0x1,0x66,0x5e, 0x1,0x66,0x63, 0x1,0x66,0x5a, 0x1,0x66,0x5b, + 0x2,0x47,0x56, 0x2,0x47,0x53, 0x2,0x47,0x4b, 0x2,0x47,0x50, + 0x3,0x44,0x5b, 0x1,0x66,0x69, 0x2,0x47,0x57, 0x1,0x66,0x6a, + 0x1,0x66,0x60, 0x3,0x44,0x5c, 0x3,0x44,0x61, 0x2,0x47,0x4d, + 0x3,0x44,0x56, 0x2,0x47,0x55, 0x2,0x47,0x51, 0x2,0x47,0x54, + 0x2,0x47,0x52, 0x1,0x66,0x64, 0x2,0x47,0x4c, 0x1,0x66,0x5f, + 0x3,0x44,0x5d, 0x2,0x4e,0x34, 0x1,0x6b,0x22, 0x1,0x6b,0x25, + 0x3,0x49,0x5f, 0x2,0x4e,0x36, 0x3,0x49,0x64, 0x1,0x6b,0x2d, + 0x2,0x4e,0x35, 0x1,0x6b,0x27, 0x3,0x49,0x63, 0x1,0x6e,0x78, + 0x2,0x4e,0x37, 0x4,0x47,0x45, 0x1,0x6b,0x2c, 0x2,0x4e,0x33, + 0x1,0x6b,0x2e, 0x3,0x49,0x5e, 0x3,0x49,0x62, 0x3,0x49,0x6b, + 0x1,0x6b,0x23, 0x3,0x49,0x68, 0x1,0x66,0x62, 0x1,0x6b,0x26, + 0x3,0x49,0x60, 0x1,0x6b,0x24, 0x1,0x6b,0x28, 0x1,0x6b,0x2a, + 0x1,0x6b,0x21, 0x1,0x6b,0x2f, 0x1,0x6b,0x2b, 0x3,0x49,0x65, + 0x1,0x6b,0x29, 0x2,0x4e,0x32, 0x3,0x49,0x66, 0xf,0x4c,0x41, + 0x3,0x4e,0x74, 0x1,0x6f,0x21, 0x3,0x4e,0x67, 0x1,0x6e,0x7b, + 0x3,0x4e,0x72, 0x3,0x4e,0x70, 0x3,0x4e,0x6e, 0x1,0x6f,0x24, + 0x3,0x4e,0x6c, 0x2,0x54,0x3f, 0x1,0x6f,0x25, 0x2,0x54,0x4b, + 0x2,0x54,0x44, 0x1,0x6e,0x74, 0x2,0x54,0x4c, 0x2,0x54,0x46, + 0x1,0x6e,0x7e, 0x2,0x54,0x47, 0x3,0x4e,0x73, 0x1,0x6e,0x7d, + 0x2,0x54,0x4a, 0x1,0x6e,0x77, 0x2,0x54,0x48, 0x2,0x54,0x3e, + 0x1,0x6e,0x76, 0x2,0x5a,0x56, 0x1,0x6e,0x7c, 0x3,0x4e,0x75, + 0x1,0x6e,0x79, 0x3,0x4e,0x69, 0x1,0x6f,0x23, 0x3,0x4e,0x6a, + 0x2,0x54,0x3d, 0x3,0x4e,0x76, 0x2,0x54,0x41, 0x1,0x6e,0x75, + 0x2,0x54,0x40, 0x2,0x54,0x42, 0x2,0x54,0x43, 0x1,0x6f,0x22, + 0x2,0x54,0x45, 0x2,0x54,0x49, 0x2,0x54,0x4d, 0x1,0x6f,0x26, + 0x1,0x72,0x3c, 0x2,0x5a,0x51, 0x2,0x5a,0x57, 0x2,0x5a,0x54, + 0x2,0x5a,0x4c, 0x2,0x5a,0x58, 0x2,0x5a,0x4d, 0x3,0x52,0x6a, + 0x2,0x5a,0x53, 0x3,0x52,0x6b, 0x1,0x72,0x37, 0x1,0x72,0x3d, + 0x2,0x5a,0x59, 0x3,0x4e,0x6f, 0x3,0x52,0x67, 0x1,0x72,0x39, + 0x3,0x52,0x6e, 0x1,0x72,0x43, 0x1,0x72,0x3e, 0x2,0x5a,0x5b, + 0x2,0x5a,0x55, 0x1,0x72,0x3a, 0x2,0x5a,0x4e, 0x1,0x72,0x44, + 0x2,0x5a,0x4f, 0x2,0x5a,0x50, 0x1,0x72,0x45, 0x1,0x72,0x42, + 0x1,0x6e,0x7a, 0x3,0x52,0x69, 0x1,0x72,0x38, 0x2,0x5a,0x5c, + 0x1,0x72,0x46, 0x3,0x52,0x68, 0x1,0x72,0x3f, 0x2,0x5a,0x5a, + 0x1,0x72,0x3b, 0x1,0x72,0x40, 0x1,0x72,0x41, 0x3,0x66,0x4c, + 0x1,0x75,0x4e, 0x2,0x5f,0x50, 0x2,0x5f,0x59, 0x2,0x5f,0x56, + 0x2,0x5f,0x58, 0x3,0x56,0x49, 0x1,0x75,0x4b, 0x2,0x5f,0x51, + 0x3,0x56,0x4a, 0x2,0x5f,0x57, 0x1,0x75,0x47, 0x2,0x5f,0x53, + 0x1,0x75,0x4f, 0x2,0x5f,0x4f, 0x2,0x5f,0x54, 0x2,0x5f,0x5b, + 0x2,0x5a,0x52, 0x2,0x5f,0x55, 0x2,0x5f,0x4e, 0x1,0x75,0x48, + 0x2,0x5f,0x4d, 0x1,0x75,0x49, 0x2,0x5f,0x5c, 0x1,0x75,0x4a, + 0x2,0x5f,0x5a, 0x1,0x75,0x4d, 0x2,0x5f,0x4c, 0x3,0x56,0x48, + 0x1,0x75,0x4c, 0x2,0x5f,0x52, 0x2,0x63,0x47, 0x2,0x63,0x55, + 0x2,0x63,0x50, 0x2,0x63,0x52, 0x2,0x63,0x46, 0x1,0x77,0x3e, + 0x3,0x59,0x2a, 0x2,0x63,0x45, 0x1,0x77,0x41, 0x1,0x77,0x40, + 0x3,0x59,0x26, 0x2,0x63,0x54, 0x2,0x63,0x4c, 0x2,0x63,0x49, + 0x2,0x63,0x4f, 0x3,0x59,0x24, 0x2,0x63,0x48, 0x3,0x59,0x28, + 0x2,0x63,0x4a, 0x2,0x63,0x53, 0x2,0x63,0x51, 0x3,0x59,0x23, + 0x1,0x77,0x3f, 0x2,0x63,0x58, 0x2,0x63,0x56, 0x2,0x63,0x4d, + 0x2,0x63,0x57, 0x2,0x63,0x4e, 0x3,0x5b,0x34, 0x2,0x67,0x26, + 0x1,0x78,0x7a, 0x2,0x67,0x2d, 0x3,0x5b,0x35, 0x4,0x61,0x3a, + 0x2,0x6c,0x3e, 0x1,0x79,0x23, 0x2,0x63,0x4b, 0x2,0x67,0x24, + 0x1,0x78,0x7d, 0x2,0x67,0x25, 0x2,0x67,0x2a, 0x3,0x5b,0x36, + 0x3,0x5d,0x33, 0x1,0x79,0x21, 0x1,0x79,0x22, 0x2,0x67,0x23, + 0x2,0x67,0x2c, 0x2,0x67,0x2e, 0x2,0x67,0x27, 0x2,0x67,0x29, + 0x2,0x67,0x2b, 0x2,0x67,0x28, 0x2,0x67,0x2f, 0x1,0x78,0x7c, + 0x1,0x79,0x24, 0x1,0x78,0x7e, 0x1,0x78,0x7b, 0x2,0x69,0x7c, + 0x4,0x64,0x4d, 0x1,0x7a,0x42, 0x2,0x69,0x7a, 0x3,0x5d,0x30, + 0x3,0x5d,0x2c, 0x2,0x69,0x7e, 0x3,0x5d,0x32, 0x2,0x6a,0x21, + 0x1,0x7a,0x40, 0x2,0x6a,0x22, 0x2,0x69,0x7d, 0x3,0x5d,0x2b, + 0x2,0x69,0x7b, 0x1,0x7a,0x43, 0x1,0x7a,0x3f, 0x2,0x6a,0x23, + 0x3,0x5d,0x2e, 0x1,0x7a,0x41, 0x1,0x7a,0x3e, 0x3,0x5c,0x6d, + 0x4,0x67,0x3b, 0x1,0x7b,0x2b, 0x3,0x5e,0x62, 0x4,0x67,0x41, + 0x1,0x7b,0x2c, 0x2,0x6c,0x3d, 0x2,0x6c,0x3c, 0x2,0x6c,0x3f, + 0x2,0x6c,0x40, 0x3,0x5e,0x63, 0x1,0x7b,0x2d, 0x2,0x6e,0x25, + 0x2,0x6e,0x2a, 0x1,0x7b,0x74, 0x3,0x5f,0x61, 0x2,0x6e,0x27, + 0x3,0x5f,0x62, 0x2,0x6e,0x26, 0x2,0x6e,0x29, 0x2,0x6e,0x28, + 0x3,0x60,0x48, 0x2,0x6f,0x51, 0x4,0x6a,0x7c, 0x1,0x7c,0x48, + 0x2,0x6f,0x50, 0x2,0x6f,0x4e, 0x3,0x60,0x47, 0x2,0x6f,0x4f, + 0x3,0x60,0x49, 0x3,0x60,0x7b, 0x1,0x7c,0x6a, 0x1,0x7c,0x69, + 0x2,0x70,0x4f, 0x2,0x70,0x50, 0x1,0x7c,0x6b, 0x3,0x61,0x4b, + 0x2,0x71,0x3c, 0x2,0x71,0x3d, 0x1,0x7d,0x34, 0x3,0x61,0x6b, + 0x1,0x7d,0x3a, 0x3,0x61,0x7e, 0x2,0x71,0x77, 0x2,0x72,0x36, + 0x1,0x4b,0x47, 0x5,0x30,0x46, 0x2,0x39,0x50, 0x3,0x39,0x2a, + 0x2,0x39,0x51, 0x2,0x47,0x58, 0x2,0x4e,0x38, 0x2,0x54,0x4e, + 0x1,0x75,0x51, 0x3,0x56,0x4d, 0x1,0x75,0x50, 0x2,0x63,0x59, + 0x2,0x67,0x30, 0x3,0x5f,0x64, 0x2,0x6f,0x52, 0x1,0x4b,0x48, + 0x2,0x33,0x22, 0x1,0x58,0x3f, 0x1,0x5d,0x47, 0x2,0x47,0x5a, + 0x2,0x47,0x59, 0x1,0x6f,0x27, 0x2,0x54,0x4f, 0x1,0x6f,0x28, + 0x2,0x5f,0x5d, 0x1,0x77,0x42, 0x3,0x5d,0x34, 0x3,0x66,0x4d, + 0x3,0x62,0x21, 0x1,0x7d,0x43, 0x1,0x4b,0x49, 0x2,0x28,0x6b, + 0x2,0x33,0x23, 0x3,0x39,0x2d, 0x4,0x35,0x4d, 0x1,0x5d,0x48, + 0x3,0x39,0x2c, 0x2,0x39,0x52, 0x2,0x39,0x53, 0x3,0x3f,0x2a, + 0x2,0x40,0x4b, 0x3,0x3f,0x29, 0x1,0x62,0x2f, 0x1,0x66,0x6d, + 0x3,0x44,0x64, 0x2,0x47,0x5c, 0x2,0x47,0x5b, 0x2,0x47,0x5d, + 0x3,0x49,0x6d, 0x2,0x4e,0x39, 0x2,0x4e,0x3a, 0x1,0x6b,0x30, + 0x1,0x72,0x47, 0x1,0x6f,0x29, 0x1,0x72,0x48, 0x2,0x5f,0x61, + 0x2,0x5f,0x5e, 0x2,0x5f,0x60, 0x2,0x5f,0x5f, 0x1,0x75,0x52, + 0x3,0x59,0x2b, 0x2,0x63,0x5a, 0x2,0x67,0x32, 0x2,0x67,0x31, + 0x2,0x25,0x24, 0x1,0x58,0x41, 0x1,0x58,0x40, 0x2,0x33,0x24, + 0x3,0x39,0x2e, 0x2,0x39,0x54, 0x3,0x3f,0x2c, 0x3,0x3f,0x2b, + 0x2,0x40,0x4d, 0x2,0x40,0x4c, 0x1,0x62,0x30, 0x3,0x3f,0x2d, + 0x2,0x47,0x5f, 0x2,0x47,0x60, 0x2,0x47,0x5e, 0x4,0x40,0x78, + 0x3,0x44,0x65, 0x1,0x66,0x6f, 0x1,0x66,0x6e, 0x4,0x47,0x54, + 0x1,0x6b,0x32, 0x1,0x6b,0x31, 0x3,0x4e,0x7a, 0x2,0x54,0x50, + 0x2,0x5a,0x5f, 0x2,0x5a,0x5d, 0x2,0x5a,0x5e, 0x1,0x72,0x49, + 0x2,0x5f,0x63, 0x2,0x5f,0x62, 0x3,0x56,0x4f, 0x2,0x63,0x5d, + 0x2,0x63,0x5c, 0x2,0x63,0x5b, 0x2,0x67,0x33, 0x3,0x61,0x4d, + 0x2,0x71,0x78, 0x1,0x4b,0x4a, 0x1,0x53,0x56, 0x3,0x2f,0x2e, + 0x1,0x53,0x57, 0x1,0x58,0x42, 0x1,0x58,0x43, 0x2,0x33,0x26, + 0x2,0x33,0x25, 0x2,0x39,0x55, 0x3,0x39,0x30, 0x1,0x5d,0x4e, + 0x1,0x5d,0x4c, 0x1,0x5d,0x49, 0x1,0x5d,0x4d, 0x1,0x5d,0x4b, + 0x1,0x5d,0x4a, 0x3,0x39,0x32, 0x3,0x39,0x31, 0x1,0x62,0x31, + 0x2,0x40,0x50, 0x3,0x3f,0x2f, 0x1,0x66,0x74, 0x1,0x62,0x33, + 0x1,0x62,0x38, 0x2,0x40,0x52, 0x1,0x62,0x3a, 0x1,0x62,0x39, + 0x1,0x62,0x3c, 0x2,0x40,0x51, 0x2,0x40,0x4e, 0x1,0x62,0x36, + 0x1,0x62,0x32, 0x1,0x62,0x34, 0x2,0x40,0x4f, 0x1,0x62,0x3b, + 0x1,0x62,0x37, 0x1,0x62,0x35, 0x1,0x66,0x76, 0x1,0x66,0x75, + 0x1,0x66,0x73, 0x1,0x66,0x77, 0x4,0x40,0x7e, 0x1,0x66,0x71, + 0x1,0x66,0x72, 0x3,0x44,0x69, 0x1,0x66,0x70, 0x5,0x43,0x2d, + 0x2,0x47,0x61, 0x3,0x44,0x67, 0x2,0x4e,0x3c, 0x3,0x49,0x70, + 0x1,0x6b,0x34, 0x1,0x6b,0x35, 0x1,0x6b,0x33, 0x3,0x49,0x72, + 0x2,0x4e,0x3b, 0x3,0x49,0x71, 0x2,0x4e,0x3d, 0x3,0x66,0x4e, + 0x2,0x54,0x53, 0x2,0x54,0x55, 0x3,0x4e,0x7e, 0x1,0x6f,0x32, + 0x2,0x54,0x56, 0x1,0x6f,0x2b, 0x2,0x54,0x52, 0x1,0x6f,0x2a, + 0x1,0x6f,0x34, 0x1,0x6f,0x30, 0x1,0x6f,0x31, 0x1,0x6f,0x2d, + 0x2,0x54,0x51, 0x1,0x6f,0x2c, 0x2,0x54,0x57, 0x2,0x54,0x54, + 0x3,0x4e,0x7d, 0x1,0x6f,0x33, 0x3,0x4f,0x22, 0x1,0x6f,0x2e, + 0x1,0x6f,0x2f, 0x2,0x5a,0x61, 0x3,0x52,0x75, 0x2,0x5a,0x63, + 0x2,0x5a,0x62, 0x3,0x52,0x73, 0x2,0x5a,0x64, 0x1,0x72,0x4a, + 0x2,0x5a,0x60, 0x3,0x56,0x51, 0x3,0x56,0x52, 0x1,0x75,0x56, + 0x2,0x5f,0x64, 0x1,0x75,0x53, 0x1,0x75,0x57, 0x1,0x75,0x55, + 0x1,0x75,0x54, 0x2,0x63,0x5e, 0x4,0x5d,0x69, 0x2,0x63,0x61, + 0x7,0x43,0x52, 0x2,0x63,0x60, 0x3,0x59,0x2e, 0x2,0x63,0x5f, + 0x1,0x77,0x43, 0x2,0x67,0x34, 0x2,0x67,0x35, 0x1,0x79,0x25, + 0x2,0x67,0x36, 0x1,0x79,0x26, 0x3,0x5b,0x38, 0x3,0x66,0x4f, + 0x1,0x7a,0x45, 0x4,0x64,0x4f, 0x1,0x7a,0x44, 0x2,0x6c,0x41, + 0x3,0x5e,0x65, 0x3,0x5e,0x66, 0x1,0x7b,0x2e, 0x2,0x6c,0x42, + 0x2,0x6e,0x2b, 0x1,0x7b,0x75, 0x1,0x7b,0x76, 0x3,0x66,0x50, + 0x2,0x6f,0x53, 0x3,0x60,0x4a, 0x1,0x7c,0x6d, 0x3,0x61,0x4e, + 0x1,0x4b,0x4b, 0x3,0x39,0x33, 0x1,0x5d,0x50, 0x1,0x5d,0x4f, + 0x2,0x47,0x62, 0x2,0x47,0x63, 0x1,0x6b,0x36, 0x2,0x5a,0x65, + 0x1,0x6f,0x35, 0x2,0x5a,0x66, 0x2,0x5f,0x65, 0x1,0x4b,0x4c, + 0x3,0x24,0x3a, 0x2,0x2d,0x53, 0x1,0x53,0x59, 0x1,0x53,0x58, + 0x2,0x33,0x27, 0x1,0x58,0x44, 0x2,0x33,0x28, 0x2,0x39,0x58, + 0x3,0x39,0x39, 0x2,0x39,0x57, 0x3,0x39,0x37, 0x2,0x39,0x56, + 0x3,0x39,0x35, 0x3,0x39,0x38, 0x2,0x40,0x54, 0x1,0x62,0x3f, + 0x3,0x3f,0x39, 0x3,0x3f,0x34, 0x2,0x40,0x53, 0x1,0x62,0x3e, + 0x3,0x3f,0x37, 0x3,0x3f,0x30, 0x3,0x3f,0x33, 0x2,0x40,0x55, + 0x1,0x62,0x3d, 0x3,0x3f,0x38, 0x2,0x47,0x65, 0x2,0x47,0x68, + 0x2,0x47,0x66, 0x2,0x47,0x67, 0x2,0x47,0x6b, 0x2,0x47,0x64, + 0x2,0x47,0x6c, 0x2,0x47,0x69, 0x2,0x47,0x6a, 0x1,0x6b,0x38, + 0x2,0x4e,0x3e, 0x3,0x49,0x75, 0x3,0x49,0x73, 0x1,0x6b,0x37, + 0x3,0x49,0x74, 0x2,0x54,0x5b, 0x2,0x54,0x59, 0x3,0x4f,0x26, + 0x4,0x4d,0x75, 0x1,0x6f,0x36, 0x2,0x54,0x58, 0x2,0x54,0x5a, + 0x3,0x4f,0x25, 0x1,0x6f,0x37, 0x3,0x4f,0x23, 0x2,0x5a,0x67, + 0x3,0x52,0x77, 0x2,0x5a,0x68, 0x1,0x75,0x58, 0x3,0x59,0x31, + 0x2,0x67,0x38, 0x2,0x67,0x3a, 0x2,0x67,0x37, 0x2,0x67,0x39, + 0x2,0x6a,0x24, 0x2,0x6c,0x43, 0x3,0x66,0x51, 0x2,0x71,0x5e, + 0x1,0x4b,0x4d, 0x1,0x53,0x5a, 0x2,0x33,0x29, 0x2,0x33,0x2b, + 0x2,0x33,0x2a, 0x2,0x39,0x5b, 0x1,0x5d,0x52, 0x3,0x39,0x3e, + 0x2,0x39,0x59, 0x3,0x39,0x3a, 0x1,0x5d,0x51, 0x2,0x39,0x5c, + 0x3,0x39,0x3d, 0x2,0x39,0x5d, 0x2,0x39,0x5a, 0x6,0x45,0x38, + 0x2,0x40,0x61, 0x1,0x62,0x47, 0x2,0x40,0x59, 0x2,0x40,0x5f, + 0x3,0x3f,0x3f, 0x3,0x3f,0x3a, 0x1,0x62,0x42, 0x1,0x62,0x45, + 0x2,0x40,0x58, 0x1,0x62,0x40, 0x2,0x40,0x5c, 0x2,0x47,0x72, + 0x1,0x62,0x44, 0x3,0x3f,0x3b, 0x2,0x40,0x57, 0x3,0x3f,0x3e, + 0x2,0x40,0x5d, 0x2,0x40,0x5a, 0x2,0x40,0x60, 0x2,0x40,0x56, + 0x2,0x40,0x5e, 0x1,0x62,0x43, 0x1,0x62,0x46, 0x2,0x40,0x5b, + 0x1,0x62,0x41, 0x1,0x66,0x79, 0x2,0x47,0x6e, 0x1,0x66,0x78, + 0x2,0x47,0x75, 0x2,0x47,0x74, 0x1,0x67,0x21, 0x1,0x67,0x22, + 0x2,0x47,0x76, 0x1,0x66,0x7a, 0x2,0x47,0x73, 0x1,0x66,0x7e, + 0x2,0x47,0x78, 0x2,0x47,0x6f, 0x3,0x44,0x6b, 0x2,0x47,0x71, + 0x1,0x66,0x7b, 0x2,0x47,0x6d, 0x2,0x47,0x70, 0x2,0x47,0x77, + 0x1,0x66,0x7c, 0x2,0x47,0x79, 0x1,0x66,0x7d, 0x1,0x6b,0x39, + 0x2,0x4e,0x43, 0x2,0x4e,0x49, 0x2,0x4e,0x41, 0x2,0x4e,0x4a, + 0x3,0x49,0x7b, 0x2,0x4e,0x40, 0x2,0x4e,0x45, 0x2,0x4e,0x4b, + 0x2,0x4e,0x48, 0x2,0x4e,0x47, 0x2,0x4e,0x46, 0x3,0x49,0x7a, + 0x2,0x4e,0x3f, 0x2,0x4e,0x44, 0x3,0x49,0x79, 0x2,0x4e,0x42, + 0x1,0x6f,0x3c, 0x1,0x6f,0x39, 0x2,0x54,0x64, 0x2,0x54,0x69, + 0x2,0x54,0x6b, 0x2,0x54,0x68, 0x2,0x54,0x61, 0x2,0x54,0x63, + 0x2,0x54,0x6d, 0x2,0x54,0x6a, 0x2,0x54,0x65, 0x2,0x54,0x6e, + 0x2,0x54,0x62, 0x2,0x54,0x6c, 0x1,0x6f,0x3a, 0x1,0x6f,0x40, + 0x1,0x6f,0x3e, 0x2,0x54,0x5c, 0x1,0x6f,0x3f, 0x1,0x6f,0x3b, + 0x2,0x54,0x5d, 0x2,0x54,0x5f, 0x2,0x54,0x5e, 0x2,0x54,0x66, + 0x2,0x54,0x67, 0x3,0x4f,0x2c, 0x1,0x6f,0x3d, 0x3,0x4f,0x2b, + 0x1,0x6f,0x38, 0x2,0x54,0x60, 0x2,0x5a,0x72, 0x1,0x72,0x4c, + 0x3,0x52,0x7e, 0x2,0x5a,0x69, 0x1,0x72,0x4d, 0x1,0x72,0x50, + 0x2,0x5a,0x6e, 0x5,0x51,0x48, 0x2,0x5a,0x6b, 0x1,0x72,0x4f, + 0x4,0x54,0x29, 0x3,0x52,0x7b, 0x2,0x5a,0x6f, 0x2,0x5a,0x70, + 0x2,0x5a,0x6a, 0x2,0x5a,0x73, 0x2,0x5a,0x6c, 0x2,0x5a,0x71, + 0x1,0x72,0x4e, 0x3,0x52,0x7c, 0x1,0x72,0x4b, 0x2,0x5a,0x6d, + 0x3,0x56,0x54, 0x2,0x5f,0x6b, 0x1,0x75,0x5b, 0x1,0x75,0x59, + 0x1,0x75,0x5c, 0x1,0x75,0x5a, 0x2,0x5f,0x6a, 0x2,0x5f,0x67, + 0x2,0x5f,0x66, 0x3,0x56,0x55, 0x2,0x5f,0x69, 0x4,0x59,0x2d, + 0x2,0x5f,0x68, 0x2,0x63,0x6f, 0x1,0x77,0x49, 0x2,0x63,0x66, + 0x2,0x63,0x65, 0x3,0x59,0x32, 0x1,0x77,0x44, 0x2,0x63,0x6b, + 0x2,0x63,0x6a, 0x2,0x63,0x62, 0x2,0x63,0x6d, 0x2,0x63,0x67, + 0x1,0x77,0x48, 0x2,0x63,0x64, 0x2,0x63,0x6c, 0x2,0x63,0x63, + 0x1,0x77,0x45, 0x1,0x77,0x47, 0x2,0x63,0x68, 0x1,0x77,0x46, + 0x2,0x63,0x69, 0x3,0x5b,0x3a, 0x2,0x63,0x6e, 0x2,0x67,0x3e, + 0x3,0x5b,0x39, 0x1,0x79,0x2b, 0x2,0x67,0x3b, 0x4,0x61,0x52, + 0x2,0x67,0x3f, 0x3,0x5b,0x3b, 0x4,0x61,0x4f, 0x1,0x79,0x28, + 0x2,0x67,0x3d, 0x1,0x79,0x2d, 0x3,0x5b,0x3c, 0x1,0x79,0x2a, + 0x3,0x5b,0x3d, 0x2,0x67,0x3c, 0x4,0x61,0x54, 0x1,0x79,0x2c, + 0x2,0x67,0x40, 0x1,0x79,0x27, 0x1,0x7a,0x47, 0x1,0x7a,0x49, + 0x3,0x5d,0x37, 0x2,0x6a,0x27, 0x1,0x7a,0x48, 0x2,0x6a,0x25, + 0x1,0x79,0x29, 0x2,0x6a,0x26, 0x1,0x7a,0x46, 0x1,0x7b,0x2f, + 0x1,0x7b,0x31, 0x2,0x6c,0x45, 0x1,0x7b,0x30, 0x2,0x6c,0x44, + 0x2,0x6e,0x30, 0x1,0x7b,0x77, 0x2,0x6e,0x2f, 0x1,0x7b,0x78, + 0x2,0x6e,0x2d, 0x2,0x6e,0x2c, 0x2,0x6e,0x31, 0x2,0x6e,0x32, + 0x2,0x6f,0x54, 0x3,0x60,0x4b, 0x2,0x6e,0x2e, 0x2,0x70,0x54, + 0x2,0x70,0x51, 0x2,0x70,0x52, 0x2,0x70,0x53, 0x1,0x7d,0x29, + 0x3,0x61,0x50, 0x2,0x71,0x40, 0x2,0x71,0x3f, 0x2,0x71,0x3e, + 0x2,0x71,0x5f, 0x3,0x61,0x6c, 0x2,0x72,0x2e, 0x2,0x71,0x79, + 0x1,0x7d,0x3b, 0x1,0x4b,0x4e, 0x1,0x58,0x45, 0x3,0x39,0x3f, + 0xf,0x38,0x6c, 0x3,0x39,0x40, 0x3,0x3f,0x40, 0x3,0x44,0x73, + 0x1,0x67,0x23, 0x3,0x49,0x7d, 0x3,0x49,0x7c, 0x3,0x4f,0x30, + 0x3,0x4f,0x32, 0x3,0x4f,0x2f, 0x3,0x4f,0x31, 0x1,0x6f,0x41, + 0x3,0x66,0x52, 0x2,0x5a,0x74, 0xf,0x58,0x33, 0x3,0x59,0x35, + 0x1,0x77,0x4a, 0x3,0x59,0x36, 0x2,0x67,0x41, 0x3,0x5b,0x3f, + 0x4,0x61,0x56, 0x3,0x5d,0x38, 0x4,0x67,0x51, 0x2,0x71,0x7a, + 0x1,0x4b,0x4f, 0x1,0x4f,0x51, 0x1,0x53,0x5c, 0x1,0x53,0x5b, + 0x5,0x30,0x55, 0x1,0x58,0x48, 0x3,0x34,0x21, 0x2,0x33,0x2c, + 0x1,0x58,0x46, 0x2,0x33,0x2d, 0x1,0x58,0x47, 0x3,0x66,0x53, + 0x3,0x39,0x41, 0x2,0x39,0x62, 0x2,0x39,0x5e, 0x3,0x39,0x47, + 0x4,0x35,0x63, 0x1,0x5d,0x53, 0x2,0x39,0x61, 0x2,0x39,0x60, + 0x2,0x39,0x5f, 0x1,0x5d,0x54, 0x2,0x39,0x63, 0x2,0x39,0x64, + 0x3,0x3f,0x45, 0x2,0x40,0x68, 0x2,0x40,0x66, 0x2,0x40,0x6a, + 0x2,0x40,0x6b, 0x2,0x40,0x71, 0x3,0x3f,0x47, 0x2,0x40,0x6d, + 0x2,0x40,0x6f, 0x5,0x43,0x50, 0x2,0x40,0x67, 0x2,0x40,0x62, + 0x4,0x3b,0x55, 0x2,0x40,0x6e, 0x3,0x3f,0x44, 0x3,0x3f,0x46, + 0x2,0x40,0x70, 0x2,0x40,0x69, 0x2,0x40,0x6c, 0x2,0x40,0x63, + 0x1,0x62,0x49, 0x2,0x40,0x65, 0x2,0x40,0x64, 0x1,0x62,0x48, + 0x1,0x62,0x4a, 0x3,0x3f,0x49, 0x1,0x67,0x26, 0x2,0x47,0x7b, + 0x2,0x47,0x7d, 0x2,0x47,0x7c, 0x2,0x48,0x23, 0x1,0x67,0x24, + 0x3,0x44,0x76, 0x2,0x47,0x7e, 0x2,0x47,0x7a, 0x2,0x48,0x21, + 0x2,0x48,0x22, 0x1,0x67,0x25, 0x1,0x67,0x27, 0x2,0x48,0x24, + 0x2,0x4e,0x4f, 0x2,0x4e,0x4e, 0x4,0x47,0x6a, 0x2,0x4e,0x4c, + 0x2,0x4e,0x4d, 0x1,0x6b,0x3b, 0x1,0x6b,0x3d, 0x1,0x6b,0x3a, + 0x1,0x6b,0x3c, 0x2,0x54,0x75, 0x2,0x54,0x76, 0x2,0x54,0x71, + 0x3,0x4f,0x36, 0x2,0x54,0x72, 0x1,0x6f,0x43, 0x1,0x6f,0x48, + 0x1,0x6f,0x42, 0x1,0x6f,0x49, 0x1,0x6f,0x44, 0x2,0x54,0x73, + 0x4,0x4e,0x2d, 0x3,0x4f,0x33, 0x2,0x54,0x74, 0x2,0x54,0x70, + 0x1,0x6f,0x4a, 0x1,0x6f,0x46, 0x3,0x4f,0x35, 0x4,0x4e,0x2b, + 0x1,0x6f,0x45, 0x1,0x6f,0x47, 0x3,0x4f,0x34, 0x2,0x54,0x6f, + 0x3,0x53,0x24, 0x2,0x5a,0x76, 0x1,0x72,0x52, 0x3,0x53,0x22, + 0x3,0x53,0x21, 0x2,0x5a,0x78, 0x1,0x72,0x54, 0x2,0x5a,0x7b, + 0x2,0x5a,0x77, 0x2,0x5a,0x75, 0x2,0x5a,0x7a, 0x1,0x72,0x53, + 0x2,0x5a,0x79, 0x7,0x34,0x32, 0x1,0x72,0x51, 0x3,0x53,0x25, + 0x3,0x56,0x59, 0x1,0x75,0x5e, 0x1,0x75,0x61, 0x2,0x5f,0x6d, + 0x3,0x56,0x5a, 0x1,0x75,0x5f, 0x2,0x5f,0x6c, 0x1,0x75,0x5d, + 0x1,0x75,0x60, 0x2,0x63,0x70, 0x2,0x63,0x71, 0x2,0x63,0x72, + 0x1,0x77,0x4b, 0x3,0x59,0x37, 0x2,0x63,0x73, 0x1,0x77,0x4c, + 0x1,0x79,0x2f, 0x2,0x67,0x44, 0x2,0x67,0x45, 0x2,0x67,0x43, + 0x2,0x67,0x42, 0x2,0x67,0x46, 0x1,0x79,0x2e, 0x2,0x6a,0x2b, + 0x2,0x6a,0x29, 0x2,0x6a,0x2a, 0x2,0x6a,0x2c, 0x2,0x6a,0x28, + 0x2,0x6a,0x2d, 0x2,0x6c,0x47, 0x3,0x5e,0x67, 0x2,0x6c,0x48, + 0x2,0x6c,0x46, 0x1,0x7b,0x32, 0x2,0x6e,0x33, 0x1,0x7b,0x79, + 0x2,0x6e,0x34, 0x2,0x6f,0x56, 0x2,0x6f,0x55, 0x3,0x62,0x22, + 0x1,0x4b,0x50, 0x1,0x62,0x4b, 0x3,0x3f,0x4b, 0x3,0x44,0x77, + 0x1,0x67,0x28, 0x3,0x44,0x78, 0x3,0x4a,0x21, 0x3,0x4a,0x22, + 0x1,0x6b,0x3e, 0x3,0x4f,0x37, 0x3,0x53,0x27, 0x1,0x72,0x56, + 0x3,0x53,0x26, 0x1,0x72,0x55, 0x3,0x66,0x54, 0x3,0x59,0x38, + 0x1,0x79,0x30, 0x1,0x7a,0x29, 0x1,0x7b,0x33, 0x1,0x4b,0x51, + 0x1,0x58,0x49, 0x1,0x67,0x29, 0x3,0x4f,0x39, 0x2,0x67,0x47, + 0x3,0x27,0x2f, 0x4,0x21,0x54, 0xf,0x21,0x6a, 0x4,0x23,0x30, + 0x3,0x24,0x3b, 0xf,0x22,0x71, 0xf,0x22,0x72, 0x3,0x27,0x30, + 0x2,0x25,0x26, 0x4,0x25,0x21, 0x3,0x27,0x33, 0x1,0x4b,0x52, + 0x4,0x25,0x23, 0x1,0x4b,0x55, 0x1,0x4b,0x54, 0x1,0x4b,0x53, + 0x3,0x27,0x31, 0xf,0x25,0x32, 0x2,0x25,0x25, 0x3,0x2a,0x72, + 0x2,0x28,0x6d, 0x3,0x2a,0x70, 0x2,0x28,0x6f, 0x1,0x4f,0x52, + 0x3,0x2a,0x74, 0x4,0x28,0x26, 0x1,0x4f,0x54, 0x2,0x28,0x6c, + 0x2,0x28,0x6e, 0x1,0x4f,0x53, 0x2,0x28,0x71, 0x2,0x28,0x70, + 0x2,0x28,0x72, 0x3,0x2a,0x73, 0x3,0x2a,0x71, 0xf,0x28,0x71, + 0xf,0x28,0x6e, 0x2,0x2d,0x57, 0x2,0x2d,0x55, 0x1,0x53,0x5f, + 0x2,0x2d,0x54, 0x1,0x53,0x64, 0x1,0x53,0x61, 0x1,0x53,0x5e, + 0x3,0x2f,0x31, 0x1,0x53,0x65, 0x3,0x2f,0x32, 0x1,0x53,0x60, + 0x1,0x53,0x63, 0x6,0x34,0x60, 0x1,0x53,0x62, 0x2,0x2d,0x56, + 0x3,0x2f,0x33, 0x1,0x53,0x5d, 0x3,0x2f,0x30, 0x1,0x58,0x4f, + 0x2,0x33,0x2f, 0x2,0x33,0x35, 0x1,0x58,0x4c, 0x1,0x58,0x53, + 0x3,0x34,0x25, 0x1,0x58,0x4e, 0x2,0x33,0x32, 0x2,0x33,0x34, + 0x1,0x58,0x51, 0x2,0x33,0x2e, 0x2,0x33,0x31, 0x1,0x58,0x4d, + 0x1,0x58,0x4a, 0x2,0x33,0x30, 0x1,0x58,0x50, 0x2,0x33,0x33, + 0x1,0x58,0x52, 0x1,0x58,0x4b, 0x4,0x30,0x2f, 0x3,0x34,0x27, + 0x3,0x34,0x26, 0x2,0x39,0x66, 0x2,0x39,0x69, 0x1,0x5d,0x56, + 0x3,0x39,0x4b, 0x1,0x5d,0x60, 0x1,0x5d,0x5c, 0x2,0x39,0x67, + 0x3,0x39,0x4a, 0x3,0x39,0x4e, 0x1,0x5d,0x64, 0x1,0x5d,0x5d, + 0x1,0x5d,0x62, 0x1,0x5d,0x58, 0x4,0x35,0x68, 0x1,0x5d,0x55, + 0x1,0x5d,0x57, 0x1,0x5d,0x63, 0x2,0x39,0x68, 0x1,0x5d,0x5b, + 0x1,0x5d,0x5e, 0x1,0x5d,0x5a, 0x1,0x5d,0x5f, 0x2,0x39,0x6a, + 0x1,0x5d,0x61, 0x1,0x5d,0x59, 0x2,0x39,0x65, 0x3,0x39,0x4c, + 0x3,0x3f,0x4f, 0x3,0x3f,0x50, 0x3,0x3f,0x4d, 0x3,0x3f,0x4c, + 0x3,0x3f,0x51, 0x2,0x40,0x72, 0x1,0x62,0x4c, 0x2,0x40,0x74, + 0x3,0x3f,0x55, 0x1,0x62,0x4e, 0x1,0x62,0x50, 0x4,0x35,0x66, + 0x2,0x40,0x73, 0x1,0x62,0x4d, 0x1,0x62,0x51, 0x3,0x3f,0x56, + 0x1,0x62,0x4f, 0x3,0x3f,0x54, 0x3,0x3f,0x57, 0x1,0x67,0x2f, + 0x2,0x48,0x29, 0x1,0x67,0x37, 0x2,0x48,0x26, 0x3,0x44,0x7d, + 0x1,0x67,0x38, 0x1,0x67,0x2d, 0x3,0x44,0x79, 0x2,0x48,0x27, + 0x3,0x44,0x7c, 0x3,0x44,0x7a, 0x1,0x67,0x32, 0x3,0x44,0x7b, + 0x2,0x48,0x28, 0x1,0x67,0x2b, 0x1,0x67,0x2a, 0x3,0x44,0x7e, + 0x1,0x67,0x35, 0x1,0x67,0x34, 0x1,0x67,0x33, 0x1,0x67,0x31, + 0x1,0x67,0x36, 0x2,0x48,0x25, 0x1,0x67,0x2c, 0x1,0x67,0x2e, + 0x1,0x67,0x30, 0x1,0x6b,0x40, 0x1,0x6b,0x43, 0x3,0x4a,0x24, + 0x1,0x6b,0x47, 0x1,0x6b,0x41, 0x1,0x6b,0x46, 0x1,0x6b,0x44, + 0x3,0x4a,0x27, 0x1,0x6b,0x3f, 0x3,0x4a,0x26, 0x1,0x6b,0x45, + 0x1,0x6b,0x42, 0xf,0x4c,0x6b, 0x4,0x4e,0x32, 0x2,0x54,0x7a, + 0x1,0x6f,0x4d, 0x1,0x6f,0x4b, 0x3,0x4f,0x3c, 0x2,0x54,0x7b, + 0x4,0x4e,0x33, 0x1,0x6f,0x4e, 0x1,0x6f,0x4c, 0x2,0x54,0x79, + 0x2,0x54,0x78, 0x3,0x4f,0x3b, 0x1,0x72,0x5a, 0x2,0x54,0x77, + 0x1,0x72,0x58, 0x1,0x72,0x57, 0x2,0x5a,0x7c, 0x1,0x6f,0x4f, + 0x1,0x72,0x59, 0x2,0x5a,0x7d, 0x1,0x72,0x5c, 0x2,0x5a,0x7e, + 0x1,0x72,0x5b, 0x1,0x75,0x63, 0x2,0x5f,0x6f, 0x1,0x75,0x62, + 0x1,0x75,0x67, 0x1,0x75,0x65, 0x1,0x75,0x66, 0x1,0x77,0x4e, + 0x1,0x75,0x64, 0x2,0x5f,0x6e, 0x2,0x5b,0x21, 0x1,0x77,0x4d, + 0x1,0x77,0x4f, 0x3,0x59,0x3a, 0x1,0x79,0x31, 0x1,0x79,0x32, + 0x4,0x61,0x5f, 0x2,0x6a,0x2e, 0x4,0x69,0x52, 0x1,0x7c,0x4a, + 0x1,0x7c,0x49, 0x1,0x4b,0x57, 0x3,0x22,0x5e, 0x3,0x22,0x5d, + 0x2,0x22,0x75, 0x1,0x58,0x54, 0x3,0x24,0x3c, 0x2,0x22,0x72, + 0x2,0x22,0x73, 0x2,0x22,0x71, 0x3,0x24,0x3d, 0x2,0x22,0x74, + 0x3,0x66,0x55, 0x2,0x25,0x2a, 0x2,0x25,0x27, 0x2,0x25,0x2c, + 0x2,0x25,0x28, 0x1,0x4b,0x58, 0x1,0x4b,0x5b, 0x3,0x27,0x35, + 0x2,0x25,0x29, 0x1,0x4b,0x5a, 0x2,0x25,0x2b, 0x3,0x27,0x39, + 0x3,0x27,0x34, 0x1,0x4b,0x59, 0x3,0x39,0x51, 0x3,0x2a,0x77, + 0x4,0x28,0x2b, 0x2,0x28,0x75, 0x2,0x28,0x77, 0x1,0x4f,0x57, + 0x2,0x28,0x73, 0x2,0x28,0x76, 0x2,0x28,0x74, 0x1,0x4f,0x55, + 0x1,0x4f,0x58, 0x3,0x2a,0x75, 0x1,0x4f,0x56, 0x3,0x2a,0x78, + 0x3,0x2f,0x35, 0x2,0x2d,0x59, 0x2,0x2d,0x5d, 0x2,0x2d,0x5a, + 0x3,0x2f,0x38, 0x1,0x53,0x68, 0x3,0x2f,0x34, 0x1,0x53,0x69, + 0x3,0x2f,0x3e, 0x2,0x2d,0x5c, 0x3,0x2f,0x37, 0x2,0x2d,0x5e, + 0x2,0x2d,0x60, 0x3,0x2f,0x3c, 0x1,0x53,0x66, 0x2,0x2d,0x5f, + 0x4,0x41,0x39, 0x3,0x2f,0x3b, 0x1,0x53,0x67, 0xf,0x45,0x6d, + 0x2,0x39,0x71, 0x2,0x2d,0x5b, 0x2,0x33,0x36, 0x2,0x33,0x3f, + 0x2,0x33,0x3d, 0x2,0x33,0x38, 0x2,0x33,0x39, 0x2,0x33,0x3e, + 0x2,0x33,0x40, 0x1,0x58,0x56, 0x3,0x34,0x29, 0x2,0x33,0x3b, + 0x2,0x33,0x37, 0x1,0x58,0x55, 0x1,0x58,0x57, 0x2,0x33,0x3a, + 0x2,0x33,0x41, 0x2,0x33,0x3c, 0x1,0x5d,0x65, 0x2,0x39,0x74, + 0x2,0x39,0x6c, 0x2,0x39,0x72, 0x2,0x39,0x73, 0x1,0x5d,0x66, + 0x3,0x39,0x4f, 0x2,0x39,0x6b, 0x2,0x39,0x6d, 0x2,0x2d,0x58, + 0x2,0x39,0x6f, 0x2,0x39,0x70, 0x2,0x39,0x6e, 0x1,0x62,0x53, + 0x4,0x4e,0x3b, 0x3,0x39,0x52, 0x2,0x40,0x7b, 0x2,0x5b,0x22, + 0x2,0x40,0x7c, 0x2,0x40,0x79, 0x1,0x5d,0x67, 0x1,0x62,0x55, + 0x2,0x40,0x78, 0x2,0x40,0x7e, 0x2,0x40,0x7d, 0x1,0x62,0x52, + 0x2,0x41,0x23, 0x2,0x40,0x77, 0x2,0x41,0x22, 0x2,0x40,0x75, + 0x2,0x41,0x21, 0x2,0x40,0x7a, 0x1,0x62,0x54, 0x3,0x3f,0x59, + 0x2,0x48,0x30, 0x3,0x45,0x23, 0x2,0x48,0x2b, 0x2,0x48,0x31, + 0x2,0x48,0x2c, 0x2,0x48,0x2a, 0x2,0x48,0x2d, 0x1,0x67,0x39, + 0x3,0x45,0x24, 0x2,0x48,0x2f, 0x3,0x45,0x25, 0x2,0x48,0x2e, + 0x1,0x67,0x3a, 0x1,0x6b,0x49, 0x1,0x6b,0x48, 0x2,0x4e,0x56, + 0x2,0x4e,0x59, 0x2,0x4e,0x51, 0x2,0x4e,0x55, 0x1,0x6b,0x4a, + 0x2,0x4e,0x54, 0x2,0x4e,0x52, 0x2,0x4e,0x58, 0x2,0x4e,0x53, + 0x2,0x4e,0x50, 0x2,0x4e,0x57, 0x3,0x4a,0x2a, 0x2,0x55,0x23, + 0x1,0x6f,0x52, 0x2,0x63,0x74, 0x2,0x54,0x7e, 0x2,0x55,0x21, + 0x2,0x54,0x7d, 0x2,0x40,0x76, 0x1,0x6f,0x51, 0x2,0x55,0x24, + 0x2,0x54,0x7c, 0x1,0x6f,0x50, 0x1,0x6f,0x53, 0x2,0x55,0x22, + 0x2,0x5b,0x23, 0x1,0x72,0x5d, 0x2,0x5b,0x24, 0x2,0x5b,0x25, + 0x3,0x53,0x2b, 0x2,0x5f,0x70, 0x1,0x75,0x68, 0x2,0x63,0x75, + 0x2,0x63,0x76, 0x3,0x59,0x3c, 0x3,0x59,0x3b, 0x2,0x63,0x77, + 0x2,0x67,0x49, 0x2,0x67,0x48, 0x2,0x6a,0x30, 0x2,0x6a,0x2f, + 0x2,0x6c,0x4a, 0x2,0x6c,0x4b, 0x2,0x6c,0x49, 0x2,0x6e,0x35, + 0x1,0x7b,0x7a, 0x1,0x4b,0x5c, 0x1,0x53,0x6b, 0x1,0x53,0x6a, + 0x1,0x58,0x5a, 0x1,0x58,0x59, 0x2,0x33,0x43, 0x2,0x33,0x44, + 0x2,0x33,0x42, 0x3,0x34,0x2a, 0x1,0x58,0x58, 0x2,0x39,0x78, + 0x3,0x39,0x55, 0x2,0x39,0x79, 0x2,0x39,0x75, 0x1,0x5d,0x68, + 0x2,0x39,0x76, 0x3,0x39,0x54, 0x2,0x39,0x77, 0x3,0x66,0x57, + 0x2,0x41,0x26, 0x2,0x41,0x28, 0x2,0x41,0x24, 0x2,0x41,0x27, + 0x1,0x62,0x56, 0x2,0x41,0x25, 0x1,0x62,0x57, 0x3,0x45,0x28, + 0x2,0x42,0x79, 0x1,0x67,0x3d, 0x1,0x67,0x3c, 0x3,0x45,0x27, + 0x1,0x67,0x3b, 0x4,0x41,0x3a, 0x2,0x48,0x32, 0x2,0x48,0x33, + 0x4,0x41,0x3b, 0x2,0x4e,0x5b, 0x2,0x4e,0x5d, 0x1,0x6b,0x4e, + 0x1,0x6b,0x4b, 0x3,0x4a,0x2c, 0x1,0x6b,0x4d, 0x1,0x6b,0x4c, + 0x2,0x4e,0x5c, 0x2,0x4e,0x5a, 0x3,0x4a,0x2b, 0x3,0x4a,0x2d, + 0x2,0x55,0x2b, 0x2,0x55,0x28, 0x2,0x55,0x29, 0x1,0x6f,0x57, + 0x2,0x55,0x2a, 0x2,0x55,0x25, 0x2,0x55,0x26, 0x1,0x6f,0x54, + 0x3,0x4f,0x3f, 0x1,0x6f,0x55, 0x2,0x55,0x27, 0x1,0x6f,0x56, + 0x3,0x4f,0x40, 0x2,0x5b,0x29, 0x3,0x53,0x2d, 0x2,0x5b,0x2a, + 0x2,0x5b,0x27, 0x2,0x5b,0x28, 0x1,0x72,0x5e, 0x2,0x5b,0x26, + 0x4,0x54,0x42, 0x3,0x53,0x2c, 0x3,0x53,0x2f, 0x4,0x59,0x3f, + 0x2,0x5f,0x74, 0x2,0x5f,0x71, 0x2,0x5f,0x73, 0x1,0x75,0x6b, + 0x2,0x5f,0x77, 0x1,0x75,0x6a, 0x2,0x5f,0x75, 0x2,0x5f,0x78, + 0x2,0x5f,0x76, 0x2,0x5f,0x72, 0x1,0x75,0x69, 0x2,0x63,0x79, + 0x4,0x5e,0x24, 0x2,0x63,0x7a, 0x2,0x63,0x78, 0x3,0x59,0x3d, + 0x2,0x63,0x7c, 0x1,0x77,0x50, 0x1,0x77,0x51, 0x2,0x67,0x4b, + 0x1,0x79,0x34, 0x2,0x63,0x7b, 0x2,0x67,0x4a, 0x1,0x79,0x33, + 0x2,0x6a,0x33, 0x2,0x6a,0x34, 0x1,0x7a,0x4a, 0x2,0x6a,0x32, + 0x4,0x64,0x65, 0x2,0x6a,0x31, 0x2,0x6c,0x4c, 0x1,0x7b,0x34, + 0x3,0x5e,0x68, 0x2,0x6f,0x57, 0x2,0x70,0x56, 0x2,0x70,0x55, + 0x3,0x60,0x7e, 0x1,0x7c,0x6e, 0x1,0x7d,0x2a, 0x2,0x70,0x57, + 0x2,0x71,0x60, 0x3,0x61,0x6d, 0x1,0x7d,0x3c, 0x1,0x4b,0x5d, + 0x1,0x4f,0x59, 0x1,0x67,0x3e, 0x1,0x7a,0x4b, 0x1,0x4b,0x5e, + 0x1,0x53,0x6c, 0x1,0x5d,0x69, 0x1,0x62,0x58, 0x1,0x77,0x52, + 0x1,0x4f,0x5a, 0x2,0x2d,0x62, 0x2,0x2d,0x61, 0x2,0x33,0x45, + 0x3,0x34,0x30, 0x1,0x58,0x5d, 0x1,0x58,0x5b, 0x1,0x58,0x5f, + 0x2,0x33,0x47, 0x3,0x34,0x2d, 0x1,0x58,0x5e, 0x1,0x58,0x5c, + 0x3,0x34,0x2f, 0x3,0x34,0x2e, 0x3,0x34,0x31, 0x2,0x33,0x46, + 0x1,0x5d,0x6c, 0x2,0x3a,0x21, 0x3,0x39,0x58, 0x1,0x5d,0x6b, + 0x1,0x5d,0x6d, 0x2,0x3a,0x26, 0x1,0x5d,0x6f, 0x2,0x3a,0x23, + 0x2,0x3a,0x24, 0x2,0x39,0x7a, 0x1,0x5d,0x6e, 0x2,0x3a,0x27, + 0x4,0x35,0x7b, 0x3,0x39,0x57, 0x2,0x39,0x7c, 0x3,0x39,0x56, + 0x2,0x39,0x7d, 0x2,0x39,0x7b, 0x1,0x5d,0x6a, 0x3,0x39,0x59, + 0x2,0x3a,0x25, 0x2,0x39,0x7e, 0x2,0x3a,0x22, 0x2,0x41,0x34, + 0x3,0x3f,0x5d, 0x2,0x41,0x33, 0x2,0x41,0x31, 0x2,0x41,0x29, + 0x2,0x41,0x38, 0x2,0x41,0x2c, 0x2,0x41,0x36, 0x2,0x41,0x3d, + 0x2,0x41,0x35, 0x1,0x62,0x60, 0x3,0x3f,0x66, 0x1,0x62,0x5c, + 0x2,0x41,0x2a, 0x3,0x3f,0x60, 0x2,0x41,0x30, 0x1,0x62,0x5e, + 0x3,0x3f,0x68, 0x2,0x41,0x2f, 0x1,0x62,0x5f, 0x1,0x62,0x61, + 0x2,0x41,0x32, 0x3,0x3f,0x69, 0x1,0x62,0x59, 0x1,0x62,0x5a, + 0x2,0x41,0x3e, 0x2,0x41,0x3c, 0x3,0x3f,0x62, 0x2,0x41,0x3b, + 0x2,0x41,0x2d, 0x3,0x3f,0x65, 0x2,0x41,0x39, 0x4,0x3b,0x66, + 0x1,0x62,0x5d, 0x6,0x4f,0x6f, 0x3,0x3f,0x5e, 0x3,0x66,0x59, + 0x3,0x3f,0x63, 0x1,0x62,0x5b, 0x2,0x41,0x3a, 0x2,0x41,0x2b, + 0x2,0x41,0x2e, 0x2,0x41,0x37, 0x3,0x66,0x58, 0x2,0x4f,0x22, + 0x2,0x48,0x3d, 0x3,0x45,0x2e, 0x2,0x48,0x36, 0x2,0x48,0x49, + 0x2,0x48,0x52, 0x2,0x48,0x39, 0x1,0x67,0x49, 0x3,0x45,0x2b, + 0x2,0x48,0x46, 0x1,0x67,0x3f, 0x1,0x67,0x41, 0x1,0x67,0x4d, + 0x2,0x48,0x37, 0x3,0x45,0x37, 0x3,0x45,0x2f, 0x1,0x67,0x42, + 0x1,0x67,0x44, 0x1,0x67,0x4e, 0x1,0x67,0x43, 0x3,0x45,0x39, + 0x4,0x41,0x41, 0x4,0x41,0x46, 0x3,0x45,0x38, 0x1,0x67,0x4c, + 0x2,0x48,0x3f, 0x4,0x41,0x48, 0x2,0x48,0x34, 0x1,0x67,0x4a, + 0x2,0x48,0x3e, 0x1,0x67,0x46, 0x2,0x48,0x50, 0x1,0x67,0x4b, + 0x2,0x48,0x4e, 0x2,0x48,0x42, 0x2,0x48,0x4c, 0x1,0x67,0x48, + 0x2,0x48,0x35, 0x2,0x48,0x4f, 0x2,0x48,0x4a, 0x3,0x45,0x2a, + 0x2,0x48,0x51, 0x1,0x67,0x40, 0x4,0x41,0x40, 0x3,0x45,0x2d, + 0x1,0x67,0x4f, 0x1,0x67,0x45, 0x3,0x45,0x31, 0x3,0x45,0x29, + 0x2,0x48,0x3b, 0x3,0x45,0x34, 0x2,0x48,0x43, 0x2,0x48,0x47, + 0x3,0x45,0x33, 0x2,0x48,0x4b, 0x1,0x67,0x47, 0x2,0x48,0x3a, + 0x2,0x48,0x38, 0x2,0x48,0x44, 0x4,0x41,0x42, 0x4,0x41,0x43, + 0x3,0x45,0x32, 0x3,0x45,0x35, 0x2,0x48,0x41, 0x2,0x48,0x40, + 0x3,0x45,0x36, 0x2,0x48,0x45, 0x2,0x48,0x48, 0x2,0x48,0x4d, + 0x3,0x66,0x5a, 0xf,0x45,0x72, 0x4,0x47,0x75, 0x2,0x4e,0x60, + 0xf,0x4d,0x22, 0x1,0x6b,0x4f, 0x2,0x4e,0x6a, 0x2,0x4e,0x62, + 0x1,0x6b,0x55, 0x1,0x6b,0x59, 0x2,0x4e,0x73, 0x2,0x4e,0x7b, + 0x2,0x4e,0x6c, 0x1,0x6b,0x51, 0x3,0x4a,0x34, 0x2,0x4e,0x70, + 0x2,0x48,0x3c, 0x3,0x4a,0x35, 0x1,0x6b,0x52, 0x2,0x4e,0x77, + 0x2,0x4e,0x7c, 0x2,0x4e,0x74, 0x3,0x4a,0x2f, 0x2,0x4e,0x76, + 0x2,0x4f,0x21, 0x2,0x4e,0x78, 0x2,0x4e,0x66, 0x2,0x4e,0x6f, + 0x3,0x45,0x30, 0x3,0x4a,0x38, 0x1,0x6b,0x5a, 0x3,0x4a,0x33, + 0x1,0x6b,0x56, 0x2,0x4e,0x64, 0x2,0x4e,0x71, 0x1,0x6b,0x54, + 0x2,0x4e,0x6b, 0x1,0x6b,0x53, 0x2,0x4e,0x79, 0x2,0x4e,0x68, + 0x2,0x4e,0x61, 0x1,0x6b,0x57, 0x2,0x4e,0x7e, 0x3,0x4a,0x39, + 0x4,0x47,0x77, 0x2,0x4e,0x63, 0x2,0x4e,0x75, 0x2,0x4e,0x72, + 0x2,0x4e,0x6d, 0x2,0x4e,0x5f, 0x2,0x4e,0x5e, 0x2,0x4e,0x67, + 0x2,0x4e,0x7a, 0x1,0x6b,0x58, 0x2,0x4e,0x7d, 0x2,0x4e,0x65, + 0x2,0x4e,0x69, 0x1,0x6b,0x50, 0x3,0x4a,0x32, 0x3,0x4a,0x37, + 0xf,0x4d,0x27, 0x3,0x67,0x2a, 0x3,0x4a,0x31, 0x1,0x6f,0x63, + 0x1,0x6f,0x5e, 0x2,0x55,0x4d, 0x2,0x55,0x49, 0x2,0x55,0x31, + 0x1,0x6f,0x5a, 0x3,0x4f,0x42, 0x3,0x4f,0x50, 0x4,0x4e,0x45, + 0x1,0x6f,0x59, 0x1,0x6f,0x5f, 0x4,0x4e,0x47, 0x3,0x4f,0x43, + 0x3,0x4f,0x41, 0x2,0x55,0x2f, 0x1,0x6f,0x5d, 0x2,0x55,0x3b, + 0x2,0x55,0x2d, 0x2,0x55,0x2e, 0x1,0x6f,0x58, 0x2,0x55,0x4c, + 0x1,0x6f,0x61, 0x2,0x55,0x3e, 0x2,0x55,0x43, 0x2,0x55,0x3d, + 0x2,0x5b,0x3c, 0x2,0x55,0x39, 0x2,0x55,0x41, 0x2,0x55,0x3f, + 0x2,0x55,0x32, 0x2,0x55,0x2c, 0x2,0x55,0x47, 0x1,0x6f,0x60, + 0x2,0x55,0x48, 0x3,0x4f,0x48, 0x2,0x55,0x42, 0x3,0x4f,0x49, + 0x2,0x55,0x37, 0x2,0x55,0x35, 0x2,0x55,0x30, 0x3,0x4f,0x4b, + 0x3,0x4f,0x4e, 0x3,0x4f,0x44, 0x2,0x55,0x38, 0x2,0x55,0x45, + 0x2,0x55,0x34, 0x2,0x55,0x44, 0x2,0x55,0x4a, 0x3,0x4f,0x51, + 0x4,0x4e,0x46, 0x1,0x6f,0x5c, 0x3,0x4f,0x45, 0x2,0x55,0x40, + 0x2,0x55,0x46, 0x2,0x55,0x3c, 0x2,0x55,0x36, 0x1,0x6f,0x5b, + 0x3,0x4f,0x52, 0x4,0x4e,0x44, 0x3,0x4f,0x4c, 0x2,0x4e,0x6e, + 0x2,0x55,0x3a, 0x1,0x6f,0x62, 0x2,0x55,0x33, 0xf,0x52,0x6b, + 0x3,0x4f,0x4d, 0x3,0x66,0x5b, 0x3,0x66,0x5c, 0x3,0x4a,0x30, + 0x2,0x5b,0x41, 0x1,0x72,0x61, 0x2,0x5b,0x40, 0x2,0x5b,0x3e, + 0x2,0x5b,0x50, 0x1,0x72,0x65, 0x3,0x53,0x35, 0x2,0x5b,0x4d, + 0x2,0x5b,0x45, 0x2,0x5b,0x4f, 0x2,0x5b,0x37, 0x2,0x5b,0x43, + 0x3,0x53,0x3d, 0x1,0x72,0x67, 0x3,0x53,0x3e, 0x2,0x5b,0x2f, + 0x3,0x53,0x38, 0x2,0x5b,0x2d, 0x2,0x5b,0x4e, 0x3,0x53,0x32, + 0x2,0x5b,0x4c, 0x2,0x5b,0x4b, 0x2,0x5b,0x3b, 0x2,0x5b,0x3a, + 0x2,0x5b,0x30, 0x1,0x72,0x69, 0x4,0x54,0x43, 0x2,0x5b,0x36, + 0x2,0x5b,0x3f, 0x2,0x5b,0x4a, 0x1,0x72,0x6c, 0x2,0x5b,0x51, + 0x3,0x53,0x36, 0x1,0x75,0x73, 0x1,0x72,0x6e, 0x1,0x72,0x68, + 0x2,0x5b,0x34, 0x3,0x53,0x37, 0x2,0x5b,0x3d, 0x2,0x5b,0x2c, + 0x2,0x5b,0x2e, 0x1,0x72,0x5f, 0x1,0x72,0x6b, 0x1,0x72,0x64, + 0x2,0x5b,0x35, 0x2,0x5b,0x44, 0x2,0x55,0x4b, 0x1,0x72,0x6a, + 0x2,0x5b,0x2b, 0x1,0x75,0x6e, 0x2,0x5b,0x46, 0x2,0x5b,0x49, + 0x1,0x72,0x66, 0x3,0x53,0x3b, 0x2,0x5b,0x39, 0x1,0x72,0x6d, + 0x1,0x72,0x63, 0x3,0x53,0x3c, 0x3,0x53,0x39, 0x3,0x53,0x3a, + 0x1,0x72,0x62, 0x2,0x5b,0x42, 0x2,0x5b,0x48, 0x1,0x72,0x60, + 0x4,0x54,0x45, 0x2,0x5b,0x32, 0x2,0x5b,0x47, 0xf,0x58,0x59, + 0xf,0x58,0x48, 0x2,0x5b,0x33, 0x7,0x34,0x63, 0x3,0x66,0x5d, + 0xf,0x58,0x55, 0x3,0x66,0x5e, 0x4,0x54,0x49, 0x3,0x53,0x31, + 0x2,0x5b,0x38, 0x2,0x5f,0x7e, 0x3,0x56,0x65, 0x2,0x60,0x25, + 0x1,0x75,0x70, 0x1,0x75,0x72, 0x2,0x60,0x2b, 0x1,0x75,0x6c, + 0x2,0x60,0x39, 0x2,0x60,0x31, 0x2,0x60,0x26, 0x2,0x60,0x27, + 0x2,0x60,0x30, 0x3,0x56,0x66, 0x1,0x75,0x79, 0x2,0x60,0x2f, + 0x2,0x5f,0x7d, 0x2,0x60,0x2e, 0x2,0x60,0x22, 0x2,0x60,0x3a, + 0x1,0x75,0x78, 0x1,0x75,0x76, 0x2,0x60,0x23, 0x3,0x56,0x5d, + 0x2,0x60,0x36, 0x3,0x56,0x67, 0x2,0x60,0x28, 0x2,0x60,0x35, + 0x3,0x56,0x64, 0x2,0x60,0x37, 0x2,0x5f,0x7c, 0x1,0x75,0x71, + 0x3,0x56,0x5b, 0x2,0x60,0x38, 0x3,0x56,0x68, 0x3,0x56,0x5e, + 0x2,0x60,0x2c, 0x3,0x56,0x6b, 0x1,0x75,0x75, 0x2,0x60,0x29, + 0x3,0x56,0x61, 0x4,0x59,0x49, 0x1,0x75,0x77, 0x2,0x60,0x32, + 0x3,0x56,0x62, 0x3,0x56,0x63, 0x3,0x56,0x5f, 0x1,0x75,0x6f, + 0x2,0x60,0x24, 0x2,0x60,0x33, 0x3,0x56,0x5c, 0x2,0x60,0x2d, + 0x2,0x5b,0x31, 0x2,0x60,0x34, 0x2,0x60,0x21, 0x3,0x56,0x60, + 0x1,0x75,0x74, 0x3,0x56,0x6a, 0x2,0x64,0x2f, 0x4,0x59,0x47, + 0x1,0x75,0x6d, 0x2,0x5f,0x7a, 0x4,0x59,0x46, 0xf,0x5d,0x41, + 0x3,0x66,0x5f, 0xf,0x5d,0x39, 0x2,0x64,0x2c, 0x2,0x64,0x25, + 0x1,0x77,0x54, 0x3,0x59,0x43, 0x2,0x63,0x7e, 0x2,0x64,0x30, + 0x2,0x64,0x27, 0x2,0x60,0x2a, 0x3,0x59,0x40, 0x2,0x64,0x32, + 0x2,0x64,0x21, 0x3,0x59,0x42, 0x1,0x77,0x53, 0x2,0x64,0x2b, + 0x1,0x77,0x55, 0x1,0x77,0x5d, 0x1,0x77,0x5b, 0x2,0x64,0x2d, + 0x1,0x77,0x5c, 0x2,0x64,0x23, 0x3,0x59,0x49, 0x2,0x64,0x24, + 0x2,0x64,0x29, 0x2,0x64,0x2e, 0x3,0x59,0x3e, 0x2,0x5f,0x79, + 0x1,0x77,0x56, 0x2,0x64,0x37, 0x2,0x64,0x34, 0x2,0x67,0x61, + 0x2,0x64,0x2a, 0x2,0x64,0x26, 0x2,0x64,0x35, 0x2,0x67,0x56, + 0x2,0x64,0x28, 0x4,0x5e,0x31, 0x1,0x77,0x59, 0x3,0x59,0x44, + 0x1,0x77,0x58, 0x2,0x5f,0x7b, 0x1,0x77,0x5a, 0x2,0x64,0x31, + 0x2,0x64,0x33, 0x1,0x77,0x57, 0x2,0x64,0x36, 0x2,0x63,0x7d, + 0x4,0x5e,0x29, 0x2,0x64,0x22, 0x3,0x59,0x46, 0xf,0x61,0x33, + 0x3,0x59,0x45, 0x3,0x66,0x61, 0x3,0x66,0x62, 0x3,0x66,0x60, + 0xf,0x61,0x43, 0x2,0x67,0x5f, 0x3,0x5b,0x50, 0x2,0x67,0x4f, + 0x1,0x79,0x38, 0x2,0x67,0x5d, 0x3,0x5b,0x44, 0x3,0x5b,0x45, + 0x2,0x67,0x4d, 0x1,0x79,0x39, 0x4,0x61,0x67, 0x2,0x67,0x58, + 0x3,0x5b,0x43, 0x2,0x67,0x54, 0x1,0x79,0x3e, 0x2,0x67,0x5e, + 0x2,0x67,0x4e, 0x2,0x67,0x51, 0x1,0x79,0x36, 0x2,0x67,0x60, + 0x3,0x5b,0x48, 0x2,0x67,0x59, 0x2,0x67,0x5c, 0x1,0x79,0x3c, + 0x1,0x79,0x41, 0x1,0x79,0x3f, 0x2,0x67,0x55, 0x2,0x67,0x50, + 0x3,0x5b,0x4d, 0x1,0x79,0x3a, 0x1,0x79,0x3b, 0x2,0x67,0x4c, + 0x1,0x79,0x37, 0x3,0x5b,0x4f, 0x1,0x79,0x35, 0x1,0x79,0x3d, + 0x2,0x67,0x5b, 0x1,0x79,0x40, 0x3,0x5b,0x4a, 0x2,0x67,0x57, + 0x2,0x67,0x62, 0x1,0x79,0x42, 0x3,0x5b,0x41, 0x3,0x5b,0x42, + 0x3,0x5b,0x4e, 0x2,0x67,0x53, 0x3,0x5b,0x47, 0x2,0x67,0x5a, + 0x3,0x66,0x65, 0x3,0x66,0x63, 0x3,0x66,0x64, 0x3,0x5d,0x41, + 0x3,0x5e,0x6a, 0x2,0x6a,0x41, 0x2,0x6a,0x50, 0x2,0x6a,0x43, + 0x2,0x6a,0x4a, 0x2,0x67,0x52, 0x2,0x6a,0x48, 0x2,0x6a,0x37, + 0x2,0x6a,0x4e, 0x1,0x7a,0x4e, 0x2,0x6a,0x3b, 0x2,0x6a,0x4d, + 0x2,0x6a,0x42, 0x4,0x64,0x67, 0x3,0x5d,0x43, 0x1,0x7a,0x4d, + 0x3,0x5d,0x3c, 0x3,0x5d,0x3f, 0x2,0x6a,0x52, 0x2,0x6a,0x44, + 0x3,0x5d,0x3e, 0x2,0x6a,0x49, 0x2,0x6a,0x4c, 0x2,0x6a,0x35, + 0x2,0x6a,0x4f, 0x2,0x6a,0x40, 0x2,0x6a,0x45, 0x2,0x6a,0x39, + 0x2,0x6a,0x3d, 0x2,0x6a,0x51, 0x2,0x6a,0x47, 0x2,0x6a,0x36, + 0x2,0x6a,0x3a, 0x2,0x6a,0x3c, 0x2,0x6a,0x46, 0x3,0x5d,0x3d, + 0x1,0x7a,0x4c, 0x2,0x6a,0x3f, 0x3,0x5d,0x44, 0x3,0x5d,0x45, + 0x3,0x5d,0x47, 0x4,0x64,0x6b, 0x3,0x5d,0x42, 0x3,0x5d,0x3a, + 0x2,0x6a,0x38, 0x3,0x66,0x66, 0x3,0x66,0x67, 0x3,0x66,0x68, + 0xf,0x66,0x57, 0x3,0x5d,0x46, 0x2,0x6a,0x3e, 0x2,0x6c,0x50, + 0x2,0x6c,0x54, 0x1,0x7b,0x3b, 0x2,0x6c,0x56, 0x3,0x5e,0x6d, + 0x1,0x7b,0x35, 0x4,0x64,0x6f, 0x2,0x6c,0x52, 0x2,0x6c,0x58, + 0x1,0x7b,0x3a, 0x1,0x7b,0x36, 0x4,0x67,0x5c, 0x1,0x7b,0x37, + 0x2,0x6c,0x4f, 0x2,0x6c,0x55, 0x1,0x7b,0x39, 0x2,0x6c,0x53, + 0x1,0x7b,0x38, 0x2,0x6c,0x4e, 0x2,0x6a,0x4b, 0x2,0x6c,0x51, + 0x4,0x67,0x62, 0x2,0x6c,0x4d, 0x2,0x6c,0x57, 0x3,0x5f,0x69, + 0x3,0x5f,0x6e, 0x1,0x7b,0x7b, 0x2,0x6e,0x3c, 0x2,0x6e,0x3f, + 0x2,0x6e,0x3b, 0x2,0x6e,0x3d, 0x2,0x6e,0x3e, 0x2,0x6e,0x38, + 0x2,0x6e,0x39, 0x2,0x6e,0x36, 0x3,0x5f,0x6a, 0x3,0x5f,0x6c, + 0x2,0x6e,0x3a, 0x2,0x6e,0x37, 0x1,0x7b,0x7c, 0x1,0x7b,0x7d, + 0x3,0x5f,0x6b, 0x2,0x6f,0x59, 0x3,0x60,0x52, 0x2,0x6f,0x5b, + 0x4,0x6b,0x29, 0x5,0x76,0x5d, 0x3,0x60,0x55, 0x3,0x60,0x54, + 0x3,0x60,0x56, 0x2,0x6f,0x5a, 0x2,0x6f,0x5c, 0x3,0x60,0x4f, + 0x1,0x7c,0x4c, 0x3,0x60,0x53, 0x2,0x6f,0x58, 0x1,0x7c,0x4b, + 0x1,0x7c,0x4d, 0x3,0x60,0x57, 0x3,0x66,0x6a, 0x3,0x66,0x69, + 0x2,0x70,0x59, 0x2,0x70,0x5a, 0x1,0x7c,0x6f, 0x2,0x70,0x58, + 0x3,0x61,0x22, 0x2,0x71,0x42, 0x2,0x71,0x41, 0x2,0x71,0x43, + 0x1,0x7d,0x2c, 0x2,0x71,0x44, 0x1,0x7d,0x2b, 0x2,0x71,0x45, + 0x2,0x71,0x61, 0x2,0x71,0x64, 0x2,0x71,0x63, 0x1,0x7d,0x35, + 0x2,0x71,0x62, 0x4,0x6d,0x62, 0x3,0x61,0x6f, 0x3,0x62,0x23, + 0x1,0x7d,0x3f, 0x1,0x7d,0x3d, 0x1,0x7d,0x3e, 0x1,0x7d,0x44, + 0x2,0x72,0x30, 0x2,0x72,0x31, 0x2,0x72,0x2f, 0x2,0x72,0x37, + 0x3,0x62,0x36, 0x1,0x4f,0x5b, 0x4,0x25,0x2b, 0x4,0x30,0x3a, + 0x2,0x3a,0x28, 0x2,0x41,0x3f, 0x2,0x55,0x4e, 0x2,0x67,0x63, + 0x5,0x71,0x56, 0x1,0x4f,0x5c, 0x3,0x2f,0x40, 0x1,0x53,0x6d, + 0x1,0x58,0x60, 0x4,0x30,0x3b, 0x3,0x34,0x32, 0x2,0x3a,0x29, + 0x3,0x39,0x5c, 0x2,0x3a,0x2a, 0x1,0x5d,0x70, 0x1,0x62,0x64, + 0x2,0x41,0x41, 0x2,0x41,0x40, 0x1,0x62,0x68, 0x1,0x62,0x63, + 0x2,0x41,0x42, 0x1,0x62,0x65, 0x1,0x62,0x67, 0x1,0x62,0x66, + 0x1,0x62,0x62, 0x3,0x3f,0x6c, 0xf,0x3f,0x7e, 0x3,0x66,0x6b, + 0x1,0x67,0x50, 0x3,0x45,0x3c, 0x3,0x45,0x3a, 0x2,0x48,0x56, + 0x2,0x48,0x54, 0x4,0x41,0x53, 0x2,0x48,0x55, 0x2,0x48,0x53, + 0xf,0x45,0x7b, 0x1,0x6b,0x5b, 0x3,0x4a,0x3d, 0x1,0x6b,0x5e, + 0x1,0x6b,0x60, 0x1,0x6b,0x5f, 0x4,0x48,0x22, 0x3,0x4a,0x3e, + 0x1,0x6b,0x5c, 0x1,0x6b,0x5d, 0x2,0x55,0x50, 0x2,0x55,0x4f, + 0x1,0x6f,0x64, 0x2,0x55,0x51, 0x3,0x4f,0x53, 0x2,0x55,0x52, + 0x1,0x6f,0x65, 0x3,0x4f,0x55, 0x3,0x4f,0x56, 0x4,0x4e,0x4a, + 0x2,0x5b,0x59, 0x2,0x5b,0x57, 0x2,0x60,0x40, 0x3,0x53,0x42, + 0x2,0x5b,0x55, 0x2,0x5b,0x56, 0x1,0x72,0x6f, 0x2,0x5b,0x52, + 0x2,0x5b,0x5a, 0x2,0x5b,0x54, 0x2,0x5b,0x58, 0x2,0x60,0x3c, + 0x3,0x53,0x44, 0x3,0x53,0x40, 0x2,0x60,0x3e, 0x3,0x56,0x6d, + 0x2,0x60,0x3f, 0x1,0x75,0x7e, 0x2,0x60,0x3b, 0x1,0x75,0x7d, + 0x2,0x60,0x3d, 0x1,0x75,0x7a, 0x1,0x75,0x7b, 0x1,0x75,0x7c, + 0x2,0x5b,0x53, 0x3,0x66,0x6c, 0x1,0x77,0x60, 0x2,0x64,0x3a, + 0x2,0x64,0x38, 0x2,0x64,0x39, 0x1,0x77,0x5e, 0x1,0x77,0x61, + 0x1,0x77,0x5f, 0x3,0x59,0x4b, 0x3,0x59,0x4a, 0x7,0x4b,0x40, + 0x2,0x67,0x64, 0x2,0x67,0x65, 0x1,0x79,0x43, 0x3,0x5b,0x53, + 0x2,0x6a,0x53, 0x2,0x6a,0x55, 0x2,0x6a,0x54, 0x1,0x7a,0x4f, + 0x1,0x7b,0x3c, 0x2,0x6c,0x5b, 0x2,0x6c,0x5a, 0x2,0x6c,0x59, + 0xf,0x68,0x72, 0x3,0x66,0x6d, 0xf,0x25,0x39, 0x1,0x4f,0x5d, + 0x3,0x21,0x43, 0x2,0x21,0x69, 0x2,0x22,0x78, 0x1,0x48,0x6a, + 0x2,0x22,0x76, 0x2,0x22,0x79, 0x2,0x22,0x77, 0x4,0x25,0x2e, + 0x3,0x27,0x3b, 0x3,0x27,0x3a, 0x2,0x25,0x2e, 0x3,0x27,0x3f, + 0x1,0x4b,0x62, 0x3,0x27,0x3c, 0x1,0x4b,0x63, 0x2,0x25,0x30, + 0x1,0x4b,0x60, 0x2,0x25,0x2f, 0x2,0x25,0x2d, 0x1,0x4b,0x61, + 0x1,0x4b,0x5f, 0x3,0x27,0x3d, 0x3,0x27,0x3e, 0x3,0x2a,0x79, + 0x4,0x28,0x33, 0x2,0x28,0x78, 0x2,0x28,0x7b, 0x1,0x4f,0x60, + 0x2,0x28,0x7a, 0x2,0x28,0x79, 0x3,0x2a,0x7c, 0x1,0x4f,0x5f, + 0x1,0x4f,0x5e, 0x3,0x2a,0x7b, 0x1,0x4f,0x62, 0x2,0x28,0x7c, + 0x1,0x4f,0x61, 0x2,0x2d,0x67, 0x1,0x53,0x6f, 0x1,0x53,0x70, + 0x1,0x53,0x71, 0x2,0x2d,0x68, 0x2,0x2d,0x64, 0x1,0x53,0x6e, + 0x2,0x2d,0x65, 0x4,0x2b,0x5d, 0x2,0x2d,0x66, 0x2,0x2d,0x63, + 0x4,0x2b,0x5b, 0x3,0x34,0x36, 0x4,0x30,0x3f, 0x1,0x58,0x67, + 0x3,0x34,0x34, 0x3,0x39,0x5e, 0x1,0x58,0x64, 0x2,0x33,0x48, + 0x1,0x58,0x65, 0x1,0x58,0x68, 0x2,0x33,0x49, 0x3,0x34,0x33, + 0x1,0x58,0x63, 0x1,0x58,0x61, 0x1,0x58,0x62, 0x1,0x58,0x66, + 0x1,0x5d,0x71, 0x2,0x3a,0x2d, 0x1,0x5d,0x79, 0x2,0x3a,0x2c, + 0x3,0x39,0x61, 0x2,0x3a,0x2f, 0x1,0x5d,0x75, 0x2,0x3a,0x2e, + 0x1,0x62,0x70, 0x1,0x5d,0x73, 0x1,0x5d,0x76, 0x1,0x5d,0x72, + 0x1,0x5d,0x77, 0x1,0x5d,0x78, 0x1,0x5d,0x74, 0x3,0x39,0x65, + 0x3,0x3f,0x71, 0x2,0x3a,0x2b, 0x1,0x62,0x6c, 0x2,0x41,0x44, + 0x3,0x3f,0x72, 0x2,0x41,0x48, 0x3,0x3f,0x73, 0x3,0x3f,0x75, + 0x2,0x41,0x47, 0x1,0x62,0x71, 0x1,0x62,0x6d, 0x1,0x62,0x6e, + 0x2,0x41,0x43, 0x2,0x41,0x45, 0x2,0x41,0x46, 0x1,0x62,0x69, + 0x1,0x62,0x6b, 0x3,0x3f,0x70, 0x1,0x62,0x6f, 0x1,0x62,0x6a, + 0x3,0x45,0x40, 0x2,0x48,0x59, 0x2,0x48,0x57, 0x2,0x48,0x58, + 0x1,0x67,0x52, 0x1,0x67,0x53, 0x3,0x45,0x42, 0x2,0x48,0x5a, + 0x1,0x67,0x51, 0x1,0x6b,0x61, 0x4,0x48,0x24, 0x1,0x6b,0x63, + 0x1,0x6b,0x62, 0x3,0x4a,0x45, 0x2,0x4f,0x23, 0x3,0x4a,0x46, + 0x3,0x4a,0x44, 0x2,0x4f,0x24, 0x2,0x55,0x54, 0x3,0x4f,0x5a, + 0x2,0x55,0x53, 0x3,0x4f,0x5b, 0x4,0x54,0x52, 0x1,0x72,0x70, + 0x1,0x72,0x71, 0x2,0x5b,0x5b, 0x1,0x72,0x72, 0x3,0x53,0x48, + 0x2,0x60,0x43, 0x3,0x56,0x70, 0x2,0x60,0x41, 0x3,0x56,0x6f, + 0x2,0x60,0x42, 0x1,0x76,0x21, 0x3,0x56,0x71, 0x2,0x64,0x3b, + 0x1,0x79,0x44, 0x3,0x5d,0x49, 0x3,0x2a,0x7d, 0x3,0x53,0x49, + 0x1,0x76,0x22, 0x1,0x4f,0x63, 0x4,0x30,0x41, 0x1,0x58,0x69, + 0x2,0x33,0x4a, 0x3,0x34,0x39, 0xf,0x32,0x6f, 0x2,0x3a,0x30, + 0x1,0x5d,0x7a, 0x1,0x62,0x72, 0x2,0x41,0x49, 0x2,0x41,0x4b, + 0x1,0x62,0x74, 0x1,0x62,0x73, 0x1,0x62,0x75, 0x1,0x62,0x76, + 0x2,0x41,0x4a, 0x1,0x67,0x56, 0x1,0x67,0x57, 0x1,0x67,0x55, + 0x1,0x6b,0x64, 0x1,0x67,0x54, 0x2,0x48,0x5b, 0x4,0x41,0x57, + 0x3,0x4a,0x47, 0x3,0x4a,0x49, 0x1,0x6b,0x65, 0x2,0x55,0x55, + 0x2,0x5b,0x5c, 0x1,0x72,0x73, 0x1,0x76,0x23, 0x2,0x64,0x3c, + 0x2,0x64,0x40, 0x1,0x77,0x64, 0x2,0x64,0x3d, 0x1,0x77,0x65, + 0x1,0x77,0x63, 0x2,0x64,0x41, 0x1,0x77,0x66, 0x2,0x64,0x3f, + 0x2,0x67,0x66, 0x1,0x77,0x62, 0x1,0x79,0x45, 0x3,0x5e,0x70, + 0x2,0x70,0x5b, 0x3,0x61,0x25, 0x3,0x62,0x2f, 0x1,0x4f,0x64, + 0x1,0x5d,0x7c, 0x1,0x5d,0x7b, 0xf,0x39,0x2a, 0x3,0x3f,0x7e, + 0x3,0x3f,0x7c, 0x3,0x3f,0x7b, 0x1,0x62,0x77, 0x2,0x41,0x4d, + 0x2,0x41,0x4c, 0x1,0x62,0x78, 0x3,0x45,0x46, 0x2,0x48,0x5f, + 0x1,0x67,0x5b, 0x1,0x67,0x58, 0x2,0x48,0x5e, 0x1,0x67,0x5a, + 0x2,0x48,0x5c, 0x1,0x67,0x59, 0x3,0x45,0x47, 0x2,0x48,0x5d, + 0x2,0x4f,0x25, 0x1,0x6b,0x66, 0x2,0x55,0x58, 0x5,0x52,0x3b, + 0x1,0x6f,0x66, 0x2,0x55,0x56, 0x1,0x6f,0x67, 0x1,0x6f,0x68, + 0x2,0x55,0x57, 0x1,0x6f,0x69, 0x3,0x4f,0x60, 0x2,0x5b,0x5d, + 0x3,0x53,0x50, 0x1,0x72,0x77, 0x1,0x72,0x74, 0x1,0x72,0x79, + 0x2,0x5b,0x5f, 0x1,0x72,0x75, 0x2,0x5b,0x5e, 0x1,0x72,0x78, + 0x3,0x53,0x4d, 0x3,0x53,0x4c, 0x1,0x72,0x76, 0x3,0x53,0x51, + 0x2,0x60,0x46, 0x2,0x60,0x48, 0x3,0x56,0x74, 0x3,0x56,0x75, + 0x1,0x76,0x24, 0x2,0x60,0x47, 0x1,0x76,0x25, 0x2,0x60,0x45, + 0x2,0x60,0x44, 0x4,0x5e,0x38, 0x2,0x64,0x43, 0x2,0x64,0x42, + 0x1,0x77,0x67, 0x2,0x64,0x44, 0x2,0x67,0x6b, 0x1,0x79,0x47, + 0x2,0x67,0x6a, 0x2,0x67,0x67, 0x1,0x79,0x46, 0x2,0x67,0x68, + 0x2,0x67,0x69, 0x2,0x6a,0x56, 0x2,0x6a,0x57, 0x1,0x7a,0x50, + 0x3,0x5d,0x4f, 0x1,0x7b,0x3f, 0x3,0x5d,0x4c, 0x3,0x5d,0x4e, + 0x2,0x6c,0x5c, 0x3,0x5e,0x72, 0x3,0x5e,0x71, 0x1,0x7b,0x3d, + 0x1,0x7b,0x3e, 0x2,0x6c,0x5d, 0x3,0x66,0x6e, 0x3,0x5f,0x71, + 0x1,0x7b,0x7e, 0x1,0x7c,0x21, 0x2,0x6e,0x40, 0x3,0x5f,0x72, + 0x3,0x60,0x59, 0x1,0x7c,0x70, 0x2,0x70,0x5d, 0x1,0x7c,0x72, + 0x3,0x61,0x26, 0x2,0x70,0x5c, 0x2,0x70,0x5e, 0x1,0x7c,0x71, + 0x2,0x71,0x46, 0x4,0x6d,0x64, 0x2,0x71,0x7b, 0x3,0x66,0x6f, + 0x3,0x62,0x45, 0x3,0x2a,0x7e, 0x1,0x4f,0x65, 0x3,0x45,0x49, + 0x1,0x67,0x5c, 0x4,0x48,0x35, 0x2,0x4f,0x26, 0x3,0x4a,0x4c, + 0x2,0x55,0x59, 0x1,0x72,0x7a, 0x1,0x72,0x7b, 0x3,0x59,0x4f, + 0x1,0x4f,0x66, 0x3,0x40,0x21, 0x1,0x6f,0x6a, 0x1,0x79,0x48, + 0x1,0x53,0x72, 0x3,0x2b,0x21, 0x3,0x4a,0x4e, 0x1,0x72,0x7c, + 0x3,0x5e,0x73, 0x1,0x7c,0x4e, 0x1,0x53,0x73, 0x2,0x3a,0x31, + 0x4,0x3b,0x77, 0x2,0x41,0x4e, 0x3,0x40,0x24, 0x2,0x41,0x50, + 0x3,0x40,0x22, 0x2,0x41,0x4f, 0x2,0x48,0x63, 0x2,0x48,0x60, + 0x1,0x67,0x5d, 0x6,0x5a,0x24, 0x1,0x67,0x5e, 0x2,0x48,0x61, + 0x2,0x48,0x62, 0x3,0x45,0x4b, 0x2,0x4f,0x28, 0x2,0x4f,0x2d, + 0x1,0x6b,0x67, 0x2,0x4f,0x27, 0x2,0x4f,0x29, 0x2,0x4f,0x30, + 0x2,0x4f,0x2b, 0x2,0x4f,0x2f, 0x2,0x4f,0x2c, 0x2,0x4f,0x2a, + 0x2,0x4f,0x2e, 0x1,0x6b,0x68, 0x3,0x4f,0x62, 0x2,0x55,0x5c, + 0x3,0x4f,0x63, 0x2,0x55,0x5a, 0x1,0x6f,0x6c, 0x3,0x4f,0x64, + 0x1,0x6f,0x6b, 0x2,0x55,0x5b, 0x1,0x6f,0x6d, 0x3,0x53,0x53, + 0x2,0x5b,0x62, 0x4,0x54,0x5f, 0x4,0x54,0x67, 0x2,0x5b,0x61, + 0x1,0x72,0x7d, 0x2,0x5b,0x60, 0x2,0x60,0x49, 0x3,0x56,0x7a, + 0x2,0x60,0x4b, 0x2,0x60,0x4d, 0x2,0x60,0x4c, 0x3,0x56,0x7b, + 0x1,0x76,0x26, 0x2,0x60,0x4a, 0x2,0x64,0x4b, 0x1,0x77,0x68, + 0x2,0x64,0x49, 0x2,0x64,0x4c, 0x1,0x77,0x69, 0x4,0x5e,0x43, + 0x2,0x64,0x47, 0x3,0x59,0x50, 0x2,0x64,0x4a, 0x2,0x64,0x48, + 0x2,0x64,0x45, 0x1,0x77,0x6a, 0x2,0x64,0x46, 0x4,0x61,0x7c, + 0x3,0x5b,0x5f, 0x3,0x5b,0x5d, 0x2,0x67,0x6c, 0x3,0x5b,0x5e, + 0x3,0x5b,0x60, 0x2,0x67,0x6e, 0x2,0x67,0x6d, 0x3,0x5d,0x50, + 0x2,0x6a,0x58, 0x3,0x5d,0x51, 0x2,0x6a,0x59, 0x4,0x67,0x71, + 0x3,0x5e,0x75, 0x3,0x5e,0x74, 0x2,0x6c,0x5e, 0x3,0x5f,0x73, + 0x1,0x7c,0x23, 0x4,0x69,0x5e, 0x1,0x7c,0x22, 0x2,0x6f,0x5d, + 0x2,0x6f,0x5e, 0x1,0x7c,0x73, 0x2,0x70,0x5f, 0x3,0x61,0x28, + 0x1,0x7d,0x36, 0x3,0x62,0x3b, 0x1,0x53,0x74, 0x1,0x62,0x79, + 0x2,0x4f,0x32, 0x2,0x4f,0x31, 0x2,0x55,0x5e, 0x2,0x55,0x5d, + 0x4,0x4e,0x57, 0x3,0x53,0x55, 0x1,0x76,0x27, 0x2,0x60,0x4f, + 0x2,0x60,0x4e, 0x2,0x64,0x4f, 0x2,0x64,0x4d, 0x2,0x64,0x50, + 0x2,0x64,0x4e, 0x3,0x59,0x51, 0x4,0x65,0x29, 0x1,0x79,0x49, + 0x2,0x67,0x6f, 0x2,0x67,0x70, 0x2,0x67,0x71, 0x4,0x65,0x27, + 0x2,0x6c,0x5f, 0x3,0x5e,0x76, 0x2,0x6e,0x41, 0x3,0x61,0x29, + 0x2,0x70,0x60, 0x1,0x53,0x75, 0x3,0x45,0x4f, 0x3,0x4f,0x65, + 0x2,0x5b,0x63, 0x2,0x60,0x50, 0x3,0x5b,0x61, 0x1,0x53,0x76, + 0x4,0x41,0x63, 0x3,0x45,0x50, 0x1,0x6b,0x69, 0x4,0x48,0x46, + 0x2,0x5b,0x64, 0x1,0x77,0x6b, 0x2,0x64,0x51, 0x1,0x79,0x4a, + 0x3,0x5d,0x53, 0x2,0x6a,0x5a, 0x2,0x6a,0x5b, 0x1,0x7b,0x40, + 0x2,0x6f,0x5f, 0x1,0x53,0x77, 0x1,0x5e,0x21, 0x1,0x5e,0x22, + 0x2,0x3a,0x32, 0x1,0x62,0x7a, 0x1,0x62,0x7b, 0x2,0x41,0x51, + 0x1,0x62,0x7c, 0x4,0x41,0x68, 0x1,0x67,0x62, 0x3,0x45,0x52, + 0x1,0x67,0x64, 0x2,0x48,0x65, 0x2,0x48,0x66, 0x2,0x48,0x64, + 0x1,0x67,0x5f, 0x1,0x67,0x60, 0x1,0x67,0x63, 0x1,0x67,0x61, + 0x3,0x4a,0x54, 0x3,0x4a,0x55, 0x2,0x4f,0x33, 0x1,0x6b,0x6a, + 0x1,0x6b,0x6b, 0x3,0x4a,0x52, 0x3,0x4a,0x56, 0x2,0x55,0x65, + 0x1,0x6f,0x70, 0x2,0x55,0x60, 0x2,0x55,0x5f, 0x3,0x4f,0x69, + 0x2,0x55,0x64, 0x1,0x6f,0x6e, 0x3,0x4f,0x67, 0x4,0x4e,0x5a, + 0x1,0x73,0x26, 0x4,0x54,0x70, 0x2,0x55,0x61, 0x2,0x55,0x66, + 0x2,0x55,0x63, 0x2,0x55,0x62, 0x3,0x4f,0x66, 0x1,0x6f,0x6f, + 0x1,0x73,0x24, 0x3,0x53,0x5c, 0x2,0x5b,0x66, 0x1,0x72,0x7e, + 0x3,0x53,0x59, 0x2,0x5b,0x67, 0x3,0x53,0x5a, 0x3,0x52,0x28, + 0x2,0x5b,0x65, 0x3,0x53,0x58, 0x1,0x73,0x23, 0x1,0x73,0x21, + 0x1,0x73,0x25, 0x3,0x53,0x5d, 0x1,0x73,0x22, 0x3,0x53,0x5b, + 0x3,0x53,0x5f, 0x4,0x5e,0x4f, 0x3,0x59,0x5b, 0x3,0x57,0x26, + 0x2,0x60,0x51, 0x4,0x59,0x70, 0x2,0x60,0x56, 0x2,0x60,0x52, + 0x2,0x60,0x55, 0x1,0x76,0x28, 0x3,0x57,0x28, 0x2,0x5e,0x41, + 0x2,0x60,0x54, 0x2,0x60,0x53, 0x3,0x59,0x59, 0x1,0x77,0x6e, + 0x1,0x77,0x6c, 0x1,0x77,0x6f, 0x1,0x77,0x6d, 0x2,0x64,0x52, + 0x2,0x64,0x53, 0x2,0x64,0x54, 0x1,0x77,0x70, 0x3,0x59,0x56, + 0x3,0x59,0x58, 0x3,0x5b,0x65, 0x2,0x67,0x75, 0x1,0x79,0x4c, + 0x2,0x67,0x73, 0x4,0x62,0x30, 0x1,0x79,0x4d, 0x2,0x67,0x72, + 0x2,0x67,0x74, 0x1,0x79,0x4b, 0x2,0x6a,0x5f, 0x2,0x6a,0x5c, + 0x4,0x65,0x2c, 0x2,0x6a,0x5d, 0x2,0x6a,0x5e, 0x2,0x6c,0x60, + 0x1,0x7b,0x42, 0x3,0x5e,0x78, 0x1,0x7b,0x41, 0x3,0x5e,0x77, + 0x2,0x6e,0x43, 0x2,0x6e,0x42, 0x1,0x7c,0x24, 0x3,0x60,0x5d, + 0x3,0x60,0x5e, 0x3,0x60,0x5c, 0x1,0x7c,0x4f, 0x1,0x7c,0x74, + 0x1,0x7d,0x2d, 0x2,0x71,0x47, 0x2,0x71,0x7c, 0x2,0x71,0x7d, + 0x1,0x53,0x78, 0x2,0x41,0x52, 0x4,0x41,0x71, 0x2,0x48,0x67, + 0x2,0x4f,0x34, 0x2,0x4f,0x35, 0x1,0x6b,0x6c, 0x4,0x48,0x57, + 0x1,0x6b,0x6d, 0x2,0x55,0x67, 0x1,0x6f,0x71, 0x3,0x53,0x61, + 0x1,0x76,0x29, 0x3,0x57,0x2a, 0x2,0x64,0x55, 0x3,0x59,0x5c, + 0x1,0x77,0x71, 0x2,0x67,0x78, 0x1,0x79,0x4e, 0x2,0x67,0x77, + 0x2,0x67,0x79, 0x2,0x67,0x76, 0x2,0x6c,0x63, 0x2,0x6a,0x60, + 0x2,0x6a,0x61, 0x3,0x5d,0x56, 0x1,0x7a,0x51, 0x2,0x6c,0x62, + 0x3,0x5e,0x7b, 0x3,0x5e,0x79, 0x2,0x6c,0x61, 0x3,0x5e,0x7a, + 0x2,0x6e,0x44, 0x2,0x71,0x7e, 0x3,0x62,0x25, 0x1,0x53,0x79, + 0x3,0x5e,0x7c, 0x3,0x62,0x26, 0x1,0x53,0x7a, 0x3,0x39,0x67, + 0x1,0x58,0x6a, 0x2,0x33,0x4b, 0x3,0x66,0x70, 0x2,0x3a,0x33, + 0x3,0x39,0x68, 0x1,0x62,0x7d, 0x1,0x63,0x22, 0x1,0x62,0x7e, + 0x2,0x41,0x53, 0x3,0x45,0x5b, 0x1,0x63,0x24, 0x1,0x63,0x21, + 0x3,0x40,0x2b, 0x3,0x45,0x5c, 0x1,0x63,0x23, 0x3,0x45,0x54, + 0x1,0x67,0x66, 0x3,0x45,0x59, 0x2,0x48,0x68, 0x3,0x45,0x57, + 0x3,0x4a,0x5d, 0x2,0x48,0x69, 0x2,0x55,0x69, 0x4,0x41,0x7b, + 0x1,0x67,0x65, 0x1,0x67,0x67, 0x1,0x67,0x68, 0x3,0x45,0x58, + 0x2,0x4f,0x37, 0x3,0x4a,0x5e, 0x2,0x4f,0x36, 0x1,0x6b,0x6e, + 0x5,0x4b,0x4c, 0x1,0x6b,0x6f, 0x3,0x4a,0x5b, 0x2,0x4f,0x38, + 0x2,0x55,0x68, 0x1,0x6b,0x71, 0x1,0x6f,0x72, 0x4,0x4e,0x63, + 0x1,0x6b,0x70, 0x3,0x66,0x7a, 0x1,0x73,0x27, 0x2,0x55,0x6a, + 0x1,0x6f,0x74, 0x1,0x6f,0x73, 0x2,0x55,0x6b, 0x2,0x55,0x6e, + 0x2,0x55,0x6c, 0x2,0x55,0x6d, 0x1,0x6f,0x75, 0x3,0x4f,0x6b, + 0x1,0x73,0x2c, 0x1,0x73,0x2a, 0x3,0x53,0x65, 0x3,0x53,0x66, + 0x1,0x73,0x29, 0x2,0x5b,0x69, 0x3,0x53,0x64, 0x1,0x73,0x2b, + 0x3,0x53,0x62, 0x3,0x53,0x63, 0x2,0x5b,0x68, 0x2,0x60,0x57, + 0x4,0x54,0x7e, 0x2,0x5b,0x6a, 0x1,0x73,0x28, 0x2,0x5b,0x6b, + 0x2,0x60,0x5a, 0x2,0x60,0x58, 0x2,0x60,0x59, 0x2,0x60,0x5e, + 0x1,0x77,0x75, 0x2,0x60,0x5d, 0x2,0x60,0x60, 0x2,0x60,0x5f, + 0x2,0x60,0x5c, 0x2,0x60,0x5b, 0x4,0x55,0x21, 0x1,0x76,0x2a, + 0x3,0x59,0x62, 0x4,0x5a,0x29, 0x3,0x59,0x61, 0x3,0x59,0x66, + 0x2,0x64,0x58, 0x3,0x59,0x65, 0x2,0x64,0x57, 0x1,0x77,0x74, + 0x1,0x77,0x72, 0x1,0x77,0x73, 0x3,0x59,0x63, 0x2,0x64,0x56, + 0x3,0x66,0x71, 0x2,0x67,0x7c, 0x3,0x5b,0x69, 0x1,0x79,0x4f, + 0x4,0x62,0x38, 0x2,0x67,0x7b, 0x2,0x67,0x7a, 0x1,0x79,0x50, + 0x4,0x65,0x3a, 0x2,0x6a,0x66, 0x2,0x6a,0x65, 0x3,0x5d,0x58, + 0x2,0x6a,0x63, 0x3,0x5e,0x7e, 0x2,0x6a,0x62, 0x1,0x7a,0x53, + 0x1,0x7a,0x52, 0x2,0x6a,0x67, 0x2,0x6e,0x45, 0x1,0x7c,0x25, + 0x2,0x6c,0x65, 0x1,0x7b,0x43, 0x2,0x6c,0x64, 0x2,0x6a,0x64, + 0x3,0x5f,0x78, 0x2,0x6e,0x46, 0x1,0x7c,0x50, 0x3,0x61,0x2a, + 0x1,0x7d,0x2e, 0x2,0x71,0x48, 0x4,0x6e,0x24, 0x2,0x72,0x21, + 0x1,0x53,0x7b, 0x2,0x3a,0x34, 0x2,0x60,0x61, 0x1,0x53,0x7c, + 0x3,0x45,0x5f, 0x5,0x4b,0x4e, 0x2,0x4f,0x3a, 0x2,0x4f,0x39, + 0x2,0x5b,0x6c, 0x5,0x5a,0x26, 0x3,0x53,0x68, 0x2,0x60,0x63, + 0x3,0x57,0x30, 0x2,0x60,0x62, 0x3,0x59,0x67, 0x1,0x77,0x76, + 0x2,0x67,0x7d, 0x2,0x67,0x7e, 0x1,0x7a,0x54, 0x3,0x5f,0x21, + 0x3,0x60,0x60, 0x2,0x72,0x22, 0x1,0x58,0x6b, 0x1,0x63,0x26, + 0x1,0x63,0x25, 0x2,0x48,0x6a, 0x2,0x48,0x6c, 0x1,0x67,0x6a, + 0x2,0x48,0x6b, 0x1,0x67,0x69, 0x1,0x67,0x6b, 0x2,0x48,0x6d, + 0x3,0x4a,0x63, 0x3,0x4a,0x62, 0x3,0x4a,0x66, 0x2,0x4f,0x3c, + 0x2,0x4f,0x3e, 0x2,0x4f,0x3d, 0x3,0x4a,0x61, 0x2,0x4f,0x40, + 0x3,0x4a,0x60, 0x3,0x4a,0x6c, 0x3,0x4a,0x64, 0x1,0x6b,0x72, + 0x2,0x4f,0x3f, 0x2,0x4f,0x3b, 0x3,0x4a,0x6a, 0x4,0x48,0x60, + 0x2,0x4f,0x41, 0x3,0x4f,0x73, 0x2,0x55,0x75, 0x3,0x4f,0x6d, + 0x2,0x55,0x78, 0x2,0x55,0x7a, 0x2,0x55,0x70, 0x2,0x55,0x74, + 0x2,0x55,0x71, 0x1,0x6f,0x77, 0x1,0x6f,0x7a, 0x1,0x6f,0x7c, + 0x2,0x55,0x72, 0x2,0x55,0x73, 0x1,0x6f,0x7b, 0x2,0x55,0x76, + 0x2,0x55,0x79, 0x2,0x55,0x77, 0x1,0x6f,0x7d, 0x3,0x4f,0x6e, + 0x1,0x6f,0x79, 0x2,0x55,0x6f, 0x1,0x6f,0x76, 0x3,0x4f,0x72, + 0x1,0x6f,0x78, 0x3,0x4f,0x74, 0x3,0x53,0x70, 0x1,0x73,0x2e, + 0x2,0x5b,0x72, 0x2,0x5b,0x70, 0x2,0x5b,0x6f, 0x3,0x53,0x71, + 0x2,0x5b,0x75, 0x3,0x53,0x6b, 0x2,0x5b,0x74, 0x2,0x5b,0x73, + 0x3,0x53,0x6c, 0x2,0x5b,0x6e, 0x1,0x73,0x2d, 0x2,0x5b,0x6d, + 0x3,0x53,0x6a, 0x2,0x5b,0x71, 0x1,0x73,0x2f, 0x3,0x57,0x34, + 0x2,0x60,0x66, 0x3,0x57,0x37, 0x2,0x60,0x6a, 0x2,0x60,0x67, + 0x2,0x60,0x69, 0x2,0x60,0x68, 0x2,0x60,0x65, 0x2,0x60,0x6b, + 0x2,0x60,0x6e, 0x2,0x60,0x6c, 0x2,0x60,0x6d, 0x1,0x76,0x2c, + 0x3,0x57,0x33, 0x1,0x76,0x2b, 0x2,0x60,0x64, 0x2,0x60,0x6f, + 0x2,0x64,0x5d, 0x2,0x64,0x60, 0x2,0x64,0x62, 0x2,0x64,0x61, + 0x3,0x59,0x6a, 0x2,0x64,0x5b, 0x2,0x64,0x5f, 0x2,0x64,0x5a, + 0x3,0x59,0x6b, 0x2,0x64,0x5c, 0x1,0x77,0x77, 0x2,0x64,0x59, + 0x3,0x59,0x6d, 0x2,0x64,0x5e, 0x2,0x68,0x2d, 0x2,0x68,0x22, + 0x1,0x79,0x51, 0x3,0x5b,0x6f, 0x3,0x5b,0x6d, 0x1,0x79,0x52, + 0x2,0x68,0x21, 0x2,0x68,0x26, 0x2,0x68,0x2c, 0x2,0x68,0x24, + 0x2,0x68,0x2b, 0x3,0x5b,0x6c, 0x2,0x68,0x28, 0x3,0x5b,0x6e, + 0x2,0x68,0x27, 0x2,0x68,0x2a, 0x2,0x68,0x25, 0x2,0x68,0x23, + 0x3,0x5b,0x6b, 0x2,0x68,0x29, 0x2,0x6a,0x6e, 0x2,0x6a,0x6c, + 0x1,0x7a,0x55, 0x2,0x6a,0x6b, 0x2,0x6a,0x71, 0x2,0x6a,0x6f, + 0x3,0x5d,0x5a, 0x1,0x7a,0x56, 0x2,0x6a,0x6a, 0x2,0x6a,0x68, + 0x4,0x65,0x46, 0x2,0x6a,0x69, 0x1,0x7a,0x58, 0x2,0x6a,0x6d, + 0x1,0x7a,0x57, 0x2,0x6a,0x70, 0x2,0x6c,0x66, 0x2,0x6c,0x6c, + 0x3,0x5f,0x24, 0x3,0x5f,0x22, 0x2,0x6c,0x67, 0x1,0x7b,0x47, + 0x2,0x6c,0x6d, 0x1,0x7b,0x46, 0x2,0x6c,0x6b, 0x2,0x6c,0x6a, + 0x1,0x7b,0x45, 0x2,0x6c,0x69, 0x1,0x7b,0x44, 0x2,0x6c,0x68, + 0x7,0x56,0x51, 0x2,0x6e,0x4c, 0x2,0x6e,0x4e, 0x2,0x6e,0x4d, + 0x4,0x69,0x6a, 0x2,0x6e,0x4a, 0x1,0x7c,0x27, 0x2,0x6e,0x47, + 0x2,0x6e,0x4b, 0x2,0x6e,0x50, 0x3,0x5f,0x79, 0x2,0x6e,0x4f, + 0x2,0x6e,0x48, 0x2,0x6e,0x49, 0x1,0x7c,0x26, 0x2,0x6f,0x60, + 0x1,0x7c,0x53, 0x3,0x60,0x62, 0x2,0x6f,0x61, 0x1,0x7c,0x51, + 0x1,0x7c,0x52, 0x3,0x60,0x61, 0x4,0x6c,0x3d, 0x2,0x70,0x61, + 0x1,0x7c,0x75, 0x2,0x71,0x65, 0x3,0x61,0x72, 0x1,0x7d,0x37, + 0x3,0x61,0x73, 0x2,0x72,0x23, 0x1,0x7d,0x38, 0x2,0x72,0x24, + 0x2,0x72,0x25, 0x2,0x72,0x33, 0x2,0x72,0x32, 0x1,0x7d,0x47, + 0x2,0x72,0x3b, 0x1,0x58,0x6c, 0x3,0x40,0x2f, 0x4,0x42,0x21, + 0x2,0x48,0x6f, 0x4,0x41,0x7d, 0x2,0x48,0x6e, 0x4,0x41,0x7e, + 0x1,0x6b,0x73, 0x1,0x6b,0x74, 0x2,0x4f,0x42, 0x4,0x4e,0x74, + 0x2,0x55,0x7b, 0x2,0x5b,0x78, 0x3,0x4f,0x77, 0x3,0x4f,0x76, + 0x1,0x6f,0x7e, 0x1,0x73,0x30, 0x2,0x5b,0x76, 0x4,0x55,0x31, + 0x2,0x5b,0x79, 0x1,0x73,0x31, 0x3,0x57,0x3a, 0x2,0x60,0x70, + 0x2,0x5b,0x77, 0x2,0x64,0x63, 0x1,0x77,0x78, 0x2,0x68,0x2e, + 0x4,0x62,0x49, 0x3,0x5d,0x61, 0x2,0x6a,0x74, 0x2,0x6a,0x72, + 0x3,0x5d,0x60, 0x3,0x5d,0x5e, 0x2,0x6a,0x73, 0x2,0x6c,0x6e, + 0x3,0x5f,0x25, 0x1,0x7b,0x48, 0x2,0x6e,0x51, 0x1,0x7c,0x56, + 0x1,0x7c,0x28, 0x1,0x7c,0x54, 0x1,0x7c,0x55, 0x2,0x70,0x62, + 0x1,0x7d,0x2f, 0x3,0x61,0x74, 0x1,0x58,0x6d, 0x4,0x36,0x2d, + 0x3,0x4a,0x6e, 0x4,0x4e,0x79, 0x2,0x64,0x64, 0x3,0x5f,0x7b, + 0x3,0x60,0x63, 0x2,0x33,0x4c, 0x3,0x40,0x32, 0x1,0x67,0x6c, + 0x3,0x45,0x61, 0x2,0x4f,0x43, 0x3,0x4a,0x6f, 0x3,0x4a,0x73, + 0x1,0x6b,0x75, 0x2,0x4f,0x44, 0x3,0x4a,0x71, 0x3,0x4a,0x70, + 0x3,0x4a,0x72, 0x2,0x55,0x7d, 0x2,0x55,0x7c, 0x1,0x73,0x33, + 0x1,0x70,0x21, 0x1,0x70,0x22, 0x4,0x4f,0x21, 0x2,0x56,0x22, + 0x2,0x56,0x21, 0x2,0x55,0x7e, 0x3,0x4f,0x79, 0x3,0x53,0x75, + 0x2,0x5b,0x7a, 0x2,0x5b,0x7d, 0x3,0x53,0x74, 0x2,0x5b,0x7c, + 0x2,0x5b,0x7b, 0x1,0x73,0x32, 0x2,0x60,0x74, 0x2,0x60,0x72, + 0x2,0x60,0x71, 0x4,0x5a,0x37, 0x3,0x57,0x3b, 0x2,0x60,0x73, + 0x3,0x57,0x3c, 0x1,0x77,0x79, 0x2,0x64,0x66, 0x2,0x64,0x67, + 0x1,0x77,0x7a, 0x3,0x59,0x6f, 0x2,0x64,0x65, 0x3,0x5b,0x71, + 0x2,0x68,0x30, 0x2,0x68,0x2f, 0x2,0x68,0x32, 0x1,0x79,0x53, + 0x2,0x68,0x31, 0x4,0x62,0x4f, 0x2,0x6a,0x75, 0x2,0x6a,0x77, + 0x2,0x6a,0x76, 0x3,0x5f,0x27, 0x2,0x6c,0x6f, 0x2,0x6c,0x72, + 0x2,0x6c,0x70, 0x2,0x6c,0x71, 0x2,0x6e,0x52, 0x1,0x7c,0x29, + 0x4,0x69,0x74, 0x4,0x69,0x71, 0x3,0x66,0x72, 0x2,0x6f,0x62, + 0x2,0x6f,0x63, 0x2,0x6f,0x64, 0x3,0x61,0x2c, 0x1,0x7c,0x76, + 0x1,0x7d,0x30, 0x2,0x72,0x26, 0x1,0x58,0x6e, 0x3,0x4a,0x75, + 0x1,0x70,0x23, 0x1,0x73,0x34, 0x2,0x64,0x68, 0x3,0x5d,0x62, + 0x2,0x6e,0x53, 0x3,0x61,0x2e, 0x4,0x6d,0x37, 0x2,0x71,0x66, + 0x2,0x33,0x4d, 0x3,0x62,0x28, 0x1,0x7d,0x48, 0x1,0x58,0x6f, + 0x2,0x5b,0x7e, 0x3,0x57,0x3e, 0x2,0x64,0x69, 0x2,0x68,0x33, + 0x3,0x5d,0x63, 0x4,0x68,0x36, 0x2,0x6c,0x73, 0x2,0x6e,0x54, + 0x1,0x58,0x70, 0x3,0x45,0x62, 0x2,0x4f,0x45, 0x2,0x4f,0x46, + 0x3,0x4a,0x78, 0x1,0x6b,0x76, 0x1,0x6b,0x77, 0x2,0x56,0x24, + 0x1,0x70,0x25, 0x1,0x70,0x24, 0x2,0x56,0x23, 0x2,0x60,0x75, + 0x3,0x57,0x3f, 0x2,0x64,0x6a, 0x2,0x64,0x6c, 0x2,0x64,0x6b, + 0x1,0x77,0x7d, 0x1,0x77,0x7c, 0x1,0x77,0x7b, 0x3,0x5d,0x64, + 0x1,0x7b,0x4a, 0x2,0x6c,0x74, 0x3,0x5f,0x28, 0x1,0x7b,0x49, + 0x2,0x6e,0x56, 0x2,0x6e,0x55, 0x3,0x61,0x2f, 0x1,0x7c,0x77, + 0x2,0x70,0x63, 0x1,0x5e,0x23, 0x2,0x48,0x70, 0x4,0x42,0x29, + 0x3,0x45,0x63, 0x2,0x4f,0x49, 0x2,0x4f,0x47, 0x2,0x4f,0x48, + 0x4,0x48,0x6b, 0x3,0x4f,0x7e, 0x2,0x56,0x2d, 0x4,0x4f,0x30, + 0x2,0x56,0x28, 0x2,0x56,0x25, 0x2,0x56,0x2c, 0x3,0x4f,0x7c, + 0x4,0x4f,0x35, 0x3,0x4f,0x7b, 0x2,0x56,0x2e, 0x4,0x4f,0x37, + 0x4,0x4f,0x2c, 0x1,0x70,0x27, 0x2,0x56,0x2b, 0x2,0x56,0x27, + 0x3,0x4f,0x7d, 0x4,0x4f,0x2a, 0x2,0x56,0x26, 0x2,0x56,0x2a, + 0x2,0x56,0x29, 0x1,0x70,0x26, 0xf,0x53,0x3e, 0x2,0x5c,0x2b, + 0x2,0x5c,0x26, 0x2,0x5c,0x24, 0x2,0x5c,0x2d, 0x2,0x5c,0x25, + 0x4,0x55,0x47, 0x2,0x5c,0x21, 0x4,0x55,0x43, 0x2,0x5c,0x27, + 0x3,0x53,0x78, 0x3,0x53,0x7a, 0x2,0x5c,0x22, 0x2,0x60,0x7e, + 0x2,0x5c,0x23, 0x2,0x5c,0x2e, 0x3,0x54,0x23, 0x4,0x55,0x45, + 0x3,0x53,0x7c, 0x3,0x54,0x21, 0x5,0x5a,0x4a, 0x3,0x54,0x25, + 0x3,0x53,0x7d, 0x2,0x5c,0x2a, 0x1,0x73,0x35, 0x2,0x5c,0x29, + 0x2,0x5c,0x28, 0x3,0x53,0x79, 0x2,0x5c,0x2c, 0xf,0x59,0x38, + 0x3,0x66,0x73, 0x3,0x57,0x44, 0x2,0x60,0x76, 0x2,0x60,0x79, + 0x4,0x5a,0x49, 0x3,0x57,0x45, 0x2,0x60,0x78, 0x3,0x57,0x40, + 0x2,0x61,0x22, 0x2,0x60,0x7b, 0x2,0x61,0x21, 0x3,0x57,0x42, + 0x2,0x60,0x7d, 0x2,0x60,0x7c, 0x2,0x60,0x7a, 0x4,0x5a,0x41, + 0x2,0x60,0x77, 0x4,0x5a,0x3f, 0x1,0x76,0x2f, 0x1,0x76,0x2e, + 0x4,0x5a,0x44, 0x1,0x76,0x30, 0x1,0x76,0x2d, 0x2,0x61,0x23, + 0x4,0x5a,0x45, 0xf,0x5d,0x76, 0x4,0x5a,0x43, 0x2,0x64,0x72, + 0x2,0x64,0x75, 0x4,0x5f,0x26, 0x2,0x64,0x73, 0x2,0x64,0x77, + 0x5,0x66,0x79, 0x3,0x59,0x74, 0x4,0x5f,0x22, 0x2,0x64,0x78, + 0x4,0x5f,0x2a, 0x2,0x64,0x70, 0x1,0x78,0x24, 0x2,0x64,0x71, + 0x3,0x59,0x73, 0x2,0x64,0x6f, 0x2,0x64,0x76, 0x3,0x5b,0x74, + 0x2,0x64,0x6e, 0x2,0x64,0x6d, 0x1,0x78,0x23, 0x1,0x78,0x21, + 0x1,0x77,0x7e, 0x3,0x59,0x76, 0x3,0x59,0x75, 0x3,0x57,0x43, + 0xf,0x61,0x72, 0x3,0x59,0x71, 0x2,0x64,0x74, 0x2,0x68,0x3c, + 0x2,0x68,0x42, 0x1,0x79,0x56, 0x2,0x68,0x3d, 0x5,0x6b,0x33, + 0x2,0x68,0x40, 0x2,0x68,0x44, 0x1,0x79,0x57, 0x2,0x68,0x3f, + 0x4,0x62,0x5c, 0x2,0x68,0x37, 0x3,0x5b,0x75, 0x2,0x68,0x36, + 0x2,0x68,0x43, 0x2,0x68,0x3a, 0x3,0x5b,0x77, 0x2,0x68,0x38, + 0x2,0x68,0x41, 0x2,0x68,0x39, 0x1,0x79,0x55, 0x1,0x79,0x54, + 0x3,0x5b,0x79, 0x2,0x68,0x34, 0x2,0x68,0x35, 0x2,0x68,0x3e, + 0x4,0x62,0x66, 0x3,0x5b,0x7a, 0x4,0x62,0x68, 0x2,0x68,0x3b, + 0xf,0x64,0x6b, 0x4,0x62,0x55, 0x3,0x5d,0x6f, 0x2,0x6a,0x7a, + 0x2,0x6a,0x7d, 0x3,0x5d,0x71, 0x4,0x62,0x56, 0x3,0x5d,0x67, + 0x3,0x5d,0x69, 0x1,0x78,0x22, 0x3,0x5d,0x6a, 0x3,0x5d,0x74, + 0x3,0x5d,0x75, 0x4,0x65,0x5a, 0x3,0x5d,0x6e, 0x4,0x65,0x59, + 0x3,0x5d,0x68, 0x2,0x6a,0x7b, 0x2,0x6b,0x23, 0x2,0x6b,0x21, + 0x2,0x6a,0x79, 0x2,0x6b,0x26, 0x3,0x5d,0x66, 0x2,0x6a,0x78, + 0x3,0x5d,0x76, 0x1,0x7a,0x5a, 0x2,0x6b,0x22, 0x4,0x65,0x54, + 0x3,0x5d,0x73, 0x4,0x65,0x57, 0x2,0x6a,0x7c, 0x1,0x7a,0x59, + 0x2,0x6b,0x25, 0x3,0x5d,0x72, 0x4,0x65,0x5d, 0x2,0x6b,0x24, + 0x3,0x5d,0x70, 0x2,0x6c,0x77, 0x2,0x6c,0x76, 0x5,0x72,0x51, + 0x3,0x5f,0x2c, 0x5,0x72,0x4b, 0x2,0x6c,0x7d, 0x5,0x72,0x4e, + 0x2,0x6c,0x79, 0x2,0x6c,0x7c, 0x1,0x7b,0x4c, 0x4,0x68,0x3b, + 0x4,0x68,0x3e, 0x2,0x6c,0x7a, 0x2,0x6c,0x7b, 0x4,0x68,0x39, + 0x2,0x6c,0x75, 0x2,0x6c,0x78, 0x1,0x7b,0x4b, 0x3,0x5f,0x2a, + 0xf,0x69,0x2a, 0x1,0x7c,0x2b, 0x2,0x6e,0x61, 0x2,0x6e,0x5c, + 0x2,0x6e,0x60, 0x3,0x60,0x25, 0x2,0x6e,0x63, 0x2,0x6e,0x5f, + 0x3,0x5f,0x7e, 0x2,0x6e,0x5b, 0x3,0x60,0x23, 0x1,0x7c,0x2d, + 0x2,0x6e,0x5e, 0x2,0x6e,0x62, 0x1,0x7c,0x2c, 0x2,0x6e,0x59, + 0x2,0x6a,0x7e, 0x2,0x6e,0x5d, 0x4,0x6a,0x23, 0x5,0x75,0x2d, + 0x2,0x6e,0x5a, 0x3,0x60,0x22, 0x2,0x6e,0x57, 0xf,0x6a,0x3e, + 0x2,0x6e,0x58, 0x1,0x7c,0x2a, 0x2,0x6f,0x68, 0x2,0x6f,0x6a, + 0x2,0x6f,0x6d, 0x2,0x6f,0x69, 0x2,0x6f,0x6e, 0x3,0x60,0x65, + 0x2,0x6f,0x67, 0x3,0x60,0x66, 0x2,0x6f,0x65, 0x3,0x60,0x68, + 0x1,0x7c,0x57, 0x2,0x6f,0x6b, 0x1,0x7c,0x59, 0x1,0x7c,0x58, + 0x2,0x6f,0x66, 0x2,0x6f,0x6c, 0x3,0x61,0x32, 0x2,0x70,0x68, + 0x1,0x7c,0x78, 0x2,0x70,0x69, 0x3,0x61,0x33, 0x2,0x70,0x67, + 0x2,0x70,0x64, 0x4,0x6c,0x4a, 0x3,0x61,0x34, 0x2,0x70,0x66, + 0x2,0x70,0x65, 0x2,0x71,0x49, 0x3,0x61,0x59, 0x2,0x71,0x4b, + 0x2,0x71,0x4a, 0x3,0x61,0x5b, 0x2,0x71,0x69, 0x5,0x7a,0x53, + 0x2,0x71,0x68, 0x2,0x71,0x67, 0x2,0x71,0x6a, 0x3,0x61,0x75, + 0x1,0x7d,0x40, 0x1,0x7d,0x41, 0x2,0x72,0x38, 0x2,0x72,0x3c, + 0x3,0x62,0x41, 0x1,0x5e,0x24, 0x2,0x41,0x54, 0x2,0x48,0x73, + 0x3,0x45,0x64, 0x1,0x67,0x6d, 0x2,0x48,0x71, 0x3,0x45,0x66, + 0x3,0x2f,0x42, 0x2,0x48,0x72, 0x3,0x45,0x68, 0x3,0x45,0x67, + 0x2,0x4f,0x4a, 0x2,0x4f,0x4b, 0x1,0x6b,0x7a, 0x1,0x6b,0x78, + 0x2,0x4f,0x4c, 0x1,0x6b,0x79, 0x2,0x56,0x33, 0x3,0x50,0x27, + 0x2,0x56,0x36, 0x2,0x56,0x30, 0x2,0x56,0x37, 0x2,0x56,0x2f, + 0x2,0x56,0x31, 0x3,0x50,0x2a, 0x2,0x56,0x32, 0x2,0x56,0x35, + 0x3,0x50,0x24, 0x3,0x50,0x2b, 0x1,0x70,0x2a, 0x2,0x56,0x3a, + 0x2,0x56,0x39, 0x1,0x70,0x28, 0x2,0x56,0x34, 0x2,0x56,0x38, + 0x1,0x70,0x29, 0x3,0x54,0x2d, 0x4,0x4f,0x42, 0x3,0x50,0x25, + 0x3,0x50,0x22, 0x3,0x54,0x2a, 0x2,0x5c,0x38, 0x4,0x55,0x52, + 0x1,0x73,0x3a, 0x3,0x54,0x2c, 0x2,0x5c,0x33, 0x1,0x73,0x36, + 0x3,0x54,0x36, 0x2,0x5c,0x30, 0x2,0x5c,0x36, 0x2,0x5c,0x39, + 0x3,0x54,0x33, 0x1,0x73,0x3b, 0x4,0x5a,0x4e, 0x2,0x5c,0x35, + 0x2,0x5c,0x32, 0x2,0x5c,0x3a, 0x2,0x5c,0x31, 0x3,0x54,0x37, + 0x2,0x5c,0x37, 0x1,0x73,0x37, 0x3,0x54,0x29, 0x2,0x5c,0x2f, + 0x1,0x73,0x38, 0x3,0x54,0x35, 0x1,0x73,0x39, 0x2,0x5c,0x34, + 0x3,0x54,0x32, 0x2,0x61,0x35, 0x2,0x61,0x28, 0x2,0x61,0x29, + 0x2,0x61,0x2c, 0x2,0x61,0x2a, 0x4,0x5a,0x55, 0x2,0x61,0x24, + 0x4,0x5a,0x56, 0x3,0x57,0x4d, 0x2,0x61,0x27, 0x2,0x61,0x31, + 0x2,0x61,0x2b, 0x3,0x57,0x48, 0x4,0x5a,0x4f, 0x1,0x76,0x31, + 0x4,0x5a,0x4d, 0x2,0x61,0x33, 0x2,0x61,0x30, 0x1,0x76,0x32, + 0x2,0x61,0x32, 0x2,0x61,0x25, 0x2,0x61,0x2e, 0x2,0x61,0x2f, + 0x3,0x57,0x4a, 0x2,0x61,0x2d, 0xf,0x5e,0x24, 0x3,0x66,0x75, + 0x2,0x64,0x7c, 0x2,0x64,0x7e, 0x2,0x65,0x23, 0x3,0x59,0x79, + 0x3,0x59,0x7b, 0x2,0x64,0x7b, 0x3,0x59,0x7d, 0x1,0x78,0x25, + 0x2,0x65,0x25, 0x2,0x64,0x7a, 0x2,0x65,0x26, 0x3,0x59,0x7e, + 0x2,0x65,0x22, 0x2,0x65,0x24, 0x2,0x65,0x28, 0x2,0x65,0x21, + 0x2,0x65,0x29, 0x2,0x64,0x7d, 0x2,0x64,0x79, 0x1,0x78,0x26, + 0x3,0x5a,0x22, 0x2,0x65,0x27, 0x1,0x78,0x27, 0x1,0x79,0x59, + 0x4,0x5f,0x34, 0x3,0x59,0x7a, 0xf,0x61,0x77, 0x3,0x5b,0x7d, + 0x2,0x61,0x26, 0x2,0x68,0x5e, 0x2,0x68,0x55, 0x1,0x79,0x5b, + 0x2,0x68,0x51, 0x1,0x79,0x5c, 0x3,0x5c,0x27, 0x3,0x5c,0x22, + 0x2,0x68,0x5a, 0x2,0x68,0x54, 0x2,0x68,0x4a, 0x1,0x79,0x5a, + 0x2,0x68,0x57, 0x2,0x68,0x52, 0x2,0x68,0x53, 0x3,0x5c,0x25, + 0x2,0x68,0x45, 0x2,0x68,0x4c, 0x2,0x68,0x5b, 0x3,0x5b,0x7e, + 0x2,0x68,0x58, 0x5,0x6b,0x3f, 0x2,0x68,0x50, 0x3,0x5c,0x26, + 0x2,0x68,0x5c, 0x2,0x68,0x4b, 0x2,0x68,0x46, 0x2,0x68,0x59, + 0x3,0x5c,0x24, 0x2,0x68,0x48, 0x2,0x68,0x56, 0x2,0x68,0x4d, + 0x2,0x68,0x5d, 0x2,0x68,0x49, 0x1,0x79,0x58, 0x2,0x68,0x47, + 0x2,0x68,0x4e, 0x2,0x68,0x4f, 0x2,0x6b,0x2d, 0x3,0x5c,0x23, + 0x2,0x6b,0x2b, 0x4,0x65,0x69, 0x2,0x6b,0x30, 0x3,0x5d,0x79, + 0x2,0x6b,0x3c, 0x2,0x6b,0x33, 0x2,0x6b,0x2c, 0x2,0x6b,0x28, + 0x2,0x6b,0x35, 0x2,0x6b,0x2e, 0x2,0x6b,0x31, 0x2,0x6b,0x2a, + 0x2,0x6b,0x38, 0x2,0x6b,0x27, 0x2,0x6b,0x2f, 0x2,0x6b,0x34, + 0x2,0x6b,0x36, 0x2,0x6b,0x39, 0x2,0x6b,0x29, 0x3,0x5d,0x7a, + 0x2,0x6b,0x3d, 0x2,0x6b,0x3e, 0x2,0x6b,0x37, 0x2,0x6b,0x3b, + 0x2,0x6b,0x32, 0x2,0x6d,0x2f, 0x2,0x6d,0x32, 0x3,0x5f,0x35, + 0x1,0x7b,0x4d, 0x3,0x5f,0x31, 0x2,0x6d,0x31, 0x2,0x6d,0x36, + 0x2,0x6d,0x34, 0x1,0x7b,0x4e, 0x2,0x6d,0x2b, 0x2,0x6d,0x21, + 0x2,0x6c,0x7e, 0x1,0x7b,0x50, 0x2,0x6d,0x2d, 0x2,0x6d,0x2e, + 0x2,0x6d,0x2a, 0x2,0x6d,0x22, 0x3,0x5f,0x32, 0x2,0x6d,0x27, + 0x2,0x6b,0x3a, 0x4,0x68,0x43, 0x2,0x6d,0x23, 0x1,0x7b,0x4f, + 0x2,0x6d,0x29, 0x3,0x5f,0x36, 0x2,0x6d,0x28, 0x2,0x6d,0x24, + 0x2,0x6d,0x30, 0x4,0x68,0x44, 0x2,0x6d,0x25, 0x2,0x6e,0x68, + 0x2,0x6d,0x33, 0x2,0x6d,0x35, 0x2,0x6d,0x2c, 0x2,0x6d,0x26, + 0x2,0x6e,0x69, 0x2,0x6e,0x6b, 0x2,0x6e,0x65, 0x1,0x7c,0x2e, + 0x4,0x6a,0x25, 0x2,0x6e,0x72, 0x2,0x6e,0x70, 0x1,0x7c,0x2f, + 0x2,0x6e,0x6f, 0x2,0x6e,0x6e, 0x2,0x6e,0x67, 0x2,0x6e,0x64, + 0x2,0x6e,0x6a, 0x2,0x6e,0x73, 0x2,0x6e,0x66, 0x2,0x6e,0x6c, + 0x5,0x75,0x45, 0x2,0x6f,0x77, 0x2,0x6f,0x7c, 0x2,0x6f,0x72, + 0x2,0x6f,0x75, 0x1,0x7c,0x5a, 0x2,0x6f,0x79, 0x4,0x6b,0x46, + 0x2,0x70,0x22, 0x2,0x6e,0x6d, 0x4,0x6b,0x4a, 0x2,0x6f,0x73, + 0x2,0x6f,0x7d, 0x2,0x70,0x23, 0x2,0x6f,0x78, 0x2,0x6f,0x71, + 0x2,0x6f,0x7b, 0x4,0x6b,0x4b, 0x2,0x6f,0x7a, 0x2,0x70,0x21, + 0x2,0x6f,0x7e, 0x2,0x6e,0x71, 0x2,0x6f,0x76, 0x2,0x6f,0x70, + 0x2,0x6f,0x74, 0x1,0x7c,0x79, 0x1,0x7c,0x7a, 0x2,0x6f,0x6f, + 0x3,0x60,0x6c, 0x2,0x70,0x74, 0x2,0x70,0x6b, 0x2,0x70,0x73, + 0x2,0x70,0x70, 0x2,0x70,0x71, 0x2,0x70,0x6a, 0x2,0x70,0x6d, + 0x2,0x70,0x75, 0x2,0x70,0x6f, 0x2,0x70,0x6e, 0x2,0x70,0x6c, + 0x3,0x61,0x35, 0x2,0x70,0x72, 0x4,0x6c,0x56, 0x2,0x71,0x4c, + 0x4,0x6d,0x3a, 0x2,0x71,0x4d, 0x3,0x61,0x5d, 0x2,0x71,0x4f, + 0x2,0x71,0x4e, 0x2,0x71,0x51, 0x2,0x71,0x50, 0x2,0x71,0x6c, + 0x2,0x71,0x6b, 0x2,0x72,0x27, 0x3,0x62,0x29, 0x2,0x72,0x28, + 0x3,0x62,0x30, 0x2,0x72,0x34, 0x1,0x7d,0x45, 0x1,0x7d,0x49, + 0x3,0x62,0x38, 0x2,0x72,0x3d, 0x1,0x7d,0x4a, 0x1,0x5e,0x25, + 0x4,0x4f,0x48, 0x5,0x5a,0x5b, 0x1,0x7a,0x5b, 0x2,0x6d,0x37, + 0x3,0x5f,0x37, 0x1,0x7c,0x7b, 0x1,0x7c,0x7c, 0x1,0x5e,0x26, + 0x2,0x48,0x74, 0x3,0x45,0x69, 0x1,0x67,0x6e, 0x2,0x56,0x3b, + 0x3,0x50,0x2c, 0x3,0x54,0x39, 0x2,0x5c,0x3c, 0x2,0x5c,0x3d, + 0x2,0x5c,0x3b, 0x2,0x61,0x37, 0x2,0x61,0x36, 0x1,0x76,0x33, + 0x2,0x65,0x2b, 0x2,0x61,0x38, 0x2,0x65,0x2a, 0x4,0x5f,0x3a, + 0x3,0x5a,0x24, 0x2,0x68,0x60, 0x1,0x79,0x5d, 0x1,0x79,0x5f, + 0x2,0x68,0x5f, 0x3,0x5c,0x29, 0x4,0x62,0x75, 0x1,0x79,0x5e, + 0x3,0x5e,0x21, 0x2,0x6b,0x3f, 0x2,0x6b,0x41, 0x2,0x6b,0x40, + 0x2,0x6d,0x38, 0x1,0x7b,0x51, 0x3,0x5f,0x3a, 0x1,0x7c,0x5b, + 0x2,0x70,0x76, 0x2,0x71,0x52, 0x3,0x62,0x31, 0x3,0x62,0x3f, + 0x2,0x72,0x41, 0x1,0x5e,0x27, 0x3,0x25,0x47, 0x2,0x4f,0x4d, + 0x4,0x4f,0x4c, 0x1,0x70,0x2b, 0x3,0x50,0x2f, 0x3,0x50,0x2e, + 0x3,0x54,0x3a, 0x2,0x5c,0x3f, 0x2,0x5c,0x3e, 0x3,0x57,0x50, + 0x2,0x61,0x39, 0x3,0x5a,0x26, 0x3,0x5a,0x25, 0x4,0x62,0x7e, + 0x1,0x79,0x60, 0x1,0x7a,0x5c, 0x2,0x6e,0x74, 0x2,0x72,0x39, + 0x1,0x5e,0x28, 0x1,0x6b,0x7b, 0x3,0x4b,0x22, 0x1,0x70,0x2c, + 0xf,0x61,0x7c, 0x2,0x68,0x61, 0x3,0x5e,0x22, 0x2,0x70,0x24, + 0x1,0x63,0x27, 0x3,0x39,0x6a, 0x3,0x54,0x3c, 0x3,0x54,0x3b, + 0x4,0x5a,0x5d, 0x2,0x61,0x3a, 0x3,0x5a,0x28, 0x4,0x5f,0x3e, + 0x1,0x7d,0x31, 0x1,0x63,0x28, 0x1,0x70,0x2d, 0x1,0x76,0x34, + 0x2,0x70,0x25, 0x1,0x63,0x29, 0x3,0x39,0x6b, 0x2,0x56,0x3c, + 0x1,0x73,0x3d, 0x2,0x5c,0x40, 0x2,0x5c,0x41, 0x3,0x54,0x3d, + 0x1,0x73,0x3c, 0x4,0x55,0x60, 0x2,0x61,0x3b, 0x1,0x76,0x38, + 0x1,0x76,0x36, 0x1,0x76,0x37, 0x1,0x76,0x35, 0x2,0x65,0x2c, + 0x1,0x78,0x28, 0x4,0x63,0x24, 0x3,0x5c,0x2a, 0x2,0x6b,0x43, + 0x2,0x6b,0x42, 0x2,0x6b,0x45, 0x2,0x6b,0x44, 0x1,0x7a,0x5d, + 0x2,0x6d,0x39, 0x4,0x68,0x56, 0x2,0x6d,0x3b, 0x2,0x6d,0x3a, + 0x1,0x7b,0x52, 0x2,0x6e,0x75, 0x3,0x60,0x29, 0x2,0x70,0x26, + 0x2,0x70,0x27, 0x1,0x7c,0x5c, 0x2,0x71,0x53, 0x2,0x71,0x6d, + 0x1,0x7d,0x42, 0x4,0x6e,0x43, 0x2,0x41,0x55, 0x2,0x5c,0x42, + 0x2,0x61,0x3c, 0x2,0x68,0x62, 0x2,0x48,0x75, 0x3,0x27,0x72, + 0x2,0x61,0x3d, 0x2,0x65,0x2e, 0x2,0x65,0x2d, 0x3,0x5a,0x29, + 0x3,0x5c,0x2d, 0x3,0x5c,0x2e, 0x3,0x5f,0x3c, 0x2,0x70,0x28, + 0x1,0x7c,0x7d, 0x3,0x61,0x5f, 0x2,0x71,0x54, 0x2,0x71,0x6e, + 0x1,0x67,0x6f, 0x2,0x56,0x3d, 0x2,0x56,0x3e, 0x4,0x4f,0x56, + 0x2,0x5c,0x43, 0x1,0x67,0x70, 0x3,0x45,0x6a, 0x1,0x78,0x29, + 0x2,0x65,0x2f, 0x3,0x5c,0x30, 0x2,0x6d,0x3d, 0x1,0x7b,0x53, + 0x2,0x6d,0x3e, 0x2,0x6d,0x3c, 0x2,0x70,0x29, 0x3,0x61,0x60, + 0x2,0x70,0x77, 0x4,0x6d,0x48, 0x1,0x67,0x71, 0x2,0x61,0x40, + 0x2,0x61,0x3f, 0x2,0x61,0x3e, 0x2,0x65,0x30, 0x3,0x5a,0x2b, + 0x3,0x5a,0x2a, 0x2,0x65,0x34, 0x2,0x65,0x33, 0x2,0x65,0x32, + 0x2,0x65,0x31, 0x1,0x78,0x2a, 0x2,0x68,0x63, 0x2,0x6b,0x47, + 0x1,0x7a,0x5e, 0x2,0x6b,0x46, 0x2,0x6d,0x3f, 0x2,0x6e,0x78, + 0x2,0x6e,0x77, 0x1,0x7c,0x30, 0x2,0x6e,0x76, 0x2,0x70,0x2c, + 0x2,0x70,0x2b, 0x2,0x70,0x2a, 0x3,0x60,0x6d, 0x4,0x6e,0x44, + 0x1,0x6b,0x7c, 0x4,0x55,0x63, 0x2,0x5c,0x44, 0x1,0x76,0x39, + 0x4,0x5a,0x64, 0x2,0x68,0x64, 0x2,0x68,0x65, 0x2,0x6e,0x79, + 0x2,0x70,0x2d, 0x4,0x6b,0x5c, 0x3,0x61,0x3b, 0x2,0x70,0x78, + 0x2,0x71,0x55, 0x2,0x72,0x29, 0x2,0x72,0x43, 0x1,0x6b,0x7d, + 0x1,0x76,0x3a, 0x2,0x65,0x35, 0x2,0x68,0x66, 0x2,0x6d,0x40, + 0x2,0x70,0x2e, 0x3,0x23,0x70, 0x1,0x70,0x2f, 0x3,0x54,0x3e, + 0x2,0x61,0x41, 0x2,0x65,0x36, 0x2,0x68,0x67, 0x2,0x68,0x68, + 0x2,0x68,0x69, 0x2,0x6b,0x4c, 0x3,0x5e,0x24, 0x2,0x6b,0x48, + 0x1,0x7b,0x54, 0x2,0x6b,0x4b, 0x2,0x6b,0x4a, 0x1,0x7a,0x5f, + 0x2,0x6b,0x49, 0x1,0x7a,0x61, 0x1,0x7a,0x60, 0x2,0x6d,0x42, + 0x2,0x6d,0x41, 0x1,0x7b,0x55, 0x1,0x7b,0x56, 0x4,0x68,0x60, + 0x3,0x5f,0x3e, 0x1,0x7c,0x32, 0x2,0x6e,0x7a, 0x1,0x7c,0x31, + 0x4,0x6b,0x61, 0x2,0x70,0x31, 0x2,0x70,0x32, 0x2,0x70,0x30, + 0x2,0x70,0x2f, 0x1,0x7d,0x21, 0x4,0x6c,0x64, 0x2,0x70,0x79, + 0x2,0x70,0x7a, 0x2,0x70,0x7b, 0x1,0x7c,0x7e, 0x2,0x71,0x56, + 0x2,0x71,0x59, 0x2,0x71,0x58, 0x2,0x71,0x57, 0x3,0x62,0x33, + 0x4,0x6e,0x45, 0x2,0x72,0x42, 0x1,0x73,0x3e, 0x3,0x57,0x55, + 0x4,0x63,0x2d, 0x1,0x78,0x32, 0x2,0x6b,0x4d, 0x2,0x6d,0x43, + 0x3,0x60,0x2b, 0x1,0x7c,0x33, 0x2,0x6e,0x7b, 0x4,0x6e,0x55, + 0x3,0x62,0x42, 0x2,0x72,0x44, 0xf,0x21,0x59, 0x1,0x73,0x3f, + 0x3,0x5e,0x47, 0x4,0x6e,0x33, 0x2,0x61,0x42, 0x3,0x5f,0x3f, + 0x2,0x6e,0x7c, 0x3,0x61,0x61, 0x2,0x71,0x6f, 0x3,0x61,0x77, + 0xf,0x58,0x4c, 0x1,0x21,0x2b, 0x1,0x21,0x36, 0x1,0x21,0x38, + 0x1,0x21,0x40, 0x1,0x21,0x41, 0x1,0x21,0x44, 0x1,0x21,0x45, + 0x1,0x21,0x48, 0x1,0x21,0x49, 0x1,0x21,0x4c, 0x1,0x21,0x4d, + 0x1,0x21,0x50, 0x1,0x21,0x51, 0x1,0x21,0x54, 0x1,0x21,0x55, + 0x1,0x21,0x58, 0x1,0x21,0x59, 0x1,0x21,0x5c, 0x1,0x21,0x5d, + 0x1,0x22,0x27, 0x1,0x22,0x28, 0x1,0x22,0x2b, 0x1,0x22,0x2c, + 0x1,0x22,0x29, 0x1,0x22,0x2a, 0x1,0x21,0x2e, 0x1,0x21,0x2f, + 0x1,0x21,0x30, 0x1,0x21,0x32, 0x1,0x21,0x33, 0x1,0x21,0x34, + 0x1,0x21,0x35, 0x1,0x21,0x5e, 0x1,0x21,0x5f, 0x1,0x21,0x60, + 0x1,0x21,0x61, 0x1,0x21,0x62, 0x1,0x21,0x63, 0x1,0x22,0x2d, + 0x1,0x22,0x2e, 0x1,0x22,0x2f, 0x1,0x22,0x3f, 0x1,0x22,0x40, + 0x1,0x22,0x41, 0x1,0x22,0x43, 0x1,0x22,0x42, 0x1,0x22,0x62, + 0x1,0x22,0x6c, 0x1,0x22,0x6d, 0x1,0x22,0x6e, 0x1,0x21,0x2a, + 0x1,0x21,0x6c, 0x1,0x22,0x63, 0x1,0x22,0x68, 0x1,0x21,0x6d, + 0x1,0x21,0x3e, 0x1,0x21,0x3f, 0x1,0x21,0x6e, 0x1,0x22,0x30, + 0x1,0x21,0x22, 0x1,0x22,0x31, 0x1,0x21,0x25, 0x1,0x22,0x5f, + 0x1,0x24,0x21, 0x1,0x24,0x22, 0x1,0x24,0x23, 0x1,0x24,0x24, + 0x1,0x24,0x25, 0x1,0x24,0x26, 0x1,0x24,0x27, 0x1,0x24,0x28, + 0x1,0x24,0x29, 0x1,0x24,0x2a, 0x1,0x21,0x28, 0x1,0x21,0x27, + 0x1,0x22,0x36, 0x1,0x22,0x38, 0x1,0x22,0x37, 0x1,0x21,0x29, + 0x1,0x22,0x69, 0x1,0x24,0x41, 0x1,0x24,0x42, 0x1,0x24,0x43, + 0x1,0x24,0x44, 0x1,0x24,0x45, 0x1,0x24,0x46, 0x1,0x24,0x47, + 0x1,0x24,0x48, 0x1,0x24,0x49, 0x1,0x24,0x4a, 0x1,0x24,0x4b, + 0x1,0x24,0x4c, 0x1,0x24,0x4d, 0x1,0x24,0x4e, 0x1,0x24,0x4f, + 0x1,0x24,0x50, 0x1,0x24,0x51, 0x1,0x24,0x52, 0x1,0x24,0x53, + 0x1,0x24,0x54, 0x1,0x24,0x55, 0x1,0x24,0x56, 0x1,0x24,0x57, + 0x1,0x24,0x58, 0x1,0x24,0x59, 0x1,0x24,0x5a, 0x1,0x22,0x60, + 0x1,0x22,0x25, 0x1,0x24,0x5b, 0x1,0x24,0x5c, 0x1,0x24,0x5d, + 0x1,0x24,0x5e, 0x1,0x24,0x5f, 0x1,0x24,0x60, 0x1,0x24,0x61, + 0x1,0x24,0x62, 0x1,0x24,0x63, 0x1,0x24,0x64, 0x1,0x24,0x65, + 0x1,0x24,0x66, 0x1,0x24,0x67, 0x1,0x24,0x68, 0x1,0x24,0x69, + 0x1,0x24,0x6a, 0x1,0x24,0x6b, 0x1,0x24,0x6c, 0x1,0x24,0x6d, + 0x1,0x24,0x6e, 0x1,0x24,0x6f, 0x1,0x24,0x70, 0x1,0x24,0x71, + 0x1,0x24,0x72, 0x1,0x24,0x73, 0x1,0x24,0x74, 0x1,0x21,0x42, + 0x1,0x22,0x5e, 0x1,0x21,0x43, 0x1,0x22,0x66, 0x1,0x22,0x67, + 0x1,0x22,0x64, 0x5,0x21,0x25, 0xf,0x21,0x21, 0x6,0x21,0x2f, + 0x6,0x21,0x2d, 0x6,0x21,0x2e, 0x6,0x21,0x42, 0x6,0x21,0x43, + 0x5,0x21,0x33, 0x3,0x21,0x44, 0xf,0x21,0x3e, 0xf,0x21,0x3f, + 0x6,0x22,0x2b, 0x5,0x21,0x4d, 0x6,0x23,0x40, 0x6,0x23,0x3e, + 0x6,0x23,0x3f, 0x6,0x24,0x67, 0x6,0x25,0x5f, 0x5,0x23,0x2f, + 0xf,0x22,0x74, 0x6,0x25,0x67, 0x6,0x25,0x63, 0x6,0x29,0x37, + 0x6,0x29,0x3a, 0x6,0x29,0x38, 0xf,0x29,0x22, 0xf,0x29,0x23, + 0x6,0x2e,0x66, 0x5,0x30,0x72, 0x5,0x33,0x23, 0xf,0x39,0x32, + 0xf,0x39,0x33, 0x6,0x47,0x2d, 0xf,0x3b,0x73, 0xf,0x40,0x35, + 0xf,0x40,0x75, 0xf,0x47,0x42, 0xf,0x4d,0x56, 0x7,0x21,0x21, + 0xf,0x59,0x47, 0x4,0x4f,0x7c, 0xf,0x5a,0x3f, 0x6,0x21,0x2c, + 0x6,0x21,0x22, 0x6,0x22,0x5f, 0x4,0x21,0x56, 0x6,0x23,0x41, + 0x6,0x25,0x60, 0x6,0x29,0x3b, 0x5,0x25,0x21, 0x5,0x27,0x7a, + 0x6,0x2e,0x4a, 0xf,0x29,0x50, 0x6,0x35,0x25, 0x6,0x35,0x26, + 0x6,0x45,0x7d, 0x6,0x46,0x3f, 0xf,0x46,0x40, 0x5,0x44,0x7e, + 0x6,0x21,0x32, 0x5,0x21,0x2d, 0x6,0x22,0x2d, 0x6,0x23,0x42, + 0xf,0x2d,0x61, 0x6,0x50,0x50, 0xf,0x53,0x44, 0x4,0x21,0x21, + 0x5,0x21,0x26, 0x6,0x21,0x24, 0xf,0x21,0x22, 0x6,0x21,0x33, + 0x6,0x21,0x44, 0xf,0x21,0x25, 0xf,0x21,0x26, 0x5,0x21,0x4e, + 0x6,0x22,0x30, 0xf,0x21,0x45, 0x6,0x22,0x4e, 0x6,0x22,0x2f, + 0xf,0x21,0x40, 0xf,0x21,0x41, 0x6,0x21,0x45, 0x6,0x22,0x31, + 0x6,0x22,0x2e, 0x4,0x22,0x26, 0x4,0x22,0x25, 0x5,0x22,0x24, + 0x5,0x22,0x25, 0x6,0x23,0x43, 0x6,0x29,0x3e, 0x6,0x24,0x5d, + 0x6,0x25,0x56, 0x6,0x25,0x61, 0x6,0x25,0x62, 0x6,0x2c,0x43, + 0x6,0x29,0x3c, 0x6,0x3a,0x65, 0xf,0x29,0x25, 0x6,0x2d,0x2d, + 0x6,0x29,0x3d, 0x6,0x2e,0x4b, 0x5,0x2b,0x67, 0x6,0x35,0x2a, + 0x6,0x35,0x27, 0x6,0x39,0x64, 0x6,0x35,0x29, 0x6,0x3c,0x7b, + 0x6,0x45,0x7e, 0x6,0x46,0x40, 0x6,0x46,0x41, 0x5,0x3d,0x56, + 0x5,0x21,0x23, 0x5,0x21,0x22, 0x6,0x21,0x26, 0x6,0x21,0x25, + 0x5,0x21,0x21, 0x5,0x21,0x2b, 0xf,0x21,0x23, 0x6,0x21,0x46, + 0x5,0x21,0x34, 0xf,0x21,0x27, 0xf,0x21,0x28, 0x6,0x22,0x33, + 0x6,0x22,0x32, 0x6,0x22,0x2a, 0x5,0x21,0x4f, 0x6,0x23,0x46, + 0x6,0x23,0x44, 0xf,0x21,0x6e, 0x6,0x23,0x45, 0xf,0x22,0x75, + 0x6,0x29,0x3f, 0x6,0x2d,0x2c, 0x4,0x26,0x24, 0x6,0x2e,0x4d, + 0x6,0x2e,0x4e, 0xf,0x25,0x40, 0x6,0x2e,0x4c, 0x6,0x35,0x2b, + 0xf,0x2d,0x60, 0x6,0x3c,0x7e, 0x5,0x30,0x73, 0x6,0x3c,0x7d, + 0xf,0x39,0x34, 0x6,0x50,0x51, 0x5,0x44,0x55, 0xf,0x46,0x41, + 0x6,0x5a,0x63, 0x6,0x5a,0x62, 0x7,0x36,0x73, 0x7,0x46,0x27, + 0x7,0x4d,0x3a, 0x5,0x21,0x24, 0x5,0x21,0x27, 0x4,0x21,0x28, + 0x5,0x21,0x28, 0x5,0x21,0x2c, 0x6,0x21,0x47, 0x6,0x21,0x48, + 0x6,0x21,0x49, 0x6,0x23,0x47, 0x5,0x23,0x30, 0x6,0x25,0x64, + 0x6,0x29,0x40, 0x5,0x30,0x74, 0x6,0x46,0x42, 0x7,0x2c,0x3c, + 0x6,0x21,0x27, 0x6,0x21,0x28, 0x6,0x21,0x29, 0x6,0x21,0x4a, + 0x6,0x25,0x65, 0x6,0x23,0x48, 0x6,0x23,0x49, 0x6,0x25,0x68, + 0xf,0x22,0x76, 0x4,0x25,0x33, 0x5,0x25,0x22, 0x4,0x25,0x32, + 0x6,0x2e,0x50, 0x5,0x27,0x7b, 0xf,0x29,0x27, 0x6,0x30,0x7c, + 0x6,0x35,0x2d, 0x6,0x35,0x2c, 0xf,0x2d,0x62, 0x6,0x3d,0x21, + 0xf,0x4d,0x6e, 0x6,0x23,0x4a, 0xf,0x21,0x6f, 0xf,0x21,0x70, + 0xf,0x22,0x2b, 0x5,0x23,0x31, 0xf,0x22,0x77, 0xf,0x22,0x78, + 0xf,0x22,0x79, 0x5,0x25,0x23, 0x6,0x29,0x41, 0xf,0x25,0x43, + 0x6,0x2e,0x52, 0x6,0x2e,0x51, 0xf,0x29,0x28, 0x6,0x35,0x2f, + 0x5,0x2c,0x66, 0x4,0x2b,0x5f, 0x6,0x35,0x30, 0xf,0x2d,0x63, + 0x6,0x35,0x31, 0x6,0x46,0x43, 0x6,0x3d,0x23, 0x6,0x3d,0x22, + 0x4,0x30,0x44, 0x5,0x30,0x75, 0xf,0x32,0x74, 0xf,0x32,0x75, + 0xf,0x32,0x72, 0x6,0x46,0x45, 0x6,0x46,0x44, 0x6,0x46,0x46, + 0x4,0x36,0x2f, 0xf,0x39,0x35, 0xf,0x39,0x36, 0xf,0x39,0x37, + 0x6,0x4c,0x2d, 0xf,0x40,0x36, 0xf,0x40,0x37, 0xf,0x40,0x38, + 0xf,0x46,0x42, 0x6,0x50,0x52, 0x5,0x4b,0x71, 0x7,0x21,0x22, + 0xf,0x4d,0x57, 0xf,0x4d,0x58, 0xf,0x4d,0x59, 0x7,0x26,0x79, + 0x7,0x21,0x24, 0x7,0x21,0x23, 0x7,0x21,0x46, 0x7,0x2c,0x3f, + 0x5,0x53,0x53, 0x7,0x2c,0x3e, 0x7,0x2c,0x3d, 0x7,0x46,0x23, + 0x7,0x46,0x28, 0x6,0x21,0x34, 0x6,0x21,0x35, 0xf,0x21,0x24, + 0x6,0x21,0x4c, 0xf,0x21,0x29, 0x6,0x21,0x4b, 0x3,0x21,0x6f, + 0xf,0x21,0x43, 0x6,0x22,0x35, 0x6,0x22,0x34, 0x6,0x22,0x36, + 0x4,0x21,0x58, 0x4,0x22,0x2c, 0x4,0x22,0x2b, 0x4,0x22,0x29, + 0x6,0x23,0x4f, 0x4,0x22,0x30, 0x6,0x23,0x50, 0x5,0x22,0x27, + 0x6,0x23,0x4d, 0x6,0x23,0x4c, 0x4,0x22,0x2f, 0x6,0x23,0x4b, + 0xf,0x21,0x73, 0xf,0x21,0x74, 0xf,0x21,0x75, 0xf,0x21,0x76, + 0xf,0x21,0x77, 0xf,0x21,0x78, 0xf,0x21,0x79, 0x5,0x22,0x28, + 0x6,0x23,0x51, 0x5,0x22,0x26, 0xf,0x21,0x7a, 0x5,0x23,0x32, + 0x6,0x25,0x6a, 0x4,0x23,0x3a, 0x6,0x25,0x6b, 0x6,0x25,0x74, + 0x6,0x25,0x70, 0x6,0x25,0x6c, 0xf,0x22,0x7a, 0xf,0x22,0x7b, + 0xf,0x22,0x7c, 0xf,0x22,0x7d, 0xf,0x23,0x21, 0xf,0x23,0x22, + 0xf,0x23,0x23, 0xf,0x23,0x25, 0xf,0x23,0x28, 0xf,0x23,0x29, + 0xf,0x23,0x2a, 0xf,0x23,0x2b, 0xf,0x23,0x2c, 0x4,0x23,0x38, + 0x6,0x25,0x6d, 0x6,0x25,0x6f, 0xf,0x23,0x26, 0x6,0x25,0x6e, + 0x6,0x25,0x69, 0x5,0x23,0x33, 0x6,0x25,0x73, 0x6,0x29,0x43, + 0x6,0x29,0x45, 0x4,0x25,0x3a, 0x5,0x25,0x28, 0x6,0x29,0x46, + 0x5,0x25,0x29, 0x3,0x27,0x4e, 0x5,0x25,0x2a, 0x4,0x25,0x37, + 0x4,0x25,0x35, 0x6,0x29,0x4a, 0x6,0x29,0x44, 0x6,0x29,0x4c, + 0x6,0x29,0x47, 0x6,0x29,0x4e, 0x5,0x25,0x26, 0x6,0x29,0x42, + 0xf,0x25,0x45, 0xf,0x25,0x46, 0xf,0x25,0x48, 0xf,0x25,0x49, + 0xf,0x25,0x4b, 0xf,0x25,0x4c, 0xf,0x25,0x4d, 0xf,0x25,0x4e, + 0xf,0x25,0x4f, 0xf,0x25,0x50, 0xf,0x25,0x51, 0x6,0x29,0x4d, + 0x6,0x29,0x48, 0x6,0x29,0x49, 0x6,0x29,0x4b, 0x5,0x25,0x24, + 0x5,0x25,0x27, 0x5,0x27,0x7c, 0x6,0x2e,0x64, 0x6,0x2e,0x59, + 0x5,0x2b,0x72, 0x4,0x28,0x36, 0x6,0x2e,0x63, 0x6,0x2e,0x57, + 0x6,0x2e,0x56, 0x5,0x28,0x23, 0x4,0x28,0x3b, 0x6,0x2e,0x5d, + 0x5,0x27,0x7e, 0x5,0x27,0x7d, 0x5,0x28,0x22, 0x6,0x2e,0x62, + 0x6,0x2e,0x55, 0x6,0x2e,0x54, 0x6,0x2e,0x65, 0x6,0x2e,0x5c, + 0xf,0x29,0x29, 0xf,0x29,0x2a, 0xf,0x29,0x2b, 0xf,0x29,0x2c, + 0xf,0x29,0x2e, 0xf,0x29,0x2f, 0xf,0x29,0x31, 0xf,0x29,0x32, + 0xf,0x29,0x33, 0xf,0x29,0x34, 0xf,0x29,0x35, 0xf,0x29,0x36, + 0xf,0x29,0x37, 0xf,0x29,0x38, 0x6,0x2e,0x53, 0x6,0x2e,0x58, + 0x6,0x2e,0x5b, 0x6,0x2e,0x5e, 0x6,0x2e,0x60, 0xf,0x25,0x47, + 0x6,0x2e,0x5f, 0x5,0x28,0x24, 0x4,0x2b,0x63, 0x5,0x2b,0x70, + 0x4,0x2b,0x67, 0x6,0x35,0x36, 0x5,0x2b,0x6b, 0x6,0x35,0x35, + 0x5,0x2b,0x74, 0x4,0x2b,0x66, 0x4,0x2b,0x68, 0x5,0x2b,0x6f, + 0x6,0x35,0x32, 0x5,0x2b,0x69, 0xf,0x2d,0x64, 0xf,0x2d,0x6e, + 0x6,0x35,0x37, 0x5,0x2b,0x6e, 0xf,0x2d,0x66, 0xf,0x2d,0x67, + 0xf,0x2d,0x6a, 0xf,0x2d,0x6b, 0xf,0x2d,0x6c, 0xf,0x2d,0x6d, + 0xf,0x2d,0x6f, 0xf,0x2d,0x71, 0xf,0x2d,0x72, 0xf,0x2d,0x73, + 0xf,0x2d,0x74, 0xf,0x2d,0x75, 0xf,0x2d,0x76, 0xf,0x2d,0x78, + 0xf,0x2d,0x79, 0xf,0x2d,0x7a, 0xf,0x2d,0x7b, 0xf,0x2d,0x7c, + 0x6,0x35,0x21, 0x6,0x35,0x3a, 0x6,0x35,0x3b, 0x6,0x35,0x33, + 0x6,0x35,0x34, 0x5,0x2b,0x68, 0x6,0x35,0x39, 0xf,0x2d,0x77, + 0xf,0x2d,0x70, 0x5,0x2b,0x6a, 0x5,0x2b,0x6d, 0x5,0x2b,0x75, + 0x5,0x2b,0x71, 0x5,0x2b,0x73, 0x4,0x2b,0x60, 0x6,0x3d,0x2b, + 0x6,0x3d,0x2d, 0x6,0x3d,0x2c, 0x4,0x30,0x49, 0x4,0x30,0x48, + 0x6,0x3d,0x30, 0x6,0x3d,0x28, 0x5,0x31,0x21, 0x6,0x3d,0x33, + 0x5,0x30,0x77, 0x6,0x3d,0x2e, 0x6,0x3d,0x27, 0x5,0x31,0x22, + 0x5,0x30,0x76, 0x4,0x30,0x46, 0x6,0x3d,0x2a, 0x6,0x3d,0x31, + 0x6,0x3d,0x37, 0x6,0x3d,0x32, 0x6,0x3d,0x29, 0x4,0x30,0x4b, + 0x6,0x3d,0x34, 0xf,0x2d,0x69, 0xf,0x32,0x77, 0xf,0x32,0x78, + 0xf,0x32,0x79, 0xf,0x32,0x7a, 0xf,0x32,0x7b, 0xf,0x32,0x7c, + 0xf,0x32,0x7e, 0xf,0x33,0x21, 0xf,0x33,0x23, 0xf,0x33,0x24, + 0xf,0x33,0x25, 0xf,0x33,0x26, 0xf,0x33,0x27, 0x6,0x46,0x37, + 0x6,0x3d,0x38, 0x6,0x3e,0x65, 0x6,0x3d,0x39, 0x6,0x3d,0x2f, + 0x5,0x30,0x7a, 0x6,0x43,0x63, 0x5,0x30,0x7d, 0x5,0x31,0x23, + 0x6,0x3d,0x24, 0x6,0x3d,0x26, 0xf,0x32,0x7d, 0x5,0x30,0x79, + 0x5,0x30,0x7e, 0x5,0x30,0x78, 0x6,0x3d,0x25, 0x6,0x3d,0x36, + 0x5,0x30,0x7c, 0x6,0x46,0x49, 0x6,0x46,0x4f, 0x5,0x36,0x56, + 0x5,0x36,0x51, 0x6,0x46,0x4c, 0x5,0x36,0x4e, 0x5,0x36,0x52, + 0x5,0x36,0x63, 0x5,0x36,0x53, 0x6,0x46,0x48, 0x5,0x36,0x55, + 0x5,0x36,0x50, 0x6,0x46,0x56, 0x4,0x36,0x35, 0x5,0x36,0x54, + 0x6,0x46,0x52, 0x6,0x46,0x50, 0x6,0x46,0x4b, 0x6,0x46,0x4e, + 0x6,0x46,0x53, 0xf,0x32,0x76, 0x6,0x46,0x58, 0x5,0x36,0x4f, + 0x5,0x36,0x57, 0x6,0x46,0x47, 0xf,0x39,0x38, 0xf,0x39,0x39, + 0xf,0x39,0x3a, 0xf,0x39,0x3b, 0xf,0x39,0x3c, 0xf,0x39,0x3d, + 0xf,0x39,0x3e, 0xf,0x39,0x3f, 0x6,0x46,0x4d, 0x4,0x36,0x3b, + 0x6,0x46,0x51, 0x6,0x46,0x54, 0x5,0x36,0x4d, 0x6,0x46,0x4a, + 0x5,0x34,0x21, 0x6,0x50,0x5a, 0x4,0x42,0x38, 0x5,0x3d,0x5a, + 0x5,0x3d,0x58, 0x6,0x50,0x53, 0x5,0x30,0x7b, 0x5,0x3d,0x5e, + 0x5,0x3d,0x5c, 0x6,0x50,0x58, 0x5,0x3d,0x5b, 0x6,0x50,0x5f, + 0x6,0x50,0x5d, 0x4,0x3c,0x2e, 0x6,0x50,0x5c, 0x6,0x50,0x62, + 0x6,0x50,0x55, 0x4,0x3c,0x2f, 0x5,0x3d,0x60, 0x6,0x50,0x54, + 0x5,0x3d,0x57, 0x6,0x50,0x57, 0x6,0x50,0x5e, 0xf,0x40,0x39, + 0xf,0x40,0x3a, 0xf,0x40,0x3b, 0xf,0x40,0x3c, 0xf,0x40,0x3d, + 0xf,0x40,0x3e, 0xf,0x40,0x3f, 0xf,0x40,0x40, 0xf,0x40,0x41, + 0xf,0x40,0x42, 0xf,0x40,0x43, 0xf,0x40,0x44, 0xf,0x40,0x45, + 0xf,0x40,0x46, 0x6,0x50,0x61, 0x6,0x56,0x4e, 0x6,0x50,0x59, + 0x6,0x50,0x56, 0x6,0x46,0x57, 0x5,0x3d,0x59, 0x5,0x3d,0x5d, + 0x5,0x3d,0x5f, 0x4,0x3c,0x2b, 0x6,0x50,0x60, 0x6,0x5a,0x71, + 0x5,0x3d,0x61, 0x7,0x21,0x2e, 0x4,0x42,0x34, 0x5,0x44,0x56, + 0x6,0x5a,0x64, 0x6,0x5a,0x69, 0x5,0x3d,0x62, 0x6,0x5a,0x6b, + 0x4,0x42,0x39, 0x6,0x5a,0x74, 0x4,0x42,0x31, 0x6,0x5a,0x75, + 0x6,0x5a,0x68, 0x6,0x5a,0x67, 0x6,0x5a,0x76, 0xf,0x46,0x43, + 0xf,0x46,0x44, 0xf,0x46,0x45, 0xf,0x46,0x46, 0xf,0x46,0x47, + 0xf,0x46,0x49, 0xf,0x46,0x4a, 0xf,0x46,0x4b, 0xf,0x46,0x4c, + 0xf,0x46,0x4d, 0xf,0x46,0x4e, 0xf,0x46,0x4f, 0xf,0x46,0x51, + 0xf,0x46,0x52, 0xf,0x46,0x53, 0xf,0x46,0x54, 0xf,0x46,0x56, + 0xf,0x46,0x57, 0xf,0x46,0x58, 0xf,0x53,0x45, 0x7,0x26,0x2d, + 0x5,0x44,0x58, 0x6,0x5a,0x77, 0x6,0x5e,0x57, 0x6,0x5a,0x6d, + 0x6,0x5a,0x6f, 0x6,0x5a,0x65, 0xf,0x46,0x50, 0xf,0x46,0x48, + 0xf,0x46,0x55, 0x4,0x42,0x30, 0x6,0x5a,0x66, 0x6,0x5a,0x6a, + 0x6,0x5a,0x6e, 0x6,0x5a,0x70, 0x4,0x42,0x36, 0x5,0x3f,0x46, + 0x4,0x48,0x7e, 0x4,0x48,0x7a, 0x6,0x5a,0x6c, 0x7,0x21,0x2f, + 0x7,0x21,0x31, 0x7,0x21,0x29, 0x7,0x21,0x26, 0x7,0x21,0x25, + 0x5,0x4b,0x77, 0x4,0x48,0x7c, 0x7,0x21,0x2b, 0x7,0x21,0x2c, + 0x5,0x4b,0x73, 0x7,0x21,0x2a, 0x5,0x4b,0x79, 0x5,0x4b,0x78, + 0x7,0x21,0x27, 0xf,0x4d,0x5a, 0xf,0x4d,0x5b, 0xf,0x4d,0x5c, + 0xf,0x4d,0x5d, 0xf,0x4d,0x5e, 0xf,0x4d,0x60, 0xf,0x4d,0x61, + 0x7,0x21,0x28, 0x5,0x4b,0x72, 0x7,0x21,0x2d, 0xf,0x4d,0x62, + 0x4,0x49,0x21, 0x5,0x4b,0x75, 0x7,0x21,0x30, 0x5,0x4b,0x74, + 0x5,0x4c,0x45, 0x5,0x53,0x54, 0x5,0x53,0x5a, 0x7,0x2c,0x40, + 0x4,0x4f,0x58, 0x4,0x4f,0x5f, 0x5,0x53,0x58, 0x4,0x4f,0x5c, + 0x4,0x4f,0x5e, 0x5,0x53,0x55, 0x5,0x53,0x56, 0xf,0x53,0x46, + 0xf,0x53,0x47, 0xf,0x53,0x48, 0xf,0x53,0x49, 0xf,0x53,0x4a, + 0x5,0x53,0x5b, 0x5,0x53,0x57, 0x7,0x36,0x78, 0x5,0x4b,0x76, + 0x5,0x5a,0x6f, 0x5,0x5a,0x70, 0x4,0x55,0x67, 0x4,0x55,0x66, + 0x7,0x36,0x76, 0xf,0x59,0x48, 0xf,0x59,0x4a, 0xf,0x59,0x4b, + 0xf,0x59,0x4c, 0xf,0x59,0x4e, 0x7,0x36,0x75, 0x7,0x36,0x77, + 0xf,0x59,0x49, 0x4,0x55,0x68, 0x7,0x36,0x74, 0x7,0x3e,0x76, + 0x4,0x5a,0x6b, 0x4,0x5a,0x69, 0x4,0x5a,0x6a, 0x7,0x3e,0x78, + 0x7,0x3e,0x77, 0xf,0x5e,0x30, 0xf,0x5e,0x31, 0xf,0x5e,0x2c, + 0xf,0x5e,0x2e, 0xf,0x5e,0x2f, 0x7,0x3e,0x75, 0x5,0x61,0x31, + 0x4,0x5a,0x6c, 0x5,0x61,0x2f, 0x5,0x61,0x30, 0x5,0x61,0x32, + 0x5,0x67,0x4a, 0x5,0x67,0x4e, 0x4,0x63,0x2e, 0x5,0x67,0x4d, + 0x5,0x67,0x4f, 0xf,0x61,0x7e, 0xf,0x62,0x21, 0x7,0x47,0x6f, + 0x5,0x67,0x4c, 0x5,0x67,0x4b, 0x5,0x69,0x7c, 0x7,0x52,0x75, + 0x7,0x4d,0x3c, 0xf,0x64,0x7a, 0x5,0x6b,0x6b, 0x7,0x4d,0x3b, + 0x7,0x4d,0x68, 0x4,0x66,0x2f, 0x4,0x66,0x2e, 0x5,0x6f,0x68, + 0x7,0x57,0x4e, 0x5,0x6b,0x6c, 0xf,0x67,0x3f, 0xf,0x67,0x7e, + 0x4,0x66,0x2d, 0x7,0x57,0x4d, 0xf,0x69,0x38, 0xf,0x69,0x3a, + 0xf,0x69,0x39, 0x5,0x73,0x31, 0x4,0x6a,0x40, 0x7,0x5b,0x45, + 0xf,0x6a,0x4b, 0xf,0x6b,0x41, 0x5,0x75,0x62, 0x4,0x6d,0x52, + 0xf,0x6c,0x49, 0x6,0x21,0x4d, 0x4,0x21,0x5c, 0x4,0x22,0x32, + 0x6,0x23,0x53, 0x6,0x23,0x54, 0x6,0x25,0x75, 0x6,0x25,0x77, + 0x6,0x25,0x78, 0x5,0x23,0x35, 0x6,0x25,0x76, 0x6,0x29,0x51, + 0x6,0x29,0x50, 0x6,0x29,0x4f, 0x6,0x29,0x53, 0xf,0x25,0x53, + 0x6,0x29,0x52, 0xf,0x25,0x52, 0x6,0x2e,0x67, 0x6,0x2e,0x68, + 0x5,0x2b,0x76, 0xf,0x2d,0x7d, 0xf,0x2d,0x7e, 0xf,0x2e,0x21, + 0x6,0x35,0x3c, 0xf,0x33,0x28, 0x5,0x31,0x24, 0x5,0x31,0x25, + 0xf,0x33,0x29, 0xf,0x33,0x2a, 0x6,0x46,0x59, 0xf,0x39,0x40, + 0xf,0x39,0x41, 0xf,0x39,0x42, 0x5,0x36,0x58, 0xf,0x39,0x43, + 0xf,0x40,0x47, 0x6,0x50,0x63, 0xf,0x40,0x48, 0xf,0x46,0x59, + 0xf,0x46,0x5a, 0x5,0x44,0x59, 0x7,0x21,0x34, 0x7,0x21,0x32, + 0x5,0x4b,0x7b, 0xf,0x4d,0x63, 0xf,0x4d,0x64, 0x5,0x4b,0x7a, + 0x7,0x21,0x33, 0x5,0x53,0x5c, 0x7,0x2c,0x41, 0xf,0x53,0x4b, + 0xf,0x53,0x4c, 0xf,0x53,0x4d, 0xf,0x53,0x4e, 0x5,0x5a,0x71, + 0xf,0x59,0x4f, 0xf,0x59,0x50, 0xf,0x59,0x51, 0x7,0x3e,0x79, + 0x5,0x61,0x33, 0xf,0x5e,0x32, 0x7,0x46,0x29, 0x5,0x67,0x50, + 0xf,0x64,0x7b, 0x5,0x67,0x51, 0x5,0x6b,0x6d, 0xf,0x67,0x41, + 0xf,0x69,0x3b, 0xf,0x6a,0x4c, 0x5,0x77,0x53, 0xf,0x6b,0x42, + 0x6,0x21,0x36, 0x5,0x21,0x36, 0x5,0x21,0x35, 0x6,0x22,0x37, + 0x6,0x23,0x56, 0x6,0x23,0x55, 0x5,0x23,0x36, 0x6,0x25,0x79, + 0x5,0x23,0x38, 0x5,0x28,0x25, 0x5,0x28,0x26, 0x4,0x2b,0x6a, + 0x6,0x35,0x3d, 0xf,0x2e,0x22, 0xf,0x2e,0x23, 0x6,0x3d,0x3a, + 0x6,0x46,0x5a, 0x6,0x50,0x64, 0x5,0x3d,0x63, 0x4,0x3c,0x31, + 0x6,0x5a,0x78, 0x5,0x5a,0x72, 0x6,0x21,0x37, 0x6,0x21,0x4e, + 0x5,0x21,0x37, 0x6,0x21,0x41, 0x6,0x21,0x59, 0x5,0x21,0x50, + 0x6,0x23,0x3b, 0x4,0x22,0x35, 0x6,0x23,0x57, 0x6,0x25,0x7c, + 0x6,0x25,0x7e, 0x5,0x23,0x39, 0xf,0x23,0x2d, 0x6,0x25,0x7a, + 0x6,0x29,0x54, 0x6,0x2e,0x6b, 0x6,0x2e,0x69, 0x5,0x28,0x27, + 0x6,0x2e,0x6a, 0x6,0x2e,0x4f, 0x6,0x30,0x7b, 0x6,0x35,0x40, + 0x6,0x35,0x3f, 0x6,0x35,0x41, 0x6,0x35,0x3e, 0x6,0x3d,0x3b, + 0x6,0x46,0x5d, 0x5,0x3d,0x64, 0xf,0x39,0x44, 0xf,0x39,0x45, + 0x6,0x46,0x5b, 0x6,0x46,0x5c, 0x5,0x3d,0x65, 0x6,0x50,0x65, + 0xf,0x40,0x49, 0xf,0x40,0x4a, 0x4,0x42,0x3a, 0x6,0x5a,0x79, + 0xf,0x54,0x46, 0xf,0x53,0x4f, 0xf,0x53,0x50, 0x5,0x61,0x34, + 0xf,0x5e,0x33, 0x7,0x46,0x2a, 0x7,0x46,0x2b, 0x4,0x21,0x2d, + 0x6,0x21,0x4f, 0x6,0x21,0x51, 0x6,0x22,0x39, 0x4,0x21,0x5d, + 0x6,0x22,0x38, 0x5,0x21,0x52, 0xf,0x21,0x46, 0x6,0x22,0x3a, + 0x5,0x21,0x51, 0x6,0x23,0x5a, 0x6,0x23,0x58, 0x6,0x25,0x47, + 0x6,0x26,0x23, 0x6,0x26,0x21, 0x6,0x26,0x22, 0x5,0x23,0x3a, + 0x6,0x28,0x7a, 0x5,0x25,0x2c, 0x6,0x29,0x55, 0x6,0x29,0x56, + 0x6,0x2e,0x6c, 0x6,0x35,0x42, 0x6,0x35,0x43, 0x5,0x2b,0x77, + 0x5,0x2b,0x78, 0x6,0x3d,0x3d, 0x6,0x46,0x5f, 0x3,0x39,0x77, + 0x6,0x46,0x5e, 0x4,0x3c,0x33, 0x5,0x3d,0x66, 0x6,0x5a,0x7b, + 0x6,0x5a,0x7a, 0x7,0x21,0x35, 0x5,0x53,0x5d, 0x7,0x2c,0x42, + 0xf,0x55,0x76, 0x4,0x5a,0x6d, 0xf,0x67,0x42, 0x7,0x57,0x4f, + 0x5,0x21,0x38, 0x6,0x22,0x3b, 0xf,0x21,0x48, 0xf,0x21,0x49, + 0x6,0x23,0x5b, 0x4,0x22,0x37, 0x5,0x22,0x29, 0xf,0x21,0x7b, + 0xf,0x23,0x2e, 0xf,0x23,0x2f, 0x5,0x25,0x2d, 0xf,0x25,0x55, + 0x6,0x2e,0x6d, 0x6,0x3d,0x3e, 0xf,0x2e,0x25, 0xf,0x2e,0x26, + 0xf,0x2e,0x27, 0xf,0x2e,0x28, 0xf,0x2e,0x29, 0x5,0x31,0x27, + 0x6,0x46,0x60, 0xf,0x39,0x47, 0xf,0x39,0x48, 0x6,0x46,0x61, + 0xf,0x3a,0x5d, 0x6,0x50,0x66, 0x6,0x5a,0x7c, 0xf,0x46,0x5b, + 0x5,0x4e,0x77, 0x7,0x2c,0x43, 0xf,0x59,0x52, 0xf,0x53,0x51, + 0x7,0x3e,0x7a, 0x7,0x46,0x2c, 0x7,0x4d,0x3f, 0x5,0x6f,0x69, + 0x5,0x75,0x63, 0xf,0x21,0x4a, 0x6,0x23,0x5c, 0xf,0x21,0x7d, + 0xf,0x21,0x7e, 0x4,0x22,0x38, 0x5,0x23,0x3b, 0x6,0x26,0x24, + 0x4,0x23,0x3c, 0xf,0x23,0x30, 0xf,0x23,0x31, 0xf,0x23,0x32, + 0xf,0x23,0x33, 0xf,0x23,0x24, 0xf,0x22,0x7e, 0x4,0x25,0x41, + 0x4,0x25,0x42, 0x6,0x29,0x58, 0x6,0x29,0x59, 0x5,0x25,0x2f, + 0xf,0x25,0x57, 0x5,0x28,0x29, 0x4,0x28,0x41, 0x4,0x28,0x42, + 0x5,0x28,0x2c, 0x5,0x28,0x28, 0x5,0x28,0x2a, 0x6,0x2e,0x6f, + 0xf,0x29,0x3a, 0xf,0x29,0x3c, 0xf,0x29,0x3d, 0xf,0x29,0x3e, + 0xf,0x29,0x3f, 0x6,0x2e,0x6e, 0x5,0x2b,0x7a, 0x4,0x2b,0x6b, + 0x5,0x2b,0x79, 0x5,0x28,0x2b, 0x6,0x35,0x45, 0x5,0x2b,0x7b, + 0xf,0x2e,0x2a, 0xf,0x2e,0x2b, 0x6,0x35,0x46, 0x5,0x31,0x28, + 0x6,0x3d,0x3f, 0x6,0x3d,0x40, 0x4,0x30,0x4e, 0xf,0x33,0x2b, + 0xf,0x33,0x2c, 0xf,0x33,0x2d, 0xf,0x33,0x2f, 0xf,0x33,0x30, + 0x6,0x46,0x62, 0x5,0x36,0x5c, 0x5,0x36,0x5a, 0x5,0x36,0x5b, + 0x5,0x36,0x59, 0x4,0x36,0x3e, 0xf,0x33,0x2e, 0x5,0x3d,0x6c, + 0x5,0x3d,0x67, 0x5,0x3d,0x69, 0x5,0x3d,0x6a, 0x5,0x3d,0x68, + 0x5,0x3d,0x6b, 0x6,0x50,0x67, 0x6,0x5a,0x7d, 0x5,0x4c,0x21, + 0x5,0x44,0x5a, 0x7,0x21,0x37, 0xf,0x46,0x5d, 0xf,0x46,0x5e, + 0x5,0x4b,0x7e, 0x5,0x4b,0x7d, 0x5,0x4b,0x7c, 0x7,0x21,0x36, + 0xf,0x4d,0x67, 0xf,0x53,0x53, 0x7,0x2c,0x45, 0xf,0x4d,0x66, + 0xf,0x53,0x52, 0x4,0x55,0x6a, 0x7,0x2c,0x46, 0x5,0x5a,0x73, + 0xf,0x59,0x53, 0xf,0x59,0x54, 0x5,0x61,0x36, 0x5,0x61,0x35, + 0x5,0x61,0x37, 0xf,0x5e,0x34, 0x7,0x3e,0x7b, 0x5,0x67,0x52, + 0x5,0x67,0x53, 0x7,0x52,0x76, 0x5,0x73,0x32, 0x4,0x21,0x29, + 0x6,0x21,0x52, 0xf,0x21,0x2a, 0xf,0x21,0x2b, 0xf,0x21,0x2c, + 0xf,0x21,0x2e, 0x6,0x21,0x5c, 0xf,0x21,0x2d, 0x5,0x21,0x53, + 0x6,0x22,0x3d, 0x4,0x21,0x5f, 0x6,0x23,0x5e, 0x6,0x23,0x5d, + 0x6,0x23,0x5f, 0x6,0x23,0x60, 0xf,0x21,0x4b, 0x6,0x26,0x27, + 0x6,0x26,0x25, 0x6,0x26,0x26, 0xf,0x23,0x34, 0xf,0x23,0x35, + 0x4,0x25,0x46, 0x6,0x29,0x5a, 0x4,0x25,0x44, 0x6,0x29,0x5b, + 0x6,0x29,0x5c, 0x6,0x29,0x5d, 0xf,0x25,0x58, 0xf,0x25,0x59, + 0x6,0x2e,0x72, 0x6,0x2e,0x70, 0x6,0x2e,0x71, 0x6,0x35,0x47, + 0xf,0x2e,0x2c, 0x6,0x37,0x27, 0x6,0x3d,0x42, 0x6,0x3d,0x43, + 0x6,0x3d,0x41, 0xf,0x33,0x31, 0xf,0x33,0x32, 0xf,0x33,0x33, + 0x6,0x46,0x63, 0x6,0x46,0x66, 0xf,0x39,0x49, 0x6,0x46,0x64, + 0xf,0x39,0x4a, 0xf,0x46,0x5f, 0xf,0x46,0x60, 0xf,0x46,0x61, + 0xf,0x4d,0x68, 0x7,0x2c,0x47, 0xf,0x53,0x54, 0xf,0x53,0x55, + 0xf,0x53,0x43, 0xf,0x59,0x55, 0xf,0x5e,0x35, 0xf,0x67,0x43, + 0x4,0x21,0x2e, 0x5,0x21,0x39, 0x6,0x21,0x53, 0x6,0x21,0x54, + 0x6,0x22,0x3f, 0x5,0x21,0x54, 0x6,0x22,0x3e, 0xf,0x21,0x4c, + 0x6,0x23,0x65, 0x6,0x23,0x61, 0x6,0x23,0x62, 0x6,0x23,0x63, + 0xf,0x22,0x21, 0x5,0x22,0x2a, 0x6,0x26,0x28, 0xf,0x23,0x36, + 0x6,0x29,0x60, 0x6,0x29,0x5f, 0x6,0x2e,0x73, 0x6,0x2e,0x74, + 0x6,0x34,0x7a, 0x6,0x35,0x48, 0x6,0x3d,0x44, 0x6,0x3d,0x45, + 0x5,0x36,0x5d, 0x6,0x5a,0x7e, 0xf,0x46,0x62, 0x7,0x21,0x70, + 0x7,0x36,0x7b, 0x5,0x5a,0x76, 0x5,0x67,0x54, 0x7,0x4e,0x3e, + 0x6,0x21,0x39, 0x4,0x21,0x40, 0x6,0x21,0x55, 0x5,0x21,0x3a, + 0x5,0x21,0x3b, 0x6,0x21,0x56, 0x4,0x21,0x41, 0xf,0x21,0x2f, + 0x6,0x21,0x57, 0x5,0x21,0x55, 0x5,0x21,0x56, 0x4,0x21,0x62, + 0x6,0x22,0x44, 0x5,0x21,0x57, 0x6,0x22,0x43, 0x6,0x22,0x40, + 0x6,0x22,0x45, 0x4,0x22,0x3a, 0x6,0x23,0x6a, 0x5,0x22,0x2e, + 0x5,0x22,0x2c, 0x5,0x22,0x2b, 0x4,0x22,0x3b, 0x4,0x22,0x39, + 0x6,0x23,0x68, 0x6,0x23,0x67, 0x5,0x22,0x2f, 0x6,0x23,0x6b, + 0x6,0x23,0x69, 0x5,0x22,0x2d, 0x4,0x22,0x3d, 0xf,0x22,0x22, + 0xf,0x22,0x23, 0x4,0x22,0x3e, 0x6,0x23,0x66, 0x4,0x23,0x41, + 0x6,0x26,0x2b, 0x4,0x23,0x43, 0x5,0x23,0x3d, 0x4,0x23,0x42, + 0x5,0x23,0x46, 0x5,0x23,0x45, 0x5,0x23,0x43, 0x5,0x23,0x40, + 0x6,0x26,0x29, 0x5,0x23,0x3f, 0x5,0x23,0x42, 0x5,0x23,0x41, + 0x6,0x26,0x2a, 0x6,0x26,0x2c, 0x5,0x23,0x3e, 0x5,0x23,0x44, + 0x6,0x29,0x69, 0x5,0x25,0x33, 0x5,0x25,0x35, 0x4,0x25,0x49, + 0x4,0x25,0x4b, 0x3,0x27,0x5c, 0x6,0x29,0x66, 0x4,0x25,0x4d, + 0x6,0x29,0x64, 0x6,0x29,0x65, 0x6,0x29,0x6c, 0x6,0x2e,0x75, + 0x6,0x29,0x6a, 0x5,0x25,0x30, 0x5,0x25,0x36, 0x6,0x29,0x6b, + 0x5,0x25,0x32, 0x6,0x29,0x67, 0x5,0x25,0x34, 0xf,0x25,0x5a, + 0xf,0x25,0x5b, 0xf,0x25,0x5c, 0xf,0x25,0x5d, 0x6,0x29,0x68, + 0x6,0x29,0x62, 0x6,0x29,0x61, 0x5,0x25,0x31, 0x6,0x29,0x57, + 0x4,0x28,0x47, 0x5,0x28,0x2d, 0x4,0x28,0x45, 0x6,0x2f,0x24, + 0x6,0x2e,0x7b, 0x6,0x2f,0x22, 0x4,0x28,0x48, 0x6,0x2f,0x21, + 0x4,0x28,0x44, 0x4,0x28,0x46, 0x6,0x2e,0x78, 0x6,0x2e,0x7e, + 0x6,0x2f,0x23, 0x6,0x2e,0x7a, 0x6,0x2e,0x7d, 0x6,0x2e,0x7c, + 0xf,0x29,0x40, 0xf,0x29,0x41, 0xf,0x29,0x42, 0x6,0x2e,0x79, + 0x5,0x28,0x2e, 0x6,0x2e,0x77, 0x6,0x35,0x49, 0x4,0x2b,0x70, + 0x4,0x2b,0x6d, 0x5,0x2c,0x25, 0x5,0x2c,0x23, 0x4,0x2b,0x6f, + 0x4,0x2b,0x73, 0x6,0x35,0x4e, 0x6,0x35,0x52, 0x5,0x2c,0x22, + 0x6,0x35,0x53, 0x4,0x2b,0x6c, 0x5,0x2c,0x26, 0x6,0x35,0x51, + 0x4,0x2b,0x71, 0x6,0x35,0x50, 0x6,0x35,0x4f, 0x6,0x35,0x4c, + 0x6,0x35,0x4b, 0x4,0x2b,0x72, 0x5,0x2c,0x24, 0x6,0x35,0x4d, + 0xf,0x2e,0x33, 0x6,0x35,0x54, 0xf,0x2e,0x2e, 0xf,0x2e,0x2f, + 0xf,0x2e,0x30, 0xf,0x2e,0x32, 0xf,0x2e,0x31, 0x6,0x35,0x4a, + 0x5,0x2c,0x27, 0x5,0x2b,0x7d, 0x5,0x2c,0x21, 0x5,0x2b,0x7e, + 0x4,0x30,0x50, 0x5,0x31,0x2b, 0x4,0x30,0x51, 0x5,0x31,0x2a, + 0x6,0x3d,0x46, 0x4,0x30,0x56, 0x4,0x36,0x49, 0x4,0x30,0x55, + 0x6,0x3d,0x49, 0x6,0x3d,0x47, 0x5,0x36,0x5e, 0x4,0x30,0x4f, + 0x5,0x2c,0x28, 0xf,0x33,0x34, 0xf,0x33,0x35, 0xf,0x33,0x37, + 0x6,0x3d,0x48, 0x6,0x3d,0x4a, 0x6,0x3d,0x4b, 0x4,0x36,0x43, + 0x5,0x36,0x5f, 0x6,0x46,0x6d, 0x6,0x46,0x69, 0x4,0x36,0x46, + 0x4,0x36,0x47, 0x5,0x36,0x60, 0x5,0x36,0x64, 0x4,0x36,0x4a, + 0x4,0x36,0x44, 0x4,0x36,0x41, 0x4,0x36,0x40, 0x6,0x46,0x6b, + 0x6,0x46,0x68, 0x6,0x46,0x6c, 0x5,0x36,0x61, 0x5,0x36,0x62, + 0x6,0x46,0x6a, 0xf,0x39,0x4b, 0xf,0x39,0x4c, 0xf,0x39,0x4d, + 0xf,0x39,0x4e, 0x4,0x36,0x48, 0x6,0x4c,0x46, 0x6,0x46,0x6e, + 0x5,0x36,0x65, 0x4,0x3c,0x39, 0x6,0x50,0x6f, 0x5,0x3d,0x73, + 0x6,0x50,0x6d, 0x4,0x3c,0x35, 0x5,0x3d,0x74, 0x6,0x50,0x6e, + 0x5,0x3d,0x6d, 0x4,0x3c,0x37, 0x4,0x3c,0x36, 0x5,0x3d,0x6e, + 0x4,0x3c,0x3a, 0x5,0x3d,0x6f, 0x6,0x50,0x6b, 0xf,0x40,0x4b, + 0x6,0x50,0x6a, 0x6,0x50,0x68, 0x6,0x50,0x70, 0x6,0x50,0x69, + 0x5,0x3d,0x72, 0x5,0x3d,0x71, 0xf,0x40,0x4c, 0x5,0x44,0x5b, + 0x4,0x42,0x3b, 0x6,0x5b,0x24, 0x5,0x44,0x61, 0x6,0x5b,0x22, + 0x6,0x5b,0x21, 0x4,0x3c,0x38, 0x4,0x42,0x40, 0x5,0x44,0x62, + 0x5,0x44,0x5c, 0x5,0x44,0x5f, 0x4,0x42,0x3d, 0x4,0x42,0x44, + 0x6,0x5b,0x2b, 0x6,0x5b,0x29, 0x6,0x5b,0x28, 0x5,0x44,0x5e, + 0x5,0x4c,0x22, 0x6,0x5b,0x26, 0x5,0x44,0x5d, 0x6,0x5b,0x2a, + 0x5,0x44,0x60, 0x6,0x5b,0x25, 0xf,0x46,0x63, 0xf,0x46,0x64, + 0xf,0x46,0x65, 0x6,0x5b,0x23, 0x6,0x5b,0x27, 0x5,0x4c,0x23, + 0x5,0x4c,0x27, 0x4,0x49,0x24, 0x5,0x4c,0x24, 0x5,0x4c,0x26, + 0x7,0x21,0x3c, 0x7,0x21,0x3d, 0x7,0x21,0x3a, 0x7,0x21,0x3e, + 0x7,0x21,0x3b, 0x5,0x4c,0x25, 0x7,0x21,0x38, 0x7,0x22,0x5a, + 0x7,0x21,0x39, 0x4,0x4f,0x60, 0x7,0x2c,0x49, 0x5,0x5a,0x77, + 0x7,0x2c,0x4a, 0x7,0x2c,0x4e, 0x7,0x2c,0x4d, 0x7,0x2c,0x4c, + 0x5,0x53,0x5f, 0x5,0x53,0x61, 0x5,0x53,0x60, 0x5,0x53,0x5e, + 0x7,0x2c,0x48, 0x7,0x2c,0x4b, 0x7,0x21,0x3f, 0xf,0x53,0x56, + 0x5,0x58,0x51, 0x5,0x5a,0x7a, 0x4,0x55,0x6b, 0x5,0x5a,0x79, + 0x5,0x5a,0x78, 0x7,0x36,0x7c, 0xf,0x59,0x56, 0x4,0x55,0x6e, + 0x7,0x3e,0x7c, 0x5,0x61,0x38, 0x5,0x61,0x39, 0x7,0x36,0x7d, + 0xf,0x5e,0x36, 0x5,0x61,0x3a, 0x7,0x46,0x2f, 0x7,0x46,0x2e, + 0x7,0x46,0x2d, 0x7,0x4d,0x40, 0x7,0x4d,0x41, 0x5,0x6f,0x6a, + 0x7,0x52,0x77, 0xf,0x67,0x44, 0x5,0x75,0x64, 0x4,0x6b,0x65, + 0x7,0x62,0x2d, 0x7,0x62,0x2c, 0x6,0x21,0x3a, 0x5,0x21,0x3c, + 0x6,0x21,0x58, 0x4,0x21,0x63, 0x5,0x21,0x59, 0x5,0x21,0x58, + 0x5,0x22,0x31, 0x5,0x22,0x32, 0xf,0x22,0x25, 0xf,0x22,0x26, + 0xf,0x22,0x27, 0xf,0x22,0x28, 0x5,0x22,0x33, 0x6,0x26,0x2e, + 0x4,0x23,0x45, 0x5,0x23,0x47, 0xf,0x23,0x38, 0xf,0x23,0x3a, + 0xf,0x23,0x3b, 0x6,0x26,0x2d, 0x4,0x23,0x49, 0x5,0x25,0x3d, + 0x5,0x25,0x39, 0x6,0x29,0x6d, 0x5,0x25,0x3c, 0x6,0x29,0x6e, + 0xf,0x25,0x60, 0xf,0x25,0x61, 0xf,0x25,0x62, 0xf,0x25,0x63, + 0x5,0x28,0x30, 0x4,0x28,0x4a, 0x6,0x2f,0x26, 0x5,0x28,0x31, + 0x5,0x28,0x2f, 0x6,0x2f,0x28, 0xf,0x29,0x43, 0xf,0x29,0x44, + 0xf,0x29,0x45, 0x6,0x35,0x55, 0x6,0x35,0x59, 0x4,0x2b,0x74, + 0x5,0x2c,0x2d, 0x5,0x2c,0x29, 0x5,0x2c,0x2b, 0x5,0x2c,0x2c, + 0x5,0x2c,0x2a, 0xf,0x2e,0x34, 0xf,0x2e,0x35, 0x6,0x35,0x56, + 0x6,0x35,0x57, 0x5,0x31,0x2d, 0x6,0x3d,0x4e, 0x6,0x3d,0x4c, + 0x6,0x3d,0x4f, 0x6,0x3d,0x50, 0x6,0x3d,0x51, 0xf,0x33,0x38, + 0xf,0x33,0x39, 0x6,0x3d,0x4d, 0x5,0x36,0x69, 0x5,0x36,0x66, + 0x5,0x36,0x68, 0x5,0x36,0x6b, 0x5,0x36,0x67, 0xf,0x39,0x4f, + 0xf,0x39,0x50, 0x6,0x46,0x6f, 0x6,0x46,0x70, 0x6,0x46,0x71, + 0x5,0x3d,0x76, 0x5,0x3d,0x75, 0x4,0x3c,0x3b, 0x6,0x50,0x72, + 0x6,0x50,0x71, 0xf,0x40,0x4d, 0x5,0x3d,0x77, 0x4,0x42,0x46, + 0x5,0x44,0x66, 0x5,0x44,0x64, 0x5,0x44,0x65, 0x5,0x44,0x69, + 0x4,0x42,0x45, 0x5,0x44,0x68, 0x6,0x5b,0x2e, 0xf,0x46,0x66, + 0x6,0x5b,0x2c, 0x6,0x5b,0x2d, 0x5,0x4c,0x2b, 0x5,0x4c,0x28, + 0x4,0x49,0x26, 0x5,0x4c,0x29, 0x5,0x4c,0x2a, 0x7,0x2c,0x4f, + 0x5,0x5a,0x7c, 0xf,0x53,0x57, 0x5,0x5a,0x7b, 0x5,0x5a,0x7d, + 0x7,0x36,0x7e, 0x7,0x37,0x22, 0x7,0x37,0x21, 0x5,0x61,0x3c, + 0x7,0x3e,0x7e, 0x7,0x3f,0x21, 0x5,0x67,0x56, 0x5,0x67,0x55, + 0x7,0x4d,0x42, 0x5,0x6f,0x6b, 0x7,0x5b,0x46, 0x5,0x75,0x65, + 0x4,0x6c,0x6b, 0x7,0x66,0x3b, 0x5,0x21,0x3d, 0x6,0x22,0x47, + 0x6,0x22,0x48, 0x5,0x22,0x35, 0x5,0x22,0x34, 0x5,0x22,0x36, + 0xf,0x22,0x2a, 0x6,0x26,0x2f, 0x5,0x23,0x48, 0x5,0x23,0x49, + 0x4,0x25,0x52, 0x6,0x29,0x71, 0x6,0x29,0x70, 0xf,0x25,0x64, + 0xf,0x25,0x65, 0x6,0x2f,0x2a, 0x4,0x28,0x4c, 0x6,0x2f,0x2b, + 0x6,0x2f,0x2c, 0xf,0x29,0x46, 0x6,0x2f,0x29, 0x4,0x2b,0x76, + 0x6,0x35,0x5c, 0x6,0x35,0x5b, 0x6,0x35,0x5e, 0x6,0x35,0x5f, + 0x6,0x35,0x5a, 0x6,0x35,0x5d, 0x5,0x2c,0x2f, 0x4,0x30,0x5d, + 0x6,0x3d,0x52, 0x5,0x2c,0x2e, 0x5,0x31,0x2e, 0x5,0x31,0x2f, + 0x6,0x3d,0x53, 0x4,0x36,0x4e, 0xf,0x39,0x51, 0x6,0x50,0x73, + 0x4,0x30,0x5b, 0x5,0x3d,0x79, 0xf,0x40,0x4e, 0xf,0x40,0x4f, + 0x6,0x5b,0x2f, 0x4,0x42,0x47, 0x5,0x44,0x6a, 0x5,0x44,0x6b, + 0xf,0x46,0x67, 0xf,0x4d,0x69, 0x4,0x4f,0x65, 0x7,0x2c,0x50, + 0x7,0x2c,0x51, 0x7,0x37,0x23, 0x7,0x37,0x24, 0x5,0x5a,0x7e, + 0x7,0x4d,0x43, 0x6,0x21,0x2a, 0x4,0x21,0x42, 0x6,0x22,0x4a, + 0x6,0x26,0x30, 0x6,0x26,0x33, 0x5,0x23,0x4a, 0x6,0x26,0x31, + 0x6,0x26,0x32, 0x4,0x28,0x4d, 0x6,0x2f,0x2f, 0x6,0x2f,0x31, + 0x6,0x2f,0x2d, 0x6,0x2f,0x2e, 0x6,0x2f,0x30, 0x6,0x3d,0x54, + 0x6,0x35,0x60, 0xf,0x2e,0x36, 0xf,0x2e,0x37, 0x6,0x35,0x24, + 0x6,0x46,0x72, 0xf,0x39,0x52, 0x4,0x3c,0x3d, 0xf,0x46,0x68, + 0x7,0x3f,0x22, 0x5,0x6d,0x32, 0x6,0x21,0x2b, 0xf,0x21,0x31, + 0x5,0x22,0x37, 0x6,0x23,0x6e, 0x4,0x22,0x43, 0x6,0x23,0x6d, + 0x6,0x26,0x34, 0x4,0x23,0x4a, 0x6,0x26,0x35, 0xf,0x23,0x3c, + 0x6,0x29,0x73, 0x5,0x25,0x3e, 0x5,0x25,0x3f, 0x4,0x28,0x4f, + 0x6,0x2f,0x34, 0x5,0x28,0x33, 0x6,0x2f,0x33, 0x5,0x28,0x32, + 0x6,0x2f,0x32, 0x6,0x2f,0x37, 0x6,0x2f,0x35, 0xf,0x29,0x47, + 0x5,0x2c,0x30, 0x6,0x35,0x62, 0x6,0x35,0x61, 0x5,0x2c,0x31, + 0x6,0x3d,0x55, 0xf,0x33,0x3a, 0x4,0x36,0x4f, 0x6,0x50,0x75, + 0x6,0x46,0x73, 0x6,0x35,0x63, 0x5,0x3d,0x7a, 0x4,0x42,0x48, + 0x6,0x5b,0x31, 0x6,0x5b,0x30, 0x5,0x4c,0x2c, 0x5,0x4c,0x2d, + 0x5,0x4c,0x2e, 0xf,0x4d,0x6a, 0x5,0x53,0x64, 0x7,0x37,0x25, + 0xf,0x5e,0x37, 0x4,0x5f,0x4b, 0x7,0x3f,0x23, 0x7,0x4d,0x44, + 0x7,0x60,0x69, 0x7,0x64,0x43, 0xf,0x21,0x32, 0x5,0x22,0x38, + 0x6,0x23,0x6f, 0x5,0x23,0x4c, 0x6,0x26,0x37, 0xf,0x23,0x3d, + 0xf,0x25,0x66, 0x6,0x2f,0x36, 0x5,0x28,0x34, 0x6,0x35,0x64, + 0xf,0x46,0x69, 0x7,0x4d,0x45, 0x7,0x57,0x50, 0x6,0x21,0x5a, + 0x5,0x21,0x5a, 0x5,0x21,0x5b, 0x6,0x22,0x4b, 0x6,0x23,0x70, + 0x4,0x22,0x44, 0x4,0x22,0x45, 0x6,0x23,0x73, 0x6,0x23,0x72, + 0x5,0x22,0x3a, 0x5,0x22,0x39, 0x6,0x23,0x74, 0x6,0x26,0x39, + 0x5,0x23,0x4d, 0x6,0x26,0x3a, 0x6,0x23,0x75, 0x6,0x26,0x3b, + 0xf,0x23,0x3e, 0x5,0x25,0x40, 0x6,0x29,0x74, 0x6,0x29,0x77, + 0x6,0x29,0x78, 0x6,0x29,0x76, 0xf,0x25,0x67, 0xf,0x25,0x69, + 0xf,0x25,0x6a, 0xf,0x25,0x6b, 0xf,0x25,0x68, 0x6,0x29,0x75, + 0x6,0x35,0x65, 0x6,0x35,0x66, 0xf,0x2e,0x38, 0xf,0x2e,0x39, + 0x4,0x30,0x63, 0x4,0x30,0x61, 0x4,0x30,0x62, 0xf,0x33,0x3b, + 0xf,0x39,0x53, 0xf,0x39,0x54, 0x6,0x50,0x78, 0x6,0x50,0x77, + 0x6,0x50,0x79, 0x6,0x50,0x7b, 0xf,0x40,0x50, 0xf,0x46,0x6a, + 0xf,0x46,0x6b, 0x5,0x4c,0x2f, 0xf,0x4d,0x6b, 0xf,0x4d,0x6c, + 0x7,0x21,0x40, 0x7,0x37,0x26, 0xf,0x5e,0x38, 0x7,0x46,0x30, + 0x7,0x52,0x78, 0x7,0x60,0x6a, 0x7,0x62,0x2e, 0x6,0x22,0x4c, + 0x6,0x23,0x77, 0x6,0x23,0x76, 0x6,0x23,0x78, 0x4,0x23,0x4c, + 0x5,0x23,0x4f, 0x5,0x23,0x4e, 0x6,0x26,0x3c, 0x4,0x25,0x55, + 0x4,0x25,0x54, 0x6,0x29,0x7c, 0x6,0x29,0x7b, 0x6,0x29,0x7d, + 0x6,0x29,0x7a, 0x6,0x29,0x7e, 0x6,0x29,0x79, 0xf,0x25,0x6c, + 0x6,0x2a,0x22, 0x4,0x28,0x52, 0x4,0x28,0x51, 0x5,0x28,0x37, + 0xf,0x29,0x48, 0xf,0x29,0x49, 0xf,0x29,0x4a, 0xf,0x29,0x4b, + 0x6,0x2f,0x39, 0x6,0x35,0x68, 0x4,0x2b,0x79, 0x5,0x2c,0x32, + 0x6,0x35,0x67, 0x6,0x35,0x6a, 0x6,0x3c,0x7a, 0x6,0x35,0x69, + 0x6,0x3d,0x57, 0x6,0x3d,0x56, 0x6,0x35,0x6b, 0x6,0x3d,0x58, + 0x6,0x46,0x75, 0x6,0x46,0x76, 0x6,0x46,0x77, 0x5,0x37,0x3f, + 0x6,0x50,0x7c, 0x5,0x44,0x6d, 0x6,0x5b,0x32, 0x7,0x21,0x41, + 0xf,0x53,0x58, 0x7,0x63,0x4b, 0x5,0x21,0x3e, 0x4,0x21,0x43, + 0xf,0x21,0x34, 0x6,0x21,0x5b, 0x4,0x22,0x46, 0x6,0x2a,0x24, + 0x6,0x23,0x7a, 0x6,0x23,0x79, 0x4,0x23,0x4e, 0x6,0x2f,0x3b, + 0x5,0x28,0x38, 0x6,0x2f,0x3a, 0x4,0x28,0x53, 0x6,0x35,0x6c, + 0x6,0x2f,0x3c, 0x6,0x46,0x78, 0x5,0x2c,0x33, 0x5,0x3d,0x7b, + 0x6,0x50,0x7d, 0x5,0x44,0x6e, 0x7,0x3f,0x24, 0x5,0x21,0x3f, + 0x5,0x21,0x5c, 0x6,0x23,0x7b, 0x6,0x22,0x4f, 0x6,0x22,0x4d, + 0x6,0x22,0x50, 0x5,0x21,0x5d, 0x4,0x22,0x47, 0x5,0x22,0x3b, + 0x6,0x23,0x7c, 0x6,0x23,0x7d, 0x5,0x22,0x3f, 0x5,0x22,0x40, + 0x5,0x22,0x3d, 0x5,0x22,0x3e, 0xf,0x22,0x2d, 0x6,0x26,0x3e, + 0x5,0x23,0x50, 0x6,0x26,0x3d, 0x5,0x23,0x51, 0x6,0x25,0x5e, + 0xf,0x23,0x3f, 0x6,0x2a,0x27, 0x6,0x2a,0x26, 0x6,0x2a,0x29, + 0x6,0x2a,0x28, 0x5,0x25,0x41, 0x4,0x25,0x58, 0xf,0x25,0x6d, + 0xf,0x25,0x6e, 0x6,0x2a,0x25, 0x5,0x28,0x39, 0x4,0x28,0x54, + 0x6,0x2f,0x46, 0x6,0x2f,0x41, 0x6,0x2f,0x44, 0x6,0x2f,0x45, + 0x6,0x2f,0x40, 0x6,0x2f,0x3e, 0x6,0x2f,0x42, 0x6,0x2f,0x43, + 0xf,0x29,0x4d, 0xf,0x29,0x4e, 0x4,0x28,0x55, 0x6,0x2f,0x3f, + 0x6,0x35,0x73, 0x6,0x35,0x74, 0x4,0x2b,0x7b, 0x5,0x2c,0x34, + 0x4,0x2b,0x7c, 0x6,0x35,0x6f, 0x6,0x35,0x6d, 0x6,0x35,0x70, + 0x6,0x35,0x72, 0x6,0x35,0x71, 0x6,0x35,0x6e, 0x5,0x2c,0x35, + 0xf,0x2e,0x3a, 0xf,0x2e,0x3b, 0x6,0x3d,0x60, 0x6,0x3d,0x5b, + 0x4,0x30,0x67, 0x6,0x3d,0x5f, 0x6,0x3d,0x5c, 0x6,0x3d,0x5d, + 0xf,0x33,0x3d, 0x5,0x31,0x30, 0x6,0x3d,0x5e, 0x4,0x30,0x66, + 0x4,0x36,0x52, 0x6,0x46,0x7c, 0x6,0x46,0x7a, 0x4,0x36,0x53, + 0x6,0x46,0x7b, 0x6,0x46,0x79, 0x6,0x46,0x7d, 0xf,0x39,0x55, + 0x6,0x46,0x7e, 0x5,0x3d,0x7c, 0x5,0x3d,0x7d, 0x6,0x51,0x24, + 0x6,0x51,0x23, 0x6,0x50,0x7e, 0xf,0x40,0x51, 0x6,0x51,0x21, + 0x4,0x3c,0x3f, 0x4,0x42,0x49, 0x6,0x5b,0x34, 0x6,0x5b,0x37, + 0x6,0x5b,0x33, 0x6,0x5b,0x38, 0x5,0x44,0x6f, 0xf,0x46,0x6d, + 0xf,0x46,0x6e, 0x6,0x5b,0x36, 0x6,0x5b,0x39, 0x6,0x5b,0x3b, + 0x6,0x5b,0x3a, 0x6,0x5b,0x35, 0x7,0x21,0x43, 0x4,0x49,0x28, + 0x5,0x4c,0x30, 0x7,0x21,0x44, 0x7,0x21,0x42, 0xf,0x4d,0x6d, + 0x7,0x25,0x48, 0x5,0x53,0x65, 0x7,0x2c,0x53, 0x7,0x2c,0x52, + 0xf,0x53,0x59, 0xf,0x53,0x5a, 0x7,0x3b,0x4d, 0xf,0x5e,0x39, + 0xf,0x5e,0x3a, 0xf,0x5e,0x3b, 0xf,0x64,0x7c, 0x7,0x4e,0x27, + 0x7,0x52,0x79, 0x5,0x77,0x54, 0x7,0x5e,0x50, 0x7,0x65,0x33, + 0x7,0x66,0x33, 0x5,0x21,0x2e, 0x6,0x21,0x3c, 0x6,0x21,0x3d, + 0x6,0x21,0x5d, 0x6,0x22,0x52, 0x6,0x22,0x51, 0x4,0x22,0x4a, + 0x6,0x24,0x23, 0x6,0x24,0x21, 0xf,0x22,0x2e, 0x4,0x22,0x49, + 0x6,0x24,0x22, 0x6,0x26,0x40, 0xf,0x23,0x40, 0x5,0x23,0x3c, + 0x6,0x2a,0x2c, 0x6,0x2a,0x2b, 0x6,0x2a,0x2d, 0x6,0x2a,0x2e, + 0x6,0x2f,0x47, 0x6,0x2f,0x48, 0x4,0x28,0x56, 0xf,0x29,0x4f, + 0x6,0x35,0x76, 0x6,0x35,0x75, 0x6,0x36,0x49, 0x6,0x35,0x2e, + 0x5,0x36,0x6c, 0x6,0x47,0x22, 0x6,0x47,0x24, 0x6,0x4d,0x62, + 0xf,0x39,0x56, 0x6,0x47,0x23, 0x5,0x3e,0x21, 0x6,0x51,0x25, + 0x5,0x3d,0x7e, 0xf,0x40,0x52, 0x6,0x5b,0x3c, 0xf,0x46,0x6f, + 0x6,0x60,0x72, 0x7,0x21,0x45, 0x5,0x53,0x66, 0xf,0x59,0x57, + 0x7,0x4b,0x6a, 0x6,0x21,0x60, 0x5,0x21,0x40, 0x6,0x21,0x5e, + 0x5,0x21,0x42, 0x6,0x21,0x62, 0x6,0x21,0x5f, 0x6,0x22,0x55, + 0x4,0x21,0x68, 0x5,0x21,0x5e, 0x6,0x22,0x56, 0x5,0x21,0x5f, + 0x6,0x22,0x53, 0x6,0x22,0x54, 0x6,0x24,0x25, 0x4,0x22,0x4b, + 0x6,0x24,0x24, 0x5,0x22,0x42, 0x6,0x24,0x26, 0x5,0x22,0x41, + 0x6,0x24,0x27, 0x6,0x26,0x44, 0x6,0x26,0x42, 0x5,0x23,0x52, + 0xf,0x23,0x41, 0xf,0x23,0x42, 0xf,0x23,0x43, 0xf,0x23,0x44, + 0x4,0x23,0x50, 0x6,0x2a,0x31, 0x6,0x2a,0x2f, 0x6,0x2a,0x32, + 0x6,0x2a,0x30, 0xf,0x25,0x6f, 0x6,0x2f,0x4d, 0x6,0x2f,0x4a, + 0x6,0x2f,0x4c, 0x6,0x2f,0x4b, 0x6,0x2f,0x49, 0xf,0x29,0x51, + 0xf,0x29,0x52, 0x6,0x32,0x72, 0x5,0x28,0x36, 0x6,0x35,0x7b, + 0x5,0x2c,0x36, 0x6,0x35,0x7c, 0x6,0x35,0x79, 0x6,0x35,0x77, + 0x6,0x35,0x7a, 0xf,0x2e,0x3c, 0xf,0x2e,0x3d, 0xf,0x2e,0x3e, + 0xf,0x2e,0x3f, 0x6,0x3c,0x67, 0x6,0x3d,0x66, 0x6,0x3d,0x68, + 0x5,0x31,0x32, 0x5,0x31,0x33, 0x6,0x3d,0x65, 0x6,0x3d,0x63, + 0x6,0x3d,0x6b, 0x6,0x3d,0x64, 0x5,0x2c,0x37, 0x6,0x3d,0x62, + 0x6,0x3d,0x69, 0x6,0x3d,0x6a, 0x6,0x3c,0x7c, 0x6,0x3d,0x67, + 0x4,0x36,0x54, 0x5,0x36,0x6d, 0x6,0x47,0x27, 0x6,0x47,0x25, + 0xf,0x33,0x3e, 0xf,0x39,0x57, 0xf,0x39,0x58, 0xf,0x39,0x59, + 0xf,0x39,0x5a, 0x6,0x47,0x26, 0x4,0x3c,0x43, 0x4,0x3c,0x42, + 0x6,0x51,0x27, 0x6,0x51,0x28, 0x6,0x51,0x26, 0x4,0x3c,0x41, + 0x6,0x47,0x28, 0x6,0x51,0x5b, 0x6,0x51,0x29, 0x6,0x5f,0x21, + 0x6,0x5b,0x3e, 0x6,0x5b,0x3d, 0x5,0x44,0x70, 0x6,0x53,0x7b, + 0xf,0x4d,0x55, 0x5,0x4c,0x33, 0x5,0x4c,0x34, 0xf,0x46,0x70, + 0x5,0x4c,0x32, 0x7,0x2c,0x55, 0xf,0x53,0x5b, 0x3,0x50,0x39, + 0x5,0x54,0x2e, 0x7,0x2c,0x54, 0x7,0x37,0x29, 0x7,0x37,0x28, + 0xf,0x59,0x58, 0x4,0x5a,0x6f, 0x7,0x46,0x32, 0x7,0x46,0x31, + 0x4,0x66,0x31, 0xf,0x67,0x45, 0x7,0x57,0x51, 0x5,0x75,0x66, + 0x7,0x5e,0x51, 0x7,0x5e,0x52, 0x5,0x21,0x43, 0x6,0x21,0x64, + 0x4,0x21,0x47, 0x4,0x21,0x46, 0xf,0x21,0x36, 0x6,0x21,0x63, + 0x5,0x21,0x61, 0x6,0x22,0x59, 0x6,0x22,0x58, 0x6,0x22,0x5e, + 0x6,0x22,0x5a, 0x6,0x22,0x5d, 0x6,0x22,0x57, 0x6,0x22,0x42, + 0xf,0x21,0x4e, 0x6,0x22,0x5c, 0x5,0x22,0x47, 0x6,0x24,0x2d, + 0x5,0x22,0x45, 0x6,0x24,0x2e, 0x4,0x22,0x4d, 0x5,0x22,0x46, + 0x4,0x22,0x50, 0x6,0x24,0x2c, 0x4,0x22,0x4f, 0x4,0x22,0x4e, + 0x5,0x22,0x44, 0x6,0x24,0x28, 0xf,0x22,0x2f, 0xf,0x22,0x30, + 0xf,0x22,0x32, 0xf,0x22,0x34, 0x6,0x24,0x2a, 0xf,0x22,0x31, + 0xf,0x22,0x33, 0x5,0x22,0x43, 0x6,0x24,0x29, 0x6,0x24,0x2b, + 0x4,0x23,0x56, 0x6,0x26,0x4f, 0x6,0x26,0x46, 0x6,0x26,0x4d, + 0x6,0x26,0x4c, 0x5,0x23,0x56, 0x4,0x23,0x5a, 0x4,0x23,0x5d, + 0x5,0x23,0x5b, 0x5,0x23,0x54, 0x6,0x26,0x48, 0x4,0x23,0x57, + 0x4,0x23,0x52, 0x4,0x23,0x58, 0x5,0x23,0x58, 0x6,0x26,0x49, + 0x5,0x23,0x59, 0x4,0x23,0x55, 0x5,0x23,0x55, 0x6,0x26,0x47, + 0x5,0x23,0x5c, 0xf,0x23,0x45, 0xf,0x23,0x46, 0xf,0x23,0x47, + 0xf,0x23,0x4a, 0xf,0x23,0x4b, 0xf,0x23,0x4c, 0xf,0x23,0x48, + 0x6,0x26,0x4b, 0x6,0x26,0x4a, 0x6,0x26,0x50, 0x6,0x26,0x45, + 0x5,0x23,0x53, 0x5,0x23,0x57, 0x5,0x23,0x5a, 0x4,0x25,0x5c, + 0x4,0x25,0x5e, 0x6,0x2a,0x36, 0x5,0x25,0x4c, 0x5,0x25,0x44, + 0x4,0x25,0x5b, 0x6,0x2a,0x34, 0x5,0x25,0x4d, 0x5,0x25,0x45, + 0x5,0x25,0x47, 0x4,0x25,0x61, 0x5,0x25,0x50, 0x6,0x2a,0x33, + 0x5,0x25,0x52, 0x5,0x28,0x47, 0x6,0x2a,0x3b, 0x5,0x25,0x48, + 0x5,0x25,0x4b, 0x5,0x25,0x4a, 0x5,0x25,0x51, 0x5,0x25,0x49, + 0x5,0x25,0x4e, 0x6,0x2a,0x3d, 0x5,0x25,0x4f, 0xf,0x25,0x70, + 0xf,0x25,0x72, 0xf,0x25,0x73, 0xf,0x25,0x74, 0xf,0x25,0x75, + 0xf,0x25,0x76, 0xf,0x25,0x77, 0xf,0x25,0x78, 0xf,0x25,0x79, + 0xf,0x25,0x7a, 0xf,0x25,0x7d, 0xf,0x25,0x7e, 0xf,0x26,0x21, + 0xf,0x26,0x22, 0xf,0x26,0x23, 0x5,0x25,0x46, 0x6,0x2a,0x35, + 0x5,0x25,0x43, 0x6,0x2a,0x38, 0x6,0x2a,0x37, 0xf,0x25,0x7c, + 0x6,0x2a,0x3a, 0x5,0x2c,0x38, 0x5,0x28,0x46, 0x5,0x28,0x52, + 0x5,0x28,0x4d, 0x5,0x28,0x3c, 0x5,0x28,0x51, 0x6,0x2f,0x54, + 0x6,0x2f,0x4e, 0x5,0x28,0x3f, 0x4,0x28,0x5b, 0x4,0x28,0x5a, + 0x5,0x28,0x4f, 0x5,0x28,0x45, 0x5,0x28,0x4b, 0x5,0x28,0x4a, + 0x5,0x28,0x4e, 0x5,0x28,0x48, 0x5,0x28,0x49, 0x5,0x28,0x3d, + 0x5,0x28,0x41, 0x5,0x28,0x4c, 0x4,0x25,0x62, 0x6,0x2f,0x59, + 0x6,0x2f,0x5a, 0x5,0x28,0x53, 0x6,0x2f,0x4f, 0x5,0x28,0x3a, + 0x6,0x2f,0x57, 0x6,0x2f,0x56, 0x5,0x28,0x50, 0x6,0x2f,0x50, + 0x6,0x2f,0x58, 0x6,0x2f,0x52, 0x5,0x28,0x40, 0x5,0x28,0x42, + 0xf,0x2b,0x33, 0xf,0x29,0x53, 0xf,0x29,0x55, 0xf,0x29,0x56, + 0xf,0x29,0x57, 0xf,0x29,0x58, 0xf,0x29,0x59, 0xf,0x29,0x5a, + 0xf,0x29,0x5b, 0xf,0x29,0x5e, 0xf,0x29,0x5f, 0xf,0x29,0x60, + 0xf,0x29,0x61, 0xf,0x29,0x62, 0xf,0x29,0x63, 0xf,0x29,0x64, + 0xf,0x29,0x66, 0xf,0x29,0x67, 0x5,0x28,0x43, 0x5,0x28,0x44, + 0x4,0x28,0x5d, 0xf,0x29,0x65, 0x6,0x2f,0x55, 0x6,0x2f,0x53, + 0x4,0x28,0x58, 0x5,0x28,0x3b, 0x5,0x28,0x3e, 0x6,0x2f,0x51, + 0x6,0x36,0x29, 0x4,0x2c,0x24, 0x4,0x2c,0x2b, 0x4,0x2c,0x2c, + 0x4,0x2c,0x27, 0x6,0x36,0x22, 0x5,0x2c,0x4e, 0x5,0x2c,0x41, + 0x5,0x2c,0x3f, 0x5,0x2c,0x4c, 0x5,0x2c,0x3d, 0x5,0x2c,0x46, + 0x5,0x2c,0x56, 0x5,0x2c,0x49, 0x4,0x2c,0x2a, 0x5,0x2c,0x4d, + 0x5,0x2c,0x54, 0x5,0x2c,0x52, 0x4,0x2c,0x22, 0x6,0x36,0x23, + 0x6,0x36,0x24, 0x5,0x2c,0x51, 0x4,0x2c,0x23, 0x5,0x2c,0x40, + 0x6,0x36,0x27, 0x6,0x36,0x28, 0x5,0x2c,0x57, 0x6,0x36,0x26, + 0x5,0x2c,0x53, 0x5,0x2c,0x58, 0x5,0x2c,0x47, 0x5,0x2c,0x59, + 0x5,0x2c,0x44, 0x5,0x2c,0x55, 0xf,0x2e,0x40, 0xf,0x2e,0x41, + 0xf,0x2e,0x43, 0xf,0x2e,0x44, 0xf,0x2e,0x48, 0xf,0x2e,0x49, + 0xf,0x2e,0x4b, 0xf,0x2e,0x4c, 0xf,0x2e,0x4d, 0xf,0x2e,0x4e, + 0xf,0x2e,0x4f, 0xf,0x2e,0x50, 0xf,0x2e,0x51, 0xf,0x2e,0x52, + 0xf,0x2e,0x53, 0xf,0x2e,0x54, 0x6,0x39,0x5e, 0x6,0x36,0x21, + 0x5,0x2c,0x42, 0x5,0x2c,0x45, 0x5,0x2c,0x48, 0x6,0x36,0x25, + 0x5,0x2c,0x50, 0x5,0x2c,0x4b, 0x5,0x2c,0x39, 0x5,0x2c,0x3a, + 0x5,0x2c,0x3b, 0xf,0x2e,0x45, 0x5,0x2c,0x4a, 0x5,0x2c,0x4f, + 0x5,0x2c,0x3e, 0x5,0x2c,0x3c, 0x5,0x2c,0x5a, 0x5,0x31,0x46, + 0x4,0x30,0x69, 0x6,0x3d,0x77, 0x6,0x3d,0x74, 0x4,0x30,0x78, + 0x6,0x3d,0x6f, 0x4,0x30,0x75, 0x5,0x31,0x51, 0x5,0x31,0x49, + 0x5,0x31,0x4c, 0x4,0x30,0x6e, 0x4,0x30,0x79, 0x5,0x31,0x44, + 0x6,0x3d,0x76, 0x5,0x31,0x36, 0x5,0x31,0x4a, 0x5,0x31,0x45, + 0x5,0x31,0x4e, 0x5,0x31,0x34, 0x5,0x31,0x4d, 0x5,0x31,0x42, + 0x5,0x31,0x3b, 0x6,0x3d,0x71, 0x6,0x3d,0x75, 0x6,0x3d,0x7d, + 0x6,0x3d,0x7a, 0x6,0x3d,0x7e, 0x5,0x31,0x3a, 0x5,0x31,0x3c, + 0x6,0x3d,0x6c, 0x5,0x31,0x38, 0x6,0x3d,0x72, 0x6,0x3d,0x7b, + 0xf,0x33,0x3f, 0xf,0x33,0x40, 0xf,0x33,0x41, 0xf,0x33,0x42, + 0xf,0x33,0x44, 0xf,0x33,0x45, 0xf,0x33,0x46, 0xf,0x33,0x47, + 0xf,0x33,0x48, 0xf,0x33,0x49, 0xf,0x33,0x4c, 0xf,0x33,0x4d, + 0x5,0x31,0x37, 0x6,0x3d,0x73, 0x5,0x31,0x39, 0x6,0x3d,0x6d, + 0x5,0x31,0x41, 0x5,0x31,0x48, 0x6,0x3e,0x21, 0x5,0x31,0x52, + 0x6,0x3d,0x70, 0x5,0x31,0x40, 0x5,0x31,0x35, 0x5,0x31,0x47, + 0x5,0x31,0x3e, 0x5,0x31,0x43, 0x5,0x31,0x3d, 0x5,0x31,0x50, + 0x6,0x3d,0x79, 0x3,0x34,0x60, 0x5,0x31,0x53, 0x5,0x31,0x4f, + 0x6,0x3d,0x78, 0x6,0x3d,0x6e, 0x5,0x31,0x3f, 0x5,0x31,0x4b, + 0x4,0x36,0x55, 0x4,0x36,0x61, 0x6,0x47,0x32, 0x5,0x37,0x24, + 0x6,0x47,0x37, 0x6,0x47,0x3e, 0x5,0x36,0x77, 0x6,0x47,0x35, + 0x5,0x36,0x7c, 0x4,0x36,0x56, 0x5,0x37,0x28, 0x5,0x36,0x6f, + 0x5,0x36,0x71, 0x4,0x36,0x5a, 0x5,0x36,0x78, 0x4,0x36,0x57, + 0x5,0x37,0x29, 0x5,0x36,0x7e, 0x4,0x36,0x62, 0x4,0x36,0x5b, + 0x5,0x37,0x23, 0x5,0x37,0x27, 0x4,0x36,0x66, 0x5,0x37,0x30, + 0x4,0x36,0x5d, 0x5,0x37,0x2c, 0x5,0x37,0x2e, 0x6,0x47,0x2e, + 0x6,0x47,0x3c, 0x5,0x3e,0x22, 0x6,0x47,0x2b, 0x6,0x47,0x2f, + 0x6,0x47,0x38, 0x5,0x37,0x22, 0x6,0x47,0x34, 0x6,0x47,0x3f, + 0x6,0x47,0x3a, 0x4,0x36,0x64, 0x5,0x37,0x26, 0x5,0x36,0x73, + 0xf,0x39,0x5b, 0xf,0x39,0x5d, 0xf,0x39,0x5e, 0xf,0x39,0x61, + 0xf,0x39,0x62, 0xf,0x39,0x63, 0xf,0x39,0x64, 0xf,0x39,0x65, + 0xf,0x39,0x66, 0xf,0x39,0x67, 0xf,0x39,0x68, 0xf,0x39,0x6a, + 0xf,0x39,0x6d, 0xf,0x39,0x6e, 0xf,0x39,0x6f, 0xf,0x39,0x70, + 0x5,0x36,0x74, 0x5,0x36,0x75, 0x5,0x36,0x7b, 0x5,0x37,0x25, + 0x5,0x37,0x21, 0x6,0x47,0x3b, 0xf,0x39,0x6b, 0xf,0x39,0x5c, + 0xf,0x39,0x5f, 0xf,0x39,0x69, 0xf,0x39,0x6c, 0x5,0x37,0x2b, + 0x5,0x37,0x2f, 0x6,0x47,0x3d, 0x5,0x37,0x2d, 0x5,0x37,0x2a, + 0x5,0x36,0x7d, 0x6,0x47,0x36, 0x6,0x51,0x39, 0x5,0x3e,0x23, + 0x4,0x3c,0x49, 0x5,0x3e,0x27, 0x4,0x3c,0x4e, 0x5,0x36,0x72, + 0x6,0x51,0x41, 0x4,0x3c,0x48, 0x4,0x3c,0x44, 0x6,0x5b,0x42, + 0x5,0x3e,0x2d, 0x6,0x51,0x33, 0x6,0x51,0x35, 0x5,0x3e,0x2a, + 0x5,0x3e,0x38, 0x6,0x51,0x3a, 0x6,0x51,0x30, 0x5,0x3e,0x2e, + 0x5,0x3e,0x24, 0x5,0x3e,0x35, 0x5,0x3e,0x3f, 0x6,0x51,0x3f, + 0x6,0x51,0x37, 0x5,0x3e,0x34, 0x5,0x3e,0x37, 0x4,0x3c,0x4d, + 0x5,0x3e,0x3a, 0x4,0x3c,0x45, 0x5,0x3e,0x33, 0x5,0x3e,0x2c, + 0x4,0x3c,0x4f, 0x5,0x3e,0x2f, 0x4,0x3c,0x51, 0x5,0x3e,0x31, + 0x5,0x3e,0x32, 0x6,0x51,0x3b, 0x6,0x51,0x40, 0x6,0x51,0x2a, + 0x6,0x51,0x3e, 0x6,0x51,0x3d, 0x5,0x3e,0x3b, 0x6,0x51,0x38, + 0x5,0x3e,0x28, 0x5,0x3e,0x30, 0x5,0x3e,0x2b, 0x6,0x51,0x2c, + 0x6,0x51,0x44, 0x6,0x51,0x2e, 0x6,0x51,0x2b, 0x6,0x51,0x2d, + 0xf,0x47,0x26, 0x5,0x3e,0x3e, 0x6,0x51,0x31, 0xf,0x40,0x56, + 0xf,0x40,0x57, 0xf,0x40,0x58, 0xf,0x40,0x59, 0xf,0x40,0x5a, + 0xf,0x40,0x5b, 0xf,0x40,0x5c, 0xf,0x40,0x5d, 0xf,0x40,0x5e, + 0xf,0x40,0x5f, 0xf,0x40,0x60, 0xf,0x40,0x61, 0xf,0x40,0x63, + 0x6,0x51,0x2f, 0x6,0x51,0x34, 0x6,0x51,0x3c, 0xf,0x40,0x54, + 0x6,0x51,0x42, 0x5,0x3e,0x3c, 0x5,0x3e,0x36, 0x5,0x3e,0x25, + 0x5,0x3e,0x29, 0x5,0x3e,0x26, 0xf,0x40,0x64, 0x6,0x5b,0x46, + 0x6,0x5b,0x40, 0x6,0x5b,0x4b, 0x4,0x42,0x4d, 0x6,0x5b,0x4f, + 0x6,0x5b,0x45, 0x6,0x5b,0x51, 0x6,0x5b,0x50, 0x4,0x42,0x4e, + 0x6,0x5b,0x4c, 0x5,0x44,0x73, 0x5,0x44,0x77, 0x5,0x44,0x75, + 0x5,0x44,0x7c, 0x6,0x5b,0x43, 0x6,0x5b,0x47, 0x4,0x42,0x4c, + 0x4,0x42,0x54, 0x5,0x44,0x7b, 0x4,0x42,0x50, 0x5,0x44,0x76, + 0x6,0x5b,0x41, 0x5,0x44,0x71, 0x5,0x44,0x72, 0x5,0x44,0x79, + 0x6,0x5b,0x52, 0x6,0x5b,0x3f, 0x6,0x5b,0x49, 0x6,0x5b,0x4a, + 0x5,0x44,0x78, 0x6,0x5b,0x4d, 0xf,0x46,0x71, 0xf,0x46,0x72, + 0xf,0x46,0x73, 0xf,0x46,0x74, 0xf,0x46,0x76, 0xf,0x46,0x77, + 0xf,0x46,0x78, 0xf,0x46,0x79, 0xf,0x46,0x7a, 0xf,0x46,0x7b, + 0xf,0x46,0x7c, 0xf,0x46,0x7e, 0xf,0x47,0x21, 0xf,0x47,0x22, + 0xf,0x47,0x23, 0xf,0x47,0x27, 0xf,0x47,0x28, 0xf,0x47,0x29, + 0xf,0x47,0x2a, 0xf,0x47,0x2b, 0xf,0x47,0x2c, 0xf,0x47,0x2d, + 0xf,0x47,0x24, 0x6,0x5b,0x48, 0xf,0x46,0x75, 0x5,0x44,0x74, + 0x5,0x44,0x7a, 0x6,0x5b,0x4e, 0x5,0x45,0x21, 0xf,0x46,0x7d, + 0x6,0x5b,0x44, 0xf,0x47,0x25, 0x5,0x4c,0x35, 0x5,0x44,0x7d, + 0xf,0x46,0x6c, 0x7,0x21,0x51, 0x5,0x4c,0x3b, 0x7,0x21,0x55, + 0x7,0x21,0x52, 0x5,0x4c,0x39, 0x7,0x21,0x58, 0x7,0x21,0x4a, + 0x5,0x4c,0x40, 0x5,0x4c,0x46, 0x5,0x4c,0x3d, 0x7,0x21,0x4f, + 0x5,0x4c,0x3e, 0x7,0x21,0x57, 0x7,0x21,0x50, 0x5,0x4c,0x36, + 0x7,0x21,0x4b, 0x5,0x4c,0x3f, 0x7,0x21,0x56, 0x7,0x21,0x59, + 0x5,0x4c,0x41, 0x4,0x49,0x2f, 0x7,0x21,0x5b, 0x5,0x4c,0x3a, + 0x7,0x21,0x48, 0x5,0x4c,0x38, 0x5,0x5b,0x27, 0x7,0x21,0x5a, + 0x4,0x49,0x2b, 0x7,0x21,0x54, 0x5,0x45,0x23, 0x7,0x21,0x53, + 0x7,0x21,0x49, 0x7,0x21,0x47, 0x7,0x21,0x62, 0x7,0x21,0x5c, + 0xf,0x4d,0x7a, 0x7,0x21,0x5e, 0x5,0x4c,0x42, 0x7,0x21,0x61, + 0x7,0x2c,0x61, 0x5,0x4c,0x37, 0x4,0x49,0x32, 0x5,0x4c,0x47, + 0xf,0x4d,0x6f, 0xf,0x4d,0x70, 0xf,0x4d,0x71, 0xf,0x4d,0x72, + 0xf,0x4d,0x73, 0xf,0x4d,0x74, 0xf,0x4d,0x75, 0xf,0x4d,0x76, + 0xf,0x4d,0x78, 0xf,0x4d,0x79, 0x5,0x4c,0x44, 0x7,0x21,0x5f, + 0x7,0x26,0x2b, 0x7,0x21,0x5d, 0x7,0x21,0x4d, 0x7,0x21,0x4c, + 0x5,0x4c,0x3c, 0x5,0x4c,0x43, 0x7,0x2c,0x6a, 0x4,0x4f,0x6e, + 0x5,0x53,0x74, 0x7,0x2c,0x5c, 0x5,0x53,0x72, 0x7,0x2c,0x68, + 0x4,0x4f,0x72, 0x5,0x53,0x6a, 0x5,0x53,0x78, 0x7,0x2c,0x60, + 0x4,0x4f,0x68, 0x4,0x4f,0x73, 0x4,0x4f,0x66, 0x5,0x53,0x71, + 0x4,0x4f,0x70, 0x5,0x53,0x6f, 0x5,0x53,0x68, 0x7,0x2c,0x6b, + 0x7,0x2c,0x5b, 0x7,0x2c,0x64, 0x5,0x53,0x6e, 0x7,0x2c,0x5f, + 0x5,0x53,0x6c, 0x5,0x53,0x67, 0x5,0x53,0x75, 0x5,0x53,0x70, + 0x5,0x53,0x73, 0x7,0x2c,0x59, 0x5,0x53,0x6b, 0x5,0x53,0x69, + 0x7,0x2c,0x67, 0x7,0x2c,0x58, 0x7,0x2c,0x57, 0xf,0x4d,0x77, + 0x4,0x4f,0x69, 0x4,0x4f,0x74, 0x5,0x53,0x77, 0x7,0x2c,0x66, + 0xf,0x53,0x5c, 0xf,0x53,0x5e, 0xf,0x53,0x5f, 0xf,0x53,0x60, + 0xf,0x53,0x61, 0xf,0x53,0x62, 0xf,0x53,0x63, 0xf,0x53,0x64, + 0xf,0x53,0x65, 0xf,0x53,0x67, 0xf,0x53,0x68, 0xf,0x53,0x69, + 0xf,0x53,0x6a, 0xf,0x53,0x6b, 0xf,0x53,0x6c, 0xf,0x53,0x6d, + 0xf,0x53,0x6e, 0xf,0x53,0x6f, 0x7,0x2c,0x5e, 0x7,0x2c,0x5d, + 0x7,0x2c,0x62, 0x7,0x2c,0x69, 0x5,0x53,0x6d, 0xf,0x55,0x74, + 0x5,0x53,0x76, 0x4,0x55,0x7a, 0x5,0x5b,0x26, 0x5,0x5b,0x21, + 0x7,0x37,0x2d, 0x7,0x37,0x2a, 0x7,0x37,0x34, 0x7,0x37,0x35, + 0x5,0x5b,0x23, 0x5,0x5b,0x2b, 0x4,0x55,0x71, 0x4,0x55,0x76, + 0x5,0x5b,0x28, 0x4,0x55,0x77, 0x7,0x37,0x2b, 0x5,0x5b,0x29, + 0x4,0x55,0x79, 0x7,0x37,0x31, 0x7,0x37,0x2f, 0x7,0x37,0x2e, + 0x5,0x5b,0x24, 0x4,0x55,0x75, 0x7,0x37,0x32, 0x7,0x37,0x39, + 0xf,0x59,0x59, 0xf,0x59,0x5a, 0xf,0x59,0x5e, 0xf,0x59,0x5f, + 0xf,0x59,0x60, 0xf,0x59,0x61, 0xf,0x59,0x62, 0x7,0x37,0x38, + 0x7,0x37,0x30, 0x7,0x37,0x36, 0x7,0x37,0x33, 0x7,0x37,0x2c, + 0x5,0x5b,0x2a, 0x5,0x5b,0x22, 0x4,0x5a,0x74, 0x7,0x3f,0x29, + 0x7,0x3f,0x2f, 0x4,0x5a,0x73, 0x5,0x61,0x3e, 0x7,0x3f,0x2b, + 0x4,0x5a,0x71, 0x4,0x5a,0x76, 0x5,0x61,0x46, 0x4,0x5a,0x77, + 0x5,0x67,0x58, 0x5,0x61,0x3d, 0x5,0x61,0x44, 0x5,0x61,0x43, + 0x4,0x5a,0x78, 0x7,0x3f,0x2a, 0x4,0x5a,0x75, 0x4,0x5a,0x79, + 0x4,0x5a,0x72, 0x7,0x3f,0x2e, 0x5,0x61,0x41, 0x7,0x3f,0x27, + 0x7,0x3f,0x2d, 0x7,0x3f,0x28, 0x7,0x3f,0x26, 0x7,0x3f,0x2c, + 0x5,0x61,0x42, 0xf,0x59,0x5b, 0x7,0x3f,0x25, 0xf,0x5e,0x3c, + 0xf,0x5e,0x3d, 0xf,0x5e,0x3e, 0xf,0x5e,0x3f, 0xf,0x5e,0x40, + 0xf,0x5e,0x43, 0xf,0x5e,0x44, 0xf,0x5e,0x45, 0x5,0x61,0x3f, + 0xf,0x5e,0x4a, 0x7,0x46,0x34, 0x4,0x5f,0x4e, 0x5,0x5b,0x25, + 0x7,0x46,0x3b, 0x7,0x46,0x39, 0x7,0x46,0x37, 0x5,0x67,0x5a, + 0x5,0x67,0x5b, 0x4,0x5f,0x50, 0x5,0x67,0x57, 0x7,0x46,0x3c, + 0x7,0x46,0x3a, 0x7,0x46,0x33, 0x7,0x46,0x35, 0x7,0x46,0x38, + 0x4,0x5f,0x4f, 0xf,0x5e,0x46, 0x5,0x67,0x5c, 0xf,0x62,0x22, + 0xf,0x62,0x23, 0xf,0x62,0x24, 0xf,0x62,0x25, 0xf,0x62,0x26, + 0x7,0x46,0x36, 0x7,0x47,0x6e, 0x7,0x46,0x3d, 0x5,0x6b,0x74, + 0x5,0x6b,0x75, 0x5,0x6b,0x6f, 0x5,0x6b,0x71, 0x5,0x6b,0x70, + 0x7,0x4d,0x47, 0x7,0x4d,0x49, 0x7,0x4d,0x4b, 0x7,0x4d,0x48, + 0x7,0x4d,0x46, 0x7,0x4d,0x4a, 0xf,0x64,0x7d, 0xf,0x64,0x7e, + 0xf,0x65,0x21, 0x7,0x4d,0x4c, 0x5,0x6b,0x72, 0x7,0x52,0x7b, + 0x5,0x6f,0x71, 0x5,0x6f,0x6f, 0x4,0x66,0x35, 0x5,0x6f,0x6e, + 0x7,0x52,0x7a, 0x5,0x6f,0x6d, 0x7,0x52,0x7e, 0x5,0x6f,0x70, + 0x7,0x52,0x7d, 0x4,0x66,0x33, 0xf,0x67,0x47, 0xf,0x67,0x48, + 0x5,0x6f,0x6c, 0x7,0x52,0x7c, 0x7,0x57,0x59, 0x7,0x57,0x5a, + 0x5,0x73,0x33, 0x7,0x57,0x55, 0x7,0x57,0x56, 0x7,0x57,0x57, + 0x7,0x57,0x54, 0x7,0x57,0x52, 0x7,0x57,0x53, 0xf,0x69,0x3c, + 0x4,0x68,0x64, 0x7,0x57,0x58, 0x7,0x5b,0x49, 0x7,0x5b,0x4a, + 0xf,0x6a,0x4d, 0x7,0x5b,0x48, 0x7,0x5b,0x47, 0x5,0x77,0x55, + 0x5,0x77,0x56, 0x4,0x6b,0x66, 0x7,0x5e,0x53, 0x7,0x5e,0x55, + 0x7,0x5e,0x54, 0x7,0x5e,0x56, 0xf,0x6b,0x43, 0x5,0x75,0x67, + 0x5,0x79,0x23, 0x4,0x6c,0x6d, 0xf,0x6c,0x22, 0xf,0x6c,0x23, + 0x7,0x60,0x6b, 0x7,0x62,0x32, 0x7,0x62,0x31, 0x7,0x62,0x34, + 0x7,0x62,0x30, 0x7,0x62,0x33, 0xf,0x6c,0x79, 0xf,0x6c,0x7a, + 0x6,0x21,0x65, 0x6,0x21,0x66, 0xf,0x21,0x37, 0x4,0x21,0x6e, + 0x6,0x24,0x32, 0x6,0x24,0x30, 0x5,0x22,0x49, 0xf,0x22,0x35, + 0x6,0x24,0x31, 0x6,0x24,0x2f, 0x5,0x22,0x48, 0x6,0x26,0x54, + 0x6,0x2f,0x5c, 0x6,0x2a,0x3e, 0x6,0x26,0x58, 0x6,0x26,0x56, + 0xf,0x23,0x4f, 0xf,0x23,0x51, 0x6,0x26,0x57, 0x6,0x26,0x59, + 0x6,0x26,0x5c, 0x6,0x26,0x5a, 0x6,0x26,0x51, 0x6,0x26,0x55, + 0x6,0x26,0x52, 0x6,0x26,0x53, 0x6,0x26,0x5b, 0x5,0x25,0x55, + 0x6,0x2a,0x43, 0x6,0x2a,0x40, 0x6,0x2a,0x41, 0x6,0x2a,0x42, + 0x6,0x2d,0x34, 0x6,0x2a,0x3f, 0xf,0x26,0x24, 0x5,0x25,0x54, + 0x5,0x28,0x54, 0x5,0x28,0x56, 0x6,0x2f,0x60, 0x6,0x2f,0x5f, + 0x5,0x28,0x55, 0x6,0x2f,0x5b, 0x6,0x2f,0x5e, 0x6,0x2f,0x5d, + 0x5,0x2c,0x5c, 0x6,0x36,0x2d, 0x6,0x36,0x2a, 0x6,0x36,0x2c, + 0x5,0x2c,0x5b, 0x6,0x36,0x2b, 0x5,0x2c,0x5d, 0x5,0x31,0x56, + 0x6,0x3e,0x25, 0x5,0x31,0x57, 0x6,0x3e,0x24, 0x6,0x3e,0x23, + 0x6,0x3e,0x22, 0x5,0x31,0x54, 0x6,0x3e,0x26, 0x5,0x37,0x33, + 0x6,0x47,0x40, 0x6,0x47,0x41, 0x5,0x37,0x31, 0x5,0x31,0x55, + 0xf,0x39,0x72, 0xf,0x39,0x73, 0xf,0x39,0x74, 0x6,0x47,0x42, + 0x5,0x37,0x32, 0x5,0x3e,0x40, 0x6,0x51,0x45, 0x5,0x3e,0x41, + 0x6,0x51,0x47, 0x6,0x51,0x48, 0x5,0x3e,0x42, 0x6,0x51,0x46, + 0xf,0x40,0x65, 0x6,0x5b,0x54, 0x6,0x5b,0x58, 0x5,0x45,0x24, + 0x6,0x5b,0x55, 0x6,0x5b,0x5a, 0x6,0x5b,0x56, 0xf,0x47,0x2e, + 0xf,0x47,0x2f, 0xf,0x47,0x30, 0x6,0x5b,0x57, 0x7,0x21,0x65, + 0x7,0x21,0x66, 0x7,0x21,0x64, 0xf,0x4d,0x7b, 0x4,0x4f,0x75, + 0xf,0x53,0x73, 0x7,0x37,0x3c, 0x7,0x37,0x3a, 0x7,0x37,0x3b, + 0x4,0x5f,0x51, 0x7,0x4d,0x4d, 0x7,0x53,0x22, 0x7,0x53,0x21, + 0x4,0x21,0x48, 0x5,0x21,0x44, 0x6,0x22,0x60, 0xf,0x21,0x51, + 0xf,0x21,0x52, 0x6,0x22,0x61, 0x6,0x24,0x35, 0xf,0x22,0x36, + 0xf,0x22,0x37, 0x6,0x24,0x34, 0x6,0x26,0x6a, 0x4,0x23,0x60, + 0x6,0x26,0x66, 0x6,0x26,0x62, 0x6,0x26,0x5e, 0x6,0x26,0x69, + 0x6,0x26,0x5d, 0x6,0x26,0x65, 0x6,0x26,0x67, 0xf,0x23,0x53, + 0xf,0x23,0x54, 0xf,0x23,0x56, 0xf,0x23,0x58, 0xf,0x23,0x5a, + 0x6,0x26,0x60, 0x6,0x26,0x63, 0x6,0x26,0x68, 0x6,0x26,0x64, + 0x6,0x26,0x61, 0x6,0x26,0x5f, 0x5,0x23,0x5e, 0xf,0x23,0x59, + 0x5,0x23,0x5d, 0x5,0x23,0x5f, 0x5,0x23,0x60, 0x5,0x23,0x61, + 0x4,0x25,0x6a, 0x6,0x2a,0x4f, 0x6,0x2a,0x47, 0x6,0x2a,0x4c, + 0x6,0x2a,0x46, 0x4,0x25,0x67, 0x6,0x2a,0x4a, 0x4,0x25,0x6c, + 0x6,0x2a,0x48, 0x5,0x25,0x56, 0x6,0x2a,0x51, 0x6,0x26,0x41, + 0x6,0x2a,0x49, 0xf,0x26,0x26, 0xf,0x26,0x27, 0xf,0x26,0x28, + 0xf,0x26,0x29, 0xf,0x26,0x2a, 0xf,0x26,0x30, 0xf,0x26,0x31, + 0xf,0x26,0x2c, 0xf,0x26,0x2b, 0x4,0x25,0x6b, 0xf,0x26,0x2f, + 0xf,0x26,0x2e, 0x6,0x2a,0x50, 0x6,0x2a,0x4b, 0x6,0x2a,0x4d, + 0x6,0x2a,0x4e, 0xf,0x26,0x32, 0xf,0x26,0x25, 0x6,0x2a,0x45, + 0x6,0x2a,0x44, 0x5,0x25,0x57, 0x5,0x28,0x5b, 0x6,0x2f,0x62, + 0x5,0x28,0x57, 0x6,0x2f,0x64, 0x6,0x2f,0x61, 0x5,0x28,0x58, + 0x4,0x28,0x5f, 0x6,0x2f,0x6b, 0x6,0x2f,0x63, 0xf,0x29,0x7a, + 0xf,0x29,0x68, 0xf,0x29,0x69, 0xf,0x29,0x6b, 0xf,0x29,0x6c, + 0xf,0x29,0x6d, 0xf,0x29,0x6e, 0xf,0x29,0x6f, 0xf,0x29,0x70, + 0xf,0x29,0x72, 0xf,0x29,0x73, 0xf,0x29,0x75, 0xf,0x29,0x76, + 0xf,0x29,0x77, 0xf,0x29,0x78, 0xf,0x29,0x79, 0xf,0x29,0x7b, + 0xf,0x29,0x7c, 0xf,0x29,0x7d, 0x6,0x2f,0x6a, 0x6,0x2f,0x6c, + 0x6,0x34,0x31, 0x6,0x2f,0x67, 0x6,0x2f,0x68, 0x6,0x2f,0x66, + 0xf,0x29,0x74, 0x5,0x28,0x5d, 0x5,0x28,0x5a, 0x5,0x28,0x5e, + 0x5,0x28,0x5c, 0x5,0x28,0x59, 0x5,0x2c,0x5e, 0x4,0x2c,0x32, + 0x6,0x36,0x34, 0x4,0x2c,0x30, 0x4,0x2c,0x34, 0x6,0x36,0x32, + 0x6,0x36,0x3c, 0x6,0x36,0x36, 0x6,0x36,0x3d, 0x6,0x36,0x3e, + 0x6,0x36,0x31, 0x6,0x36,0x2e, 0x6,0x36,0x3a, 0x6,0x36,0x2f, + 0x6,0x36,0x40, 0xf,0x2e,0x55, 0xf,0x2e,0x56, 0xf,0x2e,0x57, + 0xf,0x2e,0x58, 0xf,0x2e,0x59, 0xf,0x2e,0x5a, 0xf,0x2e,0x5b, + 0xf,0x2e,0x5e, 0xf,0x2e,0x5f, 0xf,0x2e,0x60, 0x6,0x36,0x30, + 0x6,0x36,0x3f, 0x6,0x36,0x37, 0x6,0x36,0x38, 0x6,0x36,0x39, + 0x5,0x2c,0x60, 0x6,0x36,0x3b, 0xf,0x2e,0x5d, 0xf,0x2e,0x61, + 0x6,0x36,0x33, 0x5,0x2c,0x5f, 0x5,0x2c,0x62, 0x4,0x30,0x7d, + 0x6,0x3e,0x27, 0x4,0x30,0x7c, 0x5,0x31,0x5d, 0x6,0x3e,0x34, + 0x6,0x3e,0x2d, 0x5,0x31,0x5b, 0x6,0x3e,0x2a, 0x5,0x2c,0x61, + 0x6,0x3e,0x33, 0x6,0x3e,0x30, 0x5,0x31,0x5a, 0x4,0x31,0x22, + 0x4,0x31,0x23, 0xf,0x33,0x4f, 0xf,0x33,0x5b, 0x6,0x3e,0x2e, + 0x6,0x3e,0x2f, 0xf,0x33,0x4e, 0xf,0x33,0x50, 0xf,0x33,0x51, + 0xf,0x33,0x52, 0xf,0x33,0x53, 0xf,0x33,0x54, 0xf,0x33,0x55, + 0xf,0x33,0x56, 0xf,0x33,0x58, 0xf,0x33,0x59, 0xf,0x33,0x5a, + 0xf,0x33,0x5e, 0xf,0x33,0x5f, 0xf,0x33,0x60, 0xf,0x33,0x61, + 0x5,0x31,0x5c, 0x6,0x3e,0x31, 0x6,0x3e,0x35, 0x4,0x30,0x7e, + 0x6,0x3e,0x28, 0x6,0x3e,0x29, 0x5,0x31,0x58, 0x5,0x31,0x59, + 0x3,0x3a,0x4f, 0x6,0x51,0x4e, 0x4,0x36,0x72, 0x6,0x47,0x47, + 0x4,0x36,0x6a, 0x6,0x47,0x45, 0x4,0x36,0x70, 0x4,0x36,0x6c, + 0x6,0x47,0x4b, 0x6,0x47,0x50, 0x4,0x36,0x75, 0x6,0x47,0x44, + 0x6,0x47,0x46, 0x6,0x47,0x4d, 0x5,0x37,0x34, 0x6,0x3e,0x32, + 0x6,0x47,0x4f, 0x4,0x3c,0x5a, 0x5,0x37,0x39, 0x4,0x36,0x73, + 0x6,0x4f,0x6d, 0x5,0x37,0x38, 0xf,0x39,0x76, 0xf,0x39,0x78, + 0xf,0x39,0x79, 0xf,0x39,0x7a, 0xf,0x39,0x7b, 0xf,0x39,0x7c, + 0xf,0x3a,0x21, 0xf,0x3a,0x22, 0xf,0x3a,0x23, 0xf,0x3a,0x24, + 0xf,0x3a,0x25, 0xf,0x3a,0x26, 0x6,0x47,0x51, 0x6,0x47,0x4a, + 0x6,0x47,0x49, 0x4,0x36,0x74, 0x6,0x47,0x4c, 0xf,0x39,0x75, + 0x5,0x37,0x37, 0x5,0x37,0x3a, 0x6,0x47,0x48, 0x5,0x37,0x35, + 0x5,0x37,0x36, 0x5,0x37,0x3b, 0x5,0x3e,0x46, 0x6,0x51,0x56, + 0x6,0x51,0x4b, 0x6,0x51,0x55, 0x5,0x3e,0x4d, 0x4,0x3c,0x54, + 0x6,0x5b,0x62, 0x6,0x51,0x52, 0x5,0x3e,0x4c, 0x6,0x51,0x51, + 0x5,0x3e,0x44, 0x5,0x3e,0x4b, 0x5,0x3e,0x43, 0x6,0x51,0x54, + 0x6,0x51,0x50, 0x5,0x3e,0x49, 0x5,0x3e,0x4a, 0x4,0x3c,0x55, + 0x5,0x3e,0x47, 0x6,0x51,0x49, 0x6,0x51,0x4c, 0xf,0x39,0x77, + 0x6,0x51,0x53, 0x6,0x51,0x4d, 0xf,0x40,0x66, 0xf,0x40,0x67, + 0xf,0x40,0x68, 0xf,0x40,0x6a, 0xf,0x40,0x6b, 0xf,0x40,0x6c, + 0xf,0x40,0x6d, 0xf,0x40,0x6e, 0xf,0x40,0x6f, 0xf,0x40,0x70, + 0xf,0x40,0x71, 0xf,0x40,0x72, 0xf,0x40,0x73, 0x6,0x51,0x4f, + 0x5,0x3e,0x4e, 0x5,0x3e,0x48, 0x5,0x3e,0x45, 0x5,0x45,0x29, + 0x5,0x45,0x28, 0x5,0x45,0x27, 0x6,0x5b,0x5c, 0x4,0x42,0x5c, + 0x6,0x5b,0x64, 0x6,0x5b,0x66, 0x6,0x5b,0x61, 0x5,0x45,0x2a, + 0x6,0x5b,0x60, 0x5,0x45,0x26, 0x6,0x5b,0x67, 0xf,0x47,0x32, + 0xf,0x47,0x33, 0xf,0x47,0x34, 0xf,0x47,0x35, 0xf,0x47,0x36, + 0xf,0x47,0x37, 0xf,0x47,0x39, 0xf,0x47,0x3a, 0xf,0x47,0x3b, + 0xf,0x47,0x3c, 0x6,0x5b,0x5d, 0xf,0x47,0x38, 0x6,0x5b,0x6b, + 0x6,0x5b,0x63, 0x6,0x5b,0x53, 0xf,0x47,0x31, 0x4,0x42,0x5a, + 0x6,0x5b,0x65, 0x6,0x5b,0x5e, 0x5,0x45,0x25, 0x5,0x45,0x2b, + 0x7,0x21,0x72, 0x4,0x49,0x34, 0x4,0x49,0x35, 0x7,0x21,0x6f, + 0x4,0x49,0x36, 0x5,0x4c,0x4b, 0x5,0x4c,0x4c, 0x7,0x21,0x6b, + 0x7,0x21,0x78, 0x4,0x49,0x37, 0x7,0x21,0x77, 0x7,0x21,0x74, + 0xf,0x4e,0x21, 0x5,0x4c,0x4d, 0x5,0x4c,0x4f, 0x7,0x21,0x67, + 0x7,0x21,0x75, 0xf,0x4d,0x7c, 0xf,0x4d,0x7d, 0xf,0x4e,0x26, + 0xf,0x4e,0x27, 0xf,0x4e,0x28, 0xf,0x4e,0x29, 0xf,0x4e,0x2a, + 0xf,0x4e,0x2b, 0xf,0x4e,0x2d, 0x7,0x21,0x6c, 0x7,0x21,0x6d, + 0x7,0x21,0x6e, 0x5,0x4c,0x71, 0x7,0x21,0x73, 0x7,0x21,0x71, + 0x7,0x21,0x69, 0xf,0x4d,0x7e, 0xf,0x4e,0x24, 0xf,0x4e,0x23, + 0x5,0x4c,0x4e, 0x5,0x4c,0x4a, 0x5,0x4c,0x48, 0x7,0x21,0x68, + 0x5,0x4c,0x49, 0x7,0x2c,0x6f, 0x7,0x2c,0x71, 0x7,0x2c,0x6c, + 0x4,0x4f,0x77, 0x4,0x4f,0x7a, 0x4,0x4f,0x79, 0x7,0x2c,0x6d, + 0x7,0x2c,0x70, 0xf,0x4e,0x2c, 0xf,0x53,0x74, 0xf,0x53,0x76, + 0xf,0x53,0x78, 0x5,0x53,0x7a, 0x7,0x2c,0x72, 0x5,0x53,0x7b, + 0x5,0x53,0x79, 0x7,0x34,0x6f, 0x7,0x2c,0x73, 0x7,0x2c,0x6e, + 0xf,0x53,0x77, 0x4,0x4f,0x76, 0x7,0x37,0x43, 0x4,0x55,0x7d, + 0x7,0x37,0x3d, 0x5,0x5b,0x2e, 0x7,0x37,0x3f, 0x7,0x37,0x44, + 0x7,0x37,0x42, 0x7,0x37,0x45, 0x5,0x5b,0x2c, 0x7,0x2c,0x74, + 0xf,0x59,0x64, 0xf,0x59,0x65, 0xf,0x59,0x66, 0xf,0x59,0x67, + 0xf,0x59,0x68, 0xf,0x59,0x69, 0xf,0x59,0x6a, 0xf,0x59,0x6b, + 0x7,0x3e,0x6c, 0x7,0x37,0x40, 0x7,0x37,0x41, 0x4,0x55,0x7e, + 0x5,0x5b,0x2f, 0x7,0x3f,0x34, 0x5,0x61,0x47, 0x7,0x37,0x3e, + 0x5,0x61,0x49, 0x7,0x3f,0x33, 0xf,0x5e,0x47, 0xf,0x5e,0x48, + 0xf,0x5e,0x49, 0xf,0x5e,0x4b, 0xf,0x5e,0x4d, 0xf,0x5e,0x4e, + 0x7,0x3f,0x31, 0x7,0x3f,0x32, 0x5,0x5b,0x30, 0x5,0x61,0x48, + 0xf,0x62,0x28, 0x5,0x61,0x4a, 0x7,0x46,0x42, 0x7,0x46,0x3f, + 0x5,0x67,0x5d, 0x7,0x46,0x47, 0x7,0x46,0x41, 0xf,0x5e,0x4c, + 0xf,0x62,0x27, 0x7,0x46,0x43, 0x7,0x46,0x46, 0x7,0x4a,0x3b, + 0x7,0x46,0x40, 0x7,0x3f,0x35, 0x4,0x63,0x33, 0xf,0x65,0x22, + 0xf,0x65,0x23, 0xf,0x65,0x24, 0xf,0x65,0x25, 0x7,0x4d,0x4e, + 0x5,0x6b,0x77, 0x7,0x53,0x28, 0x4,0x66,0x36, 0x7,0x53,0x24, + 0x7,0x53,0x23, 0x7,0x53,0x27, 0x7,0x53,0x25, 0x5,0x6f,0x74, + 0xf,0x67,0x49, 0xf,0x67,0x4a, 0xf,0x67,0x4c, 0x7,0x53,0x26, + 0xf,0x67,0x4b, 0x5,0x6f,0x72, 0x5,0x6f,0x73, 0x7,0x57,0x5b, + 0xf,0x69,0x3d, 0x5,0x73,0x34, 0x7,0x57,0x5d, 0x5,0x73,0x35, + 0x7,0x5b,0x4b, 0x7,0x57,0x5c, 0x7,0x5e,0x57, 0x5,0x77,0x57, + 0x5,0x7b,0x5f, 0x7,0x65,0x5a, 0x7,0x66,0x42, 0x7,0x66,0x4f, + 0x6,0x22,0x62, 0x6,0x2f,0x6d, 0x6,0x26,0x6b, 0x6,0x2a,0x52, + 0xf,0x29,0x7e, 0xf,0x2a,0x21, 0x5,0x2c,0x64, 0x6,0x36,0x42, + 0x6,0x2f,0x6e, 0x6,0x36,0x41, 0xf,0x2e,0x62, 0x5,0x2c,0x63, + 0x6,0x3e,0x36, 0xf,0x33,0x62, 0x6,0x47,0x52, 0x6,0x51,0x59, + 0x6,0x51,0x58, 0x6,0x5b,0x6a, 0x6,0x64,0x7a, 0x6,0x5b,0x68, + 0xf,0x47,0x3d, 0x6,0x5b,0x69, 0x7,0x21,0x7a, 0x7,0x21,0x79, + 0x7,0x2c,0x75, 0x7,0x3f,0x36, 0x7,0x43,0x3f, 0xf,0x5e,0x4f, + 0x7,0x3f,0x37, 0x7,0x46,0x48, 0x7,0x46,0x49, 0x7,0x48,0x3b, + 0x7,0x57,0x5e, 0x5,0x21,0x2f, 0x6,0x22,0x63, 0x6,0x24,0x37, + 0x6,0x24,0x36, 0x6,0x26,0x6c, 0xf,0x23,0x5c, 0x6,0x36,0x43, + 0x6,0x3e,0x37, 0x6,0x3e,0x38, 0x6,0x51,0x5a, 0x6,0x24,0x39, + 0x6,0x24,0x38, 0x5,0x23,0x64, 0x5,0x23,0x63, 0x4,0x25,0x6f, + 0x6,0x2a,0x53, 0xf,0x26,0x34, 0xf,0x2e,0x63, 0x5,0x31,0x5e, + 0x6,0x3e,0x39, 0x6,0x3e,0x3c, 0x5,0x2c,0x65, 0x6,0x3e,0x3b, + 0x6,0x3e,0x3a, 0x5,0x3e,0x4f, 0x6,0x51,0x5c, 0xf,0x40,0x74, + 0x6,0x5b,0x6c, 0xf,0x47,0x3e, 0x6,0x5b,0x6d, 0x5,0x4c,0x50, + 0xf,0x4e,0x2f, 0xf,0x53,0x79, 0x7,0x2c,0x76, 0x7,0x2c,0x77, + 0x7,0x37,0x46, 0x7,0x46,0x4a, 0x7,0x3f,0x3a, 0x7,0x3f,0x38, + 0x7,0x3f,0x39, 0x7,0x46,0x4b, 0x7,0x4d,0x4f, 0x6,0x22,0x64, + 0x6,0x22,0x65, 0x6,0x24,0x3a, 0x6,0x26,0x6e, 0x6,0x26,0x6d, + 0x6,0x2a,0x54, 0xf,0x25,0x42, 0x5,0x28,0x5f, 0x5,0x2c,0x68, + 0x4,0x2c,0x35, 0x5,0x2c,0x67, 0x6,0x36,0x46, 0x6,0x36,0x45, + 0xf,0x2e,0x64, 0xf,0x2e,0x65, 0x6,0x36,0x47, 0x5,0x2c,0x69, + 0x4,0x31,0x24, 0x5,0x31,0x61, 0x6,0x3e,0x3d, 0x5,0x31,0x5f, + 0x5,0x31,0x60, 0x5,0x31,0x62, 0xf,0x33,0x63, 0x6,0x47,0x54, + 0x5,0x37,0x3e, 0x5,0x37,0x42, 0x5,0x37,0x40, 0x5,0x37,0x41, + 0xf,0x3a,0x27, 0x5,0x3e,0x50, 0x6,0x51,0x5d, 0x5,0x3e,0x52, + 0x5,0x3e,0x51, 0x6,0x51,0x5f, 0x4,0x42,0x61, 0x6,0x5b,0x6f, + 0x6,0x5b,0x70, 0x6,0x5b,0x6e, 0x5,0x45,0x2c, 0x5,0x45,0x2e, + 0x7,0x21,0x7b, 0x5,0x4c,0x51, 0x7,0x3f,0x3b, 0x5,0x5b,0x31, + 0x5,0x5b,0x32, 0x7,0x46,0x4c, 0x6,0x21,0x67, 0x6,0x21,0x68, + 0xf,0x21,0x38, 0x6,0x22,0x66, 0xf,0x21,0x53, 0xf,0x21,0x54, + 0x5,0x21,0x76, 0x6,0x24,0x3c, 0x4,0x22,0x54, 0x6,0x24,0x3f, + 0x6,0x24,0x40, 0x6,0x24,0x3e, 0x6,0x24,0x3d, 0xf,0x21,0x6b, + 0x4,0x23,0x63, 0x4,0x23,0x64, 0x4,0x23,0x66, 0xf,0x23,0x5d, + 0xf,0x23,0x5e, 0xf,0x23,0x5f, 0xf,0x23,0x60, 0xf,0x23,0x61, + 0xf,0x23,0x62, 0xf,0x23,0x63, 0x6,0x26,0x70, 0x6,0x26,0x6f, + 0x4,0x25,0x76, 0x5,0x25,0x5a, 0x4,0x25,0x74, 0x6,0x2a,0x55, + 0x6,0x2a,0x56, 0x4,0x28,0x63, 0x6,0x2a,0x5c, 0x6,0x2a,0x58, + 0x6,0x2a,0x59, 0xf,0x26,0x36, 0xf,0x26,0x37, 0x6,0x2a,0x5a, + 0x6,0x2a,0x5b, 0x6,0x2a,0x5d, 0x4,0x25,0x79, 0x6,0x2a,0x57, + 0x6,0x29,0x39, 0x4,0x28,0x64, 0x4,0x28,0x62, 0x5,0x28,0x61, + 0x5,0x28,0x62, 0x5,0x28,0x60, 0xf,0x2a,0x23, 0xf,0x2a,0x24, + 0xf,0x2a,0x25, 0xf,0x2a,0x26, 0xf,0x2a,0x28, 0xf,0x2a,0x29, + 0xf,0x2a,0x27, 0xf,0x2a,0x22, 0x5,0x2c,0x6c, 0x6,0x36,0x48, + 0x6,0x36,0x4b, 0x5,0x2c,0x6a, 0x5,0x2c,0x6d, 0xf,0x2e,0x67, + 0xf,0x2e,0x68, 0xf,0x2e,0x69, 0x6,0x36,0x4a, 0x4,0x2c,0x37, + 0x5,0x2c,0x6b, 0x5,0x31,0x64, 0xf,0x2e,0x66, 0x4,0x2c,0x36, + 0x6,0x3e,0x41, 0x6,0x3e,0x44, 0x3,0x34,0x7e, 0x6,0x3e,0x3e, + 0x6,0x3e,0x43, 0x6,0x3e,0x40, 0x6,0x3e,0x45, 0x6,0x3e,0x3f, + 0xf,0x33,0x64, 0xf,0x33,0x65, 0x4,0x31,0x27, 0x5,0x31,0x63, + 0x4,0x3c,0x5e, 0x6,0x47,0x58, 0x6,0x47,0x5b, 0x6,0x47,0x5d, + 0x6,0x47,0x5a, 0xf,0x3a,0x28, 0x6,0x47,0x55, 0x6,0x47,0x5c, + 0x5,0x37,0x43, 0x6,0x47,0x59, 0x4,0x36,0x7a, 0x4,0x36,0x78, + 0x5,0x37,0x44, 0x6,0x47,0x57, 0x6,0x51,0x60, 0x6,0x51,0x61, + 0x4,0x3c,0x5d, 0xf,0x40,0x76, 0x5,0x3e,0x53, 0x5,0x3e,0x54, + 0x5,0x3e,0x55, 0x6,0x5b,0x72, 0x4,0x42,0x63, 0x5,0x45,0x2f, + 0x4,0x42,0x62, 0xf,0x47,0x3f, 0xf,0x47,0x40, 0xf,0x47,0x41, + 0x6,0x5b,0x71, 0x5,0x45,0x30, 0x4,0x49,0x38, 0x7,0x22,0x22, + 0x7,0x21,0x7c, 0x7,0x22,0x21, 0x7,0x2c,0x7c, 0x7,0x21,0x7e, + 0x5,0x4c,0x53, 0xf,0x4e,0x31, 0xf,0x4e,0x32, 0x7,0x21,0x7d, + 0x4,0x42,0x64, 0x5,0x4c,0x52, 0x7,0x2c,0x7d, 0x5,0x53,0x7c, + 0x7,0x2c,0x78, 0x7,0x2c,0x79, 0x4,0x56,0x21, 0xf,0x53,0x7a, + 0x7,0x2c,0x7a, 0x7,0x37,0x48, 0x7,0x37,0x47, 0x5,0x5b,0x33, + 0x4,0x56,0x2e, 0x4,0x5a,0x7b, 0xf,0x62,0x29, 0x5,0x6b,0x78, + 0x7,0x53,0x29, 0xf,0x69,0x3e, 0x5,0x75,0x68, 0xf,0x6b,0x44, + 0x7,0x5e,0x58, 0xf,0x6c,0x5f, 0x5,0x21,0x62, 0xf,0x21,0x55, + 0xf,0x21,0x56, 0x6,0x24,0x41, 0x4,0x22,0x58, 0x6,0x24,0x42, + 0xf,0x22,0x39, 0xf,0x22,0x3a, 0xf,0x22,0x3b, 0xf,0x22,0x3c, + 0x4,0x22,0x57, 0x5,0x22,0x4b, 0x6,0x24,0x43, 0x5,0x22,0x4a, + 0x6,0x26,0x74, 0x4,0x23,0x68, 0x4,0x23,0x6b, 0xf,0x23,0x64, + 0xf,0x23,0x66, 0xf,0x23,0x68, 0xf,0x23,0x69, 0xf,0x23,0x6b, + 0xf,0x23,0x6c, 0xf,0x23,0x6d, 0xf,0x23,0x6e, 0xf,0x23,0x6f, + 0xf,0x23,0x65, 0x6,0x26,0x72, 0x6,0x26,0x73, 0x6,0x26,0x75, + 0x6,0x26,0x71, 0xf,0x23,0x6a, 0xf,0x23,0x67, 0x5,0x23,0x66, + 0x5,0x23,0x67, 0x5,0x23,0x65, 0x4,0x25,0x7c, 0x6,0x2a,0x61, + 0x6,0x2a,0x60, 0x5,0x25,0x60, 0x4,0x25,0x7a, 0x5,0x25,0x5e, + 0x4,0x25,0x7d, 0x5,0x25,0x5b, 0x5,0x25,0x5c, 0x4,0x25,0x7e, + 0xf,0x26,0x3a, 0xf,0x26,0x3b, 0xf,0x26,0x3e, 0xf,0x26,0x3f, + 0xf,0x26,0x40, 0xf,0x26,0x41, 0xf,0x26,0x42, 0xf,0x26,0x43, + 0xf,0x26,0x45, 0xf,0x26,0x46, 0xf,0x26,0x47, 0xf,0x26,0x48, + 0xf,0x26,0x49, 0x6,0x2a,0x5f, 0x6,0x2a,0x5e, 0xf,0x26,0x44, + 0xf,0x26,0x3c, 0xf,0x26,0x3d, 0x5,0x25,0x62, 0x5,0x25,0x5f, + 0x5,0x25,0x63, 0x5,0x25,0x61, 0x4,0x28,0x68, 0x5,0x28,0x64, + 0x6,0x2f,0x76, 0x6,0x2f,0x78, 0x6,0x2f,0x79, 0x4,0x28,0x65, + 0x4,0x28,0x6b, 0x5,0x28,0x66, 0x4,0x28,0x66, 0x5,0x28,0x63, + 0x6,0x2f,0x70, 0x6,0x2f,0x7b, 0x6,0x2f,0x74, 0x5,0x28,0x6b, + 0x6,0x2f,0x7e, 0xf,0x2a,0x2d, 0xf,0x2a,0x2e, 0xf,0x2a,0x2f, + 0xf,0x2a,0x30, 0xf,0x2a,0x31, 0xf,0x2a,0x32, 0xf,0x2a,0x33, + 0xf,0x2a,0x34, 0x6,0x2f,0x73, 0x6,0x2f,0x77, 0x4,0x28,0x6c, + 0x6,0x2f,0x75, 0x6,0x2f,0x7a, 0x6,0x2f,0x6f, 0x6,0x2f,0x7d, + 0x5,0x28,0x69, 0x4,0x28,0x6a, 0x5,0x28,0x6a, 0x5,0x28,0x67, + 0x6,0x2f,0x71, 0x6,0x2f,0x7c, 0x5,0x28,0x65, 0x5,0x28,0x68, + 0x6,0x2f,0x72, 0x3,0x30,0x53, 0x5,0x2c,0x70, 0x6,0x36,0x4f, + 0x5,0x2c,0x72, 0x5,0x2c,0x75, 0x5,0x2c,0x6f, 0x6,0x36,0x55, + 0x5,0x2c,0x6e, 0x6,0x36,0x56, 0x6,0x36,0x50, 0x6,0x36,0x51, + 0xf,0x2e,0x6c, 0xf,0x2e,0x6e, 0xf,0x2e,0x70, 0xf,0x2e,0x71, + 0xf,0x2e,0x73, 0xf,0x2e,0x74, 0xf,0x2e,0x75, 0xf,0x2e,0x76, + 0xf,0x2e,0x77, 0xf,0x2e,0x79, 0x6,0x36,0x54, 0x6,0x36,0x4e, + 0x5,0x2c,0x71, 0x6,0x36,0x53, 0x6,0x36,0x52, 0xf,0x2e,0x6f, + 0xf,0x2e,0x72, 0x5,0x2c,0x77, 0x5,0x2c,0x74, 0x5,0x2c,0x73, + 0x5,0x2c,0x76, 0x5,0x2c,0x78, 0x6,0x3e,0x4c, 0x6,0x3e,0x52, + 0x6,0x3e,0x46, 0x6,0x3e,0x47, 0x5,0x31,0x6a, 0x6,0x3e,0x48, + 0x6,0x3e,0x49, 0x6,0x3e,0x4f, 0x5,0x31,0x69, 0x5,0x31,0x6d, + 0x6,0x3e,0x4d, 0x4,0x31,0x2b, 0x6,0x3e,0x4e, 0x5,0x31,0x6b, + 0x6,0x3e,0x53, 0xf,0x33,0x68, 0xf,0x33,0x69, 0xf,0x33,0x6a, + 0xf,0x33,0x6b, 0xf,0x33,0x6c, 0xf,0x33,0x6d, 0xf,0x33,0x6e, + 0xf,0x33,0x6f, 0xf,0x33,0x71, 0xf,0x33,0x72, 0xf,0x33,0x74, + 0xf,0x33,0x75, 0xf,0x33,0x76, 0xf,0x33,0x77, 0xf,0x33,0x78, + 0xf,0x33,0x79, 0xf,0x33,0x7a, 0xf,0x33,0x7b, 0xf,0x33,0x7c, + 0xf,0x33,0x7d, 0xf,0x33,0x7e, 0xf,0x34,0x21, 0xf,0x34,0x22, + 0xf,0x34,0x23, 0xf,0x33,0x70, 0x6,0x3e,0x51, 0x4,0x31,0x2a, + 0x6,0x3e,0x4b, 0x6,0x3e,0x4a, 0x5,0x31,0x66, 0x5,0x31,0x67, + 0x5,0x31,0x68, 0x5,0x31,0x65, 0x4,0x36,0x7b, 0x6,0x47,0x62, + 0x4,0x36,0x7c, 0x5,0x37,0x5a, 0x6,0x47,0x5f, 0x4,0x37,0x21, + 0x5,0x37,0x48, 0x5,0x37,0x59, 0x6,0x47,0x64, 0x6,0x47,0x66, + 0x5,0x37,0x4f, 0x6,0x47,0x65, 0x6,0x47,0x60, 0x5,0x37,0x50, + 0x5,0x37,0x49, 0x5,0x37,0x57, 0x5,0x37,0x54, 0x5,0x37,0x47, + 0x5,0x37,0x4b, 0xf,0x3a,0x29, 0xf,0x3a,0x2b, 0xf,0x3a,0x2c, + 0xf,0x3a,0x2d, 0xf,0x3a,0x2e, 0xf,0x3a,0x2f, 0xf,0x3a,0x30, + 0xf,0x3a,0x32, 0xf,0x3a,0x33, 0xf,0x3a,0x34, 0xf,0x3a,0x36, + 0xf,0x3a,0x37, 0xf,0x3a,0x38, 0xf,0x3a,0x39, 0xf,0x3a,0x3a, + 0xf,0x3a,0x3e, 0xf,0x3a,0x3f, 0xf,0x3a,0x41, 0xf,0x3a,0x42, + 0xf,0x3a,0x43, 0xf,0x3a,0x44, 0xf,0x3a,0x45, 0xf,0x3a,0x3b, + 0x5,0x37,0x56, 0x6,0x47,0x63, 0x5,0x37,0x58, 0x6,0x47,0x5e, + 0xf,0x3a,0x3d, 0xf,0x3a,0x40, 0xf,0x3a,0x31, 0xf,0x3a,0x2a, + 0x5,0x37,0x45, 0x5,0x3e,0x56, 0x5,0x37,0x53, 0x5,0x37,0x4c, + 0x5,0x37,0x52, 0x5,0x37,0x51, 0x5,0x37,0x4a, 0x5,0x37,0x4d, + 0x5,0x37,0x55, 0x6,0x47,0x67, 0xf,0x33,0x67, 0x5,0x3e,0x5f, + 0x5,0x3e,0x5a, 0x5,0x3e,0x5d, 0x5,0x3e,0x57, 0x4,0x3c,0x65, + 0x5,0x3e,0x59, 0x6,0x51,0x63, 0x4,0x3c,0x62, 0x4,0x3c,0x60, + 0x6,0x51,0x67, 0x6,0x51,0x65, 0x6,0x5b,0x7c, 0x5,0x3e,0x5c, + 0x5,0x3e,0x5b, 0x6,0x51,0x66, 0xf,0x40,0x78, 0xf,0x40,0x79, + 0xf,0x40,0x7a, 0xf,0x40,0x7c, 0xf,0x40,0x7d, 0xf,0x40,0x7e, + 0xf,0x41,0x22, 0xf,0x41,0x23, 0x6,0x51,0x62, 0x6,0x51,0x64, + 0xf,0x40,0x77, 0x6,0x51,0x68, 0x5,0x3e,0x58, 0x5,0x3e,0x5e, + 0x5,0x3e,0x60, 0x6,0x51,0x6a, 0xf,0x41,0x21, 0x4,0x42,0x70, + 0x5,0x45,0x32, 0x4,0x42,0x6a, 0x6,0x5b,0x7b, 0x4,0x42,0x71, + 0x6,0x5b,0x73, 0x5,0x45,0x34, 0x7,0x22,0x29, 0x4,0x42,0x73, + 0x6,0x5b,0x75, 0xf,0x47,0x48, 0x4,0x42,0x6f, 0x5,0x45,0x37, + 0x4,0x42,0x6e, 0xf,0x47,0x47, 0xf,0x47,0x49, 0xf,0x47,0x4a, + 0xf,0x47,0x4b, 0xf,0x47,0x4c, 0xf,0x47,0x4d, 0xf,0x47,0x4e, + 0xf,0x47,0x4f, 0xf,0x47,0x50, 0xf,0x47,0x51, 0xf,0x47,0x52, + 0xf,0x47,0x54, 0x6,0x5b,0x74, 0x6,0x5b,0x78, 0x4,0x42,0x72, + 0x4,0x42,0x65, 0x6,0x5b,0x76, 0xf,0x47,0x53, 0x5,0x45,0x33, + 0x5,0x45,0x36, 0x5,0x45,0x35, 0x7,0x22,0x26, 0x5,0x45,0x31, + 0x6,0x5b,0x77, 0x5,0x4c,0x5b, 0x5,0x4c,0x59, 0x4,0x49,0x39, + 0x5,0x4c,0x56, 0x7,0x22,0x2f, 0x5,0x4c,0x57, 0x4,0x49,0x3f, + 0x4,0x49,0x3b, 0x7,0x22,0x2c, 0x4,0x49,0x3e, 0x7,0x22,0x25, + 0x6,0x5b,0x79, 0x7,0x22,0x24, 0xf,0x4e,0x3a, 0x7,0x37,0x51, + 0xf,0x47,0x45, 0x5,0x4c,0x54, 0x5,0x4c,0x5c, 0xf,0x4e,0x33, + 0xf,0x4e,0x34, 0xf,0x4e,0x35, 0xf,0x4e,0x36, 0xf,0x4e,0x37, + 0xf,0x4e,0x38, 0xf,0x4e,0x39, 0xf,0x4e,0x3b, 0xf,0x4e,0x3d, + 0xf,0x4e,0x3e, 0xf,0x4e,0x3f, 0xf,0x4e,0x40, 0xf,0x4e,0x41, + 0xf,0x4e,0x42, 0xf,0x4e,0x44, 0x6,0x5b,0x7a, 0x7,0x22,0x27, + 0x7,0x22,0x2e, 0x7,0x22,0x2d, 0x7,0x22,0x28, 0x7,0x22,0x23, + 0xf,0x4e,0x45, 0xf,0x4e,0x43, 0xf,0x4e,0x3c, 0x5,0x4c,0x5a, + 0x5,0x4c,0x55, 0x4,0x49,0x3d, 0x7,0x22,0x2a, 0x5,0x4c,0x58, + 0x7,0x22,0x2b, 0xf,0x54,0x25, 0x5,0x54,0x28, 0x5,0x54,0x23, + 0x7,0x2d,0x25, 0x7,0x2c,0x7e, 0x5,0x54,0x29, 0x5,0x54,0x26, + 0x7,0x2d,0x21, 0x4,0x4f,0x7e, 0x7,0x2d,0x28, 0x5,0x54,0x22, + 0x7,0x2d,0x2b, 0x5,0x53,0x7d, 0x7,0x2d,0x2a, 0x7,0x2d,0x2c, + 0xf,0x53,0x7b, 0xf,0x53,0x7c, 0xf,0x53,0x7d, 0xf,0x53,0x7e, + 0xf,0x54,0x22, 0xf,0x54,0x23, 0xf,0x54,0x24, 0xf,0x54,0x26, + 0xf,0x54,0x27, 0xf,0x54,0x2b, 0xf,0x54,0x2c, 0x5,0x53,0x7e, + 0x7,0x2d,0x26, 0x7,0x2d,0x27, 0x7,0x2d,0x23, 0x7,0x2d,0x22, + 0x7,0x2d,0x24, 0xf,0x54,0x21, 0xf,0x54,0x28, 0x5,0x54,0x27, + 0x5,0x54,0x21, 0x5,0x54,0x25, 0x7,0x2d,0x29, 0x7,0x37,0x4b, + 0x7,0x37,0x54, 0x7,0x37,0x4f, 0x4,0x4f,0x7d, 0x7,0x37,0x4d, + 0x4,0x56,0x23, 0x7,0x37,0x53, 0x7,0x37,0x4a, 0x5,0x5b,0x36, + 0x5,0x5b,0x34, 0x7,0x37,0x4c, 0x7,0x37,0x4e, 0x7,0x37,0x50, + 0x5,0x5b,0x35, 0x4,0x56,0x25, 0xf,0x59,0x6c, 0xf,0x59,0x6d, + 0xf,0x59,0x6e, 0xf,0x59,0x6f, 0xf,0x59,0x70, 0xf,0x59,0x71, + 0x7,0x37,0x52, 0x7,0x37,0x55, 0x7,0x37,0x49, 0x5,0x61,0x4b, + 0x4,0x5a,0x7c, 0x7,0x3f,0x3f, 0x5,0x61,0x4c, 0x5,0x61,0x4d, + 0x7,0x3f,0x3e, 0x7,0x3f,0x40, 0xf,0x5e,0x50, 0xf,0x5e,0x51, + 0xf,0x5e,0x52, 0xf,0x5e,0x54, 0x7,0x3f,0x3d, 0x7,0x3f,0x41, + 0xf,0x5e,0x53, 0x7,0x3f,0x3c, 0x5,0x67,0x5f, 0x4,0x5f,0x53, + 0x7,0x46,0x4d, 0x7,0x46,0x52, 0x7,0x46,0x50, 0xf,0x5e,0x55, + 0xf,0x62,0x2a, 0xf,0x62,0x2b, 0x7,0x46,0x4e, 0x5,0x67,0x61, + 0x5,0x67,0x60, 0xf,0x5f,0x73, 0x7,0x4d,0x51, 0x5,0x6b,0x79, + 0xf,0x65,0x26, 0x5,0x6b,0x7a, 0x5,0x6b,0x7b, 0x7,0x53,0x2a, + 0x5,0x6f,0x76, 0x7,0x53,0x2b, 0x5,0x6f,0x75, 0xf,0x67,0x4d, + 0xf,0x67,0x4e, 0x7,0x57,0x62, 0x5,0x73,0x36, 0x7,0x57,0x61, + 0x7,0x57,0x63, 0x7,0x57,0x5f, 0xf,0x69,0x3f, 0x7,0x57,0x60, + 0x7,0x57,0x64, 0xf,0x69,0x40, 0x5,0x75,0x69, 0x7,0x5b,0x4c, + 0x7,0x5e,0x5a, 0x7,0x5e,0x5b, 0xf,0x6b,0x45, 0x7,0x5e,0x59, + 0x7,0x5e,0x5c, 0xf,0x6c,0x24, 0x5,0x79,0x24, 0xf,0x6c,0x4a, + 0x7,0x63,0x4d, 0x5,0x7a,0x65, 0x4,0x21,0x33, 0x6,0x22,0x68, + 0x5,0x21,0x63, 0x6,0x22,0x69, 0xf,0x21,0x58, 0xf,0x21,0x57, + 0x6,0x24,0x45, 0x6,0x24,0x44, 0x6,0x26,0x76, 0x6,0x26,0x77, + 0x5,0x23,0x6a, 0x4,0x23,0x6c, 0xf,0x23,0x70, 0x5,0x23,0x69, + 0x4,0x28,0x6f, 0x6,0x30,0x24, 0x6,0x2a,0x63, 0x6,0x2a,0x62, + 0xf,0x26,0x4a, 0xf,0x26,0x4b, 0xf,0x26,0x4c, 0xf,0x26,0x4d, + 0xf,0x26,0x4f, 0x6,0x2a,0x64, 0xf,0x26,0x4e, 0x6,0x30,0x23, + 0x6,0x30,0x21, 0x6,0x30,0x26, 0x6,0x30,0x25, 0xf,0x2a,0x35, + 0xf,0x2a,0x36, 0xf,0x2a,0x37, 0x6,0x30,0x22, 0x6,0x36,0x59, + 0x5,0x2c,0x79, 0x6,0x36,0x58, 0xf,0x2e,0x7a, 0xf,0x2e,0x7b, + 0x5,0x2c,0x7a, 0xf,0x33,0x66, 0xf,0x34,0x24, 0xf,0x34,0x25, + 0xf,0x34,0x26, 0xf,0x34,0x27, 0x5,0x37,0x5c, 0x6,0x47,0x69, + 0x5,0x37,0x5b, 0x6,0x47,0x6a, 0xf,0x3a,0x47, 0x6,0x47,0x68, + 0xf,0x3a,0x46, 0x4,0x3c,0x66, 0x4,0x3c,0x68, 0x6,0x51,0x6d, + 0x5,0x3e,0x62, 0xf,0x41,0x25, 0xf,0x41,0x26, 0x6,0x51,0x6b, + 0x6,0x51,0x6c, 0x5,0x3e,0x61, 0x4,0x3c,0x69, 0x6,0x5b,0x7d, + 0xf,0x47,0x55, 0xf,0x47,0x56, 0x5,0x45,0x38, 0x4,0x49,0x41, + 0x4,0x49,0x42, 0xf,0x4e,0x46, 0x5,0x4c,0x5d, 0x7,0x2d,0x2f, + 0x7,0x2d,0x2e, 0x7,0x2d,0x31, 0x7,0x2d,0x32, 0x5,0x54,0x2a, + 0x7,0x2d,0x30, 0xf,0x54,0x2d, 0xf,0x54,0x2e, 0x7,0x37,0x56, + 0x7,0x4d,0x52, 0xf,0x62,0x2c, 0xf,0x62,0x2d, 0x5,0x6b,0x7c, + 0xf,0x6c,0x60, 0x6,0x21,0x69, 0x5,0x21,0x64, 0x6,0x24,0x46, + 0x6,0x24,0x49, 0x6,0x24,0x4a, 0x4,0x22,0x5a, 0xf,0x22,0x3d, + 0xf,0x22,0x3e, 0xf,0x22,0x3f, 0xf,0x22,0x40, 0xf,0x22,0x41, + 0x6,0x24,0x47, 0x6,0x26,0x7e, 0x6,0x26,0x7d, 0x4,0x23,0x6e, + 0x6,0x26,0x7b, 0x6,0x26,0x7c, 0xf,0x23,0x72, 0x5,0x25,0x65, + 0x5,0x25,0x64, 0x6,0x2a,0x66, 0x5,0x25,0x66, 0x6,0x2a,0x67, + 0x6,0x2a,0x68, 0xf,0x26,0x51, 0xf,0x26,0x52, 0xf,0x26,0x54, + 0xf,0x26,0x55, 0x6,0x2a,0x65, 0xf,0x26,0x53, 0x5,0x28,0x6c, + 0x6,0x30,0x28, 0x6,0x30,0x2a, 0x5,0x28,0x6d, 0x4,0x28,0x71, + 0x4,0x28,0x72, 0x4,0x28,0x73, 0x6,0x30,0x2b, 0x6,0x30,0x27, + 0x6,0x30,0x29, 0xf,0x2a,0x38, 0xf,0x2a,0x3a, 0xf,0x2a,0x3b, + 0xf,0x2a,0x3c, 0x6,0x30,0x2c, 0x6,0x30,0x2d, 0x4,0x2c,0x4a, + 0x6,0x36,0x61, 0x4,0x2c,0x45, 0x4,0x2c,0x44, 0x4,0x2c,0x43, + 0x4,0x2c,0x47, 0x6,0x36,0x64, 0x6,0x36,0x65, 0x6,0x36,0x5f, + 0x6,0x36,0x5e, 0x5,0x2c,0x7d, 0x5,0x2d,0x22, 0x6,0x36,0x5b, + 0x6,0x36,0x62, 0xf,0x2e,0x7c, 0xf,0x2e,0x7d, 0x6,0x36,0x60, + 0x6,0x36,0x63, 0x6,0x36,0x5a, 0x6,0x36,0x5c, 0x5,0x2d,0x21, + 0x5,0x2c,0x7e, 0x4,0x31,0x2d, 0x5,0x31,0x6f, 0x6,0x3e,0x57, + 0x6,0x3e,0x59, 0x6,0x3e,0x58, 0x6,0x3e,0x56, 0x6,0x3e,0x5b, + 0x5,0x31,0x70, 0xf,0x34,0x28, 0xf,0x34,0x29, 0xf,0x34,0x2a, + 0xf,0x34,0x2b, 0xf,0x34,0x2c, 0xf,0x34,0x2d, 0xf,0x34,0x2e, + 0xf,0x34,0x2f, 0x4,0x31,0x2f, 0x6,0x3e,0x5c, 0x5,0x31,0x6e, + 0x6,0x3e,0x55, 0x5,0x37,0x5e, 0x4,0x37,0x26, 0x5,0x37,0x61, + 0x6,0x47,0x70, 0x6,0x47,0x6b, 0x4,0x37,0x23, 0x5,0x37,0x5d, + 0x5,0x37,0x60, 0x6,0x47,0x6e, 0x4,0x37,0x25, 0x5,0x37,0x5f, + 0x6,0x47,0x6f, 0x6,0x47,0x6c, 0xf,0x3a,0x48, 0xf,0x3a,0x49, + 0xf,0x3a,0x4a, 0xf,0x3a,0x4b, 0xf,0x3a,0x4c, 0xf,0x3a,0x4d, + 0xf,0x3a,0x4e, 0xf,0x3a,0x4f, 0x6,0x47,0x6d, 0x5,0x37,0x62, + 0xf,0x3d,0x6c, 0x6,0x51,0x74, 0x6,0x51,0x70, 0x4,0x3c,0x6b, + 0x4,0x3c,0x70, 0x5,0x3e,0x63, 0x6,0x51,0x77, 0x5,0x3e,0x64, + 0x6,0x51,0x72, 0x6,0x51,0x71, 0x6,0x51,0x76, 0x4,0x3c,0x6d, + 0x6,0x51,0x73, 0x6,0x51,0x6f, 0x6,0x51,0x75, 0xf,0x41,0x27, + 0xf,0x41,0x28, 0xf,0x41,0x29, 0xf,0x41,0x2a, 0xf,0x41,0x2c, + 0xf,0x41,0x2d, 0xf,0x41,0x2e, 0x6,0x51,0x6e, 0x6,0x5b,0x7e, + 0x6,0x5c,0x27, 0x5,0x45,0x3c, 0x5,0x45,0x3a, 0x6,0x5c,0x24, + 0x6,0x5c,0x2c, 0x4,0x42,0x76, 0x6,0x5c,0x2e, 0x6,0x5c,0x2b, + 0x6,0x5c,0x26, 0x5,0x45,0x39, 0x7,0x22,0x33, 0xf,0x47,0x57, + 0xf,0x47,0x58, 0xf,0x47,0x59, 0xf,0x47,0x5a, 0x6,0x5c,0x28, + 0x6,0x5c,0x25, 0x6,0x5c,0x29, 0x6,0x5c,0x2d, 0x6,0x5c,0x21, + 0x6,0x5c,0x23, 0x5,0x45,0x3b, 0x6,0x5c,0x2a, 0xf,0x47,0x44, + 0x6,0x62,0x67, 0x7,0x22,0x30, 0x5,0x4c,0x5e, 0x4,0x49,0x47, + 0x7,0x22,0x37, 0x4,0x49,0x48, 0x7,0x22,0x35, 0x7,0x22,0x32, + 0xf,0x4e,0x47, 0xf,0x4e,0x48, 0xf,0x4e,0x49, 0xf,0x4e,0x4a, + 0xf,0x4e,0x4b, 0xf,0x4e,0x4c, 0xf,0x4e,0x4e, 0xf,0x4e,0x4f, + 0x7,0x22,0x38, 0x7,0x22,0x36, 0xf,0x4e,0x4d, 0x5,0x4c,0x61, + 0x5,0x4c,0x5f, 0x7,0x22,0x31, 0x5,0x4c,0x60, 0x7,0x2d,0x35, + 0x7,0x2d,0x37, 0x5,0x54,0x2c, 0x4,0x50,0x22, 0x5,0x54,0x2d, + 0x5,0x54,0x2b, 0x7,0x2d,0x36, 0x7,0x2d,0x33, 0x7,0x2d,0x34, + 0xf,0x54,0x2f, 0xf,0x54,0x30, 0xf,0x54,0x31, 0xf,0x54,0x33, + 0xf,0x54,0x34, 0xf,0x54,0x35, 0xf,0x54,0x36, 0xf,0x54,0x37, + 0x7,0x37,0x59, 0x7,0x37,0x57, 0x5,0x5b,0x38, 0xf,0x59,0x72, + 0xf,0x59,0x73, 0xf,0x59,0x74, 0xf,0x59,0x75, 0x7,0x37,0x58, + 0x7,0x37,0x5a, 0x7,0x22,0x34, 0x5,0x5b,0x37, 0x7,0x46,0x58, + 0x5,0x61,0x4e, 0xf,0x59,0x76, 0xf,0x5e,0x56, 0xf,0x5e,0x57, + 0x7,0x3f,0x42, 0xf,0x62,0x2e, 0x4,0x5f,0x57, 0x7,0x46,0x53, + 0x7,0x46,0x55, 0x4,0x5f,0x56, 0x7,0x46,0x57, 0x7,0x46,0x56, + 0xf,0x62,0x2f, 0x7,0x46,0x54, 0x4,0x63,0x36, 0x7,0x4d,0x53, + 0x7,0x53,0x2c, 0x4,0x66,0x38, 0x7,0x53,0x2d, 0xf,0x67,0x4f, + 0xf,0x67,0x50, 0x7,0x53,0x2e, 0x5,0x73,0x38, 0x4,0x68,0x66, + 0x7,0x57,0x65, 0x5,0x73,0x37, 0x7,0x57,0x66, 0x4,0x6a,0x45, + 0x4,0x6b,0x67, 0xf,0x6b,0x46, 0x7,0x60,0x6c, 0x7,0x64,0x45, + 0x5,0x79,0x25, 0xf,0x6c,0x25, 0x4,0x6d,0x54, 0x5,0x7a,0x27, + 0x4,0x6d,0x71, 0x7,0x63,0x4e, 0x7,0x65,0x34, 0x6,0x21,0x6a, + 0x6,0x2a,0x6a, 0x6,0x2a,0x69, 0xf,0x26,0x56, 0xf,0x26,0x57, + 0x5,0x28,0x6f, 0x6,0x30,0x2e, 0xf,0x2a,0x3d, 0x6,0x30,0x31, + 0x6,0x30,0x2f, 0x4,0x31,0x31, 0x6,0x43,0x67, 0x6,0x3e,0x5e, + 0x6,0x3e,0x5d, 0x4,0x37,0x27, 0x6,0x3e,0x5f, 0x6,0x51,0x7a, + 0x6,0x51,0x78, 0x6,0x51,0x79, 0x6,0x5c,0x30, 0x4,0x44,0x26, + 0xf,0x47,0x5b, 0x6,0x5c,0x31, 0x5,0x45,0x3d, 0xf,0x4e,0x51, + 0x7,0x22,0x3a, 0x7,0x22,0x39, 0x7,0x2d,0x39, 0x5,0x53,0x52, + 0x7,0x2d,0x38, 0x7,0x37,0x5b, 0x7,0x37,0x5c, 0x5,0x61,0x4f, + 0x7,0x46,0x59, 0x7,0x4d,0x54, 0x7,0x53,0x2f, 0x6,0x21,0x6b, + 0xf,0x21,0x39, 0x6,0x24,0x4c, 0x5,0x22,0x4c, 0x6,0x27,0x24, + 0x4,0x23,0x72, 0x6,0x27,0x23, 0x6,0x27,0x22, 0xf,0x23,0x73, + 0x5,0x25,0x67, 0xf,0x26,0x58, 0x6,0x2a,0x6b, 0x6,0x30,0x32, + 0x6,0x30,0x30, 0x6,0x30,0x33, 0x5,0x28,0x70, 0x4,0x2c,0x4b, + 0xf,0x2f,0x21, 0x6,0x36,0x69, 0x6,0x3e,0x61, 0x5,0x31,0x71, + 0x5,0x37,0x63, 0x6,0x3e,0x63, 0x6,0x3e,0x60, 0x6,0x3e,0x62, + 0xf,0x34,0x30, 0x6,0x47,0x71, 0xf,0x3a,0x50, 0x6,0x47,0x73, + 0x6,0x47,0x72, 0x5,0x3e,0x65, 0xf,0x41,0x2f, 0x5,0x45,0x3e, + 0x6,0x5c,0x33, 0x6,0x5c,0x32, 0x5,0x4c,0x62, 0x7,0x22,0x3b, + 0x5,0x54,0x2f, 0x7,0x2d,0x3a, 0xf,0x59,0x77, 0x5,0x61,0x50, + 0x5,0x6f,0x77, 0x4,0x21,0x4a, 0xf,0x21,0x3a, 0x5,0x21,0x65, + 0xf,0x21,0x4d, 0xf,0x21,0x5a, 0x6,0x22,0x6b, 0x6,0x22,0x6a, + 0x5,0x22,0x4d, 0xf,0x22,0x43, 0x5,0x23,0x6c, 0x4,0x23,0x73, + 0x5,0x25,0x68, 0x6,0x27,0x25, 0x5,0x23,0x6b, 0x5,0x23,0x6e, + 0x5,0x23,0x6d, 0x6,0x30,0x34, 0x5,0x25,0x69, 0x6,0x2a,0x6c, + 0x5,0x25,0x6b, 0xf,0x26,0x59, 0x6,0x30,0x35, 0x5,0x25,0x6a, + 0x5,0x28,0x71, 0x6,0x30,0x37, 0x6,0x30,0x38, 0x5,0x28,0x72, + 0x6,0x30,0x39, 0x5,0x2d,0x23, 0x6,0x36,0x6c, 0x6,0x36,0x6a, + 0x5,0x2d,0x24, 0x6,0x36,0x6b, 0x6,0x36,0x6d, 0xf,0x2f,0x22, + 0x6,0x3e,0x66, 0x5,0x31,0x72, 0x4,0x31,0x34, 0x5,0x31,0x74, + 0x6,0x47,0x76, 0x6,0x47,0x74, 0x6,0x47,0x75, 0x4,0x37,0x2a, + 0x6,0x47,0x77, 0xf,0x3a,0x51, 0x6,0x51,0x7b, 0x6,0x51,0x7d, + 0x6,0x51,0x7c, 0x5,0x48,0x26, 0x4,0x42,0x7a, 0x6,0x5c,0x34, + 0x5,0x45,0x40, 0x5,0x45,0x3f, 0x6,0x5c,0x35, 0x5,0x45,0x41, + 0x7,0x2d,0x3d, 0x7,0x22,0x3e, 0x7,0x22,0x3d, 0x7,0x22,0x3c, + 0x7,0x2d,0x3b, 0x5,0x54,0x30, 0x7,0x2d,0x3c, 0x7,0x2d,0x3e, + 0xf,0x54,0x38, 0x7,0x37,0x5d, 0x4,0x66,0x39, 0x4,0x68,0x67, + 0x5,0x79,0x26, 0x6,0x21,0x3e, 0x4,0x21,0x75, 0x4,0x21,0x74, + 0x6,0x22,0x6c, 0x6,0x24,0x4d, 0x4,0x22,0x5e, 0x5,0x22,0x4e, + 0x6,0x24,0x4e, 0x6,0x24,0x50, 0x6,0x24,0x51, 0x6,0x24,0x4f, + 0xf,0x22,0x44, 0x6,0x27,0x29, 0xf,0x23,0x74, 0x6,0x27,0x27, + 0x6,0x27,0x26, 0x6,0x27,0x28, 0x5,0x23,0x6f, 0x4,0x26,0x2c, + 0x4,0x26,0x2b, 0x6,0x2a,0x6d, 0x6,0x2a,0x6e, 0x5,0x25,0x6c, + 0x6,0x2a,0x6f, 0xf,0x26,0x5b, 0x5,0x25,0x6d, 0x4,0x28,0x77, + 0x6,0x30,0x3a, 0x6,0x30,0x3f, 0x4,0x28,0x7a, 0x4,0x28,0x76, + 0x5,0x28,0x75, 0x6,0x30,0x3e, 0x6,0x30,0x3d, 0x6,0x30,0x3c, + 0x6,0x30,0x3b, 0xf,0x2a,0x40, 0xf,0x2a,0x41, 0xf,0x2a,0x42, + 0xf,0x2a,0x43, 0xf,0x2a,0x44, 0xf,0x2a,0x3f, 0x6,0x30,0x40, + 0x5,0x28,0x74, 0x6,0x36,0x72, 0x4,0x2c,0x50, 0x6,0x36,0x6f, + 0x4,0x2c,0x4f, 0x6,0x3e,0x67, 0x6,0x36,0x70, 0x6,0x36,0x6e, + 0xf,0x2f,0x23, 0xf,0x2f,0x24, 0xf,0x2f,0x26, 0xf,0x2f,0x27, + 0xf,0x2f,0x28, 0x5,0x2d,0x26, 0x5,0x2d,0x27, 0x6,0x36,0x71, + 0x6,0x36,0x73, 0x5,0x2d,0x25, 0x6,0x36,0x74, 0x6,0x3e,0x6d, + 0x6,0x3e,0x69, 0x5,0x31,0x78, 0x5,0x31,0x7a, 0x5,0x31,0x77, + 0x5,0x31,0x79, 0x5,0x31,0x76, 0x5,0x31,0x7b, 0x6,0x3e,0x70, + 0x6,0x3e,0x6a, 0xf,0x34,0x31, 0xf,0x34,0x32, 0xf,0x34,0x35, + 0xf,0x34,0x36, 0xf,0x34,0x37, 0xf,0x34,0x38, 0xf,0x34,0x39, + 0xf,0x34,0x3a, 0x6,0x3e,0x68, 0x6,0x3e,0x6c, 0x6,0x3e,0x6f, + 0x6,0x3e,0x6e, 0xf,0x34,0x33, 0x6,0x48,0x23, 0x6,0x48,0x24, + 0x6,0x48,0x22, 0x4,0x37,0x2c, 0x6,0x47,0x7e, 0x6,0x47,0x7a, + 0x5,0x37,0x64, 0x4,0x37,0x2d, 0x5,0x37,0x65, 0x6,0x47,0x79, + 0x6,0x47,0x78, 0x6,0x48,0x25, 0x6,0x48,0x21, 0x6,0x48,0x26, + 0x6,0x47,0x7c, 0xf,0x3a,0x52, 0xf,0x3a,0x53, 0xf,0x3a,0x54, + 0x6,0x47,0x7d, 0x4,0x37,0x2e, 0x6,0x52,0x23, 0x5,0x3e,0x69, + 0x5,0x3e,0x67, 0x6,0x52,0x26, 0x5,0x3e,0x68, 0x6,0x52,0x25, + 0x6,0x52,0x29, 0x6,0x52,0x21, 0x6,0x51,0x7e, 0x6,0x52,0x27, + 0x6,0x52,0x24, 0xf,0x41,0x30, 0xf,0x41,0x31, 0xf,0x41,0x32, + 0x6,0x52,0x22, 0x6,0x52,0x28, 0x5,0x3e,0x66, 0x4,0x42,0x7c, + 0x4,0x42,0x7e, 0x4,0x42,0x7b, 0x6,0x5c,0x38, 0x6,0x5c,0x36, + 0x6,0x5c,0x37, 0xf,0x47,0x5d, 0x6,0x5c,0x39, 0x5,0x45,0x42, + 0x7,0x22,0x40, 0x5,0x4c,0x66, 0xf,0x4e,0x52, 0xf,0x4e,0x53, + 0xf,0x4e,0x54, 0xf,0x4e,0x55, 0xf,0x4e,0x56, 0x5,0x4c,0x65, + 0x5,0x4c,0x64, 0x7,0x2d,0x40, 0x7,0x2d,0x3f, 0x7,0x22,0x3f, + 0xf,0x54,0x39, 0x7,0x30,0x2d, 0x7,0x37,0x5e, 0x7,0x3f,0x43, + 0x4,0x5f,0x58, 0x5,0x67,0x62, 0xf,0x65,0x27, 0xf,0x65,0x28, + 0x5,0x6b,0x7d, 0xf,0x67,0x51, 0x5,0x73,0x3a, 0x5,0x21,0x30, + 0x6,0x21,0x6c, 0x6,0x22,0x6d, 0x6,0x24,0x54, 0x6,0x24,0x53, + 0x6,0x24,0x52, 0x5,0x22,0x4f, 0x4,0x23,0x75, 0x6,0x27,0x2a, + 0x4,0x26,0x2d, 0x6,0x2a,0x71, 0x6,0x2a,0x70, 0x5,0x28,0x77, + 0x6,0x30,0x42, 0x6,0x30,0x43, 0x5,0x28,0x76, 0x6,0x30,0x44, + 0x6,0x36,0x77, 0x6,0x36,0x78, 0x6,0x36,0x76, 0x6,0x35,0x28, + 0x6,0x36,0x75, 0x6,0x3e,0x71, 0x6,0x3e,0x72, 0x6,0x48,0x28, + 0x5,0x37,0x67, 0x6,0x48,0x29, 0x6,0x48,0x27, 0xf,0x3a,0x55, + 0x6,0x52,0x2a, 0x6,0x5c,0x3a, 0x7,0x22,0x41, 0x7,0x2d,0x41, + 0x7,0x22,0x42, 0x7,0x22,0x43, 0x7,0x53,0x30, 0x7,0x5e,0x5d, + 0x5,0x21,0x45, 0x5,0x21,0x46, 0x6,0x22,0x70, 0x6,0x22,0x6e, + 0x6,0x22,0x72, 0x6,0x22,0x71, 0xf,0x21,0x5c, 0xf,0x21,0x5d, + 0xf,0x21,0x5e, 0x6,0x22,0x73, 0x5,0x21,0x66, 0x6,0x22,0x6f, + 0x6,0x24,0x57, 0x6,0x24,0x55, 0x6,0x24,0x59, 0x3,0x23,0x59, + 0xf,0x22,0x45, 0xf,0x22,0x46, 0x6,0x24,0x56, 0x5,0x22,0x53, + 0x6,0x24,0x5a, 0x6,0x24,0x58, 0x5,0x22,0x52, 0x6,0x27,0x2e, + 0x5,0x23,0x71, 0x5,0x23,0x78, 0x5,0x23,0x79, 0x6,0x27,0x30, + 0x5,0x23,0x76, 0x5,0x23,0x75, 0x5,0x23,0x77, 0x5,0x23,0x72, + 0x5,0x23,0x73, 0x6,0x27,0x31, 0x6,0x27,0x2c, 0x6,0x27,0x32, + 0xf,0x23,0x76, 0xf,0x23,0x77, 0xf,0x23,0x79, 0xf,0x23,0x7a, + 0xf,0x23,0x7b, 0xf,0x23,0x7e, 0xf,0x24,0x21, 0x6,0x27,0x2d, + 0x6,0x27,0x2f, 0x4,0x23,0x7d, 0xf,0x23,0x7d, 0x6,0x27,0x34, + 0x6,0x27,0x33, 0x4,0x23,0x7c, 0x6,0x27,0x2b, 0x5,0x23,0x7a, + 0x4,0x26,0x30, 0x5,0x25,0x75, 0x6,0x2a,0x75, 0x4,0x26,0x33, + 0x6,0x2a,0x72, 0x5,0x25,0x73, 0x5,0x25,0x74, 0x6,0x2a,0x7a, + 0x5,0x25,0x71, 0x6,0x2a,0x77, 0x6,0x2a,0x7c, 0x5,0x25,0x6f, + 0x6,0x2a,0x79, 0x5,0x25,0x72, 0x5,0x25,0x70, 0x6,0x2a,0x74, + 0x6,0x27,0x35, 0xf,0x26,0x5c, 0xf,0x26,0x5d, 0xf,0x26,0x5e, + 0xf,0x26,0x5f, 0xf,0x26,0x60, 0xf,0x26,0x61, 0xf,0x26,0x63, + 0xf,0x26,0x64, 0xf,0x26,0x65, 0xf,0x26,0x66, 0xf,0x26,0x67, + 0xf,0x26,0x68, 0x6,0x2a,0x78, 0x6,0x2d,0x2b, 0x6,0x2a,0x73, + 0x5,0x25,0x76, 0x6,0x30,0x50, 0x6,0x30,0x4a, 0x5,0x28,0x78, + 0x6,0x30,0x4b, 0x5,0x28,0x79, 0x4,0x28,0x7e, 0x5,0x28,0x7a, + 0x6,0x30,0x46, 0x6,0x30,0x49, 0x6,0x30,0x52, 0xf,0x2a,0x45, + 0xf,0x2a,0x47, 0xf,0x2a,0x48, 0xf,0x2a,0x4b, 0xf,0x2a,0x4c, + 0xf,0x2a,0x4d, 0xf,0x2a,0x4e, 0xf,0x2a,0x4f, 0xf,0x2a,0x50, + 0xf,0x2a,0x51, 0x6,0x30,0x4d, 0x6,0x30,0x45, 0x6,0x30,0x47, + 0x6,0x30,0x51, 0x6,0x30,0x4f, 0x6,0x30,0x4c, 0xf,0x2a,0x4a, + 0xf,0x2a,0x46, 0x6,0x30,0x48, 0x5,0x28,0x7b, 0x4,0x28,0x7c, + 0x5,0x2d,0x2c, 0x5,0x2d,0x29, 0x4,0x2c,0x52, 0x4,0x2c,0x59, + 0x5,0x2d,0x2a, 0x6,0x37,0x21, 0x4,0x2c,0x58, 0x5,0x2d,0x34, + 0x5,0x2d,0x30, 0x5,0x2d,0x2b, 0x6,0x36,0x7d, 0x5,0x2d,0x31, + 0x5,0x2d,0x2d, 0x5,0x2d,0x2f, 0x6,0x37,0x24, 0x6,0x36,0x7e, + 0x4,0x2c,0x62, 0x6,0x36,0x79, 0x4,0x2c,0x63, 0x4,0x2c,0x56, + 0x6,0x37,0x25, 0x6,0x37,0x22, 0x6,0x37,0x23, 0x6,0x36,0x7b, + 0xf,0x2f,0x29, 0xf,0x2f,0x2a, 0xf,0x2f,0x2b, 0xf,0x2f,0x2c, + 0xf,0x2f,0x2d, 0xf,0x2f,0x2e, 0xf,0x2f,0x2f, 0xf,0x2f,0x31, + 0xf,0x2f,0x33, 0x5,0x2d,0x28, 0xf,0x2f,0x30, 0xf,0x2f,0x32, + 0x5,0x2d,0x33, 0x4,0x2c,0x5d, 0x5,0x2d,0x35, 0x5,0x2d,0x36, + 0x5,0x2d,0x32, 0x6,0x3b,0x4e, 0x4,0x31,0x3a, 0x6,0x3f,0x2b, + 0x6,0x3f,0x24, 0x6,0x3f,0x26, 0x4,0x31,0x3c, 0x4,0x31,0x3e, + 0x5,0x31,0x7e, 0x6,0x3e,0x79, 0x6,0x3f,0x22, 0x6,0x3e,0x7b, + 0x5,0x32,0x28, 0x4,0x31,0x38, 0x6,0x3f,0x27, 0x6,0x3f,0x2c, + 0x6,0x3f,0x29, 0x6,0x3e,0x74, 0x6,0x3f,0x2a, 0x4,0x31,0x40, + 0x4,0x31,0x3b, 0x5,0x31,0x7c, 0x5,0x32,0x26, 0x6,0x3e,0x73, + 0x4,0x31,0x36, 0x5,0x31,0x7d, 0x5,0x32,0x24, 0x6,0x3f,0x28, + 0x6,0x3f,0x23, 0xf,0x34,0x3b, 0xf,0x34,0x3c, 0xf,0x34,0x3d, + 0xf,0x34,0x3e, 0xf,0x34,0x40, 0xf,0x34,0x41, 0xf,0x34,0x42, + 0xf,0x34,0x43, 0xf,0x34,0x44, 0xf,0x34,0x46, 0xf,0x34,0x47, + 0xf,0x34,0x48, 0x6,0x3e,0x77, 0x6,0x32,0x2a, 0x6,0x3e,0x7d, + 0x6,0x3e,0x7c, 0x6,0x3e,0x7e, 0x6,0x3f,0x21, 0x6,0x3f,0x25, + 0x4,0x31,0x3f, 0x5,0x32,0x29, 0x5,0x32,0x21, 0x5,0x32,0x27, + 0x5,0x32,0x23, 0x5,0x32,0x22, 0x5,0x32,0x25, 0x5,0x32,0x2a, + 0x5,0x37,0x69, 0x6,0x48,0x33, 0x5,0x37,0x6e, 0x6,0x48,0x2a, + 0x6,0x48,0x34, 0x5,0x37,0x6f, 0x5,0x37,0x6c, 0x5,0x37,0x6b, + 0x4,0x37,0x30, 0x5,0x37,0x70, 0x5,0x37,0x6a, 0x5,0x37,0x71, + 0x5,0x37,0x72, 0x5,0x37,0x74, 0x6,0x48,0x2e, 0x6,0x3e,0x7a, + 0x4,0x37,0x31, 0x6,0x48,0x2f, 0x5,0x37,0x6d, 0x4,0x37,0x33, + 0x5,0x37,0x68, 0x5,0x37,0x73, 0xf,0x3a,0x56, 0xf,0x3a,0x58, + 0xf,0x3a,0x59, 0xf,0x3a,0x5a, 0xf,0x3a,0x5b, 0x6,0x48,0x2d, + 0x5,0x37,0x75, 0x6,0x48,0x32, 0x6,0x48,0x2c, 0x6,0x48,0x31, + 0x6,0x48,0x30, 0xf,0x3a,0x5c, 0x5,0x3e,0x70, 0x6,0x52,0x2d, + 0x5,0x3e,0x6c, 0x4,0x3c,0x7a, 0x5,0x3e,0x71, 0x6,0x52,0x2e, + 0x6,0x5c,0x3b, 0x4,0x3c,0x7d, 0x6,0x52,0x35, 0x5,0x3e,0x6a, + 0x5,0x3e,0x73, 0x6,0x52,0x2b, 0x5,0x3e,0x6f, 0x6,0x52,0x2c, + 0x6,0x52,0x39, 0x6,0x52,0x30, 0x6,0x52,0x38, 0x5,0x3e,0x6e, + 0x6,0x52,0x36, 0x6,0x5c,0x40, 0xf,0x41,0x37, 0x5,0x3e,0x72, + 0xf,0x41,0x33, 0xf,0x41,0x34, 0xf,0x41,0x36, 0xf,0x41,0x38, + 0xf,0x41,0x39, 0x6,0x52,0x3a, 0x6,0x52,0x32, 0x6,0x52,0x37, + 0x5,0x3e,0x6b, 0xf,0x41,0x35, 0x6,0x52,0x2f, 0x5,0x45,0x43, + 0x5,0x45,0x4b, 0x5,0x45,0x49, 0x6,0x5c,0x41, 0x6,0x5c,0x3c, + 0x4,0x43,0x2b, 0x4,0x43,0x26, 0x4,0x43,0x25, 0x5,0x45,0x44, + 0x5,0x45,0x48, 0x5,0x45,0x47, 0x5,0x45,0x4a, 0x5,0x45,0x4e, + 0x6,0x5c,0x3e, 0x6,0x5c,0x47, 0x5,0x45,0x4d, 0x5,0x45,0x45, + 0x5,0x45,0x46, 0x6,0x5c,0x42, 0x4,0x43,0x29, 0x6,0x5c,0x46, + 0x4,0x43,0x27, 0x4,0x43,0x23, 0x5,0x45,0x4c, 0x6,0x5c,0x45, + 0x6,0x5c,0x43, 0x6,0x5c,0x3f, 0x4,0x43,0x28, 0xf,0x47,0x5e, + 0xf,0x47,0x5f, 0xf,0x47,0x60, 0xf,0x47,0x61, 0x6,0x52,0x31, + 0x4,0x49,0x4e, 0x7,0x22,0x49, 0x4,0x49,0x52, 0x7,0x22,0x45, + 0x5,0x4c,0x69, 0x7,0x22,0x50, 0x7,0x22,0x4a, 0x5,0x4c,0x6e, + 0x5,0x4c,0x67, 0x7,0x22,0x47, 0x7,0x22,0x51, 0x5,0x4c,0x6f, + 0x7,0x22,0x4f, 0x7,0x22,0x4c, 0x7,0x22,0x4d, 0x5,0x4c,0x70, + 0x5,0x4c,0x6a, 0x5,0x4c,0x6d, 0x7,0x2d,0x44, 0x7,0x22,0x46, + 0xf,0x4e,0x57, 0xf,0x4e,0x58, 0xf,0x4e,0x59, 0xf,0x4e,0x5b, + 0xf,0x4e,0x5c, 0x7,0x22,0x44, 0x7,0x22,0x4b, 0x7,0x22,0x4e, + 0x5,0x4c,0x6b, 0x7,0x22,0x48, 0x4,0x49,0x51, 0x5,0x54,0x33, + 0x4,0x50,0x23, 0x7,0x2d,0x4a, 0x4,0x50,0x24, 0x5,0x54,0x35, + 0x7,0x2d,0x42, 0x5,0x54,0x38, 0x5,0x54,0x34, 0x5,0x54,0x31, + 0x7,0x2d,0x47, 0x7,0x2d,0x43, 0x5,0x5b,0x39, 0x5,0x54,0x32, + 0xf,0x54,0x3a, 0xf,0x54,0x3b, 0xf,0x54,0x3c, 0x7,0x2d,0x45, + 0x7,0x2d,0x49, 0x7,0x2d,0x48, 0x7,0x2d,0x4b, 0x7,0x2d,0x46, + 0x7,0x2d,0x4d, 0x5,0x54,0x37, 0x4,0x56,0x29, 0x5,0x5b,0x3b, + 0x5,0x61,0x55, 0x7,0x37,0x60, 0x5,0x5b,0x3f, 0x7,0x37,0x66, + 0x5,0x5b,0x3a, 0x7,0x37,0x62, 0x7,0x37,0x64, 0x7,0x37,0x61, + 0x5,0x5b,0x3d, 0x7,0x37,0x5f, 0x7,0x37,0x65, 0xf,0x59,0x79, + 0xf,0x59,0x7a, 0xf,0x59,0x7b, 0x4,0x56,0x2a, 0x7,0x37,0x63, + 0x7,0x37,0x67, 0x7,0x39,0x27, 0x5,0x5b,0x40, 0x7,0x46,0x5a, + 0x5,0x61,0x54, 0x7,0x3f,0x47, 0x4,0x5a,0x7e, 0x5,0x61,0x51, + 0x5,0x61,0x52, 0x7,0x3f,0x49, 0xf,0x5e,0x59, 0x5,0x61,0x53, + 0x7,0x3f,0x46, 0xf,0x5e,0x58, 0x7,0x3f,0x45, 0x7,0x3f,0x48, + 0x5,0x61,0x56, 0x5,0x61,0x57, 0x7,0x46,0x5c, 0x4,0x5f,0x5b, + 0x7,0x46,0x5e, 0x5,0x67,0x65, 0x4,0x5f,0x59, 0x7,0x46,0x5d, + 0x7,0x46,0x5f, 0x7,0x46,0x60, 0xf,0x62,0x30, 0xf,0x62,0x31, + 0xf,0x62,0x32, 0x7,0x46,0x61, 0x7,0x46,0x62, 0x7,0x46,0x5b, + 0x4,0x63,0x38, 0x7,0x4d,0x55, 0x4,0x63,0x37, 0x5,0x6b,0x7e, + 0x7,0x4d,0x57, 0xf,0x65,0x29, 0x7,0x4d,0x56, 0x5,0x5b,0x3e, + 0x5,0x6f,0x78, 0x5,0x6f,0x7a, 0x5,0x6f,0x79, 0x7,0x53,0x32, + 0x7,0x53,0x31, 0x5,0x73,0x3b, 0x4,0x68,0x69, 0x4,0x68,0x6a, + 0x7,0x57,0x67, 0x7,0x57,0x69, 0x7,0x57,0x68, 0x7,0x57,0x6a, + 0x5,0x73,0x3c, 0x7,0x5e,0x5e, 0x4,0x6b,0x6a, 0x4,0x6b,0x69, + 0x7,0x5e,0x60, 0x5,0x77,0x58, 0x7,0x5e,0x5f, 0x5,0x79,0x27, + 0xf,0x6c,0x26, 0x5,0x7a,0x28, 0x5,0x7a,0x66, 0x5,0x7b,0x3c, + 0x7,0x63,0x4f, 0x5,0x7c,0x34, 0x6,0x21,0x6d, 0x4,0x21,0x25, + 0x4,0x22,0x62, 0x5,0x22,0x54, 0x6,0x24,0x5b, 0x6,0x24,0x5c, + 0x5,0x22,0x55, 0x6,0x23,0x7e, 0x4,0x23,0x7e, 0x5,0x23,0x7b, + 0x6,0x2a,0x7d, 0xf,0x26,0x6a, 0xf,0x26,0x69, 0x6,0x30,0x55, + 0x6,0x30,0x54, 0x6,0x30,0x56, 0x6,0x30,0x53, 0x6,0x37,0x26, + 0x5,0x32,0x2b, 0x4,0x31,0x41, 0x6,0x3f,0x2d, 0x5,0x37,0x76, + 0x6,0x5c,0x48, 0x7,0x22,0x52, 0x5,0x54,0x39, 0xf,0x4e,0x5d, + 0xf,0x54,0x3d, 0x7,0x37,0x68, 0x7,0x3f,0x4a, 0x7,0x46,0x63, + 0x5,0x67,0x66, 0x7,0x5e,0x61, 0x7,0x65,0x35, 0x6,0x21,0x6f, + 0x6,0x21,0x71, 0x6,0x21,0x70, 0xf,0x21,0x3b, 0x5,0x21,0x68, + 0x5,0x21,0x67, 0x5,0x23,0x7c, 0x6,0x27,0x37, 0xf,0x26,0x6b, + 0x6,0x30,0x57, 0x6,0x37,0x28, 0xf,0x2f,0x34, 0x6,0x3f,0x2e, + 0xf,0x3a,0x5e, 0x7,0x22,0x53, 0x7,0x46,0x64, 0x6,0x22,0x74, + 0x5,0x22,0x56, 0x6,0x2a,0x7e, 0x6,0x30,0x59, 0x6,0x30,0x58, + 0x4,0x2c,0x65, 0x6,0x3f,0x2f, 0x5,0x35,0x5f, 0x5,0x32,0x2d, + 0x6,0x3f,0x30, 0x5,0x32,0x2c, 0x6,0x48,0x36, 0xf,0x3a,0x5f, + 0xf,0x3a,0x60, 0xf,0x3a,0x61, 0x7,0x22,0x54, 0x7,0x3f,0x4b, + 0x4,0x21,0x77, 0x6,0x22,0x75, 0x6,0x22,0x76, 0x5,0x22,0x59, + 0x5,0x22,0x58, 0x4,0x22,0x64, 0x5,0x22,0x5b, 0x6,0x24,0x61, + 0x6,0x24,0x60, 0x6,0x24,0x5e, 0xf,0x22,0x48, 0xf,0x22,0x4a, + 0x5,0x22,0x57, 0x6,0x24,0x5f, 0x5,0x22,0x5a, 0x6,0x27,0x41, + 0x6,0x27,0x3b, 0x5,0x24,0x22, 0x6,0x27,0x38, 0x5,0x23,0x7e, + 0x5,0x23,0x7d, 0x5,0x24,0x23, 0x6,0x27,0x40, 0x5,0x24,0x24, + 0x6,0x27,0x3c, 0x6,0x27,0x3f, 0x5,0x24,0x21, 0xf,0x24,0x24, + 0x6,0x27,0x39, 0x6,0x27,0x3a, 0x6,0x27,0x3d, 0x5,0x24,0x25, + 0x6,0x27,0x3e, 0x5,0x25,0x7b, 0x4,0x26,0x35, 0x5,0x25,0x79, + 0x5,0x25,0x7d, 0x5,0x25,0x7a, 0x5,0x25,0x7c, 0x5,0x26,0x21, + 0x6,0x2b,0x23, 0x5,0x25,0x7e, 0x5,0x26,0x22, 0x6,0x2b,0x22, + 0xf,0x26,0x6c, 0x5,0x26,0x23, 0x6,0x2b,0x21, 0x5,0x25,0x77, + 0x5,0x25,0x78, 0x5,0x28,0x7e, 0x6,0x30,0x62, 0x5,0x28,0x7d, + 0x5,0x29,0x22, 0x5,0x28,0x7c, 0x5,0x29,0x23, 0x6,0x30,0x5f, + 0x5,0x29,0x25, 0x5,0x29,0x24, 0x6,0x30,0x5b, 0x5,0x29,0x21, + 0x6,0x30,0x5a, 0x6,0x30,0x65, 0x6,0x30,0x67, 0xf,0x2a,0x53, + 0xf,0x2a,0x54, 0xf,0x2a,0x55, 0x4,0x29,0x26, 0x6,0x30,0x61, + 0x6,0x30,0x60, 0x6,0x30,0x5c, 0x6,0x30,0x5d, 0x6,0x30,0x66, + 0x6,0x30,0x64, 0x6,0x30,0x5e, 0x5,0x2d,0x38, 0x6,0x37,0x32, + 0x5,0x2d,0x37, 0x6,0x37,0x2e, 0x5,0x2d,0x39, 0x5,0x32,0x2e, + 0x6,0x37,0x2a, 0x4,0x2c,0x69, 0x4,0x2c,0x6a, 0x6,0x37,0x2f, + 0x5,0x2d,0x3a, 0x6,0x37,0x2d, 0x6,0x37,0x31, 0x6,0x37,0x30, + 0x4,0x2c,0x67, 0x6,0x37,0x33, 0x6,0x37,0x34, 0xf,0x2f,0x36, + 0xf,0x2f,0x35, 0x6,0x37,0x29, 0x6,0x37,0x2b, 0x6,0x3f,0x35, + 0x5,0x32,0x35, 0x4,0x31,0x46, 0x4,0x31,0x43, 0x4,0x31,0x44, + 0x5,0x32,0x33, 0x5,0x32,0x2f, 0x6,0x3f,0x3a, 0x5,0x32,0x30, + 0x5,0x32,0x34, 0x6,0x3f,0x3c, 0x5,0x32,0x31, 0x5,0x32,0x36, + 0x6,0x3f,0x36, 0x6,0x3f,0x3b, 0x6,0x3f,0x32, 0x5,0x32,0x32, + 0x6,0x3f,0x34, 0xf,0x34,0x49, 0xf,0x34,0x4a, 0xf,0x34,0x4b, + 0xf,0x34,0x4c, 0x6,0x3f,0x39, 0x6,0x3f,0x31, 0x6,0x3f,0x3d, + 0x6,0x3f,0x37, 0x6,0x3f,0x33, 0x6,0x48,0x39, 0x4,0x37,0x3e, + 0x6,0x48,0x3e, 0x5,0x37,0x79, 0x5,0x37,0x7a, 0x4,0x37,0x38, + 0x5,0x37,0x78, 0x6,0x48,0x3a, 0x4,0x37,0x37, 0x5,0x38,0x21, + 0x5,0x38,0x22, 0x6,0x3f,0x38, 0x6,0x48,0x40, 0x6,0x48,0x3d, + 0x6,0x48,0x3b, 0x5,0x37,0x7d, 0x6,0x48,0x38, 0xf,0x3a,0x62, + 0xf,0x3a,0x63, 0x6,0x48,0x3f, 0x5,0x37,0x7b, 0x5,0x37,0x77, + 0x6,0x48,0x41, 0x5,0x37,0x7e, 0xf,0x40,0x2b, 0x5,0x3e,0x78, + 0x4,0x3d,0x22, 0x5,0x45,0x52, 0x4,0x3d,0x25, 0x5,0x3e,0x75, + 0x5,0x3e,0x74, 0x4,0x3d,0x24, 0x5,0x3e,0x77, 0x5,0x3e,0x7a, + 0x6,0x52,0x3e, 0x6,0x52,0x3b, 0x6,0x52,0x3d, 0x6,0x5c,0x4b, + 0x5,0x3e,0x7b, 0x6,0x52,0x3c, 0x5,0x3e,0x76, 0x5,0x3e,0x79, + 0x6,0x5c,0x4c, 0x6,0x5c,0x4d, 0x5,0x45,0x58, 0x4,0x43,0x34, + 0x5,0x45,0x4f, 0x5,0x45,0x55, 0x6,0x5c,0x4a, 0x5,0x45,0x54, + 0x5,0x45,0x57, 0xf,0x47,0x62, 0x5,0x45,0x59, 0x5,0x45,0x50, + 0x5,0x45,0x56, 0x5,0x45,0x51, 0x7,0x22,0x57, 0x7,0x22,0x59, + 0x5,0x4c,0x74, 0x5,0x4c,0x73, 0x5,0x4c,0x75, 0x4,0x49,0x57, + 0x5,0x4c,0x76, 0x5,0x4c,0x78, 0x4,0x49,0x56, 0x7,0x22,0x56, + 0x7,0x22,0x55, 0x7,0x22,0x58, 0x5,0x4c,0x77, 0x5,0x4c,0x79, + 0x5,0x4c,0x72, 0x7,0x2d,0x50, 0x5,0x54,0x3e, 0x7,0x2d,0x52, + 0x7,0x2d,0x58, 0x5,0x54,0x3d, 0x4,0x50,0x28, 0x7,0x2d,0x57, + 0x7,0x2d,0x56, 0x5,0x54,0x3b, 0x7,0x2d,0x51, 0x5,0x54,0x3c, + 0x7,0x2d,0x54, 0x5,0x54,0x3f, 0x7,0x2d,0x4f, 0x4,0x50,0x2a, + 0x5,0x5b,0x41, 0x5,0x5b,0x42, 0x4,0x56,0x2c, 0x7,0x37,0x6b, + 0xf,0x59,0x7c, 0x7,0x37,0x69, 0x7,0x37,0x6a, 0x5,0x61,0x5a, + 0x5,0x61,0x59, 0x5,0x61,0x58, 0x7,0x46,0x66, 0x4,0x5f,0x5d, + 0x5,0x67,0x67, 0x4,0x5f,0x5c, 0x7,0x46,0x65, 0x7,0x46,0x67, + 0x5,0x67,0x68, 0xf,0x62,0x33, 0x7,0x4d,0x58, 0x5,0x6c,0x21, + 0x7,0x53,0x33, 0x7,0x57,0x6c, 0x5,0x6f,0x7b, 0x5,0x73,0x3d, + 0x7,0x57,0x6b, 0x7,0x5e,0x62, 0x7,0x5e,0x63, 0x5,0x77,0x59, + 0x7,0x63,0x50, 0x7,0x63,0x75, 0x4,0x21,0x78, 0x6,0x27,0x42, + 0x5,0x24,0x26, 0x4,0x24,0x26, 0x6,0x2b,0x24, 0xf,0x26,0x6d, + 0xf,0x26,0x6e, 0x6,0x30,0x69, 0x6,0x30,0x68, 0xf,0x2a,0x56, + 0x6,0x37,0x35, 0x5,0x32,0x37, 0x6,0x48,0x42, 0x5,0x38,0x23, + 0x6,0x52,0x3f, 0x5,0x45,0x5a, 0xf,0x47,0x64, 0x7,0x4d,0x59, + 0xf,0x6a,0x4e, 0x6,0x21,0x72, 0x6,0x21,0x73, 0x6,0x22,0x78, + 0x5,0x21,0x69, 0x6,0x22,0x77, 0xf,0x21,0x62, 0x4,0x22,0x67, + 0x4,0x24,0x27, 0x5,0x24,0x27, 0xf,0x24,0x26, 0x6,0x29,0x5e, + 0x6,0x2b,0x25, 0x5,0x26,0x24, 0x5,0x26,0x25, 0x6,0x30,0x6a, + 0x6,0x30,0x41, 0x4,0x2f,0x27, 0x6,0x37,0x36, 0x4,0x31,0x4a, + 0x6,0x48,0x43, 0x5,0x3e,0x7c, 0x5,0x45,0x5b, 0x7,0x22,0x5b, + 0xf,0x47,0x65, 0x6,0x5c,0x4e, 0xf,0x4e,0x5f, 0x7,0x22,0x5c, + 0x7,0x22,0x5d, 0x4,0x56,0x26, 0x7,0x57,0x6d, 0x4,0x22,0x68, + 0x5,0x22,0x5e, 0x6,0x24,0x64, 0x5,0x22,0x5d, 0x6,0x24,0x63, + 0x6,0x24,0x62, 0x6,0x24,0x66, 0x4,0x22,0x69, 0x6,0x24,0x65, + 0x6,0x27,0x45, 0x5,0x24,0x2a, 0x5,0x24,0x2c, 0x5,0x24,0x2b, + 0x5,0x24,0x28, 0x5,0x24,0x29, 0x6,0x27,0x44, 0x6,0x27,0x48, + 0x6,0x2b,0x28, 0x6,0x27,0x43, 0x6,0x27,0x46, 0x5,0x24,0x2d, + 0x5,0x26,0x2c, 0x5,0x26,0x28, 0x5,0x26,0x27, 0x5,0x26,0x2b, + 0x5,0x26,0x2a, 0x4,0x26,0x39, 0x6,0x2b,0x26, 0x6,0x2b,0x29, + 0x6,0x2b,0x27, 0x4,0x26,0x3e, 0x6,0x2b,0x2a, 0xf,0x26,0x70, + 0xf,0x26,0x71, 0xf,0x26,0x72, 0xf,0x26,0x73, 0xf,0x26,0x74, + 0x5,0x26,0x29, 0x5,0x26,0x2d, 0x6,0x2b,0x2b, 0x5,0x29,0x28, + 0x5,0x29,0x2a, 0x4,0x29,0x27, 0x6,0x30,0x6c, 0x5,0x29,0x29, + 0x6,0x30,0x6d, 0xf,0x2a,0x57, 0xf,0x2a,0x59, 0xf,0x2a,0x58, + 0xf,0x2a,0x5a, 0xf,0x2a,0x5b, 0xf,0x2a,0x5c, 0x6,0x30,0x6b, + 0x5,0x2d,0x3d, 0x5,0x2d,0x40, 0x5,0x2d,0x3e, 0x5,0x2d,0x41, + 0x5,0x2d,0x3b, 0x6,0x37,0x3a, 0x6,0x37,0x3b, 0x4,0x2c,0x6e, + 0x5,0x2d,0x42, 0x5,0x2d,0x3f, 0x6,0x37,0x3c, 0x5,0x2d,0x3c, + 0x6,0x37,0x39, 0xf,0x2f,0x37, 0x6,0x37,0x37, 0x6,0x37,0x38, + 0x5,0x2c,0x7b, 0x5,0x32,0x44, 0x5,0x32,0x3b, 0x5,0x32,0x39, + 0x4,0x31,0x4d, 0x6,0x3f,0x43, 0x5,0x32,0x42, 0x6,0x3f,0x48, + 0x6,0x3f,0x3e, 0x5,0x32,0x3d, 0x5,0x32,0x3c, 0x5,0x32,0x3f, + 0x5,0x32,0x3e, 0x6,0x3f,0x3f, 0x6,0x3f,0x40, 0x5,0x32,0x41, + 0x5,0x32,0x38, 0x4,0x31,0x50, 0x6,0x3f,0x44, 0x5,0x32,0x43, + 0x5,0x38,0x28, 0x6,0x3f,0x41, 0xf,0x34,0x4d, 0xf,0x34,0x4e, + 0xf,0x34,0x4f, 0xf,0x34,0x50, 0xf,0x34,0x51, 0xf,0x34,0x52, + 0xf,0x34,0x53, 0x6,0x3f,0x47, 0x6,0x46,0x3d, 0x5,0x32,0x3a, + 0x6,0x3f,0x42, 0x5,0x32,0x40, 0x6,0x48,0x4a, 0x4,0x31,0x4b, + 0x5,0x38,0x2b, 0x5,0x38,0x2c, 0x5,0x38,0x2d, 0x6,0x48,0x4b, + 0x6,0x48,0x4e, 0x5,0x38,0x27, 0x6,0x48,0x4d, 0x4,0x37,0x42, + 0x5,0x38,0x2a, 0x5,0x38,0x26, 0x6,0x48,0x49, 0x4,0x37,0x43, + 0x5,0x38,0x25, 0x6,0x52,0x44, 0x6,0x48,0x46, 0x6,0x48,0x47, + 0x5,0x38,0x24, 0xf,0x3a,0x65, 0xf,0x3a,0x67, 0xf,0x3a,0x68, + 0xf,0x3a,0x69, 0xf,0x3a,0x6a, 0x6,0x48,0x48, 0x6,0x48,0x4c, + 0xf,0x3a,0x66, 0x4,0x3d,0x2b, 0x5,0x3f,0x25, 0x4,0x3d,0x2c, + 0x6,0x52,0x41, 0x6,0x52,0x42, 0x5,0x3f,0x22, 0x5,0x3f,0x23, + 0x6,0x52,0x47, 0x5,0x3e,0x7d, 0x6,0x52,0x45, 0xf,0x41,0x3a, + 0xf,0x41,0x3b, 0xf,0x41,0x3c, 0x6,0x52,0x43, 0x6,0x52,0x48, + 0x5,0x3f,0x24, 0x5,0x3e,0x7e, 0x6,0x52,0x46, 0x4,0x43,0x38, + 0x5,0x45,0x5c, 0x4,0x43,0x37, 0x5,0x45,0x5e, 0x6,0x5c,0x50, + 0x5,0x45,0x60, 0x5,0x45,0x5f, 0x6,0x5c,0x4f, 0xf,0x47,0x67, + 0xf,0x47,0x68, 0xf,0x47,0x69, 0xf,0x47,0x6a, 0xf,0x47,0x6b, + 0xf,0x47,0x6c, 0xf,0x47,0x6d, 0xf,0x47,0x6e, 0xf,0x47,0x6f, + 0x6,0x5c,0x51, 0x6,0x60,0x31, 0xf,0x4a,0x54, 0x7,0x22,0x5e, + 0x4,0x49,0x5a, 0x4,0x37,0x3f, 0x4,0x49,0x58, 0x5,0x4c,0x7a, + 0x4,0x49,0x59, 0x7,0x2d,0x59, 0x7,0x22,0x62, 0x5,0x4c,0x7c, + 0x5,0x4c,0x7e, 0xf,0x4e,0x60, 0xf,0x4e,0x62, 0xf,0x4e,0x63, + 0x7,0x22,0x5f, 0x7,0x22,0x61, 0x7,0x22,0x63, 0x7,0x22,0x60, + 0x5,0x4c,0x7b, 0x5,0x54,0x41, 0x5,0x4c,0x7d, 0x5,0x54,0x43, + 0x5,0x54,0x40, 0x4,0x50,0x2d, 0x5,0x54,0x44, 0xf,0x54,0x3f, + 0xf,0x54,0x40, 0xf,0x54,0x41, 0xf,0x54,0x42, 0x7,0x37,0x6e, + 0x5,0x5b,0x44, 0x7,0x37,0x6c, 0x7,0x37,0x6d, 0xf,0x59,0x7e, + 0xf,0x5a,0x21, 0xf,0x5a,0x22, 0xf,0x5a,0x23, 0x5,0x5b,0x43, + 0x7,0x37,0x6f, 0x5,0x5b,0x45, 0x7,0x3f,0x51, 0x7,0x3f,0x4e, + 0x5,0x61,0x5b, 0xf,0x5e,0x5a, 0xf,0x5e,0x5c, 0x7,0x3f,0x4d, + 0x7,0x3f,0x4f, 0x7,0x3f,0x4c, 0xf,0x5e,0x5b, 0x7,0x3f,0x50, + 0x7,0x46,0x68, 0x7,0x46,0x69, 0x5,0x61,0x5c, 0x5,0x67,0x69, + 0xf,0x62,0x34, 0xf,0x62,0x35, 0xf,0x62,0x36, 0x5,0x67,0x6a, + 0x5,0x6c,0x24, 0x5,0x6c,0x23, 0x7,0x4d,0x5d, 0x7,0x4d,0x5b, + 0x5,0x6c,0x22, 0x7,0x4d,0x5a, 0x7,0x4d,0x5c, 0x7,0x4d,0x5e, + 0x4,0x66,0x3c, 0x7,0x53,0x34, 0x7,0x53,0x61, 0x5,0x73,0x3e, + 0x7,0x57,0x6e, 0x7,0x57,0x6f, 0x5,0x75,0x6a, 0xf,0x6a,0x4f, + 0x7,0x5b,0x4d, 0x7,0x5e,0x64, 0x7,0x62,0x36, 0x5,0x7a,0x68, + 0x5,0x7a,0x67, 0xf,0x6c,0x7b, 0xf,0x21,0x63, 0xf,0x22,0x4b, + 0xf,0x22,0x4c, 0x6,0x2b,0x2c, 0xf,0x24,0x27, 0x6,0x2b,0x2d, + 0x6,0x2b,0x2e, 0xf,0x2f,0x39, 0xf,0x2f,0x3b, 0xf,0x2f,0x3c, + 0xf,0x2f,0x3a, 0x5,0x32,0x45, 0xf,0x34,0x54, 0x6,0x48,0x4f, + 0xf,0x3a,0x6b, 0xf,0x3a,0x6c, 0x5,0x3f,0x26, 0x6,0x21,0x3f, + 0x6,0x21,0x75, 0x6,0x22,0x79, 0x6,0x27,0x49, 0x4,0x24,0x2a, + 0x6,0x30,0x70, 0x6,0x27,0x4d, 0xf,0x24,0x28, 0x6,0x27,0x4b, + 0x6,0x27,0x4e, 0x4,0x26,0x3f, 0x6,0x2b,0x30, 0x5,0x26,0x2e, + 0x6,0x2b,0x31, 0x3,0x2a,0x39, 0x4,0x27,0x41, 0x6,0x35,0x23, + 0x6,0x30,0x72, 0x6,0x30,0x73, 0x6,0x30,0x71, 0x6,0x30,0x6f, + 0x6,0x30,0x6e, 0x6,0x37,0x3f, 0x6,0x37,0x3e, 0x4,0x2c,0x6f, + 0x6,0x37,0x3d, 0x6,0x37,0x40, 0x6,0x3f,0x49, 0x6,0x3f,0x4a, + 0x6,0x3f,0x4b, 0x6,0x3f,0x4c, 0x6,0x3f,0x4d, 0x6,0x3f,0x4e, + 0x4,0x37,0x44, 0x6,0x48,0x50, 0x6,0x48,0x54, 0x6,0x48,0x53, + 0x6,0x48,0x51, 0xf,0x3a,0x6d, 0x6,0x48,0x52, 0x6,0x52,0x49, + 0x5,0x3f,0x27, 0xf,0x41,0x3d, 0x6,0x5c,0x53, 0x6,0x5c,0x54, + 0x6,0x5c,0x52, 0x5,0x45,0x61, 0x7,0x22,0x64, 0x7,0x2d,0x5a, + 0x7,0x2d,0x5c, 0x4,0x50,0x2f, 0x5,0x54,0x45, 0x7,0x37,0x71, + 0x7,0x37,0x70, 0x7,0x57,0x70, 0x7,0x63,0x51, 0x7,0x63,0x52, + 0x7,0x65,0x36, 0x6,0x21,0x40, 0x6,0x21,0x76, 0xf,0x22,0x4d, + 0x4,0x24,0x2b, 0x6,0x27,0x50, 0x6,0x27,0x4f, 0x5,0x24,0x2e, + 0x6,0x2b,0x32, 0x6,0x30,0x76, 0x6,0x30,0x75, 0x6,0x30,0x77, + 0x5,0x2e,0x68, 0x6,0x3f,0x4f, 0x5,0x38,0x2e, 0x6,0x52,0x4a, + 0x6,0x5c,0x55, 0x7,0x22,0x65, 0x7,0x2d,0x5d, 0x5,0x21,0x2a, + 0x5,0x21,0x47, 0x6,0x21,0x78, 0x6,0x21,0x7c, 0x6,0x21,0x77, + 0x6,0x21,0x7a, 0x6,0x21,0x7b, 0x6,0x23,0x21, 0x6,0x23,0x22, + 0x6,0x22,0x7c, 0x6,0x22,0x7a, 0x6,0x23,0x23, 0x6,0x22,0x7b, + 0x6,0x22,0x7d, 0x6,0x22,0x7e, 0x5,0x21,0x6a, 0x5,0x22,0x60, + 0x5,0x22,0x5f, 0x6,0x24,0x68, 0x6,0x24,0x69, 0x6,0x24,0x6a, + 0x6,0x24,0x6b, 0x5,0x24,0x2f, 0x6,0x27,0x51, 0x5,0x24,0x31, + 0x6,0x27,0x53, 0x5,0x24,0x30, 0xf,0x24,0x29, 0xf,0x24,0x2a, + 0xf,0x24,0x2b, 0xf,0x24,0x2c, 0x6,0x27,0x52, 0x5,0x24,0x32, + 0x5,0x26,0x2f, 0x6,0x2b,0x36, 0x6,0x2b,0x33, 0x6,0x2b,0x34, + 0x6,0x2b,0x37, 0x6,0x2b,0x35, 0x6,0x30,0x7e, 0x5,0x29,0x2c, + 0x6,0x30,0x7d, 0x4,0x29,0x30, 0x6,0x30,0x79, 0x5,0x29,0x2b, + 0x6,0x30,0x78, 0x5,0x2d,0x44, 0x5,0x2d,0x43, 0x5,0x2d,0x45, + 0x6,0x37,0x43, 0x6,0x37,0x41, 0x5,0x2d,0x46, 0xf,0x2f,0x3d, + 0x6,0x37,0x42, 0x5,0x32,0x4a, 0x5,0x32,0x48, 0x5,0x32,0x49, + 0x6,0x3f,0x56, 0x6,0x3f,0x50, 0x4,0x29,0x2f, 0x6,0x48,0x55, + 0x6,0x3f,0x52, 0x6,0x3f,0x53, 0x5,0x32,0x47, 0x6,0x3f,0x51, + 0xf,0x34,0x55, 0xf,0x34,0x56, 0xf,0x34,0x57, 0x6,0x3f,0x54, + 0x6,0x3f,0x57, 0x6,0x3f,0x55, 0x6,0x48,0x56, 0x6,0x48,0x59, + 0x5,0x38,0x2f, 0x5,0x38,0x32, 0x5,0x38,0x31, 0x6,0x48,0x5a, + 0x5,0x38,0x30, 0x6,0x48,0x58, 0x6,0x48,0x57, 0x5,0x3f,0x28, + 0x4,0x3d,0x31, 0x6,0x52,0x4b, 0xf,0x41,0x40, 0x6,0x52,0x4c, + 0x5,0x45,0x62, 0x6,0x5c,0x56, 0x5,0x45,0x63, 0x6,0x5c,0x57, + 0x6,0x5c,0x59, 0xf,0x47,0x70, 0x6,0x5c,0x5a, 0x6,0x5c,0x58, + 0x5,0x4d,0x21, 0x5,0x4d,0x22, 0x4,0x49,0x60, 0x7,0x22,0x66, + 0xf,0x4e,0x64, 0xf,0x4e,0x65, 0x7,0x22,0x67, 0x7,0x2d,0x5f, + 0x5,0x54,0x46, 0x4,0x50,0x30, 0x7,0x2d,0x60, 0x7,0x2d,0x5e, + 0x7,0x37,0x73, 0x7,0x37,0x72, 0x7,0x37,0x74, 0xf,0x5a,0x24, + 0x4,0x5b,0x22, 0x5,0x61,0x5e, 0x7,0x3f,0x52, 0xf,0x5e,0x5d, + 0x5,0x61,0x5d, 0x7,0x46,0x6d, 0x7,0x46,0x6b, 0x7,0x46,0x6f, + 0x7,0x46,0x6a, 0x7,0x46,0x6c, 0x5,0x67,0x6b, 0x5,0x6c,0x25, + 0x7,0x4d,0x5f, 0x4,0x5f,0x5f, 0x7,0x4d,0x61, 0x7,0x4d,0x60, + 0x5,0x6c,0x26, 0x5,0x6f,0x7c, 0x5,0x6f,0x7d, 0x4,0x66,0x3d, + 0x7,0x53,0x35, 0x5,0x73,0x3f, 0x7,0x60,0x3c, 0x7,0x60,0x6f, + 0x7,0x64,0x46, 0x6,0x24,0x6e, 0x6,0x24,0x6c, 0x6,0x24,0x6d, + 0x5,0x24,0x33, 0x6,0x31,0x21, 0x6,0x2b,0x38, 0x6,0x2d,0x32, + 0x6,0x31,0x24, 0x6,0x37,0x44, 0x6,0x31,0x22, 0x6,0x31,0x23, + 0x6,0x37,0x46, 0x6,0x37,0x45, 0x6,0x3f,0x58, 0x6,0x4f,0x21, + 0x5,0x38,0x33, 0x6,0x48,0x5c, 0x6,0x48,0x5b, 0x5,0x3f,0x2a, + 0x6,0x5c,0x5c, 0x6,0x5c,0x5f, 0x6,0x5c,0x5d, 0x6,0x5c,0x5b, + 0x6,0x5c,0x5e, 0x7,0x2d,0x61, 0x7,0x2d,0x4e, 0x4,0x50,0x32, + 0x7,0x37,0x75, 0x7,0x3f,0x55, 0x7,0x3f,0x54, 0x7,0x3f,0x53, + 0x7,0x46,0x72, 0x7,0x46,0x70, 0x7,0x46,0x71, 0x7,0x57,0x71, + 0x7,0x5b,0x4e, 0x7,0x62,0x37, 0x6,0x23,0x25, 0x6,0x23,0x24, + 0xf,0x21,0x64, 0x6,0x24,0x71, 0x6,0x24,0x6f, 0xf,0x24,0x2d, + 0x6,0x27,0x54, 0x5,0x26,0x30, 0x6,0x2b,0x3b, 0x6,0x2b,0x3a, + 0x6,0x37,0x47, 0x4,0x2c,0x74, 0x4,0x2c,0x73, 0x5,0x35,0x60, + 0x6,0x3f,0x5d, 0x6,0x3f,0x59, 0x6,0x3f,0x5a, 0xf,0x34,0x58, + 0xf,0x34,0x59, 0xf,0x34,0x5a, 0x6,0x3f,0x5c, 0x6,0x3f,0x5b, + 0x5,0x32,0x4b, 0x6,0x48,0x5d, 0x6,0x48,0x60, 0x6,0x48,0x5e, + 0x6,0x48,0x5f, 0xf,0x3a,0x6e, 0x6,0x52,0x51, 0x6,0x52,0x4e, + 0x6,0x52,0x50, 0x6,0x52,0x4f, 0xf,0x41,0x41, 0x4,0x43,0x3c, + 0x6,0x5c,0x60, 0x7,0x22,0x6b, 0x7,0x22,0x6c, 0x7,0x22,0x69, + 0x7,0x22,0x6a, 0x5,0x4d,0x23, 0x4,0x50,0x33, 0x5,0x54,0x47, + 0x7,0x2d,0x64, 0x7,0x37,0x76, 0x7,0x3f,0x56, 0xf,0x67,0x54, + 0x7,0x4d,0x62, 0x7,0x53,0x36, 0x5,0x73,0x41, 0xf,0x6c,0x27, + 0x6,0x21,0x7d, 0x5,0x21,0x6b, 0x4,0x21,0x79, 0x5,0x22,0x61, + 0x4,0x22,0x6e, 0x5,0x22,0x62, 0x5,0x24,0x34, 0x6,0x27,0x58, + 0x5,0x24,0x35, 0x6,0x27,0x57, 0x6,0x27,0x59, 0x6,0x27,0x5b, + 0x6,0x27,0x56, 0x5,0x24,0x36, 0x6,0x27,0x55, 0x6,0x27,0x5a, + 0x5,0x26,0x33, 0x6,0x2b,0x3d, 0x5,0x26,0x31, 0x6,0x2b,0x3c, + 0x5,0x26,0x32, 0x5,0x29,0x2d, 0x6,0x2b,0x3f, 0x4,0x29,0x33, + 0x6,0x31,0x26, 0x5,0x29,0x30, 0x5,0x29,0x2e, 0x6,0x31,0x28, + 0x5,0x29,0x32, 0x5,0x29,0x31, 0xf,0x2a,0x5e, 0x6,0x31,0x27, + 0x6,0x37,0x4d, 0x4,0x2c,0x79, 0x4,0x2c,0x77, 0x4,0x2c,0x7c, + 0x4,0x2c,0x75, 0x5,0x2d,0x4b, 0x5,0x2d,0x49, 0x4,0x2c,0x78, + 0x4,0x2c,0x7a, 0x4,0x2c,0x76, 0x4,0x2c,0x7b, 0x5,0x2d,0x4a, + 0x6,0x37,0x49, 0x6,0x37,0x4f, 0x6,0x37,0x4c, 0xf,0x2f,0x3f, + 0xf,0x2f,0x40, 0x6,0x37,0x4b, 0x6,0x37,0x50, 0x6,0x37,0x4e, + 0x6,0x37,0x4a, 0x4,0x31,0x56, 0x5,0x32,0x4f, 0x6,0x3f,0x68, + 0x6,0x3f,0x61, 0x5,0x32,0x4c, 0x5,0x32,0x51, 0x5,0x32,0x4e, + 0x6,0x3f,0x60, 0x5,0x32,0x50, 0x4,0x31,0x58, 0x6,0x3f,0x67, + 0x6,0x3f,0x65, 0x6,0x3f,0x62, 0x4,0x31,0x59, 0x6,0x3f,0x66, + 0x5,0x32,0x4d, 0x6,0x3f,0x64, 0x6,0x3f,0x5f, 0x6,0x3f,0x63, + 0x6,0x48,0x64, 0xf,0x34,0x5c, 0x4,0x37,0x46, 0x5,0x38,0x36, + 0x5,0x38,0x35, 0x5,0x38,0x3b, 0x5,0x38,0x3a, 0x5,0x38,0x37, + 0x4,0x37,0x47, 0x6,0x48,0x61, 0x5,0x38,0x34, 0x6,0x48,0x63, + 0x5,0x38,0x38, 0x4,0x31,0x55, 0xf,0x3a,0x70, 0x6,0x48,0x62, + 0xf,0x3a,0x6f, 0x5,0x38,0x39, 0x5,0x3f,0x2c, 0x5,0x3f,0x2b, + 0x6,0x52,0x52, 0x6,0x52,0x54, 0x6,0x52,0x57, 0x6,0x52,0x53, + 0xf,0x41,0x42, 0xf,0x41,0x43, 0xf,0x41,0x44, 0xf,0x41,0x45, + 0xf,0x41,0x46, 0xf,0x41,0x47, 0x6,0x52,0x55, 0x6,0x52,0x56, + 0x6,0x56,0x6c, 0x5,0x3f,0x2d, 0x4,0x3d,0x32, 0x6,0x5c,0x66, + 0x6,0x5c,0x63, 0x5,0x45,0x66, 0x6,0x5c,0x62, 0x4,0x43,0x3e, + 0x5,0x45,0x65, 0x4,0x43,0x41, 0x4,0x43,0x40, 0x6,0x5c,0x61, + 0x5,0x45,0x68, 0x5,0x45,0x6a, 0x5,0x45,0x64, 0x6,0x5c,0x68, + 0x6,0x5c,0x69, 0x6,0x5c,0x6a, 0x5,0x45,0x67, 0x6,0x5c,0x64, + 0xf,0x47,0x71, 0xf,0x47,0x72, 0xf,0x47,0x73, 0xf,0x47,0x74, + 0xf,0x47,0x75, 0x6,0x5c,0x65, 0x4,0x49,0x64, 0x5,0x4d,0x24, + 0x5,0x5b,0x48, 0x4,0x49,0x63, 0x4,0x49,0x62, 0x5,0x4d,0x25, + 0x7,0x22,0x6d, 0x7,0x22,0x6f, 0xf,0x4e,0x66, 0xf,0x4e,0x67, + 0x7,0x22,0x6e, 0x7,0x22,0x70, 0x7,0x2d,0x65, 0x5,0x54,0x48, + 0x5,0x54,0x4a, 0x7,0x2d,0x67, 0x7,0x2d,0x66, 0xf,0x54,0x44, + 0xf,0x54,0x45, 0x7,0x2d,0x68, 0x5,0x54,0x49, 0x5,0x5b,0x47, + 0x7,0x37,0x77, 0x4,0x56,0x30, 0xf,0x5c,0x5f, 0x5,0x5b,0x46, + 0x5,0x61,0x60, 0x7,0x3f,0x57, 0x5,0x61,0x5f, 0x7,0x3f,0x58, + 0xf,0x5e,0x5e, 0x5,0x61,0x61, 0x7,0x46,0x73, 0x7,0x46,0x75, + 0x7,0x46,0x76, 0x7,0x4d,0x22, 0x7,0x46,0x74, 0x5,0x6c,0x27, + 0x4,0x63,0x3e, 0x4,0x63,0x3d, 0xf,0x65,0x2a, 0x7,0x4d,0x63, + 0x7,0x53,0x37, 0x5,0x6f,0x7e, 0x7,0x57,0x72, 0x4,0x6a,0x47, + 0x5,0x79,0x28, 0x5,0x21,0x31, 0x6,0x22,0x21, 0x4,0x22,0x6f, + 0x5,0x21,0x6c, 0x6,0x23,0x26, 0xf,0x22,0x4f, 0x6,0x24,0x75, + 0x5,0x22,0x63, 0x6,0x27,0x60, 0x5,0x22,0x69, 0x6,0x27,0x5d, + 0x5,0x22,0x64, 0x6,0x24,0x73, 0x6,0x24,0x74, 0x5,0x22,0x65, + 0x6,0x27,0x5c, 0x6,0x27,0x5e, 0x6,0x27,0x61, 0x6,0x24,0x72, + 0x5,0x22,0x68, 0x5,0x24,0x37, 0x5,0x24,0x39, 0x4,0x26,0x45, + 0x6,0x27,0x66, 0x6,0x27,0x64, 0x6,0x2b,0x46, 0x6,0x27,0x67, + 0x6,0x2b,0x40, 0x6,0x27,0x62, 0x6,0x27,0x63, 0x6,0x2b,0x44, + 0x6,0x27,0x65, 0x6,0x27,0x68, 0x3,0x25,0x7e, 0x6,0x27,0x69, + 0x5,0x24,0x3a, 0xf,0x24,0x2e, 0xf,0x24,0x2f, 0xf,0x24,0x31, + 0xf,0x24,0x32, 0xf,0x24,0x34, 0xf,0x24,0x35, 0xf,0x24,0x36, + 0xf,0x26,0x77, 0xf,0x26,0x78, 0xf,0x26,0x79, 0xf,0x26,0x7a, + 0xf,0x26,0x7b, 0xf,0x26,0x7d, 0xf,0x26,0x7e, 0xf,0x27,0x21, + 0xf,0x26,0x7c, 0x6,0x2b,0x45, 0x6,0x2b,0x41, 0x6,0x2b,0x42, + 0x4,0x24,0x2d, 0xf,0x24,0x30, 0x4,0x26,0x44, 0x5,0x26,0x34, + 0x6,0x2b,0x43, 0x4,0x26,0x47, 0x6,0x2b,0x4c, 0x4,0x29,0x47, + 0x6,0x31,0x2f, 0x4,0x26,0x4b, 0x6,0x2b,0x4d, 0x6,0x31,0x29, + 0x5,0x26,0x35, 0x6,0x31,0x2c, 0x6,0x2b,0x4f, 0x4,0x26,0x4a, + 0x5,0x26,0x37, 0x4,0x29,0x38, 0x5,0x26,0x36, 0x4,0x29,0x43, + 0x6,0x2b,0x49, 0x5,0x26,0x38, 0x4,0x26,0x51, 0x4,0x29,0x44, + 0x6,0x31,0x2a, 0x6,0x31,0x2b, 0x6,0x2b,0x50, 0x6,0x2b,0x47, + 0x6,0x31,0x2d, 0xf,0x26,0x75, 0xf,0x27,0x22, 0xf,0x2a,0x70, + 0x4,0x29,0x46, 0x6,0x31,0x2e, 0x6,0x2b,0x48, 0x6,0x2b,0x4a, + 0x6,0x2b,0x4e, 0x6,0x2b,0x4b, 0xf,0x2a,0x64, 0xf,0x2a,0x5f, + 0xf,0x2a,0x62, 0xf,0x2a,0x65, 0xf,0x2a,0x68, 0xf,0x2a,0x6c, + 0x6,0x37,0x5b, 0x6,0x37,0x59, 0x6,0x31,0x32, 0x4,0x29,0x49, + 0x5,0x29,0x37, 0x4,0x29,0x42, 0x4,0x2d,0x29, 0x5,0x2d,0x4e, + 0x5,0x29,0x36, 0x6,0x31,0x39, 0x6,0x37,0x57, 0x6,0x31,0x33, + 0x4,0x2c,0x7d, 0x5,0x2d,0x4c, 0x6,0x31,0x35, 0x6,0x37,0x53, + 0x4,0x2d,0x21, 0x6,0x31,0x38, 0x5,0x29,0x34, 0x4,0x2c,0x7e, + 0x6,0x31,0x3a, 0x6,0x31,0x31, 0x6,0x31,0x37, 0x6,0x37,0x56, + 0x6,0x37,0x55, 0x4,0x2d,0x2a, 0x6,0x31,0x34, 0xf,0x2a,0x61, + 0xf,0x2a,0x66, 0xf,0x2a,0x69, 0xf,0x2a,0x6b, 0xf,0x2a,0x6d, + 0xf,0x2a,0x6e, 0xf,0x2a,0x6f, 0xf,0x2f,0x46, 0xf,0x2f,0x47, + 0xf,0x2f,0x48, 0xf,0x2f,0x4a, 0x6,0x37,0x52, 0xf,0x2f,0x44, + 0x6,0x37,0x58, 0xf,0x2a,0x63, 0x5,0x2d,0x4d, 0x6,0x37,0x51, + 0x5,0x2d,0x52, 0x5,0x2d,0x58, 0x5,0x2d,0x5b, 0x6,0x3f,0x6d, + 0x6,0x37,0x63, 0x6,0x3f,0x6f, 0x6,0x3f,0x6b, 0x6,0x3f,0x70, + 0x6,0x37,0x64, 0x5,0x2d,0x55, 0x6,0x3f,0x69, 0x4,0x2d,0x2e, + 0x6,0x3f,0x73, 0x5,0x2d,0x56, 0x4,0x2d,0x26, 0x5,0x32,0x5d, + 0x5,0x2d,0x51, 0x5,0x2d,0x5c, 0x6,0x37,0x62, 0x6,0x37,0x5d, + 0x5,0x32,0x54, 0x6,0x37,0x5f, 0x6,0x37,0x61, 0x6,0x3f,0x6c, + 0x6,0x37,0x60, 0x6,0x3f,0x71, 0x4,0x2d,0x27, 0x5,0x2d,0x50, + 0x6,0x37,0x5c, 0x5,0x32,0x53, 0x6,0x3f,0x72, 0x6,0x3f,0x74, + 0x5,0x32,0x52, 0x5,0x2d,0x4f, 0xf,0x2f,0x41, 0xf,0x2f,0x42, + 0xf,0x2f,0x43, 0xf,0x2f,0x49, 0xf,0x2f,0x4b, 0xf,0x34,0x5d, + 0xf,0x34,0x5f, 0xf,0x34,0x60, 0xf,0x34,0x64, 0xf,0x34,0x65, + 0xf,0x34,0x66, 0xf,0x34,0x67, 0xf,0x34,0x68, 0x6,0x3f,0x6a, + 0x6,0x37,0x65, 0x6,0x37,0x66, 0x5,0x2d,0x54, 0x5,0x2d,0x59, + 0x4,0x37,0x5a, 0x6,0x48,0x71, 0x4,0x37,0x4d, 0x5,0x32,0x59, + 0x6,0x3f,0x7c, 0x4,0x37,0x4b, 0x6,0x48,0x73, 0x6,0x48,0x69, + 0x5,0x38,0x55, 0x6,0x3f,0x7e, 0x6,0x48,0x72, 0x6,0x40,0x22, + 0x4,0x31,0x65, 0x5,0x2d,0x53, 0x4,0x31,0x6d, 0x6,0x3f,0x77, + 0x6,0x48,0x6e, 0x4,0x31,0x61, 0x5,0x38,0x3f, 0x5,0x32,0x57, + 0x5,0x32,0x5a, 0x4,0x37,0x4c, 0x6,0x3f,0x79, 0x5,0x32,0x5c, + 0x6,0x3f,0x76, 0x6,0x3f,0x6e, 0x4,0x31,0x69, 0x5,0x38,0x3c, + 0x6,0x48,0x70, 0x5,0x32,0x5e, 0x4,0x31,0x5f, 0x6,0x3f,0x7d, + 0x6,0x3f,0x7b, 0x6,0x3f,0x7a, 0x6,0x48,0x66, 0x6,0x48,0x6c, + 0x5,0x38,0x3e, 0x5,0x38,0x41, 0x6,0x48,0x74, 0x5,0x32,0x55, + 0x6,0x48,0x6b, 0x6,0x48,0x76, 0x6,0x48,0x67, 0x6,0x48,0x65, + 0x6,0x3f,0x75, 0x5,0x38,0x40, 0xf,0x34,0x61, 0xf,0x34,0x5e, + 0xf,0x34,0x62, 0xf,0x34,0x63, 0xf,0x34,0x69, 0xf,0x34,0x6a, + 0xf,0x34,0x6b, 0xf,0x34,0x6c, 0xf,0x34,0x6d, 0xf,0x34,0x6f, + 0xf,0x34,0x70, 0xf,0x34,0x72, 0xf,0x3a,0x72, 0xf,0x3a,0x73, + 0xf,0x3a,0x74, 0xf,0x3a,0x75, 0xf,0x3a,0x76, 0xf,0x3a,0x77, + 0xf,0x3a,0x79, 0xf,0x3a,0x7a, 0xf,0x3a,0x7c, 0xf,0x3a,0x7d, + 0xf,0x3a,0x7e, 0xf,0x3b,0x21, 0xf,0x3b,0x22, 0xf,0x3b,0x25, + 0xf,0x3b,0x29, 0xf,0x3b,0x2a, 0xf,0x3b,0x2c, 0xf,0x3b,0x2e, + 0x6,0x48,0x68, 0x5,0x32,0x56, 0x6,0x3f,0x78, 0xf,0x3b,0x27, + 0xf,0x34,0x6e, 0x6,0x49,0x24, 0x6,0x48,0x6d, 0x6,0x40,0x21, + 0xf,0x3b,0x24, 0x4,0x3d,0x3f, 0x5,0x38,0x4a, 0x5,0x38,0x4d, + 0x5,0x38,0x52, 0x4,0x37,0x4f, 0x4,0x37,0x57, 0x4,0x37,0x51, + 0x6,0x52,0x5d, 0x6,0x49,0x23, 0x5,0x38,0x50, 0x6,0x49,0x22, + 0x4,0x37,0x53, 0x5,0x38,0x56, 0x5,0x38,0x58, 0x5,0x38,0x43, + 0x6,0x52,0x61, 0x5,0x38,0x5a, 0x5,0x3f,0x33, 0x4,0x37,0x5b, + 0x5,0x38,0x53, 0x6,0x49,0x21, 0x5,0x38,0x46, 0x6,0x48,0x7b, + 0x5,0x3f,0x34, 0x5,0x38,0x44, 0x5,0x38,0x54, 0x5,0x32,0x5f, + 0x6,0x52,0x58, 0x5,0x38,0x47, 0x4,0x3d,0x36, 0x4,0x37,0x58, + 0x5,0x38,0x59, 0x5,0x38,0x51, 0x5,0x38,0x4b, 0x5,0x3f,0x31, + 0x6,0x48,0x77, 0x5,0x38,0x4f, 0x5,0x38,0x3d, 0x6,0x48,0x7e, + 0x6,0x52,0x62, 0x6,0x52,0x63, 0x6,0x52,0x5a, 0x6,0x48,0x7d, + 0x5,0x38,0x57, 0x6,0x52,0x5e, 0x6,0x52,0x60, 0x5,0x3f,0x2f, + 0x4,0x3d,0x40, 0x4,0x37,0x52, 0x5,0x38,0x49, 0x6,0x48,0x79, + 0xf,0x3a,0x71, 0xf,0x3a,0x7b, 0xf,0x3b,0x23, 0xf,0x3b,0x28, + 0xf,0x3b,0x2d, 0xf,0x41,0x48, 0xf,0x41,0x4e, 0xf,0x41,0x50, + 0xf,0x41,0x51, 0xf,0x41,0x52, 0x6,0x52,0x5c, 0x6,0x52,0x5f, + 0x6,0x52,0x5b, 0x6,0x48,0x7a, 0xf,0x3b,0x2b, 0x5,0x38,0x4e, + 0x5,0x3f,0x2e, 0x5,0x38,0x4c, 0xf,0x34,0x71, 0xf,0x47,0x7d, + 0x5,0x3f,0x3c, 0x5,0x3f,0x36, 0x5,0x3f,0x35, 0x6,0x52,0x6b, + 0x5,0x4d,0x26, 0x5,0x3f,0x45, 0x6,0x5c,0x6f, 0x5,0x3f,0x39, + 0x5,0x3f,0x3f, 0x5,0x3f,0x44, 0x6,0x5c,0x74, 0x6,0x52,0x6f, + 0x5,0x45,0x6b, 0x5,0x3f,0x3b, 0x6,0x5c,0x6c, 0x6,0x52,0x65, + 0x5,0x3f,0x38, 0x5,0x3f,0x3d, 0x5,0x3f,0x3a, 0x6,0x52,0x59, + 0x4,0x49,0x6e, 0x6,0x5c,0x76, 0x6,0x5c,0x79, 0x5,0x3f,0x43, + 0x6,0x52,0x68, 0x6,0x5c,0x72, 0x4,0x43,0x4f, 0x6,0x5c,0x78, + 0x6,0x5c,0x77, 0x5,0x3f,0x41, 0x5,0x45,0x6d, 0x5,0x3f,0x3e, + 0x6,0x5c,0x71, 0x6,0x5c,0x6e, 0x6,0x5c,0x6d, 0x5,0x3f,0x37, + 0x6,0x52,0x67, 0x6,0x52,0x6d, 0xf,0x41,0x4a, 0xf,0x41,0x4b, + 0xf,0x41,0x4c, 0xf,0x41,0x4d, 0xf,0x41,0x4f, 0xf,0x41,0x53, + 0xf,0x47,0x76, 0xf,0x47,0x77, 0xf,0x47,0x79, 0xf,0x47,0x7a, + 0xf,0x48,0x25, 0xf,0x48,0x28, 0x6,0x5c,0x70, 0x6,0x5c,0x75, + 0x5,0x3f,0x40, 0xf,0x41,0x49, 0x6,0x5c,0x73, 0x6,0x52,0x6e, + 0x6,0x5d,0x23, 0x6,0x5d,0x27, 0x4,0x43,0x45, 0x4,0x43,0x44, + 0x5,0x4d,0x27, 0x6,0x5c,0x7c, 0x5,0x45,0x77, 0x5,0x45,0x76, + 0x5,0x45,0x73, 0x4,0x3d,0x35, 0x6,0x5c,0x7b, 0x7,0x22,0x72, + 0x7,0x22,0x75, 0x5,0x4d,0x29, 0x5,0x45,0x70, 0x5,0x45,0x6f, + 0x5,0x45,0x6c, 0x5,0x45,0x71, 0x5,0x45,0x72, 0x5,0x45,0x79, + 0x6,0x5d,0x25, 0x6,0x5c,0x7d, 0x6,0x5c,0x7e, 0x6,0x52,0x6a, + 0x6,0x5d,0x22, 0x7,0x22,0x74, 0x6,0x5d,0x21, 0x7,0x22,0x77, + 0x5,0x45,0x74, 0x5,0x45,0x78, 0x7,0x2d,0x6a, 0x4,0x43,0x53, + 0xf,0x47,0x78, 0xf,0x47,0x7c, 0xf,0x47,0x7e, 0xf,0x48,0x21, + 0xf,0x48,0x23, 0xf,0x48,0x24, 0xf,0x48,0x26, 0xf,0x4e,0x69, + 0xf,0x4e,0x6a, 0xf,0x4e,0x6b, 0xf,0x4e,0x6c, 0xf,0x4e,0x6d, + 0xf,0x4e,0x6e, 0xf,0x4e,0x6f, 0xf,0x4e,0x73, 0xf,0x4e,0x75, + 0x7,0x22,0x73, 0x7,0x22,0x78, 0x6,0x5c,0x6b, 0x5,0x45,0x6e, + 0x6,0x5c,0x7a, 0x5,0x4d,0x28, 0x5,0x45,0x75, 0x7,0x2d,0x71, + 0x4,0x49,0x66, 0x4,0x43,0x52, 0x7,0x2d,0x6b, 0x4,0x49,0x71, + 0x7,0x2d,0x6d, 0x5,0x4d,0x2f, 0x7,0x2d,0x73, 0x4,0x49,0x6a, + 0x5,0x4d,0x2e, 0x7,0x22,0x79, 0x5,0x4d,0x33, 0x4,0x49,0x72, + 0x7,0x2d,0x75, 0x5,0x38,0x45, 0x5,0x4d,0x32, 0x5,0x4d,0x35, + 0x4,0x50,0x35, 0x4,0x50,0x36, 0x7,0x23,0x21, 0x5,0x4d,0x34, + 0x7,0x37,0x7c, 0x5,0x4d,0x30, 0x5,0x54,0x4e, 0x4,0x56,0x34, + 0x7,0x22,0x7a, 0x7,0x23,0x22, 0x5,0x54,0x54, 0x5,0x4d,0x2b, + 0x5,0x4d,0x2d, 0x5,0x54,0x4d, 0x5,0x4d,0x2c, 0x7,0x2e,0x22, + 0x7,0x2d,0x77, 0x7,0x2d,0x76, 0x7,0x22,0x7e, 0x4,0x50,0x3c, + 0x7,0x2d,0x70, 0x7,0x2d,0x6f, 0xf,0x48,0x22, 0xf,0x4e,0x70, + 0x7,0x2d,0x72, 0x5,0x4d,0x31, 0x7,0x2d,0x6c, 0xf,0x4e,0x71, + 0xf,0x4e,0x72, 0xf,0x4e,0x74, 0xf,0x4e,0x76, 0xf,0x54,0x47, + 0xf,0x54,0x48, 0xf,0x54,0x4a, 0xf,0x54,0x4b, 0xf,0x54,0x51, + 0xf,0x54,0x53, 0x7,0x2d,0x74, 0x5,0x54,0x4b, 0x7,0x30,0x50, + 0x7,0x22,0x7d, 0x7,0x25,0x71, 0x4,0x49,0x70, 0x5,0x54,0x4c, + 0x5,0x54,0x4f, 0xf,0x4e,0x68, 0xf,0x54,0x4f, 0x5,0x54,0x50, + 0x5,0x54,0x52, 0x7,0x2d,0x7b, 0x7,0x2d,0x78, 0x5,0x54,0x55, + 0x5,0x54,0x56, 0x5,0x54,0x51, 0x7,0x2d,0x7e, 0x7,0x2d,0x7c, + 0x7,0x2d,0x7d, 0x5,0x54,0x57, 0x4,0x50,0x3d, 0x5,0x5b,0x49, + 0x7,0x2e,0x21, 0x7,0x37,0x7b, 0x7,0x37,0x7d, 0x7,0x37,0x7a, + 0x7,0x38,0x21, 0x5,0x5b,0x4b, 0x7,0x2d,0x7a, 0x7,0x37,0x79, + 0x7,0x2d,0x6e, 0xf,0x54,0x4d, 0x5,0x54,0x53, 0x7,0x38,0x22, + 0xf,0x54,0x49, 0xf,0x54,0x4e, 0xf,0x54,0x52, 0xf,0x5a,0x25, + 0xf,0x5a,0x26, 0xf,0x5a,0x2e, 0xf,0x5a,0x27, 0x5,0x5b,0x4a, + 0x5,0x54,0x58, 0xf,0x5a,0x2a, 0xf,0x54,0x4c, 0x7,0x37,0x78, + 0x5,0x5b,0x51, 0x4,0x56,0x35, 0x4,0x56,0x31, 0x4,0x5b,0x2a, + 0x5,0x5b,0x4e, 0x5,0x61,0x64, 0x5,0x61,0x62, 0x7,0x3f,0x5b, + 0x7,0x38,0x26, 0x4,0x5b,0x26, 0x5,0x5b,0x4d, 0x5,0x5b,0x4f, + 0x7,0x38,0x23, 0x7,0x38,0x25, 0x5,0x5b,0x50, 0x5,0x61,0x63, + 0x7,0x3f,0x5a, 0x5,0x61,0x65, 0x7,0x3f,0x59, 0x7,0x22,0x76, + 0xf,0x5a,0x2b, 0xf,0x5a,0x2d, 0xf,0x5e,0x5f, 0xf,0x5e,0x60, + 0xf,0x5e,0x62, 0xf,0x5e,0x63, 0xf,0x5e,0x65, 0xf,0x5e,0x66, + 0xf,0x5e,0x67, 0x7,0x3f,0x5c, 0x7,0x38,0x24, 0xf,0x5a,0x28, + 0x4,0x5b,0x27, 0x5,0x5b,0x52, 0x7,0x46,0x79, 0x7,0x3f,0x5d, + 0x5,0x61,0x68, 0x7,0x4d,0x64, 0x4,0x5f,0x63, 0x4,0x5f,0x62, + 0x7,0x46,0x7c, 0x5,0x61,0x69, 0x7,0x4d,0x67, 0x4,0x5b,0x28, + 0x5,0x61,0x6a, 0x7,0x47,0x25, 0x7,0x47,0x21, 0x7,0x46,0x78, + 0x5,0x61,0x67, 0x7,0x46,0x7e, 0x5,0x67,0x6d, 0x7,0x46,0x7a, + 0x5,0x67,0x70, 0x7,0x46,0x77, 0x7,0x47,0x22, 0x7,0x3f,0x5e, + 0x7,0x46,0x7d, 0x5,0x67,0x6e, 0xf,0x5e,0x64, 0x5,0x67,0x6f, + 0x7,0x46,0x7b, 0x5,0x67,0x6c, 0xf,0x62,0x39, 0x7,0x47,0x2a, + 0x4,0x63,0x44, 0x7,0x47,0x27, 0x5,0x67,0x74, 0x7,0x47,0x24, + 0x5,0x6c,0x2a, 0x7,0x47,0x29, 0x7,0x47,0x26, 0x7,0x3f,0x5f, + 0x5,0x67,0x75, 0x4,0x63,0x3f, 0x5,0x67,0x71, 0x5,0x6c,0x28, + 0x7,0x47,0x2b, 0x7,0x47,0x23, 0x7,0x4d,0x65, 0x5,0x67,0x77, + 0xf,0x62,0x3a, 0xf,0x62,0x38, 0xf,0x62,0x3b, 0xf,0x62,0x3c, + 0xf,0x62,0x3d, 0x7,0x4d,0x66, 0x5,0x61,0x66, 0x5,0x67,0x72, + 0xf,0x65,0x2b, 0x5,0x67,0x76, 0x5,0x6c,0x29, 0x7,0x53,0x39, + 0x7,0x4d,0x6a, 0x4,0x63,0x41, 0x7,0x4d,0x69, 0x4,0x63,0x45, + 0x7,0x53,0x38, 0x7,0x4d,0x6b, 0xf,0x67,0x55, 0x7,0x5b,0x4f, + 0x4,0x66,0x3e, 0x5,0x6c,0x2b, 0x7,0x57,0x73, 0x7,0x57,0x74, + 0x7,0x57,0x75, 0x7,0x53,0x3b, 0x7,0x53,0x3a, 0x7,0x53,0x3c, + 0xf,0x69,0x42, 0x7,0x57,0x76, 0x7,0x5b,0x50, 0x7,0x5b,0x52, + 0x7,0x5b,0x53, 0x7,0x5b,0x51, 0xf,0x6a,0x50, 0xf,0x69,0x41, + 0xf,0x6a,0x51, 0xf,0x6a,0x52, 0x7,0x5b,0x55, 0x5,0x77,0x5a, + 0x7,0x5b,0x54, 0x7,0x5e,0x65, 0xf,0x6a,0x53, 0xf,0x6b,0x47, + 0xf,0x6b,0x48, 0x5,0x77,0x5b, 0x7,0x5e,0x66, 0x5,0x79,0x29, + 0x7,0x5e,0x67, 0xf,0x6c,0x28, 0xf,0x6c,0x29, 0x4,0x6d,0x72, + 0xf,0x6c,0x7c, 0xf,0x6c,0x7d, 0x5,0x7b,0x3e, 0x5,0x7b,0x60, + 0xf,0x6d,0x34, 0x5,0x22,0x6a, 0x4,0x22,0x72, 0x6,0x24,0x76, + 0x6,0x27,0x6b, 0x5,0x24,0x3b, 0x6,0x27,0x6a, 0x6,0x27,0x6d, + 0x6,0x27,0x6c, 0x4,0x26,0x52, 0x6,0x2b,0x51, 0x6,0x2b,0x58, + 0x6,0x2b,0x54, 0x6,0x2b,0x56, 0x4,0x26,0x53, 0x6,0x2b,0x55, + 0x6,0x2b,0x53, 0x6,0x2b,0x57, 0xf,0x27,0x24, 0xf,0x27,0x23, + 0x6,0x31,0x3d, 0x6,0x31,0x3b, 0x6,0x31,0x3e, 0x6,0x31,0x40, + 0x4,0x29,0x4c, 0x6,0x31,0x41, 0x6,0x31,0x3f, 0xf,0x2a,0x71, + 0xf,0x2a,0x72, 0x6,0x31,0x3c, 0x6,0x37,0x67, 0x5,0x2d,0x5f, + 0x6,0x37,0x69, 0x5,0x2d,0x5e, 0x6,0x37,0x68, 0x5,0x32,0x61, + 0x4,0x31,0x6f, 0x6,0x40,0x25, 0xf,0x34,0x73, 0xf,0x34,0x74, + 0x6,0x40,0x24, 0x5,0x32,0x60, 0x6,0x49,0x28, 0x6,0x49,0x27, + 0x6,0x49,0x25, 0x6,0x49,0x26, 0x4,0x37,0x5c, 0x6,0x49,0x29, + 0xf,0x3b,0x2f, 0x5,0x38,0x5b, 0x5,0x38,0x5c, 0xf,0x34,0x76, + 0x4,0x3d,0x44, 0x6,0x52,0x71, 0x5,0x3f,0x47, 0x5,0x3f,0x49, + 0xf,0x41,0x55, 0x4,0x3d,0x41, 0x6,0x52,0x70, 0x5,0x3f,0x48, + 0x6,0x5d,0x29, 0x6,0x5d,0x2a, 0x5,0x45,0x7a, 0x5,0x45,0x7c, + 0x5,0x45,0x7b, 0x7,0x23,0x24, 0x5,0x45,0x7d, 0xf,0x48,0x29, + 0xf,0x48,0x2a, 0x6,0x5d,0x28, 0x5,0x4d,0x36, 0x4,0x49,0x73, + 0x4,0x49,0x74, 0x7,0x23,0x28, 0x7,0x23,0x27, 0x7,0x23,0x25, + 0x6,0x5d,0x2b, 0x7,0x23,0x23, 0xf,0x4e,0x7b, 0x7,0x23,0x29, + 0x7,0x23,0x26, 0xf,0x4e,0x77, 0xf,0x4e,0x78, 0xf,0x4e,0x7a, + 0x7,0x23,0x2a, 0x7,0x2e,0x2a, 0x7,0x2e,0x25, 0x7,0x2e,0x24, + 0x7,0x2e,0x27, 0x7,0x2e,0x26, 0x7,0x2e,0x29, 0x7,0x2e,0x28, + 0x7,0x2c,0x63, 0x7,0x31,0x70, 0x7,0x2e,0x23, 0x7,0x38,0x27, + 0x5,0x5b,0x53, 0xf,0x5a,0x2f, 0x7,0x3f,0x60, 0x7,0x47,0x2d, + 0x4,0x5f,0x65, 0x7,0x47,0x2e, 0x5,0x6c,0x2c, 0xf,0x65,0x2c, + 0x5,0x70,0x21, 0x7,0x53,0x3d, 0x6,0x23,0x27, 0x5,0x21,0x6d, + 0x6,0x24,0x77, 0x6,0x24,0x78, 0x4,0x24,0x34, 0xf,0x24,0x37, + 0xf,0x24,0x38, 0x5,0x26,0x39, 0x6,0x2b,0x59, 0x6,0x2b,0x5a, + 0x6,0x31,0x43, 0x6,0x31,0x42, 0x6,0x31,0x44, 0x5,0x29,0x39, + 0xf,0x2a,0x73, 0xf,0x2a,0x74, 0xf,0x2a,0x75, 0x6,0x31,0x46, + 0x6,0x31,0x45, 0x5,0x29,0x38, 0x6,0x37,0x6c, 0x6,0x37,0x6a, + 0x6,0x37,0x6b, 0x5,0x2d,0x61, 0x5,0x2d,0x60, 0x6,0x40,0x26, + 0xf,0x34,0x77, 0x5,0x38,0x5d, 0x5,0x38,0x5f, 0x5,0x38,0x60, + 0x5,0x38,0x5e, 0x5,0x3f,0x4a, 0x5,0x45,0x7e, 0x4,0x43,0x55, + 0x7,0x23,0x2b, 0x5,0x5b,0x54, 0x5,0x70,0x22, 0x6,0x23,0x28, + 0x5,0x21,0x6e, 0x6,0x23,0x29, 0x6,0x23,0x2a, 0x5,0x21,0x6f, + 0x5,0x22,0x6c, 0x4,0x22,0x76, 0x6,0x24,0x79, 0x5,0x22,0x72, + 0x5,0x22,0x70, 0x5,0x22,0x6f, 0x5,0x22,0x6b, 0x5,0x22,0x6d, + 0xf,0x22,0x50, 0xf,0x22,0x52, 0x5,0x22,0x71, 0x4,0x24,0x37, + 0x6,0x27,0x73, 0x6,0x27,0x76, 0x6,0x27,0x75, 0x4,0x26,0x57, + 0x5,0x24,0x3d, 0x6,0x27,0x6f, 0x4,0x24,0x38, 0x4,0x24,0x35, + 0x6,0x27,0x77, 0x5,0x24,0x3e, 0x4,0x24,0x3b, 0x6,0x27,0x72, + 0x6,0x2b,0x5d, 0x6,0x27,0x71, 0x6,0x2b,0x65, 0x6,0x2b,0x5b, + 0x6,0x27,0x70, 0x5,0x24,0x3c, 0x6,0x2b,0x5c, 0x6,0x27,0x74, + 0xf,0x24,0x3b, 0xf,0x24,0x3c, 0xf,0x24,0x3d, 0xf,0x24,0x3e, + 0xf,0x24,0x3f, 0xf,0x24,0x40, 0xf,0x24,0x41, 0xf,0x24,0x43, + 0xf,0x24,0x44, 0xf,0x24,0x45, 0xf,0x24,0x3a, 0x6,0x2b,0x5e, + 0x6,0x2b,0x5f, 0x6,0x2b,0x61, 0x5,0x26,0x3b, 0x5,0x29,0x3a, + 0x6,0x2b,0x64, 0x6,0x31,0x48, 0x5,0x26,0x3d, 0x6,0x31,0x4a, + 0x5,0x26,0x3c, 0x6,0x31,0x49, 0x6,0x31,0x47, 0x6,0x2b,0x62, + 0xf,0x27,0x26, 0xf,0x27,0x27, 0xf,0x27,0x28, 0xf,0x27,0x29, + 0xf,0x27,0x2a, 0xf,0x27,0x2b, 0xf,0x27,0x2c, 0xf,0x27,0x2d, + 0xf,0x27,0x2f, 0xf,0x27,0x25, 0x5,0x26,0x3e, 0x6,0x31,0x52, + 0x6,0x31,0x54, 0x4,0x29,0x58, 0x4,0x29,0x4f, 0x4,0x29,0x50, + 0x6,0x31,0x53, 0x6,0x37,0x6d, 0x5,0x29,0x3f, 0x5,0x29,0x42, + 0x5,0x29,0x41, 0x6,0x31,0x4d, 0x5,0x29,0x47, 0x4,0x2d,0x34, + 0x4,0x29,0x5c, 0x5,0x29,0x3e, 0x5,0x29,0x3d, 0x5,0x2d,0x63, + 0x4,0x29,0x53, 0x6,0x37,0x6e, 0x5,0x29,0x48, 0x4,0x29,0x5a, + 0x6,0x31,0x50, 0x5,0x29,0x40, 0x5,0x29,0x44, 0x6,0x31,0x4e, + 0x6,0x31,0x56, 0x6,0x31,0x4b, 0x5,0x29,0x43, 0x5,0x29,0x3c, + 0x6,0x31,0x55, 0x6,0x31,0x51, 0xf,0x2a,0x76, 0xf,0x2a,0x77, + 0xf,0x2a,0x78, 0xf,0x2a,0x79, 0xf,0x2a,0x7a, 0xf,0x2a,0x7b, + 0xf,0x2a,0x7c, 0xf,0x2a,0x7d, 0xf,0x2a,0x7e, 0xf,0x2b,0x21, + 0xf,0x2b,0x23, 0xf,0x2b,0x24, 0xf,0x2b,0x25, 0xf,0x2b,0x26, + 0xf,0x2b,0x27, 0xf,0x2b,0x28, 0xf,0x2b,0x29, 0xf,0x2b,0x2a, + 0xf,0x2f,0x53, 0xf,0x2f,0x5c, 0xf,0x2f,0x61, 0x6,0x31,0x4c, + 0xf,0x2b,0x22, 0x5,0x29,0x3b, 0x5,0x2d,0x62, 0x5,0x2d,0x64, + 0x4,0x2d,0x3d, 0x6,0x37,0x75, 0x4,0x2d,0x38, 0x5,0x2d,0x6d, + 0x5,0x2d,0x6b, 0x4,0x2d,0x39, 0x4,0x29,0x57, 0x4,0x2d,0x35, + 0x5,0x2d,0x6a, 0x6,0x37,0x7b, 0x6,0x37,0x70, 0x6,0x37,0x7d, + 0x6,0x37,0x73, 0x5,0x2d,0x69, 0x6,0x37,0x72, 0x6,0x37,0x77, + 0x4,0x2d,0x36, 0x6,0x37,0x78, 0x5,0x2d,0x6c, 0x5,0x2d,0x65, + 0x4,0x2d,0x37, 0x5,0x2d,0x67, 0x5,0x2d,0x68, 0x4,0x2d,0x3a, + 0x6,0x37,0x7a, 0x5,0x2d,0x66, 0x6,0x31,0x57, 0x6,0x37,0x76, + 0x6,0x40,0x27, 0x6,0x37,0x79, 0x6,0x37,0x74, 0x5,0x29,0x46, + 0x6,0x37,0x7c, 0x6,0x37,0x7e, 0xf,0x2f,0x4c, 0xf,0x2f,0x4d, + 0xf,0x2f,0x4e, 0xf,0x2f,0x4f, 0xf,0x2f,0x50, 0xf,0x2f,0x51, + 0xf,0x2f,0x52, 0xf,0x2f,0x55, 0xf,0x2f,0x56, 0xf,0x2f,0x57, + 0xf,0x2f,0x5a, 0xf,0x2f,0x5b, 0xf,0x2f,0x5d, 0xf,0x2f,0x5e, + 0xf,0x2f,0x60, 0xf,0x2f,0x62, 0x6,0x40,0x28, 0xf,0x2f,0x58, + 0x6,0x37,0x6f, 0xf,0x2f,0x54, 0x4,0x31,0x72, 0x4,0x31,0x73, + 0x4,0x37,0x5e, 0x5,0x32,0x69, 0x6,0x40,0x31, 0x5,0x2d,0x6e, + 0x6,0x40,0x37, 0x5,0x32,0x63, 0x4,0x31,0x74, 0x4,0x32,0x22, + 0x4,0x31,0x76, 0x5,0x32,0x62, 0x4,0x31,0x7d, 0x5,0x38,0x61, + 0x5,0x32,0x64, 0x6,0x40,0x34, 0x5,0x32,0x67, 0x6,0x40,0x35, + 0x6,0x40,0x2c, 0x6,0x40,0x29, 0x4,0x32,0x24, 0x6,0x49,0x2f, + 0x6,0x49,0x2a, 0x6,0x40,0x2a, 0x5,0x32,0x65, 0x6,0x49,0x2d, + 0x4,0x37,0x5d, 0x6,0x40,0x2f, 0x6,0x49,0x2c, 0x6,0x49,0x2b, + 0x5,0x32,0x68, 0x6,0x40,0x2d, 0x6,0x49,0x2e, 0x6,0x40,0x33, + 0x6,0x40,0x30, 0x4,0x31,0x75, 0x6,0x40,0x2e, 0xf,0x34,0x78, + 0xf,0x34,0x79, 0xf,0x34,0x7a, 0xf,0x34,0x7b, 0xf,0x34,0x7c, + 0xf,0x34,0x7e, 0xf,0x35,0x22, 0xf,0x35,0x23, 0xf,0x35,0x24, + 0xf,0x35,0x25, 0xf,0x35,0x26, 0xf,0x35,0x27, 0xf,0x35,0x28, + 0xf,0x35,0x29, 0xf,0x35,0x2a, 0xf,0x35,0x2b, 0xf,0x35,0x2c, + 0xf,0x35,0x2e, 0xf,0x35,0x2d, 0xf,0x35,0x2f, 0xf,0x35,0x30, + 0xf,0x3b,0x31, 0xf,0x34,0x7d, 0x5,0x32,0x66, 0x4,0x32,0x26, + 0xf,0x3b,0x41, 0x5,0x38,0x6b, 0x6,0x49,0x34, 0x4,0x37,0x69, + 0x6,0x49,0x3b, 0x6,0x49,0x36, 0x5,0x38,0x6d, 0x6,0x49,0x41, + 0x5,0x38,0x74, 0x6,0x49,0x31, 0x4,0x3d,0x51, 0x4,0x37,0x67, + 0x5,0x38,0x62, 0x5,0x38,0x6a, 0x4,0x37,0x5f, 0x5,0x38,0x68, + 0x4,0x37,0x63, 0x5,0x38,0x69, 0x4,0x37,0x6a, 0x5,0x38,0x66, + 0x4,0x37,0x6d, 0x5,0x38,0x6f, 0x4,0x37,0x66, 0x6,0x49,0x42, + 0x6,0x49,0x43, 0x6,0x49,0x3a, 0x5,0x38,0x71, 0x6,0x49,0x33, + 0x6,0x49,0x46, 0x6,0x49,0x37, 0x5,0x38,0x70, 0x4,0x37,0x6c, + 0x6,0x49,0x47, 0x6,0x49,0x32, 0x5,0x38,0x6c, 0x5,0x38,0x6e, + 0x6,0x49,0x44, 0x5,0x38,0x64, 0x6,0x49,0x3c, 0x6,0x49,0x45, + 0x6,0x49,0x40, 0x6,0x49,0x4c, 0x6,0x49,0x3f, 0x6,0x49,0x4d, + 0x6,0x49,0x48, 0x6,0x49,0x39, 0x5,0x38,0x72, 0x6,0x49,0x3d, + 0x5,0x38,0x73, 0x5,0x38,0x67, 0x6,0x49,0x38, 0x6,0x49,0x4b, + 0x5,0x38,0x65, 0x6,0x52,0x73, 0xf,0x3b,0x30, 0xf,0x3b,0x32, + 0xf,0x3b,0x34, 0xf,0x3b,0x35, 0xf,0x3b,0x36, 0xf,0x3b,0x37, + 0xf,0x3b,0x38, 0xf,0x3b,0x39, 0xf,0x3b,0x3a, 0xf,0x3b,0x3b, + 0xf,0x3b,0x3c, 0xf,0x3b,0x3d, 0xf,0x3b,0x3f, 0xf,0x3b,0x40, + 0xf,0x3b,0x42, 0xf,0x3b,0x43, 0xf,0x3b,0x44, 0xf,0x3b,0x45, + 0xf,0x3b,0x46, 0xf,0x3b,0x48, 0xf,0x3b,0x49, 0xf,0x3b,0x4a, + 0x6,0x52,0x74, 0x6,0x49,0x3e, 0x6,0x49,0x49, 0x6,0x49,0x35, + 0x5,0x38,0x63, 0xf,0x3b,0x47, 0x5,0x3f,0x52, 0x6,0x52,0x7b, + 0x4,0x3d,0x4b, 0x4,0x3d,0x49, 0x5,0x3f,0x55, 0x4,0x3d,0x46, + 0x6,0x52,0x78, 0x4,0x3d,0x4d, 0x4,0x3d,0x53, 0x4,0x3d,0x47, + 0x4,0x3d,0x52, 0x6,0x52,0x7e, 0x5,0x3f,0x51, 0x5,0x46,0x21, + 0x5,0x3f,0x4b, 0x6,0x5d,0x2c, 0x6,0x53,0x25, 0x6,0x52,0x75, + 0x6,0x53,0x23, 0x6,0x53,0x22, 0x5,0x3f,0x4d, 0x5,0x3f,0x53, + 0x5,0x3f,0x4e, 0x6,0x52,0x79, 0x6,0x53,0x21, 0x5,0x3f,0x50, + 0x6,0x53,0x24, 0x6,0x52,0x7c, 0x5,0x3f,0x4c, 0x6,0x52,0x7a, + 0x5,0x3f,0x4f, 0xf,0x41,0x56, 0xf,0x41,0x57, 0xf,0x41,0x58, + 0xf,0x41,0x59, 0xf,0x41,0x5a, 0xf,0x41,0x5b, 0xf,0x41,0x5c, + 0xf,0x41,0x5d, 0xf,0x41,0x5e, 0xf,0x41,0x60, 0xf,0x41,0x61, + 0xf,0x41,0x63, 0xf,0x41,0x64, 0xf,0x41,0x65, 0xf,0x41,0x66, + 0xf,0x41,0x67, 0xf,0x41,0x69, 0xf,0x48,0x30, 0x6,0x52,0x77, + 0x6,0x52,0x7d, 0x6,0x52,0x76, 0xf,0x41,0x68, 0x5,0x3f,0x54, + 0x6,0x5d,0x36, 0x5,0x4d,0x39, 0x5,0x46,0x27, 0x5,0x46,0x2a, + 0x4,0x43,0x62, 0x4,0x43,0x5f, 0x6,0x5d,0x3c, 0x6,0x5d,0x3d, + 0x6,0x5d,0x2e, 0x4,0x43,0x57, 0x6,0x5d,0x3f, 0x5,0x46,0x26, + 0x4,0x43,0x63, 0x5,0x4d,0x38, 0x5,0x46,0x29, 0x6,0x5d,0x35, + 0x4,0x43,0x59, 0x7,0x23,0x2f, 0x4,0x43,0x5b, 0x4,0x43,0x5a, + 0x7,0x23,0x2e, 0x7,0x23,0x31, 0x5,0x46,0x24, 0x4,0x43,0x65, + 0x6,0x5d,0x39, 0x6,0x5d,0x3e, 0x6,0x5d,0x3a, 0x5,0x46,0x28, + 0x6,0x5d,0x37, 0x5,0x46,0x2b, 0x7,0x23,0x2c, 0x6,0x5d,0x3b, + 0x6,0x5d,0x33, 0x6,0x5d,0x31, 0x5,0x46,0x22, 0x4,0x43,0x60, + 0x6,0x5d,0x2f, 0x6,0x5d,0x34, 0xf,0x48,0x2b, 0xf,0x48,0x2c, + 0xf,0x48,0x2d, 0xf,0x48,0x2e, 0xf,0x48,0x2f, 0xf,0x48,0x33, + 0xf,0x48,0x34, 0xf,0x48,0x35, 0xf,0x48,0x37, 0xf,0x48,0x38, + 0xf,0x48,0x3a, 0xf,0x48,0x3b, 0xf,0x48,0x39, 0xf,0x48,0x3c, + 0xf,0x48,0x3d, 0xf,0x48,0x3e, 0xf,0x48,0x3f, 0xf,0x48,0x40, + 0xf,0x48,0x41, 0xf,0x48,0x42, 0xf,0x48,0x43, 0xf,0x48,0x44, + 0xf,0x48,0x45, 0xf,0x48,0x47, 0xf,0x48,0x48, 0xf,0x48,0x49, + 0xf,0x48,0x46, 0x6,0x5d,0x30, 0xf,0x48,0x36, 0x7,0x23,0x33, + 0x7,0x23,0x38, 0x5,0x4d,0x3c, 0x4,0x4a,0x25, 0x7,0x23,0x3d, + 0x7,0x23,0x37, 0x7,0x23,0x39, 0x4,0x49,0x7b, 0x4,0x49,0x78, + 0x5,0x4d,0x3d, 0x5,0x4d,0x3b, 0x7,0x23,0x45, 0x4,0x49,0x7d, + 0x7,0x2e,0x2f, 0x4,0x4a,0x21, 0x5,0x4d,0x41, 0x4,0x4a,0x26, + 0x4,0x49,0x7c, 0x5,0x54,0x59, 0x7,0x2e,0x3c, 0x7,0x23,0x35, + 0x7,0x23,0x34, 0x7,0x2e,0x2d, 0x7,0x2e,0x2b, 0x7,0x23,0x44, + 0x7,0x2e,0x2c, 0x7,0x23,0x3c, 0x5,0x4d,0x40, 0x7,0x2e,0x2e, + 0x5,0x4d,0x3f, 0x7,0x23,0x3b, 0x7,0x23,0x42, 0x7,0x23,0x43, + 0x7,0x23,0x3e, 0x7,0x23,0x41, 0x4,0x49,0x77, 0xf,0x48,0x31, + 0x7,0x23,0x32, 0x7,0x23,0x3f, 0x7,0x23,0x40, 0xf,0x4e,0x7c, + 0xf,0x4e,0x7d, 0xf,0x4e,0x7e, 0xf,0x4f,0x21, 0xf,0x4f,0x22, + 0xf,0x4f,0x23, 0xf,0x4f,0x26, 0xf,0x4f,0x27, 0xf,0x4f,0x28, + 0xf,0x4f,0x29, 0xf,0x4f,0x2a, 0xf,0x4f,0x2b, 0xf,0x4f,0x2d, + 0xf,0x4f,0x2e, 0xf,0x4f,0x2f, 0xf,0x4f,0x30, 0xf,0x54,0x5f, + 0xf,0x4f,0x24, 0x4,0x56,0x38, 0x4,0x50,0x41, 0x7,0x2e,0x35, + 0x7,0x2e,0x30, 0x5,0x54,0x5a, 0x5,0x54,0x5b, 0x7,0x2e,0x3e, + 0x7,0x2e,0x3a, 0x7,0x2e,0x32, 0x7,0x23,0x36, 0x4,0x50,0x3e, + 0x4,0x50,0x43, 0x4,0x50,0x40, 0x5,0x54,0x5d, 0x4,0x50,0x3f, + 0x7,0x2e,0x3d, 0x4,0x50,0x46, 0x7,0x2e,0x3b, 0x4,0x50,0x48, + 0x4,0x50,0x42, 0x4,0x50,0x47, 0x7,0x2e,0x39, 0x7,0x2e,0x31, + 0x7,0x2e,0x40, 0x7,0x38,0x29, 0x7,0x2e,0x38, 0x5,0x54,0x5f, + 0x5,0x54,0x5c, 0x7,0x2e,0x37, 0x7,0x38,0x28, 0x7,0x2e,0x33, + 0x7,0x2e,0x3f, 0xf,0x54,0x55, 0xf,0x54,0x56, 0xf,0x54,0x57, + 0xf,0x54,0x58, 0xf,0x54,0x59, 0xf,0x54,0x5a, 0xf,0x54,0x5b, + 0xf,0x54,0x5c, 0xf,0x54,0x5d, 0xf,0x54,0x5e, 0xf,0x54,0x60, + 0x7,0x2e,0x34, 0x7,0x2e,0x36, 0x4,0x50,0x44, 0xf,0x54,0x54, + 0x5,0x5b,0x56, 0x7,0x38,0x31, 0x5,0x5b,0x57, 0x7,0x38,0x36, + 0x4,0x56,0x3b, 0x7,0x38,0x2f, 0x7,0x38,0x35, 0x4,0x56,0x3a, + 0x7,0x38,0x34, 0x7,0x38,0x2c, 0x5,0x5b,0x58, 0x4,0x56,0x37, + 0x5,0x5b,0x55, 0x7,0x38,0x2a, 0x7,0x38,0x37, 0x7,0x38,0x30, + 0x7,0x38,0x2e, 0x7,0x38,0x32, 0x7,0x38,0x38, 0x7,0x38,0x2b, + 0x7,0x38,0x2d, 0xf,0x5a,0x30, 0xf,0x5a,0x31, 0xf,0x5a,0x32, + 0xf,0x5a,0x33, 0xf,0x5a,0x34, 0xf,0x5a,0x35, 0x7,0x38,0x33, + 0x4,0x5b,0x33, 0x4,0x5b,0x38, 0x5,0x61,0x6e, 0x5,0x61,0x6b, + 0x5,0x61,0x6c, 0x5,0x61,0x6d, 0x7,0x3f,0x68, 0x7,0x3f,0x67, + 0x4,0x5b,0x35, 0x4,0x5b,0x37, 0x5,0x67,0x7a, 0x5,0x6c,0x2d, + 0x7,0x3f,0x69, 0x7,0x3f,0x66, 0x4,0x5b,0x34, 0x7,0x3f,0x63, + 0x7,0x3f,0x65, 0x7,0x47,0x2f, 0x7,0x3f,0x61, 0x7,0x3f,0x64, + 0xf,0x5e,0x68, 0xf,0x5e,0x69, 0xf,0x5e,0x6a, 0xf,0x5e,0x6d, + 0xf,0x5e,0x6e, 0xf,0x5e,0x6f, 0xf,0x5e,0x71, 0xf,0x5e,0x72, + 0xf,0x5e,0x74, 0xf,0x5e,0x6c, 0xf,0x5e,0x6b, 0x4,0x5f,0x66, + 0x4,0x5f,0x68, 0x4,0x5f,0x67, 0x4,0x5f,0x69, 0x5,0x6c,0x2f, + 0x7,0x47,0x32, 0x7,0x47,0x34, 0x7,0x47,0x36, 0x5,0x67,0x7b, + 0x7,0x47,0x30, 0x5,0x6c,0x2e, 0x7,0x47,0x38, 0x4,0x5f,0x6b, + 0x7,0x47,0x35, 0x7,0x47,0x33, 0x7,0x47,0x31, 0x4,0x5f,0x6a, + 0x5,0x67,0x79, 0xf,0x62,0x3e, 0xf,0x62,0x3f, 0xf,0x62,0x40, + 0xf,0x62,0x41, 0xf,0x62,0x42, 0xf,0x62,0x43, 0xf,0x62,0x44, + 0xf,0x62,0x45, 0xf,0x62,0x46, 0xf,0x62,0x49, 0xf,0x65,0x2f, + 0x7,0x3f,0x6a, 0x7,0x47,0x37, 0xf,0x62,0x47, 0x5,0x6c,0x32, + 0x4,0x66,0x3f, 0x7,0x4d,0x6d, 0x4,0x63,0x48, 0x7,0x4d,0x6c, + 0x4,0x63,0x49, 0x7,0x4d,0x70, 0x4,0x63,0x4a, 0x7,0x4d,0x6e, + 0x5,0x6c,0x33, 0x5,0x6c,0x30, 0x5,0x6c,0x31, 0x7,0x4d,0x6f, + 0xf,0x65,0x2d, 0xf,0x65,0x2e, 0xf,0x65,0x30, 0x7,0x53,0x44, + 0x7,0x57,0x77, 0x4,0x66,0x41, 0x7,0x53,0x3f, 0x7,0x53,0x43, + 0x7,0x53,0x42, 0x4,0x66,0x42, 0x5,0x73,0x45, 0x7,0x53,0x41, + 0x7,0x53,0x40, 0xf,0x67,0x56, 0xf,0x67,0x57, 0xf,0x67,0x58, + 0xf,0x67,0x59, 0x7,0x57,0x78, 0x7,0x57,0x79, 0x5,0x73,0x44, + 0x5,0x73,0x47, 0x5,0x70,0x23, 0x7,0x57,0x7a, 0x5,0x73,0x42, + 0x5,0x73,0x46, 0x7,0x57,0x7c, 0x7,0x5b,0x57, 0x7,0x53,0x3e, + 0xf,0x69,0x43, 0xf,0x69,0x44, 0x5,0x73,0x43, 0x7,0x57,0x7b, + 0x7,0x5b,0x58, 0xf,0x6a,0x54, 0xf,0x6a,0x55, 0xf,0x6a,0x56, + 0x7,0x5e,0x6a, 0x5,0x77,0x5d, 0x7,0x5e,0x69, 0x4,0x6b,0x6b, + 0x7,0x5e,0x6b, 0x5,0x77,0x5c, 0x7,0x5e,0x68, 0xf,0x6b,0x49, + 0xf,0x6b,0x4a, 0xf,0x6b,0x4b, 0xf,0x6b,0x4c, 0x7,0x62,0x38, + 0xf,0x6c,0x2a, 0xf,0x6c,0x2b, 0x4,0x6d,0x73, 0x7,0x63,0x53, + 0xf,0x6c,0x61, 0x7,0x66,0x26, 0x4,0x22,0x77, 0x4,0x24,0x3d, + 0x4,0x26,0x5a, 0xf,0x27,0x31, 0xf,0x27,0x32, 0xf,0x27,0x33, + 0x6,0x31,0x58, 0x6,0x38,0x22, 0x5,0x2f,0x5c, 0x4,0x2d,0x3e, + 0x6,0x38,0x21, 0x6,0x36,0x44, 0x6,0x40,0x39, 0x6,0x40,0x38, + 0x6,0x49,0x4f, 0x6,0x49,0x4e, 0xf,0x3b,0x4c, 0xf,0x3b,0x4d, + 0x5,0x38,0x75, 0x6,0x53,0x26, 0xf,0x41,0x6a, 0x6,0x53,0x27, + 0x5,0x46,0x2d, 0x6,0x5d,0x40, 0x7,0x23,0x46, 0x7,0x23,0x47, + 0x5,0x54,0x60, 0xf,0x54,0x61, 0x7,0x38,0x3b, 0x7,0x38,0x3a, + 0x5,0x5b,0x59, 0x7,0x38,0x3c, 0x7,0x4d,0x71, 0x5,0x24,0x3f, + 0x6,0x27,0x79, 0x5,0x24,0x40, 0x6,0x27,0x7a, 0x5,0x24,0x41, + 0x6,0x27,0x78, 0x6,0x2b,0x68, 0x4,0x26,0x60, 0x5,0x26,0x42, + 0x5,0x26,0x40, 0x4,0x26,0x5d, 0x6,0x2b,0x6c, 0x6,0x2b,0x66, + 0x6,0x2b,0x6a, 0x6,0x2b,0x69, 0x6,0x2b,0x67, 0x5,0x26,0x3f, + 0x5,0x26,0x41, 0x4,0x26,0x5c, 0x4,0x29,0x60, 0x6,0x31,0x59, + 0x5,0x29,0x4c, 0x5,0x29,0x4b, 0x6,0x31,0x5c, 0x6,0x31,0x5e, + 0x6,0x31,0x5d, 0x5,0x29,0x49, 0x5,0x29,0x4a, 0x4,0x29,0x5e, + 0x4,0x29,0x5f, 0x6,0x31,0x5b, 0x6,0x38,0x23, 0x6,0x38,0x24, + 0x6,0x38,0x26, 0x5,0x2d,0x72, 0x6,0x31,0x5f, 0x4,0x2d,0x45, + 0x6,0x38,0x28, 0x5,0x2d,0x70, 0x6,0x38,0x2a, 0x5,0x2d,0x6f, + 0x5,0x2d,0x74, 0x6,0x38,0x25, 0x5,0x2d,0x73, 0x5,0x2d,0x71, + 0x6,0x38,0x29, 0x6,0x38,0x27, 0x4,0x2d,0x41, 0x5,0x32,0x6d, + 0x6,0x40,0x40, 0x4,0x32,0x2e, 0x6,0x40,0x3a, 0x6,0x40,0x3b, + 0x6,0x40,0x3d, 0x5,0x32,0x6f, 0x5,0x32,0x70, 0x4,0x32,0x30, + 0x6,0x40,0x3e, 0x6,0x40,0x3c, 0x5,0x32,0x6b, 0x6,0x40,0x41, + 0x4,0x32,0x31, 0x4,0x32,0x2a, 0x4,0x32,0x2d, 0x4,0x32,0x29, + 0x5,0x32,0x6e, 0xf,0x35,0x31, 0xf,0x35,0x32, 0xf,0x35,0x33, + 0xf,0x35,0x34, 0xf,0x35,0x35, 0x5,0x32,0x6a, 0x6,0x40,0x3f, + 0x6,0x49,0x58, 0x5,0x39,0x22, 0x6,0x49,0x55, 0x4,0x37,0x7a, + 0x4,0x37,0x7b, 0x6,0x49,0x59, 0x6,0x49,0x54, 0x6,0x49,0x5a, + 0x5,0x38,0x76, 0x5,0x38,0x7e, 0x5,0x39,0x21, 0x5,0x38,0x7d, + 0x5,0x38,0x77, 0x6,0x49,0x56, 0x5,0x38,0x7b, 0x6,0x49,0x51, + 0x6,0x49,0x50, 0x6,0x49,0x53, 0x4,0x37,0x72, 0x4,0x37,0x73, + 0x4,0x37,0x74, 0x5,0x38,0x78, 0x5,0x38,0x79, 0x5,0x32,0x6c, + 0x6,0x49,0x52, 0x6,0x53,0x2f, 0x5,0x38,0x7a, 0x5,0x3f,0x57, + 0x5,0x3f,0x5a, 0x5,0x3f,0x5c, 0x4,0x3d,0x57, 0x4,0x3d,0x5f, + 0x6,0x53,0x2b, 0x6,0x53,0x2e, 0x6,0x53,0x29, 0x5,0x3f,0x5b, + 0x6,0x53,0x30, 0x6,0x53,0x2d, 0x6,0x53,0x28, 0x4,0x3d,0x60, + 0x5,0x3f,0x56, 0x6,0x53,0x31, 0x5,0x3f,0x59, 0x4,0x3d,0x5e, + 0x4,0x3d,0x55, 0x4,0x3d,0x56, 0x4,0x3d,0x58, 0x5,0x3f,0x58, + 0x6,0x53,0x2a, 0xf,0x41,0x6b, 0x6,0x53,0x2c, 0x5,0x32,0x71, + 0x4,0x3d,0x5a, 0x6,0x55,0x60, 0x5,0x46,0x34, 0x6,0x5d,0x49, + 0x5,0x46,0x32, 0x6,0x5d,0x41, 0x4,0x43,0x68, 0x5,0x46,0x31, + 0x6,0x5d,0x42, 0x5,0x46,0x2f, 0x6,0x5d,0x46, 0x5,0x46,0x37, + 0x5,0x46,0x35, 0x6,0x5d,0x47, 0x6,0x5d,0x45, 0x6,0x5d,0x44, + 0x6,0x5d,0x48, 0x6,0x5d,0x43, 0x6,0x5d,0x4a, 0x5,0x46,0x33, + 0x4,0x43,0x67, 0x5,0x46,0x36, 0x6,0x5d,0x4b, 0x5,0x48,0x25, + 0x5,0x4d,0x42, 0x5,0x4d,0x47, 0x4,0x4a,0x2c, 0x7,0x23,0x4e, + 0x7,0x23,0x49, 0x7,0x23,0x48, 0x5,0x4d,0x46, 0x7,0x23,0x52, + 0x7,0x23,0x4f, 0x7,0x23,0x4d, 0x5,0x4d,0x45, 0x7,0x23,0x50, + 0x5,0x4d,0x43, 0x5,0x4d,0x44, 0xf,0x4f,0x31, 0x7,0x23,0x4b, + 0x7,0x23,0x4c, 0x7,0x23,0x4a, 0x4,0x50,0x4b, 0x7,0x2e,0x42, + 0x7,0x2e,0x46, 0x7,0x2e,0x48, 0xf,0x54,0x62, 0x5,0x54,0x61, + 0x7,0x2e,0x4b, 0x7,0x2e,0x47, 0x7,0x2e,0x49, 0x7,0x2e,0x41, + 0x7,0x2e,0x45, 0x7,0x2e,0x4c, 0x5,0x54,0x63, 0x7,0x2e,0x4a, + 0x4,0x50,0x4a, 0x5,0x54,0x64, 0x5,0x54,0x65, 0x5,0x54,0x66, + 0xf,0x54,0x63, 0x7,0x2e,0x44, 0x5,0x54,0x62, 0x7,0x23,0x51, + 0x5,0x54,0x67, 0x7,0x38,0x3e, 0x7,0x38,0x3d, 0x5,0x5b,0x5a, + 0x5,0x5b,0x5e, 0x5,0x5b,0x5d, 0x4,0x56,0x3c, 0x4,0x56,0x3d, + 0x5,0x5b,0x5b, 0xf,0x5a,0x37, 0xf,0x5a,0x38, 0x7,0x38,0x3f, + 0x5,0x5b,0x5c, 0x5,0x61,0x70, 0x7,0x3f,0x6c, 0x5,0x61,0x6f, + 0x4,0x5b,0x3b, 0x7,0x3f,0x6d, 0x7,0x3f,0x6e, 0x4,0x5b,0x39, + 0x7,0x3f,0x6b, 0x5,0x68,0x21, 0x5,0x67,0x7e, 0x5,0x67,0x7c, + 0x5,0x67,0x7d, 0xf,0x62,0x4a, 0x5,0x6c,0x34, 0x4,0x63,0x4d, + 0x5,0x6c,0x35, 0x7,0x4d,0x72, 0x4,0x63,0x4b, 0x7,0x4d,0x75, + 0x7,0x4d,0x74, 0x5,0x6c,0x36, 0x7,0x4d,0x76, 0x7,0x4d,0x77, + 0x4,0x66,0x44, 0x5,0x70,0x25, 0x5,0x70,0x26, 0x5,0x73,0x48, + 0xf,0x69,0x45, 0x7,0x5b,0x59, 0x5,0x75,0x6b, 0x4,0x6a,0x4a, + 0x7,0x5b,0x5a, 0x4,0x6c,0x6f, 0xf,0x6c,0x62, 0xf,0x22,0x53, + 0xf,0x24,0x46, 0x6,0x2b,0x6d, 0xf,0x2b,0x2d, 0xf,0x2b,0x2e, + 0xf,0x2b,0x2f, 0x6,0x38,0x2d, 0x6,0x38,0x2e, 0xf,0x2f,0x65, + 0x6,0x40,0x42, 0x6,0x40,0x44, 0xf,0x35,0x37, 0xf,0x35,0x38, + 0x6,0x40,0x43, 0xf,0x3b,0x4e, 0x5,0x3f,0x5d, 0xf,0x41,0x6c, + 0x6,0x53,0x32, 0xf,0x35,0x36, 0x5,0x4d,0x48, 0x7,0x23,0x54, + 0x7,0x23,0x53, 0x5,0x4d,0x49, 0xf,0x4f,0x33, 0xf,0x4f,0x34, + 0x5,0x4d,0x4a, 0x7,0x2e,0x4d, 0xf,0x5a,0x39, 0xf,0x5e,0x75, + 0xf,0x62,0x4b, 0xf,0x67,0x5a, 0x7,0x5b,0x5b, 0x6,0x22,0x22, + 0xf,0x27,0x34, 0x6,0x31,0x60, 0x4,0x2d,0x48, 0x5,0x2d,0x76, + 0x5,0x2d,0x75, 0x6,0x38,0x2f, 0x5,0x32,0x72, 0xf,0x35,0x39, + 0x6,0x40,0x46, 0x6,0x40,0x45, 0x6,0x49,0x5d, 0xf,0x40,0x32, + 0x6,0x49,0x5b, 0x6,0x49,0x5c, 0x4,0x3d,0x61, 0x6,0x5d,0x4c, + 0x5,0x3f,0x5e, 0xf,0x41,0x6d, 0x4,0x43,0x6a, 0x4,0x4a,0x2d, + 0x7,0x23,0x55, 0x7,0x38,0x40, 0x4,0x5f,0x6c, 0x6,0x22,0x23, + 0xf,0x24,0x47, 0x6,0x2b,0x6f, 0x6,0x2b,0x6e, 0x6,0x31,0x61, + 0xf,0x2f,0x66, 0x4,0x32,0x32, 0x6,0x40,0x48, 0x6,0x40,0x47, + 0x6,0x49,0x60, 0x6,0x49,0x64, 0x6,0x49,0x63, 0x5,0x39,0x23, + 0x6,0x49,0x66, 0x6,0x49,0x5f, 0x6,0x49,0x5e, 0x6,0x49,0x62, + 0x4,0x37,0x7c, 0x6,0x4c,0x3e, 0x6,0x49,0x65, 0x4,0x3d,0x62, + 0x6,0x53,0x36, 0x6,0x53,0x34, 0x6,0x53,0x37, 0x5,0x3f,0x5f, + 0x6,0x5d,0x4f, 0x6,0x5d,0x4e, 0x6,0x5d,0x50, 0x3,0x47,0x31, + 0x4,0x4a,0x2f, 0x6,0x5d,0x4d, 0x5,0x4d,0x4c, 0x5,0x4d,0x4d, + 0x7,0x2e,0x51, 0x7,0x2e,0x50, 0x7,0x2e,0x4f, 0x7,0x2e,0x52, + 0x7,0x2e,0x4e, 0x4,0x50,0x4d, 0x7,0x38,0x41, 0x7,0x38,0x42, + 0x7,0x3f,0x6f, 0x4,0x5b,0x3c, 0x7,0x3f,0x70, 0x7,0x3f,0x71, + 0x7,0x47,0x39, 0xf,0x62,0x4c, 0x7,0x4d,0x78, 0x7,0x57,0x7d, + 0x4,0x24,0x42, 0x6,0x27,0x7b, 0xf,0x27,0x35, 0xf,0x27,0x36, + 0x5,0x29,0x4d, 0x6,0x31,0x64, 0x6,0x31,0x63, 0xf,0x2b,0x30, + 0x6,0x31,0x62, 0x4,0x2d,0x4a, 0x5,0x2d,0x77, 0x6,0x38,0x31, + 0x6,0x38,0x33, 0x6,0x38,0x35, 0xf,0x2f,0x67, 0xf,0x2f,0x68, + 0xf,0x2f,0x69, 0xf,0x2f,0x6a, 0x6,0x38,0x32, 0x4,0x32,0x33, + 0x4,0x32,0x35, 0x6,0x40,0x4a, 0xf,0x35,0x3a, 0xf,0x35,0x3b, + 0x6,0x40,0x49, 0x6,0x49,0x69, 0x5,0x39,0x25, 0x5,0x39,0x24, + 0x6,0x49,0x68, 0x6,0x49,0x6a, 0x6,0x49,0x67, 0xf,0x3b,0x4f, + 0xf,0x3b,0x50, 0x6,0x53,0x38, 0x5,0x3f,0x60, 0x6,0x53,0x39, + 0xf,0x41,0x6e, 0xf,0x41,0x6f, 0x5,0x46,0x38, 0x5,0x46,0x3a, + 0x6,0x5d,0x52, 0x5,0x46,0x39, 0x7,0x23,0x56, 0xf,0x4f,0x35, + 0x7,0x2e,0x53, 0x5,0x54,0x68, 0x7,0x38,0x43, 0x5,0x5b,0x5f, + 0x7,0x3f,0x73, 0x5,0x61,0x71, 0x4,0x5b,0x3d, 0x7,0x3f,0x74, + 0x7,0x3f,0x72, 0x7,0x47,0x3a, 0x7,0x53,0x45, 0x4,0x68,0x6d, + 0x7,0x57,0x7e, 0x7,0x5e,0x6c, 0x7,0x60,0x70, 0x5,0x24,0x42, + 0x5,0x29,0x4e, 0x5,0x2d,0x79, 0x5,0x2d,0x78, 0x4,0x37,0x7d, + 0x6,0x49,0x6b, 0x6,0x53,0x3a, 0x6,0x53,0x3b, 0x4,0x3d,0x66, + 0xf,0x4f,0x36, 0x6,0x23,0x2c, 0x6,0x23,0x2b, 0x6,0x24,0x7b, + 0x5,0x22,0x73, 0x6,0x24,0x7a, 0x6,0x24,0x7c, 0xf,0x22,0x54, + 0xf,0x24,0x4b, 0x6,0x27,0x7c, 0x6,0x27,0x7d, 0x6,0x28,0x25, + 0x5,0x24,0x43, 0x6,0x28,0x22, 0x6,0x27,0x7e, 0x6,0x28,0x24, + 0x6,0x28,0x23, 0x6,0x28,0x21, 0xf,0x24,0x48, 0xf,0x24,0x4a, + 0xf,0x24,0x4c, 0x4,0x24,0x44, 0x5,0x26,0x48, 0x6,0x2b,0x74, + 0x6,0x2b,0x73, 0x5,0x26,0x49, 0x6,0x2b,0x7d, 0x5,0x26,0x44, + 0x6,0x2b,0x79, 0x5,0x26,0x47, 0x6,0x2b,0x7a, 0x6,0x2b,0x77, + 0x5,0x26,0x46, 0x5,0x26,0x45, 0x6,0x2b,0x75, 0x6,0x2b,0x78, + 0xf,0x27,0x37, 0xf,0x27,0x38, 0xf,0x27,0x39, 0xf,0x27,0x3a, + 0xf,0x27,0x3b, 0xf,0x27,0x3c, 0xf,0x27,0x3d, 0x6,0x2b,0x71, + 0x6,0x2b,0x7b, 0x6,0x2b,0x7c, 0x6,0x2b,0x72, 0x6,0x2b,0x76, + 0x5,0x29,0x51, 0x6,0x31,0x65, 0x6,0x31,0x66, 0x5,0x29,0x50, + 0x4,0x29,0x66, 0x6,0x31,0x68, 0x6,0x31,0x69, 0x4,0x29,0x68, + 0xf,0x2b,0x31, 0xf,0x2b,0x32, 0x6,0x31,0x6a, 0xf,0x2b,0x35, + 0xf,0x2b,0x36, 0x6,0x31,0x6e, 0x6,0x31,0x6c, 0x6,0x31,0x6b, + 0x5,0x2d,0x7e, 0x6,0x38,0x3a, 0x5,0x2e,0x21, 0x5,0x2e,0x22, + 0x5,0x2d,0x7b, 0x5,0x2e,0x23, 0x5,0x2d,0x7c, 0x5,0x2d,0x7a, + 0x6,0x38,0x3e, 0x6,0x38,0x38, 0x6,0x38,0x3c, 0x5,0x2d,0x7d, + 0x6,0x38,0x39, 0x6,0x38,0x3d, 0xf,0x2f,0x6b, 0xf,0x2f,0x6d, + 0x6,0x38,0x3b, 0xf,0x2f,0x6c, 0x6,0x38,0x41, 0x6,0x38,0x3f, + 0x5,0x32,0x73, 0x4,0x32,0x38, 0x4,0x38,0x21, 0x6,0x40,0x53, + 0x4,0x32,0x3d, 0x6,0x40,0x4e, 0x6,0x40,0x4b, 0x6,0x40,0x4c, + 0x6,0x40,0x50, 0x6,0x40,0x4d, 0x6,0x40,0x55, 0x5,0x32,0x75, + 0x6,0x38,0x40, 0x6,0x40,0x54, 0x6,0x40,0x56, 0xf,0x35,0x3c, + 0xf,0x35,0x3d, 0xf,0x35,0x3e, 0xf,0x35,0x3f, 0xf,0x35,0x40, + 0xf,0x35,0x41, 0xf,0x35,0x42, 0xf,0x35,0x43, 0xf,0x35,0x44, + 0xf,0x35,0x45, 0xf,0x35,0x46, 0xf,0x35,0x47, 0x6,0x40,0x52, + 0x5,0x32,0x74, 0x6,0x49,0x71, 0x6,0x49,0x74, 0x4,0x32,0x3c, + 0x5,0x3f,0x61, 0x5,0x39,0x2a, 0x6,0x49,0x6f, 0x5,0x39,0x27, + 0x6,0x49,0x70, 0x5,0x39,0x29, 0x5,0x39,0x26, 0x6,0x49,0x6c, + 0x6,0x49,0x6d, 0x4,0x38,0x23, 0x6,0x49,0x76, 0x5,0x39,0x2b, + 0x4,0x38,0x27, 0x6,0x49,0x6e, 0x6,0x49,0x75, 0x6,0x49,0x77, + 0xf,0x3b,0x51, 0xf,0x3b,0x53, 0xf,0x3b,0x54, 0xf,0x3b,0x56, + 0xf,0x3b,0x57, 0xf,0x3b,0x59, 0xf,0x3b,0x5a, 0xf,0x3b,0x5c, + 0xf,0x3b,0x5d, 0xf,0x3b,0x52, 0xf,0x3b,0x58, 0x4,0x38,0x26, + 0x4,0x38,0x28, 0x6,0x49,0x72, 0x5,0x39,0x2c, 0x5,0x39,0x28, + 0x6,0x53,0x43, 0x5,0x3f,0x63, 0x6,0x53,0x41, 0x6,0x5d,0x53, + 0x6,0x53,0x42, 0x6,0x53,0x3f, 0x6,0x53,0x44, 0xf,0x46,0x39, + 0xf,0x3b,0x5b, 0x6,0x53,0x3e, 0xf,0x41,0x70, 0xf,0x41,0x71, + 0xf,0x41,0x73, 0xf,0x41,0x74, 0xf,0x41,0x75, 0xf,0x41,0x76, + 0xf,0x41,0x77, 0xf,0x41,0x78, 0xf,0x41,0x79, 0xf,0x41,0x7a, + 0xf,0x41,0x7b, 0xf,0x41,0x7d, 0x5,0x3d,0x55, 0x6,0x53,0x45, + 0x6,0x53,0x40, 0x5,0x3f,0x64, 0x5,0x46,0x3b, 0x5,0x46,0x3f, + 0x5,0x46,0x3d, 0x5,0x46,0x3e, 0x6,0x5d,0x56, 0x5,0x46,0x40, + 0x5,0x46,0x43, 0x5,0x46,0x44, 0x4,0x43,0x6c, 0x5,0x46,0x42, + 0x5,0x4d,0x4e, 0xf,0x48,0x4a, 0xf,0x48,0x4b, 0xf,0x48,0x4c, + 0xf,0x48,0x4d, 0xf,0x48,0x4e, 0xf,0x48,0x4f, 0x6,0x5d,0x54, + 0x5,0x46,0x3c, 0x6,0x5d,0x57, 0x6,0x5d,0x59, 0x6,0x5d,0x5a, + 0x6,0x5d,0x55, 0x6,0x5d,0x58, 0x7,0x23,0x61, 0x7,0x23,0x5c, + 0x7,0x23,0x5b, 0x7,0x23,0x5e, 0x5,0x4d,0x52, 0x5,0x4d,0x55, + 0x7,0x23,0x5a, 0x7,0x23,0x57, 0x7,0x23,0x58, 0x7,0x23,0x62, + 0xf,0x4f,0x37, 0xf,0x4f,0x39, 0xf,0x4f,0x3a, 0x5,0x4d,0x54, + 0x7,0x23,0x60, 0xf,0x4e,0x30, 0x7,0x23,0x5d, 0x7,0x23,0x5f, + 0x7,0x23,0x59, 0x5,0x4d,0x51, 0x5,0x54,0x69, 0x5,0x54,0x6b, + 0x7,0x2e,0x57, 0x4,0x50,0x55, 0x7,0x2e,0x55, 0x7,0x2e,0x5b, + 0x7,0x2e,0x59, 0x7,0x2e,0x5d, 0x4,0x50,0x54, 0x7,0x2e,0x5c, + 0x7,0x2e,0x54, 0xf,0x54,0x65, 0xf,0x54,0x66, 0xf,0x54,0x67, + 0xf,0x54,0x69, 0xf,0x54,0x6a, 0x7,0x2e,0x58, 0x5,0x4d,0x4f, + 0x7,0x2d,0x62, 0xf,0x54,0x68, 0x7,0x2e,0x43, 0x5,0x54,0x6a, + 0x7,0x2e,0x56, 0xf,0x4f,0x38, 0x7,0x38,0x47, 0x5,0x5b,0x60, + 0x5,0x5b,0x61, 0x7,0x38,0x48, 0x5,0x5b,0x62, 0x7,0x38,0x45, + 0x7,0x38,0x46, 0x7,0x38,0x49, 0xf,0x5a,0x3a, 0xf,0x5a,0x3b, + 0xf,0x5a,0x3c, 0x7,0x38,0x44, 0xf,0x5a,0x3d, 0x4,0x5b,0x3e, + 0x5,0x61,0x72, 0x5,0x61,0x73, 0x7,0x3f,0x75, 0xf,0x5e,0x76, + 0xf,0x5e,0x77, 0xf,0x5e,0x78, 0xf,0x5e,0x79, 0xf,0x5e,0x7b, + 0x7,0x3f,0x78, 0x5,0x68,0x23, 0x7,0x47,0x3d, 0x7,0x47,0x3c, + 0x5,0x68,0x22, 0x5,0x68,0x24, 0x7,0x47,0x3b, 0x7,0x47,0x3e, + 0xf,0x62,0x4d, 0x5,0x6c,0x37, 0xf,0x65,0x31, 0xf,0x65,0x32, + 0x5,0x6b,0x6e, 0x7,0x4d,0x79, 0x7,0x53,0x46, 0x7,0x58,0x21, + 0xf,0x69,0x46, 0x5,0x73,0x39, 0x5,0x73,0x49, 0x7,0x5b,0x5c, + 0x5,0x77,0x5e, 0x7,0x5e,0x6d, 0xf,0x6b,0x4d, 0x5,0x79,0x2b, + 0x7,0x64,0x47, 0xf,0x24,0x4d, 0x6,0x2b,0x7e, 0xf,0x27,0x3f, + 0xf,0x27,0x40, 0x6,0x2c,0x21, 0x5,0x29,0x53, 0x5,0x29,0x52, + 0x6,0x31,0x70, 0xf,0x2b,0x37, 0xf,0x2b,0x39, 0x6,0x31,0x6f, + 0x6,0x38,0x42, 0xf,0x2f,0x6f, 0xf,0x2f,0x70, 0xf,0x2f,0x71, + 0xf,0x2f,0x72, 0xf,0x2f,0x73, 0xf,0x35,0x49, 0xf,0x35,0x4a, + 0xf,0x3b,0x5f, 0x6,0x49,0x7a, 0x6,0x49,0x79, 0x5,0x3f,0x65, + 0x4,0x43,0x70, 0x6,0x53,0x46, 0x5,0x4d,0x57, 0x5,0x4d,0x56, + 0x7,0x23,0x63, 0xf,0x54,0x6b, 0x5,0x5b,0x63, 0x7,0x3f,0x7a, + 0x5,0x61,0x74, 0x7,0x3f,0x79, 0x7,0x3f,0x77, 0x4,0x5f,0x6d, + 0x7,0x4d,0x7a, 0x7,0x4d,0x7b, 0x5,0x7b,0x3f, 0x7,0x66,0x3e, + 0x6,0x23,0x2d, 0x6,0x24,0x7d, 0x5,0x24,0x44, 0x6,0x28,0x29, + 0x6,0x28,0x27, 0x6,0x28,0x28, 0x6,0x28,0x26, 0x6,0x2c,0x22, + 0x5,0x29,0x54, 0x4,0x29,0x69, 0x4,0x29,0x6a, 0xf,0x2b,0x3a, + 0x6,0x31,0x71, 0x6,0x38,0x43, 0xf,0x35,0x4b, 0x5,0x32,0x76, + 0x6,0x40,0x59, 0x6,0x40,0x5b, 0x6,0x49,0x7d, 0x6,0x49,0x7c, + 0x6,0x40,0x5a, 0x5,0x39,0x2d, 0xf,0x39,0x46, 0xf,0x3b,0x61, + 0xf,0x3b,0x62, 0x6,0x53,0x47, 0x5,0x3f,0x67, 0xf,0x3b,0x60, + 0xf,0x41,0x7e, 0xf,0x42,0x21, 0x6,0x53,0x48, 0x6,0x5d,0x5d, + 0x6,0x5d,0x5e, 0x7,0x23,0x64, 0x4,0x4a,0x34, 0x5,0x4d,0x59, + 0x4,0x4a,0x33, 0xf,0x4f,0x3b, 0xf,0x4f,0x3c, 0x5,0x54,0x6e, + 0x5,0x54,0x6c, 0x5,0x5b,0x64, 0x5,0x54,0x6d, 0xf,0x54,0x6d, + 0xf,0x54,0x6e, 0x7,0x38,0x4b, 0x7,0x38,0x4a, 0xf,0x5a,0x3e, + 0x5,0x61,0x75, 0xf,0x5e,0x7c, 0x7,0x3f,0x7b, 0x5,0x6c,0x38, + 0x5,0x75,0x6f, 0x5,0x77,0x5f, 0x5,0x21,0x48, 0x4,0x21,0x4e, + 0x4,0x21,0x7d, 0xf,0x21,0x65, 0x5,0x22,0x75, 0x6,0x25,0x22, + 0x5,0x22,0x74, 0x6,0x24,0x7e, 0x6,0x25,0x21, 0xf,0x22,0x56, + 0x4,0x22,0x7b, 0x4,0x22,0x7a, 0x6,0x28,0x2c, 0x4,0x24,0x49, + 0x6,0x28,0x2a, 0x6,0x28,0x2b, 0xf,0x24,0x4e, 0xf,0x24,0x4f, + 0xf,0x24,0x54, 0xf,0x24,0x50, 0xf,0x24,0x52, 0x5,0x24,0x46, + 0x6,0x28,0x2d, 0x5,0x24,0x45, 0x4,0x24,0x45, 0x4,0x26,0x6b, + 0x5,0x26,0x4c, 0x4,0x26,0x66, 0x5,0x26,0x4b, 0x6,0x2c,0x2b, + 0x5,0x26,0x50, 0x5,0x26,0x52, 0x6,0x2c,0x28, 0x6,0x2c,0x27, + 0x6,0x2c,0x26, 0x5,0x26,0x4d, 0x5,0x26,0x53, 0x5,0x26,0x4f, + 0x5,0x26,0x4e, 0xf,0x27,0x43, 0xf,0x27,0x45, 0xf,0x27,0x46, + 0xf,0x27,0x47, 0xf,0x27,0x49, 0xf,0x27,0x4a, 0xf,0x27,0x4b, + 0xf,0x27,0x4d, 0xf,0x27,0x4f, 0xf,0x27,0x51, 0xf,0x27,0x54, + 0xf,0x27,0x55, 0x6,0x2c,0x24, 0x6,0x2c,0x29, 0x5,0x26,0x54, + 0x6,0x2c,0x2c, 0xf,0x27,0x44, 0x6,0x2c,0x2d, 0x6,0x2c,0x2a, + 0xf,0x27,0x48, 0xf,0x27,0x42, 0x6,0x2c,0x25, 0x5,0x26,0x55, + 0x6,0x2d,0x5c, 0x6,0x31,0x74, 0x6,0x31,0x73, 0x4,0x29,0x6b, + 0x5,0x29,0x56, 0x6,0x31,0x75, 0x6,0x31,0x76, 0x5,0x29,0x55, + 0x5,0x29,0x59, 0x6,0x31,0x77, 0x5,0x2e,0x26, 0x5,0x29,0x5a, + 0x5,0x29,0x58, 0xf,0x27,0x53, 0xf,0x2b,0x3b, 0xf,0x2b,0x3c, + 0xf,0x2b,0x3d, 0xf,0x2b,0x3f, 0xf,0x2b,0x40, 0xf,0x2b,0x41, + 0xf,0x2b,0x42, 0xf,0x2b,0x43, 0xf,0x2b,0x44, 0xf,0x2b,0x45, + 0xf,0x2b,0x46, 0xf,0x2b,0x47, 0xf,0x2b,0x49, 0xf,0x2b,0x4a, + 0xf,0x2b,0x4b, 0xf,0x2b,0x4c, 0xf,0x2b,0x4d, 0xf,0x2b,0x4e, + 0xf,0x2b,0x4f, 0x5,0x29,0x5b, 0x6,0x40,0x5c, 0x6,0x38,0x4f, + 0x6,0x38,0x53, 0x6,0x38,0x4b, 0x6,0x38,0x4d, 0x6,0x38,0x46, + 0x5,0x2e,0x27, 0x6,0x38,0x48, 0x6,0x38,0x45, 0x6,0x38,0x51, + 0x4,0x2d,0x50, 0x6,0x40,0x5d, 0x5,0x29,0x57, 0x5,0x2e,0x29, + 0x5,0x2e,0x2a, 0x6,0x38,0x44, 0xf,0x2f,0x74, 0xf,0x2f,0x75, + 0xf,0x2f,0x76, 0xf,0x2f,0x78, 0xf,0x2f,0x79, 0xf,0x2f,0x7a, + 0xf,0x2f,0x7b, 0xf,0x2f,0x7c, 0xf,0x2f,0x7d, 0xf,0x2f,0x7e, + 0xf,0x30,0x21, 0xf,0x30,0x22, 0xf,0x30,0x23, 0xf,0x30,0x25, + 0xf,0x30,0x26, 0xf,0x30,0x27, 0xf,0x30,0x29, 0xf,0x30,0x2a, + 0xf,0x30,0x2b, 0xf,0x30,0x2c, 0xf,0x30,0x2e, 0x6,0x38,0x4c, + 0x6,0x38,0x47, 0x6,0x38,0x49, 0x4,0x2d,0x53, 0x6,0x38,0x4e, + 0xf,0x30,0x30, 0xf,0x30,0x28, 0x4,0x2d,0x5a, 0xf,0x30,0x2d, + 0x5,0x2e,0x2c, 0x5,0x2e,0x28, 0xf,0x2f,0x77, 0x6,0x38,0x52, + 0x6,0x40,0x68, 0x6,0x40,0x69, 0x6,0x40,0x5f, 0x5,0x32,0x77, + 0x5,0x33,0x21, 0x5,0x39,0x36, 0x4,0x32,0x45, 0x4,0x32,0x40, + 0x5,0x32,0x7d, 0x6,0x40,0x67, 0x6,0x4a,0x2e, 0x6,0x40,0x63, + 0xf,0x35,0x4c, 0xf,0x35,0x4d, 0xf,0x35,0x4f, 0xf,0x35,0x50, + 0xf,0x35,0x51, 0xf,0x35,0x52, 0xf,0x35,0x53, 0xf,0x35,0x54, + 0xf,0x35,0x55, 0xf,0x35,0x56, 0xf,0x35,0x58, 0xf,0x35,0x59, + 0xf,0x35,0x5a, 0xf,0x35,0x5b, 0xf,0x35,0x5c, 0xf,0x35,0x5d, + 0xf,0x35,0x5e, 0xf,0x35,0x5f, 0xf,0x35,0x60, 0xf,0x35,0x61, + 0xf,0x35,0x62, 0xf,0x35,0x63, 0xf,0x35,0x65, 0xf,0x35,0x66, + 0x6,0x40,0x64, 0x6,0x40,0x66, 0x6,0x40,0x65, 0x4,0x32,0x47, + 0x6,0x40,0x62, 0x6,0x40,0x60, 0x6,0x40,0x61, 0x4,0x32,0x44, + 0x5,0x33,0x22, 0x5,0x32,0x78, 0x5,0x32,0x7b, 0x5,0x32,0x7a, + 0x5,0x32,0x7c, 0x6,0x40,0x6a, 0xf,0x35,0x4e, 0x6,0x40,0x5e, + 0x4,0x38,0x36, 0x6,0x4a,0x34, 0x5,0x39,0x35, 0x6,0x53,0x49, + 0x4,0x38,0x2e, 0x5,0x39,0x38, 0x6,0x4a,0x22, 0x5,0x39,0x32, + 0x4,0x38,0x2b, 0x5,0x39,0x30, 0x5,0x39,0x34, 0x4,0x38,0x31, + 0x6,0x4a,0x2d, 0x6,0x4a,0x2f, 0x5,0x39,0x3a, 0x6,0x4a,0x24, + 0x6,0x4a,0x21, 0x5,0x39,0x37, 0x6,0x4a,0x33, 0x5,0x39,0x3c, + 0x5,0x39,0x3b, 0x6,0x4a,0x26, 0x4,0x38,0x30, 0x6,0x4a,0x27, + 0x6,0x4a,0x2a, 0x6,0x4a,0x31, 0x5,0x39,0x40, 0x6,0x53,0x4a, + 0x5,0x39,0x3d, 0x6,0x4a,0x38, 0x6,0x4a,0x23, 0x6,0x4a,0x25, + 0x6,0x4a,0x35, 0x4,0x38,0x33, 0x4,0x38,0x38, 0x6,0x4a,0x36, + 0x6,0x4a,0x37, 0xf,0x3b,0x64, 0xf,0x3b,0x65, 0xf,0x3b,0x67, + 0xf,0x3b,0x68, 0xf,0x3b,0x69, 0xf,0x3b,0x6b, 0xf,0x3b,0x6c, + 0xf,0x3b,0x6d, 0xf,0x3b,0x6f, 0xf,0x3b,0x71, 0xf,0x3b,0x72, + 0xf,0x3b,0x74, 0xf,0x3b,0x75, 0xf,0x3b,0x76, 0xf,0x3b,0x77, + 0xf,0x3b,0x78, 0xf,0x3b,0x79, 0xf,0x3b,0x7a, 0xf,0x3b,0x7b, + 0xf,0x3b,0x7c, 0xf,0x3b,0x7d, 0xf,0x3b,0x7e, 0xf,0x3c,0x22, + 0xf,0x3c,0x23, 0xf,0x3c,0x24, 0xf,0x3c,0x25, 0xf,0x3c,0x26, + 0xf,0x3c,0x27, 0xf,0x3c,0x28, 0xf,0x3c,0x2a, 0xf,0x3c,0x2b, + 0xf,0x3c,0x2c, 0xf,0x3c,0x2d, 0xf,0x3c,0x2e, 0xf,0x3c,0x2f, + 0x6,0x4a,0x29, 0x6,0x4a,0x2b, 0x6,0x4a,0x2c, 0x6,0x4a,0x32, + 0x5,0x39,0x42, 0x6,0x4a,0x30, 0x6,0x4a,0x39, 0x6,0x4a,0x28, + 0x5,0x39,0x3e, 0x5,0x39,0x41, 0x5,0x39,0x2e, 0x5,0x39,0x2f, + 0x5,0x39,0x31, 0x6,0x53,0x4e, 0x6,0x53,0x58, 0x4,0x3d,0x77, + 0x6,0x53,0x56, 0x4,0x3d,0x74, 0x6,0x53,0x57, 0x5,0x3f,0x6f, + 0x5,0x3f,0x6a, 0x5,0x3f,0x6e, 0x5,0x3f,0x6b, 0x4,0x3d,0x6a, + 0x6,0x53,0x5b, 0x5,0x3f,0x73, 0x6,0x53,0x61, 0x5,0x3f,0x68, + 0x4,0x3d,0x7a, 0x5,0x3f,0x74, 0x5,0x3f,0x69, 0x6,0x53,0x55, + 0x5,0x3f,0x70, 0x5,0x3f,0x6d, 0x6,0x53,0x60, 0x4,0x3d,0x73, + 0x6,0x53,0x59, 0x6,0x53,0x5a, 0x6,0x53,0x5d, 0x6,0x53,0x50, + 0x4,0x3d,0x70, 0x6,0x53,0x5c, 0x5,0x3f,0x6c, 0x6,0x53,0x63, + 0x6,0x53,0x4f, 0x6,0x53,0x51, 0x6,0x53,0x4c, 0xf,0x42,0x23, + 0xf,0x42,0x24, 0xf,0x42,0x25, 0xf,0x42,0x26, 0xf,0x42,0x27, + 0xf,0x42,0x29, 0xf,0x42,0x2a, 0xf,0x42,0x2b, 0xf,0x42,0x2c, + 0xf,0x42,0x2d, 0xf,0x42,0x2e, 0xf,0x42,0x30, 0xf,0x42,0x31, + 0xf,0x42,0x32, 0xf,0x42,0x33, 0xf,0x42,0x34, 0xf,0x42,0x35, + 0xf,0x42,0x36, 0xf,0x42,0x38, 0xf,0x42,0x39, 0xf,0x42,0x3a, + 0xf,0x42,0x3b, 0xf,0x42,0x3d, 0xf,0x42,0x3e, 0xf,0x42,0x3f, + 0xf,0x42,0x40, 0xf,0x42,0x41, 0xf,0x42,0x42, 0xf,0x42,0x43, + 0xf,0x42,0x44, 0xf,0x42,0x45, 0xf,0x42,0x46, 0xf,0x42,0x48, + 0xf,0x42,0x4a, 0xf,0x42,0x4c, 0x6,0x53,0x4d, 0x6,0x53,0x52, + 0x6,0x53,0x54, 0x4,0x3d,0x79, 0x6,0x53,0x62, 0x6,0x53,0x4b, + 0x6,0x53,0x5f, 0xf,0x42,0x22, 0xf,0x42,0x2f, 0xf,0x42,0x37, + 0x5,0x39,0x3f, 0x5,0x3f,0x72, 0x6,0x53,0x53, 0xf,0x43,0x74, + 0x5,0x46,0x4e, 0xf,0x42,0x4b, 0x5,0x46,0x50, 0x4,0x43,0x7b, + 0x4,0x43,0x72, 0x5,0x46,0x4d, 0x5,0x46,0x4f, 0x6,0x5d,0x69, + 0x5,0x46,0x55, 0x5,0x46,0x52, 0x7,0x23,0x65, 0x6,0x53,0x64, + 0x5,0x46,0x47, 0x6,0x5d,0x5f, 0x5,0x46,0x54, 0x5,0x46,0x46, + 0x5,0x46,0x58, 0x6,0x5d,0x62, 0x5,0x46,0x4a, 0x5,0x46,0x53, + 0x6,0x5d,0x63, 0x4,0x43,0x76, 0x5,0x46,0x48, 0x5,0x46,0x49, + 0x6,0x5d,0x65, 0x5,0x46,0x4c, 0x5,0x46,0x51, 0xf,0x48,0x57, + 0xf,0x48,0x58, 0xf,0x48,0x59, 0xf,0x48,0x5a, 0xf,0x48,0x5b, + 0xf,0x48,0x5c, 0xf,0x48,0x5d, 0xf,0x48,0x5e, 0xf,0x48,0x5f, + 0xf,0x48,0x60, 0xf,0x48,0x61, 0xf,0x48,0x62, 0xf,0x48,0x63, + 0xf,0x48,0x64, 0xf,0x48,0x65, 0xf,0x48,0x66, 0xf,0x48,0x67, + 0xf,0x48,0x68, 0xf,0x48,0x69, 0xf,0x48,0x6a, 0xf,0x48,0x6b, + 0xf,0x48,0x6c, 0xf,0x48,0x6d, 0xf,0x48,0x6e, 0xf,0x48,0x6f, + 0xf,0x48,0x71, 0xf,0x48,0x72, 0xf,0x48,0x73, 0xf,0x48,0x75, + 0x3,0x47,0x4b, 0x6,0x5d,0x6a, 0x6,0x5d,0x67, 0x6,0x5d,0x6b, + 0x6,0x5d,0x6c, 0x5,0x46,0x56, 0x5,0x46,0x57, 0xf,0x48,0x74, + 0x6,0x5d,0x64, 0x6,0x5d,0x66, 0xf,0x48,0x50, 0xf,0x48,0x51, + 0xf,0x48,0x53, 0xf,0x48,0x54, 0x6,0x5d,0x60, 0x6,0x5d,0x6d, + 0x6,0x5d,0x61, 0xf,0x48,0x56, 0x7,0x23,0x68, 0x5,0x4d,0x67, + 0x5,0x4d,0x5e, 0x4,0x4a,0x3b, 0x4,0x4a,0x47, 0x5,0x4d,0x5b, + 0x4,0x4a,0x40, 0x7,0x23,0x71, 0x7,0x23,0x6c, 0x7,0x23,0x74, + 0x5,0x4d,0x6b, 0x5,0x4d,0x65, 0x7,0x23,0x70, 0x4,0x4a,0x46, + 0x5,0x4d,0x5f, 0x4,0x4a,0x3f, 0x5,0x4d,0x64, 0x4,0x4a,0x43, + 0x4,0x4a,0x3e, 0x4,0x4a,0x35, 0x7,0x23,0x73, 0x5,0x4d,0x5c, + 0x4,0x4a,0x4a, 0x5,0x4d,0x69, 0x7,0x23,0x6e, 0x5,0x4d,0x63, + 0x5,0x4d,0x6a, 0x7,0x23,0x69, 0x4,0x4a,0x41, 0x5,0x4d,0x5d, + 0x7,0x23,0x75, 0x4,0x4a,0x3c, 0x4,0x4a,0x45, 0x4,0x4a,0x49, + 0x7,0x23,0x66, 0x7,0x23,0x6a, 0xf,0x4f,0x3d, 0xf,0x4f,0x3e, + 0xf,0x4f,0x3f, 0xf,0x4f,0x43, 0xf,0x4f,0x44, 0xf,0x4f,0x46, + 0xf,0x4f,0x47, 0xf,0x4f,0x48, 0xf,0x4f,0x49, 0xf,0x4f,0x4a, + 0xf,0x4f,0x4b, 0xf,0x4f,0x4c, 0xf,0x4f,0x4d, 0xf,0x4f,0x4e, + 0xf,0x4f,0x4f, 0xf,0x4f,0x50, 0xf,0x4f,0x51, 0xf,0x4f,0x52, + 0xf,0x4f,0x53, 0xf,0x4f,0x40, 0x7,0x23,0x6b, 0x5,0x4d,0x6c, + 0x5,0x4d,0x68, 0x5,0x4d,0x66, 0x7,0x23,0x67, 0x7,0x23,0x6d, + 0x5,0x4d,0x60, 0x5,0x4d,0x5a, 0x5,0x4d,0x62, 0x4,0x50,0x5b, + 0x5,0x54,0x7d, 0x7,0x2e,0x69, 0x4,0x50,0x65, 0x4,0x50,0x58, + 0x5,0x5b,0x65, 0x7,0x38,0x4c, 0x7,0x2e,0x60, 0x7,0x2e,0x63, + 0x5,0x54,0x7b, 0x7,0x2e,0x68, 0x7,0x2e,0x72, 0x5,0x54,0x7a, + 0x7,0x2e,0x6f, 0x7,0x2e,0x62, 0x4,0x50,0x62, 0x4,0x56,0x4c, + 0x4,0x50,0x57, 0x7,0x2e,0x5f, 0x4,0x50,0x5f, 0x5,0x54,0x79, + 0x7,0x2e,0x67, 0x7,0x2e,0x64, 0x5,0x54,0x71, 0x5,0x54,0x77, + 0x4,0x50,0x5c, 0x7,0x2e,0x6e, 0x7,0x2e,0x74, 0x5,0x54,0x78, + 0x4,0x50,0x5d, 0x7,0x2e,0x66, 0x7,0x2e,0x6b, 0x4,0x50,0x63, + 0x5,0x54,0x70, 0x7,0x2e,0x61, 0x5,0x61,0x7b, 0x5,0x54,0x75, + 0x5,0x54,0x76, 0x5,0x54,0x72, 0x4,0x4a,0x44, 0x7,0x2e,0x73, + 0x7,0x2e,0x6c, 0x7,0x2e,0x65, 0x7,0x2e,0x5e, 0x5,0x54,0x7c, + 0x5,0x54,0x6f, 0x5,0x54,0x73, 0xf,0x54,0x6f, 0xf,0x54,0x70, + 0xf,0x54,0x71, 0xf,0x54,0x72, 0xf,0x54,0x73, 0xf,0x54,0x75, + 0xf,0x54,0x76, 0xf,0x54,0x77, 0xf,0x54,0x78, 0xf,0x54,0x79, + 0xf,0x54,0x7a, 0xf,0x54,0x7c, 0xf,0x54,0x7d, 0xf,0x54,0x7e, + 0xf,0x55,0x21, 0xf,0x55,0x22, 0xf,0x55,0x24, 0xf,0x55,0x25, + 0xf,0x55,0x26, 0xf,0x55,0x27, 0xf,0x55,0x28, 0xf,0x55,0x2b, + 0xf,0x55,0x2c, 0xf,0x55,0x2d, 0xf,0x55,0x2e, 0xf,0x55,0x2f, + 0xf,0x55,0x30, 0xf,0x55,0x32, 0xf,0x55,0x33, 0xf,0x55,0x34, + 0xf,0x55,0x35, 0xf,0x55,0x36, 0xf,0x55,0x37, 0xf,0x55,0x38, + 0x7,0x2e,0x70, 0x7,0x2e,0x71, 0x4,0x50,0x61, 0xf,0x55,0x23, + 0x5,0x54,0x74, 0xf,0x48,0x70, 0xf,0x4f,0x41, 0x7,0x2e,0x6d, + 0x4,0x56,0x43, 0x7,0x38,0x50, 0x7,0x38,0x4e, 0x4,0x56,0x47, + 0x7,0x38,0x52, 0x7,0x38,0x56, 0x5,0x5b,0x6a, 0x5,0x5b,0x6b, + 0x4,0x56,0x4a, 0x4,0x56,0x46, 0x5,0x5b,0x6e, 0x7,0x38,0x53, + 0x5,0x5b,0x6c, 0x7,0x38,0x51, 0x7,0x38,0x57, 0x5,0x61,0x7c, + 0x5,0x5b,0x67, 0x4,0x56,0x4d, 0x4,0x56,0x44, 0x7,0x38,0x59, + 0x4,0x56,0x42, 0x5,0x5b,0x69, 0x7,0x38,0x5b, 0x5,0x5b,0x66, + 0x7,0x38,0x54, 0xf,0x5a,0x40, 0xf,0x5a,0x41, 0xf,0x5a,0x43, + 0xf,0x5a,0x44, 0xf,0x5a,0x45, 0xf,0x5a,0x46, 0xf,0x5a,0x47, + 0xf,0x5a,0x48, 0xf,0x5a,0x49, 0xf,0x5a,0x4a, 0xf,0x5a,0x4b, + 0xf,0x5a,0x4c, 0xf,0x5a,0x4e, 0xf,0x5a,0x4f, 0xf,0x5a,0x51, + 0xf,0x5a,0x52, 0xf,0x5a,0x54, 0x7,0x38,0x58, 0x5,0x5b,0x6d, + 0x7,0x38,0x5a, 0x7,0x38,0x4d, 0x7,0x38,0x4f, 0x7,0x37,0x27, + 0xf,0x5a,0x53, 0xf,0x5a,0x4d, 0x5,0x5b,0x6f, 0x5,0x5b,0x70, + 0xf,0x55,0x31, 0xf,0x5a,0x50, 0x4,0x5b,0x47, 0x5,0x61,0x78, + 0x7,0x40,0x27, 0x7,0x40,0x23, 0x4,0x5b,0x42, 0x7,0x40,0x2b, + 0x5,0x62,0x24, 0x5,0x61,0x7d, 0x5,0x62,0x26, 0x7,0x40,0x29, + 0x4,0x5b,0x45, 0x5,0x61,0x7a, 0x5,0x62,0x22, 0x5,0x62,0x27, + 0x5,0x61,0x7e, 0x7,0x38,0x5c, 0x5,0x62,0x2b, 0x5,0x61,0x79, + 0x4,0x5b,0x43, 0x4,0x5b,0x4c, 0x4,0x5b,0x46, 0x7,0x40,0x2d, + 0x7,0x40,0x28, 0x5,0x62,0x23, 0x7,0x47,0x46, 0x5,0x62,0x29, + 0x7,0x40,0x26, 0x4,0x5b,0x4b, 0x5,0x62,0x28, 0x5,0x62,0x25, + 0x5,0x61,0x76, 0x7,0x3f,0x7c, 0x7,0x3f,0x7d, 0xf,0x5e,0x7e, + 0xf,0x5f,0x22, 0xf,0x5f,0x23, 0xf,0x5f,0x24, 0xf,0x5f,0x25, + 0xf,0x5f,0x26, 0xf,0x5f,0x27, 0xf,0x5f,0x28, 0xf,0x5f,0x2a, + 0xf,0x5f,0x2b, 0xf,0x5f,0x2c, 0xf,0x5f,0x2e, 0xf,0x5f,0x2f, + 0xf,0x5f,0x30, 0x7,0x40,0x21, 0x7,0x40,0x25, 0x7,0x40,0x2c, + 0x7,0x40,0x2a, 0x5,0x62,0x21, 0xf,0x5f,0x21, 0x5,0x62,0x2a, + 0x5,0x61,0x77, 0x7,0x40,0x22, 0x7,0x40,0x24, 0xf,0x5f,0x2d, + 0x5,0x68,0x25, 0x7,0x47,0x43, 0x5,0x68,0x28, 0x5,0x68,0x2b, + 0x5,0x68,0x29, 0x7,0x47,0x42, 0x7,0x47,0x40, 0x5,0x68,0x2d, + 0x7,0x47,0x41, 0x4,0x5f,0x74, 0x7,0x47,0x48, 0x7,0x47,0x49, + 0x5,0x68,0x27, 0x5,0x68,0x26, 0x7,0x47,0x45, 0x5,0x68,0x2f, + 0x7,0x47,0x47, 0x7,0x3f,0x7e, 0xf,0x62,0x52, 0xf,0x62,0x56, + 0xf,0x62,0x58, 0xf,0x62,0x59, 0xf,0x62,0x5a, 0xf,0x62,0x5b, + 0xf,0x62,0x5c, 0xf,0x62,0x5d, 0xf,0x62,0x5f, 0xf,0x62,0x60, + 0xf,0x62,0x61, 0x5,0x68,0x2e, 0x7,0x47,0x44, 0x7,0x47,0x3f, + 0xf,0x62,0x54, 0x5,0x68,0x2c, 0xf,0x62,0x57, 0xf,0x62,0x4f, + 0xf,0x62,0x5e, 0xf,0x5e,0x7d, 0x4,0x63,0x53, 0x7,0x4d,0x7c, + 0x5,0x6c,0x3f, 0x7,0x4d,0x7e, 0x5,0x6c,0x42, 0x5,0x68,0x30, + 0x5,0x6c,0x3a, 0x5,0x6c,0x39, 0x5,0x6c,0x3d, 0x7,0x4d,0x7d, + 0x5,0x6c,0x3c, 0x5,0x6c,0x41, 0x5,0x6c,0x3b, 0x5,0x68,0x2a, + 0x5,0x6c,0x40, 0x5,0x6c,0x3e, 0xf,0x65,0x33, 0xf,0x65,0x34, + 0xf,0x65,0x35, 0xf,0x65,0x36, 0xf,0x65,0x37, 0xf,0x65,0x39, + 0xf,0x65,0x3a, 0xf,0x65,0x3b, 0xf,0x65,0x3c, 0xf,0x65,0x3d, + 0xf,0x65,0x3f, 0x7,0x4e,0x21, 0x4,0x63,0x52, 0x7,0x53,0x49, + 0x7,0x53,0x48, 0x5,0x70,0x2b, 0x5,0x70,0x2d, 0x4,0x66,0x46, + 0x5,0x70,0x29, 0x7,0x53,0x4d, 0x5,0x70,0x28, 0x5,0x70,0x2a, + 0x5,0x70,0x2c, 0x7,0x53,0x4a, 0x4,0x66,0x45, 0x5,0x70,0x2f, + 0x7,0x53,0x4e, 0x5,0x70,0x32, 0xf,0x67,0x5b, 0xf,0x67,0x5c, + 0xf,0x67,0x5d, 0xf,0x67,0x5e, 0xf,0x67,0x5f, 0xf,0x67,0x60, + 0xf,0x67,0x61, 0xf,0x67,0x62, 0xf,0x67,0x63, 0xf,0x67,0x64, + 0x7,0x53,0x4c, 0x5,0x70,0x31, 0x5,0x70,0x30, 0x7,0x53,0x4b, + 0x5,0x70,0x2e, 0x7,0x58,0x26, 0x5,0x73,0x4e, 0x5,0x73,0x4f, + 0x5,0x73,0x4c, 0x5,0x73,0x4a, 0x4,0x68,0x6f, 0x5,0x73,0x4b, + 0x5,0x73,0x4d, 0x7,0x58,0x25, 0xf,0x69,0x47, 0xf,0x69,0x48, + 0xf,0x69,0x49, 0xf,0x69,0x4b, 0xf,0x69,0x4e, 0xf,0x69,0x4f, + 0xf,0x69,0x50, 0xf,0x69,0x51, 0x7,0x58,0x24, 0x7,0x58,0x22, + 0xf,0x67,0x65, 0x5,0x75,0x71, 0x5,0x75,0x73, 0x5,0x77,0x60, + 0x5,0x75,0x74, 0x7,0x5b,0x60, 0x5,0x75,0x72, 0x7,0x5b,0x61, + 0x5,0x75,0x75, 0x7,0x5b,0x5f, 0x5,0x77,0x61, 0x7,0x5b,0x5d, + 0xf,0x6a,0x57, 0xf,0x6a,0x59, 0x7,0x5b,0x5e, 0x5,0x75,0x76, + 0x5,0x75,0x70, 0x4,0x6b,0x6c, 0x7,0x5e,0x6e, 0x5,0x77,0x62, + 0x7,0x60,0x71, 0xf,0x6b,0x4e, 0xf,0x6b,0x4f, 0xf,0x6b,0x50, + 0xf,0x6b,0x53, 0xf,0x6b,0x54, 0x7,0x5e,0x6f, 0x7,0x5e,0x70, + 0xf,0x6a,0x58, 0x7,0x60,0x72, 0x5,0x79,0x2d, 0xf,0x6c,0x2c, + 0x7,0x60,0x73, 0x5,0x79,0x2c, 0x5,0x79,0x2e, 0xf,0x6b,0x52, + 0x5,0x7a,0x29, 0x7,0x63,0x54, 0x7,0x60,0x74, 0x4,0x6d,0x55, + 0xf,0x6c,0x2d, 0xf,0x6c,0x4c, 0xf,0x6c,0x63, 0x7,0x63,0x4c, + 0x7,0x63,0x55, 0x5,0x7b,0x40, 0x7,0x64,0x48, 0x7,0x64,0x49, + 0x7,0x65,0x5b, 0xf,0x6d,0x2f, 0x7,0x65,0x74, 0x6,0x25,0x24, + 0x4,0x24,0x4b, 0x6,0x28,0x2f, 0x6,0x2c,0x2e, 0x6,0x28,0x32, + 0x5,0x24,0x47, 0x6,0x28,0x31, 0x4,0x24,0x4a, 0x5,0x26,0x5c, + 0x5,0x26,0x5b, 0x5,0x26,0x58, 0x6,0x2c,0x2f, 0x4,0x26,0x6f, + 0x6,0x2c,0x30, 0x5,0x26,0x5d, 0x4,0x26,0x6e, 0x5,0x26,0x59, + 0x5,0x26,0x5a, 0x5,0x26,0x57, 0xf,0x27,0x56, 0x5,0x29,0x5f, + 0x6,0x31,0x7a, 0x6,0x38,0x54, 0x6,0x31,0x7c, 0x5,0x29,0x62, + 0x4,0x29,0x75, 0x5,0x29,0x61, 0x5,0x29,0x5e, 0x6,0x31,0x79, + 0x5,0x29,0x5c, 0x5,0x29,0x60, 0x6,0x31,0x7b, 0x5,0x29,0x5d, + 0xf,0x2c,0x77, 0x6,0x38,0x57, 0x6,0x38,0x58, 0x6,0x38,0x55, + 0x5,0x2e,0x33, 0x5,0x2e,0x2d, 0x6,0x38,0x56, 0x6,0x40,0x6b, + 0x5,0x2e,0x32, 0x4,0x2d,0x5f, 0x5,0x2e,0x2f, 0x5,0x2e,0x34, + 0x5,0x2e,0x31, 0x5,0x2e,0x30, 0xf,0x30,0x31, 0x5,0x33,0x25, + 0x6,0x40,0x6c, 0x6,0x40,0x6d, 0xf,0x35,0x67, 0xf,0x35,0x68, + 0xf,0x35,0x69, 0xf,0x35,0x6a, 0xf,0x35,0x6b, 0xf,0x35,0x6c, + 0xf,0x35,0x6d, 0xf,0x35,0x6e, 0x4,0x38,0x3d, 0x5,0x39,0x47, + 0x5,0x3f,0x77, 0x4,0x38,0x3a, 0x5,0x39,0x45, 0x6,0x4a,0x3c, + 0x5,0x33,0x24, 0x5,0x39,0x48, 0x6,0x4a,0x3d, 0x5,0x39,0x44, + 0x5,0x39,0x49, 0x6,0x4a,0x3e, 0x5,0x39,0x46, 0x6,0x4a,0x3b, + 0xf,0x3c,0x30, 0xf,0x3c,0x31, 0x6,0x4a,0x3a, 0x6,0x53,0x6e, + 0x5,0x3f,0x76, 0x5,0x3f,0x75, 0x5,0x3f,0x7a, 0x6,0x53,0x6b, + 0x5,0x3f,0x79, 0x6,0x53,0x67, 0x6,0x53,0x66, 0x6,0x53,0x68, + 0x6,0x53,0x69, 0x6,0x53,0x6a, 0x6,0x53,0x6d, 0x5,0x3f,0x78, + 0xf,0x42,0x4e, 0x6,0x58,0x5a, 0x6,0x53,0x6c, 0x6,0x53,0x65, + 0xf,0x42,0x4d, 0x5,0x46,0x5c, 0x4,0x44,0x2b, 0x5,0x46,0x5e, + 0x6,0x5d,0x6f, 0x6,0x5d,0x6e, 0x4,0x44,0x2c, 0x5,0x46,0x5d, + 0x4,0x44,0x29, 0x6,0x5d,0x75, 0x6,0x5d,0x70, 0x5,0x46,0x5a, + 0x6,0x5d,0x76, 0x6,0x5d,0x74, 0x5,0x46,0x5b, 0x6,0x5d,0x72, + 0x6,0x5d,0x71, 0x6,0x5d,0x73, 0x6,0x53,0x6f, 0xf,0x48,0x76, + 0xf,0x48,0x78, 0x5,0x46,0x59, 0x5,0x4d,0x6e, 0x7,0x23,0x7d, + 0x5,0x4d,0x70, 0x5,0x4d,0x71, 0x4,0x4a,0x4d, 0x7,0x23,0x79, + 0x7,0x23,0x77, 0x7,0x23,0x7e, 0x7,0x23,0x76, 0x7,0x23,0x7a, + 0x7,0x23,0x7b, 0x5,0x4d,0x6f, 0xf,0x4f,0x54, 0x7,0x23,0x7c, + 0x5,0x54,0x7e, 0x7,0x2e,0x76, 0x4,0x50,0x68, 0x7,0x2e,0x75, + 0xf,0x55,0x3a, 0xf,0x55,0x3b, 0x7,0x38,0x5e, 0x7,0x38,0x60, + 0x5,0x5b,0x71, 0x7,0x38,0x5f, 0xf,0x5a,0x55, 0x7,0x38,0x5d, + 0x5,0x62,0x2c, 0x5,0x68,0x32, 0x5,0x68,0x31, 0xf,0x62,0x62, + 0x5,0x70,0x36, 0x7,0x4e,0x23, 0x5,0x70,0x35, 0x5,0x70,0x34, + 0x4,0x68,0x70, 0x5,0x70,0x33, 0x5,0x73,0x50, 0x7,0x58,0x29, + 0x7,0x58,0x27, 0x7,0x58,0x28, 0x5,0x77,0x63, 0x7,0x60,0x75, + 0x4,0x6c,0x70, 0x4,0x6d,0x56, 0x5,0x21,0x32, 0x5,0x21,0x70, + 0x6,0x23,0x2e, 0x6,0x25,0x26, 0x5,0x24,0x4a, 0x6,0x28,0x34, + 0x6,0x2c,0x31, 0x5,0x24,0x49, 0x5,0x24,0x4b, 0x6,0x28,0x33, + 0x6,0x2c,0x3c, 0x6,0x2c,0x34, 0x6,0x2c,0x3b, 0x6,0x2c,0x3a, + 0x6,0x2c,0x36, 0x6,0x2c,0x33, 0x6,0x2c,0x38, 0x6,0x2c,0x32, + 0x6,0x2c,0x37, 0x5,0x26,0x5e, 0x6,0x2c,0x39, 0x6,0x2c,0x35, + 0x5,0x26,0x5f, 0xf,0x27,0x57, 0xf,0x27,0x58, 0xf,0x27,0x59, + 0x4,0x26,0x72, 0x4,0x29,0x76, 0x5,0x29,0x63, 0x5,0x28,0x35, + 0x6,0x38,0x59, 0x6,0x38,0x5c, 0x5,0x2e,0x35, 0x6,0x38,0x5a, + 0x6,0x38,0x5e, 0x6,0x38,0x5d, 0x6,0x38,0x5b, 0x6,0x37,0x48, + 0x5,0x33,0x26, 0x6,0x40,0x70, 0xf,0x35,0x6f, 0x6,0x40,0x6f, + 0x4,0x38,0x40, 0x4,0x38,0x3e, 0x5,0x39,0x4a, 0x5,0x39,0x4b, + 0x6,0x4a,0x43, 0x4,0x38,0x41, 0x6,0x4a,0x42, 0x6,0x4a,0x44, + 0x6,0x4a,0x40, 0x6,0x4a,0x45, 0x6,0x4a,0x46, 0x6,0x4a,0x41, + 0x5,0x3f,0x7c, 0x6,0x53,0x70, 0x5,0x3f,0x7b, 0xf,0x42,0x4f, + 0x6,0x5a,0x61, 0x7,0x24,0x22, 0x7,0x24,0x25, 0x7,0x24,0x23, + 0x7,0x24,0x26, 0x7,0x24,0x21, 0x7,0x24,0x24, 0xf,0x4f,0x55, + 0x7,0x2e,0x7a, 0x7,0x2e,0x79, 0x7,0x2e,0x77, 0x7,0x2e,0x78, + 0x7,0x38,0x61, 0x4,0x56,0x50, 0xf,0x5a,0x56, 0xf,0x5a,0x57, + 0x5,0x62,0x2d, 0x5,0x62,0x2e, 0x7,0x40,0x2e, 0x5,0x73,0x51, + 0x7,0x5b,0x62, 0x7,0x5b,0x63, 0x5,0x21,0x71, 0x5,0x21,0x49, + 0x5,0x22,0x76, 0x6,0x28,0x35, 0x4,0x22,0x7d, 0x6,0x25,0x27, + 0x5,0x24,0x4c, 0x4,0x24,0x4d, 0x6,0x25,0x28, 0x6,0x28,0x36, + 0x6,0x28,0x3b, 0x6,0x28,0x37, 0x4,0x24,0x4c, 0x6,0x28,0x3c, + 0x5,0x24,0x4d, 0x6,0x28,0x39, 0x6,0x28,0x38, 0x6,0x28,0x3a, + 0x6,0x2c,0x3f, 0x5,0x26,0x60, 0x5,0x26,0x66, 0x5,0x26,0x61, + 0x5,0x26,0x64, 0x4,0x26,0x73, 0x4,0x26,0x74, 0x5,0x26,0x63, + 0x4,0x26,0x77, 0x6,0x2c,0x3d, 0x6,0x2c,0x3e, 0x6,0x2c,0x40, + 0x6,0x31,0x7d, 0x5,0x26,0x65, 0x5,0x29,0x68, 0x4,0x29,0x78, + 0x4,0x29,0x79, 0x6,0x32,0x26, 0x4,0x29,0x77, 0x6,0x31,0x7e, + 0x5,0x29,0x64, 0x5,0x29,0x65, 0x5,0x29,0x6b, 0x5,0x29,0x66, + 0x5,0x29,0x67, 0x6,0x32,0x25, 0x4,0x29,0x7a, 0x6,0x32,0x22, + 0x6,0x32,0x23, 0x5,0x29,0x6a, 0x6,0x32,0x24, 0x6,0x38,0x5f, + 0xf,0x2b,0x50, 0x6,0x32,0x21, 0x5,0x29,0x6c, 0x5,0x2e,0x36, + 0x4,0x2d,0x63, 0x6,0x38,0x62, 0x5,0x2e,0x3b, 0x6,0x38,0x65, + 0x5,0x2e,0x3c, 0x5,0x2e,0x38, 0x5,0x2e,0x39, 0x6,0x38,0x63, + 0x6,0x38,0x66, 0x5,0x2e,0x3d, 0x5,0x2e,0x37, 0x5,0x2e,0x3a, + 0x5,0x2e,0x3e, 0x6,0x38,0x60, 0x6,0x38,0x61, 0x5,0x33,0x2b, + 0x6,0x40,0x74, 0x5,0x33,0x2a, 0x6,0x40,0x73, 0x5,0x33,0x27, + 0x5,0x33,0x28, 0x5,0x33,0x29, 0x6,0x40,0x71, 0x4,0x32,0x4b, + 0x5,0x33,0x2c, 0x6,0x4a,0x49, 0x6,0x40,0x75, 0x6,0x40,0x72, + 0xf,0x35,0x71, 0x6,0x53,0x72, 0x6,0x4a,0x4a, 0x5,0x39,0x53, + 0x4,0x38,0x48, 0x6,0x4a,0x4b, 0x4,0x38,0x43, 0x5,0x39,0x4e, + 0x5,0x39,0x4d, 0x5,0x39,0x4f, 0x4,0x38,0x47, 0x5,0x39,0x52, + 0x5,0x39,0x54, 0x5,0x39,0x50, 0x5,0x39,0x4c, 0x5,0x39,0x51, + 0x6,0x4a,0x4c, 0x6,0x53,0x71, 0x6,0x4a,0x48, 0xf,0x3c,0x32, + 0x6,0x53,0x74, 0x6,0x53,0x79, 0x5,0x3f,0x7d, 0x5,0x3f,0x7e, + 0x6,0x53,0x76, 0x6,0x53,0x78, 0x4,0x3e,0x25, 0x6,0x5d,0x78, + 0x6,0x53,0x7a, 0x6,0x53,0x75, 0x6,0x53,0x73, 0xf,0x42,0x50, + 0xf,0x35,0x70, 0x4,0x44,0x34, 0x4,0x44,0x2e, 0x6,0x5d,0x7b, + 0x6,0x5d,0x7c, 0x4,0x44,0x2f, 0x6,0x5d,0x79, 0x6,0x5d,0x7a, + 0x6,0x5d,0x2d, 0x7,0x24,0x29, 0x4,0x4a,0x51, 0x5,0x4d,0x72, + 0x7,0x24,0x27, 0x5,0x4d,0x75, 0x7,0x24,0x28, 0x7,0x24,0x2b, + 0x5,0x4d,0x74, 0x4,0x50,0x69, 0x7,0x24,0x2c, 0x7,0x24,0x2a, + 0xf,0x4f,0x56, 0x5,0x4d,0x73, 0x7,0x2e,0x7b, 0x7,0x2e,0x7c, + 0x5,0x55,0x21, 0x4,0x50,0x6c, 0x5,0x55,0x23, 0x5,0x55,0x22, + 0x7,0x2e,0x7e, 0xf,0x55,0x3c, 0xf,0x55,0x3d, 0x7,0x38,0x64, + 0x7,0x38,0x62, 0x5,0x5b,0x73, 0x7,0x38,0x65, 0x7,0x38,0x63, + 0x5,0x5b,0x74, 0x5,0x62,0x30, 0x5,0x62,0x2f, 0x4,0x5b,0x4d, + 0x7,0x40,0x30, 0x7,0x2e,0x7d, 0x5,0x5b,0x75, 0x7,0x40,0x2f, + 0x5,0x68,0x33, 0x5,0x70,0x37, 0x5,0x70,0x38, 0x7,0x53,0x4f, + 0x7,0x58,0x2a, 0x5,0x75,0x7a, 0x5,0x75,0x79, 0x5,0x26,0x68, + 0x5,0x26,0x67, 0x6,0x32,0x27, 0x6,0x32,0x28, 0x5,0x2e,0x3f, + 0x4,0x32,0x4c, 0x4,0x32,0x4d, 0x6,0x40,0x78, 0x6,0x40,0x79, + 0x6,0x40,0x76, 0x6,0x40,0x77, 0xf,0x35,0x73, 0xf,0x35,0x75, + 0xf,0x35,0x76, 0xf,0x35,0x77, 0x6,0x40,0x7b, 0x6,0x40,0x7a, + 0x5,0x33,0x2d, 0x6,0x4a,0x4f, 0x6,0x4a,0x4e, 0xf,0x3c,0x33, + 0xf,0x35,0x72, 0x6,0x54,0x21, 0x6,0x54,0x22, 0x6,0x53,0x7d, + 0x6,0x53,0x7e, 0x6,0x54,0x24, 0xf,0x42,0x51, 0xf,0x42,0x52, + 0x6,0x54,0x23, 0x6,0x53,0x7c, 0x5,0x40,0x21, 0x5,0x40,0x7b, + 0x5,0x46,0x61, 0x4,0x44,0x36, 0x6,0x5e,0x21, 0x4,0x44,0x37, + 0x6,0x5d,0x7e, 0x6,0x5d,0x7d, 0xf,0x48,0x7a, 0x5,0x4d,0x76, + 0x6,0x5e,0x22, 0x7,0x24,0x2d, 0x4,0x4a,0x52, 0x7,0x2f,0x25, + 0x7,0x2f,0x23, 0x7,0x2f,0x26, 0x7,0x2f,0x21, 0x7,0x2f,0x24, + 0x5,0x55,0x24, 0x7,0x2f,0x22, 0xf,0x55,0x3e, 0xf,0x55,0x3f, + 0xf,0x55,0x40, 0x7,0x38,0x66, 0x7,0x38,0x67, 0x4,0x5b,0x4e, + 0x7,0x40,0x33, 0x5,0x62,0x32, 0x5,0x62,0x31, 0x7,0x40,0x31, + 0x7,0x40,0x32, 0x4,0x5f,0x78, 0x7,0x47,0x4c, 0x7,0x4e,0x25, + 0x7,0x47,0x4d, 0x7,0x53,0x50, 0x4,0x6a,0x4d, 0x5,0x75,0x7b, + 0x7,0x5b,0x64, 0x5,0x73,0x52, 0x7,0x5e,0x73, 0x5,0x77,0x65, + 0x5,0x77,0x64, 0x7,0x60,0x76, 0x7,0x63,0x56, 0x5,0x21,0x72, + 0x6,0x28,0x3d, 0x6,0x2c,0x41, 0x6,0x32,0x29, 0x6,0x38,0x67, + 0xf,0x3c,0x34, 0x5,0x40,0x22, 0x4,0x4a,0x53, 0xf,0x4f,0x57, + 0xf,0x4f,0x58, 0xf,0x5a,0x59, 0xf,0x55,0x41, 0xf,0x62,0x63, + 0xf,0x6a,0x5a, 0x5,0x24,0x4f, 0x6,0x28,0x3e, 0x6,0x2c,0x45, + 0x6,0x2c,0x44, 0x5,0x26,0x69, 0x6,0x38,0x68, 0x6,0x38,0x6a, + 0x6,0x38,0x69, 0x6,0x40,0x7c, 0x6,0x40,0x7d, 0x5,0x40,0x23, + 0x4,0x3e,0x26, 0x5,0x46,0x62, 0x5,0x46,0x63, 0x6,0x5e,0x23, + 0x7,0x24,0x2e, 0x7,0x2f,0x27, 0x7,0x2f,0x28, 0x5,0x55,0x25, + 0x7,0x47,0x4e, 0x5,0x6c,0x43, 0x5,0x79,0x30, 0x5,0x21,0x4a, + 0x4,0x22,0x7e, 0xf,0x22,0x5a, 0xf,0x22,0x5b, 0x6,0x28,0x40, + 0x6,0x28,0x3f, 0x4,0x24,0x4e, 0xf,0x24,0x55, 0xf,0x24,0x56, + 0xf,0x24,0x57, 0xf,0x24,0x59, 0xf,0x24,0x5a, 0x5,0x26,0x6d, + 0x5,0x26,0x6a, 0x5,0x26,0x6c, 0x5,0x26,0x6b, 0x6,0x2c,0x47, + 0x6,0x2c,0x46, 0xf,0x27,0x5a, 0xf,0x27,0x5c, 0xf,0x27,0x5d, + 0xf,0x27,0x5e, 0xf,0x27,0x5f, 0x5,0x26,0x43, 0x6,0x32,0x2c, + 0x5,0x29,0x6e, 0x5,0x29,0x6f, 0x5,0x29,0x6d, 0x5,0x29,0x70, + 0x5,0x29,0x71, 0x6,0x32,0x2d, 0x5,0x29,0x73, 0x6,0x32,0x2f, + 0x6,0x38,0x6d, 0x6,0x32,0x2e, 0x5,0x29,0x74, 0x6,0x32,0x2b, + 0x5,0x29,0x72, 0xf,0x2b,0x51, 0xf,0x2b,0x52, 0xf,0x2b,0x53, + 0xf,0x2b,0x54, 0xf,0x2b,0x55, 0xf,0x2b,0x56, 0xf,0x2b,0x57, + 0xf,0x2b,0x58, 0xf,0x2b,0x59, 0xf,0x2b,0x5a, 0xf,0x2b,0x5b, + 0xf,0x2b,0x5c, 0xf,0x2b,0x5e, 0xf,0x2b,0x5d, 0x6,0x38,0x6f, + 0x5,0x2e,0x41, 0x6,0x38,0x6e, 0x4,0x2d,0x69, 0x5,0x2e,0x43, + 0x4,0x2d,0x68, 0x6,0x38,0x6c, 0x5,0x2e,0x42, 0xf,0x30,0x32, + 0xf,0x30,0x33, 0xf,0x30,0x34, 0xf,0x30,0x35, 0xf,0x30,0x36, + 0xf,0x30,0x37, 0xf,0x30,0x38, 0xf,0x30,0x39, 0x6,0x38,0x6b, + 0x5,0x2e,0x40, 0x6,0x41,0x26, 0x4,0x32,0x56, 0x6,0x41,0x21, + 0x5,0x33,0x31, 0x6,0x41,0x22, 0x6,0x41,0x23, 0x5,0x33,0x2e, + 0x6,0x41,0x25, 0x5,0x33,0x32, 0x5,0x33,0x30, 0x5,0x33,0x2f, + 0x6,0x40,0x7e, 0x6,0x41,0x24, 0xf,0x35,0x78, 0xf,0x35,0x79, + 0xf,0x35,0x7a, 0xf,0x35,0x7b, 0xf,0x35,0x7c, 0x5,0x39,0x55, + 0x4,0x38,0x4d, 0x5,0x39,0x56, 0x4,0x38,0x50, 0x6,0x4a,0x51, + 0x6,0x4a,0x53, 0x5,0x39,0x59, 0x5,0x39,0x58, 0x5,0x39,0x5a, + 0x6,0x4a,0x56, 0x6,0x4a,0x50, 0x6,0x4a,0x55, 0x5,0x39,0x57, + 0x6,0x4a,0x52, 0xf,0x3c,0x3a, 0xf,0x3c,0x35, 0xf,0x3c,0x37, + 0xf,0x3c,0x38, 0xf,0x3c,0x39, 0xf,0x3c,0x3b, 0xf,0x3c,0x3d, + 0xf,0x3c,0x3f, 0xf,0x3c,0x40, 0x6,0x4a,0x54, 0xf,0x3c,0x36, + 0x5,0x39,0x5c, 0x6,0x54,0x2e, 0x6,0x54,0x2c, 0x4,0x3e,0x2b, + 0x6,0x54,0x27, 0x6,0x54,0x2b, 0x4,0x3e,0x2a, 0x6,0x54,0x28, + 0x6,0x54,0x25, 0x6,0x54,0x29, 0x6,0x54,0x26, 0x6,0x54,0x2d, + 0x6,0x54,0x2a, 0x6,0x54,0x2f, 0x5,0x40,0x24, 0xf,0x42,0x53, + 0xf,0x42,0x55, 0xf,0x42,0x56, 0xf,0x42,0x57, 0x6,0x54,0x30, + 0x6,0x5e,0x29, 0x5,0x46,0x66, 0x5,0x46,0x65, 0x6,0x5e,0x2a, + 0x6,0x5e,0x2b, 0x6,0x5e,0x2d, 0x4,0x44,0x3d, 0x6,0x5e,0x24, + 0x4,0x44,0x3e, 0x5,0x46,0x67, 0x4,0x44,0x3b, 0x6,0x5e,0x2e, + 0x6,0x5e,0x2f, 0x6,0x5e,0x26, 0x6,0x5e,0x27, 0xf,0x48,0x7c, + 0xf,0x48,0x7d, 0xf,0x48,0x7e, 0xf,0x49,0x21, 0x6,0x5e,0x28, + 0x5,0x46,0x69, 0x6,0x5e,0x30, 0x6,0x5e,0x25, 0x6,0x5e,0x2c, + 0x4,0x4a,0x56, 0x7,0x24,0x33, 0x7,0x24,0x37, 0x7,0x24,0x35, + 0x4,0x4a,0x55, 0x4,0x4a,0x54, 0x5,0x4d,0x79, 0x7,0x24,0x34, + 0x5,0x4d,0x77, 0x5,0x4d,0x78, 0x7,0x24,0x31, 0x7,0x24,0x32, + 0x7,0x24,0x30, 0x7,0x24,0x2f, 0x7,0x24,0x36, 0x7,0x24,0x38, + 0x7,0x2f,0x29, 0x5,0x55,0x27, 0x7,0x2f,0x2a, 0x4,0x50,0x70, + 0x5,0x55,0x26, 0x4,0x50,0x73, 0x7,0x2f,0x2c, 0xf,0x55,0x42, + 0xf,0x55,0x43, 0xf,0x55,0x44, 0xf,0x55,0x45, 0x7,0x2f,0x2b, + 0x7,0x24,0x39, 0x7,0x38,0x6a, 0x4,0x56,0x55, 0x4,0x56,0x54, + 0x7,0x38,0x69, 0x5,0x5b,0x76, 0x7,0x38,0x68, 0xf,0x5a,0x5a, + 0xf,0x5a,0x5b, 0xf,0x5a,0x5c, 0x7,0x38,0x6c, 0x7,0x38,0x6b, + 0x5,0x62,0x35, 0x5,0x62,0x34, 0x5,0x62,0x36, 0x7,0x40,0x37, + 0x7,0x47,0x4f, 0x7,0x40,0x35, 0x5,0x62,0x37, 0x7,0x40,0x34, + 0x7,0x40,0x36, 0xf,0x5f,0x31, 0x5,0x62,0x33, 0xf,0x5f,0x32, + 0x7,0x47,0x52, 0x5,0x68,0x34, 0x7,0x47,0x50, 0x7,0x47,0x51, + 0xf,0x65,0x41, 0x7,0x4e,0x26, 0x4,0x66,0x47, 0x5,0x70,0x39, + 0x7,0x53,0x51, 0xf,0x67,0x67, 0x7,0x58,0x2b, 0x5,0x73,0x53, + 0xf,0x69,0x52, 0x5,0x75,0x7c, 0x7,0x5b,0x65, 0x7,0x64,0x4a, + 0x6,0x2c,0x48, 0x6,0x32,0x30, 0x5,0x29,0x75, 0x5,0x29,0x76, + 0x6,0x33,0x4c, 0x6,0x41,0x27, 0xf,0x35,0x7d, 0x6,0x41,0x28, + 0x6,0x54,0x31, 0x4,0x44,0x40, 0x7,0x2f,0x2d, 0x7,0x38,0x6d, + 0x4,0x5b,0x51, 0xf,0x5a,0x5d, 0x6,0x25,0x2a, 0x6,0x25,0x29, + 0xf,0x24,0x5c, 0x6,0x2c,0x4b, 0x6,0x2c,0x4a, 0x6,0x2c,0x49, + 0x6,0x32,0x31, 0x6,0x32,0x32, 0xf,0x2b,0x5f, 0x5,0x29,0x77, + 0x5,0x2e,0x44, 0xf,0x35,0x7e, 0x5,0x39,0x5d, 0xf,0x3c,0x41, + 0x6,0x54,0x32, 0x7,0x24,0x3b, 0x7,0x24,0x3a, 0x7,0x40,0x38, + 0x7,0x53,0x52, 0xf,0x21,0x67, 0x6,0x22,0x24, 0x6,0x25,0x2b, + 0x5,0x21,0x73, 0x6,0x25,0x2c, 0xf,0x22,0x5e, 0xf,0x24,0x69, + 0x4,0x23,0x23, 0x6,0x25,0x2d, 0x5,0x24,0x50, 0x6,0x25,0x2f, + 0x6,0x25,0x31, 0x3,0x24,0x24, 0xf,0x22,0x5c, 0xf,0x24,0x5f, + 0xf,0x24,0x60, 0x6,0x25,0x30, 0x6,0x2c,0x4d, 0x5,0x24,0x52, + 0x6,0x28,0x42, 0x5,0x24,0x51, 0x5,0x24,0x53, 0x4,0x24,0x50, + 0x6,0x28,0x46, 0x6,0x28,0x47, 0x6,0x2c,0x4c, 0x6,0x28,0x43, + 0x6,0x28,0x41, 0x6,0x28,0x45, 0x6,0x28,0x48, 0xf,0x24,0x61, + 0xf,0x24,0x5e, 0xf,0x24,0x62, 0xf,0x24,0x63, 0xf,0x24,0x64, + 0xf,0x24,0x65, 0xf,0x24,0x66, 0xf,0x24,0x67, 0xf,0x27,0x63, + 0xf,0x27,0x64, 0xf,0x27,0x65, 0x4,0x27,0x23, 0x5,0x26,0x6f, + 0x6,0x32,0x33, 0x5,0x26,0x72, 0x5,0x26,0x73, 0x4,0x27,0x21, + 0x6,0x2c,0x57, 0x4,0x27,0x25, 0x6,0x2c,0x50, 0x4,0x27,0x24, + 0x6,0x2c,0x4e, 0x5,0x26,0x6e, 0x5,0x26,0x70, 0x6,0x2c,0x58, + 0x5,0x26,0x71, 0x6,0x2c,0x5a, 0x6,0x32,0x34, 0x6,0x2c,0x56, + 0x6,0x2c,0x5c, 0x4,0x26,0x7c, 0x6,0x2c,0x53, 0xf,0x27,0x60, + 0xf,0x27,0x61, 0xf,0x27,0x62, 0xf,0x27,0x67, 0xf,0x27,0x68, + 0xf,0x27,0x69, 0xf,0x27,0x6a, 0xf,0x27,0x6b, 0xf,0x27,0x6d, + 0xf,0x2b,0x64, 0xf,0x2b,0x67, 0xf,0x2b,0x6c, 0x6,0x2c,0x52, + 0x6,0x2c,0x54, 0x6,0x2c,0x55, 0x6,0x2c,0x59, 0x6,0x2c,0x4f, + 0x5,0x29,0x78, 0x4,0x29,0x7c, 0x6,0x32,0x36, 0x5,0x2a,0x22, + 0x6,0x32,0x3b, 0x6,0x32,0x3e, 0x5,0x29,0x79, 0x4,0x2a,0x22, + 0x4,0x2d,0x71, 0x5,0x2a,0x21, 0x5,0x29,0x7e, 0x6,0x32,0x3a, + 0x6,0x32,0x40, 0x5,0x29,0x7a, 0x6,0x32,0x41, 0x5,0x29,0x7d, + 0x6,0x38,0x70, 0x6,0x32,0x3d, 0x6,0x32,0x3c, 0x4,0x2a,0x23, + 0x4,0x29,0x7d, 0x6,0x32,0x3f, 0xf,0x2b,0x60, 0xf,0x2b,0x61, + 0xf,0x2b,0x62, 0xf,0x2b,0x63, 0xf,0x2b,0x65, 0xf,0x2b,0x66, + 0xf,0x2b,0x68, 0xf,0x2b,0x69, 0xf,0x2b,0x6a, 0xf,0x2b,0x6b, + 0xf,0x2b,0x6d, 0xf,0x2b,0x6e, 0xf,0x30,0x3a, 0xf,0x30,0x3d, + 0xf,0x30,0x44, 0x6,0x32,0x38, 0x4,0x2a,0x24, 0x6,0x32,0x35, + 0x6,0x32,0x37, 0x5,0x2a,0x23, 0xf,0x30,0x57, 0x4,0x2d,0x6e, + 0x5,0x2e,0x49, 0x6,0x39,0x30, 0x6,0x39,0x2e, 0x5,0x2e,0x48, + 0x5,0x2e,0x47, 0x6,0x38,0x7c, 0x5,0x2e,0x4a, 0x6,0x38,0x71, + 0x6,0x38,0x7b, 0x4,0x2d,0x6d, 0x4,0x2d,0x6f, 0x6,0x39,0x25, + 0x6,0x38,0x76, 0x6,0x39,0x26, 0x6,0x39,0x2a, 0x6,0x38,0x77, + 0x6,0x39,0x29, 0x6,0x38,0x7e, 0x6,0x39,0x28, 0x6,0x41,0x2a, + 0x6,0x41,0x29, 0x4,0x32,0x66, 0x6,0x39,0x24, 0x6,0x39,0x2c, + 0x5,0x2e,0x45, 0x6,0x39,0x23, 0x6,0x38,0x73, 0x6,0x39,0x2b, + 0x6,0x38,0x78, 0x6,0x39,0x2f, 0x6,0x39,0x32, 0x6,0x41,0x46, + 0xf,0x30,0x3b, 0xf,0x30,0x3e, 0xf,0x30,0x3f, 0xf,0x30,0x40, + 0xf,0x30,0x41, 0xf,0x30,0x42, 0xf,0x30,0x43, 0xf,0x30,0x45, + 0xf,0x30,0x46, 0xf,0x30,0x47, 0xf,0x30,0x48, 0xf,0x30,0x4a, + 0xf,0x30,0x4b, 0xf,0x30,0x4c, 0xf,0x30,0x4d, 0xf,0x30,0x4e, + 0xf,0x30,0x4f, 0xf,0x30,0x50, 0xf,0x30,0x51, 0xf,0x30,0x52, + 0xf,0x30,0x53, 0xf,0x30,0x54, 0xf,0x30,0x55, 0xf,0x30,0x56, + 0xf,0x30,0x58, 0xf,0x30,0x59, 0xf,0x30,0x5a, 0x6,0x38,0x79, + 0x6,0x39,0x22, 0x6,0x39,0x31, 0x4,0x2d,0x72, 0x6,0x39,0x27, + 0x6,0x38,0x7d, 0x6,0x38,0x75, 0x5,0x2e,0x46, 0xf,0x36,0x2d, + 0x4,0x32,0x5d, 0x5,0x33,0x40, 0x4,0x32,0x5b, 0x4,0x32,0x6b, + 0x6,0x41,0x34, 0x6,0x41,0x38, 0x6,0x41,0x3c, 0x4,0x32,0x6a, + 0x6,0x41,0x43, 0x4,0x32,0x61, 0x6,0x41,0x36, 0x4,0x32,0x65, + 0x6,0x41,0x35, 0x6,0x41,0x45, 0x4,0x32,0x69, 0x5,0x33,0x33, + 0x6,0x41,0x31, 0x4,0x32,0x60, 0x4,0x32,0x67, 0x6,0x4a,0x64, + 0x5,0x33,0x3f, 0x6,0x41,0x42, 0x5,0x33,0x3e, 0x6,0x41,0x3f, + 0x4,0x32,0x59, 0x4,0x32,0x5f, 0x6,0x41,0x2c, 0x4,0x25,0x2f, + 0x6,0x41,0x3b, 0x6,0x41,0x30, 0x6,0x4a,0x66, 0x5,0x33,0x38, + 0x5,0x33,0x41, 0x6,0x4a,0x58, 0x6,0x4a,0x59, 0x6,0x41,0x3e, + 0x6,0x41,0x44, 0x5,0x33,0x36, 0x4,0x32,0x62, 0x6,0x41,0x40, + 0x5,0x33,0x3b, 0x6,0x41,0x2f, 0x6,0x41,0x32, 0x5,0x33,0x3a, + 0x5,0x33,0x35, 0x4,0x32,0x6c, 0x4,0x32,0x6e, 0x5,0x33,0x37, + 0x6,0x41,0x3d, 0xf,0x36,0x21, 0xf,0x36,0x22, 0xf,0x36,0x23, + 0xf,0x36,0x25, 0xf,0x36,0x26, 0xf,0x36,0x27, 0xf,0x36,0x28, + 0xf,0x36,0x2a, 0xf,0x36,0x2c, 0xf,0x36,0x2e, 0xf,0x36,0x2f, + 0xf,0x36,0x30, 0xf,0x36,0x31, 0xf,0x36,0x32, 0xf,0x36,0x36, + 0xf,0x36,0x37, 0xf,0x36,0x38, 0xf,0x36,0x39, 0xf,0x36,0x3a, + 0xf,0x36,0x3b, 0xf,0x36,0x3c, 0xf,0x36,0x3d, 0xf,0x3c,0x42, + 0xf,0x3c,0x4b, 0xf,0x3c,0x4d, 0xf,0x3c,0x57, 0xf,0x42,0x5f, + 0x6,0x4a,0x57, 0x6,0x41,0x33, 0x6,0x41,0x37, 0x5,0x33,0x39, + 0x6,0x41,0x3a, 0x6,0x41,0x39, 0x6,0x41,0x47, 0x6,0x41,0x2d, + 0x6,0x41,0x2e, 0x5,0x33,0x34, 0x5,0x33,0x3c, 0x6,0x38,0x7a, + 0x6,0x4a,0x62, 0x6,0x4a,0x70, 0x4,0x38,0x54, 0x5,0x39,0x63, + 0x4,0x38,0x55, 0x6,0x4a,0x5d, 0x6,0x4a,0x5f, 0x5,0x39,0x67, + 0x5,0x39,0x6a, 0x5,0x39,0x62, 0x6,0x54,0x48, 0x5,0x39,0x6c, + 0x6,0x4a,0x5a, 0x4,0x38,0x53, 0x5,0x33,0x42, 0x4,0x38,0x58, + 0x6,0x4a,0x6c, 0x6,0x4a,0x5c, 0x5,0x39,0x68, 0x6,0x4a,0x71, + 0x6,0x54,0x35, 0x6,0x4a,0x67, 0x6,0x4a,0x68, 0x6,0x4a,0x6e, + 0x5,0x39,0x60, 0x6,0x54,0x34, 0x6,0x4a,0x6f, 0x4,0x3e,0x2c, + 0x5,0x39,0x5f, 0x5,0x39,0x66, 0x5,0x39,0x65, 0x5,0x39,0x64, + 0x6,0x4a,0x6a, 0x5,0x39,0x61, 0x6,0x54,0x33, 0x6,0x4a,0x72, + 0x5,0x39,0x6d, 0x6,0x4a,0x61, 0xf,0x3c,0x44, 0xf,0x3c,0x45, + 0xf,0x3c,0x46, 0xf,0x3c,0x48, 0xf,0x3c,0x49, 0xf,0x3c,0x4a, + 0xf,0x3c,0x4e, 0xf,0x3c,0x4f, 0xf,0x3c,0x50, 0xf,0x3c,0x51, + 0xf,0x3c,0x52, 0xf,0x3c,0x53, 0xf,0x3c,0x54, 0xf,0x3c,0x55, + 0xf,0x3c,0x56, 0xf,0x3c,0x58, 0xf,0x3c,0x59, 0xf,0x3c,0x5b, + 0xf,0x3c,0x5c, 0x6,0x4a,0x69, 0x5,0x39,0x69, 0x6,0x4a,0x6b, + 0x4,0x38,0x5d, 0x6,0x4a,0x5b, 0x6,0x4a,0x60, 0x6,0x4a,0x5e, + 0x5,0x39,0x6b, 0xf,0x42,0x73, 0x6,0x54,0x41, 0x5,0x40,0x25, + 0x4,0x3e,0x41, 0x6,0x54,0x38, 0x4,0x3e,0x34, 0x6,0x54,0x3b, + 0x6,0x54,0x43, 0x4,0x3e,0x3b, 0x4,0x3e,0x43, 0x4,0x3e,0x3e, + 0x4,0x3e,0x2e, 0x6,0x54,0x4a, 0x5,0x40,0x29, 0x5,0x40,0x26, + 0x4,0x3e,0x40, 0x6,0x5e,0x31, 0x6,0x54,0x42, 0x4,0x3e,0x3a, + 0x5,0x40,0x2f, 0x5,0x40,0x2d, 0x4,0x3e,0x31, 0x6,0x5e,0x32, + 0x4,0x3e,0x42, 0x5,0x40,0x2c, 0x5,0x40,0x2e, 0x6,0x54,0x3e, + 0x6,0x54,0x4c, 0x7,0x24,0x3c, 0x6,0x54,0x47, 0x4,0x44,0x4b, + 0x6,0x54,0x3f, 0x6,0x54,0x46, 0x6,0x54,0x37, 0x6,0x54,0x36, + 0x5,0x40,0x2b, 0x5,0x40,0x28, 0x4,0x3e,0x3d, 0x6,0x54,0x3c, + 0x6,0x54,0x3d, 0x6,0x54,0x40, 0x6,0x54,0x45, 0xf,0x42,0x58, + 0xf,0x42,0x59, 0xf,0x42,0x5a, 0xf,0x42,0x5b, 0xf,0x42,0x5c, + 0xf,0x42,0x5d, 0xf,0x42,0x5e, 0xf,0x42,0x60, 0xf,0x42,0x61, + 0xf,0x42,0x62, 0xf,0x42,0x65, 0xf,0x42,0x66, 0xf,0x42,0x67, + 0xf,0x42,0x68, 0xf,0x42,0x69, 0xf,0x42,0x6a, 0xf,0x42,0x6c, + 0xf,0x42,0x6d, 0xf,0x42,0x6e, 0xf,0x42,0x6f, 0xf,0x42,0x70, + 0xf,0x42,0x71, 0xf,0x42,0x72, 0xf,0x42,0x75, 0xf,0x49,0x22, + 0xf,0x49,0x3e, 0x5,0x40,0x2a, 0x6,0x54,0x44, 0x4,0x3e,0x35, + 0x6,0x54,0x4d, 0x6,0x54,0x3a, 0x6,0x54,0x4b, 0xf,0x49,0x2f, + 0xf,0x42,0x6b, 0xf,0x4f,0x6c, 0x6,0x54,0x39, 0x7,0x24,0x3d, + 0x4,0x44,0x54, 0x4,0x44,0x47, 0x4,0x44,0x48, 0x4,0x44,0x4c, + 0x5,0x46,0x6b, 0x4,0x44,0x4e, 0x5,0x46,0x6a, 0x5,0x46,0x74, + 0x5,0x46,0x76, 0x4,0x44,0x45, 0x4,0x44,0x53, 0x6,0x5e,0x44, + 0x5,0x46,0x6f, 0x6,0x5e,0x41, 0x6,0x5e,0x3a, 0x4,0x44,0x51, + 0x4,0x44,0x50, 0x5,0x46,0x75, 0x5,0x46,0x72, 0x5,0x46,0x6d, + 0x7,0x24,0x40, 0x7,0x24,0x3f, 0x5,0x46,0x77, 0x6,0x5e,0x45, + 0x4,0x44,0x4f, 0x6,0x5e,0x39, 0x6,0x5e,0x42, 0x5,0x46,0x70, + 0x5,0x46,0x71, 0x4,0x44,0x41, 0x6,0x5e,0x3d, 0x5,0x4d,0x7a, + 0x7,0x24,0x3e, 0x6,0x5e,0x34, 0x5,0x46,0x6e, 0x6,0x5e,0x3f, + 0x5,0x46,0x73, 0xf,0x49,0x23, 0xf,0x49,0x24, 0xf,0x49,0x25, + 0xf,0x49,0x26, 0xf,0x49,0x27, 0xf,0x49,0x28, 0xf,0x49,0x29, + 0xf,0x49,0x2b, 0xf,0x49,0x2c, 0xf,0x49,0x2d, 0xf,0x49,0x2e, + 0xf,0x49,0x30, 0xf,0x49,0x31, 0xf,0x49,0x34, 0xf,0x49,0x36, + 0xf,0x49,0x37, 0xf,0x49,0x38, 0xf,0x49,0x39, 0xf,0x49,0x3a, + 0xf,0x49,0x3c, 0xf,0x49,0x3d, 0xf,0x49,0x41, 0xf,0x49,0x42, + 0xf,0x49,0x43, 0xf,0x4f,0x6d, 0x7,0x22,0x68, 0x4,0x44,0x42, + 0x6,0x5e,0x3c, 0x6,0x5e,0x43, 0x6,0x5e,0x35, 0x5,0x46,0x6c, + 0x6,0x5e,0x33, 0x6,0x5e,0x37, 0x6,0x5e,0x38, 0xf,0x49,0x3b, + 0x6,0x5e,0x36, 0xf,0x49,0x2a, 0x7,0x24,0x62, 0x7,0x24,0x52, + 0x7,0x24,0x4d, 0x4,0x4a,0x60, 0x7,0x24,0x5a, 0x7,0x24,0x54, + 0x7,0x24,0x4c, 0x4,0x4a,0x65, 0x4,0x4a,0x67, 0x5,0x4e,0x25, + 0x7,0x24,0x63, 0x7,0x24,0x4e, 0x7,0x24,0x50, 0x7,0x24,0x56, + 0x4,0x4a,0x5c, 0x7,0x24,0x57, 0x7,0x24,0x49, 0x5,0x4e,0x21, + 0x7,0x24,0x65, 0x7,0x24,0x47, 0x7,0x24,0x44, 0x4,0x4a,0x66, + 0x5,0x4d,0x7b, 0x5,0x4e,0x24, 0x7,0x24,0x64, 0x4,0x4a,0x5b, + 0x7,0x24,0x5b, 0x4,0x4a,0x5a, 0x7,0x24,0x59, 0x5,0x4d,0x7e, + 0x7,0x24,0x43, 0x7,0x24,0x67, 0x5,0x4e,0x23, 0x5,0x4d,0x7d, + 0x7,0x24,0x53, 0x7,0x24,0x42, 0x7,0x3a,0x69, 0x7,0x24,0x45, + 0x7,0x24,0x68, 0x5,0x4e,0x22, 0x7,0x24,0x41, 0x7,0x24,0x5e, + 0x7,0x24,0x66, 0x5,0x4e,0x26, 0x5,0x4e,0x28, 0x5,0x4d,0x7c, + 0x4,0x4a,0x5e, 0x7,0x24,0x5f, 0x7,0x24,0x4b, 0x7,0x24,0x51, + 0x5,0x4e,0x27, 0x7,0x24,0x5c, 0xf,0x4f,0x59, 0xf,0x4f,0x5a, + 0xf,0x4f,0x5b, 0xf,0x4f,0x5c, 0xf,0x4f,0x5d, 0xf,0x4f,0x5e, + 0xf,0x4f,0x5f, 0xf,0x4f,0x62, 0xf,0x4f,0x63, 0xf,0x4f,0x64, + 0xf,0x4f,0x65, 0xf,0x4f,0x66, 0xf,0x4f,0x67, 0xf,0x4f,0x68, + 0xf,0x4f,0x6a, 0xf,0x4f,0x6b, 0xf,0x4f,0x6f, 0xf,0x4f,0x70, + 0xf,0x4f,0x71, 0xf,0x4f,0x72, 0xf,0x4f,0x73, 0xf,0x4f,0x74, + 0xf,0x4f,0x75, 0xf,0x4f,0x76, 0xf,0x4f,0x77, 0xf,0x4f,0x78, + 0xf,0x4f,0x7b, 0xf,0x4f,0x7c, 0xf,0x55,0x51, 0x7,0x24,0x55, + 0x7,0x24,0x60, 0x7,0x2f,0x30, 0x4,0x4a,0x63, 0x7,0x24,0x46, + 0x7,0x24,0x5d, 0x7,0x24,0x48, 0x7,0x24,0x4a, 0xf,0x55,0x4a, + 0xf,0x4f,0x7e, 0xf,0x49,0x40, 0x4,0x50,0x7c, 0x5,0x55,0x35, + 0x5,0x55,0x34, 0x5,0x55,0x28, 0x5,0x55,0x29, 0x5,0x55,0x2b, + 0x7,0x2f,0x33, 0x5,0x55,0x30, 0x7,0x2f,0x47, 0x7,0x2f,0x40, + 0x7,0x2f,0x3a, 0x4,0x50,0x79, 0x7,0x2f,0x39, 0x4,0x50,0x7e, + 0x5,0x55,0x33, 0x7,0x2f,0x3d, 0x7,0x2f,0x31, 0x7,0x2f,0x37, + 0x7,0x2f,0x46, 0x7,0x2f,0x3b, 0x7,0x2f,0x38, 0x7,0x2f,0x43, + 0x7,0x2f,0x36, 0x7,0x2f,0x32, 0x5,0x55,0x31, 0x5,0x55,0x2a, + 0x5,0x5b,0x77, 0x7,0x2f,0x3c, 0x7,0x2f,0x49, 0x5,0x55,0x2c, + 0x5,0x5b,0x79, 0x5,0x55,0x32, 0x7,0x2f,0x2f, 0x7,0x2f,0x34, + 0x7,0x2f,0x3e, 0x7,0x2f,0x41, 0xf,0x55,0x46, 0xf,0x55,0x48, + 0xf,0x55,0x49, 0xf,0x55,0x4b, 0xf,0x55,0x4c, 0xf,0x55,0x4f, + 0xf,0x55,0x50, 0xf,0x55,0x52, 0xf,0x55,0x53, 0xf,0x55,0x54, + 0xf,0x55,0x55, 0xf,0x55,0x57, 0xf,0x5a,0x6d, 0x5,0x55,0x2f, + 0x7,0x2f,0x3f, 0x7,0x2f,0x45, 0x7,0x2f,0x48, 0x7,0x2f,0x4a, + 0x7,0x2f,0x2e, 0x7,0x2f,0x44, 0x4,0x51,0x21, 0xf,0x4f,0x61, + 0xf,0x5a,0x66, 0xf,0x5a,0x5f, 0x5,0x54,0x3a, 0x5,0x5b,0x7c, + 0x4,0x56,0x5a, 0x4,0x56,0x5f, 0x5,0x5b,0x7a, 0x7,0x38,0x7a, + 0x7,0x38,0x6e, 0x4,0x5b,0x52, 0x5,0x5b,0x7b, 0x5,0x5b,0x78, + 0x7,0x38,0x70, 0x7,0x38,0x76, 0x7,0x38,0x6f, 0x7,0x38,0x79, + 0x7,0x38,0x74, 0x7,0x38,0x73, 0x5,0x62,0x38, 0x7,0x38,0x75, + 0x7,0x38,0x7b, 0x5,0x5b,0x7d, 0x7,0x38,0x77, 0x5,0x55,0x37, + 0x3,0x55,0x3a, 0x7,0x38,0x78, 0xf,0x5a,0x60, 0xf,0x5a,0x61, + 0xf,0x5a,0x62, 0xf,0x5a,0x63, 0xf,0x5a,0x64, 0xf,0x5a,0x65, + 0xf,0x5a,0x67, 0xf,0x5a,0x69, 0xf,0x5a,0x6b, 0xf,0x5a,0x70, + 0x7,0x38,0x72, 0x5,0x5b,0x7e, 0x7,0x38,0x7c, 0x7,0x38,0x71, + 0xf,0x55,0x4e, 0xf,0x5a,0x6c, 0xf,0x5a,0x6f, 0xf,0x55,0x47, + 0xf,0x55,0x4d, 0xf,0x5a,0x5e, 0x7,0x2f,0x35, 0x5,0x62,0x3f, + 0x5,0x62,0x46, 0x5,0x62,0x45, 0x4,0x5b,0x5d, 0x5,0x62,0x3d, + 0x5,0x62,0x39, 0x5,0x62,0x42, 0x7,0x40,0x40, 0x7,0x40,0x46, + 0x4,0x5b,0x59, 0x5,0x62,0x4b, 0x5,0x62,0x44, 0x7,0x40,0x3c, + 0x5,0x62,0x41, 0x5,0x62,0x4a, 0x4,0x5b,0x58, 0x5,0x62,0x43, + 0x7,0x40,0x47, 0x5,0x62,0x3b, 0x7,0x40,0x41, 0x5,0x62,0x40, + 0x7,0x40,0x48, 0x7,0x40,0x3a, 0x4,0x5b,0x5f, 0x4,0x5b,0x55, + 0x7,0x40,0x45, 0x7,0x40,0x44, 0x7,0x40,0x3e, 0x5,0x62,0x3a, + 0x4,0x5b,0x53, 0x5,0x62,0x3c, 0x5,0x62,0x3e, 0x5,0x62,0x49, + 0x5,0x62,0x4c, 0x5,0x62,0x47, 0x7,0x40,0x3f, 0x4,0x5b,0x5c, + 0x7,0x40,0x42, 0x7,0x47,0x5f, 0x5,0x62,0x4d, 0xf,0x5f,0x33, + 0xf,0x5f,0x35, 0xf,0x5f,0x36, 0xf,0x5f,0x37, 0xf,0x5f,0x39, + 0xf,0x5f,0x3a, 0xf,0x5f,0x3b, 0xf,0x5f,0x3c, 0xf,0x5f,0x3d, + 0xf,0x5f,0x3e, 0xf,0x5f,0x3f, 0xf,0x5f,0x40, 0xf,0x5f,0x41, + 0xf,0x5f,0x42, 0xf,0x5f,0x43, 0xf,0x62,0x64, 0xf,0x62,0x65, + 0xf,0x62,0x6c, 0x7,0x47,0x5e, 0x7,0x40,0x3d, 0x7,0x40,0x39, + 0x7,0x40,0x43, 0x7,0x40,0x3b, 0xf,0x5f,0x34, 0xf,0x5a,0x6a, + 0xf,0x5a,0x6e, 0x5,0x62,0x48, 0x7,0x47,0x65, 0x7,0x47,0x5c, + 0x7,0x47,0x62, 0x4,0x5f,0x7c, 0x4,0x5f,0x7a, 0x7,0x47,0x53, + 0x5,0x68,0x36, 0x7,0x47,0x56, 0x7,0x47,0x54, 0x7,0x47,0x5b, + 0x7,0x47,0x5a, 0x7,0x47,0x55, 0x5,0x68,0x35, 0x7,0x47,0x59, + 0x7,0x47,0x5d, 0x5,0x6c,0x45, 0x7,0x47,0x61, 0xf,0x62,0x66, + 0xf,0x62,0x67, 0xf,0x62,0x68, 0xf,0x62,0x69, 0xf,0x62,0x6a, + 0xf,0x62,0x6d, 0xf,0x62,0x6e, 0xf,0x62,0x6f, 0xf,0x62,0x70, + 0xf,0x62,0x71, 0x7,0x47,0x57, 0x7,0x47,0x60, 0x7,0x47,0x66, + 0x7,0x47,0x64, 0x7,0x47,0x63, 0x7,0x47,0x58, 0x5,0x6c,0x47, + 0x5,0x6c,0x4a, 0x5,0x6c,0x4b, 0x7,0x4e,0x2b, 0x4,0x63,0x59, + 0x4,0x63,0x5d, 0x7,0x4e,0x2a, 0x7,0x4e,0x29, 0x5,0x6c,0x48, + 0x4,0x63,0x5c, 0x7,0x4e,0x2e, 0x4,0x63,0x57, 0x4,0x63,0x58, + 0x4,0x63,0x56, 0x7,0x4e,0x2d, 0x5,0x70,0x3b, 0x5,0x6c,0x49, + 0x5,0x6c,0x4c, 0x7,0x4e,0x2f, 0xf,0x65,0x42, 0xf,0x65,0x43, + 0xf,0x65,0x44, 0x7,0x4e,0x2c, 0x4,0x66,0x48, 0x5,0x70,0x40, + 0x7,0x53,0x56, 0x5,0x70,0x3f, 0x5,0x70,0x3d, 0x4,0x66,0x4b, + 0x7,0x53,0x54, 0x5,0x70,0x3c, 0x7,0x53,0x59, 0x7,0x53,0x53, + 0x4,0x66,0x4d, 0x7,0x53,0x5f, 0x5,0x70,0x41, 0x7,0x53,0x55, + 0x7,0x53,0x5a, 0xf,0x67,0x68, 0xf,0x67,0x69, 0xf,0x67,0x6a, + 0xf,0x67,0x6b, 0xf,0x67,0x6d, 0xf,0x67,0x6e, 0xf,0x67,0x6f, + 0x7,0x53,0x5b, 0x7,0x53,0x5c, 0x7,0x53,0x5d, 0x7,0x53,0x5e, + 0x5,0x70,0x3a, 0xf,0x67,0x70, 0xf,0x69,0x55, 0x7,0x58,0x2e, + 0x7,0x53,0x57, 0x7,0x58,0x2f, 0x5,0x73,0x54, 0x5,0x70,0x42, + 0x7,0x58,0x2d, 0x5,0x73,0x55, 0x7,0x58,0x31, 0x4,0x68,0x72, + 0x7,0x58,0x32, 0xf,0x69,0x53, 0xf,0x69,0x54, 0x7,0x58,0x33, + 0x7,0x58,0x30, 0x7,0x58,0x2c, 0x5,0x76,0x21, 0x5,0x76,0x22, + 0x7,0x5b,0x69, 0x7,0x5b,0x68, 0x5,0x75,0x7e, 0x7,0x5b,0x67, + 0x5,0x75,0x7d, 0xf,0x6a,0x5b, 0xf,0x6a,0x5c, 0xf,0x6a,0x5d, + 0x7,0x5b,0x6a, 0x7,0x5b,0x66, 0x7,0x5e,0x76, 0x5,0x77,0x67, + 0x7,0x5e,0x77, 0x4,0x6c,0x71, 0x7,0x5e,0x74, 0x5,0x77,0x66, + 0x7,0x5e,0x75, 0x4,0x6c,0x72, 0x7,0x60,0x79, 0x7,0x60,0x78, + 0x7,0x60,0x77, 0xf,0x6c,0x2f, 0x7,0x62,0x39, 0x4,0x6d,0x58, + 0x5,0x7a,0x2b, 0x5,0x7a,0x2a, 0x4,0x6d,0x59, 0x4,0x6d,0x74, + 0x5,0x7a,0x69, 0x5,0x7a,0x6a, 0x7,0x63,0x57, 0x7,0x64,0x4b, + 0x5,0x7b,0x41, 0xf,0x6d,0x26, 0x7,0x65,0x5c, 0x5,0x7c,0x3c, + 0x6,0x23,0x2f, 0x6,0x25,0x33, 0x4,0x23,0x24, 0x4,0x23,0x25, + 0x6,0x25,0x32, 0xf,0x22,0x5f, 0xf,0x22,0x60, 0xf,0x22,0x61, + 0x6,0x25,0x34, 0x4,0x24,0x53, 0x4,0x24,0x54, 0x5,0x24,0x54, + 0x6,0x28,0x4c, 0x5,0x24,0x55, 0x5,0x24,0x57, 0xf,0x24,0x6b, + 0xf,0x24,0x6c, 0xf,0x24,0x6d, 0xf,0x24,0x70, 0xf,0x24,0x72, + 0x6,0x28,0x4b, 0x5,0x26,0x74, 0x4,0x27,0x28, 0x5,0x26,0x75, + 0xf,0x27,0x6f, 0xf,0x27,0x70, 0xf,0x27,0x71, 0xf,0x27,0x73, + 0xf,0x27,0x74, 0xf,0x27,0x75, 0xf,0x27,0x76, 0xf,0x27,0x77, + 0x6,0x2c,0x5f, 0xf,0x27,0x72, 0x6,0x2c,0x5e, 0x4,0x27,0x2a, + 0x5,0x24,0x56, 0x5,0x2a,0x25, 0x6,0x32,0x4c, 0x5,0x2a,0x26, + 0x6,0x32,0x44, 0x5,0x2a,0x27, 0x6,0x32,0x4b, 0x6,0x32,0x46, + 0xf,0x2b,0x6f, 0xf,0x2b,0x70, 0xf,0x2b,0x71, 0xf,0x2b,0x72, + 0xf,0x2b,0x73, 0xf,0x2b,0x74, 0xf,0x2b,0x75, 0xf,0x2b,0x76, + 0xf,0x2b,0x77, 0xf,0x2b,0x78, 0xf,0x2b,0x79, 0xf,0x2b,0x7b, + 0xf,0x2b,0x7c, 0xf,0x2b,0x7d, 0xf,0x2b,0x7e, 0xf,0x2c,0x21, + 0xf,0x2c,0x23, 0x4,0x2a,0x29, 0x6,0x32,0x45, 0x6,0x32,0x43, + 0x6,0x32,0x47, 0x6,0x39,0x3a, 0x5,0x2a,0x28, 0x6,0x32,0x4a, + 0xf,0x2c,0x22, 0x6,0x32,0x49, 0x5,0x2e,0x4f, 0x5,0x2e,0x4e, + 0x6,0x39,0x36, 0x6,0x39,0x39, 0xf,0x30,0x6a, 0x4,0x32,0x6f, + 0x6,0x39,0x37, 0x4,0x2d,0x74, 0x6,0x39,0x34, 0x5,0x2e,0x4b, + 0xf,0x30,0x5d, 0xf,0x30,0x5e, 0xf,0x30,0x5f, 0xf,0x30,0x60, + 0xf,0x30,0x61, 0xf,0x30,0x62, 0xf,0x30,0x63, 0xf,0x30,0x64, + 0xf,0x30,0x65, 0xf,0x30,0x66, 0xf,0x30,0x68, 0xf,0x30,0x69, + 0xf,0x30,0x6b, 0xf,0x30,0x6c, 0xf,0x30,0x6e, 0xf,0x30,0x6f, + 0xf,0x30,0x70, 0xf,0x30,0x71, 0xf,0x30,0x72, 0x5,0x2e,0x4c, + 0x6,0x39,0x35, 0x6,0x39,0x3b, 0x6,0x39,0x3c, 0xf,0x30,0x67, + 0xf,0x30,0x6d, 0x6,0x39,0x38, 0x5,0x2e,0x4d, 0x6,0x41,0x4b, + 0x4,0x32,0x74, 0x5,0x33,0x44, 0x6,0x41,0x4f, 0x4,0x32,0x73, + 0x4,0x32,0x75, 0x6,0x41,0x4e, 0x6,0x41,0x54, 0x6,0x41,0x51, + 0x6,0x41,0x4d, 0x6,0x41,0x4c, 0x6,0x4a,0x73, 0x6,0x41,0x52, + 0x6,0x41,0x50, 0x6,0x41,0x53, 0xf,0x36,0x24, 0xf,0x36,0x3e, + 0xf,0x36,0x3f, 0xf,0x36,0x40, 0xf,0x36,0x41, 0xf,0x36,0x43, + 0xf,0x36,0x44, 0xf,0x36,0x45, 0xf,0x36,0x46, 0xf,0x36,0x47, + 0xf,0x36,0x49, 0xf,0x36,0x4a, 0xf,0x36,0x4c, 0xf,0x36,0x4d, + 0xf,0x36,0x4e, 0xf,0x36,0x50, 0x6,0x41,0x49, 0x6,0x41,0x48, + 0xf,0x36,0x4b, 0x5,0x33,0x43, 0x5,0x33,0x45, 0x6,0x41,0x55, + 0x4,0x38,0x69, 0x6,0x4a,0x78, 0x6,0x41,0x4a, 0x5,0x39,0x71, + 0x5,0x39,0x6f, 0x6,0x4a,0x7e, 0x6,0x4b,0x21, 0x5,0x39,0x6e, + 0x6,0x4a,0x75, 0x4,0x38,0x66, 0x6,0x4a,0x7a, 0x6,0x4a,0x74, + 0x6,0x4a,0x7d, 0x4,0x38,0x63, 0x5,0x39,0x70, 0x6,0x4a,0x77, + 0xf,0x3c,0x5e, 0xf,0x3c,0x5f, 0xf,0x3c,0x60, 0xf,0x3c,0x61, + 0xf,0x3c,0x62, 0xf,0x3c,0x63, 0xf,0x3c,0x64, 0xf,0x3c,0x66, + 0xf,0x3c,0x67, 0xf,0x3c,0x68, 0xf,0x3c,0x69, 0xf,0x3c,0x6b, + 0xf,0x3c,0x6c, 0xf,0x3c,0x6d, 0xf,0x3c,0x6e, 0xf,0x3c,0x6f, + 0xf,0x3c,0x70, 0xf,0x3c,0x71, 0xf,0x3c,0x72, 0xf,0x3c,0x75, + 0xf,0x3c,0x77, 0xf,0x3c,0x78, 0xf,0x3c,0x79, 0xf,0x3c,0x7a, + 0xf,0x3c,0x7b, 0xf,0x3c,0x7c, 0xf,0x3d,0x21, 0x6,0x4a,0x79, + 0x6,0x4a,0x7c, 0x4,0x38,0x67, 0x6,0x4a,0x76, 0x6,0x4a,0x7b, + 0xf,0x3c,0x6a, 0x5,0x39,0x72, 0x5,0x40,0x34, 0x6,0x54,0x5a, + 0x6,0x54,0x58, 0x5,0x40,0x30, 0x6,0x54,0x56, 0x6,0x54,0x5d, + 0x4,0x3e,0x47, 0x6,0x54,0x57, 0x4,0x3e,0x44, 0x6,0x54,0x5b, + 0x6,0x54,0x5e, 0x4,0x3e,0x45, 0x5,0x40,0x32, 0x6,0x54,0x53, + 0x6,0x54,0x63, 0x6,0x54,0x5f, 0x6,0x54,0x64, 0x5,0x40,0x35, + 0x6,0x54,0x5c, 0x6,0x54,0x62, 0xf,0x42,0x76, 0xf,0x42,0x79, + 0xf,0x42,0x7b, 0xf,0x42,0x7c, 0xf,0x42,0x7d, 0xf,0x43,0x21, + 0xf,0x43,0x22, 0xf,0x43,0x23, 0xf,0x43,0x25, 0xf,0x43,0x26, + 0xf,0x43,0x27, 0xf,0x43,0x28, 0xf,0x43,0x29, 0xf,0x43,0x2a, + 0xf,0x43,0x2b, 0xf,0x43,0x2d, 0xf,0x43,0x2e, 0xf,0x43,0x30, + 0xf,0x43,0x33, 0xf,0x43,0x34, 0xf,0x43,0x35, 0xf,0x43,0x36, + 0xf,0x43,0x37, 0xf,0x43,0x38, 0xf,0x43,0x39, 0xf,0x43,0x3a, + 0xf,0x43,0x3b, 0xf,0x43,0x3d, 0xf,0x43,0x3e, 0x6,0x54,0x51, + 0x6,0x54,0x52, 0x6,0x54,0x55, 0x6,0x54,0x66, 0x4,0x3e,0x4a, + 0x6,0x54,0x61, 0x6,0x54,0x65, 0x6,0x5a,0x54, 0xf,0x43,0x2c, + 0x5,0x40,0x33, 0x5,0x40,0x31, 0xf,0x49,0x54, 0x6,0x5e,0x51, + 0x6,0x5e,0x50, 0x5,0x46,0x7e, 0x6,0x5e,0x4a, 0x5,0x47,0x22, + 0x4,0x44,0x55, 0x5,0x46,0x7c, 0x5,0x46,0x7b, 0x5,0x46,0x7a, + 0x7,0x24,0x70, 0x7,0x24,0x6a, 0x6,0x5e,0x46, 0x5,0x47,0x21, + 0x6,0x5e,0x47, 0x6,0x5e,0x48, 0x5,0x46,0x79, 0x6,0x5e,0x4b, + 0x6,0x5e,0x4f, 0xf,0x49,0x44, 0xf,0x49,0x45, 0xf,0x49,0x46, + 0xf,0x49,0x47, 0xf,0x49,0x49, 0xf,0x49,0x4a, 0xf,0x49,0x4c, + 0xf,0x49,0x4d, 0xf,0x49,0x4e, 0xf,0x49,0x4f, 0xf,0x49,0x50, + 0xf,0x49,0x51, 0xf,0x49,0x52, 0xf,0x49,0x53, 0xf,0x49,0x55, + 0xf,0x49,0x56, 0xf,0x49,0x57, 0xf,0x49,0x5a, 0xf,0x49,0x5b, + 0xf,0x49,0x5d, 0xf,0x49,0x5e, 0xf,0x49,0x60, 0xf,0x49,0x62, + 0xf,0x49,0x63, 0xf,0x49,0x64, 0x4,0x44,0x5d, 0x5,0x46,0x7d, + 0x6,0x5e,0x4c, 0x6,0x5e,0x52, 0x6,0x5e,0x49, 0x6,0x5e,0x4d, + 0xf,0x49,0x5c, 0x6,0x54,0x60, 0xf,0x42,0x7e, 0xf,0x42,0x7a, + 0x4,0x4a,0x6b, 0x5,0x4e,0x2c, 0x7,0x24,0x74, 0x7,0x24,0x6d, + 0x7,0x24,0x69, 0x5,0x4e,0x2a, 0x7,0x24,0x6c, 0x7,0x24,0x71, + 0x7,0x24,0x72, 0x7,0x24,0x75, 0x7,0x24,0x6b, 0x5,0x4e,0x29, + 0xf,0x4e,0x22, 0x5,0x4e,0x2b, 0x7,0x24,0x73, 0xf,0x50,0x23, + 0xf,0x50,0x24, 0xf,0x50,0x26, 0xf,0x50,0x27, 0xf,0x50,0x28, + 0xf,0x50,0x29, 0xf,0x50,0x2a, 0xf,0x50,0x2b, 0xf,0x50,0x2e, + 0xf,0x50,0x2f, 0xf,0x50,0x31, 0xf,0x50,0x32, 0xf,0x50,0x33, + 0xf,0x50,0x34, 0xf,0x50,0x35, 0xf,0x50,0x37, 0xf,0x50,0x38, + 0xf,0x50,0x39, 0xf,0x50,0x3a, 0xf,0x50,0x3b, 0xf,0x50,0x3c, + 0x7,0x24,0x6e, 0xf,0x50,0x2c, 0x7,0x2a,0x71, 0xf,0x50,0x2d, + 0xf,0x50,0x30, 0xf,0x50,0x25, 0xf,0x50,0x22, 0x5,0x4e,0x2e, + 0x5,0x4e,0x2d, 0x6,0x5e,0x4e, 0x4,0x51,0x2a, 0x7,0x2f,0x52, + 0x7,0x2f,0x66, 0x7,0x2f,0x50, 0x7,0x2f,0x60, 0x7,0x2f,0x5e, + 0x5,0x55,0x3b, 0x4,0x51,0x27, 0x7,0x2f,0x61, 0x7,0x2f,0x63, + 0x7,0x2f,0x55, 0x7,0x24,0x6f, 0x4,0x51,0x28, 0x7,0x2f,0x56, + 0x7,0x2f,0x64, 0x7,0x2f,0x65, 0x4,0x51,0x26, 0x7,0x2f,0x58, + 0x7,0x2f,0x54, 0x4,0x51,0x29, 0x7,0x2f,0x67, 0x5,0x55,0x3a, + 0x5,0x55,0x3c, 0x7,0x2f,0x62, 0x7,0x2f,0x59, 0x7,0x2f,0x5d, + 0x7,0x2f,0x5a, 0x7,0x2f,0x4b, 0x7,0x2f,0x53, 0x7,0x2f,0x5c, + 0xf,0x55,0x59, 0xf,0x55,0x5a, 0xf,0x55,0x5b, 0xf,0x55,0x5c, + 0xf,0x55,0x5d, 0xf,0x55,0x5e, 0xf,0x55,0x5f, 0xf,0x55,0x60, + 0xf,0x55,0x61, 0xf,0x55,0x62, 0xf,0x55,0x63, 0xf,0x55,0x66, + 0xf,0x55,0x67, 0xf,0x55,0x68, 0xf,0x55,0x6a, 0xf,0x55,0x6b, + 0xf,0x55,0x6d, 0xf,0x55,0x6e, 0xf,0x55,0x70, 0xf,0x55,0x71, + 0xf,0x55,0x72, 0xf,0x55,0x65, 0x5,0x55,0x38, 0x7,0x2f,0x4d, + 0x7,0x2f,0x4e, 0x7,0x2f,0x5b, 0x7,0x2f,0x5f, 0x7,0x31,0x7a, + 0x7,0x2f,0x51, 0x7,0x2c,0x7b, 0xf,0x55,0x6f, 0x5,0x55,0x3d, + 0x5,0x55,0x39, 0x7,0x2f,0x4c, 0x7,0x24,0x76, 0x7,0x2f,0x57, + 0x7,0x39,0x23, 0x4,0x56,0x61, 0x7,0x39,0x25, 0x5,0x55,0x3e, + 0x7,0x39,0x29, 0x7,0x39,0x28, 0x4,0x56,0x63, 0x7,0x2f,0x68, + 0x5,0x5c,0x21, 0x7,0x38,0x7d, 0x5,0x5c,0x24, 0x5,0x5c,0x22, + 0xf,0x5a,0x71, 0xf,0x5a,0x72, 0xf,0x5a,0x76, 0xf,0x5a,0x77, + 0xf,0x5a,0x78, 0xf,0x5a,0x79, 0xf,0x5a,0x7a, 0xf,0x5a,0x7b, + 0xf,0x5a,0x7c, 0xf,0x5a,0x7d, 0xf,0x5a,0x7e, 0xf,0x5b,0x21, + 0xf,0x5b,0x22, 0xf,0x5b,0x23, 0x7,0x38,0x7e, 0x7,0x39,0x24, + 0x7,0x39,0x22, 0x5,0x5c,0x23, 0x7,0x39,0x21, 0xf,0x55,0x69, + 0x7,0x40,0x4f, 0x4,0x5b,0x62, 0x7,0x40,0x4e, 0x5,0x62,0x4e, + 0x7,0x40,0x4b, 0x7,0x40,0x53, 0x7,0x40,0x51, 0x7,0x40,0x4c, + 0x4,0x5b,0x63, 0x5,0x62,0x4f, 0x5,0x62,0x50, 0x4,0x5b,0x61, + 0x7,0x40,0x54, 0x7,0x40,0x4a, 0x7,0x40,0x52, 0xf,0x5f,0x44, + 0xf,0x5f,0x46, 0xf,0x5f,0x45, 0xf,0x5f,0x47, 0xf,0x5f,0x48, + 0xf,0x5f,0x49, 0xf,0x5f,0x4a, 0xf,0x5f,0x4c, 0xf,0x5f,0x4d, + 0x7,0x40,0x50, 0x7,0x42,0x22, 0x7,0x40,0x55, 0x7,0x40,0x4d, + 0x7,0x40,0x49, 0x7,0x39,0x2a, 0xf,0x61,0x76, 0xf,0x5a,0x74, + 0xf,0x5a,0x75, 0x7,0x47,0x6c, 0x5,0x68,0x37, 0x4,0x60,0x21, + 0x7,0x47,0x6d, 0x4,0x60,0x22, 0x7,0x47,0x6a, 0xf,0x62,0x74, + 0xf,0x62,0x75, 0xf,0x62,0x76, 0xf,0x62,0x77, 0x7,0x47,0x69, + 0x7,0x47,0x67, 0x7,0x47,0x6b, 0xf,0x5f,0x4b, 0x7,0x47,0x68, + 0xf,0x65,0x45, 0x5,0x6c,0x4f, 0x7,0x4e,0x30, 0x7,0x4e,0x33, + 0x7,0x4e,0x3b, 0x5,0x6c,0x4e, 0x5,0x6c,0x4d, 0x5,0x6c,0x51, + 0x4,0x60,0x23, 0x7,0x4e,0x32, 0x7,0x4e,0x38, 0x4,0x63,0x62, + 0x4,0x63,0x60, 0x7,0x4e,0x3c, 0x7,0x4e,0x31, 0x7,0x4e,0x35, + 0x7,0x4e,0x37, 0xf,0x65,0x48, 0x7,0x4e,0x34, 0xf,0x65,0x46, + 0xf,0x65,0x47, 0xf,0x65,0x4a, 0xf,0x65,0x4b, 0xf,0x65,0x4c, + 0xf,0x65,0x4d, 0xf,0x65,0x4e, 0x7,0x4e,0x39, 0x7,0x4e,0x36, + 0x7,0x4e,0x3a, 0x5,0x6c,0x50, 0x7,0x53,0x64, 0x4,0x63,0x61, + 0x7,0x53,0x66, 0x5,0x70,0x43, 0x4,0x66,0x4f, 0x7,0x53,0x67, + 0x7,0x53,0x62, 0x7,0x53,0x63, 0x7,0x53,0x65, 0xf,0x67,0x71, + 0xf,0x67,0x72, 0xf,0x67,0x73, 0xf,0x67,0x74, 0xf,0x67,0x75, + 0x7,0x58,0x36, 0x5,0x73,0x56, 0x4,0x6a,0x4f, 0x7,0x58,0x37, + 0x7,0x58,0x38, 0x7,0x58,0x34, 0xf,0x69,0x56, 0xf,0x69,0x57, + 0xf,0x69,0x58, 0x7,0x58,0x35, 0x7,0x5b,0x24, 0x7,0x5b,0x6e, + 0x7,0x5b,0x70, 0x7,0x5b,0x6d, 0x7,0x5c,0x44, 0x7,0x5b,0x6f, + 0x7,0x5b,0x6c, 0x7,0x5b,0x6b, 0x5,0x76,0x23, 0xf,0x6a,0x60, + 0x7,0x5e,0x78, 0xf,0x6a,0x5f, 0x5,0x77,0x68, 0x7,0x61,0x21, + 0x7,0x60,0x7c, 0x7,0x60,0x7e, 0x7,0x61,0x38, 0x7,0x60,0x7b, + 0x7,0x60,0x7d, 0x7,0x62,0x3a, 0x5,0x7a,0x6b, 0xf,0x6c,0x64, + 0xf,0x6c,0x65, 0x7,0x64,0x4d, 0x7,0x64,0x4c, 0x7,0x64,0x4e, + 0x7,0x65,0x37, 0x7,0x66,0x34, 0x5,0x21,0x4b, 0x6,0x23,0x30, + 0x6,0x28,0x4d, 0x6,0x28,0x4e, 0x5,0x24,0x58, 0x6,0x2c,0x62, + 0x6,0x2c,0x61, 0x6,0x2c,0x63, 0xf,0x27,0x78, 0xf,0x27,0x79, + 0x6,0x32,0x4e, 0x5,0x2a,0x2b, 0x5,0x2a,0x29, 0x6,0x32,0x4f, + 0x5,0x2a,0x2a, 0x6,0x32,0x51, 0xf,0x2c,0x24, 0xf,0x2c,0x25, + 0xf,0x2c,0x26, 0x6,0x32,0x4d, 0x6,0x32,0x50, 0x5,0x2e,0x51, + 0x5,0x2e,0x50, 0xf,0x30,0x73, 0x6,0x41,0x57, 0x6,0x41,0x56, + 0x6,0x41,0x58, 0xf,0x36,0x51, 0x4,0x38,0x6a, 0x6,0x4b,0x22, + 0x6,0x47,0x43, 0x6,0x4d,0x5d, 0x6,0x54,0x68, 0x6,0x54,0x69, + 0x6,0x5e,0x53, 0x5,0x47,0x23, 0x6,0x5e,0x56, 0x6,0x5e,0x55, + 0x6,0x5e,0x54, 0x7,0x24,0x7a, 0x5,0x4e,0x2f, 0x7,0x24,0x77, + 0x7,0x24,0x79, 0x7,0x24,0x78, 0x7,0x2f,0x69, 0x7,0x2f,0x6a, + 0x5,0x55,0x3f, 0x4,0x56,0x65, 0xf,0x5b,0x24, 0xf,0x5b,0x25, + 0xf,0x5b,0x26, 0xf,0x55,0x73, 0x7,0x40,0x56, 0x5,0x68,0x38, + 0xf,0x65,0x4f, 0xf,0x65,0x50, 0x7,0x4e,0x3d, 0x7,0x53,0x68, + 0x7,0x5b,0x71, 0x7,0x5e,0x79, 0x7,0x61,0x22, 0xf,0x24,0x73, + 0xf,0x24,0x74, 0x6,0x2c,0x64, 0x6,0x2c,0x65, 0x6,0x41,0x59, + 0x6,0x41,0x5a, 0xf,0x3d,0x22, 0xf,0x3d,0x23, 0x6,0x54,0x6a, + 0xf,0x49,0x65, 0x5,0x47,0x24, 0x5,0x55,0x40, 0xf,0x21,0x68, + 0x6,0x2b,0x6b, 0x5,0x2a,0x2c, 0x4,0x2a,0x2b, 0x4,0x2d,0x77, + 0xf,0x30,0x74, 0x5,0x31,0x6c, 0x6,0x4b,0x23, 0x6,0x54,0x6c, + 0x6,0x54,0x6b, 0x5,0x55,0x41, 0x7,0x24,0x7b, 0x7,0x24,0x7c, + 0x5,0x55,0x42, 0x6,0x22,0x25, 0x6,0x23,0x31, 0x6,0x25,0x35, + 0x6,0x28,0x4f, 0x4,0x27,0x2d, 0x6,0x2c,0x67, 0x6,0x2c,0x66, + 0x6,0x32,0x52, 0x4,0x2a,0x2d, 0x6,0x32,0x53, 0x6,0x32,0x54, + 0x6,0x39,0x3e, 0x4,0x2d,0x78, 0xf,0x30,0x75, 0x6,0x39,0x3d, + 0x6,0x41,0x5b, 0x6,0x41,0x5e, 0x6,0x41,0x5d, 0x4,0x32,0x78, + 0x6,0x41,0x5c, 0xf,0x36,0x52, 0xf,0x36,0x53, 0x6,0x4b,0x28, + 0x6,0x4b,0x24, 0x6,0x4b,0x26, 0x6,0x4b,0x27, 0x6,0x4b,0x29, + 0x6,0x4b,0x25, 0x6,0x4d,0x58, 0x6,0x54,0x6d, 0x6,0x54,0x6e, + 0xf,0x43,0x3f, 0x6,0x5e,0x58, 0x6,0x5e,0x59, 0xf,0x49,0x66, + 0x7,0x24,0x7d, 0xf,0x50,0x3e, 0x7,0x24,0x7e, 0x5,0x55,0x43, + 0x5,0x62,0x51, 0x4,0x51,0x2c, 0x7,0x2f,0x6b, 0x7,0x25,0x21, + 0x5,0x55,0x44, 0x7,0x39,0x2b, 0x7,0x39,0x2c, 0x5,0x5c,0x25, + 0x7,0x47,0x70, 0x5,0x6c,0x52, 0x7,0x58,0x39, 0x7,0x5b,0x72, + 0x7,0x63,0x58, 0x5,0x7b,0x42, 0x7,0x64,0x4f, 0xf,0x21,0x69, + 0x6,0x28,0x51, 0x5,0x24,0x59, 0x6,0x28,0x50, 0x4,0x27,0x2e, + 0x6,0x2c,0x6b, 0x6,0x2c,0x6a, 0x6,0x2c,0x69, 0x6,0x2c,0x68, + 0x6,0x32,0x56, 0x6,0x32,0x55, 0x5,0x2a,0x2d, 0x6,0x32,0x57, + 0x5,0x2a,0x2e, 0x5,0x2e,0x52, 0x4,0x2d,0x79, 0x4,0x2d,0x7b, + 0x6,0x39,0x41, 0x6,0x39,0x3f, 0x5,0x33,0x46, 0x5,0x33,0x47, + 0x6,0x41,0x5f, 0x6,0x41,0x62, 0x6,0x41,0x60, 0x6,0x4b,0x2b, + 0x4,0x38,0x6d, 0x6,0x4b,0x2e, 0x6,0x4b,0x2a, 0x6,0x4b,0x2c, + 0x6,0x4b,0x2d, 0x5,0x39,0x73, 0x5,0x39,0x76, 0x5,0x39,0x74, + 0x5,0x39,0x75, 0x4,0x38,0x6e, 0x5,0x40,0x38, 0x6,0x54,0x6f, + 0x4,0x3e,0x4d, 0x5,0x40,0x36, 0x5,0x40,0x37, 0x6,0x54,0x70, + 0xf,0x3d,0x24, 0x5,0x47,0x25, 0x6,0x5e,0x5b, 0x6,0x5e,0x5c, + 0x6,0x5e,0x5a, 0xf,0x49,0x67, 0x5,0x4e,0x32, 0x7,0x25,0x25, + 0x5,0x4e,0x31, 0x5,0x4e,0x30, 0x5,0x4e,0x33, 0x7,0x25,0x24, + 0x7,0x25,0x22, 0x5,0x4e,0x34, 0x7,0x25,0x23, 0x5,0x55,0x46, + 0x5,0x55,0x47, 0x5,0x55,0x48, 0x7,0x2f,0x6d, 0x5,0x55,0x45, + 0x7,0x2f,0x6c, 0x5,0x5c,0x26, 0x4,0x56,0x66, 0xf,0x5b,0x27, + 0xf,0x5b,0x28, 0x5,0x62,0x53, 0x5,0x62,0x52, 0x5,0x6c,0x53, + 0x7,0x53,0x69, 0x5,0x23,0x68, 0x6,0x39,0x43, 0x6,0x39,0x42, + 0x4,0x38,0x6f, 0x6,0x4b,0x2f, 0xf,0x3d,0x25, 0xf,0x3d,0x26, + 0x6,0x54,0x71, 0x6,0x5e,0x5d, 0x5,0x21,0x75, 0xf,0x22,0x63, + 0x6,0x25,0x36, 0xf,0x22,0x62, 0x6,0x28,0x53, 0xf,0x24,0x75, + 0x6,0x28,0x52, 0x6,0x28,0x54, 0x5,0x26,0x79, 0x5,0x27,0x22, + 0x5,0x26,0x78, 0x5,0x26,0x7b, 0x5,0x26,0x76, 0x5,0x26,0x7d, + 0x6,0x2c,0x6e, 0x4,0x27,0x30, 0x5,0x27,0x21, 0x6,0x2c,0x6c, + 0x5,0x26,0x7e, 0x5,0x27,0x23, 0x5,0x26,0x7c, 0x6,0x2c,0x6d, + 0xf,0x27,0x7b, 0xf,0x27,0x7c, 0xf,0x27,0x7e, 0xf,0x28,0x21, + 0x5,0x26,0x7a, 0x6,0x2c,0x6f, 0x6,0x2c,0x70, 0x5,0x2a,0x32, + 0x5,0x2a,0x30, 0x5,0x2a,0x2f, 0x6,0x32,0x5f, 0x6,0x32,0x5c, + 0x5,0x2a,0x33, 0x5,0x2a,0x31, 0x4,0x2a,0x30, 0x6,0x32,0x5a, + 0x6,0x32,0x59, 0xf,0x2c,0x28, 0xf,0x2c,0x29, 0x6,0x32,0x5b, + 0x6,0x32,0x5e, 0x6,0x32,0x58, 0x6,0x32,0x5d, 0x5,0x2a,0x34, + 0xf,0x27,0x7d, 0x5,0x2e,0x58, 0x5,0x2e,0x54, 0x5,0x2e,0x56, + 0x5,0x2e,0x57, 0x5,0x2e,0x55, 0x6,0x39,0x44, 0x5,0x2e,0x59, + 0x4,0x32,0x7b, 0x6,0x41,0x67, 0x6,0x41,0x68, 0x5,0x33,0x49, + 0x5,0x39,0x77, 0x4,0x32,0x7d, 0x4,0x32,0x7c, 0x5,0x33,0x4b, + 0x5,0x33,0x4c, 0xf,0x36,0x54, 0xf,0x36,0x55, 0x6,0x41,0x65, + 0x6,0x41,0x69, 0x6,0x41,0x64, 0x5,0x33,0x48, 0x4,0x38,0x71, + 0x4,0x38,0x74, 0x5,0x39,0x7d, 0x6,0x4b,0x34, 0x5,0x39,0x79, + 0x5,0x39,0x7b, 0x5,0x39,0x78, 0x6,0x4b,0x32, 0x6,0x4b,0x35, + 0xf,0x3d,0x27, 0xf,0x3d,0x28, 0x6,0x4b,0x33, 0x6,0x4b,0x30, + 0x6,0x4b,0x31, 0x5,0x39,0x7a, 0x5,0x39,0x7c, 0x5,0x33,0x4a, + 0xf,0x3d,0x29, 0x6,0x4b,0x36, 0x5,0x47,0x2b, 0x5,0x40,0x3e, + 0x5,0x40,0x3c, 0x4,0x3e,0x50, 0x6,0x5e,0x64, 0x6,0x54,0x73, + 0x5,0x47,0x26, 0x6,0x54,0x72, 0x6,0x54,0x75, 0x6,0x54,0x74, + 0xf,0x43,0x40, 0xf,0x43,0x41, 0x5,0x40,0x3d, 0x6,0x54,0x77, + 0x5,0x40,0x3b, 0x4,0x44,0x61, 0x5,0x47,0x2d, 0x5,0x47,0x28, + 0x5,0x47,0x2e, 0x5,0x47,0x2c, 0x6,0x5e,0x5f, 0x6,0x5e,0x63, + 0x5,0x47,0x27, 0x5,0x47,0x2a, 0x6,0x5e,0x67, 0x6,0x5e,0x62, + 0x6,0x5e,0x61, 0x5,0x40,0x3a, 0x6,0x5e,0x66, 0xf,0x49,0x68, + 0xf,0x49,0x69, 0xf,0x49,0x6a, 0xf,0x49,0x6b, 0x5,0x47,0x2f, + 0x5,0x47,0x29, 0x6,0x5e,0x60, 0x6,0x54,0x76, 0x6,0x5e,0x65, + 0xf,0x49,0x6c, 0x5,0x47,0x30, 0x5,0x4e,0x36, 0x7,0x25,0x26, + 0x4,0x4a,0x74, 0x5,0x4e,0x39, 0x5,0x4e,0x3a, 0x5,0x4e,0x38, + 0x4,0x4a,0x70, 0x5,0x4e,0x35, 0xf,0x50,0x3f, 0x7,0x25,0x28, + 0x7,0x25,0x27, 0x7,0x2f,0x70, 0x5,0x55,0x49, 0x5,0x55,0x4e, + 0x7,0x2f,0x71, 0x5,0x55,0x4b, 0x5,0x55,0x4d, 0x5,0x55,0x4a, + 0x5,0x55,0x4c, 0x7,0x2f,0x6f, 0x7,0x39,0x30, 0x7,0x39,0x2e, + 0x5,0x5c,0x27, 0x4,0x56,0x68, 0x4,0x56,0x69, 0x7,0x2f,0x6e, + 0x7,0x39,0x2f, 0x7,0x40,0x57, 0x7,0x40,0x58, 0x5,0x68,0x3a, + 0x7,0x53,0x6a, 0x7,0x47,0x72, 0x7,0x47,0x73, 0x7,0x47,0x71, + 0x5,0x68,0x39, 0x7,0x4e,0x3f, 0x5,0x6c,0x54, 0x5,0x6c,0x55, + 0x5,0x70,0x45, 0x7,0x53,0x6c, 0x5,0x70,0x44, 0x5,0x70,0x46, + 0x7,0x58,0x3a, 0x5,0x73,0x59, 0x7,0x5b,0x74, 0x5,0x73,0x58, + 0x7,0x5b,0x75, 0x7,0x5b,0x73, 0x5,0x77,0x69, 0x7,0x61,0x23, + 0xf,0x6c,0x31, 0x7,0x64,0x50, 0xf,0x21,0x3d, 0x6,0x23,0x32, + 0x5,0x21,0x77, 0x5,0x21,0x78, 0x5,0x22,0x78, 0x5,0x22,0x7b, + 0x5,0x22,0x77, 0x4,0x23,0x28, 0x5,0x22,0x7a, 0x6,0x25,0x37, + 0x5,0x22,0x79, 0x5,0x24,0x5e, 0x5,0x24,0x5f, 0x4,0x24,0x5b, + 0x4,0x27,0x37, 0x6,0x28,0x58, 0x4,0x24,0x5a, 0x5,0x24,0x5a, + 0x6,0x28,0x5e, 0x5,0x24,0x5b, 0x6,0x28,0x5b, 0x5,0x27,0x2f, + 0x6,0x2c,0x72, 0x4,0x24,0x57, 0x5,0x24,0x5d, 0x5,0x24,0x5c, + 0x6,0x28,0x5a, 0x6,0x28,0x59, 0x6,0x2c,0x73, 0xf,0x24,0x77, + 0x6,0x28,0x57, 0x6,0x28,0x5c, 0x6,0x28,0x5d, 0x6,0x28,0x56, + 0x4,0x24,0x58, 0x6,0x2c,0x7a, 0x5,0x27,0x28, 0x6,0x2c,0x7b, + 0x5,0x27,0x2c, 0x6,0x2c,0x79, 0x6,0x2c,0x7c, 0x5,0x27,0x27, + 0x5,0x27,0x2a, 0x6,0x2c,0x78, 0x5,0x27,0x2d, 0x5,0x27,0x25, + 0x5,0x27,0x29, 0x5,0x27,0x24, 0x6,0x2c,0x77, 0x4,0x27,0x38, + 0x5,0x2a,0x36, 0x6,0x28,0x55, 0x6,0x32,0x60, 0x5,0x27,0x2b, + 0x6,0x2c,0x76, 0xf,0x28,0x22, 0x6,0x2c,0x7d, 0x6,0x2c,0x74, + 0x4,0x27,0x35, 0x5,0x2a,0x35, 0x5,0x2a,0x3e, 0x6,0x32,0x68, + 0x5,0x2a,0x39, 0x6,0x39,0x4b, 0x5,0x2a,0x3d, 0x6,0x32,0x61, + 0x6,0x39,0x4c, 0x6,0x41,0x6c, 0x5,0x2a,0x3c, 0x4,0x2a,0x31, + 0x5,0x2a,0x3b, 0x6,0x32,0x64, 0x5,0x2a,0x3a, 0x6,0x32,0x66, + 0x4,0x2a,0x33, 0x5,0x2a,0x40, 0x6,0x32,0x63, 0x5,0x27,0x26, + 0x5,0x2a,0x37, 0x5,0x2a,0x38, 0xf,0x2c,0x2a, 0xf,0x2c,0x2c, + 0xf,0x2c,0x2d, 0x6,0x32,0x65, 0xf,0x2c,0x2b, 0x5,0x2a,0x3f, + 0x6,0x39,0x4e, 0x5,0x2e,0x5e, 0x4,0x33,0x21, 0x6,0x39,0x49, + 0x6,0x39,0x4d, 0x4,0x2e,0x25, 0x5,0x2e,0x5b, 0x5,0x2e,0x60, + 0x5,0x2e,0x5d, 0x4,0x2e,0x23, 0x6,0x39,0x45, 0x6,0x39,0x4a, + 0xf,0x30,0x77, 0xf,0x30,0x78, 0x6,0x39,0x48, 0x5,0x2e,0x5a, + 0x4,0x2e,0x24, 0x6,0x39,0x47, 0x6,0x39,0x4f, 0x5,0x2e,0x5f, + 0x6,0x39,0x46, 0x5,0x33,0x4e, 0xf,0x30,0x76, 0x4,0x33,0x24, + 0x6,0x41,0x6e, 0x5,0x33,0x55, 0x5,0x39,0x7e, 0x5,0x33,0x52, + 0x6,0x41,0x70, 0x6,0x41,0x73, 0x5,0x33,0x4f, 0x6,0x41,0x6f, + 0x6,0x4b,0x3b, 0x4,0x33,0x26, 0x5,0x33,0x53, 0x6,0x4b,0x38, + 0x6,0x4b,0x37, 0x5,0x33,0x50, 0x6,0x4b,0x39, 0x6,0x41,0x71, + 0x6,0x41,0x72, 0x6,0x41,0x74, 0x6,0x4b,0x3a, 0x5,0x3a,0x28, + 0x6,0x54,0x7b, 0x5,0x3a,0x26, 0x5,0x40,0x3f, 0x4,0x38,0x75, + 0x5,0x3a,0x22, 0x6,0x4b,0x44, 0x5,0x40,0x40, 0x5,0x3a,0x27, + 0x4,0x38,0x76, 0x5,0x3a,0x25, 0x5,0x3a,0x24, 0x4,0x38,0x78, + 0x6,0x4b,0x3f, 0x4,0x3e,0x51, 0x5,0x3a,0x21, 0x6,0x4b,0x3c, + 0x6,0x4b,0x3e, 0x4,0x3e,0x57, 0xf,0x3d,0x2a, 0xf,0x3d,0x2b, + 0x6,0x54,0x79, 0x6,0x52,0x72, 0x6,0x54,0x7a, 0x6,0x4b,0x40, + 0x6,0x4b,0x41, 0x6,0x4b,0x45, 0x6,0x4b,0x3d, 0x5,0x3a,0x23, + 0xf,0x43,0x43, 0x4,0x3e,0x56, 0x5,0x40,0x48, 0x6,0x55,0x22, + 0x5,0x40,0x47, 0x4,0x3e,0x55, 0x6,0x55,0x27, 0x5,0x40,0x4b, + 0x6,0x55,0x24, 0x6,0x54,0x7e, 0x6,0x54,0x7d, 0x6,0x55,0x26, + 0x5,0x40,0x46, 0x5,0x40,0x44, 0x5,0x40,0x43, 0x6,0x55,0x21, + 0x5,0x40,0x42, 0x6,0x55,0x28, 0x5,0x40,0x4a, 0x5,0x40,0x41, + 0x4,0x3e,0x58, 0x5,0x40,0x49, 0x6,0x55,0x25, 0xf,0x43,0x45, + 0xf,0x43,0x46, 0xf,0x49,0x70, 0xf,0x50,0x40, 0x5,0x40,0x45, + 0x6,0x55,0x23, 0x5,0x40,0x4c, 0x6,0x5e,0x6d, 0x5,0x47,0x3a, + 0x6,0x5e,0x69, 0x7,0x25,0x29, 0x5,0x47,0x37, 0x4,0x44,0x6b, + 0x5,0x47,0x35, 0x5,0x47,0x33, 0x6,0x5e,0x6c, 0x5,0x47,0x3b, + 0x5,0x47,0x36, 0x5,0x47,0x34, 0x6,0x5e,0x70, 0x4,0x44,0x6c, + 0x5,0x47,0x31, 0xf,0x49,0x6d, 0x7,0x25,0x2a, 0xf,0x49,0x6f, + 0x6,0x5e,0x6b, 0x6,0x5e,0x68, 0x6,0x5e,0x6a, 0x6,0x5e,0x6f, + 0x4,0x4a,0x7d, 0x5,0x47,0x3d, 0x5,0x47,0x3c, 0x5,0x47,0x39, + 0x5,0x47,0x38, 0x6,0x5e,0x71, 0x5,0x47,0x32, 0x7,0x25,0x31, + 0x4,0x4a,0x78, 0x4,0x4a,0x79, 0x7,0x25,0x30, 0x5,0x4e,0x3c, + 0x7,0x25,0x34, 0x7,0x2f,0x73, 0x5,0x4e,0x41, 0x7,0x25,0x2f, + 0x7,0x25,0x2b, 0x5,0x4e,0x3e, 0x5,0x4e,0x45, 0x5,0x4e,0x3b, + 0x5,0x4e,0x44, 0x5,0x4e,0x43, 0x5,0x4e,0x3d, 0x5,0x55,0x4f, + 0x7,0x2f,0x72, 0x5,0x4e,0x3f, 0x5,0x4e,0x40, 0x5,0x4e,0x46, + 0x7,0x25,0x2c, 0x7,0x25,0x2d, 0xf,0x55,0x75, 0x5,0x55,0x50, + 0x7,0x25,0x2e, 0x7,0x25,0x33, 0xf,0x49,0x6e, 0x4,0x51,0x33, + 0x5,0x4e,0x42, 0x5,0x55,0x57, 0x4,0x51,0x35, 0x5,0x55,0x55, + 0x5,0x55,0x51, 0x5,0x55,0x52, 0x7,0x2f,0x79, 0x4,0x51,0x31, + 0x7,0x2f,0x78, 0x7,0x2f,0x77, 0x5,0x5c,0x28, 0x4,0x51,0x36, + 0x5,0x55,0x53, 0x5,0x55,0x56, 0x7,0x2f,0x75, 0x7,0x39,0x32, + 0x4,0x56,0x6d, 0x7,0x39,0x31, 0x7,0x2f,0x76, 0x7,0x25,0x32, + 0xf,0x55,0x77, 0x7,0x25,0x35, 0x5,0x55,0x54, 0x5,0x5c,0x2a, + 0x7,0x39,0x33, 0x5,0x5c,0x29, 0x7,0x47,0x77, 0x7,0x39,0x35, + 0x7,0x39,0x34, 0xf,0x5b,0x29, 0xf,0x5b,0x2a, 0xf,0x5b,0x2b, + 0xf,0x5b,0x2c, 0x7,0x40,0x5d, 0x5,0x62,0x55, 0x5,0x62,0x54, + 0x7,0x40,0x5a, 0x7,0x40,0x59, 0x7,0x40,0x5c, 0x4,0x5b,0x68, + 0x7,0x40,0x5b, 0xf,0x5f,0x4e, 0xf,0x5f,0x4f, 0x5,0x62,0x56, + 0x4,0x63,0x64, 0x7,0x47,0x78, 0x7,0x4e,0x40, 0x7,0x47,0x76, + 0x7,0x47,0x74, 0x7,0x4e,0x41, 0x5,0x6c,0x56, 0x7,0x4e,0x42, + 0x5,0x70,0x48, 0x7,0x53,0x6d, 0x5,0x70,0x47, 0x4,0x68,0x74, + 0x5,0x70,0x49, 0x7,0x58,0x3b, 0x7,0x5b,0x76, 0x7,0x5b,0x78, + 0x7,0x5b,0x77, 0x5,0x77,0x6a, 0x7,0x5e,0x7a, 0xf,0x6b,0x55, + 0x7,0x61,0x24, 0x7,0x63,0x59, 0xf,0x28,0x23, 0x6,0x4b,0x46, + 0x6,0x5e,0x72, 0x5,0x21,0x4c, 0x6,0x25,0x38, 0x6,0x23,0x33, + 0x6,0x28,0x5f, 0x5,0x24,0x61, 0x4,0x24,0x5d, 0x4,0x24,0x5c, + 0x6,0x28,0x61, 0x6,0x28,0x60, 0xf,0x24,0x79, 0x5,0x24,0x60, + 0x5,0x27,0x30, 0x6,0x2d,0x25, 0x4,0x27,0x3c, 0x5,0x2a,0x41, + 0xf,0x28,0x25, 0xf,0x28,0x26, 0xf,0x28,0x27, 0xf,0x28,0x28, + 0xf,0x28,0x29, 0x6,0x2d,0x23, 0xf,0x2c,0x40, 0xf,0x28,0x24, + 0x6,0x2d,0x22, 0xf,0x2c,0x3c, 0x6,0x32,0x69, 0x5,0x2a,0x45, + 0x5,0x2a,0x42, 0x4,0x2a,0x36, 0x6,0x32,0x6b, 0x6,0x2f,0x69, + 0xf,0x2c,0x2f, 0xf,0x2c,0x30, 0xf,0x2c,0x31, 0xf,0x2c,0x33, + 0xf,0x2c,0x34, 0xf,0x2c,0x35, 0xf,0x2c,0x36, 0xf,0x2c,0x37, + 0xf,0x2c,0x38, 0xf,0x2c,0x3a, 0xf,0x2c,0x3b, 0xf,0x2c,0x3d, + 0x6,0x32,0x6a, 0x6,0x32,0x6c, 0xf,0x2c,0x3e, 0xf,0x2c,0x3f, + 0xf,0x2c,0x2e, 0x5,0x2a,0x44, 0x5,0x2a,0x43, 0x6,0x39,0x53, + 0x5,0x33,0x56, 0x5,0x2e,0x61, 0x4,0x2e,0x29, 0x6,0x39,0x51, + 0x4,0x2e,0x28, 0x6,0x39,0x52, 0x6,0x39,0x54, 0xf,0x30,0x79, + 0xf,0x30,0x7a, 0xf,0x30,0x7b, 0xf,0x30,0x7c, 0xf,0x30,0x7d, + 0xf,0x30,0x7e, 0xf,0x31,0x21, 0xf,0x31,0x23, 0xf,0x31,0x24, + 0xf,0x31,0x25, 0xf,0x31,0x26, 0x6,0x39,0x50, 0xf,0x36,0x63, + 0x4,0x33,0x31, 0x6,0x39,0x55, 0x6,0x41,0x7a, 0x5,0x33,0x57, + 0x6,0x41,0x7b, 0x4,0x33,0x32, 0x6,0x41,0x77, 0x6,0x41,0x78, + 0x6,0x41,0x79, 0xf,0x31,0x22, 0xf,0x36,0x56, 0xf,0x36,0x58, + 0xf,0x36,0x5c, 0xf,0x36,0x5f, 0xf,0x36,0x60, 0xf,0x36,0x61, + 0xf,0x36,0x62, 0xf,0x36,0x64, 0xf,0x36,0x5d, 0x6,0x41,0x7c, + 0xf,0x36,0x5b, 0xf,0x36,0x5a, 0xf,0x36,0x5e, 0x5,0x33,0x58, + 0x6,0x41,0x76, 0xf,0x3d,0x3e, 0xf,0x3d,0x34, 0x6,0x4b,0x4b, + 0x5,0x3a,0x2b, 0x5,0x3a,0x2a, 0x5,0x3a,0x2c, 0x6,0x55,0x29, + 0x4,0x3e,0x5a, 0x5,0x40,0x4d, 0xf,0x3d,0x38, 0x4,0x38,0x7c, + 0x6,0x4b,0x49, 0x6,0x4b,0x4c, 0xf,0x3d,0x2c, 0xf,0x3d,0x2d, + 0xf,0x3d,0x2e, 0xf,0x3d,0x2f, 0xf,0x3d,0x30, 0xf,0x3d,0x32, + 0xf,0x3d,0x35, 0xf,0x3d,0x36, 0xf,0x3d,0x37, 0xf,0x3d,0x39, + 0xf,0x3d,0x3a, 0xf,0x3d,0x3f, 0xf,0x43,0x50, 0x6,0x4b,0x4e, + 0x6,0x55,0x32, 0x6,0x4b,0x4d, 0xf,0x3d,0x40, 0x6,0x4b,0x48, + 0x6,0x4b,0x4a, 0x6,0x55,0x2a, 0xf,0x3d,0x33, 0xf,0x3d,0x3d, + 0xf,0x3d,0x31, 0x5,0x3a,0x29, 0x6,0x55,0x2b, 0x6,0x55,0x30, + 0x4,0x3e,0x5b, 0x6,0x55,0x31, 0x6,0x55,0x2f, 0x6,0x55,0x2e, + 0x5,0x47,0x3e, 0xf,0x43,0x47, 0xf,0x43,0x4a, 0xf,0x43,0x4c, + 0xf,0x43,0x4d, 0xf,0x43,0x4e, 0xf,0x43,0x4f, 0xf,0x43,0x51, + 0xf,0x43,0x52, 0xf,0x43,0x53, 0xf,0x43,0x54, 0xf,0x43,0x55, + 0xf,0x43,0x57, 0xf,0x43,0x58, 0xf,0x43,0x5a, 0xf,0x43,0x5b, + 0xf,0x43,0x5c, 0xf,0x43,0x5d, 0xf,0x43,0x5e, 0xf,0x43,0x5f, + 0xf,0x43,0x60, 0xf,0x43,0x61, 0xf,0x43,0x62, 0xf,0x43,0x63, + 0xf,0x43,0x65, 0x6,0x55,0x2c, 0x5,0x40,0x4f, 0x5,0x3a,0x2e, + 0xf,0x43,0x4b, 0xf,0x43,0x48, 0x5,0x47,0x3f, 0x6,0x55,0x2d, + 0xf,0x43,0x59, 0xf,0x49,0x7a, 0xf,0x49,0x7b, 0xf,0x4a,0x26, + 0x7,0x25,0x38, 0x6,0x5e,0x74, 0x5,0x47,0x41, 0x7,0x25,0x36, + 0x4,0x44,0x6d, 0x5,0x47,0x40, 0x6,0x5e,0x75, 0x6,0x5e,0x77, + 0x6,0x5e,0x76, 0x6,0x5e,0x73, 0xf,0x49,0x71, 0xf,0x49,0x72, + 0xf,0x49,0x73, 0xf,0x49,0x74, 0xf,0x49,0x75, 0xf,0x49,0x77, + 0xf,0x49,0x78, 0xf,0x49,0x79, 0xf,0x49,0x7c, 0xf,0x49,0x7d, + 0xf,0x49,0x7e, 0xf,0x4a,0x21, 0xf,0x4a,0x22, 0xf,0x4a,0x24, + 0xf,0x4a,0x25, 0xf,0x4a,0x27, 0xf,0x4a,0x28, 0xf,0x4a,0x29, + 0x5,0x47,0x42, 0x3,0x48,0x26, 0x7,0x25,0x39, 0xf,0x4a,0x23, + 0x7,0x25,0x40, 0x4,0x4a,0x7e, 0x5,0x4e,0x47, 0x7,0x2f,0x7b, + 0x7,0x25,0x3a, 0x7,0x2f,0x7a, 0x7,0x25,0x3c, 0x7,0x25,0x3f, + 0x7,0x25,0x41, 0x7,0x25,0x42, 0xf,0x50,0x41, 0xf,0x50,0x42, + 0xf,0x50,0x43, 0xf,0x50,0x44, 0xf,0x50,0x45, 0xf,0x50,0x46, + 0xf,0x50,0x48, 0xf,0x50,0x49, 0xf,0x50,0x4a, 0xf,0x50,0x4b, + 0xf,0x50,0x4c, 0x7,0x25,0x3d, 0x5,0x4e,0x48, 0x7,0x25,0x3b, + 0x5,0x4e,0x49, 0xf,0x55,0x7c, 0xf,0x56,0x2e, 0xf,0x50,0x47, + 0x7,0x30,0x22, 0x7,0x25,0x3e, 0x5,0x55,0x58, 0x5,0x55,0x5b, + 0x5,0x55,0x59, 0x4,0x51,0x3b, 0x7,0x30,0x24, 0x7,0x2f,0x7d, + 0x7,0x2f,0x7e, 0x7,0x2f,0x7c, 0x4,0x51,0x3c, 0x7,0x30,0x21, + 0xf,0x55,0x78, 0xf,0x55,0x79, 0xf,0x55,0x7b, 0xf,0x55,0x7d, + 0xf,0x56,0x23, 0xf,0x56,0x24, 0xf,0x56,0x25, 0xf,0x56,0x26, + 0xf,0x56,0x27, 0xf,0x56,0x29, 0xf,0x56,0x2d, 0xf,0x56,0x2f, + 0x7,0x30,0x25, 0x7,0x30,0x23, 0x7,0x39,0x36, 0xf,0x56,0x30, + 0xf,0x56,0x21, 0xf,0x56,0x28, 0x5,0x55,0x5c, 0x5,0x55,0x5a, + 0xf,0x56,0x2c, 0x7,0x39,0x3b, 0x7,0x39,0x3d, 0x5,0x5c,0x2d, + 0x5,0x5c,0x2b, 0x7,0x40,0x5e, 0x7,0x39,0x39, 0x4,0x5b,0x6a, + 0x4,0x56,0x6e, 0x4,0x56,0x70, 0x7,0x39,0x38, 0xf,0x5b,0x2e, + 0xf,0x5b,0x2f, 0xf,0x5b,0x30, 0xf,0x5b,0x31, 0xf,0x5b,0x32, + 0xf,0x5b,0x33, 0xf,0x5b,0x34, 0xf,0x5b,0x35, 0x5,0x5c,0x2c, + 0x7,0x39,0x3a, 0x7,0x39,0x3c, 0x7,0x39,0x37, 0x7,0x40,0x5f, + 0x5,0x68,0x3c, 0x4,0x5b,0x6b, 0x5,0x62,0x57, 0x4,0x60,0x26, + 0x7,0x40,0x60, 0x4,0x60,0x28, 0xf,0x5f,0x51, 0xf,0x5f,0x53, + 0xf,0x5f,0x54, 0xf,0x5f,0x55, 0xf,0x5f,0x57, 0xf,0x5f,0x59, + 0xf,0x5f,0x5a, 0xf,0x5f,0x5b, 0xf,0x5f,0x5c, 0xf,0x5f,0x5f, + 0x7,0x40,0x61, 0x7,0x40,0x62, 0xf,0x5f,0x50, 0xf,0x5f,0x52, + 0xf,0x5f,0x58, 0xf,0x63,0x23, 0x7,0x47,0x7c, 0x7,0x47,0x7b, + 0x5,0x68,0x3e, 0x7,0x47,0x7a, 0x7,0x4e,0x43, 0x5,0x68,0x3d, + 0x7,0x47,0x79, 0xf,0x62,0x7c, 0xf,0x62,0x7e, 0xf,0x63,0x21, + 0xf,0x63,0x22, 0x4,0x60,0x29, 0xf,0x62,0x79, 0xf,0x62,0x7a, + 0xf,0x62,0x7d, 0x7,0x53,0x6f, 0x5,0x6c,0x57, 0x4,0x66,0x52, + 0xf,0x65,0x52, 0xf,0x65,0x53, 0xf,0x65,0x54, 0xf,0x65,0x55, + 0x7,0x4e,0x44, 0x7,0x53,0x6e, 0xf,0x5f,0x5e, 0x4,0x66,0x51, + 0x7,0x55,0x7c, 0x4,0x66,0x53, 0x7,0x58,0x3c, 0xf,0x67,0x76, + 0x7,0x5b,0x79, 0x4,0x6a,0x52, 0xf,0x69,0x59, 0xf,0x69,0x5a, + 0x5,0x76,0x24, 0xf,0x6a,0x61, 0xf,0x6a,0x63, 0xf,0x6b,0x56, + 0xf,0x6a,0x62, 0x5,0x79,0x31, 0x7,0x61,0x26, 0x7,0x61,0x25, + 0xf,0x6c,0x32, 0x5,0x7a,0x2c, 0x4,0x6e,0x34, 0x6,0x2d,0x26, + 0x5,0x2a,0x47, 0x5,0x2a,0x46, 0x6,0x32,0x6d, 0xf,0x2c,0x41, + 0x6,0x32,0x6e, 0x6,0x39,0x56, 0x5,0x2e,0x63, 0x5,0x2e,0x64, + 0x6,0x39,0x57, 0x6,0x39,0x58, 0x4,0x33,0x36, 0x5,0x33,0x59, + 0x5,0x33,0x5a, 0xf,0x36,0x65, 0x5,0x3a,0x2f, 0x5,0x3a,0x30, + 0x6,0x4b,0x4f, 0xf,0x3d,0x41, 0x6,0x4b,0x50, 0x4,0x3e,0x5c, + 0x5,0x40,0x50, 0x5,0x40,0x51, 0xf,0x43,0x66, 0x7,0x25,0x45, + 0x6,0x5e,0x78, 0x5,0x47,0x43, 0xf,0x4a,0x2a, 0x5,0x47,0x44, + 0x7,0x25,0x44, 0x7,0x30,0x26, 0x4,0x51,0x3d, 0x5,0x4e,0x4a, + 0xf,0x50,0x4d, 0x7,0x25,0x43, 0x4,0x51,0x3e, 0x7,0x39,0x3e, + 0x5,0x62,0x58, 0xf,0x5f,0x60, 0x4,0x5b,0x6d, 0x4,0x66,0x54, + 0x7,0x53,0x70, 0x5,0x70,0x4a, 0x5,0x76,0x25, 0x7,0x5b,0x7a, + 0x7,0x5e,0x7b, 0x7,0x62,0x3b, 0x7,0x62,0x3c, 0x5,0x24,0x62, + 0x5,0x27,0x31, 0x4,0x27,0x3d, 0x6,0x2d,0x27, 0x5,0x2a,0x48, + 0x5,0x2a,0x49, 0x6,0x32,0x6f, 0x4,0x2a,0x3b, 0x4,0x2a,0x3e, + 0x5,0x2e,0x65, 0x5,0x2e,0x67, 0x6,0x39,0x5c, 0x5,0x2e,0x66, + 0xf,0x31,0x29, 0x6,0x39,0x5b, 0x6,0x39,0x59, 0x6,0x39,0x5a, + 0x5,0x33,0x5d, 0x6,0x42,0x22, 0x6,0x41,0x7e, 0x6,0x42,0x24, + 0x5,0x33,0x5e, 0x6,0x42,0x23, 0x5,0x33,0x5c, 0xf,0x36,0x66, + 0xf,0x36,0x68, 0x4,0x39,0x22, 0x5,0x3a,0x31, 0x6,0x55,0x36, + 0x4,0x39,0x27, 0x5,0x3a,0x34, 0x5,0x3a,0x33, 0x5,0x33,0x5f, + 0x6,0x4b,0x52, 0x5,0x3a,0x32, 0x5,0x33,0x5b, 0x6,0x4b,0x51, + 0x6,0x4b,0x53, 0x4,0x3e,0x64, 0x5,0x40,0x52, 0x6,0x55,0x37, + 0x4,0x3e,0x5e, 0x5,0x40,0x53, 0x6,0x55,0x33, 0x6,0x55,0x35, + 0x4,0x3e,0x5f, 0x6,0x55,0x38, 0xf,0x43,0x67, 0x6,0x55,0x34, + 0x5,0x47,0x47, 0x6,0x5e,0x7c, 0x5,0x47,0x45, 0x6,0x5e,0x7a, + 0x4,0x44,0x72, 0x6,0x5e,0x79, 0x6,0x5e,0x7b, 0x5,0x47,0x46, + 0x4,0x4b,0x28, 0x7,0x25,0x4a, 0x5,0x4e,0x4c, 0x5,0x4e,0x4d, + 0x5,0x4e,0x4e, 0x7,0x25,0x46, 0x7,0x25,0x47, 0x7,0x25,0x49, + 0x7,0x30,0x27, 0x4,0x56,0x74, 0x7,0x30,0x28, 0x5,0x55,0x5f, + 0x5,0x55,0x61, 0x4,0x51,0x40, 0x5,0x55,0x60, 0x5,0x55,0x5e, + 0x4,0x56,0x76, 0x5,0x5c,0x2e, 0x4,0x56,0x77, 0x7,0x39,0x40, + 0x7,0x39,0x3f, 0x5,0x4e,0x4b, 0x4,0x5b,0x70, 0x5,0x62,0x5b, + 0x5,0x62,0x5a, 0x7,0x40,0x64, 0x5,0x62,0x59, 0x7,0x40,0x65, + 0x5,0x68,0x3f, 0x7,0x4e,0x45, 0x7,0x53,0x71, 0x7,0x53,0x72, + 0x4,0x66,0x56, 0x5,0x70,0x4b, 0x4,0x66,0x55, 0x7,0x53,0x73, + 0x4,0x68,0x76, 0x7,0x58,0x3d, 0x5,0x73,0x5a, 0x5,0x76,0x28, + 0x5,0x76,0x27, 0x7,0x5b,0x7b, 0x5,0x76,0x26, 0x7,0x5c,0x6b, + 0x5,0x7a,0x6c, 0x7,0x65,0x38, 0x6,0x23,0x34, 0x6,0x2d,0x28, + 0x5,0x27,0x33, 0x4,0x27,0x3e, 0xf,0x28,0x2b, 0x6,0x32,0x70, + 0xf,0x2c,0x43, 0x5,0x40,0x54, 0x6,0x5e,0x7d, 0x7,0x30,0x2b, + 0x7,0x30,0x29, 0x7,0x30,0x2a, 0x4,0x56,0x79, 0x7,0x40,0x66, + 0x5,0x70,0x4c, 0x6,0x23,0x35, 0x6,0x25,0x39, 0x6,0x2d,0x29, + 0x5,0x27,0x34, 0x6,0x2d,0x2a, 0xf,0x2c,0x44, 0xf,0x2c,0x45, + 0x5,0x2a,0x4a, 0x4,0x2a,0x3f, 0x6,0x32,0x71, 0x6,0x34,0x79, + 0x5,0x2e,0x69, 0x6,0x42,0x26, 0x5,0x33,0x60, 0x6,0x42,0x25, + 0x6,0x42,0x27, 0xf,0x36,0x69, 0x6,0x55,0x39, 0x6,0x4b,0x54, + 0xf,0x3d,0x43, 0xf,0x3d,0x42, 0x6,0x55,0x3b, 0xf,0x43,0x68, + 0x6,0x55,0x3a, 0x6,0x5e,0x7e, 0x7,0x25,0x4b, 0xf,0x4a,0x2b, + 0x4,0x56,0x7a, 0xf,0x5b,0x36, 0xf,0x63,0x26, 0x7,0x46,0x6e, + 0xf,0x63,0x25, 0x7,0x53,0x74, 0x6,0x25,0x3a, 0xf,0x24,0x7a, + 0x5,0x27,0x35, 0x6,0x2d,0x2e, 0x6,0x39,0x5d, 0x5,0x33,0x61, + 0xf,0x4a,0x2c, 0xf,0x5f,0x61, 0x7,0x47,0x7d, 0xf,0x6c,0x33, + 0x5,0x73,0x5b, 0x4,0x24,0x5f, 0xf,0x24,0x7c, 0xf,0x24,0x7b, + 0x6,0x28,0x63, 0x4,0x27,0x42, 0x4,0x25,0x53, 0x4,0x27,0x3f, + 0x5,0x27,0x36, 0x6,0x2d,0x31, 0x6,0x2d,0x30, 0x6,0x2d,0x33, + 0xf,0x28,0x2c, 0xf,0x28,0x2d, 0x6,0x2d,0x2f, 0x4,0x2a,0x42, + 0x5,0x2a,0x4d, 0x6,0x32,0x74, 0x5,0x2a,0x4c, 0x6,0x32,0x73, + 0x5,0x2a,0x4b, 0x6,0x32,0x76, 0x6,0x32,0x7a, 0x6,0x32,0x77, + 0x6,0x39,0x65, 0x5,0x2a,0x4e, 0x6,0x32,0x78, 0x6,0x32,0x75, + 0x5,0x2e,0x6e, 0xf,0x2c,0x46, 0xf,0x2c,0x47, 0xf,0x2c,0x48, + 0xf,0x2c,0x49, 0xf,0x2c,0x4b, 0xf,0x2c,0x4c, 0xf,0x2c,0x4d, + 0xf,0x2c,0x4e, 0xf,0x2c,0x4f, 0x5,0x2a,0x4f, 0x5,0x2e,0x6a, + 0x4,0x2e,0x2e, 0x5,0x2e,0x6b, 0x6,0x39,0x61, 0x6,0x39,0x60, + 0x6,0x39,0x62, 0x6,0x39,0x5f, 0x6,0x39,0x63, 0xf,0x31,0x2a, + 0xf,0x31,0x2b, 0xf,0x31,0x2c, 0xf,0x31,0x2e, 0x4,0x2e,0x30, + 0xf,0x31,0x2d, 0x5,0x2e,0x6d, 0x5,0x2e,0x6c, 0x4,0x33,0x3e, + 0x6,0x42,0x28, 0x5,0x33,0x63, 0x5,0x33,0x62, 0x4,0x33,0x3d, + 0x6,0x42,0x2c, 0x6,0x42,0x2f, 0x6,0x42,0x2a, 0x6,0x42,0x2d, + 0x6,0x42,0x2e, 0xf,0x36,0x6b, 0xf,0x36,0x6c, 0x6,0x42,0x2b, + 0x6,0x42,0x29, 0x6,0x41,0x6b, 0x4,0x39,0x2b, 0x4,0x39,0x29, + 0x4,0x39,0x2a, 0x6,0x4b,0x57, 0x6,0x4b,0x59, 0xf,0x36,0x6a, + 0xf,0x3d,0x46, 0xf,0x3d,0x47, 0xf,0x3d,0x48, 0x6,0x4b,0x58, + 0x4,0x39,0x2d, 0x6,0x4b,0x55, 0xf,0x3d,0x44, 0xf,0x3d,0x45, + 0x6,0x55,0x40, 0x4,0x3e,0x6a, 0x4,0x3e,0x67, 0x6,0x55,0x3e, + 0x6,0x55,0x3f, 0x4,0x3e,0x66, 0x5,0x40,0x56, 0x6,0x55,0x3c, + 0x6,0x55,0x42, 0x5,0x40,0x55, 0x6,0x55,0x43, 0x6,0x55,0x44, + 0x6,0x55,0x41, 0xf,0x43,0x69, 0xf,0x43,0x6a, 0x5,0x40,0x57, + 0x6,0x55,0x3d, 0x6,0x5f,0x23, 0x4,0x44,0x7a, 0x5,0x47,0x4a, + 0x6,0x5f,0x22, 0x6,0x5f,0x25, 0x6,0x5f,0x28, 0xf,0x4a,0x2d, + 0x6,0x5f,0x26, 0x6,0x5f,0x24, 0x6,0x5f,0x27, 0x7,0x25,0x50, + 0x4,0x4b,0x2c, 0x7,0x25,0x4c, 0x7,0x25,0x4e, 0x7,0x25,0x4d, + 0x7,0x25,0x4f, 0x5,0x4e,0x4f, 0x7,0x25,0x51, 0xf,0x50,0x4f, + 0x4,0x4b,0x2b, 0x4,0x51,0x45, 0x4,0x51,0x43, 0x4,0x51,0x46, + 0x7,0x30,0x2c, 0x5,0x55,0x62, 0xf,0x56,0x32, 0x7,0x2c,0x3b, + 0x7,0x39,0x41, 0x5,0x5c,0x33, 0x7,0x39,0x43, 0x5,0x5c,0x31, + 0x4,0x56,0x7b, 0x7,0x39,0x42, 0x5,0x5c,0x34, 0xf,0x5b,0x37, + 0x7,0x3c,0x76, 0x5,0x5c,0x30, 0x5,0x5c,0x32, 0xf,0x56,0x31, + 0x4,0x5b,0x71, 0x7,0x47,0x7e, 0x5,0x68,0x41, 0x7,0x48,0x23, + 0x7,0x4e,0x46, 0x7,0x48,0x21, 0x7,0x48,0x24, 0x4,0x60,0x2d, + 0x7,0x48,0x22, 0x7,0x4e,0x48, 0x7,0x4e,0x47, 0x7,0x53,0x77, + 0xf,0x67,0x77, 0x7,0x53,0x75, 0x7,0x53,0x76, 0xf,0x67,0x52, + 0x7,0x58,0x3e, 0x4,0x68,0x77, 0x7,0x53,0x78, 0x7,0x5b,0x7d, + 0xf,0x6a,0x64, 0x7,0x5b,0x7c, 0x7,0x5e,0x7c, 0x7,0x62,0x3e, + 0x7,0x62,0x3d, 0x7,0x63,0x5a, 0x7,0x63,0x5c, 0x7,0x63,0x5b, + 0x7,0x66,0x29, 0x7,0x66,0x35, 0x7,0x66,0x46, 0x6,0x23,0x36, + 0x6,0x25,0x3b, 0xf,0x28,0x2e, 0x4,0x2e,0x32, 0x5,0x2a,0x50, + 0x4,0x39,0x2e, 0x6,0x55,0x46, 0x6,0x55,0x45, 0x6,0x5f,0x29, + 0x5,0x55,0x63, 0x7,0x30,0x2e, 0x7,0x25,0x52, 0x7,0x58,0x3f, + 0x5,0x22,0x7c, 0x5,0x24,0x64, 0x5,0x24,0x65, 0x4,0x24,0x60, + 0x6,0x28,0x66, 0x6,0x28,0x67, 0x6,0x28,0x65, 0x6,0x28,0x68, + 0x4,0x27,0x45, 0x6,0x2d,0x35, 0x4,0x27,0x44, 0xf,0x28,0x2f, + 0x5,0x27,0x38, 0x6,0x2d,0x36, 0x6,0x32,0x7d, 0x4,0x2a,0x4b, + 0x6,0x32,0x7c, 0x6,0x32,0x7b, 0x5,0x2a,0x52, 0x5,0x2a,0x56, + 0x4,0x2a,0x47, 0x4,0x2a,0x48, 0x5,0x2a,0x53, 0x4,0x2a,0x45, + 0x5,0x2a,0x54, 0x5,0x2a,0x51, 0x5,0x2a,0x55, 0x6,0x33,0x24, + 0xf,0x2c,0x50, 0x6,0x32,0x7e, 0xf,0x2c,0x51, 0x6,0x33,0x22, + 0x6,0x33,0x23, 0x6,0x33,0x21, 0x6,0x39,0x69, 0x5,0x2e,0x6f, + 0x5,0x2e,0x73, 0x6,0x39,0x6f, 0x5,0x2e,0x71, 0x6,0x39,0x70, + 0x6,0x39,0x6a, 0x5,0x2e,0x76, 0x5,0x2e,0x72, 0x5,0x2e,0x75, + 0x6,0x39,0x6d, 0x6,0x39,0x71, 0x6,0x39,0x66, 0x4,0x2e,0x3d, + 0x5,0x2e,0x74, 0x6,0x39,0x68, 0x4,0x2e,0x3e, 0x5,0x2e,0x70, + 0x6,0x39,0x6e, 0xf,0x31,0x2f, 0x6,0x39,0x67, 0x6,0x39,0x6c, + 0x6,0x42,0x31, 0x6,0x42,0x37, 0x5,0x33,0x68, 0x6,0x42,0x35, + 0x5,0x33,0x6b, 0x4,0x33,0x41, 0x5,0x33,0x6a, 0x5,0x33,0x66, + 0x6,0x42,0x33, 0x4,0x33,0x44, 0x5,0x33,0x69, 0xf,0x36,0x6d, + 0xf,0x36,0x6e, 0xf,0x36,0x6f, 0x6,0x42,0x36, 0x6,0x42,0x39, + 0x6,0x42,0x34, 0x6,0x42,0x38, 0xf,0x36,0x70, 0x6,0x42,0x30, + 0x5,0x33,0x67, 0x5,0x33,0x6c, 0x5,0x3a,0x36, 0x5,0x3a,0x3f, + 0x6,0x4b,0x61, 0x5,0x3a,0x35, 0x6,0x4b,0x65, 0x5,0x3a,0x39, + 0x5,0x3a,0x3a, 0x5,0x3a,0x3c, 0x5,0x3a,0x37, 0x6,0x4b,0x63, + 0x6,0x4b,0x5f, 0x5,0x3a,0x40, 0x6,0x4b,0x62, 0x6,0x4b,0x5b, + 0x6,0x4b,0x66, 0x5,0x3a,0x3e, 0x6,0x4b,0x5e, 0x4,0x39,0x39, + 0x6,0x4b,0x5d, 0x6,0x4b,0x60, 0x6,0x4b,0x64, 0xf,0x3d,0x49, + 0xf,0x3d,0x4a, 0x4,0x39,0x37, 0x6,0x4b,0x5c, 0x4,0x39,0x31, + 0x5,0x3a,0x38, 0x6,0x55,0x4c, 0x4,0x3e,0x72, 0x4,0x3e,0x70, + 0x4,0x3e,0x7b, 0x5,0x40,0x59, 0x4,0x3e,0x71, 0x4,0x3e,0x75, + 0x4,0x44,0x7d, 0x4,0x3e,0x79, 0x6,0x55,0x49, 0x5,0x40,0x5a, + 0x5,0x40,0x5c, 0x5,0x40,0x62, 0x4,0x3e,0x7c, 0x6,0x55,0x47, + 0x5,0x40,0x61, 0x6,0x55,0x4d, 0x5,0x40,0x65, 0x5,0x40,0x63, + 0x5,0x40,0x5b, 0x5,0x3a,0x3d, 0x5,0x40,0x5f, 0x5,0x40,0x5e, + 0x6,0x55,0x4b, 0x6,0x55,0x4a, 0x4,0x3e,0x7d, 0xf,0x43,0x6b, + 0xf,0x43,0x6c, 0x6,0x55,0x48, 0x6,0x55,0x4e, 0x5,0x40,0x58, + 0x5,0x40,0x66, 0x5,0x40,0x5d, 0x5,0x47,0x58, 0x5,0x47,0x50, + 0x4,0x45,0x25, 0x4,0x45,0x2b, 0x5,0x47,0x4b, 0x5,0x47,0x4f, + 0x4,0x45,0x26, 0x6,0x5f,0x2f, 0x6,0x5f,0x2a, 0x4,0x45,0x2e, + 0x4,0x45,0x2a, 0x6,0x5f,0x2b, 0x6,0x5f,0x34, 0x5,0x47,0x4d, + 0x5,0x47,0x4e, 0x5,0x47,0x53, 0x4,0x45,0x2c, 0x6,0x5f,0x37, + 0x6,0x5f,0x35, 0x5,0x47,0x5a, 0x6,0x5f,0x2e, 0x4,0x45,0x27, + 0x4,0x45,0x22, 0x5,0x47,0x51, 0x5,0x47,0x52, 0x6,0x5f,0x33, + 0x5,0x47,0x4c, 0x5,0x47,0x56, 0x6,0x5f,0x31, 0x6,0x5f,0x30, + 0xf,0x4a,0x2e, 0x6,0x5f,0x38, 0x6,0x5f,0x2c, 0x4,0x45,0x2d, + 0x6,0x5f,0x32, 0x6,0x5f,0x36, 0x5,0x47,0x55, 0x4,0x4b,0x3a, + 0x4,0x4b,0x36, 0x4,0x4b,0x2d, 0x4,0x4b,0x39, 0x5,0x4e,0x53, + 0x4,0x4b,0x34, 0x7,0x25,0x5d, 0x4,0x4b,0x32, 0x5,0x4e,0x55, + 0x5,0x4e,0x57, 0x5,0x4e,0x54, 0x4,0x4b,0x31, 0x7,0x25,0x55, + 0x4,0x4b,0x30, 0x5,0x4e,0x51, 0x5,0x4e,0x52, 0x7,0x25,0x53, + 0x5,0x47,0x57, 0x5,0x4e,0x58, 0x7,0x25,0x54, 0x7,0x25,0x5b, + 0x7,0x25,0x59, 0xf,0x50,0x50, 0xf,0x50,0x51, 0xf,0x50,0x52, + 0xf,0x50,0x53, 0xf,0x50,0x54, 0x7,0x25,0x56, 0x7,0x25,0x5a, + 0x7,0x25,0x5e, 0x5,0x4e,0x56, 0x5,0x4e,0x50, 0x4,0x51,0x4b, + 0x5,0x55,0x65, 0x7,0x30,0x2f, 0x7,0x30,0x30, 0x5,0x55,0x6c, + 0x5,0x55,0x6d, 0x4,0x51,0x4c, 0x4,0x51,0x47, 0x5,0x55,0x68, + 0x7,0x30,0x35, 0x5,0x55,0x66, 0x5,0x55,0x67, 0x5,0x55,0x6b, + 0x7,0x30,0x31, 0x7,0x30,0x37, 0x5,0x55,0x6e, 0xf,0x56,0x34, + 0xf,0x56,0x35, 0x7,0x30,0x34, 0x7,0x30,0x33, 0x5,0x55,0x6a, + 0x7,0x30,0x32, 0x7,0x30,0x38, 0x7,0x30,0x39, 0x5,0x55,0x64, + 0x7,0x25,0x57, 0x4,0x56,0x7c, 0x5,0x5c,0x39, 0x5,0x55,0x70, + 0x7,0x39,0x50, 0x4,0x51,0x51, 0x4,0x45,0x29, 0x4,0x56,0x7e, + 0x7,0x39,0x47, 0x5,0x5c,0x35, 0x7,0x39,0x48, 0x5,0x5c,0x3c, + 0x5,0x5c,0x3a, 0x5,0x5c,0x3d, 0x7,0x39,0x4f, 0x7,0x40,0x6a, + 0x5,0x55,0x6f, 0x5,0x5c,0x37, 0x4,0x56,0x7d, 0x5,0x5c,0x38, + 0x4,0x57,0x23, 0x7,0x39,0x49, 0x7,0x39,0x4d, 0x7,0x39,0x51, + 0x7,0x39,0x4b, 0x7,0x39,0x46, 0x7,0x39,0x4c, 0xf,0x5b,0x38, + 0x7,0x39,0x44, 0x7,0x39,0x45, 0x7,0x39,0x4e, 0x5,0x5c,0x3b, + 0x5,0x62,0x5c, 0x5,0x5c,0x3e, 0x7,0x39,0x4a, 0x4,0x5b,0x78, + 0x5,0x5c,0x40, 0x5,0x62,0x60, 0x7,0x40,0x68, 0x5,0x62,0x65, + 0x7,0x40,0x69, 0x5,0x62,0x61, 0x5,0x62,0x64, 0x4,0x5b,0x76, + 0x5,0x5c,0x3f, 0x5,0x62,0x5d, 0x5,0x62,0x62, 0x5,0x62,0x5e, + 0x5,0x62,0x5f, 0x4,0x5b,0x7a, 0x7,0x40,0x6d, 0x5,0x62,0x63, + 0x7,0x48,0x2b, 0x4,0x60,0x33, 0x7,0x48,0x27, 0x4,0x60,0x34, + 0x5,0x68,0x44, 0x4,0x60,0x35, 0x7,0x48,0x26, 0x5,0x68,0x43, + 0x5,0x68,0x42, 0x4,0x60,0x36, 0xf,0x63,0x27, 0x4,0x60,0x31, + 0x7,0x48,0x28, 0x7,0x48,0x29, 0x7,0x48,0x25, 0x7,0x48,0x2a, + 0x7,0x40,0x6c, 0x4,0x63,0x6a, 0x4,0x63,0x6b, 0x7,0x4e,0x49, + 0x7,0x4e,0x4d, 0x7,0x4e,0x4c, 0x5,0x6c,0x58, 0x5,0x6c,0x59, + 0x7,0x4e,0x4e, 0x7,0x4e,0x4b, 0x7,0x4e,0x4a, 0x5,0x70,0x51, + 0x5,0x70,0x50, 0x5,0x70,0x4e, 0x4,0x66,0x57, 0x7,0x53,0x7a, + 0x5,0x70,0x4f, 0x7,0x53,0x79, 0xf,0x67,0x78, 0x5,0x73,0x5f, + 0x5,0x73,0x5e, 0x5,0x73,0x5d, 0x7,0x5c,0x22, 0x7,0x5b,0x7e, + 0x4,0x6a,0x56, 0x7,0x5c,0x21, 0x5,0x76,0x29, 0x5,0x77,0x6b, + 0x7,0x5e,0x7d, 0x7,0x5e,0x7e, 0x7,0x61,0x42, 0x7,0x61,0x27, + 0x7,0x62,0x3f, 0x7,0x62,0x40, 0x7,0x62,0x41, 0x5,0x7a,0x6d, + 0x7,0x64,0x51, 0x7,0x65,0x39, 0x4,0x24,0x63, 0x6,0x33,0x25, + 0xf,0x2c,0x52, 0x6,0x39,0x73, 0x6,0x39,0x72, 0xf,0x31,0x30, + 0x6,0x42,0x3a, 0xf,0x36,0x71, 0x6,0x4b,0x69, 0x6,0x4b,0x67, + 0x5,0x3a,0x41, 0x6,0x4b,0x68, 0x7,0x25,0x5f, 0x4,0x51,0x53, + 0x4,0x51,0x52, 0x7,0x30,0x3a, 0x6,0x25,0x3c, 0x6,0x25,0x3d, + 0x5,0x24,0x66, 0x5,0x27,0x3a, 0x5,0x27,0x3b, 0x5,0x27,0x39, + 0x5,0x27,0x3c, 0x4,0x2a,0x4d, 0x5,0x2a,0x59, 0x5,0x2a,0x58, + 0x5,0x2a,0x57, 0x6,0x33,0x27, 0x6,0x33,0x28, 0x6,0x33,0x26, + 0xf,0x2c,0x53, 0xf,0x2c,0x54, 0x6,0x33,0x29, 0x5,0x2a,0x5a, + 0x6,0x39,0x74, 0x4,0x2e,0x42, 0x6,0x39,0x75, 0x6,0x42,0x3c, + 0xf,0x31,0x31, 0xf,0x31,0x32, 0xf,0x31,0x33, 0xf,0x31,0x35, + 0xf,0x31,0x36, 0xf,0x36,0x75, 0x4,0x33,0x46, 0x5,0x33,0x6e, + 0x6,0x42,0x3b, 0xf,0x36,0x72, 0xf,0x36,0x73, 0xf,0x36,0x76, + 0x6,0x4b,0x6b, 0x6,0x4b,0x6c, 0x6,0x4b,0x6a, 0xf,0x36,0x74, + 0x5,0x40,0x68, 0x5,0x40,0x67, 0x6,0x55,0x50, 0x4,0x3e,0x7e, + 0x6,0x55,0x4f, 0x5,0x40,0x69, 0xf,0x43,0x6d, 0x4,0x45,0x2f, + 0x6,0x5f,0x39, 0x6,0x5f,0x3a, 0xf,0x4a,0x30, 0xf,0x4a,0x31, + 0xf,0x4a,0x33, 0xf,0x4a,0x34, 0xf,0x4a,0x32, 0x4,0x4b,0x3c, + 0x7,0x25,0x60, 0x7,0x25,0x61, 0x5,0x55,0x72, 0x7,0x30,0x3c, + 0x5,0x55,0x71, 0x7,0x30,0x3b, 0x4,0x57,0x27, 0x4,0x57,0x28, + 0x5,0x5c,0x42, 0x5,0x5c,0x44, 0x7,0x40,0x6e, 0x5,0x5c,0x41, + 0x7,0x39,0x52, 0x5,0x62,0x66, 0x7,0x40,0x6f, 0x7,0x40,0x70, + 0x5,0x68,0x45, 0x5,0x68,0x46, 0x5,0x68,0x47, 0x5,0x68,0x48, + 0x7,0x48,0x2c, 0x7,0x4e,0x50, 0x7,0x4e,0x4f, 0x5,0x62,0x67, + 0x7,0x58,0x40, 0x7,0x58,0x41, 0xf,0x67,0x79, 0x7,0x5c,0x23, + 0x4,0x6b,0x73, 0x7,0x5f,0x21, 0x7,0x65,0x3a, 0x5,0x24,0x67, + 0x5,0x24,0x68, 0x6,0x2d,0x39, 0x6,0x2d,0x37, 0x6,0x2d,0x38, + 0x5,0x27,0x3d, 0x6,0x33,0x2b, 0x5,0x2a,0x5b, 0x4,0x2a,0x4f, + 0x6,0x30,0x36, 0x6,0x33,0x2a, 0x5,0x2e,0x77, 0x5,0x2e,0x78, + 0x6,0x39,0x76, 0x6,0x39,0x7a, 0x5,0x33,0x6f, 0x4,0x2e,0x44, + 0x6,0x39,0x77, 0x6,0x39,0x78, 0x6,0x39,0x79, 0x4,0x33,0x49, + 0x5,0x33,0x70, 0x6,0x42,0x3e, 0xf,0x36,0x79, 0x6,0x42,0x3d, + 0x4,0x39,0x3c, 0x6,0x4b,0x6d, 0x5,0x3a,0x42, 0x6,0x4b,0x6f, + 0x4,0x39,0x3b, 0xf,0x3d,0x4b, 0x6,0x4b,0x6e, 0xf,0x36,0x78, + 0x5,0x40,0x6a, 0x5,0x40,0x6d, 0x5,0x40,0x6b, 0x5,0x40,0x6c, + 0x5,0x40,0x6e, 0x6,0x55,0x53, 0xf,0x43,0x6e, 0x6,0x55,0x51, + 0x4,0x3f,0x21, 0x4,0x45,0x31, 0x4,0x45,0x33, 0x6,0x5f,0x3e, + 0xf,0x4a,0x35, 0x6,0x5f,0x3d, 0x5,0x47,0x5c, 0x6,0x5f,0x3f, + 0x6,0x5f,0x3b, 0x6,0x5f,0x3c, 0x7,0x25,0x63, 0x5,0x4e,0x5a, + 0x5,0x4e,0x5b, 0x5,0x4e,0x5c, 0x7,0x25,0x62, 0x5,0x55,0x76, + 0x5,0x55,0x78, 0x5,0x55,0x74, 0x4,0x51,0x58, 0x5,0x55,0x77, + 0x5,0x55,0x75, 0xf,0x56,0x36, 0x5,0x55,0x73, 0x7,0x30,0x3d, + 0x7,0x30,0x3e, 0x7,0x39,0x53, 0x7,0x30,0x3f, 0x4,0x57,0x29, + 0x5,0x62,0x68, 0x7,0x40,0x72, 0x7,0x40,0x73, 0x7,0x40,0x74, + 0x7,0x40,0x71, 0x5,0x68,0x4a, 0x5,0x68,0x49, 0x7,0x48,0x2d, + 0x4,0x63,0x6d, 0x5,0x6c,0x5b, 0x5,0x6c,0x5a, 0x7,0x4e,0x51, + 0x7,0x53,0x7c, 0x4,0x66,0x5c, 0x7,0x58,0x42, 0x5,0x77,0x6c, + 0x5,0x77,0x6d, 0x7,0x63,0x44, 0x7,0x65,0x58, 0x6,0x28,0x69, + 0xf,0x24,0x7d, 0x4,0x27,0x49, 0x5,0x27,0x3e, 0x4,0x27,0x47, + 0x6,0x2d,0x3b, 0x5,0x27,0x3f, 0x5,0x2a,0x5e, 0x5,0x2a,0x5c, + 0x5,0x2a,0x5d, 0x6,0x33,0x2d, 0x6,0x33,0x2c, 0xf,0x2c,0x55, + 0x5,0x2e,0x79, 0x6,0x3a,0x21, 0x6,0x3a,0x23, 0x4,0x2e,0x48, + 0x5,0x2e,0x7a, 0x6,0x39,0x7e, 0x6,0x39,0x7b, 0x4,0x2e,0x4a, + 0x6,0x3a,0x22, 0xf,0x31,0x37, 0xf,0x31,0x38, 0x6,0x3a,0x24, + 0x6,0x39,0x7c, 0x6,0x39,0x7d, 0x4,0x33,0x4c, 0x5,0x33,0x72, + 0x4,0x33,0x4a, 0x6,0x42,0x3f, 0xf,0x36,0x7a, 0xf,0x36,0x7b, + 0xf,0x36,0x7c, 0xf,0x36,0x7d, 0xf,0x37,0x21, 0xf,0x37,0x22, + 0x6,0x42,0x40, 0x6,0x42,0x41, 0x6,0x3a,0x25, 0x6,0x4b,0x74, + 0x6,0x4b,0x70, 0x5,0x3a,0x43, 0x4,0x39,0x3d, 0x6,0x4b,0x72, + 0x6,0x4b,0x73, 0xf,0x3d,0x4c, 0xf,0x3d,0x4d, 0x6,0x4b,0x71, + 0x6,0x55,0x54, 0x6,0x55,0x56, 0x5,0x40,0x70, 0x6,0x55,0x58, + 0x6,0x55,0x57, 0x6,0x55,0x55, 0xf,0x43,0x6f, 0xf,0x43,0x70, + 0x6,0x5f,0x41, 0x6,0x5f,0x40, 0x6,0x5f,0x4b, 0xf,0x4a,0x36, + 0x5,0x4e,0x5d, 0x7,0x25,0x64, 0x7,0x25,0x65, 0xf,0x50,0x55, + 0xf,0x50,0x56, 0xf,0x50,0x57, 0xf,0x50,0x58, 0xf,0x50,0x59, + 0xf,0x50,0x5a, 0x4,0x51,0x59, 0x7,0x30,0x44, 0x4,0x51,0x5b, + 0x7,0x30,0x40, 0x7,0x30,0x45, 0x5,0x55,0x7a, 0x5,0x55,0x79, + 0xf,0x56,0x37, 0xf,0x56,0x38, 0xf,0x56,0x39, 0xf,0x56,0x3a, + 0xf,0x56,0x3b, 0x7,0x30,0x43, 0x7,0x30,0x41, 0x4,0x57,0x2b, + 0x4,0x5c,0x23, 0x4,0x57,0x2a, 0x7,0x39,0x54, 0x5,0x5c,0x47, + 0x7,0x40,0x75, 0x5,0x5c,0x46, 0xf,0x5b,0x3b, 0xf,0x5b,0x3c, + 0x7,0x39,0x55, 0x7,0x39,0x56, 0x7,0x36,0x79, 0x5,0x5c,0x45, + 0x7,0x30,0x42, 0x7,0x39,0x57, 0x4,0x5c,0x22, 0x4,0x5c,0x21, + 0x7,0x40,0x76, 0x7,0x40,0x78, 0x7,0x40,0x77, 0xf,0x5f,0x62, + 0x7,0x40,0x79, 0x7,0x48,0x2e, 0x5,0x68,0x4b, 0x7,0x48,0x2f, + 0xf,0x63,0x28, 0xf,0x63,0x29, 0x5,0x6c,0x5d, 0x7,0x4e,0x53, + 0x5,0x6c,0x5c, 0x7,0x4e,0x55, 0xf,0x65,0x56, 0x7,0x4e,0x52, + 0x7,0x4e,0x54, 0xf,0x67,0x7b, 0x7,0x58,0x44, 0x5,0x73,0x60, + 0x7,0x58,0x43, 0x7,0x58,0x45, 0xf,0x67,0x7a, 0x7,0x5f,0x22, + 0x5,0x76,0x2a, 0x7,0x5f,0x23, 0x7,0x62,0x42, 0x5,0x22,0x7d, + 0xf,0x22,0x67, 0x6,0x28,0x6a, 0x4,0x24,0x64, 0x5,0x24,0x6a, + 0x4,0x24,0x66, 0x5,0x24,0x6b, 0x5,0x24,0x69, 0xf,0x24,0x7e, + 0x4,0x27,0x50, 0x6,0x2d,0x3c, 0x5,0x27,0x41, 0x4,0x27,0x4b, + 0x6,0x2d,0x40, 0x6,0x2d,0x42, 0x6,0x2d,0x3e, 0x5,0x27,0x42, + 0x5,0x27,0x43, 0x6,0x2d,0x41, 0x6,0x2d,0x3f, 0x5,0x27,0x40, + 0x6,0x2d,0x43, 0x6,0x2d,0x44, 0x6,0x33,0x39, 0x6,0x33,0x35, + 0x6,0x33,0x2e, 0x6,0x33,0x32, 0x4,0x2a,0x5e, 0x6,0x33,0x36, + 0x4,0x2a,0x5c, 0x6,0x33,0x3c, 0x5,0x2a,0x65, 0x6,0x33,0x33, + 0x5,0x2a,0x69, 0x4,0x2a,0x5b, 0x6,0x33,0x2f, 0x6,0x33,0x3b, + 0x5,0x2a,0x60, 0x5,0x2a,0x67, 0x5,0x2a,0x6b, 0x5,0x2a,0x61, + 0x5,0x2a,0x6a, 0x5,0x2a,0x68, 0x5,0x2a,0x63, 0x5,0x2a,0x6c, + 0x6,0x33,0x30, 0x5,0x2a,0x5f, 0x5,0x2a,0x66, 0x5,0x2a,0x62, + 0x5,0x2a,0x64, 0xf,0x2c,0x56, 0xf,0x2c,0x58, 0x6,0x33,0x37, + 0x6,0x33,0x3a, 0x6,0x33,0x34, 0x4,0x2e,0x50, 0x5,0x2f,0x24, + 0x3,0x2e,0x5a, 0x4,0x2e,0x4c, 0x5,0x2e,0x7b, 0x6,0x3a,0x26, + 0x4,0x2e,0x4e, 0x5,0x2f,0x22, 0x5,0x2e,0x7c, 0x6,0x3a,0x28, + 0x4,0x2e,0x4b, 0x6,0x3a,0x29, 0x5,0x2f,0x23, 0x6,0x3a,0x2a, + 0x4,0x2e,0x53, 0x6,0x3a,0x2c, 0x5,0x2e,0x7e, 0x5,0x2f,0x25, + 0x6,0x3a,0x2b, 0xf,0x31,0x39, 0xf,0x31,0x3a, 0xf,0x31,0x3b, + 0xf,0x31,0x3c, 0xf,0x31,0x3d, 0x6,0x3a,0x27, 0x5,0x2f,0x21, + 0x5,0x2e,0x7d, 0x4,0x2e,0x54, 0x4,0x33,0x55, 0x6,0x42,0x53, + 0x6,0x42,0x46, 0x6,0x42,0x4d, 0x5,0x33,0x74, 0x5,0x33,0x73, + 0x5,0x33,0x7d, 0x4,0x33,0x54, 0x6,0x42,0x47, 0x6,0x42,0x44, + 0x6,0x42,0x42, 0x5,0x33,0x7a, 0x5,0x33,0x7b, 0x5,0x33,0x75, + 0x6,0x42,0x4a, 0x5,0x33,0x78, 0x6,0x42,0x54, 0x5,0x33,0x79, + 0x6,0x42,0x43, 0x6,0x42,0x4f, 0x6,0x42,0x4b, 0x6,0x42,0x50, + 0xf,0x37,0x25, 0x6,0x42,0x52, 0x6,0x42,0x4c, 0x6,0x42,0x49, + 0x6,0x42,0x51, 0xf,0x37,0x26, 0x5,0x33,0x7e, 0x6,0x42,0x45, + 0x6,0x42,0x4e, 0x5,0x33,0x77, 0x5,0x33,0x7c, 0x5,0x3a,0x49, + 0x5,0x3a,0x4c, 0x6,0x4b,0x79, 0x6,0x4c,0x23, 0x4,0x33,0x53, + 0x6,0x4b,0x78, 0x5,0x3a,0x4b, 0x6,0x4b,0x7d, 0x6,0x4c,0x21, + 0x5,0x3a,0x46, 0x6,0x4c,0x26, 0x6,0x4b,0x77, 0x4,0x39,0x4f, + 0x5,0x3a,0x4a, 0x5,0x3a,0x48, 0x5,0x3a,0x44, 0x4,0x39,0x4e, + 0x5,0x40,0x71, 0x6,0x4c,0x25, 0x5,0x40,0x7e, 0x4,0x39,0x40, + 0x6,0x4b,0x7e, 0x5,0x3a,0x4d, 0x6,0x4b,0x7b, 0x5,0x3a,0x4e, + 0x6,0x4c,0x28, 0x5,0x3a,0x45, 0x5,0x3a,0x47, 0xf,0x3d,0x4f, + 0xf,0x3d,0x50, 0xf,0x3d,0x51, 0x6,0x4b,0x7c, 0x6,0x4c,0x27, + 0x6,0x4b,0x76, 0x6,0x4c,0x24, 0x6,0x4c,0x22, 0x4,0x39,0x44, + 0x4,0x39,0x50, 0x5,0x3a,0x4f, 0x4,0x39,0x3e, 0x6,0x55,0x5b, + 0x6,0x55,0x5e, 0x6,0x55,0x5a, 0x4,0x3f,0x2a, 0x5,0x40,0x78, + 0x6,0x55,0x5c, 0x5,0x40,0x77, 0x6,0x55,0x5f, 0x5,0x40,0x75, + 0x6,0x55,0x59, 0x4,0x3f,0x23, 0x4,0x3f,0x28, 0x4,0x3f,0x31, + 0x4,0x3f,0x2e, 0x5,0x40,0x7a, 0x6,0x55,0x62, 0x5,0x40,0x76, + 0x4,0x3f,0x2f, 0x4,0x3f,0x24, 0x6,0x55,0x64, 0x5,0x40,0x79, + 0x5,0x40,0x72, 0x5,0x40,0x7c, 0x6,0x55,0x66, 0x6,0x55,0x5d, + 0xf,0x43,0x71, 0xf,0x43,0x72, 0xf,0x43,0x73, 0x6,0x4b,0x75, + 0x6,0x55,0x63, 0x6,0x53,0x35, 0x5,0x40,0x73, 0x5,0x40,0x7d, + 0x5,0x40,0x74, 0x6,0x55,0x65, 0x5,0x47,0x60, 0x4,0x45,0x45, + 0x6,0x5f,0x44, 0x4,0x45,0x3e, 0x5,0x47,0x63, 0x6,0x5f,0x48, + 0x5,0x47,0x65, 0x5,0x47,0x66, 0x6,0x5f,0x49, 0x4,0x4b,0x4f, + 0x6,0x5f,0x4e, 0x6,0x5f,0x46, 0x6,0x5f,0x4f, 0x7,0x25,0x6c, + 0x6,0x5f,0x47, 0x5,0x47,0x67, 0x5,0x47,0x64, 0x6,0x5f,0x43, + 0x6,0x5f,0x4a, 0x6,0x5f,0x45, 0x5,0x47,0x62, 0x6,0x5f,0x42, + 0x5,0x47,0x5f, 0x5,0x47,0x5e, 0x5,0x47,0x5d, 0x7,0x25,0x66, + 0xf,0x4a,0x37, 0xf,0x4a,0x38, 0xf,0x4a,0x39, 0xf,0x4a,0x3a, + 0xf,0x4a,0x3b, 0xf,0x4a,0x3c, 0xf,0x4a,0x3d, 0x4,0x45,0x3a, + 0x6,0x5f,0x4d, 0x6,0x5f,0x4c, 0x5,0x47,0x69, 0x4,0x45,0x3b, + 0x4,0x4b,0x50, 0x4,0x4b,0x4c, 0x4,0x4b,0x3e, 0x5,0x4e,0x62, + 0x5,0x4e,0x67, 0x4,0x4b,0x4e, 0x7,0x25,0x6b, 0x5,0x4e,0x6c, + 0x5,0x4e,0x65, 0x4,0x4b,0x41, 0x7,0x25,0x70, 0x4,0x4b,0x40, + 0x4,0x51,0x65, 0x7,0x30,0x4d, 0x5,0x4e,0x64, 0x5,0x56,0x21, + 0x5,0x4e,0x66, 0x7,0x25,0x6d, 0x5,0x4e,0x6a, 0x7,0x25,0x72, + 0x4,0x4b,0x49, 0x4,0x4b,0x4b, 0x4,0x4b,0x46, 0x5,0x4e,0x5f, + 0x5,0x4e,0x6b, 0x7,0x25,0x67, 0x7,0x25,0x68, 0x7,0x25,0x6a, + 0x4,0x4b,0x4a, 0x5,0x4e,0x63, 0x7,0x25,0x6e, 0x5,0x4e,0x5e, + 0x5,0x4e,0x61, 0x5,0x55,0x7b, 0x5,0x4e,0x69, 0x5,0x4e,0x68, + 0x7,0x25,0x69, 0xf,0x50,0x5b, 0xf,0x50,0x5c, 0xf,0x50,0x5d, + 0x7,0x25,0x6f, 0x4,0x4b,0x48, 0x5,0x56,0x2a, 0x5,0x56,0x2b, + 0x4,0x51,0x5e, 0x5,0x56,0x25, 0x5,0x56,0x23, 0x5,0x56,0x27, + 0x5,0x55,0x7d, 0x4,0x51,0x63, 0x5,0x56,0x29, 0x5,0x55,0x7e, + 0x5,0x56,0x26, 0x5,0x56,0x24, 0x4,0x51,0x62, 0x7,0x30,0x46, + 0x7,0x30,0x4e, 0x7,0x30,0x4f, 0x7,0x30,0x4b, 0x7,0x30,0x47, + 0x5,0x4e,0x6d, 0x4,0x51,0x67, 0x5,0x55,0x7c, 0x7,0x30,0x49, + 0xf,0x56,0x3d, 0x7,0x30,0x51, 0x7,0x30,0x4c, 0x5,0x56,0x2c, + 0x4,0x51,0x66, 0x5,0x47,0x68, 0x5,0x56,0x28, 0x4,0x5c,0x2b, + 0x5,0x5c,0x48, 0x5,0x5c,0x4b, 0x4,0x57,0x35, 0x4,0x57,0x36, + 0x7,0x30,0x52, 0x7,0x39,0x5e, 0x7,0x39,0x59, 0x5,0x5c,0x4a, + 0x7,0x39,0x5a, 0x5,0x5c,0x4c, 0x7,0x39,0x64, 0x5,0x5c,0x49, + 0x7,0x41,0x22, 0x7,0x39,0x5f, 0x7,0x39,0x60, 0x7,0x39,0x5d, + 0x4,0x57,0x37, 0x7,0x39,0x63, 0x5,0x5c,0x4f, 0x7,0x30,0x48, + 0x5,0x5c,0x4e, 0x7,0x39,0x61, 0x7,0x39,0x5c, 0x7,0x39,0x5b, + 0xf,0x5b,0x3e, 0xf,0x5b,0x3f, 0xf,0x5b,0x40, 0x7,0x39,0x62, + 0x7,0x39,0x58, 0x4,0x5c,0x28, 0x7,0x41,0x23, 0x7,0x40,0x7e, + 0x5,0x62,0x6e, 0x4,0x5c,0x2c, 0x5,0x62,0x6b, 0x7,0x40,0x7b, + 0x7,0x40,0x7c, 0x5,0x62,0x70, 0x4,0x5c,0x24, 0x5,0x62,0x6c, + 0x5,0x62,0x6f, 0x5,0x62,0x71, 0x5,0x62,0x6a, 0xf,0x5f,0x63, + 0xf,0x5f,0x64, 0x7,0x41,0x24, 0x7,0x41,0x25, 0x7,0x40,0x7d, + 0x5,0x62,0x6d, 0x7,0x40,0x7a, 0x7,0x41,0x21, 0x5,0x68,0x4f, + 0x5,0x68,0x4c, 0x5,0x68,0x51, 0x4,0x60,0x3e, 0x5,0x68,0x50, + 0x4,0x60,0x3b, 0x5,0x68,0x54, 0x5,0x68,0x4e, 0x7,0x48,0x32, + 0x4,0x60,0x3a, 0x7,0x48,0x34, 0x4,0x60,0x3c, 0x4,0x60,0x3d, + 0x7,0x48,0x30, 0x5,0x68,0x4d, 0x7,0x48,0x31, 0x5,0x68,0x53, + 0x5,0x68,0x52, 0xf,0x63,0x2a, 0x7,0x4b,0x5d, 0x7,0x48,0x35, + 0x7,0x48,0x33, 0x5,0x6c,0x60, 0x5,0x6c,0x62, 0x5,0x6c,0x5e, + 0x7,0x4e,0x58, 0x5,0x6c,0x61, 0x5,0x6c,0x63, 0x7,0x4e,0x57, + 0xf,0x65,0x57, 0x4,0x63,0x72, 0x5,0x6c,0x5f, 0x4,0x63,0x73, + 0x7,0x4e,0x56, 0x7,0x54,0x22, 0x5,0x70,0x52, 0x5,0x70,0x54, + 0x5,0x70,0x53, 0x5,0x70,0x55, 0x7,0x53,0x7e, 0x7,0x54,0x23, + 0x7,0x53,0x7d, 0x4,0x68,0x79, 0x5,0x73,0x63, 0x7,0x58,0x46, + 0x5,0x73,0x61, 0x5,0x73,0x62, 0x7,0x58,0x47, 0x5,0x73,0x65, + 0x4,0x6a,0x59, 0x7,0x54,0x21, 0x5,0x73,0x64, 0x7,0x59,0x33, + 0x5,0x73,0x66, 0x5,0x76,0x2b, 0x7,0x5c,0x26, 0x4,0x6a,0x58, + 0x7,0x5c,0x25, 0x7,0x5f,0x24, 0x4,0x6c,0x74, 0x7,0x62,0x43, + 0x7,0x62,0x45, 0x7,0x62,0x44, 0xf,0x6c,0x66, 0x5,0x7b,0x43, + 0x5,0x27,0x44, 0x4,0x2a,0x60, 0x4,0x2a,0x61, 0x4,0x2e,0x56, + 0x5,0x2f,0x28, 0x5,0x2f,0x27, 0x6,0x3a,0x2f, 0x6,0x3a,0x30, + 0x4,0x33,0x58, 0x5,0x34,0x22, 0xf,0x37,0x27, 0x5,0x3a,0x52, + 0x4,0x39,0x51, 0x5,0x3a,0x53, 0x5,0x3a,0x51, 0x5,0x3a,0x55, + 0x5,0x3a,0x50, 0x6,0x4c,0x29, 0x5,0x3a,0x54, 0x5,0x41,0x23, + 0x5,0x41,0x22, 0x5,0x41,0x21, 0x6,0x5f,0x51, 0x6,0x5f,0x52, + 0x4,0x45,0x47, 0x4,0x45,0x48, 0x5,0x47,0x6c, 0x5,0x47,0x6a, + 0x5,0x47,0x6b, 0x4,0x45,0x49, 0x6,0x5f,0x50, 0x4,0x45,0x4b, + 0xf,0x4d,0x3f, 0x5,0x4e,0x6e, 0x4,0x4b,0x52, 0x7,0x25,0x75, + 0x5,0x4e,0x6f, 0x4,0x4b,0x51, 0x7,0x25,0x74, 0x4,0x4b,0x53, + 0x4,0x51,0x69, 0x4,0x51,0x68, 0x4,0x51,0x6a, 0x5,0x56,0x2d, + 0x5,0x62,0x75, 0x7,0x39,0x65, 0x5,0x5a,0x75, 0x5,0x5c,0x50, + 0x5,0x62,0x74, 0x5,0x62,0x73, 0x5,0x62,0x72, 0x5,0x68,0x57, + 0x5,0x68,0x56, 0x5,0x68,0x55, 0x5,0x68,0x58, 0x7,0x48,0x36, + 0x7,0x48,0x37, 0x4,0x6a,0x5a, 0x7,0x66,0x3f, 0x7,0x66,0x49, + 0x6,0x26,0x3f, 0x6,0x28,0x6b, 0x6,0x28,0x6c, 0x6,0x33,0x41, + 0x6,0x33,0x3f, 0x6,0x33,0x40, 0x5,0x2a,0x6e, 0x5,0x2f,0x2a, + 0x5,0x2f,0x2b, 0x6,0x3a,0x33, 0xf,0x31,0x3f, 0xf,0x31,0x40, + 0x6,0x3a,0x31, 0x6,0x3a,0x32, 0x5,0x2f,0x29, 0x5,0x34,0x23, + 0x5,0x34,0x24, 0x4,0x33,0x5c, 0x6,0x42,0x59, 0x6,0x42,0x57, + 0x5,0x34,0x25, 0x6,0x42,0x55, 0x6,0x42,0x5b, 0x6,0x42,0x56, + 0x6,0x42,0x5a, 0x6,0x42,0x58, 0x4,0x39,0x52, 0x6,0x4c,0x2c, + 0xf,0x3d,0x52, 0x6,0x4c,0x2a, 0xf,0x3d,0x53, 0x5,0x41,0x24, + 0x4,0x3f,0x32, 0x6,0x55,0x69, 0x4,0x3f,0x35, 0x4,0x3f,0x34, + 0x6,0x55,0x67, 0x5,0x3a,0x56, 0x4,0x3f,0x36, 0xf,0x43,0x75, + 0x6,0x55,0x68, 0x5,0x47,0x6d, 0x5,0x47,0x6e, 0x6,0x5f,0x53, + 0x5,0x47,0x6f, 0x5,0x47,0x70, 0xf,0x4a,0x3e, 0x7,0x25,0x78, + 0x4,0x4b,0x54, 0x7,0x25,0x76, 0x7,0x25,0x77, 0xf,0x50,0x61, + 0x7,0x25,0x79, 0x7,0x30,0x54, 0x4,0x51,0x6b, 0xf,0x56,0x3f, + 0x7,0x30,0x53, 0x5,0x5c,0x51, 0x5,0x5c,0x52, 0x7,0x39,0x66, + 0x7,0x39,0x67, 0x5,0x73,0x67, 0x5,0x76,0x2c, 0x5,0x22,0x7e, + 0x6,0x25,0x3e, 0x4,0x24,0x67, 0x6,0x28,0x6d, 0x5,0x24,0x6d, + 0x5,0x24,0x6c, 0xf,0x25,0x21, 0xf,0x25,0x22, 0x5,0x27,0x45, + 0x4,0x27,0x54, 0xf,0x28,0x30, 0xf,0x28,0x31, 0xf,0x28,0x32, + 0xf,0x28,0x33, 0x6,0x2d,0x47, 0xf,0x28,0x35, 0x4,0x2a,0x65, + 0x4,0x2a,0x63, 0x6,0x33,0x45, 0x5,0x2a,0x70, 0xf,0x2c,0x59, + 0xf,0x2c,0x5a, 0xf,0x2c,0x5b, 0xf,0x2c,0x5d, 0xf,0x2c,0x5e, + 0xf,0x2c,0x5f, 0xf,0x2c,0x61, 0xf,0x2c,0x63, 0x6,0x33,0x43, + 0x6,0x33,0x44, 0xf,0x2c,0x64, 0xf,0x2c,0x60, 0x6,0x33,0x42, + 0x5,0x2a,0x6f, 0x5,0x2a,0x71, 0x4,0x2e,0x60, 0x5,0x2f,0x33, + 0x6,0x3a,0x34, 0x6,0x33,0x46, 0x6,0x3a,0x35, 0x5,0x2f,0x2f, + 0x6,0x3a,0x39, 0x5,0x2f,0x2c, 0x5,0x2f,0x31, 0x5,0x2f,0x30, + 0x4,0x2e,0x5b, 0x4,0x2e,0x5d, 0x5,0x2f,0x36, 0x5,0x2f,0x32, + 0x5,0x2f,0x35, 0xf,0x31,0x3e, 0x4,0x2e,0x59, 0x5,0x2f,0x37, + 0x6,0x3a,0x38, 0xf,0x31,0x42, 0xf,0x31,0x43, 0xf,0x31,0x45, + 0xf,0x31,0x46, 0x4,0x2e,0x5a, 0x5,0x2f,0x2d, 0x6,0x3a,0x37, + 0xf,0x31,0x48, 0xf,0x31,0x41, 0x5,0x34,0x26, 0x5,0x2f,0x2e, + 0x6,0x3a,0x36, 0x5,0x34,0x2c, 0x5,0x34,0x28, 0x6,0x42,0x61, + 0x6,0x42,0x5f, 0x5,0x34,0x31, 0x5,0x34,0x30, 0x5,0x34,0x2a, + 0x6,0x42,0x60, 0x5,0x34,0x34, 0x5,0x34,0x32, 0x5,0x2f,0x38, + 0x5,0x34,0x2e, 0x5,0x34,0x27, 0x5,0x34,0x29, 0x5,0x34,0x2d, + 0xf,0x37,0x28, 0xf,0x37,0x29, 0xf,0x37,0x2a, 0xf,0x37,0x2b, + 0xf,0x37,0x2e, 0xf,0x37,0x2f, 0xf,0x37,0x31, 0xf,0x37,0x32, + 0xf,0x37,0x33, 0x6,0x42,0x5e, 0x6,0x42,0x5c, 0x6,0x4c,0x2e, + 0xf,0x37,0x30, 0x5,0x34,0x2b, 0xf,0x37,0x2c, 0x6,0x42,0x62, + 0x5,0x34,0x2f, 0x5,0x34,0x33, 0x6,0x42,0x5d, 0x5,0x3a,0x58, + 0x5,0x3a,0x5e, 0x5,0x3a,0x57, 0x5,0x3a,0x5b, 0x4,0x39,0x56, + 0x6,0x4c,0x35, 0x4,0x39,0x57, 0x4,0x39,0x55, 0x5,0x3a,0x5c, + 0x5,0x3a,0x5d, 0x6,0x4c,0x31, 0x5,0x3a,0x5a, 0x5,0x3a,0x5f, + 0xf,0x3d,0x54, 0xf,0x3d,0x55, 0xf,0x3d,0x56, 0xf,0x3d,0x57, + 0x6,0x4c,0x34, 0x6,0x4c,0x30, 0x6,0x4c,0x32, 0x5,0x3a,0x61, + 0x5,0x3a,0x60, 0x5,0x41,0x28, 0x6,0x55,0x71, 0x4,0x3f,0x37, + 0x5,0x41,0x29, 0x6,0x55,0x6a, 0x6,0x55,0x6c, 0x5,0x41,0x25, + 0x6,0x55,0x6e, 0x4,0x3f,0x41, 0x4,0x3f,0x43, 0x6,0x55,0x6f, + 0x6,0x55,0x72, 0x5,0x41,0x26, 0x5,0x41,0x27, 0x6,0x55,0x6d, + 0xf,0x43,0x77, 0xf,0x43,0x78, 0xf,0x43,0x79, 0xf,0x43,0x7a, + 0xf,0x43,0x7b, 0xf,0x43,0x7c, 0xf,0x43,0x7d, 0xf,0x43,0x7e, + 0xf,0x44,0x21, 0xf,0x44,0x22, 0xf,0x44,0x23, 0xf,0x44,0x24, + 0xf,0x44,0x26, 0x6,0x55,0x70, 0x6,0x55,0x73, 0x6,0x5f,0x5b, + 0x5,0x47,0x78, 0x6,0x5f,0x54, 0x7,0x25,0x7e, 0x5,0x47,0x7a, + 0x6,0x5f,0x56, 0x4,0x45,0x52, 0x5,0x47,0x73, 0x5,0x47,0x72, + 0x6,0x5f,0x57, 0x5,0x47,0x7b, 0x6,0x5f,0x59, 0x6,0x5f,0x5a, + 0x5,0x47,0x75, 0x6,0x5f,0x55, 0x5,0x47,0x71, 0x5,0x47,0x7d, + 0x6,0x5f,0x58, 0xf,0x4a,0x41, 0xf,0x4a,0x43, 0xf,0x4a,0x44, + 0xf,0x4a,0x45, 0xf,0x4a,0x46, 0xf,0x4a,0x47, 0xf,0x4a,0x48, + 0xf,0x4a,0x49, 0xf,0x4a,0x4b, 0xf,0x4a,0x4c, 0xf,0x4a,0x4d, + 0xf,0x4a,0x4f, 0xf,0x4a,0x50, 0xf,0x4a,0x51, 0xf,0x4a,0x52, + 0x4,0x45,0x54, 0xf,0x4a,0x40, 0x5,0x47,0x77, 0x5,0x47,0x7c, + 0x5,0x47,0x79, 0x5,0x47,0x74, 0xf,0x50,0x64, 0x4,0x4b,0x5a, + 0x5,0x4e,0x72, 0x5,0x4e,0x73, 0x7,0x26,0x21, 0x5,0x4e,0x70, + 0x4,0x45,0x50, 0x7,0x26,0x25, 0x5,0x4e,0x75, 0x7,0x25,0x7d, + 0xf,0x50,0x62, 0xf,0x50,0x63, 0xf,0x50,0x65, 0xf,0x50,0x66, + 0xf,0x50,0x68, 0x7,0x26,0x22, 0x7,0x25,0x7a, 0x7,0x26,0x23, + 0x5,0x4e,0x71, 0x5,0x4e,0x74, 0x7,0x25,0x7c, 0xf,0x4a,0x4a, + 0x7,0x30,0x58, 0x5,0x56,0x31, 0x5,0x56,0x2e, 0x5,0x56,0x32, + 0x7,0x30,0x55, 0x4,0x51,0x71, 0x4,0x51,0x73, 0x5,0x56,0x34, + 0x4,0x51,0x72, 0x7,0x30,0x56, 0x7,0x30,0x5a, 0x4,0x51,0x6f, + 0x7,0x30,0x57, 0xf,0x56,0x41, 0xf,0x56,0x42, 0xf,0x56,0x43, + 0x5,0x56,0x30, 0xf,0x56,0x44, 0x5,0x56,0x2f, 0xf,0x56,0x45, + 0xf,0x56,0x46, 0xf,0x56,0x47, 0xf,0x56,0x49, 0xf,0x56,0x4b, + 0xf,0x56,0x4c, 0xf,0x56,0x4d, 0x5,0x5c,0x56, 0x7,0x39,0x68, + 0x5,0x5c,0x54, 0x7,0x39,0x6f, 0x7,0x39,0x6a, 0x5,0x5c,0x53, + 0x4,0x57,0x3a, 0x7,0x39,0x69, 0x5,0x5c,0x55, 0x4,0x57,0x3d, + 0x7,0x39,0x6c, 0x4,0x57,0x3c, 0x5,0x56,0x35, 0x5,0x5c,0x58, + 0x5,0x5c,0x57, 0x5,0x5c,0x59, 0xf,0x5b,0x41, 0xf,0x5b,0x42, + 0xf,0x5b,0x43, 0xf,0x5b,0x44, 0xf,0x5b,0x45, 0xf,0x5b,0x46, + 0xf,0x5b,0x47, 0xf,0x5b,0x48, 0xf,0x5b,0x49, 0x7,0x39,0x6b, + 0x7,0x39,0x6e, 0xf,0x56,0x4a, 0x7,0x41,0x29, 0x5,0x62,0x76, + 0x5,0x62,0x78, 0x7,0x41,0x26, 0x7,0x41,0x28, 0x5,0x62,0x77, + 0x4,0x5c,0x30, 0x5,0x62,0x7a, 0x7,0x41,0x27, 0x5,0x62,0x79, + 0x7,0x41,0x2a, 0xf,0x5f,0x65, 0xf,0x5f,0x66, 0xf,0x5f,0x67, + 0xf,0x5f,0x68, 0xf,0x5f,0x69, 0x4,0x60,0x40, 0x5,0x68,0x5a, + 0x5,0x68,0x59, 0xf,0x63,0x2b, 0xf,0x63,0x2c, 0xf,0x63,0x2d, + 0xf,0x63,0x2e, 0x7,0x48,0x3a, 0x7,0x48,0x38, 0x7,0x48,0x39, + 0xf,0x63,0x2f, 0x5,0x6c,0x65, 0x5,0x6c,0x66, 0x7,0x4e,0x59, + 0x7,0x4e,0x5a, 0x5,0x6c,0x64, 0x5,0x6c,0x67, 0x4,0x60,0x41, + 0x7,0x4e,0x5b, 0xf,0x65,0x5a, 0xf,0x65,0x5b, 0xf,0x65,0x5c, + 0xf,0x65,0x5d, 0x7,0x4e,0x5d, 0x5,0x70,0x56, 0x5,0x70,0x57, + 0xf,0x67,0x7d, 0x7,0x54,0x24, 0x4,0x66,0x62, 0xf,0x67,0x7c, + 0x5,0x73,0x68, 0x7,0x58,0x48, 0x5,0x73,0x69, 0xf,0x69,0x5b, + 0xf,0x69,0x5c, 0x7,0x58,0x49, 0x5,0x73,0x6a, 0x5,0x76,0x2e, + 0x4,0x6a,0x5b, 0x5,0x76,0x2d, 0x5,0x76,0x2f, 0xf,0x6a,0x65, + 0x7,0x5c,0x28, 0x7,0x5c,0x27, 0x7,0x5f,0x26, 0x7,0x5f,0x25, + 0x7,0x5f,0x27, 0x7,0x62,0x46, 0x5,0x7a,0x2d, 0x5,0x7a,0x6e, + 0x4,0x6d,0x75, 0x7,0x64,0x53, 0x7,0x65,0x3b, 0x5,0x7c,0x43, + 0x6,0x22,0x27, 0x6,0x25,0x40, 0x6,0x28,0x6e, 0xf,0x22,0x68, + 0x6,0x2d,0x48, 0xf,0x25,0x24, 0x6,0x33,0x47, 0x6,0x33,0x49, + 0xf,0x28,0x36, 0xf,0x28,0x38, 0xf,0x28,0x39, 0xf,0x28,0x3a, + 0xf,0x28,0x3b, 0xf,0x28,0x3d, 0xf,0x28,0x37, 0x6,0x31,0x5a, + 0x5,0x2f,0x39, 0x6,0x3a,0x3a, 0x4,0x2e,0x63, 0x5,0x2f,0x3a, + 0x6,0x3a,0x3b, 0x6,0x33,0x4b, 0xf,0x2c,0x65, 0xf,0x2c,0x66, + 0xf,0x2c,0x67, 0xf,0x2c,0x68, 0xf,0x2c,0x69, 0xf,0x31,0x49, + 0xf,0x31,0x4b, 0xf,0x31,0x4e, 0x6,0x3a,0x3e, 0x6,0x3a,0x3f, + 0x6,0x3a,0x3d, 0x6,0x3a,0x40, 0x6,0x3a,0x3c, 0xf,0x2c,0x6a, + 0x4,0x2a,0x68, 0x5,0x34,0x36, 0x6,0x3a,0x41, 0xf,0x31,0x4a, + 0xf,0x31,0x4c, 0xf,0x31,0x4d, 0xf,0x31,0x4f, 0xf,0x31,0x50, + 0xf,0x31,0x51, 0xf,0x31,0x52, 0xf,0x31,0x53, 0xf,0x31,0x54, + 0xf,0x37,0x37, 0x6,0x42,0x63, 0x5,0x34,0x35, 0x6,0x4c,0x38, + 0x5,0x3a,0x62, 0x6,0x4c,0x39, 0x6,0x4c,0x3a, 0x6,0x4c,0x3c, + 0x5,0x3a,0x63, 0x6,0x4c,0x3d, 0x6,0x4c,0x3b, 0x6,0x4c,0x36, + 0x6,0x4c,0x37, 0xf,0x37,0x34, 0xf,0x37,0x36, 0xf,0x37,0x38, + 0xf,0x3d,0x5b, 0xf,0x37,0x35, 0x6,0x55,0x75, 0x5,0x41,0x2b, + 0x5,0x41,0x2a, 0x5,0x41,0x2c, 0x6,0x4c,0x3f, 0x4,0x3f,0x48, + 0xf,0x3d,0x58, 0xf,0x3d,0x59, 0xf,0x3d,0x5a, 0xf,0x3d,0x5c, + 0xf,0x3d,0x5d, 0xf,0x3d,0x5e, 0xf,0x3d,0x5f, 0xf,0x3d,0x62, + 0xf,0x3d,0x63, 0xf,0x3d,0x64, 0xf,0x44,0x28, 0xf,0x44,0x2a, + 0xf,0x3d,0x61, 0x6,0x55,0x74, 0x5,0x48,0x23, 0x6,0x5f,0x5f, + 0x6,0x5f,0x60, 0x4,0x45,0x56, 0x6,0x5f,0x63, 0x6,0x5f,0x61, + 0xf,0x44,0x27, 0xf,0x44,0x29, 0xf,0x44,0x2b, 0xf,0x44,0x2c, + 0xf,0x44,0x2d, 0xf,0x44,0x2e, 0xf,0x44,0x2f, 0xf,0x44,0x30, + 0xf,0x44,0x31, 0xf,0x44,0x32, 0x6,0x5f,0x5d, 0x6,0x5f,0x62, + 0x5,0x48,0x21, 0x6,0x5f,0x5e, 0x4,0x4b,0x5f, 0x7,0x26,0x26, + 0x6,0x5f,0x5c, 0x6,0x5f,0x64, 0xf,0x4a,0x53, 0xf,0x4a,0x55, + 0xf,0x4a,0x56, 0xf,0x4a,0x57, 0xf,0x4a,0x58, 0xf,0x4a,0x5a, + 0x7,0x26,0x28, 0x5,0x56,0x38, 0x7,0x30,0x5c, 0x5,0x56,0x36, + 0x7,0x30,0x5d, 0x4,0x51,0x77, 0x5,0x56,0x39, 0x5,0x56,0x37, + 0x5,0x56,0x3a, 0x7,0x26,0x2a, 0x7,0x30,0x5b, 0xf,0x50,0x6a, + 0xf,0x50,0x69, 0xf,0x56,0x51, 0x4,0x57,0x43, 0x5,0x5c,0x5a, + 0x7,0x39,0x73, 0x4,0x57,0x44, 0x7,0x39,0x76, 0x7,0x39,0x74, + 0x7,0x30,0x5e, 0xf,0x50,0x6b, 0xf,0x56,0x4e, 0xf,0x56,0x4f, + 0xf,0x56,0x50, 0xf,0x56,0x52, 0x7,0x39,0x71, 0x7,0x39,0x75, + 0x7,0x39,0x72, 0x7,0x39,0x70, 0xf,0x5b,0x4d, 0xf,0x5b,0x4f, + 0x4,0x5c,0x34, 0x5,0x62,0x7b, 0x7,0x41,0x2c, 0xf,0x5b,0x4b, + 0xf,0x5b,0x4c, 0xf,0x5b,0x4e, 0xf,0x5b,0x50, 0xf,0x5b,0x51, + 0xf,0x5b,0x52, 0x7,0x41,0x2b, 0x4,0x5c,0x33, 0x5,0x68,0x5b, + 0x7,0x48,0x3c, 0x7,0x48,0x3d, 0xf,0x5f,0x6a, 0xf,0x5f,0x6b, + 0x5,0x6c,0x68, 0x4,0x63,0x77, 0xf,0x65,0x5e, 0x7,0x4e,0x5e, + 0x7,0x54,0x26, 0x7,0x54,0x25, 0xf,0x65,0x5f, 0x4,0x68,0x7d, + 0x7,0x58,0x4a, 0x7,0x58,0x4b, 0x7,0x5c,0x29, 0xf,0x69,0x5d, + 0x7,0x5c,0x2a, 0x7,0x5c,0x2b, 0x5,0x77,0x6e, 0x7,0x5c,0x2c, + 0x5,0x77,0x6f, 0xf,0x6a,0x67, 0x5,0x79,0x32, 0x7,0x62,0x49, + 0x7,0x62,0x47, 0x7,0x63,0x5d, 0xf,0x6c,0x67, 0xf,0x22,0x69, + 0x6,0x33,0x4d, 0x6,0x42,0x64, 0x4,0x39,0x5b, 0x6,0x4c,0x40, + 0x6,0x55,0x76, 0x6,0x5f,0x65, 0x7,0x26,0x2c, 0x7,0x30,0x5f, + 0x7,0x30,0x60, 0x7,0x41,0x2d, 0x5,0x73,0x6b, 0x7,0x61,0x28, + 0x4,0x21,0x7e, 0x6,0x25,0x41, 0xf,0x22,0x6a, 0x6,0x28,0x6f, + 0xf,0x25,0x25, 0x6,0x28,0x70, 0x4,0x27,0x55, 0x5,0x27,0x48, + 0x4,0x27,0x57, 0x5,0x27,0x47, 0xf,0x28,0x3e, 0xf,0x28,0x3f, + 0xf,0x28,0x40, 0xf,0x28,0x41, 0xf,0x28,0x42, 0x6,0x2d,0x4a, + 0x6,0x33,0x51, 0x6,0x33,0x54, 0x5,0x2a,0x74, 0x5,0x2a,0x72, + 0x4,0x2a,0x70, 0x5,0x2a,0x75, 0x6,0x33,0x56, 0x6,0x33,0x50, + 0x6,0x33,0x52, 0x4,0x2a,0x6d, 0x6,0x33,0x4f, 0x5,0x2a,0x73, + 0x6,0x33,0x57, 0xf,0x2c,0x6b, 0xf,0x2c,0x6c, 0xf,0x2c,0x6e, + 0xf,0x2c,0x6f, 0xf,0x2c,0x70, 0x6,0x33,0x55, 0x6,0x33,0x53, + 0x6,0x33,0x4e, 0x5,0x2f,0x3c, 0x5,0x2f,0x3b, 0x6,0x3a,0x45, + 0x5,0x2f,0x3d, 0x6,0x3a,0x46, 0x5,0x2f,0x3e, 0x5,0x2a,0x76, + 0x5,0x34,0x3c, 0x6,0x3a,0x47, 0xf,0x31,0x55, 0xf,0x31,0x56, + 0x6,0x3a,0x42, 0x6,0x3a,0x44, 0x5,0x34,0x3a, 0x6,0x42,0x69, + 0x5,0x34,0x3f, 0x4,0x33,0x68, 0x5,0x34,0x3d, 0x6,0x42,0x68, + 0x5,0x34,0x37, 0xf,0x37,0x3a, 0xf,0x37,0x3c, 0xf,0x37,0x3d, + 0xf,0x37,0x3e, 0x4,0x33,0x6c, 0x6,0x42,0x65, 0x6,0x42,0x6a, + 0x4,0x39,0x5f, 0x5,0x3a,0x64, 0x4,0x39,0x60, 0x4,0x39,0x5c, + 0x6,0x4c,0x41, 0x6,0x4c,0x42, 0x6,0x4c,0x45, 0x6,0x4c,0x47, + 0x4,0x39,0x5d, 0x6,0x4c,0x44, 0x4,0x3f,0x51, 0xf,0x3d,0x65, + 0xf,0x3d,0x67, 0xf,0x3d,0x69, 0x5,0x34,0x3e, 0xf,0x3d,0x66, + 0x5,0x41,0x36, 0x5,0x41,0x2f, 0x6,0x55,0x79, 0x6,0x55,0x77, + 0x6,0x55,0x7a, 0x5,0x41,0x30, 0x5,0x41,0x2d, 0x5,0x41,0x32, + 0x5,0x41,0x34, 0x5,0x41,0x38, 0x5,0x41,0x33, 0x4,0x3f,0x4e, + 0x6,0x56,0x21, 0x5,0x41,0x2e, 0x6,0x55,0x7b, 0x6,0x55,0x7e, + 0x6,0x55,0x7c, 0xf,0x44,0x33, 0xf,0x44,0x34, 0xf,0x44,0x35, + 0xf,0x44,0x36, 0xf,0x44,0x37, 0xf,0x44,0x38, 0xf,0x44,0x39, + 0xf,0x44,0x3a, 0x6,0x55,0x78, 0x6,0x55,0x7d, 0x5,0x41,0x37, + 0x5,0x41,0x35, 0x5,0x48,0x28, 0x6,0x5f,0x69, 0x5,0x45,0x2d, + 0x5,0x48,0x2d, 0x6,0x5f,0x68, 0x6,0x5f,0x66, 0x6,0x5f,0x6a, + 0x4,0x45,0x5c, 0x5,0x48,0x2e, 0x5,0x48,0x29, 0x6,0x5f,0x6e, + 0x6,0x5f,0x6f, 0x5,0x48,0x2b, 0x5,0x48,0x27, 0x5,0x48,0x2c, + 0x6,0x5f,0x70, 0x5,0x48,0x2a, 0x6,0x5f,0x67, 0xf,0x4a,0x60, + 0xf,0x4a,0x5b, 0xf,0x4a,0x5c, 0xf,0x4a,0x5d, 0xf,0x4a,0x5e, + 0xf,0x4a,0x5f, 0xf,0x4a,0x61, 0xf,0x4a,0x62, 0xf,0x4a,0x63, + 0xf,0x4a,0x65, 0x6,0x5f,0x6d, 0x6,0x5f,0x6c, 0x5,0x4e,0x7b, + 0x5,0x4e,0x78, 0x5,0x4e,0x7a, 0x7,0x26,0x33, 0x7,0x26,0x30, + 0x5,0x4e,0x79, 0x4,0x4b,0x69, 0x7,0x26,0x34, 0x7,0x26,0x31, + 0x7,0x26,0x38, 0x5,0x48,0x2f, 0x7,0x26,0x2f, 0x5,0x56,0x45, + 0x5,0x4e,0x7c, 0x5,0x4e,0x7d, 0x4,0x4b,0x67, 0x4,0x4b,0x6a, + 0x7,0x26,0x35, 0xf,0x50,0x6c, 0xf,0x50,0x6e, 0xf,0x50,0x6f, + 0xf,0x50,0x70, 0xf,0x50,0x71, 0xf,0x50,0x72, 0x7,0x26,0x2e, + 0x7,0x26,0x36, 0x7,0x26,0x37, 0x4,0x51,0x7b, 0x7,0x30,0x6d, + 0x5,0x56,0x3d, 0x5,0x56,0x40, 0x7,0x30,0x69, 0x5,0x56,0x3c, + 0x5,0x56,0x3f, 0x5,0x56,0x3e, 0x4,0x51,0x7e, 0x5,0x56,0x3b, + 0x5,0x56,0x43, 0x7,0x30,0x63, 0x7,0x30,0x64, 0x5,0x56,0x42, + 0x7,0x30,0x62, 0x5,0x56,0x46, 0x5,0x5c,0x5b, 0x5,0x56,0x47, + 0x7,0x30,0x6b, 0x7,0x30,0x6a, 0x7,0x30,0x6c, 0x7,0x30,0x61, + 0xf,0x56,0x54, 0xf,0x56,0x55, 0x7,0x30,0x65, 0x7,0x30,0x67, + 0x7,0x30,0x68, 0x5,0x56,0x44, 0x5,0x56,0x41, 0x5,0x5c,0x5e, + 0x5,0x5c,0x61, 0x5,0x5c,0x62, 0x5,0x5c,0x5f, 0x5,0x5c,0x5c, + 0x5,0x5c,0x5d, 0x4,0x57,0x4a, 0x7,0x39,0x77, 0x5,0x5c,0x64, + 0x4,0x57,0x46, 0x5,0x5c,0x60, 0x7,0x39,0x7a, 0xf,0x5b,0x54, + 0xf,0x5b,0x55, 0xf,0x5b,0x56, 0xf,0x5b,0x57, 0xf,0x5b,0x58, + 0xf,0x5b,0x5a, 0x7,0x39,0x78, 0xf,0x5b,0x53, 0x5,0x56,0x48, + 0x7,0x39,0x79, 0x5,0x5c,0x63, 0xf,0x56,0x53, 0x5,0x62,0x7d, + 0x5,0x63,0x26, 0x5,0x63,0x24, 0x5,0x63,0x21, 0x5,0x63,0x22, + 0x5,0x63,0x25, 0x7,0x41,0x30, 0x5,0x62,0x7e, 0x7,0x41,0x2f, + 0x5,0x63,0x23, 0xf,0x5f,0x6c, 0xf,0x5f,0x6d, 0xf,0x5f,0x6e, + 0xf,0x5f,0x6f, 0xf,0x5f,0x70, 0xf,0x5f,0x71, 0xf,0x5f,0x72, + 0x5,0x62,0x7c, 0x5,0x68,0x5e, 0x4,0x60,0x43, 0x5,0x68,0x5c, + 0x4,0x60,0x44, 0x4,0x60,0x47, 0x7,0x48,0x3f, 0x4,0x60,0x46, + 0x5,0x68,0x5d, 0x7,0x4e,0x62, 0x7,0x48,0x41, 0x7,0x48,0x3e, + 0xf,0x63,0x30, 0x7,0x48,0x40, 0x5,0x6c,0x6b, 0x4,0x63,0x7a, + 0x4,0x63,0x78, 0x5,0x6c,0x6a, 0x7,0x4e,0x60, 0x4,0x5c,0x38, + 0x5,0x6c,0x69, 0x5,0x6c,0x6c, 0x7,0x4e,0x5f, 0x7,0x4e,0x61, + 0xf,0x65,0x60, 0xf,0x65,0x61, 0xf,0x65,0x63, 0x7,0x4e,0x63, + 0x5,0x6c,0x6d, 0x7,0x54,0x28, 0x7,0x54,0x27, 0x5,0x70,0x58, + 0x7,0x54,0x29, 0x7,0x58,0x4d, 0x5,0x73,0x6c, 0x7,0x58,0x4e, + 0x5,0x76,0x30, 0x5,0x76,0x31, 0x7,0x58,0x4f, 0x5,0x77,0x70, + 0x7,0x5c,0x2d, 0x7,0x5c,0x2e, 0x7,0x5f,0x28, 0x7,0x5e,0x71, + 0xf,0x6b,0x57, 0xf,0x6b,0x58, 0x4,0x6c,0x77, 0x5,0x79,0x33, + 0xf,0x6c,0x34, 0x4,0x6c,0x78, 0x5,0x7a,0x2e, 0x5,0x7b,0x61, + 0x5,0x7b,0x62, 0x6,0x23,0x37, 0x5,0x24,0x6f, 0x5,0x24,0x70, + 0x4,0x27,0x59, 0x4,0x27,0x5a, 0x4,0x27,0x58, 0x6,0x2d,0x4d, + 0x6,0x2d,0x4c, 0x6,0x2d,0x4f, 0x3,0x2a,0x45, 0x6,0x2d,0x4b, + 0xf,0x28,0x43, 0x4,0x2a,0x74, 0x6,0x33,0x59, 0x6,0x33,0x5b, + 0x6,0x33,0x58, 0x5,0x2a,0x77, 0x4,0x2a,0x73, 0x5,0x2a,0x79, + 0x5,0x2a,0x78, 0x6,0x33,0x5a, 0x6,0x33,0x5c, 0x6,0x33,0x5d, + 0x5,0x2a,0x7a, 0xf,0x2c,0x71, 0xf,0x2c,0x72, 0xf,0x2c,0x73, + 0x5,0x2f,0x3f, 0x4,0x2e,0x66, 0x4,0x2e,0x6b, 0x4,0x2e,0x68, + 0x5,0x2f,0x43, 0x5,0x2f,0x42, 0x5,0x2f,0x41, 0x6,0x3a,0x4c, + 0x4,0x2e,0x69, 0x4,0x2e,0x6a, 0x4,0x2e,0x67, 0x6,0x3a,0x4a, + 0x6,0x3a,0x48, 0x5,0x2f,0x40, 0x5,0x2f,0x44, 0xf,0x31,0x58, + 0xf,0x31,0x59, 0xf,0x31,0x5a, 0x6,0x3a,0x4b, 0x6,0x3a,0x49, + 0x5,0x34,0x44, 0x5,0x34,0x43, 0x6,0x42,0x6c, 0x6,0x42,0x6b, + 0x6,0x42,0x6d, 0x5,0x34,0x41, 0x4,0x33,0x6e, 0x5,0x34,0x42, + 0x5,0x34,0x40, 0x6,0x42,0x6e, 0xf,0x37,0x40, 0xf,0x37,0x41, + 0xf,0x37,0x42, 0xf,0x37,0x43, 0xf,0x37,0x44, 0x5,0x3a,0x72, + 0x4,0x39,0x66, 0x5,0x3a,0x74, 0x6,0x4c,0x4e, 0x6,0x4c,0x4a, + 0x4,0x39,0x69, 0x6,0x4c,0x52, 0x5,0x3a,0x69, 0x5,0x3a,0x6f, + 0x5,0x3a,0x71, 0x6,0x4c,0x50, 0x5,0x3a,0x67, 0x6,0x4c,0x51, + 0x5,0x3a,0x68, 0x6,0x4c,0x4b, 0x5,0x3a,0x6a, 0x4,0x39,0x68, + 0x5,0x3a,0x73, 0x6,0x4c,0x4c, 0x5,0x3a,0x70, 0x6,0x4c,0x49, + 0x5,0x3a,0x66, 0x5,0x3a,0x6d, 0x6,0x4c,0x4f, 0x5,0x3a,0x6e, + 0x5,0x3a,0x6b, 0x6,0x4c,0x4d, 0xf,0x3d,0x6b, 0x5,0x41,0x3a, + 0x6,0x56,0x29, 0x5,0x41,0x3c, 0x5,0x41,0x3b, 0x5,0x41,0x3e, + 0x6,0x56,0x22, 0x6,0x56,0x24, 0x5,0x3a,0x6c, 0x5,0x41,0x3d, + 0x5,0x41,0x3f, 0x6,0x56,0x28, 0x6,0x56,0x2b, 0x5,0x41,0x40, + 0x6,0x56,0x26, 0x6,0x56,0x25, 0xf,0x44,0x3b, 0xf,0x44,0x3d, + 0xf,0x44,0x3e, 0xf,0x44,0x3f, 0xf,0x44,0x40, 0x6,0x56,0x23, + 0x6,0x56,0x2a, 0x6,0x57,0x26, 0x4,0x45,0x61, 0x6,0x5f,0x77, + 0x5,0x48,0x32, 0x6,0x5f,0x76, 0x6,0x5f,0x72, 0x6,0x5f,0x74, + 0x6,0x5f,0x73, 0x5,0x48,0x31, 0x6,0x5f,0x79, 0xf,0x4a,0x66, + 0x5,0x48,0x33, 0x6,0x5f,0x71, 0xf,0x44,0x3c, 0x7,0x26,0x3b, + 0x5,0x4f,0x21, 0x5,0x4f,0x27, 0x5,0x4f,0x2a, 0x5,0x48,0x30, + 0x7,0x26,0x3a, 0x5,0x4f,0x2b, 0x5,0x4f,0x26, 0x5,0x4f,0x22, + 0x5,0x4f,0x2c, 0x5,0x4f,0x25, 0x7,0x26,0x39, 0x5,0x4e,0x7e, + 0x5,0x4f,0x28, 0x5,0x4f,0x24, 0x5,0x4f,0x29, 0x7,0x27,0x2e, + 0x4,0x4b,0x6d, 0x5,0x56,0x4f, 0x5,0x56,0x51, 0x4,0x52,0x23, + 0x5,0x56,0x50, 0x4,0x52,0x26, 0x5,0x56,0x49, 0x4,0x52,0x28, + 0x7,0x30,0x70, 0x5,0x56,0x4a, 0x5,0x56,0x4c, 0x5,0x56,0x4b, + 0x5,0x56,0x53, 0x5,0x56,0x4d, 0x5,0x56,0x54, 0x7,0x30,0x6e, + 0x5,0x56,0x4e, 0x5,0x5c,0x65, 0x5,0x56,0x55, 0xf,0x56,0x56, + 0xf,0x56,0x57, 0xf,0x56,0x58, 0xf,0x56,0x59, 0xf,0x56,0x5a, + 0x7,0x30,0x71, 0x5,0x5c,0x6a, 0x5,0x5c,0x67, 0x7,0x3a,0x21, + 0x4,0x57,0x4e, 0x5,0x5c,0x69, 0x7,0x39,0x7c, 0x7,0x39,0x7d, + 0x7,0x39,0x7b, 0x5,0x5c,0x66, 0x7,0x39,0x7e, 0x7,0x30,0x72, + 0x5,0x5c,0x68, 0xf,0x5b,0x5b, 0x5,0x63,0x28, 0x5,0x63,0x27, + 0xf,0x5f,0x74, 0x4,0x60,0x4a, 0x7,0x48,0x44, 0x7,0x48,0x43, + 0x5,0x68,0x5f, 0x7,0x48,0x42, 0x7,0x4e,0x64, 0x7,0x4e,0x66, + 0x5,0x68,0x60, 0x4,0x63,0x7b, 0x5,0x6c,0x6e, 0x7,0x54,0x2d, + 0x7,0x4e,0x67, 0x7,0x4e,0x65, 0xf,0x65,0x64, 0x5,0x70,0x5b, + 0x7,0x54,0x2b, 0x4,0x66,0x67, 0x4,0x66,0x66, 0x5,0x70,0x59, + 0x7,0x54,0x2c, 0x5,0x70,0x5a, 0xf,0x68,0x21, 0xf,0x65,0x65, + 0x5,0x76,0x32, 0x7,0x5c,0x2f, 0x5,0x77,0x71, 0x7,0x61,0x2a, + 0xf,0x6b,0x59, 0x7,0x5f,0x29, 0x5,0x79,0x34, 0x7,0x62,0x4a, + 0x5,0x7b,0x63, 0x6,0x28,0x72, 0x6,0x28,0x71, 0x5,0x27,0x49, + 0x5,0x27,0x4a, 0x4,0x2a,0x75, 0xf,0x2c,0x74, 0xf,0x2c,0x78, + 0x4,0x2e,0x6f, 0x5,0x2f,0x47, 0x5,0x2f,0x48, 0x4,0x2e,0x6c, + 0x5,0x2f,0x46, 0x5,0x2f,0x45, 0x4,0x2e,0x6e, 0xf,0x31,0x5c, + 0xf,0x31,0x5d, 0xf,0x31,0x5e, 0xf,0x31,0x5f, 0xf,0x31,0x61, + 0xf,0x31,0x62, 0x6,0x3a,0x4d, 0x6,0x3a,0x4e, 0x6,0x42,0x72, + 0x4,0x33,0x73, 0x6,0x42,0x71, 0x6,0x42,0x73, 0x6,0x42,0x70, + 0x4,0x33,0x74, 0xf,0x37,0x45, 0xf,0x37,0x47, 0x5,0x34,0x47, + 0xf,0x37,0x48, 0x4,0x39,0x6b, 0x6,0x4c,0x55, 0x5,0x3a,0x75, + 0x5,0x3a,0x77, 0x5,0x3a,0x76, 0x5,0x3a,0x78, 0x6,0x4c,0x54, + 0xf,0x3d,0x6d, 0xf,0x3d,0x6e, 0xf,0x3d,0x6f, 0xf,0x3d,0x70, + 0x4,0x3f,0x56, 0x4,0x3f,0x58, 0x5,0x41,0x42, 0x4,0x3f,0x59, + 0x6,0x56,0x2c, 0x5,0x41,0x41, 0x6,0x56,0x2d, 0x6,0x56,0x2e, + 0xf,0x44,0x41, 0xf,0x44,0x42, 0xf,0x44,0x43, 0x5,0x41,0x43, + 0x5,0x48,0x34, 0x6,0x5f,0x7a, 0x5,0x48,0x35, 0x4,0x45,0x62, + 0xf,0x4a,0x67, 0xf,0x4a,0x68, 0xf,0x4a,0x6a, 0xf,0x4a,0x69, + 0x7,0x26,0x3f, 0x4,0x4b,0x6e, 0x5,0x4f,0x2d, 0xf,0x50,0x73, + 0xf,0x50,0x74, 0xf,0x50,0x75, 0x7,0x26,0x3d, 0xf,0x56,0x5c, + 0xf,0x56,0x5b, 0x4,0x57,0x51, 0x7,0x30,0x74, 0x5,0x56,0x56, + 0xf,0x5b,0x5c, 0x5,0x5c,0x6c, 0x5,0x5d,0x63, 0x7,0x3a,0x22, + 0x5,0x5c,0x6b, 0x5,0x63,0x2a, 0x7,0x3a,0x23, 0xf,0x5f,0x75, + 0x7,0x41,0x31, 0x5,0x63,0x29, 0x7,0x4e,0x68, 0x7,0x54,0x2e, + 0xf,0x65,0x66, 0x7,0x48,0x45, 0x5,0x70,0x5c, 0xf,0x68,0x22, + 0x7,0x58,0x50, 0xf,0x69,0x5e, 0xf,0x6a,0x68, 0x7,0x61,0x2b, + 0xf,0x25,0x26, 0x5,0x27,0x4b, 0x6,0x2d,0x50, 0x5,0x27,0x4d, + 0x5,0x27,0x4c, 0x5,0x2a,0x7c, 0x5,0x2a,0x7d, 0x5,0x2a,0x7b, + 0x6,0x33,0x5f, 0x6,0x33,0x5e, 0x5,0x2a,0x7e, 0xf,0x2c,0x79, + 0xf,0x2c,0x7a, 0xf,0x2c,0x7b, 0xf,0x2c,0x7c, 0xf,0x2c,0x7d, + 0xf,0x29,0x24, 0x5,0x2f,0x4e, 0x5,0x2f,0x49, 0x4,0x2e,0x74, + 0x5,0x2f,0x4a, 0x5,0x2f,0x4c, 0x5,0x2f,0x4d, 0x6,0x3a,0x50, + 0x5,0x2f,0x51, 0x5,0x2f,0x4f, 0x5,0x2f,0x4b, 0x6,0x3a,0x4f, + 0x6,0x3a,0x51, 0x5,0x2f,0x50, 0x5,0x2f,0x52, 0xf,0x31,0x63, + 0xf,0x31,0x64, 0xf,0x31,0x65, 0xf,0x31,0x66, 0xf,0x31,0x67, + 0xf,0x31,0x68, 0xf,0x31,0x69, 0xf,0x31,0x6a, 0x4,0x2e,0x76, + 0x6,0x42,0x74, 0x6,0x42,0x7a, 0x5,0x34,0x4a, 0x4,0x33,0x79, + 0x5,0x34,0x4d, 0x6,0x42,0x77, 0x5,0x34,0x4c, 0x6,0x42,0x7c, + 0x4,0x33,0x75, 0x5,0x34,0x4e, 0x6,0x42,0x75, 0x5,0x2f,0x53, + 0x5,0x34,0x49, 0x6,0x42,0x79, 0x6,0x42,0x7b, 0x5,0x34,0x50, + 0x5,0x34,0x51, 0x6,0x42,0x78, 0xf,0x37,0x49, 0xf,0x37,0x4a, + 0xf,0x37,0x4b, 0xf,0x37,0x4c, 0xf,0x37,0x4e, 0xf,0x37,0x4f, + 0x5,0x3a,0x7c, 0x5,0x3b,0x22, 0x5,0x3a,0x7b, 0x5,0x3a,0x7e, + 0x4,0x39,0x6c, 0x4,0x39,0x6e, 0x6,0x4c,0x5a, 0x5,0x34,0x4b, + 0x4,0x39,0x73, 0x5,0x3b,0x21, 0x5,0x3a,0x7a, 0x4,0x39,0x79, + 0x4,0x39,0x77, 0x4,0x39,0x70, 0x6,0x4c,0x5d, 0x4,0x39,0x78, + 0x6,0x4c,0x57, 0x5,0x3b,0x25, 0x6,0x4c,0x59, 0x6,0x4c,0x5c, + 0x5,0x34,0x4f, 0x5,0x3a,0x7d, 0xf,0x3d,0x71, 0xf,0x3d,0x72, + 0xf,0x3d,0x73, 0xf,0x3d,0x74, 0xf,0x3d,0x75, 0xf,0x3d,0x76, + 0xf,0x3d,0x78, 0xf,0x3d,0x79, 0xf,0x3d,0x7a, 0xf,0x3d,0x77, + 0x5,0x3b,0x23, 0x5,0x41,0x54, 0x5,0x41,0x48, 0x5,0x41,0x4f, + 0x4,0x3f,0x5c, 0x5,0x41,0x4d, 0x5,0x41,0x45, 0x4,0x3f,0x64, + 0x4,0x3f,0x65, 0x5,0x41,0x50, 0x4,0x3f,0x5f, 0x5,0x3a,0x79, + 0x6,0x56,0x30, 0x5,0x41,0x46, 0x5,0x41,0x55, 0x5,0x41,0x4b, + 0x5,0x41,0x52, 0x5,0x41,0x44, 0x5,0x41,0x49, 0x5,0x41,0x4c, + 0x6,0x56,0x34, 0x6,0x56,0x32, 0x6,0x56,0x37, 0x6,0x56,0x3a, + 0x6,0x56,0x33, 0x6,0x56,0x36, 0x6,0x56,0x38, 0x6,0x5f,0x7b, + 0x5,0x41,0x53, 0x5,0x41,0x51, 0x5,0x41,0x4e, 0x5,0x41,0x47, + 0x6,0x56,0x31, 0x6,0x4c,0x58, 0x6,0x56,0x35, 0x6,0x56,0x39, + 0xf,0x44,0x44, 0xf,0x44,0x46, 0xf,0x44,0x47, 0xf,0x44,0x48, + 0xf,0x44,0x49, 0xf,0x44,0x4a, 0xf,0x44,0x4b, 0xf,0x44,0x4c, + 0xf,0x44,0x4d, 0xf,0x44,0x4e, 0xf,0x44,0x4f, 0xf,0x44,0x50, + 0x6,0x56,0x2f, 0xf,0x41,0x3e, 0x5,0x48,0x45, 0x5,0x41,0x56, + 0x4,0x45,0x6c, 0x5,0x48,0x43, 0x6,0x60,0x27, 0x4,0x45,0x67, + 0x6,0x5f,0x7c, 0x6,0x5f,0x7d, 0x5,0x48,0x3c, 0x5,0x48,0x3b, + 0x5,0x48,0x42, 0x4,0x45,0x6f, 0x6,0x60,0x28, 0x5,0x48,0x40, + 0x6,0x60,0x26, 0x5,0x48,0x38, 0x5,0x48,0x39, 0x6,0x60,0x25, + 0x6,0x60,0x21, 0x5,0x48,0x3a, 0x5,0x48,0x41, 0x5,0x48,0x37, + 0x5,0x48,0x3d, 0x6,0x60,0x22, 0x5,0x41,0x4a, 0x5,0x48,0x47, + 0x6,0x5f,0x7e, 0x5,0x48,0x3e, 0x6,0x60,0x24, 0x5,0x48,0x3f, + 0x4,0x45,0x71, 0x5,0x48,0x44, 0xf,0x4a,0x6b, 0xf,0x4a,0x6c, + 0xf,0x4a,0x6d, 0xf,0x4a,0x6e, 0xf,0x4a,0x6f, 0xf,0x4a,0x70, + 0xf,0x4a,0x73, 0xf,0x4a,0x74, 0xf,0x4a,0x75, 0xf,0x4a,0x76, + 0xf,0x4a,0x77, 0xf,0x4a,0x78, 0xf,0x4a,0x79, 0xf,0x4a,0x7a, + 0xf,0x4a,0x72, 0xf,0x4a,0x71, 0x5,0x4f,0x3a, 0x7,0x26,0x49, + 0x7,0x26,0x4b, 0x5,0x4f,0x44, 0x4,0x4c,0x2f, 0x5,0x4f,0x33, + 0x7,0x26,0x51, 0x7,0x26,0x4a, 0x5,0x4f,0x3e, 0x4,0x4b,0x71, + 0x4,0x4b,0x6f, 0x5,0x4f,0x41, 0x5,0x4f,0x2f, 0x5,0x4f,0x34, + 0x5,0x4f,0x43, 0x7,0x26,0x42, 0x5,0x4f,0x40, 0x5,0x4f,0x31, + 0x4,0x52,0x40, 0x5,0x4f,0x39, 0x5,0x4f,0x42, 0x4,0x4b,0x72, + 0x4,0x4c,0x29, 0x4,0x4c,0x23, 0x4,0x4b,0x7d, 0x5,0x4f,0x38, + 0x5,0x4f,0x37, 0x5,0x4f,0x3c, 0x7,0x26,0x4e, 0x5,0x48,0x48, + 0x5,0x4f,0x35, 0x7,0x26,0x50, 0x7,0x26,0x47, 0x7,0x26,0x44, + 0x5,0x4f,0x3f, 0x7,0x26,0x40, 0x7,0x26,0x53, 0x4,0x4c,0x24, + 0x7,0x26,0x4f, 0x4,0x4b,0x7c, 0x7,0x26,0x4c, 0x5,0x4f,0x3d, + 0x7,0x26,0x45, 0x7,0x26,0x43, 0x5,0x4f,0x2e, 0x7,0x26,0x48, + 0x7,0x26,0x46, 0x5,0x4f,0x46, 0xf,0x50,0x78, 0x7,0x26,0x52, + 0xf,0x50,0x77, 0xf,0x50,0x7a, 0xf,0x50,0x7b, 0xf,0x50,0x7c, + 0xf,0x50,0x7d, 0xf,0x50,0x7e, 0xf,0x51,0x22, 0xf,0x51,0x24, + 0xf,0x51,0x29, 0xf,0x51,0x25, 0xf,0x51,0x26, 0xf,0x51,0x27, + 0xf,0x51,0x2a, 0x5,0x56,0x64, 0x4,0x52,0x41, 0x4,0x52,0x3e, + 0x5,0x56,0x58, 0x5,0x56,0x5e, 0x5,0x56,0x66, 0x7,0x31,0x2a, + 0x5,0x56,0x5c, 0x4,0x52,0x2e, 0x5,0x56,0x5d, 0x4,0x52,0x2c, + 0x5,0x56,0x68, 0x7,0x26,0x41, 0x7,0x31,0x25, 0x4,0x52,0x32, + 0x5,0x56,0x67, 0x4,0x52,0x31, 0x7,0x31,0x29, 0x4,0x52,0x3c, + 0x7,0x30,0x7e, 0x7,0x31,0x26, 0x4,0x52,0x30, 0x5,0x56,0x60, + 0x7,0x30,0x7b, 0x4,0x52,0x3f, 0x5,0x56,0x5f, 0x5,0x56,0x59, + 0x7,0x30,0x7a, 0x7,0x31,0x28, 0x4,0x52,0x2a, 0x5,0x56,0x57, + 0x7,0x31,0x24, 0x4,0x52,0x35, 0x5,0x56,0x65, 0x7,0x30,0x7d, + 0x5,0x56,0x62, 0x4,0x52,0x33, 0x7,0x31,0x2b, 0x7,0x30,0x75, + 0x7,0x31,0x27, 0x5,0x4f,0x30, 0x5,0x56,0x63, 0x5,0x56,0x5a, + 0x7,0x30,0x78, 0x7,0x31,0x23, 0x7,0x30,0x76, 0x5,0x56,0x61, + 0xf,0x56,0x72, 0x5,0x56,0x5b, 0x7,0x30,0x7c, 0x7,0x30,0x77, + 0x7,0x31,0x22, 0xf,0x56,0x5d, 0xf,0x56,0x5e, 0xf,0x56,0x60, + 0xf,0x56,0x61, 0xf,0x56,0x62, 0xf,0x56,0x63, 0xf,0x56,0x64, + 0xf,0x56,0x65, 0xf,0x56,0x66, 0xf,0x56,0x67, 0xf,0x56,0x68, + 0xf,0x56,0x69, 0xf,0x56,0x6a, 0xf,0x56,0x6b, 0xf,0x56,0x6c, + 0xf,0x56,0x6d, 0xf,0x56,0x6e, 0xf,0x56,0x6f, 0xf,0x56,0x70, + 0xf,0x56,0x71, 0xf,0x56,0x73, 0x7,0x30,0x79, 0xf,0x50,0x79, + 0x5,0x5d,0x24, 0x5,0x5d,0x21, 0x4,0x57,0x5d, 0x5,0x5c,0x75, + 0x5,0x5d,0x2d, 0x5,0x5c,0x79, 0x4,0x57,0x5c, 0x4,0x57,0x63, + 0x4,0x57,0x67, 0x7,0x3a,0x2c, 0x5,0x5d,0x2b, 0x4,0x57,0x60, + 0x5,0x5d,0x22, 0x5,0x5c,0x70, 0x5,0x5d,0x23, 0x5,0x5c,0x72, + 0x5,0x5d,0x31, 0x5,0x5c,0x7b, 0x5,0x5d,0x2a, 0x5,0x5c,0x77, + 0x5,0x5d,0x34, 0x7,0x3a,0x24, 0x5,0x5c,0x76, 0x5,0x5c,0x7c, + 0x5,0x5d,0x26, 0x4,0x57,0x64, 0x5,0x5d,0x27, 0x7,0x3a,0x29, + 0x5,0x63,0x42, 0x5,0x5d,0x2c, 0x5,0x5c,0x7a, 0x7,0x3a,0x2f, + 0x7,0x3a,0x28, 0x5,0x5c,0x6f, 0x5,0x5d,0x32, 0x5,0x5d,0x29, + 0x5,0x5c,0x73, 0x7,0x3a,0x2b, 0x5,0x5d,0x2e, 0x5,0x5c,0x71, + 0x5,0x5c,0x6e, 0x5,0x5d,0x28, 0x4,0x57,0x66, 0x4,0x5c,0x3c, + 0x5,0x5d,0x33, 0x5,0x5c,0x78, 0x5,0x5d,0x2f, 0x5,0x5d,0x25, + 0x7,0x31,0x21, 0x5,0x5c,0x74, 0x7,0x3a,0x27, 0x7,0x3a,0x26, + 0x7,0x3a,0x25, 0x7,0x3a,0x2d, 0xf,0x5b,0x5d, 0xf,0x5b,0x5e, + 0xf,0x5b,0x60, 0xf,0x5b,0x61, 0xf,0x5b,0x62, 0xf,0x5b,0x63, + 0xf,0x5b,0x64, 0xf,0x5b,0x66, 0xf,0x5b,0x67, 0xf,0x5b,0x68, + 0xf,0x5b,0x69, 0x7,0x3a,0x2a, 0x7,0x3a,0x2e, 0x4,0x57,0x68, + 0xf,0x5b,0x65, 0x4,0x57,0x61, 0x5,0x63,0x4b, 0x5,0x63,0x47, + 0x5,0x5d,0x35, 0x4,0x5c,0x52, 0x5,0x63,0x45, 0x5,0x63,0x38, + 0x5,0x63,0x33, 0x4,0x5c,0x47, 0x5,0x63,0x4a, 0x5,0x63,0x40, + 0x3,0x58,0x4f, 0x5,0x63,0x2e, 0x4,0x5c,0x4e, 0x4,0x5c,0x45, + 0x5,0x63,0x43, 0x5,0x63,0x39, 0x5,0x63,0x4c, 0x4,0x5c,0x3d, + 0x7,0x41,0x3b, 0x5,0x63,0x46, 0x5,0x63,0x30, 0x5,0x63,0x37, + 0x4,0x5c,0x3e, 0x4,0x5c,0x3f, 0x5,0x63,0x48, 0x7,0x41,0x39, + 0x5,0x63,0x35, 0x5,0x63,0x32, 0x5,0x63,0x3f, 0x7,0x41,0x35, + 0x5,0x63,0x2c, 0x7,0x41,0x36, 0x4,0x5c,0x41, 0x7,0x41,0x33, + 0x4,0x5c,0x53, 0x5,0x63,0x3e, 0x7,0x41,0x38, 0x5,0x63,0x3d, + 0x7,0x41,0x3a, 0x7,0x41,0x3e, 0x7,0x41,0x34, 0x5,0x63,0x31, + 0x4,0x5c,0x4d, 0x5,0x63,0x36, 0x5,0x63,0x3a, 0x5,0x63,0x44, + 0x5,0x63,0x49, 0x5,0x63,0x3c, 0x5,0x63,0x2d, 0x7,0x41,0x42, + 0x7,0x41,0x41, 0x5,0x63,0x3b, 0x5,0x63,0x2b, 0x5,0x63,0x2f, + 0x7,0x41,0x32, 0x7,0x41,0x37, 0xf,0x5f,0x76, 0xf,0x5f,0x77, + 0xf,0x5f,0x78, 0xf,0x5f,0x79, 0xf,0x5f,0x7a, 0xf,0x5f,0x7b, + 0xf,0x5f,0x7c, 0xf,0x5f,0x7d, 0xf,0x5f,0x7e, 0xf,0x60,0x21, + 0xf,0x60,0x23, 0xf,0x60,0x24, 0xf,0x60,0x25, 0x7,0x41,0x40, + 0x7,0x41,0x3d, 0xf,0x5b,0x6a, 0xf,0x63,0x36, 0xf,0x63,0x37, + 0xf,0x60,0x22, 0x5,0x68,0x6a, 0x5,0x68,0x6f, 0x7,0x48,0x4e, + 0x4,0x60,0x59, 0x7,0x48,0x4c, 0x5,0x68,0x63, 0x4,0x60,0x54, + 0x4,0x60,0x55, 0x4,0x60,0x51, 0x5,0x68,0x69, 0x4,0x60,0x4f, + 0x4,0x60,0x50, 0x7,0x48,0x48, 0x4,0x60,0x52, 0x5,0x68,0x62, + 0x4,0x60,0x58, 0x4,0x60,0x4d, 0x7,0x48,0x47, 0x5,0x68,0x6d, + 0x5,0x68,0x68, 0x5,0x68,0x70, 0x5,0x68,0x6c, 0x5,0x68,0x6b, + 0x5,0x68,0x65, 0x5,0x68,0x64, 0x5,0x68,0x67, 0x7,0x48,0x46, + 0x7,0x48,0x4a, 0x5,0x68,0x61, 0x5,0x68,0x71, 0x7,0x48,0x49, + 0xf,0x63,0x31, 0xf,0x63,0x33, 0xf,0x63,0x34, 0xf,0x63,0x35, + 0xf,0x63,0x38, 0xf,0x63,0x39, 0xf,0x63,0x3a, 0xf,0x63,0x3b, + 0xf,0x63,0x3c, 0x7,0x48,0x4b, 0x7,0x48,0x4d, 0x5,0x6c,0x7c, + 0x5,0x6c,0x7b, 0x5,0x6c,0x76, 0x4,0x60,0x57, 0x5,0x6c,0x74, + 0x7,0x4e,0x6c, 0x5,0x6c,0x7a, 0x4,0x63,0x7d, 0x7,0x4e,0x74, + 0x4,0x64,0x22, 0x5,0x6c,0x78, 0x5,0x6c,0x73, 0x4,0x66,0x70, + 0x7,0x4e,0x6a, 0x5,0x6c,0x6f, 0x5,0x6c,0x75, 0x5,0x6c,0x71, + 0x7,0x4e,0x69, 0x7,0x4e,0x75, 0x5,0x6c,0x77, 0x7,0x4e,0x6d, + 0x7,0x4e,0x6e, 0x5,0x6c,0x72, 0x7,0x4e,0x6f, 0x7,0x54,0x38, + 0x7,0x4e,0x71, 0x7,0x4e,0x70, 0x7,0x4e,0x72, 0x7,0x4e,0x73, + 0xf,0x65,0x68, 0xf,0x65,0x69, 0x7,0x4e,0x6b, 0x5,0x70,0x64, + 0x5,0x70,0x68, 0x5,0x70,0x69, 0x4,0x66,0x71, 0x4,0x66,0x6b, + 0x5,0x70,0x66, 0x5,0x70,0x6b, 0x7,0x54,0x2f, 0x5,0x70,0x5e, + 0x5,0x70,0x63, 0x5,0x70,0x60, 0x4,0x64,0x21, 0x5,0x70,0x67, + 0x5,0x70,0x5f, 0x5,0x6c,0x70, 0x7,0x54,0x35, 0x5,0x70,0x6a, + 0x5,0x70,0x5d, 0x7,0x54,0x31, 0x5,0x70,0x65, 0x4,0x69,0x27, + 0x5,0x70,0x6c, 0x7,0x54,0x36, 0x7,0x54,0x30, 0x7,0x54,0x34, + 0xf,0x68,0x23, 0xf,0x68,0x24, 0xf,0x68,0x25, 0xf,0x68,0x26, + 0xf,0x68,0x27, 0xf,0x68,0x28, 0xf,0x68,0x29, 0x7,0x54,0x33, + 0x7,0x54,0x39, 0x7,0x54,0x32, 0x7,0x58,0x55, 0x4,0x69,0x24, + 0x4,0x69,0x23, 0x5,0x73,0x70, 0x5,0x73,0x6e, 0x5,0x70,0x62, + 0x5,0x73,0x71, 0x7,0x58,0x52, 0x5,0x70,0x6d, 0x7,0x58,0x51, + 0x5,0x73,0x74, 0x4,0x69,0x25, 0x5,0x73,0x6d, 0x7,0x58,0x54, + 0x7,0x54,0x37, 0x5,0x73,0x76, 0x5,0x73,0x73, 0x5,0x73,0x6f, + 0x5,0x73,0x75, 0x5,0x73,0x72, 0x7,0x58,0x56, 0xf,0x69,0x5f, + 0xf,0x69,0x60, 0xf,0x69,0x61, 0xf,0x69,0x62, 0x7,0x58,0x53, + 0x7,0x59,0x34, 0x4,0x6a,0x5e, 0x5,0x76,0x33, 0x7,0x5c,0x31, + 0x5,0x76,0x34, 0x4,0x6a,0x5f, 0x4,0x6a,0x60, 0x4,0x6a,0x62, + 0x7,0x5c,0x30, 0x5,0x76,0x36, 0x7,0x5c,0x32, 0x5,0x76,0x35, + 0x7,0x5c,0x36, 0x7,0x5c,0x35, 0xf,0x6a,0x69, 0x7,0x5c,0x33, + 0x7,0x5c,0x37, 0x7,0x5c,0x34, 0x5,0x77,0x72, 0x7,0x5f,0x2b, + 0x7,0x5f,0x2e, 0x5,0x77,0x74, 0x5,0x77,0x75, 0x7,0x5f,0x2d, + 0x5,0x76,0x37, 0x7,0x5f,0x2c, 0x7,0x5f,0x2a, 0x5,0x77,0x73, + 0x7,0x5f,0x31, 0x4,0x6b,0x77, 0xf,0x6b,0x5a, 0xf,0x6b,0x5b, + 0xf,0x6b,0x5c, 0x7,0x5f,0x2f, 0x5,0x79,0x35, 0x7,0x61,0x2c, + 0x7,0x61,0x2e, 0x7,0x61,0x31, 0x4,0x6c,0x79, 0x7,0x61,0x2f, + 0x7,0x5f,0x30, 0x7,0x61,0x2d, 0x5,0x7a,0x31, 0x5,0x7a,0x2f, + 0x5,0x7a,0x30, 0x7,0x61,0x30, 0xf,0x6c,0x4f, 0xf,0x6c,0x4d, + 0x7,0x63,0x5e, 0x7,0x63,0x5f, 0xf,0x6c,0x68, 0x7,0x63,0x60, + 0x5,0x7b,0x44, 0x5,0x7b,0x64, 0xf,0x6d,0x27, 0x7,0x64,0x54, + 0x4,0x6e,0x4e, 0x5,0x7b,0x7c, 0x5,0x7c,0x2b, 0x5,0x24,0x71, + 0xf,0x25,0x27, 0x5,0x27,0x4e, 0x6,0x2d,0x51, 0xf,0x28,0x45, + 0x6,0x33,0x61, 0x5,0x2b,0x22, 0x6,0x33,0x60, 0x5,0x2b,0x23, + 0xf,0x2c,0x7e, 0xf,0x2d,0x22, 0x6,0x3a,0x52, 0x5,0x2f,0x54, + 0x6,0x3a,0x56, 0x5,0x2f,0x55, 0x6,0x3a,0x54, 0x5,0x2f,0x56, + 0xf,0x31,0x6b, 0xf,0x31,0x6c, 0xf,0x31,0x6d, 0xf,0x31,0x6e, + 0x6,0x3a,0x53, 0x6,0x3a,0x55, 0x4,0x33,0x7e, 0x5,0x34,0x55, + 0x4,0x34,0x24, 0x5,0x34,0x54, 0x4,0x34,0x21, 0x5,0x34,0x58, + 0x5,0x34,0x53, 0x5,0x34,0x56, 0x5,0x34,0x57, 0x4,0x34,0x23, + 0x5,0x34,0x5a, 0x5,0x34,0x52, 0x6,0x42,0x7d, 0x6,0x4c,0x63, + 0x6,0x43,0x21, 0xf,0x37,0x50, 0xf,0x37,0x51, 0x6,0x42,0x7e, + 0xf,0x37,0x52, 0x5,0x3b,0x26, 0x4,0x39,0x7a, 0x6,0x4c,0x61, + 0x6,0x4c,0x5e, 0x6,0x4c,0x65, 0x5,0x3b,0x28, 0x4,0x3a,0x21, + 0x6,0x4c,0x64, 0x6,0x4c,0x5f, 0xf,0x3d,0x7c, 0xf,0x3d,0x7e, + 0xf,0x3e,0x22, 0xf,0x3d,0x7b, 0x6,0x4c,0x62, 0x5,0x41,0x57, + 0x4,0x3f,0x68, 0x6,0x56,0x3d, 0x5,0x41,0x59, 0x5,0x41,0x5a, + 0x5,0x3b,0x27, 0x5,0x41,0x58, 0x6,0x56,0x3f, 0x6,0x56,0x3e, + 0x4,0x39,0x7e, 0x5,0x41,0x5b, 0x5,0x41,0x5d, 0x5,0x41,0x5c, + 0x6,0x56,0x41, 0xf,0x44,0x52, 0xf,0x44,0x53, 0xf,0x44,0x55, + 0xf,0x44,0x56, 0x6,0x56,0x3b, 0xf,0x44,0x54, 0x6,0x56,0x40, + 0xf,0x44,0x51, 0x6,0x60,0x2d, 0x5,0x48,0x4a, 0x6,0x60,0x2b, + 0x6,0x60,0x2e, 0x5,0x48,0x4c, 0x4,0x45,0x73, 0x6,0x56,0x3c, + 0x6,0x60,0x33, 0x6,0x60,0x32, 0x5,0x48,0x4b, 0x6,0x60,0x30, + 0x5,0x48,0x49, 0x5,0x48,0x4d, 0xf,0x4a,0x7c, 0xf,0x4a,0x7d, + 0xf,0x4a,0x7e, 0xf,0x4b,0x21, 0xf,0x4b,0x22, 0xf,0x4b,0x23, + 0xf,0x4b,0x25, 0xf,0x4b,0x26, 0xf,0x4b,0x28, 0xf,0x4b,0x29, + 0xf,0x4b,0x2a, 0xf,0x4b,0x2d, 0x6,0x60,0x2f, 0xf,0x4b,0x2c, + 0x6,0x60,0x29, 0x6,0x60,0x2a, 0xf,0x4b,0x24, 0x7,0x26,0x58, + 0x7,0x26,0x54, 0x4,0x4c,0x36, 0x5,0x4f,0x4b, 0x7,0x26,0x55, + 0x7,0x26,0x59, 0x4,0x4c,0x33, 0x5,0x4f,0x4a, 0x5,0x4f,0x4c, + 0x5,0x4f,0x50, 0x5,0x48,0x4e, 0x5,0x4f,0x4f, 0x5,0x4f,0x4d, + 0x7,0x26,0x5b, 0x7,0x26,0x56, 0x5,0x4f,0x49, 0x4,0x4c,0x34, + 0x5,0x4f,0x4e, 0x4,0x4c,0x32, 0x7,0x26,0x5a, 0x5,0x4f,0x48, + 0x5,0x4f,0x47, 0xf,0x51,0x2b, 0xf,0x51,0x2c, 0xf,0x51,0x2d, + 0xf,0x51,0x2f, 0x5,0x56,0x6e, 0x5,0x56,0x6c, 0x5,0x5d,0x3c, + 0x4,0x52,0x43, 0x5,0x56,0x6b, 0x4,0x52,0x42, 0x7,0x31,0x2f, + 0x7,0x31,0x30, 0x5,0x56,0x6f, 0x7,0x31,0x2c, 0x5,0x56,0x6a, + 0x5,0x56,0x6d, 0x5,0x56,0x70, 0xf,0x56,0x74, 0xf,0x56,0x75, + 0x7,0x31,0x2e, 0x5,0x5d,0x36, 0x5,0x5d,0x38, 0x7,0x3a,0x30, + 0x5,0x5d,0x39, 0x5,0x5d,0x37, 0x5,0x5d,0x3a, 0x5,0x5d,0x3b, + 0x7,0x3a,0x32, 0x7,0x3a,0x34, 0x7,0x3a,0x35, 0x7,0x3a,0x31, + 0xf,0x5b,0x6b, 0xf,0x5b,0x6c, 0xf,0x5b,0x6d, 0xf,0x5b,0x6f, + 0xf,0x5b,0x70, 0xf,0x5b,0x71, 0xf,0x5b,0x72, 0x4,0x57,0x6c, + 0x5,0x63,0x52, 0x7,0x41,0x45, 0x4,0x5c,0x57, 0x5,0x63,0x53, + 0x5,0x63,0x4f, 0x7,0x48,0x56, 0x5,0x63,0x51, 0x5,0x5d,0x3d, + 0x7,0x41,0x46, 0x5,0x63,0x50, 0x7,0x4e,0x78, 0x5,0x63,0x4d, + 0x7,0x41,0x43, 0xf,0x60,0x27, 0xf,0x60,0x28, 0xf,0x60,0x29, + 0xf,0x5b,0x6e, 0x5,0x68,0x74, 0x7,0x48,0x4f, 0x7,0x48,0x50, + 0x4,0x60,0x5e, 0x4,0x60,0x5c, 0x5,0x68,0x73, 0x5,0x70,0x6e, + 0x7,0x48,0x52, 0x7,0x48,0x53, 0x7,0x41,0x48, 0x4,0x60,0x5f, + 0x4,0x5c,0x58, 0x5,0x68,0x75, 0x7,0x41,0x47, 0x5,0x68,0x72, + 0xf,0x63,0x3e, 0x7,0x48,0x51, 0x7,0x48,0x54, 0x7,0x48,0x55, + 0xf,0x63,0x3f, 0x7,0x4e,0x77, 0x5,0x6c,0x7e, 0x7,0x4e,0x76, + 0xf,0x65,0x6a, 0xf,0x65,0x6b, 0x4,0x66,0x73, 0x4,0x66,0x72, + 0x5,0x70,0x6f, 0x7,0x54,0x3d, 0x7,0x54,0x3c, 0xf,0x68,0x2a, + 0xf,0x68,0x2b, 0x7,0x54,0x3b, 0x5,0x73,0x77, 0x7,0x58,0x57, + 0x5,0x73,0x78, 0x4,0x6a,0x63, 0x4,0x6a,0x64, 0x7,0x5c,0x38, + 0xf,0x6a,0x6a, 0x5,0x76,0x38, 0x7,0x5c,0x39, 0x7,0x5f,0x32, + 0x5,0x77,0x77, 0x5,0x77,0x76, 0x5,0x79,0x38, 0x7,0x61,0x33, + 0x5,0x79,0x37, 0x5,0x79,0x36, 0x7,0x61,0x32, 0x7,0x62,0x4c, + 0x4,0x6d,0x5d, 0x5,0x7a,0x32, 0x7,0x62,0x4b, 0x5,0x7a,0x33, + 0x7,0x63,0x62, 0x7,0x63,0x61, 0x5,0x7b,0x7d, 0x7,0x66,0x36, + 0x5,0x27,0x4f, 0x6,0x2d,0x52, 0x5,0x27,0x50, 0xf,0x28,0x47, + 0xf,0x28,0x48, 0x5,0x27,0x51, 0x5,0x2b,0x26, 0x6,0x33,0x62, + 0x6,0x33,0x65, 0x5,0x2b,0x24, 0x5,0x2b,0x25, 0x6,0x33,0x67, + 0x6,0x33,0x63, 0x5,0x2b,0x27, 0xf,0x2d,0x23, 0x6,0x33,0x68, + 0x6,0x3a,0x5b, 0x6,0x3a,0x57, 0x4,0x2e,0x79, 0x6,0x3a,0x63, + 0x4,0x2e,0x7b, 0x6,0x3a,0x5d, 0x6,0x3a,0x5c, 0x6,0x3a,0x5f, + 0x5,0x2f,0x5a, 0x4,0x2e,0x7a, 0x4,0x2f,0x24, 0x6,0x3a,0x64, + 0x6,0x3a,0x59, 0x4,0x2f,0x23, 0x6,0x3a,0x5e, 0x4,0x2f,0x22, + 0x6,0x3a,0x60, 0x6,0x3a,0x58, 0x5,0x2f,0x59, 0x6,0x3a,0x61, + 0x5,0x2f,0x58, 0x5,0x2f,0x57, 0x6,0x3a,0x5a, 0xf,0x31,0x71, + 0xf,0x31,0x72, 0xf,0x31,0x73, 0xf,0x31,0x74, 0xf,0x31,0x75, + 0xf,0x31,0x76, 0xf,0x31,0x77, 0x4,0x2f,0x26, 0x6,0x3a,0x62, + 0x5,0x34,0x5f, 0x5,0x34,0x5d, 0x4,0x34,0x32, 0x4,0x34,0x28, + 0x4,0x34,0x2a, 0x6,0x43,0x28, 0x4,0x34,0x2f, 0x5,0x34,0x5e, + 0x4,0x34,0x31, 0x6,0x43,0x29, 0x5,0x34,0x5b, 0x4,0x34,0x2c, + 0x6,0x43,0x2b, 0x6,0x43,0x2a, 0x6,0x43,0x25, 0x6,0x43,0x23, + 0x6,0x43,0x24, 0x5,0x34,0x5c, 0xf,0x37,0x58, 0xf,0x37,0x59, + 0xf,0x37,0x5a, 0xf,0x37,0x5b, 0x6,0x43,0x27, 0x6,0x43,0x2c, + 0xf,0x37,0x55, 0x5,0x3b,0x31, 0x5,0x3b,0x30, 0x5,0x3b,0x2e, + 0x5,0x3b,0x32, 0x6,0x4c,0x6d, 0x4,0x3a,0x23, 0x6,0x4c,0x66, + 0x6,0x4c,0x6c, 0x4,0x3a,0x22, 0x4,0x3a,0x24, 0x6,0x4c,0x6e, + 0x6,0x43,0x26, 0x6,0x4c,0x67, 0x6,0x4c,0x70, 0x6,0x4c,0x68, + 0x5,0x3b,0x2d, 0x6,0x4c,0x6a, 0x6,0x4c,0x69, 0x6,0x4c,0x6f, + 0x5,0x3b,0x2a, 0x5,0x3b,0x29, 0x5,0x3b,0x2b, 0xf,0x3e,0x25, + 0xf,0x3e,0x26, 0xf,0x3e,0x27, 0xf,0x3e,0x28, 0xf,0x3e,0x29, + 0xf,0x3e,0x2a, 0xf,0x3e,0x2b, 0xf,0x3e,0x2c, 0xf,0x3e,0x2d, + 0xf,0x3e,0x2e, 0x6,0x4c,0x6b, 0x5,0x3b,0x2f, 0x6,0x56,0x4b, + 0x6,0x56,0x42, 0x5,0x41,0x5f, 0x5,0x41,0x5e, 0x4,0x3f,0x6c, + 0x6,0x56,0x44, 0x4,0x3f,0x6d, 0x6,0x56,0x48, 0x6,0x56,0x45, + 0x4,0x3f,0x69, 0x5,0x41,0x61, 0x5,0x41,0x60, 0x6,0x56,0x43, + 0x6,0x56,0x49, 0x4,0x3a,0x25, 0x4,0x3f,0x6b, 0x6,0x56,0x46, + 0x5,0x41,0x62, 0x6,0x56,0x4c, 0x6,0x56,0x4d, 0x4,0x3f,0x72, + 0x6,0x56,0x4a, 0xf,0x44,0x57, 0xf,0x44,0x58, 0xf,0x44,0x59, + 0xf,0x44,0x5a, 0xf,0x44,0x5b, 0xf,0x44,0x5c, 0xf,0x44,0x5d, + 0xf,0x44,0x5e, 0xf,0x44,0x5f, 0xf,0x44,0x60, 0xf,0x44,0x61, + 0xf,0x44,0x62, 0x6,0x56,0x47, 0x4,0x3f,0x70, 0x4,0x45,0x78, + 0x5,0x48,0x50, 0x4,0x45,0x76, 0x5,0x48,0x52, 0x6,0x60,0x3f, + 0x6,0x60,0x3e, 0x5,0x48,0x56, 0x4,0x45,0x7a, 0x5,0x48,0x55, + 0x4,0x45,0x77, 0x6,0x60,0x39, 0x6,0x60,0x43, 0x6,0x60,0x42, + 0x6,0x60,0x36, 0x4,0x45,0x7d, 0x5,0x48,0x4f, 0x5,0x41,0x63, + 0x6,0x60,0x41, 0x5,0x48,0x51, 0x6,0x60,0x3c, 0x6,0x60,0x34, + 0x5,0x48,0x53, 0x5,0x48,0x57, 0x6,0x60,0x40, 0x6,0x60,0x3b, + 0x4,0x46,0x22, 0x6,0x60,0x38, 0xf,0x4b,0x2e, 0xf,0x4b,0x2f, + 0xf,0x4b,0x30, 0xf,0x4b,0x31, 0xf,0x4b,0x32, 0xf,0x4b,0x33, + 0xf,0x4b,0x34, 0xf,0x4b,0x35, 0xf,0x4b,0x36, 0xf,0x4b,0x37, + 0x6,0x60,0x35, 0x6,0x60,0x37, 0x6,0x60,0x3d, 0x4,0x4c,0x38, + 0x4,0x4c,0x43, 0x7,0x26,0x60, 0x4,0x4c,0x42, 0x4,0x4c,0x3b, + 0x5,0x4f,0x5b, 0x5,0x4f,0x59, 0x4,0x52,0x48, 0x5,0x4f,0x58, + 0x5,0x4f,0x5d, 0x5,0x4f,0x55, 0x4,0x4c,0x46, 0x5,0x4f,0x5a, + 0x7,0x26,0x6c, 0x7,0x26,0x5e, 0x7,0x26,0x64, 0x5,0x4f,0x5c, + 0x5,0x4f,0x52, 0x7,0x26,0x61, 0x7,0x26,0x66, 0x5,0x4f,0x57, + 0x4,0x4c,0x41, 0x4,0x4c,0x39, 0x7,0x26,0x5d, 0x7,0x26,0x65, + 0x7,0x26,0x5c, 0x7,0x26,0x67, 0x6,0x60,0x3a, 0x7,0x26,0x6d, + 0x7,0x26,0x6b, 0x5,0x4f,0x51, 0x5,0x4f,0x56, 0x5,0x4f,0x5e, + 0xf,0x51,0x30, 0xf,0x51,0x31, 0xf,0x51,0x32, 0xf,0x51,0x33, + 0xf,0x51,0x34, 0xf,0x51,0x35, 0xf,0x51,0x38, 0xf,0x51,0x39, + 0xf,0x51,0x3a, 0xf,0x51,0x3d, 0xf,0x51,0x3e, 0xf,0x51,0x3f, + 0x7,0x26,0x62, 0x7,0x26,0x68, 0x7,0x26,0x5f, 0x7,0x26,0x63, + 0x7,0x31,0x46, 0x4,0x52,0x46, 0x7,0x31,0x43, 0x7,0x31,0x44, + 0x4,0x52,0x4a, 0x7,0x31,0x40, 0x7,0x31,0x3d, 0x5,0x56,0x74, + 0x5,0x56,0x76, 0x7,0x31,0x31, 0x7,0x31,0x42, 0x7,0x31,0x32, + 0x7,0x3a,0x36, 0x7,0x31,0x33, 0x7,0x31,0x36, 0x5,0x56,0x75, + 0x5,0x56,0x77, 0x5,0x56,0x73, 0x5,0x5d,0x45, 0x4,0x52,0x45, + 0x5,0x56,0x71, 0x5,0x56,0x72, 0x4,0x52,0x4b, 0x7,0x31,0x3a, + 0x7,0x31,0x37, 0x7,0x31,0x38, 0x7,0x31,0x41, 0x4,0x52,0x4d, + 0x7,0x31,0x35, 0x5,0x56,0x79, 0x7,0x31,0x34, 0x7,0x31,0x45, + 0x7,0x31,0x3b, 0x5,0x56,0x78, 0x7,0x31,0x3f, 0x7,0x31,0x3e, + 0x7,0x31,0x39, 0x7,0x31,0x3c, 0xf,0x56,0x76, 0xf,0x56,0x77, + 0xf,0x56,0x78, 0xf,0x56,0x79, 0xf,0x56,0x7a, 0xf,0x56,0x7b, + 0xf,0x56,0x7c, 0xf,0x56,0x7d, 0xf,0x56,0x7e, 0x7,0x3a,0x44, + 0x7,0x3a,0x43, 0x5,0x5d,0x43, 0x5,0x5d,0x40, 0x4,0x57,0x71, + 0x7,0x3a,0x37, 0x5,0x5d,0x41, 0x7,0x3a,0x42, 0x4,0x57,0x6f, + 0x7,0x3a,0x3a, 0x5,0x5d,0x44, 0x5,0x5d,0x3e, 0x7,0x3a,0x3e, + 0x7,0x3a,0x3b, 0x7,0x3a,0x3c, 0x7,0x3a,0x40, 0x5,0x5d,0x42, + 0x7,0x3a,0x41, 0x7,0x3a,0x3d, 0x5,0x5d,0x47, 0xf,0x5b,0x73, + 0xf,0x5b,0x74, 0xf,0x5b,0x75, 0xf,0x5b,0x77, 0xf,0x5b,0x78, + 0xf,0x5b,0x79, 0xf,0x5b,0x7a, 0xf,0x5b,0x7b, 0xf,0x5b,0x7c, + 0xf,0x5b,0x7d, 0xf,0x5b,0x7e, 0xf,0x5c,0x21, 0xf,0x5c,0x22, + 0x7,0x3a,0x3f, 0x7,0x3a,0x38, 0x4,0x5c,0x64, 0x4,0x5c,0x5c, + 0x7,0x41,0x4e, 0x4,0x5c,0x63, 0x4,0x5c,0x5d, 0x7,0x41,0x4d, + 0x7,0x41,0x54, 0x4,0x5c,0x61, 0x4,0x57,0x70, 0x7,0x41,0x49, + 0x5,0x63,0x55, 0x5,0x63,0x58, 0x5,0x63,0x57, 0x7,0x41,0x4b, + 0x7,0x41,0x51, 0x5,0x63,0x56, 0x7,0x41,0x4a, 0x7,0x41,0x4f, + 0x7,0x41,0x52, 0x7,0x41,0x4c, 0x7,0x41,0x57, 0x7,0x41,0x55, + 0x7,0x41,0x50, 0x7,0x41,0x5b, 0x5,0x63,0x5a, 0x7,0x41,0x56, + 0xf,0x60,0x2a, 0xf,0x60,0x2b, 0xf,0x60,0x2c, 0xf,0x60,0x2d, + 0xf,0x60,0x2e, 0xf,0x60,0x2f, 0xf,0x60,0x30, 0xf,0x60,0x31, + 0xf,0x60,0x32, 0x5,0x63,0x59, 0x7,0x41,0x5c, 0x7,0x41,0x5a, + 0x7,0x41,0x58, 0x7,0x41,0x53, 0x4,0x60,0x64, 0x4,0x60,0x65, + 0x7,0x48,0x5f, 0x4,0x60,0x69, 0x7,0x48,0x67, 0x5,0x68,0x76, + 0x7,0x48,0x64, 0x4,0x60,0x67, 0x7,0x48,0x66, 0x4,0x60,0x6b, + 0x5,0x68,0x79, 0x4,0x60,0x60, 0x5,0x68,0x7a, 0x7,0x48,0x61, + 0x7,0x47,0x4b, 0x4,0x60,0x61, 0x7,0x48,0x5d, 0x5,0x68,0x77, + 0x7,0x48,0x63, 0x7,0x48,0x5b, 0x7,0x48,0x62, 0x5,0x68,0x78, + 0x7,0x48,0x59, 0x7,0x48,0x5a, 0x7,0x48,0x60, 0x7,0x48,0x5e, + 0xf,0x63,0x40, 0xf,0x63,0x41, 0xf,0x63,0x43, 0xf,0x63,0x44, + 0xf,0x63,0x45, 0x7,0x4a,0x73, 0x7,0x48,0x5c, 0x7,0x48,0x65, + 0x4,0x60,0x6a, 0x7,0x4e,0x7d, 0x7,0x4e,0x7c, 0x5,0x6d,0x23, + 0x5,0x6d,0x21, 0x4,0x64,0x25, 0x7,0x4e,0x7e, 0x7,0x4f,0x23, + 0x7,0x4e,0x7b, 0x7,0x54,0x42, 0x7,0x48,0x58, 0x5,0x6d,0x24, + 0x7,0x4f,0x24, 0x7,0x4f,0x26, 0x7,0x4e,0x7a, 0x4,0x66,0x79, + 0x7,0x4f,0x22, 0x7,0x4e,0x79, 0x7,0x4f,0x25, 0xf,0x65,0x6c, + 0xf,0x65,0x6d, 0xf,0x65,0x6e, 0xf,0x65,0x70, 0xf,0x65,0x71, + 0x7,0x4f,0x21, 0x5,0x70,0x72, 0x4,0x66,0x75, 0x7,0x54,0x43, + 0x5,0x70,0x73, 0x4,0x66,0x78, 0x4,0x66,0x76, 0x4,0x66,0x77, + 0x7,0x58,0x5e, 0x7,0x4f,0x27, 0x7,0x54,0x3f, 0x7,0x54,0x3e, + 0x7,0x54,0x41, 0xf,0x68,0x2c, 0xf,0x68,0x2d, 0xf,0x68,0x2e, + 0xf,0x68,0x2f, 0x4,0x66,0x74, 0x7,0x54,0x40, 0x5,0x70,0x71, + 0x7,0x54,0x44, 0x5,0x73,0x7b, 0x7,0x58,0x59, 0x5,0x73,0x7c, + 0x5,0x73,0x79, 0x4,0x69,0x29, 0x5,0x76,0x3a, 0x7,0x58,0x5d, + 0x5,0x73,0x7a, 0x7,0x58,0x5b, 0xf,0x69,0x63, 0xf,0x69,0x64, + 0xf,0x69,0x65, 0xf,0x69,0x66, 0x7,0x58,0x5a, 0x7,0x58,0x5c, + 0x4,0x69,0x4b, 0x4,0x6a,0x67, 0x7,0x58,0x5f, 0x7,0x5c,0x3a, + 0x7,0x5c,0x3b, 0x4,0x6a,0x68, 0x4,0x6a,0x69, 0x4,0x6b,0x7a, + 0x5,0x77,0x78, 0x7,0x5f,0x37, 0x7,0x5f,0x35, 0xf,0x6b,0x5d, + 0x7,0x5f,0x36, 0x7,0x5f,0x38, 0x5,0x79,0x3a, 0x7,0x5f,0x34, + 0x5,0x79,0x39, 0x7,0x61,0x34, 0x7,0x62,0x4f, 0x7,0x62,0x4e, + 0x7,0x63,0x63, 0xf,0x6c,0x69, 0x7,0x63,0x65, 0x7,0x63,0x64, + 0x7,0x64,0x55, 0x5,0x7b,0x65, 0xf,0x6d,0x30, 0x7,0x65,0x75, + 0x6,0x25,0x42, 0x4,0x2a,0x78, 0x5,0x2b,0x28, 0x4,0x2f,0x28, + 0x6,0x3a,0x66, 0x5,0x2f,0x5b, 0x5,0x34,0x61, 0x6,0x43,0x2d, + 0x5,0x3b,0x34, 0x6,0x43,0x2f, 0x6,0x43,0x2e, 0x6,0x4c,0x74, + 0x4,0x3a,0x29, 0x6,0x4c,0x73, 0x5,0x3b,0x33, 0xf,0x3e,0x2f, + 0x6,0x56,0x50, 0x6,0x56,0x4f, 0x4,0x3f,0x74, 0x4,0x46,0x24, + 0x6,0x60,0x45, 0x5,0x48,0x58, 0x6,0x60,0x44, 0x7,0x26,0x6e, + 0xf,0x4b,0x39, 0xf,0x4b,0x3a, 0xf,0x4b,0x3b, 0x7,0x26,0x70, + 0x4,0x4c,0x47, 0xf,0x51,0x40, 0xf,0x51,0x41, 0x7,0x26,0x6f, + 0x5,0x56,0x7b, 0x5,0x56,0x7a, 0xf,0x57,0x22, 0xf,0x57,0x21, + 0x5,0x5d,0x49, 0x7,0x3a,0x45, 0x5,0x5d,0x48, 0xf,0x5a,0x58, + 0xf,0x5c,0x23, 0xf,0x5c,0x24, 0x7,0x41,0x5d, 0x7,0x41,0x5e, + 0xf,0x60,0x33, 0x7,0x48,0x68, 0x4,0x60,0x6c, 0xf,0x63,0x46, + 0x5,0x70,0x74, 0x4,0x64,0x27, 0x4,0x66,0x7a, 0x7,0x54,0x45, + 0x4,0x6a,0x6a, 0x7,0x5c,0x3c, 0xf,0x6a,0x6b, 0x7,0x5f,0x3a, + 0x7,0x5f,0x39, 0x5,0x7a,0x34, 0x7,0x66,0x2a, 0x6,0x22,0x29, + 0x6,0x22,0x28, 0x4,0x24,0x6a, 0x6,0x25,0x44, 0x6,0x25,0x45, + 0x6,0x28,0x73, 0xf,0x21,0x7c, 0x6,0x25,0x43, 0xf,0x25,0x28, + 0xf,0x25,0x2a, 0x6,0x2d,0x53, 0x6,0x33,0x6a, 0x4,0x27,0x5d, + 0x6,0x33,0x69, 0x6,0x2d,0x54, 0x4,0x27,0x5e, 0x6,0x28,0x74, + 0x4,0x24,0x6b, 0x6,0x33,0x6b, 0x4,0x2a,0x7a, 0x4,0x2a,0x7c, + 0xf,0x25,0x56, 0x5,0x2b,0x29, 0xf,0x28,0x49, 0x5,0x27,0x52, + 0x6,0x3a,0x67, 0x6,0x3a,0x68, 0x6,0x3a,0x69, 0x5,0x2f,0x5f, + 0x6,0x3a,0x6c, 0x6,0x3a,0x6a, 0x4,0x2f,0x2c, 0x4,0x2f,0x2b, + 0x6,0x33,0x6e, 0x6,0x33,0x6c, 0x6,0x33,0x6f, 0x6,0x43,0x35, + 0xf,0x29,0x39, 0x5,0x2f,0x5d, 0x6,0x43,0x30, 0x6,0x43,0x31, + 0x6,0x43,0x32, 0x6,0x43,0x34, 0x6,0x43,0x36, 0xf,0x31,0x79, + 0x6,0x33,0x6d, 0x6,0x36,0x7a, 0x5,0x2b,0x2a, 0x4,0x2a,0x7d, + 0x6,0x43,0x33, 0x6,0x4c,0x77, 0x6,0x43,0x37, 0x6,0x3a,0x6d, + 0x6,0x4c,0x76, 0x6,0x43,0x38, 0x5,0x2f,0x5e, 0x5,0x34,0x62, + 0xf,0x37,0x5c, 0x6,0x4c,0x75, 0x5,0x3b,0x36, 0x5,0x3b,0x35, + 0x4,0x3a,0x2c, 0x6,0x4c,0x78, 0xf,0x3e,0x30, 0x6,0x56,0x52, + 0x5,0x41,0x67, 0x6,0x56,0x54, 0x6,0x4c,0x7a, 0x5,0x41,0x64, + 0x5,0x41,0x66, 0x6,0x56,0x53, 0x6,0x56,0x55, 0x6,0x4c,0x79, + 0x6,0x56,0x56, 0xf,0x3e,0x31, 0x6,0x56,0x51, 0xf,0x44,0x63, + 0x6,0x60,0x46, 0x6,0x60,0x48, 0x6,0x60,0x49, 0x6,0x60,0x4a, + 0x6,0x60,0x4b, 0x6,0x60,0x4c, 0x6,0x60,0x4d, 0x6,0x60,0x50, + 0x5,0x48,0x5b, 0x7,0x26,0x75, 0x6,0x60,0x4e, 0x5,0x48,0x5a, + 0x6,0x56,0x57, 0x5,0x48,0x59, 0x6,0x60,0x4f, 0x6,0x60,0x47, + 0xf,0x4b,0x3c, 0x7,0x26,0x71, 0x7,0x26,0x72, 0x7,0x26,0x73, + 0x7,0x26,0x74, 0x5,0x4f,0x62, 0x5,0x4f,0x5f, 0x6,0x60,0x52, + 0x7,0x26,0x76, 0x5,0x4f,0x60, 0x5,0x4f,0x61, 0x6,0x60,0x51, + 0xf,0x51,0x42, 0xf,0x51,0x43, 0x7,0x25,0x73, 0x7,0x31,0x47, + 0x7,0x31,0x48, 0x7,0x31,0x4c, 0x7,0x31,0x49, 0x5,0x56,0x7c, + 0x7,0x31,0x4b, 0x4,0x52,0x51, 0x7,0x3a,0x4e, 0x7,0x31,0x4a, + 0x7,0x31,0x4d, 0x5,0x4f,0x63, 0x5,0x56,0x7d, 0x4,0x52,0x50, + 0x7,0x26,0x77, 0x7,0x26,0x78, 0x7,0x3a,0x47, 0x7,0x3a,0x48, + 0x7,0x3a,0x4b, 0x5,0x5d,0x4a, 0x7,0x31,0x4e, 0x4,0x57,0x74, + 0x5,0x63,0x5b, 0x7,0x3a,0x4c, 0x7,0x3a,0x4d, 0xf,0x5c,0x25, + 0xf,0x57,0x23, 0x7,0x41,0x5f, 0x7,0x41,0x60, 0x7,0x41,0x62, + 0x7,0x41,0x64, 0x4,0x5c,0x67, 0x4,0x5c,0x66, 0x5,0x63,0x5c, + 0x7,0x41,0x63, 0x7,0x48,0x69, 0x7,0x3a,0x4a, 0x5,0x63,0x5e, + 0x5,0x68,0x7b, 0x7,0x48,0x6c, 0x4,0x60,0x6e, 0x7,0x48,0x6a, + 0x7,0x48,0x6b, 0x7,0x4f,0x28, 0x7,0x4f,0x29, 0x7,0x4f,0x2a, + 0x7,0x4f,0x2b, 0x5,0x6d,0x25, 0x5,0x6d,0x27, 0x7,0x4f,0x2c, + 0x5,0x6d,0x26, 0x5,0x6d,0x28, 0x7,0x54,0x46, 0x7,0x4f,0x2d, + 0x5,0x77,0x7a, 0x4,0x6b,0x7c, 0x7,0x5f,0x3b, 0x5,0x77,0x7b, + 0x5,0x77,0x79, 0x7,0x61,0x35, 0x7,0x62,0x50, 0x7,0x63,0x66, + 0x7,0x64,0x56, 0x7,0x65,0x3c, 0x4,0x24,0x6c, 0x4,0x23,0x2c, + 0xf,0x21,0x60, 0x6,0x2d,0x56, 0x5,0x27,0x53, 0x6,0x2d,0x55, + 0xf,0x2d,0x24, 0x6,0x33,0x71, 0x6,0x33,0x70, 0x4,0x2a,0x7e, + 0xf,0x28,0x4b, 0x6,0x3a,0x6e, 0x6,0x3a,0x6f, 0x6,0x43,0x3b, + 0x6,0x3a,0x73, 0x6,0x3a,0x72, 0x6,0x3a,0x71, 0x6,0x3a,0x70, + 0x6,0x43,0x3a, 0xf,0x31,0x7a, 0xf,0x31,0x7b, 0x6,0x43,0x3d, + 0x5,0x34,0x64, 0x4,0x3a,0x2e, 0x6,0x43,0x3e, 0x4,0x34,0x39, + 0x5,0x34,0x65, 0xf,0x37,0x5d, 0x5,0x34,0x63, 0x6,0x43,0x39, + 0xf,0x37,0x5e, 0xf,0x37,0x5f, 0x6,0x43,0x3f, 0x5,0x3b,0x39, + 0x5,0x3b,0x37, 0x6,0x4c,0x7d, 0x4,0x3a,0x2f, 0x6,0x4d,0x21, + 0x5,0x3b,0x38, 0x6,0x4c,0x7e, 0x6,0x4c,0x7c, 0x6,0x4d,0x22, + 0x6,0x47,0x21, 0x6,0x56,0x5a, 0x5,0x41,0x68, 0x6,0x56,0x5b, + 0x6,0x56,0x58, 0x5,0x41,0x69, 0x6,0x56,0x59, 0x6,0x56,0x5c, + 0x5,0x41,0x6a, 0xf,0x3e,0x33, 0xf,0x3e,0x34, 0x5,0x48,0x5c, + 0x6,0x60,0x53, 0x6,0x60,0x55, 0x5,0x48,0x5d, 0x6,0x60,0x54, + 0x5,0x4f,0x64, 0x4,0x4c,0x4a, 0x7,0x26,0x7b, 0x7,0x26,0x7c, + 0x4,0x4c,0x4b, 0x7,0x31,0x4f, 0x7,0x26,0x7a, 0x4,0x4c,0x48, + 0x5,0x57,0x21, 0x5,0x56,0x7e, 0x4,0x52,0x52, 0xf,0x57,0x25, + 0x7,0x31,0x50, 0x4,0x57,0x78, 0x4,0x57,0x76, 0x5,0x5d,0x4b, + 0x7,0x3a,0x50, 0x7,0x3a,0x4f, 0x7,0x3a,0x52, 0xf,0x5c,0x26, + 0x4,0x52,0x54, 0x7,0x3a,0x51, 0x5,0x63,0x5d, 0x4,0x5c,0x69, + 0x5,0x63,0x5f, 0x7,0x41,0x69, 0x7,0x41,0x6a, 0x4,0x5c,0x6d, + 0x7,0x41,0x67, 0x7,0x41,0x68, 0x7,0x41,0x66, 0xf,0x57,0x24, + 0xf,0x60,0x34, 0xf,0x60,0x35, 0x4,0x5c,0x6c, 0x5,0x68,0x7c, + 0x7,0x48,0x70, 0x5,0x76,0x3b, 0x7,0x48,0x6f, 0x7,0x4f,0x2e, + 0x7,0x48,0x6e, 0x5,0x6d,0x29, 0x7,0x4f,0x2f, 0x7,0x4f,0x30, + 0x7,0x4f,0x31, 0x7,0x4f,0x32, 0x7,0x41,0x65, 0x5,0x70,0x75, + 0x7,0x54,0x47, 0x7,0x54,0x48, 0x5,0x73,0x7d, 0x7,0x58,0x60, + 0x7,0x5c,0x3e, 0x7,0x5c,0x3d, 0x7,0x61,0x36, 0x7,0x63,0x67, + 0x7,0x65,0x5e, 0x6,0x2d,0x57, 0x6,0x33,0x75, 0x6,0x33,0x72, + 0x6,0x33,0x76, 0x5,0x2b,0x2b, 0x4,0x2b,0x22, 0x4,0x2b,0x21, + 0x4,0x2b,0x24, 0x6,0x33,0x74, 0x4,0x2b,0x23, 0xf,0x2d,0x25, + 0xf,0x2d,0x26, 0x6,0x33,0x73, 0x4,0x2f,0x33, 0x6,0x3a,0x76, + 0x5,0x2f,0x61, 0x5,0x2f,0x63, 0x5,0x2f,0x60, 0x4,0x2f,0x31, + 0x4,0x2f,0x36, 0x4,0x2f,0x35, 0x6,0x3a,0x75, 0x5,0x2f,0x62, + 0x4,0x2f,0x34, 0x4,0x2f,0x32, 0x6,0x3a,0x77, 0xf,0x2f,0x63, + 0xf,0x2f,0x64, 0x4,0x2f,0x37, 0xf,0x31,0x7c, 0x5,0x34,0x66, + 0x6,0x43,0x41, 0x6,0x43,0x40, 0x6,0x43,0x42, 0x6,0x43,0x43, + 0x6,0x43,0x44, 0x6,0x43,0x46, 0x6,0x43,0x47, 0x4,0x34,0x3f, + 0x6,0x43,0x45, 0x5,0x3b,0x3b, 0x4,0x3a,0x32, 0x6,0x4d,0x26, + 0x6,0x4d,0x27, 0x6,0x4d,0x2d, 0x5,0x3b,0x3d, 0x4,0x3a,0x36, + 0x6,0x4d,0x2e, 0x6,0x4d,0x28, 0x6,0x4d,0x25, 0x6,0x4d,0x2f, + 0x6,0x4d,0x30, 0x5,0x3b,0x3c, 0x6,0x4d,0x2a, 0x6,0x4d,0x2c, + 0x6,0x4d,0x2b, 0xf,0x3e,0x35, 0xf,0x3e,0x36, 0x6,0x4d,0x29, + 0x5,0x41,0x6e, 0x5,0x41,0x6b, 0x4,0x3f,0x79, 0x6,0x56,0x5d, + 0x6,0x56,0x5e, 0x6,0x56,0x5f, 0x5,0x41,0x6d, 0x5,0x41,0x6c, + 0xf,0x44,0x64, 0x6,0x4d,0x24, 0x5,0x48,0x65, 0x5,0x48,0x5e, + 0x6,0x60,0x57, 0x5,0x48,0x5f, 0x5,0x48,0x63, 0x5,0x48,0x60, + 0x5,0x48,0x64, 0x5,0x48,0x61, 0x5,0x48,0x62, 0x6,0x60,0x56, + 0x5,0x48,0x66, 0xf,0x4b,0x3d, 0xf,0x4b,0x3e, 0xf,0x4b,0x3f, + 0xf,0x4b,0x40, 0x5,0x4f,0x6a, 0x5,0x4f,0x6b, 0x7,0x26,0x7e, + 0x5,0x4f,0x68, 0x4,0x4c,0x4c, 0x5,0x4f,0x6c, 0x5,0x4f,0x65, + 0x7,0x26,0x7d, 0x5,0x4f,0x67, 0xf,0x51,0x46, 0x6,0x60,0x59, + 0x5,0x4f,0x66, 0x7,0x27,0x24, 0x7,0x27,0x25, 0x7,0x27,0x21, + 0x4,0x4c,0x4e, 0x7,0x27,0x22, 0x4,0x4c,0x4d, 0x7,0x27,0x23, + 0xf,0x51,0x44, 0xf,0x51,0x45, 0x7,0x31,0x51, 0x7,0x31,0x53, + 0x5,0x57,0x25, 0x7,0x31,0x56, 0x7,0x31,0x52, 0x7,0x31,0x54, + 0x4,0x52,0x57, 0x5,0x57,0x23, 0x5,0x57,0x26, 0x5,0x57,0x24, + 0x5,0x4f,0x69, 0x5,0x57,0x22, 0x7,0x31,0x55, 0x5,0x57,0x27, + 0xf,0x57,0x26, 0x4,0x57,0x79, 0x7,0x3a,0x54, 0x5,0x5d,0x4c, + 0x7,0x3a,0x55, 0x7,0x48,0x71, 0x5,0x5d,0x4d, 0x7,0x3a,0x53, + 0xf,0x5c,0x27, 0xf,0x5c,0x28, 0x5,0x63,0x60, 0x4,0x5c,0x6e, + 0x7,0x41,0x71, 0x5,0x5d,0x4e, 0x4,0x5c,0x6f, 0x7,0x41,0x6d, + 0x7,0x41,0x6f, 0x7,0x41,0x6c, 0x7,0x41,0x70, 0x7,0x41,0x6e, + 0xf,0x60,0x36, 0xf,0x60,0x37, 0x7,0x41,0x6b, 0x4,0x60,0x70, + 0x5,0x68,0x7e, 0x5,0x68,0x7d, 0x7,0x48,0x72, 0x7,0x4f,0x35, + 0x7,0x4f,0x36, 0xf,0x65,0x72, 0x7,0x4f,0x33, 0x4,0x66,0x7c, + 0x7,0x54,0x49, 0x7,0x54,0x4b, 0x7,0x4f,0x34, 0x7,0x54,0x4a, + 0x7,0x58,0x62, 0x7,0x58,0x63, 0x7,0x58,0x61, 0x6,0x25,0x46, + 0x6,0x2d,0x58, 0x6,0x28,0x75, 0x4,0x27,0x5f, 0x4,0x27,0x60, + 0x6,0x3a,0x78, 0x4,0x34,0x40, 0x5,0x2b,0x2c, 0xf,0x37,0x60, + 0xf,0x37,0x61, 0x6,0x43,0x48, 0x6,0x4d,0x31, 0x7,0x27,0x26, + 0x7,0x31,0x58, 0x7,0x31,0x57, 0xf,0x6b,0x5e, 0x6,0x2d,0x59, + 0x6,0x2d,0x5a, 0x5,0x21,0x79, 0xf,0x28,0x4c, 0x4,0x2f,0x39, + 0x5,0x34,0x67, 0x5,0x3b,0x3e, 0x5,0x41,0x6f, 0x6,0x60,0x5a, + 0x7,0x27,0x27, 0x7,0x27,0x29, 0x5,0x48,0x67, 0x7,0x31,0x5a, + 0x7,0x31,0x59, 0x7,0x3a,0x56, 0x5,0x23,0x21, 0x6,0x2d,0x5b, + 0xf,0x28,0x4d, 0x6,0x33,0x77, 0xf,0x2d,0x27, 0x6,0x33,0x78, + 0xf,0x31,0x7e, 0x5,0x34,0x68, 0xf,0x37,0x62, 0x6,0x43,0x49, + 0x4,0x3a,0x37, 0x5,0x3b,0x41, 0x5,0x3b,0x40, 0x4,0x3f,0x7b, + 0x6,0x56,0x60, 0x6,0x60,0x5c, 0x5,0x48,0x6c, 0x5,0x48,0x68, + 0x5,0x48,0x6d, 0x5,0x48,0x6a, 0x5,0x48,0x69, 0x5,0x48,0x6b, + 0x4,0x46,0x31, 0xf,0x44,0x65, 0x6,0x60,0x5b, 0x5,0x4f,0x6f, + 0x5,0x4f,0x70, 0x5,0x4f,0x71, 0x5,0x4f,0x6d, 0x5,0x4f,0x6e, + 0x7,0x27,0x2a, 0x5,0x57,0x29, 0x5,0x57,0x28, 0x4,0x52,0x58, + 0x4,0x52,0x59, 0x7,0x31,0x5c, 0x7,0x31,0x5d, 0x7,0x31,0x5b, + 0xf,0x51,0x47, 0x5,0x5d,0x4f, 0x4,0x57,0x7c, 0x7,0x3a,0x5a, + 0x7,0x3a,0x57, 0x7,0x3a,0x58, 0xf,0x57,0x29, 0x5,0x63,0x61, + 0x4,0x57,0x7e, 0x7,0x41,0x72, 0x7,0x3a,0x59, 0x7,0x48,0x75, + 0x5,0x63,0x62, 0x7,0x41,0x74, 0x7,0x41,0x73, 0xf,0x5c,0x29, + 0xf,0x5c,0x2a, 0x7,0x48,0x74, 0x5,0x69,0x21, 0x7,0x48,0x73, + 0x4,0x66,0x7e, 0x7,0x54,0x4c, 0x4,0x6a,0x6c, 0x5,0x77,0x7c, + 0x5,0x79,0x3b, 0x5,0x27,0x55, 0x5,0x27,0x54, 0x6,0x2d,0x5e, + 0xf,0x28,0x4e, 0xf,0x28,0x4f, 0x6,0x2d,0x5d, 0x5,0x2b,0x2f, + 0x5,0x2b,0x2d, 0x5,0x2b,0x2e, 0x4,0x2f,0x3c, 0x6,0x3a,0x7e, + 0x4,0x2f,0x3b, 0x6,0x3a,0x7a, 0x5,0x2f,0x64, 0x6,0x3b,0x22, + 0xf,0x32,0x21, 0xf,0x32,0x24, 0xf,0x32,0x26, 0xf,0x32,0x27, + 0x6,0x3a,0x7b, 0xf,0x32,0x22, 0x6,0x3a,0x7d, 0x6,0x3a,0x7c, + 0x6,0x3b,0x23, 0x6,0x3a,0x79, 0xf,0x32,0x25, 0x5,0x2f,0x65, + 0x6,0x43,0x4b, 0x4,0x34,0x43, 0x4,0x34,0x42, 0x4,0x34,0x44, + 0x6,0x43,0x4d, 0x5,0x34,0x69, 0x6,0x43,0x4f, 0x6,0x43,0x4e, + 0x6,0x43,0x4c, 0x6,0x43,0x4a, 0xf,0x37,0x63, 0xf,0x37,0x64, + 0xf,0x37,0x65, 0xf,0x37,0x66, 0x5,0x3b,0x42, 0x6,0x4d,0x33, + 0x6,0x4d,0x34, 0x5,0x3b,0x43, 0x6,0x4d,0x35, 0xf,0x3e,0x37, + 0xf,0x3e,0x38, 0xf,0x3e,0x39, 0xf,0x3e,0x3a, 0xf,0x3e,0x3c, + 0xf,0x3e,0x3d, 0xf,0x3e,0x3e, 0xf,0x3e,0x3f, 0xf,0x3e,0x40, + 0x6,0x4d,0x32, 0xf,0x3e,0x3b, 0x6,0x56,0x62, 0x6,0x56,0x66, + 0x5,0x41,0x71, 0x5,0x41,0x72, 0x6,0x56,0x61, 0x6,0x56,0x6b, + 0x6,0x56,0x69, 0x6,0x56,0x67, 0x5,0x41,0x73, 0x6,0x56,0x68, + 0x6,0x56,0x64, 0x6,0x56,0x6a, 0x6,0x56,0x63, 0xf,0x44,0x66, + 0xf,0x44,0x67, 0x6,0x56,0x65, 0x5,0x48,0x70, 0x5,0x48,0x71, + 0x5,0x48,0x6e, 0x4,0x4c,0x50, 0x6,0x60,0x5e, 0x5,0x48,0x72, + 0x5,0x48,0x6f, 0x5,0x48,0x73, 0xf,0x4b,0x41, 0xf,0x4b,0x42, + 0xf,0x4b,0x43, 0xf,0x4b,0x44, 0xf,0x4b,0x45, 0xf,0x4b,0x46, + 0xf,0x4b,0x47, 0xf,0x4b,0x48, 0xf,0x4b,0x4a, 0xf,0x4b,0x4b, + 0xf,0x4b,0x4c, 0x6,0x60,0x5f, 0x5,0x4f,0x72, 0x7,0x27,0x2c, + 0x5,0x4f,0x75, 0x7,0x27,0x2f, 0x5,0x4f,0x74, 0x5,0x4f,0x73, + 0x4,0x4c,0x51, 0x5,0x4f,0x77, 0x7,0x27,0x2b, 0x7,0x27,0x30, + 0x5,0x4f,0x76, 0xf,0x51,0x48, 0xf,0x51,0x49, 0xf,0x51,0x4a, + 0xf,0x51,0x4b, 0xf,0x51,0x4c, 0xf,0x51,0x4d, 0xf,0x51,0x4e, + 0xf,0x51,0x4f, 0x7,0x27,0x2d, 0x5,0x57,0x2c, 0x5,0x57,0x2f, + 0x5,0x57,0x2b, 0x5,0x57,0x2d, 0x5,0x57,0x2e, 0x7,0x31,0x61, + 0x7,0x31,0x5f, 0x7,0x31,0x5e, 0xf,0x57,0x2a, 0xf,0x57,0x2b, + 0xf,0x57,0x2c, 0xf,0x57,0x2d, 0xf,0x57,0x2e, 0xf,0x57,0x2f, + 0x7,0x31,0x60, 0x5,0x57,0x2a, 0x5,0x5d,0x50, 0x5,0x5d,0x51, + 0x5,0x5d,0x52, 0x7,0x3a,0x5b, 0x4,0x58,0x25, 0x4,0x58,0x26, + 0x5,0x5d,0x54, 0x5,0x5d,0x53, 0xf,0x5c,0x2c, 0x7,0x3a,0x5d, + 0x7,0x3a,0x5c, 0x3,0x58,0x63, 0x7,0x41,0x77, 0x5,0x63,0x66, + 0x5,0x63,0x63, 0x4,0x5c,0x72, 0x7,0x41,0x79, 0x5,0x5d,0x55, + 0x7,0x41,0x78, 0x5,0x63,0x64, 0x5,0x63,0x65, 0x7,0x41,0x75, + 0xf,0x60,0x38, 0xf,0x60,0x39, 0xf,0x60,0x3a, 0x7,0x41,0x76, + 0xf,0x5c,0x2b, 0xf,0x63,0x47, 0x7,0x48,0x76, 0x5,0x69,0x22, + 0x5,0x69,0x23, 0x7,0x48,0x78, 0x7,0x48,0x77, 0xf,0x63,0x48, + 0xf,0x63,0x49, 0x7,0x4f,0x39, 0xf,0x65,0x73, 0xf,0x65,0x74, + 0xf,0x65,0x75, 0x7,0x4f,0x38, 0x7,0x4f,0x37, 0x5,0x70,0x76, + 0xf,0x68,0x30, 0xf,0x68,0x31, 0x7,0x54,0x4d, 0x7,0x54,0x4e, + 0x5,0x73,0x7e, 0x7,0x58,0x64, 0x4,0x6a,0x6d, 0xf,0x6a,0x6c, + 0xf,0x6b,0x5f, 0xf,0x6c,0x36, 0xf,0x6c,0x50, 0x5,0x21,0x7a, + 0x6,0x2d,0x5f, 0x5,0x2b,0x30, 0x6,0x43,0x50, 0x6,0x4d,0x36, + 0x6,0x48,0x6a, 0x6,0x56,0x6e, 0x6,0x60,0x62, 0x6,0x60,0x61, + 0x7,0x27,0x31, 0xf,0x51,0x50, 0x7,0x31,0x62, 0x7,0x4f,0x3a, + 0x5,0x23,0x25, 0x5,0x23,0x23, 0x6,0x2d,0x60, 0x6,0x2d,0x61, + 0x6,0x25,0x48, 0xf,0x22,0x6c, 0xf,0x22,0x6d, 0x5,0x23,0x24, + 0x5,0x23,0x22, 0x5,0x24,0x73, 0x5,0x24,0x72, 0x6,0x28,0x79, + 0x6,0x28,0x78, 0x6,0x28,0x77, 0x6,0x28,0x76, 0x6,0x33,0x7b, + 0x6,0x33,0x7a, 0x6,0x33,0x79, 0x5,0x27,0x5a, 0x5,0x27,0x5e, + 0x6,0x2d,0x64, 0x4,0x2f,0x43, 0x6,0x2d,0x6d, 0x6,0x2d,0x6e, + 0x6,0x2d,0x62, 0x5,0x27,0x5d, 0x6,0x2d,0x66, 0x5,0x27,0x59, + 0x5,0x27,0x57, 0x6,0x2d,0x6b, 0x5,0x27,0x5b, 0x4,0x27,0x6b, + 0x6,0x2d,0x68, 0x6,0x2d,0x6f, 0xf,0x28,0x50, 0xf,0x28,0x51, + 0xf,0x28,0x53, 0xf,0x28,0x54, 0x6,0x2d,0x6c, 0x4,0x26,0x64, + 0x6,0x2d,0x65, 0x6,0x2d,0x67, 0x5,0x27,0x5c, 0x6,0x2d,0x6a, + 0x6,0x2d,0x63, 0x6,0x3b,0x27, 0x6,0x3b,0x25, 0x4,0x2f,0x3d, + 0x5,0x27,0x56, 0x6,0x3b,0x26, 0x6,0x34,0x2d, 0x4,0x2b,0x2d, + 0x5,0x2b,0x34, 0x6,0x34,0x28, 0x5,0x2b,0x31, 0x5,0x2b,0x38, + 0x6,0x34,0x29, 0x4,0x2b,0x2e, 0x6,0x43,0x54, 0x6,0x34,0x27, + 0x4,0x2b,0x2b, 0x6,0x34,0x2b, 0x4,0x2b,0x30, 0x6,0x34,0x25, + 0x5,0x2b,0x36, 0x6,0x34,0x26, 0x5,0x2b,0x37, 0x5,0x2b,0x32, + 0x4,0x2f,0x48, 0x5,0x2b,0x35, 0x6,0x33,0x7c, 0x6,0x34,0x21, + 0x6,0x34,0x22, 0x6,0x34,0x24, 0xf,0x2d,0x2a, 0xf,0x2d,0x2f, + 0xf,0x37,0x67, 0xf,0x37,0x68, 0x6,0x33,0x7e, 0x6,0x34,0x2f, + 0x6,0x34,0x2c, 0x6,0x34,0x2a, 0x6,0x34,0x30, 0x6,0x34,0x2e, + 0x6,0x43,0x53, 0x6,0x43,0x52, 0xf,0x2d,0x2b, 0x6,0x43,0x55, + 0x6,0x43,0x56, 0x6,0x3b,0x30, 0x6,0x43,0x51, 0xf,0x2d,0x2d, + 0x5,0x2f,0x67, 0x4,0x2f,0x3e, 0x4,0x34,0x45, 0x4,0x2f,0x45, + 0x6,0x3b,0x32, 0x5,0x2f,0x6c, 0x4,0x2f,0x44, 0x6,0x3b,0x2e, + 0x5,0x2f,0x6e, 0x6,0x3b,0x2a, 0x5,0x2f,0x70, 0x5,0x3b,0x44, + 0x5,0x2f,0x6f, 0x6,0x3b,0x29, 0x5,0x2f,0x66, 0x6,0x3b,0x2b, + 0x4,0x2f,0x40, 0x6,0x4d,0x3b, 0x5,0x2f,0x69, 0xf,0x2d,0x29, + 0xf,0x32,0x28, 0xf,0x32,0x29, 0xf,0x32,0x2d, 0xf,0x3e,0x4c, + 0x5,0x2f,0x68, 0x5,0x2e,0x24, 0x6,0x3b,0x2f, 0x6,0x3b,0x2d, + 0x6,0x3b,0x2c, 0x6,0x3b,0x33, 0x6,0x4d,0x3a, 0x6,0x4d,0x38, + 0x6,0x4d,0x39, 0x6,0x4d,0x37, 0x6,0x34,0x23, 0x5,0x2f,0x6b, + 0x5,0x2f,0x71, 0x5,0x2f,0x6a, 0x5,0x34,0x74, 0x6,0x43,0x5b, + 0x6,0x43,0x59, 0x5,0x34,0x6b, 0x4,0x34,0x4e, 0x5,0x34,0x6c, + 0x4,0x2f,0x42, 0x5,0x34,0x71, 0x4,0x34,0x46, 0x4,0x34,0x55, + 0x5,0x41,0x74, 0x4,0x34,0x54, 0x6,0x43,0x57, 0x5,0x34,0x6e, + 0x6,0x43,0x5f, 0x4,0x34,0x49, 0x5,0x34,0x75, 0x5,0x34,0x76, + 0x6,0x43,0x60, 0x6,0x43,0x5e, 0x4,0x34,0x4f, 0x5,0x34,0x72, + 0x6,0x43,0x61, 0x6,0x43,0x62, 0xf,0x37,0x69, 0xf,0x37,0x6b, + 0x6,0x43,0x5c, 0x6,0x43,0x5d, 0x6,0x56,0x6f, 0x6,0x56,0x70, + 0x6,0x56,0x71, 0x5,0x34,0x73, 0x5,0x34,0x6f, 0x5,0x34,0x70, + 0x6,0x4d,0x43, 0x5,0x3b,0x48, 0x6,0x4d,0x3d, 0x5,0x3b,0x45, + 0x6,0x4d,0x4b, 0x6,0x4d,0x42, 0x4,0x3a,0x3c, 0x5,0x3b,0x4a, + 0x6,0x4d,0x4f, 0x6,0x4d,0x3c, 0x6,0x60,0x65, 0x5,0x3b,0x47, + 0x6,0x4d,0x50, 0x6,0x56,0x75, 0x4,0x3a,0x48, 0x5,0x3b,0x4c, + 0x6,0x4d,0x55, 0x6,0x4d,0x4e, 0x6,0x4d,0x4c, 0x6,0x4d,0x53, + 0x5,0x3b,0x46, 0x5,0x48,0x75, 0x6,0x4d,0x3e, 0x6,0x4d,0x47, + 0x6,0x4d,0x4a, 0xf,0x3e,0x41, 0xf,0x3e,0x44, 0xf,0x3e,0x46, + 0xf,0x3e,0x47, 0xf,0x3e,0x48, 0xf,0x3e,0x49, 0xf,0x3e,0x4a, + 0xf,0x3e,0x4b, 0x6,0x4d,0x44, 0x6,0x4d,0x49, 0xf,0x3b,0x63, + 0x6,0x4d,0x4d, 0x6,0x4d,0x41, 0x6,0x4d,0x52, 0x6,0x4d,0x3f, + 0x6,0x4d,0x40, 0x6,0x60,0x63, 0x6,0x60,0x67, 0x6,0x60,0x64, + 0xf,0x3e,0x45, 0x5,0x3b,0x49, 0x6,0x4d,0x46, 0x5,0x34,0x6d, + 0x5,0x3b,0x4b, 0x5,0x3b,0x4e, 0x5,0x3b,0x4f, 0x6,0x4d,0x51, + 0x5,0x3b,0x51, 0x6,0x4d,0x45, 0x6,0x60,0x68, 0x6,0x60,0x66, + 0x5,0x41,0x7d, 0x4,0x40,0x21, 0x5,0x42,0x26, 0x5,0x42,0x21, + 0x5,0x41,0x75, 0x5,0x41,0x79, 0x5,0x42,0x27, 0x6,0x56,0x7d, + 0x4,0x3f,0x7e, 0x6,0x56,0x72, 0x4,0x3a,0x46, 0x5,0x42,0x22, + 0x5,0x41,0x78, 0x6,0x56,0x77, 0x4,0x40,0x24, 0x6,0x56,0x79, + 0x4,0x40,0x22, 0x6,0x57,0x21, 0x6,0x56,0x73, 0x5,0x42,0x29, + 0x6,0x56,0x74, 0x6,0x56,0x78, 0x5,0x42,0x23, 0x6,0x56,0x7c, + 0x5,0x41,0x7b, 0x5,0x41,0x7a, 0x5,0x42,0x25, 0x5,0x42,0x24, + 0x6,0x56,0x7a, 0x5,0x41,0x76, 0x6,0x56,0x7e, 0xf,0x44,0x69, + 0xf,0x44,0x6a, 0xf,0x44,0x6b, 0xf,0x44,0x6c, 0xf,0x44,0x6d, + 0xf,0x44,0x6f, 0xf,0x44,0x71, 0x4,0x40,0x2b, 0x6,0x57,0x23, + 0x6,0x57,0x22, 0xf,0x44,0x70, 0x7,0x27,0x32, 0x7,0x27,0x33, + 0x6,0x56,0x7b, 0x5,0x41,0x7e, 0x5,0x41,0x7c, 0x4,0x46,0x44, + 0x5,0x48,0x7b, 0x4,0x46,0x4c, 0x4,0x46,0x43, 0x5,0x49,0x23, + 0x6,0x60,0x6a, 0x5,0x48,0x7a, 0x4,0x46,0x4a, 0x5,0x49,0x24, + 0x5,0x49,0x21, 0x4,0x46,0x49, 0x5,0x48,0x77, 0x5,0x48,0x7d, + 0x4,0x46,0x3a, 0x4,0x46,0x4b, 0x5,0x48,0x78, 0x6,0x60,0x71, + 0x6,0x60,0x6c, 0x5,0x48,0x76, 0x6,0x60,0x6e, 0x5,0x48,0x79, + 0x6,0x60,0x6d, 0x5,0x48,0x7c, 0x7,0x31,0x63, 0x5,0x49,0x22, + 0x4,0x46,0x48, 0x6,0x60,0x6b, 0xf,0x4b,0x4d, 0xf,0x4b,0x4e, + 0xf,0x4b,0x4f, 0xf,0x4b,0x51, 0xf,0x4b,0x52, 0xf,0x4b,0x55, + 0xf,0x4b,0x53, 0x6,0x60,0x70, 0x6,0x5d,0x5c, 0x5,0x41,0x77, + 0x5,0x48,0x7e, 0x4,0x4c,0x53, 0x5,0x4f,0x7b, 0x7,0x27,0x34, + 0x4,0x4c,0x57, 0x7,0x27,0x3b, 0x5,0x4f,0x7a, 0x4,0x4c,0x59, + 0x7,0x3a,0x60, 0x7,0x27,0x37, 0x5,0x4f,0x7c, 0x7,0x27,0x35, + 0x4,0x4c,0x5a, 0x7,0x3a,0x5e, 0x5,0x4f,0x78, 0x7,0x27,0x38, + 0xf,0x51,0x51, 0xf,0x51,0x52, 0xf,0x51,0x53, 0xf,0x51,0x54, + 0x7,0x27,0x36, 0x7,0x27,0x39, 0x7,0x27,0x3a, 0x7,0x3a,0x5f, + 0x6,0x60,0x69, 0x5,0x4f,0x79, 0xf,0x5c,0x35, 0x7,0x31,0x6c, + 0x5,0x57,0x37, 0x5,0x57,0x32, 0x4,0x52,0x68, 0x4,0x52,0x5d, + 0x5,0x57,0x31, 0x4,0x52,0x5f, 0x7,0x31,0x67, 0x7,0x31,0x6e, + 0x5,0x57,0x35, 0x5,0x57,0x36, 0x4,0x52,0x65, 0x5,0x4f,0x7d, + 0x5,0x57,0x34, 0x7,0x31,0x65, 0x7,0x31,0x6d, 0x5,0x57,0x39, + 0x7,0x31,0x6a, 0x5,0x69,0x24, 0x4,0x52,0x60, 0x7,0x31,0x6f, + 0xf,0x57,0x31, 0xf,0x57,0x33, 0xf,0x57,0x32, 0x7,0x27,0x3c, + 0x7,0x31,0x68, 0x7,0x31,0x69, 0x7,0x31,0x64, 0x7,0x31,0x66, + 0x7,0x31,0x6b, 0x7,0x41,0x7a, 0x7,0x48,0x79, 0x7,0x41,0x7b, + 0x5,0x57,0x3a, 0x5,0x57,0x30, 0x5,0x57,0x3b, 0x5,0x57,0x38, + 0x5,0x57,0x33, 0x7,0x42,0x21, 0x5,0x5d,0x5a, 0x5,0x5d,0x59, + 0x7,0x3a,0x62, 0x4,0x58,0x2e, 0x4,0x58,0x2a, 0x4,0x58,0x29, + 0x5,0x5d,0x58, 0x5,0x5d,0x56, 0x4,0x60,0x71, 0x7,0x48,0x7b, + 0x5,0x5d,0x5e, 0x7,0x3a,0x65, 0xf,0x5c,0x2e, 0xf,0x5c,0x2f, + 0xf,0x5c,0x31, 0xf,0x5c,0x32, 0xf,0x5c,0x33, 0xf,0x5c,0x34, + 0xf,0x5c,0x36, 0xf,0x5c,0x30, 0x7,0x37,0x7e, 0x7,0x3a,0x63, + 0x7,0x48,0x7a, 0x7,0x48,0x7d, 0x5,0x5d,0x5d, 0x7,0x3a,0x61, + 0x5,0x5d,0x5c, 0x5,0x5d,0x57, 0x7,0x3a,0x64, 0x7,0x48,0x7e, + 0x4,0x5c,0x75, 0x5,0x63,0x6a, 0x5,0x63,0x67, 0x5,0x63,0x69, + 0x5,0x63,0x6c, 0x7,0x41,0x7c, 0x5,0x63,0x6e, 0x7,0x41,0x7e, + 0x5,0x63,0x6b, 0x7,0x42,0x23, 0x5,0x63,0x68, 0x5,0x6d,0x2a, + 0x5,0x63,0x6f, 0xf,0x60,0x3b, 0xf,0x60,0x3c, 0xf,0x60,0x3d, + 0xf,0x60,0x40, 0xf,0x60,0x41, 0x7,0x41,0x7d, 0x7,0x42,0x6d, + 0x4,0x5c,0x73, 0x4,0x60,0x72, 0x7,0x49,0x23, 0x7,0x49,0x29, + 0x5,0x69,0x25, 0x5,0x69,0x26, 0x5,0x63,0x6d, 0x7,0x49,0x24, + 0xf,0x63,0x4a, 0x7,0x49,0x28, 0x7,0x49,0x2a, 0xf,0x63,0x4c, + 0xf,0x63,0x4d, 0x7,0x49,0x22, 0x7,0x49,0x26, 0x7,0x49,0x25, + 0x7,0x49,0x27, 0x7,0x49,0x21, 0xf,0x63,0x4b, 0x7,0x49,0x2b, + 0x7,0x4f,0x3d, 0x5,0x6d,0x2e, 0x5,0x6d,0x2d, 0x4,0x64,0x2b, + 0x4,0x64,0x29, 0x5,0x6d,0x2b, 0xf,0x65,0x76, 0x7,0x4f,0x3c, + 0x7,0x4f,0x3b, 0x4,0x67,0x26, 0x7,0x54,0x4f, 0x5,0x70,0x77, + 0x7,0x5c,0x40, 0x7,0x55,0x3a, 0x7,0x5c,0x3f, 0x4,0x69,0x31, + 0x4,0x69,0x2f, 0x7,0x58,0x65, 0xf,0x68,0x33, 0x7,0x5c,0x41, + 0x5,0x76,0x3d, 0x7,0x5c,0x43, 0x7,0x5c,0x45, 0x7,0x5c,0x46, + 0x5,0x76,0x3c, 0x7,0x5c,0x42, 0x4,0x6a,0x6e, 0x7,0x5c,0x47, + 0x7,0x5c,0x48, 0x7,0x5f,0x3d, 0x5,0x77,0x7d, 0x7,0x5f,0x3e, + 0x5,0x79,0x3c, 0x7,0x64,0x57, 0x5,0x7a,0x6f, 0x5,0x7b,0x45, + 0x6,0x28,0x7c, 0x4,0x24,0x71, 0xf,0x2a,0x49, 0x6,0x3b,0x34, + 0xf,0x32,0x2f, 0x6,0x4d,0x56, 0x6,0x4d,0x57, 0xf,0x4b,0x58, + 0xf,0x4b,0x59, 0xf,0x51,0x56, 0x6,0x60,0x73, 0xf,0x5c,0x37, + 0x7,0x42,0x25, 0xf,0x60,0x42, 0x5,0x70,0x79, 0xf,0x68,0x34, + 0xf,0x69,0x67, 0x7,0x65,0x3d, 0x5,0x7c,0x2c, 0x6,0x25,0x4a, + 0x6,0x28,0x7e, 0x4,0x24,0x72, 0x6,0x28,0x7d, 0x6,0x2d,0x70, + 0x5,0x2b,0x3a, 0x6,0x34,0x32, 0xf,0x2d,0x30, 0x5,0x2f,0x72, + 0x6,0x3b,0x36, 0x4,0x2f,0x49, 0xf,0x32,0x30, 0x6,0x3b,0x37, + 0x6,0x3b,0x35, 0x6,0x43,0x66, 0x6,0x43,0x65, 0xf,0x37,0x6d, + 0xf,0x37,0x6e, 0x6,0x4d,0x59, 0x6,0x4d,0x5a, 0x6,0x57,0x24, + 0x5,0x49,0x25, 0xf,0x4b,0x5a, 0x4,0x4c,0x60, 0x4,0x4c,0x61, + 0x5,0x4f,0x7e, 0xf,0x51,0x57, 0x7,0x27,0x3d, 0x4,0x52,0x69, + 0x5,0x57,0x3c, 0x7,0x3a,0x66, 0x5,0x5d,0x60, 0x5,0x5d,0x5f, + 0xf,0x5c,0x38, 0xf,0x60,0x43, 0x5,0x69,0x27, 0x4,0x60,0x75, + 0x5,0x6d,0x31, 0xf,0x63,0x4e, 0x7,0x49,0x2c, 0x5,0x6d,0x2f, + 0x5,0x6d,0x30, 0x7,0x62,0x51, 0x6,0x29,0x21, 0x6,0x2d,0x71, + 0x6,0x2d,0x72, 0x6,0x3b,0x3a, 0xf,0x2d,0x31, 0x6,0x3b,0x38, + 0x6,0x3b,0x39, 0x5,0x34,0x77, 0x4,0x34,0x56, 0x6,0x4d,0x5b, + 0x5,0x42,0x2a, 0x5,0x49,0x26, 0xf,0x4b,0x5b, 0x5,0x50,0x21, + 0x7,0x27,0x3e, 0xf,0x51,0x58, 0x5,0x50,0x22, 0x7,0x31,0x71, + 0x4,0x52,0x6a, 0x5,0x57,0x3d, 0xf,0x57,0x34, 0x4,0x58,0x2f, + 0x5,0x63,0x70, 0x5,0x63,0x71, 0x4,0x24,0x74, 0x6,0x25,0x4b, + 0x6,0x23,0x64, 0x6,0x2d,0x73, 0x6,0x2d,0x74, 0xf,0x2d,0x32, + 0x4,0x2f,0x4b, 0x6,0x34,0x33, 0x6,0x3b,0x3b, 0x6,0x3b,0x41, + 0x6,0x3b,0x3d, 0x6,0x3b,0x3c, 0x4,0x2f,0x4c, 0x6,0x3b,0x3f, + 0x6,0x3b,0x40, 0x6,0x43,0x69, 0x5,0x34,0x78, 0x6,0x3b,0x3e, + 0x6,0x43,0x68, 0x6,0x43,0x6b, 0x6,0x43,0x6a, 0x5,0x3b,0x52, + 0x6,0x4d,0x5c, 0x5,0x3b,0x53, 0x5,0x49,0x27, 0x6,0x57,0x28, + 0x6,0x57,0x27, 0x6,0x57,0x25, 0x6,0x60,0x74, 0x6,0x60,0x7a, + 0x6,0x60,0x75, 0x6,0x60,0x76, 0x5,0x50,0x23, 0x7,0x27,0x3f, + 0x6,0x60,0x77, 0x6,0x60,0x7b, 0x6,0x60,0x78, 0x7,0x27,0x40, + 0x7,0x27,0x41, 0x7,0x27,0x42, 0x6,0x60,0x79, 0x5,0x49,0x28, + 0x5,0x50,0x24, 0x5,0x50,0x25, 0x7,0x27,0x43, 0x7,0x27,0x44, + 0x7,0x31,0x72, 0x7,0x27,0x45, 0x7,0x27,0x46, 0xf,0x57,0x35, + 0x7,0x31,0x74, 0x7,0x31,0x73, 0x5,0x5d,0x62, 0x7,0x31,0x77, + 0x7,0x31,0x76, 0x7,0x31,0x75, 0x5,0x5d,0x61, 0x5,0x5d,0x64, + 0x7,0x3a,0x67, 0x7,0x42,0x28, 0x7,0x42,0x27, 0x5,0x5d,0x65, + 0x4,0x5c,0x77, 0x7,0x42,0x26, 0xf,0x60,0x44, 0xf,0x60,0x45, + 0x7,0x49,0x2d, 0x5,0x63,0x73, 0x5,0x63,0x72, 0x7,0x49,0x2e, + 0x7,0x4f,0x3f, 0x5,0x69,0x28, 0x5,0x6d,0x33, 0x5,0x6d,0x34, + 0x5,0x6d,0x35, 0x7,0x4f,0x3e, 0x7,0x49,0x2f, 0xf,0x63,0x4f, + 0x5,0x69,0x29, 0x7,0x4f,0x40, 0x7,0x4f,0x41, 0x5,0x70,0x7a, + 0xf,0x65,0x78, 0xf,0x68,0x35, 0xf,0x68,0x37, 0x7,0x58,0x66, + 0xf,0x68,0x36, 0x7,0x58,0x67, 0x7,0x5c,0x49, 0x5,0x77,0x7e, + 0x7,0x61,0x37, 0x5,0x79,0x3d, 0x5,0x79,0x3f, 0x5,0x79,0x3e, + 0xf,0x6c,0x6a, 0x7,0x65,0x3e, 0x7,0x65,0x3f, 0x7,0x66,0x53, + 0x5,0x7c,0x50, 0xf,0x25,0x2b, 0x6,0x34,0x34, 0x4,0x2f,0x4e, + 0x4,0x2f,0x4d, 0x6,0x3b,0x42, 0x6,0x3b,0x43, 0x6,0x3b,0x44, + 0x5,0x2f,0x73, 0x5,0x2f,0x74, 0x6,0x43,0x6c, 0x6,0x43,0x6d, + 0x6,0x41,0x7d, 0x6,0x4d,0x60, 0x6,0x4d,0x5f, 0x6,0x4d,0x61, + 0xf,0x3e,0x50, 0x5,0x49,0x29, 0x4,0x46,0x4d, 0x5,0x45,0x53, + 0x4,0x46,0x4e, 0x6,0x57,0x29, 0xf,0x4b,0x5c, 0x6,0x60,0x7c, + 0x6,0x60,0x7e, 0x6,0x60,0x7d, 0x7,0x27,0x47, 0xf,0x51,0x59, + 0x7,0x27,0x49, 0x7,0x27,0x48, 0x7,0x31,0x78, 0x5,0x57,0x3e, + 0x7,0x31,0x79, 0x7,0x3a,0x68, 0xf,0x60,0x46, 0x5,0x63,0x74, + 0x7,0x42,0x2a, 0x7,0x42,0x29, 0x5,0x6d,0x36, 0x5,0x70,0x7b, + 0x7,0x5c,0x4a, 0x5,0x76,0x3e, 0x5,0x50,0x26, 0x5,0x50,0x27, + 0xf,0x60,0x47, 0x7,0x4f,0x42, 0x7,0x5c,0x4b, 0x7,0x5f,0x3f, + 0x7,0x61,0x39, 0x5,0x7a,0x70, 0x5,0x24,0x74, 0x4,0x27,0x71, + 0x4,0x27,0x70, 0x6,0x2d,0x77, 0x6,0x2d,0x76, 0x6,0x2d,0x75, + 0x5,0x27,0x5f, 0x4,0x2b,0x31, 0x4,0x2b,0x35, 0x4,0x2b,0x34, + 0x6,0x34,0x35, 0x6,0x34,0x37, 0x6,0x34,0x36, 0x6,0x3b,0x4a, + 0x5,0x2f,0x75, 0x6,0x3b,0x49, 0x6,0x3b,0x45, 0x5,0x2f,0x76, + 0x4,0x2f,0x52, 0x4,0x2f,0x51, 0x6,0x3b,0x46, 0x6,0x3b,0x47, + 0x6,0x3b,0x48, 0x5,0x34,0x7a, 0x4,0x34,0x59, 0x4,0x34,0x5b, + 0x6,0x43,0x72, 0x5,0x34,0x7b, 0x6,0x43,0x6e, 0x6,0x43,0x6f, + 0xf,0x37,0x71, 0x5,0x34,0x79, 0xf,0x37,0x70, 0xf,0x37,0x72, + 0x5,0x3b,0x54, 0x6,0x4d,0x65, 0x6,0x4d,0x64, 0x4,0x34,0x5a, + 0x4,0x3a,0x52, 0x4,0x3a,0x50, 0x4,0x3a,0x51, 0x4,0x3a,0x53, + 0x6,0x4d,0x66, 0x5,0x42,0x2b, 0x6,0x57,0x2c, 0x5,0x42,0x2c, + 0x6,0x57,0x2a, 0xf,0x44,0x72, 0x6,0x57,0x2b, 0x6,0x57,0x2d, + 0x6,0x57,0x2e, 0x5,0x42,0x2e, 0x6,0x61,0x27, 0x5,0x49,0x2d, + 0x5,0x49,0x2b, 0x4,0x46,0x52, 0x6,0x61,0x22, 0x6,0x61,0x26, + 0xf,0x4b,0x5e, 0xf,0x4b,0x5f, 0xf,0x4b,0x5d, 0x6,0x61,0x23, + 0x5,0x49,0x2a, 0x5,0x50,0x2f, 0x4,0x4c,0x67, 0x4,0x4c,0x66, + 0x5,0x50,0x2e, 0x5,0x50,0x2b, 0x5,0x50,0x2c, 0x5,0x50,0x30, + 0x5,0x50,0x28, 0x7,0x27,0x4f, 0x7,0x27,0x4d, 0x5,0x50,0x31, + 0x7,0x27,0x4a, 0x7,0x27,0x4c, 0x7,0x27,0x4e, 0x7,0x27,0x4b, + 0x5,0x50,0x2d, 0x5,0x50,0x29, 0x5,0x50,0x2a, 0x5,0x57,0x42, + 0x5,0x57,0x3f, 0x5,0x57,0x43, 0x7,0x31,0x7c, 0x5,0x57,0x40, + 0x7,0x32,0x21, 0x7,0x31,0x7d, 0x7,0x32,0x23, 0x5,0x57,0x41, + 0x7,0x32,0x22, 0xf,0x57,0x36, 0x7,0x31,0x7e, 0x7,0x31,0x7b, + 0x7,0x3a,0x6a, 0x4,0x58,0x31, 0x5,0x5d,0x6c, 0x5,0x5d,0x66, + 0x5,0x5d,0x69, 0x5,0x5d,0x68, 0x5,0x5d,0x6a, 0x5,0x5d,0x6b, + 0x4,0x5c,0x79, 0x5,0x63,0x7b, 0x7,0x42,0x2c, 0x5,0x63,0x75, + 0x5,0x63,0x7a, 0x5,0x63,0x7d, 0x5,0x63,0x79, 0x4,0x5c,0x7a, + 0x4,0x5c,0x7b, 0x5,0x63,0x76, 0x5,0x63,0x77, 0x5,0x63,0x7c, + 0x4,0x5c,0x78, 0x7,0x42,0x2d, 0x7,0x42,0x2b, 0x5,0x63,0x78, + 0x7,0x49,0x30, 0x5,0x69,0x2d, 0x5,0x69,0x2c, 0x5,0x69,0x2b, + 0x5,0x69,0x2a, 0x7,0x49,0x31, 0xf,0x63,0x50, 0x7,0x49,0x32, + 0x5,0x6d,0x37, 0x7,0x4f,0x43, 0x5,0x70,0x7d, 0x5,0x70,0x7c, + 0x7,0x54,0x52, 0x5,0x74,0x21, 0x5,0x74,0x22, 0x4,0x69,0x32, + 0x7,0x58,0x68, 0x7,0x54,0x50, 0x7,0x54,0x51, 0x4,0x6a,0x6f, + 0x7,0x5c,0x4c, 0x7,0x61,0x3b, 0x7,0x61,0x3a, 0x7,0x62,0x52, + 0x5,0x7a,0x71, 0x4,0x6e,0x4f, 0x6,0x34,0x38, 0xf,0x37,0x73, + 0x5,0x3b,0x3f, 0xf,0x3e,0x51, 0xf,0x51,0x5a, 0xf,0x5c,0x39, + 0x7,0x4f,0x44, 0x5,0x34,0x7c, 0x5,0x34,0x7d, 0x6,0x43,0x73, + 0x5,0x34,0x7e, 0xf,0x3e,0x52, 0x6,0x57,0x2f, 0x6,0x57,0x30, + 0x6,0x57,0x31, 0x6,0x61,0x29, 0xf,0x4b,0x60, 0x6,0x61,0x2a, + 0x6,0x61,0x28, 0x7,0x27,0x51, 0x7,0x27,0x50, 0x7,0x27,0x52, + 0xf,0x51,0x5b, 0xf,0x51,0x5c, 0xf,0x51,0x5d, 0x5,0x57,0x44, + 0x5,0x57,0x45, 0x7,0x32,0x25, 0x7,0x32,0x24, 0x5,0x6d,0x39, + 0x5,0x6d,0x38, 0x7,0x4f,0x45, 0xf,0x6c,0x37, 0x5,0x21,0x7b, + 0x6,0x23,0x38, 0x4,0x23,0x2e, 0x6,0x25,0x50, 0x6,0x25,0x51, + 0x6,0x2d,0x78, 0x6,0x25,0x4e, 0x5,0x23,0x26, 0x6,0x25,0x4d, + 0xf,0x22,0x6f, 0xf,0x22,0x70, 0xf,0x22,0x6e, 0x6,0x25,0x4c, + 0x4,0x24,0x77, 0x4,0x24,0x78, 0x4,0x24,0x7c, 0x6,0x29,0x22, + 0x4,0x24,0x7a, 0x6,0x29,0x25, 0x6,0x29,0x23, 0x6,0x29,0x24, + 0x6,0x29,0x26, 0xf,0x25,0x2c, 0xf,0x25,0x2d, 0xf,0x25,0x2e, + 0xf,0x25,0x2f, 0xf,0x25,0x30, 0xf,0x25,0x31, 0x6,0x2d,0x7b, + 0x4,0x27,0x7c, 0x4,0x27,0x77, 0x4,0x27,0x79, 0x5,0x27,0x62, + 0x4,0x27,0x7d, 0x4,0x27,0x78, 0x4,0x27,0x75, 0x5,0x27,0x60, + 0x6,0x2d,0x7c, 0x5,0x27,0x61, 0x4,0x27,0x74, 0x6,0x3b,0x4b, + 0x6,0x27,0x4c, 0x6,0x2e,0x21, 0x5,0x27,0x64, 0x4,0x27,0x76, + 0x6,0x2d,0x7a, 0x6,0x2d,0x7e, 0x6,0x3b,0x4d, 0x6,0x3b,0x4c, + 0xf,0x28,0x57, 0xf,0x28,0x58, 0xf,0x28,0x59, 0xf,0x28,0x5a, + 0xf,0x28,0x5b, 0xf,0x28,0x5d, 0xf,0x28,0x5e, 0xf,0x28,0x5f, + 0xf,0x28,0x60, 0xf,0x28,0x61, 0xf,0x28,0x62, 0xf,0x28,0x64, + 0x6,0x2d,0x79, 0x4,0x2b,0x3b, 0x4,0x2b,0x37, 0x4,0x2b,0x38, + 0x4,0x2b,0x39, 0x5,0x2b,0x3f, 0x6,0x34,0x43, 0x6,0x34,0x3b, + 0x4,0x2b,0x3c, 0x6,0x34,0x41, 0x6,0x34,0x3d, 0x5,0x2b,0x3d, + 0x6,0x34,0x39, 0x6,0x34,0x40, 0x6,0x34,0x3e, 0x6,0x34,0x42, + 0x6,0x34,0x45, 0x6,0x34,0x46, 0x5,0x2b,0x3b, 0x5,0x2b,0x3e, + 0x5,0x2b,0x3c, 0xf,0x2d,0x33, 0xf,0x2d,0x35, 0xf,0x2d,0x37, + 0xf,0x2d,0x38, 0xf,0x2d,0x39, 0xf,0x2d,0x3a, 0xf,0x2d,0x3b, + 0xf,0x2d,0x3c, 0xf,0x2d,0x36, 0x6,0x33,0x3e, 0x6,0x34,0x3f, + 0xf,0x2d,0x34, 0x6,0x2d,0x7d, 0x6,0x4d,0x68, 0xf,0x2a,0x52, + 0x5,0x2f,0x7c, 0x4,0x2f,0x56, 0x4,0x2f,0x57, 0x4,0x2f,0x62, + 0x5,0x2f,0x78, 0x5,0x2f,0x7a, 0x5,0x2f,0x7e, 0x4,0x2f,0x54, + 0x5,0x2f,0x77, 0x5,0x30,0x23, 0x4,0x2f,0x5b, 0x5,0x30,0x27, + 0x4,0x2f,0x58, 0x4,0x2f,0x65, 0x5,0x30,0x24, 0x4,0x2f,0x60, + 0x6,0x3b,0x5e, 0x6,0x3b,0x5f, 0x5,0x30,0x25, 0x6,0x3b,0x61, + 0x5,0x30,0x22, 0x4,0x2f,0x66, 0x6,0x3b,0x59, 0x6,0x3b,0x58, + 0x6,0x4d,0x67, 0x6,0x44,0x22, 0x6,0x3b,0x55, 0x5,0x2f,0x7d, + 0x6,0x3b,0x54, 0x6,0x3b,0x51, 0x6,0x3b,0x4f, 0x6,0x3b,0x5a, + 0x6,0x3b,0x5c, 0x5,0x2f,0x7b, 0x6,0x3b,0x57, 0x5,0x30,0x26, + 0x5,0x2f,0x79, 0x6,0x3b,0x53, 0x6,0x3b,0x5b, 0x6,0x3b,0x5d, + 0x6,0x3b,0x62, 0xf,0x32,0x33, 0xf,0x32,0x35, 0xf,0x32,0x36, + 0xf,0x32,0x37, 0xf,0x32,0x38, 0xf,0x32,0x39, 0xf,0x32,0x3b, + 0xf,0x32,0x3c, 0xf,0x32,0x3d, 0xf,0x32,0x3f, 0xf,0x32,0x40, + 0xf,0x32,0x42, 0xf,0x32,0x43, 0xf,0x32,0x44, 0xf,0x32,0x45, + 0xf,0x32,0x47, 0xf,0x32,0x48, 0xf,0x32,0x49, 0xf,0x32,0x4a, + 0xf,0x32,0x4b, 0x6,0x3b,0x50, 0xf,0x32,0x46, 0xf,0x32,0x4c, + 0xf,0x32,0x3e, 0x5,0x35,0x2b, 0x5,0x35,0x2e, 0x5,0x35,0x27, + 0x4,0x34,0x70, 0x5,0x35,0x2c, 0x4,0x34,0x61, 0x4,0x34,0x6e, + 0x4,0x34,0x68, 0x6,0x44,0x32, 0x4,0x34,0x72, 0x4,0x34,0x75, + 0x6,0x44,0x26, 0x6,0x43,0x7b, 0x6,0x44,0x23, 0x5,0x35,0x23, + 0x6,0x43,0x79, 0x6,0x43,0x75, 0x4,0x34,0x60, 0x5,0x35,0x32, + 0x6,0x43,0x74, 0x6,0x44,0x21, 0x6,0x44,0x38, 0x4,0x34,0x64, + 0x6,0x44,0x36, 0x6,0x4e,0x3a, 0x6,0x44,0x34, 0x6,0x3b,0x60, + 0x6,0x4d,0x78, 0x4,0x34,0x5f, 0x5,0x35,0x21, 0x4,0x34,0x6b, + 0x6,0x43,0x77, 0x6,0x44,0x24, 0x5,0x35,0x30, 0x6,0x44,0x2f, + 0x6,0x44,0x35, 0x6,0x44,0x2e, 0x6,0x44,0x29, 0x5,0x35,0x2f, + 0x6,0x44,0x33, 0x6,0x43,0x78, 0x6,0x44,0x27, 0x5,0x35,0x31, + 0x5,0x42,0x2f, 0x6,0x57,0x32, 0x6,0x57,0x33, 0x6,0x44,0x30, + 0x6,0x44,0x31, 0x6,0x43,0x7e, 0x5,0x35,0x22, 0x5,0x35,0x33, + 0x6,0x44,0x2a, 0x5,0x35,0x29, 0x5,0x35,0x2d, 0x5,0x35,0x26, + 0x6,0x4e,0x37, 0x6,0x44,0x39, 0x6,0x44,0x3a, 0x6,0x43,0x7c, + 0x6,0x43,0x7a, 0xf,0x37,0x74, 0xf,0x37,0x75, 0xf,0x37,0x76, + 0xf,0x37,0x77, 0xf,0x37,0x79, 0xf,0x37,0x7b, 0xf,0x37,0x7c, + 0xf,0x37,0x7d, 0xf,0x37,0x7e, 0xf,0x38,0x21, 0xf,0x38,0x22, + 0xf,0x38,0x24, 0xf,0x38,0x25, 0xf,0x38,0x26, 0xf,0x38,0x27, + 0xf,0x38,0x28, 0xf,0x38,0x29, 0xf,0x38,0x2a, 0xf,0x38,0x2b, + 0xf,0x38,0x2c, 0xf,0x38,0x2d, 0xf,0x38,0x2e, 0xf,0x38,0x2f, + 0xf,0x38,0x30, 0xf,0x38,0x31, 0xf,0x38,0x32, 0xf,0x38,0x33, + 0xf,0x38,0x34, 0xf,0x38,0x35, 0x5,0x3b,0x5d, 0x6,0x43,0x7d, + 0x5,0x35,0x28, 0x6,0x44,0x25, 0xf,0x37,0x7a, 0x6,0x44,0x2d, + 0x6,0x44,0x37, 0xf,0x38,0x23, 0x5,0x35,0x25, 0x5,0x3b,0x55, + 0x4,0x3a,0x55, 0x5,0x3b,0x69, 0x5,0x3b,0x6a, 0x5,0x3b,0x62, + 0x5,0x3b,0x6c, 0x5,0x3b,0x6d, 0x5,0x3b,0x63, 0x4,0x3a,0x5d, + 0x6,0x4d,0x7a, 0x6,0x4d,0x72, 0x6,0x4e,0x2b, 0x6,0x4d,0x70, + 0x6,0x4d,0x6b, 0x5,0x3b,0x5f, 0x5,0x3b,0x67, 0x5,0x3b,0x68, + 0x6,0x4d,0x7b, 0x6,0x4d,0x79, 0x5,0x3b,0x5e, 0x5,0x3b,0x6e, + 0x5,0x3b,0x6b, 0x4,0x34,0x6a, 0x4,0x3a,0x57, 0x4,0x3a,0x5a, + 0x4,0x3a,0x58, 0x4,0x3a,0x62, 0x5,0x3b,0x5a, 0x4,0x3a,0x54, + 0x6,0x4d,0x69, 0x6,0x4e,0x35, 0x4,0x3a,0x63, 0x6,0x4d,0x6a, + 0x5,0x3b,0x64, 0x6,0x4d,0x7c, 0x6,0x4e,0x36, 0x6,0x4d,0x7d, + 0x6,0x4e,0x2f, 0x6,0x4e,0x30, 0x4,0x3a,0x6b, 0x6,0x4e,0x26, + 0x4,0x3a,0x69, 0x6,0x4e,0x23, 0x5,0x3b,0x5c, 0x6,0x4e,0x28, + 0x6,0x4d,0x75, 0x6,0x4e,0x2d, 0x6,0x4d,0x74, 0x6,0x4e,0x22, + 0x6,0x4e,0x31, 0x6,0x4e,0x29, 0x5,0x3b,0x65, 0x6,0x61,0x32, + 0x6,0x61,0x2d, 0x6,0x61,0x2e, 0x5,0x3b,0x57, 0x6,0x4e,0x24, + 0x6,0x4d,0x6f, 0x6,0x4e,0x2e, 0x5,0x49,0x2e, 0x6,0x4d,0x73, + 0x6,0x4e,0x2c, 0x6,0x4d,0x77, 0x6,0x4e,0x25, 0x6,0x4d,0x6d, + 0x6,0x4e,0x2a, 0x4,0x3a,0x6a, 0x5,0x3b,0x60, 0x5,0x3b,0x5b, + 0x6,0x4d,0x76, 0x6,0x4e,0x38, 0x6,0x61,0x2b, 0x5,0x3b,0x66, + 0x6,0x61,0x2f, 0x5,0x3b,0x61, 0x6,0x4e,0x34, 0x6,0x61,0x31, + 0x6,0x61,0x30, 0x6,0x4d,0x6c, 0x6,0x4d,0x7e, 0x6,0x4c,0x7b, + 0x5,0x3b,0x58, 0x6,0x4d,0x6e, 0x6,0x4d,0x71, 0x6,0x4e,0x33, + 0x6,0x4e,0x39, 0xf,0x3e,0x53, 0xf,0x3e,0x55, 0xf,0x3e,0x56, + 0xf,0x3e,0x58, 0xf,0x3e,0x5a, 0xf,0x3e,0x5b, 0xf,0x3e,0x5c, + 0xf,0x3e,0x5d, 0xf,0x3e,0x5e, 0xf,0x3e,0x5f, 0xf,0x3e,0x60, + 0xf,0x3e,0x61, 0xf,0x3e,0x63, 0xf,0x3e,0x64, 0xf,0x3e,0x65, + 0xf,0x3e,0x68, 0xf,0x3e,0x69, 0xf,0x3e,0x6a, 0xf,0x3e,0x6d, + 0xf,0x3e,0x6f, 0xf,0x3e,0x70, 0xf,0x3e,0x71, 0xf,0x3e,0x72, + 0xf,0x3e,0x74, 0xf,0x3e,0x75, 0xf,0x3e,0x76, 0xf,0x3e,0x77, + 0xf,0x3e,0x78, 0xf,0x3e,0x79, 0xf,0x3e,0x7a, 0xf,0x3e,0x7b, + 0xf,0x3e,0x7c, 0xf,0x3e,0x7d, 0xf,0x3e,0x7e, 0x6,0x61,0x2c, + 0x5,0x3b,0x59, 0x6,0x4e,0x21, 0xf,0x3e,0x62, 0xf,0x3e,0x54, + 0xf,0x3e,0x6e, 0xf,0x3e,0x73, 0x4,0x40,0x43, 0x6,0x57,0x34, + 0x6,0x57,0x46, 0x5,0x42,0x4e, 0x6,0x57,0x3a, 0x6,0x57,0x3b, + 0x5,0x42,0x34, 0x4,0x40,0x3d, 0x6,0x57,0x49, 0x6,0x57,0x5a, + 0x4,0x40,0x40, 0x4,0x40,0x42, 0x5,0x42,0x45, 0x6,0x57,0x5e, + 0x5,0x42,0x3a, 0x4,0x40,0x37, 0x4,0x40,0x34, 0x6,0x57,0x41, + 0x6,0x57,0x63, 0x5,0x42,0x33, 0x6,0x57,0x51, 0x6,0x57,0x55, + 0x5,0x42,0x43, 0x6,0x57,0x4a, 0x4,0x40,0x38, 0x4,0x40,0x3b, + 0x5,0x42,0x36, 0x6,0x57,0x43, 0x4,0x40,0x3c, 0x4,0x40,0x45, + 0x5,0x42,0x41, 0x4,0x40,0x4d, 0x5,0x42,0x4f, 0x4,0x40,0x3e, + 0x5,0x42,0x46, 0x6,0x57,0x5d, 0x5,0x42,0x3f, 0x4,0x40,0x33, + 0x4,0x40,0x31, 0x6,0x57,0x65, 0x4,0x40,0x3f, 0x6,0x57,0x42, + 0x5,0x42,0x48, 0x5,0x42,0x42, 0x5,0x42,0x38, 0x5,0x42,0x3e, + 0x6,0x57,0x38, 0x6,0x57,0x53, 0x6,0x57,0x4f, 0x6,0x57,0x40, + 0x6,0x57,0x67, 0x5,0x42,0x3d, 0x6,0x57,0x39, 0x6,0x57,0x64, + 0x6,0x57,0x37, 0x5,0x42,0x50, 0x6,0x57,0x4e, 0x6,0x57,0x45, + 0x6,0x57,0x3c, 0x5,0x42,0x49, 0x5,0x42,0x4d, 0x5,0x42,0x3b, + 0x5,0x42,0x47, 0x6,0x57,0x52, 0x6,0x57,0x60, 0x6,0x57,0x5c, + 0x6,0x57,0x48, 0x6,0x57,0x56, 0x5,0x42,0x39, 0x4,0x40,0x39, + 0x6,0x57,0x57, 0x5,0x42,0x30, 0x5,0x42,0x40, 0x5,0x42,0x32, + 0x5,0x42,0x4a, 0x6,0x57,0x3f, 0x4,0x40,0x35, 0x4,0x40,0x4b, + 0x6,0x57,0x4c, 0x5,0x42,0x35, 0x5,0x42,0x31, 0x6,0x57,0x47, + 0x6,0x57,0x58, 0x7,0x27,0x53, 0x6,0x57,0x61, 0x5,0x42,0x3c, + 0x6,0x57,0x44, 0x6,0x57,0x54, 0x6,0x57,0x36, 0x6,0x57,0x62, + 0x6,0x57,0x66, 0x6,0x57,0x59, 0x4,0x40,0x4e, 0x5,0x42,0x44, + 0x5,0x42,0x4b, 0x6,0x57,0x35, 0x6,0x57,0x3e, 0x6,0x57,0x4b, + 0x6,0x57,0x4d, 0x6,0x57,0x5b, 0x6,0x57,0x5f, 0xf,0x44,0x73, + 0xf,0x44,0x75, 0xf,0x44,0x76, 0xf,0x44,0x77, 0xf,0x44,0x78, + 0xf,0x44,0x79, 0xf,0x44,0x7a, 0xf,0x44,0x7b, 0xf,0x44,0x7c, + 0xf,0x44,0x7d, 0xf,0x44,0x7e, 0xf,0x45,0x21, 0xf,0x45,0x22, + 0xf,0x45,0x23, 0xf,0x45,0x24, 0xf,0x45,0x25, 0xf,0x45,0x26, + 0xf,0x45,0x27, 0xf,0x45,0x28, 0xf,0x45,0x29, 0xf,0x45,0x2a, + 0xf,0x45,0x2b, 0xf,0x45,0x2c, 0xf,0x45,0x2e, 0xf,0x45,0x2f, + 0xf,0x45,0x30, 0xf,0x45,0x31, 0x5,0x42,0x4c, 0x4,0x40,0x4a, + 0x6,0x57,0x3d, 0x6,0x4e,0x32, 0xf,0x3e,0x57, 0x5,0x42,0x37, + 0x4,0x46,0x66, 0x6,0x61,0x60, 0x5,0x49,0x45, 0x6,0x61,0x33, + 0x6,0x61,0x43, 0x5,0x49,0x4b, 0x4,0x46,0x63, 0x6,0x61,0x56, + 0x4,0x46,0x56, 0x6,0x61,0x45, 0x4,0x46,0x59, 0x6,0x61,0x3c, + 0x5,0x49,0x41, 0x6,0x61,0x4a, 0x4,0x46,0x55, 0x6,0x61,0x52, + 0x5,0x49,0x3d, 0x6,0x61,0x40, 0x6,0x61,0x59, 0x5,0x49,0x49, + 0x5,0x49,0x46, 0x6,0x61,0x4c, 0x5,0x49,0x3a, 0x4,0x46,0x5a, + 0x6,0x61,0x39, 0x6,0x61,0x55, 0x6,0x61,0x4d, 0x6,0x61,0x3f, + 0x5,0x49,0x44, 0x5,0x49,0x39, 0x5,0x49,0x30, 0x4,0x46,0x62, + 0x6,0x61,0x41, 0x4,0x46,0x5e, 0x6,0x61,0x36, 0x4,0x46,0x5d, + 0x4,0x46,0x6b, 0x4,0x46,0x5b, 0x5,0x49,0x3f, 0x7,0x27,0x58, + 0x6,0x61,0x37, 0x5,0x49,0x32, 0x5,0x49,0x37, 0x5,0x49,0x31, + 0x5,0x49,0x48, 0x5,0x50,0x3b, 0x4,0x46,0x5f, 0x5,0x49,0x43, + 0x6,0x61,0x38, 0x4,0x46,0x68, 0x6,0x61,0x50, 0x5,0x49,0x38, + 0x6,0x61,0x57, 0x6,0x61,0x46, 0x6,0x61,0x3b, 0x5,0x49,0x40, + 0x5,0x49,0x36, 0x7,0x32,0x27, 0x5,0x49,0x2f, 0x5,0x49,0x34, + 0x6,0x61,0x47, 0x6,0x61,0x49, 0x6,0x61,0x4b, 0x6,0x61,0x4e, + 0x6,0x61,0x5a, 0x6,0x61,0x5d, 0x6,0x61,0x5e, 0xf,0x4b,0x61, + 0xf,0x4b,0x62, 0xf,0x4b,0x63, 0xf,0x4b,0x66, 0xf,0x4b,0x68, + 0xf,0x4b,0x69, 0xf,0x4b,0x6a, 0xf,0x4b,0x6b, 0xf,0x4b,0x6c, + 0xf,0x4b,0x6d, 0xf,0x4b,0x6e, 0xf,0x4b,0x6f, 0xf,0x4b,0x70, + 0xf,0x4b,0x71, 0xf,0x4b,0x72, 0xf,0x4b,0x73, 0xf,0x4b,0x74, + 0xf,0x4b,0x75, 0xf,0x4b,0x76, 0xf,0x4b,0x78, 0xf,0x4b,0x79, + 0xf,0x4b,0x7a, 0xf,0x4b,0x7c, 0xf,0x4b,0x7d, 0xf,0x4b,0x7e, + 0xf,0x4c,0x21, 0xf,0x4c,0x22, 0xf,0x4c,0x23, 0xf,0x4c,0x25, + 0xf,0x4c,0x26, 0xf,0x4c,0x27, 0xf,0x4c,0x28, 0xf,0x4c,0x29, + 0xf,0x4c,0x2a, 0x6,0x61,0x48, 0x5,0x49,0x42, 0x6,0x61,0x53, + 0x6,0x61,0x51, 0x6,0x57,0x68, 0x5,0x49,0x4a, 0x6,0x61,0x5c, + 0x6,0x61,0x5f, 0x6,0x61,0x5b, 0x6,0x61,0x3a, 0x6,0x61,0x35, + 0x6,0x61,0x42, 0x6,0x61,0x3d, 0x6,0x57,0x50, 0xf,0x4b,0x64, + 0xf,0x4b,0x67, 0x6,0x61,0x54, 0x4,0x46,0x6a, 0x4,0x46,0x54, + 0x5,0x49,0x35, 0x5,0x49,0x4d, 0x7,0x32,0x26, 0x5,0x49,0x33, + 0x6,0x61,0x61, 0x5,0x49,0x47, 0x5,0x49,0x4c, 0x5,0x57,0x46, + 0xf,0x4b,0x7b, 0x5,0x49,0x3e, 0x7,0x27,0x6c, 0x4,0x4c,0x7e, + 0x5,0x50,0x32, 0x4,0x4c,0x69, 0x4,0x4c,0x7c, 0x7,0x28,0x21, + 0x5,0x50,0x35, 0x7,0x28,0x24, 0x7,0x27,0x77, 0x7,0x27,0x5c, + 0x5,0x50,0x39, 0x7,0x27,0x69, 0x7,0x27,0x78, 0x7,0x27,0x79, + 0x7,0x27,0x6a, 0x7,0x27,0x73, 0x5,0x50,0x3a, 0x7,0x27,0x6f, + 0x4,0x4c,0x75, 0x5,0x50,0x3d, 0x5,0x50,0x42, 0x7,0x27,0x60, + 0x7,0x28,0x22, 0x5,0x50,0x40, 0x5,0x50,0x3f, 0x5,0x57,0x47, + 0x5,0x50,0x41, 0x5,0x50,0x4b, 0x7,0x27,0x6b, 0x7,0x27,0x76, + 0x7,0x27,0x59, 0x7,0x27,0x72, 0x7,0x27,0x65, 0x5,0x50,0x48, + 0x5,0x50,0x37, 0x4,0x4c,0x7b, 0x7,0x27,0x54, 0x7,0x27,0x5b, + 0x7,0x27,0x64, 0x7,0x27,0x63, 0x7,0x27,0x67, 0x5,0x50,0x33, + 0x7,0x27,0x66, 0x7,0x27,0x7d, 0x7,0x27,0x5e, 0x5,0x50,0x3e, + 0x7,0x27,0x56, 0x5,0x50,0x34, 0x5,0x50,0x4a, 0x7,0x27,0x7c, + 0x7,0x27,0x62, 0x7,0x27,0x5d, 0x7,0x27,0x6e, 0x4,0x4c,0x76, + 0x5,0x50,0x49, 0x5,0x50,0x45, 0x7,0x27,0x74, 0x5,0x57,0x58, + 0x4,0x4d,0x22, 0x5,0x50,0x43, 0x7,0x27,0x55, 0x7,0x27,0x5a, + 0x7,0x27,0x5f, 0x7,0x27,0x70, 0x7,0x27,0x71, 0x7,0x28,0x23, + 0xf,0x51,0x5e, 0xf,0x51,0x5f, 0xf,0x51,0x60, 0xf,0x51,0x62, + 0xf,0x51,0x63, 0xf,0x51,0x66, 0xf,0x51,0x67, 0xf,0x51,0x68, + 0xf,0x51,0x69, 0xf,0x51,0x6a, 0xf,0x51,0x6c, 0xf,0x51,0x6d, + 0xf,0x51,0x6e, 0xf,0x51,0x6f, 0xf,0x51,0x70, 0xf,0x51,0x72, + 0xf,0x51,0x75, 0xf,0x51,0x77, 0x4,0x4d,0x23, 0x7,0x27,0x7a, + 0x5,0x50,0x44, 0x7,0x27,0x7e, 0x7,0x27,0x75, 0x7,0x27,0x68, + 0xf,0x51,0x71, 0xf,0x51,0x61, 0xf,0x51,0x6b, 0x5,0x50,0x36, + 0x7,0x27,0x57, 0x5,0x50,0x47, 0x5,0x50,0x3c, 0x6,0x61,0x34, + 0x7,0x42,0x2e, 0xf,0x4c,0x24, 0x7,0x32,0x51, 0x4,0x53,0x2d, + 0x7,0x32,0x32, 0x4,0x53,0x2a, 0x4,0x53,0x34, 0x7,0x32,0x53, + 0x5,0x57,0x49, 0x4,0x53,0x2b, 0x5,0x57,0x5d, 0x7,0x32,0x43, + 0x5,0x57,0x54, 0x4,0x52,0x71, 0x4,0x53,0x30, 0x5,0x57,0x51, + 0x5,0x57,0x5b, 0x7,0x32,0x3c, 0x4,0x52,0x75, 0x5,0x57,0x5a, + 0x5,0x57,0x4b, 0x5,0x57,0x5f, 0x7,0x32,0x33, 0x5,0x57,0x61, + 0x4,0x53,0x2f, 0x7,0x32,0x28, 0x5,0x57,0x4d, 0x5,0x57,0x4f, + 0x7,0x32,0x4c, 0x5,0x57,0x55, 0x5,0x57,0x62, 0x7,0x32,0x3d, + 0x7,0x32,0x3b, 0x5,0x50,0x4c, 0x4,0x52,0x70, 0x5,0x57,0x48, + 0x5,0x57,0x5e, 0x7,0x32,0x45, 0x7,0x32,0x4b, 0x7,0x32,0x41, + 0x5,0x57,0x64, 0x5,0x57,0x60, 0x7,0x28,0x25, 0x7,0x27,0x7b, + 0x7,0x32,0x52, 0x5,0x5d,0x7a, 0x4,0x53,0x26, 0x7,0x32,0x2e, + 0x4,0x53,0x29, 0x7,0x32,0x36, 0x5,0x57,0x53, 0x4,0x53,0x28, + 0x4,0x52,0x74, 0x5,0x50,0x38, 0x7,0x32,0x2f, 0x5,0x57,0x52, + 0x7,0x32,0x38, 0x5,0x57,0x56, 0x5,0x57,0x4c, 0x7,0x32,0x2d, + 0x7,0x32,0x57, 0x7,0x32,0x4e, 0x4,0x53,0x2e, 0x5,0x57,0x5c, + 0x7,0x32,0x2a, 0x4,0x52,0x78, 0x7,0x32,0x39, 0x7,0x42,0x2f, + 0x7,0x32,0x2b, 0x7,0x32,0x55, 0x4,0x53,0x32, 0x7,0x32,0x42, + 0x7,0x32,0x35, 0x7,0x32,0x3f, 0xf,0x57,0x3e, 0xf,0x57,0x3f, + 0xf,0x57,0x40, 0xf,0x57,0x41, 0x5,0x57,0x4a, 0x5,0x57,0x50, + 0x5,0x57,0x57, 0x7,0x32,0x2c, 0x7,0x32,0x34, 0x7,0x32,0x37, + 0x7,0x32,0x3e, 0x7,0x32,0x40, 0x7,0x32,0x47, 0x7,0x32,0x49, + 0x7,0x32,0x4d, 0x7,0x32,0x4f, 0x7,0x32,0x54, 0x7,0x32,0x59, + 0x7,0x32,0x5a, 0xf,0x57,0x37, 0xf,0x57,0x38, 0xf,0x57,0x39, + 0xf,0x57,0x3a, 0xf,0x57,0x3b, 0xf,0x57,0x3c, 0xf,0x57,0x3d, + 0xf,0x57,0x42, 0xf,0x57,0x43, 0xf,0x57,0x44, 0xf,0x57,0x49, + 0xf,0x57,0x4c, 0xf,0x57,0x4d, 0xf,0x57,0x4e, 0xf,0x57,0x4f, + 0xf,0x57,0x50, 0xf,0x57,0x51, 0xf,0x57,0x52, 0xf,0x57,0x53, + 0xf,0x57,0x54, 0xf,0x57,0x56, 0xf,0x57,0x57, 0xf,0x57,0x58, + 0xf,0x57,0x59, 0xf,0x57,0x5a, 0xf,0x57,0x5b, 0xf,0x57,0x5c, + 0x7,0x32,0x31, 0xf,0x57,0x45, 0x4,0x52,0x7d, 0x7,0x32,0x3a, + 0x7,0x32,0x58, 0x7,0x32,0x50, 0x5,0x57,0x65, 0x5,0x57,0x4e, + 0x7,0x32,0x30, 0x7,0x32,0x29, 0x7,0x32,0x48, 0xf,0x57,0x4a, + 0x7,0x32,0x56, 0x5,0x57,0x63, 0x5,0x57,0x59, 0x7,0x32,0x46, + 0x7,0x3a,0x76, 0x4,0x58,0x3a, 0x4,0x58,0x3f, 0x7,0x3a,0x6e, + 0x7,0x42,0x3b, 0x7,0x3a,0x78, 0x4,0x58,0x48, 0x4,0x58,0x49, + 0x5,0x57,0x66, 0x5,0x5d,0x75, 0x5,0x5d,0x7d, 0x5,0x5d,0x73, + 0x7,0x3b,0x2b, 0x7,0x3b,0x2f, 0x5,0x5d,0x6f, 0x4,0x58,0x4a, + 0x4,0x58,0x37, 0x7,0x3a,0x7b, 0x4,0x58,0x45, 0x5,0x5e,0x21, + 0x7,0x3a,0x7c, 0x7,0x3b,0x23, 0x7,0x3b,0x33, 0x5,0x5d,0x7e, + 0x5,0x5e,0x25, 0x7,0x3b,0x31, 0x5,0x5e,0x22, 0x5,0x5d,0x6e, + 0x5,0x5d,0x78, 0x7,0x3a,0x7e, 0x5,0x5d,0x7c, 0x7,0x3a,0x73, + 0x7,0x3b,0x24, 0x7,0x3b,0x2a, 0x5,0x5d,0x7b, 0x4,0x58,0x4b, + 0x5,0x5d,0x6d, 0x5,0x5e,0x23, 0x4,0x58,0x41, 0x7,0x3b,0x30, + 0x5,0x5d,0x77, 0x4,0x58,0x46, 0x5,0x5d,0x71, 0x5,0x5e,0x24, + 0x7,0x3b,0x25, 0x5,0x5d,0x76, 0x7,0x3a,0x70, 0x7,0x3a,0x75, + 0x7,0x42,0x39, 0x7,0x3a,0x6b, 0x7,0x3a,0x6c, 0x7,0x3b,0x35, + 0x7,0x3a,0x7d, 0x4,0x58,0x47, 0x7,0x3b,0x2e, 0x7,0x3a,0x72, + 0x7,0x3a,0x77, 0x7,0x49,0x34, 0x7,0x3a,0x71, 0x7,0x3b,0x22, + 0x7,0x3b,0x29, 0x7,0x32,0x4a, 0x7,0x3a,0x79, 0x7,0x3b,0x21, + 0x7,0x3b,0x37, 0x5,0x5d,0x74, 0x5,0x50,0x4d, 0x4,0x58,0x43, + 0x7,0x49,0x35, 0x5,0x5d,0x70, 0x5,0x5d,0x72, 0x7,0x3a,0x6d, + 0x7,0x3b,0x27, 0x7,0x3b,0x28, 0x7,0x3b,0x2c, 0x7,0x3b,0x34, + 0xf,0x5c,0x3a, 0xf,0x5c,0x3b, 0xf,0x5c,0x3c, 0xf,0x5c,0x3d, + 0xf,0x5c,0x3e, 0xf,0x5c,0x40, 0xf,0x5c,0x41, 0xf,0x5c,0x42, + 0xf,0x5c,0x43, 0xf,0x5c,0x44, 0xf,0x5c,0x45, 0xf,0x5c,0x46, + 0xf,0x5c,0x47, 0xf,0x5c,0x49, 0xf,0x5c,0x4a, 0xf,0x5c,0x4b, + 0xf,0x5c,0x4c, 0xf,0x5c,0x4f, 0xf,0x5c,0x50, 0x4,0x58,0x39, + 0x7,0x3a,0x7a, 0x7,0x3b,0x2d, 0x7,0x3b,0x36, 0x7,0x3a,0x74, + 0xf,0x5c,0x48, 0xf,0x5c,0x3f, 0xf,0x5c,0x4e, 0xf,0x57,0x55, + 0xf,0x63,0x5b, 0x5,0x64,0x2c, 0x7,0x42,0x4b, 0x4,0x5d,0x24, + 0x7,0x42,0x4c, 0x5,0x64,0x22, 0x4,0x5d,0x25, 0x5,0x5e,0x26, + 0x5,0x64,0x2f, 0x7,0x42,0x48, 0x5,0x64,0x25, 0x5,0x63,0x7e, + 0x7,0x42,0x30, 0x5,0x64,0x21, 0x5,0x64,0x29, 0x5,0x64,0x36, + 0x5,0x64,0x39, 0x7,0x42,0x36, 0x5,0x64,0x33, 0x7,0x42,0x46, + 0x4,0x5d,0x22, 0x5,0x5e,0x27, 0x5,0x64,0x38, 0x5,0x64,0x26, + 0x5,0x64,0x30, 0x7,0x42,0x3d, 0x5,0x64,0x24, 0x5,0x64,0x2e, + 0x7,0x42,0x4d, 0x4,0x5d,0x30, 0x5,0x64,0x31, 0x4,0x5d,0x2e, + 0x4,0x5d,0x26, 0x4,0x5d,0x2a, 0x5,0x64,0x34, 0x5,0x64,0x32, + 0x7,0x42,0x3e, 0x7,0x4f,0x46, 0x7,0x42,0x3a, 0x7,0x42,0x37, + 0x4,0x5d,0x2f, 0x7,0x49,0x44, 0x5,0x64,0x2b, 0x7,0x42,0x33, + 0x7,0x42,0x45, 0x7,0x42,0x49, 0x4,0x5d,0x2d, 0x7,0x3b,0x26, + 0x7,0x42,0x32, 0x7,0x42,0x34, 0x7,0x42,0x35, 0x7,0x42,0x3f, + 0x7,0x42,0x42, 0x7,0x42,0x44, 0x7,0x42,0x4a, 0x7,0x42,0x4e, + 0x7,0x42,0x4f, 0xf,0x60,0x48, 0xf,0x60,0x49, 0xf,0x60,0x4a, + 0xf,0x60,0x4b, 0xf,0x60,0x4c, 0xf,0x60,0x4f, 0xf,0x60,0x50, + 0xf,0x60,0x51, 0xf,0x60,0x52, 0xf,0x60,0x53, 0xf,0x60,0x54, + 0xf,0x60,0x55, 0xf,0x60,0x56, 0xf,0x60,0x57, 0xf,0x60,0x58, + 0xf,0x60,0x59, 0xf,0x60,0x5a, 0xf,0x60,0x5b, 0xf,0x60,0x5c, + 0xf,0x60,0x5e, 0xf,0x60,0x5f, 0x4,0x5d,0x27, 0x7,0x42,0x40, + 0x5,0x64,0x27, 0x7,0x42,0x41, 0x7,0x49,0x33, 0x5,0x64,0x35, + 0x5,0x64,0x2a, 0x4,0x5d,0x29, 0x7,0x42,0x47, 0x5,0x64,0x23, + 0x5,0x64,0x28, 0x5,0x64,0x37, 0x7,0x42,0x43, 0x7,0x42,0x31, + 0x5,0x69,0x3e, 0x5,0x69,0x2f, 0x7,0x4f,0x5d, 0x5,0x69,0x30, + 0x5,0x69,0x3a, 0x5,0x69,0x36, 0x4,0x60,0x7d, 0x4,0x60,0x79, + 0x5,0x69,0x3f, 0x5,0x69,0x37, 0x7,0x49,0x38, 0x7,0x49,0x45, + 0x5,0x69,0x3b, 0x5,0x69,0x35, 0x4,0x60,0x7c, 0x5,0x69,0x2e, + 0x5,0x6d,0x42, 0x7,0x49,0x43, 0x5,0x69,0x38, 0x7,0x49,0x46, + 0x5,0x69,0x39, 0x7,0x49,0x41, 0x7,0x49,0x54, 0x7,0x49,0x51, + 0x7,0x49,0x3c, 0x5,0x69,0x33, 0x5,0x69,0x3d, 0x7,0x49,0x4b, + 0x7,0x49,0x4e, 0x7,0x49,0x3e, 0x7,0x49,0x3d, 0x7,0x49,0x42, + 0x7,0x49,0x47, 0x7,0x4f,0x54, 0x7,0x49,0x4d, 0x7,0x49,0x39, + 0x7,0x49,0x4c, 0x7,0x49,0x4a, 0x7,0x4f,0x47, 0x5,0x69,0x34, + 0x5,0x69,0x32, 0x4,0x60,0x76, 0x5,0x69,0x3c, 0x7,0x49,0x49, + 0x7,0x49,0x40, 0x7,0x49,0x3f, 0x7,0x49,0x36, 0x7,0x49,0x37, + 0x7,0x49,0x3a, 0x7,0x49,0x48, 0x7,0x49,0x50, 0x7,0x49,0x52, + 0xf,0x63,0x51, 0xf,0x63,0x52, 0xf,0x63,0x54, 0xf,0x63,0x55, + 0xf,0x63,0x56, 0xf,0x63,0x57, 0xf,0x63,0x58, 0xf,0x63,0x59, + 0xf,0x63,0x5a, 0xf,0x63,0x5c, 0xf,0x63,0x5d, 0xf,0x63,0x5e, + 0xf,0x63,0x5f, 0xf,0x63,0x60, 0xf,0x63,0x61, 0xf,0x63,0x62, + 0xf,0x63,0x63, 0xf,0x63,0x64, 0xf,0x63,0x65, 0xf,0x63,0x66, + 0xf,0x63,0x67, 0xf,0x63,0x68, 0xf,0x63,0x69, 0x7,0x49,0x4f, + 0x7,0x4f,0x5e, 0x7,0x4f,0x55, 0x7,0x4f,0x4e, 0x5,0x6d,0x40, + 0x5,0x6d,0x47, 0x7,0x4f,0x61, 0x5,0x6d,0x41, 0x5,0x6d,0x44, + 0x4,0x64,0x39, 0x7,0x4f,0x58, 0x5,0x6d,0x46, 0x4,0x64,0x35, + 0x5,0x6d,0x3f, 0x5,0x70,0x7e, 0x7,0x4f,0x5f, 0x5,0x6d,0x3b, + 0x7,0x4f,0x51, 0x7,0x4f,0x50, 0x7,0x4f,0x4c, 0x5,0x6d,0x3e, + 0x5,0x6d,0x45, 0x7,0x4f,0x4d, 0x4,0x64,0x31, 0x7,0x4f,0x67, + 0x5,0x6d,0x3c, 0x7,0x4f,0x4b, 0x7,0x4f,0x53, 0x7,0x4f,0x62, + 0x7,0x4f,0x5b, 0x7,0x49,0x3b, 0x7,0x4f,0x65, 0x5,0x6d,0x43, + 0x4,0x64,0x2e, 0x7,0x4f,0x59, 0x5,0x6d,0x3d, 0x7,0x4f,0x66, + 0x7,0x4f,0x5a, 0x5,0x69,0x31, 0x7,0x54,0x67, 0x7,0x58,0x69, + 0x7,0x4f,0x49, 0x5,0x6d,0x3a, 0x5,0x6d,0x48, 0x7,0x4f,0x52, + 0x7,0x4f,0x56, 0x7,0x4f,0x57, 0x7,0x4f,0x5c, 0x7,0x4f,0x63, + 0x7,0x4f,0x64, 0xf,0x65,0x79, 0xf,0x65,0x7a, 0xf,0x65,0x7b, + 0xf,0x65,0x7c, 0xf,0x65,0x7d, 0xf,0x65,0x7e, 0xf,0x66,0x21, + 0xf,0x66,0x22, 0xf,0x66,0x23, 0xf,0x66,0x24, 0xf,0x66,0x25, + 0xf,0x66,0x26, 0xf,0x66,0x27, 0xf,0x66,0x28, 0xf,0x66,0x29, + 0xf,0x66,0x2a, 0xf,0x66,0x2b, 0xf,0x66,0x2c, 0x7,0x4f,0x4a, + 0x7,0x4f,0x48, 0x7,0x4f,0x60, 0x7,0x54,0x63, 0x4,0x69,0x35, + 0x5,0x71,0x28, 0x7,0x54,0x66, 0x7,0x54,0x5f, 0x5,0x71,0x24, + 0x4,0x67,0x2c, 0x4,0x67,0x2a, 0x7,0x54,0x59, 0x4,0x67,0x2e, + 0x5,0x71,0x22, 0x7,0x54,0x64, 0x5,0x71,0x25, 0x7,0x54,0x65, + 0x4,0x67,0x29, 0x5,0x6d,0x49, 0x5,0x71,0x27, 0x7,0x54,0x5b, + 0x7,0x54,0x53, 0x5,0x71,0x26, 0x7,0x54,0x62, 0x7,0x54,0x57, + 0x7,0x54,0x55, 0x7,0x54,0x60, 0x4,0x67,0x2d, 0x5,0x71,0x23, + 0x5,0x71,0x29, 0x5,0x71,0x2a, 0x7,0x54,0x54, 0x7,0x54,0x5c, + 0x7,0x4f,0x4f, 0x7,0x54,0x5a, 0x7,0x58,0x76, 0x5,0x71,0x21, + 0x7,0x54,0x56, 0x7,0x54,0x5d, 0x7,0x54,0x61, 0xf,0x68,0x38, + 0xf,0x68,0x3a, 0xf,0x68,0x3b, 0xf,0x68,0x3c, 0xf,0x68,0x3d, + 0xf,0x68,0x3e, 0xf,0x68,0x3f, 0xf,0x68,0x41, 0xf,0x68,0x42, + 0xf,0x68,0x43, 0xf,0x68,0x44, 0xf,0x68,0x40, 0x7,0x54,0x58, + 0x5,0x74,0x24, 0x4,0x69,0x36, 0x5,0x74,0x25, 0x5,0x74,0x27, + 0x5,0x74,0x28, 0x7,0x58,0x70, 0x5,0x74,0x29, 0x4,0x69,0x3b, + 0x4,0x69,0x3a, 0x7,0x58,0x77, 0x7,0x58,0x75, 0x7,0x58,0x6d, + 0x7,0x5c,0x53, 0x5,0x74,0x23, 0x5,0x74,0x26, 0x7,0x58,0x6f, + 0x4,0x69,0x38, 0x4,0x69,0x39, 0x7,0x58,0x6e, 0x4,0x69,0x34, + 0x7,0x58,0x73, 0x7,0x58,0x6b, 0x7,0x58,0x78, 0x7,0x58,0x6a, + 0x7,0x58,0x6c, 0x7,0x58,0x71, 0x7,0x58,0x74, 0xf,0x69,0x68, + 0xf,0x69,0x6b, 0xf,0x69,0x6c, 0x7,0x5c,0x4f, 0x7,0x5c,0x5a, + 0x4,0x6a,0x75, 0x5,0x76,0x40, 0x4,0x6a,0x74, 0x5,0x76,0x3f, + 0x4,0x6a,0x71, 0x4,0x6a,0x73, 0x4,0x6a,0x72, 0x4,0x6a,0x70, + 0x5,0x76,0x43, 0x7,0x5c,0x51, 0x7,0x5c,0x5b, 0x5,0x76,0x42, + 0x5,0x79,0x40, 0x7,0x5c,0x55, 0x5,0x76,0x44, 0x7,0x5c,0x57, + 0x7,0x5c,0x58, 0x7,0x5c,0x4d, 0x7,0x5c,0x50, 0x5,0x76,0x41, + 0x7,0x5c,0x56, 0x7,0x5c,0x54, 0x7,0x5c,0x52, 0x7,0x5c,0x59, + 0xf,0x6a,0x6d, 0xf,0x6a,0x6e, 0xf,0x6a,0x6f, 0x7,0x5c,0x4e, + 0xf,0x69,0x6a, 0x5,0x78,0x23, 0x5,0x78,0x22, 0x5,0x78,0x21, + 0x7,0x5f,0x40, 0x5,0x78,0x24, 0x7,0x5f,0x42, 0x7,0x5f,0x46, + 0x7,0x5f,0x43, 0x7,0x5f,0x44, 0x7,0x5f,0x49, 0x7,0x5f,0x41, + 0x7,0x5f,0x47, 0x5,0x79,0x42, 0xf,0x6b,0x60, 0xf,0x6b,0x61, + 0xf,0x6b,0x63, 0x7,0x5f,0x45, 0x7,0x5f,0x48, 0x5,0x79,0x43, + 0x7,0x62,0x55, 0x5,0x79,0x41, 0x7,0x62,0x53, 0x7,0x61,0x3e, + 0x7,0x61,0x3d, 0x7,0x61,0x3c, 0xf,0x6c,0x38, 0xf,0x6c,0x39, + 0x7,0x61,0x3f, 0x5,0x7a,0x35, 0x5,0x7a,0x36, 0x7,0x62,0x59, + 0x7,0x62,0x57, 0x7,0x62,0x56, 0x7,0x62,0x58, 0x7,0x62,0x54, + 0xf,0x6c,0x51, 0x7,0x62,0x48, 0x4,0x6d,0x7a, 0x7,0x63,0x68, + 0x5,0x7a,0x72, 0x4,0x6d,0x5f, 0x4,0x6d,0x7c, 0xf,0x6c,0x6b, + 0xf,0x6c,0x6d, 0x5,0x7b,0x46, 0x4,0x6e,0x35, 0x7,0x64,0x58, + 0x7,0x64,0x59, 0x5,0x7c,0x49, 0x7,0x65,0x40, 0x5,0x7b,0x66, + 0x7,0x65,0x60, 0x7,0x65,0x76, 0x5,0x7c,0x4f, 0x5,0x7c,0x3d, + 0x7,0x65,0x5f, 0xf,0x28,0x65, 0x4,0x2b,0x3f, 0x6,0x34,0x49, + 0x6,0x34,0x48, 0xf,0x32,0x4e, 0x5,0x35,0x36, 0x5,0x35,0x34, + 0x4,0x34,0x77, 0x4,0x34,0x76, 0x6,0x44,0x41, 0x4,0x34,0x78, + 0x6,0x44,0x42, 0x6,0x44,0x40, 0x6,0x44,0x3f, 0x6,0x3b,0x63, + 0x6,0x4e,0x3c, 0x5,0x3b,0x71, 0x6,0x4e,0x3d, 0xf,0x3f,0x22, + 0xf,0x3f,0x23, 0xf,0x3f,0x24, 0x5,0x42,0x55, 0x5,0x42,0x51, + 0x5,0x42,0x52, 0x6,0x57,0x6b, 0x6,0x57,0x6a, 0x6,0x57,0x69, + 0x5,0x49,0x4f, 0x6,0x61,0x62, 0x6,0x61,0x66, 0x4,0x46,0x6f, + 0x6,0x61,0x65, 0x6,0x61,0x67, 0x6,0x61,0x63, 0x6,0x61,0x64, + 0x5,0x49,0x50, 0xf,0x4c,0x2b, 0xf,0x4c,0x2c, 0x4,0x46,0x6e, + 0x7,0x28,0x29, 0x7,0x28,0x27, 0x7,0x32,0x5f, 0x5,0x50,0x4e, + 0x7,0x28,0x26, 0x7,0x28,0x28, 0xf,0x51,0x79, 0x7,0x26,0x29, + 0x5,0x57,0x6a, 0x5,0x57,0x6b, 0x5,0x57,0x68, 0x5,0x57,0x69, + 0x4,0x53,0x35, 0x5,0x57,0x67, 0x7,0x32,0x60, 0x7,0x32,0x5c, + 0x7,0x32,0x5d, 0x4,0x53,0x38, 0x4,0x53,0x37, 0x5,0x57,0x6d, + 0x7,0x32,0x5e, 0xf,0x57,0x5d, 0xf,0x57,0x5e, 0xf,0x57,0x5f, + 0x5,0x57,0x6c, 0x7,0x32,0x5b, 0x4,0x58,0x4c, 0x7,0x3b,0x39, + 0xf,0x5c,0x51, 0xf,0x5c,0x52, 0xf,0x5c,0x53, 0x7,0x42,0x51, + 0x5,0x64,0x3d, 0x4,0x5d,0x33, 0x7,0x42,0x50, 0x4,0x5d,0x31, + 0x7,0x42,0x52, 0x5,0x64,0x3c, 0xf,0x60,0x60, 0x7,0x49,0x56, + 0x7,0x49,0x55, 0x4,0x60,0x7e, 0x7,0x49,0x57, 0x7,0x4f,0x69, + 0x5,0x6d,0x4a, 0x7,0x4f,0x6a, 0x7,0x4c,0x26, 0x5,0x71,0x2c, + 0x7,0x4f,0x68, 0x5,0x71,0x2b, 0x5,0x70,0x4d, 0x7,0x54,0x6a, + 0x7,0x54,0x69, 0x5,0x74,0x2a, 0x7,0x5c,0x24, 0x4,0x6e,0x38, + 0x5,0x24,0x75, 0x6,0x29,0x29, 0x4,0x28,0x22, 0x6,0x2e,0x25, + 0xf,0x28,0x66, 0xf,0x28,0x67, 0xf,0x28,0x69, 0xf,0x28,0x6a, + 0x4,0x2b,0x43, 0x6,0x34,0x4b, 0x4,0x2b,0x40, 0x4,0x2b,0x42, + 0x6,0x34,0x4a, 0x5,0x2b,0x40, 0x6,0x34,0x4d, 0x6,0x34,0x4c, + 0x6,0x34,0x4e, 0xf,0x2d,0x3d, 0xf,0x2d,0x3f, 0xf,0x2d,0x42, + 0xf,0x2d,0x43, 0xf,0x2d,0x44, 0xf,0x2d,0x41, 0x4,0x2b,0x41, + 0x5,0x30,0x30, 0x6,0x3b,0x68, 0x5,0x30,0x2c, 0x5,0x30,0x33, + 0x6,0x3b,0x67, 0x5,0x30,0x2d, 0x5,0x30,0x32, 0x6,0x3b,0x66, + 0x4,0x2f,0x6c, 0x4,0x2f,0x6a, 0x4,0x2f,0x6e, 0x5,0x30,0x2e, + 0x6,0x3b,0x70, 0x5,0x30,0x29, 0x6,0x3b,0x6b, 0x5,0x30,0x31, + 0x5,0x30,0x28, 0x6,0x3b,0x6a, 0x5,0x30,0x2f, 0x5,0x30,0x34, + 0x6,0x3b,0x6e, 0x6,0x3b,0x64, 0x5,0x30,0x2b, 0x6,0x3b,0x65, + 0xf,0x32,0x4f, 0x6,0x3b,0x6c, 0x6,0x3b,0x6d, 0x5,0x30,0x2a, + 0x6,0x3b,0x6f, 0x5,0x35,0x37, 0x4,0x34,0x7d, 0x6,0x44,0x45, + 0x5,0x35,0x38, 0x5,0x35,0x39, 0x5,0x35,0x3a, 0x5,0x35,0x40, + 0x4,0x35,0x22, 0xf,0x38,0x3d, 0x4,0x35,0x23, 0x6,0x44,0x4c, + 0x5,0x35,0x3c, 0x4,0x35,0x21, 0x5,0x35,0x3d, 0x6,0x44,0x46, + 0x5,0x35,0x41, 0x6,0x44,0x49, 0x4,0x35,0x24, 0x4,0x34,0x7e, + 0x6,0x44,0x47, 0x6,0x44,0x4a, 0x6,0x44,0x44, 0x6,0x44,0x4b, + 0x6,0x44,0x4d, 0xf,0x38,0x36, 0xf,0x38,0x37, 0xf,0x38,0x38, + 0xf,0x38,0x39, 0xf,0x38,0x3b, 0xf,0x38,0x3c, 0xf,0x38,0x3e, + 0xf,0x38,0x3f, 0xf,0x38,0x40, 0x5,0x35,0x3e, 0x6,0x44,0x4e, + 0x4,0x35,0x25, 0x6,0x44,0x43, 0x5,0x35,0x3f, 0x5,0x35,0x3b, + 0x5,0x3b,0x73, 0x6,0x4e,0x40, 0xf,0x3f,0x28, 0x4,0x3a,0x73, + 0x6,0x4e,0x48, 0x5,0x3c,0x28, 0x5,0x3b,0x78, 0x5,0x3b,0x75, + 0x5,0x3b,0x77, 0x5,0x3b,0x7a, 0x5,0x3c,0x23, 0x5,0x3b,0x7d, + 0x6,0x4e,0x49, 0x6,0x4e,0x3e, 0x6,0x4e,0x43, 0x5,0x3b,0x76, + 0x5,0x3c,0x27, 0x6,0x4e,0x42, 0x6,0x4e,0x4b, 0x6,0x4e,0x4a, + 0x5,0x3b,0x7c, 0x6,0x4e,0x3f, 0x5,0x3b,0x79, 0x5,0x3c,0x21, + 0x6,0x4e,0x4d, 0x6,0x4e,0x44, 0x6,0x4e,0x45, 0x6,0x57,0x6e, + 0x5,0x3c,0x25, 0x5,0x3b,0x7e, 0x6,0x57,0x78, 0x5,0x3c,0x24, + 0x6,0x4e,0x4c, 0x6,0x4e,0x47, 0x5,0x3c,0x22, 0x5,0x3b,0x72, + 0x6,0x4e,0x41, 0xf,0x3f,0x25, 0xf,0x3f,0x26, 0xf,0x3f,0x27, + 0xf,0x3f,0x29, 0x4,0x3a,0x77, 0x6,0x57,0x70, 0x6,0x57,0x6f, + 0x4,0x40,0x5a, 0x4,0x40,0x5c, 0x6,0x57,0x74, 0x4,0x40,0x54, + 0x5,0x42,0x58, 0x5,0x42,0x5b, 0x5,0x42,0x56, 0x4,0x40,0x51, + 0x4,0x40,0x53, 0x5,0x42,0x5c, 0x5,0x42,0x5e, 0x5,0x42,0x5a, + 0x5,0x42,0x57, 0x4,0x40,0x5e, 0x4,0x40,0x50, 0x6,0x57,0x72, + 0x6,0x57,0x73, 0x6,0x57,0x6c, 0x6,0x57,0x6d, 0x6,0x61,0x68, + 0x6,0x57,0x71, 0x6,0x57,0x75, 0x5,0x42,0x59, 0xf,0x45,0x32, + 0xf,0x45,0x33, 0xf,0x45,0x34, 0xf,0x45,0x35, 0xf,0x45,0x36, + 0xf,0x45,0x37, 0xf,0x45,0x38, 0xf,0x45,0x39, 0x6,0x57,0x76, + 0x7,0x49,0x6b, 0x6,0x57,0x77, 0x6,0x57,0x79, 0x5,0x49,0x51, + 0x5,0x49,0x56, 0x5,0x49,0x5b, 0x5,0x49,0x57, 0x5,0x49,0x5c, + 0x4,0x47,0x21, 0x5,0x49,0x55, 0x4,0x46,0x7d, 0x6,0x62,0x23, + 0x5,0x49,0x5f, 0x4,0x46,0x77, 0x5,0x49,0x59, 0x4,0x46,0x74, + 0x6,0x61,0x76, 0x6,0x61,0x6a, 0x6,0x61,0x75, 0x4,0x47,0x22, + 0x5,0x49,0x5e, 0x6,0x61,0x6b, 0x6,0x61,0x71, 0x5,0x49,0x54, + 0x6,0x61,0x7c, 0x5,0x49,0x5d, 0x5,0x49,0x58, 0x6,0x61,0x7b, + 0x6,0x62,0x21, 0x5,0x49,0x60, 0x6,0x61,0x74, 0x6,0x61,0x7d, + 0x6,0x61,0x6d, 0x5,0x49,0x61, 0x5,0x49,0x62, 0x6,0x61,0x72, + 0x6,0x62,0x22, 0x5,0x49,0x5a, 0x6,0x61,0x6c, 0x6,0x61,0x79, + 0x6,0x61,0x7a, 0x6,0x61,0x70, 0x5,0x49,0x52, 0x6,0x61,0x6e, + 0x5,0x49,0x53, 0x6,0x61,0x73, 0xf,0x4c,0x2d, 0xf,0x4c,0x2e, + 0xf,0x4c,0x30, 0xf,0x4c,0x31, 0xf,0x4c,0x32, 0x6,0x61,0x78, + 0x4,0x40,0x58, 0x6,0x61,0x7e, 0x6,0x61,0x6f, 0x4,0x4d,0x2d, + 0x7,0x28,0x43, 0x5,0x50,0x53, 0x4,0x4d,0x2e, 0x4,0x4d,0x2b, + 0x7,0x28,0x38, 0x4,0x4d,0x34, 0x5,0x50,0x5f, 0x7,0x28,0x37, + 0x7,0x28,0x2c, 0x5,0x50,0x51, 0x7,0x28,0x2b, 0x7,0x28,0x35, + 0x7,0x28,0x3f, 0x5,0x50,0x57, 0x4,0x4d,0x32, 0x4,0x4d,0x2a, + 0x7,0x28,0x40, 0x7,0x28,0x34, 0x5,0x50,0x56, 0x7,0x28,0x3b, + 0x7,0x28,0x31, 0x7,0x28,0x3e, 0x5,0x57,0x6e, 0x4,0x4d,0x2c, + 0x4,0x4d,0x29, 0x5,0x50,0x5c, 0x5,0x50,0x5a, 0x5,0x50,0x50, + 0x5,0x50,0x59, 0x5,0x50,0x58, 0x7,0x28,0x2a, 0x5,0x50,0x5b, + 0x4,0x46,0x7a, 0x5,0x50,0x52, 0x5,0x50,0x5e, 0x5,0x50,0x5d, + 0x4,0x4d,0x35, 0x7,0x28,0x46, 0x7,0x28,0x30, 0x7,0x28,0x2d, + 0x7,0x28,0x44, 0x7,0x28,0x39, 0x7,0x28,0x45, 0x7,0x28,0x3c, + 0x7,0x28,0x2f, 0x6,0x61,0x77, 0x7,0x28,0x36, 0x7,0x28,0x3d, + 0x5,0x50,0x54, 0x4,0x4d,0x27, 0x5,0x50,0x4f, 0xf,0x51,0x7a, + 0xf,0x51,0x7b, 0xf,0x51,0x7e, 0xf,0x52,0x21, 0xf,0x52,0x22, + 0xf,0x52,0x23, 0xf,0x52,0x25, 0xf,0x52,0x28, 0xf,0x52,0x29, + 0xf,0x52,0x2a, 0xf,0x52,0x2b, 0x7,0x28,0x33, 0x7,0x28,0x41, + 0x7,0x28,0x3a, 0xf,0x52,0x27, 0x7,0x28,0x32, 0xf,0x4c,0x2f, + 0x5,0x57,0x70, 0x4,0x53,0x45, 0x5,0x57,0x76, 0x5,0x57,0x75, + 0x4,0x53,0x3a, 0x5,0x57,0x74, 0x5,0x57,0x71, 0x7,0x32,0x6e, + 0x7,0x32,0x7d, 0x5,0x57,0x77, 0x4,0x53,0x48, 0x5,0x57,0x7b, + 0x4,0x53,0x49, 0x4,0x53,0x40, 0x4,0x53,0x42, 0x5,0x57,0x7c, + 0x7,0x32,0x6d, 0x4,0x53,0x3b, 0x7,0x32,0x67, 0x4,0x53,0x3f, + 0x7,0x32,0x7c, 0x5,0x57,0x79, 0x5,0x57,0x6f, 0x5,0x58,0x21, + 0x5,0x57,0x72, 0x7,0x3b,0x3a, 0x5,0x57,0x78, 0x7,0x32,0x69, + 0x4,0x53,0x46, 0x5,0x57,0x7a, 0x7,0x32,0x70, 0x7,0x33,0x22, + 0x5,0x57,0x73, 0x7,0x32,0x64, 0x5,0x57,0x7e, 0x7,0x32,0x74, + 0x4,0x53,0x47, 0x5,0x50,0x60, 0x7,0x32,0x6b, 0x7,0x32,0x65, + 0x5,0x57,0x7d, 0x7,0x32,0x76, 0x4,0x53,0x43, 0x7,0x32,0x7b, + 0x7,0x33,0x24, 0x7,0x32,0x62, 0x7,0x32,0x77, 0x7,0x32,0x63, + 0x7,0x32,0x78, 0x7,0x32,0x6f, 0x7,0x32,0x7e, 0x7,0x32,0x72, + 0x7,0x32,0x68, 0x7,0x33,0x23, 0xf,0x57,0x60, 0xf,0x57,0x61, + 0xf,0x57,0x63, 0xf,0x57,0x64, 0xf,0x57,0x65, 0xf,0x57,0x66, + 0x7,0x32,0x79, 0x7,0x32,0x6a, 0x7,0x32,0x7a, 0x7,0x32,0x71, + 0x7,0x32,0x66, 0x7,0x32,0x6c, 0x4,0x58,0x59, 0x5,0x5e,0x29, + 0x5,0x5e,0x2c, 0x4,0x58,0x55, 0x7,0x3b,0x52, 0x7,0x3b,0x44, + 0x4,0x58,0x60, 0x4,0x58,0x5c, 0x7,0x3b,0x48, 0x7,0x3b,0x42, + 0x7,0x3b,0x55, 0x4,0x58,0x5e, 0x7,0x3b,0x46, 0x7,0x28,0x47, + 0x4,0x58,0x50, 0x5,0x5e,0x31, 0x7,0x3b,0x50, 0x7,0x3b,0x3f, + 0x4,0x58,0x5d, 0x7,0x3b,0x4f, 0x5,0x5e,0x2b, 0x5,0x5e,0x2f, + 0x7,0x3b,0x53, 0x4,0x58,0x5a, 0x7,0x3b,0x47, 0x7,0x3b,0x41, + 0x5,0x5e,0x33, 0x4,0x58,0x53, 0x7,0x3b,0x40, 0x4,0x58,0x51, + 0x7,0x3b,0x3e, 0x7,0x3b,0x54, 0x5,0x5e,0x2a, 0x7,0x3b,0x3c, + 0x7,0x3b,0x3b, 0x7,0x3b,0x49, 0x4,0x58,0x5b, 0x5,0x5e,0x2d, + 0x5,0x5e,0x2e, 0x7,0x3b,0x45, 0xf,0x5c,0x54, 0xf,0x5c,0x55, + 0xf,0x5c,0x56, 0xf,0x5c,0x57, 0xf,0x5c,0x58, 0xf,0x5c,0x59, + 0xf,0x5c,0x5a, 0xf,0x5c,0x5c, 0x7,0x3b,0x43, 0x7,0x3b,0x4b, + 0x7,0x3b,0x4e, 0x7,0x3b,0x51, 0x7,0x3b,0x3d, 0x5,0x5e,0x28, + 0x7,0x3b,0x4a, 0x7,0x3b,0x4c, 0x5,0x5e,0x30, 0x4,0x5d,0x3d, + 0x4,0x5d,0x37, 0x7,0x42,0x55, 0x7,0x42,0x61, 0x7,0x42,0x58, + 0x7,0x42,0x68, 0x5,0x64,0x43, 0x5,0x64,0x44, 0x5,0x5e,0x34, + 0x4,0x5d,0x38, 0x5,0x64,0x50, 0x7,0x42,0x59, 0x4,0x5d,0x36, + 0x5,0x64,0x45, 0x4,0x5d,0x35, 0x4,0x5d,0x3a, 0x5,0x64,0x3f, + 0x5,0x64,0x42, 0x5,0x64,0x4d, 0x4,0x5d,0x34, 0x5,0x64,0x4a, + 0x7,0x42,0x56, 0x5,0x64,0x3e, 0x5,0x64,0x41, 0x5,0x64,0x4b, + 0x7,0x42,0x57, 0x7,0x42,0x5c, 0x7,0x42,0x5b, 0x5,0x64,0x40, + 0x7,0x42,0x6f, 0x7,0x42,0x6b, 0x5,0x64,0x4f, 0x7,0x42,0x6e, + 0x5,0x64,0x49, 0x5,0x64,0x4c, 0x7,0x42,0x69, 0x5,0x64,0x46, + 0x7,0x42,0x6c, 0x5,0x64,0x47, 0x7,0x42,0x65, 0x7,0x42,0x62, + 0x7,0x42,0x5d, 0x7,0x42,0x63, 0x7,0x42,0x54, 0x7,0x42,0x5a, + 0x7,0x42,0x53, 0x7,0x42,0x5e, 0x7,0x42,0x6a, 0x7,0x42,0x66, + 0xf,0x60,0x62, 0xf,0x60,0x64, 0xf,0x60,0x65, 0xf,0x60,0x66, + 0xf,0x60,0x68, 0xf,0x60,0x69, 0xf,0x60,0x6a, 0x7,0x42,0x64, + 0x4,0x5d,0x3c, 0x7,0x42,0x67, 0xf,0x60,0x67, 0xf,0x60,0x61, + 0x5,0x64,0x4e, 0x4,0x61,0x28, 0x7,0x49,0x6a, 0x7,0x49,0x59, + 0x7,0x49,0x60, 0x7,0x49,0x6c, 0x7,0x49,0x5a, 0x7,0x49,0x69, + 0x7,0x49,0x6d, 0x4,0x61,0x23, 0x5,0x69,0x42, 0x5,0x69,0x40, + 0x7,0x49,0x62, 0x7,0x49,0x67, 0x7,0x49,0x65, 0x5,0x69,0x44, + 0x7,0x49,0x5d, 0x7,0x49,0x68, 0x7,0x49,0x64, 0x7,0x49,0x66, + 0x7,0x4f,0x6b, 0x7,0x49,0x61, 0x7,0x49,0x6e, 0x7,0x49,0x6f, + 0x7,0x49,0x63, 0x5,0x69,0x45, 0x7,0x49,0x5c, 0x7,0x49,0x5f, + 0x7,0x49,0x58, 0xf,0x63,0x6b, 0xf,0x63,0x6c, 0xf,0x63,0x6d, + 0xf,0x63,0x6f, 0xf,0x63,0x70, 0xf,0x63,0x71, 0xf,0x63,0x72, + 0xf,0x63,0x73, 0xf,0x63,0x74, 0xf,0x63,0x75, 0x7,0x49,0x5b, + 0x4,0x61,0x22, 0x4,0x61,0x27, 0x7,0x49,0x5e, 0x7,0x42,0x70, + 0x7,0x4f,0x75, 0x7,0x4f,0x7a, 0x5,0x6d,0x4d, 0x7,0x4f,0x6c, + 0x4,0x64,0x42, 0x5,0x6d,0x4c, 0x5,0x6d,0x51, 0x7,0x4f,0x78, + 0x7,0x4f,0x70, 0x5,0x6d,0x50, 0x7,0x4f,0x74, 0x5,0x6d,0x52, + 0x5,0x6d,0x53, 0x7,0x4f,0x73, 0x5,0x6d,0x4e, 0x7,0x4f,0x72, + 0x7,0x4f,0x77, 0x7,0x4f,0x71, 0x7,0x4f,0x6d, 0x5,0x6d,0x4f, + 0x7,0x4f,0x6f, 0x7,0x54,0x77, 0x7,0x4f,0x6e, 0x7,0x4f,0x7b, + 0xf,0x66,0x2d, 0xf,0x66,0x2e, 0xf,0x66,0x2f, 0xf,0x66,0x30, + 0xf,0x66,0x31, 0x7,0x4f,0x76, 0x4,0x67,0x2f, 0x4,0x67,0x34, + 0x7,0x54,0x6b, 0x7,0x54,0x70, 0x5,0x71,0x2f, 0x7,0x54,0x75, + 0x7,0x54,0x6e, 0x7,0x54,0x71, 0x5,0x71,0x2e, 0x7,0x54,0x73, + 0x5,0x71,0x2d, 0x5,0x71,0x30, 0x7,0x54,0x6c, 0x4,0x67,0x33, + 0x7,0x54,0x6f, 0x4,0x67,0x35, 0x4,0x67,0x31, 0x7,0x54,0x72, + 0x5,0x71,0x32, 0x7,0x54,0x78, 0x7,0x4f,0x79, 0x7,0x54,0x74, + 0x4,0x67,0x32, 0x7,0x54,0x79, 0x5,0x71,0x31, 0x5,0x71,0x33, + 0x7,0x54,0x76, 0xf,0x68,0x45, 0xf,0x68,0x46, 0xf,0x68,0x47, + 0xf,0x68,0x48, 0xf,0x68,0x49, 0x7,0x54,0x6d, 0x5,0x74,0x2e, + 0x4,0x69,0x3c, 0x5,0x74,0x2c, 0x5,0x74,0x2b, 0x7,0x59,0x23, + 0x7,0x58,0x7c, 0x5,0x74,0x2d, 0x5,0x74,0x31, 0x5,0x74,0x30, + 0x7,0x58,0x7a, 0x5,0x74,0x33, 0x5,0x74,0x35, 0x5,0x74,0x32, + 0x7,0x58,0x79, 0x4,0x69,0x3d, 0x7,0x59,0x26, 0x7,0x59,0x28, + 0x7,0x59,0x27, 0x7,0x58,0x7e, 0x7,0x59,0x21, 0x5,0x74,0x34, + 0x5,0x74,0x36, 0x7,0x59,0x24, 0x7,0x59,0x29, 0x5,0x74,0x2f, + 0x7,0x58,0x7d, 0x7,0x58,0x7b, 0xf,0x69,0x6d, 0xf,0x69,0x6e, + 0x5,0x76,0x46, 0x4,0x6a,0x76, 0x4,0x6a,0x77, 0x7,0x5c,0x5d, + 0x5,0x76,0x47, 0x4,0x6a,0x79, 0x7,0x5c,0x5f, 0x7,0x5c,0x5c, + 0x5,0x76,0x48, 0x7,0x5c,0x62, 0x5,0x76,0x45, 0x7,0x5f,0x4a, + 0x7,0x5c,0x60, 0x4,0x6a,0x7a, 0x7,0x5c,0x61, 0x5,0x76,0x4a, + 0x7,0x59,0x22, 0x5,0x76,0x49, 0xf,0x6a,0x70, 0xf,0x6a,0x71, + 0xf,0x6a,0x72, 0x5,0x78,0x2c, 0x7,0x5f,0x4b, 0x4,0x6b,0x7e, + 0x5,0x78,0x2b, 0x5,0x78,0x29, 0x7,0x5f,0x4c, 0x5,0x78,0x26, + 0x4,0x6c,0x22, 0x7,0x5f,0x4d, 0x5,0x78,0x2a, 0x5,0x78,0x28, + 0x4,0x6c,0x24, 0x5,0x78,0x2d, 0x5,0x78,0x27, 0x5,0x79,0x44, + 0x4,0x6c,0x7e, 0x5,0x79,0x48, 0x5,0x79,0x4a, 0x4,0x6c,0x21, + 0x7,0x61,0x40, 0x5,0x79,0x46, 0x7,0x61,0x44, 0x7,0x61,0x43, + 0x7,0x61,0x45, 0x5,0x79,0x47, 0x5,0x79,0x49, 0x7,0x61,0x41, + 0x5,0x79,0x45, 0x7,0x62,0x5d, 0x7,0x62,0x5b, 0x7,0x62,0x5e, + 0x7,0x62,0x5c, 0x7,0x62,0x5f, 0x7,0x63,0x6e, 0x7,0x63,0x6c, + 0x5,0x7a,0x73, 0x7,0x63,0x6b, 0x7,0x63,0x6f, 0x7,0x62,0x5a, + 0x7,0x63,0x69, 0x7,0x63,0x71, 0x7,0x63,0x6a, 0x7,0x63,0x70, + 0x7,0x63,0x6d, 0x7,0x64,0x5c, 0x4,0x6e,0x3a, 0x7,0x64,0x5d, + 0x5,0x7b,0x47, 0x5,0x7b,0x48, 0x7,0x64,0x5a, 0x7,0x64,0x5b, + 0x5,0x7b,0x67, 0x7,0x65,0x41, 0x7,0x65,0x42, 0x5,0x7b,0x68, + 0x4,0x6e,0x50, 0x7,0x65,0x62, 0x7,0x65,0x61, 0xf,0x6d,0x31, + 0x7,0x66,0x2b, 0x5,0x27,0x65, 0x6,0x2e,0x27, 0x6,0x2e,0x26, + 0x4,0x2b,0x44, 0x6,0x3b,0x72, 0x5,0x30,0x35, 0x6,0x3b,0x75, + 0x6,0x3b,0x74, 0xf,0x38,0x41, 0x6,0x4e,0x4e, 0x6,0x4e,0x50, + 0x5,0x42,0x5f, 0x6,0x57,0x7c, 0x6,0x57,0x7a, 0x6,0x57,0x7d, + 0x6,0x57,0x7b, 0x5,0x49,0x65, 0x5,0x49,0x63, 0x5,0x49,0x64, + 0x6,0x62,0x26, 0x6,0x62,0x24, 0x7,0x28,0x48, 0x5,0x50,0x61, + 0x7,0x28,0x49, 0x7,0x28,0x4a, 0x6,0x62,0x25, 0x5,0x58,0x23, + 0x5,0x58,0x24, 0x5,0x58,0x22, 0x7,0x33,0x25, 0x7,0x33,0x26, + 0x5,0x5e,0x37, 0x5,0x5e,0x36, 0xf,0x5c,0x5d, 0x4,0x5d,0x3e, + 0x4,0x5d,0x3f, 0x7,0x42,0x71, 0x7,0x42,0x73, 0x4,0x5d,0x40, + 0x7,0x42,0x72, 0x5,0x69,0x46, 0x5,0x6d,0x54, 0x7,0x4f,0x7c, + 0x7,0x54,0x7a, 0x7,0x59,0x2b, 0x7,0x59,0x2a, 0x7,0x5f,0x4e, + 0x7,0x65,0x63, 0x4,0x28,0x23, 0x6,0x2e,0x28, 0x4,0x28,0x24, + 0x6,0x34,0x4f, 0x6,0x34,0x50, 0x5,0x2b,0x41, 0xf,0x2d,0x45, + 0x5,0x30,0x36, 0x6,0x3b,0x77, 0x6,0x3b,0x76, 0x5,0x30,0x37, + 0x6,0x44,0x4f, 0x5,0x3c,0x29, 0x6,0x4e,0x53, 0x6,0x4e,0x52, + 0xf,0x3f,0x2a, 0xf,0x3f,0x2b, 0x6,0x4e,0x51, 0x6,0x58,0x23, + 0x6,0x58,0x21, 0x4,0x40,0x5f, 0x6,0x58,0x22, 0x6,0x57,0x7e, + 0xf,0x45,0x3a, 0x4,0x47,0x24, 0x5,0x50,0x62, 0x6,0x62,0x27, + 0x6,0x62,0x28, 0x4,0x58,0x61, 0x7,0x3b,0x56, 0xf,0x5c,0x5e, + 0x4,0x5d,0x41, 0x7,0x42,0x74, 0x7,0x49,0x70, 0x7,0x54,0x7b, + 0x7,0x5c,0x64, 0x5,0x27,0x66, 0x6,0x2e,0x29, 0x6,0x2e,0x2a, + 0x6,0x2e,0x2b, 0x5,0x2b,0x43, 0x6,0x34,0x51, 0x4,0x2b,0x45, + 0x4,0x2b,0x47, 0x5,0x2b,0x45, 0x6,0x34,0x53, 0x5,0x2b,0x44, + 0xf,0x28,0x6b, 0x6,0x34,0x52, 0x5,0x2b,0x42, 0x5,0x2b,0x46, + 0x6,0x3b,0x7d, 0x5,0x30,0x3c, 0x4,0x2f,0x71, 0x6,0x3c,0x21, + 0x6,0x3c,0x25, 0x5,0x30,0x3f, 0x6,0x3c,0x26, 0x6,0x3c,0x27, + 0x4,0x2f,0x70, 0x6,0x3b,0x79, 0x5,0x30,0x40, 0x6,0x3b,0x7b, + 0x5,0x30,0x38, 0x6,0x3c,0x22, 0x6,0x3b,0x7c, 0x6,0x3c,0x23, + 0x6,0x3b,0x7e, 0x5,0x30,0x3b, 0x6,0x3b,0x7a, 0x6,0x3b,0x78, + 0x5,0x30,0x3a, 0xf,0x32,0x50, 0x6,0x3c,0x24, 0x6,0x3c,0x28, + 0x6,0x3c,0x29, 0xf,0x2d,0x48, 0xf,0x2d,0x49, 0xf,0x32,0x52, + 0x4,0x35,0x28, 0x5,0x3c,0x32, 0x4,0x35,0x2b, 0x4,0x3a,0x7c, + 0x5,0x35,0x46, 0x4,0x35,0x29, 0x6,0x44,0x58, 0x5,0x35,0x47, + 0x5,0x35,0x4a, 0x5,0x35,0x44, 0x5,0x35,0x45, 0x5,0x35,0x43, + 0x6,0x44,0x59, 0x6,0x44,0x5a, 0x5,0x35,0x42, 0x6,0x44,0x53, + 0x6,0x44,0x55, 0x6,0x44,0x54, 0x6,0x44,0x51, 0x6,0x44,0x50, + 0x6,0x44,0x57, 0x6,0x44,0x52, 0xf,0x2d,0x46, 0xf,0x38,0x45, + 0x5,0x35,0x48, 0x6,0x44,0x56, 0x5,0x35,0x49, 0x5,0x3c,0x31, + 0x6,0x4e,0x5b, 0x6,0x4e,0x59, 0x5,0x3c,0x2e, 0x6,0x4e,0x57, + 0x5,0x3c,0x2f, 0x5,0x3c,0x33, 0x4,0x3a,0x7e, 0x6,0x4e,0x58, + 0x6,0x4e,0x54, 0x4,0x3a,0x7d, 0x6,0x4e,0x56, 0x5,0x3c,0x30, + 0x5,0x3c,0x2d, 0x5,0x3c,0x2b, 0x5,0x42,0x64, 0x5,0x3c,0x2a, + 0xf,0x38,0x44, 0xf,0x3f,0x2e, 0x6,0x4e,0x55, 0x6,0x4e,0x5a, + 0x6,0x4e,0x5c, 0x5,0x3c,0x2c, 0xf,0x38,0x43, 0x5,0x42,0x6a, + 0x5,0x42,0x62, 0x5,0x42,0x66, 0x4,0x40,0x65, 0x5,0x42,0x6b, + 0x5,0x42,0x63, 0x5,0x42,0x67, 0x4,0x40,0x63, 0x5,0x42,0x65, + 0x5,0x42,0x69, 0x6,0x58,0x2f, 0x4,0x40,0x64, 0x6,0x58,0x2a, + 0x6,0x58,0x28, 0x6,0x58,0x30, 0x5,0x42,0x68, 0x5,0x42,0x60, + 0x6,0x58,0x24, 0x6,0x58,0x27, 0x6,0x58,0x2d, 0xf,0x3f,0x2c, + 0xf,0x3f,0x2d, 0xf,0x3f,0x2f, 0xf,0x3f,0x30, 0xf,0x45,0x3b, + 0x6,0x58,0x26, 0x6,0x58,0x31, 0x6,0x58,0x25, 0x6,0x58,0x29, + 0x5,0x42,0x61, 0xf,0x45,0x3e, 0x4,0x47,0x30, 0x4,0x47,0x2c, + 0x6,0x62,0x2d, 0x6,0x62,0x33, 0x4,0x47,0x29, 0x5,0x49,0x66, + 0x5,0x49,0x69, 0x4,0x47,0x28, 0x5,0x49,0x68, 0x5,0x3c,0x34, + 0x6,0x62,0x34, 0x5,0x49,0x6a, 0x6,0x62,0x2b, 0x6,0x62,0x29, + 0x6,0x62,0x2a, 0x6,0x62,0x32, 0x6,0x62,0x31, 0x5,0x49,0x67, + 0x6,0x62,0x2f, 0x5,0x49,0x6b, 0x6,0x62,0x30, 0x6,0x62,0x2c, + 0x4,0x47,0x33, 0x6,0x62,0x35, 0x6,0x62,0x2e, 0xf,0x4c,0x34, + 0xf,0x4c,0x36, 0xf,0x4c,0x37, 0x4,0x47,0x2f, 0xf,0x45,0x3c, + 0xf,0x45,0x3f, 0x5,0x50,0x66, 0x7,0x28,0x54, 0x4,0x4d,0x41, + 0x5,0x50,0x69, 0x7,0x28,0x57, 0x4,0x47,0x32, 0x7,0x28,0x56, + 0x5,0x50,0x65, 0x4,0x4d,0x38, 0x7,0x28,0x55, 0x7,0x33,0x28, + 0x5,0x50,0x67, 0x7,0x28,0x5a, 0x7,0x28,0x4b, 0x4,0x4d,0x45, + 0x4,0x4d,0x3b, 0x4,0x4d,0x3d, 0x7,0x28,0x53, 0x4,0x4d,0x44, + 0x4,0x4d,0x43, 0x5,0x50,0x63, 0x7,0x28,0x58, 0x7,0x28,0x52, + 0x7,0x28,0x4c, 0x5,0x50,0x64, 0x7,0x28,0x4f, 0x5,0x50,0x68, + 0x7,0x28,0x51, 0x7,0x28,0x50, 0x7,0x28,0x4d, 0xf,0x4c,0x35, + 0xf,0x52,0x2d, 0x7,0x28,0x4e, 0x7,0x28,0x59, 0x5,0x58,0x2c, + 0x5,0x58,0x2b, 0x7,0x33,0x2b, 0x5,0x58,0x27, 0x5,0x58,0x2a, + 0x7,0x33,0x27, 0x4,0x53,0x51, 0x7,0x33,0x29, 0x4,0x53,0x54, + 0x7,0x3b,0x62, 0x5,0x58,0x29, 0x5,0x58,0x28, 0x7,0x33,0x2a, + 0x4,0x53,0x4e, 0x7,0x33,0x2c, 0x7,0x33,0x2f, 0x4,0x53,0x4d, + 0x5,0x58,0x25, 0x7,0x33,0x30, 0x5,0x58,0x26, 0x7,0x33,0x2e, + 0xf,0x52,0x2c, 0x7,0x33,0x2d, 0x5,0x5e,0x3e, 0x5,0x5e,0x3f, + 0x7,0x3b,0x57, 0x5,0x5e,0x3b, 0x7,0x3b,0x5d, 0x7,0x3b,0x64, + 0x4,0x58,0x66, 0x5,0x5e,0x38, 0x5,0x5e,0x39, 0x5,0x5e,0x3d, + 0x5,0x5e,0x3c, 0x7,0x3b,0x5f, 0x7,0x3b,0x5b, 0x7,0x3b,0x63, + 0x7,0x42,0x7b, 0x7,0x3b,0x5c, 0x7,0x28,0x5b, 0x7,0x3b,0x5e, + 0x7,0x3b,0x60, 0x5,0x5e,0x40, 0x7,0x3b,0x58, 0x7,0x3b,0x5a, + 0x5,0x5e,0x3a, 0xf,0x57,0x67, 0xf,0x57,0x68, 0xf,0x57,0x69, + 0xf,0x57,0x6a, 0x7,0x42,0x75, 0x4,0x5d,0x45, 0x7,0x42,0x7c, + 0x7,0x42,0x7e, 0x5,0x64,0x5b, 0x5,0x64,0x57, 0x7,0x42,0x7d, + 0x4,0x5d,0x4b, 0x5,0x64,0x54, 0x5,0x64,0x55, 0x5,0x64,0x5f, + 0x4,0x5d,0x4d, 0x4,0x5d,0x42, 0x7,0x42,0x7a, 0x5,0x64,0x53, + 0x4,0x5d,0x47, 0x4,0x5d,0x4c, 0x5,0x64,0x5d, 0x7,0x42,0x79, + 0x7,0x42,0x77, 0x5,0x64,0x51, 0x4,0x5d,0x43, 0x5,0x5e,0x42, + 0x5,0x64,0x52, 0x7,0x42,0x78, 0x7,0x43,0x23, 0x7,0x42,0x76, + 0x5,0x64,0x59, 0x5,0x64,0x5a, 0x5,0x5e,0x41, 0x5,0x64,0x5c, + 0x5,0x64,0x5e, 0x5,0x64,0x58, 0xf,0x5c,0x60, 0x7,0x49,0x76, + 0x5,0x69,0x49, 0x5,0x69,0x4a, 0x4,0x61,0x29, 0x7,0x49,0x7b, + 0x7,0x49,0x7c, 0x5,0x69,0x47, 0x5,0x69,0x48, 0x7,0x49,0x72, + 0x7,0x49,0x73, 0x7,0x49,0x75, 0x7,0x49,0x79, 0x7,0x49,0x7a, + 0x7,0x49,0x74, 0x7,0x49,0x78, 0x4,0x61,0x2b, 0x7,0x49,0x77, + 0x7,0x43,0x21, 0xf,0x60,0x6b, 0xf,0x60,0x6c, 0xf,0x63,0x76, + 0x7,0x4f,0x7d, 0x5,0x6d,0x58, 0x7,0x50,0x26, 0x5,0x6d,0x5b, + 0x5,0x71,0x34, 0x5,0x6d,0x55, 0x4,0x64,0x45, 0x7,0x50,0x23, + 0x5,0x6d,0x56, 0x7,0x50,0x22, 0x7,0x54,0x7c, 0x7,0x4f,0x7e, + 0x5,0x6d,0x59, 0x7,0x49,0x71, 0x5,0x6d,0x5a, 0x5,0x6d,0x5c, + 0x7,0x50,0x24, 0xf,0x66,0x34, 0x7,0x50,0x21, 0x5,0x6d,0x5d, + 0x7,0x55,0x22, 0x7,0x55,0x24, 0x5,0x71,0x36, 0x4,0x67,0x36, + 0x7,0x55,0x26, 0x7,0x55,0x25, 0x5,0x71,0x35, 0x7,0x54,0x7e, + 0x7,0x55,0x21, 0x4,0x67,0x37, 0x7,0x55,0x23, 0x7,0x59,0x31, + 0x7,0x54,0x7d, 0xf,0x66,0x33, 0x4,0x69,0x41, 0x7,0x59,0x2e, + 0x4,0x69,0x40, 0x4,0x69,0x3f, 0x5,0x74,0x37, 0x7,0x59,0x2c, + 0x7,0x59,0x2d, 0x7,0x59,0x30, 0x7,0x59,0x2f, 0x5,0x78,0x2e, + 0xf,0x69,0x6f, 0x7,0x5f,0x51, 0x7,0x5f,0x50, 0x7,0x5f,0x4f, + 0x5,0x79,0x4b, 0x7,0x61,0x48, 0x7,0x61,0x47, 0x7,0x61,0x46, + 0x7,0x62,0x61, 0x5,0x7a,0x37, 0x7,0x62,0x62, 0x7,0x62,0x60, + 0x7,0x64,0x5f, 0x7,0x63,0x73, 0x7,0x63,0x72, 0x7,0x64,0x5e, + 0x5,0x7b,0x7e, 0x7,0x65,0x64, 0x7,0x66,0x2c, 0x5,0x7c,0x4b, + 0x7,0x66,0x4d, 0x5,0x24,0x76, 0x6,0x2e,0x2c, 0x4,0x2b,0x48, + 0x5,0x30,0x41, 0x4,0x2f,0x74, 0x6,0x3c,0x2a, 0x6,0x44,0x5b, + 0xf,0x38,0x46, 0xf,0x3f,0x31, 0xf,0x3f,0x32, 0x6,0x58,0x32, + 0x4,0x47,0x34, 0x6,0x62,0x36, 0x6,0x62,0x37, 0x6,0x62,0x38, + 0xf,0x4c,0x38, 0xf,0x4c,0x39, 0x7,0x28,0x5c, 0xf,0x4c,0x3a, + 0xf,0x52,0x30, 0x7,0x33,0x31, 0x7,0x33,0x32, 0xf,0x52,0x2f, + 0x7,0x3b,0x65, 0xf,0x60,0x6d, 0xf,0x60,0x6e, 0x5,0x69,0x4b, + 0x7,0x50,0x27, 0x7,0x55,0x27, 0x5,0x27,0x67, 0x6,0x2e,0x2d, + 0x4,0x2f,0x77, 0x5,0x30,0x42, 0xf,0x32,0x53, 0x5,0x35,0x4d, + 0x5,0x35,0x4e, 0x6,0x44,0x5c, 0x6,0x44,0x5d, 0x5,0x35,0x50, + 0x5,0x35,0x4b, 0xf,0x38,0x47, 0xf,0x38,0x49, 0xf,0x38,0x4b, + 0x4,0x35,0x32, 0x4,0x35,0x36, 0x5,0x35,0x4c, 0x5,0x35,0x4f, + 0x6,0x4e,0x5f, 0x4,0x3b,0x25, 0x6,0x4e,0x62, 0x6,0x4e,0x61, + 0x5,0x3c,0x36, 0x6,0x4e,0x5e, 0x4,0x3b,0x24, 0x6,0x4e,0x5d, + 0x6,0x58,0x36, 0x5,0x42,0x6d, 0x5,0x42,0x6f, 0x5,0x42,0x6e, + 0x6,0x58,0x33, 0x6,0x58,0x37, 0x5,0x42,0x70, 0xf,0x45,0x40, + 0xf,0x45,0x41, 0xf,0x45,0x42, 0x6,0x58,0x35, 0x6,0x62,0x39, + 0x5,0x49,0x71, 0x5,0x49,0x6e, 0x5,0x49,0x72, 0x4,0x47,0x37, + 0x6,0x62,0x3a, 0xf,0x4c,0x3b, 0xf,0x4c,0x3c, 0x5,0x49,0x6f, + 0x6,0x62,0x3b, 0x5,0x49,0x70, 0x4,0x4d,0x49, 0x7,0x28,0x5f, + 0x5,0x50,0x6c, 0x4,0x4d,0x4b, 0x5,0x50,0x6b, 0x7,0x28,0x63, + 0x5,0x50,0x6d, 0x6,0x58,0x34, 0x7,0x28,0x62, 0x5,0x50,0x6a, + 0x5,0x50,0x6e, 0xf,0x52,0x31, 0x7,0x28,0x60, 0x7,0x28,0x5e, + 0x7,0x28,0x5d, 0x7,0x28,0x61, 0x5,0x58,0x30, 0x5,0x58,0x2f, + 0x5,0x58,0x2e, 0x4,0x53,0x57, 0x7,0x33,0x34, 0x5,0x58,0x34, + 0x7,0x3b,0x67, 0x4,0x53,0x58, 0x4,0x53,0x5e, 0x4,0x53,0x5d, + 0x5,0x58,0x31, 0x5,0x58,0x35, 0x7,0x33,0x33, 0x5,0x58,0x2d, + 0x5,0x58,0x33, 0xf,0x57,0x6b, 0xf,0x57,0x6c, 0xf,0x57,0x6d, + 0x7,0x3b,0x66, 0x5,0x64,0x60, 0x5,0x5e,0x45, 0x5,0x5e,0x44, + 0x7,0x3b,0x6a, 0x7,0x3b,0x69, 0x7,0x3b,0x6b, 0x7,0x3b,0x68, + 0xf,0x5c,0x61, 0xf,0x5c,0x62, 0x5,0x64,0x62, 0x4,0x5d,0x51, + 0x4,0x5d,0x4f, 0x7,0x43,0x24, 0x5,0x64,0x61, 0xf,0x60,0x6f, + 0xf,0x60,0x70, 0xf,0x60,0x71, 0x7,0x43,0x25, 0x7,0x49,0x7d, + 0x7,0x49,0x7e, 0x5,0x6d,0x5f, 0x7,0x50,0x29, 0x7,0x50,0x28, + 0xf,0x66,0x35, 0x5,0x6d,0x5e, 0xf,0x68,0x4b, 0xf,0x68,0x4c, + 0x7,0x55,0x28, 0x4,0x69,0x43, 0x5,0x74,0x39, 0x4,0x69,0x42, + 0xf,0x69,0x70, 0xf,0x69,0x71, 0x5,0x78,0x2f, 0x7,0x5f,0x53, + 0xf,0x6b,0x64, 0x7,0x5f,0x52, 0x5,0x79,0x4d, 0x5,0x79,0x4c, + 0x7,0x61,0x49, 0x4,0x6d,0x21, 0x5,0x7a,0x74, 0x4,0x6e,0x3b, + 0x5,0x7c,0x44, 0x7,0x66,0x54, 0x6,0x2e,0x2e, 0x6,0x2e,0x2f, + 0x6,0x34,0x54, 0x5,0x2b,0x48, 0x4,0x2f,0x78, 0x6,0x3c,0x2c, + 0x4,0x2f,0x79, 0x6,0x3c,0x2b, 0x6,0x44,0x67, 0x4,0x35,0x3b, + 0x5,0x35,0x53, 0x5,0x35,0x52, 0x6,0x44,0x5f, 0x6,0x44,0x63, + 0x4,0x35,0x37, 0x6,0x44,0x64, 0x5,0x35,0x51, 0x6,0x44,0x60, + 0xf,0x38,0x4d, 0xf,0x38,0x4e, 0xf,0x38,0x4f, 0x4,0x35,0x3c, + 0x6,0x44,0x66, 0x6,0x44,0x5e, 0x6,0x44,0x62, 0x6,0x44,0x65, + 0x6,0x44,0x61, 0x5,0x3c,0x37, 0x4,0x3b,0x26, 0x6,0x4e,0x64, + 0x6,0x4e,0x67, 0x5,0x3c,0x38, 0x6,0x4e,0x63, 0x6,0x4e,0x66, + 0x6,0x4e,0x69, 0x6,0x4e,0x65, 0x4,0x3b,0x27, 0x4,0x3b,0x28, + 0x6,0x4e,0x68, 0xf,0x3f,0x33, 0x5,0x42,0x73, 0x5,0x42,0x71, + 0x5,0x42,0x72, 0x6,0x58,0x38, 0x6,0x62,0x3e, 0x5,0x49,0x75, + 0x4,0x47,0x39, 0x6,0x62,0x40, 0x5,0x49,0x73, 0x5,0x49,0x74, + 0x6,0x62,0x3d, 0x6,0x62,0x41, 0x6,0x62,0x3c, 0x6,0x62,0x3f, + 0x7,0x28,0x66, 0x5,0x50,0x75, 0x7,0x28,0x67, 0x5,0x50,0x74, + 0x5,0x50,0x70, 0x5,0x50,0x6f, 0x4,0x4d,0x50, 0x4,0x4d,0x52, + 0x4,0x4d,0x4d, 0x7,0x28,0x69, 0x4,0x4d,0x54, 0x5,0x50,0x72, + 0x7,0x28,0x68, 0x7,0x28,0x6a, 0x5,0x50,0x71, 0x7,0x28,0x64, + 0x7,0x28,0x65, 0x5,0x50,0x73, 0x7,0x33,0x38, 0x7,0x33,0x37, + 0x4,0x53,0x5f, 0x5,0x58,0x36, 0x4,0x53,0x63, 0x5,0x58,0x39, + 0x5,0x58,0x3b, 0x4,0x53,0x60, 0x7,0x33,0x36, 0x7,0x33,0x35, + 0x5,0x58,0x37, 0x5,0x58,0x38, 0x5,0x58,0x3a, 0x7,0x33,0x39, + 0x5,0x5e,0x46, 0x7,0x3b,0x6d, 0x7,0x3b,0x73, 0x7,0x3b,0x6c, + 0x5,0x5e,0x4a, 0x5,0x5e,0x49, 0x7,0x3b,0x6e, 0x7,0x33,0x3a, + 0x5,0x5e,0x48, 0x7,0x3b,0x6f, 0x7,0x3b,0x70, 0x7,0x3b,0x71, + 0x4,0x58,0x6c, 0x7,0x3b,0x74, 0x7,0x3b,0x72, 0x5,0x5e,0x47, + 0x7,0x43,0x27, 0x7,0x43,0x28, 0x4,0x5d,0x52, 0x7,0x43,0x26, + 0x7,0x43,0x29, 0x4,0x61,0x35, 0x5,0x69,0x4c, 0x4,0x61,0x32, + 0x4,0x61,0x33, 0x7,0x4a,0x21, 0x7,0x4a,0x22, 0x7,0x4a,0x23, + 0x7,0x4a,0x24, 0x4,0x61,0x36, 0x7,0x50,0x2a, 0x5,0x71,0x37, + 0x7,0x55,0x29, 0x5,0x74,0x3a, 0x4,0x69,0x44, 0x7,0x5c,0x65, + 0x5,0x78,0x30, 0x7,0x62,0x63, 0x4,0x6d,0x60, 0x7,0x64,0x60, + 0x7,0x64,0x61, 0x5,0x7b,0x69, 0x7,0x65,0x43, 0x5,0x23,0x27, + 0x5,0x23,0x28, 0x6,0x2e,0x30, 0x6,0x3c,0x33, 0x4,0x30,0x21, + 0x4,0x2f,0x7b, 0x4,0x2f,0x7a, 0x4,0x30,0x22, 0x5,0x30,0x43, + 0x6,0x3c,0x30, 0x6,0x3c,0x31, 0x6,0x3c,0x2f, 0x6,0x3c,0x32, + 0x6,0x3c,0x2e, 0x4,0x35,0x40, 0x6,0x44,0x6a, 0x6,0x44,0x73, + 0x4,0x35,0x3e, 0x6,0x44,0x6f, 0x5,0x35,0x5c, 0x5,0x35,0x59, + 0x6,0x44,0x71, 0x4,0x35,0x42, 0x5,0x35,0x54, 0x4,0x35,0x46, + 0x6,0x44,0x79, 0x5,0x35,0x55, 0x6,0x44,0x77, 0x6,0x44,0x6b, + 0x6,0x44,0x78, 0x5,0x35,0x58, 0x6,0x44,0x74, 0x6,0x44,0x75, + 0x6,0x44,0x6e, 0x6,0x44,0x7a, 0xf,0x38,0x50, 0xf,0x38,0x51, + 0xf,0x38,0x53, 0xf,0x38,0x54, 0xf,0x38,0x55, 0xf,0x38,0x56, + 0x6,0x44,0x72, 0x6,0x44,0x69, 0x6,0x44,0x68, 0x6,0x44,0x76, + 0x6,0x44,0x6c, 0x5,0x35,0x5a, 0x6,0x4e,0x74, 0x4,0x3b,0x32, + 0x4,0x3b,0x2e, 0x5,0x3c,0x3b, 0x6,0x4e,0x6f, 0x6,0x4e,0x6e, + 0x6,0x4e,0x71, 0x6,0x4e,0x6a, 0x4,0x3b,0x2d, 0x6,0x4e,0x78, + 0x4,0x3b,0x38, 0x4,0x3b,0x39, 0x5,0x3c,0x3c, 0x6,0x4e,0x6d, + 0x6,0x4e,0x76, 0x6,0x4e,0x70, 0x6,0x4e,0x77, 0x4,0x3b,0x37, + 0x5,0x3c,0x39, 0x5,0x3c,0x3a, 0xf,0x3f,0x34, 0xf,0x3f,0x35, + 0xf,0x3f,0x36, 0xf,0x3f,0x37, 0xf,0x3f,0x38, 0xf,0x3f,0x39, + 0xf,0x3f,0x3a, 0xf,0x3f,0x3c, 0x6,0x4e,0x72, 0x6,0x4e,0x75, + 0x6,0x4e,0x6c, 0x6,0x4e,0x79, 0x6,0x4e,0x73, 0x5,0x42,0x75, + 0x4,0x40,0x68, 0x4,0x40,0x6a, 0x6,0x58,0x46, 0x5,0x42,0x76, + 0x5,0x3c,0x3d, 0x5,0x42,0x79, 0x4,0x40,0x71, 0x4,0x40,0x70, + 0x6,0x58,0x40, 0x6,0x58,0x4b, 0x6,0x58,0x3d, 0x6,0x58,0x49, + 0x4,0x40,0x69, 0x4,0x40,0x6b, 0x5,0x42,0x7c, 0x5,0x42,0x74, + 0x4,0x40,0x73, 0x6,0x58,0x43, 0x6,0x58,0x3c, 0x6,0x58,0x47, + 0x6,0x58,0x42, 0x6,0x58,0x3f, 0x4,0x40,0x72, 0x5,0x42,0x7a, + 0x6,0x58,0x48, 0x5,0x42,0x78, 0x5,0x42,0x77, 0x6,0x58,0x44, + 0xf,0x45,0x43, 0xf,0x45,0x45, 0xf,0x45,0x46, 0x6,0x58,0x4a, + 0x5,0x42,0x7b, 0x6,0x58,0x39, 0x6,0x58,0x3b, 0x4,0x40,0x6f, + 0x6,0x58,0x3a, 0x6,0x58,0x45, 0x6,0x58,0x3e, 0x6,0x62,0x4e, + 0x4,0x47,0x3f, 0x5,0x49,0x7a, 0x4,0x47,0x3b, 0x5,0x49,0x78, + 0x5,0x49,0x7b, 0x4,0x47,0x3e, 0x4,0x47,0x48, 0x6,0x62,0x42, + 0x6,0x62,0x4c, 0x4,0x47,0x41, 0x6,0x62,0x53, 0x4,0x47,0x44, + 0x6,0x62,0x4f, 0x4,0x47,0x47, 0x6,0x62,0x46, 0x5,0x49,0x79, + 0x6,0x62,0x51, 0x6,0x62,0x45, 0x4,0x47,0x49, 0x6,0x62,0x50, + 0x6,0x62,0x44, 0x5,0x49,0x76, 0x5,0x49,0x77, 0xf,0x4c,0x3d, + 0xf,0x4c,0x3e, 0xf,0x4c,0x3f, 0xf,0x4c,0x40, 0xf,0x4c,0x42, + 0xf,0x4c,0x43, 0xf,0x4c,0x44, 0xf,0x4c,0x45, 0x6,0x62,0x48, + 0x4,0x47,0x4b, 0x6,0x62,0x4a, 0x5,0x42,0x7d, 0x6,0x62,0x4b, + 0x6,0x62,0x4d, 0x6,0x62,0x43, 0x6,0x62,0x52, 0x6,0x62,0x49, + 0x7,0x29,0x21, 0x5,0x51,0x2a, 0x7,0x28,0x6b, 0x5,0x50,0x7a, + 0x5,0x51,0x22, 0x7,0x28,0x71, 0x7,0x28,0x74, 0x7,0x29,0x22, + 0x7,0x28,0x7c, 0x7,0x28,0x70, 0x5,0x51,0x27, 0x4,0x4d,0x57, + 0x5,0x51,0x29, 0x5,0x51,0x23, 0x5,0x50,0x7b, 0x5,0x50,0x7e, + 0x7,0x28,0x78, 0x5,0x51,0x24, 0x4,0x4d,0x5d, 0x5,0x51,0x26, + 0x4,0x4d,0x62, 0x7,0x29,0x24, 0x7,0x28,0x77, 0x7,0x28,0x6f, + 0x5,0x50,0x78, 0x5,0x50,0x7c, 0x7,0x28,0x7d, 0x7,0x28,0x6d, + 0x5,0x51,0x25, 0x5,0x50,0x7d, 0x5,0x50,0x77, 0x5,0x50,0x79, + 0x5,0x50,0x76, 0xf,0x52,0x32, 0xf,0x52,0x33, 0xf,0x52,0x34, + 0xf,0x52,0x35, 0xf,0x52,0x37, 0xf,0x52,0x39, 0xf,0x52,0x3a, + 0x7,0x28,0x76, 0x7,0x28,0x75, 0x7,0x28,0x6c, 0x7,0x28,0x72, + 0xf,0x52,0x38, 0x5,0x51,0x21, 0x7,0x28,0x7b, 0x7,0x28,0x6e, + 0x5,0x51,0x28, 0x7,0x29,0x23, 0x7,0x28,0x7e, 0x7,0x28,0x7a, + 0x7,0x28,0x73, 0x7,0x33,0x46, 0x5,0x58,0x40, 0x4,0x53,0x71, + 0x7,0x33,0x52, 0x4,0x53,0x68, 0x4,0x53,0x65, 0x4,0x53,0x6c, + 0x7,0x33,0x49, 0x7,0x33,0x51, 0x7,0x33,0x43, 0x5,0x58,0x3d, + 0x7,0x33,0x42, 0x5,0x58,0x3c, 0x7,0x33,0x3c, 0x4,0x53,0x70, + 0x4,0x53,0x67, 0x7,0x33,0x45, 0x4,0x53,0x6f, 0x7,0x33,0x3d, + 0x4,0x53,0x6e, 0x7,0x33,0x47, 0x7,0x33,0x4e, 0x4,0x53,0x66, + 0x7,0x33,0x50, 0x7,0x33,0x3e, 0x4,0x53,0x69, 0x7,0x33,0x3b, + 0x7,0x33,0x53, 0x7,0x33,0x40, 0x7,0x33,0x3f, 0x7,0x33,0x48, + 0x7,0x33,0x4a, 0x5,0x58,0x3f, 0x7,0x33,0x4c, 0x4,0x53,0x6d, + 0x7,0x33,0x44, 0x5,0x58,0x3e, 0xf,0x57,0x6e, 0xf,0x57,0x6f, + 0xf,0x57,0x70, 0xf,0x57,0x71, 0xf,0x57,0x72, 0xf,0x57,0x73, + 0xf,0x57,0x74, 0xf,0x57,0x75, 0xf,0x57,0x76, 0xf,0x57,0x77, + 0xf,0x57,0x78, 0x7,0x33,0x54, 0x7,0x33,0x41, 0x7,0x33,0x4b, + 0x4,0x58,0x6e, 0x5,0x5e,0x52, 0x5,0x5e,0x51, 0x7,0x3b,0x7d, + 0x4,0x58,0x6f, 0x5,0x5e,0x54, 0x4,0x58,0x71, 0x7,0x3b,0x79, + 0x4,0x58,0x6d, 0x5,0x5e,0x4d, 0x5,0x5e,0x53, 0x5,0x5e,0x4e, + 0x7,0x3b,0x76, 0x7,0x3c,0x25, 0x4,0x58,0x72, 0x7,0x43,0x2a, + 0x5,0x5e,0x4f, 0x7,0x3c,0x21, 0x7,0x3b,0x77, 0x5,0x5e,0x56, + 0x7,0x3c,0x27, 0x7,0x3b,0x7c, 0x7,0x3b,0x78, 0x5,0x5e,0x50, + 0x4,0x58,0x74, 0x7,0x3b,0x7b, 0x7,0x3b,0x7e, 0x7,0x3c,0x22, + 0x7,0x3c,0x23, 0x4,0x58,0x73, 0x5,0x5e,0x4b, 0x7,0x3c,0x26, + 0x5,0x5e,0x4c, 0x7,0x3c,0x24, 0x7,0x3b,0x75, 0xf,0x5c,0x63, + 0xf,0x5c,0x64, 0xf,0x5c,0x65, 0xf,0x5c,0x66, 0xf,0x5c,0x67, + 0xf,0x5c,0x68, 0xf,0x5c,0x69, 0xf,0x5c,0x6a, 0xf,0x5c,0x6b, + 0x7,0x3c,0x28, 0x7,0x3c,0x29, 0x7,0x3b,0x7a, 0x4,0x5d,0x5e, + 0x4,0x5d,0x56, 0x7,0x43,0x37, 0x4,0x5d,0x58, 0x7,0x43,0x35, + 0x5,0x64,0x68, 0x7,0x43,0x3a, 0x7,0x43,0x2b, 0x4,0x5d,0x60, + 0x5,0x64,0x66, 0x5,0x58,0x41, 0x4,0x5d,0x59, 0x5,0x64,0x67, + 0x7,0x43,0x38, 0x7,0x43,0x32, 0x5,0x64,0x64, 0x4,0x5d,0x53, + 0x7,0x43,0x3b, 0x4,0x5d,0x55, 0x5,0x64,0x65, 0x4,0x5d,0x5d, + 0x7,0x43,0x39, 0x7,0x43,0x2f, 0x7,0x43,0x33, 0x7,0x4a,0x2a, + 0x7,0x43,0x30, 0x4,0x5d,0x5c, 0x7,0x43,0x34, 0x7,0x43,0x31, + 0x7,0x43,0x3c, 0x7,0x43,0x2c, 0x7,0x43,0x2d, 0xf,0x60,0x72, + 0xf,0x60,0x75, 0x7,0x43,0x36, 0x4,0x5d,0x5f, 0x7,0x43,0x2e, + 0x5,0x69,0x4d, 0x5,0x69,0x4f, 0x7,0x4a,0x2f, 0x4,0x61,0x3e, + 0x7,0x4a,0x2c, 0x7,0x4a,0x2e, 0x4,0x61,0x43, 0x4,0x61,0x39, + 0x5,0x69,0x50, 0x4,0x61,0x41, 0x7,0x4a,0x34, 0x4,0x61,0x42, + 0x5,0x69,0x4e, 0x4,0x61,0x3f, 0x7,0x4a,0x26, 0x7,0x4a,0x29, + 0x7,0x43,0x3d, 0x7,0x4a,0x28, 0x7,0x4a,0x35, 0x7,0x50,0x33, + 0x7,0x4a,0x33, 0x4,0x61,0x3c, 0x5,0x6d,0x60, 0x7,0x4a,0x27, + 0xf,0x63,0x78, 0xf,0x63,0x79, 0xf,0x63,0x7a, 0x4,0x61,0x44, + 0x7,0x4a,0x2b, 0x7,0x50,0x35, 0x7,0x4a,0x30, 0x7,0x4a,0x31, + 0x7,0x4a,0x2d, 0x7,0x4a,0x32, 0x4,0x61,0x38, 0xf,0x60,0x74, + 0x4,0x64,0x4a, 0x4,0x64,0x4b, 0x5,0x6d,0x62, 0x5,0x6d,0x61, + 0x7,0x50,0x2d, 0x5,0x6d,0x63, 0x7,0x50,0x2f, 0x4,0x64,0x49, + 0x7,0x50,0x2b, 0x5,0x69,0x53, 0x7,0x50,0x32, 0x7,0x50,0x2e, + 0x7,0x50,0x34, 0x7,0x50,0x36, 0x7,0x50,0x2c, 0x7,0x50,0x30, + 0xf,0x66,0x36, 0xf,0x66,0x37, 0xf,0x66,0x38, 0xf,0x66,0x39, + 0x7,0x50,0x38, 0x7,0x50,0x37, 0x7,0x50,0x39, 0x7,0x55,0x2a, + 0x4,0x67,0x42, 0x7,0x55,0x34, 0x7,0x55,0x2d, 0x7,0x55,0x33, + 0x4,0x67,0x38, 0x7,0x55,0x2e, 0x5,0x71,0x3d, 0x7,0x55,0x2c, + 0x7,0x55,0x2f, 0x4,0x67,0x3c, 0x5,0x71,0x3a, 0x5,0x71,0x39, + 0x4,0x67,0x43, 0x7,0x59,0x3b, 0x7,0x59,0x35, 0x4,0x67,0x3a, + 0x5,0x71,0x3c, 0x5,0x71,0x3b, 0x7,0x55,0x31, 0x7,0x55,0x2b, + 0x7,0x55,0x30, 0x5,0x71,0x38, 0x7,0x55,0x35, 0x5,0x74,0x3b, + 0x5,0x74,0x3d, 0x5,0x74,0x40, 0x5,0x76,0x4b, 0x4,0x69,0x47, + 0x7,0x59,0x39, 0x4,0x69,0x4a, 0x5,0x74,0x3f, 0x4,0x69,0x49, + 0x5,0x74,0x3e, 0x7,0x59,0x37, 0x7,0x59,0x40, 0x7,0x55,0x36, + 0x5,0x74,0x3c, 0x7,0x59,0x36, 0x7,0x59,0x3a, 0x7,0x59,0x3f, + 0x4,0x69,0x46, 0x7,0x59,0x3e, 0xf,0x69,0x72, 0xf,0x69,0x73, + 0xf,0x69,0x74, 0x7,0x59,0x3c, 0x7,0x59,0x3d, 0x4,0x6a,0x7d, + 0x4,0x6a,0x7e, 0x7,0x5c,0x66, 0x5,0x76,0x4e, 0x5,0x76,0x4d, + 0x5,0x78,0x31, 0x7,0x5c,0x68, 0x7,0x5c,0x69, 0x7,0x5c,0x6a, + 0xf,0x6a,0x74, 0xf,0x6a,0x75, 0x7,0x5c,0x67, 0x7,0x59,0x42, + 0x7,0x5f,0x57, 0x7,0x5f,0x58, 0x7,0x5f,0x55, 0x4,0x6c,0x27, + 0x7,0x5f,0x56, 0x7,0x5f,0x5a, 0xf,0x6b,0x65, 0xf,0x6b,0x66, + 0x7,0x5f,0x54, 0x7,0x5f,0x59, 0x7,0x5f,0x5b, 0x4,0x6d,0x23, + 0x7,0x61,0x4b, 0x5,0x79,0x4e, 0x7,0x61,0x4c, 0xf,0x6c,0x3a, + 0xf,0x6c,0x3b, 0x7,0x61,0x4a, 0x5,0x7a,0x75, 0x7,0x62,0x65, + 0x7,0x62,0x64, 0x5,0x7a,0x39, 0x4,0x6d,0x7e, 0x7,0x63,0x74, + 0x7,0x64,0x62, 0x4,0x6e,0x3c, 0x7,0x64,0x44, 0x7,0x65,0x44, + 0x7,0x66,0x50, 0x5,0x24,0x77, 0x4,0x30,0x24, 0x5,0x30,0x44, + 0x5,0x30,0x45, 0x4,0x35,0x48, 0x4,0x35,0x49, 0x4,0x35,0x47, + 0x6,0x44,0x7b, 0x4,0x3b,0x3a, 0x5,0x42,0x7e, 0x5,0x43,0x21, + 0x6,0x58,0x4c, 0x4,0x47,0x4d, 0x5,0x51,0x2c, 0x4,0x4d,0x63, + 0x5,0x51,0x2d, 0x5,0x51,0x2b, 0x5,0x58,0x42, 0x7,0x33,0x56, + 0x7,0x33,0x55, 0x7,0x3c,0x2a, 0x5,0x5e,0x57, 0x7,0x43,0x3e, + 0x7,0x4a,0x36, 0x7,0x4a,0x39, 0x5,0x69,0x54, 0x7,0x4a,0x37, + 0x5,0x69,0x55, 0x7,0x4a,0x38, 0x7,0x50,0x3a, 0x7,0x4a,0x3a, + 0x5,0x71,0x3e, 0x5,0x7a,0x76, 0x7,0x65,0x77, 0x6,0x34,0x55, + 0x6,0x3c,0x35, 0x6,0x3c,0x34, 0xf,0x38,0x57, 0x4,0x3b,0x3b, + 0x5,0x3c,0x3e, 0x6,0x4e,0x7b, 0xf,0x3f,0x3d, 0x5,0x43,0x22, + 0x4,0x40,0x75, 0x6,0x5b,0x5f, 0x4,0x47,0x50, 0x6,0x62,0x54, + 0x4,0x47,0x51, 0x7,0x29,0x28, 0x7,0x29,0x27, 0x7,0x29,0x25, + 0x5,0x51,0x2f, 0x5,0x51,0x2e, 0x7,0x29,0x26, 0xf,0x52,0x3b, + 0x5,0x58,0x43, 0x4,0x53,0x74, 0x7,0x33,0x57, 0x5,0x58,0x44, + 0x7,0x2c,0x56, 0x5,0x5e,0x5a, 0x7,0x3c,0x2d, 0x5,0x5e,0x58, + 0x7,0x3c,0x2c, 0x5,0x5e,0x59, 0x7,0x3c,0x2b, 0x5,0x64,0x69, + 0x4,0x5d,0x63, 0x7,0x43,0x40, 0x4,0x5d,0x62, 0x5,0x5e,0x5b, + 0x7,0x4a,0x3c, 0x5,0x69,0x57, 0x7,0x4a,0x3d, 0x7,0x43,0x41, + 0x7,0x43,0x42, 0x5,0x69,0x56, 0x5,0x6d,0x66, 0x5,0x6d,0x65, + 0x5,0x6d,0x67, 0xf,0x66,0x3a, 0x5,0x6d,0x64, 0xf,0x63,0x7b, + 0x5,0x71,0x3f, 0x5,0x74,0x41, 0xf,0x6a,0x76, 0xf,0x6a,0x77, + 0x5,0x78,0x32, 0x5,0x79,0x4f, 0x5,0x7a,0x77, 0x7,0x65,0x45, + 0x6,0x25,0x54, 0x5,0x23,0x29, 0x5,0x2b,0x4a, 0x5,0x30,0x48, + 0x5,0x30,0x47, 0x6,0x3c,0x37, 0x6,0x3c,0x36, 0x6,0x44,0x7e, + 0x6,0x44,0x7c, 0x5,0x35,0x61, 0x6,0x45,0x21, 0x6,0x44,0x7d, + 0x4,0x3b,0x3c, 0x6,0x4e,0x7c, 0x4,0x3b,0x3d, 0x5,0x3c,0x40, + 0x5,0x3c,0x3f, 0x6,0x4e,0x7e, 0x5,0x3c,0x41, 0x6,0x4f,0x23, + 0x6,0x4e,0x7d, 0xf,0x32,0x55, 0x4,0x40,0x77, 0x5,0x43,0x25, + 0x4,0x40,0x76, 0x6,0x58,0x4e, 0x6,0x58,0x4f, 0x5,0x43,0x27, + 0x5,0x43,0x23, 0x5,0x43,0x26, 0x6,0x58,0x4d, 0x6,0x4f,0x22, + 0x5,0x43,0x24, 0x5,0x43,0x28, 0x6,0x62,0x55, 0x6,0x62,0x56, + 0x4,0x47,0x53, 0x4,0x47,0x52, 0x6,0x62,0x59, 0x5,0x49,0x7d, + 0x5,0x49,0x7c, 0x6,0x62,0x5b, 0x6,0x62,0x5a, 0x6,0x62,0x57, + 0x6,0x62,0x58, 0x5,0x51,0x32, 0x4,0x4d,0x66, 0x7,0x29,0x29, + 0x7,0x29,0x2b, 0x5,0x51,0x31, 0x5,0x51,0x33, 0x7,0x29,0x2d, + 0x7,0x29,0x2c, 0x5,0x49,0x7e, 0x5,0x51,0x30, 0x7,0x29,0x2a, + 0x5,0x4a,0x21, 0x7,0x29,0x2e, 0xf,0x52,0x3c, 0x5,0x58,0x47, + 0x5,0x58,0x48, 0x5,0x58,0x46, 0x7,0x33,0x59, 0x4,0x53,0x76, + 0x7,0x33,0x5a, 0x7,0x33,0x5c, 0x7,0x33,0x5b, 0x5,0x58,0x45, + 0x7,0x33,0x58, 0x5,0x5e,0x5d, 0x5,0x5e,0x5e, 0x5,0x5e,0x5f, + 0x5,0x5e,0x5c, 0x7,0x3c,0x30, 0x7,0x3c,0x2e, 0x7,0x3c,0x2f, + 0x4,0x5d,0x65, 0x5,0x64,0x6a, 0x5,0x64,0x6b, 0x7,0x43,0x43, + 0x7,0x43,0x44, 0x7,0x43,0x45, 0x4,0x61,0x47, 0x5,0x69,0x58, + 0x5,0x58,0x49, 0x7,0x4a,0x3e, 0x4,0x61,0x49, 0x5,0x6d,0x6b, + 0x5,0x6d,0x68, 0x7,0x50,0x3b, 0x5,0x6d,0x6a, 0x5,0x6d,0x69, + 0x4,0x67,0x46, 0x5,0x71,0x40, 0x7,0x55,0x37, 0x7,0x55,0x38, + 0x7,0x59,0x43, 0x7,0x5c,0x6c, 0x7,0x59,0x44, 0x7,0x59,0x45, + 0x7,0x5c,0x6d, 0x7,0x5c,0x6e, 0x5,0x74,0x42, 0x7,0x5f,0x5c, + 0x7,0x61,0x4d, 0x7,0x5f,0x5d, 0x5,0x79,0x50, 0x5,0x7a,0x3a, + 0x7,0x65,0x46, 0x7,0x66,0x43, 0xf,0x28,0x6c, 0x5,0x2b,0x4b, + 0x6,0x3c,0x38, 0xf,0x32,0x56, 0x5,0x35,0x64, 0x5,0x35,0x63, + 0x4,0x35,0x4f, 0x5,0x35,0x62, 0x4,0x35,0x4e, 0x6,0x45,0x25, + 0x6,0x45,0x23, 0x6,0x4f,0x25, 0x5,0x3c,0x42, 0x5,0x3c,0x46, + 0x5,0x3c,0x44, 0x5,0x3c,0x48, 0x5,0x3c,0x45, 0x6,0x4f,0x28, + 0x6,0x4f,0x26, 0x5,0x3c,0x47, 0x5,0x3c,0x43, 0x6,0x4f,0x27, + 0x6,0x4f,0x24, 0xf,0x3f,0x3e, 0x4,0x40,0x7c, 0x4,0x40,0x7d, + 0x4,0x40,0x7a, 0x6,0x58,0x52, 0x5,0x43,0x2b, 0x6,0x58,0x51, + 0x5,0x43,0x2a, 0x4,0x40,0x79, 0x4,0x40,0x7b, 0x6,0x58,0x53, + 0xf,0x45,0x47, 0x5,0x43,0x29, 0x6,0x62,0x61, 0x6,0x62,0x5c, + 0x5,0x4a,0x25, 0x5,0x4a,0x23, 0x5,0x4a,0x22, 0x6,0x62,0x5f, + 0x5,0x4a,0x24, 0x6,0x62,0x5e, 0x6,0x62,0x60, 0xf,0x4c,0x48, + 0x6,0x62,0x5d, 0x6,0x62,0x62, 0xf,0x4c,0x49, 0x5,0x51,0x35, + 0x5,0x51,0x34, 0x4,0x4d,0x69, 0x5,0x51,0x37, 0x5,0x51,0x36, + 0x5,0x51,0x38, 0x4,0x4d,0x6a, 0x7,0x29,0x2f, 0x7,0x29,0x30, + 0x4,0x4d,0x6b, 0x7,0x29,0x31, 0x7,0x33,0x64, 0x5,0x58,0x4b, + 0x7,0x33,0x5e, 0x7,0x33,0x60, 0x7,0x33,0x61, 0x4,0x53,0x78, + 0x5,0x58,0x4a, 0x7,0x33,0x62, 0x5,0x58,0x4c, 0x7,0x33,0x5f, + 0xf,0x57,0x7a, 0x7,0x33,0x5d, 0x7,0x33,0x63, 0x4,0x58,0x79, + 0x5,0x5e,0x63, 0x7,0x3c,0x31, 0x5,0x5e,0x62, 0x4,0x58,0x78, + 0x5,0x5e,0x60, 0x5,0x5e,0x64, 0x5,0x5e,0x61, 0xf,0x5c,0x6c, + 0x7,0x43,0x46, 0x4,0x5d,0x67, 0x7,0x43,0x47, 0x4,0x5d,0x66, + 0x5,0x64,0x6c, 0x7,0x4a,0x3f, 0x5,0x64,0x6d, 0x5,0x69,0x5b, + 0x7,0x4a,0x40, 0x5,0x69,0x5a, 0x7,0x4a,0x43, 0x7,0x50,0x3d, + 0x7,0x4a,0x42, 0x5,0x69,0x59, 0x5,0x6d,0x6d, 0x5,0x6d,0x6c, + 0x7,0x50,0x3c, 0x5,0x71,0x42, 0x5,0x6d,0x6e, 0x5,0x71,0x41, + 0x7,0x55,0x39, 0x7,0x59,0x46, 0x7,0x5c,0x70, 0x7,0x5c,0x6f, + 0x5,0x7a,0x78, 0x5,0x2b,0x4c, 0x4,0x2b,0x4a, 0x6,0x34,0x56, + 0xf,0x2d,0x4a, 0x4,0x30,0x26, 0x6,0x3c,0x39, 0x5,0x30,0x49, + 0x5,0x30,0x4a, 0xf,0x32,0x57, 0xf,0x32,0x58, 0x6,0x3c,0x3a, + 0x6,0x45,0x2a, 0x6,0x45,0x2c, 0x6,0x45,0x27, 0x6,0x45,0x28, + 0x6,0x45,0x26, 0x6,0x45,0x2b, 0x5,0x35,0x65, 0xf,0x38,0x59, + 0xf,0x38,0x5a, 0xf,0x38,0x5b, 0xf,0x38,0x5c, 0xf,0x38,0x5d, + 0xf,0x38,0x5e, 0xf,0x38,0x5f, 0xf,0x38,0x60, 0x6,0x45,0x2d, + 0x4,0x35,0x53, 0x6,0x45,0x29, 0x4,0x35,0x52, 0x6,0x4f,0x2b, + 0x4,0x3b,0x40, 0x5,0x3c,0x49, 0x5,0x3c,0x4b, 0x6,0x4f,0x2e, + 0x6,0x4f,0x2c, 0x6,0x4f,0x2d, 0x6,0x58,0x57, 0x5,0x3c,0x4a, + 0xf,0x3f,0x3f, 0xf,0x3f,0x41, 0xf,0x3f,0x42, 0xf,0x3f,0x43, + 0xf,0x3f,0x44, 0xf,0x3f,0x45, 0x6,0x4f,0x2f, 0x6,0x4f,0x2a, + 0x5,0x3c,0x4d, 0x4,0x41,0x22, 0x6,0x58,0x54, 0x6,0x58,0x59, + 0x6,0x58,0x56, 0x5,0x43,0x30, 0x5,0x43,0x2c, 0x6,0x58,0x5e, + 0x6,0x58,0x55, 0x5,0x43,0x2f, 0x5,0x43,0x31, 0x5,0x43,0x32, + 0x6,0x58,0x58, 0x6,0x58,0x60, 0x6,0x58,0x62, 0x5,0x43,0x33, + 0x6,0x58,0x5f, 0xf,0x45,0x48, 0xf,0x45,0x49, 0xf,0x45,0x4a, + 0xf,0x45,0x4b, 0xf,0x45,0x4c, 0xf,0x45,0x4d, 0xf,0x45,0x4e, + 0x6,0x58,0x61, 0xf,0x3f,0x40, 0x6,0x58,0x5b, 0x5,0x43,0x2e, + 0xf,0x46,0x34, 0x6,0x62,0x65, 0x4,0x47,0x55, 0x5,0x4a,0x26, + 0x6,0x62,0x64, 0x6,0x62,0x66, 0x6,0x62,0x6c, 0x6,0x62,0x63, + 0x6,0x62,0x69, 0x5,0x4a,0x27, 0x4,0x47,0x57, 0xf,0x4c,0x4d, + 0xf,0x4c,0x4e, 0xf,0x4c,0x4f, 0xf,0x4c,0x51, 0xf,0x4c,0x50, + 0xf,0x4c,0x4c, 0x6,0x62,0x6b, 0x6,0x58,0x5d, 0x7,0x29,0x33, + 0x7,0x29,0x35, 0x5,0x4a,0x28, 0x4,0x4d,0x6f, 0x7,0x29,0x34, + 0x5,0x51,0x3a, 0x4,0x4d,0x70, 0x5,0x51,0x3b, 0x7,0x29,0x39, + 0x7,0x29,0x38, 0x7,0x29,0x32, 0xf,0x52,0x3d, 0xf,0x52,0x3e, + 0xf,0x52,0x3f, 0x7,0x29,0x37, 0xf,0x4c,0x4b, 0x7,0x33,0x6a, + 0x5,0x58,0x4e, 0x7,0x33,0x67, 0x7,0x33,0x66, 0x5,0x58,0x4f, + 0x7,0x33,0x6b, 0x7,0x33,0x6e, 0x4,0x53,0x7c, 0x7,0x33,0x68, + 0x5,0x58,0x4d, 0x6,0x62,0x68, 0xf,0x54,0x32, 0xf,0x57,0x7b, + 0xf,0x57,0x7c, 0xf,0x57,0x7d, 0xf,0x57,0x7e, 0xf,0x58,0x21, + 0xf,0x58,0x22, 0x7,0x33,0x6d, 0x7,0x33,0x6c, 0x7,0x33,0x65, + 0x7,0x33,0x69, 0x5,0x58,0x50, 0x7,0x3c,0x32, 0x5,0x5e,0x65, + 0x5,0x5b,0x2d, 0x5,0x5e,0x67, 0x5,0x58,0x52, 0x5,0x5e,0x66, + 0x4,0x58,0x7b, 0x7,0x3c,0x38, 0x7,0x3c,0x34, 0x7,0x3c,0x36, + 0x7,0x3c,0x37, 0x7,0x3c,0x35, 0xf,0x5c,0x6e, 0xf,0x5c,0x70, + 0xf,0x5c,0x6f, 0x7,0x43,0x4b, 0x5,0x64,0x73, 0x7,0x43,0x4e, + 0x5,0x64,0x6f, 0x7,0x43,0x49, 0x7,0x43,0x4a, 0x7,0x43,0x51, + 0x5,0x64,0x71, 0x5,0x64,0x6e, 0x5,0x64,0x72, 0x7,0x43,0x4d, + 0x7,0x43,0x4c, 0xf,0x60,0x76, 0xf,0x60,0x77, 0xf,0x60,0x78, + 0xf,0x60,0x79, 0xf,0x60,0x7b, 0xf,0x60,0x7c, 0x7,0x43,0x48, + 0x7,0x43,0x50, 0x5,0x64,0x70, 0x7,0x4a,0x47, 0x7,0x4a,0x4b, + 0x5,0x69,0x5d, 0x5,0x64,0x74, 0x7,0x4a,0x4a, 0x7,0x43,0x4f, + 0x5,0x69,0x5c, 0x4,0x61,0x4b, 0x7,0x4a,0x48, 0x5,0x69,0x5e, + 0x7,0x4a,0x4d, 0x7,0x4a,0x4c, 0x5,0x69,0x60, 0x7,0x4a,0x44, + 0x7,0x4a,0x49, 0x7,0x4a,0x46, 0xf,0x63,0x7c, 0xf,0x63,0x7d, + 0xf,0x63,0x7e, 0xf,0x64,0x21, 0x7,0x4a,0x4e, 0x7,0x4a,0x45, + 0x5,0x69,0x5f, 0x4,0x64,0x51, 0x5,0x6d,0x70, 0x4,0x64,0x50, + 0x5,0x6d,0x6f, 0x7,0x50,0x3e, 0x7,0x50,0x40, 0xf,0x66,0x3b, + 0xf,0x66,0x3c, 0xf,0x66,0x3d, 0xf,0x66,0x3e, 0xf,0x66,0x3f, + 0x7,0x50,0x3f, 0x5,0x71,0x43, 0x4,0x67,0x47, 0x5,0x71,0x44, + 0x5,0x71,0x45, 0xf,0x68,0x4e, 0xf,0x68,0x4f, 0x7,0x55,0x3b, + 0x7,0x59,0x47, 0x5,0x74,0x45, 0x5,0x74,0x44, 0xf,0x69,0x76, + 0xf,0x69,0x77, 0xf,0x69,0x78, 0x7,0x59,0x4a, 0x7,0x59,0x48, + 0x7,0x59,0x49, 0xf,0x68,0x4d, 0x7,0x5c,0x71, 0x4,0x6b,0x22, + 0x5,0x74,0x43, 0x7,0x5c,0x72, 0xf,0x6a,0x78, 0x7,0x5c,0x73, + 0x7,0x5f,0x5e, 0x7,0x5f,0x60, 0x7,0x5f,0x5f, 0x7,0x62,0x66, + 0x6,0x2e,0x31, 0x6,0x34,0x57, 0x6,0x34,0x58, 0x5,0x35,0x66, + 0xf,0x38,0x61, 0x6,0x4f,0x30, 0x4,0x3b,0x44, 0x6,0x58,0x63, + 0xf,0x45,0x4f, 0x5,0x4a,0x2a, 0xf,0x4c,0x52, 0x7,0x29,0x3a, + 0x5,0x58,0x54, 0x5,0x58,0x53, 0xf,0x58,0x23, 0x7,0x33,0x6f, + 0x5,0x5e,0x69, 0x5,0x5e,0x6a, 0x5,0x5e,0x68, 0xf,0x5c,0x71, + 0x5,0x64,0x75, 0x7,0x43,0x53, 0x7,0x4a,0x50, 0x7,0x4a,0x4f, + 0x5,0x71,0x46, 0x7,0x5c,0x74, 0x6,0x2e,0x32, 0x6,0x2e,0x33, + 0x6,0x34,0x59, 0xf,0x2d,0x4b, 0xf,0x2d,0x4d, 0xf,0x2d,0x4e, + 0xf,0x2d,0x4f, 0xf,0x2d,0x50, 0x4,0x2b,0x4b, 0x5,0x30,0x4d, + 0x6,0x3c,0x3e, 0x6,0x3c,0x3d, 0x5,0x30,0x4e, 0x6,0x3c,0x3c, + 0x4,0x30,0x29, 0xf,0x32,0x59, 0xf,0x32,0x5a, 0xf,0x32,0x5b, + 0xf,0x32,0x5c, 0xf,0x32,0x5d, 0x5,0x35,0x6d, 0x6,0x45,0x30, + 0x5,0x35,0x67, 0x4,0x35,0x57, 0x5,0x35,0x6a, 0x5,0x35,0x6f, + 0x5,0x35,0x6e, 0x4,0x35,0x58, 0x6,0x45,0x2e, 0x6,0x45,0x2f, + 0x5,0x35,0x6b, 0x5,0x35,0x68, 0xf,0x38,0x63, 0xf,0x38,0x64, + 0xf,0x38,0x65, 0xf,0x38,0x66, 0xf,0x38,0x68, 0xf,0x38,0x69, + 0xf,0x38,0x62, 0x5,0x35,0x6c, 0x5,0x35,0x69, 0xf,0x38,0x67, + 0x5,0x3c,0x51, 0x5,0x3c,0x50, 0x5,0x3c,0x54, 0x5,0x3c,0x4f, + 0x6,0x4f,0x34, 0x6,0x4f,0x31, 0x5,0x43,0x39, 0x5,0x3c,0x53, + 0x5,0x3c,0x4e, 0x6,0x4f,0x33, 0x4,0x3b,0x46, 0x5,0x3c,0x55, + 0x6,0x58,0x64, 0x6,0x4f,0x35, 0xf,0x3f,0x47, 0xf,0x3f,0x48, + 0xf,0x3f,0x49, 0xf,0x3f,0x4a, 0xf,0x3f,0x4b, 0xf,0x3f,0x4c, + 0xf,0x3f,0x4f, 0xf,0x3f,0x50, 0xf,0x3f,0x51, 0x6,0x4f,0x32, + 0xf,0x3f,0x4e, 0x6,0x58,0x66, 0x5,0x43,0x36, 0x4,0x41,0x23, + 0x6,0x58,0x68, 0x4,0x41,0x25, 0x5,0x43,0x3b, 0x5,0x43,0x35, + 0x5,0x43,0x3d, 0x5,0x43,0x37, 0x4,0x41,0x24, 0x6,0x58,0x6a, + 0x6,0x58,0x69, 0x5,0x43,0x3a, 0xf,0x45,0x50, 0xf,0x45,0x51, + 0xf,0x45,0x52, 0xf,0x45,0x53, 0xf,0x45,0x54, 0xf,0x45,0x55, + 0xf,0x45,0x56, 0xf,0x45,0x57, 0x6,0x58,0x65, 0x6,0x58,0x67, + 0x6,0x62,0x6d, 0xf,0x3f,0x4d, 0x6,0x62,0x6e, 0x4,0x47,0x5c, + 0x5,0x4a,0x2c, 0x5,0x4a,0x30, 0x6,0x62,0x72, 0x5,0x4a,0x2b, + 0x5,0x4a,0x2e, 0x5,0x4a,0x31, 0x6,0x62,0x71, 0x6,0x62,0x6f, + 0x5,0x4a,0x33, 0x4,0x47,0x5d, 0x5,0x4a,0x2f, 0x6,0x62,0x76, + 0x5,0x4a,0x2d, 0x6,0x62,0x73, 0xf,0x4c,0x53, 0xf,0x4c,0x54, + 0xf,0x4c,0x55, 0xf,0x4c,0x56, 0xf,0x4c,0x57, 0xf,0x4c,0x58, + 0xf,0x4c,0x59, 0x6,0x62,0x70, 0x5,0x51,0x42, 0x5,0x51,0x3c, + 0x4,0x4d,0x72, 0x5,0x51,0x3f, 0x5,0x51,0x3e, 0x5,0x51,0x3d, + 0x5,0x51,0x40, 0x7,0x29,0x3f, 0x5,0x51,0x46, 0x5,0x51,0x43, + 0x7,0x29,0x41, 0x5,0x51,0x41, 0x7,0x29,0x3c, 0x7,0x29,0x40, + 0x7,0x29,0x3e, 0x6,0x62,0x74, 0x7,0x29,0x42, 0x7,0x33,0x72, + 0x5,0x51,0x45, 0x5,0x51,0x44, 0xf,0x52,0x40, 0xf,0x52,0x41, + 0x7,0x29,0x43, 0x7,0x29,0x3b, 0xf,0x58,0x2d, 0x4,0x54,0x23, + 0x4,0x54,0x24, 0x4,0x54,0x28, 0x7,0x33,0x74, 0x5,0x58,0x59, + 0x4,0x54,0x21, 0x4,0x54,0x22, 0x4,0x54,0x27, 0x7,0x33,0x75, + 0x4,0x54,0x25, 0x7,0x33,0x71, 0x7,0x33,0x70, 0x5,0x58,0x58, + 0x5,0x58,0x5a, 0x7,0x33,0x76, 0xf,0x58,0x24, 0xf,0x58,0x26, + 0xf,0x58,0x27, 0xf,0x58,0x28, 0xf,0x58,0x29, 0xf,0x58,0x2a, + 0xf,0x58,0x2b, 0xf,0x58,0x2c, 0xf,0x58,0x2e, 0x7,0x33,0x78, + 0x7,0x33,0x77, 0x5,0x58,0x5b, 0x5,0x58,0x56, 0x5,0x58,0x57, + 0x5,0x5e,0x6f, 0x5,0x5e,0x71, 0x4,0x59,0x22, 0x5,0x5e,0x70, + 0x4,0x59,0x24, 0x4,0x59,0x21, 0x5,0x5e,0x72, 0x4,0x58,0x7e, + 0x5,0x5e,0x6c, 0x4,0x59,0x23, 0x5,0x5e,0x6e, 0x5,0x5e,0x6b, + 0x7,0x3c,0x3a, 0x5,0x5e,0x73, 0xf,0x58,0x25, 0xf,0x5c,0x72, + 0xf,0x5c,0x73, 0xf,0x5c,0x74, 0xf,0x5c,0x75, 0xf,0x5c,0x76, + 0x7,0x3c,0x39, 0x5,0x64,0x79, 0x5,0x64,0x7c, 0x4,0x5d,0x6b, + 0x7,0x43,0x57, 0x7,0x43,0x56, 0x5,0x64,0x76, 0x5,0x64,0x7a, + 0x5,0x64,0x78, 0x5,0x64,0x77, 0x5,0x64,0x7d, 0x5,0x64,0x7e, + 0x7,0x43,0x5b, 0x7,0x43,0x5a, 0x5,0x64,0x7b, 0xf,0x60,0x7d, + 0x7,0x43,0x58, 0x7,0x43,0x55, 0x7,0x43,0x59, 0x7,0x43,0x54, + 0x5,0x58,0x5d, 0x5,0x69,0x62, 0x5,0x69,0x66, 0x5,0x69,0x68, + 0x4,0x61,0x4e, 0x4,0x61,0x4c, 0x5,0x69,0x63, 0x5,0x69,0x67, + 0x5,0x69,0x65, 0x5,0x69,0x61, 0x7,0x4a,0x52, 0x5,0x69,0x69, + 0x5,0x69,0x64, 0xf,0x64,0x23, 0xf,0x64,0x24, 0xf,0x64,0x25, + 0x7,0x4a,0x51, 0x7,0x4a,0x53, 0x4,0x64,0x52, 0x4,0x64,0x54, + 0x4,0x64,0x58, 0x4,0x64,0x57, 0x5,0x6d,0x71, 0x7,0x50,0x41, + 0x7,0x50,0x43, 0x5,0x6d,0x72, 0x7,0x50,0x42, 0xf,0x66,0x40, + 0xf,0x66,0x41, 0xf,0x66,0x42, 0x4,0x67,0x49, 0x5,0x71,0x48, + 0x5,0x71,0x49, 0x7,0x55,0x3f, 0x7,0x55,0x3d, 0x7,0x55,0x3c, + 0x7,0x55,0x3e, 0x5,0x71,0x47, 0x5,0x74,0x46, 0x5,0x74,0x49, + 0x4,0x69,0x4d, 0x5,0x74,0x48, 0x5,0x74,0x47, 0xf,0x69,0x79, + 0x5,0x76,0x4f, 0x5,0x76,0x50, 0xf,0x6a,0x79, 0x7,0x59,0x4b, + 0x7,0x5c,0x75, 0x7,0x5c,0x76, 0x5,0x78,0x33, 0x5,0x78,0x34, + 0x5,0x78,0x35, 0x4,0x6d,0x26, 0x7,0x61,0x4e, 0x5,0x7a,0x79, + 0x5,0x7b,0x49, 0x6,0x2e,0x35, 0x6,0x2e,0x34, 0x6,0x34,0x5b, + 0x5,0x2b,0x4d, 0xf,0x2d,0x51, 0x6,0x34,0x5a, 0x6,0x3c,0x41, + 0x4,0x30,0x2b, 0x6,0x3c,0x42, 0x6,0x3c,0x40, 0x5,0x30,0x50, + 0x5,0x30,0x4f, 0x6,0x3c,0x3f, 0x6,0x3c,0x43, 0x4,0x35,0x5f, + 0x6,0x45,0x33, 0x4,0x35,0x5a, 0x5,0x35,0x73, 0x6,0x45,0x37, + 0x5,0x35,0x77, 0x6,0x45,0x3a, 0x5,0x35,0x71, 0x5,0x35,0x75, + 0x6,0x45,0x3c, 0x6,0x45,0x3d, 0x5,0x35,0x74, 0x6,0x45,0x3b, + 0x6,0x45,0x32, 0x6,0x45,0x36, 0xf,0x38,0x6a, 0x6,0x45,0x31, + 0x6,0x45,0x35, 0x6,0x45,0x39, 0x5,0x35,0x76, 0x5,0x35,0x70, + 0x6,0x45,0x34, 0x5,0x3c,0x60, 0x5,0x3c,0x57, 0x5,0x3c,0x58, + 0x5,0x3c,0x5b, 0x6,0x4f,0x3b, 0x5,0x3c,0x56, 0x6,0x4f,0x38, + 0x4,0x3b,0x4e, 0x5,0x3c,0x5d, 0x5,0x3c,0x59, 0x5,0x3c,0x61, + 0x5,0x3c,0x5a, 0x6,0x4f,0x39, 0x6,0x58,0x79, 0x5,0x3c,0x62, + 0xf,0x3f,0x54, 0x6,0x4f,0x37, 0xf,0x3f,0x52, 0x6,0x4f,0x3a, + 0x5,0x3c,0x5e, 0x5,0x43,0x41, 0x5,0x43,0x3f, 0x6,0x58,0x71, + 0x5,0x43,0x40, 0x5,0x43,0x42, 0x6,0x58,0x74, 0x6,0x58,0x70, + 0x5,0x43,0x47, 0x5,0x43,0x45, 0x6,0x58,0x6e, 0x6,0x58,0x6d, + 0x5,0x43,0x3e, 0x6,0x58,0x6f, 0x6,0x58,0x72, 0x6,0x58,0x76, + 0x5,0x43,0x4a, 0x6,0x58,0x6c, 0x6,0x58,0x77, 0x5,0x43,0x43, + 0x5,0x43,0x4c, 0x5,0x43,0x48, 0x6,0x58,0x73, 0x5,0x43,0x49, + 0x5,0x43,0x46, 0x6,0x58,0x75, 0x5,0x4a,0x35, 0xf,0x45,0x59, + 0x6,0x58,0x78, 0x6,0x58,0x6b, 0x6,0x63,0x22, 0x5,0x4a,0x43, + 0x4,0x47,0x60, 0x5,0x4a,0x37, 0x5,0x4a,0x3f, 0x5,0x4a,0x36, + 0x5,0x51,0x4e, 0x5,0x4a,0x3b, 0x6,0x62,0x77, 0x6,0x62,0x7b, + 0x5,0x4a,0x42, 0x5,0x4a,0x3c, 0x5,0x4a,0x39, 0x5,0x4a,0x40, + 0x5,0x4a,0x41, 0x5,0x4a,0x3d, 0x5,0x43,0x44, 0x5,0x4a,0x38, + 0x5,0x4a,0x44, 0x6,0x62,0x7e, 0x5,0x4a,0x46, 0x6,0x62,0x79, + 0x5,0x4a,0x47, 0xf,0x4c,0x5a, 0xf,0x4c,0x5b, 0x6,0x62,0x78, + 0x6,0x62,0x7a, 0x6,0x62,0x7d, 0x6,0x63,0x21, 0x6,0x62,0x7c, + 0x5,0x4a,0x3a, 0x7,0x29,0x46, 0x4,0x4d,0x7a, 0x5,0x51,0x4c, + 0x5,0x51,0x47, 0x5,0x51,0x4a, 0x5,0x51,0x4f, 0x7,0x29,0x45, + 0x7,0x29,0x49, 0x4,0x4d,0x7c, 0x7,0x29,0x4d, 0x4,0x4d,0x7b, + 0x5,0x51,0x4b, 0x5,0x51,0x4d, 0x4,0x4e,0x24, 0x5,0x51,0x51, + 0x5,0x51,0x52, 0x4,0x47,0x63, 0x7,0x29,0x4f, 0x5,0x51,0x49, + 0x7,0x29,0x4b, 0xf,0x52,0x42, 0xf,0x52,0x43, 0xf,0x52,0x44, + 0xf,0x52,0x45, 0x7,0x29,0x48, 0x7,0x29,0x4c, 0x7,0x29,0x47, + 0x7,0x29,0x4a, 0x5,0x51,0x50, 0x5,0x51,0x54, 0x5,0x51,0x55, + 0x5,0x4a,0x45, 0x7,0x34,0x21, 0x5,0x58,0x60, 0x5,0x4a,0x48, + 0x5,0x58,0x69, 0x4,0x54,0x2a, 0x7,0x33,0x7a, 0x5,0x58,0x63, + 0x7,0x33,0x7e, 0x7,0x34,0x23, 0x7,0x33,0x7c, 0x5,0x58,0x5f, + 0x7,0x33,0x7b, 0x7,0x34,0x25, 0x5,0x51,0x53, 0x7,0x34,0x26, + 0x5,0x58,0x67, 0x5,0x58,0x68, 0x5,0x58,0x5e, 0x5,0x58,0x61, + 0x7,0x33,0x7d, 0x5,0x58,0x65, 0x5,0x58,0x64, 0x7,0x34,0x24, + 0x4,0x54,0x2b, 0x5,0x58,0x66, 0x4,0x54,0x2c, 0xf,0x58,0x31, + 0xf,0x58,0x32, 0x7,0x34,0x22, 0x5,0x5e,0x7a, 0x5,0x5e,0x7d, + 0x5,0x5e,0x75, 0x7,0x3c,0x40, 0x5,0x5e,0x76, 0x5,0x5e,0x7c, + 0x5,0x5e,0x78, 0x4,0x59,0x29, 0x7,0x3c,0x3e, 0x7,0x43,0x67, + 0x7,0x3c,0x43, 0x5,0x5e,0x7e, 0x4,0x59,0x2e, 0x7,0x3c,0x3b, + 0x7,0x3c,0x42, 0x7,0x3c,0x44, 0x5,0x5e,0x79, 0x4,0x59,0x27, + 0x7,0x3c,0x41, 0x7,0x34,0x27, 0x7,0x3c,0x3f, 0x4,0x59,0x2f, + 0xf,0x5c,0x77, 0x7,0x3c,0x3d, 0xf,0x5c,0x79, 0x5,0x5e,0x77, + 0x5,0x5e,0x74, 0x7,0x43,0x62, 0x4,0x5d,0x70, 0x7,0x43,0x66, + 0x4,0x5d,0x6f, 0x5,0x65,0x21, 0x5,0x65,0x22, 0x5,0x65,0x2d, + 0x5,0x65,0x26, 0x4,0x5d,0x71, 0x5,0x65,0x2c, 0x5,0x65,0x28, + 0x7,0x43,0x5f, 0x5,0x69,0x70, 0x7,0x43,0x65, 0x7,0x43,0x5c, + 0x5,0x65,0x2e, 0x7,0x43,0x5e, 0x5,0x65,0x24, 0x7,0x43,0x61, + 0x5,0x65,0x23, 0x5,0x65,0x29, 0x4,0x5f,0x33, 0x4,0x5d,0x76, + 0x5,0x65,0x25, 0xf,0x60,0x7e, 0xf,0x61,0x21, 0xf,0x61,0x22, + 0xf,0x61,0x23, 0xf,0x61,0x24, 0xf,0x61,0x25, 0x7,0x43,0x6b, + 0x5,0x65,0x27, 0x7,0x43,0x60, 0x7,0x43,0x69, 0x7,0x43,0x68, + 0x7,0x43,0x6a, 0x7,0x43,0x5d, 0x5,0x65,0x2b, 0x7,0x43,0x63, + 0x7,0x3c,0x3c, 0x5,0x65,0x2f, 0x5,0x69,0x6a, 0x7,0x4a,0x65, + 0x5,0x69,0x6f, 0x5,0x69,0x71, 0x7,0x4a,0x68, 0x5,0x69,0x74, + 0x7,0x4a,0x5b, 0x5,0x65,0x2a, 0x5,0x69,0x6e, 0x7,0x4a,0x58, + 0x5,0x69,0x6d, 0x5,0x69,0x72, 0x4,0x61,0x55, 0x7,0x4a,0x54, + 0x4,0x5d,0x73, 0x7,0x4a,0x59, 0x7,0x43,0x64, 0x7,0x4a,0x5e, + 0x5,0x69,0x73, 0x7,0x4a,0x5a, 0x7,0x4a,0x66, 0x7,0x4a,0x55, + 0x7,0x4a,0x5c, 0x5,0x69,0x6b, 0x5,0x69,0x6c, 0x7,0x4a,0x61, + 0x7,0x4a,0x62, 0x7,0x4a,0x63, 0x7,0x4a,0x5f, 0x5,0x69,0x76, + 0x5,0x69,0x75, 0x7,0x4a,0x60, 0x7,0x4a,0x5d, 0x7,0x4a,0x67, + 0x7,0x4a,0x56, 0x7,0x4a,0x64, 0x4,0x61,0x53, 0x4,0x64,0x59, + 0x5,0x6d,0x7d, 0x5,0x6d,0x77, 0x7,0x50,0x44, 0x5,0x6d,0x7b, + 0x5,0x6d,0x76, 0x5,0x6d,0x79, 0x7,0x50,0x48, 0x7,0x50,0x46, + 0x4,0x64,0x5c, 0x5,0x6d,0x73, 0x4,0x64,0x5d, 0x7,0x50,0x47, + 0x5,0x6d,0x78, 0x5,0x6d,0x75, 0x5,0x6d,0x74, 0x7,0x50,0x49, + 0xf,0x66,0x43, 0xf,0x66,0x44, 0xf,0x66,0x45, 0xf,0x66,0x46, + 0xf,0x66,0x47, 0x7,0x50,0x45, 0x7,0x50,0x4a, 0x7,0x50,0x4b, + 0x5,0x6d,0x7c, 0x5,0x6d,0x7e, 0x5,0x6d,0x7a, 0x4,0x67,0x4e, + 0x7,0x55,0x42, 0x4,0x67,0x4f, 0x5,0x71,0x4b, 0x7,0x55,0x41, + 0x7,0x55,0x44, 0x4,0x67,0x4d, 0x4,0x67,0x4b, 0x5,0x71,0x4c, + 0x7,0x55,0x43, 0x7,0x55,0x40, 0x5,0x71,0x4a, 0xf,0x68,0x51, + 0xf,0x68,0x52, 0x5,0x74,0x4a, 0x7,0x55,0x45, 0x7,0x59,0x4c, + 0x5,0x74,0x4d, 0x5,0x74,0x4f, 0x5,0x74,0x4e, 0x5,0x74,0x4c, + 0x7,0x59,0x4d, 0x5,0x74,0x51, 0x7,0x59,0x4e, 0xf,0x69,0x7a, + 0x7,0x59,0x4f, 0x5,0x74,0x50, 0x5,0x76,0x54, 0x5,0x76,0x52, + 0x5,0x76,0x55, 0x7,0x5c,0x79, 0x7,0x5c,0x78, 0x5,0x76,0x53, + 0x5,0x76,0x51, 0x4,0x6c,0x2b, 0x7,0x5f,0x61, 0x5,0x78,0x37, + 0x5,0x78,0x36, 0x4,0x6c,0x2a, 0x5,0x78,0x38, 0x7,0x5f,0x62, + 0x7,0x61,0x4f, 0x7,0x5f,0x63, 0x7,0x61,0x52, 0x4,0x6d,0x28, + 0x7,0x61,0x54, 0x7,0x62,0x67, 0x7,0x61,0x53, 0x7,0x61,0x51, + 0x7,0x61,0x50, 0xf,0x6b,0x67, 0x5,0x7a,0x3c, 0x5,0x7a,0x3b, + 0x5,0x7a,0x3d, 0x7,0x63,0x76, 0x5,0x7b,0x4a, 0x7,0x64,0x63, + 0x5,0x7b,0x6a, 0xf,0x6d,0x28, 0x7,0x65,0x65, 0xf,0x6d,0x33, + 0x6,0x23,0x39, 0x6,0x23,0x3a, 0x6,0x25,0x55, 0x5,0x30,0x52, + 0x6,0x3c,0x44, 0x5,0x30,0x51, 0x5,0x35,0x7a, 0x5,0x35,0x79, + 0x5,0x35,0x78, 0x6,0x45,0x3e, 0x6,0x45,0x41, 0x6,0x45,0x40, + 0x6,0x45,0x42, 0x6,0x45,0x3f, 0x6,0x45,0x43, 0x6,0x45,0x44, + 0x4,0x35,0x60, 0xf,0x38,0x6b, 0x5,0x3c,0x65, 0x6,0x4f,0x3f, + 0x5,0x3c,0x64, 0x6,0x4f,0x41, 0x6,0x4f,0x3e, 0x5,0x3c,0x66, + 0xf,0x3f,0x55, 0xf,0x3f,0x56, 0xf,0x3f,0x57, 0xf,0x3f,0x58, + 0x6,0x4f,0x3d, 0x6,0x4f,0x40, 0x6,0x58,0x7d, 0x5,0x43,0x4d, + 0x6,0x58,0x7a, 0x6,0x58,0x7e, 0x6,0x59,0x21, 0xf,0x45,0x5a, + 0xf,0x45,0x5b, 0xf,0x45,0x5c, 0x6,0x58,0x7b, 0x6,0x58,0x7c, + 0x6,0x59,0x22, 0x5,0x4a,0x4a, 0x6,0x63,0x23, 0x6,0x63,0x24, + 0x5,0x4a,0x49, 0x6,0x63,0x25, 0x6,0x63,0x26, 0xf,0x4c,0x5c, + 0xf,0x4c,0x5d, 0xf,0x4c,0x5e, 0x7,0x29,0x51, 0x5,0x51,0x56, + 0x4,0x4e,0x25, 0xf,0x52,0x46, 0xf,0x52,0x48, 0x7,0x29,0x50, + 0x5,0x58,0x6a, 0x4,0x54,0x31, 0x5,0x58,0x6b, 0x7,0x34,0x28, + 0x7,0x3c,0x46, 0xf,0x58,0x34, 0xf,0x58,0x36, 0x7,0x3c,0x48, + 0x7,0x3c,0x47, 0x7,0x3c,0x45, 0x5,0x5f,0x21, 0xf,0x5c,0x7a, + 0xf,0x5c,0x7b, 0x5,0x65,0x30, 0x7,0x43,0x6c, 0xf,0x61,0x26, + 0xf,0x61,0x27, 0x7,0x4a,0x6c, 0x7,0x4a,0x6d, 0x7,0x4a,0x6a, + 0xf,0x64,0x26, 0xf,0x64,0x27, 0x7,0x4a,0x6b, 0x7,0x4a,0x69, + 0x4,0x64,0x5e, 0x7,0x50,0x4d, 0xf,0x66,0x48, 0xf,0x66,0x49, + 0x7,0x50,0x4e, 0x7,0x55,0x46, 0x5,0x71,0x4d, 0x7,0x55,0x47, + 0x7,0x55,0x48, 0x7,0x55,0x49, 0x7,0x59,0x50, 0xf,0x69,0x7c, + 0x5,0x76,0x56, 0x5,0x79,0x51, 0x6,0x34,0x5c, 0x5,0x2b,0x4e, + 0x6,0x34,0x5e, 0xf,0x2d,0x52, 0xf,0x2d,0x54, 0x6,0x3c,0x45, + 0x5,0x30,0x54, 0x6,0x3c,0x47, 0xf,0x32,0x5f, 0xf,0x32,0x60, + 0x6,0x3c,0x46, 0x5,0x30,0x53, 0xf,0x32,0x5e, 0x5,0x35,0x7b, + 0x6,0x45,0x4e, 0x6,0x45,0x4d, 0x6,0x45,0x46, 0x4,0x35,0x64, + 0x5,0x36,0x22, 0x5,0x36,0x21, 0x6,0x45,0x4a, 0x5,0x35,0x7d, + 0x6,0x45,0x47, 0x6,0x45,0x4c, 0x6,0x45,0x4b, 0x5,0x35,0x7c, + 0x5,0x35,0x7e, 0xf,0x38,0x6d, 0x6,0x45,0x48, 0x6,0x45,0x49, + 0x4,0x35,0x65, 0x6,0x4f,0x46, 0x6,0x4f,0x47, 0x5,0x3c,0x70, + 0x5,0x3c,0x6e, 0x6,0x4f,0x45, 0x6,0x4f,0x44, 0x6,0x4f,0x42, + 0x5,0x36,0x23, 0x5,0x3c,0x6d, 0x5,0x3c,0x68, 0x5,0x3c,0x6b, + 0x5,0x3c,0x6a, 0x6,0x4f,0x43, 0x5,0x3c,0x69, 0x5,0x3c,0x71, + 0x5,0x3c,0x6c, 0x5,0x3c,0x6f, 0x6,0x59,0x23, 0x6,0x59,0x28, + 0x5,0x43,0x53, 0x6,0x59,0x26, 0x6,0x59,0x29, 0x5,0x43,0x51, + 0x4,0x41,0x2b, 0x5,0x43,0x52, 0x5,0x43,0x4f, 0x6,0x59,0x27, + 0x5,0x43,0x4e, 0xf,0x45,0x5d, 0xf,0x45,0x5e, 0xf,0x45,0x5f, + 0x6,0x59,0x25, 0x4,0x41,0x2d, 0x5,0x43,0x54, 0x6,0x63,0x2d, + 0x6,0x63,0x2f, 0x5,0x4a,0x50, 0x4,0x47,0x68, 0x6,0x63,0x28, + 0x6,0x63,0x2b, 0x5,0x4a,0x4d, 0x6,0x63,0x2c, 0x6,0x63,0x27, + 0x6,0x63,0x30, 0x5,0x4a,0x4b, 0x5,0x4a,0x4e, 0x6,0x63,0x31, + 0x6,0x63,0x2e, 0xf,0x4c,0x5f, 0xf,0x4c,0x60, 0xf,0x4c,0x61, + 0xf,0x4c,0x63, 0x5,0x4a,0x4f, 0x5,0x4a,0x4c, 0x7,0x29,0x59, + 0x6,0x63,0x2a, 0x5,0x51,0x60, 0x7,0x29,0x57, 0x7,0x29,0x5e, + 0x7,0x29,0x62, 0x7,0x29,0x56, 0x5,0x51,0x59, 0x7,0x29,0x5a, + 0x7,0x29,0x55, 0x7,0x29,0x5c, 0x5,0x51,0x58, 0x5,0x51,0x5b, + 0x5,0x51,0x5e, 0x4,0x4e,0x2c, 0x6,0x63,0x29, 0x7,0x29,0x58, + 0x7,0x29,0x5d, 0x7,0x29,0x5b, 0x5,0x51,0x5d, 0x5,0x51,0x5f, + 0x7,0x29,0x52, 0x5,0x51,0x57, 0x7,0x29,0x54, 0x7,0x29,0x63, + 0xf,0x52,0x49, 0xf,0x52,0x4a, 0xf,0x52,0x4b, 0xf,0x52,0x4c, + 0x7,0x29,0x53, 0x7,0x29,0x5f, 0x7,0x29,0x60, 0x7,0x29,0x61, + 0x5,0x51,0x5c, 0x5,0x51,0x5a, 0x7,0x34,0x29, 0x5,0x58,0x73, + 0x7,0x34,0x2f, 0x5,0x58,0x74, 0x7,0x34,0x2d, 0x5,0x58,0x70, + 0x7,0x34,0x2b, 0x7,0x34,0x34, 0x5,0x58,0x6e, 0x5,0x58,0x71, + 0x5,0x58,0x6d, 0x7,0x34,0x35, 0x7,0x34,0x30, 0x7,0x34,0x36, + 0x5,0x58,0x6c, 0x7,0x34,0x33, 0xf,0x58,0x37, 0xf,0x58,0x39, + 0xf,0x58,0x3a, 0x7,0x34,0x2c, 0x7,0x34,0x2e, 0x7,0x34,0x2a, + 0xf,0x58,0x38, 0x4,0x54,0x35, 0x5,0x58,0x6f, 0x7,0x3c,0x4a, + 0x7,0x3c,0x52, 0x5,0x5f,0x25, 0x7,0x3c,0x4d, 0x7,0x3c,0x4c, + 0x7,0x3c,0x4b, 0x7,0x3c,0x53, 0x4,0x59,0x33, 0x7,0x3c,0x50, + 0x4,0x59,0x34, 0x7,0x3c,0x51, 0x5,0x5f,0x22, 0x5,0x5f,0x2b, + 0x4,0x59,0x36, 0x5,0x5f,0x28, 0x5,0x5f,0x27, 0x7,0x3c,0x54, + 0x5,0x5f,0x24, 0x5,0x5f,0x2a, 0x7,0x3c,0x49, 0xf,0x5c,0x7c, + 0xf,0x5c,0x7d, 0x7,0x3c,0x4e, 0x7,0x3c,0x4f, 0x5,0x5f,0x26, + 0x5,0x5f,0x23, 0x5,0x5f,0x29, 0x4,0x5d,0x79, 0x7,0x43,0x70, + 0x4,0x5e,0x21, 0x5,0x65,0x32, 0x5,0x65,0x34, 0xf,0x61,0x28, + 0xf,0x61,0x29, 0xf,0x61,0x2a, 0x7,0x43,0x6f, 0x7,0x43,0x72, + 0x7,0x43,0x71, 0x7,0x43,0x6e, 0x7,0x43,0x6d, 0x5,0x65,0x31, + 0x5,0x65,0x33, 0x5,0x69,0x78, 0x7,0x4a,0x6e, 0x7,0x4a,0x71, + 0x7,0x4a,0x6f, 0x7,0x4a,0x70, 0x5,0x69,0x7a, 0x4,0x61,0x5a, + 0x4,0x61,0x5b, 0x5,0x69,0x79, 0x5,0x69,0x77, 0x5,0x69,0x7b, + 0x7,0x4a,0x72, 0xf,0x64,0x28, 0x7,0x4a,0x74, 0x4,0x64,0x62, + 0x5,0x6e,0x25, 0x5,0x6e,0x23, 0x7,0x50,0x53, 0x5,0x6e,0x24, + 0x5,0x6e,0x22, 0x7,0x50,0x51, 0x5,0x6e,0x21, 0xf,0x66,0x4a, + 0x7,0x50,0x52, 0x7,0x50,0x50, 0x7,0x50,0x4f, 0x5,0x6e,0x26, + 0x7,0x50,0x54, 0x4,0x67,0x53, 0x5,0x71,0x4e, 0x4,0x67,0x54, + 0x7,0x55,0x4c, 0x7,0x55,0x4b, 0x7,0x55,0x4a, 0x7,0x59,0x56, + 0x4,0x69,0x50, 0x7,0x59,0x52, 0x7,0x59,0x51, 0x4,0x69,0x51, + 0x7,0x59,0x57, 0x7,0x59,0x53, 0x7,0x59,0x54, 0x7,0x59,0x55, + 0x7,0x5c,0x7e, 0x7,0x5d,0x21, 0x5,0x76,0x57, 0x7,0x5c,0x7b, + 0x7,0x5c,0x7a, 0x7,0x5c,0x7c, 0x7,0x5c,0x7d, 0x5,0x76,0x59, + 0x5,0x76,0x58, 0x5,0x78,0x3c, 0x5,0x78,0x3b, 0x5,0x78,0x3a, + 0x7,0x5f,0x67, 0x7,0x5f,0x65, 0x7,0x5f,0x64, 0x5,0x78,0x39, + 0x7,0x5f,0x66, 0x5,0x79,0x53, 0x5,0x79,0x52, 0x5,0x7a,0x3e, + 0x5,0x7a,0x3f, 0x7,0x62,0x68, 0x5,0x7a,0x7a, 0x7,0x64,0x64, + 0x7,0x62,0x69, 0x7,0x63,0x77, 0x5,0x7b,0x6b, 0x7,0x65,0x66, + 0x6,0x29,0x2b, 0x6,0x2e,0x36, 0x6,0x3c,0x48, 0x6,0x45,0x4f, + 0x5,0x36,0x25, 0x5,0x36,0x24, 0x4,0x41,0x2e, 0x6,0x59,0x2a, + 0xf,0x45,0x61, 0x5,0x4a,0x51, 0xf,0x4c,0x65, 0xf,0x4c,0x66, + 0x5,0x4a,0x52, 0x7,0x29,0x64, 0x7,0x29,0x65, 0x7,0x29,0x66, + 0x5,0x51,0x62, 0x7,0x34,0x37, 0x5,0x58,0x75, 0x7,0x34,0x38, + 0xf,0x58,0x3b, 0x5,0x5f,0x2d, 0x5,0x5f,0x2c, 0xf,0x5c,0x7e, + 0xf,0x5d,0x21, 0xf,0x5d,0x22, 0xf,0x5d,0x23, 0x5,0x5f,0x2e, + 0x5,0x65,0x37, 0x5,0x65,0x36, 0x7,0x43,0x73, 0x7,0x4a,0x75, + 0x4,0x61,0x5c, 0x7,0x4a,0x76, 0xf,0x66,0x4b, 0x7,0x50,0x55, + 0xf,0x68,0x54, 0x7,0x59,0x58, 0x7,0x5f,0x68, 0x7,0x65,0x47, + 0x7,0x65,0x67, 0x6,0x29,0x2c, 0x6,0x2e,0x37, 0x6,0x59,0x2d, + 0x6,0x59,0x2c, 0x6,0x59,0x2b, 0xf,0x52,0x4d, 0x7,0x33,0x21, + 0x4,0x61,0x5d, 0x7,0x55,0x4d, 0x6,0x25,0x59, 0x6,0x25,0x58, + 0x6,0x25,0x57, 0x4,0x24,0x7e, 0x6,0x29,0x2d, 0x4,0x25,0x24, + 0x6,0x3c,0x49, 0x6,0x29,0x2e, 0xf,0x25,0x33, 0xf,0x25,0x34, + 0x6,0x3c,0x4a, 0x6,0x29,0x2f, 0x5,0x24,0x78, 0x6,0x3c,0x4b, + 0x6,0x45,0x50, 0x5,0x27,0x6a, 0x5,0x27,0x6b, 0x5,0x27,0x70, + 0x6,0x2e,0x38, 0x6,0x2e,0x3d, 0x5,0x27,0x6f, 0x4,0x28,0x25, + 0x5,0x27,0x71, 0x5,0x27,0x6d, 0x4,0x28,0x28, 0x6,0x2e,0x3b, + 0xf,0x28,0x6d, 0xf,0x28,0x6f, 0xf,0x28,0x70, 0xf,0x28,0x73, + 0xf,0x28,0x74, 0xf,0x28,0x75, 0x6,0x2e,0x3a, 0x6,0x2e,0x3f, + 0x5,0x27,0x6e, 0x5,0x27,0x68, 0x6,0x2e,0x3c, 0x5,0x27,0x6c, + 0x6,0x2e,0x39, 0x6,0x2e,0x3e, 0x5,0x2b,0x4f, 0x5,0x2b,0x56, + 0x5,0x2b,0x52, 0x6,0x34,0x5f, 0x5,0x2b,0x51, 0x6,0x34,0x62, + 0x5,0x2b,0x55, 0x5,0x2b,0x53, 0x4,0x2b,0x4f, 0x4,0x2b,0x51, + 0x5,0x2b,0x50, 0x6,0x34,0x64, 0x6,0x34,0x63, 0xf,0x2d,0x55, + 0xf,0x2d,0x56, 0xf,0x2d,0x57, 0xf,0x2d,0x58, 0xf,0x2d,0x59, + 0x4,0x2b,0x52, 0x6,0x34,0x65, 0x6,0x34,0x61, 0x6,0x4a,0x47, + 0x5,0x2b,0x57, 0x5,0x2b,0x54, 0x6,0x3c,0x54, 0x6,0x3c,0x58, + 0x5,0x30,0x5b, 0x6,0x3c,0x53, 0x5,0x30,0x56, 0x5,0x30,0x5a, + 0x4,0x30,0x31, 0x5,0x30,0x57, 0x5,0x30,0x59, 0x6,0x3c,0x52, + 0x6,0x3c,0x4c, 0x6,0x3c,0x56, 0x4,0x30,0x32, 0x6,0x3c,0x57, + 0x6,0x3c,0x4d, 0x5,0x43,0x55, 0x6,0x3c,0x55, 0x5,0x30,0x58, + 0x6,0x3c,0x50, 0x6,0x3c,0x4e, 0x5,0x30,0x5c, 0x5,0x36,0x27, + 0x5,0x36,0x26, 0x6,0x3c,0x4f, 0x6,0x45,0x5b, 0x5,0x36,0x2c, + 0x4,0x35,0x6a, 0x6,0x45,0x5c, 0x5,0x36,0x2b, 0x6,0x3c,0x51, + 0x5,0x36,0x29, 0x6,0x45,0x57, 0x6,0x45,0x5a, 0xf,0x38,0x70, + 0xf,0x38,0x71, 0xf,0x38,0x72, 0x6,0x45,0x56, 0x6,0x45,0x54, + 0x6,0x45,0x55, 0x6,0x45,0x52, 0x6,0x45,0x5d, 0x6,0x45,0x58, + 0x6,0x45,0x53, 0x5,0x36,0x2a, 0x4,0x35,0x67, 0x6,0x45,0x59, + 0x5,0x36,0x2d, 0x5,0x36,0x28, 0xf,0x38,0x6f, 0x6,0x45,0x51, + 0x5,0x3c,0x76, 0x5,0x3c,0x72, 0x5,0x3c,0x78, 0x5,0x3c,0x77, + 0x4,0x3b,0x56, 0x6,0x4f,0x53, 0x4,0x3b,0x5a, 0x4,0x3b,0x58, + 0x5,0x3c,0x79, 0x6,0x4f,0x52, 0x7,0x29,0x67, 0x6,0x4f,0x4d, + 0x6,0x4f,0x4c, 0x6,0x4f,0x50, 0x6,0x4f,0x4f, 0x4,0x3b,0x5b, + 0x6,0x4f,0x49, 0x6,0x4f,0x4b, 0xf,0x3f,0x62, 0x6,0x4f,0x51, + 0x6,0x4f,0x54, 0x6,0x4f,0x55, 0x6,0x4f,0x4a, 0xf,0x3f,0x59, + 0xf,0x3f,0x5a, 0xf,0x3f,0x5b, 0xf,0x3f,0x5c, 0xf,0x3f,0x5d, + 0xf,0x3f,0x5f, 0xf,0x3f,0x60, 0xf,0x3f,0x61, 0x5,0x3c,0x75, + 0x6,0x4f,0x4e, 0x5,0x3c,0x74, 0x5,0x3c,0x73, 0x4,0x3b,0x59, + 0x6,0x4f,0x56, 0x6,0x59,0x40, 0x6,0x59,0x34, 0x6,0x59,0x3d, + 0x6,0x59,0x30, 0x4,0x41,0x31, 0x4,0x41,0x30, 0x6,0x59,0x2e, + 0x5,0x43,0x59, 0x6,0x59,0x31, 0x6,0x59,0x41, 0x6,0x59,0x3b, + 0x6,0x59,0x3f, 0x6,0x59,0x37, 0x6,0x59,0x35, 0x6,0x59,0x43, + 0x6,0x59,0x42, 0x5,0x3c,0x7a, 0x4,0x41,0x32, 0x6,0x59,0x33, + 0x6,0x59,0x3e, 0xf,0x45,0x62, 0xf,0x45,0x63, 0xf,0x45,0x64, + 0xf,0x45,0x65, 0xf,0x45,0x66, 0xf,0x45,0x67, 0xf,0x45,0x68, + 0xf,0x45,0x69, 0xf,0x45,0x6a, 0xf,0x45,0x6b, 0xf,0x45,0x6c, + 0x6,0x59,0x32, 0x6,0x59,0x36, 0x6,0x59,0x3c, 0x6,0x59,0x39, + 0x6,0x59,0x38, 0x6,0x59,0x3a, 0x6,0x59,0x2f, 0x5,0x43,0x58, + 0x5,0x43,0x57, 0x5,0x43,0x56, 0x6,0x63,0x35, 0x6,0x63,0x34, + 0x6,0x63,0x37, 0x6,0x63,0x32, 0x6,0x63,0x3a, 0x5,0x4a,0x54, + 0x6,0x63,0x36, 0x6,0x63,0x38, 0x6,0x63,0x3c, 0x5,0x4a,0x53, + 0x5,0x4a,0x56, 0x6,0x63,0x33, 0x6,0x63,0x3b, 0x7,0x3c,0x55, + 0xf,0x4c,0x69, 0xf,0x4c,0x6a, 0xf,0x4c,0x6c, 0xf,0x4c,0x6d, + 0xf,0x4c,0x6e, 0xf,0x4c,0x6f, 0xf,0x4c,0x70, 0xf,0x4c,0x71, + 0xf,0x4c,0x72, 0x6,0x63,0x39, 0x7,0x3c,0x56, 0x7,0x3c,0x57, + 0x7,0x3c,0x58, 0x5,0x4a,0x55, 0x7,0x29,0x6e, 0x7,0x29,0x6c, + 0x7,0x29,0x72, 0x7,0x29,0x69, 0x7,0x29,0x6b, 0x4,0x4e,0x2f, + 0x5,0x51,0x64, 0x4,0x4e,0x30, 0x5,0x51,0x68, 0x5,0x51,0x65, + 0x4,0x4e,0x34, 0x7,0x29,0x70, 0xf,0x52,0x4e, 0xf,0x52,0x4f, + 0xf,0x52,0x50, 0xf,0x52,0x51, 0xf,0x52,0x52, 0x5,0x51,0x6d, + 0x7,0x29,0x6a, 0x7,0x29,0x6f, 0x7,0x29,0x74, 0x7,0x29,0x75, + 0x7,0x29,0x71, 0x7,0x29,0x73, 0x7,0x43,0x74, 0x7,0x29,0x68, + 0x7,0x43,0x75, 0x7,0x29,0x6d, 0x5,0x51,0x69, 0x5,0x51,0x67, + 0x5,0x51,0x6c, 0x5,0x51,0x66, 0x5,0x51,0x6a, 0x5,0x51,0x6b, + 0x5,0x51,0x63, 0x7,0x34,0x46, 0x5,0x58,0x7c, 0x5,0x58,0x7b, + 0x5,0x58,0x79, 0x7,0x34,0x41, 0x5,0x58,0x77, 0x7,0x34,0x45, + 0x7,0x34,0x3e, 0x7,0x34,0x47, 0x4,0x54,0x36, 0x7,0x34,0x42, + 0x7,0x34,0x44, 0x7,0x34,0x39, 0x7,0x34,0x4a, 0x7,0x4a,0x77, + 0x7,0x34,0x3c, 0x7,0x34,0x40, 0x7,0x34,0x4c, 0xf,0x58,0x3c, + 0xf,0x58,0x3d, 0xf,0x58,0x3e, 0x7,0x34,0x3d, 0xf,0x58,0x3f, + 0x7,0x2c,0x5a, 0x7,0x34,0x48, 0x7,0x34,0x3b, 0x7,0x34,0x3a, + 0x7,0x34,0x43, 0x7,0x34,0x4b, 0x5,0x58,0x78, 0x5,0x58,0x7d, + 0x5,0x58,0x7a, 0x7,0x34,0x3f, 0x5,0x58,0x76, 0x5,0x5f,0x2f, + 0x4,0x59,0x3a, 0x7,0x3c,0x60, 0x5,0x5f,0x33, 0x7,0x3c,0x5d, + 0x5,0x5f,0x34, 0x7,0x3c,0x5b, 0x7,0x50,0x57, 0x7,0x34,0x49, + 0x7,0x3c,0x62, 0x7,0x3c,0x5e, 0x5,0x5f,0x32, 0x5,0x5f,0x35, + 0xf,0x5d,0x24, 0xf,0x5d,0x26, 0xf,0x5d,0x27, 0xf,0x5d,0x28, + 0x7,0x3c,0x59, 0x7,0x3c,0x5c, 0x7,0x3c,0x5f, 0x7,0x3c,0x63, + 0xf,0x5d,0x25, 0x5,0x5f,0x36, 0x5,0x5f,0x37, 0x5,0x5f,0x31, + 0x5,0x5f,0x30, 0x7,0x3c,0x5a, 0x5,0x65,0x3d, 0x7,0x43,0x7c, + 0x4,0x5e,0x22, 0x7,0x43,0x7a, 0x5,0x65,0x3a, 0x7,0x43,0x78, + 0xf,0x61,0x2b, 0xf,0x61,0x2c, 0xf,0x61,0x2d, 0x7,0x44,0x21, + 0x7,0x43,0x7e, 0x5,0x65,0x39, 0x7,0x43,0x7d, 0x7,0x43,0x76, + 0x7,0x43,0x79, 0x5,0x65,0x3c, 0x5,0x65,0x3b, 0x5,0x65,0x38, + 0x7,0x43,0x7b, 0x7,0x4b,0x21, 0x7,0x4b,0x22, 0x7,0x4a,0x7e, + 0xf,0x64,0x2a, 0xf,0x64,0x2b, 0xf,0x64,0x2d, 0xf,0x64,0x2e, + 0x7,0x4a,0x79, 0x7,0x4a,0x7a, 0x7,0x4a,0x7d, 0x7,0x4a,0x7b, + 0x7,0x4a,0x7c, 0x7,0x4a,0x78, 0x5,0x6a,0x21, 0x5,0x69,0x7e, + 0xf,0x64,0x2c, 0x7,0x50,0x5a, 0x5,0x6e,0x29, 0x7,0x50,0x59, + 0x5,0x6e,0x27, 0xf,0x66,0x4c, 0x7,0x50,0x58, 0x5,0x6e,0x28, + 0x7,0x5d,0x22, 0x4,0x67,0x55, 0x7,0x55,0x4f, 0x5,0x71,0x51, + 0x7,0x55,0x50, 0x7,0x55,0x4e, 0xf,0x68,0x55, 0xf,0x68,0x56, + 0xf,0x68,0x57, 0xf,0x68,0x58, 0x5,0x71,0x4f, 0x5,0x71,0x50, + 0x5,0x69,0x7d, 0x7,0x55,0x51, 0x5,0x71,0x52, 0x5,0x74,0x52, + 0x4,0x6b,0x25, 0x7,0x59,0x5b, 0x7,0x59,0x5a, 0x7,0x59,0x59, + 0x7,0x5d,0x23, 0x7,0x5d,0x25, 0x7,0x5d,0x24, 0x7,0x62,0x6a, + 0x7,0x5f,0x6a, 0x7,0x5f,0x69, 0x5,0x78,0x3d, 0x7,0x61,0x55, + 0x7,0x62,0x6b, 0x7,0x65,0x68, 0x6,0x29,0x30, 0x5,0x21,0x7c, + 0x5,0x23,0x2c, 0x5,0x23,0x2b, 0x5,0x23,0x2d, 0x5,0x23,0x2a, + 0x4,0x23,0x31, 0x6,0x25,0x5a, 0x6,0x25,0x5c, 0x4,0x23,0x33, + 0x4,0x25,0x27, 0x5,0x24,0x79, 0x4,0x25,0x26, 0x4,0x25,0x28, + 0x4,0x25,0x25, 0x6,0x29,0x33, 0x4,0x25,0x2a, 0x5,0x24,0x7a, + 0x4,0x35,0x71, 0x6,0x29,0x32, 0xf,0x25,0x35, 0xf,0x25,0x36, + 0xf,0x25,0x37, 0xf,0x38,0x73, 0xf,0x38,0x75, 0x6,0x45,0x61, + 0x6,0x45,0x5f, 0x6,0x45,0x60, 0x6,0x29,0x31, 0x4,0x25,0x29, + 0x4,0x28,0x2e, 0x6,0x45,0x5e, 0x4,0x28,0x2a, 0x4,0x28,0x2d, + 0x4,0x28,0x2c, 0x6,0x34,0x69, 0x4,0x28,0x2f, 0x5,0x27,0x72, + 0x5,0x27,0x73, 0x6,0x4f,0x58, 0x6,0x2e,0x43, 0xf,0x28,0x76, + 0xf,0x28,0x78, 0xf,0x28,0x79, 0xf,0x28,0x7c, 0x6,0x4f,0x5a, + 0x6,0x2e,0x41, 0x6,0x2e,0x42, 0x6,0x2e,0x40, 0xf,0x28,0x77, + 0xf,0x28,0x7b, 0x6,0x4f,0x57, 0x6,0x4f,0x59, 0x5,0x27,0x74, + 0x5,0x2b,0x5a, 0x5,0x2b,0x59, 0x5,0x2b,0x58, 0x4,0x2b,0x57, + 0x4,0x2b,0x55, 0x5,0x2b,0x5f, 0x4,0x41,0x33, 0x5,0x2b,0x5b, + 0xf,0x2d,0x5a, 0xf,0x45,0x6e, 0x6,0x59,0x45, 0x6,0x59,0x44, + 0x6,0x59,0x46, 0x6,0x34,0x6c, 0x6,0x34,0x66, 0x6,0x34,0x67, + 0x6,0x34,0x68, 0x6,0x34,0x6b, 0x6,0x34,0x6a, 0x5,0x2b,0x5e, + 0x5,0x2b,0x5c, 0x5,0x2b,0x5d, 0x5,0x30,0x61, 0x5,0x30,0x5d, + 0x4,0x30,0x36, 0x6,0x3c,0x5b, 0x5,0x30,0x65, 0x5,0x30,0x66, + 0x5,0x30,0x5e, 0x5,0x30,0x63, 0x5,0x30,0x5f, 0x4,0x30,0x35, + 0x6,0x3c,0x5d, 0x4,0x30,0x37, 0x6,0x3c,0x5f, 0x6,0x63,0x3d, + 0x6,0x63,0x3f, 0x6,0x63,0x40, 0x6,0x3c,0x5c, 0x6,0x3c,0x5e, + 0x6,0x3c,0x5a, 0x5,0x30,0x62, 0x5,0x30,0x64, 0x5,0x30,0x60, + 0x5,0x30,0x67, 0x6,0x63,0x3e, 0x6,0x3c,0x59, 0xf,0x32,0x62, + 0xf,0x32,0x63, 0xf,0x32,0x64, 0x5,0x51,0x6e, 0x4,0x4e,0x36, + 0x4,0x35,0x6f, 0x5,0x36,0x31, 0x5,0x36,0x30, 0x5,0x36,0x35, + 0x5,0x36,0x2e, 0x5,0x36,0x32, 0x4,0x35,0x6d, 0x6,0x45,0x66, + 0x5,0x36,0x34, 0x7,0x29,0x7a, 0x7,0x29,0x79, 0x6,0x45,0x68, + 0xf,0x32,0x61, 0xf,0x38,0x76, 0xf,0x52,0x54, 0x7,0x29,0x76, + 0x7,0x29,0x77, 0x7,0x29,0x7b, 0x7,0x29,0x78, 0x6,0x45,0x63, + 0x6,0x45,0x65, 0x6,0x45,0x64, 0x6,0x45,0x62, 0xf,0x33,0x3c, + 0x6,0x45,0x67, 0x5,0x36,0x2f, 0x5,0x36,0x33, 0x5,0x30,0x68, + 0x4,0x3b,0x5f, 0x5,0x3d,0x23, 0x5,0x3c,0x7e, 0x5,0x3d,0x22, + 0x4,0x3b,0x5d, 0x5,0x3d,0x24, 0x6,0x4f,0x64, 0x5,0x3d,0x21, + 0x5,0x43,0x67, 0x5,0x3c,0x7d, 0x5,0x3c,0x7c, 0x6,0x4f,0x62, + 0x6,0x4f,0x5b, 0x4,0x3b,0x5c, 0xf,0x3f,0x63, 0xf,0x3f,0x64, + 0xf,0x3f,0x65, 0xf,0x58,0x41, 0x7,0x34,0x4e, 0x6,0x4f,0x5d, + 0x6,0x4f,0x5c, 0x6,0x4f,0x5e, 0x6,0x4f,0x5f, 0x6,0x4f,0x60, + 0x6,0x4f,0x61, 0xf,0x3f,0x66, 0x6,0x4f,0x63, 0x7,0x34,0x4d, + 0x5,0x3c,0x7b, 0x7,0x3c,0x64, 0x5,0x43,0x5b, 0x5,0x43,0x60, + 0x5,0x43,0x63, 0x5,0x43,0x5e, 0x5,0x43,0x5d, 0x4,0x41,0x35, + 0x6,0x63,0x41, 0x5,0x43,0x5c, 0x5,0x43,0x62, 0x5,0x43,0x5f, + 0x5,0x43,0x64, 0x5,0x43,0x66, 0x4,0x41,0x37, 0x5,0x43,0x65, + 0x6,0x59,0x49, 0x5,0x43,0x5a, 0xf,0x45,0x6f, 0x6,0x59,0x48, + 0x6,0x59,0x4b, 0x5,0x43,0x61, 0x4,0x47,0x6f, 0x5,0x4a,0x5d, + 0x5,0x4a,0x5c, 0x5,0x4a,0x59, 0x5,0x4a,0x58, 0x5,0x4a,0x63, + 0x5,0x4a,0x5f, 0x5,0x4a,0x5b, 0x6,0x63,0x46, 0x6,0x63,0x43, + 0x6,0x63,0x42, 0x5,0x4a,0x61, 0x5,0x4a,0x62, 0x7,0x44,0x22, + 0x7,0x44,0x24, 0x7,0x44,0x23, 0x7,0x44,0x25, 0x6,0x63,0x45, + 0x5,0x4a,0x57, 0x4,0x47,0x72, 0x6,0x63,0x44, 0x5,0x65,0x3e, + 0x5,0x4a,0x5a, 0x5,0x4a,0x5e, 0x5,0x4a,0x64, 0x4,0x4e,0x38, + 0x7,0x4b,0x23, 0x5,0x51,0x72, 0x7,0x2a,0x21, 0x4,0x4e,0x37, + 0x5,0x51,0x73, 0x4,0x4e,0x39, 0x5,0x59,0x28, 0x5,0x51,0x6f, + 0x5,0x51,0x70, 0x7,0x29,0x7e, 0x7,0x2a,0x22, 0x4,0x4e,0x3a, + 0xf,0x52,0x53, 0xf,0x52,0x55, 0xf,0x52,0x56, 0x7,0x4b,0x26, + 0x7,0x4b,0x24, 0x7,0x2a,0x23, 0x7,0x2a,0x25, 0x7,0x2a,0x26, + 0x7,0x2a,0x24, 0x7,0x29,0x7c, 0x7,0x29,0x7d, 0x5,0x51,0x74, + 0x7,0x34,0x50, 0x5,0x51,0x71, 0x7,0x4b,0x25, 0x5,0x6e,0x2a, + 0x5,0x59,0x25, 0x5,0x59,0x26, 0x7,0x50,0x5c, 0x4,0x54,0x38, + 0x7,0x34,0x4f, 0x5,0x59,0x21, 0x5,0x59,0x24, 0x7,0x34,0x52, + 0x5,0x59,0x22, 0x5,0x59,0x23, 0x4,0x54,0x39, 0x7,0x34,0x51, + 0xf,0x58,0x40, 0x7,0x50,0x5d, 0x7,0x50,0x5b, 0x5,0x6e,0x2b, + 0x7,0x3c,0x65, 0x7,0x3c,0x69, 0x5,0x5f,0x38, 0x4,0x59,0x3b, + 0x5,0x5f,0x39, 0x7,0x55,0x52, 0x7,0x55,0x53, 0x7,0x55,0x54, + 0x7,0x3c,0x67, 0x7,0x3c,0x6a, 0x7,0x3c,0x66, 0x5,0x5f,0x3b, + 0x5,0x5f,0x3a, 0x7,0x55,0x55, 0x7,0x3c,0x68, 0x5,0x65,0x40, + 0x7,0x44,0x26, 0x7,0x44,0x27, 0x5,0x65,0x41, 0x5,0x6a,0x25, + 0x5,0x65,0x44, 0x7,0x44,0x29, 0x7,0x44,0x28, 0x5,0x65,0x42, + 0x5,0x65,0x43, 0x7,0x59,0x5c, 0x5,0x65,0x3f, 0x7,0x44,0x2a, + 0x7,0x4b,0x28, 0x7,0x44,0x2b, 0x5,0x6a,0x24, 0x7,0x4b,0x27, + 0x5,0x6a,0x23, 0x7,0x4b,0x2a, 0x7,0x4b,0x29, 0x4,0x61,0x60, + 0x5,0x59,0x27, 0x5,0x6a,0x22, 0x4,0x64,0x64, 0x5,0x6e,0x2c, + 0x7,0x50,0x5f, 0x7,0x50,0x61, 0x7,0x50,0x5e, 0x7,0x50,0x60, + 0x4,0x67,0x56, 0xf,0x68,0x59, 0x7,0x55,0x56, 0x7,0x55,0x57, + 0x7,0x59,0x5d, 0x7,0x55,0x58, 0xf,0x68,0x5a, 0x7,0x5d,0x26, + 0x7,0x5f,0x6b, 0x7,0x5f,0x6c, 0x5,0x7b,0x4b, 0x7,0x63,0x78, + 0x4,0x30,0x39, 0xf,0x32,0x65, 0x6,0x3c,0x60, 0x5,0x36,0x38, + 0x5,0x36,0x37, 0x6,0x45,0x72, 0x6,0x45,0x6e, 0x5,0x36,0x39, + 0x4,0x35,0x76, 0x6,0x45,0x6c, 0x6,0x45,0x73, 0x6,0x45,0x69, + 0x4,0x35,0x77, 0x5,0x36,0x3a, 0x6,0x45,0x70, 0x6,0x45,0x6f, + 0x6,0x45,0x6a, 0x6,0x45,0x6b, 0xf,0x38,0x77, 0x6,0x45,0x71, + 0x4,0x35,0x79, 0x6,0x45,0x6d, 0x6,0x45,0x74, 0x6,0x4f,0x6b, + 0x5,0x3d,0x25, 0x5,0x3d,0x26, 0x4,0x3b,0x65, 0x6,0x4f,0x69, + 0x5,0x43,0x6a, 0x4,0x3b,0x62, 0x4,0x3b,0x63, 0x6,0x4f,0x6a, + 0x6,0x4f,0x66, 0x6,0x4f,0x65, 0x4,0x3b,0x61, 0x6,0x4f,0x67, + 0x6,0x4f,0x68, 0xf,0x3f,0x68, 0xf,0x3f,0x69, 0xf,0x3f,0x6a, + 0xf,0x3f,0x6b, 0x6,0x4f,0x6c, 0x5,0x43,0x69, 0x5,0x43,0x6c, + 0x5,0x43,0x68, 0x6,0x59,0x4e, 0x6,0x59,0x4d, 0x5,0x43,0x6b, + 0x6,0x63,0x4a, 0x5,0x4a,0x66, 0x5,0x4a,0x65, 0xf,0x4c,0x73, + 0xf,0x4c,0x74, 0xf,0x4c,0x75, 0xf,0x4c,0x77, 0x6,0x63,0x49, + 0x6,0x63,0x48, 0xf,0x4c,0x78, 0x6,0x63,0x47, 0x7,0x2a,0x28, + 0x5,0x51,0x78, 0x7,0x2a,0x2c, 0x5,0x51,0x79, 0x5,0x51,0x75, + 0x7,0x2a,0x30, 0x5,0x51,0x76, 0x7,0x2a,0x2f, 0x7,0x2a,0x2e, + 0x7,0x2a,0x2d, 0x7,0x2a,0x29, 0x7,0x2a,0x27, 0x5,0x51,0x77, + 0xf,0x4c,0x76, 0xf,0x52,0x58, 0xf,0x52,0x59, 0x7,0x2a,0x2a, + 0x7,0x2a,0x2b, 0x7,0x2a,0x32, 0x7,0x2a,0x31, 0x7,0x34,0x56, + 0x7,0x34,0x55, 0x5,0x59,0x29, 0x7,0x34,0x58, 0x5,0x59,0x2c, + 0x7,0x34,0x5a, 0x4,0x54,0x41, 0x7,0x34,0x5f, 0x4,0x54,0x3e, + 0x4,0x54,0x3f, 0x7,0x34,0x5e, 0x5,0x59,0x2a, 0x7,0x34,0x57, + 0x7,0x34,0x5d, 0x7,0x34,0x5c, 0x5,0x59,0x2b, 0xf,0x58,0x42, + 0xf,0x58,0x43, 0x7,0x34,0x59, 0x7,0x34,0x5b, 0x7,0x34,0x53, + 0x7,0x34,0x60, 0x5,0x5f,0x41, 0x5,0x5f,0x3f, 0x5,0x5f,0x40, + 0x5,0x5f,0x43, 0x4,0x59,0x40, 0x7,0x3c,0x6c, 0x5,0x5f,0x42, + 0x4,0x59,0x3e, 0x7,0x3c,0x6e, 0x5,0x5f,0x3e, 0x7,0x3c,0x74, + 0x5,0x5f,0x44, 0x7,0x3c,0x6d, 0x7,0x3c,0x73, 0xf,0x5d,0x2a, + 0xf,0x5d,0x2b, 0xf,0x5d,0x2c, 0x7,0x3c,0x6f, 0x7,0x3c,0x71, + 0x7,0x3c,0x72, 0x5,0x5f,0x3d, 0x5,0x65,0x46, 0x5,0x65,0x47, + 0x5,0x65,0x49, 0x7,0x44,0x33, 0x7,0x44,0x2f, 0x4,0x5e,0x23, + 0x7,0x44,0x2c, 0x5,0x65,0x48, 0x4,0x5e,0x26, 0x5,0x65,0x4a, + 0x7,0x3c,0x75, 0x4,0x5e,0x25, 0x7,0x44,0x32, 0x5,0x65,0x4b, + 0x7,0x44,0x35, 0x7,0x44,0x36, 0x7,0x44,0x2d, 0xf,0x61,0x2e, + 0x7,0x44,0x31, 0x7,0x44,0x2e, 0x5,0x65,0x4c, 0x7,0x44,0x30, + 0x7,0x4b,0x2f, 0x7,0x4b,0x2c, 0x5,0x6a,0x2e, 0x5,0x6a,0x2b, + 0x5,0x6a,0x27, 0x5,0x6a,0x2a, 0x5,0x6a,0x29, 0x5,0x6a,0x2f, + 0x5,0x6a,0x2c, 0x5,0x6a,0x28, 0x5,0x6a,0x2d, 0x7,0x4b,0x2d, + 0x7,0x4b,0x2e, 0x7,0x4b,0x30, 0x7,0x4b,0x2b, 0x7,0x44,0x34, + 0x5,0x6a,0x30, 0x5,0x6a,0x26, 0x7,0x50,0x62, 0x5,0x6e,0x31, + 0x5,0x6e,0x2e, 0x5,0x6e,0x2f, 0x5,0x6e,0x2d, 0x5,0x6e,0x30, + 0x7,0x50,0x63, 0x7,0x50,0x64, 0xf,0x66,0x4e, 0x7,0x50,0x65, + 0x7,0x50,0x67, 0x7,0x50,0x66, 0x4,0x67,0x59, 0x4,0x67,0x57, + 0x4,0x67,0x58, 0x5,0x71,0x53, 0x7,0x55,0x5a, 0xf,0x68,0x5b, + 0x7,0x55,0x59, 0x7,0x59,0x5e, 0x7,0x59,0x5f, 0x7,0x59,0x62, + 0x5,0x74,0x53, 0x7,0x59,0x61, 0x7,0x59,0x60, 0xf,0x69,0x7d, + 0x7,0x5d,0x27, 0x7,0x5d,0x29, 0x5,0x76,0x5a, 0x7,0x5d,0x2b, + 0x7,0x5d,0x2a, 0x5,0x76,0x5b, 0x7,0x5d,0x28, 0xf,0x6a,0x7a, + 0x5,0x78,0x3f, 0x4,0x6c,0x2f, 0x7,0x5f,0x6d, 0x7,0x5f,0x6e, + 0x5,0x78,0x3e, 0x7,0x62,0x6c, 0x5,0x7a,0x7b, 0x7,0x63,0x7a, + 0x7,0x63,0x79, 0x7,0x64,0x66, 0x7,0x64,0x65, 0x7,0x65,0x78, + 0x7,0x65,0x79, 0x6,0x34,0x6e, 0x5,0x3d,0x27, 0x5,0x36,0x3b, + 0x6,0x63,0x4b, 0x6,0x63,0x4c, 0x5,0x51,0x7a, 0x7,0x2a,0x34, + 0x7,0x2a,0x33, 0x5,0x59,0x2d, 0x7,0x34,0x61, 0x5,0x5f,0x45, + 0xf,0x5d,0x2d, 0x7,0x44,0x37, 0xf,0x66,0x4f, 0xf,0x68,0x5c, + 0x5,0x74,0x54, 0x5,0x36,0x3c, 0x6,0x3c,0x61, 0x6,0x45,0x75, + 0x6,0x4f,0x6e, 0x5,0x3d,0x29, 0x5,0x3d,0x28, 0xf,0x45,0x70, + 0x6,0x63,0x4d, 0x7,0x2a,0x35, 0x5,0x5f,0x46, 0xf,0x61,0x2f, + 0x5,0x65,0x4d, 0xf,0x68,0x5d, 0x5,0x71,0x54, 0x7,0x55,0x5b, + 0x6,0x3c,0x64, 0xf,0x32,0x66, 0x6,0x3c,0x62, 0x5,0x36,0x3d, + 0x6,0x45,0x76, 0x6,0x45,0x77, 0xf,0x38,0x78, 0x6,0x4f,0x73, + 0x6,0x4f,0x74, 0x6,0x4f,0x75, 0x6,0x4f,0x71, 0x6,0x4f,0x72, + 0x6,0x4f,0x78, 0x6,0x4f,0x76, 0x6,0x4f,0x70, 0x6,0x4f,0x79, + 0xf,0x3f,0x6c, 0xf,0x3f,0x6d, 0xf,0x3f,0x6e, 0xf,0x3f,0x6f, + 0xf,0x3f,0x72, 0xf,0x3f,0x74, 0xf,0x3f,0x71, 0x6,0x4f,0x77, + 0xf,0x3f,0x70, 0x4,0x41,0x47, 0x5,0x43,0x6e, 0x4,0x41,0x45, + 0x4,0x41,0x44, 0x6,0x59,0x53, 0x6,0x59,0x4f, 0xf,0x45,0x71, + 0xf,0x45,0x75, 0xf,0x45,0x76, 0xf,0x45,0x77, 0xf,0x45,0x78, + 0x6,0x59,0x55, 0x6,0x59,0x51, 0x6,0x59,0x52, 0xf,0x45,0x79, + 0x6,0x59,0x54, 0x6,0x59,0x50, 0xf,0x45,0x74, 0x5,0x4a,0x67, + 0x5,0x4a,0x68, 0x6,0x63,0x52, 0x5,0x4a,0x69, 0xf,0x4c,0x68, + 0xf,0x4c,0x79, 0xf,0x4c,0x7b, 0xf,0x4c,0x7c, 0xf,0x4c,0x7d, + 0xf,0x4d,0x21, 0xf,0x4d,0x23, 0xf,0x4d,0x24, 0xf,0x4d,0x25, + 0xf,0x4d,0x28, 0xf,0x4d,0x29, 0x6,0x63,0x4e, 0x4,0x47,0x7a, + 0x6,0x63,0x50, 0x6,0x63,0x51, 0xf,0x4d,0x2a, 0x6,0x63,0x54, + 0xf,0x4c,0x7a, 0x6,0x63,0x55, 0xf,0x4d,0x2b, 0xf,0x4d,0x26, + 0xf,0x4c,0x7e, 0x7,0x2a,0x3a, 0x4,0x4e,0x42, 0x5,0x51,0x7e, + 0x7,0x2a,0x41, 0x7,0x2a,0x3b, 0x7,0x2a,0x40, 0x7,0x2a,0x39, + 0x5,0x51,0x7d, 0x7,0x2a,0x43, 0x7,0x2a,0x44, 0x7,0x2a,0x3d, + 0x5,0x51,0x7b, 0x7,0x2a,0x37, 0xf,0x52,0x5b, 0xf,0x52,0x5d, + 0xf,0x52,0x5f, 0xf,0x52,0x60, 0xf,0x52,0x63, 0xf,0x52,0x64, + 0xf,0x52,0x65, 0xf,0x52,0x67, 0xf,0x52,0x68, 0xf,0x52,0x69, + 0xf,0x52,0x6a, 0xf,0x52,0x6c, 0xf,0x52,0x6d, 0x7,0x2a,0x42, + 0x7,0x2a,0x3c, 0x7,0x2a,0x3f, 0x7,0x2a,0x45, 0xf,0x52,0x5e, + 0x7,0x2a,0x36, 0x5,0x51,0x7c, 0xf,0x52,0x62, 0xf,0x52,0x66, + 0xf,0x52,0x5a, 0x5,0x59,0x34, 0x5,0x59,0x37, 0x5,0x59,0x32, + 0x4,0x54,0x47, 0x5,0x59,0x2e, 0x5,0x59,0x30, 0x7,0x34,0x65, + 0x7,0x34,0x64, 0x7,0x34,0x6b, 0x7,0x34,0x69, 0x7,0x34,0x67, + 0x5,0x59,0x36, 0x4,0x54,0x44, 0x7,0x34,0x62, 0x7,0x34,0x6a, + 0x7,0x34,0x68, 0x5,0x59,0x2f, 0x7,0x34,0x66, 0xf,0x52,0x5c, + 0x5,0x59,0x33, 0xf,0x58,0x44, 0xf,0x58,0x46, 0xf,0x58,0x47, + 0xf,0x58,0x49, 0xf,0x58,0x4a, 0xf,0x58,0x4b, 0xf,0x58,0x4d, + 0xf,0x58,0x4e, 0xf,0x58,0x4f, 0xf,0x58,0x51, 0xf,0x58,0x53, + 0xf,0x58,0x54, 0xf,0x58,0x56, 0xf,0x58,0x57, 0xf,0x58,0x5a, + 0xf,0x58,0x5c, 0xf,0x58,0x5d, 0xf,0x58,0x5e, 0xf,0x58,0x60, + 0xf,0x58,0x61, 0xf,0x58,0x63, 0xf,0x58,0x64, 0xf,0x58,0x50, + 0xf,0x58,0x52, 0xf,0x58,0x5f, 0xf,0x58,0x45, 0xf,0x58,0x58, + 0x5,0x59,0x38, 0x5,0x59,0x31, 0x5,0x5f,0x48, 0x5,0x5f,0x49, + 0x7,0x3c,0x79, 0x4,0x59,0x43, 0x5,0x5f,0x4c, 0x5,0x5f,0x4b, + 0x7,0x3c,0x7c, 0x5,0x59,0x35, 0x5,0x5f,0x47, 0x7,0x3c,0x7a, + 0x5,0x5f,0x4a, 0x5,0x5f,0x4f, 0x7,0x3c,0x7e, 0x7,0x3d,0x24, + 0x7,0x3d,0x21, 0x7,0x3d,0x25, 0xf,0x5d,0x2f, 0xf,0x5d,0x30, + 0xf,0x5d,0x34, 0xf,0x5d,0x35, 0xf,0x5d,0x36, 0xf,0x5d,0x37, + 0xf,0x5d,0x3a, 0xf,0x5d,0x3b, 0xf,0x5d,0x3c, 0xf,0x5d,0x3d, + 0xf,0x5d,0x3f, 0xf,0x5d,0x40, 0xf,0x5d,0x42, 0xf,0x5d,0x43, + 0xf,0x5d,0x44, 0xf,0x5d,0x45, 0xf,0x5d,0x46, 0xf,0x5d,0x47, + 0xf,0x5d,0x48, 0xf,0x5d,0x49, 0xf,0x5d,0x4b, 0xf,0x5d,0x4e, + 0xf,0x5d,0x4f, 0x7,0x3c,0x7d, 0x7,0x3d,0x22, 0x7,0x3c,0x78, + 0x7,0x3d,0x23, 0x4,0x59,0x48, 0xf,0x5d,0x4a, 0xf,0x5d,0x38, + 0xf,0x5d,0x33, 0xf,0x5d,0x31, 0x5,0x5f,0x4e, 0x5,0x5f,0x4d, + 0xf,0x5d,0x2e, 0x5,0x65,0x51, 0x4,0x5e,0x2d, 0x4,0x5e,0x2e, + 0x5,0x65,0x52, 0x4,0x5e,0x28, 0x4,0x5e,0x2a, 0x7,0x44,0x38, + 0x5,0x65,0x50, 0x5,0x65,0x4e, 0x5,0x6a,0x31, 0x7,0x44,0x3a, + 0x5,0x65,0x53, 0x4,0x5e,0x30, 0x7,0x44,0x40, 0x7,0x44,0x3f, + 0x5,0x65,0x54, 0x5,0x65,0x55, 0x7,0x44,0x41, 0xf,0x61,0x31, + 0xf,0x61,0x32, 0xf,0x61,0x34, 0xf,0x61,0x36, 0xf,0x61,0x37, + 0xf,0x61,0x38, 0xf,0x61,0x3a, 0xf,0x61,0x3c, 0xf,0x61,0x3d, + 0xf,0x61,0x3e, 0xf,0x61,0x40, 0xf,0x61,0x41, 0xf,0x61,0x42, + 0xf,0x61,0x44, 0xf,0x61,0x45, 0xf,0x61,0x46, 0x7,0x44,0x3b, + 0x7,0x44,0x3c, 0x7,0x44,0x3e, 0x7,0x44,0x3d, 0xf,0x61,0x30, + 0xf,0x61,0x39, 0xf,0x61,0x35, 0xf,0x5f,0x5d, 0x4,0x61,0x6b, + 0x7,0x4b,0x33, 0x7,0x4b,0x37, 0x5,0x6a,0x32, 0x7,0x4b,0x34, + 0x5,0x6a,0x34, 0x7,0x4b,0x32, 0x7,0x4b,0x3a, 0x7,0x4b,0x36, + 0x7,0x4b,0x39, 0x7,0x4b,0x3b, 0xf,0x64,0x31, 0xf,0x64,0x32, + 0xf,0x64,0x33, 0xf,0x64,0x35, 0xf,0x64,0x36, 0xf,0x64,0x38, + 0xf,0x64,0x39, 0xf,0x64,0x3a, 0xf,0x64,0x3b, 0xf,0x64,0x3c, + 0xf,0x64,0x3d, 0xf,0x64,0x3f, 0xf,0x64,0x40, 0xf,0x64,0x41, + 0xf,0x64,0x42, 0xf,0x64,0x43, 0xf,0x64,0x44, 0xf,0x64,0x45, + 0x7,0x4b,0x3c, 0x7,0x4b,0x35, 0x7,0x4b,0x38, 0x4,0x61,0x6a, + 0x7,0x4b,0x31, 0x5,0x65,0x56, 0xf,0x64,0x3e, 0x4,0x64,0x68, + 0x7,0x50,0x6d, 0x7,0x50,0x6e, 0x5,0x6e,0x38, 0x7,0x50,0x72, + 0x5,0x6e,0x33, 0x4,0x64,0x6a, 0x5,0x6e,0x36, 0x5,0x6e,0x32, + 0x7,0x50,0x70, 0x7,0x50,0x68, 0x7,0x50,0x69, 0x5,0x6e,0x37, + 0x4,0x64,0x6e, 0x7,0x50,0x71, 0x5,0x6e,0x34, 0xf,0x66,0x50, + 0xf,0x66,0x51, 0xf,0x66,0x53, 0xf,0x66,0x54, 0xf,0x66,0x55, + 0xf,0x66,0x56, 0xf,0x66,0x58, 0xf,0x66,0x59, 0xf,0x66,0x5a, + 0xf,0x66,0x5b, 0xf,0x66,0x5d, 0xf,0x66,0x5f, 0xf,0x66,0x60, + 0xf,0x66,0x61, 0xf,0x66,0x62, 0xf,0x66,0x63, 0xf,0x66,0x64, + 0xf,0x66,0x66, 0xf,0x66,0x68, 0xf,0x66,0x6a, 0xf,0x66,0x6b, + 0xf,0x66,0x6c, 0xf,0x66,0x6d, 0xf,0x66,0x6e, 0xf,0x66,0x6f, + 0x7,0x50,0x6c, 0x7,0x50,0x6f, 0xf,0x66,0x52, 0xf,0x66,0x5c, + 0xf,0x66,0x67, 0x7,0x50,0x6a, 0x7,0x55,0x62, 0x4,0x67,0x5e, + 0x7,0x55,0x67, 0x7,0x55,0x61, 0x7,0x55,0x5c, 0x4,0x67,0x60, + 0x4,0x67,0x5d, 0x7,0x55,0x60, 0x7,0x55,0x63, 0x7,0x55,0x69, + 0x7,0x55,0x5e, 0xf,0x68,0x5e, 0xf,0x68,0x5f, 0xf,0x68,0x60, + 0xf,0x68,0x61, 0xf,0x68,0x62, 0xf,0x68,0x63, 0xf,0x68,0x64, + 0xf,0x68,0x65, 0xf,0x68,0x66, 0xf,0x68,0x67, 0xf,0x68,0x68, + 0xf,0x68,0x69, 0xf,0x68,0x6b, 0xf,0x68,0x6c, 0xf,0x68,0x6d, + 0xf,0x68,0x6e, 0xf,0x68,0x6f, 0x7,0x55,0x5f, 0x7,0x55,0x64, + 0x7,0x55,0x65, 0x7,0x55,0x66, 0x7,0x55,0x5d, 0xf,0x68,0x6a, + 0x5,0x74,0x57, 0x7,0x59,0x6b, 0x7,0x59,0x6a, 0x7,0x5d,0x30, + 0x7,0x59,0x66, 0x7,0x59,0x64, 0xf,0x69,0x7e, 0xf,0x6a,0x21, + 0xf,0x6a,0x22, 0xf,0x6a,0x23, 0xf,0x6a,0x24, 0xf,0x6a,0x25, + 0xf,0x6a,0x26, 0xf,0x6a,0x27, 0xf,0x6a,0x28, 0xf,0x6a,0x29, + 0xf,0x6a,0x2a, 0xf,0x6a,0x2b, 0x7,0x59,0x63, 0x7,0x59,0x65, + 0x5,0x74,0x56, 0x5,0x76,0x5e, 0x4,0x6b,0x28, 0x5,0x76,0x5c, + 0xf,0x6b,0x2f, 0x7,0x5d,0x2f, 0x7,0x5d,0x2d, 0x7,0x59,0x69, + 0x7,0x5d,0x2c, 0xf,0x6a,0x7c, 0xf,0x6a,0x7d, 0xf,0x6b,0x23, + 0xf,0x6b,0x24, 0xf,0x6b,0x25, 0xf,0x6b,0x26, 0xf,0x6b,0x29, + 0xf,0x6b,0x2a, 0xf,0x6b,0x2b, 0xf,0x6b,0x2c, 0xf,0x6b,0x2d, + 0xf,0x6b,0x2e, 0x7,0x5d,0x2e, 0x7,0x5d,0x31, 0xf,0x6b,0x21, + 0xf,0x6a,0x7e, 0xf,0x6b,0x27, 0x5,0x78,0x40, 0x7,0x5f,0x70, + 0x7,0x5f,0x71, 0x7,0x5f,0x72, 0x7,0x5f,0x6f, 0x7,0x5f,0x73, + 0xf,0x6b,0x68, 0xf,0x6b,0x69, 0xf,0x6b,0x6a, 0xf,0x6b,0x6b, + 0xf,0x6b,0x6c, 0x4,0x6d,0x63, 0x7,0x61,0x57, 0x7,0x61,0x58, + 0xf,0x6b,0x6d, 0xf,0x6c,0x3c, 0xf,0x6c,0x3d, 0x7,0x61,0x56, + 0x7,0x62,0x72, 0x7,0x62,0x6d, 0x7,0x62,0x6e, 0x7,0x62,0x74, + 0x7,0x62,0x70, 0x7,0x62,0x6f, 0x5,0x7a,0x40, 0x7,0x62,0x73, + 0x7,0x62,0x71, 0x7,0x62,0x75, 0xf,0x6c,0x52, 0xf,0x6c,0x53, + 0xf,0x6c,0x54, 0xf,0x6c,0x55, 0xf,0x6c,0x56, 0xf,0x6c,0x57, + 0xf,0x6c,0x58, 0xf,0x6c,0x40, 0x5,0x7a,0x41, 0x5,0x7a,0x7c, + 0x7,0x63,0x7d, 0x7,0x63,0x7b, 0xf,0x6c,0x6f, 0x7,0x63,0x7c, + 0xf,0x6d,0x23, 0x7,0x64,0x68, 0xf,0x6d,0x21, 0x7,0x64,0x67, + 0x7,0x64,0x69, 0xf,0x6d,0x22, 0xf,0x6c,0x3e, 0x7,0x65,0x48, + 0x7,0x65,0x49, 0xf,0x6d,0x29, 0x5,0x7c,0x21, 0xf,0x6d,0x35, + 0xf,0x6d,0x38, 0xf,0x6d,0x39, 0x6,0x2e,0x44, 0x6,0x29,0x34, + 0x5,0x2b,0x60, 0x5,0x36,0x3f, 0x6,0x45,0x7b, 0x5,0x36,0x3e, + 0x5,0x36,0x40, 0x6,0x45,0x7a, 0xf,0x38,0x79, 0x6,0x45,0x79, + 0x6,0x45,0x78, 0x5,0x3d,0x2a, 0x5,0x3d,0x2b, 0x4,0x3b,0x68, + 0x6,0x4f,0x7a, 0x6,0x4f,0x7b, 0xf,0x3f,0x75, 0x6,0x59,0x59, + 0x6,0x59,0x58, 0x4,0x41,0x4a, 0x6,0x59,0x56, 0x6,0x59,0x57, + 0xf,0x45,0x7a, 0x5,0x43,0x70, 0x5,0x43,0x6f, 0x5,0x4a,0x6a, + 0x4,0x47,0x7c, 0x6,0x63,0x56, 0x6,0x63,0x57, 0x5,0x4a,0x6b, + 0x5,0x52,0x21, 0x5,0x52,0x23, 0x5,0x59,0x39, 0x5,0x52,0x22, + 0x5,0x52,0x24, 0x5,0x52,0x25, 0xf,0x58,0x65, 0x5,0x59,0x3b, + 0x7,0x34,0x6e, 0x5,0x59,0x3a, 0x7,0x3d,0x26, 0x7,0x34,0x6d, + 0x7,0x34,0x70, 0x7,0x34,0x6c, 0x7,0x3d,0x29, 0x4,0x59,0x4a, + 0x5,0x5f,0x50, 0x4,0x59,0x4b, 0x7,0x3d,0x2a, 0x7,0x3d,0x28, + 0x7,0x3d,0x27, 0x7,0x44,0x43, 0x5,0x65,0x58, 0x7,0x44,0x42, + 0x5,0x65,0x57, 0x5,0x6a,0x38, 0x5,0x6a,0x36, 0x5,0x6a,0x35, + 0x5,0x6a,0x37, 0x5,0x6e,0x39, 0x7,0x50,0x73, 0x7,0x50,0x74, + 0x4,0x67,0x64, 0x7,0x55,0x6a, 0x7,0x59,0x6d, 0x7,0x59,0x6e, + 0x7,0x59,0x6c, 0x5,0x76,0x61, 0x5,0x76,0x60, 0x5,0x78,0x41, + 0x7,0x5f,0x74, 0x7,0x62,0x76, 0x7,0x64,0x6a, 0x5,0x2b,0x61, + 0x5,0x30,0x6a, 0x5,0x30,0x6b, 0x5,0x30,0x69, 0xf,0x32,0x67, + 0x6,0x3c,0x66, 0x5,0x36,0x42, 0x5,0x36,0x41, 0xf,0x38,0x7a, + 0xf,0x38,0x7b, 0x6,0x45,0x7c, 0x5,0x3d,0x33, 0x5,0x3d,0x31, + 0x5,0x3d,0x2f, 0x4,0x3b,0x6a, 0x5,0x3d,0x30, 0x4,0x3b,0x6c, + 0x3,0x3f,0x6d, 0x5,0x3d,0x2c, 0x5,0x3d,0x2d, 0x5,0x3d,0x2e, + 0x6,0x4f,0x7e, 0x6,0x50,0x21, 0x5,0x3d,0x32, 0x6,0x4f,0x7c, + 0xf,0x3f,0x78, 0xf,0x3f,0x79, 0xf,0x3f,0x7a, 0xf,0x3f,0x7b, + 0xf,0x3f,0x7c, 0xf,0x3f,0x7d, 0xf,0x40,0x21, 0x6,0x4f,0x7d, + 0x4,0x3b,0x69, 0x4,0x41,0x4c, 0x6,0x59,0x5e, 0x4,0x41,0x52, + 0x4,0x41,0x4d, 0x4,0x41,0x4b, 0xf,0x45,0x7e, 0x6,0x59,0x5d, + 0x5,0x43,0x74, 0x5,0x43,0x71, 0x5,0x43,0x73, 0x5,0x43,0x72, + 0x6,0x59,0x5b, 0x4,0x41,0x51, 0x4,0x41,0x4f, 0x6,0x59,0x5c, + 0x6,0x59,0x5a, 0xf,0x45,0x7d, 0xf,0x46,0x21, 0x5,0x4a,0x73, + 0x5,0x4a,0x6f, 0x5,0x4a,0x71, 0x4,0x47,0x7e, 0x5,0x4a,0x6d, + 0x4,0x48,0x21, 0x5,0x4a,0x74, 0x6,0x63,0x5a, 0x5,0x4a,0x70, + 0x5,0x4a,0x75, 0x4,0x47,0x7d, 0x5,0x4a,0x72, 0x5,0x4a,0x76, + 0x6,0x63,0x59, 0x6,0x63,0x5b, 0x6,0x63,0x5c, 0x5,0x4a,0x6c, + 0x7,0x2a,0x48, 0x5,0x52,0x2d, 0x5,0x52,0x28, 0x7,0x2a,0x4d, + 0x5,0x52,0x2a, 0x5,0x52,0x27, 0x7,0x2a,0x4e, 0x4,0x4e,0x49, + 0x5,0x52,0x2c, 0x5,0x52,0x29, 0x7,0x2a,0x4c, 0xf,0x52,0x6e, + 0xf,0x52,0x6f, 0xf,0x52,0x71, 0x7,0x2a,0x47, 0x7,0x2a,0x49, + 0x7,0x2a,0x4a, 0x7,0x2a,0x4b, 0x5,0x52,0x26, 0x5,0x52,0x2b, + 0x5,0x52,0x2e, 0xf,0x52,0x70, 0x4,0x54,0x50, 0x4,0x54,0x4d, + 0x5,0x59,0x3d, 0x5,0x59,0x40, 0x7,0x34,0x72, 0x5,0x59,0x3c, + 0x5,0x59,0x3e, 0x5,0x59,0x3f, 0x7,0x34,0x75, 0x7,0x34,0x77, + 0x7,0x34,0x79, 0xf,0x58,0x66, 0xf,0x58,0x67, 0xf,0x58,0x68, + 0x7,0x34,0x74, 0x7,0x34,0x78, 0x7,0x34,0x76, 0x4,0x54,0x4e, + 0x4,0x59,0x53, 0x4,0x59,0x51, 0x5,0x5f,0x54, 0x7,0x3d,0x2b, + 0x5,0x5f,0x51, 0x5,0x5f,0x53, 0x5,0x5f,0x55, 0x5,0x5f,0x52, + 0x7,0x3d,0x2d, 0x4,0x59,0x50, 0x7,0x3d,0x2c, 0x4,0x59,0x4c, + 0x7,0x3d,0x2e, 0xf,0x5d,0x50, 0x7,0x3d,0x2f, 0x7,0x3d,0x30, + 0x7,0x3d,0x31, 0x5,0x65,0x5f, 0x5,0x65,0x5e, 0x5,0x65,0x5a, + 0x4,0x5e,0x33, 0x7,0x44,0x44, 0x5,0x65,0x5b, 0x5,0x65,0x61, + 0x5,0x65,0x60, 0x7,0x44,0x46, 0x5,0x65,0x5d, 0x5,0x65,0x59, + 0x5,0x65,0x5c, 0xf,0x61,0x47, 0xf,0x61,0x48, 0xf,0x61,0x49, + 0xf,0x61,0x4c, 0xf,0x61,0x4b, 0x7,0x44,0x45, 0x7,0x44,0x47, + 0x5,0x6a,0x39, 0x7,0x4b,0x3e, 0x7,0x4b,0x3f, 0x4,0x61,0x6d, + 0x5,0x6a,0x3a, 0x7,0x4b,0x3d, 0x4,0x61,0x6e, 0xf,0x64,0x46, + 0xf,0x64,0x47, 0xf,0x64,0x48, 0xf,0x64,0x49, 0xf,0x64,0x4a, + 0x4,0x64,0x70, 0x5,0x6e,0x3f, 0x5,0x6e,0x3a, 0x5,0x6e,0x3d, + 0x5,0x6e,0x3c, 0x5,0x6e,0x3e, 0x5,0x6e,0x40, 0x4,0x64,0x72, + 0x7,0x50,0x78, 0x5,0x6a,0x3b, 0x7,0x50,0x75, 0xf,0x66,0x70, + 0xf,0x66,0x71, 0x7,0x50,0x76, 0x5,0x6e,0x3b, 0x7,0x50,0x77, + 0x5,0x71,0x5a, 0x5,0x6e,0x41, 0x4,0x67,0x65, 0x5,0x71,0x59, + 0x5,0x71,0x57, 0xf,0x68,0x70, 0xf,0x68,0x71, 0xf,0x68,0x73, + 0xf,0x68,0x74, 0xf,0x68,0x75, 0x5,0x71,0x5c, 0x5,0x71,0x58, + 0x5,0x74,0x58, 0x7,0x55,0x6b, 0xf,0x6a,0x2f, 0x7,0x59,0x6f, + 0xf,0x6a,0x2c, 0xf,0x6a,0x2d, 0xf,0x6a,0x2e, 0xf,0x6a,0x30, + 0xf,0x6a,0x31, 0xf,0x6b,0x30, 0xf,0x6b,0x31, 0xf,0x6b,0x32, + 0x7,0x5d,0x32, 0x5,0x78,0x42, 0xf,0x6b,0x6e, 0xf,0x6b,0x6f, + 0x7,0x5f,0x76, 0x7,0x5f,0x75, 0x5,0x79,0x54, 0x4,0x6d,0x29, + 0x4,0x6d,0x2a, 0x7,0x61,0x59, 0x7,0x62,0x77, 0x7,0x62,0x78, + 0x5,0x7a,0x7d, 0xf,0x6d,0x2a, 0x6,0x2e,0x45, 0x5,0x22,0x22, + 0x5,0x21,0x7e, 0x4,0x22,0x23, 0x5,0x22,0x23, 0x4,0x22,0x22, + 0x5,0x22,0x21, 0x5,0x23,0x2e, 0x4,0x23,0x34, 0x6,0x25,0x5d, + 0x5,0x24,0x7d, 0x4,0x25,0x2c, 0x4,0x25,0x2d, 0x5,0x24,0x7e, + 0x5,0x24,0x7c, 0xf,0x25,0x3a, 0xf,0x25,0x3b, 0xf,0x25,0x3c, + 0xf,0x25,0x3d, 0xf,0x25,0x3e, 0xf,0x25,0x3f, 0x5,0x27,0x75, + 0x6,0x2e,0x47, 0x5,0x27,0x76, 0x5,0x27,0x78, 0x5,0x27,0x79, + 0x4,0x28,0x30, 0x5,0x27,0x77, 0x6,0x2e,0x46, 0x6,0x2e,0x48, + 0xf,0x28,0x7d, 0xf,0x28,0x7e, 0x5,0x2b,0x62, 0x6,0x34,0x70, + 0x6,0x34,0x73, 0x4,0x2b,0x5c, 0x5,0x2b,0x65, 0x6,0x34,0x71, + 0x6,0x63,0x5d, 0x6,0x34,0x75, 0x6,0x34,0x76, 0x6,0x34,0x77, + 0x6,0x34,0x72, 0x5,0x2b,0x63, 0x6,0x34,0x78, 0xf,0x2d,0x5b, + 0xf,0x2d,0x5c, 0xf,0x2d,0x5d, 0x6,0x34,0x74, 0x6,0x34,0x6f, + 0x6,0x3c,0x69, 0x5,0x30,0x6f, 0x5,0x2b,0x66, 0x6,0x3c,0x68, + 0x5,0x30,0x6c, 0x5,0x30,0x6e, 0x6,0x3c,0x6e, 0x6,0x3c,0x6b, + 0x6,0x3c,0x6f, 0x5,0x30,0x6d, 0x6,0x3c,0x6a, 0x6,0x3c,0x6d, + 0x6,0x3c,0x6c, 0xf,0x32,0x68, 0xf,0x32,0x69, 0xf,0x32,0x6a, + 0xf,0x32,0x6b, 0xf,0x32,0x6c, 0xf,0x32,0x6d, 0xf,0x32,0x6e, + 0x5,0x36,0x43, 0x6,0x46,0x28, 0x6,0x46,0x21, 0x4,0x35,0x7e, + 0x4,0x36,0x22, 0x4,0x36,0x21, 0x5,0x36,0x44, 0x6,0x46,0x23, + 0x6,0x46,0x24, 0x6,0x46,0x2b, 0x6,0x46,0x2a, 0x6,0x63,0x5e, + 0x6,0x46,0x26, 0x6,0x46,0x22, 0x6,0x46,0x29, 0x6,0x46,0x27, + 0x7,0x34,0x7b, 0x6,0x46,0x25, 0xf,0x38,0x7c, 0xf,0x38,0x7d, + 0xf,0x38,0x7e, 0xf,0x39,0x21, 0xf,0x39,0x22, 0xf,0x39,0x23, + 0xf,0x39,0x24, 0xf,0x39,0x25, 0xf,0x39,0x26, 0xf,0x39,0x27, + 0x5,0x3d,0x38, 0x5,0x3d,0x3d, 0x5,0x3d,0x39, 0x5,0x3d,0x3a, + 0x5,0x3d,0x3c, 0x6,0x50,0x25, 0x6,0x50,0x23, 0x5,0x3d,0x34, + 0x5,0x3d,0x35, 0x5,0x3d,0x37, 0x6,0x50,0x24, 0x6,0x50,0x29, + 0x7,0x3d,0x34, 0x6,0x50,0x27, 0x5,0x3d,0x3b, 0x6,0x50,0x28, + 0x6,0x50,0x26, 0xf,0x40,0x22, 0xf,0x40,0x23, 0x7,0x3d,0x32, + 0x5,0x3d,0x36, 0x6,0x59,0x6a, 0x5,0x43,0x7b, 0x5,0x43,0x78, + 0x6,0x59,0x62, 0x6,0x59,0x69, 0x6,0x59,0x67, 0x5,0x43,0x7c, + 0x5,0x43,0x79, 0x5,0x43,0x77, 0x6,0x63,0x5f, 0x6,0x59,0x63, + 0x6,0x59,0x65, 0x5,0x43,0x7d, 0x5,0x43,0x7a, 0x6,0x59,0x66, + 0x7,0x44,0x49, 0x6,0x59,0x64, 0x7,0x44,0x48, 0x5,0x43,0x76, + 0x6,0x59,0x5f, 0x6,0x59,0x6b, 0x6,0x59,0x60, 0x5,0x43,0x75, + 0x6,0x59,0x61, 0xf,0x46,0x22, 0xf,0x46,0x23, 0xf,0x46,0x24, + 0xf,0x46,0x25, 0xf,0x46,0x26, 0xf,0x46,0x27, 0xf,0x46,0x28, + 0xf,0x46,0x29, 0x6,0x59,0x68, 0x6,0x59,0x6c, 0x7,0x3d,0x33, + 0x6,0x63,0x64, 0x6,0x63,0x62, 0x6,0x63,0x66, 0x4,0x48,0x27, + 0x4,0x48,0x26, 0x5,0x52,0x2f, 0x4,0x48,0x28, 0x4,0x48,0x29, + 0x5,0x4a,0x78, 0x6,0x63,0x63, 0x6,0x63,0x60, 0x4,0x48,0x25, + 0x5,0x4a,0x79, 0x5,0x4a,0x7a, 0x6,0x63,0x65, 0x6,0x63,0x67, + 0x7,0x4b,0x41, 0xf,0x4d,0x2e, 0xf,0x4d,0x2f, 0xf,0x4d,0x30, + 0xf,0x4d,0x31, 0xf,0x4d,0x32, 0xf,0x4d,0x33, 0x6,0x63,0x61, + 0x5,0x4a,0x77, 0x5,0x52,0x36, 0x5,0x52,0x34, 0x5,0x52,0x35, + 0x7,0x2a,0x55, 0x5,0x52,0x38, 0x5,0x52,0x32, 0x5,0x52,0x31, + 0x7,0x2a,0x4f, 0x5,0x52,0x33, 0x5,0x52,0x37, 0x5,0x52,0x30, + 0x7,0x50,0x7a, 0x7,0x2a,0x53, 0x7,0x2a,0x51, 0x7,0x2a,0x50, + 0x7,0x2a,0x52, 0xf,0x52,0x72, 0xf,0x52,0x73, 0xf,0x52,0x74, + 0xf,0x52,0x75, 0xf,0x52,0x76, 0xf,0x52,0x77, 0x7,0x2a,0x56, + 0x5,0x59,0x41, 0x5,0x59,0x42, 0x4,0x54,0x54, 0x7,0x34,0x7c, + 0x5,0x59,0x44, 0x5,0x59,0x43, 0x7,0x34,0x7e, 0x7,0x50,0x79, + 0xf,0x58,0x69, 0xf,0x58,0x6a, 0xf,0x58,0x6b, 0xf,0x58,0x6c, + 0x5,0x6a,0x3c, 0x7,0x34,0x7d, 0x5,0x5f,0x56, 0x5,0x5f,0x57, + 0x7,0x3d,0x36, 0x7,0x3d,0x37, 0x7,0x3d,0x35, 0x5,0x74,0x59, + 0xf,0x5d,0x51, 0xf,0x5d,0x52, 0xf,0x5d,0x53, 0xf,0x5d,0x54, + 0x5,0x65,0x62, 0x7,0x44,0x4c, 0x4,0x5e,0x34, 0x7,0x44,0x4a, + 0x7,0x44,0x4b, 0xf,0x61,0x4d, 0xf,0x61,0x4e, 0xf,0x61,0x4f, + 0xf,0x61,0x50, 0x5,0x6a,0x3d, 0x7,0x4b,0x43, 0x7,0x55,0x6c, + 0x7,0x4b,0x45, 0xf,0x64,0x4c, 0x5,0x78,0x43, 0x7,0x4b,0x42, + 0x7,0x4b,0x44, 0x7,0x5f,0x77, 0xf,0x66,0x72, 0xf,0x66,0x73, + 0x7,0x51,0x72, 0x5,0x71,0x5d, 0x7,0x55,0x6e, 0x7,0x55,0x6d, + 0x7,0x62,0x79, 0x7,0x62,0x7a, 0x7,0x59,0x70, 0x7,0x5d,0x49, + 0x7,0x5f,0x78, 0x5,0x7a,0x7e, 0x5,0x7b,0x21, 0x7,0x66,0x37, + 0x7,0x66,0x28, 0x6,0x59,0x6d, 0x4,0x4e,0x4b, 0x7,0x2a,0x57, + 0xf,0x52,0x79, 0xf,0x52,0x78, 0x5,0x59,0x45, 0x7,0x35,0x21, + 0x4,0x59,0x56, 0x7,0x44,0x4d, 0x7,0x44,0x4e, 0x5,0x6a,0x3e, + 0x7,0x50,0x7b, 0x6,0x3c,0x70, 0x6,0x3c,0x71, 0x6,0x3c,0x72, + 0x6,0x46,0x2c, 0x5,0x36,0x45, 0x4,0x36,0x23, 0x6,0x46,0x2e, + 0x6,0x46,0x2d, 0x6,0x46,0x30, 0x6,0x46,0x2f, 0x4,0x3b,0x70, + 0x6,0x50,0x2c, 0x4,0x3b,0x6e, 0x6,0x50,0x2a, 0x6,0x59,0x73, + 0x6,0x50,0x30, 0x6,0x50,0x2e, 0x6,0x50,0x2b, 0x4,0x3b,0x71, + 0x4,0x3b,0x6f, 0x6,0x50,0x2f, 0x6,0x50,0x2d, 0x6,0x59,0x7b, + 0x5,0x43,0x7e, 0x6,0x59,0x6e, 0x6,0x59,0x71, 0x6,0x59,0x77, + 0x6,0x59,0x75, 0x6,0x59,0x7a, 0x6,0x59,0x72, 0x6,0x59,0x70, + 0x6,0x59,0x74, 0x6,0x59,0x79, 0x6,0x59,0x78, 0x6,0x59,0x6f, + 0x6,0x59,0x76, 0x6,0x63,0x74, 0x6,0x63,0x72, 0x5,0x4a,0x7b, + 0x6,0x63,0x6b, 0x6,0x63,0x6c, 0x6,0x63,0x76, 0x6,0x63,0x68, + 0x6,0x63,0x77, 0x6,0x63,0x70, 0x4,0x48,0x2a, 0x6,0x63,0x75, + 0x6,0x63,0x6f, 0x5,0x4a,0x7c, 0x6,0x63,0x71, 0x6,0x63,0x69, + 0x5,0x4a,0x7d, 0x4,0x48,0x2b, 0x6,0x63,0x6a, 0xf,0x4d,0x34, + 0xf,0x4d,0x35, 0x6,0x63,0x73, 0x6,0x63,0x78, 0x6,0x63,0x6d, + 0x7,0x2a,0x5d, 0x7,0x2a,0x5b, 0x7,0x2a,0x64, 0x7,0x2a,0x5f, + 0x7,0x2a,0x5c, 0x5,0x52,0x3a, 0x7,0x2a,0x5e, 0x7,0x2a,0x66, + 0x7,0x2a,0x62, 0x7,0x2a,0x60, 0x7,0x2a,0x61, 0x7,0x2a,0x63, + 0x7,0x2a,0x5a, 0x7,0x2a,0x58, 0x5,0x52,0x39, 0x7,0x2a,0x65, + 0x7,0x2a,0x67, 0x4,0x59,0x57, 0x4,0x54,0x55, 0x5,0x59,0x47, + 0x7,0x35,0x29, 0x7,0x35,0x24, 0x7,0x35,0x2f, 0x7,0x35,0x22, + 0x7,0x35,0x2d, 0x7,0x35,0x28, 0x7,0x35,0x25, 0x7,0x35,0x2c, + 0x7,0x35,0x2a, 0x7,0x35,0x26, 0x5,0x59,0x46, 0x7,0x35,0x30, + 0x4,0x54,0x56, 0x7,0x35,0x2b, 0x7,0x35,0x33, 0x7,0x35,0x27, + 0x7,0x2a,0x59, 0x7,0x35,0x34, 0x7,0x35,0x31, 0x7,0x35,0x23, + 0x7,0x35,0x32, 0xf,0x58,0x6d, 0x7,0x35,0x2e, 0xf,0x52,0x7a, + 0x4,0x59,0x59, 0x7,0x3d,0x3d, 0x7,0x3d,0x3b, 0x7,0x3d,0x45, + 0x7,0x3d,0x3c, 0x7,0x3d,0x3e, 0x7,0x3d,0x49, 0x7,0x3d,0x3a, + 0x7,0x3d,0x42, 0x7,0x3d,0x39, 0x7,0x3d,0x38, 0x7,0x3d,0x3f, + 0x5,0x5f,0x58, 0x7,0x3d,0x47, 0x7,0x3d,0x41, 0x7,0x3d,0x40, + 0x7,0x3d,0x43, 0x7,0x3d,0x48, 0x7,0x35,0x36, 0xf,0x5d,0x55, + 0xf,0x5d,0x57, 0x7,0x3d,0x44, 0x7,0x3d,0x46, 0x7,0x44,0x50, + 0x7,0x44,0x56, 0x7,0x44,0x52, 0x7,0x44,0x53, 0x7,0x44,0x4f, + 0x5,0x65,0x63, 0x7,0x44,0x57, 0x7,0x44,0x55, 0x5,0x65,0x64, + 0x7,0x44,0x51, 0x7,0x44,0x54, 0x7,0x4b,0x4a, 0x7,0x4b,0x47, + 0x7,0x4b,0x4b, 0x7,0x4b,0x48, 0x5,0x6a,0x3f, 0x7,0x4b,0x4e, + 0x4,0x61,0x6f, 0x5,0x6a,0x40, 0x7,0x4b,0x46, 0x7,0x4b,0x4c, + 0x7,0x4b,0x4d, 0x4,0x61,0x70, 0x7,0x4b,0x49, 0x7,0x4b,0x4f, + 0x7,0x51,0x23, 0x7,0x51,0x27, 0x7,0x50,0x7d, 0x7,0x51,0x2a, + 0x7,0x51,0x24, 0x7,0x51,0x2b, 0x7,0x51,0x28, 0x7,0x50,0x7c, + 0x5,0x6e,0x42, 0x7,0x51,0x25, 0x7,0x51,0x26, 0x5,0x6e,0x43, + 0x7,0x51,0x22, 0xf,0x66,0x74, 0x7,0x50,0x7e, 0x7,0x51,0x2c, + 0x7,0x51,0x29, 0x7,0x55,0x74, 0x4,0x67,0x68, 0x7,0x55,0x72, + 0x7,0x55,0x6f, 0x7,0x55,0x76, 0x7,0x55,0x70, 0x7,0x55,0x75, + 0x7,0x55,0x73, 0x7,0x55,0x77, 0x7,0x51,0x21, 0xf,0x68,0x76, + 0x7,0x55,0x71, 0x7,0x59,0x71, 0x7,0x59,0x72, 0x4,0x69,0x57, + 0x7,0x59,0x75, 0x7,0x59,0x76, 0x7,0x59,0x74, 0xf,0x6a,0x32, + 0x7,0x59,0x73, 0x7,0x5d,0x38, 0x7,0x5d,0x39, 0x7,0x5d,0x3a, + 0x4,0x6b,0x2b, 0x7,0x5d,0x37, 0x7,0x5d,0x33, 0x7,0x5d,0x34, + 0x7,0x5d,0x35, 0x7,0x5d,0x36, 0x7,0x5f,0x7c, 0x7,0x5f,0x7a, + 0x7,0x5f,0x7b, 0x7,0x5f,0x79, 0x7,0x61,0x5a, 0xf,0x6c,0x41, + 0x7,0x63,0x7e, 0x7,0x64,0x6b, 0x7,0x66,0x40, 0xf,0x2d,0x5e, + 0x5,0x30,0x70, 0xf,0x32,0x70, 0x6,0x46,0x32, 0x6,0x46,0x33, + 0x4,0x36,0x25, 0x6,0x46,0x31, 0xf,0x39,0x28, 0xf,0x39,0x29, + 0x5,0x3d,0x40, 0x5,0x3d,0x3e, 0x5,0x3d,0x41, 0x5,0x3d,0x3f, + 0x4,0x3b,0x73, 0x6,0x50,0x33, 0x4,0x3b,0x72, 0x6,0x50,0x32, + 0xf,0x40,0x25, 0xf,0x40,0x27, 0xf,0x40,0x26, 0x4,0x41,0x58, + 0x5,0x44,0x25, 0x5,0x44,0x22, 0x5,0x44,0x21, 0x5,0x44,0x24, + 0x5,0x44,0x23, 0x6,0x59,0x7c, 0xf,0x46,0x2b, 0xf,0x46,0x2c, + 0xf,0x46,0x2d, 0x5,0x44,0x26, 0x5,0x4b,0x22, 0x4,0x48,0x30, + 0x5,0x4b,0x23, 0x5,0x4b,0x21, 0x5,0x4a,0x7e, 0x4,0x48,0x2c, + 0x4,0x48,0x2f, 0x6,0x63,0x7d, 0x4,0x48,0x32, 0x6,0x63,0x7c, + 0x6,0x63,0x7e, 0xf,0x4d,0x37, 0xf,0x4d,0x38, 0x6,0x63,0x7a, + 0x6,0x63,0x79, 0x7,0x2a,0x6a, 0x7,0x2a,0x69, 0x5,0x52,0x45, + 0x5,0x52,0x40, 0x5,0x52,0x41, 0x5,0x52,0x3f, 0x5,0x52,0x3e, + 0x5,0x52,0x43, 0x5,0x52,0x3d, 0x4,0x54,0x57, 0x5,0x52,0x3c, + 0x7,0x2a,0x6b, 0x7,0x2a,0x6c, 0xf,0x46,0x2a, 0xf,0x52,0x7b, + 0xf,0x52,0x7c, 0xf,0x52,0x7d, 0xf,0x52,0x7e, 0xf,0x53,0x21, + 0x7,0x2a,0x68, 0x5,0x52,0x44, 0x5,0x52,0x42, 0x5,0x5f,0x59, + 0x7,0x35,0x3b, 0x4,0x54,0x5b, 0x5,0x59,0x4e, 0x5,0x59,0x4b, + 0x4,0x54,0x5a, 0x7,0x35,0x38, 0x5,0x59,0x4d, 0x5,0x59,0x4a, + 0x7,0x35,0x3a, 0x5,0x59,0x49, 0x7,0x35,0x39, 0x7,0x35,0x37, + 0x5,0x59,0x48, 0x7,0x35,0x3c, 0xf,0x58,0x6e, 0xf,0x58,0x6f, + 0xf,0x58,0x71, 0xf,0x58,0x72, 0xf,0x58,0x73, 0xf,0x58,0x74, + 0xf,0x58,0x75, 0xf,0x58,0x70, 0xf,0x55,0x64, 0x5,0x59,0x4c, + 0x4,0x59,0x5c, 0x4,0x59,0x5a, 0x4,0x59,0x5b, 0x5,0x5f,0x5a, + 0x4,0x59,0x61, 0x5,0x5f,0x5c, 0x4,0x59,0x5e, 0x7,0x3d,0x4a, + 0x5,0x65,0x68, 0x7,0x3d,0x4b, 0x7,0x3d,0x4d, 0x5,0x5f,0x5b, + 0xf,0x5d,0x59, 0x7,0x3d,0x4c, 0x7,0x3d,0x4e, 0xf,0x5d,0x5a, + 0x5,0x5f,0x5d, 0x5,0x65,0x6c, 0x5,0x65,0x6f, 0x7,0x44,0x5f, + 0x7,0x44,0x63, 0x5,0x65,0x69, 0x7,0x44,0x5e, 0x5,0x65,0x66, + 0x7,0x44,0x65, 0x7,0x44,0x62, 0x4,0x5e,0x37, 0x5,0x65,0x65, + 0x5,0x65,0x67, 0x7,0x44,0x61, 0x7,0x44,0x5a, 0x7,0x44,0x5d, + 0x5,0x65,0x6e, 0x7,0x44,0x5b, 0xf,0x61,0x51, 0x7,0x44,0x64, + 0x7,0x44,0x59, 0x7,0x44,0x5c, 0x5,0x65,0x6b, 0x5,0x65,0x6d, + 0xf,0x5d,0x58, 0x5,0x65,0x6a, 0x5,0x6a,0x47, 0x5,0x6a,0x41, + 0x5,0x6a,0x45, 0x5,0x6a,0x42, 0x5,0x6a,0x43, 0x4,0x61,0x72, + 0x5,0x6a,0x46, 0x5,0x6a,0x44, 0x5,0x6a,0x49, 0x4,0x61,0x71, + 0x7,0x4b,0x50, 0x7,0x4b,0x55, 0x7,0x4b,0x51, 0x5,0x6a,0x48, + 0x7,0x4b,0x53, 0xf,0x64,0x4e, 0x7,0x4b,0x57, 0x7,0x4b,0x56, + 0x7,0x4b,0x54, 0x7,0x4b,0x52, 0x7,0x4b,0x58, 0x7,0x51,0x2e, + 0x4,0x64,0x74, 0x7,0x51,0x36, 0x4,0x64,0x76, 0x5,0x6e,0x44, + 0x4,0x67,0x6d, 0x4,0x64,0x78, 0x7,0x51,0x34, 0x7,0x51,0x33, + 0x5,0x6e,0x45, 0x4,0x64,0x7a, 0x4,0x64,0x77, 0x4,0x64,0x79, + 0x7,0x51,0x2f, 0x7,0x51,0x31, 0x7,0x51,0x32, 0xf,0x66,0x75, + 0x7,0x51,0x35, 0x7,0x51,0x37, 0x7,0x51,0x30, 0x7,0x51,0x2d, + 0x4,0x67,0x6a, 0x4,0x67,0x69, 0x7,0x55,0x78, 0x5,0x71,0x5e, + 0x5,0x71,0x5f, 0x4,0x67,0x6b, 0x4,0x67,0x6c, 0x7,0x55,0x7a, + 0x5,0x71,0x60, 0x5,0x71,0x61, 0x7,0x55,0x7d, 0x7,0x55,0x79, + 0x7,0x55,0x7e, 0x7,0x55,0x7b, 0x5,0x74,0x5c, 0x5,0x74,0x5f, + 0x4,0x69,0x59, 0x7,0x59,0x78, 0x5,0x74,0x5d, 0x7,0x59,0x79, + 0x7,0x59,0x7a, 0x5,0x74,0x5a, 0x5,0x74,0x5e, 0x5,0x74,0x5b, + 0x7,0x59,0x77, 0x5,0x76,0x62, 0x7,0x5d,0x3b, 0x7,0x5d,0x3c, + 0xf,0x6b,0x33, 0x5,0x76,0x63, 0x5,0x78,0x44, 0x4,0x6c,0x32, + 0x4,0x6c,0x31, 0x7,0x5f,0x7d, 0x7,0x5f,0x7e, 0x7,0x60,0x21, + 0xf,0x6b,0x70, 0x4,0x6d,0x2c, 0x5,0x79,0x56, 0x4,0x6d,0x2b, + 0x5,0x79,0x55, 0x7,0x61,0x5b, 0x5,0x79,0x57, 0x5,0x7a,0x44, + 0x7,0x62,0x7b, 0x5,0x7a,0x43, 0x7,0x62,0x7c, 0xf,0x6c,0x59, + 0x7,0x63,0x23, 0x5,0x7a,0x42, 0x7,0x64,0x6c, 0x4,0x6e,0x3e, + 0x7,0x65,0x4b, 0x7,0x65,0x4a, 0x7,0x65,0x4c, 0x5,0x7b,0x6c, + 0x7,0x66,0x2d, 0x7,0x66,0x4e, 0x7,0x66,0x51, 0x4,0x6e,0x5c, + 0x4,0x36,0x26, 0x6,0x50,0x34, 0xf,0x46,0x2e, 0xf,0x46,0x2f, + 0xf,0x46,0x30, 0x6,0x59,0x7d, 0x4,0x48,0x36, 0x7,0x2c,0x44, + 0x7,0x35,0x3d, 0x5,0x5a,0x74, 0x7,0x44,0x66, 0xf,0x64,0x4f, + 0x5,0x71,0x62, 0xf,0x6b,0x71, 0x6,0x3c,0x74, 0x6,0x2e,0x49, + 0x6,0x3c,0x73, 0x4,0x36,0x27, 0x6,0x46,0x34, 0x4,0x36,0x29, + 0xf,0x39,0x2d, 0x6,0x50,0x35, 0x5,0x3d,0x42, 0x4,0x3b,0x75, + 0x6,0x50,0x37, 0x6,0x50,0x36, 0xf,0x40,0x28, 0xf,0x40,0x29, + 0x6,0x5a,0x21, 0x6,0x59,0x7e, 0xf,0x4d,0x3b, 0x4,0x4e,0x4d, + 0x7,0x2a,0x6e, 0x7,0x2a,0x6d, 0x7,0x35,0x3e, 0x7,0x51,0x38, + 0x7,0x51,0x39, 0x6,0x50,0x39, 0x6,0x50,0x3a, 0x6,0x50,0x38, + 0x4,0x41,0x59, 0x4,0x41,0x5b, 0x5,0x44,0x28, 0x5,0x44,0x27, + 0x6,0x5a,0x23, 0x6,0x5a,0x22, 0x6,0x64,0x22, 0x5,0x4b,0x25, + 0x4,0x48,0x39, 0x6,0x64,0x21, 0x5,0x4b,0x24, 0xf,0x4d,0x3c, + 0x6,0x64,0x23, 0x4,0x4e,0x4e, 0x5,0x52,0x46, 0x5,0x52,0x48, + 0x5,0x52,0x47, 0x7,0x2a,0x70, 0x7,0x2a,0x6f, 0xf,0x58,0x77, + 0x5,0x59,0x50, 0x5,0x59,0x4f, 0x5,0x59,0x54, 0x5,0x59,0x51, + 0x5,0x59,0x52, 0x5,0x59,0x53, 0xf,0x58,0x76, 0x7,0x35,0x3f, + 0x7,0x3d,0x4f, 0x5,0x5f,0x5f, 0x5,0x5f,0x60, 0x5,0x5f,0x62, + 0x5,0x5f,0x61, 0xf,0x5d,0x5b, 0x7,0x3d,0x51, 0x5,0x65,0x72, + 0x7,0x44,0x67, 0x5,0x65,0x70, 0x5,0x65,0x71, 0x4,0x5e,0x39, + 0x5,0x6a,0x4b, 0x5,0x6a,0x4a, 0x5,0x6e,0x47, 0x5,0x6e,0x46, + 0x7,0x4d,0x50, 0x7,0x51,0x3a, 0x5,0x6c,0x46, 0x5,0x71,0x64, + 0x7,0x56,0x22, 0x5,0x71,0x66, 0x5,0x71,0x65, 0xf,0x68,0x79, + 0x7,0x56,0x21, 0x7,0x56,0x24, 0x7,0x56,0x23, 0x7,0x59,0x7b, + 0x7,0x59,0x7c, 0x7,0x5d,0x3d, 0x5,0x76,0x64, 0xf,0x6b,0x34, + 0x7,0x60,0x22, 0x5,0x7a,0x45, 0x7,0x64,0x21, 0x7,0x64,0x6e, + 0x7,0x64,0x6d, 0xf,0x39,0x2e, 0x5,0x3d,0x43, 0x4,0x3b,0x78, + 0x6,0x50,0x3b, 0x5,0x44,0x2c, 0x5,0x44,0x2b, 0x6,0x5a,0x26, + 0x6,0x5a,0x29, 0x5,0x44,0x2a, 0x6,0x5a,0x27, 0x5,0x44,0x29, + 0x6,0x5a,0x25, 0x6,0x5a,0x2b, 0x6,0x5a,0x2a, 0x4,0x41,0x5c, + 0x4,0x41,0x5e, 0xf,0x46,0x31, 0x5,0x4b,0x27, 0x4,0x48,0x3c, + 0x5,0x4b,0x26, 0x6,0x64,0x27, 0x6,0x64,0x25, 0x5,0x4b,0x28, + 0x5,0x4b,0x29, 0x4,0x48,0x3e, 0x5,0x4b,0x2c, 0x5,0x4b,0x2a, + 0x5,0x4b,0x2d, 0x5,0x4b,0x2b, 0x6,0x64,0x29, 0x4,0x48,0x3f, + 0x6,0x64,0x28, 0x6,0x64,0x24, 0x6,0x64,0x26, 0x7,0x2a,0x73, + 0x5,0x52,0x49, 0x7,0x2a,0x77, 0x7,0x2a,0x76, 0x4,0x4e,0x51, + 0x7,0x2a,0x79, 0x5,0x52,0x4a, 0x4,0x4e,0x52, 0x7,0x2a,0x75, + 0x4,0x4e,0x53, 0x5,0x52,0x4d, 0x4,0x4e,0x50, 0x5,0x52,0x4c, + 0x5,0x52,0x4e, 0x7,0x2a,0x74, 0x5,0x52,0x4b, 0x7,0x2a,0x78, + 0x7,0x2a,0x72, 0x7,0x35,0x44, 0x5,0x59,0x55, 0x5,0x59,0x58, + 0x4,0x54,0x66, 0x4,0x54,0x5e, 0x4,0x54,0x65, 0x5,0x59,0x56, + 0x5,0x59,0x57, 0x7,0x35,0x43, 0x7,0x35,0x47, 0x7,0x35,0x40, + 0x7,0x35,0x41, 0x7,0x35,0x45, 0x7,0x35,0x46, 0x7,0x3d,0x58, + 0x7,0x3d,0x5a, 0x5,0x5f,0x63, 0x5,0x5f,0x69, 0x4,0x59,0x66, + 0x5,0x5f,0x65, 0x7,0x3d,0x53, 0x4,0x59,0x67, 0x7,0x35,0x42, + 0x5,0x5f,0x6d, 0x7,0x3d,0x57, 0x4,0x59,0x65, 0x7,0x3d,0x59, + 0x5,0x5f,0x67, 0x5,0x5f,0x6a, 0x7,0x3d,0x55, 0x5,0x5f,0x6b, + 0x7,0x3d,0x5b, 0x7,0x35,0x48, 0x5,0x5f,0x68, 0x7,0x3d,0x54, + 0x7,0x3d,0x5c, 0xf,0x5d,0x5c, 0x7,0x3d,0x52, 0x5,0x5f,0x6c, + 0x5,0x5f,0x66, 0x4,0x5e,0x44, 0x5,0x65,0x7c, 0x5,0x65,0x74, + 0x4,0x5e,0x3a, 0x5,0x65,0x76, 0x5,0x66,0x22, 0x7,0x44,0x6a, + 0x7,0x44,0x68, 0x4,0x5e,0x3f, 0x5,0x65,0x77, 0x4,0x5e,0x40, + 0x7,0x44,0x6d, 0x7,0x44,0x70, 0x5,0x66,0x21, 0x7,0x44,0x6f, + 0x4,0x5e,0x3d, 0x5,0x66,0x23, 0x7,0x44,0x71, 0x7,0x44,0x72, + 0x7,0x44,0x6e, 0xf,0x61,0x53, 0xf,0x61,0x54, 0x5,0x5f,0x64, + 0x7,0x44,0x6c, 0x7,0x44,0x6b, 0x5,0x65,0x78, 0x5,0x66,0x24, + 0x7,0x44,0x69, 0x5,0x65,0x75, 0x5,0x65,0x7a, 0x5,0x65,0x79, + 0x5,0x65,0x7d, 0x4,0x61,0x7a, 0x5,0x6a,0x51, 0x5,0x6a,0x54, + 0x5,0x6a,0x4f, 0x4,0x61,0x79, 0x5,0x6a,0x4d, 0x7,0x4b,0x5a, + 0x5,0x6a,0x55, 0x7,0x4b,0x63, 0x5,0x6a,0x4e, 0x4,0x61,0x78, + 0x7,0x4b,0x61, 0x4,0x61,0x76, 0x7,0x4b,0x5e, 0x4,0x61,0x75, + 0x7,0x4b,0x62, 0x5,0x6a,0x50, 0x7,0x4b,0x60, 0xf,0x64,0x50, + 0xf,0x64,0x52, 0xf,0x64,0x53, 0x7,0x4b,0x5b, 0x7,0x4b,0x5c, + 0x5,0x6a,0x53, 0x5,0x6a,0x52, 0x7,0x4b,0x59, 0x5,0x6a,0x4c, + 0x4,0x65,0x24, 0x5,0x6e,0x4e, 0x4,0x64,0x7d, 0x5,0x6e,0x4f, + 0x5,0x6e,0x4a, 0x7,0x51,0x3b, 0x5,0x6e,0x48, 0x7,0x51,0x3d, + 0x4,0x65,0x21, 0x5,0x6e,0x4c, 0x4,0x65,0x22, 0x4,0x65,0x25, + 0x5,0x6e,0x4d, 0x7,0x51,0x41, 0x7,0x51,0x3c, 0xf,0x66,0x78, + 0x7,0x51,0x3e, 0x7,0x51,0x43, 0x7,0x51,0x40, 0x5,0x6e,0x4b, + 0x7,0x51,0x3f, 0x5,0x6e,0x50, 0x4,0x65,0x26, 0x7,0x51,0x42, + 0x5,0x71,0x6d, 0x7,0x56,0x28, 0x4,0x67,0x6f, 0x7,0x56,0x2a, + 0x7,0x56,0x2b, 0x5,0x71,0x6a, 0x5,0x71,0x6b, 0x5,0x71,0x6c, + 0x5,0x71,0x67, 0x5,0x71,0x68, 0x7,0x56,0x29, 0xf,0x66,0x77, + 0x5,0x74,0x60, 0x7,0x5a,0x26, 0x7,0x59,0x7d, 0x4,0x69,0x5d, + 0x5,0x74,0x61, 0x7,0x5a,0x25, 0x7,0x5a,0x23, 0x7,0x59,0x7e, + 0x7,0x5a,0x24, 0x5,0x74,0x63, 0x5,0x74,0x64, 0x7,0x5a,0x21, + 0x7,0x5a,0x22, 0x5,0x74,0x65, 0x5,0x76,0x65, 0x5,0x76,0x68, + 0x5,0x76,0x66, 0x7,0x5d,0x3e, 0x5,0x76,0x69, 0x5,0x76,0x67, + 0x7,0x5d,0x41, 0x7,0x5d,0x3f, 0x7,0x5d,0x42, 0x7,0x5d,0x40, + 0x5,0x78,0x46, 0x5,0x79,0x58, 0x7,0x60,0x23, 0x5,0x78,0x45, + 0x5,0x78,0x47, 0x7,0x61,0x5e, 0x7,0x61,0x5c, 0x7,0x61,0x5d, + 0x5,0x7a,0x46, 0x7,0x62,0x7e, 0x7,0x63,0x22, 0x5,0x79,0x59, + 0x7,0x63,0x21, 0x7,0x62,0x7d, 0x5,0x7b,0x22, 0x7,0x64,0x70, + 0x7,0x64,0x6f, 0x5,0x7b,0x4c, 0x7,0x65,0x69, 0x5,0x7c,0x35, + 0x7,0x66,0x2e, 0x7,0x66,0x39, 0x7,0x66,0x38, 0x5,0x7c,0x4c, + 0x5,0x3d,0x44, 0x4,0x41,0x60, 0x4,0x41,0x62, 0x6,0x5a,0x2c, + 0x5,0x44,0x2d, 0x6,0x64,0x2b, 0x5,0x4b,0x2f, 0x5,0x4b,0x31, + 0x5,0x4b,0x2e, 0x5,0x4b,0x30, 0x6,0x64,0x2a, 0xf,0x4d,0x3d, + 0x5,0x4b,0x32, 0x4,0x4e,0x55, 0x5,0x52,0x50, 0x4,0x4e,0x54, + 0x4,0x4e,0x56, 0x7,0x2a,0x7b, 0x7,0x2a,0x7a, 0x7,0x2a,0x7c, + 0x7,0x2a,0x7d, 0x7,0x2a,0x7e, 0x5,0x52,0x4f, 0x5,0x52,0x51, + 0x5,0x59,0x59, 0x7,0x35,0x49, 0x7,0x35,0x4a, 0x5,0x59,0x5c, + 0x5,0x59,0x5d, 0x5,0x59,0x5b, 0x7,0x35,0x4b, 0x5,0x59,0x5a, + 0x4,0x59,0x69, 0x7,0x3d,0x5e, 0x5,0x5f,0x6e, 0x7,0x3d,0x5f, + 0x4,0x59,0x6c, 0x4,0x59,0x6a, 0x5,0x5f,0x6f, 0x5,0x5f,0x70, + 0xf,0x5d,0x5d, 0x7,0x3d,0x5d, 0x7,0x3d,0x60, 0x7,0x44,0x76, + 0x7,0x44,0x73, 0x4,0x5e,0x46, 0x7,0x44,0x74, 0x7,0x3d,0x61, + 0x5,0x66,0x25, 0x7,0x44,0x78, 0x7,0x44,0x75, 0x7,0x4b,0x64, + 0x7,0x4b,0x66, 0x7,0x4b,0x69, 0x7,0x4b,0x65, 0x7,0x4b,0x68, + 0x7,0x4b,0x67, 0x7,0x51,0x44, 0x5,0x6a,0x56, 0x5,0x6a,0x57, + 0x7,0x51,0x45, 0x7,0x51,0x46, 0x4,0x65,0x28, 0xf,0x66,0x79, + 0x5,0x6e,0x52, 0x5,0x6e,0x51, 0x5,0x71,0x6e, 0x5,0x71,0x70, + 0x5,0x71,0x72, 0x4,0x67,0x74, 0x7,0x56,0x2c, 0x5,0x71,0x6f, + 0x5,0x71,0x71, 0x7,0x5a,0x27, 0x4,0x69,0x5f, 0x5,0x74,0x66, + 0x7,0x5a,0x28, 0x7,0x5a,0x29, 0x5,0x74,0x67, 0x7,0x5d,0x43, + 0x7,0x5d,0x46, 0x7,0x5d,0x45, 0x7,0x5d,0x44, 0x4,0x6c,0x35, + 0x7,0x61,0x5f, 0x5,0x7a,0x47, 0x7,0x64,0x24, 0x7,0x64,0x22, + 0x7,0x64,0x23, 0x5,0x7b,0x4d, 0x5,0x7b,0x6d, 0x5,0x7c,0x22, + 0x5,0x44,0x2e, 0x6,0x5a,0x2d, 0x5,0x52,0x52, 0x7,0x35,0x4c, + 0x4,0x59,0x6d, 0x7,0x3d,0x62, 0x7,0x4b,0x6c, 0x7,0x51,0x48, + 0x4,0x65,0x2b, 0x5,0x71,0x73, 0x7,0x51,0x47, 0x7,0x56,0x2d, + 0x7,0x5a,0x2a, 0x7,0x5d,0x48, 0x7,0x5d,0x47, 0x7,0x61,0x60, + 0xf,0x40,0x2c, 0x5,0x44,0x30, 0x5,0x44,0x2f, 0x5,0x4b,0x33, + 0x4,0x48,0x45, 0x5,0x4b,0x34, 0x5,0x52,0x5a, 0x7,0x2b,0x21, + 0x5,0x52,0x54, 0x5,0x52,0x57, 0x7,0x2b,0x22, 0x5,0x52,0x55, + 0x5,0x52,0x56, 0x5,0x52,0x59, 0x5,0x52,0x53, 0x4,0x54,0x6b, + 0x5,0x52,0x58, 0xf,0x58,0x79, 0x5,0x59,0x5e, 0x7,0x35,0x4d, + 0x7,0x3d,0x63, 0x5,0x5f,0x71, 0x5,0x5f,0x72, 0x5,0x66,0x26, + 0x5,0x66,0x27, 0x5,0x66,0x28, 0x4,0x62,0x21, 0x5,0x6a,0x58, + 0x5,0x6a,0x59, 0x7,0x51,0x49, 0x7,0x51,0x4a, 0x5,0x6e,0x54, + 0x5,0x6e,0x53, 0x5,0x6e,0x55, 0x7,0x56,0x2e, 0x5,0x71,0x74, + 0x5,0x66,0x29, 0x5,0x74,0x68, 0x5,0x74,0x69, 0x4,0x69,0x61, + 0xf,0x6a,0x33, 0x7,0x5d,0x4a, 0x4,0x6c,0x36, 0x5,0x7b,0x23, + 0x5,0x7c,0x3f, 0x6,0x34,0x7b, 0x6,0x46,0x35, 0x5,0x36,0x46, + 0x5,0x3d,0x4a, 0x5,0x3d,0x48, 0x5,0x3d,0x49, 0x5,0x3d,0x46, + 0x4,0x3b,0x7d, 0x5,0x3d,0x45, 0x4,0x3b,0x7c, 0x6,0x50,0x3c, + 0x4,0x3b,0x7a, 0x4,0x41,0x6c, 0x5,0x44,0x3a, 0x4,0x41,0x6b, + 0x5,0x44,0x31, 0x5,0x44,0x39, 0x6,0x5a,0x2f, 0x4,0x41,0x69, + 0x5,0x4b,0x3b, 0x5,0x44,0x37, 0x4,0x41,0x66, 0x4,0x41,0x67, + 0x4,0x41,0x6a, 0x6,0x5a,0x32, 0x5,0x44,0x36, 0x5,0x44,0x32, + 0x6,0x5a,0x30, 0x6,0x5a,0x31, 0x6,0x5a,0x2e, 0xf,0x46,0x33, + 0x5,0x44,0x33, 0x5,0x44,0x38, 0x5,0x4b,0x3d, 0x6,0x64,0x31, + 0x6,0x64,0x32, 0x5,0x4b,0x37, 0x5,0x4b,0x44, 0x5,0x4b,0x38, + 0x4,0x48,0x49, 0x4,0x48,0x48, 0x5,0x4b,0x3a, 0x5,0x4b,0x36, + 0x4,0x48,0x4f, 0x5,0x4b,0x42, 0x5,0x4b,0x39, 0x7,0x2b,0x2b, + 0x5,0x4b,0x43, 0x6,0x64,0x35, 0x6,0x64,0x33, 0x6,0x64,0x2e, + 0x5,0x4b,0x3c, 0x5,0x4b,0x41, 0xf,0x4d,0x3e, 0x6,0x64,0x2d, + 0x5,0x4b,0x40, 0x6,0x64,0x2c, 0x6,0x64,0x36, 0x5,0x4b,0x35, + 0x6,0x64,0x2f, 0x6,0x64,0x34, 0x5,0x52,0x5d, 0x4,0x4e,0x5b, + 0x7,0x2b,0x25, 0x7,0x2b,0x30, 0x5,0x52,0x5c, 0x5,0x52,0x5b, + 0x4,0x4e,0x58, 0x7,0x2b,0x24, 0x7,0x2b,0x2a, 0x4,0x48,0x4a, + 0x7,0x2b,0x2e, 0x5,0x52,0x5e, 0x4,0x4e,0x5e, 0x7,0x2b,0x2d, + 0x7,0x2b,0x29, 0x7,0x35,0x4f, 0x7,0x2b,0x2c, 0xf,0x53,0x23, + 0xf,0x53,0x24, 0x7,0x2b,0x27, 0x7,0x2b,0x28, 0x7,0x2b,0x2f, + 0x7,0x2b,0x31, 0x7,0x2b,0x23, 0x7,0x2b,0x26, 0x5,0x52,0x5f, + 0x4,0x54,0x6c, 0x5,0x59,0x61, 0x4,0x54,0x6e, 0x5,0x59,0x69, + 0x7,0x35,0x58, 0x5,0x59,0x68, 0x5,0x59,0x66, 0x7,0x35,0x59, + 0x7,0x35,0x57, 0x5,0x59,0x65, 0x5,0x59,0x63, 0x7,0x35,0x5b, + 0x7,0x35,0x50, 0x5,0x59,0x6a, 0x5,0x59,0x62, 0x5,0x59,0x6b, + 0x5,0x59,0x64, 0x5,0x59,0x67, 0x4,0x54,0x71, 0x7,0x35,0x4e, + 0x5,0x59,0x60, 0x7,0x35,0x5a, 0x4,0x54,0x72, 0x7,0x35,0x56, + 0x7,0x35,0x5c, 0xf,0x4d,0x40, 0xf,0x58,0x7a, 0xf,0x58,0x7c, + 0xf,0x58,0x7d, 0xf,0x59,0x21, 0xf,0x59,0x22, 0xf,0x59,0x23, + 0x7,0x35,0x52, 0x7,0x35,0x53, 0x7,0x35,0x54, 0x7,0x35,0x55, + 0x5,0x59,0x6c, 0x5,0x59,0x5f, 0xf,0x58,0x7e, 0x5,0x59,0x6d, + 0x4,0x59,0x75, 0x4,0x59,0x71, 0x4,0x59,0x6e, 0x7,0x3d,0x65, + 0x5,0x5f,0x77, 0x4,0x59,0x79, 0x5,0x5f,0x78, 0x4,0x59,0x74, + 0x5,0x5f,0x76, 0x5,0x5f,0x73, 0x5,0x5f,0x75, 0x4,0x59,0x6f, + 0x5,0x5f,0x7b, 0x7,0x3d,0x6a, 0x4,0x59,0x72, 0x7,0x3d,0x6c, + 0x5,0x5f,0x74, 0x7,0x3d,0x67, 0x4,0x59,0x78, 0x7,0x3d,0x6b, + 0xf,0x5d,0x5e, 0xf,0x5d,0x5f, 0xf,0x5d,0x60, 0xf,0x5d,0x61, + 0xf,0x5d,0x62, 0xf,0x5d,0x63, 0x7,0x3d,0x64, 0x7,0x3d,0x66, + 0x5,0x5f,0x79, 0x5,0x5f,0x7a, 0x7,0x3d,0x68, 0x7,0x3d,0x6d, + 0x5,0x66,0x2a, 0x4,0x5e,0x4a, 0x5,0x66,0x30, 0x5,0x66,0x2e, + 0x4,0x62,0x24, 0x5,0x66,0x2d, 0x5,0x66,0x2b, 0x7,0x44,0x7b, + 0x5,0x66,0x2c, 0x4,0x5e,0x48, 0x5,0x66,0x31, 0x5,0x66,0x2f, + 0x7,0x44,0x7c, 0xf,0x61,0x55, 0xf,0x61,0x56, 0xf,0x61,0x57, + 0xf,0x61,0x58, 0x7,0x44,0x79, 0x7,0x44,0x7a, 0x7,0x4b,0x76, + 0x5,0x6a,0x5d, 0x7,0x4b,0x70, 0x7,0x4b,0x6d, 0x5,0x6a,0x5e, + 0x4,0x62,0x2e, 0x7,0x4b,0x72, 0x5,0x6a,0x5c, 0x5,0x6e,0x56, + 0x5,0x6a,0x5b, 0x5,0x6a,0x5a, 0x7,0x4b,0x74, 0x7,0x4b,0x6f, + 0x4,0x62,0x2a, 0x7,0x4b,0x6e, 0x7,0x4b,0x75, 0x7,0x4b,0x71, + 0xf,0x64,0x54, 0xf,0x64,0x55, 0x7,0x4b,0x77, 0x7,0x4b,0x73, + 0x4,0x65,0x2e, 0x4,0x65,0x2d, 0x5,0x6e,0x5b, 0x5,0x6e,0x59, + 0x7,0x51,0x4e, 0x5,0x6e,0x5a, 0x4,0x65,0x32, 0x7,0x51,0x4d, + 0x4,0x65,0x33, 0x5,0x6e,0x58, 0x7,0x51,0x4b, 0x7,0x51,0x4f, + 0xf,0x66,0x7a, 0x4,0x65,0x34, 0x7,0x51,0x50, 0x7,0x51,0x4c, + 0x5,0x6e,0x57, 0x7,0x50,0x4c, 0x5,0x71,0x75, 0x5,0x71,0x76, + 0x7,0x56,0x2f, 0x5,0x71,0x78, 0x7,0x56,0x38, 0x7,0x5a,0x31, + 0x4,0x67,0x7a, 0x4,0x67,0x78, 0x7,0x56,0x33, 0x7,0x56,0x31, + 0x7,0x56,0x36, 0x5,0x71,0x77, 0x5,0x71,0x79, 0x5,0x71,0x7a, + 0x7,0x56,0x30, 0x7,0x56,0x34, 0xf,0x68,0x7a, 0xf,0x68,0x7b, + 0xf,0x68,0x7c, 0x7,0x56,0x37, 0x7,0x56,0x35, 0x7,0x5a,0x30, + 0x5,0x74,0x6c, 0x5,0x74,0x6b, 0x7,0x5a,0x2d, 0x7,0x5a,0x2f, + 0x5,0x74,0x6a, 0xf,0x6a,0x34, 0x7,0x5a,0x2b, 0x7,0x5a,0x2e, + 0x7,0x5a,0x2c, 0x7,0x5d,0x52, 0x7,0x5d,0x51, 0x7,0x5d,0x4f, + 0x5,0x76,0x6c, 0x5,0x76,0x6d, 0x4,0x6b,0x2e, 0x5,0x76,0x6a, + 0x7,0x5d,0x4d, 0x4,0x6b,0x2f, 0x7,0x5d,0x4e, 0xf,0x6b,0x35, + 0x7,0x5d,0x50, 0x7,0x5d,0x4c, 0x7,0x5d,0x4b, 0x4,0x6c,0x38, + 0x7,0x60,0x24, 0x5,0x76,0x6b, 0x4,0x6c,0x37, 0xf,0x6b,0x72, + 0x7,0x60,0x25, 0x4,0x6d,0x2e, 0x5,0x79,0x5a, 0x5,0x7a,0x48, + 0x7,0x63,0x24, 0x5,0x7a,0x49, 0x7,0x63,0x25, 0x7,0x63,0x26, + 0x4,0x6e,0x23, 0x7,0x64,0x25, 0x7,0x65,0x4d, 0x6,0x46,0x36, + 0x6,0x50,0x3f, 0x4,0x3c,0x21, 0x6,0x50,0x3d, 0x5,0x3d,0x4b, + 0xf,0x40,0x2e, 0x6,0x50,0x3e, 0x5,0x44,0x3b, 0x5,0x44,0x40, + 0x4,0x41,0x6f, 0x5,0x44,0x3d, 0x5,0x44,0x3e, 0x6,0x5a,0x34, + 0x6,0x5a,0x36, 0x5,0x44,0x3c, 0x4,0x41,0x70, 0x6,0x5a,0x35, + 0x6,0x53,0x33, 0x5,0x44,0x3f, 0x6,0x5a,0x37, 0x4,0x48,0x58, + 0x5,0x4b,0x48, 0x4,0x48,0x55, 0x5,0x4b,0x47, 0x5,0x4b,0x46, + 0x5,0x4b,0x45, 0x4,0x48,0x53, 0x6,0x64,0x37, 0x4,0x48,0x52, + 0x6,0x64,0x3b, 0x6,0x64,0x39, 0x6,0x64,0x38, 0x4,0x4e,0x5f, + 0x5,0x52,0x62, 0x4,0x4e,0x62, 0x7,0x2b,0x34, 0x7,0x2b,0x33, + 0x7,0x2b,0x32, 0x5,0x52,0x61, 0x7,0x2b,0x35, 0xf,0x53,0x25, + 0xf,0x53,0x26, 0x5,0x59,0x6f, 0x5,0x59,0x77, 0x5,0x59,0x70, + 0x7,0x35,0x5d, 0x7,0x35,0x60, 0x5,0x59,0x6e, 0x5,0x59,0x73, + 0x5,0x59,0x76, 0x7,0x35,0x5f, 0x7,0x35,0x61, 0x5,0x59,0x74, + 0x5,0x59,0x75, 0x7,0x35,0x5e, 0xf,0x59,0x25, 0x5,0x59,0x72, + 0x5,0x59,0x71, 0x7,0x3d,0x71, 0x4,0x5a,0x25, 0x5,0x60,0x25, + 0x5,0x60,0x26, 0x4,0x59,0x7b, 0x5,0x5f,0x7c, 0x7,0x3d,0x70, + 0x4,0x5a,0x24, 0x5,0x66,0x32, 0x5,0x60,0x22, 0x4,0x5a,0x23, + 0x5,0x5f,0x7e, 0x5,0x60,0x21, 0x5,0x60,0x24, 0x5,0x5f,0x7d, + 0x5,0x60,0x23, 0x7,0x3d,0x6e, 0xf,0x5d,0x64, 0xf,0x5d,0x65, + 0x7,0x3d,0x72, 0x7,0x3d,0x6f, 0x4,0x5e,0x53, 0x7,0x45,0x22, + 0x7,0x45,0x24, 0x5,0x66,0x37, 0x7,0x45,0x26, 0x5,0x66,0x34, + 0x5,0x66,0x38, 0x4,0x5e,0x54, 0x5,0x66,0x3a, 0x4,0x62,0x31, + 0x5,0x66,0x35, 0x7,0x45,0x25, 0x5,0x66,0x36, 0x5,0x66,0x39, + 0x5,0x66,0x33, 0xf,0x61,0x59, 0x7,0x45,0x28, 0x7,0x45,0x23, + 0x7,0x45,0x21, 0x7,0x45,0x27, 0x7,0x44,0x7d, 0x5,0x6a,0x5f, + 0x4,0x62,0x33, 0x4,0x62,0x34, 0x4,0x62,0x35, 0x5,0x6a,0x60, + 0x7,0x4b,0x79, 0xf,0x64,0x56, 0xf,0x64,0x57, 0x7,0x4b,0x78, + 0x7,0x4b,0x7a, 0x7,0x4b,0x7b, 0x7,0x4b,0x7c, 0x5,0x6e,0x5e, + 0x5,0x6e,0x61, 0x5,0x6e,0x60, 0x4,0x65,0x35, 0x5,0x6e,0x5c, + 0x4,0x65,0x37, 0x5,0x6e,0x5f, 0xf,0x66,0x7b, 0x5,0x6e,0x62, + 0x5,0x6e,0x5d, 0x4,0x65,0x38, 0x7,0x56,0x40, 0x4,0x67,0x7d, + 0x4,0x68,0x21, 0x5,0x71,0x7b, 0x7,0x56,0x39, 0x5,0x71,0x7c, + 0x7,0x56,0x3c, 0x7,0x56,0x3a, 0xf,0x68,0x7d, 0x7,0x56,0x3f, + 0x7,0x56,0x41, 0x7,0x56,0x42, 0x7,0x56,0x3d, 0x7,0x56,0x3e, + 0x7,0x56,0x3b, 0x7,0x5a,0x32, 0xf,0x6a,0x35, 0x7,0x5a,0x33, + 0x7,0x5d,0x53, 0x5,0x78,0x49, 0x4,0x6c,0x3b, 0x7,0x60,0x26, + 0x7,0x60,0x27, 0x5,0x79,0x5b, 0x7,0x61,0x61, 0x5,0x79,0x5c, + 0x4,0x6d,0x2f, 0x4,0x6d,0x66, 0x5,0x7a,0x4a, 0x5,0x7b,0x24, + 0x7,0x64,0x26, 0xf,0x6d,0x24, 0x5,0x7c,0x47, 0x7,0x66,0x55, + 0x6,0x3c,0x75, 0x5,0x40,0x39, 0x7,0x2b,0x36, 0x7,0x4b,0x7d, + 0x5,0x6a,0x61, 0x7,0x56,0x43, 0x4,0x69,0x64, 0x5,0x74,0x6d, + 0x6,0x34,0x7c, 0x6,0x34,0x7d, 0x6,0x35,0x22, 0x6,0x34,0x7e, + 0x5,0x30,0x71, 0x6,0x3c,0x76, 0x6,0x3c,0x78, 0x5,0x3d,0x4c, + 0x5,0x36,0x4a, 0x5,0x36,0x47, 0x6,0x46,0x3a, 0x6,0x46,0x38, + 0x5,0x36,0x49, 0x6,0x46,0x39, 0x6,0x46,0x3b, 0x6,0x50,0x40, + 0x5,0x36,0x48, 0x6,0x50,0x41, 0x6,0x50,0x46, 0x4,0x3c,0x22, + 0x5,0x3d,0x4d, 0x6,0x50,0x44, 0x6,0x50,0x45, 0x4,0x3c,0x26, + 0x5,0x3d,0x4e, 0x6,0x5a,0x38, 0x5,0x3d,0x4f, 0x6,0x50,0x42, + 0xf,0x40,0x2f, 0x6,0x50,0x43, 0x4,0x3c,0x23, 0x6,0x5a,0x42, + 0x6,0x5a,0x39, 0x5,0x44,0x42, 0x5,0x44,0x44, 0x5,0x44,0x41, + 0x5,0x44,0x47, 0x4,0x41,0x76, 0x5,0x44,0x43, 0x6,0x64,0x43, + 0x5,0x44,0x45, 0x6,0x5a,0x3c, 0x6,0x5a,0x3b, 0x6,0x64,0x3d, + 0x4,0x41,0x73, 0x6,0x5a,0x3a, 0x6,0x64,0x3e, 0x6,0x5a,0x3e, + 0x5,0x44,0x48, 0x6,0x5a,0x41, 0x5,0x52,0x63, 0xf,0x46,0x37, + 0x6,0x5a,0x40, 0x6,0x5a,0x3f, 0x6,0x64,0x3c, 0x4,0x41,0x78, + 0x5,0x44,0x46, 0x6,0x64,0x3f, 0x7,0x2b,0x37, 0x6,0x64,0x44, + 0x5,0x4b,0x4d, 0x5,0x4b,0x49, 0x6,0x64,0x45, 0x5,0x4b,0x4a, + 0x4,0x48,0x5a, 0x6,0x64,0x42, 0x5,0x4b,0x4b, 0x7,0x2b,0x39, + 0x6,0x64,0x41, 0xf,0x46,0x36, 0xf,0x53,0x28, 0x7,0x2b,0x3a, + 0x4,0x4e,0x6b, 0x7,0x2b,0x40, 0x4,0x4e,0x6a, 0x5,0x52,0x69, + 0x5,0x52,0x64, 0x5,0x59,0x79, 0x4,0x4e,0x68, 0x5,0x52,0x66, + 0x5,0x52,0x6b, 0x5,0x52,0x68, 0x4,0x4e,0x6c, 0x5,0x52,0x6a, + 0x7,0x2b,0x3c, 0x5,0x52,0x65, 0x7,0x2b,0x3b, 0x7,0x3d,0x73, + 0x5,0x52,0x67, 0x7,0x2b,0x3e, 0x7,0x2b,0x3d, 0xf,0x53,0x27, + 0x5,0x59,0x78, 0x7,0x2b,0x3f, 0x5,0x5a,0x23, 0x4,0x5a,0x26, + 0x5,0x5a,0x24, 0x4,0x54,0x7b, 0x7,0x35,0x66, 0x7,0x35,0x6a, + 0x5,0x60,0x27, 0x5,0x59,0x7b, 0x7,0x35,0x69, 0x5,0x59,0x7e, + 0x7,0x35,0x67, 0x5,0x59,0x7c, 0x7,0x35,0x6f, 0x4,0x54,0x79, + 0x7,0x35,0x6b, 0x7,0x35,0x70, 0x5,0x5a,0x25, 0x7,0x35,0x68, + 0x7,0x35,0x63, 0x5,0x59,0x7a, 0x7,0x35,0x65, 0x7,0x35,0x64, + 0x7,0x35,0x6c, 0x5,0x60,0x29, 0x7,0x35,0x6e, 0x7,0x3d,0x75, + 0x7,0x35,0x62, 0x5,0x5a,0x22, 0x7,0x35,0x6d, 0x5,0x59,0x7d, + 0xf,0x59,0x26, 0xf,0x59,0x27, 0xf,0x59,0x28, 0xf,0x59,0x29, + 0x5,0x5a,0x21, 0x7,0x3d,0x74, 0x5,0x60,0x28, 0x5,0x60,0x34, + 0x7,0x3d,0x77, 0x5,0x60,0x2d, 0x5,0x60,0x2f, 0x5,0x60,0x33, + 0x5,0x60,0x2b, 0x7,0x3d,0x76, 0x5,0x60,0x32, 0x5,0x60,0x35, + 0x4,0x5a,0x2b, 0x5,0x60,0x36, 0x7,0x3d,0x78, 0x7,0x3d,0x7d, + 0x7,0x45,0x2a, 0x7,0x3d,0x7a, 0x5,0x60,0x2a, 0x7,0x45,0x2b, + 0x7,0x3e,0x21, 0x5,0x60,0x2e, 0x7,0x3d,0x79, 0x7,0x3d,0x7e, + 0xf,0x5d,0x66, 0xf,0x5d,0x67, 0x7,0x3d,0x7b, 0x5,0x60,0x30, + 0x7,0x3d,0x7c, 0x7,0x45,0x2f, 0x5,0x66,0x3f, 0x5,0x66,0x3b, + 0x4,0x5e,0x56, 0x4,0x5e,0x5c, 0x5,0x60,0x38, 0x4,0x5e,0x5d, + 0x5,0x66,0x3d, 0x5,0x60,0x37, 0x5,0x66,0x3c, 0x7,0x45,0x2e, + 0x7,0x45,0x2d, 0x7,0x4b,0x7e, 0x4,0x5e,0x5e, 0x5,0x66,0x3e, + 0x7,0x4c,0x22, 0x7,0x51,0x54, 0x7,0x45,0x2c, 0x7,0x45,0x29, + 0x7,0x45,0x31, 0xf,0x61,0x5a, 0xf,0x61,0x5b, 0x7,0x4c,0x25, + 0x7,0x4c,0x21, 0x4,0x5e,0x55, 0x7,0x45,0x32, 0x7,0x45,0x30, + 0x5,0x6a,0x64, 0x7,0x4c,0x23, 0x5,0x6a,0x62, 0x4,0x62,0x3b, + 0x4,0x65,0x3d, 0x7,0x51,0x53, 0x5,0x6a,0x69, 0x5,0x6a,0x66, + 0x5,0x6a,0x68, 0x5,0x6a,0x6a, 0x7,0x51,0x51, 0x4,0x62,0x37, + 0x5,0x6a,0x67, 0x5,0x60,0x39, 0x5,0x6a,0x63, 0x7,0x51,0x52, + 0x4,0x62,0x39, 0x7,0x51,0x58, 0x7,0x4c,0x24, 0x7,0x51,0x57, + 0x4,0x62,0x3a, 0xf,0x64,0x58, 0xf,0x64,0x59, 0x5,0x6a,0x65, + 0x7,0x51,0x56, 0x5,0x6a,0x6b, 0x4,0x65,0x3e, 0x7,0x51,0x55, + 0x7,0x51,0x59, 0x7,0x51,0x5f, 0x7,0x56,0x44, 0x5,0x71,0x7d, + 0x7,0x51,0x60, 0x5,0x6e,0x65, 0x4,0x65,0x3f, 0x5,0x71,0x7e, + 0x5,0x6e,0x64, 0x7,0x51,0x5e, 0x7,0x51,0x62, 0x5,0x6e,0x63, + 0x7,0x4c,0x27, 0x7,0x51,0x61, 0x7,0x51,0x5b, 0x7,0x51,0x5c, + 0x7,0x51,0x5d, 0x7,0x56,0x45, 0x7,0x51,0x63, 0x7,0x51,0x5a, + 0x5,0x72,0x28, 0x5,0x72,0x22, 0x7,0x56,0x46, 0x4,0x68,0x25, + 0x5,0x72,0x24, 0x5,0x72,0x21, 0x7,0x56,0x47, 0x5,0x72,0x2b, + 0x7,0x56,0x48, 0x5,0x72,0x2a, 0x5,0x72,0x23, 0x5,0x72,0x27, + 0x5,0x72,0x25, 0x7,0x56,0x49, 0x5,0x72,0x26, 0x5,0x72,0x29, + 0xf,0x68,0x7e, 0x4,0x69,0x66, 0x5,0x74,0x6e, 0x5,0x74,0x6f, + 0x7,0x5a,0x37, 0x7,0x5d,0x54, 0x7,0x5a,0x36, 0x5,0x74,0x70, + 0x7,0x5a,0x35, 0xf,0x6a,0x37, 0x7,0x5a,0x34, 0x5,0x76,0x6e, + 0x7,0x5d,0x56, 0x5,0x76,0x6f, 0x5,0x76,0x70, 0x5,0x78,0x4a, + 0x7,0x5d,0x55, 0x5,0x78,0x4b, 0x5,0x78,0x4c, 0x4,0x6c,0x3c, + 0x7,0x60,0x28, 0x7,0x60,0x2a, 0x7,0x60,0x29, 0x5,0x79,0x5d, + 0x7,0x64,0x27, 0x5,0x7b,0x25, 0x6,0x3c,0x79, 0x6,0x46,0x3c, + 0x6,0x64,0x46, 0x7,0x2b,0x41, 0x6,0x64,0x48, 0x6,0x64,0x47, + 0x5,0x52,0x6c, 0x4,0x55,0x24, 0x4,0x55,0x25, 0x7,0x3e,0x22, + 0x7,0x3e,0x23, 0x7,0x35,0x71, 0x7,0x35,0x73, 0x7,0x35,0x72, + 0x7,0x4c,0x29, 0x7,0x4c,0x28, 0x7,0x45,0x33, 0x7,0x4d,0x73, + 0x7,0x51,0x64, 0x7,0x60,0x2b, 0x4,0x6e,0x26, 0xf,0x32,0x71, + 0x4,0x41,0x7c, 0x6,0x5a,0x43, 0x5,0x47,0x54, 0x6,0x64,0x49, + 0x6,0x64,0x4a, 0xf,0x4d,0x41, 0xf,0x53,0x29, 0x6,0x64,0x4b, + 0x7,0x2b,0x42, 0xf,0x53,0x2a, 0xf,0x59,0x2a, 0x7,0x35,0x74, + 0xf,0x5d,0x68, 0x7,0x3e,0x24, 0x7,0x45,0x36, 0x5,0x66,0x41, + 0x5,0x66,0x40, 0x5,0x66,0x42, 0x7,0x45,0x35, 0x7,0x45,0x34, + 0x5,0x6a,0x6c, 0x4,0x62,0x3d, 0x4,0x62,0x3e, 0x7,0x4c,0x2a, + 0x7,0x51,0x65, 0xf,0x66,0x7c, 0x5,0x72,0x2c, 0xf,0x69,0x21, + 0x7,0x56,0x4a, 0x7,0x5d,0x57, 0x5,0x7a,0x4b, 0x5,0x36,0x4b, + 0x5,0x36,0x4c, 0x5,0x3d,0x50, 0x6,0x50,0x48, 0xf,0x40,0x31, + 0x6,0x50,0x47, 0x5,0x44,0x49, 0x6,0x5a,0x45, 0x6,0x5a,0x44, + 0x6,0x5a,0x47, 0x6,0x5a,0x46, 0x5,0x4b,0x51, 0x6,0x64,0x4d, + 0x6,0x64,0x4e, 0x5,0x4b,0x50, 0x4,0x48,0x61, 0x6,0x64,0x4c, + 0x6,0x64,0x52, 0x5,0x4b,0x4f, 0x7,0x2b,0x43, 0xf,0x4d,0x42, + 0xf,0x4d,0x43, 0xf,0x4d,0x44, 0xf,0x4d,0x45, 0x7,0x2b,0x46, + 0x6,0x64,0x4f, 0x6,0x64,0x51, 0x5,0x4b,0x52, 0x7,0x2b,0x4a, + 0x5,0x52,0x72, 0x7,0x2b,0x4e, 0x7,0x2b,0x47, 0x5,0x5a,0x32, + 0x5,0x52,0x74, 0x5,0x52,0x77, 0x5,0x52,0x6d, 0x5,0x52,0x70, + 0x5,0x52,0x6e, 0x5,0x52,0x75, 0x7,0x2b,0x44, 0x5,0x52,0x76, + 0x7,0x2b,0x48, 0x5,0x52,0x73, 0x7,0x2b,0x4b, 0x7,0x2b,0x49, + 0x5,0x52,0x6f, 0x7,0x2b,0x45, 0x7,0x2b,0x4c, 0x5,0x52,0x71, + 0xf,0x53,0x2b, 0xf,0x53,0x2c, 0xf,0x53,0x2d, 0x7,0x2b,0x4d, + 0x7,0x35,0x7a, 0x4,0x55,0x2c, 0x7,0x35,0x79, 0x5,0x5a,0x2f, + 0x4,0x55,0x2a, 0x4,0x55,0x27, 0x4,0x55,0x2b, 0x4,0x55,0x28, + 0x7,0x35,0x75, 0x5,0x5a,0x29, 0x4,0x55,0x29, 0x5,0x5a,0x30, + 0x5,0x5a,0x2d, 0x7,0x36,0x24, 0x5,0x5a,0x33, 0x5,0x5a,0x27, + 0x5,0x5a,0x31, 0x5,0x5a,0x34, 0x5,0x5a,0x2b, 0x7,0x35,0x7c, + 0x7,0x35,0x7b, 0x7,0x36,0x26, 0x7,0x36,0x21, 0x7,0x35,0x78, + 0x7,0x36,0x23, 0x5,0x5a,0x2a, 0x7,0x36,0x22, 0xf,0x59,0x2c, + 0x5,0x5a,0x28, 0x7,0x35,0x7d, 0x7,0x35,0x7e, 0x7,0x36,0x27, + 0x7,0x36,0x25, 0xf,0x59,0x2b, 0x7,0x35,0x76, 0x7,0x35,0x77, + 0x5,0x60,0x3a, 0x7,0x3e,0x2c, 0x5,0x60,0x3b, 0x7,0x3e,0x26, + 0x4,0x5a,0x2f, 0x7,0x3e,0x27, 0x7,0x3e,0x25, 0x5,0x60,0x3c, + 0x4,0x5a,0x2c, 0x7,0x3e,0x2a, 0x7,0x3e,0x2b, 0x5,0x4b,0x53, + 0x7,0x3e,0x28, 0x5,0x60,0x3e, 0x5,0x60,0x3d, 0xf,0x5d,0x69, + 0xf,0x5d,0x6a, 0x7,0x45,0x3c, 0x5,0x66,0x4c, 0x5,0x66,0x4b, + 0x5,0x66,0x47, 0x4,0x5e,0x64, 0x5,0x66,0x49, 0x5,0x66,0x48, + 0x4,0x5e,0x61, 0x5,0x66,0x45, 0x5,0x66,0x4e, 0x4,0x5e,0x6d, + 0x4,0x5e,0x69, 0x4,0x5e,0x6a, 0x4,0x5e,0x66, 0x5,0x66,0x4f, + 0x5,0x66,0x43, 0x4,0x5e,0x6c, 0x7,0x45,0x3b, 0x7,0x45,0x3a, + 0x7,0x45,0x37, 0x5,0x66,0x4a, 0xf,0x61,0x5d, 0xf,0x61,0x5e, + 0xf,0x61,0x60, 0x4,0x5e,0x6b, 0xf,0x61,0x5c, 0x7,0x45,0x38, + 0x5,0x66,0x44, 0x7,0x45,0x39, 0x5,0x66,0x4d, 0x5,0x6a,0x6d, + 0x5,0x6a,0x73, 0x5,0x6a,0x6f, 0x4,0x62,0x43, 0x7,0x4c,0x31, + 0x5,0x66,0x50, 0x7,0x4c,0x2c, 0x5,0x66,0x46, 0x5,0x6a,0x71, + 0x5,0x6a,0x70, 0x5,0x6a,0x74, 0x7,0x4c,0x2b, 0x5,0x6a,0x72, + 0x5,0x6a,0x76, 0x4,0x62,0x42, 0x5,0x6a,0x77, 0x7,0x4c,0x32, + 0x7,0x4c,0x34, 0x5,0x6a,0x75, 0x7,0x4c,0x33, 0x7,0x4c,0x2d, + 0x7,0x4c,0x2e, 0x7,0x4c,0x2f, 0xf,0x64,0x5b, 0xf,0x64,0x5c, + 0xf,0x64,0x5d, 0x7,0x4c,0x30, 0x3,0x57,0x36, 0x7,0x4c,0x35, + 0x4,0x65,0x45, 0x7,0x51,0x6a, 0x7,0x51,0x69, 0x5,0x6e,0x6e, + 0x5,0x6e,0x69, 0x5,0x6e,0x6b, 0x5,0x6e,0x68, 0x4,0x65,0x42, + 0x5,0x6e,0x70, 0xf,0x66,0x7d, 0x4,0x65,0x43, 0x4,0x65,0x44, + 0x4,0x65,0x48, 0x5,0x6e,0x71, 0x5,0x6e,0x72, 0x5,0x6e,0x67, + 0x7,0x51,0x68, 0x4,0x68,0x26, 0x5,0x6e,0x6a, 0x5,0x6e,0x6f, + 0x5,0x6e,0x6c, 0x7,0x51,0x6b, 0x7,0x51,0x6f, 0x7,0x51,0x70, + 0x7,0x51,0x71, 0x7,0x51,0x6d, 0x7,0x51,0x6c, 0xf,0x66,0x7e, + 0xf,0x67,0x21, 0x7,0x51,0x67, 0x7,0x51,0x6e, 0x7,0x52,0x27, + 0x7,0x51,0x66, 0x5,0x72,0x2f, 0x5,0x72,0x2e, 0x5,0x72,0x31, + 0x4,0x68,0x27, 0x5,0x72,0x32, 0x5,0x72,0x30, 0x4,0x68,0x2c, + 0x7,0x56,0x4d, 0x7,0x56,0x4c, 0x7,0x56,0x4e, 0x7,0x56,0x4b, + 0xf,0x69,0x22, 0x7,0x56,0x4f, 0x7,0x56,0x50, 0x5,0x74,0x78, + 0x7,0x5a,0x3d, 0x5,0x72,0x34, 0x7,0x5a,0x41, 0x7,0x5a,0x38, + 0x5,0x74,0x71, 0x7,0x5a,0x3b, 0x5,0x72,0x33, 0x5,0x74,0x74, + 0x5,0x74,0x77, 0x5,0x74,0x73, 0x7,0x5a,0x40, 0x4,0x69,0x6c, + 0x5,0x74,0x75, 0x7,0x5a,0x39, 0x7,0x5a,0x3a, 0x7,0x5a,0x3c, + 0xf,0x6a,0x38, 0xf,0x6a,0x39, 0xf,0x6a,0x3a, 0x5,0x74,0x72, + 0x5,0x74,0x79, 0x7,0x5a,0x3f, 0x7,0x5d,0x5f, 0x7,0x5d,0x5d, + 0x5,0x76,0x71, 0x5,0x78,0x4e, 0x7,0x5d,0x5c, 0x7,0x5d,0x59, + 0x5,0x76,0x72, 0x7,0x5d,0x5a, 0x7,0x5d,0x5e, 0x7,0x5d,0x5b, + 0x7,0x5d,0x60, 0xf,0x6b,0x38, 0xf,0x6b,0x39, 0x7,0x5d,0x58, + 0x5,0x78,0x4f, 0x7,0x60,0x31, 0x7,0x60,0x34, 0x5,0x78,0x4d, + 0x7,0x60,0x33, 0x7,0x60,0x36, 0x7,0x60,0x35, 0x7,0x60,0x2f, + 0x7,0x60,0x30, 0x7,0x60,0x2c, 0x7,0x60,0x32, 0x5,0x79,0x62, + 0x7,0x61,0x63, 0x5,0x79,0x63, 0x5,0x79,0x5f, 0x4,0x6d,0x31, + 0x5,0x79,0x60, 0x7,0x61,0x62, 0x5,0x79,0x5e, 0x5,0x79,0x61, + 0x4,0x6d,0x32, 0x7,0x61,0x64, 0x5,0x7a,0x4c, 0x5,0x7a,0x4d, + 0x4,0x6e,0x27, 0x7,0x64,0x29, 0x7,0x64,0x28, 0x4,0x6e,0x40, + 0x7,0x64,0x72, 0x7,0x64,0x73, 0x7,0x64,0x71, 0x7,0x65,0x4e, + 0x5,0x7c,0x23, 0x7,0x65,0x6a, 0x7,0x65,0x7a, 0x7,0x65,0x7b, + 0x7,0x66,0x44, 0x5,0x3d,0x51, 0x4,0x3c,0x27, 0x6,0x5a,0x49, + 0x6,0x5a,0x4a, 0x6,0x5a,0x48, 0x6,0x5a,0x4b, 0x4,0x48,0x63, + 0x4,0x48,0x65, 0x5,0x4b,0x55, 0x6,0x64,0x58, 0x5,0x4b,0x54, + 0x4,0x48,0x64, 0x6,0x64,0x56, 0x6,0x64,0x53, 0x6,0x64,0x54, + 0x6,0x64,0x55, 0x6,0x64,0x57, 0x4,0x4e,0x72, 0x4,0x4e,0x71, + 0x5,0x52,0x7a, 0x5,0x52,0x79, 0x7,0x2b,0x52, 0x7,0x36,0x2c, + 0x5,0x52,0x78, 0x5,0x52,0x7b, 0x4,0x4e,0x77, 0x7,0x2b,0x50, + 0x7,0x2b,0x54, 0x7,0x2b,0x51, 0x4,0x4e,0x78, 0x7,0x2b,0x53, + 0x5,0x5a,0x36, 0x5,0x5a,0x35, 0x4,0x55,0x33, 0x7,0x36,0x2b, + 0x7,0x2b,0x4f, 0x7,0x36,0x2a, 0x7,0x36,0x29, 0x7,0x3e,0x2e, + 0x4,0x5a,0x34, 0x7,0x3e,0x32, 0x4,0x5a,0x32, 0x7,0x3e,0x33, + 0x5,0x60,0x3f, 0x7,0x3e,0x31, 0x7,0x3e,0x2d, 0x7,0x3e,0x2f, + 0x7,0x3e,0x30, 0x5,0x66,0x59, 0x7,0x45,0x3e, 0x4,0x5e,0x6f, + 0x7,0x45,0x3d, 0x5,0x66,0x57, 0x7,0x45,0x3f, 0x5,0x66,0x52, + 0x5,0x6a,0x78, 0x5,0x66,0x55, 0x5,0x66,0x53, 0x5,0x66,0x56, + 0x5,0x66,0x58, 0x7,0x3e,0x34, 0x5,0x66,0x54, 0x7,0x4c,0x3b, + 0x5,0x6a,0x7a, 0x5,0x6a,0x79, 0x7,0x4c,0x3a, 0x7,0x4c,0x37, + 0x5,0x6a,0x7c, 0x5,0x6a,0x7d, 0x5,0x6a,0x7b, 0x7,0x4c,0x3d, + 0x7,0x4c,0x3e, 0x7,0x4c,0x39, 0x7,0x4c,0x38, 0x7,0x4c,0x3c, + 0x7,0x4c,0x36, 0x4,0x65,0x4a, 0x5,0x6e,0x75, 0x5,0x6e,0x74, + 0x5,0x6e,0x73, 0x7,0x51,0x73, 0x7,0x51,0x74, 0x7,0x51,0x75, + 0x4,0x68,0x2f, 0x5,0x72,0x36, 0x7,0x56,0x57, 0x4,0x68,0x2e, + 0x5,0x72,0x35, 0x5,0x72,0x37, 0x7,0x56,0x53, 0x7,0x56,0x54, + 0x5,0x72,0x38, 0x7,0x56,0x55, 0xf,0x69,0x23, 0x7,0x56,0x56, + 0x7,0x56,0x52, 0x4,0x69,0x6d, 0x7,0x5a,0x42, 0x4,0x69,0x70, + 0x7,0x5a,0x43, 0x4,0x69,0x6f, 0x7,0x5a,0x44, 0x7,0x5d,0x65, + 0x7,0x5d,0x66, 0x5,0x76,0x73, 0x4,0x6b,0x36, 0x5,0x76,0x75, + 0x4,0x6b,0x37, 0x7,0x5d,0x62, 0x5,0x76,0x74, 0x7,0x5d,0x67, + 0x7,0x5d,0x61, 0x7,0x5d,0x63, 0x7,0x5d,0x64, 0x4,0x6c,0x3f, + 0x5,0x78,0x50, 0x4,0x6d,0x34, 0x7,0x61,0x65, 0xf,0x6b,0x3a, + 0x7,0x63,0x27, 0x5,0x7a,0x4e, 0x7,0x63,0x28, 0x7,0x64,0x2a, + 0x7,0x64,0x74, 0x5,0x7b,0x6e, 0x4,0x42,0x23, 0x4,0x48,0x66, + 0x5,0x46,0x64, 0x5,0x4b,0x56, 0x6,0x64,0x5a, 0xf,0x4d,0x46, + 0xf,0x4d,0x47, 0xf,0x4d,0x48, 0x6,0x64,0x59, 0x7,0x2b,0x56, + 0xf,0x53,0x2e, 0xf,0x53,0x2f, 0x7,0x36,0x2e, 0x7,0x36,0x2d, + 0xf,0x59,0x2d, 0xf,0x59,0x2e, 0x4,0x5a,0x36, 0x5,0x60,0x40, + 0xf,0x5d,0x6b, 0xf,0x5d,0x6c, 0x7,0x45,0x40, 0xf,0x61,0x61, + 0xf,0x61,0x62, 0x7,0x4c,0x3f, 0xf,0x64,0x5f, 0x5,0x6e,0x76, + 0xf,0x67,0x22, 0xf,0x67,0x23, 0xf,0x67,0x24, 0xf,0x67,0x25, + 0x4,0x68,0x31, 0x7,0x56,0x58, 0x7,0x5a,0x45, 0x7,0x5d,0x68, + 0x7,0x5d,0x69, 0x7,0x5d,0x6a, 0x7,0x60,0x37, 0xf,0x6b,0x73, + 0x7,0x61,0x66, 0x7,0x61,0x67, 0x7,0x63,0x29, 0x7,0x64,0x2b, + 0x4,0x6e,0x28, 0x7,0x65,0x7c, 0x6,0x50,0x49, 0x6,0x50,0x4a, + 0x6,0x5a,0x4d, 0x6,0x5a,0x4c, 0xf,0x46,0x3a, 0xf,0x40,0x69, + 0x4,0x48,0x68, 0x5,0x4b,0x58, 0x6,0x64,0x60, 0x6,0x64,0x5f, + 0x6,0x64,0x5d, 0x6,0x64,0x61, 0x6,0x64,0x5b, 0x6,0x64,0x5c, + 0x5,0x4b,0x57, 0x5,0x4b,0x5a, 0x5,0x52,0x7e, 0x7,0x2b,0x57, + 0x7,0x2b,0x5a, 0x4,0x4e,0x7e, 0x7,0x2b,0x58, 0x5,0x53,0x24, + 0x4,0x4f,0x22, 0x7,0x2b,0x5b, 0x5,0x53,0x23, 0x4,0x4e,0x7c, + 0x4,0x4e,0x7d, 0x5,0x52,0x7c, 0x4,0x4e,0x7a, 0x5,0x52,0x7d, + 0x5,0x53,0x22, 0x5,0x53,0x21, 0x7,0x2b,0x5c, 0x7,0x2b,0x59, + 0xf,0x53,0x30, 0xf,0x53,0x31, 0xf,0x53,0x32, 0xf,0x53,0x33, + 0x7,0x36,0x2f, 0x4,0x55,0x37, 0x7,0x36,0x31, 0x5,0x5a,0x3a, + 0x7,0x36,0x30, 0x4,0x55,0x39, 0x4,0x55,0x34, 0x4,0x55,0x3b, + 0x5,0x5a,0x37, 0x5,0x5a,0x39, 0x4,0x55,0x3a, 0x4,0x55,0x38, + 0x7,0x36,0x33, 0x5,0x5a,0x38, 0xf,0x59,0x2f, 0xf,0x59,0x30, + 0xf,0x59,0x31, 0xf,0x59,0x33, 0x7,0x36,0x32, 0x4,0x5a,0x3a, + 0x4,0x5a,0x3c, 0x7,0x3e,0x3a, 0x5,0x60,0x41, 0x5,0x60,0x44, + 0x5,0x60,0x42, 0x7,0x3e,0x38, 0x5,0x60,0x45, 0x5,0x60,0x46, + 0x5,0x60,0x43, 0x7,0x3e,0x35, 0x4,0x5a,0x39, 0x7,0x3e,0x36, + 0xf,0x5d,0x6d, 0xf,0x5d,0x6e, 0xf,0x5d,0x6f, 0x7,0x3e,0x37, + 0x7,0x3e,0x39, 0x7,0x3e,0x3b, 0x7,0x45,0x42, 0x5,0x66,0x5e, + 0x4,0x5e,0x71, 0x5,0x66,0x5c, 0x5,0x66,0x60, 0x5,0x66,0x5f, + 0x7,0x45,0x44, 0x5,0x66,0x61, 0x7,0x4c,0x40, 0x7,0x45,0x43, + 0x4,0x5e,0x72, 0x5,0x66,0x5a, 0x4,0x5e,0x78, 0x5,0x66,0x5b, + 0xf,0x61,0x63, 0xf,0x61,0x65, 0x5,0x66,0x5d, 0x7,0x45,0x41, + 0xf,0x61,0x64, 0x4,0x62,0x4d, 0x7,0x4c,0x43, 0x7,0x4c,0x47, + 0x5,0x6a,0x7e, 0x5,0x6b,0x21, 0x5,0x6b,0x23, 0x4,0x62,0x50, + 0x7,0x4c,0x48, 0x7,0x4c,0x46, 0x7,0x4c,0x41, 0x5,0x6b,0x24, + 0x5,0x6b,0x22, 0x7,0x4c,0x45, 0x7,0x4c,0x42, 0x4,0x62,0x4b, + 0x7,0x4c,0x44, 0xf,0x64,0x60, 0xf,0x64,0x61, 0xf,0x64,0x63, + 0x5,0x6e,0x7c, 0x7,0x51,0x76, 0x5,0x6e,0x77, 0x5,0x6e,0x7b, + 0x5,0x6e,0x7a, 0x5,0x6e,0x79, 0x4,0x65,0x50, 0x4,0x65,0x4c, + 0x5,0x6e,0x7e, 0x5,0x6e,0x78, 0x4,0x65,0x4b, 0x7,0x51,0x77, + 0x7,0x51,0x78, 0x7,0x51,0x7b, 0x7,0x51,0x7c, 0xf,0x67,0x26, + 0xf,0x67,0x27, 0xf,0x67,0x28, 0x5,0x6e,0x7d, 0x5,0x72,0x3b, + 0x5,0x72,0x3e, 0x5,0x72,0x3a, 0x7,0x56,0x59, 0x4,0x68,0x32, + 0x4,0x68,0x34, 0x5,0x72,0x39, 0x4,0x68,0x33, 0x5,0x72,0x3d, + 0x7,0x56,0x5a, 0x5,0x72,0x3c, 0x7,0x56,0x5e, 0xf,0x69,0x24, + 0x7,0x56,0x5b, 0x7,0x56,0x5c, 0x5,0x75,0x21, 0x5,0x74,0x7c, + 0x7,0x5a,0x46, 0x5,0x75,0x22, 0x5,0x74,0x7e, 0x5,0x74,0x7b, + 0x5,0x75,0x25, 0x5,0x75,0x24, 0x5,0x75,0x23, 0x5,0x74,0x7d, + 0x5,0x75,0x26, 0x7,0x56,0x5d, 0x4,0x69,0x73, 0x7,0x5a,0x47, + 0x7,0x5a,0x48, 0xf,0x6a,0x3b, 0xf,0x6a,0x3c, 0x5,0x76,0x77, + 0x4,0x6b,0x38, 0x4,0x6b,0x39, 0x5,0x76,0x76, 0x7,0x5d,0x6c, + 0x7,0x5d,0x6d, 0x7,0x5d,0x6b, 0xf,0x6b,0x3b, 0x4,0x6c,0x40, + 0x7,0x60,0x38, 0x5,0x78,0x51, 0x4,0x6c,0x44, 0x4,0x6c,0x42, + 0x5,0x79,0x65, 0x7,0x61,0x68, 0x5,0x79,0x64, 0x4,0x6d,0x36, + 0xf,0x6c,0x42, 0xf,0x6c,0x43, 0x7,0x61,0x69, 0x5,0x7a,0x4f, + 0x7,0x63,0x2a, 0x7,0x63,0x2b, 0x7,0x64,0x2c, 0x4,0x6e,0x29, + 0x5,0x7b,0x26, 0xf,0x6c,0x72, 0x7,0x64,0x77, 0x7,0x64,0x76, + 0x5,0x7b,0x4e, 0x4,0x6e,0x54, 0x6,0x23,0x3d, 0x6,0x23,0x3c, + 0x5,0x44,0x4b, 0x5,0x4b,0x5b, 0x5,0x4b,0x5c, 0x6,0x64,0x62, + 0x7,0x2b,0x5d, 0x7,0x36,0x34, 0x7,0x3e,0x3c, 0x7,0x45,0x45, + 0x4,0x5e,0x79, 0x7,0x51,0x7e, 0x7,0x56,0x5f, 0x5,0x72,0x40, + 0x7,0x5a,0x49, 0x7,0x60,0x3a, 0x7,0x60,0x39, 0x5,0x78,0x53, + 0x5,0x7b,0x4f, 0x7,0x2b,0x5e, 0x4,0x4f,0x23, 0x4,0x55,0x3c, + 0x7,0x45,0x46, 0x7,0x52,0x21, 0x7,0x56,0x61, 0x7,0x56,0x60, + 0x7,0x5a,0x4a, 0x7,0x5d,0x6e, 0xf,0x6c,0x73, 0x5,0x7b,0x50, + 0x4,0x42,0x24, 0x6,0x5a,0x4e, 0x6,0x64,0x64, 0x6,0x64,0x63, + 0x7,0x2b,0x5f, 0x7,0x36,0x38, 0x4,0x55,0x3e, 0x5,0x5a,0x3b, + 0x7,0x36,0x36, 0x7,0x36,0x35, 0x4,0x55,0x3d, 0x7,0x36,0x37, + 0x5,0x60,0x47, 0x7,0x3e,0x3d, 0x4,0x5e,0x7a, 0x7,0x45,0x48, + 0x7,0x45,0x49, 0x7,0x45,0x47, 0x7,0x4c,0x49, 0x5,0x6b,0x25, + 0x7,0x4c,0x4a, 0x4,0x65,0x51, 0x7,0x52,0x24, 0x7,0x52,0x23, + 0x7,0x52,0x22, 0x7,0x52,0x25, 0x7,0x56,0x62, 0x4,0x68,0x35, + 0x7,0x56,0x64, 0x5,0x72,0x42, 0x7,0x56,0x63, 0x7,0x56,0x65, + 0x7,0x56,0x66, 0x5,0x75,0x27, 0x7,0x5a,0x4c, 0x7,0x5d,0x71, + 0x7,0x5d,0x72, 0x5,0x76,0x78, 0x4,0x69,0x75, 0x4,0x6b,0x3a, + 0x7,0x5d,0x70, 0x5,0x76,0x79, 0x7,0x5d,0x6f, 0x7,0x5d,0x73, + 0x4,0x6c,0x46, 0x4,0x6c,0x45, 0x7,0x5d,0x74, 0x7,0x60,0x3b, + 0x7,0x61,0x6b, 0x7,0x61,0x6c, 0x5,0x7a,0x50, 0x7,0x63,0x2c, + 0x7,0x63,0x2d, 0x7,0x63,0x2e, 0x4,0x6e,0x2a, 0x7,0x64,0x2d, + 0x7,0x64,0x79, 0x7,0x64,0x78, 0x7,0x64,0x7a, 0x7,0x65,0x4f, + 0x5,0x7c,0x24, 0x4,0x6e,0x51, 0x5,0x7c,0x2d, 0x7,0x65,0x7d, + 0x7,0x66,0x4a, 0x7,0x66,0x4b, 0x6,0x50,0x4b, 0x5,0x3d,0x53, + 0x6,0x5a,0x52, 0x5,0x44,0x4e, 0x6,0x5a,0x51, 0x4,0x42,0x26, + 0x5,0x44,0x4c, 0x6,0x5a,0x50, 0x5,0x44,0x4d, 0x4,0x42,0x25, + 0x6,0x5a,0x4f, 0xf,0x39,0x30, 0xf,0x39,0x2f, 0x6,0x5a,0x53, + 0x5,0x4b,0x5f, 0x5,0x4b,0x60, 0x5,0x4b,0x61, 0x5,0x4b,0x5e, + 0x5,0x4b,0x5d, 0x5,0x4b,0x62, 0x6,0x64,0x68, 0x6,0x64,0x65, + 0x6,0x64,0x69, 0xf,0x4d,0x49, 0xf,0x4d,0x4a, 0xf,0x4d,0x4b, + 0x6,0x64,0x6b, 0x6,0x64,0x66, 0x6,0x64,0x6e, 0x6,0x64,0x6c, + 0x6,0x64,0x6d, 0x6,0x64,0x6a, 0x6,0x64,0x67, 0x4,0x4f,0x27, + 0x5,0x53,0x29, 0x7,0x2b,0x61, 0x7,0x2b,0x60, 0x5,0x53,0x28, + 0x5,0x53,0x2b, 0x5,0x5a,0x41, 0x5,0x53,0x2a, 0x4,0x4f,0x26, + 0x7,0x2b,0x63, 0x5,0x53,0x25, 0xf,0x53,0x34, 0xf,0x53,0x35, + 0xf,0x53,0x36, 0x5,0x53,0x27, 0x7,0x2b,0x62, 0x5,0x53,0x26, + 0x5,0x5a,0x3c, 0x7,0x36,0x3a, 0x5,0x5a,0x45, 0x5,0x5a,0x43, + 0x7,0x36,0x39, 0x4,0x55,0x40, 0x5,0x5a,0x44, 0x7,0x36,0x3b, + 0xf,0x59,0x34, 0x5,0x5a,0x3e, 0x5,0x5a,0x3d, 0x5,0x5a,0x3f, + 0x5,0x5a,0x42, 0x7,0x36,0x3c, 0x5,0x5a,0x40, 0x4,0x5a,0x3d, + 0x5,0x60,0x49, 0x5,0x60,0x4c, 0x5,0x60,0x50, 0x4,0x5a,0x3e, + 0x7,0x3e,0x3e, 0x5,0x60,0x48, 0x5,0x60,0x4a, 0x5,0x60,0x4f, + 0x5,0x60,0x4d, 0x7,0x3e,0x40, 0x7,0x3e,0x41, 0x7,0x3e,0x43, + 0xf,0x5d,0x70, 0xf,0x5d,0x71, 0xf,0x5d,0x72, 0x5,0x60,0x4e, + 0x7,0x3e,0x3f, 0x7,0x3e,0x42, 0x5,0x60,0x4b, 0x5,0x66,0x63, + 0x7,0x45,0x4b, 0x4,0x5e,0x7b, 0x5,0x66,0x69, 0x7,0x45,0x4e, + 0x5,0x66,0x67, 0x5,0x66,0x65, 0x7,0x45,0x4f, 0x7,0x45,0x4c, + 0xf,0x61,0x67, 0x7,0x45,0x4a, 0x7,0x45,0x51, 0x5,0x66,0x62, + 0x7,0x45,0x4d, 0x7,0x45,0x50, 0x5,0x66,0x66, 0x5,0x6b,0x26, + 0x5,0x6b,0x29, 0x7,0x4c,0x4b, 0x5,0x6b,0x27, 0x7,0x4c,0x4c, + 0x7,0x4c,0x4d, 0xf,0x64,0x64, 0xf,0x64,0x65, 0xf,0x64,0x66, + 0xf,0x64,0x67, 0x5,0x66,0x64, 0x5,0x6b,0x28, 0x7,0x52,0x2b, + 0x4,0x65,0x52, 0x7,0x52,0x2a, 0x5,0x6f,0x21, 0x7,0x52,0x29, + 0x7,0x52,0x28, 0x5,0x6f,0x22, 0x7,0x52,0x26, 0xf,0x67,0x29, + 0x5,0x72,0x44, 0x5,0x72,0x46, 0x5,0x72,0x48, 0x4,0x68,0x37, + 0x7,0x56,0x67, 0x7,0x56,0x68, 0xf,0x69,0x25, 0x5,0x72,0x45, + 0x5,0x72,0x43, 0x7,0x56,0x69, 0x5,0x72,0x47, 0x5,0x75,0x2a, + 0x4,0x62,0x51, 0x7,0x5a,0x50, 0x4,0x69,0x78, 0x5,0x75,0x28, + 0x7,0x5a,0x4e, 0x4,0x69,0x79, 0x5,0x75,0x2b, 0xf,0x6a,0x3d, + 0x5,0x75,0x2c, 0x5,0x75,0x29, 0x4,0x69,0x7a, 0xf,0x67,0x2a, + 0x7,0x5a,0x4d, 0x5,0x76,0x7b, 0x5,0x76,0x7a, 0xf,0x69,0x26, + 0x5,0x78,0x54, 0x5,0x78,0x55, 0x4,0x6c,0x47, 0x7,0x60,0x3f, + 0x7,0x60,0x3e, 0x7,0x60,0x40, 0x7,0x60,0x3d, 0x5,0x79,0x67, + 0x5,0x79,0x66, 0xf,0x6c,0x44, 0x7,0x63,0x2f, 0x4,0x6e,0x2b, + 0x7,0x64,0x2e, 0x7,0x64,0x2f, 0x4,0x6e,0x41, 0x5,0x7b,0x51, + 0x5,0x7b,0x6f, 0x5,0x7c,0x25, 0x5,0x7c,0x40, 0x4,0x30,0x43, + 0x4,0x42,0x2a, 0x4,0x42,0x27, 0x6,0x5a,0x55, 0x4,0x42,0x28, + 0x6,0x5a,0x56, 0x5,0x44,0x4f, 0xf,0x46,0x3b, 0x6,0x64,0x6f, + 0x5,0x4b,0x65, 0x4,0x48,0x6c, 0x5,0x4b,0x63, 0xf,0x4d,0x4c, + 0xf,0x4d,0x4d, 0x5,0x4b,0x66, 0x4,0x4f,0x2f, 0x4,0x4f,0x33, + 0x4,0x4f,0x31, 0x4,0x4f,0x2d, 0x7,0x2b,0x68, 0x5,0x53,0x31, + 0x5,0x53,0x30, 0x7,0x2b,0x65, 0x7,0x2b,0x64, 0x5,0x53,0x2e, + 0x4,0x4f,0x38, 0x5,0x53,0x33, 0x5,0x53,0x2c, 0x5,0x53,0x2d, + 0x7,0x2b,0x6c, 0x7,0x2b,0x66, 0x4,0x4f,0x36, 0x5,0x53,0x32, + 0xf,0x53,0x37, 0xf,0x53,0x3a, 0xf,0x53,0x3d, 0x7,0x2b,0x6b, + 0x7,0x2b,0x67, 0x7,0x2b,0x69, 0x4,0x4f,0x2e, 0xf,0x53,0x39, + 0x5,0x53,0x2f, 0x5,0x5a,0x48, 0x5,0x5a,0x46, 0x7,0x36,0x3d, + 0x5,0x5a,0x49, 0x4,0x55,0x46, 0x4,0x5a,0x46, 0x5,0x5a,0x4e, + 0x5,0x5a,0x4d, 0x4,0x55,0x49, 0x7,0x36,0x43, 0x7,0x36,0x3e, + 0x7,0x36,0x41, 0x7,0x36,0x40, 0x5,0x5a,0x4c, 0x7,0x36,0x44, + 0xf,0x59,0x36, 0xf,0x59,0x37, 0xf,0x59,0x39, 0xf,0x59,0x3a, + 0x5,0x5a,0x4b, 0x7,0x36,0x42, 0xf,0x59,0x35, 0x5,0x5a,0x47, + 0x7,0x36,0x3f, 0x5,0x60,0x56, 0x4,0x5a,0x48, 0x5,0x60,0x57, + 0x5,0x60,0x54, 0x5,0x60,0x52, 0x4,0x5a,0x47, 0x7,0x3e,0x4b, + 0x5,0x60,0x55, 0x7,0x3e,0x46, 0x7,0x3e,0x4d, 0x7,0x3e,0x45, + 0x4,0x5a,0x4b, 0x7,0x3e,0x4c, 0x5,0x60,0x5a, 0x5,0x60,0x58, + 0x7,0x3e,0x44, 0x4,0x5a,0x4a, 0xf,0x46,0x3c, 0xf,0x5d,0x73, + 0xf,0x5d,0x74, 0xf,0x5d,0x75, 0xf,0x5d,0x77, 0xf,0x5d,0x79, + 0x7,0x3e,0x48, 0x5,0x60,0x5b, 0x5,0x60,0x53, 0x7,0x3e,0x4a, + 0x5,0x60,0x51, 0x5,0x60,0x59, 0x5,0x66,0x77, 0x5,0x66,0x74, + 0x5,0x66,0x70, 0x5,0x66,0x6b, 0x7,0x45,0x53, 0x4,0x5f,0x28, + 0x5,0x66,0x6d, 0x7,0x45,0x52, 0x5,0x66,0x6a, 0x5,0x66,0x71, + 0x5,0x66,0x75, 0x5,0x66,0x72, 0x5,0x66,0x6f, 0x5,0x66,0x6c, + 0x7,0x45,0x54, 0xf,0x61,0x68, 0xf,0x61,0x69, 0xf,0x61,0x6a, + 0xf,0x61,0x6b, 0xf,0x61,0x6c, 0xf,0x61,0x6d, 0xf,0x61,0x6e, + 0xf,0x61,0x6f, 0xf,0x61,0x71, 0xf,0x61,0x73, 0x7,0x45,0x55, + 0x7,0x3e,0x47, 0x5,0x66,0x76, 0x5,0x66,0x73, 0x7,0x4c,0x5b, + 0x7,0x4c,0x58, 0x4,0x62,0x5e, 0x7,0x4c,0x52, 0x5,0x6b,0x2d, + 0x4,0x62,0x52, 0x5,0x6b,0x2f, 0x7,0x4c,0x4f, 0x7,0x4c,0x51, + 0x4,0x62,0x5f, 0x5,0x66,0x78, 0x4,0x62,0x63, 0x5,0x6b,0x32, + 0x4,0x62,0x5b, 0x7,0x4c,0x4e, 0x4,0x62,0x5a, 0x4,0x62,0x65, + 0x7,0x4c,0x5a, 0x7,0x4c,0x53, 0x7,0x4c,0x59, 0x4,0x62,0x58, + 0x7,0x4c,0x55, 0x5,0x6b,0x36, 0x5,0x6b,0x2e, 0x7,0x4c,0x50, + 0x5,0x6b,0x34, 0xf,0x64,0x6e, 0xf,0x64,0x68, 0xf,0x64,0x6a, + 0xf,0x64,0x6c, 0xf,0x64,0x6f, 0xf,0x64,0x70, 0xf,0x64,0x71, + 0x5,0x6b,0x30, 0x7,0x4c,0x54, 0x7,0x4c,0x57, 0x4,0x62,0x53, + 0x5,0x6b,0x37, 0x5,0x6b,0x2a, 0xf,0x64,0x69, 0x5,0x6b,0x2c, + 0xf,0x61,0x70, 0x7,0x4c,0x56, 0x5,0x6f,0x27, 0x7,0x52,0x2e, + 0x5,0x6f,0x26, 0x5,0x6b,0x38, 0x5,0x6f,0x29, 0x7,0x52,0x2c, + 0x4,0x65,0x58, 0x5,0x6f,0x2b, 0x7,0x52,0x2f, 0x7,0x52,0x2d, + 0x5,0x6f,0x28, 0x4,0x65,0x56, 0x5,0x6f,0x24, 0x7,0x52,0x32, + 0x4,0x65,0x5e, 0x5,0x6f,0x25, 0x5,0x6f,0x23, 0x4,0x65,0x60, + 0x7,0x52,0x30, 0x5,0x6f,0x2c, 0x7,0x52,0x34, 0xf,0x67,0x2b, + 0xf,0x67,0x2c, 0xf,0x67,0x2d, 0xf,0x67,0x2f, 0xf,0x67,0x30, + 0xf,0x67,0x31, 0xf,0x67,0x32, 0xf,0x67,0x2e, 0x5,0x6f,0x2a, + 0xf,0x67,0x34, 0x5,0x72,0x4a, 0x4,0x68,0x3f, 0x5,0x72,0x4f, + 0x5,0x72,0x53, 0x5,0x77,0x23, 0x5,0x72,0x49, 0x5,0x72,0x52, + 0x4,0x68,0x38, 0x7,0x56,0x71, 0x5,0x72,0x4c, 0x7,0x56,0x72, + 0x5,0x72,0x57, 0x7,0x56,0x6d, 0x5,0x72,0x54, 0x5,0x72,0x4d, + 0x7,0x56,0x73, 0x7,0x56,0x75, 0x7,0x56,0x6a, 0x7,0x56,0x74, + 0x5,0x72,0x56, 0x7,0x56,0x6e, 0x7,0x56,0x6f, 0xf,0x69,0x28, + 0xf,0x69,0x29, 0xf,0x69,0x2b, 0xf,0x69,0x2c, 0xf,0x69,0x2d, + 0xf,0x69,0x2e, 0xf,0x69,0x2f, 0xf,0x69,0x30, 0xf,0x69,0x31, + 0xf,0x69,0x32, 0x7,0x56,0x6b, 0x7,0x56,0x6c, 0x5,0x72,0x55, + 0x7,0x56,0x70, 0x5,0x72,0x50, 0x7,0x5a,0x54, 0x7,0x5a,0x52, + 0x5,0x75,0x32, 0x4,0x6a,0x22, 0x5,0x75,0x2e, 0x5,0x75,0x2f, + 0x7,0x5a,0x5a, 0x7,0x5a,0x57, 0x5,0x75,0x30, 0x7,0x5a,0x5c, + 0x7,0x5a,0x59, 0x5,0x75,0x34, 0x7,0x5a,0x56, 0x7,0x5a,0x5b, + 0x7,0x5a,0x53, 0x7,0x5a,0x55, 0x7,0x5a,0x51, 0x7,0x5a,0x5e, + 0xf,0x6a,0x41, 0xf,0x6a,0x42, 0xf,0x6a,0x43, 0xf,0x6a,0x40, + 0x7,0x5a,0x5f, 0x5,0x75,0x33, 0x7,0x5a,0x58, 0x7,0x5a,0x5d, + 0x5,0x75,0x31, 0x5,0x76,0x7e, 0x7,0x5d,0x78, 0x5,0x77,0x22, + 0x4,0x6b,0x3e, 0x4,0x6b,0x3f, 0x5,0x76,0x7c, 0x7,0x5d,0x77, + 0x4,0x65,0x5c, 0x7,0x60,0x46, 0x7,0x5d,0x75, 0x7,0x5e,0x22, + 0x7,0x5d,0x76, 0x5,0x76,0x7d, 0x7,0x5e,0x21, 0x7,0x5d,0x7c, + 0x5,0x77,0x21, 0x7,0x5d,0x79, 0xf,0x6b,0x3d, 0xf,0x6b,0x3f, + 0x7,0x5d,0x7a, 0x7,0x5d,0x7d, 0x7,0x5d,0x7e, 0x7,0x5d,0x7b, + 0xf,0x6b,0x3c, 0x7,0x60,0x43, 0x5,0x78,0x5c, 0x5,0x78,0x60, + 0x5,0x78,0x5a, 0x7,0x60,0x41, 0x4,0x6c,0x4f, 0x4,0x6c,0x4c, + 0x5,0x78,0x59, 0x5,0x78,0x61, 0x4,0x6c,0x4b, 0x5,0x78,0x5f, + 0x5,0x78,0x5e, 0x5,0x78,0x57, 0x7,0x60,0x4b, 0x7,0x60,0x47, + 0x5,0x78,0x58, 0xf,0x6b,0x75, 0xf,0x6b,0x78, 0x7,0x60,0x48, + 0x7,0x60,0x42, 0x7,0x60,0x44, 0x7,0x60,0x45, 0x5,0x78,0x5d, + 0x7,0x60,0x4a, 0x7,0x60,0x49, 0x7,0x61,0x73, 0x5,0x79,0x68, + 0x4,0x6d,0x38, 0x5,0x79,0x69, 0x7,0x61,0x6e, 0x7,0x60,0x7a, + 0x7,0x61,0x71, 0x7,0x61,0x6f, 0x5,0x79,0x6b, 0x7,0x61,0x72, + 0x7,0x61,0x70, 0xf,0x6c,0x45, 0xf,0x6c,0x46, 0x5,0x79,0x6a, + 0x7,0x61,0x6d, 0x7,0x63,0x35, 0x7,0x63,0x30, 0x7,0x63,0x32, + 0x7,0x63,0x33, 0x7,0x63,0x34, 0x5,0x7a,0x51, 0x5,0x7a,0x52, + 0xf,0x6c,0x5a, 0xf,0x6c,0x5b, 0xf,0x6c,0x5c, 0xf,0x6c,0x5d, + 0x7,0x63,0x31, 0x5,0x7b,0x28, 0x5,0x7b,0x27, 0x7,0x64,0x30, + 0x5,0x7b,0x29, 0xf,0x6c,0x74, 0x7,0x64,0x31, 0x5,0x7b,0x2a, + 0x7,0x64,0x32, 0x7,0x64,0x7e, 0x5,0x7b,0x53, 0x5,0x7b,0x52, + 0x5,0x7b,0x55, 0x7,0x64,0x7c, 0x7,0x65,0x21, 0x7,0x64,0x7b, + 0x5,0x7b,0x54, 0x7,0x64,0x7d, 0xf,0x6c,0x75, 0x5,0x7b,0x73, + 0x5,0x7b,0x72, 0x5,0x7b,0x71, 0x5,0x7b,0x70, 0x7,0x65,0x50, + 0x5,0x7c,0x26, 0xf,0x6d,0x2b, 0xf,0x6d,0x2c, 0x5,0x7c,0x27, + 0x7,0x65,0x6b, 0x5,0x7c,0x2e, 0x5,0x7c,0x37, 0x7,0x66,0x2f, + 0x5,0x7c,0x36, 0xf,0x53,0x3c, 0xf,0x5d,0x78, 0xf,0x6b,0x3e, + 0x6,0x50,0x4c, 0xf,0x40,0x33, 0x6,0x50,0x4d, 0x4,0x42,0x2b, + 0x6,0x5a,0x57, 0x5,0x44,0x51, 0x5,0x44,0x52, 0x6,0x5a,0x5c, + 0x6,0x5a,0x58, 0x6,0x5a,0x59, 0x5,0x44,0x50, 0x6,0x5a,0x5a, + 0x6,0x5a,0x5b, 0x6,0x64,0x70, 0x5,0x4b,0x6a, 0x6,0x64,0x71, + 0x5,0x4b,0x69, 0x4,0x48,0x6e, 0x4,0x48,0x6f, 0x6,0x64,0x72, + 0x6,0x64,0x73, 0x6,0x64,0x74, 0x4,0x48,0x70, 0x5,0x4b,0x68, + 0xf,0x4d,0x4f, 0xf,0x4d,0x50, 0xf,0x4d,0x51, 0x5,0x4b,0x67, + 0x4,0x4f,0x45, 0x7,0x2b,0x72, 0x7,0x2b,0x7d, 0x7,0x2b,0x6f, + 0x7,0x2b,0x73, 0x7,0x2b,0x79, 0x5,0x53,0x37, 0x5,0x53,0x3b, + 0x5,0x53,0x3d, 0x5,0x53,0x39, 0x7,0x2b,0x76, 0x7,0x2b,0x7c, + 0x5,0x53,0x3f, 0x5,0x53,0x34, 0x4,0x4f,0x3d, 0x5,0x53,0x41, + 0x5,0x53,0x3e, 0x5,0x53,0x35, 0x4,0x4f,0x3e, 0x5,0x53,0x42, + 0x7,0x2b,0x7a, 0x4,0x4f,0x3c, 0x7,0x2b,0x75, 0x4,0x4f,0x43, + 0x4,0x4f,0x3a, 0x5,0x53,0x43, 0x4,0x4f,0x46, 0x7,0x2b,0x70, + 0x7,0x2b,0x7b, 0xf,0x53,0x40, 0x7,0x2b,0x6e, 0x7,0x2b,0x77, + 0x7,0x2b,0x78, 0x5,0x53,0x36, 0x5,0x53,0x3a, 0x5,0x53,0x40, + 0x7,0x2b,0x71, 0x7,0x2b,0x74, 0x5,0x53,0x3c, 0x7,0x36,0x4b, + 0x5,0x5a,0x54, 0x5,0x5a,0x56, 0x5,0x5a,0x51, 0x5,0x5a,0x4f, + 0x4,0x55,0x4c, 0x5,0x5a,0x53, 0x5,0x5a,0x59, 0x5,0x5a,0x52, + 0x7,0x36,0x57, 0x7,0x36,0x52, 0x5,0x5a,0x57, 0x4,0x55,0x56, + 0x7,0x36,0x54, 0x5,0x5a,0x58, 0x7,0x36,0x50, 0x5,0x5a,0x55, + 0x7,0x36,0x53, 0x7,0x36,0x4c, 0x7,0x36,0x45, 0x7,0x36,0x4e, + 0xf,0x59,0x3d, 0xf,0x59,0x3e, 0xf,0x59,0x3f, 0xf,0x59,0x40, + 0x7,0x36,0x4d, 0x7,0x36,0x4f, 0x7,0x36,0x58, 0x7,0x36,0x56, + 0x7,0x36,0x47, 0x7,0x36,0x48, 0x7,0x36,0x55, 0x4,0x55,0x53, + 0x4,0x55,0x51, 0x6,0x50,0x4e, 0x7,0x36,0x49, 0x5,0x5a,0x50, + 0x7,0x36,0x46, 0xf,0x56,0x33, 0x7,0x3e,0x51, 0x4,0x5a,0x4c, + 0x5,0x60,0x5e, 0x5,0x60,0x69, 0x7,0x3e,0x54, 0x4,0x5a,0x53, + 0x5,0x60,0x67, 0x7,0x3e,0x55, 0x5,0x60,0x5d, 0x5,0x60,0x61, + 0x7,0x3e,0x4e, 0x5,0x60,0x64, 0x5,0x60,0x6b, 0x5,0x60,0x60, + 0x5,0x60,0x62, 0x4,0x5a,0x54, 0x7,0x3e,0x57, 0x5,0x60,0x5c, + 0x5,0x60,0x63, 0x4,0x5a,0x58, 0x7,0x3e,0x4f, 0x4,0x5a,0x5b, + 0x5,0x60,0x6c, 0x7,0x3e,0x58, 0x7,0x3e,0x53, 0x5,0x60,0x68, + 0x5,0x60,0x6a, 0xf,0x5d,0x7a, 0xf,0x5d,0x7b, 0xf,0x5d,0x7c, + 0xf,0x5d,0x7d, 0xf,0x5e,0x21, 0xf,0x5e,0x22, 0xf,0x5e,0x23, + 0xf,0x5e,0x25, 0x7,0x3e,0x50, 0x5,0x60,0x5f, 0x4,0x5a,0x5a, + 0x7,0x3e,0x56, 0x5,0x60,0x65, 0x5,0x60,0x66, 0x7,0x3e,0x52, + 0x4,0x5a,0x57, 0x7,0x45,0x5b, 0x5,0x60,0x6d, 0x7,0x45,0x5f, + 0x5,0x66,0x7d, 0x5,0x67,0x25, 0x5,0x67,0x27, 0x4,0x5f,0x2e, + 0x5,0x67,0x2a, 0x5,0x66,0x7a, 0x5,0x67,0x21, 0x5,0x66,0x7e, + 0x5,0x66,0x7b, 0x7,0x45,0x5d, 0x7,0x45,0x58, 0x4,0x5f,0x2d, + 0x7,0x45,0x5e, 0x5,0x66,0x7c, 0x5,0x67,0x2b, 0x4,0x5f,0x30, + 0x7,0x45,0x67, 0x5,0x67,0x22, 0x7,0x45,0x64, 0x7,0x45,0x5c, + 0x5,0x67,0x28, 0x7,0x45,0x61, 0x7,0x45,0x62, 0x7,0x45,0x66, + 0x5,0x67,0x24, 0x7,0x45,0x59, 0x5,0x67,0x23, 0x7,0x45,0x68, + 0x7,0x45,0x56, 0x7,0x45,0x60, 0xf,0x61,0x74, 0xf,0x61,0x75, + 0x7,0x45,0x57, 0x5,0x67,0x29, 0x7,0x45,0x63, 0x5,0x6b,0x39, + 0x7,0x4c,0x5d, 0x5,0x6b,0x3a, 0x7,0x4c,0x62, 0x5,0x6b,0x3e, + 0x5,0x6b,0x4a, 0x5,0x6b,0x40, 0x7,0x4c,0x6a, 0x7,0x4c,0x64, + 0x5,0x6b,0x3b, 0x7,0x4c,0x68, 0x7,0x4c,0x6b, 0x7,0x4c,0x63, + 0x5,0x6b,0x4c, 0x5,0x6b,0x3d, 0x5,0x6b,0x4b, 0x4,0x62,0x6b, + 0x5,0x6b,0x42, 0x5,0x6b,0x45, 0x7,0x4c,0x60, 0x7,0x4c,0x5e, + 0x5,0x6b,0x48, 0x5,0x6b,0x44, 0x7,0x4c,0x5c, 0x7,0x4c,0x66, + 0x7,0x4c,0x6c, 0x5,0x6b,0x41, 0x4,0x62,0x6d, 0x7,0x4c,0x69, + 0x5,0x6b,0x46, 0xf,0x64,0x74, 0xf,0x64,0x76, 0xf,0x64,0x77, + 0x7,0x4c,0x61, 0x5,0x6b,0x47, 0x7,0x4c,0x6f, 0x5,0x6b,0x49, + 0x7,0x45,0x69, 0x7,0x4c,0x65, 0x7,0x4c,0x67, 0x7,0x4c,0x6d, + 0x5,0x6b,0x43, 0x7,0x4c,0x6e, 0x7,0x4c,0x5f, 0x4,0x62,0x69, + 0x5,0x6f,0x38, 0x5,0x6f,0x30, 0x7,0x52,0x3a, 0x4,0x65,0x65, + 0x5,0x6f,0x3e, 0x7,0x52,0x43, 0x5,0x6f,0x32, 0x5,0x6f,0x42, + 0x4,0x62,0x70, 0x7,0x52,0x36, 0x5,0x6f,0x2f, 0x4,0x65,0x63, + 0x5,0x6f,0x31, 0x4,0x65,0x6e, 0x4,0x65,0x68, 0x5,0x6f,0x33, + 0x5,0x6f,0x2d, 0x5,0x6f,0x37, 0x5,0x6f,0x44, 0x5,0x6f,0x39, + 0x4,0x65,0x6d, 0x4,0x65,0x66, 0x5,0x6f,0x3a, 0x5,0x6f,0x3c, + 0x5,0x6f,0x40, 0x4,0x65,0x67, 0x5,0x6f,0x2e, 0x5,0x6f,0x3b, + 0x5,0x6f,0x36, 0x5,0x6f,0x3f, 0x7,0x52,0x3f, 0x7,0x52,0x3b, + 0x7,0x52,0x40, 0x7,0x52,0x35, 0x7,0x52,0x37, 0x5,0x6f,0x3d, + 0x5,0x6f,0x35, 0x5,0x6f,0x34, 0x5,0x6f,0x43, 0x7,0x52,0x38, + 0xf,0x67,0x37, 0x7,0x52,0x3e, 0x7,0x52,0x3d, 0x7,0x52,0x39, + 0x7,0x52,0x44, 0x7,0x52,0x41, 0x7,0x52,0x3c, 0xf,0x67,0x38, + 0x5,0x6f,0x41, 0x7,0x45,0x5a, 0x5,0x72,0x5e, 0x7,0x56,0x79, + 0x5,0x72,0x66, 0x7,0x56,0x7e, 0x5,0x72,0x5d, 0x5,0x72,0x60, + 0x5,0x72,0x5b, 0x5,0x72,0x65, 0x5,0x72,0x64, 0x7,0x57,0x21, + 0x7,0x56,0x7d, 0x7,0x56,0x7a, 0x5,0x72,0x68, 0x7,0x57,0x27, + 0x7,0x57,0x26, 0x7,0x57,0x24, 0x5,0x72,0x5c, 0x5,0x72,0x61, + 0x5,0x6f,0x45, 0x5,0x72,0x5a, 0x5,0x72,0x62, 0x7,0x57,0x22, + 0x7,0x56,0x7c, 0x5,0x72,0x69, 0x5,0x72,0x6a, 0xf,0x69,0x34, + 0x5,0x72,0x5f, 0x7,0x57,0x23, 0x7,0x56,0x77, 0x7,0x57,0x28, + 0x7,0x56,0x76, 0x7,0x56,0x7b, 0xf,0x69,0x33, 0x5,0x72,0x58, + 0x7,0x56,0x78, 0x5,0x72,0x59, 0xf,0x67,0x36, 0x5,0x75,0x42, + 0x5,0x75,0x3d, 0x4,0x6a,0x24, 0x4,0x6a,0x2d, 0x5,0x75,0x3c, + 0x4,0x6a,0x28, 0x5,0x75,0x43, 0x5,0x75,0x39, 0x5,0x6f,0x46, + 0x5,0x75,0x44, 0x5,0x75,0x40, 0x5,0x75,0x3f, 0x4,0x6a,0x2b, + 0x7,0x5a,0x62, 0x7,0x5a,0x6c, 0x7,0x5a,0x6a, 0x7,0x5a,0x70, + 0x4,0x6a,0x2a, 0x7,0x5a,0x6b, 0x7,0x5a,0x6e, 0x5,0x75,0x3b, + 0x4,0x6a,0x29, 0x7,0x5a,0x69, 0x5,0x75,0x37, 0x7,0x5a,0x68, + 0x5,0x75,0x38, 0x5,0x75,0x46, 0x5,0x72,0x67, 0x7,0x5a,0x71, + 0x5,0x75,0x41, 0x7,0x5a,0x6f, 0x7,0x5a,0x67, 0x7,0x57,0x25, + 0xf,0x6a,0x44, 0xf,0x6a,0x45, 0xf,0x6a,0x46, 0xf,0x6a,0x47, + 0xf,0x6a,0x48, 0x5,0x75,0x3e, 0x7,0x5a,0x66, 0x7,0x5a,0x64, + 0x7,0x5a,0x61, 0x7,0x5a,0x63, 0x5,0x75,0x3a, 0x7,0x5e,0x2b, + 0x7,0x5e,0x27, 0x7,0x5e,0x31, 0x5,0x77,0x33, 0x7,0x5e,0x2f, + 0x5,0x77,0x2e, 0x5,0x77,0x29, 0x4,0x6b,0x43, 0x7,0x5e,0x32, + 0x7,0x5e,0x36, 0x5,0x77,0x25, 0x5,0x77,0x30, 0x5,0x77,0x2a, + 0x5,0x77,0x28, 0x5,0x77,0x2f, 0x7,0x5e,0x2c, 0x5,0x77,0x27, + 0x5,0x77,0x26, 0x5,0x77,0x38, 0x5,0x77,0x2b, 0x4,0x6b,0x49, + 0x4,0x6b,0x42, 0x7,0x5e,0x35, 0x5,0x77,0x31, 0x7,0x5e,0x30, + 0x7,0x5e,0x33, 0x5,0x77,0x2d, 0x7,0x5a,0x65, 0x5,0x77,0x35, + 0x7,0x5a,0x6d, 0x7,0x5e,0x34, 0x5,0x77,0x36, 0x7,0x5e,0x2d, + 0xf,0x6b,0x40, 0x7,0x5e,0x24, 0x7,0x5e,0x26, 0x7,0x5e,0x2e, + 0x7,0x5e,0x29, 0x7,0x5e,0x28, 0x5,0x77,0x32, 0x7,0x5e,0x2a, + 0x7,0x5e,0x25, 0x4,0x6b,0x41, 0xf,0x6b,0x7a, 0x7,0x5e,0x37, + 0x7,0x60,0x4d, 0x5,0x78,0x67, 0x5,0x78,0x69, 0x5,0x78,0x6d, + 0x5,0x78,0x65, 0x5,0x77,0x37, 0x5,0x78,0x68, 0x7,0x60,0x4e, + 0x5,0x78,0x6a, 0x5,0x78,0x6b, 0x7,0x60,0x4f, 0x7,0x60,0x50, + 0x7,0x60,0x54, 0x5,0x78,0x6c, 0x7,0x60,0x53, 0x7,0x60,0x4c, + 0x7,0x60,0x51, 0x5,0x78,0x63, 0x5,0x78,0x66, 0x5,0x78,0x62, + 0xf,0x6b,0x79, 0x7,0x60,0x52, 0x4,0x6c,0x55, 0x5,0x78,0x64, + 0x4,0x6c,0x53, 0x5,0x79,0x71, 0x5,0x79,0x6d, 0x5,0x79,0x70, + 0x7,0x61,0x76, 0x4,0x6d,0x3b, 0x5,0x79,0x6e, 0x5,0x79,0x6c, + 0x4,0x6d,0x3c, 0x7,0x61,0x74, 0x5,0x79,0x6f, 0x7,0x61,0x78, + 0x7,0x61,0x75, 0x7,0x61,0x77, 0x4,0x6d,0x3e, 0x5,0x7a,0x58, + 0x7,0x63,0x39, 0x5,0x7a,0x56, 0x4,0x6d,0x6b, 0x5,0x7a,0x5a, + 0x5,0x7a,0x59, 0x5,0x7a,0x55, 0x5,0x7a,0x57, 0x4,0x6d,0x6a, + 0x7,0x63,0x38, 0x5,0x7a,0x54, 0x7,0x63,0x3b, 0x5,0x7a,0x5b, + 0x7,0x63,0x3d, 0xf,0x6c,0x5e, 0x7,0x63,0x3a, 0x7,0x63,0x36, + 0x7,0x63,0x3c, 0x5,0x7b,0x2e, 0x7,0x64,0x34, 0x7,0x64,0x36, + 0x5,0x7b,0x2f, 0x5,0x7b,0x2c, 0x5,0x7b,0x2b, 0x5,0x7b,0x31, + 0x5,0x7b,0x30, 0x5,0x7b,0x2d, 0x7,0x64,0x37, 0xf,0x6c,0x76, + 0x4,0x6e,0x2e, 0x7,0x64,0x33, 0x7,0x64,0x35, 0x5,0x7b,0x56, + 0x7,0x65,0x22, 0x7,0x65,0x53, 0x7,0x65,0x24, 0x7,0x65,0x26, + 0x7,0x65,0x23, 0x7,0x65,0x27, 0x5,0x7b,0x57, 0x7,0x65,0x25, + 0x4,0x6e,0x42, 0x5,0x7b,0x74, 0x7,0x65,0x54, 0x7,0x65,0x55, + 0x5,0x7b,0x75, 0x7,0x65,0x52, 0x7,0x65,0x56, 0x7,0x65,0x51, + 0x7,0x65,0x6d, 0x7,0x65,0x6c, 0x5,0x7c,0x29, 0x5,0x7c,0x28, + 0xf,0x6d,0x32, 0x5,0x7c,0x2f, 0x7,0x66,0x21, 0x7,0x65,0x7e, + 0x5,0x7c,0x38, 0x7,0x66,0x30, 0x5,0x7c,0x39, 0x7,0x66,0x3a, + 0x5,0x7c,0x41, 0xf,0x6d,0x37, 0x5,0x7c,0x48, 0x7,0x66,0x45, + 0x4,0x48,0x71, 0x4,0x48,0x72, 0x5,0x53,0x44, 0x7,0x2c,0x22, + 0x7,0x2c,0x21, 0x7,0x2b,0x7e, 0x5,0x5a,0x5a, 0x5,0x5a,0x5c, + 0x7,0x36,0x5a, 0x7,0x36,0x5b, 0xf,0x59,0x41, 0x7,0x36,0x59, + 0x5,0x67,0x2c, 0x7,0x3e,0x59, 0x4,0x62,0x71, 0x7,0x4c,0x70, + 0x5,0x6b,0x4d, 0x7,0x4c,0x71, 0x7,0x52,0x46, 0x5,0x6f,0x48, + 0x5,0x6f,0x49, 0x7,0x52,0x47, 0x5,0x6f,0x47, 0x7,0x52,0x49, + 0x7,0x52,0x48, 0x4,0x68,0x45, 0x7,0x57,0x2b, 0x7,0x57,0x2a, + 0x5,0x72,0x6b, 0x7,0x5a,0x73, 0x7,0x5a,0x72, 0x4,0x6b,0x4c, + 0x7,0x5e,0x38, 0x7,0x5e,0x39, 0x5,0x77,0x39, 0x7,0x60,0x55, + 0x4,0x6c,0x57, 0x5,0x79,0x72, 0x4,0x6d,0x3f, 0x7,0x63,0x3e, + 0x5,0x7b,0x32, 0x6,0x5a,0x5d, 0xf,0x46,0x3d, 0x5,0x4b,0x6c, + 0xf,0x4d,0x52, 0x7,0x2c,0x28, 0x5,0x53,0x45, 0x7,0x2c,0x27, + 0x7,0x2c,0x26, 0x7,0x2c,0x24, 0x5,0x53,0x46, 0x7,0x2c,0x25, + 0x5,0x53,0x47, 0x7,0x2c,0x29, 0x7,0x2c,0x23, 0x7,0x36,0x5d, + 0x5,0x5a,0x5d, 0xf,0x59,0x42, 0xf,0x59,0x43, 0xf,0x59,0x44, + 0x5,0x60,0x6f, 0x5,0x60,0x72, 0x5,0x60,0x70, 0x4,0x5a,0x5c, + 0x5,0x60,0x73, 0x5,0x60,0x71, 0x7,0x3e,0x5b, 0x7,0x3e,0x5a, + 0x7,0x3e,0x5e, 0x7,0x3e,0x5d, 0xf,0x5e,0x26, 0x5,0x60,0x6e, + 0x7,0x45,0x6e, 0x5,0x67,0x31, 0x5,0x67,0x2e, 0x5,0x67,0x2d, + 0x7,0x45,0x6b, 0x7,0x45,0x6d, 0x7,0x45,0x6a, 0x5,0x67,0x30, + 0x7,0x45,0x6c, 0xf,0x61,0x78, 0xf,0x61,0x79, 0xf,0x61,0x7a, + 0x5,0x67,0x2f, 0x5,0x6b,0x4f, 0x5,0x6b,0x4e, 0x5,0x6b,0x51, + 0x4,0x62,0x73, 0x7,0x4c,0x73, 0x5,0x6b,0x50, 0x7,0x4c,0x72, + 0x5,0x68,0x40, 0x7,0x52,0x4b, 0x4,0x62,0x74, 0x4,0x65,0x6f, + 0x7,0x4c,0x74, 0xf,0x67,0x39, 0x7,0x52,0x4a, 0x7,0x52,0x4c, + 0x5,0x6f,0x4a, 0x4,0x68,0x47, 0x7,0x57,0x2c, 0x7,0x57,0x2d, + 0x4,0x68,0x46, 0xf,0x69,0x35, 0x5,0x75,0x47, 0x4,0x6a,0x2e, + 0xf,0x6a,0x49, 0x5,0x77,0x3a, 0x5,0x77,0x3c, 0x5,0x77,0x3b, + 0x7,0x5e,0x3a, 0x7,0x5e,0x3b, 0x7,0x60,0x56, 0x4,0x6c,0x58, + 0x7,0x60,0x57, 0xf,0x6b,0x7b, 0x5,0x79,0x75, 0x5,0x79,0x74, + 0x5,0x78,0x6e, 0x4,0x6d,0x40, 0x4,0x6d,0x6c, 0xf,0x6c,0x47, + 0x7,0x65,0x28, 0x7,0x65,0x57, 0x5,0x7c,0x46, 0x7,0x66,0x47, + 0x6,0x5a,0x5f, 0x6,0x5a,0x5e, 0x5,0x44,0x53, 0xf,0x46,0x3f, + 0x4,0x48,0x75, 0x6,0x64,0x75, 0xf,0x4d,0x53, 0x5,0x53,0x4b, + 0x5,0x53,0x4a, 0x4,0x4f,0x4f, 0x5,0x53,0x49, 0x5,0x53,0x48, + 0x7,0x2c,0x2b, 0x7,0x2c,0x2f, 0x7,0x2c,0x2a, 0x4,0x4f,0x4e, + 0x7,0x2c,0x2c, 0x5,0x53,0x4c, 0x7,0x2c,0x2e, 0x7,0x2c,0x2d, + 0x7,0x36,0x61, 0x7,0x36,0x5f, 0x7,0x36,0x5e, 0x7,0x36,0x63, + 0x4,0x55,0x5b, 0x7,0x36,0x62, 0x6,0x47,0x53, 0xf,0x59,0x45, + 0x5,0x5a,0x5e, 0x7,0x36,0x60, 0x5,0x60,0x74, 0x5,0x60,0x75, + 0x7,0x3e,0x60, 0x7,0x3e,0x61, 0xf,0x5e,0x28, 0x7,0x3e,0x62, + 0x7,0x3e,0x5f, 0x7,0x45,0x70, 0x5,0x67,0x32, 0x7,0x45,0x72, + 0x5,0x67,0x33, 0x5,0x67,0x35, 0x7,0x45,0x73, 0x5,0x67,0x34, + 0xf,0x61,0x7b, 0x7,0x45,0x71, 0x7,0x45,0x6f, 0x4,0x62,0x7a, + 0x4,0x62,0x78, 0x7,0x4c,0x79, 0x7,0x4c,0x7b, 0x7,0x4c,0x75, + 0x5,0x6b,0x54, 0x5,0x6b,0x52, 0x7,0x4c,0x7a, 0x5,0x6b,0x55, + 0x5,0x6b,0x53, 0x7,0x4c,0x78, 0x4,0x62,0x7b, 0x7,0x4c,0x77, + 0x7,0x4c,0x76, 0x5,0x6f,0x4b, 0x7,0x52,0x53, 0x7,0x52,0x52, + 0x5,0x6f,0x4c, 0x7,0x52,0x50, 0x4,0x65,0x70, 0x7,0x52,0x4f, + 0x5,0x6f,0x4e, 0x5,0x6f,0x4d, 0x7,0x52,0x51, 0xf,0x67,0x3a, + 0x7,0x52,0x4e, 0x7,0x52,0x4d, 0x5,0x72,0x6c, 0x7,0x57,0x2f, + 0x5,0x72,0x6f, 0x7,0x57,0x30, 0x5,0x72,0x6e, 0x7,0x57,0x31, + 0x7,0x57,0x2e, 0x5,0x72,0x6d, 0x5,0x75,0x4b, 0x5,0x75,0x4c, + 0x7,0x5a,0x74, 0x5,0x75,0x49, 0x5,0x75,0x4e, 0x7,0x5a,0x7b, + 0x7,0x5a,0x76, 0x7,0x5a,0x77, 0x7,0x5a,0x7c, 0x7,0x5a,0x79, + 0x5,0x75,0x4a, 0x7,0x5a,0x75, 0x7,0x5a,0x78, 0x7,0x5a,0x7a, + 0x5,0x77,0x3f, 0x4,0x6b,0x4f, 0x5,0x77,0x3e, 0x5,0x77,0x40, + 0x5,0x77,0x3d, 0x5,0x78,0x6f, 0x5,0x78,0x71, 0x5,0x78,0x70, + 0x7,0x60,0x59, 0x7,0x5e,0x3c, 0x4,0x6c,0x59, 0x7,0x60,0x58, + 0x4,0x6d,0x6d, 0x7,0x63,0x3f, 0x7,0x64,0x39, 0x7,0x64,0x38, + 0x5,0x7b,0x58, 0x7,0x65,0x29, 0x4,0x6e,0x52, 0x5,0x7c,0x30, + 0xf,0x29,0x21, 0xf,0x46,0x3e, 0xf,0x53,0x42, 0xf,0x5e,0x27, + 0x5,0x4b,0x70, 0x5,0x4b,0x6e, 0x5,0x4b,0x6f, 0x5,0x53,0x4e, + 0x4,0x4f,0x50, 0x5,0x53,0x4d, 0x7,0x2c,0x30, 0x5,0x5a,0x61, + 0x7,0x36,0x64, 0x5,0x5a,0x5f, 0x5,0x5a,0x60, 0xf,0x59,0x46, + 0x5,0x60,0x78, 0x5,0x60,0x76, 0xf,0x5e,0x29, 0x5,0x60,0x77, + 0x5,0x67,0x36, 0x7,0x4c,0x7c, 0x5,0x6b,0x56, 0x7,0x4c,0x7d, + 0x4,0x65,0x73, 0x7,0x57,0x32, 0x5,0x72,0x70, 0x7,0x5a,0x7e, + 0x4,0x6b,0x50, 0x7,0x5b,0x56, 0x7,0x5e,0x3d, 0x4,0x6b,0x51, + 0x5,0x7c,0x31, 0xf,0x4d,0x54, 0x7,0x2c,0x32, 0x5,0x5a,0x62, + 0x5,0x5a,0x64, 0x5,0x5a,0x63, 0x5,0x60,0x7a, 0x5,0x67,0x38, + 0x5,0x60,0x79, 0x5,0x67,0x39, 0x5,0x67,0x37, 0x5,0x6b,0x57, + 0x4,0x63,0x22, 0xf,0x64,0x79, 0x4,0x65,0x75, 0x4,0x65,0x74, + 0x5,0x6f,0x50, 0x5,0x6f,0x4f, 0x4,0x65,0x77, 0x7,0x52,0x54, + 0x7,0x52,0x55, 0x7,0x52,0x56, 0xf,0x67,0x3b, 0x7,0x52,0x57, + 0x5,0x72,0x73, 0x5,0x72,0x72, 0x5,0x72,0x71, 0x7,0x57,0x33, + 0x7,0x57,0x34, 0x5,0x75,0x4f, 0x4,0x6a,0x2f, 0x4,0x6a,0x30, + 0x7,0x5b,0x23, 0x7,0x5b,0x22, 0x7,0x5b,0x21, 0x7,0x5e,0x3e, + 0x5,0x78,0x72, 0x7,0x60,0x5a, 0x5,0x78,0x73, 0x7,0x61,0x79, + 0x5,0x79,0x76, 0x7,0x66,0x27, 0x4,0x48,0x76, 0x5,0x53,0x4f, + 0x4,0x4f,0x51, 0x7,0x36,0x68, 0x7,0x36,0x66, 0x5,0x5a,0x66, + 0x5,0x5a,0x65, 0x5,0x5a,0x67, 0x5,0x60,0x7e, 0x7,0x3e,0x64, + 0x5,0x60,0x7c, 0x7,0x3e,0x63, 0x5,0x60,0x7b, 0x4,0x5a,0x5e, + 0x5,0x60,0x7d, 0x7,0x3e,0x65, 0x7,0x3e,0x66, 0x5,0x67,0x3b, + 0x5,0x67,0x3a, 0x4,0x65,0x78, 0x5,0x6f,0x51, 0x5,0x6f,0x53, + 0x5,0x72,0x74, 0x7,0x57,0x36, 0x7,0x57,0x35, 0xf,0x69,0x36, + 0x5,0x75,0x50, 0x4,0x6b,0x54, 0x5,0x77,0x42, 0x5,0x77,0x41, + 0x4,0x6b,0x53, 0x7,0x63,0x40, 0x7,0x61,0x7a, 0x4,0x6d,0x6e, + 0x5,0x7b,0x5a, 0x7,0x65,0x2a, 0x5,0x7b,0x59, 0x6,0x64,0x76, + 0x5,0x44,0x54, 0x6,0x64,0x78, 0x6,0x64,0x77, 0x7,0x2c,0x34, + 0x4,0x4f,0x55, 0x4,0x4f,0x54, 0x5,0x53,0x50, 0x7,0x2c,0x35, + 0x7,0x2c,0x36, 0x7,0x36,0x6a, 0x5,0x5a,0x6a, 0x5,0x5a,0x68, + 0x5,0x5a,0x69, 0x7,0x36,0x69, 0x7,0x36,0x6b, 0x7,0x36,0x6c, + 0x4,0x5a,0x60, 0x7,0x3e,0x68, 0x5,0x61,0x21, 0xf,0x5e,0x2a, + 0x7,0x3e,0x67, 0x5,0x67,0x3e, 0x5,0x67,0x3c, 0x7,0x45,0x74, + 0x5,0x6b,0x58, 0x5,0x61,0x22, 0x5,0x67,0x3f, 0x5,0x6b,0x5a, + 0x5,0x6b,0x59, 0x5,0x6b,0x5b, 0x5,0x6b,0x5d, 0x5,0x6b,0x5c, + 0x7,0x4d,0x21, 0x7,0x4c,0x7e, 0x5,0x6f,0x56, 0x5,0x6f,0x57, + 0x7,0x52,0x5b, 0x5,0x6f,0x5b, 0x5,0x6f,0x59, 0x5,0x6f,0x55, + 0x7,0x52,0x58, 0x4,0x65,0x7e, 0x4,0x65,0x7b, 0x7,0x52,0x5c, + 0x5,0x6f,0x5a, 0x4,0x65,0x7a, 0x7,0x52,0x5a, 0xf,0x67,0x3c, + 0x7,0x52,0x59, 0x7,0x57,0x38, 0x4,0x68,0x53, 0x4,0x68,0x51, + 0x5,0x72,0x78, 0x4,0x68,0x50, 0x5,0x72,0x7b, 0x7,0x57,0x37, + 0x5,0x72,0x75, 0x5,0x72,0x79, 0x5,0x72,0x77, 0x4,0x68,0x54, + 0x5,0x72,0x76, 0x4,0x68,0x55, 0x4,0x6a,0x34, 0x7,0x57,0x39, + 0x7,0x57,0x3a, 0x5,0x72,0x7a, 0x5,0x75,0x51, 0x4,0x6a,0x33, + 0x4,0x6a,0x35, 0x7,0x5b,0x2a, 0x7,0x5b,0x27, 0x7,0x5b,0x26, + 0x4,0x6a,0x32, 0x7,0x5b,0x29, 0x7,0x5b,0x28, 0x5,0x75,0x52, + 0x7,0x5b,0x25, 0x5,0x77,0x47, 0x7,0x5e,0x41, 0x5,0x77,0x46, + 0x5,0x77,0x44, 0x5,0x77,0x45, 0x5,0x77,0x43, 0x5,0x77,0x48, + 0x7,0x5e,0x3f, 0x5,0x78,0x76, 0x5,0x78,0x77, 0x7,0x60,0x5d, + 0x4,0x6c,0x5c, 0x4,0x6c,0x60, 0x5,0x78,0x75, 0x7,0x60,0x5c, + 0x5,0x78,0x74, 0x4,0x6c,0x5f, 0x4,0x6c,0x5e, 0x4,0x6c,0x5d, + 0x7,0x5e,0x40, 0x7,0x60,0x5b, 0x5,0x79,0x78, 0x5,0x79,0x79, + 0x5,0x79,0x7a, 0x5,0x79,0x77, 0x4,0x6d,0x45, 0x7,0x61,0x7b, + 0x7,0x61,0x7c, 0x4,0x6d,0x46, 0x5,0x7a,0x5c, 0x7,0x64,0x3a, + 0x7,0x65,0x2b, 0x4,0x6e,0x30, 0x7,0x64,0x3b, 0x5,0x7b,0x33, + 0x4,0x6e,0x2f, 0x5,0x7b,0x5b, 0x5,0x7b,0x5c, 0x7,0x65,0x2c, + 0x4,0x6e,0x4a, 0x5,0x7b,0x76, 0x7,0x65,0x6e, 0x5,0x7c,0x4a, + 0x7,0x66,0x52, 0x7,0x45,0x75, 0x4,0x66,0x22, 0x5,0x72,0x7c, + 0x4,0x68,0x57, 0x5,0x77,0x49, 0x6,0x64,0x79, 0x7,0x2c,0x38, + 0x7,0x2c,0x37, 0x5,0x61,0x24, 0x7,0x36,0x6d, 0x4,0x5a,0x61, + 0x7,0x3e,0x69, 0x7,0x3e,0x6a, 0x7,0x45,0x78, 0x5,0x67,0x42, + 0x7,0x45,0x79, 0x7,0x45,0x77, 0x7,0x45,0x76, 0x4,0x5f,0x41, + 0x7,0x4d,0x24, 0x7,0x4d,0x25, 0x7,0x3e,0x6b, 0x7,0x4d,0x23, + 0x7,0x52,0x5e, 0x7,0x52,0x5f, 0x7,0x52,0x5d, 0x5,0x72,0x7d, + 0x7,0x57,0x3b, 0x4,0x6a,0x36, 0x7,0x5b,0x2c, 0x7,0x5b,0x31, + 0x7,0x5b,0x32, 0x7,0x5b,0x2e, 0x7,0x5b,0x30, 0x7,0x5b,0x2d, + 0x7,0x5b,0x2b, 0x7,0x5b,0x2f, 0x5,0x77,0x4a, 0x7,0x5e,0x42, + 0x5,0x78,0x78, 0x5,0x79,0x7b, 0x5,0x7a,0x5d, 0x4,0x6d,0x47, + 0x7,0x63,0x41, 0x5,0x7b,0x34, 0x7,0x63,0x42, 0x7,0x65,0x2d, + 0x6,0x50,0x4f, 0x7,0x36,0x6e, 0x7,0x36,0x6f, 0x5,0x5a,0x6b, + 0x7,0x46,0x4f, 0x7,0x65,0x2e, 0x5,0x5a,0x6c, 0x5,0x61,0x25, + 0x7,0x3e,0x6d, 0x5,0x67,0x43, 0x7,0x45,0x7a, 0x5,0x67,0x44, + 0xf,0x61,0x7d, 0x7,0x4d,0x27, 0x5,0x6b,0x60, 0x7,0x4d,0x26, + 0x5,0x6b,0x5e, 0x5,0x6b,0x5f, 0x4,0x63,0x25, 0x4,0x66,0x23, + 0x7,0x52,0x60, 0x4,0x6a,0x39, 0x4,0x68,0x58, 0x7,0x57,0x3c, + 0x7,0x57,0x3d, 0x5,0x75,0x53, 0x7,0x5b,0x34, 0x7,0x5b,0x35, + 0x5,0x75,0x55, 0x4,0x6a,0x38, 0x7,0x5b,0x33, 0x5,0x75,0x54, + 0x7,0x5e,0x43, 0x7,0x60,0x5e, 0x5,0x78,0x79, 0x7,0x60,0x5f, + 0x5,0x79,0x7c, 0x7,0x63,0x43, 0x5,0x7b,0x35, 0x5,0x7b,0x77, + 0x7,0x2c,0x39, 0x5,0x5a,0x6d, 0x7,0x3e,0x6e, 0x5,0x5a,0x6e, + 0x5,0x61,0x28, 0x5,0x61,0x2a, 0x5,0x61,0x2b, 0x5,0x61,0x29, + 0x5,0x61,0x27, 0x7,0x3e,0x70, 0x5,0x61,0x26, 0x7,0x3e,0x6f, + 0x5,0x61,0x2c, 0x4,0x5a,0x62, 0x7,0x45,0x7c, 0x7,0x4d,0x2c, + 0x5,0x67,0x47, 0x5,0x67,0x48, 0x5,0x67,0x46, 0x5,0x67,0x45, + 0x7,0x45,0x7b, 0x7,0x4d,0x2a, 0x5,0x6b,0x61, 0x5,0x6b,0x63, + 0x5,0x6b,0x62, 0x7,0x4d,0x2d, 0x7,0x4d,0x2e, 0x7,0x4d,0x29, + 0x7,0x52,0x62, 0x7,0x52,0x64, 0x7,0x52,0x63, 0x5,0x6f,0x5d, + 0x5,0x6f,0x5e, 0x7,0x4d,0x2b, 0x7,0x52,0x65, 0x5,0x6f,0x5c, + 0x7,0x52,0x61, 0x5,0x73,0x21, 0x5,0x72,0x7e, 0x7,0x57,0x3e, + 0x5,0x75,0x57, 0x7,0x5b,0x36, 0x5,0x75,0x58, 0x5,0x75,0x59, + 0x5,0x75,0x56, 0x4,0x6a,0x3a, 0x7,0x5e,0x44, 0x5,0x77,0x4b, + 0x4,0x6b,0x59, 0x7,0x5e,0x48, 0x4,0x6b,0x57, 0x4,0x6b,0x5a, + 0x7,0x5e,0x47, 0x7,0x5e,0x46, 0x7,0x5e,0x45, 0x5,0x78,0x7d, + 0x4,0x6c,0x63, 0x5,0x78,0x7b, 0x5,0x78,0x7a, 0x7,0x60,0x60, + 0x7,0x61,0x7e, 0x7,0x61,0x7d, 0x4,0x6d,0x49, 0x5,0x79,0x7d, + 0x5,0x7b,0x36, 0x5,0x7b,0x79, 0x5,0x7b,0x78, 0x7,0x65,0x6f, + 0x7,0x66,0x22, 0x4,0x4f,0x57, 0x7,0x36,0x70, 0x7,0x36,0x71, + 0x7,0x3e,0x72, 0x7,0x3e,0x71, 0x5,0x67,0x49, 0x7,0x45,0x7e, + 0x7,0x46,0x21, 0x7,0x45,0x7d, 0x5,0x6b,0x64, 0x5,0x6b,0x65, + 0x7,0x52,0x66, 0x5,0x6f,0x5f, 0x5,0x6f,0x60, 0x7,0x52,0x68, + 0x4,0x68,0x5b, 0x5,0x73,0x22, 0x7,0x57,0x3f, 0x7,0x57,0x40, + 0x5,0x73,0x23, 0x5,0x73,0x24, 0x7,0x5b,0x37, 0x5,0x77,0x4c, + 0x7,0x5e,0x49, 0x5,0x78,0x7c, 0xf,0x6b,0x7e, 0x7,0x60,0x61, + 0x5,0x79,0x7e, 0x5,0x7a,0x21, 0x7,0x63,0x46, 0x5,0x7a,0x5e, + 0x7,0x63,0x45, 0x7,0x64,0x3c, 0x4,0x6e,0x53, 0x5,0x7c,0x32, + 0xf,0x40,0x34, 0x4,0x55,0x64, 0x4,0x5a,0x65, 0x7,0x46,0x22, + 0x4,0x63,0x28, 0x7,0x4d,0x2f, 0x5,0x6d,0x57, 0x4,0x66,0x24, + 0x4,0x6a,0x3b, 0xf,0x69,0x37, 0x5,0x7a,0x23, 0x5,0x7a,0x22, + 0x7,0x62,0x21, 0x7,0x65,0x2f, 0x5,0x61,0x2e, 0x7,0x3e,0x73, + 0x7,0x46,0x25, 0x4,0x5f,0x47, 0x7,0x46,0x24, 0x7,0x4d,0x30, + 0x5,0x6b,0x66, 0x4,0x63,0x2a, 0x7,0x4d,0x31, 0x7,0x4d,0x34, + 0x7,0x4d,0x32, 0x7,0x4d,0x33, 0x7,0x4d,0x35, 0x7,0x4d,0x36, + 0x5,0x6b,0x67, 0x7,0x52,0x6b, 0x5,0x6f,0x63, 0x5,0x6f,0x62, + 0x4,0x66,0x28, 0x7,0x52,0x69, 0x4,0x66,0x2a, 0x7,0x52,0x6d, + 0x4,0x66,0x29, 0x7,0x52,0x6e, 0x7,0x52,0x6a, 0x4,0x48,0x78, + 0x7,0x52,0x6c, 0x7,0x57,0x46, 0x5,0x73,0x2a, 0x5,0x73,0x27, + 0x7,0x57,0x43, 0x7,0x57,0x42, 0x4,0x68,0x5e, 0x5,0x73,0x28, + 0x4,0x68,0x5f, 0x4,0x68,0x5d, 0x7,0x57,0x44, 0x5,0x73,0x25, + 0x5,0x73,0x2b, 0x7,0x57,0x45, 0x7,0x57,0x47, 0x5,0x73,0x29, + 0x7,0x57,0x41, 0x5,0x73,0x26, 0x7,0x5b,0x38, 0x4,0x6a,0x3e, + 0x5,0x75,0x5c, 0x5,0x75,0x5b, 0x5,0x75,0x5e, 0x7,0x5b,0x40, + 0x7,0x5b,0x3f, 0x5,0x75,0x5f, 0x7,0x5b,0x3a, 0x5,0x75,0x60, + 0x4,0x6a,0x3f, 0x7,0x5b,0x39, 0x5,0x75,0x5a, 0x7,0x5b,0x3b, + 0x7,0x5b,0x3d, 0x7,0x5b,0x3e, 0x7,0x5b,0x3c, 0x5,0x75,0x5d, + 0x5,0x77,0x4f, 0x5,0x77,0x4e, 0x4,0x6b,0x5e, 0x4,0x6b,0x62, + 0x4,0x6b,0x63, 0x4,0x6b,0x5f, 0x4,0x6b,0x60, 0x5,0x77,0x50, + 0x7,0x5e,0x4e, 0x7,0x5e,0x4c, 0x4,0x6b,0x5d, 0x7,0x5e,0x4a, + 0x7,0x5e,0x4b, 0x7,0x5e,0x4f, 0x4,0x6b,0x64, 0x4,0x6c,0x67, + 0x5,0x78,0x7e, 0x7,0x60,0x67, 0x4,0x6c,0x68, 0x7,0x60,0x65, + 0x5,0x79,0x21, 0x7,0x62,0x23, 0x4,0x6c,0x65, 0x7,0x60,0x63, + 0x7,0x60,0x66, 0x7,0x60,0x64, 0x7,0x60,0x62, 0x7,0x60,0x68, + 0x5,0x79,0x22, 0x4,0x6d,0x4e, 0x4,0x6d,0x4a, 0x7,0x62,0x25, + 0x5,0x7a,0x26, 0x4,0x6d,0x50, 0x4,0x6d,0x4d, 0x5,0x7a,0x24, + 0x7,0x62,0x27, 0x4,0x6d,0x4f, 0x7,0x62,0x24, 0x7,0x62,0x26, + 0x7,0x62,0x28, 0x7,0x62,0x29, 0x7,0x62,0x22, 0x5,0x7a,0x25, + 0x7,0x63,0x48, 0x5,0x7a,0x60, 0x7,0x63,0x47, 0x5,0x7a,0x62, + 0x5,0x7a,0x5f, 0x5,0x7a,0x61, 0x7,0x64,0x3e, 0x4,0x6e,0x32, + 0x7,0x64,0x3d, 0x5,0x7b,0x37, 0x5,0x7b,0x39, 0x5,0x7b,0x38, + 0x7,0x64,0x40, 0x7,0x64,0x41, 0x7,0x64,0x3f, 0x4,0x6e,0x46, + 0x7,0x65,0x32, 0x5,0x7b,0x5d, 0x7,0x65,0x31, 0x7,0x65,0x30, + 0x7,0x65,0x59, 0x7,0x65,0x71, 0x7,0x65,0x72, 0x5,0x7c,0x2a, + 0x7,0x65,0x70, 0x7,0x65,0x73, 0x5,0x7c,0x33, 0x7,0x66,0x24, + 0x7,0x66,0x23, 0x5,0x7c,0x3b, 0x7,0x66,0x32, 0x5,0x7c,0x3a, + 0x7,0x66,0x31, 0x7,0x66,0x3d, 0x7,0x66,0x3c, 0x5,0x7c,0x45, + 0x7,0x66,0x41, 0x7,0x66,0x48, 0x5,0x7c,0x4e, 0x5,0x7c,0x4d, + 0x5,0x6b,0x68, 0x7,0x4d,0x37, 0x4,0x63,0x2c, 0x7,0x52,0x70, + 0x7,0x52,0x6f, 0x7,0x4e,0x24, 0x5,0x6f,0x64, 0x7,0x57,0x48, + 0xf,0x67,0x3d, 0x7,0x5b,0x42, 0x7,0x5b,0x41, 0x7,0x5b,0x43, + 0x7,0x5b,0x44, 0x5,0x77,0x51, 0x5,0x7c,0x51, 0x7,0x36,0x72, + 0x7,0x3e,0x74, 0x7,0x46,0x26, 0x7,0x57,0x49, 0x5,0x6f,0x65, + 0x4,0x66,0x2b, 0x5,0x6f,0x67, 0x5,0x6f,0x66, 0x4,0x66,0x2c, + 0x7,0x52,0x73, 0x7,0x52,0x71, 0xf,0x67,0x3e, 0x7,0x52,0x72, + 0x5,0x73,0x2c, 0x5,0x73,0x2e, 0x7,0x57,0x4b, 0x5,0x73,0x2f, + 0x5,0x6b,0x6a, 0x5,0x73,0x2d, 0x7,0x54,0x2a, 0x7,0x57,0x4a, + 0x7,0x4d,0x39, 0x7,0x4d,0x38, 0x5,0x7b,0x5e, 0x7,0x61,0x29, + 0x5,0x7b,0x3a, 0x5,0x77,0x52, 0x7,0x64,0x42, 0xf,0x6d,0x2d, + 0x5,0x7c,0x42, 0xf,0x29,0x26, 0x5,0x73,0x30, 0x7,0x62,0x2b, + 0x7,0x62,0x2a, 0x5,0x7a,0x64, 0x5,0x7a,0x63, 0x7,0x63,0x4a, + 0x7,0x63,0x49, 0x5,0x7b,0x3b, 0x4,0x6e,0x47, 0x7,0x66,0x25, + 0x4,0x6e,0x56, 0x7,0x66,0x4c, 0x6,0x29,0x36, 0x6,0x21,0x31, + 0x6,0x21,0x21, 0x6,0x25,0x66, 0x6,0x25,0x72, 0x4,0x25,0x3d, + 0x6,0x2e,0x61, 0xf,0x2d,0x68, 0x6,0x3d,0x35, 0x6,0x50,0x5b, + 0x4,0x3c,0x30, 0x6,0x5a,0x72, 0xf,0x59,0x4d, 0x6,0x23,0x52, + 0x3,0x24,0x52, 0x3,0x27,0x53, 0xf,0x67,0x40, 0x3,0x27,0x54, + 0x6,0x3d,0x3c, 0x7,0x4d,0x3e, 0x6,0x21,0x50, 0x3,0x22,0x7b, + 0x6,0x23,0x59, 0x3,0x21,0x4f, 0x6,0x35,0x44, 0x4,0x21,0x3f, + 0x6,0x22,0x3c, 0x3,0x24,0x41, 0x7,0x36,0x7a, 0x5,0x21,0x29, + 0x6,0x21,0x38, 0xf,0x23,0x37, 0x6,0x29,0x63, 0x6,0x2e,0x76, + 0x6,0x46,0x67, 0x3,0x40,0x43, 0xf,0x22,0x29, 0x6,0x2f,0x25, + 0x6,0x35,0x58, 0x4,0x36,0x4c, 0x4,0x21,0x2f, 0x6,0x22,0x46, + 0x3,0x22,0x25, 0x6,0x22,0x49, 0x3,0x23,0x29, 0x6,0x2f,0x38, + 0x6,0x46,0x74, 0x6,0x2a,0x23, 0x6,0x2f,0x3d, 0x6,0x3d,0x59, + 0x6,0x3d,0x5a, 0x3,0x3a,0x26, 0xf,0x21,0x33, 0x3,0x24,0x29, + 0x6,0x21,0x61, 0x6,0x26,0x43, 0x5,0x31,0x31, 0x6,0x22,0x5b, + 0x5,0x21,0x60, 0x3,0x23,0x3c, 0x4,0x23,0x5c, 0x6,0x26,0x4e, + 0x4,0x23,0x5b, 0x6,0x2a,0x3c, 0x3,0x30,0x23, 0x6,0x35,0x7e, + 0x4,0x30,0x76, 0x6,0x3d,0x7c, 0x6,0x47,0x2a, 0x6,0x47,0x2c, + 0x6,0x47,0x30, 0x6,0x47,0x31, 0x6,0x47,0x33, 0x4,0x3c,0x50, + 0x6,0x5b,0x5b, 0x6,0x51,0x36, 0x6,0x5b,0x59, 0x7,0x21,0x60, + 0x7,0x2c,0x65, 0x3,0x21,0x7c, 0x6,0x24,0x33, 0x6,0x36,0x35, + 0x6,0x3e,0x2c, 0x6,0x3e,0x2b, 0x3,0x34,0x70, 0x4,0x36,0x76, + 0x6,0x51,0x4a, 0x7,0x21,0x76, 0x7,0x46,0x3e, 0xf,0x23,0x5b, + 0x6,0x51,0x57, 0x5,0x23,0x62, 0x6,0x24,0x3b, 0x6,0x51,0x5e, + 0x6,0x47,0x56, 0x6,0x22,0x67, 0xf,0x2a,0x2b, 0x6,0x36,0x4c, + 0x6,0x36,0x4d, 0xf,0x2e,0x6d, 0x6,0x3e,0x54, 0x6,0x3e,0x50, + 0x6,0x47,0x61, 0x6,0x51,0x69, 0xf,0x47,0x46, 0x3,0x5a,0x33, + 0x7,0x46,0x51, 0x6,0x24,0x48, 0x4,0x31,0x30, 0xf,0x41,0x2b, + 0x6,0x5c,0x22, 0x3,0x5a,0x36, 0x7,0x60,0x6d, 0x6,0x27,0x21, + 0x6,0x36,0x67, 0x6,0x24,0x4b, 0x4,0x21,0x34, 0x5,0x28,0x73, + 0x6,0x47,0x7b, 0x4,0x21,0x35, 0xf,0x26,0x62, 0x3,0x2c,0x40, + 0x6,0x30,0x4e, 0x6,0x48,0x2b, 0x6,0x48,0x35, 0x3,0x40,0x7e, + 0x6,0x52,0x33, 0x6,0x5c,0x3d, 0x6,0x27,0x36, 0x6,0x5c,0x49, + 0xf,0x21,0x5f, 0x6,0x48,0x37, 0x6,0x37,0x2c, 0x6,0x48,0x3c, + 0x7,0x2d,0x53, 0x7,0x2d,0x55, 0x7,0x60,0x6e, 0x5,0x29,0x27, + 0x6,0x3f,0x46, 0x6,0x3f,0x45, 0x3,0x35,0x5f, 0x6,0x52,0x40, + 0x5,0x45,0x5d, 0x6,0x21,0x74, 0x6,0x27,0x4a, 0x6,0x2b,0x2f, + 0x6,0x30,0x74, 0xf,0x2a,0x5d, 0x6,0x2b,0x39, 0x7,0x2d,0x63, + 0x5,0x73,0x40, 0x3,0x2c,0x51, 0x6,0x3f,0x5e, 0x5,0x2d,0x48, + 0x3,0x35,0x65, 0x6,0x27,0x5f, 0xf,0x24,0x33, 0x5,0x24,0x38, + 0x6,0x31,0x36, 0x6,0x31,0x30, 0xf,0x2a,0x67, 0x4,0x29,0x4a, + 0x6,0x48,0x7c, 0x6,0x48,0x78, 0x3,0x46,0x70, 0x6,0x52,0x6c, + 0x6,0x52,0x66, 0x6,0x5d,0x26, 0x6,0x5d,0x24, 0x4,0x43,0x51, + 0x7,0x2d,0x69, 0x7,0x2d,0x79, 0x7,0x22,0x7b, 0x3,0x54,0x60, + 0x4,0x5b,0x2c, 0x7,0x47,0x28, 0x3,0x26,0x27, 0x6,0x40,0x23, + 0x5,0x22,0x6e, 0x6,0x2b,0x63, 0x6,0x2b,0x60, 0x6,0x31,0x4f, + 0xf,0x2b,0x2b, 0x6,0x37,0x71, 0x3,0x36,0x28, 0x6,0x40,0x36, + 0x6,0x40,0x2b, 0x6,0x49,0x4a, 0x6,0x49,0x30, 0xf,0x41,0x5f, + 0x7,0x23,0x30, 0x6,0x5d,0x38, 0x5,0x46,0x2c, 0x7,0x23,0x2d, + 0xf,0x4f,0x25, 0x4,0x4a,0x27, 0x7,0x38,0x39, 0xf,0x5e,0x70, + 0x4,0x2d,0x46, 0x6,0x49,0x57, 0xf,0x5a,0x36, 0x3,0x36,0x40, + 0x6,0x38,0x36, 0xf,0x41,0x72, 0x6,0x53,0x3c, 0x5,0x46,0x41, + 0xf,0x2b,0x38, 0x6,0x31,0x6d, 0x6,0x40,0x57, 0x6,0x49,0x78, + 0x6,0x5d,0x5b, 0x6,0x2c,0x23, 0x5,0x26,0x4a, 0x4,0x32,0x3e, + 0x6,0x40,0x58, 0x5,0x3f,0x66, 0x4,0x24,0x47, 0x6,0x28,0x2e, + 0xf,0x24,0x51, 0x4,0x26,0x68, 0x3,0x2d,0x35, 0x6,0x38,0x4a, + 0x3,0x31,0x5c, 0x4,0x2d,0x5c, 0x6,0x38,0x50, 0x5,0x32,0x7e, + 0x3,0x3c,0x3a, 0x6,0x53,0x5e, 0x5,0x3f,0x71, 0x3,0x41,0x6e, + 0x6,0x5d,0x68, 0x7,0x23,0x72, 0xf,0x54,0x74, 0x7,0x2e,0x6a, + 0x4,0x5f,0x76, 0x7,0x58,0x23, 0x6,0x25,0x23, 0x6,0x4a,0x3f, + 0x7,0x23,0x78, 0x7,0x5e,0x72, 0xf,0x48,0x79, 0x6,0x53,0x77, + 0x4,0x2d,0x65, 0xf,0x35,0x74, 0x6,0x4a,0x4d, 0x6,0x2c,0x42, + 0xf,0x48,0x7b, 0x6,0x25,0x2e, 0xf,0x24,0x5d, 0x6,0x2c,0x5b, + 0x6,0x2c,0x51, 0x3,0x2d,0x52, 0x6,0x32,0x39, 0x6,0x32,0x42, + 0x4,0x2a,0x25, 0x4,0x2d,0x70, 0x6,0x39,0x2d, 0x6,0x38,0x74, + 0x6,0x39,0x21, 0xf,0x30,0x5b, 0x3,0x36,0x75, 0x6,0x4a,0x65, + 0x6,0x4a,0x63, 0x4,0x3e,0x33, 0x6,0x54,0x49, 0x6,0x54,0x4f, + 0xf,0x42,0x74, 0x6,0x5e,0x3e, 0x7,0x24,0x4f, 0x7,0x24,0x58, + 0xf,0x4f,0x69, 0x7,0x2f,0x42, 0xf,0x55,0x56, 0x4,0x56,0x5d, + 0x7,0x4e,0x28, 0x7,0x53,0x60, 0x7,0x53,0x58, 0x6,0x2c,0x60, + 0x6,0x2c,0x5d, 0x6,0x32,0x48, 0x4,0x38,0x68, 0xf,0x43,0x2f, + 0x6,0x54,0x59, 0xf,0x50,0x3d, 0xf,0x55,0x58, 0x5,0x7b,0x7b, + 0x3,0x55,0x45, 0x6,0x41,0x61, 0x6,0x41,0x63, 0x6,0x41,0x6a, + 0x6,0x5e,0x5e, 0x6,0x32,0x62, 0x6,0x4b,0x42, 0x7,0x47,0x75, + 0x6,0x22,0x26, 0xf,0x24,0x78, 0x6,0x2d,0x24, 0xf,0x2c,0x39, + 0xf,0x31,0x28, 0x6,0x4b,0x47, 0xf,0x43,0x64, 0x4,0x44,0x6e, + 0x7,0x40,0x63, 0xf,0x63,0x24, 0x6,0x42,0x21, 0x3,0x3d,0x3f, + 0x6,0x32,0x79, 0x4,0x2a,0x44, 0x5,0x33,0x65, 0x6,0x4b,0x56, + 0x4,0x3e,0x6c, 0x6,0x42,0x32, 0xf,0x4a,0x2f, 0x7,0x53,0x7b, + 0x6,0x2d,0x3a, 0x5,0x33,0x71, 0xf,0x56,0x3c, 0x6,0x2d,0x45, + 0x6,0x2d,0x3d, 0x6,0x33,0x3d, 0x6,0x33,0x31, 0x5,0x2f,0x26, + 0xf,0x2c,0x57, 0x6,0x3a,0x2d, 0x6,0x3a,0x2e, 0x6,0x42,0x48, + 0x6,0x4b,0x7a, 0xf,0x50,0x5f, 0x7,0x30,0x4a, 0x6,0x25,0x3f, + 0x6,0x2d,0x46, 0x3,0x43,0x33, 0x6,0x55,0x6b, 0x7,0x25,0x7b, + 0x7,0x39,0x6d, 0xf,0x28,0x3c, 0x6,0x33,0x4a, 0xf,0x3d,0x60, + 0x4,0x4b,0x60, 0x7,0x26,0x27, 0x6,0x3a,0x43, 0x6,0x42,0x67, + 0x4,0x45,0x5f, 0x4,0x52,0x21, 0x7,0x30,0x66, 0x6,0x5f,0x75, + 0x7,0x26,0x3e, 0x7,0x26,0x3c, 0x7,0x30,0x73, 0xf,0x4a,0x7b, + 0x6,0x60,0x23, 0xf,0x51,0x23, 0x7,0x26,0x4d, 0x7,0x41,0x3c, + 0x5,0x6c,0x7d, 0x7,0x31,0x2d, 0x7,0x3a,0x33, 0x4,0x5c,0x59, + 0x7,0x41,0x44, 0x3,0x2e,0x56, 0x6,0x33,0x66, 0x3,0x48,0x6a, + 0xf,0x51,0x37, 0x7,0x26,0x6a, 0x7,0x26,0x69, 0x4,0x64,0x26, + 0x7,0x62,0x4d, 0x6,0x4c,0x72, 0x7,0x3a,0x46, 0xf,0x3e,0x32, + 0x7,0x3a,0x49, 0x7,0x48,0x6d, 0x7,0x5f,0x3c, 0x6,0x4d,0x23, + 0xf,0x57,0x27, 0x4,0x2b,0x26, 0x7,0x27,0x28, 0xf,0x57,0x28, + 0x6,0x60,0x5d, 0x5,0x48,0x74, 0xf,0x5c,0x2d, 0x6,0x28,0x7b, + 0x4,0x27,0x68, 0x6,0x2d,0x69, 0x3,0x33,0x50, 0x5,0x3b,0x50, + 0x6,0x4d,0x48, 0xf,0x44,0x68, 0xf,0x4b,0x57, 0xf,0x4b,0x56, + 0x4,0x4c,0x56, 0x4,0x58,0x2d, 0x4,0x34,0x57, 0x6,0x4d,0x5e, + 0x3,0x44,0x25, 0x6,0x61,0x25, 0x3,0x27,0x2a, 0x6,0x25,0x52, + 0x6,0x29,0x27, 0xf,0x28,0x5c, 0x6,0x29,0x28, 0x6,0x2e,0x22, + 0x6,0x2e,0x23, 0x6,0x34,0x44, 0x6,0x2e,0x24, 0x6,0x3b,0x52, + 0xf,0x32,0x3a, 0x4,0x34,0x73, 0x6,0x44,0x2b, 0x4,0x34,0x74, + 0x6,0x43,0x76, 0x6,0x44,0x3b, 0x4,0x3a,0x66, 0x6,0x44,0x3e, + 0x6,0x44,0x3c, 0x6,0x44,0x3d, 0x6,0x4e,0x3b, 0x6,0x61,0x3e, + 0x6,0x61,0x4f, 0xf,0x51,0x64, 0x4,0x4c,0x79, 0x7,0x27,0x61, + 0x7,0x27,0x6d, 0x7,0x32,0x44, 0xf,0x57,0x47, 0x7,0x3a,0x6f, + 0xf,0x60,0x5d, 0x7,0x42,0x3c, 0x7,0x54,0x5e, 0x4,0x67,0x2b, + 0x6,0x34,0x47, 0x4,0x40,0x4f, 0x7,0x3b,0x38, 0x3,0x5b,0x26, + 0x6,0x3b,0x71, 0x4,0x3a,0x75, 0x6,0x4e,0x46, 0x4,0x46,0x7c, + 0x4,0x4d,0x33, 0xf,0x52,0x24, 0x7,0x28,0x2e, 0xf,0x51,0x7d, + 0x7,0x42,0x60, 0x7,0x42,0x5f, 0x3,0x5b,0x2d, 0x4,0x64,0x3f, + 0x4,0x53,0x4c, 0x6,0x25,0x53, 0x5,0x30,0x3e, 0x6,0x58,0x2e, + 0x6,0x58,0x2c, 0xf,0x45,0x3d, 0x7,0x3b,0x61, 0xf,0x38,0x4a, + 0x5,0x7a,0x38, 0x6,0x3c,0x2d, 0x4,0x35,0x45, 0xf,0x3f,0x3b, + 0x6,0x62,0x47, 0x7,0x33,0x4f, 0x7,0x59,0x41, 0x6,0x29,0x2a, + 0x6,0x58,0x50, 0x6,0x58,0x5c, 0x3,0x60,0x7c, 0x6,0x3c,0x3b, + 0x7,0x33,0x79, 0x7,0x33,0x73, 0xf,0x3f,0x53, 0x3,0x44,0x6d, + 0x7,0x29,0x44, 0x6,0x34,0x5d, 0x4,0x30,0x2c, 0x7,0x34,0x31, + 0x4,0x54,0x37, 0x7,0x3c,0x61, 0x6,0x25,0x5b, 0x4,0x35,0x72, + 0x6,0x59,0x47, 0x6,0x59,0x4a, 0x7,0x3c,0x6b, 0xf,0x45,0x73, + 0x6,0x63,0x53, 0x6,0x63,0x4f, 0x4,0x54,0x4a, 0xf,0x66,0x5e, + 0x7,0x50,0x6b, 0xf,0x6c,0x3f, 0x6,0x63,0x58, 0x7,0x34,0x7a, + 0x7,0x34,0x71, 0xf,0x61,0x4a, 0x6,0x50,0x22, 0x6,0x63,0x6e, + 0x7,0x35,0x35, 0x3,0x56,0x78, 0x5,0x5f,0x5e, 0x7,0x3d,0x50, + 0xf,0x58,0x78, 0x7,0x4b,0x5f, 0x4,0x65,0x2a, 0x7,0x4b,0x6b, + 0x5,0x3d,0x47, 0x5,0x44,0x35, 0x6,0x5a,0x33, 0x6,0x64,0x30, + 0x4,0x59,0x76, 0x6,0x64,0x3a, 0x6,0x3c,0x77, 0x6,0x5a,0x3d, + 0x4,0x55,0x23, 0x4,0x5e,0x60, 0x6,0x64,0x50, 0x7,0x3e,0x29, + 0x7,0x2b,0x55, 0xf,0x59,0x32, 0x7,0x51,0x7a, 0x7,0x5a,0x60, + 0x4,0x5a,0x59, 0x7,0x45,0x65, 0x4,0x5f,0x37, 0x4,0x62,0x6e, + 0x7,0x52,0x45, 0x5,0x75,0x36, 0x5,0x75,0x35, 0xf,0x6c,0x77, + 0x7,0x3e,0x5c, 0x6,0x46,0x3e, 0x4,0x68,0x4f, 0x6,0x5a,0x60, + 0x4,0x28,0x34, 0x3,0x5c,0x2f, 0x5,0x53,0x51, 0x7,0x4d,0x28, + 0x4,0x48,0x77, 0x7,0x5e,0x4d, +}; + +static const Summary16 cns11643_inv_uni2indx_page00[16] = { + /* 0x0000 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0080 }, { 1, 0x0083 }, + { 4, 0x0000 }, { 4, 0x0080 }, { 5, 0x0000 }, { 5, 0x0080 }, +}; +static const Summary16 cns11643_inv_uni2indx_page02[29] = { + /* 0x0200 */ + { 6, 0x0000 }, { 6, 0x0000 }, { 6, 0x0000 }, { 6, 0x0000 }, + { 6, 0x0000 }, { 6, 0x0000 }, { 6, 0x0000 }, { 6, 0x0000 }, + { 6, 0x0000 }, { 6, 0x0000 }, { 6, 0x0000 }, { 6, 0x0000 }, + { 6, 0x0e80 }, { 10, 0x0200 }, { 11, 0x0000 }, { 11, 0x0000 }, + /* 0x0300 */ + { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, + { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, + { 11, 0x0000 }, { 11, 0xfffe }, { 26, 0x03fb }, { 35, 0xfffe }, + { 50, 0x03fb }, +}; +static const Summary16 cns11643_inv_uni2indx_page20[44] = { + /* 0x2000 */ + { 59, 0x0000 }, { 59, 0x3358 }, { 66, 0x0060 }, { 68, 0x4824 }, + { 72, 0x0000 }, { 72, 0x0000 }, { 72, 0x0000 }, { 72, 0x0000 }, + { 72, 0x0000 }, { 72, 0x0000 }, { 72, 0x1000 }, { 73, 0x0000 }, + { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, + /* 0x2100 */ + { 73, 0x0228 }, { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, + { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x03ff }, { 86, 0x03ff }, + { 96, 0x0000 }, { 96, 0x03cf }, { 104, 0x0000 }, { 104, 0x0000 }, + { 104, 0x0000 }, { 104, 0x0000 }, { 104, 0x0000 }, { 104, 0x0000 }, + /* 0x2200 */ + { 104, 0x0000 }, { 104, 0xc420 }, { 108, 0x4e01 }, { 113, 0x1030 }, + { 116, 0x0000 }, { 116, 0x0004 }, { 117, 0x00c3 }, { 121, 0x0000 }, + { 121, 0x0000 }, { 121, 0x0000 }, { 121, 0x0020 }, { 122, 0x8000 }, +}; +static const Summary16 cns11643_inv_uni2indx_page24[37] = { + /* 0x2400 */ + { 123, 0xffff }, { 139, 0xffff }, { 155, 0x0002 }, { 156, 0x0000 }, + { 156, 0x0000 }, { 156, 0x0000 }, { 156, 0x03ff }, { 166, 0x3ff0 }, + { 176, 0x0000 }, { 176, 0x0000 }, { 176, 0x0000 }, { 176, 0x0000 }, + { 176, 0x0000 }, { 176, 0x0000 }, { 176, 0x0000 }, { 176, 0x0000 }, + /* 0x2500 */ + { 176, 0x1005 }, { 179, 0x1111 }, { 183, 0x1010 }, { 185, 0x1010 }, + { 187, 0x0000 }, { 187, 0x4001 }, { 189, 0xe402 }, { 194, 0x000f }, + { 198, 0xfffe }, { 213, 0x0030 }, { 215, 0x0003 }, { 217, 0x300c }, + { 221, 0xc8c0 }, { 226, 0x0000 }, { 226, 0x003c }, { 230, 0x0000 }, + /* 0x2600 */ + { 230, 0x0260 }, { 233, 0x0000 }, { 233, 0x0000 }, { 233, 0x0000 }, + { 233, 0x0007 }, +}; +static const Summary16 cns11643_inv_uni2indx_page30[1787] = { + /* 0x3000 */ + { 236, 0xff0f }, { 248, 0x6037 }, { 255, 0x03fe }, { 264, 0x0000 }, + { 264, 0x0000 }, { 264, 0x0000 }, { 264, 0x0000 }, { 264, 0x0000 }, + { 264, 0x0000 }, { 264, 0x0000 }, { 264, 0x0000 }, { 264, 0x0000 }, + { 264, 0x0000 }, { 264, 0x0000 }, { 264, 0x0000 }, { 264, 0x0800 }, + /* 0x3100 */ + { 265, 0xffe0 }, { 276, 0xffff }, { 292, 0x03ff }, { 302, 0x0000 }, + { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0000 }, + { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0000 }, + { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0000 }, + /* 0x3200 */ + { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0000 }, + { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0000 }, + { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0008 }, { 303, 0x0000 }, + { 303, 0x0000 }, { 303, 0x0000 }, { 303, 0x0000 }, { 303, 0x0000 }, + /* 0x3300 */ + { 303, 0x0000 }, { 303, 0x0000 }, { 303, 0x0000 }, { 303, 0x0000 }, + { 303, 0x0000 }, { 303, 0x0000 }, { 303, 0x0000 }, { 303, 0x0000 }, + { 303, 0xc000 }, { 305, 0x7000 }, { 308, 0x0002 }, { 309, 0x0000 }, + { 309, 0x4010 }, { 311, 0x0026 }, { 314, 0x0000 }, { 314, 0x0000 }, + /* 0x3400 */ + { 314, 0x1073 }, { 320, 0x1040 }, { 322, 0x7b12 }, { 330, 0x5f5f }, + { 342, 0xfe3e }, { 354, 0xff8b }, { 366, 0xc0f8 }, { 373, 0xfefb }, + { 387, 0x7fff }, { 402, 0xfefe }, { 416, 0xbff3 }, { 429, 0xfffd }, + { 444, 0xdfbc }, { 456, 0xfdfb }, { 470, 0xf39f }, { 482, 0x7ffe }, + /* 0x3500 */ + { 496, 0xfcff }, { 510, 0x77af }, { 522, 0xf7ff }, { 537, 0xffff }, + { 553, 0xffff }, { 569, 0xdff7 }, { 583, 0xfeff }, { 598, 0x1fef }, + { 610, 0x81ff }, { 620, 0x81ff }, { 630, 0x0fff }, { 642, 0xfff0 }, + { 654, 0x3fff }, { 668, 0x1ff9 }, { 679, 0x3ffc }, { 691, 0xf87f }, + /* 0x3600 */ + { 703, 0x3fe7 }, { 715, 0xfe7b }, { 728, 0xbfff }, { 743, 0x8fdf }, + { 755, 0xefbf }, { 769, 0x7e2f }, { 780, 0xffbf }, { 795, 0x5fff }, + { 809, 0xfebf }, { 823, 0xf5fd }, { 836, 0x7fff }, { 851, 0xffff }, + { 867, 0xe63e }, { 877, 0x7fff }, { 892, 0xffe6 }, { 905, 0x7fff }, + /* 0x3700 */ + { 920, 0xfffe }, { 935, 0x7fef }, { 949, 0xdfff }, { 964, 0xffff }, + { 980, 0xf5bf }, { 993, 0xfbff }, { 1008, 0xfefd }, { 1022, 0xfff7 }, + { 1037, 0x9fff }, { 1051, 0x9fff }, { 1065, 0xbffe }, { 1079, 0xfeff }, + { 1094, 0xffbb }, { 1108, 0xffdf }, { 1123, 0xbfe5 }, { 1135, 0xff7f }, + /* 0x3800 */ + { 1150, 0xfff7 }, { 1165, 0x3fff }, { 1179, 0xe7e7 }, { 1191, 0xfff6 }, + { 1205, 0xdfff }, { 1220, 0xffff }, { 1236, 0xefed }, { 1249, 0xffff }, + { 1265, 0xff7f }, { 1280, 0xffff }, { 1296, 0xd7eb }, { 1308, 0x7d7d }, + { 1320, 0xfbff }, { 1335, 0xff1f }, { 1348, 0xb87d }, { 1358, 0xfce7 }, + /* 0x3900 */ + { 1370, 0xfffe }, { 1385, 0xfeff }, { 1400, 0xd7ff }, { 1414, 0xcfff }, + { 1428, 0xffff }, { 1444, 0xfc7f }, { 1457, 0xfbff }, { 1472, 0xf7ff }, + { 1487, 0xfeff }, { 1502, 0xfdff }, { 1517, 0xffff }, { 1533, 0xfff5 }, + { 1547, 0x7fff }, { 1562, 0x47fc }, { 1572, 0xfffe }, { 1587, 0xfffe }, + /* 0x3a00 */ + { 1602, 0xffff }, { 1618, 0xfeff }, { 1633, 0xe7ff }, { 1647, 0xffff }, + { 1663, 0x7ff9 }, { 1676, 0x7ffd }, { 1690, 0xbfff }, { 1705, 0xfeff }, + { 1720, 0xfbb7 }, { 1733, 0xf46e }, { 1743, 0xfb7f }, { 1757, 0xdff3 }, + { 1770, 0xec3f }, { 1781, 0xffbf }, { 1796, 0xdef3 }, { 1808, 0x3fff }, + /* 0x3b00 */ + { 1822, 0xfffe }, { 1837, 0x7fbd }, { 1850, 0xfeef }, { 1864, 0x9b7f }, + { 1876, 0x1f9e }, { 1886, 0xff3e }, { 1899, 0xff07 }, { 1910, 0xff07 }, + { 1921, 0xf9ff }, { 1935, 0xffff }, { 1951, 0xfffa }, { 1965, 0x97ff }, + { 1978, 0xffff }, { 1994, 0xfff9 }, { 2008, 0xfc7f }, { 2021, 0xcfff }, + /* 0x3c00 */ + { 2035, 0xffff }, { 2051, 0xeff7 }, { 2065, 0xffff }, { 2081, 0xfeff }, + { 2096, 0xffff }, { 2112, 0xdff4 }, { 2124, 0xbdff }, { 2138, 0xff7f }, + { 2153, 0xffff }, { 2169, 0xfffe }, { 2184, 0xbdff }, { 2198, 0x7fff }, + { 2213, 0xfdff }, { 2228, 0xffcf }, { 2242, 0x7ff0 }, { 2253, 0xfff8 }, + /* 0x3d00 */ + { 2266, 0xc7ff }, { 2279, 0x7fff }, { 2294, 0xffe3 }, { 2307, 0xf9ff }, + { 2321, 0xfc7f }, { 2334, 0xe3ff }, { 2347, 0xffff }, { 2363, 0xefff }, + { 2378, 0xf1f3 }, { 2389, 0xddfe }, { 2402, 0xfffb }, { 2417, 0xde3d }, + { 2428, 0xefff }, { 2443, 0x8fff }, { 2456, 0xf97f }, { 2469, 0xdbf9 }, + /* 0x3e00 */ + { 2481, 0xff3f }, { 2495, 0xffff }, { 2511, 0xffff }, { 2527, 0x7fef }, + { 2541, 0xfeff }, { 2556, 0xffff }, { 2572, 0xf8ff }, { 2585, 0xfffe }, + { 2600, 0xdfbf }, { 2614, 0xfdff }, { 2629, 0x7ffb }, { 2643, 0xa7bf }, + { 2655, 0x7f9f }, { 2668, 0xe6fe }, { 2680, 0xf98f }, { 2691, 0xffe7 }, + /* 0x3f00 */ + { 2705, 0xfef6 }, { 2718, 0xffff }, { 2734, 0xffff }, { 2750, 0xffff }, + { 2766, 0x7fdf }, { 2780, 0xffef }, { 2795, 0xffff }, { 2811, 0xefb7 }, + { 2824, 0xffff }, { 2840, 0xffff }, { 2856, 0xffff }, { 2872, 0xffc1 }, + { 2883, 0xfffe }, { 2898, 0xffee }, { 2912, 0xfffe }, { 2927, 0xffff }, + /* 0x4000 */ + { 2943, 0xefff }, { 2958, 0xdfff }, { 2973, 0xff9f }, { 2987, 0xffff }, + { 3003, 0xfffe }, { 3018, 0xffbf }, { 3033, 0xfbfd }, { 3047, 0xffff }, + { 3063, 0xf7ff }, { 3078, 0xffff }, { 3094, 0xfeff }, { 3109, 0xffdf }, + { 3124, 0xff87 }, { 3136, 0x7ffe }, { 3150, 0x7eff }, { 3164, 0xefff }, + /* 0x4100 */ + { 3179, 0xfbff }, { 3194, 0xbf3f }, { 3207, 0xfff7 }, { 3222, 0xfdcf }, + { 3235, 0xfdff }, { 3250, 0x7fff }, { 3265, 0xf3ff }, { 3279, 0xffff }, + { 3295, 0xef3f }, { 3308, 0xffff }, { 3324, 0xbfff }, { 3339, 0xffef }, + { 3354, 0xfbef }, { 3368, 0xffff }, { 3384, 0xffff }, { 3400, 0x7fe7 }, + /* 0x4200 */ + { 3413, 0xffff }, { 3429, 0xffff }, { 3445, 0xfcff }, { 3459, 0xffff }, + { 3475, 0xff7f }, { 3490, 0xffff }, { 3506, 0xffef }, { 3521, 0xffff }, + { 3537, 0xefff }, { 3552, 0xffff }, { 3568, 0xfffb }, { 3583, 0xffff }, + { 3599, 0xff1f }, { 3612, 0xdfff }, { 3627, 0xffff }, { 3643, 0xffff }, + /* 0x4300 */ + { 3659, 0xf7ff }, { 3674, 0xffff }, { 3690, 0xffff }, { 3706, 0x003f }, + { 3712, 0xfffc }, { 3726, 0xffff }, { 3742, 0xfffe }, { 3757, 0xffff }, + { 3773, 0xffff }, { 3789, 0xb7ff }, { 3803, 0xefdf }, { 3817, 0xffff }, + { 3833, 0xffff }, { 3849, 0xdfff }, { 3864, 0x9fff }, { 3878, 0xffff }, + /* 0x4400 */ + { 3894, 0xffbf }, { 3909, 0xffff }, { 3925, 0xfbff }, { 3940, 0xffff }, + { 3956, 0xffff }, { 3972, 0xffbf }, { 3987, 0xbdff }, { 4001, 0xbe7f }, + { 4014, 0xff7f }, { 4029, 0xfdfd }, { 4043, 0x3fff }, { 4057, 0x3fff }, + { 4071, 0xfffe }, { 4086, 0xff8f }, { 4099, 0xe4ff }, { 4111, 0xf7ff }, + /* 0x4500 */ + { 4126, 0xffff }, { 4142, 0xffff }, { 4158, 0xffff }, { 4174, 0xffff }, + { 4190, 0xfffb }, { 4205, 0xfffe }, { 4220, 0xfff7 }, { 4235, 0xffbf }, + { 4250, 0xffff }, { 4266, 0xffff }, { 4282, 0xefff }, { 4297, 0xbfff }, + { 4312, 0xffff }, { 4328, 0xffbf }, { 4343, 0xdfff }, { 4358, 0xf7f7 }, + /* 0x4600 */ + { 4372, 0xffff }, { 4388, 0xb7ff }, { 4402, 0xffff }, { 4418, 0xfffb }, + { 4433, 0xc3ff }, { 4445, 0xfff7 }, { 4460, 0xf7ff }, { 4475, 0xf7bf }, + { 4489, 0xffff }, { 4505, 0xffdf }, { 4520, 0xefef }, { 4534, 0xffff }, + { 4550, 0xffff }, { 4566, 0xfff7 }, { 4581, 0xffff }, { 4597, 0xffff }, + /* 0x4700 */ + { 4613, 0xffff }, { 4629, 0xffff }, { 4645, 0xfc07 }, { 4654, 0xfff7 }, + { 4669, 0xffff }, { 4685, 0xf5ff }, { 4699, 0xffff }, { 4715, 0xefff }, + { 4730, 0x0fff }, { 4742, 0xfffe }, { 4757, 0xffff }, { 4773, 0xfffb }, + { 4788, 0xffff }, { 4804, 0xffff }, { 4820, 0xffff }, { 4836, 0xfffb }, + /* 0x4800 */ + { 4851, 0xefff }, { 4866, 0xffbf }, { 4881, 0xffff }, { 4897, 0xfbff }, + { 4912, 0xffff }, { 4928, 0xffff }, { 4944, 0xffff }, { 4960, 0xf7fd }, + { 4974, 0x7ff8 }, { 4986, 0xfe7f }, { 5000, 0xfff7 }, { 5015, 0xfbff }, + { 5030, 0xfdff }, { 5045, 0xfffb }, { 5060, 0xffbf }, { 5075, 0xfff7 }, + /* 0x4900 */ + { 5090, 0xfffe }, { 5105, 0xffff }, { 5121, 0xfdf7 }, { 5135, 0xfffb }, + { 5150, 0xff7f }, { 5165, 0xefff }, { 5180, 0xffff }, { 5196, 0x01ff }, + { 5205, 0xff80 }, { 5214, 0xf7ff }, { 5229, 0xfdff }, { 5244, 0x3e3e }, + { 5254, 0x7efe }, { 5267, 0xffff }, { 5283, 0xd5ff }, { 5296, 0xffff }, + /* 0x4a00 */ + { 5312, 0xffff }, { 5328, 0xfbff }, { 5343, 0xffff }, { 5359, 0xffff }, + { 5375, 0xbfef }, { 5389, 0xffff }, { 5405, 0xffff }, { 5421, 0xffff }, + { 5437, 0xffff }, { 5453, 0x7fff }, { 5468, 0xfbff }, { 5483, 0xffff }, + { 5499, 0xffff }, { 5515, 0xffff }, { 5531, 0xffff }, { 5547, 0xffff }, + /* 0x4b00 */ + { 5563, 0xffff }, { 5579, 0xffff }, { 5595, 0xffff }, { 5611, 0xffff }, + { 5627, 0x7fff }, { 5642, 0xefff }, { 5657, 0xfbff }, { 5672, 0xffff }, + { 5688, 0xffff }, { 5704, 0xffff }, { 5720, 0xffff }, { 5736, 0xffff }, + { 5752, 0xffc7 }, { 5765, 0xffff }, { 5781, 0xfdff }, { 5796, 0xf7ff }, + /* 0x4c00 */ + { 5811, 0xff7f }, { 5826, 0xffff }, { 5842, 0xbfff }, { 5857, 0xffb7 }, + { 5871, 0xffff }, { 5887, 0xffff }, { 5903, 0xfbff }, { 5918, 0xffef }, + { 5933, 0xff7f }, { 5948, 0x1eff }, { 5960, 0xffe0 }, { 5971, 0xffbf }, + { 5986, 0xffff }, { 6002, 0xffff }, { 6018, 0xffff }, { 6034, 0xfdff }, + /* 0x4d00 */ + { 6049, 0xffff }, { 6065, 0xfc07 }, { 6074, 0xfeff }, { 6089, 0xffff }, + { 6105, 0xffff }, { 6121, 0xffff }, { 6137, 0xffff }, { 6153, 0xffff }, + { 6169, 0xffff }, { 6185, 0xffff }, { 6201, 0x9fff }, { 6215, 0x003b }, + { 6220, 0x0000 }, { 6220, 0x0000 }, { 6220, 0x0000 }, { 6220, 0x0000 }, + /* 0x4e00 */ + { 6220, 0xffbf }, { 6235, 0xc3f7 }, { 6246, 0xef5f }, { 6259, 0xbb6f }, + { 6271, 0xebef }, { 6284, 0xf7de }, { 6297, 0x070c }, { 6302, 0xc23a }, + { 6309, 0xfbff }, { 6324, 0xfbfe }, { 6338, 0xf97f }, { 6351, 0x56df }, + { 6362, 0xffff }, { 6378, 0xfff1 }, { 6391, 0xc3ff }, { 6403, 0xffff }, + /* 0x4f00 */ + { 6419, 0xffff }, { 6435, 0x3fff }, { 6449, 0xf304 }, { 6456, 0xffff }, + { 6472, 0xffff }, { 6488, 0xffff }, { 6504, 0xffdf }, { 6519, 0xffff }, + { 6535, 0xffff }, { 6551, 0xffff }, { 6567, 0xc80f }, { 6574, 0xffff }, + { 6590, 0xffff }, { 6606, 0xffff }, { 6622, 0xd2bf }, { 6633, 0xffff }, + /* 0x5000 */ + { 6649, 0xffff }, { 6665, 0xffff }, { 6681, 0xffff }, { 6697, 0x93ff }, + { 6709, 0xffff }, { 6725, 0xffff }, { 6741, 0xffff }, { 6757, 0x3fff }, + { 6771, 0xffff }, { 6787, 0xffff }, { 6803, 0xfc4f }, { 6814, 0xffff }, + { 6830, 0xffff }, { 6846, 0xffff }, { 6862, 0xffff }, { 6878, 0xfffb }, + /* 0x5100 */ + { 6893, 0xffff }, { 6909, 0xffff }, { 6925, 0xffff }, { 6941, 0xffff }, + { 6957, 0xffff }, { 6973, 0xffff }, { 6989, 0x7fff }, { 7004, 0xd3ee }, + { 7015, 0xfffd }, { 7030, 0xe3ff }, { 7043, 0x3f7f }, { 7056, 0xf7ff }, + { 7071, 0xffff }, { 7087, 0xffff }, { 7103, 0x753f }, { 7114, 0x67ff }, + /* 0x5200 */ + { 7127, 0xdfff }, { 7142, 0xf1ff }, { 7155, 0xcfff }, { 7169, 0x7fff }, + { 7184, 0xfffa }, { 7198, 0xfffc }, { 7212, 0xffff }, { 7228, 0xfffd }, + { 7243, 0x7fff }, { 7258, 0xffff }, { 7274, 0xfff9 }, { 7288, 0xfffb }, + { 7303, 0xf7ff }, { 7318, 0xfbff }, { 7333, 0xffff }, { 7349, 0xffff }, + /* 0x5300 */ + { 7365, 0xfffb }, { 7380, 0xffff }, { 7396, 0xbfbf }, { 7410, 0xffff }, + { 7426, 0xffff }, { 7442, 0xffbf }, { 7457, 0xf7fb }, { 7471, 0xffff }, + { 7487, 0xcfdd }, { 7499, 0xffdc }, { 7512, 0xfff3 }, { 7526, 0x6fff }, + { 7540, 0xff3f }, { 7554, 0xfefd }, { 7568, 0xffff }, { 7584, 0xbfff }, + /* 0x5400 */ + { 7599, 0xffff }, { 7615, 0xff6f }, { 7629, 0xffff }, { 7645, 0xffff }, + { 7661, 0xffff }, { 7677, 0xe413 }, { 7684, 0xffff }, { 7700, 0xffff }, + { 7716, 0xffff }, { 7732, 0xd57f }, { 7744, 0xffff }, { 7760, 0xffff }, + { 7776, 0xffff }, { 7792, 0x4441 }, { 7796, 0xffff }, { 7812, 0xffff }, + /* 0x5500 */ + { 7828, 0xffff }, { 7844, 0x0fff }, { 7856, 0xffc3 }, { 7868, 0xffff }, + { 7884, 0xffff }, { 7900, 0xffff }, { 7916, 0x0d7f }, { 7926, 0xfcee }, + { 7938, 0xffff }, { 7954, 0xffff }, { 7970, 0xffff }, { 7986, 0x8c7f }, + { 7996, 0xffff }, { 8012, 0xffff }, { 8028, 0xc7ff }, { 8041, 0xffd7 }, + /* 0x5600 */ + { 8055, 0xffff }, { 8071, 0xfbff }, { 8086, 0xffc5 }, { 8098, 0xffff }, + { 8114, 0xffff }, { 8130, 0xc7ff }, { 8143, 0xffff }, { 8159, 0xefff }, + { 8174, 0xffff }, { 8190, 0xffff }, { 8206, 0xffe1 }, { 8218, 0xffff }, + { 8234, 0xbfff }, { 8249, 0xff9f }, { 8263, 0xfffb }, { 8278, 0xbfcf }, + /* 0x5700 */ + { 8291, 0xffbf }, { 8306, 0xfdff }, { 8321, 0xffbf }, { 8336, 0xf87f }, + { 8348, 0xffff }, { 8364, 0x8bff }, { 8376, 0xfffe }, { 8391, 0xffff }, + { 8407, 0xfd8f }, { 8419, 0xffff }, { 8435, 0x5fff }, { 8449, 0xfff0 }, + { 8461, 0xffff }, { 8477, 0xf8bf }, { 8489, 0xffff }, { 8505, 0xffff }, + /* 0x5800 */ + { 8521, 0xffff }, { 8537, 0xff9d }, { 8550, 0xffff }, { 8566, 0xffff }, + { 8582, 0xffbd }, { 8596, 0xffff }, { 8612, 0xbfff }, { 8627, 0xfffe }, + { 8642, 0xffff }, { 8658, 0xfdff }, { 8673, 0xffff }, { 8689, 0xfcbf }, + { 8702, 0xe7ff }, { 8716, 0xff7f }, { 8731, 0xdbdf }, { 8744, 0xfebf }, + /* 0x5900 */ + { 8758, 0xff7f }, { 8773, 0xbfff }, { 8788, 0xffff }, { 8804, 0xf1ff }, + { 8817, 0xfff9 }, { 8831, 0xffbf }, { 8846, 0xffff }, { 8862, 0xffff }, + { 8878, 0xfe7f }, { 8892, 0xffff }, { 8908, 0xf1ff }, { 8921, 0xffff }, + { 8937, 0xffff }, { 8953, 0xffff }, { 8969, 0xffff }, { 8985, 0xffff }, + /* 0x5a00 */ + { 9001, 0xfe1f }, { 9013, 0xffff }, { 9029, 0xffff }, { 9045, 0xffeb }, + { 9059, 0xffff }, { 9075, 0xffff }, { 9091, 0xffff }, { 9107, 0xffaf }, + { 9121, 0xffff }, { 9137, 0xffff }, { 9153, 0xdfff }, { 9168, 0xffff }, + { 9184, 0xffff }, { 9200, 0xffeb }, { 9214, 0xffff }, { 9230, 0xfff9 }, + /* 0x5b00 */ + { 9244, 0xffff }, { 9260, 0xffff }, { 9276, 0xffff }, { 9292, 0xffbf }, + { 9307, 0xffff }, { 9323, 0xbdff }, { 9337, 0xdfff }, { 9352, 0xffff }, + { 9368, 0xffff }, { 9384, 0xfffd }, { 9399, 0xfbfc }, { 9412, 0xdfff }, + { 9427, 0xfdff }, { 9442, 0xffff }, { 9458, 0xffff }, { 9474, 0xe7ff }, + /* 0x5c00 */ + { 9488, 0xfffb }, { 9503, 0xcfff }, { 9517, 0xbf3f }, { 9530, 0xffeb }, + { 9544, 0xfff3 }, { 9558, 0xffff }, { 9574, 0xffbf }, { 9589, 0x7fbb }, + { 9602, 0xfff3 }, { 9616, 0xf2bf }, { 9628, 0xffff }, { 9644, 0x0fff }, + { 9656, 0xffc3 }, { 9668, 0xffff }, { 9684, 0xff66 }, { 9696, 0xffff }, + /* 0x5d00 */ + { 9712, 0xffc3 }, { 9724, 0xffff }, { 9740, 0xdfff }, { 9755, 0xffff }, + { 9771, 0xffff }, { 9787, 0xcaff }, { 9799, 0xffff }, { 9815, 0xffbf }, + { 9830, 0xffff }, { 9846, 0xffff }, { 9862, 0xffff }, { 9878, 0xffff }, + { 9894, 0xffdf }, { 9909, 0xffff }, { 9925, 0x4bff }, { 9937, 0xefff }, + /* 0x5e00 */ + { 9952, 0x7fdf }, { 9966, 0xeffe }, { 9980, 0xff3f }, { 9994, 0xe7fd }, + { 10007, 0xfdff }, { 10022, 0xffff }, { 10038, 0xffff }, { 10054, 0xffff }, + { 10070, 0xffbf }, { 10085, 0x3fe5 }, { 10096, 0xffff }, { 10112, 0xefff }, + { 10127, 0xffff }, { 10143, 0xffff }, { 10159, 0xffef }, { 10174, 0xffff }, + /* 0x5f00 */ + { 10190, 0xfdff }, { 10205, 0xffbf }, { 10220, 0xfbfe }, { 10234, 0xffff }, + { 10250, 0xffdf }, { 10265, 0x7fff }, { 10280, 0xfeff }, { 10295, 0xf7ff }, + { 10310, 0xffff }, { 10326, 0xffdf }, { 10341, 0xffff }, { 10357, 0xffff }, + { 10373, 0xffbf }, { 10388, 0xffff }, { 10404, 0xffff }, { 10420, 0xffff }, + /* 0x6000 */ + { 10436, 0xff81 }, { 10446, 0xffff }, { 10462, 0xffff }, { 10478, 0x23ff }, + { 10489, 0xffff }, { 10505, 0xffff }, { 10521, 0xffff }, { 10537, 0xd03f }, + { 10546, 0xffff }, { 10562, 0xffff }, { 10578, 0x47ff }, { 10590, 0xffff }, + { 10606, 0xffff }, { 10622, 0xffff }, { 10638, 0x47ff }, { 10650, 0xffff }, + /* 0x6100 */ + { 10666, 0xffff }, { 10682, 0xffff }, { 10698, 0xffaf }, { 10712, 0xffff }, + { 10728, 0xffff }, { 10744, 0xfffd }, { 10759, 0xffff }, { 10775, 0xffff }, + { 10791, 0xffff }, { 10807, 0xffff }, { 10823, 0xffff }, { 10839, 0xffff }, + { 10855, 0xffff }, { 10871, 0xffe9 }, { 10884, 0xffff }, { 10900, 0xffef }, + /* 0x6200 */ + { 10915, 0xf7bf }, { 10929, 0xff7f }, { 10944, 0xffff }, { 10960, 0xffff }, + { 10976, 0xffef }, { 10991, 0xff9f }, { 11005, 0xe1ff }, { 11017, 0xffff }, + { 11033, 0xffff }, { 11049, 0x7fff }, { 11064, 0xfff8 }, { 11077, 0xffff }, + { 11093, 0xffff }, { 11109, 0xffff }, { 11125, 0xfc13 }, { 11134, 0xffff }, + /* 0x6300 */ + { 11150, 0xffff }, { 11166, 0x8aff }, { 11177, 0xff0a }, { 11187, 0xffff }, + { 11203, 0xffff }, { 11219, 0x3fff }, { 11233, 0xfff1 }, { 11246, 0xffff }, + { 11262, 0xffff }, { 11278, 0xffff }, { 11294, 0xffff }, { 11310, 0xe447 }, + { 11318, 0xffff }, { 11334, 0xffff }, { 11350, 0xffff }, { 11366, 0x47ff }, + /* 0x6400 */ + { 11378, 0xffc8 }, { 11389, 0xffff }, { 11405, 0xffff }, { 11421, 0xffff }, + { 11437, 0xfacb }, { 11448, 0xffff }, { 11464, 0xffff }, { 11480, 0xffff }, + { 11496, 0xffef }, { 11511, 0xffff }, { 11527, 0xffff }, { 11543, 0xfa5f }, + { 11555, 0xffff }, { 11571, 0x9fff }, { 11585, 0xffff }, { 11601, 0xffff }, + /* 0x6500 */ + { 11617, 0xffff }, { 11633, 0xfffb }, { 11648, 0xffff }, { 11664, 0xffff }, + { 11680, 0xffff }, { 11696, 0xf7ff }, { 11711, 0xfdff }, { 11726, 0x9fff }, + { 11740, 0x7fbf }, { 11754, 0xfff7 }, { 11769, 0xfdff }, { 11784, 0xffff }, + { 11800, 0xfffe }, { 11815, 0xffdf }, { 11830, 0xffff }, { 11846, 0xfe7f }, + /* 0x6600 */ + { 11860, 0xffff }, { 11876, 0xffff }, { 11892, 0xffff }, { 11908, 0x1fff }, + { 11921, 0xffff }, { 11937, 0xff87 }, { 11949, 0xffff }, { 11965, 0xffff }, + { 11981, 0xfff3 }, { 11995, 0xffff }, { 12011, 0xff7f }, { 12026, 0xffff }, + { 12042, 0xffff }, { 12058, 0xffff }, { 12074, 0xffff }, { 12090, 0xd7ff }, + /* 0x6700 */ + { 12104, 0xffff }, { 12120, 0xffff }, { 12136, 0xfdff }, { 12151, 0xfffe }, + { 12166, 0xfff5 }, { 12180, 0xffff }, { 12196, 0xfc67 }, { 12207, 0xffff }, + { 12223, 0xffff }, { 12239, 0xffff }, { 12255, 0xd05e }, { 12263, 0xffff }, + { 12279, 0xffff }, { 12295, 0xffff }, { 12311, 0xffff }, { 12327, 0xdfff }, + /* 0x6800 */ + { 12342, 0x0073 }, { 12347, 0xffff }, { 12363, 0xffff }, { 12379, 0xffff }, + { 12395, 0xffff }, { 12411, 0x47ff }, { 12423, 0xf800 }, { 12428, 0xffff }, + { 12444, 0xdfff }, { 12459, 0xffff }, { 12475, 0xffff }, { 12491, 0x23ff }, + { 12502, 0xfffa }, { 12516, 0xffff }, { 12532, 0xffff }, { 12548, 0xffff }, + /* 0x6900 */ + { 12564, 0xffff }, { 12580, 0x59ff }, { 12592, 0xdea0 }, { 12600, 0xffff }, + { 12616, 0xffff }, { 12632, 0xffff }, { 12648, 0xffff }, { 12664, 0xbfff }, + { 12679, 0xf46d }, { 12689, 0xffff }, { 12705, 0xffff }, { 12721, 0xffff }, + { 12737, 0xffff }, { 12753, 0x03ff }, { 12763, 0xfffe }, { 12778, 0xffff }, + /* 0x6a00 */ + { 12794, 0xffff }, { 12810, 0xffff }, { 12826, 0x3fff }, { 12840, 0xfffc }, + { 12854, 0xffff }, { 12870, 0xffff }, { 12886, 0xffff }, { 12902, 0xe5c7 }, + { 12912, 0xffff }, { 12928, 0xffff }, { 12944, 0xfdff }, { 12959, 0xffff }, + { 12975, 0xfdff }, { 12990, 0xffff }, { 13006, 0xffef }, { 13021, 0xff7f }, + /* 0x6b00 */ + { 13036, 0xffdf }, { 13051, 0x7fff }, { 13066, 0xffff }, { 13082, 0xffff }, + { 13098, 0xffff }, { 13114, 0xffff }, { 13130, 0xffff }, { 13146, 0xefff }, + { 13161, 0xff7f }, { 13176, 0xfbf3 }, { 13189, 0xffff }, { 13205, 0xfffd }, + { 13220, 0xfffb }, { 13235, 0x7ddf }, { 13248, 0xbfff }, { 13263, 0xffff }, + /* 0x6c00 */ + { 13279, 0xbf7f }, { 13293, 0xff7f }, { 13308, 0xfdfb }, { 13322, 0xdbdf }, + { 13335, 0xfe7f }, { 13349, 0xffff }, { 13365, 0xffef }, { 13380, 0xffff }, + { 13396, 0xffff }, { 13412, 0xffff }, { 13428, 0xfc0f }, { 13438, 0xffff }, + { 13454, 0xffff }, { 13470, 0xffff }, { 13486, 0xffff }, { 13502, 0x823f }, + /* 0x6d00 */ + { 13510, 0xffff }, { 13526, 0xffff }, { 13542, 0xffff }, { 13558, 0xffff }, + { 13574, 0x003f }, { 13580, 0xffc0 }, { 13590, 0xffff }, { 13606, 0xffff }, + { 13622, 0xffff }, { 13638, 0x0fff }, { 13650, 0xfc20 }, { 13657, 0xffff }, + { 13673, 0xffff }, { 13689, 0xffff }, { 13705, 0xffff }, { 13721, 0xffff }, + /* 0x6e00 */ + { 13737, 0x9fff }, { 13751, 0xffa4 }, { 13762, 0xffff }, { 13778, 0xffff }, + { 13794, 0xffff }, { 13810, 0xffff }, { 13826, 0xffff }, { 13842, 0x7fff }, + { 13857, 0xef55 }, { 13868, 0xffff }, { 13884, 0xffff }, { 13900, 0xffff }, + { 13916, 0xffff }, { 13932, 0x3fff }, { 13946, 0xfb48 }, { 13955, 0xffff }, + /* 0x6f00 */ + { 13971, 0xffff }, { 13987, 0xffff }, { 14003, 0xffff }, { 14019, 0xffff }, + { 14035, 0xd77f }, { 14048, 0xffff }, { 14064, 0xffff }, { 14080, 0xffff }, + { 14096, 0xffff }, { 14112, 0xe7ff }, { 14126, 0xffff }, { 14142, 0xffff }, + { 14158, 0xffff }, { 14174, 0xfff9 }, { 14188, 0xffff }, { 14204, 0xfdff }, + /* 0x7000 */ + { 14219, 0xffff }, { 14235, 0xffff }, { 14251, 0xffff }, { 14267, 0xffff }, + { 14283, 0x3fff }, { 14297, 0xfffe }, { 14312, 0xdfff }, { 14327, 0xffff }, + { 14343, 0xfffe }, { 14358, 0x8fff }, { 14371, 0xffff }, { 14387, 0xcfff }, + { 14401, 0xfff1 }, { 14414, 0xffff }, { 14430, 0xc43f }, { 14439, 0xffff }, + /* 0x7100 */ + { 14455, 0xffff }, { 14471, 0xfe8f }, { 14483, 0xffff }, { 14499, 0xafff }, + { 14513, 0xfffe }, { 14528, 0xffdf }, { 14543, 0xffff }, { 14559, 0xfff7 }, + { 14574, 0xffff }, { 14590, 0xffff }, { 14606, 0xffff }, { 14622, 0xffff }, + { 14638, 0xffff }, { 14654, 0xffff }, { 14670, 0xffff }, { 14686, 0xff3f }, + /* 0x7200 */ + { 14700, 0xffff }, { 14716, 0xffff }, { 14732, 0xffff }, { 14748, 0xff75 }, + { 14761, 0xdfff }, { 14776, 0xefff }, { 14791, 0xffff }, { 14807, 0xffdf }, + { 14822, 0xfbff }, { 14837, 0xffff }, { 14853, 0xfffe }, { 14868, 0xfe7f }, + { 14882, 0xfeff }, { 14897, 0xbfff }, { 14912, 0x3fff }, { 14926, 0xfff8 }, + /* 0x7300 */ + { 14939, 0xfff7 }, { 14954, 0x7fff }, { 14969, 0xfffc }, { 14983, 0xfdff }, + { 14998, 0xffff }, { 15014, 0xffff }, { 15030, 0xdfe7 }, { 15043, 0xffff }, + { 15059, 0xffff }, { 15075, 0xf1ff }, { 15088, 0xbfff }, { 15103, 0xfffc }, + { 15117, 0xffff }, { 15133, 0xfffd }, { 15148, 0xffff }, { 15164, 0xfff8 }, + /* 0x7400 */ + { 15177, 0x3fff }, { 15191, 0xfffc }, { 15205, 0xffff }, { 15221, 0xff7f }, + { 15236, 0xffff }, { 15252, 0xffff }, { 15268, 0xffff }, { 15284, 0xff7f }, + { 15299, 0xbfff }, { 15314, 0xffff }, { 15330, 0xffff }, { 15346, 0xffff }, + { 15362, 0xffff }, { 15378, 0xfffb }, { 15393, 0xff7f }, { 15408, 0xeff8 }, + /* 0x7500 */ + { 15420, 0xffdf }, { 15435, 0xfdff }, { 15450, 0xffff }, { 15466, 0xefcf }, + { 15479, 0xffdf }, { 15494, 0xfffb }, { 15509, 0xfdfe }, { 15523, 0xffe7 }, + { 15537, 0xdffb }, { 15551, 0x7f3f }, { 15564, 0x0ffc }, { 15574, 0xffff }, + { 15590, 0xfcff }, { 15604, 0xffbf }, { 15619, 0xf0ff }, { 15631, 0xffff }, + /* 0x7600 */ + { 15647, 0xff8f }, { 15660, 0xfe7f }, { 15674, 0xf3ff }, { 15688, 0x3fff }, + { 15702, 0xdfff }, { 15717, 0x9fff }, { 15731, 0xf7b7 }, { 15744, 0xfbff }, + { 15759, 0xffff }, { 15775, 0xfffd }, { 15790, 0xffff }, { 15806, 0xfff9 }, + { 15820, 0x7fff }, { 15835, 0xfffc }, { 15849, 0xffff }, { 15865, 0xffff }, + /* 0x7700 */ + { 15881, 0xcfff }, { 15895, 0xffff }, { 15911, 0xefff }, { 15926, 0xffff }, + { 15942, 0xffff }, { 15958, 0xfffc }, { 15972, 0xffff }, { 15988, 0xffff }, + { 16004, 0xffbf }, { 16019, 0xfff3 }, { 16033, 0xffff }, { 16049, 0xffff }, + { 16065, 0xf6ff }, { 16079, 0xffff }, { 16095, 0xf7ff }, { 16110, 0x7fff }, + /* 0x7800 */ + { 16125, 0xfffc }, { 16139, 0xeb3f }, { 16151, 0xffff }, { 16167, 0x21ff }, + { 16177, 0xfffc }, { 16191, 0xf11f }, { 16201, 0xffff }, { 16217, 0xff43 }, + { 16228, 0xffff }, { 16244, 0xf7ff }, { 16259, 0xffff }, { 16275, 0xff9f }, + { 16289, 0xffff }, { 16305, 0xfd7f }, { 16319, 0xffff }, { 16335, 0xffdf }, + /* 0x7900 */ + { 16350, 0xfff7 }, { 16365, 0xffbf }, { 16380, 0xffff }, { 16396, 0xf7e7 }, + { 16409, 0xbff7 }, { 16423, 0xffff }, { 16439, 0x7fff }, { 16454, 0xfeff }, + { 16469, 0xffdf }, { 16484, 0xffff }, { 16500, 0xffff }, { 16516, 0xffff }, + { 16532, 0xffff }, { 16548, 0xffff }, { 16564, 0x7fff }, { 16579, 0x9fef }, + /* 0x7a00 */ + { 16592, 0xffff }, { 16608, 0xffff }, { 16624, 0xffe7 }, { 16638, 0xffff }, + { 16654, 0xfff7 }, { 16669, 0x9ff9 }, { 16681, 0xfff7 }, { 16696, 0xff7f }, + { 16711, 0x9fff }, { 16725, 0xcfff }, { 16739, 0xdf9f }, { 16752, 0xffff }, + { 16768, 0xfff7 }, { 16783, 0xbfbf }, { 16797, 0xffff }, { 16813, 0xffff }, + /* 0x7b00 */ + { 16829, 0xff73 }, { 16842, 0xffdf }, { 16857, 0xffff }, { 16873, 0xabff }, + { 16886, 0xffff }, { 16902, 0xc3ff }, { 16914, 0xffff }, { 16930, 0x0bff }, + { 16941, 0xfffe }, { 16956, 0xfbff }, { 16971, 0xf03f }, { 16981, 0xffff }, + { 16997, 0x7fff }, { 17012, 0xfff1 }, { 17025, 0x3fff }, { 17039, 0xffff }, + /* 0x7c00 */ + { 17055, 0xffff }, { 17071, 0xff37 }, { 17084, 0xffff }, { 17100, 0xfffd }, + { 17115, 0xfffd }, { 17130, 0xffff }, { 17146, 0xfffd }, { 17161, 0xffff }, + { 17177, 0x7ffb }, { 17191, 0xfffe }, { 17206, 0xdbff }, { 17220, 0xffff }, + { 17236, 0xffff }, { 17252, 0xfeff }, { 17267, 0xffff }, { 17283, 0xfdff }, + /* 0x7d00 */ + { 17298, 0xffff }, { 17314, 0xffff }, { 17330, 0xff3f }, { 17344, 0xffff }, + { 17360, 0xffff }, { 17376, 0xffff }, { 17392, 0xffff }, { 17408, 0xff7f }, + { 17423, 0xffff }, { 17439, 0xf3ff }, { 17453, 0xffff }, { 17469, 0xffff }, + { 17485, 0xffff }, { 17501, 0xffcf }, { 17515, 0xffff }, { 17531, 0xffff }, + /* 0x7e00 */ + { 17547, 0xff9f }, { 17561, 0xffff }, { 17577, 0xfeff }, { 17592, 0xffff }, + { 17608, 0xf3ff }, { 17622, 0xffff }, { 17638, 0xff7f }, { 17653, 0xffff }, + { 17669, 0xfff7 }, { 17684, 0x7ffe }, { 17698, 0x0000 }, { 17698, 0x0000 }, + { 17698, 0x0000 }, { 17698, 0x0000 }, { 17698, 0x0000 }, { 17698, 0x0000 }, + /* 0x7f00 */ + { 17698, 0x0000 }, { 17698, 0x0000 }, { 17698, 0x0000 }, { 17698, 0xffc0 }, + { 17708, 0xfdfb }, { 17722, 0xfbb7 }, { 17735, 0xffff }, { 17751, 0xffef }, + { 17766, 0xfffd }, { 17781, 0x7fff }, { 17796, 0xfbff }, { 17811, 0xffff }, + { 17827, 0xffff }, { 17843, 0xf8ff }, { 17856, 0xffff }, { 17872, 0xffff }, + /* 0x8000 */ + { 17888, 0xffff }, { 17904, 0xffff }, { 17920, 0xff7b }, { 17934, 0xffff }, + { 17950, 0xc7fb }, { 17962, 0xffef }, { 17977, 0xfdfb }, { 17991, 0xffff }, + { 18007, 0xfff6 }, { 18021, 0xffff }, { 18037, 0xfffe }, { 18052, 0x0fff }, + { 18064, 0xfffc }, { 18078, 0xffff }, { 18094, 0xe07f }, { 18104, 0xffff }, + /* 0x8100 */ + { 18120, 0x07ff }, { 18131, 0xfff0 }, { 18143, 0xffff }, { 18159, 0xfe13 }, + { 18169, 0xffff }, { 18185, 0xf93f }, { 18197, 0xffff }, { 18213, 0xa7ff }, + { 18226, 0xffff }, { 18242, 0xfffd }, { 18257, 0xffcf }, { 18271, 0xffbf }, + { 18286, 0xffff }, { 18302, 0xeff7 }, { 18316, 0xffff }, { 18332, 0xffff }, + /* 0x8200 */ + { 18348, 0xffbf }, { 18363, 0xff7f }, { 18378, 0xbff7 }, { 18392, 0xb7fc }, + { 18404, 0xdfff }, { 18419, 0xdfef }, { 18433, 0xfffe }, { 18448, 0xfbfe }, + { 18462, 0xfefb }, { 18476, 0xff7f }, { 18491, 0xffff }, { 18507, 0xffff }, + { 18523, 0x063f }, { 18531, 0xffff }, { 18547, 0xffff }, { 18563, 0xffff }, + /* 0x8300 */ + { 18579, 0x7fff }, { 18594, 0xffc5 }, { 18606, 0xffff }, { 18622, 0xffff }, + { 18638, 0xffff }, { 18654, 0x01ff }, { 18663, 0x000c }, { 18665, 0xffff }, + { 18681, 0xffff }, { 18697, 0xffff }, { 18713, 0xffff }, { 18729, 0xe281 }, + { 18735, 0xffff }, { 18751, 0xffff }, { 18767, 0xffff }, { 18783, 0xffff }, + /* 0x8400 */ + { 18799, 0xffff }, { 18815, 0xc9ff }, { 18827, 0xfe0a }, { 18836, 0xffff }, + { 18852, 0xffff }, { 18868, 0xffff }, { 18884, 0xffff }, { 18900, 0xffff }, + { 18916, 0xe15f }, { 18926, 0xffff }, { 18942, 0xffff }, { 18958, 0xffff }, + { 18974, 0xffff }, { 18990, 0x4dff }, { 19002, 0xff96 }, { 19014, 0xffff }, + /* 0x8500 */ + { 19030, 0xffff }, { 19046, 0xffff }, { 19062, 0xffff }, { 19078, 0xe93f }, + { 19089, 0xffff }, { 19105, 0xffff }, { 19121, 0xffff }, { 19137, 0xffeb }, + { 19151, 0xffff }, { 19167, 0xffff }, { 19183, 0x9fff }, { 19197, 0xffff }, + { 19213, 0xffff }, { 19229, 0xfff7 }, { 19244, 0xffff }, { 19260, 0xffff }, + /* 0x8600 */ + { 19276, 0xffff }, { 19292, 0xffeb }, { 19306, 0xffff }, { 19322, 0xfffe }, + { 19337, 0x7fef }, { 19351, 0xffff }, { 19367, 0xffff }, { 19383, 0x7fff }, + { 19398, 0xfff0 }, { 19410, 0xffff }, { 19426, 0xe7ff }, { 19440, 0xffff }, + { 19456, 0x9fff }, { 19470, 0xffff }, { 19486, 0x7fff }, { 19501, 0xffe0 }, + /* 0x8700 */ + { 19512, 0xffff }, { 19528, 0xff7f }, { 19543, 0xffff }, { 19559, 0xffff }, + { 19575, 0xf4ff }, { 19588, 0xffff }, { 19604, 0xffff }, { 19620, 0x3fff }, + { 19634, 0xfffe }, { 19649, 0xffff }, { 19665, 0xfe3f }, { 19678, 0xffff }, + { 19694, 0x7fff }, { 19709, 0xfffe }, { 19724, 0xffff }, { 19740, 0xffff }, + /* 0x8800 */ + { 19756, 0xffff }, { 19772, 0xffff }, { 19788, 0xffff }, { 19804, 0xffff }, + { 19820, 0xffff }, { 19836, 0xffef }, { 19851, 0xefcf }, { 19864, 0xffff }, + { 19880, 0xff9f }, { 19894, 0xffff }, { 19910, 0x1fff }, { 19923, 0xfffe }, + { 19938, 0xfe07 }, { 19948, 0xffff }, { 19964, 0xffc3 }, { 19976, 0xffff }, + /* 0x8900 */ + { 19992, 0xffef }, { 20007, 0xcfff }, { 20021, 0xffff }, { 20037, 0xffef }, + { 20052, 0xff5f }, { 20066, 0xffdf }, { 20081, 0xfeff }, { 20096, 0xffff }, + { 20112, 0xfffe }, { 20127, 0xffff }, { 20143, 0xffff }, { 20159, 0xffff }, + { 20175, 0x0001 }, { 20176, 0xbffc }, { 20189, 0x7fff }, { 20204, 0xffff }, + /* 0x8a00 */ + { 20220, 0xfffd }, { 20235, 0xfbff }, { 20250, 0xffff }, { 20266, 0xfff7 }, + { 20281, 0xffff }, { 20297, 0x7fff }, { 20312, 0xffff }, { 20328, 0xffff }, + { 20344, 0xf9ff }, { 20358, 0xffff }, { 20374, 0xbfff }, { 20389, 0xffff }, + { 20405, 0xffff }, { 20421, 0xfbff }, { 20436, 0xffff }, { 20452, 0xffff }, + /* 0x8b00 */ + { 20468, 0xffff }, { 20484, 0xffff }, { 20500, 0xfffd }, { 20515, 0xffff }, + { 20531, 0xffff }, { 20547, 0xf7ff }, { 20562, 0xffff }, { 20578, 0xfffb }, + { 20593, 0x7fff }, { 20608, 0xffff }, { 20624, 0x0000 }, { 20624, 0x0000 }, + { 20624, 0x0000 }, { 20624, 0x0000 }, { 20624, 0x0000 }, { 20624, 0x0000 }, + /* 0x8c00 */ + { 20624, 0x0000 }, { 20624, 0x0000 }, { 20624, 0x0000 }, { 20624, 0xff80 }, + { 20633, 0xffff }, { 20649, 0xffff }, { 20665, 0xbfff }, { 20680, 0xffff }, + { 20696, 0xffff }, { 20712, 0xffff }, { 20728, 0xffff }, { 20744, 0xffff }, + { 20760, 0xbfff }, { 20775, 0xffff }, { 20791, 0xffff }, { 20807, 0xffff }, + /* 0x8d00 */ + { 20823, 0xffff }, { 20839, 0x1fff }, { 20852, 0x0000 }, { 20852, 0x0000 }, + { 20852, 0x0000 }, { 20852, 0x0000 }, { 20852, 0xfbf0 }, { 20863, 0xffdf }, + { 20878, 0xffff }, { 20894, 0xffff }, { 20910, 0xffff }, { 20926, 0xfefd }, + { 20940, 0xffef }, { 20955, 0xbfff }, { 20970, 0xffdf }, { 20985, 0xf41f }, + /* 0x8e00 */ + { 20995, 0xafff }, { 21009, 0xffff }, { 21025, 0x4fff }, { 21038, 0xffff }, + { 21054, 0xffff }, { 21070, 0xfffb }, { 21085, 0xffff }, { 21101, 0x1fff }, + { 21114, 0x7ffe }, { 21128, 0xe7ff }, { 21142, 0xffff }, { 21158, 0xf7df }, + { 21172, 0xfedf }, { 21186, 0xffff }, { 21202, 0xfff3 }, { 21216, 0xffff }, + /* 0x8f00 */ + { 21232, 0xefff }, { 21247, 0xffff }, { 21263, 0xffff }, { 21279, 0xffff }, + { 21295, 0xefff }, { 21310, 0xffff }, { 21326, 0x003f }, { 21332, 0x0000 }, + { 21332, 0x0000 }, { 21332, 0xf800 }, { 21337, 0xf5ff }, { 21351, 0xdbff }, + { 21365, 0xffff }, { 21381, 0x93ff }, { 21393, 0xffff }, { 21409, 0xfff3 }, + /* 0x9000 */ + { 21423, 0xfbff }, { 21438, 0xffff }, { 21454, 0xff3f }, { 21468, 0xfdff }, + { 21483, 0xffff }, { 21499, 0xff3f }, { 21513, 0xffdf }, { 21528, 0xffff }, + { 21544, 0xffff }, { 21560, 0xdfff }, { 21575, 0xefff }, { 21590, 0xf3ff }, + { 21604, 0x7fff }, { 21619, 0xfff4 }, { 21632, 0xff3f }, { 21646, 0xfeff }, + /* 0x9100 */ + { 21661, 0xffff }, { 21677, 0xffff }, { 21693, 0xffff }, { 21709, 0xffff }, + { 21725, 0xfffb }, { 21740, 0x97ff }, { 21753, 0xffbf }, { 21768, 0x1ffd }, + { 21780, 0xffff }, { 21796, 0xff7f }, { 21811, 0xffef }, { 21826, 0xfeff }, + { 21841, 0xfaff }, { 21855, 0xfffb }, { 21870, 0xfffd }, { 21885, 0xe3ff }, + /* 0x9200 */ + { 21898, 0xffff }, { 21914, 0xffff }, { 21930, 0xe8ff }, { 21942, 0xffff }, + { 21958, 0xffff }, { 21974, 0xffff }, { 21990, 0xffff }, { 22006, 0xfffd }, + { 22021, 0xffff }, { 22037, 0xffff }, { 22053, 0xffff }, { 22069, 0xffff }, + { 22085, 0xffff }, { 22101, 0xffff }, { 22117, 0xffff }, { 22133, 0xffff }, + /* 0x9300 */ + { 22149, 0xffff }, { 22165, 0xffff }, { 22181, 0xffff }, { 22197, 0xbfff }, + { 22212, 0xffed }, { 22226, 0xffff }, { 22242, 0xffff }, { 22258, 0xffff }, + { 22274, 0xffff }, { 22290, 0xffff }, { 22306, 0xffff }, { 22322, 0xfbff }, + { 22337, 0xffff }, { 22353, 0xffff }, { 22369, 0xffff }, { 22385, 0xfffe }, + /* 0x9400 */ + { 22400, 0xffff }, { 22416, 0xffff }, { 22432, 0xffbd }, { 22446, 0xffff }, + { 22462, 0xfffd }, { 22477, 0xfff7 }, { 22492, 0xffff }, { 22508, 0xffff }, + { 22524, 0x001f }, { 22529, 0x0000 }, { 22529, 0x0000 }, { 22529, 0x0000 }, + { 22529, 0x0000 }, { 22529, 0x0000 }, { 22529, 0x0000 }, { 22529, 0x0000 }, + /* 0x9500 */ + { 22529, 0x0000 }, { 22529, 0x0000 }, { 22529, 0x0000 }, { 22529, 0x0000 }, + { 22529, 0x0000 }, { 22529, 0x0000 }, { 22529, 0x0000 }, { 22529, 0x7f80 }, + { 22537, 0xfbff }, { 22552, 0xffff }, { 22568, 0xfbff }, { 22583, 0xffff }, + { 22599, 0x7fff }, { 22614, 0xffff }, { 22630, 0x00ff }, { 22638, 0x0020 }, + /* 0x9600 */ + { 22639, 0x0000 }, { 22639, 0x7000 }, { 22642, 0xffff }, { 22658, 0xff9f }, + { 22672, 0xfc1f }, { 22683, 0xffff }, { 22699, 0xfc1f }, { 22710, 0xfbff }, + { 22725, 0xffff }, { 22741, 0xfffe }, { 22756, 0xffff }, { 22772, 0xffff }, + { 22788, 0xffff }, { 22804, 0xffff }, { 22820, 0xfffe }, { 22835, 0xbff7 }, + /* 0x9700 */ + { 22849, 0xfffd }, { 22864, 0xffff }, { 22880, 0xdfff }, { 22895, 0xffff }, + { 22911, 0x2fff }, { 22924, 0xffe7 }, { 22938, 0xffdf }, { 22953, 0xfffd }, + { 22968, 0xffbf }, { 22983, 0xfff8 }, { 22996, 0x7fff }, { 23011, 0xffff }, + { 23027, 0xffff }, { 23043, 0xffff }, { 23059, 0xe03f }, { 23068, 0xffff }, + /* 0x9800 */ + { 23084, 0xffff }, { 23100, 0xffff }, { 23116, 0xefff }, { 23131, 0xffff }, + { 23147, 0xffff }, { 23163, 0xffff }, { 23179, 0xffff }, { 23195, 0x001f }, + { 23200, 0x0000 }, { 23200, 0x0000 }, { 23200, 0xfb00 }, { 23207, 0xffef }, + { 23222, 0x3fdf }, { 23235, 0xb800 }, { 23239, 0xbefe }, { 23252, 0xffff }, + /* 0x9900 */ + { 23268, 0x5fff }, { 23282, 0xffff }, { 23298, 0xffff }, { 23314, 0xffff }, + { 23330, 0xffff }, { 23346, 0xffff }, { 23362, 0x0003 }, { 23364, 0x0000 }, + { 23364, 0x0000 }, { 23364, 0xffc0 }, { 23374, 0xffff }, { 23390, 0xffff }, + { 23406, 0xffdf }, { 23421, 0xffff }, { 23437, 0xffff }, { 23453, 0xfffb }, + /* 0x9a00 */ + { 23468, 0xffff }, { 23484, 0xfff3 }, { 23498, 0xfeff }, { 23513, 0xffff }, + { 23529, 0xffff }, { 23545, 0xffff }, { 23561, 0x0fff }, { 23573, 0x0000 }, + { 23573, 0x0000 }, { 23573, 0x0000 }, { 23573, 0xff00 }, { 23581, 0xffff }, + { 23597, 0xe7df }, { 23610, 0xffff }, { 23626, 0xffff }, { 23642, 0xffff }, + /* 0x9b00 */ + { 23658, 0xffff }, { 23674, 0xfff7 }, { 23689, 0xffff }, { 23705, 0xffbf }, + { 23720, 0xff7f }, { 23735, 0xbfff }, { 23750, 0xffff }, { 23766, 0xfeff }, + { 23781, 0xffff }, { 23797, 0xff7f }, { 23812, 0xffff }, { 23828, 0xffeb }, + { 23842, 0xbfff }, { 23857, 0xfffc }, { 23871, 0xffff }, { 23887, 0xffd9 }, + /* 0x9c00 */ + { 23900, 0xffff }, { 23916, 0xf8ff }, { 23929, 0xffff }, { 23945, 0xfffe }, + { 23960, 0xffff }, { 23976, 0xe3ff }, { 23989, 0xf1ff }, { 24002, 0x0ffe }, + { 24013, 0x0000 }, { 24013, 0x0000 }, { 24013, 0x0000 }, { 24013, 0x0000 }, + { 24013, 0x0000 }, { 24013, 0x0000 }, { 24013, 0xffe0 }, { 24024, 0xfffe }, + /* 0x9d00 */ + { 24039, 0xbfff }, { 24054, 0xffff }, { 24070, 0xe7ff }, { 24084, 0xffff }, + { 24100, 0xfebf }, { 24114, 0xffff }, { 24130, 0xffdf }, { 24145, 0xffff }, + { 24161, 0x1fff }, { 24174, 0xffff }, { 24190, 0xf7ff }, { 24205, 0xffff }, + { 24221, 0xffbf }, { 24236, 0xffff }, { 24252, 0xffff }, { 24268, 0xffff }, + /* 0x9e00 */ + { 24284, 0xffff }, { 24300, 0x7fff }, { 24315, 0x0000 }, { 24315, 0x0000 }, + { 24315, 0x0000 }, { 24315, 0x0000 }, { 24315, 0x0000 }, { 24315, 0xbee0 }, + { 24324, 0xffff }, { 24340, 0xffff }, { 24356, 0xffff }, { 24372, 0xf8ff }, + { 24385, 0xfdff }, { 24400, 0xffff }, { 24416, 0xf9fd }, { 24429, 0xffff }, + /* 0x9f00 */ + { 24445, 0xc7ff }, { 24458, 0xffff }, { 24474, 0xfffd }, { 24489, 0xffff }, + { 24505, 0xffff }, { 24521, 0xfffd }, { 24536, 0xfffb }, { 24551, 0x7fff }, + { 24566, 0xe000 }, { 24569, 0x73ff }, { 24582, 0x003f }, +}; +static const Summary16 cns11643_inv_uni2indx_pagefa[3] = { + /* 0xfa00 */ + { 24588, 0x0000 }, { 24588, 0x0000 }, { 24588, 0x0100 }, +}; +static const Summary16 cns11643_inv_uni2indx_pagefe[31] = { + /* 0xfe00 */ + { 24589, 0x0000 }, { 24589, 0x0000 }, { 24589, 0x0000 }, { 24589, 0xffe7 }, + { 24603, 0x7e1f }, { 24614, 0xfef7 }, { 24628, 0x0f7f }, { 24639, 0x0000 }, + { 24639, 0x0000 }, { 24639, 0x0000 }, { 24639, 0x0000 }, { 24639, 0x0000 }, + { 24639, 0x0000 }, { 24639, 0x0000 }, { 24639, 0x0000 }, { 24639, 0x0000 }, + /* 0xff00 */ + { 24639, 0xff7a }, { 24652, 0xffff }, { 24668, 0xffff }, { 24684, 0x97ff }, + { 24697, 0xfffe }, { 24712, 0x3fff }, { 24726, 0x0000 }, { 24726, 0x0000 }, + { 24726, 0x0000 }, { 24726, 0x0000 }, { 24726, 0x0000 }, { 24726, 0x0000 }, + { 24726, 0x0000 }, { 24726, 0x0000 }, { 24726, 0x0023 }, +}; +static const Summary16 cns11643_inv_uni2indx_page200[2670] = { + /* 0x20000 */ + { 24729, 0x8bbd }, { 24739, 0x0715 }, { 24745, 0x722f }, { 24754, 0x0860 }, + { 24757, 0x39ca }, { 24765, 0x08ec }, { 24771, 0xeaf6 }, { 24782, 0xe0d7 }, + { 24791, 0xb1fc }, { 24801, 0x5fbc }, { 24812, 0xd33d }, { 24822, 0xf6ff }, + { 24836, 0x8a5c }, { 24843, 0xc377 }, { 24853, 0x24f3 }, { 24861, 0x795f }, + /* 0x20100 */ + { 24872, 0xfff4 }, { 24885, 0xeefe }, { 24898, 0x751f }, { 24908, 0x03b7 }, + { 24916, 0x9fb9 }, { 24927, 0xe3fa }, { 24938, 0xfebf }, { 24952, 0x4071 }, + { 24957, 0xd6ff }, { 24970, 0x3004 }, { 24973, 0xb3f8 }, { 24983, 0x1ff5 }, + { 24994, 0x8ffc }, { 25005, 0xff11 }, { 25015, 0x0fff }, { 25027, 0xc096 }, + /* 0x20200 */ + { 25033, 0xfffb }, { 25048, 0xffe3 }, { 25061, 0xf787 }, { 25072, 0xffff }, + { 25088, 0xfff0 }, { 25100, 0x0977 }, { 25108, 0x7ffe }, { 25122, 0xffce }, + { 25135, 0x1dff }, { 25147, 0x4056 }, { 25152, 0x7ffd }, { 25166, 0x4fff }, + { 25179, 0xfffe }, { 25194, 0x287f }, { 25203, 0xffae }, { 25216, 0xffff }, + /* 0x20300 */ + { 25232, 0xfb81 }, { 25241, 0x119f }, { 25249, 0xfe03 }, { 25258, 0xdeff }, + { 25272, 0xff11 }, { 25282, 0xc17f }, { 25292, 0xdf84 }, { 25301, 0x0fff }, + { 25313, 0xfffc }, { 25327, 0x4fff }, { 25340, 0xd08e }, { 25347, 0xffcf }, + { 25361, 0xf59f }, { 25373, 0x04d7 }, { 25380, 0xff9e }, { 25393, 0x0dd1 }, + /* 0x20400 */ + { 25400, 0x7f41 }, { 25409, 0x8de4 }, { 25417, 0xcdfe }, { 25429, 0xfc6f }, + { 25441, 0xf037 }, { 25450, 0xbf8e }, { 25461, 0xefd0 }, { 25471, 0xeecc }, + { 25481, 0x3d7b }, { 25492, 0xcff9 }, { 25504, 0x2f1f }, { 25514, 0xbf7f }, + { 25528, 0xfb5c }, { 25539, 0xb9ac }, { 25548, 0xecb3 }, { 25558, 0x21db }, + /* 0x20500 */ + { 25566, 0xdfdf }, { 25580, 0xbfed }, { 25593, 0x8fa7 }, { 25603, 0x73fa }, + { 25614, 0x6d5e }, { 25624, 0xed5f }, { 25636, 0xf3fd }, { 25649, 0x2eef }, + { 25660, 0xb433 }, { 25668, 0xd6ff }, { 25681, 0x4acf }, { 25690, 0x3fd6 }, + { 25701, 0x7fff }, { 25716, 0x7fbe }, { 25729, 0xf5e6 }, { 25740, 0xfcfe }, + /* 0x20600 */ + { 25753, 0x7ff1 }, { 25765, 0xf9de }, { 25777, 0xfabf }, { 25790, 0xf5ef }, + { 25803, 0xbfc1 }, { 25813, 0xbf8f }, { 25825, 0xef87 }, { 25836, 0xefef }, + { 25850, 0xe9c7 }, { 25860, 0xefc6 }, { 25871, 0xffea }, { 25884, 0xff9f }, + { 25898, 0xe39f }, { 25909, 0x0fff }, { 25921, 0xffe1 }, { 25933, 0xfbf7 }, + /* 0x20700 */ + { 25947, 0x12c4 }, { 25952, 0xbfff }, { 25967, 0x016f }, { 25974, 0xffff }, + { 25990, 0x3f3f }, { 26002, 0xef06 }, { 26011, 0xe7bf }, { 26024, 0xe002 }, + { 26028, 0xffff }, { 26044, 0x311f }, { 26052, 0xfff0 }, { 26064, 0xf88f }, + { 26074, 0xfffe }, { 26089, 0x9fff }, { 26103, 0xffc0 }, { 26113, 0xfc2b }, + /* 0x20800 */ + { 26123, 0xe9ff }, { 26136, 0xf88d }, { 26145, 0xdccf }, { 26156, 0xfbdf }, + { 26170, 0x31de }, { 26179, 0xc3fe }, { 26190, 0xff47 }, { 26202, 0xfb37 }, + { 26214, 0xcff7 }, { 26227, 0x03fc }, { 26235, 0xa1ff }, { 26246, 0x9fdf }, + { 26259, 0xfffb }, { 26274, 0xf7de }, { 26287, 0xcfff }, { 26301, 0xffbb }, + /* 0x20900 */ + { 26315, 0xcfbb }, { 26327, 0xdfbf }, { 26341, 0xfd3f }, { 26354, 0xd77b }, + { 26366, 0xde3f }, { 26378, 0x7e4f }, { 26389, 0xfe6e }, { 26401, 0x6dff }, + { 26414, 0x31ed }, { 26423, 0xff7e }, { 26437, 0x3c7f }, { 26448, 0x70f3 }, + { 26457, 0xc517 }, { 26465, 0xdf9b }, { 26477, 0xff7f }, { 26492, 0x3ffc }, + /* 0x20a00 */ + { 26504, 0xebef }, { 26517, 0xff5d }, { 26530, 0xf0ad }, { 26539, 0x2ff7 }, + { 26551, 0xfc9f }, { 26563, 0xffc6 }, { 26575, 0xffdd }, { 26589, 0xff1f }, + { 26602, 0xffd0 }, { 26613, 0xff7e }, { 26627, 0xec75 }, { 26637, 0xfe29 }, + { 26647, 0x5387 }, { 26655, 0xc6bd }, { 26665, 0x1ff5 }, { 26676, 0x9e1b }, + /* 0x20b00 */ + { 26685, 0xc5f7 }, { 26696, 0xfd8b }, { 26707, 0xffee }, { 26721, 0xbffe }, + { 26735, 0xfebf }, { 26749, 0xffff }, { 26765, 0xffeb }, { 26779, 0xd97f }, + { 26791, 0xeffe }, { 26805, 0x7fff }, { 26820, 0xfdff }, { 26835, 0x0fbf }, + { 26846, 0xff46 }, { 26857, 0x7fff }, { 26872, 0x59fa }, { 26882, 0x0068 }, + /* 0x20c00 */ + { 26885, 0xff30 }, { 26895, 0x7fff }, { 26910, 0xfffe }, { 26925, 0x8165 }, + { 26931, 0x4001 }, { 26933, 0xffff }, { 26949, 0xfbff }, { 26964, 0xfe2f }, + { 26976, 0xdbff }, { 26990, 0x0089 }, { 26993, 0xee00 }, { 26999, 0xffff }, + { 27015, 0x7fff }, { 27030, 0xf800 }, { 27035, 0xcfff }, { 27049, 0x8f93 }, + /* 0x20d00 */ + { 27058, 0x0008 }, { 27059, 0x0000 }, { 27059, 0xffce }, { 27072, 0xffff }, + { 27088, 0x040f }, { 27093, 0xfffe }, { 27108, 0x0427 }, { 27113, 0x02a5 }, + { 27118, 0x0000 }, { 27118, 0x0000 }, { 27118, 0x7f80 }, { 27126, 0xfdbf }, + { 27140, 0xffff }, { 27156, 0xfffe }, { 27171, 0xff80 }, { 27180, 0x79ff }, + /* 0x20e00 */ + { 27193, 0x3011 }, { 27197, 0x2040 }, { 27199, 0x6000 }, { 27201, 0x8fef }, + { 27213, 0xffff }, { 27229, 0xdfff }, { 27244, 0x4fff }, { 27257, 0x8000 }, + { 27258, 0xffff }, { 27274, 0x0008 }, { 27275, 0x0014 }, { 27277, 0x0000 }, + { 27277, 0xf000 }, { 27281, 0xfff3 }, { 27295, 0xffff }, { 27311, 0xc043 }, + /* 0x20f00 */ + { 27316, 0xffff }, { 27332, 0x557f }, { 27343, 0x020c }, { 27346, 0x0000 }, + { 27346, 0x0000 }, { 27346, 0x3000 }, { 27348, 0xfffd }, { 27363, 0xff7f }, + { 27378, 0x1f7f }, { 27390, 0xffc0 }, { 27400, 0x84e3 }, { 27407, 0x0001 }, + { 27408, 0xffe0 }, { 27419, 0xffff }, { 27435, 0x40ff }, { 27444, 0xfc00 }, + /* 0x21000 */ + { 27450, 0xffff }, { 27466, 0x000d }, { 27469, 0x0000 }, { 27469, 0xbe00 }, + { 27475, 0xfbfe }, { 27489, 0x80ef }, { 27497, 0x3b3f }, { 27508, 0x0000 }, + { 27508, 0x8c00 }, { 27511, 0xffff }, { 27527, 0x13ff }, { 27538, 0x7fc0 }, + { 27547, 0x0000 }, { 27547, 0xa000 }, { 27549, 0xffff }, { 27565, 0x0084 }, + /* 0x21100 */ + { 27567, 0x077c }, { 27575, 0x7ffe }, { 27589, 0x0009 }, { 27591, 0x8ffe }, + { 27603, 0x0003 }, { 27605, 0xf790 }, { 27614, 0x600a }, { 27618, 0xff47 }, + { 27630, 0xce68 }, { 27638, 0x180f }, { 27644, 0x238f }, { 27652, 0xdffd }, + { 27666, 0x7fda }, { 27678, 0x09ff }, { 27688, 0x041f }, { 27694, 0xf2ff }, + /* 0x21200 */ + { 27707, 0xfe9d }, { 27719, 0xbff2 }, { 27731, 0x743c }, { 27739, 0xd38a }, + { 27747, 0x3416 }, { 27753, 0xaf04 }, { 27760, 0x10ff }, { 27769, 0x10ee }, + { 27776, 0xffff }, { 27792, 0x5ff8 }, { 27803, 0x11fb }, { 27812, 0x7ff0 }, + { 27823, 0xfff0 }, { 27835, 0x797f }, { 27847, 0xff89 }, { 27858, 0x01ff }, + /* 0x21300 */ + { 27867, 0xffc2 }, { 27878, 0x97ed }, { 27889, 0xfef0 }, { 27900, 0xfbdf }, + { 27914, 0x87ff }, { 27926, 0x003a }, { 27930, 0xfff3 }, { 27944, 0xfcff }, + { 27958, 0x40ff }, { 27967, 0x04e1 }, { 27972, 0xdf80 }, { 27980, 0xfffb }, + { 27995, 0xffaf }, { 28009, 0x00bf }, { 28016, 0xee00 }, { 28022, 0x81ff }, + /* 0x21400 */ + { 28032, 0x47ff }, { 28044, 0xe83b }, { 28053, 0x2f7f }, { 28065, 0x5fff }, + { 28079, 0x8784 }, { 28085, 0xdf16 }, { 28095, 0x395f }, { 28105, 0x07c0 }, + { 28110, 0x7fc4 }, { 28120, 0xfe4d }, { 28131, 0x811b }, { 28137, 0x3fbf }, + { 28150, 0x3600 }, { 28154, 0x0ebf }, { 28164, 0x1ed8 }, { 28172, 0xbf7f }, + /* 0x21500 */ + { 28186, 0x8f96 }, { 28195, 0xefa0 }, { 28204, 0xb1f7 }, { 28215, 0x7ee1 }, + { 28225, 0x7c60 }, { 28232, 0xff6e }, { 28245, 0xdfdf }, { 28259, 0xffde }, + { 28273, 0xad53 }, { 28282, 0xf7be }, { 28295, 0xfe3c }, { 28306, 0xe3dd }, + { 28317, 0x114a }, { 28322, 0xf33c }, { 28332, 0xff6f }, { 28346, 0xff91 }, + /* 0x21600 */ + { 28357, 0xfa77 }, { 28369, 0xa7f5 }, { 28380, 0x0a7d }, { 28388, 0xbffd }, + { 28402, 0xf792 }, { 28412, 0x35e1 }, { 28420, 0xff05 }, { 28430, 0xffc7 }, + { 28443, 0x9fe3 }, { 28454, 0x59c3 }, { 28462, 0x8d39 }, { 28470, 0xff3f }, + { 28484, 0x6ff8 }, { 28495, 0xffed }, { 28509, 0xfe27 }, { 28520, 0x7e9f }, + /* 0x21700 */ + { 28532, 0xffff }, { 28548, 0xbbfe }, { 28561, 0xffeb }, { 28575, 0xe17f }, + { 28586, 0xb4ff }, { 28598, 0xff82 }, { 28608, 0x0fff }, { 28620, 0xffe4 }, + { 28632, 0x5fff }, { 28646, 0xff1b }, { 28658, 0xffdf }, { 28673, 0xffc1 }, + { 28684, 0x47ff }, { 28696, 0xfe72 }, { 28707, 0xffff }, { 28723, 0xe09f }, + /* 0x21800 */ + { 28732, 0x493f }, { 28741, 0xfebf }, { 28755, 0xf8f5 }, { 28766, 0x21ff }, + { 28776, 0xbf2c }, { 28786, 0xbeff }, { 28800, 0xff21 }, { 28810, 0xf2ff }, + { 28823, 0x2ffc }, { 28834, 0x3ffe }, { 28847, 0x7ff8 }, { 28859, 0xc1b6 }, + { 28867, 0xfbef }, { 28881, 0xfc37 }, { 28892, 0xee12 }, { 28900, 0xf5bf }, + /* 0x21900 */ + { 28913, 0xb9c7 }, { 28923, 0x3fe4 }, { 28933, 0xdf7e }, { 28946, 0xd6d7 }, + { 28957, 0xe7ef }, { 28970, 0x79ff }, { 28983, 0xff4e }, { 28995, 0x6ec7 }, + { 29005, 0xdaf8 }, { 29015, 0xe5ae }, { 29025, 0xa23f }, { 29034, 0xf321 }, + { 29042, 0xf9fc }, { 29054, 0xf7c2 }, { 29064, 0xfe0d }, { 29074, 0x0df3 }, + /* 0x21a00 */ + { 29083, 0xe7ff }, { 29097, 0xd01b }, { 29104, 0xfffd }, { 29119, 0xf853 }, + { 29128, 0xc3ff }, { 29140, 0xca3f }, { 29150, 0xf7ff }, { 29165, 0xfc1f }, + { 29176, 0xcf7f }, { 29189, 0x8dd9 }, { 29198, 0x7fbf }, { 29212, 0xf5d0 }, + { 29221, 0x7fff }, { 29236, 0xfdfc }, { 29249, 0xf60d }, { 29258, 0xf88f }, + /* 0x21b00 */ + { 29268, 0xb4f9 }, { 29278, 0xaf5e }, { 29289, 0xd78d }, { 29299, 0xee1b }, + { 29309, 0x7d66 }, { 29319, 0xe66f }, { 29330, 0x8f23 }, { 29338, 0xe238 }, + { 29345, 0xc00f }, { 29351, 0xe221 }, { 29357, 0x00c2 }, { 29360, 0x8813 }, + { 29365, 0xe67c }, { 29375, 0xfb55 }, { 29386, 0xf7ef }, { 29400, 0x1dfc }, + /* 0x21c00 */ + { 29410, 0x7e9c }, { 29420, 0x33f7 }, { 29431, 0xfe7d }, { 29444, 0xf5c1 }, + { 29453, 0xf81f }, { 29463, 0x2fbf }, { 29475, 0x7dff }, { 29489, 0xfe97 }, + { 29501, 0x5fff }, { 29515, 0xfffe }, { 29530, 0xf7cb }, { 29542, 0x4f7f }, + { 29554, 0xa7f4 }, { 29564, 0xc1fb }, { 29574, 0x39c3 }, { 29582, 0xc196 }, + /* 0x21d00 */ + { 29589, 0xf977 }, { 29601, 0xfbee }, { 29614, 0xbbfa }, { 29626, 0x99ef }, + { 29637, 0xcdc3 }, { 29646, 0x7ffa }, { 29659, 0x4fd8 }, { 29668, 0x560b }, + { 29675, 0xfffc }, { 29689, 0xefff }, { 29704, 0xfe15 }, { 29714, 0xfb0b }, + { 29724, 0x92ff }, { 29735, 0xffff }, { 29751, 0xe7ff }, { 29765, 0x81ff }, + /* 0x21e00 */ + { 29775, 0x5704 }, { 29781, 0xdfff }, { 29796, 0x17ff }, { 29808, 0xff60 }, + { 29818, 0xac4f }, { 29827, 0x0014 }, { 29829, 0xffbc }, { 29842, 0x7fed }, + { 29855, 0xfd40 }, { 29863, 0x2614 }, { 29868, 0xf812 }, { 29875, 0xfeff }, + { 29890, 0x28ff }, { 29900, 0xffa2 }, { 29911, 0xf7ff }, { 29926, 0x43f7 }, + /* 0x21f00 */ + { 29936, 0x7c00 }, { 29941, 0x3fff }, { 29955, 0x87e0 }, { 29962, 0xf441 }, + { 29969, 0x77ff }, { 29983, 0xfd39 }, { 29994, 0xf0fb }, { 30005, 0x2521 }, + { 30010, 0x7fe5 }, { 30022, 0xff33 }, { 30034, 0xc2dc }, { 30042, 0x78c7 }, + { 30051, 0x9fc2 }, { 30060, 0xb972 }, { 30069, 0xffaf }, { 30083, 0xeb8f }, + /* 0x22000 */ + { 30094, 0x47ff }, { 30106, 0xb31f }, { 30116, 0x821f }, { 30123, 0x8ad0 }, + { 30129, 0x11ff }, { 30139, 0x9ffd }, { 30152, 0xf7fc }, { 30165, 0xfe3f }, + { 30178, 0xadcf }, { 30189, 0xe5ff }, { 30202, 0xde6f }, { 30214, 0xfff6 }, + { 30228, 0xf85f }, { 30239, 0xffff }, { 30255, 0xfd9b }, { 30267, 0x6fff }, + /* 0x22100 */ + { 30281, 0xfdf2 }, { 30293, 0xddf9 }, { 30305, 0x08ff }, { 30314, 0xf7ff }, + { 30329, 0xee04 }, { 30336, 0xceff }, { 30349, 0xef4f }, { 30361, 0xfb67 }, + { 30373, 0xefb8 }, { 30384, 0x9e0f }, { 30393, 0xd014 }, { 30398, 0xfbfe }, + { 30412, 0xfcc3 }, { 30422, 0x7fd7 }, { 30435, 0xaff9 }, { 30447, 0xfffd }, + /* 0x22200 */ + { 30462, 0xffb7 }, { 30476, 0xfe87 }, { 30487, 0x313f }, { 30496, 0xfffc }, + { 30510, 0xfd7f }, { 30524, 0xff61 }, { 30535, 0xffff }, { 30551, 0x9057 }, + { 30558, 0x5eff }, { 30571, 0xfbfd }, { 30585, 0xf57f }, { 30598, 0x1fff }, + { 30611, 0xf0fe }, { 30622, 0x35ff }, { 30634, 0xacfe }, { 30645, 0xf9e7 }, + /* 0x22300 */ + { 30657, 0xabdd }, { 30668, 0x7bfe }, { 30681, 0xbfed }, { 30694, 0xfd7a }, + { 30706, 0xe47e }, { 30716, 0xfff5 }, { 30730, 0xd9dd }, { 30741, 0xcfcf }, + { 30753, 0x74db }, { 30763, 0xb70f }, { 30773, 0x2ffd }, { 30785, 0xdfc7 }, + { 30797, 0x03e3 }, { 30804, 0x07fc }, { 30813, 0xdfd0 }, { 30823, 0x7fff }, + /* 0x22400 */ + { 30838, 0xbdff }, { 30852, 0xe37c }, { 30862, 0xb3ff }, { 30875, 0xdfbd }, + { 30888, 0x3fdf }, { 30901, 0x5fff }, { 30915, 0xaf5e }, { 30926, 0xe3ef }, + { 30938, 0x979f }, { 30949, 0xfff3 }, { 30963, 0xfff7 }, { 30978, 0xebfd }, + { 30991, 0x8ffd }, { 31003, 0xf1fd }, { 31015, 0xfe2d }, { 31026, 0x77ff }, + /* 0x22500 */ + { 31040, 0xffdf }, { 31055, 0xf503 }, { 31063, 0x2fff }, { 31076, 0xf9fb }, + { 31089, 0xe189 }, { 31096, 0xffff }, { 31112, 0xfc9f }, { 31124, 0x5edb }, + { 31135, 0xe71e }, { 31145, 0xff8f }, { 31158, 0x3efd }, { 31170, 0x2ffd }, + { 31182, 0x7f8a }, { 31192, 0xf9bf }, { 31205, 0x5fff }, { 31219, 0x8e26 }, + /* 0x22600 */ + { 31226, 0xffff }, { 31242, 0x647f }, { 31252, 0x8dc9 }, { 31260, 0xfdff }, + { 31275, 0x7fff }, { 31290, 0xffc0 }, { 31300, 0x414f }, { 31307, 0xffff }, + { 31323, 0xffff }, { 31339, 0xfe83 }, { 31349, 0x807f }, { 31357, 0x0c01 }, + { 31360, 0xfffe }, { 31375, 0xffff }, { 31391, 0x7fff }, { 31406, 0xff81 }, + /* 0x22700 */ + { 31416, 0xffff }, { 31432, 0x8ccf }, { 31441, 0xffb8 }, { 31453, 0xffff }, + { 31469, 0xffff }, { 31485, 0xe0bf }, { 31495, 0x67ff }, { 31508, 0x2004 }, + { 31510, 0xf682 }, { 31518, 0xf7ff }, { 31533, 0xffff }, { 31549, 0xffcf }, + { 31563, 0x0c1f }, { 31570, 0x3000 }, { 31572, 0xdfdf }, { 31586, 0xffff }, + /* 0x22800 */ + { 31602, 0xfc01 }, { 31609, 0xd7ff }, { 31623, 0x5003 }, { 31627, 0xfffe }, + { 31642, 0xcfff }, { 31656, 0x43ff }, { 31667, 0xfff6 }, { 31681, 0xe118 }, + { 31687, 0xb000 }, { 31690, 0xfffe }, { 31705, 0x40ff }, { 31714, 0x00ff }, + { 31722, 0xfe02 }, { 31730, 0xff7f }, { 31745, 0xff07 }, { 31756, 0xf8c5 }, + /* 0x22900 */ + { 31765, 0xdfff }, { 31780, 0x03ef }, { 31789, 0xfff0 }, { 31801, 0x7c7f }, + { 31813, 0xfc1a }, { 31822, 0xfd9f }, { 31835, 0xfbf2 }, { 31847, 0xff07 }, + { 31858, 0xcbe2 }, { 31867, 0xfe79 }, { 31879, 0xdfdf }, { 31893, 0x8fc0 }, + { 31900, 0x7fcf }, { 31913, 0x997e }, { 31923, 0x1ff5 }, { 31934, 0xe7f8 }, + /* 0x22a00 */ + { 31945, 0x7ff0 }, { 31956, 0xce3f }, { 31967, 0xb67b }, { 31978, 0x7f94 }, + { 31988, 0x69f2 }, { 31997, 0x236e }, { 32005, 0x7b65 }, { 32015, 0x007f }, + { 32022, 0xfffc }, { 32036, 0xf0ff }, { 32048, 0x029f }, { 32055, 0xfdf0 }, + { 32066, 0x7fc5 }, { 32077, 0x0010 }, { 32078, 0xfff4 }, { 32091, 0xffff }, + /* 0x22b00 */ + { 32107, 0xffc9 }, { 32119, 0x4fff }, { 32132, 0x9c04 }, { 32137, 0xffff }, + { 32153, 0x7fff }, { 32168, 0xfffc }, { 32182, 0x055f }, { 32190, 0x0000 }, + { 32190, 0xffde }, { 32204, 0xf7ff }, { 32219, 0xc19f }, { 32228, 0xffff }, + { 32244, 0x115f }, { 32252, 0x0000 }, { 32252, 0xfe08 }, { 32260, 0xffff }, + /* 0x22c00 */ + { 32276, 0xffff }, { 32292, 0x1fff }, { 32305, 0xff00 }, { 32313, 0x7fff }, + { 32328, 0x20ad }, { 32334, 0x8000 }, { 32335, 0xdfff }, { 32350, 0xdfdf }, + { 32364, 0xffff }, { 32380, 0x0167 }, { 32386, 0x0002 }, { 32387, 0x7ff9 }, + { 32400, 0xebff }, { 32414, 0x077f }, { 32424, 0xfffe }, { 32439, 0x5fff }, + /* 0x22d00 */ + { 32453, 0x0003 }, { 32455, 0x0000 }, { 32455, 0x7fff }, { 32470, 0xffff }, + { 32486, 0xe51b }, { 32495, 0xffff }, { 32511, 0x0009 }, { 32513, 0x8000 }, + { 32514, 0xffff }, { 32530, 0x3fff }, { 32544, 0xffc0 }, { 32554, 0x0023 }, + { 32557, 0xfb80 }, { 32565, 0x3fff }, { 32579, 0x2ff0 }, { 32588, 0xffc0 }, + /* 0x22e00 */ + { 32598, 0xc3ff }, { 32610, 0x037f }, { 32619, 0xfff8 }, { 32632, 0xff9f }, + { 32646, 0xa817 }, { 32653, 0x87fb }, { 32664, 0xf007 }, { 32671, 0x0ebf }, + { 32681, 0x9ffc }, { 32693, 0xc763 }, { 32702, 0x77e7 }, { 32714, 0x47f7 }, + { 32725, 0xe51e }, { 32734, 0x6cf3 }, { 32744, 0xf6e3 }, { 32755, 0x6ede }, + /* 0x22f00 */ + { 32766, 0xffe0 }, { 32777, 0xf133 }, { 32786, 0xf5af }, { 32798, 0xac40 }, + { 32803, 0x8fff }, { 32816, 0xe9bf }, { 32828, 0xf7f3 }, { 32841, 0x84fd }, + { 32850, 0xbbfd }, { 32863, 0xfe1d }, { 32874, 0xffb9 }, { 32887, 0x77fa }, + { 32899, 0x6fc0 }, { 32907, 0xcbff }, { 32920, 0x7f3b }, { 32932, 0xe3fc }, + /* 0x23000 */ + { 32943, 0xde47 }, { 32953, 0x6577 }, { 32963, 0xfdff }, { 32978, 0x34fa }, + { 32987, 0xddce }, { 32998, 0xf7a7 }, { 33010, 0x5abf }, { 33021, 0xbdfa }, + { 33033, 0x9677 }, { 33043, 0xca3a }, { 33051, 0xedff }, { 33065, 0xbf66 }, + { 33076, 0xbd4f }, { 33087, 0xfb5b }, { 33099, 0xffc6 }, { 33111, 0xfba8 }, + /* 0x23100 */ + { 33121, 0xdf17 }, { 33132, 0xe793 }, { 33142, 0x4dd7 }, { 33152, 0xdbf7 }, + { 33165, 0x5fd7 }, { 33177, 0xfc4f }, { 33188, 0xffff }, { 33204, 0x7f9e }, + { 33216, 0x0e7a }, { 33224, 0x7ffc }, { 33237, 0x0bc9 }, { 33244, 0xfffc }, + { 33258, 0xf841 }, { 33265, 0x043f }, { 33272, 0xdffc }, { 33285, 0xfc4f }, + /* 0x23200 */ + { 33296, 0xa19f }, { 33305, 0x8000 }, { 33306, 0x47f3 }, { 33316, 0x7fe0 }, + { 33326, 0x051f }, { 33333, 0x1ffe }, { 33345, 0x3ff8 }, { 33356, 0xfc01 }, + { 33363, 0x805e }, { 33369, 0xee73 }, { 33380, 0xc1fb }, { 33390, 0x255f }, + { 33399, 0xbf30 }, { 33408, 0xc1f9 }, { 33417, 0xfc28 }, { 33425, 0x85fc }, + /* 0x23300 */ + { 33434, 0xe1b8 }, { 33442, 0x93c8 }, { 33449, 0xbffc }, { 33462, 0x798f }, + { 33472, 0x91d8 }, { 33479, 0xfb5e }, { 33491, 0x58ff }, { 33502, 0x17f8 }, + { 33511, 0x3e36 }, { 33520, 0x9f9d }, { 33531, 0x723b }, { 33540, 0xbf7e }, + { 33553, 0x0fef }, { 33564, 0xfff7 }, { 33579, 0xffa3 }, { 33591, 0x6b4f }, + /* 0x23400 */ + { 33601, 0xff8b }, { 33613, 0xff8f }, { 33626, 0x07ff }, { 33637, 0xffe1 }, + { 33649, 0x801f }, { 33655, 0xfffe }, { 33670, 0xed3f }, { 33682, 0xe306 }, + { 33689, 0x83ff }, { 33700, 0xffff }, { 33716, 0xbfff }, { 33731, 0x9fc0 }, + { 33739, 0xffff }, { 33755, 0xffff }, { 33771, 0xff83 }, { 33782, 0xffff }, + /* 0x23500 */ + { 33798, 0xffff }, { 33814, 0x007e }, { 33820, 0xf800 }, { 33825, 0xfffe }, + { 33840, 0x7fff }, { 33855, 0xfa0f }, { 33865, 0xffff }, { 33881, 0x9fff }, + { 33895, 0x048f }, { 33901, 0x0029 }, { 33904, 0xff78 }, { 33916, 0xfff7 }, + { 33931, 0x000e }, { 33934, 0xfff1 }, { 33947, 0xffff }, { 33963, 0x0db9 }, + /* 0x23600 */ + { 33971, 0xe8a1 }, { 33978, 0xfff7 }, { 33993, 0xffff }, { 34009, 0x880f }, + { 34015, 0xfffe }, { 34030, 0x0a7f }, { 34039, 0x0010 }, { 34040, 0xf87f }, + { 34052, 0xffff }, { 34068, 0xfff7 }, { 34083, 0x877f }, { 34094, 0xffff }, + { 34110, 0xffff }, { 34126, 0x8543 }, { 34132, 0x5800 }, { 34135, 0xbfff }, + /* 0x23700 */ + { 34150, 0xe1ff }, { 34162, 0xffff }, { 34178, 0x91f8 }, { 34186, 0x9600 }, + { 34190, 0xfffe }, { 34205, 0x7fff }, { 34220, 0xffa0 }, { 34230, 0x5aff }, + { 34242, 0x1ac2 }, { 34248, 0xffff }, { 34264, 0xfff8 }, { 34277, 0x98e5 }, + { 34285, 0xfff4 }, { 34298, 0xff07 }, { 34309, 0x910f }, { 34316, 0x7f7d }, + /* 0x23800 */ + { 34329, 0xdffe }, { 34343, 0xfe11 }, { 34352, 0x7fe3 }, { 34364, 0xffa0 }, + { 34374, 0xf679 }, { 34385, 0x591f }, { 34394, 0x6fad }, { 34405, 0x1dde }, + { 34415, 0xfeff }, { 34430, 0xff9f }, { 34444, 0xf7cf }, { 34457, 0xac3f }, + { 34467, 0xff7f }, { 34482, 0xe3ef }, { 34494, 0x9bff }, { 34507, 0xffff }, + /* 0x23900 */ + { 34523, 0xffbf }, { 34538, 0x77b7 }, { 34550, 0x723f }, { 34560, 0xdef6 }, + { 34572, 0xffbf }, { 34587, 0x3bff }, { 34600, 0x2fed }, { 34611, 0xff3c }, + { 34623, 0x0fbe }, { 34633, 0xf7f0 }, { 34644, 0x81f6 }, { 34652, 0xbfe6 }, + { 34664, 0xfeff }, { 34679, 0xe07f }, { 34689, 0xffff }, { 34705, 0xfbff }, + /* 0x23a00 */ + { 34720, 0xffeb }, { 34734, 0xffc7 }, { 34747, 0x837f }, { 34757, 0x2bfe }, + { 34768, 0xfbf8 }, { 34780, 0xe3ff }, { 34793, 0xbf3f }, { 34806, 0xdcdf }, + { 34818, 0xf96d }, { 34829, 0x9aff }, { 34841, 0xf6fb }, { 34854, 0xfbef }, + { 34868, 0x30e3 }, { 34875, 0xc74f }, { 34885, 0xbbfe }, { 34898, 0xf711 }, + /* 0x23b00 */ + { 34907, 0xff7f }, { 34922, 0xdcff }, { 34935, 0xfffe }, { 34950, 0xff2f }, + { 34963, 0xfeb7 }, { 34976, 0xf43f }, { 34987, 0x7fef }, { 35001, 0xfffe }, + { 35016, 0xff07 }, { 35027, 0xffbf }, { 35042, 0xff98 }, { 35053, 0x3e1f }, + { 35063, 0xffe4 }, { 35075, 0xbbee }, { 35087, 0xfff4 }, { 35100, 0xff87 }, + /* 0x23c00 */ + { 35112, 0x7e47 }, { 35122, 0xdc5f }, { 35133, 0x7d1f }, { 35144, 0xdbc6 }, + { 35154, 0xdfb1 }, { 35165, 0xdf7f }, { 35179, 0xcc7b }, { 35189, 0x03f4 }, + { 35196, 0xcbdf }, { 35208, 0xe03f }, { 35217, 0xffa3 }, { 35229, 0xfffd }, + { 35244, 0xfc37 }, { 35255, 0x2fff }, { 35268, 0xfff8 }, { 35281, 0x00ff }, + /* 0x23d00 */ + { 35289, 0xfffe }, { 35304, 0xe077 }, { 35313, 0xffff }, { 35329, 0x5fff }, + { 35343, 0xfffc }, { 35357, 0x7fff }, { 35372, 0x1354 }, { 35378, 0xff8a }, + { 35389, 0xffff }, { 35405, 0xff7f }, { 35420, 0x007e }, { 35426, 0xc020 }, + { 35429, 0xffff }, { 35445, 0xafff }, { 35459, 0x02d6 }, { 35465, 0xf860 }, + /* 0x23e00 */ + { 35472, 0xffff }, { 35488, 0xffff }, { 35504, 0x0003 }, { 35506, 0xfffc }, + { 35520, 0x76df }, { 35532, 0xec00 }, { 35537, 0xffff }, { 35553, 0xfffe }, + { 35568, 0xf003 }, { 35574, 0xffff }, { 35590, 0x97ff }, { 35603, 0x8057 }, + { 35609, 0xb400 }, { 35613, 0xffff }, { 35629, 0xffff }, { 35645, 0x8007 }, + /* 0x23f00 */ + { 35649, 0xffff }, { 35665, 0xafff }, { 35679, 0x000f }, { 35683, 0x8820 }, + { 35686, 0xdff8 }, { 35698, 0xffff }, { 35714, 0xffff }, { 35730, 0x2079 }, + { 35736, 0xfff0 }, { 35748, 0xffff }, { 35764, 0x7f0f }, { 35775, 0x0081 }, + { 35777, 0xffe2 }, { 35789, 0xffff }, { 35805, 0x001f }, { 35810, 0xfffe }, + /* 0x24000 */ + { 35825, 0x49f3 }, { 35834, 0x8002 }, { 35836, 0xffff }, { 35852, 0xc2ff }, + { 35863, 0x37ff }, { 35876, 0xf481 }, { 35883, 0xfffe }, { 35898, 0xffff }, + { 35914, 0xc4ff }, { 35925, 0xffff }, { 35941, 0x806e }, { 35947, 0xefff }, + { 35962, 0xfc17 }, { 35972, 0x07bf }, { 35982, 0xbe08 }, { 35989, 0x7bf7 }, + /* 0x24100 */ + { 36002, 0xc2e0 }, { 36008, 0xfffb }, { 36023, 0x1f5f }, { 36034, 0x2ff8 }, + { 36044, 0x7cee }, { 36055, 0x2f06 }, { 36062, 0x6f5f }, { 36074, 0xfb9f }, + { 36087, 0xef7d }, { 36100, 0xe5f7 }, { 36112, 0xbfc0 }, { 36121, 0xf017 }, + { 36129, 0xff83 }, { 36140, 0xafff }, { 36154, 0x8807 }, { 36159, 0xe0ff }, + /* 0x24200 */ + { 36170, 0xffff }, { 36186, 0x0967 }, { 36193, 0xffec }, { 36206, 0xfe07 }, + { 36216, 0x07ff }, { 36227, 0xa202 }, { 36231, 0xfefe }, { 36245, 0xfe00 }, + { 36252, 0xffff }, { 36268, 0x1bff }, { 36280, 0x8020 }, { 36282, 0xfff4 }, + { 36295, 0xf8df }, { 36307, 0xffff }, { 36323, 0x97ff }, { 36336, 0x040b }, + /* 0x24300 */ + { 36340, 0xff8a }, { 36351, 0xf87f }, { 36363, 0xffff }, { 36379, 0x3f7f }, + { 36392, 0xe100 }, { 36396, 0x3ff9 }, { 36408, 0xffc4 }, { 36419, 0xdfff }, + { 36434, 0x1034 }, { 36438, 0xe5c0 }, { 36445, 0xffff }, { 36461, 0xc1bf }, + { 36471, 0xffff }, { 36487, 0xefbf }, { 36501, 0xe201 }, { 36506, 0xfff1 }, + /* 0x24400 */ + { 36519, 0xfff1 }, { 36532, 0xc0a7 }, { 36539, 0xbfc4 }, { 36549, 0xff8f }, + { 36562, 0xcc6f }, { 36572, 0xf0dd }, { 36582, 0x0185 }, { 36586, 0xf7ff }, + { 36601, 0xff47 }, { 36613, 0x5089 }, { 36618, 0x58de }, { 36627, 0x7de8 }, + { 36637, 0x873f }, { 36647, 0xf6f5 }, { 36659, 0xfde3 }, { 36671, 0x79de }, + /* 0x24500 */ + { 36682, 0xd4ff }, { 36694, 0x11bf }, { 36703, 0x57fd }, { 36715, 0x033f }, + { 36723, 0xeb2d }, { 36733, 0xffeb }, { 36747, 0xefff }, { 36762, 0x7eff }, + { 36776, 0xffee }, { 36790, 0x7ffb }, { 36804, 0xfffd }, { 36819, 0x7c9f }, + { 36830, 0xffb7 }, { 36844, 0x1f82 }, { 36851, 0xffef }, { 36866, 0xbdfa }, + /* 0x24600 */ + { 36878, 0xf339 }, { 36888, 0xfff3 }, { 36902, 0xf8ff }, { 36915, 0xff1d }, + { 36927, 0xb61d }, { 36936, 0xf9bf }, { 36949, 0x2dd7 }, { 36959, 0x0fbf }, + { 36970, 0xff1c }, { 36981, 0x437f }, { 36991, 0xff01 }, { 37000, 0xff7f }, + { 37015, 0xff04 }, { 37024, 0x8823 }, { 37029, 0x8afe }, { 37039, 0xee5f }, + /* 0x24700 */ + { 37051, 0xbbbd }, { 37063, 0x3ed7 }, { 37074, 0x895e }, { 37082, 0xffff }, + { 37098, 0xb04f }, { 37106, 0xdfff }, { 37121, 0xd17b }, { 37131, 0xffff }, + { 37147, 0x8177 }, { 37155, 0xfe80 }, { 37163, 0xb02f }, { 37171, 0xc305 }, + { 37177, 0xfffb }, { 37192, 0xf6b7 }, { 37204, 0x3fff }, { 37218, 0x2d7c }, + /* 0x24800 */ + { 37227, 0xe480 }, { 37232, 0xf7ff }, { 37247, 0x1bf3 }, { 37257, 0xfe20 }, + { 37265, 0x60ff }, { 37275, 0xf383 }, { 37284, 0x7fff }, { 37299, 0xbe7f }, + { 37312, 0xfe28 }, { 37321, 0x77ff }, { 37335, 0x87cf }, { 37345, 0x0fff }, + { 37357, 0x6f2b }, { 37367, 0xbb8f }, { 37378, 0xcfdd }, { 37390, 0x1fb5 }, + /* 0x24900 */ + { 37400, 0xf97c }, { 37411, 0xfd0f }, { 37422, 0x9d3f }, { 37433, 0x1fe6 }, + { 37443, 0xfff8 }, { 37456, 0x1ff0 }, { 37465, 0x3ff0 }, { 37475, 0xfbf2 }, + { 37487, 0x002b }, { 37491, 0xffff }, { 37507, 0xf977 }, { 37519, 0xf01f }, + { 37528, 0xffff }, { 37544, 0xc2df }, { 37554, 0xfcfd }, { 37567, 0xfc05 }, + /* 0x24a00 */ + { 37575, 0xbfff }, { 37590, 0x3ff9 }, { 37602, 0xf800 }, { 37607, 0x7f3f }, + { 37620, 0x0bff }, { 37631, 0xfffc }, { 37645, 0xfff8 }, { 37658, 0xf837 }, + { 37668, 0xf8ff }, { 37681, 0xff81 }, { 37691, 0x7f7d }, { 37704, 0xf7f0 }, + { 37715, 0x377f }, { 37727, 0x9df1 }, { 37737, 0xff78 }, { 37749, 0x7dff }, + /* 0x24b00 */ + { 37763, 0xfb9e }, { 37775, 0x3fc7 }, { 37786, 0xf75f }, { 37799, 0xdef1 }, + { 37810, 0xf07f }, { 37821, 0xf9bf }, { 37834, 0x17ef }, { 37845, 0xfe19 }, + { 37855, 0xefe1 }, { 37866, 0x3f59 }, { 37876, 0xefc6 }, { 37887, 0x3f2f }, + { 37898, 0x7b8b }, { 37908, 0xeff9 }, { 37921, 0xdcdf }, { 37933, 0x729c }, + /* 0x24c00 */ + { 37941, 0x65f9 }, { 37951, 0xeaa3 }, { 37960, 0xff3f }, { 37974, 0xff7f }, + { 37989, 0xf801 }, { 37995, 0xc7e5 }, { 38005, 0xfff8 }, { 38018, 0x704b }, + { 38025, 0xe9f8 }, { 38035, 0x3fff }, { 38049, 0xf88b }, { 38058, 0xefe7 }, + { 38071, 0xbf21 }, { 38080, 0x8dfc }, { 38090, 0xfe13 }, { 38100, 0xde4c }, + /* 0x24d00 */ + { 38109, 0x59bf }, { 38120, 0xf3ef }, { 38133, 0xcff3 }, { 38145, 0xff9f }, + { 38159, 0x398f }, { 38168, 0xff92 }, { 38179, 0x2fff }, { 38192, 0xff80 }, + { 38201, 0x1e7f }, { 38212, 0xfff8 }, { 38225, 0x3f3f }, { 38237, 0x00c0 }, + { 38239, 0xffff }, { 38255, 0x7ffb }, { 38269, 0x0021 }, { 38271, 0xfb80 }, + /* 0x24e00 */ + { 38279, 0xffff }, { 38295, 0xe3fe }, { 38307, 0xfe15 }, { 38317, 0xffff }, + { 38333, 0xa27c }, { 38341, 0xf800 }, { 38346, 0x9fff }, { 38360, 0x0a5b }, + { 38367, 0xfff3 }, { 38381, 0x3fff }, { 38395, 0x03c2 }, { 38400, 0xff80 }, + { 38409, 0x23ff }, { 38420, 0x7fe0 }, { 38430, 0xc12e }, { 38437, 0x07fe }, + /* 0x24f00 */ + { 38447, 0x38ff }, { 38458, 0xb7c7 }, { 38469, 0xbfbf }, { 38483, 0x7687 }, + { 38492, 0x77ce }, { 38503, 0xef57 }, { 38515, 0x97f3 }, { 38526, 0xbe81 }, + { 38534, 0xff08 }, { 38543, 0x7b20 }, { 38550, 0x3dff }, { 38563, 0x795c }, + { 38572, 0xcfe9 }, { 38583, 0xbfe7 }, { 38596, 0x5fa7 }, { 38607, 0x86fc }, + /* 0x25000 */ + { 38616, 0xefde }, { 38629, 0xdff3 }, { 38642, 0xb97e }, { 38653, 0xb677 }, + { 38664, 0xdbff }, { 38678, 0xdf7f }, { 38692, 0xfffb }, { 38707, 0x9fdb }, + { 38719, 0xf5f9 }, { 38731, 0xdffb }, { 38745, 0x73f3 }, { 38756, 0xd7ee }, + { 38768, 0x6fbf }, { 38781, 0x13fc }, { 38790, 0x1ff2 }, { 38800, 0x3ffc }, + /* 0x25100 */ + { 38812, 0xfffd }, { 38827, 0x7bff }, { 38841, 0x02b8 }, { 38846, 0xfffe }, + { 38861, 0x7e13 }, { 38870, 0xff88 }, { 38880, 0x7fef }, { 38894, 0x324f }, + { 38902, 0xfbe0 }, { 38912, 0xffff }, { 38928, 0x1c7f }, { 38938, 0x0069 }, + { 38942, 0xfef8 }, { 38954, 0xff7f }, { 38969, 0x4f13 }, { 38977, 0xc030 }, + /* 0x25200 */ + { 38981, 0xffed }, { 38995, 0x1fff }, { 39008, 0x07fc }, { 39017, 0xf980 }, + { 39024, 0xffff }, { 39040, 0xffff }, { 39056, 0x007c }, { 39061, 0xfff1 }, + { 39074, 0x47f7 }, { 39085, 0x0021 }, { 39087, 0xfd80 }, { 39095, 0xffff }, + { 39111, 0x271f }, { 39120, 0xfe01 }, { 39128, 0xbf3f }, { 39141, 0x8801 }, + /* 0x25300 */ + { 39144, 0xffff }, { 39160, 0xfcf1 }, { 39171, 0xe70e }, { 39180, 0xfc67 }, + { 39191, 0x9e5f }, { 39202, 0xc6b8 }, { 39210, 0xffbf }, { 39225, 0xffef }, + { 39240, 0xfefd }, { 39254, 0x17fd }, { 39265, 0x1ff2 }, { 39275, 0xff7f }, + { 39290, 0xc207 }, { 39296, 0xf792 }, { 39306, 0x9c07 }, { 39313, 0x78ff }, + /* 0x25400 */ + { 39325, 0x001b }, { 39329, 0x7fea }, { 39341, 0x1e3f }, { 39351, 0x35fe }, + { 39362, 0xfff3 }, { 39376, 0x7f9f }, { 39389, 0xd20c }, { 39395, 0xff7d }, + { 39409, 0xbfd7 }, { 39422, 0x5054 }, { 39427, 0xff90 }, { 39437, 0x3e7f }, + { 39449, 0xfcc3 }, { 39459, 0xfcff }, { 39473, 0x20ff }, { 39482, 0xfc02 }, + /* 0x25500 */ + { 39489, 0x07ff }, { 39500, 0xfffd }, { 39515, 0xff0d }, { 39526, 0x07ff }, + { 39537, 0xfbe8 }, { 39548, 0xc5fb }, { 39559, 0x3fe3 }, { 39570, 0xffff }, + { 39586, 0x9ffc }, { 39598, 0xff80 }, { 39607, 0xdc7f }, { 39619, 0xfa9b }, + { 39630, 0x027f }, { 39638, 0xeb4c }, { 39647, 0xfc0e }, { 39656, 0xcd96 }, + /* 0x25600 */ + { 39665, 0x637a }, { 39674, 0x7e60 }, { 39682, 0x7850 }, { 39688, 0xff03 }, + { 39698, 0xfe14 }, { 39707, 0x3ff0 }, { 39717, 0xf910 }, { 39724, 0x1f87 }, + { 39733, 0xff08 }, { 39742, 0x17ff }, { 39754, 0x0fc0 }, { 39760, 0x03ff }, + { 39770, 0xfdef }, { 39784, 0xff10 }, { 39793, 0xc01f }, { 39800, 0xbfbf }, + /* 0x25700 */ + { 39814, 0x9fbe }, { 39826, 0xccbe }, { 39836, 0x9ee9 }, { 39846, 0xff9f }, + { 39860, 0xbdba }, { 39871, 0x7d7d }, { 39883, 0xfffc }, { 39897, 0xde78 }, + { 39907, 0x037f }, { 39916, 0xff84 }, { 39926, 0x8207 }, { 39931, 0xfffe }, + { 39946, 0xe0a0 }, { 39951, 0x5fff }, { 39965, 0x03fc }, { 39973, 0xed80 }, + /* 0x25800 */ + { 39980, 0xffff }, { 39996, 0x01ff }, { 40005, 0x0006 }, { 40007, 0xf6fe }, + { 40020, 0x1feb }, { 40031, 0xbc10 }, { 40037, 0xffff }, { 40053, 0x0279 }, + { 40059, 0xfd83 }, { 40069, 0x7f7e }, { 40082, 0x6080 }, { 40085, 0xbff3 }, + { 40098, 0x003f }, { 40104, 0xd7c8 }, { 40113, 0xffe1 }, { 40125, 0x40bf }, + /* 0x25900 */ + { 40133, 0x5cef }, { 40144, 0xd7fe }, { 40157, 0x6f9c }, { 40167, 0xfff3 }, + { 40181, 0xff8e }, { 40193, 0x4f9f }, { 40204, 0x7fff }, { 40219, 0xffc0 }, + { 40229, 0xfdff }, { 40244, 0xf80b }, { 40252, 0xe7f7 }, { 40265, 0xff67 }, + { 40278, 0x84e0 }, { 40283, 0xfffd }, { 40298, 0xf025 }, { 40305, 0xbfff }, + /* 0x25a00 */ + { 40320, 0xe40f }, { 40328, 0x05ff }, { 40338, 0x7c0e }, { 40346, 0xb9ff }, + { 40359, 0xdd0f }, { 40369, 0x1bfd }, { 40380, 0x7fff }, { 40395, 0xdb7e }, + { 40407, 0xffdf }, { 40422, 0x8f3f }, { 40433, 0xf7f3 }, { 40446, 0xf86f }, + { 40457, 0xe708 }, { 40464, 0xff47 }, { 40476, 0xe1e7 }, { 40486, 0xfffb }, + /* 0x25b00 */ + { 40501, 0xf0bf }, { 40512, 0xeeff }, { 40526, 0xfc7e }, { 40538, 0xfbff }, + { 40553, 0x0fff }, { 40565, 0xffff }, { 40581, 0xfdff }, { 40596, 0xff83 }, + { 40607, 0xf03f }, { 40617, 0x7fff }, { 40632, 0xeffd }, { 40646, 0xffe0 }, + { 40657, 0x0047 }, { 40661, 0xffff }, { 40677, 0xffff }, { 40693, 0xf7ff }, + /* 0x25c00 */ + { 40708, 0xfa64 }, { 40717, 0xffff }, { 40733, 0xffff }, { 40749, 0xffff }, + { 40765, 0xf0f7 }, { 40776, 0xffff }, { 40792, 0x025f }, { 40799, 0xffe8 }, + { 40811, 0xfff3 }, { 40825, 0xffe7 }, { 40839, 0xdfff }, { 40854, 0x3fff }, + { 40868, 0xffc1 }, { 40879, 0xffff }, { 40895, 0xffff }, { 40911, 0x87ff }, + /* 0x25d00 */ + { 40923, 0xffff }, { 40939, 0xe018 }, { 40944, 0xffff }, { 40960, 0xeff7 }, + { 40974, 0x7ff0 }, { 40985, 0xf009 }, { 40991, 0xffff }, { 41007, 0x2f7f }, + { 41019, 0xfdc0 }, { 41028, 0xffff }, { 41044, 0x0ff8 }, { 41053, 0xfff0 }, + { 41065, 0xf3ff }, { 41079, 0xfff3 }, { 41093, 0xff1f }, { 41106, 0xf1f7 }, + /* 0x25e00 */ + { 41118, 0xcfa9 }, { 41128, 0x13d3 }, { 41136, 0xbbee }, { 41148, 0x7ffb }, + { 41162, 0xffee }, { 41176, 0xf467 }, { 41186, 0x29d7 }, { 41195, 0xfffc }, + { 41209, 0x0bf0 }, { 41216, 0xff80 }, { 41225, 0xff9f }, { 41239, 0x115f }, + { 41247, 0xfffe }, { 41262, 0x1e7f }, { 41273, 0xfff0 }, { 41285, 0x800f }, + /* 0x25f00 */ + { 41290, 0xf3ff }, { 41304, 0xff0f }, { 41316, 0x01f7 }, { 41324, 0xffe0 }, + { 41335, 0x8eef }, { 41346, 0x6fe3 }, { 41357, 0xf0e8 }, { 41365, 0xffdf }, + { 41380, 0xf7f7 }, { 41394, 0x7e5f }, { 41406, 0xffff }, { 41422, 0x0dfd }, + { 41432, 0xfff8 }, { 41445, 0x93ef }, { 41456, 0xffc2 }, { 41467, 0xf7ff }, + /* 0x26000 */ + { 41482, 0x02ff }, { 41491, 0xfffc }, { 41505, 0xf0ff }, { 41517, 0x00ff }, + { 41525, 0xff58 }, { 41536, 0x7fff }, { 41551, 0xfff2 }, { 41564, 0x0013 }, + { 41567, 0xfbff }, { 41582, 0xffbf }, { 41597, 0xffc7 }, { 41610, 0x00b3 }, + { 41615, 0xfffa }, { 41629, 0xfbff }, { 41644, 0x01fd }, { 41652, 0x07ff }, + /* 0x26100 */ + { 41663, 0xfe00 }, { 41670, 0x1fff }, { 41683, 0x7ffc }, { 41696, 0xf006 }, + { 41702, 0xffff }, { 41718, 0xe03f }, { 41727, 0x15bf }, { 41737, 0xffe8 }, + { 41749, 0xff7f }, { 41764, 0xf8ff }, { 41777, 0x9eff }, { 41790, 0xf87f }, + { 41802, 0xdf3f }, { 41815, 0xdffa }, { 41828, 0x1faf }, { 41839, 0xffdf }, + /* 0x26200 */ + { 41854, 0x00eb }, { 41860, 0x0000 }, { 41860, 0xfbec }, { 41872, 0xdf7f }, + { 41886, 0xdbb7 }, { 41898, 0xeeef }, { 41911, 0xfefd }, { 41925, 0xdbbc }, + { 41936, 0xeb8f }, { 41947, 0xf3ff }, { 41961, 0xef9f }, { 41974, 0xf078 }, + { 41982, 0x3ff4 }, { 41993, 0xffc7 }, { 42006, 0xf99f }, { 42018, 0xfbbf }, + /* 0x26300 */ + { 42032, 0xe66f }, { 42043, 0xfaff }, { 42057, 0x7f1f }, { 42069, 0xddfe }, + { 42082, 0xfdcf }, { 42095, 0xfdf7 }, { 42109, 0xf7e6 }, { 42121, 0xfe05 }, + { 42130, 0x2fe9 }, { 42140, 0x27f0 }, { 42148, 0x8afc }, { 42157, 0x9f9b }, + { 42168, 0xffea }, { 42181, 0xf7e3 }, { 42193, 0xaf8f }, { 42204, 0x7ff5 }, + /* 0x26400 */ + { 42217, 0x7ffd }, { 42231, 0x5ffb }, { 42244, 0xf7fc }, { 42257, 0x7fef }, + { 42271, 0xffd1 }, { 42283, 0xff3f }, { 42297, 0x1fff }, { 42310, 0xff7f }, + { 42325, 0xfdf8 }, { 42337, 0xbe7f }, { 42350, 0xf77d }, { 42363, 0x7dce }, + { 42374, 0xd01b }, { 42381, 0x67df }, { 42393, 0xff71 }, { 42405, 0x7fb3 }, + /* 0x26500 */ + { 42417, 0xfa7f }, { 42430, 0xfdbf }, { 42444, 0xbf7f }, { 42458, 0xf3af }, + { 42470, 0xfdbf }, { 42484, 0x7dff }, { 42498, 0xffe7 }, { 42512, 0xffe6 }, + { 42525, 0x7f3d }, { 42537, 0x1fff }, { 42550, 0x9ffc }, { 42562, 0xf27f }, + { 42574, 0x27ff }, { 42586, 0x87ff }, { 42598, 0x9fff }, { 42612, 0x43fe }, + /* 0x26600 */ + { 42622, 0xefff }, { 42637, 0xe93f }, { 42648, 0xff0d }, { 42659, 0xedfc }, + { 42671, 0x2fff }, { 42684, 0x99ff }, { 42696, 0xff87 }, { 42708, 0x9fff }, + { 42722, 0x73ff }, { 42735, 0xff1e }, { 42747, 0x7fff }, { 42762, 0x2ffc }, + { 42773, 0xc03e }, { 42780, 0xfffd }, { 42795, 0x7efb }, { 42808, 0x02d8 }, + /* 0x26700 */ + { 42813, 0xfddc }, { 42825, 0x9fff }, { 42839, 0x17ff }, { 42851, 0xee68 }, + { 42860, 0x8002 }, { 42862, 0xffff }, { 42878, 0xffff }, { 42894, 0xfdff }, + { 42909, 0x0ab3 }, { 42916, 0xfee0 }, { 42926, 0xbfff }, { 42941, 0x3fe7 }, + { 42953, 0x0003 }, { 42955, 0xbb30 }, { 42963, 0xbeff }, { 42977, 0x0019 }, + /* 0x26800 */ + { 42980, 0xffff }, { 42996, 0xd6ff }, { 43009, 0x1b31 }, { 43016, 0xdf80 }, + { 43024, 0xf1ef }, { 43036, 0x19bf }, { 43046, 0x3f00 }, { 43052, 0xfff7 }, + { 43067, 0xf52f }, { 43078, 0x3ff3 }, { 43090, 0xbff0 }, { 43101, 0xbf00 }, + { 43108, 0xbfe3 }, { 43120, 0xfc4f }, { 43131, 0x7a13 }, { 43139, 0xfffe }, + /* 0x26900 */ + { 43154, 0xf47d }, { 43165, 0xef75 }, { 43177, 0x1ffe }, { 43189, 0x9efc }, + { 43200, 0xdff6 }, { 43213, 0xebbf }, { 43226, 0x6be7 }, { 43237, 0xfffc }, + { 43251, 0xd7ff }, { 43265, 0xffeb }, { 43279, 0xfebf }, { 43293, 0xff7f }, + { 43308, 0xd7f7 }, { 43321, 0xa4fb }, { 43331, 0x6dff }, { 43344, 0xdb7b }, + /* 0x26a00 */ + { 43356, 0xfffb }, { 43371, 0xb7fd }, { 43384, 0xf5df }, { 43397, 0xf4f7 }, + { 43409, 0xff98 }, { 43420, 0xf318 }, { 43428, 0x1fff }, { 43441, 0x7ff6 }, + { 43454, 0x6ff0 }, { 43464, 0x3ffe }, { 43477, 0xfeb0 }, { 43487, 0xe1c7 }, + { 43496, 0xddff }, { 43510, 0x7eb7 }, { 43522, 0xbffd }, { 43536, 0xffdf }, + /* 0x26b00 */ + { 43551, 0xfbff }, { 43566, 0xfff9 }, { 43580, 0xfeff }, { 43595, 0xffbf }, + { 43610, 0x0bff }, { 43621, 0x3ff0 }, { 43631, 0xfb04 }, { 43639, 0xffff }, + { 43655, 0xffff }, { 43671, 0xff0f }, { 43683, 0xffff }, { 43699, 0xffa8 }, + { 43710, 0xffff }, { 43726, 0xff7e }, { 43740, 0xff7f }, { 43755, 0xff1f }, + /* 0x26c00 */ + { 43768, 0xffff }, { 43784, 0x6bff }, { 43797, 0xfc82 }, { 43805, 0xffff }, + { 43821, 0xffbf }, { 43836, 0xdfff }, { 43851, 0xffff }, { 43867, 0x1ffd }, + { 43879, 0xfff8 }, { 43892, 0xffff }, { 43908, 0x97ff }, { 43921, 0x20c1 }, + { 43925, 0xffff }, { 43941, 0xffff }, { 43957, 0x7fff }, { 43972, 0xffff }, + /* 0x26d00 */ + { 43988, 0xffa7 }, { 44001, 0xffff }, { 44017, 0xf801 }, { 44023, 0xffff }, + { 44039, 0x7fff }, { 44054, 0xe007 }, { 44060, 0xfffe }, { 44075, 0xffff }, + { 44091, 0xfff7 }, { 44106, 0x0fff }, { 44118, 0xff00 }, { 44126, 0xffff }, + { 44142, 0xffff }, { 44158, 0xefbf }, { 44172, 0x040b }, { 44176, 0xbfff }, + /* 0x26e00 */ + { 44191, 0xffdf }, { 44206, 0xffff }, { 44222, 0xffdf }, { 44237, 0x07ff }, + { 44248, 0xffc0 }, { 44258, 0xffff }, { 44274, 0x451e }, { 44281, 0xe084 }, + { 44286, 0xffd7 }, { 44300, 0xffff }, { 44316, 0xffff }, { 44332, 0xffff }, + { 44348, 0x3fff }, { 44362, 0xff00 }, { 44370, 0xffff }, { 44386, 0xffff }, + /* 0x26f00 */ + { 44402, 0xfcff }, { 44416, 0x0227 }, { 44421, 0xfe16 }, { 44431, 0xffff }, + { 44447, 0xdfff }, { 44462, 0xffff }, { 44478, 0x5fff }, { 44492, 0xffe2 }, + { 44504, 0xffff }, { 44520, 0x8895 }, { 44526, 0xf482 }, { 44533, 0xffff }, + { 44549, 0xff7f }, { 44564, 0x03ff }, { 44574, 0xffff }, { 44590, 0xfe3f }, + /* 0x27000 */ + { 44603, 0x20f7 }, { 44611, 0x2ff0 }, { 44620, 0xffff }, { 44636, 0xffbf }, + { 44651, 0xbfff }, { 44666, 0xfff2 }, { 44679, 0xffff }, { 44695, 0xf801 }, + { 44701, 0xff7f }, { 44716, 0xffff }, { 44732, 0x03ba }, { 44739, 0xffff }, + { 44755, 0xc3ff }, { 44767, 0xffff }, { 44783, 0xdfff }, { 44798, 0xfe01 }, + /* 0x27100 */ + { 44806, 0xeaff }, { 44819, 0xffff }, { 44835, 0x7f0f }, { 44846, 0xffc0 }, + { 44856, 0xffff }, { 44872, 0xffdf }, { 44887, 0xc7c7 }, { 44897, 0x7ddf }, + { 44910, 0xefea }, { 44922, 0x7fff }, { 44937, 0x1ff9 }, { 44948, 0xfc7e }, + { 44960, 0x2ffe }, { 44972, 0xf1bf }, { 44984, 0x3fff }, { 44998, 0xf83e }, + /* 0x27200 */ + { 45008, 0x6bcb }, { 45018, 0xf5ef }, { 45031, 0xffb9 }, { 45044, 0xfff1 }, + { 45057, 0xffff }, { 45073, 0xd9e3 }, { 45083, 0xffff }, { 45099, 0xf8f9 }, + { 45110, 0xe1ef }, { 45121, 0xffff }, { 45137, 0xfbff }, { 45152, 0x9fc3 }, + { 45162, 0xff00 }, { 45170, 0xfbff }, { 45185, 0xff83 }, { 45196, 0x0009 }, + /* 0x27300 */ + { 45198, 0xfffa }, { 45212, 0xbfff }, { 45227, 0x3fdf }, { 45240, 0xaff0 }, + { 45250, 0x0000 }, { 45250, 0xfffe }, { 45265, 0xffff }, { 45281, 0xffff }, + { 45297, 0xff1f }, { 45310, 0xc59f }, { 45320, 0xff7e }, { 45334, 0xffff }, + { 45350, 0xffff }, { 45366, 0xf03f }, { 45376, 0x175f }, { 45386, 0xff00 }, + /* 0x27400 */ + { 45394, 0xfff7 }, { 45409, 0xffff }, { 45425, 0xeff8 }, { 45437, 0x007a }, + { 45442, 0xfff1 }, { 45455, 0xf7ff }, { 45470, 0xffff }, { 45486, 0xff1f }, + { 45499, 0xc15e }, { 45507, 0xfdff }, { 45522, 0x0ffe }, { 45533, 0xfffc }, + { 45547, 0xdf00 }, { 45554, 0xffff }, { 45570, 0x18fe }, { 45579, 0xfffe }, + /* 0x27500 */ + { 45594, 0xc1df }, { 45604, 0xe13f }, { 45614, 0xddff }, { 45628, 0x24ff }, + { 45638, 0xfffe }, { 45653, 0xf9f7 }, { 45666, 0xc1ff }, { 45677, 0xf7ff }, + { 45692, 0xfdf5 }, { 45705, 0xfffe }, { 45720, 0xbf90 }, { 45729, 0x7ffc }, + { 45742, 0xffdf }, { 45757, 0xfff7 }, { 45772, 0xffee }, { 45786, 0x8ffe }, + /* 0x27600 */ + { 45798, 0xef7f }, { 45812, 0xf64f }, { 45823, 0xffff }, { 45839, 0x7cf9 }, + { 45850, 0xffff }, { 45866, 0xff07 }, { 45877, 0xffbf }, { 45892, 0xc2ac }, + { 45899, 0xffff }, { 45915, 0x7fe7 }, { 45928, 0xfffa }, { 45942, 0xf7ff }, + { 45957, 0xe009 }, { 45962, 0xffff }, { 45978, 0x1fff }, { 45991, 0xff0f }, + /* 0x27700 */ + { 46003, 0x2dff }, { 46015, 0xe026 }, { 46021, 0xfaff }, { 46035, 0xe187 }, + { 46043, 0xbfff }, { 46058, 0x0fff }, { 46070, 0xfc0c }, { 46078, 0xffff }, + { 46094, 0xf1c7 }, { 46104, 0xfafd }, { 46117, 0xffc6 }, { 46129, 0x3fef }, + { 46142, 0xf78c }, { 46152, 0xcff7 }, { 46165, 0xefca }, { 46176, 0xff9e }, + /* 0x27800 */ + { 46189, 0xdadf }, { 46201, 0xffef }, { 46216, 0x6f0f }, { 46226, 0xf82f }, + { 46236, 0xf979 }, { 46247, 0x29ef }, { 46257, 0xffff }, { 46273, 0xef8e }, + { 46284, 0xe77f }, { 46297, 0x777c }, { 46308, 0xe9ff }, { 46321, 0xffbe }, + { 46335, 0xe3ff }, { 46348, 0x5fff }, { 46362, 0xff2e }, { 46374, 0x7ff3 }, + /* 0x27900 */ + { 46387, 0xfbf8 }, { 46399, 0xf9ff }, { 46413, 0xdecf }, { 46425, 0xfcc6 }, + { 46435, 0x3517 }, { 46443, 0x3fea }, { 46454, 0xef7e }, { 46467, 0xffbb }, + { 46481, 0xbfc7 }, { 46493, 0xfe84 }, { 46502, 0xffff }, { 46518, 0x4cff }, + { 46529, 0xff76 }, { 46542, 0xffff }, { 46558, 0x0df3 }, { 46567, 0xffff }, + /* 0x27a00 */ + { 46583, 0x8fff }, { 46596, 0x7e7f }, { 46609, 0xffd9 }, { 46622, 0xffff }, + { 46638, 0xfefd }, { 46652, 0xff43 }, { 46663, 0xffff }, { 46679, 0xfffe }, + { 46694, 0xffff }, { 46710, 0xffd7 }, { 46724, 0xffff }, { 46740, 0x86ff }, + { 46751, 0x89ff }, { 46762, 0xfffd }, { 46777, 0xffff }, { 46793, 0xe565 }, + /* 0x27b00 */ + { 46802, 0xfffd }, { 46817, 0xbeef }, { 46830, 0xffbf }, { 46845, 0xf87f }, + { 46857, 0xff7f }, { 46872, 0xff7f }, { 46887, 0xffbf }, { 46902, 0xff97 }, + { 46915, 0xdfff }, { 46930, 0xef7f }, { 46944, 0xfb2c }, { 46954, 0x3def }, + { 46966, 0xfe47 }, { 46977, 0x9f39 }, { 46987, 0xeeef }, { 47000, 0xff9b }, + /* 0x27c00 */ + { 47013, 0x3efb }, { 47025, 0x637f }, { 47036, 0xffab }, { 47049, 0xfff5 }, + { 47063, 0xe7ff }, { 47077, 0xffff }, { 47093, 0xff3f }, { 47107, 0xd9ff }, + { 47120, 0xffff }, { 47136, 0xfdbf }, { 47150, 0xf7ff }, { 47165, 0xc2ff }, + { 47176, 0xffff }, { 47192, 0xfedf }, { 47206, 0xffe7 }, { 47220, 0x5fee }, + /* 0x27d00 */ + { 47232, 0xf0fe }, { 47243, 0xe7f1 }, { 47254, 0x3d7b }, { 47265, 0xffef }, + { 47280, 0xffb7 }, { 47294, 0x37e3 }, { 47304, 0xfff9 }, { 47318, 0xe7f7 }, + { 47331, 0x7fec }, { 47343, 0xff8f }, { 47356, 0x05ff }, { 47366, 0xdfff }, + { 47381, 0xfe9f }, { 47394, 0xd6ff }, { 47407, 0xfbff }, { 47422, 0xf825 }, + /* 0x27e00 */ + { 47430, 0xffff }, { 47446, 0x47f2 }, { 47455, 0xe9ff }, { 47468, 0xf3fe }, + { 47481, 0x43c9 }, { 47488, 0x7f00 }, { 47495, 0xf09b }, { 47504, 0x23fc }, + { 47513, 0xffd0 }, { 47524, 0xefdd }, { 47537, 0xffff }, { 47553, 0xffec }, + { 47566, 0xdfff }, { 47581, 0xbffe }, { 47595, 0xd8ff }, { 47607, 0xbf7f }, + /* 0x27f00 */ + { 47621, 0xc2ff }, { 47632, 0xffff }, { 47648, 0xffef }, { 47663, 0xffff }, + { 47679, 0xfe76 }, { 47691, 0xffff }, { 47707, 0xbfff }, { 47722, 0xffd8 }, + { 47734, 0xe93f }, { 47745, 0xffff }, { 47761, 0xff7f }, { 47776, 0x1f73 }, + { 47786, 0x227f }, { 47795, 0xfffc }, { 47809, 0xc05d }, { 47816, 0xfffe }, + /* 0x28000 */ + { 47831, 0x0249 }, { 47835, 0xfff8 }, { 47848, 0x7fff }, { 47863, 0x00c2 }, + { 47866, 0xffff }, { 47882, 0x5e3f }, { 47893, 0x000d }, { 47896, 0xffe8 }, + { 47908, 0xf9ff }, { 47922, 0xf80a }, { 47929, 0xffff }, { 47945, 0x81ff }, + { 47955, 0x0003 }, { 47957, 0xfffc }, { 47971, 0x51ff }, { 47982, 0x8008 }, + /* 0x28100 */ + { 47984, 0xffe9 }, { 47997, 0x0fff }, { 48009, 0x3ffe }, { 48022, 0x0000 }, + { 48022, 0xdd60 }, { 48030, 0xffff }, { 48046, 0x07ff }, { 48057, 0x0076 }, + { 48062, 0xffff }, { 48078, 0x1df3 }, { 48088, 0xfdc0 }, { 48097, 0x183f }, + { 48105, 0x9dfe }, { 48117, 0x67d0 }, { 48125, 0xeff0 }, { 48136, 0x3c1f }, + /* 0x28200 */ + { 48145, 0xad38 }, { 48153, 0xff3b }, { 48166, 0xfe17 }, { 48177, 0xff37 }, + { 48190, 0xff0d }, { 48201, 0x0bb1 }, { 48208, 0xc1fc }, { 48217, 0x9e0f }, + { 48226, 0xe45b }, { 48235, 0x2bfd }, { 48246, 0x9e9f }, { 48257, 0xfffe }, + { 48272, 0xd0d1 }, { 48279, 0x1fff }, { 48292, 0xffc0 }, { 48302, 0x1277 }, + /* 0x28300 */ + { 48310, 0xeffe }, { 48324, 0xbe40 }, { 48331, 0xffff }, { 48347, 0x79ff }, + { 48360, 0xffef }, { 48375, 0x87df }, { 48386, 0xffa9 }, { 48398, 0x8bdf }, + { 48409, 0x3fbf }, { 48422, 0x136f }, { 48431, 0xfff6 }, { 48445, 0x53ff }, + { 48457, 0xcfe2 }, { 48467, 0xe37e }, { 48478, 0x9f5f }, { 48490, 0x677f }, + /* 0x28400 */ + { 48502, 0xb806 }, { 48508, 0xffb3 }, { 48521, 0xbf17 }, { 48532, 0x7a67 }, + { 48542, 0xafff }, { 48556, 0x4f1f }, { 48566, 0xbfff }, { 48581, 0xf0bf }, + { 48592, 0xfffb }, { 48607, 0x2cf8 }, { 48615, 0xfffd }, { 48630, 0xf00d }, + { 48637, 0x6fbf }, { 48650, 0x2bfc }, { 48660, 0xfff0 }, { 48672, 0xefff }, + /* 0x28500 */ + { 48687, 0xc829 }, { 48693, 0xfeff }, { 48708, 0xffde }, { 48722, 0x0007 }, + { 48725, 0xaffe }, { 48738, 0xfc5b }, { 48749, 0xc7ff }, { 48762, 0x317f }, + { 48772, 0xffca }, { 48784, 0xe3f9 }, { 48795, 0xfc3b }, { 48806, 0xdffb }, + { 48820, 0xf81f }, { 48830, 0xc3bd }, { 48840, 0xffee }, { 48854, 0x3fc3 }, + /* 0x28600 */ + { 48864, 0xf7bf }, { 48878, 0xfe0b }, { 48888, 0x7fcf }, { 48901, 0xb3e5 }, + { 48911, 0xc7ff }, { 48924, 0xd7bf }, { 48937, 0xebd9 }, { 48948, 0x7fe7 }, + { 48961, 0xaefc }, { 48972, 0xfffe }, { 48987, 0xfd25 }, { 48997, 0xbe7f }, + { 49010, 0xffda }, { 49023, 0xde7f }, { 49036, 0xfffb }, { 49051, 0xf9fb }, + /* 0x28700 */ + { 49064, 0xfd6f }, { 49077, 0x9fff }, { 49091, 0xe5ff }, { 49104, 0xfffd }, + { 49119, 0xfe9b }, { 49131, 0xe9bb }, { 49142, 0xfdef }, { 49156, 0xe1fb }, + { 49167, 0xf2bf }, { 49179, 0xdffe }, { 49193, 0xcfc3 }, { 49203, 0xffeb }, + { 49217, 0xe13f }, { 49227, 0xdff3 }, { 49240, 0xd9df }, { 49252, 0xfff7 }, + /* 0x28800 */ + { 49267, 0xfde7 }, { 49280, 0x79ff }, { 49293, 0x40f4 }, { 49299, 0x7fc0 }, + { 49308, 0xf826 }, { 49316, 0x3dfb }, { 49328, 0xfe0d }, { 49338, 0x61ff }, + { 49349, 0xfffb }, { 49364, 0x0e77 }, { 49373, 0xbfff }, { 49388, 0xe66f }, + { 49399, 0x48ff }, { 49409, 0xbffb }, { 49423, 0xefcb }, { 49435, 0xffdf }, + /* 0x28900 */ + { 49450, 0xf7a7 }, { 49462, 0x6fef }, { 49475, 0x376f }, { 49486, 0xc7d0 }, + { 49494, 0xfe1d }, { 49505, 0x03ff }, { 49515, 0xe7f4 }, { 49526, 0x4a6f }, + { 49535, 0xfc74 }, { 49545, 0xf25f }, { 49556, 0xfd09 }, { 49565, 0xc19f }, + { 49574, 0xfffe }, { 49589, 0x1a68 }, { 49595, 0xfff2 }, { 49608, 0xe07f }, + /* 0x28a00 */ + { 49618, 0x7fff }, { 49633, 0x20ff }, { 49642, 0xd220 }, { 49647, 0x7fff }, + { 49662, 0xf000 }, { 49666, 0xf9ff }, { 49680, 0x121f }, { 49687, 0x1620 }, + { 49691, 0xfffe }, { 49706, 0x80df }, { 49714, 0xffff }, { 49730, 0x30c1 }, + { 49735, 0xd840 }, { 49740, 0x037f }, { 49749, 0xffc0 }, { 49759, 0x2bff }, + /* 0x28b00 */ + { 49771, 0xf038 }, { 49778, 0xafdf }, { 49791, 0xc7f8 }, { 49801, 0x7fff }, + { 49816, 0x4290 }, { 49820, 0xffe9 }, { 49833, 0xef84 }, { 49842, 0x50ff }, + { 49852, 0x8019 }, { 49856, 0xccbc }, { 49865, 0x89ff }, { 49876, 0xfb80 }, + { 49884, 0xffd0 }, { 49895, 0xc697 }, { 49904, 0xe04f }, { 49912, 0x5c01 }, + /* 0x28c00 */ + { 49917, 0xfe23 }, { 49927, 0xf7f7 }, { 49941, 0xd315 }, { 49949, 0x394f }, + { 49958, 0x0000 }, { 49958, 0xff80 }, { 49967, 0x0bf4 }, { 49975, 0x86f8 }, + { 49983, 0x3fcf }, { 49995, 0xedb8 }, { 50005, 0xe3e7 }, { 50016, 0x5d5c }, + { 50025, 0xde3f }, { 50037, 0xffeb }, { 50051, 0x3faf }, { 50063, 0xfffd }, + /* 0x28d00 */ + { 50078, 0xe037 }, { 50086, 0xa3ff }, { 50098, 0xff21 }, { 50108, 0x81eb }, + { 50116, 0xbff3 }, { 50129, 0x10ff }, { 50138, 0xfff4 }, { 50151, 0x02ad }, + { 50157, 0xffff }, { 50173, 0xf444 }, { 50180, 0xf0ff }, { 50192, 0x43df }, + { 50202, 0x3efe }, { 50214, 0xfabc }, { 50225, 0x0dde }, { 50234, 0x198f }, + /* 0x28e00 */ + { 50242, 0x8000 }, { 50243, 0x7dff }, { 50257, 0xfa1f }, { 50268, 0x012f }, + { 50274, 0xdffe }, { 50288, 0xff2b }, { 50300, 0xe08f }, { 50308, 0xffef }, + { 50323, 0xfc7f }, { 50336, 0x800f }, { 50341, 0xffff }, { 50357, 0x8032 }, + { 50361, 0xffff }, { 50377, 0xfd7f }, { 50391, 0x8543 }, { 50397, 0xffff }, + /* 0x28f00 */ + { 50413, 0xfd7f }, { 50427, 0xfbff }, { 50442, 0xfc41 }, { 50450, 0xe07b }, + { 50459, 0xf0ff }, { 50471, 0xb3ff }, { 50484, 0x5def }, { 50496, 0xbf7e }, + { 50509, 0xafef }, { 50522, 0x3ffe }, { 50535, 0xcfff }, { 50549, 0xfffc }, + { 50563, 0xfb7f }, { 50577, 0x47ff }, { 50589, 0xffff }, { 50605, 0xe67f }, + /* 0x29000 */ + { 50617, 0xffff }, { 50633, 0xffbf }, { 50648, 0xfff3 }, { 50662, 0xfff3 }, + { 50676, 0xffe7 }, { 50690, 0xfbff }, { 50705, 0x3b9f }, { 50716, 0x7fe5 }, + { 50728, 0x37fc }, { 50739, 0x1dfc }, { 50749, 0x77fe }, { 50762, 0xffac }, + { 50774, 0x17ef }, { 50785, 0x7fff }, { 50800, 0xafcb }, { 50811, 0xf7f0 }, + /* 0x29100 */ + { 50822, 0x221b }, { 50828, 0xffc0 }, { 50838, 0x6aff }, { 50850, 0xff80 }, + { 50859, 0xceff }, { 50872, 0xe00d }, { 50878, 0x3fff }, { 50892, 0xf0c6 }, + { 50900, 0x03ff }, { 50910, 0x8dfe }, { 50921, 0xea70 }, { 50929, 0xa5ef }, + { 50940, 0x5f9f }, { 50952, 0xffbe }, { 50966, 0xffdb }, { 50980, 0xd7ef }, + /* 0x29200 */ + { 50993, 0xf7f8 }, { 51005, 0xbe4e }, { 51015, 0xf9ff }, { 51029, 0x7b7f }, + { 51042, 0x7fbf }, { 51056, 0xee52 }, { 51065, 0x5ffe }, { 51078, 0xff00 }, + { 51086, 0x0b3f }, { 51095, 0xffff }, { 51111, 0xfe60 }, { 51120, 0x938d }, + { 51128, 0xffff }, { 51144, 0xe83f }, { 51154, 0xffff }, { 51170, 0xf77f }, + /* 0x29300 */ + { 51184, 0xfff9 }, { 51198, 0x2cff }, { 51209, 0xffc7 }, { 51222, 0xcecf }, + { 51233, 0xceff }, { 51246, 0xfffe }, { 51261, 0xcff0 }, { 51271, 0xc3be }, + { 51281, 0xffb7 }, { 51295, 0x7fbe }, { 51308, 0xfff2 }, { 51321, 0xffef }, + { 51336, 0xcfeb }, { 51348, 0xcfff }, { 51362, 0xff7f }, { 51377, 0x0ff7 }, + /* 0x29400 */ + { 51388, 0xbebe }, { 51400, 0xdff8 }, { 51412, 0x7dff }, { 51426, 0xdef7 }, + { 51439, 0x3fef }, { 51452, 0xffff }, { 51468, 0x5fff }, { 51482, 0x7fff }, + { 51497, 0x9fff }, { 51511, 0xffff }, { 51527, 0xecd7 }, { 51538, 0xffff }, + { 51554, 0x7f7f }, { 51568, 0xe37a }, { 51578, 0xffff }, { 51594, 0x7dff }, + /* 0x29500 */ + { 51608, 0xffff }, { 51624, 0xfe19 }, { 51634, 0xb3ff }, { 51647, 0xfff9 }, + { 51661, 0xff65 }, { 51673, 0xefff }, { 51688, 0xfa7f }, { 51701, 0xd5fe }, + { 51713, 0xfcdb }, { 51725, 0xbe09 }, { 51733, 0x53fe }, { 51744, 0x7ffd }, + { 51758, 0x3ff2 }, { 51769, 0xeff8 }, { 51781, 0xff0f }, { 51793, 0x0dff }, + /* 0x29600 */ + { 51804, 0xffea }, { 51817, 0xf6ff }, { 51831, 0xe0ff }, { 51842, 0xffff }, + { 51858, 0x477f }, { 51869, 0xfede }, { 51882, 0x0012 }, { 51884, 0x34d6 }, + { 51892, 0xffff }, { 51908, 0x7fec }, { 51920, 0xff19 }, { 51931, 0xafff }, + { 51945, 0xff63 }, { 51957, 0xe8cf }, { 51967, 0xffff }, { 51983, 0xfe0a }, + /* 0x29700 */ + { 51992, 0xffff }, { 52008, 0xfcfd }, { 52021, 0xb004 }, { 52025, 0xffff }, + { 52041, 0x0267 }, { 52047, 0xef80 }, { 52055, 0x5bff }, { 52068, 0xf337 }, + { 52079, 0xffff }, { 52095, 0xc6c3 }, { 52103, 0x7fff }, { 52118, 0xf4a4 }, + { 52126, 0xbfff }, { 52141, 0x2bf8 }, { 52150, 0xe5f8 }, { 52160, 0x01d3 }, + /* 0x29800 */ + { 52166, 0x0000 }, { 52166, 0x1ee3 }, { 52175, 0x1c7c }, { 52183, 0xde85 }, + { 52192, 0x77f7 }, { 52205, 0x6d3f }, { 52216, 0x67b2 }, { 52225, 0xffaf }, + { 52239, 0xf35e }, { 52250, 0xffff }, { 52266, 0xe0eb }, { 52275, 0xffff }, + { 52291, 0x77bf }, { 52304, 0xffe7 }, { 52318, 0xe19f }, { 52328, 0xffff }, + /* 0x29900 */ + { 52344, 0x82d3 }, { 52351, 0xffcd }, { 52364, 0x7fff }, { 52379, 0xe88b }, + { 52387, 0xffff }, { 52403, 0x5ddf }, { 52415, 0xf814 }, { 52422, 0x0c1f }, + { 52429, 0xffff }, { 52445, 0xdaf3 }, { 52456, 0x31ff }, { 52467, 0xffc8 }, + { 52478, 0xcffd }, { 52491, 0x0f71 }, { 52499, 0x003f }, { 52505, 0x0000 }, + /* 0x29a00 */ + { 52505, 0x0000 }, { 52505, 0xf8e6 }, { 52515, 0xf0df }, { 52526, 0xe5ff }, + { 52539, 0xfe4f }, { 52551, 0xffa8 }, { 52562, 0xe04f }, { 52570, 0x637f }, + { 52581, 0xfe7f }, { 52595, 0x1fbf }, { 52607, 0x6fff }, { 52621, 0xdbcc }, + { 52631, 0xde7f }, { 52644, 0xf7a3 }, { 52655, 0xffff }, { 52671, 0xb69b }, + /* 0x29b00 */ + { 52681, 0x8e1b }, { 52689, 0xffff }, { 52705, 0x03c7 }, { 52712, 0xbfff }, + { 52727, 0xff8f }, { 52740, 0xe5ef }, { 52752, 0x6fff }, { 52766, 0xff80 }, + { 52775, 0x3bff }, { 52788, 0xffc0 }, { 52798, 0xc3cf }, { 52808, 0x77ff }, + { 52822, 0xfff8 }, { 52835, 0xf853 }, { 52844, 0x23f1 }, { 52852, 0x8d3f }, + /* 0x29c00 */ + { 52862, 0xfefe }, { 52876, 0xf2ff }, { 52889, 0xffff }, { 52905, 0xd2fe }, + { 52916, 0xffbb }, { 52930, 0xbfdf }, { 52944, 0xbbff }, { 52958, 0xe7bf }, + { 52971, 0xfdff }, { 52986, 0x7ff3 }, { 52999, 0xdfee }, { 53012, 0xfa49 }, + { 53021, 0xfbf7 }, { 53035, 0xbf7f }, { 53049, 0xf7ff }, { 53064, 0xf7e7 }, + /* 0x29d00 */ + { 53077, 0xefc9 }, { 53088, 0xfb7f }, { 53102, 0xef5f }, { 53115, 0xaddf }, + { 53127, 0xfdb7 }, { 53140, 0x0bfb }, { 53150, 0xffff }, { 53166, 0x13fb }, + { 53176, 0x7fff }, { 53191, 0x4c7e }, { 53200, 0xfffd }, { 53215, 0xbfc3 }, + { 53226, 0xf80c }, { 53233, 0xf7ff }, { 53248, 0x507f }, { 53257, 0xffb0 }, + /* 0x29e00 */ + { 53268, 0xffff }, { 53284, 0x9f85 }, { 53293, 0x21a5 }, { 53299, 0xd600 }, + { 53304, 0xffff }, { 53320, 0x5fc7 }, { 53331, 0x0104 }, { 53333, 0xfffe }, + { 53348, 0xe07f }, { 53358, 0x1e7f }, { 53369, 0xe800 }, { 53373, 0x7fff }, + { 53388, 0x2fe0 }, { 53396, 0xff40 }, { 53405, 0x0dff }, { 53416, 0x0174 }, + /* 0x29f00 */ + { 53421, 0x7ffc }, { 53434, 0xf1c7 }, { 53444, 0x7fe3 }, { 53456, 0xf83e }, + { 53466, 0xf11f }, { 53476, 0xfd2b }, { 53487, 0x7fcb }, { 53499, 0x00eb }, + { 53505, 0xa201 }, { 53509, 0xfbff }, { 53524, 0x1eff }, { 53536, 0xffff }, + { 53552, 0x9fff }, { 53566, 0xf8ff }, { 53579, 0x7fff }, { 53594, 0x11fe }, + /* 0x2a000 */ + { 53603, 0xbf83 }, { 53613, 0xeffe }, { 53627, 0x3fff }, { 53641, 0xb5ff }, + { 53654, 0xff01 }, { 53663, 0xffff }, { 53679, 0x7fff }, { 53694, 0xfb85 }, + { 53704, 0xffff }, { 53720, 0xefbb }, { 53733, 0x242a }, { 53738, 0xfff0 }, + { 53750, 0xffff }, { 53766, 0x3dff }, { 53779, 0x86d5 }, { 53787, 0xfe48 }, + /* 0x2a100 */ + { 53796, 0xfeff }, { 53811, 0x599f }, { 53821, 0xfe09 }, { 53830, 0xfbff }, + { 53845, 0x7fff }, { 53860, 0x947e }, { 53869, 0xc002 }, { 53872, 0xffff }, + { 53888, 0x3fff }, { 53902, 0x24f2 }, { 53909, 0xff02 }, { 53918, 0xffff }, + { 53934, 0x065e }, { 53941, 0x35fe }, { 53952, 0xf003 }, { 53958, 0x9fff }, + /* 0x2a200 */ + { 53972, 0x7efa }, { 53984, 0xff0d }, { 53995, 0xcff4 }, { 54006, 0xbfb7 }, + { 54019, 0x0001 }, { 54020, 0xffc0 }, { 54030, 0xe3db }, { 54041, 0x95ef }, + { 54052, 0xfbdf }, { 54066, 0x5bfb }, { 54078, 0xbde3 }, { 54089, 0xfffe }, + { 54104, 0xebf8 }, { 54115, 0x7ff7 }, { 54129, 0xfcae }, { 54140, 0xfd9d }, + /* 0x2a300 */ + { 54152, 0x7fee }, { 54165, 0x3df7 }, { 54177, 0xf17d }, { 54188, 0xf91f }, + { 54199, 0xfaff }, { 54213, 0xfd7f }, { 54227, 0xffff }, { 54243, 0xff7d }, + { 54257, 0xe0df }, { 54267, 0xfcfd }, { 54280, 0xfdff }, { 54295, 0x6e7d }, + { 54306, 0x7fde }, { 54319, 0x7f7a }, { 54331, 0xf1f2 }, { 54341, 0xffdf }, + /* 0x2a400 */ + { 54356, 0xff9d }, { 54369, 0xfbfe }, { 54383, 0x0df3 }, { 54392, 0x831c }, + { 54398, 0x7f1f }, { 54410, 0x7ffc }, { 54423, 0xffea }, { 54436, 0xc09f }, + { 54444, 0x993f }, { 54454, 0xff7f }, { 54469, 0xfe8f }, { 54481, 0xcf31 }, + { 54490, 0xde5b }, { 54501, 0xfdff }, { 54516, 0xf3b6 }, { 54527, 0xfbff }, + /* 0x2a500 */ + { 54542, 0xed77 }, { 54554, 0x39f7 }, { 54565, 0xdffc }, { 54578, 0xfdeb }, + { 54591, 0xff5f }, { 54605, 0xff9e }, { 54618, 0xff92 }, { 54629, 0xefe2 }, + { 54640, 0xf9ef }, { 54653, 0x0dff }, { 54664, 0xc7fe }, { 54676, 0x78f9 }, + { 54686, 0xfef6 }, { 54699, 0xff37 }, { 54712, 0xbfff }, { 54727, 0xffe4 }, + /* 0x2a600 */ + { 54739, 0xec33 }, { 54748, 0x99ff }, { 54760, 0x77f7 }, { 54773, 0xffd5 }, + { 54786, 0xffcf }, { 54800, 0xffcf }, { 54814, 0x56f8 }, { 54823, 0xbbfd }, + { 54836, 0x7b5f }, { 54848, 0xfbee }, { 54861, 0xf9e1 }, { 54871, 0xfffb }, + { 54886, 0xef5f }, { 54899, 0x007f }, +}; +static const Summary16 cns11643_inv_uni2indx_page2f8[34] = { + /* 0x2f800 */ + { 54906, 0xffff }, { 54922, 0xffff }, { 54938, 0xffff }, { 54954, 0xffff }, + { 54970, 0xfffe }, { 54985, 0xffff }, { 55001, 0xffff }, { 55017, 0xffff }, + { 55033, 0xffff }, { 55049, 0xffef }, { 55064, 0xffff }, { 55080, 0xffff }, + { 55096, 0xdfff }, { 55111, 0xffff }, { 55127, 0xffff }, { 55143, 0xffff }, + /* 0x2f900 */ + { 55159, 0xffff }, { 55175, 0xffff }, { 55191, 0xffff }, { 55207, 0xffff }, + { 55223, 0xffff }, { 55239, 0xffff }, { 55255, 0xffff }, { 55271, 0xffff }, + { 55287, 0xffff }, { 55303, 0xffef }, { 55318, 0xffff }, { 55334, 0xfffb }, + { 55349, 0xffff }, { 55365, 0xffef }, { 55380, 0xffff }, { 55396, 0xffff }, + /* 0x2fa00 */ + { 55412, 0xffff }, { 55428, 0x3fff }, +}; + +static int +cns11643_inv_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc >= 0x0000 && wc < 0x0100) + summary = &cns11643_inv_uni2indx_page00[(wc>>4)]; + else if (wc >= 0x0200 && wc < 0x03d0) + summary = &cns11643_inv_uni2indx_page02[(wc>>4)-0x020]; + else if (wc >= 0x2000 && wc < 0x22c0) + summary = &cns11643_inv_uni2indx_page20[(wc>>4)-0x200]; + else if (wc >= 0x2400 && wc < 0x2650) + summary = &cns11643_inv_uni2indx_page24[(wc>>4)-0x240]; + else if (wc >= 0x3000 && wc < 0x9fb0) + summary = &cns11643_inv_uni2indx_page30[(wc>>4)-0x300]; + else if (wc >= 0xfa00 && wc < 0xfa30) + summary = &cns11643_inv_uni2indx_pagefa[(wc>>4)-0xfa0]; + else if (wc >= 0xfe00 && wc < 0xfff0) + summary = &cns11643_inv_uni2indx_pagefe[(wc>>4)-0xfe0]; + else if (wc >= 0x20000 && wc < 0x2a6e0) + summary = &cns11643_inv_uni2indx_page200[(wc>>4)-0x2000]; + else if (wc >= 0x2f800 && wc < 0x2fa20) + summary = &cns11643_inv_uni2indx_page2f8[(wc>>4)-0x2f80]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + used += summary->indx; + r[0] = cns11643_inv_2charset[3*used]; + r[1] = cns11643_inv_2charset[3*used+1]; + r[2] = cns11643_inv_2charset[3*used+2]; + return 3; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/config.h b/libs/libiconv/lib/config.h new file mode 100644 index 00000000..7edf9a10 --- /dev/null +++ b/libs/libiconv/lib/config.h @@ -0,0 +1,72 @@ +/* lib/config.h. Generated from config.h.in by configure. */ +/* Copyright (C) 1999-2003, 2005, 2007, 2010 Free Software Foundation, Inc. + This file is part of the GNU LIBICONV Library. + + The GNU LIBICONV Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + The GNU LIBICONV Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU LIBICONV Library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + Fifth Floor, Boston, MA 02110-1301, USA. */ + + +/* Define to 1 to enable a few rarely used encodings. */ +/* #undef ENABLE_EXTRA */ + +/* Define to 1 if the package shall run at any location in the filesystem. */ +/* #undef ENABLE_RELOCATABLE */ + +/* Define to a type if does not define. */ +/* #undef mbstate_t */ + +/* Define if you have , the iconv_t type, and the + iconv_open, iconv, iconv_close functions. */ +#define HAVE_ICONV 1 +/* Define as const if the declaration of iconv() needs const. */ +#define ICONV_CONST + +/* Define to 1 if you have the getc_unlocked() function. */ +#define HAVE_GETC_UNLOCKED 1 + +/* Define if you have and nl_langinfo(CODESET). */ +#define HAVE_LANGINFO_CODESET 1 + +/* Define if you have the mbrtowc() function. */ +#define HAVE_MBRTOWC 1 + +/* Define to 1 if you have the setlocale() function. */ +#define HAVE_SETLOCALE 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_STDDEF_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 or 0, depending whether the compiler supports simple visibility + declarations. */ +#define HAVE_VISIBILITY 1 + +/* Define if you have the wcrtomb() function. */ +#define HAVE_WCRTOMB 1 + +/* Define to 1 if O_NOFOLLOW works. */ +#define HAVE_WORKING_O_NOFOLLOW 1 + +/* Define if the machine's byte ordering is little endian. */ +#define WORDS_LITTLEENDIAN 1 + +/* Define to the value of ${prefix}, as a string. */ +#define INSTALLPREFIX "/usr/local" + diff --git a/libs/libiconv/lib/converters.h b/libs/libiconv/lib/converters.h new file mode 100644 index 00000000..18c5f996 --- /dev/null +++ b/libs/libiconv/lib/converters.h @@ -0,0 +1,298 @@ +/* + * Copyright (C) 1999-2002, 2004-2010 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* This file defines all the converters. */ + + +/* Our own notion of wide character, as UCS-4, according to ISO-10646-1. */ +typedef unsigned int ucs4_t; + +/* State used by a conversion. 0 denotes the initial state. */ +typedef unsigned int state_t; + +/* iconv_t is an opaque type. This is the real iconv_t type. */ +typedef struct conv_struct * conv_t; + +/* + * Data type for conversion multibyte -> unicode + */ +struct mbtowc_funcs { + int (*xxx_mbtowc) (conv_t conv, ucs4_t *pwc, unsigned char const *s, int n); + /* + * int xxx_mbtowc (conv_t conv, ucs4_t *pwc, unsigned char const *s, int n) + * converts the byte sequence starting at s to a wide character. Up to n bytes + * are available at s. n is >= 1. + * Result is number of bytes consumed (if a wide character was read), + * or -1 if invalid, or -2 if n too small, or -2-(number of bytes consumed) + * if only a shift sequence was read. + */ + int (*xxx_flushwc) (conv_t conv, ucs4_t *pwc); + /* + * int xxx_flushwc (conv_t conv, ucs4_t *pwc) + * returns to the initial state and stores the pending wide character, if any. + * Result is 1 (if a wide character was read) or 0 if none was pending. + */ +}; + +/* Return code if invalid input after a shift sequence of n bytes was read. + (xxx_mbtowc) */ +#define RET_SHIFT_ILSEQ(n) (-1-2*(n)) +/* Return code if invalid. (xxx_mbtowc) */ +#define RET_ILSEQ RET_SHIFT_ILSEQ(0) +/* Return code if only a shift sequence of n bytes was read. (xxx_mbtowc) */ +#define RET_TOOFEW(n) (-2-2*(n)) +/* Retrieve the n from the encoded RET_... value. */ +#define DECODE_SHIFT_ILSEQ(r) ((unsigned int)(RET_SHIFT_ILSEQ(0) - (r)) / 2) +#define DECODE_TOOFEW(r) ((unsigned int)(RET_TOOFEW(0) - (r)) / 2) + +/* + * Data type for conversion unicode -> multibyte + */ +struct wctomb_funcs { + int (*xxx_wctomb) (conv_t conv, unsigned char *r, ucs4_t wc, int n); + /* + * int xxx_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) + * converts the wide character wc to the character set xxx, and stores the + * result beginning at r. Up to n bytes may be written at r. n is >= 1. + * Result is number of bytes written, or -1 if invalid, or -2 if n too small. + */ + int (*xxx_reset) (conv_t conv, unsigned char *r, int n); + /* + * int xxx_reset (conv_t conv, unsigned char *r, int n) + * stores a shift sequences returning to the initial state beginning at r. + * Up to n bytes may be written at r. n is >= 0. + * Result is number of bytes written, or -2 if n too small. + */ +}; + +/* Return code if invalid. (xxx_wctomb) */ +#define RET_ILUNI -1 +/* Return code if output buffer is too small. (xxx_wctomb, xxx_reset) */ +#define RET_TOOSMALL -2 + +/* + * Contents of a conversion descriptor. + */ +struct conv_struct { + struct loop_funcs lfuncs; + /* Input (conversion multibyte -> unicode) */ + int iindex; + struct mbtowc_funcs ifuncs; + state_t istate; + /* Output (conversion unicode -> multibyte) */ + int oindex; + struct wctomb_funcs ofuncs; + int oflags; + state_t ostate; + /* Operation flags */ + int transliterate; + int discard_ilseq; + #ifndef LIBICONV_PLUG + struct iconv_fallbacks fallbacks; + struct iconv_hooks hooks; + #endif +}; + +/* + * Include all the converters. + */ + +#include "ascii.h" + +/* General multi-byte encodings */ +#include "utf8.h" +#include "ucs2.h" +#include "ucs2be.h" +#include "ucs2le.h" +#include "ucs4.h" +#include "ucs4be.h" +#include "ucs4le.h" +#include "utf16.h" +#include "utf16be.h" +#include "utf16le.h" +#include "utf32.h" +#include "utf32be.h" +#include "utf32le.h" +#include "utf7.h" +#include "ucs2internal.h" +#include "ucs2swapped.h" +#include "ucs4internal.h" +#include "ucs4swapped.h" +#include "c99.h" +#include "java.h" + +/* 8-bit encodings */ +#include "iso8859_1.h" +#include "iso8859_2.h" +#include "iso8859_3.h" +#include "iso8859_4.h" +#include "iso8859_5.h" +#include "iso8859_6.h" +#include "iso8859_7.h" +#include "iso8859_8.h" +#include "iso8859_9.h" +#include "iso8859_10.h" +#include "iso8859_11.h" +#include "iso8859_13.h" +#include "iso8859_14.h" +#include "iso8859_15.h" +#include "iso8859_16.h" +#include "koi8_r.h" +#include "koi8_u.h" +#include "koi8_ru.h" +#include "cp1250.h" +#include "cp1251.h" +#include "cp1252.h" +#include "cp1253.h" +#include "cp1254.h" +#include "cp1255.h" +#include "cp1256.h" +#include "cp1257.h" +#include "cp1258.h" +#include "cp850.h" +#include "cp862.h" +#include "cp866.h" +#include "cp1131.h" +#include "mac_roman.h" +#include "mac_centraleurope.h" +#include "mac_iceland.h" +#include "mac_croatian.h" +#include "mac_romania.h" +#include "mac_cyrillic.h" +#include "mac_ukraine.h" +#include "mac_greek.h" +#include "mac_turkish.h" +#include "mac_hebrew.h" +#include "mac_arabic.h" +#include "mac_thai.h" +#include "hp_roman8.h" +#include "nextstep.h" +#include "armscii_8.h" +#include "georgian_academy.h" +#include "georgian_ps.h" +#include "koi8_t.h" +#include "pt154.h" +#include "rk1048.h" +#include "mulelao.h" +#include "cp1133.h" +#include "tis620.h" +#include "cp874.h" +#include "viscii.h" +#include "tcvn.h" + +/* CJK character sets [CCS = coded character set] [CJKV.INF chapter 3] */ + +typedef struct { + unsigned short indx; /* index into big table */ + unsigned short used; /* bitmask of used entries */ +} Summary16; + +#include "iso646_jp.h" +#include "jisx0201.h" +#include "jisx0208.h" +#include "jisx0212.h" + +#include "iso646_cn.h" +#include "gb2312.h" +#include "isoir165.h" +/*#include "gb12345.h"*/ +#include "gbk.h" +#include "cns11643.h" +#include "big5.h" + +#include "ksc5601.h" +#include "johab_hangul.h" + +/* CJK encodings [CES = character encoding scheme] [CJKV.INF chapter 4] */ + +#include "euc_jp.h" +#include "sjis.h" +#include "cp932.h" +#include "iso2022_jp.h" +#include "iso2022_jp1.h" +#include "iso2022_jp2.h" + +#include "euc_cn.h" +#include "ces_gbk.h" +#include "cp936.h" +#include "gb18030.h" +#include "iso2022_cn.h" +#include "iso2022_cnext.h" +#include "hz.h" +#include "euc_tw.h" +#include "ces_big5.h" +#include "cp950.h" +#include "big5hkscs1999.h" +#include "big5hkscs2001.h" +#include "big5hkscs2004.h" +#include "big5hkscs2008.h" + +#include "euc_kr.h" +#include "cp949.h" +#include "johab.h" +#include "iso2022_kr.h" + +/* Encodings used by system dependent locales. */ + +#ifdef USE_AIX +#include "cp856.h" +#include "cp922.h" +#include "cp943.h" +#include "cp1046.h" +#include "cp1124.h" +#include "cp1129.h" +#include "cp1161.h" +#include "cp1162.h" +#include "cp1163.h" +#endif + +#ifdef USE_OSF1 +#include "dec_kanji.h" +#include "dec_hanyu.h" +#endif + +#ifdef USE_DOS +#include "cp437.h" +#include "cp737.h" +#include "cp775.h" +#include "cp852.h" +#include "cp853.h" +#include "cp855.h" +#include "cp857.h" +#include "cp858.h" +#include "cp860.h" +#include "cp861.h" +#include "cp863.h" +#include "cp864.h" +#include "cp865.h" +#include "cp869.h" +#include "cp1125.h" +#endif + +#ifdef USE_EXTRA +#include "euc_jisx0213.h" +#include "shift_jisx0213.h" +#include "iso2022_jp3.h" +#include "big5_2003.h" +#include "tds565.h" +#include "atarist.h" +#include "riscos1.h" +#endif + diff --git a/libs/libiconv/lib/cp1046.h b/libs/libiconv/lib/cp1046.h new file mode 100644 index 00000000..b6716b73 --- /dev/null +++ b/libs/libiconv/lib/cp1046.h @@ -0,0 +1,157 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1046 + */ + +static const unsigned short cp1046_2uni[128] = { + /* 0x80 */ + 0xfe88, 0x00d7, 0x00f7, 0xf8f6, 0xf8f5, 0xf8f4, 0xf8f7, 0xfe71, + 0x0088, 0x25a0, 0x2502, 0x2500, 0x2510, 0x250c, 0x2514, 0x2518, + /* 0x90 */ + 0xfe79, 0xfe7b, 0xfe7d, 0xfe7f, 0xfe77, 0xfe8a, 0xfef0, 0xfef3, + 0xfef2, 0xfece, 0xfecf, 0xfed0, 0xfef6, 0xfef8, 0xfefa, 0xfefc, + /* 0xa0 */ + 0x00a0, 0xf8fa, 0xf8f9, 0xf8f8, 0x00a4, 0xf8fb, 0xfe8b, 0xfe91, + 0xfe97, 0xfe9b, 0xfe9f, 0xfea3, 0x060c, 0x00ad, 0xfea7, 0xfeb3, + /* 0xb0 */ + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, + 0x0668, 0x0669, 0xfeb7, 0x061b, 0xfebb, 0xfebf, 0xfeca, 0x061f, + /* 0xc0 */ + 0xfecb, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, + /* 0xd0 */ + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, + 0xfec7, 0x0639, 0x063a, 0xfecc, 0xfe82, 0xfe84, 0xfe8e, 0xfed3, + /* 0xe0 */ + 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, + 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, + /* 0xf0 */ + 0x0650, 0x0651, 0x0652, 0xfed7, 0xfedb, 0xfedf, 0xf8fc, 0xfef5, + 0xfef7, 0xfef9, 0xfefb, 0xfee3, 0xfee7, 0xfeec, 0xfee9, 0xfffd, +}; + +static int +cp1046_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp1046_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp1046_page00[112] = { + 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, /* 0xf0-0xf7 */ +}; +static const unsigned char cp1046_page06[104] = { + 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0xbf, /* 0x18-0x1f */ + 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x30-0x37 */ + 0x00, 0xd9, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0xf0, 0xf1, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x60-0x67 */ + 0xb8, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ +}; +static const unsigned char cp1046_page25[32] = { + 0x8b, 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x8c, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ +}; +static const unsigned char cp1046_pagef8[16] = { + 0x00, 0x00, 0x00, 0x00, 0x85, 0x84, 0x83, 0x86, /* 0xf0-0xf7 */ + 0xa3, 0xa2, 0xa1, 0xa5, 0xf6, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; +static const unsigned char cp1046_pagefe[144] = { + 0x00, 0x87, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, /* 0x70-0x77 */ + 0x00, 0x90, 0x00, 0x91, 0x00, 0x92, 0x00, 0x93, /* 0x78-0x7f */ + 0x00, 0x00, 0xdc, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x80, 0x00, 0x95, 0xa6, 0x00, 0x00, 0xde, 0x00, /* 0x88-0x8f */ + 0x00, 0xa7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0xaa, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, 0xae, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0xba, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xbc, 0x00, 0x00, 0x00, 0xbd, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, /* 0xc0-0xc7 */ + 0x00, 0x00, 0xbe, 0xc0, 0xdb, 0x00, 0x99, 0x9a, /* 0xc8-0xcf */ + 0x9b, 0x00, 0x00, 0xdf, 0x00, 0x00, 0x00, 0xf3, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0x00, 0xf5, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, 0xfc, /* 0xe0-0xe7 */ + 0x00, 0xfe, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x96, 0x00, 0x98, 0x97, 0x00, 0xf7, 0x9c, 0xf8, /* 0xf0-0xf7 */ + 0x9d, 0xf9, 0x9e, 0xfa, 0x9f, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static int +cp1046_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x0088 && wc < 0x00f8) + c = cp1046_page00[wc-0x0088]; + else if (wc >= 0x0608 && wc < 0x0670) + c = cp1046_page06[wc-0x0608]; + else if (wc >= 0x2500 && wc < 0x2520) + c = cp1046_page25[wc-0x2500]; + else if (wc == 0x25a0) + c = 0x89; + else if (wc >= 0xf8f0 && wc < 0xf900) + c = cp1046_pagef8[wc-0xf8f0]; + else if (wc >= 0xfe70 && wc < 0xff00) + c = cp1046_pagefe[wc-0xfe70]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1124.h b/libs/libiconv/lib/cp1124.h new file mode 100644 index 00000000..8b97a7e8 --- /dev/null +++ b/libs/libiconv/lib/cp1124.h @@ -0,0 +1,102 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1124 + */ + +static const unsigned short cp1124_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0401, 0x0402, 0x0490, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f, + /* 0xb0 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + /* 0xc0 */ + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + /* 0xd0 */ + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + /* 0xe0 */ + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, + /* 0xf0 */ + 0x2116, 0x0451, 0x0452, 0x0491, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f, +}; + +static int +cp1124_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp1124_2uni[c-0xa0]; + return 1; +} + +static const unsigned char cp1124_page00[16] = { + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ +}; +static const unsigned char cp1124_page04[152] = { + 0x00, 0xa1, 0xa2, 0x00, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x00-0x07 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0x00, 0xae, 0xaf, /* 0x08-0x0f */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x10-0x17 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0x18-0x1f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x30-0x37 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0x00, 0xf1, 0xf2, 0x00, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x50-0x57 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0xfe, 0xff, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xa3, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; + +static int +cp1124_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00b0) + c = cp1124_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x0498) + c = cp1124_page04[wc-0x0400]; + else if (wc == 0x2116) + c = 0xf0; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1125.h b/libs/libiconv/lib/cp1125.h new file mode 100644 index 00000000..802f0742 --- /dev/null +++ b/libs/libiconv/lib/cp1125.h @@ -0,0 +1,129 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1125 + */ + +static const unsigned short cp1125_2uni[80] = { + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + /* 0xd0 */ + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + /* 0xe0 */ + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, + /* 0xf0 */ + 0x0401, 0x0451, 0x0490, 0x0491, 0x0404, 0x0454, 0x0406, 0x0456, + 0x0407, 0x0457, 0x00b7, 0x221a, 0x2116, 0x00a4, 0x25a0, 0x00a0, +}; + +static int +cp1125_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else if (c < 0xb0) + *pwc = (ucs4_t) c + 0x0390; + else + *pwc = (ucs4_t) cp1125_2uni[c-0xb0]; + return 1; +} + +static const unsigned char cp1125_page00[24] = { + 0xff, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, /* 0xb0-0xb7 */ +}; +static const unsigned char cp1125_page04[152] = { + 0x00, 0xf0, 0x00, 0x00, 0xf4, 0x00, 0xf6, 0xf8, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x10-0x17 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x18-0x1f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x20-0x27 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x28-0x2f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x30-0x37 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0x00, 0xf1, 0x00, 0x00, 0xf5, 0x00, 0xf7, 0xf9, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xf2, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char cp1125_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp1125_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00b8) + c = cp1125_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x0498) + c = cp1125_page04[wc-0x0400]; + else if (wc == 0x2116) + c = 0xfc; + else if (wc == 0x221a) + c = 0xfb; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp1125_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1129.h b/libs/libiconv/lib/cp1129.h new file mode 100644 index 00000000..1b7cff85 --- /dev/null +++ b/libs/libiconv/lib/cp1129.h @@ -0,0 +1,121 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1129 + */ + +static const unsigned short cp1129_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x0153, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0178, 0x00b5, 0x00b6, 0x00b7, + 0x0152, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + /* 0xc0 */ + 0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x0300, 0x00cd, 0x00ce, 0x00cf, + /* 0xd0 */ + 0x0110, 0x00d1, 0x0309, 0x00d3, 0x00d4, 0x01a0, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x01af, 0x0303, 0x00df, + /* 0xe0 */ + 0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0301, 0x00ed, 0x00ee, 0x00ef, + /* 0xf0 */ + 0x0111, 0x00f1, 0x0323, 0x00f3, 0x00f4, 0x01a1, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x01b0, 0x20ab, 0x00ff, +}; + +static int +cp1129_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp1129_2uni[c-0xa0]; + return 1; +} + +static const unsigned char cp1129_page00[272] = { + 0x00, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0x00, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0x00, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0xd1, 0x00, 0xd3, 0xd4, 0x00, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0x00, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0x00, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0xf1, 0x00, 0xf3, 0xf4, 0x00, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0xff, /* 0xf8-0xff */ + /* 0x0100 */ + 0x00, 0x00, 0xc3, 0xe3, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0xb8, 0xa8, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xd5, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, /* 0xa8-0xaf */ + 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ +}; +static const unsigned char cp1129_page03[40] = { + 0xcc, 0xec, 0x00, 0xde, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; + +static int +cp1129_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a8) { + *r = wc; + return 1; + } + else if (wc >= 0x00a8 && wc < 0x01b8) + c = cp1129_page00[wc-0x00a8]; + else if (wc >= 0x0300 && wc < 0x0328) + c = cp1129_page03[wc-0x0300]; + else if (wc == 0x20ab) + c = 0xfe; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1131.h b/libs/libiconv/lib/cp1131.h new file mode 100644 index 00000000..15f4ed2a --- /dev/null +++ b/libs/libiconv/lib/cp1131.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1131 + */ + +static const unsigned short cp1131_2uni[128] = { + /* 0x80 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + /* 0x90 */ + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + /* 0xa0 */ + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + /* 0xd0 */ + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + /* 0xe0 */ + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, + /* 0xf0 */ + 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040e, 0x045e, + 0x0406, 0x0456, 0x00b7, 0x00a4, 0x0490, 0x0491, 0x2219, 0x00a0, +}; + +static int +cp1131_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp1131_2uni[c-0x80]; + return 1; +} + +static const unsigned char cp1131_page00[24] = { + 0xff, 0x00, 0x00, 0x00, 0xfb, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, /* 0xb0-0xb7 */ +}; +static const unsigned char cp1131_page04[152] = { + 0x00, 0xf0, 0x00, 0x00, 0xf2, 0x00, 0xf8, 0xf4, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x00, /* 0x08-0x0f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x10-0x17 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x18-0x1f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x20-0x27 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x28-0x2f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x30-0x37 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0x00, 0xf1, 0x00, 0x00, 0xf3, 0x00, 0xf9, 0xf5, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xfc, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char cp1131_page25[152] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; + +static int +cp1131_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00b8) + c = cp1131_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x0498) + c = cp1131_page04[wc-0x0400]; + else if (wc == 0x2219) + c = 0xfe; + else if (wc >= 0x2500 && wc < 0x2598) + c = cp1131_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1133.h b/libs/libiconv/lib/cp1133.h new file mode 100644 index 00000000..a16d93f1 --- /dev/null +++ b/libs/libiconv/lib/cp1133.h @@ -0,0 +1,110 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * IBM-CP1133 + */ + +static const unsigned short cp1133_2uni_1[64] = { + /* 0xa0 */ + 0x00a0, 0x0e81, 0x0e82, 0x0e84, 0x0e87, 0x0e88, 0x0eaa, 0x0e8a, + 0x0e8d, 0x0e94, 0x0e95, 0x0e96, 0x0e97, 0x0e99, 0x0e9a, 0x0e9b, + /* 0xb0 */ + 0x0e9c, 0x0e9d, 0x0e9e, 0x0e9f, 0x0ea1, 0x0ea2, 0x0ea3, 0x0ea5, + 0x0ea7, 0x0eab, 0x0ead, 0x0eae, 0xfffd, 0xfffd, 0xfffd, 0x0eaf, + /* 0xc0 */ + 0x0eb0, 0x0eb2, 0x0eb3, 0x0eb4, 0x0eb5, 0x0eb6, 0x0eb7, 0x0eb8, + 0x0eb9, 0x0ebc, 0x0eb1, 0x0ebb, 0x0ebd, 0xfffd, 0xfffd, 0xfffd, + /* 0xd0 */ + 0x0ec0, 0x0ec1, 0x0ec2, 0x0ec3, 0x0ec4, 0x0ec8, 0x0ec9, 0x0eca, + 0x0ecb, 0x0ecc, 0x0ecd, 0x0ec6, 0xfffd, 0x0edc, 0x0edd, 0x20ad, +}; +static const unsigned short cp1133_2uni_2[16] = { + /* 0xf0 */ + 0x0ed0, 0x0ed1, 0x0ed2, 0x0ed3, 0x0ed4, 0x0ed5, 0x0ed6, 0x0ed7, + 0x0ed8, 0x0ed9, 0xfffd, 0xfffd, 0x00a2, 0x00ac, 0x00a6, 0xfffd, +}; + +static int +cp1133_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + else if (c < 0xe0) { + unsigned short wc = cp1133_2uni_1[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + else if (c < 0xf0) { + } + else { + unsigned short wc = cp1133_2uni_2[c-0xf0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp1133_page00[16] = { + 0xa0, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfe, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ +}; +static const unsigned char cp1133_page0e[96] = { + 0x00, 0xa1, 0xa2, 0x00, 0xa3, 0x00, 0x00, 0xa4, /* 0x80-0x87 */ + 0xa5, 0x00, 0xa7, 0x00, 0x00, 0xa8, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0xa9, 0xaa, 0xab, 0xac, /* 0x90-0x97 */ + 0x00, 0xad, 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, /* 0x98-0x9f */ + 0x00, 0xb4, 0xb5, 0xb6, 0x00, 0xb7, 0x00, 0xb8, /* 0xa0-0xa7 */ + 0x00, 0x00, 0xa6, 0xb9, 0x00, 0xba, 0xbb, 0xbf, /* 0xa8-0xaf */ + 0xc0, 0xca, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, /* 0xb0-0xb7 */ + 0xc7, 0xc8, 0x00, 0xcb, 0xc9, 0xcc, 0x00, 0x00, /* 0xb8-0xbf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0x00, 0xdb, 0x00, /* 0xc0-0xc7 */ + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0x00, 0x00, /* 0xc8-0xcf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xd0-0xd7 */ + 0xf8, 0xf9, 0x00, 0x00, 0xdd, 0xde, 0x00, 0x00, /* 0xd8-0xdf */ +}; + +static int +cp1133_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00b0) + c = cp1133_page00[wc-0x00a0]; + else if (wc >= 0x0e80 && wc < 0x0ee0) + c = cp1133_page0e[wc-0x0e80]; + else if (wc == 0x20ad) + c = 0xdf; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1161.h b/libs/libiconv/lib/cp1161.h new file mode 100644 index 00000000..b6349c67 --- /dev/null +++ b/libs/libiconv/lib/cp1161.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1161 + */ + +static const unsigned short cp1161_2uni[96] = { + /* 0xa0 */ + 0x0e48, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, + 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, + /* 0xb0 */ + 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, + 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, + /* 0xc0 */ + 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, + 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, + /* 0xd0 */ + 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, + 0x0e38, 0x0e39, 0x0e3a, 0x0e49, 0x0e4a, 0x0e4b, 0x20ac, 0x0e3f, + /* 0xe0 */ + 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, + 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f, + /* 0xf0 */ + 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, + 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0x00a2, 0x00ac, 0x00a6, 0x00a0, +}; + +static int +cp1161_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else if (c < 0xa0) { + } + else { + *pwc = (ucs4_t) cp1161_2uni[c-0xa0]; + return 1; + } + return RET_ILSEQ; +} + +static const unsigned char cp1161_page00[16] = { + 0xff, 0x00, 0xfc, 0x00, 0x00, 0x00, 0xfe, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ +}; + +static int +cp1161_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00b0) + c = cp1161_page00[wc-0x00a0]; + else if (wc >= 0x0e48 && wc < 0x0e4c) + c = wc-0x0d60; + else if (wc >= 0x0e00 && wc < 0x0e60) + c = cp874_page0e[wc-0x0e00]; + else if (wc == 0x20ac) + c = 0xde; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1162.h b/libs/libiconv/lib/cp1162.h new file mode 100644 index 00000000..6c7fa82a --- /dev/null +++ b/libs/libiconv/lib/cp1162.h @@ -0,0 +1,70 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1162 + */ + +static int +cp1162_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp874_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + if (c < 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + } + return RET_ILSEQ; +} + +static int +cp1162_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x0080 && wc < 0x00a0 && cp874_2uni[wc-0x0080] == 0xfffd) + c = wc; + else if (wc == 0x00a0) + c = 0xa0; + else if (wc >= 0x0e00 && wc < 0x0e60) + c = cp874_page0e[wc-0x0e00]; + else if (wc >= 0x2010 && wc < 0x2028) + c = cp874_page20[wc-0x2010]; + else if (wc == 0x20ac) + c = 0x80; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1163.h b/libs/libiconv/lib/cp1163.h new file mode 100644 index 00000000..ca5d0b07 --- /dev/null +++ b/libs/libiconv/lib/cp1163.h @@ -0,0 +1,63 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1163 + */ + +static int +cp1163_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else if (c == 0xa4) + *pwc = 0x20ac; + else + *pwc = (ucs4_t) cp1129_2uni[c-0xa0]; + return 1; +} + +static const unsigned char cp1163_page20[8] = { + 0x00, 0x00, 0x00, 0xfe, 0xa4, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ +}; + +static int +cp1163_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0 || (wc < 0x00a8 && wc != 0x00a4) || wc == 0x00d0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a8 && wc < 0x01b8) + c = cp1129_page00[wc-0x00a8]; + else if (wc >= 0x0300 && wc < 0x0328) + c = cp1129_page03[wc-0x0300]; + else if (wc == 0x203e) + c = 0xaf; + else if (wc >= 0x20a8 && wc < 0x20b0) + c = cp1163_page20[wc-0x20a8]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1250.h b/libs/libiconv/lib/cp1250.h new file mode 100644 index 00000000..b89300fe --- /dev/null +++ b/libs/libiconv/lib/cp1250.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1250 + */ + +static const unsigned short cp1250_2uni[128] = { + /* 0x80 */ + 0x20ac, 0xfffd, 0x201a, 0xfffd, 0x201e, 0x2026, 0x2020, 0x2021, + 0xfffd, 0x2030, 0x0160, 0x2039, 0x015a, 0x0164, 0x017d, 0x0179, + /* 0x90 */ + 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0xfffd, 0x2122, 0x0161, 0x203a, 0x015b, 0x0165, 0x017e, 0x017a, + /* 0xa0 */ + 0x00a0, 0x02c7, 0x02d8, 0x0141, 0x00a4, 0x0104, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x015e, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x017b, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x02db, 0x0142, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x0105, 0x015f, 0x00bb, 0x013d, 0x02dd, 0x013e, 0x017c, + /* 0xc0 */ + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + /* 0xd0 */ + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, + 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + /* 0xe0 */ + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + /* 0xf0 */ + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, + 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9, +}; + +static int +cp1250_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp1250_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp1250_page00[224] = { + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0x00, 0x00, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0xc1, 0xc2, 0x00, 0xc4, 0x00, 0x00, 0xc7, /* 0xc0-0xc7 */ + 0x00, 0xc9, 0x00, 0xcb, 0x00, 0xcd, 0xce, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xd3, 0xd4, 0x00, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0x00, 0x00, 0xda, 0x00, 0xdc, 0xdd, 0x00, 0xdf, /* 0xd8-0xdf */ + 0x00, 0xe1, 0xe2, 0x00, 0xe4, 0x00, 0x00, 0xe7, /* 0xe0-0xe7 */ + 0x00, 0xe9, 0x00, 0xeb, 0x00, 0xed, 0xee, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xf3, 0xf4, 0x00, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0x00, 0xfa, 0x00, 0xfc, 0xfd, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0x00, 0x00, 0xc3, 0xe3, 0xa5, 0xb9, 0xc6, 0xe6, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0xcf, 0xef, /* 0x08-0x0f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xca, 0xea, 0xcc, 0xec, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0xc5, 0xe5, 0x00, 0x00, 0xbc, 0xbe, 0x00, /* 0x38-0x3f */ + 0x00, 0xa3, 0xb3, 0xd1, 0xf1, 0x00, 0x00, 0xd2, /* 0x40-0x47 */ + 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xd5, 0xf5, 0x00, 0x00, 0xc0, 0xe0, 0x00, 0x00, /* 0x50-0x57 */ + 0xd8, 0xf8, 0x8c, 0x9c, 0x00, 0x00, 0xaa, 0xba, /* 0x58-0x5f */ + 0x8a, 0x9a, 0xde, 0xfe, 0x8d, 0x9d, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0xf9, /* 0x68-0x6f */ + 0xdb, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x8f, 0x9f, 0xaf, 0xbf, 0x8e, 0x9e, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char cp1250_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xa2, 0xff, 0x00, 0xb2, 0x00, 0xbd, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char cp1250_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +cp1250_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = cp1250_page00[wc-0x00a0]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = cp1250_page02[wc-0x02c0]; + else if (wc >= 0x2010 && wc < 0x2040) + c = cp1250_page20[wc-0x2010]; + else if (wc == 0x20ac) + c = 0x80; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1251.h b/libs/libiconv/lib/cp1251.h new file mode 100644 index 00000000..0fa540db --- /dev/null +++ b/libs/libiconv/lib/cp1251.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1251 + */ + +static const unsigned short cp1251_2uni[128] = { + /* 0x80 */ + 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, + 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x040c, 0x040b, 0x040f, + /* 0x90 */ + 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0xfffd, 0x2122, 0x0459, 0x203a, 0x045a, 0x045c, 0x045b, 0x045f, + /* 0xa0 */ + 0x00a0, 0x040e, 0x045e, 0x0408, 0x00a4, 0x0490, 0x00a6, 0x00a7, + 0x0401, 0x00a9, 0x0404, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x0407, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x0406, 0x0456, 0x0491, 0x00b5, 0x00b6, 0x00b7, + 0x0451, 0x2116, 0x0454, 0x00bb, 0x0458, 0x0405, 0x0455, 0x0457, + /* 0xc0 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + /* 0xd0 */ + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + /* 0xe0 */ + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + /* 0xf0 */ + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, +}; + +static int +cp1251_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp1251_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp1251_page00[32] = { + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0x00, 0x00, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char cp1251_page04[152] = { + 0x00, 0xa8, 0x80, 0x81, 0xaa, 0xbd, 0xb2, 0xaf, /* 0x00-0x07 */ + 0xa3, 0x8a, 0x8c, 0x8e, 0x8d, 0x00, 0xa1, 0x8f, /* 0x08-0x0f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x10-0x17 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x18-0x1f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x20-0x27 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0x28-0x2f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x30-0x37 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x38-0x3f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x40-0x47 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0x48-0x4f */ + 0x00, 0xb8, 0x90, 0x83, 0xba, 0xbe, 0xb3, 0xbf, /* 0x50-0x57 */ + 0xbc, 0x9a, 0x9c, 0x9e, 0x9d, 0x00, 0xa2, 0x9f, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xa5, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char cp1251_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +cp1251_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = cp1251_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x0498) + c = cp1251_page04[wc-0x0400]; + else if (wc >= 0x2010 && wc < 0x2040) + c = cp1251_page20[wc-0x2010]; + else if (wc == 0x20ac) + c = 0x88; + else if (wc == 0x2116) + c = 0xb9; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1252.h b/libs/libiconv/lib/cp1252.h new file mode 100644 index 00000000..15644423 --- /dev/null +++ b/libs/libiconv/lib/cp1252.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1252 + */ + +static const unsigned short cp1252_2uni[32] = { + /* 0x80 */ + 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0xfffd, 0x017d, 0xfffd, + /* 0x90 */ + 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0xfffd, 0x017e, 0x0178, +}; + +static int +cp1252_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80 || c >= 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp1252_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp1252_page01[72] = { + 0x00, 0x00, 0x8c, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x8a, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x9f, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x9e, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char cp1252_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char cp1252_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +cp1252_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = wc; + else if (wc >= 0x0150 && wc < 0x0198) + c = cp1252_page01[wc-0x0150]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = cp1252_page02[wc-0x02c0]; + else if (wc >= 0x2010 && wc < 0x2040) + c = cp1252_page20[wc-0x2010]; + else if (wc == 0x20ac) + c = 0x80; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1253.h b/libs/libiconv/lib/cp1253.h new file mode 100644 index 00000000..020f0d6e --- /dev/null +++ b/libs/libiconv/lib/cp1253.h @@ -0,0 +1,122 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1253 + */ + +static const unsigned short cp1253_2uni[128] = { + /* 0x80 */ + 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0xfffd, 0x2030, 0xfffd, 0x2039, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x90 */ + 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0xfffd, 0x2122, 0xfffd, 0x203a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xa0 */ + 0x00a0, 0x0385, 0x0386, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0xfffd, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x2015, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x00b5, 0x00b6, 0x00b7, + 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, + /* 0xc0 */ + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, + /* 0xd0 */ + 0x03a0, 0x03a1, 0xfffd, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, + 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, + /* 0xe0 */ + 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, + /* 0xf0 */ + 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0xfffd, +}; + +static int +cp1253_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp1253_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp1253_page00[32] = { + 0xa0, 0x00, 0x00, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0xbd, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char cp1253_page03[80] = { + 0x00, 0x00, 0x00, 0x00, 0xb4, 0xa1, 0xa2, 0x00, /* 0x80-0x87 */ + 0xb8, 0xb9, 0xba, 0x00, 0xbc, 0x00, 0xbe, 0xbf, /* 0x88-0x8f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x90-0x97 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x98-0x9f */ + 0xd0, 0xd1, 0x00, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xa0-0xa7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xa8-0xaf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xb0-0xb7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xb8-0xbf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xc0-0xc7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x00, /* 0xc8-0xcf */ +}; +static const unsigned char cp1253_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0xaf, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +cp1253_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = cp1253_page00[wc-0x00a0]; + else if (wc == 0x0192) + c = 0x83; + else if (wc >= 0x0380 && wc < 0x03d0) + c = cp1253_page03[wc-0x0380]; + else if (wc >= 0x2010 && wc < 0x2040) + c = cp1253_page20[wc-0x2010]; + else if (wc == 0x20ac) + c = 0x80; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1254.h b/libs/libiconv/lib/cp1254.h new file mode 100644 index 00000000..845a01b8 --- /dev/null +++ b/libs/libiconv/lib/cp1254.h @@ -0,0 +1,146 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1254 + */ + +static const unsigned short cp1254_2uni_1[32] = { + /* 0x80 */ + 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0xfffd, 0xfffd, 0xfffd, + /* 0x90 */ + 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0xfffd, 0xfffd, 0x0178, +}; +static const unsigned short cp1254_2uni_2[16] = { + /* 0xd0 */ + 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, +}; +static const unsigned short cp1254_2uni_3[16] = { + /* 0xf0 */ + 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff, +}; + +static int +cp1254_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else if (c < 0xa0) { + unsigned short wc = cp1254_2uni_1[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + else if (c < 0xd0) { + *pwc = (ucs4_t) c; + return 1; + } + else if (c < 0xe0) { + *pwc = (ucs4_t) cp1254_2uni_2[c-0xd0]; + return 1; + } + else if (c < 0xf0) { + *pwc = (ucs4_t) c; + return 1; + } + else { + *pwc = (ucs4_t) cp1254_2uni_3[c-0xf0]; + return 1; + } + return RET_ILSEQ; +} + +static const unsigned char cp1254_page00[48] = { + 0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0xff, /* 0xf8-0xff */ +}; +static const unsigned char cp1254_page01[128] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xf0, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xdd, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x8c, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xfe, /* 0x58-0x5f */ + 0x8a, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char cp1254_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char cp1254_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +cp1254_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00d0) + c = wc; + else if (wc >= 0x00d0 && wc < 0x0100) + c = cp1254_page00[wc-0x00d0]; + else if (wc >= 0x0118 && wc < 0x0198) + c = cp1254_page01[wc-0x0118]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = cp1254_page02[wc-0x02c0]; + else if (wc >= 0x2010 && wc < 0x2040) + c = cp1254_page20[wc-0x2010]; + else if (wc == 0x20ac) + c = 0x80; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1255.h b/libs/libiconv/lib/cp1255.h new file mode 100644 index 00000000..e7761aeb --- /dev/null +++ b/libs/libiconv/lib/cp1255.h @@ -0,0 +1,380 @@ +/* + * Copyright (C) 1999-2001, 2004 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1255 + */ + +#include "flushwc.h" + +/* Combining characters used in Hebrew encoding CP1255. */ + +/* Relevant combining characters: + 0x05b4, 0x05b7, 0x05b8, 0x05b9, 0x05bc, 0x05bf, 0x05c1, 0x05c2. */ + +/* Composition tables for each of the relevant combining characters. */ +static const struct { unsigned short base; unsigned short composed; } cp1255_comp_table_data[] = { +#define cp1255_comp_table05b4_idx 0 +#define cp1255_comp_table05b4_len 1 + { 0x05D9, 0xFB1D }, +#define cp1255_comp_table05b7_idx (cp1255_comp_table05b4_idx+cp1255_comp_table05b4_len) +#define cp1255_comp_table05b7_len 2 + { 0x05D0, 0xFB2E }, + { 0x05F2, 0xFB1F }, +#define cp1255_comp_table05b8_idx (cp1255_comp_table05b7_idx+cp1255_comp_table05b7_len) +#define cp1255_comp_table05b8_len 1 + { 0x05D0, 0xFB2F }, +#define cp1255_comp_table05b9_idx (cp1255_comp_table05b8_idx+cp1255_comp_table05b8_len) +#define cp1255_comp_table05b9_len 1 + { 0x05D5, 0xFB4B }, +#define cp1255_comp_table05bc_idx (cp1255_comp_table05b9_idx+cp1255_comp_table05b9_len) +#define cp1255_comp_table05bc_len 24 + { 0x05D0, 0xFB30 }, + { 0x05D1, 0xFB31 }, + { 0x05D2, 0xFB32 }, + { 0x05D3, 0xFB33 }, + { 0x05D4, 0xFB34 }, + { 0x05D5, 0xFB35 }, + { 0x05D6, 0xFB36 }, + { 0x05D8, 0xFB38 }, + { 0x05D9, 0xFB39 }, + { 0x05DA, 0xFB3A }, + { 0x05DB, 0xFB3B }, + { 0x05DC, 0xFB3C }, + { 0x05DE, 0xFB3E }, + { 0x05E0, 0xFB40 }, + { 0x05E1, 0xFB41 }, + { 0x05E3, 0xFB43 }, + { 0x05E4, 0xFB44 }, + { 0x05E6, 0xFB46 }, + { 0x05E7, 0xFB47 }, + { 0x05E8, 0xFB48 }, + { 0x05E9, 0xFB49 }, + { 0x05EA, 0xFB4A }, + { 0xFB2A, 0xFB2C }, + { 0xFB2B, 0xFB2D }, +#define cp1255_comp_table05bf_idx (cp1255_comp_table05bc_idx+cp1255_comp_table05bc_len) +#define cp1255_comp_table05bf_len 3 + { 0x05D1, 0xFB4C }, + { 0x05DB, 0xFB4D }, + { 0x05E4, 0xFB4E }, +#define cp1255_comp_table05c1_idx (cp1255_comp_table05bf_idx+cp1255_comp_table05bf_len) +#define cp1255_comp_table05c1_len 2 + { 0x05E9, 0xFB2A }, + { 0xFB49, 0xFB2C }, +#define cp1255_comp_table05c2_idx (cp1255_comp_table05c1_idx+cp1255_comp_table05c1_len) +#define cp1255_comp_table05c2_len 2 + { 0x05E9, 0xFB2B }, + { 0xFB49, 0xFB2D }, +}; +static const struct { unsigned int len; unsigned int idx; } cp1255_comp_table[] = { + { cp1255_comp_table05b4_len, cp1255_comp_table05b4_idx }, + { cp1255_comp_table05b7_len, cp1255_comp_table05b7_idx }, + { cp1255_comp_table05b8_len, cp1255_comp_table05b8_idx }, + { cp1255_comp_table05b9_len, cp1255_comp_table05b9_idx }, + { cp1255_comp_table05bc_len, cp1255_comp_table05bc_idx }, + { cp1255_comp_table05bf_len, cp1255_comp_table05bf_idx }, + { cp1255_comp_table05c1_len, cp1255_comp_table05c1_idx }, + { cp1255_comp_table05c2_len, cp1255_comp_table05c2_idx }, +}; + +/* Decomposition table for the relevant Unicode characters. */ +struct cp1255_decomp { unsigned short composed; unsigned short base; int comb1 : 8; signed int comb2 : 8; }; +static const struct cp1255_decomp cp1255_decomp_table[] = { + { 0xFB1D, 0x05D9, 0, -1 }, + { 0xFB1F, 0x05F2, 1, -1 }, + { 0xFB2A, 0x05E9, 6, -1 }, + { 0xFB2B, 0x05E9, 7, -1 }, + { 0xFB2C, 0x05E9, 4, 6 }, + { 0xFB2D, 0x05E9, 4, 7 }, + { 0xFB2E, 0x05D0, 1, -1 }, + { 0xFB2F, 0x05D0, 2, -1 }, + { 0xFB30, 0x05D0, 4, -1 }, + { 0xFB31, 0x05D1, 4, -1 }, + { 0xFB32, 0x05D2, 4, -1 }, + { 0xFB33, 0x05D3, 4, -1 }, + { 0xFB34, 0x05D4, 4, -1 }, + { 0xFB35, 0x05D5, 4, -1 }, + { 0xFB36, 0x05D6, 4, -1 }, + { 0xFB38, 0x05D8, 4, -1 }, + { 0xFB39, 0x05D9, 4, -1 }, + { 0xFB3A, 0x05DA, 4, -1 }, + { 0xFB3B, 0x05DB, 4, -1 }, + { 0xFB3C, 0x05DC, 4, -1 }, + { 0xFB3E, 0x05DE, 4, -1 }, + { 0xFB40, 0x05E0, 4, -1 }, + { 0xFB41, 0x05E1, 4, -1 }, + { 0xFB43, 0x05E3, 4, -1 }, + { 0xFB44, 0x05E4, 4, -1 }, + { 0xFB46, 0x05E6, 4, -1 }, + { 0xFB47, 0x05E7, 4, -1 }, + { 0xFB48, 0x05E8, 4, -1 }, + { 0xFB49, 0x05E9, 4, -1 }, + { 0xFB4A, 0x05EA, 4, -1 }, + { 0xFB4B, 0x05D5, 3, -1 }, + { 0xFB4C, 0x05D1, 5, -1 }, + { 0xFB4D, 0x05DB, 5, -1 }, + { 0xFB4E, 0x05E4, 5, -1 }, +}; + +static const unsigned char cp1255_comb_table[] = { + 0xc4, 0xc7, 0xc8, 0xc9, 0xcc, 0xcf, 0xd1, 0xd2, +}; + +static const unsigned short cp1255_2uni[128] = { + /* 0x80 */ + 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0xfffd, 0x2039, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x90 */ + 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0xfffd, 0x203a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xa0 */ + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20aa, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + /* 0xc0 */ + 0x05b0, 0x05b1, 0x05b2, 0x05b3, 0x05b4, 0x05b5, 0x05b6, 0x05b7, + 0x05b8, 0x05b9, 0xfffd, 0x05bb, 0x05bc, 0x05bd, 0x05be, 0x05bf, + /* 0xd0 */ + 0x05c0, 0x05c1, 0x05c2, 0x05c3, 0x05f0, 0x05f1, 0x05f2, 0x05f3, + 0x05f4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xe0 */ + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + /* 0xf0 */ + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, 0xfffd, 0xfffd, 0x200e, 0x200f, 0xfffd, +}; + +/* In the CP1255 to Unicode direction, the state contains a buffered + character, or 0 if none. */ + +static int +cp1255_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + unsigned short wc; + unsigned short last_wc; + if (c < 0x80) { + wc = c; + } else { + wc = cp1255_2uni[c-0x80]; + if (wc == 0xfffd) + return RET_ILSEQ; + } + last_wc = conv->istate; + if (last_wc) { + if (wc >= 0x05b0 && wc < 0x05c5) { + /* See whether last_wc and wc can be combined. */ + unsigned int k; + unsigned int i1, i2; + switch (wc) { + case 0x05b4: k = 0; break; + case 0x05b7: k = 1; break; + case 0x05b8: k = 2; break; + case 0x05b9: k = 3; break; + case 0x05bc: k = 4; break; + case 0x05bf: k = 5; break; + case 0x05c1: k = 6; break; + case 0x05c2: k = 7; break; + default: goto not_combining; + } + i1 = cp1255_comp_table[k].idx; + i2 = i1 + cp1255_comp_table[k].len-1; + if (last_wc >= cp1255_comp_table_data[i1].base + && last_wc <= cp1255_comp_table_data[i2].base) { + unsigned int i; + for (;;) { + i = (i1+i2)>>1; + if (last_wc == cp1255_comp_table_data[i].base) + break; + if (last_wc < cp1255_comp_table_data[i].base) { + if (i1 == i) + goto not_combining; + i2 = i; + } else { + if (i1 != i) + i1 = i; + else { + i = i2; + if (last_wc == cp1255_comp_table_data[i].base) + break; + goto not_combining; + } + } + } + last_wc = cp1255_comp_table_data[i].composed; + if (last_wc == 0xfb2a || last_wc == 0xfb2b || last_wc == 0xfb49) { + /* Buffer the combined character. */ + conv->istate = last_wc; + return RET_TOOFEW(1); + } else { + /* Output the combined character. */ + conv->istate = 0; + *pwc = (ucs4_t) last_wc; + return 1; + } + } + } + not_combining: + /* Output the buffered character. */ + conv->istate = 0; + *pwc = (ucs4_t) last_wc; + return 0; /* Don't advance the input pointer. */ + } + if ((wc >= 0x05d0 && wc <= 0x05ea && ((0x07db5f7f >> (wc - 0x05d0)) & 1)) + || wc == 0x05f2) { + /* wc is a possible match in cp1255_comp_table_data. Buffer it. */ + conv->istate = wc; + return RET_TOOFEW(1); + } else { + /* Output wc immediately. */ + *pwc = (ucs4_t) wc; + return 1; + } +} + +#define cp1255_flushwc normal_flushwc + +static const unsigned char cp1255_page00[88] = { + 0xa0, 0xa1, 0xa2, 0xa3, 0x00, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, /* 0xf0-0xf7 */ +}; +static const unsigned char cp1255_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char cp1255_page05[72] = { + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xb0-0xb7 */ + 0xc8, 0xc9, 0x00, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xb8-0xbf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xd0-0xd7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xd8-0xdf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xe0-0xe7 */ + 0xf8, 0xf9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ +}; +static const unsigned char cp1255_page20[56] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xfe, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +cp1255_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00f8) + c = cp1255_page00[wc-0x00a0]; + else if (wc == 0x0192) + c = 0x83; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = cp1255_page02[wc-0x02c0]; + else if (wc >= 0x05b0 && wc < 0x05f8) + c = cp1255_page05[wc-0x05b0]; + else if (wc >= 0x2008 && wc < 0x2040) + c = cp1255_page20[wc-0x2008]; + else if (wc == 0x20aa) + c = 0xa4; + else if (wc == 0x20ac) + c = 0x80; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + /* Try canonical decomposition. */ + { + /* Binary search through cp1255_decomp_table. */ + unsigned int i1 = 0; + unsigned int i2 = sizeof(cp1255_decomp_table)/sizeof(cp1255_decomp_table[0])-1; + if (wc >= cp1255_decomp_table[i1].composed + && wc <= cp1255_decomp_table[i2].composed) { + unsigned int i; + for (;;) { + /* Here i2 - i1 > 0. */ + i = (i1+i2)>>1; + if (wc == cp1255_decomp_table[i].composed) + break; + if (wc < cp1255_decomp_table[i].composed) { + if (i1 == i) + return RET_ILUNI; + /* Here i1 < i < i2. */ + i2 = i; + } else { + /* Here i1 <= i < i2. */ + if (i1 != i) + i1 = i; + else { + /* Here i2 - i1 = 1. */ + i = i2; + if (wc == cp1255_decomp_table[i].composed) + break; + else + return RET_ILUNI; + } + } + } + /* Found a canonical decomposition. */ + wc = cp1255_decomp_table[i].base; + /* wc is one of 0x05d0..0x05d6, 0x05d8..0x05dc, 0x05de, 0x05e0..0x05e1, + 0x05e3..0x05e4, 0x05e6..0x05ea, 0x05f2. */ + c = cp1255_page05[wc-0x05b0]; + if (cp1255_decomp_table[i].comb2 < 0) { + if (n < 2) + return RET_TOOSMALL; + r[0] = c; + r[1] = cp1255_comb_table[cp1255_decomp_table[i].comb1]; + return 2; + } else { + if (n < 3) + return RET_TOOSMALL; + r[0] = c; + r[1] = cp1255_comb_table[cp1255_decomp_table[i].comb1]; + r[2] = cp1255_comb_table[cp1255_decomp_table[i].comb2]; + return 3; + } + } + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1256.h b/libs/libiconv/lib/cp1256.h new file mode 100644 index 00000000..3804e8f4 --- /dev/null +++ b/libs/libiconv/lib/cp1256.h @@ -0,0 +1,153 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1256 + */ + +static const unsigned short cp1256_2uni[128] = { + /* 0x80 */ + 0x20ac, 0x067e, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0679, 0x2039, 0x0152, 0x0686, 0x0698, 0x0688, + /* 0x90 */ + 0x06af, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x06a9, 0x2122, 0x0691, 0x203a, 0x0153, 0x200c, 0x200d, 0x06ba, + /* 0xa0 */ + 0x00a0, 0x060c, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x06be, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x061b, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x061f, + /* 0xc0 */ + 0x06c1, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, + /* 0xd0 */ + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x00d7, + 0x0637, 0x0638, 0x0639, 0x063a, 0x0640, 0x0641, 0x0642, 0x0643, + /* 0xe0 */ + 0x00e0, 0x0644, 0x00e2, 0x0645, 0x0646, 0x0647, 0x0648, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0649, 0x064a, 0x00ee, 0x00ef, + /* 0xf0 */ + 0x064b, 0x064c, 0x064d, 0x064e, 0x00f4, 0x064f, 0x0650, 0x00f7, + 0x0651, 0x00f9, 0x0652, 0x00fb, 0x00fc, 0x200e, 0x200f, 0x06d2, +}; + +static int +cp1256_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp1256_2uni[c-0x80]; + return 1; +} + +static const unsigned char cp1256_page00[96] = { + 0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd7, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0xe0, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0x00, 0x00, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0xf4, 0x00, 0x00, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0xf9, 0x00, 0xfb, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; +static const unsigned char cp1256_page01[72] = { + 0x00, 0x00, 0x8c, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char cp1256_page06[208] = { + 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0xbf, /* 0x18-0x1f */ + 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd8, /* 0x30-0x37 */ + 0xd9, 0xda, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0xdc, 0xdd, 0xde, 0xdf, 0xe1, 0xe3, 0xe4, 0xe5, /* 0x40-0x47 */ + 0xe6, 0xec, 0xed, 0xf0, 0xf1, 0xf2, 0xf3, 0xf5, /* 0x48-0x4f */ + 0xf6, 0xf8, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x81, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x00, /* 0x80-0x87 */ + 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x9f, 0x00, 0x00, 0x00, 0xaa, 0x00, /* 0xb8-0xbf */ + 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ +}; +static const unsigned char cp1256_page20[56] = { + 0x00, 0x00, 0x00, 0x00, 0x9d, 0x9e, 0xfd, 0xfe, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +cp1256_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = cp1256_page00[wc-0x00a0]; + else if (wc >= 0x0150 && wc < 0x0198) + c = cp1256_page01[wc-0x0150]; + else if (wc == 0x02c6) + c = 0x88; + else if (wc >= 0x0608 && wc < 0x06d8) + c = cp1256_page06[wc-0x0608]; + else if (wc >= 0x2008 && wc < 0x2040) + c = cp1256_page20[wc-0x2008]; + else if (wc == 0x20ac) + c = 0x80; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1257.h b/libs/libiconv/lib/cp1257.h new file mode 100644 index 00000000..0d8518e4 --- /dev/null +++ b/libs/libiconv/lib/cp1257.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1257 + */ + +static const unsigned short cp1257_2uni[128] = { + /* 0x80 */ + 0x20ac, 0xfffd, 0x201a, 0xfffd, 0x201e, 0x2026, 0x2020, 0x2021, + 0xfffd, 0x2030, 0xfffd, 0x2039, 0xfffd, 0x00a8, 0x02c7, 0x00b8, + /* 0x90 */ + 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0xfffd, 0x2122, 0xfffd, 0x203a, 0xfffd, 0x00af, 0x02db, 0xfffd, + /* 0xa0 */ + 0x00a0, 0xfffd, 0x00a2, 0x00a3, 0x00a4, 0xfffd, 0x00a6, 0x00a7, + 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, + /* 0xc0 */ + 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, + 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b, + /* 0xd0 */ + 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, + 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df, + /* 0xe0 */ + 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, + 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, + /* 0xf0 */ + 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, + 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x02d9, +}; + +static int +cp1257_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp1257_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp1257_page00[224] = { + 0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0x8d, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x9d, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x8f, 0xb9, 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0xc4, 0xc5, 0xaf, 0x00, /* 0xc0-0xc7 */ + 0x00, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xd3, 0x00, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xa8, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0xe4, 0xe5, 0xbf, 0x00, /* 0xe0-0xe7 */ + 0x00, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xf3, 0x00, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xb8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0xc2, 0xe2, 0x00, 0x00, 0xc0, 0xe0, 0xc3, 0xe3, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0xc7, 0xe7, 0x00, 0x00, 0xcb, 0xeb, /* 0x10-0x17 */ + 0xc6, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xcc, 0xec, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0xce, 0xee, 0x00, 0x00, 0xc1, 0xe1, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xed, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0xcf, 0xef, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0xd9, 0xf9, 0xd1, 0xf1, 0xd2, 0xf2, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf4, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xba, /* 0x50-0x57 */ + 0x00, 0x00, 0xda, 0xfa, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0xdb, 0xfb, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0xd8, 0xf8, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0xca, 0xea, 0xdd, 0xfd, 0xde, 0xfe, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char cp1257_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0xff, 0x00, 0x9e, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char cp1257_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +cp1257_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = cp1257_page00[wc-0x00a0]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = cp1257_page02[wc-0x02c0]; + else if (wc >= 0x2010 && wc < 0x2040) + c = cp1257_page20[wc-0x2010]; + else if (wc == 0x20ac) + c = 0x80; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp1258.h b/libs/libiconv/lib/cp1258.h new file mode 100644 index 00000000..57834048 --- /dev/null +++ b/libs/libiconv/lib/cp1258.h @@ -0,0 +1,288 @@ +/* + * Copyright (C) 1999-2001, 2004 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP1258 + */ + +#include "flushwc.h" +#include "vietcomb.h" + +static const unsigned char cp1258_comb_table[] = { + 0xcc, 0xec, 0xde, 0xd2, 0xf2, +}; + +/* The possible bases in viet_comp_table_data: + 0x0041..0x0045, 0x0047..0x0049, 0x004B..0x0050, 0x0052..0x0057, + 0x0059..0x005A, 0x0061..0x0065, 0x0067..0x0069, 0x006B..0x0070, + 0x0072..0x0077, 0x0079..0x007A, 0x00A5, 0x00A8, 0x00C2, 0x00C5..0x00C7, + 0x00CA, 0x00CF, 0x00D3..0x00D4, 0x00D6, 0x00D8, 0x00DA, 0x00DC, 0x00E2, + 0x00E5..0x00E7, 0x00EA, 0x00EF, 0x00F3..0x00F4, 0x00F6, 0x00F8, 0x00FA, + 0x00FC, 0x0102..0x0103, 0x01A0..0x01A1, 0x01AF..0x01B0. */ +static const unsigned int cp1258_comp_bases[] = { + 0x06fdfbbe, 0x06fdfbbe, 0x00000000, 0x00000120, 0x155884e4, 0x155884e4, + 0x0000000c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00018003 +}; + +static const unsigned short cp1258_2uni[128] = { + /* 0x80 */ + 0x20ac, 0xfffd, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0xfffd, 0x2039, 0x0152, 0xfffd, 0xfffd, 0xfffd, + /* 0x90 */ + 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0xfffd, 0x203a, 0x0153, 0xfffd, 0xfffd, 0x0178, + /* 0xa0 */ + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + /* 0xc0 */ + 0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x0300, 0x00cd, 0x00ce, 0x00cf, + /* 0xd0 */ + 0x0110, 0x00d1, 0x0309, 0x00d3, 0x00d4, 0x01a0, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x01af, 0x0303, 0x00df, + /* 0xe0 */ + 0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x0301, 0x00ed, 0x00ee, 0x00ef, + /* 0xf0 */ + 0x0111, 0x00f1, 0x0323, 0x00f3, 0x00f4, 0x01a1, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x01b0, 0x20ab, 0x00ff, +}; + +/* In the CP1258 to Unicode direction, the state contains a buffered + character, or 0 if none. */ + +static int +cp1258_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + unsigned short wc; + unsigned short last_wc; + if (c < 0x80) { + wc = c; + } else { + wc = cp1258_2uni[c-0x80]; + if (wc == 0xfffd) + return RET_ILSEQ; + } + last_wc = conv->istate; + if (last_wc) { + if (wc >= 0x0300 && wc < 0x0340) { + /* See whether last_wc and wc can be combined. */ + unsigned int k; + unsigned int i1, i2; + switch (wc) { + case 0x0300: k = 0; break; + case 0x0301: k = 1; break; + case 0x0303: k = 2; break; + case 0x0309: k = 3; break; + case 0x0323: k = 4; break; + default: abort(); + } + i1 = viet_comp_table[k].idx; + i2 = i1 + viet_comp_table[k].len-1; + if (last_wc >= viet_comp_table_data[i1].base + && last_wc <= viet_comp_table_data[i2].base) { + unsigned int i; + for (;;) { + i = (i1+i2)>>1; + if (last_wc == viet_comp_table_data[i].base) + break; + if (last_wc < viet_comp_table_data[i].base) { + if (i1 == i) + goto not_combining; + i2 = i; + } else { + if (i1 != i) + i1 = i; + else { + i = i2; + if (last_wc == viet_comp_table_data[i].base) + break; + goto not_combining; + } + } + } + last_wc = viet_comp_table_data[i].composed; + /* Output the combined character. */ + conv->istate = 0; + *pwc = (ucs4_t) last_wc; + return 1; + } + } + not_combining: + /* Output the buffered character. */ + conv->istate = 0; + *pwc = (ucs4_t) last_wc; + return 0; /* Don't advance the input pointer. */ + } + if (wc >= 0x0041 && wc <= 0x01b0 + && ((cp1258_comp_bases[(wc - 0x0040) >> 5] >> (wc & 0x1f)) & 1)) { + /* wc is a possible match in viet_comp_table_data. Buffer it. */ + conv->istate = wc; + return RET_TOOFEW(1); + } else { + /* Output wc immediately. */ + *pwc = (ucs4_t) wc; + return 1; + } +} + +#define cp1258_flushwc normal_flushwc + +static const unsigned char cp1258_page00[88] = { + 0xc0, 0xc1, 0xc2, 0x00, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0x00, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0xd1, 0x00, 0xd3, 0xd4, 0x00, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0x00, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0x00, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0xf1, 0x00, 0xf3, 0xf4, 0x00, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0xff, /* 0xf8-0xff */ + /* 0x0100 */ + 0x00, 0x00, 0xc3, 0xe3, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ +}; +static const unsigned char cp1258_page01[104] = { + 0x00, 0x00, 0x8c, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xd5, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, /* 0xa8-0xaf */ + 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ +}; +static const unsigned char cp1258_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char cp1258_page03[40] = { + 0xcc, 0xec, 0x00, 0xde, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0xf2, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char cp1258_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +cp1258_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = wc; + else if (wc >= 0x00c0 && wc < 0x0118) + c = cp1258_page00[wc-0x00c0]; + else if (wc >= 0x0150 && wc < 0x01b8) + c = cp1258_page01[wc-0x0150]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = cp1258_page02[wc-0x02c0]; + else if (wc >= 0x0300 && wc < 0x0328) + c = cp1258_page03[wc-0x0300]; + else if (wc >= 0x0340 && wc < 0x0342) /* deprecated Vietnamese tone marks */ + c = cp1258_page03[wc-0x0340]; + else if (wc >= 0x2010 && wc < 0x2040) + c = cp1258_page20[wc-0x2010]; + else if (wc == 0x20ab) + c = 0xfe; + else if (wc == 0x20ac) + c = 0x80; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + /* Try canonical decomposition. */ + { + /* Binary search through viet_decomp_table. */ + unsigned int i1 = 0; + unsigned int i2 = sizeof(viet_decomp_table)/sizeof(viet_decomp_table[0])-1; + if (wc >= viet_decomp_table[i1].composed + && wc <= viet_decomp_table[i2].composed) { + unsigned int i; + for (;;) { + /* Here i2 - i1 > 0. */ + i = (i1+i2)>>1; + if (wc == viet_decomp_table[i].composed) + break; + if (wc < viet_decomp_table[i].composed) { + if (i1 == i) + return RET_ILUNI; + /* Here i1 < i < i2. */ + i2 = i; + } else { + /* Here i1 <= i < i2. */ + if (i1 != i) + i1 = i; + else { + /* Here i2 - i1 = 1. */ + i = i2; + if (wc == viet_decomp_table[i].composed) + break; + else + return RET_ILUNI; + } + } + } + /* Found a canonical decomposition. */ + wc = viet_decomp_table[i].base; + /* wc is one of 0x0020, 0x0041..0x005a, 0x0061..0x007a, 0x00a5, 0x00a8, + 0x00c2, 0x00c5..0x00c7, 0x00ca, 0x00cf, 0x00d3, 0x00d4, 0x00d6, + 0x00d8, 0x00da, 0x00dc, 0x00e2, 0x00e5..0x00e7, 0x00ea, 0x00ef, + 0x00f3, 0x00f4, 0x00f6, 0x00f8, 0x00fc, 0x0102, 0x0103, 0x01a0, + 0x01a1, 0x01af, 0x01b0. */ + if (wc < 0x0100) + c = wc; + else if (wc < 0x0118) + c = cp1258_page00[wc-0x00c0]; + else + c = cp1258_page01[wc-0x0150]; + if (n < 2) + return RET_TOOSMALL; + r[0] = c; + r[1] = cp1258_comb_table[viet_decomp_table[i].comb1]; + return 2; + } + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp437.h b/libs/libiconv/lib/cp437.h new file mode 100644 index 00000000..a3c8e685 --- /dev/null +++ b/libs/libiconv/lib/cp437.h @@ -0,0 +1,156 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP437 + */ + +static const unsigned short cp437_2uni[128] = { + /* 0x80 */ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + /* 0x90 */ + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, + /* 0xa0 */ + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + /* 0xd0 */ + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + /* 0xe0 */ + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + /* 0xf0 */ + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0, +}; + +static int +cp437_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp437_2uni[c-0x80]; + return 1; +} + +static const unsigned char cp437_page00[96] = { + 0xff, 0xad, 0x9b, 0x9c, 0x00, 0x9d, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0xa6, 0xae, 0xaa, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0xe6, 0x00, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0x00, 0xa7, 0xaf, 0xac, 0xab, 0x00, 0xa8, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x8e, 0x8f, 0x92, 0x80, /* 0xc0-0xc7 */ + 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0x00, 0x84, 0x86, 0x91, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b, /* 0xe8-0xef */ + 0x00, 0xa4, 0x95, 0xa2, 0x93, 0x00, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x00, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0x98, /* 0xf8-0xff */ +}; +static const unsigned char cp437_page03[56] = { + 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe8, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0xe0, 0x00, 0x00, 0xeb, 0xee, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */ +}; +static const unsigned char cp437_page22[80] = { + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xec, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ +}; +static const unsigned char cp437_page23[24] = { + 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char cp437_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp437_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = cp437_page00[wc-0x00a0]; + else if (wc == 0x0192) + c = 0x9f; + else if (wc >= 0x0390 && wc < 0x03c8) + c = cp437_page03[wc-0x0390]; + else if (wc == 0x207f) + c = 0xfc; + else if (wc == 0x20a7) + c = 0x9e; + else if (wc >= 0x2218 && wc < 0x2268) + c = cp437_page22[wc-0x2218]; + else if (wc >= 0x2310 && wc < 0x2328) + c = cp437_page23[wc-0x2310]; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp437_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp737.h b/libs/libiconv/lib/cp737.h new file mode 100644 index 00000000..955e458d --- /dev/null +++ b/libs/libiconv/lib/cp737.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP737 + */ + +static const unsigned short cp737_2uni[128] = { + /* 0x80 */ + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, + /* 0x90 */ + 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, + 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, + /* 0xa0 */ + 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, + 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + /* 0xd0 */ + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + /* 0xe0 */ + 0x03c9, 0x03ac, 0x03ad, 0x03ae, 0x03ca, 0x03af, 0x03cc, 0x03cd, + 0x03cb, 0x03ce, 0x0386, 0x0388, 0x0389, 0x038a, 0x038c, 0x038e, + /* 0xf0 */ + 0x038f, 0x00b1, 0x2265, 0x2264, 0x03aa, 0x03ab, 0x00f7, 0x2248, + 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0, +}; + +static int +cp737_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp737_2uni[c-0x80]; + return 1; +} + +static const unsigned char cp737_page00[24] = { + 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0x00, 0x00, 0xfa, /* 0xb0-0xb7 */ +}; +static const unsigned char cp737_page03[80] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xea, 0x00, /* 0x80-0x87 */ + 0xeb, 0xec, 0xed, 0x00, 0xee, 0x00, 0xef, 0xf0, /* 0x88-0x8f */ + 0x00, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, /* 0x90-0x97 */ + 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, /* 0x98-0x9f */ + 0x8f, 0x90, 0x00, 0x91, 0x92, 0x93, 0x94, 0x95, /* 0xa0-0xa7 */ + 0x96, 0x97, 0xf4, 0xf5, 0xe1, 0xe2, 0xe3, 0xe5, /* 0xa8-0xaf */ + 0x00, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, /* 0xb0-0xb7 */ + 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, /* 0xb8-0xbf */ + 0xa7, 0xa8, 0xaa, 0xa9, 0xab, 0xac, 0xad, 0xae, /* 0xc0-0xc7 */ + 0xaf, 0xe0, 0xe4, 0xe8, 0xe6, 0xe7, 0xe9, 0x00, /* 0xc8-0xcf */ +}; +static const unsigned char cp737_page22[80] = { + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ +}; +static const unsigned char cp737_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp737_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00b8) + c = cp737_page00[wc-0x00a0]; + else if (wc == 0x00f7) + c = 0xf6; + else if (wc >= 0x0380 && wc < 0x03d0) + c = cp737_page03[wc-0x0380]; + else if (wc == 0x207f) + c = 0xfc; + else if (wc >= 0x2218 && wc < 0x2268) + c = cp737_page22[wc-0x2218]; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp737_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp775.h b/libs/libiconv/lib/cp775.h new file mode 100644 index 00000000..b9a5a5c4 --- /dev/null +++ b/libs/libiconv/lib/cp775.h @@ -0,0 +1,142 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP775 + */ + +static const unsigned short cp775_2uni[128] = { + /* 0x80 */ + 0x0106, 0x00fc, 0x00e9, 0x0101, 0x00e4, 0x0123, 0x00e5, 0x0107, + 0x0142, 0x0113, 0x0156, 0x0157, 0x012b, 0x0179, 0x00c4, 0x00c5, + /* 0x90 */ + 0x00c9, 0x00e6, 0x00c6, 0x014d, 0x00f6, 0x0122, 0x00a2, 0x015a, + 0x015b, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x00a4, + /* 0xa0 */ + 0x0100, 0x012a, 0x00f3, 0x017b, 0x017c, 0x017a, 0x201d, 0x00a6, + 0x00a9, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x0141, 0x00ab, 0x00bb, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0104, 0x010c, 0x0118, + 0x0116, 0x2563, 0x2551, 0x2557, 0x255d, 0x012e, 0x0160, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x0172, 0x016a, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x017d, + /* 0xd0 */ + 0x0105, 0x010d, 0x0119, 0x0117, 0x012f, 0x0161, 0x0173, 0x016b, + 0x017e, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + /* 0xe0 */ + 0x00d3, 0x00df, 0x014c, 0x0143, 0x00f5, 0x00d5, 0x00b5, 0x0144, + 0x0136, 0x0137, 0x013b, 0x013c, 0x0146, 0x0112, 0x0145, 0x2019, + /* 0xf0 */ + 0x00ad, 0x00b1, 0x201c, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x201e, + 0x00b0, 0x2219, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0, +}; + +static int +cp775_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp775_2uni[c-0x80]; + return 1; +} + +static const unsigned char cp775_page00[224] = { + 0xff, 0x00, 0x96, 0x9c, 0x9f, 0x00, 0xa7, 0xf5, /* 0xa0-0xa7 */ + 0x00, 0xa8, 0x00, 0xae, 0xaa, 0xf0, 0xa9, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0xfc, 0x00, 0xe6, 0xf4, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0xfb, 0x00, 0xaf, 0xac, 0xab, 0xf3, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x8e, 0x8f, 0x92, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xe0, 0x00, 0xe5, 0x99, 0x9e, /* 0xd0-0xd7 */ + 0x9d, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x84, 0x86, 0x91, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xa2, 0x00, 0xe4, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x9b, 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0xa0, 0x83, 0x00, 0x00, 0xb5, 0xd0, 0x80, 0x87, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xb6, 0xd1, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0xed, 0x89, 0x00, 0x00, 0xb8, 0xd3, /* 0x10-0x17 */ + 0xb7, 0xd2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x95, 0x85, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0xa1, 0x8c, 0x00, 0x00, 0xbd, 0xd4, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0xe9, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0xea, 0xeb, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0xad, 0x88, 0xe3, 0xe7, 0xee, 0xec, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0xe2, 0x93, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8a, 0x8b, /* 0x50-0x57 */ + 0x00, 0x00, 0x97, 0x98, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xbe, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0xc7, 0xd7, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0xc6, 0xd6, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x8d, 0xa5, 0xa3, 0xa4, 0xcf, 0xd8, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char cp775_page20[8] = { + 0x00, 0xef, 0x00, 0x00, 0xf2, 0xa6, 0xf7, 0x00, /* 0x18-0x1f */ +}; +static const unsigned char cp775_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb, /* 0x50-0x57 */ + 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00, /* 0x58-0x5f */ + 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00, /* 0x60-0x67 */ + 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp775_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = cp775_page00[wc-0x00a0]; + else if (wc >= 0x2018 && wc < 0x2020) + c = cp775_page20[wc-0x2018]; + else if (wc == 0x2219) + c = 0xf9; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp775_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp850.h b/libs/libiconv/lib/cp850.h new file mode 100644 index 00000000..25acfee1 --- /dev/null +++ b/libs/libiconv/lib/cp850.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP850 + */ + +static const unsigned short cp850_2uni[128] = { + /* 0x80 */ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + /* 0x90 */ + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x00d7, 0x0192, + /* 0xa0 */ + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, + 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + /* 0xd0 */ + 0x00f0, 0x00d0, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce, + 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, + /* 0xe0 */ + 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0x00fe, + 0x00de, 0x00da, 0x00db, 0x00d9, 0x00fd, 0x00dd, 0x00af, 0x00b4, + /* 0xf0 */ + 0x00ad, 0x00b1, 0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, + 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0, +}; + +static int +cp850_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp850_2uni[c-0x80]; + return 1; +} + +static const unsigned char cp850_page00[96] = { + 0xff, 0xad, 0xbd, 0x9c, 0xcf, 0xbe, 0xdd, 0xf5, /* 0xa0-0xa7 */ + 0xf9, 0xb8, 0xa6, 0xae, 0xaa, 0xf0, 0xa9, 0xee, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0xfc, 0xef, 0xe6, 0xf4, 0xfa, /* 0xb0-0xb7 */ + 0xf7, 0xfb, 0xa7, 0xaf, 0xac, 0xab, 0xf3, 0xa8, /* 0xb8-0xbf */ + 0xb7, 0xb5, 0xb6, 0xc7, 0x8e, 0x8f, 0x92, 0x80, /* 0xc0-0xc7 */ + 0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8, /* 0xc8-0xcf */ + 0xd1, 0xa5, 0xe3, 0xe0, 0xe2, 0xe5, 0x99, 0x9e, /* 0xd0-0xd7 */ + 0x9d, 0xeb, 0xe9, 0xea, 0x9a, 0xed, 0xe8, 0xe1, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0xc6, 0x84, 0x86, 0x91, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b, /* 0xe8-0xef */ + 0xd0, 0xa4, 0x95, 0xa2, 0x93, 0xe4, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x9b, 0x97, 0xa3, 0x96, 0x81, 0xec, 0xe7, 0x98, /* 0xf8-0xff */ +}; +static const unsigned char cp850_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb, /* 0x50-0x57 */ + 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00, /* 0x58-0x5f */ + 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00, /* 0x60-0x67 */ + 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp850_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = cp850_page00[wc-0x00a0]; + else if (wc == 0x0131) + c = 0xd5; + else if (wc == 0x0192) + c = 0x9f; + else if (wc == 0x2017) + c = 0xf2; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp850_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp852.h b/libs/libiconv/lib/cp852.h new file mode 100644 index 00000000..fac7a63f --- /dev/null +++ b/libs/libiconv/lib/cp852.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP852 + */ + +static const unsigned short cp852_2uni[128] = { + /* 0x80 */ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x016f, 0x0107, 0x00e7, + 0x0142, 0x00eb, 0x0150, 0x0151, 0x00ee, 0x0179, 0x00c4, 0x0106, + /* 0x90 */ + 0x00c9, 0x0139, 0x013a, 0x00f4, 0x00f6, 0x013d, 0x013e, 0x015a, + 0x015b, 0x00d6, 0x00dc, 0x0164, 0x0165, 0x0141, 0x00d7, 0x010d, + /* 0xa0 */ + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x0104, 0x0105, 0x017d, 0x017e, + 0x0118, 0x0119, 0x00ac, 0x017a, 0x010c, 0x015f, 0x00ab, 0x00bb, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x011a, + 0x015e, 0x2563, 0x2551, 0x2557, 0x255d, 0x017b, 0x017c, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x0102, 0x0103, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + /* 0xd0 */ + 0x0111, 0x0110, 0x010e, 0x00cb, 0x010f, 0x0147, 0x00cd, 0x00ce, + 0x011b, 0x2518, 0x250c, 0x2588, 0x2584, 0x0162, 0x016e, 0x2580, + /* 0xe0 */ + 0x00d3, 0x00df, 0x00d4, 0x0143, 0x0144, 0x0148, 0x0160, 0x0161, + 0x0154, 0x00da, 0x0155, 0x0170, 0x00fd, 0x00dd, 0x0163, 0x00b4, + /* 0xf0 */ + 0x00ad, 0x02dd, 0x02db, 0x02c7, 0x02d8, 0x00a7, 0x00f7, 0x00b8, + 0x00b0, 0x00a8, 0x02d9, 0x0171, 0x0158, 0x0159, 0x25a0, 0x00a0, +}; + +static int +cp852_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp852_2uni[c-0x80]; + return 1; +} + +static const unsigned char cp852_page00[224] = { + 0xff, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0xf5, /* 0xa0-0xa7 */ + 0xf9, 0x00, 0x00, 0xae, 0xaa, 0xf0, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0x00, 0x00, 0x00, 0xef, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0xf7, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0xb5, 0xb6, 0x00, 0x8e, 0x00, 0x00, 0x80, /* 0xc0-0xc7 */ + 0x00, 0x90, 0x00, 0xd3, 0x00, 0xd6, 0xd7, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xe0, 0xe2, 0x00, 0x99, 0x9e, /* 0xd0-0xd7 */ + 0x00, 0x00, 0xe9, 0x00, 0x9a, 0xed, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x00, 0xa0, 0x83, 0x00, 0x84, 0x00, 0x00, 0x87, /* 0xe0-0xe7 */ + 0x00, 0x82, 0x00, 0x89, 0x00, 0xa1, 0x8c, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xa2, 0x93, 0x00, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x00, 0x00, 0xa3, 0x00, 0x81, 0xec, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0x00, 0x00, 0xc6, 0xc7, 0xa4, 0xa5, 0x8f, 0x86, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xac, 0x9f, 0xd2, 0xd4, /* 0x08-0x0f */ + 0xd1, 0xd0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xa8, 0xa9, 0xb7, 0xd8, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x91, 0x92, 0x00, 0x00, 0x95, 0x96, 0x00, /* 0x38-0x3f */ + 0x00, 0x9d, 0x88, 0xe3, 0xe4, 0x00, 0x00, 0xd5, /* 0x40-0x47 */ + 0xe5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x8a, 0x8b, 0x00, 0x00, 0xe8, 0xea, 0x00, 0x00, /* 0x50-0x57 */ + 0xfc, 0xfd, 0x97, 0x98, 0x00, 0x00, 0xb8, 0xad, /* 0x58-0x5f */ + 0xe6, 0xe7, 0xdd, 0xee, 0x9b, 0x9c, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0x85, /* 0x68-0x6f */ + 0xeb, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x8d, 0xab, 0xbd, 0xbe, 0xa6, 0xa7, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char cp852_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xf4, 0xfa, 0x00, 0xf2, 0x00, 0xf1, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char cp852_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb, /* 0x50-0x57 */ + 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00, /* 0x58-0x5f */ + 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00, /* 0x60-0x67 */ + 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp852_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = cp852_page00[wc-0x00a0]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = cp852_page02[wc-0x02c0]; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp852_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp853.h b/libs/libiconv/lib/cp853.h new file mode 100644 index 00000000..fe82ae98 --- /dev/null +++ b/libs/libiconv/lib/cp853.h @@ -0,0 +1,151 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP853 + */ + +static const unsigned short cp853_2uni[128] = { + /* 0x80 */ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x0109, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x0108, + /* 0x90 */ + 0x00c9, 0x010b, 0x010a, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x0130, 0x00d6, 0x00dc, 0x011d, 0x00a3, 0x011c, 0x00d7, 0x0135, + /* 0xa0 */ + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x011e, 0x011f, + 0x0124, 0x0125, 0xfffd, 0x00bd, 0x0134, 0x015f, 0x00ab, 0x00bb, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, + 0x015e, 0x2563, 0x2551, 0x2557, 0x255d, 0x017b, 0x017c, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x015c, 0x015d, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + /* 0xd0 */ + 0xfffd, 0xfffd, 0x00ca, 0x00cb, 0x00c8, 0x0131, 0x00cd, 0x00ce, + 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0xfffd, 0x00cc, 0x2580, + /* 0xe0 */ + 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x0120, 0x0121, 0x00b5, 0x0126, + 0x0127, 0x00da, 0x00db, 0x00d9, 0x016c, 0x016d, 0xfffd, 0x00b4, + /* 0xf0 */ + 0x00ad, 0xfffd, 0x2113, 0x0149, 0x02d8, 0x00a7, 0x00f7, 0x00b8, + 0x00b0, 0x00a8, 0x02d9, 0xfffd, 0x00b3, 0x00b2, 0x25a0, 0x00a0, +}; + +static int +cp853_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp853_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp853_page00[96] = { + 0xff, 0x00, 0x00, 0x9c, 0xcf, 0x00, 0x00, 0xf5, /* 0xa0-0xa7 */ + 0xf9, 0x00, 0x00, 0xae, 0x00, 0xf0, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0x00, 0xfd, 0xfc, 0xef, 0xe6, 0x00, 0x00, /* 0xb0-0xb7 */ + 0xf7, 0x00, 0x00, 0xaf, 0x00, 0xab, 0x00, 0x00, /* 0xb8-0xbf */ + 0xb7, 0xb5, 0xb6, 0x00, 0x8e, 0x00, 0x00, 0x80, /* 0xc0-0xc7 */ + 0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8, /* 0xc8-0xcf */ + 0x00, 0xa5, 0xe3, 0xe0, 0xe2, 0x00, 0x99, 0x9e, /* 0xd0-0xd7 */ + 0x00, 0xeb, 0xe9, 0xea, 0x9a, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0x00, 0x84, 0x00, 0x00, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b, /* 0xe8-0xef */ + 0x00, 0xa4, 0x95, 0xa2, 0x93, 0x00, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x00, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; +static const unsigned char cp853_page01[120] = { + 0x8f, 0x86, 0x92, 0x91, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x9d, 0x9b, 0xa6, 0xa7, /* 0x18-0x1f */ + 0xe4, 0xe5, 0x00, 0x00, 0xa8, 0xa9, 0xe7, 0xe8, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x98, 0xd5, 0x00, 0x00, 0xac, 0x9f, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc7, 0xb8, 0xad, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0xec, 0xed, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0xbd, 0xbe, 0x00, 0x00, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char cp853_page02[8] = { + 0xf4, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char cp853_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb, /* 0x50-0x57 */ + 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00, /* 0x58-0x5f */ + 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00, /* 0x60-0x67 */ + 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp853_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = cp853_page00[wc-0x00a0]; + else if (wc >= 0x0108 && wc < 0x0180) + c = cp853_page01[wc-0x0108]; + else if (wc >= 0x02d8 && wc < 0x02e0) + c = cp853_page02[wc-0x02d8]; + else if (wc == 0x2113) + c = 0xf2; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp853_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp855.h b/libs/libiconv/lib/cp855.h new file mode 100644 index 00000000..ddb8bf17 --- /dev/null +++ b/libs/libiconv/lib/cp855.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP855 + */ + +static const unsigned short cp855_2uni[128] = { + /* 0x80 */ + 0x0452, 0x0402, 0x0453, 0x0403, 0x0451, 0x0401, 0x0454, 0x0404, + 0x0455, 0x0405, 0x0456, 0x0406, 0x0457, 0x0407, 0x0458, 0x0408, + /* 0x90 */ + 0x0459, 0x0409, 0x045a, 0x040a, 0x045b, 0x040b, 0x045c, 0x040c, + 0x045e, 0x040e, 0x045f, 0x040f, 0x044e, 0x042e, 0x044a, 0x042a, + /* 0xa0 */ + 0x0430, 0x0410, 0x0431, 0x0411, 0x0446, 0x0426, 0x0434, 0x0414, + 0x0435, 0x0415, 0x0444, 0x0424, 0x0433, 0x0413, 0x00ab, 0x00bb, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x0445, 0x0425, 0x0438, + 0x0418, 0x2563, 0x2551, 0x2557, 0x255d, 0x0439, 0x0419, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x043a, 0x041a, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + /* 0xd0 */ + 0x043b, 0x041b, 0x043c, 0x041c, 0x043d, 0x041d, 0x043e, 0x041e, + 0x043f, 0x2518, 0x250c, 0x2588, 0x2584, 0x041f, 0x044f, 0x2580, + /* 0xe0 */ + 0x042f, 0x0440, 0x0420, 0x0441, 0x0421, 0x0442, 0x0422, 0x0443, + 0x0423, 0x0436, 0x0416, 0x0432, 0x0412, 0x044c, 0x042c, 0x2116, + /* 0xf0 */ + 0x00ad, 0x044b, 0x042b, 0x0437, 0x0417, 0x0448, 0x0428, 0x044d, + 0x042d, 0x0449, 0x0429, 0x0447, 0x0427, 0x00a7, 0x25a0, 0x00a0, +}; + +static int +cp855_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp855_2uni[c-0x80]; + return 1; +} + +static const unsigned char cp855_page00[32] = { + 0xff, 0x00, 0x00, 0x00, 0xcf, 0x00, 0x00, 0xfd, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0xae, 0x00, 0xf0, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char cp855_page04[96] = { + 0x00, 0x85, 0x81, 0x83, 0x87, 0x89, 0x8b, 0x8d, /* 0x00-0x07 */ + 0x8f, 0x91, 0x93, 0x95, 0x97, 0x00, 0x99, 0x9b, /* 0x08-0x0f */ + 0xa1, 0xa3, 0xec, 0xad, 0xa7, 0xa9, 0xea, 0xf4, /* 0x10-0x17 */ + 0xb8, 0xbe, 0xc7, 0xd1, 0xd3, 0xd5, 0xd7, 0xdd, /* 0x18-0x1f */ + 0xe2, 0xe4, 0xe6, 0xe8, 0xab, 0xb6, 0xa5, 0xfc, /* 0x20-0x27 */ + 0xf6, 0xfa, 0x9f, 0xf2, 0xee, 0xf8, 0x9d, 0xe0, /* 0x28-0x2f */ + 0xa0, 0xa2, 0xeb, 0xac, 0xa6, 0xa8, 0xe9, 0xf3, /* 0x30-0x37 */ + 0xb7, 0xbd, 0xc6, 0xd0, 0xd2, 0xd4, 0xd6, 0xd8, /* 0x38-0x3f */ + 0xe1, 0xe3, 0xe5, 0xe7, 0xaa, 0xb5, 0xa4, 0xfb, /* 0x40-0x47 */ + 0xf5, 0xf9, 0x9e, 0xf1, 0xed, 0xf7, 0x9c, 0xde, /* 0x48-0x4f */ + 0x00, 0x84, 0x80, 0x82, 0x86, 0x88, 0x8a, 0x8c, /* 0x50-0x57 */ + 0x8e, 0x90, 0x92, 0x94, 0x96, 0x00, 0x98, 0x9a, /* 0x58-0x5f */ +}; +static const unsigned char cp855_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb, /* 0x50-0x57 */ + 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00, /* 0x58-0x5f */ + 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00, /* 0x60-0x67 */ + 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp855_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = cp855_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x0460) + c = cp855_page04[wc-0x0400]; + else if (wc == 0x2116) + c = 0xef; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp855_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp856.h b/libs/libiconv/lib/cp856.h new file mode 100644 index 00000000..30ba80b3 --- /dev/null +++ b/libs/libiconv/lib/cp856.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP856 + */ + +static const unsigned short cp856_2uni[128] = { + /* 0x80 */ + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + /* 0x90 */ + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, 0xfffd, 0x00a3, 0xfffd, 0x00d7, 0xfffd, + /* 0xa0 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0xfffd, 0x00ab, 0x00bb, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0xfffd, 0xfffd, 0xfffd, + 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0xfffd, 0xfffd, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + /* 0xd0 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0xfffd, 0x2580, + /* 0xe0 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x00b5, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x00af, 0x00b4, + /* 0xf0 */ + 0x00ad, 0x00b1, 0x2017, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, + 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0, +}; + +static int +cp856_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp856_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp856_page00[88] = { + 0xff, 0x00, 0xbd, 0x9c, 0xcf, 0xbe, 0xdd, 0xf5, /* 0xa0-0xa7 */ + 0xf9, 0xb8, 0x00, 0xae, 0xaa, 0xf0, 0xa9, 0xee, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0xfc, 0xef, 0xe6, 0xf4, 0xfa, /* 0xb0-0xb7 */ + 0xf7, 0xfb, 0x00, 0xaf, 0xac, 0xab, 0xf3, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, /* 0xf0-0xf7 */ +}; +static const unsigned char cp856_page05[32] = { + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0xd0-0xd7 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0xd8-0xdf */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0xe0-0xe7 */ + 0x98, 0x99, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ +}; +static const unsigned char cp856_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb, /* 0x50-0x57 */ + 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00, /* 0x58-0x5f */ + 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00, /* 0x60-0x67 */ + 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp856_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00f8) + c = cp856_page00[wc-0x00a0]; + else if (wc >= 0x05d0 && wc < 0x05f0) + c = cp856_page05[wc-0x05d0]; + else if (wc == 0x2017) + c = 0xf2; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp856_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp857.h b/libs/libiconv/lib/cp857.h new file mode 100644 index 00000000..09de722d --- /dev/null +++ b/libs/libiconv/lib/cp857.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP857 + */ + +static const unsigned short cp857_2uni[128] = { + /* 0x80 */ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x0131, 0x00c4, 0x00c5, + /* 0x90 */ + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x0130, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x015e, 0x015f, + /* 0xa0 */ + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x011e, 0x011f, + 0x00bf, 0x00ae, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x00c1, 0x00c2, 0x00c0, + 0x00a9, 0x2563, 0x2551, 0x2557, 0x255d, 0x00a2, 0x00a5, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x00e3, 0x00c3, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x00a4, + /* 0xd0 */ + 0x00ba, 0x00aa, 0x00ca, 0x00cb, 0x00c8, 0xfffd, 0x00cd, 0x00ce, + 0x00cf, 0x2518, 0x250c, 0x2588, 0x2584, 0x00a6, 0x00cc, 0x2580, + /* 0xe0 */ + 0x00d3, 0x00df, 0x00d4, 0x00d2, 0x00f5, 0x00d5, 0x00b5, 0xfffd, + 0x00d7, 0x00da, 0x00db, 0x00d9, 0x00ec, 0x00ff, 0x00af, 0x00b4, + /* 0xf0 */ + 0x00ad, 0x00b1, 0xfffd, 0x00be, 0x00b6, 0x00a7, 0x00f7, 0x00b8, + 0x00b0, 0x00a8, 0x00b7, 0x00b9, 0x00b3, 0x00b2, 0x25a0, 0x00a0, +}; + +static int +cp857_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp857_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp857_page00[96] = { + 0xff, 0xad, 0xbd, 0x9c, 0xcf, 0xbe, 0xdd, 0xf5, /* 0xa0-0xa7 */ + 0xf9, 0xb8, 0xd1, 0xae, 0xaa, 0xf0, 0xa9, 0xee, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0xfc, 0xef, 0xe6, 0xf4, 0xfa, /* 0xb0-0xb7 */ + 0xf7, 0xfb, 0xd0, 0xaf, 0xac, 0xab, 0xf3, 0xa8, /* 0xb8-0xbf */ + 0xb7, 0xb5, 0xb6, 0xc7, 0x8e, 0x8f, 0x92, 0x80, /* 0xc0-0xc7 */ + 0xd4, 0x90, 0xd2, 0xd3, 0xde, 0xd6, 0xd7, 0xd8, /* 0xc8-0xcf */ + 0x00, 0xa5, 0xe3, 0xe0, 0xe2, 0xe5, 0x99, 0xe8, /* 0xd0-0xd7 */ + 0x9d, 0xeb, 0xe9, 0xea, 0x9a, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0xc6, 0x84, 0x86, 0x91, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0xec, 0xa1, 0x8c, 0x8b, /* 0xe8-0xef */ + 0x00, 0xa4, 0x95, 0xa2, 0x93, 0xe4, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x9b, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0xed, /* 0xf8-0xff */ +}; +static const unsigned char cp857_page01[72] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xa7, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x98, 0x8d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x9f, /* 0x58-0x5f */ +}; +static const unsigned char cp857_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb, /* 0x50-0x57 */ + 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00, /* 0x58-0x5f */ + 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00, /* 0x60-0x67 */ + 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp857_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = cp857_page00[wc-0x00a0]; + else if (wc >= 0x0118 && wc < 0x0160) + c = cp857_page01[wc-0x0118]; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp857_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp858.h b/libs/libiconv/lib/cp858.h new file mode 100644 index 00000000..dd26d0a2 --- /dev/null +++ b/libs/libiconv/lib/cp858.h @@ -0,0 +1,61 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP858 + */ + +static int +cp858_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else if (c == 0xd5) + *pwc = 0x20ac; + else + *pwc = (ucs4_t) cp850_2uni[c-0x80]; + return 1; +} + +static int +cp858_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = cp850_page00[wc-0x00a0]; + else if (wc == 0x0192) + c = 0x9f; + else if (wc == 0x2017) + c = 0xf2; + else if (wc == 0x20ac) + c = 0xd5; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp850_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp860.h b/libs/libiconv/lib/cp860.h new file mode 100644 index 00000000..2cca2f12 --- /dev/null +++ b/libs/libiconv/lib/cp860.h @@ -0,0 +1,149 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP860 + */ + +static const unsigned short cp860_2uni[128] = { + /* 0x80 */ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e3, 0x00e0, 0x00c1, 0x00e7, + 0x00ea, 0x00ca, 0x00e8, 0x00cd, 0x00d4, 0x00ec, 0x00c3, 0x00c2, + /* 0x90 */ + 0x00c9, 0x00c0, 0x00c8, 0x00f4, 0x00f5, 0x00f2, 0x00da, 0x00f9, + 0x00cc, 0x00d5, 0x00dc, 0x00a2, 0x00a3, 0x00d9, 0x20a7, 0x00d3, + /* 0xa0 */ + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x00d2, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + /* 0xd0 */ + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + /* 0xe0 */ + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + /* 0xf0 */ + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0, +}; + +static int +cp860_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp860_2uni[c-0x80]; + return 1; +} + +static const unsigned char cp860_page00[96] = { + 0xff, 0xad, 0x9b, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0xa6, 0xae, 0xaa, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0xe6, 0x00, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0x00, 0xa7, 0xaf, 0xac, 0xab, 0x00, 0xa8, /* 0xb8-0xbf */ + 0x91, 0x86, 0x8f, 0x8e, 0x00, 0x00, 0x00, 0x80, /* 0xc0-0xc7 */ + 0x92, 0x90, 0x89, 0x00, 0x98, 0x8b, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0xa5, 0xa9, 0x9f, 0x8c, 0x99, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x9d, 0x96, 0x00, 0x9a, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0x84, 0x00, 0x00, 0x00, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x00, 0x8d, 0xa1, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0xa4, 0x95, 0xa2, 0x93, 0x94, 0x00, 0xf6, /* 0xf0-0xf7 */ + 0x00, 0x97, 0xa3, 0x00, 0x81, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; +static const unsigned char cp860_page03[56] = { + 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe8, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0xe0, 0x00, 0x00, 0xeb, 0xee, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */ +}; +static const unsigned char cp860_page22[80] = { + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xec, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ +}; +static const unsigned char cp860_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp860_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = cp860_page00[wc-0x00a0]; + else if (wc >= 0x0390 && wc < 0x03c8) + c = cp860_page03[wc-0x0390]; + else if (wc == 0x207f) + c = 0xfc; + else if (wc == 0x20a7) + c = 0x9e; + else if (wc >= 0x2218 && wc < 0x2268) + c = cp860_page22[wc-0x2218]; + else if (wc >= 0x2320 && wc < 0x2322) + c = wc-0x222c; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp860_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp861.h b/libs/libiconv/lib/cp861.h new file mode 100644 index 00000000..07bcf5f2 --- /dev/null +++ b/libs/libiconv/lib/cp861.h @@ -0,0 +1,156 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP861 + */ + +static const unsigned short cp861_2uni[128] = { + /* 0x80 */ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00d0, 0x00f0, 0x00de, 0x00c4, 0x00c5, + /* 0x90 */ + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00fe, 0x00fb, 0x00dd, + 0x00fd, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x20a7, 0x0192, + /* 0xa0 */ + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00c1, 0x00cd, 0x00d3, 0x00da, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + /* 0xd0 */ + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + /* 0xe0 */ + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + /* 0xf0 */ + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0, +}; + +static int +cp861_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp861_2uni[c-0x80]; + return 1; +} + +static const unsigned char cp861_page00[96] = { + 0xff, 0xad, 0x00, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0xae, 0xaa, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0xe6, 0x00, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xaf, 0xac, 0xab, 0x00, 0xa8, /* 0xb8-0xbf */ + 0x00, 0xa4, 0x00, 0x00, 0x8e, 0x8f, 0x92, 0x80, /* 0xc0-0xc7 */ + 0x00, 0x90, 0x00, 0x00, 0x00, 0xa5, 0x00, 0x00, /* 0xc8-0xcf */ + 0x8b, 0x00, 0x00, 0xa6, 0x00, 0x00, 0x99, 0x00, /* 0xd0-0xd7 */ + 0x9d, 0x00, 0xa7, 0x00, 0x9a, 0x97, 0x8d, 0xe1, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0x00, 0x84, 0x86, 0x91, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0x00, 0xa1, 0x00, 0x00, /* 0xe8-0xef */ + 0x8c, 0x00, 0x00, 0xa2, 0x93, 0x00, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x9b, 0x00, 0xa3, 0x96, 0x81, 0x98, 0x95, 0x00, /* 0xf8-0xff */ +}; +static const unsigned char cp861_page03[56] = { + 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe8, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0xe0, 0x00, 0x00, 0xeb, 0xee, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */ +}; +static const unsigned char cp861_page22[80] = { + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xec, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ +}; +static const unsigned char cp861_page23[24] = { + 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char cp861_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp861_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = cp861_page00[wc-0x00a0]; + else if (wc == 0x0192) + c = 0x9f; + else if (wc >= 0x0390 && wc < 0x03c8) + c = cp861_page03[wc-0x0390]; + else if (wc == 0x207f) + c = 0xfc; + else if (wc == 0x20a7) + c = 0x9e; + else if (wc >= 0x2218 && wc < 0x2268) + c = cp861_page22[wc-0x2218]; + else if (wc >= 0x2310 && wc < 0x2328) + c = cp861_page23[wc-0x2310]; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp861_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp862.h b/libs/libiconv/lib/cp862.h new file mode 100644 index 00000000..623fc4d5 --- /dev/null +++ b/libs/libiconv/lib/cp862.h @@ -0,0 +1,155 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP862 + */ + +static const unsigned short cp862_2uni[128] = { + /* 0x80 */ + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + /* 0x90 */ + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192, + /* 0xa0 */ + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + /* 0xd0 */ + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + /* 0xe0 */ + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + /* 0xf0 */ + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0, +}; + +static int +cp862_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp862_2uni[c-0x80]; + return 1; +} + +static const unsigned char cp862_page00[96] = { + 0xff, 0xad, 0x9b, 0x9c, 0x00, 0x9d, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0xa6, 0xae, 0xaa, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0xe6, 0x00, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0x00, 0xa7, 0xaf, 0xac, 0xab, 0x00, 0xa8, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x00, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0xa4, 0x00, 0xa2, 0x00, 0x00, 0x00, 0xf6, /* 0xf0-0xf7 */ + 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; +static const unsigned char cp862_page03[56] = { + 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe8, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0xe0, 0x00, 0x00, 0xeb, 0xee, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */ +}; +static const unsigned char cp862_page22[80] = { + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xec, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ +}; +static const unsigned char cp862_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp862_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = cp862_page00[wc-0x00a0]; + else if (wc == 0x0192) + c = 0x9f; + else if (wc >= 0x0390 && wc < 0x03c8) + c = cp862_page03[wc-0x0390]; + else if (wc >= 0x05d0 && wc < 0x05eb) + c = wc-0x0550; + else if (wc == 0x207f) + c = 0xfc; + else if (wc == 0x20a7) + c = 0x9e; + else if (wc >= 0x2218 && wc < 0x2268) + c = cp862_page22[wc-0x2218]; + else if (wc == 0x2310) + c = 0xa9; + else if (wc >= 0x2320 && wc < 0x2322) + c = wc-0x222c; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp862_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp863.h b/libs/libiconv/lib/cp863.h new file mode 100644 index 00000000..5890ad42 --- /dev/null +++ b/libs/libiconv/lib/cp863.h @@ -0,0 +1,156 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP863 + */ + +static const unsigned short cp863_2uni[128] = { + /* 0x80 */ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00c2, 0x00e0, 0x00b6, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x2017, 0x00c0, 0x00a7, + /* 0x90 */ + 0x00c9, 0x00c8, 0x00ca, 0x00f4, 0x00cb, 0x00cf, 0x00fb, 0x00f9, + 0x00a4, 0x00d4, 0x00dc, 0x00a2, 0x00a3, 0x00d9, 0x00db, 0x0192, + /* 0xa0 */ + 0x00a6, 0x00b4, 0x00f3, 0x00fa, 0x00a8, 0x00b8, 0x00b3, 0x00af, + 0x00ce, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00be, 0x00ab, 0x00bb, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + /* 0xd0 */ + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + /* 0xe0 */ + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + /* 0xf0 */ + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0, +}; + +static int +cp863_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp863_2uni[c-0x80]; + return 1; +} + +static const unsigned char cp863_page00[96] = { + 0xff, 0x00, 0x9b, 0x9c, 0x98, 0x00, 0xa0, 0x8f, /* 0xa0-0xa7 */ + 0xa4, 0x00, 0x00, 0xae, 0xaa, 0x00, 0x00, 0xa7, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0xa6, 0xa1, 0xe6, 0x86, 0xfa, /* 0xb0-0xb7 */ + 0xa5, 0x00, 0x00, 0xaf, 0xac, 0xab, 0xad, 0x00, /* 0xb8-0xbf */ + 0x8e, 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x80, /* 0xc0-0xc7 */ + 0x91, 0x90, 0x92, 0x94, 0x00, 0x00, 0xa8, 0x95, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x9d, 0x00, 0x9e, 0x9a, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x85, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0x00, 0x00, 0x8c, 0x8b, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xa2, 0x93, 0x00, 0x00, 0xf6, /* 0xf0-0xf7 */ + 0x00, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; +static const unsigned char cp863_page03[56] = { + 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe8, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0xe0, 0x00, 0x00, 0xeb, 0xee, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */ +}; +static const unsigned char cp863_page22[80] = { + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xec, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ +}; +static const unsigned char cp863_page23[24] = { + 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char cp863_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp863_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = cp863_page00[wc-0x00a0]; + else if (wc == 0x0192) + c = 0x9f; + else if (wc >= 0x0390 && wc < 0x03c8) + c = cp863_page03[wc-0x0390]; + else if (wc == 0x2017) + c = 0x8d; + else if (wc == 0x207f) + c = 0xfc; + else if (wc >= 0x2218 && wc < 0x2268) + c = cp863_page22[wc-0x2218]; + else if (wc >= 0x2310 && wc < 0x2328) + c = cp863_page23[wc-0x2310]; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp863_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp864.h b/libs/libiconv/lib/cp864.h new file mode 100644 index 00000000..a1d8c4a2 --- /dev/null +++ b/libs/libiconv/lib/cp864.h @@ -0,0 +1,188 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP864 + */ + +static const unsigned short cp864_2uni_1[16] = { + /* 0x20 */ + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x066a, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, +}; +static const unsigned short cp864_2uni_2[128] = { + /* 0x80 */ + 0x00b0, 0x00b7, 0x2219, 0x221a, 0x2592, 0x2500, 0x2502, 0x253c, + 0x2524, 0x252c, 0x251c, 0x2534, 0x2510, 0x250c, 0x2514, 0x2518, + /* 0x90 */ + 0x03b2, 0x221e, 0x03c6, 0x00b1, 0x00bd, 0x00bc, 0x2248, 0x00ab, + 0x00bb, 0xfef7, 0xfef8, 0xfffd, 0xfffd, 0xfefb, 0xfefc, 0xfffd, + /* 0xa0 */ + 0x00a0, 0x00ad, 0xfe82, 0x00a3, 0x00a4, 0xfe84, 0xfffd, 0xfffd, + 0xfe8e, 0xfe8f, 0xfe95, 0xfe99, 0x060c, 0xfe9d, 0xfea1, 0xfea5, + /* 0xb0 */ + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, + 0x0668, 0x0669, 0xfed1, 0x061b, 0xfeb1, 0xfeb5, 0xfeb9, 0x061f, + /* 0xc0 */ + 0x00a2, 0xfe80, 0xfe81, 0xfe83, 0xfe85, 0xfeca, 0xfe8b, 0xfe8d, + 0xfe91, 0xfe93, 0xfe97, 0xfe9b, 0xfe9f, 0xfea3, 0xfea7, 0xfea9, + /* 0xd0 */ + 0xfeab, 0xfead, 0xfeaf, 0xfeb3, 0xfeb7, 0xfebb, 0xfebf, 0xfec1, + 0xfec5, 0xfecb, 0xfecf, 0x00a6, 0x00ac, 0x00f7, 0x00d7, 0xfec9, + /* 0xe0 */ + 0x0640, 0xfed3, 0xfed7, 0xfedb, 0xfedf, 0xfee3, 0xfee7, 0xfeeb, + 0xfeed, 0xfeef, 0xfef3, 0xfebd, 0xfecc, 0xfece, 0xfecd, 0xfee1, + /* 0xf0 */ + 0xfe7d, 0x0651, 0xfee5, 0xfee9, 0xfeec, 0xfef0, 0xfef2, 0xfed0, + 0xfed5, 0xfef5, 0xfef6, 0xfedd, 0xfed9, 0xfef1, 0x25a0, 0xfffd, +}; + +static int +cp864_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x20) { + *pwc = (ucs4_t) c; + return 1; + } + else if (c < 0x30) { + *pwc = (ucs4_t) cp864_2uni_1[c-0x20]; + return 1; + } + else if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp864_2uni_2[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp864_page00[8] = { + 0x20, 0x21, 0x22, 0x23, 0x24, 0x00, 0x26, 0x27, /* 0x20-0x27 */ +}; +static const unsigned char cp864_page00_1[88] = { + 0xa0, 0x00, 0xc0, 0xa3, 0xa4, 0x00, 0xdb, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x97, 0xdc, 0xa1, 0x00, 0x00, /* 0xa8-0xaf */ + 0x80, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x98, 0x95, 0x94, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdd, /* 0xf0-0xf7 */ +}; +static const unsigned char cp864_page06[104] = { + 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0xbf, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0xf1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x60-0x67 */ + 0xb8, 0xb9, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ +}; +static const unsigned char cp864_page22[56] = { + 0x00, 0x82, 0x83, 0x00, 0x00, 0x00, 0x91, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ +}; +static const unsigned char cp864_page25[64] = { + 0x85, 0x00, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x8d, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x8c, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x8f, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; +static const unsigned char cp864_pagefe[136] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, /* 0x78-0x7f */ + 0xc1, 0xc2, 0xa2, 0xc3, 0xa5, 0xc4, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc7, 0xa8, 0xa9, /* 0x88-0x8f */ + 0x00, 0xc8, 0x00, 0xc9, 0x00, 0xaa, 0x00, 0xca, /* 0x90-0x97 */ + 0x00, 0xab, 0x00, 0xcb, 0x00, 0xad, 0x00, 0xcc, /* 0x98-0x9f */ + 0x00, 0xae, 0x00, 0xcd, 0x00, 0xaf, 0x00, 0xce, /* 0xa0-0xa7 */ + 0x00, 0xcf, 0x00, 0xd0, 0x00, 0xd1, 0x00, 0xd2, /* 0xa8-0xaf */ + 0x00, 0xbc, 0x00, 0xd3, 0x00, 0xbd, 0x00, 0xd4, /* 0xb0-0xb7 */ + 0x00, 0xbe, 0x00, 0xd5, 0x00, 0xeb, 0x00, 0xd6, /* 0xb8-0xbf */ + 0x00, 0xd7, 0x00, 0x00, 0x00, 0xd8, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0xdf, 0xc5, 0xd9, 0xec, 0xee, 0xed, 0xda, /* 0xc8-0xcf */ + 0xf7, 0xba, 0x00, 0xe1, 0x00, 0xf8, 0x00, 0xe2, /* 0xd0-0xd7 */ + 0x00, 0xfc, 0x00, 0xe3, 0x00, 0xfb, 0x00, 0xe4, /* 0xd8-0xdf */ + 0x00, 0xef, 0x00, 0xe5, 0x00, 0xf2, 0x00, 0xe6, /* 0xe0-0xe7 */ + 0x00, 0xf3, 0x00, 0xe7, 0xf4, 0xe8, 0x00, 0xe9, /* 0xe8-0xef */ + 0xf5, 0xfd, 0xf6, 0xea, 0x00, 0xf9, 0xfa, 0x99, /* 0xf0-0xf7 */ + 0x9a, 0x00, 0x00, 0x9d, 0x9e, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static int +cp864_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0020) { + *r = wc; + return 1; + } + else if (wc >= 0x0020 && wc < 0x0028) + c = cp864_page00[wc-0x0020]; + else if (wc >= 0x0028 && wc < 0x0080) + c = wc; + else if (wc >= 0x00a0 && wc < 0x00f8) + c = cp864_page00_1[wc-0x00a0]; + else if (wc == 0x03b2) + c = 0x90; + else if (wc == 0x03c6) + c = 0x92; + else if (wc >= 0x0608 && wc < 0x0670) + c = cp864_page06[wc-0x0608]; + else if (wc >= 0x2218 && wc < 0x2250) + c = cp864_page22[wc-0x2218]; + else if (wc >= 0x2500 && wc < 0x2540) + c = cp864_page25[wc-0x2500]; + else if (wc == 0x2592) + c = 0x84; + else if (wc == 0x25a0) + c = 0xfe; + else if (wc >= 0xfe78 && wc < 0xff00) + c = cp864_pagefe[wc-0xfe78]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp865.h b/libs/libiconv/lib/cp865.h new file mode 100644 index 00000000..3944916d --- /dev/null +++ b/libs/libiconv/lib/cp865.h @@ -0,0 +1,156 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP865 + */ + +static const unsigned short cp865_2uni[128] = { + /* 0x80 */ + 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7, + 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5, + /* 0x90 */ + 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9, + 0x00ff, 0x00d6, 0x00dc, 0x00f8, 0x00a3, 0x00d8, 0x20a7, 0x0192, + /* 0xa0 */ + 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba, + 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00a4, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + /* 0xd0 */ + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + /* 0xe0 */ + 0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4, + 0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229, + /* 0xf0 */ + 0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248, + 0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0, +}; + +static int +cp865_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp865_2uni[c-0x80]; + return 1; +} + +static const unsigned char cp865_page00[96] = { + 0xff, 0xad, 0x00, 0x9c, 0xaf, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0xa6, 0xae, 0xaa, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0xfd, 0x00, 0x00, 0xe6, 0x00, 0xfa, /* 0xb0-0xb7 */ + 0x00, 0x00, 0xa7, 0x00, 0xac, 0xab, 0x00, 0xa8, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x8e, 0x8f, 0x92, 0x80, /* 0xc0-0xc7 */ + 0x00, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0xa5, 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, /* 0xd0-0xd7 */ + 0x9d, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00, 0xe1, /* 0xd8-0xdf */ + 0x85, 0xa0, 0x83, 0x00, 0x84, 0x86, 0x91, 0x87, /* 0xe0-0xe7 */ + 0x8a, 0x82, 0x88, 0x89, 0x8d, 0xa1, 0x8c, 0x8b, /* 0xe8-0xef */ + 0x00, 0xa4, 0x95, 0xa2, 0x93, 0x00, 0x94, 0xf6, /* 0xf0-0xf7 */ + 0x9b, 0x97, 0xa3, 0x96, 0x81, 0x00, 0x00, 0x98, /* 0xf8-0xff */ +}; +static const unsigned char cp865_page03[56] = { + 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0xe4, 0x00, 0x00, 0xe8, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0xe0, 0x00, 0x00, 0xeb, 0xee, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe3, 0x00, 0x00, 0xe5, 0xe7, 0x00, 0xed, 0x00, /* 0xc0-0xc7 */ +}; +static const unsigned char cp865_page22[80] = { + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xec, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0xf0, 0x00, 0x00, 0xf3, 0xf2, 0x00, 0x00, /* 0x60-0x67 */ +}; +static const unsigned char cp865_page23[24] = { + 0xa9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0xf4, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char cp865_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp865_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = cp865_page00[wc-0x00a0]; + else if (wc == 0x0192) + c = 0x9f; + else if (wc >= 0x0390 && wc < 0x03c8) + c = cp865_page03[wc-0x0390]; + else if (wc == 0x207f) + c = 0xfc; + else if (wc == 0x20a7) + c = 0x9e; + else if (wc >= 0x2218 && wc < 0x2268) + c = cp865_page22[wc-0x2218]; + else if (wc >= 0x2310 && wc < 0x2328) + c = cp865_page23[wc-0x2310]; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp865_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp866.h b/libs/libiconv/lib/cp866.h new file mode 100644 index 00000000..0aaa2169 --- /dev/null +++ b/libs/libiconv/lib/cp866.h @@ -0,0 +1,125 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP866 + */ + +static const unsigned short cp866_2uni[80] = { + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556, + 0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567, + /* 0xd0 */ + 0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b, + 0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580, + /* 0xe0 */ + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, + /* 0xf0 */ + 0x0401, 0x0451, 0x0404, 0x0454, 0x0407, 0x0457, 0x040e, 0x045e, + 0x00b0, 0x2219, 0x00b7, 0x221a, 0x2116, 0x00a4, 0x25a0, 0x00a0, +}; + +static int +cp866_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else if (c < 0xb0) + *pwc = (ucs4_t) c + 0x0390; + else + *pwc = (ucs4_t) cp866_2uni[c-0xb0]; + return 1; +} + +static const unsigned char cp866_page00[24] = { + 0xff, 0x00, 0x00, 0x00, 0xfd, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfa, /* 0xb0-0xb7 */ +}; +static const unsigned char cp866_page04[96] = { + 0x00, 0xf0, 0x00, 0x00, 0xf2, 0x00, 0x00, 0xf4, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x00, /* 0x08-0x0f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x10-0x17 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x18-0x1f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x20-0x27 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x28-0x2f */ + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x30-0x37 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0x00, 0xf1, 0x00, 0x00, 0xf3, 0x00, 0x00, 0xf5, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf7, 0x00, /* 0x58-0x5f */ +}; +static const unsigned char cp866_page22[8] = { + 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ +}; +static const unsigned char cp866_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0xd5, 0xd6, 0xc9, 0xb8, 0xb7, 0xbb, /* 0x50-0x57 */ + 0xd4, 0xd3, 0xc8, 0xbe, 0xbd, 0xbc, 0xc6, 0xc7, /* 0x58-0x5f */ + 0xcc, 0xb5, 0xb6, 0xb9, 0xd1, 0xd2, 0xcb, 0xcf, /* 0x60-0x67 */ + 0xd0, 0xca, 0xd8, 0xd7, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0xdd, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xde, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp866_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00b8) + c = cp866_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x0460) + c = cp866_page04[wc-0x0400]; + else if (wc == 0x2116) + c = 0xfc; + else if (wc >= 0x2218 && wc < 0x2220) + c = cp866_page22[wc-0x2218]; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp866_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp869.h b/libs/libiconv/lib/cp869.h new file mode 100644 index 00000000..8e839d2c --- /dev/null +++ b/libs/libiconv/lib/cp869.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP869 + */ + +static const unsigned short cp869_2uni[128] = { + /* 0x80 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x0386, 0xfffd, + 0x00b7, 0x00ac, 0x00a6, 0x2018, 0x2019, 0x0388, 0x2015, 0x0389, + /* 0x90 */ + 0x038a, 0x03aa, 0x038c, 0xfffd, 0xfffd, 0x038e, 0x03ab, 0x00a9, + 0x038f, 0x00b2, 0x00b3, 0x03ac, 0x00a3, 0x03ad, 0x03ae, 0x03af, + /* 0xa0 */ + 0x03ca, 0x0390, 0x03cc, 0x03cd, 0x0391, 0x0392, 0x0393, 0x0394, + 0x0395, 0x0396, 0x0397, 0x00bd, 0x0398, 0x0399, 0x00ab, 0x00bb, + /* 0xb0 */ + 0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x039a, 0x039b, 0x039c, + 0x039d, 0x2563, 0x2551, 0x2557, 0x255d, 0x039e, 0x039f, 0x2510, + /* 0xc0 */ + 0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x03a0, 0x03a1, + 0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x03a3, + /* 0xd0 */ + 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, 0x03b1, 0x03b2, + 0x03b3, 0x2518, 0x250c, 0x2588, 0x2584, 0x03b4, 0x03b5, 0x2580, + /* 0xe0 */ + 0x03b6, 0x03b7, 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, + 0x03be, 0x03bf, 0x03c0, 0x03c1, 0x03c3, 0x03c2, 0x03c4, 0x0384, + /* 0xf0 */ + 0x00ad, 0x00b1, 0x03c5, 0x03c6, 0x03c7, 0x00a7, 0x03c8, 0x0385, + 0x00b0, 0x00a8, 0x03c9, 0x03cb, 0x03b0, 0x03ce, 0x25a0, 0x00a0, +}; + +static int +cp869_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp869_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp869_page00[32] = { + 0xff, 0x00, 0x00, 0x9c, 0x00, 0x00, 0x8a, 0xf5, /* 0xa0-0xa7 */ + 0xf9, 0x97, 0x00, 0xae, 0x89, 0xf0, 0x00, 0x00, /* 0xa8-0xaf */ + 0xf8, 0xf1, 0x99, 0x9a, 0x00, 0x00, 0x00, 0x88, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xaf, 0x00, 0xab, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char cp869_page03[80] = { + 0x00, 0x00, 0x00, 0x00, 0xef, 0xf7, 0x86, 0x00, /* 0x80-0x87 */ + 0x8d, 0x8f, 0x90, 0x00, 0x92, 0x00, 0x95, 0x98, /* 0x88-0x8f */ + 0xa1, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, /* 0x90-0x97 */ + 0xac, 0xad, 0xb5, 0xb6, 0xb7, 0xb8, 0xbd, 0xbe, /* 0x98-0x9f */ + 0xc6, 0xc7, 0x00, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, /* 0xa0-0xa7 */ + 0xd4, 0xd5, 0x91, 0x96, 0x9b, 0x9d, 0x9e, 0x9f, /* 0xa8-0xaf */ + 0xfc, 0xd6, 0xd7, 0xd8, 0xdd, 0xde, 0xe0, 0xe1, /* 0xb0-0xb7 */ + 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, /* 0xb8-0xbf */ + 0xea, 0xeb, 0xed, 0xec, 0xee, 0xf2, 0xf3, 0xf4, /* 0xc0-0xc7 */ + 0xf6, 0xfa, 0xa0, 0xfb, 0xa2, 0xa3, 0xfd, 0x00, /* 0xc8-0xcf */ +}; +static const unsigned char cp869_page20[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, /* 0x10-0x17 */ + 0x8b, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ +}; +static const unsigned char cp869_page25[168] = { + 0xc4, 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xbf, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd9, 0x00, 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0xc2, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0xc5, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xcd, 0xba, 0x00, 0x00, 0xc9, 0x00, 0x00, 0xbb, /* 0x50-0x57 */ + 0x00, 0x00, 0xc8, 0x00, 0x00, 0xbc, 0x00, 0x00, /* 0x58-0x5f */ + 0xcc, 0x00, 0x00, 0xb9, 0x00, 0x00, 0xcb, 0x00, /* 0x60-0x67 */ + 0x00, 0xca, 0x00, 0x00, 0xce, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xdf, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +cp869_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = cp869_page00[wc-0x00a0]; + else if (wc >= 0x0380 && wc < 0x03d0) + c = cp869_page03[wc-0x0380]; + else if (wc >= 0x2010 && wc < 0x2020) + c = cp869_page20[wc-0x2010]; + else if (wc >= 0x2500 && wc < 0x25a8) + c = cp869_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp874.h b/libs/libiconv/lib/cp874.h new file mode 100644 index 00000000..6374dd7d --- /dev/null +++ b/libs/libiconv/lib/cp874.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP874 + */ + +static const unsigned short cp874_2uni[128] = { + /* 0x80 */ + 0x20ac, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2026, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x90 */ + 0xfffd, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xa0 */ + 0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, + 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, + /* 0xb0 */ + 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, + 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, + /* 0xc0 */ + 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, + 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, + /* 0xd0 */ + 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, + 0x0e38, 0x0e39, 0x0e3a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x0e3f, + /* 0xe0 */ + 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, + 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x0e4e, 0x0e4f, + /* 0xf0 */ + 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, + 0x0e58, 0x0e59, 0x0e5a, 0x0e5b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, +}; + +static int +cp874_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = cp874_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char cp874_page0e[96] = { + 0x00, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x00-0x07 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0x08-0x0f */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x10-0x17 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0x18-0x1f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x30-0x37 */ + 0xd8, 0xd9, 0xda, 0x00, 0x00, 0x00, 0x00, 0xdf, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x50-0x57 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ +}; +static const unsigned char cp874_page20[24] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x00, 0x00, 0x93, 0x94, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ +}; + +static int +cp874_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc == 0x00a0) + c = 0xa0; + else if (wc >= 0x0e00 && wc < 0x0e60) + c = cp874_page0e[wc-0x0e00]; + else if (wc >= 0x2010 && wc < 0x2028) + c = cp874_page20[wc-0x2010]; + else if (wc == 0x20ac) + c = 0x80; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp922.h b/libs/libiconv/lib/cp922.h new file mode 100644 index 00000000..ca661b38 --- /dev/null +++ b/libs/libiconv/lib/cp922.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP922 + */ + +static const unsigned short cp922_2uni_1[16] = { + /* 0xa0 */ + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x203e, +}; +static const unsigned short cp922_2uni_2[16] = { + /* 0xd0 */ + 0x0160, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x017d, 0x00df, +}; +static const unsigned short cp922_2uni_3[16] = { + /* 0xf0 */ + 0x0161, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x017e, 0x00ff, +}; + +static int +cp922_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else if (c < 0xb0) + *pwc = (ucs4_t) cp922_2uni_1[c-0xa0]; + else if (c < 0xd0) + *pwc = (ucs4_t) c; + else if (c < 0xe0) + *pwc = (ucs4_t) cp922_2uni_2[c-0xd0]; + else if (c < 0xf0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) cp922_2uni_3[c-0xf0]; + return 1; +} + +static const unsigned char cp922_page00[88] = { + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0x00, 0xff, /* 0xf8-0xff */ +}; +static const unsigned char cp922_page01[32] = { + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xfe, 0x00, /* 0x78-0x7f */ +}; + +static int +cp922_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a8) { + *r = wc; + return 1; + } + else if (wc >= 0x00a8 && wc < 0x0100) + c = cp922_page00[wc-0x00a8]; + else if (wc >= 0x0160 && wc < 0x0180) + c = cp922_page01[wc-0x0160]; + else if (wc == 0x203e) + c = 0xaf; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp932.h b/libs/libiconv/lib/cp932.h new file mode 100644 index 00000000..6534cd02 --- /dev/null +++ b/libs/libiconv/lib/cp932.h @@ -0,0 +1,240 @@ +/* + * Copyright (C) 1999-2002, 2005 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP932 + */ + +/* + * Microsoft CP932 is a slightly extended version of SHIFT_JIS. + * The differences between the EASTASIA/JIS/SHIFTJIS.TXT and the + * VENDORS/MICSFT/WINDOWS/CP932.TXT tables found on ftp.unicode.org are + * as follows: + * + * 1. CP932 uses ASCII, not JISX0201 Roman. + * + * 2. Some characters in the JISX0208 range are defined differently: + * + * code SHIFTJIS.TXT CP932.TXT + * 0x815F 0x005C # REVERSE SOLIDUS 0xFF3C # FULLWIDTH REVERSE SOLIDUS + * 0x8160 0x301C # WAVE DASH 0xFF5E # FULLWIDTH TILDE + * 0x8161 0x2016 # DOUBLE VERTICAL LINE 0x2225 # PARALLEL TO + * 0x817C 0x2212 # MINUS SIGN 0xFF0D # FULLWIDTH HYPHEN-MINUS + * 0x8191 0x00A2 # CENT SIGN 0xFFE0 # FULLWIDTH CENT SIGN + * 0x8192 0x00A3 # POUND SIGN 0xFFE1 # FULLWIDTH POUND SIGN + * 0x81CA 0x00AC # NOT SIGN 0xFFE2 # FULLWIDTH NOT SIGN + * + * We don't implement the latter 6 of these changes, only the first one. + * SHIFTJIS.TXT makes more sense. However, as a compromise with user + * expectation, we implement the middle 5 of these changes in the + * Unicode to CP932 direction. We don't implement the last one at all, + * because it would collide with the mapping of 0xFA54. + * + * 3. A few new rows. See cp932ext.h. + * + * Many variants of CP932 (in GNU libc, JDK, OSF/1, Windows-2000, ICU) also + * add: + * + * 4. Private area mappings: + * + * code Unicode + * 0x{F0..F9}{40..7E,80..FC} U+E000..U+E757 + * + * We add them too because, although there are backward compatibility problems + * when a character from a private area is moved to an official Unicode code + * point, they are useful for some people in practice. + */ + +#include "cp932ext.h" + +/* + Conversion between SJIS codes (s1,s2) and JISX0208 codes (c1,c2): + Example. (s1,s2) = 0x8140, (c1,c2) = 0x2121. + 0x81 <= s1 <= 0x9F || 0xE0 <= s1 <= 0xEA, + 0x40 <= s2 <= 0x7E || 0x80 <= s2 <= 0xFC, + 0x21 <= c1 <= 0x74, 0x21 <= c2 <= 0x7E. + Invariant: + 94*2*(s1 < 0xE0 ? s1-0x81 : s1-0xC1) + (s2 < 0x80 ? s2-0x40 : s2-0x41) + = 94*(c1-0x21)+(c2-0x21) + Conversion (s1,s2) -> (c1,c2): + t1 := (s1 < 0xE0 ? s1-0x81 : s1-0xC1) + t2 := (s2 < 0x80 ? s2-0x40 : s2-0x41) + c1 := 2*t1 + (t2 < 0x5E ? 0 : 1) + 0x21 + c2 := (t2 < 0x5E ? t2 : t2-0x5E) + 0x21 + Conversion (c1,c2) -> (s1,s2): + t1 := (c1 - 0x21) >> 1 + t2 := ((c1 - 0x21) & 1) * 0x5E + (c2 - 0x21) + s1 := (t1 < 0x1F ? t1+0x81 : t1+0xC1) + s2 := (t2 < 0x3F ? t2+0x40 : t2+0x41) + */ + +static int +cp932_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + else if (c >= 0xa1 && c <= 0xdf) + return jisx0201_mbtowc(conv,pwc,s,n); + else { + unsigned char s1, s2; + s1 = c; + if ((s1 >= 0x81 && s1 <= 0x9f && s1 != 0x87) || (s1 >= 0xe0 && s1 <= 0xea)) { + if (n < 2) + return RET_TOOFEW(0); + s2 = s[1]; + if ((s2 >= 0x40 && s2 <= 0x7e) || (s2 >= 0x80 && s2 <= 0xfc)) { + unsigned char t1 = (s1 < 0xe0 ? s1-0x81 : s1-0xc1); + unsigned char t2 = (s2 < 0x80 ? s2-0x40 : s2-0x41); + unsigned char buf[2]; + buf[0] = 2*t1 + (t2 < 0x5e ? 0 : 1) + 0x21; + buf[1] = (t2 < 0x5e ? t2 : t2-0x5e) + 0x21; + return jisx0208_mbtowc(conv,pwc,buf,2); + } + } else if ((s1 == 0x87) || (s1 >= 0xed && s1 <= 0xee) || (s1 >= 0xfa)) { + if (n < 2) + return RET_TOOFEW(0); + return cp932ext_mbtowc(conv,pwc,s,2); + } else if (s1 >= 0xf0 && s1 <= 0xf9) { + /* User-defined range. See + * Ken Lunde's "CJKV Information Processing", table 4-66, p. 206. */ + if (n < 2) + return RET_TOOFEW(0); + s2 = s[1]; + if ((s2 >= 0x40 && s2 <= 0x7e) || (s2 >= 0x80 && s2 <= 0xfc)) { + *pwc = 0xe000 + 188*(s1 - 0xf0) + (s2 < 0x80 ? s2-0x40 : s2-0x41); + return 2; + } + } + return RET_ILSEQ; + } +} + +static int +cp932_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[2]; + int ret; + + /* Try ASCII. */ + ret = ascii_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + unsigned char c; + if (ret != 1) abort(); + c = buf[0]; + if (c < 0x80) { + r[0] = c; + return 1; + } + } + + /* Try JIS X 0201-1976 Katakana. */ + ret = jisx0201_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + unsigned char c; + if (ret != 1) abort(); + c = buf[0]; + if (c >= 0xa1 && c <= 0xdf) { + r[0] = c; + return 1; + } + } + + /* Try JIS X 0208-1990. */ + ret = jisx0208_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + unsigned char c1, c2; + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + c1 = buf[0]; + c2 = buf[1]; + if ((c1 >= 0x21 && c1 <= 0x74) && (c2 >= 0x21 && c2 <= 0x7e)) { + unsigned char t1 = (c1 - 0x21) >> 1; + unsigned char t2 = (((c1 - 0x21) & 1) ? 0x5e : 0) + (c2 - 0x21); + r[0] = (t1 < 0x1f ? t1+0x81 : t1+0xc1); + r[1] = (t2 < 0x3f ? t2+0x40 : t2+0x41); + return 2; + } + } + + /* Try CP932 extensions. */ + ret = cp932ext_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]; + r[1] = buf[1]; + return 2; + } + + /* User-defined range. See + * Ken Lunde's "CJKV Information Processing", table 4-66, p. 206. */ + if (wc >= 0xe000 && wc < 0xe758) { + unsigned char c1, c2; + if (n < 2) + return RET_TOOSMALL; + c1 = (unsigned int) (wc - 0xe000) / 188; + c2 = (unsigned int) (wc - 0xe000) % 188; + r[0] = c1+0xf0; + r[1] = (c2 < 0x3f ? c2+0x40 : c2+0x41); + return 2; + } + + /* Irreversible mappings. */ + if (wc == 0xff5e) { + if (n < 2) + return RET_TOOSMALL; + r[0] = 0x81; + r[1] = 0x60; + return 2; + } + if (wc == 0x2225) { + if (n < 2) + return RET_TOOSMALL; + r[0] = 0x81; + r[1] = 0x61; + return 2; + } + if (wc == 0xff0d) { + if (n < 2) + return RET_TOOSMALL; + r[0] = 0x81; + r[1] = 0x7c; + return 2; + } + if (wc == 0xffe0) { + if (n < 2) + return RET_TOOSMALL; + r[0] = 0x81; + r[1] = 0x91; + return 2; + } + if (wc == 0xffe1) { + if (n < 2) + return RET_TOOSMALL; + r[0] = 0x81; + r[1] = 0x92; + return 2; + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp932ext.h b/libs/libiconv/lib/cp932ext.h new file mode 100644 index 00000000..6f94c9a5 --- /dev/null +++ b/libs/libiconv/lib/cp932ext.h @@ -0,0 +1,709 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP932 extensions + */ + +static const unsigned short cp932ext_2uni_page87[92] = { + /* 0x87 */ + 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, + 0x2468, 0x2469, 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, + 0x2470, 0x2471, 0x2472, 0x2473, 0x2160, 0x2161, 0x2162, 0x2163, + 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, 0x2169, 0xfffd, 0x3349, + 0x3314, 0x3322, 0x334d, 0x3318, 0x3327, 0x3303, 0x3336, 0x3351, + 0x3357, 0x330d, 0x3326, 0x3323, 0x332b, 0x334a, 0x333b, 0x339c, + 0x339d, 0x339e, 0x338e, 0x338f, 0x33c4, 0x33a1, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x337b, 0x301d, + 0x301f, 0x2116, 0x33cd, 0x2121, 0x32a4, 0x32a5, 0x32a6, 0x32a7, + 0x32a8, 0x3231, 0x3232, 0x3239, 0x337e, 0x337d, 0x337c, 0x2252, + 0x2261, 0x222b, 0x222e, 0x2211, 0x221a, 0x22a5, 0x2220, 0x221f, + 0x22bf, 0x2235, 0x2229, 0x222a, +}; +static const unsigned short cp932ext_2uni_pageed[376] = { + /* 0xed */ + 0x7e8a, 0x891c, 0x9348, 0x9288, 0x84dc, 0x4fc9, 0x70bb, 0x6631, + 0x68c8, 0x92f9, 0x66fb, 0x5f45, 0x4e28, 0x4ee1, 0x4efc, 0x4f00, + 0x4f03, 0x4f39, 0x4f56, 0x4f92, 0x4f8a, 0x4f9a, 0x4f94, 0x4fcd, + 0x5040, 0x5022, 0x4fff, 0x501e, 0x5046, 0x5070, 0x5042, 0x5094, + 0x50f4, 0x50d8, 0x514a, 0x5164, 0x519d, 0x51be, 0x51ec, 0x5215, + 0x529c, 0x52a6, 0x52c0, 0x52db, 0x5300, 0x5307, 0x5324, 0x5372, + 0x5393, 0x53b2, 0x53dd, 0xfa0e, 0x549c, 0x548a, 0x54a9, 0x54ff, + 0x5586, 0x5759, 0x5765, 0x57ac, 0x57c8, 0x57c7, 0xfa0f, 0xfa10, + 0x589e, 0x58b2, 0x590b, 0x5953, 0x595b, 0x595d, 0x5963, 0x59a4, + 0x59ba, 0x5b56, 0x5bc0, 0x752f, 0x5bd8, 0x5bec, 0x5c1e, 0x5ca6, + 0x5cba, 0x5cf5, 0x5d27, 0x5d53, 0xfa11, 0x5d42, 0x5d6d, 0x5db8, + 0x5db9, 0x5dd0, 0x5f21, 0x5f34, 0x5f67, 0x5fb7, 0x5fde, 0x605d, + 0x6085, 0x608a, 0x60de, 0x60d5, 0x6120, 0x60f2, 0x6111, 0x6137, + 0x6130, 0x6198, 0x6213, 0x62a6, 0x63f5, 0x6460, 0x649d, 0x64ce, + 0x654e, 0x6600, 0x6615, 0x663b, 0x6609, 0x662e, 0x661e, 0x6624, + 0x6665, 0x6657, 0x6659, 0xfa12, 0x6673, 0x6699, 0x66a0, 0x66b2, + 0x66bf, 0x66fa, 0x670e, 0xf929, 0x6766, 0x67bb, 0x6852, 0x67c0, + 0x6801, 0x6844, 0x68cf, 0xfa13, 0x6968, 0xfa14, 0x6998, 0x69e2, + 0x6a30, 0x6a6b, 0x6a46, 0x6a73, 0x6a7e, 0x6ae2, 0x6ae4, 0x6bd6, + 0x6c3f, 0x6c5c, 0x6c86, 0x6c6f, 0x6cda, 0x6d04, 0x6d87, 0x6d6f, + 0x6d96, 0x6dac, 0x6dcf, 0x6df8, 0x6df2, 0x6dfc, 0x6e39, 0x6e5c, + 0x6e27, 0x6e3c, 0x6ebf, 0x6f88, 0x6fb5, 0x6ff5, 0x7005, 0x7007, + 0x7028, 0x7085, 0x70ab, 0x710f, 0x7104, 0x715c, 0x7146, 0x7147, + 0xfa15, 0x71c1, 0x71fe, 0x72b1, + /* 0xee */ + 0x72be, 0x7324, 0xfa16, 0x7377, 0x73bd, 0x73c9, 0x73d6, 0x73e3, + 0x73d2, 0x7407, 0x73f5, 0x7426, 0x742a, 0x7429, 0x742e, 0x7462, + 0x7489, 0x749f, 0x7501, 0x756f, 0x7682, 0x769c, 0x769e, 0x769b, + 0x76a6, 0xfa17, 0x7746, 0x52af, 0x7821, 0x784e, 0x7864, 0x787a, + 0x7930, 0xfa18, 0xfa19, 0xfa1a, 0x7994, 0xfa1b, 0x799b, 0x7ad1, + 0x7ae7, 0xfa1c, 0x7aeb, 0x7b9e, 0xfa1d, 0x7d48, 0x7d5c, 0x7db7, + 0x7da0, 0x7dd6, 0x7e52, 0x7f47, 0x7fa1, 0xfa1e, 0x8301, 0x8362, + 0x837f, 0x83c7, 0x83f6, 0x8448, 0x84b4, 0x8553, 0x8559, 0x856b, + 0xfa1f, 0x85b0, 0xfa20, 0xfa21, 0x8807, 0x88f5, 0x8a12, 0x8a37, + 0x8a79, 0x8aa7, 0x8abe, 0x8adf, 0xfa22, 0x8af6, 0x8b53, 0x8b7f, + 0x8cf0, 0x8cf4, 0x8d12, 0x8d76, 0xfa23, 0x8ecf, 0xfa24, 0xfa25, + 0x9067, 0x90de, 0xfa26, 0x9115, 0x9127, 0x91da, 0x91d7, 0x91de, + 0x91ed, 0x91ee, 0x91e4, 0x91e5, 0x9206, 0x9210, 0x920a, 0x923a, + 0x9240, 0x923c, 0x924e, 0x9259, 0x9251, 0x9239, 0x9267, 0x92a7, + 0x9277, 0x9278, 0x92e7, 0x92d7, 0x92d9, 0x92d0, 0xfa27, 0x92d5, + 0x92e0, 0x92d3, 0x9325, 0x9321, 0x92fb, 0xfa28, 0x931e, 0x92ff, + 0x931d, 0x9302, 0x9370, 0x9357, 0x93a4, 0x93c6, 0x93de, 0x93f8, + 0x9431, 0x9445, 0x9448, 0x9592, 0xf9dc, 0xfa29, 0x969d, 0x96af, + 0x9733, 0x973b, 0x9743, 0x974d, 0x974f, 0x9751, 0x9755, 0x9857, + 0x9865, 0xfa2a, 0xfa2b, 0x9927, 0xfa2c, 0x999e, 0x9a4e, 0x9ad9, + 0x9adc, 0x9b75, 0x9b72, 0x9b8f, 0x9bb1, 0x9bbb, 0x9c00, 0x9d70, + 0x9d6b, 0xfa2d, 0x9e19, 0x9ed1, 0xfffd, 0xfffd, 0x2170, 0x2171, + 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, 0x2178, 0x2179, + 0xffe2, 0xffe4, 0xff07, 0xff02, +}; +static const unsigned short cp932ext_2uni_pagefa[388] = { + /* 0xfa */ + 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, + 0x2178, 0x2179, 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, + 0x2166, 0x2167, 0x2168, 0x2169, 0xffe2, 0xffe4, 0xff07, 0xff02, + 0x3231, 0x2116, 0x2121, 0x2235, 0x7e8a, 0x891c, 0x9348, 0x9288, + 0x84dc, 0x4fc9, 0x70bb, 0x6631, 0x68c8, 0x92f9, 0x66fb, 0x5f45, + 0x4e28, 0x4ee1, 0x4efc, 0x4f00, 0x4f03, 0x4f39, 0x4f56, 0x4f92, + 0x4f8a, 0x4f9a, 0x4f94, 0x4fcd, 0x5040, 0x5022, 0x4fff, 0x501e, + 0x5046, 0x5070, 0x5042, 0x5094, 0x50f4, 0x50d8, 0x514a, 0x5164, + 0x519d, 0x51be, 0x51ec, 0x5215, 0x529c, 0x52a6, 0x52c0, 0x52db, + 0x5300, 0x5307, 0x5324, 0x5372, 0x5393, 0x53b2, 0x53dd, 0xfa0e, + 0x549c, 0x548a, 0x54a9, 0x54ff, 0x5586, 0x5759, 0x5765, 0x57ac, + 0x57c8, 0x57c7, 0xfa0f, 0xfa10, 0x589e, 0x58b2, 0x590b, 0x5953, + 0x595b, 0x595d, 0x5963, 0x59a4, 0x59ba, 0x5b56, 0x5bc0, 0x752f, + 0x5bd8, 0x5bec, 0x5c1e, 0x5ca6, 0x5cba, 0x5cf5, 0x5d27, 0x5d53, + 0xfa11, 0x5d42, 0x5d6d, 0x5db8, 0x5db9, 0x5dd0, 0x5f21, 0x5f34, + 0x5f67, 0x5fb7, 0x5fde, 0x605d, 0x6085, 0x608a, 0x60de, 0x60d5, + 0x6120, 0x60f2, 0x6111, 0x6137, 0x6130, 0x6198, 0x6213, 0x62a6, + 0x63f5, 0x6460, 0x649d, 0x64ce, 0x654e, 0x6600, 0x6615, 0x663b, + 0x6609, 0x662e, 0x661e, 0x6624, 0x6665, 0x6657, 0x6659, 0xfa12, + 0x6673, 0x6699, 0x66a0, 0x66b2, 0x66bf, 0x66fa, 0x670e, 0xf929, + 0x6766, 0x67bb, 0x6852, 0x67c0, 0x6801, 0x6844, 0x68cf, 0xfa13, + 0x6968, 0xfa14, 0x6998, 0x69e2, 0x6a30, 0x6a6b, 0x6a46, 0x6a73, + 0x6a7e, 0x6ae2, 0x6ae4, 0x6bd6, 0x6c3f, 0x6c5c, 0x6c86, 0x6c6f, + 0x6cda, 0x6d04, 0x6d87, 0x6d6f, + /* 0xfb */ + 0x6d96, 0x6dac, 0x6dcf, 0x6df8, 0x6df2, 0x6dfc, 0x6e39, 0x6e5c, + 0x6e27, 0x6e3c, 0x6ebf, 0x6f88, 0x6fb5, 0x6ff5, 0x7005, 0x7007, + 0x7028, 0x7085, 0x70ab, 0x710f, 0x7104, 0x715c, 0x7146, 0x7147, + 0xfa15, 0x71c1, 0x71fe, 0x72b1, 0x72be, 0x7324, 0xfa16, 0x7377, + 0x73bd, 0x73c9, 0x73d6, 0x73e3, 0x73d2, 0x7407, 0x73f5, 0x7426, + 0x742a, 0x7429, 0x742e, 0x7462, 0x7489, 0x749f, 0x7501, 0x756f, + 0x7682, 0x769c, 0x769e, 0x769b, 0x76a6, 0xfa17, 0x7746, 0x52af, + 0x7821, 0x784e, 0x7864, 0x787a, 0x7930, 0xfa18, 0xfa19, 0xfa1a, + 0x7994, 0xfa1b, 0x799b, 0x7ad1, 0x7ae7, 0xfa1c, 0x7aeb, 0x7b9e, + 0xfa1d, 0x7d48, 0x7d5c, 0x7db7, 0x7da0, 0x7dd6, 0x7e52, 0x7f47, + 0x7fa1, 0xfa1e, 0x8301, 0x8362, 0x837f, 0x83c7, 0x83f6, 0x8448, + 0x84b4, 0x8553, 0x8559, 0x856b, 0xfa1f, 0x85b0, 0xfa20, 0xfa21, + 0x8807, 0x88f5, 0x8a12, 0x8a37, 0x8a79, 0x8aa7, 0x8abe, 0x8adf, + 0xfa22, 0x8af6, 0x8b53, 0x8b7f, 0x8cf0, 0x8cf4, 0x8d12, 0x8d76, + 0xfa23, 0x8ecf, 0xfa24, 0xfa25, 0x9067, 0x90de, 0xfa26, 0x9115, + 0x9127, 0x91da, 0x91d7, 0x91de, 0x91ed, 0x91ee, 0x91e4, 0x91e5, + 0x9206, 0x9210, 0x920a, 0x923a, 0x9240, 0x923c, 0x924e, 0x9259, + 0x9251, 0x9239, 0x9267, 0x92a7, 0x9277, 0x9278, 0x92e7, 0x92d7, + 0x92d9, 0x92d0, 0xfa27, 0x92d5, 0x92e0, 0x92d3, 0x9325, 0x9321, + 0x92fb, 0xfa28, 0x931e, 0x92ff, 0x931d, 0x9302, 0x9370, 0x9357, + 0x93a4, 0x93c6, 0x93de, 0x93f8, 0x9431, 0x9445, 0x9448, 0x9592, + 0xf9dc, 0xfa29, 0x969d, 0x96af, 0x9733, 0x973b, 0x9743, 0x974d, + 0x974f, 0x9751, 0x9755, 0x9857, 0x9865, 0xfa2a, 0xfa2b, 0x9927, + 0xfa2c, 0x999e, 0x9a4e, 0x9ad9, + /* 0xfc */ + 0x9adc, 0x9b75, 0x9b72, 0x9b8f, 0x9bb1, 0x9bbb, 0x9c00, 0x9d70, + 0x9d6b, 0xfa2d, 0x9e19, 0x9ed1, +}; + +static int +cp932ext_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 == 0x87) || (c1 >= 0xed && c1 <= 0xee) || (c1 >= 0xfa && c1 <= 0xfc)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0x80 && c2 < 0xfd)) { + unsigned int i = 188 * (c1 - (c1 >= 0xe0 ? 0xc1 : 0x81)) + (c2 - (c2 >= 0x80 ? 0x41 : 0x40)); + unsigned short wc = 0xfffd; + if (i < 8272) { + if (i < 1220) + wc = cp932ext_2uni_page87[i-1128]; + } else if (i < 10716) { + if (i < 8648) + wc = cp932ext_2uni_pageed[i-8272]; + } else { + if (i < 11104) + wc = cp932ext_2uni_pagefa[i-10716]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short cp932ext_2charset[457] = { + 0xfa59, 0xfa5a, 0xfa4a, 0xfa4b, 0xfa4c, 0xfa4d, 0xfa4e, 0xfa4f, + 0xfa50, 0xfa51, 0xfa52, 0xfa53, 0xfa40, 0xfa41, 0xfa42, 0xfa43, + 0xfa44, 0xfa45, 0xfa46, 0xfa47, 0xfa48, 0xfa49, 0x8794, 0x8795, + 0x8798, 0x8797, 0x879b, 0x879c, 0x8792, 0x8793, 0xfa5b, 0x8790, + 0x8791, 0x8796, 0x8799, 0x8740, 0x8741, 0x8742, 0x8743, 0x8744, + 0x8745, 0x8746, 0x8747, 0x8748, 0x8749, 0x874a, 0x874b, 0x874c, + 0x874d, 0x874e, 0x874f, 0x8750, 0x8751, 0x8752, 0x8753, 0x8780, + 0x8781, 0xfa58, 0x878b, 0x878c, 0x8785, 0x8786, 0x8787, 0x8788, + 0x8789, 0x8765, 0x8769, 0x8760, 0x8763, 0x8761, 0x876b, 0x876a, + 0x8764, 0x876c, 0x8766, 0x876e, 0x875f, 0x876d, 0x8762, 0x8767, + 0x8768, 0x877e, 0x878f, 0x878e, 0x878d, 0x8772, 0x8773, 0x876f, + 0x8770, 0x8771, 0x8775, 0x8774, 0x8783, 0xfa68, 0xfa69, 0xfa6a, + 0xfa6b, 0xfa6c, 0xfa6d, 0xfa6e, 0xfa70, 0xfa6f, 0xfa72, 0xfa71, + 0xfa61, 0xfa73, 0xfa76, 0xfa77, 0xfa75, 0xfa74, 0xfa7a, 0xfa78, + 0xfa79, 0xfa7b, 0xfa7d, 0xfa7c, 0xfa7e, 0xfa80, 0xfa81, 0xfa82, + 0xfa83, 0xfa84, 0xfa85, 0xfa86, 0xfb77, 0xfa87, 0xfa88, 0xfa89, + 0xfa8a, 0xfa8b, 0xfa8c, 0xfa8d, 0xfa8e, 0xfa8f, 0xfa92, 0xfa91, + 0xfa93, 0xfa94, 0xfa95, 0xfa96, 0xfa97, 0xfa98, 0xfa9a, 0xfa99, + 0xfa9d, 0xfa9e, 0xfa9f, 0xfaa0, 0xfaa1, 0xfaa2, 0xfaa3, 0xfaa4, + 0xfaa5, 0xfaa6, 0xfaa7, 0xfaa9, 0xfaaa, 0xfaab, 0xfaac, 0xfaad, + 0xfaae, 0xfaaf, 0xfab2, 0xfab0, 0xfab3, 0xfab4, 0xfab5, 0xfab6, + 0xfab7, 0xfab8, 0xfa67, 0xfab9, 0xfaba, 0xfabb, 0xfabc, 0xfabd, + 0xfabe, 0xfac0, 0xfabf, 0xfac2, 0xfac3, 0xfac1, 0xfac5, 0xfac4, + 0xfac6, 0xfac7, 0xfac8, 0xfac9, 0xfaca, 0xfacb, 0xfacc, 0xfacd, + 0xface, 0xfad1, 0xfacf, 0xfad3, 0xfad4, 0xfad2, 0xfa63, 0xfad0, + 0xfad6, 0xfad7, 0xfad5, 0xfad9, 0xfada, 0xfadb, 0xfadc, 0xfadd, + 0xfade, 0xfa66, 0xfadf, 0xfae1, 0xfae2, 0xfae4, 0xfae5, 0xfae6, + 0xfae3, 0xfa64, 0xfae7, 0xfae9, 0xfaeb, 0xfaec, 0xfaed, 0xfaef, + 0xfaee, 0xfaf0, 0xfaf1, 0xfaf2, 0xfaf3, 0xfaf4, 0xfaf5, 0xfaf6, + 0xfaf8, 0xfaf7, 0xfaf9, 0xfafa, 0xfafc, 0xfafb, 0xfb40, 0xfb41, + 0xfb42, 0xfb44, 0xfb43, 0xfb45, 0xfb48, 0xfb46, 0xfb49, 0xfb47, + 0xfb4a, 0xfb4b, 0xfb4c, 0xfb4d, 0xfb4e, 0xfb4f, 0xfb50, 0xfb51, + 0xfb52, 0xfa62, 0xfb54, 0xfb53, 0xfb56, 0xfb57, 0xfb55, 0xfb59, + 0xfb5a, 0xfb5b, 0xfb5c, 0xfb5d, 0xfb5f, 0xfb60, 0xfb61, 0xfb64, + 0xfb62, 0xfb63, 0xfb66, 0xfb65, 0xfb67, 0xfb69, 0xfb68, 0xfb6a, + 0xfb6b, 0xfb6c, 0xfb6d, 0xfb6e, 0xfaa8, 0xfb6f, 0xfb70, 0xfb73, + 0xfb71, 0xfb72, 0xfb74, 0xfb76, 0xfb78, 0xfb79, 0xfb7a, 0xfb7b, + 0xfb7c, 0xfb81, 0xfb83, 0xfb84, 0xfb85, 0xfb87, 0xfb88, 0xfb8a, + 0xfb8b, 0xfb8d, 0xfb8c, 0xfb8e, 0xfb8f, 0xfa5c, 0xfb90, 0xfb91, + 0xfb93, 0xfb94, 0xfb95, 0xfb96, 0xfb97, 0xfb98, 0xfb99, 0xfa60, + 0xfb9a, 0xfb9b, 0xfb9c, 0xfb9e, 0xfba1, 0xfba2, 0xfa5d, 0xfba3, + 0xfba4, 0xfba5, 0xfba6, 0xfba7, 0xfba8, 0xfbaa, 0xfbab, 0xfbac, + 0xfbad, 0xfbae, 0xfbaf, 0xfbb0, 0xfbb2, 0xfbb5, 0xfbb6, 0xfbb8, + 0xfbb9, 0xfbbb, 0xfbba, 0xfbbc, 0xfbbf, 0xfbc0, 0xfbbd, 0xfbbe, + 0xfbc1, 0xfbc3, 0xfbc2, 0xfbca, 0xfbc4, 0xfbc6, 0xfbc5, 0xfbc7, + 0xfbc9, 0xfbc8, 0xfbcb, 0xfbcd, 0xfbce, 0xfa5f, 0xfbcc, 0xfbd2, + 0xfbd6, 0xfbd4, 0xfbd0, 0xfbd1, 0xfbd5, 0xfbcf, 0xfa65, 0xfbd9, + 0xfbdc, 0xfbde, 0xfbdd, 0xfbdb, 0xfbd8, 0xfbd7, 0xfa5e, 0xfbe0, + 0xfbdf, 0xfbe1, 0xfbe2, 0xfbe3, 0xfbe4, 0xfbe5, 0xfbe6, 0xfbe7, + 0xfbe8, 0xfbeb, 0xfbec, 0xfbed, 0xfbee, 0xfbef, 0xfbf0, 0xfbf1, + 0xfbf2, 0xfbf3, 0xfbf4, 0xfbf5, 0xfbf8, 0xfbfa, 0xfbfb, 0xfbfc, + 0xfc40, 0xfc42, 0xfc41, 0xfc43, 0xfc44, 0xfc45, 0xfc46, 0xfc48, + 0xfc47, 0xfc4a, 0xfc4b, 0xfae0, 0xfbe9, 0xfa90, 0xfa9b, 0xfa9c, + 0xfab1, 0xfad8, 0xfae8, 0xfaea, 0xfb58, 0xfb5e, 0xfb75, 0xfb7d, + 0xfb7e, 0xfb80, 0xfb82, 0xfb86, 0xfb89, 0xfb92, 0xfb9d, 0xfb9f, + 0xfba0, 0xfba9, 0xfbb1, 0xfbb3, 0xfbb4, 0xfbb7, 0xfbd3, 0xfbda, + 0xfbea, 0xfbf6, 0xfbf7, 0xfbf9, 0xfc49, 0xfa57, 0xfa56, 0xfa54, + 0xfa55, +}; + +static const Summary16 cp932ext_uni2indx_page21[28] = { + /* 0x2100 */ + { 0, 0x0000 }, { 0, 0x0040 }, { 1, 0x0002 }, { 2, 0x0000 }, + { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x03ff }, { 12, 0x03ff }, + { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, + { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, + /* 0x2200 */ + { 22, 0x0000 }, { 22, 0x8402 }, { 25, 0x4e01 }, { 30, 0x0020 }, + { 31, 0x0000 }, { 31, 0x0004 }, { 32, 0x0002 }, { 33, 0x0000 }, + { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0020 }, { 34, 0x8000 }, +}; +static const Summary16 cp932ext_uni2indx_page24[8] = { + /* 0x2400 */ + { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, + { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0xffff }, { 51, 0x000f }, +}; +static const Summary16 cp932ext_uni2indx_page30[2] = { + /* 0x3000 */ + { 55, 0x0000 }, { 55, 0xa000 }, +}; +static const Summary16 cp932ext_uni2indx_page32[29] = { + /* 0x3200 */ + { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0206 }, + { 60, 0x0000 }, { 60, 0x0000 }, { 60, 0x0000 }, { 60, 0x0000 }, + { 60, 0x0000 }, { 60, 0x0000 }, { 60, 0x01f0 }, { 65, 0x0000 }, + { 65, 0x0000 }, { 65, 0x0000 }, { 65, 0x0000 }, { 65, 0x0000 }, + /* 0x3300 */ + { 65, 0x2008 }, { 67, 0x0110 }, { 69, 0x08cc }, { 74, 0x0840 }, + { 76, 0x2600 }, { 79, 0x0082 }, { 81, 0x0000 }, { 81, 0x7800 }, + { 85, 0xc000 }, { 87, 0x7000 }, { 90, 0x0002 }, { 91, 0x0000 }, + { 91, 0x2010 }, +}; +static const Summary16 cp932ext_uni2indx_page4e[121] = { + /* 0x4e00 */ + { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0100 }, { 94, 0x0000 }, + { 94, 0x0000 }, { 94, 0x0000 }, { 94, 0x0000 }, { 94, 0x0000 }, + { 94, 0x0000 }, { 94, 0x0000 }, { 94, 0x0000 }, { 94, 0x0000 }, + { 94, 0x0000 }, { 94, 0x0000 }, { 94, 0x0002 }, { 95, 0x1000 }, + /* 0x4f00 */ + { 96, 0x0009 }, { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x0200 }, + { 99, 0x0000 }, { 99, 0x0040 }, { 100, 0x0000 }, { 100, 0x0000 }, + { 100, 0x0400 }, { 101, 0x0414 }, { 104, 0x0000 }, { 104, 0x0000 }, + { 104, 0x2200 }, { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x8000 }, + /* 0x5000 */ + { 107, 0x0000 }, { 107, 0x4000 }, { 108, 0x0004 }, { 109, 0x0000 }, + { 109, 0x0045 }, { 112, 0x0000 }, { 112, 0x0000 }, { 112, 0x0001 }, + { 113, 0x0000 }, { 113, 0x0010 }, { 114, 0x0000 }, { 114, 0x0000 }, + { 114, 0x0000 }, { 114, 0x0100 }, { 115, 0x0000 }, { 115, 0x0010 }, + /* 0x5100 */ + { 116, 0x0000 }, { 116, 0x0000 }, { 116, 0x0000 }, { 116, 0x0000 }, + { 116, 0x0400 }, { 117, 0x0000 }, { 117, 0x0010 }, { 118, 0x0000 }, + { 118, 0x0000 }, { 118, 0x2000 }, { 119, 0x0000 }, { 119, 0x4000 }, + { 120, 0x0000 }, { 120, 0x0000 }, { 120, 0x1000 }, { 121, 0x0000 }, + /* 0x5200 */ + { 121, 0x0000 }, { 121, 0x0020 }, { 122, 0x0000 }, { 122, 0x0000 }, + { 122, 0x0000 }, { 122, 0x0000 }, { 122, 0x0000 }, { 122, 0x0000 }, + { 122, 0x0000 }, { 122, 0x1000 }, { 123, 0x8040 }, { 125, 0x0000 }, + { 125, 0x0001 }, { 126, 0x0800 }, { 127, 0x0000 }, { 127, 0x0000 }, + /* 0x5300 */ + { 127, 0x0081 }, { 129, 0x0000 }, { 129, 0x0010 }, { 130, 0x0000 }, + { 130, 0x0000 }, { 130, 0x0000 }, { 130, 0x0000 }, { 130, 0x0004 }, + { 131, 0x0000 }, { 131, 0x0008 }, { 132, 0x0000 }, { 132, 0x0004 }, + { 133, 0x0000 }, { 133, 0x2000 }, { 134, 0x0000 }, { 134, 0x0000 }, + /* 0x5400 */ + { 134, 0x0000 }, { 134, 0x0000 }, { 134, 0x0000 }, { 134, 0x0000 }, + { 134, 0x0000 }, { 134, 0x0000 }, { 134, 0x0000 }, { 134, 0x0000 }, + { 134, 0x0400 }, { 135, 0x1000 }, { 136, 0x0200 }, { 137, 0x0000 }, + { 137, 0x0000 }, { 137, 0x0000 }, { 137, 0x0000 }, { 137, 0x8000 }, + /* 0x5500 */ + { 138, 0x0000 }, { 138, 0x0000 }, { 138, 0x0000 }, { 138, 0x0000 }, + { 138, 0x0000 }, { 138, 0x0000 }, { 138, 0x0000 }, { 138, 0x0000 }, + { 138, 0x0040 }, +}; +static const Summary16 cp932ext_uni2indx_page57[44] = { + /* 0x5700 */ + { 139, 0x0000 }, { 139, 0x0000 }, { 139, 0x0000 }, { 139, 0x0000 }, + { 139, 0x0000 }, { 139, 0x0200 }, { 140, 0x0020 }, { 141, 0x0000 }, + { 141, 0x0000 }, { 141, 0x0000 }, { 141, 0x1000 }, { 142, 0x0000 }, + { 142, 0x0180 }, { 144, 0x0000 }, { 144, 0x0000 }, { 144, 0x0000 }, + /* 0x5800 */ + { 144, 0x0000 }, { 144, 0x0000 }, { 144, 0x0000 }, { 144, 0x0000 }, + { 144, 0x0000 }, { 144, 0x0000 }, { 144, 0x0000 }, { 144, 0x0000 }, + { 144, 0x0000 }, { 144, 0x4000 }, { 145, 0x0000 }, { 145, 0x0004 }, + { 146, 0x0000 }, { 146, 0x0000 }, { 146, 0x0000 }, { 146, 0x0000 }, + /* 0x5900 */ + { 146, 0x0800 }, { 147, 0x0000 }, { 147, 0x0000 }, { 147, 0x0000 }, + { 147, 0x0000 }, { 147, 0x2808 }, { 150, 0x0008 }, { 151, 0x0000 }, + { 151, 0x0000 }, { 151, 0x0000 }, { 151, 0x0010 }, { 152, 0x0400 }, +}; +static const Summary16 cp932ext_uni2indx_page5b[46] = { + /* 0x5b00 */ + { 153, 0x0000 }, { 153, 0x0000 }, { 153, 0x0000 }, { 153, 0x0000 }, + { 153, 0x0000 }, { 153, 0x0040 }, { 154, 0x0000 }, { 154, 0x0000 }, + { 154, 0x0000 }, { 154, 0x0000 }, { 154, 0x0000 }, { 154, 0x0000 }, + { 154, 0x0001 }, { 155, 0x0100 }, { 156, 0x1000 }, { 157, 0x0000 }, + /* 0x5c00 */ + { 157, 0x0000 }, { 157, 0x4000 }, { 158, 0x0000 }, { 158, 0x0000 }, + { 158, 0x0000 }, { 158, 0x0000 }, { 158, 0x0000 }, { 158, 0x0000 }, + { 158, 0x0000 }, { 158, 0x0000 }, { 158, 0x0040 }, { 159, 0x0400 }, + { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0020 }, + /* 0x5d00 */ + { 161, 0x0000 }, { 161, 0x0000 }, { 161, 0x0080 }, { 162, 0x0000 }, + { 162, 0x0004 }, { 163, 0x0008 }, { 164, 0x2000 }, { 165, 0x0000 }, + { 165, 0x0000 }, { 165, 0x0000 }, { 165, 0x0000 }, { 165, 0x0300 }, + { 167, 0x0000 }, { 167, 0x0001 }, +}; +static const Summary16 cp932ext_uni2indx_page5f[458] = { + /* 0x5f00 */ + { 168, 0x0000 }, { 168, 0x0000 }, { 168, 0x0002 }, { 169, 0x0010 }, + { 170, 0x0020 }, { 171, 0x0000 }, { 171, 0x0080 }, { 172, 0x0000 }, + { 172, 0x0000 }, { 172, 0x0000 }, { 172, 0x0000 }, { 172, 0x0080 }, + { 173, 0x0000 }, { 173, 0x4000 }, { 174, 0x0000 }, { 174, 0x0000 }, + /* 0x6000 */ + { 174, 0x0000 }, { 174, 0x0000 }, { 174, 0x0000 }, { 174, 0x0000 }, + { 174, 0x0000 }, { 174, 0x2000 }, { 175, 0x0000 }, { 175, 0x0000 }, + { 175, 0x0420 }, { 177, 0x0000 }, { 177, 0x0000 }, { 177, 0x0000 }, + { 177, 0x0000 }, { 177, 0x4020 }, { 179, 0x0000 }, { 179, 0x0004 }, + /* 0x6100 */ + { 180, 0x0000 }, { 180, 0x0002 }, { 181, 0x0001 }, { 182, 0x0081 }, + { 184, 0x0000 }, { 184, 0x0000 }, { 184, 0x0000 }, { 184, 0x0000 }, + { 184, 0x0000 }, { 184, 0x0100 }, { 185, 0x0000 }, { 185, 0x0000 }, + { 185, 0x0000 }, { 185, 0x0000 }, { 185, 0x0000 }, { 185, 0x0000 }, + /* 0x6200 */ + { 185, 0x0000 }, { 185, 0x0008 }, { 186, 0x0000 }, { 186, 0x0000 }, + { 186, 0x0000 }, { 186, 0x0000 }, { 186, 0x0000 }, { 186, 0x0000 }, + { 186, 0x0000 }, { 186, 0x0000 }, { 186, 0x0040 }, { 187, 0x0000 }, + { 187, 0x0000 }, { 187, 0x0000 }, { 187, 0x0000 }, { 187, 0x0000 }, + /* 0x6300 */ + { 187, 0x0000 }, { 187, 0x0000 }, { 187, 0x0000 }, { 187, 0x0000 }, + { 187, 0x0000 }, { 187, 0x0000 }, { 187, 0x0000 }, { 187, 0x0000 }, + { 187, 0x0000 }, { 187, 0x0000 }, { 187, 0x0000 }, { 187, 0x0000 }, + { 187, 0x0000 }, { 187, 0x0000 }, { 187, 0x0000 }, { 187, 0x0020 }, + /* 0x6400 */ + { 188, 0x0000 }, { 188, 0x0000 }, { 188, 0x0000 }, { 188, 0x0000 }, + { 188, 0x0000 }, { 188, 0x0000 }, { 188, 0x0001 }, { 189, 0x0000 }, + { 189, 0x0000 }, { 189, 0x2000 }, { 190, 0x0000 }, { 190, 0x0000 }, + { 190, 0x4000 }, { 191, 0x0000 }, { 191, 0x0000 }, { 191, 0x0000 }, + /* 0x6500 */ + { 191, 0x0000 }, { 191, 0x0000 }, { 191, 0x0000 }, { 191, 0x0000 }, + { 191, 0x4000 }, { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, + { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, + { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, { 192, 0x0000 }, + /* 0x6600 */ + { 192, 0x0201 }, { 194, 0x4020 }, { 196, 0x4010 }, { 198, 0x0802 }, + { 200, 0x0000 }, { 200, 0x0280 }, { 202, 0x0020 }, { 203, 0x0008 }, + { 204, 0x0000 }, { 204, 0x0200 }, { 205, 0x0001 }, { 206, 0x8004 }, + { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0c00 }, + /* 0x6700 */ + { 210, 0x4000 }, { 211, 0x0000 }, { 211, 0x0000 }, { 211, 0x0000 }, + { 211, 0x0000 }, { 211, 0x0000 }, { 211, 0x0040 }, { 212, 0x0000 }, + { 212, 0x0000 }, { 212, 0x0000 }, { 212, 0x0000 }, { 212, 0x0800 }, + { 213, 0x0001 }, { 214, 0x0000 }, { 214, 0x0000 }, { 214, 0x0000 }, + /* 0x6800 */ + { 214, 0x0002 }, { 215, 0x0000 }, { 215, 0x0000 }, { 215, 0x0000 }, + { 215, 0x0010 }, { 216, 0x0004 }, { 217, 0x0000 }, { 217, 0x0000 }, + { 217, 0x0000 }, { 217, 0x0000 }, { 217, 0x0000 }, { 217, 0x0000 }, + { 217, 0x8100 }, { 219, 0x0000 }, { 219, 0x0000 }, { 219, 0x0000 }, + /* 0x6900 */ + { 219, 0x0000 }, { 219, 0x0000 }, { 219, 0x0000 }, { 219, 0x0000 }, + { 219, 0x0000 }, { 219, 0x0000 }, { 219, 0x0100 }, { 220, 0x0000 }, + { 220, 0x0000 }, { 220, 0x0100 }, { 221, 0x0000 }, { 221, 0x0000 }, + { 221, 0x0000 }, { 221, 0x0000 }, { 221, 0x0004 }, { 222, 0x0000 }, + /* 0x6a00 */ + { 222, 0x0000 }, { 222, 0x0000 }, { 222, 0x0000 }, { 222, 0x0001 }, + { 223, 0x0040 }, { 224, 0x0000 }, { 224, 0x0800 }, { 225, 0x4008 }, + { 227, 0x0000 }, { 227, 0x0000 }, { 227, 0x0000 }, { 227, 0x0000 }, + { 227, 0x0000 }, { 227, 0x0000 }, { 227, 0x0014 }, { 229, 0x0000 }, + /* 0x6b00 */ + { 229, 0x0000 }, { 229, 0x0000 }, { 229, 0x0000 }, { 229, 0x0000 }, + { 229, 0x0000 }, { 229, 0x0000 }, { 229, 0x0000 }, { 229, 0x0000 }, + { 229, 0x0000 }, { 229, 0x0000 }, { 229, 0x0000 }, { 229, 0x0000 }, + { 229, 0x0000 }, { 229, 0x0040 }, { 230, 0x0000 }, { 230, 0x0000 }, + /* 0x6c00 */ + { 230, 0x0000 }, { 230, 0x0000 }, { 230, 0x0000 }, { 230, 0x8000 }, + { 231, 0x0000 }, { 231, 0x1000 }, { 232, 0x8000 }, { 233, 0x0000 }, + { 233, 0x0040 }, { 234, 0x0000 }, { 234, 0x0000 }, { 234, 0x0000 }, + { 234, 0x0000 }, { 234, 0x0400 }, { 235, 0x0000 }, { 235, 0x0000 }, + /* 0x6d00 */ + { 235, 0x0010 }, { 236, 0x0000 }, { 236, 0x0000 }, { 236, 0x0000 }, + { 236, 0x0000 }, { 236, 0x0000 }, { 236, 0x8000 }, { 237, 0x0000 }, + { 237, 0x0080 }, { 238, 0x0040 }, { 239, 0x1000 }, { 240, 0x0000 }, + { 240, 0x8000 }, { 241, 0x0000 }, { 241, 0x0000 }, { 241, 0x1104 }, + /* 0x6e00 */ + { 244, 0x0000 }, { 244, 0x0000 }, { 244, 0x0080 }, { 245, 0x1200 }, + { 247, 0x0000 }, { 247, 0x1000 }, { 248, 0x0000 }, { 248, 0x0000 }, + { 248, 0x0000 }, { 248, 0x0000 }, { 248, 0x0000 }, { 248, 0x8000 }, + { 249, 0x0000 }, { 249, 0x0000 }, { 249, 0x0000 }, { 249, 0x0000 }, + /* 0x6f00 */ + { 249, 0x0000 }, { 249, 0x0000 }, { 249, 0x0000 }, { 249, 0x0000 }, + { 249, 0x0000 }, { 249, 0x0000 }, { 249, 0x0000 }, { 249, 0x0000 }, + { 249, 0x0100 }, { 250, 0x0000 }, { 250, 0x0000 }, { 250, 0x0020 }, + { 251, 0x0000 }, { 251, 0x0000 }, { 251, 0x0000 }, { 251, 0x0020 }, + /* 0x7000 */ + { 252, 0x00a0 }, { 254, 0x0000 }, { 254, 0x0100 }, { 255, 0x0000 }, + { 255, 0x0000 }, { 255, 0x0000 }, { 255, 0x0000 }, { 255, 0x0000 }, + { 255, 0x0020 }, { 256, 0x0000 }, { 256, 0x0800 }, { 257, 0x0800 }, + { 258, 0x0000 }, { 258, 0x0000 }, { 258, 0x0000 }, { 258, 0x0000 }, + /* 0x7100 */ + { 258, 0x8010 }, { 260, 0x0000 }, { 260, 0x0000 }, { 260, 0x0000 }, + { 260, 0x00c0 }, { 262, 0x1000 }, { 263, 0x0000 }, { 263, 0x0000 }, + { 263, 0x0000 }, { 263, 0x0000 }, { 263, 0x0000 }, { 263, 0x0000 }, + { 263, 0x0002 }, { 264, 0x0000 }, { 264, 0x0000 }, { 264, 0x4000 }, + /* 0x7200 */ + { 265, 0x0000 }, { 265, 0x0000 }, { 265, 0x0000 }, { 265, 0x0000 }, + { 265, 0x0000 }, { 265, 0x0000 }, { 265, 0x0000 }, { 265, 0x0000 }, + { 265, 0x0000 }, { 265, 0x0000 }, { 265, 0x0000 }, { 265, 0x4002 }, + { 267, 0x0000 }, { 267, 0x0000 }, { 267, 0x0000 }, { 267, 0x0000 }, + /* 0x7300 */ + { 267, 0x0000 }, { 267, 0x0000 }, { 267, 0x0010 }, { 268, 0x0000 }, + { 268, 0x0000 }, { 268, 0x0000 }, { 268, 0x0000 }, { 268, 0x0080 }, + { 269, 0x0000 }, { 269, 0x0000 }, { 269, 0x0000 }, { 269, 0x2000 }, + { 270, 0x0200 }, { 271, 0x0044 }, { 273, 0x0008 }, { 274, 0x0020 }, + /* 0x7400 */ + { 275, 0x0080 }, { 276, 0x0000 }, { 276, 0x4640 }, { 280, 0x0000 }, + { 280, 0x0000 }, { 280, 0x0000 }, { 280, 0x0004 }, { 281, 0x0000 }, + { 281, 0x0200 }, { 282, 0x8000 }, { 283, 0x0000 }, { 283, 0x0000 }, + { 283, 0x0000 }, { 283, 0x0000 }, { 283, 0x0000 }, { 283, 0x0000 }, + /* 0x7500 */ + { 283, 0x0002 }, { 284, 0x0000 }, { 284, 0x8000 }, { 285, 0x0000 }, + { 285, 0x0000 }, { 285, 0x0000 }, { 285, 0x8000 }, { 286, 0x0000 }, + { 286, 0x0000 }, { 286, 0x0000 }, { 286, 0x0000 }, { 286, 0x0000 }, + { 286, 0x0000 }, { 286, 0x0000 }, { 286, 0x0000 }, { 286, 0x0000 }, + /* 0x7600 */ + { 286, 0x0000 }, { 286, 0x0000 }, { 286, 0x0000 }, { 286, 0x0000 }, + { 286, 0x0000 }, { 286, 0x0000 }, { 286, 0x0000 }, { 286, 0x0000 }, + { 286, 0x0004 }, { 287, 0x5800 }, { 290, 0x0040 }, { 291, 0x0000 }, + { 291, 0x0000 }, { 291, 0x0000 }, { 291, 0x0000 }, { 291, 0x0000 }, + /* 0x7700 */ + { 291, 0x0000 }, { 291, 0x0000 }, { 291, 0x0000 }, { 291, 0x0000 }, + { 291, 0x0040 }, { 292, 0x0000 }, { 292, 0x0000 }, { 292, 0x0000 }, + { 292, 0x0000 }, { 292, 0x0000 }, { 292, 0x0000 }, { 292, 0x0000 }, + { 292, 0x0000 }, { 292, 0x0000 }, { 292, 0x0000 }, { 292, 0x0000 }, + /* 0x7800 */ + { 292, 0x0000 }, { 292, 0x0000 }, { 292, 0x0002 }, { 293, 0x0000 }, + { 293, 0x4000 }, { 294, 0x0000 }, { 294, 0x0010 }, { 295, 0x0400 }, + { 296, 0x0000 }, { 296, 0x0000 }, { 296, 0x0000 }, { 296, 0x0000 }, + { 296, 0x0000 }, { 296, 0x0000 }, { 296, 0x0000 }, { 296, 0x0000 }, + /* 0x7900 */ + { 296, 0x0000 }, { 296, 0x0000 }, { 296, 0x0000 }, { 296, 0x0001 }, + { 297, 0x0000 }, { 297, 0x0000 }, { 297, 0x0000 }, { 297, 0x0000 }, + { 297, 0x0000 }, { 297, 0x0810 }, { 299, 0x0000 }, { 299, 0x0000 }, + { 299, 0x0000 }, { 299, 0x0000 }, { 299, 0x0000 }, { 299, 0x0000 }, + /* 0x7a00 */ + { 299, 0x0000 }, { 299, 0x0000 }, { 299, 0x0000 }, { 299, 0x0000 }, + { 299, 0x0000 }, { 299, 0x0000 }, { 299, 0x0000 }, { 299, 0x0000 }, + { 299, 0x0000 }, { 299, 0x0000 }, { 299, 0x0000 }, { 299, 0x0000 }, + { 299, 0x0000 }, { 299, 0x0002 }, { 300, 0x0880 }, { 302, 0x0000 }, + /* 0x7b00 */ + { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0000 }, + { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0000 }, + { 302, 0x0000 }, { 302, 0x4000 }, +}; +static const Summary16 cp932ext_uni2indx_page7d[43] = { + /* 0x7d00 */ + { 303, 0x0000 }, { 303, 0x0000 }, { 303, 0x0000 }, { 303, 0x0000 }, + { 303, 0x0100 }, { 304, 0x1000 }, { 305, 0x0000 }, { 305, 0x0000 }, + { 305, 0x0000 }, { 305, 0x0000 }, { 305, 0x0001 }, { 306, 0x0080 }, + { 307, 0x0000 }, { 307, 0x0040 }, { 308, 0x0000 }, { 308, 0x0000 }, + /* 0x7e00 */ + { 308, 0x0000 }, { 308, 0x0000 }, { 308, 0x0000 }, { 308, 0x0000 }, + { 308, 0x0000 }, { 308, 0x0004 }, { 309, 0x0000 }, { 309, 0x0000 }, + { 309, 0x0400 }, { 310, 0x0000 }, { 310, 0x0000 }, { 310, 0x0000 }, + { 310, 0x0000 }, { 310, 0x0000 }, { 310, 0x0000 }, { 310, 0x0000 }, + /* 0x7f00 */ + { 310, 0x0000 }, { 310, 0x0000 }, { 310, 0x0000 }, { 310, 0x0000 }, + { 310, 0x0080 }, { 311, 0x0000 }, { 311, 0x0000 }, { 311, 0x0000 }, + { 311, 0x0000 }, { 311, 0x0000 }, { 311, 0x0002 }, +}; +static const Summary16 cp932ext_uni2indx_page83[44] = { + /* 0x8300 */ + { 312, 0x0002 }, { 313, 0x0000 }, { 313, 0x0000 }, { 313, 0x0000 }, + { 313, 0x0000 }, { 313, 0x0000 }, { 313, 0x0004 }, { 314, 0x8000 }, + { 315, 0x0000 }, { 315, 0x0000 }, { 315, 0x0000 }, { 315, 0x0000 }, + { 315, 0x0080 }, { 316, 0x0000 }, { 316, 0x0000 }, { 316, 0x0040 }, + /* 0x8400 */ + { 317, 0x0000 }, { 317, 0x0000 }, { 317, 0x0000 }, { 317, 0x0000 }, + { 317, 0x0100 }, { 318, 0x0000 }, { 318, 0x0000 }, { 318, 0x0000 }, + { 318, 0x0000 }, { 318, 0x0000 }, { 318, 0x0000 }, { 318, 0x0010 }, + { 319, 0x0000 }, { 319, 0x1000 }, { 320, 0x0000 }, { 320, 0x0000 }, + /* 0x8500 */ + { 320, 0x0000 }, { 320, 0x0000 }, { 320, 0x0000 }, { 320, 0x0000 }, + { 320, 0x0000 }, { 320, 0x0208 }, { 322, 0x0800 }, { 323, 0x0000 }, + { 323, 0x0000 }, { 323, 0x0000 }, { 323, 0x0000 }, { 323, 0x0001 }, +}; +static const Summary16 cp932ext_uni2indx_page88[109] = { + /* 0x8800 */ + { 324, 0x0080 }, { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, + { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, + { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, + { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0020 }, + /* 0x8900 */ + { 326, 0x0000 }, { 326, 0x1000 }, { 327, 0x0000 }, { 327, 0x0000 }, + { 327, 0x0000 }, { 327, 0x0000 }, { 327, 0x0000 }, { 327, 0x0000 }, + { 327, 0x0000 }, { 327, 0x0000 }, { 327, 0x0000 }, { 327, 0x0000 }, + { 327, 0x0000 }, { 327, 0x0000 }, { 327, 0x0000 }, { 327, 0x0000 }, + /* 0x8a00 */ + { 327, 0x0000 }, { 327, 0x0004 }, { 328, 0x0000 }, { 328, 0x0080 }, + { 329, 0x0000 }, { 329, 0x0000 }, { 329, 0x0000 }, { 329, 0x0200 }, + { 330, 0x0000 }, { 330, 0x0000 }, { 330, 0x0080 }, { 331, 0x4000 }, + { 332, 0x0000 }, { 332, 0x8000 }, { 333, 0x0000 }, { 333, 0x0040 }, + /* 0x8b00 */ + { 334, 0x0000 }, { 334, 0x0000 }, { 334, 0x0000 }, { 334, 0x0000 }, + { 334, 0x0000 }, { 334, 0x0008 }, { 335, 0x0000 }, { 335, 0x8000 }, + { 336, 0x0000 }, { 336, 0x0000 }, { 336, 0x0000 }, { 336, 0x0000 }, + { 336, 0x0000 }, { 336, 0x0000 }, { 336, 0x0000 }, { 336, 0x0000 }, + /* 0x8c00 */ + { 336, 0x0000 }, { 336, 0x0000 }, { 336, 0x0000 }, { 336, 0x0000 }, + { 336, 0x0000 }, { 336, 0x0000 }, { 336, 0x0000 }, { 336, 0x0000 }, + { 336, 0x0000 }, { 336, 0x0000 }, { 336, 0x0000 }, { 336, 0x0000 }, + { 336, 0x0000 }, { 336, 0x0000 }, { 336, 0x0000 }, { 336, 0x0011 }, + /* 0x8d00 */ + { 338, 0x0000 }, { 338, 0x0004 }, { 339, 0x0000 }, { 339, 0x0000 }, + { 339, 0x0000 }, { 339, 0x0000 }, { 339, 0x0000 }, { 339, 0x0040 }, + { 340, 0x0000 }, { 340, 0x0000 }, { 340, 0x0000 }, { 340, 0x0000 }, + { 340, 0x0000 }, { 340, 0x0000 }, { 340, 0x0000 }, { 340, 0x0000 }, + /* 0x8e00 */ + { 340, 0x0000 }, { 340, 0x0000 }, { 340, 0x0000 }, { 340, 0x0000 }, + { 340, 0x0000 }, { 340, 0x0000 }, { 340, 0x0000 }, { 340, 0x0000 }, + { 340, 0x0000 }, { 340, 0x0000 }, { 340, 0x0000 }, { 340, 0x0000 }, + { 340, 0x8000 }, +}; +static const Summary16 cp932ext_uni2indx_page90[238] = { + /* 0x9000 */ + { 341, 0x0000 }, { 341, 0x0000 }, { 341, 0x0000 }, { 341, 0x0000 }, + { 341, 0x0000 }, { 341, 0x0000 }, { 341, 0x0080 }, { 342, 0x0000 }, + { 342, 0x0000 }, { 342, 0x0000 }, { 342, 0x0000 }, { 342, 0x0000 }, + { 342, 0x0000 }, { 342, 0x4000 }, { 343, 0x0000 }, { 343, 0x0000 }, + /* 0x9100 */ + { 343, 0x0000 }, { 343, 0x0020 }, { 344, 0x0080 }, { 345, 0x0000 }, + { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 }, + { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 }, + { 345, 0x0000 }, { 345, 0x4480 }, { 348, 0x6030 }, { 352, 0x0000 }, + /* 0x9200 */ + { 352, 0x0440 }, { 354, 0x0001 }, { 355, 0x0000 }, { 355, 0x1600 }, + { 358, 0x4001 }, { 360, 0x0202 }, { 362, 0x0080 }, { 363, 0x0180 }, + { 365, 0x0100 }, { 366, 0x0000 }, { 366, 0x0080 }, { 367, 0x0000 }, + { 367, 0x0000 }, { 367, 0x02a9 }, { 372, 0x0081 }, { 374, 0x8a00 }, + /* 0x9300 */ + { 377, 0x0004 }, { 378, 0x6000 }, { 380, 0x0022 }, { 382, 0x0000 }, + { 382, 0x0100 }, { 383, 0x0080 }, { 384, 0x0000 }, { 384, 0x0001 }, + { 385, 0x0000 }, { 385, 0x0000 }, { 385, 0x0010 }, { 386, 0x0000 }, + { 386, 0x0040 }, { 387, 0x4000 }, { 388, 0x0000 }, { 388, 0x0100 }, + /* 0x9400 */ + { 389, 0x0000 }, { 389, 0x0000 }, { 389, 0x0000 }, { 389, 0x0002 }, + { 390, 0x0120 }, { 392, 0x0000 }, { 392, 0x0000 }, { 392, 0x0000 }, + { 392, 0x0000 }, { 392, 0x0000 }, { 392, 0x0000 }, { 392, 0x0000 }, + { 392, 0x0000 }, { 392, 0x0000 }, { 392, 0x0000 }, { 392, 0x0000 }, + /* 0x9500 */ + { 392, 0x0000 }, { 392, 0x0000 }, { 392, 0x0000 }, { 392, 0x0000 }, + { 392, 0x0000 }, { 392, 0x0000 }, { 392, 0x0000 }, { 392, 0x0000 }, + { 392, 0x0000 }, { 392, 0x0004 }, { 393, 0x0000 }, { 393, 0x0000 }, + { 393, 0x0000 }, { 393, 0x0000 }, { 393, 0x0000 }, { 393, 0x0000 }, + /* 0x9600 */ + { 393, 0x0000 }, { 393, 0x0000 }, { 393, 0x0000 }, { 393, 0x0000 }, + { 393, 0x0000 }, { 393, 0x0000 }, { 393, 0x0000 }, { 393, 0x0000 }, + { 393, 0x0000 }, { 393, 0x2000 }, { 394, 0x8000 }, { 395, 0x0000 }, + { 395, 0x0000 }, { 395, 0x0000 }, { 395, 0x0000 }, { 395, 0x0000 }, + /* 0x9700 */ + { 395, 0x0000 }, { 395, 0x0000 }, { 395, 0x0000 }, { 395, 0x0808 }, + { 397, 0xa008 }, { 400, 0x0022 }, { 402, 0x0000 }, { 402, 0x0000 }, + { 402, 0x0000 }, { 402, 0x0000 }, { 402, 0x0000 }, { 402, 0x0000 }, + { 402, 0x0000 }, { 402, 0x0000 }, { 402, 0x0000 }, { 402, 0x0000 }, + /* 0x9800 */ + { 402, 0x0000 }, { 402, 0x0000 }, { 402, 0x0000 }, { 402, 0x0000 }, + { 402, 0x0000 }, { 402, 0x0080 }, { 403, 0x0020 }, { 404, 0x0000 }, + { 404, 0x0000 }, { 404, 0x0000 }, { 404, 0x0000 }, { 404, 0x0000 }, + { 404, 0x0000 }, { 404, 0x0000 }, { 404, 0x0000 }, { 404, 0x0000 }, + /* 0x9900 */ + { 404, 0x0000 }, { 404, 0x0000 }, { 404, 0x0080 }, { 405, 0x0000 }, + { 405, 0x0000 }, { 405, 0x0000 }, { 405, 0x0000 }, { 405, 0x0000 }, + { 405, 0x0000 }, { 405, 0x4000 }, { 406, 0x0000 }, { 406, 0x0000 }, + { 406, 0x0000 }, { 406, 0x0000 }, { 406, 0x0000 }, { 406, 0x0000 }, + /* 0x9a00 */ + { 406, 0x0000 }, { 406, 0x0000 }, { 406, 0x0000 }, { 406, 0x0000 }, + { 406, 0x4000 }, { 407, 0x0000 }, { 407, 0x0000 }, { 407, 0x0000 }, + { 407, 0x0000 }, { 407, 0x0000 }, { 407, 0x0000 }, { 407, 0x0000 }, + { 407, 0x0000 }, { 407, 0x1200 }, { 409, 0x0000 }, { 409, 0x0000 }, + /* 0x9b00 */ + { 409, 0x0000 }, { 409, 0x0000 }, { 409, 0x0000 }, { 409, 0x0000 }, + { 409, 0x0000 }, { 409, 0x0000 }, { 409, 0x0000 }, { 409, 0x0024 }, + { 411, 0x8000 }, { 412, 0x0000 }, { 412, 0x0000 }, { 412, 0x0802 }, + { 414, 0x0000 }, { 414, 0x0000 }, { 414, 0x0000 }, { 414, 0x0000 }, + /* 0x9c00 */ + { 414, 0x0001 }, { 415, 0x0000 }, { 415, 0x0000 }, { 415, 0x0000 }, + { 415, 0x0000 }, { 415, 0x0000 }, { 415, 0x0000 }, { 415, 0x0000 }, + { 415, 0x0000 }, { 415, 0x0000 }, { 415, 0x0000 }, { 415, 0x0000 }, + { 415, 0x0000 }, { 415, 0x0000 }, { 415, 0x0000 }, { 415, 0x0000 }, + /* 0x9d00 */ + { 415, 0x0000 }, { 415, 0x0000 }, { 415, 0x0000 }, { 415, 0x0000 }, + { 415, 0x0000 }, { 415, 0x0000 }, { 415, 0x0800 }, { 416, 0x0001 }, + { 417, 0x0000 }, { 417, 0x0000 }, { 417, 0x0000 }, { 417, 0x0000 }, + { 417, 0x0000 }, { 417, 0x0000 }, { 417, 0x0000 }, { 417, 0x0000 }, + /* 0x9e00 */ + { 417, 0x0000 }, { 417, 0x0200 }, { 418, 0x0000 }, { 418, 0x0000 }, + { 418, 0x0000 }, { 418, 0x0000 }, { 418, 0x0000 }, { 418, 0x0000 }, + { 418, 0x0000 }, { 418, 0x0000 }, { 418, 0x0000 }, { 418, 0x0000 }, + { 418, 0x0000 }, { 418, 0x0002 }, +}; +static const Summary16 cp932ext_uni2indx_pagef9[19] = { + /* 0xf900 */ + { 419, 0x0000 }, { 419, 0x0000 }, { 419, 0x0200 }, { 420, 0x0000 }, + { 420, 0x0000 }, { 420, 0x0000 }, { 420, 0x0000 }, { 420, 0x0000 }, + { 420, 0x0000 }, { 420, 0x0000 }, { 420, 0x0000 }, { 420, 0x0000 }, + { 420, 0x0000 }, { 420, 0x1000 }, { 421, 0x0000 }, { 421, 0x0000 }, + /* 0xfa00 */ + { 421, 0xc000 }, { 423, 0xffff }, { 439, 0x3fff }, +}; +static const Summary16 cp932ext_uni2indx_pageff[15] = { + /* 0xff00 */ + { 453, 0x0084 }, { 455, 0x0000 }, { 455, 0x0000 }, { 455, 0x0000 }, + { 455, 0x0000 }, { 455, 0x0000 }, { 455, 0x0000 }, { 455, 0x0000 }, + { 455, 0x0000 }, { 455, 0x0000 }, { 455, 0x0000 }, { 455, 0x0000 }, + { 455, 0x0000 }, { 455, 0x0000 }, { 455, 0x0014 }, +}; + +static int +cp932ext_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc >= 0x2100 && wc < 0x22c0) + summary = &cp932ext_uni2indx_page21[(wc>>4)-0x210]; + else if (wc >= 0x2400 && wc < 0x2480) + summary = &cp932ext_uni2indx_page24[(wc>>4)-0x240]; + else if (wc >= 0x3000 && wc < 0x3020) + summary = &cp932ext_uni2indx_page30[(wc>>4)-0x300]; + else if (wc >= 0x3200 && wc < 0x33d0) + summary = &cp932ext_uni2indx_page32[(wc>>4)-0x320]; + else if (wc >= 0x4e00 && wc < 0x5590) + summary = &cp932ext_uni2indx_page4e[(wc>>4)-0x4e0]; + else if (wc >= 0x5700 && wc < 0x59c0) + summary = &cp932ext_uni2indx_page57[(wc>>4)-0x570]; + else if (wc >= 0x5b00 && wc < 0x5de0) + summary = &cp932ext_uni2indx_page5b[(wc>>4)-0x5b0]; + else if (wc >= 0x5f00 && wc < 0x7ba0) + summary = &cp932ext_uni2indx_page5f[(wc>>4)-0x5f0]; + else if (wc >= 0x7d00 && wc < 0x7fb0) + summary = &cp932ext_uni2indx_page7d[(wc>>4)-0x7d0]; + else if (wc >= 0x8300 && wc < 0x85c0) + summary = &cp932ext_uni2indx_page83[(wc>>4)-0x830]; + else if (wc >= 0x8800 && wc < 0x8ed0) + summary = &cp932ext_uni2indx_page88[(wc>>4)-0x880]; + else if (wc >= 0x9000 && wc < 0x9ee0) + summary = &cp932ext_uni2indx_page90[(wc>>4)-0x900]; + else if (wc >= 0xf900 && wc < 0xfa30) + summary = &cp932ext_uni2indx_pagef9[(wc>>4)-0xf90]; + else if (wc >= 0xff00 && wc < 0xfff0) + summary = &cp932ext_uni2indx_pageff[(wc>>4)-0xff0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = cp932ext_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/cp936.h b/libs/libiconv/lib/cp936.h new file mode 100644 index 00000000..06e510ca --- /dev/null +++ b/libs/libiconv/lib/cp936.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2005 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP936 + */ + +/* + * The IANA has CP936 as an alias of GBK. But GBK is an official Chinese + * specification, whereas CP936 is de-facto maintained by Microsoft. And, + * of course, Microsoft modified CP936 since 1999. + * + * The differences from GBK are: + * + * 1. A single character: + * + * code CP936.TXT + * 0x80 0x20AC # EURO SIGN + * + * Some variants of CP936 (in JDK, Windows-2000, ICU) also add: + * + * 2. Private area mappings: + * + * code Unicode + * 0x{A1..A2}{40..7E,80..A0} U+E4C6..U+E585 + * 0x{AA..AF,F8..FE}{A1..FE} U+E000..U+E4C5 + * + * We add them too because, although there are backward compatibility problems + * when a character from a private area is moved to an official Unicode code + * point, they are useful for some people in practice. + */ + +static int +cp936_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + /* Try GBK first. */ + { + int ret = ces_gbk_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + } + /* Then handle the additional mappings. */ + { + unsigned char c = *s; + if (c == 0x80) { + *pwc = 0x20ac; + return 1; + } + /* User-defined characters */ + if (c >= 0xa1 && c <= 0xa2) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0x80 && c2 < 0xa1)) { + *pwc = 0xe4c6 + 96 * (c - 0xa1) + (c2 - (c2 >= 0x80 ? 0x41 : 0x40)); + return 2; + } + } + } else if ((c >= 0xaa && c < 0xb0) || (c >= 0xf8 && c < 0xff)) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if (c2 >= 0xa1 && c2 < 0xff) { + *pwc = 0xe000 + 94 * (c - (c >= 0xf8 ? 0xf2 : 0xaa)) + (c2 - 0xa1); + return 2; + } + } + } + } + return RET_ILSEQ; +} + +static int +cp936_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + /* Try GBK first. */ + { + int ret = ces_gbk_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + } + /* Then handle the additional mappings. */ + if (wc >= 0xe000 && wc < 0xe586) { + /* User-defined characters */ + if (n < 2) + return RET_TOOFEW(0); + if (wc < 0xe4c6) { + unsigned int i = wc - 0xe000; + unsigned int c1 = i / 94; + unsigned int c2 = i % 94; + r[0] = c1 + (c1 < 6 ? 0xaa : 0xf2); + r[1] = c2 + 0xa1; + return 2; + } else { + unsigned int i = wc - 0xe4c6; + unsigned int c1 = i / 96; + unsigned int c2 = i % 96; + r[0] = c1 + 0xa1; + r[1] = c2 + (c2 < 0x3f ? 0x40 : 0x41); + return 2; + } + } else if (wc == 0x20ac) { + r[0] = 0x80; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp936ext.h b/libs/libiconv/lib/cp936ext.h new file mode 100644 index 00000000..db1817b7 --- /dev/null +++ b/libs/libiconv/lib/cp936ext.h @@ -0,0 +1,99 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP936 extensions + */ + +static const unsigned short cp936ext_2uni_pagea6[181-159] = { + /* 0xa6 */ + 0xfe35, + 0xfe36, 0xfe39, 0xfe3a, 0xfe3f, 0xfe40, 0xfe3d, 0xfe3e, 0xfe41, + 0xfe42, 0xfe43, 0xfe44, 0xfffd, 0xfffd, 0xfe3b, 0xfe3c, 0xfe37, + 0xfe38, 0xfe31, 0xfffd, 0xfe33, 0xfe34, +}; +static const unsigned short cp936ext_2uni_pagea8[128-122] = { + /* 0xa8 */ + 0x0251, 0xfffd, 0x0144, 0x0148, 0xfffd, 0x0261, +}; + +static int +cp936ext_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 == 0xa6) || (c1 == 0xa8)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0x80 && c2 < 0xff)) { + unsigned int i = 190 * (c1 - 0x81) + (c2 - (c2 >= 0x80 ? 0x41 : 0x40)); + unsigned short wc = 0xfffd; + if (i < 7410) { + if (i >= 7189 && i < 7211) + wc = cp936ext_2uni_pagea6[i-7189]; + } else { + if (i >= 7532 && i < 7538) + wc = cp936ext_2uni_pagea8[i-7532]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short cp936ext_page01[16] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0xa8bd, 0x0000, 0x0000, 0x0000, /*0x40-0x47*/ + 0xa8be, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x48-0x4f*/ +}; +static const unsigned short cp936ext_page02[24] = { + 0x0000, 0xa8bb, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x50-0x57*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x58-0x5f*/ + 0x0000, 0xa8c0, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x60-0x67*/ +}; +static const unsigned short cp936ext_pagefe[24] = { + 0x0000, 0xa6f2, 0x0000, 0xa6f4, 0xa6f5, 0xa6e0, 0xa6e1, 0xa6f0, /*0x30-0x37*/ + 0xa6f1, 0xa6e2, 0xa6e3, 0xa6ee, 0xa6ef, 0xa6e6, 0xa6e7, 0xa6e4, /*0x38-0x3f*/ + 0xa6e5, 0xa6e8, 0xa6e9, 0xa6ea, 0xa6eb, 0x0000, 0x0000, 0x0000, /*0x40-0x47*/ +}; + +static int +cp936ext_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + unsigned short c = 0; + if (wc >= 0x0140 && wc < 0x0150) + c = cp936ext_page01[wc-0x0140]; + else if (wc >= 0x0250 && wc < 0x0268) + c = cp936ext_page02[wc-0x0250]; + else if (wc >= 0xfe30 && wc < 0xfe48) + c = cp936ext_pagefe[wc-0xfe30]; + if (c != 0) { + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/cp943.h b/libs/libiconv/lib/cp943.h new file mode 100644 index 00000000..dbaebe97 --- /dev/null +++ b/libs/libiconv/lib/cp943.h @@ -0,0 +1,29 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * IBM CP943 + */ + +/* This is essentially CP932, with many mappings missing in the AIX conversion + table. We just pretend it were the same as CP932. */ + +#define cp943_mbtowc cp932_mbtowc +#define cp943_wctomb cp932_wctomb diff --git a/libs/libiconv/lib/cp949.h b/libs/libiconv/lib/cp949.h new file mode 100644 index 00000000..665e7243 --- /dev/null +++ b/libs/libiconv/lib/cp949.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 1999-2001, 2005, 2007 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP949 is EUC-KR, extended with UHC (Unified Hangul Code). + * + * Some variants of CP949 (in JDK, Windows-2000, ICU) also add: + * + * 2. Private area mappings: + * + * code Unicode + * 0xC9{A1..FE} U+E000..U+E05D + * 0xFE{A1..FE} U+E05E..U+E0BB + * + * We add them too because, although there are backward compatibility problems + * when a character from a private area is moved to an official Unicode code + * point, they are useful for some people in practice. + */ + +#include "uhc_1.h" +#include "uhc_2.h" + +static int +cp949_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + /* Code set 0 (ASCII) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* UHC part 1 */ + if (c >= 0x81 && c <= 0xa0) + return uhc_1_mbtowc(conv,pwc,s,n); + if (c >= 0xa1 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if (c2 < 0xa1) + /* UHC part 2 */ + return uhc_2_mbtowc(conv,pwc,s,n); + else if (c2 < 0xff && !(c == 0xa2 && c2 == 0xe8)) { + /* Code set 1 (KS C 5601-1992, now KS X 1001:1998) */ + unsigned char buf[2]; + int ret; + buf[0] = c-0x80; buf[1] = c2-0x80; + ret = ksc5601_mbtowc(conv,pwc,buf,2); + if (ret != RET_ILSEQ) + return ret; + /* User-defined characters */ + if (c == 0xc9) { + *pwc = 0xe000 + (c2 - 0xa1); + return 2; + } + if (c == 0xfe) { + *pwc = 0xe05e + (c2 - 0xa1); + return 2; + } + } + } + } + return RET_ILSEQ; +} + +static int +cp949_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[2]; + int ret; + + /* Code set 0 (ASCII) */ + ret = ascii_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + /* Code set 1 (KS C 5601-1992, now KS X 1001:1998) */ + if (wc != 0x327e) { + ret = ksc5601_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]+0x80; + r[1] = buf[1]+0x80; + return 2; + } + } + + /* UHC */ + if (wc >= 0xac00 && wc < 0xd7a4) { + if (wc < 0xc8a5) + return uhc_1_wctomb(conv,r,wc,n); + else + return uhc_2_wctomb(conv,r,wc,n); + } + + /* User-defined characters */ + if (wc >= 0xe000 && wc < 0xe0bc) { + if (n < 2) + return RET_TOOSMALL; + if (wc < 0xe05e) { + r[0] = 0xc9; + r[1] = wc - 0xe000 + 0xa1; + } else { + r[0] = 0xfe; + r[1] = wc - 0xe05e + 0xa1; + } + return 2; + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp950.h b/libs/libiconv/lib/cp950.h new file mode 100644 index 00000000..28ca1994 --- /dev/null +++ b/libs/libiconv/lib/cp950.h @@ -0,0 +1,284 @@ +/* + * Copyright (C) 1999-2001, 2005 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP950 + */ + +/* + * Microsoft CP950 is a slightly extended and slightly modified version of + * BIG5. The differences between the EASTASIA/OTHER/BIG5.TXT and + * VENDORS/MICSFT/WINDOWS/CP950.TXT tables found on ftp.unicode.org are + * as follows: + * + * 1. Some characters in the BIG5 range are defined differently: + * + * code BIG5.TXT CP950.TXT + * 0xA145 0x2022 # BULLET 0x2027 # HYPHENATION POINT + * 0xA14E 0xFF64 # HALFWIDTH IDEOGRAPHIC COMMA + * 0xFE51 # SMALL IDEOGRAPHIC COMMA + * 0xA15A --- 0x2574 # BOX DRAWINGS LIGHT LEFT + * 0xA1C2 0x203E # OVERLINE 0x00AF # MACRON + * 0xA1C3 --- 0xFFE3 # FULLWIDTH MACRON + * 0xA1C5 --- 0x02CD # MODIFIER LETTER LOW MACRON + * 0xA1E3 0x223C # TILDE OPERATOR 0xFF5E # FULLWIDTH TILDE + * 0xA1F2 0x2641 # EARTH 0x2295 # CIRCLED PLUS + * 0xA1F3 0x2609 # SUN 0x2299 # CIRCLED DOT OPERATOR + * 0xA1FE --- 0xFF0F # FULLWIDTH SOLIDUS + * 0xA240 --- 0xFF3C # FULLWIDTH REVERSE SOLIDUS + * 0xA241 0xFF0F # FULLWIDTH SOLIDUS 0x2215 # DIVISION SLASH + * 0xA242 0xFF3C # FULLWIDTH REVERSE SOLIDUS + * 0xFE68 # SMALL REVERSE SOLIDUS + * 0xA244 0x00A5 # YEN SIGN 0xFFE5 # FULLWIDTH YEN SIGN + * 0xA246 0x00A2 # CENT SIGN 0xFFE0 # FULLWIDTH CENT SIGN + * 0xA247 0x00A3 # POUND SIGN 0xFFE1 # FULLWIDTH POUND SIGN + * 0xA2CC --- 0x5341 + * 0xA2CE --- 0x5345 + * + * 2. A small new row. See cp950ext.h. + * + * 3. CP950.TXT is lacking the range 0xC6A1..0xC7FC (Hiragana, Katakana, + * Cyrillic, circled digits, parenthesized digits). + * + * We implement this omission, because said range is marked "uncertain" + * in the unicode.org BIG5 table. + * + * The table found on Microsoft's website furthermore adds: + * + * 4. A single character: + * + * code CP950.TXT + * 0xA3E1 0x20AC # EURO SIGN + * + * Many variants of BIG5 or CP950 (in JDK, Solaris, OSF/1, Windows-2000, ICU, + * as well as our BIG5-2003 converter) also add: + * + * 5. Private area mappings: + * + * code Unicode + * 0x{81..8D}{40..7E,A1..FE} U+EEB8..U+F6B0 + * 0x{8E..A0}{40..7E,A1..FE} U+E311..U+EEB7 + * 0x{FA..FE}{40..7E,A1..FE} U+E000..U+E310 + * + * We add them too because, although there are backward compatibility problems + * when a character from a private area is moved to an official Unicode code + * point, they are useful for some people in practice. + */ + +static const unsigned short cp950_2uni_pagea1[314] = { + /* 0xa1 */ + 0x3000, 0xff0c, 0x3001, 0x3002, 0xff0e, 0x2027, 0xff1b, 0xff1a, + 0xff1f, 0xff01, 0xfe30, 0x2026, 0x2025, 0xfe50, 0xfe51, 0xfe52, + 0x00b7, 0xfe54, 0xfe55, 0xfe56, 0xfe57, 0xff5c, 0x2013, 0xfe31, + 0x2014, 0xfe33, 0x2574, 0xfe34, 0xfe4f, 0xff08, 0xff09, 0xfe35, + 0xfe36, 0xff5b, 0xff5d, 0xfe37, 0xfe38, 0x3014, 0x3015, 0xfe39, + 0xfe3a, 0x3010, 0x3011, 0xfe3b, 0xfe3c, 0x300a, 0x300b, 0xfe3d, + 0xfe3e, 0x3008, 0x3009, 0xfe3f, 0xfe40, 0x300c, 0x300d, 0xfe41, + 0xfe42, 0x300e, 0x300f, 0xfe43, 0xfe44, 0xfe59, 0xfe5a, 0xfe5b, + 0xfe5c, 0xfe5d, 0xfe5e, 0x2018, 0x2019, 0x201c, 0x201d, 0x301d, + 0x301e, 0x2035, 0x2032, 0xff03, 0xff06, 0xff0a, 0x203b, 0x00a7, + 0x3003, 0x25cb, 0x25cf, 0x25b3, 0x25b2, 0x25ce, 0x2606, 0x2605, + 0x25c7, 0x25c6, 0x25a1, 0x25a0, 0x25bd, 0x25bc, 0x32a3, 0x2105, + 0x00af, 0xffe3, 0xff3f, 0x02cd, 0xfe49, 0xfe4a, 0xfe4d, 0xfe4e, + 0xfe4b, 0xfe4c, 0xfe5f, 0xfe60, 0xfe61, 0xff0b, 0xff0d, 0x00d7, + 0x00f7, 0x00b1, 0x221a, 0xff1c, 0xff1e, 0xff1d, 0x2266, 0x2267, + 0x2260, 0x221e, 0x2252, 0x2261, 0xfe62, 0xfe63, 0xfe64, 0xfe65, + 0xfe66, 0xff5e, 0x2229, 0x222a, 0x22a5, 0x2220, 0x221f, 0x22bf, + 0x33d2, 0x33d1, 0x222b, 0x222e, 0x2235, 0x2234, 0x2640, 0x2642, + 0x2295, 0x2299, 0x2191, 0x2193, 0x2190, 0x2192, 0x2196, 0x2197, + 0x2199, 0x2198, 0x2225, 0x2223, 0xff0f, + /* 0xa2 */ + 0xff3c, 0x2215, 0xfe68, 0xff04, 0xffe5, 0x3012, 0xffe0, 0xffe1, + 0xff05, 0xff20, 0x2103, 0x2109, 0xfe69, 0xfe6a, 0xfe6b, 0x33d5, + 0x339c, 0x339d, 0x339e, 0x33ce, 0x33a1, 0x338e, 0x338f, 0x33c4, + 0x00b0, 0x5159, 0x515b, 0x515e, 0x515d, 0x5161, 0x5163, 0x55e7, + 0x74e9, 0x7cce, 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586, + 0x2587, 0x2588, 0x258f, 0x258e, 0x258d, 0x258c, 0x258b, 0x258a, + 0x2589, 0x253c, 0x2534, 0x252c, 0x2524, 0x251c, 0x2594, 0x2500, + 0x2502, 0x2595, 0x250c, 0x2510, 0x2514, 0x2518, 0x256d, 0x256e, + 0x2570, 0x256f, 0x2550, 0x255e, 0x256a, 0x2561, 0x25e2, 0x25e3, + 0x25e5, 0x25e4, 0x2571, 0x2572, 0x2573, 0xff10, 0xff11, 0xff12, + 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18, 0xff19, 0x2160, + 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, + 0x2169, 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, 0x3027, + 0x3028, 0x3029, 0x5341, 0x5344, 0x5345, 0xff21, 0xff22, 0xff23, + 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, 0xff29, 0xff2a, 0xff2b, + 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, 0xff31, 0xff32, 0xff33, + 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, 0xff39, 0xff3a, 0xff41, + 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, 0xff49, + 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, 0xff51, + 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, +}; + +#include "cp950ext.h" + +static int +cp950_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + /* Code set 0 (ASCII) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* Code set 1 (BIG5 extended) */ + if (c >= 0x81 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) { + if (c >= 0xa1) { + if (c < 0xa3) { + unsigned int i = 157 * (c - 0xa1) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); + unsigned short wc = cp950_2uni_pagea1[i]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + if (!((c == 0xc6 && c2 >= 0xa1) || c == 0xc7)) { + int ret = big5_mbtowc(conv,pwc,s,2); + if (ret != RET_ILSEQ) + return ret; + } + if (c == 0xa3 && c2 == 0xe1) { + *pwc = 0x20ac; + return 2; + } + if (c >= 0xfa) { + /* User-defined characters */ + *pwc = 0xe000 + 157 * (c - 0xfa) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); + return 2; + } + } else { + /* 0x81 <= c < 0xa1. */ + /* User-defined characters */ + *pwc = (c >= 0x8e ? 0xdb18 : 0xeeb8) + 157 * (c - 0x81) + + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); + return 2; + } + } + } + if (c == 0xf9) { + int ret = cp950ext_mbtowc(conv,pwc,s,2); + if (ret != RET_ILSEQ) + return ret; + } + } + return RET_ILSEQ; +} + +static int +cp950_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[2]; + int ret; + + /* Code set 0 (ASCII) */ + ret = ascii_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + /* Code set 1 (BIG5 extended) */ + switch (wc >> 8) { + case 0x00: + if (wc == 0x00af) { buf[0] = 0xa1; buf[1] = 0xc2; ret = 2; break; } + if (wc == 0x00a2 || wc == 0x00a3 || wc == 0x00a4) + return RET_ILUNI; + break; + case 0x02: + if (wc == 0x02cd) { buf[0] = 0xa1; buf[1] = 0xc5; ret = 2; break; } + break; + case 0x20: + if (wc == 0x2027) { buf[0] = 0xa1; buf[1] = 0x45; ret = 2; break; } + if (wc == 0x20ac) { buf[0] = 0xa3; buf[1] = 0xe1; ret = 2; break; } + if (wc == 0x2022 || wc == 0x203e) + return RET_ILUNI; + break; + case 0x22: + if (wc == 0x2215) { buf[0] = 0xa2; buf[1] = 0x41; ret = 2; break; } + if (wc == 0x2295) { buf[0] = 0xa1; buf[1] = 0xf2; ret = 2; break; } + if (wc == 0x2299) { buf[0] = 0xa1; buf[1] = 0xf3; ret = 2; break; } + if (wc == 0x223c) + return RET_ILUNI; + break; + case 0x25: + if (wc == 0x2574) { buf[0] = 0xa1; buf[1] = 0x5a; ret = 2; break; } + break; + case 0x26: + if (wc == 0x2609 || wc == 0x2641) + return RET_ILUNI; + break; + case 0xe0: case 0xe1: case 0xe2: case 0xe3: case 0xe4: case 0xe5: + case 0xe6: case 0xe7: case 0xe8: case 0xe9: case 0xea: case 0xeb: + case 0xec: case 0xed: case 0xee: case 0xef: case 0xf0: case 0xf1: + case 0xf2: case 0xf3: case 0xf4: case 0xf5: case 0xf6: + { + /* User-defined characters */ + unsigned int i = wc - 0xe000; + if (i < 5809) { + unsigned int c1 = i / 157; + unsigned int c2 = i % 157; + buf[0] = c1 + (c1 < 5 ? 0xfa : c1 < 24 ? 0x89 : 0x69); + buf[1] = c2 + (c2 < 0x3f ? 0x40 : 0x62); + ret = 2; + break; + } + } + break; + case 0xfe: + if (wc == 0xfe51) { buf[0] = 0xa1; buf[1] = 0x4e; ret = 2; break; } + if (wc == 0xfe68) { buf[0] = 0xa2; buf[1] = 0x42; ret = 2; break; } + break; + case 0xff: + if (wc == 0xff0f) { buf[0] = 0xa1; buf[1] = 0xfe; ret = 2; break; } + if (wc == 0xff3c) { buf[0] = 0xa2; buf[1] = 0x40; ret = 2; break; } + if (wc == 0xff5e) { buf[0] = 0xa1; buf[1] = 0xe3; ret = 2; break; } + if (wc == 0xffe0) { buf[0] = 0xa2; buf[1] = 0x46; ret = 2; break; } + if (wc == 0xffe1) { buf[0] = 0xa2; buf[1] = 0x47; ret = 2; break; } + if (wc == 0xffe3) { buf[0] = 0xa1; buf[1] = 0xc3; ret = 2; break; } + if (wc == 0xffe5) { buf[0] = 0xa2; buf[1] = 0x44; ret = 2; break; } + if (wc == 0xff64) + return RET_ILUNI; + break; + } + if (ret == RET_ILUNI) + ret = big5_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (!((buf[0] == 0xc6 && buf[1] >= 0xa1) || buf[0] == 0xc7)) { + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]; + r[1] = buf[1]; + return 2; + } + } + ret = cp950ext_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]; + r[1] = buf[1]; + return 2; + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/cp950ext.h b/libs/libiconv/lib/cp950ext.h new file mode 100644 index 00000000..2a18d805 --- /dev/null +++ b/libs/libiconv/lib/cp950ext.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * CP950 extensions + */ + +static const unsigned short cp950ext_2uni_pagef9[157-116] = { + /* 0xf9 */ + 0x7881, 0x92b9, 0x88cf, 0x58bb, + 0x6052, 0x7ca7, 0x5afa, 0x2554, 0x2566, 0x2557, 0x2560, 0x256c, + 0x2563, 0x255a, 0x2569, 0x255d, 0x2552, 0x2564, 0x2555, 0x255e, + 0x256a, 0x2561, 0x2558, 0x2567, 0x255b, 0x2553, 0x2565, 0x2556, + 0x255f, 0x256b, 0x2562, 0x2559, 0x2568, 0x255c, 0x2551, 0x2550, + 0x256d, 0x256e, 0x2570, 0x256f, 0x2593, +}; + +static int +cp950ext_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 == 0xf9)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) { + unsigned int i = 157 * (c1 - 0xa1) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); + unsigned short wc = 0xfffd; + { + if (i >= 13932 && i < 13973) + wc = cp950ext_2uni_pagef9[i-13932]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short cp950ext_2charset[41] = { + 0xf9f9, 0xf9f8, 0xf9e6, 0xf9ef, 0xf9dd, 0xf9e8, 0xf9f1, 0xf9df, + 0xf9ec, 0xf9f5, 0xf9e3, 0xf9ee, 0xf9f7, 0xf9e5, 0xf9e9, 0xf9f2, + 0xf9e0, 0xf9eb, 0xf9f4, 0xf9e2, 0xf9e7, 0xf9f0, 0xf9de, 0xf9ed, + 0xf9f6, 0xf9e4, 0xf9ea, 0xf9f3, 0xf9e1, 0xf9fa, 0xf9fb, 0xf9fd, + 0xf9fc, 0xf9fe, 0xf9d9, 0xf9dc, 0xf9da, 0xf9d6, 0xf9db, 0xf9d8, + 0xf9d7, +}; + +static const Summary16 cp950ext_uni2indx_page25[10] = { + /* 0x2500 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0xffff }, { 16, 0xffff }, { 32, 0x0001 }, + { 33, 0x0000 }, { 33, 0x0008 }, +}; +static const Summary16 cp950ext_uni2indx_page58[12] = { + /* 0x5800 */ + { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0000 }, + { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0000 }, + { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0800 }, +}; +static const Summary16 cp950ext_uni2indx_page5a[16] = { + /* 0x5a00 */ + { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, + { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, + { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, + { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0400 }, +}; +static const Summary16 cp950ext_uni2indx_page60[6] = { + /* 0x6000 */ + { 36, 0x0000 }, { 36, 0x0000 }, { 36, 0x0000 }, { 36, 0x0000 }, + { 36, 0x0000 }, { 36, 0x0004 }, +}; +static const Summary16 cp950ext_uni2indx_page78[9] = { + /* 0x7800 */ + { 37, 0x0000 }, { 37, 0x0000 }, { 37, 0x0000 }, { 37, 0x0000 }, + { 37, 0x0000 }, { 37, 0x0000 }, { 37, 0x0000 }, { 37, 0x0000 }, + { 37, 0x0002 }, +}; +static const Summary16 cp950ext_uni2indx_page7c[11] = { + /* 0x7c00 */ + { 38, 0x0000 }, { 38, 0x0000 }, { 38, 0x0000 }, { 38, 0x0000 }, + { 38, 0x0000 }, { 38, 0x0000 }, { 38, 0x0000 }, { 38, 0x0000 }, + { 38, 0x0000 }, { 38, 0x0000 }, { 38, 0x0080 }, +}; +static const Summary16 cp950ext_uni2indx_page88[13] = { + /* 0x8800 */ + { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0000 }, + { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0000 }, + { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0000 }, + { 39, 0x8000 }, +}; +static const Summary16 cp950ext_uni2indx_page92[12] = { + /* 0x9200 */ + { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0000 }, + { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0000 }, + { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0200 }, +}; + +static int +cp950ext_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc >= 0x2500 && wc < 0x25a0) + summary = &cp950ext_uni2indx_page25[(wc>>4)-0x250]; + else if (wc >= 0x5800 && wc < 0x58c0) + summary = &cp950ext_uni2indx_page58[(wc>>4)-0x580]; + else if (wc >= 0x5a00 && wc < 0x5b00) + summary = &cp950ext_uni2indx_page5a[(wc>>4)-0x5a0]; + else if (wc >= 0x6000 && wc < 0x6060) + summary = &cp950ext_uni2indx_page60[(wc>>4)-0x600]; + else if (wc >= 0x7800 && wc < 0x7890) + summary = &cp950ext_uni2indx_page78[(wc>>4)-0x780]; + else if (wc >= 0x7c00 && wc < 0x7cb0) + summary = &cp950ext_uni2indx_page7c[(wc>>4)-0x7c0]; + else if (wc >= 0x8800 && wc < 0x88d0) + summary = &cp950ext_uni2indx_page88[(wc>>4)-0x880]; + else if (wc >= 0x9200 && wc < 0x92c0) + summary = &cp950ext_uni2indx_page92[(wc>>4)-0x920]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = cp950ext_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/dec_hanyu.h b/libs/libiconv/lib/dec_hanyu.h new file mode 100644 index 00000000..065fd5d5 --- /dev/null +++ b/libs/libiconv/lib/dec_hanyu.h @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2001, 2005 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * DEC-HANYU + */ + +static int +dec_hanyu_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + /* Code set 0 (ASCII) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* Code set 1 (CNS 11643-1992 Plane 1), + Code set 2 (CNS 11643-1992 Plane 2), + Code set 3 (CNS 11643-1992 Plane 3) */ + if (c >= 0xa1 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if (c == 0xc2 && c2 == 0xcb) { + if (n < 4) + return RET_TOOFEW(0); + if (s[2] >= 0xa1 && s[2] < 0xff && s[3] >= 0xa1 && s[3] < 0xff) { + unsigned char buf[2]; + int ret; + buf[0] = s[2]-0x80; buf[1] = s[3]-0x80; + ret = cns11643_3_mbtowc(conv,pwc,buf,2); + if (ret != RET_ILSEQ) { + if (ret != 2) abort(); + return 4; + } + } + } else if (c2 >= 0xa1 && c2 < 0xff) { + if (c != 0xc2 || c2 < 0xc2) { + unsigned char buf[2]; + buf[0] = c-0x80; buf[1] = c2-0x80; + return cns11643_1_mbtowc(conv,pwc,buf,2); + } + } else if (c2 >= 0x21 && c2 < 0x7f) { + unsigned char buf[2]; + buf[0] = c-0x80; buf[1] = c2; + return cns11643_2_mbtowc(conv,pwc,buf,2); + } + } + } + return RET_ILSEQ; +} + +static int +dec_hanyu_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[3]; + int ret; + + /* Code set 0 (ASCII) */ + ret = ascii_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + ret = cns11643_wctomb(conv,buf,wc,3); + if (ret != RET_ILUNI) { + if (ret != 3) abort(); + + /* Code set 1 (CNS 11643-1992 Plane 1) */ + if (buf[0] == 1 && (buf[1] != 0x42 || buf[2] < 0x42)) { + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[1]+0x80; + r[1] = buf[2]+0x80; + return 2; + } + + /* Code set 2 (CNS 11643-1992 Plane 2) */ + if (buf[0] == 2) { + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[1]+0x80; + r[1] = buf[2]; + return 2; + } + + /* Code set 3 (CNS 11643-1992 Plane 3) */ + if (buf[0] == 3) { + if (n < 4) + return RET_TOOSMALL; + r[0] = 0xc2; + r[1] = 0xcb; + r[2] = buf[1]+0x80; + r[3] = buf[2]+0x80; + return 4; + } + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/dec_kanji.h b/libs/libiconv/lib/dec_kanji.h new file mode 100644 index 00000000..0a056fb8 --- /dev/null +++ b/libs/libiconv/lib/dec_kanji.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * DEC-KANJI + */ + +static int +dec_kanji_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + /* Code set 0 (ASCII or JIS X 0201-1976 Roman) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* Code set 1 (JIS X 0208) */ + if (c >= 0xa1 && c < 0xf5) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if (c2 >= 0xa1 && c2 < 0xff) { + unsigned char buf[2]; + buf[0] = c-0x80; buf[1] = c2-0x80; + return jisx0208_mbtowc(conv,pwc,buf,2); + } + } + } + return RET_ILSEQ; +} + +static int +dec_kanji_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[2]; + int ret; + + /* Code set 0 (ASCII or JIS X 0201-1976 Roman) */ + ret = ascii_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + /* Code set 1 (JIS X 0208) */ + ret = jisx0208_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]+0x80; + r[1] = buf[1]+0x80; + return 2; + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/encodings.def b/libs/libiconv/lib/encodings.def new file mode 100644 index 00000000..01743435 --- /dev/null +++ b/libs/libiconv/lib/encodings.def @@ -0,0 +1,1030 @@ +/* Copyright (C) 1999-2010 Free Software Foundation, Inc. + This file is part of the GNU LIBICONV Library. + + The GNU LIBICONV Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + The GNU LIBICONV Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU LIBICONV Library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* The list of all system independent user-visible encodings. */ + +/* By convention, an encoding named FOOBAR or FOO_BAR or FOO-BAR is defined + in a file named "foobar.h" through the functions foobar_mbtowc and + foobar_wctomb (and possibly foobar_reset). */ + +/* DEFENCODING(( name, alias1, ..., ), + xxx, + { xxx_mbtowc, xxx_flushwc }, + { xxx_wctomb, xxx_reset }) + defines an encoding with the given name and aliases. (There is no + difference between a name and an alias. By convention, the name is chosen + as the preferred MIME name or the standard name.) + All names and aliases must be in ASCII. Case is not significant, but + for the "cs*" aliases mixed case is preferred, otherwise UPPERCASE is + preferred. For all names and aliases, note where it comes from. + xxx is the name as used in the C code (lowercase). + */ + + +DEFENCODING(( "US-ASCII", /* IANA */ + "ASCII", /* IANA, JDK 1.1 */ + "ISO646-US", /* IANA */ + "ISO_646.IRV:1991", /* IANA */ + "ISO-IR-6", /* IANA */ + "ANSI_X3.4-1968", /* IANA */ + "ANSI_X3.4-1986", /* IANA */ + "CP367", /* IANA */ + "IBM367", /* IANA */ + "US", /* IANA */ + "csASCII", /* IANA */ + /*"ISO646.1991-IRV", X11R6.4 */ + ), + ascii, + { ascii_mbtowc, NULL }, { ascii_wctomb, NULL }) +#ifdef USE_SOLARIS_ALIASES +DEFALIAS( "646", /* Solaris */ + ascii) +#endif + +/* General multi-byte encodings */ + +DEFENCODING(( "UTF-8", /* IANA, RFC 2279 */ + /*"UTF8", JDK 1.1 */ + /*"CP65001", Windows */ + ), + utf8, + { utf8_mbtowc, NULL }, { utf8_wctomb, NULL }) +#ifdef USE_HPUX_ALIASES +DEFALIAS( "UTF8", /* HP-UX */ + utf8) +#endif + +DEFENCODING(( "UCS-2", /* glibc */ + "ISO-10646-UCS-2", /* IANA */ + "csUnicode", /* IANA */ + ), + ucs2, + { ucs2_mbtowc, NULL }, { ucs2_wctomb, NULL }) + +DEFENCODING(( "UCS-2BE", /* glibc */ + "UNICODEBIG", /* glibc */ + "UNICODE-1-1", /* IANA */ + "csUnicode11", /* IANA */ + /*"CP1201", Windows */ + ), + ucs2be, + { ucs2be_mbtowc, NULL }, { ucs2be_wctomb, NULL }) + +DEFENCODING(( "UCS-2LE", /* glibc */ + "UNICODELITTLE", /* glibc */ + /*"CP1200", Windows */ + ), + ucs2le, + { ucs2le_mbtowc, NULL }, { ucs2le_wctomb, NULL }) + +DEFENCODING(( "UCS-4", /* glibc */ + "ISO-10646-UCS-4", /* IANA */ + "csUCS4", /* IANA */ + ), + ucs4, + { ucs4_mbtowc, NULL }, { ucs4_wctomb, NULL }) + +DEFENCODING(( "UCS-4BE", /* glibc */ + /*"CP12001", Windows */ + ), + ucs4be, + { ucs4be_mbtowc, NULL }, { ucs4be_wctomb, NULL }) + +DEFENCODING(( "UCS-4LE", /* glibc */ + /*"CP12000", Windows */ + ), + ucs4le, + { ucs4le_mbtowc, NULL }, { ucs4le_wctomb, NULL }) + +DEFENCODING(( "UTF-16", /* IANA, RFC 2781 */ + ), + utf16, + { utf16_mbtowc, NULL }, { utf16_wctomb, NULL }) + +DEFENCODING(( "UTF-16BE", /* IANA, RFC 2781 */ + ), + utf16be, + { utf16be_mbtowc, NULL }, { utf16be_wctomb, NULL }) + +DEFENCODING(( "UTF-16LE", /* IANA, RFC 2781 */ + ), + utf16le, + { utf16le_mbtowc, NULL }, { utf16le_wctomb, NULL }) + +DEFENCODING(( "UTF-32", /* IANA, Unicode 3.1 */ + ), + utf32, + { utf32_mbtowc, NULL }, { utf32_wctomb, NULL }) + +DEFENCODING(( "UTF-32BE", /* IANA, Unicode 3.1 */ + ), + utf32be, + { utf32be_mbtowc, NULL }, { utf32be_wctomb, NULL }) + +DEFENCODING(( "UTF-32LE", /* IANA, Unicode 3.1 */ + ), + utf32le, + { utf32le_mbtowc, NULL }, { utf32le_wctomb, NULL }) + +DEFENCODING(( "UTF-7", /* IANA, RFC 2152 */ + "UNICODE-1-1-UTF-7", /* IANA, RFC 1642 */ + "csUnicode11UTF7", /* IANA */ + /*"CP65000", Windows */ + ), + utf7, + { utf7_mbtowc, NULL }, { utf7_wctomb, utf7_reset }) + +DEFENCODING(( "UCS-2-INTERNAL", /* libiconv */ + ), + ucs2internal, + { ucs2internal_mbtowc, NULL }, { ucs2internal_wctomb, NULL }) + +DEFENCODING(( "UCS-2-SWAPPED", /* libiconv */ + ), + ucs2swapped, + { ucs2swapped_mbtowc, NULL }, { ucs2swapped_wctomb, NULL }) + +DEFENCODING(( "UCS-4-INTERNAL", /* libiconv */ + ), + ucs4internal, + { ucs4internal_mbtowc, NULL },{ ucs4internal_wctomb, NULL }) + +DEFENCODING(( "UCS-4-SWAPPED", /* libiconv */ + ), + ucs4swapped, + { ucs4swapped_mbtowc, NULL }, { ucs4swapped_wctomb, NULL }) + +DEFENCODING(( "C99", + ), + c99, + { c99_mbtowc, NULL }, { c99_wctomb, NULL }) + +DEFENCODING(( "JAVA", + ), + java, + { java_mbtowc, NULL }, { java_wctomb, NULL }) + +/* Standard 8-bit encodings */ + +DEFENCODING(( "ISO-8859-1", /* IANA */ + "ISO_8859-1", /* IANA */ + "ISO_8859-1:1987", /* IANA */ + "ISO-IR-100", /* IANA */ + "CP819", /* IANA */ + "IBM819", /* IANA */ + "LATIN1", /* IANA */ + "L1", /* IANA */ + "csISOLatin1", /* IANA */ + "ISO8859-1", /* X11R6.4, glibc, FreeBSD, AIX, IRIX, OSF/1, Solaris */ + /*"ISO8859_1", JDK 1.1 */ + /*"CP28591", Windows */ + ), + iso8859_1, + { iso8859_1_mbtowc, NULL }, { iso8859_1_wctomb, NULL }) +#ifdef USE_HPUX_ALIASES +DEFALIAS( "ISO88591", /* HP-UX */ + iso8859_1) +#endif + +DEFENCODING(( "ISO-8859-2", /* IANA */ + "ISO_8859-2", /* IANA */ + "ISO_8859-2:1987", /* IANA */ + "ISO-IR-101", /* IANA */ + "LATIN2", /* IANA */ + "L2", /* IANA */ + "csISOLatin2", /* IANA */ + "ISO8859-2", /* X11R6.4, glibc, FreeBSD, AIX, IRIX, OSF/1, Solaris */ + /*"ISO8859_2", JDK 1.1 */ + /*"CP28592", Windows */ + ), + iso8859_2, + { iso8859_2_mbtowc, NULL }, { iso8859_2_wctomb, NULL }) +#ifdef USE_HPUX_ALIASES +DEFALIAS( "ISO88592", /* HP-UX */ + iso8859_2) +#endif + +DEFENCODING(( "ISO-8859-3", /* IANA */ + "ISO_8859-3", /* IANA */ + "ISO_8859-3:1988", /* IANA */ + "ISO-IR-109", /* IANA */ + "LATIN3", /* IANA */ + "L3", /* IANA */ + "csISOLatin3", /* IANA */ + "ISO8859-3", /* X11R6.4, glibc, FreeBSD, Solaris */ + /*"ISO8859_3", JDK 1.1 */ + /*"CP28593", Windows */ + ), + iso8859_3, + { iso8859_3_mbtowc, NULL }, { iso8859_3_wctomb, NULL }) + +DEFENCODING(( "ISO-8859-4", /* IANA */ + "ISO_8859-4", /* IANA */ + "ISO_8859-4:1988", /* IANA */ + "ISO-IR-110", /* IANA */ + "LATIN4", /* IANA */ + "L4", /* IANA */ + "csISOLatin4", /* IANA */ + "ISO8859-4", /* X11R6.4, glibc, FreeBSD, OSF/1, Solaris */ + /*"ISO8859_4", JDK 1.1 */ + /*"CP28594", Windows */ + ), + iso8859_4, + { iso8859_4_mbtowc, NULL }, { iso8859_4_wctomb, NULL }) + +DEFENCODING(( "ISO-8859-5", /* IANA */ + "ISO_8859-5", /* IANA */ + "ISO_8859-5:1988", /* IANA */ + "ISO-IR-144", /* IANA */ + "CYRILLIC", /* IANA */ + "csISOLatinCyrillic", /* IANA */ + "ISO8859-5", /* X11R6.4, glibc, FreeBSD, AIX, IRIX, OSF/1, Solaris */ + /*"ISO8859_5", JDK 1.1 */ + /*"CP28595", Windows */ + ), + iso8859_5, + { iso8859_5_mbtowc, NULL }, { iso8859_5_wctomb, NULL }) +#ifdef USE_HPUX_ALIASES +DEFALIAS( "ISO88595", /* HP-UX */ + iso8859_5) +#endif + +DEFENCODING(( "ISO-8859-6", /* IANA */ + "ISO_8859-6", /* IANA */ + "ISO_8859-6:1987", /* IANA */ + "ISO-IR-127", /* IANA */ + "ECMA-114", /* IANA */ + "ASMO-708", /* IANA */ + "ARABIC", /* IANA */ + "csISOLatinArabic", /* IANA */ + "ISO8859-6", /* X11R6.4, glibc, FreeBSD, AIX, Solaris */ + /*"ISO8859_6", JDK 1.1 */ + /*"CP28596", Windows */ + ), + iso8859_6, + { iso8859_6_mbtowc, NULL }, { iso8859_6_wctomb, NULL }) +#ifdef USE_HPUX_ALIASES +DEFALIAS( "ISO88596", /* HP-UX */ + iso8859_6) +#endif + +DEFENCODING(( "ISO-8859-7", /* IANA, RFC 1947 */ + "ISO_8859-7", /* IANA */ + "ISO_8859-7:1987", /* IANA */ + "ISO_8859-7:2003", + "ISO-IR-126", /* IANA */ + "ECMA-118", /* IANA */ + "ELOT_928", /* IANA */ + "GREEK8", /* IANA */ + "GREEK", /* IANA */ + "csISOLatinGreek", /* IANA */ + "ISO8859-7", /* X11R6.4, glibc, FreeBSD, AIX, IRIX, OSF/1, Solaris */ + /*"ISO8859_7", JDK 1.1 */ + /*"CP28597", Windows */ + ), + iso8859_7, + { iso8859_7_mbtowc, NULL }, { iso8859_7_wctomb, NULL }) +#ifdef USE_HPUX_ALIASES +DEFALIAS( "ISO88597", /* HP-UX */ + iso8859_7) +#endif + +DEFENCODING(( "ISO-8859-8", /* IANA */ + "ISO_8859-8", /* IANA */ + "ISO_8859-8:1988", /* IANA */ + "ISO-IR-138", /* IANA */ + "HEBREW", /* IANA */ + "csISOLatinHebrew", /* IANA */ + "ISO8859-8", /* X11R6.4, glibc, FreeBSD, AIX, OSF/1, Solaris */ + /*"ISO8859_8", JDK 1.1 */ + /*"CP28598", Windows */ + /*"CP38598", Windows */ + ), + iso8859_8, + { iso8859_8_mbtowc, NULL }, { iso8859_8_wctomb, NULL }) +#ifdef USE_HPUX_ALIASES +DEFALIAS( "ISO88598", /* HP-UX */ + iso8859_8) +#endif + +DEFENCODING(( "ISO-8859-9", /* IANA */ + "ISO_8859-9", /* IANA */ + "ISO_8859-9:1989", /* IANA */ + "ISO-IR-148", /* IANA */ + "LATIN5", /* IANA */ + "L5", /* IANA */ + "csISOLatin5", /* IANA */ + "ISO8859-9", /* X11R6.4, glibc, FreeBSD, AIX, IRIX, OSF/1, Solaris */ + /*"ISO8859_9", JDK 1.1 */ + /*"CP28599", Windows */ + ), + iso8859_9, + { iso8859_9_mbtowc, NULL }, { iso8859_9_wctomb, NULL }) +#ifdef USE_HPUX_ALIASES +DEFALIAS( "ISO88599", /* HP-UX */ + iso8859_9) +#endif + +DEFENCODING(( "ISO-8859-10", /* IANA */ + "ISO_8859-10", + "ISO_8859-10:1992", /* IANA */ + "ISO-IR-157", /* IANA */ + "LATIN6", /* IANA */ + "L6", /* IANA */ + "csISOLatin6", /* IANA */ + "ISO8859-10", /* X11R6.4, glibc, FreeBSD */ + ), + iso8859_10, + { iso8859_10_mbtowc, NULL }, { iso8859_10_wctomb, NULL }) + +DEFENCODING(( "ISO-8859-11", /* glibc */ + "ISO_8859-11", + "ISO8859-11", /* X11R6.7, glibc */ + ), + iso8859_11, + { iso8859_11_mbtowc, NULL }, { iso8859_11_wctomb, NULL }) + +DEFENCODING(( "ISO-8859-13", /* IANA, glibc */ + "ISO_8859-13", + "ISO-IR-179", /* glibc */ + "LATIN7", /* glibc */ + "L7", /* glibc */ + "ISO8859-13", /* glibc, FreeBSD */ + ), + iso8859_13, + { iso8859_13_mbtowc, NULL }, { iso8859_13_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-921", /* AIX */ + iso8859_13) +#endif + +DEFENCODING(( "ISO-8859-14", /* IANA, glibc */ + "ISO_8859-14", /* IANA */ + "ISO_8859-14:1998", /* IANA, glibc */ + "ISO-IR-199", /* IANA */ + "LATIN8", /* IANA, glibc */ + "L8", /* IANA, glibc */ + "ISO-CELTIC", /* IANA */ + "ISO8859-14", /* glibc, FreeBSD */ + ), + iso8859_14, + { iso8859_14_mbtowc, NULL }, { iso8859_14_wctomb, NULL }) + +DEFENCODING(( "ISO-8859-15", /* IANA, glibc */ + "ISO_8859-15", /* IANA */ + "ISO_8859-15:1998", /* glibc */ + "ISO-IR-203", + "LATIN-9", /* IANA */ + "ISO8859-15", /* glibc, FreeBSD, AIX, OSF/1, Solaris */ + /*"CP28605", Windows */ + ), + iso8859_15, + { iso8859_15_mbtowc, NULL }, { iso8859_15_wctomb, NULL }) +#ifdef USE_HPUX_ALIASES +DEFALIAS( "ISO885915", /* HP-UX */ + iso8859_15) +#endif + +DEFENCODING(( "ISO-8859-16", /* IANA */ + "ISO_8859-16", /* IANA */ + "ISO_8859-16:2001", /* IANA */ + "ISO-IR-226", /* IANA */ + "LATIN10", /* IANA */ + "L10", /* IANA */ + "ISO8859-16", /* glibc, FreeBSD */ + ), + iso8859_16, + { iso8859_16_mbtowc, NULL }, { iso8859_16_wctomb, NULL }) + +DEFENCODING(( "KOI8-R", /* IANA, RFC 1489, X11R6.4, JDK 1.1 */ + "csKOI8R", /* IANA */ + /*"CP20866", Windows */ + ), + koi8_r, + { koi8_r_mbtowc, NULL }, { koi8_r_wctomb, NULL }) + +DEFENCODING(( "KOI8-U", /* IANA, RFC 2319 */ + ), + koi8_u, + { koi8_u_mbtowc, NULL }, { koi8_u_wctomb, NULL }) + +DEFENCODING(( "KOI8-RU", + ), + koi8_ru, + { koi8_ru_mbtowc, NULL }, { koi8_ru_wctomb, NULL }) + +/* Windows 8-bit encodings */ + +DEFENCODING(( "CP1250", /* JDK 1.1 */ + "WINDOWS-1250", /* IANA */ + "MS-EE", + ), + cp1250, + { cp1250_mbtowc, NULL }, { cp1250_wctomb, NULL }) + +DEFENCODING(( "CP1251", /* JDK 1.1 */ + "WINDOWS-1251", /* IANA */ + "MS-CYRL", + ), + cp1251, + { cp1251_mbtowc, NULL }, { cp1251_wctomb, NULL }) +#ifdef USE_SOLARIS_ALIASES +DEFALIAS( "ANSI-1251", /* Solaris */ + cp1251) +#endif + +DEFENCODING(( "CP1252", /* JDK 1.1 */ + "WINDOWS-1252", /* IANA */ + "MS-ANSI", + ), + cp1252, + { cp1252_mbtowc, NULL }, { cp1252_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-1252", /* AIX */ + cp1252) +#endif + +DEFENCODING(( "CP1253", /* JDK 1.1 */ + "WINDOWS-1253", /* IANA */ + "MS-GREEK", + ), + cp1253, + { cp1253_mbtowc, NULL }, { cp1253_wctomb, NULL }) + +DEFENCODING(( "CP1254", /* JDK 1.1 */ + "WINDOWS-1254", /* IANA */ + "MS-TURK", + ), + cp1254, + { cp1254_mbtowc, NULL }, { cp1254_wctomb, NULL }) + +DEFENCODING(( "CP1255", /* JDK 1.1 */ + "WINDOWS-1255", /* IANA */ + "MS-HEBR", + ), + cp1255, + { cp1255_mbtowc, cp1255_flushwc }, { cp1255_wctomb, NULL }) + +DEFENCODING(( "CP1256", /* JDK 1.1 */ + "WINDOWS-1256", /* IANA */ + "MS-ARAB", + ), + cp1256, + { cp1256_mbtowc, NULL }, { cp1256_wctomb, NULL }) + +DEFENCODING(( "CP1257", /* JDK 1.1 */ + "WINDOWS-1257", /* IANA */ + "WINBALTRIM", + ), + cp1257, + { cp1257_mbtowc, NULL }, { cp1257_wctomb, NULL }) + +DEFENCODING(( "CP1258", /* JDK 1.1 */ + "WINDOWS-1258", /* IANA */ + ), + cp1258, + { cp1258_mbtowc, cp1258_flushwc }, { cp1258_wctomb, NULL }) + +/* DOS 8-bit encodings */ + +DEFENCODING(( "CP850", /* IANA, JDK 1.1 */ + "IBM850", /* IANA */ + "850", /* IANA */ + "csPC850Multilingual", /* IANA */ + ), + cp850, + { cp850_mbtowc, NULL }, { cp850_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-850", /* AIX */ + cp850) +#endif + +DEFENCODING(( "CP862", /* IANA, JDK 1.1 */ + "IBM862", /* IANA */ + "862", /* IANA */ + "csPC862LatinHebrew", /* IANA */ + ), + cp862, + { cp862_mbtowc, NULL }, { cp862_wctomb, NULL }) + +DEFENCODING(( "CP866", /* IANA, JDK 1.1 */ + "IBM866", /* IANA */ + "866", /* IANA */ + "csIBM866", /* IANA */ + ), + cp866, + { cp866_mbtowc, NULL }, { cp866_wctomb, NULL }) + +DEFENCODING(( "CP1131", /* FreeBSD, MacOS X */ + ), + cp1131, + { cp1131_mbtowc, NULL }, { cp1131_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-1131", /* AIX */ + cp1131) +#endif + +/* Macintosh 8-bit encodings */ + +DEFENCODING(( "MacRoman", /* JDK 1.1 */ + /* This is the best table for MACINTOSH. The ones */ + /* in glibc and FreeBSD-iconv are bad quality. */ + "MACINTOSH", /* IANA */ + "MAC", /* IANA */ + "csMacintosh", /* IANA */ + /*"CP10000", Windows */ + ), + mac_roman, + { mac_roman_mbtowc, NULL }, { mac_roman_wctomb, NULL }) + +DEFENCODING(( "MacCentralEurope", /* JDK 1.1 */ + /*"CP10029", Windows */ + ), + mac_centraleurope, + { mac_centraleurope_mbtowc, NULL }, { mac_centraleurope_wctomb, NULL }) + +DEFENCODING(( "MacIceland", /* JDK 1.1 */ + /*"CP10079", Windows */ + ), + mac_iceland, + { mac_iceland_mbtowc, NULL }, { mac_iceland_wctomb, NULL }) + +DEFENCODING(( "MacCroatian", /* JDK 1.1 */ + /*"CP10082", Windows */ + ), + mac_croatian, + { mac_croatian_mbtowc, NULL }, { mac_croatian_wctomb, NULL }) + +DEFENCODING(( "MacRomania", /* JDK 1.1 */ + /*"CP10010", Windows */ + ), + mac_romania, + { mac_romania_mbtowc, NULL }, { mac_romania_wctomb, NULL }) + +DEFENCODING(( "MacCyrillic", /* JDK 1.1 */ + /*"CP10007", Windows */ + ), + mac_cyrillic, + { mac_cyrillic_mbtowc, NULL }, { mac_cyrillic_wctomb, NULL }) + +DEFENCODING(( "MacUkraine", /* JDK 1.1 */ + /*"CP10017", Windows */ + ), + mac_ukraine, + { mac_ukraine_mbtowc, NULL }, { mac_ukraine_wctomb, NULL }) + +DEFENCODING(( "MacGreek", /* JDK 1.1 */ + /*"CP10006", Windows */ + ), + mac_greek, + { mac_greek_mbtowc, NULL }, { mac_greek_wctomb, NULL }) + +DEFENCODING(( "MacTurkish", /* JDK 1.1 */ + /*"CP10081", Windows */ + ), + mac_turkish, + { mac_turkish_mbtowc, NULL }, { mac_turkish_wctomb, NULL }) + +DEFENCODING(( "MacHebrew", /* JDK 1.1 */ + /*"CP10005", Windows */ + ), + mac_hebrew, + { mac_hebrew_mbtowc, NULL }, { mac_hebrew_wctomb, NULL }) + +DEFENCODING(( "MacArabic", /* JDK 1.1 */ + /*"CP10004", Windows */ + ), + mac_arabic, + { mac_arabic_mbtowc, NULL }, { mac_arabic_wctomb, NULL }) + +DEFENCODING(( "MacThai", /* JDK 1.1 */ + /*"CP10021", Windows */ + ), + mac_thai, + { mac_thai_mbtowc, NULL }, { mac_thai_wctomb, NULL }) + +/* Other platform specific 8-bit encodings */ + +DEFENCODING(( "HP-ROMAN8", /* IANA, X11R6.4 */ + "ROMAN8", /* IANA */ + "R8", /* IANA */ + "csHPRoman8", /* IANA */ + ), + hp_roman8, + { hp_roman8_mbtowc, NULL }, { hp_roman8_wctomb, NULL }) + +DEFENCODING(( "NEXTSTEP", + ), + nextstep, + { nextstep_mbtowc, NULL }, { nextstep_wctomb, NULL }) + +/* Regional 8-bit encodings used for a single language */ + +DEFENCODING(( "ARMSCII-8", + ), + armscii_8, + { armscii_8_mbtowc, NULL }, { armscii_8_wctomb, NULL }) + +DEFENCODING(( "GEORGIAN-ACADEMY", + ), + georgian_academy, + { georgian_academy_mbtowc, NULL }, { georgian_academy_wctomb, NULL }) + +DEFENCODING(( "GEORGIAN-PS", + ), + georgian_ps, + { georgian_ps_mbtowc, NULL }, { georgian_ps_wctomb, NULL }) + +DEFENCODING(( "KOI8-T", + ), + koi8_t, + { koi8_t_mbtowc, NULL }, { koi8_t_wctomb, NULL }) + +DEFENCODING(( "PT154", /* IANA, glibc */ + "PTCP154", /* IANA */ + "CP154", /* IANA */ + "CYRILLIC-ASIAN", /* IANA */ + "csPTCP154", /* IANA */ + ), + pt154, + { pt154_mbtowc, NULL }, { pt154_wctomb, NULL }) + +DEFENCODING(( "RK1048", /* IANA, glibc */ + "STRK1048-2002", /* IANA */ + "KZ-1048", /* IANA */ + "csKZ1048", /* IANA */ + ), + rk1048, + { rk1048_mbtowc, NULL }, { rk1048_wctomb, NULL }) + +DEFENCODING(( "MULELAO-1", + ), + mulelao, + { mulelao_mbtowc, NULL }, { mulelao_wctomb, NULL }) + +DEFENCODING(( "CP1133", + "IBM-CP1133", + ), + cp1133, + { cp1133_mbtowc, NULL }, { cp1133_wctomb, NULL }) + +DEFENCODING(( "TIS-620", /* IANA */ + "TIS620", /* glibc, HP-UX */ + "TIS620-0", /* glibc */ + "TIS620.2529-1", /* glibc */ + "TIS620.2533-0", /* glibc */ + "TIS620.2533-1", + "ISO-IR-166", /* glibc */ + ), + tis620, + { tis620_mbtowc, NULL }, { tis620_wctomb, NULL }) +#ifdef USE_OSF1_ALIASES +DEFALIAS( "TACTIS", /* OSF/1 */ + tis620) +#endif +#ifdef USE_SOLARIS_ALIASES +DEFALIAS( "TIS620.2533", /* Solaris */ + tis620) +#endif + +DEFENCODING(( "CP874", /* JDK 1.1 */ + "WINDOWS-874", + ), + cp874, + { cp874_mbtowc, NULL }, { cp874_wctomb, NULL }) + +DEFENCODING(( "VISCII", /* IANA, RFC 1456 */ + "VISCII1.1-1", + "csVISCII", /* IANA */ + ), + viscii, + { viscii_mbtowc, NULL }, { viscii_wctomb, NULL }) + +DEFENCODING(( "TCVN", + "TCVN-5712", + "TCVN5712-1", + "TCVN5712-1:1993", + ), + tcvn, + { tcvn_mbtowc, tcvn_flushwc }, { tcvn_wctomb, NULL }) + +/* CJK character sets (not documented) */ + +DEFENCODING(( "JIS_C6220-1969-RO", /* IANA */ + "ISO646-JP", /* IANA */ + "ISO-IR-14", /* IANA */ + "JP", /* IANA */ + "csISO14JISC6220ro", /* IANA */ + ), + iso646_jp, + { iso646_jp_mbtowc, NULL }, { iso646_jp_wctomb, NULL }) + +DEFENCODING(( "JIS_X0201", /* IANA */ + "JISX0201-1976", + "X0201", /* IANA */ + "csHalfWidthKatakana", /* IANA */ + /*"JISX0201.1976-0", X11R6.4 */ + /*"JIS0201", JDK 1.1 */ + ), + jisx0201, + { jisx0201_mbtowc, NULL }, { jisx0201_wctomb, NULL }) + +DEFENCODING(( "JIS_X0208", + "JIS_X0208-1983", /* IANA */ + "JIS_X0208-1990", + "JIS0208", + "X0208", /* IANA */ + "ISO-IR-87", /* IANA */ + "JIS_C6226-1983", /* IANA */ + "csISO87JISX0208", /* IANA */ + /*"JISX0208.1983-0", X11R6.4 */ + /*"JISX0208.1990-0", X11R6.4 */ + /*"JIS0208", JDK 1.1 */ + ), + jisx0208, + { jisx0208_mbtowc, NULL }, { jisx0208_wctomb, NULL }) + +DEFENCODING(( "JIS_X0212", + "JIS_X0212.1990-0", + "JIS_X0212-1990", /* IANA */ + "X0212", /* IANA */ + "ISO-IR-159", /* IANA */ + "csISO159JISX02121990", /* IANA */ + /*"JISX0212.1990-0", X11R6.4 */ + /*"JIS0212", JDK 1.1 */ + ), + jisx0212, + { jisx0212_mbtowc, NULL }, { jisx0212_wctomb, NULL }) + +DEFENCODING(( "GB_1988-80", /* IANA */ + "ISO646-CN", /* IANA */ + "ISO-IR-57", /* IANA */ + "CN", /* IANA */ + "csISO57GB1988", /* IANA */ + ), + iso646_cn, + { iso646_cn_mbtowc, NULL }, { iso646_cn_wctomb, NULL }) + +DEFENCODING(( "GB_2312-80", /* IANA */ + "ISO-IR-58", /* IANA */ + "csISO58GB231280", /* IANA */ + "CHINESE", /* IANA */ + /*"GB2312.1980-0", X11R6.4 */ + ), + gb2312, + { gb2312_mbtowc, NULL }, { gb2312_wctomb, NULL }) + +DEFENCODING(( "ISO-IR-165", + "CN-GB-ISOIR165", /* RFC 1922 */ + ), + isoir165, + { isoir165_mbtowc, NULL }, { isoir165_wctomb, NULL }) + +DEFENCODING(( "KSC_5601", /* IANA */ + "KS_C_5601-1987", /* IANA */ + "KS_C_5601-1989", /* IANA */ + "ISO-IR-149", /* IANA */ + "csKSC56011987", /* IANA */ + "KOREAN", /* IANA */ + /*"KSC5601.1987-0", X11R6.4 */ + /*"KSX1001:1992", Ken Lunde */ + ), + ksc5601, + { ksc5601_mbtowc, NULL }, { ksc5601_wctomb, NULL }) + +/* CJK encodings */ + +DEFENCODING(( "EUC-JP", /* IANA */ + "EUCJP", /* glibc, HP-UX, IRIX, OSF/1, Solaris */ + "Extended_UNIX_Code_Packed_Format_for_Japanese", /* IANA */ + "csEUCPkdFmtJapanese", /* IANA */ + /*"EUC_JP", JDK 1.1 */ + /*"CP51932", Windows */ + ), + euc_jp, + { euc_jp_mbtowc, NULL }, { euc_jp_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-EUCJP", /* AIX */ + euc_jp) +#endif +#ifdef USE_OSF1_ALIASES +DEFALIAS( "SDECKANJI", /* OSF/1 */ + euc_jp) +#endif + +DEFENCODING(( "SHIFT_JIS", /* IANA */ + "SHIFT-JIS", /* glibc */ + "SJIS", /* JDK 1.1, HP-UX, OSF/1 */ + "MS_KANJI", /* IANA */ + "csShiftJIS", /* IANA */ + ), + sjis, + { sjis_mbtowc, NULL }, { sjis_wctomb, NULL }) +#ifdef USE_SOLARIS_ALIASES +DEFALIAS( "PCK", /* Solaris */ + sjis) +#endif + +DEFENCODING(( "CP932", /* glibc */ + ), + cp932, + { cp932_mbtowc, NULL }, { cp932_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-932", /* AIX */ + cp932) +#endif + +DEFENCODING(( "ISO-2022-JP", /* IANA, RFC 1468 */ + "csISO2022JP", /* IANA */ + /*"ISO2022JP", JDK 1.1 */ + ), + iso2022_jp, + { iso2022_jp_mbtowc, NULL }, { iso2022_jp_wctomb, iso2022_jp_reset }) + +DEFENCODING(( "ISO-2022-JP-1", /* RFC 2237 */ + ), + iso2022_jp1, + { iso2022_jp1_mbtowc, NULL }, { iso2022_jp1_wctomb, iso2022_jp1_reset }) + +DEFENCODING(( "ISO-2022-JP-2", /* IANA, RFC 1554 */ + "csISO2022JP2", /* IANA */ + ), + iso2022_jp2, + { iso2022_jp2_mbtowc, NULL }, { iso2022_jp2_wctomb, iso2022_jp2_reset }) + +DEFENCODING(( "EUC-CN", /* glibc */ + "EUCCN", /* glibc, IRIX */ + "GB2312", /* IANA */ + "CN-GB", /* RFC 1922 */ + "csGB2312", /* IANA */ + /*"EUC_CN", JDK 1.1 */ + /*"CP51936", Windows */ + ), + euc_cn, + { euc_cn_mbtowc, NULL }, { euc_cn_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-EUCCN", /* AIX */ + euc_cn) +#endif +#ifdef USE_HPUX_ALIASES +DEFALIAS( "HP15CN", /* HP-UX */ + euc_cn) +#endif +#ifdef USE_OSF1_ALIASES +DEFALIAS( "DECHANZI", /* OSF/1 */ + euc_cn) +#endif + +DEFENCODING(( "GBK", /* IANA, JDK 1.1 */ + ), + ces_gbk, + { ces_gbk_mbtowc, NULL }, { ces_gbk_wctomb, NULL }) + +DEFENCODING(( "CP936", /* IANA */ + "MS936", /* IANA */ + "WINDOWS-936", /* IANA */ + ), + cp936, + { cp936_mbtowc, NULL }, { cp936_wctomb, NULL }) + +DEFENCODING(( "GB18030", /* IANA, glibc */ + /*"CP54936", Windows */ + ), + gb18030, + { gb18030_mbtowc, NULL }, { gb18030_wctomb, NULL }) + +DEFENCODING(( "ISO-2022-CN", /* IANA, RFC 1922 */ + "csISO2022CN", + /*"ISO2022CN", JDK 1.1 */ + ), + iso2022_cn, + { iso2022_cn_mbtowc, NULL }, { iso2022_cn_wctomb, iso2022_cn_reset }) + +DEFENCODING(( "ISO-2022-CN-EXT", /* IANA, RFC 1922 */ + ), + iso2022_cn_ext, + { iso2022_cn_ext_mbtowc, NULL }, { iso2022_cn_ext_wctomb, iso2022_cn_ext_reset }) + +DEFENCODING(( "HZ", /* RFC 1843 */ + "HZ-GB-2312", /* IANA, RFC 1842 */ + ), + hz, + { hz_mbtowc, NULL }, { hz_wctomb, hz_reset }) + +DEFENCODING(( "EUC-TW", /* glibc */ + "EUCTW", /* glibc, HP-UX, IRIX, OSF/1 */ + "csEUCTW", + /*"EUC_TW", JDK 1.1 */ + /*"CP51950", Windows */ + ), + euc_tw, + { euc_tw_mbtowc, NULL }, { euc_tw_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-EUCTW", /* AIX */ + euc_tw) +#endif +#ifdef USE_SOLARIS_ALIASES +DEFALIAS( "CNS11643", /* Solaris */ + euc_tw) +#endif + +DEFENCODING(( "BIG5", /* IANA, JDK 1.1 */ + "BIG-5", /* glibc */ + "BIG-FIVE", /* glibc */ + "BIGFIVE", /* glibc */ + "CN-BIG5", /* RFC 1922 */ + "csBig5", /* IANA */ + ), + ces_big5, + { ces_big5_mbtowc, NULL }, { ces_big5_wctomb, NULL }) + +DEFENCODING(( "CP950", /* JDK 1.1 */ + ), + cp950, + { cp950_mbtowc, NULL }, { cp950_wctomb, NULL }) + +DEFENCODING(( "BIG5-HKSCS:1999", + ), + big5hkscs1999, + { big5hkscs1999_mbtowc, big5hkscs1999_flushwc }, { big5hkscs1999_wctomb, big5hkscs1999_reset }) + +DEFENCODING(( "BIG5-HKSCS:2001", + ), + big5hkscs2001, + { big5hkscs2001_mbtowc, big5hkscs2001_flushwc }, { big5hkscs2001_wctomb, big5hkscs2001_reset }) + +DEFENCODING(( "BIG5-HKSCS:2004", + ), + big5hkscs2004, + { big5hkscs2004_mbtowc, big5hkscs2004_flushwc }, { big5hkscs2004_wctomb, big5hkscs2004_reset }) + +DEFENCODING(( "BIG5-HKSCS", /* IANA */ + "BIG5HKSCS", /* glibc */ + "BIG5-HKSCS:2008", + ), + big5hkscs2008, + { big5hkscs2008_mbtowc, big5hkscs2008_flushwc }, { big5hkscs2008_wctomb, big5hkscs2008_reset }) + +DEFENCODING(( "EUC-KR", /* IANA, RFC 1557 */ + "EUCKR", /* glibc, HP-UX, IRIX, OSF/1 */ + "csEUCKR", /* IANA */ + /*"EUC_KR", JDK 1.1 */ + /*"CP51949", Windows */ + ), + euc_kr, + { euc_kr_mbtowc, NULL }, { euc_kr_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-EUCKR", /* AIX */ + euc_kr) +#endif +#ifdef USE_OSF1_ALIASES +DEFALIAS( "DECKOREAN", /* OSF/1 */ + euc_kr) +#endif +#ifdef USE_SOLARIS_ALIASES +DEFALIAS( "5601", /* Solaris */ + euc_kr) +#endif + +DEFENCODING(( "CP949", /* JDK 1.1 */ + "UHC", /* glibc */ + ), + cp949, + { cp949_mbtowc, NULL }, { cp949_wctomb, NULL }) +#ifdef USE_OSF1_ALIASES +DEFALIAS( "KSC5601", /* OSF/1 */ + cp949) +#endif + +DEFENCODING(( "JOHAB", /* glibc */ + "CP1361", /* glibc */ + ), + johab, + { johab_mbtowc, NULL }, { johab_wctomb, NULL }) +#ifdef USE_SOLARIS_ALIASES +DEFALIAS( "KO_KR.JOHAP92", /* Solaris */ + johab) +#endif + +DEFENCODING(( "ISO-2022-KR", /* IANA, RFC 1557 */ + "csISO2022KR", /* IANA */ + /*"ISO2022KR", JDK 1.1 */ + ), + iso2022_kr, + { iso2022_kr_mbtowc, NULL }, { iso2022_kr_wctomb, iso2022_kr_reset }) + diff --git a/libs/libiconv/lib/encodings_aix.def b/libs/libiconv/lib/encodings_aix.def new file mode 100644 index 00000000..259452eb --- /dev/null +++ b/libs/libiconv/lib/encodings_aix.def @@ -0,0 +1,97 @@ +/* Copyright (C) 2000-2002, 2008 Free Software Foundation, Inc. + This file is part of the GNU LIBICONV Library. + + The GNU LIBICONV Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + The GNU LIBICONV Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU LIBICONV Library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Encodings used by system dependent locales on AIX. */ + +DEFENCODING(( "CP856", + ), + cp856, + { cp856_mbtowc, NULL }, { cp856_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-856", /* AIX */ + cp856) +#endif + +DEFENCODING(( "CP922", + ), + cp922, + { cp922_mbtowc, NULL }, { cp922_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-922", /* AIX */ + cp922) +#endif + +DEFENCODING(( "CP943", + ), + cp943, + { cp943_mbtowc, NULL }, { cp943_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-943", /* AIX */ + cp943) +#endif + +DEFENCODING(( "CP1046", + ), + cp1046, + { cp1046_mbtowc, NULL }, { cp1046_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-1046", /* AIX */ + cp1046) +#endif + +DEFENCODING(( "CP1124", + ), + cp1124, + { cp1124_mbtowc, NULL }, { cp1124_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-1124", /* AIX */ + cp1124) +#endif + +DEFENCODING(( "CP1129", + ), + cp1129, + { cp1129_mbtowc, NULL }, { cp1129_wctomb, NULL }) +#ifdef USE_AIX_ALIASES +DEFALIAS( "IBM-1129", /* AIX */ + cp1129) +#endif + +DEFENCODING(( "CP1161", + "IBM1161", /* glibc */ + "IBM-1161", /* glibc */ + "csIBM1161", /* glibc */ + ), + cp1161, + { cp1161_mbtowc, NULL }, { cp1161_wctomb, NULL }) + +DEFENCODING(( "CP1162", + "IBM1162", /* glibc */ + "IBM-1162", /* glibc */ + "csIBM1162", /* glibc */ + ), + cp1162, + { cp1162_mbtowc, NULL }, { cp1162_wctomb, NULL }) + +DEFENCODING(( "CP1163", + "IBM1163", /* glibc */ + "IBM-1163", /* glibc */ + "csIBM1163", /* glibc */ + ), + cp1163, + { cp1163_mbtowc, NULL }, { cp1163_wctomb, NULL }) diff --git a/libs/libiconv/lib/encodings_dos.def b/libs/libiconv/lib/encodings_dos.def new file mode 100644 index 00000000..c9d30c8c --- /dev/null +++ b/libs/libiconv/lib/encodings_dos.def @@ -0,0 +1,127 @@ +/* Copyright (C) 2001-2002 Free Software Foundation, Inc. + This file is part of the GNU LIBICONV Library. + + The GNU LIBICONV Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + The GNU LIBICONV Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU LIBICONV Library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Encodings used by system dependent locales on MSDOS. */ + +DEFENCODING(( "CP437", /* IANA, JDK 1.1 */ + "IBM437", /* IANA */ + "437", /* IANA */ + "csPC8CodePage437", /* IANA */ + ), + cp437, + { cp437_mbtowc, NULL }, { cp437_wctomb, NULL }) + +DEFENCODING(( "CP737", /* JDK 1.1 */ + ), + cp737, + { cp737_mbtowc, NULL }, { cp737_wctomb, NULL }) + +DEFENCODING(( "CP775", /* IANA, JDK 1.1 */ + "IBM775", /* IANA */ + "csPC775Baltic", /* IANA */ + ), + cp775, + { cp775_mbtowc, NULL }, { cp775_wctomb, NULL }) + +DEFENCODING(( "CP852", /* IANA, JDK 1.1 */ + "IBM852", /* IANA */ + "852", /* IANA */ + "csPCp852", /* IANA */ + ), + cp852, + { cp852_mbtowc, NULL }, { cp852_wctomb, NULL }) + +DEFENCODING(( "CP853", + ), + cp853, + { cp853_mbtowc, NULL }, { cp853_wctomb, NULL }) + +DEFENCODING(( "CP855", /* IANA, JDK 1.1 */ + "IBM855", /* IANA */ + "855", /* IANA */ + "csIBM855", /* IANA */ + ), + cp855, + { cp855_mbtowc, NULL }, { cp855_wctomb, NULL }) + +DEFENCODING(( "CP857", /* IANA, JDK 1.1 */ + "IBM857", /* IANA */ + "857", /* IANA */ + "csIBM857", /* IANA */ + ), + cp857, + { cp857_mbtowc, NULL }, { cp857_wctomb, NULL }) + +DEFENCODING(( "CP858", /* JDK 1.1.7 */ + ), + cp858, + { cp858_mbtowc, NULL }, { cp858_wctomb, NULL }) + +DEFENCODING(( "CP860", /* IANA, JDK 1.1 */ + "IBM860", /* IANA */ + "860", /* IANA */ + "csIBM860", /* IANA */ + ), + cp860, + { cp860_mbtowc, NULL }, { cp860_wctomb, NULL }) + +DEFENCODING(( "CP861", /* IANA, JDK 1.1 */ + "IBM861", /* IANA */ + "861", /* IANA */ + "CP-IS", /* IANA */ + "csIBM861", /* IANA */ + ), + cp861, + { cp861_mbtowc, NULL }, { cp861_wctomb, NULL }) + +DEFENCODING(( "CP863", /* IANA, JDK 1.1 */ + "IBM863", /* IANA */ + "863", /* IANA */ + "csIBM863", /* IANA */ + ), + cp863, + { cp863_mbtowc, NULL }, { cp863_wctomb, NULL }) + +DEFENCODING(( "CP864", /* IANA, JDK 1.1 */ + "IBM864", /* IANA */ + "csIBM864", /* IANA */ + ), + cp864, + { cp864_mbtowc, NULL }, { cp864_wctomb, NULL }) + +DEFENCODING(( "CP865", /* IANA, JDK 1.1 */ + "IBM865", /* IANA */ + "865", /* IANA */ + "csIBM865", /* IANA */ + ), + cp865, + { cp865_mbtowc, NULL }, { cp865_wctomb, NULL }) + +DEFENCODING(( "CP869", /* IANA, JDK 1.1 */ + "IBM869", /* IANA */ + "869", /* IANA */ + "CP-GR", /* IANA */ + "csIBM869", /* IANA */ + ), + cp869, + { cp869_mbtowc, NULL }, { cp869_wctomb, NULL }) + +DEFENCODING(( "CP1125", /* ICU */ + ), + cp1125, + { cp1125_mbtowc, NULL }, { cp1125_wctomb, NULL }) diff --git a/libs/libiconv/lib/encodings_extra.def b/libs/libiconv/lib/encodings_extra.def new file mode 100644 index 00000000..614422b6 --- /dev/null +++ b/libs/libiconv/lib/encodings_extra.def @@ -0,0 +1,57 @@ +/* Copyright (C) 2002, 2005, 2008 Free Software Foundation, Inc. + This file is part of the GNU LIBICONV Library. + + The GNU LIBICONV Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + The GNU LIBICONV Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU LIBICONV Library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + Fifth Floor, Boston, MA 02110-1301, USA. */ + +DEFENCODING(( "EUC-JISX0213", + "EUC-JIS-2004", /* x0213.org */ + ), + euc_jisx0213, + { euc_jisx0213_mbtowc, euc_jisx0213_flushwc }, { euc_jisx0213_wctomb, euc_jisx0213_reset }) + +DEFENCODING(( "SHIFT_JISX0213", + "SHIFT_JIS-2004", /* x0213.org */ + ), + shift_jisx0213, + { shift_jisx0213_mbtowc, shift_jisx0213_flushwc }, { shift_jisx0213_wctomb, shift_jisx0213_reset }) + +DEFENCODING(( "ISO-2022-JP-3", + "ISO-2022-JP-2004", /* x0213.org */ + ), + iso2022_jp3, + { iso2022_jp3_mbtowc, iso2022_jp3_flushwc }, { iso2022_jp3_wctomb, iso2022_jp3_reset }) + +DEFENCODING(( "BIG5-2003", + ), + big5_2003, + { big5_2003_mbtowc, NULL }, { big5_2003_wctomb, NULL }) + +DEFENCODING(( "TDS565", + "ISO-IR-230", + ), + tds565, + { tds565_mbtowc, NULL }, { tds565_wctomb, NULL }) + +DEFENCODING(( "ATARIST", + "ATARI", + ), + atarist, + { atarist_mbtowc, NULL }, { atarist_wctomb, NULL }) + +DEFENCODING(( "RISCOS-LATIN1", + ), + riscos1, + { riscos1_mbtowc, NULL }, { riscos1_wctomb, NULL }) diff --git a/libs/libiconv/lib/encodings_local.def b/libs/libiconv/lib/encodings_local.def new file mode 100644 index 00000000..4e793e5b --- /dev/null +++ b/libs/libiconv/lib/encodings_local.def @@ -0,0 +1,29 @@ +/* Copyright (C) 2000-2001 Free Software Foundation, Inc. + This file is part of the GNU LIBICONV Library. + + The GNU LIBICONV Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + The GNU LIBICONV Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU LIBICONV Library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Names for locale dependent encodings. */ + +DEFENCODING(( "CHAR", + ), + local_char, + { NULL, NULL }, { NULL, NULL }) + +DEFENCODING(( "WCHAR_T", /* glibc */ + ), + local_wchar_t, + { NULL, NULL }, { NULL, NULL }) diff --git a/libs/libiconv/lib/encodings_osf1.def b/libs/libiconv/lib/encodings_osf1.def new file mode 100644 index 00000000..7912854b --- /dev/null +++ b/libs/libiconv/lib/encodings_osf1.def @@ -0,0 +1,37 @@ +/* Copyright (C) 2001, 2008 Free Software Foundation, Inc. + This file is part of the GNU LIBICONV Library. + + The GNU LIBICONV Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + The GNU LIBICONV Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU LIBICONV Library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Encodings used by system dependent locales on OSF/1 a.k.a. Tru64. */ + +DEFENCODING(( "DEC-KANJI", + ), + dec_kanji, + { dec_kanji_mbtowc, NULL }, { dec_kanji_wctomb, NULL }) +#ifdef USE_OSF1_ALIASES +DEFALIAS( "DECKANJI", /* OSF/1 */ + dec_kanji) +#endif + +DEFENCODING(( "DEC-HANYU", + ), + dec_hanyu, + { dec_hanyu_mbtowc, NULL }, { dec_hanyu_wctomb, NULL }) +#ifdef USE_OSF1_ALIASES +DEFALIAS( "DECHANYU", /* OSF/1 */ + dec_hanyu) +#endif diff --git a/libs/libiconv/lib/euc_cn.h b/libs/libiconv/lib/euc_cn.h new file mode 100644 index 00000000..a25417a9 --- /dev/null +++ b/libs/libiconv/lib/euc_cn.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * EUC-CN + */ + +static int +euc_cn_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + /* Code set 0 (ASCII or GB 1988-89) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* Code set 1 (GB 2312-1980) */ + if (c >= 0xa1 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if (c2 >= 0xa1 && c2 < 0xff) { + unsigned char buf[2]; + buf[0] = c-0x80; buf[1] = c2-0x80; + return gb2312_mbtowc(conv,pwc,buf,2); + } else + return RET_ILSEQ; + } + } + return RET_ILSEQ; +} + +static int +euc_cn_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[2]; + int ret; + + /* Code set 0 (ASCII or GB 1988-89) */ + ret = ascii_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + /* Code set 1 (GB 2312-1980) */ + ret = gb2312_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]+0x80; + r[1] = buf[1]+0x80; + return 2; + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/euc_jisx0213.h b/libs/libiconv/lib/euc_jisx0213.h new file mode 100644 index 00000000..4d417ca1 --- /dev/null +++ b/libs/libiconv/lib/euc_jisx0213.h @@ -0,0 +1,268 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * EUC-JISX0213 + */ + +/* The structure of EUC-JISX0213 is as follows: + + 0x00..0x7F: ASCII + + 0x8E{A1..FE}: JISX0201 Katakana, with prefix 0x8E, offset by +0x80. + + 0x8F{A1..FE}{A1..FE}: JISX0213 plane 2, with prefix 0x8F, offset by +0x8080. + + 0x{A1..FE}{A1..FE}: JISX0213 plane 1, offset by +0x8080. + + Note that some JISX0213 characters are not contained in Unicode 3.2 + and are therefore best represented as sequences of Unicode characters. +*/ + +#include "jisx0213.h" +#include "flushwc.h" + +static int +euc_jisx0213_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + ucs4_t last_wc = conv->istate; + if (last_wc) { + /* Output the buffered character. */ + conv->istate = 0; + *pwc = last_wc; + return 0; /* Don't advance the input pointer. */ + } else { + unsigned char c = *s; + if (c < 0x80) { + /* Plain ASCII character. */ + *pwc = (ucs4_t) c; + return 1; + } else { + if ((c >= 0xa1 && c <= 0xfe) || c == 0x8e || c == 0x8f) { + /* Two or three byte character. */ + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0xa1 && c2 <= 0xfe) { + if (c == 0x8e) { + /* Half-width katakana. */ + if (c2 <= 0xdf) { + *pwc = c2 + 0xfec0; + return 2; + } + } else { + ucs4_t wc; + if (c == 0x8f) { + /* JISX 0213 plane 2. */ + if (n >= 3) { + unsigned char c3 = s[2]; + wc = jisx0213_to_ucs4(0x200-0x80+c2,c3^0x80); + } else + return RET_TOOFEW(0); + } else { + /* JISX 0213 plane 1. */ + wc = jisx0213_to_ucs4(0x100-0x80+c,c2^0x80); + } + if (wc) { + if (wc < 0x80) { + /* It's a combining character. */ + ucs4_t wc1 = jisx0213_to_ucs_combining[wc - 1][0]; + ucs4_t wc2 = jisx0213_to_ucs_combining[wc - 1][1]; + /* We cannot output two Unicode characters at once. So, + output the first character and buffer the second one. */ + *pwc = wc1; + conv->istate = wc2; + } else + *pwc = wc; + return (c == 0x8f ? 3 : 2); + } + } + } + } else + return RET_TOOFEW(0); + } + return RET_ILSEQ; + } + } +} + +#define euc_jisx0213_flushwc normal_flushwc + +/* Composition tables for each of the relevant combining characters. */ +static const struct { unsigned short base; unsigned short composed; } euc_jisx0213_comp_table_data[] = { +#define euc_jisx0213_comp_table02e5_idx 0 +#define euc_jisx0213_comp_table02e5_len 1 + { 0xabe4, 0xabe5 }, /* 0x12B65 = 0x12B64 U+02E5 */ +#define euc_jisx0213_comp_table02e9_idx (euc_jisx0213_comp_table02e5_idx+euc_jisx0213_comp_table02e5_len) +#define euc_jisx0213_comp_table02e9_len 1 + { 0xabe0, 0xabe6 }, /* 0x12B66 = 0x12B60 U+02E9 */ +#define euc_jisx0213_comp_table0300_idx (euc_jisx0213_comp_table02e9_idx+euc_jisx0213_comp_table02e9_len) +#define euc_jisx0213_comp_table0300_len 5 + { 0xa9dc, 0xabc4 }, /* 0x12B44 = 0x1295C U+0300 */ + { 0xabb8, 0xabc8 }, /* 0x12B48 = 0x12B38 U+0300 */ + { 0xabb7, 0xabca }, /* 0x12B4A = 0x12B37 U+0300 */ + { 0xabb0, 0xabcc }, /* 0x12B4C = 0x12B30 U+0300 */ + { 0xabc3, 0xabce }, /* 0x12B4E = 0x12B43 U+0300 */ +#define euc_jisx0213_comp_table0301_idx (euc_jisx0213_comp_table0300_idx+euc_jisx0213_comp_table0300_len) +#define euc_jisx0213_comp_table0301_len 4 + { 0xabb8, 0xabc9 }, /* 0x12B49 = 0x12B38 U+0301 */ + { 0xabb7, 0xabcb }, /* 0x12B4B = 0x12B37 U+0301 */ + { 0xabb0, 0xabcd }, /* 0x12B4D = 0x12B30 U+0301 */ + { 0xabc3, 0xabcf }, /* 0x12B4F = 0x12B43 U+0301 */ +#define euc_jisx0213_comp_table309a_idx (euc_jisx0213_comp_table0301_idx+euc_jisx0213_comp_table0301_len) +#define euc_jisx0213_comp_table309a_len 14 + { 0xa4ab, 0xa4f7 }, /* 0x12477 = 0x1242B U+309A */ + { 0xa4ad, 0xa4f8 }, /* 0x12478 = 0x1242D U+309A */ + { 0xa4af, 0xa4f9 }, /* 0x12479 = 0x1242F U+309A */ + { 0xa4b1, 0xa4fa }, /* 0x1247A = 0x12431 U+309A */ + { 0xa4b3, 0xa4fb }, /* 0x1247B = 0x12433 U+309A */ + { 0xa5ab, 0xa5f7 }, /* 0x12577 = 0x1252B U+309A */ + { 0xa5ad, 0xa5f8 }, /* 0x12578 = 0x1252D U+309A */ + { 0xa5af, 0xa5f9 }, /* 0x12579 = 0x1252F U+309A */ + { 0xa5b1, 0xa5fa }, /* 0x1257A = 0x12531 U+309A */ + { 0xa5b3, 0xa5fb }, /* 0x1257B = 0x12533 U+309A */ + { 0xa5bb, 0xa5fc }, /* 0x1257C = 0x1253B U+309A */ + { 0xa5c4, 0xa5fd }, /* 0x1257D = 0x12544 U+309A */ + { 0xa5c8, 0xa5fe }, /* 0x1257E = 0x12548 U+309A */ + { 0xa6f5, 0xa6f8 }, /* 0x12678 = 0x12675 U+309A */ +}; + +static int +euc_jisx0213_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + int count = 0; + unsigned short lasttwo = conv->ostate; + + if (lasttwo) { + /* Attempt to combine the last character with this one. */ + unsigned int idx; + unsigned int len; + + if (wc == 0x02e5) + idx = euc_jisx0213_comp_table02e5_idx, + len = euc_jisx0213_comp_table02e5_len; + else if (wc == 0x02e9) + idx = euc_jisx0213_comp_table02e9_idx, + len = euc_jisx0213_comp_table02e9_len; + else if (wc == 0x0300) + idx = euc_jisx0213_comp_table0300_idx, + len = euc_jisx0213_comp_table0300_len; + else if (wc == 0x0301) + idx = euc_jisx0213_comp_table0301_idx, + len = euc_jisx0213_comp_table0301_len; + else if (wc == 0x309a) + idx = euc_jisx0213_comp_table309a_idx, + len = euc_jisx0213_comp_table309a_len; + else + goto not_combining; + + do + if (euc_jisx0213_comp_table_data[idx].base == lasttwo) + break; + while (++idx, --len > 0); + + if (len > 0) { + /* Output the combined character. */ + if (n >= 2) { + lasttwo = euc_jisx0213_comp_table_data[idx].composed; + r[0] = (lasttwo >> 8) & 0xff; + r[1] = lasttwo & 0xff; + conv->ostate = 0; + return 2; + } else + return RET_TOOSMALL; + } + + not_combining: + /* Output the buffered character. */ + if (n < 2) + return RET_TOOSMALL; + r[0] = (lasttwo >> 8) & 0xff; + r[1] = lasttwo & 0xff; + r += 2; + count = 2; + } + + if (wc < 0x80) { + /* Plain ASCII character. */ + if (n > count) { + r[0] = (unsigned char) wc; + conv->ostate = 0; + return count+1; + } else + return RET_TOOSMALL; + } else if (wc >= 0xff61 && wc <= 0xff9f) { + /* Half-width katakana. */ + if (n >= count+2) { + r[0] = 0x8e; + r[1] = wc - 0xfec0; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } else { + unsigned short jch = ucs4_to_jisx0213(wc); + if (jch != 0) { + if (jch & 0x0080) { + /* A possible match in comp_table_data. We have to buffer it. */ + /* We know it's a JISX 0213 plane 1 character. */ + if (jch & 0x8000) abort(); + conv->ostate = jch | 0x8080; + return count+0; + } + if (jch & 0x8000) { + /* JISX 0213 plane 2. */ + if (n >= count+3) { + r[0] = 0x8f; + r[1] = (jch >> 8) | 0x80; + r[2] = (jch & 0xff) | 0x80; + conv->ostate = 0; + return count+3; + } else + return RET_TOOSMALL; + } else { + /* JISX 0213 plane 1. */ + if (n >= count+2) { + r[0] = (jch >> 8) | 0x80; + r[1] = (jch & 0xff) | 0x80; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + } + return RET_ILUNI; + } +} + +static int +euc_jisx0213_reset (conv_t conv, unsigned char *r, int n) +{ + state_t lasttwo = conv->ostate; + + if (lasttwo) { + if (n < 2) + return RET_TOOSMALL; + r[0] = (lasttwo >> 8) & 0xff; + r[1] = lasttwo & 0xff; + /* conv->ostate = 0; will be done by the caller */ + return 2; + } else + return 0; +} diff --git a/libs/libiconv/lib/euc_jp.h b/libs/libiconv/lib/euc_jp.h new file mode 100644 index 00000000..84fa2e7e --- /dev/null +++ b/libs/libiconv/lib/euc_jp.h @@ -0,0 +1,191 @@ +/* + * Copyright (C) 1999-2001, 2005 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * EUC-JP + */ + +static int +euc_jp_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + /* Code set 0 (ASCII or JIS X 0201-1976 Roman) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* Code set 1 (JIS X 0208) */ + if (c >= 0xa1 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + if (c < 0xf5) { + unsigned char c2 = s[1]; + if (c2 >= 0xa1 && c2 < 0xff) { + unsigned char buf[2]; + buf[0] = c-0x80; buf[1] = c2-0x80; + return jisx0208_mbtowc(conv,pwc,buf,2); + } else + return RET_ILSEQ; + } else { + /* User-defined range. See + * Ken Lunde's "CJKV Information Processing", table 4-66, p. 206. */ + unsigned char c2 = s[1]; + if (c2 >= 0xa1 && c2 < 0xff) { + *pwc = 0xe000 + 94*(c-0xf5) + (c2-0xa1); + return 2; + } else + return RET_ILSEQ; + } + } + /* Code set 2 (half-width katakana) */ + if (c == 0x8e) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if (c2 >= 0xa1 && c2 < 0xe0) { + int ret = jisx0201_mbtowc(conv,pwc,s+1,n-1); + if (ret == RET_ILSEQ) + return RET_ILSEQ; + if (ret != 1) abort(); + return 2; + } else + return RET_ILSEQ; + } + } + /* Code set 3 (JIS X 0212-1990) */ + if (c == 0x8f) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if (c2 >= 0xa1 && c2 < 0xff) { + if (n < 3) + return RET_TOOFEW(0); + if (c2 < 0xf5) { + unsigned char c3 = s[2]; + if (c3 >= 0xa1 && c3 < 0xff) { + unsigned char buf[2]; + int ret; + buf[0] = c2-0x80; buf[1] = c3-0x80; + ret = jisx0212_mbtowc(conv,pwc,buf,2); + if (ret == RET_ILSEQ) + return RET_ILSEQ; + if (ret != 2) abort(); + return 3; + } else + return RET_ILSEQ; + } else { + /* User-defined range. See + * Ken Lunde's "CJKV Information Processing", table 4-66, p. 206. */ + unsigned char c3 = s[2]; + if (c3 >= 0xa1 && c3 < 0xff) { + *pwc = 0xe3ac + 94*(c2-0xf5) + (c3-0xa1); + return 3; + } else + return RET_ILSEQ; + } + } else + return RET_ILSEQ; + } + } + return RET_ILSEQ; +} + +static int +euc_jp_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[2]; + int ret; + + /* Code set 0 (ASCII or JIS X 0201-1976 Roman) */ + ret = ascii_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + /* Code set 1 (JIS X 0208) */ + ret = jisx0208_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]+0x80; + r[1] = buf[1]+0x80; + return 2; + } + + /* Code set 2 (half-width katakana) */ + ret = jisx0201_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI && buf[0] >= 0x80) { + if (ret != 1) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = 0x8e; + r[1] = buf[0]; + return 2; + } + + /* Code set 3 (JIS X 0212-1990) */ + ret = jisx0212_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 3) + return RET_TOOSMALL; + r[0] = 0x8f; + r[1] = buf[0]+0x80; + r[2] = buf[1]+0x80; + return 3; + } + + /* Extra compatibility with Shift_JIS. */ + if (wc == 0x00a5) { + r[0] = 0x5c; + return 1; + } + if (wc == 0x203e) { + r[0] = 0x7e; + return 1; + } + + /* User-defined range. See + * Ken Lunde's "CJKV Information Processing", table 4-66, p. 206. */ + if (wc >= 0xe000 && wc < 0xe758) { + if (wc < 0xe3ac) { + unsigned char c1, c2; + if (n < 2) + return RET_TOOSMALL; + c1 = (unsigned int) (wc - 0xe000) / 94; + c2 = (unsigned int) (wc - 0xe000) % 94; + r[0] = c1+0xf5; + r[1] = c2+0xa1; + return 2; + } else { + unsigned char c1, c2; + if (n < 3) + return RET_TOOSMALL; + c1 = (unsigned int) (wc - 0xe3ac) / 94; + c2 = (unsigned int) (wc - 0xe3ac) % 94; + r[0] = 0x8f; + r[1] = c1+0xf5; + r[2] = c2+0xa1; + return 3; + } + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/euc_kr.h b/libs/libiconv/lib/euc_kr.h new file mode 100644 index 00000000..8b3dd052 --- /dev/null +++ b/libs/libiconv/lib/euc_kr.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 1999-2001, 2007 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * EUC-KR + */ + +/* Specification: RFC 1557 */ + +static int +euc_kr_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + /* Code set 0 (ASCII or KS C 5636-1993) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* Code set 1 (KS C 5601-1992, now KS X 1001:2002) */ + if (c >= 0xa1 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if (c2 >= 0xa1 && c2 < 0xff) { + unsigned char buf[2]; + buf[0] = c-0x80; buf[1] = c2-0x80; + return ksc5601_mbtowc(conv,pwc,buf,2); + } else + return RET_ILSEQ; + } + } + return RET_ILSEQ; +} + +static int +euc_kr_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[2]; + int ret; + + /* Code set 0 (ASCII or KS C 5636-1993) */ + ret = ascii_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + /* Code set 1 (KS C 5601-1992, now KS X 1001:2002) */ + ret = ksc5601_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]+0x80; + r[1] = buf[1]+0x80; + return 2; + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/euc_tw.h b/libs/libiconv/lib/euc_tw.h new file mode 100644 index 00000000..f7bdc8b7 --- /dev/null +++ b/libs/libiconv/lib/euc_tw.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * EUC-TW + */ + +static int +euc_tw_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + /* Code set 0 (ASCII) */ + if (c < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + /* Code set 1 (CNS 11643-1992 Plane 1) */ + if (c >= 0xa1 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if (c2 >= 0xa1 && c2 < 0xff) { + unsigned char buf[2]; + buf[0] = c-0x80; buf[1] = c2-0x80; + return cns11643_1_mbtowc(conv,pwc,buf,2); + } else + return RET_ILSEQ; + } + } + /* Code set 2 (CNS 11643-1992 Planes 1-16) */ + if (c == 0x8e) { + if (n < 4) + return RET_TOOFEW(0); + { + unsigned char c2 = s[1]; + if (c2 >= 0xa1 && c2 <= 0xb0) { + unsigned char c3 = s[2]; + unsigned char c4 = s[3]; + if (c3 >= 0xa1 && c3 < 0xff && c4 >= 0xa1 && c4 < 0xff) { + unsigned char buf[2]; + int ret; + buf[0] = c3-0x80; buf[1] = c4-0x80; + switch (c2-0xa0) { + case 1: ret = cns11643_1_mbtowc(conv,pwc,buf,2); break; + case 2: ret = cns11643_2_mbtowc(conv,pwc,buf,2); break; + case 3: ret = cns11643_3_mbtowc(conv,pwc,buf,2); break; + case 4: ret = cns11643_4_mbtowc(conv,pwc,buf,2); break; + case 5: ret = cns11643_5_mbtowc(conv,pwc,buf,2); break; + case 6: ret = cns11643_6_mbtowc(conv,pwc,buf,2); break; + case 7: ret = cns11643_7_mbtowc(conv,pwc,buf,2); break; + case 15: ret = cns11643_15_mbtowc(conv,pwc,buf,2); break; + default: return RET_ILSEQ; + } + if (ret == RET_ILSEQ) + return RET_ILSEQ; + if (ret != 2) abort(); + return 4; + } + } + } + } + return RET_ILSEQ; +} + +static int +euc_tw_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[3]; + int ret; + + /* Code set 0 (ASCII) */ + ret = ascii_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + ret = cns11643_wctomb(conv,buf,wc,3); + if (ret != RET_ILUNI) { + if (ret != 3) abort(); + + /* Code set 1 (CNS 11643-1992 Plane 1) */ + if (buf[0] == 1) { + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[1]+0x80; + r[1] = buf[2]+0x80; + return 2; + } + + /* Code set 2 (CNS 11643-1992 Planes 1-16) */ + if (n < 4) + return RET_TOOSMALL; + r[0] = 0x8e; + r[1] = buf[0]+0xa0; + r[2] = buf[1]+0x80; + r[3] = buf[2]+0x80; + return 4; + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/flags.h b/libs/libiconv/lib/flags.h new file mode 100644 index 00000000..e91934ab --- /dev/null +++ b/libs/libiconv/lib/flags.h @@ -0,0 +1,157 @@ +/* Generated automatically by genflags. */ + +/* Set if the encoding can encode + the acute and grave accents U+00B4 and U+0060. */ +#define HAVE_ACCENTS 1 + +/* Set if the encoding can encode + the single quotation marks U+2018 and U+2019. */ +#define HAVE_QUOTATION_MARKS 2 + +/* Set if the encoding can encode + the double-width Hangul letters (Jamo) U+3131 to U+3163. */ +#define HAVE_HANGUL_JAMO 4 + +#define ei_ascii_oflags (0) +#define ei_utf8_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_ucs2_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_ucs2be_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_ucs2le_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_ucs4_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_ucs4be_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_ucs4le_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_utf16_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_utf16be_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_utf16le_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_utf32_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_utf32be_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_utf32le_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_utf7_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_ucs2internal_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_ucs2swapped_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_ucs4internal_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_ucs4swapped_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_c99_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_java_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_iso8859_1_oflags (HAVE_ACCENTS) +#define ei_iso8859_2_oflags (HAVE_ACCENTS) +#define ei_iso8859_3_oflags (HAVE_ACCENTS) +#define ei_iso8859_4_oflags (HAVE_ACCENTS) +#define ei_iso8859_5_oflags (0) +#define ei_iso8859_6_oflags (0) +#define ei_iso8859_7_oflags (HAVE_QUOTATION_MARKS) +#define ei_iso8859_8_oflags (HAVE_ACCENTS) +#define ei_iso8859_9_oflags (HAVE_ACCENTS) +#define ei_iso8859_10_oflags (0) +#define ei_iso8859_11_oflags (0) +#define ei_iso8859_13_oflags (0) +#define ei_iso8859_14_oflags (0) +#define ei_iso8859_15_oflags (0) +#define ei_iso8859_16_oflags (0) +#define ei_koi8_r_oflags (0) +#define ei_koi8_u_oflags (0) +#define ei_koi8_ru_oflags (0) +#define ei_cp1250_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_cp1251_oflags (HAVE_QUOTATION_MARKS) +#define ei_cp1252_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_cp1253_oflags (HAVE_QUOTATION_MARKS) +#define ei_cp1254_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_cp1255_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_cp1256_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_cp1257_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_cp1258_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_cp850_oflags (HAVE_ACCENTS) +#define ei_cp862_oflags (0) +#define ei_cp866_oflags (0) +#define ei_cp1131_oflags (0) +#define ei_mac_roman_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_mac_centraleurope_oflags (HAVE_QUOTATION_MARKS) +#define ei_mac_iceland_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_mac_croatian_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_mac_romania_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_mac_cyrillic_oflags (HAVE_QUOTATION_MARKS) +#define ei_mac_ukraine_oflags (HAVE_QUOTATION_MARKS) +#define ei_mac_greek_oflags (HAVE_QUOTATION_MARKS) +#define ei_mac_turkish_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_mac_hebrew_oflags (HAVE_QUOTATION_MARKS) +#define ei_mac_arabic_oflags (0) +#define ei_mac_thai_oflags (HAVE_QUOTATION_MARKS) +#define ei_hp_roman8_oflags (HAVE_ACCENTS) +#define ei_nextstep_oflags (HAVE_ACCENTS) +#define ei_armscii_8_oflags (0) +#define ei_georgian_academy_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_georgian_ps_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_koi8_t_oflags (HAVE_QUOTATION_MARKS) +#define ei_pt154_oflags (HAVE_QUOTATION_MARKS) +#define ei_rk1048_oflags (HAVE_QUOTATION_MARKS) +#define ei_mulelao_oflags (0) +#define ei_cp1133_oflags (0) +#define ei_tis620_oflags (0) +#define ei_cp874_oflags (HAVE_QUOTATION_MARKS) +#define ei_viscii_oflags (0) +#define ei_tcvn_oflags (HAVE_ACCENTS) +#define ei_iso646_jp_oflags (0) +#define ei_jisx0201_oflags (0) +#define ei_jisx0208_oflags (HAVE_QUOTATION_MARKS) +#define ei_jisx0212_oflags (0) +#define ei_iso646_cn_oflags (0) +#define ei_gb2312_oflags (HAVE_QUOTATION_MARKS) +#define ei_isoir165_oflags (HAVE_QUOTATION_MARKS) +#define ei_ksc5601_oflags (HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_euc_jp_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_sjis_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_cp932_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_iso2022_jp_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_iso2022_jp1_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_iso2022_jp2_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_euc_cn_oflags (HAVE_QUOTATION_MARKS) +#define ei_ces_gbk_oflags (HAVE_QUOTATION_MARKS) +#define ei_cp936_oflags (HAVE_QUOTATION_MARKS) +#define ei_gb18030_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_iso2022_cn_oflags (HAVE_QUOTATION_MARKS) +#define ei_iso2022_cn_ext_oflags (HAVE_QUOTATION_MARKS) +#define ei_hz_oflags (HAVE_QUOTATION_MARKS) +#define ei_euc_tw_oflags (HAVE_QUOTATION_MARKS) +#define ei_ces_big5_oflags (HAVE_QUOTATION_MARKS) +#define ei_cp950_oflags (HAVE_QUOTATION_MARKS) +#define ei_big5hkscs1999_oflags (HAVE_QUOTATION_MARKS) +#define ei_big5hkscs2001_oflags (HAVE_QUOTATION_MARKS) +#define ei_big5hkscs2004_oflags (HAVE_QUOTATION_MARKS) +#define ei_big5hkscs2008_oflags (HAVE_QUOTATION_MARKS) +#define ei_euc_kr_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_cp949_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_johab_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_iso2022_kr_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS | HAVE_HANGUL_JAMO) +#define ei_cp856_oflags (HAVE_ACCENTS) +#define ei_cp922_oflags (HAVE_ACCENTS) +#define ei_cp943_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_cp1046_oflags (0) +#define ei_cp1124_oflags (0) +#define ei_cp1129_oflags (0) +#define ei_cp1161_oflags (0) +#define ei_cp1162_oflags (HAVE_QUOTATION_MARKS) +#define ei_cp1163_oflags (0) +#define ei_dec_kanji_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_dec_hanyu_oflags (HAVE_QUOTATION_MARKS) +#define ei_cp437_oflags (0) +#define ei_cp737_oflags (0) +#define ei_cp775_oflags (0) +#define ei_cp852_oflags (HAVE_ACCENTS) +#define ei_cp853_oflags (HAVE_ACCENTS) +#define ei_cp855_oflags (0) +#define ei_cp857_oflags (HAVE_ACCENTS) +#define ei_cp858_oflags (HAVE_ACCENTS) +#define ei_cp860_oflags (0) +#define ei_cp861_oflags (0) +#define ei_cp863_oflags (HAVE_ACCENTS) +#define ei_cp864_oflags (0) +#define ei_cp865_oflags (0) +#define ei_cp869_oflags (HAVE_QUOTATION_MARKS) +#define ei_cp1125_oflags (0) +#define ei_euc_jisx0213_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_shift_jisx0213_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_iso2022_jp3_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) +#define ei_big5_2003_oflags (HAVE_QUOTATION_MARKS) +#define ei_tds565_oflags (0) +#define ei_atarist_oflags (HAVE_ACCENTS) +#define ei_riscos1_oflags (HAVE_ACCENTS | HAVE_QUOTATION_MARKS) diff --git a/libs/libiconv/lib/flushwc.h b/libs/libiconv/lib/flushwc.h new file mode 100644 index 00000000..da25212e --- /dev/null +++ b/libs/libiconv/lib/flushwc.h @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _FLUSHWC_H +#define _FLUSHWC_H + +static int +normal_flushwc (conv_t conv, ucs4_t *pwc) +{ + ucs4_t last_wc = conv->istate; + if (last_wc) { + /* Output the buffered character. */ + conv->istate = 0; + *pwc = (ucs4_t) last_wc; + return 1; + } else + return 0; +} + +#endif /* _FLUSHWC_H */ diff --git a/libs/libiconv/lib/gb12345.h b/libs/libiconv/lib/gb12345.h new file mode 100644 index 00000000..b7e062e3 --- /dev/null +++ b/libs/libiconv/lib/gb12345.h @@ -0,0 +1,67 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * GB/T 12345-1990 + */ + +/* + * GB/T 12345-1990 is a traditional chinese counterpart of GB 2312-1986. + * According to the unicode.org tables: + * 2146 characters have been changed to their traditional counterpart, + * 103 characters have been added, no characters have been removed. + * Therefore we use an auxiliary table, which contains only the changes. + */ + +#include "gb12345ext.h" + +static int +gb12345_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + int ret; + + /* The gb12345ext table overrides some entries in the gb2312 table. */ + /* Try the GB12345 extensions -> Unicode table. */ + ret = gb12345ext_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + /* Try the GB2312 -> Unicode table. */ + ret = gb2312_mbtowc(conv,pwc,s,n); + return ret; +} + +static int +gb12345_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + int ret; + + /* The gb12345ext table overrides some entries in the gb2312 table. */ + /* Try the Unicode -> GB12345 extensions table. */ + ret = gb12345ext_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + /* Try the Unicode -> GB2312 table, and check that the resulting GB2312 + byte sequence is not overridden by the GB12345 extensions table. */ + ret = gb2312_wctomb(conv,r,wc,n); + if (ret == 2 && gb12345ext_mbtowc(conv,&wc,r,2) == 2) + return RET_ILUNI; + else + return ret; +} diff --git a/libs/libiconv/lib/gb12345ext.h b/libs/libiconv/lib/gb12345ext.h new file mode 100644 index 00000000..b461ec87 --- /dev/null +++ b/libs/libiconv/lib/gb12345ext.h @@ -0,0 +1,1796 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * GB/T 12345.1990-0 extensions + */ + +static const unsigned short gb12345ext_2uni_page21[12] = { + /* 0x21 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x2225, +}; +static const unsigned short gb12345ext_2uni_page26[85] = { + /* 0x26 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfe35, + 0xfe36, 0xfe39, 0xfe3a, 0xfe3f, 0xfe40, 0xfe3d, 0xfe3e, 0xfe41, + 0xfe42, 0xfe43, 0xfe44, 0xfffd, 0xfffd, 0xfe3b, 0xfe3c, 0xfe37, + 0xfe38, 0xfe31, 0xfffd, 0xfe33, 0xfe34, +}; +static const unsigned short gb12345ext_2uni_page28[32] = { + /* 0x28 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x0251, 0x1e3f, 0x0144, 0x0148, 0x01f9, 0x0261, +}; +static const unsigned short gb12345ext_2uni_page30[6871] = { + /* 0x30 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x769a, + 0xfffd, 0x85f9, 0xfffd, 0xfffd, 0x7919, 0x611b, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x9aaf, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8956, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x58e9, 0xfffd, 0x7f77, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x64fa, 0xfffd, 0x6557, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x9812, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x8fa6, 0x7d46, 0xfffd, 0x5e6b, 0xfffd, + 0xfffd, 0xfffd, 0x7d81, 0xfffd, 0xfffd, 0xfffd, 0x938a, 0xfffd, + 0x8b17, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x31 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x98fd, 0x5bf6, 0xfffd, 0x5831, + 0xfffd, 0xfffd, 0x9b91, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x8f29, 0xfffd, 0x8c9d, 0x92c7, 0xfffd, 0x72fd, 0x5099, + 0x618a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x7db3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x7b46, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7562, 0x6583, + 0xfffd, 0x5e63, 0xfffd, 0xfffd, 0x9589, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x908a, 0x7de8, + 0x8cb6, 0xfffd, 0xfffd, 0x8b8a, 0xfffd, 0xfffd, 0x8faf, 0x8fae, + 0xfffd, 0x6a19, 0xfffd, 0xfffd, 0xfffd, 0x9c49, 0xfffd, 0xfffd, + 0x765f, 0xfffd, 0xfffd, 0x7015, 0x6ff1, 0x8cd3, 0x64ef, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9905, 0xfffd, + /* 0x32 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x64a5, 0x9262, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x9251, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x99c1, 0xfffd, 0xfffd, 0xfffd, + 0x88dc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ca1, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x53c3, 0x8836, 0x6b98, + 0x615a, 0x6158, 0x71e6, 0x84bc, 0x8259, 0x5009, 0x6ec4, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x53a0, 0xfffd, 0x5074, + 0xfffd, 0x6e2c, 0x5c64, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a6b, 0xfffd, + 0xfffd, 0xfffd, 0x6519, 0x647b, 0x87ec, 0x995e, 0x8b92, 0x7e8f, + 0x93df, 0x7523, 0x95e1, 0x986b, 0xfffd, 0xfffd, + /* 0x33 */ + 0x5834, 0x5617, 0xfffd, 0x9577, 0x511f, 0x8178, 0x5ee0, 0xfffd, + 0x66a2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9214, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8eca, 0xfffd, 0xfffd, 0xfffd, + 0x5fb9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5875, 0xfffd, 0xfffd, + 0xfffd, 0x9673, 0xfffd, 0x896f, 0xfffd, 0x7a31, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x61f2, 0xfffd, 0x8aa0, 0xfffd, + 0xfffd, 0x9a01, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x9072, 0xfffd, 0x99b3, 0xfffd, 0x9f52, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x71be, 0xfffd, 0x885d, 0x87f2, 0xfffd, 0x5bf5, + 0xfffd, 0xfffd, 0x7587, 0x8e8a, 0xfffd, 0xfffd, 0x7c4c, 0xfffd, + 0x7da2, 0xfffd, 0x919c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x92e4, 0x96db, 0xfffd, 0xfffd, 0xfffd, + /* 0x34 */ + 0x790e, 0x5132, 0xfffd, 0xfffd, 0x89f8, 0x8655, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x50b3, 0xfffd, 0xfffd, 0xfffd, 0x7621, 0xfffd, + 0xfffd, 0xfffd, 0x95d6, 0x5275, 0xfffd, 0xfffd, 0xfffd, 0x9318, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7d14, 0xfffd, + 0xfffd, 0x7dbd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8fad, 0xfffd, + 0xfffd, 0x8a5e, 0xfffd, 0xfffd, 0x8cdc, 0xfffd, 0x8070, 0xfffd, + 0xfffd, 0xfffd, 0x5f9e, 0x53e2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x8ea5, 0xfffd, 0x7ac4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x932f, 0xfffd, 0x9054, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5e36, + 0xfffd, 0xfffd, 0x8cb8, 0xfffd, 0xfffd, 0xfffd, + /* 0x35 */ + 0xfffd, 0xfffd, 0x64d4, 0xfffd, 0x55ae, 0x9132, 0x64a3, 0x81bd, + 0xfffd, 0xfffd, 0xfffd, 0x619a, 0xfffd, 0x8a95, 0x5f48, 0xfffd, + 0x7576, 0x64cb, 0x9ee8, 0x8569, 0x6a94, 0xfffd, 0x6417, 0xfffd, + 0xfffd, 0x5cf6, 0x79b1, 0x5c0e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x71c8, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x9127, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6575, + 0xfffd, 0xfffd, 0x6ecc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x905e, 0x7de0, 0x985b, 0xfffd, + 0xfffd, 0xfffd, 0x9ede, 0xfffd, 0xfffd, 0x588a, 0x96fb, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6fb1, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x91e3, 0x8abf, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8adc, 0xfffd, + /* 0x36 */ + 0xfffd, 0xfffd, 0xfffd, 0x91d8, 0x9802, 0xfffd, 0x9320, 0xfffd, + 0x8a02, 0xfffd, 0x6771, 0xfffd, 0xfffd, 0xfffd, 0x52d5, 0x68df, + 0xfffd, 0xfffd, 0x51cd, 0xfffd, 0xfffd, 0xfffd, 0x9b25, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x72a2, 0x7368, + 0x8b80, 0xfffd, 0xfffd, 0x8ced, 0xfffd, 0x934d, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x935b, 0xfffd, 0x65b7, 0x7dde, + 0xfffd, 0xfffd, 0x968a, 0x5c0d, 0xfffd, 0x5678, 0xfffd, 0xfffd, + 0x9813, 0xfffd, 0x920d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x596a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x58ae, 0xfffd, 0xfffd, 0x9d5d, 0xfffd, 0x984d, 0x8a1b, 0xfffd, + 0x60e1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9913, 0xfffd, 0xfffd, + 0x5152, 0xfffd, 0x723e, 0x990c, 0xfffd, 0xfffd, + /* 0x37 */ + 0x8cb3, 0x767c, 0x7f70, 0xfffd, 0xfffd, 0xfffd, 0x95a5, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x792c, 0x91e9, + 0xfffd, 0xfffd, 0x7169, 0xfffd, 0xfffd, 0x7bc4, 0x8ca9, 0xfffd, + 0x98ef, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x8a2a, 0x7d21, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x98db, 0xfffd, 0xfffd, 0x8ab9, 0xfffd, 0xfffd, 0x5ee2, 0xfffd, + 0x8cbb, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7d1b, 0x58b3, + 0xfffd, 0xfffd, 0xfffd, 0x596e, 0xfffd, 0xfffd, 0x61a4, 0x7cde, + 0x8c50, 0xfffd, 0x6953, 0xfffd, 0xfffd, 0x92d2, 0x98a8, 0x760b, + 0xfffd, 0xfffd, 0x99ae, 0x7e2b, 0x8af7, 0xfffd, 0x9cf3, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x819a, 0xfffd, 0xfffd, 0xfffd, 0x8f3b, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x38 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x64ab, 0x8f14, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x8ce6, 0x5fa9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x8ca0, 0xfffd, 0x8a03, 0xfffd, 0x5a66, 0x7e1b, 0xfffd, + 0xfffd, 0xfffd, 0x8a72, 0xfffd, 0xfffd, 0x9223, 0x84cb, 0xfffd, + 0x5e79, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8d95, 0xfffd, + 0xfffd, 0xfffd, 0x8d1b, 0x5ca1, 0x525b, 0x92fc, 0xfffd, 0xfffd, + 0x7db1, 0x5d17, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x93ac, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x64f1, 0xfffd, 0x9d3f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x95a3, 0xfffd, 0x927b, 0x500b, 0xfffd, 0x7d66, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x39 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9f94, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x978f, 0xfffd, 0xfffd, + 0x8ca2, 0xfffd, 0x920e, 0xfffd, 0x6e9d, 0xfffd, 0xfffd, 0xfffd, + 0x69cb, 0x8cfc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8831, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x9867, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x526e, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x95dc, + 0xfffd, 0xfffd, 0x89c0, 0xfffd, 0x9928, 0xfffd, 0x6163, 0xfffd, + 0x8cab, 0xfffd, 0x5ee3, 0xfffd, 0xfffd, 0x898f, 0xfffd, 0xfffd, + 0x6b78, 0x9f9c, 0x95a8, 0x8ecc, 0xfffd, 0x8a6d, 0xfffd, 0xfffd, + 0x6ac3, 0xfffd, 0x8cb4, 0x528a, 0x8f25, 0xfffd, 0xfffd, 0x934b, + 0xfffd, 0x570b, 0xfffd, 0xfffd, 0x904e, 0xfffd, + /* 0x3a */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x99ed, 0xfffd, + 0xfffd, 0xfffd, 0x97d3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x6f22, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x865f, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x95a1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9db4, 0x8cc0, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x8f5f, 0xfffd, 0xfffd, 0xfffd, 0x9d3b, + 0xfffd, 0xfffd, 0xfffd, 0x7d05, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x5f8c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x58fa, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x3b */ + 0xfffd, 0xfffd, 0xfffd, 0x8b77, 0xfffd, 0x6eec, 0xfffd, 0xfffd, + 0x5629, 0x83ef, 0xfffd, 0xfffd, 0x756b, 0x5283, 0xfffd, 0x8a71, + 0xfffd, 0xfffd, 0x61f7, 0xfffd, 0x58de, 0x6b61, 0x74b0, 0xfffd, + 0x9084, 0x7de9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x8b0a, 0xfffd, 0x63ee, 0x8f1d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8cc4, 0x7a62, + 0x6703, 0x71f4, 0x532f, 0x8af1, 0x8aa8, 0x7e6a, 0x8477, 0xfffd, + 0xfffd, 0xfffd, 0x6e3e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x7372, 0xfffd, 0xfffd, 0xfffd, 0x8ca8, 0x798d, 0x64ca, 0xfffd, + 0xfffd, 0x6a5f, 0xfffd, 0xfffd, 0x7a4d, 0xfffd, + /* 0x3c */ + 0xfffd, 0x9951, 0xfffd, 0xfffd, 0x8b4f, 0x9dc4, 0xfffd, 0x7e3e, + 0x7ddd, 0xfffd, 0x6975, 0xfffd, 0x8f2f, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7d1a, 0x64e0, 0x5e7e, + 0xfffd, 0xfffd, 0x858a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x5291, 0xfffd, 0x6fdf, 0xfffd, 0xfffd, 0x8a08, 0x8a18, 0xfffd, + 0xfffd, 0x969b, 0xfffd, 0x7e7c, 0x7d00, 0xfffd, 0xfffd, 0x593e, + 0xfffd, 0xfffd, 0xfffd, 0x83a2, 0x9830, 0x8cc8, 0xfffd, 0x9240, + 0xfffd, 0xfffd, 0x50f9, 0xfffd, 0x99d5, 0xfffd, 0x6bb2, 0x76e3, + 0x5805, 0xfffd, 0x7b8b, 0x9593, 0xfffd, 0xfffd, 0xfffd, 0x8271, + 0xfffd, 0x7dd8, 0x7e6d, 0x6aa2, 0xfffd, 0xfffd, 0x9e7c, 0x63c0, + 0x64bf, 0x7c21, 0x5109, 0xfffd, 0xfffd, 0x85a6, 0x6abb, 0x9452, + 0x8e10, 0x8ce4, 0x898b, 0x9375, 0xfffd, 0xfffd, + /* 0x3d */ + 0xfffd, 0x8266, 0x528d, 0x991e, 0x6f38, 0x6ffa, 0x6f97, 0xfffd, + 0xfffd, 0xfffd, 0x5c07, 0x6f3f, 0xfffd, 0xfffd, 0x8523, 0x69f3, + 0x596c, 0x8b1b, 0xfffd, 0x91ac, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x81a0, 0xfffd, 0xfffd, 0x6f86, 0x9a55, 0x5b0c, 0xfffd, + 0x652a, 0x9278, 0x77ef, 0x50e5, 0xfffd, 0xfffd, 0xfffd, 0x9903, + 0x7e73, 0x7d5e, 0xfffd, 0xfffd, 0xfffd, 0x8f4e, 0x8f03, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x968e, 0xfffd, + 0xfffd, 0x7bc0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6f54, + 0x7d50, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x8aa1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x7dca, 0x9326, 0x50c5, 0x8b39, 0x9032, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x71fc, 0xfffd, + /* 0x3e */ + 0x76e1, 0x52c1, 0xfffd, 0xfffd, 0x8396, 0xfffd, 0xfffd, 0x9be8, + 0xfffd, 0x9a5a, 0xfffd, 0xfffd, 0x7d93, 0xfffd, 0xfffd, 0xfffd, + 0x9838, 0xfffd, 0xfffd, 0xfffd, 0x93e1, 0x5f91, 0x75d9, 0xfffd, + 0xfffd, 0x7af6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7cfe, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x820a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x99d2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x8209, 0xfffd, 0xfffd, 0xfffd, 0x64da, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x92f8, 0xfffd, 0xfffd, 0x61fc, 0xfffd, 0x5287, 0xfffd, + 0x9d51, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7d79, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x89ba, 0xfffd, 0x8a23, 0x7d76, + 0xfffd, 0xfffd, 0x921e, 0x8ecd, 0xfffd, 0xfffd, + /* 0x3f */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x99ff, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x958b, 0xfffd, 0xfffd, 0x51f1, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9846, 0xfffd, 0x6bbb, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ab2, 0xfffd, 0xfffd, + 0x58be, 0x61c7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x6473, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x5eab, 0x8932, 0x8a87, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x584a, 0xfffd, 0x5108, 0xfffd, 0x5bec, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x7926, 0xfffd, 0x66e0, 0xfffd, 0x8667, 0xfffd, + 0x5dcb, 0x7aba, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x40 */ + 0x994b, 0xfffd, 0x6f70, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x64f4, 0xfffd, 0x95ca, 0xfffd, 0xfffd, 0xfffd, 0x881f, 0x81d8, + 0xfffd, 0xfffd, 0x840a, 0x4f86, 0x8cf4, 0x85cd, 0xfffd, 0x6b04, + 0x6514, 0x7c43, 0x95cc, 0x862d, 0x703e, 0x8b95, 0x652c, 0x89bd, + 0x61f6, 0x7e9c, 0x721b, 0x6feb, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x6488, 0x52de, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x6f87, 0xfffd, 0x6a02, 0xfffd, 0x9433, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x58d8, 0xfffd, 0xfffd, 0x985e, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x7c6c, 0xfffd, 0x96e2, 0x7055, 0xfffd, 0xfffd, 0x88cf, 0x9bc9, + 0x79ae, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9e97, 0x53b2, 0x52f5, + 0x792b, 0x6b77, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x41 */ + 0xfffd, 0xfffd, 0xfffd, 0x701d, 0x96b8, 0xfffd, 0xfffd, 0xfffd, + 0x5006, 0x806f, 0x84ee, 0x9023, 0x942e, 0xfffd, 0x6190, 0x6f23, + 0x7c3e, 0x6582, 0x81c9, 0x93c8, 0x6200, 0x7149, 0x7df4, 0x7ce7, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5169, 0x8f1b, 0xfffd, 0xfffd, + 0xfffd, 0x8ad2, 0xfffd, 0xfffd, 0xfffd, 0x7642, 0xfffd, 0xfffd, + 0x907c, 0xfffd, 0xfffd, 0xfffd, 0x9410, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x7375, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x81e8, 0x9130, 0x9c57, 0xfffd, 0xfffd, 0x8cc3, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x9f61, 0x9234, 0xfffd, 0xfffd, 0xfffd, + 0x9748, 0xfffd, 0x5dba, 0x9818, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x993e, 0xfffd, 0x5289, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x9f8d, 0x807e, 0x56a8, 0x7c60, 0xfffd, + /* 0x42 */ + 0xfffd, 0x58df, 0x650f, 0x96b4, 0x6a13, 0x5a41, 0x645f, 0x7c0d, + 0xfffd, 0xfffd, 0x8606, 0x76e7, 0x9871, 0x5eec, 0x7210, 0x64c4, + 0x6ef7, 0x865c, 0x9b6f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8cc2, + 0xfffd, 0xfffd, 0xfffd, 0x9332, 0x9678, 0xfffd, 0x9a62, 0xfffd, + 0x92c1, 0xfffd, 0xfffd, 0xfffd, 0x5c62, 0x7e37, 0x616e, 0xfffd, + 0xfffd, 0xfffd, 0x6ffe, 0x7dd1, 0x5dd2, 0x6523, 0x5b7f, 0x7064, + 0xfffd, 0x4e82, 0xfffd, 0xfffd, 0x6384, 0x8f2a, 0x502b, 0x4f96, + 0x6dea, 0x7db8, 0x8ad6, 0x863f, 0xfffd, 0x7f85, 0x908f, 0x947c, + 0x7c6e, 0x9a3e, 0xfffd, 0xfffd, 0xfffd, 0x99f1, 0x7d61, 0x5abd, + 0xfffd, 0x746a, 0x78bc, 0x879e, 0x99ac, 0x99e1, 0xfffd, 0x55ce, + 0xfffd, 0x8cb7, 0x9ea5, 0x8ce3, 0x9081, 0xfffd, 0x779e, 0x9945, + 0x883b, 0x6eff, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x43 */ + 0x8b3e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x9328, 0xfffd, 0xfffd, 0x925a, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x8cbf, 0x9ebd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9382, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9580, 0x60b6, 0x5011, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x9333, 0xfffd, 0x5922, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8b0e, 0x5f4c, 0xfffd, 0xfffd, + 0x8993, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7dbf, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7dec, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5edf, 0xfffd, 0xfffd, 0x6ec5, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x61ab, 0x95a9, 0xfffd, 0xfffd, + 0x9cf4, 0x9298, 0xfffd, 0xfffd, 0x8b2c, 0xfffd, + /* 0x44 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x8b00, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x755d, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9209, 0xfffd, 0xfffd, + 0x7d0d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x96e3, 0xfffd, 0x6493, 0x8166, 0x60f1, 0x9b27, 0xfffd, 0xfffd, + 0x9912, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x64ec, 0xfffd, 0xfffd, 0x81a9, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x6506, 0xfffd, 0xfffd, 0xfffd, 0x91c0, + 0x9ce5, 0xfffd, 0xfffd, 0x8076, 0xfffd, 0x5699, 0x9477, 0x93b3, + 0xfffd, 0xfffd, 0x6ab8, 0x7370, 0xfffd, 0x5be7, + /* 0x45 */ + 0x64f0, 0x6fd8, 0xfffd, 0xfffd, 0x9215, 0x7d10, 0x81bf, 0x6fc3, + 0x8fb2, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x7627, 0xfffd, 0xfffd, 0xfffd, 0x8afe, 0xfffd, 0x6b50, 0x9dd7, + 0x6bc6, 0xfffd, 0x5614, 0xfffd, 0x6f1a, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x76e4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x9f90, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x8ce0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5674, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x9d6c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x46 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9a19, 0x98c4, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x983b, 0x8ca7, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x860b, 0xfffd, 0xfffd, 0x6191, 0xfffd, 0x8a55, + 0xfffd, 0xfffd, 0x6f51, 0x9817, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x64b2, 0x92ea, 0x50d5, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x6a38, 0xfffd, 0xfffd, 0xfffd, 0x8b5c, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x81cd, 0x9f4a, 0xfffd, 0xfffd, 0xfffd, 0x9a0e, 0xfffd, + 0x8c48, 0xfffd, 0xfffd, 0x5553, 0xfffd, 0xfffd, 0xfffd, 0x6c23, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a16, 0xfffd, + /* 0x47 */ + 0xfffd, 0xfffd, 0x727d, 0xfffd, 0x91fa, 0x925b, 0xfffd, 0x9077, + 0x7c3d, 0xfffd, 0x8b19, 0xfffd, 0xfffd, 0x9322, 0x9257, 0xfffd, + 0xfffd, 0xfffd, 0x6dfa, 0x8b74, 0x5879, 0xfffd, 0xfffd, 0xfffd, + 0x69cd, 0x55c6, 0xfffd, 0xfffd, 0x58bb, 0x8594, 0xfffd, 0x6436, + 0xfffd, 0x936c, 0xfffd, 0xfffd, 0x6a4b, 0xfffd, 0x55ac, 0x50d1, + 0xfffd, 0xfffd, 0xfffd, 0x7ff9, 0xfffd, 0xfffd, 0x7ac5, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x7aca, 0x6b3d, 0xfffd, 0x89aa, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5be2, 0xfffd, 0xfffd, + 0x8f15, 0x6c2b, 0x50be, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x9803, 0x8acb, 0x6176, 0x74ca, 0x7aae, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8da8, 0x5340, + 0xfffd, 0xfffd, 0x8ec0, 0xfffd, 0x9a45, 0xfffd, + /* 0x48 */ + 0xfffd, 0xfffd, 0x9f72, 0xfffd, 0xfffd, 0xfffd, 0x9874, 0x6b0a, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x52f8, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9d72, 0xfffd, 0x78ba, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x8b93, 0x9952, 0x64fe, 0x7e5e, 0xfffd, 0x71b1, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x97cc, 0xfffd, 0x8a8d, 0xfffd, + 0xfffd, 0x7d09, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x69ae, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7d68, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8edf, 0xfffd, 0xfffd, 0xfffd, + 0x92ed, 0x958f, 0x6f64, 0xfffd, 0xfffd, 0xfffd, 0x7051, 0x85a9, + 0xfffd, 0x9c13, 0xfffd, 0x8cfd, 0xfffd, 0xfffd, + /* 0x49 */ + 0x5098, 0xfffd, 0xfffd, 0xfffd, 0x55aa, 0xfffd, 0x9a37, 0x6383, + 0xfffd, 0xfffd, 0xfffd, 0x6f80, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x6bba, 0xfffd, 0xfffd, 0x7d17, 0xfffd, 0xfffd, 0xfffd, 0x7be9, + 0x66ec, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x9583, 0x965d, 0xfffd, 0x8d0d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x7e55, 0xfffd, 0x50b7, 0xfffd, 0x8cde, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x71d2, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x7d39, 0xfffd, 0x8cd2, 0xfffd, 0xfffd, + 0x6368, 0xfffd, 0x651d, 0xfffd, 0x61fe, 0xfffd, 0xfffd, 0x8a2d, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7d33, + 0xfffd, 0xfffd, 0x5be9, 0x5b38, 0xfffd, 0x814e, 0xfffd, 0x6ef2, + 0x8072, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7e69, + /* 0x4a */ + 0xfffd, 0xfffd, 0xfffd, 0x52dd, 0x8056, 0x5e2b, 0xfffd, 0x7345, + 0xfffd, 0x6fd5, 0x8a69, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x6642, 0xfffd, 0xfffd, 0x8755, 0x5be6, 0x8b58, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x99db, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x52e2, 0xfffd, 0xfffd, + 0xfffd, 0x9069, 0xfffd, 0xfffd, 0x91cb, 0x98fe, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x8996, 0x8a66, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x58fd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7378, 0xfffd, 0x6a1e, + 0xfffd, 0xfffd, 0xfffd, 0x8f38, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x66f8, 0x8d16, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x5c6c, 0x8853, 0xfffd, 0x6a39, 0xfffd, + 0xfffd, 0x7aea, 0xfffd, 0xfffd, 0x6578, 0xfffd, + /* 0x4b */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5e25, 0xfffd, + 0xfffd, 0xfffd, 0x96d9, 0xfffd, 0x8ab0, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x9806, 0xfffd, 0x8aac, 0x78a9, 0xfffd, 0x720d, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7d72, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x98fc, 0xfffd, + 0x9b06, 0x8073, 0x616b, 0x980c, 0xfffd, 0xfffd, 0x8a1f, 0x8aa6, + 0xfffd, 0xfffd, 0x64fb, 0xfffd, 0x8607, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a34, 0x8085, + 0xfffd, 0xfffd, 0xfffd, 0x96d6, 0xfffd, 0x96a8, 0x7d8f, 0xfffd, + 0xfffd, 0x6b72, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5b6b, 0x640d, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7e2e, 0x7463, 0xfffd, 0x9396, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x4c */ + 0x737a, 0x64bb, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x81fa, + 0xfffd, 0xfffd, 0xfffd, 0x614b, 0xfffd, 0xfffd, 0x6524, 0x8caa, + 0x7671, 0x7058, 0x58c7, 0xfffd, 0xfffd, 0xfffd, 0x8b5a, 0x8ac7, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5606, 0xfffd, 0x6e6f, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x71d9, 0xfffd, 0x6fe4, 0xfffd, 0x7e27, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a0e, 0xfffd, 0xfffd, + 0xfffd, 0x9a30, 0xfffd, 0x8b04, 0xfffd, 0xfffd, 0xfffd, 0x92bb, + 0xfffd, 0x984c, 0xfffd, 0xfffd, 0x9ad4, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x689d, 0xfffd, 0xfffd, 0xfffd, + 0x8cbc, 0x9435, 0xfffd, 0x5ef3, 0x807d, 0x70f4, + /* 0x4d */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9285, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x7d71, 0xfffd, 0xfffd, 0xfffd, 0x982d, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x5716, 0xfffd, 0xfffd, 0x5857, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5718, 0xfffd, 0x983d, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x9d15, 0xfffd, 0x99b1, 0x99dd, 0x6a62, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7aaa, 0xfffd, 0xfffd, 0x896a, + 0xfffd, 0xfffd, 0xfffd, 0x5f4e, 0x7063, 0xfffd, 0x9811, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x842c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7db2, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x4e */ + 0xfffd, 0xfffd, 0xfffd, 0x97cb, 0x9055, 0xfffd, 0x570d, 0xfffd, + 0xfffd, 0x7232, 0x6ff0, 0x7dad, 0x8466, 0xfffd, 0xfffd, 0x5049, + 0x50de, 0xfffd, 0x7def, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8b02, 0xfffd, 0xfffd, 0x885b, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x805e, 0x7d0b, 0xfffd, 0x7a69, + 0xfffd, 0x554f, 0xfffd, 0xfffd, 0xfffd, 0x64be, 0x8778, 0x6e26, + 0x7aa9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x55da, + 0x93a2, 0x70cf, 0xfffd, 0x8aa3, 0xfffd, 0x7121, 0x856a, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x5862, 0xfffd, 0x9727, 0xfffd, 0xfffd, 0xfffd, + 0x52d9, 0xfffd, 0x8aa4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x932b, 0x72a7, + /* 0x4f */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8972, 0xfffd, 0x7fd2, + 0xfffd, 0xfffd, 0x9291, 0xfffd, 0xfffd, 0xfffd, 0x6232, 0x7d30, + 0xfffd, 0x8766, 0xfffd, 0xfffd, 0x8f44, 0xfffd, 0x5cfd, 0x4fe0, + 0x72f9, 0xfffd, 0xfffd, 0xfffd, 0x5687, 0xfffd, 0x9341, 0xfffd, + 0xfffd, 0x9bae, 0x7e96, 0xfffd, 0x8ce2, 0x929c, 0xfffd, 0x9591, + 0xfffd, 0xfffd, 0xfffd, 0x986f, 0x96aa, 0x73fe, 0x737b, 0x7e23, + 0xfffd, 0x9921, 0xfffd, 0x61b2, 0xfffd, 0xfffd, 0x7dab, 0xfffd, + 0xfffd, 0x9472, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9109, 0xfffd, + 0xfffd, 0x8a73, 0xfffd, 0x97ff, 0xfffd, 0x9805, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x856d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x56c2, 0x92b7, 0xfffd, 0xfffd, 0xfffd, 0x66c9, + /* 0x50 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x562f, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5354, 0x633e, 0xfffd, 0xfffd, + 0xfffd, 0x8105, 0x8ae7, 0x5beb, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x7009, 0x8b1d, 0xfffd, 0xfffd, 0xfffd, 0x92c5, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x91c1, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x8208, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x92b9, 0xfffd, 0xfffd, 0x7d89, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x9808, 0xfffd, 0x8a31, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7dd2, 0x7e8c, + 0x8ed2, 0xfffd, 0xfffd, 0x61f8, 0xfffd, 0xfffd, + /* 0x51 */ + 0x9078, 0x766c, 0xfffd, 0x7d62, 0xfffd, 0xfffd, 0x5b78, 0xfffd, + 0xfffd, 0xfffd, 0x52db, 0xfffd, 0xfffd, 0xfffd, 0x8a62, 0x5c0b, + 0x99b4, 0xfffd, 0xfffd, 0xfffd, 0x8a13, 0x8a0a, 0x905c, 0xfffd, + 0x58d3, 0xfffd, 0x9d09, 0x9d28, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x555e, 0x4e9e, 0x8a1d, + 0xfffd, 0xfffd, 0x95b9, 0xfffd, 0xfffd, 0x9e7d, 0x56b4, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9854, 0x95bb, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8277, 0xfffd, 0xfffd, + 0x53ad, 0x786f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8afa, + 0x9a57, 0xfffd, 0xfffd, 0x9d26, 0xfffd, 0x694a, 0x63da, 0xfffd, + 0x760d, 0xfffd, 0xfffd, 0x967d, 0xfffd, 0xfffd, 0x7662, 0x990a, + 0x6a23, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x52 */ + 0xfffd, 0x582f, 0xfffd, 0xfffd, 0x8b21, 0xfffd, 0xfffd, 0xfffd, + 0x85e5, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x723a, 0xfffd, + 0xfffd, 0xfffd, 0x9801, 0xfffd, 0x696d, 0x8449, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x91ab, 0xfffd, 0x92a5, 0xfffd, + 0xfffd, 0xfffd, 0x9824, 0xfffd, 0x907a, 0xfffd, 0x5100, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x87fb, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x85dd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x5104, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x61b6, 0x7fa9, 0xfffd, 0xfffd, 0x8a63, + 0x8b70, 0x8abc, 0x8b6f, 0xfffd, 0xfffd, 0xfffd, 0x7e79, 0xfffd, + 0x852d, 0xfffd, 0xfffd, 0xfffd, 0x9670, 0xfffd, 0xfffd, 0x9280, + 0xfffd, 0xfffd, 0x98f2, 0xfffd, 0xfffd, 0x96b1, + /* 0x53 */ + 0xfffd, 0xfffd, 0x6afb, 0x5b30, 0x9df9, 0x61c9, 0x7e93, 0x7469, + 0x87a2, 0x71df, 0x7192, 0x8805, 0xfffd, 0x8d0f, 0xfffd, 0xfffd, + 0x7a4e, 0xfffd, 0xfffd, 0x55b2, 0x64c1, 0x50ad, 0xfffd, 0x7670, + 0xfffd, 0xfffd, 0x8e34, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x512a, 0xfffd, 0x6182, 0xfffd, + 0xfffd, 0x90f5, 0x923e, 0x7336, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a98, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f3f, 0x9918, + 0xfffd, 0xfffd, 0x9b5a, 0xfffd, 0xfffd, 0x6f01, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x8207, 0x5dbc, 0xfffd, 0xfffd, 0x8a9e, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x9b31, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x7344, 0xfffd, 0x8b7d, + /* 0x54 */ + 0xfffd, 0xfffd, 0xfffd, 0x9810, 0xfffd, 0x99ad, 0x9d1b, 0x6df5, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f45, 0x5712, + 0x54e1, 0x5713, 0xfffd, 0xfffd, 0x7de3, 0x9060, 0xfffd, 0x9858, + 0xfffd, 0xfffd, 0xfffd, 0x7d04, 0xfffd, 0x8e8d, 0x9470, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x95b2, 0xfffd, 0x96f2, 0x9116, 0xfffd, + 0x9695, 0xfffd, 0x904b, 0x85f4, 0x9196, 0x6688, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x96dc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f09, + 0xfffd, 0xfffd, 0xfffd, 0x6522, 0x66ab, 0x8d0a, 0x8d1c, 0x81df, + 0xfffd, 0xfffd, 0xfffd, 0x947f, 0xfffd, 0x68d7, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7ac8, 0xfffd, 0x8cac, + 0x64c7, 0x5247, 0x6fa4, 0x8cca, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x8d08, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ecb, + /* 0x55 */ + 0x9358, 0x9598, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x8a50, 0xfffd, 0x9f4b, 0xfffd, 0xfffd, 0x50b5, 0xfffd, 0xfffd, + 0x6c08, 0xfffd, 0xfffd, 0xfffd, 0x76de, 0x65ac, 0x8f3e, 0x5d84, + 0xfffd, 0xfffd, 0x68e7, 0xfffd, 0x6230, 0xfffd, 0xfffd, 0x7dbb, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5f35, 0xfffd, 0x6f32, 0xfffd, + 0xfffd, 0x5e33, 0x8cec, 0xfffd, 0x8139, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x8d99, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x87c4, 0x8f4d, 0xfffd, 0x937a, + 0xfffd, 0x9019, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x8c9e, 0x91dd, 0x5075, 0xfffd, 0xfffd, 0x8a3a, 0xfffd, + 0xfffd, 0x93ae, 0x9663, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x56 */ + 0x5e40, 0x7665, 0x912d, 0x8b49, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7e54, 0x8077, + 0xfffd, 0xfffd, 0xfffd, 0x57f7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x8879, 0xfffd, 0x7d19, 0xfffd, 0x646f, 0x64f2, + 0xfffd, 0xfffd, 0xfffd, 0x5e5f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x8cea, 0xfffd, 0xfffd, 0x6eef, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x9418, 0xfffd, 0x7d42, 0x7a2e, 0x816b, 0xfffd, + 0xfffd, 0x8846, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8b05, 0xfffd, + 0x8ef8, 0xfffd, 0xfffd, 0xfffd, 0x76ba, 0xfffd, 0x665d, 0x9a5f, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8af8, 0x8a85, 0xfffd, + 0xfffd, 0x71ed, 0xfffd, 0xfffd, 0x77da, 0x56d1, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x8caf, 0x9444, 0x7bc9, + /* 0x57 */ + 0xfffd, 0xfffd, 0xfffd, 0x99d0, 0xfffd, 0xfffd, 0xfffd, 0x5c08, + 0x78da, 0x8f49, 0xfffd, 0x8cfa, 0xfffd, 0x6a01, 0x838a, 0x88dd, + 0x599d, 0xfffd, 0x58ef, 0x72c0, 0xfffd, 0x9310, 0xfffd, 0x8d05, + 0x589c, 0x7db4, 0x8ac4, 0x6e96, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6fc1, 0xfffd, + 0xfffd, 0x8cc7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6f2c, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x7d9c, 0x7e3d, 0x7e31, 0x9112, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a5b, 0xfffd, + 0x7d44, 0x947d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x58 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x55c7, 0xfffd, 0xfffd, 0x5399, 0xfffd, + 0x53b4, 0xfffd, 0xfffd, 0x9768, 0x8d0b, 0xfffd, 0xfffd, 0x532d, + 0x5331, 0xfffd, 0x8cfe, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x5244, 0xfffd, 0x528c, 0x5274, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x50b4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5000, 0x5096, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x59 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5115, 0xfffd, 0x5102, 0xfffd, + 0x5114, 0x513c, 0x5137, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x50e8, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x50c2, 0x513b, 0x5110, 0x513a, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x50c9, 0xfffd, 0xfffd, 0xfffd, + 0x7cf4, 0xfffd, 0xfffd, 0x9ecc, 0xfffd, 0x56c5, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x9cec, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x893b, 0x81e0, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x5a */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8a01, 0x8a10, 0x8a0c, 0x8a15, + 0x8b33, 0x8a4e, 0x8a25, 0x8a41, 0x8a36, 0x8a46, 0x8a54, 0x8a58, + 0x8a52, 0x8a86, 0x8a84, 0x8a7f, 0x8a70, 0x8a7c, 0x8a75, 0x8a6c, + 0x8a6e, 0x8acd, 0x8ae2, 0x8a61, 0x8a9a, 0x8aa5, 0x8a91, 0x8a92, + 0x8acf, 0x8ad1, 0x8ac9, 0x8adb, 0x8ad7, 0x8ac2, 0x8ab6, 0x8af6, + 0x8aeb, 0x8b14, 0x8b01, 0x8ae4, 0x8aed, 0x8afc, 0x8af3, 0x8ae6, + 0x8aee, 0x8ade, 0x8b28, 0x8b9c, 0x8b16, 0x8b1a, 0x8b10, 0x8b2b, + 0x8b2d, 0x8b56, 0x8b59, 0x8b4e, 0x8b9e, 0x8b6b, 0x8b96, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x9658, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x913a, 0xfffd, + 0x9114, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9134, + /* 0x5b */ + 0xfffd, 0xfffd, 0x90df, 0xfffd, 0xfffd, 0x9136, 0xfffd, 0xfffd, + 0x9106, 0x9148, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x82bb, 0xfffd, 0x52f1, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5df0, 0xfffd, + 0x580a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x58d9, 0xfffd, 0xfffd, 0x58e2, 0xfffd, 0xfffd, + 0xfffd, 0x58e0, 0xfffd, 0x58da, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x57e1, 0xfffd, 0xfffd, 0x584f, 0xfffd, 0xfffd, + 0x5816, 0xfffd, 0xfffd, 0xfffd, 0x5852, 0x581d, 0x5864, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x5c */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x858c, 0xfffd, 0xfffd, 0x8553, 0xfffd, + 0xfffd, 0x85f6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x83a7, + 0x8407, 0x84ef, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x82e7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8622, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8526, + 0xfffd, 0xfffd, 0x584b, 0x7162, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x8558, 0x84fd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x854e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8588, 0xfffd, 0xfffd, + 0x85ba, 0xfffd, 0xfffd, 0xfffd, 0x7296, 0x6ece, + /* 0x5d */ + 0x8541, 0xfffd, 0x85ce, 0x8552, 0x84c0, 0x8452, 0x8464, 0xfffd, + 0xfffd, 0x8494, 0x8435, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x859f, 0xfffd, 0xfffd, 0x8555, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x9daf, 0x8493, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x7e08, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x8546, 0xfffd, 0xfffd, 0x8562, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x851e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x9a40, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x863a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x93a3, 0x8577, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x861e, 0xfffd, 0x85fa, + /* 0x5e */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8604, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x85ea, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x861a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5969, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5c37, 0xfffd, + 0x636b, 0x6476, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x649f, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x6451, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x645c, + 0xfffd, 0xfffd, 0xfffd, 0x64b3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x6504, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x6516, 0xfffd, 0xfffd, + /* 0x5f */ + 0xfffd, 0x64f7, 0x64fc, 0xfffd, 0x651b, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x5630, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x5638, 0x56c8, 0xfffd, 0x56a6, 0xfffd, + 0xfffd, 0x5504, 0x54bc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x5680, 0xfffd, 0xfffd, 0xfffd, 0x565d, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5660, 0xfffd, 0xfffd, 0x5635, + 0x55f6, 0xfffd, 0xfffd, 0x5666, 0xfffd, 0xfffd, 0xfffd, 0x5672, + 0xfffd, 0x568c, 0xfffd, 0xfffd, 0xfffd, 0x5665, 0xfffd, 0xfffd, + 0x561c, 0xfffd, 0x562e, 0xfffd, 0xfffd, 0xfffd, 0x55e9, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5616, 0xfffd, 0xfffd, 0xfffd, + 0x56c0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x60 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x560d, 0x56b3, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x56c1, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x566f, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8f61, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x56b6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5695, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5707, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5e43, + 0xfffd, 0xfffd, 0xfffd, 0x5e6c, 0x5e58, 0x5e57, + /* 0x61 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x5d87, 0xfffd, 0x5cf4, 0xfffd, 0xfffd, 0x5d50, + 0xfffd, 0xfffd, 0xfffd, 0x5d2c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x5da7, 0xfffd, 0x5da0, 0xfffd, 0xfffd, 0x5d97, + 0x5d0d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x5db8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5d81, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x5dd4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x540e, 0x5fa0, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7377, 0x7341, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x736a, 0xfffd, 0x733b, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x736b, 0xfffd, + /* 0x62 */ + 0xfffd, 0xfffd, 0xfffd, 0x7380, 0xfffd, 0xfffd, 0xfffd, 0x737c, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x98e0, 0x9933, 0x98e9, 0x993c, 0x98ea, 0x98eb, + 0x98ed, 0x98f4, 0x9909, 0x9911, 0x4f59, 0x991b, 0x9937, 0x993f, + 0x9943, 0x9948, 0x9949, 0x994a, 0x994c, 0x9962, 0xfffd, 0x5ee1, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x8ce1, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x61fa, 0x61ae, 0xfffd, 0x616a, 0xfffd, 0xfffd, + 0x613e, 0x60b5, 0x6134, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x61cc, + 0xfffd, 0x615f, 0x61e8, 0x60fb, 0x6137, 0xfffd, + /* 0x63 */ + 0xfffd, 0x60f2, 0xfffd, 0xfffd, 0x6173, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x611c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x6192, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9582, 0x9586, 0x95c8, 0x958e, + 0x9594, 0x958c, 0x95e5, 0x95ad, 0x95ab, 0x9b2e, 0x95ac, 0x95be, + 0x95b6, 0x9b29, 0x95bf, 0x95bd, 0x95bc, 0x95c3, 0x95cb, 0x95d4, + 0x95d0, 0x95d5, 0x95de, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x7043, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6f59, 0xfffd, 0xfffd, 0xfffd, + 0x7027, 0x7018, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6ffc, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6d87, + /* 0x64 */ + 0xfffd, 0xfffd, 0xfffd, 0x6d79, 0x6e5e, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x6fae, 0xfffd, 0xfffd, 0xfffd, 0x700f, 0x6ef8, + 0x6f6f, 0xfffd, 0xfffd, 0xfffd, 0x6df6, 0x6f7f, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x7006, 0xfffd, 0xfffd, 0x6fa0, 0xfffd, 0xfffd, 0xfffd, + 0x700b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x7067, 0xfffd, 0xfffd, 0x7044, 0xfffd, 0x7005, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x6f77, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x7020, 0x701f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x7032, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7028, + /* 0x65 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x705d, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x9a2b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9087, 0xfffd, + 0x9015, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9090, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5c68, + 0xfffd, 0x5f33, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x5af5, 0x5ad7, 0xfffd, + /* 0x66 */ + 0xfffd, 0xfffd, 0x5b00, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x5a6d, 0x5b08, 0xfffd, 0x5b4c, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x5aa7, 0x5afb, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5b0b, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x5b21, + 0x5b2a, 0xfffd, 0xfffd, 0xfffd, 0x5b19, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x99d4, + 0x99df, 0x99d9, 0x9a36, 0x9a5b, 0x99d1, 0x99d8, 0x9a4d, 0x9a4a, + 0x99e2, 0x9a6a, 0x9a0f, 0x9a0d, 0x9a05, 0x9a42, 0x9a2d, 0x9a16, + 0x9a41, 0x9a2e, 0x9a38, 0x9a43, 0x9a44, 0x9a4f, 0x9a65, 0x9a64, + 0x7cf9, 0x7d06, 0x7d02, 0x7d07, 0x7d08, 0x7e8a, + /* 0x67 */ + 0x7d1c, 0x7d15, 0x7d13, 0x7d3a, 0x7d32, 0x7d31, 0x7e10, 0x7d3c, + 0x7d40, 0x7d3f, 0x7d5d, 0x7d4e, 0x7d73, 0x7d86, 0x7d83, 0x7d88, + 0x7dbe, 0x7dba, 0x7dcb, 0x7dd4, 0x7dc4, 0x7d9e, 0x7dac, 0x7db9, + 0x7da3, 0x7db0, 0x7dc7, 0x7dd9, 0x7dd7, 0x7df9, 0x7df2, 0x7e62, + 0x7de6, 0x7df6, 0x7df1, 0x7e0b, 0x7de1, 0x7e09, 0x7e1d, 0x7e1f, + 0x7e1e, 0x7e2d, 0x7e0a, 0x7e11, 0x7e7d, 0x7e39, 0x7e35, 0x7e32, + 0x7e46, 0x7e45, 0x7e88, 0x7e5a, 0x7e52, 0x7e6e, 0x7e7e, 0x7e70, + 0x7e6f, 0x7e98, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x74a3, 0x744b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x74cf, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x980a, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x74bd, 0x743f, 0x7489, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x68 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x74a6, + 0xfffd, 0xfffd, 0xfffd, 0x74d4, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x74da, 0xfffd, 0x97d9, + 0x97de, 0x97dc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x69aa, 0x6aea, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6898, 0xfffd, 0x68d6, 0x6a05, + 0x689f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6adb, 0xfffd, 0x6af3, + 0xfffd, 0xfffd, 0x6ae8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6adf, 0xfffd, 0x6a89, 0xfffd, + 0xfffd, 0x690f, 0x6a48, 0xfffd, 0x6968, 0xfffd, 0x69bf, 0xfffd, + 0xfffd, 0xfffd, 0x6a3a, 0xfffd, 0x6a9c, 0xfffd, 0x6b12, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x6b1e, 0xfffd, 0xfffd, 0x6add, 0x69e7, 0xfffd, + /* 0x69 */ + 0x6b0f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6b16, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x6aec, 0x6ada, 0xfffd, 0x6af8, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x6ab3, 0xfffd, 0x6ae7, 0xfffd, 0xfffd, + 0x6aa3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6ad3, 0xfffd, 0xfffd, + 0xfffd, 0x6ade, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x6ba4, 0xfffd, 0x6b9e, 0x6bae, 0xfffd, + 0x6bab, 0xfffd, 0x6baf, 0xfffd, 0x8ed4, 0x8edb, 0x8ef2, 0x8efb, + 0x8f64, 0x8ef9, 0x8efc, 0x8eeb, 0x8ee4, 0x8f62, 0x8efa, 0x8efe, + 0x8f0a, 0x8f07, 0x8f05, 0x8f12, 0x8f26, 0x8f1e, + /* 0x6a */ + 0x8f1f, 0x8f1c, 0x8f33, 0x8f46, 0x8f54, 0xfffd, 0x6214, 0x6227, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x750c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x66c7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x66c4, 0xfffd, 0xfffd, 0x6689, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x66d6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x8cc1, 0x8cb0, 0x8cba, 0x8cbd, 0x8d04, 0x8cb2, 0x8cc5, + 0x8d10, 0x8cd1, 0x8cda, 0x8cd5, 0x8ceb, 0x8ce7, 0x8cfb, 0x8998, + 0x89ac, 0x89a1, 0x89bf, 0x89a6, 0x89af, 0x89b2, 0x89b7, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x6b */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6bff, 0xfffd, + 0xfffd, 0x6c0c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x6c2c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x7258, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x6727, 0x8156, 0xfffd, 0x81da, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x811b, 0xfffd, 0xfffd, + 0xfffd, 0x81be, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x8161, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x81cf, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x6c */ + 0xfffd, 0xfffd, 0x6b5f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x98ae, 0x98af, 0x98b6, 0x98bc, 0x98c6, 0x98c8, 0xfffd, 0xfffd, + 0x8f42, 0xfffd, 0xfffd, 0x9f4f, 0x6595, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x716c, 0x7152, 0xfffd, + 0x7197, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x71c1, 0xfffd, + 0xfffd, 0xfffd, 0x71dc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x71fe, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x79b0, 0xfffd, 0xfffd, 0x798e, 0xfffd, 0xfffd, 0x79aa, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x6d */ + 0x61df, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x6164, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x61e3, 0x6207, + 0xfffd, 0xfffd, 0xfffd, 0x6fa9, 0xfffd, 0x78ef, 0xfffd, 0x78ad, + 0xfffd, 0x7868, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x78b8, 0xfffd, + 0xfffd, 0x792a, 0x7931, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x7864, 0x78fd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x78e7, 0xfffd, 0xfffd, 0xfffd, 0x78e3, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9f95, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7798, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x775e, 0x77bc, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x6e */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x7f86, 0xfffd, 0xfffd, 0x7f88, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x91d2, 0x91d3, 0x91d4, 0x91d9, 0x91d7, + 0x91d5, 0x91f7, 0x91e7, 0x91e4, 0x9346, 0x91f5, 0x91f9, 0x9208, + 0x9226, 0x9245, 0x9211, 0x9210, 0x9201, 0x9227, 0x9204, 0x9225, + 0x9200, 0x923a, 0x9266, 0x9237, 0x9233, 0x9255, 0x923d, 0x9238, + 0x925e, 0x926c, 0x926d, 0x923f, 0x9460, 0x9230, 0x9249, 0x9248, + 0x924d, 0x922e, 0x9239, 0x9438, 0x92ac, 0x92a0, 0x927a, 0x92aa, + 0x92ee, 0x92cf, 0x9403, 0x92e3, 0x943a, 0x92b1, 0x92a6, 0x93a7, + 0x9296, 0x92cc, 0x92a9, 0x93f5, 0x9293, 0x927f, + /* 0x6f */ + 0x93a9, 0x929a, 0x931a, 0x92ab, 0x9283, 0x940b, 0x92a8, 0x92a3, + 0x9412, 0x9338, 0x92f1, 0x93d7, 0x92e5, 0x92f0, 0x92ef, 0x92e8, + 0x92bc, 0x92dd, 0x92f6, 0x9426, 0x9427, 0x92c3, 0x92df, 0x92e6, + 0x9312, 0x9306, 0x9369, 0x931b, 0x9340, 0x9301, 0x9315, 0x932e, + 0x9343, 0x9307, 0x9308, 0x931f, 0x9319, 0x9365, 0x9347, 0x9376, + 0x9354, 0x9364, 0x93aa, 0x9370, 0x9384, 0x93e4, 0x93d8, 0x9428, + 0x9387, 0x93cc, 0x9398, 0x93b8, 0x93bf, 0x93a6, 0x93b0, 0x93b5, + 0x944c, 0x93e2, 0x93dc, 0x93dd, 0x93cd, 0x93de, 0x93c3, 0x93c7, + 0x93d1, 0x9414, 0x941d, 0x93f7, 0x9465, 0x9413, 0x946d, 0x9420, + 0x9479, 0x93f9, 0x9419, 0x944a, 0x9432, 0x943f, 0x9454, 0x9463, + 0x937e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x70 */ + 0xfffd, 0xfffd, 0x7a61, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9ce9, 0x9cf6, + 0x9d07, 0x9d06, 0x9d23, 0x9d87, 0x9e15, 0x9d1d, 0x9d1f, 0x9de5, + 0x9d2f, 0x9dd9, 0x9d30, 0x9d42, 0x9e1e, 0x9d53, 0x9e1d, 0x9d60, + 0x9d52, 0x9df3, 0x9d5c, 0x9d61, 0x9d93, 0x9d6a, 0x9d6f, 0x9d89, + 0x9d98, 0x9d9a, 0x9dc0, 0x9da5, 0x9da9, 0x9dc2, 0x9dbc, 0x9e1a, + 0x9dd3, 0x9dda, 0x9def, 0x9de6, 0x9df2, 0x9df8, 0x9e0c, 0x9dfa, + 0x9e1b, 0xfffd, 0xfffd, 0x7664, 0x7658, 0xfffd, 0x7667, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x7602, 0xfffd, 0xfffd, 0x7646, 0xfffd, 0xfffd, 0x7647, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7649, 0xfffd, + 0x761e, 0xfffd, 0xfffd, 0x763b, 0xfffd, 0xfffd, + /* 0x71 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x766d, + 0xfffd, 0xfffd, 0x766e, 0xfffd, 0xfffd, 0x7669, 0xfffd, 0xfffd, + 0xfffd, 0x7672, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x7ac7, 0xfffd, 0xfffd, 0xfffd, 0x7ab6, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x8960, 0xfffd, 0xfffd, 0xfffd, 0x8933, 0xfffd, 0x895d, 0x8947, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x8938, 0xfffd, 0x8964, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x76b8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x802e, 0xfffd, 0xfffd, 0x802c, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8079, 0xfffd, + 0x8075, 0xfffd, 0xfffd, 0x9807, 0x980e, 0x980f, + /* 0x72 */ + 0x9821, 0x981c, 0x6f41, 0x9826, 0x9837, 0x984e, 0x9853, 0x9873, + 0x9862, 0x9859, 0x9865, 0x986c, 0x9870, 0xfffd, 0xfffd, 0xfffd, + 0x87e3, 0x8806, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x8706, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x8823, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x87f6, 0xfffd, 0xfffd, 0x86fa, 0x87ef, 0xfffd, 0x8784, 0xfffd, + 0xfffd, 0xfffd, 0x8810, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x87c8, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8811, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x87bb, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x87ce, 0xfffd, + /* 0x73 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7f4c, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7be4, 0xfffd, 0x7b67, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7c69, 0xfffd, 0xfffd, + 0x7bf3, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7c00, 0x7bcb, 0xfffd, 0xfffd, + 0xfffd, 0x7c5c, 0xfffd, 0x7c1e, 0xfffd, 0xfffd, 0x7c2b, 0xfffd, + 0x7c23, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7c6a, 0xfffd, + /* 0x74 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7c5f, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8264, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x826b, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x88ca, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7fa5, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7cf2, 0x7cf6, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x7cdd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x7e36, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9ea9, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8db2, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x75 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x91c5, 0x91c3, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x9e7a, 0x8e89, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x8e4c, 0xfffd, 0xfffd, 0xfffd, 0x8e92, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8e7a, 0x8e55, 0xfffd, + 0x8e9a, 0x8e8b, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x8e93, 0xfffd, 0xfffd, 0x8e91, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8ea1, 0x8e63, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8eaa, 0xfffd, + 0xfffd, 0x8ea6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x89f4, 0xfffd, 0xfffd, + /* 0x76 */ + 0xfffd, 0xfffd, 0x89f6, 0xfffd, 0xfffd, 0x975a, 0xfffd, 0x9742, + 0xfffd, 0xfffd, 0x973d, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9744, + 0xfffd, 0xfffd, 0x9f54, 0x9f5f, 0x9f59, 0x9f60, 0x9f5c, 0x9f66, + 0x9f6c, 0x9f6a, 0x9f77, 0x9efd, 0x9eff, 0x9f09, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x8b8e, 0xfffd, 0x947e, 0xfffd, + 0x93e8, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9b77, 0x9b74, + 0x9b81, 0x9b83, 0x9b8e, 0x9c78, 0x7a4c, 0x9b92, 0x9c5f, 0x9b90, + 0x9bad, 0x9b9a, 0x9baa, 0x9b9e, 0x9c6d, 0x9bab, 0x9b9d, 0x9c58, + 0x9bc1, 0x9c7a, 0x9c31, 0x9c39, 0x9c23, 0x9c37, 0x9bc0, 0x9bca, + 0x9bc7, 0x9bfd, 0x9bd6, 0x9bea, 0x9beb, 0x9be1, 0x9be4, 0x9be7, + 0x9bdd, 0x9be2, 0x9bf0, 0x9bdb, 0x9bf4, 0x9bd4, 0x9c5d, 0x9c08, + 0x9c10, 0x9c0d, 0x9c12, 0x9c09, 0x9bff, 0x9c20, + /* 0x77 */ + 0x9c32, 0x9c2d, 0x9c28, 0x9c25, 0x9c29, 0x9c33, 0x9c3e, 0x9c48, + 0x9c3b, 0x9c35, 0x9c45, 0x9c56, 0x9c54, 0x9c52, 0x9c67, 0xfffd, + 0xfffd, 0x97c3, 0x97bd, 0xfffd, 0x97c9, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9dbb, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x9acf, 0xfffd, 0x9ad6, 0x9ad5, 0xfffd, 0xfffd, + 0xfffd, 0x9b58, 0x9b4e, 0xfffd, 0xfffd, 0xfffd, 0x9957, 0x995c, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x9b22, 0xfffd, 0xfffd, + 0x4e48, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x9ef7, 0xfffd, 0xfffd, 0x9ef2, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x78 */ + 0x896c, 0x95c6, 0x9336, 0x5f46, 0x8514, 0x7e94, 0x5382, 0x51b2, + 0x4e11, 0x9f63, 0x5679, 0x515a, 0x6dc0, 0x9f15, 0x6597, 0x5641, + 0x9aee, 0x8303, 0x4e30, 0x8907, 0x5e72, 0x7a40, 0x98b3, 0x5e7f, + 0x95a4, 0x9b0d, 0x5212, 0x8ff4, 0x5f59, 0x7a6b, 0x98e2, 0x51e0, + 0x50a2, 0x4ef7, 0x8350, 0x8591, 0x5118, 0x636e, 0x6372, 0x524b, + 0x5938, 0x774f, 0x8721, 0x814a, 0x7e8d, 0x91cc, 0x66c6, 0x5e18, + 0x77ad, 0x9e75, 0x56c9, 0x9ef4, 0x6fdb, 0x61de, 0x77c7, 0x7030, + 0x9eb5, 0x884a, 0x95e2, 0x82f9, 0x51ed, 0x6251, 0x4ec6, 0x6734, + 0x97c6, 0x7c64, 0x7e34, 0x97a6, 0x9eaf, 0x786e, 0x820d, 0x672f, + 0x677e, 0x56cc, 0x53f0, 0x98b1, 0x6aaf, 0x7f4e, 0x6d82, 0x7cf0, + 0x4e07, 0x4fc2, 0x7e6b, 0x9e79, 0x56ae, 0x9b1a, 0x846f, 0x53f6, + 0x90c1, 0x79a6, 0x7c72, 0x613f, 0x4e91, 0x9ad2, + /* 0x79 */ + 0x75c7, 0x96bb, 0x53ea, 0x7dfb, 0x88fd, 0x79cd, 0x7843, 0x7b51, + 0x51c6, +}; + +static int +gb12345ext_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 == 0x21) || (c1 == 0x26) || (c1 == 0x28) || (c1 >= 0x30 && c1 <= 0x79)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + unsigned short wc = 0xfffd; + if (i < 470) { + if (i < 12) + wc = gb12345ext_2uni_page21[i]; + } else if (i < 658) { + if (i < 555) + wc = gb12345ext_2uni_page26[i-470]; + } else if (i < 1410) { + if (i < 690) + wc = gb12345ext_2uni_page28[i-658]; + } else { + if (i < 8281) + wc = gb12345ext_2uni_page30[i-1410]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short gb12345ext_2charset[2252] = { + 0x283d, 0x283e, 0x283f, 0x283b, 0x2840, 0x283c, 0x212c, 0x7871, + 0x7829, 0x7833, 0x7761, 0x4252, 0x787d, 0x5147, 0x785f, 0x7842, + 0x6245, 0x4034, 0x4258, 0x7872, 0x4f40, 0x5876, 0x4129, 0x3256, + 0x3876, 0x4347, 0x4257, 0x4e30, 0x3260, 0x556c, 0x5877, 0x4921, + 0x3138, 0x7841, 0x5336, 0x342b, 0x5871, 0x552e, 0x494b, 0x4763, + 0x594d, 0x3d76, 0x595d, 0x4748, 0x464d, 0x4e31, 0x3d44, 0x5947, + 0x3c5b, 0x5247, 0x592f, 0x525a, 0x3f6b, 0x3c73, 0x594f, 0x5931, + 0x592d, 0x7845, 0x3325, 0x5345, 0x3422, 0x5933, 0x5950, 0x594e, + 0x5932, 0x3679, 0x782c, 0x413d, 0x7828, 0x7929, 0x3633, 0x7840, + 0x785d, 0x3f2d, 0x783b, 0x5859, 0x5472, 0x7848, 0x3855, 0x3950, + 0x585c, 0x3434, 0x3b2e, 0x3e67, 0x4175, 0x3974, 0x585b, 0x3d23, + 0x3c41, 0x3e22, 0x362f, 0x4e71, 0x512b, 0x4a24, 0x404d, 0x4a46, + 0x5b3d, 0x4078, 0x4830, 0x5850, 0x3b63, 0x5851, 0x4778, 0x502d, + 0x7827, 0x5847, 0x325e, 0x5161, 0x4077, 0x5849, 0x324e, 0x3454, + 0x7923, 0x786b, 0x7878, 0x6161, 0x5f43, 0x5431, 0x5f42, 0x4e4a, + 0x4674, 0x5146, 0x4925, 0x4747, 0x3525, 0x5334, 0x473a, 0x5844, + 0x4270, 0x4e58, 0x5f6f, 0x5f59, 0x4c3e, 0x6036, 0x453b, 0x5f75, + 0x3322, 0x5f69, 0x3b29, 0x5f6b, 0x5025, 0x5f34, 0x5f58, 0x5f3c, + 0x7830, 0x5f50, 0x5f55, 0x5f66, 0x5f5c, 0x6048, 0x5f60, 0x4567, + 0x3656, 0x782b, 0x5f4c, 0x4f45, 0x5f62, 0x6060, 0x4476, 0x5f3f, + 0x417c, 0x7875, 0x6037, 0x514f, 0x6053, 0x5f79, 0x603f, 0x4f79, + 0x5966, 0x5f3d, 0x7853, 0x786a, 0x5676, 0x6070, 0x397a, 0x4e27, + 0x5430, 0x5432, 0x4d3c, 0x4d45, 0x5b6b, 0x5634, 0x3c61, 0x5b51, + 0x5b71, 0x5b76, 0x5222, 0x3128, 0x3321, 0x3f69, 0x5c63, 0x5b6e, + 0x5b75, 0x4d3f, 0x4e6b, 0x5b77, 0x333e, 0x4735, 0x3566, 0x5739, + 0x3669, 0x3758, 0x473d, 0x3f51, 0x4c33, 0x5139, 0x405d, 0x5b5b, + 0x5b64, 0x3b35, 0x4222, 0x5b62, 0x5b5e, 0x3053, 0x5733, 0x3a78, + 0x4a59, 0x434e, 0x7849, 0x3c50, 0x5e46, 0x3661, 0x3d31, 0x375c, + 0x5731, 0x4226, 0x383e, 0x662b, 0x6634, 0x4268, 0x657d, 0x657c, + 0x6635, 0x6623, 0x662c, 0x663f, 0x3d3f, 0x664d, 0x6648, 0x6649, + 0x5324, 0x4974, 0x662e, 0x4b6f, 0x5127, 0x424f, 0x475e, 0x4a35, + 0x447e, 0x4973, 0x5034, 0x3f6d, 0x3368, 0x3126, 0x3d2b, 0x5728, + 0x5130, 0x3654, 0x353c, 0x5e4f, 0x4245, 0x3263, 0x6570, 0x4a74, + 0x3854, 0x612d, 0x353a, 0x4f3f, 0x6141, 0x385a, 0x6134, 0x6130, + 0x6150, 0x5538, 0x612b, 0x6140, 0x613d, 0x613b, 0x6149, 0x416b, + 0x536c, 0x3f79, 0x424d, 0x615b, 0x5b4f, 0x7850, 0x4b27, 0x4a26, + 0x554a, 0x3478, 0x5621, 0x6078, 0x607e, 0x607d, 0x5644, 0x3152, + 0x306f, 0x607c, 0x7835, 0x3849, 0x3c38, 0x7838, 0x3f62, 0x436d, + 0x3327, 0x6250, 0x374f, 0x3963, 0x422e, 0x4c7c, 0x6572, 0x5545, + 0x7824, 0x352f, 0x4356, 0x4d64, 0x783d, 0x3a73, 0x3e36, 0x3453, + 0x6162, 0x3834, 0x3339, 0x626a, 0x4346, 0x3671, 0x4455, 0x6322, + 0x627c, 0x302e, 0x632b, 0x626b, 0x627d, 0x6269, 0x787c, 0x4c2c, + 0x3252, 0x3251, 0x627a, 0x395f, 0x6d28, 0x6266, 0x4b4b, 0x4247, + 0x6325, 0x476c, 0x5347, 0x3139, 0x412f, 0x463e, 0x6334, 0x352c, + 0x375f, 0x4375, 0x6264, 0x4f5c, 0x5264, 0x3f52, 0x5326, 0x6278, + 0x7856, 0x6d21, 0x6d2f, 0x627b, 0x334d, 0x4041, 0x3b33, 0x507c, + 0x6263, 0x3e65, 0x4965, 0x4135, 0x6d30, 0x6a27, 0x6a28, 0x553d, + 0x4f37, 0x785e, 0x502e, 0x4961, 0x5e51, 0x7846, 0x7847, 0x4928, + 0x4255, 0x3c70, 0x516f, 0x3b53, 0x4b70, 0x3537, 0x4740, 0x5e62, + 0x5e68, 0x4227, 0x563f, 0x3f59, 0x5e52, 0x3274, 0x404c, 0x4453, + 0x5e58, 0x3527, 0x3226, 0x3827, 0x464b, 0x5e6c, 0x4c22, 0x4e4e, + 0x3c71, 0x5335, 0x4230, 0x5471, 0x3b77, 0x3532, 0x3523, 0x3e5d, + 0x3c37, 0x4462, 0x3177, 0x4521, 0x3869, 0x5640, 0x4029, 0x5f22, + 0x305a, 0x4b53, 0x5f23, 0x4845, 0x5e73, 0x446c, 0x4223, 0x4039, + 0x5e7c, 0x3273, 0x5f25, 0x4963, 0x545c, 0x424e, 0x4c2f, 0x3d41, + 0x403f, 0x305c, 0x3550, 0x4a7d, 0x4132, 0x3150, 0x6c35, 0x782f, + 0x5536, 0x364f, 0x4a31, 0x5667, 0x544e, 0x6a4d, 0x3329, 0x545d, + 0x6a4a, 0x784f, 0x6a3c, 0x4f7e, 0x6a53, 0x3f75, 0x4939, 0x4a69, + 0x3b61, 0x6b4a, 0x7868, 0x7860, 0x362b, 0x7869, 0x6845, 0x4c75, + 0x6849, 0x6847, 0x5466, 0x3630, 0x553b, 0x6862, 0x516e, 0x3763, + 0x6865, 0x5235, 0x3c2b, 0x683f, 0x4859, 0x6867, 0x3939, 0x4739, + 0x687d, 0x3d30, 0x572e, 0x4056, 0x6848, 0x4225, 0x316a, 0x4a60, + 0x5179, 0x4653, 0x4a77, 0x686b, 0x6863, 0x4745, 0x3b7a, 0x4d56, + 0x685f, 0x3535, 0x686d, 0x3c6c, 0x6949, 0x786d, 0x6944, 0x447b, + 0x3c77, 0x3971, 0x6956, 0x6935, 0x684e, 0x687c, 0x695a, 0x685d, + 0x6946, 0x6853, 0x6840, 0x6934, 0x6850, 0x6937, 0x5323, 0x4038, + 0x4828, 0x6921, 0x686f, 0x692d, 0x6879, 0x4755, 0x4537, 0x6c23, + 0x3b36, 0x4b6a, 0x407a, 0x3969, 0x3250, 0x6966, 0x6964, 0x6969, + 0x6967, 0x696b, 0x3c5f, 0x4931, 0x3f47, 0x4539, 0x6b27, 0x5531, + 0x6b2a, 0x4678, 0x4762, 0x6b32, 0x6424, 0x786f, 0x637e, 0x782d, + 0x4259, 0x5428, 0x6435, 0x4733, 0x4e50, 0x3262, 0x3b6b, 0x6425, + 0x4c40, 0x573c, 0x3935, 0x3257, 0x4370, 0x3553, 0x5c7e, 0x3b26, + 0x564d, 0x4978, 0x4231, 0x6430, 0x427a, 0x5366, 0x453d, 0x3a3a, + 0x4130, 0x5755, 0x5547, 0x3d25, 0x3d2c, 0x7223, 0x4643, 0x3d60, + 0x636d, 0x4873, 0x6431, 0x4023, 0x6464, 0x6436, 0x492c, 0x3d3d, + 0x4054, 0x3d27, 0x6445, 0x5473, 0x6d34, 0x642b, 0x356d, 0x5747, + 0x4528, 0x4a2a, 0x4522, 0x7855, 0x3c43, 0x4c4e, 0x4044, 0x4e2b, + 0x3175, 0x3d26, 0x6378, 0x424b, 0x645e, 0x6442, 0x503a, 0x6449, + 0x642f, 0x3174, 0x6372, 0x4124, 0x646c, 0x646b, 0x6371, 0x647e, + 0x7858, 0x6472, 0x403d, 0x6363, 0x645c, 0x4877, 0x406c, 0x4c32, + 0x6530, 0x4d65, 0x4250, 0x6459, 0x4e5a, 0x4c7e, 0x4e5e, 0x4136, + 0x6c3f, 0x5c64, 0x3733, 0x6c3e, 0x532b, 0x6c41, 0x4848, 0x3363, + 0x6c47, 0x3546, 0x4955, 0x4c4c, 0x6c4b, 0x532a, 0x3253, 0x5672, + 0x3b62, 0x3d7d, 0x6c62, 0x4b38, 0x422f, 0x4043, 0x4e2a, 0x522f, + 0x367b, 0x6b39, 0x4723, 0x5c7d, 0x363f, 0x4e7e, 0x5734, 0x4f41, + 0x3137, 0x534c, 0x6178, 0x616f, 0x537c, 0x4a28, 0x3640, 0x6176, + 0x617d, 0x447c, 0x3b71, 0x4154, 0x616e, 0x4a5e, 0x4c21, 0x4f57, + 0x6228, 0x6224, 0x4f56, 0x6775, 0x6762, 0x4b76, 0x5328, 0x426a, + 0x6776, 0x6761, 0x6828, 0x3b37, 0x6774, 0x476d, 0x6767, 0x682c, + 0x6836, 0x6a31, 0x327a, 0x4436, 0x314f, 0x3b2d, 0x3531, 0x336b, + 0x7921, 0x3e37, 0x7069, 0x3768, 0x5171, 0x7079, 0x342f, 0x4531, + 0x707c, 0x4146, 0x706c, 0x706f, 0x7077, 0x705d, 0x3171, 0x5177, + 0x705c, 0x5622, 0x705f, 0x712e, 0x5122, 0x7128, 0x712b, 0x5338, + 0x4c31, 0x7132, 0x3722, 0x3028, 0x7164, 0x5665, 0x5535, 0x3e21, + 0x3c60, 0x454c, 0x422c, 0x784a, 0x6d79, 0x6d6e, 0x4277, 0x7851, + 0x6d7a, 0x7857, 0x5675, 0x3d43, 0x7927, 0x6d4c, 0x6d3a, 0x7866, + 0x5162, 0x4b36, 0x6d38, 0x6d3f, 0x4837, 0x426b, 0x5729, 0x6d57, + 0x6d53, 0x6d36, 0x6d4d, 0x3421, 0x302d, 0x3f73, 0x6d42, 0x4079, + 0x372f, 0x6d43, 0x3b76, 0x6c75, 0x787a, 0x6c78, 0x4071, 0x6c72, + 0x353b, 0x7926, 0x5656, 0x3346, 0x7836, 0x7655, 0x3b7d, 0x5331, + 0x7023, 0x3b60, 0x4e48, 0x783e, 0x4e51, 0x4d5d, 0x476e, 0x7140, + 0x3f7a, 0x345c, 0x474f, 0x713c, 0x546e, 0x4754, 0x4a7a, 0x3e3a, + 0x314a, 0x7928, 0x7348, 0x3c63, 0x3d5a, 0x3736, 0x567e, 0x7366, + 0x7346, 0x4938, 0x7359, 0x7365, 0x4228, 0x736c, 0x3c72, 0x7371, + 0x736f, 0x4729, 0x4131, 0x403a, 0x336f, 0x736a, 0x7425, 0x417d, + 0x7862, 0x7356, 0x737d, 0x4069, 0x4261, 0x787b, 0x7456, 0x3760, + 0x4138, 0x7870, 0x744f, 0x5961, 0x7450, 0x6679, 0x3e40, 0x3c4d, + 0x667b, 0x543c, 0x3a6c, 0x667a, 0x667c, 0x667d, 0x4852, 0x4e46, + 0x4449, 0x4526, 0x6723, 0x343f, 0x6722, 0x4934, 0x563d, 0x3c36, + 0x3757, 0x6721, 0x3744, 0x4f38, 0x6726, 0x6725, 0x4970, 0x495c, + 0x6724, 0x6728, 0x672a, 0x6729, 0x5655, 0x5769, 0x306d, 0x672c, + 0x3d61, 0x672b, 0x3d4a, 0x4267, 0x5124, 0x3878, 0x485e, 0x4d33, + 0x4b3f, 0x672d, 0x3e78, 0x3e6e, 0x3073, 0x672f, 0x672e, 0x6730, + 0x5065, 0x4b67, 0x3e2d, 0x575b, 0x6736, 0x3371, 0x6739, 0x4f5f, + 0x6737, 0x4e2c, 0x673a, 0x3859, 0x4d78, 0x3141, 0x573a, 0x425a, + 0x6738, 0x6732, 0x5540, 0x3442, 0x6731, 0x4360, 0x6735, 0x673b, + 0x3d74, 0x6733, 0x424c, 0x5077, 0x6734, 0x673d, 0x3c6a, 0x673c, + 0x3c29, 0x3650, 0x355e, 0x6745, 0x5435, 0x6741, 0x3160, 0x3b3a, + 0x4365, 0x4e33, 0x6743, 0x673f, 0x4137, 0x6742, 0x673e, 0x7924, + 0x5d53, 0x6746, 0x674b, 0x6744, 0x6727, 0x674c, 0x383f, 0x6747, + 0x6749, 0x6748, 0x4f58, 0x4c50, 0x376c, 0x674a, 0x4b75, 0x575d, + 0x6750, 0x7863, 0x674f, 0x746a, 0x4246, 0x674e, 0x575c, 0x3c28, + 0x6752, 0x6751, 0x6755, 0x562f, 0x4949, 0x6754, 0x4846, 0x6740, + 0x497e, 0x3b66, 0x7873, 0x3c6b, 0x6756, 0x6759, 0x6758, 0x3d49, + 0x526f, 0x3c4c, 0x674d, 0x6757, 0x6753, 0x667e, 0x5078, 0x784d, + 0x3278, 0x5327, 0x7826, 0x4f4b, 0x675a, 0x4042, 0x733f, 0x786e, + 0x3723, 0x3055, 0x425e, 0x6e3c, 0x6e3f, 0x7447, 0x5265, 0x4f30, + 0x474c, 0x716f, 0x716c, 0x4a25, 0x4e45, 0x412a, 0x344f, 0x4979, + 0x4b4a, 0x7179, 0x4474, 0x5630, 0x7177, 0x4c7d, 0x417b, 0x4b60, + 0x5032, 0x6b56, 0x554d, 0x784c, 0x4976, 0x6b4b, 0x6b61, 0x4454, + 0x5657, 0x3326, 0x3774, 0x3d3a, 0x4465, 0x3528, 0x6b5a, 0x4527, + 0x4133, 0x466a, 0x6b77, 0x4030, 0x6b4d, 0x5460, 0x5975, 0x4159, + 0x4c28, 0x536b, 0x504b, 0x3e59, 0x3e49, 0x7867, 0x3255, 0x742f, + 0x3d22, 0x7435, 0x3c68, 0x515e, 0x5b3b, 0x5c51, 0x785c, 0x7832, + 0x7843, 0x572f, 0x3e25, 0x3c54, 0x5c48, 0x3b2a, 0x5c49, 0x4033, + 0x4d72, 0x5d2b, 0x5236, 0x5d26, 0x5d27, 0x4e2d, 0x7877, 0x3b67, + 0x5d3b, 0x5d2a, 0x3254, 0x5d25, 0x3847, 0x412b, 0x5c4a, 0x5c6a, + 0x7825, 0x5d64, 0x3d2f, 0x5c60, 0x5271, 0x5d21, 0x5d5b, 0x5c71, + 0x5d24, 0x5c3f, 0x5d35, 0x5c69, 0x5d5e, 0x3534, 0x4e5f, 0x4f74, + 0x5d77, 0x5c76, 0x3c3b, 0x5c3c, 0x7844, 0x473e, 0x5d32, 0x3c76, + 0x4878, 0x5c79, 0x4036, 0x5d23, 0x5255, 0x5229, 0x5e34, 0x544c, + 0x5c42, 0x302a, 0x5d7e, 0x5e2d, 0x422b, 0x4b55, 0x463b, 0x5e3a, + 0x5d7c, 0x5c57, 0x403c, 0x5d71, 0x425c, 0x3426, 0x4232, 0x3a45, + 0x3f77, 0x724c, 0x7239, 0x784b, 0x4a34, 0x4f3a, 0x4e4f, 0x724f, + 0x426c, 0x5329, 0x7277, 0x555d, 0x7265, 0x727d, 0x7231, 0x3275, + 0x724d, 0x3366, 0x7249, 0x524f, 0x532c, 0x7232, 0x7253, 0x726e, + 0x402f, 0x7243, 0x3946, 0x324f, 0x4279, 0x565a, 0x785a, 0x4a75, + 0x4e40, 0x3365, 0x563b, 0x7441, 0x406f, 0x3239, 0x5730, 0x7925, + 0x7834, 0x3f63, 0x714d, 0x715a, 0x5974, 0x7150, 0x3040, 0x714f, + 0x7149, 0x715c, 0x4d60, 0x7821, 0x3344, 0x4f2e, 0x3c7b, 0x3966, + 0x4359, 0x4a53, 0x6a68, 0x6a6a, 0x6a6c, 0x4757, 0x6a69, 0x6a6d, + 0x6a6e, 0x6a6f, 0x3e75, 0x4040, 0x6a6b, 0x395b, 0x757c, 0x7623, + 0x3425, 0x5a25, 0x3629, 0x383c, 0x3c46, 0x5136, 0x5a27, 0x4c56, + 0x5a26, 0x5135, 0x5a28, 0x467d, 0x3c47, 0x366f, 0x5148, 0x4b4f, + 0x3e77, 0x5a2b, 0x3743, 0x4968, 0x506d, 0x4b5f, 0x5a2d, 0x556f, + 0x5a2c, 0x5a2e, 0x5a2a, 0x5529, 0x5a31, 0x5a2f, 0x4640, 0x5a30, + 0x5767, 0x344a, 0x5a3c, 0x512f, 0x5268, 0x4a54, 0x4a2b, 0x326f, + 0x5a38, 0x396e, 0x5a39, 0x5a35, 0x3b30, 0x3843, 0x4f6a, 0x5a37, + 0x5a36, 0x5a34, 0x5a33, 0x566f, 0x5a32, 0x3f64, 0x484f, 0x5a3f, + 0x5a40, 0x352e, 0x5355, 0x5a3d, 0x536f, 0x334f, 0x3d6b, 0x4e5c, + 0x4e73, 0x5a3e, 0x4b50, 0x3b65, 0x4b35, 0x4b2d, 0x3f4e, 0x5a47, + 0x374c, 0x526a, 0x3577, 0x5a46, 0x573b, 0x4c38, 0x5a43, 0x476b, + 0x5a3a, 0x5a41, 0x5a42, 0x4142, 0x425b, 0x5a45, 0x5a44, 0x357d, + 0x5a52, 0x5a3b, 0x5a4c, 0x5a50, 0x5033, 0x5a49, 0x5a4d, 0x5a51, + 0x3b64, 0x5a4f, 0x5a48, 0x376d, 0x566e, 0x5168, 0x5a4e, 0x4535, + 0x4431, 0x5a4b, 0x4e3d, 0x4c5c, 0x565f, 0x3b51, 0x4355, 0x5a57, + 0x5a4a, 0x5a55, 0x3079, 0x472b, 0x5a56, 0x3d32, 0x503b, 0x5225, + 0x5a53, 0x5a58, 0x437d, 0x5a59, 0x5a29, 0x3d77, 0x4321, 0x5624, + 0x5a5c, 0x3c25, 0x5a5a, 0x4a36, 0x5a5b, 0x4c37, 0x4657, 0x5a5e, + 0x526b, 0x5269, 0x4734, 0x3b24, 0x537e, 0x3641, 0x3164, 0x7645, + 0x3277, 0x4843, 0x403e, 0x5a5f, 0x5a54, 0x5a5d, 0x4671, 0x3761, + 0x3134, 0x556a, 0x383a, 0x3246, 0x3931, 0x4636, 0x3b75, 0x3737, + 0x4c30, 0x3961, 0x5470, 0x567c, 0x6a5b, 0x6a5f, 0x3721, 0x3973, + 0x3161, 0x4272, 0x347b, 0x6a5c, 0x3751, 0x4c79, 0x6a5d, 0x4333, + 0x3a58, 0x6a5a, 0x4238, 0x415e, 0x3b5f, 0x6a60, 0x574a, 0x3c56, + 0x5474, 0x6a62, 0x495e, 0x3176, 0x6a64, 0x6a63, 0x344d, 0x494d, + 0x4562, 0x6259, 0x4f4d, 0x4274, 0x3c7a, 0x3833, 0x6a66, 0x564a, + 0x6a65, 0x554b, 0x3644, 0x4035, 0x572c, 0x6a67, 0x393a, 0x487c, + 0x5853, 0x6a5e, 0x5738, 0x5479, 0x545e, 0x584d, 0x4944, 0x532e, + 0x6a61, 0x4a6a, 0x3853, 0x545f, 0x384f, 0x5554, 0x4777, 0x7475, + 0x3c79, 0x533b, 0x7544, 0x754f, 0x7567, 0x754e, 0x753b, 0x336c, + 0x7552, 0x543e, 0x755c, 0x7548, 0x7559, 0x7551, 0x7566, 0x345a, + 0x7572, 0x756f, 0x477b, 0x3335, 0x547e, 0x396c, 0x3e7c, 0x5079, + 0x696d, 0x696e, 0x486d, 0x6975, 0x6974, 0x696f, 0x5661, 0x6972, + 0x6977, 0x6970, 0x6973, 0x6978, 0x3d4f, 0x697b, 0x697a, 0x5458, + 0x6979, 0x697c, 0x3828, 0x4761, 0x413e, 0x6a22, 0x3b54, 0x697e, + 0x6a21, 0x3975, 0x697d, 0x3132, 0x4256, 0x3c2d, 0x6a23, 0x4a64, + 0x3778, 0x5537, 0x535f, 0x6c31, 0x4f3d, 0x542f, 0x6a24, 0x572a, + 0x555e, 0x3d4e, 0x6a25, 0x3a64, 0x604e, 0x6976, 0x6971, 0x306c, + 0x3447, 0x3168, 0x3167, 0x4529, 0x783c, 0x6549, 0x5562, 0x412c, + 0x3d78, 0x544b, 0x397d, 0x346f, 0x4e25, 0x5137, 0x355d, 0x5436, + 0x4a4a, 0x3359, 0x4728, 0x5121, 0x5245, 0x4149, 0x4275, 0x3b39, + 0x6547, 0x315f, 0x425f, 0x654e, 0x7879, 0x5b23, 0x534a, 0x5b29, + 0x4f67, 0x575e, 0x5a79, 0x5447, 0x354b, 0x5623, 0x415a, 0x3526, + 0x5a7e, 0x5b26, 0x5a77, 0x5b2a, 0x544d, 0x3373, 0x523d, 0x3d34, + 0x4470, 0x5046, 0x7527, 0x7526, 0x4a4d, 0x784e, 0x6e44, 0x6e45, + 0x6e46, 0x6e49, 0x6e48, 0x3624, 0x6e47, 0x556b, 0x3576, 0x6e4c, + 0x6e4b, 0x3730, 0x6e4e, 0x6e4a, 0x6e4f, 0x4725, 0x6e59, 0x6e55, + 0x6e57, 0x6e50, 0x4446, 0x365b, 0x3933, 0x6e54, 0x6e53, 0x332e, + 0x4525, 0x3e7b, 0x3846, 0x6e58, 0x6e51, 0x6e56, 0x6e6a, 0x6e66, + 0x6e5d, 0x4165, 0x6e5c, 0x6e60, 0x6e6b, 0x6e5a, 0x6e5f, 0x534b, + 0x6e64, 0x3c58, 0x6e52, 0x6e68, 0x6e67, 0x6e69, 0x322c, 0x6e5e, + 0x472f, 0x432d, 0x4726, 0x6e61, 0x3227, 0x6e5b, 0x6e62, 0x6e63, + 0x3d42, 0x6e6f, 0x3875, 0x6e7e, 0x5278, 0x6f25, 0x4d2d, 0x4f33, + 0x6e7d, 0x6e79, 0x437a, 0x6f22, 0x4f4e, 0x6e6e, 0x6f28, 0x523f, + 0x6e77, 0x6f27, 0x6e7b, 0x6e70, 0x6f24, 0x6e6d, 0x6e76, 0x4f7a, + 0x5062, 0x4c60, 0x6f31, 0x4241, 0x6f36, 0x503f, 0x3135, 0x6e7a, + 0x6e72, 0x3766, 0x6f32, 0x6f37, 0x6e74, 0x337a, 0x6f2d, 0x6f38, + 0x6f30, 0x464c, 0x4871, 0x6e71, 0x6f2f, 0x6f2e, 0x6f2b, 0x6f33, + 0x3e62, 0x3856, 0x6f3e, 0x6f3a, 0x6f42, 0x6f43, 0x5736, 0x6f39, + 0x6f3f, 0x3438, 0x6f45, 0x6f23, 0x6f3c, 0x6f44, 0x3627, 0x472e, + 0x3d75, 0x432a, 0x4e7d, 0x6f40, 0x346d, 0x423c, 0x434c, 0x7823, + 0x6f2a, 0x6f3d, 0x4f47, 0x6f41, 0x6e4d, 0x6f47, 0x3978, 0x3646, + 0x6f49, 0x5521, 0x364d, 0x6f4a, 0x6f46, 0x6f3b, 0x4742, 0x6f4c, + 0x3c7c, 0x6f48, 0x5560, 0x6f71, 0x433e, 0x6f4d, 0x6f51, 0x3077, + 0x4b78, 0x6f53, 0x4e59, 0x5d76, 0x6f56, 0x6e78, 0x6f21, 0x6f4b, + 0x3864, 0x5572, 0x6f57, 0x4478, 0x6f58, 0x6f54, 0x6f55, 0x6f5f, + 0x6f60, 0x4134, 0x6f52, 0x6f5d, 0x6f61, 0x6f2c, 0x6f4f, 0x6f5b, + 0x6f5c, 0x6f5e, 0x3279, 0x3e35, 0x6f5a, 0x6f4e, 0x7649, 0x6e7c, + 0x6f64, 0x6f6a, 0x6e73, 0x6f26, 0x414d, 0x6f29, 0x6f66, 0x6f62, + 0x5653, 0x6f6b, 0x6f63, 0x6f68, 0x6f34, 0x6f35, 0x6f50, 0x412d, + 0x6f6d, 0x4058, 0x4c7a, 0x6e6c, 0x6e75, 0x6f6e, 0x567d, 0x6f6c, + 0x6f59, 0x3c78, 0x6f6f, 0x6e65, 0x6f70, 0x6f65, 0x6f67, 0x543f, + 0x4f62, 0x4477, 0x6f69, 0x4260, 0x576a, 0x7647, 0x5464, 0x3324, + 0x4345, 0x6345, 0x4941, 0x6346, 0x3155, 0x3f2a, 0x634a, 0x6348, + 0x4872, 0x4f50, 0x3c64, 0x6349, 0x5522, 0x3a52, 0x3873, 0x7839, + 0x3727, 0x396b, 0x4376, 0x634d, 0x634f, 0x634c, 0x5444, 0x6351, + 0x514b, 0x5156, 0x6355, 0x6354, 0x6350, 0x6353, 0x6356, 0x7822, + 0x6347, 0x402b, 0x6357, 0x403b, 0x6359, 0x6358, 0x635a, 0x3433, + 0x3958, 0x635b, 0x327b, 0x785b, 0x634b, 0x5a6a, 0x4942, 0x5573, + 0x5275, 0x3342, 0x423d, 0x5174, 0x3653, 0x3d57, 0x5449, 0x3c4a, + 0x4b66, 0x4f55, 0x527e, 0x4224, 0x4125, 0x7922, 0x4b64, 0x4b2b, + 0x337b, 0x5453, 0x406b, 0x4451, 0x5446, 0x3567, 0x4e6d, 0x762b, + 0x7628, 0x7630, 0x4169, 0x7626, 0x584c, 0x392e, 0x7864, 0x7733, + 0x7732, 0x7861, 0x7735, 0x4e24, 0x484d, 0x3a2b, 0x6838, 0x683a, + 0x6839, 0x4f6c, 0x5233, 0x3625, 0x476a, 0x4f6e, 0x4b33, 0x717c, + 0x506b, 0x676f, 0x4b4c, 0x717d, 0x717e, 0x5424, 0x4d67, 0x3064, + 0x3659, 0x4644, 0x416c, 0x7222, 0x7221, 0x5243, 0x7224, 0x4d37, + 0x3c55, 0x7225, 0x3e31, 0x4635, 0x4d47, 0x3f45, 0x4c62, 0x366e, + 0x7226, 0x7227, 0x5155, 0x5438, 0x722a, 0x355f, 0x4060, 0x7229, + 0x722b, 0x394b, 0x327c, 0x722c, 0x4f54, 0x722d, 0x422d, 0x7228, + 0x4827, 0x3767, 0x6c29, 0x6c2a, 0x786c, 0x7837, 0x6c2b, 0x6c2c, + 0x462e, 0x6c2d, 0x6c2e, 0x3749, 0x623b, 0x783f, 0x623d, 0x623f, + 0x6240, 0x6241, 0x3739, 0x527b, 0x6242, 0x4b47, 0x3125, 0x4a4e, + 0x3d48, 0x317d, 0x6243, 0x5178, 0x367c, 0x6244, 0x4459, 0x3676, + 0x5360, 0x6246, 0x3d24, 0x4f5a, 0x395d, 0x623c, 0x6247, 0x623e, + 0x4173, 0x6248, 0x6249, 0x4278, 0x624a, 0x624b, 0x624c, 0x4021, + 0x624d, 0x3c22, 0x4844, 0x774f, 0x7750, 0x3276, 0x624e, 0x426d, + 0x5426, 0x376b, 0x4d54, 0x335b, 0x5131, 0x3235, 0x5724, 0x6665, + 0x3e54, 0x6660, 0x3c5d, 0x6666, 0x6662, 0x4a3b, 0x4d55, 0x6661, + 0x426e, 0x6669, 0x3a27, 0x4266, 0x3f25, 0x3352, 0x666d, 0x666c, + 0x466f, 0x666b, 0x6670, 0x462d, 0x6539, 0x666f, 0x6672, 0x4c5a, + 0x6663, 0x4927, 0x6673, 0x4262, 0x5d6b, 0x6671, 0x666e, 0x6674, + 0x6675, 0x477d, 0x6668, 0x6667, 0x6676, 0x3d3e, 0x5169, 0x3e2a, + 0x6664, 0x5668, 0x423f, 0x6678, 0x6677, 0x666a, 0x3039, 0x7743, + 0x787e, 0x4c65, 0x7746, 0x7745, 0x7831, 0x4b49, 0x783a, 0x7876, + 0x775e, 0x3637, 0x4456, 0x6352, 0x634e, 0x5374, 0x774b, 0x774a, + 0x5363, 0x4233, 0x7650, 0x764f, 0x7651, 0x7652, 0x7653, 0x7658, + 0x312b, 0x7656, 0x765a, 0x765f, 0x765c, 0x765b, 0x765e, 0x7659, + 0x4f4a, 0x7667, 0x7661, 0x7669, 0x4070, 0x7668, 0x7676, 0x766b, + 0x7674, 0x7671, 0x766e, 0x7672, 0x766f, 0x7670, 0x3e28, 0x766c, + 0x766d, 0x7673, 0x7675, 0x766a, 0x767d, 0x7678, 0x767c, 0x767a, + 0x7679, 0x767b, 0x487a, 0x767e, 0x7665, 0x7724, 0x7723, 0x7725, + 0x7722, 0x7663, 0x7721, 0x7726, 0x772a, 0x7666, 0x7664, 0x7729, + 0x7727, 0x772b, 0x7728, 0x316e, 0x772e, 0x772d, 0x772c, 0x415b, + 0x7660, 0x7677, 0x7657, 0x772f, 0x765d, 0x7654, 0x7662, 0x4471, + 0x702f, 0x596c, 0x376f, 0x4379, 0x7030, 0x7032, 0x7031, 0x513b, + 0x4d52, 0x5427, 0x7036, 0x7037, 0x7033, 0x516c, 0x513c, 0x7039, + 0x703b, 0x3a68, 0x386b, 0x703c, 0x3e69, 0x7041, 0x703e, 0x7043, + 0x366c, 0x7040, 0x7044, 0x7046, 0x4574, 0x7047, 0x4835, 0x7034, + 0x7048, 0x7045, 0x7049, 0x704a, 0x704c, 0x704d, 0x5d3a, 0x3a57, + 0x773d, 0x704f, 0x704b, 0x704e, 0x3c26, 0x7051, 0x4538, 0x703a, + 0x7052, 0x7038, 0x7054, 0x7053, 0x7055, 0x7042, 0x7056, 0x5325, + 0x7058, 0x7057, 0x7035, 0x7050, 0x7059, 0x703f, 0x703d, 0x7852, + 0x7874, 0x753a, 0x3c6f, 0x514e, 0x4076, 0x4273, 0x746f, 0x7865, + 0x7859, 0x4334, 0x5964, 0x3563, 0x3533, 0x7775, 0x7854, 0x7772, + 0x763c, 0x763d, 0x763e, 0x782e, 0x466b, 0x552b, 0x6c34, 0x335d, + 0x7633, 0x7635, 0x7637, 0x7634, 0x7636, 0x4164, 0x782a, 0x7638, + 0x763a, 0x7639, 0x4823, 0x763b, 0x417a, 0x4553, 0x3928, 0x6d68, + 0x396a, 0x2672, 0x2674, 0x2675, 0x2660, 0x2661, 0x2670, 0x2671, + 0x2662, 0x2663, 0x266e, 0x266f, 0x2666, 0x2667, 0x2664, 0x2665, + 0x2668, 0x2669, 0x266a, 0x266b, +}; + +static const Summary16 gb12345ext_uni2indx_page01[23] = { + /* 0x0100 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0110 }, { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, + { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, + { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0200 }, + /* 0x0200 */ + { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, + { 3, 0x0000 }, { 3, 0x0002 }, { 4, 0x0002 }, +}; +static const Summary16 gb12345ext_uni2indx_page1e[4] = { + /* 0x1e00 */ + { 5, 0x0000 }, { 5, 0x0000 }, { 5, 0x0000 }, { 5, 0x8000 }, +}; +static const Summary16 gb12345ext_uni2indx_page22[3] = { + /* 0x2200 */ + { 6, 0x0000 }, { 6, 0x0000 }, { 6, 0x0020 }, +}; +static const Summary16 gb12345ext_uni2indx_page4e[1306] = { + /* 0x4e00 */ + { 7, 0x0080 }, { 8, 0x0002 }, { 9, 0x0000 }, { 9, 0x0001 }, + { 10, 0x0100 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, + { 11, 0x0004 }, { 12, 0x4002 }, { 14, 0x0000 }, { 14, 0x0000 }, + { 14, 0x0040 }, { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0080 }, + /* 0x4f00 */ + { 16, 0x0000 }, { 16, 0x0000 }, { 16, 0x0000 }, { 16, 0x0000 }, + { 16, 0x0000 }, { 16, 0x0200 }, { 17, 0x0000 }, { 17, 0x0000 }, + { 17, 0x0040 }, { 18, 0x0040 }, { 19, 0x0000 }, { 19, 0x0000 }, + { 19, 0x0004 }, { 20, 0x0000 }, { 20, 0x0001 }, { 21, 0x0000 }, + /* 0x5000 */ + { 21, 0x0a41 }, { 25, 0x0002 }, { 26, 0x0800 }, { 27, 0x0000 }, + { 27, 0x0200 }, { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0030 }, + { 30, 0x0000 }, { 30, 0x0340 }, { 33, 0x2004 }, { 35, 0x40b8 }, + { 40, 0x0224 }, { 43, 0x4022 }, { 46, 0x0120 }, { 48, 0x0200 }, + /* 0x5100 */ + { 49, 0x0315 }, { 54, 0x8131 }, { 59, 0x0400 }, { 60, 0x1c84 }, + { 65, 0x0000 }, { 65, 0x0404 }, { 67, 0x0200 }, { 68, 0x0000 }, + { 68, 0x0000 }, { 68, 0x0000 }, { 68, 0x0000 }, { 68, 0x0004 }, + { 69, 0x2040 }, { 71, 0x0000 }, { 71, 0x2001 }, { 73, 0x0002 }, + /* 0x5200 */ + { 74, 0x0000 }, { 74, 0x0004 }, { 75, 0x0000 }, { 75, 0x0000 }, + { 75, 0x0890 }, { 78, 0x0800 }, { 79, 0x4000 }, { 80, 0x0030 }, + { 82, 0x3688 }, { 88, 0x0002 }, { 89, 0x0000 }, { 89, 0x0000 }, + { 89, 0x0002 }, { 90, 0x6a20 }, { 95, 0x0004 }, { 96, 0x0122 }, + /* 0x5300 */ + { 99, 0x0000 }, { 99, 0x0000 }, { 99, 0xa000 }, { 101, 0x0002 }, + { 102, 0x0001 }, { 103, 0x0010 }, { 104, 0x0000 }, { 104, 0x0000 }, + { 104, 0x0004 }, { 105, 0x0200 }, { 106, 0x2001 }, { 108, 0x0014 }, + { 110, 0x0008 }, { 111, 0x0000 }, { 111, 0x0404 }, { 113, 0x0041 }, + /* 0x5400 */ + { 115, 0x4000 }, { 116, 0x0000 }, { 116, 0x0000 }, { 116, 0x0000 }, + { 116, 0x0000 }, { 116, 0x0000 }, { 116, 0x0000 }, { 116, 0x0000 }, + { 116, 0x0000 }, { 116, 0x0000 }, { 116, 0x0000 }, { 116, 0x1000 }, + { 117, 0x0000 }, { 117, 0x0000 }, { 117, 0x0002 }, { 118, 0x0000 }, + /* 0x5500 */ + { 118, 0x0010 }, { 119, 0x0000 }, { 119, 0x0000 }, { 119, 0x0000 }, + { 119, 0x8000 }, { 120, 0x4008 }, { 122, 0x0000 }, { 122, 0x0000 }, + { 122, 0x0000 }, { 122, 0x0000 }, { 122, 0x5400 }, { 125, 0x0004 }, + { 126, 0x40c0 }, { 129, 0x0400 }, { 130, 0x0200 }, { 131, 0x0040 }, + /* 0x5600 */ + { 132, 0x2040 }, { 134, 0x10d0 }, { 138, 0xc200 }, { 141, 0x0121 }, + { 144, 0x0002 }, { 145, 0x2000 }, { 146, 0x8061 }, { 150, 0x0314 }, + { 154, 0x1081 }, { 157, 0x0220 }, { 159, 0x4140 }, { 162, 0x0058 }, + { 165, 0x1327 }, { 172, 0x0002 }, { 173, 0x0000 }, { 173, 0x0000 }, + /* 0x5700 */ + { 173, 0x2880 }, { 176, 0x014c }, { 180, 0x0000 }, { 180, 0x0000 }, + { 180, 0x0000 }, { 180, 0x0000 }, { 180, 0x0000 }, { 180, 0x0000 }, + { 180, 0x0000 }, { 180, 0x0000 }, { 180, 0x0000 }, { 180, 0x0000 }, + { 180, 0x0000 }, { 180, 0x0000 }, { 180, 0x0002 }, { 181, 0x0080 }, + /* 0x5800 */ + { 182, 0x0420 }, { 184, 0x2040 }, { 186, 0x8000 }, { 187, 0x0012 }, + { 189, 0x8c00 }, { 192, 0x0084 }, { 194, 0x0014 }, { 196, 0x0220 }, + { 198, 0x0400 }, { 199, 0x1000 }, { 200, 0x4000 }, { 201, 0x4808 }, + { 204, 0x0080 }, { 205, 0xc708 }, { 211, 0x8205 }, { 215, 0x2400 }, + /* 0x5900 */ + { 217, 0x0000 }, { 217, 0x0000 }, { 217, 0x0004 }, { 218, 0x4100 }, + { 220, 0x0000 }, { 220, 0x0000 }, { 220, 0x5600 }, { 224, 0x0000 }, + { 224, 0x0000 }, { 224, 0x2000 }, { 225, 0x0000 }, { 225, 0x0000 }, + { 225, 0x0000 }, { 225, 0x0000 }, { 225, 0x0000 }, { 225, 0x0000 }, + /* 0x5a00 */ + { 225, 0x0000 }, { 225, 0x0000 }, { 225, 0x0000 }, { 225, 0x0000 }, + { 225, 0x0002 }, { 226, 0x0000 }, { 226, 0x2040 }, { 228, 0x0000 }, + { 228, 0x0000 }, { 228, 0x0000 }, { 228, 0x0080 }, { 229, 0x2000 }, + { 230, 0x0000 }, { 230, 0x0080 }, { 231, 0x0000 }, { 231, 0x0820 }, + /* 0x5b00 */ + { 233, 0x1901 }, { 237, 0x0200 }, { 238, 0x0402 }, { 240, 0x0101 }, + { 242, 0x1000 }, { 243, 0x0000 }, { 243, 0x0800 }, { 244, 0x8100 }, + { 246, 0x0000 }, { 246, 0x0000 }, { 246, 0x0000 }, { 246, 0x0000 }, + { 246, 0x0000 }, { 246, 0x0000 }, { 246, 0x1ac4 }, { 252, 0x0060 }, + /* 0x5c00 */ + { 254, 0x6980 }, { 259, 0x0000 }, { 259, 0x0000 }, { 259, 0x0080 }, + { 260, 0x0000 }, { 260, 0x0000 }, { 260, 0x1114 }, { 264, 0x0000 }, + { 264, 0x0000 }, { 264, 0x0000 }, { 264, 0x0002 }, { 265, 0x0000 }, + { 265, 0x0000 }, { 265, 0x0000 }, { 265, 0x0000 }, { 265, 0x2050 }, + /* 0x5d00 */ + { 268, 0x2000 }, { 269, 0x0080 }, { 270, 0x1000 }, { 271, 0x0000 }, + { 271, 0x0000 }, { 271, 0x0001 }, { 272, 0x0000 }, { 272, 0x0000 }, + { 272, 0x0092 }, { 275, 0x0080 }, { 276, 0x0081 }, { 278, 0x1500 }, + { 281, 0x0800 }, { 282, 0x0014 }, { 284, 0x0000 }, { 284, 0x0001 }, + /* 0x5e00 */ + { 285, 0x0000 }, { 285, 0x0100 }, { 286, 0x0820 }, { 288, 0x0048 }, + { 290, 0x0009 }, { 292, 0x8180 }, { 295, 0x1808 }, { 298, 0xc204 }, + { 302, 0x0000 }, { 302, 0x0000 }, { 302, 0x0800 }, { 303, 0x0000 }, + { 303, 0x0000 }, { 303, 0x8000 }, { 304, 0x100f }, { 309, 0x0008 }, + /* 0x5f00 */ + { 310, 0x0000 }, { 310, 0x0000 }, { 310, 0x0000 }, { 310, 0x0028 }, + { 312, 0x5140 }, { 316, 0x0200 }, { 317, 0x0000 }, { 317, 0x0000 }, + { 317, 0x1000 }, { 318, 0x4002 }, { 320, 0x0201 }, { 322, 0x0200 }, + { 323, 0x0000 }, { 323, 0x0000 }, { 323, 0x0000 }, { 323, 0x0000 }, + /* 0x6000 */ + { 323, 0x0000 }, { 323, 0x0000 }, { 323, 0x0000 }, { 323, 0x0000 }, + { 323, 0x0000 }, { 323, 0x0000 }, { 323, 0x0000 }, { 323, 0x0000 }, + { 323, 0x0000 }, { 323, 0x0000 }, { 323, 0x0000 }, { 323, 0x0060 }, + { 325, 0x0000 }, { 325, 0x0000 }, { 325, 0x0002 }, { 326, 0x0806 }, + /* 0x6100 */ + { 329, 0x0000 }, { 329, 0x1800 }, { 331, 0x0000 }, { 331, 0xc090 }, + { 335, 0x0800 }, { 336, 0x8500 }, { 339, 0x4c18 }, { 344, 0x0048 }, + { 346, 0x0404 }, { 348, 0x0407 }, { 352, 0x4810 }, { 355, 0x0044 }, + { 357, 0x1280 }, { 360, 0xc000 }, { 362, 0x0108 }, { 364, 0x55c4 }, + /* 0x6200 */ + { 371, 0x0081 }, { 373, 0x0010 }, { 374, 0x0080 }, { 375, 0x0005 }, + { 377, 0x0000 }, { 377, 0x0002 }, { 378, 0x0000 }, { 378, 0x0000 }, + { 378, 0x0000 }, { 378, 0x0000 }, { 378, 0x0000 }, { 378, 0x0000 }, + { 378, 0x0000 }, { 378, 0x0000 }, { 378, 0x0000 }, { 378, 0x0000 }, + /* 0x6300 */ + { 378, 0x0000 }, { 378, 0x0000 }, { 378, 0x0000 }, { 378, 0x4000 }, + { 379, 0x0000 }, { 379, 0x0000 }, { 379, 0x4900 }, { 382, 0x0004 }, + { 383, 0x0018 }, { 385, 0x0000 }, { 385, 0x0000 }, { 385, 0x0000 }, + { 385, 0x0001 }, { 386, 0x0400 }, { 387, 0x4000 }, { 388, 0x0000 }, + /* 0x6400 */ + { 388, 0x2000 }, { 389, 0x0080 }, { 390, 0x0000 }, { 390, 0x0040 }, + { 391, 0x0000 }, { 391, 0x9002 }, { 394, 0x8000 }, { 395, 0x0848 }, + { 398, 0x0100 }, { 399, 0x8008 }, { 401, 0x0828 }, { 404, 0xc80c }, + { 409, 0x0c92 }, { 414, 0x0410 }, { 416, 0x9001 }, { 419, 0x5c97 }, + /* 0x6500 */ + { 428, 0x8050 }, { 431, 0x2a50 }, { 436, 0x141c }, { 441, 0x0000 }, + { 441, 0x0000 }, { 441, 0x0080 }, { 442, 0x0000 }, { 442, 0x0120 }, + { 444, 0x000c }, { 446, 0x00a0 }, { 448, 0x1000 }, { 449, 0x0080 }, + { 450, 0x0000 }, { 450, 0x0000 }, { 450, 0x0000 }, { 450, 0x0000 }, + /* 0x6600 */ + { 450, 0x0000 }, { 450, 0x0000 }, { 450, 0x0000 }, { 450, 0x0000 }, + { 450, 0x0004 }, { 451, 0x2000 }, { 452, 0x0000 }, { 452, 0x0000 }, + { 452, 0x0300 }, { 454, 0x0000 }, { 454, 0x0804 }, { 456, 0x0000 }, + { 456, 0x02d0 }, { 460, 0x0040 }, { 461, 0x1001 }, { 463, 0x0100 }, + /* 0x6700 */ + { 464, 0x0008 }, { 465, 0x0000 }, { 465, 0x8080 }, { 467, 0x0010 }, + { 468, 0x0000 }, { 468, 0x0000 }, { 468, 0x0000 }, { 468, 0x4002 }, + { 470, 0x0000 }, { 470, 0x0000 }, { 470, 0x0000 }, { 470, 0x0000 }, + { 470, 0x0000 }, { 470, 0x0000 }, { 470, 0x0000 }, { 470, 0x0000 }, + /* 0x6800 */ + { 470, 0x0000 }, { 470, 0x0000 }, { 470, 0x0000 }, { 470, 0x0000 }, + { 470, 0x0000 }, { 470, 0x0000 }, { 470, 0x0000 }, { 470, 0x0000 }, + { 470, 0x0000 }, { 470, 0xa100 }, { 473, 0x0000 }, { 473, 0x0000 }, + { 473, 0x0000 }, { 473, 0x80c0 }, { 476, 0x0080 }, { 477, 0x0000 }, + /* 0x6900 */ + { 477, 0x8000 }, { 478, 0x0000 }, { 478, 0x0000 }, { 478, 0x0000 }, + { 478, 0x0400 }, { 479, 0x0008 }, { 480, 0x2100 }, { 482, 0x0020 }, + { 483, 0x0000 }, { 483, 0x0000 }, { 483, 0x4400 }, { 485, 0x8000 }, + { 486, 0x2800 }, { 488, 0x0000 }, { 488, 0x0080 }, { 489, 0x0008 }, + /* 0x6a00 */ + { 490, 0x0026 }, { 493, 0x4208 }, { 496, 0x0008 }, { 497, 0x0700 }, + { 500, 0x0900 }, { 502, 0x8000 }, { 503, 0x0004 }, { 504, 0x0000 }, + { 504, 0x0200 }, { 505, 0x1010 }, { 507, 0x800c }, { 510, 0x0908 }, + { 513, 0x0008 }, { 514, 0xec08 }, { 520, 0x1580 }, { 524, 0x0908 }, + /* 0x6b00 */ + { 527, 0x8410 }, { 530, 0x4044 }, { 533, 0x0000 }, { 533, 0x2000 }, + { 534, 0x0000 }, { 534, 0x8001 }, { 536, 0x0002 }, { 537, 0x0184 }, + { 540, 0x0000 }, { 540, 0x4100 }, { 542, 0xc810 }, { 546, 0x0c04 }, + { 549, 0x0040 }, { 550, 0x0000 }, { 550, 0x0000 }, { 550, 0x8000 }, + /* 0x6c00 */ + { 551, 0x1100 }, { 553, 0x0000 }, { 553, 0x1808 }, { 556, 0x0000 }, + { 556, 0x0000 }, { 556, 0x0000 }, { 556, 0x0000 }, { 556, 0x0000 }, + { 556, 0x0000 }, { 556, 0x0000 }, { 556, 0x0000 }, { 556, 0x0000 }, + { 556, 0x0000 }, { 556, 0x0000 }, { 556, 0x0000 }, { 556, 0x0000 }, + /* 0x6d00 */ + { 556, 0x0000 }, { 556, 0x0000 }, { 556, 0x0000 }, { 556, 0x0000 }, + { 556, 0x0000 }, { 556, 0x0000 }, { 556, 0x0000 }, { 556, 0x0200 }, + { 557, 0x0084 }, { 559, 0x0000 }, { 559, 0x0000 }, { 559, 0x0000 }, + { 559, 0x0001 }, { 560, 0x0000 }, { 560, 0x0400 }, { 561, 0x0460 }, + /* 0x6e00 */ + { 564, 0x0000 }, { 564, 0x0000 }, { 564, 0x1040 }, { 566, 0x4000 }, + { 567, 0x0000 }, { 567, 0x4000 }, { 568, 0x8000 }, { 569, 0x0000 }, + { 569, 0x0000 }, { 569, 0x2040 }, { 571, 0x0000 }, { 571, 0x0000 }, + { 571, 0x5030 }, { 575, 0x0000 }, { 575, 0x9000 }, { 577, 0x8184 }, + /* 0x6f00 */ + { 581, 0x0002 }, { 582, 0x0400 }, { 583, 0x100c }, { 586, 0x8104 }, + { 589, 0x0002 }, { 590, 0x0212 }, { 593, 0x8010 }, { 595, 0x8081 }, + { 598, 0x00c1 }, { 601, 0x0080 }, { 602, 0x4211 }, { 606, 0x0002 }, + { 607, 0x000a }, { 609, 0x8920 }, { 613, 0x0810 }, { 615, 0x5403 }, + /* 0x7000 */ + { 620, 0x8a60 }, { 625, 0xa120 }, { 629, 0x0181 }, { 632, 0x4005 }, + { 635, 0x0018 }, { 637, 0x2122 }, { 641, 0x0098 }, { 644, 0x0000 }, + { 644, 0x0000 }, { 644, 0x0000 }, { 644, 0x0000 }, { 644, 0x0000 }, + { 644, 0x8000 }, { 645, 0x0000 }, { 645, 0x0000 }, { 645, 0x0010 }, + /* 0x7100 */ + { 646, 0x0000 }, { 646, 0x0000 }, { 646, 0x0002 }, { 647, 0x0000 }, + { 647, 0x0200 }, { 648, 0x0004 }, { 649, 0x1204 }, { 652, 0x0000 }, + { 652, 0x0000 }, { 652, 0x0084 }, { 654, 0x0000 }, { 654, 0x4002 }, + { 656, 0x0102 }, { 658, 0x9204 }, { 662, 0x2040 }, { 664, 0x5010 }, + /* 0x7200 */ + { 667, 0x2000 }, { 668, 0x0801 }, { 670, 0x0000 }, { 670, 0x4404 }, + { 673, 0x0000 }, { 673, 0x0100 }, { 674, 0x0000 }, { 674, 0x2000 }, + { 675, 0x0000 }, { 675, 0x0040 }, { 676, 0x0084 }, { 678, 0x0000 }, + { 678, 0x0001 }, { 679, 0x0000 }, { 679, 0x0000 }, { 679, 0x2200 }, + /* 0x7300 */ + { 681, 0x0000 }, { 681, 0x0000 }, { 681, 0x0000 }, { 681, 0x0840 }, + { 683, 0x0032 }, { 686, 0x0000 }, { 686, 0x0d00 }, { 689, 0x1da5 }, + { 697, 0x0001 }, { 698, 0x0000 }, { 698, 0x0000 }, { 698, 0x0000 }, + { 698, 0x0000 }, { 698, 0x0000 }, { 698, 0x0000 }, { 698, 0x4000 }, + /* 0x7400 */ + { 699, 0x0000 }, { 699, 0x0000 }, { 699, 0x0000 }, { 699, 0x8000 }, + { 700, 0x0800 }, { 701, 0x0000 }, { 701, 0x0608 }, { 704, 0x0000 }, + { 704, 0x0200 }, { 705, 0x0000 }, { 705, 0x0048 }, { 707, 0x2001 }, + { 709, 0x8400 }, { 711, 0x0410 }, { 713, 0x0000 }, { 713, 0x0000 }, + /* 0x7500 */ + { 713, 0x1000 }, { 714, 0x0000 }, { 714, 0x0008 }, { 715, 0x0000 }, + { 715, 0x0000 }, { 715, 0x2000 }, { 716, 0x0804 }, { 718, 0x0040 }, + { 719, 0x0080 }, { 720, 0x0000 }, { 720, 0x0000 }, { 720, 0x0000 }, + { 720, 0x0080 }, { 721, 0x0200 }, { 722, 0x0000 }, { 722, 0x0000 }, + /* 0x7600 */ + { 722, 0x2804 }, { 725, 0x4000 }, { 726, 0x0082 }, { 728, 0x0800 }, + { 729, 0x02c4 }, { 733, 0x8100 }, { 735, 0x72b4 }, { 743, 0x1007 }, + { 747, 0x0000 }, { 747, 0x0400 }, { 748, 0x0000 }, { 748, 0x0500 }, + { 750, 0x0000 }, { 750, 0x4000 }, { 751, 0x009a }, { 755, 0x0000 }, + /* 0x7700 */ + { 755, 0x0000 }, { 755, 0x0000 }, { 755, 0x0000 }, { 755, 0x0000 }, + { 755, 0x8000 }, { 756, 0x4000 }, { 757, 0x0000 }, { 757, 0x0000 }, + { 757, 0x0000 }, { 757, 0x4100 }, { 759, 0x2000 }, { 760, 0x1000 }, + { 761, 0x0080 }, { 762, 0x0400 }, { 763, 0x8000 }, { 764, 0x0000 }, + /* 0x7800 */ + { 764, 0x0000 }, { 764, 0x0000 }, { 764, 0x0000 }, { 764, 0x0000 }, + { 764, 0x0008 }, { 765, 0x0000 }, { 765, 0xc110 }, { 769, 0x0000 }, + { 769, 0x0000 }, { 769, 0x0000 }, { 769, 0x2200 }, { 771, 0x1500 }, + { 774, 0x0000 }, { 774, 0x0400 }, { 775, 0x8088 }, { 778, 0x2000 }, + /* 0x7900 */ + { 779, 0x4000 }, { 780, 0x0200 }, { 781, 0x1c40 }, { 785, 0x0002 }, + { 786, 0x0000 }, { 786, 0x0000 }, { 786, 0x0000 }, { 786, 0x0000 }, + { 786, 0x6000 }, { 788, 0x0000 }, { 788, 0x4440 }, { 791, 0x0003 }, + { 793, 0x2000 }, { 794, 0x0000 }, { 794, 0x0000 }, { 794, 0x0000 }, + /* 0x7a00 */ + { 794, 0x0000 }, { 794, 0x0000 }, { 794, 0x4000 }, { 795, 0x0002 }, + { 796, 0x7001 }, { 800, 0x0000 }, { 800, 0x0a06 }, { 804, 0x0000 }, + { 804, 0x0000 }, { 804, 0x0000 }, { 804, 0x4600 }, { 807, 0x0440 }, + { 809, 0x05b0 }, { 814, 0x0000 }, { 814, 0x0400 }, { 815, 0x0040 }, + /* 0x7b00 */ + { 816, 0x0000 }, { 816, 0x0000 }, { 816, 0x0000 }, { 816, 0x0000 }, + { 816, 0x0040 }, { 817, 0x0002 }, { 818, 0x0080 }, { 819, 0x0000 }, + { 819, 0x0800 }, { 820, 0x0000 }, { 820, 0x0000 }, { 820, 0x0000 }, + { 820, 0x0a11 }, { 824, 0x0000 }, { 824, 0x0210 }, { 826, 0x0008 }, + /* 0x7c00 */ + { 827, 0x2001 }, { 829, 0x4000 }, { 830, 0x080a }, { 833, 0x6000 }, + { 835, 0x1008 }, { 837, 0x9000 }, { 839, 0x5611 }, { 845, 0x0004 }, + { 846, 0x0000 }, { 846, 0x0000 }, { 846, 0x0000 }, { 846, 0x0000 }, + { 846, 0x0000 }, { 846, 0x6000 }, { 848, 0x0080 }, { 849, 0x4255 }, + /* 0x7d00 */ + { 855, 0x2bf5 }, { 865, 0x1eb9 }, { 874, 0x0002 }, { 875, 0x960f }, + { 883, 0x4055 }, { 888, 0x6001 }, { 891, 0x0146 }, { 895, 0x024e }, + { 900, 0x834a }, { 906, 0x5008 }, { 909, 0x380c }, { 914, 0xef1f }, + { 926, 0x0c90 }, { 930, 0x6396 }, { 938, 0x934b }, { 946, 0x0a56 }, + /* 0x7e00 */ + { 952, 0x0f00 }, { 956, 0xe803 }, { 962, 0x6888 }, { 967, 0x62f6 }, + { 976, 0x0060 }, { 978, 0x4434 }, { 983, 0xee04 }, { 990, 0x7209 }, + { 996, 0xb500 }, { 1001, 0x1158 }, { 1006, 0x0000 }, { 1006, 0x0000 }, + { 1006, 0x0000 }, { 1006, 0x0000 }, { 1006, 0x0000 }, { 1006, 0x0000 }, + /* 0x7f00 */ + { 1006, 0x0000 }, { 1006, 0x0000 }, { 1006, 0x0000 }, { 1006, 0x0000 }, + { 1006, 0x5000 }, { 1008, 0x0000 }, { 1008, 0x0000 }, { 1008, 0x0081 }, + { 1010, 0x0160 }, { 1013, 0x0000 }, { 1013, 0x0220 }, { 1015, 0x0000 }, + { 1015, 0x0000 }, { 1015, 0x0004 }, { 1016, 0x0000 }, { 1016, 0x0200 }, + /* 0x8000 */ + { 1017, 0x0000 }, { 1017, 0x0000 }, { 1017, 0x5000 }, { 1019, 0x0000 }, + { 1019, 0x0000 }, { 1019, 0x4040 }, { 1021, 0x8000 }, { 1022, 0x62ed }, + { 1031, 0x0020 }, { 1032, 0x0000 }, { 1032, 0x0000 }, { 1032, 0x0000 }, + { 1032, 0x0000 }, { 1032, 0x0000 }, { 1032, 0x0000 }, { 1032, 0x0000 }, + /* 0x8100 */ + { 1032, 0x0020 }, { 1033, 0x0800 }, { 1034, 0x0000 }, { 1034, 0x0200 }, + { 1035, 0x4400 }, { 1037, 0x0040 }, { 1038, 0x0842 }, { 1041, 0x0100 }, + { 1042, 0x0000 }, { 1042, 0x0400 }, { 1043, 0x0201 }, { 1045, 0xe000 }, + { 1048, 0xa200 }, { 1051, 0x8500 }, { 1054, 0x0101 }, { 1056, 0x0400 }, + /* 0x8200 */ + { 1057, 0x2780 }, { 1062, 0x0000 }, { 1062, 0x0000 }, { 1062, 0x0000 }, + { 1062, 0x0000 }, { 1062, 0x0200 }, { 1063, 0x0850 }, { 1066, 0x0082 }, + { 1068, 0x0000 }, { 1068, 0x0000 }, { 1068, 0x0000 }, { 1068, 0x0800 }, + { 1069, 0x0000 }, { 1069, 0x0000 }, { 1069, 0x0080 }, { 1070, 0x0200 }, + /* 0x8300 */ + { 1071, 0x0008 }, { 1072, 0x0000 }, { 1072, 0x0000 }, { 1072, 0x0000 }, + { 1072, 0x0000 }, { 1072, 0x0001 }, { 1073, 0x0000 }, { 1073, 0x0000 }, + { 1073, 0x0400 }, { 1074, 0x0040 }, { 1075, 0x0084 }, { 1077, 0x0000 }, + { 1077, 0x0000 }, { 1077, 0x0000 }, { 1077, 0x8000 }, { 1078, 0x0000 }, + /* 0x8400 */ + { 1078, 0x0480 }, { 1080, 0x0000 }, { 1080, 0x1000 }, { 1081, 0x0020 }, + { 1082, 0x0200 }, { 1083, 0x0004 }, { 1084, 0x8050 }, { 1087, 0x0080 }, + { 1088, 0x0000 }, { 1088, 0x0018 }, { 1090, 0x0000 }, { 1090, 0x1000 }, + { 1091, 0x0801 }, { 1093, 0x0000 }, { 1093, 0xc000 }, { 1095, 0x2000 }, + /* 0x8500 */ + { 1096, 0x0000 }, { 1096, 0x4010 }, { 1098, 0x2048 }, { 1101, 0x0000 }, + { 1101, 0x4042 }, { 1104, 0x012c }, { 1108, 0x2604 }, { 1112, 0x0080 }, + { 1113, 0x1500 }, { 1116, 0x8012 }, { 1119, 0x0240 }, { 1121, 0x0400 }, + { 1122, 0x6000 }, { 1124, 0x2000 }, { 1125, 0x0420 }, { 1127, 0x0650 }, + /* 0x8600 */ + { 1131, 0x08d0 }, { 1135, 0x4400 }, { 1137, 0x2004 }, { 1139, 0x8400 }, + { 1141, 0x0000 }, { 1141, 0x9020 }, { 1144, 0x0080 }, { 1145, 0x0000 }, + { 1145, 0x0000 }, { 1145, 0x0000 }, { 1145, 0x0000 }, { 1145, 0x0000 }, + { 1145, 0x0000 }, { 1145, 0x0000 }, { 1145, 0x0000 }, { 1145, 0x0400 }, + /* 0x8700 */ + { 1146, 0x0040 }, { 1147, 0x0000 }, { 1147, 0x0002 }, { 1148, 0x0000 }, + { 1148, 0x0000 }, { 1148, 0x0020 }, { 1149, 0x0040 }, { 1150, 0x0100 }, + { 1151, 0x0010 }, { 1152, 0x4000 }, { 1153, 0x0004 }, { 1154, 0x0800 }, + { 1155, 0x4110 }, { 1158, 0x0000 }, { 1158, 0x9008 }, { 1161, 0x0844 }, + /* 0x8800 */ + { 1164, 0x0060 }, { 1166, 0x8003 }, { 1169, 0x0008 }, { 1170, 0x0842 }, + { 1173, 0x0440 }, { 1175, 0x2808 }, { 1178, 0x0000 }, { 1178, 0x0200 }, + { 1179, 0x0000 }, { 1179, 0x0000 }, { 1179, 0x0000 }, { 1179, 0x0000 }, + { 1179, 0x8400 }, { 1181, 0x3000 }, { 1183, 0x0000 }, { 1183, 0x2000 }, + /* 0x8900 */ + { 1184, 0x0080 }, { 1185, 0x0000 }, { 1185, 0x0000 }, { 1185, 0x090c }, + { 1189, 0x0080 }, { 1190, 0x2040 }, { 1192, 0x9411 }, { 1197, 0x0004 }, + { 1198, 0x8800 }, { 1200, 0x0148 }, { 1203, 0x9442 }, { 1208, 0xa484 }, + { 1213, 0x0001 }, { 1214, 0x0000 }, { 1214, 0x0000 }, { 1214, 0x0150 }, + /* 0x8a00 */ + { 1217, 0x550e }, { 1224, 0xa969 }, { 1232, 0x2428 }, { 1236, 0x0452 }, + { 1240, 0x4042 }, { 1243, 0x4935 }, { 1250, 0x7a4e }, { 1259, 0x902f }, + { 1266, 0x20f0 }, { 1271, 0x4526 }, { 1277, 0x117b }, { 1285, 0x9245 }, + { 1291, 0xaa94 }, { 1298, 0x58c6 }, { 1305, 0x68d4 }, { 1312, 0x55ca }, + /* 0x8b00 */ + { 1320, 0x4437 }, { 1327, 0x2ed1 }, { 1335, 0x3902 }, { 1340, 0x4208 }, + { 1343, 0xc200 }, { 1346, 0x1740 }, { 1351, 0x8800 }, { 1353, 0x2091 }, + { 1357, 0x4401 }, { 1360, 0x506c }, { 1366, 0x0000 }, { 1366, 0x0000 }, + { 1366, 0x0000 }, { 1366, 0x0000 }, { 1366, 0x0000 }, { 1366, 0x0000 }, + /* 0x8c00 */ + { 1366, 0x0000 }, { 1366, 0x0000 }, { 1366, 0x0000 }, { 1366, 0x0000 }, + { 1366, 0x0100 }, { 1367, 0x0001 }, { 1368, 0x0000 }, { 1368, 0x0000 }, + { 1368, 0x0000 }, { 1368, 0x6000 }, { 1370, 0x9f87 }, { 1380, 0xbddd }, + { 1392, 0x05bf }, { 1401, 0x542e }, { 1408, 0x3cdf }, { 1419, 0x7c10 }, + /* 0x8d00 */ + { 1425, 0xad30 }, { 1432, 0x1841 }, { 1436, 0x0000 }, { 1436, 0x0000 }, + { 1436, 0x0000 }, { 1436, 0x0000 }, { 1436, 0x0000 }, { 1436, 0x0000 }, + { 1436, 0x0000 }, { 1436, 0x0220 }, { 1438, 0x0100 }, { 1439, 0x0004 }, + { 1440, 0x0000 }, { 1440, 0x0000 }, { 1440, 0x0000 }, { 1440, 0x0000 }, + /* 0x8e00 */ + { 1440, 0x0000 }, { 1440, 0x0001 }, { 1441, 0x0000 }, { 1441, 0x0010 }, + { 1442, 0x1000 }, { 1443, 0x0020 }, { 1444, 0x0008 }, { 1445, 0x0400 }, + { 1446, 0x2e00 }, { 1450, 0x040e }, { 1454, 0x0462 }, { 1458, 0x0000 }, + { 1458, 0x3c01 }, { 1463, 0x8814 }, { 1467, 0x0810 }, { 1469, 0x5f04 }, + /* 0x8f00 */ + { 1476, 0x06a8 }, { 1481, 0xf834 }, { 1489, 0x8660 }, { 1494, 0xc908 }, + { 1499, 0x6274 }, { 1506, 0x8010 }, { 1508, 0x0016 }, { 1511, 0x0000 }, + { 1511, 0x0000 }, { 1511, 0x0000 }, { 1511, 0xe040 }, { 1515, 0x0004 }, + { 1516, 0x0000 }, { 1516, 0x0000 }, { 1516, 0x0000 }, { 1516, 0x0010 }, + /* 0x9000 */ + { 1517, 0x0000 }, { 1517, 0x0220 }, { 1519, 0x0008 }, { 1520, 0x0004 }, + { 1521, 0x4800 }, { 1523, 0x5030 }, { 1527, 0x0201 }, { 1529, 0x1584 }, + { 1534, 0x8492 }, { 1539, 0x0001 }, { 1540, 0x0000 }, { 1540, 0x0000 }, + { 1540, 0x0002 }, { 1541, 0x8000 }, { 1542, 0x0000 }, { 1542, 0x0020 }, + /* 0x9100 */ + { 1543, 0x0240 }, { 1545, 0x0054 }, { 1548, 0x2080 }, { 1550, 0x0455 }, + { 1555, 0x0100 }, { 1556, 0x0000 }, { 1556, 0x0000 }, { 1556, 0x0000 }, + { 1556, 0x0000 }, { 1556, 0x1040 }, { 1558, 0x1800 }, { 1560, 0x0000 }, + { 1560, 0x182b }, { 1566, 0x23bc }, { 1574, 0x0298 }, { 1578, 0x06a0 }, + /* 0x9200 */ + { 1582, 0x6313 }, { 1589, 0x4033 }, { 1594, 0x40e8 }, { 1599, 0xe799 }, + { 1609, 0x2321 }, { 1614, 0x4ca2 }, { 1620, 0x3044 }, { 1624, 0x8d00 }, + { 1628, 0x0029 }, { 1631, 0x154a }, { 1637, 0x1f69 }, { 1646, 0x1a82 }, + { 1651, 0x90aa }, { 1657, 0xa004 }, { 1660, 0xe578 }, { 1669, 0x1143 }, + /* 0x9300 */ + { 1674, 0x01c2 }, { 1678, 0x8f25 }, { 1686, 0xc945 }, { 1693, 0x014c }, + { 1697, 0x28cb }, { 1704, 0x0910 }, { 1707, 0x1230 }, { 1711, 0x4461 }, + { 1716, 0x0494 }, { 1720, 0x0140 }, { 1722, 0x56cc }, { 1730, 0x8129 }, + { 1735, 0x3188 }, { 1740, 0xf182 }, { 1747, 0x0116 }, { 1751, 0x02a0 }, + /* 0x9400 */ + { 1754, 0x0808 }, { 1756, 0x231d }, { 1763, 0x41c1 }, { 1768, 0x852c }, + { 1774, 0x1410 }, { 1777, 0x0014 }, { 1779, 0x2029 }, { 1783, 0xf285 }, + { 1791, 0x0000 }, { 1791, 0x0000 }, { 1791, 0x0000 }, { 1791, 0x0000 }, + { 1791, 0x0000 }, { 1791, 0x0000 }, { 1791, 0x0000 }, { 1791, 0x0000 }, + /* 0x9500 */ + { 1791, 0x0000 }, { 1791, 0x0000 }, { 1791, 0x0000 }, { 1791, 0x0000 }, + { 1791, 0x0000 }, { 1791, 0x0000 }, { 1791, 0x0000 }, { 1791, 0x0080 }, + { 1792, 0xda4d }, { 1801, 0x011a }, { 1805, 0x3b3a }, { 1814, 0xfa44 }, + { 1822, 0x1d48 }, { 1828, 0x5071 }, { 1834, 0x0026 }, { 1837, 0x0000 }, + /* 0x9600 */ + { 1837, 0x0000 }, { 1837, 0x0000 }, { 1837, 0x0000 }, { 1837, 0x0000 }, + { 1837, 0x0000 }, { 1837, 0x2100 }, { 1839, 0x0008 }, { 1840, 0x2109 }, + { 1844, 0x4400 }, { 1846, 0x0820 }, { 1848, 0x0500 }, { 1850, 0x0912 }, + { 1854, 0x0000 }, { 1854, 0x1a40 }, { 1858, 0x000c }, { 1860, 0x0804 }, + /* 0x9700 */ + { 1862, 0x0000 }, { 1862, 0x0000 }, { 1862, 0x0080 }, { 1863, 0x2000 }, + { 1864, 0x0114 }, { 1867, 0x0400 }, { 1868, 0x0100 }, { 1869, 0x0000 }, + { 1869, 0x8000 }, { 1870, 0x0000 }, { 1870, 0x0040 }, { 1871, 0x2000 }, + { 1872, 0x1a48 }, { 1877, 0x5208 }, { 1881, 0x0000 }, { 1881, 0x8000 }, + /* 0x9800 */ + { 1882, 0xd5ee }, { 1893, 0x118f }, { 1900, 0x2052 }, { 1904, 0x2981 }, + { 1909, 0x7040 }, { 1913, 0x4b18 }, { 1919, 0x98a4 }, { 1925, 0x001b }, + { 1929, 0x0000 }, { 1929, 0x0000 }, { 1929, 0xc100 }, { 1932, 0x104a }, + { 1936, 0x0150 }, { 1939, 0x0800 }, { 1940, 0xae05 }, { 1947, 0x7014 }, + /* 0x9900 */ + { 1952, 0x1628 }, { 1957, 0x490e }, { 1963, 0x0102 }, { 1965, 0xd088 }, + { 1970, 0x1f28 }, { 1977, 0x5086 }, { 1982, 0x0004 }, { 1983, 0x0000 }, + { 1983, 0x0000 }, { 1983, 0x0000 }, { 1983, 0x7000 }, { 1986, 0x001a }, + { 1989, 0x0002 }, { 1990, 0xab37 }, { 2000, 0x2006 }, { 2003, 0x8002 }, + /* 0x9a00 */ + { 2005, 0xe022 }, { 2010, 0x0240 }, { 2012, 0x6800 }, { 2015, 0x41c1 }, + { 2020, 0xa43f }, { 2029, 0x8ca0 }, { 2034, 0x0434 }, { 2038, 0x0000 }, + { 2038, 0x0000 }, { 2038, 0x0000 }, { 2038, 0x8000 }, { 2039, 0x0000 }, + { 2039, 0x8000 }, { 2040, 0x0074 }, { 2044, 0x4000 }, { 2045, 0x0000 }, + /* 0x9b00 */ + { 2045, 0x2040 }, { 2047, 0x0400 }, { 2048, 0x42a4 }, { 2053, 0x0002 }, + { 2054, 0x4000 }, { 2055, 0x0500 }, { 2057, 0x8000 }, { 2058, 0x0090 }, + { 2060, 0x400a }, { 2063, 0x6407 }, { 2069, 0x6c00 }, { 2073, 0x0000 }, + { 2073, 0x0683 }, { 2078, 0x2850 }, { 2082, 0x0d96 }, { 2089, 0xa011 }, + /* 0x9c00 */ + { 2093, 0x2300 }, { 2096, 0x000d }, { 2099, 0x2329 }, { 2105, 0x4aae }, + { 2113, 0x0320 }, { 2116, 0xa1d4 }, { 2123, 0x2080 }, { 2125, 0x0500 }, + { 2127, 0x0000 }, { 2127, 0x0000 }, { 2127, 0x0000 }, { 2127, 0x0000 }, + { 2127, 0x0000 }, { 2127, 0x0000 }, { 2127, 0x1220 }, { 2130, 0x0058 }, + /* 0x9d00 */ + { 2133, 0x02c0 }, { 2136, 0xa820 }, { 2140, 0x8148 }, { 2144, 0x8801 }, + { 2147, 0x0004 }, { 2148, 0x300e }, { 2153, 0x9403 }, { 2158, 0x0004 }, + { 2159, 0x0280 }, { 2161, 0x0508 }, { 2164, 0x8220 }, { 2167, 0x1810 }, + { 2170, 0x0015 }, { 2173, 0x0688 }, { 2177, 0x8060 }, { 2180, 0x070c }, + /* 0x9e00 */ + { 2185, 0x1000 }, { 2186, 0x6c20 }, { 2191, 0x0000 }, { 2191, 0x0000 }, + { 2191, 0x0000 }, { 2191, 0x0000 }, { 2191, 0x0000 }, { 2191, 0x3620 }, + { 2196, 0x0000 }, { 2196, 0x0080 }, { 2197, 0x8220 }, { 2200, 0x2020 }, + { 2202, 0x1000 }, { 2203, 0x4000 }, { 2204, 0x0100 }, { 2205, 0xa094 }, + /* 0x9f00 */ + { 2210, 0x0200 }, { 2211, 0x0020 }, { 2212, 0x0000 }, { 2212, 0x0000 }, + { 2212, 0x8c00 }, { 2215, 0x9214 }, { 2220, 0x144b }, { 2226, 0x0084 }, + { 2228, 0x2000 }, { 2229, 0x1031 }, +}; +static const Summary16 gb12345ext_uni2indx_pagefe[5] = { + /* 0xfe00 */ + { 2233, 0x0000 }, { 2233, 0x0000 }, { 2233, 0x0000 }, { 2233, 0xfffa }, + { 2247, 0x001f }, +}; + +static int +gb12345ext_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc >= 0x0100 && wc < 0x0270) + summary = &gb12345ext_uni2indx_page01[(wc>>4)-0x010]; + else if (wc >= 0x1e00 && wc < 0x1e40) + summary = &gb12345ext_uni2indx_page1e[(wc>>4)-0x1e0]; + else if (wc >= 0x2200 && wc < 0x2230) + summary = &gb12345ext_uni2indx_page22[(wc>>4)-0x220]; + else if (wc >= 0x4e00 && wc < 0x9fa0) + summary = &gb12345ext_uni2indx_page4e[(wc>>4)-0x4e0]; + else if (wc >= 0xfe00 && wc < 0xfe50) + summary = &gb12345ext_uni2indx_pagefe[(wc>>4)-0xfe0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = gb12345ext_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/gb18030.h b/libs/libiconv/lib/gb18030.h new file mode 100644 index 00000000..e9502e1b --- /dev/null +++ b/libs/libiconv/lib/gb18030.h @@ -0,0 +1,382 @@ +/* + * Copyright (C) 1999-2001, 2005 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * GB18030 + */ + +/* + * GB18030, as specified in the GB18030 standard, is an extension of GBK. + * + * In what follows, page numbers refer to the GB18030 standard (second + * printing). + * + * + * It consists of the following parts: + * + * One-byte range: + * ASCII p. 2 0x{00..7F} + * + * Two-byte range: + * GBK part 1 p. 10..12 0x{A1..A9}{A1..FE} + * GBK part 2 p. 13..36 0x{B0..F7}{A1..FE} + * GBK part 3 p. 37..52 0x{81..A0}{40..7E,80..FE} + * GBK part 4 p. 53..81 0x{AA..FE}{40..7E,80..A0} + * GBK part 5 p. 82 0x{A8..A9}{40..7E,80..A0} + * UDA part 1 p. 83..84 0x{AA..AF}{A1..FE} U+E000..U+E233 + * UDA part 2 p. 85..87 0x{F8..FE}{A1..FE} U+E234..U+E4C5 + * UDA part 3 p. 88..90 0x{A1..A7}{40..7E,80..A0} U+E4C6..U+E765 + * + * Four-byte range: + * BMP rest p. 94..283 0x{81..84}{30..39}{81..FE}{30..39} + * rest of U+0080..U+FFFF + * Planes 1-16 p. 5 0x{90..FE}{30..39}{81..FE}{30..39} + * U+10000..U+10FFFF + * + * To GBK part 1 were added: + * 1. 0xA2E3, 0xA8BF. + * 2. Characters mapped to the Unicode PUA + * 0xA2AB..0xA2B0 U+E766..U+E76B + * 0xA2E4 U+E76D + * 0xA2EF..0xA2F0 U+E76E..U+E76F + * 0xA2FD..0xA2FE U+E770..U+E771 + * 0xA4F4..0xA4FE U+E772..U+E77C + * 0xA5F7..0xA5FE U+E77D..U+E784 + * 0xA6B9..0xA6C0 U+E785..U+E78C + * 0xA6D9..0xA6DF [glyphs here!!] U+E78D..U+E793 + * 0xA6EC..0xA6ED [glyphs here!!] U+E794..U+E795 + * 0xA6F3 [glyphs here!!] U+E796 + * 0xA6F6..0xA6FE U+E797..U+E79F + * 0xA7C2..0xA7D0 U+E7A0..U+E7AE + * 0xA7F2..0xA7FE U+E7AF..U+E7BB + * 0xA8BC [glyphs here!!] U+E7C7 + * 0xA8C1..0xA8C4 U+E7C9..U+E7CC + * 0xA8EA..0xA8FE U+E7CD..U+E7E1 + * 0xA9A1..0xA9A3 U+E7FE..U+E800 + * 0xA9F0..0xA9FE U+E801..U+E80F + * + * To GBK part 2 were added: + * 3. Characters mapped to the Unicode PUA + * 0xD7FA..0xD7FE U+E810..0xE814 + * + * To GBK part 3 nothing was added. + * + * To GBK part 4 were added: + * 4. 0xFE{50,54..58,5A..60,62..65,68..6B,6E..75,77..7D,80..8F,92..9F}. + * 5. Characters mapped to the Unicode PUA + * 0xFE51..0xFE53 [glyphs here!!] U+E816..U+E818 + * 0xFE59 [glyphs here!!] U+E81E + * 0xFE61 [glyphs here!!] U+E826 + * 0xFE66..0xFE67 [glyphs here!!] U+E82B..U+E82C + * 0xFE6C..0xFE6D [glyphs here!!] U+E831..U+E832 + * 0xFE76 [glyphs here!!] U+E83B + * 0xFE7E [glyphs here!!] U+E843 + * 0xFE90..0xFE91 [glyphs here!!] U+E854..U+E855 + * 0xFEA0 [glyphs here!!] U+E864 + * + * To GBK part 5 were added: + * 6. 0xA98A..0xA995. + * 7. Characters mapped to the Unicode PUA + * 0xA896..0xA8A0 U+E7BC..U+E7C6 + * 0xA958 U+E7E2 + * 0xA95B U+E7E3 + * 0xA95D..0xA95F U+E7E4..U+E7E6 + * 0xA997..0xA9A0 U+E7F4..U+E7FD + * + * UDA part 1 contains the user-defined characters, mapped to the Unicode PUA + * U+E000..U+E233 in ascending order. + * + * UDA part 2 contains the user-defined characters, mapped to the Unicode PUA + * U+E234..U+E4C5 in ascending order. + * + * UDA part 3 contains the user-defined characters, mapped to the Unicode PUA + * U+E4C6..U+E765 in ascending order. + * + * The four-byte range 0x{81..84}{30..39}{81..FE}{30..39} + * contains the rest of the Unicode BMP in ascending order. + * Start: 0x81308130 = 0x0080 + * End: 0x8431A439 = 0xFFFF + * + * The four-byte range 0x{90..E3}{30..39}{81..FE}{30..39} + * contains the remaining 16 Unicode planes in Unicode order. + * Start: 0x90308130 = 0x010000 + * End: 0xE3329A35 = 0x10FFFF + * + * + * Unassigned Unicode characters are mapped. For example, + * U+173F = 0x8134BF35 (p. 120) + * U+2EFF = 0x81398B31 (p. 148) + * U+FFFE = 0x8431A438 (p. 283) + * + * + * The Unicode PUA (U+E000..U+F8FF) is mapped as follows: + * p. 83..84 0x{AA..AF}{A1..FE} U+E000..U+E233 + * p. 85..87 0x{F8..FE}{A1..FE} U+E234..U+E4C5 + * p. 88..90 0x{A1..A7}{40..7E,80..A0} U+E4C6..U+E765 + * p. 10 0xA2AB..0xA2B0 U+E766..U+E76B + * p. 255 0x8336C739 U+E76C + * p. 10 0xA2E4 U+E76D + * p. 10 0xA2EF..0xA2F0 U+E76E..U+E76F + * p. 10 0xA2FD..0xA2FE U+E770..U+E771 + * p. 11 0xA4F4..0xA4FE U+E772..U+E77C + * p. 11 0xA5F7..0xA5FE U+E77D..U+E784 + * p. 11 0xA6B9..0xA6C0 U+E785..U+E78C + * p. 11 0xA6D9..0xA6DF [glyphs here!!] U+E78D..U+E793 + * p. 11 0xA6EC..0xA6ED [glyphs here!!] U+E794..U+E795 + * p. 11 0xA6F3 [glyphs here!!] U+E796 + * p. 11 0xA6F6..0xA6FE U+E797..U+E79F + * p. 12 0xA7C2..0xA7D0 U+E7A0..U+E7AE + * p. 12 0xA7F2..0xA7FE U+E7AF..U+E7BB + * p. 82 0xA896..0xA8A0 U+E7BC..U+E7C6 + * p. 12 0xA8BC [glyphs here!!] U+E7C7 + * p. 255 0x8336C830 U+E7C8 + * p. 12 0xA8C1..0xA8C4 U+E7C9..U+E7CC + * p. 12 0xA8EA..0xA8FE U+E7CD..U+E7E1 + * p. 82 0xA958 U+E7E2 + * p. 82 0xA95B U+E7E3 + * p. 82 0xA95D..0xA95F U+E7E4..U+E7E6 + * p. 255 0x8336C831..0x8336C933 U+E7E7..U+E7F3 + * p. 82 0xA997..0xA9A0 U+E7F4..U+E7FD + * p. 12 0xA9A1..0xA9A3 U+E7FE..U+E800 + * p. 12 0xA9F0..0xA9FE U+E801..U+E80F + * p. 26 0xD7FA..0xD7FE U+E810..0xE814 + * p. 255 0x8336C934 U+E815 + * p. 81 0xFE51..0xFE53 [glyphs here!!] U+E816..U+E818 + * p. 255 0x8336C935..0x8336C939 U+E819..U+E81D + * p. 81 0xFE59 [glyphs here!!] U+E81E + * p. 255 0x8336CA30..0x8336CA36 U+E81F..U+E825 + * p. 81 0xFE61 [glyphs here!!] U+E826 + * p. 255 0x8336CA37..0x8336CB30 U+E827..U+E82A + * p. 81 0xFE66..0xFE67 [glyphs here!!] U+E82B..U+E82C + * p. 255 0x8336CB31..0x8336CB34 U+E82D..U+E830 + * p. 81 0xFE6C..0xFE6D [glyphs here!!] U+E831..U+E832 + * p. 255 0x8336CB35..0x8336CC32 U+E833..U+E83A + * p. 81 0xFE76 [glyphs here!!] U+E83B + * p. 255 0x8336CC33..0x8336CC39 U+E83C..U+E842 + * p. 81 0xFE7E [glyphs here!!] U+E843 + * p. 255 0x8336CD30..0x8336CE35 U+E844..U+E853 + * p. 81 0xFE90..0xFE91 [glyphs here!!] U+E854..U+E855 + * p. 255 0x8336CE36..0x8336CF39 U+E856..U+E863 + * p. 81 0xFEA0 [glyphs here!!] U+E864 + * p. 255..276 0x8336D030..0x84308130 U+E865..U+F8FF + * + * + * The Unicode surrogate area (U+D800..U+DFFF) is not mapped. (p. 255) + * + */ + +#include "gb18030ext.h" +#include "gb18030uni.h" + +static int +gb18030_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + int ret; + + /* Code set 0 (ASCII) */ + if (*s < 0x80) + return ascii_mbtowc(conv,pwc,s,n); + + /* Code set 1 (GBK extended) */ + ret = gbk_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + + ret = gb18030ext_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + + /* Code set 2 (remainder of Unicode U+0000..U+FFFF), including + User-defined characters, two-byte part of range U+E766..U+E864 */ + ret = gb18030uni_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + /* User-defined characters range U+E000..U+E765 */ + { + unsigned char c1 = s[0]; + if ((c1 >= 0xaa && c1 <= 0xaf) || (c1 >= 0xf8 && c1 <= 0xfe)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0xa1 && c2 <= 0xfe) { + *pwc = 0xe000 + 94 * (c1 >= 0xf8 ? c1 - 0xf2 : c1 - 0xaa) + (c2 - 0xa1); + return 2; + } + } else + return RET_TOOFEW(0); + } else if (c1 >= 0xa1 && c1 <= 0xa7) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x40 && c2 <= 0xa1 && c2 != 0x7f) { + *pwc = 0xe4c6 + 96 * (c1 - 0xa1) + c2 - (c2 >= 0x80 ? 0x41 : 0x40); + return 2; + } + } else + return RET_TOOFEW(0); + } + } + + /* Code set 3 (Unicode U+10000..U+10FFFF) */ + { + unsigned char c1 = s[0]; + if (c1 >= 0x90 && c1 <= 0xe3) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x30 && c2 <= 0x39) { + if (n >= 3) { + unsigned char c3 = s[2]; + if (c3 >= 0x81 && c3 <= 0xfe) { + if (n >= 4) { + unsigned char c4 = s[3]; + if (c4 >= 0x30 && c4 <= 0x39) { + unsigned int i = (((c1 - 0x90) * 10 + (c2 - 0x30)) * 126 + (c3 - 0x81)) * 10 + (c4 - 0x30); + if (i >= 0 && i < 0x100000) { + *pwc = (ucs4_t) (0x10000 + i); + return 4; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; + } +} + +static const unsigned short gb18030_pua2charset[32*3] = { +/* Unicode range GB18030 range */ + 0xe766, 0xe76b, 0xa2ab, /*.. 0xa2b0, */ + 0xe76d, 0xe76d, 0xa2e4, + 0xe76e, 0xe76f, 0xa2ef, /*.. 0xa2f0, */ + 0xe770, 0xe771, 0xa2fd, /*.. 0xa2fe, */ + 0xe772, 0xe77c, 0xa4f4, /*.. 0xa4fe, */ + 0xe77d, 0xe784, 0xa5f7, /*.. 0xa5fe, */ + 0xe785, 0xe78c, 0xa6b9, /*.. 0xa6c0, */ + 0xe78d, 0xe793, 0xa6d9, /*.. 0xa6df, */ + 0xe794, 0xe795, 0xa6ec, /*.. 0xa6ed, */ + 0xe796, 0xe796, 0xa6f3, + 0xe797, 0xe79f, 0xa6f6, /*.. 0xa6fe, */ + 0xe7a0, 0xe7ae, 0xa7c2, /*.. 0xa7d0, */ + 0xe7af, 0xe7bb, 0xa7f2, /*.. 0xa7fe, */ + 0xe7bc, 0xe7c6, 0xa896, /*.. 0xa8a0, */ + 0xe7c7, 0xe7c7, 0xa8bc, + 0xe7c9, 0xe7cc, 0xa8c1, /*.. 0xa8c4, */ + 0xe7cd, 0xe7e1, 0xa8ea, /*.. 0xa8fe, */ + 0xe7e2, 0xe7e2, 0xa958, + 0xe7e3, 0xe7e3, 0xa95b, + 0xe7e4, 0xe7e6, 0xa95d, /*.. 0xa95f, */ + 0xe7f4, 0xe800, 0xa997, /*.. 0xa9a3, */ + 0xe801, 0xe80f, 0xa9f0, /*.. 0xa9fe, */ + 0xe810, 0xe814, 0xd7fa, /*.. 0xd7fe, */ + 0xe816, 0xe818, 0xfe51, /*.. 0xfe53, */ + 0xe81e, 0xe81e, 0xfe59, + 0xe826, 0xe826, 0xfe61, + 0xe82b, 0xe82c, 0xfe66, /*.. 0xfe67, */ + 0xe831, 0xe832, 0xfe6c, /*.. 0xfe6d, */ + 0xe83b, 0xe83b, 0xfe76, + 0xe843, 0xe843, 0xfe7e, + 0xe854, 0xe855, 0xfe90, /*.. 0xfe91, */ + 0xe864, 0xe864, 0xfea0, +}; + +static int +gb18030_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + int ret; + + /* Code set 0 (ASCII) */ + ret = ascii_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + /* Code set 1 (GBK extended) */ + ret = gbk_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + ret = gb18030ext_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + /* Code set 2 (remainder of Unicode U+0000..U+FFFF) */ + if (wc >= 0xe000 && wc <= 0xe864) { + if (n >= 2) { + if (wc < 0xe766) { + /* User-defined characters range U+E000..U+E765 */ + if (wc < 0xe4c6) { + unsigned int i = wc - 0xe000; + r[1] = (i % 94) + 0xa1; i = i / 94; + r[0] = (i < 6 ? i + 0xaa : i + 0xf2); + return 2; + } else { + unsigned int i = wc - 0xe4c6; + r[0] = (i / 96) + 0xa1; i = i % 96; + r[1] = i + (i >= 0x3f ? 0x41 : 0x40); + return 2; + } + } else { + /* User-defined characters, two-byte part of range U+E766..U+E864 */ + unsigned int k1 = 0; + unsigned int k2 = 32; + /* Invariant: We know that if wc occurs in Unicode interval in + gb18030_pua2charset, it does so at a k with k1 <= k < k2. */ + while (k1 < k2) { + unsigned int k = (k1 + k2) / 2; + if (wc < gb18030_pua2charset[k*3+0]) + k2 = k; + else if (wc > gb18030_pua2charset[k*3+1]) + k1 = k + 1; + else { + unsigned short c = + gb18030_pua2charset[k*3+2] + (wc - gb18030_pua2charset[k*3+0]); + r[0] = (c >> 8); + r[1] = (c & 0xff); + return 2; + } + } + } + } else + return RET_TOOSMALL; + } + ret = gb18030uni_wctomb(conv,r,wc,n); + if (ret != RET_ILUNI) + return ret; + + /* Code set 3 (Unicode U+10000..U+10FFFF) */ + if (n >= 4) { + if (wc >= 0x10000 && wc < 0x110000) { + unsigned int i = wc - 0x10000; + r[3] = (i % 10) + 0x30; i = i / 10; + r[2] = (i % 126) + 0x81; i = i / 126; + r[1] = (i % 10) + 0x30; i = i / 10; + r[0] = i + 0x90; + return 4; + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/gb18030ext.h b/libs/libiconv/lib/gb18030ext.h new file mode 100644 index 00000000..5e59419b --- /dev/null +++ b/libs/libiconv/lib/gb18030ext.h @@ -0,0 +1,328 @@ +/* + * Copyright (C) 1999-2001, 2005, 2011 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * GB18030 two-byte extension + */ + +static const unsigned short gb18030ext_2uni_pagea9[13] = { + /* 0xa9 */ + 0x303e, 0x2ff0, 0x2ff1, 0x2ff2, 0x2ff3, 0x2ff4, 0x2ff5, 0x2ff6, + 0x2ff7, 0x2ff8, 0x2ff9, 0x2ffa, 0x2ffb, +}; +static const unsigned int gb18030ext_2uni_pagefe[96] = { + /* 0xfe */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x2e81, 0x20087, 0x20089, 0x200cc, 0x2e84, 0x3473, 0x3447, 0x2e88, + 0x2e8b, 0x9fb4, 0x359e, 0x361a, 0x360e, 0x2e8c, 0x2e97, 0x396e, + 0x3918, 0x9fb5, 0x39cf, 0x39df, 0x3a73, 0x39d0, 0x9fb6, 0x9fb7, + 0x3b4e, 0x3c6e, 0x3ce0, 0x2ea7, 0x215d7, 0x9fb8, 0x2eaa, 0x4056, + 0x415f, 0x2eae, 0x4337, 0x2eb3, 0x2eb6, 0x2eb7, 0x2298f, 0x43b1, + 0x43ac, 0x2ebb, 0x43dd, 0x44d6, 0x4661, 0x464c, 0x9fb9, 0x4723, + 0x4729, 0x477c, 0x478d, 0x2eca, 0x4947, 0x497a, 0x497d, 0x4982, + 0x4983, 0x4985, 0x4986, 0x499f, 0x499b, 0x49b7, 0x49b6, 0x9fba, + 0x241fe, 0x4ca3, 0x4c9f, 0x4ca0, 0x4ca1, 0x4c77, 0x4ca2, 0x4d13, + 0x4d14, 0x4d15, 0x4d16, 0x4d17, 0x4d18, 0x4d19, 0x4dae, 0x9fbb, +}; + +static int +gb18030ext_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 == 0xa2) || (c1 >= 0xa4 && c1 <= 0xa9) || (c1 == 0xd7) || (c1 == 0xfe)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0x80 && c2 < 0xff)) { + unsigned int i = 190 * (c1 - 0x81) + (c2 - (c2 >= 0x80 ? 0x41 : 0x40)); + unsigned int wc = 0xfffd; + switch (c1) { + case 0xa2: + if (i >= 6376 && i <= 6381) /* 0xA2AB..0xA2B0 */ + wc = 0xe766 + (i - 6376); + else if (i == 6432) /* 0xA2E3 */ + wc = 0x20ac; + else if (i == 6433) /* 0xA2E4 */ + wc = 0xe76d; + else if (i >= 6444 && i <= 6445) /* 0xA2EF..0xA2F0 */ + wc = 0xe76e + (i - 6444); + else if (i >= 6458 && i <= 6459) /* 0xA2FD..0xA2FE */ + wc = 0xe770 + (i - 6458); + break; + case 0xa4: + if (i >= 6829 && i <= 6839) /* 0xA4F4..0xA4FE */ + wc = 0xe772 + (i - 6829); + break; + case 0xa5: + if (i >= 7022 && i <= 7029) /* 0xA5F7..0xA5FE */ + wc = 0xe77d + (i - 7022); + break; + case 0xa6: + if (i >= 7150 && i <= 7157) /* 0xA6B9..0xA6C0 */ + wc = 0xe785 + (i - 7150); + else if (i >= 7183 && i <= 7184) /* 0xA6DA..0xA6DB */ + wc = 0xfe12 - (i - 7183); + else if (i >= 7182 && i <= 7190) /* 0xA6D9..0xA6DF */ + wc = 0xfe10 + (i - 7182); + else if (i >= 7201 && i <= 7202) /* 0xA6EC..0xA6ED */ + wc = 0xfe17 + (i - 7201); + else if (i == 7208) /* 0xA6F3 */ + wc = 0xfe19; + else if (i >= 7211 && i <= 7219) /* 0xA6F6..0xA6FE */ + wc = 0xe797 + (i - 7211); + break; + case 0xa7: + if (i >= 7349 && i <= 7363) /* 0xA7C2..0xA7D0 */ + wc = 0xe7a0 + (i - 7349); + else if (i >= 7397 && i <= 7409) /* 0xA7F2..0xA7FE */ + wc = 0xe7af + (i - 7397); + break; + case 0xa8: + if (i >= 7495 && i <= 7505) /* 0xA896..0xA8A0 */ + wc = 0xe7bc + (i - 7495); + else if (i == 7533) /* 0xA8BC */ + wc = 0x1e3f; + else if (i == 7536) /* 0xA8BF */ + wc = 0x01f9; + else if (i >= 7538 && i <= 7541) /* 0xA8C1..0xA8C4 */ + wc = 0xe7c9 + (i - 7538); + else if (i >= 7579 && i <= 7599) /* 0xA8EA..0xA8FE */ + wc = 0xe7cd + (i - 7579); + break; + case 0xa9: + if (i == 7624) /* 0xA958 */ + wc = 0xe7e2; + else if (i == 7627) /* 0xA95B */ + wc = 0xe7e3; + else if (i >= 7629 && i <= 7631) /* 0xA95D..0xA95F */ + wc = 0xe7e4 + (i - 7629); + else if (i >= 7672 && i < 7685) /* 0xA989..0xA995 */ + wc = gb18030ext_2uni_pagea9[i-7672]; + else if (i >= 7686 && i <= 7698) /* 0xA997..0xA9A3 */ + wc = 0xe7f4 + (i - 7686); + else if (i >= 7775 && i <= 7789) /* 0xA9F0..0xA9FE */ + wc = 0xe801 + (i - 7775); + break; + case 0xd7: + if (i >= 16525 && i <= 16529) /* 0xD7FA..0xD7FE */ + wc = 0xe810 + (i - 16525); + break; + case 0xfe: + if (i < 23846) + wc = gb18030ext_2uni_pagefe[i-23750]; + break; + default: + break; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short gb18030ext_page2e[80] = { + 0x0000, 0xfe50, 0x0000, 0x0000, 0xfe54, 0x0000, 0x0000, 0x0000, /*0x80-0x87*/ + 0xfe57, 0x0000, 0x0000, 0xfe58, 0xfe5d, 0x0000, 0x0000, 0x0000, /*0x88-0x8f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe5e, /*0x90-0x97*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x98-0x9f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe6b, /*0xa0-0xa7*/ + 0x0000, 0x0000, 0xfe6e, 0x0000, 0x0000, 0x0000, 0xfe71, 0x0000, /*0xa8-0xaf*/ + 0x0000, 0x0000, 0x0000, 0xfe73, 0x0000, 0x0000, 0xfe74, 0xfe75, /*0xb0-0xb7*/ + 0x0000, 0x0000, 0x0000, 0xfe79, 0x0000, 0x0000, 0x0000, 0x0000, /*0xb8-0xbf*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xc0-0xc7*/ + 0x0000, 0x0000, 0xfe84, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xc8-0xcf*/ +}; +static const unsigned short gb18030ext_page2f[16] = { + 0xa98a, 0xa98b, 0xa98c, 0xa98d, 0xa98e, 0xa98f, 0xa990, 0xa991, /*0xf0-0xf7*/ + 0xa992, 0xa993, 0xa994, 0xa995, 0x0000, 0x0000, 0x0000, 0x0000, /*0xf8-0xff*/ +}; +static const unsigned short gb18030ext_page34[56] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe56, /*0x40-0x47*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x48-0x4f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x50-0x57*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x58-0x5f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x60-0x67*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x68-0x6f*/ + 0x0000, 0x0000, 0x0000, 0xfe55, 0x0000, 0x0000, 0x0000, 0x0000, /*0x70-0x77*/ +}; +static const unsigned short gb18030ext_page36[24] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe5c, 0x0000, /*0x08-0x0f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x10-0x17*/ + 0x0000, 0x0000, 0xfe5b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x18-0x1f*/ +}; +static const unsigned short gb18030ext_page39[24] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe62, /*0xc8-0xcf*/ + 0xfe65, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xd0-0xd7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe63, /*0xd8-0xdf*/ +}; +static const unsigned short gb18030ext_page43[56] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0xfe78, 0x0000, 0x0000, 0x0000, /*0xa8-0xaf*/ + 0x0000, 0xfe77, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xb0-0xb7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xb8-0xbf*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xc0-0xc7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xc8-0xcf*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xd0-0xd7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe7a, 0x0000, 0x0000, /*0xd8-0xdf*/ +}; +static const unsigned short gb18030ext_page46[32] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0xfe7d, 0x0000, 0x0000, 0x0000, /*0x48-0x4f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x50-0x57*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x58-0x5f*/ + 0x0000, 0xfe7c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x60-0x67*/ +}; +static const unsigned short gb18030ext_page47_1[16] = { + 0x0000, 0x0000, 0x0000, 0xfe80, 0x0000, 0x0000, 0x0000, 0x0000, /*0x20-0x27*/ + 0x0000, 0xfe81, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x28-0x2f*/ +}; +static const unsigned short gb18030ext_page47_2[24] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0xfe82, 0x0000, 0x0000, 0x0000, /*0x78-0x7f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x80-0x87*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe83, 0x0000, 0x0000, /*0x88-0x8f*/ +}; +static const unsigned short gb18030ext_page49[120] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe85, /*0x40-0x47*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x48-0x4f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x50-0x57*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x58-0x5f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x60-0x67*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x68-0x6f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x70-0x77*/ + 0x0000, 0x0000, 0xfe86, 0x0000, 0x0000, 0xfe87, 0x0000, 0x0000, /*0x78-0x7f*/ + 0x0000, 0x0000, 0xfe88, 0xfe89, 0x0000, 0xfe8a, 0xfe8b, 0x0000, /*0x80-0x87*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x88-0x8f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x90-0x97*/ + 0x0000, 0x0000, 0x0000, 0xfe8d, 0x0000, 0x0000, 0x0000, 0xfe8c, /*0x98-0x9f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xa0-0xa7*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0xa8-0xaf*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe8f, 0xfe8e, /*0xb0-0xb7*/ +}; +static const unsigned short gb18030ext_page4c[56] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe96, /*0x70-0x77*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x78-0x7f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x80-0x87*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x88-0x8f*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x90-0x97*/ + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xfe93, /*0x98-0x9f*/ + 0xfe94, 0xfe95, 0xfe97, 0xfe92, 0x0000, 0x0000, 0x0000, 0x0000, /*0xa0-0xa7*/ +}; +static const unsigned short gb18030ext_page4d[16] = { + 0x0000, 0x0000, 0x0000, 0xfe98, 0xfe99, 0xfe9a, 0xfe9b, 0xfe9c, /*0x10-0x17*/ + 0xfe9d, 0xfe9e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x18-0x1f*/ +}; +static const unsigned short gb18030ext_page9f[16] = { + 0x0000, 0x0000, 0x0000, 0x0000, 0xfe59, 0xfe61, 0xfe66, 0xfe67, /*0xb0-0xb7*/ + 0xfe6d, 0xfe7e, 0xfe90, 0xfea0, 0x0000, 0x0000, 0x0000, 0x0000, /*0xb8-0xbf*/ +}; +static const unsigned short gb18030ext_pagefe[16] = { + 0xa6d9, 0xa6db, 0xa6da, 0xa6dc, 0xa6dd, 0xa6de, 0xa6df, 0xa6ec, /*0x10-0x17*/ + 0xa6ed, 0xa6f3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, /*0x18-0x1f*/ +}; + +static int +gb18030ext_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + unsigned short c = 0; + if (wc == 0x01f9) + c = 0xa8bf; + else if (wc == 0x1e3f) + c = 0xa8bc; + else if (wc == 0x20ac) + c = 0xa2e3; + else if (wc >= 0x2e80 && wc < 0x2ed0) + c = gb18030ext_page2e[wc-0x2e80]; + else if (wc >= 0x2ff0 && wc < 0x3000) + c = gb18030ext_page2f[wc-0x2ff0]; + else if (wc == 0x303e) + c = 0xa989; + else if (wc >= 0x3440 && wc < 0x3478) + c = gb18030ext_page34[wc-0x3440]; + else if (wc == 0x359e) + c = 0xfe5a; + else if (wc >= 0x3608 && wc < 0x3620) + c = gb18030ext_page36[wc-0x3608]; + else if (wc == 0x3918) + c = 0xfe60; + else if (wc == 0x396e) + c = 0xfe5f; + else if (wc >= 0x39c8 && wc < 0x39e0) + c = gb18030ext_page39[wc-0x39c8]; + else if (wc == 0x3a73) + c = 0xfe64; + else if (wc == 0x3b4e) + c = 0xfe68; + else if (wc == 0x3c6e) + c = 0xfe69; + else if (wc == 0x3ce0) + c = 0xfe6a; + else if (wc == 0x4056) + c = 0xfe6f; + else if (wc == 0x415f) + c = 0xfe70; + else if (wc == 0x4337) + c = 0xfe72; + else if (wc >= 0x43a8 && wc < 0x43e0) + c = gb18030ext_page43[wc-0x43a8]; + else if (wc == 0x44d6) + c = 0xfe7b; + else if (wc >= 0x4648 && wc < 0x4668) + c = gb18030ext_page46[wc-0x4648]; + else if (wc >= 0x4720 && wc < 0x4730) + c = gb18030ext_page47_1[wc-0x4720]; + else if (wc >= 0x4778 && wc < 0x4790) + c = gb18030ext_page47_2[wc-0x4778]; + else if (wc >= 0x4940 && wc < 0x49b8) + c = gb18030ext_page49[wc-0x4940]; + else if (wc >= 0x4c70 && wc < 0x4ca8) + c = gb18030ext_page4c[wc-0x4c70]; + else if (wc >= 0x4d10 && wc < 0x4d20) + c = gb18030ext_page4d[wc-0x4d10]; + else if (wc == 0x4dae) + c = 0xfe9f; + else if (wc >= 0x9fb4 && wc < 0x9fbc) + c = gb18030ext_page9f[wc-0x9fb0]; + else if (wc >= 0xfe10 && wc < 0xfe1a) + c = gb18030ext_pagefe[wc-0xfe10]; + else if (wc == 0x20087) + c = 0xfe51; + else if (wc == 0x20089) + c = 0xfe52; + else if (wc == 0x200cc) + c = 0xfe53; + else if (wc == 0x215d7) + c = 0xfe6c; + else if (wc == 0x2298f) + c = 0xfe76; + else if (wc == 0x241fe) + c = 0xfe91; + if (c != 0) { + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/gb18030uni.h b/libs/libiconv/lib/gb18030uni.h new file mode 100644 index 00000000..bea31e51 --- /dev/null +++ b/libs/libiconv/lib/gb18030uni.h @@ -0,0 +1,249 @@ +/* + * Copyright (C) 1999-2001, 2005 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * GB18030 four-byte extension + */ + +static const unsigned short gb18030uni_charset2uni_ranges[412] = { + 0x0000, 0x0023, 0x0024, 0x0025, 0x0026, 0x002c, 0x002d, 0x0031, + 0x0032, 0x0050, 0x0051, 0x0058, 0x0059, 0x005e, 0x005f, 0x005f, + 0x0060, 0x0063, 0x0064, 0x0066, 0x0067, 0x0067, 0x0068, 0x0068, + 0x0069, 0x006c, 0x006d, 0x007d, 0x007e, 0x0084, 0x0085, 0x0093, + 0x0094, 0x00ab, 0x00ac, 0x00ae, 0x00af, 0x00b2, 0x00b3, 0x00cf, + 0x00d0, 0x0131, 0x0132, 0x0132, 0x0133, 0x0133, 0x0134, 0x0134, + 0x0135, 0x0135, 0x0136, 0x0136, 0x0137, 0x0137, 0x0138, 0x0138, + 0x0139, 0x0154, 0x0155, 0x01ab, 0x01ac, 0x01ba, 0x01bb, 0x021f, + 0x0220, 0x0220, 0x0221, 0x022d, 0x022e, 0x02e4, 0x02e5, 0x02e5, + 0x02e6, 0x02ec, 0x02ed, 0x02ed, 0x02ee, 0x0324, 0x0325, 0x0332, + 0x0333, 0x0333, 0x0334, 0x1ef1, 0x1ef2, 0x1ef3, 0x1ef4, 0x1ef4, + 0x1ef5, 0x1ef6, 0x1ef7, 0x1efd, 0x1efe, 0x1f06, 0x1f07, 0x1f07, + 0x1f08, 0x1f08, 0x1f09, 0x1f0d, 0x1f0e, 0x1f7d, 0x1f7e, 0x1fd3, + 0x1fd4, 0x1fd4, 0x1fd5, 0x1fd7, 0x1fd8, 0x1fe3, 0x1fe4, 0x1fed, + 0x1fee, 0x202b, 0x202c, 0x202f, 0x2030, 0x2045, 0x2046, 0x2047, + 0x2048, 0x20b5, 0x20b6, 0x20bb, 0x20bc, 0x20bc, 0x20bd, 0x20bf, + 0x20c0, 0x20c3, 0x20c4, 0x20c5, 0x20c6, 0x20c7, 0x20c8, 0x20c8, + 0x20c9, 0x20c9, 0x20ca, 0x20cb, 0x20cc, 0x20d0, 0x20d1, 0x20d5, + 0x20d6, 0x20df, 0x20e0, 0x20e2, 0x20e3, 0x20e7, 0x20e8, 0x20f4, + 0x20f5, 0x20f6, 0x20f7, 0x20fc, 0x20fd, 0x2121, 0x2122, 0x2124, + 0x2125, 0x212f, 0x2130, 0x2148, 0x2149, 0x219a, 0x219b, 0x22e7, + 0x22e8, 0x22f1, 0x22f2, 0x2355, 0x2356, 0x2359, 0x235a, 0x2366, + 0x2367, 0x2369, 0x236a, 0x2373, 0x2374, 0x2383, 0x2384, 0x238b, + 0x238c, 0x2393, 0x2394, 0x2396, 0x2397, 0x2398, 0x2399, 0x23aa, + 0x23ab, 0x23c9, 0x23ca, 0x23cb, 0x23cc, 0x2401, 0x2402, 0x2402, + 0x2403, 0x2c40, 0x2c41, 0x2c42, 0x2c43, 0x2c45, 0x2c46, 0x2c47, + 0x2c48, 0x2c51, 0x2c52, 0x2c60, 0x2c61, 0x2c62, 0x2c63, 0x2c65, + 0x2c66, 0x2c69, 0x2c6a, 0x2c6b, 0x2c6c, 0x2c6e, 0x2c6f, 0x2c7c, + 0x2c7d, 0x2da1, 0x2da2, 0x2da5, 0x2da6, 0x2da6, 0x2da7, 0x2dab, + 0x2dac, 0x2dad, 0x2dae, 0x2dc1, 0x2dc2, 0x2dc3, 0x2dc4, 0x2dca, + 0x2dcb, 0x2dcc, 0x2dcd, 0x2dd1, 0x2dd2, 0x2dd7, 0x2dd8, 0x2ecd, + 0x2ece, 0x2ed4, 0x2ed5, 0x2f45, 0x2f46, 0x302f, 0x3030, 0x303b, + 0x303c, 0x303d, 0x303e, 0x305f, 0x3060, 0x3068, 0x3069, 0x306a, + 0x306b, 0x306c, 0x306d, 0x30dd, 0x30de, 0x3108, 0x3109, 0x3232, + 0x3233, 0x32a1, 0x32a2, 0x32ac, 0x32ad, 0x35a9, 0x35aa, 0x35fe, + 0x35ff, 0x365e, 0x365f, 0x366c, 0x366d, 0x36ff, 0x3700, 0x37d9, + 0x37da, 0x38f8, 0x38f9, 0x3969, 0x396a, 0x3cde, 0x3cdf, 0x3de6, + 0x3de7, 0x3fbd, 0x3fbe, 0x4031, 0x4032, 0x4035, 0x4036, 0x4060, + 0x4061, 0x4158, 0x4159, 0x42cd, 0x42ce, 0x42e1, 0x42e2, 0x43a2, + 0x43a3, 0x43a7, 0x43a8, 0x43f9, 0x43fa, 0x4409, 0x440a, 0x45c2, + 0x45c3, 0x45f4, 0x45f5, 0x45f6, 0x45f7, 0x45fa, 0x45fb, 0x45fb, + 0x45fc, 0x460f, 0x4610, 0x4612, 0x4613, 0x4628, 0x4629, 0x48e7, + 0x48e8, 0x490e, 0x490f, 0x497d, 0x497e, 0x4a11, 0x4a12, 0x4a62, + 0x4a63, 0x82bc, + 0x82bd, 0x82bd, 0x82be, 0x82be, 0x82bf, 0x82cb, + 0x82cc, 0x82cc, 0x82cd, 0x82d1, 0x82d2, 0x82d8, 0x82d9, 0x82dc, + 0x82dd, 0x82e0, 0x82e1, 0x82e8, 0x82e9, 0x82ef, 0x82f0, 0x82ff, + 0x8300, 0x830d, + 0x830e, 0x93d4, 0x93d5, 0x9420, 0x9421, 0x943b, + 0x943c, 0x948c, 0x948d, 0x9495, 0x9496, 0x94af, 0x94b0, 0x94b0, + 0x94b1, 0x94b1, 0x94b2, 0x94b4, 0x94b5, 0x94ba, 0x94bb, 0x94bb, + 0x94bc, 0x94bd, 0x94be, 0x98c3, 0x98c4, 0x98c4, 0x98c5, 0x98c8, + 0x98c9, 0x98c9, 0x98ca, 0x98ca, 0x98cb, 0x98cb, 0x98cc, 0x9960, + 0x9961, 0x99e1, 0x99e2, 0x99fb +}; + +static const unsigned short gb18030uni_uni2charset_ranges[412] = { + 0x0080, 0x00a3, 0x00a5, 0x00a6, 0x00a9, 0x00af, 0x00b2, 0x00b6, + 0x00b8, 0x00d6, 0x00d8, 0x00df, 0x00e2, 0x00e7, 0x00eb, 0x00eb, + 0x00ee, 0x00f1, 0x00f4, 0x00f6, 0x00f8, 0x00f8, 0x00fb, 0x00fb, + 0x00fd, 0x0100, 0x0102, 0x0112, 0x0114, 0x011a, 0x011c, 0x012a, + 0x012c, 0x0143, 0x0145, 0x0147, 0x0149, 0x014c, 0x014e, 0x016a, + 0x016c, 0x01cd, 0x01cf, 0x01cf, 0x01d1, 0x01d1, 0x01d3, 0x01d3, + 0x01d5, 0x01d5, 0x01d7, 0x01d7, 0x01d9, 0x01d9, 0x01db, 0x01db, + 0x01dd, 0x01f8, 0x01fa, 0x0250, 0x0252, 0x0260, 0x0262, 0x02c6, + 0x02c8, 0x02c8, 0x02cc, 0x02d8, 0x02da, 0x0390, 0x03a2, 0x03a2, + 0x03aa, 0x03b0, 0x03c2, 0x03c2, 0x03ca, 0x0400, 0x0402, 0x040f, + 0x0450, 0x0450, 0x0452, 0x200f, 0x2011, 0x2012, 0x2017, 0x2017, + 0x201a, 0x201b, 0x201e, 0x2024, 0x2027, 0x202f, 0x2031, 0x2031, + 0x2034, 0x2034, 0x2036, 0x203a, 0x203c, 0x20ab, 0x20ad, 0x2102, + 0x2104, 0x2104, 0x2106, 0x2108, 0x210a, 0x2115, 0x2117, 0x2120, + 0x2122, 0x215f, 0x216c, 0x216f, 0x217a, 0x218f, 0x2194, 0x2195, + 0x219a, 0x2207, 0x2209, 0x220e, 0x2210, 0x2210, 0x2212, 0x2214, + 0x2216, 0x2219, 0x221b, 0x221c, 0x2221, 0x2222, 0x2224, 0x2224, + 0x2226, 0x2226, 0x222c, 0x222d, 0x222f, 0x2233, 0x2238, 0x223c, + 0x223e, 0x2247, 0x2249, 0x224b, 0x224d, 0x2251, 0x2253, 0x225f, + 0x2262, 0x2263, 0x2268, 0x226d, 0x2270, 0x2294, 0x2296, 0x2298, + 0x229a, 0x22a4, 0x22a6, 0x22be, 0x22c0, 0x2311, 0x2313, 0x245f, + 0x246a, 0x2473, 0x249c, 0x24ff, 0x254c, 0x254f, 0x2574, 0x2580, + 0x2590, 0x2592, 0x2596, 0x259f, 0x25a2, 0x25b1, 0x25b4, 0x25bb, + 0x25be, 0x25c5, 0x25c8, 0x25ca, 0x25cc, 0x25cd, 0x25d0, 0x25e1, + 0x25e6, 0x2604, 0x2607, 0x2608, 0x260a, 0x263f, 0x2641, 0x2641, + 0x2643, 0x2e80, 0x2e82, 0x2e83, 0x2e85, 0x2e87, 0x2e89, 0x2e8a, + 0x2e8d, 0x2e96, 0x2e98, 0x2ea6, 0x2ea8, 0x2ea9, 0x2eab, 0x2ead, + 0x2eaf, 0x2eb2, 0x2eb4, 0x2eb5, 0x2eb8, 0x2eba, 0x2ebc, 0x2ec9, + 0x2ecb, 0x2fef, 0x2ffc, 0x2fff, 0x3004, 0x3004, 0x3018, 0x301c, + 0x301f, 0x3020, 0x302a, 0x303d, 0x303f, 0x3040, 0x3094, 0x309a, + 0x309f, 0x30a0, 0x30f7, 0x30fb, 0x30ff, 0x3104, 0x312a, 0x321f, + 0x322a, 0x3230, 0x3232, 0x32a2, 0x32a4, 0x338d, 0x3390, 0x339b, + 0x339f, 0x33a0, 0x33a2, 0x33c3, 0x33c5, 0x33cd, 0x33cf, 0x33d0, + 0x33d3, 0x33d4, 0x33d6, 0x3446, 0x3448, 0x3472, 0x3474, 0x359d, + 0x359f, 0x360d, 0x360f, 0x3619, 0x361b, 0x3917, 0x3919, 0x396d, + 0x396f, 0x39ce, 0x39d1, 0x39de, 0x39e0, 0x3a72, 0x3a74, 0x3b4d, + 0x3b4f, 0x3c6d, 0x3c6f, 0x3cdf, 0x3ce1, 0x4055, 0x4057, 0x415e, + 0x4160, 0x4336, 0x4338, 0x43ab, 0x43ad, 0x43b0, 0x43b2, 0x43dc, + 0x43de, 0x44d5, 0x44d7, 0x464b, 0x464d, 0x4660, 0x4662, 0x4722, + 0x4724, 0x4728, 0x472a, 0x477b, 0x477d, 0x478c, 0x478e, 0x4946, + 0x4948, 0x4979, 0x497b, 0x497c, 0x497e, 0x4981, 0x4984, 0x4984, + 0x4987, 0x499a, 0x499c, 0x499e, 0x49a0, 0x49b5, 0x49b8, 0x4c76, + 0x4c78, 0x4c9e, 0x4ca4, 0x4d12, 0x4d1a, 0x4dad, 0x4daf, 0x4dff, + 0x9fa6, 0xd7ff, + 0xe76c, 0xe76c, 0xe7c8, 0xe7c8, 0xe7e7, 0xe7f3, + 0xe815, 0xe815, 0xe819, 0xe81d, 0xe81f, 0xe825, 0xe827, 0xe82a, + 0xe82d, 0xe830, 0xe833, 0xe83a, 0xe83c, 0xe842, 0xe844, 0xe853, + 0xe856, 0xe863, + 0xe865, 0xf92b, 0xf92d, 0xf978, 0xf97a, 0xf994, + 0xf996, 0xf9e6, 0xf9e8, 0xf9f0, 0xf9f2, 0xfa0b, 0xfa10, 0xfa10, + 0xfa12, 0xfa12, 0xfa15, 0xfa17, 0xfa19, 0xfa1e, 0xfa22, 0xfa22, + 0xfa25, 0xfa26, 0xfa2a, 0xfe2f, 0xfe32, 0xfe32, 0xfe45, 0xfe48, + 0xfe53, 0xfe53, 0xfe58, 0xfe58, 0xfe67, 0xfe67, 0xfe6c, 0xff00, + 0xff5f, 0xffdf, 0xffe6, 0xffff +}; + +static const unsigned short gb18030uni_ranges[206] = { + 128, 129, 131, 133, 134, 135, 137, 140, + 142, 144, 145, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 171, 172, 189, 196, 213, 220, 221, + 285, 286, 287, 291, 293, 295, 297, 298, + 300, 301, 302, 303, 304, 305, 306, 307, + 308, 320, 330, 334, 338, 339, 340, 341, + 342, 343, 347, 348, 349, 354, 355, 359, + 360, 361, 362, 363, 365, 369, 371, 372, + 373, 374, 375, 376, 386, 426, 502, 538, + 553, 556, 558, 560, 562, 564, 565, 567, + 571, 573, 574, 575, 576, 577, 578, 579, + 581, 582, 583, 584, 585, 586, 588, 589, + 590, 602, 606, 625, 627, 636, 637, 720, + 724, 810, 813, 850, 860, 861, 862, 864, + 867, 868, 869, 870, 872, 873, 874, 875, + 876, 877, 878, 879, 880, 882, 883, 884, + 885, 886, 887, 888, 889, 890, 891, 892, + 893, 894, 895, 896, 897, 898, 899, 900, + 901, 902, 903, 905, 907, 908, 909, 911, + 912, 917, 924, 925, 21827, + 25775, 25866, 25896, + 25929, 25932, 25933, 25934, 25936, 25938, 25939, 25940, + 25942, + 25943, 25944, 25945, 25946, 25947, 25948, 25952, + 25953, 25955, 25956, 25959, 25961, 25964, 25966, 25984, + 25994, 25998, 26012, 26016, 26110, 26116 +}; + +static int +gb18030uni_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if (c1 >= 0x81 && c1 <= 0x84) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x30 && c2 <= 0x39) { + if (n >= 3) { + unsigned char c3 = s[2]; + if (c3 >= 0x81 && c3 <= 0xfe) { + if (n >= 4) { + unsigned char c4 = s[3]; + if (c4 >= 0x30 && c4 <= 0x39) { + unsigned int i = (((c1 - 0x81) * 10 + (c2 - 0x30)) * 126 + (c3 - 0x81)) * 10 + (c4 - 0x30); + if (i >= 0 && i <= 39419) { + unsigned int k1 = 0; + unsigned int k2 = 205; + while (k1 < k2) { + unsigned int k = (k1 + k2) / 2; + if (i <= gb18030uni_charset2uni_ranges[2*k+1]) + k2 = k; + else if (i >= gb18030uni_charset2uni_ranges[2*k+2]) + k1 = k + 1; + else + return RET_ILSEQ; + } + { + unsigned int diff = gb18030uni_ranges[k1]; + *pwc = (ucs4_t) (i + diff); + return 4; + } + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static int +gb18030uni_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 4) { + unsigned int i = wc; + if (i >= 0x0080 && i <= 0xffff) { + unsigned int k1 = 0; + unsigned int k2 = 205; + while (k1 < k2) { + unsigned int k = (k1 + k2) / 2; + if (i <= gb18030uni_uni2charset_ranges[2*k+1]) + k2 = k; + else if (i >= gb18030uni_uni2charset_ranges[2*k+2]) + k1 = k + 1; + else + return RET_ILUNI; + } + { + unsigned int diff = gb18030uni_ranges[k1]; + i -= diff; + r[3] = (i % 10) + 0x30; i = i / 10; + r[2] = (i % 126) + 0x81; i = i / 126; + r[1] = (i % 10) + 0x30; i = i / 10; + r[0] = i + 0x81; + return 4; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/gb2312.h b/libs/libiconv/lib/gb2312.h new file mode 100644 index 00000000..831a5691 --- /dev/null +++ b/libs/libiconv/lib/gb2312.h @@ -0,0 +1,2571 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * GB2312.1980-0 + */ + +static const unsigned short gb2312_2uni_page21[831] = { + /* 0x21 */ + 0x3000, 0x3001, 0x3002, 0x30fb, 0x02c9, 0x02c7, 0x00a8, 0x3003, + 0x3005, 0x2015, 0xff5e, 0x2016, 0x2026, 0x2018, 0x2019, 0x201c, + 0x201d, 0x3014, 0x3015, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c, + 0x300d, 0x300e, 0x300f, 0x3016, 0x3017, 0x3010, 0x3011, 0x00b1, + 0x00d7, 0x00f7, 0x2236, 0x2227, 0x2228, 0x2211, 0x220f, 0x222a, + 0x2229, 0x2208, 0x2237, 0x221a, 0x22a5, 0x2225, 0x2220, 0x2312, + 0x2299, 0x222b, 0x222e, 0x2261, 0x224c, 0x2248, 0x223d, 0x221d, + 0x2260, 0x226e, 0x226f, 0x2264, 0x2265, 0x221e, 0x2235, 0x2234, + 0x2642, 0x2640, 0x00b0, 0x2032, 0x2033, 0x2103, 0xff04, 0x00a4, + 0xffe0, 0xffe1, 0x2030, 0x00a7, 0x2116, 0x2606, 0x2605, 0x25cb, + 0x25cf, 0x25ce, 0x25c7, 0x25c6, 0x25a1, 0x25a0, 0x25b3, 0x25b2, + 0x203b, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, + /* 0x22 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x2488, 0x2489, 0x248a, 0x248b, 0x248c, 0x248d, 0x248e, 0x248f, + 0x2490, 0x2491, 0x2492, 0x2493, 0x2494, 0x2495, 0x2496, 0x2497, + 0x2498, 0x2499, 0x249a, 0x249b, 0x2474, 0x2475, 0x2476, 0x2477, + 0x2478, 0x2479, 0x247a, 0x247b, 0x247c, 0x247d, 0x247e, 0x247f, + 0x2480, 0x2481, 0x2482, 0x2483, 0x2484, 0x2485, 0x2486, 0x2487, + 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, + 0x2468, 0x2469, 0xfffd, 0xfffd, 0x3220, 0x3221, 0x3222, 0x3223, + 0x3224, 0x3225, 0x3226, 0x3227, 0x3228, 0x3229, 0xfffd, 0xfffd, + 0x2160, 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, + 0x2168, 0x2169, 0x216a, 0x216b, 0xfffd, 0xfffd, + /* 0x23 */ + 0xff01, 0xff02, 0xff03, 0xffe5, 0xff05, 0xff06, 0xff07, 0xff08, + 0xff09, 0xff0a, 0xff0b, 0xff0c, 0xff0d, 0xff0e, 0xff0f, 0xff10, + 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18, + 0xff19, 0xff1a, 0xff1b, 0xff1c, 0xff1d, 0xff1e, 0xff1f, 0xff20, + 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, + 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, + 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, + 0xff39, 0xff3a, 0xff3b, 0xff3c, 0xff3d, 0xff3e, 0xff3f, 0xff40, + 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, + 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, + 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, 0xff58, + 0xff59, 0xff5a, 0xff5b, 0xff5c, 0xff5d, 0xffe3, + /* 0x24 */ + 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, + 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, 0x3050, + 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, + 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, 0x3060, + 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, + 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3070, + 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, + 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x307f, 0x3080, + 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, + 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, 0x308e, 0x308f, 0x3090, + 0x3091, 0x3092, 0x3093, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x25 */ + 0x30a1, 0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, 0x30a8, + 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0, + 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8, + 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0, + 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7, 0x30c8, + 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d0, + 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7, 0x30d8, + 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, 0x30e0, + 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7, 0x30e8, + 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef, 0x30f0, + 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x26 */ + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, + 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, + 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, + 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x27 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, + 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, + 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, + 0x042f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, + 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, + 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, + 0x044f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x28 */ + 0x0101, 0x00e1, 0x01ce, 0x00e0, 0x0113, 0x00e9, 0x011b, 0x00e8, + 0x012b, 0x00ed, 0x01d0, 0x00ec, 0x014d, 0x00f3, 0x01d2, 0x00f2, + 0x016b, 0x00fa, 0x01d4, 0x00f9, 0x01d6, 0x01d8, 0x01da, 0x01dc, + 0x00fc, 0x00ea, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x3105, 0x3106, 0x3107, 0x3108, + 0x3109, 0x310a, 0x310b, 0x310c, 0x310d, 0x310e, 0x310f, 0x3110, + 0x3111, 0x3112, 0x3113, 0x3114, 0x3115, 0x3116, 0x3117, 0x3118, + 0x3119, 0x311a, 0x311b, 0x311c, 0x311d, 0x311e, 0x311f, 0x3120, + 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 0x3128, + 0x3129, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x29 */ + 0xfffd, 0xfffd, 0xfffd, 0x2500, 0x2501, 0x2502, 0x2503, 0x2504, + 0x2505, 0x2506, 0x2507, 0x2508, 0x2509, 0x250a, 0x250b, 0x250c, + 0x250d, 0x250e, 0x250f, 0x2510, 0x2511, 0x2512, 0x2513, 0x2514, + 0x2515, 0x2516, 0x2517, 0x2518, 0x2519, 0x251a, 0x251b, 0x251c, + 0x251d, 0x251e, 0x251f, 0x2520, 0x2521, 0x2522, 0x2523, 0x2524, + 0x2525, 0x2526, 0x2527, 0x2528, 0x2529, 0x252a, 0x252b, 0x252c, + 0x252d, 0x252e, 0x252f, 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, + 0x2535, 0x2536, 0x2537, 0x2538, 0x2539, 0x253a, 0x253b, 0x253c, + 0x253d, 0x253e, 0x253f, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, + 0x2545, 0x2546, 0x2547, 0x2548, 0x2549, 0x254a, 0x254b, +}; +static const unsigned short gb2312_2uni_page30[6768] = { + /* 0x30 */ + 0x554a, 0x963f, 0x57c3, 0x6328, 0x54ce, 0x5509, 0x54c0, 0x7691, + 0x764c, 0x853c, 0x77ee, 0x827e, 0x788d, 0x7231, 0x9698, 0x978d, + 0x6c28, 0x5b89, 0x4ffa, 0x6309, 0x6697, 0x5cb8, 0x80fa, 0x6848, + 0x80ae, 0x6602, 0x76ce, 0x51f9, 0x6556, 0x71ac, 0x7ff1, 0x8884, + 0x50b2, 0x5965, 0x61ca, 0x6fb3, 0x82ad, 0x634c, 0x6252, 0x53ed, + 0x5427, 0x7b06, 0x516b, 0x75a4, 0x5df4, 0x62d4, 0x8dcb, 0x9776, + 0x628a, 0x8019, 0x575d, 0x9738, 0x7f62, 0x7238, 0x767d, 0x67cf, + 0x767e, 0x6446, 0x4f70, 0x8d25, 0x62dc, 0x7a17, 0x6591, 0x73ed, + 0x642c, 0x6273, 0x822c, 0x9881, 0x677f, 0x7248, 0x626e, 0x62cc, + 0x4f34, 0x74e3, 0x534a, 0x529e, 0x7eca, 0x90a6, 0x5e2e, 0x6886, + 0x699c, 0x8180, 0x7ed1, 0x68d2, 0x78c5, 0x868c, 0x9551, 0x508d, + 0x8c24, 0x82de, 0x80de, 0x5305, 0x8912, 0x5265, + /* 0x31 */ + 0x8584, 0x96f9, 0x4fdd, 0x5821, 0x9971, 0x5b9d, 0x62b1, 0x62a5, + 0x66b4, 0x8c79, 0x9c8d, 0x7206, 0x676f, 0x7891, 0x60b2, 0x5351, + 0x5317, 0x8f88, 0x80cc, 0x8d1d, 0x94a1, 0x500d, 0x72c8, 0x5907, + 0x60eb, 0x7119, 0x88ab, 0x5954, 0x82ef, 0x672c, 0x7b28, 0x5d29, + 0x7ef7, 0x752d, 0x6cf5, 0x8e66, 0x8ff8, 0x903c, 0x9f3b, 0x6bd4, + 0x9119, 0x7b14, 0x5f7c, 0x78a7, 0x84d6, 0x853d, 0x6bd5, 0x6bd9, + 0x6bd6, 0x5e01, 0x5e87, 0x75f9, 0x95ed, 0x655d, 0x5f0a, 0x5fc5, + 0x8f9f, 0x58c1, 0x81c2, 0x907f, 0x965b, 0x97ad, 0x8fb9, 0x7f16, + 0x8d2c, 0x6241, 0x4fbf, 0x53d8, 0x535e, 0x8fa8, 0x8fa9, 0x8fab, + 0x904d, 0x6807, 0x5f6a, 0x8198, 0x8868, 0x9cd6, 0x618b, 0x522b, + 0x762a, 0x5f6c, 0x658c, 0x6fd2, 0x6ee8, 0x5bbe, 0x6448, 0x5175, + 0x51b0, 0x67c4, 0x4e19, 0x79c9, 0x997c, 0x70b3, + /* 0x32 */ + 0x75c5, 0x5e76, 0x73bb, 0x83e0, 0x64ad, 0x62e8, 0x94b5, 0x6ce2, + 0x535a, 0x52c3, 0x640f, 0x94c2, 0x7b94, 0x4f2f, 0x5e1b, 0x8236, + 0x8116, 0x818a, 0x6e24, 0x6cca, 0x9a73, 0x6355, 0x535c, 0x54fa, + 0x8865, 0x57e0, 0x4e0d, 0x5e03, 0x6b65, 0x7c3f, 0x90e8, 0x6016, + 0x64e6, 0x731c, 0x88c1, 0x6750, 0x624d, 0x8d22, 0x776c, 0x8e29, + 0x91c7, 0x5f69, 0x83dc, 0x8521, 0x9910, 0x53c2, 0x8695, 0x6b8b, + 0x60ed, 0x60e8, 0x707f, 0x82cd, 0x8231, 0x4ed3, 0x6ca7, 0x85cf, + 0x64cd, 0x7cd9, 0x69fd, 0x66f9, 0x8349, 0x5395, 0x7b56, 0x4fa7, + 0x518c, 0x6d4b, 0x5c42, 0x8e6d, 0x63d2, 0x53c9, 0x832c, 0x8336, + 0x67e5, 0x78b4, 0x643d, 0x5bdf, 0x5c94, 0x5dee, 0x8be7, 0x62c6, + 0x67f4, 0x8c7a, 0x6400, 0x63ba, 0x8749, 0x998b, 0x8c17, 0x7f20, + 0x94f2, 0x4ea7, 0x9610, 0x98a4, 0x660c, 0x7316, + /* 0x33 */ + 0x573a, 0x5c1d, 0x5e38, 0x957f, 0x507f, 0x80a0, 0x5382, 0x655e, + 0x7545, 0x5531, 0x5021, 0x8d85, 0x6284, 0x949e, 0x671d, 0x5632, + 0x6f6e, 0x5de2, 0x5435, 0x7092, 0x8f66, 0x626f, 0x64a4, 0x63a3, + 0x5f7b, 0x6f88, 0x90f4, 0x81e3, 0x8fb0, 0x5c18, 0x6668, 0x5ff1, + 0x6c89, 0x9648, 0x8d81, 0x886c, 0x6491, 0x79f0, 0x57ce, 0x6a59, + 0x6210, 0x5448, 0x4e58, 0x7a0b, 0x60e9, 0x6f84, 0x8bda, 0x627f, + 0x901e, 0x9a8b, 0x79e4, 0x5403, 0x75f4, 0x6301, 0x5319, 0x6c60, + 0x8fdf, 0x5f1b, 0x9a70, 0x803b, 0x9f7f, 0x4f88, 0x5c3a, 0x8d64, + 0x7fc5, 0x65a5, 0x70bd, 0x5145, 0x51b2, 0x866b, 0x5d07, 0x5ba0, + 0x62bd, 0x916c, 0x7574, 0x8e0c, 0x7a20, 0x6101, 0x7b79, 0x4ec7, + 0x7ef8, 0x7785, 0x4e11, 0x81ed, 0x521d, 0x51fa, 0x6a71, 0x53a8, + 0x8e87, 0x9504, 0x96cf, 0x6ec1, 0x9664, 0x695a, + /* 0x34 */ + 0x7840, 0x50a8, 0x77d7, 0x6410, 0x89e6, 0x5904, 0x63e3, 0x5ddd, + 0x7a7f, 0x693d, 0x4f20, 0x8239, 0x5598, 0x4e32, 0x75ae, 0x7a97, + 0x5e62, 0x5e8a, 0x95ef, 0x521b, 0x5439, 0x708a, 0x6376, 0x9524, + 0x5782, 0x6625, 0x693f, 0x9187, 0x5507, 0x6df3, 0x7eaf, 0x8822, + 0x6233, 0x7ef0, 0x75b5, 0x8328, 0x78c1, 0x96cc, 0x8f9e, 0x6148, + 0x74f7, 0x8bcd, 0x6b64, 0x523a, 0x8d50, 0x6b21, 0x806a, 0x8471, + 0x56f1, 0x5306, 0x4ece, 0x4e1b, 0x51d1, 0x7c97, 0x918b, 0x7c07, + 0x4fc3, 0x8e7f, 0x7be1, 0x7a9c, 0x6467, 0x5d14, 0x50ac, 0x8106, + 0x7601, 0x7cb9, 0x6dec, 0x7fe0, 0x6751, 0x5b58, 0x5bf8, 0x78cb, + 0x64ae, 0x6413, 0x63aa, 0x632b, 0x9519, 0x642d, 0x8fbe, 0x7b54, + 0x7629, 0x6253, 0x5927, 0x5446, 0x6b79, 0x50a3, 0x6234, 0x5e26, + 0x6b86, 0x4ee3, 0x8d37, 0x888b, 0x5f85, 0x902e, + /* 0x35 */ + 0x6020, 0x803d, 0x62c5, 0x4e39, 0x5355, 0x90f8, 0x63b8, 0x80c6, + 0x65e6, 0x6c2e, 0x4f46, 0x60ee, 0x6de1, 0x8bde, 0x5f39, 0x86cb, + 0x5f53, 0x6321, 0x515a, 0x8361, 0x6863, 0x5200, 0x6363, 0x8e48, + 0x5012, 0x5c9b, 0x7977, 0x5bfc, 0x5230, 0x7a3b, 0x60bc, 0x9053, + 0x76d7, 0x5fb7, 0x5f97, 0x7684, 0x8e6c, 0x706f, 0x767b, 0x7b49, + 0x77aa, 0x51f3, 0x9093, 0x5824, 0x4f4e, 0x6ef4, 0x8fea, 0x654c, + 0x7b1b, 0x72c4, 0x6da4, 0x7fdf, 0x5ae1, 0x62b5, 0x5e95, 0x5730, + 0x8482, 0x7b2c, 0x5e1d, 0x5f1f, 0x9012, 0x7f14, 0x98a0, 0x6382, + 0x6ec7, 0x7898, 0x70b9, 0x5178, 0x975b, 0x57ab, 0x7535, 0x4f43, + 0x7538, 0x5e97, 0x60e6, 0x5960, 0x6dc0, 0x6bbf, 0x7889, 0x53fc, + 0x96d5, 0x51cb, 0x5201, 0x6389, 0x540a, 0x9493, 0x8c03, 0x8dcc, + 0x7239, 0x789f, 0x8776, 0x8fed, 0x8c0d, 0x53e0, + /* 0x36 */ + 0x4e01, 0x76ef, 0x53ee, 0x9489, 0x9876, 0x9f0e, 0x952d, 0x5b9a, + 0x8ba2, 0x4e22, 0x4e1c, 0x51ac, 0x8463, 0x61c2, 0x52a8, 0x680b, + 0x4f97, 0x606b, 0x51bb, 0x6d1e, 0x515c, 0x6296, 0x6597, 0x9661, + 0x8c46, 0x9017, 0x75d8, 0x90fd, 0x7763, 0x6bd2, 0x728a, 0x72ec, + 0x8bfb, 0x5835, 0x7779, 0x8d4c, 0x675c, 0x9540, 0x809a, 0x5ea6, + 0x6e21, 0x5992, 0x7aef, 0x77ed, 0x953b, 0x6bb5, 0x65ad, 0x7f0e, + 0x5806, 0x5151, 0x961f, 0x5bf9, 0x58a9, 0x5428, 0x8e72, 0x6566, + 0x987f, 0x56e4, 0x949d, 0x76fe, 0x9041, 0x6387, 0x54c6, 0x591a, + 0x593a, 0x579b, 0x8eb2, 0x6735, 0x8dfa, 0x8235, 0x5241, 0x60f0, + 0x5815, 0x86fe, 0x5ce8, 0x9e45, 0x4fc4, 0x989d, 0x8bb9, 0x5a25, + 0x6076, 0x5384, 0x627c, 0x904f, 0x9102, 0x997f, 0x6069, 0x800c, + 0x513f, 0x8033, 0x5c14, 0x9975, 0x6d31, 0x4e8c, + /* 0x37 */ + 0x8d30, 0x53d1, 0x7f5a, 0x7b4f, 0x4f10, 0x4e4f, 0x9600, 0x6cd5, + 0x73d0, 0x85e9, 0x5e06, 0x756a, 0x7ffb, 0x6a0a, 0x77fe, 0x9492, + 0x7e41, 0x51e1, 0x70e6, 0x53cd, 0x8fd4, 0x8303, 0x8d29, 0x72af, + 0x996d, 0x6cdb, 0x574a, 0x82b3, 0x65b9, 0x80aa, 0x623f, 0x9632, + 0x59a8, 0x4eff, 0x8bbf, 0x7eba, 0x653e, 0x83f2, 0x975e, 0x5561, + 0x98de, 0x80a5, 0x532a, 0x8bfd, 0x5420, 0x80ba, 0x5e9f, 0x6cb8, + 0x8d39, 0x82ac, 0x915a, 0x5429, 0x6c1b, 0x5206, 0x7eb7, 0x575f, + 0x711a, 0x6c7e, 0x7c89, 0x594b, 0x4efd, 0x5fff, 0x6124, 0x7caa, + 0x4e30, 0x5c01, 0x67ab, 0x8702, 0x5cf0, 0x950b, 0x98ce, 0x75af, + 0x70fd, 0x9022, 0x51af, 0x7f1d, 0x8bbd, 0x5949, 0x51e4, 0x4f5b, + 0x5426, 0x592b, 0x6577, 0x80a4, 0x5b75, 0x6276, 0x62c2, 0x8f90, + 0x5e45, 0x6c1f, 0x7b26, 0x4f0f, 0x4fd8, 0x670d, + /* 0x38 */ + 0x6d6e, 0x6daa, 0x798f, 0x88b1, 0x5f17, 0x752b, 0x629a, 0x8f85, + 0x4fef, 0x91dc, 0x65a7, 0x812f, 0x8151, 0x5e9c, 0x8150, 0x8d74, + 0x526f, 0x8986, 0x8d4b, 0x590d, 0x5085, 0x4ed8, 0x961c, 0x7236, + 0x8179, 0x8d1f, 0x5bcc, 0x8ba3, 0x9644, 0x5987, 0x7f1a, 0x5490, + 0x5676, 0x560e, 0x8be5, 0x6539, 0x6982, 0x9499, 0x76d6, 0x6e89, + 0x5e72, 0x7518, 0x6746, 0x67d1, 0x7aff, 0x809d, 0x8d76, 0x611f, + 0x79c6, 0x6562, 0x8d63, 0x5188, 0x521a, 0x94a2, 0x7f38, 0x809b, + 0x7eb2, 0x5c97, 0x6e2f, 0x6760, 0x7bd9, 0x768b, 0x9ad8, 0x818f, + 0x7f94, 0x7cd5, 0x641e, 0x9550, 0x7a3f, 0x544a, 0x54e5, 0x6b4c, + 0x6401, 0x6208, 0x9e3d, 0x80f3, 0x7599, 0x5272, 0x9769, 0x845b, + 0x683c, 0x86e4, 0x9601, 0x9694, 0x94ec, 0x4e2a, 0x5404, 0x7ed9, + 0x6839, 0x8ddf, 0x8015, 0x66f4, 0x5e9a, 0x7fb9, + /* 0x39 */ + 0x57c2, 0x803f, 0x6897, 0x5de5, 0x653b, 0x529f, 0x606d, 0x9f9a, + 0x4f9b, 0x8eac, 0x516c, 0x5bab, 0x5f13, 0x5de9, 0x6c5e, 0x62f1, + 0x8d21, 0x5171, 0x94a9, 0x52fe, 0x6c9f, 0x82df, 0x72d7, 0x57a2, + 0x6784, 0x8d2d, 0x591f, 0x8f9c, 0x83c7, 0x5495, 0x7b8d, 0x4f30, + 0x6cbd, 0x5b64, 0x59d1, 0x9f13, 0x53e4, 0x86ca, 0x9aa8, 0x8c37, + 0x80a1, 0x6545, 0x987e, 0x56fa, 0x96c7, 0x522e, 0x74dc, 0x5250, + 0x5be1, 0x6302, 0x8902, 0x4e56, 0x62d0, 0x602a, 0x68fa, 0x5173, + 0x5b98, 0x51a0, 0x89c2, 0x7ba1, 0x9986, 0x7f50, 0x60ef, 0x704c, + 0x8d2f, 0x5149, 0x5e7f, 0x901b, 0x7470, 0x89c4, 0x572d, 0x7845, + 0x5f52, 0x9f9f, 0x95fa, 0x8f68, 0x9b3c, 0x8be1, 0x7678, 0x6842, + 0x67dc, 0x8dea, 0x8d35, 0x523d, 0x8f8a, 0x6eda, 0x68cd, 0x9505, + 0x90ed, 0x56fd, 0x679c, 0x88f9, 0x8fc7, 0x54c8, + /* 0x3a */ + 0x9ab8, 0x5b69, 0x6d77, 0x6c26, 0x4ea5, 0x5bb3, 0x9a87, 0x9163, + 0x61a8, 0x90af, 0x97e9, 0x542b, 0x6db5, 0x5bd2, 0x51fd, 0x558a, + 0x7f55, 0x7ff0, 0x64bc, 0x634d, 0x65f1, 0x61be, 0x608d, 0x710a, + 0x6c57, 0x6c49, 0x592f, 0x676d, 0x822a, 0x58d5, 0x568e, 0x8c6a, + 0x6beb, 0x90dd, 0x597d, 0x8017, 0x53f7, 0x6d69, 0x5475, 0x559d, + 0x8377, 0x83cf, 0x6838, 0x79be, 0x548c, 0x4f55, 0x5408, 0x76d2, + 0x8c89, 0x9602, 0x6cb3, 0x6db8, 0x8d6b, 0x8910, 0x9e64, 0x8d3a, + 0x563f, 0x9ed1, 0x75d5, 0x5f88, 0x72e0, 0x6068, 0x54fc, 0x4ea8, + 0x6a2a, 0x8861, 0x6052, 0x8f70, 0x54c4, 0x70d8, 0x8679, 0x9e3f, + 0x6d2a, 0x5b8f, 0x5f18, 0x7ea2, 0x5589, 0x4faf, 0x7334, 0x543c, + 0x539a, 0x5019, 0x540e, 0x547c, 0x4e4e, 0x5ffd, 0x745a, 0x58f6, + 0x846b, 0x80e1, 0x8774, 0x72d0, 0x7cca, 0x6e56, + /* 0x3b */ + 0x5f27, 0x864e, 0x552c, 0x62a4, 0x4e92, 0x6caa, 0x6237, 0x82b1, + 0x54d7, 0x534e, 0x733e, 0x6ed1, 0x753b, 0x5212, 0x5316, 0x8bdd, + 0x69d0, 0x5f8a, 0x6000, 0x6dee, 0x574f, 0x6b22, 0x73af, 0x6853, + 0x8fd8, 0x7f13, 0x6362, 0x60a3, 0x5524, 0x75ea, 0x8c62, 0x7115, + 0x6da3, 0x5ba6, 0x5e7b, 0x8352, 0x614c, 0x9ec4, 0x78fa, 0x8757, + 0x7c27, 0x7687, 0x51f0, 0x60f6, 0x714c, 0x6643, 0x5e4c, 0x604d, + 0x8c0e, 0x7070, 0x6325, 0x8f89, 0x5fbd, 0x6062, 0x86d4, 0x56de, + 0x6bc1, 0x6094, 0x6167, 0x5349, 0x60e0, 0x6666, 0x8d3f, 0x79fd, + 0x4f1a, 0x70e9, 0x6c47, 0x8bb3, 0x8bf2, 0x7ed8, 0x8364, 0x660f, + 0x5a5a, 0x9b42, 0x6d51, 0x6df7, 0x8c41, 0x6d3b, 0x4f19, 0x706b, + 0x83b7, 0x6216, 0x60d1, 0x970d, 0x8d27, 0x7978, 0x51fb, 0x573e, + 0x57fa, 0x673a, 0x7578, 0x7a3d, 0x79ef, 0x7b95, + /* 0x3c */ + 0x808c, 0x9965, 0x8ff9, 0x6fc0, 0x8ba5, 0x9e21, 0x59ec, 0x7ee9, + 0x7f09, 0x5409, 0x6781, 0x68d8, 0x8f91, 0x7c4d, 0x96c6, 0x53ca, + 0x6025, 0x75be, 0x6c72, 0x5373, 0x5ac9, 0x7ea7, 0x6324, 0x51e0, + 0x810a, 0x5df1, 0x84df, 0x6280, 0x5180, 0x5b63, 0x4f0e, 0x796d, + 0x5242, 0x60b8, 0x6d4e, 0x5bc4, 0x5bc2, 0x8ba1, 0x8bb0, 0x65e2, + 0x5fcc, 0x9645, 0x5993, 0x7ee7, 0x7eaa, 0x5609, 0x67b7, 0x5939, + 0x4f73, 0x5bb6, 0x52a0, 0x835a, 0x988a, 0x8d3e, 0x7532, 0x94be, + 0x5047, 0x7a3c, 0x4ef7, 0x67b6, 0x9a7e, 0x5ac1, 0x6b7c, 0x76d1, + 0x575a, 0x5c16, 0x7b3a, 0x95f4, 0x714e, 0x517c, 0x80a9, 0x8270, + 0x5978, 0x7f04, 0x8327, 0x68c0, 0x67ec, 0x78b1, 0x7877, 0x62e3, + 0x6361, 0x7b80, 0x4fed, 0x526a, 0x51cf, 0x8350, 0x69db, 0x9274, + 0x8df5, 0x8d31, 0x89c1, 0x952e, 0x7bad, 0x4ef6, + /* 0x3d */ + 0x5065, 0x8230, 0x5251, 0x996f, 0x6e10, 0x6e85, 0x6da7, 0x5efa, + 0x50f5, 0x59dc, 0x5c06, 0x6d46, 0x6c5f, 0x7586, 0x848b, 0x6868, + 0x5956, 0x8bb2, 0x5320, 0x9171, 0x964d, 0x8549, 0x6912, 0x7901, + 0x7126, 0x80f6, 0x4ea4, 0x90ca, 0x6d47, 0x9a84, 0x5a07, 0x56bc, + 0x6405, 0x94f0, 0x77eb, 0x4fa5, 0x811a, 0x72e1, 0x89d2, 0x997a, + 0x7f34, 0x7ede, 0x527f, 0x6559, 0x9175, 0x8f7f, 0x8f83, 0x53eb, + 0x7a96, 0x63ed, 0x63a5, 0x7686, 0x79f8, 0x8857, 0x9636, 0x622a, + 0x52ab, 0x8282, 0x6854, 0x6770, 0x6377, 0x776b, 0x7aed, 0x6d01, + 0x7ed3, 0x89e3, 0x59d0, 0x6212, 0x85c9, 0x82a5, 0x754c, 0x501f, + 0x4ecb, 0x75a5, 0x8beb, 0x5c4a, 0x5dfe, 0x7b4b, 0x65a4, 0x91d1, + 0x4eca, 0x6d25, 0x895f, 0x7d27, 0x9526, 0x4ec5, 0x8c28, 0x8fdb, + 0x9773, 0x664b, 0x7981, 0x8fd1, 0x70ec, 0x6d78, + /* 0x3e */ + 0x5c3d, 0x52b2, 0x8346, 0x5162, 0x830e, 0x775b, 0x6676, 0x9cb8, + 0x4eac, 0x60ca, 0x7cbe, 0x7cb3, 0x7ecf, 0x4e95, 0x8b66, 0x666f, + 0x9888, 0x9759, 0x5883, 0x656c, 0x955c, 0x5f84, 0x75c9, 0x9756, + 0x7adf, 0x7ade, 0x51c0, 0x70af, 0x7a98, 0x63ea, 0x7a76, 0x7ea0, + 0x7396, 0x97ed, 0x4e45, 0x7078, 0x4e5d, 0x9152, 0x53a9, 0x6551, + 0x65e7, 0x81fc, 0x8205, 0x548e, 0x5c31, 0x759a, 0x97a0, 0x62d8, + 0x72d9, 0x75bd, 0x5c45, 0x9a79, 0x83ca, 0x5c40, 0x5480, 0x77e9, + 0x4e3e, 0x6cae, 0x805a, 0x62d2, 0x636e, 0x5de8, 0x5177, 0x8ddd, + 0x8e1e, 0x952f, 0x4ff1, 0x53e5, 0x60e7, 0x70ac, 0x5267, 0x6350, + 0x9e43, 0x5a1f, 0x5026, 0x7737, 0x5377, 0x7ee2, 0x6485, 0x652b, + 0x6289, 0x6398, 0x5014, 0x7235, 0x89c9, 0x51b3, 0x8bc0, 0x7edd, + 0x5747, 0x83cc, 0x94a7, 0x519b, 0x541b, 0x5cfb, + /* 0x3f */ + 0x4fca, 0x7ae3, 0x6d5a, 0x90e1, 0x9a8f, 0x5580, 0x5496, 0x5361, + 0x54af, 0x5f00, 0x63e9, 0x6977, 0x51ef, 0x6168, 0x520a, 0x582a, + 0x52d8, 0x574e, 0x780d, 0x770b, 0x5eb7, 0x6177, 0x7ce0, 0x625b, + 0x6297, 0x4ea2, 0x7095, 0x8003, 0x62f7, 0x70e4, 0x9760, 0x5777, + 0x82db, 0x67ef, 0x68f5, 0x78d5, 0x9897, 0x79d1, 0x58f3, 0x54b3, + 0x53ef, 0x6e34, 0x514b, 0x523b, 0x5ba2, 0x8bfe, 0x80af, 0x5543, + 0x57a6, 0x6073, 0x5751, 0x542d, 0x7a7a, 0x6050, 0x5b54, 0x63a7, + 0x62a0, 0x53e3, 0x6263, 0x5bc7, 0x67af, 0x54ed, 0x7a9f, 0x82e6, + 0x9177, 0x5e93, 0x88e4, 0x5938, 0x57ae, 0x630e, 0x8de8, 0x80ef, + 0x5757, 0x7b77, 0x4fa9, 0x5feb, 0x5bbd, 0x6b3e, 0x5321, 0x7b50, + 0x72c2, 0x6846, 0x77ff, 0x7736, 0x65f7, 0x51b5, 0x4e8f, 0x76d4, + 0x5cbf, 0x7aa5, 0x8475, 0x594e, 0x9b41, 0x5080, + /* 0x40 */ + 0x9988, 0x6127, 0x6e83, 0x5764, 0x6606, 0x6346, 0x56f0, 0x62ec, + 0x6269, 0x5ed3, 0x9614, 0x5783, 0x62c9, 0x5587, 0x8721, 0x814a, + 0x8fa3, 0x5566, 0x83b1, 0x6765, 0x8d56, 0x84dd, 0x5a6a, 0x680f, + 0x62e6, 0x7bee, 0x9611, 0x5170, 0x6f9c, 0x8c30, 0x63fd, 0x89c8, + 0x61d2, 0x7f06, 0x70c2, 0x6ee5, 0x7405, 0x6994, 0x72fc, 0x5eca, + 0x90ce, 0x6717, 0x6d6a, 0x635e, 0x52b3, 0x7262, 0x8001, 0x4f6c, + 0x59e5, 0x916a, 0x70d9, 0x6d9d, 0x52d2, 0x4e50, 0x96f7, 0x956d, + 0x857e, 0x78ca, 0x7d2f, 0x5121, 0x5792, 0x64c2, 0x808b, 0x7c7b, + 0x6cea, 0x68f1, 0x695e, 0x51b7, 0x5398, 0x68a8, 0x7281, 0x9ece, + 0x7bf1, 0x72f8, 0x79bb, 0x6f13, 0x7406, 0x674e, 0x91cc, 0x9ca4, + 0x793c, 0x8389, 0x8354, 0x540f, 0x6817, 0x4e3d, 0x5389, 0x52b1, + 0x783e, 0x5386, 0x5229, 0x5088, 0x4f8b, 0x4fd0, + /* 0x41 */ + 0x75e2, 0x7acb, 0x7c92, 0x6ca5, 0x96b6, 0x529b, 0x7483, 0x54e9, + 0x4fe9, 0x8054, 0x83b2, 0x8fde, 0x9570, 0x5ec9, 0x601c, 0x6d9f, + 0x5e18, 0x655b, 0x8138, 0x94fe, 0x604b, 0x70bc, 0x7ec3, 0x7cae, + 0x51c9, 0x6881, 0x7cb1, 0x826f, 0x4e24, 0x8f86, 0x91cf, 0x667e, + 0x4eae, 0x8c05, 0x64a9, 0x804a, 0x50da, 0x7597, 0x71ce, 0x5be5, + 0x8fbd, 0x6f66, 0x4e86, 0x6482, 0x9563, 0x5ed6, 0x6599, 0x5217, + 0x88c2, 0x70c8, 0x52a3, 0x730e, 0x7433, 0x6797, 0x78f7, 0x9716, + 0x4e34, 0x90bb, 0x9cde, 0x6dcb, 0x51db, 0x8d41, 0x541d, 0x62ce, + 0x73b2, 0x83f1, 0x96f6, 0x9f84, 0x94c3, 0x4f36, 0x7f9a, 0x51cc, + 0x7075, 0x9675, 0x5cad, 0x9886, 0x53e6, 0x4ee4, 0x6e9c, 0x7409, + 0x69b4, 0x786b, 0x998f, 0x7559, 0x5218, 0x7624, 0x6d41, 0x67f3, + 0x516d, 0x9f99, 0x804b, 0x5499, 0x7b3c, 0x7abf, + /* 0x42 */ + 0x9686, 0x5784, 0x62e2, 0x9647, 0x697c, 0x5a04, 0x6402, 0x7bd3, + 0x6f0f, 0x964b, 0x82a6, 0x5362, 0x9885, 0x5e90, 0x7089, 0x63b3, + 0x5364, 0x864f, 0x9c81, 0x9e93, 0x788c, 0x9732, 0x8def, 0x8d42, + 0x9e7f, 0x6f5e, 0x7984, 0x5f55, 0x9646, 0x622e, 0x9a74, 0x5415, + 0x94dd, 0x4fa3, 0x65c5, 0x5c65, 0x5c61, 0x7f15, 0x8651, 0x6c2f, + 0x5f8b, 0x7387, 0x6ee4, 0x7eff, 0x5ce6, 0x631b, 0x5b6a, 0x6ee6, + 0x5375, 0x4e71, 0x63a0, 0x7565, 0x62a1, 0x8f6e, 0x4f26, 0x4ed1, + 0x6ca6, 0x7eb6, 0x8bba, 0x841d, 0x87ba, 0x7f57, 0x903b, 0x9523, + 0x7ba9, 0x9aa1, 0x88f8, 0x843d, 0x6d1b, 0x9a86, 0x7edc, 0x5988, + 0x9ebb, 0x739b, 0x7801, 0x8682, 0x9a6c, 0x9a82, 0x561b, 0x5417, + 0x57cb, 0x4e70, 0x9ea6, 0x5356, 0x8fc8, 0x8109, 0x7792, 0x9992, + 0x86ee, 0x6ee1, 0x8513, 0x66fc, 0x6162, 0x6f2b, + /* 0x43 */ + 0x8c29, 0x8292, 0x832b, 0x76f2, 0x6c13, 0x5fd9, 0x83bd, 0x732b, + 0x8305, 0x951a, 0x6bdb, 0x77db, 0x94c6, 0x536f, 0x8302, 0x5192, + 0x5e3d, 0x8c8c, 0x8d38, 0x4e48, 0x73ab, 0x679a, 0x6885, 0x9176, + 0x9709, 0x7164, 0x6ca1, 0x7709, 0x5a92, 0x9541, 0x6bcf, 0x7f8e, + 0x6627, 0x5bd0, 0x59b9, 0x5a9a, 0x95e8, 0x95f7, 0x4eec, 0x840c, + 0x8499, 0x6aac, 0x76df, 0x9530, 0x731b, 0x68a6, 0x5b5f, 0x772f, + 0x919a, 0x9761, 0x7cdc, 0x8ff7, 0x8c1c, 0x5f25, 0x7c73, 0x79d8, + 0x89c5, 0x6ccc, 0x871c, 0x5bc6, 0x5e42, 0x68c9, 0x7720, 0x7ef5, + 0x5195, 0x514d, 0x52c9, 0x5a29, 0x7f05, 0x9762, 0x82d7, 0x63cf, + 0x7784, 0x85d0, 0x79d2, 0x6e3a, 0x5e99, 0x5999, 0x8511, 0x706d, + 0x6c11, 0x62bf, 0x76bf, 0x654f, 0x60af, 0x95fd, 0x660e, 0x879f, + 0x9e23, 0x94ed, 0x540d, 0x547d, 0x8c2c, 0x6478, + /* 0x44 */ + 0x6479, 0x8611, 0x6a21, 0x819c, 0x78e8, 0x6469, 0x9b54, 0x62b9, + 0x672b, 0x83ab, 0x58a8, 0x9ed8, 0x6cab, 0x6f20, 0x5bde, 0x964c, + 0x8c0b, 0x725f, 0x67d0, 0x62c7, 0x7261, 0x4ea9, 0x59c6, 0x6bcd, + 0x5893, 0x66ae, 0x5e55, 0x52df, 0x6155, 0x6728, 0x76ee, 0x7766, + 0x7267, 0x7a46, 0x62ff, 0x54ea, 0x5450, 0x94a0, 0x90a3, 0x5a1c, + 0x7eb3, 0x6c16, 0x4e43, 0x5976, 0x8010, 0x5948, 0x5357, 0x7537, + 0x96be, 0x56ca, 0x6320, 0x8111, 0x607c, 0x95f9, 0x6dd6, 0x5462, + 0x9981, 0x5185, 0x5ae9, 0x80fd, 0x59ae, 0x9713, 0x502a, 0x6ce5, + 0x5c3c, 0x62df, 0x4f60, 0x533f, 0x817b, 0x9006, 0x6eba, 0x852b, + 0x62c8, 0x5e74, 0x78be, 0x64b5, 0x637b, 0x5ff5, 0x5a18, 0x917f, + 0x9e1f, 0x5c3f, 0x634f, 0x8042, 0x5b7d, 0x556e, 0x954a, 0x954d, + 0x6d85, 0x60a8, 0x67e0, 0x72de, 0x51dd, 0x5b81, + /* 0x45 */ + 0x62e7, 0x6cde, 0x725b, 0x626d, 0x94ae, 0x7ebd, 0x8113, 0x6d53, + 0x519c, 0x5f04, 0x5974, 0x52aa, 0x6012, 0x5973, 0x6696, 0x8650, + 0x759f, 0x632a, 0x61e6, 0x7cef, 0x8bfa, 0x54e6, 0x6b27, 0x9e25, + 0x6bb4, 0x85d5, 0x5455, 0x5076, 0x6ca4, 0x556a, 0x8db4, 0x722c, + 0x5e15, 0x6015, 0x7436, 0x62cd, 0x6392, 0x724c, 0x5f98, 0x6e43, + 0x6d3e, 0x6500, 0x6f58, 0x76d8, 0x78d0, 0x76fc, 0x7554, 0x5224, + 0x53db, 0x4e53, 0x5e9e, 0x65c1, 0x802a, 0x80d6, 0x629b, 0x5486, + 0x5228, 0x70ae, 0x888d, 0x8dd1, 0x6ce1, 0x5478, 0x80da, 0x57f9, + 0x88f4, 0x8d54, 0x966a, 0x914d, 0x4f69, 0x6c9b, 0x55b7, 0x76c6, + 0x7830, 0x62a8, 0x70f9, 0x6f8e, 0x5f6d, 0x84ec, 0x68da, 0x787c, + 0x7bf7, 0x81a8, 0x670b, 0x9e4f, 0x6367, 0x78b0, 0x576f, 0x7812, + 0x9739, 0x6279, 0x62ab, 0x5288, 0x7435, 0x6bd7, + /* 0x46 */ + 0x5564, 0x813e, 0x75b2, 0x76ae, 0x5339, 0x75de, 0x50fb, 0x5c41, + 0x8b6c, 0x7bc7, 0x504f, 0x7247, 0x9a97, 0x98d8, 0x6f02, 0x74e2, + 0x7968, 0x6487, 0x77a5, 0x62fc, 0x9891, 0x8d2b, 0x54c1, 0x8058, + 0x4e52, 0x576a, 0x82f9, 0x840d, 0x5e73, 0x51ed, 0x74f6, 0x8bc4, + 0x5c4f, 0x5761, 0x6cfc, 0x9887, 0x5a46, 0x7834, 0x9b44, 0x8feb, + 0x7c95, 0x5256, 0x6251, 0x94fa, 0x4ec6, 0x8386, 0x8461, 0x83e9, + 0x84b2, 0x57d4, 0x6734, 0x5703, 0x666e, 0x6d66, 0x8c31, 0x66dd, + 0x7011, 0x671f, 0x6b3a, 0x6816, 0x621a, 0x59bb, 0x4e03, 0x51c4, + 0x6f06, 0x67d2, 0x6c8f, 0x5176, 0x68cb, 0x5947, 0x6b67, 0x7566, + 0x5d0e, 0x8110, 0x9f50, 0x65d7, 0x7948, 0x7941, 0x9a91, 0x8d77, + 0x5c82, 0x4e5e, 0x4f01, 0x542f, 0x5951, 0x780c, 0x5668, 0x6c14, + 0x8fc4, 0x5f03, 0x6c7d, 0x6ce3, 0x8bab, 0x6390, + /* 0x47 */ + 0x6070, 0x6d3d, 0x7275, 0x6266, 0x948e, 0x94c5, 0x5343, 0x8fc1, + 0x7b7e, 0x4edf, 0x8c26, 0x4e7e, 0x9ed4, 0x94b1, 0x94b3, 0x524d, + 0x6f5c, 0x9063, 0x6d45, 0x8c34, 0x5811, 0x5d4c, 0x6b20, 0x6b49, + 0x67aa, 0x545b, 0x8154, 0x7f8c, 0x5899, 0x8537, 0x5f3a, 0x62a2, + 0x6a47, 0x9539, 0x6572, 0x6084, 0x6865, 0x77a7, 0x4e54, 0x4fa8, + 0x5de7, 0x9798, 0x64ac, 0x7fd8, 0x5ced, 0x4fcf, 0x7a8d, 0x5207, + 0x8304, 0x4e14, 0x602f, 0x7a83, 0x94a6, 0x4fb5, 0x4eb2, 0x79e6, + 0x7434, 0x52e4, 0x82b9, 0x64d2, 0x79bd, 0x5bdd, 0x6c81, 0x9752, + 0x8f7b, 0x6c22, 0x503e, 0x537f, 0x6e05, 0x64ce, 0x6674, 0x6c30, + 0x60c5, 0x9877, 0x8bf7, 0x5e86, 0x743c, 0x7a77, 0x79cb, 0x4e18, + 0x90b1, 0x7403, 0x6c42, 0x56da, 0x914b, 0x6cc5, 0x8d8b, 0x533a, + 0x86c6, 0x66f2, 0x8eaf, 0x5c48, 0x9a71, 0x6e20, + /* 0x48 */ + 0x53d6, 0x5a36, 0x9f8b, 0x8da3, 0x53bb, 0x5708, 0x98a7, 0x6743, + 0x919b, 0x6cc9, 0x5168, 0x75ca, 0x62f3, 0x72ac, 0x5238, 0x529d, + 0x7f3a, 0x7094, 0x7638, 0x5374, 0x9e4a, 0x69b7, 0x786e, 0x96c0, + 0x88d9, 0x7fa4, 0x7136, 0x71c3, 0x5189, 0x67d3, 0x74e4, 0x58e4, + 0x6518, 0x56b7, 0x8ba9, 0x9976, 0x6270, 0x7ed5, 0x60f9, 0x70ed, + 0x58ec, 0x4ec1, 0x4eba, 0x5fcd, 0x97e7, 0x4efb, 0x8ba4, 0x5203, + 0x598a, 0x7eab, 0x6254, 0x4ecd, 0x65e5, 0x620e, 0x8338, 0x84c9, + 0x8363, 0x878d, 0x7194, 0x6eb6, 0x5bb9, 0x7ed2, 0x5197, 0x63c9, + 0x67d4, 0x8089, 0x8339, 0x8815, 0x5112, 0x5b7a, 0x5982, 0x8fb1, + 0x4e73, 0x6c5d, 0x5165, 0x8925, 0x8f6f, 0x962e, 0x854a, 0x745e, + 0x9510, 0x95f0, 0x6da6, 0x82e5, 0x5f31, 0x6492, 0x6d12, 0x8428, + 0x816e, 0x9cc3, 0x585e, 0x8d5b, 0x4e09, 0x53c1, + /* 0x49 */ + 0x4f1e, 0x6563, 0x6851, 0x55d3, 0x4e27, 0x6414, 0x9a9a, 0x626b, + 0x5ac2, 0x745f, 0x8272, 0x6da9, 0x68ee, 0x50e7, 0x838e, 0x7802, + 0x6740, 0x5239, 0x6c99, 0x7eb1, 0x50bb, 0x5565, 0x715e, 0x7b5b, + 0x6652, 0x73ca, 0x82eb, 0x6749, 0x5c71, 0x5220, 0x717d, 0x886b, + 0x95ea, 0x9655, 0x64c5, 0x8d61, 0x81b3, 0x5584, 0x6c55, 0x6247, + 0x7f2e, 0x5892, 0x4f24, 0x5546, 0x8d4f, 0x664c, 0x4e0a, 0x5c1a, + 0x88f3, 0x68a2, 0x634e, 0x7a0d, 0x70e7, 0x828d, 0x52fa, 0x97f6, + 0x5c11, 0x54e8, 0x90b5, 0x7ecd, 0x5962, 0x8d4a, 0x86c7, 0x820c, + 0x820d, 0x8d66, 0x6444, 0x5c04, 0x6151, 0x6d89, 0x793e, 0x8bbe, + 0x7837, 0x7533, 0x547b, 0x4f38, 0x8eab, 0x6df1, 0x5a20, 0x7ec5, + 0x795e, 0x6c88, 0x5ba1, 0x5a76, 0x751a, 0x80be, 0x614e, 0x6e17, + 0x58f0, 0x751f, 0x7525, 0x7272, 0x5347, 0x7ef3, + /* 0x4a */ + 0x7701, 0x76db, 0x5269, 0x80dc, 0x5723, 0x5e08, 0x5931, 0x72ee, + 0x65bd, 0x6e7f, 0x8bd7, 0x5c38, 0x8671, 0x5341, 0x77f3, 0x62fe, + 0x65f6, 0x4ec0, 0x98df, 0x8680, 0x5b9e, 0x8bc6, 0x53f2, 0x77e2, + 0x4f7f, 0x5c4e, 0x9a76, 0x59cb, 0x5f0f, 0x793a, 0x58eb, 0x4e16, + 0x67ff, 0x4e8b, 0x62ed, 0x8a93, 0x901d, 0x52bf, 0x662f, 0x55dc, + 0x566c, 0x9002, 0x4ed5, 0x4f8d, 0x91ca, 0x9970, 0x6c0f, 0x5e02, + 0x6043, 0x5ba4, 0x89c6, 0x8bd5, 0x6536, 0x624b, 0x9996, 0x5b88, + 0x5bff, 0x6388, 0x552e, 0x53d7, 0x7626, 0x517d, 0x852c, 0x67a2, + 0x68b3, 0x6b8a, 0x6292, 0x8f93, 0x53d4, 0x8212, 0x6dd1, 0x758f, + 0x4e66, 0x8d4e, 0x5b70, 0x719f, 0x85af, 0x6691, 0x66d9, 0x7f72, + 0x8700, 0x9ecd, 0x9f20, 0x5c5e, 0x672f, 0x8ff0, 0x6811, 0x675f, + 0x620d, 0x7ad6, 0x5885, 0x5eb6, 0x6570, 0x6f31, + /* 0x4b */ + 0x6055, 0x5237, 0x800d, 0x6454, 0x8870, 0x7529, 0x5e05, 0x6813, + 0x62f4, 0x971c, 0x53cc, 0x723d, 0x8c01, 0x6c34, 0x7761, 0x7a0e, + 0x542e, 0x77ac, 0x987a, 0x821c, 0x8bf4, 0x7855, 0x6714, 0x70c1, + 0x65af, 0x6495, 0x5636, 0x601d, 0x79c1, 0x53f8, 0x4e1d, 0x6b7b, + 0x8086, 0x5bfa, 0x55e3, 0x56db, 0x4f3a, 0x4f3c, 0x9972, 0x5df3, + 0x677e, 0x8038, 0x6002, 0x9882, 0x9001, 0x5b8b, 0x8bbc, 0x8bf5, + 0x641c, 0x8258, 0x64de, 0x55fd, 0x82cf, 0x9165, 0x4fd7, 0x7d20, + 0x901f, 0x7c9f, 0x50f3, 0x5851, 0x6eaf, 0x5bbf, 0x8bc9, 0x8083, + 0x9178, 0x849c, 0x7b97, 0x867d, 0x968b, 0x968f, 0x7ee5, 0x9ad3, + 0x788e, 0x5c81, 0x7a57, 0x9042, 0x96a7, 0x795f, 0x5b59, 0x635f, + 0x7b0b, 0x84d1, 0x68ad, 0x5506, 0x7f29, 0x7410, 0x7d22, 0x9501, + 0x6240, 0x584c, 0x4ed6, 0x5b83, 0x5979, 0x5854, + /* 0x4c */ + 0x736d, 0x631e, 0x8e4b, 0x8e0f, 0x80ce, 0x82d4, 0x62ac, 0x53f0, + 0x6cf0, 0x915e, 0x592a, 0x6001, 0x6c70, 0x574d, 0x644a, 0x8d2a, + 0x762b, 0x6ee9, 0x575b, 0x6a80, 0x75f0, 0x6f6d, 0x8c2d, 0x8c08, + 0x5766, 0x6bef, 0x8892, 0x78b3, 0x63a2, 0x53f9, 0x70ad, 0x6c64, + 0x5858, 0x642a, 0x5802, 0x68e0, 0x819b, 0x5510, 0x7cd6, 0x5018, + 0x8eba, 0x6dcc, 0x8d9f, 0x70eb, 0x638f, 0x6d9b, 0x6ed4, 0x7ee6, + 0x8404, 0x6843, 0x9003, 0x6dd8, 0x9676, 0x8ba8, 0x5957, 0x7279, + 0x85e4, 0x817e, 0x75bc, 0x8a8a, 0x68af, 0x5254, 0x8e22, 0x9511, + 0x63d0, 0x9898, 0x8e44, 0x557c, 0x4f53, 0x66ff, 0x568f, 0x60d5, + 0x6d95, 0x5243, 0x5c49, 0x5929, 0x6dfb, 0x586b, 0x7530, 0x751c, + 0x606c, 0x8214, 0x8146, 0x6311, 0x6761, 0x8fe2, 0x773a, 0x8df3, + 0x8d34, 0x94c1, 0x5e16, 0x5385, 0x542c, 0x70c3, + /* 0x4d */ + 0x6c40, 0x5ef7, 0x505c, 0x4ead, 0x5ead, 0x633a, 0x8247, 0x901a, + 0x6850, 0x916e, 0x77b3, 0x540c, 0x94dc, 0x5f64, 0x7ae5, 0x6876, + 0x6345, 0x7b52, 0x7edf, 0x75db, 0x5077, 0x6295, 0x5934, 0x900f, + 0x51f8, 0x79c3, 0x7a81, 0x56fe, 0x5f92, 0x9014, 0x6d82, 0x5c60, + 0x571f, 0x5410, 0x5154, 0x6e4d, 0x56e2, 0x63a8, 0x9893, 0x817f, + 0x8715, 0x892a, 0x9000, 0x541e, 0x5c6f, 0x81c0, 0x62d6, 0x6258, + 0x8131, 0x9e35, 0x9640, 0x9a6e, 0x9a7c, 0x692d, 0x59a5, 0x62d3, + 0x553e, 0x6316, 0x54c7, 0x86d9, 0x6d3c, 0x5a03, 0x74e6, 0x889c, + 0x6b6a, 0x5916, 0x8c4c, 0x5f2f, 0x6e7e, 0x73a9, 0x987d, 0x4e38, + 0x70f7, 0x5b8c, 0x7897, 0x633d, 0x665a, 0x7696, 0x60cb, 0x5b9b, + 0x5a49, 0x4e07, 0x8155, 0x6c6a, 0x738b, 0x4ea1, 0x6789, 0x7f51, + 0x5f80, 0x65fa, 0x671b, 0x5fd8, 0x5984, 0x5a01, + /* 0x4e */ + 0x5dcd, 0x5fae, 0x5371, 0x97e6, 0x8fdd, 0x6845, 0x56f4, 0x552f, + 0x60df, 0x4e3a, 0x6f4d, 0x7ef4, 0x82c7, 0x840e, 0x59d4, 0x4f1f, + 0x4f2a, 0x5c3e, 0x7eac, 0x672a, 0x851a, 0x5473, 0x754f, 0x80c3, + 0x5582, 0x9b4f, 0x4f4d, 0x6e2d, 0x8c13, 0x5c09, 0x6170, 0x536b, + 0x761f, 0x6e29, 0x868a, 0x6587, 0x95fb, 0x7eb9, 0x543b, 0x7a33, + 0x7d0a, 0x95ee, 0x55e1, 0x7fc1, 0x74ee, 0x631d, 0x8717, 0x6da1, + 0x7a9d, 0x6211, 0x65a1, 0x5367, 0x63e1, 0x6c83, 0x5deb, 0x545c, + 0x94a8, 0x4e4c, 0x6c61, 0x8bec, 0x5c4b, 0x65e0, 0x829c, 0x68a7, + 0x543e, 0x5434, 0x6bcb, 0x6b66, 0x4e94, 0x6342, 0x5348, 0x821e, + 0x4f0d, 0x4fae, 0x575e, 0x620a, 0x96fe, 0x6664, 0x7269, 0x52ff, + 0x52a1, 0x609f, 0x8bef, 0x6614, 0x7199, 0x6790, 0x897f, 0x7852, + 0x77fd, 0x6670, 0x563b, 0x5438, 0x9521, 0x727a, + /* 0x4f */ + 0x7a00, 0x606f, 0x5e0c, 0x6089, 0x819d, 0x5915, 0x60dc, 0x7184, + 0x70ef, 0x6eaa, 0x6c50, 0x7280, 0x6a84, 0x88ad, 0x5e2d, 0x4e60, + 0x5ab3, 0x559c, 0x94e3, 0x6d17, 0x7cfb, 0x9699, 0x620f, 0x7ec6, + 0x778e, 0x867e, 0x5323, 0x971e, 0x8f96, 0x6687, 0x5ce1, 0x4fa0, + 0x72ed, 0x4e0b, 0x53a6, 0x590f, 0x5413, 0x6380, 0x9528, 0x5148, + 0x4ed9, 0x9c9c, 0x7ea4, 0x54b8, 0x8d24, 0x8854, 0x8237, 0x95f2, + 0x6d8e, 0x5f26, 0x5acc, 0x663e, 0x9669, 0x73b0, 0x732e, 0x53bf, + 0x817a, 0x9985, 0x7fa1, 0x5baa, 0x9677, 0x9650, 0x7ebf, 0x76f8, + 0x53a2, 0x9576, 0x9999, 0x7bb1, 0x8944, 0x6e58, 0x4e61, 0x7fd4, + 0x7965, 0x8be6, 0x60f3, 0x54cd, 0x4eab, 0x9879, 0x5df7, 0x6a61, + 0x50cf, 0x5411, 0x8c61, 0x8427, 0x785d, 0x9704, 0x524a, 0x54ee, + 0x56a3, 0x9500, 0x6d88, 0x5bb5, 0x6dc6, 0x6653, + /* 0x50 */ + 0x5c0f, 0x5b5d, 0x6821, 0x8096, 0x5578, 0x7b11, 0x6548, 0x6954, + 0x4e9b, 0x6b47, 0x874e, 0x978b, 0x534f, 0x631f, 0x643a, 0x90aa, + 0x659c, 0x80c1, 0x8c10, 0x5199, 0x68b0, 0x5378, 0x87f9, 0x61c8, + 0x6cc4, 0x6cfb, 0x8c22, 0x5c51, 0x85aa, 0x82af, 0x950c, 0x6b23, + 0x8f9b, 0x65b0, 0x5ffb, 0x5fc3, 0x4fe1, 0x8845, 0x661f, 0x8165, + 0x7329, 0x60fa, 0x5174, 0x5211, 0x578b, 0x5f62, 0x90a2, 0x884c, + 0x9192, 0x5e78, 0x674f, 0x6027, 0x59d3, 0x5144, 0x51f6, 0x80f8, + 0x5308, 0x6c79, 0x96c4, 0x718a, 0x4f11, 0x4fee, 0x7f9e, 0x673d, + 0x55c5, 0x9508, 0x79c0, 0x8896, 0x7ee3, 0x589f, 0x620c, 0x9700, + 0x865a, 0x5618, 0x987b, 0x5f90, 0x8bb8, 0x84c4, 0x9157, 0x53d9, + 0x65ed, 0x5e8f, 0x755c, 0x6064, 0x7d6e, 0x5a7f, 0x7eea, 0x7eed, + 0x8f69, 0x55a7, 0x5ba3, 0x60ac, 0x65cb, 0x7384, + /* 0x51 */ + 0x9009, 0x7663, 0x7729, 0x7eda, 0x9774, 0x859b, 0x5b66, 0x7a74, + 0x96ea, 0x8840, 0x52cb, 0x718f, 0x5faa, 0x65ec, 0x8be2, 0x5bfb, + 0x9a6f, 0x5de1, 0x6b89, 0x6c5b, 0x8bad, 0x8baf, 0x900a, 0x8fc5, + 0x538b, 0x62bc, 0x9e26, 0x9e2d, 0x5440, 0x4e2b, 0x82bd, 0x7259, + 0x869c, 0x5d16, 0x8859, 0x6daf, 0x96c5, 0x54d1, 0x4e9a, 0x8bb6, + 0x7109, 0x54bd, 0x9609, 0x70df, 0x6df9, 0x76d0, 0x4e25, 0x7814, + 0x8712, 0x5ca9, 0x5ef6, 0x8a00, 0x989c, 0x960e, 0x708e, 0x6cbf, + 0x5944, 0x63a9, 0x773c, 0x884d, 0x6f14, 0x8273, 0x5830, 0x71d5, + 0x538c, 0x781a, 0x96c1, 0x5501, 0x5f66, 0x7130, 0x5bb4, 0x8c1a, + 0x9a8c, 0x6b83, 0x592e, 0x9e2f, 0x79e7, 0x6768, 0x626c, 0x4f6f, + 0x75a1, 0x7f8a, 0x6d0b, 0x9633, 0x6c27, 0x4ef0, 0x75d2, 0x517b, + 0x6837, 0x6f3e, 0x9080, 0x8170, 0x5996, 0x7476, + /* 0x52 */ + 0x6447, 0x5c27, 0x9065, 0x7a91, 0x8c23, 0x59da, 0x54ac, 0x8200, + 0x836f, 0x8981, 0x8000, 0x6930, 0x564e, 0x8036, 0x7237, 0x91ce, + 0x51b6, 0x4e5f, 0x9875, 0x6396, 0x4e1a, 0x53f6, 0x66f3, 0x814b, + 0x591c, 0x6db2, 0x4e00, 0x58f9, 0x533b, 0x63d6, 0x94f1, 0x4f9d, + 0x4f0a, 0x8863, 0x9890, 0x5937, 0x9057, 0x79fb, 0x4eea, 0x80f0, + 0x7591, 0x6c82, 0x5b9c, 0x59e8, 0x5f5d, 0x6905, 0x8681, 0x501a, + 0x5df2, 0x4e59, 0x77e3, 0x4ee5, 0x827a, 0x6291, 0x6613, 0x9091, + 0x5c79, 0x4ebf, 0x5f79, 0x81c6, 0x9038, 0x8084, 0x75ab, 0x4ea6, + 0x88d4, 0x610f, 0x6bc5, 0x5fc6, 0x4e49, 0x76ca, 0x6ea2, 0x8be3, + 0x8bae, 0x8c0a, 0x8bd1, 0x5f02, 0x7ffc, 0x7fcc, 0x7ece, 0x8335, + 0x836b, 0x56e0, 0x6bb7, 0x97f3, 0x9634, 0x59fb, 0x541f, 0x94f6, + 0x6deb, 0x5bc5, 0x996e, 0x5c39, 0x5f15, 0x9690, + /* 0x53 */ + 0x5370, 0x82f1, 0x6a31, 0x5a74, 0x9e70, 0x5e94, 0x7f28, 0x83b9, + 0x8424, 0x8425, 0x8367, 0x8747, 0x8fce, 0x8d62, 0x76c8, 0x5f71, + 0x9896, 0x786c, 0x6620, 0x54df, 0x62e5, 0x4f63, 0x81c3, 0x75c8, + 0x5eb8, 0x96cd, 0x8e0a, 0x86f9, 0x548f, 0x6cf3, 0x6d8c, 0x6c38, + 0x607f, 0x52c7, 0x7528, 0x5e7d, 0x4f18, 0x60a0, 0x5fe7, 0x5c24, + 0x7531, 0x90ae, 0x94c0, 0x72b9, 0x6cb9, 0x6e38, 0x9149, 0x6709, + 0x53cb, 0x53f3, 0x4f51, 0x91c9, 0x8bf1, 0x53c8, 0x5e7c, 0x8fc2, + 0x6de4, 0x4e8e, 0x76c2, 0x6986, 0x865e, 0x611a, 0x8206, 0x4f59, + 0x4fde, 0x903e, 0x9c7c, 0x6109, 0x6e1d, 0x6e14, 0x9685, 0x4e88, + 0x5a31, 0x96e8, 0x4e0e, 0x5c7f, 0x79b9, 0x5b87, 0x8bed, 0x7fbd, + 0x7389, 0x57df, 0x828b, 0x90c1, 0x5401, 0x9047, 0x55bb, 0x5cea, + 0x5fa1, 0x6108, 0x6b32, 0x72f1, 0x80b2, 0x8a89, + /* 0x54 */ + 0x6d74, 0x5bd3, 0x88d5, 0x9884, 0x8c6b, 0x9a6d, 0x9e33, 0x6e0a, + 0x51a4, 0x5143, 0x57a3, 0x8881, 0x539f, 0x63f4, 0x8f95, 0x56ed, + 0x5458, 0x5706, 0x733f, 0x6e90, 0x7f18, 0x8fdc, 0x82d1, 0x613f, + 0x6028, 0x9662, 0x66f0, 0x7ea6, 0x8d8a, 0x8dc3, 0x94a5, 0x5cb3, + 0x7ca4, 0x6708, 0x60a6, 0x9605, 0x8018, 0x4e91, 0x90e7, 0x5300, + 0x9668, 0x5141, 0x8fd0, 0x8574, 0x915d, 0x6655, 0x97f5, 0x5b55, + 0x531d, 0x7838, 0x6742, 0x683d, 0x54c9, 0x707e, 0x5bb0, 0x8f7d, + 0x518d, 0x5728, 0x54b1, 0x6512, 0x6682, 0x8d5e, 0x8d43, 0x810f, + 0x846c, 0x906d, 0x7cdf, 0x51ff, 0x85fb, 0x67a3, 0x65e9, 0x6fa1, + 0x86a4, 0x8e81, 0x566a, 0x9020, 0x7682, 0x7076, 0x71e5, 0x8d23, + 0x62e9, 0x5219, 0x6cfd, 0x8d3c, 0x600e, 0x589e, 0x618e, 0x66fe, + 0x8d60, 0x624e, 0x55b3, 0x6e23, 0x672d, 0x8f67, + /* 0x55 */ + 0x94e1, 0x95f8, 0x7728, 0x6805, 0x69a8, 0x548b, 0x4e4d, 0x70b8, + 0x8bc8, 0x6458, 0x658b, 0x5b85, 0x7a84, 0x503a, 0x5be8, 0x77bb, + 0x6be1, 0x8a79, 0x7c98, 0x6cbe, 0x76cf, 0x65a9, 0x8f97, 0x5d2d, + 0x5c55, 0x8638, 0x6808, 0x5360, 0x6218, 0x7ad9, 0x6e5b, 0x7efd, + 0x6a1f, 0x7ae0, 0x5f70, 0x6f33, 0x5f20, 0x638c, 0x6da8, 0x6756, + 0x4e08, 0x5e10, 0x8d26, 0x4ed7, 0x80c0, 0x7634, 0x969c, 0x62db, + 0x662d, 0x627e, 0x6cbc, 0x8d75, 0x7167, 0x7f69, 0x5146, 0x8087, + 0x53ec, 0x906e, 0x6298, 0x54f2, 0x86f0, 0x8f99, 0x8005, 0x9517, + 0x8517, 0x8fd9, 0x6d59, 0x73cd, 0x659f, 0x771f, 0x7504, 0x7827, + 0x81fb, 0x8d1e, 0x9488, 0x4fa6, 0x6795, 0x75b9, 0x8bca, 0x9707, + 0x632f, 0x9547, 0x9635, 0x84b8, 0x6323, 0x7741, 0x5f81, 0x72f0, + 0x4e89, 0x6014, 0x6574, 0x62ef, 0x6b63, 0x653f, + /* 0x56 */ + 0x5e27, 0x75c7, 0x90d1, 0x8bc1, 0x829d, 0x679d, 0x652f, 0x5431, + 0x8718, 0x77e5, 0x80a2, 0x8102, 0x6c41, 0x4e4b, 0x7ec7, 0x804c, + 0x76f4, 0x690d, 0x6b96, 0x6267, 0x503c, 0x4f84, 0x5740, 0x6307, + 0x6b62, 0x8dbe, 0x53ea, 0x65e8, 0x7eb8, 0x5fd7, 0x631a, 0x63b7, + 0x81f3, 0x81f4, 0x7f6e, 0x5e1c, 0x5cd9, 0x5236, 0x667a, 0x79e9, + 0x7a1a, 0x8d28, 0x7099, 0x75d4, 0x6ede, 0x6cbb, 0x7a92, 0x4e2d, + 0x76c5, 0x5fe0, 0x949f, 0x8877, 0x7ec8, 0x79cd, 0x80bf, 0x91cd, + 0x4ef2, 0x4f17, 0x821f, 0x5468, 0x5dde, 0x6d32, 0x8bcc, 0x7ca5, + 0x8f74, 0x8098, 0x5e1a, 0x5492, 0x76b1, 0x5b99, 0x663c, 0x9aa4, + 0x73e0, 0x682a, 0x86db, 0x6731, 0x732a, 0x8bf8, 0x8bdb, 0x9010, + 0x7af9, 0x70db, 0x716e, 0x62c4, 0x77a9, 0x5631, 0x4e3b, 0x8457, + 0x67f1, 0x52a9, 0x86c0, 0x8d2e, 0x94f8, 0x7b51, + /* 0x57 */ + 0x4f4f, 0x6ce8, 0x795d, 0x9a7b, 0x6293, 0x722a, 0x62fd, 0x4e13, + 0x7816, 0x8f6c, 0x64b0, 0x8d5a, 0x7bc6, 0x6869, 0x5e84, 0x88c5, + 0x5986, 0x649e, 0x58ee, 0x72b6, 0x690e, 0x9525, 0x8ffd, 0x8d58, + 0x5760, 0x7f00, 0x8c06, 0x51c6, 0x6349, 0x62d9, 0x5353, 0x684c, + 0x7422, 0x8301, 0x914c, 0x5544, 0x7740, 0x707c, 0x6d4a, 0x5179, + 0x54a8, 0x8d44, 0x59ff, 0x6ecb, 0x6dc4, 0x5b5c, 0x7d2b, 0x4ed4, + 0x7c7d, 0x6ed3, 0x5b50, 0x81ea, 0x6e0d, 0x5b57, 0x9b03, 0x68d5, + 0x8e2a, 0x5b97, 0x7efc, 0x603b, 0x7eb5, 0x90b9, 0x8d70, 0x594f, + 0x63cd, 0x79df, 0x8db3, 0x5352, 0x65cf, 0x7956, 0x8bc5, 0x963b, + 0x7ec4, 0x94bb, 0x7e82, 0x5634, 0x9189, 0x6700, 0x7f6a, 0x5c0a, + 0x9075, 0x6628, 0x5de6, 0x4f50, 0x67de, 0x505a, 0x4f5c, 0x5750, + 0x5ea7, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x58 */ + 0x4e8d, 0x4e0c, 0x5140, 0x4e10, 0x5eff, 0x5345, 0x4e15, 0x4e98, + 0x4e1e, 0x9b32, 0x5b6c, 0x5669, 0x4e28, 0x79ba, 0x4e3f, 0x5315, + 0x4e47, 0x592d, 0x723b, 0x536e, 0x6c10, 0x56df, 0x80e4, 0x9997, + 0x6bd3, 0x777e, 0x9f17, 0x4e36, 0x4e9f, 0x9f10, 0x4e5c, 0x4e69, + 0x4e93, 0x8288, 0x5b5b, 0x556c, 0x560f, 0x4ec4, 0x538d, 0x539d, + 0x53a3, 0x53a5, 0x53ae, 0x9765, 0x8d5d, 0x531a, 0x53f5, 0x5326, + 0x532e, 0x533e, 0x8d5c, 0x5366, 0x5363, 0x5202, 0x5208, 0x520e, + 0x522d, 0x5233, 0x523f, 0x5240, 0x524c, 0x525e, 0x5261, 0x525c, + 0x84af, 0x527d, 0x5282, 0x5281, 0x5290, 0x5293, 0x5182, 0x7f54, + 0x4ebb, 0x4ec3, 0x4ec9, 0x4ec2, 0x4ee8, 0x4ee1, 0x4eeb, 0x4ede, + 0x4f1b, 0x4ef3, 0x4f22, 0x4f64, 0x4ef5, 0x4f25, 0x4f27, 0x4f09, + 0x4f2b, 0x4f5e, 0x4f67, 0x6538, 0x4f5a, 0x4f5d, + /* 0x59 */ + 0x4f5f, 0x4f57, 0x4f32, 0x4f3d, 0x4f76, 0x4f74, 0x4f91, 0x4f89, + 0x4f83, 0x4f8f, 0x4f7e, 0x4f7b, 0x4faa, 0x4f7c, 0x4fac, 0x4f94, + 0x4fe6, 0x4fe8, 0x4fea, 0x4fc5, 0x4fda, 0x4fe3, 0x4fdc, 0x4fd1, + 0x4fdf, 0x4ff8, 0x5029, 0x504c, 0x4ff3, 0x502c, 0x500f, 0x502e, + 0x502d, 0x4ffe, 0x501c, 0x500c, 0x5025, 0x5028, 0x507e, 0x5043, + 0x5055, 0x5048, 0x504e, 0x506c, 0x507b, 0x50a5, 0x50a7, 0x50a9, + 0x50ba, 0x50d6, 0x5106, 0x50ed, 0x50ec, 0x50e6, 0x50ee, 0x5107, + 0x510b, 0x4edd, 0x6c3d, 0x4f58, 0x4f65, 0x4fce, 0x9fa0, 0x6c46, + 0x7c74, 0x516e, 0x5dfd, 0x9ec9, 0x9998, 0x5181, 0x5914, 0x52f9, + 0x530d, 0x8a07, 0x5310, 0x51eb, 0x5919, 0x5155, 0x4ea0, 0x5156, + 0x4eb3, 0x886e, 0x88a4, 0x4eb5, 0x8114, 0x88d2, 0x7980, 0x5b34, + 0x8803, 0x7fb8, 0x51ab, 0x51b1, 0x51bd, 0x51bc, + /* 0x5a */ + 0x51c7, 0x5196, 0x51a2, 0x51a5, 0x8ba0, 0x8ba6, 0x8ba7, 0x8baa, + 0x8bb4, 0x8bb5, 0x8bb7, 0x8bc2, 0x8bc3, 0x8bcb, 0x8bcf, 0x8bce, + 0x8bd2, 0x8bd3, 0x8bd4, 0x8bd6, 0x8bd8, 0x8bd9, 0x8bdc, 0x8bdf, + 0x8be0, 0x8be4, 0x8be8, 0x8be9, 0x8bee, 0x8bf0, 0x8bf3, 0x8bf6, + 0x8bf9, 0x8bfc, 0x8bff, 0x8c00, 0x8c02, 0x8c04, 0x8c07, 0x8c0c, + 0x8c0f, 0x8c11, 0x8c12, 0x8c14, 0x8c15, 0x8c16, 0x8c19, 0x8c1b, + 0x8c18, 0x8c1d, 0x8c1f, 0x8c20, 0x8c21, 0x8c25, 0x8c27, 0x8c2a, + 0x8c2b, 0x8c2e, 0x8c2f, 0x8c32, 0x8c33, 0x8c35, 0x8c36, 0x5369, + 0x537a, 0x961d, 0x9622, 0x9621, 0x9631, 0x962a, 0x963d, 0x963c, + 0x9642, 0x9649, 0x9654, 0x965f, 0x9667, 0x966c, 0x9672, 0x9674, + 0x9688, 0x968d, 0x9697, 0x96b0, 0x9097, 0x909b, 0x909d, 0x9099, + 0x90ac, 0x90a1, 0x90b4, 0x90b3, 0x90b6, 0x90ba, + /* 0x5b */ + 0x90b8, 0x90b0, 0x90cf, 0x90c5, 0x90be, 0x90d0, 0x90c4, 0x90c7, + 0x90d3, 0x90e6, 0x90e2, 0x90dc, 0x90d7, 0x90db, 0x90eb, 0x90ef, + 0x90fe, 0x9104, 0x9122, 0x911e, 0x9123, 0x9131, 0x912f, 0x9139, + 0x9143, 0x9146, 0x520d, 0x5942, 0x52a2, 0x52ac, 0x52ad, 0x52be, + 0x54ff, 0x52d0, 0x52d6, 0x52f0, 0x53df, 0x71ee, 0x77cd, 0x5ef4, + 0x51f5, 0x51fc, 0x9b2f, 0x53b6, 0x5f01, 0x755a, 0x5def, 0x574c, + 0x57a9, 0x57a1, 0x587e, 0x58bc, 0x58c5, 0x58d1, 0x5729, 0x572c, + 0x572a, 0x5733, 0x5739, 0x572e, 0x572f, 0x575c, 0x573b, 0x5742, + 0x5769, 0x5785, 0x576b, 0x5786, 0x577c, 0x577b, 0x5768, 0x576d, + 0x5776, 0x5773, 0x57ad, 0x57a4, 0x578c, 0x57b2, 0x57cf, 0x57a7, + 0x57b4, 0x5793, 0x57a0, 0x57d5, 0x57d8, 0x57da, 0x57d9, 0x57d2, + 0x57b8, 0x57f4, 0x57ef, 0x57f8, 0x57e4, 0x57dd, + /* 0x5c */ + 0x580b, 0x580d, 0x57fd, 0x57ed, 0x5800, 0x581e, 0x5819, 0x5844, + 0x5820, 0x5865, 0x586c, 0x5881, 0x5889, 0x589a, 0x5880, 0x99a8, + 0x9f19, 0x61ff, 0x8279, 0x827d, 0x827f, 0x828f, 0x828a, 0x82a8, + 0x8284, 0x828e, 0x8291, 0x8297, 0x8299, 0x82ab, 0x82b8, 0x82be, + 0x82b0, 0x82c8, 0x82ca, 0x82e3, 0x8298, 0x82b7, 0x82ae, 0x82cb, + 0x82cc, 0x82c1, 0x82a9, 0x82b4, 0x82a1, 0x82aa, 0x829f, 0x82c4, + 0x82ce, 0x82a4, 0x82e1, 0x8309, 0x82f7, 0x82e4, 0x830f, 0x8307, + 0x82dc, 0x82f4, 0x82d2, 0x82d8, 0x830c, 0x82fb, 0x82d3, 0x8311, + 0x831a, 0x8306, 0x8314, 0x8315, 0x82e0, 0x82d5, 0x831c, 0x8351, + 0x835b, 0x835c, 0x8308, 0x8392, 0x833c, 0x8334, 0x8331, 0x839b, + 0x835e, 0x832f, 0x834f, 0x8347, 0x8343, 0x835f, 0x8340, 0x8317, + 0x8360, 0x832d, 0x833a, 0x8333, 0x8366, 0x8365, + /* 0x5d */ + 0x8368, 0x831b, 0x8369, 0x836c, 0x836a, 0x836d, 0x836e, 0x83b0, + 0x8378, 0x83b3, 0x83b4, 0x83a0, 0x83aa, 0x8393, 0x839c, 0x8385, + 0x837c, 0x83b6, 0x83a9, 0x837d, 0x83b8, 0x837b, 0x8398, 0x839e, + 0x83a8, 0x83ba, 0x83bc, 0x83c1, 0x8401, 0x83e5, 0x83d8, 0x5807, + 0x8418, 0x840b, 0x83dd, 0x83fd, 0x83d6, 0x841c, 0x8438, 0x8411, + 0x8406, 0x83d4, 0x83df, 0x840f, 0x8403, 0x83f8, 0x83f9, 0x83ea, + 0x83c5, 0x83c0, 0x8426, 0x83f0, 0x83e1, 0x845c, 0x8451, 0x845a, + 0x8459, 0x8473, 0x8487, 0x8488, 0x847a, 0x8489, 0x8478, 0x843c, + 0x8446, 0x8469, 0x8476, 0x848c, 0x848e, 0x8431, 0x846d, 0x84c1, + 0x84cd, 0x84d0, 0x84e6, 0x84bd, 0x84d3, 0x84ca, 0x84bf, 0x84ba, + 0x84e0, 0x84a1, 0x84b9, 0x84b4, 0x8497, 0x84e5, 0x84e3, 0x850c, + 0x750d, 0x8538, 0x84f0, 0x8539, 0x851f, 0x853a, + /* 0x5e */ + 0x8556, 0x853b, 0x84ff, 0x84fc, 0x8559, 0x8548, 0x8568, 0x8564, + 0x855e, 0x857a, 0x77a2, 0x8543, 0x8572, 0x857b, 0x85a4, 0x85a8, + 0x8587, 0x858f, 0x8579, 0x85ae, 0x859c, 0x8585, 0x85b9, 0x85b7, + 0x85b0, 0x85d3, 0x85c1, 0x85dc, 0x85ff, 0x8627, 0x8605, 0x8629, + 0x8616, 0x863c, 0x5efe, 0x5f08, 0x593c, 0x5941, 0x8037, 0x5955, + 0x595a, 0x5958, 0x530f, 0x5c22, 0x5c25, 0x5c2c, 0x5c34, 0x624c, + 0x626a, 0x629f, 0x62bb, 0x62ca, 0x62da, 0x62d7, 0x62ee, 0x6322, + 0x62f6, 0x6339, 0x634b, 0x6343, 0x63ad, 0x63f6, 0x6371, 0x637a, + 0x638e, 0x63b4, 0x636d, 0x63ac, 0x638a, 0x6369, 0x63ae, 0x63bc, + 0x63f2, 0x63f8, 0x63e0, 0x63ff, 0x63c4, 0x63de, 0x63ce, 0x6452, + 0x63c6, 0x63be, 0x6445, 0x6441, 0x640b, 0x641b, 0x6420, 0x640c, + 0x6426, 0x6421, 0x645e, 0x6484, 0x646d, 0x6496, + /* 0x5f */ + 0x647a, 0x64b7, 0x64b8, 0x6499, 0x64ba, 0x64c0, 0x64d0, 0x64d7, + 0x64e4, 0x64e2, 0x6509, 0x6525, 0x652e, 0x5f0b, 0x5fd2, 0x7519, + 0x5f11, 0x535f, 0x53f1, 0x53fd, 0x53e9, 0x53e8, 0x53fb, 0x5412, + 0x5416, 0x5406, 0x544b, 0x5452, 0x5453, 0x5454, 0x5456, 0x5443, + 0x5421, 0x5457, 0x5459, 0x5423, 0x5432, 0x5482, 0x5494, 0x5477, + 0x5471, 0x5464, 0x549a, 0x549b, 0x5484, 0x5476, 0x5466, 0x549d, + 0x54d0, 0x54ad, 0x54c2, 0x54b4, 0x54d2, 0x54a7, 0x54a6, 0x54d3, + 0x54d4, 0x5472, 0x54a3, 0x54d5, 0x54bb, 0x54bf, 0x54cc, 0x54d9, + 0x54da, 0x54dc, 0x54a9, 0x54aa, 0x54a4, 0x54dd, 0x54cf, 0x54de, + 0x551b, 0x54e7, 0x5520, 0x54fd, 0x5514, 0x54f3, 0x5522, 0x5523, + 0x550f, 0x5511, 0x5527, 0x552a, 0x5567, 0x558f, 0x55b5, 0x5549, + 0x556d, 0x5541, 0x5555, 0x553f, 0x5550, 0x553c, + /* 0x60 */ + 0x5537, 0x5556, 0x5575, 0x5576, 0x5577, 0x5533, 0x5530, 0x555c, + 0x558b, 0x55d2, 0x5583, 0x55b1, 0x55b9, 0x5588, 0x5581, 0x559f, + 0x557e, 0x55d6, 0x5591, 0x557b, 0x55df, 0x55bd, 0x55be, 0x5594, + 0x5599, 0x55ea, 0x55f7, 0x55c9, 0x561f, 0x55d1, 0x55eb, 0x55ec, + 0x55d4, 0x55e6, 0x55dd, 0x55c4, 0x55ef, 0x55e5, 0x55f2, 0x55f3, + 0x55cc, 0x55cd, 0x55e8, 0x55f5, 0x55e4, 0x8f94, 0x561e, 0x5608, + 0x560c, 0x5601, 0x5624, 0x5623, 0x55fe, 0x5600, 0x5627, 0x562d, + 0x5658, 0x5639, 0x5657, 0x562c, 0x564d, 0x5662, 0x5659, 0x565c, + 0x564c, 0x5654, 0x5686, 0x5664, 0x5671, 0x566b, 0x567b, 0x567c, + 0x5685, 0x5693, 0x56af, 0x56d4, 0x56d7, 0x56dd, 0x56e1, 0x56f5, + 0x56eb, 0x56f9, 0x56ff, 0x5704, 0x570a, 0x5709, 0x571c, 0x5e0f, + 0x5e19, 0x5e14, 0x5e11, 0x5e31, 0x5e3b, 0x5e3c, + /* 0x61 */ + 0x5e37, 0x5e44, 0x5e54, 0x5e5b, 0x5e5e, 0x5e61, 0x5c8c, 0x5c7a, + 0x5c8d, 0x5c90, 0x5c96, 0x5c88, 0x5c98, 0x5c99, 0x5c91, 0x5c9a, + 0x5c9c, 0x5cb5, 0x5ca2, 0x5cbd, 0x5cac, 0x5cab, 0x5cb1, 0x5ca3, + 0x5cc1, 0x5cb7, 0x5cc4, 0x5cd2, 0x5ce4, 0x5ccb, 0x5ce5, 0x5d02, + 0x5d03, 0x5d27, 0x5d26, 0x5d2e, 0x5d24, 0x5d1e, 0x5d06, 0x5d1b, + 0x5d58, 0x5d3e, 0x5d34, 0x5d3d, 0x5d6c, 0x5d5b, 0x5d6f, 0x5d5d, + 0x5d6b, 0x5d4b, 0x5d4a, 0x5d69, 0x5d74, 0x5d82, 0x5d99, 0x5d9d, + 0x8c73, 0x5db7, 0x5dc5, 0x5f73, 0x5f77, 0x5f82, 0x5f87, 0x5f89, + 0x5f8c, 0x5f95, 0x5f99, 0x5f9c, 0x5fa8, 0x5fad, 0x5fb5, 0x5fbc, + 0x8862, 0x5f61, 0x72ad, 0x72b0, 0x72b4, 0x72b7, 0x72b8, 0x72c3, + 0x72c1, 0x72ce, 0x72cd, 0x72d2, 0x72e8, 0x72ef, 0x72e9, 0x72f2, + 0x72f4, 0x72f7, 0x7301, 0x72f3, 0x7303, 0x72fa, + /* 0x62 */ + 0x72fb, 0x7317, 0x7313, 0x7321, 0x730a, 0x731e, 0x731d, 0x7315, + 0x7322, 0x7339, 0x7325, 0x732c, 0x7338, 0x7331, 0x7350, 0x734d, + 0x7357, 0x7360, 0x736c, 0x736f, 0x737e, 0x821b, 0x5925, 0x98e7, + 0x5924, 0x5902, 0x9963, 0x9967, 0x9968, 0x9969, 0x996a, 0x996b, + 0x996c, 0x9974, 0x9977, 0x997d, 0x9980, 0x9984, 0x9987, 0x998a, + 0x998d, 0x9990, 0x9991, 0x9993, 0x9994, 0x9995, 0x5e80, 0x5e91, + 0x5e8b, 0x5e96, 0x5ea5, 0x5ea0, 0x5eb9, 0x5eb5, 0x5ebe, 0x5eb3, + 0x8d53, 0x5ed2, 0x5ed1, 0x5edb, 0x5ee8, 0x5eea, 0x81ba, 0x5fc4, + 0x5fc9, 0x5fd6, 0x5fcf, 0x6003, 0x5fee, 0x6004, 0x5fe1, 0x5fe4, + 0x5ffe, 0x6005, 0x6006, 0x5fea, 0x5fed, 0x5ff8, 0x6019, 0x6035, + 0x6026, 0x601b, 0x600f, 0x600d, 0x6029, 0x602b, 0x600a, 0x603f, + 0x6021, 0x6078, 0x6079, 0x607b, 0x607a, 0x6042, + /* 0x63 */ + 0x606a, 0x607d, 0x6096, 0x609a, 0x60ad, 0x609d, 0x6083, 0x6092, + 0x608c, 0x609b, 0x60ec, 0x60bb, 0x60b1, 0x60dd, 0x60d8, 0x60c6, + 0x60da, 0x60b4, 0x6120, 0x6126, 0x6115, 0x6123, 0x60f4, 0x6100, + 0x610e, 0x612b, 0x614a, 0x6175, 0x61ac, 0x6194, 0x61a7, 0x61b7, + 0x61d4, 0x61f5, 0x5fdd, 0x96b3, 0x95e9, 0x95eb, 0x95f1, 0x95f3, + 0x95f5, 0x95f6, 0x95fc, 0x95fe, 0x9603, 0x9604, 0x9606, 0x9608, + 0x960a, 0x960b, 0x960c, 0x960d, 0x960f, 0x9612, 0x9615, 0x9616, + 0x9617, 0x9619, 0x961a, 0x4e2c, 0x723f, 0x6215, 0x6c35, 0x6c54, + 0x6c5c, 0x6c4a, 0x6ca3, 0x6c85, 0x6c90, 0x6c94, 0x6c8c, 0x6c68, + 0x6c69, 0x6c74, 0x6c76, 0x6c86, 0x6ca9, 0x6cd0, 0x6cd4, 0x6cad, + 0x6cf7, 0x6cf8, 0x6cf1, 0x6cd7, 0x6cb2, 0x6ce0, 0x6cd6, 0x6cfa, + 0x6ceb, 0x6cee, 0x6cb1, 0x6cd3, 0x6cef, 0x6cfe, + /* 0x64 */ + 0x6d39, 0x6d27, 0x6d0c, 0x6d43, 0x6d48, 0x6d07, 0x6d04, 0x6d19, + 0x6d0e, 0x6d2b, 0x6d4d, 0x6d2e, 0x6d35, 0x6d1a, 0x6d4f, 0x6d52, + 0x6d54, 0x6d33, 0x6d91, 0x6d6f, 0x6d9e, 0x6da0, 0x6d5e, 0x6d93, + 0x6d94, 0x6d5c, 0x6d60, 0x6d7c, 0x6d63, 0x6e1a, 0x6dc7, 0x6dc5, + 0x6dde, 0x6e0e, 0x6dbf, 0x6de0, 0x6e11, 0x6de6, 0x6ddd, 0x6dd9, + 0x6e16, 0x6dab, 0x6e0c, 0x6dae, 0x6e2b, 0x6e6e, 0x6e4e, 0x6e6b, + 0x6eb2, 0x6e5f, 0x6e86, 0x6e53, 0x6e54, 0x6e32, 0x6e25, 0x6e44, + 0x6edf, 0x6eb1, 0x6e98, 0x6ee0, 0x6f2d, 0x6ee2, 0x6ea5, 0x6ea7, + 0x6ebd, 0x6ebb, 0x6eb7, 0x6ed7, 0x6eb4, 0x6ecf, 0x6e8f, 0x6ec2, + 0x6e9f, 0x6f62, 0x6f46, 0x6f47, 0x6f24, 0x6f15, 0x6ef9, 0x6f2f, + 0x6f36, 0x6f4b, 0x6f74, 0x6f2a, 0x6f09, 0x6f29, 0x6f89, 0x6f8d, + 0x6f8c, 0x6f78, 0x6f72, 0x6f7c, 0x6f7a, 0x6fd1, + /* 0x65 */ + 0x6fc9, 0x6fa7, 0x6fb9, 0x6fb6, 0x6fc2, 0x6fe1, 0x6fee, 0x6fde, + 0x6fe0, 0x6fef, 0x701a, 0x7023, 0x701b, 0x7039, 0x7035, 0x704f, + 0x705e, 0x5b80, 0x5b84, 0x5b95, 0x5b93, 0x5ba5, 0x5bb8, 0x752f, + 0x9a9e, 0x6434, 0x5be4, 0x5bee, 0x8930, 0x5bf0, 0x8e47, 0x8b07, + 0x8fb6, 0x8fd3, 0x8fd5, 0x8fe5, 0x8fee, 0x8fe4, 0x8fe9, 0x8fe6, + 0x8ff3, 0x8fe8, 0x9005, 0x9004, 0x900b, 0x9026, 0x9011, 0x900d, + 0x9016, 0x9021, 0x9035, 0x9036, 0x902d, 0x902f, 0x9044, 0x9051, + 0x9052, 0x9050, 0x9068, 0x9058, 0x9062, 0x905b, 0x66b9, 0x9074, + 0x907d, 0x9082, 0x9088, 0x9083, 0x908b, 0x5f50, 0x5f57, 0x5f56, + 0x5f58, 0x5c3b, 0x54ab, 0x5c50, 0x5c59, 0x5b71, 0x5c63, 0x5c66, + 0x7fbc, 0x5f2a, 0x5f29, 0x5f2d, 0x8274, 0x5f3c, 0x9b3b, 0x5c6e, + 0x5981, 0x5983, 0x598d, 0x59a9, 0x59aa, 0x59a3, + /* 0x66 */ + 0x5997, 0x59ca, 0x59ab, 0x599e, 0x59a4, 0x59d2, 0x59b2, 0x59af, + 0x59d7, 0x59be, 0x5a05, 0x5a06, 0x59dd, 0x5a08, 0x59e3, 0x59d8, + 0x59f9, 0x5a0c, 0x5a09, 0x5a32, 0x5a34, 0x5a11, 0x5a23, 0x5a13, + 0x5a40, 0x5a67, 0x5a4a, 0x5a55, 0x5a3c, 0x5a62, 0x5a75, 0x80ec, + 0x5aaa, 0x5a9b, 0x5a77, 0x5a7a, 0x5abe, 0x5aeb, 0x5ab2, 0x5ad2, + 0x5ad4, 0x5ab8, 0x5ae0, 0x5ae3, 0x5af1, 0x5ad6, 0x5ae6, 0x5ad8, + 0x5adc, 0x5b09, 0x5b17, 0x5b16, 0x5b32, 0x5b37, 0x5b40, 0x5c15, + 0x5c1c, 0x5b5a, 0x5b65, 0x5b73, 0x5b51, 0x5b53, 0x5b62, 0x9a75, + 0x9a77, 0x9a78, 0x9a7a, 0x9a7f, 0x9a7d, 0x9a80, 0x9a81, 0x9a85, + 0x9a88, 0x9a8a, 0x9a90, 0x9a92, 0x9a93, 0x9a96, 0x9a98, 0x9a9b, + 0x9a9c, 0x9a9d, 0x9a9f, 0x9aa0, 0x9aa2, 0x9aa3, 0x9aa5, 0x9aa7, + 0x7e9f, 0x7ea1, 0x7ea3, 0x7ea5, 0x7ea8, 0x7ea9, + /* 0x67 */ + 0x7ead, 0x7eb0, 0x7ebe, 0x7ec0, 0x7ec1, 0x7ec2, 0x7ec9, 0x7ecb, + 0x7ecc, 0x7ed0, 0x7ed4, 0x7ed7, 0x7edb, 0x7ee0, 0x7ee1, 0x7ee8, + 0x7eeb, 0x7eee, 0x7eef, 0x7ef1, 0x7ef2, 0x7f0d, 0x7ef6, 0x7efa, + 0x7efb, 0x7efe, 0x7f01, 0x7f02, 0x7f03, 0x7f07, 0x7f08, 0x7f0b, + 0x7f0c, 0x7f0f, 0x7f11, 0x7f12, 0x7f17, 0x7f19, 0x7f1c, 0x7f1b, + 0x7f1f, 0x7f21, 0x7f22, 0x7f23, 0x7f24, 0x7f25, 0x7f26, 0x7f27, + 0x7f2a, 0x7f2b, 0x7f2c, 0x7f2d, 0x7f2f, 0x7f30, 0x7f31, 0x7f32, + 0x7f33, 0x7f35, 0x5e7a, 0x757f, 0x5ddb, 0x753e, 0x9095, 0x738e, + 0x7391, 0x73ae, 0x73a2, 0x739f, 0x73cf, 0x73c2, 0x73d1, 0x73b7, + 0x73b3, 0x73c0, 0x73c9, 0x73c8, 0x73e5, 0x73d9, 0x987c, 0x740a, + 0x73e9, 0x73e7, 0x73de, 0x73ba, 0x73f2, 0x740f, 0x742a, 0x745b, + 0x7426, 0x7425, 0x7428, 0x7430, 0x742e, 0x742c, + /* 0x68 */ + 0x741b, 0x741a, 0x7441, 0x745c, 0x7457, 0x7455, 0x7459, 0x7477, + 0x746d, 0x747e, 0x749c, 0x748e, 0x7480, 0x7481, 0x7487, 0x748b, + 0x749e, 0x74a8, 0x74a9, 0x7490, 0x74a7, 0x74d2, 0x74ba, 0x97ea, + 0x97eb, 0x97ec, 0x674c, 0x6753, 0x675e, 0x6748, 0x6769, 0x67a5, + 0x6787, 0x676a, 0x6773, 0x6798, 0x67a7, 0x6775, 0x67a8, 0x679e, + 0x67ad, 0x678b, 0x6777, 0x677c, 0x67f0, 0x6809, 0x67d8, 0x680a, + 0x67e9, 0x67b0, 0x680c, 0x67d9, 0x67b5, 0x67da, 0x67b3, 0x67dd, + 0x6800, 0x67c3, 0x67b8, 0x67e2, 0x680e, 0x67c1, 0x67fd, 0x6832, + 0x6833, 0x6860, 0x6861, 0x684e, 0x6862, 0x6844, 0x6864, 0x6883, + 0x681d, 0x6855, 0x6866, 0x6841, 0x6867, 0x6840, 0x683e, 0x684a, + 0x6849, 0x6829, 0x68b5, 0x688f, 0x6874, 0x6877, 0x6893, 0x686b, + 0x68c2, 0x696e, 0x68fc, 0x691f, 0x6920, 0x68f9, + /* 0x69 */ + 0x6924, 0x68f0, 0x690b, 0x6901, 0x6957, 0x68e3, 0x6910, 0x6971, + 0x6939, 0x6960, 0x6942, 0x695d, 0x6984, 0x696b, 0x6980, 0x6998, + 0x6978, 0x6934, 0x69cc, 0x6987, 0x6988, 0x69ce, 0x6989, 0x6966, + 0x6963, 0x6979, 0x699b, 0x69a7, 0x69bb, 0x69ab, 0x69ad, 0x69d4, + 0x69b1, 0x69c1, 0x69ca, 0x69df, 0x6995, 0x69e0, 0x698d, 0x69ff, + 0x6a2f, 0x69ed, 0x6a17, 0x6a18, 0x6a65, 0x69f2, 0x6a44, 0x6a3e, + 0x6aa0, 0x6a50, 0x6a5b, 0x6a35, 0x6a8e, 0x6a79, 0x6a3d, 0x6a28, + 0x6a58, 0x6a7c, 0x6a91, 0x6a90, 0x6aa9, 0x6a97, 0x6aab, 0x7337, + 0x7352, 0x6b81, 0x6b82, 0x6b87, 0x6b84, 0x6b92, 0x6b93, 0x6b8d, + 0x6b9a, 0x6b9b, 0x6ba1, 0x6baa, 0x8f6b, 0x8f6d, 0x8f71, 0x8f72, + 0x8f73, 0x8f75, 0x8f76, 0x8f78, 0x8f77, 0x8f79, 0x8f7a, 0x8f7c, + 0x8f7e, 0x8f81, 0x8f82, 0x8f84, 0x8f87, 0x8f8b, + /* 0x6a */ + 0x8f8d, 0x8f8e, 0x8f8f, 0x8f98, 0x8f9a, 0x8ece, 0x620b, 0x6217, + 0x621b, 0x621f, 0x6222, 0x6221, 0x6225, 0x6224, 0x622c, 0x81e7, + 0x74ef, 0x74f4, 0x74ff, 0x750f, 0x7511, 0x7513, 0x6534, 0x65ee, + 0x65ef, 0x65f0, 0x660a, 0x6619, 0x6772, 0x6603, 0x6615, 0x6600, + 0x7085, 0x66f7, 0x661d, 0x6634, 0x6631, 0x6636, 0x6635, 0x8006, + 0x665f, 0x6654, 0x6641, 0x664f, 0x6656, 0x6661, 0x6657, 0x6677, + 0x6684, 0x668c, 0x66a7, 0x669d, 0x66be, 0x66db, 0x66dc, 0x66e6, + 0x66e9, 0x8d32, 0x8d33, 0x8d36, 0x8d3b, 0x8d3d, 0x8d40, 0x8d45, + 0x8d46, 0x8d48, 0x8d49, 0x8d47, 0x8d4d, 0x8d55, 0x8d59, 0x89c7, + 0x89ca, 0x89cb, 0x89cc, 0x89ce, 0x89cf, 0x89d0, 0x89d1, 0x726e, + 0x729f, 0x725d, 0x7266, 0x726f, 0x727e, 0x727f, 0x7284, 0x728b, + 0x728d, 0x728f, 0x7292, 0x6308, 0x6332, 0x63b0, + /* 0x6b */ + 0x643f, 0x64d8, 0x8004, 0x6bea, 0x6bf3, 0x6bfd, 0x6bf5, 0x6bf9, + 0x6c05, 0x6c07, 0x6c06, 0x6c0d, 0x6c15, 0x6c18, 0x6c19, 0x6c1a, + 0x6c21, 0x6c29, 0x6c24, 0x6c2a, 0x6c32, 0x6535, 0x6555, 0x656b, + 0x724d, 0x7252, 0x7256, 0x7230, 0x8662, 0x5216, 0x809f, 0x809c, + 0x8093, 0x80bc, 0x670a, 0x80bd, 0x80b1, 0x80ab, 0x80ad, 0x80b4, + 0x80b7, 0x80e7, 0x80e8, 0x80e9, 0x80ea, 0x80db, 0x80c2, 0x80c4, + 0x80d9, 0x80cd, 0x80d7, 0x6710, 0x80dd, 0x80eb, 0x80f1, 0x80f4, + 0x80ed, 0x810d, 0x810e, 0x80f2, 0x80fc, 0x6715, 0x8112, 0x8c5a, + 0x8136, 0x811e, 0x812c, 0x8118, 0x8132, 0x8148, 0x814c, 0x8153, + 0x8174, 0x8159, 0x815a, 0x8171, 0x8160, 0x8169, 0x817c, 0x817d, + 0x816d, 0x8167, 0x584d, 0x5ab5, 0x8188, 0x8182, 0x8191, 0x6ed5, + 0x81a3, 0x81aa, 0x81cc, 0x6726, 0x81ca, 0x81bb, + /* 0x6c */ + 0x81c1, 0x81a6, 0x6b24, 0x6b37, 0x6b39, 0x6b43, 0x6b46, 0x6b59, + 0x98d1, 0x98d2, 0x98d3, 0x98d5, 0x98d9, 0x98da, 0x6bb3, 0x5f40, + 0x6bc2, 0x89f3, 0x6590, 0x9f51, 0x6593, 0x65bc, 0x65c6, 0x65c4, + 0x65c3, 0x65cc, 0x65ce, 0x65d2, 0x65d6, 0x7080, 0x709c, 0x7096, + 0x709d, 0x70bb, 0x70c0, 0x70b7, 0x70ab, 0x70b1, 0x70e8, 0x70ca, + 0x7110, 0x7113, 0x7116, 0x712f, 0x7131, 0x7173, 0x715c, 0x7168, + 0x7145, 0x7172, 0x714a, 0x7178, 0x717a, 0x7198, 0x71b3, 0x71b5, + 0x71a8, 0x71a0, 0x71e0, 0x71d4, 0x71e7, 0x71f9, 0x721d, 0x7228, + 0x706c, 0x7118, 0x7166, 0x71b9, 0x623e, 0x623d, 0x6243, 0x6248, + 0x6249, 0x793b, 0x7940, 0x7946, 0x7949, 0x795b, 0x795c, 0x7953, + 0x795a, 0x7962, 0x7957, 0x7960, 0x796f, 0x7967, 0x797a, 0x7985, + 0x798a, 0x799a, 0x79a7, 0x79b3, 0x5fd1, 0x5fd0, + /* 0x6d */ + 0x603c, 0x605d, 0x605a, 0x6067, 0x6041, 0x6059, 0x6063, 0x60ab, + 0x6106, 0x610d, 0x615d, 0x61a9, 0x619d, 0x61cb, 0x61d1, 0x6206, + 0x8080, 0x807f, 0x6c93, 0x6cf6, 0x6dfc, 0x77f6, 0x77f8, 0x7800, + 0x7809, 0x7817, 0x7818, 0x7811, 0x65ab, 0x782d, 0x781c, 0x781d, + 0x7839, 0x783a, 0x783b, 0x781f, 0x783c, 0x7825, 0x782c, 0x7823, + 0x7829, 0x784e, 0x786d, 0x7856, 0x7857, 0x7826, 0x7850, 0x7847, + 0x784c, 0x786a, 0x789b, 0x7893, 0x789a, 0x7887, 0x789c, 0x78a1, + 0x78a3, 0x78b2, 0x78b9, 0x78a5, 0x78d4, 0x78d9, 0x78c9, 0x78ec, + 0x78f2, 0x7905, 0x78f4, 0x7913, 0x7924, 0x791e, 0x7934, 0x9f9b, + 0x9ef9, 0x9efb, 0x9efc, 0x76f1, 0x7704, 0x770d, 0x76f9, 0x7707, + 0x7708, 0x771a, 0x7722, 0x7719, 0x772d, 0x7726, 0x7735, 0x7738, + 0x7750, 0x7751, 0x7747, 0x7743, 0x775a, 0x7768, + /* 0x6e */ + 0x7762, 0x7765, 0x777f, 0x778d, 0x777d, 0x7780, 0x778c, 0x7791, + 0x779f, 0x77a0, 0x77b0, 0x77b5, 0x77bd, 0x753a, 0x7540, 0x754e, + 0x754b, 0x7548, 0x755b, 0x7572, 0x7579, 0x7583, 0x7f58, 0x7f61, + 0x7f5f, 0x8a48, 0x7f68, 0x7f74, 0x7f71, 0x7f79, 0x7f81, 0x7f7e, + 0x76cd, 0x76e5, 0x8832, 0x9485, 0x9486, 0x9487, 0x948b, 0x948a, + 0x948c, 0x948d, 0x948f, 0x9490, 0x9494, 0x9497, 0x9495, 0x949a, + 0x949b, 0x949c, 0x94a3, 0x94a4, 0x94ab, 0x94aa, 0x94ad, 0x94ac, + 0x94af, 0x94b0, 0x94b2, 0x94b4, 0x94b6, 0x94b7, 0x94b8, 0x94b9, + 0x94ba, 0x94bc, 0x94bd, 0x94bf, 0x94c4, 0x94c8, 0x94c9, 0x94ca, + 0x94cb, 0x94cc, 0x94cd, 0x94ce, 0x94d0, 0x94d1, 0x94d2, 0x94d5, + 0x94d6, 0x94d7, 0x94d9, 0x94d8, 0x94db, 0x94de, 0x94df, 0x94e0, + 0x94e2, 0x94e4, 0x94e5, 0x94e7, 0x94e8, 0x94ea, + /* 0x6f */ + 0x94e9, 0x94eb, 0x94ee, 0x94ef, 0x94f3, 0x94f4, 0x94f5, 0x94f7, + 0x94f9, 0x94fc, 0x94fd, 0x94ff, 0x9503, 0x9502, 0x9506, 0x9507, + 0x9509, 0x950a, 0x950d, 0x950e, 0x950f, 0x9512, 0x9513, 0x9514, + 0x9515, 0x9516, 0x9518, 0x951b, 0x951d, 0x951e, 0x951f, 0x9522, + 0x952a, 0x952b, 0x9529, 0x952c, 0x9531, 0x9532, 0x9534, 0x9536, + 0x9537, 0x9538, 0x953c, 0x953e, 0x953f, 0x9542, 0x9535, 0x9544, + 0x9545, 0x9546, 0x9549, 0x954c, 0x954e, 0x954f, 0x9552, 0x9553, + 0x9554, 0x9556, 0x9557, 0x9558, 0x9559, 0x955b, 0x955e, 0x955f, + 0x955d, 0x9561, 0x9562, 0x9564, 0x9565, 0x9566, 0x9567, 0x9568, + 0x9569, 0x956a, 0x956b, 0x956c, 0x956f, 0x9571, 0x9572, 0x9573, + 0x953a, 0x77e7, 0x77ec, 0x96c9, 0x79d5, 0x79ed, 0x79e3, 0x79eb, + 0x7a06, 0x5d47, 0x7a03, 0x7a02, 0x7a1e, 0x7a14, + /* 0x70 */ + 0x7a39, 0x7a37, 0x7a51, 0x9ecf, 0x99a5, 0x7a70, 0x7688, 0x768e, + 0x7693, 0x7699, 0x76a4, 0x74de, 0x74e0, 0x752c, 0x9e20, 0x9e22, + 0x9e28, 0x9e29, 0x9e2a, 0x9e2b, 0x9e2c, 0x9e32, 0x9e31, 0x9e36, + 0x9e38, 0x9e37, 0x9e39, 0x9e3a, 0x9e3e, 0x9e41, 0x9e42, 0x9e44, + 0x9e46, 0x9e47, 0x9e48, 0x9e49, 0x9e4b, 0x9e4c, 0x9e4e, 0x9e51, + 0x9e55, 0x9e57, 0x9e5a, 0x9e5b, 0x9e5c, 0x9e5e, 0x9e63, 0x9e66, + 0x9e67, 0x9e68, 0x9e69, 0x9e6a, 0x9e6b, 0x9e6c, 0x9e71, 0x9e6d, + 0x9e73, 0x7592, 0x7594, 0x7596, 0x75a0, 0x759d, 0x75ac, 0x75a3, + 0x75b3, 0x75b4, 0x75b8, 0x75c4, 0x75b1, 0x75b0, 0x75c3, 0x75c2, + 0x75d6, 0x75cd, 0x75e3, 0x75e8, 0x75e6, 0x75e4, 0x75eb, 0x75e7, + 0x7603, 0x75f1, 0x75fc, 0x75ff, 0x7610, 0x7600, 0x7605, 0x760c, + 0x7617, 0x760a, 0x7625, 0x7618, 0x7615, 0x7619, + /* 0x71 */ + 0x761b, 0x763c, 0x7622, 0x7620, 0x7640, 0x762d, 0x7630, 0x763f, + 0x7635, 0x7643, 0x763e, 0x7633, 0x764d, 0x765e, 0x7654, 0x765c, + 0x7656, 0x766b, 0x766f, 0x7fca, 0x7ae6, 0x7a78, 0x7a79, 0x7a80, + 0x7a86, 0x7a88, 0x7a95, 0x7aa6, 0x7aa0, 0x7aac, 0x7aa8, 0x7aad, + 0x7ab3, 0x8864, 0x8869, 0x8872, 0x887d, 0x887f, 0x8882, 0x88a2, + 0x88c6, 0x88b7, 0x88bc, 0x88c9, 0x88e2, 0x88ce, 0x88e3, 0x88e5, + 0x88f1, 0x891a, 0x88fc, 0x88e8, 0x88fe, 0x88f0, 0x8921, 0x8919, + 0x8913, 0x891b, 0x890a, 0x8934, 0x892b, 0x8936, 0x8941, 0x8966, + 0x897b, 0x758b, 0x80e5, 0x76b2, 0x76b4, 0x77dc, 0x8012, 0x8014, + 0x8016, 0x801c, 0x8020, 0x8022, 0x8025, 0x8026, 0x8027, 0x8029, + 0x8028, 0x8031, 0x800b, 0x8035, 0x8043, 0x8046, 0x804d, 0x8052, + 0x8069, 0x8071, 0x8983, 0x9878, 0x9880, 0x9883, + /* 0x72 */ + 0x9889, 0x988c, 0x988d, 0x988f, 0x9894, 0x989a, 0x989b, 0x989e, + 0x989f, 0x98a1, 0x98a2, 0x98a5, 0x98a6, 0x864d, 0x8654, 0x866c, + 0x866e, 0x867f, 0x867a, 0x867c, 0x867b, 0x86a8, 0x868d, 0x868b, + 0x86ac, 0x869d, 0x86a7, 0x86a3, 0x86aa, 0x8693, 0x86a9, 0x86b6, + 0x86c4, 0x86b5, 0x86ce, 0x86b0, 0x86ba, 0x86b1, 0x86af, 0x86c9, + 0x86cf, 0x86b4, 0x86e9, 0x86f1, 0x86f2, 0x86ed, 0x86f3, 0x86d0, + 0x8713, 0x86de, 0x86f4, 0x86df, 0x86d8, 0x86d1, 0x8703, 0x8707, + 0x86f8, 0x8708, 0x870a, 0x870d, 0x8709, 0x8723, 0x873b, 0x871e, + 0x8725, 0x872e, 0x871a, 0x873e, 0x8748, 0x8734, 0x8731, 0x8729, + 0x8737, 0x873f, 0x8782, 0x8722, 0x877d, 0x877e, 0x877b, 0x8760, + 0x8770, 0x874c, 0x876e, 0x878b, 0x8753, 0x8763, 0x877c, 0x8764, + 0x8759, 0x8765, 0x8793, 0x87af, 0x87a8, 0x87d2, + /* 0x73 */ + 0x87c6, 0x8788, 0x8785, 0x87ad, 0x8797, 0x8783, 0x87ab, 0x87e5, + 0x87ac, 0x87b5, 0x87b3, 0x87cb, 0x87d3, 0x87bd, 0x87d1, 0x87c0, + 0x87ca, 0x87db, 0x87ea, 0x87e0, 0x87ee, 0x8816, 0x8813, 0x87fe, + 0x880a, 0x881b, 0x8821, 0x8839, 0x883c, 0x7f36, 0x7f42, 0x7f44, + 0x7f45, 0x8210, 0x7afa, 0x7afd, 0x7b08, 0x7b03, 0x7b04, 0x7b15, + 0x7b0a, 0x7b2b, 0x7b0f, 0x7b47, 0x7b38, 0x7b2a, 0x7b19, 0x7b2e, + 0x7b31, 0x7b20, 0x7b25, 0x7b24, 0x7b33, 0x7b3e, 0x7b1e, 0x7b58, + 0x7b5a, 0x7b45, 0x7b75, 0x7b4c, 0x7b5d, 0x7b60, 0x7b6e, 0x7b7b, + 0x7b62, 0x7b72, 0x7b71, 0x7b90, 0x7ba6, 0x7ba7, 0x7bb8, 0x7bac, + 0x7b9d, 0x7ba8, 0x7b85, 0x7baa, 0x7b9c, 0x7ba2, 0x7bab, 0x7bb4, + 0x7bd1, 0x7bc1, 0x7bcc, 0x7bdd, 0x7bda, 0x7be5, 0x7be6, 0x7bea, + 0x7c0c, 0x7bfe, 0x7bfc, 0x7c0f, 0x7c16, 0x7c0b, + /* 0x74 */ + 0x7c1f, 0x7c2a, 0x7c26, 0x7c38, 0x7c41, 0x7c40, 0x81fe, 0x8201, + 0x8202, 0x8204, 0x81ec, 0x8844, 0x8221, 0x8222, 0x8223, 0x822d, + 0x822f, 0x8228, 0x822b, 0x8238, 0x823b, 0x8233, 0x8234, 0x823e, + 0x8244, 0x8249, 0x824b, 0x824f, 0x825a, 0x825f, 0x8268, 0x887e, + 0x8885, 0x8888, 0x88d8, 0x88df, 0x895e, 0x7f9d, 0x7f9f, 0x7fa7, + 0x7faf, 0x7fb0, 0x7fb2, 0x7c7c, 0x6549, 0x7c91, 0x7c9d, 0x7c9c, + 0x7c9e, 0x7ca2, 0x7cb2, 0x7cbc, 0x7cbd, 0x7cc1, 0x7cc7, 0x7ccc, + 0x7ccd, 0x7cc8, 0x7cc5, 0x7cd7, 0x7ce8, 0x826e, 0x66a8, 0x7fbf, + 0x7fce, 0x7fd5, 0x7fe5, 0x7fe1, 0x7fe6, 0x7fe9, 0x7fee, 0x7ff3, + 0x7cf8, 0x7d77, 0x7da6, 0x7dae, 0x7e47, 0x7e9b, 0x9eb8, 0x9eb4, + 0x8d73, 0x8d84, 0x8d94, 0x8d91, 0x8db1, 0x8d67, 0x8d6d, 0x8c47, + 0x8c49, 0x914a, 0x9150, 0x914e, 0x914f, 0x9164, + /* 0x75 */ + 0x9162, 0x9161, 0x9170, 0x9169, 0x916f, 0x917d, 0x917e, 0x9172, + 0x9174, 0x9179, 0x918c, 0x9185, 0x9190, 0x918d, 0x9191, 0x91a2, + 0x91a3, 0x91aa, 0x91ad, 0x91ae, 0x91af, 0x91b5, 0x91b4, 0x91ba, + 0x8c55, 0x9e7e, 0x8db8, 0x8deb, 0x8e05, 0x8e59, 0x8e69, 0x8db5, + 0x8dbf, 0x8dbc, 0x8dba, 0x8dc4, 0x8dd6, 0x8dd7, 0x8dda, 0x8dde, + 0x8dce, 0x8dcf, 0x8ddb, 0x8dc6, 0x8dec, 0x8df7, 0x8df8, 0x8de3, + 0x8df9, 0x8dfb, 0x8de4, 0x8e09, 0x8dfd, 0x8e14, 0x8e1d, 0x8e1f, + 0x8e2c, 0x8e2e, 0x8e23, 0x8e2f, 0x8e3a, 0x8e40, 0x8e39, 0x8e35, + 0x8e3d, 0x8e31, 0x8e49, 0x8e41, 0x8e42, 0x8e51, 0x8e52, 0x8e4a, + 0x8e70, 0x8e76, 0x8e7c, 0x8e6f, 0x8e74, 0x8e85, 0x8e8f, 0x8e94, + 0x8e90, 0x8e9c, 0x8e9e, 0x8c78, 0x8c82, 0x8c8a, 0x8c85, 0x8c98, + 0x8c94, 0x659b, 0x89d6, 0x89de, 0x89da, 0x89dc, + /* 0x76 */ + 0x89e5, 0x89eb, 0x89ef, 0x8a3e, 0x8b26, 0x9753, 0x96e9, 0x96f3, + 0x96ef, 0x9706, 0x9701, 0x9708, 0x970f, 0x970e, 0x972a, 0x972d, + 0x9730, 0x973e, 0x9f80, 0x9f83, 0x9f85, 0x9f86, 0x9f87, 0x9f88, + 0x9f89, 0x9f8a, 0x9f8c, 0x9efe, 0x9f0b, 0x9f0d, 0x96b9, 0x96bc, + 0x96bd, 0x96ce, 0x96d2, 0x77bf, 0x96e0, 0x928e, 0x92ae, 0x92c8, + 0x933e, 0x936a, 0x93ca, 0x938f, 0x943e, 0x946b, 0x9c7f, 0x9c82, + 0x9c85, 0x9c86, 0x9c87, 0x9c88, 0x7a23, 0x9c8b, 0x9c8e, 0x9c90, + 0x9c91, 0x9c92, 0x9c94, 0x9c95, 0x9c9a, 0x9c9b, 0x9c9e, 0x9c9f, + 0x9ca0, 0x9ca1, 0x9ca2, 0x9ca3, 0x9ca5, 0x9ca6, 0x9ca7, 0x9ca8, + 0x9ca9, 0x9cab, 0x9cad, 0x9cae, 0x9cb0, 0x9cb1, 0x9cb2, 0x9cb3, + 0x9cb4, 0x9cb5, 0x9cb6, 0x9cb7, 0x9cba, 0x9cbb, 0x9cbc, 0x9cbd, + 0x9cc4, 0x9cc5, 0x9cc6, 0x9cc7, 0x9cca, 0x9ccb, + /* 0x77 */ + 0x9ccc, 0x9ccd, 0x9cce, 0x9ccf, 0x9cd0, 0x9cd3, 0x9cd4, 0x9cd5, + 0x9cd7, 0x9cd8, 0x9cd9, 0x9cdc, 0x9cdd, 0x9cdf, 0x9ce2, 0x977c, + 0x9785, 0x9791, 0x9792, 0x9794, 0x97af, 0x97ab, 0x97a3, 0x97b2, + 0x97b4, 0x9ab1, 0x9ab0, 0x9ab7, 0x9e58, 0x9ab6, 0x9aba, 0x9abc, + 0x9ac1, 0x9ac0, 0x9ac5, 0x9ac2, 0x9acb, 0x9acc, 0x9ad1, 0x9b45, + 0x9b43, 0x9b47, 0x9b49, 0x9b48, 0x9b4d, 0x9b51, 0x98e8, 0x990d, + 0x992e, 0x9955, 0x9954, 0x9adf, 0x9ae1, 0x9ae6, 0x9aef, 0x9aeb, + 0x9afb, 0x9aed, 0x9af9, 0x9b08, 0x9b0f, 0x9b13, 0x9b1f, 0x9b23, + 0x9ebd, 0x9ebe, 0x7e3b, 0x9e82, 0x9e87, 0x9e88, 0x9e8b, 0x9e92, + 0x93d6, 0x9e9d, 0x9e9f, 0x9edb, 0x9edc, 0x9edd, 0x9ee0, 0x9edf, + 0x9ee2, 0x9ee9, 0x9ee7, 0x9ee5, 0x9eea, 0x9eef, 0x9f22, 0x9f2c, + 0x9f2f, 0x9f39, 0x9f37, 0x9f3d, 0x9f3e, 0x9f44, +}; + +static int +gb2312_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x21 && c1 <= 0x29) || (c1 >= 0x30 && c1 <= 0x77)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + unsigned short wc = 0xfffd; + if (i < 1410) { + if (i < 831) + wc = gb2312_2uni_page21[i]; + } else { + if (i < 8178) + wc = gb2312_2uni_page30[i-1410]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short gb2312_2charset[7445] = { + 0x2168, 0x216c, 0x2127, 0x2163, 0x2140, 0x2141, 0x2824, 0x2822, + 0x2828, 0x2826, 0x283a, 0x282c, 0x282a, 0x2830, 0x282e, 0x2142, + 0x2834, 0x2832, 0x2839, 0x2821, 0x2825, 0x2827, 0x2829, 0x282d, + 0x2831, 0x2823, 0x282b, 0x282f, 0x2833, 0x2835, 0x2836, 0x2837, + 0x2838, 0x2126, 0x2125, 0x2621, 0x2622, 0x2623, 0x2624, 0x2625, + 0x2626, 0x2627, 0x2628, 0x2629, 0x262a, 0x262b, 0x262c, 0x262d, + 0x262e, 0x262f, 0x2630, 0x2631, 0x2632, 0x2633, 0x2634, 0x2635, + 0x2636, 0x2637, 0x2638, 0x2641, 0x2642, 0x2643, 0x2644, 0x2645, + 0x2646, 0x2647, 0x2648, 0x2649, 0x264a, 0x264b, 0x264c, 0x264d, + 0x264e, 0x264f, 0x2650, 0x2651, 0x2652, 0x2653, 0x2654, 0x2655, + 0x2656, 0x2657, 0x2658, 0x2727, 0x2721, 0x2722, 0x2723, 0x2724, + 0x2725, 0x2726, 0x2728, 0x2729, 0x272a, 0x272b, 0x272c, 0x272d, + 0x272e, 0x272f, 0x2730, 0x2731, 0x2732, 0x2733, 0x2734, 0x2735, + 0x2736, 0x2737, 0x2738, 0x2739, 0x273a, 0x273b, 0x273c, 0x273d, + 0x273e, 0x273f, 0x2740, 0x2741, 0x2751, 0x2752, 0x2753, 0x2754, + 0x2755, 0x2756, 0x2758, 0x2759, 0x275a, 0x275b, 0x275c, 0x275d, + 0x275e, 0x275f, 0x2760, 0x2761, 0x2762, 0x2763, 0x2764, 0x2765, + 0x2766, 0x2767, 0x2768, 0x2769, 0x276a, 0x276b, 0x276c, 0x276d, + 0x276e, 0x276f, 0x2770, 0x2771, 0x2757, 0x212a, 0x212c, 0x212e, + 0x212f, 0x2130, 0x2131, 0x212d, 0x216b, 0x2164, 0x2165, 0x2179, + 0x2166, 0x216d, 0x2271, 0x2272, 0x2273, 0x2274, 0x2275, 0x2276, + 0x2277, 0x2278, 0x2279, 0x227a, 0x227b, 0x227c, 0x217b, 0x217c, + 0x217a, 0x217d, 0x214a, 0x2147, 0x2146, 0x214c, 0x2158, 0x215e, + 0x214f, 0x214e, 0x2144, 0x2145, 0x2149, 0x2148, 0x2152, 0x2153, + 0x2160, 0x215f, 0x2143, 0x214b, 0x2157, 0x2156, 0x2155, 0x2159, + 0x2154, 0x215c, 0x215d, 0x215a, 0x215b, 0x2151, 0x214d, 0x2150, + 0x2259, 0x225a, 0x225b, 0x225c, 0x225d, 0x225e, 0x225f, 0x2260, + 0x2261, 0x2262, 0x2245, 0x2246, 0x2247, 0x2248, 0x2249, 0x224a, + 0x224b, 0x224c, 0x224d, 0x224e, 0x224f, 0x2250, 0x2251, 0x2252, + 0x2253, 0x2254, 0x2255, 0x2256, 0x2257, 0x2258, 0x2231, 0x2232, + 0x2233, 0x2234, 0x2235, 0x2236, 0x2237, 0x2238, 0x2239, 0x223a, + 0x223b, 0x223c, 0x223d, 0x223e, 0x223f, 0x2240, 0x2241, 0x2242, + 0x2243, 0x2244, 0x2924, 0x2925, 0x2926, 0x2927, 0x2928, 0x2929, + 0x292a, 0x292b, 0x292c, 0x292d, 0x292e, 0x292f, 0x2930, 0x2931, + 0x2932, 0x2933, 0x2934, 0x2935, 0x2936, 0x2937, 0x2938, 0x2939, + 0x293a, 0x293b, 0x293c, 0x293d, 0x293e, 0x293f, 0x2940, 0x2941, + 0x2942, 0x2943, 0x2944, 0x2945, 0x2946, 0x2947, 0x2948, 0x2949, + 0x294a, 0x294b, 0x294c, 0x294d, 0x294e, 0x294f, 0x2950, 0x2951, + 0x2952, 0x2953, 0x2954, 0x2955, 0x2956, 0x2957, 0x2958, 0x2959, + 0x295a, 0x295b, 0x295c, 0x295d, 0x295e, 0x295f, 0x2960, 0x2961, + 0x2962, 0x2963, 0x2964, 0x2965, 0x2966, 0x2967, 0x2968, 0x2969, + 0x296a, 0x296b, 0x296c, 0x296d, 0x296e, 0x296f, 0x2176, 0x2175, + 0x2178, 0x2177, 0x2174, 0x2173, 0x2170, 0x2172, 0x2171, 0x216f, + 0x216e, 0x2162, 0x2161, 0x2121, 0x2122, 0x2123, 0x2128, 0x2129, + 0x2134, 0x2135, 0x2136, 0x2137, 0x2138, 0x2139, 0x213a, 0x213b, + 0x213e, 0x213f, 0x217e, 0x2132, 0x2133, 0x213c, 0x213d, 0x2421, + 0x2422, 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, 0x2428, 0x2429, + 0x242a, 0x242b, 0x242c, 0x242d, 0x242e, 0x242f, 0x2430, 0x2431, + 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, 0x2438, 0x2439, + 0x243a, 0x243b, 0x243c, 0x243d, 0x243e, 0x243f, 0x2440, 0x2441, + 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, 0x2447, 0x2448, 0x2449, + 0x244a, 0x244b, 0x244c, 0x244d, 0x244e, 0x244f, 0x2450, 0x2451, + 0x2452, 0x2453, 0x2454, 0x2455, 0x2456, 0x2457, 0x2458, 0x2459, + 0x245a, 0x245b, 0x245c, 0x245d, 0x245e, 0x245f, 0x2460, 0x2461, + 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, + 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, 0x2470, 0x2471, + 0x2472, 0x2473, 0x2521, 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, + 0x2527, 0x2528, 0x2529, 0x252a, 0x252b, 0x252c, 0x252d, 0x252e, + 0x252f, 0x2530, 0x2531, 0x2532, 0x2533, 0x2534, 0x2535, 0x2536, + 0x2537, 0x2538, 0x2539, 0x253a, 0x253b, 0x253c, 0x253d, 0x253e, + 0x253f, 0x2540, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, 0x2546, + 0x2547, 0x2548, 0x2549, 0x254a, 0x254b, 0x254c, 0x254d, 0x254e, + 0x254f, 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, 0x2556, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, + 0x255f, 0x2560, 0x2561, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, + 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x256d, 0x256e, + 0x256f, 0x2570, 0x2571, 0x2572, 0x2573, 0x2574, 0x2575, 0x2576, + 0x2124, 0x2845, 0x2846, 0x2847, 0x2848, 0x2849, 0x284a, 0x284b, + 0x284c, 0x284d, 0x284e, 0x284f, 0x2850, 0x2851, 0x2852, 0x2853, + 0x2854, 0x2855, 0x2856, 0x2857, 0x2858, 0x2859, 0x285a, 0x285b, + 0x285c, 0x285d, 0x285e, 0x285f, 0x2860, 0x2861, 0x2862, 0x2863, + 0x2864, 0x2865, 0x2866, 0x2867, 0x2868, 0x2869, 0x2265, 0x2266, + 0x2267, 0x2268, 0x2269, 0x226a, 0x226b, 0x226c, 0x226d, 0x226e, + 0x523b, 0x3621, 0x465f, 0x4d72, 0x5549, 0x487d, 0x494f, 0x4f42, + 0x5822, 0x323b, 0x536b, 0x5824, 0x3373, 0x5728, 0x4752, 0x5827, + 0x4a40, 0x4770, 0x317b, 0x5235, 0x3454, 0x362b, 0x4b3f, 0x5829, + 0x362a, 0x413d, 0x514f, 0x4925, 0x582d, 0x3876, 0x513e, 0x635c, + 0x5650, 0x3761, 0x342e, 0x4159, 0x583c, 0x4d68, 0x3524, 0x4e2a, + 0x5677, 0x4076, 0x3e59, 0x582f, 0x444b, 0x3e43, 0x5831, 0x4334, + 0x5265, 0x562e, 0x4e5a, 0x5527, 0x3a75, 0x3726, 0x4056, 0x4639, + 0x4552, 0x4747, 0x3954, 0x334b, 0x5252, 0x583f, 0x3e45, 0x4672, + 0x5232, 0x4f30, 0x4f67, 0x4a69, 0x5840, 0x4272, 0x4252, 0x4869, + 0x472c, 0x414b, 0x5368, 0x5579, 0x4a42, 0x367e, 0x5821, 0x535a, + 0x3f77, 0x5446, 0x3b25, 0x5841, 0x4e65, 0x3e2e, 0x5828, 0x5147, + 0x5029, 0x583d, 0x596f, 0x4d76, 0x3f3a, 0x3d3b, 0x3a25, 0x5260, + 0x327a, 0x3a60, 0x4436, 0x4f6d, 0x3e29, 0x4d24, 0x4141, 0x4757, + 0x5971, 0x5974, 0x484b, 0x5869, 0x525a, 0x4a32, 0x484a, 0x586c, + 0x586a, 0x5846, 0x3d76, 0x464d, 0x3370, 0x586b, 0x3d71, 0x3d69, + 0x4854, 0x3453, 0x4258, 0x3256, 0x5750, 0x4a4b, 0x4b7b, 0x554c, + 0x3836, 0x4f49, 0x595a, 0x5870, 0x472a, 0x586e, 0x347a, 0x416e, + 0x5254, 0x586d, 0x5247, 0x586f, 0x4347, 0x5176, 0x5659, 0x5872, + 0x5875, 0x3c7e, 0x3c5b, 0x484e, 0x375d, 0x3742, 0x4673, 0x5878, + 0x5241, 0x4e69, 0x3c3f, 0x377c, 0x3725, 0x505d, 0x565a, 0x5345, + 0x3b6f, 0x3b61, 0x5871, 0x4921, 0x4e30, 0x342b, 0x5873, 0x494b, + 0x5876, 0x4257, 0x5877, 0x4e31, 0x5879, 0x322e, 0x3940, 0x5923, + 0x3069, 0x4166, 0x496c, 0x4b45, 0x4b46, 0x5924, 0x3568, 0x352b, + 0x4e3b, 0x354d, 0x5721, 0x5774, 0x5353, 0x4c65, 0x3a4e, 0x5922, + 0x595c, 0x5360, 0x587d, 0x3770, 0x5777, 0x587e, 0x587a, 0x5921, + 0x4463, 0x5336, 0x5874, 0x595d, 0x587b, 0x4565, 0x4050, 0x5170, + 0x305b, 0x3c51, 0x5926, 0x5925, 0x592c, 0x592e, 0x592b, 0x4a39, + 0x5929, 0x5636, 0x335e, 0x5928, 0x407d, 0x4a4c, 0x592a, 0x5927, + 0x5930, 0x3631, 0x3929, 0x5240, 0x4f40, 0x4242, 0x3d44, 0x556c, + 0x3260, 0x4748, 0x3f6b, 0x592d, 0x592f, 0x4e6a, 0x3a6e, 0x4756, + 0x3163, 0x3459, 0x366d, 0x5934, 0x3f21, 0x595e, 0x474e, 0x407e, + 0x5938, 0x4b57, 0x377d, 0x5935, 0x5937, 0x3123, 0x5361, 0x5939, + 0x5045, 0x5936, 0x5931, 0x5932, 0x4129, 0x5933, 0x3c73, 0x505e, + 0x3829, 0x3e63, 0x593d, 0x593a, 0x3033, 0x5942, 0x5944, 0x3136, + 0x593f, 0x3539, 0x3e73, 0x4c48, 0x3a72, 0x5250, 0x5943, 0x3d68, + 0x332b, 0x5945, 0x3e6b, 0x5946, 0x593b, 0x445f, 0x593e, 0x5941, + 0x5940, 0x552e, 0x5635, 0x4763, 0x5948, 0x3c59, 0x594a, 0x593c, + 0x594b, 0x462b, 0x5949, 0x5776, 0x4d23, 0x3d21, 0x594c, 0x453c, + 0x4d35, 0x594d, 0x5947, 0x3325, 0x3f7e, 0x3835, 0x407c, 0x3078, + 0x3476, 0x594e, 0x594f, 0x3422, 0x5950, 0x345f, 0x3041, 0x5951, + 0x4935, 0x4f71, 0x5952, 0x4145, 0x5956, 0x492e, 0x5955, 0x5954, + 0x5957, 0x4b5b, 0x3d29, 0x4627, 0x5953, 0x5958, 0x5959, 0x4865, + 0x405c, 0x3679, 0x5823, 0x544a, 0x542a, 0x5056, 0x3364, 0x5557, + 0x4f48, 0x3962, 0x3f4b, 0x4362, 0x3652, 0x4d43, 0x596e, 0x5970, + 0x3533, 0x3635, 0x3e24, 0x486b, 0x482b, 0x304b, 0x392b, 0x4179, + 0x5962, 0x403c, 0x3932, 0x3958, 0x504b, 0x3178, 0x4664, 0x3e5f, + 0x3564, 0x5748, 0x5178, 0x3c66, 0x4a5e, 0x3c3d, 0x5966, 0x5867, + 0x445a, 0x3854, 0x483d, 0x3261, 0x5459, 0x4330, 0x4361, 0x5a22, + 0x485f, 0x5034, 0x3e7c, 0x4529, 0x395a, 0x5a23, 0x5429, 0x5a24, + 0x597b, 0x362c, 0x376b, 0x3179, 0x597c, 0x3365, 0x3e76, 0x3f76, + 0x5231, 0x4064, 0x3633, 0x597e, 0x597d, 0x3e3b, 0x4660, 0x573c, + 0x5a21, 0x4139, 0x3572, 0x4168, 0x3c75, 0x3455, 0x415d, 0x447d, + 0x3c38, 0x3732, 0x376f, 0x596c, 0x463e, 0x3f2d, 0x3b4b, 0x354a, + 0x5b49, 0x5057, 0x4d39, 0x303c, 0x3376, 0x3b77, 0x5b4a, 0x3a2f, + 0x5464, 0x3536, 0x3573, 0x5856, 0x4850, 0x3756, 0x4750, 0x5857, + 0x3f2f, 0x5b3b, 0x5858, 0x504c, 0x3b2e, 0x6b3e, 0x4150, 0x4175, + 0x5472, 0x3855, 0x3434, 0x3375, 0x493e, 0x4550, 0x4559, 0x407b, + 0x3170, 0x5859, 0x394e, 0x353d, 0x585a, 0x5646, 0x4b22, 0x482f, + 0x4932, 0x344c, 0x3f4c, 0x3974, 0x585b, 0x585c, 0x3667, 0x3c41, + 0x4c6a, 0x4f77, 0x585d, 0x4730, 0x3950, 0x3d23, 0x4c5e, 0x464a, + 0x5860, 0x585e, 0x585f, 0x307e, 0x3e67, 0x4a23, 0x3c74, 0x3831, + 0x386e, 0x5862, 0x3d4b, 0x5864, 0x5863, 0x457c, 0x5865, 0x5866, + 0x4126, 0x4830, 0x306c, 0x3926, 0x3c53, 0x4e71, 0x5b3d, 0x4153, + 0x362f, 0x567a, 0x452c, 0x3d59, 0x5b3e, 0x5b3f, 0x4078, 0x3e22, + 0x404d, 0x5b40, 0x4a46, 0x322a, 0x5342, 0x4363, 0x512b, 0x5b42, + 0x4055, 0x5b43, 0x3f31, 0x443c, 0x475a, 0x5b44, 0x5968, 0x4957, + 0x3934, 0x4e70, 0x5448, 0x307c, 0x3452, 0x5059, 0x5969, 0x5e4b, + 0x596b, 0x5830, 0x3b2f, 0x3131, 0x3357, 0x584e, 0x5451, 0x3d33, + 0x3f6f, 0x4f3b, 0x5850, 0x374b, 0x5851, 0x4625, 0x4778, 0x523d, + 0x5852, 0x4464, 0x4a2e, 0x4727, 0x5826, 0x497d, 0x4e67, 0x3b5c, + 0x306b, 0x3b2a, 0x502d, 0x3130, 0x5764, 0x573f, 0x3525, 0x4274, + 0x444f, 0x3229, 0x3237, 0x3165, 0x5f32, 0x553c, 0x3f28, 0x422c, + 0x5855, 0x4231, 0x5854, 0x4e54, 0x5a60, 0x4e40, 0x5834, 0x432e, + 0x5321, 0x4e23, 0x3c34, 0x4834, 0x4251, 0x3e6d, 0x5036, 0x5a61, + 0x4764, 0x3327, 0x3672, 0x4c7c, 0x407a, 0x4077, 0x5139, 0x5161, + 0x5847, 0x325e, 0x4065, 0x3a71, 0x5848, 0x542d, 0x4f61, 0x5849, + 0x584a, 0x4f43, 0x3378, 0x3e47, 0x584b, 0x5b4c, 0x4825, 0x4f58, + 0x487e, 0x324e, 0x5356, 0x3266, 0x3c30, 0x5351, 0x4b2b, 0x3734, + 0x3722, 0x4a65, 0x4821, 0x4a5c, 0x3164, 0x5070, 0x4551, 0x5b45, + 0x357e, 0x3f5a, 0x3945, 0x3e64, 0x416d, 0x5f36, 0x5f35, 0x563b, + 0x3d50, 0x5559, 0x3048, 0x3623, 0x3f49, 0x4c28, 0x5f33, 0x4a37, + 0x5352, 0x584f, 0x5236, 0x3a45, 0x4b3e, 0x4c3e, 0x5f37, 0x3570, + 0x5f34, 0x5375, 0x3354, 0x3877, 0x5f3a, 0x3a4f, 0x3c2a, 0x3575, + 0x4d2c, 0x437b, 0x3a73, 0x4074, 0x4d42, 0x4f72, 0x5f38, 0x4f45, + 0x4240, 0x5f39, 0x4270, 0x3e7d, 0x415f, 0x4d4c, 0x5277, 0x374d, + 0x5f41, 0x5f44, 0x3771, 0x3049, 0x3656, 0x3754, 0x3a2c, 0x4c7d, + 0x3f54, 0x4b31, 0x4674, 0x5628, 0x5f45, 0x4e62, 0x3333, 0x4e7c, + 0x3435, 0x4e47, 0x3a70, 0x4e61, 0x513d, 0x5f40, 0x3474, 0x334a, + 0x3866, 0x5f3b, 0x4445, 0x5f3c, 0x5f3d, 0x5f3e, 0x453b, 0x5f3f, + 0x5f42, 0x5431, 0x5f43, 0x473a, 0x4e58, 0x4458, 0x5f4a, 0x5f4f, + 0x565c, 0x5f49, 0x5f5a, 0x4e36, 0x3a47, 0x5f4e, 0x5f48, 0x455e, + 0x496b, 0x3a74, 0x437c, 0x3e57, 0x5f46, 0x5f4d, 0x4558, 0x5526, + 0x3a4d, 0x3e4c, 0x533d, 0x3840, 0x5664, 0x5f47, 0x393e, 0x3f27, + 0x417c, 0x5f4b, 0x5f4c, 0x5f50, 0x5f5b, 0x5f65, 0x5f57, 0x5f56, + 0x5749, 0x5f63, 0x5f64, 0x656b, 0x5227, 0x5f52, 0x3f29, 0x545b, + 0x3f48, 0x5f54, 0x4f4c, 0x5f5d, 0x514a, 0x5f5e, 0x3027, 0x4637, + 0x5f53, 0x3a65, 0x365f, 0x4d5b, 0x397e, 0x5455, 0x5f5f, 0x4f6c, + 0x3025, 0x5f67, 0x5f51, 0x5146, 0x5f55, 0x5f58, 0x5f59, 0x5f5c, + 0x3b29, 0x5f60, 0x5f61, 0x5f62, 0x5f66, 0x5f68, 0x5334, 0x3867, + 0x4536, 0x5f6a, 0x495a, 0x4128, 0x4444, 0x3f5e, 0x4f78, 0x555c, + 0x5f6e, 0x3238, 0x3a5f, 0x5f6c, 0x5b41, 0x5164, 0x4b74, 0x343d, + 0x3026, 0x5f71, 0x4c46, 0x5f72, 0x5f6d, 0x5f69, 0x5f6b, 0x5f6f, + 0x5f70, 0x3b3d, 0x5f73, 0x5f74, 0x3b23, 0x4a5b, 0x4e28, 0x6027, + 0x332a, 0x6026, 0x6021, 0x5f7e, 0x4d59, 0x5f7c, 0x5f7a, 0x3f50, + 0x5744, 0x494c, 0x5f78, 0x3021, 0x5f7d, 0x5f7b, 0x6022, 0x6028, + 0x3748, 0x4621, 0x4936, 0x4032, 0x5f75, 0x453e, 0x5844, 0x5f79, + 0x4476, 0x6023, 0x6024, 0x6025, 0x5025, 0x6034, 0x4c64, 0x6031, + 0x3f26, 0x602f, 0x4e39, 0x602b, 0x4946, 0x402e, 0x602e, 0x3a6d, + 0x3a30, 0x6029, 0x5f76, 0x6033, 0x6038, 0x342d, 0x6039, 0x4f32, + 0x3a48, 0x6030, 0x507a, 0x602c, 0x547b, 0x5f77, 0x4567, 0x602d, + 0x5377, 0x6036, 0x6037, 0x6044, 0x5061, 0x603c, 0x6049, 0x604a, + 0x603e, 0x602a, 0x4924, 0x6041, 0x6032, 0x4a48, 0x6043, 0x6035, + 0x4e4b, 0x4b43, 0x604d, 0x6046, 0x6042, 0x604b, 0x603a, 0x603f, + 0x6040, 0x6045, 0x6047, 0x6048, 0x604c, 0x603b, 0x4b54, 0x6055, + 0x6056, 0x6052, 0x6050, 0x3c4e, 0x6051, 0x3842, 0x5845, 0x506a, + 0x426f, 0x604f, 0x603d, 0x6054, 0x6053, 0x6057, 0x605c, 0x6058, + 0x5676, 0x3330, 0x576c, 0x4b3b, 0x605a, 0x4e7b, 0x3a59, 0x6061, + 0x605d, 0x522d, 0x6062, 0x605b, 0x6059, 0x605f, 0x6060, 0x605e, + 0x6064, 0x4677, 0x582c, 0x546b, 0x6066, 0x4a49, 0x6065, 0x3841, + 0x6067, 0x6068, 0x6069, 0x6063, 0x3a3f, 0x4c67, 0x606a, 0x4f79, + 0x606b, 0x4842, 0x3d40, 0x4452, 0x606c, 0x606d, 0x4774, 0x4b44, + 0x606e, 0x3b58, 0x5836, 0x5272, 0x606f, 0x4d45, 0x365a, 0x6071, + 0x5430, 0x4027, 0x3451, 0x4e27, 0x6070, 0x6072, 0x394c, 0x397a, + 0x4d3c, 0x6073, 0x4654, 0x6074, 0x5432, 0x4826, 0x6076, 0x6075, + 0x6077, 0x4d41, 0x4a25, 0x545a, 0x5b57, 0x5b59, 0x5b58, 0x3967, + 0x5b5c, 0x5b5d, 0x3558, 0x5b5a, 0x5b5b, 0x3321, 0x5b5f, 0x3b78, + 0x5637, 0x5b60, 0x3e79, 0x373b, 0x5b50, 0x4c2e, 0x3f32, 0x3b35, + 0x5778, 0x3f53, 0x3f69, 0x3c61, 0x4c33, 0x5b5e, 0x3053, 0x4e6b, + 0x3758, 0x5739, 0x4642, 0x4024, 0x4c39, 0x5b67, 0x5b61, 0x463a, + 0x5b63, 0x5b68, 0x4577, 0x5b6a, 0x5b69, 0x3f40, 0x5b66, 0x5b65, + 0x3439, 0x402c, 0x4222, 0x5b62, 0x5b64, 0x504d, 0x5b6d, 0x405d, + 0x5b72, 0x3662, 0x5b73, 0x5b52, 0x3938, 0x542b, 0x5b6c, 0x3f51, + 0x5b70, 0x5b51, 0x3566, 0x5b6b, 0x3f65, 0x5b6e, 0x5b71, 0x5b79, + 0x3921, 0x3023, 0x4271, 0x3347, 0x5b6f, 0x5b78, 0x4652, 0x5b74, + 0x5b75, 0x5b77, 0x5b76, 0x5b7e, 0x5372, 0x323a, 0x5b7d, 0x5c24, + 0x5b7b, 0x5b7a, 0x5b7c, 0x4560, 0x3b79, 0x5c23, 0x5c25, 0x4c43, + 0x3651, 0x5d40, 0x5c21, 0x5c22, 0x4735, 0x3669, 0x5c27, 0x5c26, + 0x5c29, 0x3124, 0x354c, 0x3f30, 0x515f, 0x3642, 0x5c28, 0x4b7a, + 0x6b73, 0x4b5c, 0x4b7e, 0x4c41, 0x487b, 0x5c2a, 0x4c6e, 0x5c2b, + 0x5b53, 0x5c2f, 0x5c2c, 0x3e33, 0x4a7b, 0x5c2d, 0x494a, 0x4439, + 0x473d, 0x5c2e, 0x5476, 0x5066, 0x442b, 0x3655, 0x5b54, 0x315a, + 0x5b55, 0x5b56, 0x3a3e, 0x4840, 0x4a3f, 0x4849, 0x5733, 0x4979, + 0x3f47, 0x3a78, 0x523c, 0x623a, 0x3426, 0x3138, 0x3834, 0x4f44, + 0x5967, 0x4f26, 0x4d62, 0x596d, 0x3660, 0x5239, 0x393b, 0x6239, + 0x6237, 0x3473, 0x4c6c, 0x4c2b, 0x3772, 0x5832, 0x516b, 0x3a3b, + 0x4a27, 0x4d37, 0x5244, 0x3f64, 0x3c50, 0x3661, 0x5e45, 0x5e46, + 0x5b3c, 0x5159, 0x4666, 0x444e, 0x376e, 0x375c, 0x3f7c, 0x5760, + 0x4675, 0x313c, 0x5e48, 0x3d31, 0x4c57, 0x5e4a, 0x5e49, 0x356c, + 0x495d, 0x3042, 0x452e, 0x452b, 0x444c, 0x3c69, 0x4b7d, 0x3a43, + 0x6579, 0x4867, 0x657a, 0x4d7d, 0x5731, 0x383e, 0x4268, 0x4851, + 0x657b, 0x364a, 0x3c4b, 0x517d, 0x6621, 0x436e, 0x6624, 0x657e, + 0x6625, 0x4d57, 0x3741, 0x657c, 0x657d, 0x6623, 0x445d, 0x6628, + 0x6627, 0x4343, 0x465e, 0x662a, 0x4437, 0x6622, 0x4a3c, 0x3d63, + 0x3943, 0x6626, 0x5055, 0x4e2f, 0x6629, 0x6630, 0x5226, 0x3d2a, + 0x662d, 0x662f, 0x4051, 0x524c, 0x3c27, 0x6631, 0x5276, 0x574b, + 0x4d7e, 0x4d5e, 0x4226, 0x662b, 0x662c, 0x3d3f, 0x662e, 0x6633, + 0x6632, 0x6636, 0x6638, 0x446f, 0x4448, 0x3e6a, 0x496f, 0x6637, + 0x3670, 0x4364, 0x5369, 0x6634, 0x6635, 0x4822, 0x663d, 0x6639, + 0x4645, 0x4d71, 0x663b, 0x663c, 0x3b69, 0x663e, 0x663a, 0x4037, + 0x5324, 0x663f, 0x4974, 0x6643, 0x6644, 0x5076, 0x433d, 0x4344, + 0x6642, 0x6641, 0x6647, 0x4f31, 0x6b74, 0x664a, 0x6645, 0x3c5e, + 0x4929, 0x3c35, 0x4f53, 0x6648, 0x6649, 0x664e, 0x6650, 0x6651, + 0x664b, 0x3555, 0x664c, 0x664f, 0x445b, 0x6646, 0x664d, 0x6652, + 0x6654, 0x6653, 0x6655, 0x5978, 0x6656, 0x6657, 0x5753, 0x665d, + 0x665e, 0x3f57, 0x5450, 0x5756, 0x3466, 0x4b6f, 0x665a, 0x5843, + 0x574e, 0x5022, 0x434f, 0x665f, 0x3c3e, 0x3942, 0x665b, 0x5127, + 0x3a22, 0x424f, 0x582b, 0x4a6b, 0x656e, 0x665c, 0x3775, 0x4866, + 0x4475, 0x6532, 0x447e, 0x4b7c, 0x6533, 0x552c, 0x536e, 0x4a58, + 0x3032, 0x4b4e, 0x4d6a, 0x3a6a, 0x6535, 0x6534, 0x575a, 0x3959, + 0x5666, 0x3628, 0x4d70, 0x524b, 0x3126, 0x4a35, 0x3368, 0x4973, + 0x3f4d, 0x507b, 0x4a52, 0x6536, 0x3b42, 0x4f5c, 0x392c, 0x5457, + 0x3a26, 0x5167, 0x4f7c, 0x3c52, 0x6537, 0x485d, 0x3f6d, 0x3176, + 0x4b5e, 0x3c45, 0x3c44, 0x527a, 0x435c, 0x3f5c, 0x383b, 0x4342, + 0x3a2e, 0x5422, 0x475e, 0x442f, 0x326c, 0x3951, 0x653b, 0x4148, + 0x552f, 0x653c, 0x653e, 0x3467, 0x3654, 0x4b42, 0x5130, 0x353c, + 0x4a59, 0x3762, 0x4964, 0x3d2b, 0x4e3e, 0x5770, 0x5021, 0x4959, + 0x367b, 0x6658, 0x3c62, 0x333e, 0x4950, 0x6659, 0x3322, 0x5e4c, + 0x5348, 0x5e4d, 0x5222, 0x5e4e, 0x3e4d, 0x5e4f, 0x4a2c, 0x527c, + 0x335f, 0x656a, 0x4461, 0x3e21, 0x4e32, 0x4472, 0x3e56, 0x4628, + 0x3263, 0x3e53, 0x477c, 0x4c6b, 0x3d6c, 0x4e5d, 0x4a3a, 0x4641, + 0x656c, 0x503c, 0x5539, 0x656d, 0x4a74, 0x4d40, 0x4245, 0x656f, + 0x4244, 0x6570, 0x6578, 0x4d4d, 0x493d, 0x5259, 0x6128, 0x536c, + 0x4b6a, 0x4671, 0x612c, 0x6127, 0x6129, 0x612a, 0x612f, 0x326d, + 0x612b, 0x385a, 0x612d, 0x612e, 0x6130, 0x353a, 0x6131, 0x6133, + 0x6138, 0x5152, 0x6136, 0x6135, 0x416b, 0x6137, 0x5440, 0x6132, + 0x613a, 0x3036, 0x6134, 0x3f79, 0x6139, 0x613b, 0x613e, 0x613c, + 0x5645, 0x4f3f, 0x613d, 0x613f, 0x424d, 0x366b, 0x5378, 0x474d, + 0x3765, 0x3e7e, 0x6140, 0x6141, 0x6147, 0x3367, 0x4669, 0x345e, + 0x5142, 0x6148, 0x6146, 0x6145, 0x6143, 0x6142, 0x3140, 0x5538, + 0x6144, 0x614b, 0x614c, 0x614a, 0x6f7a, 0x6153, 0x6152, 0x4736, + 0x6149, 0x614e, 0x6150, 0x6154, 0x6151, 0x614d, 0x614f, 0x6155, + 0x6156, 0x6157, 0x6158, 0x615a, 0x615b, 0x4e21, 0x675d, 0x3428, + 0x565d, 0x5132, 0x3332, 0x3924, 0x5773, 0x4749, 0x3e5e, 0x392e, + 0x4e57, 0x326e, 0x5b4f, 0x3c3a, 0x5251, 0x4b48, 0x304d, 0x4f6f, + 0x5963, 0x3d6d, 0x3152, 0x4a50, 0x323c, 0x4b27, 0x372b, 0x4a26, + 0x4f23, 0x6078, 0x554a, 0x607b, 0x607a, 0x4541, 0x4c7b, 0x4131, + 0x6079, 0x5663, 0x322f, 0x5644, 0x355b, 0x3478, 0x5621, 0x4f2f, + 0x306f, 0x607c, 0x6121, 0x3323, 0x607d, 0x607e, 0x4331, 0x435d, + 0x6122, 0x3779, 0x3b4f, 0x6123, 0x443b, 0x6124, 0x6125, 0x6126, + 0x3431, 0x3849, 0x463d, 0x446a, 0x3222, 0x5052, 0x675b, 0x3b43, + 0x5357, 0x5344, 0x3963, 0x624f, 0x572f, 0x476c, 0x3153, 0x3432, + 0x6251, 0x5072, 0x422e, 0x6250, 0x3f62, 0x5326, 0x3557, 0x6252, + 0x356a, 0x436d, 0x387d, 0x382e, 0x4553, 0x374f, 0x6254, 0x6253, + 0x3648, 0x5779, 0x4d25, 0x6258, 0x6256, 0x4a7c, 0x3f35, 0x5339, + 0x6255, 0x6257, 0x412e, 0x4048, 0x625b, 0x625a, 0x402a, 0x414e, + 0x625c, 0x625d, 0x625e, 0x5b48, 0x5153, 0x4d22, 0x3d28, 0x5e43, + 0x5825, 0x3f2a, 0x5b4d, 0x526c, 0x467a, 0x452a, 0x5e44, 0x3157, + 0x5f2e, 0x4a3d, 0x5f31, 0x392d, 0x527d, 0x3825, 0x3a6b, 0x335a, + 0x355c, 0x5545, 0x4356, 0x4f52, 0x3b21, 0x6573, 0x6572, 0x6574, + 0x4d64, 0x4875, 0x352f, 0x473f, 0x6576, 0x6c30, 0x6566, 0x3969, + 0x3531, 0x423c, 0x6568, 0x6567, 0x6569, 0x524d, 0x616a, 0x504e, + 0x4d2e, 0x5165, 0x324a, 0x316b, 0x3172, 0x456d, 0x5543, 0x5330, + 0x615c, 0x615d, 0x525b, 0x3339, 0x314b, 0x4d79, 0x5577, 0x615e, + 0x3e36, 0x347d, 0x615f, 0x3a5c, 0x6160, 0x3b32, 0x4249, 0x6161, + 0x506c, 0x4d3d, 0x6162, 0x3543, 0x4547, 0x6163, 0x6164, 0x5379, + 0x6165, 0x512d, 0x6166, 0x4e22, 0x6167, 0x3542, 0x6168, 0x3b55, + 0x5044, 0x6260, 0x3158, 0x5264, 0x6261, 0x3c49, 0x484c, 0x6263, + 0x6c7e, 0x6c7d, 0x5f2f, 0x6262, 0x563e, 0x4d7c, 0x4326, 0x6343, + 0x5652, 0x6267, 0x6268, 0x5347, 0x626c, 0x3f6c, 0x626d, 0x6265, + 0x3340, 0x446e, 0x626e, 0x5043, 0x3a76, 0x6269, 0x375e, 0x3b33, + 0x4c2c, 0x4b4b, 0x6264, 0x6266, 0x626a, 0x626b, 0x6277, 0x6274, + 0x5475, 0x6273, 0x452d, 0x557a, 0x4542, 0x3240, 0x626f, 0x6272, + 0x412f, 0x4b3c, 0x3521, 0x6279, 0x3c31, 0x6271, 0x5054, 0x5439, + 0x6275, 0x3956, 0x6276, 0x4753, 0x6270, 0x575c, 0x6d21, 0x6278, + 0x6d25, 0x627e, 0x4a51, 0x4135, 0x3b50, 0x3f56, 0x3a63, 0x4b21, + 0x6d26, 0x6d23, 0x6d22, 0x3b56, 0x6d27, 0x5074, 0x6d24, 0x3a5e, + 0x3677, 0x6321, 0x3632, 0x4c71, 0x3927, 0x4f22, 0x4721, 0x3f52, + 0x3671, 0x627a, 0x627b, 0x627d, 0x627c, 0x4455, 0x6322, 0x5341, + 0x6327, 0x4744, 0x4f24, 0x6329, 0x3a37, 0x6328, 0x3b5a, 0x6323, + 0x6324, 0x632a, 0x6326, 0x4e72, 0x5346, 0x3b3c, 0x5443, 0x447a, + 0x6d28, 0x507c, 0x6325, 0x4375, 0x632d, 0x312f, 0x6332, 0x3c42, + 0x632c, 0x353f, 0x4769, 0x6330, 0x3e2a, 0x4d6f, 0x3b73, 0x4c68, + 0x632f, 0x6331, 0x4f27, 0x632e, 0x4e29, 0x3b5d, 0x356b, 0x3e65, + 0x3252, 0x334d, 0x3139, 0x632b, 0x3251, 0x352c, 0x395f, 0x3668, + 0x4f6b, 0x6337, 0x3b4c, 0x4847, 0x504a, 0x6338, 0x336e, 0x6d29, + 0x537a, 0x5364, 0x6d2a, 0x6339, 0x5262, 0x6335, 0x535e, 0x3850, + 0x6333, 0x6336, 0x375f, 0x6334, 0x4022, 0x633a, 0x5438, 0x3448, + 0x633b, 0x3b45, 0x4977, 0x4965, 0x443d, 0x6d2b, 0x427d, 0x3b5b, + 0x3f2e, 0x4e3f, 0x633c, 0x3f36, 0x316f, 0x5477, 0x633e, 0x6d2d, + 0x633f, 0x3a29, 0x6d2c, 0x633d, 0x6340, 0x3a36, 0x362e, 0x5038, + 0x3043, 0x6d2e, 0x6d2f, 0x4041, 0x6341, 0x4533, 0x6342, 0x5c32, + 0x6d30, 0x386a, 0x4e6c, 0x6a27, 0x5067, 0x4a79, 0x4856, 0x4f37, + 0x3349, 0x4e52, 0x3d64, 0x635e, 0x3b72, 0x6a28, 0x553d, 0x465d, + 0x6a29, 0x6a2a, 0x6a2c, 0x6a2b, 0x6a2e, 0x6a2d, 0x3d58, 0x6a2f, + 0x423e, 0x3441, 0x3477, 0x3b27, 0x6c66, 0x6c65, 0x373f, 0x4b79, + 0x3162, 0x6c67, 0x4948, 0x6c68, 0x6c69, 0x4a56, 0x5e50, 0x3245, + 0x547a, 0x464b, 0x3047, 0x3472, 0x4853, 0x4d50, 0x3f38, 0x3f5b, + 0x4724, 0x5634, 0x4029, 0x5e51, 0x4928, 0x516f, 0x4524, 0x3067, + 0x3336, 0x4845, 0x3062, 0x3776, 0x457a, 0x3673, 0x5552, 0x3350, + 0x3c3c, 0x332d, 0x3e71, 0x3051, 0x5256, 0x4a63, 0x5725, 0x4d36, + 0x3636, 0x3f39, 0x555b, 0x3827, 0x4557, 0x5e52, 0x3f59, 0x4255, + 0x4740, 0x3b24, 0x3128, 0x456a, 0x457b, 0x4c27, 0x3127, 0x3556, + 0x4428, 0x5e53, 0x513a, 0x3369, 0x4372, 0x3777, 0x5674, 0x3523, + 0x3270, 0x4434, 0x4469, 0x402d, 0x5e54, 0x3068, 0x4544, 0x4160, + 0x3955, 0x3e5c, 0x4d58, 0x304e, 0x4d4f, 0x5e56, 0x3e50, 0x573e, + 0x5e55, 0x5550, 0x305d, 0x4462, 0x4223, 0x3c70, 0x5335, 0x4039, + 0x4521, 0x3226, 0x5471, 0x4028, 0x4a43, 0x5e57, 0x557c, 0x3930, + 0x482d, 0x4b29, 0x5e59, 0x3f3d, 0x4634, 0x5727, 0x4a30, 0x4443, + 0x3356, 0x3952, 0x5638, 0x6a7c, 0x3034, 0x3f66, 0x4c74, 0x4d5a, + 0x563f, 0x424e, 0x4e4e, 0x4c22, 0x502e, 0x4453, 0x3532, 0x5e58, + 0x5575, 0x3c37, 0x3b53, 0x3024, 0x4532, 0x346c, 0x5571, 0x6a7d, + 0x5e5a, 0x4d26, 0x4d6c, 0x4e66, 0x5e5c, 0x4d31, 0x4026, 0x573d, + 0x5e5b, 0x3046, 0x3a34, 0x4953, 0x4473, 0x3e68, 0x3236, 0x404c, + 0x4b70, 0x3c71, 0x3b3b, 0x3537, 0x4575, 0x5e66, 0x5e63, 0x3e5d, + 0x5e5f, 0x3437, 0x3d5d, 0x5e60, 0x446d, 0x4f46, 0x3560, 0x365e, + 0x4a5a, 0x3574, 0x5e65, 0x5546, 0x5e61, 0x4c4d, 0x467e, 0x4545, + 0x5234, 0x3e72, 0x4253, 0x4c3d, 0x3338, 0x3d53, 0x3f58, 0x4d46, + 0x515a, 0x346b, 0x5e64, 0x5e5d, 0x5e67, 0x6a7e, 0x4230, 0x5e62, + 0x5640, 0x3527, 0x3274, 0x5e68, 0x5e72, 0x5e6d, 0x5e71, 0x4860, + 0x5761, 0x5e6f, 0x4368, 0x4c61, 0x3265, 0x523e, 0x5e6e, 0x5e6b, + 0x4e55, 0x3427, 0x3f2b, 0x3e3e, 0x3d52, 0x5e69, 0x542e, 0x5e5e, + 0x5e6a, 0x403f, 0x5e6c, 0x3273, 0x3869, 0x4227, 0x3d41, 0x5e75, + 0x5e78, 0x322b, 0x3424, 0x346a, 0x4926, 0x5e76, 0x4b51, 0x3863, + 0x5e77, 0x5e7a, 0x5e79, 0x4c42, 0x3061, 0x346e, 0x653a, 0x502f, + 0x326b, 0x6b21, 0x5e74, 0x4963, 0x5e73, 0x305a, 0x5221, 0x3177, + 0x4c2f, 0x5e70, 0x4b24, 0x552a, 0x5e7b, 0x345d, 0x4426, 0x5e7d, + 0x437e, 0x4421, 0x5f21, 0x414c, 0x5e7c, 0x3e6f, 0x4632, 0x3345, + 0x4876, 0x4b3a, 0x5e7e, 0x5f24, 0x5732, 0x3337, 0x4143, 0x474b, + 0x3225, 0x3469, 0x572b, 0x446c, 0x5f22, 0x5f23, 0x5f25, 0x3a33, + 0x5f26, 0x405e, 0x4943, 0x3259, 0x4766, 0x5f27, 0x475c, 0x5f28, + 0x6b22, 0x4b53, 0x5f2a, 0x5f29, 0x3241, 0x454a, 0x5f2b, 0x545c, + 0x4841, 0x5f2c, 0x3e70, 0x5f2d, 0x5627, 0x6a37, 0x6b36, 0x4a55, + 0x587c, 0x3844, 0x3925, 0x3745, 0x557e, 0x394a, 0x5027, 0x744d, + 0x3550, 0x4374, 0x3e48, 0x6b37, 0x303d, 0x3d4c, 0x4132, 0x3156, + 0x3328, 0x3852, 0x4922, 0x3658, 0x6b38, 0x3e34, 0x4a7d, 0x4743, + 0x557b, 0x3773, 0x4e44, 0x552b, 0x3173, 0x6c33, 0x305f, 0x6c35, + 0x3637, 0x414f, 0x757a, 0x5031, 0x5565, 0x4e53, 0x3d6f, 0x3362, + 0x382b, 0x5536, 0x6d3d, 0x364f, 0x4b39, 0x5042, 0x373d, 0x6c36, + 0x4a29, 0x4554, 0x6c39, 0x6c38, 0x4243, 0x6c37, 0x507d, 0x6c3a, + 0x6c3b, 0x5765, 0x6c3c, 0x6c3d, 0x466c, 0x4e5e, 0x3c48, 0x4855, + 0x3529, 0x3e49, 0x563c, 0x5467, 0x512e, 0x5071, 0x6a38, 0x6a39, + 0x6a3a, 0x3a35, 0x4a31, 0x3f75, 0x4d7a, 0x6a40, 0x303a, 0x6a3e, + 0x4025, 0x6a3b, 0x327d, 0x4377, 0x3b68, 0x5257, 0x4e74, 0x6a3f, + 0x6a3c, 0x6a43, 0x5047, 0x5333, 0x343a, 0x4341, 0x5772, 0x5551, + 0x4a47, 0x6a45, 0x6a44, 0x6a47, 0x6a46, 0x5667, 0x4f54, 0x6a4b, + 0x3b4e, 0x3d7a, 0x494e, 0x6a4c, 0x4939, 0x4f7e, 0x6a4a, 0x544e, + 0x6a4d, 0x6a4f, 0x4d6d, 0x6a49, 0x6a4e, 0x4e6e, 0x3b5e, 0x333f, + 0x4655, 0x3e30, 0x4e7a, 0x4767, 0x3e27, 0x6a50, 0x5647, 0x4140, + 0x545d, 0x6a51, 0x4f3e, 0x6a52, 0x4a6e, 0x452f, 0x3035, 0x6a54, + 0x6a53, 0x745f, 0x443a, 0x3129, 0x655f, 0x6a55, 0x4a6f, 0x6a56, + 0x6a57, 0x4658, 0x6a58, 0x6a59, 0x543b, 0x477a, 0x5237, 0x387c, + 0x6a42, 0x325c, 0x427c, 0x5478, 0x4c66, 0x576e, 0x5442, 0x5350, + 0x6b43, 0x4573, 0x377e, 0x6b54, 0x4b37, 0x6b5e, 0x404a, 0x4d7b, + 0x332f, 0x465a, 0x6b7c, 0x443e, 0x4e34, 0x4429, 0x313e, 0x547d, + 0x4a75, 0x566c, 0x4653, 0x3664, 0x3b7a, 0x5060, 0x4931, 0x5453, + 0x4828, 0x384b, 0x683e, 0x493c, 0x683b, 0x406e, 0x5053, 0x3244, + 0x3465, 0x683c, 0x5548, 0x3645, 0x683d, 0x4a78, 0x385c, 0x4c75, + 0x4034, 0x516e, 0x683f, 0x6842, 0x3a3c, 0x312d, 0x3d5c, 0x6a3d, + 0x6843, 0x6846, 0x684b, 0x684c, 0x4b49, 0x3065, 0x3c2b, 0x3939, + 0x6841, 0x4d77, 0x684a, 0x4e76, 0x556d, 0x4156, 0x6844, 0x4336, + 0x397b, 0x5626, 0x6848, 0x4a60, 0x5466, 0x6840, 0x6845, 0x6847, + 0x4739, 0x3763, 0x6849, 0x3f5d, 0x6852, 0x6857, 0x6855, 0x3c5c, + 0x3c4f, 0x685b, 0x685e, 0x685a, 0x317a, 0x3058, 0x4433, 0x384c, + 0x4662, 0x483e, 0x4861, 0x684f, 0x6854, 0x6856, 0x3971, 0x6858, + 0x5775, 0x447b, 0x685c, 0x3269, 0x6851, 0x3c6d, 0x3f42, 0x684d, + 0x5679, 0x4178, 0x3271, 0x685f, 0x4a41, 0x6859, 0x5524, 0x316a, + 0x553b, 0x684e, 0x6850, 0x3630, 0x6853, 0x685d, 0x4038, 0x4a77, + 0x4b28, 0x465c, 0x4075, 0x6869, 0x5023, 0x6872, 0x566a, 0x6860, + 0x6861, 0x5179, 0x3a4b, 0x3879, 0x3871, 0x5454, 0x686f, 0x686e, + 0x686c, 0x3970, 0x4c52, 0x6866, 0x4e26, 0x3f72, 0x3038, 0x6871, + 0x6870, 0x5740, 0x6864, 0x4d29, 0x4923, 0x3b38, 0x3d5b, 0x686a, + 0x6862, 0x6863, 0x6865, 0x3535, 0x6867, 0x4745, 0x686b, 0x686d, + 0x3d30, 0x572e, 0x6878, 0x6875, 0x4d30, 0x6876, 0x413a, 0x6868, + 0x4337, 0x3070, 0x6874, 0x6877, 0x3923, 0x4952, 0x434e, 0x4e60, + 0x4066, 0x4b73, 0x4c5d, 0x5035, 0x4a61, 0x6873, 0x3c6c, 0x6879, + 0x435e, 0x4665, 0x3977, 0x3074, 0x5758, 0x3c2c, 0x456f, 0x4c44, + 0x6926, 0x492d, 0x6922, 0x4062, 0x3f43, 0x687e, 0x3957, 0x687b, + 0x6924, 0x524e, 0x6923, 0x5632, 0x5735, 0x6927, 0x3d37, 0x687c, + 0x687d, 0x6921, 0x4d56, 0x522c, 0x6932, 0x6929, 0x342a, 0x343b, + 0x692b, 0x5028, 0x6925, 0x337e, 0x692c, 0x4063, 0x692a, 0x6939, + 0x6938, 0x692e, 0x687a, 0x6928, 0x3f2c, 0x6931, 0x693a, 0x4225, + 0x692f, 0x3845, 0x692d, 0x535c, 0x6934, 0x6935, 0x6937, 0x6947, + 0x4046, 0x6945, 0x6930, 0x693b, 0x3071, 0x693c, 0x5525, 0x693e, + 0x693f, 0x6941, 0x4171, 0x4836, 0x693d, 0x6942, 0x6943, 0x6933, + 0x6936, 0x3b31, 0x6940, 0x3c77, 0x6944, 0x6946, 0x694a, 0x694e, + 0x325b, 0x6948, 0x372e, 0x694b, 0x694c, 0x5541, 0x4423, 0x6958, + 0x3a61, 0x6949, 0x5323, 0x6954, 0x6957, 0x6950, 0x694f, 0x4741, + 0x6952, 0x6959, 0x3348, 0x6953, 0x4f70, 0x694d, 0x3377, 0x6956, + 0x695a, 0x4c34, 0x4f2d, 0x6955, 0x695c, 0x695b, 0x695e, 0x6951, + 0x695d, 0x695f, 0x434a, 0x4737, 0x344e, 0x3b36, 0x5040, 0x6c23, + 0x4537, 0x537b, 0x6c24, 0x6c25, 0x465b, 0x3f6e, 0x6c26, 0x6c27, + 0x502a, 0x4738, 0x3868, 0x6c28, 0x5639, 0x557d, 0x344b, 0x323d, + 0x4e64, 0x4667, 0x4d61, 0x3475, 0x4b40, 0x3c5f, 0x6962, 0x6963, + 0x516a, 0x6965, 0x3479, 0x6964, 0x5133, 0x4a62, 0x3250, 0x6968, + 0x6966, 0x6967, 0x5633, 0x6969, 0x696a, 0x696b, 0x696c, 0x6c2f, + 0x4539, 0x364e, 0x5273, 0x356e, 0x3b59, 0x6c31, 0x5263, 0x4e63, + 0x4438, 0x433f, 0x363e, 0x5839, 0x3148, 0x314f, 0x3151, 0x457e, + 0x3150, 0x432b, 0x5531, 0x6b24, 0x3a41, 0x4c3a, 0x6b25, 0x6b27, + 0x6b28, 0x6b26, 0x6b29, 0x6b2b, 0x6b2a, 0x6b2c, 0x4a4f, 0x5835, + 0x4371, 0x4325, 0x4678, 0x6b2d, 0x444a, 0x6b2e, 0x6b2f, 0x6b30, + 0x3755, 0x377a, 0x6b31, 0x4762, 0x6b33, 0x3a24, 0x5175, 0x3031, + 0x6b32, 0x6b34, 0x352a, 0x4248, 0x4768, 0x6b35, 0x4b2e, 0x635f, + 0x5340, 0x595b, 0x4d21, 0x562d, 0x4773, 0x5960, 0x3b63, 0x3a3a, + 0x6362, 0x4f2b, 0x6360, 0x4947, 0x3a39, 0x5134, 0x6361, 0x486a, + 0x392f, 0x3d2d, 0x3358, 0x4e5b, 0x4c40, 0x6368, 0x6369, 0x4d74, + 0x4c2d, 0x3c33, 0x636a, 0x636b, 0x505a, 0x467b, 0x375a, 0x475f, + 0x524a, 0x4e56, 0x6364, 0x636c, 0x4972, 0x3341, 0x6367, 0x4663, + 0x6365, 0x6d33, 0x6366, 0x4933, 0x4566, 0x3935, 0x433b, 0x6363, + 0x453d, 0x4124, 0x4259, 0x3257, 0x636d, 0x3b26, 0x442d, 0x6370, + 0x3e5a, 0x637b, 0x6375, 0x3a53, 0x3750, 0x534d, 0x564e, 0x5553, + 0x3941, 0x5534, 0x5158, 0x5039, 0x4776, 0x482a, 0x3234, 0x435a, + 0x636e, 0x637c, 0x636f, 0x3728, 0x6377, 0x6374, 0x373a, 0x4522, + 0x6376, 0x455d, 0x3228, 0x467c, 0x4460, 0x5722, 0x4061, 0x6379, + 0x637a, 0x637d, 0x4c29, 0x6373, 0x533e, 0x3143, 0x6d34, 0x6371, + 0x6372, 0x6378, 0x503a, 0x4643, 0x5473, 0x637e, 0x3d60, 0x6427, + 0x6426, 0x5173, 0x6423, 0x6429, 0x4877, 0x4f34, 0x6428, 0x642e, + 0x4265, 0x3634, 0x3d72, 0x6422, 0x3a69, 0x642a, 0x642c, 0x367d, + 0x565e, 0x6432, 0x642d, 0x6421, 0x3b6e, 0x4d5d, 0x4722, 0x4549, + 0x4177, 0x6424, 0x4733, 0x3d2c, 0x3d3d, 0x6425, 0x5747, 0x3262, + 0x642b, 0x3c43, 0x642f, 0x3b6b, 0x6430, 0x4528, 0x6431, 0x5563, + 0x3f23, 0x643a, 0x6437, 0x643b, 0x643d, 0x4656, 0x3a46, 0x404b, + 0x3821, 0x6434, 0x5421, 0x3a23, 0x3d7e, 0x643c, 0x4d3f, 0x4479, + 0x4f7b, 0x4966, 0x533f, 0x4f51, 0x6433, 0x6438, 0x6439, 0x4c69, + 0x4c4e, 0x4054, 0x6435, 0x4130, 0x6436, 0x4e50, 0x3b41, 0x3553, + 0x4873, 0x3d27, 0x5547, 0x492c, 0x3822, 0x644a, 0x644c, 0x5144, + 0x523a, 0x3a2d, 0x3a54, 0x6443, 0x356d, 0x574d, 0x6440, 0x4f7d, + 0x643f, 0x415c, 0x4c4a, 0x4a67, 0x4457, 0x4c54, 0x6448, 0x6447, + 0x6441, 0x6444, 0x352d, 0x5359, 0x6446, 0x5279, 0x3463, 0x3b34, + 0x496e, 0x343e, 0x3b6c, 0x514d, 0x4c6d, 0x6d35, 0x4765, 0x5428, + 0x644b, 0x5755, 0x6442, 0x3d25, 0x6445, 0x5366, 0x6449, 0x4978, + 0x643e, 0x5365, 0x477e, 0x3649, 0x547c, 0x3233, 0x6457, 0x4e42, + 0x644d, 0x4e3c, 0x385b, 0x6456, 0x3f4a, 0x534e, 0x436c, 0x4548, + 0x6458, 0x4d44, 0x644f, 0x6454, 0x6455, 0x3a7e, 0x4f66, 0x553f, + 0x6452, 0x6450, 0x644e, 0x4d65, 0x4a2a, 0x4023, 0x3d26, 0x6453, + 0x3848, 0x6467, 0x5434, 0x645b, 0x416f, 0x6469, 0x5267, 0x645f, + 0x6460, 0x4f2a, 0x4b5d, 0x645a, 0x6451, 0x6465, 0x485c, 0x6463, + 0x4467, 0x6462, 0x6461, 0x337c, 0x6468, 0x3561, 0x574c, 0x6466, + 0x3b2c, 0x5752, 0x4c4f, 0x6b78, 0x6464, 0x3976, 0x564d, 0x6459, + 0x645c, 0x427a, 0x645e, 0x424b, 0x4044, 0x4250, 0x3175, 0x4c32, + 0x354e, 0x646f, 0x462f, 0x4661, 0x6475, 0x4229, 0x406c, 0x515d, + 0x646e, 0x442e, 0x646d, 0x6476, 0x6474, 0x427e, 0x645d, 0x6470, + 0x4a7e, 0x5544, 0x6471, 0x517a, 0x646b, 0x646c, 0x6472, 0x4e2b, + 0x454b, 0x4731, 0x423a, 0x646a, 0x414a, 0x4c36, 0x3331, 0x647b, + 0x6473, 0x647a, 0x647d, 0x647c, 0x334e, 0x333a, 0x6477, 0x6479, + 0x6478, 0x456c, 0x403d, 0x5468, 0x6522, 0x3044, 0x6524, 0x6523, + 0x3c24, 0x6525, 0x6521, 0x647e, 0x3174, 0x6528, 0x6529, 0x6526, + 0x6527, 0x652a, 0x4659, 0x652b, 0x652d, 0x652c, 0x652f, 0x652e, + 0x3960, 0x6530, 0x6531, 0x3b70, 0x6c61, 0x4370, 0x3546, 0x3b52, + 0x4169, 0x546e, 0x3e44, 0x5746, 0x5456, 0x3253, 0x6c3e, 0x6a41, + 0x422f, 0x3436, 0x5157, 0x3334, 0x4832, 0x3f3b, 0x6c40, 0x564b, + 0x6c3f, 0x6c41, 0x6c45, 0x3e66, 0x4c3f, 0x455a, 0x3e3c, 0x6c46, + 0x317e, 0x6c44, 0x5528, 0x3563, 0x6c42, 0x4136, 0x3363, 0x6c43, + 0x4b38, 0x4043, 0x4c7e, 0x4152, 0x6c48, 0x3a66, 0x4053, 0x5672, + 0x514c, 0x3f3e, 0x3733, 0x4955, 0x6c47, 0x3b62, 0x4c4c, 0x3d7d, + 0x4848, 0x4f29, 0x4d69, 0x456b, 0x3769, 0x5149, 0x3a38, 0x6c49, + 0x6c4a, 0x3b40, 0x6c4b, 0x6c62, 0x313a, 0x3759, 0x3d39, 0x6c4c, + 0x5166, 0x6c4d, 0x483b, 0x6c51, 0x6c53, 0x3b4d, 0x3c65, 0x6c4f, + 0x4937, 0x433a, 0x6c63, 0x5555, 0x6c50, 0x5673, 0x6c52, 0x6c4e, + 0x6c54, 0x6c55, 0x493f, 0x4f28, 0x505c, 0x512c, 0x485b, 0x6c56, + 0x4e75, 0x4a6c, 0x6c5a, 0x6c59, 0x303e, 0x6c57, 0x6c58, 0x6c64, + 0x483c, 0x4147, 0x6c5c, 0x5160, 0x6c5b, 0x546f, 0x6c5d, 0x5b46, + 0x6c5e, 0x312c, 0x6c5f, 0x6c60, 0x5726, 0x4540, 0x6b3c, 0x302e, + 0x3e74, 0x3838, 0x522f, 0x3056, 0x3579, 0x5833, 0x4b2c, 0x635d, + 0x462c, 0x3066, 0x4546, 0x6b39, 0x6b3a, 0x6b3b, 0x5140, 0x4523, + 0x6a72, 0x4432, 0x4435, 0x404e, 0x6a73, 0x4441, 0x4e6f, 0x6a70, + 0x6a74, 0x497c, 0x4723, 0x4c58, 0x4e7e, 0x6a75, 0x6a76, 0x4f2c, + 0x4067, 0x6a77, 0x363f, 0x6a78, 0x6a79, 0x6a7a, 0x6a7b, 0x6a71, + 0x482e, 0x616b, 0x3738, 0x616c, 0x616d, 0x5734, 0x616e, 0x616f, + 0x534c, 0x6171, 0x3f71, 0x6170, 0x3552, 0x3137, 0x6173, 0x6172, + 0x3a7c, 0x6174, 0x3937, 0x3e51, 0x447c, 0x3a5d, 0x3d46, 0x6175, + 0x6177, 0x3640, 0x4f41, 0x4a28, 0x6176, 0x5578, 0x537c, 0x6178, + 0x617c, 0x6179, 0x617a, 0x406a, 0x617e, 0x6221, 0x4047, 0x617b, + 0x617d, 0x6225, 0x4154, 0x6223, 0x6228, 0x327e, 0x6222, 0x434d, + 0x3242, 0x6227, 0x6226, 0x6224, 0x6229, 0x622b, 0x5049, 0x566d, + 0x4328, 0x622c, 0x4f57, 0x622e, 0x3a6f, 0x6960, 0x622d, 0x622a, + 0x3b2b, 0x5433, 0x6230, 0x622f, 0x6961, 0x6231, 0x6232, 0x6233, + 0x4c21, 0x6234, 0x6235, 0x507e, 0x424a, 0x5371, 0x4d75, 0x6760, + 0x6761, 0x3e41, 0x426a, 0x6764, 0x6763, 0x4d66, 0x4335, 0x6762, + 0x3b37, 0x4f56, 0x4161, 0x6769, 0x6768, 0x6774, 0x3223, 0x676a, + 0x6766, 0x676c, 0x676b, 0x493a, 0x5564, 0x6765, 0x3729, 0x6767, + 0x676e, 0x6773, 0x5669, 0x676d, 0x6772, 0x6771, 0x3060, 0x6775, + 0x4772, 0x4045, 0x406d, 0x4170, 0x6770, 0x6776, 0x4b76, 0x6822, + 0x6821, 0x5741, 0x677a, 0x6779, 0x677b, 0x6777, 0x677e, 0x677d, + 0x677c, 0x4155, 0x4759, 0x457d, 0x4543, 0x476d, 0x6823, 0x6826, + 0x6825, 0x6827, 0x3a77, 0x6778, 0x6824, 0x4870, 0x492a, 0x6829, + 0x3965, 0x517e, 0x6828, 0x682a, 0x682d, 0x682e, 0x4127, 0x682f, + 0x6830, 0x682c, 0x6834, 0x682b, 0x6831, 0x6835, 0x6832, 0x6833, + 0x6837, 0x6836, 0x394f, 0x702c, 0x702d, 0x4630, 0x306a, 0x483f, + 0x4d5f, 0x4e4d, 0x6a31, 0x6a32, 0x463f, 0x3449, 0x6a33, 0x5567, + 0x5d79, 0x6a34, 0x6a35, 0x6a36, 0x384a, 0x5f30, 0x4975, 0x4c70, + 0x497a, 0x497b, 0x5343, 0x4b26, 0x3826, 0x702e, 0x3142, 0x6538, + 0x4c6f, 0x5349, 0x3c57, 0x496a, 0x3567, 0x4450, 0x3569, 0x6e2e, + 0x3b2d, 0x675e, 0x6e2f, 0x3329, 0x6e32, 0x6e31, 0x3d67, 0x6e30, + 0x4e37, 0x454f, 0x4174, 0x5b4e, 0x6e33, 0x5073, 0x4254, 0x4668, + 0x372c, 0x6e34, 0x336b, 0x3b7b, 0x6e35, 0x675c, 0x6e36, 0x3d2e, + 0x7162, 0x4a68, 0x5249, 0x705a, 0x705b, 0x705c, 0x4146, 0x386d, + 0x3e4e, 0x705e, 0x4531, 0x705d, 0x5171, 0x7060, 0x304c, 0x3d6a, + 0x525f, 0x705f, 0x342f, 0x3768, 0x7066, 0x7065, 0x4623, 0x7061, + 0x7062, 0x3443, 0x7063, 0x556e, 0x4c5b, 0x3e52, 0x3c32, 0x7068, + 0x7067, 0x7064, 0x3221, 0x5622, 0x5338, 0x3e37, 0x482c, 0x706a, + 0x5177, 0x564c, 0x3a5b, 0x7069, 0x363b, 0x4d34, 0x4626, 0x4121, + 0x706b, 0x706e, 0x706d, 0x7070, 0x706c, 0x3b3e, 0x706f, 0x4c35, + 0x7072, 0x3355, 0x3154, 0x7073, 0x7074, 0x7076, 0x3461, 0x7071, + 0x7077, 0x707a, 0x7078, 0x7075, 0x707d, 0x7079, 0x707c, 0x707e, + 0x7121, 0x4e41, 0x7124, 0x7123, 0x4176, 0x707b, 0x4a5d, 0x3471, + 0x3171, 0x4c31, 0x7126, 0x7127, 0x712c, 0x554e, 0x7129, 0x4833, + 0x7122, 0x712b, 0x7128, 0x7125, 0x712a, 0x3029, 0x712d, 0x712f, + 0x7131, 0x7130, 0x712e, 0x5122, 0x7132, 0x7133, 0x396f, 0x3547, + 0x3057, 0x3059, 0x546d, 0x3544, 0x3d54, 0x3b4a, 0x7027, 0x385e, + 0x7028, 0x3028, 0x7029, 0x4d6e, 0x702a, 0x702b, 0x4624, 0x5665, + 0x7164, 0x7165, 0x4373, 0x535b, 0x5651, 0x4568, 0x532f, 0x5266, + 0x6e41, 0x303b, 0x5535, 0x514e, 0x3c60, 0x3a50, 0x3f78, 0x3847, + 0x3541, 0x454c, 0x4a22, 0x434b, 0x6e42, 0x443f, 0x3622, 0x6d6c, + 0x4324, 0x5631, 0x4f60, 0x6d6f, 0x454e, 0x365c, 0x4a21, 0x6d6d, + 0x6d70, 0x6d71, 0x433c, 0x3f34, 0x6d6e, 0x6d74, 0x6d72, 0x5566, + 0x435f, 0x6d73, 0x6d76, 0x5523, 0x5123, 0x6d75, 0x4350, 0x6d77, + 0x3f74, 0x3e6c, 0x6d78, 0x4c77, 0x515b, 0x5745, 0x5576, 0x6d7c, + 0x6d7b, 0x6d79, 0x6d7a, 0x6d7d, 0x3e26, 0x4b2f, 0x6e21, 0x363d, + 0x6e22, 0x4440, 0x6d7e, 0x3d5e, 0x3247, 0x3643, 0x6e25, 0x583a, + 0x6e23, 0x6e26, 0x4369, 0x3372, 0x6e27, 0x6e24, 0x4f39, 0x6e28, + 0x4277, 0x6e29, 0x6e2a, 0x5e2b, 0x4633, 0x4746, 0x5675, 0x3549, + 0x4b32, 0x6e2b, 0x4d2b, 0x6e2c, 0x5530, 0x6e2d, 0x7644, 0x5b47, + 0x3423, 0x432c, 0x7166, 0x4a38, 0x5253, 0x562a, 0x6f72, 0x3e58, + 0x3d43, 0x6f73, 0x364c, 0x302b, 0x4a2f, 0x6d36, 0x6d37, 0x4e79, + 0x372f, 0x3f73, 0x6d38, 0x426b, 0x4930, 0x6d39, 0x4676, 0x3f33, + 0x6d3c, 0x4578, 0x5150, 0x5729, 0x6d3a, 0x6d3b, 0x5162, 0x6d3f, + 0x6d40, 0x6d44, 0x6d48, 0x6d46, 0x6d4e, 0x5568, 0x6d49, 0x6d47, + 0x6d3e, 0x4569, 0x4646, 0x4969, 0x5452, 0x6d41, 0x6d42, 0x6d43, + 0x6d45, 0x4079, 0x3421, 0x3968, 0x6d50, 0x6d51, 0x6d4a, 0x6d4f, + 0x4e78, 0x4b36, 0x6d4c, 0x6d4d, 0x4f75, 0x6d52, 0x4172, 0x5332, + 0x6d4b, 0x4837, 0x3c6f, 0x4570, 0x6d56, 0x356f, 0x4235, 0x302d, + 0x4b69, 0x312e, 0x6d54, 0x4d6b, 0x3562, 0x6d55, 0x6d53, 0x6d57, + 0x357a, 0x6d58, 0x6d59, 0x6d5c, 0x314c, 0x4576, 0x3c6e, 0x6d5a, + 0x4c3c, 0x326a, 0x6d5b, 0x446b, 0x3445, 0x3075, 0x6d5f, 0x405a, + 0x3468, 0x454d, 0x6d5d, 0x3f44, 0x6d5e, 0x4425, 0x6d60, 0x6d61, + 0x6d63, 0x4157, 0x3b47, 0x3d38, 0x6d62, 0x6d64, 0x6d66, 0x6d65, + 0x6d67, 0x4a3e, 0x6c6a, 0x4071, 0x4967, 0x6c6b, 0x466e, 0x6c6c, + 0x466d, 0x6c6d, 0x6c70, 0x5766, 0x6c73, 0x6c71, 0x6c6e, 0x6c6f, + 0x5723, 0x4971, 0x4b6e, 0x6c74, 0x6c72, 0x4f69, 0x6c76, 0x4631, + 0x3c40, 0x6c75, 0x353b, 0x3b76, 0x6c77, 0x5977, 0x3d7b, 0x423b, + 0x6c78, 0x6c79, 0x3823, 0x6c7a, 0x6c7b, 0x6c7c, 0x536d, 0x582e, + 0x406b, 0x475d, 0x3a4c, 0x5063, 0x4b3d, 0x4d3a, 0x3851, 0x317c, + 0x476f, 0x5656, 0x3f46, 0x436b, 0x6f75, 0x4358, 0x5762, 0x6f77, + 0x3353, 0x4758, 0x516d, 0x5648, 0x6f78, 0x6f76, 0x3b7d, 0x3346, + 0x3d55, 0x5246, 0x3b60, 0x4f21, 0x6f7c, 0x6f7b, 0x6f79, 0x334c, + 0x4954, 0x4b30, 0x6f7e, 0x305e, 0x5649, 0x6f7d, 0x336d, 0x7655, + 0x4e48, 0x7022, 0x7021, 0x353e, 0x3c5a, 0x3b7c, 0x3865, 0x4442, + 0x7023, 0x4b6b, 0x7026, 0x5128, 0x3e3f, 0x476e, 0x7136, 0x7137, + 0x3f55, 0x3429, 0x7138, 0x4d3b, 0x4754, 0x552d, 0x7139, 0x713a, + 0x474f, 0x5224, 0x564f, 0x713b, 0x3d51, 0x3430, 0x3e3d, 0x345c, + 0x4e51, 0x3f5f, 0x713d, 0x3f7a, 0x713c, 0x713f, 0x713e, 0x7140, + 0x7141, 0x417e, 0x4122, 0x4a7a, 0x553e, 0x3e3a, 0x3e39, 0x5542, + 0x3f22, 0x4d2f, 0x7135, 0x3d5f, 0x364b, 0x5671, 0x7343, 0x7344, + 0x384d, 0x7346, 0x7347, 0x304a, 0x7345, 0x7349, 0x4b71, 0x734b, + 0x5026, 0x314a, 0x7348, 0x734f, 0x3551, 0x7357, 0x7352, 0x7354, + 0x7353, 0x377b, 0x313f, 0x734e, 0x734a, 0x355a, 0x7350, 0x7351, + 0x7355, 0x734d, 0x3c63, 0x417d, 0x7356, 0x735a, 0x734c, 0x3548, + 0x3d6e, 0x735c, 0x3724, 0x3f70, 0x567e, 0x4d32, 0x3470, 0x325f, + 0x7358, 0x7359, 0x4938, 0x735d, 0x735e, 0x7361, 0x735f, 0x7363, + 0x7362, 0x735b, 0x3f6a, 0x336f, 0x7360, 0x4729, 0x3c72, 0x736b, + 0x393f, 0x7364, 0x322d, 0x3b7e, 0x4b63, 0x736d, 0x7369, 0x395c, + 0x736e, 0x7365, 0x7366, 0x736a, 0x4261, 0x736c, 0x736f, 0x7368, + 0x3c7d, 0x4f64, 0x7370, 0x7367, 0x7372, 0x572d, 0x462a, 0x7373, + 0x7371, 0x4228, 0x385d, 0x7375, 0x7374, 0x345b, 0x7376, 0x7377, + 0x7378, 0x403a, 0x4069, 0x4571, 0x737b, 0x737a, 0x3458, 0x737e, + 0x7379, 0x737c, 0x737d, 0x7421, 0x7423, 0x3b49, 0x7422, 0x7424, + 0x323e, 0x7426, 0x7425, 0x3c2e, 0x4357, 0x5961, 0x4060, 0x744c, + 0x5751, 0x375b, 0x744e, 0x4123, 0x4649, 0x3456, 0x5533, 0x7450, + 0x744f, 0x7451, 0x4b5a, 0x7452, 0x5441, 0x5660, 0x3760, 0x4138, + 0x413b, 0x7453, 0x3e2c, 0x3462, 0x7454, 0x7455, 0x3e2b, 0x7456, + 0x745b, 0x7457, 0x745a, 0x3a7d, 0x7458, 0x7459, 0x3862, 0x4c47, + 0x745c, 0x325a, 0x4353, 0x5463, 0x3f37, 0x745d, 0x4534, 0x7469, + 0x4f35, 0x4e49, 0x4b58, 0x4b77, 0x3d74, 0x574f, 0x405b, 0x5075, + 0x746a, 0x746b, 0x746c, 0x7763, 0x3731, 0x746d, 0x576b, 0x746e, + 0x6679, 0x3e40, 0x667a, 0x3a6c, 0x667b, 0x4f4b, 0x667c, 0x543c, + 0x3c36, 0x667d, 0x667e, 0x3c4d, 0x4852, 0x4e33, 0x6721, 0x343f, + 0x6722, 0x4934, 0x3859, 0x4449, 0x575d, 0x425a, 0x3757, 0x563d, + 0x4e46, 0x3744, 0x4526, 0x6723, 0x4f5f, 0x6724, 0x6725, 0x6726, + 0x4137, 0x5769, 0x4970, 0x4f38, 0x562f, 0x5655, 0x6727, 0x306d, + 0x6728, 0x6729, 0x495c, 0x526f, 0x3e2d, 0x672a, 0x3073, 0x485e, + 0x3d61, 0x672b, 0x4846, 0x672c, 0x3b66, 0x3878, 0x5124, 0x672d, + 0x4267, 0x3e78, 0x3d4a, 0x4d33, 0x672e, 0x672f, 0x3e6e, 0x5065, + 0x4b67, 0x4c50, 0x3c4c, 0x6730, 0x3c28, 0x5077, 0x6731, 0x5078, + 0x6732, 0x6733, 0x3442, 0x6734, 0x6735, 0x497e, 0x4e2c, 0x4360, + 0x6737, 0x3141, 0x3371, 0x6738, 0x6739, 0x575b, 0x5540, 0x673a, + 0x424c, 0x573a, 0x673b, 0x673c, 0x673d, 0x3c6a, 0x4365, 0x4042, + 0x673e, 0x673f, 0x3c29, 0x6740, 0x6741, 0x6736, 0x3650, 0x6742, + 0x6743, 0x6744, 0x3b3a, 0x355e, 0x4246, 0x3160, 0x6745, 0x5435, + 0x6746, 0x383f, 0x6748, 0x6747, 0x376c, 0x6749, 0x3278, 0x674a, + 0x674b, 0x674c, 0x674d, 0x674e, 0x674f, 0x6750, 0x5327, 0x4b75, + 0x6751, 0x6752, 0x6753, 0x6754, 0x4949, 0x6755, 0x6756, 0x6757, + 0x6758, 0x6759, 0x3d49, 0x675a, 0x733e, 0x3857, 0x4831, 0x733f, + 0x7340, 0x7341, 0x395e, 0x4d78, 0x5868, 0x3a31, 0x425e, 0x6e37, + 0x3723, 0x6e39, 0x6e38, 0x3055, 0x6e3b, 0x5556, 0x576f, 0x5643, + 0x6e3d, 0x4a70, 0x6e3c, 0x6e3e, 0x6e40, 0x6e3f, 0x5172, 0x473c, + 0x4340, 0x3861, 0x4167, 0x7446, 0x505f, 0x7447, 0x4f5b, 0x483a, + 0x7448, 0x7449, 0x744a, 0x744b, 0x597a, 0x387e, 0x6571, 0x5370, + 0x7460, 0x4e4c, 0x3361, 0x7134, 0x526e, 0x7461, 0x4f68, 0x7462, + 0x474c, 0x3554, 0x3464, 0x7464, 0x7463, 0x7465, 0x7466, 0x7467, + 0x3a32, 0x303f, 0x7468, 0x372d, 0x526d, 0x522b, 0x404f, 0x3f3c, + 0x6b23, 0x555f, 0x6a48, 0x7173, 0x3678, 0x4b23, 0x444d, 0x7167, + 0x7168, 0x387b, 0x7169, 0x3a44, 0x5445, 0x3052, 0x716a, 0x716b, + 0x716c, 0x716d, 0x716e, 0x716f, 0x7171, 0x7170, 0x4555, 0x7172, + 0x367a, 0x7174, 0x522e, 0x5e47, 0x4b4a, 0x335c, 0x3522, 0x3922, + 0x4474, 0x7175, 0x7176, 0x4144, 0x417b, 0x5630, 0x7177, 0x7178, + 0x412a, 0x4638, 0x3e5b, 0x7179, 0x344f, 0x717a, 0x6d32, 0x6d31, + 0x4b60, 0x525e, 0x4b41, 0x5558, 0x4862, 0x405f, 0x3c21, 0x6b41, + 0x5024, 0x5662, 0x3647, 0x3858, 0x6b40, 0x384e, 0x6b3f, 0x3326, + 0x3949, 0x562b, 0x3774, 0x374a, 0x3c67, 0x373e, 0x6b46, 0x6b47, + 0x3039, 0x3f4f, 0x6b45, 0x537d, 0x6b48, 0x6b49, 0x374e, 0x6b42, + 0x6b44, 0x4976, 0x5657, 0x554d, 0x5032, 0x6b4f, 0x4e38, 0x6b50, + 0x3528, 0x3133, 0x6b52, 0x4c25, 0x4556, 0x6b53, 0x6b51, 0x455f, + 0x6b4e, 0x4a24, 0x6b55, 0x307b, 0x3a7a, 0x5837, 0x7163, 0x6b4a, + 0x6b4b, 0x6b4c, 0x6b4d, 0x6b56, 0x6640, 0x6b59, 0x3f68, 0x5248, + 0x6b57, 0x6b5c, 0x386c, 0x6b58, 0x3d3a, 0x5058, 0x3037, 0x6b5d, + 0x445c, 0x562c, 0x3460, 0x4276, 0x3c39, 0x6b5a, 0x6b5b, 0x5460, + 0x466a, 0x4454, 0x6b5f, 0x4527, 0x5975, 0x3231, 0x6b64, 0x3d45, + 0x6b62, 0x6b63, 0x382c, 0x4d51, 0x6b65, 0x6b61, 0x4133, 0x4622, + 0x4c73, 0x6b66, 0x4030, 0x5238, 0x6b67, 0x382f, 0x382d, 0x6b68, + 0x473b, 0x4d73, 0x6b6a, 0x6b6b, 0x6b6d, 0x5048, 0x6b72, 0x6b6e, + 0x6b71, 0x4879, 0x517c, 0x6b6c, 0x6b69, 0x3839, 0x4f59, 0x4465, + 0x6b6f, 0x6b70, 0x4c5a, 0x4d48, 0x3072, 0x6b76, 0x6b75, 0x3232, + 0x3860, 0x6b77, 0x316c, 0x4c45, 0x4424, 0x4f25, 0x6b79, 0x6c22, + 0x4572, 0x6b7a, 0x4945, 0x625f, 0x6b7e, 0x4d4e, 0x6c21, 0x315b, + 0x5337, 0x525c, 0x6b7d, 0x6b7b, 0x333c, 0x6a30, 0x5754, 0x742b, + 0x3374, 0x5641, 0x5642, 0x5569, 0x3e4a, 0x7427, 0x5228, 0x7428, + 0x7429, 0x742a, 0x3e4b, 0x535f, 0x4960, 0x4961, 0x7342, 0x4a66, + 0x4c72, 0x6236, 0x4b34, 0x4e68, 0x565b, 0x742d, 0x742e, 0x742f, + 0x7432, 0x3a3d, 0x7433, 0x3063, 0x7430, 0x7431, 0x3d22, 0x3255, + 0x7436, 0x7437, 0x3666, 0x3230, 0x4f4f, 0x7434, 0x342c, 0x7435, + 0x7438, 0x7439, 0x4d27, 0x743a, 0x743b, 0x743c, 0x4b52, 0x743d, + 0x743e, 0x743f, 0x745e, 0x413c, 0x3c68, 0x492b, 0x515e, 0x6575, + 0x5c33, 0x5255, 0x5c34, 0x302c, 0x5c35, 0x3d5a, 0x5c39, 0x5842, + 0x5c37, 0x5373, 0x4956, 0x5c3a, 0x5c36, 0x5c3b, 0x4322, 0x5c3c, + 0x5c45, 0x5c3d, 0x4e5f, 0x5625, 0x5c4f, 0x5c4d, 0x5c52, 0x3d66, + 0x422b, 0x5c38, 0x5c4b, 0x5c4e, 0x5c3e, 0x3752, 0x3045, 0x5c47, + 0x503e, 0x5c41, 0x3b28, 0x373c, 0x5c4c, 0x5c46, 0x5c3f, 0x475b, + 0x513f, 0x5c40, 0x5c4a, 0x5c50, 0x4e2d, 0x5c42, 0x5c43, 0x5c48, + 0x5c49, 0x3254, 0x5c51, 0x4b55, 0x5437, 0x5c5b, 0x5c5f, 0x4c26, + 0x5c66, 0x4367, 0x5c5c, 0x3f41, 0x5c59, 0x307a, 0x3936, 0x5c65, + 0x5c53, 0x5c44, 0x5c56, 0x4874, 0x3f60, 0x493b, 0x313d, 0x5322, + 0x5c5a, 0x5c55, 0x463b, 0x5c5e, 0x5742, 0x432f, 0x3736, 0x4751, + 0x4329, 0x5c62, 0x5c58, 0x5c6b, 0x5c54, 0x5c5d, 0x3e25, 0x5c57, + 0x5c60, 0x5c63, 0x5c64, 0x5c78, 0x5c61, 0x5d22, 0x5c67, 0x3c6b, + 0x3444, 0x4323, 0x3267, 0x5c7a, 0x5c72, 0x5c6f, 0x5c7c, 0x5c6e, + 0x5270, 0x3268, 0x4857, 0x4863, 0x5c7b, 0x5c6d, 0x5c77, 0x5c75, + 0x3e23, 0x5c74, 0x325d, 0x5c73, 0x3c76, 0x5c68, 0x3b44, 0x4073, + 0x3c54, 0x5c69, 0x5c6a, 0x5c71, 0x5c76, 0x5c79, 0x3534, 0x4859, + 0x3b67, 0x5c7e, 0x5c7d, 0x532b, 0x5d21, 0x5d23, 0x5d25, 0x5271, + 0x5d24, 0x5d26, 0x5d27, 0x5229, 0x3a49, 0x5d29, 0x5d36, 0x5d31, + 0x5d34, 0x5d30, 0x464e, 0x4072, 0x492f, 0x5c6c, 0x5d2e, 0x5d37, + 0x5c70, 0x5d2f, 0x5d38, 0x5d2c, 0x5d39, 0x5d33, 0x5d2d, 0x442a, + 0x5d28, 0x4033, 0x412b, 0x5d2a, 0x5d2b, 0x5d32, 0x3b71, 0x5d35, + 0x5328, 0x5d3a, 0x5d3b, 0x4327, 0x5d52, 0x5d3c, 0x5d51, 0x393d, + 0x3e55, 0x3e7a, 0x3a4a, 0x5d4a, 0x5d45, 0x5d3f, 0x324b, 0x5d43, + 0x5d4b, 0x3224, 0x5d55, 0x5d3e, 0x4650, 0x5d50, 0x5d54, 0x4162, + 0x3746, 0x5d4e, 0x5d4f, 0x5d44, 0x5d3d, 0x5d4d, 0x4c51, 0x5d49, + 0x5d42, 0x4348, 0x463c, 0x4e2e, 0x5d4c, 0x5d48, 0x5d41, 0x5d46, + 0x425c, 0x5329, 0x532a, 0x5d53, 0x4f74, 0x4878, 0x5d66, 0x5d47, + 0x5d60, 0x4264, 0x5d61, 0x5d57, 0x5678, 0x5d59, 0x5d58, 0x3870, + 0x5d56, 0x464f, 0x362d, 0x5d62, 0x3a79, 0x5461, 0x5d67, 0x3450, + 0x5d5a, 0x3f7b, 0x5d63, 0x5d5f, 0x5d5d, 0x3559, 0x5d5b, 0x5d5c, + 0x5d5e, 0x3d2f, 0x5d64, 0x5d65, 0x5d75, 0x4349, 0x4b62, 0x5d72, + 0x5861, 0x4651, 0x5d74, 0x5574, 0x5d73, 0x5d70, 0x5d6c, 0x5d6f, + 0x5d68, 0x506e, 0x4858, 0x5d6e, 0x5d69, 0x5d6a, 0x4b72, 0x5d6d, + 0x314d, 0x4036, 0x3c3b, 0x5d71, 0x5d77, 0x5d76, 0x5d6b, 0x456e, + 0x5d7b, 0x5e24, 0x5e23, 0x5d78, 0x436f, 0x427b, 0x5561, 0x4e35, + 0x5d7d, 0x324c, 0x4468, 0x4a5f, 0x473e, 0x5d7a, 0x5d7c, 0x5d7e, + 0x5e22, 0x302a, 0x314e, 0x5e2c, 0x5e26, 0x3d36, 0x486f, 0x5e21, + 0x5e25, 0x5e29, 0x5e28, 0x5e27, 0x5e2d, 0x544c, 0x5e33, 0x5e2a, + 0x5e2e, 0x4059, 0x3121, 0x5e36, 0x5e31, 0x5e32, 0x5126, 0x5e35, + 0x5e2f, 0x5e30, 0x503d, 0x5e34, 0x4a6d, 0x5e39, 0x5e38, 0x5e37, + 0x5e3b, 0x3d65, 0x3258, 0x436a, 0x5e3a, 0x453a, 0x5e3c, 0x4c59, + 0x372a, 0x5465, 0x5e3d, 0x5e3f, 0x4422, 0x5e41, 0x5e3e, 0x5e40, + 0x553a, 0x5e42, 0x722e, 0x3b22, 0x4232, 0x4530, 0x4247, 0x722f, + 0x5069, 0x535d, 0x6b3d, 0x3366, 0x7230, 0x7231, 0x4a2d, 0x3a67, + 0x7233, 0x7235, 0x7234, 0x4b64, 0x4f3a, 0x7232, 0x4a34, 0x524f, + 0x426c, 0x4e43, 0x7238, 0x3076, 0x7237, 0x723e, 0x324f, 0x5141, + 0x723a, 0x723c, 0x5469, 0x723b, 0x7236, 0x723f, 0x723d, 0x7239, + 0x7247, 0x7244, 0x7246, 0x724a, 0x7242, 0x7240, 0x7245, 0x567b, + 0x7241, 0x4779, 0x495f, 0x7248, 0x3946, 0x3530, 0x7243, 0x7249, + 0x7250, 0x7256, 0x3b57, 0x7255, 0x4d5c, 0x566b, 0x7252, 0x7254, + 0x3872, 0x724b, 0x724e, 0x4279, 0x555d, 0x724c, 0x724d, 0x724f, + 0x7253, 0x7259, 0x533c, 0x366a, 0x4a71, 0x3764, 0x7257, 0x7258, + 0x725a, 0x725d, 0x725b, 0x725c, 0x5151, 0x7251, 0x4d49, 0x4e4f, + 0x5629, 0x7263, 0x435b, 0x7260, 0x402f, 0x726c, 0x725e, 0x7261, + 0x7268, 0x7262, 0x7267, 0x7266, 0x7269, 0x725f, 0x7264, 0x726a, + 0x532c, 0x7265, 0x3275, 0x7272, 0x502b, 0x7275, 0x3b48, 0x7279, + 0x7270, 0x7276, 0x7278, 0x727a, 0x7273, 0x7271, 0x3a7b, 0x357b, + 0x726f, 0x7277, 0x726d, 0x726e, 0x726b, 0x7326, 0x7323, 0x7322, + 0x7274, 0x485a, 0x727b, 0x7325, 0x4378, 0x727d, 0x7327, 0x7329, + 0x7324, 0x727c, 0x732b, 0x732a, 0x425d, 0x732e, 0x7330, 0x7321, + 0x7331, 0x732c, 0x732f, 0x727e, 0x732d, 0x7332, 0x7334, 0x7328, + 0x7333, 0x7335, 0x5037, 0x7338, 0x5979, 0x7339, 0x7337, 0x4864, + 0x7336, 0x733a, 0x733b, 0x3440, 0x6e43, 0x733c, 0x733d, 0x512a, + 0x742c, 0x5046, 0x5050, 0x515c, 0x4f4e, 0x3d56, 0x5143, 0x3a62, + 0x6169, 0x5242, 0x7142, 0x3239, 0x316d, 0x7143, 0x4940, 0x3344, + 0x5972, 0x4b25, 0x7144, 0x5654, 0x7145, 0x7440, 0x7146, 0x542c, + 0x7147, 0x3040, 0x7441, 0x7442, 0x347c, 0x455b, 0x4c3b, 0x5064, + 0x4d60, 0x7148, 0x5973, 0x313b, 0x4f2e, 0x3824, 0x714a, 0x714b, + 0x3243, 0x4151, 0x5730, 0x7149, 0x714c, 0x714e, 0x5976, 0x5261, + 0x5423, 0x7443, 0x4839, 0x7444, 0x714d, 0x714f, 0x3f63, 0x7150, + 0x7154, 0x7156, 0x7151, 0x4951, 0x4561, 0x4263, 0x397c, 0x7153, + 0x7155, 0x3953, 0x715b, 0x3a56, 0x307d, 0x7159, 0x7158, 0x7152, + 0x715a, 0x7157, 0x486c, 0x4d4a, 0x715d, 0x653d, 0x715c, 0x715e, + 0x715f, 0x4f65, 0x7445, 0x3d73, 0x7160, 0x7161, 0x4e77, 0x522a, + 0x717b, 0x3832, 0x3c7b, 0x395b, 0x3966, 0x4359, 0x4a53, 0x6a68, + 0x4040, 0x3e75, 0x6a69, 0x6a6a, 0x6a6b, 0x6a6c, 0x6a6d, 0x6a6e, + 0x6a6f, 0x3d47, 0x757b, 0x757d, 0x757e, 0x757c, 0x3d62, 0x7621, + 0x3425, 0x7622, 0x7623, 0x6c32, 0x5154, 0x596a, 0x7624, 0x6e3a, + 0x5532, 0x537e, 0x4c5c, 0x4a44, 0x6540, 0x7625, 0x3e2f, 0x4629, + 0x5a25, 0x3c46, 0x3629, 0x383c, 0x484f, 0x3c25, 0x5a26, 0x5a27, + 0x4c56, 0x4843, 0x5a28, 0x467d, 0x5135, 0x5269, 0x5136, 0x3c47, + 0x3d32, 0x3b64, 0x5a29, 0x5a2a, 0x5148, 0x5a2b, 0x506d, 0x366f, + 0x425b, 0x4b4f, 0x376d, 0x4968, 0x3743, 0x3e77, 0x5624, 0x5a2c, + 0x5a2d, 0x4640, 0x5767, 0x4a36, 0x5529, 0x4b5f, 0x556f, 0x5a2e, + 0x565f, 0x344a, 0x5a30, 0x5a2f, 0x526b, 0x5a31, 0x5a32, 0x5a33, + 0x4a54, 0x5a34, 0x4a2b, 0x5a35, 0x5a36, 0x334f, 0x566f, 0x5a37, + 0x3b30, 0x352e, 0x5a38, 0x5a39, 0x396e, 0x512f, 0x5268, 0x5a3a, + 0x3843, 0x4f6a, 0x326f, 0x5a3b, 0x5a3c, 0x3d6b, 0x4e5c, 0x536f, + 0x5a3d, 0x4e73, 0x5a3e, 0x5355, 0x3b65, 0x5a3f, 0x4b35, 0x4b50, + 0x5a40, 0x476b, 0x566e, 0x5a41, 0x4535, 0x3641, 0x5a42, 0x374c, + 0x3f4e, 0x5a43, 0x5a44, 0x4b2d, 0x5a45, 0x3577, 0x5a46, 0x4142, + 0x573b, 0x5a47, 0x4c38, 0x526a, 0x4431, 0x5a48, 0x357d, 0x3b51, + 0x5a49, 0x5033, 0x5a4a, 0x5a4b, 0x4e3d, 0x5a4c, 0x5a4d, 0x5a4e, + 0x3277, 0x5a51, 0x5a4f, 0x5168, 0x5a50, 0x4355, 0x5a52, 0x5a53, + 0x5a54, 0x5a55, 0x503b, 0x5225, 0x3079, 0x5a56, 0x472b, 0x5a57, + 0x3d77, 0x4321, 0x5a58, 0x5a59, 0x437d, 0x4c37, 0x5a5a, 0x5a5b, + 0x403e, 0x4657, 0x5a5c, 0x5a5d, 0x4734, 0x5a5e, 0x5a5f, 0x3948, + 0x3b6d, 0x3639, 0x7478, 0x7479, 0x4d63, 0x7539, 0x6b60, 0x4f73, + 0x3b3f, 0x3a40, 0x5425, 0x6159, 0x7574, 0x312a, 0x3272, 0x7575, + 0x7577, 0x3a51, 0x7576, 0x4332, 0x7579, 0x7578, 0x3134, 0x556a, + 0x383a, 0x3931, 0x3246, 0x5470, 0x4f4d, 0x305c, 0x554b, 0x3b75, + 0x564a, 0x3737, 0x4c30, 0x4636, 0x3161, 0x393a, 0x567c, 0x3961, + 0x3721, 0x3c7a, 0x6a5a, 0x6a5b, 0x4c79, 0x3973, 0x6a5c, 0x347b, + 0x4333, 0x3751, 0x3a58, 0x6a5d, 0x5474, 0x6a5e, 0x3c56, 0x3b5f, + 0x6a5f, 0x415e, 0x4238, 0x545f, 0x574a, 0x6a60, 0x6a61, 0x6a64, + 0x6a62, 0x6a63, 0x495e, 0x3833, 0x3644, 0x6a65, 0x4a6a, 0x494d, + 0x344d, 0x6259, 0x4562, 0x6a66, 0x4035, 0x5738, 0x6a67, 0x572c, + 0x487c, 0x5853, 0x584d, 0x545e, 0x5479, 0x4944, 0x532e, 0x3853, + 0x3360, 0x4962, 0x7476, 0x3a55, 0x7477, 0x575f, 0x7471, 0x3830, + 0x5554, 0x384f, 0x4670, 0x3343, 0x7472, 0x332c, 0x543d, 0x4777, + 0x7474, 0x7473, 0x4c4b, 0x4824, 0x7475, 0x5763, 0x453f, 0x7540, + 0x753b, 0x7543, 0x7542, 0x563a, 0x7541, 0x543e, 0x7544, 0x754c, + 0x304f, 0x3578, 0x7549, 0x754a, 0x455c, 0x7545, 0x7546, 0x7547, + 0x754b, 0x3e60, 0x7548, 0x387a, 0x7550, 0x7553, 0x3f67, 0x3972, + 0x753c, 0x754d, 0x4237, 0x4c78, 0x3c79, 0x754e, 0x754f, 0x7551, + 0x3665, 0x7552, 0x7555, 0x753d, 0x7554, 0x533b, 0x336c, 0x4c24, + 0x7556, 0x7557, 0x3e61, 0x7558, 0x4c5f, 0x755b, 0x3248, 0x5759, + 0x7559, 0x755a, 0x755c, 0x7562, 0x7560, 0x755f, 0x755d, 0x7561, + 0x755e, 0x7564, 0x7565, 0x4c63, 0x653f, 0x3538, 0x7563, 0x7568, + 0x4c23, 0x7566, 0x7567, 0x753e, 0x3144, 0x753f, 0x3545, 0x3264, + 0x756c, 0x7569, 0x3657, 0x756d, 0x756a, 0x756b, 0x345a, 0x546a, + 0x756e, 0x3379, 0x756f, 0x7571, 0x7570, 0x7572, 0x7573, 0x496d, + 0x392a, 0x477b, 0x3663, 0x4c49, 0x6a26, 0x3335, 0x547e, 0x396c, + 0x5079, 0x696d, 0x572a, 0x696e, 0x4256, 0x486d, 0x3a64, 0x696f, + 0x6970, 0x6971, 0x5661, 0x6972, 0x6973, 0x6975, 0x6974, 0x6976, + 0x6977, 0x4761, 0x6978, 0x5458, 0x6979, 0x3d4e, 0x697a, 0x697b, + 0x3d4f, 0x697c, 0x3828, 0x413e, 0x697d, 0x3132, 0x3b54, 0x3975, + 0x697e, 0x6a21, 0x6a22, 0x6a23, 0x3778, 0x3c2d, 0x4a64, 0x604e, + 0x542f, 0x4f3d, 0x5537, 0x6a24, 0x555e, 0x6a25, 0x5041, 0x393c, + 0x3447, 0x3159, 0x4031, 0x3166, 0x3167, 0x3168, 0x333d, 0x4868, + 0x6541, 0x315f, 0x4149, 0x346f, 0x4728, 0x5358, 0x4679, 0x5138, + 0x397d, 0x4275, 0x532d, 0x544b, 0x3d7c, 0x6542, 0x3735, 0x6543, + 0x3b39, 0x5562, 0x3d78, 0x5436, 0x4e25, 0x412c, 0x3359, 0x4c76, + 0x6546, 0x6544, 0x6548, 0x654a, 0x6547, 0x354f, 0x4648, 0x357c, + 0x6545, 0x4a76, 0x6549, 0x4354, 0x3145, 0x3c23, 0x5737, 0x4d4b, + 0x4b4d, 0x4a4a, 0x4c53, 0x654c, 0x654b, 0x4466, 0x5121, 0x5137, + 0x654d, 0x6550, 0x4d38, 0x5670, 0x654f, 0x355d, 0x4d3e, 0x6551, + 0x363a, 0x4d28, 0x3964, 0x4a45, 0x3351, 0x4b59, 0x546c, 0x6552, + 0x376a, 0x654e, 0x6555, 0x347e, 0x6556, 0x6553, 0x6554, 0x525d, + 0x425f, 0x3146, 0x5362, 0x365d, 0x4b6c, 0x6557, 0x5376, 0x3169, + 0x3674, 0x655a, 0x6558, 0x6559, 0x3540, 0x5245, 0x655c, 0x655e, + 0x655d, 0x4732, 0x5223, 0x655b, 0x5462, 0x555a, 0x6560, 0x5771, + 0x6561, 0x315c, 0x517b, 0x6562, 0x6564, 0x6563, 0x6565, 0x5258, + 0x354b, 0x675f, 0x5a75, 0x5a78, 0x5a76, 0x5a77, 0x5a7a, 0x504f, + 0x4447, 0x306e, 0x5030, 0x5a79, 0x534a, 0x3a2a, 0x5b22, 0x4771, + 0x5a7c, 0x5a7b, 0x495b, 0x5a7d, 0x5b21, 0x575e, 0x5a7e, 0x415a, + 0x5b25, 0x5374, 0x5b27, 0x5b24, 0x5b28, 0x3d3c, 0x4049, 0x5b23, + 0x5b26, 0x5623, 0x5b29, 0x5b2d, 0x5b2e, 0x5b2c, 0x3a42, 0x3f24, + 0x5b2b, 0x5b2a, 0x5447, 0x323f, 0x5b2f, 0x3979, 0x5b30, 0x333b, + 0x3526, 0x363c, 0x5b31, 0x3675, 0x5b32, 0x3149, 0x5b34, 0x5b33, + 0x5b35, 0x5b37, 0x5b36, 0x5b38, 0x5b39, 0x5b3a, 0x534f, 0x747a, + 0x4775, 0x5743, 0x4564, 0x747c, 0x747d, 0x747b, 0x3e46, 0x506f, + 0x3753, 0x544d, 0x4c2a, 0x7522, 0x7521, 0x3a28, 0x747e, 0x4b56, + 0x7524, 0x4052, 0x336a, 0x4d2a, 0x7525, 0x7523, 0x3d34, 0x7528, + 0x7529, 0x3d4d, 0x4338, 0x3f61, 0x4b61, 0x752a, 0x7526, 0x7527, + 0x4470, 0x752c, 0x343c, 0x576d, 0x3457, 0x752b, 0x752e, 0x752d, + 0x752f, 0x5051, 0x4351, 0x4829, 0x7530, 0x7531, 0x7532, 0x7533, + 0x7534, 0x7535, 0x7537, 0x7536, 0x7538, 0x3249, 0x5354, 0x4a4d, + 0x406f, 0x5658, 0x5230, 0x413f, 0x3d70, 0x382a, 0x3c78, 0x7646, + 0x7647, 0x7648, 0x7649, 0x764a, 0x764c, 0x764b, 0x7769, 0x764d, + 0x764e, 0x6e44, 0x6e45, 0x6e46, 0x556b, 0x3624, 0x6e48, 0x6e47, + 0x6e49, 0x6e4a, 0x4725, 0x6e4b, 0x6e4c, 0x3730, 0x3576, 0x6e4d, + 0x6e4f, 0x6e4e, 0x3846, 0x6e50, 0x6e51, 0x6e52, 0x365b, 0x332e, + 0x5653, 0x4446, 0x3135, 0x3856, 0x6e53, 0x6e54, 0x543f, 0x4755, + 0x3e7b, 0x4e59, 0x3933, 0x6e56, 0x6e55, 0x6e58, 0x6e57, 0x4525, + 0x6e59, 0x6e5a, 0x472e, 0x6e5b, 0x472f, 0x6e5c, 0x3227, 0x6e5d, + 0x6e5e, 0x6e5f, 0x6e60, 0x6e61, 0x576a, 0x6e62, 0x6e63, 0x3c58, + 0x6e64, 0x534b, 0x4c7a, 0x322c, 0x4165, 0x6e65, 0x4726, 0x432d, + 0x6e66, 0x6e67, 0x6e68, 0x6e69, 0x6e6a, 0x6e6b, 0x6e6c, 0x6e6d, + 0x6e6e, 0x6e6f, 0x6e70, 0x6e71, 0x6e72, 0x6e74, 0x6e73, 0x6e75, + 0x4d2d, 0x4241, 0x6e76, 0x6e77, 0x6e78, 0x5521, 0x6e79, 0x4f33, + 0x6e7a, 0x6e7b, 0x6e7c, 0x6e7d, 0x6f21, 0x6e7e, 0x6f22, 0x3875, + 0x437a, 0x6f23, 0x6f24, 0x3d42, 0x523f, 0x3279, 0x6f25, 0x6f26, + 0x6f27, 0x5278, 0x6f28, 0x567d, 0x6f29, 0x464c, 0x6f2a, 0x6f2b, + 0x4134, 0x6f2c, 0x4f7a, 0x4b78, 0x6f2e, 0x6f2d, 0x337a, 0x3978, + 0x6f2f, 0x6f30, 0x5062, 0x6f31, 0x6f32, 0x3766, 0x503f, 0x6f33, + 0x6f34, 0x6f35, 0x4871, 0x4c60, 0x6f36, 0x6f37, 0x6f38, 0x6f39, + 0x6f3a, 0x5560, 0x6f3b, 0x346d, 0x432a, 0x6f3c, 0x6f3d, 0x6f3e, + 0x6f3f, 0x4e7d, 0x6f40, 0x4260, 0x3438, 0x5736, 0x3d75, 0x4f47, + 0x6f43, 0x6f41, 0x6f42, 0x6f44, 0x3627, 0x3c7c, 0x3e62, 0x434c, + 0x6f45, 0x6f46, 0x6f47, 0x6f4f, 0x6f48, 0x6f49, 0x6f4a, 0x4742, + 0x6f71, 0x364d, 0x6f4b, 0x6f4c, 0x6f4d, 0x3646, 0x433e, 0x6f4e, + 0x6f50, 0x6f51, 0x6f52, 0x5572, 0x6f53, 0x4477, 0x6f54, 0x4478, + 0x6f55, 0x6f56, 0x3864, 0x3077, 0x6f57, 0x6f58, 0x6f59, 0x6f5a, + 0x6f5b, 0x6f5c, 0x6f5d, 0x6f5e, 0x3e35, 0x6f61, 0x6f5f, 0x6f60, + 0x6f62, 0x6f63, 0x414d, 0x6f64, 0x6f65, 0x6f66, 0x6f67, 0x6f68, + 0x6f69, 0x6f6a, 0x6f6b, 0x6f6c, 0x4058, 0x6f6d, 0x412d, 0x6f6e, + 0x6f6f, 0x6f70, 0x4f62, 0x3324, 0x4345, 0x6345, 0x4941, 0x6346, + 0x3155, 0x4e4a, 0x3433, 0x4872, 0x6347, 0x4f50, 0x6348, 0x3c64, + 0x6349, 0x634a, 0x4346, 0x5522, 0x4456, 0x396b, 0x4e45, 0x634b, + 0x4376, 0x634c, 0x3727, 0x3873, 0x3a52, 0x634d, 0x634e, 0x5444, + 0x634f, 0x6350, 0x514b, 0x6351, 0x6352, 0x6353, 0x6354, 0x5156, + 0x6355, 0x327b, 0x403b, 0x6356, 0x402b, 0x6357, 0x6358, 0x6359, + 0x635a, 0x635b, 0x3837, 0x5a62, 0x3653, 0x5a64, 0x5a63, 0x5a66, + 0x486e, 0x5a65, 0x3740, 0x5174, 0x5275, 0x5573, 0x3d57, 0x5768, + 0x5a68, 0x5a67, 0x3022, 0x4d53, 0x5a69, 0x383d, 0x3c4a, 0x423d, + 0x4224, 0x3342, 0x5a6a, 0x422a, 0x4430, 0x3d35, 0x4f5e, 0x5a6b, + 0x4942, 0x315d, 0x5a6c, 0x3638, 0x543a, 0x337d, 0x5a6d, 0x5449, + 0x4f55, 0x4563, 0x5a6e, 0x5a6f, 0x5a70, 0x416a, 0x4c55, 0x4f5d, + 0x5367, 0x4221, 0x5a71, 0x4b65, 0x5a72, 0x4b66, 0x527e, 0x3874, + 0x5a73, 0x302f, 0x4f36, 0x554f, 0x4b6d, 0x5a74, 0x6344, 0x4125, + 0x763f, 0x7640, 0x7641, 0x4451, 0x4838, 0x5163, 0x505b, 0x5145, + 0x3c2f, 0x394d, 0x6f74, 0x3446, 0x533a, 0x7642, 0x337b, 0x7643, + 0x3571, 0x7645, 0x536a, 0x7627, 0x5129, 0x7629, 0x7628, 0x4163, + 0x4057, 0x3122, 0x4e6d, 0x5068, 0x762b, 0x4f76, 0x762a, 0x5570, + 0x762c, 0x4339, 0x3b74, 0x762e, 0x762d, 0x445e, 0x4158, 0x4b2a, + 0x4f3c, 0x762f, 0x7630, 0x7631, 0x4236, 0x3054, 0x4579, 0x7632, + 0x4760, 0x7626, 0x3e38, 0x3e32, 0x3565, 0x3747, 0x3f3f, 0x4352, + 0x4366, 0x584c, 0x386f, 0x3d79, 0x5125, 0x3050, 0x7730, 0x7731, + 0x502c, 0x3030, 0x7732, 0x7733, 0x7734, 0x474a, 0x3e4f, 0x7737, + 0x7736, 0x315e, 0x7735, 0x7738, 0x7739, 0x4e24, 0x484d, 0x3a2b, + 0x6838, 0x6839, 0x683a, 0x3e42, 0x5274, 0x544f, 0x4958, 0x5233, + 0x3625, 0x476a, 0x717c, 0x4f6e, 0x4b33, 0x506b, 0x676f, 0x4d67, + 0x394b, 0x3659, 0x717d, 0x3064, 0x4b4c, 0x717e, 0x5424, 0x422d, + 0x416c, 0x4644, 0x3e31, 0x7221, 0x3c55, 0x7222, 0x7223, 0x7224, + 0x5243, 0x4635, 0x4d47, 0x7225, 0x5331, 0x3f45, 0x4c62, 0x7226, + 0x7227, 0x5155, 0x366e, 0x7228, 0x7229, 0x355f, 0x722a, 0x722b, + 0x327c, 0x722c, 0x722d, 0x4827, 0x3767, 0x6c29, 0x6c2a, 0x6c2b, + 0x6c2c, 0x462e, 0x6c2d, 0x6c2e, 0x3749, 0x4a33, 0x6238, 0x774f, + 0x7750, 0x324d, 0x7751, 0x7753, 0x7752, 0x623b, 0x3c22, 0x623c, + 0x623d, 0x623e, 0x623f, 0x6240, 0x6241, 0x3739, 0x527b, 0x3d24, + 0x4a4e, 0x3125, 0x4b47, 0x6242, 0x367c, 0x4844, 0x6243, 0x3d48, + 0x317d, 0x6244, 0x3676, 0x6245, 0x4459, 0x6246, 0x4f5a, 0x395d, + 0x6247, 0x4021, 0x6248, 0x3276, 0x6249, 0x4173, 0x624a, 0x624b, + 0x4278, 0x624c, 0x624d, 0x624e, 0x4a57, 0x5838, 0x5965, 0x4f63, + 0x7025, 0x5c30, 0x426d, 0x5426, 0x4d54, 0x5131, 0x335b, 0x477d, + 0x3235, 0x423f, 0x6660, 0x4a3b, 0x6661, 0x6662, 0x3e54, 0x6663, + 0x5724, 0x4d55, 0x6665, 0x3c5d, 0x6664, 0x6666, 0x6667, 0x426e, + 0x3d3e, 0x6668, 0x4266, 0x3a27, 0x6669, 0x666a, 0x3352, 0x5169, + 0x3f25, 0x666b, 0x466f, 0x666c, 0x666d, 0x666e, 0x462d, 0x666f, + 0x4927, 0x6670, 0x6671, 0x6672, 0x6539, 0x6673, 0x6674, 0x4262, + 0x6675, 0x6676, 0x5668, 0x6677, 0x6678, 0x3947, 0x773b, 0x773a, + 0x773e, 0x773c, 0x3a21, 0x773f, 0x7740, 0x7742, 0x7741, 0x7744, + 0x7743, 0x7745, 0x7746, 0x7747, 0x4b68, 0x385f, 0x7754, 0x7755, + 0x7756, 0x7758, 0x775a, 0x7757, 0x775b, 0x7759, 0x5757, 0x775c, + 0x775d, 0x775e, 0x775f, 0x7760, 0x5b4b, 0x582a, 0x6577, 0x396d, + 0x3f7d, 0x3b6a, 0x7749, 0x4647, 0x7748, 0x774a, 0x774c, 0x774b, + 0x774d, 0x4e3a, 0x774e, 0x4427, 0x5363, 0x764f, 0x4233, 0x7650, + 0x7651, 0x7652, 0x7653, 0x7654, 0x7656, 0x312b, 0x7657, 0x7658, + 0x7659, 0x765a, 0x765b, 0x765c, 0x765d, 0x765e, 0x4f4a, 0x765f, + 0x7660, 0x7661, 0x7662, 0x7663, 0x7664, 0x4070, 0x7665, 0x7666, + 0x7667, 0x7668, 0x7669, 0x766a, 0x766b, 0x766c, 0x766d, 0x766e, + 0x766f, 0x7670, 0x7671, 0x7672, 0x7673, 0x7674, 0x3e28, 0x7675, + 0x7676, 0x7677, 0x7678, 0x487a, 0x7679, 0x767a, 0x767b, 0x767c, + 0x767d, 0x767e, 0x7721, 0x7722, 0x7723, 0x7724, 0x7725, 0x7726, + 0x7727, 0x7728, 0x316e, 0x7729, 0x772a, 0x772b, 0x772c, 0x772d, + 0x415b, 0x772e, 0x772f, 0x4471, 0x702f, 0x3c26, 0x7030, 0x4379, + 0x4538, 0x513b, 0x7031, 0x7032, 0x7033, 0x7034, 0x7035, 0x513c, + 0x516c, 0x7037, 0x7036, 0x5427, 0x4d52, 0x7038, 0x703a, 0x7039, + 0x703b, 0x703c, 0x386b, 0x703d, 0x3a68, 0x703e, 0x703f, 0x3e69, + 0x7040, 0x366c, 0x7041, 0x7042, 0x7043, 0x7044, 0x4835, 0x7045, + 0x7046, 0x7047, 0x4574, 0x7048, 0x7049, 0x704a, 0x773d, 0x704b, + 0x704c, 0x704d, 0x704e, 0x704f, 0x3a57, 0x7050, 0x7051, 0x7052, + 0x7053, 0x7054, 0x7055, 0x7056, 0x7058, 0x5325, 0x7057, 0x7059, + 0x753a, 0x4239, 0x7764, 0x7765, 0x7766, 0x7767, 0x7768, 0x4234, + 0x776a, 0x776b, 0x4273, 0x7470, 0x746f, 0x4269, 0x7761, 0x7762, + 0x3b46, 0x5964, 0x4a72, 0x4068, 0x7024, 0x3a5a, 0x472d, 0x442c, + 0x776c, 0x776d, 0x776e, 0x7770, 0x776f, 0x7771, 0x7774, 0x7773, + 0x7772, 0x7775, 0x7776, 0x6d69, 0x6d6a, 0x6d6b, 0x763c, 0x763d, + 0x763e, 0x3626, 0x583e, 0x3944, 0x583b, 0x5c31, 0x4a73, 0x7777, + 0x7778, 0x7779, 0x777b, 0x777a, 0x3147, 0x777c, 0x777d, 0x777e, + 0x466b, 0x6c34, 0x335d, 0x7633, 0x7634, 0x4164, 0x7635, 0x7636, + 0x7637, 0x7638, 0x7639, 0x763a, 0x4823, 0x763b, 0x417a, 0x3928, + 0x6d68, 0x396a, 0x595f, 0x2321, 0x2322, 0x2323, 0x2167, 0x2325, + 0x2326, 0x2327, 0x2328, 0x2329, 0x232a, 0x232b, 0x232c, 0x232d, + 0x232e, 0x232f, 0x2330, 0x2331, 0x2332, 0x2333, 0x2334, 0x2335, + 0x2336, 0x2337, 0x2338, 0x2339, 0x233a, 0x233b, 0x233c, 0x233d, + 0x233e, 0x233f, 0x2340, 0x2341, 0x2342, 0x2343, 0x2344, 0x2345, + 0x2346, 0x2347, 0x2348, 0x2349, 0x234a, 0x234b, 0x234c, 0x234d, + 0x234e, 0x234f, 0x2350, 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, + 0x2356, 0x2357, 0x2358, 0x2359, 0x235a, 0x235b, 0x235c, 0x235d, + 0x235e, 0x235f, 0x2360, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, + 0x2366, 0x2367, 0x2368, 0x2369, 0x236a, 0x236b, 0x236c, 0x236d, + 0x236e, 0x236f, 0x2370, 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, + 0x2376, 0x2377, 0x2378, 0x2379, 0x237a, 0x237b, 0x237c, 0x237d, + 0x212b, 0x2169, 0x216a, 0x237e, 0x2324, +}; + +static const Summary16 gb2312_uni2indx_page00[70] = { + /* 0x0000 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0190 }, { 3, 0x0003 }, + { 5, 0x0000 }, { 5, 0x0080 }, { 6, 0x3703 }, { 13, 0x168c }, + /* 0x0100 */ + { 19, 0x0002 }, { 20, 0x0808 }, { 22, 0x0800 }, { 23, 0x0000 }, + { 23, 0x2000 }, { 24, 0x0000 }, { 24, 0x0800 }, { 25, 0x0000 }, + { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, + { 25, 0x4000 }, { 26, 0x1555 }, { 33, 0x0000 }, { 33, 0x0000 }, + /* 0x0200 */ + { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, + { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, + { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, + { 33, 0x0280 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, + /* 0x0300 */ + { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, + { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, + { 35, 0x0000 }, { 35, 0xfffe }, { 50, 0x03fb }, { 59, 0xfffe }, + { 74, 0x03fb }, { 83, 0x0000 }, { 83, 0x0000 }, { 83, 0x0000 }, + /* 0x0400 */ + { 83, 0x0002 }, { 84, 0xffff }, { 100, 0xffff }, { 116, 0xffff }, + { 132, 0xffff }, { 148, 0x0002 }, +}; +static const Summary16 gb2312_uni2indx_page20[101] = { + /* 0x2000 */ + { 149, 0x0000 }, { 149, 0x3360 }, { 155, 0x0040 }, { 156, 0x080d }, + { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, + { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, + { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, + /* 0x2100 */ + { 160, 0x0008 }, { 161, 0x0040 }, { 162, 0x0000 }, { 162, 0x0000 }, + { 162, 0x0000 }, { 162, 0x0000 }, { 162, 0x0fff }, { 174, 0x0000 }, + { 174, 0x0000 }, { 174, 0x000f }, { 178, 0x0000 }, { 178, 0x0000 }, + { 178, 0x0000 }, { 178, 0x0000 }, { 178, 0x0000 }, { 178, 0x0000 }, + /* 0x2200 */ + { 178, 0x8100 }, { 180, 0x6402 }, { 184, 0x4fa1 }, { 192, 0x20f0 }, + { 197, 0x1100 }, { 199, 0x0000 }, { 199, 0xc033 }, { 205, 0x0000 }, + { 205, 0x0000 }, { 205, 0x0200 }, { 206, 0x0020 }, { 207, 0x0000 }, + { 207, 0x0000 }, { 207, 0x0000 }, { 207, 0x0000 }, { 207, 0x0000 }, + /* 0x2300 */ + { 207, 0x0000 }, { 207, 0x0004 }, { 208, 0x0000 }, { 208, 0x0000 }, + { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, + { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, + { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, + /* 0x2400 */ + { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, + { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x03ff }, { 218, 0xfff0 }, + { 230, 0xffff }, { 246, 0x0fff }, { 258, 0x0000 }, { 258, 0x0000 }, + { 258, 0x0000 }, { 258, 0x0000 }, { 258, 0x0000 }, { 258, 0x0000 }, + /* 0x2500 */ + { 258, 0xffff }, { 274, 0xffff }, { 290, 0xffff }, { 306, 0xffff }, + { 322, 0x0fff }, { 334, 0x0000 }, { 334, 0x0000 }, { 334, 0x0000 }, + { 334, 0x0000 }, { 334, 0x0000 }, { 334, 0x0003 }, { 336, 0x000c }, + { 338, 0xc8c0 }, { 343, 0x0000 }, { 343, 0x0000 }, { 343, 0x0000 }, + /* 0x2600 */ + { 343, 0x0060 }, { 345, 0x0000 }, { 345, 0x0000 }, { 345, 0x0000 }, + { 345, 0x0005 }, +}; +static const Summary16 gb2312_uni2indx_page30[35] = { + /* 0x3000 */ + { 347, 0xff2f }, { 360, 0x00fb }, { 367, 0x0000 }, { 367, 0x0000 }, + { 367, 0xfffe }, { 382, 0xffff }, { 398, 0xffff }, { 414, 0xffff }, + { 430, 0xffff }, { 446, 0x000f }, { 450, 0xfffe }, { 465, 0xffff }, + { 481, 0xffff }, { 497, 0xffff }, { 513, 0xffff }, { 529, 0x087f }, + /* 0x3100 */ + { 537, 0xffe0 }, { 548, 0xffff }, { 564, 0x03ff }, { 574, 0x0000 }, + { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, + { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, + { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x0000 }, + /* 0x3200 */ + { 574, 0x0000 }, { 574, 0x0000 }, { 574, 0x03ff }, +}; +static const Summary16 gb2312_uni2indx_page4e[1263] = { + /* 0x4e00 */ + { 584, 0x7f8b }, { 595, 0x7f7b }, { 608, 0x3db4 }, { 617, 0xef55 }, + { 628, 0xfba8 }, { 638, 0xf35d }, { 649, 0x0243 }, { 653, 0x400b }, + { 657, 0xfb40 }, { 665, 0x8d3e }, { 674, 0x7bf7 }, { 687, 0x8c2c }, + { 693, 0x6eff }, { 706, 0xe3fa }, { 717, 0x1d3a }, { 725, 0xa8ed }, + /* 0x4f00 */ + { 734, 0xe602 }, { 740, 0xcf83 }, { 749, 0x8cf5 }, { 758, 0x3555 }, + { 766, 0xe048 }, { 771, 0xffab }, { 784, 0x92b9 }, { 792, 0xd859 }, + { 800, 0xab18 }, { 807, 0x2892 }, { 812, 0xd7e9 }, { 823, 0x8020 }, + { 825, 0xc438 }, { 831, 0xf583 }, { 840, 0xe74a }, { 849, 0x450a }, + /* 0x5000 */ + { 854, 0xb000 }, { 857, 0x9714 }, { 864, 0x7762 }, { 873, 0x5400 }, + { 876, 0xd188 }, { 882, 0x1420 }, { 885, 0x1020 }, { 887, 0xc8c0 }, + { 892, 0x2121 }, { 896, 0x0000 }, { 896, 0x13a8 }, { 902, 0x0c04 }, + { 905, 0x8000 }, { 906, 0x0440 }, { 908, 0x70c0 }, { 913, 0x0828 }, + /* 0x5100 */ + { 916, 0x08c0 }, { 919, 0x0004 }, { 920, 0x0002 }, { 921, 0x8000 }, + { 922, 0x2b7b }, { 932, 0x1472 }, { 938, 0x7924 }, { 945, 0x3bfb }, + { 957, 0x3327 }, { 965, 0x1ae4 }, { 972, 0x9835 }, { 979, 0x38ef }, + { 989, 0x9ad1 }, { 997, 0x2802 }, { 1000, 0xa813 }, { 1006, 0xbf69 }, + /* 0x5200 */ + { 1017, 0x65cf }, { 1027, 0x2fc6 }, { 1036, 0x6b11 }, { 1043, 0xafc9 }, + { 1053, 0x340f }, { 1060, 0x5053 }, { 1066, 0x86a2 }, { 1072, 0xa004 }, + { 1075, 0x0106 }, { 1078, 0xe809 }, { 1084, 0x3f0f }, { 1094, 0xc00e }, + { 1099, 0x0a88 }, { 1103, 0x8145 }, { 1108, 0x0010 }, { 1109, 0xc601 }, + /* 0x5300 */ + { 1114, 0xa161 }, { 1120, 0x26e1 }, { 1127, 0x444b }, { 1133, 0xce00 }, + { 1138, 0xc7aa }, { 1147, 0xd4ee }, { 1157, 0xcadf }, { 1168, 0x85bb }, + { 1177, 0x3a74 }, { 1185, 0xa520 }, { 1190, 0x436c }, { 1197, 0x8840 }, + { 1200, 0x3f06 }, { 1208, 0x8bd2 }, { 1216, 0xff79 }, { 1229, 0x3bef }, + /* 0x5400 */ + { 1241, 0xf75a }, { 1252, 0xe8ef }, { 1263, 0xfbcb }, { 1275, 0x5b36 }, + { 1284, 0x0d49 }, { 1290, 0x1bfd }, { 1301, 0x0154 }, { 1305, 0x39ee }, + { 1315, 0xd855 }, { 1323, 0x2e75 }, { 1332, 0xbfd8 }, { 1343, 0xa91a }, + { 1350, 0xf3d7 }, { 1362, 0xf6bf }, { 1375, 0x67e0 }, { 1383, 0xb40c }, + /* 0x5500 */ + { 1389, 0x82c2 }, { 1394, 0x0813 }, { 1398, 0xd49d }, { 1407, 0xd08b }, + { 1414, 0x065a }, { 1420, 0x1061 }, { 1424, 0x74f2 }, { 1433, 0x59e0 }, + { 1440, 0x8f9f }, { 1451, 0xb312 }, { 1458, 0x0080 }, { 1459, 0x6aaa }, + { 1467, 0x3230 }, { 1472, 0xb05e }, { 1480, 0x9d7a }, { 1490, 0x60ac }, + /* 0x5600 */ + { 1496, 0xd303 }, { 1503, 0xc900 }, { 1507, 0x3098 }, { 1512, 0x8a56 }, + { 1519, 0x7000 }, { 1522, 0x1390 }, { 1527, 0x1f14 }, { 1534, 0x1842 }, + { 1538, 0xc060 }, { 1542, 0x0008 }, { 1543, 0x8008 }, { 1545, 0x1080 }, + { 1547, 0x0400 }, { 1548, 0xec90 }, { 1555, 0x2817 }, { 1561, 0xe633 }, + /* 0x5700 */ + { 1570, 0x0758 }, { 1576, 0x9000 }, { 1578, 0xf708 }, { 1586, 0x4e09 }, + { 1592, 0xf485 }, { 1600, 0xfc83 }, { 1609, 0xaf53 }, { 1619, 0x18c8 }, + { 1624, 0x187c }, { 1631, 0x080c }, { 1634, 0x6adf }, { 1645, 0x0114 }, + { 1648, 0xc80c }, { 1653, 0xa734 }, { 1661, 0xa011 }, { 1665, 0x2710 }, + /* 0x5800 */ + { 1670, 0x28c5 }, { 1676, 0x4222 }, { 1680, 0x0413 }, { 1684, 0x0021 }, + { 1686, 0x3010 }, { 1689, 0x4112 }, { 1693, 0x1820 }, { 1696, 0x4000 }, + { 1697, 0x022b }, { 1702, 0xc60c }, { 1708, 0x0300 }, { 1710, 0x1000 }, + { 1711, 0x0022 }, { 1713, 0x0022 }, { 1715, 0x5810 }, { 1719, 0x0249 }, + /* 0x5900 */ + { 1723, 0xa094 }, { 1728, 0x9670 }, { 1735, 0xeeb0 }, { 1744, 0x1792 }, + { 1751, 0xcb96 }, { 1760, 0x05f2 }, { 1767, 0x0025 }, { 1770, 0x2358 }, + { 1776, 0x25de }, { 1785, 0x42cc }, { 1791, 0xcf38 }, { 1800, 0x4a04 }, + { 1804, 0x0c40 }, { 1807, 0x359f }, { 1817, 0x1128 }, { 1821, 0x8a00 }, + /* 0x5a00 */ + { 1824, 0x13fa }, { 1833, 0x910a }, { 1838, 0x0229 }, { 1842, 0x1056 }, + { 1847, 0x0641 }, { 1851, 0x0420 }, { 1853, 0x0484 }, { 1856, 0x84f0 }, + { 1862, 0x0000 }, { 1862, 0x0c04 }, { 1865, 0x0400 }, { 1866, 0x412c }, + { 1871, 0x1206 }, { 1875, 0x1154 }, { 1880, 0x0a4b }, { 1886, 0x0002 }, + /* 0x5b00 */ + { 1887, 0x0200 }, { 1888, 0x00c0 }, { 1890, 0x0000 }, { 1890, 0x0094 }, + { 1893, 0x0001 }, { 1894, 0xbfbb }, { 1907, 0x167c }, { 1915, 0x242b }, + { 1921, 0x9bbb }, { 1932, 0x7fa8 }, { 1942, 0x0c7f }, { 1951, 0xe379 }, + { 1961, 0x10f4 }, { 1967, 0xe00d }, { 1973, 0x4132 }, { 1978, 0x9f01 }, + /* 0x5c00 */ + { 1985, 0x8652 }, { 1991, 0x3572 }, { 1999, 0x10b4 }, { 2004, 0xff12 }, + { 2014, 0xcf27 }, { 2024, 0x4223 }, { 2029, 0xc06b }, { 2036, 0x8602 }, + { 2040, 0x3106 }, { 2045, 0x1fd3 }, { 2055, 0x3a0c }, { 2061, 0xa1aa }, + { 2068, 0x0812 }, { 2071, 0x0204 }, { 2073, 0x2572 }, { 2080, 0x0801 }, + /* 0x5d00 */ + { 2082, 0x40cc }, { 2087, 0x4850 }, { 2091, 0x62d0 }, { 2097, 0x6010 }, + { 2100, 0x1c80 }, { 2104, 0x2900 }, { 2107, 0x9a00 }, { 2111, 0x0010 }, + { 2112, 0x0004 }, { 2113, 0x2200 }, { 2115, 0x0000 }, { 2115, 0x0080 }, + { 2116, 0x2020 }, { 2118, 0x6800 }, { 2121, 0xcbe6 }, { 2131, 0x609e }, + /* 0x5e00 */ + { 2138, 0x916e }, { 2146, 0x3f73 }, { 2157, 0x60c0 }, { 2161, 0x3982 }, + { 2167, 0x1034 }, { 2171, 0x4830 }, { 2175, 0x0006 }, { 2177, 0xbd5c }, + { 2187, 0x8cd1 }, { 2194, 0xd6fb }, { 2206, 0x20e1 }, { 2211, 0x43e8 }, + { 2218, 0x0600 }, { 2220, 0x084e }, { 2225, 0x0500 }, { 2227, 0xc4d0 }, + /* 0x5f00 */ + { 2233, 0x8d1f }, { 2242, 0x89aa }, { 2249, 0xa6e1 }, { 2257, 0x1602 }, + { 2261, 0x0001 }, { 2262, 0x21ed }, { 2270, 0x3656 }, { 2278, 0x1a8b }, + { 2285, 0x1fb7 }, { 2296, 0x13a5 }, { 2303, 0x6502 }, { 2308, 0x30a0 }, + { 2312, 0xb278 }, { 2320, 0x23c7 }, { 2328, 0x6c93 }, { 2336, 0xe922 }, + /* 0x6000 */ + { 2343, 0xe47f }, { 2354, 0x3a74 }, { 2362, 0x8fe3 }, { 2372, 0x9820 }, + { 2376, 0x280e }, { 2381, 0x2625 }, { 2387, 0xbf9c }, { 2398, 0xbf49 }, + { 2408, 0x3218 }, { 2413, 0xac54 }, { 2420, 0xb949 }, { 2428, 0x1916 }, + { 2434, 0x0c60 }, { 2438, 0xb522 }, { 2445, 0xfbc1 }, { 2455, 0x0659 }, + /* 0x6100 */ + { 2461, 0xe343 }, { 2469, 0x8420 }, { 2472, 0x08d9 }, { 2478, 0x8000 }, + { 2479, 0x5500 }, { 2483, 0x2022 }, { 2486, 0x0184 }, { 2489, 0x00a1 }, + { 2492, 0x4800 }, { 2494, 0x2010 }, { 2496, 0x1380 }, { 2500, 0x4080 }, + { 2502, 0x0d04 }, { 2506, 0x0016 }, { 2509, 0x0040 }, { 2510, 0x8020 }, + /* 0x6200 */ + { 2512, 0xfd40 }, { 2520, 0x8de7 }, { 2530, 0x5436 }, { 2537, 0xe098 }, + { 2543, 0x7b8b }, { 2553, 0x091e }, { 2559, 0xfec8 }, { 2569, 0xd249 }, + { 2576, 0x0611 }, { 2580, 0x8dee }, { 2590, 0x1937 }, { 2598, 0xba22 }, + { 2605, 0x77f4 }, { 2616, 0x9fdd }, { 2628, 0xf3ec }, { 2639, 0xf0da }, + /* 0x6300 */ + { 2648, 0x4386 }, { 2654, 0xec42 }, { 2661, 0x8d3f }, { 2671, 0x2604 }, + { 2675, 0xfa6c }, { 2685, 0xc021 }, { 2689, 0x628e }, { 2696, 0x0cc2 }, + { 2701, 0xd785 }, { 2710, 0x0145 }, { 2714, 0x77ad }, { 2725, 0x5599 }, + { 2733, 0xe250 }, { 2739, 0x4045 }, { 2743, 0x260b }, { 2749, 0xa154 }, + /* 0x6400 */ + { 2755, 0x9827 }, { 2762, 0x5819 }, { 2768, 0x3443 }, { 2774, 0xa410 }, + { 2778, 0x05f2 }, { 2785, 0x4114 }, { 2789, 0x2280 }, { 2792, 0x0700 }, + { 2795, 0x00b4 }, { 2799, 0x4266 }, { 2805, 0x7210 }, { 2810, 0x15a1 }, + { 2816, 0x6025 }, { 2821, 0x4185 }, { 2826, 0x0054 }, { 2829, 0x0000 }, + /* 0x6500 */ + { 2829, 0x0201 }, { 2831, 0x0104 }, { 2833, 0xc820 }, { 2837, 0xcb70 }, + { 2845, 0x9320 }, { 2850, 0x6a62 }, { 2857, 0x184c }, { 2862, 0x0095 }, + { 2866, 0x1880 }, { 2869, 0x9a8b }, { 2877, 0xaab2 }, { 2885, 0x3201 }, + { 2889, 0xd87a }, { 2898, 0x00c4 }, { 2901, 0xf3e5 }, { 2912, 0x04c3 }, + /* 0x6600 */ + { 2917, 0xd44d }, { 2925, 0xa238 }, { 2931, 0xa1a1 }, { 2937, 0x5072 }, + { 2943, 0x980a }, { 2948, 0x84fc }, { 2956, 0xc152 }, { 2962, 0x44d1 }, + { 2968, 0x1094 }, { 2972, 0x20c2 }, { 2976, 0x4180 }, { 2979, 0x4210 }, + { 2982, 0x0000 }, { 2982, 0x3a00 }, { 2986, 0x0240 }, { 2988, 0xd29d }, + /* 0x6700 */ + { 2997, 0x2f01 }, { 3003, 0xa8b1 }, { 3010, 0xbd40 }, { 3017, 0x2432 }, + { 3022, 0xd34d }, { 3031, 0xd04b }, { 3038, 0xa723 }, { 3046, 0xd0ad }, + { 3054, 0x0a92 }, { 3059, 0x75a1 }, { 3067, 0xadac }, { 3076, 0x01e9 }, + { 3082, 0x801a }, { 3086, 0x771f }, { 3097, 0x9225 }, { 3103, 0xa01b }, + /* 0x6800 */ + { 3109, 0xdfa1 }, { 3119, 0x20ca }, { 3124, 0x0602 }, { 3127, 0x738c }, + { 3135, 0x577f }, { 3147, 0x003b }, { 3152, 0x0bff }, { 3163, 0x00d0 }, + { 3166, 0x806a }, { 3171, 0x0088 }, { 3173, 0xa1c4 }, { 3179, 0x0029 }, + { 3182, 0x2a05 }, { 3187, 0x0524 }, { 3191, 0x4009 }, { 3194, 0x1623 }, + /* 0x6900 */ + { 3200, 0x6822 }, { 3205, 0x8005 }, { 3208, 0x2011 }, { 3211, 0xa211 }, + { 3216, 0x0004 }, { 3217, 0x6490 }, { 3222, 0x4849 }, { 3227, 0x1382 }, + { 3232, 0x23d5 }, { 3240, 0x1930 }, { 3245, 0x2980 }, { 3249, 0x0892 }, + { 3253, 0x5402 }, { 3257, 0x8811 }, { 3261, 0x2001 }, { 3263, 0xa004 }, + /* 0x6a00 */ + { 3266, 0x0400 }, { 3267, 0x8180 }, { 3270, 0x8502 }, { 3274, 0x6022 }, + { 3278, 0x0090 }, { 3280, 0x0b01 }, { 3284, 0x0022 }, { 3286, 0x1202 }, + { 3289, 0x4011 }, { 3292, 0x0083 }, { 3295, 0x1a01 }, { 3299, 0x0000 }, + { 3299, 0x0000 }, { 3299, 0x0000 }, { 3299, 0x0000 }, { 3299, 0x0000 }, + /* 0x6b00 */ + { 3299, 0x0000 }, { 3299, 0x0000 }, { 3299, 0x009f }, { 3305, 0x4684 }, + { 3310, 0x12c8 }, { 3315, 0x0200 }, { 3316, 0x04fc }, { 3323, 0x1a00 }, + { 3326, 0x2ede }, { 3336, 0x0c4c }, { 3341, 0x0402 }, { 3343, 0x80b8 }, + { 3348, 0xa826 }, { 3354, 0x0afc }, { 3362, 0x8c02 }, { 3366, 0x2228 }, + /* 0x6c00 */ + { 3370, 0xa0e0 }, { 3375, 0x8f7b }, { 3386, 0xc7d6 }, { 3396, 0x2135 }, + { 3402, 0x06c7 }, { 3409, 0xf8b1 }, { 3418, 0x0713 }, { 3424, 0x6255 }, + { 3431, 0x936e }, { 3440, 0x8a19 }, { 3446, 0x6efa }, { 3457, 0xfb0e }, + { 3467, 0x1630 }, { 3472, 0x48f9 }, { 3480, 0xcd2f }, { 3490, 0x7deb }, + /* 0x6d00 */ + { 3502, 0x5892 }, { 3508, 0x4e84 }, { 3514, 0x4ca0 }, { 3519, 0x7a2e }, + { 3528, 0xedea }, { 3539, 0x561e }, { 3547, 0xc649 }, { 3554, 0x1190 }, + { 3558, 0x5324 }, { 3564, 0xe83a }, { 3572, 0xcfdb }, { 3584, 0x8124 }, + { 3588, 0x18f1 }, { 3595, 0x6342 }, { 3601, 0x5853 }, { 3608, 0x1a8a }, + /* 0x6e00 */ + { 3614, 0x7420 }, { 3619, 0x24d3 }, { 3626, 0xaa3b }, { 3635, 0x0514 }, + { 3639, 0x6018 }, { 3643, 0x8958 }, { 3649, 0x4800 }, { 3651, 0xc000 }, + { 3653, 0x8268 }, { 3658, 0x9101 }, { 3662, 0x84a4 }, { 3667, 0x2cd6 }, + { 3675, 0x8886 }, { 3680, 0xc4ba }, { 3688, 0x0377 }, { 3696, 0x0210 }, + /* 0x6f00 */ + { 3698, 0x8244 }, { 3702, 0x0038 }, { 3705, 0xae11 }, { 3712, 0x404a }, + { 3716, 0x28c0 }, { 3720, 0x5100 }, { 3723, 0x6044 }, { 3727, 0x1514 }, + { 3732, 0x7310 }, { 3738, 0x1000 }, { 3739, 0x0082 }, { 3741, 0x0248 }, + { 3744, 0x0205 }, { 3747, 0x4006 }, { 3750, 0xc003 }, { 3754, 0x0000 }, + /* 0x7000 */ + { 3754, 0x0000 }, { 3754, 0x0c02 }, { 3757, 0x0008 }, { 3758, 0x0220 }, + { 3760, 0x9000 }, { 3762, 0x4000 }, { 3763, 0xb800 }, { 3767, 0xd161 }, + { 3774, 0x4621 }, { 3779, 0x3274 }, { 3786, 0xf800 }, { 3791, 0x3b8a }, + { 3799, 0x050f }, { 3805, 0x8b00 }, { 3809, 0xbbd0 }, { 3818, 0x2280 }, + /* 0x7100 */ + { 3821, 0x0600 }, { 3823, 0x0769 }, { 3830, 0x8040 }, { 3832, 0x0043 }, + { 3835, 0x5420 }, { 3839, 0x5000 }, { 3841, 0x41d0 }, { 3846, 0x250c }, + { 3851, 0x8410 }, { 3854, 0x8310 }, { 3858, 0x1101 }, { 3861, 0x0228 }, + { 3864, 0x4008 }, { 3866, 0x0030 }, { 3868, 0x40a1 }, { 3872, 0x0200 }, + /* 0x7200 */ + { 3873, 0x0040 }, { 3874, 0x2000 }, { 3875, 0x1500 }, { 3878, 0xabe3 }, + { 3888, 0x3180 }, { 3892, 0xaa44 }, { 3898, 0xc2c6 }, { 3905, 0xc624 }, + { 3911, 0xac13 }, { 3918, 0x8004 }, { 3920, 0xb000 }, { 3923, 0x03d1 }, + { 3929, 0x611e }, { 3936, 0x4285 }, { 3941, 0xf303 }, { 3949, 0x1d9f }, + /* 0x7300 */ + { 3959, 0x440a }, { 3963, 0x78e8 }, { 3971, 0x5e26 }, { 3979, 0xc392 }, + { 3986, 0x2000 }, { 3987, 0x0085 }, { 3990, 0xb001 }, { 3994, 0x4000 }, + { 3995, 0x4a90 }, { 4000, 0x8842 }, { 4004, 0xca04 }, { 4009, 0x0c8d }, + { 4015, 0xa705 }, { 4022, 0x4203 }, { 4026, 0x22a1 }, { 4031, 0x0004 }, + /* 0x7400 */ + { 4032, 0x8668 }, { 4038, 0x0c01 }, { 4041, 0x5564 }, { 4048, 0x1079 }, + { 4054, 0x0002 }, { 4055, 0xdea0 }, { 4063, 0x2000 }, { 4064, 0x40c1 }, + { 4068, 0x488b }, { 4074, 0x5001 }, { 4077, 0x0380 }, { 4080, 0x0400 }, + { 4081, 0x0000 }, { 4081, 0x5004 }, { 4084, 0xc05d }, { 4091, 0x80d0 }, + /* 0x7500 */ + { 4095, 0xa010 }, { 4098, 0x970a }, { 4105, 0xbb20 }, { 4112, 0x4daf }, + { 4122, 0xd921 }, { 4129, 0x1e10 }, { 4134, 0x0460 }, { 4137, 0x8314 }, + { 4142, 0x8848 }, { 4146, 0xa6d6 }, { 4155, 0xd83b }, { 4164, 0x733f }, + { 4175, 0x27bc }, { 4184, 0x4974 }, { 4191, 0x0ddc }, { 4199, 0x9213 }, + /* 0x7600 */ + { 4205, 0x142b }, { 4211, 0x8ba1 }, { 4218, 0x2e75 }, { 4227, 0xd139 }, + { 4235, 0x3009 }, { 4239, 0x5050 }, { 4243, 0x8808 }, { 4246, 0x6900 }, + { 4250, 0x49d4 }, { 4257, 0x024a }, { 4261, 0x4010 }, { 4263, 0x8016 }, + { 4267, 0xe564 }, { 4275, 0x89d7 }, { 4284, 0xc020 }, { 4287, 0x5316 }, + /* 0x7700 */ + { 4294, 0x2b92 }, { 4301, 0x8600 }, { 4304, 0xa345 }, { 4311, 0x15e0 }, + { 4317, 0x008b }, { 4321, 0x0c03 }, { 4325, 0x196e }, { 4333, 0xe200 }, + { 4337, 0x7031 }, { 4343, 0x8006 }, { 4346, 0x16a5 }, { 4353, 0xa829 }, + { 4359, 0x2000 }, { 4360, 0x1880 }, { 4363, 0x7aac }, { 4372, 0xe148 }, + /* 0x7800 */ + { 4378, 0x3207 }, { 4384, 0xb5d6 }, { 4394, 0x32e8 }, { 4401, 0x5f91 }, + { 4410, 0x50a1 }, { 4415, 0x20e5 }, { 4421, 0x7c00 }, { 4426, 0x1080 }, + { 4428, 0x7280 }, { 4433, 0x9d8a }, { 4441, 0x00aa }, { 4445, 0x421f }, + { 4452, 0x0e22 }, { 4457, 0x0231 }, { 4461, 0x1100 }, { 4463, 0x0494 }, + /* 0x7900 */ + { 4467, 0x0022 }, { 4469, 0x4008 }, { 4471, 0x0010 }, { 4472, 0x5c10 }, + { 4477, 0x0343 }, { 4482, 0xfcc8 }, { 4491, 0xa1a5 }, { 4498, 0x0580 }, + { 4501, 0x8433 }, { 4507, 0x0400 }, { 4508, 0x0080 }, { 4509, 0x6e08 }, + { 4515, 0x2a4b }, { 4522, 0x8126 }, { 4527, 0xaad8 }, { 4535, 0x2901 }, + /* 0x7a00 */ + { 4539, 0x684d }, { 4546, 0x4490 }, { 4550, 0x0009 }, { 4552, 0xba88 }, + { 4559, 0x0040 }, { 4560, 0x0082 }, { 4562, 0x0000 }, { 4562, 0x87d1 }, + { 4570, 0x215b }, { 4577, 0xb1e6 }, { 4586, 0x3161 }, { 4592, 0x8008 }, + { 4594, 0x0800 }, { 4595, 0xc240 }, { 4599, 0xa069 }, { 4605, 0xa600 }, + /* 0x7b00 */ + { 4609, 0x8d58 }, { 4616, 0x4a32 }, { 4622, 0x5d71 }, { 4631, 0x550a }, + { 4637, 0x9aa0 }, { 4643, 0x2d57 }, { 4652, 0x4005 }, { 4655, 0x4aa6 }, + { 4662, 0x2021 }, { 4665, 0x30b1 }, { 4671, 0x3fc6 }, { 4681, 0x0112 }, + { 4684, 0x10c2 }, { 4688, 0x260a }, { 4693, 0x4462 }, { 4698, 0x5082 }, + /* 0x7c00 */ + { 4702, 0x9880 }, { 4706, 0x8040 }, { 4708, 0x04c0 }, { 4711, 0x8100 }, + { 4713, 0x2003 }, { 4716, 0x0000 }, { 4716, 0x0000 }, { 4716, 0x3818 }, + { 4721, 0x0200 }, { 4722, 0xf1a6 }, { 4731, 0x4434 }, { 4736, 0x720e }, + { 4743, 0x35a2 }, { 4750, 0x92e0 }, { 4756, 0x8101 }, { 4759, 0x0900 }, + /* 0x7d00 */ + { 4761, 0x0400 }, { 4762, 0x0000 }, { 4762, 0x8885 }, { 4767, 0x0000 }, + { 4767, 0x0000 }, { 4767, 0x0000 }, { 4767, 0x4000 }, { 4768, 0x0080 }, + { 4769, 0x0000 }, { 4769, 0x0000 }, { 4769, 0x4040 }, { 4771, 0x0000 }, + { 4771, 0x0000 }, { 4771, 0x0000 }, { 4771, 0x0000 }, { 4771, 0x0000 }, + /* 0x7e00 */ + { 4771, 0x0000 }, { 4771, 0x0000 }, { 4771, 0x0000 }, { 4771, 0x0800 }, + { 4772, 0x0082 }, { 4774, 0x0000 }, { 4774, 0x0000 }, { 4774, 0x0000 }, + { 4774, 0x0004 }, { 4775, 0x8800 }, { 4777, 0xbfff }, { 4792, 0xe7ef }, + { 4805, 0xffff }, { 4821, 0xffbf }, { 4836, 0xefef }, { 4850, 0xfdff }, + /* 0x7f00 */ + { 4865, 0xfbff }, { 4880, 0xbffe }, { 4894, 0xffff }, { 4910, 0x057f }, + { 4919, 0x0034 }, { 4922, 0x85b3 }, { 4930, 0x4706 }, { 4936, 0x4216 }, + { 4941, 0x5402 }, { 4945, 0xe410 }, { 4950, 0x8092 }, { 4954, 0xb305 }, + { 4961, 0x5422 }, { 4966, 0x8130 }, { 4970, 0x4263 }, { 4976, 0x180b }, + /* 0x8000 */ + { 4981, 0x387b }, { 4990, 0x13f5 }, { 4999, 0x07e5 }, { 5007, 0xa9ea }, + { 5016, 0x3c4c }, { 5023, 0x0514 }, { 5027, 0x0600 }, { 5029, 0x8002 }, + { 5031, 0x1ad9 }, { 5039, 0xbd48 }, { 5047, 0xee37 }, { 5058, 0xf496 }, + { 5067, 0x705f }, { 5076, 0x7ec0 }, { 5084, 0xbfb2 }, { 5095, 0x355f }, + /* 0x8100 */ + { 5105, 0xe644 }, { 5112, 0x455f }, { 5121, 0x9000 }, { 5123, 0x4146 }, + { 5128, 0x1d40 }, { 5133, 0x063b }, { 5140, 0x62a1 }, { 5146, 0xfe13 }, + { 5156, 0x8505 }, { 5161, 0x3902 }, { 5166, 0x0548 }, { 5170, 0x0c08 }, + { 5173, 0x144f }, { 5180, 0x0000 }, { 5180, 0x3488 }, { 5185, 0x5818 }, + /* 0x8200 */ + { 5190, 0x3077 }, { 5198, 0xd815 }, { 5205, 0xbd0e }, { 5214, 0x4bfb }, + { 5225, 0x8a90 }, { 5230, 0x8500 }, { 5233, 0xc100 }, { 5236, 0xe61d }, + { 5245, 0xed14 }, { 5253, 0xb386 }, { 5261, 0xff72 }, { 5273, 0x639b }, + { 5282, 0xfd92 }, { 5292, 0xd9be }, { 5303, 0x887b }, { 5311, 0x0a92 }, + /* 0x8300 */ + { 5316, 0xd3fe }, { 5328, 0x1cb2 }, { 5335, 0xb980 }, { 5341, 0x177a }, + { 5350, 0x82c9 }, { 5356, 0xdc17 }, { 5365, 0xfffb }, { 5380, 0x3980 }, + { 5385, 0x4260 }, { 5389, 0x590c }, { 5395, 0x0f01 }, { 5400, 0x37df }, + { 5412, 0x94a3 }, { 5419, 0xb150 }, { 5425, 0x0623 }, { 5430, 0x2307 }, + /* 0x8400 */ + { 5436, 0xf85a }, { 5445, 0x3102 }, { 5449, 0x01f0 }, { 5454, 0x3102 }, + { 5458, 0x0040 }, { 5459, 0x1e82 }, { 5465, 0x3a0a }, { 5471, 0x056a }, + { 5477, 0x5b84 }, { 5484, 0x1280 }, { 5487, 0x8002 }, { 5489, 0xa714 }, + { 5496, 0x2612 }, { 5501, 0xa04b }, { 5507, 0x1069 }, { 5512, 0x9001 }, + /* 0x8500 */ + { 5515, 0x1000 }, { 5516, 0x848a }, { 5521, 0x1802 }, { 5524, 0x3f80 }, + { 5531, 0x0708 }, { 5535, 0x4240 }, { 5538, 0x0110 }, { 5540, 0x4e14 }, + { 5546, 0x80b0 }, { 5550, 0x1800 }, { 5552, 0xc510 }, { 5557, 0x0281 }, + { 5560, 0x8202 }, { 5563, 0x1029 }, { 5567, 0x0210 }, { 5569, 0x8800 }, + /* 0x8600 */ + { 5571, 0x0020 }, { 5572, 0x0042 }, { 5574, 0x0280 }, { 5576, 0x1100 }, + { 5578, 0xe000 }, { 5581, 0x4413 }, { 5586, 0x5804 }, { 5590, 0xfe02 }, + { 5598, 0x3c07 }, { 5605, 0x3028 }, { 5609, 0x9798 }, { 5617, 0x0473 }, + { 5623, 0xced1 }, { 5632, 0xcb13 }, { 5640, 0x6210 }, { 5644, 0x431f }, + /* 0x8700 */ + { 5652, 0x278d }, { 5660, 0x55ac }, { 5668, 0x422e }, { 5674, 0xc892 }, + { 5680, 0x5380 }, { 5685, 0x0288 }, { 5688, 0x4039 }, { 5693, 0x7851 }, + { 5700, 0x292c }, { 5706, 0x8088 }, { 5709, 0xb900 }, { 5714, 0x2428 }, + { 5718, 0x0c41 }, { 5722, 0x080e }, { 5726, 0x4421 }, { 5730, 0x4200 }, + /* 0x8800 */ + { 5732, 0x0408 }, { 5734, 0x0868 }, { 5738, 0x0006 }, { 5740, 0x1204 }, + { 5743, 0x3031 }, { 5748, 0x0290 }, { 5751, 0x5b3e }, { 5761, 0xe085 }, + { 5767, 0x2936 }, { 5774, 0x1044 }, { 5777, 0x2814 }, { 5781, 0x1082 }, + { 5784, 0x4266 }, { 5790, 0x8334 }, { 5796, 0x013c }, { 5801, 0x531b }, + /* 0x8900 */ + { 5809, 0x0404 }, { 5811, 0x0e0d }, { 5817, 0x0c22 }, { 5821, 0x0051 }, + { 5824, 0x0012 }, { 5826, 0xc000 }, { 5828, 0x0040 }, { 5829, 0x8800 }, + { 5831, 0x004a }, { 5834, 0x0000 }, { 5834, 0x0000 }, { 5834, 0x0000 }, + { 5834, 0xdff6 }, { 5847, 0x5447 }, { 5854, 0x8868 }, { 5859, 0x0008 }, + /* 0x8a00 */ + { 5860, 0x0081 }, { 5862, 0x0000 }, { 5862, 0x0000 }, { 5862, 0x4000 }, + { 5863, 0x0100 }, { 5864, 0x0000 }, { 5864, 0x0000 }, { 5864, 0x0200 }, + { 5865, 0x0600 }, { 5867, 0x0008 }, { 5868, 0x0000 }, { 5868, 0x0000 }, + { 5868, 0x0000 }, { 5868, 0x0000 }, { 5868, 0x0000 }, { 5868, 0x0000 }, + /* 0x8b00 */ + { 5868, 0x0080 }, { 5869, 0x0000 }, { 5869, 0x0040 }, { 5870, 0x0000 }, + { 5870, 0x0000 }, { 5870, 0x0000 }, { 5870, 0x1040 }, { 5872, 0x0000 }, + { 5872, 0x0000 }, { 5872, 0x0000 }, { 5872, 0xefff }, { 5887, 0xf7fd }, + { 5901, 0xff7f }, { 5916, 0xfffe }, { 5931, 0xfbff }, { 5946, 0xffff }, + /* 0x8c00 */ + { 5962, 0xfdff }, { 5977, 0xbfff }, { 5992, 0xffff }, { 6008, 0x00ff }, + { 6016, 0x12c2 }, { 6021, 0x0420 }, { 6023, 0x0c06 }, { 6027, 0x0708 }, + { 6031, 0x1624 }, { 6036, 0x0110 }, { 6038, 0x0000 }, { 6038, 0x0000 }, + { 6038, 0x0000 }, { 6038, 0x0000 }, { 6038, 0x0000 }, { 6038, 0x0000 }, + /* 0x8d00 */ + { 6038, 0x0000 }, { 6038, 0xe000 }, { 6041, 0xfffe }, { 6056, 0xffff }, + { 6072, 0xffff }, { 6088, 0x7f79 }, { 6100, 0x28df }, { 6109, 0x00f9 }, + { 6115, 0x0c32 }, { 6120, 0x8012 }, { 6123, 0x0008 }, { 6124, 0xd53a }, + { 6133, 0xd858 }, { 6140, 0xecc2 }, { 6148, 0x9d18 }, { 6155, 0x2fa8 }, + /* 0x8e00 */ + { 6163, 0x9620 }, { 6168, 0xe010 }, { 6172, 0xd60c }, { 6179, 0x2622 }, + { 6184, 0x0f97 }, { 6193, 0x0206 }, { 6196, 0xb240 }, { 6201, 0x9055 }, + { 6207, 0x80a2 }, { 6211, 0x5011 }, { 6215, 0x9800 }, { 6218, 0x0404 }, + { 6220, 0x4000 }, { 6221, 0x0000 }, { 6221, 0x0000 }, { 6221, 0x0000 }, + /* 0x8f00 */ + { 6221, 0x0000 }, { 6221, 0x0000 }, { 6221, 0x0000 }, { 6221, 0x0000 }, + { 6221, 0x0000 }, { 6221, 0x0000 }, { 6221, 0xfbc0 }, { 6230, 0xffff }, + { 6246, 0xeffe }, { 6260, 0xdffb }, { 6274, 0x0b08 }, { 6278, 0x6243 }, + { 6284, 0x41b6 }, { 6291, 0xfb3b }, { 6303, 0x6f74 }, { 6313, 0x2389 }, + /* 0x9000 */ + { 6319, 0xae7f }, { 6331, 0xecd7 }, { 6342, 0xe047 }, { 6349, 0x5960 }, + { 6355, 0xa096 }, { 6361, 0x098f }, { 6368, 0x612c }, { 6374, 0xa030 }, + { 6378, 0x090d }, { 6383, 0x2aaa }, { 6390, 0xd44e }, { 6398, 0x4f7b }, + { 6409, 0xc4b2 }, { 6416, 0x388b }, { 6423, 0xa9c6 }, { 6431, 0x6110 }, + /* 0x9100 */ + { 6435, 0x0014 }, { 6437, 0x4200 }, { 6439, 0x800c }, { 6442, 0x0202 }, + { 6444, 0xfe48 }, { 6453, 0x6485 }, { 6459, 0xd63e }, { 6469, 0xe3f7 }, + { 6481, 0x3aa0 }, { 6487, 0x0c07 }, { 6492, 0xe40c }, { 6498, 0x0430 }, + { 6501, 0xf680 }, { 6508, 0x1002 }, { 6510, 0x0000 }, { 6510, 0x0000 }, + /* 0x9200 */ + { 6510, 0x0000 }, { 6510, 0x0000 }, { 6510, 0x0000 }, { 6510, 0x0000 }, + { 6510, 0x0000 }, { 6510, 0x0000 }, { 6510, 0x0000 }, { 6510, 0x0010 }, + { 6511, 0x4000 }, { 6512, 0x0000 }, { 6512, 0x4000 }, { 6513, 0x0000 }, + { 6513, 0x0100 }, { 6514, 0x0000 }, { 6514, 0x0000 }, { 6514, 0x0000 }, + /* 0x9300 */ + { 6514, 0x0000 }, { 6514, 0x0000 }, { 6514, 0x0000 }, { 6514, 0x4000 }, + { 6515, 0x0000 }, { 6515, 0x0000 }, { 6515, 0x0400 }, { 6516, 0x0000 }, + { 6516, 0x8000 }, { 6517, 0x0000 }, { 6517, 0x0000 }, { 6517, 0x0000 }, + { 6517, 0x0400 }, { 6518, 0x0040 }, { 6519, 0x0000 }, { 6519, 0x0000 }, + /* 0x9400 */ + { 6519, 0x0000 }, { 6519, 0x0000 }, { 6519, 0x0000 }, { 6519, 0x4000 }, + { 6520, 0x0000 }, { 6520, 0x0000 }, { 6520, 0x0800 }, { 6521, 0x0000 }, + { 6521, 0xffe0 }, { 6532, 0xfebd }, { 6545, 0xffff }, { 6561, 0xffff }, + { 6577, 0x7f7f }, { 6591, 0xfbe7 }, { 6604, 0xffbf }, { 6619, 0xf7ff }, + /* 0x9500 */ + { 6634, 0xffff }, { 6650, 0xefff }, { 6665, 0xff7e }, { 6679, 0xdff7 }, + { 6693, 0xf6f7 }, { 6706, 0xfbdf }, { 6720, 0xbffe }, { 6734, 0x804f }, + { 6740, 0x0000 }, { 6740, 0x0000 }, { 6740, 0x0000 }, { 6740, 0x0000 }, + { 6740, 0x0000 }, { 6740, 0x0000 }, { 6740, 0xef00 }, { 6747, 0x7fff }, + /* 0x9600 */ + { 6762, 0xff7f }, { 6777, 0xb6f7 }, { 6789, 0x4406 }, { 6793, 0xb87e }, + { 6803, 0x3bf5 }, { 6814, 0x8831 }, { 6819, 0x1796 }, { 6827, 0x00f4 }, + { 6832, 0xa960 }, { 6838, 0x1391 }, { 6844, 0x0080 }, { 6845, 0x7249 }, + { 6852, 0xf2f3 }, { 6863, 0x0024 }, { 6865, 0x8701 }, { 6870, 0x42c8 }, + /* 0x9700 */ + { 6875, 0xe3d3 }, { 6885, 0x5048 }, { 6889, 0x2400 }, { 6891, 0x4305 }, + { 6896, 0x0000 }, { 6896, 0x4a4c }, { 6902, 0x0227 }, { 6907, 0x1058 }, + { 6911, 0x2820 }, { 6914, 0x0116 }, { 6918, 0xa809 }, { 6923, 0x0014 }, + { 6925, 0x0000 }, { 6925, 0x0000 }, { 6925, 0x3ec0 }, { 6932, 0x0068 }, + /* 0x9800 */ + { 6935, 0x0000 }, { 6935, 0x0000 }, { 6935, 0x0000 }, { 6935, 0x0000 }, + { 6935, 0x0000 }, { 6935, 0x0000 }, { 6935, 0x0000 }, { 6935, 0xffe0 }, + { 6946, 0xb7ff }, { 6960, 0xfddb }, { 6973, 0x00f7 }, { 6980, 0x0000 }, + { 6980, 0x4000 }, { 6981, 0xc72e }, { 6990, 0x0180 }, { 6992, 0x0000 }, + /* 0x9900 */ + { 6992, 0x2000 }, { 6993, 0x0001 }, { 6994, 0x4000 }, { 6995, 0x0000 }, + { 6995, 0x0000 }, { 6995, 0x0030 }, { 6997, 0xffa8 }, { 7008, 0xb4f7 }, + { 7019, 0xadf3 }, { 7030, 0x03ff }, { 7040, 0x0120 }, { 7042, 0x0000 }, + { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0x0000 }, + /* 0x9a00 */ + { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0x0000 }, + { 7042, 0x0000 }, { 7042, 0x0000 }, { 7042, 0xf000 }, { 7046, 0xfffb }, + { 7061, 0x9df7 }, { 7073, 0xfdcf }, { 7086, 0x01bf }, { 7094, 0x15c3 }, + { 7101, 0x1827 }, { 7107, 0x810a }, { 7111, 0xa842 }, { 7116, 0x0a00 }, + /* 0x9b00 */ + { 7118, 0x8108 }, { 7121, 0x8008 }, { 7123, 0x8008 }, { 7125, 0x1804 }, + { 7128, 0xa3be }, { 7138, 0x0012 }, { 7140, 0x0000 }, { 7140, 0x0000 }, + { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, + { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, + /* 0x9c00 */ + { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, + { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x0000 }, { 7140, 0x9000 }, + { 7142, 0x69e6 }, { 7151, 0xdc37 }, { 7161, 0x6bff }, { 7174, 0x3dff }, + { 7187, 0xfcf8 }, { 7198, 0xf3f9 }, { 7210, 0x0004 }, +}; +static const Summary16 gb2312_uni2indx_page9e[27] = { + /* 0x9e00 */ + { 7211, 0x0000 }, { 7211, 0x8000 }, { 7212, 0xbf6f }, { 7225, 0xe7ee }, + { 7237, 0xdffe }, { 7251, 0x5da2 }, { 7259, 0x3fd8 }, { 7269, 0xc00b }, + { 7274, 0x0984 }, { 7278, 0xa00c }, { 7282, 0x0040 }, { 7283, 0x6910 }, + { 7288, 0xe210 }, { 7293, 0xb912 }, { 7300, 0x86a5 }, { 7307, 0x5a00 }, + /* 0x9f00 */ + { 7311, 0x6800 }, { 7314, 0x0289 }, { 7318, 0x9005 }, { 7322, 0x6a80 }, + { 7327, 0x0010 }, { 7328, 0x0003 }, { 7330, 0x0000 }, { 7330, 0x8000 }, + { 7331, 0x1ff9 }, { 7342, 0x8e00 }, { 7346, 0x0001 }, +}; +static const Summary16 gb2312_uni2indx_pageff[15] = { + /* 0xff00 */ + { 7347, 0xfffe }, { 7362, 0xffff }, { 7378, 0xffff }, { 7394, 0xffff }, + { 7410, 0xffff }, { 7426, 0x7fff }, { 7441, 0x0000 }, { 7441, 0x0000 }, + { 7441, 0x0000 }, { 7441, 0x0000 }, { 7441, 0x0000 }, { 7441, 0x0000 }, + { 7441, 0x0000 }, { 7441, 0x0000 }, { 7441, 0x002b }, +}; + +static int +gb2312_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc >= 0x0000 && wc < 0x0460) + summary = &gb2312_uni2indx_page00[(wc>>4)]; + else if (wc >= 0x2000 && wc < 0x2650) + summary = &gb2312_uni2indx_page20[(wc>>4)-0x200]; + else if (wc >= 0x3000 && wc < 0x3230) + summary = &gb2312_uni2indx_page30[(wc>>4)-0x300]; + else if (wc >= 0x4e00 && wc < 0x9cf0) + summary = &gb2312_uni2indx_page4e[(wc>>4)-0x4e0]; + else if (wc >= 0x9e00 && wc < 0x9fb0) + summary = &gb2312_uni2indx_page9e[(wc>>4)-0x9e0]; + else if (wc >= 0xff00 && wc < 0xfff0) + summary = &gb2312_uni2indx_pageff[(wc>>4)-0xff0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = gb2312_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/gbk.h b/libs/libiconv/lib/gbk.h new file mode 100644 index 00000000..b6ff5262 --- /dev/null +++ b/libs/libiconv/lib/gbk.h @@ -0,0 +1,169 @@ +/* + * Copyright (C) 1999-2001, 2005, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * GBK + */ + +/* + * GBK, as described in Ken Lunde's book, is an extension of GB 2312-1980 + * (shifted by adding 0x8080 to the range 0xA1A1..0xFEFE, as used in EUC-CN). + * It adds the following ranges: + * + * (part of GBK/1) 0xA2A1-0xA2AA Small Roman numerals + * GBK/3 0x{81-A0}{40-7E,80-FE} 6080 new characters, all in Unicode + * GBK/4 0x{AA-FE}{40-7E,80-A0} 8160 new characters, 8080 in Unicode + * GBK/5 0x{A8-A9}{40-7E,80-A0} 166 new characters, 153 in Unicode + * + * Furthermore, all four tables I have looked at + * - the CP936 table by Microsoft, found on ftp.unicode.org in 1999, + * - the GBK table by Sun, investigated on a Solaris 2.7 machine, + * - the GBK tables by CWEX, found in the Big5+ package, + * - the GB18030 standard (second printing), + * agree in the following extensions. (Ken Lunde must have overlooked these + * differences between GB2312 and GBK. Also, the CWEX tables have additional + * differences.) + * + * 1. Some characters in the GB2312 range are defined differently: + * + * code GB2312 GBK + * 0xA1A4 0x30FB # KATAKANA MIDDLE DOT 0x00B7 # MIDDLE DOT + * 0xA1AA 0x2015 # HORIZONTAL BAR 0x2014 # EM DASH + * + * 2. 19 characters added in the range 0xA6E0-0xA6F5. + * + * 3. 4 characters added in the range 0xA8BB-0xA8C0. + * + * CP936 as of 1999 was identical to GBK. However, since 1999, Microsoft has + * added new mappings to CP936... + */ + +#include "gbkext1.h" +#include "gbkext2.h" +#include "gbkext_inv.h" +#include "cp936ext.h" + +static int +gbk_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + + if (c >= 0x81 && c < 0xff) { + if (n < 2) + return RET_TOOFEW(0); + if (c >= 0xa1 && c <= 0xf7) { + unsigned char c2 = s[1]; + if (c == 0xa1) { + if (c2 == 0xa4) { + *pwc = 0x00b7; + return 2; + } + if (c2 == 0xaa) { + *pwc = 0x2014; + return 2; + } + } + if (c2 >= 0xa1 && c2 < 0xff) { + unsigned char buf[2]; + int ret; + buf[0] = c-0x80; buf[1] = c2-0x80; + ret = gb2312_mbtowc(conv,pwc,buf,2); + if (ret != RET_ILSEQ) + return ret; + buf[0] = c; buf[1] = c2; + ret = cp936ext_mbtowc(conv,pwc,buf,2); + if (ret != RET_ILSEQ) + return ret; + } + } + if (c >= 0x81 && c <= 0xa0) + return gbkext1_mbtowc(conv,pwc,s,2); + if (c >= 0xa8 && c <= 0xfe) + return gbkext2_mbtowc(conv,pwc,s,2); + if (c == 0xa2) { + unsigned char c2 = s[1]; + if (c2 >= 0xa1 && c2 <= 0xaa) { + *pwc = 0x2170+(c2-0xa1); + return 2; + } + } + } + return RET_ILSEQ; +} + +static int +gbk_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[2]; + int ret; + + if (wc != 0x30fb && wc != 0x2015) { + ret = gb2312_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]+0x80; + r[1] = buf[1]+0x80; + return 2; + } + } + ret = gbkext_inv_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]; + r[1] = buf[1]; + return 2; + } + if (wc >= 0x2170 && wc <= 0x2179) { + if (n < 2) + return RET_TOOSMALL; + r[0] = 0xa2; + r[1] = 0xa1 + (wc-0x2170); + return 2; + } + ret = cp936ext_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]; + r[1] = buf[1]; + return 2; + } + if (wc == 0x00b7) { + if (n < 2) + return RET_TOOSMALL; + r[0] = 0xa1; + r[1] = 0xa4; + return 2; + } + if (wc == 0x2014) { + if (n < 2) + return RET_TOOSMALL; + r[0] = 0xa1; + r[1] = 0xaa; + return 2; + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/gbkext1.h b/libs/libiconv/lib/gbkext1.h new file mode 100644 index 00000000..d244c769 --- /dev/null +++ b/libs/libiconv/lib/gbkext1.h @@ -0,0 +1,853 @@ +/* + * Copyright (C) 1999-2000 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * GBK/3 extensions + */ + +static const unsigned short gbkext1_2uni_page81[6080] = { + /* 0x81 */ + 0x4e02, 0x4e04, 0x4e05, 0x4e06, 0x4e0f, 0x4e12, 0x4e17, 0x4e1f, + 0x4e20, 0x4e21, 0x4e23, 0x4e26, 0x4e29, 0x4e2e, 0x4e2f, 0x4e31, + 0x4e33, 0x4e35, 0x4e37, 0x4e3c, 0x4e40, 0x4e41, 0x4e42, 0x4e44, + 0x4e46, 0x4e4a, 0x4e51, 0x4e55, 0x4e57, 0x4e5a, 0x4e5b, 0x4e62, + 0x4e63, 0x4e64, 0x4e65, 0x4e67, 0x4e68, 0x4e6a, 0x4e6b, 0x4e6c, + 0x4e6d, 0x4e6e, 0x4e6f, 0x4e72, 0x4e74, 0x4e75, 0x4e76, 0x4e77, + 0x4e78, 0x4e79, 0x4e7a, 0x4e7b, 0x4e7c, 0x4e7d, 0x4e7f, 0x4e80, + 0x4e81, 0x4e82, 0x4e83, 0x4e84, 0x4e85, 0x4e87, 0x4e8a, 0x4e90, + 0x4e96, 0x4e97, 0x4e99, 0x4e9c, 0x4e9d, 0x4e9e, 0x4ea3, 0x4eaa, + 0x4eaf, 0x4eb0, 0x4eb1, 0x4eb4, 0x4eb6, 0x4eb7, 0x4eb8, 0x4eb9, + 0x4ebc, 0x4ebd, 0x4ebe, 0x4ec8, 0x4ecc, 0x4ecf, 0x4ed0, 0x4ed2, + 0x4eda, 0x4edb, 0x4edc, 0x4ee0, 0x4ee2, 0x4ee6, 0x4ee7, 0x4ee9, + 0x4eed, 0x4eee, 0x4eef, 0x4ef1, 0x4ef4, 0x4ef8, 0x4ef9, 0x4efa, + 0x4efc, 0x4efe, 0x4f00, 0x4f02, 0x4f03, 0x4f04, 0x4f05, 0x4f06, + 0x4f07, 0x4f08, 0x4f0b, 0x4f0c, 0x4f12, 0x4f13, 0x4f14, 0x4f15, + 0x4f16, 0x4f1c, 0x4f1d, 0x4f21, 0x4f23, 0x4f28, 0x4f29, 0x4f2c, + 0x4f2d, 0x4f2e, 0x4f31, 0x4f33, 0x4f35, 0x4f37, 0x4f39, 0x4f3b, + 0x4f3e, 0x4f3f, 0x4f40, 0x4f41, 0x4f42, 0x4f44, 0x4f45, 0x4f47, + 0x4f48, 0x4f49, 0x4f4a, 0x4f4b, 0x4f4c, 0x4f52, 0x4f54, 0x4f56, + 0x4f61, 0x4f62, 0x4f66, 0x4f68, 0x4f6a, 0x4f6b, 0x4f6d, 0x4f6e, + 0x4f71, 0x4f72, 0x4f75, 0x4f77, 0x4f78, 0x4f79, 0x4f7a, 0x4f7d, + 0x4f80, 0x4f81, 0x4f82, 0x4f85, 0x4f86, 0x4f87, 0x4f8a, 0x4f8c, + 0x4f8e, 0x4f90, 0x4f92, 0x4f93, 0x4f95, 0x4f96, 0x4f98, 0x4f99, + 0x4f9a, 0x4f9c, 0x4f9e, 0x4f9f, 0x4fa1, 0x4fa2, + /* 0x82 */ + 0x4fa4, 0x4fab, 0x4fad, 0x4fb0, 0x4fb1, 0x4fb2, 0x4fb3, 0x4fb4, + 0x4fb6, 0x4fb7, 0x4fb8, 0x4fb9, 0x4fba, 0x4fbb, 0x4fbc, 0x4fbd, + 0x4fbe, 0x4fc0, 0x4fc1, 0x4fc2, 0x4fc6, 0x4fc7, 0x4fc8, 0x4fc9, + 0x4fcb, 0x4fcc, 0x4fcd, 0x4fd2, 0x4fd3, 0x4fd4, 0x4fd5, 0x4fd6, + 0x4fd9, 0x4fdb, 0x4fe0, 0x4fe2, 0x4fe4, 0x4fe5, 0x4fe7, 0x4feb, + 0x4fec, 0x4ff0, 0x4ff2, 0x4ff4, 0x4ff5, 0x4ff6, 0x4ff7, 0x4ff9, + 0x4ffb, 0x4ffc, 0x4ffd, 0x4fff, 0x5000, 0x5001, 0x5002, 0x5003, + 0x5004, 0x5005, 0x5006, 0x5007, 0x5008, 0x5009, 0x500a, 0x500b, + 0x500e, 0x5010, 0x5011, 0x5013, 0x5015, 0x5016, 0x5017, 0x501b, + 0x501d, 0x501e, 0x5020, 0x5022, 0x5023, 0x5024, 0x5027, 0x502b, + 0x502f, 0x5030, 0x5031, 0x5032, 0x5033, 0x5034, 0x5035, 0x5036, + 0x5037, 0x5038, 0x5039, 0x503b, 0x503d, 0x503f, 0x5040, 0x5041, + 0x5042, 0x5044, 0x5045, 0x5046, 0x5049, 0x504a, 0x504b, 0x504d, + 0x5050, 0x5051, 0x5052, 0x5053, 0x5054, 0x5056, 0x5057, 0x5058, + 0x5059, 0x505b, 0x505d, 0x505e, 0x505f, 0x5060, 0x5061, 0x5062, + 0x5063, 0x5064, 0x5066, 0x5067, 0x5068, 0x5069, 0x506a, 0x506b, + 0x506d, 0x506e, 0x506f, 0x5070, 0x5071, 0x5072, 0x5073, 0x5074, + 0x5075, 0x5078, 0x5079, 0x507a, 0x507c, 0x507d, 0x5081, 0x5082, + 0x5083, 0x5084, 0x5086, 0x5087, 0x5089, 0x508a, 0x508b, 0x508c, + 0x508e, 0x508f, 0x5090, 0x5091, 0x5092, 0x5093, 0x5094, 0x5095, + 0x5096, 0x5097, 0x5098, 0x5099, 0x509a, 0x509b, 0x509c, 0x509d, + 0x509e, 0x509f, 0x50a0, 0x50a1, 0x50a2, 0x50a4, 0x50a6, 0x50aa, + 0x50ab, 0x50ad, 0x50ae, 0x50af, 0x50b0, 0x50b1, 0x50b3, 0x50b4, + 0x50b5, 0x50b6, 0x50b7, 0x50b8, 0x50b9, 0x50bc, + /* 0x83 */ + 0x50bd, 0x50be, 0x50bf, 0x50c0, 0x50c1, 0x50c2, 0x50c3, 0x50c4, + 0x50c5, 0x50c6, 0x50c7, 0x50c8, 0x50c9, 0x50ca, 0x50cb, 0x50cc, + 0x50cd, 0x50ce, 0x50d0, 0x50d1, 0x50d2, 0x50d3, 0x50d4, 0x50d5, + 0x50d7, 0x50d8, 0x50d9, 0x50db, 0x50dc, 0x50dd, 0x50de, 0x50df, + 0x50e0, 0x50e1, 0x50e2, 0x50e3, 0x50e4, 0x50e5, 0x50e8, 0x50e9, + 0x50ea, 0x50eb, 0x50ef, 0x50f0, 0x50f1, 0x50f2, 0x50f4, 0x50f6, + 0x50f7, 0x50f8, 0x50f9, 0x50fa, 0x50fc, 0x50fd, 0x50fe, 0x50ff, + 0x5100, 0x5101, 0x5102, 0x5103, 0x5104, 0x5105, 0x5108, 0x5109, + 0x510a, 0x510c, 0x510d, 0x510e, 0x510f, 0x5110, 0x5111, 0x5113, + 0x5114, 0x5115, 0x5116, 0x5117, 0x5118, 0x5119, 0x511a, 0x511b, + 0x511c, 0x511d, 0x511e, 0x511f, 0x5120, 0x5122, 0x5123, 0x5124, + 0x5125, 0x5126, 0x5127, 0x5128, 0x5129, 0x512a, 0x512b, 0x512c, + 0x512d, 0x512e, 0x512f, 0x5130, 0x5131, 0x5132, 0x5133, 0x5134, + 0x5135, 0x5136, 0x5137, 0x5138, 0x5139, 0x513a, 0x513b, 0x513c, + 0x513d, 0x513e, 0x5142, 0x5147, 0x514a, 0x514c, 0x514e, 0x514f, + 0x5150, 0x5152, 0x5153, 0x5157, 0x5158, 0x5159, 0x515b, 0x515d, + 0x515e, 0x515f, 0x5160, 0x5161, 0x5163, 0x5164, 0x5166, 0x5167, + 0x5169, 0x516a, 0x516f, 0x5172, 0x517a, 0x517e, 0x517f, 0x5183, + 0x5184, 0x5186, 0x5187, 0x518a, 0x518b, 0x518e, 0x518f, 0x5190, + 0x5191, 0x5193, 0x5194, 0x5198, 0x519a, 0x519d, 0x519e, 0x519f, + 0x51a1, 0x51a3, 0x51a6, 0x51a7, 0x51a8, 0x51a9, 0x51aa, 0x51ad, + 0x51ae, 0x51b4, 0x51b8, 0x51b9, 0x51ba, 0x51be, 0x51bf, 0x51c1, + 0x51c2, 0x51c3, 0x51c5, 0x51c8, 0x51ca, 0x51cd, 0x51ce, 0x51d0, + 0x51d2, 0x51d3, 0x51d4, 0x51d5, 0x51d6, 0x51d7, + /* 0x84 */ + 0x51d8, 0x51d9, 0x51da, 0x51dc, 0x51de, 0x51df, 0x51e2, 0x51e3, + 0x51e5, 0x51e6, 0x51e7, 0x51e8, 0x51e9, 0x51ea, 0x51ec, 0x51ee, + 0x51f1, 0x51f2, 0x51f4, 0x51f7, 0x51fe, 0x5204, 0x5205, 0x5209, + 0x520b, 0x520c, 0x520f, 0x5210, 0x5213, 0x5214, 0x5215, 0x521c, + 0x521e, 0x521f, 0x5221, 0x5222, 0x5223, 0x5225, 0x5226, 0x5227, + 0x522a, 0x522c, 0x522f, 0x5231, 0x5232, 0x5234, 0x5235, 0x523c, + 0x523e, 0x5244, 0x5245, 0x5246, 0x5247, 0x5248, 0x5249, 0x524b, + 0x524e, 0x524f, 0x5252, 0x5253, 0x5255, 0x5257, 0x5258, 0x5259, + 0x525a, 0x525b, 0x525d, 0x525f, 0x5260, 0x5262, 0x5263, 0x5264, + 0x5266, 0x5268, 0x526b, 0x526c, 0x526d, 0x526e, 0x5270, 0x5271, + 0x5273, 0x5274, 0x5275, 0x5276, 0x5277, 0x5278, 0x5279, 0x527a, + 0x527b, 0x527c, 0x527e, 0x5280, 0x5283, 0x5284, 0x5285, 0x5286, + 0x5287, 0x5289, 0x528a, 0x528b, 0x528c, 0x528d, 0x528e, 0x528f, + 0x5291, 0x5292, 0x5294, 0x5295, 0x5296, 0x5297, 0x5298, 0x5299, + 0x529a, 0x529c, 0x52a4, 0x52a5, 0x52a6, 0x52a7, 0x52ae, 0x52af, + 0x52b0, 0x52b4, 0x52b5, 0x52b6, 0x52b7, 0x52b8, 0x52b9, 0x52ba, + 0x52bb, 0x52bc, 0x52bd, 0x52c0, 0x52c1, 0x52c2, 0x52c4, 0x52c5, + 0x52c6, 0x52c8, 0x52ca, 0x52cc, 0x52cd, 0x52ce, 0x52cf, 0x52d1, + 0x52d3, 0x52d4, 0x52d5, 0x52d7, 0x52d9, 0x52da, 0x52db, 0x52dc, + 0x52dd, 0x52de, 0x52e0, 0x52e1, 0x52e2, 0x52e3, 0x52e5, 0x52e6, + 0x52e7, 0x52e8, 0x52e9, 0x52ea, 0x52eb, 0x52ec, 0x52ed, 0x52ee, + 0x52ef, 0x52f1, 0x52f2, 0x52f3, 0x52f4, 0x52f5, 0x52f6, 0x52f7, + 0x52f8, 0x52fb, 0x52fc, 0x52fd, 0x5301, 0x5302, 0x5303, 0x5304, + 0x5307, 0x5309, 0x530a, 0x530b, 0x530c, 0x530e, + /* 0x85 */ + 0x5311, 0x5312, 0x5313, 0x5314, 0x5318, 0x531b, 0x531c, 0x531e, + 0x531f, 0x5322, 0x5324, 0x5325, 0x5327, 0x5328, 0x5329, 0x532b, + 0x532c, 0x532d, 0x532f, 0x5330, 0x5331, 0x5332, 0x5333, 0x5334, + 0x5335, 0x5336, 0x5337, 0x5338, 0x533c, 0x533d, 0x5340, 0x5342, + 0x5344, 0x5346, 0x534b, 0x534c, 0x534d, 0x5350, 0x5354, 0x5358, + 0x5359, 0x535b, 0x535d, 0x5365, 0x5368, 0x536a, 0x536c, 0x536d, + 0x5372, 0x5376, 0x5379, 0x537b, 0x537c, 0x537d, 0x537e, 0x5380, + 0x5381, 0x5383, 0x5387, 0x5388, 0x538a, 0x538e, 0x538f, 0x5390, + 0x5391, 0x5392, 0x5393, 0x5394, 0x5396, 0x5397, 0x5399, 0x539b, + 0x539c, 0x539e, 0x53a0, 0x53a1, 0x53a4, 0x53a7, 0x53aa, 0x53ab, + 0x53ac, 0x53ad, 0x53af, 0x53b0, 0x53b1, 0x53b2, 0x53b3, 0x53b4, + 0x53b5, 0x53b7, 0x53b8, 0x53b9, 0x53ba, 0x53bc, 0x53bd, 0x53be, + 0x53c0, 0x53c3, 0x53c4, 0x53c5, 0x53c6, 0x53c7, 0x53ce, 0x53cf, + 0x53d0, 0x53d2, 0x53d3, 0x53d5, 0x53da, 0x53dc, 0x53dd, 0x53de, + 0x53e1, 0x53e2, 0x53e7, 0x53f4, 0x53fa, 0x53fe, 0x53ff, 0x5400, + 0x5402, 0x5405, 0x5407, 0x540b, 0x5414, 0x5418, 0x5419, 0x541a, + 0x541c, 0x5422, 0x5424, 0x5425, 0x542a, 0x5430, 0x5433, 0x5436, + 0x5437, 0x543a, 0x543d, 0x543f, 0x5441, 0x5442, 0x5444, 0x5445, + 0x5447, 0x5449, 0x544c, 0x544d, 0x544e, 0x544f, 0x5451, 0x545a, + 0x545d, 0x545e, 0x545f, 0x5460, 0x5461, 0x5463, 0x5465, 0x5467, + 0x5469, 0x546a, 0x546b, 0x546c, 0x546d, 0x546e, 0x546f, 0x5470, + 0x5474, 0x5479, 0x547a, 0x547e, 0x547f, 0x5481, 0x5483, 0x5485, + 0x5487, 0x5488, 0x5489, 0x548a, 0x548d, 0x5491, 0x5493, 0x5497, + 0x5498, 0x549c, 0x549e, 0x549f, 0x54a0, 0x54a1, + /* 0x86 */ + 0x54a2, 0x54a5, 0x54ae, 0x54b0, 0x54b2, 0x54b5, 0x54b6, 0x54b7, + 0x54b9, 0x54ba, 0x54bc, 0x54be, 0x54c3, 0x54c5, 0x54ca, 0x54cb, + 0x54d6, 0x54d8, 0x54db, 0x54e0, 0x54e1, 0x54e2, 0x54e3, 0x54e4, + 0x54eb, 0x54ec, 0x54ef, 0x54f0, 0x54f1, 0x54f4, 0x54f5, 0x54f6, + 0x54f7, 0x54f8, 0x54f9, 0x54fb, 0x54fe, 0x5500, 0x5502, 0x5503, + 0x5504, 0x5505, 0x5508, 0x550a, 0x550b, 0x550c, 0x550d, 0x550e, + 0x5512, 0x5513, 0x5515, 0x5516, 0x5517, 0x5518, 0x5519, 0x551a, + 0x551c, 0x551d, 0x551e, 0x551f, 0x5521, 0x5525, 0x5526, 0x5528, + 0x5529, 0x552b, 0x552d, 0x5532, 0x5534, 0x5535, 0x5536, 0x5538, + 0x5539, 0x553a, 0x553b, 0x553d, 0x5540, 0x5542, 0x5545, 0x5547, + 0x5548, 0x554b, 0x554c, 0x554d, 0x554e, 0x554f, 0x5551, 0x5552, + 0x5553, 0x5554, 0x5557, 0x5558, 0x5559, 0x555a, 0x555b, 0x555d, + 0x555e, 0x555f, 0x5560, 0x5562, 0x5563, 0x5568, 0x5569, 0x556b, + 0x556f, 0x5570, 0x5571, 0x5572, 0x5573, 0x5574, 0x5579, 0x557a, + 0x557d, 0x557f, 0x5585, 0x5586, 0x558c, 0x558d, 0x558e, 0x5590, + 0x5592, 0x5593, 0x5595, 0x5596, 0x5597, 0x559a, 0x559b, 0x559e, + 0x55a0, 0x55a1, 0x55a2, 0x55a3, 0x55a4, 0x55a5, 0x55a6, 0x55a8, + 0x55a9, 0x55aa, 0x55ab, 0x55ac, 0x55ad, 0x55ae, 0x55af, 0x55b0, + 0x55b2, 0x55b4, 0x55b6, 0x55b8, 0x55ba, 0x55bc, 0x55bf, 0x55c0, + 0x55c1, 0x55c2, 0x55c3, 0x55c6, 0x55c7, 0x55c8, 0x55ca, 0x55cb, + 0x55ce, 0x55cf, 0x55d0, 0x55d5, 0x55d7, 0x55d8, 0x55d9, 0x55da, + 0x55db, 0x55de, 0x55e0, 0x55e2, 0x55e7, 0x55e9, 0x55ed, 0x55ee, + 0x55f0, 0x55f1, 0x55f4, 0x55f6, 0x55f8, 0x55f9, 0x55fa, 0x55fb, + 0x55fc, 0x55ff, 0x5602, 0x5603, 0x5604, 0x5605, + /* 0x87 */ + 0x5606, 0x5607, 0x560a, 0x560b, 0x560d, 0x5610, 0x5611, 0x5612, + 0x5613, 0x5614, 0x5615, 0x5616, 0x5617, 0x5619, 0x561a, 0x561c, + 0x561d, 0x5620, 0x5621, 0x5622, 0x5625, 0x5626, 0x5628, 0x5629, + 0x562a, 0x562b, 0x562e, 0x562f, 0x5630, 0x5633, 0x5635, 0x5637, + 0x5638, 0x563a, 0x563c, 0x563d, 0x563e, 0x5640, 0x5641, 0x5642, + 0x5643, 0x5644, 0x5645, 0x5646, 0x5647, 0x5648, 0x5649, 0x564a, + 0x564b, 0x564f, 0x5650, 0x5651, 0x5652, 0x5653, 0x5655, 0x5656, + 0x565a, 0x565b, 0x565d, 0x565e, 0x565f, 0x5660, 0x5661, 0x5663, + 0x5665, 0x5666, 0x5667, 0x566d, 0x566e, 0x566f, 0x5670, 0x5672, + 0x5673, 0x5674, 0x5675, 0x5677, 0x5678, 0x5679, 0x567a, 0x567d, + 0x567e, 0x567f, 0x5680, 0x5681, 0x5682, 0x5683, 0x5684, 0x5687, + 0x5688, 0x5689, 0x568a, 0x568b, 0x568c, 0x568d, 0x5690, 0x5691, + 0x5692, 0x5694, 0x5695, 0x5696, 0x5697, 0x5698, 0x5699, 0x569a, + 0x569b, 0x569c, 0x569d, 0x569e, 0x569f, 0x56a0, 0x56a1, 0x56a2, + 0x56a4, 0x56a5, 0x56a6, 0x56a7, 0x56a8, 0x56a9, 0x56aa, 0x56ab, + 0x56ac, 0x56ad, 0x56ae, 0x56b0, 0x56b1, 0x56b2, 0x56b3, 0x56b4, + 0x56b5, 0x56b6, 0x56b8, 0x56b9, 0x56ba, 0x56bb, 0x56bd, 0x56be, + 0x56bf, 0x56c0, 0x56c1, 0x56c2, 0x56c3, 0x56c4, 0x56c5, 0x56c6, + 0x56c7, 0x56c8, 0x56c9, 0x56cb, 0x56cc, 0x56cd, 0x56ce, 0x56cf, + 0x56d0, 0x56d1, 0x56d2, 0x56d3, 0x56d5, 0x56d6, 0x56d8, 0x56d9, + 0x56dc, 0x56e3, 0x56e5, 0x56e6, 0x56e7, 0x56e8, 0x56e9, 0x56ea, + 0x56ec, 0x56ee, 0x56ef, 0x56f2, 0x56f3, 0x56f6, 0x56f7, 0x56f8, + 0x56fb, 0x56fc, 0x5700, 0x5701, 0x5702, 0x5705, 0x5707, 0x570b, + 0x570c, 0x570d, 0x570e, 0x570f, 0x5710, 0x5711, + /* 0x88 */ + 0x5712, 0x5713, 0x5714, 0x5715, 0x5716, 0x5717, 0x5718, 0x5719, + 0x571a, 0x571b, 0x571d, 0x571e, 0x5720, 0x5721, 0x5722, 0x5724, + 0x5725, 0x5726, 0x5727, 0x572b, 0x5731, 0x5732, 0x5734, 0x5735, + 0x5736, 0x5737, 0x5738, 0x573c, 0x573d, 0x573f, 0x5741, 0x5743, + 0x5744, 0x5745, 0x5746, 0x5748, 0x5749, 0x574b, 0x5752, 0x5753, + 0x5754, 0x5755, 0x5756, 0x5758, 0x5759, 0x5762, 0x5763, 0x5765, + 0x5767, 0x576c, 0x576e, 0x5770, 0x5771, 0x5772, 0x5774, 0x5775, + 0x5778, 0x5779, 0x577a, 0x577d, 0x577e, 0x577f, 0x5780, 0x5781, + 0x5787, 0x5788, 0x5789, 0x578a, 0x578d, 0x578e, 0x578f, 0x5790, + 0x5791, 0x5794, 0x5795, 0x5796, 0x5797, 0x5798, 0x5799, 0x579a, + 0x579c, 0x579d, 0x579e, 0x579f, 0x57a5, 0x57a8, 0x57aa, 0x57ac, + 0x57af, 0x57b0, 0x57b1, 0x57b3, 0x57b5, 0x57b6, 0x57b7, 0x57b9, + 0x57ba, 0x57bb, 0x57bc, 0x57bd, 0x57be, 0x57bf, 0x57c0, 0x57c1, + 0x57c4, 0x57c5, 0x57c6, 0x57c7, 0x57c8, 0x57c9, 0x57ca, 0x57cc, + 0x57cd, 0x57d0, 0x57d1, 0x57d3, 0x57d6, 0x57d7, 0x57db, 0x57dc, + 0x57de, 0x57e1, 0x57e2, 0x57e3, 0x57e5, 0x57e6, 0x57e7, 0x57e8, + 0x57e9, 0x57ea, 0x57eb, 0x57ec, 0x57ee, 0x57f0, 0x57f1, 0x57f2, + 0x57f3, 0x57f5, 0x57f6, 0x57f7, 0x57fb, 0x57fc, 0x57fe, 0x57ff, + 0x5801, 0x5803, 0x5804, 0x5805, 0x5808, 0x5809, 0x580a, 0x580c, + 0x580e, 0x580f, 0x5810, 0x5812, 0x5813, 0x5814, 0x5816, 0x5817, + 0x5818, 0x581a, 0x581b, 0x581c, 0x581d, 0x581f, 0x5822, 0x5823, + 0x5825, 0x5826, 0x5827, 0x5828, 0x5829, 0x582b, 0x582c, 0x582d, + 0x582e, 0x582f, 0x5831, 0x5832, 0x5833, 0x5834, 0x5836, 0x5837, + 0x5838, 0x5839, 0x583a, 0x583b, 0x583c, 0x583d, + /* 0x89 */ + 0x583e, 0x583f, 0x5840, 0x5841, 0x5842, 0x5843, 0x5845, 0x5846, + 0x5847, 0x5848, 0x5849, 0x584a, 0x584b, 0x584e, 0x584f, 0x5850, + 0x5852, 0x5853, 0x5855, 0x5856, 0x5857, 0x5859, 0x585a, 0x585b, + 0x585c, 0x585d, 0x585f, 0x5860, 0x5861, 0x5862, 0x5863, 0x5864, + 0x5866, 0x5867, 0x5868, 0x5869, 0x586a, 0x586d, 0x586e, 0x586f, + 0x5870, 0x5871, 0x5872, 0x5873, 0x5874, 0x5875, 0x5876, 0x5877, + 0x5878, 0x5879, 0x587a, 0x587b, 0x587c, 0x587d, 0x587f, 0x5882, + 0x5884, 0x5886, 0x5887, 0x5888, 0x588a, 0x588b, 0x588c, 0x588d, + 0x588e, 0x588f, 0x5890, 0x5891, 0x5894, 0x5895, 0x5896, 0x5897, + 0x5898, 0x589b, 0x589c, 0x589d, 0x58a0, 0x58a1, 0x58a2, 0x58a3, + 0x58a4, 0x58a5, 0x58a6, 0x58a7, 0x58aa, 0x58ab, 0x58ac, 0x58ad, + 0x58ae, 0x58af, 0x58b0, 0x58b1, 0x58b2, 0x58b3, 0x58b4, 0x58b5, + 0x58b6, 0x58b7, 0x58b8, 0x58b9, 0x58ba, 0x58bb, 0x58bd, 0x58be, + 0x58bf, 0x58c0, 0x58c2, 0x58c3, 0x58c4, 0x58c6, 0x58c7, 0x58c8, + 0x58c9, 0x58ca, 0x58cb, 0x58cc, 0x58cd, 0x58ce, 0x58cf, 0x58d0, + 0x58d2, 0x58d3, 0x58d4, 0x58d6, 0x58d7, 0x58d8, 0x58d9, 0x58da, + 0x58db, 0x58dc, 0x58dd, 0x58de, 0x58df, 0x58e0, 0x58e1, 0x58e2, + 0x58e3, 0x58e5, 0x58e6, 0x58e7, 0x58e8, 0x58e9, 0x58ea, 0x58ed, + 0x58ef, 0x58f1, 0x58f2, 0x58f4, 0x58f5, 0x58f7, 0x58f8, 0x58fa, + 0x58fb, 0x58fc, 0x58fd, 0x58fe, 0x58ff, 0x5900, 0x5901, 0x5903, + 0x5905, 0x5906, 0x5908, 0x5909, 0x590a, 0x590b, 0x590c, 0x590e, + 0x5910, 0x5911, 0x5912, 0x5913, 0x5917, 0x5918, 0x591b, 0x591d, + 0x591e, 0x5920, 0x5921, 0x5922, 0x5923, 0x5926, 0x5928, 0x592c, + 0x5930, 0x5932, 0x5933, 0x5935, 0x5936, 0x593b, + /* 0x8a */ + 0x593d, 0x593e, 0x593f, 0x5940, 0x5943, 0x5945, 0x5946, 0x594a, + 0x594c, 0x594d, 0x5950, 0x5952, 0x5953, 0x5959, 0x595b, 0x595c, + 0x595d, 0x595e, 0x595f, 0x5961, 0x5963, 0x5964, 0x5966, 0x5967, + 0x5968, 0x5969, 0x596a, 0x596b, 0x596c, 0x596d, 0x596e, 0x596f, + 0x5970, 0x5971, 0x5972, 0x5975, 0x5977, 0x597a, 0x597b, 0x597c, + 0x597e, 0x597f, 0x5980, 0x5985, 0x5989, 0x598b, 0x598c, 0x598e, + 0x598f, 0x5990, 0x5991, 0x5994, 0x5995, 0x5998, 0x599a, 0x599b, + 0x599c, 0x599d, 0x599f, 0x59a0, 0x59a1, 0x59a2, 0x59a6, 0x59a7, + 0x59ac, 0x59ad, 0x59b0, 0x59b1, 0x59b3, 0x59b4, 0x59b5, 0x59b6, + 0x59b7, 0x59b8, 0x59ba, 0x59bc, 0x59bd, 0x59bf, 0x59c0, 0x59c1, + 0x59c2, 0x59c3, 0x59c4, 0x59c5, 0x59c7, 0x59c8, 0x59c9, 0x59cc, + 0x59cd, 0x59ce, 0x59cf, 0x59d5, 0x59d6, 0x59d9, 0x59db, 0x59de, + 0x59df, 0x59e0, 0x59e1, 0x59e2, 0x59e4, 0x59e6, 0x59e7, 0x59e9, + 0x59ea, 0x59eb, 0x59ed, 0x59ee, 0x59ef, 0x59f0, 0x59f1, 0x59f2, + 0x59f3, 0x59f4, 0x59f5, 0x59f6, 0x59f7, 0x59f8, 0x59fa, 0x59fc, + 0x59fd, 0x59fe, 0x5a00, 0x5a02, 0x5a0a, 0x5a0b, 0x5a0d, 0x5a0e, + 0x5a0f, 0x5a10, 0x5a12, 0x5a14, 0x5a15, 0x5a16, 0x5a17, 0x5a19, + 0x5a1a, 0x5a1b, 0x5a1d, 0x5a1e, 0x5a21, 0x5a22, 0x5a24, 0x5a26, + 0x5a27, 0x5a28, 0x5a2a, 0x5a2b, 0x5a2c, 0x5a2d, 0x5a2e, 0x5a2f, + 0x5a30, 0x5a33, 0x5a35, 0x5a37, 0x5a38, 0x5a39, 0x5a3a, 0x5a3b, + 0x5a3d, 0x5a3e, 0x5a3f, 0x5a41, 0x5a42, 0x5a43, 0x5a44, 0x5a45, + 0x5a47, 0x5a48, 0x5a4b, 0x5a4c, 0x5a4d, 0x5a4e, 0x5a4f, 0x5a50, + 0x5a51, 0x5a52, 0x5a53, 0x5a54, 0x5a56, 0x5a57, 0x5a58, 0x5a59, + 0x5a5b, 0x5a5c, 0x5a5d, 0x5a5e, 0x5a5f, 0x5a60, + /* 0x8b */ + 0x5a61, 0x5a63, 0x5a64, 0x5a65, 0x5a66, 0x5a68, 0x5a69, 0x5a6b, + 0x5a6c, 0x5a6d, 0x5a6e, 0x5a6f, 0x5a70, 0x5a71, 0x5a72, 0x5a73, + 0x5a78, 0x5a79, 0x5a7b, 0x5a7c, 0x5a7d, 0x5a7e, 0x5a80, 0x5a81, + 0x5a82, 0x5a83, 0x5a84, 0x5a85, 0x5a86, 0x5a87, 0x5a88, 0x5a89, + 0x5a8a, 0x5a8b, 0x5a8c, 0x5a8d, 0x5a8e, 0x5a8f, 0x5a90, 0x5a91, + 0x5a93, 0x5a94, 0x5a95, 0x5a96, 0x5a97, 0x5a98, 0x5a99, 0x5a9c, + 0x5a9d, 0x5a9e, 0x5a9f, 0x5aa0, 0x5aa1, 0x5aa2, 0x5aa3, 0x5aa4, + 0x5aa5, 0x5aa6, 0x5aa7, 0x5aa8, 0x5aa9, 0x5aab, 0x5aac, 0x5aad, + 0x5aae, 0x5aaf, 0x5ab0, 0x5ab1, 0x5ab4, 0x5ab6, 0x5ab7, 0x5ab9, + 0x5aba, 0x5abb, 0x5abc, 0x5abd, 0x5abf, 0x5ac0, 0x5ac3, 0x5ac4, + 0x5ac5, 0x5ac6, 0x5ac7, 0x5ac8, 0x5aca, 0x5acb, 0x5acd, 0x5ace, + 0x5acf, 0x5ad0, 0x5ad1, 0x5ad3, 0x5ad5, 0x5ad7, 0x5ad9, 0x5ada, + 0x5adb, 0x5add, 0x5ade, 0x5adf, 0x5ae2, 0x5ae4, 0x5ae5, 0x5ae7, + 0x5ae8, 0x5aea, 0x5aec, 0x5aed, 0x5aee, 0x5aef, 0x5af0, 0x5af2, + 0x5af3, 0x5af4, 0x5af5, 0x5af6, 0x5af7, 0x5af8, 0x5af9, 0x5afa, + 0x5afb, 0x5afc, 0x5afd, 0x5afe, 0x5aff, 0x5b00, 0x5b01, 0x5b02, + 0x5b03, 0x5b04, 0x5b05, 0x5b06, 0x5b07, 0x5b08, 0x5b0a, 0x5b0b, + 0x5b0c, 0x5b0d, 0x5b0e, 0x5b0f, 0x5b10, 0x5b11, 0x5b12, 0x5b13, + 0x5b14, 0x5b15, 0x5b18, 0x5b19, 0x5b1a, 0x5b1b, 0x5b1c, 0x5b1d, + 0x5b1e, 0x5b1f, 0x5b20, 0x5b21, 0x5b22, 0x5b23, 0x5b24, 0x5b25, + 0x5b26, 0x5b27, 0x5b28, 0x5b29, 0x5b2a, 0x5b2b, 0x5b2c, 0x5b2d, + 0x5b2e, 0x5b2f, 0x5b30, 0x5b31, 0x5b33, 0x5b35, 0x5b36, 0x5b38, + 0x5b39, 0x5b3a, 0x5b3b, 0x5b3c, 0x5b3d, 0x5b3e, 0x5b3f, 0x5b41, + 0x5b42, 0x5b43, 0x5b44, 0x5b45, 0x5b46, 0x5b47, + /* 0x8c */ + 0x5b48, 0x5b49, 0x5b4a, 0x5b4b, 0x5b4c, 0x5b4d, 0x5b4e, 0x5b4f, + 0x5b52, 0x5b56, 0x5b5e, 0x5b60, 0x5b61, 0x5b67, 0x5b68, 0x5b6b, + 0x5b6d, 0x5b6e, 0x5b6f, 0x5b72, 0x5b74, 0x5b76, 0x5b77, 0x5b78, + 0x5b79, 0x5b7b, 0x5b7c, 0x5b7e, 0x5b7f, 0x5b82, 0x5b86, 0x5b8a, + 0x5b8d, 0x5b8e, 0x5b90, 0x5b91, 0x5b92, 0x5b94, 0x5b96, 0x5b9f, + 0x5ba7, 0x5ba8, 0x5ba9, 0x5bac, 0x5bad, 0x5bae, 0x5baf, 0x5bb1, + 0x5bb2, 0x5bb7, 0x5bba, 0x5bbb, 0x5bbc, 0x5bc0, 0x5bc1, 0x5bc3, + 0x5bc8, 0x5bc9, 0x5bca, 0x5bcb, 0x5bcd, 0x5bce, 0x5bcf, 0x5bd1, + 0x5bd4, 0x5bd5, 0x5bd6, 0x5bd7, 0x5bd8, 0x5bd9, 0x5bda, 0x5bdb, + 0x5bdc, 0x5be0, 0x5be2, 0x5be3, 0x5be6, 0x5be7, 0x5be9, 0x5bea, + 0x5beb, 0x5bec, 0x5bed, 0x5bef, 0x5bf1, 0x5bf2, 0x5bf3, 0x5bf4, + 0x5bf5, 0x5bf6, 0x5bf7, 0x5bfd, 0x5bfe, 0x5c00, 0x5c02, 0x5c03, + 0x5c05, 0x5c07, 0x5c08, 0x5c0b, 0x5c0c, 0x5c0d, 0x5c0e, 0x5c10, + 0x5c12, 0x5c13, 0x5c17, 0x5c19, 0x5c1b, 0x5c1e, 0x5c1f, 0x5c20, + 0x5c21, 0x5c23, 0x5c26, 0x5c28, 0x5c29, 0x5c2a, 0x5c2b, 0x5c2d, + 0x5c2e, 0x5c2f, 0x5c30, 0x5c32, 0x5c33, 0x5c35, 0x5c36, 0x5c37, + 0x5c43, 0x5c44, 0x5c46, 0x5c47, 0x5c4c, 0x5c4d, 0x5c52, 0x5c53, + 0x5c54, 0x5c56, 0x5c57, 0x5c58, 0x5c5a, 0x5c5b, 0x5c5c, 0x5c5d, + 0x5c5f, 0x5c62, 0x5c64, 0x5c67, 0x5c68, 0x5c69, 0x5c6a, 0x5c6b, + 0x5c6c, 0x5c6d, 0x5c70, 0x5c72, 0x5c73, 0x5c74, 0x5c75, 0x5c76, + 0x5c77, 0x5c78, 0x5c7b, 0x5c7c, 0x5c7d, 0x5c7e, 0x5c80, 0x5c83, + 0x5c84, 0x5c85, 0x5c86, 0x5c87, 0x5c89, 0x5c8a, 0x5c8b, 0x5c8e, + 0x5c8f, 0x5c92, 0x5c93, 0x5c95, 0x5c9d, 0x5c9e, 0x5c9f, 0x5ca0, + 0x5ca1, 0x5ca4, 0x5ca5, 0x5ca6, 0x5ca7, 0x5ca8, + /* 0x8d */ + 0x5caa, 0x5cae, 0x5caf, 0x5cb0, 0x5cb2, 0x5cb4, 0x5cb6, 0x5cb9, + 0x5cba, 0x5cbb, 0x5cbc, 0x5cbe, 0x5cc0, 0x5cc2, 0x5cc3, 0x5cc5, + 0x5cc6, 0x5cc7, 0x5cc8, 0x5cc9, 0x5cca, 0x5ccc, 0x5ccd, 0x5cce, + 0x5ccf, 0x5cd0, 0x5cd1, 0x5cd3, 0x5cd4, 0x5cd5, 0x5cd6, 0x5cd7, + 0x5cd8, 0x5cda, 0x5cdb, 0x5cdc, 0x5cdd, 0x5cde, 0x5cdf, 0x5ce0, + 0x5ce2, 0x5ce3, 0x5ce7, 0x5ce9, 0x5ceb, 0x5cec, 0x5cee, 0x5cef, + 0x5cf1, 0x5cf2, 0x5cf3, 0x5cf4, 0x5cf5, 0x5cf6, 0x5cf7, 0x5cf8, + 0x5cf9, 0x5cfa, 0x5cfc, 0x5cfd, 0x5cfe, 0x5cff, 0x5d00, 0x5d01, + 0x5d04, 0x5d05, 0x5d08, 0x5d09, 0x5d0a, 0x5d0b, 0x5d0c, 0x5d0d, + 0x5d0f, 0x5d10, 0x5d11, 0x5d12, 0x5d13, 0x5d15, 0x5d17, 0x5d18, + 0x5d19, 0x5d1a, 0x5d1c, 0x5d1d, 0x5d1f, 0x5d20, 0x5d21, 0x5d22, + 0x5d23, 0x5d25, 0x5d28, 0x5d2a, 0x5d2b, 0x5d2c, 0x5d2f, 0x5d30, + 0x5d31, 0x5d32, 0x5d33, 0x5d35, 0x5d36, 0x5d37, 0x5d38, 0x5d39, + 0x5d3a, 0x5d3b, 0x5d3c, 0x5d3f, 0x5d40, 0x5d41, 0x5d42, 0x5d43, + 0x5d44, 0x5d45, 0x5d46, 0x5d48, 0x5d49, 0x5d4d, 0x5d4e, 0x5d4f, + 0x5d50, 0x5d51, 0x5d52, 0x5d53, 0x5d54, 0x5d55, 0x5d56, 0x5d57, + 0x5d59, 0x5d5a, 0x5d5c, 0x5d5e, 0x5d5f, 0x5d60, 0x5d61, 0x5d62, + 0x5d63, 0x5d64, 0x5d65, 0x5d66, 0x5d67, 0x5d68, 0x5d6a, 0x5d6d, + 0x5d6e, 0x5d70, 0x5d71, 0x5d72, 0x5d73, 0x5d75, 0x5d76, 0x5d77, + 0x5d78, 0x5d79, 0x5d7a, 0x5d7b, 0x5d7c, 0x5d7d, 0x5d7e, 0x5d7f, + 0x5d80, 0x5d81, 0x5d83, 0x5d84, 0x5d85, 0x5d86, 0x5d87, 0x5d88, + 0x5d89, 0x5d8a, 0x5d8b, 0x5d8c, 0x5d8d, 0x5d8e, 0x5d8f, 0x5d90, + 0x5d91, 0x5d92, 0x5d93, 0x5d94, 0x5d95, 0x5d96, 0x5d97, 0x5d98, + 0x5d9a, 0x5d9b, 0x5d9c, 0x5d9e, 0x5d9f, 0x5da0, + /* 0x8e */ + 0x5da1, 0x5da2, 0x5da3, 0x5da4, 0x5da5, 0x5da6, 0x5da7, 0x5da8, + 0x5da9, 0x5daa, 0x5dab, 0x5dac, 0x5dad, 0x5dae, 0x5daf, 0x5db0, + 0x5db1, 0x5db2, 0x5db3, 0x5db4, 0x5db5, 0x5db6, 0x5db8, 0x5db9, + 0x5dba, 0x5dbb, 0x5dbc, 0x5dbd, 0x5dbe, 0x5dbf, 0x5dc0, 0x5dc1, + 0x5dc2, 0x5dc3, 0x5dc4, 0x5dc6, 0x5dc7, 0x5dc8, 0x5dc9, 0x5dca, + 0x5dcb, 0x5dcc, 0x5dce, 0x5dcf, 0x5dd0, 0x5dd1, 0x5dd2, 0x5dd3, + 0x5dd4, 0x5dd5, 0x5dd6, 0x5dd7, 0x5dd8, 0x5dd9, 0x5dda, 0x5ddc, + 0x5ddf, 0x5de0, 0x5de3, 0x5de4, 0x5dea, 0x5dec, 0x5ded, 0x5df0, + 0x5df5, 0x5df6, 0x5df8, 0x5df9, 0x5dfa, 0x5dfb, 0x5dfc, 0x5dff, + 0x5e00, 0x5e04, 0x5e07, 0x5e09, 0x5e0a, 0x5e0b, 0x5e0d, 0x5e0e, + 0x5e12, 0x5e13, 0x5e17, 0x5e1e, 0x5e1f, 0x5e20, 0x5e21, 0x5e22, + 0x5e23, 0x5e24, 0x5e25, 0x5e28, 0x5e29, 0x5e2a, 0x5e2b, 0x5e2c, + 0x5e2f, 0x5e30, 0x5e32, 0x5e33, 0x5e34, 0x5e35, 0x5e36, 0x5e39, + 0x5e3a, 0x5e3e, 0x5e3f, 0x5e40, 0x5e41, 0x5e43, 0x5e46, 0x5e47, + 0x5e48, 0x5e49, 0x5e4a, 0x5e4b, 0x5e4d, 0x5e4e, 0x5e4f, 0x5e50, + 0x5e51, 0x5e52, 0x5e53, 0x5e56, 0x5e57, 0x5e58, 0x5e59, 0x5e5a, + 0x5e5c, 0x5e5d, 0x5e5f, 0x5e60, 0x5e63, 0x5e64, 0x5e65, 0x5e66, + 0x5e67, 0x5e68, 0x5e69, 0x5e6a, 0x5e6b, 0x5e6c, 0x5e6d, 0x5e6e, + 0x5e6f, 0x5e70, 0x5e71, 0x5e75, 0x5e77, 0x5e79, 0x5e7e, 0x5e81, + 0x5e82, 0x5e83, 0x5e85, 0x5e88, 0x5e89, 0x5e8c, 0x5e8d, 0x5e8e, + 0x5e92, 0x5e98, 0x5e9b, 0x5e9d, 0x5ea1, 0x5ea2, 0x5ea3, 0x5ea4, + 0x5ea8, 0x5ea9, 0x5eaa, 0x5eab, 0x5eac, 0x5eae, 0x5eaf, 0x5eb0, + 0x5eb1, 0x5eb2, 0x5eb4, 0x5eba, 0x5ebb, 0x5ebc, 0x5ebd, 0x5ebf, + 0x5ec0, 0x5ec1, 0x5ec2, 0x5ec3, 0x5ec4, 0x5ec5, + /* 0x8f */ + 0x5ec6, 0x5ec7, 0x5ec8, 0x5ecb, 0x5ecc, 0x5ecd, 0x5ece, 0x5ecf, + 0x5ed0, 0x5ed4, 0x5ed5, 0x5ed7, 0x5ed8, 0x5ed9, 0x5eda, 0x5edc, + 0x5edd, 0x5ede, 0x5edf, 0x5ee0, 0x5ee1, 0x5ee2, 0x5ee3, 0x5ee4, + 0x5ee5, 0x5ee6, 0x5ee7, 0x5ee9, 0x5eeb, 0x5eec, 0x5eed, 0x5eee, + 0x5eef, 0x5ef0, 0x5ef1, 0x5ef2, 0x5ef3, 0x5ef5, 0x5ef8, 0x5ef9, + 0x5efb, 0x5efc, 0x5efd, 0x5f05, 0x5f06, 0x5f07, 0x5f09, 0x5f0c, + 0x5f0d, 0x5f0e, 0x5f10, 0x5f12, 0x5f14, 0x5f16, 0x5f19, 0x5f1a, + 0x5f1c, 0x5f1d, 0x5f1e, 0x5f21, 0x5f22, 0x5f23, 0x5f24, 0x5f28, + 0x5f2b, 0x5f2c, 0x5f2e, 0x5f30, 0x5f32, 0x5f33, 0x5f34, 0x5f35, + 0x5f36, 0x5f37, 0x5f38, 0x5f3b, 0x5f3d, 0x5f3e, 0x5f3f, 0x5f41, + 0x5f42, 0x5f43, 0x5f44, 0x5f45, 0x5f46, 0x5f47, 0x5f48, 0x5f49, + 0x5f4a, 0x5f4b, 0x5f4c, 0x5f4d, 0x5f4e, 0x5f4f, 0x5f51, 0x5f54, + 0x5f59, 0x5f5a, 0x5f5b, 0x5f5c, 0x5f5e, 0x5f5f, 0x5f60, 0x5f63, + 0x5f65, 0x5f67, 0x5f68, 0x5f6b, 0x5f6e, 0x5f6f, 0x5f72, 0x5f74, + 0x5f75, 0x5f76, 0x5f78, 0x5f7a, 0x5f7d, 0x5f7e, 0x5f7f, 0x5f83, + 0x5f86, 0x5f8d, 0x5f8e, 0x5f8f, 0x5f91, 0x5f93, 0x5f94, 0x5f96, + 0x5f9a, 0x5f9b, 0x5f9d, 0x5f9e, 0x5f9f, 0x5fa0, 0x5fa2, 0x5fa3, + 0x5fa4, 0x5fa5, 0x5fa6, 0x5fa7, 0x5fa9, 0x5fab, 0x5fac, 0x5faf, + 0x5fb0, 0x5fb1, 0x5fb2, 0x5fb3, 0x5fb4, 0x5fb6, 0x5fb8, 0x5fb9, + 0x5fba, 0x5fbb, 0x5fbe, 0x5fbf, 0x5fc0, 0x5fc1, 0x5fc2, 0x5fc7, + 0x5fc8, 0x5fca, 0x5fcb, 0x5fce, 0x5fd3, 0x5fd4, 0x5fd5, 0x5fda, + 0x5fdb, 0x5fdc, 0x5fde, 0x5fdf, 0x5fe2, 0x5fe3, 0x5fe5, 0x5fe6, + 0x5fe8, 0x5fe9, 0x5fec, 0x5fef, 0x5ff0, 0x5ff2, 0x5ff3, 0x5ff4, + 0x5ff6, 0x5ff7, 0x5ff9, 0x5ffa, 0x5ffc, 0x6007, + /* 0x90 */ + 0x6008, 0x6009, 0x600b, 0x600c, 0x6010, 0x6011, 0x6013, 0x6017, + 0x6018, 0x601a, 0x601e, 0x601f, 0x6022, 0x6023, 0x6024, 0x602c, + 0x602d, 0x602e, 0x6030, 0x6031, 0x6032, 0x6033, 0x6034, 0x6036, + 0x6037, 0x6038, 0x6039, 0x603a, 0x603d, 0x603e, 0x6040, 0x6044, + 0x6045, 0x6046, 0x6047, 0x6048, 0x6049, 0x604a, 0x604c, 0x604e, + 0x604f, 0x6051, 0x6053, 0x6054, 0x6056, 0x6057, 0x6058, 0x605b, + 0x605c, 0x605e, 0x605f, 0x6060, 0x6061, 0x6065, 0x6066, 0x606e, + 0x6071, 0x6072, 0x6074, 0x6075, 0x6077, 0x607e, 0x6080, 0x6081, + 0x6082, 0x6085, 0x6086, 0x6087, 0x6088, 0x608a, 0x608b, 0x608e, + 0x608f, 0x6090, 0x6091, 0x6093, 0x6095, 0x6097, 0x6098, 0x6099, + 0x609c, 0x609e, 0x60a1, 0x60a2, 0x60a4, 0x60a5, 0x60a7, 0x60a9, + 0x60aa, 0x60ae, 0x60b0, 0x60b3, 0x60b5, 0x60b6, 0x60b7, 0x60b9, + 0x60ba, 0x60bd, 0x60be, 0x60bf, 0x60c0, 0x60c1, 0x60c2, 0x60c3, + 0x60c4, 0x60c7, 0x60c8, 0x60c9, 0x60cc, 0x60cd, 0x60ce, 0x60cf, + 0x60d0, 0x60d2, 0x60d3, 0x60d4, 0x60d6, 0x60d7, 0x60d9, 0x60db, + 0x60de, 0x60e1, 0x60e2, 0x60e3, 0x60e4, 0x60e5, 0x60ea, 0x60f1, + 0x60f2, 0x60f5, 0x60f7, 0x60f8, 0x60fb, 0x60fc, 0x60fd, 0x60fe, + 0x60ff, 0x6102, 0x6103, 0x6104, 0x6105, 0x6107, 0x610a, 0x610b, + 0x610c, 0x6110, 0x6111, 0x6112, 0x6113, 0x6114, 0x6116, 0x6117, + 0x6118, 0x6119, 0x611b, 0x611c, 0x611d, 0x611e, 0x6121, 0x6122, + 0x6125, 0x6128, 0x6129, 0x612a, 0x612c, 0x612d, 0x612e, 0x612f, + 0x6130, 0x6131, 0x6132, 0x6133, 0x6134, 0x6135, 0x6136, 0x6137, + 0x6138, 0x6139, 0x613a, 0x613b, 0x613c, 0x613d, 0x613e, 0x6140, + 0x6141, 0x6142, 0x6143, 0x6144, 0x6145, 0x6146, + /* 0x91 */ + 0x6147, 0x6149, 0x614b, 0x614d, 0x614f, 0x6150, 0x6152, 0x6153, + 0x6154, 0x6156, 0x6157, 0x6158, 0x6159, 0x615a, 0x615b, 0x615c, + 0x615e, 0x615f, 0x6160, 0x6161, 0x6163, 0x6164, 0x6165, 0x6166, + 0x6169, 0x616a, 0x616b, 0x616c, 0x616d, 0x616e, 0x616f, 0x6171, + 0x6172, 0x6173, 0x6174, 0x6176, 0x6178, 0x6179, 0x617a, 0x617b, + 0x617c, 0x617d, 0x617e, 0x617f, 0x6180, 0x6181, 0x6182, 0x6183, + 0x6184, 0x6185, 0x6186, 0x6187, 0x6188, 0x6189, 0x618a, 0x618c, + 0x618d, 0x618f, 0x6190, 0x6191, 0x6192, 0x6193, 0x6195, 0x6196, + 0x6197, 0x6198, 0x6199, 0x619a, 0x619b, 0x619c, 0x619e, 0x619f, + 0x61a0, 0x61a1, 0x61a2, 0x61a3, 0x61a4, 0x61a5, 0x61a6, 0x61aa, + 0x61ab, 0x61ad, 0x61ae, 0x61af, 0x61b0, 0x61b1, 0x61b2, 0x61b3, + 0x61b4, 0x61b5, 0x61b6, 0x61b8, 0x61b9, 0x61ba, 0x61bb, 0x61bc, + 0x61bd, 0x61bf, 0x61c0, 0x61c1, 0x61c3, 0x61c4, 0x61c5, 0x61c6, + 0x61c7, 0x61c9, 0x61cc, 0x61cd, 0x61ce, 0x61cf, 0x61d0, 0x61d3, + 0x61d5, 0x61d6, 0x61d7, 0x61d8, 0x61d9, 0x61da, 0x61db, 0x61dc, + 0x61dd, 0x61de, 0x61df, 0x61e0, 0x61e1, 0x61e2, 0x61e3, 0x61e4, + 0x61e5, 0x61e7, 0x61e8, 0x61e9, 0x61ea, 0x61eb, 0x61ec, 0x61ed, + 0x61ee, 0x61ef, 0x61f0, 0x61f1, 0x61f2, 0x61f3, 0x61f4, 0x61f6, + 0x61f7, 0x61f8, 0x61f9, 0x61fa, 0x61fb, 0x61fc, 0x61fd, 0x61fe, + 0x6200, 0x6201, 0x6202, 0x6203, 0x6204, 0x6205, 0x6207, 0x6209, + 0x6213, 0x6214, 0x6219, 0x621c, 0x621d, 0x621e, 0x6220, 0x6223, + 0x6226, 0x6227, 0x6228, 0x6229, 0x622b, 0x622d, 0x622f, 0x6230, + 0x6231, 0x6232, 0x6235, 0x6236, 0x6238, 0x6239, 0x623a, 0x623b, + 0x623c, 0x6242, 0x6244, 0x6245, 0x6246, 0x624a, + /* 0x92 */ + 0x624f, 0x6250, 0x6255, 0x6256, 0x6257, 0x6259, 0x625a, 0x625c, + 0x625d, 0x625e, 0x625f, 0x6260, 0x6261, 0x6262, 0x6264, 0x6265, + 0x6268, 0x6271, 0x6272, 0x6274, 0x6275, 0x6277, 0x6278, 0x627a, + 0x627b, 0x627d, 0x6281, 0x6282, 0x6283, 0x6285, 0x6286, 0x6287, + 0x6288, 0x628b, 0x628c, 0x628d, 0x628e, 0x628f, 0x6290, 0x6294, + 0x6299, 0x629c, 0x629d, 0x629e, 0x62a3, 0x62a6, 0x62a7, 0x62a9, + 0x62aa, 0x62ad, 0x62ae, 0x62af, 0x62b0, 0x62b2, 0x62b3, 0x62b4, + 0x62b6, 0x62b7, 0x62b8, 0x62ba, 0x62be, 0x62c0, 0x62c1, 0x62c3, + 0x62cb, 0x62cf, 0x62d1, 0x62d5, 0x62dd, 0x62de, 0x62e0, 0x62e1, + 0x62e4, 0x62ea, 0x62eb, 0x62f0, 0x62f2, 0x62f5, 0x62f8, 0x62f9, + 0x62fa, 0x62fb, 0x6300, 0x6303, 0x6304, 0x6305, 0x6306, 0x630a, + 0x630b, 0x630c, 0x630d, 0x630f, 0x6310, 0x6312, 0x6313, 0x6314, + 0x6315, 0x6317, 0x6318, 0x6319, 0x631c, 0x6326, 0x6327, 0x6329, + 0x632c, 0x632d, 0x632e, 0x6330, 0x6331, 0x6333, 0x6334, 0x6335, + 0x6336, 0x6337, 0x6338, 0x633b, 0x633c, 0x633e, 0x633f, 0x6340, + 0x6341, 0x6344, 0x6347, 0x6348, 0x634a, 0x6351, 0x6352, 0x6353, + 0x6354, 0x6356, 0x6357, 0x6358, 0x6359, 0x635a, 0x635b, 0x635c, + 0x635d, 0x6360, 0x6364, 0x6365, 0x6366, 0x6368, 0x636a, 0x636b, + 0x636c, 0x636f, 0x6370, 0x6372, 0x6373, 0x6374, 0x6375, 0x6378, + 0x6379, 0x637c, 0x637d, 0x637e, 0x637f, 0x6381, 0x6383, 0x6384, + 0x6385, 0x6386, 0x638b, 0x638d, 0x6391, 0x6393, 0x6394, 0x6395, + 0x6397, 0x6399, 0x639a, 0x639b, 0x639c, 0x639d, 0x639e, 0x639f, + 0x63a1, 0x63a4, 0x63a6, 0x63ab, 0x63af, 0x63b1, 0x63b2, 0x63b5, + 0x63b6, 0x63b9, 0x63bb, 0x63bd, 0x63bf, 0x63c0, + /* 0x93 */ + 0x63c1, 0x63c2, 0x63c3, 0x63c5, 0x63c7, 0x63c8, 0x63ca, 0x63cb, + 0x63cc, 0x63d1, 0x63d3, 0x63d4, 0x63d5, 0x63d7, 0x63d8, 0x63d9, + 0x63da, 0x63db, 0x63dc, 0x63dd, 0x63df, 0x63e2, 0x63e4, 0x63e5, + 0x63e6, 0x63e7, 0x63e8, 0x63eb, 0x63ec, 0x63ee, 0x63ef, 0x63f0, + 0x63f1, 0x63f3, 0x63f5, 0x63f7, 0x63f9, 0x63fa, 0x63fb, 0x63fc, + 0x63fe, 0x6403, 0x6404, 0x6406, 0x6407, 0x6408, 0x6409, 0x640a, + 0x640d, 0x640e, 0x6411, 0x6412, 0x6415, 0x6416, 0x6417, 0x6418, + 0x6419, 0x641a, 0x641d, 0x641f, 0x6422, 0x6423, 0x6424, 0x6425, + 0x6427, 0x6428, 0x6429, 0x642b, 0x642e, 0x642f, 0x6430, 0x6431, + 0x6432, 0x6433, 0x6435, 0x6436, 0x6437, 0x6438, 0x6439, 0x643b, + 0x643c, 0x643e, 0x6440, 0x6442, 0x6443, 0x6449, 0x644b, 0x644c, + 0x644d, 0x644e, 0x644f, 0x6450, 0x6451, 0x6453, 0x6455, 0x6456, + 0x6457, 0x6459, 0x645a, 0x645b, 0x645c, 0x645d, 0x645f, 0x6460, + 0x6461, 0x6462, 0x6463, 0x6464, 0x6465, 0x6466, 0x6468, 0x646a, + 0x646b, 0x646c, 0x646e, 0x646f, 0x6470, 0x6471, 0x6472, 0x6473, + 0x6474, 0x6475, 0x6476, 0x6477, 0x647b, 0x647c, 0x647d, 0x647e, + 0x647f, 0x6480, 0x6481, 0x6483, 0x6486, 0x6488, 0x6489, 0x648a, + 0x648b, 0x648c, 0x648d, 0x648e, 0x648f, 0x6490, 0x6493, 0x6494, + 0x6497, 0x6498, 0x649a, 0x649b, 0x649c, 0x649d, 0x649f, 0x64a0, + 0x64a1, 0x64a2, 0x64a3, 0x64a5, 0x64a6, 0x64a7, 0x64a8, 0x64aa, + 0x64ab, 0x64af, 0x64b1, 0x64b2, 0x64b3, 0x64b4, 0x64b6, 0x64b9, + 0x64bb, 0x64bd, 0x64be, 0x64bf, 0x64c1, 0x64c3, 0x64c4, 0x64c6, + 0x64c7, 0x64c8, 0x64c9, 0x64ca, 0x64cb, 0x64cc, 0x64cf, 0x64d1, + 0x64d3, 0x64d4, 0x64d5, 0x64d6, 0x64d9, 0x64da, + /* 0x94 */ + 0x64db, 0x64dc, 0x64dd, 0x64df, 0x64e0, 0x64e1, 0x64e3, 0x64e5, + 0x64e7, 0x64e8, 0x64e9, 0x64ea, 0x64eb, 0x64ec, 0x64ed, 0x64ee, + 0x64ef, 0x64f0, 0x64f1, 0x64f2, 0x64f3, 0x64f4, 0x64f5, 0x64f6, + 0x64f7, 0x64f8, 0x64f9, 0x64fa, 0x64fb, 0x64fc, 0x64fd, 0x64fe, + 0x64ff, 0x6501, 0x6502, 0x6503, 0x6504, 0x6505, 0x6506, 0x6507, + 0x6508, 0x650a, 0x650b, 0x650c, 0x650d, 0x650e, 0x650f, 0x6510, + 0x6511, 0x6513, 0x6514, 0x6515, 0x6516, 0x6517, 0x6519, 0x651a, + 0x651b, 0x651c, 0x651d, 0x651e, 0x651f, 0x6520, 0x6521, 0x6522, + 0x6523, 0x6524, 0x6526, 0x6527, 0x6528, 0x6529, 0x652a, 0x652c, + 0x652d, 0x6530, 0x6531, 0x6532, 0x6533, 0x6537, 0x653a, 0x653c, + 0x653d, 0x6540, 0x6541, 0x6542, 0x6543, 0x6544, 0x6546, 0x6547, + 0x654a, 0x654b, 0x654d, 0x654e, 0x6550, 0x6552, 0x6553, 0x6554, + 0x6557, 0x6558, 0x655a, 0x655c, 0x655f, 0x6560, 0x6561, 0x6564, + 0x6565, 0x6567, 0x6568, 0x6569, 0x656a, 0x656d, 0x656e, 0x656f, + 0x6571, 0x6573, 0x6575, 0x6576, 0x6578, 0x6579, 0x657a, 0x657b, + 0x657c, 0x657d, 0x657e, 0x657f, 0x6580, 0x6581, 0x6582, 0x6583, + 0x6584, 0x6585, 0x6586, 0x6588, 0x6589, 0x658a, 0x658d, 0x658e, + 0x658f, 0x6592, 0x6594, 0x6595, 0x6596, 0x6598, 0x659a, 0x659d, + 0x659e, 0x65a0, 0x65a2, 0x65a3, 0x65a6, 0x65a8, 0x65aa, 0x65ac, + 0x65ae, 0x65b1, 0x65b2, 0x65b3, 0x65b4, 0x65b5, 0x65b6, 0x65b7, + 0x65b8, 0x65ba, 0x65bb, 0x65be, 0x65bf, 0x65c0, 0x65c2, 0x65c7, + 0x65c8, 0x65c9, 0x65ca, 0x65cd, 0x65d0, 0x65d1, 0x65d3, 0x65d4, + 0x65d5, 0x65d8, 0x65d9, 0x65da, 0x65db, 0x65dc, 0x65dd, 0x65de, + 0x65df, 0x65e1, 0x65e3, 0x65e4, 0x65ea, 0x65eb, + /* 0x95 */ + 0x65f2, 0x65f3, 0x65f4, 0x65f5, 0x65f8, 0x65f9, 0x65fb, 0x65fc, + 0x65fd, 0x65fe, 0x65ff, 0x6601, 0x6604, 0x6605, 0x6607, 0x6608, + 0x6609, 0x660b, 0x660d, 0x6610, 0x6611, 0x6612, 0x6616, 0x6617, + 0x6618, 0x661a, 0x661b, 0x661c, 0x661e, 0x6621, 0x6622, 0x6623, + 0x6624, 0x6626, 0x6629, 0x662a, 0x662b, 0x662c, 0x662e, 0x6630, + 0x6632, 0x6633, 0x6637, 0x6638, 0x6639, 0x663a, 0x663b, 0x663d, + 0x663f, 0x6640, 0x6642, 0x6644, 0x6645, 0x6646, 0x6647, 0x6648, + 0x6649, 0x664a, 0x664d, 0x664e, 0x6650, 0x6651, 0x6658, 0x6659, + 0x665b, 0x665c, 0x665d, 0x665e, 0x6660, 0x6662, 0x6663, 0x6665, + 0x6667, 0x6669, 0x666a, 0x666b, 0x666c, 0x666d, 0x6671, 0x6672, + 0x6673, 0x6675, 0x6678, 0x6679, 0x667b, 0x667c, 0x667d, 0x667f, + 0x6680, 0x6681, 0x6683, 0x6685, 0x6686, 0x6688, 0x6689, 0x668a, + 0x668b, 0x668d, 0x668e, 0x668f, 0x6690, 0x6692, 0x6693, 0x6694, + 0x6695, 0x6698, 0x6699, 0x669a, 0x669b, 0x669c, 0x669e, 0x669f, + 0x66a0, 0x66a1, 0x66a2, 0x66a3, 0x66a4, 0x66a5, 0x66a6, 0x66a9, + 0x66aa, 0x66ab, 0x66ac, 0x66ad, 0x66af, 0x66b0, 0x66b1, 0x66b2, + 0x66b3, 0x66b5, 0x66b6, 0x66b7, 0x66b8, 0x66ba, 0x66bb, 0x66bc, + 0x66bd, 0x66bf, 0x66c0, 0x66c1, 0x66c2, 0x66c3, 0x66c4, 0x66c5, + 0x66c6, 0x66c7, 0x66c8, 0x66c9, 0x66ca, 0x66cb, 0x66cc, 0x66cd, + 0x66ce, 0x66cf, 0x66d0, 0x66d1, 0x66d2, 0x66d3, 0x66d4, 0x66d5, + 0x66d6, 0x66d7, 0x66d8, 0x66da, 0x66de, 0x66df, 0x66e0, 0x66e1, + 0x66e2, 0x66e3, 0x66e4, 0x66e5, 0x66e7, 0x66e8, 0x66ea, 0x66eb, + 0x66ec, 0x66ed, 0x66ee, 0x66ef, 0x66f1, 0x66f5, 0x66f6, 0x66f8, + 0x66fa, 0x66fb, 0x66fd, 0x6701, 0x6702, 0x6703, + /* 0x96 */ + 0x6704, 0x6705, 0x6706, 0x6707, 0x670c, 0x670e, 0x670f, 0x6711, + 0x6712, 0x6713, 0x6716, 0x6718, 0x6719, 0x671a, 0x671c, 0x671e, + 0x6720, 0x6721, 0x6722, 0x6723, 0x6724, 0x6725, 0x6727, 0x6729, + 0x672e, 0x6730, 0x6732, 0x6733, 0x6736, 0x6737, 0x6738, 0x6739, + 0x673b, 0x673c, 0x673e, 0x673f, 0x6741, 0x6744, 0x6745, 0x6747, + 0x674a, 0x674b, 0x674d, 0x6752, 0x6754, 0x6755, 0x6757, 0x6758, + 0x6759, 0x675a, 0x675b, 0x675d, 0x6762, 0x6763, 0x6764, 0x6766, + 0x6767, 0x676b, 0x676c, 0x676e, 0x6771, 0x6774, 0x6776, 0x6778, + 0x6779, 0x677a, 0x677b, 0x677d, 0x6780, 0x6782, 0x6783, 0x6785, + 0x6786, 0x6788, 0x678a, 0x678c, 0x678d, 0x678e, 0x678f, 0x6791, + 0x6792, 0x6793, 0x6794, 0x6796, 0x6799, 0x679b, 0x679f, 0x67a0, + 0x67a1, 0x67a4, 0x67a6, 0x67a9, 0x67ac, 0x67ae, 0x67b1, 0x67b2, + 0x67b4, 0x67b9, 0x67ba, 0x67bb, 0x67bc, 0x67bd, 0x67be, 0x67bf, + 0x67c0, 0x67c2, 0x67c5, 0x67c6, 0x67c7, 0x67c8, 0x67c9, 0x67ca, + 0x67cb, 0x67cc, 0x67cd, 0x67ce, 0x67d5, 0x67d6, 0x67d7, 0x67db, + 0x67df, 0x67e1, 0x67e3, 0x67e4, 0x67e6, 0x67e7, 0x67e8, 0x67ea, + 0x67eb, 0x67ed, 0x67ee, 0x67f2, 0x67f5, 0x67f6, 0x67f7, 0x67f8, + 0x67f9, 0x67fa, 0x67fb, 0x67fc, 0x67fe, 0x6801, 0x6802, 0x6803, + 0x6804, 0x6806, 0x680d, 0x6810, 0x6812, 0x6814, 0x6815, 0x6818, + 0x6819, 0x681a, 0x681b, 0x681c, 0x681e, 0x681f, 0x6820, 0x6822, + 0x6823, 0x6824, 0x6825, 0x6826, 0x6827, 0x6828, 0x682b, 0x682c, + 0x682d, 0x682e, 0x682f, 0x6830, 0x6831, 0x6834, 0x6835, 0x6836, + 0x683a, 0x683b, 0x683f, 0x6847, 0x684b, 0x684d, 0x684f, 0x6852, + 0x6856, 0x6857, 0x6858, 0x6859, 0x685a, 0x685b, + /* 0x97 */ + 0x685c, 0x685d, 0x685e, 0x685f, 0x686a, 0x686c, 0x686d, 0x686e, + 0x686f, 0x6870, 0x6871, 0x6872, 0x6873, 0x6875, 0x6878, 0x6879, + 0x687a, 0x687b, 0x687c, 0x687d, 0x687e, 0x687f, 0x6880, 0x6882, + 0x6884, 0x6887, 0x6888, 0x6889, 0x688a, 0x688b, 0x688c, 0x688d, + 0x688e, 0x6890, 0x6891, 0x6892, 0x6894, 0x6895, 0x6896, 0x6898, + 0x6899, 0x689a, 0x689b, 0x689c, 0x689d, 0x689e, 0x689f, 0x68a0, + 0x68a1, 0x68a3, 0x68a4, 0x68a5, 0x68a9, 0x68aa, 0x68ab, 0x68ac, + 0x68ae, 0x68b1, 0x68b2, 0x68b4, 0x68b6, 0x68b7, 0x68b8, 0x68b9, + 0x68ba, 0x68bb, 0x68bc, 0x68bd, 0x68be, 0x68bf, 0x68c1, 0x68c3, + 0x68c4, 0x68c5, 0x68c6, 0x68c7, 0x68c8, 0x68ca, 0x68cc, 0x68ce, + 0x68cf, 0x68d0, 0x68d1, 0x68d3, 0x68d4, 0x68d6, 0x68d7, 0x68d9, + 0x68db, 0x68dc, 0x68dd, 0x68de, 0x68df, 0x68e1, 0x68e2, 0x68e4, + 0x68e5, 0x68e6, 0x68e7, 0x68e8, 0x68e9, 0x68ea, 0x68eb, 0x68ec, + 0x68ed, 0x68ef, 0x68f2, 0x68f3, 0x68f4, 0x68f6, 0x68f7, 0x68f8, + 0x68fb, 0x68fd, 0x68fe, 0x68ff, 0x6900, 0x6902, 0x6903, 0x6904, + 0x6906, 0x6907, 0x6908, 0x6909, 0x690a, 0x690c, 0x690f, 0x6911, + 0x6913, 0x6914, 0x6915, 0x6916, 0x6917, 0x6918, 0x6919, 0x691a, + 0x691b, 0x691c, 0x691d, 0x691e, 0x6921, 0x6922, 0x6923, 0x6925, + 0x6926, 0x6927, 0x6928, 0x6929, 0x692a, 0x692b, 0x692c, 0x692e, + 0x692f, 0x6931, 0x6932, 0x6933, 0x6935, 0x6936, 0x6937, 0x6938, + 0x693a, 0x693b, 0x693c, 0x693e, 0x6940, 0x6941, 0x6943, 0x6944, + 0x6945, 0x6946, 0x6947, 0x6948, 0x6949, 0x694a, 0x694b, 0x694c, + 0x694d, 0x694e, 0x694f, 0x6950, 0x6951, 0x6952, 0x6953, 0x6955, + 0x6956, 0x6958, 0x6959, 0x695b, 0x695c, 0x695f, + /* 0x98 */ + 0x6961, 0x6962, 0x6964, 0x6965, 0x6967, 0x6968, 0x6969, 0x696a, + 0x696c, 0x696d, 0x696f, 0x6970, 0x6972, 0x6973, 0x6974, 0x6975, + 0x6976, 0x697a, 0x697b, 0x697d, 0x697e, 0x697f, 0x6981, 0x6983, + 0x6985, 0x698a, 0x698b, 0x698c, 0x698e, 0x698f, 0x6990, 0x6991, + 0x6992, 0x6993, 0x6996, 0x6997, 0x6999, 0x699a, 0x699d, 0x699e, + 0x699f, 0x69a0, 0x69a1, 0x69a2, 0x69a3, 0x69a4, 0x69a5, 0x69a6, + 0x69a9, 0x69aa, 0x69ac, 0x69ae, 0x69af, 0x69b0, 0x69b2, 0x69b3, + 0x69b5, 0x69b6, 0x69b8, 0x69b9, 0x69ba, 0x69bc, 0x69bd, 0x69be, + 0x69bf, 0x69c0, 0x69c2, 0x69c3, 0x69c4, 0x69c5, 0x69c6, 0x69c7, + 0x69c8, 0x69c9, 0x69cb, 0x69cd, 0x69cf, 0x69d1, 0x69d2, 0x69d3, + 0x69d5, 0x69d6, 0x69d7, 0x69d8, 0x69d9, 0x69da, 0x69dc, 0x69dd, + 0x69de, 0x69e1, 0x69e2, 0x69e3, 0x69e4, 0x69e5, 0x69e6, 0x69e7, + 0x69e8, 0x69e9, 0x69ea, 0x69eb, 0x69ec, 0x69ee, 0x69ef, 0x69f0, + 0x69f1, 0x69f3, 0x69f4, 0x69f5, 0x69f6, 0x69f7, 0x69f8, 0x69f9, + 0x69fa, 0x69fb, 0x69fc, 0x69fe, 0x6a00, 0x6a01, 0x6a02, 0x6a03, + 0x6a04, 0x6a05, 0x6a06, 0x6a07, 0x6a08, 0x6a09, 0x6a0b, 0x6a0c, + 0x6a0d, 0x6a0e, 0x6a0f, 0x6a10, 0x6a11, 0x6a12, 0x6a13, 0x6a14, + 0x6a15, 0x6a16, 0x6a19, 0x6a1a, 0x6a1b, 0x6a1c, 0x6a1d, 0x6a1e, + 0x6a20, 0x6a22, 0x6a23, 0x6a24, 0x6a25, 0x6a26, 0x6a27, 0x6a29, + 0x6a2b, 0x6a2c, 0x6a2d, 0x6a2e, 0x6a30, 0x6a32, 0x6a33, 0x6a34, + 0x6a36, 0x6a37, 0x6a38, 0x6a39, 0x6a3a, 0x6a3b, 0x6a3c, 0x6a3f, + 0x6a40, 0x6a41, 0x6a42, 0x6a43, 0x6a45, 0x6a46, 0x6a48, 0x6a49, + 0x6a4a, 0x6a4b, 0x6a4c, 0x6a4d, 0x6a4e, 0x6a4f, 0x6a51, 0x6a52, + 0x6a53, 0x6a54, 0x6a55, 0x6a56, 0x6a57, 0x6a5a, + /* 0x99 */ + 0x6a5c, 0x6a5d, 0x6a5e, 0x6a5f, 0x6a60, 0x6a62, 0x6a63, 0x6a64, + 0x6a66, 0x6a67, 0x6a68, 0x6a69, 0x6a6a, 0x6a6b, 0x6a6c, 0x6a6d, + 0x6a6e, 0x6a6f, 0x6a70, 0x6a72, 0x6a73, 0x6a74, 0x6a75, 0x6a76, + 0x6a77, 0x6a78, 0x6a7a, 0x6a7b, 0x6a7d, 0x6a7e, 0x6a7f, 0x6a81, + 0x6a82, 0x6a83, 0x6a85, 0x6a86, 0x6a87, 0x6a88, 0x6a89, 0x6a8a, + 0x6a8b, 0x6a8c, 0x6a8d, 0x6a8f, 0x6a92, 0x6a93, 0x6a94, 0x6a95, + 0x6a96, 0x6a98, 0x6a99, 0x6a9a, 0x6a9b, 0x6a9c, 0x6a9d, 0x6a9e, + 0x6a9f, 0x6aa1, 0x6aa2, 0x6aa3, 0x6aa4, 0x6aa5, 0x6aa6, 0x6aa7, + 0x6aa8, 0x6aaa, 0x6aad, 0x6aae, 0x6aaf, 0x6ab0, 0x6ab1, 0x6ab2, + 0x6ab3, 0x6ab4, 0x6ab5, 0x6ab6, 0x6ab7, 0x6ab8, 0x6ab9, 0x6aba, + 0x6abb, 0x6abc, 0x6abd, 0x6abe, 0x6abf, 0x6ac0, 0x6ac1, 0x6ac2, + 0x6ac3, 0x6ac4, 0x6ac5, 0x6ac6, 0x6ac7, 0x6ac8, 0x6ac9, 0x6aca, + 0x6acb, 0x6acc, 0x6acd, 0x6ace, 0x6acf, 0x6ad0, 0x6ad1, 0x6ad2, + 0x6ad3, 0x6ad4, 0x6ad5, 0x6ad6, 0x6ad7, 0x6ad8, 0x6ad9, 0x6ada, + 0x6adb, 0x6adc, 0x6add, 0x6ade, 0x6adf, 0x6ae0, 0x6ae1, 0x6ae2, + 0x6ae3, 0x6ae4, 0x6ae5, 0x6ae6, 0x6ae7, 0x6ae8, 0x6ae9, 0x6aea, + 0x6aeb, 0x6aec, 0x6aed, 0x6aee, 0x6aef, 0x6af0, 0x6af1, 0x6af2, + 0x6af3, 0x6af4, 0x6af5, 0x6af6, 0x6af7, 0x6af8, 0x6af9, 0x6afa, + 0x6afb, 0x6afc, 0x6afd, 0x6afe, 0x6aff, 0x6b00, 0x6b01, 0x6b02, + 0x6b03, 0x6b04, 0x6b05, 0x6b06, 0x6b07, 0x6b08, 0x6b09, 0x6b0a, + 0x6b0b, 0x6b0c, 0x6b0d, 0x6b0e, 0x6b0f, 0x6b10, 0x6b11, 0x6b12, + 0x6b13, 0x6b14, 0x6b15, 0x6b16, 0x6b17, 0x6b18, 0x6b19, 0x6b1a, + 0x6b1b, 0x6b1c, 0x6b1d, 0x6b1e, 0x6b1f, 0x6b25, 0x6b26, 0x6b28, + 0x6b29, 0x6b2a, 0x6b2b, 0x6b2c, 0x6b2d, 0x6b2e, + /* 0x9a */ + 0x6b2f, 0x6b30, 0x6b31, 0x6b33, 0x6b34, 0x6b35, 0x6b36, 0x6b38, + 0x6b3b, 0x6b3c, 0x6b3d, 0x6b3f, 0x6b40, 0x6b41, 0x6b42, 0x6b44, + 0x6b45, 0x6b48, 0x6b4a, 0x6b4b, 0x6b4d, 0x6b4e, 0x6b4f, 0x6b50, + 0x6b51, 0x6b52, 0x6b53, 0x6b54, 0x6b55, 0x6b56, 0x6b57, 0x6b58, + 0x6b5a, 0x6b5b, 0x6b5c, 0x6b5d, 0x6b5e, 0x6b5f, 0x6b60, 0x6b61, + 0x6b68, 0x6b69, 0x6b6b, 0x6b6c, 0x6b6d, 0x6b6e, 0x6b6f, 0x6b70, + 0x6b71, 0x6b72, 0x6b73, 0x6b74, 0x6b75, 0x6b76, 0x6b77, 0x6b78, + 0x6b7a, 0x6b7d, 0x6b7e, 0x6b7f, 0x6b80, 0x6b85, 0x6b88, 0x6b8c, + 0x6b8e, 0x6b8f, 0x6b90, 0x6b91, 0x6b94, 0x6b95, 0x6b97, 0x6b98, + 0x6b99, 0x6b9c, 0x6b9d, 0x6b9e, 0x6b9f, 0x6ba0, 0x6ba2, 0x6ba3, + 0x6ba4, 0x6ba5, 0x6ba6, 0x6ba7, 0x6ba8, 0x6ba9, 0x6bab, 0x6bac, + 0x6bad, 0x6bae, 0x6baf, 0x6bb0, 0x6bb1, 0x6bb2, 0x6bb6, 0x6bb8, + 0x6bb9, 0x6bba, 0x6bbb, 0x6bbc, 0x6bbd, 0x6bbe, 0x6bc0, 0x6bc3, + 0x6bc4, 0x6bc6, 0x6bc7, 0x6bc8, 0x6bc9, 0x6bca, 0x6bcc, 0x6bce, + 0x6bd0, 0x6bd1, 0x6bd8, 0x6bda, 0x6bdc, 0x6bdd, 0x6bde, 0x6bdf, + 0x6be0, 0x6be2, 0x6be3, 0x6be4, 0x6be5, 0x6be6, 0x6be7, 0x6be8, + 0x6be9, 0x6bec, 0x6bed, 0x6bee, 0x6bf0, 0x6bf1, 0x6bf2, 0x6bf4, + 0x6bf6, 0x6bf7, 0x6bf8, 0x6bfa, 0x6bfb, 0x6bfc, 0x6bfe, 0x6bff, + 0x6c00, 0x6c01, 0x6c02, 0x6c03, 0x6c04, 0x6c08, 0x6c09, 0x6c0a, + 0x6c0b, 0x6c0c, 0x6c0e, 0x6c12, 0x6c17, 0x6c1c, 0x6c1d, 0x6c1e, + 0x6c20, 0x6c23, 0x6c25, 0x6c2b, 0x6c2c, 0x6c2d, 0x6c31, 0x6c33, + 0x6c36, 0x6c37, 0x6c39, 0x6c3a, 0x6c3b, 0x6c3c, 0x6c3e, 0x6c3f, + 0x6c43, 0x6c44, 0x6c45, 0x6c48, 0x6c4b, 0x6c4c, 0x6c4d, 0x6c4e, + 0x6c4f, 0x6c51, 0x6c52, 0x6c53, 0x6c56, 0x6c58, + /* 0x9b */ + 0x6c59, 0x6c5a, 0x6c62, 0x6c63, 0x6c65, 0x6c66, 0x6c67, 0x6c6b, + 0x6c6c, 0x6c6d, 0x6c6e, 0x6c6f, 0x6c71, 0x6c73, 0x6c75, 0x6c77, + 0x6c78, 0x6c7a, 0x6c7b, 0x6c7c, 0x6c7f, 0x6c80, 0x6c84, 0x6c87, + 0x6c8a, 0x6c8b, 0x6c8d, 0x6c8e, 0x6c91, 0x6c92, 0x6c95, 0x6c96, + 0x6c97, 0x6c98, 0x6c9a, 0x6c9c, 0x6c9d, 0x6c9e, 0x6ca0, 0x6ca2, + 0x6ca8, 0x6cac, 0x6caf, 0x6cb0, 0x6cb4, 0x6cb5, 0x6cb6, 0x6cb7, + 0x6cba, 0x6cc0, 0x6cc1, 0x6cc2, 0x6cc3, 0x6cc6, 0x6cc7, 0x6cc8, + 0x6ccb, 0x6ccd, 0x6cce, 0x6ccf, 0x6cd1, 0x6cd2, 0x6cd8, 0x6cd9, + 0x6cda, 0x6cdc, 0x6cdd, 0x6cdf, 0x6ce4, 0x6ce6, 0x6ce7, 0x6ce9, + 0x6cec, 0x6ced, 0x6cf2, 0x6cf4, 0x6cf9, 0x6cff, 0x6d00, 0x6d02, + 0x6d03, 0x6d05, 0x6d06, 0x6d08, 0x6d09, 0x6d0a, 0x6d0d, 0x6d0f, + 0x6d10, 0x6d11, 0x6d13, 0x6d14, 0x6d15, 0x6d16, 0x6d18, 0x6d1c, + 0x6d1d, 0x6d1f, 0x6d20, 0x6d21, 0x6d22, 0x6d23, 0x6d24, 0x6d26, + 0x6d28, 0x6d29, 0x6d2c, 0x6d2d, 0x6d2f, 0x6d30, 0x6d34, 0x6d36, + 0x6d37, 0x6d38, 0x6d3a, 0x6d3f, 0x6d40, 0x6d42, 0x6d44, 0x6d49, + 0x6d4c, 0x6d50, 0x6d55, 0x6d56, 0x6d57, 0x6d58, 0x6d5b, 0x6d5d, + 0x6d5f, 0x6d61, 0x6d62, 0x6d64, 0x6d65, 0x6d67, 0x6d68, 0x6d6b, + 0x6d6c, 0x6d6d, 0x6d70, 0x6d71, 0x6d72, 0x6d73, 0x6d75, 0x6d76, + 0x6d79, 0x6d7a, 0x6d7b, 0x6d7d, 0x6d7e, 0x6d7f, 0x6d80, 0x6d81, + 0x6d83, 0x6d84, 0x6d86, 0x6d87, 0x6d8a, 0x6d8b, 0x6d8d, 0x6d8f, + 0x6d90, 0x6d92, 0x6d96, 0x6d97, 0x6d98, 0x6d99, 0x6d9a, 0x6d9c, + 0x6da2, 0x6da5, 0x6dac, 0x6dad, 0x6db0, 0x6db1, 0x6db3, 0x6db4, + 0x6db6, 0x6db7, 0x6db9, 0x6dba, 0x6dbb, 0x6dbc, 0x6dbd, 0x6dbe, + 0x6dc1, 0x6dc2, 0x6dc3, 0x6dc8, 0x6dc9, 0x6dca, + /* 0x9c */ + 0x6dcd, 0x6dce, 0x6dcf, 0x6dd0, 0x6dd2, 0x6dd3, 0x6dd4, 0x6dd5, + 0x6dd7, 0x6dda, 0x6ddb, 0x6ddc, 0x6ddf, 0x6de2, 0x6de3, 0x6de5, + 0x6de7, 0x6de8, 0x6de9, 0x6dea, 0x6ded, 0x6def, 0x6df0, 0x6df2, + 0x6df4, 0x6df5, 0x6df6, 0x6df8, 0x6dfa, 0x6dfd, 0x6dfe, 0x6dff, + 0x6e00, 0x6e01, 0x6e02, 0x6e03, 0x6e04, 0x6e06, 0x6e07, 0x6e08, + 0x6e09, 0x6e0b, 0x6e0f, 0x6e12, 0x6e13, 0x6e15, 0x6e18, 0x6e19, + 0x6e1b, 0x6e1c, 0x6e1e, 0x6e1f, 0x6e22, 0x6e26, 0x6e27, 0x6e28, + 0x6e2a, 0x6e2c, 0x6e2e, 0x6e30, 0x6e31, 0x6e33, 0x6e35, 0x6e36, + 0x6e37, 0x6e39, 0x6e3b, 0x6e3c, 0x6e3d, 0x6e3e, 0x6e3f, 0x6e40, + 0x6e41, 0x6e42, 0x6e45, 0x6e46, 0x6e47, 0x6e48, 0x6e49, 0x6e4a, + 0x6e4b, 0x6e4c, 0x6e4f, 0x6e50, 0x6e51, 0x6e52, 0x6e55, 0x6e57, + 0x6e59, 0x6e5a, 0x6e5c, 0x6e5d, 0x6e5e, 0x6e60, 0x6e61, 0x6e62, + 0x6e63, 0x6e64, 0x6e65, 0x6e66, 0x6e67, 0x6e68, 0x6e69, 0x6e6a, + 0x6e6c, 0x6e6d, 0x6e6f, 0x6e70, 0x6e71, 0x6e72, 0x6e73, 0x6e74, + 0x6e75, 0x6e76, 0x6e77, 0x6e78, 0x6e79, 0x6e7a, 0x6e7b, 0x6e7c, + 0x6e7d, 0x6e80, 0x6e81, 0x6e82, 0x6e84, 0x6e87, 0x6e88, 0x6e8a, + 0x6e8b, 0x6e8c, 0x6e8d, 0x6e8e, 0x6e91, 0x6e92, 0x6e93, 0x6e94, + 0x6e95, 0x6e96, 0x6e97, 0x6e99, 0x6e9a, 0x6e9b, 0x6e9d, 0x6e9e, + 0x6ea0, 0x6ea1, 0x6ea3, 0x6ea4, 0x6ea6, 0x6ea8, 0x6ea9, 0x6eab, + 0x6eac, 0x6ead, 0x6eae, 0x6eb0, 0x6eb3, 0x6eb5, 0x6eb8, 0x6eb9, + 0x6ebc, 0x6ebe, 0x6ebf, 0x6ec0, 0x6ec3, 0x6ec4, 0x6ec5, 0x6ec6, + 0x6ec8, 0x6ec9, 0x6eca, 0x6ecc, 0x6ecd, 0x6ece, 0x6ed0, 0x6ed2, + 0x6ed6, 0x6ed8, 0x6ed9, 0x6edb, 0x6edc, 0x6edd, 0x6ee3, 0x6ee7, + 0x6eea, 0x6eeb, 0x6eec, 0x6eed, 0x6eee, 0x6eef, + /* 0x9d */ + 0x6ef0, 0x6ef1, 0x6ef2, 0x6ef3, 0x6ef5, 0x6ef6, 0x6ef7, 0x6ef8, + 0x6efa, 0x6efb, 0x6efc, 0x6efd, 0x6efe, 0x6eff, 0x6f00, 0x6f01, + 0x6f03, 0x6f04, 0x6f05, 0x6f07, 0x6f08, 0x6f0a, 0x6f0b, 0x6f0c, + 0x6f0d, 0x6f0e, 0x6f10, 0x6f11, 0x6f12, 0x6f16, 0x6f17, 0x6f18, + 0x6f19, 0x6f1a, 0x6f1b, 0x6f1c, 0x6f1d, 0x6f1e, 0x6f1f, 0x6f21, + 0x6f22, 0x6f23, 0x6f25, 0x6f26, 0x6f27, 0x6f28, 0x6f2c, 0x6f2e, + 0x6f30, 0x6f32, 0x6f34, 0x6f35, 0x6f37, 0x6f38, 0x6f39, 0x6f3a, + 0x6f3b, 0x6f3c, 0x6f3d, 0x6f3f, 0x6f40, 0x6f41, 0x6f42, 0x6f43, + 0x6f44, 0x6f45, 0x6f48, 0x6f49, 0x6f4a, 0x6f4c, 0x6f4e, 0x6f4f, + 0x6f50, 0x6f51, 0x6f52, 0x6f53, 0x6f54, 0x6f55, 0x6f56, 0x6f57, + 0x6f59, 0x6f5a, 0x6f5b, 0x6f5d, 0x6f5f, 0x6f60, 0x6f61, 0x6f63, + 0x6f64, 0x6f65, 0x6f67, 0x6f68, 0x6f69, 0x6f6a, 0x6f6b, 0x6f6c, + 0x6f6f, 0x6f70, 0x6f71, 0x6f73, 0x6f75, 0x6f76, 0x6f77, 0x6f79, + 0x6f7b, 0x6f7d, 0x6f7e, 0x6f7f, 0x6f80, 0x6f81, 0x6f82, 0x6f83, + 0x6f85, 0x6f86, 0x6f87, 0x6f8a, 0x6f8b, 0x6f8f, 0x6f90, 0x6f91, + 0x6f92, 0x6f93, 0x6f94, 0x6f95, 0x6f96, 0x6f97, 0x6f98, 0x6f99, + 0x6f9a, 0x6f9b, 0x6f9d, 0x6f9e, 0x6f9f, 0x6fa0, 0x6fa2, 0x6fa3, + 0x6fa4, 0x6fa5, 0x6fa6, 0x6fa8, 0x6fa9, 0x6faa, 0x6fab, 0x6fac, + 0x6fad, 0x6fae, 0x6faf, 0x6fb0, 0x6fb1, 0x6fb2, 0x6fb4, 0x6fb5, + 0x6fb7, 0x6fb8, 0x6fba, 0x6fbb, 0x6fbc, 0x6fbd, 0x6fbe, 0x6fbf, + 0x6fc1, 0x6fc3, 0x6fc4, 0x6fc5, 0x6fc6, 0x6fc7, 0x6fc8, 0x6fca, + 0x6fcb, 0x6fcc, 0x6fcd, 0x6fce, 0x6fcf, 0x6fd0, 0x6fd3, 0x6fd4, + 0x6fd5, 0x6fd6, 0x6fd7, 0x6fd8, 0x6fd9, 0x6fda, 0x6fdb, 0x6fdc, + 0x6fdd, 0x6fdf, 0x6fe2, 0x6fe3, 0x6fe4, 0x6fe5, + /* 0x9e */ + 0x6fe6, 0x6fe7, 0x6fe8, 0x6fe9, 0x6fea, 0x6feb, 0x6fec, 0x6fed, + 0x6ff0, 0x6ff1, 0x6ff2, 0x6ff3, 0x6ff4, 0x6ff5, 0x6ff6, 0x6ff7, + 0x6ff8, 0x6ff9, 0x6ffa, 0x6ffb, 0x6ffc, 0x6ffd, 0x6ffe, 0x6fff, + 0x7000, 0x7001, 0x7002, 0x7003, 0x7004, 0x7005, 0x7006, 0x7007, + 0x7008, 0x7009, 0x700a, 0x700b, 0x700c, 0x700d, 0x700e, 0x700f, + 0x7010, 0x7012, 0x7013, 0x7014, 0x7015, 0x7016, 0x7017, 0x7018, + 0x7019, 0x701c, 0x701d, 0x701e, 0x701f, 0x7020, 0x7021, 0x7022, + 0x7024, 0x7025, 0x7026, 0x7027, 0x7028, 0x7029, 0x702a, 0x702b, + 0x702c, 0x702d, 0x702e, 0x702f, 0x7030, 0x7031, 0x7032, 0x7033, + 0x7034, 0x7036, 0x7037, 0x7038, 0x703a, 0x703b, 0x703c, 0x703d, + 0x703e, 0x703f, 0x7040, 0x7041, 0x7042, 0x7043, 0x7044, 0x7045, + 0x7046, 0x7047, 0x7048, 0x7049, 0x704a, 0x704b, 0x704d, 0x704e, + 0x7050, 0x7051, 0x7052, 0x7053, 0x7054, 0x7055, 0x7056, 0x7057, + 0x7058, 0x7059, 0x705a, 0x705b, 0x705c, 0x705d, 0x705f, 0x7060, + 0x7061, 0x7062, 0x7063, 0x7064, 0x7065, 0x7066, 0x7067, 0x7068, + 0x7069, 0x706a, 0x706e, 0x7071, 0x7072, 0x7073, 0x7074, 0x7077, + 0x7079, 0x707a, 0x707b, 0x707d, 0x7081, 0x7082, 0x7083, 0x7084, + 0x7086, 0x7087, 0x7088, 0x708b, 0x708c, 0x708d, 0x708f, 0x7090, + 0x7091, 0x7093, 0x7097, 0x7098, 0x709a, 0x709b, 0x709e, 0x709f, + 0x70a0, 0x70a1, 0x70a2, 0x70a3, 0x70a4, 0x70a5, 0x70a6, 0x70a7, + 0x70a8, 0x70a9, 0x70aa, 0x70b0, 0x70b2, 0x70b4, 0x70b5, 0x70b6, + 0x70ba, 0x70be, 0x70bf, 0x70c4, 0x70c5, 0x70c6, 0x70c7, 0x70c9, + 0x70cb, 0x70cc, 0x70cd, 0x70ce, 0x70cf, 0x70d0, 0x70d1, 0x70d2, + 0x70d3, 0x70d4, 0x70d5, 0x70d6, 0x70d7, 0x70da, + /* 0x9f */ + 0x70dc, 0x70dd, 0x70de, 0x70e0, 0x70e1, 0x70e2, 0x70e3, 0x70e5, + 0x70ea, 0x70ee, 0x70f0, 0x70f1, 0x70f2, 0x70f3, 0x70f4, 0x70f5, + 0x70f6, 0x70f8, 0x70fa, 0x70fb, 0x70fc, 0x70fe, 0x70ff, 0x7100, + 0x7101, 0x7102, 0x7103, 0x7104, 0x7105, 0x7106, 0x7107, 0x7108, + 0x710b, 0x710c, 0x710d, 0x710e, 0x710f, 0x7111, 0x7112, 0x7114, + 0x7117, 0x711b, 0x711c, 0x711d, 0x711e, 0x711f, 0x7120, 0x7121, + 0x7122, 0x7123, 0x7124, 0x7125, 0x7127, 0x7128, 0x7129, 0x712a, + 0x712b, 0x712c, 0x712d, 0x712e, 0x7132, 0x7133, 0x7134, 0x7135, + 0x7137, 0x7138, 0x7139, 0x713a, 0x713b, 0x713c, 0x713d, 0x713e, + 0x713f, 0x7140, 0x7141, 0x7142, 0x7143, 0x7144, 0x7146, 0x7147, + 0x7148, 0x7149, 0x714b, 0x714d, 0x714f, 0x7150, 0x7151, 0x7152, + 0x7153, 0x7154, 0x7155, 0x7156, 0x7157, 0x7158, 0x7159, 0x715a, + 0x715b, 0x715d, 0x715f, 0x7160, 0x7161, 0x7162, 0x7163, 0x7165, + 0x7169, 0x716a, 0x716b, 0x716c, 0x716d, 0x716f, 0x7170, 0x7171, + 0x7174, 0x7175, 0x7176, 0x7177, 0x7179, 0x717b, 0x717c, 0x717e, + 0x717f, 0x7180, 0x7181, 0x7182, 0x7183, 0x7185, 0x7186, 0x7187, + 0x7188, 0x7189, 0x718b, 0x718c, 0x718d, 0x718e, 0x7190, 0x7191, + 0x7192, 0x7193, 0x7195, 0x7196, 0x7197, 0x719a, 0x719b, 0x719c, + 0x719d, 0x719e, 0x71a1, 0x71a2, 0x71a3, 0x71a4, 0x71a5, 0x71a6, + 0x71a7, 0x71a9, 0x71aa, 0x71ab, 0x71ad, 0x71ae, 0x71af, 0x71b0, + 0x71b1, 0x71b2, 0x71b4, 0x71b6, 0x71b7, 0x71b8, 0x71ba, 0x71bb, + 0x71bc, 0x71bd, 0x71be, 0x71bf, 0x71c0, 0x71c1, 0x71c2, 0x71c4, + 0x71c5, 0x71c6, 0x71c7, 0x71c8, 0x71c9, 0x71ca, 0x71cb, 0x71cc, + 0x71cd, 0x71cf, 0x71d0, 0x71d1, 0x71d2, 0x71d3, + /* 0xa0 */ + 0x71d6, 0x71d7, 0x71d8, 0x71d9, 0x71da, 0x71db, 0x71dc, 0x71dd, + 0x71de, 0x71df, 0x71e1, 0x71e2, 0x71e3, 0x71e4, 0x71e6, 0x71e8, + 0x71e9, 0x71ea, 0x71eb, 0x71ec, 0x71ed, 0x71ef, 0x71f0, 0x71f1, + 0x71f2, 0x71f3, 0x71f4, 0x71f5, 0x71f6, 0x71f7, 0x71f8, 0x71fa, + 0x71fb, 0x71fc, 0x71fd, 0x71fe, 0x71ff, 0x7200, 0x7201, 0x7202, + 0x7203, 0x7204, 0x7205, 0x7207, 0x7208, 0x7209, 0x720a, 0x720b, + 0x720c, 0x720d, 0x720e, 0x720f, 0x7210, 0x7211, 0x7212, 0x7213, + 0x7214, 0x7215, 0x7216, 0x7217, 0x7218, 0x7219, 0x721a, 0x721b, + 0x721c, 0x721e, 0x721f, 0x7220, 0x7221, 0x7222, 0x7223, 0x7224, + 0x7225, 0x7226, 0x7227, 0x7229, 0x722b, 0x722d, 0x722e, 0x722f, + 0x7232, 0x7233, 0x7234, 0x723a, 0x723c, 0x723e, 0x7240, 0x7241, + 0x7242, 0x7243, 0x7244, 0x7245, 0x7246, 0x7249, 0x724a, 0x724b, + 0x724e, 0x724f, 0x7250, 0x7251, 0x7253, 0x7254, 0x7255, 0x7257, + 0x7258, 0x725a, 0x725c, 0x725e, 0x7260, 0x7263, 0x7264, 0x7265, + 0x7268, 0x726a, 0x726b, 0x726c, 0x726d, 0x7270, 0x7271, 0x7273, + 0x7274, 0x7276, 0x7277, 0x7278, 0x727b, 0x727c, 0x727d, 0x7282, + 0x7283, 0x7285, 0x7286, 0x7287, 0x7288, 0x7289, 0x728c, 0x728e, + 0x7290, 0x7291, 0x7293, 0x7294, 0x7295, 0x7296, 0x7297, 0x7298, + 0x7299, 0x729a, 0x729b, 0x729c, 0x729d, 0x729e, 0x72a0, 0x72a1, + 0x72a2, 0x72a3, 0x72a4, 0x72a5, 0x72a6, 0x72a7, 0x72a8, 0x72a9, + 0x72aa, 0x72ab, 0x72ae, 0x72b1, 0x72b2, 0x72b3, 0x72b5, 0x72ba, + 0x72bb, 0x72bc, 0x72bd, 0x72be, 0x72bf, 0x72c0, 0x72c5, 0x72c6, + 0x72c7, 0x72c9, 0x72ca, 0x72cb, 0x72cc, 0x72cf, 0x72d1, 0x72d3, + 0x72d4, 0x72d5, 0x72d6, 0x72d8, 0x72da, 0x72db, +}; + +static int +gbkext1_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x81 && c1 <= 0xa0)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0x80 && c2 < 0xff)) { + unsigned int i = 190 * (c1 - 0x81) + (c2 - (c2 >= 0x80 ? 0x41 : 0x40)); + unsigned short wc = 0xfffd; + { + if (i < 6080) + wc = gbkext1_2uni_page81[i]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + diff --git a/libs/libiconv/lib/gbkext2.h b/libs/libiconv/lib/gbkext2.h new file mode 100644 index 00000000..5a0dbdec --- /dev/null +++ b/libs/libiconv/lib/gbkext2.h @@ -0,0 +1,1174 @@ +/* + * Copyright (C) 1999-2000 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * GBK/4 and GBK/5 extensions + */ + +static const unsigned short gbkext2_2uni_pagea8[8272] = { + /* 0xa8 */ + 0x02ca, 0x02cb, 0x02d9, 0x2013, 0x2015, 0x2025, 0x2035, 0x2105, + 0x2109, 0x2196, 0x2197, 0x2198, 0x2199, 0x2215, 0x221f, 0x2223, + 0x2252, 0x2266, 0x2267, 0x22bf, 0x2550, 0x2551, 0x2552, 0x2553, + 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, + 0x255c, 0x255d, 0x255e, 0x255f, 0x2560, 0x2561, 0x2562, 0x2563, + 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, + 0x256c, 0x256d, 0x256e, 0x256f, 0x2570, 0x2571, 0x2572, 0x2573, + 0x2581, 0x2582, 0x2583, 0x2584, 0x2585, 0x2586, 0x2587, 0x2588, + 0x2589, 0x258a, 0x258b, 0x258c, 0x258d, 0x258e, 0x258f, 0x2593, + 0x2594, 0x2595, 0x25bc, 0x25bd, 0x25e2, 0x25e3, 0x25e4, 0x25e5, + 0x2609, 0x2295, 0x3012, 0x301d, 0x301e, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xa9 */ + 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, 0x3027, 0x3028, + 0x3029, 0x32a3, 0x338e, 0x338f, 0x339c, 0x339d, 0x339e, 0x33a1, + 0x33c4, 0x33ce, 0x33d1, 0x33d2, 0x33d5, 0xfe30, 0xffe2, 0xffe4, + 0xfffd, 0x2121, 0x3231, 0xfffd, 0x2010, 0xfffd, 0xfffd, 0xfffd, + 0x30fc, 0x309b, 0x309c, 0x30fd, 0x30fe, 0x3006, 0x309d, 0x309e, + 0xfe49, 0xfe4a, 0xfe4b, 0xfe4c, 0xfe4d, 0xfe4e, 0xfe4f, 0xfe50, + 0xfe51, 0xfe52, 0xfe54, 0xfe55, 0xfe56, 0xfe57, 0xfe59, 0xfe5a, + 0xfe5b, 0xfe5c, 0xfe5d, 0xfe5e, 0xfe5f, 0xfe60, 0xfe61, 0xfe62, + 0xfe63, 0xfe64, 0xfe65, 0xfe66, 0xfe68, 0xfe69, 0xfe6a, 0xfe6b, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x3007, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xaa */ + 0x72dc, 0x72dd, 0x72df, 0x72e2, 0x72e3, 0x72e4, 0x72e5, 0x72e6, + 0x72e7, 0x72ea, 0x72eb, 0x72f5, 0x72f6, 0x72f9, 0x72fd, 0x72fe, + 0x72ff, 0x7300, 0x7302, 0x7304, 0x7305, 0x7306, 0x7307, 0x7308, + 0x7309, 0x730b, 0x730c, 0x730d, 0x730f, 0x7310, 0x7311, 0x7312, + 0x7314, 0x7318, 0x7319, 0x731a, 0x731f, 0x7320, 0x7323, 0x7324, + 0x7326, 0x7327, 0x7328, 0x732d, 0x732f, 0x7330, 0x7332, 0x7333, + 0x7335, 0x7336, 0x733a, 0x733b, 0x733c, 0x733d, 0x7340, 0x7341, + 0x7342, 0x7343, 0x7344, 0x7345, 0x7346, 0x7347, 0x7348, 0x7349, + 0x734a, 0x734b, 0x734c, 0x734e, 0x734f, 0x7351, 0x7353, 0x7354, + 0x7355, 0x7356, 0x7358, 0x7359, 0x735a, 0x735b, 0x735c, 0x735d, + 0x735e, 0x735f, 0x7361, 0x7362, 0x7363, 0x7364, 0x7365, 0x7366, + 0x7367, 0x7368, 0x7369, 0x736a, 0x736b, 0x736e, 0x7370, 0x7371, + /* 0xab */ + 0x7372, 0x7373, 0x7374, 0x7375, 0x7376, 0x7377, 0x7378, 0x7379, + 0x737a, 0x737b, 0x737c, 0x737d, 0x737f, 0x7380, 0x7381, 0x7382, + 0x7383, 0x7385, 0x7386, 0x7388, 0x738a, 0x738c, 0x738d, 0x738f, + 0x7390, 0x7392, 0x7393, 0x7394, 0x7395, 0x7397, 0x7398, 0x7399, + 0x739a, 0x739c, 0x739d, 0x739e, 0x73a0, 0x73a1, 0x73a3, 0x73a4, + 0x73a5, 0x73a6, 0x73a7, 0x73a8, 0x73aa, 0x73ac, 0x73ad, 0x73b1, + 0x73b4, 0x73b5, 0x73b6, 0x73b8, 0x73b9, 0x73bc, 0x73bd, 0x73be, + 0x73bf, 0x73c1, 0x73c3, 0x73c4, 0x73c5, 0x73c6, 0x73c7, 0x73cb, + 0x73cc, 0x73ce, 0x73d2, 0x73d3, 0x73d4, 0x73d5, 0x73d6, 0x73d7, + 0x73d8, 0x73da, 0x73db, 0x73dc, 0x73dd, 0x73df, 0x73e1, 0x73e2, + 0x73e3, 0x73e4, 0x73e6, 0x73e8, 0x73ea, 0x73eb, 0x73ec, 0x73ee, + 0x73ef, 0x73f0, 0x73f1, 0x73f3, 0x73f4, 0x73f5, 0x73f6, 0x73f7, + /* 0xac */ + 0x73f8, 0x73f9, 0x73fa, 0x73fb, 0x73fc, 0x73fd, 0x73fe, 0x73ff, + 0x7400, 0x7401, 0x7402, 0x7404, 0x7407, 0x7408, 0x740b, 0x740c, + 0x740d, 0x740e, 0x7411, 0x7412, 0x7413, 0x7414, 0x7415, 0x7416, + 0x7417, 0x7418, 0x7419, 0x741c, 0x741d, 0x741e, 0x741f, 0x7420, + 0x7421, 0x7423, 0x7424, 0x7427, 0x7429, 0x742b, 0x742d, 0x742f, + 0x7431, 0x7432, 0x7437, 0x7438, 0x7439, 0x743a, 0x743b, 0x743d, + 0x743e, 0x743f, 0x7440, 0x7442, 0x7443, 0x7444, 0x7445, 0x7446, + 0x7447, 0x7448, 0x7449, 0x744a, 0x744b, 0x744c, 0x744d, 0x744e, + 0x744f, 0x7450, 0x7451, 0x7452, 0x7453, 0x7454, 0x7456, 0x7458, + 0x745d, 0x7460, 0x7461, 0x7462, 0x7463, 0x7464, 0x7465, 0x7466, + 0x7467, 0x7468, 0x7469, 0x746a, 0x746b, 0x746c, 0x746e, 0x746f, + 0x7471, 0x7472, 0x7473, 0x7474, 0x7475, 0x7478, 0x7479, 0x747a, + /* 0xad */ + 0x747b, 0x747c, 0x747d, 0x747f, 0x7482, 0x7484, 0x7485, 0x7486, + 0x7488, 0x7489, 0x748a, 0x748c, 0x748d, 0x748f, 0x7491, 0x7492, + 0x7493, 0x7494, 0x7495, 0x7496, 0x7497, 0x7498, 0x7499, 0x749a, + 0x749b, 0x749d, 0x749f, 0x74a0, 0x74a1, 0x74a2, 0x74a3, 0x74a4, + 0x74a5, 0x74a6, 0x74aa, 0x74ab, 0x74ac, 0x74ad, 0x74ae, 0x74af, + 0x74b0, 0x74b1, 0x74b2, 0x74b3, 0x74b4, 0x74b5, 0x74b6, 0x74b7, + 0x74b8, 0x74b9, 0x74bb, 0x74bc, 0x74bd, 0x74be, 0x74bf, 0x74c0, + 0x74c1, 0x74c2, 0x74c3, 0x74c4, 0x74c5, 0x74c6, 0x74c7, 0x74c8, + 0x74c9, 0x74ca, 0x74cb, 0x74cc, 0x74cd, 0x74ce, 0x74cf, 0x74d0, + 0x74d1, 0x74d3, 0x74d4, 0x74d5, 0x74d6, 0x74d7, 0x74d8, 0x74d9, + 0x74da, 0x74db, 0x74dd, 0x74df, 0x74e1, 0x74e5, 0x74e7, 0x74e8, + 0x74e9, 0x74ea, 0x74eb, 0x74ec, 0x74ed, 0x74f0, 0x74f1, 0x74f2, + /* 0xae */ + 0x74f3, 0x74f5, 0x74f8, 0x74f9, 0x74fa, 0x74fb, 0x74fc, 0x74fd, + 0x74fe, 0x7500, 0x7501, 0x7502, 0x7503, 0x7505, 0x7506, 0x7507, + 0x7508, 0x7509, 0x750a, 0x750b, 0x750c, 0x750e, 0x7510, 0x7512, + 0x7514, 0x7515, 0x7516, 0x7517, 0x751b, 0x751d, 0x751e, 0x7520, + 0x7521, 0x7522, 0x7523, 0x7524, 0x7526, 0x7527, 0x752a, 0x752e, + 0x7534, 0x7536, 0x7539, 0x753c, 0x753d, 0x753f, 0x7541, 0x7542, + 0x7543, 0x7544, 0x7546, 0x7547, 0x7549, 0x754a, 0x754d, 0x7550, + 0x7551, 0x7552, 0x7553, 0x7555, 0x7556, 0x7557, 0x7558, 0x755d, + 0x755e, 0x755f, 0x7560, 0x7561, 0x7562, 0x7563, 0x7564, 0x7567, + 0x7568, 0x7569, 0x756b, 0x756c, 0x756d, 0x756e, 0x756f, 0x7570, + 0x7571, 0x7573, 0x7575, 0x7576, 0x7577, 0x757a, 0x757b, 0x757c, + 0x757d, 0x757e, 0x7580, 0x7581, 0x7582, 0x7584, 0x7585, 0x7587, + /* 0xaf */ + 0x7588, 0x7589, 0x758a, 0x758c, 0x758d, 0x758e, 0x7590, 0x7593, + 0x7595, 0x7598, 0x759b, 0x759c, 0x759e, 0x75a2, 0x75a6, 0x75a7, + 0x75a8, 0x75a9, 0x75aa, 0x75ad, 0x75b6, 0x75b7, 0x75ba, 0x75bb, + 0x75bf, 0x75c0, 0x75c1, 0x75c6, 0x75cb, 0x75cc, 0x75ce, 0x75cf, + 0x75d0, 0x75d1, 0x75d3, 0x75d7, 0x75d9, 0x75da, 0x75dc, 0x75dd, + 0x75df, 0x75e0, 0x75e1, 0x75e5, 0x75e9, 0x75ec, 0x75ed, 0x75ee, + 0x75ef, 0x75f2, 0x75f3, 0x75f5, 0x75f6, 0x75f7, 0x75f8, 0x75fa, + 0x75fb, 0x75fd, 0x75fe, 0x7602, 0x7604, 0x7606, 0x7607, 0x7608, + 0x7609, 0x760b, 0x760d, 0x760e, 0x760f, 0x7611, 0x7612, 0x7613, + 0x7614, 0x7616, 0x761a, 0x761c, 0x761d, 0x761e, 0x7621, 0x7623, + 0x7627, 0x7628, 0x762c, 0x762e, 0x762f, 0x7631, 0x7632, 0x7636, + 0x7637, 0x7639, 0x763a, 0x763b, 0x763d, 0x7641, 0x7642, 0x7644, + /* 0xb0 */ + 0x7645, 0x7646, 0x7647, 0x7648, 0x7649, 0x764a, 0x764b, 0x764e, + 0x764f, 0x7650, 0x7651, 0x7652, 0x7653, 0x7655, 0x7657, 0x7658, + 0x7659, 0x765a, 0x765b, 0x765d, 0x765f, 0x7660, 0x7661, 0x7662, + 0x7664, 0x7665, 0x7666, 0x7667, 0x7668, 0x7669, 0x766a, 0x766c, + 0x766d, 0x766e, 0x7670, 0x7671, 0x7672, 0x7673, 0x7674, 0x7675, + 0x7676, 0x7677, 0x7679, 0x767a, 0x767c, 0x767f, 0x7680, 0x7681, + 0x7683, 0x7685, 0x7689, 0x768a, 0x768c, 0x768d, 0x768f, 0x7690, + 0x7692, 0x7694, 0x7695, 0x7697, 0x7698, 0x769a, 0x769b, 0x769c, + 0x769d, 0x769e, 0x769f, 0x76a0, 0x76a1, 0x76a2, 0x76a3, 0x76a5, + 0x76a6, 0x76a7, 0x76a8, 0x76a9, 0x76aa, 0x76ab, 0x76ac, 0x76ad, + 0x76af, 0x76b0, 0x76b3, 0x76b5, 0x76b6, 0x76b7, 0x76b8, 0x76b9, + 0x76ba, 0x76bb, 0x76bc, 0x76bd, 0x76be, 0x76c0, 0x76c1, 0x76c3, + /* 0xb1 */ + 0x76c4, 0x76c7, 0x76c9, 0x76cb, 0x76cc, 0x76d3, 0x76d5, 0x76d9, + 0x76da, 0x76dc, 0x76dd, 0x76de, 0x76e0, 0x76e1, 0x76e2, 0x76e3, + 0x76e4, 0x76e6, 0x76e7, 0x76e8, 0x76e9, 0x76ea, 0x76eb, 0x76ec, + 0x76ed, 0x76f0, 0x76f3, 0x76f5, 0x76f6, 0x76f7, 0x76fa, 0x76fb, + 0x76fd, 0x76ff, 0x7700, 0x7702, 0x7703, 0x7705, 0x7706, 0x770a, + 0x770c, 0x770e, 0x770f, 0x7710, 0x7711, 0x7712, 0x7713, 0x7714, + 0x7715, 0x7716, 0x7717, 0x7718, 0x771b, 0x771c, 0x771d, 0x771e, + 0x7721, 0x7723, 0x7724, 0x7725, 0x7727, 0x772a, 0x772b, 0x772c, + 0x772e, 0x7730, 0x7731, 0x7732, 0x7733, 0x7734, 0x7739, 0x773b, + 0x773d, 0x773e, 0x773f, 0x7742, 0x7744, 0x7745, 0x7746, 0x7748, + 0x7749, 0x774a, 0x774b, 0x774c, 0x774d, 0x774e, 0x774f, 0x7752, + 0x7753, 0x7754, 0x7755, 0x7756, 0x7757, 0x7758, 0x7759, 0x775c, + /* 0xb2 */ + 0x775d, 0x775e, 0x775f, 0x7760, 0x7764, 0x7767, 0x7769, 0x776a, + 0x776d, 0x776e, 0x776f, 0x7770, 0x7771, 0x7772, 0x7773, 0x7774, + 0x7775, 0x7776, 0x7777, 0x7778, 0x777a, 0x777b, 0x777c, 0x7781, + 0x7782, 0x7783, 0x7786, 0x7787, 0x7788, 0x7789, 0x778a, 0x778b, + 0x778f, 0x7790, 0x7793, 0x7794, 0x7795, 0x7796, 0x7797, 0x7798, + 0x7799, 0x779a, 0x779b, 0x779c, 0x779d, 0x779e, 0x77a1, 0x77a3, + 0x77a4, 0x77a6, 0x77a8, 0x77ab, 0x77ad, 0x77ae, 0x77af, 0x77b1, + 0x77b2, 0x77b4, 0x77b6, 0x77b7, 0x77b8, 0x77b9, 0x77ba, 0x77bc, + 0x77be, 0x77c0, 0x77c1, 0x77c2, 0x77c3, 0x77c4, 0x77c5, 0x77c6, + 0x77c7, 0x77c8, 0x77c9, 0x77ca, 0x77cb, 0x77cc, 0x77ce, 0x77cf, + 0x77d0, 0x77d1, 0x77d2, 0x77d3, 0x77d4, 0x77d5, 0x77d6, 0x77d8, + 0x77d9, 0x77da, 0x77dd, 0x77de, 0x77df, 0x77e0, 0x77e1, 0x77e4, + /* 0xb3 */ + 0x77e6, 0x77e8, 0x77ea, 0x77ef, 0x77f0, 0x77f1, 0x77f2, 0x77f4, + 0x77f5, 0x77f7, 0x77f9, 0x77fa, 0x77fb, 0x77fc, 0x7803, 0x7804, + 0x7805, 0x7806, 0x7807, 0x7808, 0x780a, 0x780b, 0x780e, 0x780f, + 0x7810, 0x7813, 0x7815, 0x7819, 0x781b, 0x781e, 0x7820, 0x7821, + 0x7822, 0x7824, 0x7828, 0x782a, 0x782b, 0x782e, 0x782f, 0x7831, + 0x7832, 0x7833, 0x7835, 0x7836, 0x783d, 0x783f, 0x7841, 0x7842, + 0x7843, 0x7844, 0x7846, 0x7848, 0x7849, 0x784a, 0x784b, 0x784d, + 0x784f, 0x7851, 0x7853, 0x7854, 0x7858, 0x7859, 0x785a, 0x785b, + 0x785c, 0x785e, 0x785f, 0x7860, 0x7861, 0x7862, 0x7863, 0x7864, + 0x7865, 0x7866, 0x7867, 0x7868, 0x7869, 0x786f, 0x7870, 0x7871, + 0x7872, 0x7873, 0x7874, 0x7875, 0x7876, 0x7878, 0x7879, 0x787a, + 0x787b, 0x787d, 0x787e, 0x787f, 0x7880, 0x7881, 0x7882, 0x7883, + /* 0xb4 */ + 0x7884, 0x7885, 0x7886, 0x7888, 0x788a, 0x788b, 0x788f, 0x7890, + 0x7892, 0x7894, 0x7895, 0x7896, 0x7899, 0x789d, 0x789e, 0x78a0, + 0x78a2, 0x78a4, 0x78a6, 0x78a8, 0x78a9, 0x78aa, 0x78ab, 0x78ac, + 0x78ad, 0x78ae, 0x78af, 0x78b5, 0x78b6, 0x78b7, 0x78b8, 0x78ba, + 0x78bb, 0x78bc, 0x78bd, 0x78bf, 0x78c0, 0x78c2, 0x78c3, 0x78c4, + 0x78c6, 0x78c7, 0x78c8, 0x78cc, 0x78cd, 0x78ce, 0x78cf, 0x78d1, + 0x78d2, 0x78d3, 0x78d6, 0x78d7, 0x78d8, 0x78da, 0x78db, 0x78dc, + 0x78dd, 0x78de, 0x78df, 0x78e0, 0x78e1, 0x78e2, 0x78e3, 0x78e4, + 0x78e5, 0x78e6, 0x78e7, 0x78e9, 0x78ea, 0x78eb, 0x78ed, 0x78ee, + 0x78ef, 0x78f0, 0x78f1, 0x78f3, 0x78f5, 0x78f6, 0x78f8, 0x78f9, + 0x78fb, 0x78fc, 0x78fd, 0x78fe, 0x78ff, 0x7900, 0x7902, 0x7903, + 0x7904, 0x7906, 0x7907, 0x7908, 0x7909, 0x790a, 0x790b, 0x790c, + /* 0xb5 */ + 0x790d, 0x790e, 0x790f, 0x7910, 0x7911, 0x7912, 0x7914, 0x7915, + 0x7916, 0x7917, 0x7918, 0x7919, 0x791a, 0x791b, 0x791c, 0x791d, + 0x791f, 0x7920, 0x7921, 0x7922, 0x7923, 0x7925, 0x7926, 0x7927, + 0x7928, 0x7929, 0x792a, 0x792b, 0x792c, 0x792d, 0x792e, 0x792f, + 0x7930, 0x7931, 0x7932, 0x7933, 0x7935, 0x7936, 0x7937, 0x7938, + 0x7939, 0x793d, 0x793f, 0x7942, 0x7943, 0x7944, 0x7945, 0x7947, + 0x794a, 0x794b, 0x794c, 0x794d, 0x794e, 0x794f, 0x7950, 0x7951, + 0x7952, 0x7954, 0x7955, 0x7958, 0x7959, 0x7961, 0x7963, 0x7964, + 0x7966, 0x7969, 0x796a, 0x796b, 0x796c, 0x796e, 0x7970, 0x7971, + 0x7972, 0x7973, 0x7974, 0x7975, 0x7976, 0x7979, 0x797b, 0x797c, + 0x797d, 0x797e, 0x797f, 0x7982, 0x7983, 0x7986, 0x7987, 0x7988, + 0x7989, 0x798b, 0x798c, 0x798d, 0x798e, 0x7990, 0x7991, 0x7992, + /* 0xb6 */ + 0x7993, 0x7994, 0x7995, 0x7996, 0x7997, 0x7998, 0x7999, 0x799b, + 0x799c, 0x799d, 0x799e, 0x799f, 0x79a0, 0x79a1, 0x79a2, 0x79a3, + 0x79a4, 0x79a5, 0x79a6, 0x79a8, 0x79a9, 0x79aa, 0x79ab, 0x79ac, + 0x79ad, 0x79ae, 0x79af, 0x79b0, 0x79b1, 0x79b2, 0x79b4, 0x79b5, + 0x79b6, 0x79b7, 0x79b8, 0x79bc, 0x79bf, 0x79c2, 0x79c4, 0x79c5, + 0x79c7, 0x79c8, 0x79ca, 0x79cc, 0x79ce, 0x79cf, 0x79d0, 0x79d3, + 0x79d4, 0x79d6, 0x79d7, 0x79d9, 0x79da, 0x79db, 0x79dc, 0x79dd, + 0x79de, 0x79e0, 0x79e1, 0x79e2, 0x79e5, 0x79e8, 0x79ea, 0x79ec, + 0x79ee, 0x79f1, 0x79f2, 0x79f3, 0x79f4, 0x79f5, 0x79f6, 0x79f7, + 0x79f9, 0x79fa, 0x79fc, 0x79fe, 0x79ff, 0x7a01, 0x7a04, 0x7a05, + 0x7a07, 0x7a08, 0x7a09, 0x7a0a, 0x7a0c, 0x7a0f, 0x7a10, 0x7a11, + 0x7a12, 0x7a13, 0x7a15, 0x7a16, 0x7a18, 0x7a19, 0x7a1b, 0x7a1c, + /* 0xb7 */ + 0x7a1d, 0x7a1f, 0x7a21, 0x7a22, 0x7a24, 0x7a25, 0x7a26, 0x7a27, + 0x7a28, 0x7a29, 0x7a2a, 0x7a2b, 0x7a2c, 0x7a2d, 0x7a2e, 0x7a2f, + 0x7a30, 0x7a31, 0x7a32, 0x7a34, 0x7a35, 0x7a36, 0x7a38, 0x7a3a, + 0x7a3e, 0x7a40, 0x7a41, 0x7a42, 0x7a43, 0x7a44, 0x7a45, 0x7a47, + 0x7a48, 0x7a49, 0x7a4a, 0x7a4b, 0x7a4c, 0x7a4d, 0x7a4e, 0x7a4f, + 0x7a50, 0x7a52, 0x7a53, 0x7a54, 0x7a55, 0x7a56, 0x7a58, 0x7a59, + 0x7a5a, 0x7a5b, 0x7a5c, 0x7a5d, 0x7a5e, 0x7a5f, 0x7a60, 0x7a61, + 0x7a62, 0x7a63, 0x7a64, 0x7a65, 0x7a66, 0x7a67, 0x7a68, 0x7a69, + 0x7a6a, 0x7a6b, 0x7a6c, 0x7a6d, 0x7a6e, 0x7a6f, 0x7a71, 0x7a72, + 0x7a73, 0x7a75, 0x7a7b, 0x7a7c, 0x7a7d, 0x7a7e, 0x7a82, 0x7a85, + 0x7a87, 0x7a89, 0x7a8a, 0x7a8b, 0x7a8c, 0x7a8e, 0x7a8f, 0x7a90, + 0x7a93, 0x7a94, 0x7a99, 0x7a9a, 0x7a9b, 0x7a9e, 0x7aa1, 0x7aa2, + /* 0xb8 */ + 0x7aa3, 0x7aa4, 0x7aa7, 0x7aa9, 0x7aaa, 0x7aab, 0x7aae, 0x7aaf, + 0x7ab0, 0x7ab1, 0x7ab2, 0x7ab4, 0x7ab5, 0x7ab6, 0x7ab7, 0x7ab8, + 0x7ab9, 0x7aba, 0x7abb, 0x7abc, 0x7abd, 0x7abe, 0x7ac0, 0x7ac1, + 0x7ac2, 0x7ac3, 0x7ac4, 0x7ac5, 0x7ac6, 0x7ac7, 0x7ac8, 0x7ac9, + 0x7aca, 0x7acc, 0x7acd, 0x7ace, 0x7acf, 0x7ad0, 0x7ad1, 0x7ad2, + 0x7ad3, 0x7ad4, 0x7ad5, 0x7ad7, 0x7ad8, 0x7ada, 0x7adb, 0x7adc, + 0x7add, 0x7ae1, 0x7ae2, 0x7ae4, 0x7ae7, 0x7ae8, 0x7ae9, 0x7aea, + 0x7aeb, 0x7aec, 0x7aee, 0x7af0, 0x7af1, 0x7af2, 0x7af3, 0x7af4, + 0x7af5, 0x7af6, 0x7af7, 0x7af8, 0x7afb, 0x7afc, 0x7afe, 0x7b00, + 0x7b01, 0x7b02, 0x7b05, 0x7b07, 0x7b09, 0x7b0c, 0x7b0d, 0x7b0e, + 0x7b10, 0x7b12, 0x7b13, 0x7b16, 0x7b17, 0x7b18, 0x7b1a, 0x7b1c, + 0x7b1d, 0x7b1f, 0x7b21, 0x7b22, 0x7b23, 0x7b27, 0x7b29, 0x7b2d, + /* 0xb9 */ + 0x7b2f, 0x7b30, 0x7b32, 0x7b34, 0x7b35, 0x7b36, 0x7b37, 0x7b39, + 0x7b3b, 0x7b3d, 0x7b3f, 0x7b40, 0x7b41, 0x7b42, 0x7b43, 0x7b44, + 0x7b46, 0x7b48, 0x7b4a, 0x7b4d, 0x7b4e, 0x7b53, 0x7b55, 0x7b57, + 0x7b59, 0x7b5c, 0x7b5e, 0x7b5f, 0x7b61, 0x7b63, 0x7b64, 0x7b65, + 0x7b66, 0x7b67, 0x7b68, 0x7b69, 0x7b6a, 0x7b6b, 0x7b6c, 0x7b6d, + 0x7b6f, 0x7b70, 0x7b73, 0x7b74, 0x7b76, 0x7b78, 0x7b7a, 0x7b7c, + 0x7b7d, 0x7b7f, 0x7b81, 0x7b82, 0x7b83, 0x7b84, 0x7b86, 0x7b87, + 0x7b88, 0x7b89, 0x7b8a, 0x7b8b, 0x7b8c, 0x7b8e, 0x7b8f, 0x7b91, + 0x7b92, 0x7b93, 0x7b96, 0x7b98, 0x7b99, 0x7b9a, 0x7b9b, 0x7b9e, + 0x7b9f, 0x7ba0, 0x7ba3, 0x7ba4, 0x7ba5, 0x7bae, 0x7baf, 0x7bb0, + 0x7bb2, 0x7bb3, 0x7bb5, 0x7bb6, 0x7bb7, 0x7bb9, 0x7bba, 0x7bbb, + 0x7bbc, 0x7bbd, 0x7bbe, 0x7bbf, 0x7bc0, 0x7bc2, 0x7bc3, 0x7bc4, + /* 0xba */ + 0x7bc5, 0x7bc8, 0x7bc9, 0x7bca, 0x7bcb, 0x7bcd, 0x7bce, 0x7bcf, + 0x7bd0, 0x7bd2, 0x7bd4, 0x7bd5, 0x7bd6, 0x7bd7, 0x7bd8, 0x7bdb, + 0x7bdc, 0x7bde, 0x7bdf, 0x7be0, 0x7be2, 0x7be3, 0x7be4, 0x7be7, + 0x7be8, 0x7be9, 0x7beb, 0x7bec, 0x7bed, 0x7bef, 0x7bf0, 0x7bf2, + 0x7bf3, 0x7bf4, 0x7bf5, 0x7bf6, 0x7bf8, 0x7bf9, 0x7bfa, 0x7bfb, + 0x7bfd, 0x7bff, 0x7c00, 0x7c01, 0x7c02, 0x7c03, 0x7c04, 0x7c05, + 0x7c06, 0x7c08, 0x7c09, 0x7c0a, 0x7c0d, 0x7c0e, 0x7c10, 0x7c11, + 0x7c12, 0x7c13, 0x7c14, 0x7c15, 0x7c17, 0x7c18, 0x7c19, 0x7c1a, + 0x7c1b, 0x7c1c, 0x7c1d, 0x7c1e, 0x7c20, 0x7c21, 0x7c22, 0x7c23, + 0x7c24, 0x7c25, 0x7c28, 0x7c29, 0x7c2b, 0x7c2c, 0x7c2d, 0x7c2e, + 0x7c2f, 0x7c30, 0x7c31, 0x7c32, 0x7c33, 0x7c34, 0x7c35, 0x7c36, + 0x7c37, 0x7c39, 0x7c3a, 0x7c3b, 0x7c3c, 0x7c3d, 0x7c3e, 0x7c42, + /* 0xbb */ + 0x7c43, 0x7c44, 0x7c45, 0x7c46, 0x7c47, 0x7c48, 0x7c49, 0x7c4a, + 0x7c4b, 0x7c4c, 0x7c4e, 0x7c4f, 0x7c50, 0x7c51, 0x7c52, 0x7c53, + 0x7c54, 0x7c55, 0x7c56, 0x7c57, 0x7c58, 0x7c59, 0x7c5a, 0x7c5b, + 0x7c5c, 0x7c5d, 0x7c5e, 0x7c5f, 0x7c60, 0x7c61, 0x7c62, 0x7c63, + 0x7c64, 0x7c65, 0x7c66, 0x7c67, 0x7c68, 0x7c69, 0x7c6a, 0x7c6b, + 0x7c6c, 0x7c6d, 0x7c6e, 0x7c6f, 0x7c70, 0x7c71, 0x7c72, 0x7c75, + 0x7c76, 0x7c77, 0x7c78, 0x7c79, 0x7c7a, 0x7c7e, 0x7c7f, 0x7c80, + 0x7c81, 0x7c82, 0x7c83, 0x7c84, 0x7c85, 0x7c86, 0x7c87, 0x7c88, + 0x7c8a, 0x7c8b, 0x7c8c, 0x7c8d, 0x7c8e, 0x7c8f, 0x7c90, 0x7c93, + 0x7c94, 0x7c96, 0x7c99, 0x7c9a, 0x7c9b, 0x7ca0, 0x7ca1, 0x7ca3, + 0x7ca6, 0x7ca7, 0x7ca8, 0x7ca9, 0x7cab, 0x7cac, 0x7cad, 0x7caf, + 0x7cb0, 0x7cb4, 0x7cb5, 0x7cb6, 0x7cb7, 0x7cb8, 0x7cba, 0x7cbb, + /* 0xbc */ + 0x7cbf, 0x7cc0, 0x7cc2, 0x7cc3, 0x7cc4, 0x7cc6, 0x7cc9, 0x7ccb, + 0x7cce, 0x7ccf, 0x7cd0, 0x7cd1, 0x7cd2, 0x7cd3, 0x7cd4, 0x7cd8, + 0x7cda, 0x7cdb, 0x7cdd, 0x7cde, 0x7ce1, 0x7ce2, 0x7ce3, 0x7ce4, + 0x7ce5, 0x7ce6, 0x7ce7, 0x7ce9, 0x7cea, 0x7ceb, 0x7cec, 0x7ced, + 0x7cee, 0x7cf0, 0x7cf1, 0x7cf2, 0x7cf3, 0x7cf4, 0x7cf5, 0x7cf6, + 0x7cf7, 0x7cf9, 0x7cfa, 0x7cfc, 0x7cfd, 0x7cfe, 0x7cff, 0x7d00, + 0x7d01, 0x7d02, 0x7d03, 0x7d04, 0x7d05, 0x7d06, 0x7d07, 0x7d08, + 0x7d09, 0x7d0b, 0x7d0c, 0x7d0d, 0x7d0e, 0x7d0f, 0x7d10, 0x7d11, + 0x7d12, 0x7d13, 0x7d14, 0x7d15, 0x7d16, 0x7d17, 0x7d18, 0x7d19, + 0x7d1a, 0x7d1b, 0x7d1c, 0x7d1d, 0x7d1e, 0x7d1f, 0x7d21, 0x7d23, + 0x7d24, 0x7d25, 0x7d26, 0x7d28, 0x7d29, 0x7d2a, 0x7d2c, 0x7d2d, + 0x7d2e, 0x7d30, 0x7d31, 0x7d32, 0x7d33, 0x7d34, 0x7d35, 0x7d36, + /* 0xbd */ + 0x7d37, 0x7d38, 0x7d39, 0x7d3a, 0x7d3b, 0x7d3c, 0x7d3d, 0x7d3e, + 0x7d3f, 0x7d40, 0x7d41, 0x7d42, 0x7d43, 0x7d44, 0x7d45, 0x7d46, + 0x7d47, 0x7d48, 0x7d49, 0x7d4a, 0x7d4b, 0x7d4c, 0x7d4d, 0x7d4e, + 0x7d4f, 0x7d50, 0x7d51, 0x7d52, 0x7d53, 0x7d54, 0x7d55, 0x7d56, + 0x7d57, 0x7d58, 0x7d59, 0x7d5a, 0x7d5b, 0x7d5c, 0x7d5d, 0x7d5e, + 0x7d5f, 0x7d60, 0x7d61, 0x7d62, 0x7d63, 0x7d64, 0x7d65, 0x7d66, + 0x7d67, 0x7d68, 0x7d69, 0x7d6a, 0x7d6b, 0x7d6c, 0x7d6d, 0x7d6f, + 0x7d70, 0x7d71, 0x7d72, 0x7d73, 0x7d74, 0x7d75, 0x7d76, 0x7d78, + 0x7d79, 0x7d7a, 0x7d7b, 0x7d7c, 0x7d7d, 0x7d7e, 0x7d7f, 0x7d80, + 0x7d81, 0x7d82, 0x7d83, 0x7d84, 0x7d85, 0x7d86, 0x7d87, 0x7d88, + 0x7d89, 0x7d8a, 0x7d8b, 0x7d8c, 0x7d8d, 0x7d8e, 0x7d8f, 0x7d90, + 0x7d91, 0x7d92, 0x7d93, 0x7d94, 0x7d95, 0x7d96, 0x7d97, 0x7d98, + /* 0xbe */ + 0x7d99, 0x7d9a, 0x7d9b, 0x7d9c, 0x7d9d, 0x7d9e, 0x7d9f, 0x7da0, + 0x7da1, 0x7da2, 0x7da3, 0x7da4, 0x7da5, 0x7da7, 0x7da8, 0x7da9, + 0x7daa, 0x7dab, 0x7dac, 0x7dad, 0x7daf, 0x7db0, 0x7db1, 0x7db2, + 0x7db3, 0x7db4, 0x7db5, 0x7db6, 0x7db7, 0x7db8, 0x7db9, 0x7dba, + 0x7dbb, 0x7dbc, 0x7dbd, 0x7dbe, 0x7dbf, 0x7dc0, 0x7dc1, 0x7dc2, + 0x7dc3, 0x7dc4, 0x7dc5, 0x7dc6, 0x7dc7, 0x7dc8, 0x7dc9, 0x7dca, + 0x7dcb, 0x7dcc, 0x7dcd, 0x7dce, 0x7dcf, 0x7dd0, 0x7dd1, 0x7dd2, + 0x7dd3, 0x7dd4, 0x7dd5, 0x7dd6, 0x7dd7, 0x7dd8, 0x7dd9, 0x7dda, + 0x7ddb, 0x7ddc, 0x7ddd, 0x7dde, 0x7ddf, 0x7de0, 0x7de1, 0x7de2, + 0x7de3, 0x7de4, 0x7de5, 0x7de6, 0x7de7, 0x7de8, 0x7de9, 0x7dea, + 0x7deb, 0x7dec, 0x7ded, 0x7dee, 0x7def, 0x7df0, 0x7df1, 0x7df2, + 0x7df3, 0x7df4, 0x7df5, 0x7df6, 0x7df7, 0x7df8, 0x7df9, 0x7dfa, + /* 0xbf */ + 0x7dfb, 0x7dfc, 0x7dfd, 0x7dfe, 0x7dff, 0x7e00, 0x7e01, 0x7e02, + 0x7e03, 0x7e04, 0x7e05, 0x7e06, 0x7e07, 0x7e08, 0x7e09, 0x7e0a, + 0x7e0b, 0x7e0c, 0x7e0d, 0x7e0e, 0x7e0f, 0x7e10, 0x7e11, 0x7e12, + 0x7e13, 0x7e14, 0x7e15, 0x7e16, 0x7e17, 0x7e18, 0x7e19, 0x7e1a, + 0x7e1b, 0x7e1c, 0x7e1d, 0x7e1e, 0x7e1f, 0x7e20, 0x7e21, 0x7e22, + 0x7e23, 0x7e24, 0x7e25, 0x7e26, 0x7e27, 0x7e28, 0x7e29, 0x7e2a, + 0x7e2b, 0x7e2c, 0x7e2d, 0x7e2e, 0x7e2f, 0x7e30, 0x7e31, 0x7e32, + 0x7e33, 0x7e34, 0x7e35, 0x7e36, 0x7e37, 0x7e38, 0x7e39, 0x7e3a, + 0x7e3c, 0x7e3d, 0x7e3e, 0x7e3f, 0x7e40, 0x7e42, 0x7e43, 0x7e44, + 0x7e45, 0x7e46, 0x7e48, 0x7e49, 0x7e4a, 0x7e4b, 0x7e4c, 0x7e4d, + 0x7e4e, 0x7e4f, 0x7e50, 0x7e51, 0x7e52, 0x7e53, 0x7e54, 0x7e55, + 0x7e56, 0x7e57, 0x7e58, 0x7e59, 0x7e5a, 0x7e5b, 0x7e5c, 0x7e5d, + /* 0xc0 */ + 0x7e5e, 0x7e5f, 0x7e60, 0x7e61, 0x7e62, 0x7e63, 0x7e64, 0x7e65, + 0x7e66, 0x7e67, 0x7e68, 0x7e69, 0x7e6a, 0x7e6b, 0x7e6c, 0x7e6d, + 0x7e6e, 0x7e6f, 0x7e70, 0x7e71, 0x7e72, 0x7e73, 0x7e74, 0x7e75, + 0x7e76, 0x7e77, 0x7e78, 0x7e79, 0x7e7a, 0x7e7b, 0x7e7c, 0x7e7d, + 0x7e7e, 0x7e7f, 0x7e80, 0x7e81, 0x7e83, 0x7e84, 0x7e85, 0x7e86, + 0x7e87, 0x7e88, 0x7e89, 0x7e8a, 0x7e8b, 0x7e8c, 0x7e8d, 0x7e8e, + 0x7e8f, 0x7e90, 0x7e91, 0x7e92, 0x7e93, 0x7e94, 0x7e95, 0x7e96, + 0x7e97, 0x7e98, 0x7e99, 0x7e9a, 0x7e9c, 0x7e9d, 0x7e9e, 0x7eae, + 0x7eb4, 0x7ebb, 0x7ebc, 0x7ed6, 0x7ee4, 0x7eec, 0x7ef9, 0x7f0a, + 0x7f10, 0x7f1e, 0x7f37, 0x7f39, 0x7f3b, 0x7f3c, 0x7f3d, 0x7f3e, + 0x7f3f, 0x7f40, 0x7f41, 0x7f43, 0x7f46, 0x7f47, 0x7f48, 0x7f49, + 0x7f4a, 0x7f4b, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f4f, 0x7f52, 0x7f53, + /* 0xc1 */ + 0x7f56, 0x7f59, 0x7f5b, 0x7f5c, 0x7f5d, 0x7f5e, 0x7f60, 0x7f63, + 0x7f64, 0x7f65, 0x7f66, 0x7f67, 0x7f6b, 0x7f6c, 0x7f6d, 0x7f6f, + 0x7f70, 0x7f73, 0x7f75, 0x7f76, 0x7f77, 0x7f78, 0x7f7a, 0x7f7b, + 0x7f7c, 0x7f7d, 0x7f7f, 0x7f80, 0x7f82, 0x7f83, 0x7f84, 0x7f85, + 0x7f86, 0x7f87, 0x7f88, 0x7f89, 0x7f8b, 0x7f8d, 0x7f8f, 0x7f90, + 0x7f91, 0x7f92, 0x7f93, 0x7f95, 0x7f96, 0x7f97, 0x7f98, 0x7f99, + 0x7f9b, 0x7f9c, 0x7fa0, 0x7fa2, 0x7fa3, 0x7fa5, 0x7fa6, 0x7fa8, + 0x7fa9, 0x7faa, 0x7fab, 0x7fac, 0x7fad, 0x7fae, 0x7fb1, 0x7fb3, + 0x7fb4, 0x7fb5, 0x7fb6, 0x7fb7, 0x7fba, 0x7fbb, 0x7fbe, 0x7fc0, + 0x7fc2, 0x7fc3, 0x7fc4, 0x7fc6, 0x7fc7, 0x7fc8, 0x7fc9, 0x7fcb, + 0x7fcd, 0x7fcf, 0x7fd0, 0x7fd1, 0x7fd2, 0x7fd3, 0x7fd6, 0x7fd7, + 0x7fd9, 0x7fda, 0x7fdb, 0x7fdc, 0x7fdd, 0x7fde, 0x7fe2, 0x7fe3, + /* 0xc2 */ + 0x7fe4, 0x7fe7, 0x7fe8, 0x7fea, 0x7feb, 0x7fec, 0x7fed, 0x7fef, + 0x7ff2, 0x7ff4, 0x7ff5, 0x7ff6, 0x7ff7, 0x7ff8, 0x7ff9, 0x7ffa, + 0x7ffd, 0x7ffe, 0x7fff, 0x8002, 0x8007, 0x8008, 0x8009, 0x800a, + 0x800e, 0x800f, 0x8011, 0x8013, 0x801a, 0x801b, 0x801d, 0x801e, + 0x801f, 0x8021, 0x8023, 0x8024, 0x802b, 0x802c, 0x802d, 0x802e, + 0x802f, 0x8030, 0x8032, 0x8034, 0x8039, 0x803a, 0x803c, 0x803e, + 0x8040, 0x8041, 0x8044, 0x8045, 0x8047, 0x8048, 0x8049, 0x804e, + 0x804f, 0x8050, 0x8051, 0x8053, 0x8055, 0x8056, 0x8057, 0x8059, + 0x805b, 0x805c, 0x805d, 0x805e, 0x805f, 0x8060, 0x8061, 0x8062, + 0x8063, 0x8064, 0x8065, 0x8066, 0x8067, 0x8068, 0x806b, 0x806c, + 0x806d, 0x806e, 0x806f, 0x8070, 0x8072, 0x8073, 0x8074, 0x8075, + 0x8076, 0x8077, 0x8078, 0x8079, 0x807a, 0x807b, 0x807c, 0x807d, + /* 0xc3 */ + 0x807e, 0x8081, 0x8082, 0x8085, 0x8088, 0x808a, 0x808d, 0x808e, + 0x808f, 0x8090, 0x8091, 0x8092, 0x8094, 0x8095, 0x8097, 0x8099, + 0x809e, 0x80a3, 0x80a6, 0x80a7, 0x80a8, 0x80ac, 0x80b0, 0x80b3, + 0x80b5, 0x80b6, 0x80b8, 0x80b9, 0x80bb, 0x80c5, 0x80c7, 0x80c8, + 0x80c9, 0x80ca, 0x80cb, 0x80cf, 0x80d0, 0x80d1, 0x80d2, 0x80d3, + 0x80d4, 0x80d5, 0x80d8, 0x80df, 0x80e0, 0x80e2, 0x80e3, 0x80e6, + 0x80ee, 0x80f5, 0x80f7, 0x80f9, 0x80fb, 0x80fe, 0x80ff, 0x8100, + 0x8101, 0x8103, 0x8104, 0x8105, 0x8107, 0x8108, 0x810b, 0x810c, + 0x8115, 0x8117, 0x8119, 0x811b, 0x811c, 0x811d, 0x811f, 0x8120, + 0x8121, 0x8122, 0x8123, 0x8124, 0x8125, 0x8126, 0x8127, 0x8128, + 0x8129, 0x812a, 0x812b, 0x812d, 0x812e, 0x8130, 0x8133, 0x8134, + 0x8135, 0x8137, 0x8139, 0x813a, 0x813b, 0x813c, 0x813d, 0x813f, + /* 0xc4 */ + 0x8140, 0x8141, 0x8142, 0x8143, 0x8144, 0x8145, 0x8147, 0x8149, + 0x814d, 0x814e, 0x814f, 0x8152, 0x8156, 0x8157, 0x8158, 0x815b, + 0x815c, 0x815d, 0x815e, 0x815f, 0x8161, 0x8162, 0x8163, 0x8164, + 0x8166, 0x8168, 0x816a, 0x816b, 0x816c, 0x816f, 0x8172, 0x8173, + 0x8175, 0x8176, 0x8177, 0x8178, 0x8181, 0x8183, 0x8184, 0x8185, + 0x8186, 0x8187, 0x8189, 0x818b, 0x818c, 0x818d, 0x818e, 0x8190, + 0x8192, 0x8193, 0x8194, 0x8195, 0x8196, 0x8197, 0x8199, 0x819a, + 0x819e, 0x819f, 0x81a0, 0x81a1, 0x81a2, 0x81a4, 0x81a5, 0x81a7, + 0x81a9, 0x81ab, 0x81ac, 0x81ad, 0x81ae, 0x81af, 0x81b0, 0x81b1, + 0x81b2, 0x81b4, 0x81b5, 0x81b6, 0x81b7, 0x81b8, 0x81b9, 0x81bc, + 0x81bd, 0x81be, 0x81bf, 0x81c4, 0x81c5, 0x81c7, 0x81c8, 0x81c9, + 0x81cb, 0x81cd, 0x81ce, 0x81cf, 0x81d0, 0x81d1, 0x81d2, 0x81d3, + /* 0xc5 */ + 0x81d4, 0x81d5, 0x81d6, 0x81d7, 0x81d8, 0x81d9, 0x81da, 0x81db, + 0x81dc, 0x81dd, 0x81de, 0x81df, 0x81e0, 0x81e1, 0x81e2, 0x81e4, + 0x81e5, 0x81e6, 0x81e8, 0x81e9, 0x81eb, 0x81ee, 0x81ef, 0x81f0, + 0x81f1, 0x81f2, 0x81f5, 0x81f6, 0x81f7, 0x81f8, 0x81f9, 0x81fa, + 0x81fd, 0x81ff, 0x8203, 0x8207, 0x8208, 0x8209, 0x820a, 0x820b, + 0x820e, 0x820f, 0x8211, 0x8213, 0x8215, 0x8216, 0x8217, 0x8218, + 0x8219, 0x821a, 0x821d, 0x8220, 0x8224, 0x8225, 0x8226, 0x8227, + 0x8229, 0x822e, 0x8232, 0x823a, 0x823c, 0x823d, 0x823f, 0x8240, + 0x8241, 0x8242, 0x8243, 0x8245, 0x8246, 0x8248, 0x824a, 0x824c, + 0x824d, 0x824e, 0x8250, 0x8251, 0x8252, 0x8253, 0x8254, 0x8255, + 0x8256, 0x8257, 0x8259, 0x825b, 0x825c, 0x825d, 0x825e, 0x8260, + 0x8261, 0x8262, 0x8263, 0x8264, 0x8265, 0x8266, 0x8267, 0x8269, + /* 0xc6 */ + 0x826a, 0x826b, 0x826c, 0x826d, 0x8271, 0x8275, 0x8276, 0x8277, + 0x8278, 0x827b, 0x827c, 0x8280, 0x8281, 0x8283, 0x8285, 0x8286, + 0x8287, 0x8289, 0x828c, 0x8290, 0x8293, 0x8294, 0x8295, 0x8296, + 0x829a, 0x829b, 0x829e, 0x82a0, 0x82a2, 0x82a3, 0x82a7, 0x82b2, + 0x82b5, 0x82b6, 0x82ba, 0x82bb, 0x82bc, 0x82bf, 0x82c0, 0x82c2, + 0x82c3, 0x82c5, 0x82c6, 0x82c9, 0x82d0, 0x82d6, 0x82d9, 0x82da, + 0x82dd, 0x82e2, 0x82e7, 0x82e8, 0x82e9, 0x82ea, 0x82ec, 0x82ed, + 0x82ee, 0x82f0, 0x82f2, 0x82f3, 0x82f5, 0x82f6, 0x82f8, 0x82fa, + 0x82fc, 0x82fd, 0x82fe, 0x82ff, 0x8300, 0x830a, 0x830b, 0x830d, + 0x8310, 0x8312, 0x8313, 0x8316, 0x8318, 0x8319, 0x831d, 0x831e, + 0x831f, 0x8320, 0x8321, 0x8322, 0x8323, 0x8324, 0x8325, 0x8326, + 0x8329, 0x832a, 0x832e, 0x8330, 0x8332, 0x8337, 0x833b, 0x833d, + /* 0xc7 */ + 0x833e, 0x833f, 0x8341, 0x8342, 0x8344, 0x8345, 0x8348, 0x834a, + 0x834b, 0x834c, 0x834d, 0x834e, 0x8353, 0x8355, 0x8356, 0x8357, + 0x8358, 0x8359, 0x835d, 0x8362, 0x8370, 0x8371, 0x8372, 0x8373, + 0x8374, 0x8375, 0x8376, 0x8379, 0x837a, 0x837e, 0x837f, 0x8380, + 0x8381, 0x8382, 0x8383, 0x8384, 0x8387, 0x8388, 0x838a, 0x838b, + 0x838c, 0x838d, 0x838f, 0x8390, 0x8391, 0x8394, 0x8395, 0x8396, + 0x8397, 0x8399, 0x839a, 0x839d, 0x839f, 0x83a1, 0x83a2, 0x83a3, + 0x83a4, 0x83a5, 0x83a6, 0x83a7, 0x83ac, 0x83ad, 0x83ae, 0x83af, + 0x83b5, 0x83bb, 0x83be, 0x83bf, 0x83c2, 0x83c3, 0x83c4, 0x83c6, + 0x83c8, 0x83c9, 0x83cb, 0x83cd, 0x83ce, 0x83d0, 0x83d1, 0x83d2, + 0x83d3, 0x83d5, 0x83d7, 0x83d9, 0x83da, 0x83db, 0x83de, 0x83e2, + 0x83e3, 0x83e4, 0x83e6, 0x83e7, 0x83e8, 0x83eb, 0x83ec, 0x83ed, + /* 0xc8 */ + 0x83ee, 0x83ef, 0x83f3, 0x83f4, 0x83f5, 0x83f6, 0x83f7, 0x83fa, + 0x83fb, 0x83fc, 0x83fe, 0x83ff, 0x8400, 0x8402, 0x8405, 0x8407, + 0x8408, 0x8409, 0x840a, 0x8410, 0x8412, 0x8413, 0x8414, 0x8415, + 0x8416, 0x8417, 0x8419, 0x841a, 0x841b, 0x841e, 0x841f, 0x8420, + 0x8421, 0x8422, 0x8423, 0x8429, 0x842a, 0x842b, 0x842c, 0x842d, + 0x842e, 0x842f, 0x8430, 0x8432, 0x8433, 0x8434, 0x8435, 0x8436, + 0x8437, 0x8439, 0x843a, 0x843b, 0x843e, 0x843f, 0x8440, 0x8441, + 0x8442, 0x8443, 0x8444, 0x8445, 0x8447, 0x8448, 0x8449, 0x844a, + 0x844b, 0x844c, 0x844d, 0x844e, 0x844f, 0x8450, 0x8452, 0x8453, + 0x8454, 0x8455, 0x8456, 0x8458, 0x845d, 0x845e, 0x845f, 0x8460, + 0x8462, 0x8464, 0x8465, 0x8466, 0x8467, 0x8468, 0x846a, 0x846e, + 0x846f, 0x8470, 0x8472, 0x8474, 0x8477, 0x8479, 0x847b, 0x847c, + /* 0xc9 */ + 0x847d, 0x847e, 0x847f, 0x8480, 0x8481, 0x8483, 0x8484, 0x8485, + 0x8486, 0x848a, 0x848d, 0x848f, 0x8490, 0x8491, 0x8492, 0x8493, + 0x8494, 0x8495, 0x8496, 0x8498, 0x849a, 0x849b, 0x849d, 0x849e, + 0x849f, 0x84a0, 0x84a2, 0x84a3, 0x84a4, 0x84a5, 0x84a6, 0x84a7, + 0x84a8, 0x84a9, 0x84aa, 0x84ab, 0x84ac, 0x84ad, 0x84ae, 0x84b0, + 0x84b1, 0x84b3, 0x84b5, 0x84b6, 0x84b7, 0x84bb, 0x84bc, 0x84be, + 0x84c0, 0x84c2, 0x84c3, 0x84c5, 0x84c6, 0x84c7, 0x84c8, 0x84cb, + 0x84cc, 0x84ce, 0x84cf, 0x84d2, 0x84d4, 0x84d5, 0x84d7, 0x84d8, + 0x84d9, 0x84da, 0x84db, 0x84dc, 0x84de, 0x84e1, 0x84e2, 0x84e4, + 0x84e7, 0x84e8, 0x84e9, 0x84ea, 0x84eb, 0x84ed, 0x84ee, 0x84ef, + 0x84f1, 0x84f2, 0x84f3, 0x84f4, 0x84f5, 0x84f6, 0x84f7, 0x84f8, + 0x84f9, 0x84fa, 0x84fb, 0x84fd, 0x84fe, 0x8500, 0x8501, 0x8502, + /* 0xca */ + 0x8503, 0x8504, 0x8505, 0x8506, 0x8507, 0x8508, 0x8509, 0x850a, + 0x850b, 0x850d, 0x850e, 0x850f, 0x8510, 0x8512, 0x8514, 0x8515, + 0x8516, 0x8518, 0x8519, 0x851b, 0x851c, 0x851d, 0x851e, 0x8520, + 0x8522, 0x8523, 0x8524, 0x8525, 0x8526, 0x8527, 0x8528, 0x8529, + 0x852a, 0x852d, 0x852e, 0x852f, 0x8530, 0x8531, 0x8532, 0x8533, + 0x8534, 0x8535, 0x8536, 0x853e, 0x853f, 0x8540, 0x8541, 0x8542, + 0x8544, 0x8545, 0x8546, 0x8547, 0x854b, 0x854c, 0x854d, 0x854e, + 0x854f, 0x8550, 0x8551, 0x8552, 0x8553, 0x8554, 0x8555, 0x8557, + 0x8558, 0x855a, 0x855b, 0x855c, 0x855d, 0x855f, 0x8560, 0x8561, + 0x8562, 0x8563, 0x8565, 0x8566, 0x8567, 0x8569, 0x856a, 0x856b, + 0x856c, 0x856d, 0x856e, 0x856f, 0x8570, 0x8571, 0x8573, 0x8575, + 0x8576, 0x8577, 0x8578, 0x857c, 0x857d, 0x857f, 0x8580, 0x8581, + /* 0xcb */ + 0x8582, 0x8583, 0x8586, 0x8588, 0x8589, 0x858a, 0x858b, 0x858c, + 0x858d, 0x858e, 0x8590, 0x8591, 0x8592, 0x8593, 0x8594, 0x8595, + 0x8596, 0x8597, 0x8598, 0x8599, 0x859a, 0x859d, 0x859e, 0x859f, + 0x85a0, 0x85a1, 0x85a2, 0x85a3, 0x85a5, 0x85a6, 0x85a7, 0x85a9, + 0x85ab, 0x85ac, 0x85ad, 0x85b1, 0x85b2, 0x85b3, 0x85b4, 0x85b5, + 0x85b6, 0x85b8, 0x85ba, 0x85bb, 0x85bc, 0x85bd, 0x85be, 0x85bf, + 0x85c0, 0x85c2, 0x85c3, 0x85c4, 0x85c5, 0x85c6, 0x85c7, 0x85c8, + 0x85ca, 0x85cb, 0x85cc, 0x85cd, 0x85ce, 0x85d1, 0x85d2, 0x85d4, + 0x85d6, 0x85d7, 0x85d8, 0x85d9, 0x85da, 0x85db, 0x85dd, 0x85de, + 0x85df, 0x85e0, 0x85e1, 0x85e2, 0x85e3, 0x85e5, 0x85e6, 0x85e7, + 0x85e8, 0x85ea, 0x85eb, 0x85ec, 0x85ed, 0x85ee, 0x85ef, 0x85f0, + 0x85f1, 0x85f2, 0x85f3, 0x85f4, 0x85f5, 0x85f6, 0x85f7, 0x85f8, + /* 0xcc */ + 0x85f9, 0x85fa, 0x85fc, 0x85fd, 0x85fe, 0x8600, 0x8601, 0x8602, + 0x8603, 0x8604, 0x8606, 0x8607, 0x8608, 0x8609, 0x860a, 0x860b, + 0x860c, 0x860d, 0x860e, 0x860f, 0x8610, 0x8612, 0x8613, 0x8614, + 0x8615, 0x8617, 0x8618, 0x8619, 0x861a, 0x861b, 0x861c, 0x861d, + 0x861e, 0x861f, 0x8620, 0x8621, 0x8622, 0x8623, 0x8624, 0x8625, + 0x8626, 0x8628, 0x862a, 0x862b, 0x862c, 0x862d, 0x862e, 0x862f, + 0x8630, 0x8631, 0x8632, 0x8633, 0x8634, 0x8635, 0x8636, 0x8637, + 0x8639, 0x863a, 0x863b, 0x863d, 0x863e, 0x863f, 0x8640, 0x8641, + 0x8642, 0x8643, 0x8644, 0x8645, 0x8646, 0x8647, 0x8648, 0x8649, + 0x864a, 0x864b, 0x864c, 0x8652, 0x8653, 0x8655, 0x8656, 0x8657, + 0x8658, 0x8659, 0x865b, 0x865c, 0x865d, 0x865f, 0x8660, 0x8661, + 0x8663, 0x8664, 0x8665, 0x8666, 0x8667, 0x8668, 0x8669, 0x866a, + /* 0xcd */ + 0x866d, 0x866f, 0x8670, 0x8672, 0x8673, 0x8674, 0x8675, 0x8676, + 0x8677, 0x8678, 0x8683, 0x8684, 0x8685, 0x8686, 0x8687, 0x8688, + 0x8689, 0x868e, 0x868f, 0x8690, 0x8691, 0x8692, 0x8694, 0x8696, + 0x8697, 0x8698, 0x8699, 0x869a, 0x869b, 0x869e, 0x869f, 0x86a0, + 0x86a1, 0x86a2, 0x86a5, 0x86a6, 0x86ab, 0x86ad, 0x86ae, 0x86b2, + 0x86b3, 0x86b7, 0x86b8, 0x86b9, 0x86bb, 0x86bc, 0x86bd, 0x86be, + 0x86bf, 0x86c1, 0x86c2, 0x86c3, 0x86c5, 0x86c8, 0x86cc, 0x86cd, + 0x86d2, 0x86d3, 0x86d5, 0x86d6, 0x86d7, 0x86da, 0x86dc, 0x86dd, + 0x86e0, 0x86e1, 0x86e2, 0x86e3, 0x86e5, 0x86e6, 0x86e7, 0x86e8, + 0x86ea, 0x86eb, 0x86ec, 0x86ef, 0x86f5, 0x86f6, 0x86f7, 0x86fa, + 0x86fb, 0x86fc, 0x86fd, 0x86ff, 0x8701, 0x8704, 0x8705, 0x8706, + 0x870b, 0x870c, 0x870e, 0x870f, 0x8710, 0x8711, 0x8714, 0x8716, + /* 0xce */ + 0x8719, 0x871b, 0x871d, 0x871f, 0x8720, 0x8724, 0x8726, 0x8727, + 0x8728, 0x872a, 0x872b, 0x872c, 0x872d, 0x872f, 0x8730, 0x8732, + 0x8733, 0x8735, 0x8736, 0x8738, 0x8739, 0x873a, 0x873c, 0x873d, + 0x8740, 0x8741, 0x8742, 0x8743, 0x8744, 0x8745, 0x8746, 0x874a, + 0x874b, 0x874d, 0x874f, 0x8750, 0x8751, 0x8752, 0x8754, 0x8755, + 0x8756, 0x8758, 0x875a, 0x875b, 0x875c, 0x875d, 0x875e, 0x875f, + 0x8761, 0x8762, 0x8766, 0x8767, 0x8768, 0x8769, 0x876a, 0x876b, + 0x876c, 0x876d, 0x876f, 0x8771, 0x8772, 0x8773, 0x8775, 0x8777, + 0x8778, 0x8779, 0x877a, 0x877f, 0x8780, 0x8781, 0x8784, 0x8786, + 0x8787, 0x8789, 0x878a, 0x878c, 0x878e, 0x878f, 0x8790, 0x8791, + 0x8792, 0x8794, 0x8795, 0x8796, 0x8798, 0x8799, 0x879a, 0x879b, + 0x879c, 0x879d, 0x879e, 0x87a0, 0x87a1, 0x87a2, 0x87a3, 0x87a4, + /* 0xcf */ + 0x87a5, 0x87a6, 0x87a7, 0x87a9, 0x87aa, 0x87ae, 0x87b0, 0x87b1, + 0x87b2, 0x87b4, 0x87b6, 0x87b7, 0x87b8, 0x87b9, 0x87bb, 0x87bc, + 0x87be, 0x87bf, 0x87c1, 0x87c2, 0x87c3, 0x87c4, 0x87c5, 0x87c7, + 0x87c8, 0x87c9, 0x87cc, 0x87cd, 0x87ce, 0x87cf, 0x87d0, 0x87d4, + 0x87d5, 0x87d6, 0x87d7, 0x87d8, 0x87d9, 0x87da, 0x87dc, 0x87dd, + 0x87de, 0x87df, 0x87e1, 0x87e2, 0x87e3, 0x87e4, 0x87e6, 0x87e7, + 0x87e8, 0x87e9, 0x87eb, 0x87ec, 0x87ed, 0x87ef, 0x87f0, 0x87f1, + 0x87f2, 0x87f3, 0x87f4, 0x87f5, 0x87f6, 0x87f7, 0x87f8, 0x87fa, + 0x87fb, 0x87fc, 0x87fd, 0x87ff, 0x8800, 0x8801, 0x8802, 0x8804, + 0x8805, 0x8806, 0x8807, 0x8808, 0x8809, 0x880b, 0x880c, 0x880d, + 0x880e, 0x880f, 0x8810, 0x8811, 0x8812, 0x8814, 0x8817, 0x8818, + 0x8819, 0x881a, 0x881c, 0x881d, 0x881e, 0x881f, 0x8820, 0x8823, + /* 0xd0 */ + 0x8824, 0x8825, 0x8826, 0x8827, 0x8828, 0x8829, 0x882a, 0x882b, + 0x882c, 0x882d, 0x882e, 0x882f, 0x8830, 0x8831, 0x8833, 0x8834, + 0x8835, 0x8836, 0x8837, 0x8838, 0x883a, 0x883b, 0x883d, 0x883e, + 0x883f, 0x8841, 0x8842, 0x8843, 0x8846, 0x8847, 0x8848, 0x8849, + 0x884a, 0x884b, 0x884e, 0x884f, 0x8850, 0x8851, 0x8852, 0x8853, + 0x8855, 0x8856, 0x8858, 0x885a, 0x885b, 0x885c, 0x885d, 0x885e, + 0x885f, 0x8860, 0x8866, 0x8867, 0x886a, 0x886d, 0x886f, 0x8871, + 0x8873, 0x8874, 0x8875, 0x8876, 0x8878, 0x8879, 0x887a, 0x887b, + 0x887c, 0x8880, 0x8883, 0x8886, 0x8887, 0x8889, 0x888a, 0x888c, + 0x888e, 0x888f, 0x8890, 0x8891, 0x8893, 0x8894, 0x8895, 0x8897, + 0x8898, 0x8899, 0x889a, 0x889b, 0x889d, 0x889e, 0x889f, 0x88a0, + 0x88a1, 0x88a3, 0x88a5, 0x88a6, 0x88a7, 0x88a8, 0x88a9, 0x88aa, + /* 0xd1 */ + 0x88ac, 0x88ae, 0x88af, 0x88b0, 0x88b2, 0x88b3, 0x88b4, 0x88b5, + 0x88b6, 0x88b8, 0x88b9, 0x88ba, 0x88bb, 0x88bd, 0x88be, 0x88bf, + 0x88c0, 0x88c3, 0x88c4, 0x88c7, 0x88c8, 0x88ca, 0x88cb, 0x88cc, + 0x88cd, 0x88cf, 0x88d0, 0x88d1, 0x88d3, 0x88d6, 0x88d7, 0x88da, + 0x88db, 0x88dc, 0x88dd, 0x88de, 0x88e0, 0x88e1, 0x88e6, 0x88e7, + 0x88e9, 0x88ea, 0x88eb, 0x88ec, 0x88ed, 0x88ee, 0x88ef, 0x88f2, + 0x88f5, 0x88f6, 0x88f7, 0x88fa, 0x88fb, 0x88fd, 0x88ff, 0x8900, + 0x8901, 0x8903, 0x8904, 0x8905, 0x8906, 0x8907, 0x8908, 0x8909, + 0x890b, 0x890c, 0x890d, 0x890e, 0x890f, 0x8911, 0x8914, 0x8915, + 0x8916, 0x8917, 0x8918, 0x891c, 0x891d, 0x891e, 0x891f, 0x8920, + 0x8922, 0x8923, 0x8924, 0x8926, 0x8927, 0x8928, 0x8929, 0x892c, + 0x892d, 0x892e, 0x892f, 0x8931, 0x8932, 0x8933, 0x8935, 0x8937, + /* 0xd2 */ + 0x8938, 0x8939, 0x893a, 0x893b, 0x893c, 0x893d, 0x893e, 0x893f, + 0x8940, 0x8942, 0x8943, 0x8945, 0x8946, 0x8947, 0x8948, 0x8949, + 0x894a, 0x894b, 0x894c, 0x894d, 0x894e, 0x894f, 0x8950, 0x8951, + 0x8952, 0x8953, 0x8954, 0x8955, 0x8956, 0x8957, 0x8958, 0x8959, + 0x895a, 0x895b, 0x895c, 0x895d, 0x8960, 0x8961, 0x8962, 0x8963, + 0x8964, 0x8965, 0x8967, 0x8968, 0x8969, 0x896a, 0x896b, 0x896c, + 0x896d, 0x896e, 0x896f, 0x8970, 0x8971, 0x8972, 0x8973, 0x8974, + 0x8975, 0x8976, 0x8977, 0x8978, 0x8979, 0x897a, 0x897c, 0x897d, + 0x897e, 0x8980, 0x8982, 0x8984, 0x8985, 0x8987, 0x8988, 0x8989, + 0x898a, 0x898b, 0x898c, 0x898d, 0x898e, 0x898f, 0x8990, 0x8991, + 0x8992, 0x8993, 0x8994, 0x8995, 0x8996, 0x8997, 0x8998, 0x8999, + 0x899a, 0x899b, 0x899c, 0x899d, 0x899e, 0x899f, 0x89a0, 0x89a1, + /* 0xd3 */ + 0x89a2, 0x89a3, 0x89a4, 0x89a5, 0x89a6, 0x89a7, 0x89a8, 0x89a9, + 0x89aa, 0x89ab, 0x89ac, 0x89ad, 0x89ae, 0x89af, 0x89b0, 0x89b1, + 0x89b2, 0x89b3, 0x89b4, 0x89b5, 0x89b6, 0x89b7, 0x89b8, 0x89b9, + 0x89ba, 0x89bb, 0x89bc, 0x89bd, 0x89be, 0x89bf, 0x89c0, 0x89c3, + 0x89cd, 0x89d3, 0x89d4, 0x89d5, 0x89d7, 0x89d8, 0x89d9, 0x89db, + 0x89dd, 0x89df, 0x89e0, 0x89e1, 0x89e2, 0x89e4, 0x89e7, 0x89e8, + 0x89e9, 0x89ea, 0x89ec, 0x89ed, 0x89ee, 0x89f0, 0x89f1, 0x89f2, + 0x89f4, 0x89f5, 0x89f6, 0x89f7, 0x89f8, 0x89f9, 0x89fa, 0x89fb, + 0x89fc, 0x89fd, 0x89fe, 0x89ff, 0x8a01, 0x8a02, 0x8a03, 0x8a04, + 0x8a05, 0x8a06, 0x8a08, 0x8a09, 0x8a0a, 0x8a0b, 0x8a0c, 0x8a0d, + 0x8a0e, 0x8a0f, 0x8a10, 0x8a11, 0x8a12, 0x8a13, 0x8a14, 0x8a15, + 0x8a16, 0x8a17, 0x8a18, 0x8a19, 0x8a1a, 0x8a1b, 0x8a1c, 0x8a1d, + /* 0xd4 */ + 0x8a1e, 0x8a1f, 0x8a20, 0x8a21, 0x8a22, 0x8a23, 0x8a24, 0x8a25, + 0x8a26, 0x8a27, 0x8a28, 0x8a29, 0x8a2a, 0x8a2b, 0x8a2c, 0x8a2d, + 0x8a2e, 0x8a2f, 0x8a30, 0x8a31, 0x8a32, 0x8a33, 0x8a34, 0x8a35, + 0x8a36, 0x8a37, 0x8a38, 0x8a39, 0x8a3a, 0x8a3b, 0x8a3c, 0x8a3d, + 0x8a3f, 0x8a40, 0x8a41, 0x8a42, 0x8a43, 0x8a44, 0x8a45, 0x8a46, + 0x8a47, 0x8a49, 0x8a4a, 0x8a4b, 0x8a4c, 0x8a4d, 0x8a4e, 0x8a4f, + 0x8a50, 0x8a51, 0x8a52, 0x8a53, 0x8a54, 0x8a55, 0x8a56, 0x8a57, + 0x8a58, 0x8a59, 0x8a5a, 0x8a5b, 0x8a5c, 0x8a5d, 0x8a5e, 0x8a5f, + 0x8a60, 0x8a61, 0x8a62, 0x8a63, 0x8a64, 0x8a65, 0x8a66, 0x8a67, + 0x8a68, 0x8a69, 0x8a6a, 0x8a6b, 0x8a6c, 0x8a6d, 0x8a6e, 0x8a6f, + 0x8a70, 0x8a71, 0x8a72, 0x8a73, 0x8a74, 0x8a75, 0x8a76, 0x8a77, + 0x8a78, 0x8a7a, 0x8a7b, 0x8a7c, 0x8a7d, 0x8a7e, 0x8a7f, 0x8a80, + /* 0xd5 */ + 0x8a81, 0x8a82, 0x8a83, 0x8a84, 0x8a85, 0x8a86, 0x8a87, 0x8a88, + 0x8a8b, 0x8a8c, 0x8a8d, 0x8a8e, 0x8a8f, 0x8a90, 0x8a91, 0x8a92, + 0x8a94, 0x8a95, 0x8a96, 0x8a97, 0x8a98, 0x8a99, 0x8a9a, 0x8a9b, + 0x8a9c, 0x8a9d, 0x8a9e, 0x8a9f, 0x8aa0, 0x8aa1, 0x8aa2, 0x8aa3, + 0x8aa4, 0x8aa5, 0x8aa6, 0x8aa7, 0x8aa8, 0x8aa9, 0x8aaa, 0x8aab, + 0x8aac, 0x8aad, 0x8aae, 0x8aaf, 0x8ab0, 0x8ab1, 0x8ab2, 0x8ab3, + 0x8ab4, 0x8ab5, 0x8ab6, 0x8ab7, 0x8ab8, 0x8ab9, 0x8aba, 0x8abb, + 0x8abc, 0x8abd, 0x8abe, 0x8abf, 0x8ac0, 0x8ac1, 0x8ac2, 0x8ac3, + 0x8ac4, 0x8ac5, 0x8ac6, 0x8ac7, 0x8ac8, 0x8ac9, 0x8aca, 0x8acb, + 0x8acc, 0x8acd, 0x8ace, 0x8acf, 0x8ad0, 0x8ad1, 0x8ad2, 0x8ad3, + 0x8ad4, 0x8ad5, 0x8ad6, 0x8ad7, 0x8ad8, 0x8ad9, 0x8ada, 0x8adb, + 0x8adc, 0x8add, 0x8ade, 0x8adf, 0x8ae0, 0x8ae1, 0x8ae2, 0x8ae3, + /* 0xd6 */ + 0x8ae4, 0x8ae5, 0x8ae6, 0x8ae7, 0x8ae8, 0x8ae9, 0x8aea, 0x8aeb, + 0x8aec, 0x8aed, 0x8aee, 0x8aef, 0x8af0, 0x8af1, 0x8af2, 0x8af3, + 0x8af4, 0x8af5, 0x8af6, 0x8af7, 0x8af8, 0x8af9, 0x8afa, 0x8afb, + 0x8afc, 0x8afd, 0x8afe, 0x8aff, 0x8b00, 0x8b01, 0x8b02, 0x8b03, + 0x8b04, 0x8b05, 0x8b06, 0x8b08, 0x8b09, 0x8b0a, 0x8b0b, 0x8b0c, + 0x8b0d, 0x8b0e, 0x8b0f, 0x8b10, 0x8b11, 0x8b12, 0x8b13, 0x8b14, + 0x8b15, 0x8b16, 0x8b17, 0x8b18, 0x8b19, 0x8b1a, 0x8b1b, 0x8b1c, + 0x8b1d, 0x8b1e, 0x8b1f, 0x8b20, 0x8b21, 0x8b22, 0x8b23, 0x8b24, + 0x8b25, 0x8b27, 0x8b28, 0x8b29, 0x8b2a, 0x8b2b, 0x8b2c, 0x8b2d, + 0x8b2e, 0x8b2f, 0x8b30, 0x8b31, 0x8b32, 0x8b33, 0x8b34, 0x8b35, + 0x8b36, 0x8b37, 0x8b38, 0x8b39, 0x8b3a, 0x8b3b, 0x8b3c, 0x8b3d, + 0x8b3e, 0x8b3f, 0x8b40, 0x8b41, 0x8b42, 0x8b43, 0x8b44, 0x8b45, + /* 0xd7 */ + 0x8b46, 0x8b47, 0x8b48, 0x8b49, 0x8b4a, 0x8b4b, 0x8b4c, 0x8b4d, + 0x8b4e, 0x8b4f, 0x8b50, 0x8b51, 0x8b52, 0x8b53, 0x8b54, 0x8b55, + 0x8b56, 0x8b57, 0x8b58, 0x8b59, 0x8b5a, 0x8b5b, 0x8b5c, 0x8b5d, + 0x8b5e, 0x8b5f, 0x8b60, 0x8b61, 0x8b62, 0x8b63, 0x8b64, 0x8b65, + 0x8b67, 0x8b68, 0x8b69, 0x8b6a, 0x8b6b, 0x8b6d, 0x8b6e, 0x8b6f, + 0x8b70, 0x8b71, 0x8b72, 0x8b73, 0x8b74, 0x8b75, 0x8b76, 0x8b77, + 0x8b78, 0x8b79, 0x8b7a, 0x8b7b, 0x8b7c, 0x8b7d, 0x8b7e, 0x8b7f, + 0x8b80, 0x8b81, 0x8b82, 0x8b83, 0x8b84, 0x8b85, 0x8b86, 0x8b87, + 0x8b88, 0x8b89, 0x8b8a, 0x8b8b, 0x8b8c, 0x8b8d, 0x8b8e, 0x8b8f, + 0x8b90, 0x8b91, 0x8b92, 0x8b93, 0x8b94, 0x8b95, 0x8b96, 0x8b97, + 0x8b98, 0x8b99, 0x8b9a, 0x8b9b, 0x8b9c, 0x8b9d, 0x8b9e, 0x8b9f, + 0x8bac, 0x8bb1, 0x8bbb, 0x8bc7, 0x8bd0, 0x8bea, 0x8c09, 0x8c1e, + /* 0xd8 */ + 0x8c38, 0x8c39, 0x8c3a, 0x8c3b, 0x8c3c, 0x8c3d, 0x8c3e, 0x8c3f, + 0x8c40, 0x8c42, 0x8c43, 0x8c44, 0x8c45, 0x8c48, 0x8c4a, 0x8c4b, + 0x8c4d, 0x8c4e, 0x8c4f, 0x8c50, 0x8c51, 0x8c52, 0x8c53, 0x8c54, + 0x8c56, 0x8c57, 0x8c58, 0x8c59, 0x8c5b, 0x8c5c, 0x8c5d, 0x8c5e, + 0x8c5f, 0x8c60, 0x8c63, 0x8c64, 0x8c65, 0x8c66, 0x8c67, 0x8c68, + 0x8c69, 0x8c6c, 0x8c6d, 0x8c6e, 0x8c6f, 0x8c70, 0x8c71, 0x8c72, + 0x8c74, 0x8c75, 0x8c76, 0x8c77, 0x8c7b, 0x8c7c, 0x8c7d, 0x8c7e, + 0x8c7f, 0x8c80, 0x8c81, 0x8c83, 0x8c84, 0x8c86, 0x8c87, 0x8c88, + 0x8c8b, 0x8c8d, 0x8c8e, 0x8c8f, 0x8c90, 0x8c91, 0x8c92, 0x8c93, + 0x8c95, 0x8c96, 0x8c97, 0x8c99, 0x8c9a, 0x8c9b, 0x8c9c, 0x8c9d, + 0x8c9e, 0x8c9f, 0x8ca0, 0x8ca1, 0x8ca2, 0x8ca3, 0x8ca4, 0x8ca5, + 0x8ca6, 0x8ca7, 0x8ca8, 0x8ca9, 0x8caa, 0x8cab, 0x8cac, 0x8cad, + /* 0xd9 */ + 0x8cae, 0x8caf, 0x8cb0, 0x8cb1, 0x8cb2, 0x8cb3, 0x8cb4, 0x8cb5, + 0x8cb6, 0x8cb7, 0x8cb8, 0x8cb9, 0x8cba, 0x8cbb, 0x8cbc, 0x8cbd, + 0x8cbe, 0x8cbf, 0x8cc0, 0x8cc1, 0x8cc2, 0x8cc3, 0x8cc4, 0x8cc5, + 0x8cc6, 0x8cc7, 0x8cc8, 0x8cc9, 0x8cca, 0x8ccb, 0x8ccc, 0x8ccd, + 0x8cce, 0x8ccf, 0x8cd0, 0x8cd1, 0x8cd2, 0x8cd3, 0x8cd4, 0x8cd5, + 0x8cd6, 0x8cd7, 0x8cd8, 0x8cd9, 0x8cda, 0x8cdb, 0x8cdc, 0x8cdd, + 0x8cde, 0x8cdf, 0x8ce0, 0x8ce1, 0x8ce2, 0x8ce3, 0x8ce4, 0x8ce5, + 0x8ce6, 0x8ce7, 0x8ce8, 0x8ce9, 0x8cea, 0x8ceb, 0x8cec, 0x8ced, + 0x8cee, 0x8cef, 0x8cf0, 0x8cf1, 0x8cf2, 0x8cf3, 0x8cf4, 0x8cf5, + 0x8cf6, 0x8cf7, 0x8cf8, 0x8cf9, 0x8cfa, 0x8cfb, 0x8cfc, 0x8cfd, + 0x8cfe, 0x8cff, 0x8d00, 0x8d01, 0x8d02, 0x8d03, 0x8d04, 0x8d05, + 0x8d06, 0x8d07, 0x8d08, 0x8d09, 0x8d0a, 0x8d0b, 0x8d0c, 0x8d0d, + /* 0xda */ + 0x8d0e, 0x8d0f, 0x8d10, 0x8d11, 0x8d12, 0x8d13, 0x8d14, 0x8d15, + 0x8d16, 0x8d17, 0x8d18, 0x8d19, 0x8d1a, 0x8d1b, 0x8d1c, 0x8d20, + 0x8d51, 0x8d52, 0x8d57, 0x8d5f, 0x8d65, 0x8d68, 0x8d69, 0x8d6a, + 0x8d6c, 0x8d6e, 0x8d6f, 0x8d71, 0x8d72, 0x8d78, 0x8d79, 0x8d7a, + 0x8d7b, 0x8d7c, 0x8d7d, 0x8d7e, 0x8d7f, 0x8d80, 0x8d82, 0x8d83, + 0x8d86, 0x8d87, 0x8d88, 0x8d89, 0x8d8c, 0x8d8d, 0x8d8e, 0x8d8f, + 0x8d90, 0x8d92, 0x8d93, 0x8d95, 0x8d96, 0x8d97, 0x8d98, 0x8d99, + 0x8d9a, 0x8d9b, 0x8d9c, 0x8d9d, 0x8d9e, 0x8da0, 0x8da1, 0x8da2, + 0x8da4, 0x8da5, 0x8da6, 0x8da7, 0x8da8, 0x8da9, 0x8daa, 0x8dab, + 0x8dac, 0x8dad, 0x8dae, 0x8daf, 0x8db0, 0x8db2, 0x8db6, 0x8db7, + 0x8db9, 0x8dbb, 0x8dbd, 0x8dc0, 0x8dc1, 0x8dc2, 0x8dc5, 0x8dc7, + 0x8dc8, 0x8dc9, 0x8dca, 0x8dcd, 0x8dd0, 0x8dd2, 0x8dd3, 0x8dd4, + /* 0xdb */ + 0x8dd5, 0x8dd8, 0x8dd9, 0x8ddc, 0x8de0, 0x8de1, 0x8de2, 0x8de5, + 0x8de6, 0x8de7, 0x8de9, 0x8ded, 0x8dee, 0x8df0, 0x8df1, 0x8df2, + 0x8df4, 0x8df6, 0x8dfc, 0x8dfe, 0x8dff, 0x8e00, 0x8e01, 0x8e02, + 0x8e03, 0x8e04, 0x8e06, 0x8e07, 0x8e08, 0x8e0b, 0x8e0d, 0x8e0e, + 0x8e10, 0x8e11, 0x8e12, 0x8e13, 0x8e15, 0x8e16, 0x8e17, 0x8e18, + 0x8e19, 0x8e1a, 0x8e1b, 0x8e1c, 0x8e20, 0x8e21, 0x8e24, 0x8e25, + 0x8e26, 0x8e27, 0x8e28, 0x8e2b, 0x8e2d, 0x8e30, 0x8e32, 0x8e33, + 0x8e34, 0x8e36, 0x8e37, 0x8e38, 0x8e3b, 0x8e3c, 0x8e3e, 0x8e3f, + 0x8e43, 0x8e45, 0x8e46, 0x8e4c, 0x8e4d, 0x8e4e, 0x8e4f, 0x8e50, + 0x8e53, 0x8e54, 0x8e55, 0x8e56, 0x8e57, 0x8e58, 0x8e5a, 0x8e5b, + 0x8e5c, 0x8e5d, 0x8e5e, 0x8e5f, 0x8e60, 0x8e61, 0x8e62, 0x8e63, + 0x8e64, 0x8e65, 0x8e67, 0x8e68, 0x8e6a, 0x8e6b, 0x8e6e, 0x8e71, + /* 0xdc */ + 0x8e73, 0x8e75, 0x8e77, 0x8e78, 0x8e79, 0x8e7a, 0x8e7b, 0x8e7d, + 0x8e7e, 0x8e80, 0x8e82, 0x8e83, 0x8e84, 0x8e86, 0x8e88, 0x8e89, + 0x8e8a, 0x8e8b, 0x8e8c, 0x8e8d, 0x8e8e, 0x8e91, 0x8e92, 0x8e93, + 0x8e95, 0x8e96, 0x8e97, 0x8e98, 0x8e99, 0x8e9a, 0x8e9b, 0x8e9d, + 0x8e9f, 0x8ea0, 0x8ea1, 0x8ea2, 0x8ea3, 0x8ea4, 0x8ea5, 0x8ea6, + 0x8ea7, 0x8ea8, 0x8ea9, 0x8eaa, 0x8ead, 0x8eae, 0x8eb0, 0x8eb1, + 0x8eb3, 0x8eb4, 0x8eb5, 0x8eb6, 0x8eb7, 0x8eb8, 0x8eb9, 0x8ebb, + 0x8ebc, 0x8ebd, 0x8ebe, 0x8ebf, 0x8ec0, 0x8ec1, 0x8ec2, 0x8ec3, + 0x8ec4, 0x8ec5, 0x8ec6, 0x8ec7, 0x8ec8, 0x8ec9, 0x8eca, 0x8ecb, + 0x8ecc, 0x8ecd, 0x8ecf, 0x8ed0, 0x8ed1, 0x8ed2, 0x8ed3, 0x8ed4, + 0x8ed5, 0x8ed6, 0x8ed7, 0x8ed8, 0x8ed9, 0x8eda, 0x8edb, 0x8edc, + 0x8edd, 0x8ede, 0x8edf, 0x8ee0, 0x8ee1, 0x8ee2, 0x8ee3, 0x8ee4, + /* 0xdd */ + 0x8ee5, 0x8ee6, 0x8ee7, 0x8ee8, 0x8ee9, 0x8eea, 0x8eeb, 0x8eec, + 0x8eed, 0x8eee, 0x8eef, 0x8ef0, 0x8ef1, 0x8ef2, 0x8ef3, 0x8ef4, + 0x8ef5, 0x8ef6, 0x8ef7, 0x8ef8, 0x8ef9, 0x8efa, 0x8efb, 0x8efc, + 0x8efd, 0x8efe, 0x8eff, 0x8f00, 0x8f01, 0x8f02, 0x8f03, 0x8f04, + 0x8f05, 0x8f06, 0x8f07, 0x8f08, 0x8f09, 0x8f0a, 0x8f0b, 0x8f0c, + 0x8f0d, 0x8f0e, 0x8f0f, 0x8f10, 0x8f11, 0x8f12, 0x8f13, 0x8f14, + 0x8f15, 0x8f16, 0x8f17, 0x8f18, 0x8f19, 0x8f1a, 0x8f1b, 0x8f1c, + 0x8f1d, 0x8f1e, 0x8f1f, 0x8f20, 0x8f21, 0x8f22, 0x8f23, 0x8f24, + 0x8f25, 0x8f26, 0x8f27, 0x8f28, 0x8f29, 0x8f2a, 0x8f2b, 0x8f2c, + 0x8f2d, 0x8f2e, 0x8f2f, 0x8f30, 0x8f31, 0x8f32, 0x8f33, 0x8f34, + 0x8f35, 0x8f36, 0x8f37, 0x8f38, 0x8f39, 0x8f3a, 0x8f3b, 0x8f3c, + 0x8f3d, 0x8f3e, 0x8f3f, 0x8f40, 0x8f41, 0x8f42, 0x8f43, 0x8f44, + /* 0xde */ + 0x8f45, 0x8f46, 0x8f47, 0x8f48, 0x8f49, 0x8f4a, 0x8f4b, 0x8f4c, + 0x8f4d, 0x8f4e, 0x8f4f, 0x8f50, 0x8f51, 0x8f52, 0x8f53, 0x8f54, + 0x8f55, 0x8f56, 0x8f57, 0x8f58, 0x8f59, 0x8f5a, 0x8f5b, 0x8f5c, + 0x8f5d, 0x8f5e, 0x8f5f, 0x8f60, 0x8f61, 0x8f62, 0x8f63, 0x8f64, + 0x8f65, 0x8f6a, 0x8f80, 0x8f8c, 0x8f92, 0x8f9d, 0x8fa0, 0x8fa1, + 0x8fa2, 0x8fa4, 0x8fa5, 0x8fa6, 0x8fa7, 0x8faa, 0x8fac, 0x8fad, + 0x8fae, 0x8faf, 0x8fb2, 0x8fb3, 0x8fb4, 0x8fb5, 0x8fb7, 0x8fb8, + 0x8fba, 0x8fbb, 0x8fbc, 0x8fbf, 0x8fc0, 0x8fc3, 0x8fc6, 0x8fc9, + 0x8fca, 0x8fcb, 0x8fcc, 0x8fcd, 0x8fcf, 0x8fd2, 0x8fd6, 0x8fd7, + 0x8fda, 0x8fe0, 0x8fe1, 0x8fe3, 0x8fe7, 0x8fec, 0x8fef, 0x8ff1, + 0x8ff2, 0x8ff4, 0x8ff5, 0x8ff6, 0x8ffa, 0x8ffb, 0x8ffc, 0x8ffe, + 0x8fff, 0x9007, 0x9008, 0x900c, 0x900e, 0x9013, 0x9015, 0x9018, + /* 0xdf */ + 0x9019, 0x901c, 0x9023, 0x9024, 0x9025, 0x9027, 0x9028, 0x9029, + 0x902a, 0x902b, 0x902c, 0x9030, 0x9031, 0x9032, 0x9033, 0x9034, + 0x9037, 0x9039, 0x903a, 0x903d, 0x903f, 0x9040, 0x9043, 0x9045, + 0x9046, 0x9048, 0x9049, 0x904a, 0x904b, 0x904c, 0x904e, 0x9054, + 0x9055, 0x9056, 0x9059, 0x905a, 0x905c, 0x905d, 0x905e, 0x905f, + 0x9060, 0x9061, 0x9064, 0x9066, 0x9067, 0x9069, 0x906a, 0x906b, + 0x906c, 0x906f, 0x9070, 0x9071, 0x9072, 0x9073, 0x9076, 0x9077, + 0x9078, 0x9079, 0x907a, 0x907b, 0x907c, 0x907e, 0x9081, 0x9084, + 0x9085, 0x9086, 0x9087, 0x9089, 0x908a, 0x908c, 0x908d, 0x908e, + 0x908f, 0x9090, 0x9092, 0x9094, 0x9096, 0x9098, 0x909a, 0x909c, + 0x909e, 0x909f, 0x90a0, 0x90a4, 0x90a5, 0x90a7, 0x90a8, 0x90a9, + 0x90ab, 0x90ad, 0x90b2, 0x90b7, 0x90bc, 0x90bd, 0x90bf, 0x90c0, + /* 0xe0 */ + 0x90c2, 0x90c3, 0x90c6, 0x90c8, 0x90c9, 0x90cb, 0x90cc, 0x90cd, + 0x90d2, 0x90d4, 0x90d5, 0x90d6, 0x90d8, 0x90d9, 0x90da, 0x90de, + 0x90df, 0x90e0, 0x90e3, 0x90e4, 0x90e5, 0x90e9, 0x90ea, 0x90ec, + 0x90ee, 0x90f0, 0x90f1, 0x90f2, 0x90f3, 0x90f5, 0x90f6, 0x90f7, + 0x90f9, 0x90fa, 0x90fb, 0x90fc, 0x90ff, 0x9100, 0x9101, 0x9103, + 0x9105, 0x9106, 0x9107, 0x9108, 0x9109, 0x910a, 0x910b, 0x910c, + 0x910d, 0x910e, 0x910f, 0x9110, 0x9111, 0x9112, 0x9113, 0x9114, + 0x9115, 0x9116, 0x9117, 0x9118, 0x911a, 0x911b, 0x911c, 0x911d, + 0x911f, 0x9120, 0x9121, 0x9124, 0x9125, 0x9126, 0x9127, 0x9128, + 0x9129, 0x912a, 0x912b, 0x912c, 0x912d, 0x912e, 0x9130, 0x9132, + 0x9133, 0x9134, 0x9135, 0x9136, 0x9137, 0x9138, 0x913a, 0x913b, + 0x913c, 0x913d, 0x913e, 0x913f, 0x9140, 0x9141, 0x9142, 0x9144, + /* 0xe1 */ + 0x9145, 0x9147, 0x9148, 0x9151, 0x9153, 0x9154, 0x9155, 0x9156, + 0x9158, 0x9159, 0x915b, 0x915c, 0x915f, 0x9160, 0x9166, 0x9167, + 0x9168, 0x916b, 0x916d, 0x9173, 0x917a, 0x917b, 0x917c, 0x9180, + 0x9181, 0x9182, 0x9183, 0x9184, 0x9186, 0x9188, 0x918a, 0x918e, + 0x918f, 0x9193, 0x9194, 0x9195, 0x9196, 0x9197, 0x9198, 0x9199, + 0x919c, 0x919d, 0x919e, 0x919f, 0x91a0, 0x91a1, 0x91a4, 0x91a5, + 0x91a6, 0x91a7, 0x91a8, 0x91a9, 0x91ab, 0x91ac, 0x91b0, 0x91b1, + 0x91b2, 0x91b3, 0x91b6, 0x91b7, 0x91b8, 0x91b9, 0x91bb, 0x91bc, + 0x91bd, 0x91be, 0x91bf, 0x91c0, 0x91c1, 0x91c2, 0x91c3, 0x91c4, + 0x91c5, 0x91c6, 0x91c8, 0x91cb, 0x91d0, 0x91d2, 0x91d3, 0x91d4, + 0x91d5, 0x91d6, 0x91d7, 0x91d8, 0x91d9, 0x91da, 0x91db, 0x91dd, + 0x91de, 0x91df, 0x91e0, 0x91e1, 0x91e2, 0x91e3, 0x91e4, 0x91e5, + /* 0xe2 */ + 0x91e6, 0x91e7, 0x91e8, 0x91e9, 0x91ea, 0x91eb, 0x91ec, 0x91ed, + 0x91ee, 0x91ef, 0x91f0, 0x91f1, 0x91f2, 0x91f3, 0x91f4, 0x91f5, + 0x91f6, 0x91f7, 0x91f8, 0x91f9, 0x91fa, 0x91fb, 0x91fc, 0x91fd, + 0x91fe, 0x91ff, 0x9200, 0x9201, 0x9202, 0x9203, 0x9204, 0x9205, + 0x9206, 0x9207, 0x9208, 0x9209, 0x920a, 0x920b, 0x920c, 0x920d, + 0x920e, 0x920f, 0x9210, 0x9211, 0x9212, 0x9213, 0x9214, 0x9215, + 0x9216, 0x9217, 0x9218, 0x9219, 0x921a, 0x921b, 0x921c, 0x921d, + 0x921e, 0x921f, 0x9220, 0x9221, 0x9222, 0x9223, 0x9224, 0x9225, + 0x9226, 0x9227, 0x9228, 0x9229, 0x922a, 0x922b, 0x922c, 0x922d, + 0x922e, 0x922f, 0x9230, 0x9231, 0x9232, 0x9233, 0x9234, 0x9235, + 0x9236, 0x9237, 0x9238, 0x9239, 0x923a, 0x923b, 0x923c, 0x923d, + 0x923e, 0x923f, 0x9240, 0x9241, 0x9242, 0x9243, 0x9244, 0x9245, + /* 0xe3 */ + 0x9246, 0x9247, 0x9248, 0x9249, 0x924a, 0x924b, 0x924c, 0x924d, + 0x924e, 0x924f, 0x9250, 0x9251, 0x9252, 0x9253, 0x9254, 0x9255, + 0x9256, 0x9257, 0x9258, 0x9259, 0x925a, 0x925b, 0x925c, 0x925d, + 0x925e, 0x925f, 0x9260, 0x9261, 0x9262, 0x9263, 0x9264, 0x9265, + 0x9266, 0x9267, 0x9268, 0x9269, 0x926a, 0x926b, 0x926c, 0x926d, + 0x926e, 0x926f, 0x9270, 0x9271, 0x9272, 0x9273, 0x9275, 0x9276, + 0x9277, 0x9278, 0x9279, 0x927a, 0x927b, 0x927c, 0x927d, 0x927e, + 0x927f, 0x9280, 0x9281, 0x9282, 0x9283, 0x9284, 0x9285, 0x9286, + 0x9287, 0x9288, 0x9289, 0x928a, 0x928b, 0x928c, 0x928d, 0x928f, + 0x9290, 0x9291, 0x9292, 0x9293, 0x9294, 0x9295, 0x9296, 0x9297, + 0x9298, 0x9299, 0x929a, 0x929b, 0x929c, 0x929d, 0x929e, 0x929f, + 0x92a0, 0x92a1, 0x92a2, 0x92a3, 0x92a4, 0x92a5, 0x92a6, 0x92a7, + /* 0xe4 */ + 0x92a8, 0x92a9, 0x92aa, 0x92ab, 0x92ac, 0x92ad, 0x92af, 0x92b0, + 0x92b1, 0x92b2, 0x92b3, 0x92b4, 0x92b5, 0x92b6, 0x92b7, 0x92b8, + 0x92b9, 0x92ba, 0x92bb, 0x92bc, 0x92bd, 0x92be, 0x92bf, 0x92c0, + 0x92c1, 0x92c2, 0x92c3, 0x92c4, 0x92c5, 0x92c6, 0x92c7, 0x92c9, + 0x92ca, 0x92cb, 0x92cc, 0x92cd, 0x92ce, 0x92cf, 0x92d0, 0x92d1, + 0x92d2, 0x92d3, 0x92d4, 0x92d5, 0x92d6, 0x92d7, 0x92d8, 0x92d9, + 0x92da, 0x92db, 0x92dc, 0x92dd, 0x92de, 0x92df, 0x92e0, 0x92e1, + 0x92e2, 0x92e3, 0x92e4, 0x92e5, 0x92e6, 0x92e7, 0x92e8, 0x92e9, + 0x92ea, 0x92eb, 0x92ec, 0x92ed, 0x92ee, 0x92ef, 0x92f0, 0x92f1, + 0x92f2, 0x92f3, 0x92f4, 0x92f5, 0x92f6, 0x92f7, 0x92f8, 0x92f9, + 0x92fa, 0x92fb, 0x92fc, 0x92fd, 0x92fe, 0x92ff, 0x9300, 0x9301, + 0x9302, 0x9303, 0x9304, 0x9305, 0x9306, 0x9307, 0x9308, 0x9309, + /* 0xe5 */ + 0x930a, 0x930b, 0x930c, 0x930d, 0x930e, 0x930f, 0x9310, 0x9311, + 0x9312, 0x9313, 0x9314, 0x9315, 0x9316, 0x9317, 0x9318, 0x9319, + 0x931a, 0x931b, 0x931c, 0x931d, 0x931e, 0x931f, 0x9320, 0x9321, + 0x9322, 0x9323, 0x9324, 0x9325, 0x9326, 0x9327, 0x9328, 0x9329, + 0x932a, 0x932b, 0x932c, 0x932d, 0x932e, 0x932f, 0x9330, 0x9331, + 0x9332, 0x9333, 0x9334, 0x9335, 0x9336, 0x9337, 0x9338, 0x9339, + 0x933a, 0x933b, 0x933c, 0x933d, 0x933f, 0x9340, 0x9341, 0x9342, + 0x9343, 0x9344, 0x9345, 0x9346, 0x9347, 0x9348, 0x9349, 0x934a, + 0x934b, 0x934c, 0x934d, 0x934e, 0x934f, 0x9350, 0x9351, 0x9352, + 0x9353, 0x9354, 0x9355, 0x9356, 0x9357, 0x9358, 0x9359, 0x935a, + 0x935b, 0x935c, 0x935d, 0x935e, 0x935f, 0x9360, 0x9361, 0x9362, + 0x9363, 0x9364, 0x9365, 0x9366, 0x9367, 0x9368, 0x9369, 0x936b, + /* 0xe6 */ + 0x936c, 0x936d, 0x936e, 0x936f, 0x9370, 0x9371, 0x9372, 0x9373, + 0x9374, 0x9375, 0x9376, 0x9377, 0x9378, 0x9379, 0x937a, 0x937b, + 0x937c, 0x937d, 0x937e, 0x937f, 0x9380, 0x9381, 0x9382, 0x9383, + 0x9384, 0x9385, 0x9386, 0x9387, 0x9388, 0x9389, 0x938a, 0x938b, + 0x938c, 0x938d, 0x938e, 0x9390, 0x9391, 0x9392, 0x9393, 0x9394, + 0x9395, 0x9396, 0x9397, 0x9398, 0x9399, 0x939a, 0x939b, 0x939c, + 0x939d, 0x939e, 0x939f, 0x93a0, 0x93a1, 0x93a2, 0x93a3, 0x93a4, + 0x93a5, 0x93a6, 0x93a7, 0x93a8, 0x93a9, 0x93aa, 0x93ab, 0x93ac, + 0x93ad, 0x93ae, 0x93af, 0x93b0, 0x93b1, 0x93b2, 0x93b3, 0x93b4, + 0x93b5, 0x93b6, 0x93b7, 0x93b8, 0x93b9, 0x93ba, 0x93bb, 0x93bc, + 0x93bd, 0x93be, 0x93bf, 0x93c0, 0x93c1, 0x93c2, 0x93c3, 0x93c4, + 0x93c5, 0x93c6, 0x93c7, 0x93c8, 0x93c9, 0x93cb, 0x93cc, 0x93cd, + /* 0xe7 */ + 0x93ce, 0x93cf, 0x93d0, 0x93d1, 0x93d2, 0x93d3, 0x93d4, 0x93d5, + 0x93d7, 0x93d8, 0x93d9, 0x93da, 0x93db, 0x93dc, 0x93dd, 0x93de, + 0x93df, 0x93e0, 0x93e1, 0x93e2, 0x93e3, 0x93e4, 0x93e5, 0x93e6, + 0x93e7, 0x93e8, 0x93e9, 0x93ea, 0x93eb, 0x93ec, 0x93ed, 0x93ee, + 0x93ef, 0x93f0, 0x93f1, 0x93f2, 0x93f3, 0x93f4, 0x93f5, 0x93f6, + 0x93f7, 0x93f8, 0x93f9, 0x93fa, 0x93fb, 0x93fc, 0x93fd, 0x93fe, + 0x93ff, 0x9400, 0x9401, 0x9402, 0x9403, 0x9404, 0x9405, 0x9406, + 0x9407, 0x9408, 0x9409, 0x940a, 0x940b, 0x940c, 0x940d, 0x940e, + 0x940f, 0x9410, 0x9411, 0x9412, 0x9413, 0x9414, 0x9415, 0x9416, + 0x9417, 0x9418, 0x9419, 0x941a, 0x941b, 0x941c, 0x941d, 0x941e, + 0x941f, 0x9420, 0x9421, 0x9422, 0x9423, 0x9424, 0x9425, 0x9426, + 0x9427, 0x9428, 0x9429, 0x942a, 0x942b, 0x942c, 0x942d, 0x942e, + /* 0xe8 */ + 0x942f, 0x9430, 0x9431, 0x9432, 0x9433, 0x9434, 0x9435, 0x9436, + 0x9437, 0x9438, 0x9439, 0x943a, 0x943b, 0x943c, 0x943d, 0x943f, + 0x9440, 0x9441, 0x9442, 0x9443, 0x9444, 0x9445, 0x9446, 0x9447, + 0x9448, 0x9449, 0x944a, 0x944b, 0x944c, 0x944d, 0x944e, 0x944f, + 0x9450, 0x9451, 0x9452, 0x9453, 0x9454, 0x9455, 0x9456, 0x9457, + 0x9458, 0x9459, 0x945a, 0x945b, 0x945c, 0x945d, 0x945e, 0x945f, + 0x9460, 0x9461, 0x9462, 0x9463, 0x9464, 0x9465, 0x9466, 0x9467, + 0x9468, 0x9469, 0x946a, 0x946c, 0x946d, 0x946e, 0x946f, 0x9470, + 0x9471, 0x9472, 0x9473, 0x9474, 0x9475, 0x9476, 0x9477, 0x9478, + 0x9479, 0x947a, 0x947b, 0x947c, 0x947d, 0x947e, 0x947f, 0x9480, + 0x9481, 0x9482, 0x9483, 0x9484, 0x9491, 0x9496, 0x9498, 0x94c7, + 0x94cf, 0x94d3, 0x94d4, 0x94da, 0x94e6, 0x94fb, 0x951c, 0x9520, + /* 0xe9 */ + 0x9527, 0x9533, 0x953d, 0x9543, 0x9548, 0x954b, 0x9555, 0x955a, + 0x9560, 0x956e, 0x9574, 0x9575, 0x9577, 0x9578, 0x9579, 0x957a, + 0x957b, 0x957c, 0x957d, 0x957e, 0x9580, 0x9581, 0x9582, 0x9583, + 0x9584, 0x9585, 0x9586, 0x9587, 0x9588, 0x9589, 0x958a, 0x958b, + 0x958c, 0x958d, 0x958e, 0x958f, 0x9590, 0x9591, 0x9592, 0x9593, + 0x9594, 0x9595, 0x9596, 0x9597, 0x9598, 0x9599, 0x959a, 0x959b, + 0x959c, 0x959d, 0x959e, 0x959f, 0x95a0, 0x95a1, 0x95a2, 0x95a3, + 0x95a4, 0x95a5, 0x95a6, 0x95a7, 0x95a8, 0x95a9, 0x95aa, 0x95ab, + 0x95ac, 0x95ad, 0x95ae, 0x95af, 0x95b0, 0x95b1, 0x95b2, 0x95b3, + 0x95b4, 0x95b5, 0x95b6, 0x95b7, 0x95b8, 0x95b9, 0x95ba, 0x95bb, + 0x95bc, 0x95bd, 0x95be, 0x95bf, 0x95c0, 0x95c1, 0x95c2, 0x95c3, + 0x95c4, 0x95c5, 0x95c6, 0x95c7, 0x95c8, 0x95c9, 0x95ca, 0x95cb, + /* 0xea */ + 0x95cc, 0x95cd, 0x95ce, 0x95cf, 0x95d0, 0x95d1, 0x95d2, 0x95d3, + 0x95d4, 0x95d5, 0x95d6, 0x95d7, 0x95d8, 0x95d9, 0x95da, 0x95db, + 0x95dc, 0x95dd, 0x95de, 0x95df, 0x95e0, 0x95e1, 0x95e2, 0x95e3, + 0x95e4, 0x95e5, 0x95e6, 0x95e7, 0x95ec, 0x95ff, 0x9607, 0x9613, + 0x9618, 0x961b, 0x961e, 0x9620, 0x9623, 0x9624, 0x9625, 0x9626, + 0x9627, 0x9628, 0x9629, 0x962b, 0x962c, 0x962d, 0x962f, 0x9630, + 0x9637, 0x9638, 0x9639, 0x963a, 0x963e, 0x9641, 0x9643, 0x964a, + 0x964e, 0x964f, 0x9651, 0x9652, 0x9653, 0x9656, 0x9657, 0x9658, + 0x9659, 0x965a, 0x965c, 0x965d, 0x965e, 0x9660, 0x9663, 0x9665, + 0x9666, 0x966b, 0x966d, 0x966e, 0x966f, 0x9670, 0x9671, 0x9673, + 0x9678, 0x9679, 0x967a, 0x967b, 0x967c, 0x967d, 0x967e, 0x967f, + 0x9680, 0x9681, 0x9682, 0x9683, 0x9684, 0x9687, 0x9689, 0x968a, + /* 0xeb */ + 0x968c, 0x968e, 0x9691, 0x9692, 0x9693, 0x9695, 0x9696, 0x969a, + 0x969b, 0x969d, 0x969e, 0x969f, 0x96a0, 0x96a1, 0x96a2, 0x96a3, + 0x96a4, 0x96a5, 0x96a6, 0x96a8, 0x96a9, 0x96aa, 0x96ab, 0x96ac, + 0x96ad, 0x96ae, 0x96af, 0x96b1, 0x96b2, 0x96b4, 0x96b5, 0x96b7, + 0x96b8, 0x96ba, 0x96bb, 0x96bf, 0x96c2, 0x96c3, 0x96c8, 0x96ca, + 0x96cb, 0x96d0, 0x96d1, 0x96d3, 0x96d4, 0x96d6, 0x96d7, 0x96d8, + 0x96d9, 0x96da, 0x96db, 0x96dc, 0x96dd, 0x96de, 0x96df, 0x96e1, + 0x96e2, 0x96e3, 0x96e4, 0x96e5, 0x96e6, 0x96e7, 0x96eb, 0x96ec, + 0x96ed, 0x96ee, 0x96f0, 0x96f1, 0x96f2, 0x96f4, 0x96f5, 0x96f8, + 0x96fa, 0x96fb, 0x96fc, 0x96fd, 0x96ff, 0x9702, 0x9703, 0x9705, + 0x970a, 0x970b, 0x970c, 0x9710, 0x9711, 0x9712, 0x9714, 0x9715, + 0x9717, 0x9718, 0x9719, 0x971a, 0x971b, 0x971d, 0x971f, 0x9720, + /* 0xec */ + 0x9721, 0x9722, 0x9723, 0x9724, 0x9725, 0x9726, 0x9727, 0x9728, + 0x9729, 0x972b, 0x972c, 0x972e, 0x972f, 0x9731, 0x9733, 0x9734, + 0x9735, 0x9736, 0x9737, 0x973a, 0x973b, 0x973c, 0x973d, 0x973f, + 0x9740, 0x9741, 0x9742, 0x9743, 0x9744, 0x9745, 0x9746, 0x9747, + 0x9748, 0x9749, 0x974a, 0x974b, 0x974c, 0x974d, 0x974e, 0x974f, + 0x9750, 0x9751, 0x9754, 0x9755, 0x9757, 0x9758, 0x975a, 0x975c, + 0x975d, 0x975f, 0x9763, 0x9764, 0x9766, 0x9767, 0x9768, 0x976a, + 0x976b, 0x976c, 0x976d, 0x976e, 0x976f, 0x9770, 0x9771, 0x9772, + 0x9775, 0x9777, 0x9778, 0x9779, 0x977a, 0x977b, 0x977d, 0x977e, + 0x977f, 0x9780, 0x9781, 0x9782, 0x9783, 0x9784, 0x9786, 0x9787, + 0x9788, 0x9789, 0x978a, 0x978c, 0x978e, 0x978f, 0x9790, 0x9793, + 0x9795, 0x9796, 0x9797, 0x9799, 0x979a, 0x979b, 0x979c, 0x979d, + /* 0xed */ + 0x979e, 0x979f, 0x97a1, 0x97a2, 0x97a4, 0x97a5, 0x97a6, 0x97a7, + 0x97a8, 0x97a9, 0x97aa, 0x97ac, 0x97ae, 0x97b0, 0x97b1, 0x97b3, + 0x97b5, 0x97b6, 0x97b7, 0x97b8, 0x97b9, 0x97ba, 0x97bb, 0x97bc, + 0x97bd, 0x97be, 0x97bf, 0x97c0, 0x97c1, 0x97c2, 0x97c3, 0x97c4, + 0x97c5, 0x97c6, 0x97c7, 0x97c8, 0x97c9, 0x97ca, 0x97cb, 0x97cc, + 0x97cd, 0x97ce, 0x97cf, 0x97d0, 0x97d1, 0x97d2, 0x97d3, 0x97d4, + 0x97d5, 0x97d6, 0x97d7, 0x97d8, 0x97d9, 0x97da, 0x97db, 0x97dc, + 0x97dd, 0x97de, 0x97df, 0x97e0, 0x97e1, 0x97e2, 0x97e3, 0x97e4, + 0x97e5, 0x97e8, 0x97ee, 0x97ef, 0x97f0, 0x97f1, 0x97f2, 0x97f4, + 0x97f7, 0x97f8, 0x97f9, 0x97fa, 0x97fb, 0x97fc, 0x97fd, 0x97fe, + 0x97ff, 0x9800, 0x9801, 0x9802, 0x9803, 0x9804, 0x9805, 0x9806, + 0x9807, 0x9808, 0x9809, 0x980a, 0x980b, 0x980c, 0x980d, 0x980e, + /* 0xee */ + 0x980f, 0x9810, 0x9811, 0x9812, 0x9813, 0x9814, 0x9815, 0x9816, + 0x9817, 0x9818, 0x9819, 0x981a, 0x981b, 0x981c, 0x981d, 0x981e, + 0x981f, 0x9820, 0x9821, 0x9822, 0x9823, 0x9824, 0x9825, 0x9826, + 0x9827, 0x9828, 0x9829, 0x982a, 0x982b, 0x982c, 0x982d, 0x982e, + 0x982f, 0x9830, 0x9831, 0x9832, 0x9833, 0x9834, 0x9835, 0x9836, + 0x9837, 0x9838, 0x9839, 0x983a, 0x983b, 0x983c, 0x983d, 0x983e, + 0x983f, 0x9840, 0x9841, 0x9842, 0x9843, 0x9844, 0x9845, 0x9846, + 0x9847, 0x9848, 0x9849, 0x984a, 0x984b, 0x984c, 0x984d, 0x984e, + 0x984f, 0x9850, 0x9851, 0x9852, 0x9853, 0x9854, 0x9855, 0x9856, + 0x9857, 0x9858, 0x9859, 0x985a, 0x985b, 0x985c, 0x985d, 0x985e, + 0x985f, 0x9860, 0x9861, 0x9862, 0x9863, 0x9864, 0x9865, 0x9866, + 0x9867, 0x9868, 0x9869, 0x986a, 0x986b, 0x986c, 0x986d, 0x986e, + /* 0xef */ + 0x986f, 0x9870, 0x9871, 0x9872, 0x9873, 0x9874, 0x988b, 0x988e, + 0x9892, 0x9895, 0x9899, 0x98a3, 0x98a8, 0x98a9, 0x98aa, 0x98ab, + 0x98ac, 0x98ad, 0x98ae, 0x98af, 0x98b0, 0x98b1, 0x98b2, 0x98b3, + 0x98b4, 0x98b5, 0x98b6, 0x98b7, 0x98b8, 0x98b9, 0x98ba, 0x98bb, + 0x98bc, 0x98bd, 0x98be, 0x98bf, 0x98c0, 0x98c1, 0x98c2, 0x98c3, + 0x98c4, 0x98c5, 0x98c6, 0x98c7, 0x98c8, 0x98c9, 0x98ca, 0x98cb, + 0x98cc, 0x98cd, 0x98cf, 0x98d0, 0x98d4, 0x98d6, 0x98d7, 0x98db, + 0x98dc, 0x98dd, 0x98e0, 0x98e1, 0x98e2, 0x98e3, 0x98e4, 0x98e5, + 0x98e6, 0x98e9, 0x98ea, 0x98eb, 0x98ec, 0x98ed, 0x98ee, 0x98ef, + 0x98f0, 0x98f1, 0x98f2, 0x98f3, 0x98f4, 0x98f5, 0x98f6, 0x98f7, + 0x98f8, 0x98f9, 0x98fa, 0x98fb, 0x98fc, 0x98fd, 0x98fe, 0x98ff, + 0x9900, 0x9901, 0x9902, 0x9903, 0x9904, 0x9905, 0x9906, 0x9907, + /* 0xf0 */ + 0x9908, 0x9909, 0x990a, 0x990b, 0x990c, 0x990e, 0x990f, 0x9911, + 0x9912, 0x9913, 0x9914, 0x9915, 0x9916, 0x9917, 0x9918, 0x9919, + 0x991a, 0x991b, 0x991c, 0x991d, 0x991e, 0x991f, 0x9920, 0x9921, + 0x9922, 0x9923, 0x9924, 0x9925, 0x9926, 0x9927, 0x9928, 0x9929, + 0x992a, 0x992b, 0x992c, 0x992d, 0x992f, 0x9930, 0x9931, 0x9932, + 0x9933, 0x9934, 0x9935, 0x9936, 0x9937, 0x9938, 0x9939, 0x993a, + 0x993b, 0x993c, 0x993d, 0x993e, 0x993f, 0x9940, 0x9941, 0x9942, + 0x9943, 0x9944, 0x9945, 0x9946, 0x9947, 0x9948, 0x9949, 0x994a, + 0x994b, 0x994c, 0x994d, 0x994e, 0x994f, 0x9950, 0x9951, 0x9952, + 0x9953, 0x9956, 0x9957, 0x9958, 0x9959, 0x995a, 0x995b, 0x995c, + 0x995d, 0x995e, 0x995f, 0x9960, 0x9961, 0x9962, 0x9964, 0x9966, + 0x9973, 0x9978, 0x9979, 0x997b, 0x997e, 0x9982, 0x9983, 0x9989, + /* 0xf1 */ + 0x998c, 0x998e, 0x999a, 0x999b, 0x999c, 0x999d, 0x999e, 0x999f, + 0x99a0, 0x99a1, 0x99a2, 0x99a3, 0x99a4, 0x99a6, 0x99a7, 0x99a9, + 0x99aa, 0x99ab, 0x99ac, 0x99ad, 0x99ae, 0x99af, 0x99b0, 0x99b1, + 0x99b2, 0x99b3, 0x99b4, 0x99b5, 0x99b6, 0x99b7, 0x99b8, 0x99b9, + 0x99ba, 0x99bb, 0x99bc, 0x99bd, 0x99be, 0x99bf, 0x99c0, 0x99c1, + 0x99c2, 0x99c3, 0x99c4, 0x99c5, 0x99c6, 0x99c7, 0x99c8, 0x99c9, + 0x99ca, 0x99cb, 0x99cc, 0x99cd, 0x99ce, 0x99cf, 0x99d0, 0x99d1, + 0x99d2, 0x99d3, 0x99d4, 0x99d5, 0x99d6, 0x99d7, 0x99d8, 0x99d9, + 0x99da, 0x99db, 0x99dc, 0x99dd, 0x99de, 0x99df, 0x99e0, 0x99e1, + 0x99e2, 0x99e3, 0x99e4, 0x99e5, 0x99e6, 0x99e7, 0x99e8, 0x99e9, + 0x99ea, 0x99eb, 0x99ec, 0x99ed, 0x99ee, 0x99ef, 0x99f0, 0x99f1, + 0x99f2, 0x99f3, 0x99f4, 0x99f5, 0x99f6, 0x99f7, 0x99f8, 0x99f9, + /* 0xf2 */ + 0x99fa, 0x99fb, 0x99fc, 0x99fd, 0x99fe, 0x99ff, 0x9a00, 0x9a01, + 0x9a02, 0x9a03, 0x9a04, 0x9a05, 0x9a06, 0x9a07, 0x9a08, 0x9a09, + 0x9a0a, 0x9a0b, 0x9a0c, 0x9a0d, 0x9a0e, 0x9a0f, 0x9a10, 0x9a11, + 0x9a12, 0x9a13, 0x9a14, 0x9a15, 0x9a16, 0x9a17, 0x9a18, 0x9a19, + 0x9a1a, 0x9a1b, 0x9a1c, 0x9a1d, 0x9a1e, 0x9a1f, 0x9a20, 0x9a21, + 0x9a22, 0x9a23, 0x9a24, 0x9a25, 0x9a26, 0x9a27, 0x9a28, 0x9a29, + 0x9a2a, 0x9a2b, 0x9a2c, 0x9a2d, 0x9a2e, 0x9a2f, 0x9a30, 0x9a31, + 0x9a32, 0x9a33, 0x9a34, 0x9a35, 0x9a36, 0x9a37, 0x9a38, 0x9a39, + 0x9a3a, 0x9a3b, 0x9a3c, 0x9a3d, 0x9a3e, 0x9a3f, 0x9a40, 0x9a41, + 0x9a42, 0x9a43, 0x9a44, 0x9a45, 0x9a46, 0x9a47, 0x9a48, 0x9a49, + 0x9a4a, 0x9a4b, 0x9a4c, 0x9a4d, 0x9a4e, 0x9a4f, 0x9a50, 0x9a51, + 0x9a52, 0x9a53, 0x9a54, 0x9a55, 0x9a56, 0x9a57, 0x9a58, 0x9a59, + /* 0xf3 */ + 0x9a5a, 0x9a5b, 0x9a5c, 0x9a5d, 0x9a5e, 0x9a5f, 0x9a60, 0x9a61, + 0x9a62, 0x9a63, 0x9a64, 0x9a65, 0x9a66, 0x9a67, 0x9a68, 0x9a69, + 0x9a6a, 0x9a6b, 0x9a72, 0x9a83, 0x9a89, 0x9a8d, 0x9a8e, 0x9a94, + 0x9a95, 0x9a99, 0x9aa6, 0x9aa9, 0x9aaa, 0x9aab, 0x9aac, 0x9aad, + 0x9aae, 0x9aaf, 0x9ab2, 0x9ab3, 0x9ab4, 0x9ab5, 0x9ab9, 0x9abb, + 0x9abd, 0x9abe, 0x9abf, 0x9ac3, 0x9ac4, 0x9ac6, 0x9ac7, 0x9ac8, + 0x9ac9, 0x9aca, 0x9acd, 0x9ace, 0x9acf, 0x9ad0, 0x9ad2, 0x9ad4, + 0x9ad5, 0x9ad6, 0x9ad7, 0x9ad9, 0x9ada, 0x9adb, 0x9adc, 0x9add, + 0x9ade, 0x9ae0, 0x9ae2, 0x9ae3, 0x9ae4, 0x9ae5, 0x9ae7, 0x9ae8, + 0x9ae9, 0x9aea, 0x9aec, 0x9aee, 0x9af0, 0x9af1, 0x9af2, 0x9af3, + 0x9af4, 0x9af5, 0x9af6, 0x9af7, 0x9af8, 0x9afa, 0x9afc, 0x9afd, + 0x9afe, 0x9aff, 0x9b00, 0x9b01, 0x9b02, 0x9b04, 0x9b05, 0x9b06, + /* 0xf4 */ + 0x9b07, 0x9b09, 0x9b0a, 0x9b0b, 0x9b0c, 0x9b0d, 0x9b0e, 0x9b10, + 0x9b11, 0x9b12, 0x9b14, 0x9b15, 0x9b16, 0x9b17, 0x9b18, 0x9b19, + 0x9b1a, 0x9b1b, 0x9b1c, 0x9b1d, 0x9b1e, 0x9b20, 0x9b21, 0x9b22, + 0x9b24, 0x9b25, 0x9b26, 0x9b27, 0x9b28, 0x9b29, 0x9b2a, 0x9b2b, + 0x9b2c, 0x9b2d, 0x9b2e, 0x9b30, 0x9b31, 0x9b33, 0x9b34, 0x9b35, + 0x9b36, 0x9b37, 0x9b38, 0x9b39, 0x9b3a, 0x9b3d, 0x9b3e, 0x9b3f, + 0x9b40, 0x9b46, 0x9b4a, 0x9b4b, 0x9b4c, 0x9b4e, 0x9b50, 0x9b52, + 0x9b53, 0x9b55, 0x9b56, 0x9b57, 0x9b58, 0x9b59, 0x9b5a, 0x9b5b, + 0x9b5c, 0x9b5d, 0x9b5e, 0x9b5f, 0x9b60, 0x9b61, 0x9b62, 0x9b63, + 0x9b64, 0x9b65, 0x9b66, 0x9b67, 0x9b68, 0x9b69, 0x9b6a, 0x9b6b, + 0x9b6c, 0x9b6d, 0x9b6e, 0x9b6f, 0x9b70, 0x9b71, 0x9b72, 0x9b73, + 0x9b74, 0x9b75, 0x9b76, 0x9b77, 0x9b78, 0x9b79, 0x9b7a, 0x9b7b, + /* 0xf5 */ + 0x9b7c, 0x9b7d, 0x9b7e, 0x9b7f, 0x9b80, 0x9b81, 0x9b82, 0x9b83, + 0x9b84, 0x9b85, 0x9b86, 0x9b87, 0x9b88, 0x9b89, 0x9b8a, 0x9b8b, + 0x9b8c, 0x9b8d, 0x9b8e, 0x9b8f, 0x9b90, 0x9b91, 0x9b92, 0x9b93, + 0x9b94, 0x9b95, 0x9b96, 0x9b97, 0x9b98, 0x9b99, 0x9b9a, 0x9b9b, + 0x9b9c, 0x9b9d, 0x9b9e, 0x9b9f, 0x9ba0, 0x9ba1, 0x9ba2, 0x9ba3, + 0x9ba4, 0x9ba5, 0x9ba6, 0x9ba7, 0x9ba8, 0x9ba9, 0x9baa, 0x9bab, + 0x9bac, 0x9bad, 0x9bae, 0x9baf, 0x9bb0, 0x9bb1, 0x9bb2, 0x9bb3, + 0x9bb4, 0x9bb5, 0x9bb6, 0x9bb7, 0x9bb8, 0x9bb9, 0x9bba, 0x9bbb, + 0x9bbc, 0x9bbd, 0x9bbe, 0x9bbf, 0x9bc0, 0x9bc1, 0x9bc2, 0x9bc3, + 0x9bc4, 0x9bc5, 0x9bc6, 0x9bc7, 0x9bc8, 0x9bc9, 0x9bca, 0x9bcb, + 0x9bcc, 0x9bcd, 0x9bce, 0x9bcf, 0x9bd0, 0x9bd1, 0x9bd2, 0x9bd3, + 0x9bd4, 0x9bd5, 0x9bd6, 0x9bd7, 0x9bd8, 0x9bd9, 0x9bda, 0x9bdb, + /* 0xf6 */ + 0x9bdc, 0x9bdd, 0x9bde, 0x9bdf, 0x9be0, 0x9be1, 0x9be2, 0x9be3, + 0x9be4, 0x9be5, 0x9be6, 0x9be7, 0x9be8, 0x9be9, 0x9bea, 0x9beb, + 0x9bec, 0x9bed, 0x9bee, 0x9bef, 0x9bf0, 0x9bf1, 0x9bf2, 0x9bf3, + 0x9bf4, 0x9bf5, 0x9bf6, 0x9bf7, 0x9bf8, 0x9bf9, 0x9bfa, 0x9bfb, + 0x9bfc, 0x9bfd, 0x9bfe, 0x9bff, 0x9c00, 0x9c01, 0x9c02, 0x9c03, + 0x9c04, 0x9c05, 0x9c06, 0x9c07, 0x9c08, 0x9c09, 0x9c0a, 0x9c0b, + 0x9c0c, 0x9c0d, 0x9c0e, 0x9c0f, 0x9c10, 0x9c11, 0x9c12, 0x9c13, + 0x9c14, 0x9c15, 0x9c16, 0x9c17, 0x9c18, 0x9c19, 0x9c1a, 0x9c1b, + 0x9c1c, 0x9c1d, 0x9c1e, 0x9c1f, 0x9c20, 0x9c21, 0x9c22, 0x9c23, + 0x9c24, 0x9c25, 0x9c26, 0x9c27, 0x9c28, 0x9c29, 0x9c2a, 0x9c2b, + 0x9c2c, 0x9c2d, 0x9c2e, 0x9c2f, 0x9c30, 0x9c31, 0x9c32, 0x9c33, + 0x9c34, 0x9c35, 0x9c36, 0x9c37, 0x9c38, 0x9c39, 0x9c3a, 0x9c3b, + /* 0xf7 */ + 0x9c3c, 0x9c3d, 0x9c3e, 0x9c3f, 0x9c40, 0x9c41, 0x9c42, 0x9c43, + 0x9c44, 0x9c45, 0x9c46, 0x9c47, 0x9c48, 0x9c49, 0x9c4a, 0x9c4b, + 0x9c4c, 0x9c4d, 0x9c4e, 0x9c4f, 0x9c50, 0x9c51, 0x9c52, 0x9c53, + 0x9c54, 0x9c55, 0x9c56, 0x9c57, 0x9c58, 0x9c59, 0x9c5a, 0x9c5b, + 0x9c5c, 0x9c5d, 0x9c5e, 0x9c5f, 0x9c60, 0x9c61, 0x9c62, 0x9c63, + 0x9c64, 0x9c65, 0x9c66, 0x9c67, 0x9c68, 0x9c69, 0x9c6a, 0x9c6b, + 0x9c6c, 0x9c6d, 0x9c6e, 0x9c6f, 0x9c70, 0x9c71, 0x9c72, 0x9c73, + 0x9c74, 0x9c75, 0x9c76, 0x9c77, 0x9c78, 0x9c79, 0x9c7a, 0x9c7b, + 0x9c7d, 0x9c7e, 0x9c80, 0x9c83, 0x9c84, 0x9c89, 0x9c8a, 0x9c8c, + 0x9c8f, 0x9c93, 0x9c96, 0x9c97, 0x9c98, 0x9c99, 0x9c9d, 0x9caa, + 0x9cac, 0x9caf, 0x9cb9, 0x9cbe, 0x9cbf, 0x9cc0, 0x9cc1, 0x9cc2, + 0x9cc8, 0x9cc9, 0x9cd1, 0x9cd2, 0x9cda, 0x9cdb, 0x9ce0, 0x9ce1, + /* 0xf8 */ + 0x9ce3, 0x9ce4, 0x9ce5, 0x9ce6, 0x9ce7, 0x9ce8, 0x9ce9, 0x9cea, + 0x9ceb, 0x9cec, 0x9ced, 0x9cee, 0x9cef, 0x9cf0, 0x9cf1, 0x9cf2, + 0x9cf3, 0x9cf4, 0x9cf5, 0x9cf6, 0x9cf7, 0x9cf8, 0x9cf9, 0x9cfa, + 0x9cfb, 0x9cfc, 0x9cfd, 0x9cfe, 0x9cff, 0x9d00, 0x9d01, 0x9d02, + 0x9d03, 0x9d04, 0x9d05, 0x9d06, 0x9d07, 0x9d08, 0x9d09, 0x9d0a, + 0x9d0b, 0x9d0c, 0x9d0d, 0x9d0e, 0x9d0f, 0x9d10, 0x9d11, 0x9d12, + 0x9d13, 0x9d14, 0x9d15, 0x9d16, 0x9d17, 0x9d18, 0x9d19, 0x9d1a, + 0x9d1b, 0x9d1c, 0x9d1d, 0x9d1e, 0x9d1f, 0x9d20, 0x9d21, 0x9d22, + 0x9d23, 0x9d24, 0x9d25, 0x9d26, 0x9d27, 0x9d28, 0x9d29, 0x9d2a, + 0x9d2b, 0x9d2c, 0x9d2d, 0x9d2e, 0x9d2f, 0x9d30, 0x9d31, 0x9d32, + 0x9d33, 0x9d34, 0x9d35, 0x9d36, 0x9d37, 0x9d38, 0x9d39, 0x9d3a, + 0x9d3b, 0x9d3c, 0x9d3d, 0x9d3e, 0x9d3f, 0x9d40, 0x9d41, 0x9d42, + /* 0xf9 */ + 0x9d43, 0x9d44, 0x9d45, 0x9d46, 0x9d47, 0x9d48, 0x9d49, 0x9d4a, + 0x9d4b, 0x9d4c, 0x9d4d, 0x9d4e, 0x9d4f, 0x9d50, 0x9d51, 0x9d52, + 0x9d53, 0x9d54, 0x9d55, 0x9d56, 0x9d57, 0x9d58, 0x9d59, 0x9d5a, + 0x9d5b, 0x9d5c, 0x9d5d, 0x9d5e, 0x9d5f, 0x9d60, 0x9d61, 0x9d62, + 0x9d63, 0x9d64, 0x9d65, 0x9d66, 0x9d67, 0x9d68, 0x9d69, 0x9d6a, + 0x9d6b, 0x9d6c, 0x9d6d, 0x9d6e, 0x9d6f, 0x9d70, 0x9d71, 0x9d72, + 0x9d73, 0x9d74, 0x9d75, 0x9d76, 0x9d77, 0x9d78, 0x9d79, 0x9d7a, + 0x9d7b, 0x9d7c, 0x9d7d, 0x9d7e, 0x9d7f, 0x9d80, 0x9d81, 0x9d82, + 0x9d83, 0x9d84, 0x9d85, 0x9d86, 0x9d87, 0x9d88, 0x9d89, 0x9d8a, + 0x9d8b, 0x9d8c, 0x9d8d, 0x9d8e, 0x9d8f, 0x9d90, 0x9d91, 0x9d92, + 0x9d93, 0x9d94, 0x9d95, 0x9d96, 0x9d97, 0x9d98, 0x9d99, 0x9d9a, + 0x9d9b, 0x9d9c, 0x9d9d, 0x9d9e, 0x9d9f, 0x9da0, 0x9da1, 0x9da2, + /* 0xfa */ + 0x9da3, 0x9da4, 0x9da5, 0x9da6, 0x9da7, 0x9da8, 0x9da9, 0x9daa, + 0x9dab, 0x9dac, 0x9dad, 0x9dae, 0x9daf, 0x9db0, 0x9db1, 0x9db2, + 0x9db3, 0x9db4, 0x9db5, 0x9db6, 0x9db7, 0x9db8, 0x9db9, 0x9dba, + 0x9dbb, 0x9dbc, 0x9dbd, 0x9dbe, 0x9dbf, 0x9dc0, 0x9dc1, 0x9dc2, + 0x9dc3, 0x9dc4, 0x9dc5, 0x9dc6, 0x9dc7, 0x9dc8, 0x9dc9, 0x9dca, + 0x9dcb, 0x9dcc, 0x9dcd, 0x9dce, 0x9dcf, 0x9dd0, 0x9dd1, 0x9dd2, + 0x9dd3, 0x9dd4, 0x9dd5, 0x9dd6, 0x9dd7, 0x9dd8, 0x9dd9, 0x9dda, + 0x9ddb, 0x9ddc, 0x9ddd, 0x9dde, 0x9ddf, 0x9de0, 0x9de1, 0x9de2, + 0x9de3, 0x9de4, 0x9de5, 0x9de6, 0x9de7, 0x9de8, 0x9de9, 0x9dea, + 0x9deb, 0x9dec, 0x9ded, 0x9dee, 0x9def, 0x9df0, 0x9df1, 0x9df2, + 0x9df3, 0x9df4, 0x9df5, 0x9df6, 0x9df7, 0x9df8, 0x9df9, 0x9dfa, + 0x9dfb, 0x9dfc, 0x9dfd, 0x9dfe, 0x9dff, 0x9e00, 0x9e01, 0x9e02, + /* 0xfb */ + 0x9e03, 0x9e04, 0x9e05, 0x9e06, 0x9e07, 0x9e08, 0x9e09, 0x9e0a, + 0x9e0b, 0x9e0c, 0x9e0d, 0x9e0e, 0x9e0f, 0x9e10, 0x9e11, 0x9e12, + 0x9e13, 0x9e14, 0x9e15, 0x9e16, 0x9e17, 0x9e18, 0x9e19, 0x9e1a, + 0x9e1b, 0x9e1c, 0x9e1d, 0x9e1e, 0x9e24, 0x9e27, 0x9e2e, 0x9e30, + 0x9e34, 0x9e3b, 0x9e3c, 0x9e40, 0x9e4d, 0x9e50, 0x9e52, 0x9e53, + 0x9e54, 0x9e56, 0x9e59, 0x9e5d, 0x9e5f, 0x9e60, 0x9e61, 0x9e62, + 0x9e65, 0x9e6e, 0x9e6f, 0x9e72, 0x9e74, 0x9e75, 0x9e76, 0x9e77, + 0x9e78, 0x9e79, 0x9e7a, 0x9e7b, 0x9e7c, 0x9e7d, 0x9e80, 0x9e81, + 0x9e83, 0x9e84, 0x9e85, 0x9e86, 0x9e89, 0x9e8a, 0x9e8c, 0x9e8d, + 0x9e8e, 0x9e8f, 0x9e90, 0x9e91, 0x9e94, 0x9e95, 0x9e96, 0x9e97, + 0x9e98, 0x9e99, 0x9e9a, 0x9e9b, 0x9e9c, 0x9e9e, 0x9ea0, 0x9ea1, + 0x9ea2, 0x9ea3, 0x9ea4, 0x9ea5, 0x9ea7, 0x9ea8, 0x9ea9, 0x9eaa, + /* 0xfc */ + 0x9eab, 0x9eac, 0x9ead, 0x9eae, 0x9eaf, 0x9eb0, 0x9eb1, 0x9eb2, + 0x9eb3, 0x9eb5, 0x9eb6, 0x9eb7, 0x9eb9, 0x9eba, 0x9ebc, 0x9ebf, + 0x9ec0, 0x9ec1, 0x9ec2, 0x9ec3, 0x9ec5, 0x9ec6, 0x9ec7, 0x9ec8, + 0x9eca, 0x9ecb, 0x9ecc, 0x9ed0, 0x9ed2, 0x9ed3, 0x9ed5, 0x9ed6, + 0x9ed7, 0x9ed9, 0x9eda, 0x9ede, 0x9ee1, 0x9ee3, 0x9ee4, 0x9ee6, + 0x9ee8, 0x9eeb, 0x9eec, 0x9eed, 0x9eee, 0x9ef0, 0x9ef1, 0x9ef2, + 0x9ef3, 0x9ef4, 0x9ef5, 0x9ef6, 0x9ef7, 0x9ef8, 0x9efa, 0x9efd, + 0x9eff, 0x9f00, 0x9f01, 0x9f02, 0x9f03, 0x9f04, 0x9f05, 0x9f06, + 0x9f07, 0x9f08, 0x9f09, 0x9f0a, 0x9f0c, 0x9f0f, 0x9f11, 0x9f12, + 0x9f14, 0x9f15, 0x9f16, 0x9f18, 0x9f1a, 0x9f1b, 0x9f1c, 0x9f1d, + 0x9f1e, 0x9f1f, 0x9f21, 0x9f23, 0x9f24, 0x9f25, 0x9f26, 0x9f27, + 0x9f28, 0x9f29, 0x9f2a, 0x9f2b, 0x9f2d, 0x9f2e, 0x9f30, 0x9f31, + /* 0xfd */ + 0x9f32, 0x9f33, 0x9f34, 0x9f35, 0x9f36, 0x9f38, 0x9f3a, 0x9f3c, + 0x9f3f, 0x9f40, 0x9f41, 0x9f42, 0x9f43, 0x9f45, 0x9f46, 0x9f47, + 0x9f48, 0x9f49, 0x9f4a, 0x9f4b, 0x9f4c, 0x9f4d, 0x9f4e, 0x9f4f, + 0x9f52, 0x9f53, 0x9f54, 0x9f55, 0x9f56, 0x9f57, 0x9f58, 0x9f59, + 0x9f5a, 0x9f5b, 0x9f5c, 0x9f5d, 0x9f5e, 0x9f5f, 0x9f60, 0x9f61, + 0x9f62, 0x9f63, 0x9f64, 0x9f65, 0x9f66, 0x9f67, 0x9f68, 0x9f69, + 0x9f6a, 0x9f6b, 0x9f6c, 0x9f6d, 0x9f6e, 0x9f6f, 0x9f70, 0x9f71, + 0x9f72, 0x9f73, 0x9f74, 0x9f75, 0x9f76, 0x9f77, 0x9f78, 0x9f79, + 0x9f7a, 0x9f7b, 0x9f7c, 0x9f7d, 0x9f7e, 0x9f81, 0x9f82, 0x9f8d, + 0x9f8e, 0x9f8f, 0x9f90, 0x9f91, 0x9f92, 0x9f93, 0x9f94, 0x9f95, + 0x9f96, 0x9f97, 0x9f98, 0x9f9c, 0x9f9d, 0x9f9e, 0x9fa1, 0x9fa2, + 0x9fa3, 0x9fa4, 0x9fa5, 0xf92c, 0xf979, 0xf995, 0xf9e7, 0xf9f1, + /* 0xfe */ + 0xfa0c, 0xfa0d, 0xfa0e, 0xfa0f, 0xfa11, 0xfa13, 0xfa14, 0xfa18, + 0xfa1f, 0xfa20, 0xfa21, 0xfa23, 0xfa24, 0xfa27, 0xfa28, 0xfa29, +}; + +static int +gbkext2_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0xa8 && c1 <= 0xfe)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0x80 && c2 < 0xa1)) { + unsigned int i = 96 * (c1 - 0x81) + (c2 - (c2 >= 0x80 ? 0x41 : 0x40)); + unsigned short wc = 0xfffd; + { + if (i < 12016) + wc = gbkext2_2uni_pagea8[i-3744]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + diff --git a/libs/libiconv/lib/gbkext_inv.h b/libs/libiconv/lib/gbkext_inv.h new file mode 100644 index 00000000..45f57d9b --- /dev/null +++ b/libs/libiconv/lib/gbkext_inv.h @@ -0,0 +1,2343 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * GBK extensions + */ + +static const unsigned short gbkext_inv_2charset[14313] = { + 0xa840, 0xa841, 0xa842, 0xa95c, 0xa843, 0xa844, 0xa845, 0xa846, + 0xa847, 0xa848, 0xa959, 0xa849, 0xa84a, 0xa84b, 0xa84c, 0xa84d, + 0xa84e, 0xa84f, 0xa850, 0xa851, 0xa852, 0xa892, 0xa853, 0xa854, + 0xa855, 0xa856, 0xa857, 0xa858, 0xa859, 0xa85a, 0xa85b, 0xa85c, + 0xa85d, 0xa85e, 0xa85f, 0xa860, 0xa861, 0xa862, 0xa863, 0xa864, + 0xa865, 0xa866, 0xa867, 0xa868, 0xa869, 0xa86a, 0xa86b, 0xa86c, + 0xa86d, 0xa86e, 0xa86f, 0xa870, 0xa871, 0xa872, 0xa873, 0xa874, + 0xa875, 0xa876, 0xa877, 0xa878, 0xa879, 0xa87a, 0xa87b, 0xa87c, + 0xa87d, 0xa87e, 0xa880, 0xa881, 0xa882, 0xa883, 0xa884, 0xa885, + 0xa886, 0xa887, 0xa888, 0xa889, 0xa88a, 0xa88b, 0xa88c, 0xa88d, + 0xa88e, 0xa88f, 0xa890, 0xa891, 0xa965, 0xa996, 0xa893, 0xa894, + 0xa895, 0xa940, 0xa941, 0xa942, 0xa943, 0xa944, 0xa945, 0xa946, + 0xa947, 0xa948, 0xa961, 0xa962, 0xa966, 0xa967, 0xa960, 0xa963, + 0xa964, 0xa95a, 0xa949, 0xa94a, 0xa94b, 0xa94c, 0xa94d, 0xa94e, + 0xa94f, 0xa950, 0xa951, 0xa952, 0xa953, 0xa954, 0x8140, 0x8141, + 0x8142, 0x8143, 0x8144, 0x8145, 0x8146, 0x8147, 0x8148, 0x8149, + 0x814a, 0x814b, 0x814c, 0x814d, 0x814e, 0x814f, 0x8150, 0x8151, + 0x8152, 0x8153, 0x8154, 0x8155, 0x8156, 0x8157, 0x8158, 0x8159, + 0x815a, 0x815b, 0x815c, 0x815d, 0x815e, 0x815f, 0x8160, 0x8161, + 0x8162, 0x8163, 0x8164, 0x8165, 0x8166, 0x8167, 0x8168, 0x8169, + 0x816a, 0x816b, 0x816c, 0x816d, 0x816e, 0x816f, 0x8170, 0x8171, + 0x8172, 0x8173, 0x8174, 0x8175, 0x8176, 0x8177, 0x8178, 0x8179, + 0x817a, 0x817b, 0x817c, 0x817d, 0x817e, 0x8180, 0x8181, 0x8182, + 0x8183, 0x8184, 0x8185, 0x8186, 0x8187, 0x8188, 0x8189, 0x818a, + 0x818b, 0x818c, 0x818d, 0x818e, 0x818f, 0x8190, 0x8191, 0x8192, + 0x8193, 0x8194, 0x8195, 0x8196, 0x8197, 0x8198, 0x8199, 0x819a, + 0x819b, 0x819c, 0x819d, 0x819e, 0x819f, 0x81a0, 0x81a1, 0x81a2, + 0x81a3, 0x81a4, 0x81a5, 0x81a6, 0x81a7, 0x81a8, 0x81a9, 0x81aa, + 0x81ab, 0x81ac, 0x81ad, 0x81ae, 0x81af, 0x81b0, 0x81b1, 0x81b2, + 0x81b3, 0x81b4, 0x81b5, 0x81b6, 0x81b7, 0x81b8, 0x81b9, 0x81ba, + 0x81bb, 0x81bc, 0x81bd, 0x81be, 0x81bf, 0x81c0, 0x81c1, 0x81c2, + 0x81c3, 0x81c4, 0x81c5, 0x81c6, 0x81c7, 0x81c8, 0x81c9, 0x81ca, + 0x81cb, 0x81cc, 0x81cd, 0x81ce, 0x81cf, 0x81d0, 0x81d1, 0x81d2, + 0x81d3, 0x81d4, 0x81d5, 0x81d6, 0x81d7, 0x81d8, 0x81d9, 0x81da, + 0x81db, 0x81dc, 0x81dd, 0x81de, 0x81df, 0x81e0, 0x81e1, 0x81e2, + 0x81e3, 0x81e4, 0x81e5, 0x81e6, 0x81e7, 0x81e8, 0x81e9, 0x81ea, + 0x81eb, 0x81ec, 0x81ed, 0x81ee, 0x81ef, 0x81f0, 0x81f1, 0x81f2, + 0x81f3, 0x81f4, 0x81f5, 0x81f6, 0x81f7, 0x81f8, 0x81f9, 0x81fa, + 0x81fb, 0x81fc, 0x81fd, 0x81fe, 0x8240, 0x8241, 0x8242, 0x8243, + 0x8244, 0x8245, 0x8246, 0x8247, 0x8248, 0x8249, 0x824a, 0x824b, + 0x824c, 0x824d, 0x824e, 0x824f, 0x8250, 0x8251, 0x8252, 0x8253, + 0x8254, 0x8255, 0x8256, 0x8257, 0x8258, 0x8259, 0x825a, 0x825b, + 0x825c, 0x825d, 0x825e, 0x825f, 0x8260, 0x8261, 0x8262, 0x8263, + 0x8264, 0x8265, 0x8266, 0x8267, 0x8268, 0x8269, 0x826a, 0x826b, + 0x826c, 0x826d, 0x826e, 0x826f, 0x8270, 0x8271, 0x8272, 0x8273, + 0x8274, 0x8275, 0x8276, 0x8277, 0x8278, 0x8279, 0x827a, 0x827b, + 0x827c, 0x827d, 0x827e, 0x8280, 0x8281, 0x8282, 0x8283, 0x8284, + 0x8285, 0x8286, 0x8287, 0x8288, 0x8289, 0x828a, 0x828b, 0x828c, + 0x828d, 0x828e, 0x828f, 0x8290, 0x8291, 0x8292, 0x8293, 0x8294, + 0x8295, 0x8296, 0x8297, 0x8298, 0x8299, 0x829a, 0x829b, 0x829c, + 0x829d, 0x829e, 0x829f, 0x82a0, 0x82a1, 0x82a2, 0x82a3, 0x82a4, + 0x82a5, 0x82a6, 0x82a7, 0x82a8, 0x82a9, 0x82aa, 0x82ab, 0x82ac, + 0x82ad, 0x82ae, 0x82af, 0x82b0, 0x82b1, 0x82b2, 0x82b3, 0x82b4, + 0x82b5, 0x82b6, 0x82b7, 0x82b8, 0x82b9, 0x82ba, 0x82bb, 0x82bc, + 0x82bd, 0x82be, 0x82bf, 0x82c0, 0x82c1, 0x82c2, 0x82c3, 0x82c4, + 0x82c5, 0x82c6, 0x82c7, 0x82c8, 0x82c9, 0x82ca, 0x82cb, 0x82cc, + 0x82cd, 0x82ce, 0x82cf, 0x82d0, 0x82d1, 0x82d2, 0x82d3, 0x82d4, + 0x82d5, 0x82d6, 0x82d7, 0x82d8, 0x82d9, 0x82da, 0x82db, 0x82dc, + 0x82dd, 0x82de, 0x82df, 0x82e0, 0x82e1, 0x82e2, 0x82e3, 0x82e4, + 0x82e5, 0x82e6, 0x82e7, 0x82e8, 0x82e9, 0x82ea, 0x82eb, 0x82ec, + 0x82ed, 0x82ee, 0x82ef, 0x82f0, 0x82f1, 0x82f2, 0x82f3, 0x82f4, + 0x82f5, 0x82f6, 0x82f7, 0x82f8, 0x82f9, 0x82fa, 0x82fb, 0x82fc, + 0x82fd, 0x82fe, 0x8340, 0x8341, 0x8342, 0x8343, 0x8344, 0x8345, + 0x8346, 0x8347, 0x8348, 0x8349, 0x834a, 0x834b, 0x834c, 0x834d, + 0x834e, 0x834f, 0x8350, 0x8351, 0x8352, 0x8353, 0x8354, 0x8355, + 0x8356, 0x8357, 0x8358, 0x8359, 0x835a, 0x835b, 0x835c, 0x835d, + 0x835e, 0x835f, 0x8360, 0x8361, 0x8362, 0x8363, 0x8364, 0x8365, + 0x8366, 0x8367, 0x8368, 0x8369, 0x836a, 0x836b, 0x836c, 0x836d, + 0x836e, 0x836f, 0x8370, 0x8371, 0x8372, 0x8373, 0x8374, 0x8375, + 0x8376, 0x8377, 0x8378, 0x8379, 0x837a, 0x837b, 0x837c, 0x837d, + 0x837e, 0x8380, 0x8381, 0x8382, 0x8383, 0x8384, 0x8385, 0x8386, + 0x8387, 0x8388, 0x8389, 0x838a, 0x838b, 0x838c, 0x838d, 0x838e, + 0x838f, 0x8390, 0x8391, 0x8392, 0x8393, 0x8394, 0x8395, 0x8396, + 0x8397, 0x8398, 0x8399, 0x839a, 0x839b, 0x839c, 0x839d, 0x839e, + 0x839f, 0x83a0, 0x83a1, 0x83a2, 0x83a3, 0x83a4, 0x83a5, 0x83a6, + 0x83a7, 0x83a8, 0x83a9, 0x83aa, 0x83ab, 0x83ac, 0x83ad, 0x83ae, + 0x83af, 0x83b0, 0x83b1, 0x83b2, 0x83b3, 0x83b4, 0x83b5, 0x83b6, + 0x83b7, 0x83b8, 0x83b9, 0x83ba, 0x83bb, 0x83bc, 0x83bd, 0x83be, + 0x83bf, 0x83c0, 0x83c1, 0x83c2, 0x83c3, 0x83c4, 0x83c5, 0x83c6, + 0x83c7, 0x83c8, 0x83c9, 0x83ca, 0x83cb, 0x83cc, 0x83cd, 0x83ce, + 0x83cf, 0x83d0, 0x83d1, 0x83d2, 0x83d3, 0x83d4, 0x83d5, 0x83d6, + 0x83d7, 0x83d8, 0x83d9, 0x83da, 0x83db, 0x83dc, 0x83dd, 0x83de, + 0x83df, 0x83e0, 0x83e1, 0x83e2, 0x83e3, 0x83e4, 0x83e5, 0x83e6, + 0x83e7, 0x83e8, 0x83e9, 0x83ea, 0x83eb, 0x83ec, 0x83ed, 0x83ee, + 0x83ef, 0x83f0, 0x83f1, 0x83f2, 0x83f3, 0x83f4, 0x83f5, 0x83f6, + 0x83f7, 0x83f8, 0x83f9, 0x83fa, 0x83fb, 0x83fc, 0x83fd, 0x83fe, + 0x8440, 0x8441, 0x8442, 0x8443, 0x8444, 0x8445, 0x8446, 0x8447, + 0x8448, 0x8449, 0x844a, 0x844b, 0x844c, 0x844d, 0x844e, 0x844f, + 0x8450, 0x8451, 0x8452, 0x8453, 0x8454, 0x8455, 0x8456, 0x8457, + 0x8458, 0x8459, 0x845a, 0x845b, 0x845c, 0x845d, 0x845e, 0x845f, + 0x8460, 0x8461, 0x8462, 0x8463, 0x8464, 0x8465, 0x8466, 0x8467, + 0x8468, 0x8469, 0x846a, 0x846b, 0x846c, 0x846d, 0x846e, 0x846f, + 0x8470, 0x8471, 0x8472, 0x8473, 0x8474, 0x8475, 0x8476, 0x8477, + 0x8478, 0x8479, 0x847a, 0x847b, 0x847c, 0x847d, 0x847e, 0x8480, + 0x8481, 0x8482, 0x8483, 0x8484, 0x8485, 0x8486, 0x8487, 0x8488, + 0x8489, 0x848a, 0x848b, 0x848c, 0x848d, 0x848e, 0x848f, 0x8490, + 0x8491, 0x8492, 0x8493, 0x8494, 0x8495, 0x8496, 0x8497, 0x8498, + 0x8499, 0x849a, 0x849b, 0x849c, 0x849d, 0x849e, 0x849f, 0x84a0, + 0x84a1, 0x84a2, 0x84a3, 0x84a4, 0x84a5, 0x84a6, 0x84a7, 0x84a8, + 0x84a9, 0x84aa, 0x84ab, 0x84ac, 0x84ad, 0x84ae, 0x84af, 0x84b0, + 0x84b1, 0x84b2, 0x84b3, 0x84b4, 0x84b5, 0x84b6, 0x84b7, 0x84b8, + 0x84b9, 0x84ba, 0x84bb, 0x84bc, 0x84bd, 0x84be, 0x84bf, 0x84c0, + 0x84c1, 0x84c2, 0x84c3, 0x84c4, 0x84c5, 0x84c6, 0x84c7, 0x84c8, + 0x84c9, 0x84ca, 0x84cb, 0x84cc, 0x84cd, 0x84ce, 0x84cf, 0x84d0, + 0x84d1, 0x84d2, 0x84d3, 0x84d4, 0x84d5, 0x84d6, 0x84d7, 0x84d8, + 0x84d9, 0x84da, 0x84db, 0x84dc, 0x84dd, 0x84de, 0x84df, 0x84e0, + 0x84e1, 0x84e2, 0x84e3, 0x84e4, 0x84e5, 0x84e6, 0x84e7, 0x84e8, + 0x84e9, 0x84ea, 0x84eb, 0x84ec, 0x84ed, 0x84ee, 0x84ef, 0x84f0, + 0x84f1, 0x84f2, 0x84f3, 0x84f4, 0x84f5, 0x84f6, 0x84f7, 0x84f8, + 0x84f9, 0x84fa, 0x84fb, 0x84fc, 0x84fd, 0x84fe, 0x8540, 0x8541, + 0x8542, 0x8543, 0x8544, 0x8545, 0x8546, 0x8547, 0x8548, 0x8549, + 0x854a, 0x854b, 0x854c, 0x854d, 0x854e, 0x854f, 0x8550, 0x8551, + 0x8552, 0x8553, 0x8554, 0x8555, 0x8556, 0x8557, 0x8558, 0x8559, + 0x855a, 0x855b, 0x855c, 0x855d, 0x855e, 0x855f, 0x8560, 0x8561, + 0x8562, 0x8563, 0x8564, 0x8565, 0x8566, 0x8567, 0x8568, 0x8569, + 0x856a, 0x856b, 0x856c, 0x856d, 0x856e, 0x856f, 0x8570, 0x8571, + 0x8572, 0x8573, 0x8574, 0x8575, 0x8576, 0x8577, 0x8578, 0x8579, + 0x857a, 0x857b, 0x857c, 0x857d, 0x857e, 0x8580, 0x8581, 0x8582, + 0x8583, 0x8584, 0x8585, 0x8586, 0x8587, 0x8588, 0x8589, 0x858a, + 0x858b, 0x858c, 0x858d, 0x858e, 0x858f, 0x8590, 0x8591, 0x8592, + 0x8593, 0x8594, 0x8595, 0x8596, 0x8597, 0x8598, 0x8599, 0x859a, + 0x859b, 0x859c, 0x859d, 0x859e, 0x859f, 0x85a0, 0x85a1, 0x85a2, + 0x85a3, 0x85a4, 0x85a5, 0x85a6, 0x85a7, 0x85a8, 0x85a9, 0x85aa, + 0x85ab, 0x85ac, 0x85ad, 0x85ae, 0x85af, 0x85b0, 0x85b1, 0x85b2, + 0x85b3, 0x85b4, 0x85b5, 0x85b6, 0x85b7, 0x85b8, 0x85b9, 0x85ba, + 0x85bb, 0x85bc, 0x85bd, 0x85be, 0x85bf, 0x85c0, 0x85c1, 0x85c2, + 0x85c3, 0x85c4, 0x85c5, 0x85c6, 0x85c7, 0x85c8, 0x85c9, 0x85ca, + 0x85cb, 0x85cc, 0x85cd, 0x85ce, 0x85cf, 0x85d0, 0x85d1, 0x85d2, + 0x85d3, 0x85d4, 0x85d5, 0x85d6, 0x85d7, 0x85d8, 0x85d9, 0x85da, + 0x85db, 0x85dc, 0x85dd, 0x85de, 0x85df, 0x85e0, 0x85e1, 0x85e2, + 0x85e3, 0x85e4, 0x85e5, 0x85e6, 0x85e7, 0x85e8, 0x85e9, 0x85ea, + 0x85eb, 0x85ec, 0x85ed, 0x85ee, 0x85ef, 0x85f0, 0x85f1, 0x85f2, + 0x85f3, 0x85f4, 0x85f5, 0x85f6, 0x85f7, 0x85f8, 0x85f9, 0x85fa, + 0x85fb, 0x85fc, 0x85fd, 0x85fe, 0x8640, 0x8641, 0x8642, 0x8643, + 0x8644, 0x8645, 0x8646, 0x8647, 0x8648, 0x8649, 0x864a, 0x864b, + 0x864c, 0x864d, 0x864e, 0x864f, 0x8650, 0x8651, 0x8652, 0x8653, + 0x8654, 0x8655, 0x8656, 0x8657, 0x8658, 0x8659, 0x865a, 0x865b, + 0x865c, 0x865d, 0x865e, 0x865f, 0x8660, 0x8661, 0x8662, 0x8663, + 0x8664, 0x8665, 0x8666, 0x8667, 0x8668, 0x8669, 0x866a, 0x866b, + 0x866c, 0x866d, 0x866e, 0x866f, 0x8670, 0x8671, 0x8672, 0x8673, + 0x8674, 0x8675, 0x8676, 0x8677, 0x8678, 0x8679, 0x867a, 0x867b, + 0x867c, 0x867d, 0x867e, 0x8680, 0x8681, 0x8682, 0x8683, 0x8684, + 0x8685, 0x8686, 0x8687, 0x8688, 0x8689, 0x868a, 0x868b, 0x868c, + 0x868d, 0x868e, 0x868f, 0x8690, 0x8691, 0x8692, 0x8693, 0x8694, + 0x8695, 0x8696, 0x8697, 0x8698, 0x8699, 0x869a, 0x869b, 0x869c, + 0x869d, 0x869e, 0x869f, 0x86a0, 0x86a1, 0x86a2, 0x86a3, 0x86a4, + 0x86a5, 0x86a6, 0x86a7, 0x86a8, 0x86a9, 0x86aa, 0x86ab, 0x86ac, + 0x86ad, 0x86ae, 0x86af, 0x86b0, 0x86b1, 0x86b2, 0x86b3, 0x86b4, + 0x86b5, 0x86b6, 0x86b7, 0x86b8, 0x86b9, 0x86ba, 0x86bb, 0x86bc, + 0x86bd, 0x86be, 0x86bf, 0x86c0, 0x86c1, 0x86c2, 0x86c3, 0x86c4, + 0x86c5, 0x86c6, 0x86c7, 0x86c8, 0x86c9, 0x86ca, 0x86cb, 0x86cc, + 0x86cd, 0x86ce, 0x86cf, 0x86d0, 0x86d1, 0x86d2, 0x86d3, 0x86d4, + 0x86d5, 0x86d6, 0x86d7, 0x86d8, 0x86d9, 0x86da, 0x86db, 0x86dc, + 0x86dd, 0x86de, 0x86df, 0x86e0, 0x86e1, 0x86e2, 0x86e3, 0x86e4, + 0x86e5, 0x86e6, 0x86e7, 0x86e8, 0x86e9, 0x86ea, 0x86eb, 0x86ec, + 0x86ed, 0x86ee, 0x86ef, 0x86f0, 0x86f1, 0x86f2, 0x86f3, 0x86f4, + 0x86f5, 0x86f6, 0x86f7, 0x86f8, 0x86f9, 0x86fa, 0x86fb, 0x86fc, + 0x86fd, 0x86fe, 0x8740, 0x8741, 0x8742, 0x8743, 0x8744, 0x8745, + 0x8746, 0x8747, 0x8748, 0x8749, 0x874a, 0x874b, 0x874c, 0x874d, + 0x874e, 0x874f, 0x8750, 0x8751, 0x8752, 0x8753, 0x8754, 0x8755, + 0x8756, 0x8757, 0x8758, 0x8759, 0x875a, 0x875b, 0x875c, 0x875d, + 0x875e, 0x875f, 0x8760, 0x8761, 0x8762, 0x8763, 0x8764, 0x8765, + 0x8766, 0x8767, 0x8768, 0x8769, 0x876a, 0x876b, 0x876c, 0x876d, + 0x876e, 0x876f, 0x8770, 0x8771, 0x8772, 0x8773, 0x8774, 0x8775, + 0x8776, 0x8777, 0x8778, 0x8779, 0x877a, 0x877b, 0x877c, 0x877d, + 0x877e, 0x8780, 0x8781, 0x8782, 0x8783, 0x8784, 0x8785, 0x8786, + 0x8787, 0x8788, 0x8789, 0x878a, 0x878b, 0x878c, 0x878d, 0x878e, + 0x878f, 0x8790, 0x8791, 0x8792, 0x8793, 0x8794, 0x8795, 0x8796, + 0x8797, 0x8798, 0x8799, 0x879a, 0x879b, 0x879c, 0x879d, 0x879e, + 0x879f, 0x87a0, 0x87a1, 0x87a2, 0x87a3, 0x87a4, 0x87a5, 0x87a6, + 0x87a7, 0x87a8, 0x87a9, 0x87aa, 0x87ab, 0x87ac, 0x87ad, 0x87ae, + 0x87af, 0x87b0, 0x87b1, 0x87b2, 0x87b3, 0x87b4, 0x87b5, 0x87b6, + 0x87b7, 0x87b8, 0x87b9, 0x87ba, 0x87bb, 0x87bc, 0x87bd, 0x87be, + 0x87bf, 0x87c0, 0x87c1, 0x87c2, 0x87c3, 0x87c4, 0x87c5, 0x87c6, + 0x87c7, 0x87c8, 0x87c9, 0x87ca, 0x87cb, 0x87cc, 0x87cd, 0x87ce, + 0x87cf, 0x87d0, 0x87d1, 0x87d2, 0x87d3, 0x87d4, 0x87d5, 0x87d6, + 0x87d7, 0x87d8, 0x87d9, 0x87da, 0x87db, 0x87dc, 0x87dd, 0x87de, + 0x87df, 0x87e0, 0x87e1, 0x87e2, 0x87e3, 0x87e4, 0x87e5, 0x87e6, + 0x87e7, 0x87e8, 0x87e9, 0x87ea, 0x87eb, 0x87ec, 0x87ed, 0x87ee, + 0x87ef, 0x87f0, 0x87f1, 0x87f2, 0x87f3, 0x87f4, 0x87f5, 0x87f6, + 0x87f7, 0x87f8, 0x87f9, 0x87fa, 0x87fb, 0x87fc, 0x87fd, 0x87fe, + 0x8840, 0x8841, 0x8842, 0x8843, 0x8844, 0x8845, 0x8846, 0x8847, + 0x8848, 0x8849, 0x884a, 0x884b, 0x884c, 0x884d, 0x884e, 0x884f, + 0x8850, 0x8851, 0x8852, 0x8853, 0x8854, 0x8855, 0x8856, 0x8857, + 0x8858, 0x8859, 0x885a, 0x885b, 0x885c, 0x885d, 0x885e, 0x885f, + 0x8860, 0x8861, 0x8862, 0x8863, 0x8864, 0x8865, 0x8866, 0x8867, + 0x8868, 0x8869, 0x886a, 0x886b, 0x886c, 0x886d, 0x886e, 0x886f, + 0x8870, 0x8871, 0x8872, 0x8873, 0x8874, 0x8875, 0x8876, 0x8877, + 0x8878, 0x8879, 0x887a, 0x887b, 0x887c, 0x887d, 0x887e, 0x8880, + 0x8881, 0x8882, 0x8883, 0x8884, 0x8885, 0x8886, 0x8887, 0x8888, + 0x8889, 0x888a, 0x888b, 0x888c, 0x888d, 0x888e, 0x888f, 0x8890, + 0x8891, 0x8892, 0x8893, 0x8894, 0x8895, 0x8896, 0x8897, 0x8898, + 0x8899, 0x889a, 0x889b, 0x889c, 0x889d, 0x889e, 0x889f, 0x88a0, + 0x88a1, 0x88a2, 0x88a3, 0x88a4, 0x88a5, 0x88a6, 0x88a7, 0x88a8, + 0x88a9, 0x88aa, 0x88ab, 0x88ac, 0x88ad, 0x88ae, 0x88af, 0x88b0, + 0x88b1, 0x88b2, 0x88b3, 0x88b4, 0x88b5, 0x88b6, 0x88b7, 0x88b8, + 0x88b9, 0x88ba, 0x88bb, 0x88bc, 0x88bd, 0x88be, 0x88bf, 0x88c0, + 0x88c1, 0x88c2, 0x88c3, 0x88c4, 0x88c5, 0x88c6, 0x88c7, 0x88c8, + 0x88c9, 0x88ca, 0x88cb, 0x88cc, 0x88cd, 0x88ce, 0x88cf, 0x88d0, + 0x88d1, 0x88d2, 0x88d3, 0x88d4, 0x88d5, 0x88d6, 0x88d7, 0x88d8, + 0x88d9, 0x88da, 0x88db, 0x88dc, 0x88dd, 0x88de, 0x88df, 0x88e0, + 0x88e1, 0x88e2, 0x88e3, 0x88e4, 0x88e5, 0x88e6, 0x88e7, 0x88e8, + 0x88e9, 0x88ea, 0x88eb, 0x88ec, 0x88ed, 0x88ee, 0x88ef, 0x88f0, + 0x88f1, 0x88f2, 0x88f3, 0x88f4, 0x88f5, 0x88f6, 0x88f7, 0x88f8, + 0x88f9, 0x88fa, 0x88fb, 0x88fc, 0x88fd, 0x88fe, 0x8940, 0x8941, + 0x8942, 0x8943, 0x8944, 0x8945, 0x8946, 0x8947, 0x8948, 0x8949, + 0x894a, 0x894b, 0x894c, 0x894d, 0x894e, 0x894f, 0x8950, 0x8951, + 0x8952, 0x8953, 0x8954, 0x8955, 0x8956, 0x8957, 0x8958, 0x8959, + 0x895a, 0x895b, 0x895c, 0x895d, 0x895e, 0x895f, 0x8960, 0x8961, + 0x8962, 0x8963, 0x8964, 0x8965, 0x8966, 0x8967, 0x8968, 0x8969, + 0x896a, 0x896b, 0x896c, 0x896d, 0x896e, 0x896f, 0x8970, 0x8971, + 0x8972, 0x8973, 0x8974, 0x8975, 0x8976, 0x8977, 0x8978, 0x8979, + 0x897a, 0x897b, 0x897c, 0x897d, 0x897e, 0x8980, 0x8981, 0x8982, + 0x8983, 0x8984, 0x8985, 0x8986, 0x8987, 0x8988, 0x8989, 0x898a, + 0x898b, 0x898c, 0x898d, 0x898e, 0x898f, 0x8990, 0x8991, 0x8992, + 0x8993, 0x8994, 0x8995, 0x8996, 0x8997, 0x8998, 0x8999, 0x899a, + 0x899b, 0x899c, 0x899d, 0x899e, 0x899f, 0x89a0, 0x89a1, 0x89a2, + 0x89a3, 0x89a4, 0x89a5, 0x89a6, 0x89a7, 0x89a8, 0x89a9, 0x89aa, + 0x89ab, 0x89ac, 0x89ad, 0x89ae, 0x89af, 0x89b0, 0x89b1, 0x89b2, + 0x89b3, 0x89b4, 0x89b5, 0x89b6, 0x89b7, 0x89b8, 0x89b9, 0x89ba, + 0x89bb, 0x89bc, 0x89bd, 0x89be, 0x89bf, 0x89c0, 0x89c1, 0x89c2, + 0x89c3, 0x89c4, 0x89c5, 0x89c6, 0x89c7, 0x89c8, 0x89c9, 0x89ca, + 0x89cb, 0x89cc, 0x89cd, 0x89ce, 0x89cf, 0x89d0, 0x89d1, 0x89d2, + 0x89d3, 0x89d4, 0x89d5, 0x89d6, 0x89d7, 0x89d8, 0x89d9, 0x89da, + 0x89db, 0x89dc, 0x89dd, 0x89de, 0x89df, 0x89e0, 0x89e1, 0x89e2, + 0x89e3, 0x89e4, 0x89e5, 0x89e6, 0x89e7, 0x89e8, 0x89e9, 0x89ea, + 0x89eb, 0x89ec, 0x89ed, 0x89ee, 0x89ef, 0x89f0, 0x89f1, 0x89f2, + 0x89f3, 0x89f4, 0x89f5, 0x89f6, 0x89f7, 0x89f8, 0x89f9, 0x89fa, + 0x89fb, 0x89fc, 0x89fd, 0x89fe, 0x8a40, 0x8a41, 0x8a42, 0x8a43, + 0x8a44, 0x8a45, 0x8a46, 0x8a47, 0x8a48, 0x8a49, 0x8a4a, 0x8a4b, + 0x8a4c, 0x8a4d, 0x8a4e, 0x8a4f, 0x8a50, 0x8a51, 0x8a52, 0x8a53, + 0x8a54, 0x8a55, 0x8a56, 0x8a57, 0x8a58, 0x8a59, 0x8a5a, 0x8a5b, + 0x8a5c, 0x8a5d, 0x8a5e, 0x8a5f, 0x8a60, 0x8a61, 0x8a62, 0x8a63, + 0x8a64, 0x8a65, 0x8a66, 0x8a67, 0x8a68, 0x8a69, 0x8a6a, 0x8a6b, + 0x8a6c, 0x8a6d, 0x8a6e, 0x8a6f, 0x8a70, 0x8a71, 0x8a72, 0x8a73, + 0x8a74, 0x8a75, 0x8a76, 0x8a77, 0x8a78, 0x8a79, 0x8a7a, 0x8a7b, + 0x8a7c, 0x8a7d, 0x8a7e, 0x8a80, 0x8a81, 0x8a82, 0x8a83, 0x8a84, + 0x8a85, 0x8a86, 0x8a87, 0x8a88, 0x8a89, 0x8a8a, 0x8a8b, 0x8a8c, + 0x8a8d, 0x8a8e, 0x8a8f, 0x8a90, 0x8a91, 0x8a92, 0x8a93, 0x8a94, + 0x8a95, 0x8a96, 0x8a97, 0x8a98, 0x8a99, 0x8a9a, 0x8a9b, 0x8a9c, + 0x8a9d, 0x8a9e, 0x8a9f, 0x8aa0, 0x8aa1, 0x8aa2, 0x8aa3, 0x8aa4, + 0x8aa5, 0x8aa6, 0x8aa7, 0x8aa8, 0x8aa9, 0x8aaa, 0x8aab, 0x8aac, + 0x8aad, 0x8aae, 0x8aaf, 0x8ab0, 0x8ab1, 0x8ab2, 0x8ab3, 0x8ab4, + 0x8ab5, 0x8ab6, 0x8ab7, 0x8ab8, 0x8ab9, 0x8aba, 0x8abb, 0x8abc, + 0x8abd, 0x8abe, 0x8abf, 0x8ac0, 0x8ac1, 0x8ac2, 0x8ac3, 0x8ac4, + 0x8ac5, 0x8ac6, 0x8ac7, 0x8ac8, 0x8ac9, 0x8aca, 0x8acb, 0x8acc, + 0x8acd, 0x8ace, 0x8acf, 0x8ad0, 0x8ad1, 0x8ad2, 0x8ad3, 0x8ad4, + 0x8ad5, 0x8ad6, 0x8ad7, 0x8ad8, 0x8ad9, 0x8ada, 0x8adb, 0x8adc, + 0x8add, 0x8ade, 0x8adf, 0x8ae0, 0x8ae1, 0x8ae2, 0x8ae3, 0x8ae4, + 0x8ae5, 0x8ae6, 0x8ae7, 0x8ae8, 0x8ae9, 0x8aea, 0x8aeb, 0x8aec, + 0x8aed, 0x8aee, 0x8aef, 0x8af0, 0x8af1, 0x8af2, 0x8af3, 0x8af4, + 0x8af5, 0x8af6, 0x8af7, 0x8af8, 0x8af9, 0x8afa, 0x8afb, 0x8afc, + 0x8afd, 0x8afe, 0x8b40, 0x8b41, 0x8b42, 0x8b43, 0x8b44, 0x8b45, + 0x8b46, 0x8b47, 0x8b48, 0x8b49, 0x8b4a, 0x8b4b, 0x8b4c, 0x8b4d, + 0x8b4e, 0x8b4f, 0x8b50, 0x8b51, 0x8b52, 0x8b53, 0x8b54, 0x8b55, + 0x8b56, 0x8b57, 0x8b58, 0x8b59, 0x8b5a, 0x8b5b, 0x8b5c, 0x8b5d, + 0x8b5e, 0x8b5f, 0x8b60, 0x8b61, 0x8b62, 0x8b63, 0x8b64, 0x8b65, + 0x8b66, 0x8b67, 0x8b68, 0x8b69, 0x8b6a, 0x8b6b, 0x8b6c, 0x8b6d, + 0x8b6e, 0x8b6f, 0x8b70, 0x8b71, 0x8b72, 0x8b73, 0x8b74, 0x8b75, + 0x8b76, 0x8b77, 0x8b78, 0x8b79, 0x8b7a, 0x8b7b, 0x8b7c, 0x8b7d, + 0x8b7e, 0x8b80, 0x8b81, 0x8b82, 0x8b83, 0x8b84, 0x8b85, 0x8b86, + 0x8b87, 0x8b88, 0x8b89, 0x8b8a, 0x8b8b, 0x8b8c, 0x8b8d, 0x8b8e, + 0x8b8f, 0x8b90, 0x8b91, 0x8b92, 0x8b93, 0x8b94, 0x8b95, 0x8b96, + 0x8b97, 0x8b98, 0x8b99, 0x8b9a, 0x8b9b, 0x8b9c, 0x8b9d, 0x8b9e, + 0x8b9f, 0x8ba0, 0x8ba1, 0x8ba2, 0x8ba3, 0x8ba4, 0x8ba5, 0x8ba6, + 0x8ba7, 0x8ba8, 0x8ba9, 0x8baa, 0x8bab, 0x8bac, 0x8bad, 0x8bae, + 0x8baf, 0x8bb0, 0x8bb1, 0x8bb2, 0x8bb3, 0x8bb4, 0x8bb5, 0x8bb6, + 0x8bb7, 0x8bb8, 0x8bb9, 0x8bba, 0x8bbb, 0x8bbc, 0x8bbd, 0x8bbe, + 0x8bbf, 0x8bc0, 0x8bc1, 0x8bc2, 0x8bc3, 0x8bc4, 0x8bc5, 0x8bc6, + 0x8bc7, 0x8bc8, 0x8bc9, 0x8bca, 0x8bcb, 0x8bcc, 0x8bcd, 0x8bce, + 0x8bcf, 0x8bd0, 0x8bd1, 0x8bd2, 0x8bd3, 0x8bd4, 0x8bd5, 0x8bd6, + 0x8bd7, 0x8bd8, 0x8bd9, 0x8bda, 0x8bdb, 0x8bdc, 0x8bdd, 0x8bde, + 0x8bdf, 0x8be0, 0x8be1, 0x8be2, 0x8be3, 0x8be4, 0x8be5, 0x8be6, + 0x8be7, 0x8be8, 0x8be9, 0x8bea, 0x8beb, 0x8bec, 0x8bed, 0x8bee, + 0x8bef, 0x8bf0, 0x8bf1, 0x8bf2, 0x8bf3, 0x8bf4, 0x8bf5, 0x8bf6, + 0x8bf7, 0x8bf8, 0x8bf9, 0x8bfa, 0x8bfb, 0x8bfc, 0x8bfd, 0x8bfe, + 0x8c40, 0x8c41, 0x8c42, 0x8c43, 0x8c44, 0x8c45, 0x8c46, 0x8c47, + 0x8c48, 0x8c49, 0x8c4a, 0x8c4b, 0x8c4c, 0x8c4d, 0x8c4e, 0x8c4f, + 0x8c50, 0x8c51, 0x8c52, 0x8c53, 0x8c54, 0x8c55, 0x8c56, 0x8c57, + 0x8c58, 0x8c59, 0x8c5a, 0x8c5b, 0x8c5c, 0x8c5d, 0x8c5e, 0x8c5f, + 0x8c60, 0x8c61, 0x8c62, 0x8c63, 0x8c64, 0x8c65, 0x8c66, 0x8c67, + 0x8c68, 0x8c69, 0x8c6a, 0x8c6b, 0x8c6c, 0x8c6d, 0x8c6e, 0x8c6f, + 0x8c70, 0x8c71, 0x8c72, 0x8c73, 0x8c74, 0x8c75, 0x8c76, 0x8c77, + 0x8c78, 0x8c79, 0x8c7a, 0x8c7b, 0x8c7c, 0x8c7d, 0x8c7e, 0x8c80, + 0x8c81, 0x8c82, 0x8c83, 0x8c84, 0x8c85, 0x8c86, 0x8c87, 0x8c88, + 0x8c89, 0x8c8a, 0x8c8b, 0x8c8c, 0x8c8d, 0x8c8e, 0x8c8f, 0x8c90, + 0x8c91, 0x8c92, 0x8c93, 0x8c94, 0x8c95, 0x8c96, 0x8c97, 0x8c98, + 0x8c99, 0x8c9a, 0x8c9b, 0x8c9c, 0x8c9d, 0x8c9e, 0x8c9f, 0x8ca0, + 0x8ca1, 0x8ca2, 0x8ca3, 0x8ca4, 0x8ca5, 0x8ca6, 0x8ca7, 0x8ca8, + 0x8ca9, 0x8caa, 0x8cab, 0x8cac, 0x8cad, 0x8cae, 0x8caf, 0x8cb0, + 0x8cb1, 0x8cb2, 0x8cb3, 0x8cb4, 0x8cb5, 0x8cb6, 0x8cb7, 0x8cb8, + 0x8cb9, 0x8cba, 0x8cbb, 0x8cbc, 0x8cbd, 0x8cbe, 0x8cbf, 0x8cc0, + 0x8cc1, 0x8cc2, 0x8cc3, 0x8cc4, 0x8cc5, 0x8cc6, 0x8cc7, 0x8cc8, + 0x8cc9, 0x8cca, 0x8ccb, 0x8ccc, 0x8ccd, 0x8cce, 0x8ccf, 0x8cd0, + 0x8cd1, 0x8cd2, 0x8cd3, 0x8cd4, 0x8cd5, 0x8cd6, 0x8cd7, 0x8cd8, + 0x8cd9, 0x8cda, 0x8cdb, 0x8cdc, 0x8cdd, 0x8cde, 0x8cdf, 0x8ce0, + 0x8ce1, 0x8ce2, 0x8ce3, 0x8ce4, 0x8ce5, 0x8ce6, 0x8ce7, 0x8ce8, + 0x8ce9, 0x8cea, 0x8ceb, 0x8cec, 0x8ced, 0x8cee, 0x8cef, 0x8cf0, + 0x8cf1, 0x8cf2, 0x8cf3, 0x8cf4, 0x8cf5, 0x8cf6, 0x8cf7, 0x8cf8, + 0x8cf9, 0x8cfa, 0x8cfb, 0x8cfc, 0x8cfd, 0x8cfe, 0x8d40, 0x8d41, + 0x8d42, 0x8d43, 0x8d44, 0x8d45, 0x8d46, 0x8d47, 0x8d48, 0x8d49, + 0x8d4a, 0x8d4b, 0x8d4c, 0x8d4d, 0x8d4e, 0x8d4f, 0x8d50, 0x8d51, + 0x8d52, 0x8d53, 0x8d54, 0x8d55, 0x8d56, 0x8d57, 0x8d58, 0x8d59, + 0x8d5a, 0x8d5b, 0x8d5c, 0x8d5d, 0x8d5e, 0x8d5f, 0x8d60, 0x8d61, + 0x8d62, 0x8d63, 0x8d64, 0x8d65, 0x8d66, 0x8d67, 0x8d68, 0x8d69, + 0x8d6a, 0x8d6b, 0x8d6c, 0x8d6d, 0x8d6e, 0x8d6f, 0x8d70, 0x8d71, + 0x8d72, 0x8d73, 0x8d74, 0x8d75, 0x8d76, 0x8d77, 0x8d78, 0x8d79, + 0x8d7a, 0x8d7b, 0x8d7c, 0x8d7d, 0x8d7e, 0x8d80, 0x8d81, 0x8d82, + 0x8d83, 0x8d84, 0x8d85, 0x8d86, 0x8d87, 0x8d88, 0x8d89, 0x8d8a, + 0x8d8b, 0x8d8c, 0x8d8d, 0x8d8e, 0x8d8f, 0x8d90, 0x8d91, 0x8d92, + 0x8d93, 0x8d94, 0x8d95, 0x8d96, 0x8d97, 0x8d98, 0x8d99, 0x8d9a, + 0x8d9b, 0x8d9c, 0x8d9d, 0x8d9e, 0x8d9f, 0x8da0, 0x8da1, 0x8da2, + 0x8da3, 0x8da4, 0x8da5, 0x8da6, 0x8da7, 0x8da8, 0x8da9, 0x8daa, + 0x8dab, 0x8dac, 0x8dad, 0x8dae, 0x8daf, 0x8db0, 0x8db1, 0x8db2, + 0x8db3, 0x8db4, 0x8db5, 0x8db6, 0x8db7, 0x8db8, 0x8db9, 0x8dba, + 0x8dbb, 0x8dbc, 0x8dbd, 0x8dbe, 0x8dbf, 0x8dc0, 0x8dc1, 0x8dc2, + 0x8dc3, 0x8dc4, 0x8dc5, 0x8dc6, 0x8dc7, 0x8dc8, 0x8dc9, 0x8dca, + 0x8dcb, 0x8dcc, 0x8dcd, 0x8dce, 0x8dcf, 0x8dd0, 0x8dd1, 0x8dd2, + 0x8dd3, 0x8dd4, 0x8dd5, 0x8dd6, 0x8dd7, 0x8dd8, 0x8dd9, 0x8dda, + 0x8ddb, 0x8ddc, 0x8ddd, 0x8dde, 0x8ddf, 0x8de0, 0x8de1, 0x8de2, + 0x8de3, 0x8de4, 0x8de5, 0x8de6, 0x8de7, 0x8de8, 0x8de9, 0x8dea, + 0x8deb, 0x8dec, 0x8ded, 0x8dee, 0x8def, 0x8df0, 0x8df1, 0x8df2, + 0x8df3, 0x8df4, 0x8df5, 0x8df6, 0x8df7, 0x8df8, 0x8df9, 0x8dfa, + 0x8dfb, 0x8dfc, 0x8dfd, 0x8dfe, 0x8e40, 0x8e41, 0x8e42, 0x8e43, + 0x8e44, 0x8e45, 0x8e46, 0x8e47, 0x8e48, 0x8e49, 0x8e4a, 0x8e4b, + 0x8e4c, 0x8e4d, 0x8e4e, 0x8e4f, 0x8e50, 0x8e51, 0x8e52, 0x8e53, + 0x8e54, 0x8e55, 0x8e56, 0x8e57, 0x8e58, 0x8e59, 0x8e5a, 0x8e5b, + 0x8e5c, 0x8e5d, 0x8e5e, 0x8e5f, 0x8e60, 0x8e61, 0x8e62, 0x8e63, + 0x8e64, 0x8e65, 0x8e66, 0x8e67, 0x8e68, 0x8e69, 0x8e6a, 0x8e6b, + 0x8e6c, 0x8e6d, 0x8e6e, 0x8e6f, 0x8e70, 0x8e71, 0x8e72, 0x8e73, + 0x8e74, 0x8e75, 0x8e76, 0x8e77, 0x8e78, 0x8e79, 0x8e7a, 0x8e7b, + 0x8e7c, 0x8e7d, 0x8e7e, 0x8e80, 0x8e81, 0x8e82, 0x8e83, 0x8e84, + 0x8e85, 0x8e86, 0x8e87, 0x8e88, 0x8e89, 0x8e8a, 0x8e8b, 0x8e8c, + 0x8e8d, 0x8e8e, 0x8e8f, 0x8e90, 0x8e91, 0x8e92, 0x8e93, 0x8e94, + 0x8e95, 0x8e96, 0x8e97, 0x8e98, 0x8e99, 0x8e9a, 0x8e9b, 0x8e9c, + 0x8e9d, 0x8e9e, 0x8e9f, 0x8ea0, 0x8ea1, 0x8ea2, 0x8ea3, 0x8ea4, + 0x8ea5, 0x8ea6, 0x8ea7, 0x8ea8, 0x8ea9, 0x8eaa, 0x8eab, 0x8eac, + 0x8ead, 0x8eae, 0x8eaf, 0x8eb0, 0x8eb1, 0x8eb2, 0x8eb3, 0x8eb4, + 0x8eb5, 0x8eb6, 0x8eb7, 0x8eb8, 0x8eb9, 0x8eba, 0x8ebb, 0x8ebc, + 0x8ebd, 0x8ebe, 0x8ebf, 0x8ec0, 0x8ec1, 0x8ec2, 0x8ec3, 0x8ec4, + 0x8ec5, 0x8ec6, 0x8ec7, 0x8ec8, 0x8ec9, 0x8eca, 0x8ecb, 0x8ecc, + 0x8ecd, 0x8ece, 0x8ecf, 0x8ed0, 0x8ed1, 0x8ed2, 0x8ed3, 0x8ed4, + 0x8ed5, 0x8ed6, 0x8ed7, 0x8ed8, 0x8ed9, 0x8eda, 0x8edb, 0x8edc, + 0x8edd, 0x8ede, 0x8edf, 0x8ee0, 0x8ee1, 0x8ee2, 0x8ee3, 0x8ee4, + 0x8ee5, 0x8ee6, 0x8ee7, 0x8ee8, 0x8ee9, 0x8eea, 0x8eeb, 0x8eec, + 0x8eed, 0x8eee, 0x8eef, 0x8ef0, 0x8ef1, 0x8ef2, 0x8ef3, 0x8ef4, + 0x8ef5, 0x8ef6, 0x8ef7, 0x8ef8, 0x8ef9, 0x8efa, 0x8efb, 0x8efc, + 0x8efd, 0x8efe, 0x8f40, 0x8f41, 0x8f42, 0x8f43, 0x8f44, 0x8f45, + 0x8f46, 0x8f47, 0x8f48, 0x8f49, 0x8f4a, 0x8f4b, 0x8f4c, 0x8f4d, + 0x8f4e, 0x8f4f, 0x8f50, 0x8f51, 0x8f52, 0x8f53, 0x8f54, 0x8f55, + 0x8f56, 0x8f57, 0x8f58, 0x8f59, 0x8f5a, 0x8f5b, 0x8f5c, 0x8f5d, + 0x8f5e, 0x8f5f, 0x8f60, 0x8f61, 0x8f62, 0x8f63, 0x8f64, 0x8f65, + 0x8f66, 0x8f67, 0x8f68, 0x8f69, 0x8f6a, 0x8f6b, 0x8f6c, 0x8f6d, + 0x8f6e, 0x8f6f, 0x8f70, 0x8f71, 0x8f72, 0x8f73, 0x8f74, 0x8f75, + 0x8f76, 0x8f77, 0x8f78, 0x8f79, 0x8f7a, 0x8f7b, 0x8f7c, 0x8f7d, + 0x8f7e, 0x8f80, 0x8f81, 0x8f82, 0x8f83, 0x8f84, 0x8f85, 0x8f86, + 0x8f87, 0x8f88, 0x8f89, 0x8f8a, 0x8f8b, 0x8f8c, 0x8f8d, 0x8f8e, + 0x8f8f, 0x8f90, 0x8f91, 0x8f92, 0x8f93, 0x8f94, 0x8f95, 0x8f96, + 0x8f97, 0x8f98, 0x8f99, 0x8f9a, 0x8f9b, 0x8f9c, 0x8f9d, 0x8f9e, + 0x8f9f, 0x8fa0, 0x8fa1, 0x8fa2, 0x8fa3, 0x8fa4, 0x8fa5, 0x8fa6, + 0x8fa7, 0x8fa8, 0x8fa9, 0x8faa, 0x8fab, 0x8fac, 0x8fad, 0x8fae, + 0x8faf, 0x8fb0, 0x8fb1, 0x8fb2, 0x8fb3, 0x8fb4, 0x8fb5, 0x8fb6, + 0x8fb7, 0x8fb8, 0x8fb9, 0x8fba, 0x8fbb, 0x8fbc, 0x8fbd, 0x8fbe, + 0x8fbf, 0x8fc0, 0x8fc1, 0x8fc2, 0x8fc3, 0x8fc4, 0x8fc5, 0x8fc6, + 0x8fc7, 0x8fc8, 0x8fc9, 0x8fca, 0x8fcb, 0x8fcc, 0x8fcd, 0x8fce, + 0x8fcf, 0x8fd0, 0x8fd1, 0x8fd2, 0x8fd3, 0x8fd4, 0x8fd5, 0x8fd6, + 0x8fd7, 0x8fd8, 0x8fd9, 0x8fda, 0x8fdb, 0x8fdc, 0x8fdd, 0x8fde, + 0x8fdf, 0x8fe0, 0x8fe1, 0x8fe2, 0x8fe3, 0x8fe4, 0x8fe5, 0x8fe6, + 0x8fe7, 0x8fe8, 0x8fe9, 0x8fea, 0x8feb, 0x8fec, 0x8fed, 0x8fee, + 0x8fef, 0x8ff0, 0x8ff1, 0x8ff2, 0x8ff3, 0x8ff4, 0x8ff5, 0x8ff6, + 0x8ff7, 0x8ff8, 0x8ff9, 0x8ffa, 0x8ffb, 0x8ffc, 0x8ffd, 0x8ffe, + 0x9040, 0x9041, 0x9042, 0x9043, 0x9044, 0x9045, 0x9046, 0x9047, + 0x9048, 0x9049, 0x904a, 0x904b, 0x904c, 0x904d, 0x904e, 0x904f, + 0x9050, 0x9051, 0x9052, 0x9053, 0x9054, 0x9055, 0x9056, 0x9057, + 0x9058, 0x9059, 0x905a, 0x905b, 0x905c, 0x905d, 0x905e, 0x905f, + 0x9060, 0x9061, 0x9062, 0x9063, 0x9064, 0x9065, 0x9066, 0x9067, + 0x9068, 0x9069, 0x906a, 0x906b, 0x906c, 0x906d, 0x906e, 0x906f, + 0x9070, 0x9071, 0x9072, 0x9073, 0x9074, 0x9075, 0x9076, 0x9077, + 0x9078, 0x9079, 0x907a, 0x907b, 0x907c, 0x907d, 0x907e, 0x9080, + 0x9081, 0x9082, 0x9083, 0x9084, 0x9085, 0x9086, 0x9087, 0x9088, + 0x9089, 0x908a, 0x908b, 0x908c, 0x908d, 0x908e, 0x908f, 0x9090, + 0x9091, 0x9092, 0x9093, 0x9094, 0x9095, 0x9096, 0x9097, 0x9098, + 0x9099, 0x909a, 0x909b, 0x909c, 0x909d, 0x909e, 0x909f, 0x90a0, + 0x90a1, 0x90a2, 0x90a3, 0x90a4, 0x90a5, 0x90a6, 0x90a7, 0x90a8, + 0x90a9, 0x90aa, 0x90ab, 0x90ac, 0x90ad, 0x90ae, 0x90af, 0x90b0, + 0x90b1, 0x90b2, 0x90b3, 0x90b4, 0x90b5, 0x90b6, 0x90b7, 0x90b8, + 0x90b9, 0x90ba, 0x90bb, 0x90bc, 0x90bd, 0x90be, 0x90bf, 0x90c0, + 0x90c1, 0x90c2, 0x90c3, 0x90c4, 0x90c5, 0x90c6, 0x90c7, 0x90c8, + 0x90c9, 0x90ca, 0x90cb, 0x90cc, 0x90cd, 0x90ce, 0x90cf, 0x90d0, + 0x90d1, 0x90d2, 0x90d3, 0x90d4, 0x90d5, 0x90d6, 0x90d7, 0x90d8, + 0x90d9, 0x90da, 0x90db, 0x90dc, 0x90dd, 0x90de, 0x90df, 0x90e0, + 0x90e1, 0x90e2, 0x90e3, 0x90e4, 0x90e5, 0x90e6, 0x90e7, 0x90e8, + 0x90e9, 0x90ea, 0x90eb, 0x90ec, 0x90ed, 0x90ee, 0x90ef, 0x90f0, + 0x90f1, 0x90f2, 0x90f3, 0x90f4, 0x90f5, 0x90f6, 0x90f7, 0x90f8, + 0x90f9, 0x90fa, 0x90fb, 0x90fc, 0x90fd, 0x90fe, 0x9140, 0x9141, + 0x9142, 0x9143, 0x9144, 0x9145, 0x9146, 0x9147, 0x9148, 0x9149, + 0x914a, 0x914b, 0x914c, 0x914d, 0x914e, 0x914f, 0x9150, 0x9151, + 0x9152, 0x9153, 0x9154, 0x9155, 0x9156, 0x9157, 0x9158, 0x9159, + 0x915a, 0x915b, 0x915c, 0x915d, 0x915e, 0x915f, 0x9160, 0x9161, + 0x9162, 0x9163, 0x9164, 0x9165, 0x9166, 0x9167, 0x9168, 0x9169, + 0x916a, 0x916b, 0x916c, 0x916d, 0x916e, 0x916f, 0x9170, 0x9171, + 0x9172, 0x9173, 0x9174, 0x9175, 0x9176, 0x9177, 0x9178, 0x9179, + 0x917a, 0x917b, 0x917c, 0x917d, 0x917e, 0x9180, 0x9181, 0x9182, + 0x9183, 0x9184, 0x9185, 0x9186, 0x9187, 0x9188, 0x9189, 0x918a, + 0x918b, 0x918c, 0x918d, 0x918e, 0x918f, 0x9190, 0x9191, 0x9192, + 0x9193, 0x9194, 0x9195, 0x9196, 0x9197, 0x9198, 0x9199, 0x919a, + 0x919b, 0x919c, 0x919d, 0x919e, 0x919f, 0x91a0, 0x91a1, 0x91a2, + 0x91a3, 0x91a4, 0x91a5, 0x91a6, 0x91a7, 0x91a8, 0x91a9, 0x91aa, + 0x91ab, 0x91ac, 0x91ad, 0x91ae, 0x91af, 0x91b0, 0x91b1, 0x91b2, + 0x91b3, 0x91b4, 0x91b5, 0x91b6, 0x91b7, 0x91b8, 0x91b9, 0x91ba, + 0x91bb, 0x91bc, 0x91bd, 0x91be, 0x91bf, 0x91c0, 0x91c1, 0x91c2, + 0x91c3, 0x91c4, 0x91c5, 0x91c6, 0x91c7, 0x91c8, 0x91c9, 0x91ca, + 0x91cb, 0x91cc, 0x91cd, 0x91ce, 0x91cf, 0x91d0, 0x91d1, 0x91d2, + 0x91d3, 0x91d4, 0x91d5, 0x91d6, 0x91d7, 0x91d8, 0x91d9, 0x91da, + 0x91db, 0x91dc, 0x91dd, 0x91de, 0x91df, 0x91e0, 0x91e1, 0x91e2, + 0x91e3, 0x91e4, 0x91e5, 0x91e6, 0x91e7, 0x91e8, 0x91e9, 0x91ea, + 0x91eb, 0x91ec, 0x91ed, 0x91ee, 0x91ef, 0x91f0, 0x91f1, 0x91f2, + 0x91f3, 0x91f4, 0x91f5, 0x91f6, 0x91f7, 0x91f8, 0x91f9, 0x91fa, + 0x91fb, 0x91fc, 0x91fd, 0x91fe, 0x9240, 0x9241, 0x9242, 0x9243, + 0x9244, 0x9245, 0x9246, 0x9247, 0x9248, 0x9249, 0x924a, 0x924b, + 0x924c, 0x924d, 0x924e, 0x924f, 0x9250, 0x9251, 0x9252, 0x9253, + 0x9254, 0x9255, 0x9256, 0x9257, 0x9258, 0x9259, 0x925a, 0x925b, + 0x925c, 0x925d, 0x925e, 0x925f, 0x9260, 0x9261, 0x9262, 0x9263, + 0x9264, 0x9265, 0x9266, 0x9267, 0x9268, 0x9269, 0x926a, 0x926b, + 0x926c, 0x926d, 0x926e, 0x926f, 0x9270, 0x9271, 0x9272, 0x9273, + 0x9274, 0x9275, 0x9276, 0x9277, 0x9278, 0x9279, 0x927a, 0x927b, + 0x927c, 0x927d, 0x927e, 0x9280, 0x9281, 0x9282, 0x9283, 0x9284, + 0x9285, 0x9286, 0x9287, 0x9288, 0x9289, 0x928a, 0x928b, 0x928c, + 0x928d, 0x928e, 0x928f, 0x9290, 0x9291, 0x9292, 0x9293, 0x9294, + 0x9295, 0x9296, 0x9297, 0x9298, 0x9299, 0x929a, 0x929b, 0x929c, + 0x929d, 0x929e, 0x929f, 0x92a0, 0x92a1, 0x92a2, 0x92a3, 0x92a4, + 0x92a5, 0x92a6, 0x92a7, 0x92a8, 0x92a9, 0x92aa, 0x92ab, 0x92ac, + 0x92ad, 0x92ae, 0x92af, 0x92b0, 0x92b1, 0x92b2, 0x92b3, 0x92b4, + 0x92b5, 0x92b6, 0x92b7, 0x92b8, 0x92b9, 0x92ba, 0x92bb, 0x92bc, + 0x92bd, 0x92be, 0x92bf, 0x92c0, 0x92c1, 0x92c2, 0x92c3, 0x92c4, + 0x92c5, 0x92c6, 0x92c7, 0x92c8, 0x92c9, 0x92ca, 0x92cb, 0x92cc, + 0x92cd, 0x92ce, 0x92cf, 0x92d0, 0x92d1, 0x92d2, 0x92d3, 0x92d4, + 0x92d5, 0x92d6, 0x92d7, 0x92d8, 0x92d9, 0x92da, 0x92db, 0x92dc, + 0x92dd, 0x92de, 0x92df, 0x92e0, 0x92e1, 0x92e2, 0x92e3, 0x92e4, + 0x92e5, 0x92e6, 0x92e7, 0x92e8, 0x92e9, 0x92ea, 0x92eb, 0x92ec, + 0x92ed, 0x92ee, 0x92ef, 0x92f0, 0x92f1, 0x92f2, 0x92f3, 0x92f4, + 0x92f5, 0x92f6, 0x92f7, 0x92f8, 0x92f9, 0x92fa, 0x92fb, 0x92fc, + 0x92fd, 0x92fe, 0x9340, 0x9341, 0x9342, 0x9343, 0x9344, 0x9345, + 0x9346, 0x9347, 0x9348, 0x9349, 0x934a, 0x934b, 0x934c, 0x934d, + 0x934e, 0x934f, 0x9350, 0x9351, 0x9352, 0x9353, 0x9354, 0x9355, + 0x9356, 0x9357, 0x9358, 0x9359, 0x935a, 0x935b, 0x935c, 0x935d, + 0x935e, 0x935f, 0x9360, 0x9361, 0x9362, 0x9363, 0x9364, 0x9365, + 0x9366, 0x9367, 0x9368, 0x9369, 0x936a, 0x936b, 0x936c, 0x936d, + 0x936e, 0x936f, 0x9370, 0x9371, 0x9372, 0x9373, 0x9374, 0x9375, + 0x9376, 0x9377, 0x9378, 0x9379, 0x937a, 0x937b, 0x937c, 0x937d, + 0x937e, 0x9380, 0x9381, 0x9382, 0x9383, 0x9384, 0x9385, 0x9386, + 0x9387, 0x9388, 0x9389, 0x938a, 0x938b, 0x938c, 0x938d, 0x938e, + 0x938f, 0x9390, 0x9391, 0x9392, 0x9393, 0x9394, 0x9395, 0x9396, + 0x9397, 0x9398, 0x9399, 0x939a, 0x939b, 0x939c, 0x939d, 0x939e, + 0x939f, 0x93a0, 0x93a1, 0x93a2, 0x93a3, 0x93a4, 0x93a5, 0x93a6, + 0x93a7, 0x93a8, 0x93a9, 0x93aa, 0x93ab, 0x93ac, 0x93ad, 0x93ae, + 0x93af, 0x93b0, 0x93b1, 0x93b2, 0x93b3, 0x93b4, 0x93b5, 0x93b6, + 0x93b7, 0x93b8, 0x93b9, 0x93ba, 0x93bb, 0x93bc, 0x93bd, 0x93be, + 0x93bf, 0x93c0, 0x93c1, 0x93c2, 0x93c3, 0x93c4, 0x93c5, 0x93c6, + 0x93c7, 0x93c8, 0x93c9, 0x93ca, 0x93cb, 0x93cc, 0x93cd, 0x93ce, + 0x93cf, 0x93d0, 0x93d1, 0x93d2, 0x93d3, 0x93d4, 0x93d5, 0x93d6, + 0x93d7, 0x93d8, 0x93d9, 0x93da, 0x93db, 0x93dc, 0x93dd, 0x93de, + 0x93df, 0x93e0, 0x93e1, 0x93e2, 0x93e3, 0x93e4, 0x93e5, 0x93e6, + 0x93e7, 0x93e8, 0x93e9, 0x93ea, 0x93eb, 0x93ec, 0x93ed, 0x93ee, + 0x93ef, 0x93f0, 0x93f1, 0x93f2, 0x93f3, 0x93f4, 0x93f5, 0x93f6, + 0x93f7, 0x93f8, 0x93f9, 0x93fa, 0x93fb, 0x93fc, 0x93fd, 0x93fe, + 0x9440, 0x9441, 0x9442, 0x9443, 0x9444, 0x9445, 0x9446, 0x9447, + 0x9448, 0x9449, 0x944a, 0x944b, 0x944c, 0x944d, 0x944e, 0x944f, + 0x9450, 0x9451, 0x9452, 0x9453, 0x9454, 0x9455, 0x9456, 0x9457, + 0x9458, 0x9459, 0x945a, 0x945b, 0x945c, 0x945d, 0x945e, 0x945f, + 0x9460, 0x9461, 0x9462, 0x9463, 0x9464, 0x9465, 0x9466, 0x9467, + 0x9468, 0x9469, 0x946a, 0x946b, 0x946c, 0x946d, 0x946e, 0x946f, + 0x9470, 0x9471, 0x9472, 0x9473, 0x9474, 0x9475, 0x9476, 0x9477, + 0x9478, 0x9479, 0x947a, 0x947b, 0x947c, 0x947d, 0x947e, 0x9480, + 0x9481, 0x9482, 0x9483, 0x9484, 0x9485, 0x9486, 0x9487, 0x9488, + 0x9489, 0x948a, 0x948b, 0x948c, 0x948d, 0x948e, 0x948f, 0x9490, + 0x9491, 0x9492, 0x9493, 0x9494, 0x9495, 0x9496, 0x9497, 0x9498, + 0x9499, 0x949a, 0x949b, 0x949c, 0x949d, 0x949e, 0x949f, 0x94a0, + 0x94a1, 0x94a2, 0x94a3, 0x94a4, 0x94a5, 0x94a6, 0x94a7, 0x94a8, + 0x94a9, 0x94aa, 0x94ab, 0x94ac, 0x94ad, 0x94ae, 0x94af, 0x94b0, + 0x94b1, 0x94b2, 0x94b3, 0x94b4, 0x94b5, 0x94b6, 0x94b7, 0x94b8, + 0x94b9, 0x94ba, 0x94bb, 0x94bc, 0x94bd, 0x94be, 0x94bf, 0x94c0, + 0x94c1, 0x94c2, 0x94c3, 0x94c4, 0x94c5, 0x94c6, 0x94c7, 0x94c8, + 0x94c9, 0x94ca, 0x94cb, 0x94cc, 0x94cd, 0x94ce, 0x94cf, 0x94d0, + 0x94d1, 0x94d2, 0x94d3, 0x94d4, 0x94d5, 0x94d6, 0x94d7, 0x94d8, + 0x94d9, 0x94da, 0x94db, 0x94dc, 0x94dd, 0x94de, 0x94df, 0x94e0, + 0x94e1, 0x94e2, 0x94e3, 0x94e4, 0x94e5, 0x94e6, 0x94e7, 0x94e8, + 0x94e9, 0x94ea, 0x94eb, 0x94ec, 0x94ed, 0x94ee, 0x94ef, 0x94f0, + 0x94f1, 0x94f2, 0x94f3, 0x94f4, 0x94f5, 0x94f6, 0x94f7, 0x94f8, + 0x94f9, 0x94fa, 0x94fb, 0x94fc, 0x94fd, 0x94fe, 0x9540, 0x9541, + 0x9542, 0x9543, 0x9544, 0x9545, 0x9546, 0x9547, 0x9548, 0x9549, + 0x954a, 0x954b, 0x954c, 0x954d, 0x954e, 0x954f, 0x9550, 0x9551, + 0x9552, 0x9553, 0x9554, 0x9555, 0x9556, 0x9557, 0x9558, 0x9559, + 0x955a, 0x955b, 0x955c, 0x955d, 0x955e, 0x955f, 0x9560, 0x9561, + 0x9562, 0x9563, 0x9564, 0x9565, 0x9566, 0x9567, 0x9568, 0x9569, + 0x956a, 0x956b, 0x956c, 0x956d, 0x956e, 0x956f, 0x9570, 0x9571, + 0x9572, 0x9573, 0x9574, 0x9575, 0x9576, 0x9577, 0x9578, 0x9579, + 0x957a, 0x957b, 0x957c, 0x957d, 0x957e, 0x9580, 0x9581, 0x9582, + 0x9583, 0x9584, 0x9585, 0x9586, 0x9587, 0x9588, 0x9589, 0x958a, + 0x958b, 0x958c, 0x958d, 0x958e, 0x958f, 0x9590, 0x9591, 0x9592, + 0x9593, 0x9594, 0x9595, 0x9596, 0x9597, 0x9598, 0x9599, 0x959a, + 0x959b, 0x959c, 0x959d, 0x959e, 0x959f, 0x95a0, 0x95a1, 0x95a2, + 0x95a3, 0x95a4, 0x95a5, 0x95a6, 0x95a7, 0x95a8, 0x95a9, 0x95aa, + 0x95ab, 0x95ac, 0x95ad, 0x95ae, 0x95af, 0x95b0, 0x95b1, 0x95b2, + 0x95b3, 0x95b4, 0x95b5, 0x95b6, 0x95b7, 0x95b8, 0x95b9, 0x95ba, + 0x95bb, 0x95bc, 0x95bd, 0x95be, 0x95bf, 0x95c0, 0x95c1, 0x95c2, + 0x95c3, 0x95c4, 0x95c5, 0x95c6, 0x95c7, 0x95c8, 0x95c9, 0x95ca, + 0x95cb, 0x95cc, 0x95cd, 0x95ce, 0x95cf, 0x95d0, 0x95d1, 0x95d2, + 0x95d3, 0x95d4, 0x95d5, 0x95d6, 0x95d7, 0x95d8, 0x95d9, 0x95da, + 0x95db, 0x95dc, 0x95dd, 0x95de, 0x95df, 0x95e0, 0x95e1, 0x95e2, + 0x95e3, 0x95e4, 0x95e5, 0x95e6, 0x95e7, 0x95e8, 0x95e9, 0x95ea, + 0x95eb, 0x95ec, 0x95ed, 0x95ee, 0x95ef, 0x95f0, 0x95f1, 0x95f2, + 0x95f3, 0x95f4, 0x95f5, 0x95f6, 0x95f7, 0x95f8, 0x95f9, 0x95fa, + 0x95fb, 0x95fc, 0x95fd, 0x95fe, 0x9640, 0x9641, 0x9642, 0x9643, + 0x9644, 0x9645, 0x9646, 0x9647, 0x9648, 0x9649, 0x964a, 0x964b, + 0x964c, 0x964d, 0x964e, 0x964f, 0x9650, 0x9651, 0x9652, 0x9653, + 0x9654, 0x9655, 0x9656, 0x9657, 0x9658, 0x9659, 0x965a, 0x965b, + 0x965c, 0x965d, 0x965e, 0x965f, 0x9660, 0x9661, 0x9662, 0x9663, + 0x9664, 0x9665, 0x9666, 0x9667, 0x9668, 0x9669, 0x966a, 0x966b, + 0x966c, 0x966d, 0x966e, 0x966f, 0x9670, 0x9671, 0x9672, 0x9673, + 0x9674, 0x9675, 0x9676, 0x9677, 0x9678, 0x9679, 0x967a, 0x967b, + 0x967c, 0x967d, 0x967e, 0x9680, 0x9681, 0x9682, 0x9683, 0x9684, + 0x9685, 0x9686, 0x9687, 0x9688, 0x9689, 0x968a, 0x968b, 0x968c, + 0x968d, 0x968e, 0x968f, 0x9690, 0x9691, 0x9692, 0x9693, 0x9694, + 0x9695, 0x9696, 0x9697, 0x9698, 0x9699, 0x969a, 0x969b, 0x969c, + 0x969d, 0x969e, 0x969f, 0x96a0, 0x96a1, 0x96a2, 0x96a3, 0x96a4, + 0x96a5, 0x96a6, 0x96a7, 0x96a8, 0x96a9, 0x96aa, 0x96ab, 0x96ac, + 0x96ad, 0x96ae, 0x96af, 0x96b0, 0x96b1, 0x96b2, 0x96b3, 0x96b4, + 0x96b5, 0x96b6, 0x96b7, 0x96b8, 0x96b9, 0x96ba, 0x96bb, 0x96bc, + 0x96bd, 0x96be, 0x96bf, 0x96c0, 0x96c1, 0x96c2, 0x96c3, 0x96c4, + 0x96c5, 0x96c6, 0x96c7, 0x96c8, 0x96c9, 0x96ca, 0x96cb, 0x96cc, + 0x96cd, 0x96ce, 0x96cf, 0x96d0, 0x96d1, 0x96d2, 0x96d3, 0x96d4, + 0x96d5, 0x96d6, 0x96d7, 0x96d8, 0x96d9, 0x96da, 0x96db, 0x96dc, + 0x96dd, 0x96de, 0x96df, 0x96e0, 0x96e1, 0x96e2, 0x96e3, 0x96e4, + 0x96e5, 0x96e6, 0x96e7, 0x96e8, 0x96e9, 0x96ea, 0x96eb, 0x96ec, + 0x96ed, 0x96ee, 0x96ef, 0x96f0, 0x96f1, 0x96f2, 0x96f3, 0x96f4, + 0x96f5, 0x96f6, 0x96f7, 0x96f8, 0x96f9, 0x96fa, 0x96fb, 0x96fc, + 0x96fd, 0x96fe, 0x9740, 0x9741, 0x9742, 0x9743, 0x9744, 0x9745, + 0x9746, 0x9747, 0x9748, 0x9749, 0x974a, 0x974b, 0x974c, 0x974d, + 0x974e, 0x974f, 0x9750, 0x9751, 0x9752, 0x9753, 0x9754, 0x9755, + 0x9756, 0x9757, 0x9758, 0x9759, 0x975a, 0x975b, 0x975c, 0x975d, + 0x975e, 0x975f, 0x9760, 0x9761, 0x9762, 0x9763, 0x9764, 0x9765, + 0x9766, 0x9767, 0x9768, 0x9769, 0x976a, 0x976b, 0x976c, 0x976d, + 0x976e, 0x976f, 0x9770, 0x9771, 0x9772, 0x9773, 0x9774, 0x9775, + 0x9776, 0x9777, 0x9778, 0x9779, 0x977a, 0x977b, 0x977c, 0x977d, + 0x977e, 0x9780, 0x9781, 0x9782, 0x9783, 0x9784, 0x9785, 0x9786, + 0x9787, 0x9788, 0x9789, 0x978a, 0x978b, 0x978c, 0x978d, 0x978e, + 0x978f, 0x9790, 0x9791, 0x9792, 0x9793, 0x9794, 0x9795, 0x9796, + 0x9797, 0x9798, 0x9799, 0x979a, 0x979b, 0x979c, 0x979d, 0x979e, + 0x979f, 0x97a0, 0x97a1, 0x97a2, 0x97a3, 0x97a4, 0x97a5, 0x97a6, + 0x97a7, 0x97a8, 0x97a9, 0x97aa, 0x97ab, 0x97ac, 0x97ad, 0x97ae, + 0x97af, 0x97b0, 0x97b1, 0x97b2, 0x97b3, 0x97b4, 0x97b5, 0x97b6, + 0x97b7, 0x97b8, 0x97b9, 0x97ba, 0x97bb, 0x97bc, 0x97bd, 0x97be, + 0x97bf, 0x97c0, 0x97c1, 0x97c2, 0x97c3, 0x97c4, 0x97c5, 0x97c6, + 0x97c7, 0x97c8, 0x97c9, 0x97ca, 0x97cb, 0x97cc, 0x97cd, 0x97ce, + 0x97cf, 0x97d0, 0x97d1, 0x97d2, 0x97d3, 0x97d4, 0x97d5, 0x97d6, + 0x97d7, 0x97d8, 0x97d9, 0x97da, 0x97db, 0x97dc, 0x97dd, 0x97de, + 0x97df, 0x97e0, 0x97e1, 0x97e2, 0x97e3, 0x97e4, 0x97e5, 0x97e6, + 0x97e7, 0x97e8, 0x97e9, 0x97ea, 0x97eb, 0x97ec, 0x97ed, 0x97ee, + 0x97ef, 0x97f0, 0x97f1, 0x97f2, 0x97f3, 0x97f4, 0x97f5, 0x97f6, + 0x97f7, 0x97f8, 0x97f9, 0x97fa, 0x97fb, 0x97fc, 0x97fd, 0x97fe, + 0x9840, 0x9841, 0x9842, 0x9843, 0x9844, 0x9845, 0x9846, 0x9847, + 0x9848, 0x9849, 0x984a, 0x984b, 0x984c, 0x984d, 0x984e, 0x984f, + 0x9850, 0x9851, 0x9852, 0x9853, 0x9854, 0x9855, 0x9856, 0x9857, + 0x9858, 0x9859, 0x985a, 0x985b, 0x985c, 0x985d, 0x985e, 0x985f, + 0x9860, 0x9861, 0x9862, 0x9863, 0x9864, 0x9865, 0x9866, 0x9867, + 0x9868, 0x9869, 0x986a, 0x986b, 0x986c, 0x986d, 0x986e, 0x986f, + 0x9870, 0x9871, 0x9872, 0x9873, 0x9874, 0x9875, 0x9876, 0x9877, + 0x9878, 0x9879, 0x987a, 0x987b, 0x987c, 0x987d, 0x987e, 0x9880, + 0x9881, 0x9882, 0x9883, 0x9884, 0x9885, 0x9886, 0x9887, 0x9888, + 0x9889, 0x988a, 0x988b, 0x988c, 0x988d, 0x988e, 0x988f, 0x9890, + 0x9891, 0x9892, 0x9893, 0x9894, 0x9895, 0x9896, 0x9897, 0x9898, + 0x9899, 0x989a, 0x989b, 0x989c, 0x989d, 0x989e, 0x989f, 0x98a0, + 0x98a1, 0x98a2, 0x98a3, 0x98a4, 0x98a5, 0x98a6, 0x98a7, 0x98a8, + 0x98a9, 0x98aa, 0x98ab, 0x98ac, 0x98ad, 0x98ae, 0x98af, 0x98b0, + 0x98b1, 0x98b2, 0x98b3, 0x98b4, 0x98b5, 0x98b6, 0x98b7, 0x98b8, + 0x98b9, 0x98ba, 0x98bb, 0x98bc, 0x98bd, 0x98be, 0x98bf, 0x98c0, + 0x98c1, 0x98c2, 0x98c3, 0x98c4, 0x98c5, 0x98c6, 0x98c7, 0x98c8, + 0x98c9, 0x98ca, 0x98cb, 0x98cc, 0x98cd, 0x98ce, 0x98cf, 0x98d0, + 0x98d1, 0x98d2, 0x98d3, 0x98d4, 0x98d5, 0x98d6, 0x98d7, 0x98d8, + 0x98d9, 0x98da, 0x98db, 0x98dc, 0x98dd, 0x98de, 0x98df, 0x98e0, + 0x98e1, 0x98e2, 0x98e3, 0x98e4, 0x98e5, 0x98e6, 0x98e7, 0x98e8, + 0x98e9, 0x98ea, 0x98eb, 0x98ec, 0x98ed, 0x98ee, 0x98ef, 0x98f0, + 0x98f1, 0x98f2, 0x98f3, 0x98f4, 0x98f5, 0x98f6, 0x98f7, 0x98f8, + 0x98f9, 0x98fa, 0x98fb, 0x98fc, 0x98fd, 0x98fe, 0x9940, 0x9941, + 0x9942, 0x9943, 0x9944, 0x9945, 0x9946, 0x9947, 0x9948, 0x9949, + 0x994a, 0x994b, 0x994c, 0x994d, 0x994e, 0x994f, 0x9950, 0x9951, + 0x9952, 0x9953, 0x9954, 0x9955, 0x9956, 0x9957, 0x9958, 0x9959, + 0x995a, 0x995b, 0x995c, 0x995d, 0x995e, 0x995f, 0x9960, 0x9961, + 0x9962, 0x9963, 0x9964, 0x9965, 0x9966, 0x9967, 0x9968, 0x9969, + 0x996a, 0x996b, 0x996c, 0x996d, 0x996e, 0x996f, 0x9970, 0x9971, + 0x9972, 0x9973, 0x9974, 0x9975, 0x9976, 0x9977, 0x9978, 0x9979, + 0x997a, 0x997b, 0x997c, 0x997d, 0x997e, 0x9980, 0x9981, 0x9982, + 0x9983, 0x9984, 0x9985, 0x9986, 0x9987, 0x9988, 0x9989, 0x998a, + 0x998b, 0x998c, 0x998d, 0x998e, 0x998f, 0x9990, 0x9991, 0x9992, + 0x9993, 0x9994, 0x9995, 0x9996, 0x9997, 0x9998, 0x9999, 0x999a, + 0x999b, 0x999c, 0x999d, 0x999e, 0x999f, 0x99a0, 0x99a1, 0x99a2, + 0x99a3, 0x99a4, 0x99a5, 0x99a6, 0x99a7, 0x99a8, 0x99a9, 0x99aa, + 0x99ab, 0x99ac, 0x99ad, 0x99ae, 0x99af, 0x99b0, 0x99b1, 0x99b2, + 0x99b3, 0x99b4, 0x99b5, 0x99b6, 0x99b7, 0x99b8, 0x99b9, 0x99ba, + 0x99bb, 0x99bc, 0x99bd, 0x99be, 0x99bf, 0x99c0, 0x99c1, 0x99c2, + 0x99c3, 0x99c4, 0x99c5, 0x99c6, 0x99c7, 0x99c8, 0x99c9, 0x99ca, + 0x99cb, 0x99cc, 0x99cd, 0x99ce, 0x99cf, 0x99d0, 0x99d1, 0x99d2, + 0x99d3, 0x99d4, 0x99d5, 0x99d6, 0x99d7, 0x99d8, 0x99d9, 0x99da, + 0x99db, 0x99dc, 0x99dd, 0x99de, 0x99df, 0x99e0, 0x99e1, 0x99e2, + 0x99e3, 0x99e4, 0x99e5, 0x99e6, 0x99e7, 0x99e8, 0x99e9, 0x99ea, + 0x99eb, 0x99ec, 0x99ed, 0x99ee, 0x99ef, 0x99f0, 0x99f1, 0x99f2, + 0x99f3, 0x99f4, 0x99f5, 0x99f6, 0x99f7, 0x99f8, 0x99f9, 0x99fa, + 0x99fb, 0x99fc, 0x99fd, 0x99fe, 0x9a40, 0x9a41, 0x9a42, 0x9a43, + 0x9a44, 0x9a45, 0x9a46, 0x9a47, 0x9a48, 0x9a49, 0x9a4a, 0x9a4b, + 0x9a4c, 0x9a4d, 0x9a4e, 0x9a4f, 0x9a50, 0x9a51, 0x9a52, 0x9a53, + 0x9a54, 0x9a55, 0x9a56, 0x9a57, 0x9a58, 0x9a59, 0x9a5a, 0x9a5b, + 0x9a5c, 0x9a5d, 0x9a5e, 0x9a5f, 0x9a60, 0x9a61, 0x9a62, 0x9a63, + 0x9a64, 0x9a65, 0x9a66, 0x9a67, 0x9a68, 0x9a69, 0x9a6a, 0x9a6b, + 0x9a6c, 0x9a6d, 0x9a6e, 0x9a6f, 0x9a70, 0x9a71, 0x9a72, 0x9a73, + 0x9a74, 0x9a75, 0x9a76, 0x9a77, 0x9a78, 0x9a79, 0x9a7a, 0x9a7b, + 0x9a7c, 0x9a7d, 0x9a7e, 0x9a80, 0x9a81, 0x9a82, 0x9a83, 0x9a84, + 0x9a85, 0x9a86, 0x9a87, 0x9a88, 0x9a89, 0x9a8a, 0x9a8b, 0x9a8c, + 0x9a8d, 0x9a8e, 0x9a8f, 0x9a90, 0x9a91, 0x9a92, 0x9a93, 0x9a94, + 0x9a95, 0x9a96, 0x9a97, 0x9a98, 0x9a99, 0x9a9a, 0x9a9b, 0x9a9c, + 0x9a9d, 0x9a9e, 0x9a9f, 0x9aa0, 0x9aa1, 0x9aa2, 0x9aa3, 0x9aa4, + 0x9aa5, 0x9aa6, 0x9aa7, 0x9aa8, 0x9aa9, 0x9aaa, 0x9aab, 0x9aac, + 0x9aad, 0x9aae, 0x9aaf, 0x9ab0, 0x9ab1, 0x9ab2, 0x9ab3, 0x9ab4, + 0x9ab5, 0x9ab6, 0x9ab7, 0x9ab8, 0x9ab9, 0x9aba, 0x9abb, 0x9abc, + 0x9abd, 0x9abe, 0x9abf, 0x9ac0, 0x9ac1, 0x9ac2, 0x9ac3, 0x9ac4, + 0x9ac5, 0x9ac6, 0x9ac7, 0x9ac8, 0x9ac9, 0x9aca, 0x9acb, 0x9acc, + 0x9acd, 0x9ace, 0x9acf, 0x9ad0, 0x9ad1, 0x9ad2, 0x9ad3, 0x9ad4, + 0x9ad5, 0x9ad6, 0x9ad7, 0x9ad8, 0x9ad9, 0x9ada, 0x9adb, 0x9adc, + 0x9add, 0x9ade, 0x9adf, 0x9ae0, 0x9ae1, 0x9ae2, 0x9ae3, 0x9ae4, + 0x9ae5, 0x9ae6, 0x9ae7, 0x9ae8, 0x9ae9, 0x9aea, 0x9aeb, 0x9aec, + 0x9aed, 0x9aee, 0x9aef, 0x9af0, 0x9af1, 0x9af2, 0x9af3, 0x9af4, + 0x9af5, 0x9af6, 0x9af7, 0x9af8, 0x9af9, 0x9afa, 0x9afb, 0x9afc, + 0x9afd, 0x9afe, 0x9b40, 0x9b41, 0x9b42, 0x9b43, 0x9b44, 0x9b45, + 0x9b46, 0x9b47, 0x9b48, 0x9b49, 0x9b4a, 0x9b4b, 0x9b4c, 0x9b4d, + 0x9b4e, 0x9b4f, 0x9b50, 0x9b51, 0x9b52, 0x9b53, 0x9b54, 0x9b55, + 0x9b56, 0x9b57, 0x9b58, 0x9b59, 0x9b5a, 0x9b5b, 0x9b5c, 0x9b5d, + 0x9b5e, 0x9b5f, 0x9b60, 0x9b61, 0x9b62, 0x9b63, 0x9b64, 0x9b65, + 0x9b66, 0x9b67, 0x9b68, 0x9b69, 0x9b6a, 0x9b6b, 0x9b6c, 0x9b6d, + 0x9b6e, 0x9b6f, 0x9b70, 0x9b71, 0x9b72, 0x9b73, 0x9b74, 0x9b75, + 0x9b76, 0x9b77, 0x9b78, 0x9b79, 0x9b7a, 0x9b7b, 0x9b7c, 0x9b7d, + 0x9b7e, 0x9b80, 0x9b81, 0x9b82, 0x9b83, 0x9b84, 0x9b85, 0x9b86, + 0x9b87, 0x9b88, 0x9b89, 0x9b8a, 0x9b8b, 0x9b8c, 0x9b8d, 0x9b8e, + 0x9b8f, 0x9b90, 0x9b91, 0x9b92, 0x9b93, 0x9b94, 0x9b95, 0x9b96, + 0x9b97, 0x9b98, 0x9b99, 0x9b9a, 0x9b9b, 0x9b9c, 0x9b9d, 0x9b9e, + 0x9b9f, 0x9ba0, 0x9ba1, 0x9ba2, 0x9ba3, 0x9ba4, 0x9ba5, 0x9ba6, + 0x9ba7, 0x9ba8, 0x9ba9, 0x9baa, 0x9bab, 0x9bac, 0x9bad, 0x9bae, + 0x9baf, 0x9bb0, 0x9bb1, 0x9bb2, 0x9bb3, 0x9bb4, 0x9bb5, 0x9bb6, + 0x9bb7, 0x9bb8, 0x9bb9, 0x9bba, 0x9bbb, 0x9bbc, 0x9bbd, 0x9bbe, + 0x9bbf, 0x9bc0, 0x9bc1, 0x9bc2, 0x9bc3, 0x9bc4, 0x9bc5, 0x9bc6, + 0x9bc7, 0x9bc8, 0x9bc9, 0x9bca, 0x9bcb, 0x9bcc, 0x9bcd, 0x9bce, + 0x9bcf, 0x9bd0, 0x9bd1, 0x9bd2, 0x9bd3, 0x9bd4, 0x9bd5, 0x9bd6, + 0x9bd7, 0x9bd8, 0x9bd9, 0x9bda, 0x9bdb, 0x9bdc, 0x9bdd, 0x9bde, + 0x9bdf, 0x9be0, 0x9be1, 0x9be2, 0x9be3, 0x9be4, 0x9be5, 0x9be6, + 0x9be7, 0x9be8, 0x9be9, 0x9bea, 0x9beb, 0x9bec, 0x9bed, 0x9bee, + 0x9bef, 0x9bf0, 0x9bf1, 0x9bf2, 0x9bf3, 0x9bf4, 0x9bf5, 0x9bf6, + 0x9bf7, 0x9bf8, 0x9bf9, 0x9bfa, 0x9bfb, 0x9bfc, 0x9bfd, 0x9bfe, + 0x9c40, 0x9c41, 0x9c42, 0x9c43, 0x9c44, 0x9c45, 0x9c46, 0x9c47, + 0x9c48, 0x9c49, 0x9c4a, 0x9c4b, 0x9c4c, 0x9c4d, 0x9c4e, 0x9c4f, + 0x9c50, 0x9c51, 0x9c52, 0x9c53, 0x9c54, 0x9c55, 0x9c56, 0x9c57, + 0x9c58, 0x9c59, 0x9c5a, 0x9c5b, 0x9c5c, 0x9c5d, 0x9c5e, 0x9c5f, + 0x9c60, 0x9c61, 0x9c62, 0x9c63, 0x9c64, 0x9c65, 0x9c66, 0x9c67, + 0x9c68, 0x9c69, 0x9c6a, 0x9c6b, 0x9c6c, 0x9c6d, 0x9c6e, 0x9c6f, + 0x9c70, 0x9c71, 0x9c72, 0x9c73, 0x9c74, 0x9c75, 0x9c76, 0x9c77, + 0x9c78, 0x9c79, 0x9c7a, 0x9c7b, 0x9c7c, 0x9c7d, 0x9c7e, 0x9c80, + 0x9c81, 0x9c82, 0x9c83, 0x9c84, 0x9c85, 0x9c86, 0x9c87, 0x9c88, + 0x9c89, 0x9c8a, 0x9c8b, 0x9c8c, 0x9c8d, 0x9c8e, 0x9c8f, 0x9c90, + 0x9c91, 0x9c92, 0x9c93, 0x9c94, 0x9c95, 0x9c96, 0x9c97, 0x9c98, + 0x9c99, 0x9c9a, 0x9c9b, 0x9c9c, 0x9c9d, 0x9c9e, 0x9c9f, 0x9ca0, + 0x9ca1, 0x9ca2, 0x9ca3, 0x9ca4, 0x9ca5, 0x9ca6, 0x9ca7, 0x9ca8, + 0x9ca9, 0x9caa, 0x9cab, 0x9cac, 0x9cad, 0x9cae, 0x9caf, 0x9cb0, + 0x9cb1, 0x9cb2, 0x9cb3, 0x9cb4, 0x9cb5, 0x9cb6, 0x9cb7, 0x9cb8, + 0x9cb9, 0x9cba, 0x9cbb, 0x9cbc, 0x9cbd, 0x9cbe, 0x9cbf, 0x9cc0, + 0x9cc1, 0x9cc2, 0x9cc3, 0x9cc4, 0x9cc5, 0x9cc6, 0x9cc7, 0x9cc8, + 0x9cc9, 0x9cca, 0x9ccb, 0x9ccc, 0x9ccd, 0x9cce, 0x9ccf, 0x9cd0, + 0x9cd1, 0x9cd2, 0x9cd3, 0x9cd4, 0x9cd5, 0x9cd6, 0x9cd7, 0x9cd8, + 0x9cd9, 0x9cda, 0x9cdb, 0x9cdc, 0x9cdd, 0x9cde, 0x9cdf, 0x9ce0, + 0x9ce1, 0x9ce2, 0x9ce3, 0x9ce4, 0x9ce5, 0x9ce6, 0x9ce7, 0x9ce8, + 0x9ce9, 0x9cea, 0x9ceb, 0x9cec, 0x9ced, 0x9cee, 0x9cef, 0x9cf0, + 0x9cf1, 0x9cf2, 0x9cf3, 0x9cf4, 0x9cf5, 0x9cf6, 0x9cf7, 0x9cf8, + 0x9cf9, 0x9cfa, 0x9cfb, 0x9cfc, 0x9cfd, 0x9cfe, 0x9d40, 0x9d41, + 0x9d42, 0x9d43, 0x9d44, 0x9d45, 0x9d46, 0x9d47, 0x9d48, 0x9d49, + 0x9d4a, 0x9d4b, 0x9d4c, 0x9d4d, 0x9d4e, 0x9d4f, 0x9d50, 0x9d51, + 0x9d52, 0x9d53, 0x9d54, 0x9d55, 0x9d56, 0x9d57, 0x9d58, 0x9d59, + 0x9d5a, 0x9d5b, 0x9d5c, 0x9d5d, 0x9d5e, 0x9d5f, 0x9d60, 0x9d61, + 0x9d62, 0x9d63, 0x9d64, 0x9d65, 0x9d66, 0x9d67, 0x9d68, 0x9d69, + 0x9d6a, 0x9d6b, 0x9d6c, 0x9d6d, 0x9d6e, 0x9d6f, 0x9d70, 0x9d71, + 0x9d72, 0x9d73, 0x9d74, 0x9d75, 0x9d76, 0x9d77, 0x9d78, 0x9d79, + 0x9d7a, 0x9d7b, 0x9d7c, 0x9d7d, 0x9d7e, 0x9d80, 0x9d81, 0x9d82, + 0x9d83, 0x9d84, 0x9d85, 0x9d86, 0x9d87, 0x9d88, 0x9d89, 0x9d8a, + 0x9d8b, 0x9d8c, 0x9d8d, 0x9d8e, 0x9d8f, 0x9d90, 0x9d91, 0x9d92, + 0x9d93, 0x9d94, 0x9d95, 0x9d96, 0x9d97, 0x9d98, 0x9d99, 0x9d9a, + 0x9d9b, 0x9d9c, 0x9d9d, 0x9d9e, 0x9d9f, 0x9da0, 0x9da1, 0x9da2, + 0x9da3, 0x9da4, 0x9da5, 0x9da6, 0x9da7, 0x9da8, 0x9da9, 0x9daa, + 0x9dab, 0x9dac, 0x9dad, 0x9dae, 0x9daf, 0x9db0, 0x9db1, 0x9db2, + 0x9db3, 0x9db4, 0x9db5, 0x9db6, 0x9db7, 0x9db8, 0x9db9, 0x9dba, + 0x9dbb, 0x9dbc, 0x9dbd, 0x9dbe, 0x9dbf, 0x9dc0, 0x9dc1, 0x9dc2, + 0x9dc3, 0x9dc4, 0x9dc5, 0x9dc6, 0x9dc7, 0x9dc8, 0x9dc9, 0x9dca, + 0x9dcb, 0x9dcc, 0x9dcd, 0x9dce, 0x9dcf, 0x9dd0, 0x9dd1, 0x9dd2, + 0x9dd3, 0x9dd4, 0x9dd5, 0x9dd6, 0x9dd7, 0x9dd8, 0x9dd9, 0x9dda, + 0x9ddb, 0x9ddc, 0x9ddd, 0x9dde, 0x9ddf, 0x9de0, 0x9de1, 0x9de2, + 0x9de3, 0x9de4, 0x9de5, 0x9de6, 0x9de7, 0x9de8, 0x9de9, 0x9dea, + 0x9deb, 0x9dec, 0x9ded, 0x9dee, 0x9def, 0x9df0, 0x9df1, 0x9df2, + 0x9df3, 0x9df4, 0x9df5, 0x9df6, 0x9df7, 0x9df8, 0x9df9, 0x9dfa, + 0x9dfb, 0x9dfc, 0x9dfd, 0x9dfe, 0x9e40, 0x9e41, 0x9e42, 0x9e43, + 0x9e44, 0x9e45, 0x9e46, 0x9e47, 0x9e48, 0x9e49, 0x9e4a, 0x9e4b, + 0x9e4c, 0x9e4d, 0x9e4e, 0x9e4f, 0x9e50, 0x9e51, 0x9e52, 0x9e53, + 0x9e54, 0x9e55, 0x9e56, 0x9e57, 0x9e58, 0x9e59, 0x9e5a, 0x9e5b, + 0x9e5c, 0x9e5d, 0x9e5e, 0x9e5f, 0x9e60, 0x9e61, 0x9e62, 0x9e63, + 0x9e64, 0x9e65, 0x9e66, 0x9e67, 0x9e68, 0x9e69, 0x9e6a, 0x9e6b, + 0x9e6c, 0x9e6d, 0x9e6e, 0x9e6f, 0x9e70, 0x9e71, 0x9e72, 0x9e73, + 0x9e74, 0x9e75, 0x9e76, 0x9e77, 0x9e78, 0x9e79, 0x9e7a, 0x9e7b, + 0x9e7c, 0x9e7d, 0x9e7e, 0x9e80, 0x9e81, 0x9e82, 0x9e83, 0x9e84, + 0x9e85, 0x9e86, 0x9e87, 0x9e88, 0x9e89, 0x9e8a, 0x9e8b, 0x9e8c, + 0x9e8d, 0x9e8e, 0x9e8f, 0x9e90, 0x9e91, 0x9e92, 0x9e93, 0x9e94, + 0x9e95, 0x9e96, 0x9e97, 0x9e98, 0x9e99, 0x9e9a, 0x9e9b, 0x9e9c, + 0x9e9d, 0x9e9e, 0x9e9f, 0x9ea0, 0x9ea1, 0x9ea2, 0x9ea3, 0x9ea4, + 0x9ea5, 0x9ea6, 0x9ea7, 0x9ea8, 0x9ea9, 0x9eaa, 0x9eab, 0x9eac, + 0x9ead, 0x9eae, 0x9eaf, 0x9eb0, 0x9eb1, 0x9eb2, 0x9eb3, 0x9eb4, + 0x9eb5, 0x9eb6, 0x9eb7, 0x9eb8, 0x9eb9, 0x9eba, 0x9ebb, 0x9ebc, + 0x9ebd, 0x9ebe, 0x9ebf, 0x9ec0, 0x9ec1, 0x9ec2, 0x9ec3, 0x9ec4, + 0x9ec5, 0x9ec6, 0x9ec7, 0x9ec8, 0x9ec9, 0x9eca, 0x9ecb, 0x9ecc, + 0x9ecd, 0x9ece, 0x9ecf, 0x9ed0, 0x9ed1, 0x9ed2, 0x9ed3, 0x9ed4, + 0x9ed5, 0x9ed6, 0x9ed7, 0x9ed8, 0x9ed9, 0x9eda, 0x9edb, 0x9edc, + 0x9edd, 0x9ede, 0x9edf, 0x9ee0, 0x9ee1, 0x9ee2, 0x9ee3, 0x9ee4, + 0x9ee5, 0x9ee6, 0x9ee7, 0x9ee8, 0x9ee9, 0x9eea, 0x9eeb, 0x9eec, + 0x9eed, 0x9eee, 0x9eef, 0x9ef0, 0x9ef1, 0x9ef2, 0x9ef3, 0x9ef4, + 0x9ef5, 0x9ef6, 0x9ef7, 0x9ef8, 0x9ef9, 0x9efa, 0x9efb, 0x9efc, + 0x9efd, 0x9efe, 0x9f40, 0x9f41, 0x9f42, 0x9f43, 0x9f44, 0x9f45, + 0x9f46, 0x9f47, 0x9f48, 0x9f49, 0x9f4a, 0x9f4b, 0x9f4c, 0x9f4d, + 0x9f4e, 0x9f4f, 0x9f50, 0x9f51, 0x9f52, 0x9f53, 0x9f54, 0x9f55, + 0x9f56, 0x9f57, 0x9f58, 0x9f59, 0x9f5a, 0x9f5b, 0x9f5c, 0x9f5d, + 0x9f5e, 0x9f5f, 0x9f60, 0x9f61, 0x9f62, 0x9f63, 0x9f64, 0x9f65, + 0x9f66, 0x9f67, 0x9f68, 0x9f69, 0x9f6a, 0x9f6b, 0x9f6c, 0x9f6d, + 0x9f6e, 0x9f6f, 0x9f70, 0x9f71, 0x9f72, 0x9f73, 0x9f74, 0x9f75, + 0x9f76, 0x9f77, 0x9f78, 0x9f79, 0x9f7a, 0x9f7b, 0x9f7c, 0x9f7d, + 0x9f7e, 0x9f80, 0x9f81, 0x9f82, 0x9f83, 0x9f84, 0x9f85, 0x9f86, + 0x9f87, 0x9f88, 0x9f89, 0x9f8a, 0x9f8b, 0x9f8c, 0x9f8d, 0x9f8e, + 0x9f8f, 0x9f90, 0x9f91, 0x9f92, 0x9f93, 0x9f94, 0x9f95, 0x9f96, + 0x9f97, 0x9f98, 0x9f99, 0x9f9a, 0x9f9b, 0x9f9c, 0x9f9d, 0x9f9e, + 0x9f9f, 0x9fa0, 0x9fa1, 0x9fa2, 0x9fa3, 0x9fa4, 0x9fa5, 0x9fa6, + 0x9fa7, 0x9fa8, 0x9fa9, 0x9faa, 0x9fab, 0x9fac, 0x9fad, 0x9fae, + 0x9faf, 0x9fb0, 0x9fb1, 0x9fb2, 0x9fb3, 0x9fb4, 0x9fb5, 0x9fb6, + 0x9fb7, 0x9fb8, 0x9fb9, 0x9fba, 0x9fbb, 0x9fbc, 0x9fbd, 0x9fbe, + 0x9fbf, 0x9fc0, 0x9fc1, 0x9fc2, 0x9fc3, 0x9fc4, 0x9fc5, 0x9fc6, + 0x9fc7, 0x9fc8, 0x9fc9, 0x9fca, 0x9fcb, 0x9fcc, 0x9fcd, 0x9fce, + 0x9fcf, 0x9fd0, 0x9fd1, 0x9fd2, 0x9fd3, 0x9fd4, 0x9fd5, 0x9fd6, + 0x9fd7, 0x9fd8, 0x9fd9, 0x9fda, 0x9fdb, 0x9fdc, 0x9fdd, 0x9fde, + 0x9fdf, 0x9fe0, 0x9fe1, 0x9fe2, 0x9fe3, 0x9fe4, 0x9fe5, 0x9fe6, + 0x9fe7, 0x9fe8, 0x9fe9, 0x9fea, 0x9feb, 0x9fec, 0x9fed, 0x9fee, + 0x9fef, 0x9ff0, 0x9ff1, 0x9ff2, 0x9ff3, 0x9ff4, 0x9ff5, 0x9ff6, + 0x9ff7, 0x9ff8, 0x9ff9, 0x9ffa, 0x9ffb, 0x9ffc, 0x9ffd, 0x9ffe, + 0xa040, 0xa041, 0xa042, 0xa043, 0xa044, 0xa045, 0xa046, 0xa047, + 0xa048, 0xa049, 0xa04a, 0xa04b, 0xa04c, 0xa04d, 0xa04e, 0xa04f, + 0xa050, 0xa051, 0xa052, 0xa053, 0xa054, 0xa055, 0xa056, 0xa057, + 0xa058, 0xa059, 0xa05a, 0xa05b, 0xa05c, 0xa05d, 0xa05e, 0xa05f, + 0xa060, 0xa061, 0xa062, 0xa063, 0xa064, 0xa065, 0xa066, 0xa067, + 0xa068, 0xa069, 0xa06a, 0xa06b, 0xa06c, 0xa06d, 0xa06e, 0xa06f, + 0xa070, 0xa071, 0xa072, 0xa073, 0xa074, 0xa075, 0xa076, 0xa077, + 0xa078, 0xa079, 0xa07a, 0xa07b, 0xa07c, 0xa07d, 0xa07e, 0xa080, + 0xa081, 0xa082, 0xa083, 0xa084, 0xa085, 0xa086, 0xa087, 0xa088, + 0xa089, 0xa08a, 0xa08b, 0xa08c, 0xa08d, 0xa08e, 0xa08f, 0xa090, + 0xa091, 0xa092, 0xa093, 0xa094, 0xa095, 0xa096, 0xa097, 0xa098, + 0xa099, 0xa09a, 0xa09b, 0xa09c, 0xa09d, 0xa09e, 0xa09f, 0xa0a0, + 0xa0a1, 0xa0a2, 0xa0a3, 0xa0a4, 0xa0a5, 0xa0a6, 0xa0a7, 0xa0a8, + 0xa0a9, 0xa0aa, 0xa0ab, 0xa0ac, 0xa0ad, 0xa0ae, 0xa0af, 0xa0b0, + 0xa0b1, 0xa0b2, 0xa0b3, 0xa0b4, 0xa0b5, 0xa0b6, 0xa0b7, 0xa0b8, + 0xa0b9, 0xa0ba, 0xa0bb, 0xa0bc, 0xa0bd, 0xa0be, 0xa0bf, 0xa0c0, + 0xa0c1, 0xa0c2, 0xa0c3, 0xa0c4, 0xa0c5, 0xa0c6, 0xa0c7, 0xa0c8, + 0xa0c9, 0xa0ca, 0xa0cb, 0xa0cc, 0xa0cd, 0xa0ce, 0xa0cf, 0xa0d0, + 0xa0d1, 0xa0d2, 0xa0d3, 0xa0d4, 0xa0d5, 0xa0d6, 0xa0d7, 0xa0d8, + 0xa0d9, 0xa0da, 0xa0db, 0xa0dc, 0xa0dd, 0xa0de, 0xa0df, 0xa0e0, + 0xa0e1, 0xa0e2, 0xa0e3, 0xa0e4, 0xa0e5, 0xa0e6, 0xa0e7, 0xa0e8, + 0xa0e9, 0xa0ea, 0xa0eb, 0xa0ec, 0xa0ed, 0xa0ee, 0xa0ef, 0xa0f0, + 0xa0f1, 0xa0f2, 0xa0f3, 0xa0f4, 0xa0f5, 0xa0f6, 0xa0f7, 0xa0f8, + 0xa0f9, 0xa0fa, 0xa0fb, 0xa0fc, 0xa0fd, 0xa0fe, 0xaa40, 0xaa41, + 0xaa42, 0xaa43, 0xaa44, 0xaa45, 0xaa46, 0xaa47, 0xaa48, 0xaa49, + 0xaa4a, 0xaa4b, 0xaa4c, 0xaa4d, 0xaa4e, 0xaa4f, 0xaa50, 0xaa51, + 0xaa52, 0xaa53, 0xaa54, 0xaa55, 0xaa56, 0xaa57, 0xaa58, 0xaa59, + 0xaa5a, 0xaa5b, 0xaa5c, 0xaa5d, 0xaa5e, 0xaa5f, 0xaa60, 0xaa61, + 0xaa62, 0xaa63, 0xaa64, 0xaa65, 0xaa66, 0xaa67, 0xaa68, 0xaa69, + 0xaa6a, 0xaa6b, 0xaa6c, 0xaa6d, 0xaa6e, 0xaa6f, 0xaa70, 0xaa71, + 0xaa72, 0xaa73, 0xaa74, 0xaa75, 0xaa76, 0xaa77, 0xaa78, 0xaa79, + 0xaa7a, 0xaa7b, 0xaa7c, 0xaa7d, 0xaa7e, 0xaa80, 0xaa81, 0xaa82, + 0xaa83, 0xaa84, 0xaa85, 0xaa86, 0xaa87, 0xaa88, 0xaa89, 0xaa8a, + 0xaa8b, 0xaa8c, 0xaa8d, 0xaa8e, 0xaa8f, 0xaa90, 0xaa91, 0xaa92, + 0xaa93, 0xaa94, 0xaa95, 0xaa96, 0xaa97, 0xaa98, 0xaa99, 0xaa9a, + 0xaa9b, 0xaa9c, 0xaa9d, 0xaa9e, 0xaa9f, 0xaaa0, 0xab40, 0xab41, + 0xab42, 0xab43, 0xab44, 0xab45, 0xab46, 0xab47, 0xab48, 0xab49, + 0xab4a, 0xab4b, 0xab4c, 0xab4d, 0xab4e, 0xab4f, 0xab50, 0xab51, + 0xab52, 0xab53, 0xab54, 0xab55, 0xab56, 0xab57, 0xab58, 0xab59, + 0xab5a, 0xab5b, 0xab5c, 0xab5d, 0xab5e, 0xab5f, 0xab60, 0xab61, + 0xab62, 0xab63, 0xab64, 0xab65, 0xab66, 0xab67, 0xab68, 0xab69, + 0xab6a, 0xab6b, 0xab6c, 0xab6d, 0xab6e, 0xab6f, 0xab70, 0xab71, + 0xab72, 0xab73, 0xab74, 0xab75, 0xab76, 0xab77, 0xab78, 0xab79, + 0xab7a, 0xab7b, 0xab7c, 0xab7d, 0xab7e, 0xab80, 0xab81, 0xab82, + 0xab83, 0xab84, 0xab85, 0xab86, 0xab87, 0xab88, 0xab89, 0xab8a, + 0xab8b, 0xab8c, 0xab8d, 0xab8e, 0xab8f, 0xab90, 0xab91, 0xab92, + 0xab93, 0xab94, 0xab95, 0xab96, 0xab97, 0xab98, 0xab99, 0xab9a, + 0xab9b, 0xab9c, 0xab9d, 0xab9e, 0xab9f, 0xaba0, 0xac40, 0xac41, + 0xac42, 0xac43, 0xac44, 0xac45, 0xac46, 0xac47, 0xac48, 0xac49, + 0xac4a, 0xac4b, 0xac4c, 0xac4d, 0xac4e, 0xac4f, 0xac50, 0xac51, + 0xac52, 0xac53, 0xac54, 0xac55, 0xac56, 0xac57, 0xac58, 0xac59, + 0xac5a, 0xac5b, 0xac5c, 0xac5d, 0xac5e, 0xac5f, 0xac60, 0xac61, + 0xac62, 0xac63, 0xac64, 0xac65, 0xac66, 0xac67, 0xac68, 0xac69, + 0xac6a, 0xac6b, 0xac6c, 0xac6d, 0xac6e, 0xac6f, 0xac70, 0xac71, + 0xac72, 0xac73, 0xac74, 0xac75, 0xac76, 0xac77, 0xac78, 0xac79, + 0xac7a, 0xac7b, 0xac7c, 0xac7d, 0xac7e, 0xac80, 0xac81, 0xac82, + 0xac83, 0xac84, 0xac85, 0xac86, 0xac87, 0xac88, 0xac89, 0xac8a, + 0xac8b, 0xac8c, 0xac8d, 0xac8e, 0xac8f, 0xac90, 0xac91, 0xac92, + 0xac93, 0xac94, 0xac95, 0xac96, 0xac97, 0xac98, 0xac99, 0xac9a, + 0xac9b, 0xac9c, 0xac9d, 0xac9e, 0xac9f, 0xaca0, 0xad40, 0xad41, + 0xad42, 0xad43, 0xad44, 0xad45, 0xad46, 0xad47, 0xad48, 0xad49, + 0xad4a, 0xad4b, 0xad4c, 0xad4d, 0xad4e, 0xad4f, 0xad50, 0xad51, + 0xad52, 0xad53, 0xad54, 0xad55, 0xad56, 0xad57, 0xad58, 0xad59, + 0xad5a, 0xad5b, 0xad5c, 0xad5d, 0xad5e, 0xad5f, 0xad60, 0xad61, + 0xad62, 0xad63, 0xad64, 0xad65, 0xad66, 0xad67, 0xad68, 0xad69, + 0xad6a, 0xad6b, 0xad6c, 0xad6d, 0xad6e, 0xad6f, 0xad70, 0xad71, + 0xad72, 0xad73, 0xad74, 0xad75, 0xad76, 0xad77, 0xad78, 0xad79, + 0xad7a, 0xad7b, 0xad7c, 0xad7d, 0xad7e, 0xad80, 0xad81, 0xad82, + 0xad83, 0xad84, 0xad85, 0xad86, 0xad87, 0xad88, 0xad89, 0xad8a, + 0xad8b, 0xad8c, 0xad8d, 0xad8e, 0xad8f, 0xad90, 0xad91, 0xad92, + 0xad93, 0xad94, 0xad95, 0xad96, 0xad97, 0xad98, 0xad99, 0xad9a, + 0xad9b, 0xad9c, 0xad9d, 0xad9e, 0xad9f, 0xada0, 0xae40, 0xae41, + 0xae42, 0xae43, 0xae44, 0xae45, 0xae46, 0xae47, 0xae48, 0xae49, + 0xae4a, 0xae4b, 0xae4c, 0xae4d, 0xae4e, 0xae4f, 0xae50, 0xae51, + 0xae52, 0xae53, 0xae54, 0xae55, 0xae56, 0xae57, 0xae58, 0xae59, + 0xae5a, 0xae5b, 0xae5c, 0xae5d, 0xae5e, 0xae5f, 0xae60, 0xae61, + 0xae62, 0xae63, 0xae64, 0xae65, 0xae66, 0xae67, 0xae68, 0xae69, + 0xae6a, 0xae6b, 0xae6c, 0xae6d, 0xae6e, 0xae6f, 0xae70, 0xae71, + 0xae72, 0xae73, 0xae74, 0xae75, 0xae76, 0xae77, 0xae78, 0xae79, + 0xae7a, 0xae7b, 0xae7c, 0xae7d, 0xae7e, 0xae80, 0xae81, 0xae82, + 0xae83, 0xae84, 0xae85, 0xae86, 0xae87, 0xae88, 0xae89, 0xae8a, + 0xae8b, 0xae8c, 0xae8d, 0xae8e, 0xae8f, 0xae90, 0xae91, 0xae92, + 0xae93, 0xae94, 0xae95, 0xae96, 0xae97, 0xae98, 0xae99, 0xae9a, + 0xae9b, 0xae9c, 0xae9d, 0xae9e, 0xae9f, 0xaea0, 0xaf40, 0xaf41, + 0xaf42, 0xaf43, 0xaf44, 0xaf45, 0xaf46, 0xaf47, 0xaf48, 0xaf49, + 0xaf4a, 0xaf4b, 0xaf4c, 0xaf4d, 0xaf4e, 0xaf4f, 0xaf50, 0xaf51, + 0xaf52, 0xaf53, 0xaf54, 0xaf55, 0xaf56, 0xaf57, 0xaf58, 0xaf59, + 0xaf5a, 0xaf5b, 0xaf5c, 0xaf5d, 0xaf5e, 0xaf5f, 0xaf60, 0xaf61, + 0xaf62, 0xaf63, 0xaf64, 0xaf65, 0xaf66, 0xaf67, 0xaf68, 0xaf69, + 0xaf6a, 0xaf6b, 0xaf6c, 0xaf6d, 0xaf6e, 0xaf6f, 0xaf70, 0xaf71, + 0xaf72, 0xaf73, 0xaf74, 0xaf75, 0xaf76, 0xaf77, 0xaf78, 0xaf79, + 0xaf7a, 0xaf7b, 0xaf7c, 0xaf7d, 0xaf7e, 0xaf80, 0xaf81, 0xaf82, + 0xaf83, 0xaf84, 0xaf85, 0xaf86, 0xaf87, 0xaf88, 0xaf89, 0xaf8a, + 0xaf8b, 0xaf8c, 0xaf8d, 0xaf8e, 0xaf8f, 0xaf90, 0xaf91, 0xaf92, + 0xaf93, 0xaf94, 0xaf95, 0xaf96, 0xaf97, 0xaf98, 0xaf99, 0xaf9a, + 0xaf9b, 0xaf9c, 0xaf9d, 0xaf9e, 0xaf9f, 0xafa0, 0xb040, 0xb041, + 0xb042, 0xb043, 0xb044, 0xb045, 0xb046, 0xb047, 0xb048, 0xb049, + 0xb04a, 0xb04b, 0xb04c, 0xb04d, 0xb04e, 0xb04f, 0xb050, 0xb051, + 0xb052, 0xb053, 0xb054, 0xb055, 0xb056, 0xb057, 0xb058, 0xb059, + 0xb05a, 0xb05b, 0xb05c, 0xb05d, 0xb05e, 0xb05f, 0xb060, 0xb061, + 0xb062, 0xb063, 0xb064, 0xb065, 0xb066, 0xb067, 0xb068, 0xb069, + 0xb06a, 0xb06b, 0xb06c, 0xb06d, 0xb06e, 0xb06f, 0xb070, 0xb071, + 0xb072, 0xb073, 0xb074, 0xb075, 0xb076, 0xb077, 0xb078, 0xb079, + 0xb07a, 0xb07b, 0xb07c, 0xb07d, 0xb07e, 0xb080, 0xb081, 0xb082, + 0xb083, 0xb084, 0xb085, 0xb086, 0xb087, 0xb088, 0xb089, 0xb08a, + 0xb08b, 0xb08c, 0xb08d, 0xb08e, 0xb08f, 0xb090, 0xb091, 0xb092, + 0xb093, 0xb094, 0xb095, 0xb096, 0xb097, 0xb098, 0xb099, 0xb09a, + 0xb09b, 0xb09c, 0xb09d, 0xb09e, 0xb09f, 0xb0a0, 0xb140, 0xb141, + 0xb142, 0xb143, 0xb144, 0xb145, 0xb146, 0xb147, 0xb148, 0xb149, + 0xb14a, 0xb14b, 0xb14c, 0xb14d, 0xb14e, 0xb14f, 0xb150, 0xb151, + 0xb152, 0xb153, 0xb154, 0xb155, 0xb156, 0xb157, 0xb158, 0xb159, + 0xb15a, 0xb15b, 0xb15c, 0xb15d, 0xb15e, 0xb15f, 0xb160, 0xb161, + 0xb162, 0xb163, 0xb164, 0xb165, 0xb166, 0xb167, 0xb168, 0xb169, + 0xb16a, 0xb16b, 0xb16c, 0xb16d, 0xb16e, 0xb16f, 0xb170, 0xb171, + 0xb172, 0xb173, 0xb174, 0xb175, 0xb176, 0xb177, 0xb178, 0xb179, + 0xb17a, 0xb17b, 0xb17c, 0xb17d, 0xb17e, 0xb180, 0xb181, 0xb182, + 0xb183, 0xb184, 0xb185, 0xb186, 0xb187, 0xb188, 0xb189, 0xb18a, + 0xb18b, 0xb18c, 0xb18d, 0xb18e, 0xb18f, 0xb190, 0xb191, 0xb192, + 0xb193, 0xb194, 0xb195, 0xb196, 0xb197, 0xb198, 0xb199, 0xb19a, + 0xb19b, 0xb19c, 0xb19d, 0xb19e, 0xb19f, 0xb1a0, 0xb240, 0xb241, + 0xb242, 0xb243, 0xb244, 0xb245, 0xb246, 0xb247, 0xb248, 0xb249, + 0xb24a, 0xb24b, 0xb24c, 0xb24d, 0xb24e, 0xb24f, 0xb250, 0xb251, + 0xb252, 0xb253, 0xb254, 0xb255, 0xb256, 0xb257, 0xb258, 0xb259, + 0xb25a, 0xb25b, 0xb25c, 0xb25d, 0xb25e, 0xb25f, 0xb260, 0xb261, + 0xb262, 0xb263, 0xb264, 0xb265, 0xb266, 0xb267, 0xb268, 0xb269, + 0xb26a, 0xb26b, 0xb26c, 0xb26d, 0xb26e, 0xb26f, 0xb270, 0xb271, + 0xb272, 0xb273, 0xb274, 0xb275, 0xb276, 0xb277, 0xb278, 0xb279, + 0xb27a, 0xb27b, 0xb27c, 0xb27d, 0xb27e, 0xb280, 0xb281, 0xb282, + 0xb283, 0xb284, 0xb285, 0xb286, 0xb287, 0xb288, 0xb289, 0xb28a, + 0xb28b, 0xb28c, 0xb28d, 0xb28e, 0xb28f, 0xb290, 0xb291, 0xb292, + 0xb293, 0xb294, 0xb295, 0xb296, 0xb297, 0xb298, 0xb299, 0xb29a, + 0xb29b, 0xb29c, 0xb29d, 0xb29e, 0xb29f, 0xb2a0, 0xb340, 0xb341, + 0xb342, 0xb343, 0xb344, 0xb345, 0xb346, 0xb347, 0xb348, 0xb349, + 0xb34a, 0xb34b, 0xb34c, 0xb34d, 0xb34e, 0xb34f, 0xb350, 0xb351, + 0xb352, 0xb353, 0xb354, 0xb355, 0xb356, 0xb357, 0xb358, 0xb359, + 0xb35a, 0xb35b, 0xb35c, 0xb35d, 0xb35e, 0xb35f, 0xb360, 0xb361, + 0xb362, 0xb363, 0xb364, 0xb365, 0xb366, 0xb367, 0xb368, 0xb369, + 0xb36a, 0xb36b, 0xb36c, 0xb36d, 0xb36e, 0xb36f, 0xb370, 0xb371, + 0xb372, 0xb373, 0xb374, 0xb375, 0xb376, 0xb377, 0xb378, 0xb379, + 0xb37a, 0xb37b, 0xb37c, 0xb37d, 0xb37e, 0xb380, 0xb381, 0xb382, + 0xb383, 0xb384, 0xb385, 0xb386, 0xb387, 0xb388, 0xb389, 0xb38a, + 0xb38b, 0xb38c, 0xb38d, 0xb38e, 0xb38f, 0xb390, 0xb391, 0xb392, + 0xb393, 0xb394, 0xb395, 0xb396, 0xb397, 0xb398, 0xb399, 0xb39a, + 0xb39b, 0xb39c, 0xb39d, 0xb39e, 0xb39f, 0xb3a0, 0xb440, 0xb441, + 0xb442, 0xb443, 0xb444, 0xb445, 0xb446, 0xb447, 0xb448, 0xb449, + 0xb44a, 0xb44b, 0xb44c, 0xb44d, 0xb44e, 0xb44f, 0xb450, 0xb451, + 0xb452, 0xb453, 0xb454, 0xb455, 0xb456, 0xb457, 0xb458, 0xb459, + 0xb45a, 0xb45b, 0xb45c, 0xb45d, 0xb45e, 0xb45f, 0xb460, 0xb461, + 0xb462, 0xb463, 0xb464, 0xb465, 0xb466, 0xb467, 0xb468, 0xb469, + 0xb46a, 0xb46b, 0xb46c, 0xb46d, 0xb46e, 0xb46f, 0xb470, 0xb471, + 0xb472, 0xb473, 0xb474, 0xb475, 0xb476, 0xb477, 0xb478, 0xb479, + 0xb47a, 0xb47b, 0xb47c, 0xb47d, 0xb47e, 0xb480, 0xb481, 0xb482, + 0xb483, 0xb484, 0xb485, 0xb486, 0xb487, 0xb488, 0xb489, 0xb48a, + 0xb48b, 0xb48c, 0xb48d, 0xb48e, 0xb48f, 0xb490, 0xb491, 0xb492, + 0xb493, 0xb494, 0xb495, 0xb496, 0xb497, 0xb498, 0xb499, 0xb49a, + 0xb49b, 0xb49c, 0xb49d, 0xb49e, 0xb49f, 0xb4a0, 0xb540, 0xb541, + 0xb542, 0xb543, 0xb544, 0xb545, 0xb546, 0xb547, 0xb548, 0xb549, + 0xb54a, 0xb54b, 0xb54c, 0xb54d, 0xb54e, 0xb54f, 0xb550, 0xb551, + 0xb552, 0xb553, 0xb554, 0xb555, 0xb556, 0xb557, 0xb558, 0xb559, + 0xb55a, 0xb55b, 0xb55c, 0xb55d, 0xb55e, 0xb55f, 0xb560, 0xb561, + 0xb562, 0xb563, 0xb564, 0xb565, 0xb566, 0xb567, 0xb568, 0xb569, + 0xb56a, 0xb56b, 0xb56c, 0xb56d, 0xb56e, 0xb56f, 0xb570, 0xb571, + 0xb572, 0xb573, 0xb574, 0xb575, 0xb576, 0xb577, 0xb578, 0xb579, + 0xb57a, 0xb57b, 0xb57c, 0xb57d, 0xb57e, 0xb580, 0xb581, 0xb582, + 0xb583, 0xb584, 0xb585, 0xb586, 0xb587, 0xb588, 0xb589, 0xb58a, + 0xb58b, 0xb58c, 0xb58d, 0xb58e, 0xb58f, 0xb590, 0xb591, 0xb592, + 0xb593, 0xb594, 0xb595, 0xb596, 0xb597, 0xb598, 0xb599, 0xb59a, + 0xb59b, 0xb59c, 0xb59d, 0xb59e, 0xb59f, 0xb5a0, 0xb640, 0xb641, + 0xb642, 0xb643, 0xb644, 0xb645, 0xb646, 0xb647, 0xb648, 0xb649, + 0xb64a, 0xb64b, 0xb64c, 0xb64d, 0xb64e, 0xb64f, 0xb650, 0xb651, + 0xb652, 0xb653, 0xb654, 0xb655, 0xb656, 0xb657, 0xb658, 0xb659, + 0xb65a, 0xb65b, 0xb65c, 0xb65d, 0xb65e, 0xb65f, 0xb660, 0xb661, + 0xb662, 0xb663, 0xb664, 0xb665, 0xb666, 0xb667, 0xb668, 0xb669, + 0xb66a, 0xb66b, 0xb66c, 0xb66d, 0xb66e, 0xb66f, 0xb670, 0xb671, + 0xb672, 0xb673, 0xb674, 0xb675, 0xb676, 0xb677, 0xb678, 0xb679, + 0xb67a, 0xb67b, 0xb67c, 0xb67d, 0xb67e, 0xb680, 0xb681, 0xb682, + 0xb683, 0xb684, 0xb685, 0xb686, 0xb687, 0xb688, 0xb689, 0xb68a, + 0xb68b, 0xb68c, 0xb68d, 0xb68e, 0xb68f, 0xb690, 0xb691, 0xb692, + 0xb693, 0xb694, 0xb695, 0xb696, 0xb697, 0xb698, 0xb699, 0xb69a, + 0xb69b, 0xb69c, 0xb69d, 0xb69e, 0xb69f, 0xb6a0, 0xb740, 0xb741, + 0xb742, 0xb743, 0xb744, 0xb745, 0xb746, 0xb747, 0xb748, 0xb749, + 0xb74a, 0xb74b, 0xb74c, 0xb74d, 0xb74e, 0xb74f, 0xb750, 0xb751, + 0xb752, 0xb753, 0xb754, 0xb755, 0xb756, 0xb757, 0xb758, 0xb759, + 0xb75a, 0xb75b, 0xb75c, 0xb75d, 0xb75e, 0xb75f, 0xb760, 0xb761, + 0xb762, 0xb763, 0xb764, 0xb765, 0xb766, 0xb767, 0xb768, 0xb769, + 0xb76a, 0xb76b, 0xb76c, 0xb76d, 0xb76e, 0xb76f, 0xb770, 0xb771, + 0xb772, 0xb773, 0xb774, 0xb775, 0xb776, 0xb777, 0xb778, 0xb779, + 0xb77a, 0xb77b, 0xb77c, 0xb77d, 0xb77e, 0xb780, 0xb781, 0xb782, + 0xb783, 0xb784, 0xb785, 0xb786, 0xb787, 0xb788, 0xb789, 0xb78a, + 0xb78b, 0xb78c, 0xb78d, 0xb78e, 0xb78f, 0xb790, 0xb791, 0xb792, + 0xb793, 0xb794, 0xb795, 0xb796, 0xb797, 0xb798, 0xb799, 0xb79a, + 0xb79b, 0xb79c, 0xb79d, 0xb79e, 0xb79f, 0xb7a0, 0xb840, 0xb841, + 0xb842, 0xb843, 0xb844, 0xb845, 0xb846, 0xb847, 0xb848, 0xb849, + 0xb84a, 0xb84b, 0xb84c, 0xb84d, 0xb84e, 0xb84f, 0xb850, 0xb851, + 0xb852, 0xb853, 0xb854, 0xb855, 0xb856, 0xb857, 0xb858, 0xb859, + 0xb85a, 0xb85b, 0xb85c, 0xb85d, 0xb85e, 0xb85f, 0xb860, 0xb861, + 0xb862, 0xb863, 0xb864, 0xb865, 0xb866, 0xb867, 0xb868, 0xb869, + 0xb86a, 0xb86b, 0xb86c, 0xb86d, 0xb86e, 0xb86f, 0xb870, 0xb871, + 0xb872, 0xb873, 0xb874, 0xb875, 0xb876, 0xb877, 0xb878, 0xb879, + 0xb87a, 0xb87b, 0xb87c, 0xb87d, 0xb87e, 0xb880, 0xb881, 0xb882, + 0xb883, 0xb884, 0xb885, 0xb886, 0xb887, 0xb888, 0xb889, 0xb88a, + 0xb88b, 0xb88c, 0xb88d, 0xb88e, 0xb88f, 0xb890, 0xb891, 0xb892, + 0xb893, 0xb894, 0xb895, 0xb896, 0xb897, 0xb898, 0xb899, 0xb89a, + 0xb89b, 0xb89c, 0xb89d, 0xb89e, 0xb89f, 0xb8a0, 0xb940, 0xb941, + 0xb942, 0xb943, 0xb944, 0xb945, 0xb946, 0xb947, 0xb948, 0xb949, + 0xb94a, 0xb94b, 0xb94c, 0xb94d, 0xb94e, 0xb94f, 0xb950, 0xb951, + 0xb952, 0xb953, 0xb954, 0xb955, 0xb956, 0xb957, 0xb958, 0xb959, + 0xb95a, 0xb95b, 0xb95c, 0xb95d, 0xb95e, 0xb95f, 0xb960, 0xb961, + 0xb962, 0xb963, 0xb964, 0xb965, 0xb966, 0xb967, 0xb968, 0xb969, + 0xb96a, 0xb96b, 0xb96c, 0xb96d, 0xb96e, 0xb96f, 0xb970, 0xb971, + 0xb972, 0xb973, 0xb974, 0xb975, 0xb976, 0xb977, 0xb978, 0xb979, + 0xb97a, 0xb97b, 0xb97c, 0xb97d, 0xb97e, 0xb980, 0xb981, 0xb982, + 0xb983, 0xb984, 0xb985, 0xb986, 0xb987, 0xb988, 0xb989, 0xb98a, + 0xb98b, 0xb98c, 0xb98d, 0xb98e, 0xb98f, 0xb990, 0xb991, 0xb992, + 0xb993, 0xb994, 0xb995, 0xb996, 0xb997, 0xb998, 0xb999, 0xb99a, + 0xb99b, 0xb99c, 0xb99d, 0xb99e, 0xb99f, 0xb9a0, 0xba40, 0xba41, + 0xba42, 0xba43, 0xba44, 0xba45, 0xba46, 0xba47, 0xba48, 0xba49, + 0xba4a, 0xba4b, 0xba4c, 0xba4d, 0xba4e, 0xba4f, 0xba50, 0xba51, + 0xba52, 0xba53, 0xba54, 0xba55, 0xba56, 0xba57, 0xba58, 0xba59, + 0xba5a, 0xba5b, 0xba5c, 0xba5d, 0xba5e, 0xba5f, 0xba60, 0xba61, + 0xba62, 0xba63, 0xba64, 0xba65, 0xba66, 0xba67, 0xba68, 0xba69, + 0xba6a, 0xba6b, 0xba6c, 0xba6d, 0xba6e, 0xba6f, 0xba70, 0xba71, + 0xba72, 0xba73, 0xba74, 0xba75, 0xba76, 0xba77, 0xba78, 0xba79, + 0xba7a, 0xba7b, 0xba7c, 0xba7d, 0xba7e, 0xba80, 0xba81, 0xba82, + 0xba83, 0xba84, 0xba85, 0xba86, 0xba87, 0xba88, 0xba89, 0xba8a, + 0xba8b, 0xba8c, 0xba8d, 0xba8e, 0xba8f, 0xba90, 0xba91, 0xba92, + 0xba93, 0xba94, 0xba95, 0xba96, 0xba97, 0xba98, 0xba99, 0xba9a, + 0xba9b, 0xba9c, 0xba9d, 0xba9e, 0xba9f, 0xbaa0, 0xbb40, 0xbb41, + 0xbb42, 0xbb43, 0xbb44, 0xbb45, 0xbb46, 0xbb47, 0xbb48, 0xbb49, + 0xbb4a, 0xbb4b, 0xbb4c, 0xbb4d, 0xbb4e, 0xbb4f, 0xbb50, 0xbb51, + 0xbb52, 0xbb53, 0xbb54, 0xbb55, 0xbb56, 0xbb57, 0xbb58, 0xbb59, + 0xbb5a, 0xbb5b, 0xbb5c, 0xbb5d, 0xbb5e, 0xbb5f, 0xbb60, 0xbb61, + 0xbb62, 0xbb63, 0xbb64, 0xbb65, 0xbb66, 0xbb67, 0xbb68, 0xbb69, + 0xbb6a, 0xbb6b, 0xbb6c, 0xbb6d, 0xbb6e, 0xbb6f, 0xbb70, 0xbb71, + 0xbb72, 0xbb73, 0xbb74, 0xbb75, 0xbb76, 0xbb77, 0xbb78, 0xbb79, + 0xbb7a, 0xbb7b, 0xbb7c, 0xbb7d, 0xbb7e, 0xbb80, 0xbb81, 0xbb82, + 0xbb83, 0xbb84, 0xbb85, 0xbb86, 0xbb87, 0xbb88, 0xbb89, 0xbb8a, + 0xbb8b, 0xbb8c, 0xbb8d, 0xbb8e, 0xbb8f, 0xbb90, 0xbb91, 0xbb92, + 0xbb93, 0xbb94, 0xbb95, 0xbb96, 0xbb97, 0xbb98, 0xbb99, 0xbb9a, + 0xbb9b, 0xbb9c, 0xbb9d, 0xbb9e, 0xbb9f, 0xbba0, 0xbc40, 0xbc41, + 0xbc42, 0xbc43, 0xbc44, 0xbc45, 0xbc46, 0xbc47, 0xbc48, 0xbc49, + 0xbc4a, 0xbc4b, 0xbc4c, 0xbc4d, 0xbc4e, 0xbc4f, 0xbc50, 0xbc51, + 0xbc52, 0xbc53, 0xbc54, 0xbc55, 0xbc56, 0xbc57, 0xbc58, 0xbc59, + 0xbc5a, 0xbc5b, 0xbc5c, 0xbc5d, 0xbc5e, 0xbc5f, 0xbc60, 0xbc61, + 0xbc62, 0xbc63, 0xbc64, 0xbc65, 0xbc66, 0xbc67, 0xbc68, 0xbc69, + 0xbc6a, 0xbc6b, 0xbc6c, 0xbc6d, 0xbc6e, 0xbc6f, 0xbc70, 0xbc71, + 0xbc72, 0xbc73, 0xbc74, 0xbc75, 0xbc76, 0xbc77, 0xbc78, 0xbc79, + 0xbc7a, 0xbc7b, 0xbc7c, 0xbc7d, 0xbc7e, 0xbc80, 0xbc81, 0xbc82, + 0xbc83, 0xbc84, 0xbc85, 0xbc86, 0xbc87, 0xbc88, 0xbc89, 0xbc8a, + 0xbc8b, 0xbc8c, 0xbc8d, 0xbc8e, 0xbc8f, 0xbc90, 0xbc91, 0xbc92, + 0xbc93, 0xbc94, 0xbc95, 0xbc96, 0xbc97, 0xbc98, 0xbc99, 0xbc9a, + 0xbc9b, 0xbc9c, 0xbc9d, 0xbc9e, 0xbc9f, 0xbca0, 0xbd40, 0xbd41, + 0xbd42, 0xbd43, 0xbd44, 0xbd45, 0xbd46, 0xbd47, 0xbd48, 0xbd49, + 0xbd4a, 0xbd4b, 0xbd4c, 0xbd4d, 0xbd4e, 0xbd4f, 0xbd50, 0xbd51, + 0xbd52, 0xbd53, 0xbd54, 0xbd55, 0xbd56, 0xbd57, 0xbd58, 0xbd59, + 0xbd5a, 0xbd5b, 0xbd5c, 0xbd5d, 0xbd5e, 0xbd5f, 0xbd60, 0xbd61, + 0xbd62, 0xbd63, 0xbd64, 0xbd65, 0xbd66, 0xbd67, 0xbd68, 0xbd69, + 0xbd6a, 0xbd6b, 0xbd6c, 0xbd6d, 0xbd6e, 0xbd6f, 0xbd70, 0xbd71, + 0xbd72, 0xbd73, 0xbd74, 0xbd75, 0xbd76, 0xbd77, 0xbd78, 0xbd79, + 0xbd7a, 0xbd7b, 0xbd7c, 0xbd7d, 0xbd7e, 0xbd80, 0xbd81, 0xbd82, + 0xbd83, 0xbd84, 0xbd85, 0xbd86, 0xbd87, 0xbd88, 0xbd89, 0xbd8a, + 0xbd8b, 0xbd8c, 0xbd8d, 0xbd8e, 0xbd8f, 0xbd90, 0xbd91, 0xbd92, + 0xbd93, 0xbd94, 0xbd95, 0xbd96, 0xbd97, 0xbd98, 0xbd99, 0xbd9a, + 0xbd9b, 0xbd9c, 0xbd9d, 0xbd9e, 0xbd9f, 0xbda0, 0xbe40, 0xbe41, + 0xbe42, 0xbe43, 0xbe44, 0xbe45, 0xbe46, 0xbe47, 0xbe48, 0xbe49, + 0xbe4a, 0xbe4b, 0xbe4c, 0xbe4d, 0xbe4e, 0xbe4f, 0xbe50, 0xbe51, + 0xbe52, 0xbe53, 0xbe54, 0xbe55, 0xbe56, 0xbe57, 0xbe58, 0xbe59, + 0xbe5a, 0xbe5b, 0xbe5c, 0xbe5d, 0xbe5e, 0xbe5f, 0xbe60, 0xbe61, + 0xbe62, 0xbe63, 0xbe64, 0xbe65, 0xbe66, 0xbe67, 0xbe68, 0xbe69, + 0xbe6a, 0xbe6b, 0xbe6c, 0xbe6d, 0xbe6e, 0xbe6f, 0xbe70, 0xbe71, + 0xbe72, 0xbe73, 0xbe74, 0xbe75, 0xbe76, 0xbe77, 0xbe78, 0xbe79, + 0xbe7a, 0xbe7b, 0xbe7c, 0xbe7d, 0xbe7e, 0xbe80, 0xbe81, 0xbe82, + 0xbe83, 0xbe84, 0xbe85, 0xbe86, 0xbe87, 0xbe88, 0xbe89, 0xbe8a, + 0xbe8b, 0xbe8c, 0xbe8d, 0xbe8e, 0xbe8f, 0xbe90, 0xbe91, 0xbe92, + 0xbe93, 0xbe94, 0xbe95, 0xbe96, 0xbe97, 0xbe98, 0xbe99, 0xbe9a, + 0xbe9b, 0xbe9c, 0xbe9d, 0xbe9e, 0xbe9f, 0xbea0, 0xbf40, 0xbf41, + 0xbf42, 0xbf43, 0xbf44, 0xbf45, 0xbf46, 0xbf47, 0xbf48, 0xbf49, + 0xbf4a, 0xbf4b, 0xbf4c, 0xbf4d, 0xbf4e, 0xbf4f, 0xbf50, 0xbf51, + 0xbf52, 0xbf53, 0xbf54, 0xbf55, 0xbf56, 0xbf57, 0xbf58, 0xbf59, + 0xbf5a, 0xbf5b, 0xbf5c, 0xbf5d, 0xbf5e, 0xbf5f, 0xbf60, 0xbf61, + 0xbf62, 0xbf63, 0xbf64, 0xbf65, 0xbf66, 0xbf67, 0xbf68, 0xbf69, + 0xbf6a, 0xbf6b, 0xbf6c, 0xbf6d, 0xbf6e, 0xbf6f, 0xbf70, 0xbf71, + 0xbf72, 0xbf73, 0xbf74, 0xbf75, 0xbf76, 0xbf77, 0xbf78, 0xbf79, + 0xbf7a, 0xbf7b, 0xbf7c, 0xbf7d, 0xbf7e, 0xbf80, 0xbf81, 0xbf82, + 0xbf83, 0xbf84, 0xbf85, 0xbf86, 0xbf87, 0xbf88, 0xbf89, 0xbf8a, + 0xbf8b, 0xbf8c, 0xbf8d, 0xbf8e, 0xbf8f, 0xbf90, 0xbf91, 0xbf92, + 0xbf93, 0xbf94, 0xbf95, 0xbf96, 0xbf97, 0xbf98, 0xbf99, 0xbf9a, + 0xbf9b, 0xbf9c, 0xbf9d, 0xbf9e, 0xbf9f, 0xbfa0, 0xc040, 0xc041, + 0xc042, 0xc043, 0xc044, 0xc045, 0xc046, 0xc047, 0xc048, 0xc049, + 0xc04a, 0xc04b, 0xc04c, 0xc04d, 0xc04e, 0xc04f, 0xc050, 0xc051, + 0xc052, 0xc053, 0xc054, 0xc055, 0xc056, 0xc057, 0xc058, 0xc059, + 0xc05a, 0xc05b, 0xc05c, 0xc05d, 0xc05e, 0xc05f, 0xc060, 0xc061, + 0xc062, 0xc063, 0xc064, 0xc065, 0xc066, 0xc067, 0xc068, 0xc069, + 0xc06a, 0xc06b, 0xc06c, 0xc06d, 0xc06e, 0xc06f, 0xc070, 0xc071, + 0xc072, 0xc073, 0xc074, 0xc075, 0xc076, 0xc077, 0xc078, 0xc079, + 0xc07a, 0xc07b, 0xc07c, 0xc07d, 0xc07e, 0xc080, 0xc081, 0xc082, + 0xc083, 0xc084, 0xc085, 0xc086, 0xc087, 0xc088, 0xc089, 0xc08a, + 0xc08b, 0xc08c, 0xc08d, 0xc08e, 0xc08f, 0xc090, 0xc091, 0xc092, + 0xc093, 0xc094, 0xc095, 0xc096, 0xc097, 0xc098, 0xc099, 0xc09a, + 0xc09b, 0xc09c, 0xc09d, 0xc09e, 0xc09f, 0xc0a0, 0xc140, 0xc141, + 0xc142, 0xc143, 0xc144, 0xc145, 0xc146, 0xc147, 0xc148, 0xc149, + 0xc14a, 0xc14b, 0xc14c, 0xc14d, 0xc14e, 0xc14f, 0xc150, 0xc151, + 0xc152, 0xc153, 0xc154, 0xc155, 0xc156, 0xc157, 0xc158, 0xc159, + 0xc15a, 0xc15b, 0xc15c, 0xc15d, 0xc15e, 0xc15f, 0xc160, 0xc161, + 0xc162, 0xc163, 0xc164, 0xc165, 0xc166, 0xc167, 0xc168, 0xc169, + 0xc16a, 0xc16b, 0xc16c, 0xc16d, 0xc16e, 0xc16f, 0xc170, 0xc171, + 0xc172, 0xc173, 0xc174, 0xc175, 0xc176, 0xc177, 0xc178, 0xc179, + 0xc17a, 0xc17b, 0xc17c, 0xc17d, 0xc17e, 0xc180, 0xc181, 0xc182, + 0xc183, 0xc184, 0xc185, 0xc186, 0xc187, 0xc188, 0xc189, 0xc18a, + 0xc18b, 0xc18c, 0xc18d, 0xc18e, 0xc18f, 0xc190, 0xc191, 0xc192, + 0xc193, 0xc194, 0xc195, 0xc196, 0xc197, 0xc198, 0xc199, 0xc19a, + 0xc19b, 0xc19c, 0xc19d, 0xc19e, 0xc19f, 0xc1a0, 0xc240, 0xc241, + 0xc242, 0xc243, 0xc244, 0xc245, 0xc246, 0xc247, 0xc248, 0xc249, + 0xc24a, 0xc24b, 0xc24c, 0xc24d, 0xc24e, 0xc24f, 0xc250, 0xc251, + 0xc252, 0xc253, 0xc254, 0xc255, 0xc256, 0xc257, 0xc258, 0xc259, + 0xc25a, 0xc25b, 0xc25c, 0xc25d, 0xc25e, 0xc25f, 0xc260, 0xc261, + 0xc262, 0xc263, 0xc264, 0xc265, 0xc266, 0xc267, 0xc268, 0xc269, + 0xc26a, 0xc26b, 0xc26c, 0xc26d, 0xc26e, 0xc26f, 0xc270, 0xc271, + 0xc272, 0xc273, 0xc274, 0xc275, 0xc276, 0xc277, 0xc278, 0xc279, + 0xc27a, 0xc27b, 0xc27c, 0xc27d, 0xc27e, 0xc280, 0xc281, 0xc282, + 0xc283, 0xc284, 0xc285, 0xc286, 0xc287, 0xc288, 0xc289, 0xc28a, + 0xc28b, 0xc28c, 0xc28d, 0xc28e, 0xc28f, 0xc290, 0xc291, 0xc292, + 0xc293, 0xc294, 0xc295, 0xc296, 0xc297, 0xc298, 0xc299, 0xc29a, + 0xc29b, 0xc29c, 0xc29d, 0xc29e, 0xc29f, 0xc2a0, 0xc340, 0xc341, + 0xc342, 0xc343, 0xc344, 0xc345, 0xc346, 0xc347, 0xc348, 0xc349, + 0xc34a, 0xc34b, 0xc34c, 0xc34d, 0xc34e, 0xc34f, 0xc350, 0xc351, + 0xc352, 0xc353, 0xc354, 0xc355, 0xc356, 0xc357, 0xc358, 0xc359, + 0xc35a, 0xc35b, 0xc35c, 0xc35d, 0xc35e, 0xc35f, 0xc360, 0xc361, + 0xc362, 0xc363, 0xc364, 0xc365, 0xc366, 0xc367, 0xc368, 0xc369, + 0xc36a, 0xc36b, 0xc36c, 0xc36d, 0xc36e, 0xc36f, 0xc370, 0xc371, + 0xc372, 0xc373, 0xc374, 0xc375, 0xc376, 0xc377, 0xc378, 0xc379, + 0xc37a, 0xc37b, 0xc37c, 0xc37d, 0xc37e, 0xc380, 0xc381, 0xc382, + 0xc383, 0xc384, 0xc385, 0xc386, 0xc387, 0xc388, 0xc389, 0xc38a, + 0xc38b, 0xc38c, 0xc38d, 0xc38e, 0xc38f, 0xc390, 0xc391, 0xc392, + 0xc393, 0xc394, 0xc395, 0xc396, 0xc397, 0xc398, 0xc399, 0xc39a, + 0xc39b, 0xc39c, 0xc39d, 0xc39e, 0xc39f, 0xc3a0, 0xc440, 0xc441, + 0xc442, 0xc443, 0xc444, 0xc445, 0xc446, 0xc447, 0xc448, 0xc449, + 0xc44a, 0xc44b, 0xc44c, 0xc44d, 0xc44e, 0xc44f, 0xc450, 0xc451, + 0xc452, 0xc453, 0xc454, 0xc455, 0xc456, 0xc457, 0xc458, 0xc459, + 0xc45a, 0xc45b, 0xc45c, 0xc45d, 0xc45e, 0xc45f, 0xc460, 0xc461, + 0xc462, 0xc463, 0xc464, 0xc465, 0xc466, 0xc467, 0xc468, 0xc469, + 0xc46a, 0xc46b, 0xc46c, 0xc46d, 0xc46e, 0xc46f, 0xc470, 0xc471, + 0xc472, 0xc473, 0xc474, 0xc475, 0xc476, 0xc477, 0xc478, 0xc479, + 0xc47a, 0xc47b, 0xc47c, 0xc47d, 0xc47e, 0xc480, 0xc481, 0xc482, + 0xc483, 0xc484, 0xc485, 0xc486, 0xc487, 0xc488, 0xc489, 0xc48a, + 0xc48b, 0xc48c, 0xc48d, 0xc48e, 0xc48f, 0xc490, 0xc491, 0xc492, + 0xc493, 0xc494, 0xc495, 0xc496, 0xc497, 0xc498, 0xc499, 0xc49a, + 0xc49b, 0xc49c, 0xc49d, 0xc49e, 0xc49f, 0xc4a0, 0xc540, 0xc541, + 0xc542, 0xc543, 0xc544, 0xc545, 0xc546, 0xc547, 0xc548, 0xc549, + 0xc54a, 0xc54b, 0xc54c, 0xc54d, 0xc54e, 0xc54f, 0xc550, 0xc551, + 0xc552, 0xc553, 0xc554, 0xc555, 0xc556, 0xc557, 0xc558, 0xc559, + 0xc55a, 0xc55b, 0xc55c, 0xc55d, 0xc55e, 0xc55f, 0xc560, 0xc561, + 0xc562, 0xc563, 0xc564, 0xc565, 0xc566, 0xc567, 0xc568, 0xc569, + 0xc56a, 0xc56b, 0xc56c, 0xc56d, 0xc56e, 0xc56f, 0xc570, 0xc571, + 0xc572, 0xc573, 0xc574, 0xc575, 0xc576, 0xc577, 0xc578, 0xc579, + 0xc57a, 0xc57b, 0xc57c, 0xc57d, 0xc57e, 0xc580, 0xc581, 0xc582, + 0xc583, 0xc584, 0xc585, 0xc586, 0xc587, 0xc588, 0xc589, 0xc58a, + 0xc58b, 0xc58c, 0xc58d, 0xc58e, 0xc58f, 0xc590, 0xc591, 0xc592, + 0xc593, 0xc594, 0xc595, 0xc596, 0xc597, 0xc598, 0xc599, 0xc59a, + 0xc59b, 0xc59c, 0xc59d, 0xc59e, 0xc59f, 0xc5a0, 0xc640, 0xc641, + 0xc642, 0xc643, 0xc644, 0xc645, 0xc646, 0xc647, 0xc648, 0xc649, + 0xc64a, 0xc64b, 0xc64c, 0xc64d, 0xc64e, 0xc64f, 0xc650, 0xc651, + 0xc652, 0xc653, 0xc654, 0xc655, 0xc656, 0xc657, 0xc658, 0xc659, + 0xc65a, 0xc65b, 0xc65c, 0xc65d, 0xc65e, 0xc65f, 0xc660, 0xc661, + 0xc662, 0xc663, 0xc664, 0xc665, 0xc666, 0xc667, 0xc668, 0xc669, + 0xc66a, 0xc66b, 0xc66c, 0xc66d, 0xc66e, 0xc66f, 0xc670, 0xc671, + 0xc672, 0xc673, 0xc674, 0xc675, 0xc676, 0xc677, 0xc678, 0xc679, + 0xc67a, 0xc67b, 0xc67c, 0xc67d, 0xc67e, 0xc680, 0xc681, 0xc682, + 0xc683, 0xc684, 0xc685, 0xc686, 0xc687, 0xc688, 0xc689, 0xc68a, + 0xc68b, 0xc68c, 0xc68d, 0xc68e, 0xc68f, 0xc690, 0xc691, 0xc692, + 0xc693, 0xc694, 0xc695, 0xc696, 0xc697, 0xc698, 0xc699, 0xc69a, + 0xc69b, 0xc69c, 0xc69d, 0xc69e, 0xc69f, 0xc6a0, 0xc740, 0xc741, + 0xc742, 0xc743, 0xc744, 0xc745, 0xc746, 0xc747, 0xc748, 0xc749, + 0xc74a, 0xc74b, 0xc74c, 0xc74d, 0xc74e, 0xc74f, 0xc750, 0xc751, + 0xc752, 0xc753, 0xc754, 0xc755, 0xc756, 0xc757, 0xc758, 0xc759, + 0xc75a, 0xc75b, 0xc75c, 0xc75d, 0xc75e, 0xc75f, 0xc760, 0xc761, + 0xc762, 0xc763, 0xc764, 0xc765, 0xc766, 0xc767, 0xc768, 0xc769, + 0xc76a, 0xc76b, 0xc76c, 0xc76d, 0xc76e, 0xc76f, 0xc770, 0xc771, + 0xc772, 0xc773, 0xc774, 0xc775, 0xc776, 0xc777, 0xc778, 0xc779, + 0xc77a, 0xc77b, 0xc77c, 0xc77d, 0xc77e, 0xc780, 0xc781, 0xc782, + 0xc783, 0xc784, 0xc785, 0xc786, 0xc787, 0xc788, 0xc789, 0xc78a, + 0xc78b, 0xc78c, 0xc78d, 0xc78e, 0xc78f, 0xc790, 0xc791, 0xc792, + 0xc793, 0xc794, 0xc795, 0xc796, 0xc797, 0xc798, 0xc799, 0xc79a, + 0xc79b, 0xc79c, 0xc79d, 0xc79e, 0xc79f, 0xc7a0, 0xc840, 0xc841, + 0xc842, 0xc843, 0xc844, 0xc845, 0xc846, 0xc847, 0xc848, 0xc849, + 0xc84a, 0xc84b, 0xc84c, 0xc84d, 0xc84e, 0xc84f, 0xc850, 0xc851, + 0xc852, 0xc853, 0xc854, 0xc855, 0xc856, 0xc857, 0xc858, 0xc859, + 0xc85a, 0xc85b, 0xc85c, 0xc85d, 0xc85e, 0xc85f, 0xc860, 0xc861, + 0xc862, 0xc863, 0xc864, 0xc865, 0xc866, 0xc867, 0xc868, 0xc869, + 0xc86a, 0xc86b, 0xc86c, 0xc86d, 0xc86e, 0xc86f, 0xc870, 0xc871, + 0xc872, 0xc873, 0xc874, 0xc875, 0xc876, 0xc877, 0xc878, 0xc879, + 0xc87a, 0xc87b, 0xc87c, 0xc87d, 0xc87e, 0xc880, 0xc881, 0xc882, + 0xc883, 0xc884, 0xc885, 0xc886, 0xc887, 0xc888, 0xc889, 0xc88a, + 0xc88b, 0xc88c, 0xc88d, 0xc88e, 0xc88f, 0xc890, 0xc891, 0xc892, + 0xc893, 0xc894, 0xc895, 0xc896, 0xc897, 0xc898, 0xc899, 0xc89a, + 0xc89b, 0xc89c, 0xc89d, 0xc89e, 0xc89f, 0xc8a0, 0xc940, 0xc941, + 0xc942, 0xc943, 0xc944, 0xc945, 0xc946, 0xc947, 0xc948, 0xc949, + 0xc94a, 0xc94b, 0xc94c, 0xc94d, 0xc94e, 0xc94f, 0xc950, 0xc951, + 0xc952, 0xc953, 0xc954, 0xc955, 0xc956, 0xc957, 0xc958, 0xc959, + 0xc95a, 0xc95b, 0xc95c, 0xc95d, 0xc95e, 0xc95f, 0xc960, 0xc961, + 0xc962, 0xc963, 0xc964, 0xc965, 0xc966, 0xc967, 0xc968, 0xc969, + 0xc96a, 0xc96b, 0xc96c, 0xc96d, 0xc96e, 0xc96f, 0xc970, 0xc971, + 0xc972, 0xc973, 0xc974, 0xc975, 0xc976, 0xc977, 0xc978, 0xc979, + 0xc97a, 0xc97b, 0xc97c, 0xc97d, 0xc97e, 0xc980, 0xc981, 0xc982, + 0xc983, 0xc984, 0xc985, 0xc986, 0xc987, 0xc988, 0xc989, 0xc98a, + 0xc98b, 0xc98c, 0xc98d, 0xc98e, 0xc98f, 0xc990, 0xc991, 0xc992, + 0xc993, 0xc994, 0xc995, 0xc996, 0xc997, 0xc998, 0xc999, 0xc99a, + 0xc99b, 0xc99c, 0xc99d, 0xc99e, 0xc99f, 0xc9a0, 0xca40, 0xca41, + 0xca42, 0xca43, 0xca44, 0xca45, 0xca46, 0xca47, 0xca48, 0xca49, + 0xca4a, 0xca4b, 0xca4c, 0xca4d, 0xca4e, 0xca4f, 0xca50, 0xca51, + 0xca52, 0xca53, 0xca54, 0xca55, 0xca56, 0xca57, 0xca58, 0xca59, + 0xca5a, 0xca5b, 0xca5c, 0xca5d, 0xca5e, 0xca5f, 0xca60, 0xca61, + 0xca62, 0xca63, 0xca64, 0xca65, 0xca66, 0xca67, 0xca68, 0xca69, + 0xca6a, 0xca6b, 0xca6c, 0xca6d, 0xca6e, 0xca6f, 0xca70, 0xca71, + 0xca72, 0xca73, 0xca74, 0xca75, 0xca76, 0xca77, 0xca78, 0xca79, + 0xca7a, 0xca7b, 0xca7c, 0xca7d, 0xca7e, 0xca80, 0xca81, 0xca82, + 0xca83, 0xca84, 0xca85, 0xca86, 0xca87, 0xca88, 0xca89, 0xca8a, + 0xca8b, 0xca8c, 0xca8d, 0xca8e, 0xca8f, 0xca90, 0xca91, 0xca92, + 0xca93, 0xca94, 0xca95, 0xca96, 0xca97, 0xca98, 0xca99, 0xca9a, + 0xca9b, 0xca9c, 0xca9d, 0xca9e, 0xca9f, 0xcaa0, 0xcb40, 0xcb41, + 0xcb42, 0xcb43, 0xcb44, 0xcb45, 0xcb46, 0xcb47, 0xcb48, 0xcb49, + 0xcb4a, 0xcb4b, 0xcb4c, 0xcb4d, 0xcb4e, 0xcb4f, 0xcb50, 0xcb51, + 0xcb52, 0xcb53, 0xcb54, 0xcb55, 0xcb56, 0xcb57, 0xcb58, 0xcb59, + 0xcb5a, 0xcb5b, 0xcb5c, 0xcb5d, 0xcb5e, 0xcb5f, 0xcb60, 0xcb61, + 0xcb62, 0xcb63, 0xcb64, 0xcb65, 0xcb66, 0xcb67, 0xcb68, 0xcb69, + 0xcb6a, 0xcb6b, 0xcb6c, 0xcb6d, 0xcb6e, 0xcb6f, 0xcb70, 0xcb71, + 0xcb72, 0xcb73, 0xcb74, 0xcb75, 0xcb76, 0xcb77, 0xcb78, 0xcb79, + 0xcb7a, 0xcb7b, 0xcb7c, 0xcb7d, 0xcb7e, 0xcb80, 0xcb81, 0xcb82, + 0xcb83, 0xcb84, 0xcb85, 0xcb86, 0xcb87, 0xcb88, 0xcb89, 0xcb8a, + 0xcb8b, 0xcb8c, 0xcb8d, 0xcb8e, 0xcb8f, 0xcb90, 0xcb91, 0xcb92, + 0xcb93, 0xcb94, 0xcb95, 0xcb96, 0xcb97, 0xcb98, 0xcb99, 0xcb9a, + 0xcb9b, 0xcb9c, 0xcb9d, 0xcb9e, 0xcb9f, 0xcba0, 0xcc40, 0xcc41, + 0xcc42, 0xcc43, 0xcc44, 0xcc45, 0xcc46, 0xcc47, 0xcc48, 0xcc49, + 0xcc4a, 0xcc4b, 0xcc4c, 0xcc4d, 0xcc4e, 0xcc4f, 0xcc50, 0xcc51, + 0xcc52, 0xcc53, 0xcc54, 0xcc55, 0xcc56, 0xcc57, 0xcc58, 0xcc59, + 0xcc5a, 0xcc5b, 0xcc5c, 0xcc5d, 0xcc5e, 0xcc5f, 0xcc60, 0xcc61, + 0xcc62, 0xcc63, 0xcc64, 0xcc65, 0xcc66, 0xcc67, 0xcc68, 0xcc69, + 0xcc6a, 0xcc6b, 0xcc6c, 0xcc6d, 0xcc6e, 0xcc6f, 0xcc70, 0xcc71, + 0xcc72, 0xcc73, 0xcc74, 0xcc75, 0xcc76, 0xcc77, 0xcc78, 0xcc79, + 0xcc7a, 0xcc7b, 0xcc7c, 0xcc7d, 0xcc7e, 0xcc80, 0xcc81, 0xcc82, + 0xcc83, 0xcc84, 0xcc85, 0xcc86, 0xcc87, 0xcc88, 0xcc89, 0xcc8a, + 0xcc8b, 0xcc8c, 0xcc8d, 0xcc8e, 0xcc8f, 0xcc90, 0xcc91, 0xcc92, + 0xcc93, 0xcc94, 0xcc95, 0xcc96, 0xcc97, 0xcc98, 0xcc99, 0xcc9a, + 0xcc9b, 0xcc9c, 0xcc9d, 0xcc9e, 0xcc9f, 0xcca0, 0xcd40, 0xcd41, + 0xcd42, 0xcd43, 0xcd44, 0xcd45, 0xcd46, 0xcd47, 0xcd48, 0xcd49, + 0xcd4a, 0xcd4b, 0xcd4c, 0xcd4d, 0xcd4e, 0xcd4f, 0xcd50, 0xcd51, + 0xcd52, 0xcd53, 0xcd54, 0xcd55, 0xcd56, 0xcd57, 0xcd58, 0xcd59, + 0xcd5a, 0xcd5b, 0xcd5c, 0xcd5d, 0xcd5e, 0xcd5f, 0xcd60, 0xcd61, + 0xcd62, 0xcd63, 0xcd64, 0xcd65, 0xcd66, 0xcd67, 0xcd68, 0xcd69, + 0xcd6a, 0xcd6b, 0xcd6c, 0xcd6d, 0xcd6e, 0xcd6f, 0xcd70, 0xcd71, + 0xcd72, 0xcd73, 0xcd74, 0xcd75, 0xcd76, 0xcd77, 0xcd78, 0xcd79, + 0xcd7a, 0xcd7b, 0xcd7c, 0xcd7d, 0xcd7e, 0xcd80, 0xcd81, 0xcd82, + 0xcd83, 0xcd84, 0xcd85, 0xcd86, 0xcd87, 0xcd88, 0xcd89, 0xcd8a, + 0xcd8b, 0xcd8c, 0xcd8d, 0xcd8e, 0xcd8f, 0xcd90, 0xcd91, 0xcd92, + 0xcd93, 0xcd94, 0xcd95, 0xcd96, 0xcd97, 0xcd98, 0xcd99, 0xcd9a, + 0xcd9b, 0xcd9c, 0xcd9d, 0xcd9e, 0xcd9f, 0xcda0, 0xce40, 0xce41, + 0xce42, 0xce43, 0xce44, 0xce45, 0xce46, 0xce47, 0xce48, 0xce49, + 0xce4a, 0xce4b, 0xce4c, 0xce4d, 0xce4e, 0xce4f, 0xce50, 0xce51, + 0xce52, 0xce53, 0xce54, 0xce55, 0xce56, 0xce57, 0xce58, 0xce59, + 0xce5a, 0xce5b, 0xce5c, 0xce5d, 0xce5e, 0xce5f, 0xce60, 0xce61, + 0xce62, 0xce63, 0xce64, 0xce65, 0xce66, 0xce67, 0xce68, 0xce69, + 0xce6a, 0xce6b, 0xce6c, 0xce6d, 0xce6e, 0xce6f, 0xce70, 0xce71, + 0xce72, 0xce73, 0xce74, 0xce75, 0xce76, 0xce77, 0xce78, 0xce79, + 0xce7a, 0xce7b, 0xce7c, 0xce7d, 0xce7e, 0xce80, 0xce81, 0xce82, + 0xce83, 0xce84, 0xce85, 0xce86, 0xce87, 0xce88, 0xce89, 0xce8a, + 0xce8b, 0xce8c, 0xce8d, 0xce8e, 0xce8f, 0xce90, 0xce91, 0xce92, + 0xce93, 0xce94, 0xce95, 0xce96, 0xce97, 0xce98, 0xce99, 0xce9a, + 0xce9b, 0xce9c, 0xce9d, 0xce9e, 0xce9f, 0xcea0, 0xcf40, 0xcf41, + 0xcf42, 0xcf43, 0xcf44, 0xcf45, 0xcf46, 0xcf47, 0xcf48, 0xcf49, + 0xcf4a, 0xcf4b, 0xcf4c, 0xcf4d, 0xcf4e, 0xcf4f, 0xcf50, 0xcf51, + 0xcf52, 0xcf53, 0xcf54, 0xcf55, 0xcf56, 0xcf57, 0xcf58, 0xcf59, + 0xcf5a, 0xcf5b, 0xcf5c, 0xcf5d, 0xcf5e, 0xcf5f, 0xcf60, 0xcf61, + 0xcf62, 0xcf63, 0xcf64, 0xcf65, 0xcf66, 0xcf67, 0xcf68, 0xcf69, + 0xcf6a, 0xcf6b, 0xcf6c, 0xcf6d, 0xcf6e, 0xcf6f, 0xcf70, 0xcf71, + 0xcf72, 0xcf73, 0xcf74, 0xcf75, 0xcf76, 0xcf77, 0xcf78, 0xcf79, + 0xcf7a, 0xcf7b, 0xcf7c, 0xcf7d, 0xcf7e, 0xcf80, 0xcf81, 0xcf82, + 0xcf83, 0xcf84, 0xcf85, 0xcf86, 0xcf87, 0xcf88, 0xcf89, 0xcf8a, + 0xcf8b, 0xcf8c, 0xcf8d, 0xcf8e, 0xcf8f, 0xcf90, 0xcf91, 0xcf92, + 0xcf93, 0xcf94, 0xcf95, 0xcf96, 0xcf97, 0xcf98, 0xcf99, 0xcf9a, + 0xcf9b, 0xcf9c, 0xcf9d, 0xcf9e, 0xcf9f, 0xcfa0, 0xd040, 0xd041, + 0xd042, 0xd043, 0xd044, 0xd045, 0xd046, 0xd047, 0xd048, 0xd049, + 0xd04a, 0xd04b, 0xd04c, 0xd04d, 0xd04e, 0xd04f, 0xd050, 0xd051, + 0xd052, 0xd053, 0xd054, 0xd055, 0xd056, 0xd057, 0xd058, 0xd059, + 0xd05a, 0xd05b, 0xd05c, 0xd05d, 0xd05e, 0xd05f, 0xd060, 0xd061, + 0xd062, 0xd063, 0xd064, 0xd065, 0xd066, 0xd067, 0xd068, 0xd069, + 0xd06a, 0xd06b, 0xd06c, 0xd06d, 0xd06e, 0xd06f, 0xd070, 0xd071, + 0xd072, 0xd073, 0xd074, 0xd075, 0xd076, 0xd077, 0xd078, 0xd079, + 0xd07a, 0xd07b, 0xd07c, 0xd07d, 0xd07e, 0xd080, 0xd081, 0xd082, + 0xd083, 0xd084, 0xd085, 0xd086, 0xd087, 0xd088, 0xd089, 0xd08a, + 0xd08b, 0xd08c, 0xd08d, 0xd08e, 0xd08f, 0xd090, 0xd091, 0xd092, + 0xd093, 0xd094, 0xd095, 0xd096, 0xd097, 0xd098, 0xd099, 0xd09a, + 0xd09b, 0xd09c, 0xd09d, 0xd09e, 0xd09f, 0xd0a0, 0xd140, 0xd141, + 0xd142, 0xd143, 0xd144, 0xd145, 0xd146, 0xd147, 0xd148, 0xd149, + 0xd14a, 0xd14b, 0xd14c, 0xd14d, 0xd14e, 0xd14f, 0xd150, 0xd151, + 0xd152, 0xd153, 0xd154, 0xd155, 0xd156, 0xd157, 0xd158, 0xd159, + 0xd15a, 0xd15b, 0xd15c, 0xd15d, 0xd15e, 0xd15f, 0xd160, 0xd161, + 0xd162, 0xd163, 0xd164, 0xd165, 0xd166, 0xd167, 0xd168, 0xd169, + 0xd16a, 0xd16b, 0xd16c, 0xd16d, 0xd16e, 0xd16f, 0xd170, 0xd171, + 0xd172, 0xd173, 0xd174, 0xd175, 0xd176, 0xd177, 0xd178, 0xd179, + 0xd17a, 0xd17b, 0xd17c, 0xd17d, 0xd17e, 0xd180, 0xd181, 0xd182, + 0xd183, 0xd184, 0xd185, 0xd186, 0xd187, 0xd188, 0xd189, 0xd18a, + 0xd18b, 0xd18c, 0xd18d, 0xd18e, 0xd18f, 0xd190, 0xd191, 0xd192, + 0xd193, 0xd194, 0xd195, 0xd196, 0xd197, 0xd198, 0xd199, 0xd19a, + 0xd19b, 0xd19c, 0xd19d, 0xd19e, 0xd19f, 0xd1a0, 0xd240, 0xd241, + 0xd242, 0xd243, 0xd244, 0xd245, 0xd246, 0xd247, 0xd248, 0xd249, + 0xd24a, 0xd24b, 0xd24c, 0xd24d, 0xd24e, 0xd24f, 0xd250, 0xd251, + 0xd252, 0xd253, 0xd254, 0xd255, 0xd256, 0xd257, 0xd258, 0xd259, + 0xd25a, 0xd25b, 0xd25c, 0xd25d, 0xd25e, 0xd25f, 0xd260, 0xd261, + 0xd262, 0xd263, 0xd264, 0xd265, 0xd266, 0xd267, 0xd268, 0xd269, + 0xd26a, 0xd26b, 0xd26c, 0xd26d, 0xd26e, 0xd26f, 0xd270, 0xd271, + 0xd272, 0xd273, 0xd274, 0xd275, 0xd276, 0xd277, 0xd278, 0xd279, + 0xd27a, 0xd27b, 0xd27c, 0xd27d, 0xd27e, 0xd280, 0xd281, 0xd282, + 0xd283, 0xd284, 0xd285, 0xd286, 0xd287, 0xd288, 0xd289, 0xd28a, + 0xd28b, 0xd28c, 0xd28d, 0xd28e, 0xd28f, 0xd290, 0xd291, 0xd292, + 0xd293, 0xd294, 0xd295, 0xd296, 0xd297, 0xd298, 0xd299, 0xd29a, + 0xd29b, 0xd29c, 0xd29d, 0xd29e, 0xd29f, 0xd2a0, 0xd340, 0xd341, + 0xd342, 0xd343, 0xd344, 0xd345, 0xd346, 0xd347, 0xd348, 0xd349, + 0xd34a, 0xd34b, 0xd34c, 0xd34d, 0xd34e, 0xd34f, 0xd350, 0xd351, + 0xd352, 0xd353, 0xd354, 0xd355, 0xd356, 0xd357, 0xd358, 0xd359, + 0xd35a, 0xd35b, 0xd35c, 0xd35d, 0xd35e, 0xd35f, 0xd360, 0xd361, + 0xd362, 0xd363, 0xd364, 0xd365, 0xd366, 0xd367, 0xd368, 0xd369, + 0xd36a, 0xd36b, 0xd36c, 0xd36d, 0xd36e, 0xd36f, 0xd370, 0xd371, + 0xd372, 0xd373, 0xd374, 0xd375, 0xd376, 0xd377, 0xd378, 0xd379, + 0xd37a, 0xd37b, 0xd37c, 0xd37d, 0xd37e, 0xd380, 0xd381, 0xd382, + 0xd383, 0xd384, 0xd385, 0xd386, 0xd387, 0xd388, 0xd389, 0xd38a, + 0xd38b, 0xd38c, 0xd38d, 0xd38e, 0xd38f, 0xd390, 0xd391, 0xd392, + 0xd393, 0xd394, 0xd395, 0xd396, 0xd397, 0xd398, 0xd399, 0xd39a, + 0xd39b, 0xd39c, 0xd39d, 0xd39e, 0xd39f, 0xd3a0, 0xd440, 0xd441, + 0xd442, 0xd443, 0xd444, 0xd445, 0xd446, 0xd447, 0xd448, 0xd449, + 0xd44a, 0xd44b, 0xd44c, 0xd44d, 0xd44e, 0xd44f, 0xd450, 0xd451, + 0xd452, 0xd453, 0xd454, 0xd455, 0xd456, 0xd457, 0xd458, 0xd459, + 0xd45a, 0xd45b, 0xd45c, 0xd45d, 0xd45e, 0xd45f, 0xd460, 0xd461, + 0xd462, 0xd463, 0xd464, 0xd465, 0xd466, 0xd467, 0xd468, 0xd469, + 0xd46a, 0xd46b, 0xd46c, 0xd46d, 0xd46e, 0xd46f, 0xd470, 0xd471, + 0xd472, 0xd473, 0xd474, 0xd475, 0xd476, 0xd477, 0xd478, 0xd479, + 0xd47a, 0xd47b, 0xd47c, 0xd47d, 0xd47e, 0xd480, 0xd481, 0xd482, + 0xd483, 0xd484, 0xd485, 0xd486, 0xd487, 0xd488, 0xd489, 0xd48a, + 0xd48b, 0xd48c, 0xd48d, 0xd48e, 0xd48f, 0xd490, 0xd491, 0xd492, + 0xd493, 0xd494, 0xd495, 0xd496, 0xd497, 0xd498, 0xd499, 0xd49a, + 0xd49b, 0xd49c, 0xd49d, 0xd49e, 0xd49f, 0xd4a0, 0xd540, 0xd541, + 0xd542, 0xd543, 0xd544, 0xd545, 0xd546, 0xd547, 0xd548, 0xd549, + 0xd54a, 0xd54b, 0xd54c, 0xd54d, 0xd54e, 0xd54f, 0xd550, 0xd551, + 0xd552, 0xd553, 0xd554, 0xd555, 0xd556, 0xd557, 0xd558, 0xd559, + 0xd55a, 0xd55b, 0xd55c, 0xd55d, 0xd55e, 0xd55f, 0xd560, 0xd561, + 0xd562, 0xd563, 0xd564, 0xd565, 0xd566, 0xd567, 0xd568, 0xd569, + 0xd56a, 0xd56b, 0xd56c, 0xd56d, 0xd56e, 0xd56f, 0xd570, 0xd571, + 0xd572, 0xd573, 0xd574, 0xd575, 0xd576, 0xd577, 0xd578, 0xd579, + 0xd57a, 0xd57b, 0xd57c, 0xd57d, 0xd57e, 0xd580, 0xd581, 0xd582, + 0xd583, 0xd584, 0xd585, 0xd586, 0xd587, 0xd588, 0xd589, 0xd58a, + 0xd58b, 0xd58c, 0xd58d, 0xd58e, 0xd58f, 0xd590, 0xd591, 0xd592, + 0xd593, 0xd594, 0xd595, 0xd596, 0xd597, 0xd598, 0xd599, 0xd59a, + 0xd59b, 0xd59c, 0xd59d, 0xd59e, 0xd59f, 0xd5a0, 0xd640, 0xd641, + 0xd642, 0xd643, 0xd644, 0xd645, 0xd646, 0xd647, 0xd648, 0xd649, + 0xd64a, 0xd64b, 0xd64c, 0xd64d, 0xd64e, 0xd64f, 0xd650, 0xd651, + 0xd652, 0xd653, 0xd654, 0xd655, 0xd656, 0xd657, 0xd658, 0xd659, + 0xd65a, 0xd65b, 0xd65c, 0xd65d, 0xd65e, 0xd65f, 0xd660, 0xd661, + 0xd662, 0xd663, 0xd664, 0xd665, 0xd666, 0xd667, 0xd668, 0xd669, + 0xd66a, 0xd66b, 0xd66c, 0xd66d, 0xd66e, 0xd66f, 0xd670, 0xd671, + 0xd672, 0xd673, 0xd674, 0xd675, 0xd676, 0xd677, 0xd678, 0xd679, + 0xd67a, 0xd67b, 0xd67c, 0xd67d, 0xd67e, 0xd680, 0xd681, 0xd682, + 0xd683, 0xd684, 0xd685, 0xd686, 0xd687, 0xd688, 0xd689, 0xd68a, + 0xd68b, 0xd68c, 0xd68d, 0xd68e, 0xd68f, 0xd690, 0xd691, 0xd692, + 0xd693, 0xd694, 0xd695, 0xd696, 0xd697, 0xd698, 0xd699, 0xd69a, + 0xd69b, 0xd69c, 0xd69d, 0xd69e, 0xd69f, 0xd6a0, 0xd740, 0xd741, + 0xd742, 0xd743, 0xd744, 0xd745, 0xd746, 0xd747, 0xd748, 0xd749, + 0xd74a, 0xd74b, 0xd74c, 0xd74d, 0xd74e, 0xd74f, 0xd750, 0xd751, + 0xd752, 0xd753, 0xd754, 0xd755, 0xd756, 0xd757, 0xd758, 0xd759, + 0xd75a, 0xd75b, 0xd75c, 0xd75d, 0xd75e, 0xd75f, 0xd760, 0xd761, + 0xd762, 0xd763, 0xd764, 0xd765, 0xd766, 0xd767, 0xd768, 0xd769, + 0xd76a, 0xd76b, 0xd76c, 0xd76d, 0xd76e, 0xd76f, 0xd770, 0xd771, + 0xd772, 0xd773, 0xd774, 0xd775, 0xd776, 0xd777, 0xd778, 0xd779, + 0xd77a, 0xd77b, 0xd77c, 0xd77d, 0xd77e, 0xd780, 0xd781, 0xd782, + 0xd783, 0xd784, 0xd785, 0xd786, 0xd787, 0xd788, 0xd789, 0xd78a, + 0xd78b, 0xd78c, 0xd78d, 0xd78e, 0xd78f, 0xd790, 0xd791, 0xd792, + 0xd793, 0xd794, 0xd795, 0xd796, 0xd797, 0xd798, 0xd799, 0xd79a, + 0xd79b, 0xd79c, 0xd79d, 0xd79e, 0xd79f, 0xd7a0, 0xd840, 0xd841, + 0xd842, 0xd843, 0xd844, 0xd845, 0xd846, 0xd847, 0xd848, 0xd849, + 0xd84a, 0xd84b, 0xd84c, 0xd84d, 0xd84e, 0xd84f, 0xd850, 0xd851, + 0xd852, 0xd853, 0xd854, 0xd855, 0xd856, 0xd857, 0xd858, 0xd859, + 0xd85a, 0xd85b, 0xd85c, 0xd85d, 0xd85e, 0xd85f, 0xd860, 0xd861, + 0xd862, 0xd863, 0xd864, 0xd865, 0xd866, 0xd867, 0xd868, 0xd869, + 0xd86a, 0xd86b, 0xd86c, 0xd86d, 0xd86e, 0xd86f, 0xd870, 0xd871, + 0xd872, 0xd873, 0xd874, 0xd875, 0xd876, 0xd877, 0xd878, 0xd879, + 0xd87a, 0xd87b, 0xd87c, 0xd87d, 0xd87e, 0xd880, 0xd881, 0xd882, + 0xd883, 0xd884, 0xd885, 0xd886, 0xd887, 0xd888, 0xd889, 0xd88a, + 0xd88b, 0xd88c, 0xd88d, 0xd88e, 0xd88f, 0xd890, 0xd891, 0xd892, + 0xd893, 0xd894, 0xd895, 0xd896, 0xd897, 0xd898, 0xd899, 0xd89a, + 0xd89b, 0xd89c, 0xd89d, 0xd89e, 0xd89f, 0xd8a0, 0xd940, 0xd941, + 0xd942, 0xd943, 0xd944, 0xd945, 0xd946, 0xd947, 0xd948, 0xd949, + 0xd94a, 0xd94b, 0xd94c, 0xd94d, 0xd94e, 0xd94f, 0xd950, 0xd951, + 0xd952, 0xd953, 0xd954, 0xd955, 0xd956, 0xd957, 0xd958, 0xd959, + 0xd95a, 0xd95b, 0xd95c, 0xd95d, 0xd95e, 0xd95f, 0xd960, 0xd961, + 0xd962, 0xd963, 0xd964, 0xd965, 0xd966, 0xd967, 0xd968, 0xd969, + 0xd96a, 0xd96b, 0xd96c, 0xd96d, 0xd96e, 0xd96f, 0xd970, 0xd971, + 0xd972, 0xd973, 0xd974, 0xd975, 0xd976, 0xd977, 0xd978, 0xd979, + 0xd97a, 0xd97b, 0xd97c, 0xd97d, 0xd97e, 0xd980, 0xd981, 0xd982, + 0xd983, 0xd984, 0xd985, 0xd986, 0xd987, 0xd988, 0xd989, 0xd98a, + 0xd98b, 0xd98c, 0xd98d, 0xd98e, 0xd98f, 0xd990, 0xd991, 0xd992, + 0xd993, 0xd994, 0xd995, 0xd996, 0xd997, 0xd998, 0xd999, 0xd99a, + 0xd99b, 0xd99c, 0xd99d, 0xd99e, 0xd99f, 0xd9a0, 0xda40, 0xda41, + 0xda42, 0xda43, 0xda44, 0xda45, 0xda46, 0xda47, 0xda48, 0xda49, + 0xda4a, 0xda4b, 0xda4c, 0xda4d, 0xda4e, 0xda4f, 0xda50, 0xda51, + 0xda52, 0xda53, 0xda54, 0xda55, 0xda56, 0xda57, 0xda58, 0xda59, + 0xda5a, 0xda5b, 0xda5c, 0xda5d, 0xda5e, 0xda5f, 0xda60, 0xda61, + 0xda62, 0xda63, 0xda64, 0xda65, 0xda66, 0xda67, 0xda68, 0xda69, + 0xda6a, 0xda6b, 0xda6c, 0xda6d, 0xda6e, 0xda6f, 0xda70, 0xda71, + 0xda72, 0xda73, 0xda74, 0xda75, 0xda76, 0xda77, 0xda78, 0xda79, + 0xda7a, 0xda7b, 0xda7c, 0xda7d, 0xda7e, 0xda80, 0xda81, 0xda82, + 0xda83, 0xda84, 0xda85, 0xda86, 0xda87, 0xda88, 0xda89, 0xda8a, + 0xda8b, 0xda8c, 0xda8d, 0xda8e, 0xda8f, 0xda90, 0xda91, 0xda92, + 0xda93, 0xda94, 0xda95, 0xda96, 0xda97, 0xda98, 0xda99, 0xda9a, + 0xda9b, 0xda9c, 0xda9d, 0xda9e, 0xda9f, 0xdaa0, 0xdb40, 0xdb41, + 0xdb42, 0xdb43, 0xdb44, 0xdb45, 0xdb46, 0xdb47, 0xdb48, 0xdb49, + 0xdb4a, 0xdb4b, 0xdb4c, 0xdb4d, 0xdb4e, 0xdb4f, 0xdb50, 0xdb51, + 0xdb52, 0xdb53, 0xdb54, 0xdb55, 0xdb56, 0xdb57, 0xdb58, 0xdb59, + 0xdb5a, 0xdb5b, 0xdb5c, 0xdb5d, 0xdb5e, 0xdb5f, 0xdb60, 0xdb61, + 0xdb62, 0xdb63, 0xdb64, 0xdb65, 0xdb66, 0xdb67, 0xdb68, 0xdb69, + 0xdb6a, 0xdb6b, 0xdb6c, 0xdb6d, 0xdb6e, 0xdb6f, 0xdb70, 0xdb71, + 0xdb72, 0xdb73, 0xdb74, 0xdb75, 0xdb76, 0xdb77, 0xdb78, 0xdb79, + 0xdb7a, 0xdb7b, 0xdb7c, 0xdb7d, 0xdb7e, 0xdb80, 0xdb81, 0xdb82, + 0xdb83, 0xdb84, 0xdb85, 0xdb86, 0xdb87, 0xdb88, 0xdb89, 0xdb8a, + 0xdb8b, 0xdb8c, 0xdb8d, 0xdb8e, 0xdb8f, 0xdb90, 0xdb91, 0xdb92, + 0xdb93, 0xdb94, 0xdb95, 0xdb96, 0xdb97, 0xdb98, 0xdb99, 0xdb9a, + 0xdb9b, 0xdb9c, 0xdb9d, 0xdb9e, 0xdb9f, 0xdba0, 0xdc40, 0xdc41, + 0xdc42, 0xdc43, 0xdc44, 0xdc45, 0xdc46, 0xdc47, 0xdc48, 0xdc49, + 0xdc4a, 0xdc4b, 0xdc4c, 0xdc4d, 0xdc4e, 0xdc4f, 0xdc50, 0xdc51, + 0xdc52, 0xdc53, 0xdc54, 0xdc55, 0xdc56, 0xdc57, 0xdc58, 0xdc59, + 0xdc5a, 0xdc5b, 0xdc5c, 0xdc5d, 0xdc5e, 0xdc5f, 0xdc60, 0xdc61, + 0xdc62, 0xdc63, 0xdc64, 0xdc65, 0xdc66, 0xdc67, 0xdc68, 0xdc69, + 0xdc6a, 0xdc6b, 0xdc6c, 0xdc6d, 0xdc6e, 0xdc6f, 0xdc70, 0xdc71, + 0xdc72, 0xdc73, 0xdc74, 0xdc75, 0xdc76, 0xdc77, 0xdc78, 0xdc79, + 0xdc7a, 0xdc7b, 0xdc7c, 0xdc7d, 0xdc7e, 0xdc80, 0xdc81, 0xdc82, + 0xdc83, 0xdc84, 0xdc85, 0xdc86, 0xdc87, 0xdc88, 0xdc89, 0xdc8a, + 0xdc8b, 0xdc8c, 0xdc8d, 0xdc8e, 0xdc8f, 0xdc90, 0xdc91, 0xdc92, + 0xdc93, 0xdc94, 0xdc95, 0xdc96, 0xdc97, 0xdc98, 0xdc99, 0xdc9a, + 0xdc9b, 0xdc9c, 0xdc9d, 0xdc9e, 0xdc9f, 0xdca0, 0xdd40, 0xdd41, + 0xdd42, 0xdd43, 0xdd44, 0xdd45, 0xdd46, 0xdd47, 0xdd48, 0xdd49, + 0xdd4a, 0xdd4b, 0xdd4c, 0xdd4d, 0xdd4e, 0xdd4f, 0xdd50, 0xdd51, + 0xdd52, 0xdd53, 0xdd54, 0xdd55, 0xdd56, 0xdd57, 0xdd58, 0xdd59, + 0xdd5a, 0xdd5b, 0xdd5c, 0xdd5d, 0xdd5e, 0xdd5f, 0xdd60, 0xdd61, + 0xdd62, 0xdd63, 0xdd64, 0xdd65, 0xdd66, 0xdd67, 0xdd68, 0xdd69, + 0xdd6a, 0xdd6b, 0xdd6c, 0xdd6d, 0xdd6e, 0xdd6f, 0xdd70, 0xdd71, + 0xdd72, 0xdd73, 0xdd74, 0xdd75, 0xdd76, 0xdd77, 0xdd78, 0xdd79, + 0xdd7a, 0xdd7b, 0xdd7c, 0xdd7d, 0xdd7e, 0xdd80, 0xdd81, 0xdd82, + 0xdd83, 0xdd84, 0xdd85, 0xdd86, 0xdd87, 0xdd88, 0xdd89, 0xdd8a, + 0xdd8b, 0xdd8c, 0xdd8d, 0xdd8e, 0xdd8f, 0xdd90, 0xdd91, 0xdd92, + 0xdd93, 0xdd94, 0xdd95, 0xdd96, 0xdd97, 0xdd98, 0xdd99, 0xdd9a, + 0xdd9b, 0xdd9c, 0xdd9d, 0xdd9e, 0xdd9f, 0xdda0, 0xde40, 0xde41, + 0xde42, 0xde43, 0xde44, 0xde45, 0xde46, 0xde47, 0xde48, 0xde49, + 0xde4a, 0xde4b, 0xde4c, 0xde4d, 0xde4e, 0xde4f, 0xde50, 0xde51, + 0xde52, 0xde53, 0xde54, 0xde55, 0xde56, 0xde57, 0xde58, 0xde59, + 0xde5a, 0xde5b, 0xde5c, 0xde5d, 0xde5e, 0xde5f, 0xde60, 0xde61, + 0xde62, 0xde63, 0xde64, 0xde65, 0xde66, 0xde67, 0xde68, 0xde69, + 0xde6a, 0xde6b, 0xde6c, 0xde6d, 0xde6e, 0xde6f, 0xde70, 0xde71, + 0xde72, 0xde73, 0xde74, 0xde75, 0xde76, 0xde77, 0xde78, 0xde79, + 0xde7a, 0xde7b, 0xde7c, 0xde7d, 0xde7e, 0xde80, 0xde81, 0xde82, + 0xde83, 0xde84, 0xde85, 0xde86, 0xde87, 0xde88, 0xde89, 0xde8a, + 0xde8b, 0xde8c, 0xde8d, 0xde8e, 0xde8f, 0xde90, 0xde91, 0xde92, + 0xde93, 0xde94, 0xde95, 0xde96, 0xde97, 0xde98, 0xde99, 0xde9a, + 0xde9b, 0xde9c, 0xde9d, 0xde9e, 0xde9f, 0xdea0, 0xdf40, 0xdf41, + 0xdf42, 0xdf43, 0xdf44, 0xdf45, 0xdf46, 0xdf47, 0xdf48, 0xdf49, + 0xdf4a, 0xdf4b, 0xdf4c, 0xdf4d, 0xdf4e, 0xdf4f, 0xdf50, 0xdf51, + 0xdf52, 0xdf53, 0xdf54, 0xdf55, 0xdf56, 0xdf57, 0xdf58, 0xdf59, + 0xdf5a, 0xdf5b, 0xdf5c, 0xdf5d, 0xdf5e, 0xdf5f, 0xdf60, 0xdf61, + 0xdf62, 0xdf63, 0xdf64, 0xdf65, 0xdf66, 0xdf67, 0xdf68, 0xdf69, + 0xdf6a, 0xdf6b, 0xdf6c, 0xdf6d, 0xdf6e, 0xdf6f, 0xdf70, 0xdf71, + 0xdf72, 0xdf73, 0xdf74, 0xdf75, 0xdf76, 0xdf77, 0xdf78, 0xdf79, + 0xdf7a, 0xdf7b, 0xdf7c, 0xdf7d, 0xdf7e, 0xdf80, 0xdf81, 0xdf82, + 0xdf83, 0xdf84, 0xdf85, 0xdf86, 0xdf87, 0xdf88, 0xdf89, 0xdf8a, + 0xdf8b, 0xdf8c, 0xdf8d, 0xdf8e, 0xdf8f, 0xdf90, 0xdf91, 0xdf92, + 0xdf93, 0xdf94, 0xdf95, 0xdf96, 0xdf97, 0xdf98, 0xdf99, 0xdf9a, + 0xdf9b, 0xdf9c, 0xdf9d, 0xdf9e, 0xdf9f, 0xdfa0, 0xe040, 0xe041, + 0xe042, 0xe043, 0xe044, 0xe045, 0xe046, 0xe047, 0xe048, 0xe049, + 0xe04a, 0xe04b, 0xe04c, 0xe04d, 0xe04e, 0xe04f, 0xe050, 0xe051, + 0xe052, 0xe053, 0xe054, 0xe055, 0xe056, 0xe057, 0xe058, 0xe059, + 0xe05a, 0xe05b, 0xe05c, 0xe05d, 0xe05e, 0xe05f, 0xe060, 0xe061, + 0xe062, 0xe063, 0xe064, 0xe065, 0xe066, 0xe067, 0xe068, 0xe069, + 0xe06a, 0xe06b, 0xe06c, 0xe06d, 0xe06e, 0xe06f, 0xe070, 0xe071, + 0xe072, 0xe073, 0xe074, 0xe075, 0xe076, 0xe077, 0xe078, 0xe079, + 0xe07a, 0xe07b, 0xe07c, 0xe07d, 0xe07e, 0xe080, 0xe081, 0xe082, + 0xe083, 0xe084, 0xe085, 0xe086, 0xe087, 0xe088, 0xe089, 0xe08a, + 0xe08b, 0xe08c, 0xe08d, 0xe08e, 0xe08f, 0xe090, 0xe091, 0xe092, + 0xe093, 0xe094, 0xe095, 0xe096, 0xe097, 0xe098, 0xe099, 0xe09a, + 0xe09b, 0xe09c, 0xe09d, 0xe09e, 0xe09f, 0xe0a0, 0xe140, 0xe141, + 0xe142, 0xe143, 0xe144, 0xe145, 0xe146, 0xe147, 0xe148, 0xe149, + 0xe14a, 0xe14b, 0xe14c, 0xe14d, 0xe14e, 0xe14f, 0xe150, 0xe151, + 0xe152, 0xe153, 0xe154, 0xe155, 0xe156, 0xe157, 0xe158, 0xe159, + 0xe15a, 0xe15b, 0xe15c, 0xe15d, 0xe15e, 0xe15f, 0xe160, 0xe161, + 0xe162, 0xe163, 0xe164, 0xe165, 0xe166, 0xe167, 0xe168, 0xe169, + 0xe16a, 0xe16b, 0xe16c, 0xe16d, 0xe16e, 0xe16f, 0xe170, 0xe171, + 0xe172, 0xe173, 0xe174, 0xe175, 0xe176, 0xe177, 0xe178, 0xe179, + 0xe17a, 0xe17b, 0xe17c, 0xe17d, 0xe17e, 0xe180, 0xe181, 0xe182, + 0xe183, 0xe184, 0xe185, 0xe186, 0xe187, 0xe188, 0xe189, 0xe18a, + 0xe18b, 0xe18c, 0xe18d, 0xe18e, 0xe18f, 0xe190, 0xe191, 0xe192, + 0xe193, 0xe194, 0xe195, 0xe196, 0xe197, 0xe198, 0xe199, 0xe19a, + 0xe19b, 0xe19c, 0xe19d, 0xe19e, 0xe19f, 0xe1a0, 0xe240, 0xe241, + 0xe242, 0xe243, 0xe244, 0xe245, 0xe246, 0xe247, 0xe248, 0xe249, + 0xe24a, 0xe24b, 0xe24c, 0xe24d, 0xe24e, 0xe24f, 0xe250, 0xe251, + 0xe252, 0xe253, 0xe254, 0xe255, 0xe256, 0xe257, 0xe258, 0xe259, + 0xe25a, 0xe25b, 0xe25c, 0xe25d, 0xe25e, 0xe25f, 0xe260, 0xe261, + 0xe262, 0xe263, 0xe264, 0xe265, 0xe266, 0xe267, 0xe268, 0xe269, + 0xe26a, 0xe26b, 0xe26c, 0xe26d, 0xe26e, 0xe26f, 0xe270, 0xe271, + 0xe272, 0xe273, 0xe274, 0xe275, 0xe276, 0xe277, 0xe278, 0xe279, + 0xe27a, 0xe27b, 0xe27c, 0xe27d, 0xe27e, 0xe280, 0xe281, 0xe282, + 0xe283, 0xe284, 0xe285, 0xe286, 0xe287, 0xe288, 0xe289, 0xe28a, + 0xe28b, 0xe28c, 0xe28d, 0xe28e, 0xe28f, 0xe290, 0xe291, 0xe292, + 0xe293, 0xe294, 0xe295, 0xe296, 0xe297, 0xe298, 0xe299, 0xe29a, + 0xe29b, 0xe29c, 0xe29d, 0xe29e, 0xe29f, 0xe2a0, 0xe340, 0xe341, + 0xe342, 0xe343, 0xe344, 0xe345, 0xe346, 0xe347, 0xe348, 0xe349, + 0xe34a, 0xe34b, 0xe34c, 0xe34d, 0xe34e, 0xe34f, 0xe350, 0xe351, + 0xe352, 0xe353, 0xe354, 0xe355, 0xe356, 0xe357, 0xe358, 0xe359, + 0xe35a, 0xe35b, 0xe35c, 0xe35d, 0xe35e, 0xe35f, 0xe360, 0xe361, + 0xe362, 0xe363, 0xe364, 0xe365, 0xe366, 0xe367, 0xe368, 0xe369, + 0xe36a, 0xe36b, 0xe36c, 0xe36d, 0xe36e, 0xe36f, 0xe370, 0xe371, + 0xe372, 0xe373, 0xe374, 0xe375, 0xe376, 0xe377, 0xe378, 0xe379, + 0xe37a, 0xe37b, 0xe37c, 0xe37d, 0xe37e, 0xe380, 0xe381, 0xe382, + 0xe383, 0xe384, 0xe385, 0xe386, 0xe387, 0xe388, 0xe389, 0xe38a, + 0xe38b, 0xe38c, 0xe38d, 0xe38e, 0xe38f, 0xe390, 0xe391, 0xe392, + 0xe393, 0xe394, 0xe395, 0xe396, 0xe397, 0xe398, 0xe399, 0xe39a, + 0xe39b, 0xe39c, 0xe39d, 0xe39e, 0xe39f, 0xe3a0, 0xe440, 0xe441, + 0xe442, 0xe443, 0xe444, 0xe445, 0xe446, 0xe447, 0xe448, 0xe449, + 0xe44a, 0xe44b, 0xe44c, 0xe44d, 0xe44e, 0xe44f, 0xe450, 0xe451, + 0xe452, 0xe453, 0xe454, 0xe455, 0xe456, 0xe457, 0xe458, 0xe459, + 0xe45a, 0xe45b, 0xe45c, 0xe45d, 0xe45e, 0xe45f, 0xe460, 0xe461, + 0xe462, 0xe463, 0xe464, 0xe465, 0xe466, 0xe467, 0xe468, 0xe469, + 0xe46a, 0xe46b, 0xe46c, 0xe46d, 0xe46e, 0xe46f, 0xe470, 0xe471, + 0xe472, 0xe473, 0xe474, 0xe475, 0xe476, 0xe477, 0xe478, 0xe479, + 0xe47a, 0xe47b, 0xe47c, 0xe47d, 0xe47e, 0xe480, 0xe481, 0xe482, + 0xe483, 0xe484, 0xe485, 0xe486, 0xe487, 0xe488, 0xe489, 0xe48a, + 0xe48b, 0xe48c, 0xe48d, 0xe48e, 0xe48f, 0xe490, 0xe491, 0xe492, + 0xe493, 0xe494, 0xe495, 0xe496, 0xe497, 0xe498, 0xe499, 0xe49a, + 0xe49b, 0xe49c, 0xe49d, 0xe49e, 0xe49f, 0xe4a0, 0xe540, 0xe541, + 0xe542, 0xe543, 0xe544, 0xe545, 0xe546, 0xe547, 0xe548, 0xe549, + 0xe54a, 0xe54b, 0xe54c, 0xe54d, 0xe54e, 0xe54f, 0xe550, 0xe551, + 0xe552, 0xe553, 0xe554, 0xe555, 0xe556, 0xe557, 0xe558, 0xe559, + 0xe55a, 0xe55b, 0xe55c, 0xe55d, 0xe55e, 0xe55f, 0xe560, 0xe561, + 0xe562, 0xe563, 0xe564, 0xe565, 0xe566, 0xe567, 0xe568, 0xe569, + 0xe56a, 0xe56b, 0xe56c, 0xe56d, 0xe56e, 0xe56f, 0xe570, 0xe571, + 0xe572, 0xe573, 0xe574, 0xe575, 0xe576, 0xe577, 0xe578, 0xe579, + 0xe57a, 0xe57b, 0xe57c, 0xe57d, 0xe57e, 0xe580, 0xe581, 0xe582, + 0xe583, 0xe584, 0xe585, 0xe586, 0xe587, 0xe588, 0xe589, 0xe58a, + 0xe58b, 0xe58c, 0xe58d, 0xe58e, 0xe58f, 0xe590, 0xe591, 0xe592, + 0xe593, 0xe594, 0xe595, 0xe596, 0xe597, 0xe598, 0xe599, 0xe59a, + 0xe59b, 0xe59c, 0xe59d, 0xe59e, 0xe59f, 0xe5a0, 0xe640, 0xe641, + 0xe642, 0xe643, 0xe644, 0xe645, 0xe646, 0xe647, 0xe648, 0xe649, + 0xe64a, 0xe64b, 0xe64c, 0xe64d, 0xe64e, 0xe64f, 0xe650, 0xe651, + 0xe652, 0xe653, 0xe654, 0xe655, 0xe656, 0xe657, 0xe658, 0xe659, + 0xe65a, 0xe65b, 0xe65c, 0xe65d, 0xe65e, 0xe65f, 0xe660, 0xe661, + 0xe662, 0xe663, 0xe664, 0xe665, 0xe666, 0xe667, 0xe668, 0xe669, + 0xe66a, 0xe66b, 0xe66c, 0xe66d, 0xe66e, 0xe66f, 0xe670, 0xe671, + 0xe672, 0xe673, 0xe674, 0xe675, 0xe676, 0xe677, 0xe678, 0xe679, + 0xe67a, 0xe67b, 0xe67c, 0xe67d, 0xe67e, 0xe680, 0xe681, 0xe682, + 0xe683, 0xe684, 0xe685, 0xe686, 0xe687, 0xe688, 0xe689, 0xe68a, + 0xe68b, 0xe68c, 0xe68d, 0xe68e, 0xe68f, 0xe690, 0xe691, 0xe692, + 0xe693, 0xe694, 0xe695, 0xe696, 0xe697, 0xe698, 0xe699, 0xe69a, + 0xe69b, 0xe69c, 0xe69d, 0xe69e, 0xe69f, 0xe6a0, 0xe740, 0xe741, + 0xe742, 0xe743, 0xe744, 0xe745, 0xe746, 0xe747, 0xe748, 0xe749, + 0xe74a, 0xe74b, 0xe74c, 0xe74d, 0xe74e, 0xe74f, 0xe750, 0xe751, + 0xe752, 0xe753, 0xe754, 0xe755, 0xe756, 0xe757, 0xe758, 0xe759, + 0xe75a, 0xe75b, 0xe75c, 0xe75d, 0xe75e, 0xe75f, 0xe760, 0xe761, + 0xe762, 0xe763, 0xe764, 0xe765, 0xe766, 0xe767, 0xe768, 0xe769, + 0xe76a, 0xe76b, 0xe76c, 0xe76d, 0xe76e, 0xe76f, 0xe770, 0xe771, + 0xe772, 0xe773, 0xe774, 0xe775, 0xe776, 0xe777, 0xe778, 0xe779, + 0xe77a, 0xe77b, 0xe77c, 0xe77d, 0xe77e, 0xe780, 0xe781, 0xe782, + 0xe783, 0xe784, 0xe785, 0xe786, 0xe787, 0xe788, 0xe789, 0xe78a, + 0xe78b, 0xe78c, 0xe78d, 0xe78e, 0xe78f, 0xe790, 0xe791, 0xe792, + 0xe793, 0xe794, 0xe795, 0xe796, 0xe797, 0xe798, 0xe799, 0xe79a, + 0xe79b, 0xe79c, 0xe79d, 0xe79e, 0xe79f, 0xe7a0, 0xe840, 0xe841, + 0xe842, 0xe843, 0xe844, 0xe845, 0xe846, 0xe847, 0xe848, 0xe849, + 0xe84a, 0xe84b, 0xe84c, 0xe84d, 0xe84e, 0xe84f, 0xe850, 0xe851, + 0xe852, 0xe853, 0xe854, 0xe855, 0xe856, 0xe857, 0xe858, 0xe859, + 0xe85a, 0xe85b, 0xe85c, 0xe85d, 0xe85e, 0xe85f, 0xe860, 0xe861, + 0xe862, 0xe863, 0xe864, 0xe865, 0xe866, 0xe867, 0xe868, 0xe869, + 0xe86a, 0xe86b, 0xe86c, 0xe86d, 0xe86e, 0xe86f, 0xe870, 0xe871, + 0xe872, 0xe873, 0xe874, 0xe875, 0xe876, 0xe877, 0xe878, 0xe879, + 0xe87a, 0xe87b, 0xe87c, 0xe87d, 0xe87e, 0xe880, 0xe881, 0xe882, + 0xe883, 0xe884, 0xe885, 0xe886, 0xe887, 0xe888, 0xe889, 0xe88a, + 0xe88b, 0xe88c, 0xe88d, 0xe88e, 0xe88f, 0xe890, 0xe891, 0xe892, + 0xe893, 0xe894, 0xe895, 0xe896, 0xe897, 0xe898, 0xe899, 0xe89a, + 0xe89b, 0xe89c, 0xe89d, 0xe89e, 0xe89f, 0xe8a0, 0xe940, 0xe941, + 0xe942, 0xe943, 0xe944, 0xe945, 0xe946, 0xe947, 0xe948, 0xe949, + 0xe94a, 0xe94b, 0xe94c, 0xe94d, 0xe94e, 0xe94f, 0xe950, 0xe951, + 0xe952, 0xe953, 0xe954, 0xe955, 0xe956, 0xe957, 0xe958, 0xe959, + 0xe95a, 0xe95b, 0xe95c, 0xe95d, 0xe95e, 0xe95f, 0xe960, 0xe961, + 0xe962, 0xe963, 0xe964, 0xe965, 0xe966, 0xe967, 0xe968, 0xe969, + 0xe96a, 0xe96b, 0xe96c, 0xe96d, 0xe96e, 0xe96f, 0xe970, 0xe971, + 0xe972, 0xe973, 0xe974, 0xe975, 0xe976, 0xe977, 0xe978, 0xe979, + 0xe97a, 0xe97b, 0xe97c, 0xe97d, 0xe97e, 0xe980, 0xe981, 0xe982, + 0xe983, 0xe984, 0xe985, 0xe986, 0xe987, 0xe988, 0xe989, 0xe98a, + 0xe98b, 0xe98c, 0xe98d, 0xe98e, 0xe98f, 0xe990, 0xe991, 0xe992, + 0xe993, 0xe994, 0xe995, 0xe996, 0xe997, 0xe998, 0xe999, 0xe99a, + 0xe99b, 0xe99c, 0xe99d, 0xe99e, 0xe99f, 0xe9a0, 0xea40, 0xea41, + 0xea42, 0xea43, 0xea44, 0xea45, 0xea46, 0xea47, 0xea48, 0xea49, + 0xea4a, 0xea4b, 0xea4c, 0xea4d, 0xea4e, 0xea4f, 0xea50, 0xea51, + 0xea52, 0xea53, 0xea54, 0xea55, 0xea56, 0xea57, 0xea58, 0xea59, + 0xea5a, 0xea5b, 0xea5c, 0xea5d, 0xea5e, 0xea5f, 0xea60, 0xea61, + 0xea62, 0xea63, 0xea64, 0xea65, 0xea66, 0xea67, 0xea68, 0xea69, + 0xea6a, 0xea6b, 0xea6c, 0xea6d, 0xea6e, 0xea6f, 0xea70, 0xea71, + 0xea72, 0xea73, 0xea74, 0xea75, 0xea76, 0xea77, 0xea78, 0xea79, + 0xea7a, 0xea7b, 0xea7c, 0xea7d, 0xea7e, 0xea80, 0xea81, 0xea82, + 0xea83, 0xea84, 0xea85, 0xea86, 0xea87, 0xea88, 0xea89, 0xea8a, + 0xea8b, 0xea8c, 0xea8d, 0xea8e, 0xea8f, 0xea90, 0xea91, 0xea92, + 0xea93, 0xea94, 0xea95, 0xea96, 0xea97, 0xea98, 0xea99, 0xea9a, + 0xea9b, 0xea9c, 0xea9d, 0xea9e, 0xea9f, 0xeaa0, 0xeb40, 0xeb41, + 0xeb42, 0xeb43, 0xeb44, 0xeb45, 0xeb46, 0xeb47, 0xeb48, 0xeb49, + 0xeb4a, 0xeb4b, 0xeb4c, 0xeb4d, 0xeb4e, 0xeb4f, 0xeb50, 0xeb51, + 0xeb52, 0xeb53, 0xeb54, 0xeb55, 0xeb56, 0xeb57, 0xeb58, 0xeb59, + 0xeb5a, 0xeb5b, 0xeb5c, 0xeb5d, 0xeb5e, 0xeb5f, 0xeb60, 0xeb61, + 0xeb62, 0xeb63, 0xeb64, 0xeb65, 0xeb66, 0xeb67, 0xeb68, 0xeb69, + 0xeb6a, 0xeb6b, 0xeb6c, 0xeb6d, 0xeb6e, 0xeb6f, 0xeb70, 0xeb71, + 0xeb72, 0xeb73, 0xeb74, 0xeb75, 0xeb76, 0xeb77, 0xeb78, 0xeb79, + 0xeb7a, 0xeb7b, 0xeb7c, 0xeb7d, 0xeb7e, 0xeb80, 0xeb81, 0xeb82, + 0xeb83, 0xeb84, 0xeb85, 0xeb86, 0xeb87, 0xeb88, 0xeb89, 0xeb8a, + 0xeb8b, 0xeb8c, 0xeb8d, 0xeb8e, 0xeb8f, 0xeb90, 0xeb91, 0xeb92, + 0xeb93, 0xeb94, 0xeb95, 0xeb96, 0xeb97, 0xeb98, 0xeb99, 0xeb9a, + 0xeb9b, 0xeb9c, 0xeb9d, 0xeb9e, 0xeb9f, 0xeba0, 0xec40, 0xec41, + 0xec42, 0xec43, 0xec44, 0xec45, 0xec46, 0xec47, 0xec48, 0xec49, + 0xec4a, 0xec4b, 0xec4c, 0xec4d, 0xec4e, 0xec4f, 0xec50, 0xec51, + 0xec52, 0xec53, 0xec54, 0xec55, 0xec56, 0xec57, 0xec58, 0xec59, + 0xec5a, 0xec5b, 0xec5c, 0xec5d, 0xec5e, 0xec5f, 0xec60, 0xec61, + 0xec62, 0xec63, 0xec64, 0xec65, 0xec66, 0xec67, 0xec68, 0xec69, + 0xec6a, 0xec6b, 0xec6c, 0xec6d, 0xec6e, 0xec6f, 0xec70, 0xec71, + 0xec72, 0xec73, 0xec74, 0xec75, 0xec76, 0xec77, 0xec78, 0xec79, + 0xec7a, 0xec7b, 0xec7c, 0xec7d, 0xec7e, 0xec80, 0xec81, 0xec82, + 0xec83, 0xec84, 0xec85, 0xec86, 0xec87, 0xec88, 0xec89, 0xec8a, + 0xec8b, 0xec8c, 0xec8d, 0xec8e, 0xec8f, 0xec90, 0xec91, 0xec92, + 0xec93, 0xec94, 0xec95, 0xec96, 0xec97, 0xec98, 0xec99, 0xec9a, + 0xec9b, 0xec9c, 0xec9d, 0xec9e, 0xec9f, 0xeca0, 0xed40, 0xed41, + 0xed42, 0xed43, 0xed44, 0xed45, 0xed46, 0xed47, 0xed48, 0xed49, + 0xed4a, 0xed4b, 0xed4c, 0xed4d, 0xed4e, 0xed4f, 0xed50, 0xed51, + 0xed52, 0xed53, 0xed54, 0xed55, 0xed56, 0xed57, 0xed58, 0xed59, + 0xed5a, 0xed5b, 0xed5c, 0xed5d, 0xed5e, 0xed5f, 0xed60, 0xed61, + 0xed62, 0xed63, 0xed64, 0xed65, 0xed66, 0xed67, 0xed68, 0xed69, + 0xed6a, 0xed6b, 0xed6c, 0xed6d, 0xed6e, 0xed6f, 0xed70, 0xed71, + 0xed72, 0xed73, 0xed74, 0xed75, 0xed76, 0xed77, 0xed78, 0xed79, + 0xed7a, 0xed7b, 0xed7c, 0xed7d, 0xed7e, 0xed80, 0xed81, 0xed82, + 0xed83, 0xed84, 0xed85, 0xed86, 0xed87, 0xed88, 0xed89, 0xed8a, + 0xed8b, 0xed8c, 0xed8d, 0xed8e, 0xed8f, 0xed90, 0xed91, 0xed92, + 0xed93, 0xed94, 0xed95, 0xed96, 0xed97, 0xed98, 0xed99, 0xed9a, + 0xed9b, 0xed9c, 0xed9d, 0xed9e, 0xed9f, 0xeda0, 0xee40, 0xee41, + 0xee42, 0xee43, 0xee44, 0xee45, 0xee46, 0xee47, 0xee48, 0xee49, + 0xee4a, 0xee4b, 0xee4c, 0xee4d, 0xee4e, 0xee4f, 0xee50, 0xee51, + 0xee52, 0xee53, 0xee54, 0xee55, 0xee56, 0xee57, 0xee58, 0xee59, + 0xee5a, 0xee5b, 0xee5c, 0xee5d, 0xee5e, 0xee5f, 0xee60, 0xee61, + 0xee62, 0xee63, 0xee64, 0xee65, 0xee66, 0xee67, 0xee68, 0xee69, + 0xee6a, 0xee6b, 0xee6c, 0xee6d, 0xee6e, 0xee6f, 0xee70, 0xee71, + 0xee72, 0xee73, 0xee74, 0xee75, 0xee76, 0xee77, 0xee78, 0xee79, + 0xee7a, 0xee7b, 0xee7c, 0xee7d, 0xee7e, 0xee80, 0xee81, 0xee82, + 0xee83, 0xee84, 0xee85, 0xee86, 0xee87, 0xee88, 0xee89, 0xee8a, + 0xee8b, 0xee8c, 0xee8d, 0xee8e, 0xee8f, 0xee90, 0xee91, 0xee92, + 0xee93, 0xee94, 0xee95, 0xee96, 0xee97, 0xee98, 0xee99, 0xee9a, + 0xee9b, 0xee9c, 0xee9d, 0xee9e, 0xee9f, 0xeea0, 0xef40, 0xef41, + 0xef42, 0xef43, 0xef44, 0xef45, 0xef46, 0xef47, 0xef48, 0xef49, + 0xef4a, 0xef4b, 0xef4c, 0xef4d, 0xef4e, 0xef4f, 0xef50, 0xef51, + 0xef52, 0xef53, 0xef54, 0xef55, 0xef56, 0xef57, 0xef58, 0xef59, + 0xef5a, 0xef5b, 0xef5c, 0xef5d, 0xef5e, 0xef5f, 0xef60, 0xef61, + 0xef62, 0xef63, 0xef64, 0xef65, 0xef66, 0xef67, 0xef68, 0xef69, + 0xef6a, 0xef6b, 0xef6c, 0xef6d, 0xef6e, 0xef6f, 0xef70, 0xef71, + 0xef72, 0xef73, 0xef74, 0xef75, 0xef76, 0xef77, 0xef78, 0xef79, + 0xef7a, 0xef7b, 0xef7c, 0xef7d, 0xef7e, 0xef80, 0xef81, 0xef82, + 0xef83, 0xef84, 0xef85, 0xef86, 0xef87, 0xef88, 0xef89, 0xef8a, + 0xef8b, 0xef8c, 0xef8d, 0xef8e, 0xef8f, 0xef90, 0xef91, 0xef92, + 0xef93, 0xef94, 0xef95, 0xef96, 0xef97, 0xef98, 0xef99, 0xef9a, + 0xef9b, 0xef9c, 0xef9d, 0xef9e, 0xef9f, 0xefa0, 0xf040, 0xf041, + 0xf042, 0xf043, 0xf044, 0xf045, 0xf046, 0xf047, 0xf048, 0xf049, + 0xf04a, 0xf04b, 0xf04c, 0xf04d, 0xf04e, 0xf04f, 0xf050, 0xf051, + 0xf052, 0xf053, 0xf054, 0xf055, 0xf056, 0xf057, 0xf058, 0xf059, + 0xf05a, 0xf05b, 0xf05c, 0xf05d, 0xf05e, 0xf05f, 0xf060, 0xf061, + 0xf062, 0xf063, 0xf064, 0xf065, 0xf066, 0xf067, 0xf068, 0xf069, + 0xf06a, 0xf06b, 0xf06c, 0xf06d, 0xf06e, 0xf06f, 0xf070, 0xf071, + 0xf072, 0xf073, 0xf074, 0xf075, 0xf076, 0xf077, 0xf078, 0xf079, + 0xf07a, 0xf07b, 0xf07c, 0xf07d, 0xf07e, 0xf080, 0xf081, 0xf082, + 0xf083, 0xf084, 0xf085, 0xf086, 0xf087, 0xf088, 0xf089, 0xf08a, + 0xf08b, 0xf08c, 0xf08d, 0xf08e, 0xf08f, 0xf090, 0xf091, 0xf092, + 0xf093, 0xf094, 0xf095, 0xf096, 0xf097, 0xf098, 0xf099, 0xf09a, + 0xf09b, 0xf09c, 0xf09d, 0xf09e, 0xf09f, 0xf0a0, 0xf140, 0xf141, + 0xf142, 0xf143, 0xf144, 0xf145, 0xf146, 0xf147, 0xf148, 0xf149, + 0xf14a, 0xf14b, 0xf14c, 0xf14d, 0xf14e, 0xf14f, 0xf150, 0xf151, + 0xf152, 0xf153, 0xf154, 0xf155, 0xf156, 0xf157, 0xf158, 0xf159, + 0xf15a, 0xf15b, 0xf15c, 0xf15d, 0xf15e, 0xf15f, 0xf160, 0xf161, + 0xf162, 0xf163, 0xf164, 0xf165, 0xf166, 0xf167, 0xf168, 0xf169, + 0xf16a, 0xf16b, 0xf16c, 0xf16d, 0xf16e, 0xf16f, 0xf170, 0xf171, + 0xf172, 0xf173, 0xf174, 0xf175, 0xf176, 0xf177, 0xf178, 0xf179, + 0xf17a, 0xf17b, 0xf17c, 0xf17d, 0xf17e, 0xf180, 0xf181, 0xf182, + 0xf183, 0xf184, 0xf185, 0xf186, 0xf187, 0xf188, 0xf189, 0xf18a, + 0xf18b, 0xf18c, 0xf18d, 0xf18e, 0xf18f, 0xf190, 0xf191, 0xf192, + 0xf193, 0xf194, 0xf195, 0xf196, 0xf197, 0xf198, 0xf199, 0xf19a, + 0xf19b, 0xf19c, 0xf19d, 0xf19e, 0xf19f, 0xf1a0, 0xf240, 0xf241, + 0xf242, 0xf243, 0xf244, 0xf245, 0xf246, 0xf247, 0xf248, 0xf249, + 0xf24a, 0xf24b, 0xf24c, 0xf24d, 0xf24e, 0xf24f, 0xf250, 0xf251, + 0xf252, 0xf253, 0xf254, 0xf255, 0xf256, 0xf257, 0xf258, 0xf259, + 0xf25a, 0xf25b, 0xf25c, 0xf25d, 0xf25e, 0xf25f, 0xf260, 0xf261, + 0xf262, 0xf263, 0xf264, 0xf265, 0xf266, 0xf267, 0xf268, 0xf269, + 0xf26a, 0xf26b, 0xf26c, 0xf26d, 0xf26e, 0xf26f, 0xf270, 0xf271, + 0xf272, 0xf273, 0xf274, 0xf275, 0xf276, 0xf277, 0xf278, 0xf279, + 0xf27a, 0xf27b, 0xf27c, 0xf27d, 0xf27e, 0xf280, 0xf281, 0xf282, + 0xf283, 0xf284, 0xf285, 0xf286, 0xf287, 0xf288, 0xf289, 0xf28a, + 0xf28b, 0xf28c, 0xf28d, 0xf28e, 0xf28f, 0xf290, 0xf291, 0xf292, + 0xf293, 0xf294, 0xf295, 0xf296, 0xf297, 0xf298, 0xf299, 0xf29a, + 0xf29b, 0xf29c, 0xf29d, 0xf29e, 0xf29f, 0xf2a0, 0xf340, 0xf341, + 0xf342, 0xf343, 0xf344, 0xf345, 0xf346, 0xf347, 0xf348, 0xf349, + 0xf34a, 0xf34b, 0xf34c, 0xf34d, 0xf34e, 0xf34f, 0xf350, 0xf351, + 0xf352, 0xf353, 0xf354, 0xf355, 0xf356, 0xf357, 0xf358, 0xf359, + 0xf35a, 0xf35b, 0xf35c, 0xf35d, 0xf35e, 0xf35f, 0xf360, 0xf361, + 0xf362, 0xf363, 0xf364, 0xf365, 0xf366, 0xf367, 0xf368, 0xf369, + 0xf36a, 0xf36b, 0xf36c, 0xf36d, 0xf36e, 0xf36f, 0xf370, 0xf371, + 0xf372, 0xf373, 0xf374, 0xf375, 0xf376, 0xf377, 0xf378, 0xf379, + 0xf37a, 0xf37b, 0xf37c, 0xf37d, 0xf37e, 0xf380, 0xf381, 0xf382, + 0xf383, 0xf384, 0xf385, 0xf386, 0xf387, 0xf388, 0xf389, 0xf38a, + 0xf38b, 0xf38c, 0xf38d, 0xf38e, 0xf38f, 0xf390, 0xf391, 0xf392, + 0xf393, 0xf394, 0xf395, 0xf396, 0xf397, 0xf398, 0xf399, 0xf39a, + 0xf39b, 0xf39c, 0xf39d, 0xf39e, 0xf39f, 0xf3a0, 0xf440, 0xf441, + 0xf442, 0xf443, 0xf444, 0xf445, 0xf446, 0xf447, 0xf448, 0xf449, + 0xf44a, 0xf44b, 0xf44c, 0xf44d, 0xf44e, 0xf44f, 0xf450, 0xf451, + 0xf452, 0xf453, 0xf454, 0xf455, 0xf456, 0xf457, 0xf458, 0xf459, + 0xf45a, 0xf45b, 0xf45c, 0xf45d, 0xf45e, 0xf45f, 0xf460, 0xf461, + 0xf462, 0xf463, 0xf464, 0xf465, 0xf466, 0xf467, 0xf468, 0xf469, + 0xf46a, 0xf46b, 0xf46c, 0xf46d, 0xf46e, 0xf46f, 0xf470, 0xf471, + 0xf472, 0xf473, 0xf474, 0xf475, 0xf476, 0xf477, 0xf478, 0xf479, + 0xf47a, 0xf47b, 0xf47c, 0xf47d, 0xf47e, 0xf480, 0xf481, 0xf482, + 0xf483, 0xf484, 0xf485, 0xf486, 0xf487, 0xf488, 0xf489, 0xf48a, + 0xf48b, 0xf48c, 0xf48d, 0xf48e, 0xf48f, 0xf490, 0xf491, 0xf492, + 0xf493, 0xf494, 0xf495, 0xf496, 0xf497, 0xf498, 0xf499, 0xf49a, + 0xf49b, 0xf49c, 0xf49d, 0xf49e, 0xf49f, 0xf4a0, 0xf540, 0xf541, + 0xf542, 0xf543, 0xf544, 0xf545, 0xf546, 0xf547, 0xf548, 0xf549, + 0xf54a, 0xf54b, 0xf54c, 0xf54d, 0xf54e, 0xf54f, 0xf550, 0xf551, + 0xf552, 0xf553, 0xf554, 0xf555, 0xf556, 0xf557, 0xf558, 0xf559, + 0xf55a, 0xf55b, 0xf55c, 0xf55d, 0xf55e, 0xf55f, 0xf560, 0xf561, + 0xf562, 0xf563, 0xf564, 0xf565, 0xf566, 0xf567, 0xf568, 0xf569, + 0xf56a, 0xf56b, 0xf56c, 0xf56d, 0xf56e, 0xf56f, 0xf570, 0xf571, + 0xf572, 0xf573, 0xf574, 0xf575, 0xf576, 0xf577, 0xf578, 0xf579, + 0xf57a, 0xf57b, 0xf57c, 0xf57d, 0xf57e, 0xf580, 0xf581, 0xf582, + 0xf583, 0xf584, 0xf585, 0xf586, 0xf587, 0xf588, 0xf589, 0xf58a, + 0xf58b, 0xf58c, 0xf58d, 0xf58e, 0xf58f, 0xf590, 0xf591, 0xf592, + 0xf593, 0xf594, 0xf595, 0xf596, 0xf597, 0xf598, 0xf599, 0xf59a, + 0xf59b, 0xf59c, 0xf59d, 0xf59e, 0xf59f, 0xf5a0, 0xf640, 0xf641, + 0xf642, 0xf643, 0xf644, 0xf645, 0xf646, 0xf647, 0xf648, 0xf649, + 0xf64a, 0xf64b, 0xf64c, 0xf64d, 0xf64e, 0xf64f, 0xf650, 0xf651, + 0xf652, 0xf653, 0xf654, 0xf655, 0xf656, 0xf657, 0xf658, 0xf659, + 0xf65a, 0xf65b, 0xf65c, 0xf65d, 0xf65e, 0xf65f, 0xf660, 0xf661, + 0xf662, 0xf663, 0xf664, 0xf665, 0xf666, 0xf667, 0xf668, 0xf669, + 0xf66a, 0xf66b, 0xf66c, 0xf66d, 0xf66e, 0xf66f, 0xf670, 0xf671, + 0xf672, 0xf673, 0xf674, 0xf675, 0xf676, 0xf677, 0xf678, 0xf679, + 0xf67a, 0xf67b, 0xf67c, 0xf67d, 0xf67e, 0xf680, 0xf681, 0xf682, + 0xf683, 0xf684, 0xf685, 0xf686, 0xf687, 0xf688, 0xf689, 0xf68a, + 0xf68b, 0xf68c, 0xf68d, 0xf68e, 0xf68f, 0xf690, 0xf691, 0xf692, + 0xf693, 0xf694, 0xf695, 0xf696, 0xf697, 0xf698, 0xf699, 0xf69a, + 0xf69b, 0xf69c, 0xf69d, 0xf69e, 0xf69f, 0xf6a0, 0xf740, 0xf741, + 0xf742, 0xf743, 0xf744, 0xf745, 0xf746, 0xf747, 0xf748, 0xf749, + 0xf74a, 0xf74b, 0xf74c, 0xf74d, 0xf74e, 0xf74f, 0xf750, 0xf751, + 0xf752, 0xf753, 0xf754, 0xf755, 0xf756, 0xf757, 0xf758, 0xf759, + 0xf75a, 0xf75b, 0xf75c, 0xf75d, 0xf75e, 0xf75f, 0xf760, 0xf761, + 0xf762, 0xf763, 0xf764, 0xf765, 0xf766, 0xf767, 0xf768, 0xf769, + 0xf76a, 0xf76b, 0xf76c, 0xf76d, 0xf76e, 0xf76f, 0xf770, 0xf771, + 0xf772, 0xf773, 0xf774, 0xf775, 0xf776, 0xf777, 0xf778, 0xf779, + 0xf77a, 0xf77b, 0xf77c, 0xf77d, 0xf77e, 0xf780, 0xf781, 0xf782, + 0xf783, 0xf784, 0xf785, 0xf786, 0xf787, 0xf788, 0xf789, 0xf78a, + 0xf78b, 0xf78c, 0xf78d, 0xf78e, 0xf78f, 0xf790, 0xf791, 0xf792, + 0xf793, 0xf794, 0xf795, 0xf796, 0xf797, 0xf798, 0xf799, 0xf79a, + 0xf79b, 0xf79c, 0xf79d, 0xf79e, 0xf79f, 0xf7a0, 0xf840, 0xf841, + 0xf842, 0xf843, 0xf844, 0xf845, 0xf846, 0xf847, 0xf848, 0xf849, + 0xf84a, 0xf84b, 0xf84c, 0xf84d, 0xf84e, 0xf84f, 0xf850, 0xf851, + 0xf852, 0xf853, 0xf854, 0xf855, 0xf856, 0xf857, 0xf858, 0xf859, + 0xf85a, 0xf85b, 0xf85c, 0xf85d, 0xf85e, 0xf85f, 0xf860, 0xf861, + 0xf862, 0xf863, 0xf864, 0xf865, 0xf866, 0xf867, 0xf868, 0xf869, + 0xf86a, 0xf86b, 0xf86c, 0xf86d, 0xf86e, 0xf86f, 0xf870, 0xf871, + 0xf872, 0xf873, 0xf874, 0xf875, 0xf876, 0xf877, 0xf878, 0xf879, + 0xf87a, 0xf87b, 0xf87c, 0xf87d, 0xf87e, 0xf880, 0xf881, 0xf882, + 0xf883, 0xf884, 0xf885, 0xf886, 0xf887, 0xf888, 0xf889, 0xf88a, + 0xf88b, 0xf88c, 0xf88d, 0xf88e, 0xf88f, 0xf890, 0xf891, 0xf892, + 0xf893, 0xf894, 0xf895, 0xf896, 0xf897, 0xf898, 0xf899, 0xf89a, + 0xf89b, 0xf89c, 0xf89d, 0xf89e, 0xf89f, 0xf8a0, 0xf940, 0xf941, + 0xf942, 0xf943, 0xf944, 0xf945, 0xf946, 0xf947, 0xf948, 0xf949, + 0xf94a, 0xf94b, 0xf94c, 0xf94d, 0xf94e, 0xf94f, 0xf950, 0xf951, + 0xf952, 0xf953, 0xf954, 0xf955, 0xf956, 0xf957, 0xf958, 0xf959, + 0xf95a, 0xf95b, 0xf95c, 0xf95d, 0xf95e, 0xf95f, 0xf960, 0xf961, + 0xf962, 0xf963, 0xf964, 0xf965, 0xf966, 0xf967, 0xf968, 0xf969, + 0xf96a, 0xf96b, 0xf96c, 0xf96d, 0xf96e, 0xf96f, 0xf970, 0xf971, + 0xf972, 0xf973, 0xf974, 0xf975, 0xf976, 0xf977, 0xf978, 0xf979, + 0xf97a, 0xf97b, 0xf97c, 0xf97d, 0xf97e, 0xf980, 0xf981, 0xf982, + 0xf983, 0xf984, 0xf985, 0xf986, 0xf987, 0xf988, 0xf989, 0xf98a, + 0xf98b, 0xf98c, 0xf98d, 0xf98e, 0xf98f, 0xf990, 0xf991, 0xf992, + 0xf993, 0xf994, 0xf995, 0xf996, 0xf997, 0xf998, 0xf999, 0xf99a, + 0xf99b, 0xf99c, 0xf99d, 0xf99e, 0xf99f, 0xf9a0, 0xfa40, 0xfa41, + 0xfa42, 0xfa43, 0xfa44, 0xfa45, 0xfa46, 0xfa47, 0xfa48, 0xfa49, + 0xfa4a, 0xfa4b, 0xfa4c, 0xfa4d, 0xfa4e, 0xfa4f, 0xfa50, 0xfa51, + 0xfa52, 0xfa53, 0xfa54, 0xfa55, 0xfa56, 0xfa57, 0xfa58, 0xfa59, + 0xfa5a, 0xfa5b, 0xfa5c, 0xfa5d, 0xfa5e, 0xfa5f, 0xfa60, 0xfa61, + 0xfa62, 0xfa63, 0xfa64, 0xfa65, 0xfa66, 0xfa67, 0xfa68, 0xfa69, + 0xfa6a, 0xfa6b, 0xfa6c, 0xfa6d, 0xfa6e, 0xfa6f, 0xfa70, 0xfa71, + 0xfa72, 0xfa73, 0xfa74, 0xfa75, 0xfa76, 0xfa77, 0xfa78, 0xfa79, + 0xfa7a, 0xfa7b, 0xfa7c, 0xfa7d, 0xfa7e, 0xfa80, 0xfa81, 0xfa82, + 0xfa83, 0xfa84, 0xfa85, 0xfa86, 0xfa87, 0xfa88, 0xfa89, 0xfa8a, + 0xfa8b, 0xfa8c, 0xfa8d, 0xfa8e, 0xfa8f, 0xfa90, 0xfa91, 0xfa92, + 0xfa93, 0xfa94, 0xfa95, 0xfa96, 0xfa97, 0xfa98, 0xfa99, 0xfa9a, + 0xfa9b, 0xfa9c, 0xfa9d, 0xfa9e, 0xfa9f, 0xfaa0, 0xfb40, 0xfb41, + 0xfb42, 0xfb43, 0xfb44, 0xfb45, 0xfb46, 0xfb47, 0xfb48, 0xfb49, + 0xfb4a, 0xfb4b, 0xfb4c, 0xfb4d, 0xfb4e, 0xfb4f, 0xfb50, 0xfb51, + 0xfb52, 0xfb53, 0xfb54, 0xfb55, 0xfb56, 0xfb57, 0xfb58, 0xfb59, + 0xfb5a, 0xfb5b, 0xfb5c, 0xfb5d, 0xfb5e, 0xfb5f, 0xfb60, 0xfb61, + 0xfb62, 0xfb63, 0xfb64, 0xfb65, 0xfb66, 0xfb67, 0xfb68, 0xfb69, + 0xfb6a, 0xfb6b, 0xfb6c, 0xfb6d, 0xfb6e, 0xfb6f, 0xfb70, 0xfb71, + 0xfb72, 0xfb73, 0xfb74, 0xfb75, 0xfb76, 0xfb77, 0xfb78, 0xfb79, + 0xfb7a, 0xfb7b, 0xfb7c, 0xfb7d, 0xfb7e, 0xfb80, 0xfb81, 0xfb82, + 0xfb83, 0xfb84, 0xfb85, 0xfb86, 0xfb87, 0xfb88, 0xfb89, 0xfb8a, + 0xfb8b, 0xfb8c, 0xfb8d, 0xfb8e, 0xfb8f, 0xfb90, 0xfb91, 0xfb92, + 0xfb93, 0xfb94, 0xfb95, 0xfb96, 0xfb97, 0xfb98, 0xfb99, 0xfb9a, + 0xfb9b, 0xfb9c, 0xfb9d, 0xfb9e, 0xfb9f, 0xfba0, 0xfc40, 0xfc41, + 0xfc42, 0xfc43, 0xfc44, 0xfc45, 0xfc46, 0xfc47, 0xfc48, 0xfc49, + 0xfc4a, 0xfc4b, 0xfc4c, 0xfc4d, 0xfc4e, 0xfc4f, 0xfc50, 0xfc51, + 0xfc52, 0xfc53, 0xfc54, 0xfc55, 0xfc56, 0xfc57, 0xfc58, 0xfc59, + 0xfc5a, 0xfc5b, 0xfc5c, 0xfc5d, 0xfc5e, 0xfc5f, 0xfc60, 0xfc61, + 0xfc62, 0xfc63, 0xfc64, 0xfc65, 0xfc66, 0xfc67, 0xfc68, 0xfc69, + 0xfc6a, 0xfc6b, 0xfc6c, 0xfc6d, 0xfc6e, 0xfc6f, 0xfc70, 0xfc71, + 0xfc72, 0xfc73, 0xfc74, 0xfc75, 0xfc76, 0xfc77, 0xfc78, 0xfc79, + 0xfc7a, 0xfc7b, 0xfc7c, 0xfc7d, 0xfc7e, 0xfc80, 0xfc81, 0xfc82, + 0xfc83, 0xfc84, 0xfc85, 0xfc86, 0xfc87, 0xfc88, 0xfc89, 0xfc8a, + 0xfc8b, 0xfc8c, 0xfc8d, 0xfc8e, 0xfc8f, 0xfc90, 0xfc91, 0xfc92, + 0xfc93, 0xfc94, 0xfc95, 0xfc96, 0xfc97, 0xfc98, 0xfc99, 0xfc9a, + 0xfc9b, 0xfc9c, 0xfc9d, 0xfc9e, 0xfc9f, 0xfca0, 0xfd40, 0xfd41, + 0xfd42, 0xfd43, 0xfd44, 0xfd45, 0xfd46, 0xfd47, 0xfd48, 0xfd49, + 0xfd4a, 0xfd4b, 0xfd4c, 0xfd4d, 0xfd4e, 0xfd4f, 0xfd50, 0xfd51, + 0xfd52, 0xfd53, 0xfd54, 0xfd55, 0xfd56, 0xfd57, 0xfd58, 0xfd59, + 0xfd5a, 0xfd5b, 0xfd5c, 0xfd5d, 0xfd5e, 0xfd5f, 0xfd60, 0xfd61, + 0xfd62, 0xfd63, 0xfd64, 0xfd65, 0xfd66, 0xfd67, 0xfd68, 0xfd69, + 0xfd6a, 0xfd6b, 0xfd6c, 0xfd6d, 0xfd6e, 0xfd6f, 0xfd70, 0xfd71, + 0xfd72, 0xfd73, 0xfd74, 0xfd75, 0xfd76, 0xfd77, 0xfd78, 0xfd79, + 0xfd7a, 0xfd7b, 0xfd7c, 0xfd7d, 0xfd7e, 0xfd80, 0xfd81, 0xfd82, + 0xfd83, 0xfd84, 0xfd85, 0xfd86, 0xfd87, 0xfd88, 0xfd89, 0xfd8a, + 0xfd8b, 0xfd8c, 0xfd8d, 0xfd8e, 0xfd8f, 0xfd90, 0xfd91, 0xfd92, + 0xfd93, 0xfd94, 0xfd95, 0xfd96, 0xfd97, 0xfd98, 0xfd99, 0xfd9a, + 0xfd9b, 0xfd9c, 0xfd9d, 0xfd9e, 0xfd9f, 0xfda0, 0xfe40, 0xfe41, + 0xfe42, 0xfe43, 0xfe44, 0xfe45, 0xfe46, 0xfe47, 0xfe48, 0xfe49, + 0xfe4a, 0xfe4b, 0xfe4c, 0xfe4d, 0xfe4e, 0xfe4f, 0xa955, 0xa968, + 0xa969, 0xa96a, 0xa96b, 0xa96c, 0xa96d, 0xa96e, 0xa96f, 0xa970, + 0xa971, 0xa972, 0xa973, 0xa974, 0xa975, 0xa976, 0xa977, 0xa978, + 0xa979, 0xa97a, 0xa97b, 0xa97c, 0xa97d, 0xa97e, 0xa980, 0xa981, + 0xa982, 0xa983, 0xa984, 0xa985, 0xa986, 0xa987, 0xa988, 0xa956, + 0xa957, +}; + +static const Summary16 gbkext_inv_uni2indx_page02[14] = { + /* 0x0200 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0c00 }, { 2, 0x0200 }, +}; +static const Summary16 gbkext_inv_uni2indx_page20[44] = { + /* 0x2000 */ + { 3, 0x0000 }, { 3, 0x0029 }, { 6, 0x0020 }, { 7, 0x0020 }, + { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, + { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, + { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, + /* 0x2100 */ + { 8, 0x0220 }, { 10, 0x0000 }, { 10, 0x0002 }, { 11, 0x0000 }, + { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, + { 11, 0x0000 }, { 11, 0x03c0 }, { 15, 0x0000 }, { 15, 0x0000 }, + { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0000 }, + /* 0x2200 */ + { 15, 0x0000 }, { 15, 0x8020 }, { 17, 0x0008 }, { 18, 0x0000 }, + { 18, 0x0000 }, { 18, 0x0004 }, { 19, 0x00c0 }, { 21, 0x0000 }, + { 21, 0x0000 }, { 21, 0x0020 }, { 22, 0x0000 }, { 22, 0x8000 }, +}; +static const Summary16 gbkext_inv_uni2indx_page25[17] = { + /* 0x2500 */ + { 23, 0x0000 }, { 23, 0x0000 }, { 23, 0x0000 }, { 23, 0x0000 }, + { 23, 0x0000 }, { 23, 0xffff }, { 39, 0xffff }, { 55, 0x000f }, + { 59, 0xfffe }, { 74, 0x0038 }, { 77, 0x0000 }, { 77, 0x3000 }, + { 79, 0x0000 }, { 79, 0x0000 }, { 79, 0x003c }, { 83, 0x0000 }, + /* 0x2600 */ + { 83, 0x0200 }, +}; +static const Summary16 gbkext_inv_uni2indx_page30[16] = { + /* 0x3000 */ + { 84, 0x00c0 }, { 86, 0x6004 }, { 89, 0x03fe }, { 98, 0x0000 }, + { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x0000 }, + { 98, 0x0000 }, { 98, 0x7800 }, { 102, 0x0000 }, { 102, 0x0000 }, + { 102, 0x0000 }, { 102, 0x0000 }, { 102, 0x0000 }, { 102, 0x7000 }, +}; +static const Summary16 gbkext_inv_uni2indx_page32[30] = { + /* 0x3200 */ + { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x0002 }, + { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x0000 }, + { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x0008 }, { 107, 0x0000 }, + { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0000 }, + /* 0x3300 */ + { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0000 }, + { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0000 }, + { 107, 0xc000 }, { 109, 0x7000 }, { 112, 0x0002 }, { 113, 0x0000 }, + { 113, 0x4010 }, { 115, 0x0026 }, +}; +static const Summary16 gbkext_inv_uni2indx_page4e[1307] = { + /* 0x4e00 */ + { 118, 0x8074 }, { 123, 0x8084 }, { 126, 0xc24b }, { 133, 0x10aa }, + { 138, 0x0457 }, { 144, 0x0ca2 }, { 149, 0xfdbc }, { 161, 0xbff4 }, + { 173, 0x04bf }, { 181, 0x72c1 }, { 188, 0x8408 }, { 191, 0x73d3 }, + { 201, 0x9100 }, { 204, 0x1c05 }, { 209, 0xe2c5 }, { 217, 0x5712 }, + /* 0x4f00 */ + { 224, 0x19fd }, { 234, 0x307c }, { 241, 0x730a }, { 248, 0xcaaa }, + { 256, 0x1fb7 }, { 267, 0x0054 }, { 270, 0x6d46 }, { 278, 0x27a6 }, + { 286, 0x54e7 }, { 295, 0xd76d }, { 306, 0x2816 }, { 311, 0x7fdf }, + { 325, 0x3bc7 }, { 335, 0x0a7c }, { 342, 0x18b5 }, { 349, 0xbaf5 }, + /* 0x5000 */ + { 360, 0x4fff }, { 373, 0x68eb }, { 382, 0x889d }, { 389, 0xabff }, + { 402, 0x2e77 }, { 412, 0xebdf }, { 425, 0xefdf }, { 439, 0x373f }, + { 450, 0xdede }, { 462, 0xffff }, { 478, 0xec57 }, { 488, 0xf3fb }, + { 501, 0x7fff }, { 516, 0xfbbf }, { 530, 0x8f3f }, { 541, 0xf7d7 }, + /* 0x5100 */ + { 554, 0xf73f }, { 567, 0xfffb }, { 582, 0xfffd }, { 597, 0x7fff }, + { 612, 0xd484 }, { 618, 0xeb8d }, { 628, 0x86db }, { 637, 0xc404 }, + { 641, 0xccd8 }, { 649, 0xe51b }, { 658, 0x67ca }, { 667, 0xc710 }, + { 673, 0x652e }, { 681, 0xd7fd }, { 694, 0x57ec }, { 704, 0x4096 }, + /* 0x5200 */ + { 709, 0x9a30 }, { 715, 0xd039 }, { 722, 0x94ee }, { 731, 0x5036 }, + { 737, 0xcbf0 }, { 746, 0xafac }, { 756, 0x795d }, { 766, 0x5ffb }, + { 779, 0xfef9 }, { 792, 0x17f6 }, { 802, 0xc0f0 }, { 808, 0x3ff1 }, + { 819, 0xf577 }, { 831, 0x7eba }, { 842, 0xffef }, { 857, 0x39fe }, + /* 0x5300 */ + { 868, 0x5e9e }, { 878, 0xd91e }, { 887, 0xbbb4 }, { 897, 0x31ff }, + { 908, 0x3855 }, { 915, 0x2b11 }, { 921, 0x3520 }, { 926, 0x7a44 }, + { 933, 0xc58b }, { 941, 0x5adf }, { 952, 0xbc93 }, { 961, 0x77bf }, + { 974, 0xc0f9 }, { 982, 0x742d }, { 990, 0x0086 }, { 993, 0xc410 }, + /* 0x5400 */ + { 997, 0x08a5 }, { 1002, 0x1710 }, { 1007, 0x0434 }, { 1011, 0xa4c9 }, + { 1018, 0xf2b6 }, { 1028, 0xe402 }, { 1033, 0xfeab }, { 1045, 0xc611 }, + { 1051, 0x27aa }, { 1059, 0xd18a }, { 1066, 0x4027 }, { 1071, 0x56e5 }, + { 1080, 0x0c28 }, { 1084, 0x0940 }, { 1087, 0x981f }, { 1095, 0x4bf3 }, + /* 0x5500 */ + { 1105, 0x7d3d }, { 1116, 0xf7ec }, { 1128, 0x2b62 }, { 1135, 0x2f74 }, + { 1144, 0xf9a5 }, { 1154, 0xef9e }, { 1166, 0x8b0d }, { 1173, 0xa61f }, + { 1182, 0x7060 }, { 1187, 0x4ced }, { 1196, 0xff7f }, { 1211, 0x9555 }, + { 1219, 0xcdcf }, { 1230, 0x4fa1 }, { 1238, 0x6285 }, { 1244, 0x9f53 }, + /* 0x5600 */ + { 1254, 0x2cfc }, { 1263, 0x36ff }, { 1275, 0xcf67 }, { 1286, 0x75a9 }, + { 1295, 0x8fff }, { 1308, 0xec6f }, { 1319, 0xe0eb }, { 1328, 0xe7bd }, + { 1340, 0x3f9f }, { 1352, 0xfff7 }, { 1367, 0x7ff7 }, { 1381, 0xef7f }, + { 1395, 0xfbff }, { 1410, 0x136f }, { 1419, 0xd7e8 }, { 1429, 0x19cc }, + /* 0x5700 */ + { 1436, 0xf8a7 }, { 1446, 0x6fff }, { 1460, 0x08f7 }, { 1468, 0xb1f6 }, + { 1478, 0x0b7a }, { 1486, 0x037c }, { 1493, 0x50ac }, { 1499, 0xe737 }, + { 1510, 0xe783 }, { 1519, 0xf7f3 }, { 1532, 0x9520 }, { 1537, 0xfeeb }, + { 1550, 0x37f3 }, { 1561, 0x58cb }, { 1569, 0x5fee }, { 1581, 0xd8ef }, + /* 0x5800 */ + { 1592, 0xd73a }, { 1602, 0xbddd }, { 1614, 0xfbec }, { 1626, 0xffde }, + { 1640, 0xcfef }, { 1653, 0xbeed }, { 1665, 0xe7df }, { 1678, 0xbfff }, + { 1693, 0xfdd4 }, { 1704, 0x39f3 }, { 1714, 0xfcff }, { 1728, 0xefff }, + { 1743, 0xffdd }, { 1757, 0xffdd }, { 1771, 0xa7ef }, { 1783, 0xfdb6 }, + /* 0x5900 */ + { 1795, 0x5f6b }, { 1806, 0x698f }, { 1815, 0x114f }, { 1822, 0xe86d }, + { 1831, 0x3469 }, { 1838, 0xfa0d }, { 1847, 0xffda }, { 1860, 0xdca7 }, + { 1870, 0xda21 }, { 1877, 0xbd33 }, { 1887, 0x30c7 }, { 1894, 0xb5fb }, + { 1906, 0xf3bf }, { 1919, 0xca60 }, { 1925, 0xeed7 }, { 1937, 0x75ff }, + /* 0x5a00 */ + { 1950, 0xec05 }, { 1957, 0x6ef5 }, { 1968, 0xfdd6 }, { 1980, 0xefa9 }, + { 1991, 0xf9be }, { 2003, 0xfbdf }, { 2017, 0xfb7b }, { 2030, 0x7b0f }, + { 2040, 0xffff }, { 2056, 0xf3fb }, { 2069, 0xfbff }, { 2084, 0xbed3 }, + { 2095, 0xedf9 }, { 2107, 0xeeab }, { 2118, 0xf5b4 }, { 2128, 0xfffd }, + /* 0x5b00 */ + { 2143, 0xfdff }, { 2158, 0xff3f }, { 2172, 0xffff }, { 2188, 0xff6b }, + { 2201, 0xfffe }, { 2216, 0x4044 }, { 2219, 0xe983 }, { 2227, 0xdbd4 }, + { 2237, 0x6444 }, { 2242, 0x8057 }, { 2248, 0xf380 }, { 2255, 0x1c86 }, + { 2261, 0xef0b }, { 2271, 0x1ff2 }, { 2281, 0xbecd }, { 2292, 0x60fe }, + /* 0x5c00 */ + { 2301, 0x79ad }, { 2311, 0xca8d }, { 2319, 0xef4b }, { 2330, 0x00ed }, + { 2336, 0x30d8 }, { 2342, 0xbddc }, { 2353, 0x3f94 }, { 2362, 0x79fd }, + { 2374, 0xcef9 }, { 2385, 0xe02c }, { 2391, 0xc5f3 }, { 2401, 0x5e55 }, + { 2410, 0xf7ed }, { 2423, 0xfdfb }, { 2437, 0xda8d }, { 2446, 0xf7fe }, + /* 0x5d00 */ + { 2460, 0xbf33 }, { 2471, 0xb7af }, { 2483, 0x9d2f }, { 2493, 0x9fef }, + { 2506, 0xe37f }, { 2518, 0xd6ff }, { 2531, 0x65ff }, { 2543, 0xffef }, + { 2558, 0xfffb }, { 2573, 0xddff }, { 2587, 0xffff }, { 2603, 0xff7f }, + { 2618, 0xdfdf }, { 2632, 0x97ff }, { 2645, 0x3419 }, { 2651, 0x9f61 }, + /* 0x5e00 */ + { 2660, 0x6e91 }, { 2668, 0xc08c }, { 2673, 0x9f3f }, { 2685, 0xc67d }, + { 2695, 0xefcb }, { 2707, 0xb7cf }, { 2719, 0xfff9 }, { 2733, 0x42a3 }, + { 2739, 0x732e }, { 2748, 0x2904 }, { 2752, 0xdf1e }, { 2763, 0xbc17 }, + { 2772, 0xf9ff }, { 2786, 0xf7b1 }, { 2797, 0xfaff }, { 2811, 0x3b2f }, + /* 0x5f00 */ + { 2821, 0x72e0 }, { 2828, 0x7655 }, { 2837, 0x591e }, { 2845, 0xe9fd }, + { 2857, 0xfffe }, { 2872, 0xde12 }, { 2880, 0xc9a9 }, { 2888, 0xe574 }, + { 2897, 0xe048 }, { 2902, 0xec5a }, { 2911, 0x9afd }, { 2922, 0xcf5f }, + { 2934, 0x4d87 }, { 2942, 0xdc38 }, { 2950, 0x936c }, { 2958, 0x16dd }, + /* 0x6000 */ + { 2967, 0x1b80 }, { 2972, 0xc58b }, { 2980, 0x701c }, { 2986, 0x67df }, + { 2998, 0xd7f1 }, { 3009, 0xd9da }, { 3019, 0x4063 }, { 3024, 0x40b6 }, + { 3030, 0xcde7 }, { 3041, 0x53ab }, { 3050, 0x46b6 }, { 3058, 0xe6e9 }, + { 3068, 0xf39f }, { 3080, 0x4add }, { 3089, 0x043e }, { 3095, 0xf9a6 }, + /* 0x6100 */ + { 3105, 0x1cbc }, { 3113, 0x7bdf }, { 3126, 0xf726 }, { 3136, 0x7fff }, + { 3151, 0xaaff }, { 3163, 0xdfdd }, { 3176, 0xfe7b }, { 3189, 0xff5e }, + { 3202, 0xb7ff }, { 3216, 0xdfef }, { 3230, 0xec7f }, { 3242, 0xbf7f }, + { 3256, 0xf2fb }, { 3268, 0xffe9 }, { 3281, 0xffbf }, { 3296, 0x7fdf }, + /* 0x6200 */ + { 3310, 0x02bf }, { 3318, 0x7218 }, { 3324, 0xabc9 }, { 3333, 0x1f67 }, + { 3343, 0x8474 }, { 3349, 0xf6e1 }, { 3359, 0x0137 }, { 3365, 0x2db6 }, + { 3374, 0xf9ee }, { 3386, 0x7211 }, { 3392, 0xe6c8 }, { 3400, 0x45dd }, + { 3409, 0x880b }, { 3414, 0x6022 }, { 3418, 0x0c13 }, { 3423, 0x0f25 }, + /* 0x6300 */ + { 3430, 0xbc79 }, { 3440, 0x13bd }, { 3449, 0x72c0 }, { 3455, 0xd9fb }, + { 3467, 0x0593 }, { 3473, 0x3fde }, { 3485, 0x9d71 }, { 3494, 0xf33d }, + { 3505, 0x287a }, { 3512, 0xfeba }, { 3524, 0x8852 }, { 3529, 0xaa66 }, + { 3537, 0x1daf }, { 3547, 0xbfba }, { 3559, 0xd9f4 }, { 3569, 0x5eab }, + /* 0x6400 */ + { 3579, 0x67d8 }, { 3588, 0xa7e6 }, { 3598, 0xcbbc }, { 3608, 0x5bef }, + { 3620, 0xfa0d }, { 3629, 0xbeeb }, { 3641, 0xdd7f }, { 3654, 0xf8ff }, + { 3667, 0xff4b }, { 3679, 0xbd99 }, { 3689, 0x8def }, { 3700, 0xea5e }, + { 3710, 0x9fda }, { 3721, 0xbe7a }, { 3732, 0xffab }, { 3745, 0xffff }, + /* 0x6500 */ + { 3761, 0xfdfe }, { 3775, 0xfefb }, { 3789, 0x37df }, { 3801, 0x348f }, + { 3809, 0x6cdf }, { 3820, 0x959d }, { 3829, 0xe7b3 }, { 3840, 0xff6a }, + { 3852, 0xe77f }, { 3865, 0x6574 }, { 3873, 0x554d }, { 3881, 0xcdfe }, + { 3893, 0x2785 }, { 3900, 0xff3b }, { 3913, 0x0c1a }, { 3918, 0xfb3c }, + /* 0x6600 */ + { 3929, 0x2bb2 }, { 3937, 0x5dc7 }, { 3947, 0x5e5e }, { 3957, 0xaf8d }, + { 3967, 0x67f5 }, { 3978, 0x7b03 }, { 3986, 0x3ead }, { 3996, 0xbb2e }, + { 4006, 0xef6b }, { 4018, 0xdf3d }, { 4030, 0xbe7f }, { 4043, 0xbdef }, + { 4056, 0xffff }, { 4072, 0xc5ff }, { 4084, 0xfdbf }, { 4098, 0x2d62 }, + /* 0x6700 */ + { 4105, 0xd0fe }, { 4115, 0x574e }, { 4124, 0x42bf }, { 4133, 0xdbcd }, + { 4144, 0x2cb2 }, { 4151, 0x2fb4 }, { 4160, 0x58dc }, { 4168, 0x2f52 }, + { 4176, 0xf56d }, { 4187, 0x8a5e }, { 4195, 0x5253 }, { 4202, 0xfe16 }, + { 4212, 0x7fe5 }, { 4224, 0x88e0 }, { 4229, 0x6dda }, { 4239, 0x5fe4 }, + /* 0x6800 */ + { 4249, 0x205e }, { 4255, 0xdf35 }, { 4266, 0xf9fd }, { 4279, 0x8c73 }, + { 4287, 0xa880 }, { 4291, 0xffc4 }, { 4302, 0xf400 }, { 4307, 0xff2f }, + { 4320, 0x7f95 }, { 4331, 0xff77 }, { 4345, 0x5e3b }, { 4355, 0xffd6 }, + { 4368, 0xd5fa }, { 4379, 0xfadb }, { 4391, 0xbff6 }, { 4404, 0xe9dc }, + /* 0x6900 */ + { 4414, 0x97dd }, { 4425, 0x7ffa }, { 4438, 0xdfee }, { 4451, 0x5dee }, + { 4462, 0xfffb }, { 4477, 0x9b6f }, { 4488, 0xb7b6 }, { 4499, 0xec7d }, + { 4510, 0xdc2a }, { 4518, 0xe6cf }, { 4529, 0xd67f }, { 4541, 0xf76d }, + { 4553, 0xabfd }, { 4565, 0x77ee }, { 4577, 0xdffe }, { 4591, 0x5ffb }, + /* 0x6a00 */ + { 4604, 0xfbff }, { 4619, 0x7e7f }, { 4632, 0x7afd }, { 4644, 0x9fdd }, + { 4656, 0xff6f }, { 4670, 0xf4fe }, { 4682, 0xffdd }, { 4696, 0xedfd }, + { 4709, 0xbfee }, { 4722, 0xff7c }, { 4735, 0xe5fe }, { 4747, 0xffff }, + { 4763, 0xffff }, { 4779, 0xffff }, { 4795, 0xffff }, { 4811, 0xffff }, + /* 0x6b00 */ + { 4827, 0xffff }, { 4843, 0xffff }, { 4859, 0xff60 }, { 4869, 0xb97b }, + { 4880, 0xed37 }, { 4891, 0xfdff }, { 4906, 0xfb03 }, { 4915, 0xe5ff }, + { 4928, 0xd121 }, { 4934, 0xf3b3 }, { 4945, 0xfbfd }, { 4959, 0x7f47 }, + { 4970, 0x57d9 }, { 4980, 0xf503 }, { 4988, 0x73fd }, { 5000, 0xddd7 }, + /* 0x6c00 */ + { 5012, 0x5f1f }, { 5023, 0x7084 }, { 5028, 0x3829 }, { 5034, 0xdeca }, + { 5044, 0xf938 }, { 5053, 0x074e }, { 5060, 0xf8ec }, { 5070, 0x9daa }, + { 5079, 0x6c91 }, { 5086, 0x75e6 }, { 5096, 0x9105 }, { 5101, 0x04f1 }, + { 5107, 0xe9cf }, { 5118, 0xb706 }, { 5126, 0x32d0 }, { 5132, 0x8214 }, + /* 0x6d00 */ + { 5136, 0xa76d }, { 5146, 0xb17b }, { 5156, 0xb35f }, { 5167, 0x85d1 }, + { 5174, 0x1215 }, { 5179, 0xa9e1 }, { 5187, 0x39b6 }, { 5196, 0xee6f }, + { 5208, 0xacdb }, { 5218, 0x17c5 }, { 5226, 0x3024 }, { 5230, 0x7edb }, + { 5242, 0xe70e }, { 5251, 0x9cbd }, { 5261, 0xa7ac }, { 5270, 0xe575 }, + /* 0x6e00 */ + { 5280, 0x8bdf }, { 5291, 0xdb2c }, { 5300, 0x55c4 }, { 5307, 0xfaeb }, + { 5319, 0x9fe7 }, { 5331, 0x76a7 }, { 5341, 0xb7ff }, { 5355, 0x3fff }, + { 5369, 0x7d97 }, { 5380, 0x6efe }, { 5392, 0x7b5b }, { 5403, 0xd329 }, + { 5411, 0x7779 }, { 5422, 0x3b45 }, { 5430, 0xfc88 }, { 5438, 0xfdef }, + /* 0x6f00 */ + { 5452, 0x7dbb }, { 5464, 0xffc7 }, { 5477, 0x51ee }, { 5486, 0xbfb5 }, + { 5498, 0xd73f }, { 5510, 0xaeff }, { 5523, 0x9fbb }, { 5535, 0xeaeb }, + { 5546, 0x8cef }, { 5556, 0xefff }, { 5571, 0xff7d }, { 5585, 0xfdb7 }, + { 5598, 0xfdfa }, { 5611, 0xbff9 }, { 5624, 0x3ffc }, { 5636, 0xffff }, + /* 0x7000 */ + { 5652, 0xffff }, { 5668, 0xf3fd }, { 5681, 0xfff7 }, { 5696, 0xfddf }, + { 5710, 0x6fff }, { 5724, 0xbfff }, { 5739, 0x47ff }, { 5751, 0x2e9e }, + { 5760, 0xb9de }, { 5771, 0xcd8b }, { 5780, 0x07ff }, { 5791, 0xc475 }, + { 5799, 0xfaf0 }, { 5809, 0x74ff }, { 5821, 0x442f }, { 5828, 0xdd7f }, + /* 0x7100 */ + { 5841, 0xf9ff }, { 5855, 0xf896 }, { 5864, 0x7fbf }, { 5878, 0xffbc }, + { 5891, 0xabdf }, { 5903, 0xafff }, { 5917, 0xbe2f }, { 5928, 0xdaf3 }, + { 5939, 0x7bef }, { 5952, 0x7cef }, { 5964, 0xeefe }, { 5977, 0xfdd7 }, + { 5990, 0xbff7 }, { 6004, 0xffcf }, { 6018, 0xbf5e }, { 6030, 0xfdff }, + /* 0x7200 */ + { 6045, 0xffbf }, { 6060, 0xdfff }, { 6075, 0xeaff }, { 6088, 0x541c }, + { 6094, 0xce7f }, { 6106, 0x55bb }, { 6116, 0x3d39 }, { 6125, 0x39db }, + { 6135, 0x53ec }, { 6144, 0x7ffb }, { 6158, 0x4fff }, { 6171, 0xfc2e }, + { 6181, 0x9ee1 }, { 6190, 0xbd7a }, { 6201, 0x0cfc }, { 6209, 0xe260 }, + /* 0x7300 */ + { 6215, 0xbbf5 }, { 6227, 0x8717 }, { 6235, 0xa1d9 }, { 6243, 0x3c6d }, + { 6252, 0xdfff }, { 6267, 0xff7a }, { 6280, 0x4ffe }, { 6292, 0xbfff }, + { 6307, 0xb56f }, { 6318, 0x77bd }, { 6330, 0x35fb }, { 6341, 0xf372 }, + { 6351, 0x58fa }, { 6360, 0xbdfc }, { 6372, 0xdd5e }, { 6383, 0xfffb }, + /* 0x7400 */ + { 6398, 0x7997 }, { 6408, 0xf3fe }, { 6421, 0xaa9b }, { 6430, 0xef86 }, + { 6440, 0xfffd }, { 6455, 0x215f }, { 6463, 0xdfff }, { 6478, 0xbf3e }, + { 6490, 0xb774 }, { 6500, 0xaffe }, { 6513, 0xfc7f }, { 6526, 0xfbff }, + { 6541, 0xffff }, { 6557, 0xaffb }, { 6570, 0x3fa2 }, { 6579, 0x7f2f }, + /* 0x7500 */ + { 6591, 0x5fef }, { 6604, 0x68f5 }, { 6613, 0x44df }, { 6622, 0xb250 }, + { 6628, 0x26de }, { 6637, 0xe1ef }, { 6648, 0xfb9f }, { 6661, 0x7ceb }, + { 6672, 0x77b7 }, { 6684, 0x5929 }, { 6691, 0x27c4 }, { 6698, 0x8cc0 }, + { 6703, 0xd843 }, { 6710, 0xb68b }, { 6719, 0xf223 }, { 6727, 0x6dec }, + /* 0x7600 */ + { 6737, 0xebd4 }, { 6747, 0x745e }, { 6756, 0xd18a }, { 6763, 0x2ec6 }, + { 6771, 0xcff6 }, { 6783, 0xafaf }, { 6795, 0x77f7 }, { 6808, 0x96ff }, + { 6820, 0xb62b }, { 6829, 0xfdb5 }, { 6841, 0xbfef }, { 6855, 0x7fe9 }, + { 6867, 0x1a9b }, { 6875, 0x7628 }, { 6882, 0x3fdf }, { 6895, 0xace9 }, + /* 0x7700 */ + { 6904, 0xd46d }, { 6913, 0x79ff }, { 6926, 0x5cba }, { 6935, 0xea1f }, + { 6945, 0xff74 }, { 6957, 0xf3fc }, { 6969, 0xe691 }, { 6977, 0x1dff }, + { 6989, 0x8fce }, { 6999, 0x7ff9 }, { 7012, 0xe95a }, { 7021, 0x57d6 }, + { 7031, 0xdfff }, { 7046, 0xe77f }, { 7059, 0x8553 }, { 7066, 0x1eb7 }, + /* 0x7800 */ + { 7076, 0xcdf8 }, { 7086, 0x4a29 }, { 7092, 0xcd17 }, { 7101, 0xa06e }, + { 7108, 0xaf5e }, { 7119, 0xdf1a }, { 7129, 0x83ff }, { 7140, 0xef7f }, + { 7154, 0x8d7f }, { 7165, 0x6275 }, { 7173, 0xff55 }, { 7185, 0xbde0 }, + { 7194, 0xf1dd }, { 7205, 0xfdce }, { 7217, 0xeeff }, { 7231, 0xfb6b }, + /* 0x7900 */ + { 7243, 0xffdd }, { 7257, 0xbff7 }, { 7271, 0xffef }, { 7286, 0xa3ef }, + { 7297, 0xfcbc }, { 7308, 0x0337 }, { 7315, 0x5e5a }, { 7324, 0xfa7f }, + { 7337, 0x7bcc }, { 7347, 0xfbff }, { 7362, 0xff7f }, { 7377, 0x91f7 }, + { 7387, 0xd5b4 }, { 7396, 0x7ed9 }, { 7407, 0x5527 }, { 7415, 0xd6fe }, + /* 0x7a00 */ + { 7427, 0x97b2 }, { 7436, 0xbb6f }, { 7448, 0xfff6 }, { 7462, 0x4577 }, + { 7471, 0xffbf }, { 7486, 0xff7d }, { 7500, 0xffff }, { 7516, 0x782e }, + { 7524, 0xdea4 }, { 7533, 0x4e19 }, { 7540, 0xce9e }, { 7550, 0x7ff7 }, + { 7564, 0xf7ff }, { 7579, 0x3dbf }, { 7591, 0x5f96 }, { 7601, 0x59ff }, + /* 0x7b00 */ + { 7613, 0x72a7 }, { 7622, 0xb5cd }, { 7632, 0xa28e }, { 7639, 0xaaf5 }, + { 7649, 0x655f }, { 7659, 0xd2a8 }, { 7666, 0xbffa }, { 7679, 0xb559 }, + { 7688, 0xdfde }, { 7701, 0xcf4e }, { 7711, 0xc039 }, { 7717, 0xfeed }, + { 7730, 0xef3d }, { 7742, 0xd9f5 }, { 7753, 0xbb9d }, { 7764, 0xaf7d }, + /* 0x7c00 */ + { 7776, 0x677f }, { 7788, 0x7fbf }, { 7802, 0xfb3f }, { 7815, 0x7eff }, + { 7829, 0xdffc }, { 7842, 0xffff }, { 7858, 0xffff }, { 7874, 0xc7e7 }, + { 7885, 0xfdff }, { 7900, 0x0e59 }, { 7907, 0xbbcb }, { 7918, 0x8df1 }, + { 7927, 0xca5d }, { 7936, 0x6d1f }, { 7946, 0x7efe }, { 7959, 0xf6ff }, + /* 0x7d00 */ + { 7973, 0xfbff }, { 7988, 0xffff }, { 8004, 0x777a }, { 8015, 0xffff }, + { 8031, 0xffff }, { 8047, 0xffff }, { 8063, 0xbfff }, { 8078, 0xff7f }, + { 8093, 0xffff }, { 8109, 0xffff }, { 8125, 0xbfbf }, { 8139, 0xffff }, + { 8155, 0xffff }, { 8171, 0xffff }, { 8187, 0xffff }, { 8203, 0xffff }, + /* 0x7e00 */ + { 8219, 0xffff }, { 8235, 0xffff }, { 8251, 0xffff }, { 8267, 0xf7ff }, + { 8282, 0xff7d }, { 8296, 0xffff }, { 8312, 0xffff }, { 8328, 0xffff }, + { 8344, 0xfffb }, { 8359, 0x77ff }, { 8373, 0x4000 }, { 8374, 0x1810 }, + { 8377, 0x0000 }, { 8377, 0x0040 }, { 8378, 0x1010 }, { 8380, 0x0200 }, + /* 0x7f00 */ + { 8381, 0x0400 }, { 8382, 0x4001 }, { 8384, 0x0000 }, { 8384, 0xfa80 }, + { 8391, 0xffcb }, { 8404, 0x7a4c }, { 8412, 0xb8f9 }, { 8422, 0xbde9 }, + { 8433, 0xabfd }, { 8445, 0x1bef }, { 8456, 0x7f6d }, { 8468, 0x4cfa }, + { 8477, 0xabdd }, { 8488, 0x7ecf }, { 8500, 0xbd9c }, { 8510, 0xe7f4 }, + /* 0x8000 */ + { 8521, 0xc784 }, { 8528, 0xec0a }, { 8535, 0xf81a }, { 8543, 0x5615 }, + { 8550, 0xc3b3 }, { 8559, 0xfaeb }, { 8571, 0xf9ff }, { 8585, 0x7ffd }, + { 8599, 0xe526 }, { 8607, 0x42b7 }, { 8615, 0x11c8 }, { 8620, 0x0b69 }, + { 8627, 0x8fa0 }, { 8634, 0x813f }, { 8642, 0x404d }, { 8647, 0xcaa0 }, + /* 0x8100 */ + { 8653, 0x19bb }, { 8662, 0xbaa0 }, { 8669, 0x6fff }, { 8683, 0xbeb9 }, + { 8694, 0xe2bf }, { 8705, 0xf9c4 }, { 8714, 0x9d5e }, { 8724, 0x01ec }, + { 8730, 0x7afa }, { 8741, 0xc6fd }, { 8752, 0xfab7 }, { 8764, 0xf3f7 }, + { 8777, 0xebb0 }, { 8786, 0xffff }, { 8802, 0xcb77 }, { 8813, 0xa7e7 }, + /* 0x8200 */ + { 8824, 0xcf88 }, { 8832, 0x27ea }, { 8841, 0x42f1 }, { 8848, 0xb404 }, + { 8853, 0x756f }, { 8864, 0x7aff }, { 8877, 0x3eff }, { 8890, 0x19e2 }, + { 8897, 0x12eb }, { 8905, 0x4c79 }, { 8913, 0x008d }, { 8917, 0x9c64 }, + { 8924, 0x026d }, { 8930, 0x2641 }, { 8935, 0x7784 }, { 8943, 0xf56d }, + /* 0x8300 */ + { 8954, 0x2c01 }, { 8958, 0xe34d }, { 8967, 0x467f }, { 8977, 0xe885 }, + { 8984, 0x7d36 }, { 8994, 0x23e8 }, { 9001, 0x0004 }, { 9002, 0xc67f }, + { 9013, 0xbd9f }, { 9025, 0xa6f3 }, { 9035, 0xf0fe }, { 9046, 0xc820 }, + { 9050, 0x6b5c }, { 9059, 0x4eaf }, { 9069, 0xf9dc }, { 9080, 0xdcf8 }, + /* 0x8400 */ + { 9090, 0x07a5 }, { 9097, 0xcefd }, { 9109, 0xfe0f }, { 9120, 0xcefd }, + { 9132, 0xffbf }, { 9147, 0xe17d }, { 9157, 0xc5f5 }, { 9167, 0xfa95 }, + { 9177, 0xa47b }, { 9186, 0xed7f }, { 9199, 0x7ffd }, { 9213, 0x58eb }, + { 9222, 0xd9ed }, { 9233, 0x5fb4 }, { 9243, 0xef96 }, { 9254, 0x6ffe }, + /* 0x8500 */ + { 9267, 0xefff }, { 9282, 0x7b75 }, { 9293, 0xe7fd }, { 9306, 0xc07f }, + { 9315, 0xf8f7 }, { 9327, 0xbdbf }, { 9340, 0xfeef }, { 9354, 0xb1eb }, + { 9364, 0x7f4f }, { 9376, 0xe7ff }, { 9390, 0x3aef }, { 9401, 0xfd7e }, + { 9414, 0x7dfd }, { 9427, 0xefd6 }, { 9439, 0xfdef }, { 9453, 0x77ff }, + /* 0x8600 */ + { 9467, 0xffdf }, { 9482, 0xffbd }, { 9496, 0xfd7f }, { 9510, 0xeeff }, + { 9524, 0x1fff }, { 9537, 0xbbec }, { 9548, 0xa7fb }, { 9560, 0x01fd }, + { 9568, 0xc3f8 }, { 9577, 0xcfd7 }, { 9589, 0x6867 }, { 9597, 0xfb8c }, + { 9607, 0x312e }, { 9614, 0x34ec }, { 9622, 0x9def }, { 9634, 0xbce0 }, + /* 0x8700 */ + { 9642, 0xd872 }, { 9650, 0xaa53 }, { 9658, 0xbdd1 }, { 9668, 0x376d }, + { 9678, 0xac7f }, { 9689, 0xfd77 }, { 9702, 0xbfc6 }, { 9713, 0x87ae }, + { 9722, 0xd6d3 }, { 9732, 0x7f77 }, { 9745, 0x46ff }, { 9756, 0xdbd7 }, + { 9768, 0xf3be }, { 9780, 0xf7f1 }, { 9792, 0xbbde }, { 9804, 0xbdff }, + /* 0x8800 */ + { 9818, 0xfbf7 }, { 9832, 0xf797 }, { 9844, 0xfff9 }, { 9858, 0xedfb }, + { 9871, 0xcfce }, { 9882, 0xfd6f }, { 9895, 0xa4c1 }, { 9901, 0x1f7a }, + { 9911, 0xd6c9 }, { 9920, 0xefbb }, { 9933, 0xd7eb }, { 9945, 0xef7d }, + { 9958, 0xbd99 }, { 9968, 0x7ccb }, { 9978, 0xfec3 }, { 9989, 0xace4 }, + /* 0x8900 */ + { 9997, 0xfbfb }, { 10011, 0xf1f2 }, { 10021, 0xf3dd }, { 10033, 0xffae }, + { 10046, 0xffed }, { 10060, 0x3fff }, { 10074, 0xffbf }, { 10089, 0x77ff }, + { 10103, 0xffb5 }, { 10116, 0xffff }, { 10132, 0xffff }, { 10148, 0xffff }, + { 10164, 0x2009 }, { 10167, 0xabb8 }, { 10176, 0x7797 }, { 10187, 0xfff7 }, + /* 0x8a00 */ + { 10202, 0xff7e }, { 10216, 0xffff }, { 10232, 0xffff }, { 10248, 0xbfff }, + { 10263, 0xfeff }, { 10278, 0xffff }, { 10294, 0xffff }, { 10310, 0xfdff }, + { 10325, 0xf9ff }, { 10339, 0xfff7 }, { 10354, 0xffff }, { 10370, 0xffff }, + { 10386, 0xffff }, { 10402, 0xffff }, { 10418, 0xffff }, { 10434, 0xffff }, + /* 0x8b00 */ + { 10450, 0xff7f }, { 10465, 0xffff }, { 10481, 0xffbf }, { 10496, 0xffff }, + { 10512, 0xffff }, { 10528, 0xffff }, { 10544, 0xefbf }, { 10558, 0xffff }, + { 10574, 0xffff }, { 10590, 0xffff }, { 10606, 0x1000 }, { 10607, 0x0802 }, + { 10609, 0x0080 }, { 10610, 0x0001 }, { 10611, 0x0400 }, { 10612, 0x0000 }, + /* 0x8c00 */ + { 10612, 0x0200 }, { 10613, 0x4000 }, { 10614, 0x0000 }, { 10614, 0xff00 }, + { 10622, 0xed3d }, { 10633, 0xfbdf }, { 10647, 0xf3f9 }, { 10659, 0xf8f7 }, + { 10671, 0xe9db }, { 10682, 0xfeef }, { 10696, 0xffff }, { 10712, 0xffff }, + { 10728, 0xffff }, { 10744, 0xffff }, { 10760, 0xffff }, { 10776, 0xffff }, + /* 0x8d00 */ + { 10792, 0xffff }, { 10808, 0x1fff }, { 10821, 0x0001 }, { 10822, 0x0000 }, + { 10822, 0x0000 }, { 10822, 0x8086 }, { 10826, 0xd720 }, { 10833, 0xff06 }, + { 10843, 0xf3cd }, { 10854, 0x7fed }, { 10867, 0xfff7 }, { 10882, 0x2ac5 }, + { 10889, 0x27a7 }, { 10898, 0x133d }, { 10906, 0x62e7 }, { 10915, 0xd057 }, + /* 0x8e00 */ + { 10923, 0x69df }, { 10934, 0x1fef }, { 10946, 0x29f3 }, { 10955, 0xd9dd }, + { 10966, 0xf068 }, { 10973, 0xfdf9 }, { 10986, 0x4dbf }, { 10997, 0x6faa }, + { 11007, 0x7f5d }, { 11019, 0xafee }, { 11031, 0x67ff }, { 11044, 0xfbfb }, + { 11058, 0xbfff }, { 11073, 0xffff }, { 11089, 0xffff }, { 11105, 0xffff }, + /* 0x8f00 */ + { 11121, 0xffff }, { 11137, 0xffff }, { 11153, 0xffff }, { 11169, 0xffff }, + { 11185, 0xffff }, { 11201, 0xffff }, { 11217, 0x043f }, { 11224, 0x0000 }, + { 11224, 0x1001 }, { 11226, 0x2004 }, { 11228, 0xf4f7 }, { 11240, 0x9dbc }, + { 11250, 0xbe49 }, { 11259, 0x04c4 }, { 11263, 0x908b }, { 11269, 0xdc76 }, + /* 0x9000 */ + { 11279, 0x5180 }, { 11283, 0x1328 }, { 11288, 0x1fb8 }, { 11297, 0xa69f }, + { 11307, 0x5f69 }, { 11317, 0xf670 }, { 11326, 0x9ed3 }, { 11336, 0x5fcf }, + { 11348, 0xf6f2 }, { 11359, 0xd555 }, { 11368, 0x2bb1 }, { 11376, 0xb084 }, + { 11381, 0x3b4d }, { 11390, 0xc774 }, { 11399, 0x5639 }, { 11407, 0x9eef }, + /* 0x9100 */ + { 11419, 0xffeb }, { 11433, 0xbdff }, { 11447, 0x7ff3 }, { 11460, 0xfdfd }, + { 11474, 0x01b7 }, { 11481, 0x9b7a }, { 11491, 0x29c1 }, { 11497, 0x1c08 }, + { 11501, 0xc55f }, { 11511, 0xf3f8 }, { 11522, 0x1bf3 }, { 11532, 0xfbcf }, + { 11545, 0x097f }, { 11554, 0xeffd }, { 11568, 0xffff }, { 11584, 0xffff }, + /* 0x9200 */ + { 11600, 0xffff }, { 11616, 0xffff }, { 11632, 0xffff }, { 11648, 0xffff }, + { 11664, 0xffff }, { 11680, 0xffff }, { 11696, 0xffff }, { 11712, 0xffef }, + { 11727, 0xbfff }, { 11742, 0xffff }, { 11758, 0xbfff }, { 11773, 0xffff }, + { 11789, 0xfeff }, { 11804, 0xffff }, { 11820, 0xffff }, { 11836, 0xffff }, + /* 0x9300 */ + { 11852, 0xffff }, { 11868, 0xffff }, { 11884, 0xffff }, { 11900, 0xbfff }, + { 11915, 0xffff }, { 11931, 0xffff }, { 11947, 0xfbff }, { 11962, 0xffff }, + { 11978, 0x7fff }, { 11993, 0xffff }, { 12009, 0xffff }, { 12025, 0xffff }, + { 12041, 0xfbff }, { 12056, 0xffbf }, { 12071, 0xffff }, { 12087, 0xffff }, + /* 0x9400 */ + { 12103, 0xffff }, { 12119, 0xffff }, { 12135, 0xffff }, { 12151, 0xbfff }, + { 12166, 0xffff }, { 12182, 0xffff }, { 12198, 0xf7ff }, { 12213, 0xffff }, + { 12229, 0x001f }, { 12234, 0x0142 }, { 12237, 0x0000 }, { 12237, 0x0000 }, + { 12237, 0x8080 }, { 12239, 0x0418 }, { 12242, 0x0040 }, { 12243, 0x0800 }, + /* 0x9500 */ + { 12244, 0x0000 }, { 12244, 0x1000 }, { 12245, 0x0081 }, { 12247, 0x2008 }, + { 12249, 0x0908 }, { 12252, 0x0420 }, { 12254, 0x4001 }, { 12256, 0x7fb0 }, + { 12266, 0xffff }, { 12282, 0xffff }, { 12298, 0xffff }, { 12314, 0xffff }, + { 12330, 0xffff }, { 12346, 0xffff }, { 12362, 0x10ff }, { 12371, 0x8000 }, + /* 0x9600 */ + { 12372, 0x0080 }, { 12373, 0x4908 }, { 12377, 0xbbf9 }, { 12389, 0x4781 }, + { 12395, 0xc40a }, { 12400, 0x77ce }, { 12411, 0xe869 }, { 12419, 0xff0b }, + { 12430, 0x569f }, { 12440, 0xec6e }, { 12450, 0xff7f }, { 12465, 0x8db6 }, + { 12474, 0x0d0c }, { 12479, 0xffdb }, { 12493, 0x78fe }, { 12504, 0xbd37 }, + /* 0x9700 */ + { 12515, 0x1c2c }, { 12521, 0xafb7 }, { 12533, 0xdbff }, { 12547, 0xbcfa }, + { 12558, 0xffff }, { 12574, 0xb5b3 }, { 12584, 0xfdd8 }, { 12595, 0xefa7 }, + { 12607, 0xd7df }, { 12620, 0xfee9 }, { 12632, 0x57f6 }, { 12643, 0xffeb }, + { 12657, 0xffff }, { 12673, 0xffff }, { 12689, 0xc13f }, { 12698, 0xff97 }, + /* 0x9800 */ + { 12711, 0xffff }, { 12727, 0xffff }, { 12743, 0xffff }, { 12759, 0xffff }, + { 12775, 0xffff }, { 12791, 0xffff }, { 12807, 0xffff }, { 12823, 0x001f }, + { 12828, 0x4800 }, { 12830, 0x0224 }, { 12833, 0xff08 }, { 12842, 0xffff }, + { 12858, 0xbfff }, { 12873, 0x38d1 }, { 12880, 0xfe7f }, { 12894, 0xffff }, + /* 0x9900 */ + { 12910, 0xdfff }, { 12925, 0xfffe }, { 12940, 0xbfff }, { 12955, 0xffff }, + { 12971, 0xffff }, { 12987, 0xffcf }, { 13001, 0x0057 }, { 13006, 0x4b08 }, + { 13011, 0x520c }, { 13016, 0xfc00 }, { 13022, 0xfedf }, { 13036, 0xffff }, + { 13052, 0xffff }, { 13068, 0xffff }, { 13084, 0xffff }, { 13100, 0xffff }, + /* 0x9a00 */ + { 13116, 0xffff }, { 13132, 0xffff }, { 13148, 0xffff }, { 13164, 0xffff }, + { 13180, 0xffff }, { 13196, 0xffff }, { 13212, 0x0fff }, { 13224, 0x0004 }, + { 13225, 0x6208 }, { 13229, 0x0230 }, { 13232, 0xfe40 }, { 13240, 0xea3c }, + { 13249, 0xe7d8 }, { 13259, 0x7ef5 }, { 13271, 0x57bd }, { 13282, 0xf5ff }, + /* 0x9b00 */ + { 13296, 0x7ef7 }, { 13309, 0x7ff7 }, { 13323, 0x7ff7 }, { 13337, 0xe7fb }, + { 13350, 0x5c41 }, { 13356, 0xffed }, { 13370, 0xffff }, { 13386, 0xffff }, + { 13402, 0xffff }, { 13418, 0xffff }, { 13434, 0xffff }, { 13450, 0xffff }, + { 13466, 0xffff }, { 13482, 0xffff }, { 13498, 0xffff }, { 13514, 0xffff }, + /* 0x9c00 */ + { 13530, 0xffff }, { 13546, 0xffff }, { 13562, 0xffff }, { 13578, 0xffff }, + { 13594, 0xffff }, { 13610, 0xffff }, { 13626, 0xffff }, { 13642, 0x6fff }, + { 13656, 0x9619 }, { 13663, 0x23c8 }, { 13669, 0x9400 }, { 13672, 0xc200 }, + { 13675, 0x0307 }, { 13680, 0x0c06 }, { 13684, 0xfffb }, { 13699, 0xffff }, + /* 0x9d00 */ + { 13715, 0xffff }, { 13731, 0xffff }, { 13747, 0xffff }, { 13763, 0xffff }, + { 13779, 0xffff }, { 13795, 0xffff }, { 13811, 0xffff }, { 13827, 0xffff }, + { 13843, 0xffff }, { 13859, 0xffff }, { 13875, 0xffff }, { 13891, 0xffff }, + { 13907, 0xffff }, { 13923, 0xffff }, { 13939, 0xffff }, { 13955, 0xffff }, + /* 0x9e00 */ + { 13971, 0xffff }, { 13987, 0x7fff }, { 14002, 0x4090 }, { 14005, 0x1811 }, + { 14009, 0x2001 }, { 14011, 0xa25d }, { 14019, 0xc027 }, { 14025, 0x3ff4 }, + { 14036, 0xf67b }, { 14048, 0x5ff3 }, { 14060, 0xffbf }, { 14075, 0x96ef }, + { 14086, 0x1def }, { 14097, 0x46ed }, { 14106, 0x795a }, { 14115, 0xa5ff }, + /* 0x9f00 */ + { 14127, 0x97ff }, { 14140, 0xfd76 }, { 14152, 0x6ffa }, { 14164, 0x957f }, + { 14175, 0xffef }, { 14190, 0xfffc }, { 14204, 0xffff }, { 14220, 0x7fff }, + { 14235, 0xe006 }, { 14240, 0x71ff }, { 14252, 0x003e }, +}; +static const Summary16 gbkext_inv_uni2indx_pagef9[19] = { + /* 0xf900 */ + { 14257, 0x0000 }, { 14257, 0x0000 }, { 14257, 0x1000 }, { 14258, 0x0000 }, + { 14258, 0x0000 }, { 14258, 0x0000 }, { 14258, 0x0000 }, { 14258, 0x0200 }, + { 14259, 0x0000 }, { 14259, 0x0020 }, { 14260, 0x0000 }, { 14260, 0x0000 }, + { 14260, 0x0000 }, { 14260, 0x0000 }, { 14260, 0x0080 }, { 14261, 0x0002 }, + /* 0xfa00 */ + { 14262, 0xf000 }, { 14266, 0x811a }, { 14271, 0x039b }, +}; +static const Summary16 gbkext_inv_uni2indx_pagefe[31] = { + /* 0xfe00 */ + { 14278, 0x0000 }, { 14278, 0x0000 }, { 14278, 0x0000 }, { 14278, 0x0001 }, + { 14279, 0xfe00 }, { 14286, 0xfef7 }, { 14300, 0x0f7f }, { 14311, 0x0000 }, + { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, + { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, + /* 0xff00 */ + { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, + { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, + { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0000 }, + { 14311, 0x0000 }, { 14311, 0x0000 }, { 14311, 0x0014 }, +}; + +static int +gbkext_inv_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc >= 0x0200 && wc < 0x02e0) + summary = &gbkext_inv_uni2indx_page02[(wc>>4)-0x020]; + else if (wc >= 0x2000 && wc < 0x22c0) + summary = &gbkext_inv_uni2indx_page20[(wc>>4)-0x200]; + else if (wc >= 0x2500 && wc < 0x2610) + summary = &gbkext_inv_uni2indx_page25[(wc>>4)-0x250]; + else if (wc >= 0x3000 && wc < 0x3100) + summary = &gbkext_inv_uni2indx_page30[(wc>>4)-0x300]; + else if (wc >= 0x3200 && wc < 0x33e0) + summary = &gbkext_inv_uni2indx_page32[(wc>>4)-0x320]; + else if (wc >= 0x4e00 && wc < 0x9fb0) + summary = &gbkext_inv_uni2indx_page4e[(wc>>4)-0x4e0]; + else if (wc >= 0xf900 && wc < 0xfa30) + summary = &gbkext_inv_uni2indx_pagef9[(wc>>4)-0xf90]; + else if (wc >= 0xfe00 && wc < 0xfff0) + summary = &gbkext_inv_uni2indx_pagefe[(wc>>4)-0xfe0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = gbkext_inv_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/genaliases.c b/libs/libiconv/lib/genaliases.c new file mode 100644 index 00000000..b54b97d5 --- /dev/null +++ b/libs/libiconv/lib/genaliases.c @@ -0,0 +1,104 @@ +/* Copyright (C) 1999-2001, 2003, 2005, 2008 Free Software Foundation, Inc. + This file is part of the GNU LIBICONV Library. + + The GNU LIBICONV Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + The GNU LIBICONV Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU LIBICONV Library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Creates the aliases.gperf table. */ + +#include +#include + +static void emit_alias (FILE* out1, const char* alias, const char* c_name) +{ + /* Output alias in upper case. */ + const char* s = alias; + for (; *s; s++) { + unsigned char c = * (unsigned char *) s; + if (c >= 0x80) + exit(1); + if (c >= 'a' && c <= 'z') + c -= 'a'-'A'; + putc(c, out1); + } + fprintf(out1,", ei_%s\n", c_name); +} + +static void emit_encoding (FILE* out1, FILE* out2, const char* const* names, size_t n, const char* c_name) +{ + fprintf(out2,"grep 'sizeof(\""); + /* Output *names in upper case. */ + { + const char* s = *names; + for (; *s; s++) { + unsigned char c = * (unsigned char *) s; + if (c >= 0x80) + exit(1); + if (c >= 'a' && c <= 'z') + c -= 'a'-'A'; + putc(c, out2); + } + } + fprintf(out2,"\")' tmp.h | sed -e 's|^.*\\(stringpool_str[0-9]*\\).*$| (int)(long)\\&((struct stringpool_t *)0)->\\1,|'\n"); + for (; n > 0; names++, n--) + emit_alias(out1, *names, c_name); +} + +int main () +{ + FILE* stdout2; + + printf("struct alias { int name; unsigned int encoding_index; };\n"); + printf("%%struct-type\n"); + printf("%%language=ANSI-C\n"); + printf("%%define hash-function-name aliases_hash\n"); + printf("%%define lookup-function-name aliases_lookup\n"); + printf("%%7bit\n"); + printf("%%readonly-tables\n"); + printf("%%global-table\n"); + printf("%%define word-array-name aliases\n"); + printf("%%pic\n"); + printf("%%%%\n"); + +#define DEFENCODING(xxx_names,xxx,xxx_ifuncs1,xxx_ifuncs2,xxx_ofuncs1,xxx_ofuncs2) \ + { \ + static const char* const names[] = BRACIFY xxx_names; \ + emit_encoding(stdout,stdout2,names,sizeof(names)/sizeof(names[0]),#xxx); \ + } +#define BRACIFY(...) { __VA_ARGS__ } +#define DEFALIAS(xxx_alias,xxx) emit_alias(stdout,xxx_alias,#xxx); + + stdout2 = fdopen(3, "w"); + if (stdout2 == NULL) + exit(1); +#include "encodings.def" + if (fclose(stdout2)) + exit(1); + + stdout2 = fdopen(4, "w"); + if (stdout2 == NULL) + exit(1); +#include "encodings_local.def" + if (fclose(stdout2)) + exit(1); + +#undef DEFALIAS +#undef BRACIFY +#undef DEFENCODING + + if (ferror(stdout) || fclose(stdout)) + exit(1); + exit(0); +} diff --git a/libs/libiconv/lib/genaliases2.c b/libs/libiconv/lib/genaliases2.c new file mode 100644 index 00000000..1b789ed9 --- /dev/null +++ b/libs/libiconv/lib/genaliases2.c @@ -0,0 +1,83 @@ +/* Copyright (C) 1999-2003, 2005, 2008 Free Software Foundation, Inc. + This file is part of the GNU LIBICONV Library. + + The GNU LIBICONV Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + The GNU LIBICONV Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU LIBICONV Library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Creates the aliases2.h table. */ + +#include +#include + +static unsigned int counter = 0; + +static void emit_alias (FILE* out1, const char* tag, const char* alias, const char* c_name) +{ + fprintf(out1," S(%s_%u, \"",tag,counter); + /* Output alias in upper case. */ + { + const char* s = alias; + for (; *s; s++) { + unsigned char c = * (unsigned char *) s; + if (c >= 0x80) + exit(1); + if (c >= 'a' && c <= 'z') + c -= 'a'-'A'; + putc(c, out1); + } + } + fprintf(out1,"\", ei_%s )\n", c_name); + counter++; +} + +static void emit_encoding (FILE* out1, FILE* out2, const char* tag, const char* const* names, size_t n, const char* c_name) +{ + fprintf(out2," (int)(long)&((struct stringpool2_t *)0)->stringpool_%s_%u,\n",tag,counter); + for (; n > 0; names++, n--) + emit_alias(out1, tag, *names, c_name); +} + +int main (int argc, char* argv[]) +{ + const char * tag = (argc > 1 ? argv[1] : "xxx"); + FILE * stdout2 = fdopen(3, "w"); + if (stdout2 == NULL) + exit(1); +#define DEFENCODING(xxx_names,xxx,xxx_ifuncs1,xxx_ifuncs2,xxx_ofuncs1,xxx_ofuncs2) \ + { \ + static const char* const names[] = BRACIFY xxx_names; \ + emit_encoding(stdout,stdout2,tag,names,sizeof(names)/sizeof(names[0]),#xxx); \ + } +#define BRACIFY(...) { __VA_ARGS__ } +#define DEFALIAS(xxx_alias,xxx) emit_alias(stdout,tag,xxx_alias,#xxx); +#ifdef USE_AIX +#include "encodings_aix.def" +#endif +#ifdef USE_OSF1 +#include "encodings_osf1.def" +#endif +#ifdef USE_DOS +#include "encodings_dos.def" +#endif +#ifdef USE_EXTRA +#include "encodings_extra.def" +#endif +#undef DEFALIAS +#undef BRACIFY +#undef DEFENCODING + if (ferror(stdout) || fclose(stdout) || ferror(stdout2) || fclose(stdout2)) + exit(1); + exit(0); +} diff --git a/libs/libiconv/lib/genflags.c b/libs/libiconv/lib/genflags.c new file mode 100644 index 00000000..448f8928 --- /dev/null +++ b/libs/libiconv/lib/genflags.c @@ -0,0 +1,114 @@ +/* Copyright (C) 2000-2002, 2005-2006, 2008-2009 Free Software Foundation, Inc. + This file is part of the GNU LIBICONV Library. + + The GNU LIBICONV Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + The GNU LIBICONV Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU LIBICONV Library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* Creates the flags.h include file. */ + +#include +#include +#include + +/* Consider all encodings, including the system dependent ones. */ +#define USE_AIX +#define USE_OSF1 +#define USE_DOS +#define USE_EXTRA + +struct loop_funcs {}; +struct iconv_fallbacks {}; +struct iconv_hooks {}; +#include "converters.h" + +static void emit_encoding (struct wctomb_funcs * ofuncs, const char* c_name) +{ + /* Prepare a converter struct. */ + struct conv_struct conv; + memset(&conv,'\0',sizeof(conv)); + conv.ofuncs = *ofuncs; + + { + /* See whether the encoding can encode the accents and quotation marks. */ + ucs4_t probe[6] = { 0x0060, 0x00b4, 0x2018, 0x2019, 0x3131, 0x3163, }; + int res[6]; + int i; + for (i = 0; i < 6; i++) { + unsigned char buf[10]; + memset(&conv.ostate,'\0',sizeof(state_t)); + res[i] = (conv.ofuncs.xxx_wctomb(&conv,buf,probe[i],sizeof(buf)) != RET_ILUNI); + } + printf("#define ei_%s_oflags (",c_name); + { + int first = 1; + if (res[0] && res[1]) { + printf("HAVE_ACCENTS"); + first = 0; + } + if (res[2] && res[3]) { + if (!first) printf(" | "); + printf("HAVE_QUOTATION_MARKS"); + first = 0; + } + if (res[4] && res[5]) { + if (!first) printf(" | "); + printf("HAVE_HANGUL_JAMO"); + first = 0; + } + if (first) printf("0"); + } + printf(")\n"); + } +} + +int main () +{ + int bitmask = 1; + printf("/* Generated automatically by genflags. */\n"); + printf("\n"); + printf("/* Set if the encoding can encode\n"); + printf(" the acute and grave accents U+00B4 and U+0060. */\n"); + printf("#define HAVE_ACCENTS %d\n",bitmask); + printf("\n"); + bitmask = bitmask << 1; + printf("/* Set if the encoding can encode\n"); + printf(" the single quotation marks U+2018 and U+2019. */\n"); + printf("#define HAVE_QUOTATION_MARKS %d\n",bitmask); + printf("\n"); + bitmask = bitmask << 1; + printf("/* Set if the encoding can encode\n"); + printf(" the double-width Hangul letters (Jamo) U+3131 to U+3163. */\n"); + printf("#define HAVE_HANGUL_JAMO %d\n",bitmask); + printf("\n"); + +#define DEFENCODING(xxx_names,xxx,xxx_ifuncs1,xxx_ifuncs2,xxx_ofuncs1,xxx_ofuncs2) \ + { \ + struct wctomb_funcs ofuncs = xxx_ofuncs1,xxx_ofuncs2; \ + emit_encoding(&ofuncs,#xxx); \ + } +#define DEFALIAS(xxx_alias,xxx) /* nothing */ +/* Consider all encodings, including the system dependent ones. */ +#include "encodings.def" +#include "encodings_aix.def" +#include "encodings_osf1.def" +#include "encodings_dos.def" +#include "encodings_extra.def" +#undef DEFALIAS +#undef DEFENCODING + + if (ferror(stdout) || fclose(stdout)) + exit(1); + exit(0); +} diff --git a/libs/libiconv/lib/gentranslit.c b/libs/libiconv/lib/gentranslit.c new file mode 100644 index 00000000..0b2779c7 --- /dev/null +++ b/libs/libiconv/lib/gentranslit.c @@ -0,0 +1,258 @@ +/* Copyright (C) 1999-2003, 2005, 2011 Free Software Foundation, Inc. + This file is part of the GNU LIBICONV Library. + + The GNU LIBICONV Library is free software; you can redistribute it + and/or modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + The GNU LIBICONV Library is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU LIBICONV Library; see the file COPYING.LIB. + If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + Fifth Floor, Boston, MA 02110-1301, USA. */ + +/* + * Generates a table of small strings, used for transliteration, from a table + * containing lines of the form + * Unicode utf-8 replacement # comment + */ + +#include +#include +#include + +int main (int argc, char *argv[]) +{ + unsigned int data[0x100000]; + int uni2index[0x110000]; + int index; + + if (argc != 1) + exit(1); + + printf("/*\n"); + printf(" * Copyright (C) 1999-2003 Free Software Foundation, Inc.\n"); + printf(" * This file is part of the GNU LIBICONV Library.\n"); + printf(" *\n"); + printf(" * The GNU LIBICONV Library is free software; you can redistribute it\n"); + printf(" * and/or modify it under the terms of the GNU Library General Public\n"); + printf(" * License as published by the Free Software Foundation; either version 2\n"); + printf(" * of the License, or (at your option) any later version.\n"); + printf(" *\n"); + printf(" * The GNU LIBICONV Library is distributed in the hope that it will be\n"); + printf(" * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of\n"); + printf(" * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"); + printf(" * Library General Public License for more details.\n"); + printf(" *\n"); + printf(" * You should have received a copy of the GNU Library General Public\n"); + printf(" * License along with the GNU LIBICONV Library; see the file COPYING.LIB.\n"); + printf(" * If not, write to the Free Software Foundation, Inc., 51 Franklin Street,\n"); + printf(" * Fifth Floor, Boston, MA 02110-1301, USA.\n"); + printf(" */\n"); + printf("\n"); + printf("/*\n"); + printf(" * Transliteration table\n"); + printf(" */\n"); + printf("\n"); + { + int c; + int j; + for (j = 0; j < 0x110000; j++) + uni2index[j] = -1; + index = 0; + for (;;) { + c = getc(stdin); + if (c == EOF) + break; + if (c == '#') { + do { c = getc(stdin); } while (!(c == EOF || c == '\n')); + continue; + } + ungetc(c,stdin); + if (scanf("%x",&j) != 1) + exit(1); + c = getc(stdin); + if (c != '\t') + exit(1); + for (;;) { + c = getc(stdin); + if (c == EOF || c == '\n') + exit(1); + if (c == '\t') + break; + if (uni2index[j] < 0) { + uni2index[j] = index; + data[index++] = 0; + } + if (c >= 0x80) { + /* Finish reading an UTF-8 character. */ + if (c < 0xc0) + exit(1); + else { + unsigned int i = (c < 0xe0 ? 2 : c < 0xf0 ? 3 : c < 0xf8 ? 4 : c < 0xfc ? 5 : 6); + c &= (1 << (8-i)) - 1; + while (--i > 0) { + int cc = getc(stdin); + if (!(cc >= 0x80 && cc < 0xc0)) + exit(1); + c <<= 6; c |= (cc & 0x3f); + } + } + } + data[index++] = (unsigned int) c; + } + if (uni2index[j] >= 0) + data[uni2index[j]] = index - uni2index[j] - 1; + do { c = getc(stdin); } while (!(c == EOF || c == '\n')); + } + } + printf("static const unsigned int translit_data[%d] = {",index); + { + int i; + for (i = 0; i < index; i++) { + if (data[i] < 32) + printf("\n %3d,",data[i]); + else if (data[i] == '\'') + printf("'\\'',"); + else if (data[i] == '\\') + printf("'\\\\',"); + else if (data[i] < 127) + printf(" '%c',",data[i]); + else if (data[i] < 256) + printf("0x%02X,",data[i]); + else + printf("0x%04X,",data[i]); + } + printf("\n};\n"); + } + printf("\n"); + { + bool pages[0x1100]; + int line[0x22000]; + int tableno; + struct { int minline; int maxline; int usecount; const char* suffix; } tables[0x2000]; + int i, j, p, j1, j2, t; + + for (p = 0; p < 0x1100; p++) + pages[p] = false; + for (j = 0; j < 0x110000; j++) + if (uni2index[j] >= 0) + pages[j>>8] = true; + for (j1 = 0; j1 < 0x22000; j1++) { + bool all_invalid = true; + for (j2 = 0; j2 < 8; j2++) { + j = 8*j1+j2; + if (uni2index[j] >= 0) + all_invalid = false; + } + if (all_invalid) + line[j1] = -1; + else + line[j1] = 0; + } + tableno = 0; + for (j1 = 0; j1 < 0x22000; j1++) { + if (line[j1] >= 0) { + if (tableno > 0 + && ((j1 > 0 && line[j1-1] == tableno-1) + || ((tables[tableno-1].maxline >> 5) == (j1 >> 5) + && j1 - tables[tableno-1].maxline <= 8))) { + line[j1] = tableno-1; + tables[tableno-1].maxline = j1; + } else { + tableno++; + line[j1] = tableno-1; + tables[tableno-1].minline = tables[tableno-1].maxline = j1; + } + } + } + for (t = 0; t < tableno; t++) { + tables[t].usecount = 0; + j1 = 8*tables[t].minline; + j2 = 8*(tables[t].maxline+1); + for (j = j1; j < j2; j++) + if (uni2index[j] >= 0) + tables[t].usecount++; + } + for (t = 0, p = -1, i = 0; t < tableno; t++) { + if (tables[t].usecount > 1) { + char* s; + if (p == tables[t].minline >> 5) { + s = (char*) malloc(4+1+2+1); + sprintf(s, "%02x_%d", p, ++i); + } else { + p = tables[t].minline >> 5; + s = (char*) malloc(4+1); + sprintf(s, "%02x", p); + } + tables[t].suffix = s; + } else + tables[t].suffix = NULL; + } + { + p = -1; + for (t = 0; t < tableno; t++) + if (tables[t].usecount > 1) { + p = 0; + printf("static const short translit_page%s[%d] = {\n", tables[t].suffix, 8*(tables[t].maxline-tables[t].minline+1)); + for (j1 = tables[t].minline; j1 <= tables[t].maxline; j1++) { + if ((j1 % 0x20) == 0 && j1 > tables[t].minline) + printf(" /* 0x%04x */\n", 8*j1); + printf(" "); + for (j2 = 0; j2 < 8; j2++) { + j = 8*j1+j2; + printf(" %4d,", uni2index[j]); + } + printf(" /* 0x%02x-0x%02x */\n", 8*(j1 % 0x20), 8*(j1 % 0x20)+7); + } + printf("};\n"); + } + if (p >= 0) + printf("\n"); + } + printf("#define translit_index(wc) \\\n ("); + for (j1 = 0; j1 < 0x22000;) { + t = line[j1]; + for (j2 = j1; j2 < 0x22000 && line[j2] == t; j2++); + if (t >= 0) { + if (j1 != tables[t].minline) abort(); + if (j2 > tables[t].maxline+1) abort(); + j2 = tables[t].maxline+1; + } + if (t == -1) { + } else { + if (t >= 0 && tables[t].usecount == 0) abort(); + if (t >= 0 && tables[t].usecount == 1) { + if (j2 != j1+1) abort(); + for (j = 8*j1; j < 8*j2; j++) + if (uni2index[j] >= 0) { + printf("wc == 0x%04x ? %d", j, uni2index[j]); + break; + } + } else { + if (j1 == 0) { + printf("wc < 0x%04x", 8*j2); + } else { + printf("wc >= 0x%04x && wc < 0x%04x", 8*j1, 8*j2); + } + printf(" ? translit_page%s[wc", tables[t].suffix); + if (tables[t].minline > 0) + printf("-0x%04x", 8*j1); + printf("]"); + } + printf(" : \\\n "); + } + j1 = j2; + } + printf("-1)\n"); + } + + if (ferror(stdout) || fclose(stdout)) + exit(1); + exit(0); +} diff --git a/libs/libiconv/lib/georgian_academy.h b/libs/libiconv/lib/georgian_academy.h new file mode 100644 index 00000000..ddbe5780 --- /dev/null +++ b/libs/libiconv/lib/georgian_academy.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * GEORGIAN-ACADEMY + */ + +static const unsigned short georgian_academy_2uni[32] = { + /* 0x80 */ + 0x0080, 0x0081, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008d, 0x008e, 0x008f, + /* 0x90 */ + 0x0090, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x009d, 0x009e, 0x0178, +}; + +static int +georgian_academy_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0x80 && c < 0xa0) + *pwc = (ucs4_t) georgian_academy_2uni[c-0x80]; + else if (c >= 0xc0 && c < 0xe7) + *pwc = (ucs4_t) c + 0x1010; + else + *pwc = (ucs4_t) c; + return 1; +} + +static const unsigned char georgian_academy_page00[32] = { + 0x80, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x9e, 0x00, /* 0x98-0x9f */ +}; +static const unsigned char georgian_academy_page01[72] = { + 0x00, 0x00, 0x8c, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x8a, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char georgian_academy_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char georgian_academy_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +georgian_academy_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x0080 && wc < 0x00a0) + c = georgian_academy_page00[wc-0x0080]; + else if ((wc >= 0x00a0 && wc < 0x00c0) || (wc >= 0x00e7 && wc < 0x0100)) + c = wc; + else if (wc >= 0x0150 && wc < 0x0198) + c = georgian_academy_page01[wc-0x0150]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = georgian_academy_page02[wc-0x02c0]; + else if (wc >= 0x10d0 && wc < 0x10f7) + c = wc-0x1010; + else if (wc >= 0x2010 && wc < 0x2040) + c = georgian_academy_page20[wc-0x2010]; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/georgian_ps.h b/libs/libiconv/lib/georgian_ps.h new file mode 100644 index 00000000..e23dbae1 --- /dev/null +++ b/libs/libiconv/lib/georgian_ps.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * GEORGIAN-PS + */ + +static const unsigned short georgian_ps_2uni_1[32] = { + /* 0x80 */ + 0x0080, 0x0081, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x008d, 0x008e, 0x008f, + /* 0x90 */ + 0x0090, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x009d, 0x009e, 0x0178, +}; +static const unsigned short georgian_ps_2uni_2[39] = { + /* 0xc0 */ + 0x10d0, 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10f1, + 0x10d7, 0x10d8, 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10f2, 0x10dd, + /* 0xd0 */ + 0x10de, 0x10df, 0x10e0, 0x10e1, 0x10e2, 0x10f3, 0x10e3, 0x10e4, + 0x10e5, 0x10e6, 0x10e7, 0x10e8, 0x10e9, 0x10ea, 0x10eb, 0x10ec, + /* 0xe0 */ + 0x10ed, 0x10ee, 0x10f4, 0x10ef, 0x10f0, 0x10f5, +}; + +static int +georgian_ps_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0x80 && c < 0xa0) + *pwc = (ucs4_t) georgian_ps_2uni_1[c-0x80]; + else if (c >= 0xc0 && c < 0xe6) + *pwc = (ucs4_t) georgian_ps_2uni_2[c-0xc0]; + else + *pwc = (ucs4_t) c; + return 1; +} + +static const unsigned char georgian_ps_page00[32] = { + 0x80, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x8d, 0x8e, 0x8f, /* 0x88-0x8f */ + 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x9d, 0x9e, 0x00, /* 0x98-0x9f */ +}; +static const unsigned char georgian_ps_page01[72] = { + 0x00, 0x00, 0x8c, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x8a, 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x9f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char georgian_ps_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char georgian_ps_page10[40] = { + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc8, /* 0xd0-0xd7 */ + 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xcf, 0xd0, 0xd1, /* 0xd8-0xdf */ + 0xd2, 0xd3, 0xd4, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, /* 0xe0-0xe7 */ + 0xdb, 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe1, 0xe3, /* 0xe8-0xef */ + 0xe4, 0xc7, 0xce, 0xd5, 0xe2, 0xe5, 0x00, 0x00, /* 0xf0-0xf7 */ +}; +static const unsigned char georgian_ps_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; + +static int +georgian_ps_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x0080 && wc < 0x00a0) + c = georgian_ps_page00[wc-0x0080]; + else if ((wc >= 0x00a0 && wc < 0x00c0) || (wc >= 0x00e6 && wc < 0x0100)) + c = wc; + else if (wc >= 0x0150 && wc < 0x0198) + c = georgian_ps_page01[wc-0x0150]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = georgian_ps_page02[wc-0x02c0]; + else if (wc >= 0x10d0 && wc < 0x10f8) + c = georgian_ps_page10[wc-0x10d0]; + else if (wc >= 0x2010 && wc < 0x2040) + c = georgian_ps_page20[wc-0x2010]; + else if (wc == 0x2122) + c = 0x99; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/hkscs1999.h b/libs/libiconv/lib/hkscs1999.h new file mode 100644 index 00000000..37327633 --- /dev/null +++ b/libs/libiconv/lib/hkscs1999.h @@ -0,0 +1,3005 @@ +/* + * Copyright (C) 1999-2006 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * HKSCS:1999 + */ + +static const unsigned short hkscs1999_2uni_page88[627] = { + /* 0x88 */ + 0x06c0, 0x06c1, 0x06c2, 0x06c3, 0x06c4, 0x720c, 0x06c5, 0x71d1, + 0x71cd, 0x06c6, 0x06c7, 0x71cb, 0x8c68, 0x06c8, 0x71ca, 0x06c9, + 0x06ca, 0x06cb, 0x06cc, 0x720e, 0x06cd, 0x06ce, 0x0080, 0x0041, + 0x010d, 0x0040, 0x0092, 0x0049, 0x009a, 0x0048, 0x00cc, 0x0053, + 0x0111, 0x0052, 0x70fd, 0x02be, 0x70fd, 0x02c0, 0x004a, 0x0081, + 0x0061, 0x010e, 0x0060, 0x0151, 0x0093, 0x0069, 0x009b, 0x0068, + 0x00ab, 0x006d, 0x0110, 0x006c, 0x00cd, 0x0073, 0x0112, 0x0072, + 0x00eb, 0x007a, 0x0114, 0x0079, 0x0116, 0x0118, 0x011a, 0x011c, + 0x007c, 0x70fd, 0x02bf, 0x70fd, 0x02c1, 0x006a, 0x0161, 0x041a, + 0x041b, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + /* 0x89 */ + 0xf029, 0x8005, 0x70fd, 0x374a, 0x70fd, 0x70fd, 0x207d, 0x40dd, + 0x6dce, 0x62df, 0x70fd, 0x70fd, 0xd275, 0x36d1, 0x215a, 0x2168, + 0x21e8, 0x2396, 0x23b4, 0x23dc, 0x2424, 0x24e1, 0x24e8, 0x257b, + 0x258e, 0x2611, 0x2618, 0x2922, 0x2b30, 0x2b44, 0x2b47, 0x2b72, + 0x2b74, 0x2da6, 0x2dde, 0x2ddf, 0x2eda, 0x30c6, 0x327b, 0x37c9, + 0x3a3e, 0x3a44, 0x3aa5, 0x3f8e, 0x42bc, 0x4735, 0x50a4, 0x50ac, + 0x50ba, 0x50c7, 0x50cf, 0x50df, 0x5106, 0x5137, 0x547a, 0x54cf, + 0x556f, 0x5b46, 0x5d3e, 0x5d62, 0x60a6, 0x60a7, 0x60ae, 0x4611, + 0x4efc, 0x4fcd, 0x3b86, 0x4cc9, 0x2467, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x628c, 0x4ab8, 0x625e, 0x52bc, 0x70fd, 0x5e4b, 0x52f6, + 0x78e7, 0x70fd, 0x70fd, 0x529f, 0x6f47, 0x1f8d, 0x6e49, 0x6e8c, + 0x1efe, 0xebb6, 0xcd4e, 0x6e8a, 0xee73, 0x0901, 0x70fd, 0x409a, + 0x543e, 0x4719, 0x70fd, 0x1c11, 0x6b6c, 0x6b8f, 0x7019, 0x4b87, + 0xdcac, 0x8a8a, 0x7650, 0x9526, 0x2064, 0x20c1, 0x20c0, 0x20c7, + 0x20ff, 0x212b, 0x2177, 0x078c, 0x21fd, 0x1148, 0x2243, 0x22c8, + 0x07bd, 0x07d3, 0x07e5, 0x23c6, 0x2b45, 0x241b, 0x243c, 0x2445, + 0x20c9, 0x24b9, 0x24d0, 0x2567, 0x0907, 0x25e9, 0x0891, 0x25f0, + 0x0893, 0x2602, 0x2663, 0x08ad, 0x08b2, 0x09c1, 0x26d3, 0x26e3, + 0x26f4, 0x26f9, 0x2710, 0x272f, 0x2758, 0x2763, 0x2768, 0x08d8, + 0x277f, 0x08e5, 0x08ff, 0x2817, 0x0905, + /* 0x8a */ + 0xd784, 0x2765, 0x70fd, 0x7b02, 0x7bd5, 0xb42b, 0x27d0, 0x96c6, + 0x0d2c, 0x7401, 0x5f86, 0xb138, 0xe665, 0x1353, 0xd97e, 0x497a, + 0x9638, 0x0d74, 0x1ad5, 0xda1d, 0xc7b2, 0xb16a, 0x371d, 0x7c3c, + 0x7e74, 0x7b95, 0x7fb4, 0x36cd, 0x5fbe, 0x7d56, 0x7acb, 0x7e24, + 0x96a9, 0xdad6, 0xaa13, 0x70fd, 0x7c06, 0xe9cd, 0xd9a9, 0x1af4, + 0xb227, 0x96c2, 0x6bb2, 0x0da7, 0xe6f4, 0x12ed, 0x0846, 0xb587, + 0xe754, 0xd3c8, 0x9744, 0x6dee, 0x6915, 0x70fd, 0x16d9, 0xbfe5, + 0x36f4, 0x2723, 0x974c, 0x95ca, 0x7f37, 0x0d3b, 0x7f2f, 0xc49a, + 0xc4d6, 0xd4a0, 0x372a, 0xb392, 0x7b03, 0x5fa8, 0x8de1, 0xe14c, + 0x7731, 0x70fd, 0x1b0b, 0x7269, 0x12fa, 0x2ab3, 0x978d, 0x70fd, + 0xaac8, 0x75bc, 0xbfd7, 0x7e0c, 0x7c56, 0x27b9, 0x13bb, 0x16ba, + 0x70fd, 0x1d74, 0x94e6, 0x7f5d, 0x53aa, 0x69f5, 0x7c5c, 0x35b9, + 0x0d3e, 0x9275, 0x5f00, 0x28e1, 0x36bc, 0x1143, 0x70fd, 0xf101, + 0x7cc9, 0x950f, 0x96c9, 0x70fd, 0x7f88, 0xa142, 0x0cd2, 0x0d46, + 0xdb1b, 0x08b8, 0xbdc9, 0x8d07, 0x2892, 0x7df1, 0x96b2, 0xe720, + 0x07fc, 0x3e7d, 0xb1bb, 0x70fd, 0x70fd, 0xd0f4, 0x988b, 0x8e48, + 0xf15b, 0xe24d, 0x7d3a, 0x7af4, 0xc5dc, 0x5193, 0x7f8f, 0x9303, + 0x9439, 0x093b, 0xb4a3, 0x7d4c, 0x7e4d, 0x7d6a, 0x1293, 0x7df0, + 0x7c07, 0x800f, 0x7d0c, 0x70fd, 0x7d6b, 0x7a69, 0x7c08, 0x7f80, + 0x7ffd, 0x12f9, 0x9196, 0x3672, 0x7e6d, + /* 0x8b */ + 0x9d34, 0xd1b9, 0x95ce, 0x7c3e, 0x7c3f, 0x9651, 0x9655, 0x0d58, + 0x7d58, 0x7f87, 0x7dee, 0xf132, 0xc890, 0xe252, 0xe2d9, 0xe24a, + 0x66aa, 0x270c, 0x54c4, 0x27f9, 0x70fd, 0xec83, 0x6d26, 0x6bb6, + 0xd29e, 0x97ee, 0x4340, 0x536d, 0x52ec, 0x2e5c, 0xc3b2, 0x5334, + 0x0ad7, 0x259f, 0xd97d, 0x62b6, 0x7dba, 0x7ccf, 0x7d37, 0x7dbb, + 0x091d, 0xb16b, 0x0949, 0x7b96, 0x28ef, 0x92b5, 0x7f89, 0x7cd0, + 0x7d38, 0x7f38, 0x8008, 0xda87, 0x8315, 0x7d39, 0xb1d0, 0x97a4, + 0x2c94, 0x7edd, 0x7ede, 0x7fb5, 0x7fb6, 0x29dc, 0x7cd1, 0xd214, + 0xdb4d, 0x7e75, 0x7d3b, 0xb47e, 0x0a43, 0x7e76, 0x8040, 0xb598, + 0xefbd, 0xae5a, 0x867a, 0xa6b7, 0xdafc, 0x2ad9, 0x24a8, 0x095a, + 0xb8bd, 0x4db2, 0x2da8, 0x1b00, 0x1dec, 0x6fa7, 0x1ce7, 0x6d1f, + 0x6c8d, 0xbb74, 0x9abd, 0x283b, 0x0932, 0x28c9, 0x2068, 0x2b42, + 0x8901, 0xf238, 0x6851, 0x7186, 0x209b, 0x20fb, 0x087e, 0x2e63, + 0x3191, 0x3204, 0x0c3a, 0x348c, 0x3775, 0x3dba, 0x3e75, 0x3e7a, + 0x426c, 0x442b, 0x206c, 0x44ad, 0xad69, 0x5152, 0x4b3b, 0x4ef9, + 0x5153, 0xc12a, 0x0801, 0x70fd, 0xc1cb, 0x5202, 0x5280, 0xc412, + 0xc711, 0x259d, 0x59e4, 0x5b41, 0xd3b2, 0x5d20, 0x5e5d, 0x6585, + 0x6678, 0x667f, 0x66e8, 0xe30f, 0x68e6, 0x6975, 0x69ce, 0x69de, + 0x6a63, 0xe790, 0x6d7c, 0x6e9f, 0x6f44, 0x3daf, 0x7047, 0x2077, + 0x7187, 0x671d, 0x3477, 0x65a2, +}; +static const unsigned short hkscs1999_2uni_page8d[3140] = { + /* 0x8d */ + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x2f7e, 0x2f88, 0x2f96, 0x10fc, 0x0b4f, 0x2fe4, 0x2ff9, 0x0b60, + 0x0b78, 0x3082, 0x30fd, 0x3165, 0x31c3, 0x0c48, 0x0c54, 0x0c7f, + 0x0c8d, 0x3317, 0x337d, 0x2f25, 0x0cc9, 0x33f7, 0x33f9, 0x340f, + 0x0cf8, 0x346c, 0x34d0, 0x3525, 0x3558, 0x0d38, 0x28f1, 0x0d43, + 0x3622, 0x363b, 0x3647, 0x369a, 0x0d8b, 0x3700, 0x2f55, 0x2861, + 0x701f, 0x0dd7, 0x37c6, 0x0dfd, 0x383f, 0x3893, 0x0e32, 0x38d2, + 0x0e62, 0x3956, 0x0e82, 0x39e4, 0x3a40, 0x0e98, 0x3a8a, 0x3ac4, + 0x0eb2, 0x0eb1, 0x0ebb, 0x3b49, 0x3b83, 0x445c, 0x3ba4, 0x3bdf, + 0x3bc5, 0x0efc, 0x3c16, 0x0f1d, 0x3ca5, 0x3cb4, 0x3cb1, 0x3cc2, + 0x0f2c, 0x3cd9, 0x0f32, 0x3ceb, 0x3cf5, 0x3d14, 0x3d36, 0x3dc1, + 0x3e01, 0x3e2a, 0x3eb5, 0x3eea, 0x0fcb, 0x3f42, 0x3f46, 0x3f66, + 0x3fc1, 0x0fef, 0x3fe4, 0x3ff1, 0x4015, 0x4018, 0x4029, 0x4086, + 0xdfc0, 0x40bb, 0x40e2, 0x40da, 0x6fff, 0x40e8, 0x40e9, 0x4124, + 0x4134, 0x1046, 0xa481, 0x4181, 0x41be, 0x106a, 0x1075, 0x43b7, + 0x2ed9, 0x108a, 0x422c, 0x1091, 0x4250, 0x4254, 0x426f, 0x427f, + 0x4289, 0x73e5, 0x16c1, 0x0931, 0x7d98, + /* 0x8e */ + 0xa417, 0x29fe, 0xcc13, 0x433e, 0xb920, 0x098e, 0x3be2, 0xe1e9, + 0x2db4, 0x4c49, 0xb9a1, 0xe659, 0x4c65, 0x4c7d, 0xba6c, 0x4cbb, + 0x4cb0, 0x4cc2, 0x4cc3, 0x43d1, 0xc30d, 0x14ca, 0x4cda, 0x4cdd, + 0x4cea, 0x14ef, 0x26f2, 0xbc01, 0x4d0b, 0x4d55, 0x4d29, 0xb5ce, + 0xbcfe, 0x4da2, 0x4d6f, 0x559c, 0xbbb4, 0xc9bf, 0x4dd0, 0x5621, + 0x4d92, 0x70fd, 0xbd20, 0x10ad, 0xbc65, 0x5692, 0x4dfa, 0x70fd, + 0x4e35, 0xbcc1, 0x4e44, 0x4e83, 0xad02, 0x4ea6, 0x38bd, 0xaab8, + 0x4ec9, 0x4ec7, 0x4ee6, 0x4e74, 0x4ef3, 0x4ef5, 0x70fd, 0x5067, + 0x181d, 0xcb84, 0x4f5d, 0xcc16, 0x468d, 0x4f89, 0x4fab, 0x4335, + 0x4fb3, 0x70fd, 0xa597, 0xbf69, 0x4fe4, 0x1013, 0x4ff5, 0x8639, + 0x4fe5, 0xdbed, 0x70fd, 0xc021, 0xc05a, 0x506e, 0x5092, 0x162b, + 0x656c, 0x5027, 0x5140, 0x5141, 0x5147, 0x4b36, 0xc150, 0x6ae1, + 0x5197, 0xc1d1, 0x51a3, 0x84a1, 0x7168, 0x185c, 0xa066, 0x1803, + 0xdbba, 0x51fa, 0xc309, 0x70fd, 0x5208, 0x521d, 0x70fd, 0x522f, + 0xedc7, 0xca03, 0x523b, 0x523c, 0x5261, 0x9214, 0x1c89, 0xc426, + 0xa363, 0xc4a8, 0x3965, 0x52a7, 0xe048, 0x5307, 0x531a, 0x2af0, + 0x91f6, 0x3ebf, 0xc318, 0xb2f8, 0x3727, 0x834a, 0x5418, 0x869e, + 0x3c93, 0xaee5, 0xaf15, 0x177a, 0x5429, 0x7a0d, 0xc812, 0xa2fe, + 0x2239, 0x83bd, 0x56e2, 0x5562, 0xc84a, 0xae27, 0x9e30, 0x85b3, + 0xa378, 0x54aa, 0x3b5b, 0xf2d4, 0x14db, + /* 0x8f */ + 0x574b, 0x54d0, 0x551a, 0x7cd6, 0x85f4, 0x0a01, 0x9afd, 0x9e5a, + 0x547b, 0x54e2, 0x5518, 0xa3cb, 0xcae3, 0xc845, 0xc8d7, 0x9ece, + 0x10bf, 0x551d, 0x282c, 0x5585, 0x180b, 0xcae5, 0x55ac, 0x70fd, + 0x55d3, 0x07be, 0xcc14, 0x3c97, 0x575a, 0x07d6, 0xcb82, 0x98ef, + 0x5658, 0xbbe4, 0x5671, 0x10d3, 0x17e4, 0x3ce7, 0x564a, 0xa275, + 0x4b58, 0x70fd, 0xc8d6, 0xcbb7, 0xcb83, 0x56de, 0x70fd, 0x5591, + 0x17a0, 0x5693, 0x56e4, 0xbc91, 0x1540, 0xbcc0, 0x1843, 0x5734, + 0x2d32, 0xcbd9, 0x1827, 0x5773, 0x1816, 0x39ff, 0x57d6, 0xdde5, + 0xddfb, 0x5781, 0xcdc8, 0x57c2, 0x8402, 0xce0d, 0xf2f2, 0x186a, + 0x57e8, 0x0988, 0x86e2, 0x2637, 0xcfda, 0x583e, 0x58f1, 0xee38, + 0x596e, 0x9627, 0x5931, 0x595a, 0x598f, 0x28a1, 0x582c, 0x3a96, + 0x190f, 0x59c5, 0x59c6, 0xd160, 0xa339, 0xd164, 0x59de, 0x5a1c, + 0x195b, 0x5a34, 0x5a35, 0x3601, 0x5a45, 0x4977, 0xd24f, 0x5b07, + 0x5b0a, 0x70fd, 0x70fd, 0x5b27, 0x5b3c, 0xe025, 0x5b67, 0xd424, + 0xd5bd, 0x5c1c, 0x4993, 0x62fe, 0x5c10, 0xd559, 0x4ce9, 0xd63a, + 0xa4cf, 0x1a13, 0xd638, 0x437c, 0x5c8c, 0x5c9f, 0xb630, 0xb6e5, + 0x5cbf, 0x5ccc, 0x5ccd, 0x5c29, 0xaefa, 0x5d10, 0x5d1b, 0x5c2f, + 0x851f, 0x1915, 0x59cf, 0x5ddb, 0xd754, 0xd78f, 0xf314, 0x0a65, + 0xd753, 0x5e16, 0xd798, 0xd7bd, 0x5e52, 0x5e43, 0x8750, 0x5e1b, + 0x425c, 0x5e51, 0xb089, 0x11d0, 0x70fd, + /* 0x90 */ + 0x5ee9, 0xd8c2, 0x7ed4, 0xae0a, 0x0ebc, 0xda7c, 0xce4c, 0x4ce7, + 0x5fed, 0x5ff6, 0x6003, 0x63d4, 0x6059, 0x606d, 0xdbe5, 0xdc52, + 0x60e5, 0x6403, 0xef9f, 0x7950, 0x60f3, 0x1c2a, 0xdfde, 0xdd3d, + 0xa33b, 0x3138, 0x9be2, 0x6139, 0xed94, 0xde3c, 0xdd01, 0x8ee5, + 0x0cc0, 0xcc17, 0x6177, 0xdd3c, 0xd5be, 0x61a1, 0xdd6c, 0xddcb, + 0x61e8, 0xde93, 0x6204, 0xde66, 0x61ee, 0x70fd, 0x6267, 0x0e30, + 0x62a9, 0x62c4, 0x4eac, 0xdf33, 0x8b09, 0x630e, 0x3edf, 0x6341, + 0x6362, 0xb739, 0x70fd, 0xe0c6, 0xa25b, 0xe10c, 0xb75b, 0x7bf1, + 0x642c, 0x646b, 0xe0e1, 0xe1eb, 0x428f, 0x2d03, 0xe0e2, 0xe0e5, + 0x1c65, 0x6344, 0xe1ec, 0xe239, 0xe1ff, 0x6473, 0x655b, 0x5ffc, + 0x6685, 0x66a6, 0x6526, 0x66a0, 0x41f6, 0x15b9, 0x917a, 0xde58, + 0x813c, 0xa3ae, 0x1cdf, 0x3e5c, 0x677b, 0x6796, 0x146c, 0x67a3, + 0xcc15, 0x341a, 0x67b6, 0x4af5, 0xe0e0, 0x67bd, 0x260c, 0x1ca1, + 0xc9f8, 0x7334, 0xc290, 0xe46f, 0xe4a5, 0xaf51, 0x8755, 0x9c8a, + 0x6831, 0x5802, 0x6836, 0x1d0f, 0x183d, 0x1885, 0xaf69, 0x4275, + 0x2d81, 0x681b, 0x70fd, 0xe595, 0x6857, 0x2d8a, 0xe5ab, 0x685f, + 0x6525, 0x2310, 0x9a37, 0x9a3c, 0x6889, 0x689f, 0x68b1, 0x68be, + 0x68c0, 0x68d2, 0x68e0, 0xb66c, 0x68ee, 0x461c, 0xe5f3, 0x70fd, + 0x68f5, 0xe5dd, 0xd47a, 0x1d91, 0x6934, 0x6933, 0x694b, 0x6966, + 0x0e4e, 0xceb5, 0x1051, 0x76b0, 0xa69c, + /* 0x91 */ + 0xb886, 0x69ca, 0x69b7, 0x69c8, 0x69c7, 0x1dbf, 0xca67, 0x8513, + 0x27f0, 0x69e1, 0x69e6, 0x69ec, 0x6478, 0x6a39, 0xaea9, 0x1e32, + 0xe7d7, 0xe885, 0x6af5, 0x6b0c, 0x6b3b, 0x6b10, 0x6b58, 0xb8a5, + 0x0a04, 0xe471, 0xea55, 0x6be0, 0x6be2, 0xea05, 0x6bf4, 0x1ece, + 0x6c14, 0x6c2d, 0xddc0, 0x2274, 0x6c34, 0xc768, 0x0c03, 0x99fd, + 0x6c50, 0x6c40, 0xeafe, 0x2c85, 0x86a3, 0x6c8e, 0xa78b, 0x6d02, + 0x6cff, 0x6d0c, 0xec28, 0x6e54, 0xed37, 0xeed2, 0xeeeb, 0xee21, + 0xee63, 0xef1f, 0x6dfe, 0x6e03, 0xee74, 0x6e8e, 0x3ac8, 0x6e44, + 0x8d9b, 0xeed3, 0xef60, 0x877b, 0xef73, 0x6db9, 0xedf9, 0xefb4, + 0x6f10, 0x6f15, 0x6f1e, 0x6f22, 0x1ff4, 0x6f2a, 0x6f2f, 0xa8a4, + 0x6f41, 0x0ea0, 0x0d25, 0x101d, 0x2172, 0x0afe, 0xe22b, 0x6f82, + 0x6f88, 0x1e56, 0x6524, 0xcae2, 0x6f97, 0x70fd, 0x6fb9, 0x28df, + 0x28ca, 0x6fc5, 0x6ab8, 0xe44b, 0x68f2, 0x567f, 0x6fe2, 0x6fe9, + 0x4cdc, 0x700e, 0x4416, 0x1e7e, 0xadf5, 0xae3b, 0x4377, 0xae78, + 0xa888, 0xaed1, 0x459e, 0xe1da, 0x873a, 0x4b9f, 0xdf7e, 0xe336, + 0x6469, 0x64f3, 0xe044, 0x63ec, 0x6481, 0x64cb, 0xdf6c, 0xa9f9, + 0x4417, 0x11eb, 0x4972, 0x4c43, 0x42d0, 0xa9b3, 0xa938, 0x437e, + 0x862f, 0x42a3, 0x86fe, 0x9e99, 0x11c7, 0x86c5, 0xb62f, 0x8638, + 0x0a62, 0x853b, 0x8679, 0x0a21, 0x85b4, 0x8711, 0xbecb, 0x0a63, + 0x8500, 0x299b, 0xaea5, 0x82be, 0x8168, + /* 0x92 */ + 0x8286, 0x8376, 0x5703, 0x9fa6, 0x70fd, 0x5655, 0xae14, 0xcea5, + 0xa3b1, 0xb6dc, 0xa43b, 0xcd92, 0x17f4, 0x9fee, 0xe91d, 0xcc66, + 0x3a39, 0x0a73, 0x0f55, 0x10e7, 0x2aac, 0x8762, 0x3a50, 0x1357, + 0xa03f, 0xa621, 0xa5cb, 0xa64f, 0xc961, 0x270b, 0x28de, 0xc471, + 0x28d2, 0x7e9f, 0x7a68, 0x7ccd, 0x64c6, 0xe113, 0x649c, 0x2138, + 0x236b, 0x0b59, 0xa976, 0x20fc, 0x7525, 0x743f, 0x218b, 0x21ca, + 0xb7d1, 0x2ca8, 0x726b, 0x748b, 0x0cd9, 0x73ca, 0x74d4, 0x0775, + 0x2169, 0x7380, 0xe3b3, 0x7335, 0x5c5a, 0x72cc, 0x20d8, 0x230d, + 0x234d, 0x21e2, 0x2143, 0xae8e, 0xa3ca, 0x2182, 0x226e, 0x22ac, + 0x22c1, 0x220c, 0x2225, 0x2298, 0x233c, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x4076, 0x9e95, 0xa3b9, 0xa3ff, 0x3fb2, 0x86c4, 0xa3c9, + 0x23e8, 0x2403, 0x7660, 0x17dd, 0x7563, 0x7552, 0x7551, 0x5eba, + 0xe09c, 0x770e, 0x2499, 0x24e4, 0x77f3, 0x2521, 0x70fd, 0x197a, + 0x438c, 0xa8cc, 0x7ae0, 0xae2c, 0x7fa4, 0x3c11, 0x7cdd, 0x70fd, + 0x11de, 0x4699, 0x4614, 0x4656, 0x4598, 0x1e4e, 0xaf3c, 0xa5cd, + 0x2610, 0x08c4, 0x440f, 0xa609, 0x27f4, 0x7405, 0x270d, 0x7a86, + 0x295d, 0x635d, 0x67f4, 0x6466, 0x2a1d, 0x29cd, 0x29bf, 0x097e, + 0x2b0b, 0x2cd9, 0xe046, 0x853a, 0x85af, 0x8550, 0x2c6c, 0x2bf8, + 0x638f, 0x2cbe, 0x2d0f, 0x2c52, 0xba06, 0x8833, 0x86a1, 0xa7d5, + 0x0a35, 0x3f45, 0x4643, 0x2c61, 0xbe03, + /* 0x93 */ + 0x2cc1, 0xe1d7, 0x74d3, 0x64e0, 0x468c, 0x81c3, 0x4305, 0x1c72, + 0x6508, 0xdffb, 0x64bd, 0x0ae0, 0x2e5e, 0x2ede, 0x309e, 0x3088, + 0x87d6, 0x87bc, 0xa1ee, 0x310d, 0x2d8f, 0x8743, 0x8744, 0x0a41, + 0x86e0, 0x0a1d, 0x853e, 0x0a13, 0x532a, 0xe047, 0x8a7a, 0x9db2, + 0xdfa8, 0x314c, 0x314e, 0x8767, 0x85eb, 0x2cab, 0x857b, 0x2d84, + 0x57d4, 0xd17d, 0x59e0, 0x32be, 0x9360, 0x912b, 0x321b, 0x11b8, + 0x90ef, 0x90fe, 0xe448, 0xccb3, 0x3400, 0x713e, 0x7146, 0x911b, + 0x33d9, 0x33d8, 0x32b5, 0x969b, 0x9707, 0xabd4, 0xe50d, 0x36b1, + 0xab65, 0x95aa, 0x0d69, 0x9562, 0x9d90, 0xe86a, 0x9878, 0x3577, + 0xf09b, 0x36f6, 0x3571, 0x3611, 0xae63, 0x9767, 0x34e4, 0x96a1, + 0x367b, 0x37ab, 0x3bb2, 0x0f34, 0x9a0e, 0x9c2d, 0xae09, 0x9c2b, + 0x274d, 0x9c60, 0x8719, 0xe5ff, 0x390e, 0x9c09, 0x9b33, 0x0e20, + 0x1490, 0xb704, 0xe122, 0xb70f, 0x853c, 0xb6db, 0xb625, 0x4aee, + 0x9a83, 0x866a, 0x9bb4, 0x07a4, 0x9b8f, 0x9b02, 0xa809, 0x38ce, + 0xca64, 0x38ab, 0x1e53, 0x3870, 0xd370, 0x8aab, 0x38a3, 0x9c52, + 0x9c61, 0x385e, 0xb972, 0x0c11, 0xa13a, 0xa0bc, 0x0ed9, 0xa0a2, + 0x9d3e, 0x46d0, 0x0ed6, 0x39cf, 0xab2a, 0x3af6, 0x3a5e, 0x0f04, + 0x3cfe, 0x0ba3, 0xa0d5, 0xa9c7, 0x3c73, 0x3c92, 0x3d09, 0x3d45, + 0x8752, 0x3751, 0x3ad8, 0x3c8c, 0x0f17, 0x3cba, 0x3d97, 0xa500, + 0xa25a, 0x64a0, 0x63f2, 0xe1ea, 0xe0cb, + /* 0x94 */ + 0x6389, 0xd8de, 0xdfdc, 0x6567, 0x3fe5, 0x410b, 0xae6c, 0x70fd, + 0xa4bf, 0x108f, 0x4004, 0xa57c, 0x2c7d, 0x400a, 0x2a87, 0x3f64, + 0x4a42, 0x433b, 0xa85a, 0xa7b6, 0x42f1, 0x4450, 0x4487, 0x4494, + 0xac4f, 0xac25, 0x23b9, 0xaf24, 0x766b, 0x467a, 0xa438, 0x9f5f, + 0xaeca, 0xad97, 0xbf21, 0x1206, 0x11b1, 0xaf5f, 0xe223, 0xa475, + 0x32e7, 0x11f3, 0x46cc, 0x463c, 0x6487, 0x4637, 0x179f, 0xcb2a, + 0x1851, 0x4783, 0x1263, 0xb099, 0xb0c6, 0x1258, 0x4755, 0x4873, + 0xf0c6, 0x0e59, 0x4668, 0xe0cc, 0xae2b, 0xae0e, 0x0e3b, 0x10cd, + 0xaece, 0x11ff, 0xae45, 0xad73, 0x62fa, 0x2972, 0x6442, 0xe0e3, + 0x86a4, 0x231f, 0xb4e1, 0xb4a7, 0x4978, 0x9bb2, 0x490e, 0x490f, + 0x497b, 0xab97, 0xa081, 0x0d9e, 0xad70, 0x4638, 0x469b, 0x11bf, + 0xaf3a, 0xaf47, 0x13c8, 0xaf16, 0xc0ae, 0x6407, 0xb701, 0x4a1e, + 0x4a8d, 0x4a88, 0x4ad2, 0x45d0, 0x4b59, 0xd281, 0xb863, 0x140e, + 0x70fd, 0x5696, 0x4ba5, 0x3c6d, 0xa43a, 0x4c3a, 0x4bf4, 0x146e, + 0x8526, 0x1432, 0x6335, 0x4bf1, 0x7c0c, 0xae0c, 0x7359, 0xa33a, + 0x85ae, 0x08d7, 0x27ab, 0x08b0, 0x09ea, 0x7294, 0x7acd, 0x4ce2, + 0x2c99, 0x91f5, 0xbaef, 0xbadc, 0x2c4d, 0x731b, 0x4af0, 0x2c6a, + 0xbbc6, 0x4cfe, 0x14f9, 0x4e5d, 0x4e6d, 0x1511, 0xbbb3, 0xbe3c, + 0xbe26, 0x4ecd, 0xae79, 0x85f0, 0x4e8e, 0x4e7c, 0x4eae, 0x3cf2, + 0x4fdc, 0x5007, 0x4fd3, 0x514e, 0xc121, + /* 0x95 */ + 0xc05c, 0xd648, 0x4f97, 0xbe02, 0x156a, 0xc8b5, 0x7856, 0x3a16, + 0x714e, 0x9ecf, 0x2a04, 0xc292, 0xc278, 0xade2, 0x51dd, 0x4d27, + 0x77ac, 0xbb29, 0xbd43, 0x4d0c, 0xbd8e, 0x6ae6, 0x5805, 0x6b63, + 0x3c5c, 0x9d7f, 0x0d22, 0xae77, 0xc3ed, 0x6b1f, 0xc3e0, 0x5680, + 0xce67, 0xca11, 0x17ea, 0x5337, 0x1702, 0x52c6, 0x5309, 0x5342, + 0xc574, 0x69c3, 0xc802, 0x5462, 0x5465, 0xc811, 0x5653, 0xcae7, + 0x57d0, 0xcf1b, 0x2cc6, 0x147f, 0x8680, 0x2d6b, 0x86e1, 0x2d24, + 0x8718, 0x5860, 0xf2fc, 0xa30f, 0x59ad, 0xd022, 0x2c42, 0x59ee, + 0x2185, 0x5a07, 0x5a3f, 0x5a66, 0x5ae5, 0x5acd, 0xb803, 0x5ad4, + 0xd2c5, 0xd2c4, 0xe1f5, 0xe1d9, 0xe19c, 0xdff9, 0x11ad, 0x56a3, + 0x19f5, 0x19cf, 0x0b32, 0x5bbd, 0x5b9c, 0xe608, 0x318d, 0x632b, + 0xa7c4, 0x3814, 0x4329, 0x42c4, 0x8685, 0x6ded, 0x5ddf, 0x5e29, + 0xd7dc, 0x2bda, 0x49c3, 0x2c30, 0x166e, 0x0a14, 0x5f6a, 0x5fe7, + 0xb009, 0x6070, 0x608a, 0x15f4, 0x3e98, 0x41bb, 0x8ee1, 0x1b9b, + 0x4179, 0x408b, 0x861a, 0x6ce9, 0x09f5, 0xadaf, 0x61fb, 0x70fd, + 0x27b1, 0x1c06, 0x62bb, 0x6504, 0xe04b, 0x1362, 0xe0fc, 0x6527, + 0xe21d, 0xe23b, 0x56e5, 0x5bab, 0x6699, 0x66a7, 0x6697, 0x6696, + 0xe2b4, 0x4645, 0x11c2, 0xad7f, 0xaec2, 0xa92a, 0x11e7, 0x9ba5, + 0x678f, 0xe3e7, 0xe366, 0xe365, 0x11cc, 0xae6d, 0xaef8, 0xa52e, + 0x4612, 0x466b, 0x11fc, 0x6841, 0xe470, + /* 0x96 */ + 0x3a87, 0x1d1d, 0xe453, 0xb91f, 0x70fd, 0x6468, 0xdf89, 0xe226, + 0xe12f, 0xc23e, 0x63ba, 0x2d51, 0x5ce9, 0x1c3c, 0x45f9, 0xa75b, + 0x689b, 0x6871, 0x6a38, 0x7de6, 0x3001, 0xe1c5, 0xaf32, 0x691f, + 0xe65a, 0x63f6, 0xe6d7, 0x62e5, 0x17c0, 0xe150, 0xaee7, 0xe164, + 0x69dc, 0xe045, 0x1200, 0x632a, 0x1c25, 0x5614, 0x6a3b, 0x6a4d, + 0xd606, 0x10fd, 0x6a9b, 0x1e2f, 0x6aaa, 0x6b5c, 0xe165, 0xb988, + 0x3ccf, 0x6b21, 0x2d3e, 0x6b2f, 0xe871, 0x1e50, 0xe8c8, 0x6abc, + 0x1e7d, 0x1e57, 0x647d, 0x2ab2, 0x81c2, 0x2a62, 0xae38, 0x83a8, + 0x4a44, 0x921f, 0xa338, 0x3b05, 0x107d, 0x6558, 0x0c67, 0x3390, + 0x9281, 0x946b, 0x3347, 0x6d4f, 0x6d53, 0x6d7b, 0x6d35, 0x6d10, + 0x6c7f, 0x6ccf, 0xebed, 0x6c9f, 0xef35, 0xee3e, 0x6da1, 0x1f6e, + 0xa644, 0x6e98, 0x1f70, 0x6d8c, 0xeef4, 0xee2d, 0xee33, 0xe8af, + 0x6e25, 0x56bd, 0xcb52, 0xcd1f, 0xc8c2, 0x57bc, 0x1833, 0xcae4, + 0xcbc4, 0xcb30, 0x5620, 0x57ae, 0xcb40, 0xa0d7, 0xbfa4, 0x4be2, + 0x9e9c, 0x9f40, 0x1c2d, 0xae5e, 0x1062, 0x64db, 0x63be, 0x6448, + 0x737f, 0x4ab9, 0x6377, 0x654d, 0x2224, 0x0780, 0x61a4, 0xb6dd, + 0x4a3d, 0x4a54, 0x4ab6, 0x4a4b, 0x8597, 0x9b49, 0xadc1, 0x09da, + 0x21b2, 0x41da, 0x41d9, 0x70fd, 0x421e, 0x2654, 0xa6f5, 0x29fb, + 0x2b33, 0x29ca, 0x6d96, 0x2a17, 0x4334, 0x07ef, 0xa6ec, 0x43eb, + 0xc980, 0xb2d7, 0x70fd, 0x85f5, 0xe049, + /* 0x97 */ + 0x334c, 0x2d0e, 0x2c4b, 0x15bc, 0xa9c8, 0x0a6c, 0x1e3b, 0xdffc, + 0x64bb, 0x64b8, 0x8716, 0x7ddd, 0x5672, 0xca00, 0x82d3, 0xa83a, + 0x9626, 0xa901, 0x2bd4, 0xa337, 0xc501, 0x4fa8, 0xc05b, 0xbfe4, + 0xae39, 0xae0b, 0xdffa, 0x63e5, 0x45e2, 0x11e9, 0x46b4, 0xe163, + 0x86df, 0x11e1, 0xaf33, 0x3d18, 0x45f3, 0x45fb, 0x11d6, 0xaebe, + 0xaf14, 0x8619, 0xaee6, 0x7467, 0x82e4, 0xae65, 0x4648, 0xad96, + 0x42a5, 0xadf6, 0x6384, 0x45e6, 0x645f, 0x75be, 0x6431, 0xe0ce, + 0xe016, 0x6486, 0xe1e7, 0xb755, 0x1c35, 0xe082, 0x436b, 0xadc3, + 0x7bbf, 0x28e4, 0x769a, 0x7aab, 0x7b78, 0x2742, 0x4bc4, 0x863a, + 0x4ffe, 0x8502, 0xaed0, 0x8692, 0x182e, 0x6501, 0x0a4a, 0xe0c0, + 0xae2d, 0x2bf0, 0x86ff, 0x86c3, 0xd084, 0x2ce1, 0x0a22, 0xa2db, + 0x09f0, 0x635f, 0x2cb9, 0xe081, 0x86a2, 0x6474, 0x0fcd, 0x79b4, + 0x1d56, 0x0cca, 0x2334, 0x1069, 0x104c, 0x825c, 0x4375, 0x15fb, + 0xda98, 0x400f, 0xe4a4, 0x17eb, 0x3f97, 0xd80f, 0x4267, 0x3eef, + 0x0fd6, 0xa52d, 0xa3ad, 0x4002, 0x410c, 0x106f, 0x74b5, 0x4751, + 0x09fc, 0x0808, 0x1980, 0x11da, 0x1b71, 0x2c04, 0x636e, 0x1c3e, + 0x6081, 0xe21c, 0xc900, 0x2a52, 0x2a08, 0x0a16, 0x8312, 0x42fe, + 0xa8a2, 0xaef1, 0x9963, 0x8170, 0x8f3d, 0x3af9, 0x3ba7, 0x8258, + 0x9de5, 0xd6b4, 0x9fdf, 0xe083, 0xa0d6, 0x9d3a, 0xb05f, 0x3c5a, + 0x9fad, 0xc9f7, 0x563e, 0x17df, 0x17ce, + /* 0x98 */ + 0xca66, 0xca91, 0xc9c2, 0xcd1e, 0x4117, 0xce49, 0x553d, 0x857a, + 0x55ed, 0xc9c0, 0xcd93, 0x861b, 0x2bc9, 0x2cc2, 0x85f3, 0x2ca1, + 0x2cb1, 0x8745, 0xa73c, 0x0a6d, 0x2c2f, 0x857c, 0x0a07, 0x438e, + 0x6490, 0x38da, 0xa7e5, 0x2cae, 0x2c6b, 0xa7d3, 0x3c6b, 0xa439, + 0xd276, 0xa99b, 0xa80a, 0x431d, 0xa799, 0xdfe1, 0x21f0, 0xca68, + 0x2f02, 0xaa0e, 0xd80d, 0xa8fd, 0x3c4c, 0xa796, 0x81c4, 0x42a6, + 0x4333, 0xa929, 0x10a5, 0x3f1f, 0xf1e5, 0xaecf, 0x5065, 0x2c2b, + 0x2f6f, 0x10f3, 0x319c, 0xaedd, 0x861f, 0x4fa4, 0x5626, 0x26c5, + 0xa1fa, 0x9c80, 0x72d4, 0x29be, 0x7815, 0x7699, 0x12e5, 0x8c1e, + 0xefb6, 0x4203, 0xe51b, 0x2fb0, 0x458f, 0x4ed3, 0xe059, 0xe5e0, + 0x2208, 0x51e7, 0x44cd, 0x4510, 0xd5f4, 0x4538, 0x4539, 0xb876, + 0x4541, 0x4548, 0x11a9, 0xd618, 0x61ac, 0x43f5, 0xad72, 0x45e1, + 0x53f6, 0x11ca, 0x490c, 0x11d1, 0x3ee2, 0x293d, 0x4619, 0x461e, + 0x461f, 0x11e2, 0x11f0, 0x11f4, 0x11fa, 0x46d3, 0x120e, 0x1253, + 0x4742, 0x476d, 0x4772, 0x478d, 0x127c, 0x47c8, 0x47dc, 0x12c0, + 0x484d, 0x12d7, 0x4874, 0x12dc, 0x487a, 0xb29c, 0x4388, 0x2863, + 0x5b00, 0x2aa9, 0x131d, 0x4943, 0x1339, 0x39a1, 0x1345, 0x091b, + 0x4998, 0x136a, 0x136f, 0x2e9e, 0x49be, 0x49cb, 0x2b32, 0x4a18, + 0x42b9, 0x4a1c, 0x13a8, 0x4a39, 0x4a47, 0x4a51, 0x4a66, 0x5648, + 0xb6b5, 0x4b33, 0x3a43, 0x4b32, 0x1403, + /* 0x99 */ + 0x1409, 0x4b91, 0x4b99, 0x60fb, 0x4c06, 0x60fc, 0x1467, 0x4c91, + 0x14b2, 0x4cbc, 0x5479, 0x14c4, 0x4ccf, 0x4cdb, 0x14cf, 0x2061, + 0x4d62, 0x4d6c, 0x4d7b, 0x4e12, 0x4e1b, 0x1560, 0x157a, 0x4e7b, + 0x4e9c, 0x158c, 0x4eb8, 0x1594, 0x4eed, 0x60d3, 0x42c0, 0x7b8f, + 0x4fcf, 0x4fd4, 0x4fd0, 0x4ffd, 0x51ae, 0x51b4, 0x449f, 0x1697, + 0x5220, 0x5225, 0x4d39, 0x522e, 0x5231, 0x5254, 0x10cc, 0x29f4, + 0x42a0, 0x52b7, 0x52e9, 0x16ed, 0x530c, 0x452a, 0x530e, 0x5312, + 0x4760, 0x5314, 0x1701, 0x0e79, 0x5356, 0x5359, 0x535a, 0x1713, + 0x2a7a, 0x537c, 0x5384, 0x1725, 0x5393, 0x172d, 0x53a5, 0x2a2f, + 0x53c1, 0x53e4, 0x5454, 0x178f, 0x54a6, 0x5476, 0x54ca, 0x54d8, + 0x54ff, 0x17b0, 0x5557, 0x6769, 0x3bca, 0x5605, 0x42f5, 0x5664, + 0x3323, 0x5688, 0x1804, 0x56be, 0x56e1, 0x56f8, 0x5710, 0x5738, + 0x5752, 0x183b, 0x576f, 0x5770, 0x57a0, 0x1877, 0x5832, 0x5852, + 0x5872, 0x58af, 0x6745, 0x590b, 0x1906, 0x1917, 0x5a2e, 0x5a7f, + 0x5aa4, 0x5ac7, 0x5b11, 0xd467, 0x5ba9, 0x5bb8, 0x5c14, 0x5c34, + 0x5d91, 0x5e14, 0x5e32, 0x5e5c, 0x1a98, 0x2a9f, 0x5f03, 0x1aed, + 0x212e, 0x5f7a, 0x2818, 0x2994, 0x5fb1, 0x2835, 0x5ff0, 0x1b37, + 0x600e, 0x6022, 0x6024, 0x602d, 0x6032, 0x60f7, 0x6101, 0x610a, + 0x610c, 0x6173, 0x6ac4, 0x1bad, 0x69e0, 0x6313, 0x1c1e, 0x6328, + 0x6358, 0x636b, 0x63b1, 0x63ae, 0x63bf, + /* 0x9a */ + 0x63e3, 0x63eb, 0x63f3, 0x63f4, 0x63fd, 0x6443, 0x6484, 0x64ad, + 0x1c45, 0x1c51, 0x6f3f, 0x6517, 0x2541, 0x651d, 0x652d, 0x653e, + 0x1c6a, 0x6554, 0x6579, 0x662d, 0x66a2, 0x1ca7, 0x66f4, 0x6733, + 0x1ce5, 0x39e0, 0x1d24, 0x6840, 0x1d35, 0x68b2, 0x68c2, 0x2894, + 0x1da4, 0x3328, 0x69b9, 0x1dd9, 0x69f1, 0x2a84, 0x6a0e, 0x6a19, + 0x23f4, 0x6a1c, 0x6a37, 0x6a42, 0x6a5d, 0x6a62, 0x1e30, 0x6ac5, + 0x1e5d, 0x6b3c, 0x6c0f, 0x4c83, 0x6c69, 0x6c81, 0x6cdd, 0x6cf1, + 0x6cf4, 0x1f2d, 0x6d20, 0x0aaf, 0x8902, 0x6dc9, 0x6d3a, 0x6f7e, + 0x2890, 0x6e13, 0x6e3d, 0x6e40, 0x6e7c, 0x65f6, 0x60f6, 0x6efb, + 0x6f2c, 0x6f31, 0x6f3d, 0x6f46, 0x65dc, 0x6f62, 0x6f71, 0x6f78, + 0x4cc8, 0x6fc4, 0x7194, 0x7377, 0x7460, 0x3b5a, 0x65c3, 0x2bec, + 0x7597, 0x2a80, 0x65c1, 0x0af9, 0x7655, 0x7695, 0x76f6, 0x84fa, + 0x2997, 0x4373, 0x79c2, 0x79cd, 0x7a7f, 0x26aa, 0xf1fb, 0x7a8b, + 0x26de, 0x7abb, 0x7afb, 0x7b13, 0x7b25, 0x7b3c, 0x3327, 0x7b4d, + 0x28ba, 0x7b75, 0x7b9d, 0x7bad, 0x7c2f, 0x7c72, 0x7c88, 0x3b95, + 0x6d2f, 0x5925, 0x7cc4, 0x7cce, 0x7d97, 0x7e50, 0x7ded, 0x7d33, + 0x2e60, 0x7e7c, 0x304b, 0x7f1c, 0x7f0f, 0x7f36, 0x395e, 0x7f3b, + 0x7f48, 0x7f56, 0x0987, 0x7f7f, 0x7f93, 0x7fef, 0x7ffb, 0x25a4, + 0x56ad, 0x81a3, 0x8235, 0x81f6, 0x5d01, 0x83f7, 0x8459, 0x8603, + 0x8607, 0x20b8, 0x42bb, 0x866d, 0x87aa, + /* 0x9b */ + 0x886d, 0x8885, 0x896a, 0x89b0, 0x89ec, 0x8b48, 0x3503, 0x8b55, + 0x8b95, 0x4398, 0x3a95, 0x8c85, 0x3c29, 0x0a08, 0x8ebc, 0x8f57, + 0x8f7a, 0x922a, 0x9371, 0x944f, 0x54fd, 0x9467, 0x9493, 0x9515, + 0x5b25, 0x9528, 0x60e0, 0x954e, 0x68b8, 0x957f, 0x6947, 0x6bbd, + 0x964c, 0x70fd, 0x9688, 0x96b7, 0xbbe8, 0x9708, 0x9712, 0x97b7, + 0x9795, 0x9842, 0x9934, 0x994c, 0x99b3, 0x99e6, 0x9c9f, 0x9d1e, + 0x31f1, 0x3888, 0x38ff, 0xd579, 0x9e67, 0x9ef3, 0x70fd, 0xae3a, + 0x70fd, 0x9f1a, 0xa016, 0x70fd, 0x7406, 0x2af5, 0x394e, 0x3b58, + 0xa1a7, 0xd1d7, 0xbf22, 0xa391, 0xa3f9, 0xd17e, 0x8cda, 0x1bd0, + 0x1d78, 0xa659, 0xe09a, 0xa82e, 0xa84d, 0xa57b, 0xa874, 0xa8d6, + 0xaec5, 0x764a, 0x2412, 0x7691, 0x2bdf, 0x8b28, 0x0efe, 0xa2bf, + 0xa944, 0xaa16, 0x29c8, 0xab74, 0x0cdb, 0xac2f, 0xdda8, 0xe949, + 0x0aa2, 0x8e03, 0x5cde, 0xe14e, 0x70fd, 0xacd2, 0xad7b, 0xae95, + 0x4409, 0xaf40, 0x7b38, 0x2ba5, 0xb225, 0xb2c6, 0x7779, 0x601a, + 0xb36c, 0x24cf, 0x297f, 0x4371, 0xb559, 0xb619, 0xa48a, 0xaf27, + 0x27fc, 0xb646, 0xb66e, 0xc892, 0x70fd, 0x07b3, 0xb6bf, 0xd1b2, + 0xb6de, 0x1a18, 0xb6e2, 0xb6e6, 0xb907, 0xadbf, 0xb95d, 0x22a6, + 0x083b, 0x9d0c, 0x70fd, 0xb9c3, 0x1a7c, 0xdf48, 0xbaee, 0xbb89, + 0xbc06, 0x8a50, 0x29e1, 0x4351, 0x70fd, 0xc002, 0xd6d2, 0x6196, + 0xc0b2, 0xb2da, 0x5ce2, 0xc282, 0xc2ca, + /* 0x9c */ + 0x2f9b, 0xc937, 0x70fd, 0xc304, 0x875c, 0x5c6a, 0xae76, 0xc308, + 0xa52f, 0xc352, 0x1e80, 0xc3ff, 0xc475, 0x921b, 0x6565, 0xb921, + 0x33d5, 0x2c67, 0xf28d, 0x70fd, 0x28f9, 0xaa61, 0xc4bc, 0x20aa, + 0xadb4, 0x6756, 0x3fcf, 0xc9fd, 0x0958, 0x5af7, 0xc559, 0xc62e, + 0xc291, 0xc61e, 0x70fd, 0xc687, 0x4d42, 0xe480, 0x7911, 0xc6e6, + 0x70fd, 0xc6f9, 0x4c45, 0x70fd, 0xc7ba, 0x6b26, 0xc7ed, 0x099f, + 0xc2e9, 0x7121, 0x4b83, 0xc7f4, 0xc89b, 0x2f6c, 0x9e19, 0x70fd, + 0xc8dd, 0x19d0, 0xc9e4, 0x473b, 0x59e5, 0xcaee, 0x2af6, 0x0a5c, + 0x90cd, 0xcd8b, 0xcecd, 0x0f94, 0xcf40, 0xcf45, 0x6381, 0x8dba, + 0xcf4b, 0x6430, 0xcfa6, 0xae50, 0x3e79, 0x659f, 0xd050, 0x7db8, + 0x59a7, 0x5a75, 0x9426, 0xdcb3, 0x85f1, 0x40b8, 0xaeaa, 0x8660, + 0x0ce4, 0x09f9, 0x70fd, 0x70fd, 0x183f, 0x38f6, 0xeaad, 0xe824, + 0x5ac3, 0xd30c, 0xd358, 0x2916, 0x13df, 0x844a, 0x0ce1, 0xa02f, + 0xd9a8, 0x8285, 0x43ad, 0x5566, 0xd4dd, 0xe568, 0x70fd, 0x1f77, + 0xcdef, 0xdfab, 0xd4fd, 0xd50a, 0xd60b, 0xd766, 0xa6ba, 0x4d43, + 0x4b7e, 0xd8c9, 0x41b5, 0xefdf, 0x3c43, 0xdb98, 0x25e2, 0xcb47, + 0x64bf, 0x3a76, 0x685d, 0xda2f, 0xd8e3, 0xc775, 0x82ad, 0x9baf, + 0xd908, 0x2fc5, 0xe230, 0xd943, 0x2955, 0x6923, 0xdf49, 0x2feb, + 0xae08, 0x37fe, 0x3c15, 0x2612, 0xaf25, 0xa4c1, 0x0f51, 0x3976, + 0xd950, 0xd9b4, 0xd9ee, 0x8c21, 0xda0f, + /* 0x9d */ + 0xda49, 0xda6f, 0xda9a, 0xdb86, 0xdbaf, 0xdc0a, 0x090a, 0xdca8, + 0xde2a, 0x1bfa, 0x3626, 0xdf56, 0x4a08, 0x6355, 0xdfb8, 0x16f2, + 0xdfe7, 0x16df, 0xdfe8, 0xe146, 0xe1d4, 0x2c38, 0xe209, 0x70fd, + 0xe405, 0xe4ac, 0x70fd, 0xe4d0, 0xe4fc, 0x10f7, 0xe51e, 0xaf4a, + 0x6110, 0x448f, 0x28cb, 0xe667, 0xe6e9, 0xe6b0, 0xe6b8, 0xe732, + 0xe851, 0xe8c9, 0xe8ea, 0xe943, 0xe9a8, 0xea0e, 0xeb1a, 0xeb5b, + 0x509f, 0xecb8, 0xece3, 0x1f64, 0x6647, 0xef93, 0x43a2, 0xefff, + 0x2011, 0x6152, 0xf0cb, 0x201c, 0x7b5c, 0x60fe, 0x2801, 0x60fa, + 0x8ff0, 0x60f9, 0xaf13, 0x1809, 0x507f, 0x4156, 0x3cf1, 0x212a, + 0x0824, 0xe12c, 0xd39d, 0x0a7a, 0x5fc0, 0x8635, 0xd8e4, 0xe16c, + 0xe199, 0xd53e, 0xc46f, 0x10eb, 0xd1d5, 0xa277, 0xb7b5, 0xba16, + 0x20da, 0xbe01, 0xc118, 0x28ff, 0x7d2d, 0x5f4e, 0x2dad, 0xa3c8, + 0xb05e, 0x361e, 0x70fd, 0x8636, 0x86bb, 0x3770, 0x286d, 0xbc4a, + 0x265a, 0xb5d1, 0x10c6, 0xeb58, 0x1f3d, 0x2862, 0x285e, 0x5149, + 0xbe58, 0x2bb5, 0xa2c0, 0x58f0, 0x205c, 0x7eaa, 0x7c09, 0x9fba, + 0x5317, 0x6dde, 0x5e58, 0x483b, 0x6d45, 0x484e, 0x49b9, 0x6445, + 0x2672, 0x5348, 0x54f7, 0x2865, 0x5332, 0x5618, 0x52bd, 0x282a, + 0x4b62, 0x2883, 0x2656, 0x7d5d, 0x090e, 0x2845, 0x2831, 0x3931, + 0xdb62, 0x096d, 0x4734, 0x2830, 0x27fa, 0x26d7, 0x27b2, 0x7b01, + 0x7b56, 0x3110, 0xb448, 0x7d36, 0x9662, + /* 0x9e */ + 0x7d62, 0x6f2b, 0x4f5a, 0x281e, 0x7f35, 0x34dd, 0x686d, 0x26d4, + 0x5e0d, 0x43f6, 0x6276, 0x363c, 0x35f9, 0x363e, 0x27a9, 0x9583, + 0x6d72, 0x98b3, 0x23da, 0x081f, 0x7c67, 0x23e7, 0x268d, 0x275e, + 0x2753, 0x4866, 0x5f6d, 0xc64a, 0x47b1, 0x52b6, 0x5984, 0x5906, + 0x5a47, 0x53b6, 0x561c, 0x7f81, 0x17ec, 0x4504, 0xac06, 0x2dd0, + 0x550b, 0xc653, 0x28bb, 0x91f4, 0xd72f, 0xa6e3, 0xd773, 0xcc10, + 0xcf76, 0x6270, 0x8099, 0x6308, 0xa2bc, 0xf1a9, 0x7d6c, 0x7db9, + 0x4466, 0x89e2, 0x1a4e, 0xb302, 0xd8b9, 0x7eab, 0x13fa, 0x6d5d, + 0x375f, 0x97a0, 0x1bf3, 0xaca0, 0xeb3c, 0x7eac, 0x7cca, 0x70fd, + 0xd123, 0x7ead, 0x70fd, 0xbf88, 0x8047, 0x43a3, 0x508e, 0x6dd0, + 0x205a, 0x2044, 0x08b7, 0x2d4d, 0x3ef2, 0x25a7, 0x09ec, 0x0d1c, + 0x25bd, 0x09e5, 0xab18, 0x2ada, 0xafae, 0x542d, 0x268b, 0x29ea, + 0xbad5, 0x78b9, 0x70fd, 0x0d92, 0x8fa5, 0x4574, 0xec6c, 0x1fc9, + 0x6ced, 0xa2be, 0xecf0, 0x1f1b, 0xb2e9, 0xe69e, 0xed5e, 0x565c, + 0xa336, 0xcf72, 0xc573, 0xa020, 0x356e, 0x4f25, 0xa437, 0xa3ac, + 0x0d6a, 0x6148, 0x250c, 0x1174, 0x09ba, 0x18e9, 0x754e, 0x4840, + 0x2d30, 0x7d76, 0x4a7a, 0xd86e, 0x2ae7, 0x13bf, 0x28bc, 0x6c8b, + 0x2fb4, 0x4854, 0xf074, 0x6f05, 0x1fa1, 0x70fd, 0x0b3b, 0x3359, + 0x9a5a, 0xa932, 0x70fd, 0x289d, 0x8169, 0x29e7, 0xade3, 0xebc6, + 0x2474, 0xcdee, 0x08ed, 0x70fd, 0x6dfc, + /* 0x9f */ + 0x4e56, 0x6c39, 0x2a1e, 0x85ac, 0x2e93, 0x3713, 0xe650, 0xc1b5, + 0xcea4, 0x586d, 0x7be8, 0xca62, 0xaf62, 0x7c31, 0x70fd, 0x243e, + 0x8b8f, 0x2fce, 0x6803, 0x8a91, 0x6f01, 0x618c, 0x4d1f, 0x6c02, + 0x2f11, 0x4da3, 0x34a8, 0x3575, 0x6bff, 0x4dcf, 0x6c2a, 0x4e7e, + 0x70fd, 0x4e42, 0x4e86, 0x6d15, 0x4dfc, 0x6c09, 0x70fd, 0x6d1b, + 0xadbe, 0x6fda, 0x27b3, 0x2e03, 0x223d, 0x6f18, 0x2232, 0x24a0, + 0x1106, 0x2511, 0x29a7, 0x2296, 0x2bf7, 0x3052, 0x68c8, 0x6e2b, + 0x609c, 0x26a9, 0x68b4, 0x6a40, 0x68ba, 0x256c, 0x3370, 0x3b6c, + 0x261a, 0x6d0a, 0x6d82, 0x1efb, 0x6741, 0x3bc0, 0x22e6, 0x4746, + 0x85ad, 0x6ada, 0x24b3, 0x70fd, 0x6259, 0x6781, 0x625c, 0x70fd, + 0x6251, 0xe397, 0x35bf, 0xca63, 0x3d0a, 0x2851, 0x628e, 0x477a, + 0x34c5, 0x74bc, 0x454f, 0x4e70, 0xbc21, 0xa2bd, 0x70fd, 0xad99, + 0x48d6, 0x6c9d, 0x206a, 0x7b94, 0x55be, 0x59c2, 0x70fd, 0x2e8a, + 0x3c00, 0x70fd, 0x29ba, 0x245f, 0x3035, 0x210e, 0x3e71, 0x72b2, + 0x2179, 0x26dc, 0x271a, 0x24da, 0x5ec2, 0x093e, 0x70fd, 0x0933, + 0x70fd, 0x3d92, 0x627c, 0x7025, 0x6c97, 0x692e, 0x69b4, 0x6bba, + 0x6f28, 0x6f04, 0x437a, 0x4d14, 0x70fd, 0x3e3a, 0x5998, 0x5178, + 0x70fd, 0x2860, 0xf14a, 0x5fb7, 0x6fd3, 0x70fd, 0x5f14, 0x5f8f, + 0x6e9c, 0x5f41, 0x34c2, 0xdbfd, 0x5f68, 0x5fb5, 0x4cd3, 0xaef7, + 0x4c3e, 0x4ad8, 0x3f2a, 0x5be7, 0x4807, + /* 0xa0 */ + 0xe05a, 0x6fa6, 0x3f0e, 0x5956, 0x47c3, 0xefb2, 0x4a53, 0xf200, + 0x5e4c, 0x44e2, 0x4571, 0x5cad, 0x4502, 0x46f1, 0x5e2b, 0xaf3b, + 0x57ef, 0x31fa, 0x5a20, 0x17b7, 0x70fd, 0x867b, 0xcb45, 0x70fd, + 0x5bfe, 0x905b, 0x70fd, 0x333d, 0x4867, 0x6bd7, 0x6dc4, 0x646e, + 0x6c8f, 0x5975, 0x70fd, 0x70fd, 0x5e37, 0x452c, 0x6821, 0x6cb0, + 0x0916, 0x44b2, 0x1ec7, 0x4e51, 0x6a4a, 0xc059, 0x3399, 0x1ec4, + 0x6f16, 0x33bd, 0x70fd, 0x299f, 0x33af, 0x34e6, 0x3479, 0x70fd, + 0x0d9c, 0x3422, 0x25ea, 0x9d35, 0x35a4, 0x3a42, 0x0912, 0x2f97, + 0xe1c2, 0x611a, 0xe339, 0x70fd, 0x2319, 0x8a06, 0x4b06, 0x2572, + 0x6738, 0x7dfb, 0x1365, 0x70fd, 0x49fe, 0x70fd, 0x4ec2, 0xbe9a, + 0x4eda, 0x4c2d, 0x5266, 0x5263, 0x4f4d, 0x4705, 0x46f2, 0x5b14, + 0x541a, 0x394c, 0x5262, 0xd086, 0x525b, 0x46f0, 0x5303, 0x4924, + 0x5b09, 0xc58c, 0x4753, 0xcc11, 0x5929, 0x594e, 0x53c8, 0x590c, + 0x5bc9, 0x5ded, 0x5cc3, 0x492b, 0x46f8, 0x56da, 0x0975, 0x3bf2, + 0x5ee6, 0x70fd, 0x5b29, 0x70fd, 0x3ff9, 0x5941, 0xa551, 0x46e7, + 0x10db, 0x4376, 0x32e4, 0x33dc, 0x0fd1, 0x70fd, 0x32b7, 0x70fd, + 0x5171, 0xe12d, 0x70fd, 0x3329, 0x1e3e, 0x2460, 0x0f58, 0xa287, + 0xbe57, 0xd1d6, 0xb6b1, 0x8784, 0x81be, 0xe883, 0xcb1c, 0xcded, + 0x2f01, 0xc0ad, 0xe00f, 0x9f77, 0x71ee, 0xc606, 0xb24e, 0x1862, + 0x2d5f, 0xc1cc, 0x6fd0, 0x6f26, 0xc12b, +}; +static const unsigned short hkscs1999_2uni_pagec6[471] = { + /* 0xc6 */ + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x0460, + 0x0461, 0x0462, 0x0463, 0x0464, 0x0465, 0x0466, 0x0467, 0x0468, + 0x0469, 0x0474, 0x0475, 0x0476, 0x0477, 0x0478, 0x0479, 0x047a, + 0x047b, 0x047c, 0x047d, 0x0370, 0x0371, 0x0372, 0x0373, 0x0374, + 0x0375, 0x0376, 0x0377, 0x0378, 0x0379, 0x2076, 0x207f, 0x20c5, + 0x20e0, 0x23c2, 0x23d6, 0x23eb, 0x2539, 0x2578, 0x25a9, 0x25f6, + 0x2b4a, 0x2dc0, 0x301b, 0x05b3, 0x30bf, 0x70fd, 0x3190, 0x31a1, + 0x3774, 0x70fd, 0x4792, 0x70fd, 0x60f5, 0x70fd, 0x0028, 0x01c6, + 0x06bd, 0x06be, 0x065d, 0x065e, 0x70fd, 0x70fd, 0x05c5, 0x05c6, + 0x05c7, 0x06bc, 0x70bb, 0x70bd, 0x04fd, 0x0601, 0x0602, 0x0603, + 0x0604, 0x0605, 0x0606, 0x0607, 0x0608, 0x0609, 0x060a, 0x060b, + 0x060c, 0x060d, 0x060e, 0x060f, 0x0610, 0x0611, 0x0612, 0x0613, + 0x0614, 0x0615, 0x0616, 0x0617, 0x0618, + /* 0xc7 */ + 0x0619, 0x061a, 0x061b, 0x061c, 0x061d, 0x061e, 0x061f, 0x0620, + 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, 0x0628, + 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, 0x0630, + 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, 0x0638, + 0x0639, 0x063a, 0x063b, 0x063c, 0x063d, 0x063e, 0x063f, 0x0640, + 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, 0x0648, + 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, 0x0650, + 0x0651, 0x0652, 0x0653, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, + 0x0666, 0x0667, 0x0668, 0x0669, 0x066a, 0x066b, 0x066c, 0x066d, + 0x066e, 0x066f, 0x0670, 0x0671, 0x0672, 0x0673, 0x0674, 0x0675, + 0x0676, 0x0677, 0x0678, 0x0679, 0x067a, 0x067b, 0x067c, 0x067d, + 0x067e, 0x067f, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, + 0x0686, 0x0687, 0x0688, 0x0689, 0x068a, 0x068b, 0x068c, 0x068d, + 0x068e, 0x068f, 0x0690, 0x0691, 0x0692, 0x0693, 0x0694, 0x0695, + 0x0696, 0x0697, 0x0698, 0x0699, 0x069a, 0x069b, 0x069c, 0x069d, + 0x069e, 0x069f, 0x06a0, 0x06a1, 0x06a2, 0x06a3, 0x06a4, 0x06a5, + 0x06a6, 0x06a7, 0x06a8, 0x06a9, 0x06aa, 0x06ab, 0x06ac, 0x06ad, + 0x06ae, 0x06af, 0x06b0, 0x06b1, 0x06b2, 0x06b3, 0x06b4, 0x06b5, + 0x06b6, 0x0210, 0x0211, 0x0212, 0x0213, 0x0214, 0x0215, 0x0201, + 0x0216, 0x0217, 0x0218, 0x0219, 0x021a, + /* 0xc8 */ + 0x021b, 0x021c, 0x021d, 0x021e, 0x021f, 0x0220, 0x0221, 0x0222, + 0x0223, 0x0224, 0x0225, 0x0226, 0x0227, 0x0228, 0x0229, 0x022a, + 0x022b, 0x022c, 0x022d, 0x022e, 0x022f, 0x0230, 0x0231, 0x0232, + 0x0233, 0x0234, 0x0235, 0x0251, 0x0236, 0x0237, 0x0238, 0x0239, + 0x023a, 0x023b, 0x023c, 0x023d, 0x023e, 0x023f, 0x0240, 0x0241, + 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247, 0x0248, 0x0249, + 0x024a, 0x024b, 0x024c, 0x024d, 0x024e, 0x024f, 0x03e7, 0x03b8, + 0x03b9, 0x06cf, 0x71cc, 0x209a, 0x718a, 0x2442, 0x1791, 0x7030, + 0x23c8, 0x7031, 0xd187, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70e2, 0x70e4, 0x7087, 0x7082, 0x0731, + 0x0316, 0x0321, 0x065b, 0x065c, 0x0500, 0x0504, 0x0506, 0x0507, + 0x0508, 0x050a, 0x050c, 0x050d, 0x0515, 0x051c, 0x051d, 0x0525, + 0x0527, 0x052a, 0x052c, 0x052e, 0x0536, 0x053c, 0x053e, 0x0546, + 0x054a, 0x054c, 0x054d, 0x054f, 0x0556, 0x0557, 0x055e, 0x0563, + 0x70fd, 0x70fd, 0x70fd, 0x0183, 0x0150, 0x015b, 0x0154, 0x0175, + 0x00d3, 0x0078, 0x00cb, 0x018a, 0x016a, +}; +static const unsigned short hkscs1999_2uni_pagef9[942] = { + /* 0xf9 */ + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x70fd, + 0x70fd, 0x70fd, 0x70fd, 0x70fd, 0x4a81, 0x63b9, 0x5a4f, 0x2afb, + 0x3292, 0x4ea7, 0x2d3a, 0x0494, 0x04a6, 0x0497, 0x04a0, 0x04ac, + 0x04a3, 0x049a, 0x04a9, 0x049d, 0x0492, 0x04a4, 0x0495, 0x049e, + 0x04aa, 0x04a1, 0x0498, 0x04a7, 0x049b, 0x0493, 0x04a5, 0x0496, + 0x049f, 0x04ab, 0x04a2, 0x0499, 0x04a8, 0x049c, 0x0491, 0x0490, + 0x04ad, 0x04ae, 0x04b0, 0x04af, 0x70ed, + /* 0xfa */ + 0x75c7, 0x63db, 0x765f, 0xa505, 0x574c, 0x15b5, 0x45ef, 0x23f5, + 0x0989, 0xadc2, 0xdfe4, 0x6444, 0x881b, 0x54ee, 0xa288, 0x4a3c, + 0x3984, 0x351f, 0xadb3, 0xdfaa, 0x7360, 0xc8f3, 0x81c5, 0x21eb, + 0x902d, 0x2248, 0xca69, 0xd584, 0x9f00, 0xaf31, 0x9053, 0x70fd, + 0x743e, 0x31e4, 0x7440, 0x7407, 0x40db, 0x74df, 0x70fd, 0x2341, + 0x07ba, 0x234e, 0x696c, 0x0a83, 0x5616, 0xae24, 0x7547, 0x23a0, + 0x9cf4, 0x23aa, 0x7abf, 0x8d3c, 0x73a5, 0x9070, 0x760e, 0x9bb3, + 0x87c3, 0x2dc2, 0x58fd, 0x7633, 0xa259, 0x23f2, 0x23f8, 0x6db4, + 0x2409, 0x240f, 0x2411, 0x0fdc, 0x2413, 0xaf26, 0x23f3, 0x2422, + 0x2582, 0x242d, 0x55cd, 0x3b7e, 0xa02d, 0x31bb, 0x244b, 0x2466, + 0x247c, 0x24f5, 0x2497, 0x24d4, 0x24f9, 0x2505, 0x4e15, 0x5742, + 0x2520, 0x57cd, 0xc853, 0x70fd, 0xe0de, 0x2789, 0x40d9, 0xa4c0, + 0x7894, 0xa52c, 0x2573, 0x70fd, 0x7aa2, 0x3f0b, 0x8566, 0x3a5b, + 0x45d5, 0x328a, 0x11aa, 0x0c0c, 0x8528, 0x43dd, 0x17a2, 0x25ad, + 0x25b4, 0xde2b, 0x25be, 0x70fd, 0x8416, 0x8453, 0x49e6, 0x25d3, + 0xe09b, 0x25e0, 0x25eb, 0x25ee, 0x45a7, 0xb8f2, 0x1259, 0x459c, + 0x2601, 0x2605, 0x3e89, 0x2089, 0x2a3e, 0x2619, 0x0deb, 0x7a4f, + 0x2620, 0xa52b, 0x97a3, 0x2636, 0x7b37, 0x2653, 0x4279, 0x276b, + 0x3897, 0x3f9b, 0x26ad, 0xc893, 0x7c34, 0x279d, 0x26cf, 0x26e4, + 0x1aa6, 0x854d, 0x7d9d, 0x10b4, 0x7c0d, + /* 0xfb */ + 0xdfbc, 0x9198, 0x2787, 0x1fad, 0x266f, 0x4617, 0x27c6, 0x27e9, + 0x70fd, 0x8717, 0xa57a, 0x1852, 0xa975, 0x38f3, 0x7f74, 0x2877, + 0x390d, 0x9c0a, 0x38e4, 0x38ed, 0x288d, 0x288f, 0x4af1, 0x2931, + 0x6887, 0x263e, 0x2940, 0x292f, 0x292d, 0xe166, 0x0963, 0x810f, + 0x2986, 0xa6e5, 0x3eae, 0x428b, 0x2982, 0x09f1, 0xc9be, 0x2a26, + 0x82d6, 0x2a43, 0x8314, 0xa8a3, 0x2a66, 0xaff5, 0x2a9c, 0x2aea, + 0x08a1, 0x2b20, 0x2b1c, 0x80fc, 0x2b3b, 0x2e3f, 0x2983, 0xee90, + 0xa7b8, 0x64d3, 0x08e1, 0x2b5f, 0x3ae6, 0x0a03, 0x4059, 0x847e, + 0x2c64, 0x2793, 0x84d2, 0x5705, 0x2c09, 0x7c0e, 0xc9c1, 0xca6a, + 0x861c, 0x2c19, 0x863b, 0x85f2, 0xcae6, 0x3fb1, 0x8668, 0x8515, + 0x2c39, 0xcb85, 0x2ceb, 0x2ca3, 0x0a26, 0xae29, 0x70fd, 0x0a48, + 0x2cd6, 0x4665, 0x2d13, 0xcce1, 0x9094, 0x1085, 0x8751, 0x0a72, + 0x84f8, 0x30c3, 0x2510, 0x2db6, 0x37c8, 0x2dbc, 0xd50e, 0x1304, + 0x1b5d, 0x72c4, 0x2e15, 0x33a0, 0x8874, 0xba8c, 0x7625, 0x2e33, + 0x2ddd, 0x1fd0, 0x2e45, 0x88c4, 0x2e53, 0x45ce, 0x2e54, 0x89e5, + 0xc868, 0x2e89, 0x1bdd, 0x2ec5, 0x2f29, 0x2f2f, 0x2fcb, 0x8ab9, + 0x8af7, 0x2f50, 0x2f58, 0x2f86, 0x8b24, 0x2efa, 0x3017, 0x54fc, + 0x0b6d, 0xad81, 0x8c89, 0x8db3, 0x5487, 0x0b76, 0x0f02, 0x306e, + 0x3cca, 0x70fd, 0x30ba, 0xa9fc, 0x7b93, 0x25e6, 0x20f7, 0x70fd, + 0x25e8, 0x85b1, 0x3049, 0x3134, 0xdcc2, + /* 0xfc */ + 0x3139, 0x313b, 0x0be0, 0x313c, 0x3a7e, 0x651b, 0x314d, 0x7281, + 0xf254, 0x0e1e, 0x1bae, 0x81fa, 0x317a, 0xc648, 0x8f50, 0x70fd, + 0x8fb1, 0x31a3, 0x68bd, 0xcbae, 0x31b2, 0x6440, 0xe036, 0x31e7, + 0x2ff6, 0x105f, 0xb510, 0x8bea, 0xce38, 0x9168, 0x62d6, 0x735e, + 0xe029, 0x3271, 0x38c5, 0x86b7, 0x0ca3, 0x10c7, 0x0979, 0x29d0, + 0x92b4, 0x4b71, 0x1140, 0x32de, 0x70fd, 0x32f3, 0xae02, 0xae0f, + 0xd553, 0x46a4, 0x2321, 0x2ce0, 0x33a4, 0x5624, 0x3382, 0xf266, + 0xcc12, 0x33c1, 0x2434, 0x76d6, 0x33c7, 0x2dea, 0xa4f7, 0x935f, + 0x3413, 0xe19d, 0xe8dd, 0x3410, 0x0c72, 0x9480, 0x93c1, 0x3263, + 0x339c, 0x375e, 0x35cb, 0x7218, 0x3505, 0x85b0, 0x3515, 0x980d, + 0x35ac, 0xae5f, 0x0d57, 0x3678, 0x3638, 0x824e, 0x863c, 0x70fd, + 0x418a, 0x9836, 0x6914, 0xa5cc, 0xb89d, 0x3721, 0x3725, 0x657b, + 0x0da6, 0x367a, 0x0d97, 0x378d, 0x4116, 0xaea8, 0xaea3, 0x37c5, + 0x37ad, 0x379f, 0x99fe, 0x37f5, 0xadc0, 0x1df7, 0x3811, 0x13d8, + 0x8669, 0x3820, 0x3823, 0x321f, 0x9d40, 0x3858, 0x9b77, 0x9b78, + 0x3884, 0x9b24, 0x9b25, 0x388b, 0x7d35, 0x38a7, 0xb4a6, 0x38b3, + 0x70fd, 0x8afd, 0x9bb1, 0xddb4, 0x9b48, 0xb5d3, 0x49c5, 0x93f7, + 0x6aa4, 0x3942, 0xa8dc, 0xaea1, 0x0e6b, 0x3c3a, 0xa0c2, 0x70fd, + 0x39a7, 0x39a2, 0xa70d, 0xe4ad, 0x3a17, 0x17e9, 0x3a62, 0x4050, + 0x633c, 0x3a41, 0x9d26, 0xcae0, 0x3a9d, + /* 0xfd */ + 0x9daf, 0x3c21, 0x3c4b, 0xe0df, 0x3bb3, 0x3b03, 0x9ecd, 0x3b41, + 0x3b40, 0x1032, 0x0d41, 0x9f3c, 0x0ec0, 0x39ec, 0x3ba1, 0xe04a, + 0x15fc, 0x3b76, 0x3bd8, 0x0ee1, 0x7489, 0x5563, 0x22d0, 0x3c39, + 0x9f59, 0x8d6a, 0x3c85, 0xa003, 0x3cdd, 0x0f33, 0x39f1, 0x3d08, + 0xe55c, 0x0f4d, 0x3d5d, 0x7863, 0x331e, 0x3d75, 0x3db4, 0x92cd, + 0x40b5, 0xa1db, 0x7475, 0x8798, 0x0a80, 0x2661, 0xa21a, 0x3e21, + 0xa43c, 0x3e1c, 0x3e77, 0x8fcb, 0xad71, 0xc891, 0x3e9a, 0x5426, + 0x3eb9, 0xa33c, 0x17c5, 0xa33d, 0xa6e4, 0xad8c, 0xad80, 0xa289, + 0x0a25, 0x0feb, 0x7bf2, 0x6c83, 0x9b79, 0x8fd1, 0x518f, 0x3a77, + 0xca65, 0xcae1, 0xcb2b, 0x3fd6, 0x3f9c, 0x407c, 0x4104, 0xadff, + 0xa5c5, 0xcbb2, 0x5733, 0xccb4, 0x2407, 0x70fd, 0x70fd, 0x562e, + 0xe121, 0x70fd, 0xa3af, 0x4653, 0xa4c2, 0x4bcc, 0x404f, 0x2cd1, + 0x99cb, 0x41f8, 0x0a4d, 0x419d, 0xa3b0, 0x40fa, 0x8357, 0xa57d, + 0x1855, 0x64f0, 0x4144, 0x415c, 0x104e, 0x4174, 0xe530, 0x103b, + 0x419f, 0xa684, 0x41d3, 0xa5d1, 0xa695, 0xa579, 0xa530, 0xa4f4, + 0xa67f, 0x241f, 0xa696, 0xa697, 0xa680, 0xc0dd, 0x424b, 0x427e, + 0x42a7, 0x4281, 0x42cc, 0x42d5, 0x42d6, 0x42df, 0x1404, 0x10e8, + 0x43b4, 0x4396, 0xa7b7, 0x432b, 0x4345, 0x2cc8, 0x434a, 0x70fd, + 0x2edc, 0xa8a5, 0x434f, 0x6462, 0xa801, 0x432c, 0xa99a, 0xaea7, + 0xaea2, 0x43ba, 0xe1e8, 0x42bd, 0x440e, + /* 0xfe */ + 0x6542, 0x4415, 0x2b51, 0x6543, 0x4424, 0x6441, 0xb785, 0x442e, + 0x4440, 0xadf4, 0x3afd, 0x4455, 0x4457, 0x1155, 0x99c4, 0x3a4d, + 0x413d, 0x4482, 0x70fd, 0x452b, 0xace3, 0xdeeb, 0x1bed, 0xdec4, + 0x4528, 0x452e, 0x45cf, 0x45aa, 0x7afa, 0xc7ee, 0x45c9, 0x4649, + 0xa722, 0x8527, 0xaea4, 0x3863, 0x0a05, 0xae37, 0xae0d, 0xae7b, + 0x45f7, 0x4615, 0x3b43, 0xaea6, 0x4639, 0x7643, 0x11d7, 0x70fd, + 0x93ad, 0x4660, 0xe3b2, 0x4647, 0x45e4, 0x4676, 0x55b9, 0x466c, + 0x0a70, 0x4674, 0x64f1, 0x3c6c, 0x4682, 0x1c53, 0xaf0c, 0xa69f, + 0xaef9, 0xe18f, 0x2d86, 0xe203, 0x86de, 0x46c8, 0x87c8, 0x470e, + 0x70fd, 0x471e, 0xe3d9, 0x888b, 0x2e17, 0xe3ac, 0x6485, 0x474d, + 0x474a, 0x4767, 0x476e, 0xb2c2, 0x1204, 0xb0d3, 0x478e, 0x465d, + 0x479e, 0x47b4, 0x4802, 0x482c, 0x4851, 0x484f, 0x486f, 0x4876, + 0xc275, 0x4890, 0x53ef, 0x0b38, 0xc6d1, 0xc6ce, 0x48a1, 0x48a5, + 0x48b7, 0x48cc, 0xccdf, 0x5662, 0xb3dd, 0xb47d, 0x8adc, 0x491e, + 0x4926, 0x4940, 0x36ef, 0xb4e0, 0x4958, 0x9c2c, 0x49af, 0xdf64, + 0xdf68, 0x8501, 0x49f4, 0x70fd, 0x8236, 0xae92, 0x3b0a, 0x4aaf, + 0x4ac7, 0x4ad3, 0x67a5, 0x4b2e, 0xb760, 0x4ad7, 0x4b34, 0x4ab1, + 0xd18c, 0x60f8, 0x5a04, 0xe12b, 0xbfc3, 0x911c, 0x4b86, 0x5a80, + 0x3b42, 0x4b80, 0xb957, 0x4b9d, 0xd639, 0x4b3c, 0x4ba9, 0x402a, + 0xce66, 0x11a8, 0x4bc6, 0xe4cd, 0x4bd4, +}; + +static const ucs4_t hkscs1999_2uni_upages[973] = { + 0x00080, 0x000c0, 0x00100, 0x00140, 0x001c0, 0x00240, 0x00280, 0x002c0, + 0x00400, 0x00440, 0x01e80, 0x01ec0, 0x02100, 0x02140, 0x02180, 0x021c0, + 0x023c0, 0x02440, 0x02540, 0x02700, 0x02e80, 0x02ec0, 0x02f00, 0x03000, + 0x03040, 0x03080, 0x030c0, 0x031c0, 0x03200, 0x03400, 0x03440, 0x03480, + 0x034c0, 0x03500, 0x03540, 0x03580, 0x035c0, 0x03600, 0x03640, 0x03680, + 0x036c0, 0x03700, 0x03740, 0x03780, 0x037c0, 0x03800, 0x03840, 0x03880, + 0x038c0, 0x03900, 0x03940, 0x03980, 0x039c0, 0x03a00, 0x03a40, 0x03a80, + 0x03ac0, 0x03b00, 0x03b40, 0x03b80, 0x03bc0, 0x03c00, 0x03c40, 0x03cc0, + 0x03d00, 0x03d40, 0x03d80, 0x03dc0, 0x03e00, 0x03e40, 0x03e80, 0x03ec0, + 0x03f00, 0x03f40, 0x03f80, 0x03fc0, 0x04000, 0x04040, 0x04080, 0x040c0, + 0x04100, 0x04140, 0x04180, 0x041c0, 0x04200, 0x04240, 0x04280, 0x042c0, + 0x04300, 0x04340, 0x04380, 0x043c0, 0x04400, 0x04440, 0x04480, 0x044c0, + 0x04500, 0x04540, 0x04580, 0x045c0, 0x04600, 0x04640, 0x04680, 0x046c0, + 0x04700, 0x04740, 0x04780, 0x047c0, 0x04800, 0x04840, 0x04880, 0x048c0, + 0x04900, 0x04940, 0x04980, 0x049c0, 0x04a00, 0x04a80, 0x04ac0, 0x04b00, + 0x04b40, 0x04b80, 0x04bc0, 0x04c00, 0x04c40, 0x04c80, 0x04cc0, 0x04d00, + 0x04d80, 0x04e00, 0x04e40, 0x04e80, 0x04ec0, 0x04f00, 0x04f40, 0x04f80, + 0x04fc0, 0x05000, 0x05040, 0x05080, 0x050c0, 0x05100, 0x05140, 0x05180, + 0x051c0, 0x05200, 0x05240, 0x05280, 0x052c0, 0x05300, 0x05340, 0x05380, + 0x053c0, 0x05400, 0x05440, 0x05480, 0x054c0, 0x05500, 0x05540, 0x05580, + 0x055c0, 0x05600, 0x05640, 0x05680, 0x056c0, 0x05700, 0x05740, 0x05780, + 0x057c0, 0x05800, 0x05840, 0x05880, 0x058c0, 0x05900, 0x05940, 0x05980, + 0x059c0, 0x05a00, 0x05a40, 0x05a80, 0x05ac0, 0x05b00, 0x05b40, 0x05b80, + 0x05bc0, 0x05c00, 0x05c40, 0x05c80, 0x05cc0, 0x05d00, 0x05d40, 0x05d80, + 0x05dc0, 0x05e00, 0x05e40, 0x05e80, 0x05ec0, 0x05f00, 0x05f40, 0x05f80, + 0x05fc0, 0x06000, 0x06040, 0x06080, 0x060c0, 0x06100, 0x06140, 0x06180, + 0x061c0, 0x06200, 0x06240, 0x06280, 0x062c0, 0x06300, 0x06340, 0x06380, + 0x063c0, 0x06400, 0x06440, 0x06480, 0x064c0, 0x06500, 0x06540, 0x06580, + 0x065c0, 0x06600, 0x06640, 0x06680, 0x066c0, 0x06700, 0x06740, 0x06780, + 0x067c0, 0x06800, 0x06840, 0x06880, 0x068c0, 0x06900, 0x06940, 0x06980, + 0x069c0, 0x06a00, 0x06a40, 0x06a80, 0x06ac0, 0x06b00, 0x06b40, 0x06b80, + 0x06bc0, 0x06c00, 0x06c40, 0x06c80, 0x06cc0, 0x06d00, 0x06d40, 0x06d80, + 0x06e00, 0x06e40, 0x06e80, 0x06ec0, 0x06f00, 0x06f40, 0x06f80, 0x06fc0, + 0x07000, 0x07040, 0x07080, 0x070c0, 0x07100, 0x07140, 0x07180, 0x071c0, + 0x07200, 0x07240, 0x07280, 0x072c0, 0x07300, 0x07340, 0x07380, 0x073c0, + 0x07400, 0x07440, 0x07480, 0x074c0, 0x07500, 0x07540, 0x07580, 0x075c0, + 0x07600, 0x07640, 0x07680, 0x076c0, 0x07700, 0x07740, 0x07780, 0x077c0, + 0x07800, 0x07840, 0x07880, 0x078c0, 0x07900, 0x07940, 0x07980, 0x079c0, + 0x07a00, 0x07a40, 0x07a80, 0x07ac0, 0x07b00, 0x07b40, 0x07b80, 0x07bc0, + 0x07c00, 0x07c40, 0x07c80, 0x07cc0, 0x07d00, 0x07d40, 0x07d80, 0x07dc0, + 0x07e00, 0x07e40, 0x07e80, 0x07ec0, 0x07f00, 0x07f40, 0x07f80, 0x07fc0, + 0x08000, 0x08040, 0x08080, 0x080c0, 0x08100, 0x08140, 0x08180, 0x081c0, + 0x08200, 0x08240, 0x08280, 0x082c0, 0x08300, 0x08340, 0x08380, 0x083c0, + 0x08400, 0x08440, 0x08480, 0x084c0, 0x08500, 0x08540, 0x085c0, 0x08600, + 0x08640, 0x08680, 0x086c0, 0x08740, 0x08780, 0x087c0, 0x08800, 0x08840, + 0x08880, 0x088c0, 0x08900, 0x08940, 0x08980, 0x089c0, 0x08a00, 0x08a40, + 0x08a80, 0x08ac0, 0x08b00, 0x08b40, 0x08b80, 0x08bc0, 0x08c40, 0x08c80, + 0x08cc0, 0x08d00, 0x08d40, 0x08d80, 0x08dc0, 0x08e00, 0x08e40, 0x08e80, + 0x08ec0, 0x08f00, 0x08f40, 0x08f80, 0x08fc0, 0x09000, 0x09040, 0x09080, + 0x090c0, 0x09140, 0x09180, 0x091c0, 0x09200, 0x09240, 0x09280, 0x092c0, + 0x09300, 0x09340, 0x09380, 0x093c0, 0x09400, 0x09440, 0x09480, 0x094c0, + 0x09500, 0x09540, 0x09580, 0x095c0, 0x09600, 0x09640, 0x09680, 0x096c0, + 0x09700, 0x09740, 0x09780, 0x097c0, 0x09800, 0x09840, 0x09880, 0x098c0, + 0x09900, 0x09940, 0x09980, 0x099c0, 0x09a00, 0x09a40, 0x09a80, 0x09ac0, + 0x09b00, 0x09b40, 0x09b80, 0x09bc0, 0x09c00, 0x09c40, 0x09d00, 0x09d40, + 0x09d80, 0x09dc0, 0x09e00, 0x09e40, 0x09e80, 0x09ec0, 0x09f00, 0x09f40, + 0x09f80, 0x0f900, 0x0ff00, 0x0ffc0, 0x20000, 0x20040, 0x20080, 0x200c0, + 0x20100, 0x20180, 0x201c0, 0x20200, 0x20240, 0x20280, 0x202c0, 0x20300, + 0x20340, 0x20380, 0x203c0, 0x20400, 0x20440, 0x20480, 0x204c0, 0x20540, + 0x20580, 0x205c0, 0x20600, 0x20640, 0x20700, 0x20740, 0x20800, 0x20840, + 0x208c0, 0x20900, 0x20940, 0x209c0, 0x20a00, 0x20a40, 0x20a80, 0x20ac0, + 0x20b00, 0x20b80, 0x20bc0, 0x20c00, 0x20c40, 0x20c80, 0x20cc0, 0x20d00, + 0x20d40, 0x20d80, 0x20dc0, 0x20e00, 0x20e40, 0x20e80, 0x20ec0, 0x20f00, + 0x20f40, 0x20f80, 0x20fc0, 0x21000, 0x21040, 0x21080, 0x210c0, 0x21100, + 0x21140, 0x21180, 0x211c0, 0x21200, 0x21240, 0x21280, 0x212c0, 0x21300, + 0x21340, 0x21380, 0x213c0, 0x21400, 0x21440, 0x21480, 0x214c0, 0x21540, + 0x21580, 0x21600, 0x21640, 0x21680, 0x216c0, 0x21700, 0x21740, 0x21780, + 0x217c0, 0x21800, 0x21840, 0x21880, 0x218c0, 0x21900, 0x21940, 0x21980, + 0x219c0, 0x21a00, 0x21a40, 0x21b40, 0x21bc0, 0x21c00, 0x21c40, 0x21c80, + 0x21d40, 0x21d80, 0x21dc0, 0x21e00, 0x21e80, 0x21ec0, 0x21f00, 0x21f40, + 0x21f80, 0x21fc0, 0x22040, 0x22080, 0x220c0, 0x22100, 0x22140, 0x22180, + 0x221c0, 0x22200, 0x22240, 0x22300, 0x22380, 0x223c0, 0x22440, 0x22480, + 0x224c0, 0x22500, 0x22540, 0x22580, 0x22600, 0x22640, 0x22680, 0x226c0, + 0x22700, 0x22740, 0x22780, 0x227c0, 0x22800, 0x22840, 0x22880, 0x228c0, + 0x22900, 0x22940, 0x22980, 0x22a40, 0x22ac0, 0x22b00, 0x22b40, 0x22bc0, + 0x22c00, 0x22c40, 0x22c80, 0x22cc0, 0x22d00, 0x22d40, 0x22d80, 0x22dc0, + 0x22e00, 0x22e40, 0x22e80, 0x22ec0, 0x22f40, 0x22fc0, 0x23000, 0x23040, + 0x23080, 0x230c0, 0x23100, 0x23140, 0x23180, 0x231c0, 0x23200, 0x23240, + 0x23280, 0x232c0, 0x23300, 0x23380, 0x233c0, 0x23400, 0x23440, 0x234c0, + 0x23500, 0x23540, 0x23580, 0x235c0, 0x23600, 0x23640, 0x23680, 0x236c0, + 0x23700, 0x23740, 0x23780, 0x237c0, 0x23800, 0x239c0, 0x23a80, 0x23ac0, + 0x23b40, 0x23c80, 0x23cc0, 0x23d40, 0x23d80, 0x23dc0, 0x23e00, 0x23e80, + 0x23ec0, 0x23f00, 0x23f40, 0x23f80, 0x23fc0, 0x24000, 0x24040, 0x24080, + 0x240c0, 0x24100, 0x24140, 0x24180, 0x241c0, 0x24200, 0x24240, 0x24280, + 0x242c0, 0x24300, 0x24340, 0x24380, 0x243c0, 0x24400, 0x24440, 0x24480, + 0x244c0, 0x24500, 0x24540, 0x245c0, 0x24600, 0x24640, 0x24680, 0x246c0, + 0x24700, 0x24780, 0x247c0, 0x24800, 0x24880, 0x248c0, 0x24900, 0x24940, + 0x24980, 0x249c0, 0x24a00, 0x24a40, 0x24a80, 0x24ac0, 0x24b40, 0x24bc0, + 0x24c00, 0x24c80, 0x24cc0, 0x24d00, 0x24d80, 0x24dc0, 0x24e00, 0x24e40, + 0x24e80, 0x24f00, 0x24f40, 0x24f80, 0x24fc0, 0x25000, 0x25040, 0x25080, + 0x25100, 0x25140, 0x251c0, 0x25200, 0x25240, 0x25280, 0x252c0, 0x25300, + 0x25400, 0x25440, 0x25500, 0x25540, 0x25580, 0x255c0, 0x25600, 0x25640, + 0x25680, 0x256c0, 0x25700, 0x25740, 0x257c0, 0x25840, 0x258c0, 0x25900, + 0x25940, 0x25980, 0x259c0, 0x25a80, 0x25ac0, 0x25b40, 0x25b80, 0x25bc0, + 0x25c00, 0x25c40, 0x25c80, 0x25cc0, 0x25d00, 0x25d40, 0x25e00, 0x25e40, + 0x25e80, 0x25ec0, 0x25f00, 0x25f40, 0x25fc0, 0x26000, 0x26040, 0x26080, + 0x26100, 0x26140, 0x26180, 0x261c0, 0x26240, 0x262c0, 0x26300, 0x26340, + 0x26380, 0x263c0, 0x26400, 0x26440, 0x26480, 0x26500, 0x26540, 0x26580, + 0x26600, 0x26680, 0x266c0, 0x26700, 0x26740, 0x26780, 0x267c0, 0x26800, + 0x26840, 0x26880, 0x268c0, 0x26900, 0x26940, 0x26980, 0x269c0, 0x26a00, + 0x26a40, 0x26b00, 0x26b40, 0x26b80, 0x26bc0, 0x26c00, 0x26c40, 0x26c80, + 0x26cc0, 0x26d00, 0x26d40, 0x26d80, 0x26dc0, 0x26e00, 0x26e40, 0x26e80, + 0x26ec0, 0x26f00, 0x26f40, 0x26f80, 0x26fc0, 0x27000, 0x27040, 0x27080, + 0x270c0, 0x27100, 0x27140, 0x271c0, 0x27200, 0x27280, 0x272c0, 0x27380, + 0x27400, 0x27440, 0x27480, 0x27540, 0x27580, 0x275c0, 0x27600, 0x27640, + 0x27680, 0x27700, 0x27740, 0x27780, 0x277c0, 0x27840, 0x27880, 0x278c0, + 0x27900, 0x27940, 0x27980, 0x279c0, 0x27a00, 0x27a40, 0x27a80, 0x27ac0, + 0x27b00, 0x27b40, 0x27bc0, 0x27c00, 0x27d00, 0x27d40, 0x27d80, 0x27dc0, + 0x27e40, 0x27f00, 0x27fc0, 0x28000, 0x28040, 0x28080, 0x280c0, 0x28100, + 0x28140, 0x28180, 0x28200, 0x28240, 0x28280, 0x282c0, 0x28300, 0x28340, + 0x28380, 0x28400, 0x28440, 0x28480, 0x28500, 0x28540, 0x285c0, 0x28600, + 0x28680, 0x286c0, 0x28700, 0x28800, 0x28900, 0x28940, 0x28980, 0x289c0, + 0x28a00, 0x28a40, 0x28a80, 0x28ac0, 0x28b00, 0x28b40, 0x28b80, 0x28bc0, + 0x28c00, 0x28cc0, 0x28d00, 0x28d80, 0x28e00, 0x28e40, 0x28e80, 0x28ec0, + 0x28fc0, 0x29080, 0x290c0, 0x29100, 0x29140, 0x29180, 0x291c0, 0x29400, + 0x29440, 0x294c0, 0x29580, 0x295c0, 0x29700, 0x297c0, 0x29800, 0x29840, + 0x29880, 0x298c0, 0x29900, 0x29940, 0x29980, 0x299c0, 0x29a00, 0x29a40, + 0x29b00, 0x29bc0, 0x29c80, 0x29d00, 0x29d40, 0x29d80, 0x29dc0, 0x29e00, + 0x29e40, 0x29e80, 0x29ec0, 0x29f00, 0x29f80, 0x29fc0, 0x2a000, 0x2a080, + 0x2a0c0, 0x2a100, 0x2a140, 0x2a180, 0x2a1c0, 0x2a200, 0x2a280, 0x2a2c0, + 0x2a380, 0x2a400, 0x2a440, 0x2a5c0, 0x2a600, 0x2a640, 0x2a680, 0x2f800, + 0x2f840, 0x2f880, 0x2f8c0, 0x2f980, 0x2f9c0, +}; + +static int +hkscs1999_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x88 && c1 <= 0x8b) || (c1 >= 0x8d && c1 <= 0xa0) || (c1 >= 0xc6 && c1 <= 0xc8) || (c1 >= 0xf9 && c1 <= 0xfe)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) { + unsigned int i = 157 * (c1 - 0x80) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); + ucs4_t wc = 0xfffd; + unsigned short swc; + if (i < 2041) { + if (i < 1883) + swc = hkscs1999_2uni_page88[i-1256], + wc = hkscs1999_2uni_upages[swc>>6] | (swc & 0x3f); + } else if (i < 10990) { + if (i < 5181) + swc = hkscs1999_2uni_page8d[i-2041], + wc = hkscs1999_2uni_upages[swc>>6] | (swc & 0x3f); + } else if (i < 18997) { + if (i < 11461) + swc = hkscs1999_2uni_pagec6[i-10990], + wc = hkscs1999_2uni_upages[swc>>6] | (swc & 0x3f); + } else { + if (i < 19939) + swc = hkscs1999_2uni_pagef9[i-18997], + wc = hkscs1999_2uni_upages[swc>>6] | (swc & 0x3f); + } + if (wc != 0xfffd) { + *pwc = wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short hkscs1999_2charset[4698] = { + 0xc6d8, 0x8859, 0x8857, 0x885d, 0x885b, 0x8866, 0x8861, 0x885f, + 0x886a, 0x8868, 0x886f, 0x886d, 0x88a7, 0x8873, 0x8871, 0x8877, + 0x8875, 0xc8fb, 0x887b, 0x8879, 0x88a2, 0x8856, 0x8867, 0x885a, + 0x886c, 0x885c, 0x886e, 0x8870, 0xc8fc, 0x885e, 0x8874, 0xc8fa, + 0x8878, 0x8858, 0x8869, 0x8872, 0x8860, 0x8876, 0x887a, 0x887c, + 0x887d, 0x887e, 0x88a1, 0xc8f6, 0x886b, 0xc8f8, 0xc8f7, 0x88a8, + 0xc8fe, 0xc8f9, 0xc8f5, 0xc8fd, 0xc6d9, 0xc7f9, 0xc7f3, 0xc7f4, + 0xc7f5, 0xc7f6, 0xc7f7, 0xc7f8, 0xc7fa, 0xc7fb, 0xc7fc, 0xc7fd, + 0xc7fe, 0xc840, 0xc841, 0xc842, 0xc843, 0xc844, 0xc845, 0xc846, + 0xc847, 0xc848, 0xc849, 0xc84a, 0xc84b, 0xc84c, 0xc84d, 0xc84e, + 0xc84f, 0xc850, 0xc851, 0xc852, 0xc853, 0xc854, 0xc855, 0xc856, + 0xc857, 0xc858, 0xc859, 0xc85a, 0xc85c, 0xc85d, 0xc85e, 0xc85f, + 0xc860, 0xc861, 0xc862, 0xc863, 0xc864, 0xc865, 0xc866, 0xc867, + 0xc868, 0xc869, 0xc86a, 0xc86b, 0xc86c, 0xc86d, 0xc86e, 0xc86f, + 0xc870, 0xc871, 0xc872, 0xc873, 0xc874, 0xc875, 0xc85b, 0x8863, + 0x88a4, 0x8865, 0x88a6, 0xc8d2, 0xc8d3, 0xc6b5, 0xc6b6, 0xc6b7, + 0xc6b8, 0xc6b9, 0xc6ba, 0xc6bb, 0xc6bc, 0xc6bd, 0xc6be, 0xc877, + 0xc878, 0xc876, 0x88a9, 0x88aa, 0xc6a1, 0xc6a2, 0xc6a3, 0xc6a4, + 0xc6a5, 0xc6a6, 0xc6a7, 0xc6a8, 0xc6a9, 0xc6aa, 0xc6ab, 0xc6ac, + 0xc6ad, 0xc6ae, 0xc6af, 0xc6b0, 0xc6b1, 0xc6b2, 0xc6b3, 0xc6b4, + 0xf9f9, 0xf9f8, 0xf9e6, 0xf9ef, 0xf9dd, 0xf9e8, 0xf9f1, 0xf9df, + 0xf9ec, 0xf9f5, 0xf9e3, 0xf9ee, 0xf9f7, 0xf9e5, 0xf9e9, 0xf9f2, + 0xf9e0, 0xf9eb, 0xf9f4, 0xf9e2, 0xf9e7, 0xf9f0, 0xf9de, 0xf9ed, + 0xf9f6, 0xf9e4, 0xf9ea, 0xf9f3, 0xf9e1, 0xf9fa, 0xf9fb, 0xf9fd, + 0xf9fc, 0xc6e6, 0xc8d6, 0xc8d7, 0xc8d8, 0xc8d9, 0xc8da, 0xc8db, + 0xc8dc, 0xc8dd, 0xc8de, 0xc8df, 0xc8e0, 0xc8e1, 0xc8e2, 0xc8e3, + 0xc8e4, 0xc8e5, 0xc8e6, 0xc8e7, 0xc8e8, 0xc8e9, 0xc8ea, 0xc8eb, + 0xc8ec, 0xc8ed, 0xc8ee, 0xc8ef, 0xc8f0, 0xc8f1, 0xc6cd, 0xc6e0, + 0xc6e1, 0xc6e2, 0xc6e7, 0xc6e8, 0xc6e9, 0xc6ea, 0xc6eb, 0xc6ec, + 0xc6ed, 0xc6ee, 0xc6ef, 0xc6f0, 0xc6f1, 0xc6f2, 0xc6f3, 0xc6f4, + 0xc6f5, 0xc6f6, 0xc6f7, 0xc6f8, 0xc6f9, 0xc6fa, 0xc6fb, 0xc6fc, + 0xc6fd, 0xc6fe, 0xc740, 0xc741, 0xc742, 0xc743, 0xc744, 0xc745, + 0xc746, 0xc747, 0xc748, 0xc749, 0xc74a, 0xc74b, 0xc74c, 0xc74d, + 0xc74e, 0xc74f, 0xc750, 0xc751, 0xc752, 0xc753, 0xc754, 0xc755, + 0xc756, 0xc757, 0xc758, 0xc759, 0xc75a, 0xc75b, 0xc75c, 0xc75d, + 0xc75e, 0xc75f, 0xc760, 0xc761, 0xc762, 0xc763, 0xc764, 0xc765, + 0xc766, 0xc767, 0xc768, 0xc769, 0xc76a, 0xc76b, 0xc76c, 0xc76d, + 0xc76e, 0xc76f, 0xc770, 0xc771, 0xc772, 0xc773, 0xc774, 0xc775, + 0xc776, 0xc777, 0xc778, 0xc779, 0xc77a, 0xc8d4, 0xc8d5, 0xc6dc, + 0xc6dd, 0xc77b, 0xc77c, 0xc77d, 0xc77e, 0xc7a1, 0xc7a2, 0xc7a3, + 0xc7a4, 0xc7a5, 0xc7a6, 0xc7a7, 0xc7a8, 0xc7a9, 0xc7aa, 0xc7ab, + 0xc7ac, 0xc7ad, 0xc7ae, 0xc7af, 0xc7b0, 0xc7b1, 0xc7b2, 0xc7b3, + 0xc7b4, 0xc7b5, 0xc7b6, 0xc7b7, 0xc7b8, 0xc7b9, 0xc7ba, 0xc7bb, + 0xc7bc, 0xc7bd, 0xc7be, 0xc7bf, 0xc7c0, 0xc7c1, 0xc7c2, 0xc7c3, + 0xc7c4, 0xc7c5, 0xc7c6, 0xc7c7, 0xc7c8, 0xc7c9, 0xc7ca, 0xc7cb, + 0xc7cc, 0xc7cd, 0xc7ce, 0xc7cf, 0xc7d0, 0xc7d1, 0xc7d2, 0xc7d3, + 0xc7d4, 0xc7d5, 0xc7d6, 0xc7d7, 0xc7d8, 0xc7d9, 0xc7da, 0xc7db, + 0xc7dc, 0xc7dd, 0xc7de, 0xc7df, 0xc7e0, 0xc7e1, 0xc7e2, 0xc7e3, + 0xc7e4, 0xc7e5, 0xc7e6, 0xc7e7, 0xc7e8, 0xc7e9, 0xc7ea, 0xc7eb, + 0xc7ec, 0xc7ed, 0xc7ee, 0xc7ef, 0xc7f0, 0xc7f1, 0xc7f2, 0xc6e3, + 0xc6da, 0xc6db, 0x8840, 0x8841, 0x8842, 0x8843, 0x8844, 0x8846, + 0x8849, 0x884a, 0x884d, 0x884f, 0x8850, 0x8851, 0x8852, 0x8854, + 0x8855, 0xc879, 0xc8d1, 0x9277, 0x96df, 0x89d5, 0x93cd, 0x9bdf, + 0xfa68, 0x89da, 0x8f59, 0x89db, 0x8f5d, 0x89dc, 0x96f7, 0x8ada, + 0x8bdc, 0x97db, 0x9e53, 0x9daa, 0x9bea, 0x8a6e, 0x8bc8, 0x89e8, + 0x89ea, 0xfb70, 0x89ed, 0x94dd, 0x89ee, 0x9eb4, 0x8ad3, 0x92db, + 0x94db, 0x89f9, 0xfb7a, 0x89fb, 0x9efc, 0x89fc, 0x89bf, 0x89fe, + 0x89e6, 0x9d46, 0x9dee, 0xa07e, 0xa068, 0x98e9, 0x8b68, 0x8dfd, + 0x8bbe, 0x9fd9, 0x8aeb, 0x9fd7, 0x8b6a, 0x9c5c, 0x8bb1, 0xfb5e, + 0x9df3, 0xa0d0, 0xfc66, 0x92e9, 0x9aec, 0x8fab, 0xfa48, 0x8e45, + 0x9c6f, 0x9ede, 0x89ef, 0x96e9, 0x9ebb, 0x94de, 0x9eb8, 0x97ba, + 0xfb65, 0x95d6, 0x9cbb, 0x97da, 0x8f45, 0xfb7d, 0x9158, 0xfe64, + 0x9856, 0x9b4d, 0x935b, 0x95c7, 0x97e7, 0x9359, 0x91f5, 0x97b8, + 0xfda2, 0xfbb6, 0x92fa, 0x9357, 0x8ba6, 0xfbb9, 0x97b0, 0xfdc4, + 0x9ca1, 0x91f2, 0x91f9, 0x8ff1, 0x9745, 0x9853, 0xfe78, 0xfbc1, + 0x9251, 0x9dad, 0xfd6c, 0xfa6b, 0x9bc2, 0x9a7b, 0x8b60, 0x934b, + 0x9abd, 0x91b7, 0x95b4, 0xfec5, 0x9ef0, 0x8d64, 0x9269, 0x8d67, + 0xfbea, 0xfbef, 0x8d68, 0x93eb, 0xfc42, 0x9166, 0xfacd, 0x93dd, + 0x8bcc, 0x8d6d, 0x8d6e, 0x96a8, 0xfca6, 0x8d6f, 0x8d70, 0xfc64, + 0x9060, 0x8d74, 0x97c3, 0x8ad0, 0x9274, 0x9bbe, 0x9cc8, 0x9cba, + 0x8d78, 0x9eb9, 0x955a, 0x91b4, 0x8a48, 0x8d7d, 0x8a7d, 0x8ac2, + 0xfd4a, 0x8da1, 0x8ad1, 0xfcb4, 0x8b47, 0x93a4, 0x9eda, 0x8a51, + 0x8da6, 0x9ec5, 0xfcc4, 0xa078, 0x94b5, 0xfcc2, 0x8a6b, 0x8dab, + 0xfae8, 0x8dad, 0xfc49, 0x93c1, 0x906f, 0x8db0, 0x947e, 0x90fa, + 0x9479, 0x8db2, 0xfcee, 0x997b, 0x8db4, 0x8db7, 0x91b3, 0x8dbb, + 0x8dba, 0x8dbc, 0x9044, 0xfd4c, 0x93e4, 0x93e0, 0xfd53, 0x8dc3, + 0x9bb8, 0xfbf0, 0x93e9, 0x93f6, 0x8dc5, 0x8dca, 0x8dcc, 0xfd5d, + 0x93b5, 0xfd61, 0x9cf8, 0x9252, 0xa0e8, 0x9ca5, 0x8dd6, 0x97c0, + 0xa0de, 0x97d2, 0xfaa5, 0xfda3, 0x8ddb, 0x8eaf, 0x91b5, 0xfd49, + 0xfdd1, 0x8deb, 0x97c6, 0xfdce, 0x90fc, 0xfc59, 0x96d6, 0x97c5, + 0x8def, 0x97d7, 0x8df0, 0x96a6, 0xfbbf, 0x8df3, 0x9449, 0x8df5, + 0x9872, 0x8e6b, 0xfafd, 0x8f50, 0x9dcc, 0xfc65, 0x996e, 0x94a1, + 0x8f63, 0xa0da, 0x9253, 0xfde9, 0x9db5, 0x9879, 0x9d5d, 0x8d63, + 0x9669, 0x9f70, 0xfc6a, 0x8ac7, 0x89d7, 0xfe4d, 0x9edd, 0xfefb, + 0x98bc, 0xfacc, 0x95b0, 0x9464, 0x936f, 0x94b9, 0x95ec, 0x91ee, + 0x98c3, 0x95f6, 0x8ffd, 0x98c5, 0x9766, 0xfe6e, 0x97dd, 0x92d2, + 0x9761, 0x98cb, 0x95f0, 0x975d, 0x91e3, 0x98cc, 0x9469, 0x98cd, + 0x98ce, 0x95fc, 0x94a3, 0x9662, 0xfeb6, 0x9463, 0x98d0, 0x98d1, + 0x9475, 0xfae0, 0x9472, 0x98d6, 0x8af0, 0x98d9, 0x98db, 0x98dd, + 0x98a8, 0x8a6d, 0x8afb, 0x8aae, 0xfbc9, 0x98e4, 0x98e6, 0x98e8, + 0x8a4d, 0x9257, 0x95df, 0xa0ac, 0x98eb, 0x98ec, 0x98f4, 0x8ab8, + 0x9ee7, 0x94bc, 0xfcd1, 0x9cc6, 0x9e7e, 0x98fe, 0xfde8, 0x9940, + 0x94c9, 0x94d3, 0x9946, 0x90c0, 0x94d1, 0x9573, 0x93c2, 0x9948, + 0x994b, 0x8e55, 0x994e, 0x8efe, 0x8e59, 0x94ec, 0x94ef, 0x8f74, + 0x9955, 0x9544, 0x9956, 0x9959, 0x995b, 0xfa45, 0x90b7, 0x9743, + 0x95cd, 0x97c9, 0xfd50, 0x8eb9, 0x95c6, 0x9967, 0x8ab9, 0x8dfc, + 0x8a76, 0x9d51, 0x9973, 0x9d4f, 0x997a, 0x9564, 0x99a1, 0x99a5, + 0x99a7, 0x8eed, 0x99ad, 0xc87e, 0x946e, 0x8f70, 0xfad0, 0x99b3, + 0xa053, 0x965c, 0xfd7a, 0x97fe, 0x92bd, 0x97fd, 0x8f64, 0xfcf7, + 0x9562, 0x97cd, 0x9e64, 0x924c, 0x8ec9, 0x99bc, 0x9da5, 0x8f54, + 0x8f7c, 0x8ea2, 0x8f7a, 0x97ae, 0x96c8, 0x99c3, 0x90d6, 0x9cbe, + 0x8f76, 0x9470, 0xfb4b, 0xfdca, 0x8ec7, 0xa0f9, 0x8fa9, 0x99c7, + 0x90d7, 0x9edf, 0x99ce, 0x8fba, 0x8feb, 0x99cf, 0x8fc2, 0x92c9, + 0x97dc, 0x95b3, 0x9c79, 0x95b2, 0x8fdb, 0x9be3, 0x9e7a, 0x9bee, + 0x99de, 0xfafa, 0x8a52, 0x99e1, 0x8a67, 0x8bb5, 0x8aac, 0x99e9, + 0xfbca, 0x97de, 0x95d1, 0x99f5, 0xfc4a, 0x9ba9, 0xfbdc, 0xfe56, + 0x9ea4, 0x9d49, 0x95db, 0x89c5, 0x99f8, 0x9664, 0x9055, 0x96d4, + 0x977c, 0x964d, 0x97e1, 0x9a48, 0x9a49, 0xfe7d, 0x90aa, 0x9a50, + 0x9347, 0x8ed8, 0x90c9, 0x9a55, 0x90bc, 0x9a58, 0x8bb8, 0x90d5, + 0x9641, 0x9a5a, 0x9a5c, 0x97c2, 0x8abb, 0x9baa, 0x90f5, 0x9a60, + 0x9145, 0x9a63, 0x8bb6, 0xfccf, 0x966b, 0x9a6e, 0x914f, 0x9746, + 0xa0e6, 0x92d7, 0x9675, 0x93d4, 0x91bb, 0x9679, 0x9a70, 0x9678, + 0x91cd, 0x9c4a, 0xa06f, 0xa06a, 0x915f, 0x9fa5, 0x89ba, 0x9ecd, + 0x9a79, 0x9dce, 0x9d73, 0x96b9, 0x96bc, 0x9cd1, 0x89b7, 0x9eee, + 0xfb43, 0x9ec9, 0xfbd3, 0x91ae, 0x9d78, 0x9d7b, 0x9eb3, 0x9eb2, + 0x9dd6, 0x994f, 0x89ce, 0x8bc0, 0x9fc4, 0x8bd4, 0xc6bf, 0x8bf9, + 0x8946, 0xc6c0, 0xfae5, 0xc87b, 0x8bc6, 0x9c57, 0x9afb, 0x89d0, + 0x89cf, 0xc6c1, 0x89d1, 0x89e2, 0x927e, 0x9dba, 0xc6c2, 0xfbf8, + 0x8bc7, 0x926b, 0x89d2, 0x9fcf, 0x9da9, 0x89d3, 0x99e2, 0x9267, + 0x92a4, 0x894e, 0x894f, 0x9278, 0x91b6, 0x89d4, 0x9fd2, 0x92a7, + 0x95a2, 0x926e, 0x96ea, 0x926f, 0x92a3, 0x8950, 0xfa57, 0x9866, + 0x89d6, 0x98b2, 0x92ab, 0x96de, 0x92ac, 0x9f6e, 0x8ef2, 0x9f6c, + 0x89d8, 0xfa59, 0x92a8, 0x9163, 0x9f73, 0x92ad, 0x9be9, 0x92a9, + 0x92aa, 0x89d9, 0xfd56, 0x9fa8, 0x92a1, 0x90e3, 0xa0a6, 0x94ab, + 0xfc72, 0x97c4, 0x92ae, 0xfa67, 0x92a2, 0xfa69, 0x9268, 0x8951, + 0xfa6f, 0xfa71, 0x8952, 0x945a, 0xc6c3, 0x89dd, 0xc8a2, 0xc6c4, + 0x9e52, 0x8953, 0x9e55, 0x92ba, 0xc6c5, 0xfa7d, 0xfaa8, 0x9a68, + 0xfa47, 0xfa7e, 0x92bb, 0xfdb6, 0xfaa2, 0xfaa3, 0xfaa4, 0x9bb4, + 0xfaa6, 0x89df, 0xfddb, 0xfaa9, 0x8954, 0xfaab, 0xfc7a, 0x89e0, + 0x9f4f, 0xc87d, 0x89e1, 0xfab0, 0x9fcd, 0xa0e7, 0xfab1, 0x89a6, + 0x9efa, 0xfab2, 0xfab4, 0x92c4, 0x9f6f, 0x8bb0, 0x9fac, 0x89e3, + 0x9bd3, 0x89e4, 0xfab5, 0x9fd5, 0x8955, 0x92c5, 0x8956, 0xfab3, + 0xfab6, 0xfab7, 0x9edc, 0xfbc4, 0x9f71, 0xfaba, 0x92c7, 0xc6c6, + 0x9a4c, 0x89e5, 0x9f7d, 0xa0a9, 0xfac4, 0xc6c7, 0x8957, 0xfaaa, + 0x8958, 0x8be3, 0x8b61, 0x9af1, 0x9eb7, 0xc6c8, 0xfad1, 0xfad2, + 0x9eba, 0xfad4, 0xfad9, 0xfadb, 0x9ce0, 0xfbf7, 0xfbfa, 0x89e7, + 0xa07a, 0xfadc, 0xfadd, 0x89e9, 0xc6c9, 0xfae2, 0x89eb, 0xfae3, + 0x90c8, 0x92da, 0x8959, 0x9cf5, 0x895a, 0xfae7, 0x9fa2, 0xfaea, + 0xfaed, 0x8fad, 0xfb59, 0xfaef, 0x96ef, 0x9dec, 0x9dca, 0xfd6d, + 0x89ec, 0xfb44, 0x9de2, 0x9ec0, 0x9e56, 0x9f79, 0x9ac7, 0xfaf4, + 0x98a1, 0xfaf8, 0x89f0, 0x9e47, 0x9df7, 0x9fd3, 0x9aca, 0x89f1, + 0xfaf9, 0x8e5a, 0x89f2, 0x89f3, 0x925d, 0x8b51, 0x92e0, 0x89f4, + 0x9fd4, 0x8a79, 0x89f5, 0x97a7, 0x93ba, 0x9e58, 0x89f6, 0x9e57, + 0x89f7, 0x8a41, 0x89f8, 0xfaf1, 0x89fa, 0xfb42, 0xfabf, 0xfba3, + 0xfaf7, 0x9e4e, 0x94dc, 0x95da, 0x9df8, 0x9f6a, 0x8ab7, 0xfb46, + 0x8a46, 0xfb47, 0x9148, 0x92de, 0x8b53, 0x9df6, 0x9bda, 0x9d7e, + 0x89fd, 0x99e4, 0x9e43, 0x9de9, 0x8f52, 0x9df5, 0x9df0, 0x99e7, + 0x8bbd, 0x9def, 0x9fb7, 0x9dd0, 0x9feb, 0x8da9, 0x9dcf, 0x98e1, + 0x9de5, 0x9dc8, 0xfb4f, 0x9deb, 0xfb54, 0xfb55, 0x9aa2, 0x8ad6, + 0x9a5f, 0x9ef5, 0x8fb7, 0x9ad2, 0x9e6a, 0x9ee8, 0x8bbf, 0x91c2, + 0x9d62, 0x9260, 0x925e, 0x91c1, 0x8ac5, 0x97a3, 0x8b6c, 0x8d7e, + 0x9c54, 0x9dbd, 0x9cc5, 0x895b, 0xfb5c, 0xfb5b, 0xfb57, 0x98c7, + 0xfb5a, 0x9cee, 0x92e2, 0x94a7, 0x9bd4, 0xfb64, 0xfb76, 0xfb60, + 0x99e5, 0x9ac2, 0x91fb, 0xa073, 0x9f72, 0x9fcc, 0x98a5, 0x92e8, + 0x9bbc, 0x96f3, 0x92e7, 0xfc67, 0x8b7d, 0x9bf4, 0x9ef7, 0x9ec1, + 0x996f, 0x96f1, 0x8e41, 0x954a, 0x97e6, 0x96f5, 0x92e6, 0x9f42, + 0xfb67, 0x99a9, 0xfae6, 0xfb69, 0x97e5, 0x967d, 0xfb6c, 0x99a2, + 0x9abb, 0x9a65, 0x944e, 0xfb6e, 0x99df, 0x98e3, 0x9254, 0x967b, + 0x8aaf, 0x8baf, 0x9ebd, 0x9ee6, 0xfb6f, 0x8ee1, 0x9b7d, 0x9c7e, + 0xf9d9, 0x92ea, 0xfb72, 0xfb71, 0x895c, 0x98f0, 0x96f2, 0xfb74, + 0x8bc1, 0x895d, 0x89de, 0x895e, 0xc6ca, 0xfe42, 0xfb7b, 0x895f, + 0x8960, 0x9bcd, 0x9dd3, 0x984c, 0x9752, 0x95c3, 0x9bb6, 0x9ab9, + 0x97b3, 0x9f74, 0x92f1, 0x97df, 0xfba6, 0xfbab, 0x9877, 0x9854, + 0x95c5, 0x9d55, 0xfbb2, 0x957e, 0x9742, 0x94e6, 0x92f5, 0x92fd, + 0xfba2, 0x9c51, 0x94e9, 0x985c, 0x92f0, 0x944c, 0x916b, 0x8b78, + 0x94e2, 0x984f, 0xfbb5, 0x9271, 0x9365, 0x985b, 0x9850, 0x97bc, + 0x92f3, 0x9340, 0x984d, 0x9572, 0xfdef, 0xfdc1, 0xfbba, 0x92eb, + 0xfc73, 0x97b7, 0xfbb4, 0x90a7, 0x9741, 0x92f4, 0xfbbc, 0x9577, + 0x9ee2, 0x8f78, 0xf9dc, 0x9672, 0x9eb5, 0x964b, 0xa0fa, 0x9575, + 0x90da, 0x9367, 0xfea4, 0x90df, 0x9354, 0x8961, 0x8bb4, 0x9dc0, + 0x8e48, 0xfbc5, 0xfbc7, 0xc6cb, 0xfa79, 0x9e67, 0xfbd2, 0x8962, + 0x8963, 0xfc7d, 0x9f6b, 0xfbcc, 0xfeae, 0xfbd1, 0xfb75, 0xfbd4, + 0xfbd6, 0xfbd8, 0x8b5d, 0x934c, 0x9ae2, 0x8bc9, 0xfbdb, 0x9fc9, + 0x9f44, 0x98ed, 0xfbdd, 0x8df2, 0x8964, 0xfdf2, 0x934d, 0xfbe7, + 0xa0f2, 0x9868, 0x9f58, 0x8d73, 0xfbde, 0xfbdf, 0xfbe3, 0x8da8, + 0xfbe4, 0x9c75, 0x9878, 0x8d60, 0xfbe5, 0x8d61, 0x8d62, 0xa0a1, + 0x9c40, 0x98ad, 0x9eea, 0x9ceb, 0xfbe0, 0x9f51, 0x8d65, 0x9cf1, + 0xfc58, 0x8d66, 0x9654, 0xfbe8, 0xc6cc, 0x9fce, 0xfbfc, 0x9ae4, + 0x9f75, 0xfbf1, 0x8d69, 0x934f, 0x934e, 0xfbf4, 0xc6ce, 0xfbc3, + 0x8965, 0x8d6a, 0x9353, 0x9dfb, 0xfbfd, 0x9059, 0xfc40, 0xfc41, + 0xfc43, 0x9361, 0xfc46, 0x9362, 0x8d6b, 0xfc4c, 0x95b8, 0xc6d0, + 0x8bca, 0x987a, 0xc6d1, 0xfc51, 0xfc54, 0xfaaf, 0x8d6c, 0xfa61, + 0xfc57, 0x9b70, 0xa051, 0x8bcb, 0x936e, 0xfcd5, 0xfca9, 0xfc61, + 0x8966, 0xfacb, 0xf9da, 0x937a, 0xa0e0, 0x936b, 0xfc6b, 0xa0dc, + 0x9468, 0xfc6d, 0x8d71, 0xfd64, 0x99ba, 0x9ad0, 0x9a61, 0xa0e5, + 0xa05b, 0x96ac, 0x9740, 0x9ef1, 0x9f7e, 0x8d72, 0xfc76, 0x96a9, + 0xa06e, 0xfcaa, 0xfbcd, 0xfc74, 0xa074, 0xa071, 0xfc79, 0xfc7c, + 0x9c50, 0x9379, 0x9378, 0xa0dd, 0x8d75, 0x8d76, 0x9374, 0x8d77, + 0xfca5, 0xfca2, 0x90c3, 0xa079, 0x8d79, 0x8bfc, 0xa076, 0x8bcd, + 0x9f5a, 0x9ff4, 0x9fba, 0x8d7a, 0x9e45, 0x93b0, 0xa075, 0x9b46, + 0xfcae, 0xfcb0, 0xfa51, 0x8d7b, 0x8d7c, 0x9ed6, 0x93ac, 0x9f5b, + 0x93a9, 0xa07c, 0xfcb2, 0x8ac1, 0x9fb4, 0xfcac, 0x9e4c, 0x8fc5, + 0x93ad, 0x9dc3, 0x8da2, 0x9d4a, 0xfcb6, 0x8da3, 0x9e4b, 0x9e4d, + 0x8da4, 0x8afd, 0xfcb5, 0xfcc3, 0x93b2, 0x8da5, 0x93a1, 0x8ac6, + 0x8a5b, 0x894d, 0xfed4, 0x8a78, 0x93ab, 0x8da7, 0x9f45, 0x8a56, + 0xfcbf, 0xfcc0, 0x8ee6, 0x8aa4, 0x8943, 0x93f3, 0xfcab, 0x9ea2, + 0x9dc7, 0xc6d2, 0x8bce, 0xfcc5, 0xfccb, 0x93b3, 0xfcca, 0xfcc9, + 0x8dac, 0xfbc6, 0x8967, 0xfccd, 0x9cf3, 0xfcd0, 0x95bb, 0xfcd3, + 0xfcd4, 0x8dae, 0xfcd7, 0x93db, 0xfe63, 0x93d5, 0xfcda, 0x9b71, + 0xfcdd, 0x8daf, 0xfaf2, 0x93d8, 0xfcdf, 0x93d3, 0xfce1, 0x8e76, + 0xfc62, 0x93d1, 0x8db1, 0x9859, 0xfb52, 0xfb53, 0xfb4d, 0x9cbf, + 0x9b72, 0xfb50, 0x93be, 0x9df1, 0xfceb, 0xa0bb, 0x9b7e, 0x8db3, + 0x9ae8, 0x8edc, 0x9cf9, 0xfa50, 0x98e7, 0xfcf3, 0xfcf2, 0x93e5, + 0x9a59, 0x8db5, 0xfd4d, 0xfd5e, 0x8f7d, 0x9547, 0xfcf6, 0x9250, + 0x8968, 0x8db6, 0xfcfb, 0xa07d, 0x98fc, 0x8969, 0xfe4f, 0x9256, + 0xfac9, 0x93e8, 0xfcf8, 0x9ce3, 0xfda9, 0xfc44, 0x9640, 0x8db8, + 0x9b4a, 0x8fb9, 0xfcfe, 0x896a, 0x8db9, 0x917e, 0x93f4, 0xfb7c, + 0x93e7, 0x97ef, 0xfe4a, 0xfd45, 0x96a5, 0xfee0, 0xfd48, 0xfd47, + 0xfef2, 0xfe6a, 0x8dbd, 0x9ba1, 0x9ab7, 0x8efc, 0x9fa1, 0xfd51, + 0xfaad, 0x8dbe, 0x89a4, 0x9ad9, 0xfd4e, 0x8dc0, 0x97f0, 0x93b4, + 0xfd44, 0x9fa7, 0x8dc2, 0x99b6, 0xfd52, 0x8dc1, 0x8e46, 0xa0d1, + 0x9fca, 0x92cf, 0x9cf4, 0x8dc4, 0xfd41, 0x9b4c, 0xfd57, 0xfcef, + 0x9cde, 0xfd42, 0x986c, 0x97f9, 0x9558, 0x985e, 0xfe7b, 0x94cd, + 0x93ee, 0xfd5a, 0x93f5, 0x93ef, 0x8eea, 0x8f5b, 0x8dc6, 0x8dc8, + 0x8dc7, 0x93f7, 0x8dc9, 0xfbf2, 0x9670, 0x8dcb, 0xfd5c, 0x8f65, + 0x8dcd, 0x9da8, 0x94f9, 0x8dce, 0x93ea, 0xfd5f, 0x93f0, 0x9fb6, + 0x8dcf, 0x9763, 0x8dd0, 0x93f1, 0xfd62, 0xfd65, 0x9fdb, 0x93f8, + 0x8bf7, 0xfd66, 0x8bcf, 0x8dd1, 0x8dd2, 0xfd71, 0xfd6f, 0x8dd3, + 0x9fe7, 0x90bd, 0x9fd0, 0x8bd0, 0xfd72, 0x9cae, 0x8bd1, 0x8adb, + 0xfae4, 0x95ce, 0xfd76, 0xfb62, 0x8dd4, 0xfd78, 0x8ee3, 0x9076, + 0x98c6, 0x8dd5, 0x97d1, 0x9eb6, 0xfac7, 0xa042, 0x9873, 0x9ffc, + 0x8dd7, 0x92fb, 0x8dd8, 0x944f, 0x8dd9, 0x896b, 0x97ce, 0xfaf3, + 0xfdae, 0xfbaf, 0x92b7, 0x8dda, 0x9c5a, 0xfdad, 0x8ddc, 0x9444, + 0x8ddd, 0xa0d6, 0x97d5, 0x944a, 0x944d, 0x97cb, 0x8dde, 0x8ddf, + 0x8de0, 0xfef9, 0xfdc0, 0xfcf9, 0xfb7e, 0x92b3, 0xfdaf, 0x8de1, + 0x95d3, 0x89c1, 0xfd68, 0x9cb7, 0x8de3, 0xfac0, 0x8de5, 0xfa64, + 0x8947, 0x8de4, 0x8de7, 0x8de8, 0xfdc7, 0xfdb0, 0x9445, 0x97d6, + 0xfcc6, 0x9844, 0x8de9, 0x8dea, 0xfe50, 0xfdcc, 0x9da7, 0xfdcd, + 0xfdcf, 0x95d2, 0x8ded, 0xfcba, 0xfdc5, 0xfdd2, 0x9cdc, 0x95cf, + 0x8dee, 0xfdd4, 0x96ec, 0x96eb, 0x90b6, 0xfdc3, 0x98ab, 0x96ee, + 0x8df4, 0xfde0, 0x8df6, 0x8df7, 0x8ffa, 0x97d0, 0x8bd2, 0x8df8, + 0x90d9, 0xfaf0, 0xfde1, 0x8df9, 0xfde3, 0x8dfa, 0xfb63, 0x90a6, + 0x9970, 0x91eb, 0x9770, 0x986f, 0xfde2, 0x98f2, 0x9afc, 0x896c, + 0xfdfd, 0x995e, 0x95bd, 0xfde4, 0x91e6, 0xfde5, 0xfde6, 0xfde7, + 0x9454, 0x99b8, 0x97e9, 0x9346, 0x9863, 0x95bc, 0xfded, 0xfdf7, + 0x9870, 0x96f6, 0x8ea9, 0x9451, 0x8e43, 0x8b5a, 0xfdee, 0xfdf0, + 0xfdf4, 0x9bf5, 0x977e, 0x9bd5, 0x9ac3, 0x97c8, 0xa0db, 0x91d0, + 0x9fe4, 0x8fdd, 0x91e9, 0x98e0, 0x92ca, 0x9857, 0xfdeb, 0x9b49, + 0x9d76, 0x9eaf, 0x9ccc, 0xfdea, 0x8df1, 0xfdfb, 0x8e53, 0xfacf, + 0x96f9, 0x98bf, 0x9e49, 0x9bca, 0xfdfe, 0x92dc, 0xfe41, 0x91cc, + 0x91e2, 0xfe44, 0x8bd3, 0xfe47, 0xfe48, 0x9455, 0xfe4b, 0xfe4c, + 0x8dbf, 0x9e78, 0xfe51, 0x9456, 0x9d61, 0x9457, 0x9966, 0x8bd5, + 0xa069, 0x98b4, 0xa049, 0xa04c, 0x9e65, 0x98b5, 0xfe58, 0x9975, + 0xfe53, 0xa065, 0xfe59, 0x98b7, 0x98b8, 0x98ba, 0x98bb, 0x9fbc, + 0xa04a, 0x9ec7, 0x98ae, 0x92d6, 0xfae1, 0x91d4, 0xfade, 0xfe5b, + 0xfe5e, 0xfbd7, 0xfe5a, 0x94c5, 0xfaca, 0x98c1, 0x975c, 0xfe74, + 0x9773, 0xfa46, 0x9764, 0xfe68, 0x964e, 0x9765, 0x89a1, 0x95fa, + 0x92d4, 0xfe69, 0xfb45, 0x98c8, 0x90ef, 0x98c9, 0x98ca, 0x946d, + 0x94b7, 0xfe6c, 0x946b, 0x92fc, 0x95eb, 0xfe73, 0x976e, 0xfe5f, + 0xfdbd, 0x92d5, 0xfeb9, 0xfe71, 0xfbbb, 0x947a, 0x95fb, 0xfe77, + 0xfe79, 0xfe75, 0x945d, 0xfe7c, 0x9344, 0x8ea6, 0x92d3, 0x94b8, + 0xfc71, 0x975e, 0xfea7, 0x946a, 0x93e3, 0x98cf, 0xa0d9, 0xa0bf, + 0xa04d, 0xa0b8, 0xa0ce, 0xa0b7, 0xfea9, 0x89c3, 0xfeab, 0x9df4, + 0x896d, 0x9c7b, 0x98d2, 0x9fa9, 0xfeb2, 0xfeb1, 0x97d9, 0xa0c4, + 0x9476, 0x9978, 0xfeb3, 0x98d3, 0xfeb4, 0x98d4, 0x9fb9, 0x9471, + 0x98d5, 0xfeb8, 0xc6d4, 0xfeba, 0x9e5c, 0xfebb, 0xa044, 0x98d7, + 0x98d8, 0xfebc, 0x9ffe, 0xfebd, 0x9ddd, 0x9ee1, 0x98da, 0x9ddf, + 0xfebf, 0xfebe, 0x9eeb, 0x9e59, 0xa05c, 0xfec0, 0x9477, 0x98dc, + 0xfec1, 0x98de, 0xfec3, 0xfec8, 0xfec9, 0xfeca, 0xfecb, 0x9fc2, + 0x98c4, 0x94b0, 0x94b1, 0xfed1, 0xa0c1, 0xfed2, 0xa0cd, 0xfed3, + 0x98e5, 0xfed6, 0x91e4, 0x8fc7, 0x94ae, 0x8a4f, 0x94b2, 0x8fd4, + 0x98ea, 0xfed8, 0x9de0, 0x98ee, 0x95c4, 0xfce8, 0x98ef, 0xfad8, + 0xfedc, 0xa0ae, 0x9d4c, 0x98f1, 0x98f3, 0x94c1, 0x98f5, 0xfa4f, + 0x96e2, 0x9450, 0x96a2, 0x98f6, 0x96e5, 0x98f7, 0xa046, 0x96e3, + 0x98f8, 0x9ee4, 0xf9d6, 0x94c3, 0x94c2, 0xfee1, 0xfee9, 0x96e4, + 0x89ac, 0x96db, 0xfee2, 0x94c4, 0xfee3, 0xfee7, 0x9ffb, 0x93c9, + 0x94e8, 0xfb56, 0x90c5, 0xa0a8, 0xfee5, 0x98fd, 0x98fb, 0xfee8, + 0x8ebf, 0x8bd8, 0xfef7, 0x8f68, 0x94c6, 0x9dea, 0xfc69, 0x9cda, + 0xfef3, 0x9c72, 0xfef0, 0x89c9, 0x9941, 0x9942, 0xfef5, 0x91d7, + 0x94cc, 0xfef8, 0x97a8, 0xfefc, 0xfdbf, 0xfefe, 0x96d1, 0x94d5, + 0x94d0, 0x9944, 0xa0b3, 0x94cf, 0x9ffa, 0x91e5, 0x9c6a, 0x8e49, + 0x8e4c, 0x8e4d, 0x9a73, 0x9947, 0x8e50, 0x8e4f, 0x9949, 0x8e51, + 0x8e52, 0x9ab2, 0x89a5, 0x994c, 0x9ff8, 0x8e56, 0x994d, 0x91ca, + 0x8e57, 0x94e1, 0x9047, 0x8fd8, 0x8e58, 0x94eb, 0x8e5c, 0x9553, + 0x9fe5, 0x9f56, 0x954f, 0x8e5e, 0x996a, 0x9c64, 0x9cd9, 0x8e5d, + 0x9950, 0x9951, 0x8e62, 0x9952, 0x8e68, 0x8e61, 0x9f59, 0x8bb3, + 0x9f5d, 0x8e66, 0x8e6e, 0x9f64, 0x9953, 0xfab8, 0x9954, 0x8e70, + 0x9f61, 0x8e72, 0xa06b, 0x9f40, 0x94ed, 0x94ee, 0x9fbd, 0x8e7b, + 0x9957, 0x94f7, 0x9f5f, 0x8e73, 0x9f62, 0x94f6, 0x9958, 0x8e75, + 0xf9db, 0x9072, 0x94f8, 0x995a, 0xa0b0, 0x8e79, 0x8e78, 0x94f3, + 0x98af, 0xa0b2, 0x8e7a, 0x995c, 0x8e7c, 0x8e7d, 0x8bd9, 0x89a2, + 0x9ed7, 0xa0b6, 0x9e42, 0x8ea4, 0x8ea7, 0x9542, 0x987d, 0x9755, + 0x8ea8, 0x8eaa, 0x89a3, 0x9960, 0x9962, 0x94fc, 0x9961, 0x94fa, + 0x8eae, 0x8eb2, 0x8eb0, 0x9963, 0x97aa, 0x94fb, 0x8ebb, 0x9876, + 0x8ea1, 0x8eb7, 0x9da6, 0x9eb0, 0x8eb8, 0x9d70, 0x896e, 0x896f, + 0x8970, 0x8971, 0x8972, 0x8973, 0x8974, 0x8975, 0x8ebc, 0x8ebd, + 0x8ebe, 0x9dd1, 0x94fd, 0x8bd7, 0x8bda, 0xa0e2, 0x9fe9, 0xfda8, + 0x8ae7, 0x8ec2, 0x8ec4, 0x9964, 0x9965, 0x954e, 0x98b3, 0x8ecb, + 0x8bdf, 0x8ece, 0x8ecf, 0x9968, 0x9969, 0x996b, 0x8ed1, 0x996c, + 0x8ed4, 0x8ed5, 0x996d, 0xa0be, 0x8ed6, 0xa0bc, 0xa0b5, 0xa0b4, + 0x8be0, 0x89b5, 0x8edd, 0x9e5d, 0x9971, 0x89ae, 0x9de8, 0x9565, + 0x9972, 0x8b5c, 0x89b1, 0xa0c0, 0x8edf, 0x9566, 0x9974, 0x9976, + 0x9977, 0x9979, 0x9dda, 0x8ee0, 0x935c, 0x9de6, 0x8b5f, 0x9563, + 0x9567, 0x9de3, 0x997c, 0x997d, 0x997e, 0x8b5b, 0x99a3, 0x99a4, + 0x99a6, 0x99a8, 0x8abe, 0x9e61, 0x99aa, 0xa0c8, 0x99ab, 0xfec4, + 0x98c2, 0x8ee8, 0xa0ba, 0xfd77, 0x8eee, 0x9ebf, 0x89c2, 0x99ac, + 0x956b, 0x956c, 0x99af, 0x994a, 0x8976, 0x8f48, 0xfbee, 0x99ae, + 0x8efb, 0x8b52, 0x99b0, 0x8977, 0x8f41, 0x99b1, 0x8f49, 0xfa4d, + 0x9de4, 0xfbe9, 0x9b54, 0x99b2, 0x9e68, 0x8f4a, 0x8f42, 0x8f51, + 0x9846, 0x99b4, 0x8ef5, 0xfd55, 0x9ccd, 0x8978, 0x8f53, 0x8f6f, + 0x8e63, 0x8f56, 0xfe76, 0x9fc6, 0xfaac, 0x8f58, 0x9848, 0x99b7, + 0x9665, 0xfa6c, 0x9de7, 0x9e62, 0x96cc, 0x8e67, 0xfc75, 0x987e, + 0xfdb9, 0x97fc, 0x98f9, 0x8f66, 0x956e, 0x9245, 0x8f60, 0x9ed1, + 0xfecd, 0x99b9, 0x8f62, 0x974c, 0x91c7, 0x955f, 0x99bb, 0x8e6d, + 0x8f71, 0x94cb, 0x95b1, 0x9af2, 0x96c3, 0x99bd, 0xa0cf, 0x8f6d, + 0x99be, 0x8ef4, 0x8f72, 0x95e4, 0x99bf, 0x9242, 0xfba5, 0x99c0, + 0xfdb4, 0x8f77, 0x99c1, 0xfab9, 0x8f40, 0xfa44, 0x99c2, 0x8f5c, + 0x99c4, 0x99c5, 0x8f7b, 0x8fa3, 0x99c6, 0x96cd, 0x96c7, 0x8fa5, + 0xfabb, 0x9570, 0x9368, 0x8f7e, 0x8faa, 0xa050, 0x90d3, 0x9556, + 0x8fb8, 0x99c8, 0x8faf, 0x99c9, 0x9579, 0x9f49, 0x99ca, 0x99cb, + 0x9dd5, 0x8fb0, 0xfa7a, 0x9e5f, 0x99cd, 0xa0c9, 0x9adb, 0xa0c6, + 0x8fb4, 0xa0d7, 0xa0c7, 0xa043, 0x8fb5, 0x8fb2, 0xa061, 0x9e5e, + 0x8fb6, 0x9fe8, 0x9cb2, 0x957c, 0x9fc7, 0x8fbb, 0x8fbc, 0x8fec, + 0x8fc0, 0x936a, 0x8be4, 0x9c7c, 0x95a1, 0xfeec, 0x95a3, 0x8fc1, + 0xa052, 0x99d0, 0x8fc3, 0x8fc4, 0x95a4, 0x8fc6, 0x9e60, 0xf9d8, + 0x95a5, 0x9cb3, 0x99d1, 0xfef1, 0x99d2, 0x9cc2, 0x99d3, 0x95a7, + 0x95a9, 0x95a6, 0x9c5d, 0x98e2, 0x8fc9, 0xa0c2, 0x8fca, 0x99d4, + 0xa0b9, 0x9b58, 0x8fcd, 0xa0d4, 0x8fce, 0x8be5, 0x8979, 0x8fd0, + 0x95b6, 0x99d6, 0x95e5, 0x99d7, 0x95b5, 0xa0ca, 0x9ffd, 0xa058, + 0x8fd6, 0x99d8, 0x8fd3, 0x8fe5, 0x8fe9, 0x99d9, 0x927c, 0x9c45, + 0x8fde, 0x8fdf, 0xa04b, 0x8fe2, 0xa0cc, 0x8fe3, 0x8fe4, 0x9bc4, + 0x9bfc, 0x964c, 0x9af6, 0x8fe7, 0x8fe8, 0x8be7, 0x897a, 0x897b, + 0x99da, 0x8fed, 0x95c0, 0xa0cb, 0x9e48, 0x99db, 0x8ff3, 0x8ff9, + 0x95c1, 0xa04e, 0x99dc, 0xa064, 0x8ff7, 0x89b0, 0xa048, 0x8ffb, + 0x8ff6, 0x9ddc, 0x99dd, 0x8be8, 0x92c1, 0x9fd6, 0xa0d2, 0x9040, + 0x8ac4, 0x99e0, 0x9ff0, 0x9ff3, 0x9dbf, 0x9ff6, 0x95c8, 0x9e5a, + 0x99e3, 0x8a4a, 0x9ff1, 0x8aa7, 0x99e6, 0x9ff7, 0x9fed, 0x8a5c, + 0x9dae, 0x95c9, 0x9048, 0x99e8, 0x9049, 0x90b1, 0x904a, 0x99ea, + 0x9bd1, 0x99eb, 0x99ec, 0x99ed, 0x99ee, 0x904c, 0x904d, 0x95cb, + 0x97e2, 0x95cc, 0x9f78, 0x897c, 0x897d, 0x897e, 0x995d, 0x9b5a, + 0x9050, 0x9054, 0xc6d6, 0x9aa8, 0x99ef, 0xfeeb, 0x9da3, 0x9da1, + 0x9943, 0x9945, 0x9d7d, 0x99f0, 0x99f1, 0x99f2, 0x9d60, 0xa0a3, + 0x905b, 0x9edb, 0x9d79, 0x99f3, 0x9062, 0x9f55, 0x9bf9, 0x9065, + 0x96e0, 0x98be, 0x9068, 0x906c, 0x95d8, 0x906a, 0x9fb2, 0x9fae, + 0x9fb0, 0x89ad, 0x906e, 0x9e71, 0x9e4a, 0x9fdc, 0x89ab, 0x9fb8, + 0x9070, 0x8b63, 0x95dc, 0x9071, 0xfc5e, 0x8949, 0x965b, 0x94a6, + 0x8fd5, 0x9e73, 0x9075, 0x99f7, 0x99f9, 0x9663, 0x95b9, 0x94d4, + 0xfcfa, 0x9077, 0x90ab, 0x9d4d, 0x99fa, 0x92e3, 0x97bb, 0x9078, + 0x99fb, 0x97e0, 0x96dc, 0x9ca8, 0x9772, 0x9440, 0x92f2, 0x99fd, + 0x99fc, 0xf9d7, 0x964a, 0x96d8, 0x99fe, 0x904b, 0xfa41, 0x9a40, + 0x975b, 0x9a41, 0x91dd, 0x93fc, 0x9a42, 0x9a43, 0x9659, 0x9a44, + 0x9051, 0x94bf, 0x90a2, 0x9cab, 0x9776, 0xfc55, 0xfe45, 0x94a8, + 0x9a45, 0xfa4b, 0x9de1, 0x96d9, 0x9774, 0xfdf5, 0x92e5, 0x9645, + 0x91da, 0x90a3, 0xa05f, 0x90af, 0x97bf, 0x914c, 0x967a, 0x91de, + 0x9a46, 0xfeb0, 0x9779, 0x946c, 0x9858, 0x9266, 0x93fb, 0x9a47, + 0x9749, 0x9748, 0x934a, 0x9ce2, 0x9264, 0x91df, 0xfb79, 0x96d7, + 0x9343, 0xfdcb, 0xfe7a, 0x91db, 0x97af, 0x95dd, 0x9348, 0x9a4b, + 0xfc45, 0x9a4d, 0x91bc, 0x90e2, 0x90b4, 0x95e1, 0x9a4e, 0x9a4f, + 0xfe40, 0xfe43, 0x96dd, 0x9a51, 0x96a7, 0x90b0, 0x9c4e, 0x9443, + 0x8eba, 0x9a52, 0xfcc1, 0x8be9, 0x9caf, 0x8bfd, 0x9abc, 0x9ab8, + 0x9aae, 0x9aa7, 0x9a53, 0x9d74, 0x8bea, 0x8beb, 0x90b2, 0x95e9, + 0x95e8, 0x95e6, 0x90b5, 0x9a54, 0x90b3, 0x95e7, 0x8b50, 0x8bec, + 0x9a56, 0x8bfb, 0x9a57, 0xa0aa, 0x9fa6, 0x99cc, 0x9c59, 0x99b5, + 0x90be, 0x9faf, 0x95f2, 0x90bf, 0x90c1, 0xfee4, 0x90c4, 0x90c7, + 0x92e4, 0x9f52, 0x90db, 0xa066, 0x90d2, 0x90d4, 0x9a5b, 0x95fd, + 0x8bc4, 0x90de, 0x9ce4, 0x90e1, 0x9e46, 0x9651, 0xfb58, 0x90e6, + 0x9650, 0x90e7, 0x90e8, 0x9a5d, 0x9f7a, 0x9b5c, 0x9f7c, 0xfc52, + 0x90e9, 0x90ea, 0x9a5e, 0x9f76, 0x90eb, 0x90ec, 0x8bee, 0x90ee, + 0x91c6, 0x90f2, 0xfcbc, 0x8a74, 0x9657, 0x9cef, 0x9fdf, 0x90f7, + 0x90f6, 0x9b5e, 0x90f8, 0x90f9, 0xfa6a, 0x8bef, 0x9fe0, 0x9142, + 0x9a62, 0x9569, 0x9144, 0x9143, 0x9141, 0x8bf0, 0x9660, 0x8bf1, + 0x99f6, 0x9149, 0x914a, 0x914b, 0x9a64, 0x8abf, 0x9a66, 0x9a67, + 0x9a69, 0x9a6a, 0x9652, 0x914d, 0x9666, 0x9f7b, 0x9a6b, 0xa06c, + 0x9667, 0x9a6c, 0x9a6d, 0x8bf2, 0x966a, 0xfcea, 0x966c, 0x91c4, + 0x9677, 0x99f4, 0x9a6f, 0x9fab, 0x8ec1, 0x9555, 0x9152, 0x9153, + 0x9155, 0x955d, 0x9671, 0x9c6d, 0x9673, 0x9154, 0x9a71, 0x9156, + 0x966d, 0x9557, 0x89c6, 0x89c7, 0x8a6a, 0x8b57, 0x9fe1, 0x9b5f, + 0xa05d, 0x915b, 0x915c, 0x915e, 0x9f5c, 0x9f57, 0x9f65, 0x9a72, + 0x9160, 0x9f5e, 0x9161, 0x9164, 0x9f41, 0x9169, 0x9168, 0x9a74, + 0x96b2, 0x9a75, 0xfda5, 0x9ee9, 0x8bba, 0x916d, 0xa060, 0x9fde, + 0x9fc3, 0x96b5, 0xa067, 0x96b3, 0x9a76, 0x95d5, 0x9eca, 0x9a77, + 0x9a78, 0x9170, 0x916f, 0x9fa3, 0x9171, 0x96b1, 0x9f63, 0x9f67, + 0x8bb9, 0x9a7a, 0x8b56, 0x9ada, 0x96b0, 0x9a7e, 0x9dde, 0x96ad, + 0x96ae, 0x9ea1, 0x9e50, 0x96af, 0x8bf4, 0x9fa4, 0x96bd, 0x96f4, + 0x96b8, 0xfaa1, 0x91a7, 0xa05e, 0x9a7d, 0x8948, 0x9eb1, 0x9ddb, + 0x95bf, 0x8a73, 0x9efe, 0x917a, 0x917b, 0x9aa3, 0x96c2, 0x9f77, + 0x9aa4, 0x9aa5, 0x91a1, 0x89b8, 0x9173, 0x9aa6, 0x89bd, 0x89b9, + 0x917d, 0x96bb, 0x9ff2, 0x8bf5, 0x9aa9, 0x9f54, 0x9fe3, 0x9eed, + 0x91aa, 0x91ab, 0xa070, 0x9f6d, 0x91ac, 0x91ad, 0xa0fd, 0x9fe2, + 0x91af, 0x9e41, 0x9aaa, 0x91b0, 0x9aab, 0x9aac, 0x9a4a, 0x91b2, + 0x8bf6, 0x9aad, 0x89b6, 0x9aaf, 0x9ab0, 0x9ab1, 0x9aa1, 0x91b9, + 0x91ba, 0x91be, 0xa041, 0x8bb7, 0x91c0, 0x9ab3, 0x91c3, 0xa0fc, + 0x9fee, 0x9f69, 0x91c8, 0x91c9, 0x8de6, 0x91cb, 0x89c8, 0x8daa, + 0x9fdd, 0xc8a1, 0xc8a3, 0x8bf8, 0xc8d0, 0xc8cf, 0xc6e4, 0xc6e5, + 0xc8cd, 0xc8ce, 0xf9fe, 0x9c71, 0x9375, 0x9376, 0x9548, 0x8ec6, + 0x8bc5, 0x8bfa, 0xc87c, 0x9ab4, 0x884e, 0x884b, 0xc87a, 0x8848, + 0x8847, 0xa0f6, 0x8845, 0x8853, 0xfcad, 0x8aad, 0x9272, 0xfc47, + 0x94df, 0x9fd1, 0xfbcb, 0x927d, 0x98a4, 0x94e7, 0x90cb, 0x927b, + 0x94d8, 0xfc5f, 0xfa54, 0x9ab5, 0x96da, 0x9279, 0xfa74, 0x9275, + 0x8dfb, 0x8a49, 0x92df, 0x9b7c, 0xfa63, 0xfa60, 0x926d, 0xfa62, + 0x9ab6, 0x976b, 0xfd6a, 0xfd54, 0x9273, 0x97d8, 0x9fbb, 0x9342, + 0x9276, 0xfa65, 0x926c, 0xfa6e, 0x9ee0, 0x92c0, 0x92bf, 0x92be, + 0x9aba, 0x8ab3, 0x9775, 0xfa40, 0xfa76, 0xfbd0, 0xfa7b, 0xfe6d, + 0x9bb3, 0x89cc, 0x9abe, 0xfa42, 0x92bc, 0x945c, 0x9bb5, 0x9abf, + 0x98a7, 0x97a4, 0x90fd, 0xfc7b, 0x9ac0, 0x92c3, 0x8aaa, 0x9bd0, + 0x9550, 0x92c6, 0x98a6, 0x9546, 0xfd63, 0xfac2, 0x9ec3, 0x89b2, + 0x9c66, 0x9053, 0x97c1, 0x9ac4, 0x9ac5, 0x8eef, 0xfae9, 0x9262, + 0x8af7, 0x9ac6, 0x92e1, 0x9ac9, 0xfac6, 0x97a5, 0x9acb, 0xfa72, + 0x8a5e, 0x94e0, 0x92cc, 0x8ae5, 0xfe5c, 0x9acc, 0x9df9, 0x8a43, + 0x8aa6, 0x9acd, 0x9ace, 0xfaee, 0x9bcc, 0x9acf, 0x9ad1, 0x9dfa, + 0x9d7c, 0x9ad3, 0x97a6, 0x995f, 0xfbf6, 0x9fc5, 0x8a59, 0x8b6b, + 0x9ad4, 0x9ad5, 0x97a2, 0x8a44, 0x9f4a, 0x90a1, 0xfda4, 0x8a64, + 0x8af2, 0x8af8, 0x9dd8, 0x94d6, 0xfafe, 0xfba7, 0x9ad6, 0x9f4d, + 0xfaf6, 0x8a57, 0x8b43, 0x8b44, 0x8ab6, 0x8ac0, 0x9e54, 0x9ad7, + 0x9ad8, 0x9adc, 0x8aca, 0x9ea8, 0x9263, 0x9add, 0x8b65, 0x8b6f, + 0x8b7e, 0x8f43, 0x92d0, 0x8af4, 0x9dbe, 0x9ae1, 0xfcde, 0x9dfd, + 0x8b66, 0x8b70, 0x8b75, 0x8ae4, 0x8ba4, 0x8aed, 0x8a5d, 0x8b48, + 0x9ded, 0x9e40, 0x8aef, 0x8af6, 0x9e76, 0x9ee3, 0x9ade, 0x8dfe, + 0xfafc, 0x9cb1, 0x9e77, 0x8b64, 0x8b67, 0x974b, 0x9653, 0x9ae0, + 0x8b4a, 0x8af1, 0x8ad7, 0xa0ab, 0x8ab5, 0x8a5f, 0x8aee, 0x9adf, + 0x8afe, 0x8a58, 0x8ba3, 0x8ba7, 0x9ae3, 0x9261, 0x9dd7, 0x9e7d, + 0x9ea7, 0x9eab, 0x9042, 0x8b79, 0x8b7a, 0x9ae6, 0x9ae5, 0x8a7e, + 0x9e44, 0x9ae7, 0x8a7c, 0x8b71, 0x9ae9, 0x9aea, 0x9aeb, 0x8abd, + 0xfb4e, 0x9aed, 0x8af9, 0x9e63, 0x8b49, 0x8ace, 0x8b6e, 0x8ae8, + 0x9aee, 0x92ce, 0x8a5a, 0x8b7b, 0x8b7c, 0x9aef, 0x9af0, 0x8afa, + 0x8941, 0x8b72, 0x8af3, 0x8ba8, 0x9eae, 0x9e72, 0xfb73, 0xfb5f, + 0x90ba, 0x91fe, 0x9ef6, 0x97ed, 0x9af3, 0xa0ee, 0x967c, 0x9345, + 0x986e, 0xfa56, 0x9af5, 0xfc4b, 0x9af4, 0xfede, 0xfcb7, 0x97f1, + 0x97c7, 0x9ccb, 0x9240, 0x9ce8, 0x91fd, 0x974e, 0xfb68, 0x976c, + 0x97e8, 0xfb6a, 0x8b74, 0x8ee7, 0xfdc8, 0x9241, 0x96a1, 0x8ef3, + 0x9af7, 0x8fa6, 0xfad6, 0x9cc7, 0xfad7, 0x9af8, 0xfba1, 0x8ec5, + 0xfba4, 0xfbc2, 0x9ac1, 0x91fa, 0xfedb, 0x97ab, 0x9147, 0xfbb1, + 0x8fea, 0x94d2, 0xfe61, 0xface, 0x92ed, 0x91f3, 0x93c6, 0x935a, + 0xfafb, 0x92ef, 0xfac8, 0x9847, 0x9366, 0x9855, 0x96e6, 0x9f43, + 0x9faa, 0x94da, 0x92ee, 0xfcaf, 0xfbfb, 0x8ef9, 0x91f6, 0x9364, + 0x94f5, 0x9cb6, 0xfbad, 0x984e, 0x8f44, 0x96fd, 0x9af9, 0x9afa, + 0x9769, 0x95d4, 0x984b, 0xfbaa, 0x987c, 0x91ea, 0x9daf, 0x9dc5, + 0x91f1, 0x8eb1, 0x97a9, 0xfbac, 0xfcb8, 0x9cb9, 0xfbb0, 0xfcd2, + 0x93cb, 0x9afd, 0x91f4, 0x8bac, 0xa055, 0x9574, 0x95be, 0x97ad, + 0x8ee9, 0x92f8, 0x97be, 0x916c, 0x94aa, 0xfc63, 0x9dc6, 0x97b5, + 0x92b8, 0x91ef, 0xfea6, 0x9760, 0x9358, 0x9576, 0x8fac, 0x91ec, + 0x97b4, 0x91f7, 0x974a, 0xfb49, 0x9578, 0x93bc, 0x91d6, 0x9355, + 0x9356, 0x9851, 0x8ff8, 0xfbc0, 0x93f2, 0x90d0, 0x9c44, 0x9255, + 0x9363, 0x91a5, 0xa0ed, 0xfd6b, 0x9afe, 0x9351, 0xfa78, 0xfea8, + 0x9350, 0xfa4c, 0x92f7, 0x9b40, 0xfbce, 0x9b41, 0xfead, 0xfbd5, + 0x8bc2, 0x9a7c, 0x9b42, 0x9b43, 0x9e79, 0xfbd9, 0x9b44, 0xa0a7, + 0x9bf3, 0x935e, 0x89cb, 0x9f53, 0x93d7, 0xfbe1, 0xfed0, 0xfbe2, + 0xfce3, 0x9074, 0xfbe6, 0x9bb7, 0x9b45, 0x9b47, 0x9f50, 0x9b48, + 0xfc5b, 0x98a9, 0x9cfd, 0x884c, 0x9b4b, 0xfbec, 0x9ba8, 0x8ad5, + 0xfa73, 0xfd59, 0x91a2, 0xfbed, 0x9ca9, 0x8aa8, 0x9bc3, 0x8ae1, + 0x9b4e, 0x95d0, 0x905f, 0x97ee, 0xfc4e, 0x9b4f, 0x9b50, 0x9ec6, + 0xfc50, 0xfd73, 0xfda7, 0x9da2, 0xfa58, 0xfa5e, 0xa059, 0xfa75, + 0xfbbe, 0x9ca2, 0x9370, 0x9371, 0x9377, 0xfeef, 0x936d, 0xfc5d, + 0x90b8, 0x8afc, 0xfb41, 0x9e6b, 0x94e3, 0x8ee2, 0x8ed7, 0x9c4d, + 0x96a3, 0x9b51, 0x8ac3, 0x96aa, 0xfc68, 0x8b6d, 0xfd67, 0x8ae9, + 0xfca1, 0x936c, 0x9b52, 0xfe70, 0xfca8, 0xfce9, 0x9cb4, 0x8aea, + 0x9b53, 0x9b55, 0x96ab, 0xfca7, 0x9b56, 0x8abc, 0x8acb, 0x9b57, + 0x89cd, 0x9b59, 0x9b5b, 0x93a5, 0x9b5d, 0x9e4f, 0x93a3, 0x8a7b, + 0x8b42, 0x9750, 0x8fb3, 0x8a50, 0x9b60, 0x8b45, 0x8b46, 0x9dfe, + 0x9b62, 0x937b, 0x93b1, 0x8a60, 0x8ad8, 0x9b63, 0x8a69, 0x8a47, + 0x8acc, 0x937c, 0x9b65, 0x9b66, 0x8a72, 0x8a7a, 0x93af, 0x8ab0, + 0x9b68, 0x9ea3, 0xfaec, 0x8b77, 0x9b67, 0x8b59, 0xfcb1, 0xfcbb, + 0x9b69, 0x93a8, 0x8ae0, 0x9e51, 0x8f5f, 0x9b6a, 0x9b6b, 0x97ec, + 0x9b6c, 0xfe4e, 0xfdc2, 0x9b6d, 0x9167, 0xfccc, 0x93b6, 0x90e4, + 0x90e5, 0x9ef2, 0x93ca, 0x8bbc, 0x8f46, 0x93cf, 0xfcdb, 0xfcdc, + 0x93c0, 0xfce6, 0x96e7, 0xfcd8, 0xfcd9, 0xfda6, 0x93ce, 0x95f1, + 0x9ce9, 0xfce4, 0x94af, 0xfa77, 0x93cc, 0x905a, 0x93bf, 0xfb51, + 0x93b9, 0xfed7, 0x93b7, 0x93d9, 0x93bb, 0x93da, 0x98a3, 0x90d1, + 0x9b6e, 0xfa70, 0x9beb, 0x9b6f, 0xfcfc, 0x8b40, 0xa07b, 0x97f7, + 0x93e2, 0xfcd6, 0x9559, 0x93a6, 0xfd40, 0x935f, 0x97f2, 0x9c76, + 0x8ef8, 0x8f47, 0x9b74, 0x92b4, 0x91ed, 0x96d2, 0xfd46, 0x8f4f, + 0x9549, 0x9b75, 0xfa5c, 0x9b79, 0xfd4b, 0x96d3, 0xfd58, 0x945f, + 0xa0f5, 0x9243, 0x97fa, 0x9dd9, 0x97f4, 0x924d, 0xfd5b, 0x9b7a, + 0x9ed5, 0xfaae, 0x9cc9, 0x9258, 0x8ec8, 0x94b4, 0x93e1, 0x93df, + 0xfcf0, 0x93ec, 0x97f6, 0x96cf, 0x93de, 0x8acf, 0x9ba2, 0xfd69, + 0x9352, 0x98a2, 0xfd6e, 0xfa7c, 0x93fa, 0x907c, 0x8f67, 0x9db7, + 0xa0e9, 0xfa4e, 0xfda1, 0x9e74, 0x9fbf, 0x9ecb, 0x9bb9, 0x9dd4, + 0x97b9, 0x8ef1, 0x957b, 0x9ed2, 0x9753, 0x96a4, 0x8fbe, 0x94d9, + 0x9058, 0xfd79, 0xfd7b, 0x8eda, 0x8efa, 0x9ba5, 0x9ed9, 0x97d4, + 0x90bb, 0xfdbc, 0xfdc6, 0x9248, 0x92b5, 0x9dc1, 0x92b9, 0x92a6, + 0x8f4b, 0x9ba6, 0x92b6, 0x8e40, 0x9ed8, 0x945e, 0x985f, 0x94ce, + 0x924a, 0xfd70, 0x9467, 0x8dec, 0x9bd8, 0x9448, 0xfac1, 0x9cf7, + 0xfdbe, 0x8fda, 0xfdd9, 0xfc7e, 0x93f9, 0xfa43, 0xfaeb, 0xfac3, + 0x97d3, 0x95f9, 0x9c48, 0xfdd8, 0xa0d8, 0xfdd7, 0xfb4a, 0x9baf, + 0x944b, 0xfdc9, 0x8eac, 0xfdb2, 0x925a, 0xfcbd, 0x92d9, 0xfdd5, + 0x92dd, 0x9259, 0x96ba, 0x925b, 0x9bab, 0xfdda, 0xfdde, 0xfdd3, + 0xfdd6, 0xfddc, 0xfddd, 0x90fe, 0xfea1, 0x8bad, 0x9cd8, 0x9e6d, + 0xfd7c, 0xfb61, 0x96f8, 0x96f0, 0xfcf4, 0xfe60, 0x9852, 0x964f, + 0x916e, 0x986d, 0x9864, 0x9453, 0xfdec, 0xfb78, 0x95ba, 0x985d, + 0x92f9, 0x985a, 0xfdf6, 0x93d0, 0x9862, 0x9bad, 0x974f, 0x9bae, + 0x9452, 0x9bb0, 0x91d2, 0x97ea, 0xfb6b, 0x91b1, 0xfdf3, 0x92cb, + 0x9bb1, 0xfcec, 0x986b, 0x9751, 0x9871, 0x95ef, 0x9ef3, 0x91e8, + 0x9bba, 0xfb4c, 0x926a, 0xfdf8, 0x9861, 0x91e7, 0x93ed, 0x9744, + 0x91e1, 0xfbf5, 0x9869, 0x8a62, 0x9bbb, 0x9c55, 0x8e77, 0x8ab2, + 0x9ebc, 0x93e6, 0x93a2, 0x9bbd, 0x94b3, 0x937d, 0x9e66, 0x9459, + 0x9bbf, 0x9458, 0x9ea5, 0x9bc7, 0xfe54, 0x8e74, 0x8bd6, 0x94b6, + 0xfd74, 0x98c0, 0x94a5, 0x9bc8, 0x95ed, 0xfd7e, 0xfbeb, 0xfd7d, + 0x976f, 0x9461, 0x9fc1, 0x95d7, 0xfa52, 0x9c58, 0x9f68, 0x9be7, + 0xfcce, 0x96e8, 0xfa49, 0x97a1, 0x954d, 0x9ef8, 0xfe49, 0x91ce, + 0x9771, 0xfdb1, 0xfc6e, 0x9cf2, 0x93b8, 0x9043, 0x9759, 0x94d7, + 0xfe66, 0x947d, 0xfc6f, 0x9246, 0xfa6d, 0x8ef7, 0xfbb7, 0x947c, + 0x92cd, 0x97b2, 0xfe65, 0x967e, 0x9758, 0x9b77, 0x91cf, 0x94a4, + 0x9cad, 0x8bab, 0x96d5, 0xfcb3, 0x93ae, 0x976d, 0x9446, 0x95f7, + 0x9c46, 0x955b, 0x91d1, 0x94f4, 0xfe67, 0x92a5, 0xfedf, 0x9bc9, + 0xfced, 0xfdfa, 0xfcc8, 0xfe62, 0x91fc, 0xfe6b, 0xfdf9, 0xfcc7, + 0x914e, 0x9cb8, 0x9767, 0x95ee, 0x9bb2, 0x9460, 0x94a2, 0x9875, + 0x97ac, 0x91d3, 0x987b, 0x8eeb, 0x976a, 0x965e, 0x97eb, 0x9ff9, + 0x95f8, 0xfea2, 0x8fe6, 0xfe7e, 0x9da4, 0x9768, 0x8eec, 0x94bd, + 0x945b, 0x9cf6, 0xfaa7, 0x9bd9, 0xfa5d, 0x9656, 0x9762, 0x94ba, + 0xa04f, 0x92d8, 0x9bcb, 0x94bb, 0x9d5f, 0x90cf, 0x9465, 0x9f4c, + 0x90d8, 0x9ebe, 0xfb6d, 0x95ca, 0x9dc2, 0x97f8, 0x8ffc, 0x9473, + 0x9474, 0xfeb7, 0x8a4b, 0x8a55, 0x8b69, 0x8adc, 0x8b76, 0x9bce, + 0x8a68, 0xa0f8, 0x98df, 0xfeb5, 0x9bcf, 0x96fb, 0x9bfb, 0x9ece, + 0x8ee5, 0x9e7b, 0x9bd2, 0x8aa5, 0xfece, 0x8a45, 0x9dfc, 0xfecf, + 0x8ba5, 0x8aec, 0xfce0, 0x94ad, 0xfed5, 0x94ac, 0xfc5a, 0x9bd6, + 0x8a6f, 0x8ba9, 0x8e5f, 0x9dcb, 0xfce7, 0x9bd7, 0x93c8, 0x91f0, + 0x8fe0, 0x9bdb, 0x90ed, 0x9bdc, 0xa0ec, 0x98fa, 0x9be0, 0x93c7, + 0x9249, 0x96e1, 0x9be2, 0x9be4, 0x8fe1, 0x9be5, 0x94c0, 0x93c3, + 0x93c5, 0x9079, 0x977b, 0x907e, 0xfee6, 0xfe46, 0x9db8, 0x9270, + 0x95a8, 0x94c8, 0x98b9, 0x9140, 0xfcbe, 0x9157, 0x8bb2, 0xfadf, + 0x9be6, 0x9643, 0x8e44, 0x9c4f, 0xfef4, 0x9be8, 0x93dc, 0x966f, + 0x8e4a, 0x9bed, 0x92f6, 0x9db9, 0x8e4e, 0xfbcf, 0x9ec2, 0x94e5, + 0x9bf0, 0x94e4, 0x9551, 0x8bbb, 0x9bf1, 0x94f0, 0x8e64, 0x94ea, + 0x8f61, 0x9b64, 0x8e5b, 0x9bf2, 0x9fbe, 0x9dc9, 0x8e6c, 0x8f73, + 0x8f75, 0x8e71, 0x8e60, 0x8e6a, 0x9552, 0x9554, 0x8ad4, 0x9dbb, + 0x9543, 0x92fe, 0x94f2, 0x94f1, 0xa0ea, 0x9dd2, 0xa0b1, 0x91f8, + 0x9462, 0x9ba4, 0x8ead, 0x9ead, 0x96d0, 0xfeee, 0x8ab4, 0x9757, + 0x8a77, 0x9bf7, 0x8eb5, 0xa06d, 0x8eb6, 0x9756, 0x9540, 0xa0f3, + 0x94be, 0x9bfa, 0xfddf, 0x9dbc, 0x94fe, 0x8bdb, 0xa0fe, 0x8ec0, + 0x9f47, 0x8bde, 0xa0fb, 0x8ec3, 0x9649, 0xfec2, 0x954c, 0x9bfd, + 0x90cc, 0x9c60, 0x954b, 0x9bfe, 0x9c70, 0x9c43, 0x9c47, 0x8ecc, + 0x8e54, 0x8ee4, 0x9c49, 0x8b5e, 0x955e, 0x955c, 0x9c4b, 0x8be1, + 0x8ed9, 0x9db4, 0x925f, 0x9c4c, 0x8aa1, 0x8edb, 0x9c56, 0x8aa2, + 0x9754, 0x9c5e, 0x9ed4, 0x9568, 0xa0c3, 0x8ae6, 0xa0f7, 0x9c61, + 0x9c5f, 0xfc4d, 0x9e5b, 0x9e69, 0x9c63, 0xfec7, 0xfec6, 0x9c67, + 0x9c69, 0x8be2, 0x9165, 0x9ce7, 0x8a54, 0x9c6c, 0x9c6e, 0xfe5d, + 0x9c73, 0x956a, 0x956d, 0x8ef0, 0x8f4d, 0x8ef6, 0xfabc, 0xfbda, + 0x8b4c, 0xfd75, 0x9bdd, 0xfaf5, 0x9c74, 0x9545, 0x96c6, 0x8f6a, + 0x8f4e, 0x9c78, 0xfa55, 0x97e4, 0x9c41, 0x925c, 0x96fa, 0xfb66, + 0x8e65, 0x9849, 0xfba8, 0x9842, 0x9c7a, 0x97fb, 0x90ca, 0x9c5b, + 0x974d, 0x8ed3, 0x9561, 0x9f4b, 0x9fb5, 0x93d2, 0xfdaa, 0x9840, + 0x9146, 0x9867, 0xfa5a, 0xfba9, 0x9841, 0xfcfd, 0xfdab, 0x91bd, + 0x8f4c, 0x96c9, 0x8f55, 0xfbae, 0x956f, 0x9c7d, 0xa0f0, 0x946f, + 0xfdac, 0x96cb, 0x96ce, 0xa056, 0x9ce1, 0x96c4, 0x8f5e, 0x8f6c, + 0x8ea3, 0xfbb3, 0xfc53, 0xfdb3, 0x8f6b, 0x96ca, 0x8f79, 0x9e6f, + 0xa0c5, 0xfc78, 0x8e42, 0x8f5a, 0x90c2, 0x8ea5, 0x9061, 0x924f, + 0x9373, 0xfdb5, 0xfecc, 0xfbbd, 0x9843, 0x96c5, 0x89bc, 0x9ca3, + 0x924b, 0x984a, 0x8fa4, 0xa0f1, 0x9efb, 0x9cd2, 0x8fa7, 0xfc5c, + 0x9845, 0x9046, 0xfefa, 0x9560, 0x9f48, 0x9247, 0x90fb, 0x9ca4, + 0x9571, 0x9ca6, 0x9ca7, 0x9caa, 0x9ed3, 0x9e70, 0x9cac, 0x8fae, + 0x957d, 0x9cb0, 0x97b6, 0xa0bd, 0x8adf, 0x9eaa, 0x8fbd, 0x8fbf, + 0x9369, 0x9ba7, 0xc8a4, 0xfeea, 0x9be1, 0x8b41, 0x9db6, 0xa0eb, + 0x9ba3, 0x8ba1, 0x8fc8, 0x894c, 0x9860, 0x94c7, 0x8b58, 0x95ab, + 0x95aa, 0x9cc3, 0x9cc4, 0x93d6, 0x9dac, 0x8be6, 0x8a71, 0x8fd1, + 0x99d5, 0x90f4, 0x8aa3, 0x9cce, 0x9cd4, 0x9cd5, 0xfbc8, 0x9db3, + 0xfc70, 0x8fd7, 0x9b73, 0xfa5b, 0x8fd2, 0x9064, 0x98b6, 0x9668, + 0x9cd6, 0x98bd, 0x8fdc, 0xfef6, 0x8fd9, 0x9541, 0x97f3, 0x9bf8, + 0x9e6c, 0x8ff2, 0x8fee, 0x9cd7, 0x9e6e, 0x8a40, 0x8fef, 0x8ff4, + 0x8ff5, 0x95c2, 0x986a, 0x97cf, 0x9ee5, 0x9e7c, 0x9041, 0x9cdb, + 0x9441, 0x9ce6, 0x9db0, 0x9cea, 0x9ced, 0x9cfa, 0x8b62, 0x8a4e, + 0x9cca, 0x8a66, 0x9cfb, 0x9cfc, 0x9cfe, 0x8a53, 0x9ce5, 0x9d40, + 0x9d41, 0x9045, 0x8b73, 0x97ca, 0x9d42, 0x8a61, 0x8bae, 0x8ad2, + 0x8ba2, 0x9df2, 0x9d43, 0x9cdf, 0x9d44, 0x8eca, 0x904e, 0x8eb3, + 0x9ff5, 0x9d45, 0x904f, 0x9d47, 0x89ca, 0x9cb5, 0xfbfe, 0x905e, + 0x9063, 0x9057, 0x9066, 0x9bc0, 0xfce5, 0x9162, 0x9067, 0x8fa1, + 0x8fa2, 0x9d48, 0xfad3, 0x905d, 0x90b9, 0x906b, 0x9069, 0xfe57, + 0xfe55, 0x9073, 0x9bef, 0x9cf0, 0x9d4b, 0xfed9, 0xfeda, 0x91e0, + 0x91d8, 0x9646, 0x9360, 0xfa53, 0x9cd3, 0x9d4e, 0xfb40, 0x8de2, + 0x9442, 0x9056, 0x9865, 0xfa4a, 0x9d50, 0x9d52, 0x95af, 0x975a, + 0x9349, 0x9747, 0xa0f4, 0x9778, 0x8fcf, 0xfc60, 0xfc56, 0x91dc, + 0x9661, 0x92ec, 0x935d, 0x8ede, 0x96fe, 0xfd4f, 0x95de, 0x98b0, + 0xa040, 0x97bd, 0x977d, 0x97f5, 0x9bac, 0xfada, 0x92c2, 0x97b1, + 0x907b, 0x93fe, 0x947b, 0x9777, 0xfabe, 0xfd43, 0x90c6, 0x90a4, + 0x90a8, 0x94a9, 0x90a9, 0x95e0, 0x907d, 0x9265, 0xfdba, 0x93c4, + 0xfeed, 0x9dab, 0xa0e3, 0x9648, 0x9d53, 0x8aa9, 0x9bc5, 0x965d, + 0x975f, 0x965f, 0x966e, 0xfb5d, 0x9db1, 0xfea3, 0x9db2, 0x95ae, + 0xfca3, 0xa0a2, 0x9655, 0x9d54, 0x9341, 0x95ad, 0x91d5, 0x977a, + 0xfdfc, 0x8e47, 0x93fd, 0x90a5, 0x90ac, 0x95ac, 0x90ae, 0xfea5, + 0x9d56, 0x97e3, 0x95e2, 0x9466, 0x9647, 0x91b8, 0x9cec, 0x90ad, + 0x95e3, 0x8b4f, 0x8ae3, 0x8b4d, 0x95ea, 0x8b4e, 0x8bed, 0x91d9, + 0xa0a4, 0x95f5, 0x95f4, 0x9fb3, 0xfeaf, 0xfe72, 0x927a, 0xfeac, + 0x95f3, 0x9d58, 0x9372, 0x91c5, 0x9642, 0x90cd, 0x95fe, 0x9159, + 0x9c65, 0x97cc, 0x90ce, 0x9d59, 0xfcf5, 0xfefd, 0x9d5b, 0x9d5c, + 0x937e, 0x98ac, 0x9d5e, 0xfdd0, 0xfd60, 0x9ccf, 0x90dd, 0x90e0, + 0x90f3, 0x98b1, 0x90f0, 0x93bd, 0x95b7, 0x9f46, 0x8e4b, 0x9658, + 0x8a4c, 0x9d63, 0x9ecf, 0x9d65, 0x9d66, 0x965a, 0x9d64, 0x8a6c, + 0x8ad9, 0x9d67, 0x8a70, 0x8bf3, 0x9150, 0x9cc1, 0x9d68, 0x93a7, + 0x9674, 0xa0ef, 0x9151, 0x96c1, 0x9676, 0x9d69, 0xfca4, 0x9d6a, + 0x924e, 0x9d6b, 0x9bc1, 0x9d6c, 0x8a65, 0x915d, 0x9d6d, 0x915a, + 0x9cc0, 0x916a, 0x9d6e, 0x9ea6, 0x9dcd, 0x9d6f, 0x89bb, 0x9ef9, + 0x96b4, 0x9172, 0x9ec8, 0x8b55, 0x9d71, 0x9d72, 0x9ecc, 0x9174, + 0x9ed0, 0x905c, 0x8ed2, 0x91a8, 0x9177, 0x96bf, 0x96c0, 0x8fb1, + 0x96b7, 0x9178, 0x89be, 0x917c, 0xfb77, 0x9175, 0x91a3, 0x9176, + 0x96be, 0x9179, 0x96b6, 0x91a4, 0x91a6, 0x9d75, 0x9052, 0xa045, + 0x91a9, 0x98aa, 0x8baa, 0x9cdd, 0x9d77, 0x8940, 0x9eec, 0x93aa, + 0x9478, 0x9d7a, 0x8ac9, 0x8b4b, 0x9fec, 0x8ae2, 0x9e75, 0x9874, + 0x9ac8, 0xa047, 0x8bc3, 0xfc48, 0xfc77, 0x9c52, 0x8efd, 0x8fa8, + 0x957a, 0x8ff0, +}; + +static const Summary16 hkscs1999_uni2indx_page00[45] = { + /* 0x0000 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0100 }, { 1, 0x0000 }, + { 1, 0x0703 }, { 6, 0x000c }, { 8, 0x3703 }, { 15, 0x170c }, + /* 0x0100 */ + { 21, 0x0003 }, { 23, 0x0c0c }, { 27, 0x0800 }, { 28, 0x0000 }, + { 28, 0x3800 }, { 31, 0x0008 }, { 32, 0x0800 }, { 33, 0x0000 }, + { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, + { 33, 0x6000 }, { 35, 0x1557 }, { 43, 0x0000 }, { 43, 0x0000 }, + /* 0x0200 */ + { 43, 0x0000 }, { 43, 0x0000 }, { 43, 0x0000 }, { 43, 0x0000 }, + { 43, 0x0000 }, { 43, 0x0813 }, { 47, 0x0402 }, { 49, 0x0020 }, + { 50, 0x0408 }, { 52, 0x0000 }, { 52, 0x0000 }, { 52, 0x0000 }, + { 52, 0x0040 }, +}; +static const Summary16 hkscs1999_uni2indx_page04[6] = { + /* 0x0400 */ + { 53, 0x0002 }, { 54, 0xffff }, { 70, 0xffff }, { 86, 0xffff }, + { 102, 0xffff }, { 118, 0x0002 }, +}; +static const Summary16 hkscs1999_uni2indx_page1e[13] = { + /* 0x1e00 */ + { 119, 0x0000 }, { 119, 0x0000 }, { 119, 0x0000 }, { 119, 0x0000 }, + { 119, 0x0000 }, { 119, 0x0000 }, { 119, 0x0000 }, { 119, 0x0000 }, + { 119, 0x0000 }, { 119, 0x0000 }, { 119, 0x0000 }, { 119, 0xc000 }, + { 121, 0x0003 }, +}; +static const Summary16 hkscs1999_uni2indx_page21[15] = { + /* 0x2100 */ + { 123, 0x0000 }, { 123, 0x0040 }, { 124, 0x0002 }, { 125, 0x0000 }, + { 125, 0x0000 }, { 125, 0x0000 }, { 125, 0x0000 }, { 125, 0x03ff }, + { 135, 0x0000 }, { 135, 0x0000 }, { 135, 0x0000 }, { 135, 0x0300 }, + { 137, 0x0000 }, { 137, 0x0000 }, { 137, 0x0080 }, +}; +static const Summary16 hkscs1999_uni2indx_page23[40] = { + /* 0x2300 */ + { 138, 0x0000 }, { 138, 0x0000 }, { 138, 0x0000 }, { 138, 0x0000 }, + { 138, 0x0000 }, { 138, 0x0000 }, { 138, 0x0000 }, { 138, 0x0000 }, + { 138, 0x0000 }, { 138, 0x0000 }, { 138, 0x0000 }, { 138, 0x0000 }, + { 138, 0x0000 }, { 138, 0x0c00 }, { 140, 0x0000 }, { 140, 0x0000 }, + /* 0x2400 */ + { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x0000 }, + { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x03ff }, { 150, 0x3ff0 }, + { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, + { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, + /* 0x2500 */ + { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, { 160, 0x0000 }, + { 160, 0x0000 }, { 160, 0xffff }, { 176, 0xffff }, { 192, 0x0001 }, +}; +static const Summary16 hkscs1999_uni2indx_page27[4] = { + /* 0x2700 */ + { 193, 0x0000 }, { 193, 0x0000 }, { 193, 0x0000 }, { 193, 0x2000 }, +}; +static const Summary16 hkscs1999_uni2indx_page2e[68] = { + /* 0x2e00 */ + { 194, 0x0000 }, { 194, 0x0000 }, { 194, 0x0000 }, { 194, 0x0000 }, + { 194, 0x0000 }, { 194, 0x0000 }, { 194, 0x0000 }, { 194, 0x0000 }, + { 194, 0x35d1 }, { 202, 0x3020 }, { 205, 0x54a0 }, { 210, 0x5040 }, + { 213, 0xb440 }, { 218, 0x40c0 }, { 221, 0x0008 }, { 222, 0x0000 }, + /* 0x2f00 */ + { 222, 0x0000 }, { 222, 0x0000 }, { 222, 0x0000 }, { 222, 0x0008 }, + { 223, 0x0000 }, { 223, 0x0000 }, { 223, 0x0000 }, { 223, 0x0000 }, + { 223, 0x0000 }, { 223, 0x0000 }, { 223, 0x0000 }, { 223, 0x0000 }, + { 223, 0x0000 }, { 223, 0x0000 }, { 223, 0x0000 }, { 223, 0x0000 }, + /* 0x3000 */ + { 223, 0x00e0 }, { 226, 0x0000 }, { 226, 0x0000 }, { 226, 0x0000 }, + { 226, 0xfffe }, { 241, 0xffff }, { 257, 0xffff }, { 273, 0xffff }, + { 289, 0xffff }, { 305, 0x780f }, { 313, 0xfffe }, { 328, 0xffff }, + { 344, 0xffff }, { 360, 0xffff }, { 376, 0xffff }, { 392, 0x707f }, + /* 0x3100 */ + { 402, 0x0000 }, { 402, 0x0000 }, { 402, 0x0000 }, { 402, 0x0000 }, + { 402, 0x0000 }, { 402, 0x0000 }, { 402, 0x0000 }, { 402, 0x0000 }, + { 402, 0x0000 }, { 402, 0x0000 }, { 402, 0x0000 }, { 402, 0x0000 }, + { 402, 0xffff }, { 418, 0x0000 }, { 418, 0x0000 }, { 418, 0x0000 }, + /* 0x3200 */ + { 418, 0x0000 }, { 418, 0x0000 }, { 418, 0x0000 }, { 418, 0x0002 }, +}; +static const Summary16 hkscs1999_uni2indx_page34[1724] = { + /* 0x3400 */ + { 419, 0x0000 }, { 419, 0x0000 }, { 419, 0x0000 }, { 419, 0x0020 }, + { 420, 0x1001 }, { 422, 0x0000 }, { 422, 0x0010 }, { 423, 0x6408 }, + { 427, 0x0000 }, { 427, 0x0048 }, { 429, 0x8020 }, { 431, 0x1000 }, + { 432, 0x0102 }, { 434, 0x8000 }, { 435, 0x0010 }, { 436, 0x0800 }, + /* 0x3500 */ + { 437, 0x0040 }, { 438, 0x0000 }, { 438, 0x0000 }, { 438, 0x4000 }, + { 439, 0x0000 }, { 439, 0x000a }, { 441, 0x2002 }, { 443, 0x0185 }, + { 447, 0x0010 }, { 448, 0x0180 }, { 450, 0x2022 }, { 453, 0x8000 }, + { 454, 0x44a2 }, { 459, 0x2844 }, { 463, 0x0000 }, { 463, 0x480e }, + /* 0x3600 */ + { 468, 0x0200 }, { 469, 0x0500 }, { 471, 0x2008 }, { 473, 0x4220 }, + { 476, 0x4380 }, { 480, 0x8000 }, { 481, 0x0000 }, { 481, 0x0400 }, + { 482, 0x0002 }, { 483, 0x0400 }, { 484, 0x1420 }, { 487, 0x1223 }, + { 492, 0x01ba }, { 498, 0x2058 }, { 502, 0x0066 }, { 506, 0x0020 }, + /* 0x3700 */ + { 507, 0x250a }, { 512, 0x1000 }, { 513, 0x302c }, { 518, 0x040d }, + { 522, 0x0009 }, { 524, 0x0000 }, { 524, 0x8004 }, { 526, 0x0000 }, + { 526, 0x0000 }, { 526, 0x0080 }, { 527, 0x0001 }, { 528, 0x4200 }, + { 530, 0x0000 }, { 530, 0x0000 }, { 530, 0x0000 }, { 530, 0x0904 }, + /* 0x3800 */ + { 533, 0x8000 }, { 534, 0x0200 }, { 535, 0x2001 }, { 537, 0x0140 }, + { 539, 0x0000 }, { 539, 0x0000 }, { 539, 0x0008 }, { 540, 0x0000 }, + { 540, 0x0000 }, { 540, 0x0000 }, { 540, 0x0001 }, { 541, 0x0000 }, + { 541, 0x1008 }, { 543, 0x0002 }, { 544, 0x0000 }, { 544, 0x0400 }, + /* 0x3900 */ + { 545, 0x0100 }, { 546, 0x0010 }, { 547, 0x0080 }, { 548, 0x8004 }, + { 550, 0x2000 }, { 551, 0x0000 }, { 551, 0x0008 }, { 552, 0x0000 }, + { 552, 0x0601 }, { 555, 0x0a04 }, { 558, 0x0012 }, { 560, 0x0100 }, + { 561, 0x0000 }, { 561, 0x1000 }, { 562, 0x1024 }, { 565, 0x4900 }, + /* 0x3a00 */ + { 568, 0x004a }, { 571, 0x0180 }, { 573, 0x0600 }, { 575, 0x0010 }, + { 576, 0x0800 }, { 577, 0x5084 }, { 581, 0x00c0 }, { 583, 0x0000 }, + { 583, 0x0000 }, { 583, 0x0080 }, { 584, 0x0800 }, { 585, 0x2000 }, + { 586, 0x0000 }, { 586, 0x4000 }, { 587, 0x0001 }, { 588, 0x0805 }, + /* 0x3b00 */ + { 591, 0x4000 }, { 592, 0x0200 }, { 593, 0x0804 }, { 595, 0x0200 }, + { 596, 0x0004 }, { 597, 0x0100 }, { 598, 0x0001 }, { 599, 0x1806 }, + { 603, 0x0001 }, { 604, 0x0240 }, { 606, 0x0002 }, { 607, 0x5000 }, + { 609, 0x0014 }, { 611, 0x2080 }, { 613, 0x1000 }, { 614, 0x001c }, + /* 0x3c00 */ + { 617, 0x2000 }, { 618, 0x0122 }, { 621, 0x0000 }, { 621, 0x0000 }, + { 621, 0x0000 }, { 621, 0x0010 }, { 622, 0x0000 }, { 622, 0x0000 }, + { 622, 0x0000 }, { 622, 0x0000 }, { 622, 0x0000 }, { 622, 0x0000 }, + { 622, 0x2800 }, { 624, 0x1042 }, { 627, 0x8800 }, { 629, 0x0000 }, + /* 0x3d00 */ + { 629, 0x0000 }, { 629, 0x2008 }, { 631, 0x0000 }, { 631, 0x0804 }, + { 633, 0x5040 }, { 636, 0x8002 }, { 638, 0x8604 }, { 642, 0x2020 }, + { 644, 0x8420 }, { 647, 0x0002 }, { 648, 0x2020 }, { 650, 0x8010 }, + { 652, 0x30c0 }, { 656, 0x0808 }, { 658, 0x0980 }, { 661, 0x3088 }, + /* 0x3e00 */ + { 665, 0x0040 }, { 666, 0x0000 }, { 666, 0x0000 }, { 666, 0x0000 }, + { 666, 0x0109 }, { 669, 0x0020 }, { 670, 0x0000 }, { 670, 0x0010 }, + { 671, 0x0000 }, { 671, 0x0000 }, { 671, 0x2700 }, { 675, 0x8102 }, + { 678, 0x1484 }, { 682, 0x44c3 }, { 688, 0x0a86 }, { 693, 0x9419 }, + /* 0x3f00 */ + { 699, 0x4051 }, { 703, 0x0000 }, { 703, 0x0000 }, { 703, 0x0000 }, + { 703, 0x0000 }, { 703, 0x0308 }, { 706, 0x0008 }, { 707, 0x1000 }, + { 708, 0x0000 }, { 708, 0x0008 }, { 709, 0x0000 }, { 709, 0x0000 }, + { 709, 0x0001 }, { 710, 0x1080 }, { 712, 0x2020 }, { 714, 0x0600 }, + /* 0x4000 */ + { 716, 0x0010 }, { 717, 0x2000 }, { 718, 0x0000 }, { 718, 0x0200 }, + { 719, 0x0020 }, { 720, 0x0088 }, { 722, 0x8424 }, { 726, 0x0000 }, + { 726, 0x0000 }, { 726, 0x0000 }, { 726, 0x0100 }, { 727, 0x8800 }, + { 729, 0x0100 }, { 730, 0x8100 }, { 732, 0x0000 }, { 732, 0x0400 }, + /* 0x4100 */ + { 733, 0x4218 }, { 737, 0x0000 }, { 737, 0x0000 }, { 737, 0x0004 }, + { 738, 0x0000 }, { 738, 0x0000 }, { 738, 0x5080 }, { 741, 0x8000 }, + { 742, 0x0000 }, { 742, 0x0001 }, { 743, 0x0000 }, { 743, 0x0004 }, + { 744, 0x8410 }, { 747, 0x0800 }, { 748, 0x8000 }, { 749, 0x0200 }, + /* 0x4200 */ + { 750, 0x0000 }, { 750, 0x0002 }, { 751, 0x0000 }, { 751, 0x0000 }, + { 751, 0x0001 }, { 752, 0x0000 }, { 752, 0x0401 }, { 754, 0x0400 }, + { 755, 0x1000 }, { 756, 0x0010 }, { 757, 0x0000 }, { 757, 0x1220 }, + { 760, 0x0000 }, { 760, 0x0000 }, { 760, 0x0000 }, { 760, 0x1810 }, + /* 0x4300 */ + { 763, 0x0000 }, { 763, 0x0000 }, { 763, 0x0800 }, { 764, 0x0000 }, + { 764, 0x0000 }, { 764, 0x0000 }, { 764, 0x4000 }, { 765, 0x0000 }, + { 765, 0x0000 }, { 765, 0x0080 }, { 766, 0x0000 }, { 766, 0x0400 }, + { 767, 0x0002 }, { 768, 0x8200 }, { 770, 0x2000 }, { 771, 0x0004 }, + /* 0x4400 */ + { 772, 0x0006 }, { 774, 0x0008 }, { 775, 0x2020 }, { 777, 0x0000 }, + { 777, 0x0000 }, { 777, 0x0000 }, { 777, 0x0000 }, { 777, 0x0400 }, + { 778, 0x8000 }, { 779, 0x8002 }, { 781, 0x0005 }, { 783, 0x0081 }, + { 785, 0x4021 }, { 788, 0xa000 }, { 790, 0x1e10 }, { 795, 0x0010 }, + /* 0x4500 */ + { 796, 0x0a18 }, { 800, 0x2040 }, { 802, 0x4080 }, { 804, 0xa808 }, + { 808, 0x0008 }, { 809, 0x1026 }, { 813, 0x0404 }, { 815, 0x0080 }, + { 816, 0x0020 }, { 817, 0x0000 }, { 817, 0x0000 }, { 817, 0x0000 }, + { 817, 0x0000 }, { 817, 0x0000 }, { 817, 0x0200 }, { 818, 0x0000 }, + /* 0x4600 */ + { 818, 0x8040 }, { 820, 0x00a0 }, { 822, 0x0000 }, { 822, 0x0000 }, + { 822, 0x0000 }, { 822, 0x0800 }, { 823, 0x0000 }, { 823, 0x0400 }, + { 824, 0x0001 }, { 825, 0x0000 }, { 825, 0x0000 }, { 825, 0x0000 }, + { 825, 0x8000 }, { 826, 0x0001 }, { 827, 0x0000 }, { 827, 0x0020 }, + /* 0x4700 */ + { 828, 0x0000 }, { 828, 0x0108 }, { 830, 0x0000 }, { 830, 0x0000 }, + { 830, 0x4000 }, { 831, 0x0000 }, { 831, 0x0000 }, { 831, 0x1000 }, + { 832, 0x0000 }, { 832, 0x0100 }, { 833, 0x0040 }, { 834, 0x0000 }, + { 834, 0x0000 }, { 834, 0x0020 }, { 835, 0x2000 }, { 836, 0x0010 }, + /* 0x4800 */ + { 837, 0x0801 }, { 839, 0x0000 }, { 839, 0x0000 }, { 839, 0x0080 }, + { 840, 0x0000 }, { 840, 0x2000 }, { 841, 0x0000 }, { 841, 0x0002 }, + { 842, 0x0000 }, { 842, 0x0800 }, { 843, 0x6000 }, { 845, 0x0000 }, + { 845, 0x0000 }, { 845, 0x2001 }, { 847, 0x2000 }, { 848, 0x0408 }, + /* 0x4900 */ + { 850, 0x0040 }, { 851, 0x4002 }, { 853, 0x2420 }, { 856, 0x5020 }, + { 859, 0x0020 }, { 860, 0x000a }, { 862, 0x0420 }, { 864, 0x0004 }, + { 865, 0x0200 }, { 866, 0x0000 }, { 866, 0x0082 }, { 868, 0x0000 }, + { 868, 0x0000 }, { 868, 0x8000 }, { 869, 0x00a0 }, { 871, 0x0000 }, + /* 0x4a00 */ + { 871, 0x8000 }, { 872, 0x2000 }, { 873, 0x0010 }, { 874, 0x0020 }, + { 875, 0x0000 }, { 875, 0x0000 }, { 875, 0x0000 }, { 875, 0x0000 }, + { 875, 0x0000 }, { 875, 0x0040 }, { 876, 0x0000 }, { 876, 0x0110 }, + { 878, 0x0000 }, { 878, 0x0002 }, { 879, 0x0010 }, { 880, 0x8000 }, + /* 0x4b00 */ + { 881, 0x0000 }, { 881, 0x0200 }, { 882, 0x1000 }, { 883, 0x0080 }, + { 884, 0x0000 }, { 884, 0x0000 }, { 884, 0x8000 }, { 885, 0x4805 }, + { 889, 0x4000 }, { 890, 0x20c9 }, { 895, 0x0000 }, { 895, 0x6000 }, + { 897, 0x0001 }, { 898, 0x0000 }, { 898, 0x0000 }, { 898, 0x0000 }, + /* 0x4c00 */ + { 898, 0x4090 }, { 901, 0x0000 }, { 901, 0x0000 }, { 901, 0x4800 }, + { 903, 0x0000 }, { 903, 0x0800 }, { 904, 0x2000 }, { 905, 0x2000 }, + { 906, 0x0000 }, { 906, 0x0000 }, { 906, 0x4010 }, { 908, 0x0081 }, + { 910, 0x2000 }, { 911, 0x0000 }, { 911, 0x2002 }, { 913, 0x0000 }, + /* 0x4d00 */ + { 913, 0x0200 }, { 914, 0x0001 }, { 915, 0x0000 }, { 915, 0x0010 }, + { 916, 0x0000 }, { 916, 0x0000 }, { 916, 0x0000 }, { 916, 0x0000 }, + { 916, 0x0000 }, { 916, 0x1002 }, { 918, 0x0000 }, { 918, 0x0000 }, + { 918, 0x0000 }, { 918, 0x0000 }, { 918, 0x0000 }, { 918, 0x0000 }, + /* 0x4e00 */ + { 918, 0x0010 }, { 919, 0x1400 }, { 921, 0x1512 }, { 926, 0xa0c0 }, + { 930, 0x0200 }, { 931, 0x0c00 }, { 933, 0x0400 }, { 934, 0x0100 }, + { 935, 0x02a3 }, { 940, 0x0500 }, { 942, 0x0001 }, { 943, 0x9880 }, + { 947, 0x4000 }, { 948, 0x0000 }, { 948, 0x4c00 }, { 951, 0x0100 }, + /* 0x4f00 */ + { 952, 0x0008 }, { 953, 0x0400 }, { 954, 0x0300 }, { 956, 0x0284 }, + { 959, 0x0824 }, { 962, 0x0000 }, { 962, 0x0000 }, { 962, 0x0004 }, + { 963, 0x0400 }, { 964, 0x0000 }, { 964, 0x0904 }, { 967, 0x2001 }, + { 969, 0x1100 }, { 971, 0x0000 }, { 971, 0x0030 }, { 973, 0x2204 }, + /* 0x5000 */ + { 976, 0x0108 }, { 978, 0x0000 }, { 978, 0x4000 }, { 979, 0x0010 }, + { 980, 0x0000 }, { 980, 0x0140 }, { 982, 0x1040 }, { 984, 0x0000 }, + { 984, 0x0102 }, { 986, 0x0001 }, { 987, 0x0040 }, { 988, 0x0000 }, + { 988, 0x2000 }, { 989, 0x8201 }, { 992, 0x0002 }, { 993, 0x1010 }, + /* 0x5100 */ + { 995, 0x6002 }, { 998, 0x0000 }, { 998, 0x0800 }, { 999, 0x0000 }, + { 999, 0x0000 }, { 999, 0x0040 }, { 1000, 0x0401 }, { 1002, 0x0210 }, + { 1004, 0x0144 }, { 1007, 0x1440 }, { 1010, 0x0980 }, { 1013, 0x013c }, + { 1018, 0x8288 }, { 1022, 0x880e }, { 1027, 0x2014 }, { 1030, 0x5010 }, + /* 0x5200 */ + { 1033, 0x0824 }, { 1036, 0x8000 }, { 1037, 0x00c1 }, { 1040, 0x1010 }, + { 1042, 0x0000 }, { 1042, 0x0280 }, { 1044, 0x0101 }, { 1046, 0x0208 }, + { 1048, 0x8000 }, { 1049, 0x0411 }, { 1052, 0x0112 }, { 1055, 0x0220 }, + { 1057, 0x1020 }, { 1059, 0x0003 }, { 1061, 0x0003 }, { 1063, 0x0200 }, + /* 0x5300 */ + { 1064, 0x0002 }, { 1065, 0x0000 }, { 1065, 0x1080 }, { 1067, 0x090c }, + { 1071, 0x4004 }, { 1073, 0xa000 }, { 1075, 0x2290 }, { 1079, 0x6010 }, + { 1082, 0x0000 }, { 1082, 0x0008 }, { 1083, 0x4f45 }, { 1091, 0x0041 }, + { 1093, 0x1026 }, { 1097, 0x0707 }, { 1103, 0x0001 }, { 1104, 0x40c0 }, + /* 0x5400 */ + { 1107, 0x0000 }, { 1107, 0x0458 }, { 1111, 0x800a }, { 1114, 0x0004 }, + { 1115, 0x2800 }, { 1117, 0x0000 }, { 1117, 0x2600 }, { 1120, 0x0000 }, + { 1120, 0x8020 }, { 1122, 0x5098 }, { 1127, 0x0018 }, { 1129, 0x0214 }, + { 1132, 0x3800 }, { 1135, 0x0401 }, { 1137, 0x8008 }, { 1139, 0x0000 }, + /* 0x5500 */ + { 1139, 0x2004 }, { 1141, 0x4108 }, { 1144, 0x0928 }, { 1148, 0x8000 }, + { 1149, 0x0280 }, { 1151, 0x2008 }, { 1153, 0x0a00 }, { 1155, 0x020e }, + { 1159, 0x0040 }, { 1160, 0x0001 }, { 1161, 0x0200 }, { 1162, 0x1611 }, + { 1167, 0x0002 }, { 1168, 0x4180 }, { 1171, 0x1400 }, { 1173, 0x0823 }, + /* 0x5600 */ + { 1177, 0x0020 }, { 1178, 0x4002 }, { 1180, 0x202f }, { 1186, 0x0080 }, + { 1187, 0xa008 }, { 1190, 0x2015 }, { 1194, 0x0002 }, { 1195, 0x1c00 }, + { 1198, 0x0e00 }, { 1201, 0xc004 }, { 1204, 0x8012 }, { 1207, 0x8202 }, + { 1210, 0x0000 }, { 1210, 0x0040 }, { 1211, 0xa004 }, { 1214, 0x2002 }, + /* 0x5700 */ + { 1216, 0x0001 }, { 1217, 0x2020 }, { 1219, 0x0000 }, { 1219, 0x8004 }, + { 1221, 0x004c }, { 1224, 0x8890 }, { 1228, 0x0080 }, { 1229, 0xc400 }, + { 1232, 0x2500 }, { 1235, 0x1001 }, { 1237, 0x0482 }, { 1240, 0x4810 }, + { 1243, 0x0110 }, { 1245, 0x6080 }, { 1248, 0x8040 }, { 1250, 0x4000 }, + /* 0x5800 */ + { 1251, 0x0008 }, { 1252, 0x0004 }, { 1253, 0x0044 }, { 1255, 0x0400 }, + { 1256, 0x0091 }, { 1259, 0x9000 }, { 1261, 0x1200 }, { 1263, 0x000c }, + { 1265, 0x0000 }, { 1265, 0x0600 }, { 1267, 0x0480 }, { 1269, 0x0861 }, + { 1273, 0x0800 }, { 1274, 0x1000 }, { 1275, 0x0001 }, { 1276, 0x080d }, + /* 0x5900 */ + { 1280, 0x04b4 }, { 1285, 0x8002 }, { 1287, 0x0000 }, { 1287, 0x0014 }, + { 1289, 0x0000 }, { 1289, 0x0000 }, { 1289, 0x0020 }, { 1290, 0x0020 }, + { 1291, 0x0200 }, { 1292, 0x8410 }, { 1295, 0x1000 }, { 1296, 0x0181 }, + { 1299, 0x0210 }, { 1301, 0x0200 }, { 1302, 0x8800 }, { 1304, 0x0301 }, + /* 0x5a00 */ + { 1307, 0x2804 }, { 1310, 0x0004 }, { 1311, 0x1c92 }, { 1317, 0x2000 }, + { 1318, 0x0020 }, { 1319, 0x0210 }, { 1321, 0x490a }, { 1326, 0x4202 }, + { 1329, 0x0146 }, { 1333, 0x0242 }, { 1336, 0x0803 }, { 1339, 0x0000 }, + { 1339, 0xc008 }, { 1342, 0x0008 }, { 1343, 0x0010 }, { 1344, 0x4405 }, + /* 0x5b00 */ + { 1348, 0x2000 }, { 1349, 0x8002 }, { 1351, 0x0800 }, { 1352, 0x0000 }, + { 1352, 0x8452 }, { 1357, 0x0000 }, { 1357, 0x2140 }, { 1360, 0x1050 }, + { 1363, 0x0005 }, { 1365, 0xe001 }, { 1369, 0x0400 }, { 1370, 0x0000 }, + { 1370, 0x0008 }, { 1371, 0x00a0 }, { 1373, 0x0000 }, { 1373, 0x8008 }, + /* 0x5c00 */ + { 1375, 0x0020 }, { 1376, 0x5018 }, { 1380, 0x0009 }, { 1382, 0x0000 }, + { 1382, 0x0600 }, { 1384, 0x4008 }, { 1386, 0x0000 }, { 1386, 0x0000 }, + { 1386, 0x0020 }, { 1387, 0x5600 }, { 1391, 0x0000 }, { 1391, 0x0400 }, + { 1392, 0x0006 }, { 1394, 0x0002 }, { 1395, 0x8220 }, { 1398, 0x0000 }, + /* 0x5d00 */ + { 1398, 0x0000 }, { 1398, 0x0121 }, { 1401, 0x9000 }, { 1403, 0x4000 }, + { 1404, 0x0140 }, { 1406, 0x08c0 }, { 1409, 0x0000 }, { 1409, 0x0011 }, + { 1411, 0x4820 }, { 1414, 0x0000 }, { 1414, 0x0810 }, { 1416, 0x0240 }, + { 1418, 0x0002 }, { 1419, 0x0880 }, { 1421, 0x0000 }, { 1421, 0x0020 }, + /* 0x5e00 */ + { 1422, 0x0a00 }, { 1424, 0x0004 }, { 1425, 0x4000 }, { 1426, 0x0000 }, + { 1426, 0x0104 }, { 1428, 0x4000 }, { 1429, 0x0000 }, { 1429, 0x8400 }, + { 1431, 0x0048 }, { 1433, 0x0000 }, { 1433, 0x0000 }, { 1433, 0x2000 }, + { 1434, 0x2000 }, { 1435, 0x0001 }, { 1436, 0x0000 }, { 1436, 0x1b10 }, + /* 0x5f00 */ + { 1441, 0x7000 }, { 1444, 0x0000 }, { 1444, 0x0020 }, { 1445, 0x0400 }, + { 1446, 0x2000 }, { 1447, 0x1003 }, { 1450, 0x000a }, { 1452, 0x0804 }, + { 1454, 0x0008 }, { 1455, 0x0000 }, { 1455, 0x0090 }, { 1457, 0x0402 }, + { 1459, 0x0010 }, { 1460, 0x8800 }, { 1462, 0x0000 }, { 1462, 0x0000 }, + /* 0x6000 */ + { 1462, 0x0000 }, { 1462, 0x0000 }, { 1462, 0x0008 }, { 1463, 0x0802 }, + { 1465, 0x0400 }, { 1466, 0x0004 }, { 1467, 0x0000 }, { 1467, 0x40a0 }, + { 1470, 0x0000 }, { 1470, 0x4000 }, { 1471, 0x0090 }, { 1473, 0x0008 }, + { 1474, 0x0000 }, { 1474, 0x4080 }, { 1476, 0x0388 }, { 1480, 0x2000 }, + /* 0x6100 */ + { 1481, 0x1080 }, { 1483, 0x0200 }, { 1484, 0x0000 }, { 1484, 0x2001 }, + { 1486, 0x0004 }, { 1487, 0x1201 }, { 1490, 0x8011 }, { 1493, 0x2000 }, + { 1494, 0x0082 }, { 1496, 0x1320 }, { 1500, 0x0000 }, { 1500, 0x0280 }, + { 1502, 0x8001 }, { 1504, 0x0409 }, { 1507, 0x0004 }, { 1508, 0x0000 }, + /* 0x6200 */ + { 1508, 0x0000 }, { 1508, 0x0000 }, { 1508, 0x1000 }, { 1509, 0x0280 }, + { 1511, 0x1000 }, { 1512, 0x0000 }, { 1512, 0x0100 }, { 1513, 0x0000 }, + { 1513, 0x0024 }, { 1515, 0x2001 }, { 1517, 0x0050 }, { 1519, 0x0000 }, + { 1519, 0x0028 }, { 1521, 0x8020 }, { 1523, 0x0020 }, { 1524, 0x0000 }, + /* 0x6300 */ + { 1524, 0x0000 }, { 1524, 0x0100 }, { 1525, 0x4000 }, { 1526, 0x00a2 }, + { 1529, 0x0000 }, { 1529, 0x0000 }, { 1529, 0x1010 }, { 1531, 0x8200 }, + { 1533, 0x0800 }, { 1534, 0x0000 }, { 1534, 0x0000 }, { 1534, 0x0200 }, + { 1535, 0x0002 }, { 1536, 0x4002 }, { 1538, 0x0044 }, { 1540, 0x5900 }, + /* 0x6400 */ + { 1544, 0x0080 }, { 1545, 0x0000 }, { 1545, 0x0000 }, { 1545, 0x0d04 }, + { 1549, 0x0000 }, { 1549, 0x0400 }, { 1550, 0x0000 }, { 1550, 0x1002 }, + { 1552, 0x2000 }, { 1553, 0x0002 }, { 1554, 0x8000 }, { 1555, 0x0050 }, + { 1557, 0x0001 }, { 1558, 0x2008 }, { 1560, 0x04a2 }, { 1564, 0x0000 }, + /* 0x6500 */ + { 1564, 0x0400 }, { 1565, 0xc002 }, { 1568, 0x0000 }, { 1568, 0x0031 }, + { 1571, 0x2000 }, { 1572, 0x8000 }, { 1573, 0x2800 }, { 1575, 0x0000 }, + { 1575, 0x0360 }, { 1579, 0x0000 }, { 1579, 0x0000 }, { 1579, 0x4020 }, + { 1581, 0x0000 }, { 1581, 0x0012 }, { 1583, 0x0009 }, { 1585, 0x8000 }, + /* 0x6600 */ + { 1586, 0x0000 }, { 1586, 0x4100 }, { 1588, 0x0008 }, { 1589, 0x0001 }, + { 1590, 0x0910 }, { 1593, 0x0088 }, { 1595, 0x0888 }, { 1598, 0x2008 }, + { 1600, 0x4020 }, { 1602, 0x0404 }, { 1604, 0x2010 }, { 1606, 0x8048 }, + { 1609, 0x6000 }, { 1611, 0x0000 }, { 1611, 0x0000 }, { 1611, 0x0002 }, + /* 0x6700 */ + { 1612, 0x5004 }, { 1615, 0x4040 }, { 1617, 0x0020 }, { 1618, 0x0040 }, + { 1619, 0x0010 }, { 1620, 0x0000 }, { 1620, 0x0086 }, { 1623, 0x0000 }, + { 1623, 0x8000 }, { 1624, 0x0000 }, { 1624, 0x1011 }, { 1627, 0x8002 }, + { 1629, 0x0000 }, { 1629, 0x00c0 }, { 1631, 0x0000 }, { 1631, 0x4200 }, + /* 0x6800 */ + { 1633, 0x201f }, { 1639, 0x4801 }, { 1642, 0x0004 }, { 1643, 0x40c0 }, + { 1646, 0x0480 }, { 1648, 0x2060 }, { 1651, 0x0020 }, { 1652, 0x0000 }, + { 1652, 0x0110 }, { 1654, 0x0100 }, { 1655, 0x0040 }, { 1656, 0x2240 }, + { 1659, 0x0428 }, { 1662, 0x0000 }, { 1662, 0x0000 }, { 1662, 0x0000 }, + /* 0x6900 */ + { 1662, 0x020f }, { 1667, 0x0d00 }, { 1670, 0x1000 }, { 1671, 0x4040 }, + { 1673, 0x0048 }, { 1675, 0x0020 }, { 1676, 0x0092 }, { 1679, 0x000c }, + { 1681, 0x0421 }, { 1684, 0x8100 }, { 1686, 0x0004 }, { 1687, 0x0004 }, + { 1688, 0x0001 }, { 1689, 0x0062 }, { 1692, 0x0202 }, { 1694, 0x0600 }, + /* 0x6a00 */ + { 1696, 0x1808 }, { 1699, 0x1400 }, { 1701, 0x3800 }, { 1704, 0x0008 }, + { 1705, 0x1020 }, { 1707, 0x008c }, { 1710, 0x0020 }, { 1711, 0x0412 }, + { 1714, 0x8404 }, { 1717, 0x2200 }, { 1719, 0x0880 }, { 1721, 0x4026 }, + { 1725, 0x0700 }, { 1728, 0x0110 }, { 1730, 0x0000 }, { 1730, 0x0040 }, + /* 0x6b00 */ + { 1731, 0x0020 }, { 1732, 0x2000 }, { 1733, 0x0000 }, { 1733, 0x0020 }, + { 1734, 0x0000 }, { 1734, 0x0084 }, { 1736, 0x8000 }, { 1737, 0x0410 }, + { 1739, 0x0002 }, { 1740, 0x0000 }, { 1740, 0x0000 }, { 1740, 0x0000 }, + { 1740, 0x0002 }, { 1741, 0x1000 }, { 1742, 0x0402 }, { 1744, 0x0400 }, + /* 0x6c00 */ + { 1745, 0x0000 }, { 1745, 0x1000 }, { 1746, 0x0000 }, { 1746, 0x26a2 }, + { 1752, 0x0200 }, { 1753, 0x0500 }, { 1755, 0x4000 }, { 1756, 0x8220 }, + { 1759, 0x0000 }, { 1759, 0x8000 }, { 1760, 0x8404 }, { 1763, 0x0004 }, + { 1764, 0x4800 }, { 1766, 0x8000 }, { 1767, 0x0400 }, { 1768, 0x0000 }, + /* 0x6d00 */ + { 1768, 0x0064 }, { 1771, 0x0000 }, { 1771, 0x0050 }, { 1773, 0x0000 }, + { 1773, 0x4000 }, { 1774, 0x1880 }, { 1777, 0x0000 }, { 1777, 0x0006 }, + { 1779, 0x8002 }, { 1781, 0x0040 }, { 1782, 0x0030 }, { 1784, 0x0202 }, + { 1786, 0x0000 }, { 1786, 0x0000 }, { 1786, 0x0000 }, { 1786, 0x0000 }, + /* 0x6e00 */ + { 1786, 0x8414 }, { 1790, 0x0120 }, { 1792, 0x0600 }, { 1794, 0x0000 }, + { 1794, 0x8000 }, { 1795, 0x0201 }, { 1797, 0x0000 }, { 1797, 0x1040 }, + { 1799, 0x0840 }, { 1801, 0x0400 }, { 1802, 0x0000 }, { 1802, 0x0920 }, + { 1805, 0x0000 }, { 1805, 0x2e00 }, { 1809, 0x0304 }, { 1812, 0x0400 }, + /* 0x6f00 */ + { 1813, 0x1810 }, { 1816, 0x00c0 }, { 1818, 0x0010 }, { 1819, 0x2010 }, + { 1821, 0x0010 }, { 1822, 0x1040 }, { 1824, 0x0000 }, { 1824, 0x0210 }, + { 1826, 0x0402 }, { 1828, 0xa000 }, { 1830, 0x0000 }, { 1830, 0x4820 }, + { 1833, 0x0000 }, { 1833, 0x0608 }, { 1836, 0x0000 }, { 1836, 0x0140 }, + /* 0x7000 */ + { 1838, 0x0008 }, { 1839, 0x4000 }, { 1840, 0x1000 }, { 1841, 0x0000 }, + { 1841, 0x0800 }, { 1842, 0x1011 }, { 1845, 0x9080 }, { 1848, 0xc220 }, + { 1852, 0x8a02 }, { 1856, 0x0000 }, { 1856, 0x00e9 }, { 1861, 0x3a00 }, + { 1865, 0x1011 }, { 1868, 0x8061 }, { 1872, 0x0000 }, { 1872, 0x4022 }, + /* 0x7100 */ + { 1875, 0x0020 }, { 1876, 0x2000 }, { 1877, 0x1a00 }, { 1880, 0x4838 }, + { 1885, 0x8421 }, { 1889, 0x0002 }, { 1890, 0x0800 }, { 1891, 0x54ea }, + { 1899, 0x5100 }, { 1902, 0x0140 }, { 1904, 0x200c }, { 1907, 0x0490 }, + { 1910, 0x0000 }, { 1910, 0x2002 }, { 1912, 0x0800 }, { 1913, 0x0060 }, + /* 0x7200 */ + { 1915, 0xc200 }, { 1918, 0x00e0 }, { 1921, 0x4810 }, { 1924, 0x0000 }, + { 1924, 0x0001 }, { 1925, 0x10a1 }, { 1929, 0x0040 }, { 1930, 0x0000 }, + { 1930, 0x8084 }, { 1933, 0x8010 }, { 1935, 0x2000 }, { 1936, 0x0004 }, + { 1937, 0x2000 }, { 1938, 0x0000 }, { 1938, 0x0004 }, { 1939, 0x0000 }, + /* 0x7300 */ + { 1939, 0x0014 }, { 1941, 0x0001 }, { 1942, 0x5d00 }, { 1947, 0x0300 }, + { 1949, 0x8102 }, { 1952, 0x0000 }, { 1952, 0x0000 }, { 1952, 0x0012 }, + { 1954, 0x8000 }, { 1955, 0x5100 }, { 1958, 0x0480 }, { 1960, 0x0000 }, + { 1960, 0xc200 }, { 1963, 0x0021 }, { 1965, 0x8056 }, { 1970, 0x0a88 }, + /* 0x7400 */ + { 1974, 0x0000 }, { 1974, 0xd2b6 }, { 1983, 0x0000 }, { 1983, 0x1380 }, + { 1987, 0x03a8 }, { 1992, 0x2048 }, { 1995, 0x1921 }, { 2000, 0x0450 }, + { 2003, 0x3004 }, { 2006, 0x0a00 }, { 2008, 0x0010 }, { 2009, 0x0010 }, + { 2010, 0x1100 }, { 2012, 0x0009 }, { 2014, 0x0080 }, { 2015, 0x0107 }, + /* 0x7500 */ + { 2019, 0x4020 }, { 2021, 0x4200 }, { 2023, 0x0000 }, { 2023, 0x0830 }, + { 2026, 0x2444 }, { 2030, 0x002a }, { 2033, 0x6081 }, { 2037, 0x0404 }, + { 2039, 0x6008 }, { 2042, 0x4004 }, { 2044, 0x0000 }, { 2044, 0x0012 }, + { 2046, 0x0108 }, { 2048, 0x1000 }, { 2049, 0x0000 }, { 2049, 0x0000 }, + /* 0x7600 */ + { 2049, 0x0084 }, { 2051, 0x0000 }, { 2051, 0x1000 }, { 2052, 0x0800 }, + { 2053, 0xe001 }, { 2057, 0x0012 }, { 2059, 0x80c0 }, { 2062, 0x0458 }, + { 2066, 0x0000 }, { 2066, 0x0001 }, { 2067, 0x0022 }, { 2069, 0x0080 }, + { 2070, 0x1000 }, { 2071, 0x0040 }, { 2072, 0x0000 }, { 2072, 0x0000 }, + /* 0x7700 */ + { 2072, 0xd000 }, { 2075, 0x4000 }, { 2076, 0x0850 }, { 2079, 0x0000 }, + { 2079, 0x0009 }, { 2081, 0x0100 }, { 2082, 0x0000 }, { 2082, 0x0d84 }, + { 2087, 0x0000 }, { 2087, 0x0108 }, { 2089, 0x8000 }, { 2090, 0x4200 }, + { 2092, 0x0828 }, { 2095, 0x0000 }, { 2095, 0x0040 }, { 2096, 0x4010 }, + /* 0x7800 */ + { 2098, 0x0100 }, { 2099, 0x5100 }, { 2102, 0x0000 }, { 2102, 0x3200 }, + { 2105, 0x0894 }, { 2109, 0x001a }, { 2112, 0x0040 }, { 2113, 0x0400 }, + { 2114, 0x2102 }, { 2117, 0x0000 }, { 2117, 0x8000 }, { 2118, 0x0342 }, + { 2122, 0x0080 }, { 2123, 0x018c }, { 2127, 0x4000 }, { 2128, 0x0023 }, + /* 0x7900 */ + { 2131, 0x0040 }, { 2132, 0x0000 }, { 2132, 0x4000 }, { 2133, 0x185c }, + { 2139, 0x0000 }, { 2139, 0x0300 }, { 2141, 0x0004 }, { 2142, 0x4002 }, + { 2144, 0x00c9 }, { 2148, 0xa202 }, { 2152, 0x0220 }, { 2154, 0x0000 }, + { 2154, 0x1050 }, { 2157, 0x0010 }, { 2158, 0x0004 }, { 2159, 0x0012 }, + /* 0x7a00 */ + { 2161, 0x0040 }, { 2162, 0x0000 }, { 2162, 0x2000 }, { 2163, 0x4400 }, + { 2165, 0x0228 }, { 2168, 0x0000 }, { 2168, 0x0020 }, { 2169, 0x2000 }, + { 2170, 0x0008 }, { 2171, 0x0002 }, { 2172, 0x0000 }, { 2172, 0x1801 }, + { 2175, 0x830c }, { 2180, 0x3c08 }, { 2185, 0x0684 }, { 2189, 0x4000 }, + /* 0x7b00 */ + { 2190, 0x1800 }, { 2192, 0x8010 }, { 2194, 0x0280 }, { 2196, 0x0200 }, + { 2197, 0x000c }, { 2199, 0x0020 }, { 2200, 0x9004 }, { 2203, 0x0800 }, + { 2204, 0x0000 }, { 2204, 0x0004 }, { 2205, 0x000c }, { 2207, 0x0004 }, + { 2208, 0x8000 }, { 2209, 0x0001 }, { 2210, 0x0000 }, { 2210, 0x1400 }, + /* 0x7c00 */ + { 2212, 0x0000 }, { 2212, 0x0824 }, { 2215, 0x0000 }, { 2215, 0x0020 }, + { 2216, 0x0014 }, { 2218, 0x2042 }, { 2221, 0x2000 }, { 2222, 0x5811 }, + { 2227, 0x4048 }, { 2230, 0x1000 }, { 2231, 0x50c0 }, { 2235, 0x0100 }, + { 2236, 0x2284 }, { 2240, 0x0408 }, { 2242, 0x2040 }, { 2244, 0x1228 }, + /* 0x7d00 */ + { 2248, 0x0000 }, { 2248, 0x0000 }, { 2248, 0x0020 }, { 2249, 0x0000 }, + { 2249, 0x2000 }, { 2250, 0x2400 }, { 2252, 0x0000 }, { 2252, 0x0000 }, + { 2252, 0x0200 }, { 2253, 0x0080 }, { 2254, 0x0910 }, { 2257, 0x0008 }, + { 2258, 0xa000 }, { 2260, 0x1019 }, { 2264, 0x0030 }, { 2266, 0x6020 }, + /* 0x7e00 */ + { 2269, 0x0080 }, { 2270, 0x0000 }, { 2270, 0x0080 }, { 2271, 0x0000 }, + { 2271, 0x0000 }, { 2271, 0x0000 }, { 2271, 0x40a0 }, { 2274, 0x8000 }, + { 2275, 0x4000 }, { 2276, 0x8004 }, { 2278, 0x1010 }, { 2280, 0x0400 }, + { 2281, 0x8080 }, { 2283, 0x8000 }, { 2284, 0x0000 }, { 2284, 0x0000 }, + /* 0x7f00 */ + { 2284, 0x0040 }, { 2285, 0x0000 }, { 2285, 0x0000 }, { 2285, 0x0080 }, + { 2286, 0x4283 }, { 2291, 0x000c }, { 2293, 0x0000 }, { 2293, 0x0102 }, + { 2295, 0x8000 }, { 2296, 0x0088 }, { 2298, 0x4008 }, { 2300, 0x0010 }, + { 2301, 0x0000 }, { 2301, 0x2000 }, { 2302, 0x0080 }, { 2303, 0x0400 }, + /* 0x8000 */ + { 2304, 0x0104 }, { 2306, 0x2000 }, { 2307, 0xc021 }, { 2311, 0x1802 }, + { 2314, 0x0000 }, { 2314, 0x0810 }, { 2316, 0x004e }, { 2320, 0x0000 }, + { 2320, 0x0001 }, { 2321, 0x8000 }, { 2322, 0x0080 }, { 2323, 0x30c0 }, + { 2327, 0x0040 }, { 2328, 0x0000 }, { 2328, 0x1200 }, { 2330, 0x0040 }, + /* 0x8100 */ + { 2331, 0x5288 }, { 2336, 0x0494 }, { 2340, 0x0400 }, { 2341, 0x0094 }, + { 2344, 0x0104 }, { 2346, 0x0640 }, { 2349, 0x2000 }, { 2350, 0x1000 }, + { 2351, 0x0010 }, { 2352, 0x0008 }, { 2353, 0x0420 }, { 2355, 0x0040 }, + { 2356, 0x0102 }, { 2358, 0x0000 }, { 2358, 0x8010 }, { 2360, 0x0040 }, + /* 0x8200 */ + { 2361, 0x0000 }, { 2361, 0x0500 }, { 2363, 0x2240 }, { 2366, 0x4000 }, + { 2367, 0x0000 }, { 2367, 0x0010 }, { 2368, 0x0024 }, { 2370, 0x0e40 }, + { 2374, 0x0080 }, { 2375, 0x0000 }, { 2375, 0x0440 }, { 2377, 0x0000 }, + { 2377, 0x8410 }, { 2380, 0x0101 }, { 2382, 0x4004 }, { 2384, 0xb080 }, + /* 0x8300 */ + { 2388, 0x0800 }, { 2389, 0x2500 }, { 2392, 0x0000 }, { 2392, 0x2000 }, + { 2393, 0x0000 }, { 2393, 0x0080 }, { 2394, 0x804c }, { 2398, 0x0000 }, + { 2398, 0x0020 }, { 2399, 0x1002 }, { 2401, 0x1000 }, { 2402, 0x4200 }, + { 2404, 0x2000 }, { 2405, 0x0008 }, { 2406, 0x2000 }, { 2407, 0x0000 }, + /* 0x8400 */ + { 2407, 0x0020 }, { 2408, 0x1150 }, { 2412, 0x4053 }, { 2417, 0x4000 }, + { 2418, 0x0500 }, { 2420, 0x1128 }, { 2424, 0x0014 }, { 2426, 0x8006 }, + { 2429, 0x0101 }, { 2431, 0x004c }, { 2434, 0x2008 }, { 2436, 0x6000 }, + { 2438, 0x0000 }, { 2438, 0x4400 }, { 2440, 0x0036 }, { 2444, 0x0100 }, + /* 0x8500 */ + { 2445, 0x0028 }, { 2447, 0x0001 }, { 2448, 0x0000 }, { 2448, 0x0118 }, + { 2451, 0x1804 }, { 2454, 0x0404 }, { 2456, 0x8000 }, { 2457, 0x0009 }, + { 2459, 0x0000 }, { 2459, 0x0000 }, { 2459, 0x0000 }, { 2459, 0x0000 }, + { 2459, 0x0002 }, { 2460, 0x0000 }, { 2460, 0x4001 }, { 2462, 0x1000 }, + /* 0x8600 */ + { 2463, 0x2004 }, { 2465, 0x0051 }, { 2468, 0x8100 }, { 2470, 0x0000 }, + { 2470, 0x0024 }, { 2472, 0x0000 }, { 2472, 0x1000 }, { 2473, 0x4004 }, + { 2475, 0x0000 }, { 2475, 0x0004 }, { 2476, 0x2001 }, { 2478, 0x0004 }, + { 2479, 0x0000 }, { 2479, 0x0000 }, { 2479, 0x8000 }, { 2480, 0x0000 }, + /* 0x8700 */ + { 2480, 0x0000 }, { 2480, 0x0000 }, { 2480, 0x0000 }, { 2480, 0x0000 }, + { 2480, 0x0000 }, { 2480, 0x0000 }, { 2480, 0x0000 }, { 2480, 0x2003 }, + { 2483, 0x1840 }, { 2486, 0x0000 }, { 2486, 0x0220 }, { 2488, 0x0002 }, + { 2489, 0x4002 }, { 2491, 0x0440 }, { 2493, 0x4000 }, { 2494, 0x0020 }, + /* 0x8800 */ + { 2495, 0x8010 }, { 2497, 0x0100 }, { 2498, 0x2080 }, { 2500, 0x0000 }, + { 2500, 0x8064 }, { 2504, 0x4000 }, { 2505, 0x4031 }, { 2509, 0x0000 }, + { 2509, 0x0090 }, { 2511, 0x1000 }, { 2512, 0x4001 }, { 2514, 0x8030 }, + { 2517, 0x80a0 }, { 2520, 0x0000 }, { 2520, 0x0040 }, { 2521, 0x8020 }, + /* 0x8900 */ + { 2523, 0x0001 }, { 2524, 0x0000 }, { 2524, 0x0010 }, { 2525, 0x0000 }, + { 2525, 0x2088 }, { 2528, 0x0010 }, { 2529, 0x0020 }, { 2530, 0x0080 }, + { 2531, 0x0681 }, { 2535, 0x0012 }, { 2537, 0x02a0 }, { 2540, 0x1000 }, + { 2541, 0x0042 }, { 2543, 0x0000 }, { 2543, 0x0080 }, { 2544, 0x0000 }, + /* 0x8a00 */ + { 2544, 0x0000 }, { 2544, 0x1000 }, { 2545, 0x0a00 }, { 2547, 0x2100 }, + { 2549, 0x0200 }, { 2550, 0x0000 }, { 2550, 0x0080 }, { 2551, 0x4000 }, + { 2552, 0x0000 }, { 2552, 0x1011 }, { 2555, 0x8200 }, { 2557, 0x0010 }, + { 2558, 0x0000 }, { 2558, 0x0400 }, { 2559, 0x0400 }, { 2560, 0x0000 }, + /* 0x8b00 */ + { 2560, 0x1000 }, { 2561, 0x8000 }, { 2562, 0x2000 }, { 2563, 0x8000 }, + { 2564, 0x3008 }, { 2567, 0x4000 }, { 2568, 0x0204 }, { 2570, 0x0000 }, + { 2570, 0x0002 }, { 2571, 0x0801 }, { 2573, 0x0001 }, { 2574, 0x4000 }, + { 2575, 0x0000 }, { 2575, 0x0000 }, { 2575, 0x0004 }, { 2576, 0x0000 }, + /* 0x8c00 */ + { 2576, 0x0000 }, { 2576, 0x0000 }, { 2576, 0x0000 }, { 2576, 0x0000 }, + { 2576, 0x0000 }, { 2576, 0x0002 }, { 2577, 0x0000 }, { 2577, 0x0000 }, + { 2577, 0x0000 }, { 2577, 0x8800 }, { 2579, 0x2000 }, { 2580, 0x0000 }, + { 2580, 0x2000 }, { 2581, 0x0850 }, { 2584, 0x0a00 }, { 2586, 0x0084 }, + /* 0x8d00 */ + { 2588, 0x1808 }, { 2591, 0x3106 }, { 2596, 0x0000 }, { 2596, 0x0000 }, + { 2596, 0x0000 }, { 2596, 0x0000 }, { 2596, 0x0000 }, { 2596, 0x0400 }, + { 2597, 0x0004 }, { 2598, 0x0000 }, { 2598, 0x0240 }, { 2600, 0x0000 }, + { 2600, 0x0009 }, { 2602, 0x0010 }, { 2603, 0x0000 }, { 2603, 0x0000 }, + /* 0x8e00 */ + { 2603, 0x4002 }, { 2605, 0x0000 }, { 2605, 0x2500 }, { 2608, 0x0400 }, + { 2609, 0x8040 }, { 2611, 0x0000 }, { 2611, 0x0100 }, { 2612, 0x40a2 }, + { 2616, 0x0001 }, { 2617, 0x0000 }, { 2617, 0x2080 }, { 2619, 0x1041 }, + { 2622, 0x4008 }, { 2624, 0x0400 }, { 2625, 0x2014 }, { 2628, 0x0004 }, + /* 0x8f00 */ + { 2629, 0x0000 }, { 2629, 0x0200 }, { 2630, 0x2000 }, { 2631, 0x0001 }, + { 2632, 0x0402 }, { 2634, 0x1000 }, { 2635, 0x40c0 }, { 2638, 0x0000 }, + { 2638, 0x0000 }, { 2638, 0x0008 }, { 2639, 0x0021 }, { 2641, 0x5fe8 }, + { 2651, 0x1402 }, { 2654, 0x0401 }, { 2656, 0x0000 }, { 2656, 0x0200 }, + /* 0x9000 */ + { 2657, 0x0100 }, { 2658, 0x0004 }, { 2659, 0x0000 }, { 2659, 0x0088 }, + { 2661, 0x1000 }, { 2662, 0x0040 }, { 2663, 0x1012 }, { 2666, 0x0000 }, + { 2666, 0x0000 }, { 2666, 0x0000 }, { 2666, 0x4100 }, { 2668, 0x0800 }, + { 2669, 0x0010 }, { 2670, 0x0000 }, { 2670, 0x0000 }, { 2670, 0x0000 }, + /* 0x9100 */ + { 2670, 0x0000 }, { 2670, 0x0000 }, { 2670, 0x0000 }, { 2670, 0x0000 }, + { 2670, 0x0000 }, { 2670, 0x5202 }, { 2674, 0x0080 }, { 2675, 0x1041 }, + { 2678, 0x5000 }, { 2680, 0x0000 }, { 2680, 0x0200 }, { 2681, 0x0840 }, + { 2683, 0x0010 }, { 2684, 0x8040 }, { 2686, 0x0020 }, { 2687, 0x4400 }, + /* 0x9200 */ + { 2689, 0x4100 }, { 2691, 0x0008 }, { 2692, 0x0d00 }, { 2695, 0x1020 }, + { 2697, 0x0012 }, { 2699, 0xa120 }, { 2703, 0x4804 }, { 2706, 0x0080 }, + { 2707, 0x8212 }, { 2711, 0x0000 }, { 2711, 0x4000 }, { 2712, 0xc602 }, + { 2717, 0x0000 }, { 2717, 0x0810 }, { 2719, 0x1828 }, { 2723, 0x205c }, + /* 0x9300 */ + { 2728, 0x0088 }, { 2730, 0x0000 }, { 2730, 0x1000 }, { 2731, 0x0003 }, + { 2733, 0x013f }, { 2740, 0x8000 }, { 2741, 0x4b44 }, { 2747, 0x2118 }, + { 2751, 0x00f2 }, { 2756, 0x1001 }, { 2758, 0x2001 }, { 2760, 0xa900 }, + { 2764, 0x0840 }, { 2766, 0x0808 }, { 2768, 0x0001 }, { 2769, 0x000b }, + /* 0x9400 */ + { 2772, 0x0112 }, { 2775, 0x2880 }, { 2778, 0x20f0 }, { 2783, 0x4000 }, + { 2784, 0x200c }, { 2787, 0x0910 }, { 2790, 0x10a0 }, { 2793, 0x0a00 }, + { 2795, 0x0020 }, { 2796, 0x8000 }, { 2797, 0x0004 }, { 2798, 0x0000 }, + { 2798, 0x000a }, { 2800, 0x1000 }, { 2801, 0x0000 }, { 2801, 0x0040 }, + /* 0x9500 */ + { 2802, 0x0000 }, { 2802, 0x0000 }, { 2802, 0x2000 }, { 2803, 0x0000 }, + { 2803, 0x0080 }, { 2804, 0x0000 }, { 2804, 0x0000 }, { 2804, 0x8100 }, + { 2806, 0x0020 }, { 2807, 0x02c0 }, { 2810, 0x04c5 }, { 2815, 0x0000 }, + { 2815, 0x0000 }, { 2815, 0x0000 }, { 2815, 0x0100 }, { 2816, 0x0010 }, + /* 0x9600 */ + { 2817, 0x0000 }, { 2817, 0x2000 }, { 2818, 0x0000 }, { 2818, 0x0108 }, + { 2820, 0x0022 }, { 2822, 0x0040 }, { 2823, 0x0200 }, { 2824, 0x0800 }, + { 2825, 0x8002 }, { 2827, 0x0040 }, { 2828, 0x0028 }, { 2830, 0x2040 }, + { 2832, 0x0000 }, { 2832, 0x0000 }, { 2832, 0x0000 }, { 2832, 0x0010 }, + /* 0x9700 */ + { 2833, 0x0008 }, { 2834, 0x0800 }, { 2835, 0x0002 }, { 2836, 0x0042 }, + { 2838, 0x0003 }, { 2840, 0xa082 }, { 2844, 0x2000 }, { 2845, 0x0002 }, + { 2846, 0x0280 }, { 2848, 0x8800 }, { 2850, 0x0000 }, { 2850, 0x6516 }, + { 2857, 0x0105 }, { 2860, 0x0004 }, { 2861, 0x4041 }, { 2864, 0x0024 }, + /* 0x9800 */ + { 2866, 0x0000 }, { 2866, 0x8030 }, { 2869, 0x4008 }, { 2871, 0x0018 }, + { 2873, 0x0880 }, { 2875, 0x0000 }, { 2875, 0x1040 }, { 2877, 0x0020 }, + { 2878, 0x0000 }, { 2878, 0x0000 }, { 2878, 0x0000 }, { 2878, 0x0290 }, + { 2881, 0x4588 }, { 2886, 0x5000 }, { 2888, 0x1043 }, { 2892, 0x0022 }, + /* 0x9900 */ + { 2894, 0x4000 }, { 2895, 0x1200 }, { 2897, 0x0000 }, { 2897, 0x0b80 }, + { 2901, 0x2405 }, { 2905, 0x2000 }, { 2906, 0x000c }, { 2908, 0x0000 }, + { 2908, 0x0000 }, { 2908, 0x0800 }, { 2909, 0x0410 }, { 2911, 0x1100 }, + { 2913, 0x0030 }, { 2915, 0x0400 }, { 2916, 0x0042 }, { 2918, 0x0020 }, + /* 0x9a00 */ + { 2919, 0x1000 }, { 2920, 0x8001 }, { 2922, 0x8042 }, { 2925, 0x1800 }, + { 2927, 0x0000 }, { 2927, 0x1100 }, { 2929, 0x1008 }, { 2931, 0x0000 }, + { 2931, 0x8000 }, { 2932, 0x0000 }, { 2932, 0x0000 }, { 2932, 0x2444 }, + { 2936, 0x0000 }, { 2936, 0x0080 }, { 2937, 0x0005 }, { 2939, 0x8010 }, + /* 0x9b00 */ + { 2941, 0x8204 }, { 2944, 0x0010 }, { 2945, 0x2400 }, { 2947, 0x0210 }, + { 2949, 0x0001 }, { 2950, 0x0001 }, { 2951, 0x0200 }, { 2952, 0x8000 }, + { 2953, 0xe80a }, { 2959, 0xa080 }, { 2962, 0x0000 }, { 2962, 0x0001 }, + { 2963, 0x8000 }, { 2964, 0x2000 }, { 2965, 0x2200 }, { 2967, 0x8012 }, + /* 0x9c00 */ + { 2970, 0x1404 }, { 2973, 0x8821 }, { 2977, 0x8041 }, { 2980, 0x0420 }, + { 2982, 0x8020 }, { 2984, 0x2008 }, { 2986, 0x0000 }, { 2986, 0x1804 }, + { 2989, 0x0000 }, { 2989, 0x0000 }, { 2989, 0x0000 }, { 2989, 0x0000 }, + { 2989, 0x0000 }, { 2989, 0x0000 }, { 2989, 0x0000 }, { 2989, 0x0000 }, + /* 0x9d00 */ + { 2989, 0x1004 }, { 2991, 0x0040 }, { 2992, 0x0002 }, { 2993, 0x0210 }, + { 2995, 0x4210 }, { 2998, 0x4001 }, { 3000, 0x6000 }, { 3002, 0x5000 }, + { 3004, 0x0008 }, { 3005, 0x0008 }, { 3006, 0x0820 }, { 3008, 0x2000 }, + { 3009, 0x0211 }, { 3012, 0x0010 }, { 3013, 0x0000 }, { 3013, 0x1000 }, + /* 0x9e00 */ + { 3014, 0x5400 }, { 3017, 0x9100 }, { 3020, 0x0000 }, { 3020, 0x0000 }, + { 3020, 0x0000 }, { 3020, 0x0000 }, { 3020, 0x0000 }, { 3020, 0x0800 }, + { 3021, 0x0032 }, { 3024, 0x4161 }, { 3029, 0x9d44 }, { 3036, 0xa002 }, + { 3039, 0x00d2 }, { 3043, 0x0000 }, { 3043, 0x0004 }, { 3044, 0x4102 }, + /* 0x9f00 */ + { 3047, 0x0104 }, { 3049, 0x0080 }, { 3050, 0x00c0 }, { 3052, 0x0200 }, + { 3053, 0x0030 }, { 3055, 0x0409 }, { 3058, 0x0204 }, { 3060, 0x8000 }, + { 3061, 0x4000 }, { 3062, 0x8200 }, { 3064, 0x0020 }, { 3065, 0x0003 }, +}; +static const Summary16 hkscs1999_uni2indx_pagef9[1] = { + /* 0xf900 */ + { 3067, 0x0080 }, +}; +static const Summary16 hkscs1999_uni2indx_pageff[15] = { + /* 0xff00 */ + { 3068, 0x0084 }, { 3070, 0x0000 }, { 3070, 0x0000 }, { 3070, 0x2800 }, + { 3072, 0x0000 }, { 3072, 0x0000 }, { 3072, 0x0000 }, { 3072, 0x0000 }, + { 3072, 0x0000 }, { 3072, 0x0000 }, { 3072, 0x0000 }, { 3072, 0x0000 }, + { 3072, 0x0000 }, { 3072, 0x0000 }, { 3072, 0x2014 }, +}; +static const Summary16 hkscs1999_uni2indx_page200[2335] = { + /* 0x20000 */ + { 3075, 0x0000 }, { 3075, 0x0000 }, { 3075, 0x0002 }, { 3076, 0x4000 }, + { 3077, 0x4040 }, { 3079, 0x0000 }, { 3079, 0x0100 }, { 3080, 0x0000 }, + { 3080, 0x04c0 }, { 3083, 0x0010 }, { 3084, 0x0000 }, { 3084, 0x0000 }, + { 3084, 0x3c00 }, { 3088, 0x0002 }, { 3089, 0x4000 }, { 3090, 0x0000 }, + /* 0x20100 */ + { 3090, 0x5000 }, { 3092, 0x0100 }, { 3093, 0x0000 }, { 3093, 0x0000 }, + { 3093, 0x0000 }, { 3093, 0x0000 }, { 3093, 0x0000 }, { 3093, 0x0000 }, + { 3093, 0x0000 }, { 3093, 0x0000 }, { 3093, 0x0a00 }, { 3095, 0x0000 }, + { 3095, 0x0002 }, { 3096, 0x0010 }, { 3097, 0x0000 }, { 3097, 0x0004 }, + /* 0x20200 */ + { 3098, 0x1010 }, { 3100, 0x0010 }, { 3101, 0x0000 }, { 3101, 0x0000 }, + { 3101, 0x0000 }, { 3101, 0x0800 }, { 3102, 0x0000 }, { 3102, 0x0030 }, + { 3104, 0x0000 }, { 3104, 0x4200 }, { 3106, 0x0001 }, { 3107, 0x8080 }, + { 3109, 0x0001 }, { 3110, 0x0000 }, { 3110, 0x0020 }, { 3111, 0x0000 }, + /* 0x20300 */ + { 3111, 0x0400 }, { 3112, 0x0000 }, { 3112, 0x0020 }, { 3113, 0x0000 }, + { 3113, 0x00e2 }, { 3117, 0x0000 }, { 3117, 0x0000 }, { 3117, 0xc000 }, + { 3119, 0x0001 }, { 3120, 0x0000 }, { 3120, 0x0081 }, { 3122, 0x0020 }, + { 3123, 0x0a00 }, { 3125, 0x0000 }, { 3125, 0x0000 }, { 3125, 0x1020 }, + /* 0x20400 */ + { 3127, 0x0000 }, { 3127, 0x8018 }, { 3130, 0x0000 }, { 3130, 0x0000 }, + { 3130, 0x0000 }, { 3130, 0x0000 }, { 3130, 0x0020 }, { 3131, 0x0000 }, + { 3131, 0x4080 }, { 3133, 0x0006 }, { 3135, 0x0008 }, { 3136, 0x0000 }, + { 3136, 0x0000 }, { 3136, 0x0080 }, { 3137, 0x0000 }, { 3137, 0x5000 }, + /* 0x20500 */ + { 3139, 0x0000 }, { 3139, 0x0000 }, { 3139, 0x0000 }, { 3139, 0x0000 }, + { 3139, 0x0080 }, { 3140, 0x0000 }, { 3140, 0x0000 }, { 3140, 0x0000 }, + { 3140, 0x4000 }, { 3141, 0x0000 }, { 3141, 0x0020 }, { 3142, 0x0008 }, + { 3143, 0x0408 }, { 3145, 0x8021 }, { 3148, 0x0801 }, { 3150, 0x0000 }, + /* 0x20600 */ + { 3150, 0x0000 }, { 3150, 0x0622 }, { 3154, 0x0000 }, { 3154, 0x0001 }, + { 3155, 0x0000 }, { 3155, 0x0040 }, { 3156, 0x0000 }, { 3156, 0x0040 }, + { 3157, 0x0000 }, { 3157, 0x0000 }, { 3157, 0x0000 }, { 3157, 0x0000 }, + { 3157, 0x0000 }, { 3157, 0x0000 }, { 3157, 0x0000 }, { 3157, 0x0000 }, + /* 0x20700 */ + { 3157, 0x4000 }, { 3158, 0x0000 }, { 3158, 0x0000 }, { 3158, 0x0002 }, + { 3159, 0x0000 }, { 3159, 0x0000 }, { 3159, 0x0000 }, { 3159, 0x0200 }, + { 3160, 0x0000 }, { 3160, 0x0000 }, { 3160, 0x0000 }, { 3160, 0x0000 }, + { 3160, 0x0000 }, { 3160, 0x0000 }, { 3160, 0x0000 }, { 3160, 0x0000 }, + /* 0x20800 */ + { 3160, 0x0000 }, { 3160, 0x0000 }, { 3160, 0x1000 }, { 3161, 0x0000 }, + { 3161, 0x0000 }, { 3161, 0x0000 }, { 3161, 0x0000 }, { 3161, 0x0008 }, + { 3162, 0x0000 }, { 3162, 0x0000 }, { 3162, 0x0000 }, { 3162, 0x0000 }, + { 3162, 0x0000 }, { 3162, 0x0020 }, { 3163, 0x0000 }, { 3163, 0x0000 }, + /* 0x20900 */ + { 3163, 0x0000 }, { 3163, 0x0040 }, { 3164, 0x0008 }, { 3165, 0x0000 }, + { 3165, 0x0000 }, { 3165, 0x0010 }, { 3166, 0x0000 }, { 3166, 0x0200 }, + { 3167, 0x0000 }, { 3167, 0x0000 }, { 3167, 0x0000 }, { 3167, 0x0000 }, + { 3167, 0x0000 }, { 3167, 0x0000 }, { 3167, 0x0080 }, { 3168, 0x0000 }, + /* 0x20a00 */ + { 3168, 0x0000 }, { 3168, 0x0002 }, { 3169, 0x0000 }, { 3169, 0x0000 }, + { 3169, 0x0000 }, { 3169, 0x0001 }, { 3170, 0x0000 }, { 3170, 0x0000 }, + { 3170, 0x0000 }, { 3170, 0x0000 }, { 3170, 0x0000 }, { 3170, 0x0010 }, + { 3171, 0x2004 }, { 3173, 0x0000 }, { 3173, 0x0000 }, { 3173, 0x0000 }, + /* 0x20b00 */ + { 3173, 0x2000 }, { 3174, 0x0000 }, { 3174, 0x0000 }, { 3174, 0x0000 }, + { 3174, 0x0000 }, { 3174, 0x0000 }, { 3174, 0x0000 }, { 3174, 0x0000 }, + { 3174, 0x8000 }, { 3175, 0x0000 }, { 3175, 0x0300 }, { 3177, 0x8000 }, + { 3178, 0x0840 }, { 3180, 0x0000 }, { 3180, 0x0804 }, { 3182, 0x8800 }, + /* 0x20c00 */ + { 3184, 0x2800 }, { 3186, 0x0000 }, { 3186, 0x0001 }, { 3187, 0x0c10 }, + { 3190, 0x000e }, { 3193, 0x0008 }, { 3194, 0x0020 }, { 3195, 0x1180 }, + { 3198, 0x2000 }, { 3199, 0x1040 }, { 3201, 0x0000 }, { 3201, 0x0120 }, + { 3203, 0x8000 }, { 3204, 0x2078 }, { 3209, 0x2000 }, { 3210, 0x8000 }, + /* 0x20d00 */ + { 3211, 0x0000 }, { 3211, 0x0020 }, { 3212, 0x0100 }, { 3213, 0x0006 }, + { 3215, 0x73c0 }, { 3222, 0x0000 }, { 3222, 0x8000 }, { 3223, 0xd012 }, + { 3228, 0x0000 }, { 3228, 0x1040 }, { 3230, 0x0080 }, { 3231, 0x0004 }, + { 3232, 0x0100 }, { 3233, 0x0000 }, { 3233, 0x0000 }, { 3233, 0x0000 }, + /* 0x20e00 */ + { 3233, 0xe610 }, { 3239, 0x2043 }, { 3243, 0x0000 }, { 3243, 0x0000 }, + { 3243, 0x1000 }, { 3244, 0x0000 }, { 3244, 0x2000 }, { 3245, 0x0fe8 }, + { 3253, 0x1000 }, { 3254, 0x2140 }, { 3257, 0x1c04 }, { 3261, 0x0040 }, + { 3262, 0x0000 }, { 3262, 0x2180 }, { 3265, 0x0000 }, { 3265, 0x0f00 }, + /* 0x20f00 */ + { 3269, 0x0000 }, { 3269, 0x2000 }, { 3270, 0x6040 }, { 3273, 0x0803 }, + { 3276, 0x1000 }, { 3277, 0x0000 }, { 3277, 0x0010 }, { 3278, 0x0000 }, + { 3278, 0x2000 }, { 3279, 0x0001 }, { 3280, 0x2000 }, { 3281, 0x1070 }, + { 3285, 0x0000 }, { 3285, 0x8000 }, { 3286, 0x3c00 }, { 3290, 0x0000 }, + /* 0x21000 */ + { 3290, 0x0000 }, { 3290, 0x6010 }, { 3293, 0x0000 }, { 3293, 0x0000 }, + { 3293, 0x8000 }, { 3294, 0x1000 }, { 3295, 0x8000 }, { 3296, 0x09e0 }, + { 3301, 0x0100 }, { 3302, 0x2040 }, { 3304, 0x0000 }, { 3304, 0x8010 }, + { 3306, 0x8383 }, { 3312, 0x0008 }, { 3313, 0x0010 }, { 3314, 0x0070 }, + /* 0x21100 */ + { 3317, 0x0000 }, { 3317, 0x0000 }, { 3317, 0x8000 }, { 3318, 0x2800 }, + { 3320, 0x8120 }, { 3323, 0x0000 }, { 3323, 0x0000 }, { 3323, 0x0000 }, + { 3323, 0x0081 }, { 3325, 0x0000 }, { 3325, 0x0000 }, { 3325, 0x0000 }, + { 3325, 0x0000 }, { 3325, 0x0200 }, { 3326, 0x0000 }, { 3326, 0x0000 }, + /* 0x21200 */ + { 3326, 0x0000 }, { 3326, 0x0000 }, { 3326, 0x0000 }, { 3326, 0x1000 }, + { 3327, 0x8000 }, { 3328, 0x0000 }, { 3328, 0x0000 }, { 3328, 0x1000 }, + { 3329, 0x0000 }, { 3329, 0x0000 }, { 3329, 0x0300 }, { 3331, 0x0001 }, + { 3332, 0x0000 }, { 3332, 0x0000 }, { 3332, 0x0008 }, { 3333, 0x4000 }, + /* 0x21300 */ + { 3334, 0x003c }, { 3338, 0x0000 }, { 3338, 0x0000 }, { 3338, 0x0440 }, + { 3340, 0x0000 }, { 3340, 0x0000 }, { 3340, 0x0000 }, { 3340, 0x0060 }, + { 3342, 0x4000 }, { 3343, 0x1100 }, { 3345, 0x0000 }, { 3345, 0x0000 }, + { 3345, 0x0060 }, { 3347, 0x0000 }, { 3347, 0x2000 }, { 3348, 0x4000 }, + /* 0x21400 */ + { 3349, 0x0000 }, { 3349, 0x0048 }, { 3351, 0x0010 }, { 3352, 0x0000 }, + { 3352, 0x0000 }, { 3352, 0x0034 }, { 3355, 0x0000 }, { 3355, 0x0000 }, + { 3355, 0x0400 }, { 3356, 0x0080 }, { 3357, 0x0000 }, { 3357, 0x0040 }, + { 3358, 0x0000 }, { 3358, 0x0000 }, { 3358, 0x0100 }, { 3359, 0x2000 }, + /* 0x21500 */ + { 3360, 0x0000 }, { 3360, 0x0000 }, { 3360, 0x0000 }, { 3360, 0x0000 }, + { 3360, 0x0000 }, { 3360, 0x0000 }, { 3360, 0x0000 }, { 3360, 0x0080 }, + { 3361, 0x0004 }, { 3362, 0x0040 }, { 3363, 0x0000 }, { 3363, 0x0000 }, + { 3363, 0x0000 }, { 3363, 0x0000 }, { 3363, 0x0000 }, { 3363, 0x0000 }, + /* 0x21600 */ + { 3363, 0x0400 }, { 3364, 0x0208 }, { 3366, 0x0000 }, { 3366, 0x4000 }, + { 3367, 0x0000 }, { 3367, 0x0000 }, { 3367, 0x0002 }, { 3368, 0x0000 }, + { 3368, 0x0000 }, { 3368, 0x0004 }, { 3369, 0x0000 }, { 3369, 0x0500 }, + { 3371, 0x0007 }, { 3374, 0x8028 }, { 3377, 0x01c0 }, { 3380, 0x5c00 }, + /* 0x21700 */ + { 3384, 0x2000 }, { 3385, 0x0001 }, { 3386, 0x0040 }, { 3387, 0x1c00 }, + { 3390, 0x0000 }, { 3390, 0x0080 }, { 3391, 0xf000 }, { 3395, 0x001b }, + { 3399, 0x0000 }, { 3399, 0x0000 }, { 3399, 0x0800 }, { 3400, 0x003f }, + { 3406, 0x0088 }, { 3408, 0x9e00 }, { 3413, 0x8000 }, { 3414, 0x1f60 }, + /* 0x21800 */ + { 3421, 0x0000 }, { 3421, 0x0000 }, { 3421, 0x2701 }, { 3426, 0x0e00 }, + { 3429, 0x0021 }, { 3431, 0x4004 }, { 3433, 0x001e }, { 3437, 0x0880 }, + { 3439, 0x0038 }, { 3442, 0xc000 }, { 3444, 0x0007 }, { 3447, 0xc000 }, + { 3449, 0x0000 }, { 3449, 0x03c2 }, { 3454, 0x0000 }, { 3454, 0x0400 }, + /* 0x21900 */ + { 3455, 0x0038 }, { 3458, 0x1027 }, { 3463, 0x0084 }, { 3465, 0x0800 }, + { 3466, 0x0010 }, { 3467, 0x0100 }, { 3468, 0x0400 }, { 3469, 0x1000 }, + { 3470, 0x0108 }, { 3472, 0x0040 }, { 3473, 0x0000 }, { 3473, 0x0000 }, + { 3473, 0x0000 }, { 3473, 0x0800 }, { 3474, 0x0000 }, { 3474, 0x0008 }, + /* 0x21a00 */ + { 3475, 0x0000 }, { 3475, 0x0000 }, { 3475, 0x2000 }, { 3476, 0x0010 }, + { 3477, 0x0820 }, { 3479, 0x0000 }, { 3479, 0x0000 }, { 3479, 0x0000 }, + { 3479, 0x0000 }, { 3479, 0x0000 }, { 3479, 0x0000 }, { 3479, 0x0000 }, + { 3479, 0x0000 }, { 3479, 0x0000 }, { 3479, 0x0000 }, { 3479, 0x0000 }, + /* 0x21b00 */ + { 3479, 0x0000 }, { 3479, 0x0000 }, { 3479, 0x0000 }, { 3479, 0x0000 }, + { 3479, 0x0010 }, { 3480, 0x0000 }, { 3480, 0x0000 }, { 3480, 0x0000 }, + { 3480, 0x0000 }, { 3480, 0x0000 }, { 3480, 0x0000 }, { 3480, 0x0000 }, + { 3480, 0x0006 }, { 3482, 0x0000 }, { 3482, 0x0000 }, { 3482, 0x0000 }, + /* 0x21c00 */ + { 3482, 0x0000 }, { 3482, 0x0000 }, { 3482, 0x0400 }, { 3483, 0x0000 }, + { 3483, 0x0000 }, { 3483, 0x0000 }, { 3483, 0x0000 }, { 3483, 0x0001 }, + { 3484, 0x0000 }, { 3484, 0x0000 }, { 3484, 0x1024 }, { 3487, 0x0000 }, + { 3487, 0x0000 }, { 3487, 0x0000 }, { 3487, 0x0000 }, { 3487, 0x0000 }, + /* 0x21d00 */ + { 3487, 0x0000 }, { 3487, 0x0000 }, { 3487, 0x0000 }, { 3487, 0x0000 }, + { 3487, 0x0040 }, { 3488, 0x0000 }, { 3488, 0x0000 }, { 3488, 0x0000 }, + { 3488, 0x0000 }, { 3488, 0x0001 }, { 3489, 0x0000 }, { 3489, 0x0400 }, + { 3490, 0x0400 }, { 3491, 0x0002 }, { 3492, 0x0800 }, { 3493, 0x0200 }, + /* 0x21e00 */ + { 3494, 0x0000 }, { 3494, 0x1000 }, { 3495, 0x0000 }, { 3495, 0x2080 }, + { 3497, 0x0000 }, { 3497, 0x0000 }, { 3497, 0x0000 }, { 3497, 0x0000 }, + { 3497, 0x0200 }, { 3498, 0x0000 }, { 3498, 0x0110 }, { 3500, 0x0000 }, + { 3500, 0x0100 }, { 3501, 0x0020 }, { 3502, 0x0000 }, { 3502, 0x0000 }, + /* 0x21f00 */ + { 3502, 0x8000 }, { 3503, 0x0020 }, { 3504, 0x0000 }, { 3504, 0x0000 }, + { 3504, 0x0000 }, { 3504, 0x0000 }, { 3504, 0x0400 }, { 3505, 0x0000 }, + { 3505, 0x0000 }, { 3505, 0x4000 }, { 3506, 0x0002 }, { 3507, 0x0000 }, + { 3507, 0x0000 }, { 3507, 0x0000 }, { 3507, 0x0100 }, { 3508, 0x0000 }, + /* 0x22000 */ + { 3508, 0x0000 }, { 3508, 0x0000 }, { 3508, 0x0000 }, { 3508, 0x0000 }, + { 3508, 0x0220 }, { 3510, 0x0000 }, { 3510, 0x0000 }, { 3510, 0x0000 }, + { 3510, 0x0000 }, { 3510, 0x0400 }, { 3511, 0x0000 }, { 3511, 0x0000 }, + { 3511, 0x0080 }, { 3512, 0x0000 }, { 3512, 0x0000 }, { 3512, 0x1000 }, + /* 0x22100 */ + { 3513, 0x0000 }, { 3513, 0x0000 }, { 3513, 0x0400 }, { 3514, 0x0000 }, + { 3514, 0x0000 }, { 3514, 0x0800 }, { 3515, 0x0000 }, { 3515, 0x0408 }, + { 3517, 0x0000 }, { 3517, 0x0000 }, { 3517, 0x0002 }, { 3518, 0x0000 }, + { 3518, 0x0008 }, { 3519, 0x0000 }, { 3519, 0x0000 }, { 3519, 0x0000 }, + /* 0x22200 */ + { 3519, 0x0100 }, { 3520, 0x0000 }, { 3520, 0x0000 }, { 3520, 0x0000 }, + { 3520, 0x0000 }, { 3520, 0x0000 }, { 3520, 0x0000 }, { 3520, 0x1000 }, + { 3521, 0x0000 }, { 3521, 0x0000 }, { 3521, 0x0000 }, { 3521, 0x0000 }, + { 3521, 0x0000 }, { 3521, 0x0000 }, { 3521, 0x0000 }, { 3521, 0x0000 }, + /* 0x22300 */ + { 3521, 0x0000 }, { 3521, 0x0000 }, { 3521, 0x0022 }, { 3523, 0x0000 }, + { 3523, 0x0000 }, { 3523, 0x0000 }, { 3523, 0x0000 }, { 3523, 0x0000 }, + { 3523, 0x0000 }, { 3523, 0x0000 }, { 3523, 0x0000 }, { 3523, 0x2000 }, + { 3524, 0x0000 }, { 3524, 0x0081 }, { 3526, 0x0000 }, { 3526, 0x0400 }, + /* 0x22400 */ + { 3527, 0x0000 }, { 3527, 0x0000 }, { 3527, 0x0000 }, { 3527, 0x0000 }, + { 3527, 0x0000 }, { 3527, 0x0000 }, { 3527, 0x0020 }, { 3528, 0x0002 }, + { 3529, 0x0800 }, { 3530, 0x0002 }, { 3531, 0x0000 }, { 3531, 0x0001 }, + { 3532, 0x0000 }, { 3532, 0x0000 }, { 3532, 0x2000 }, { 3533, 0x0000 }, + /* 0x22500 */ + { 3533, 0x0000 }, { 3533, 0x0808 }, { 3535, 0x0000 }, { 3535, 0x0001 }, + { 3536, 0x0000 }, { 3536, 0x0010 }, { 3537, 0x0000 }, { 3537, 0x0000 }, + { 3537, 0x2000 }, { 3538, 0x0000 }, { 3538, 0x8000 }, { 3539, 0x4000 }, + { 3540, 0x0000 }, { 3540, 0x0000 }, { 3540, 0x0000 }, { 3540, 0x0000 }, + /* 0x22600 */ + { 3540, 0x0000 }, { 3540, 0x1800 }, { 3542, 0x0800 }, { 3543, 0x0000 }, + { 3543, 0x0000 }, { 3543, 0x0000 }, { 3543, 0x0100 }, { 3544, 0x0400 }, + { 3545, 0x0000 }, { 3545, 0x0140 }, { 3547, 0x0000 }, { 3547, 0x0000 }, + { 3547, 0x0000 }, { 3547, 0x0000 }, { 3547, 0x0000 }, { 3547, 0x0070 }, + /* 0x22700 */ + { 3550, 0x0000 }, { 3550, 0x8810 }, { 3553, 0x0400 }, { 3554, 0x0000 }, + { 3554, 0x0000 }, { 3554, 0x0000 }, { 3554, 0x0000 }, { 3554, 0x0020 }, + { 3555, 0x0002 }, { 3556, 0x0000 }, { 3556, 0x0000 }, { 3556, 0x0030 }, + { 3558, 0x2000 }, { 3559, 0x0000 }, { 3559, 0x0000 }, { 3559, 0x0000 }, + /* 0x22800 */ + { 3559, 0x0008 }, { 3560, 0x0000 }, { 3560, 0x0000 }, { 3560, 0x0000 }, + { 3560, 0x0000 }, { 3560, 0x8000 }, { 3561, 0x0001 }, { 3562, 0x0002 }, + { 3563, 0x0000 }, { 3563, 0x0000 }, { 3563, 0x2000 }, { 3564, 0x0000 }, + { 3564, 0x0002 }, { 3565, 0x0000 }, { 3565, 0x0000 }, { 3565, 0x0080 }, + /* 0x22900 */ + { 3566, 0x0000 }, { 3566, 0x0000 }, { 3566, 0x0040 }, { 3567, 0x0200 }, + { 3568, 0x8000 }, { 3569, 0x0000 }, { 3569, 0x0880 }, { 3571, 0x0000 }, + { 3571, 0x0001 }, { 3572, 0x0008 }, { 3573, 0x0000 }, { 3573, 0x0000 }, + { 3573, 0x0000 }, { 3573, 0x0000 }, { 3573, 0x0000 }, { 3573, 0x0000 }, + /* 0x22a00 */ + { 3573, 0x0000 }, { 3573, 0x0000 }, { 3573, 0x0000 }, { 3573, 0x0000 }, + { 3573, 0x0000 }, { 3573, 0x0000 }, { 3573, 0x0040 }, { 3574, 0x0000 }, + { 3574, 0x0000 }, { 3574, 0x0000 }, { 3574, 0x0000 }, { 3574, 0x0000 }, + { 3574, 0x8000 }, { 3575, 0x0020 }, { 3576, 0x0140 }, { 3578, 0x0000 }, + /* 0x22b00 */ + { 3578, 0x4000 }, { 3579, 0x0000 }, { 3579, 0x0004 }, { 3580, 0x8000 }, + { 3581, 0x0008 }, { 3582, 0x0000 }, { 3582, 0x0400 }, { 3583, 0x0000 }, + { 3583, 0x0000 }, { 3583, 0x0000 }, { 3583, 0x0000 }, { 3583, 0x0000 }, + { 3583, 0x4400 }, { 3585, 0x0000 }, { 3585, 0x0000 }, { 3585, 0x0000 }, + /* 0x22c00 */ + { 3585, 0x0000 }, { 3585, 0x0000 }, { 3585, 0x00c0 }, { 3587, 0x0100 }, + { 3588, 0x1000 }, { 3589, 0x0022 }, { 3591, 0x0004 }, { 3592, 0x0000 }, + { 3592, 0x0100 }, { 3593, 0x0800 }, { 3594, 0x0202 }, { 3596, 0x0084 }, + { 3598, 0x0244 }, { 3601, 0x0000 }, { 3601, 0x0000 }, { 3601, 0x0000 }, + /* 0x22d00 */ + { 3601, 0x0180 }, { 3603, 0x0004 }, { 3604, 0x0000 }, { 3604, 0x0000 }, + { 3604, 0x1010 }, { 3606, 0x0000 }, { 3606, 0x0080 }, { 3607, 0x0000 }, + { 3607, 0x2000 }, { 3608, 0x0020 }, { 3609, 0x0019 }, { 3612, 0x0080 }, + { 3613, 0x0000 }, { 3613, 0x0000 }, { 3613, 0x4000 }, { 3614, 0x0000 }, + /* 0x22e00 */ + { 3614, 0x2000 }, { 3615, 0x0000 }, { 3615, 0x0000 }, { 3615, 0x0040 }, + { 3616, 0x0004 }, { 3617, 0x0000 }, { 3617, 0x0000 }, { 3617, 0x0100 }, + { 3618, 0x0800 }, { 3619, 0x0000 }, { 3619, 0x0000 }, { 3619, 0x0008 }, + { 3620, 0x0000 }, { 3620, 0x0000 }, { 3620, 0x8000 }, { 3621, 0x0000 }, + /* 0x22f00 */ + { 3621, 0x0000 }, { 3621, 0x0000 }, { 3621, 0x0000 }, { 3621, 0x0000 }, + { 3621, 0x0000 }, { 3621, 0x0000 }, { 3621, 0x0000 }, { 3621, 0x0010 }, + { 3622, 0x0000 }, { 3622, 0x0000 }, { 3622, 0x0000 }, { 3622, 0x0000 }, + { 3622, 0x1000 }, { 3623, 0x0000 }, { 3623, 0x0008 }, { 3624, 0x0000 }, + /* 0x23000 */ + { 3624, 0x0000 }, { 3624, 0x0000 }, { 3624, 0x0000 }, { 3624, 0x0008 }, + { 3625, 0x0810 }, { 3627, 0x0000 }, { 3627, 0x0040 }, { 3628, 0x6000 }, + { 3630, 0x4000 }, { 3631, 0x0000 }, { 3631, 0x0000 }, { 3631, 0x1080 }, + { 3633, 0x0000 }, { 3633, 0x0400 }, { 3634, 0x0000 }, { 3634, 0x0000 }, + /* 0x23100 */ + { 3634, 0x0008 }, { 3635, 0x0000 }, { 3635, 0x0000 }, { 3635, 0x2000 }, + { 3636, 0x0000 }, { 3636, 0x0000 }, { 3636, 0x0000 }, { 3636, 0x2000 }, + { 3637, 0x0004 }, { 3638, 0x0000 }, { 3638, 0x0030 }, { 3640, 0x0008 }, + { 3641, 0x0300 }, { 3643, 0x0000 }, { 3643, 0x0000 }, { 3643, 0x0380 }, + /* 0x23200 */ + { 3646, 0x8000 }, { 3647, 0x0000 }, { 3647, 0x8020 }, { 3649, 0x001e }, + { 3653, 0x0000 }, { 3653, 0x0000 }, { 3653, 0x0004 }, { 3654, 0x0000 }, + { 3654, 0x0600 }, { 3656, 0x0000 }, { 3656, 0x3800 }, { 3659, 0x0000 }, + { 3659, 0x0000 }, { 3659, 0x0004 }, { 3660, 0x0003 }, { 3662, 0x0000 }, + /* 0x23300 */ + { 3662, 0x0401 }, { 3664, 0x8000 }, { 3665, 0x0000 }, { 3665, 0x0000 }, + { 3665, 0x0000 }, { 3665, 0x0000 }, { 3665, 0x0000 }, { 3665, 0x0000 }, + { 3665, 0x0000 }, { 3665, 0x0000 }, { 3665, 0x0000 }, { 3665, 0x0010 }, + { 3666, 0x1000 }, { 3667, 0x4000 }, { 3668, 0x0040 }, { 3669, 0x4430 }, + /* 0x23400 */ + { 3673, 0x0001 }, { 3674, 0x0000 }, { 3674, 0x0000 }, { 3674, 0x8000 }, + { 3675, 0x0000 }, { 3675, 0x0001 }, { 3676, 0x8000 }, { 3677, 0x0004 }, + { 3678, 0x0000 }, { 3678, 0x0000 }, { 3678, 0x0000 }, { 3678, 0x0000 }, + { 3678, 0x0000 }, { 3678, 0x0000 }, { 3678, 0x0020 }, { 3679, 0x0000 }, + /* 0x23500 */ + { 3679, 0x0000 }, { 3679, 0x0200 }, { 3680, 0x0000 }, { 3680, 0x0001 }, + { 3681, 0x0000 }, { 3681, 0x0400 }, { 3682, 0x0080 }, { 3683, 0x0000 }, + { 3683, 0x0000 }, { 3683, 0x1220 }, { 3686, 0x0000 }, { 3686, 0x0000 }, + { 3686, 0xe000 }, { 3689, 0x0000 }, { 3689, 0x0000 }, { 3689, 0x0008 }, + /* 0x23600 */ + { 3690, 0x0001 }, { 3691, 0x0400 }, { 3692, 0x0000 }, { 3692, 0x1000 }, + { 3693, 0x0001 }, { 3694, 0x8200 }, { 3696, 0x0000 }, { 3696, 0x0080 }, + { 3697, 0x0000 }, { 3697, 0x0000 }, { 3697, 0x2040 }, { 3699, 0x0400 }, + { 3700, 0x0000 }, { 3700, 0x8000 }, { 3701, 0x4000 }, { 3702, 0x0000 }, + /* 0x23700 */ + { 3702, 0x0008 }, { 3703, 0x0040 }, { 3704, 0xa001 }, { 3707, 0x8000 }, + { 3708, 0x0000 }, { 3708, 0x0000 }, { 3708, 0x0040 }, { 3709, 0x0000 }, + { 3709, 0x0002 }, { 3710, 0x0000 }, { 3710, 0x0004 }, { 3711, 0x1000 }, + { 3712, 0x0004 }, { 3713, 0x00e0 }, { 3716, 0x0000 }, { 3716, 0x0000 }, + /* 0x23800 */ + { 3716, 0x0000 }, { 3716, 0x0000 }, { 3716, 0x0000 }, { 3716, 0x0400 }, + { 3717, 0x0000 }, { 3717, 0x0000 }, { 3717, 0x0000 }, { 3717, 0x0000 }, + { 3717, 0x0000 }, { 3717, 0x0000 }, { 3717, 0x0000 }, { 3717, 0x0000 }, + { 3717, 0x0000 }, { 3717, 0x0000 }, { 3717, 0x0000 }, { 3717, 0x0000 }, + /* 0x23900 */ + { 3717, 0x0000 }, { 3717, 0x0000 }, { 3717, 0x0000 }, { 3717, 0x0000 }, + { 3717, 0x0000 }, { 3717, 0x0000 }, { 3717, 0x0000 }, { 3717, 0x0000 }, + { 3717, 0x0000 }, { 3717, 0x0000 }, { 3717, 0x0000 }, { 3717, 0x0000 }, + { 3717, 0x0004 }, { 3718, 0x0000 }, { 3718, 0x0000 }, { 3718, 0x0000 }, + /* 0x23a00 */ + { 3718, 0x0000 }, { 3718, 0x0000 }, { 3718, 0x0000 }, { 3718, 0x0000 }, + { 3718, 0x0000 }, { 3718, 0x0000 }, { 3718, 0x0000 }, { 3718, 0x0000 }, + { 3718, 0x0000 }, { 3718, 0x0000 }, { 3718, 0x0080 }, { 3719, 0x0000 }, + { 3719, 0x0000 }, { 3719, 0x0800 }, { 3720, 0x4000 }, { 3721, 0x0400 }, + /* 0x23b00 */ + { 3722, 0x0000 }, { 3722, 0x0000 }, { 3722, 0x0000 }, { 3722, 0x0000 }, + { 3722, 0x0000 }, { 3722, 0x0400 }, { 3723, 0x0000 }, { 3723, 0x0000 }, + { 3723, 0x0000 }, { 3723, 0x0000 }, { 3723, 0x0000 }, { 3723, 0x0000 }, + { 3723, 0x0000 }, { 3723, 0x0000 }, { 3723, 0x0000 }, { 3723, 0x0000 }, + /* 0x23c00 */ + { 3723, 0x0000 }, { 3723, 0x0000 }, { 3723, 0x0000 }, { 3723, 0x0000 }, + { 3723, 0x0000 }, { 3723, 0x0000 }, { 3723, 0x0000 }, { 3723, 0x0000 }, + { 3723, 0x0000 }, { 3723, 0x0e00 }, { 3726, 0x0000 }, { 3726, 0x00a0 }, + { 3728, 0x0380 }, { 3731, 0x0000 }, { 3731, 0x0000 }, { 3731, 0xf000 }, + /* 0x23d00 */ + { 3735, 0x0000 }, { 3735, 0x0000 }, { 3735, 0x0000 }, { 3735, 0x0000 }, + { 3735, 0x0001 }, { 3736, 0x0800 }, { 3737, 0x0000 }, { 3737, 0x4000 }, + { 3738, 0x8000 }, { 3739, 0x0000 }, { 3739, 0x0000 }, { 3739, 0x3fc0 }, + { 3747, 0x0000 }, { 3747, 0x0000 }, { 3747, 0x0008 }, { 3748, 0x0100 }, + /* 0x23e00 */ + { 3749, 0x0000 }, { 3749, 0x0002 }, { 3750, 0xf000 }, { 3754, 0x0203 }, + { 3757, 0x0000 }, { 3757, 0x0000 }, { 3757, 0x0000 }, { 3757, 0x0000 }, + { 3757, 0x0f00 }, { 3761, 0x0000 }, { 3761, 0x0000 }, { 3761, 0x8200 }, + { 3763, 0x0000 }, { 3763, 0x0080 }, { 3764, 0x0000 }, { 3764, 0x1f80 }, + /* 0x23f00 */ + { 3770, 0x0000 }, { 3770, 0x0000 }, { 3770, 0x0000 }, { 3770, 0x0020 }, + { 3771, 0x0402 }, { 3773, 0x0000 }, { 3773, 0x0000 }, { 3773, 0x8000 }, + { 3774, 0x8007 }, { 3778, 0x0000 }, { 3778, 0x0000 }, { 3778, 0x0090 }, + { 3780, 0x0021 }, { 3782, 0x0000 }, { 3782, 0xf800 }, { 3787, 0x0001 }, + /* 0x24000 */ + { 3788, 0x0000 }, { 3788, 0x0002 }, { 3789, 0x0000 }, { 3789, 0x3e00 }, + { 3794, 0x0000 }, { 3794, 0x0080 }, { 3795, 0x0000 }, { 3795, 0x0000 }, + { 3795, 0x3820 }, { 3799, 0x0002 }, { 3800, 0x0000 }, { 3800, 0x0000 }, + { 3800, 0x0200 }, { 3801, 0x0000 }, { 3801, 0x0002 }, { 3802, 0x0000 }, + /* 0x24100 */ + { 3802, 0x8010 }, { 3804, 0x0200 }, { 3805, 0x0000 }, { 3805, 0x8000 }, + { 3806, 0x0011 }, { 3808, 0x90e0 }, { 3813, 0x0000 }, { 3813, 0x0480 }, + { 3815, 0x0000 }, { 3815, 0x0000 }, { 3815, 0x1038 }, { 3819, 0x0020 }, + { 3820, 0x2000 }, { 3821, 0x0000 }, { 3821, 0x0004 }, { 3822, 0x1000 }, + /* 0x24200 */ + { 3823, 0x0000 }, { 3823, 0x0800 }, { 3824, 0x0000 }, { 3824, 0x0000 }, + { 3824, 0x0800 }, { 3825, 0x0240 }, { 3827, 0x0000 }, { 3827, 0x01c0 }, + { 3830, 0x0010 }, { 3831, 0x0028 }, { 3833, 0x0020 }, { 3834, 0x0000 }, + { 3834, 0x0602 }, { 3837, 0x0000 }, { 3837, 0x4000 }, { 3838, 0x0400 }, + /* 0x24300 */ + { 3839, 0x2000 }, { 3840, 0x0400 }, { 3841, 0x0000 }, { 3841, 0x0010 }, + { 3842, 0x0100 }, { 3843, 0x0000 }, { 3843, 0x003c }, { 3847, 0x0000 }, + { 3847, 0x1000 }, { 3848, 0x1040 }, { 3850, 0x0000 }, { 3850, 0x2000 }, + { 3851, 0x0002 }, { 3852, 0x0000 }, { 3852, 0x0600 }, { 3854, 0x0104 }, + /* 0x24400 */ + { 3856, 0x0010 }, { 3857, 0x0000 }, { 3857, 0x0000 }, { 3857, 0x0060 }, + { 3859, 0x0000 }, { 3859, 0x0c00 }, { 3861, 0x0000 }, { 3861, 0x0008 }, + { 3862, 0x0180 }, { 3864, 0x0000 }, { 3864, 0x0000 }, { 3864, 0x1200 }, + { 3866, 0x4000 }, { 3867, 0x0048 }, { 3869, 0x0000 }, { 3869, 0x0000 }, + /* 0x24500 */ + { 3869, 0x0000 }, { 3869, 0x0000 }, { 3869, 0x0002 }, { 3870, 0x0000 }, + { 3870, 0x0000 }, { 3870, 0x0000 }, { 3870, 0x0000 }, { 3870, 0x0100 }, + { 3871, 0x0000 }, { 3871, 0x0000 }, { 3871, 0x0000 }, { 3871, 0x0000 }, + { 3871, 0x0100 }, { 3872, 0x0000 }, { 3872, 0x0000 }, { 3872, 0x0000 }, + /* 0x24600 */ + { 3872, 0x0000 }, { 3872, 0x0100 }, { 3873, 0x0400 }, { 3874, 0x0000 }, + { 3874, 0x0000 }, { 3874, 0x0000 }, { 3874, 0x0020 }, { 3875, 0x0010 }, + { 3876, 0x0000 }, { 3876, 0x0080 }, { 3877, 0x0000 }, { 3877, 0x0000 }, + { 3877, 0x0000 }, { 3877, 0x0010 }, { 3878, 0x0000 }, { 3878, 0x0000 }, + /* 0x24700 */ + { 3878, 0x0040 }, { 3879, 0x0000 }, { 3879, 0x8020 }, { 3881, 0x0000 }, + { 3881, 0x0000 }, { 3881, 0x0000 }, { 3881, 0x0000 }, { 3881, 0x0000 }, + { 3881, 0x8000 }, { 3882, 0x0000 }, { 3882, 0x0000 }, { 3882, 0x0000 }, + { 3882, 0x0000 }, { 3882, 0x0000 }, { 3882, 0x0001 }, { 3883, 0x0000 }, + /* 0x24800 */ + { 3883, 0x0000 }, { 3883, 0x0004 }, { 3884, 0x0008 }, { 3885, 0x0000 }, + { 3885, 0x0000 }, { 3885, 0x0000 }, { 3885, 0x0000 }, { 3885, 0x0000 }, + { 3885, 0x0004 }, { 3886, 0x0000 }, { 3886, 0x0000 }, { 3886, 0x0000 }, + { 3886, 0x0000 }, { 3886, 0x0000 }, { 3886, 0x0200 }, { 3887, 0x880f }, + /* 0x24900 */ + { 3893, 0x1003 }, { 3896, 0x02c0 }, { 3899, 0x8000 }, { 3900, 0xc018 }, + { 3904, 0x000f }, { 3908, 0x0000 }, { 3908, 0x000c }, { 3910, 0x8070 }, + { 3914, 0xff04 }, { 3923, 0x0010 }, { 3924, 0x3a90 }, { 3930, 0x0f80 }, + { 3935, 0x0020 }, { 3936, 0xc401 }, { 3940, 0x3028 }, { 3944, 0x0bc0 }, + /* 0x24a00 */ + { 3949, 0x4000 }, { 3950, 0x0024 }, { 3952, 0x07fe }, { 3962, 0x4000 }, + { 3963, 0xc424 }, { 3968, 0x2003 }, { 3971, 0x00e0 }, { 3974, 0x0782 }, + { 3979, 0x1000 }, { 3980, 0x0078 }, { 3984, 0x00f0 }, { 3988, 0x1c0e }, + { 3994, 0x0481 }, { 3997, 0x8002 }, { 3999, 0x0204 }, { 4001, 0x0000 }, + /* 0x24b00 */ + { 4001, 0x0000 }, { 4001, 0x0000 }, { 4001, 0x0000 }, { 4001, 0x0000 }, + { 4001, 0x0000 }, { 4001, 0x0000 }, { 4001, 0x4000 }, { 4002, 0x0000 }, + { 4002, 0x0000 }, { 4002, 0x0000 }, { 4002, 0x0000 }, { 4002, 0x0000 }, + { 4002, 0x0000 }, { 4002, 0x0000 }, { 4002, 0x0000 }, { 4002, 0x0020 }, + /* 0x24c00 */ + { 4003, 0x0200 }, { 4004, 0x0000 }, { 4004, 0x0000 }, { 4004, 0x0000 }, + { 4004, 0x0000 }, { 4004, 0x0000 }, { 4004, 0x0000 }, { 4004, 0x0000 }, + { 4004, 0x0000 }, { 4004, 0xc000 }, { 4006, 0x0000 }, { 4006, 0x0000 }, + { 4006, 0x0200 }, { 4007, 0x0200 }, { 4008, 0x0000 }, { 4008, 0x0000 }, + /* 0x24d00 */ + { 4008, 0x0040 }, { 4009, 0x0008 }, { 4010, 0x0000 }, { 4010, 0x0000 }, + { 4010, 0x0000 }, { 4010, 0x0000 }, { 4010, 0x0000 }, { 4010, 0x0000 }, + { 4010, 0x0000 }, { 4010, 0x0000 }, { 4010, 0x0000 }, { 4010, 0x0100 }, + { 4011, 0x0000 }, { 4011, 0x0000 }, { 4011, 0x0c00 }, { 4013, 0x0000 }, + /* 0x24e00 */ + { 4013, 0x0000 }, { 4013, 0x0000 }, { 4013, 0x0000 }, { 4013, 0x0800 }, + { 4014, 0x0000 }, { 4014, 0x0001 }, { 4015, 0x0000 }, { 4015, 0x0000 }, + { 4015, 0x0000 }, { 4015, 0x0000 }, { 4015, 0x00a0 }, { 4017, 0x0000 }, + { 4017, 0x0000 }, { 4017, 0x0000 }, { 4017, 0x0000 }, { 4017, 0x0000 }, + /* 0x24f00 */ + { 4017, 0x4000 }, { 4018, 0x0000 }, { 4018, 0x0000 }, { 4018, 0x0000 }, + { 4018, 0x0000 }, { 4018, 0x1000 }, { 4019, 0x0000 }, { 4019, 0x0000 }, + { 4019, 0x0044 }, { 4021, 0x0480 }, { 4023, 0x0200 }, { 4024, 0x0100 }, + { 4025, 0x0004 }, { 4026, 0x0000 }, { 4026, 0x0000 }, { 4026, 0x0000 }, + /* 0x25000 */ + { 4026, 0x0000 }, { 4026, 0x0000 }, { 4026, 0x1000 }, { 4027, 0x0000 }, + { 4027, 0x0000 }, { 4027, 0x0004 }, { 4028, 0x0000 }, { 4028, 0x0000 }, + { 4028, 0x0000 }, { 4028, 0x2000 }, { 4029, 0x0000 }, { 4029, 0x0000 }, + { 4029, 0x0000 }, { 4029, 0x0000 }, { 4029, 0x0000 }, { 4029, 0x0000 }, + /* 0x25100 */ + { 4029, 0x0000 }, { 4029, 0x0000 }, { 4029, 0x0800 }, { 4030, 0x0000 }, + { 4030, 0x0100 }, { 4031, 0x0000 }, { 4031, 0x0000 }, { 4031, 0x6000 }, + { 4033, 0x0000 }, { 4033, 0x0000 }, { 4033, 0x0000 }, { 4033, 0x0000 }, + { 4033, 0x0000 }, { 4033, 0x0000 }, { 4033, 0x00c8 }, { 4036, 0x0000 }, + /* 0x25200 */ + { 4036, 0x0000 }, { 4036, 0x0000 }, { 4036, 0x0003 }, { 4038, 0x0000 }, + { 4038, 0x0000 }, { 4038, 0x0001 }, { 4039, 0x0000 }, { 4039, 0x0000 }, + { 4039, 0x0000 }, { 4039, 0x0200 }, { 4040, 0x0000 }, { 4040, 0x0000 }, + { 4040, 0x0080 }, { 4041, 0x0100 }, { 4042, 0x0000 }, { 4042, 0x0000 }, + /* 0x25300 */ + { 4042, 0x4000 }, { 4043, 0x000a }, { 4045, 0x0000 }, { 4045, 0x0000 }, + { 4045, 0x0000 }, { 4045, 0x0000 }, { 4045, 0x0000 }, { 4045, 0x0000 }, + { 4045, 0x0000 }, { 4045, 0x0000 }, { 4045, 0x0000 }, { 4045, 0x0000 }, + { 4045, 0x0000 }, { 4045, 0x0000 }, { 4045, 0x0000 }, { 4045, 0x0000 }, + /* 0x25400 */ + { 4045, 0x0000 }, { 4045, 0x0200 }, { 4046, 0x8020 }, { 4048, 0x0001 }, + { 4049, 0x0040 }, { 4050, 0x0000 }, { 4050, 0x5000 }, { 4052, 0x0000 }, + { 4052, 0x0000 }, { 4052, 0x0000 }, { 4052, 0x0000 }, { 4052, 0x0000 }, + { 4052, 0x0000 }, { 4052, 0x0000 }, { 4052, 0x0000 }, { 4052, 0x0000 }, + /* 0x25500 */ + { 4052, 0x0000 }, { 4052, 0x0000 }, { 4052, 0x0000 }, { 4052, 0x8022 }, + { 4055, 0x0000 }, { 4055, 0x7800 }, { 4059, 0x0064 }, { 4062, 0x0000 }, + { 4062, 0x8012 }, { 4065, 0x0000 }, { 4065, 0x0000 }, { 4065, 0x0200 }, + { 4066, 0x0000 }, { 4066, 0x0820 }, { 4068, 0x0001 }, { 4069, 0x0000 }, + /* 0x25600 */ + { 4069, 0x0020 }, { 4070, 0x0000 }, { 4070, 0x0000 }, { 4070, 0x0020 }, + { 4071, 0x0000 }, { 4071, 0x0002 }, { 4072, 0x0000 }, { 4072, 0x0000 }, + { 4072, 0x0008 }, { 4073, 0x0000 }, { 4073, 0x0000 }, { 4073, 0x0000 }, + { 4073, 0x0000 }, { 4073, 0x0000 }, { 4073, 0x0008 }, { 4074, 0x0040 }, + /* 0x25700 */ + { 4075, 0x0040 }, { 4076, 0x2000 }, { 4077, 0x0020 }, { 4078, 0x2000 }, + { 4079, 0x0000 }, { 4079, 0x0000 }, { 4079, 0x0000 }, { 4079, 0x0004 }, + { 4080, 0x0000 }, { 4080, 0x0000 }, { 4080, 0x0000 }, { 4080, 0x0000 }, + { 4080, 0x0080 }, { 4081, 0x8000 }, { 4082, 0x0003 }, { 4084, 0x0000 }, + /* 0x25800 */ + { 4084, 0x0000 }, { 4084, 0x0000 }, { 4084, 0x0000 }, { 4084, 0x0000 }, + { 4084, 0x0000 }, { 4084, 0x2080 }, { 4086, 0x0000 }, { 4086, 0x0004 }, + { 4087, 0x0000 }, { 4087, 0x0000 }, { 4087, 0x0000 }, { 4087, 0x0000 }, + { 4087, 0x0100 }, { 4088, 0x0000 }, { 4088, 0x0002 }, { 4089, 0x0000 }, + /* 0x25900 */ + { 4089, 0x0008 }, { 4090, 0x0000 }, { 4090, 0x0000 }, { 4090, 0x0000 }, + { 4090, 0x0040 }, { 4091, 0x0040 }, { 4092, 0x0000 }, { 4092, 0x0000 }, + { 4092, 0x0000 }, { 4092, 0x0000 }, { 4092, 0x1000 }, { 4093, 0x0000 }, + { 4093, 0x1000 }, { 4094, 0x0000 }, { 4094, 0x0000 }, { 4094, 0x0000 }, + /* 0x25a00 */ + { 4094, 0x0000 }, { 4094, 0x0000 }, { 4094, 0x0000 }, { 4094, 0x0000 }, + { 4094, 0x0000 }, { 4094, 0x0000 }, { 4094, 0x0000 }, { 4094, 0x0000 }, + { 4094, 0x0000 }, { 4094, 0x1020 }, { 4096, 0xc000 }, { 4098, 0x0000 }, + { 4098, 0x0000 }, { 4098, 0x0000 }, { 4098, 0x0200 }, { 4099, 0x0000 }, + /* 0x25b00 */ + { 4099, 0x0000 }, { 4099, 0x0000 }, { 4099, 0x0000 }, { 4099, 0x0000 }, + { 4099, 0x0000 }, { 4099, 0x0000 }, { 4099, 0x0000 }, { 4099, 0x0010 }, + { 4100, 0x0200 }, { 4101, 0x0000 }, { 4101, 0x0000 }, { 4101, 0x0018 }, + { 4103, 0x0040 }, { 4104, 0x0000 }, { 4104, 0x0110 }, { 4106, 0x0000 }, + /* 0x25c00 */ + { 4106, 0x0042 }, { 4108, 0x0000 }, { 4108, 0x0002 }, { 4109, 0x0000 }, + { 4109, 0x0400 }, { 4110, 0x0000 }, { 4110, 0x0020 }, { 4111, 0x0000 }, + { 4111, 0x0000 }, { 4111, 0x0002 }, { 4112, 0x0000 }, { 4112, 0x0000 }, + { 4112, 0x0003 }, { 4114, 0x0000 }, { 4114, 0x0000 }, { 4114, 0x4000 }, + /* 0x25d00 */ + { 4115, 0x0000 }, { 4115, 0x0000 }, { 4115, 0x0001 }, { 4116, 0x0000 }, + { 4116, 0x0008 }, { 4117, 0x0000 }, { 4117, 0x0000 }, { 4117, 0x0000 }, + { 4117, 0x0000 }, { 4117, 0x0000 }, { 4117, 0x0000 }, { 4117, 0x0000 }, + { 4117, 0x0000 }, { 4117, 0x0000 }, { 4117, 0x0000 }, { 4117, 0x0000 }, + /* 0x25e00 */ + { 4117, 0x4000 }, { 4118, 0x0000 }, { 4118, 0x0000 }, { 4118, 0x0000 }, + { 4118, 0x0200 }, { 4119, 0x0000 }, { 4119, 0x0000 }, { 4119, 0x0000 }, + { 4119, 0x000e }, { 4122, 0x0000 }, { 4122, 0x0040 }, { 4123, 0x1000 }, + { 4124, 0x0000 }, { 4124, 0x0180 }, { 4126, 0x0000 }, { 4126, 0x0000 }, + /* 0x25f00 */ + { 4126, 0x0000 }, { 4126, 0x0400 }, { 4127, 0x0000 }, { 4127, 0x0000 }, + { 4127, 0x0800 }, { 4128, 0x0000 }, { 4128, 0x0000 }, { 4128, 0x0000 }, + { 4128, 0x0000 }, { 4128, 0x0000 }, { 4128, 0x0000 }, { 4128, 0x0000 }, + { 4128, 0x0000 }, { 4128, 0x0000 }, { 4128, 0x0006 }, { 4130, 0x0000 }, + /* 0x26000 */ + { 4130, 0x0000 }, { 4130, 0x0000 }, { 4130, 0x0200 }, { 4131, 0x0000 }, + { 4131, 0x0100 }, { 4132, 0x0000 }, { 4132, 0x0010 }, { 4133, 0x0000 }, + { 4133, 0x0008 }, { 4134, 0x0080 }, { 4135, 0x0030 }, { 4137, 0x0000 }, + { 4137, 0x0000 }, { 4137, 0x0000 }, { 4137, 0x0000 }, { 4137, 0x0000 }, + /* 0x26100 */ + { 4137, 0x0004 }, { 4138, 0x0000 }, { 4138, 0x0002 }, { 4139, 0x0000 }, + { 4139, 0x0000 }, { 4139, 0x1e00 }, { 4143, 0x0000 }, { 4143, 0x0000 }, + { 4143, 0x0000 }, { 4143, 0x0000 }, { 4143, 0x6000 }, { 4145, 0x0004 }, + { 4146, 0x0000 }, { 4146, 0x2000 }, { 4147, 0x0000 }, { 4147, 0x0000 }, + /* 0x26200 */ + { 4147, 0x0000 }, { 4147, 0x0000 }, { 4147, 0x0000 }, { 4147, 0x0000 }, + { 4147, 0x0000 }, { 4147, 0x0100 }, { 4148, 0x0c02 }, { 4151, 0x0000 }, + { 4151, 0x0000 }, { 4151, 0x0000 }, { 4151, 0x0000 }, { 4151, 0x0000 }, + { 4151, 0x0000 }, { 4151, 0x0001 }, { 4152, 0x0000 }, { 4152, 0x0000 }, + /* 0x26300 */ + { 4152, 0x0000 }, { 4152, 0x0000 }, { 4152, 0x0000 }, { 4152, 0x0020 }, + { 4153, 0x1800 }, { 4155, 0x0002 }, { 4156, 0x0000 }, { 4156, 0x0000 }, + { 4156, 0x0000 }, { 4156, 0x0000 }, { 4156, 0x0000 }, { 4156, 0x4000 }, + { 4157, 0x0000 }, { 4157, 0x0000 }, { 4157, 0x0000 }, { 4157, 0x0120 }, + /* 0x26400 */ + { 4159, 0x0004 }, { 4160, 0x0007 }, { 4163, 0x0000 }, { 4163, 0x0000 }, + { 4163, 0x0400 }, { 4164, 0x0000 }, { 4164, 0x0200 }, { 4165, 0x0000 }, + { 4165, 0x2310 }, { 4169, 0x0100 }, { 4170, 0x0000 }, { 4170, 0x0000 }, + { 4170, 0x0000 }, { 4170, 0x0000 }, { 4170, 0x0000 }, { 4170, 0x0000 }, + /* 0x26500 */ + { 4170, 0x0000 }, { 4170, 0x0004 }, { 4171, 0x0000 }, { 4171, 0x0000 }, + { 4171, 0x0000 }, { 4171, 0x0000 }, { 4171, 0x0000 }, { 4171, 0x0004 }, + { 4172, 0x0000 }, { 4172, 0x0000 }, { 4172, 0x2001 }, { 4174, 0x8000 }, + { 4175, 0x0000 }, { 4175, 0x0000 }, { 4175, 0x0000 }, { 4175, 0x0000 }, + /* 0x26600 */ + { 4175, 0x0000 }, { 4175, 0x0004 }, { 4176, 0x0040 }, { 4177, 0x0000 }, + { 4177, 0x0000 }, { 4177, 0x0000 }, { 4177, 0x0000 }, { 4177, 0x0000 }, + { 4177, 0x0000 }, { 4177, 0x0000 }, { 4177, 0x8000 }, { 4178, 0x0022 }, + { 4180, 0x0000 }, { 4180, 0x0400 }, { 4181, 0x0100 }, { 4182, 0x1000 }, + /* 0x26700 */ + { 4183, 0x0000 }, { 4183, 0x0040 }, { 4184, 0x0000 }, { 4184, 0x0000 }, + { 4184, 0x0002 }, { 4185, 0x0000 }, { 4185, 0x0000 }, { 4185, 0x0000 }, + { 4185, 0x0000 }, { 4185, 0x0200 }, { 4186, 0x0000 }, { 4186, 0x0018 }, + { 4188, 0x1000 }, { 4189, 0x0000 }, { 4189, 0x0000 }, { 4189, 0x0000 }, + /* 0x26800 */ + { 4189, 0x0000 }, { 4189, 0x1000 }, { 4190, 0x0000 }, { 4190, 0x0000 }, + { 4190, 0x0040 }, { 4191, 0x4000 }, { 4192, 0x4000 }, { 4193, 0x0000 }, + { 4193, 0x0500 }, { 4195, 0x0008 }, { 4196, 0x0000 }, { 4196, 0x0000 }, + { 4196, 0x0080 }, { 4197, 0x0000 }, { 4197, 0x0000 }, { 4197, 0x0000 }, + /* 0x26900 */ + { 4197, 0x4000 }, { 4198, 0x0002 }, { 4199, 0x0040 }, { 4200, 0x0200 }, + { 4201, 0x0000 }, { 4201, 0x0002 }, { 4202, 0x0000 }, { 4202, 0x0000 }, + { 4202, 0x0000 }, { 4202, 0x0000 }, { 4202, 0x0100 }, { 4203, 0x0020 }, + { 4204, 0x0000 }, { 4204, 0x0000 }, { 4204, 0x0000 }, { 4204, 0x0404 }, + /* 0x26a00 */ + { 4206, 0x0000 }, { 4206, 0x0000 }, { 4206, 0x6000 }, { 4208, 0x0010 }, + { 4209, 0x0004 }, { 4210, 0x0006 }, { 4212, 0x0000 }, { 4212, 0x0000 }, + { 4212, 0x0000 }, { 4212, 0x0000 }, { 4212, 0x0000 }, { 4212, 0x0000 }, + { 4212, 0x0000 }, { 4212, 0x0000 }, { 4212, 0x0000 }, { 4212, 0x0000 }, + /* 0x26b00 */ + { 4212, 0x0420 }, { 4214, 0x0008 }, { 4215, 0x0100 }, { 4216, 0x0000 }, + { 4216, 0x0000 }, { 4216, 0x080f }, { 4221, 0x0000 }, { 4221, 0x0020 }, + { 4222, 0x0004 }, { 4223, 0x20c0 }, { 4226, 0x0000 }, { 4226, 0x0008 }, + { 4227, 0x0001 }, { 4228, 0x0000 }, { 4228, 0x0000 }, { 4228, 0x0080 }, + /* 0x26c00 */ + { 4229, 0x0000 }, { 4229, 0x0000 }, { 4229, 0x0002 }, { 4230, 0x0000 }, + { 4230, 0x0001 }, { 4231, 0x0000 }, { 4231, 0x0000 }, { 4231, 0xc000 }, + { 4233, 0x0007 }, { 4236, 0x0000 }, { 4236, 0x0010 }, { 4237, 0x2180 }, + { 4240, 0x0009 }, { 4242, 0x0002 }, { 4243, 0x0000 }, { 4243, 0x0000 }, + /* 0x26d00 */ + { 4243, 0x0000 }, { 4243, 0x0000 }, { 4243, 0x07fc }, { 4252, 0x0000 }, + { 4252, 0x0000 }, { 4252, 0x0002 }, { 4253, 0x0000 }, { 4253, 0x0000 }, + { 4253, 0x0000 }, { 4253, 0x0000 }, { 4253, 0x40ff }, { 4262, 0x0000 }, + { 4262, 0x0000 }, { 4262, 0x1000 }, { 4263, 0x0c00 }, { 4265, 0x0001 }, + /* 0x26e00 */ + { 4266, 0x00a1 }, { 4269, 0x0004 }, { 4270, 0x0000 }, { 4270, 0x0000 }, + { 4270, 0x003c }, { 4274, 0x0000 }, { 4274, 0x4000 }, { 4275, 0x0084 }, + { 4277, 0x0010 }, { 4278, 0x0200 }, { 4279, 0x0000 }, { 4279, 0x0000 }, + { 4279, 0x0000 }, { 4279, 0x00ff }, { 4287, 0x0000 }, { 4287, 0x0000 }, + /* 0x26f00 */ + { 4287, 0x0000 }, { 4287, 0x0000 }, { 4287, 0x0040 }, { 4288, 0x0000 }, + { 4288, 0x0000 }, { 4288, 0x0000 }, { 4288, 0x0000 }, { 4288, 0x0018 }, + { 4290, 0x0000 }, { 4290, 0x8000 }, { 4291, 0x0002 }, { 4292, 0x0000 }, + { 4292, 0x0000 }, { 4292, 0xc000 }, { 4294, 0x0000 }, { 4294, 0x0000 }, + /* 0x27000 */ + { 4294, 0x4000 }, { 4295, 0x0000 }, { 4295, 0x0000 }, { 4295, 0x0000 }, + { 4295, 0x0800 }, { 4296, 0x000c }, { 4298, 0x0000 }, { 4298, 0x0000 }, + { 4298, 0x0100 }, { 4299, 0x0000 }, { 4299, 0xe000 }, { 4302, 0x0000 }, + { 4302, 0x2000 }, { 4303, 0x0000 }, { 4303, 0x0000 }, { 4303, 0x0100 }, + /* 0x27100 */ + { 4304, 0x1200 }, { 4306, 0x0000 }, { 4306, 0x00c0 }, { 4308, 0x0000 }, + { 4308, 0x0000 }, { 4308, 0x0000 }, { 4308, 0x0030 }, { 4310, 0x0020 }, + { 4311, 0x0000 }, { 4311, 0x0000 }, { 4311, 0x0000 }, { 4311, 0x0000 }, + { 4311, 0x2000 }, { 4312, 0x0000 }, { 4312, 0x0000 }, { 4312, 0x0000 }, + /* 0x27200 */ + { 4312, 0x0000 }, { 4312, 0x0800 }, { 4313, 0x0000 }, { 4313, 0x0000 }, + { 4313, 0x0000 }, { 4313, 0x0000 }, { 4313, 0x0000 }, { 4313, 0x0000 }, + { 4313, 0x0821 }, { 4316, 0x0000 }, { 4316, 0x0000 }, { 4316, 0x0044 }, + { 4318, 0x0000 }, { 4318, 0x0000 }, { 4318, 0x0040 }, { 4319, 0x0000 }, + /* 0x27300 */ + { 4319, 0x0000 }, { 4319, 0x0000 }, { 4319, 0x0000 }, { 4319, 0x0000 }, + { 4319, 0x0000 }, { 4319, 0x0000 }, { 4319, 0x0000 }, { 4319, 0x0000 }, + { 4319, 0x0000 }, { 4319, 0x0400 }, { 4320, 0x0000 }, { 4320, 0x0000 }, + { 4320, 0x0000 }, { 4320, 0x0000 }, { 4320, 0x0000 }, { 4320, 0x0000 }, + /* 0x27400 */ + { 4320, 0x0000 }, { 4320, 0x0000 }, { 4320, 0x0004 }, { 4321, 0x0000 }, + { 4321, 0x0000 }, { 4321, 0x0001 }, { 4322, 0x0000 }, { 4322, 0x0000 }, + { 4322, 0x0050 }, { 4324, 0x0000 }, { 4324, 0x0000 }, { 4324, 0x0000 }, + { 4324, 0x0000 }, { 4324, 0x0000 }, { 4324, 0x0000 }, { 4324, 0x0000 }, + /* 0x27500 */ + { 4324, 0x0000 }, { 4324, 0x0000 }, { 4324, 0x0000 }, { 4324, 0x0000 }, + { 4324, 0x0000 }, { 4324, 0x0000 }, { 4324, 0x0000 }, { 4324, 0x0010 }, + { 4325, 0x0000 }, { 4325, 0x0000 }, { 4325, 0x0008 }, { 4326, 0x0000 }, + { 4326, 0x0000 }, { 4326, 0x0000 }, { 4326, 0x0011 }, { 4328, 0x6000 }, + /* 0x27600 */ + { 4330, 0x1080 }, { 4332, 0x0000 }, { 4332, 0x0000 }, { 4332, 0x0204 }, + { 4334, 0x0000 }, { 4334, 0x00e0 }, { 4337, 0x0000 }, { 4337, 0x0000 }, + { 4337, 0x0000 }, { 4337, 0x0010 }, { 4338, 0x0000 }, { 4338, 0x0000 }, + { 4338, 0x0000 }, { 4338, 0x0000 }, { 4338, 0x0000 }, { 4338, 0x0000 }, + /* 0x27700 */ + { 4338, 0x8000 }, { 4339, 0x0000 }, { 4339, 0x0000 }, { 4339, 0x0060 }, + { 4341, 0x0002 }, { 4342, 0x4000 }, { 4343, 0x0000 }, { 4343, 0x0000 }, + { 4343, 0x0030 }, { 4345, 0x0000 }, { 4345, 0x0000 }, { 4345, 0x0000 }, + { 4345, 0x1000 }, { 4346, 0x0000 }, { 4346, 0x0000 }, { 4346, 0x0000 }, + /* 0x27800 */ + { 4346, 0x0000 }, { 4346, 0x0000 }, { 4346, 0x0000 }, { 4346, 0x0000 }, + { 4346, 0x0000 }, { 4346, 0x0100 }, { 4347, 0x0000 }, { 4347, 0x0001 }, + { 4348, 0x0000 }, { 4348, 0x2000 }, { 4349, 0x0000 }, { 4349, 0x0004 }, + { 4350, 0x0100 }, { 4351, 0x0000 }, { 4351, 0x0000 }, { 4351, 0x0000 }, + /* 0x27900 */ + { 4351, 0x0000 }, { 4351, 0x0000 }, { 4351, 0x0010 }, { 4352, 0x0000 }, + { 4352, 0x0000 }, { 4352, 0x0000 }, { 4352, 0x0080 }, { 4353, 0x0400 }, + { 4354, 0x0000 }, { 4354, 0x0000 }, { 4354, 0x0001 }, { 4355, 0x0000 }, + { 4355, 0x0000 }, { 4355, 0x2000 }, { 4356, 0x0000 }, { 4356, 0x2000 }, + /* 0x27a00 */ + { 4357, 0x4400 }, { 4359, 0x0000 }, { 4359, 0x0000 }, { 4359, 0x4000 }, + { 4360, 0x0000 }, { 4360, 0x0208 }, { 4362, 0x0000 }, { 4362, 0x0200 }, + { 4363, 0x0010 }, { 4364, 0x0000 }, { 4364, 0x0000 }, { 4364, 0x6000 }, + { 4366, 0x0000 }, { 4366, 0x0000 }, { 4366, 0x0000 }, { 4366, 0x0010 }, + /* 0x27b00 */ + { 4367, 0x0840 }, { 4369, 0x0100 }, { 4370, 0x0000 }, { 4370, 0x0700 }, + { 4373, 0x0100 }, { 4374, 0x0000 }, { 4374, 0x0000 }, { 4374, 0x0000 }, + { 4374, 0x0000 }, { 4374, 0x0000 }, { 4374, 0x0000 }, { 4374, 0x0000 }, + { 4374, 0x0000 }, { 4374, 0x0000 }, { 4374, 0x0000 }, { 4374, 0x0010 }, + /* 0x27c00 */ + { 4375, 0x0000 }, { 4375, 0x0004 }, { 4376, 0x0000 }, { 4376, 0x0000 }, + { 4376, 0x0000 }, { 4376, 0x0000 }, { 4376, 0x0000 }, { 4376, 0x0000 }, + { 4376, 0x0000 }, { 4376, 0x0000 }, { 4376, 0x0000 }, { 4376, 0x0000 }, + { 4376, 0x0000 }, { 4376, 0x0000 }, { 4376, 0x0000 }, { 4376, 0x0000 }, + /* 0x27d00 */ + { 4376, 0x0000 }, { 4376, 0x0000 }, { 4376, 0x8000 }, { 4377, 0x0000 }, + { 4377, 0x0000 }, { 4377, 0x0018 }, { 4379, 0x0040 }, { 4380, 0x0008 }, + { 4381, 0x8010 }, { 4383, 0x0100 }, { 4384, 0x0000 }, { 4384, 0x2000 }, + { 4385, 0x0000 }, { 4385, 0x1000 }, { 4386, 0x0000 }, { 4386, 0x0000 }, + /* 0x27e00 */ + { 4386, 0x0000 }, { 4386, 0x0000 }, { 4386, 0x0000 }, { 4386, 0x0000 }, + { 4386, 0xa000 }, { 4388, 0x0000 }, { 4388, 0x0000 }, { 4388, 0x0000 }, + { 4388, 0x0000 }, { 4388, 0x0000 }, { 4388, 0x0000 }, { 4388, 0x0000 }, + { 4388, 0x0000 }, { 4388, 0x0000 }, { 4388, 0x0000 }, { 4388, 0x0000 }, + /* 0x27f00 */ + { 4388, 0x0000 }, { 4388, 0x0000 }, { 4388, 0x4000 }, { 4389, 0x0000 }, + { 4389, 0x0000 }, { 4389, 0x0000 }, { 4389, 0x0000 }, { 4389, 0x0000 }, + { 4389, 0x0000 }, { 4389, 0x0000 }, { 4389, 0x0000 }, { 4389, 0x0000 }, + { 4389, 0x0000 }, { 4389, 0x0000 }, { 4389, 0x0000 }, { 4389, 0x0200 }, + /* 0x28000 */ + { 4390, 0x0204 }, { 4392, 0x4000 }, { 4393, 0x0018 }, { 4395, 0x0000 }, + { 4395, 0x0100 }, { 4396, 0x0000 }, { 4396, 0x0000 }, { 4396, 0x0000 }, + { 4396, 0x0008 }, { 4397, 0x0001 }, { 4398, 0x0000 }, { 4398, 0x6000 }, + { 4400, 0x0000 }, { 4400, 0x0000 }, { 4400, 0x0300 }, { 4402, 0x0010 }, + /* 0x28100 */ + { 4403, 0x0000 }, { 4403, 0x0000 }, { 4403, 0x4000 }, { 4404, 0x0000 }, + { 4404, 0x8000 }, { 4405, 0x2000 }, { 4406, 0x8000 }, { 4407, 0x0000 }, + { 4407, 0x0200 }, { 4408, 0x0000 }, { 4408, 0x8000 }, { 4409, 0x1000 }, + { 4410, 0x0000 }, { 4410, 0x0000 }, { 4410, 0x0000 }, { 4410, 0x0000 }, + /* 0x28200 */ + { 4410, 0x0080 }, { 4411, 0x0500 }, { 4413, 0x0000 }, { 4413, 0x0000 }, + { 4413, 0x0000 }, { 4413, 0x0040 }, { 4414, 0x0000 }, { 4414, 0x1000 }, + { 4415, 0x0000 }, { 4415, 0x0800 }, { 4416, 0x0000 }, { 4416, 0x0000 }, + { 4416, 0x2000 }, { 4417, 0x0000 }, { 4417, 0x0004 }, { 4418, 0x0000 }, + /* 0x28300 */ + { 4418, 0x0040 }, { 4419, 0x0100 }, { 4420, 0x8000 }, { 4421, 0x0400 }, + { 4422, 0x0000 }, { 4422, 0x0000 }, { 4422, 0x2020 }, { 4424, 0x2000 }, + { 4425, 0x0400 }, { 4426, 0x0000 }, { 4426, 0x0000 }, { 4426, 0x0000 }, + { 4426, 0x0000 }, { 4426, 0x0000 }, { 4426, 0x0000 }, { 4426, 0x0000 }, + /* 0x28400 */ + { 4426, 0x0000 }, { 4426, 0x0004 }, { 4427, 0x0000 }, { 4427, 0x0000 }, + { 4427, 0x0000 }, { 4427, 0x0000 }, { 4427, 0x1100 }, { 4429, 0x0008 }, + { 4430, 0x0004 }, { 4431, 0x0000 }, { 4431, 0x0000 }, { 4431, 0x0000 }, + { 4431, 0x0000 }, { 4431, 0x0000 }, { 4431, 0x0000 }, { 4431, 0x0000 }, + /* 0x28500 */ + { 4431, 0x0002 }, { 4432, 0x0000 }, { 4432, 0x0000 }, { 4432, 0x3000 }, + { 4434, 0x0000 }, { 4434, 0x0000 }, { 4434, 0x1000 }, { 4435, 0x0000 }, + { 4435, 0x0000 }, { 4435, 0x0000 }, { 4435, 0x0000 }, { 4435, 0x0000 }, + { 4435, 0x0000 }, { 4435, 0x0000 }, { 4435, 0x0100 }, { 4436, 0x0010 }, + /* 0x28600 */ + { 4437, 0x0801 }, { 4439, 0x0000 }, { 4439, 0x0020 }, { 4440, 0x0800 }, + { 4441, 0x0000 }, { 4441, 0x0000 }, { 4441, 0x0000 }, { 4441, 0x0000 }, + { 4441, 0x0000 }, { 4441, 0x0000 }, { 4441, 0x0c00 }, { 4443, 0x1000 }, + { 4444, 0x0000 }, { 4444, 0x0100 }, { 4445, 0x0040 }, { 4446, 0x0000 }, + /* 0x28700 */ + { 4446, 0x0000 }, { 4446, 0x0008 }, { 4447, 0x0000 }, { 4447, 0x0000 }, + { 4447, 0x0000 }, { 4447, 0x0000 }, { 4447, 0x0000 }, { 4447, 0x0000 }, + { 4447, 0x0000 }, { 4447, 0x0000 }, { 4447, 0x0000 }, { 4447, 0x0000 }, + { 4447, 0x0000 }, { 4447, 0x0000 }, { 4447, 0x0000 }, { 4447, 0x0000 }, + /* 0x28800 */ + { 4447, 0x0010 }, { 4448, 0x0000 }, { 4448, 0x0800 }, { 4449, 0x0000 }, + { 4449, 0x0000 }, { 4449, 0x0000 }, { 4449, 0x0000 }, { 4449, 0x0000 }, + { 4449, 0x0000 }, { 4449, 0x0000 }, { 4449, 0x0000 }, { 4449, 0x0000 }, + { 4449, 0x0000 }, { 4449, 0x0000 }, { 4449, 0x0000 }, { 4449, 0x0000 }, + /* 0x28900 */ + { 4449, 0x0000 }, { 4449, 0x0000 }, { 4449, 0x0000 }, { 4449, 0x0008 }, + { 4450, 0x0300 }, { 4452, 0x0040 }, { 4453, 0x1110 }, { 4456, 0x4000 }, + { 4457, 0x0200 }, { 4458, 0x0000 }, { 4458, 0x0d00 }, { 4461, 0x1100 }, + { 4463, 0x0001 }, { 4464, 0x5000 }, { 4466, 0x0192 }, { 4470, 0x1e00 }, + /* 0x28a00 */ + { 4474, 0x8000 }, { 4475, 0x0040 }, { 4476, 0x0220 }, { 4478, 0x0040 }, + { 4479, 0x0ff0 }, { 4487, 0x0600 }, { 4489, 0x0000 }, { 4489, 0x0000 }, + { 4489, 0x000e }, { 4492, 0x1c00 }, { 4495, 0x0000 }, { 4495, 0x0000 }, + { 4495, 0x5841 }, { 4500, 0xc000 }, { 4502, 0x002f }, { 4507, 0x1000 }, + /* 0x28b00 */ + { 4508, 0x1000 }, { 4509, 0x0008 }, { 4510, 0xb806 }, { 4516, 0x0000 }, + { 4516, 0x5040 }, { 4519, 0x0001 }, { 4520, 0x1078 }, { 4525, 0x0000 }, + { 4525, 0x8000 }, { 4526, 0x3200 }, { 4529, 0x0000 }, { 4529, 0x0000 }, + { 4529, 0x0024 }, { 4531, 0x0690 }, { 4535, 0x1f80 }, { 4541, 0x8020 }, + /* 0x28c00 */ + { 4543, 0x0208 }, { 4545, 0x3000 }, { 4547, 0x0848 }, { 4550, 0x0a01 }, + { 4553, 0x0000 }, { 4553, 0x0000 }, { 4553, 0x0000 }, { 4553, 0x0000 }, + { 4553, 0x0000 }, { 4553, 0x0000 }, { 4553, 0x0000 }, { 4553, 0x0000 }, + { 4553, 0x2400 }, { 4555, 0x0004 }, { 4556, 0x0000 }, { 4556, 0x0000 }, + /* 0x28d00 */ + { 4556, 0x0000 }, { 4556, 0x0000 }, { 4556, 0x0000 }, { 4556, 0x0010 }, + { 4557, 0x0000 }, { 4557, 0x0000 }, { 4557, 0x0000 }, { 4557, 0x0000 }, + { 4557, 0x0000 }, { 4557, 0x0200 }, { 4558, 0x0000 }, { 4558, 0x0000 }, + { 4558, 0x0000 }, { 4558, 0x0000 }, { 4558, 0x0000 }, { 4558, 0x0000 }, + /* 0x28e00 */ + { 4558, 0x8000 }, { 4559, 0x0000 }, { 4559, 0x0000 }, { 4559, 0x0240 }, + { 4561, 0x0000 }, { 4561, 0x0000 }, { 4561, 0x0060 }, { 4563, 0x0000 }, + { 4563, 0x0000 }, { 4563, 0x0080 }, { 4564, 0x1000 }, { 4565, 0x000c }, + { 4567, 0x0000 }, { 4567, 0x0200 }, { 4568, 0x0080 }, { 4569, 0x0000 }, + /* 0x28f00 */ + { 4569, 0x0000 }, { 4569, 0x0000 }, { 4569, 0x0000 }, { 4569, 0x0000 }, + { 4569, 0x0000 }, { 4569, 0x0000 }, { 4569, 0x0000 }, { 4569, 0x0000 }, + { 4569, 0x0000 }, { 4569, 0x0000 }, { 4569, 0x0000 }, { 4569, 0x0000 }, + { 4569, 0x0020 }, { 4570, 0x0000 }, { 4570, 0x0000 }, { 4570, 0x0000 }, + /* 0x29000 */ + { 4570, 0x0000 }, { 4570, 0x0000 }, { 4570, 0x0000 }, { 4570, 0x0000 }, + { 4570, 0x0000 }, { 4570, 0x0000 }, { 4570, 0x0000 }, { 4570, 0x0000 }, + { 4570, 0x0900 }, { 4572, 0x0008 }, { 4573, 0x8000 }, { 4574, 0x0003 }, + { 4576, 0x0001 }, { 4577, 0x0000 }, { 4577, 0x3030 }, { 4581, 0x0000 }, + /* 0x29100 */ + { 4581, 0x2000 }, { 4582, 0x0001 }, { 4583, 0x0000 }, { 4583, 0x1000 }, + { 4584, 0x2000 }, { 4585, 0x4800 }, { 4587, 0x0000 }, { 4587, 0x0001 }, + { 4588, 0x0000 }, { 4588, 0x1000 }, { 4589, 0x0100 }, { 4590, 0x0000 }, + { 4590, 0x0000 }, { 4590, 0x0020 }, { 4591, 0x0800 }, +}; +static const Summary16 hkscs1999_uni2indx_page294[32] = { + /* 0x29400 */ + { 4592, 0x0000 }, { 4592, 0x2000 }, { 4593, 0x0001 }, { 4594, 0x8008 }, + { 4596, 0x0100 }, { 4597, 0x0000 }, { 4597, 0x0000 }, { 4597, 0x0000 }, + { 4597, 0x0000 }, { 4597, 0x0000 }, { 4597, 0x0000 }, { 4597, 0x0000 }, + { 4597, 0x0000 }, { 4597, 0x0601 }, { 4600, 0x00a0 }, { 4602, 0x0000 }, + /* 0x29500 */ + { 4602, 0x0000 }, { 4602, 0x0000 }, { 4602, 0x0000 }, { 4602, 0x0000 }, + { 4602, 0x0000 }, { 4602, 0x0000 }, { 4602, 0x0000 }, { 4602, 0x0000 }, + { 4602, 0x0000 }, { 4602, 0x4000 }, { 4603, 0x0000 }, { 4603, 0x0101 }, + { 4605, 0x0000 }, { 4605, 0x0080 }, { 4606, 0x0200 }, { 4607, 0x0010 }, +}; +static const Summary16 hkscs1999_uni2indx_page297[251] = { + /* 0x29700 */ + { 4608, 0x0000 }, { 4608, 0x0000 }, { 4608, 0x0001 }, { 4609, 0x0004 }, + { 4610, 0x0000 }, { 4610, 0x0000 }, { 4610, 0x0000 }, { 4610, 0x0000 }, + { 4610, 0x0000 }, { 4610, 0x0000 }, { 4610, 0x0000 }, { 4610, 0x0000 }, + { 4610, 0x0000 }, { 4610, 0x0010 }, { 4611, 0x0000 }, { 4611, 0x0000 }, + /* 0x29800 */ + { 4611, 0x0000 }, { 4611, 0x0001 }, { 4612, 0x0000 }, { 4612, 0x0000 }, + { 4612, 0x0000 }, { 4612, 0x0080 }, { 4613, 0x0000 }, { 4613, 0x0000 }, + { 4613, 0x0000 }, { 4613, 0x0000 }, { 4613, 0x0010 }, { 4614, 0x0000 }, + { 4614, 0x0000 }, { 4614, 0x0002 }, { 4615, 0x0400 }, { 4616, 0x0002 }, + /* 0x29900 */ + { 4617, 0x0028 }, { 4619, 0x0000 }, { 4619, 0x8000 }, { 4620, 0x0000 }, + { 4620, 0x0300 }, { 4622, 0x2000 }, { 4623, 0x0400 }, { 4624, 0x0000 }, + { 4624, 0x0000 }, { 4624, 0x2000 }, { 4625, 0x0000 }, { 4625, 0x0000 }, + { 4625, 0x0208 }, { 4627, 0x0000 }, { 4627, 0x0000 }, { 4627, 0x0000 }, + /* 0x29a00 */ + { 4627, 0x0000 }, { 4627, 0x0000 }, { 4627, 0x0100 }, { 4628, 0x0000 }, + { 4628, 0x2000 }, { 4629, 0x0000 }, { 4629, 0x0000 }, { 4629, 0x0000 }, + { 4629, 0x0000 }, { 4629, 0x0000 }, { 4629, 0x0000 }, { 4629, 0x0000 }, + { 4629, 0x0000 }, { 4629, 0x0000 }, { 4629, 0x0000 }, { 4629, 0x0000 }, + /* 0x29b00 */ + { 4629, 0x4020 }, { 4631, 0x0000 }, { 4631, 0x0000 }, { 4631, 0x0000 }, + { 4631, 0x0000 }, { 4631, 0x0000 }, { 4631, 0x0000 }, { 4631, 0x0000 }, + { 4631, 0x0000 }, { 4631, 0x0000 }, { 4631, 0x0000 }, { 4631, 0x0000 }, + { 4631, 0x0000 }, { 4631, 0x0020 }, { 4632, 0x0000 }, { 4632, 0x0000 }, + /* 0x29c00 */ + { 4632, 0x0000 }, { 4632, 0x0000 }, { 4632, 0x0000 }, { 4632, 0x0000 }, + { 4632, 0x0000 }, { 4632, 0x0000 }, { 4632, 0x0000 }, { 4632, 0x0000 }, + { 4632, 0x0000 }, { 4632, 0x0000 }, { 4632, 0x2000 }, { 4633, 0x0000 }, + { 4633, 0x0000 }, { 4633, 0x0000 }, { 4633, 0x0000 }, { 4633, 0x0000 }, + /* 0x29d00 */ + { 4633, 0x0000 }, { 4633, 0x0000 }, { 4633, 0x0000 }, { 4633, 0x4000 }, + { 4634, 0x0000 }, { 4634, 0x0400 }, { 4635, 0x0000 }, { 4635, 0x1000 }, + { 4636, 0x0000 }, { 4636, 0x0900 }, { 4638, 0x0000 }, { 4638, 0x0000 }, + { 4638, 0x0000 }, { 4638, 0x0000 }, { 4638, 0x0000 }, { 4638, 0x0040 }, + /* 0x29e00 */ + { 4639, 0x0040 }, { 4640, 0x0000 }, { 4640, 0x2000 }, { 4641, 0x0000 }, + { 4641, 0x0000 }, { 4641, 0x0000 }, { 4641, 0x0100 }, { 4642, 0x0000 }, + { 4642, 0x0000 }, { 4642, 0x0000 }, { 4642, 0x1000 }, { 4643, 0x0000 }, + { 4643, 0x0008 }, { 4644, 0x0000 }, { 4644, 0x0000 }, { 4644, 0x0100 }, + /* 0x29f00 */ + { 4645, 0x0000 }, { 4645, 0x0000 }, { 4645, 0x0008 }, { 4646, 0x0001 }, + { 4647, 0x0000 }, { 4647, 0x0000 }, { 4647, 0x0000 }, { 4647, 0x0000 }, + { 4647, 0x0000 }, { 4647, 0x0000 }, { 4647, 0x0000 }, { 4647, 0x0080 }, + { 4648, 0x0000 }, { 4648, 0x4000 }, { 4649, 0x0000 }, { 4649, 0x0000 }, + /* 0x2a000 */ + { 4649, 0x0000 }, { 4649, 0x0010 }, { 4650, 0x0000 }, { 4650, 0x0000 }, + { 4650, 0x0000 }, { 4650, 0x0000 }, { 4650, 0x0000 }, { 4650, 0x0000 }, + { 4650, 0x0080 }, { 4651, 0x0000 }, { 4651, 0x0000 }, { 4651, 0x0200 }, + { 4652, 0x0000 }, { 4652, 0x0000 }, { 4652, 0x2002 }, { 4654, 0x4108 }, + /* 0x2a100 */ + { 4657, 0x0000 }, { 4657, 0x0000 }, { 4657, 0x0008 }, { 4658, 0x0018 }, + { 4660, 0x0000 }, { 4660, 0x0001 }, { 4661, 0x0000 }, { 4661, 0x0000 }, + { 4661, 0x0000 }, { 4661, 0x000c }, { 4663, 0x0800 }, { 4664, 0x0010 }, + { 4665, 0x0000 }, { 4665, 0x8000 }, { 4666, 0x0000 }, { 4666, 0x0020 }, + /* 0x2a200 */ + { 4667, 0x0000 }, { 4667, 0x0000 }, { 4667, 0x0001 }, { 4668, 0x0008 }, + { 4669, 0x0000 }, { 4669, 0x0000 }, { 4669, 0x0000 }, { 4669, 0x0000 }, + { 4669, 0x0000 }, { 4669, 0x8008 }, { 4671, 0x0000 }, { 4671, 0x2054 }, + { 4675, 0x0000 }, { 4675, 0x8000 }, { 4676, 0x0000 }, { 4676, 0x8000 }, + /* 0x2a300 */ + { 4677, 0x0000 }, { 4677, 0x0000 }, { 4677, 0x0000 }, { 4677, 0x0000 }, + { 4677, 0x0000 }, { 4677, 0x0000 }, { 4677, 0x0000 }, { 4677, 0x0000 }, + { 4677, 0x0000 }, { 4677, 0x0000 }, { 4677, 0x0200 }, { 4678, 0x0000 }, + { 4678, 0x0000 }, { 4678, 0x0000 }, { 4678, 0x0000 }, { 4678, 0x0000 }, + /* 0x2a400 */ + { 4678, 0x0000 }, { 4678, 0x0000 }, { 4678, 0x0000 }, { 4678, 0x0010 }, + { 4679, 0x0000 }, { 4679, 0x0800 }, { 4680, 0x0000 }, { 4680, 0x0000 }, + { 4680, 0x0000 }, { 4680, 0x0000 }, { 4680, 0x0000 }, { 4680, 0x0000 }, + { 4680, 0x0000 }, { 4680, 0x0000 }, { 4680, 0x0000 }, { 4680, 0x0000 }, + /* 0x2a500 */ + { 4680, 0x0000 }, { 4680, 0x0000 }, { 4680, 0x0000 }, { 4680, 0x0000 }, + { 4680, 0x0000 }, { 4680, 0x0000 }, { 4680, 0x0000 }, { 4680, 0x0000 }, + { 4680, 0x0000 }, { 4680, 0x0000 }, { 4680, 0x0000 }, { 4680, 0x0000 }, + { 4680, 0x0840 }, { 4682, 0x0000 }, { 4682, 0x0000 }, { 4682, 0x0000 }, + /* 0x2a600 */ + { 4682, 0x0002 }, { 4683, 0x0000 }, { 4683, 0x0000 }, { 4683, 0x0004 }, + { 4684, 0x0400 }, { 4685, 0x0800 }, { 4686, 0x0000 }, { 4686, 0x0000 }, + { 4686, 0x0000 }, { 4686, 0x0000 }, { 4686, 0x0200 }, +}; +static const Summary16 hkscs1999_uni2indx_page2f8[30] = { + /* 0x2f800 */ + { 4687, 0x0000 }, { 4687, 0x0000 }, { 4687, 0x0020 }, { 4688, 0x0800 }, + { 4689, 0x0001 }, { 4690, 0x0000 }, { 4690, 0x0000 }, { 4690, 0x0100 }, + { 4691, 0x0000 }, { 4691, 0x0010 }, { 4692, 0x0040 }, { 4693, 0x0000 }, + { 4693, 0x2000 }, { 4694, 0x0000 }, { 4694, 0x0000 }, { 4694, 0x0000 }, + /* 0x2f900 */ + { 4694, 0x0000 }, { 4694, 0x0000 }, { 4694, 0x0000 }, { 4694, 0x0000 }, + { 4694, 0x0000 }, { 4694, 0x0000 }, { 4694, 0x0000 }, { 4694, 0x0000 }, + { 4694, 0x0000 }, { 4694, 0x0010 }, { 4695, 0x0000 }, { 4695, 0x1004 }, + { 4697, 0x0000 }, { 4697, 0x0010 }, +}; + +static int +hkscs1999_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc >= 0x0000 && wc < 0x02d0) + summary = &hkscs1999_uni2indx_page00[(wc>>4)]; + else if (wc >= 0x0400 && wc < 0x0460) + summary = &hkscs1999_uni2indx_page04[(wc>>4)-0x040]; + else if (wc >= 0x1e00 && wc < 0x1ed0) + summary = &hkscs1999_uni2indx_page1e[(wc>>4)-0x1e0]; + else if (wc >= 0x2100 && wc < 0x21f0) + summary = &hkscs1999_uni2indx_page21[(wc>>4)-0x210]; + else if (wc >= 0x2300 && wc < 0x2580) + summary = &hkscs1999_uni2indx_page23[(wc>>4)-0x230]; + else if (wc >= 0x2700 && wc < 0x2740) + summary = &hkscs1999_uni2indx_page27[(wc>>4)-0x270]; + else if (wc >= 0x2e00 && wc < 0x3240) + summary = &hkscs1999_uni2indx_page2e[(wc>>4)-0x2e0]; + else if (wc >= 0x3400 && wc < 0x9fc0) + summary = &hkscs1999_uni2indx_page34[(wc>>4)-0x340]; + else if (wc >= 0xf900 && wc < 0xf910) + summary = &hkscs1999_uni2indx_pagef9[(wc>>4)-0xf90]; + else if (wc >= 0xff00 && wc < 0xfff0) + summary = &hkscs1999_uni2indx_pageff[(wc>>4)-0xff0]; + else if (wc >= 0x20000 && wc < 0x291f0) + summary = &hkscs1999_uni2indx_page200[(wc>>4)-0x2000]; + else if (wc >= 0x29400 && wc < 0x29600) + summary = &hkscs1999_uni2indx_page294[(wc>>4)-0x2940]; + else if (wc >= 0x29700 && wc < 0x2a6b0) + summary = &hkscs1999_uni2indx_page297[(wc>>4)-0x2970]; + else if (wc >= 0x2f800 && wc < 0x2f9e0) + summary = &hkscs1999_uni2indx_page2f8[(wc>>4)-0x2f80]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = hkscs1999_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/hkscs2001.h b/libs/libiconv/lib/hkscs2001.h new file mode 100644 index 00000000..66642cf9 --- /dev/null +++ b/libs/libiconv/lib/hkscs2001.h @@ -0,0 +1,683 @@ +/* + * Copyright (C) 1999-2006 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * HKSCS:2001 + */ + +static const unsigned short hkscs2001_2uni_page8c[123] = { + /* 0x8c */ + 0x0a3b, 0x1cfe, 0x5273, 0x37a6, 0x02c9, 0x2d8f, 0x414e, 0x1d77, + 0x12f5, 0x0620, 0x45cd, 0x0059, 0x4830, 0x1622, 0x4f32, 0x30a7, + 0x31f6, 0x1e91, 0x1819, 0x20ba, 0x3e81, 0x5307, 0x018b, 0x3a80, + 0x0610, 0x24e4, 0x2102, 0x0bae, 0x4d0f, 0x0409, 0x1a63, 0x54ba, + 0x0523, 0x2c0f, 0x38fd, 0x252a, 0x5147, 0x4fea, 0x3455, 0x1d4d, + 0x0c24, 0x3c7e, 0x33f4, 0x22d9, 0x4ee3, 0x37a7, 0x23dd, 0x08a3, + 0x09f0, 0x0abc, 0x082f, 0x0917, 0x37a8, 0x0d34, 0x288b, 0x0f92, + 0x0fd0, 0x3bb6, 0x1492, 0x1499, 0x15c2, 0x3d12, 0x178b, 0x3ff9, + 0x1919, 0x1a43, 0x4063, 0x1bff, 0x38fd, 0x1f00, 0x4205, 0x208c, + 0x03db, 0x4413, 0x1115, 0x21b9, 0x2e83, 0x47a4, 0x4695, 0x2593, + 0x26ec, 0x27c3, 0x296c, 0x2af8, 0x2b97, 0x37a9, 0x2d90, 0x37aa, + 0x2fb9, 0x37ab, 0x30cf, 0x2b5f, 0x36e0, 0x3221, 0x37ac, 0x50b9, + 0x393f, 0x0471, 0x05a2, 0x101a, 0x38fd, 0x38fd, 0x38fd, 0x3568, + 0x186b, 0x0576, 0x0e3d, 0x38fd, 0x2bd6, 0x437b, 0x2abf, 0x4c0d, + 0x0781, 0x4a74, 0x137b, 0x4915, 0x4bbe, 0x37ad, 0x37ae, 0x1196, + 0x37af, 0x38fd, 0x295b, +}; + +static const ucs4_t hkscs2001_2uni_upages[85] = { + 0x03500, 0x03c00, 0x03d00, 0x03e00, 0x04000, 0x04200, 0x04b00, 0x04c00, + 0x04e00, 0x04f00, 0x05000, 0x05100, 0x05300, 0x05400, 0x05700, 0x05800, + 0x05a00, 0x05b00, 0x05c00, 0x05d00, 0x05e00, 0x05f00, 0x06100, 0x06500, + 0x06700, 0x06900, 0x06a00, 0x06c00, 0x06d00, 0x07000, 0x07100, 0x07200, + 0x07300, 0x07400, 0x07600, 0x07700, 0x07800, 0x07a00, 0x07b00, 0x07c00, + 0x07d00, 0x07e00, 0x08200, 0x08500, 0x08600, 0x08800, 0x08b00, 0x08e00, + 0x08f00, 0x09100, 0x09200, 0x09300, 0x09700, 0x09800, 0x09900, 0x09f00, + 0x0ff00, 0x21400, 0x21900, 0x21d00, 0x22000, 0x22700, 0x23200, 0x23300, + 0x23c00, 0x24100, 0x24500, 0x24900, 0x24a00, 0x25100, 0x25600, 0x25c00, + 0x25d00, 0x26b00, 0x26d00, 0x26f00, 0x27100, 0x28700, 0x28900, 0x28a00, + 0x28d00, 0x29900, 0x29c00, 0x2a100, 0x2a200, +}; + +static int +hkscs2001_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 == 0x8c)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) { + unsigned int i = 157 * (c1 - 0x80) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); + ucs4_t wc = 0xfffd; + unsigned short swc; + { + if (i < 2007) + swc = hkscs2001_2uni_page8c[i-1884], + wc = hkscs2001_2uni_upages[swc>>8] | (swc & 0xff); + } + if (wc != 0xfffd) { + *pwc = wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short hkscs2001_2charset[116] = { + 0x8c4b, 0x8c56, 0x8c44, 0x8caa, 0x8c5d, 0x8cc3, 0x8c60, 0x8ccb, + 0x8cc4, 0x8c58, 0x8c49, 0x8cd2, 0x8c72, 0x8c6f, 0x8c73, 0x8c70, + 0x8c40, 0x8c71, 0x8c5b, 0x8c68, 0x8c75, 0x8ccc, 0x8c77, 0x8c78, + 0x8cc5, 0x8cac, 0x8cd9, 0x8c48, 0x8cd4, 0x8c7a, 0x8c7b, 0x8c7c, + 0x8c4d, 0x8c7e, 0x8c52, 0x8cca, 0x8ca2, 0x8ca3, 0x8c5e, 0x8ca5, + 0x8c41, 0x8c67, 0x8c47, 0x8c51, 0x8ca7, 0x8ca9, 0x8c53, 0x8c5a, + 0x8cad, 0x8c6b, 0x8c6e, 0x8c59, 0x8c63, 0x8cb1, 0x8cb2, 0x8cb3, + 0x8c76, 0x8cdc, 0x8cb4, 0x8cd0, 0x8cb5, 0x8cbd, 0x8cb6, 0x8cce, + 0x8c61, 0x8c45, 0x8cb8, 0x8cae, 0x8cba, 0x8c4f, 0x8cbc, 0x8c50, + 0x8cbf, 0x8c6a, 0x8c66, 0x8cc9, 0x8cbe, 0x8c43, 0x8c6d, 0x8c74, + 0x8cb7, 0x8cb9, 0x8cbb, 0x8cc0, 0x8cd7, 0x8cd8, 0x8cda, 0x8cc2, + 0x8c57, 0x8c79, 0x8c69, 0x8c7d, 0x8c54, 0x8ca1, 0x8ca4, 0x8c46, + 0x8ca8, 0x8ccf, 0x8cab, 0x8c4a, 0x8cb0, 0x8caf, 0x8c4c, 0x8cd5, + 0x8cd3, 0x8cd6, 0x8cd1, 0x8c5c, 0x8c6c, 0x8c4e, 0x8c65, 0x8cc1, + 0x8c64, 0x8c42, 0x8c55, 0x8c5f, +}; + +static const Summary16 hkscs2001_uni2indx_page35[6] = { + /* 0x3500 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0200 }, +}; +static const Summary16 hkscs2001_uni2indx_page3c[46] = { + /* 0x3c00 */ + { 1, 0x0000 }, { 1, 0x0000 }, { 1, 0x0000 }, { 1, 0x0000 }, + { 1, 0x0000 }, { 1, 0x0000 }, { 1, 0x0000 }, { 1, 0x0000 }, + { 1, 0x0800 }, { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, + { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, + /* 0x3d00 */ + { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, + { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, + { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, + { 2, 0x0200 }, { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, + /* 0x3e00 */ + { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, + { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, + { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, + { 3, 0x0000 }, { 3, 0x0800 }, +}; +static const Summary16 hkscs2001_uni2indx_page40[8] = { + /* 0x4000 */ + { 4, 0x0200 }, { 5, 0x0000 }, { 5, 0x0000 }, { 5, 0x0000 }, + { 5, 0x0000 }, { 5, 0x0000 }, { 5, 0x0000 }, { 5, 0x0002 }, +}; +static const Summary16 hkscs2001_uni2indx_page42[11] = { + /* 0x4200 */ + { 6, 0x0000 }, { 6, 0x0000 }, { 6, 0x0008 }, { 7, 0x0000 }, + { 7, 0x0000 }, { 7, 0x0000 }, { 7, 0x0000 }, { 7, 0x0040 }, + { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0004 }, +}; +static const Summary16 hkscs2001_uni2indx_page4b[25] = { + /* 0x4b00 */ + { 9, 0x0000 }, { 9, 0x0001 }, { 10, 0x0001 }, { 11, 0x0000 }, + { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, + { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, + { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, + /* 0x4c00 */ + { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, + { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, + { 11, 0x0002 }, +}; +static const Summary16 hkscs2001_uni2indx_page4e[59] = { + /* 0x4e00 */ + { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x8000 }, { 13, 0x0000 }, + { 13, 0x0000 }, { 13, 0x0000 }, { 13, 0x0000 }, { 13, 0x0000 }, + { 13, 0x0000 }, { 13, 0x0000 }, { 13, 0x0008 }, { 14, 0x0000 }, + { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, + /* 0x4f00 */ + { 14, 0x0000 }, { 14, 0x0080 }, { 15, 0x0000 }, { 15, 0x0000 }, + { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0000 }, + { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0000 }, + { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0001 }, + /* 0x5000 */ + { 16, 0x0000 }, { 16, 0x0000 }, { 16, 0x0000 }, { 16, 0x0800 }, + { 17, 0x0000 }, { 17, 0x0000 }, { 17, 0x0000 }, { 17, 0x0000 }, + { 17, 0x0000 }, { 17, 0x0000 }, { 17, 0x0000 }, { 17, 0x1000 }, + { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x0000 }, + /* 0x5100 */ + { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x0000 }, + { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x0000 }, + { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x4000 }, +}; +static const Summary16 hkscs2001_uni2indx_page53[20] = { + /* 0x5300 */ + { 19, 0x0000 }, { 19, 0x0000 }, { 19, 0x0010 }, { 20, 0x0000 }, + { 20, 0x0000 }, { 20, 0x0000 }, { 20, 0x0000 }, { 20, 0x0000 }, + { 20, 0x0000 }, { 20, 0x0000 }, { 20, 0x0000 }, { 20, 0x0000 }, + { 20, 0x0000 }, { 20, 0x0000 }, { 20, 0x0000 }, { 20, 0x0000 }, + /* 0x5400 */ + { 20, 0x0000 }, { 20, 0x0000 }, { 20, 0x0000 }, { 20, 0x0010 }, +}; +static const Summary16 hkscs2001_uni2indx_page57[30] = { + /* 0x5700 */ + { 21, 0x0000 }, { 21, 0x0000 }, { 21, 0x0000 }, { 21, 0x2000 }, + { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, + { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, + { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, + /* 0x5800 */ + { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, + { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, + { 22, 0x0000 }, { 22, 0x0004 }, { 23, 0x0000 }, { 23, 0x0000 }, + { 23, 0x0000 }, { 23, 0x0001 }, +}; +static const Summary16 hkscs2001_uni2indx_page5a[93] = { + /* 0x5a00 */ + { 24, 0x0000 }, { 24, 0x0400 }, { 25, 0x0000 }, { 25, 0x0000 }, + { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, + { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, + { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, + /* 0x5b00 */ + { 25, 0x0000 }, { 25, 0x0020 }, { 26, 0x0000 }, { 26, 0x0000 }, + { 26, 0x0000 }, { 26, 0x0000 }, { 26, 0x0000 }, { 26, 0x0000 }, + { 26, 0x0000 }, { 26, 0x0040 }, { 27, 0x0000 }, { 27, 0x0000 }, + { 27, 0x0000 }, { 27, 0x0000 }, { 27, 0x0000 }, { 27, 0x0000 }, + /* 0x5c00 */ + { 27, 0x0000 }, { 27, 0x0000 }, { 27, 0x0000 }, { 27, 0x0000 }, + { 27, 0x0000 }, { 27, 0x0000 }, { 27, 0x0000 }, { 27, 0x0000 }, + { 27, 0x0000 }, { 27, 0x0000 }, { 27, 0x0000 }, { 27, 0x0000 }, + { 27, 0x0000 }, { 27, 0x0000 }, { 27, 0x0000 }, { 27, 0x0020 }, + /* 0x5d00 */ + { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0000 }, + { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0800 }, + { 29, 0x0000 }, { 29, 0x0000 }, { 29, 0x0000 }, { 29, 0x0000 }, + { 29, 0x0000 }, { 29, 0x0000 }, { 29, 0x0000 }, { 29, 0x0000 }, + /* 0x5e00 */ + { 29, 0x0000 }, { 29, 0x0000 }, { 29, 0x0000 }, { 29, 0x0000 }, + { 29, 0x0000 }, { 29, 0x0000 }, { 29, 0x0000 }, { 29, 0x0000 }, + { 29, 0x0000 }, { 29, 0x0204 }, { 31, 0x0000 }, { 31, 0x0000 }, + { 31, 0x0000 }, { 31, 0x0000 }, { 31, 0x0000 }, { 31, 0x0000 }, + /* 0x5f00 */ + { 31, 0x0000 }, { 31, 0x0000 }, { 31, 0x0000 }, { 31, 0x0000 }, + { 31, 0x0000 }, { 31, 0x0000 }, { 31, 0x0000 }, { 31, 0x0000 }, + { 31, 0x0000 }, { 31, 0x0000 }, { 31, 0x0000 }, { 31, 0x0000 }, + { 31, 0x0004 }, +}; +static const Summary16 hkscs2001_uni2indx_page61[3] = { + /* 0x6100 */ + { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0004 }, +}; +static const Summary16 hkscs2001_uni2indx_page65[9] = { + /* 0x6500 */ + { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, + { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, + { 33, 0x0800 }, +}; +static const Summary16 hkscs2001_uni2indx_page67[7] = { + /* 0x6700 */ + { 34, 0x0000 }, { 34, 0x0200 }, { 35, 0x0000 }, { 35, 0x0000 }, + { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0800 }, +}; +static const Summary16 hkscs2001_uni2indx_page69[23] = { + /* 0x6900 */ + { 36, 0x0000 }, { 36, 0x0200 }, { 37, 0x0000 }, { 37, 0x0000 }, + { 37, 0x0000 }, { 37, 0x0000 }, { 37, 0x0000 }, { 37, 0x0000 }, + { 37, 0x0000 }, { 37, 0x0000 }, { 37, 0x0000 }, { 37, 0x0000 }, + { 37, 0x0000 }, { 37, 0x0000 }, { 37, 0x0000 }, { 37, 0x0000 }, + /* 0x6a00 */ + { 37, 0x0000 }, { 37, 0x0000 }, { 37, 0x0000 }, { 37, 0x0000 }, + { 37, 0x0008 }, { 38, 0x0000 }, { 38, 0x0008 }, +}; +static const Summary16 hkscs2001_uni2indx_page6c[32] = { + /* 0x6c00 */ + { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0000 }, + { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0000 }, + { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0000 }, + { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x8000 }, + /* 0x6d00 */ + { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0000 }, + { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0000 }, + { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0000 }, + { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x4000 }, +}; +static const Summary16 hkscs2001_uni2indx_page70[76] = { + /* 0x7000 */ + { 41, 0x0000 }, { 41, 0x0000 }, { 41, 0x0000 }, { 41, 0x0000 }, + { 41, 0x2000 }, { 42, 0x0000 }, { 42, 0x0000 }, { 42, 0x0080 }, + { 43, 0x0000 }, { 43, 0x0000 }, { 43, 0x0000 }, { 43, 0x0000 }, + { 43, 0x0000 }, { 43, 0x0000 }, { 43, 0x0000 }, { 43, 0x0000 }, + /* 0x7100 */ + { 43, 0x0000 }, { 43, 0x0000 }, { 43, 0x0000 }, { 43, 0x0000 }, + { 43, 0x0000 }, { 43, 0x0000 }, { 43, 0x0000 }, { 43, 0x0000 }, + { 43, 0x0000 }, { 43, 0x0002 }, { 44, 0x0000 }, { 44, 0x0000 }, + { 44, 0x0000 }, { 44, 0x0000 }, { 44, 0x0000 }, { 44, 0x0000 }, + /* 0x7200 */ + { 44, 0x0001 }, { 45, 0x0000 }, { 45, 0x0000 }, { 45, 0x0000 }, + { 45, 0x0000 }, { 45, 0x0000 }, { 45, 0x0000 }, { 45, 0x0000 }, + { 45, 0x0000 }, { 45, 0x0000 }, { 45, 0x0000 }, { 45, 0x0000 }, + { 45, 0x0000 }, { 45, 0x0000 }, { 45, 0x0000 }, { 45, 0x0000 }, + /* 0x7300 */ + { 45, 0x0000 }, { 45, 0x0000 }, { 45, 0x0000 }, { 45, 0x0000 }, + { 45, 0x0000 }, { 45, 0x0000 }, { 45, 0x0000 }, { 45, 0x0000 }, + { 45, 0x1000 }, { 46, 0x0000 }, { 46, 0x0000 }, { 46, 0x0400 }, + { 47, 0x0000 }, { 47, 0x0000 }, { 47, 0x0000 }, { 47, 0x0000 }, + /* 0x7400 */ + { 47, 0x0004 }, { 48, 0x0000 }, { 48, 0x0000 }, { 48, 0x0000 }, + { 48, 0x0000 }, { 48, 0x0000 }, { 48, 0x0000 }, { 48, 0x0000 }, + { 48, 0x0000 }, { 48, 0x0000 }, { 48, 0x0000 }, { 48, 0x0200 }, +}; +static const Summary16 hkscs2001_uni2indx_page76[47] = { + /* 0x7600 */ + { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, + { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, + { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, + { 49, 0x0000 }, { 49, 0x0200 }, { 50, 0x0000 }, { 50, 0x0000 }, + /* 0x7700 */ + { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, + { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, + { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, + { 50, 0x0000 }, { 50, 0x2000 }, { 51, 0x0000 }, { 51, 0x0000 }, + /* 0x7800 */ + { 51, 0x0000 }, { 51, 0x0000 }, { 51, 0x0000 }, { 51, 0x0000 }, + { 51, 0x0000 }, { 51, 0x0000 }, { 51, 0x0000 }, { 51, 0x0000 }, + { 51, 0x0000 }, { 51, 0x0000 }, { 51, 0x0000 }, { 51, 0x0000 }, + { 51, 0x0000 }, { 51, 0x0000 }, { 51, 0x0010 }, +}; +static const Summary16 hkscs2001_uni2indx_page7a[71] = { + /* 0x7a00 */ + { 52, 0x0000 }, { 52, 0x0000 }, { 52, 0x0400 }, { 53, 0x0000 }, + { 53, 0x0000 }, { 53, 0x0000 }, { 53, 0x0000 }, { 53, 0x0000 }, + { 53, 0x0000 }, { 53, 0x0008 }, { 54, 0x0000 }, { 54, 0x0000 }, + { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, + /* 0x7b00 */ + { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, + { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, + { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, + { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x1000 }, { 55, 0x0000 }, + /* 0x7c00 */ + { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0000 }, + { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0000 }, + { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0000 }, + { 55, 0x0008 }, { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0000 }, + /* 0x7d00 */ + { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0000 }, + { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0000 }, + { 56, 0x0800 }, { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, + { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, + /* 0x7e00 */ + { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, + { 57, 0x0000 }, { 57, 0x0800 }, { 58, 0x1000 }, +}; +static const Summary16 hkscs2001_uni2indx_page82[16] = { + /* 0x8200 */ + { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x0000 }, + { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x0000 }, + { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x8000 }, + { 60, 0x0000 }, { 60, 0x0000 }, { 60, 0x0000 }, { 60, 0x0100 }, +}; +static const Summary16 hkscs2001_uni2indx_page85[17] = { + /* 0x8500 */ + { 61, 0x0000 }, { 61, 0x0000 }, { 61, 0x0000 }, { 61, 0x0000 }, + { 61, 0x0000 }, { 61, 0x8000 }, { 62, 0x0000 }, { 62, 0x0000 }, + { 62, 0x0000 }, { 62, 0x0080 }, { 63, 0x0000 }, { 63, 0x0000 }, + { 63, 0x0000 }, { 63, 0x0040 }, { 64, 0x0000 }, { 64, 0x0000 }, + /* 0x8600 */ + { 64, 0x8000 }, +}; +static const Summary16 hkscs2001_uni2indx_page88[10] = { + /* 0x8800 */ + { 65, 0x0000 }, { 65, 0x0000 }, { 65, 0x0000 }, { 65, 0x0000 }, + { 65, 0x0000 }, { 65, 0x0000 }, { 65, 0x0000 }, { 65, 0x0000 }, + { 65, 0x8000 }, { 66, 0x0001 }, +}; +static const Summary16 hkscs2001_uni2indx_page8b[9] = { + /* 0x8b00 */ + { 67, 0x0000 }, { 67, 0x0000 }, { 67, 0x0000 }, { 67, 0x0000 }, + { 67, 0x0000 }, { 67, 0x0000 }, { 67, 0x0000 }, { 67, 0x0000 }, + { 67, 0x0008 }, +}; +static const Summary16 hkscs2001_uni2indx_page8e[29] = { + /* 0x8e00 */ + { 68, 0x0000 }, { 68, 0x0000 }, { 68, 0x0000 }, { 68, 0x0000 }, + { 68, 0x0000 }, { 68, 0x0000 }, { 68, 0x0000 }, { 68, 0x0000 }, + { 68, 0x0000 }, { 68, 0x0000 }, { 68, 0x0000 }, { 68, 0x0200 }, + { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0x0000 }, + /* 0x8f00 */ + { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0x0000 }, + { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0x0000 }, + { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0x0080 }, { 70, 0x0000 }, + { 70, 0x8000 }, +}; +static const Summary16 hkscs2001_uni2indx_page91[48] = { + /* 0x9100 */ + { 71, 0x0000 }, { 71, 0x0000 }, { 71, 0x0000 }, { 71, 0x0000 }, + { 71, 0x0000 }, { 71, 0x0000 }, { 71, 0x0000 }, { 71, 0x0000 }, + { 71, 0x0000 }, { 71, 0x0000 }, { 71, 0x0000 }, { 71, 0x0000 }, + { 71, 0x0000 }, { 71, 0x0000 }, { 71, 0x0000 }, { 71, 0x0040 }, + /* 0x9200 */ + { 72, 0x0000 }, { 72, 0x0000 }, { 72, 0x0002 }, { 73, 0x0000 }, + { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, + { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, + { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, + /* 0x9300 */ + { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, + { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, + { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, + { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0010 }, +}; +static const Summary16 hkscs2001_uni2indx_page97[47] = { + /* 0x9700 */ + { 74, 0x0000 }, { 74, 0x0000 }, { 74, 0x0000 }, { 74, 0x0000 }, + { 74, 0x0000 }, { 74, 0x0020 }, { 75, 0x0000 }, { 75, 0x0000 }, + { 75, 0x0000 }, { 75, 0x0000 }, { 75, 0x0000 }, { 75, 0x0000 }, + { 75, 0x0000 }, { 75, 0x0000 }, { 75, 0x0000 }, { 75, 0x0000 }, + /* 0x9800 */ + { 75, 0x0000 }, { 75, 0x0000 }, { 75, 0x0000 }, { 75, 0x0000 }, + { 75, 0x0000 }, { 75, 0x0000 }, { 75, 0x0100 }, { 76, 0x0000 }, + { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, + { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, + /* 0x9900 */ + { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, + { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, + { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, + { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0001 }, +}; +static const Summary16 hkscs2001_uni2indx_page9f[11] = { + /* 0x9f00 */ + { 77, 0x0000 }, { 77, 0x0000 }, { 77, 0x0000 }, { 77, 0x0000 }, + { 77, 0x0000 }, { 77, 0x0000 }, { 77, 0x0000 }, { 77, 0x0000 }, + { 77, 0x0000 }, { 77, 0x0000 }, { 77, 0xffc0 }, +}; +static const Summary16 hkscs2001_uni2indx_page214[4] = { + /* 0x21400 */ + { 87, 0x0000 }, { 87, 0x0000 }, { 87, 0x0000 }, { 87, 0x8000 }, +}; +static const Summary16 hkscs2001_uni2indx_page219[9] = { + /* 0x21900 */ + { 88, 0x0000 }, { 88, 0x0000 }, { 88, 0x0000 }, { 88, 0x0000 }, + { 88, 0x0000 }, { 88, 0x0000 }, { 88, 0x0000 }, { 88, 0x0000 }, + { 88, 0x0001 }, +}; +static const Summary16 hkscs2001_uni2indx_page21d[12] = { + /* 0x21d00 */ + { 89, 0x0000 }, { 89, 0x0000 }, { 89, 0x0000 }, { 89, 0x0000 }, + { 89, 0x0000 }, { 89, 0x0000 }, { 89, 0x0000 }, { 89, 0x0000 }, + { 89, 0x0000 }, { 89, 0x0000 }, { 89, 0x0000 }, { 89, 0x0040 }, +}; +static const Summary16 hkscs2001_uni2indx_page220[8] = { + /* 0x22000 */ + { 90, 0x0000 }, { 90, 0x0000 }, { 90, 0x0000 }, { 90, 0x0000 }, + { 90, 0x0000 }, { 90, 0x0000 }, { 90, 0x0000 }, { 90, 0x4000 }, +}; +static const Summary16 hkscs2001_uni2indx_page227[2] = { + /* 0x22700 */ + { 91, 0x0000 }, { 91, 0x0004 }, +}; +static const Summary16 hkscs2001_uni2indx_page232[32] = { + /* 0x23200 */ + { 92, 0x0000 }, { 92, 0x0000 }, { 92, 0x0000 }, { 92, 0x0000 }, + { 92, 0x0000 }, { 92, 0x0000 }, { 92, 0x0000 }, { 92, 0x0000 }, + { 92, 0x0002 }, { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0000 }, + { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0000 }, + /* 0x23300 */ + { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0000 }, + { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0000 }, + { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0000 }, + { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0200 }, +}; +static const Summary16 hkscs2001_uni2indx_page23c[7] = { + /* 0x23c00 */ + { 94, 0x0000 }, { 94, 0x0000 }, { 94, 0x0000 }, { 94, 0x0000 }, + { 94, 0x0000 }, { 94, 0x0000 }, { 94, 0x0008 }, +}; +static const Summary16 hkscs2001_uni2indx_page241[5] = { + /* 0x24100 */ + { 95, 0x0000 }, { 95, 0x0000 }, { 95, 0x0000 }, { 95, 0x0000 }, + { 95, 0x4000 }, +}; +static const Summary16 hkscs2001_uni2indx_page245[1] = { + /* 0x24500 */ + { 96, 0x0020 }, +}; +static const Summary16 hkscs2001_uni2indx_page249[18] = { + /* 0x24900 */ + { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x0000 }, + { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x0800 }, + { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x0000 }, + { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x0000 }, + /* 0x24a00 */ + { 98, 0x0000 }, { 98, 0x0008 }, +}; +static const Summary16 hkscs2001_uni2indx_page251[13] = { + /* 0x25100 */ + { 99, 0x0000 }, { 99, 0x0000 }, { 99, 0x0000 }, { 99, 0x0000 }, + { 99, 0x0000 }, { 99, 0x0000 }, { 99, 0x0000 }, { 99, 0x0000 }, + { 99, 0x0000 }, { 99, 0x0000 }, { 99, 0x0000 }, { 99, 0x0000 }, + { 99, 0x2000 }, +}; +static const Summary16 hkscs2001_uni2indx_page256[10] = { + /* 0x25600 */ + { 100, 0x0000 }, { 100, 0x0000 }, { 100, 0x0000 }, { 100, 0x0000 }, + { 100, 0x0000 }, { 100, 0x0000 }, { 100, 0x0000 }, { 100, 0x0000 }, + { 100, 0x0000 }, { 100, 0x0020 }, +}; +static const Summary16 hkscs2001_uni2indx_page25c[20] = { + /* 0x25c00 */ + { 101, 0x0000 }, { 101, 0x0000 }, { 101, 0x0000 }, { 101, 0x0000 }, + { 101, 0x0000 }, { 101, 0x0000 }, { 101, 0x0000 }, { 101, 0x0000 }, + { 101, 0x0000 }, { 101, 0x0000 }, { 101, 0x0010 }, { 102, 0x0000 }, + { 102, 0x0000 }, { 102, 0x0000 }, { 102, 0x0000 }, { 102, 0x0000 }, + /* 0x25d00 */ + { 102, 0x0000 }, { 102, 0x0000 }, { 102, 0x0000 }, { 102, 0x0001 }, +}; +static const Summary16 hkscs2001_uni2indx_page26b[2] = { + /* 0x26b00 */ + { 103, 0x0000 }, { 103, 0x0020 }, +}; +static const Summary16 hkscs2001_uni2indx_page26d[8] = { + /* 0x26d00 */ + { 104, 0x0000 }, { 104, 0x0000 }, { 104, 0x0000 }, { 104, 0x0000 }, + { 104, 0x0000 }, { 104, 0x0000 }, { 104, 0x0000 }, { 104, 0x0010 }, +}; +static const Summary16 hkscs2001_uni2indx_page26f[12] = { + /* 0x26f00 */ + { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x0000 }, + { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x0000 }, + { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x4000 }, +}; +static const Summary16 hkscs2001_uni2indx_page271[1] = { + /* 0x27100 */ + { 106, 0x2000 }, +}; +static const Summary16 hkscs2001_uni2indx_page287[1] = { + /* 0x28700 */ + { 107, 0x8000 }, +}; +static const Summary16 hkscs2001_uni2indx_page289[31] = { + /* 0x28900 */ + { 108, 0x0000 }, { 108, 0x0000 }, { 108, 0x0000 }, { 108, 0x0000 }, + { 108, 0x0000 }, { 108, 0x0000 }, { 108, 0x0000 }, { 108, 0x0000 }, + { 108, 0x0000 }, { 108, 0x0000 }, { 108, 0x0000 }, { 108, 0x0000 }, + { 108, 0x0000 }, { 108, 0x0000 }, { 108, 0x0008 }, { 109, 0x0000 }, + /* 0x28a00 */ + { 109, 0x0000 }, { 109, 0x0000 }, { 109, 0x0000 }, { 109, 0x0004 }, + { 110, 0x0000 }, { 110, 0x0000 }, { 110, 0x0000 }, { 110, 0x0000 }, + { 110, 0x0000 }, { 110, 0x0000 }, { 110, 0x0000 }, { 110, 0x0000 }, + { 110, 0x0000 }, { 110, 0x0000 }, { 110, 0x0400 }, +}; +static const Summary16 hkscs2001_uni2indx_page28d[12] = { + /* 0x28d00 */ + { 111, 0x0000 }, { 111, 0x0000 }, { 111, 0x0000 }, { 111, 0x0000 }, + { 111, 0x0000 }, { 111, 0x0000 }, { 111, 0x0000 }, { 111, 0x0000 }, + { 111, 0x0000 }, { 111, 0x0000 }, { 111, 0x0000 }, { 111, 0x0200 }, +}; +static const Summary16 hkscs2001_uni2indx_page299[5] = { + /* 0x29900 */ + { 112, 0x0000 }, { 112, 0x0000 }, { 112, 0x0000 }, { 112, 0x0000 }, + { 112, 0x0080 }, +}; +static const Summary16 hkscs2001_uni2indx_page29c[8] = { + /* 0x29c00 */ + { 113, 0x0000 }, { 113, 0x0000 }, { 113, 0x0000 }, { 113, 0x0000 }, + { 113, 0x0000 }, { 113, 0x0000 }, { 113, 0x0000 }, { 113, 0x0008 }, +}; +static const Summary16 hkscs2001_uni2indx_page2a1[28] = { + /* 0x2a100 */ + { 114, 0x0080 }, { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0000 }, + { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0000 }, + { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0000 }, + { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0000 }, + /* 0x2a200 */ + { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0000 }, + { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0000 }, + { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0400 }, +}; + +static int +hkscs2001_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc < 0x9f00) { + if (wc < 0x6900) { + if (wc >= 0x3500 && wc < 0x3560) + summary = &hkscs2001_uni2indx_page35[(wc>>4)-0x350]; + else if (wc >= 0x3c00 && wc < 0x3ee0) + summary = &hkscs2001_uni2indx_page3c[(wc>>4)-0x3c0]; + else if (wc >= 0x4000 && wc < 0x4080) + summary = &hkscs2001_uni2indx_page40[(wc>>4)-0x400]; + else if (wc >= 0x4200 && wc < 0x42b0) + summary = &hkscs2001_uni2indx_page42[(wc>>4)-0x420]; + else if (wc >= 0x4b00 && wc < 0x4c90) + summary = &hkscs2001_uni2indx_page4b[(wc>>4)-0x4b0]; + else if (wc >= 0x4e00 && wc < 0x51b0) + summary = &hkscs2001_uni2indx_page4e[(wc>>4)-0x4e0]; + else if (wc >= 0x5300 && wc < 0x5440) + summary = &hkscs2001_uni2indx_page53[(wc>>4)-0x530]; + else if (wc >= 0x5700 && wc < 0x58e0) + summary = &hkscs2001_uni2indx_page57[(wc>>4)-0x570]; + else if (wc >= 0x5a00 && wc < 0x5fd0) + summary = &hkscs2001_uni2indx_page5a[(wc>>4)-0x5a0]; + else if (wc >= 0x6100 && wc < 0x6130) + summary = &hkscs2001_uni2indx_page61[(wc>>4)-0x610]; + else if (wc >= 0x6500 && wc < 0x6590) + summary = &hkscs2001_uni2indx_page65[(wc>>4)-0x650]; + else if (wc >= 0x6700 && wc < 0x6770) + summary = &hkscs2001_uni2indx_page67[(wc>>4)-0x670]; + } else { + if (wc >= 0x6900 && wc < 0x6a70) + summary = &hkscs2001_uni2indx_page69[(wc>>4)-0x690]; + else if (wc >= 0x6c00 && wc < 0x6e00) + summary = &hkscs2001_uni2indx_page6c[(wc>>4)-0x6c0]; + else if (wc >= 0x7000 && wc < 0x74c0) + summary = &hkscs2001_uni2indx_page70[(wc>>4)-0x700]; + else if (wc >= 0x7600 && wc < 0x78f0) + summary = &hkscs2001_uni2indx_page76[(wc>>4)-0x760]; + else if (wc >= 0x7a00 && wc < 0x7e70) + summary = &hkscs2001_uni2indx_page7a[(wc>>4)-0x7a0]; + else if (wc >= 0x8200 && wc < 0x8300) + summary = &hkscs2001_uni2indx_page82[(wc>>4)-0x820]; + else if (wc >= 0x8500 && wc < 0x8610) + summary = &hkscs2001_uni2indx_page85[(wc>>4)-0x850]; + else if (wc >= 0x8800 && wc < 0x88a0) + summary = &hkscs2001_uni2indx_page88[(wc>>4)-0x880]; + else if (wc >= 0x8b00 && wc < 0x8b90) + summary = &hkscs2001_uni2indx_page8b[(wc>>4)-0x8b0]; + else if (wc >= 0x8e00 && wc < 0x8fd0) + summary = &hkscs2001_uni2indx_page8e[(wc>>4)-0x8e0]; + else if (wc >= 0x9100 && wc < 0x9400) + summary = &hkscs2001_uni2indx_page91[(wc>>4)-0x910]; + else if (wc >= 0x9700 && wc < 0x99f0) + summary = &hkscs2001_uni2indx_page97[(wc>>4)-0x970]; + } + } else { + if (wc < 0x25600) { + if (wc >= 0x9f00 && wc < 0x9fb0) + summary = &hkscs2001_uni2indx_page9f[(wc>>4)-0x9f0]; + else if (wc >= 0x21400 && wc < 0x21440) + summary = &hkscs2001_uni2indx_page214[(wc>>4)-0x2140]; + else if (wc >= 0x21900 && wc < 0x21990) + summary = &hkscs2001_uni2indx_page219[(wc>>4)-0x2190]; + else if (wc >= 0x21d00 && wc < 0x21dc0) + summary = &hkscs2001_uni2indx_page21d[(wc>>4)-0x21d0]; + else if (wc >= 0x22000 && wc < 0x22080) + summary = &hkscs2001_uni2indx_page220[(wc>>4)-0x2200]; + else if (wc >= 0x22700 && wc < 0x22720) + summary = &hkscs2001_uni2indx_page227[(wc>>4)-0x2270]; + else if (wc >= 0x23200 && wc < 0x23400) + summary = &hkscs2001_uni2indx_page232[(wc>>4)-0x2320]; + else if (wc >= 0x23c00 && wc < 0x23c70) + summary = &hkscs2001_uni2indx_page23c[(wc>>4)-0x23c0]; + else if (wc >= 0x24100 && wc < 0x24150) + summary = &hkscs2001_uni2indx_page241[(wc>>4)-0x2410]; + else if (wc >= 0x24500 && wc < 0x24510) + summary = &hkscs2001_uni2indx_page245[(wc>>4)-0x2450]; + else if (wc >= 0x24900 && wc < 0x24a20) + summary = &hkscs2001_uni2indx_page249[(wc>>4)-0x2490]; + else if (wc >= 0x25100 && wc < 0x251d0) + summary = &hkscs2001_uni2indx_page251[(wc>>4)-0x2510]; + } else { + if (wc >= 0x25600 && wc < 0x256a0) + summary = &hkscs2001_uni2indx_page256[(wc>>4)-0x2560]; + else if (wc >= 0x25c00 && wc < 0x25d40) + summary = &hkscs2001_uni2indx_page25c[(wc>>4)-0x25c0]; + else if (wc >= 0x26b00 && wc < 0x26b20) + summary = &hkscs2001_uni2indx_page26b[(wc>>4)-0x26b0]; + else if (wc >= 0x26d00 && wc < 0x26d80) + summary = &hkscs2001_uni2indx_page26d[(wc>>4)-0x26d0]; + else if (wc >= 0x26f00 && wc < 0x26fc0) + summary = &hkscs2001_uni2indx_page26f[(wc>>4)-0x26f0]; + else if (wc >= 0x27100 && wc < 0x27110) + summary = &hkscs2001_uni2indx_page271[(wc>>4)-0x2710]; + else if (wc >= 0x28700 && wc < 0x28710) + summary = &hkscs2001_uni2indx_page287[(wc>>4)-0x2870]; + else if (wc >= 0x28900 && wc < 0x28af0) + summary = &hkscs2001_uni2indx_page289[(wc>>4)-0x2890]; + else if (wc >= 0x28d00 && wc < 0x28dc0) + summary = &hkscs2001_uni2indx_page28d[(wc>>4)-0x28d0]; + else if (wc >= 0x29900 && wc < 0x29950) + summary = &hkscs2001_uni2indx_page299[(wc>>4)-0x2990]; + else if (wc >= 0x29c00 && wc < 0x29c80) + summary = &hkscs2001_uni2indx_page29c[(wc>>4)-0x29c0]; + else if (wc >= 0x2a100 && wc < 0x2a2c0) + summary = &hkscs2001_uni2indx_page2a1[(wc>>4)-0x2a10]; + } + } + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = hkscs2001_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/hkscs2004.h b/libs/libiconv/lib/hkscs2004.h new file mode 100644 index 00000000..d5ab9974 --- /dev/null +++ b/libs/libiconv/lib/hkscs2004.h @@ -0,0 +1,679 @@ +/* + * Copyright (C) 1999-2006 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * HKSCS:2004 + */ + +static const unsigned short hkscs2004_2uni_page87[58] = { + /* 0x87 */ + 0x0af0, 0x1032, 0x0d03, 0x0ca6, 0x0c78, 0x4167, 0x1177, 0x0cb3, + 0x44b1, 0x10e2, 0x44c5, 0x0595, 0x0e36, 0x0e44, 0x1047, 0x1040, + 0x39bf, 0x3417, 0x4252, 0x3f8b, 0x40d2, 0x1057, 0x4d51, 0x0e4f, + 0x0cda, 0x1085, 0x446c, 0x1107, 0x0fa4, 0x0da1, 0x3d23, 0x1e25, + 0x3c54, 0x2d63, 0x3606, 0x3761, 0x1a4d, 0x13fb, 0x28fd, 0x2195, + 0x141d, 0x47b9, 0x06f4, 0x2534, 0x43ef, 0x16db, 0x2e5e, 0x15a4, + 0x0125, 0x4bb0, 0x15d1, 0x16b7, 0x17fc, 0x1b6e, 0x2393, 0x4a45, + 0x1f61, 0x1f9d, +}; +static const unsigned short hkscs2004_2uni_page8c[189] = { + /* 0x8c */ + 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x28fd, 0x2b6f, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, 0x28fd, + 0x28fd, 0x1ae7, 0x28fd, 0x1c57, 0x20ca, 0x0688, 0x0bc3, 0x3256, + 0x3196, 0x0a9a, 0x0c36, 0x28fd, 0x17d5, 0x351a, 0x24f9, 0x1778, + 0x0612, 0x3351, 0x1878, 0x27b2, 0x1d57, 0x0c58, 0x38ec, 0x2f23, + 0x1077, 0x0478, 0x004a, 0x29a4, 0x3e41, 0x24cc, 0x12b4, 0x2a39, + 0x14bf, 0x226c, 0x2656, 0x49fa, 0x193b, + /* 0x8d */ + 0x2c9f, 0x28fd, 0x30c1, 0x466d, 0x0902, 0x0dbb, 0x4879, 0x0707, + 0x27b3, 0x4cb5, 0x08f8, 0x02d6, 0x0df7, 0x3e46, 0x097c, 0x45b2, + 0x42ff, 0x0c6d, 0x03d4, 0x3b9a, 0x0c61, 0x0c1b, 0x1189, 0x107b, + 0x1176, 0x0cea, 0x07c8, 0x3a0f, 0x0161, 0x0bde, 0x0bbd, 0x09ed, +}; + +static const ucs4_t hkscs2004_2uni_upages[78] = { + 0x03400, 0x03600, 0x03700, 0x03800, 0x03900, 0x03b00, 0x03d00, 0x03f00, + 0x04000, 0x04100, 0x04300, 0x04400, 0x04500, 0x04600, 0x04700, 0x04a00, + 0x04c00, 0x04d00, 0x04f00, 0x05600, 0x05900, 0x05a00, 0x05b00, 0x05c00, + 0x05d00, 0x05f00, 0x06600, 0x06700, 0x06e00, 0x07100, 0x07200, 0x07400, + 0x07900, 0x07d00, 0x08100, 0x08500, 0x08a00, 0x09700, 0x09800, 0x09f00, + 0x0ff00, 0x20100, 0x20200, 0x20a00, 0x20b00, 0x21a00, 0x21d00, 0x21e00, + 0x22100, 0x22700, 0x23200, 0x23500, 0x23600, 0x23b00, 0x23e00, 0x23f00, + 0x24000, 0x24200, 0x24b00, 0x25400, 0x25a00, 0x26b00, 0x26c00, 0x26e00, + 0x27000, 0x27200, 0x27300, 0x27b00, 0x27c00, 0x28600, 0x28900, 0x28b00, + 0x29000, 0x29800, 0x29900, 0x29e00, 0x2a100, 0x2a300, +}; + +static int +hkscs2004_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 == 0x87) || (c1 >= 0x8c && c1 <= 0x8d)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) { + unsigned int i = 157 * (c1 - 0x80) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); + ucs4_t wc = 0xfffd; + unsigned short swc; + if (i < 1884) { + if (i < 1157) + swc = hkscs2004_2uni_page87[i-1099], + wc = hkscs2004_2uni_upages[swc>>8] | (swc & 0xff); + } else { + if (i < 2073) + swc = hkscs2004_2uni_page8c[i-1884], + wc = hkscs2004_2uni_upages[swc>>8] | (swc & 0xff); + } + if (wc != 0xfffd) { + *pwc = wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short hkscs2004_2charset[123] = { + 0x8cf4, 0x8770, 0x8d5c, 0x8d4b, 0x8d52, 0x8cf3, 0x874b, 0x8cea, + 0x8cdf, 0x876a, 0x8d47, 0x8d5a, 0x8d4a, 0x8d44, 0x8d4e, 0x8d5f, + 0x8ce3, 0x8740, 0x8d5e, 0x8ce0, 0x8d5d, 0x8d55, 0x8ce4, 0x8cef, + 0x8d54, 0x8d51, 0x8744, 0x8743, 0x8747, 0x8758, 0x8d59, 0x8742, + 0x875d, 0x8d45, 0x8d4c, 0x874c, 0x874d, 0x8757, 0x875c, 0x8741, + 0x874f, 0x874e, 0x8755, 0x8cf2, 0x8d57, 0x8759, 0x8749, 0x875b, + 0x8d58, 0x8746, 0x8d56, 0x8cf8, 0x8765, 0x8768, 0x8cfa, 0x876f, + 0x8772, 0x8773, 0x876d, 0x8ce9, 0x8ce6, 0x8774, 0x8cec, 0x8cfe, + 0x8764, 0x8cdb, 0x8775, 0x8cdd, 0x8cee, 0x875f, 0x8778, 0x8779, + 0x8cde, 0x8767, 0x8cfb, 0x8776, 0x8cf7, 0x8ce8, 0x876b, 0x8cfc, + 0x8ced, 0x8d48, 0x8cf5, 0x8cf9, 0x8c62, 0x8d40, 0x8761, 0x876e, + 0x8cf1, 0x8d42, 0x8ce2, 0x8ce1, 0x8ceb, 0x8751, 0x8ce7, 0x8762, + 0x8763, 0x8cf0, 0x8750, 0x8d5b, 0x8d53, 0x8760, 0x875e, 0x8cf6, + 0x8d4d, 0x8753, 0x8754, 0x8745, 0x8752, 0x8d50, 0x876c, 0x875a, + 0x8748, 0x874a, 0x8d4f, 0x8d43, 0x8769, 0x8d46, 0x8cfd, 0x8777, + 0x8771, 0x8d49, 0x8756, +}; + +static const Summary16 hkscs2004_uni2indx_page34[5] = { + /* 0x3400 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0400 }, +}; +static const Summary16 hkscs2004_uni2indx_page36[56] = { + /* 0x3600 */ + { 1, 0x0000 }, { 1, 0x0000 }, { 1, 0x0020 }, { 2, 0x0000 }, + { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0002 }, { 3, 0x0000 }, + { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, + { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, + /* 0x3700 */ + { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, + { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, + { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, + { 3, 0x0000 }, { 3, 0x0040 }, { 4, 0x0000 }, { 4, 0x0000 }, + /* 0x3800 */ + { 4, 0x0000 }, { 4, 0x0000 }, { 4, 0x0000 }, { 4, 0x0000 }, + { 4, 0x0000 }, { 4, 0x0000 }, { 4, 0x0000 }, { 4, 0x0000 }, + { 4, 0x0000 }, { 4, 0x0000 }, { 4, 0x0000 }, { 4, 0x0000 }, + { 4, 0x0000 }, { 4, 0x0010 }, { 5, 0x0000 }, { 5, 0x0000 }, + /* 0x3900 */ + { 5, 0x0000 }, { 5, 0x0000 }, { 5, 0x0000 }, { 5, 0x0000 }, + { 5, 0x0000 }, { 5, 0x0000 }, { 5, 0x0000 }, { 5, 0x0100 }, +}; +static const Summary16 hkscs2004_uni2indx_page3b[10] = { + /* 0x3b00 */ + { 6, 0x0000 }, { 6, 0x0000 }, { 6, 0x0000 }, { 6, 0x0000 }, + { 6, 0x0000 }, { 6, 0x0000 }, { 6, 0x0000 }, { 6, 0x0000 }, + { 6, 0x0000 }, { 6, 0x0020 }, +}; +static const Summary16 hkscs2004_uni2indx_page3d[16] = { + /* 0x3d00 */ + { 7, 0x0000 }, { 7, 0x0004 }, { 8, 0x0000 }, { 8, 0x0000 }, + { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, + { 8, 0x0100 }, { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, + { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0010 }, +}; +static const Summary16 hkscs2004_uni2indx_page3f[47] = { + /* 0x3f00 */ + { 10, 0x0080 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, + { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, + { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, + { 11, 0x0100 }, { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0000 }, + /* 0x4000 */ + { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0000 }, + { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0000 }, + { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0000 }, + { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0100 }, + /* 0x4100 */ + { 13, 0x0004 }, { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, + { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x1000 }, + { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0000 }, + { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x2000 }, +}; +static const Summary16 hkscs2004_uni2indx_page43[69] = { + /* 0x4300 */ + { 16, 0x0000 }, { 16, 0x0000 }, { 16, 0x0000 }, { 16, 0x0000 }, + { 16, 0x0000 }, { 16, 0x0000 }, { 16, 0x0000 }, { 16, 0x0000 }, + { 16, 0x0000 }, { 16, 0x0400 }, { 17, 0x0000 }, { 17, 0x0000 }, + { 17, 0x0000 }, { 17, 0x0000 }, { 17, 0x0000 }, { 17, 0x0001 }, + /* 0x4400 */ + { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x0000 }, + { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x0000 }, + { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x2000 }, + { 19, 0x0008 }, { 20, 0x4000 }, { 21, 0x0000 }, { 21, 0x0000 }, + /* 0x4500 */ + { 21, 0x0000 }, { 21, 0x0800 }, { 22, 0x0000 }, { 22, 0x0040 }, + { 23, 0x0000 }, { 23, 0x0100 }, { 24, 0x2002 }, { 26, 0x0100 }, + { 27, 0x0000 }, { 27, 0x0000 }, { 27, 0x0040 }, { 28, 0x0008 }, + { 29, 0x0000 }, { 29, 0x0400 }, { 30, 0x0400 }, { 31, 0x0000 }, + /* 0x4600 */ + { 31, 0x0008 }, { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0000 }, + { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0000 }, + { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0002 }, { 33, 0x0800 }, + { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0080 }, + /* 0x4700 */ + { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0040 }, + { 36, 0x8010 }, +}; +static const Summary16 hkscs2004_uni2indx_page4a[11] = { + /* 0x4a00 */ + { 38, 0x0000 }, { 38, 0x0000 }, { 38, 0x0000 }, { 38, 0x0000 }, + { 38, 0x0000 }, { 38, 0x0000 }, { 38, 0x0000 }, { 38, 0x0000 }, + { 38, 0x0000 }, { 38, 0x0000 }, { 38, 0x0010 }, +}; +static const Summary16 hkscs2004_uni2indx_page4c[25] = { + /* 0x4c00 */ + { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x0004 }, + { 40, 0x0081 }, { 42, 0x0080 }, { 43, 0x0000 }, { 43, 0x0880 }, + { 45, 0x0020 }, { 46, 0x0000 }, { 46, 0x0000 }, { 46, 0x0000 }, + { 46, 0x0000 }, { 46, 0x0000 }, { 46, 0x0004 }, { 47, 0x0000 }, + /* 0x4d00 */ + { 47, 0x0080 }, { 48, 0x0000 }, { 48, 0x0000 }, { 48, 0x0000 }, + { 48, 0x0000 }, { 48, 0x0000 }, { 48, 0x0000 }, { 48, 0x00c0 }, + { 50, 0x0200 }, +}; +static const Summary16 hkscs2004_uni2indx_page4f[12] = { + /* 0x4f00 */ + { 51, 0x0000 }, { 51, 0x0000 }, { 51, 0x0000 }, { 51, 0x0000 }, + { 51, 0x0000 }, { 51, 0x0000 }, { 51, 0x0000 }, { 51, 0x0000 }, + { 51, 0x0000 }, { 51, 0x0000 }, { 51, 0x0000 }, { 51, 0x0010 }, +}; +static const Summary16 hkscs2004_uni2indx_page56[16] = { + /* 0x5600 */ + { 52, 0x0000 }, { 52, 0x0000 }, { 52, 0x0000 }, { 52, 0x0000 }, + { 52, 0x0000 }, { 52, 0x0000 }, { 52, 0x0000 }, { 52, 0x0000 }, + { 52, 0x0000 }, { 52, 0x0000 }, { 52, 0x0000 }, { 52, 0x0000 }, + { 52, 0x0000 }, { 52, 0x0000 }, { 52, 0x0000 }, { 52, 0x0800 }, +}; +static const Summary16 hkscs2004_uni2indx_page59[72] = { + /* 0x5900 */ + { 53, 0x0000 }, { 53, 0x2000 }, { 54, 0x0000 }, { 54, 0x0000 }, + { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, + { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x8000 }, + { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0000 }, + /* 0x5a00 */ + { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0000 }, + { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0000 }, + { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0010 }, { 56, 0x0000 }, + { 56, 0x0000 }, { 56, 0x0002 }, { 57, 0x0000 }, { 57, 0x0000 }, + /* 0x5b00 */ + { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, + { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, + { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0080 }, + { 58, 0x0000 }, { 58, 0x0800 }, { 59, 0x0000 }, { 59, 0x0000 }, + /* 0x5c00 */ + { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x0000 }, + { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x0100 }, + { 60, 0x0000 }, { 60, 0x0000 }, { 60, 0x0000 }, { 60, 0x0000 }, + { 60, 0x0000 }, { 60, 0x0020 }, { 61, 0x0000 }, { 61, 0x1000 }, + /* 0x5d00 */ + { 62, 0x0000 }, { 62, 0x0000 }, { 62, 0x0000 }, { 62, 0x0000 }, + { 62, 0x0000 }, { 62, 0x0000 }, { 62, 0x0000 }, { 62, 0x0100 }, +}; +static const Summary16 hkscs2004_uni2indx_page5f[4] = { + /* 0x5f00 */ + { 63, 0x0000 }, { 63, 0x0000 }, { 63, 0x0000 }, { 63, 0x0800 }, +}; +static const Summary16 hkscs2004_uni2indx_page66[23] = { + /* 0x6600 */ + { 64, 0x0000 }, { 64, 0x0000 }, { 64, 0x0000 }, { 64, 0x0000 }, + { 64, 0x2000 }, { 65, 0x0000 }, { 65, 0x0000 }, { 65, 0x0000 }, + { 65, 0x0000 }, { 65, 0x0000 }, { 65, 0x0000 }, { 65, 0x0000 }, + { 65, 0x0000 }, { 65, 0x0000 }, { 65, 0x0080 }, { 66, 0x0000 }, + /* 0x6700 */ + { 66, 0x0000 }, { 66, 0x0000 }, { 66, 0x0000 }, { 66, 0x0000 }, + { 66, 0x0000 }, { 66, 0x0000 }, { 66, 0x4000 }, +}; +static const Summary16 hkscs2004_uni2indx_page6e[6] = { + /* 0x6e00 */ + { 67, 0x0000 }, { 67, 0x0000 }, { 67, 0x0000 }, { 67, 0x0000 }, + { 67, 0x0000 }, { 67, 0x0080 }, +}; +static const Summary16 hkscs2004_uni2indx_page71[19] = { + /* 0x7100 */ + { 68, 0x0000 }, { 68, 0x0000 }, { 68, 0x0000 }, { 68, 0x0000 }, + { 68, 0x0000 }, { 68, 0x0080 }, { 69, 0x0000 }, { 69, 0x0000 }, + { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0x0000 }, + { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0x0000 }, + /* 0x7200 */ + { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0x0020 }, +}; +static const Summary16 hkscs2004_uni2indx_page74[10] = { + /* 0x7400 */ + { 70, 0x0000 }, { 70, 0x0000 }, { 70, 0x0000 }, { 70, 0x0000 }, + { 70, 0x0000 }, { 70, 0x0000 }, { 70, 0x0002 }, { 71, 0x0000 }, + { 71, 0x0000 }, { 71, 0x2000 }, +}; +static const Summary16 hkscs2004_uni2indx_page79[13] = { + /* 0x7900 */ + { 72, 0x0000 }, { 72, 0x0000 }, { 72, 0x0000 }, { 72, 0x0000 }, + { 72, 0x0000 }, { 72, 0x0000 }, { 72, 0x0000 }, { 72, 0x0000 }, + { 72, 0x0000 }, { 72, 0x0000 }, { 72, 0x0000 }, { 72, 0x0000 }, + { 72, 0x0400 }, +}; +static const Summary16 hkscs2004_uni2indx_page7d[10] = { + /* 0x7d00 */ + { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, + { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, { 73, 0x0000 }, + { 73, 0x0000 }, { 73, 0x0020 }, +}; +static const Summary16 hkscs2004_uni2indx_page81[7] = { + /* 0x8100 */ + { 74, 0x0000 }, { 74, 0x0000 }, { 74, 0x0000 }, { 74, 0x0000 }, + { 74, 0x0000 }, { 74, 0x0000 }, { 74, 0x1000 }, +}; +static const Summary16 hkscs2004_uni2indx_page85[10] = { + /* 0x8500 */ + { 75, 0x0000 }, { 75, 0x0000 }, { 75, 0x0000 }, { 75, 0x0000 }, + { 75, 0x0000 }, { 75, 0x0000 }, { 75, 0x0000 }, { 75, 0x0000 }, + { 75, 0x0000 }, { 75, 0x0008 }, +}; +static const Summary16 hkscs2004_uni2indx_page8a[16] = { + /* 0x8a00 */ + { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, + { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, + { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, { 76, 0x0000 }, + { 76, 0x1000 }, { 77, 0x0000 }, { 77, 0x0000 }, { 77, 0x0200 }, +}; +static const Summary16 hkscs2004_uni2indx_page97[22] = { + /* 0x9700 */ + { 78, 0x0000 }, { 78, 0x0000 }, { 78, 0x0000 }, { 78, 0x0010 }, + { 79, 0x0000 }, { 79, 0x0000 }, { 79, 0x0000 }, { 79, 0x0000 }, + { 79, 0x0000 }, { 79, 0x0000 }, { 79, 0x0000 }, { 79, 0x0000 }, + { 79, 0x0000 }, { 79, 0x0000 }, { 79, 0x0000 }, { 79, 0x0000 }, + /* 0x9800 */ + { 79, 0x0000 }, { 79, 0x0000 }, { 79, 0x0000 }, { 79, 0x0000 }, + { 79, 0x0000 }, { 79, 0x0040 }, +}; +static const Summary16 hkscs2004_uni2indx_page9f[12] = { + /* 0x9f00 */ + { 80, 0x0000 }, { 80, 0x0000 }, { 80, 0x0000 }, { 80, 0x0000 }, + { 80, 0x0000 }, { 80, 0x0000 }, { 80, 0x0000 }, { 80, 0x0000 }, + { 80, 0x0000 }, { 80, 0x0000 }, { 80, 0x0000 }, { 80, 0x000c }, +}; +static const Summary16 hkscs2004_uni2indx_page201[20] = { + /* 0x20100 */ + { 82, 0x0000 }, { 82, 0x0000 }, { 82, 0x0000 }, { 82, 0x0000 }, + { 82, 0x0000 }, { 82, 0x0000 }, { 82, 0x0000 }, { 82, 0x0000 }, + { 82, 0x0000 }, { 82, 0x0000 }, { 82, 0x0010 }, { 83, 0x0000 }, + { 83, 0x0000 }, { 83, 0x0000 }, { 83, 0x0000 }, { 83, 0x0000 }, + /* 0x20200 */ + { 83, 0x0000 }, { 83, 0x0000 }, { 83, 0x0000 }, { 83, 0x0200 }, +}; +static const Summary16 hkscs2004_uni2indx_page20a[26] = { + /* 0x20a00 */ + { 84, 0x0000 }, { 84, 0x0000 }, { 84, 0x0000 }, { 84, 0x0000 }, + { 84, 0x0000 }, { 84, 0x0000 }, { 84, 0x8000 }, { 85, 0x0000 }, + { 85, 0x0000 }, { 85, 0x0000 }, { 85, 0x0000 }, { 85, 0x0000 }, + { 85, 0x0000 }, { 85, 0x0000 }, { 85, 0x0000 }, { 85, 0x0000 }, + /* 0x20b00 */ + { 85, 0x0000 }, { 85, 0x0000 }, { 85, 0x0000 }, { 85, 0x0000 }, + { 85, 0x0000 }, { 85, 0x0000 }, { 85, 0x0000 }, { 85, 0x0000 }, + { 85, 0x0000 }, { 85, 0x8000 }, +}; +static const Summary16 hkscs2004_uni2indx_page21a[7] = { + /* 0x21a00 */ + { 86, 0x0000 }, { 86, 0x0000 }, { 86, 0x0000 }, { 86, 0x0000 }, + { 86, 0x0000 }, { 86, 0x0000 }, { 86, 0x0008 }, +}; +static const Summary16 hkscs2004_uni2indx_page21d[19] = { + /* 0x21d00 */ + { 87, 0x0000 }, { 87, 0x0000 }, { 87, 0x0000 }, { 87, 0x0000 }, + { 87, 0x0000 }, { 87, 0x4000 }, { 88, 0x0000 }, { 88, 0x0000 }, + { 88, 0x0000 }, { 88, 0x0000 }, { 88, 0x0000 }, { 88, 0x0000 }, + { 88, 0x0000 }, { 88, 0x0000 }, { 88, 0x0000 }, { 88, 0x0000 }, + /* 0x21e00 */ + { 88, 0x0000 }, { 88, 0x0000 }, { 88, 0x0008 }, +}; +static const Summary16 hkscs2004_uni2indx_page221[13] = { + /* 0x22100 */ + { 89, 0x0000 }, { 89, 0x0000 }, { 89, 0x0000 }, { 89, 0x0000 }, + { 89, 0x0000 }, { 89, 0x0000 }, { 89, 0x0000 }, { 89, 0x0000 }, + { 89, 0x0000 }, { 89, 0x0000 }, { 89, 0x0000 }, { 89, 0x0000 }, + { 89, 0x0002 }, +}; +static const Summary16 hkscs2004_uni2indx_page227[10] = { + /* 0x22700 */ + { 90, 0x0000 }, { 90, 0x0000 }, { 90, 0x0000 }, { 90, 0x0000 }, + { 90, 0x0000 }, { 90, 0x0000 }, { 90, 0x0000 }, { 90, 0x0000 }, + { 90, 0x0000 }, { 90, 0x0040 }, +}; +static const Summary16 hkscs2004_uni2indx_page232[6] = { + /* 0x23200 */ + { 91, 0x0000 }, { 91, 0x0000 }, { 91, 0x0000 }, { 91, 0x0000 }, + { 91, 0x0000 }, { 91, 0x0040 }, +}; +static const Summary16 hkscs2004_uni2indx_page235[18] = { + /* 0x23500 */ + { 92, 0x0000 }, { 92, 0x0000 }, { 92, 0x0000 }, { 92, 0x0000 }, + { 92, 0x0000 }, { 92, 0x0002 }, { 93, 0x0000 }, { 93, 0x0000 }, + { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0000 }, + { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0000 }, { 93, 0x0000 }, + /* 0x23600 */ + { 93, 0x0000 }, { 93, 0x0080 }, +}; +static const Summary16 hkscs2004_uni2indx_page23b[2] = { + /* 0x23b00 */ + { 94, 0x0000 }, { 94, 0x0400 }, +}; +static const Summary16 hkscs2004_uni2indx_page23e[47] = { + /* 0x23e00 */ + { 95, 0x0040 }, { 96, 0x0000 }, { 96, 0x0000 }, { 96, 0x0000 }, + { 96, 0x0000 }, { 96, 0x0000 }, { 96, 0x0000 }, { 96, 0x0000 }, + { 96, 0x0000 }, { 96, 0x0000 }, { 96, 0x0000 }, { 96, 0x0000 }, + { 96, 0x0000 }, { 96, 0x0000 }, { 96, 0x0000 }, { 96, 0x0000 }, + /* 0x23f00 */ + { 96, 0x0000 }, { 96, 0x0000 }, { 96, 0x0000 }, { 96, 0x0000 }, + { 96, 0x0000 }, { 96, 0x0000 }, { 96, 0x0002 }, { 97, 0x0000 }, + { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x0000 }, + { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x0000 }, + /* 0x24000 */ + { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x0000 }, + { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x0000 }, + { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x0000 }, + { 97, 0x0000 }, { 97, 0x0000 }, { 97, 0x1000 }, +}; +static const Summary16 hkscs2004_uni2indx_page242[12] = { + /* 0x24200 */ + { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x0000 }, + { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x0000 }, + { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x0000 }, { 98, 0x8000 }, +}; +static const Summary16 hkscs2004_uni2indx_page24b[1] = { + /* 0x24b00 */ + { 99, 0x8000 }, +}; +static const Summary16 hkscs2004_uni2indx_page254[10] = { + /* 0x25400 */ + { 100, 0x0000 }, { 100, 0x0000 }, { 100, 0x0000 }, { 100, 0x0000 }, + { 100, 0x0000 }, { 100, 0x0000 }, { 100, 0x0000 }, { 100, 0x0000 }, + { 100, 0x0000 }, { 100, 0x0400 }, +}; +static const Summary16 hkscs2004_uni2indx_page25a[6] = { + /* 0x25a00 */ + { 101, 0x0000 }, { 101, 0x0000 }, { 101, 0x0000 }, { 101, 0x0000 }, + { 101, 0x0000 }, { 101, 0x0010 }, +}; +static const Summary16 hkscs2004_uni2indx_page26b[21] = { + /* 0x26b00 */ + { 102, 0x0000 }, { 102, 0x0000 }, { 102, 0x0008 }, { 103, 0x0000 }, + { 103, 0x0000 }, { 103, 0x0000 }, { 103, 0x0000 }, { 103, 0x0000 }, + { 103, 0x0000 }, { 103, 0x0000 }, { 103, 0x0000 }, { 103, 0x0000 }, + { 103, 0x0000 }, { 103, 0x0000 }, { 103, 0x0000 }, { 103, 0x0000 }, + /* 0x26c00 */ + { 103, 0x0000 }, { 103, 0x0000 }, { 103, 0x0000 }, { 103, 0x0000 }, + { 103, 0x0042 }, +}; +static const Summary16 hkscs2004_uni2indx_page26e[9] = { + /* 0x26e00 */ + { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x0000 }, + { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x0000 }, + { 105, 0x0800 }, +}; +static const Summary16 hkscs2004_uni2indx_page270[14] = { + /* 0x27000 */ + { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x0000 }, + { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x0000 }, + { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x0000 }, + { 106, 0x0000 }, { 106, 0x0004 }, +}; +static const Summary16 hkscs2004_uni2indx_page272[32] = { + /* 0x27200 */ + { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0000 }, + { 107, 0x0000 }, { 107, 0x0000 }, { 107, 0x0080 }, { 108, 0x0000 }, + { 108, 0x0000 }, { 108, 0x0000 }, { 108, 0x0000 }, { 108, 0x0000 }, + { 108, 0x0000 }, { 108, 0x0000 }, { 108, 0x0000 }, { 108, 0x0000 }, + /* 0x27300 */ + { 108, 0x0000 }, { 108, 0x0000 }, { 108, 0x0000 }, { 108, 0x0000 }, + { 108, 0x0000 }, { 108, 0x0004 }, { 109, 0x0000 }, { 109, 0x0000 }, + { 109, 0x0000 }, { 109, 0x0000 }, { 109, 0x0000 }, { 109, 0x0000 }, + { 109, 0x0000 }, { 109, 0x0000 }, { 109, 0x0000 }, { 109, 0x8000 }, +}; +static const Summary16 hkscs2004_uni2indx_page27b[29] = { + /* 0x27b00 */ + { 110, 0x0000 }, { 110, 0x0000 }, { 110, 0x0000 }, { 110, 0x0000 }, + { 110, 0x0000 }, { 110, 0x0000 }, { 110, 0x0000 }, { 110, 0x0000 }, + { 110, 0x0000 }, { 110, 0x0000 }, { 110, 0x0000 }, { 110, 0x0000 }, + { 110, 0x0000 }, { 110, 0x0000 }, { 110, 0x8000 }, { 111, 0x0000 }, + /* 0x27c00 */ + { 111, 0x0000 }, { 111, 0x0000 }, { 111, 0x0000 }, { 111, 0x0000 }, + { 111, 0x0000 }, { 111, 0x0000 }, { 111, 0x1000 }, { 112, 0x0000 }, + { 112, 0x0000 }, { 112, 0x0000 }, { 112, 0x0000 }, { 112, 0x0002 }, + { 113, 0x0020 }, +}; +static const Summary16 hkscs2004_uni2indx_page286[12] = { + /* 0x28600 */ + { 114, 0x0000 }, { 114, 0x0000 }, { 114, 0x0000 }, { 114, 0x0000 }, + { 114, 0x0000 }, { 114, 0x0000 }, { 114, 0x0000 }, { 114, 0x0000 }, + { 114, 0x0000 }, { 114, 0x0000 }, { 114, 0x0000 }, { 114, 0x0004 }, +}; +static const Summary16 hkscs2004_uni2indx_page289[7] = { + /* 0x28900 */ + { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x0000 }, + { 115, 0x0000 }, { 115, 0x0000 }, { 115, 0x2000 }, +}; +static const Summary16 hkscs2004_uni2indx_page28b[12] = { + /* 0x28b00 */ + { 116, 0x0000 }, { 116, 0x0000 }, { 116, 0x0000 }, { 116, 0x0000 }, + { 116, 0x0000 }, { 116, 0x0000 }, { 116, 0x0000 }, { 116, 0x0000 }, + { 116, 0x0000 }, { 116, 0x0000 }, { 116, 0x0000 }, { 116, 0x0200 }, +}; +static const Summary16 hkscs2004_uni2indx_page290[8] = { + /* 0x29000 */ + { 117, 0x0000 }, { 117, 0x0000 }, { 117, 0x0000 }, { 117, 0x0000 }, + { 117, 0x0000 }, { 117, 0x0000 }, { 117, 0x0000 }, { 117, 0x0200 }, +}; +static const Summary16 hkscs2004_uni2indx_page298[21] = { + /* 0x29800 */ + { 118, 0x0000 }, { 118, 0x0000 }, { 118, 0x0000 }, { 118, 0x0000 }, + { 118, 0x0000 }, { 118, 0x0000 }, { 118, 0x0000 }, { 118, 0x0000 }, + { 118, 0x0000 }, { 118, 0x0000 }, { 118, 0x0000 }, { 118, 0x0000 }, + { 118, 0x0000 }, { 118, 0x0000 }, { 118, 0x0000 }, { 118, 0x0400 }, + /* 0x29900 */ + { 119, 0x0000 }, { 119, 0x0000 }, { 119, 0x0000 }, { 119, 0x0000 }, + { 119, 0x0020 }, +}; +static const Summary16 hkscs2004_uni2indx_page29e[12] = { + /* 0x29e00 */ + { 120, 0x0000 }, { 120, 0x0000 }, { 120, 0x0000 }, { 120, 0x0000 }, + { 120, 0x0000 }, { 120, 0x0000 }, { 120, 0x0000 }, { 120, 0x0000 }, + { 120, 0x0000 }, { 120, 0x0000 }, { 120, 0x0000 }, { 120, 0x0001 }, +}; +static const Summary16 hkscs2004_uni2indx_page2a1[12] = { + /* 0x2a100 */ + { 121, 0x0000 }, { 121, 0x0000 }, { 121, 0x0000 }, { 121, 0x0000 }, + { 121, 0x0000 }, { 121, 0x0000 }, { 121, 0x0000 }, { 121, 0x0000 }, + { 121, 0x0000 }, { 121, 0x0000 }, { 121, 0x0000 }, { 121, 0x0020 }, +}; +static const Summary16 hkscs2004_uni2indx_page2a3[6] = { + /* 0x2a300 */ + { 122, 0x0000 }, { 122, 0x0000 }, { 122, 0x0000 }, { 122, 0x0000 }, + { 122, 0x0000 }, { 122, 0x0002 }, +}; + +static int +hkscs2004_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc < 0x21a00) { + if (wc < 0x6e00) { + if (wc >= 0x3400 && wc < 0x3450) + summary = &hkscs2004_uni2indx_page34[(wc>>4)-0x340]; + else if (wc >= 0x3600 && wc < 0x3980) + summary = &hkscs2004_uni2indx_page36[(wc>>4)-0x360]; + else if (wc >= 0x3b00 && wc < 0x3ba0) + summary = &hkscs2004_uni2indx_page3b[(wc>>4)-0x3b0]; + else if (wc >= 0x3d00 && wc < 0x3e00) + summary = &hkscs2004_uni2indx_page3d[(wc>>4)-0x3d0]; + else if (wc >= 0x3f00 && wc < 0x41f0) + summary = &hkscs2004_uni2indx_page3f[(wc>>4)-0x3f0]; + else if (wc >= 0x4300 && wc < 0x4750) + summary = &hkscs2004_uni2indx_page43[(wc>>4)-0x430]; + else if (wc >= 0x4a00 && wc < 0x4ab0) + summary = &hkscs2004_uni2indx_page4a[(wc>>4)-0x4a0]; + else if (wc >= 0x4c00 && wc < 0x4d90) + summary = &hkscs2004_uni2indx_page4c[(wc>>4)-0x4c0]; + else if (wc >= 0x4f00 && wc < 0x4fc0) + summary = &hkscs2004_uni2indx_page4f[(wc>>4)-0x4f0]; + else if (wc >= 0x5600 && wc < 0x5700) + summary = &hkscs2004_uni2indx_page56[(wc>>4)-0x560]; + else if (wc >= 0x5900 && wc < 0x5d80) + summary = &hkscs2004_uni2indx_page59[(wc>>4)-0x590]; + else if (wc >= 0x5f00 && wc < 0x5f40) + summary = &hkscs2004_uni2indx_page5f[(wc>>4)-0x5f0]; + else if (wc >= 0x6600 && wc < 0x6770) + summary = &hkscs2004_uni2indx_page66[(wc>>4)-0x660]; + } else { + if (wc >= 0x6e00 && wc < 0x6e60) + summary = &hkscs2004_uni2indx_page6e[(wc>>4)-0x6e0]; + else if (wc >= 0x7100 && wc < 0x7230) + summary = &hkscs2004_uni2indx_page71[(wc>>4)-0x710]; + else if (wc >= 0x7400 && wc < 0x74a0) + summary = &hkscs2004_uni2indx_page74[(wc>>4)-0x740]; + else if (wc >= 0x7900 && wc < 0x79d0) + summary = &hkscs2004_uni2indx_page79[(wc>>4)-0x790]; + else if (wc >= 0x7d00 && wc < 0x7da0) + summary = &hkscs2004_uni2indx_page7d[(wc>>4)-0x7d0]; + else if (wc >= 0x8100 && wc < 0x8170) + summary = &hkscs2004_uni2indx_page81[(wc>>4)-0x810]; + else if (wc >= 0x8500 && wc < 0x85a0) + summary = &hkscs2004_uni2indx_page85[(wc>>4)-0x850]; + else if (wc >= 0x8a00 && wc < 0x8b00) + summary = &hkscs2004_uni2indx_page8a[(wc>>4)-0x8a0]; + else if (wc >= 0x9700 && wc < 0x9860) + summary = &hkscs2004_uni2indx_page97[(wc>>4)-0x970]; + else if (wc >= 0x9f00 && wc < 0x9fc0) + summary = &hkscs2004_uni2indx_page9f[(wc>>4)-0x9f0]; + else if (wc >= 0x20100 && wc < 0x20240) + summary = &hkscs2004_uni2indx_page201[(wc>>4)-0x2010]; + else if (wc >= 0x20a00 && wc < 0x20ba0) + summary = &hkscs2004_uni2indx_page20a[(wc>>4)-0x20a0]; + } + } else { + if (wc < 0x26b00) { + if (wc >= 0x21a00 && wc < 0x21a70) + summary = &hkscs2004_uni2indx_page21a[(wc>>4)-0x21a0]; + else if (wc >= 0x21d00 && wc < 0x21e30) + summary = &hkscs2004_uni2indx_page21d[(wc>>4)-0x21d0]; + else if (wc >= 0x22100 && wc < 0x221d0) + summary = &hkscs2004_uni2indx_page221[(wc>>4)-0x2210]; + else if (wc >= 0x22700 && wc < 0x227a0) + summary = &hkscs2004_uni2indx_page227[(wc>>4)-0x2270]; + else if (wc >= 0x23200 && wc < 0x23260) + summary = &hkscs2004_uni2indx_page232[(wc>>4)-0x2320]; + else if (wc >= 0x23500 && wc < 0x23620) + summary = &hkscs2004_uni2indx_page235[(wc>>4)-0x2350]; + else if (wc >= 0x23b00 && wc < 0x23b20) + summary = &hkscs2004_uni2indx_page23b[(wc>>4)-0x23b0]; + else if (wc >= 0x23e00 && wc < 0x240f0) + summary = &hkscs2004_uni2indx_page23e[(wc>>4)-0x23e0]; + else if (wc >= 0x24200 && wc < 0x242c0) + summary = &hkscs2004_uni2indx_page242[(wc>>4)-0x2420]; + else if (wc >= 0x24b00 && wc < 0x24b10) + summary = &hkscs2004_uni2indx_page24b[(wc>>4)-0x24b0]; + else if (wc >= 0x25400 && wc < 0x254a0) + summary = &hkscs2004_uni2indx_page254[(wc>>4)-0x2540]; + else if (wc >= 0x25a00 && wc < 0x25a60) + summary = &hkscs2004_uni2indx_page25a[(wc>>4)-0x25a0]; + } else { + if (wc >= 0x26b00 && wc < 0x26c50) + summary = &hkscs2004_uni2indx_page26b[(wc>>4)-0x26b0]; + else if (wc >= 0x26e00 && wc < 0x26e90) + summary = &hkscs2004_uni2indx_page26e[(wc>>4)-0x26e0]; + else if (wc >= 0x27000 && wc < 0x270e0) + summary = &hkscs2004_uni2indx_page270[(wc>>4)-0x2700]; + else if (wc >= 0x27200 && wc < 0x27400) + summary = &hkscs2004_uni2indx_page272[(wc>>4)-0x2720]; + else if (wc >= 0x27b00 && wc < 0x27cd0) + summary = &hkscs2004_uni2indx_page27b[(wc>>4)-0x27b0]; + else if (wc >= 0x28600 && wc < 0x286c0) + summary = &hkscs2004_uni2indx_page286[(wc>>4)-0x2860]; + else if (wc >= 0x28900 && wc < 0x28970) + summary = &hkscs2004_uni2indx_page289[(wc>>4)-0x2890]; + else if (wc >= 0x28b00 && wc < 0x28bc0) + summary = &hkscs2004_uni2indx_page28b[(wc>>4)-0x28b0]; + else if (wc >= 0x29000 && wc < 0x29080) + summary = &hkscs2004_uni2indx_page290[(wc>>4)-0x2900]; + else if (wc >= 0x29800 && wc < 0x29950) + summary = &hkscs2004_uni2indx_page298[(wc>>4)-0x2980]; + else if (wc >= 0x29e00 && wc < 0x29ec0) + summary = &hkscs2004_uni2indx_page29e[(wc>>4)-0x29e0]; + else if (wc >= 0x2a100 && wc < 0x2a1c0) + summary = &hkscs2004_uni2indx_page2a1[(wc>>4)-0x2a10]; + else if (wc >= 0x2a300 && wc < 0x2a360) + summary = &hkscs2004_uni2indx_page2a3[(wc>>4)-0x2a30]; + } + } + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = hkscs2004_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/hkscs2008.h b/libs/libiconv/lib/hkscs2008.h new file mode 100644 index 00000000..ee6235c0 --- /dev/null +++ b/libs/libiconv/lib/hkscs2008.h @@ -0,0 +1,467 @@ +/* + * Copyright (C) 1999-2010 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * HKSCS:2008 + */ + +static const unsigned short hkscs2008_2uni_page87[126] = { + /* 0x87 */ + 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, + 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, + 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, + 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, + 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, + 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, + 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, 0x22fd, + 0x22fd, 0x22fd, 0x0175, 0x2453, 0x299e, 0x2d21, 0x03ec, 0x2bde, + 0x02f5, 0x16fc, 0x2197, 0x2a61, 0x300d, 0x26ea, 0x238a, 0x275e, + 0x060a, 0x1884, 0x2196, 0x1f2f, 0x0930, 0x1a13, 0x0d96, 0x204a, + 0x1e18, 0x15d0, 0x1632, 0x0f60, 0x1129, 0x1b9d, 0x144c, 0x17c5, + 0x1082, 0x162c, 0x0a4f, 0x1d46, 0x00e6, 0x13c4, 0x2cb9, 0x14c6, + 0x21c7, 0x0cb3, 0x092f, 0x0b4c, 0x0531, 0x298e, 0x0d18, 0x1672, + 0x2f65, 0x1c8f, 0x08ae, 0x2e88, 0x0581, 0x2c99, 0x17ae, 0x25bc, + 0x21c8, 0x25c1, 0x25c9, 0x25cc, 0x21c9, 0x1904, 0x28bb, 0x04b4, + 0x21ca, 0x07e1, 0x31ff, 0x0ec1, 0x126e, 0x21cb, +}; + +static const ucs4_t hkscs2008_2uni_upages[50] = { + 0x03400, 0x03800, 0x03a00, 0x03e00, 0x04000, 0x04100, 0x04300, 0x04400, + 0x04600, 0x04900, 0x05200, 0x05400, 0x05700, 0x05800, 0x06200, 0x06600, + 0x06700, 0x06a00, 0x07000, 0x07300, 0x07400, 0x07900, 0x07a00, 0x07b00, + 0x08400, 0x08500, 0x08600, 0x08800, 0x08b00, 0x09000, 0x09200, 0x09400, + 0x09700, 0x09f00, 0x0ff00, 0x20a00, 0x21d00, 0x22400, 0x23100, 0x23200, + 0x23500, 0x23600, 0x24100, 0x25800, 0x25d00, 0x26000, 0x26e00, 0x27b00, + 0x28900, 0x2ad00, +}; + +static int +hkscs2008_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 == 0x87)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 < 0x7f) || (c2 >= 0xa1 && c2 < 0xff)) { + unsigned int i = 157 * (c1 - 0x80) + (c2 - (c2 >= 0xa1 ? 0x62 : 0x40)); + ucs4_t wc = 0xfffd; + unsigned short swc; + { + if (i < 1225) + swc = hkscs2008_2uni_page87[i-1099], + wc = hkscs2008_2uni_upages[swc>>8] | (swc & 0xff); + } + if (wc != 0xfffd) { + *pwc = wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short hkscs2008_2charset[68] = { + 0x87be, 0x877a, 0x87a2, 0x877e, 0x87d9, 0x87c6, 0x87ce, 0x87aa, + 0x87db, 0x87cc, 0x87c4, 0x87ae, 0x87bc, 0x87c5, 0x87c3, 0x87c8, + 0x87b0, 0x87dd, 0x87b5, 0x87ba, 0x87b6, 0x87de, 0x87bf, 0x87b8, + 0x87c1, 0x87b3, 0x87bb, 0x87b4, 0x87c9, 0x87a3, 0x87d0, 0x87b9, + 0x87ab, 0x87d7, 0x87af, 0x87b7, 0x87cb, 0x87bd, 0x87b2, 0x87ad, + 0x87b1, 0x87ac, 0x87a4, 0x87c2, 0x87d2, 0x87d6, 0x87da, 0x87df, + 0x87a8, 0x877b, 0x87d1, 0x87d3, 0x87d4, 0x87d5, 0x87a7, 0x87a9, + 0x87d8, 0x87c7, 0x877c, 0x87a5, 0x87a1, 0x87cf, 0x87c0, 0x877d, + 0x87cd, 0x87ca, 0x87a6, 0x87dc, +}; + +static const Summary16 hkscs2008_uni2indx_page34[15] = { + /* 0x3400 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0040 }, +}; +static const Summary16 hkscs2008_uni2indx_page38[8] = { + /* 0x3800 */ + { 1, 0x0000 }, { 1, 0x0000 }, { 1, 0x0000 }, { 1, 0x0000 }, + { 1, 0x0000 }, { 1, 0x0000 }, { 1, 0x0000 }, { 1, 0x0020 }, +}; +static const Summary16 hkscs2008_uni2indx_page3a[16] = { + /* 0x3a00 */ + { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, + { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, + { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, + { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0000 }, { 2, 0x0020 }, +}; +static const Summary16 hkscs2008_uni2indx_page3e[15] = { + /* 0x3e00 */ + { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, + { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, + { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x0000 }, + { 3, 0x0000 }, { 3, 0x0000 }, { 3, 0x1000 }, +}; +static const Summary16 hkscs2008_uni2indx_page40[25] = { + /* 0x4000 */ + { 4, 0x0000 }, { 4, 0x0000 }, { 4, 0x0000 }, { 4, 0x0000 }, + { 4, 0x0000 }, { 4, 0x0000 }, { 4, 0x0000 }, { 4, 0x0000 }, + { 4, 0x0000 }, { 4, 0x0000 }, { 4, 0x0000 }, { 4, 0x0010 }, + { 5, 0x0000 }, { 5, 0x0000 }, { 5, 0x0000 }, { 5, 0x0000 }, + /* 0x4100 */ + { 5, 0x0000 }, { 5, 0x0000 }, { 5, 0x0000 }, { 5, 0x0002 }, + { 6, 0x0000 }, { 6, 0x0000 }, { 6, 0x0000 }, { 6, 0x0000 }, + { 6, 0x0002 }, +}; +static const Summary16 hkscs2008_uni2indx_page43[31] = { + /* 0x4300 */ + { 7, 0x0400 }, { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, + { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, + { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, + { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, + /* 0x4400 */ + { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, + { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, + { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0000 }, + { 8, 0x0000 }, { 8, 0x0000 }, { 8, 0x0002 }, +}; +static const Summary16 hkscs2008_uni2indx_page46[11] = { + /* 0x4600 */ + { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, + { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x0000 }, + { 9, 0x0000 }, { 9, 0x0000 }, { 9, 0x4000 }, +}; +static const Summary16 hkscs2008_uni2indx_page49[4] = { + /* 0x4900 */ + { 10, 0x0000 }, { 10, 0x0000 }, { 10, 0x8000 }, { 11, 0x0001 }, +}; +static const Summary16 hkscs2008_uni2indx_page52[5] = { + /* 0x5200 */ + { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0000 }, { 12, 0x0000 }, + { 12, 0x8000 }, +}; +static const Summary16 hkscs2008_uni2indx_page54[5] = { + /* 0x5400 */ + { 13, 0x0000 }, { 13, 0x0000 }, { 13, 0x0000 }, { 13, 0x0000 }, + { 13, 0x1000 }, +}; +static const Summary16 hkscs2008_uni2indx_page57[26] = { + /* 0x5700 */ + { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, + { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, + { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0000 }, { 14, 0x0008 }, + { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0000 }, { 15, 0x0000 }, + /* 0x5800 */ + { 15, 0x0000 }, { 15, 0x0100 }, { 16, 0x0000 }, { 16, 0x0000 }, + { 16, 0x0000 }, { 16, 0x0000 }, { 16, 0x0000 }, { 16, 0x0000 }, + { 16, 0x0000 }, { 16, 0x0040 }, +}; +static const Summary16 hkscs2008_uni2indx_page62[13] = { + /* 0x6200 */ + { 17, 0x0000 }, { 17, 0x0000 }, { 17, 0x0000 }, { 17, 0x0000 }, + { 17, 0x0000 }, { 17, 0x0000 }, { 17, 0x0000 }, { 17, 0x0000 }, + { 17, 0x0000 }, { 17, 0x0000 }, { 17, 0x0000 }, { 17, 0x0000 }, + { 17, 0x0002 }, +}; +static const Summary16 hkscs2008_uni2indx_page66[25] = { + /* 0x6600 */ + { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x0000 }, + { 18, 0x0000 }, { 18, 0x0000 }, { 18, 0x0001 }, { 19, 0x0000 }, + { 19, 0x0000 }, { 19, 0x0000 }, { 19, 0x0000 }, { 19, 0x0000 }, + { 19, 0x0000 }, { 19, 0x0000 }, { 19, 0x0000 }, { 19, 0x0000 }, + /* 0x6700 */ + { 19, 0x0000 }, { 19, 0x0000 }, { 19, 0x0000 }, { 19, 0x0000 }, + { 19, 0x0000 }, { 19, 0x0000 }, { 19, 0x0000 }, { 19, 0x0000 }, + { 19, 0x0004 }, +}; +static const Summary16 hkscs2008_uni2indx_page6a[3] = { + /* 0x6a00 */ + { 20, 0x0000 }, { 20, 0x0000 }, { 20, 0x0200 }, +}; +static const Summary16 hkscs2008_uni2indx_page70[7] = { + /* 0x7000 */ + { 21, 0x0000 }, { 21, 0x0000 }, { 21, 0x0000 }, { 21, 0x0000 }, + { 21, 0x0000 }, { 21, 0x0000 }, { 21, 0x4000 }, +}; +static const Summary16 hkscs2008_uni2indx_page73[29] = { + /* 0x7300 */ + { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, + { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, + { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, { 22, 0x0000 }, + { 22, 0x0010 }, { 23, 0x0000 }, { 23, 0x0000 }, { 23, 0x0000 }, + /* 0x7400 */ + { 23, 0x0000 }, { 23, 0x0000 }, { 23, 0x0000 }, { 23, 0x0000 }, + { 23, 0x1000 }, { 24, 0x0000 }, { 24, 0x0000 }, { 24, 0x0000 }, + { 24, 0x0000 }, { 24, 0x0000 }, { 24, 0x0000 }, { 24, 0x0000 }, + { 24, 0x0040 }, +}; +static const Summary16 hkscs2008_uni2indx_page79[45] = { + /* 0x7900 */ + { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, + { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, + { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, + { 25, 0x0000 }, { 25, 0x0001 }, { 26, 0x0000 }, { 26, 0x0000 }, + /* 0x7a00 */ + { 26, 0x0000 }, { 26, 0x0000 }, { 26, 0x1000 }, { 27, 0x0004 }, + { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0004 }, + { 29, 0x0000 }, { 29, 0x0000 }, { 29, 0x0000 }, { 29, 0x0000 }, + { 29, 0x0000 }, { 29, 0x0000 }, { 29, 0x0000 }, { 29, 0x1000 }, + /* 0x7b00 */ + { 30, 0x0000 }, { 30, 0x0000 }, { 30, 0x0000 }, { 30, 0x0000 }, + { 30, 0x0000 }, { 30, 0x0000 }, { 30, 0x0000 }, { 30, 0x0000 }, + { 30, 0x0000 }, { 30, 0x0000 }, { 30, 0x4000 }, { 31, 0x0000 }, + { 31, 0x0020 }, +}; +static const Summary16 hkscs2008_uni2indx_page84[34] = { + /* 0x8400 */ + { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0000 }, + { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0000 }, + { 32, 0x0010 }, { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, + { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, { 33, 0x0000 }, + /* 0x8500 */ + { 33, 0x0010 }, { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0000 }, + { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0000 }, + { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0000 }, + { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0000 }, { 34, 0x0000 }, + /* 0x8600 */ + { 34, 0x0000 }, { 34, 0x0008 }, +}; +static const Summary16 hkscs2008_uni2indx_page88[10] = { + /* 0x8800 */ + { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, + { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, { 35, 0x0000 }, + { 35, 0x0000 }, { 35, 0x2000 }, +}; +static const Summary16 hkscs2008_uni2indx_page8b[9] = { + /* 0x8b00 */ + { 36, 0x0000 }, { 36, 0x0000 }, { 36, 0x0000 }, { 36, 0x0000 }, + { 36, 0x0000 }, { 36, 0x0000 }, { 36, 0x0000 }, { 36, 0x0000 }, + { 36, 0x8000 }, +}; +static const Summary16 hkscs2008_uni2indx_page90[5] = { + /* 0x9000 */ + { 37, 0x0000 }, { 37, 0x0000 }, { 37, 0x0000 }, { 37, 0x0000 }, + { 37, 0x0040 }, +}; +static const Summary16 hkscs2008_uni2indx_page92[2] = { + /* 0x9200 */ + { 38, 0x0000 }, { 38, 0x0100 }, +}; +static const Summary16 hkscs2008_uni2indx_page94[3] = { + /* 0x9400 */ + { 39, 0x0000 }, { 39, 0x0000 }, { 39, 0x8000 }, +}; +static const Summary16 hkscs2008_uni2indx_page97[5] = { + /* 0x9700 */ + { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0000 }, { 40, 0x0000 }, + { 40, 0x0400 }, +}; +static const Summary16 hkscs2008_uni2indx_page9f[13] = { + /* 0x9f00 */ + { 41, 0x0000 }, { 41, 0x0000 }, { 41, 0x0000 }, { 41, 0x0000 }, + { 41, 0x0000 }, { 41, 0x0000 }, { 41, 0x0000 }, { 41, 0x0000 }, + { 41, 0x0000 }, { 41, 0x00c0 }, { 43, 0x0000 }, { 43, 0x0000 }, + { 43, 0x0f80 }, +}; +static const Summary16 hkscs2008_uni2indx_page20a[9] = { + /* 0x20a00 */ + { 48, 0x0000 }, { 48, 0x0000 }, { 48, 0x0000 }, { 48, 0x0000 }, + { 48, 0x0000 }, { 48, 0x0000 }, { 48, 0x0000 }, { 48, 0x0000 }, + { 48, 0x0400 }, +}; +static const Summary16 hkscs2008_uni2indx_page21d[6] = { + /* 0x21d00 */ + { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, { 49, 0x0000 }, + { 49, 0x0000 }, { 49, 0x0008 }, +}; +static const Summary16 hkscs2008_uni2indx_page224[13] = { + /* 0x22400 */ + { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, + { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, + { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x1000 }, + { 51, 0x1202 }, +}; +static const Summary16 hkscs2008_uni2indx_page231[22] = { + /* 0x23100 */ + { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, + { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, + { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0000 }, + { 54, 0x0000 }, { 54, 0x0000 }, { 54, 0x0400 }, { 55, 0x0000 }, + /* 0x23200 */ + { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0000 }, { 55, 0x0000 }, + { 55, 0x0000 }, { 55, 0x4000 }, +}; +static const Summary16 hkscs2008_uni2indx_page235[26] = { + /* 0x23500 */ + { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0000 }, + { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0000 }, + { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0000 }, { 56, 0x0800 }, + { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, + /* 0x23600 */ + { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, + { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, + { 57, 0x4000 }, { 58, 0x4000 }, +}; +static const Summary16 hkscs2008_uni2indx_page241[7] = { + /* 0x24100 */ + { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x0000 }, + { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x0002 }, +}; +static const Summary16 hkscs2008_uni2indx_page258[14] = { + /* 0x25800 */ + { 60, 0x0000 }, { 60, 0x0000 }, { 60, 0x0000 }, { 60, 0x0000 }, + { 60, 0x0000 }, { 60, 0x0000 }, { 60, 0x0000 }, { 60, 0x0000 }, + { 60, 0x0000 }, { 60, 0x0000 }, { 60, 0x0000 }, { 60, 0x0000 }, + { 60, 0x0000 }, { 60, 0x4000 }, +}; +static const Summary16 hkscs2008_uni2indx_page25d[12] = { + /* 0x25d00 */ + { 61, 0x0000 }, { 61, 0x0000 }, { 61, 0x0000 }, { 61, 0x0000 }, + { 61, 0x0000 }, { 61, 0x0000 }, { 61, 0x0000 }, { 61, 0x0000 }, + { 61, 0x0000 }, { 61, 0x0200 }, { 62, 0x0000 }, { 62, 0x0200 }, +}; +static const Summary16 hkscs2008_uni2indx_page260[3] = { + /* 0x26000 */ + { 63, 0x0000 }, { 63, 0x0000 }, { 63, 0x0002 }, +}; +static const Summary16 hkscs2008_uni2indx_page26e[9] = { + /* 0x26e00 */ + { 64, 0x0000 }, { 64, 0x0000 }, { 64, 0x0000 }, { 64, 0x0000 }, + { 64, 0x0000 }, { 64, 0x0000 }, { 64, 0x0000 }, { 64, 0x0000 }, + { 64, 0x0100 }, +}; +static const Summary16 hkscs2008_uni2indx_page27b[7] = { + /* 0x27b00 */ + { 65, 0x0000 }, { 65, 0x0000 }, { 65, 0x0000 }, { 65, 0x0000 }, + { 65, 0x0000 }, { 65, 0x0000 }, { 65, 0x0020 }, +}; +static const Summary16 hkscs2008_uni2indx_page289[1] = { + /* 0x28900 */ + { 66, 0x2000 }, +}; +static const Summary16 hkscs2008_uni2indx_page2ad[16] = { + /* 0x2ad00 */ + { 67, 0x0000 }, { 67, 0x0000 }, { 67, 0x0000 }, { 67, 0x0000 }, + { 67, 0x0000 }, { 67, 0x0000 }, { 67, 0x0000 }, { 67, 0x0000 }, + { 67, 0x0000 }, { 67, 0x0000 }, { 67, 0x0000 }, { 67, 0x0000 }, + { 67, 0x0000 }, { 67, 0x0000 }, { 67, 0x0000 }, { 67, 0x8000 }, +}; + +static int +hkscs2008_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc >= 0x3400 && wc < 0x34f0) + summary = &hkscs2008_uni2indx_page34[(wc>>4)-0x340]; + else if (wc >= 0x3800 && wc < 0x3880) + summary = &hkscs2008_uni2indx_page38[(wc>>4)-0x380]; + else if (wc >= 0x3a00 && wc < 0x3b00) + summary = &hkscs2008_uni2indx_page3a[(wc>>4)-0x3a0]; + else if (wc >= 0x3e00 && wc < 0x3ef0) + summary = &hkscs2008_uni2indx_page3e[(wc>>4)-0x3e0]; + else if (wc >= 0x4000 && wc < 0x4190) + summary = &hkscs2008_uni2indx_page40[(wc>>4)-0x400]; + else if (wc >= 0x4300 && wc < 0x44f0) + summary = &hkscs2008_uni2indx_page43[(wc>>4)-0x430]; + else if (wc >= 0x4600 && wc < 0x46b0) + summary = &hkscs2008_uni2indx_page46[(wc>>4)-0x460]; + else if (wc >= 0x4900 && wc < 0x4940) + summary = &hkscs2008_uni2indx_page49[(wc>>4)-0x490]; + else if (wc >= 0x5200 && wc < 0x5250) + summary = &hkscs2008_uni2indx_page52[(wc>>4)-0x520]; + else if (wc >= 0x5400 && wc < 0x5450) + summary = &hkscs2008_uni2indx_page54[(wc>>4)-0x540]; + else if (wc >= 0x5700 && wc < 0x58a0) + summary = &hkscs2008_uni2indx_page57[(wc>>4)-0x570]; + else if (wc >= 0x6200 && wc < 0x62d0) + summary = &hkscs2008_uni2indx_page62[(wc>>4)-0x620]; + else if (wc >= 0x6600 && wc < 0x6790) + summary = &hkscs2008_uni2indx_page66[(wc>>4)-0x660]; + else if (wc >= 0x6a00 && wc < 0x6a30) + summary = &hkscs2008_uni2indx_page6a[(wc>>4)-0x6a0]; + else if (wc >= 0x7000 && wc < 0x7070) + summary = &hkscs2008_uni2indx_page70[(wc>>4)-0x700]; + else if (wc >= 0x7300 && wc < 0x74d0) + summary = &hkscs2008_uni2indx_page73[(wc>>4)-0x730]; + else if (wc >= 0x7900 && wc < 0x7bd0) + summary = &hkscs2008_uni2indx_page79[(wc>>4)-0x790]; + else if (wc >= 0x8400 && wc < 0x8620) + summary = &hkscs2008_uni2indx_page84[(wc>>4)-0x840]; + else if (wc >= 0x8800 && wc < 0x88a0) + summary = &hkscs2008_uni2indx_page88[(wc>>4)-0x880]; + else if (wc >= 0x8b00 && wc < 0x8b90) + summary = &hkscs2008_uni2indx_page8b[(wc>>4)-0x8b0]; + else if (wc >= 0x9000 && wc < 0x9050) + summary = &hkscs2008_uni2indx_page90[(wc>>4)-0x900]; + else if (wc >= 0x9200 && wc < 0x9220) + summary = &hkscs2008_uni2indx_page92[(wc>>4)-0x920]; + else if (wc >= 0x9400 && wc < 0x9430) + summary = &hkscs2008_uni2indx_page94[(wc>>4)-0x940]; + else if (wc >= 0x9700 && wc < 0x9750) + summary = &hkscs2008_uni2indx_page97[(wc>>4)-0x970]; + else if (wc >= 0x9f00 && wc < 0x9fd0) + summary = &hkscs2008_uni2indx_page9f[(wc>>4)-0x9f0]; + else if (wc >= 0x20a00 && wc < 0x20a90) + summary = &hkscs2008_uni2indx_page20a[(wc>>4)-0x20a0]; + else if (wc >= 0x21d00 && wc < 0x21d60) + summary = &hkscs2008_uni2indx_page21d[(wc>>4)-0x21d0]; + else if (wc >= 0x22400 && wc < 0x224d0) + summary = &hkscs2008_uni2indx_page224[(wc>>4)-0x2240]; + else if (wc >= 0x23100 && wc < 0x23260) + summary = &hkscs2008_uni2indx_page231[(wc>>4)-0x2310]; + else if (wc >= 0x23500 && wc < 0x236a0) + summary = &hkscs2008_uni2indx_page235[(wc>>4)-0x2350]; + else if (wc >= 0x24100 && wc < 0x24170) + summary = &hkscs2008_uni2indx_page241[(wc>>4)-0x2410]; + else if (wc >= 0x25800 && wc < 0x258e0) + summary = &hkscs2008_uni2indx_page258[(wc>>4)-0x2580]; + else if (wc >= 0x25d00 && wc < 0x25dc0) + summary = &hkscs2008_uni2indx_page25d[(wc>>4)-0x25d0]; + else if (wc >= 0x26000 && wc < 0x26030) + summary = &hkscs2008_uni2indx_page260[(wc>>4)-0x2600]; + else if (wc >= 0x26e00 && wc < 0x26e90) + summary = &hkscs2008_uni2indx_page26e[(wc>>4)-0x26e0]; + else if (wc >= 0x27b00 && wc < 0x27b70) + summary = &hkscs2008_uni2indx_page27b[(wc>>4)-0x27b0]; + else if (wc >= 0x28900 && wc < 0x28910) + summary = &hkscs2008_uni2indx_page289[(wc>>4)-0x2890]; + else if (wc >= 0x2ad00 && wc < 0x2ae00) + summary = &hkscs2008_uni2indx_page2ad[(wc>>4)-0x2ad0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = hkscs2008_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/hp_roman8.h b/libs/libiconv/lib/hp_roman8.h new file mode 100644 index 00000000..da776ed0 --- /dev/null +++ b/libs/libiconv/lib/hp_roman8.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * HP-ROMAN8 + */ + +static const unsigned short hp_roman8_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x00c0, 0x00c2, 0x00c8, 0x00ca, 0x00cb, 0x00ce, 0x00cf, + 0x00b4, 0x02cb, 0x02c6, 0x00a8, 0x02dc, 0x00d9, 0x00db, 0x20a4, + /* 0xb0 */ + 0x00af, 0x00dd, 0x00fd, 0x00b0, 0x00c7, 0x00e7, 0x00d1, 0x00f1, + 0x00a1, 0x00bf, 0x00a4, 0x00a3, 0x00a5, 0x00a7, 0x0192, 0x00a2, + /* 0xc0 */ + 0x00e2, 0x00ea, 0x00f4, 0x00fb, 0x00e1, 0x00e9, 0x00f3, 0x00fa, + 0x00e0, 0x00e8, 0x00f2, 0x00f9, 0x00e4, 0x00eb, 0x00f6, 0x00fc, + /* 0xd0 */ + 0x00c5, 0x00ee, 0x00d8, 0x00c6, 0x00e5, 0x00ed, 0x00f8, 0x00e6, + 0x00c4, 0x00ec, 0x00d6, 0x00dc, 0x00c9, 0x00ef, 0x00df, 0x00d4, + /* 0xe0 */ + 0x00c1, 0x00c3, 0x00e3, 0x00d0, 0x00f0, 0x00cd, 0x00cc, 0x00d3, + 0x00d2, 0x00d5, 0x00f5, 0x0160, 0x0161, 0x00da, 0x0178, 0x00ff, + /* 0xf0 */ + 0x00de, 0x00fe, 0x00b7, 0x00b5, 0x00b6, 0x00be, 0x2014, 0x00bc, + 0x00bd, 0x00aa, 0x00ba, 0x00ab, 0x25a0, 0x00bb, 0x00b1, 0xfffd, +}; + +static int +hp_roman8_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = hp_roman8_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char hp_roman8_page00[96] = { + 0xa0, 0xb8, 0xbf, 0xbb, 0xba, 0xbc, 0x00, 0xbd, /* 0xa0-0xa7 */ + 0xab, 0x00, 0xf9, 0xfb, 0x00, 0x00, 0x00, 0xb0, /* 0xa8-0xaf */ + 0xb3, 0xfe, 0x00, 0x00, 0xa8, 0xf3, 0xf4, 0xf2, /* 0xb0-0xb7 */ + 0x00, 0x00, 0xfa, 0xfd, 0xf7, 0xf8, 0xf5, 0xb9, /* 0xb8-0xbf */ + 0xa1, 0xe0, 0xa2, 0xe1, 0xd8, 0xd0, 0xd3, 0xb4, /* 0xc0-0xc7 */ + 0xa3, 0xdc, 0xa4, 0xa5, 0xe6, 0xe5, 0xa6, 0xa7, /* 0xc8-0xcf */ + 0xe3, 0xb6, 0xe8, 0xe7, 0xdf, 0xe9, 0xda, 0x00, /* 0xd0-0xd7 */ + 0xd2, 0xad, 0xed, 0xae, 0xdb, 0xb1, 0xf0, 0xde, /* 0xd8-0xdf */ + 0xc8, 0xc4, 0xc0, 0xe2, 0xcc, 0xd4, 0xd7, 0xb5, /* 0xe0-0xe7 */ + 0xc9, 0xc5, 0xc1, 0xcd, 0xd9, 0xd5, 0xd1, 0xdd, /* 0xe8-0xef */ + 0xe4, 0xb7, 0xca, 0xc6, 0xc2, 0xea, 0xce, 0x00, /* 0xf0-0xf7 */ + 0xd6, 0xcb, 0xc7, 0xc3, 0xcf, 0xb2, 0xf1, 0xef, /* 0xf8-0xff */ +}; +static const unsigned char hp_roman8_page01[56] = { + 0xeb, 0xec, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0xbe, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char hp_roman8_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0xa9, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; + +static int +hp_roman8_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = hp_roman8_page00[wc-0x00a0]; + else if (wc >= 0x0160 && wc < 0x0198) + c = hp_roman8_page01[wc-0x0160]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = hp_roman8_page02[wc-0x02c0]; + else if (wc == 0x2014) + c = 0xf6; + else if (wc == 0x20a4) + c = 0xaf; + else if (wc == 0x25a0) + c = 0xfc; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/hz.h b/libs/libiconv/lib/hz.h new file mode 100644 index 00000000..db0b4b11 --- /dev/null +++ b/libs/libiconv/lib/hz.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * HZ + */ + +/* Specification: RFC 1842, RFC 1843 */ + +/* + * The state is 1 in GB mode, 0 in ASCII mode. + */ + +static int +hz_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + state_t state = conv->istate; + unsigned int count = 0; + unsigned char c; + for (;;) { + c = *s; + if (c == '~') { + if (n < count+2) + goto none; + c = s[1]; + if (state == 0) { + if (c == '~') { + *pwc = (ucs4_t) '~'; + conv->istate = state; + return count+2; + } + if (c == '{') { + state = 1; + s += 2; count += 2; + if (n < count+1) + goto none; + continue; + } + if (c == '\n') { + s += 2; count += 2; + if (n < count+1) + goto none; + continue; + } + } else { + if (c == '}') { + state = 0; + s += 2; count += 2; + if (n < count+1) + goto none; + continue; + } + } + goto ilseq; + } + break; + } + if (state == 0) { + *pwc = (ucs4_t) c; + conv->istate = state; + return count+1; + } else { + int ret; + if (n < count+2) + goto none; + ret = gb2312_mbtowc(conv,pwc,s,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + conv->istate = state; + return count+2; + } + +none: + conv->istate = state; + return RET_TOOFEW(count); + +ilseq: + conv->istate = state; + return RET_SHIFT_ILSEQ(count); +} + +static int +hz_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + state_t state = conv->ostate; + unsigned char buf[2]; + int ret; + + /* Code set 0 (ASCII or GB 1988-89) */ + ret = ascii_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] < 0x80) { + int count = (state ? 3 : 1); + if (n < count) + return RET_TOOSMALL; + if (state) { + r[0] = '~'; + r[1] = '}'; + r += 2; + state = 0; + } + r[0] = buf[0]; + conv->ostate = state; + return count; + } + } + + /* Code set 1 (GB 2312-1980) */ + ret = gb2312_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (buf[0] < 0x80 && buf[1] < 0x80) { + int count = (state ? 2 : 4); + if (n < count) + return RET_TOOSMALL; + if (!state) { + r[0] = '~'; + r[1] = '{'; + r += 2; + state = 1; + } + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = state; + return count; + } + } + + return RET_ILUNI; +} + +static int +hz_reset (conv_t conv, unsigned char *r, int n) +{ + state_t state = conv->ostate; + if (state) { + if (n < 2) + return RET_TOOSMALL; + r[0] = '~'; + r[1] = '}'; + /* conv->ostate = 0; will be done by the caller */ + return 2; + } else + return 0; +} diff --git a/libs/libiconv/lib/iconv.c b/libs/libiconv/lib/iconv.c new file mode 100644 index 00000000..37852968 --- /dev/null +++ b/libs/libiconv/lib/iconv.c @@ -0,0 +1,610 @@ +/* + * Copyright (C) 1999-2008, 2011 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include + +#include +#include +#include "config.h" +#include "localcharset.h" + +#ifdef __CYGWIN__ +#include +#endif + +#if ENABLE_EXTRA +/* + * Consider all system dependent encodings, for any system, + * and the extra encodings. + */ +#define USE_AIX +#define USE_OSF1 +#define USE_DOS +#define USE_EXTRA +#else +/* + * Consider those system dependent encodings that are needed for the + * current system. + */ +#ifdef _AIX +#define USE_AIX +#endif +#if defined(__osf__) || defined(VMS) +#define USE_OSF1 +#endif +#if defined(__DJGPP__) || (defined(_WIN32) && (defined(_MSC_VER) || defined(__MINGW32__))) +#define USE_DOS +#endif +#endif + +/* + * Data type for general conversion loop. + */ +struct loop_funcs { + size_t (*loop_convert) (iconv_t icd, + const char* * inbuf, size_t *inbytesleft, + char* * outbuf, size_t *outbytesleft); + size_t (*loop_reset) (iconv_t icd, + char* * outbuf, size_t *outbytesleft); +}; + +/* + * Converters. + */ +#include "converters.h" + +/* + * Transliteration tables. + */ +#include "cjk_variants.h" +#include "translit.h" + +/* + * Table of all supported encodings. + */ +struct encoding { + struct mbtowc_funcs ifuncs; /* conversion multibyte -> unicode */ + struct wctomb_funcs ofuncs; /* conversion unicode -> multibyte */ + int oflags; /* flags for unicode -> multibyte conversion */ +}; +#define DEFALIAS(xxx_alias,xxx) /* nothing */ +enum { +#define DEFENCODING(xxx_names,xxx,xxx_ifuncs1,xxx_ifuncs2,xxx_ofuncs1,xxx_ofuncs2) \ + ei_##xxx , +#include "encodings.def" +#ifdef USE_AIX +# include "encodings_aix.def" +#endif +#ifdef USE_OSF1 +# include "encodings_osf1.def" +#endif +#ifdef USE_DOS +# include "encodings_dos.def" +#endif +#ifdef USE_EXTRA +# include "encodings_extra.def" +#endif +#include "encodings_local.def" +#undef DEFENCODING +ei_for_broken_compilers_that_dont_like_trailing_commas +}; +#include "flags.h" +static struct encoding const all_encodings[] = { +#define DEFENCODING(xxx_names,xxx,xxx_ifuncs1,xxx_ifuncs2,xxx_ofuncs1,xxx_ofuncs2) \ + { xxx_ifuncs1,xxx_ifuncs2, xxx_ofuncs1,xxx_ofuncs2, ei_##xxx##_oflags }, +#include "encodings.def" +#ifdef USE_AIX +# include "encodings_aix.def" +#endif +#ifdef USE_OSF1 +# include "encodings_osf1.def" +#endif +#ifdef USE_DOS +# include "encodings_dos.def" +#endif +#ifdef USE_EXTRA +# include "encodings_extra.def" +#endif +#undef DEFENCODING +#define DEFENCODING(xxx_names,xxx,xxx_ifuncs1,xxx_ifuncs2,xxx_ofuncs1,xxx_ofuncs2) \ + { xxx_ifuncs1,xxx_ifuncs2, xxx_ofuncs1,xxx_ofuncs2, 0 }, +#include "encodings_local.def" +#undef DEFENCODING +}; +#undef DEFALIAS + +/* + * Conversion loops. + */ +#include "loops.h" + +/* + * Alias lookup function. + * Defines + * struct alias { int name; unsigned int encoding_index; }; + * const struct alias * aliases_lookup (const char *str, unsigned int len); + * #define MAX_WORD_LENGTH ... + */ +#if defined _AIX +# include "aliases_sysaix.h" +#elif defined hpux || defined __hpux +# include "aliases_syshpux.h" +#elif defined __osf__ +# include "aliases_sysosf1.h" +#elif defined __sun +# include "aliases_syssolaris.h" +#else +# include "aliases.h" +#endif + +/* + * System dependent alias lookup function. + * Defines + * const struct alias * aliases2_lookup (const char *str); + */ +#if defined(USE_AIX) || defined(USE_OSF1) || defined(USE_DOS) || defined(USE_EXTRA) /* || ... */ +struct stringpool2_t { +#define S(tag,name,encoding_index) char stringpool_##tag[sizeof(name)]; +#include "aliases2.h" +#undef S +}; +static const struct stringpool2_t stringpool2_contents = { +#define S(tag,name,encoding_index) name, +#include "aliases2.h" +#undef S +}; +#define stringpool2 ((const char *) &stringpool2_contents) +static const struct alias sysdep_aliases[] = { +#define S(tag,name,encoding_index) { (int)(long)&((struct stringpool2_t *)0)->stringpool_##tag, encoding_index }, +#include "aliases2.h" +#undef S +}; +#ifdef __GNUC__ +__inline +#endif +const struct alias * +aliases2_lookup (register const char *str) +{ + const struct alias * ptr; + unsigned int count; + for (ptr = sysdep_aliases, count = sizeof(sysdep_aliases)/sizeof(sysdep_aliases[0]); count > 0; ptr++, count--) + if (!strcmp(str, stringpool2 + ptr->name)) + return ptr; + return NULL; +} +#else +#define aliases2_lookup(str) NULL +#define stringpool2 NULL +#endif + +#if 0 +/* Like !strcasecmp, except that the both strings can be assumed to be ASCII + and the first string can be assumed to be in uppercase. */ +static int strequal (const char* str1, const char* str2) +{ + unsigned char c1; + unsigned char c2; + for (;;) { + c1 = * (unsigned char *) str1++; + c2 = * (unsigned char *) str2++; + if (c1 == 0) + break; + if (c2 >= 'a' && c2 <= 'z') + c2 -= 'a'-'A'; + if (c1 != c2) + break; + } + return (c1 == c2); +} +#endif + +iconv_t iconv_open (const char* tocode, const char* fromcode) +{ + struct conv_struct * cd; + unsigned int from_index; + int from_wchar; + unsigned int to_index; + int to_wchar; + int transliterate; + int discard_ilseq; + +#include "iconv_open1.h" + + cd = (struct conv_struct *) malloc(from_wchar != to_wchar + ? sizeof(struct wchar_conv_struct) + : sizeof(struct conv_struct)); + if (cd == NULL) { + errno = ENOMEM; + return (iconv_t)(-1); + } + +#include "iconv_open2.h" + + return (iconv_t)cd; +invalid: + errno = EINVAL; + return (iconv_t)(-1); +} + +size_t iconv (iconv_t icd, + ICONV_CONST char* * inbuf, size_t *inbytesleft, + char* * outbuf, size_t *outbytesleft) +{ + conv_t cd = (conv_t) icd; + if (inbuf == NULL || *inbuf == NULL) + return cd->lfuncs.loop_reset(icd,outbuf,outbytesleft); + else + return cd->lfuncs.loop_convert(icd, + (const char* *)inbuf,inbytesleft, + outbuf,outbytesleft); +} + +int iconv_close (iconv_t icd) +{ + conv_t cd = (conv_t) icd; + free(cd); + return 0; +} + +#ifndef LIBICONV_PLUG + +/* + * Verify that a 'struct conv_struct' and a 'struct wchar_conv_struct' each + * fit in an iconv_allocation_t. + * If this verification fails, iconv_allocation_t must be made larger and + * the major version in LIBICONV_VERSION_INFO must be bumped. + * Currently 'struct conv_struct' has 21 integer/pointer fields, and + * 'struct wchar_conv_struct' additionally has an 'mbstate_t' field. + */ +typedef int verify_size_1[2 * (sizeof (struct conv_struct) <= sizeof (iconv_allocation_t)) - 1]; +typedef int verify_size_2[2 * (sizeof (struct wchar_conv_struct) <= sizeof (iconv_allocation_t)) - 1]; + +int iconv_open_into (const char* tocode, const char* fromcode, + iconv_allocation_t* resultp) +{ + struct conv_struct * cd; + unsigned int from_index; + int from_wchar; + unsigned int to_index; + int to_wchar; + int transliterate; + int discard_ilseq; + +#include "iconv_open1.h" + + cd = (struct conv_struct *) resultp; + +#include "iconv_open2.h" + + return 0; +invalid: + errno = EINVAL; + return -1; +} + +int iconvctl (iconv_t icd, int request, void* argument) +{ + conv_t cd = (conv_t) icd; + switch (request) { + case ICONV_TRIVIALP: + *(int *)argument = + ((cd->lfuncs.loop_convert == unicode_loop_convert + && cd->iindex == cd->oindex) + || cd->lfuncs.loop_convert == wchar_id_loop_convert + ? 1 : 0); + return 0; + case ICONV_GET_TRANSLITERATE: + *(int *)argument = cd->transliterate; + return 0; + case ICONV_SET_TRANSLITERATE: + cd->transliterate = (*(const int *)argument ? 1 : 0); + return 0; + case ICONV_GET_DISCARD_ILSEQ: + *(int *)argument = cd->discard_ilseq; + return 0; + case ICONV_SET_DISCARD_ILSEQ: + cd->discard_ilseq = (*(const int *)argument ? 1 : 0); + return 0; + case ICONV_SET_HOOKS: + if (argument != NULL) { + cd->hooks = *(const struct iconv_hooks *)argument; + } else { + cd->hooks.uc_hook = NULL; + cd->hooks.wc_hook = NULL; + cd->hooks.data = NULL; + } + return 0; + case ICONV_SET_FALLBACKS: + if (argument != NULL) { + cd->fallbacks = *(const struct iconv_fallbacks *)argument; + } else { + cd->fallbacks.mb_to_uc_fallback = NULL; + cd->fallbacks.uc_to_mb_fallback = NULL; + cd->fallbacks.mb_to_wc_fallback = NULL; + cd->fallbacks.wc_to_mb_fallback = NULL; + cd->fallbacks.data = NULL; + } + return 0; + default: + errno = EINVAL; + return -1; + } +} + +/* An alias after its name has been converted from 'int' to 'const char*'. */ +struct nalias { const char* name; unsigned int encoding_index; }; + +static int compare_by_index (const void * arg1, const void * arg2) +{ + const struct nalias * alias1 = (const struct nalias *) arg1; + const struct nalias * alias2 = (const struct nalias *) arg2; + return (int)alias1->encoding_index - (int)alias2->encoding_index; +} + +static int compare_by_name (const void * arg1, const void * arg2) +{ + const char * name1 = *(const char **)arg1; + const char * name2 = *(const char **)arg2; + /* Compare alphabetically, but put "CS" names at the end. */ + int sign = strcmp(name1,name2); + if (sign != 0) { + sign = ((name1[0]=='C' && name1[1]=='S') - (name2[0]=='C' && name2[1]=='S')) + * 4 + (sign >= 0 ? 1 : -1); + } + return sign; +} + +void iconvlist (int (*do_one) (unsigned int namescount, + const char * const * names, + void* data), + void* data) +{ +#define aliascount1 sizeof(aliases)/sizeof(aliases[0]) +#ifndef aliases2_lookup +#define aliascount2 sizeof(sysdep_aliases)/sizeof(sysdep_aliases[0]) +#else +#define aliascount2 0 +#endif +#define aliascount (aliascount1+aliascount2) + struct nalias aliasbuf[aliascount]; + const char * namesbuf[aliascount]; + size_t num_aliases; + { + /* Put all existing aliases into a buffer. */ + size_t i; + size_t j; + j = 0; + for (i = 0; i < aliascount1; i++) { + const struct alias * p = &aliases[i]; + if (p->name >= 0 + && p->encoding_index != ei_local_char + && p->encoding_index != ei_local_wchar_t) { + aliasbuf[j].name = stringpool + p->name; + aliasbuf[j].encoding_index = p->encoding_index; + j++; + } + } +#ifndef aliases2_lookup + for (i = 0; i < aliascount2; i++) { + aliasbuf[j].name = stringpool2 + sysdep_aliases[i].name; + aliasbuf[j].encoding_index = sysdep_aliases[i].encoding_index; + j++; + } +#endif + num_aliases = j; + } + /* Sort by encoding_index. */ + if (num_aliases > 1) + qsort(aliasbuf, num_aliases, sizeof(struct nalias), compare_by_index); + { + /* Process all aliases with the same encoding_index together. */ + size_t j; + j = 0; + while (j < num_aliases) { + unsigned int ei = aliasbuf[j].encoding_index; + size_t i = 0; + do + namesbuf[i++] = aliasbuf[j++].name; + while (j < num_aliases && aliasbuf[j].encoding_index == ei); + if (i > 1) + qsort(namesbuf, i, sizeof(const char *), compare_by_name); + /* Call the callback. */ + if (do_one(i,namesbuf,data)) + break; + } + } +#undef aliascount +#undef aliascount2 +#undef aliascount1 +} + +/* + * Table of canonical names of encodings. + * Instead of strings, it contains offsets into stringpool and stringpool2. + */ +static const unsigned short all_canonical[] = { +#if defined _AIX +# include "canonical_sysaix.h" +#elif defined hpux || defined __hpux +# include "canonical_syshpux.h" +#elif defined __osf__ +# include "canonical_sysosf1.h" +#elif defined __sun +# include "canonical_syssolaris.h" +#else +# include "canonical.h" +#endif +#ifdef USE_AIX +# if defined _AIX +# include "canonical_aix_sysaix.h" +# else +# include "canonical_aix.h" +# endif +#endif +#ifdef USE_OSF1 +# if defined __osf__ +# include "canonical_osf1_sysosf1.h" +# else +# include "canonical_osf1.h" +# endif +#endif +#ifdef USE_DOS +# include "canonical_dos.h" +#endif +#ifdef USE_EXTRA +# include "canonical_extra.h" +#endif +#if defined _AIX +# include "canonical_local_sysaix.h" +#elif defined hpux || defined __hpux +# include "canonical_local_syshpux.h" +#elif defined __osf__ +# include "canonical_local_sysosf1.h" +#elif defined __sun +# include "canonical_local_syssolaris.h" +#else +# include "canonical_local.h" +#endif +}; + +const char * iconv_canonicalize (const char * name) +{ + const char* code; + char buf[MAX_WORD_LENGTH+10+1]; + const char* cp; + char* bp; + const struct alias * ap; + unsigned int count; + unsigned int index; + const char* pool; + + /* Before calling aliases_lookup, convert the input string to upper case, + * and check whether it's entirely ASCII (we call gperf with option "-7" + * to achieve a smaller table) and non-empty. If it's not entirely ASCII, + * or if it's too long, it is not a valid encoding name. + */ + for (code = name;;) { + /* Search code in the table. */ + for (cp = code, bp = buf, count = MAX_WORD_LENGTH+10+1; ; cp++, bp++) { + unsigned char c = * (unsigned char *) cp; + if (c >= 0x80) + goto invalid; + if (c >= 'a' && c <= 'z') + c -= 'a'-'A'; + *bp = c; + if (c == '\0') + break; + if (--count == 0) + goto invalid; + } + for (;;) { + if (bp-buf >= 10 && memcmp(bp-10,"//TRANSLIT",10)==0) { + bp -= 10; + *bp = '\0'; + continue; + } + if (bp-buf >= 8 && memcmp(bp-8,"//IGNORE",8)==0) { + bp -= 8; + *bp = '\0'; + continue; + } + break; + } + if (buf[0] == '\0') { + code = locale_charset(); + /* Avoid an endless loop that could occur when using an older version + of localcharset.c. */ + if (code[0] == '\0') + goto invalid; + continue; + } + pool = stringpool; + ap = aliases_lookup(buf,bp-buf); + if (ap == NULL) { + pool = stringpool2; + ap = aliases2_lookup(buf); + if (ap == NULL) + goto invalid; + } + if (ap->encoding_index == ei_local_char) { + code = locale_charset(); + /* Avoid an endless loop that could occur when using an older version + of localcharset.c. */ + if (code[0] == '\0') + goto invalid; + continue; + } + if (ap->encoding_index == ei_local_wchar_t) { + /* On systems which define __STDC_ISO_10646__, wchar_t is Unicode. + This is also the case on native Woe32 systems and Cygwin >= 1.7, where + we know that it is UTF-16. */ +#if ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || (defined __CYGWIN__ && CYGWIN_VERSION_DLL_MAJOR >= 1007) + if (sizeof(wchar_t) == 4) { + index = ei_ucs4internal; + break; + } + if (sizeof(wchar_t) == 2) { +# if WORDS_LITTLEENDIAN + index = ei_utf16le; +# else + index = ei_utf16be; +# endif + break; + } +#elif __STDC_ISO_10646__ + if (sizeof(wchar_t) == 4) { + index = ei_ucs4internal; + break; + } + if (sizeof(wchar_t) == 2) { + index = ei_ucs2internal; + break; + } + if (sizeof(wchar_t) == 1) { + index = ei_iso8859_1; + break; + } +#endif + } + index = ap->encoding_index; + break; + } + return all_canonical[index] + pool; + invalid: + return name; +} + +int _libiconv_version = _LIBICONV_VERSION; + +#if defined __FreeBSD__ && !defined __gnu_freebsd__ +/* GNU libiconv is the native FreeBSD iconv implementation since 2002. + It wants to define the symbols 'iconv_open', 'iconv', 'iconv_close'. */ +#define strong_alias(name, aliasname) _strong_alias(name, aliasname) +#define _strong_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((alias (#name))); +#undef iconv_open +#undef iconv +#undef iconv_close +strong_alias (libiconv_open, iconv_open) +strong_alias (libiconv, iconv) +strong_alias (libiconv_close, iconv_close) +#endif + +#endif diff --git a/libs/libiconv/lib/iconv_open1.h b/libs/libiconv/lib/iconv_open1.h new file mode 100644 index 00000000..acee5a4a --- /dev/null +++ b/libs/libiconv/lib/iconv_open1.h @@ -0,0 +1,229 @@ +/* + * Copyright (C) 1999-2008, 2011 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Part 1 of iconv_open. + Input: const char* tocode, const char* fromcode. + Output: + unsigned int from_index; + int from_wchar; + unsigned int to_index; + int to_wchar; + int transliterate; + int discard_ilseq; + Jumps to 'invalid' in case of errror. + */ +{ + char buf[MAX_WORD_LENGTH+10+1]; + const char* cp; + char* bp; + const struct alias * ap; + unsigned int count; + + transliterate = 0; + discard_ilseq = 0; + + /* Before calling aliases_lookup, convert the input string to upper case, + * and check whether it's entirely ASCII (we call gperf with option "-7" + * to achieve a smaller table) and non-empty. If it's not entirely ASCII, + * or if it's too long, it is not a valid encoding name. + */ + for (to_wchar = 0;;) { + /* Search tocode in the table. */ + for (cp = tocode, bp = buf, count = MAX_WORD_LENGTH+10+1; ; cp++, bp++) { + unsigned char c = * (unsigned char *) cp; + if (c >= 0x80) + goto invalid; + if (c >= 'a' && c <= 'z') + c -= 'a'-'A'; + *bp = c; + if (c == '\0') + break; + if (--count == 0) + goto invalid; + } + for (;;) { + if (bp-buf >= 10 && memcmp(bp-10,"//TRANSLIT",10)==0) { + bp -= 10; + *bp = '\0'; + transliterate = 1; + continue; + } + if (bp-buf >= 8 && memcmp(bp-8,"//IGNORE",8)==0) { + bp -= 8; + *bp = '\0'; + discard_ilseq = 1; + continue; + } + break; + } + if (buf[0] == '\0') { + tocode = locale_charset(); + /* Avoid an endless loop that could occur when using an older version + of localcharset.c. */ + if (tocode[0] == '\0') + goto invalid; + continue; + } + ap = aliases_lookup(buf,bp-buf); + if (ap == NULL) { + ap = aliases2_lookup(buf); + if (ap == NULL) + goto invalid; + } + if (ap->encoding_index == ei_local_char) { + tocode = locale_charset(); + /* Avoid an endless loop that could occur when using an older version + of localcharset.c. */ + if (tocode[0] == '\0') + goto invalid; + continue; + } + if (ap->encoding_index == ei_local_wchar_t) { + /* On systems which define __STDC_ISO_10646__, wchar_t is Unicode. + This is also the case on native Woe32 systems and Cygwin >= 1.7, where + we know that it is UTF-16. */ +#if ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || (defined __CYGWIN__ && CYGWIN_VERSION_DLL_MAJOR >= 1007) + if (sizeof(wchar_t) == 4) { + to_index = ei_ucs4internal; + break; + } + if (sizeof(wchar_t) == 2) { +# if WORDS_LITTLEENDIAN + to_index = ei_utf16le; +# else + to_index = ei_utf16be; +# endif + break; + } +#elif __STDC_ISO_10646__ + if (sizeof(wchar_t) == 4) { + to_index = ei_ucs4internal; + break; + } + if (sizeof(wchar_t) == 2) { + to_index = ei_ucs2internal; + break; + } + if (sizeof(wchar_t) == 1) { + to_index = ei_iso8859_1; + break; + } +#endif +#if HAVE_MBRTOWC + to_wchar = 1; + tocode = locale_charset(); + continue; +#endif + goto invalid; + } + to_index = ap->encoding_index; + break; + } + for (from_wchar = 0;;) { + /* Search fromcode in the table. */ + for (cp = fromcode, bp = buf, count = MAX_WORD_LENGTH+10+1; ; cp++, bp++) { + unsigned char c = * (unsigned char *) cp; + if (c >= 0x80) + goto invalid; + if (c >= 'a' && c <= 'z') + c -= 'a'-'A'; + *bp = c; + if (c == '\0') + break; + if (--count == 0) + goto invalid; + } + for (;;) { + if (bp-buf >= 10 && memcmp(bp-10,"//TRANSLIT",10)==0) { + bp -= 10; + *bp = '\0'; + continue; + } + if (bp-buf >= 8 && memcmp(bp-8,"//IGNORE",8)==0) { + bp -= 8; + *bp = '\0'; + continue; + } + break; + } + if (buf[0] == '\0') { + fromcode = locale_charset(); + /* Avoid an endless loop that could occur when using an older version + of localcharset.c. */ + if (fromcode[0] == '\0') + goto invalid; + continue; + } + ap = aliases_lookup(buf,bp-buf); + if (ap == NULL) { + ap = aliases2_lookup(buf); + if (ap == NULL) + goto invalid; + } + if (ap->encoding_index == ei_local_char) { + fromcode = locale_charset(); + /* Avoid an endless loop that could occur when using an older version + of localcharset.c. */ + if (fromcode[0] == '\0') + goto invalid; + continue; + } + if (ap->encoding_index == ei_local_wchar_t) { + /* On systems which define __STDC_ISO_10646__, wchar_t is Unicode. + This is also the case on native Woe32 systems and Cygwin >= 1.7, where + we know that it is UTF-16. */ +#if ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || (defined __CYGWIN__ && CYGWIN_VERSION_DLL_MAJOR >= 1007) + if (sizeof(wchar_t) == 4) { + from_index = ei_ucs4internal; + break; + } + if (sizeof(wchar_t) == 2) { +# if WORDS_LITTLEENDIAN + from_index = ei_utf16le; +# else + from_index = ei_utf16be; +# endif + break; + } +#elif __STDC_ISO_10646__ + if (sizeof(wchar_t) == 4) { + from_index = ei_ucs4internal; + break; + } + if (sizeof(wchar_t) == 2) { + from_index = ei_ucs2internal; + break; + } + if (sizeof(wchar_t) == 1) { + from_index = ei_iso8859_1; + break; + } +#endif +#if HAVE_WCRTOMB + from_wchar = 1; + fromcode = locale_charset(); + continue; +#endif + goto invalid; + } + from_index = ap->encoding_index; + break; + } +} diff --git a/libs/libiconv/lib/iconv_open2.h b/libs/libiconv/lib/iconv_open2.h new file mode 100644 index 00000000..6d6296f0 --- /dev/null +++ b/libs/libiconv/lib/iconv_open2.h @@ -0,0 +1,89 @@ +/* + * Copyright (C) 1999-2009 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Part 2 of iconv_open. + Input: + struct conv_struct * cd; + unsigned int from_index; + int from_wchar; + unsigned int to_index; + int to_wchar; + int transliterate; + int discard_ilseq; + Output: none. + Side effects: Fills cd. + */ + + cd->iindex = from_index; + cd->ifuncs = all_encodings[from_index].ifuncs; + cd->oindex = to_index; + cd->ofuncs = all_encodings[to_index].ofuncs; + cd->oflags = all_encodings[to_index].oflags; + /* Initialize the loop functions. */ +#if HAVE_MBRTOWC + if (to_wchar) { +#if HAVE_WCRTOMB + if (from_wchar) { + cd->lfuncs.loop_convert = wchar_id_loop_convert; + cd->lfuncs.loop_reset = wchar_id_loop_reset; + } else +#endif + { + cd->lfuncs.loop_convert = wchar_to_loop_convert; + cd->lfuncs.loop_reset = wchar_to_loop_reset; + } + } else +#endif + { +#if HAVE_WCRTOMB + if (from_wchar) { + cd->lfuncs.loop_convert = wchar_from_loop_convert; + cd->lfuncs.loop_reset = wchar_from_loop_reset; + } else +#endif + { + cd->lfuncs.loop_convert = unicode_loop_convert; + cd->lfuncs.loop_reset = unicode_loop_reset; + } + } + /* Initialize the states. */ + memset(&cd->istate,'\0',sizeof(state_t)); + memset(&cd->ostate,'\0',sizeof(state_t)); + /* Initialize the operation flags. */ + cd->transliterate = transliterate; + cd->discard_ilseq = discard_ilseq; + #ifndef LIBICONV_PLUG + cd->fallbacks.mb_to_uc_fallback = NULL; + cd->fallbacks.uc_to_mb_fallback = NULL; + cd->fallbacks.mb_to_wc_fallback = NULL; + cd->fallbacks.wc_to_mb_fallback = NULL; + cd->fallbacks.data = NULL; + cd->hooks.uc_hook = NULL; + cd->hooks.wc_hook = NULL; + cd->hooks.data = NULL; + #endif + /* Initialize additional fields. */ + if (from_wchar != to_wchar) { + struct wchar_conv_struct * wcd = (struct wchar_conv_struct *) cd; +#if HAVE_WCRTOMB || HAVE_MBRTOWC + memset(&wcd->state,'\0',sizeof(mbstate_t)); +#endif + } + /* Done. */ diff --git a/libs/libiconv/lib/iso2022_cn.h b/libs/libiconv/lib/iso2022_cn.h new file mode 100644 index 00000000..d7e3e393 --- /dev/null +++ b/libs/libiconv/lib/iso2022_cn.h @@ -0,0 +1,324 @@ +/* + * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-2022-CN + */ + +/* Specification: RFC 1922 */ + +#define ESC 0x1b +#define SO 0x0e +#define SI 0x0f + +/* + * The state is composed of one of the following values + */ +#define STATE_ASCII 0 +#define STATE_TWOBYTE 1 +/* + * and one of the following values, << 8 + */ +#define STATE2_NONE 0 +#define STATE2_DESIGNATED_GB2312 1 +#define STATE2_DESIGNATED_CNS11643_1 2 +/* + * and one of the following values, << 16 + */ +#define STATE3_NONE 0 +#define STATE3_DESIGNATED_CNS11643_2 1 + +#define SPLIT_STATE \ + unsigned int state1 = state & 0xff, state2 = (state >> 8) & 0xff, state3 = state >> 16 +#define COMBINE_STATE \ + state = (state3 << 16) | (state2 << 8) | state1 + +static int +iso2022_cn_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + state_t state = conv->istate; + SPLIT_STATE; + int count = 0; + unsigned char c; + for (;;) { + c = *s; + if (c == ESC) { + if (n < count+4) + goto none; + if (s[1] == '$') { + if (s[2] == ')') { + if (s[3] == 'A') { + state2 = STATE2_DESIGNATED_GB2312; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + if (s[3] == 'G') { + state2 = STATE2_DESIGNATED_CNS11643_1; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + } + if (s[2] == '*') { + if (s[3] == 'H') { + state3 = STATE3_DESIGNATED_CNS11643_2; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + } + } + if (s[1] == 'N') { + switch (state3) { + case STATE3_NONE: + goto ilseq; + case STATE3_DESIGNATED_CNS11643_2: + if (s[2] < 0x80 && s[3] < 0x80) { + int ret = cns11643_2_mbtowc(conv,pwc,s+2,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + COMBINE_STATE; + conv->istate = state; + return count+4; + } else + goto ilseq; + default: abort(); + } + } + goto ilseq; + } + if (c == SO) { + if (state2 != STATE2_DESIGNATED_GB2312 && state2 != STATE2_DESIGNATED_CNS11643_1) + goto ilseq; + state1 = STATE_TWOBYTE; + s++; count++; + if (n < count+1) + goto none; + continue; + } + if (c == SI) { + state1 = STATE_ASCII; + s++; count++; + if (n < count+1) + goto none; + continue; + } + break; + } + switch (state1) { + case STATE_ASCII: + if (c < 0x80) { + int ret = ascii_mbtowc(conv,pwc,s,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); + if (*pwc == 0x000a || *pwc == 0x000d) { + state2 = STATE2_NONE; state3 = STATE3_NONE; + } + COMBINE_STATE; + conv->istate = state; + return count+1; + } else + goto ilseq; + case STATE_TWOBYTE: + if (n < count+2) + goto none; + if (s[0] < 0x80 && s[1] < 0x80) { + int ret; + switch (state2) { + case STATE2_NONE: + goto ilseq; + case STATE2_DESIGNATED_GB2312: + ret = gb2312_mbtowc(conv,pwc,s,2); break; + case STATE2_DESIGNATED_CNS11643_1: + ret = cns11643_1_mbtowc(conv,pwc,s,2); break; + default: abort(); + } + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + COMBINE_STATE; + conv->istate = state; + return count+2; + } else + goto ilseq; + default: abort(); + } + +none: + COMBINE_STATE; + conv->istate = state; + return RET_TOOFEW(count); + +ilseq: + COMBINE_STATE; + conv->istate = state; + return RET_SHIFT_ILSEQ(count); +} + +static int +iso2022_cn_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + state_t state = conv->ostate; + SPLIT_STATE; + unsigned char buf[3]; + int ret; + + /* There is no need to handle Unicode 3.1 tag characters and to look for + "zh-CN" or "zh-TW" tags, because GB2312 and CNS11643 are disjoint. */ + + /* Try ASCII. */ + ret = ascii_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] < 0x80) { + int count = (state1 == STATE_ASCII ? 1 : 2); + if (n < count) + return RET_TOOSMALL; + if (state1 != STATE_ASCII) { + r[0] = SI; + r += 1; + state1 = STATE_ASCII; + } + r[0] = buf[0]; + if (wc == 0x000a || wc == 0x000d) { + state2 = STATE2_NONE; state3 = STATE3_NONE; + } + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + /* Try GB 2312-1980. */ + ret = gb2312_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (buf[0] < 0x80 && buf[1] < 0x80) { + int count = (state2 == STATE2_DESIGNATED_GB2312 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2; + if (n < count) + return RET_TOOSMALL; + if (state2 != STATE2_DESIGNATED_GB2312) { + r[0] = ESC; + r[1] = '$'; + r[2] = ')'; + r[3] = 'A'; + r += 4; + state2 = STATE2_DESIGNATED_GB2312; + } + if (state1 != STATE_TWOBYTE) { + r[0] = SO; + r += 1; + state1 = STATE_TWOBYTE; + } + r[0] = buf[0]; + r[1] = buf[1]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + ret = cns11643_wctomb(conv,buf,wc,3); + if (ret != RET_ILUNI) { + if (ret != 3) abort(); + + /* Try CNS 11643-1992 Plane 1. */ + if (buf[0] == 1 && buf[1] < 0x80 && buf[2] < 0x80) { + int count = (state2 == STATE2_DESIGNATED_CNS11643_1 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2; + if (n < count) + return RET_TOOSMALL; + if (state2 != STATE2_DESIGNATED_CNS11643_1) { + r[0] = ESC; + r[1] = '$'; + r[2] = ')'; + r[3] = 'G'; + r += 4; + state2 = STATE2_DESIGNATED_CNS11643_1; + } + if (state1 != STATE_TWOBYTE) { + r[0] = SO; + r += 1; + state1 = STATE_TWOBYTE; + } + r[0] = buf[1]; + r[1] = buf[2]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + + /* Try CNS 11643-1992 Plane 2. */ + if (buf[0] == 2 && buf[1] < 0x80 && buf[2] < 0x80) { + int count = (state3 == STATE3_DESIGNATED_CNS11643_2 ? 0 : 4) + 4; + if (n < count) + return RET_TOOSMALL; + if (state3 != STATE3_DESIGNATED_CNS11643_2) { + r[0] = ESC; + r[1] = '$'; + r[2] = '*'; + r[3] = 'H'; + r += 4; + state3 = STATE3_DESIGNATED_CNS11643_2; + } + r[0] = ESC; + r[1] = 'N'; + r[2] = buf[1]; + r[3] = buf[2]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + return RET_ILUNI; +} + +static int +iso2022_cn_reset (conv_t conv, unsigned char *r, int n) +{ + state_t state = conv->ostate; + SPLIT_STATE; + (void)state2; + (void)state3; + if (state1 != STATE_ASCII) { + if (n < 1) + return RET_TOOSMALL; + r[0] = SI; + /* conv->ostate = 0; will be done by the caller */ + return 1; + } else + return 0; +} + +#undef COMBINE_STATE +#undef SPLIT_STATE +#undef STATE3_DESIGNATED_CNS11643_2 +#undef STATE3_NONE +#undef STATE2_DESIGNATED_CNS11643_1 +#undef STATE2_DESIGNATED_GB2312 +#undef STATE2_NONE +#undef STATE_TWOBYTE +#undef STATE_ASCII diff --git a/libs/libiconv/lib/iso2022_cnext.h b/libs/libiconv/lib/iso2022_cnext.h new file mode 100644 index 00000000..f8488709 --- /dev/null +++ b/libs/libiconv/lib/iso2022_cnext.h @@ -0,0 +1,590 @@ +/* + * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-2022-CN-EXT + */ + +/* Specification: RFC 1922 */ + +#define ESC 0x1b +#define SO 0x0e +#define SI 0x0f + +/* + * The state is composed of one of the following values + */ +#define STATE_ASCII 0 +#define STATE_TWOBYTE 1 +/* + * and one of the following values, << 8 + */ +#define STATE2_NONE 0 +#define STATE2_DESIGNATED_GB2312 1 +#define STATE2_DESIGNATED_CNS11643_1 2 +#define STATE2_DESIGNATED_ISO_IR_165 3 +/* + * and one of the following values, << 16 + */ +#define STATE3_NONE 0 +#define STATE3_DESIGNATED_CNS11643_2 1 +/* + * and one of the following values, << 24 + */ +#define STATE4_NONE 0 +#define STATE4_DESIGNATED_CNS11643_3 1 +#define STATE4_DESIGNATED_CNS11643_4 2 +#define STATE4_DESIGNATED_CNS11643_5 3 +#define STATE4_DESIGNATED_CNS11643_6 4 +#define STATE4_DESIGNATED_CNS11643_7 5 + +#define SPLIT_STATE \ + unsigned int state1 = state & 0xff, state2 = (state >> 8) & 0xff, state3 = (state >> 16) & 0xff, state4 = state >> 24 +#define COMBINE_STATE \ + state = (state4 << 24) | (state3 << 16) | (state2 << 8) | state1 + +static int +iso2022_cn_ext_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + state_t state = conv->istate; + SPLIT_STATE; + int count = 0; + unsigned char c; + for (;;) { + c = *s; + if (c == ESC) { + if (n < count+4) + goto none; + if (s[1] == '$') { + if (s[2] == ')') { + if (s[3] == 'A') { + state2 = STATE2_DESIGNATED_GB2312; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + if (s[3] == 'G') { + state2 = STATE2_DESIGNATED_CNS11643_1; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + if (s[3] == 'E') { + state2 = STATE2_DESIGNATED_ISO_IR_165; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + } + if (s[2] == '*') { + if (s[3] == 'H') { + state3 = STATE3_DESIGNATED_CNS11643_2; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + } + if (s[2] == '+') { + if (s[3] == 'I') { + state4 = STATE4_DESIGNATED_CNS11643_3; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + if (s[3] == 'J') { + state4 = STATE4_DESIGNATED_CNS11643_4; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + if (s[3] == 'K') { + state4 = STATE4_DESIGNATED_CNS11643_5; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + if (s[3] == 'L') { + state4 = STATE4_DESIGNATED_CNS11643_6; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + if (s[3] == 'M') { + state4 = STATE4_DESIGNATED_CNS11643_7; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + } + } + if (s[1] == 'N') { + switch (state3) { + case STATE3_NONE: + goto ilseq; + case STATE3_DESIGNATED_CNS11643_2: + if (s[2] < 0x80 && s[3] < 0x80) { + int ret = cns11643_2_mbtowc(conv,pwc,s+2,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + COMBINE_STATE; + conv->istate = state; + return count+4; + } else + goto ilseq; + default: abort(); + } + } + if (s[1] == 'O') { + switch (state4) { + case STATE4_NONE: + goto ilseq; + case STATE4_DESIGNATED_CNS11643_3: + if (s[2] < 0x80 && s[3] < 0x80) { + int ret = cns11643_3_mbtowc(conv,pwc,s+2,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + COMBINE_STATE; + conv->istate = state; + return count+4; + } else + goto ilseq; + case STATE4_DESIGNATED_CNS11643_4: + if (s[2] < 0x80 && s[3] < 0x80) { + int ret = cns11643_4_mbtowc(conv,pwc,s+2,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + COMBINE_STATE; + conv->istate = state; + return count+4; + } else + goto ilseq; + case STATE4_DESIGNATED_CNS11643_5: + if (s[2] < 0x80 && s[3] < 0x80) { + int ret = cns11643_5_mbtowc(conv,pwc,s+2,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + COMBINE_STATE; + conv->istate = state; + return count+4; + } else + goto ilseq; + case STATE4_DESIGNATED_CNS11643_6: + if (s[2] < 0x80 && s[3] < 0x80) { + int ret = cns11643_6_mbtowc(conv,pwc,s+2,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + COMBINE_STATE; + conv->istate = state; + return count+4; + } else + goto ilseq; + case STATE4_DESIGNATED_CNS11643_7: + if (s[2] < 0x80 && s[3] < 0x80) { + int ret = cns11643_7_mbtowc(conv,pwc,s+2,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + COMBINE_STATE; + conv->istate = state; + return count+4; + } else + goto ilseq; + default: abort(); + } + } + goto ilseq; + } + if (c == SO) { + if (state2 != STATE2_DESIGNATED_GB2312 && state2 != STATE2_DESIGNATED_CNS11643_1 && state2 != STATE2_DESIGNATED_ISO_IR_165) + goto ilseq; + state1 = STATE_TWOBYTE; + s++; count++; + if (n < count+1) + goto none; + continue; + } + if (c == SI) { + state1 = STATE_ASCII; + s++; count++; + if (n < count+1) + goto none; + continue; + } + break; + } + switch (state1) { + case STATE_ASCII: + if (c < 0x80) { + int ret = ascii_mbtowc(conv,pwc,s,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); + if (*pwc == 0x000a || *pwc == 0x000d) { + state2 = STATE2_NONE; state3 = STATE3_NONE; state4 = STATE3_NONE; + } + COMBINE_STATE; + conv->istate = state; + return count+1; + } else + goto ilseq; + case STATE_TWOBYTE: + if (n < count+2) + goto none; + if (s[0] < 0x80 && s[1] < 0x80) { + int ret; + switch (state2) { + case STATE2_NONE: + goto ilseq; + case STATE2_DESIGNATED_GB2312: + ret = gb2312_mbtowc(conv,pwc,s,2); break; + case STATE2_DESIGNATED_CNS11643_1: + ret = cns11643_1_mbtowc(conv,pwc,s,2); break; + case STATE2_DESIGNATED_ISO_IR_165: + ret = isoir165_mbtowc(conv,pwc,s,2); break; + default: abort(); + } + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + COMBINE_STATE; + conv->istate = state; + return count+2; + } else + goto ilseq; + default: abort(); + } + +none: + COMBINE_STATE; + conv->istate = state; + return RET_TOOFEW(count); + +ilseq: + COMBINE_STATE; + conv->istate = state; + return RET_SHIFT_ILSEQ(count); +} + +static int +iso2022_cn_ext_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + state_t state = conv->ostate; + SPLIT_STATE; + unsigned char buf[3]; + int ret; + + /* There is no need to handle Unicode 3.1 tag characters and to look for + "zh-CN" or "zh-TW" tags, because GB2312 and CNS11643 are disjoint. */ + + /* Try ASCII. */ + ret = ascii_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] < 0x80) { + int count = (state1 == STATE_ASCII ? 1 : 2); + if (n < count) + return RET_TOOSMALL; + if (state1 != STATE_ASCII) { + r[0] = SI; + r += 1; + state1 = STATE_ASCII; + } + r[0] = buf[0]; + if (wc == 0x000a || wc == 0x000d) { + state2 = STATE2_NONE; state3 = STATE3_NONE; state4 = STATE3_NONE; + } + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + /* Try GB 2312-1980. */ + ret = gb2312_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (buf[0] < 0x80 && buf[1] < 0x80) { + int count = (state2 == STATE2_DESIGNATED_GB2312 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2; + if (n < count) + return RET_TOOSMALL; + if (state2 != STATE2_DESIGNATED_GB2312) { + r[0] = ESC; + r[1] = '$'; + r[2] = ')'; + r[3] = 'A'; + r += 4; + state2 = STATE2_DESIGNATED_GB2312; + } + if (state1 != STATE_TWOBYTE) { + r[0] = SO; + r += 1; + state1 = STATE_TWOBYTE; + } + r[0] = buf[0]; + r[1] = buf[1]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + ret = cns11643_wctomb(conv,buf,wc,3); + if (ret != RET_ILUNI) { + if (ret != 3) abort(); + + /* Try CNS 11643-1992 Plane 1. */ + if (buf[0] == 1 && buf[1] < 0x80 && buf[2] < 0x80) { + int count = (state2 == STATE2_DESIGNATED_CNS11643_1 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2; + if (n < count) + return RET_TOOSMALL; + if (state2 != STATE2_DESIGNATED_CNS11643_1) { + r[0] = ESC; + r[1] = '$'; + r[2] = ')'; + r[3] = 'G'; + r += 4; + state2 = STATE2_DESIGNATED_CNS11643_1; + } + if (state1 != STATE_TWOBYTE) { + r[0] = SO; + r += 1; + state1 = STATE_TWOBYTE; + } + r[0] = buf[1]; + r[1] = buf[2]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + + /* Try CNS 11643-1992 Plane 2. */ + if (buf[0] == 2 && buf[1] < 0x80 && buf[2] < 0x80) { + int count = (state3 == STATE3_DESIGNATED_CNS11643_2 ? 0 : 4) + 4; + if (n < count) + return RET_TOOSMALL; + if (state3 != STATE3_DESIGNATED_CNS11643_2) { + r[0] = ESC; + r[1] = '$'; + r[2] = '*'; + r[3] = 'H'; + r += 4; + state3 = STATE3_DESIGNATED_CNS11643_2; + } + r[0] = ESC; + r[1] = 'N'; + r[2] = buf[1]; + r[3] = buf[2]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + + /* Try CNS 11643-1992 Plane 3. */ + if (buf[0] == 3 && buf[1] < 0x80 && buf[2] < 0x80) { + int count = (state4 == STATE4_DESIGNATED_CNS11643_3 ? 0 : 4) + 4; + if (n < count) + return RET_TOOSMALL; + if (state4 != STATE4_DESIGNATED_CNS11643_3) { + r[0] = ESC; + r[1] = '$'; + r[2] = '+'; + r[3] = 'I'; + r += 4; + state4 = STATE4_DESIGNATED_CNS11643_3; + } + r[0] = ESC; + r[1] = 'O'; + r[2] = buf[1]; + r[3] = buf[2]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + + /* Try CNS 11643-1992 Plane 4. */ + if (buf[0] == 4 && buf[1] < 0x80 && buf[2] < 0x80) { + int count = (state4 == STATE4_DESIGNATED_CNS11643_4 ? 0 : 4) + 4; + if (n < count) + return RET_TOOSMALL; + if (state4 != STATE4_DESIGNATED_CNS11643_4) { + r[0] = ESC; + r[1] = '$'; + r[2] = '+'; + r[3] = 'J'; + r += 4; + state4 = STATE4_DESIGNATED_CNS11643_4; + } + r[0] = ESC; + r[1] = 'O'; + r[2] = buf[1]; + r[3] = buf[2]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + + /* Try CNS 11643-1992 Plane 5. */ + if (buf[0] == 5 && buf[1] < 0x80 && buf[2] < 0x80) { + int count = (state4 == STATE4_DESIGNATED_CNS11643_5 ? 0 : 4) + 4; + if (n < count) + return RET_TOOSMALL; + if (state4 != STATE4_DESIGNATED_CNS11643_5) { + r[0] = ESC; + r[1] = '$'; + r[2] = '+'; + r[3] = 'K'; + r += 4; + state4 = STATE4_DESIGNATED_CNS11643_5; + } + r[0] = ESC; + r[1] = 'O'; + r[2] = buf[1]; + r[3] = buf[2]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + + /* Try CNS 11643-1992 Plane 6. */ + if (buf[0] == 6 && buf[1] < 0x80 && buf[2] < 0x80) { + int count = (state4 == STATE4_DESIGNATED_CNS11643_6 ? 0 : 4) + 4; + if (n < count) + return RET_TOOSMALL; + if (state4 != STATE4_DESIGNATED_CNS11643_6) { + r[0] = ESC; + r[1] = '$'; + r[2] = '+'; + r[3] = 'L'; + r += 4; + state4 = STATE4_DESIGNATED_CNS11643_6; + } + r[0] = ESC; + r[1] = 'O'; + r[2] = buf[1]; + r[3] = buf[2]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + + /* Try CNS 11643-1992 Plane 7. */ + if (buf[0] == 7 && buf[1] < 0x80 && buf[2] < 0x80) { + int count = (state4 == STATE4_DESIGNATED_CNS11643_7 ? 0 : 4) + 4; + if (n < count) + return RET_TOOSMALL; + if (state4 != STATE4_DESIGNATED_CNS11643_7) { + r[0] = ESC; + r[1] = '$'; + r[2] = '+'; + r[3] = 'M'; + r += 4; + state4 = STATE4_DESIGNATED_CNS11643_7; + } + r[0] = ESC; + r[1] = 'O'; + r[2] = buf[1]; + r[3] = buf[2]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + + } + + /* Try ISO-IR-165. */ + ret = isoir165_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (buf[0] < 0x80 && buf[1] < 0x80) { + int count = (state2 == STATE2_DESIGNATED_ISO_IR_165 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2; + if (n < count) + return RET_TOOSMALL; + if (state2 != STATE2_DESIGNATED_ISO_IR_165) { + r[0] = ESC; + r[1] = '$'; + r[2] = ')'; + r[3] = 'E'; + r += 4; + state2 = STATE2_DESIGNATED_ISO_IR_165; + } + if (state1 != STATE_TWOBYTE) { + r[0] = SO; + r += 1; + state1 = STATE_TWOBYTE; + } + r[0] = buf[0]; + r[1] = buf[1]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + return RET_ILUNI; +} + +static int +iso2022_cn_ext_reset (conv_t conv, unsigned char *r, int n) +{ + state_t state = conv->ostate; + SPLIT_STATE; + (void)state2; + (void)state3; + (void)state4; + if (state1 != STATE_ASCII) { + if (n < 1) + return RET_TOOSMALL; + r[0] = SI; + /* conv->ostate = 0; will be done by the caller */ + return 1; + } else + return 0; +} + +#undef COMBINE_STATE +#undef SPLIT_STATE +#undef STATE4_DESIGNATED_CNS11643_7 +#undef STATE4_DESIGNATED_CNS11643_6 +#undef STATE4_DESIGNATED_CNS11643_5 +#undef STATE4_DESIGNATED_CNS11643_4 +#undef STATE4_DESIGNATED_CNS11643_3 +#undef STATE4_NONE +#undef STATE3_DESIGNATED_CNS11643_2 +#undef STATE3_NONE +#undef STATE2_DESIGNATED_ISO_IR_165 +#undef STATE2_DESIGNATED_CNS11643_1 +#undef STATE2_DESIGNATED_GB2312 +#undef STATE2_NONE +#undef STATE_TWOBYTE +#undef STATE_ASCII diff --git a/libs/libiconv/lib/iso2022_jp.h b/libs/libiconv/lib/iso2022_jp.h new file mode 100644 index 00000000..1c8abec1 --- /dev/null +++ b/libs/libiconv/lib/iso2022_jp.h @@ -0,0 +1,216 @@ +/* + * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-2022-JP + */ + +/* Specification: RFC 1468 */ + +#define ESC 0x1b + +/* + * The state can be one of the following values. + */ +#define STATE_ASCII 0 +#define STATE_JISX0201ROMAN 1 +#define STATE_JISX0208 2 + +static int +iso2022_jp_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + state_t state = conv->istate; + int count = 0; + unsigned char c; + for (;;) { + c = *s; + if (c == ESC) { + if (n < count+3) + goto none; + if (s[1] == '(') { + if (s[2] == 'B') { + state = STATE_ASCII; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + if (s[2] == 'J') { + state = STATE_JISX0201ROMAN; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + goto ilseq; + } + if (s[1] == '$') { + if (s[2] == '@' || s[2] == 'B') { + /* We don't distinguish JIS X 0208-1978 and JIS X 0208-1983. */ + state = STATE_JISX0208; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + goto ilseq; + } + goto ilseq; + } + break; + } + switch (state) { + case STATE_ASCII: + if (c < 0x80) { + int ret = ascii_mbtowc(conv,pwc,s,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); + conv->istate = state; + return count+1; + } else + goto ilseq; + case STATE_JISX0201ROMAN: + if (c < 0x80) { + int ret = jisx0201_mbtowc(conv,pwc,s,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); + conv->istate = state; + return count+1; + } else + goto ilseq; + case STATE_JISX0208: + if (n < count+2) + goto none; + if (s[0] < 0x80 && s[1] < 0x80) { + int ret = jisx0208_mbtowc(conv,pwc,s,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + conv->istate = state; + return count+2; + } else + goto ilseq; + default: abort(); + } + +none: + conv->istate = state; + return RET_TOOFEW(count); + +ilseq: + conv->istate = state; + return RET_SHIFT_ILSEQ(count); +} + +static int +iso2022_jp_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + state_t state = conv->ostate; + unsigned char buf[2]; + int ret; + + /* Try ASCII. */ + ret = ascii_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] < 0x80) { + int count = (state == STATE_ASCII ? 1 : 4); + if (n < count) + return RET_TOOSMALL; + if (state != STATE_ASCII) { + r[0] = ESC; + r[1] = '('; + r[2] = 'B'; + r += 3; + state = STATE_ASCII; + } + r[0] = buf[0]; + conv->ostate = state; + return count; + } + } + + /* Try JIS X 0201-1976 Roman. */ + ret = jisx0201_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] < 0x80) { + int count = (state == STATE_JISX0201ROMAN ? 1 : 4); + if (n < count) + return RET_TOOSMALL; + if (state != STATE_JISX0201ROMAN) { + r[0] = ESC; + r[1] = '('; + r[2] = 'J'; + r += 3; + state = STATE_JISX0201ROMAN; + } + r[0] = buf[0]; + conv->ostate = state; + return count; + } + } + + /* Try JIS X 0208-1990 in place of JIS X 0208-1978 and JIS X 0208-1983. */ + ret = jisx0208_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (buf[0] < 0x80 && buf[1] < 0x80) { + int count = (state == STATE_JISX0208 ? 2 : 5); + if (n < count) + return RET_TOOSMALL; + if (state != STATE_JISX0208) { + r[0] = ESC; + r[1] = '$'; + r[2] = 'B'; + r += 3; + state = STATE_JISX0208; + } + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = state; + return count; + } + } + + return RET_ILUNI; +} + +static int +iso2022_jp_reset (conv_t conv, unsigned char *r, int n) +{ + state_t state = conv->ostate; + if (state != STATE_ASCII) { + if (n < 3) + return RET_TOOSMALL; + r[0] = ESC; + r[1] = '('; + r[2] = 'B'; + /* conv->ostate = 0; will be done by the caller */ + return 3; + } else + return 0; +} + +#undef STATE_JISX0208 +#undef STATE_JISX0201ROMAN +#undef STATE_ASCII diff --git a/libs/libiconv/lib/iso2022_jp1.h b/libs/libiconv/lib/iso2022_jp1.h new file mode 100644 index 00000000..c3094740 --- /dev/null +++ b/libs/libiconv/lib/iso2022_jp1.h @@ -0,0 +1,264 @@ +/* + * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-2022-JP-1 + */ + +/* Specification: RFC 2237 */ + +#define ESC 0x1b + +/* + * The state can be one of the following values. + */ +#define STATE_ASCII 0 +#define STATE_JISX0201ROMAN 1 +#define STATE_JISX0208 2 +#define STATE_JISX0212 3 + +static int +iso2022_jp1_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + state_t state = conv->istate; + int count = 0; + unsigned char c; + for (;;) { + c = *s; + if (c == ESC) { + if (n < count+3) + goto none; + if (s[1] == '(') { + if (s[2] == 'B') { + state = STATE_ASCII; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + if (s[2] == 'J') { + state = STATE_JISX0201ROMAN; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + goto ilseq; + } + if (s[1] == '$') { + if (s[2] == '@' || s[2] == 'B') { + /* We don't distinguish JIS X 0208-1978 and JIS X 0208-1983. */ + state = STATE_JISX0208; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + if (s[2] == '(') { + if (n < count+4) + goto none; + if (s[3] == 'D') { + state = STATE_JISX0212; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + } + goto ilseq; + } + goto ilseq; + } + break; + } + switch (state) { + case STATE_ASCII: + if (c < 0x80) { + int ret = ascii_mbtowc(conv,pwc,s,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); + conv->istate = state; + return count+1; + } else + goto ilseq; + case STATE_JISX0201ROMAN: + if (c < 0x80) { + int ret = jisx0201_mbtowc(conv,pwc,s,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); + conv->istate = state; + return count+1; + } else + goto ilseq; + case STATE_JISX0208: + if (n < count+2) + goto none; + if (s[0] < 0x80 && s[1] < 0x80) { + int ret = jisx0208_mbtowc(conv,pwc,s,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + conv->istate = state; + return count+2; + } else + goto ilseq; + case STATE_JISX0212: + if (n < count+2) + goto none; + if (s[0] < 0x80 && s[1] < 0x80) { + int ret = jisx0212_mbtowc(conv,pwc,s,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + conv->istate = state; + return count+2; + } else + goto ilseq; + default: abort(); + } + +none: + conv->istate = state; + return RET_TOOFEW(count); + +ilseq: + conv->istate = state; + return RET_SHIFT_ILSEQ(count); +} + +static int +iso2022_jp1_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + state_t state = conv->ostate; + unsigned char buf[2]; + int ret; + + /* Try ASCII. */ + ret = ascii_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] < 0x80) { + int count = (state == STATE_ASCII ? 1 : 4); + if (n < count) + return RET_TOOSMALL; + if (state != STATE_ASCII) { + r[0] = ESC; + r[1] = '('; + r[2] = 'B'; + r += 3; + state = STATE_ASCII; + } + r[0] = buf[0]; + conv->ostate = state; + return count; + } + } + + /* Try JIS X 0201-1976 Roman. */ + ret = jisx0201_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] < 0x80) { + int count = (state == STATE_JISX0201ROMAN ? 1 : 4); + if (n < count) + return RET_TOOSMALL; + if (state != STATE_JISX0201ROMAN) { + r[0] = ESC; + r[1] = '('; + r[2] = 'J'; + r += 3; + state = STATE_JISX0201ROMAN; + } + r[0] = buf[0]; + conv->ostate = state; + return count; + } + } + + /* Try JIS X 0208-1990 in place of JIS X 0208-1978 and JIS X 0208-1983. */ + ret = jisx0208_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (buf[0] < 0x80 && buf[1] < 0x80) { + int count = (state == STATE_JISX0208 ? 2 : 5); + if (n < count) + return RET_TOOSMALL; + if (state != STATE_JISX0208) { + r[0] = ESC; + r[1] = '$'; + r[2] = 'B'; + r += 3; + state = STATE_JISX0208; + } + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = state; + return count; + } + } + + /* Try JIS X 0212-1990. */ + ret = jisx0212_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (buf[0] < 0x80 && buf[1] < 0x80) { + int count = (state == STATE_JISX0212 ? 2 : 6); + if (n < count) + return RET_TOOSMALL; + if (state != STATE_JISX0212) { + r[0] = ESC; + r[1] = '$'; + r[2] = '('; + r[3] = 'D'; + r += 4; + state = STATE_JISX0212; + } + r[0] = buf[0]; + r[1] = buf[1]; + conv->ostate = state; + return count; + } + } + + return RET_ILUNI; +} + +static int +iso2022_jp1_reset (conv_t conv, unsigned char *r, int n) +{ + state_t state = conv->ostate; + if (state != STATE_ASCII) { + if (n < 3) + return RET_TOOSMALL; + r[0] = ESC; + r[1] = '('; + r[2] = 'B'; + /* conv->ostate = 0; will be done by the caller */ + return 3; + } else + return 0; +} + +#undef STATE_JISX0212 +#undef STATE_JISX0208 +#undef STATE_JISX0201ROMAN +#undef STATE_ASCII diff --git a/libs/libiconv/lib/iso2022_jp2.h b/libs/libiconv/lib/iso2022_jp2.h new file mode 100644 index 00000000..5e3ca415 --- /dev/null +++ b/libs/libiconv/lib/iso2022_jp2.h @@ -0,0 +1,693 @@ +/* + * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-2022-JP-2 + */ + +/* Specification: RFC 1554 */ +/* ESC '(' 'I' for JISX0201 Katakana is an extension not found in RFC 1554 or + CJK.INF, but implemented in glibc-2.1 and qt-2.0. */ + +#define ESC 0x1b + +/* + * The state is composed of one of the following values + */ +#define STATE_ASCII 0 +#define STATE_JISX0201ROMAN 1 +#define STATE_JISX0201KATAKANA 2 +#define STATE_JISX0208 3 +#define STATE_JISX0212 4 +#define STATE_GB2312 5 +#define STATE_KSC5601 6 +/* + * and one of the following values, << 8 + */ +#define STATE_G2_NONE 0 +#define STATE_G2_ISO8859_1 1 +#define STATE_G2_ISO8859_7 2 + +#define SPLIT_STATE \ + unsigned int state1 = state & 0xff, state2 = state >> 8 +#define COMBINE_STATE \ + state = (state2 << 8) | state1 + +static int +iso2022_jp2_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + state_t state = conv->istate; + SPLIT_STATE; + int count = 0; + unsigned char c; + for (;;) { + c = *s; + if (c == ESC) { + if (n < count+3) + goto none; + if (s[1] == '(') { + if (s[2] == 'B') { + state1 = STATE_ASCII; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + if (s[2] == 'J') { + state1 = STATE_JISX0201ROMAN; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + if (s[2] == 'I') { + state1 = STATE_JISX0201KATAKANA; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + goto ilseq; + } + if (s[1] == '$') { + if (s[2] == '@' || s[2] == 'B') { + /* We don't distinguish JIS X 0208-1978 and JIS X 0208-1983. */ + state1 = STATE_JISX0208; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + if (s[2] == 'A') { + state1 = STATE_GB2312; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + if (s[2] == '(') { + if (n < count+4) + goto none; + if (s[3] == 'D') { + state1 = STATE_JISX0212; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + if (s[3] == 'C') { + state1 = STATE_KSC5601; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + goto ilseq; + } + goto ilseq; + } + if (s[1] == '.') { + if (n < count+3) + goto none; + if (s[2] == 'A') { + state2 = STATE_G2_ISO8859_1; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + if (s[2] == 'F') { + state2 = STATE_G2_ISO8859_7; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + goto ilseq; + } + if (s[1] == 'N') { + switch (state2) { + case STATE_G2_NONE: + goto ilseq; + case STATE_G2_ISO8859_1: + if (s[2] < 0x80) { + unsigned char buf = s[2]+0x80; + int ret = iso8859_1_mbtowc(conv,pwc,&buf,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); + COMBINE_STATE; + conv->istate = state; + return count+3; + } else + goto ilseq; + case STATE_G2_ISO8859_7: + if (s[2] < 0x80) { + unsigned char buf = s[2]+0x80; + int ret = iso8859_7_mbtowc(conv,pwc,&buf,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); + COMBINE_STATE; + conv->istate = state; + return count+3; + } else + goto ilseq; + default: abort(); + } + } + goto ilseq; + } + break; + } + switch (state1) { + case STATE_ASCII: + if (c < 0x80) { + int ret = ascii_mbtowc(conv,pwc,s,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); + if (*pwc == 0x000a || *pwc == 0x000d) + state2 = STATE_G2_NONE; + COMBINE_STATE; + conv->istate = state; + return count+1; + } else + goto ilseq; + case STATE_JISX0201ROMAN: + if (c < 0x80) { + int ret = jisx0201_mbtowc(conv,pwc,s,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); + if (*pwc == 0x000a || *pwc == 0x000d) + state2 = STATE_G2_NONE; + COMBINE_STATE; + conv->istate = state; + return count+1; + } else + goto ilseq; + case STATE_JISX0201KATAKANA: + if (c < 0x80) { + unsigned char buf = c+0x80; + int ret = jisx0201_mbtowc(conv,pwc,&buf,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); + COMBINE_STATE; + conv->istate = state; + return count+1; + } else + goto ilseq; + case STATE_JISX0208: + if (n < count+2) + goto none; + if (s[0] < 0x80 && s[1] < 0x80) { + int ret = jisx0208_mbtowc(conv,pwc,s,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + COMBINE_STATE; + conv->istate = state; + return count+2; + } else + goto ilseq; + case STATE_JISX0212: + if (n < count+2) + goto none; + if (s[0] < 0x80 && s[1] < 0x80) { + int ret = jisx0212_mbtowc(conv,pwc,s,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + COMBINE_STATE; + conv->istate = state; + return count+2; + } else + goto ilseq; + case STATE_GB2312: + if (n < count+2) + goto none; + if (s[0] < 0x80 && s[1] < 0x80) { + int ret = gb2312_mbtowc(conv,pwc,s,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + COMBINE_STATE; + conv->istate = state; + return count+2; + } else + goto ilseq; + case STATE_KSC5601: + if (n < count+2) + goto none; + if (s[0] < 0x80 && s[1] < 0x80) { + int ret = ksc5601_mbtowc(conv,pwc,s,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + COMBINE_STATE; + conv->istate = state; + return count+2; + } else + goto ilseq; + default: abort(); + } + +none: + COMBINE_STATE; + conv->istate = state; + return RET_TOOFEW(count); + +ilseq: + COMBINE_STATE; + conv->istate = state; + return RET_SHIFT_ILSEQ(count); +} + +#undef COMBINE_STATE +#undef SPLIT_STATE + +/* + * The state can also contain one of the following values, << 16. + * Values >= STATE_TAG_LANGUAGE are temporary tag parsing states. + */ +#define STATE_TAG_NONE 0 +#define STATE_TAG_LANGUAGE 4 +#define STATE_TAG_LANGUAGE_j 5 +#define STATE_TAG_LANGUAGE_ja 1 +#define STATE_TAG_LANGUAGE_k 6 +#define STATE_TAG_LANGUAGE_ko 2 +#define STATE_TAG_LANGUAGE_z 7 +#define STATE_TAG_LANGUAGE_zh 3 + +#define SPLIT_STATE \ + unsigned int state1 = state & 0xff, state2 = (state >> 8) & 0xff, state3 = state >> 16 +#define COMBINE_STATE \ + state = (state3 << 16) | (state2 << 8) | state1 + +static int +iso2022_jp2_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + state_t state = conv->ostate; + SPLIT_STATE; + unsigned char buf[2]; + int ret; + /* This defines the conversion preferences depending on the current + langauge tag. */ + enum conversion { none = 0, european, japanese, chinese, korean, other }; + static const unsigned int conversion_lists[STATE_TAG_LANGUAGE] = { + /* STATE_TAG_NONE */ + japanese + (european << 3) + (chinese << 6) + (korean << 9) + (other << 12), + /* STATE_TAG_LANGUAGE_ja */ + japanese + (european << 3) + (chinese << 6) + (korean << 9) + (other << 12), + /* STATE_TAG_LANGUAGE_ko */ + korean + (european << 3) + (japanese << 6) + (chinese << 9) + (other << 12), + /* STATE_TAG_LANGUAGE_zh */ + chinese + (european << 3) + (japanese << 6) + (korean << 9) + (other << 12) + }; + unsigned int conversion_list; + + /* Handle Unicode tag characters (range U+E0000..U+E007F). */ + if ((wc >> 7) == (0xe0000 >> 7)) { + char c = wc & 0x7f; + if (c >= 'A' && c <= 'Z') + c += 'a'-'A'; + switch (c) { + case 0x01: + state3 = STATE_TAG_LANGUAGE; + COMBINE_STATE; + conv->ostate = state; + return 0; + case 'j': + if (state3 == STATE_TAG_LANGUAGE) { + state3 = STATE_TAG_LANGUAGE_j; + COMBINE_STATE; + conv->ostate = state; + return 0; + } + break; + case 'a': + if (state3 == STATE_TAG_LANGUAGE_j) { + state3 = STATE_TAG_LANGUAGE_ja; + COMBINE_STATE; + conv->ostate = state; + return 0; + } + break; + case 'k': + if (state3 == STATE_TAG_LANGUAGE) { + state3 = STATE_TAG_LANGUAGE_k; + COMBINE_STATE; + conv->ostate = state; + return 0; + } + break; + case 'o': + if (state3 == STATE_TAG_LANGUAGE_k) { + state3 = STATE_TAG_LANGUAGE_ko; + COMBINE_STATE; + conv->ostate = state; + return 0; + } + break; + case 'z': + if (state3 == STATE_TAG_LANGUAGE) { + state3 = STATE_TAG_LANGUAGE_z; + COMBINE_STATE; + conv->ostate = state; + return 0; + } + break; + case 'h': + if (state3 == STATE_TAG_LANGUAGE_z) { + state3 = STATE_TAG_LANGUAGE_zh; + COMBINE_STATE; + conv->ostate = state; + return 0; + } + break; + case 0x7f: + state3 = STATE_TAG_NONE; + COMBINE_STATE; + conv->ostate = state; + return 0; + default: + break; + } + /* Other tag characters reset the tag parsing state or are ignored. */ + if (state3 >= STATE_TAG_LANGUAGE) + state3 = STATE_TAG_NONE; + COMBINE_STATE; + conv->ostate = state; + return 0; + } + if (state3 >= STATE_TAG_LANGUAGE) + state3 = STATE_TAG_NONE; + + /* Try ASCII. */ + ret = ascii_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] < 0x80) { + int count = (state1 == STATE_ASCII ? 1 : 4); + if (n < count) + return RET_TOOSMALL; + if (state1 != STATE_ASCII) { + r[0] = ESC; + r[1] = '('; + r[2] = 'B'; + r += 3; + state1 = STATE_ASCII; + } + r[0] = buf[0]; + if (wc == 0x000a || wc == 0x000d) + state2 = STATE_G2_NONE; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + conversion_list = conversion_lists[state3]; + + do { + switch (conversion_list & ((1 << 3) - 1)) { + + case european: + + /* Try ISO-8859-1. */ + ret = iso8859_1_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] >= 0x80) { + int count = (state2 == STATE_G2_ISO8859_1 ? 3 : 6); + if (n < count) + return RET_TOOSMALL; + if (state2 != STATE_G2_ISO8859_1) { + r[0] = ESC; + r[1] = '.'; + r[2] = 'A'; + r += 3; + state2 = STATE_G2_ISO8859_1; + } + r[0] = ESC; + r[1] = 'N'; + r[2] = buf[0]-0x80; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + /* Try ISO-8859-7. */ + ret = iso8859_7_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] >= 0x80) { + int count = (state2 == STATE_G2_ISO8859_7 ? 3 : 6); + if (n < count) + return RET_TOOSMALL; + if (state2 != STATE_G2_ISO8859_7) { + r[0] = ESC; + r[1] = '.'; + r[2] = 'F'; + r += 3; + state2 = STATE_G2_ISO8859_7; + } + r[0] = ESC; + r[1] = 'N'; + r[2] = buf[0]-0x80; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + break; + + case japanese: + + /* Try JIS X 0201-1976 Roman. */ + ret = jisx0201_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] < 0x80) { + int count = (state1 == STATE_JISX0201ROMAN ? 1 : 4); + if (n < count) + return RET_TOOSMALL; + if (state1 != STATE_JISX0201ROMAN) { + r[0] = ESC; + r[1] = '('; + r[2] = 'J'; + r += 3; + state1 = STATE_JISX0201ROMAN; + } + r[0] = buf[0]; + if (wc == 0x000a || wc == 0x000d) + state2 = STATE_G2_NONE; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + /* Try JIS X 0208-1990 in place of JIS X 0208-1978 and + JIS X 0208-1983. */ + ret = jisx0208_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (buf[0] < 0x80 && buf[1] < 0x80) { + int count = (state1 == STATE_JISX0208 ? 2 : 5); + if (n < count) + return RET_TOOSMALL; + if (state1 != STATE_JISX0208) { + r[0] = ESC; + r[1] = '$'; + r[2] = 'B'; + r += 3; + state1 = STATE_JISX0208; + } + r[0] = buf[0]; + r[1] = buf[1]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + /* Try JIS X 0212-1990. */ + ret = jisx0212_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (buf[0] < 0x80 && buf[1] < 0x80) { + int count = (state1 == STATE_JISX0212 ? 2 : 6); + if (n < count) + return RET_TOOSMALL; + if (state1 != STATE_JISX0212) { + r[0] = ESC; + r[1] = '$'; + r[2] = '('; + r[3] = 'D'; + r += 4; + state1 = STATE_JISX0212; + } + r[0] = buf[0]; + r[1] = buf[1]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + break; + + case chinese: + + /* Try GB 2312-1980. */ + ret = gb2312_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (buf[0] < 0x80 && buf[1] < 0x80) { + int count = (state1 == STATE_GB2312 ? 2 : 5); + if (n < count) + return RET_TOOSMALL; + if (state1 != STATE_GB2312) { + r[0] = ESC; + r[1] = '$'; + r[2] = 'A'; + r += 3; + state1 = STATE_GB2312; + } + r[0] = buf[0]; + r[1] = buf[1]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + break; + + case korean: + + /* Try KS C 5601-1992. */ + ret = ksc5601_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (buf[0] < 0x80 && buf[1] < 0x80) { + int count = (state1 == STATE_KSC5601 ? 2 : 6); + if (n < count) + return RET_TOOSMALL; + if (state1 != STATE_KSC5601) { + r[0] = ESC; + r[1] = '$'; + r[2] = '('; + r[3] = 'C'; + r += 4; + state1 = STATE_KSC5601; + } + r[0] = buf[0]; + r[1] = buf[1]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + break; + + case other: + + /* Try JIS X 0201-1976 Kana. This is not officially part of + ISO-2022-JP-2, according to RFC 1554. Therefore we try this + only after all other attempts. */ + ret = jisx0201_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] >= 0x80) { + int count = (state1 == STATE_JISX0201KATAKANA ? 1 : 4); + if (n < count) + return RET_TOOSMALL; + if (state1 != STATE_JISX0201KATAKANA) { + r[0] = ESC; + r[1] = '('; + r[2] = 'I'; + r += 3; + state1 = STATE_JISX0201KATAKANA; + } + r[0] = buf[0]-0x80; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + break; + + default: + abort(); + } + + conversion_list = conversion_list >> 3; + } while (conversion_list != 0); + + return RET_ILUNI; +} + +static int +iso2022_jp2_reset (conv_t conv, unsigned char *r, int n) +{ + state_t state = conv->ostate; + SPLIT_STATE; + (void)state2; + (void)state3; + if (state1 != STATE_ASCII) { + if (n < 3) + return RET_TOOSMALL; + r[0] = ESC; + r[1] = '('; + r[2] = 'B'; + /* conv->ostate = 0; will be done by the caller */ + return 3; + } else + return 0; +} + +#undef COMBINE_STATE +#undef SPLIT_STATE +#undef STATE_TAG_LANGUAGE_zh +#undef STATE_TAG_LANGUAGE_z +#undef STATE_TAG_LANGUAGE_ko +#undef STATE_TAG_LANGUAGE_k +#undef STATE_TAG_LANGUAGE_ja +#undef STATE_TAG_LANGUAGE_j +#undef STATE_TAG_LANGUAGE +#undef STATE_TAG_NONE +#undef STATE_G2_ISO8859_7 +#undef STATE_G2_ISO8859_1 +#undef STATE_G2_NONE +#undef STATE_KSC5601 +#undef STATE_GB2312 +#undef STATE_JISX0212 +#undef STATE_JISX0208 +#undef STATE_JISX0201KATAKANA +#undef STATE_JISX0201ROMAN +#undef STATE_ASCII diff --git a/libs/libiconv/lib/iso2022_jp3.h b/libs/libiconv/lib/iso2022_jp3.h new file mode 100644 index 00000000..58cea1bb --- /dev/null +++ b/libs/libiconv/lib/iso2022_jp3.h @@ -0,0 +1,538 @@ +/* + * Copyright (C) 1999-2004, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-2022-JP-3 + */ + +#include "jisx0213.h" + +#define ESC 0x1b + +/* + * The state is composed of one of the following values + */ +#define STATE_ASCII 0 /* Esc ( B */ +#define STATE_JISX0201ROMAN 1 /* Esc ( J */ +#define STATE_JISX0201KATAKANA 2 /* Esc ( I */ +#define STATE_JISX0208 3 /* Esc $ @ or Esc $ B */ +#define STATE_JISX02131 4 /* Esc $ ( O or Esc $ ( Q*/ +#define STATE_JISX02132 5 /* Esc $ ( P */ + +/* + * In the ISO-2022-JP-3 to UCS-4 direction, the state also holds the last + * character to be output, shifted by 3 bits. + */ + +static int +iso2022_jp3_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + ucs4_t last_wc = conv->istate >> 3; + if (last_wc) { + /* Output the buffered character. */ + conv->istate &= 7; + *pwc = last_wc; + return 0; /* Don't advance the input pointer. */ + } else { + state_t state = conv->istate; + int count = 0; + unsigned char c; + for (;;) { + c = *s; + if (c == ESC) { + if (n < count+3) + goto none; + if (s[1] == '(') { + if (s[2] == 'B') { + state = STATE_ASCII; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + if (s[2] == 'J') { + state = STATE_JISX0201ROMAN; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + if (s[2] == 'I') { + state = STATE_JISX0201KATAKANA; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + goto ilseq; + } + if (s[1] == '$') { + if (s[2] == '@' || s[2] == 'B') { + /* We don't distinguish JIS X 0208-1978 and JIS X 0208-1983. */ + state = STATE_JISX0208; + s += 3; count += 3; + if (n < count+1) + goto none; + continue; + } + if (s[2] == '(') { + if (n < count+4) + goto none; + if (s[3] == 'O' || s[3] == 'Q') { + state = STATE_JISX02131; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + if (s[3] == 'P') { + state = STATE_JISX02132; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + } + goto ilseq; + } + goto ilseq; + } + break; + } + switch (state) { + case STATE_ASCII: + if (c < 0x80) { + int ret = ascii_mbtowc(conv,pwc,s,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); + conv->istate = state; + return count+1; + } else + goto ilseq; + case STATE_JISX0201ROMAN: + if (c < 0x80) { + int ret = jisx0201_mbtowc(conv,pwc,s,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); + conv->istate = state; + return count+1; + } else + goto ilseq; + case STATE_JISX0201KATAKANA: + if (c < 0x80) { + unsigned char buf = c+0x80; + int ret = jisx0201_mbtowc(conv,pwc,&buf,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); + conv->istate = state; + return count+1; + } else + goto ilseq; + case STATE_JISX0208: + if (n < count+2) + goto none; + if (s[0] < 0x80 && s[1] < 0x80) { + int ret = jisx0208_mbtowc(conv,pwc,s,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + conv->istate = state; + return count+2; + } else + goto ilseq; + case STATE_JISX02131: + case STATE_JISX02132: + if (n < count+2) + goto none; + if (s[0] < 0x80 && s[1] < 0x80) { + ucs4_t wc = jisx0213_to_ucs4(((state-STATE_JISX02131+1)<<8)+s[0],s[1]); + if (wc) { + if (wc < 0x80) { + /* It's a combining character. */ + ucs4_t wc1 = jisx0213_to_ucs_combining[wc - 1][0]; + ucs4_t wc2 = jisx0213_to_ucs_combining[wc - 1][1]; + /* We cannot output two Unicode characters at once. So, + output the first character and buffer the second one. */ + *pwc = wc1; + conv->istate = (wc2 << 3) | state; + } else { + *pwc = wc; + conv->istate = state; + } + return count+2; + } + } + goto ilseq; + default: abort(); + } + none: + conv->istate = state; + return RET_TOOFEW(count); + + ilseq: + conv->istate = state; + return RET_SHIFT_ILSEQ(count); + } +} + +static int +iso2022_jp3_flushwc (conv_t conv, ucs4_t *pwc) +{ + ucs4_t last_wc = conv->istate >> 3; + if (last_wc) { + /* Output the buffered character. */ + conv->istate &= 7; + *pwc = last_wc; + return 1; + } else + return 0; +} + +/* + * In the UCS-4 to ISO-2022-JP-3 direction, the state also holds the last two + * bytes to be output, shifted by 3 bits, and the STATE_xxxxx value that was + * effective before this buffered character, shifted by 19 bits. + */ + +/* Composition tables for each of the relevant combining characters. */ +static const struct { unsigned short base; unsigned short composed; } iso2022_jp3_comp_table_data[] = { +#define iso2022_jp3_comp_table02e5_idx 0 +#define iso2022_jp3_comp_table02e5_len 1 + { 0x2b64, 0x2b65 }, /* 0x12B65 = 0x12B64 U+02E5 */ +#define iso2022_jp3_comp_table02e9_idx (iso2022_jp3_comp_table02e5_idx+iso2022_jp3_comp_table02e5_len) +#define iso2022_jp3_comp_table02e9_len 1 + { 0x2b60, 0x2b66 }, /* 0x12B66 = 0x12B60 U+02E9 */ +#define iso2022_jp3_comp_table0300_idx (iso2022_jp3_comp_table02e9_idx+iso2022_jp3_comp_table02e9_len) +#define iso2022_jp3_comp_table0300_len 5 + { 0x295c, 0x2b44 }, /* 0x12B44 = 0x1295C U+0300 */ + { 0x2b38, 0x2b48 }, /* 0x12B48 = 0x12B38 U+0300 */ + { 0x2b37, 0x2b4a }, /* 0x12B4A = 0x12B37 U+0300 */ + { 0x2b30, 0x2b4c }, /* 0x12B4C = 0x12B30 U+0300 */ + { 0x2b43, 0x2b4e }, /* 0x12B4E = 0x12B43 U+0300 */ +#define iso2022_jp3_comp_table0301_idx (iso2022_jp3_comp_table0300_idx+iso2022_jp3_comp_table0300_len) +#define iso2022_jp3_comp_table0301_len 4 + { 0x2b38, 0x2b49 }, /* 0x12B49 = 0x12B38 U+0301 */ + { 0x2b37, 0x2b4b }, /* 0x12B4B = 0x12B37 U+0301 */ + { 0x2b30, 0x2b4d }, /* 0x12B4D = 0x12B30 U+0301 */ + { 0x2b43, 0x2b4f }, /* 0x12B4F = 0x12B43 U+0301 */ +#define iso2022_jp3_comp_table309a_idx (iso2022_jp3_comp_table0301_idx+iso2022_jp3_comp_table0301_len) +#define iso2022_jp3_comp_table309a_len 14 + { 0x242b, 0x2477 }, /* 0x12477 = 0x1242B U+309A */ + { 0x242d, 0x2478 }, /* 0x12478 = 0x1242D U+309A */ + { 0x242f, 0x2479 }, /* 0x12479 = 0x1242F U+309A */ + { 0x2431, 0x247a }, /* 0x1247A = 0x12431 U+309A */ + { 0x2433, 0x247b }, /* 0x1247B = 0x12433 U+309A */ + { 0x252b, 0x2577 }, /* 0x12577 = 0x1252B U+309A */ + { 0x252d, 0x2578 }, /* 0x12578 = 0x1252D U+309A */ + { 0x252f, 0x2579 }, /* 0x12579 = 0x1252F U+309A */ + { 0x2531, 0x257a }, /* 0x1257A = 0x12531 U+309A */ + { 0x2533, 0x257b }, /* 0x1257B = 0x12533 U+309A */ + { 0x253b, 0x257c }, /* 0x1257C = 0x1253B U+309A */ + { 0x2544, 0x257d }, /* 0x1257D = 0x12544 U+309A */ + { 0x2548, 0x257e }, /* 0x1257E = 0x12548 U+309A */ + { 0x2675, 0x2678 }, /* 0x12678 = 0x12675 U+309A */ +}; + +#define SPLIT_STATE \ + unsigned short lasttwo = state >> 3; state_t prevstate = state >> 19; state &= 7 +#define COMBINE_STATE \ + state |= (prevstate << 19) | (lasttwo << 3) +#define COMBINE_STATE_NO_LASTTWO \ + /* assume lasttwo == 0, then prevstate is ignored */ + +static int +iso2022_jp3_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + int count = 0; + unsigned char buf[2]; + unsigned short jch; + int ret; + state_t state = conv->ostate; + SPLIT_STATE; + + if (lasttwo) { + /* Attempt to combine the last character with this one. */ + unsigned int idx; + unsigned int len; + + if (wc == 0x02e5) + idx = iso2022_jp3_comp_table02e5_idx, + len = iso2022_jp3_comp_table02e5_len; + else if (wc == 0x02e9) + idx = iso2022_jp3_comp_table02e9_idx, + len = iso2022_jp3_comp_table02e9_len; + else if (wc == 0x0300) + idx = iso2022_jp3_comp_table0300_idx, + len = iso2022_jp3_comp_table0300_len; + else if (wc == 0x0301) + idx = iso2022_jp3_comp_table0301_idx, + len = iso2022_jp3_comp_table0301_len; + else if (wc == 0x309a) + idx = iso2022_jp3_comp_table309a_idx, + len = iso2022_jp3_comp_table309a_len; + else + goto not_combining; + + do + if (iso2022_jp3_comp_table_data[idx].base == lasttwo) + break; + while (++idx, --len > 0); + + if (len > 0) { + /* Output the combined character. */ + /* We know the combined character is in JISX0213 plane 1, but + the buffered character may have been in JISX0208 or in + JISX0213 plane 1. */ + count = (state != STATE_JISX02131 ? 4 : 0) + 2; + if (n < count) + return RET_TOOSMALL; + if (state != STATE_JISX02131) { + r[0] = ESC; + r[1] = '$'; + r[2] = '('; + r[3] = 'Q'; + r += 4; + state = STATE_JISX02131; + } + lasttwo = iso2022_jp3_comp_table_data[idx].composed; + r[0] = (lasttwo >> 8) & 0xff; + r[1] = lasttwo & 0xff; + COMBINE_STATE_NO_LASTTWO; + conv->ostate = state; + return count; + } + + not_combining: + /* Output the buffered character. */ + /* We know it is in JISX0208 or in JISX0213 plane 1. */ + count = (prevstate != state ? 3 : 0) + 2; + if (n < count) + return RET_TOOSMALL; + if (prevstate != state) { + if (state != STATE_JISX0208) abort(); + r[0] = ESC; + r[1] = '$'; + r[2] = 'B'; + r += 3; + } + r[0] = (lasttwo >> 8) & 0xff; + r[1] = lasttwo & 0xff; + r += 2; + } + + /* Try ASCII. */ + ret = ascii_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] < 0x80) { + count += (state == STATE_ASCII ? 1 : 4); + if (n < count) + return RET_TOOSMALL; + if (state != STATE_ASCII) { + r[0] = ESC; + r[1] = '('; + r[2] = 'B'; + r += 3; + state = STATE_ASCII; + } + r[0] = buf[0]; + COMBINE_STATE_NO_LASTTWO; + conv->ostate = state; + return count; + } + } + + /* Try JIS X 0201-1976 Roman. */ + ret = jisx0201_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] < 0x80) { + count += (state == STATE_JISX0201ROMAN ? 1 : 4); + if (n < count) + return RET_TOOSMALL; + if (state != STATE_JISX0201ROMAN) { + r[0] = ESC; + r[1] = '('; + r[2] = 'J'; + r += 3; + state = STATE_JISX0201ROMAN; + } + r[0] = buf[0]; + COMBINE_STATE_NO_LASTTWO; + conv->ostate = state; + return count; + } + } + + jch = ucs4_to_jisx0213(wc); + + /* Try JIS X 0208-1990 in place of JIS X 0208-1978 and JIS X 0208-1983. */ + ret = jisx0208_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (buf[0] < 0x80 && buf[1] < 0x80) { + if (jch & 0x0080) { + /* A possible match in comp_table_data. Buffer it. */ + prevstate = state; + lasttwo = jch & 0x7f7f; + state = STATE_JISX0208; + COMBINE_STATE; + conv->ostate = state; + return count; + } else { + count += (state == STATE_JISX0208 ? 2 : 5); + if (n < count) + return RET_TOOSMALL; + if (state != STATE_JISX0208) { + r[0] = ESC; + r[1] = '$'; + r[2] = 'B'; + r += 3; + state = STATE_JISX0208; + } + r[0] = buf[0]; + r[1] = buf[1]; + COMBINE_STATE_NO_LASTTWO; + conv->ostate = state; + return count; + } + } + } + + /* Try JISX 0213 plane 1 and JISX 0213 plane 2. */ + if (jch != 0) { + if (jch & 0x8000) { + /* JISX 0213 plane 2. */ + if (state != STATE_JISX02132) { + count += 4; + if (n < count) + return RET_TOOSMALL; + r[0] = ESC; + r[1] = '$'; + r[2] = '('; + r[3] = 'P'; + r += 4; + state = STATE_JISX02132; + } + } else { + /* JISX 0213 plane 1. */ + if (state != STATE_JISX02131) { + count += 4; + if (n < count) + return RET_TOOSMALL; + r[0] = ESC; + r[1] = '$'; + r[2] = '('; + r[3] = 'Q'; + r += 4; + state = STATE_JISX02131; + } + } + if (jch & 0x0080) { + /* A possible match in comp_table_data. We have to buffer it. */ + /* We know it's a JISX 0213 plane 1 character. */ + if (jch & 0x8000) abort(); + prevstate = state; + lasttwo = jch & 0x7f7f; + COMBINE_STATE; + conv->ostate = state; + return count; + } + count += 2; + if (n < count) + return RET_TOOSMALL; + r[0] = (jch >> 8) & 0x7f; + r[1] = jch & 0x7f; + COMBINE_STATE_NO_LASTTWO; + conv->ostate = state; + return count; + } + + /* Try JIS X 0201-1976 Katakana. This is not officially part of + ISO-2022-JP-3. Therefore we try it after all other attempts. */ + ret = jisx0201_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] >= 0x80) { + count += (state == STATE_JISX0201KATAKANA ? 1 : 4); + if (n < count) + return RET_TOOSMALL; + if (state != STATE_JISX0201KATAKANA) { + r[0] = ESC; + r[1] = '('; + r[2] = 'I'; + r += 3; + state = STATE_JISX0201KATAKANA; + } + r[0] = buf[0]-0x80; + COMBINE_STATE_NO_LASTTWO; + conv->ostate = state; + return count; + } + } + + return RET_ILUNI; +} + +static int +iso2022_jp3_reset (conv_t conv, unsigned char *r, int n) +{ + state_t state = conv->ostate; + SPLIT_STATE; + { + int count = + (lasttwo ? (prevstate != state ? 3 : 0) + 2 : 0) + + (state != STATE_ASCII ? 3 : 0); + if (n < count) + return RET_TOOSMALL; + if (lasttwo) { + if (prevstate != state) { + if (state != STATE_JISX0208) abort(); + r[0] = ESC; + r[1] = '$'; + r[2] = 'B'; + r += 3; + } + r[0] = (lasttwo >> 8) & 0xff; + r[1] = lasttwo & 0xff; + r += 2; + } + if (state != STATE_ASCII) { + r[0] = ESC; + r[1] = '('; + r[2] = 'B'; + } + /* conv->ostate = 0; will be done by the caller */ + return count; + } +} + +#undef COMBINE_STATE_NO_LASTTWO +#undef COMBINE_STATE +#undef SPLIT_STATE +#undef STATE_JISX02132 +#undef STATE_JISX02131 +#undef STATE_JISX0208 +#undef STATE_JISX0201KATAKANA +#undef STATE_JISX0201ROMAN +#undef STATE_ASCII diff --git a/libs/libiconv/lib/iso2022_kr.h b/libs/libiconv/lib/iso2022_kr.h new file mode 100644 index 00000000..8045d4e5 --- /dev/null +++ b/libs/libiconv/lib/iso2022_kr.h @@ -0,0 +1,222 @@ +/* + * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-2022-KR + */ + +/* Specification: RFC 1557 */ + +/* Note: CJK.INF says the SO designator needs to appear only once at the + beginning of a text, but to decrease the risk of ambiguities, when + producing ISO-2022-KR, we repeat the designator in every line containing + SO characters. RFC 1557 does not mandate this. */ + +#define ESC 0x1b +#define SO 0x0e +#define SI 0x0f + +/* + * The state is composed of one of the following values + */ +#define STATE_ASCII 0 +#define STATE_TWOBYTE 1 +/* + * and one of the following values, << 8 + */ +#define STATE2_NONE 0 +#define STATE2_DESIGNATED_KSC5601 1 + +#define SPLIT_STATE \ + unsigned int state1 = state & 0xff, state2 = state >> 8 +#define COMBINE_STATE \ + state = (state2 << 8) | state1 + +static int +iso2022_kr_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + state_t state = conv->istate; + SPLIT_STATE; + int count = 0; + unsigned char c; + for (;;) { + c = *s; + if (c == ESC) { + if (n < count+4) + goto none; + if (s[1] == '$') { + if (s[2] == ')') { + if (s[3] == 'C') { + state2 = STATE2_DESIGNATED_KSC5601; + s += 4; count += 4; + if (n < count+1) + goto none; + continue; + } + } + } + goto ilseq; + } + if (c == SO) { + if (state2 != STATE2_DESIGNATED_KSC5601) + goto ilseq; + state1 = STATE_TWOBYTE; + s++; count++; + if (n < count+1) + goto none; + continue; + } + if (c == SI) { + state1 = STATE_ASCII; + s++; count++; + if (n < count+1) + goto none; + continue; + } + break; + } + switch (state1) { + case STATE_ASCII: + if (c < 0x80) { + int ret = ascii_mbtowc(conv,pwc,s,1); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 1) abort(); +#if 0 /* Accept ISO-2022-KR according to CJK.INF. */ + if (*pwc == 0x000a || *pwc == 0x000d) + state2 = STATE2_NONE; +#endif + COMBINE_STATE; + conv->istate = state; + return count+1; + } else + goto ilseq; + case STATE_TWOBYTE: + if (n < count+2) + goto none; + if (state2 != STATE2_DESIGNATED_KSC5601) abort(); + if (s[0] < 0x80 && s[1] < 0x80) { + int ret = ksc5601_mbtowc(conv,pwc,s,2); + if (ret == RET_ILSEQ) + goto ilseq; + if (ret != 2) abort(); + COMBINE_STATE; + conv->istate = state; + return count+2; + } else + goto ilseq; + default: abort(); + } + +none: + COMBINE_STATE; + conv->istate = state; + return RET_TOOFEW(count); + +ilseq: + COMBINE_STATE; + conv->istate = state; + return RET_SHIFT_ILSEQ(count); +} + +static int +iso2022_kr_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + state_t state = conv->ostate; + SPLIT_STATE; + unsigned char buf[2]; + int ret; + + /* Try ASCII. */ + ret = ascii_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] < 0x80) { + int count = (state1 == STATE_ASCII ? 1 : 2); + if (n < count) + return RET_TOOSMALL; + if (state1 != STATE_ASCII) { + r[0] = SI; + r += 1; + state1 = STATE_ASCII; + } + r[0] = buf[0]; + if (wc == 0x000a || wc == 0x000d) + state2 = STATE2_NONE; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + /* Try KS C 5601-1992. */ + ret = ksc5601_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (buf[0] < 0x80 && buf[1] < 0x80) { + int count = (state2 == STATE2_DESIGNATED_KSC5601 ? 0 : 4) + (state1 == STATE_TWOBYTE ? 0 : 1) + 2; + if (n < count) + return RET_TOOSMALL; + if (state2 != STATE2_DESIGNATED_KSC5601) { + r[0] = ESC; + r[1] = '$'; + r[2] = ')'; + r[3] = 'C'; + r += 4; + state2 = STATE2_DESIGNATED_KSC5601; + } + if (state1 != STATE_TWOBYTE) { + r[0] = SO; + r += 1; + state1 = STATE_TWOBYTE; + } + r[0] = buf[0]; + r[1] = buf[1]; + COMBINE_STATE; + conv->ostate = state; + return count; + } + } + + return RET_ILUNI; +} + +static int +iso2022_kr_reset (conv_t conv, unsigned char *r, int n) +{ + state_t state = conv->ostate; + SPLIT_STATE; + (void)state2; + if (state1 != STATE_ASCII) { + if (n < 1) + return RET_TOOSMALL; + r[0] = SI; + /* conv->ostate = 0; will be done by the caller */ + return 1; + } else + return 0; +} + +#undef COMBINE_STATE +#undef SPLIT_STATE +#undef STATE2_DESIGNATED_KSC5601 +#undef STATE2_NONE +#undef STATE_TWOBYTE +#undef STATE_ASCII diff --git a/libs/libiconv/lib/iso646_cn.h b/libs/libiconv/lib/iso646_cn.h new file mode 100644 index 00000000..a571ce71 --- /dev/null +++ b/libs/libiconv/lib/iso646_cn.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO646-CN + * also known as GB_1988-80 + */ + +static int +iso646_cn_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + if (c == 0x24) + *pwc = (ucs4_t) 0x00a5; + else if (c == 0x7e) + *pwc = (ucs4_t) 0x203e; + else + *pwc = (ucs4_t) c; + return 1; + } + return RET_ILSEQ; +} + +static int +iso646_cn_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x0080 && !(wc == 0x0024 || wc == 0x007e)) { + *r = wc; + return 1; + } + if (wc == 0x00a5) { + *r = 0x24; + return 1; + } + if (wc == 0x203e) { + *r = 0x7e; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso646_jp.h b/libs/libiconv/lib/iso646_jp.h new file mode 100644 index 00000000..7cc3abd0 --- /dev/null +++ b/libs/libiconv/lib/iso646_jp.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO646-JP + * also known as JIS_C6220-1969-RO + */ + +/* This is the lower half of JIS_X0201. */ + +static int +iso646_jp_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + if (c == 0x5c) + *pwc = (ucs4_t) 0x00a5; + else if (c == 0x7e) + *pwc = (ucs4_t) 0x203e; + else + *pwc = (ucs4_t) c; + return 1; + } + return RET_ILSEQ; +} + +static int +iso646_jp_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x0080 && !(wc == 0x005c || wc == 0x007e)) { + *r = wc; + return 1; + } + if (wc == 0x00a5) { + *r = 0x5c; + return 1; + } + if (wc == 0x203e) { + *r = 0x7e; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_1.h b/libs/libiconv/lib/iso8859_1.h new file mode 100644 index 00000000..53469164 --- /dev/null +++ b/libs/libiconv/lib/iso8859_1.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-1 + */ + +static int +iso8859_1_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + *pwc = (ucs4_t) c; + return 1; +} + +static int +iso8859_1_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x0100) { + *r = wc; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_10.h b/libs/libiconv/lib/iso8859_10.h new file mode 100644 index 00000000..49b3f6ad --- /dev/null +++ b/libs/libiconv/lib/iso8859_10.h @@ -0,0 +1,106 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-10 + */ + +static const unsigned short iso8859_10_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0104, 0x0112, 0x0122, 0x012a, 0x0128, 0x0136, 0x00a7, + 0x013b, 0x0110, 0x0160, 0x0166, 0x017d, 0x00ad, 0x016a, 0x014a, + /* 0xb0 */ + 0x00b0, 0x0105, 0x0113, 0x0123, 0x012b, 0x0129, 0x0137, 0x00b7, + 0x013c, 0x0111, 0x0161, 0x0167, 0x017e, 0x2015, 0x016b, 0x014b, + /* 0xc0 */ + 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x00cf, + /* 0xd0 */ + 0x00d0, 0x0145, 0x014c, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0168, + 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + /* 0xe0 */ + 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x00ef, + /* 0xf0 */ + 0x00f0, 0x0146, 0x014d, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0169, + 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x0138, +}; + +static int +iso8859_10_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) iso8859_10_2uni[c-0xa0]; + return 1; +} + +static const unsigned char iso8859_10_page00[224] = { + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0x00, /* 0xc0-0xc7 */ + 0x00, 0xc9, 0x00, 0xcb, 0x00, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0xd0, 0x00, 0x00, 0xd3, 0xd4, 0xd5, 0xd6, 0x00, /* 0xd0-0xd7 */ + 0xd8, 0x00, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xd8-0xdf */ + 0x00, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0x00, 0xe9, 0x00, 0xeb, 0x00, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0xf0, 0x00, 0x00, 0xf3, 0xf4, 0xf5, 0xf6, 0x00, /* 0xf0-0xf7 */ + 0xf8, 0x00, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0xc0, 0xe0, 0x00, 0x00, 0xa1, 0xb1, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0x00, 0x00, /* 0x08-0x0f */ + 0xa9, 0xb9, 0xa2, 0xb2, 0x00, 0x00, 0xcc, 0xec, /* 0x10-0x17 */ + 0xca, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xa3, 0xb3, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0xa5, 0xb5, 0xa4, 0xb4, 0x00, 0x00, 0xc7, 0xe7, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0xb6, /* 0x30-0x37 */ + 0xff, 0x00, 0x00, 0xa8, 0xb8, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf1, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0xaf, 0xbf, 0xd2, 0xf2, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xaa, 0xba, 0x00, 0x00, 0x00, 0x00, 0xab, 0xbb, /* 0x60-0x67 */ + 0xd7, 0xf7, 0xae, 0xbe, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0xd9, 0xf9, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0xbc, 0x00, /* 0x78-0x7f */ +}; + +static int +iso8859_10_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = iso8859_10_page00[wc-0x00a0]; + else if (wc == 0x2015) + c = 0xbd; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_11.h b/libs/libiconv/lib/iso8859_11.h new file mode 100644 index 00000000..ef8b1a66 --- /dev/null +++ b/libs/libiconv/lib/iso8859_11.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 1999-2004 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-11 + */ + +static int +iso8859_11_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa1) { + *pwc = (ucs4_t) c; + return 1; + } + else if (c <= 0xfb && !(c >= 0xdb && c <= 0xde)) { + *pwc = (ucs4_t) (c + 0x0d60); + return 1; + } + return RET_ILSEQ; +} + +static int +iso8859_11_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x00a1) { + *r = wc; + return 1; + } + else if (wc >= 0x0e01 && wc <= 0x0e5b && !(wc >= 0x0e3b && wc <= 0x0e3e)) { + *r = wc-0x0d60; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_13.h b/libs/libiconv/lib/iso8859_13.h new file mode 100644 index 00000000..2fadc7b8 --- /dev/null +++ b/libs/libiconv/lib/iso8859_13.h @@ -0,0 +1,109 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-13 + */ + +static const unsigned short iso8859_13_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x201d, 0x00a2, 0x00a3, 0x00a4, 0x201e, 0x00a6, 0x00a7, + 0x00d8, 0x00a9, 0x0156, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00c6, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x201c, 0x00b5, 0x00b6, 0x00b7, + 0x00f8, 0x00b9, 0x0157, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00e6, + /* 0xc0 */ + 0x0104, 0x012e, 0x0100, 0x0106, 0x00c4, 0x00c5, 0x0118, 0x0112, + 0x010c, 0x00c9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012a, 0x013b, + /* 0xd0 */ + 0x0160, 0x0143, 0x0145, 0x00d3, 0x014c, 0x00d5, 0x00d6, 0x00d7, + 0x0172, 0x0141, 0x015a, 0x016a, 0x00dc, 0x017b, 0x017d, 0x00df, + /* 0xe0 */ + 0x0105, 0x012f, 0x0101, 0x0107, 0x00e4, 0x00e5, 0x0119, 0x0113, + 0x010d, 0x00e9, 0x017a, 0x0117, 0x0123, 0x0137, 0x012b, 0x013c, + /* 0xf0 */ + 0x0161, 0x0144, 0x0146, 0x00f3, 0x014d, 0x00f5, 0x00f6, 0x00f7, + 0x0173, 0x0142, 0x015b, 0x016b, 0x00fc, 0x017c, 0x017e, 0x2019, +}; + +static int +iso8859_13_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) iso8859_13_2uni[c-0xa0]; + return 1; +} + +static const unsigned char iso8859_13_page00[224] = { + 0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0xb9, 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0xc4, 0xc5, 0xaf, 0x00, /* 0xc0-0xc7 */ + 0x00, 0xc9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xd3, 0x00, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xa8, 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0xe4, 0xe5, 0xbf, 0x00, /* 0xe0-0xe7 */ + 0x00, 0xe9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xf3, 0x00, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xb8, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0xc2, 0xe2, 0x00, 0x00, 0xc0, 0xe0, 0xc3, 0xe3, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0xc7, 0xe7, 0x00, 0x00, 0xcb, 0xeb, /* 0x10-0x17 */ + 0xc6, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xcc, 0xec, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0xce, 0xee, 0x00, 0x00, 0xc1, 0xe1, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xcd, 0xed, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0xcf, 0xef, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0xd9, 0xf9, 0xd1, 0xf1, 0xd2, 0xf2, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0xd4, 0xf4, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xba, /* 0x50-0x57 */ + 0x00, 0x00, 0xda, 0xfa, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0xdb, 0xfb, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0xd8, 0xf8, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0xca, 0xea, 0xdd, 0xfd, 0xde, 0xfe, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char iso8859_13_page20[8] = { + 0x00, 0xff, 0x00, 0x00, 0xb4, 0xa1, 0xa5, 0x00, /* 0x18-0x1f */ +}; + +static int +iso8859_13_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = iso8859_13_page00[wc-0x00a0]; + else if (wc >= 0x2018 && wc < 0x2020) + c = iso8859_13_page20[wc-0x2018]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_14.h b/libs/libiconv/lib/iso8859_14.h new file mode 100644 index 00000000..01c9cdd9 --- /dev/null +++ b/libs/libiconv/lib/iso8859_14.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-14 + */ + +static const unsigned short iso8859_14_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x1e02, 0x1e03, 0x00a3, 0x010a, 0x010b, 0x1e0a, 0x00a7, + 0x1e80, 0x00a9, 0x1e82, 0x1e0b, 0x1ef2, 0x00ad, 0x00ae, 0x0178, + /* 0xb0 */ + 0x1e1e, 0x1e1f, 0x0120, 0x0121, 0x1e40, 0x1e41, 0x00b6, 0x1e56, + 0x1e81, 0x1e57, 0x1e83, 0x1e60, 0x1ef3, 0x1e84, 0x1e85, 0x1e61, + /* 0xc0 */ + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + /* 0xd0 */ + 0x0174, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x1e6a, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x0176, 0x00df, + /* 0xe0 */ + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + /* 0xf0 */ + 0x0175, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x1e6b, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x0177, 0x00ff, +}; + +static int +iso8859_14_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0xa0) + *pwc = (ucs4_t) iso8859_14_2uni[c-0xa0]; + else + *pwc = (ucs4_t) c; + return 1; +} + +static const unsigned char iso8859_14_page00[96] = { + 0xa0, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0x00, 0x00, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0x00, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0x00, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0x00, 0xff, /* 0xf8-0xff */ +}; +static const unsigned char iso8859_14_page01_0[32] = { + 0x00, 0x00, 0xa4, 0xa5, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0xb2, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char iso8859_14_page01_1[16] = { + 0x00, 0x00, 0x00, 0x00, 0xd0, 0xf0, 0xde, 0xfe, /* 0x70-0x77 */ + 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char iso8859_14_page1e_0[136] = { + 0x00, 0x00, 0xa1, 0xa2, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0xa6, 0xab, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xb1, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0xb4, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, 0xb9, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xbb, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0xd7, 0xf7, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0xa8, 0xb8, 0xaa, 0xba, 0xbd, 0xbe, 0x00, 0x00, /* 0x80-0x87 */ +}; +static const unsigned char iso8859_14_page1e_1[8] = { + 0x00, 0x00, 0xac, 0xbc, 0x00, 0x00, 0x00, 0x00, /* 0xf0-0xf7 */ +}; + +static int +iso8859_14_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = iso8859_14_page00[wc-0x00a0]; + else if (wc >= 0x0108 && wc < 0x0128) + c = iso8859_14_page01_0[wc-0x0108]; + else if (wc >= 0x0170 && wc < 0x0180) + c = iso8859_14_page01_1[wc-0x0170]; + else if (wc >= 0x1e00 && wc < 0x1e88) + c = iso8859_14_page1e_0[wc-0x1e00]; + else if (wc >= 0x1ef0 && wc < 0x1ef8) + c = iso8859_14_page1e_1[wc-0x1ef0]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_15.h b/libs/libiconv/lib/iso8859_15.h new file mode 100644 index 00000000..24de90d7 --- /dev/null +++ b/libs/libiconv/lib/iso8859_15.h @@ -0,0 +1,81 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-15 + */ + +static const unsigned short iso8859_15_2uni[32] = { + /* 0xa0 */ + 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x20ac, 0x00a5, 0x0160, 0x00a7, + 0x0161, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x017d, 0x00b5, 0x00b6, 0x00b7, + 0x017e, 0x00b9, 0x00ba, 0x00bb, 0x0152, 0x0153, 0x0178, 0x00bf, +}; + +static int +iso8859_15_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0xa0 && c < 0xc0) + *pwc = (ucs4_t) iso8859_15_2uni[c-0xa0]; + else + *pwc = (ucs4_t) c; + return 1; +} + +static const unsigned char iso8859_15_page00[32] = { + 0xa0, 0xa1, 0xa2, 0xa3, 0x00, 0xa5, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0xb9, 0xba, 0xbb, 0x00, 0x00, 0x00, 0xbf, /* 0xb8-0xbf */ +}; +static const unsigned char iso8859_15_page01[48] = { + 0x00, 0x00, 0xbc, 0xbd, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xa6, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xbe, 0x00, 0x00, 0x00, 0x00, 0xb4, 0xb8, 0x00, /* 0x78-0x7f */ +}; + +static int +iso8859_15_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = iso8859_15_page00[wc-0x00a0]; + else if (wc >= 0x00c0 && wc < 0x0100) + c = wc; + else if (wc >= 0x0150 && wc < 0x0180) + c = iso8859_15_page01[wc-0x0150]; + else if (wc == 0x20ac) + c = 0xa4; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_16.h b/libs/libiconv/lib/iso8859_16.h new file mode 100644 index 00000000..20047184 --- /dev/null +++ b/libs/libiconv/lib/iso8859_16.h @@ -0,0 +1,116 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-16 + */ + +static const unsigned short iso8859_16_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0104, 0x0105, 0x0141, 0x20ac, 0x201e, 0x0160, 0x00a7, + 0x0161, 0x00a9, 0x0218, 0x00ab, 0x0179, 0x00ad, 0x017a, 0x017b, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x010c, 0x0142, 0x017d, 0x201d, 0x00b6, 0x00b7, + 0x017e, 0x010d, 0x0219, 0x00bb, 0x0152, 0x0153, 0x0178, 0x017c, + /* 0xc0 */ + 0x00c0, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0106, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + /* 0xd0 */ + 0x0110, 0x0143, 0x00d2, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x015a, + 0x0170, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0118, 0x021a, 0x00df, + /* 0xe0 */ + 0x00e0, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x0107, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + /* 0xf0 */ + 0x0111, 0x0144, 0x00f2, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x015b, + 0x0171, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0119, 0x021b, 0x00ff, +}; + +static int +iso8859_16_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) iso8859_16_2uni[c-0xa0]; + return 1; +} + +static const unsigned char iso8859_16_page00[224] = { + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xab, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0x00, 0x00, 0x00, 0x00, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0x00, 0xc4, 0x00, 0xc6, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0x00, 0xd2, 0xd3, 0xd4, 0x00, 0xd6, 0x00, /* 0xd0-0xd7 */ + 0x00, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0x00, 0xe4, 0x00, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0x00, 0xf2, 0xf3, 0xf4, 0x00, 0xf6, 0x00, /* 0xf0-0xf7 */ + 0x00, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0xff, /* 0xf8-0xff */ + /* 0x0100 */ + 0x00, 0x00, 0xc3, 0xe3, 0xa1, 0xa2, 0xc5, 0xe5, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xb2, 0xb9, 0x00, 0x00, /* 0x08-0x0f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xdd, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0xa3, 0xb3, 0xd1, 0xf1, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xd5, 0xf5, 0xbc, 0xbd, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0xd7, 0xf7, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xa6, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0xd8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xbe, 0xac, 0xae, 0xaf, 0xbf, 0xb4, 0xb8, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char iso8859_16_page02[8] = { + 0xaa, 0xba, 0xde, 0xfe, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ +}; +static const unsigned char iso8859_16_page20[8] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xa5, 0x00, /* 0x18-0x1f */ +}; + +static int +iso8859_16_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = iso8859_16_page00[wc-0x00a0]; + else if (wc >= 0x0218 && wc < 0x0220) + c = iso8859_16_page02[wc-0x0218]; + else if (wc >= 0x2018 && wc < 0x2020) + c = iso8859_16_page20[wc-0x2018]; + else if (wc == 0x20ac) + c = 0xa4; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_2.h b/libs/libiconv/lib/iso8859_2.h new file mode 100644 index 00000000..9ad4d4aa --- /dev/null +++ b/libs/libiconv/lib/iso8859_2.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-2 + */ + +static const unsigned short iso8859_2_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0104, 0x02d8, 0x0141, 0x00a4, 0x013d, 0x015a, 0x00a7, + 0x00a8, 0x0160, 0x015e, 0x0164, 0x0179, 0x00ad, 0x017d, 0x017b, + /* 0xb0 */ + 0x00b0, 0x0105, 0x02db, 0x0142, 0x00b4, 0x013e, 0x015b, 0x02c7, + 0x00b8, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, + /* 0xc0 */ + 0x0154, 0x00c1, 0x00c2, 0x0102, 0x00c4, 0x0139, 0x0106, 0x00c7, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x011a, 0x00cd, 0x00ce, 0x010e, + /* 0xd0 */ + 0x0110, 0x0143, 0x0147, 0x00d3, 0x00d4, 0x0150, 0x00d6, 0x00d7, + 0x0158, 0x016e, 0x00da, 0x0170, 0x00dc, 0x00dd, 0x0162, 0x00df, + /* 0xe0 */ + 0x0155, 0x00e1, 0x00e2, 0x0103, 0x00e4, 0x013a, 0x0107, 0x00e7, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x011b, 0x00ed, 0x00ee, 0x010f, + /* 0xf0 */ + 0x0111, 0x0144, 0x0148, 0x00f3, 0x00f4, 0x0151, 0x00f6, 0x00f7, + 0x0159, 0x016f, 0x00fa, 0x0171, 0x00fc, 0x00fd, 0x0163, 0x02d9, +}; + +static int +iso8859_2_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) iso8859_2_2uni[c-0xa0]; + return 1; +} + +static const unsigned char iso8859_2_page00[224] = { + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0xc1, 0xc2, 0x00, 0xc4, 0x00, 0x00, 0xc7, /* 0xc0-0xc7 */ + 0x00, 0xc9, 0x00, 0xcb, 0x00, 0xcd, 0xce, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xd3, 0xd4, 0x00, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0x00, 0x00, 0xda, 0x00, 0xdc, 0xdd, 0x00, 0xdf, /* 0xd8-0xdf */ + 0x00, 0xe1, 0xe2, 0x00, 0xe4, 0x00, 0x00, 0xe7, /* 0xe0-0xe7 */ + 0x00, 0xe9, 0x00, 0xeb, 0x00, 0xed, 0xee, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0xf3, 0xf4, 0x00, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0x00, 0xfa, 0x00, 0xfc, 0xfd, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0x00, 0x00, 0xc3, 0xe3, 0xa1, 0xb1, 0xc6, 0xe6, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0xcf, 0xef, /* 0x08-0x0f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xca, 0xea, 0xcc, 0xec, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0xc5, 0xe5, 0x00, 0x00, 0xa5, 0xb5, 0x00, /* 0x38-0x3f */ + 0x00, 0xa3, 0xb3, 0xd1, 0xf1, 0x00, 0x00, 0xd2, /* 0x40-0x47 */ + 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xd5, 0xf5, 0x00, 0x00, 0xc0, 0xe0, 0x00, 0x00, /* 0x50-0x57 */ + 0xd8, 0xf8, 0xa6, 0xb6, 0x00, 0x00, 0xaa, 0xba, /* 0x58-0x5f */ + 0xa9, 0xb9, 0xde, 0xfe, 0xab, 0xbb, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd9, 0xf9, /* 0x68-0x6f */ + 0xdb, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0xac, 0xbc, 0xaf, 0xbf, 0xae, 0xbe, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char iso8859_2_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xa2, 0xff, 0x00, 0xb2, 0x00, 0xbd, 0x00, 0x00, /* 0xd8-0xdf */ +}; + +static int +iso8859_2_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = iso8859_2_page00[wc-0x00a0]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = iso8859_2_page02[wc-0x02c0]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_3.h b/libs/libiconv/lib/iso8859_3.h new file mode 100644 index 00000000..308e0b0d --- /dev/null +++ b/libs/libiconv/lib/iso8859_3.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-3 + */ + +static const unsigned short iso8859_3_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0126, 0x02d8, 0x00a3, 0x00a4, 0xfffd, 0x0124, 0x00a7, + 0x00a8, 0x0130, 0x015e, 0x011e, 0x0134, 0x00ad, 0xfffd, 0x017b, + /* 0xb0 */ + 0x00b0, 0x0127, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x0125, 0x00b7, + 0x00b8, 0x0131, 0x015f, 0x011f, 0x0135, 0x00bd, 0xfffd, 0x017c, + /* 0xc0 */ + 0x00c0, 0x00c1, 0x00c2, 0xfffd, 0x00c4, 0x010a, 0x0108, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + /* 0xd0 */ + 0xfffd, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x0120, 0x00d6, 0x00d7, + 0x011c, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x016c, 0x015c, 0x00df, + /* 0xe0 */ + 0x00e0, 0x00e1, 0x00e2, 0xfffd, 0x00e4, 0x010b, 0x0109, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + /* 0xf0 */ + 0xfffd, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x0121, 0x00f6, 0x00f7, + 0x011d, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x016d, 0x015d, 0x02d9, +}; + +static int +iso8859_3_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = iso8859_3_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char iso8859_3_page00[96] = { + 0xa0, 0x00, 0x00, 0xa3, 0xa4, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0x00, 0xb2, 0xb3, 0xb4, 0xb5, 0x00, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0xbd, 0x00, 0x00, /* 0xb8-0xbf */ + 0xc0, 0xc1, 0xc2, 0x00, 0xc4, 0x00, 0x00, 0xc7, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0xc8-0xcf */ + 0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0x00, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0x00, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0x00, 0xe4, 0x00, 0x00, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0x00, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0x00, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; +static const unsigned char iso8859_3_page01[120] = { + 0xc6, 0xe6, 0xc5, 0xe5, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0xd8, 0xf8, 0xab, 0xbb, /* 0x18-0x1f */ + 0xd5, 0xf5, 0x00, 0x00, 0xa6, 0xb6, 0xa1, 0xb1, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xa9, 0xb9, 0x00, 0x00, 0xac, 0xbc, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0xde, 0xfe, 0xaa, 0xba, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0xdd, 0xfd, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0xaf, 0xbf, 0x00, 0x00, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char iso8859_3_page02[8] = { + 0xa2, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; + +static int +iso8859_3_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = iso8859_3_page00[wc-0x00a0]; + else if (wc >= 0x0108 && wc < 0x0180) + c = iso8859_3_page01[wc-0x0108]; + else if (wc >= 0x02d8 && wc < 0x02e0) + c = iso8859_3_page02[wc-0x02d8]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_4.h b/libs/libiconv/lib/iso8859_4.h new file mode 100644 index 00000000..51e17786 --- /dev/null +++ b/libs/libiconv/lib/iso8859_4.h @@ -0,0 +1,112 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-4 + */ + +static const unsigned short iso8859_4_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0104, 0x0138, 0x0156, 0x00a4, 0x0128, 0x013b, 0x00a7, + 0x00a8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00ad, 0x017d, 0x00af, + /* 0xb0 */ + 0x00b0, 0x0105, 0x02db, 0x0157, 0x00b4, 0x0129, 0x013c, 0x02c7, + 0x00b8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014a, 0x017e, 0x014b, + /* 0xc0 */ + 0x0100, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x012e, + 0x010c, 0x00c9, 0x0118, 0x00cb, 0x0116, 0x00cd, 0x00ce, 0x012a, + /* 0xd0 */ + 0x0110, 0x0145, 0x014c, 0x0136, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x0172, 0x00da, 0x00db, 0x00dc, 0x0168, 0x016a, 0x00df, + /* 0xe0 */ + 0x0101, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x012f, + 0x010d, 0x00e9, 0x0119, 0x00eb, 0x0117, 0x00ed, 0x00ee, 0x012b, + /* 0xf0 */ + 0x0111, 0x0146, 0x014d, 0x0137, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x0173, 0x00fa, 0x00fb, 0x00fc, 0x0169, 0x016b, 0x02d9, +}; + +static int +iso8859_4_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) iso8859_4_2uni[c-0xa0]; + return 1; +} + +static const unsigned char iso8859_4_page00[224] = { + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0xb8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0x00, /* 0xc0-0xc7 */ + 0x00, 0xc9, 0x00, 0xcb, 0x00, 0xcd, 0xce, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0x00, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0x00, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0x00, /* 0xe0-0xe7 */ + 0x00, 0xe9, 0x00, 0xeb, 0x00, 0xed, 0xee, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0x00, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0xc0, 0xe0, 0x00, 0x00, 0xa1, 0xb1, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0x00, 0x00, /* 0x08-0x0f */ + 0xd0, 0xf0, 0xaa, 0xba, 0x00, 0x00, 0xcc, 0xec, /* 0x10-0x17 */ + 0xca, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xab, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0xa5, 0xb5, 0xcf, 0xef, 0x00, 0x00, 0xc7, 0xe7, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd3, 0xf3, /* 0x30-0x37 */ + 0xa2, 0x00, 0x00, 0xa6, 0xb6, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xd1, 0xf1, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0xbd, 0xbf, 0xd2, 0xf2, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa3, 0xb3, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xa9, 0xb9, 0x00, 0x00, 0x00, 0x00, 0xac, 0xbc, /* 0x60-0x67 */ + 0xdd, 0xfd, 0xde, 0xfe, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0xd9, 0xf9, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0xbe, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char iso8859_4_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb7, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0xff, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; + +static int +iso8859_4_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = iso8859_4_page00[wc-0x00a0]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = iso8859_4_page02[wc-0x02c0]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_5.h b/libs/libiconv/lib/iso8859_5.h new file mode 100644 index 00000000..6b836055 --- /dev/null +++ b/libs/libiconv/lib/iso8859_5.h @@ -0,0 +1,95 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-5 + */ + +static const unsigned short iso8859_5_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, + 0x0408, 0x0409, 0x040a, 0x040b, 0x040c, 0x00ad, 0x040e, 0x040f, + /* 0xb0 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + /* 0xc0 */ + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + /* 0xd0 */ + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + /* 0xe0 */ + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, + /* 0xf0 */ + 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, + 0x0458, 0x0459, 0x045a, 0x045b, 0x045c, 0x00a7, 0x045e, 0x045f, +}; + +static int +iso8859_5_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) iso8859_5_2uni[c-0xa0]; + return 1; +} + +static const unsigned char iso8859_5_page00[16] = { + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ +}; +static const unsigned char iso8859_5_page04[96] = { + 0x00, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x00-0x07 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0x00, 0xae, 0xaf, /* 0x08-0x0f */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x10-0x17 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0x18-0x1f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x30-0x37 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x50-0x57 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0xfe, 0xff, /* 0x58-0x5f */ +}; + +static int +iso8859_5_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00b0) + c = iso8859_5_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x0460) + c = iso8859_5_page04[wc-0x0400]; + else if (wc == 0x2116) + c = 0xf0; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_6.h b/libs/libiconv/lib/iso8859_6.h new file mode 100644 index 00000000..8d311994 --- /dev/null +++ b/libs/libiconv/lib/iso8859_6.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-6 + */ + +static const unsigned short iso8859_6_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0xfffd, 0xfffd, 0xfffd, 0x00a4, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x060c, 0x00ad, 0xfffd, 0xfffd, + /* 0xb0 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x061b, 0xfffd, 0xfffd, 0xfffd, 0x061f, + /* 0xc0 */ + 0xfffd, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, + /* 0xd0 */ + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, + 0x0638, 0x0639, 0x063a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xe0 */ + 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, + 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, + /* 0xf0 */ + 0x0650, 0x0651, 0x0652, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, +}; + +static int +iso8859_6_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = iso8859_6_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char iso8859_6_page00[16] = { + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ +}; +static const unsigned char iso8859_6_page06[80] = { + 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0xbf, /* 0x18-0x1f */ + 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x30-0x37 */ + 0xd8, 0xd9, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0xf0, 0xf1, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ +}; + +static int +iso8859_6_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00b0) + c = iso8859_6_page00[wc-0x00a0]; + else if (wc >= 0x0608 && wc < 0x0658) + c = iso8859_6_page06[wc-0x0608]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_7.h b/libs/libiconv/lib/iso8859_7.h new file mode 100644 index 00000000..0825ef5c --- /dev/null +++ b/libs/libiconv/lib/iso8859_7.h @@ -0,0 +1,111 @@ +/* + * Copyright (C) 1999-2004 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-7 + */ + +static const unsigned short iso8859_7_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x2018, 0x2019, 0x00a3, 0x20ac, 0x20af, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x037a, 0x00ab, 0x00ac, 0x00ad, 0xfffd, 0x2015, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x0384, 0x0385, 0x0386, 0x00b7, + 0x0388, 0x0389, 0x038a, 0x00bb, 0x038c, 0x00bd, 0x038e, 0x038f, + /* 0xc0 */ + 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, + 0x0398, 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, + /* 0xd0 */ + 0x03a0, 0x03a1, 0xfffd, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, + 0x03a8, 0x03a9, 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03ae, 0x03af, + /* 0xe0 */ + 0x03b0, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, + 0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, + /* 0xf0 */ + 0x03c0, 0x03c1, 0x03c2, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, + 0x03c8, 0x03c9, 0x03ca, 0x03cb, 0x03cc, 0x03cd, 0x03ce, 0xfffd, +}; + +static int +iso8859_7_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = iso8859_7_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char iso8859_7_page00[32] = { + 0xa0, 0x00, 0x00, 0xa3, 0x00, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0x00, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0x00, 0x00, 0x00, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0xbd, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char iso8859_7_page03[88] = { + 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0xb5, 0xb6, 0x00, /* 0x80-0x87 */ + 0xb8, 0xb9, 0xba, 0x00, 0xbc, 0x00, 0xbe, 0xbf, /* 0x88-0x8f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x90-0x97 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x98-0x9f */ + 0xd0, 0xd1, 0x00, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xa0-0xa7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0xa8-0xaf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xb0-0xb7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xb8-0xbf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xc0-0xc7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0x00, /* 0xc8-0xcf */ +}; +static const unsigned char iso8859_7_page20[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0x00, 0x00, /* 0x10-0x17 */ + 0xa1, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ +}; + +static int +iso8859_7_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = iso8859_7_page00[wc-0x00a0]; + else if (wc >= 0x0378 && wc < 0x03d0) + c = iso8859_7_page03[wc-0x0378]; + else if (wc >= 0x2010 && wc < 0x2020) + c = iso8859_7_page20[wc-0x2010]; + else if (wc == 0x20ac) + c = 0xa4; + else if (wc == 0x20af) + c = 0xa5; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_8.h b/libs/libiconv/lib/iso8859_8.h new file mode 100644 index 00000000..6184846e --- /dev/null +++ b/libs/libiconv/lib/iso8859_8.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-8 + */ + +static const unsigned short iso8859_8_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0xfffd, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00d7, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00f7, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0xfffd, + /* 0xc0 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xd0 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2017, + /* 0xe0 */ + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + /* 0xf0 */ + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, 0xfffd, 0xfffd, 0x200e, 0x200f, 0xfffd, +}; + +static int +iso8859_8_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0xa0) { + unsigned short wc = iso8859_8_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + else { + *pwc = (ucs4_t) c; + return 1; + } + return RET_ILSEQ; +} + +static const unsigned char iso8859_8_page00[88] = { + 0xa0, 0x00, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0xa8, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0xb8, 0xb9, 0x00, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xba, /* 0xf0-0xf7 */ +}; +static const unsigned char iso8859_8_page05[32] = { + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xd0-0xd7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xd8-0xdf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xe0-0xe7 */ + 0xf8, 0xf9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ +}; +static const unsigned char iso8859_8_page20[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xfe, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, /* 0x10-0x17 */ +}; + +static int +iso8859_8_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00f8) + c = iso8859_8_page00[wc-0x00a0]; + else if (wc >= 0x05d0 && wc < 0x05f0) + c = iso8859_8_page05[wc-0x05d0]; + else if (wc >= 0x2008 && wc < 0x2018) + c = iso8859_8_page20[wc-0x2008]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/iso8859_9.h b/libs/libiconv/lib/iso8859_9.h new file mode 100644 index 00000000..7dbd37d2 --- /dev/null +++ b/libs/libiconv/lib/iso8859_9.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-8859-9 + */ + +static const unsigned short iso8859_9_2uni[48] = { + /* 0xd0 */ + 0x011e, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x0130, 0x015e, 0x00df, + /* 0xe0 */ + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + /* 0xf0 */ + 0x011f, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x0131, 0x015f, 0x00ff, +}; + +static int +iso8859_9_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0xd0) + *pwc = (ucs4_t) iso8859_9_2uni[c-0xd0]; + else + *pwc = (ucs4_t) c; + return 1; +} + +static const unsigned char iso8859_9_page00[48] = { + 0x00, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xd0-0xd7 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0x00, 0x00, 0xdf, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xe8-0xef */ + 0x00, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xf0-0xf7 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0x00, 0x00, 0xff, /* 0xf8-0xff */ +}; +static const unsigned char iso8859_9_page01[72] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd0, 0xf0, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xdd, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xfe, /* 0x58-0x5f */ +}; + +static int +iso8859_9_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00d0) { + *r = wc; + return 1; + } + else if (wc >= 0x00d0 && wc < 0x0100) + c = iso8859_9_page00[wc-0x00d0]; + else if (wc >= 0x0118 && wc < 0x0160) + c = iso8859_9_page01[wc-0x0118]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/isoir165.h b/libs/libiconv/lib/isoir165.h new file mode 100644 index 00000000..4d6e9ffa --- /dev/null +++ b/libs/libiconv/lib/isoir165.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 1999-2001, 2005 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-IR-165 + */ + +/* + * ISO-IR-165 is an extension of GB 2312, consisting of: + * 1. GB 6345.1-86 corrections: + * Two corrections to GB 2312, at 0x2367 and 0x6F71. + * 2. GB 6345.1-86 additions: + * - 6 new full-width pinyin characters in row 0x28. + * - ISO646-CN in row 0x2A. + * - 32 half-width pinyin characters in row 0x2B. + * 3. GB 8565.2-88 additions: + * - 50 characters in row 0x2D. + * - 92 characters in row 0x2E. + * - 93 characters in row 0x2F. + * - 470 characters in rows 0x7A-0x7E. + * 4. ISO-IR-165 additions: + * - 22 characters in row 0x26. + * - 94 characters in row 0x2C. + * - 44 new characters in row 0x2D. + * - 1 new character in row 0x2F. + * + * The conversion table was created from the following sources: + * Ad 1. The 0x2367 correction is already integrated in the unicode.org + * GB2312.TXT table. The 0x6F71 mapping is the same in the unicode.org + * GB2312.TXT and UNIHAN.TXT table and in Koichi Yasuoka's Uni2GB table, + * so we assume it's correct. + * The unicode.org UNIHAN.TXT table about GB 8565 is not usable: it has + * extraneous code points at rows 0x28, 0x2C, 0x2D. Note also that it does + * not list the 69 non-hanzi in row 0x2F. Moreover, it has the characters + * 0x2F7A-0x2F7D shifted down by one to 0x2F79-0x2F7C. + * Therefore we take the GB8565 and ISO-IR-165 data from Koichi Yasuoka's + * Uni2GB table. + * Ad 1. Yasuoka maps 0x2367 to U+0261 (small script g) and 0x2840 to U+FF47 + * (full-width small normal g). While coherent with ISO-IR's 165.pdf, + * this disagrees with Ken Lunde's book: He says that ISO-IR-165 + * includes the GB6345 correction, i.e. maps 0x2367 to U+FF47 or U+0067 + * and _not_ to U+0261 (small script g). + * To overcome the confusion, we just map both 0x2367 and 0x2840 to + * U+FF47. + * Ad 2. Row 0x28: Add a mapping from 0x283F to U+01F9. + * Row 0x2A: Mapping is well-known, also present in Koichi Yasuoka's + * table. + * Row 0x2B: Typed in by hand from appendix E in Ken Lunde's book. + * When converting from Unicode to ISO-IR-165, prefer the half-width + * range 0x2B{21..40} to the full-width range 0x28{21..40}. + * Ad 3. Rows 0x2D, 0x2E: Both Koichi Yasuoka's Uni2GB table and the UNIHAN.TXT + * data for GB 8565 agree here. + * Row 0x2F: Taken from Koichi Yasuoka's Uni2GB table. + * Rows 0x7A-0x7E: Koichi Yasuoka's Uni2GB table and the UNIHAN.TXT + * data for GB 8565 agree here mostly. Differences: + * 0x7C38 -> U+6F26 or U+527A ? We choose U+6F26. + * 0x7C5A -> U+7A40 or U+6996 ? We choose U+6996. + * Ad 4. Row 0x26: Mapping unknown. + * Rows 0x2C, 0x2D: Both Koichi Yasuoka's Uni2GB table and the UNIHAN.TXT + * data for GB 8565 (!) agree here. + * Row 0x2F: Taken from Koichi Yasuoka's Uni2GB table. + */ + +#include "isoir165ext.h" + +static int +isoir165_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + int ret; + + /* Map full-width pinyin (row 0x28) like half-width pinyin (row 0x2B). */ + if (s[0] == 0x28) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 <= 0x40) { + unsigned char buf[2]; + buf[0] = 0x2b; + buf[1] = c2; + ret = isoir165ext_mbtowc(conv,pwc,buf,2); + if (ret != RET_ILSEQ) + return ret; + } + } + } + /* Try the GB2312 -> Unicode table. */ + ret = gb2312_mbtowc(conv,pwc,s,n); + if (ret != RET_ILSEQ) + return ret; + /* Row 0x2A is GB_1988-80. */ + if (s[0] == 0x2a) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + int ret = iso646_cn_mbtowc(conv,pwc,s+1,1); + if (ret != 1) abort(); + return 2; + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + /* Try the ISO-IR-165 extensions -> Unicode table. */ + ret = isoir165ext_mbtowc(conv,pwc,s,n); + return ret; +} + +static int +isoir165_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[2]; + int ret; + + /* Try the Unicode -> GB2312 table. */ + ret = gb2312_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (!(buf[0] == 0x28 && buf[1] >= 0x21 && buf[1] <= 0x40)) { + if (n >= 2) { + r[0] = buf[0]; + r[1] = buf[1]; + return 2; + } + return RET_TOOSMALL; + } + } + /* Row 0x2A is GB_1988-80. */ + ret = iso646_cn_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + if (ret != 1) abort(); + if (buf[0] >= 0x21 && buf[0] < 0x7f) { + if (n >= 2) { + r[0] = 0x2a; + r[1] = buf[0]; + return 2; + } + return RET_TOOSMALL; + } + } + /* Try the Unicode -> ISO-IR-165 extensions table. */ + ret = isoir165ext_wctomb(conv,r,wc,n); + return ret; +} diff --git a/libs/libiconv/lib/isoir165ext.h b/libs/libiconv/lib/isoir165ext.h new file mode 100644 index 00000000..0bc811ac --- /dev/null +++ b/libs/libiconv/lib/isoir165ext.h @@ -0,0 +1,800 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * ISO-IR-165 extensions + */ + +static const unsigned short isoir165ext_2uni_page2b[470] = { + /* 0x2b */ + 0x1fb1, 0x03ac, 0x1fb0, 0x1f70, 0x0113, 0x00e9, 0x011b, 0x00e8, + 0x012b, 0x00ed, 0x01d0, 0x00ec, 0x014d, 0x00f3, 0x01d2, 0x00f2, + 0x016b, 0x00fa, 0x01d4, 0x00f9, 0x01d6, 0x01d8, 0x01da, 0x01dc, + 0x00fc, 0x00ea, 0x03b1, 0x1e3f, 0x0144, 0x0148, 0x01f9, 0xff47, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x2c */ + 0x53be, 0x4eb8, 0x4f3e, 0x501e, 0x50c7, 0x9118, 0x6c98, 0x6cdc, + 0x6cc3, 0x6e5d, 0x6ea6, 0x6eeb, 0x6fa5, 0x6165, 0x5ea4, 0x9618, + 0x5848, 0x8453, 0x7cf5, 0x5f07, 0x6294, 0x647d, 0x725a, 0x5574, + 0x55a4, 0x5640, 0x5684, 0x5d1f, 0x72c9, 0x998c, 0x59de, 0x59fd, + 0x5a5e, 0x7ebb, 0x7ee4, 0x7ef9, 0x9a99, 0x71cf, 0x6245, 0x624a, + 0x797c, 0x739a, 0x742b, 0x7488, 0x74aa, 0x74d8, 0x6767, 0x6ab5, + 0x71ca, 0x6ba3, 0x8f80, 0x8f92, 0x8d5f, 0x9b36, 0x72a8, 0x87a3, + 0x8152, 0x6b38, 0x98d0, 0x8897, 0x88af, 0x8955, 0x770a, 0x94da, + 0x955a, 0x9560, 0x9e24, 0x9e40, 0x9e50, 0x9e5d, 0x9e60, 0x870e, + 0x7b5c, 0x7fd9, 0x7fef, 0x7e44, 0x8e45, 0x8e36, 0x8e62, 0x8e5c, + 0x9778, 0x9b46, 0x9f2b, 0x9f41, 0x7526, 0x4e26, 0x8bac, 0x8129, + 0x5091, 0x50cd, 0x52b9, 0x89d4, 0x5557, 0x94c7, + /* 0x2d */ + 0x9496, 0x9498, 0x94cf, 0x94d3, 0x94d4, 0x94e6, 0x9533, 0x951c, + 0x9520, 0x9527, 0x953d, 0x9543, 0x956e, 0x9574, 0x9c80, 0x9c84, + 0x9c8a, 0x9c93, 0x9c96, 0x9c97, 0x9c98, 0x9c99, 0x9cbf, 0x9cc0, + 0x9cc1, 0x9cd2, 0x9cdb, 0x9ce0, 0x9ce3, 0x9770, 0x977a, 0x97a1, + 0x97ae, 0x97a8, 0x9964, 0x9966, 0x9978, 0x9979, 0x997b, 0x997e, + 0x9982, 0x9983, 0x998e, 0x9b10, 0x9b18, 0x65a2, 0x9e80, 0x911c, + 0x9e91, 0x9f12, 0x52f3, 0x6c96, 0x6d44, 0x6e1b, 0x6e67, 0x6f82, + 0x6fec, 0x60ae, 0x5ec8, 0x8ffa, 0x577f, 0x5586, 0x849e, 0x8460, + 0x5c05, 0x5e0b, 0x5d11, 0x5d19, 0x5dd6, 0x59b3, 0x5aae, 0x9a94, + 0x658f, 0x709e, 0x7551, 0x71ff, 0x691d, 0x6a11, 0x68bf, 0x6607, + 0x668e, 0x6673, 0x6c25, 0x7652, 0x778b, 0x76ea, 0x9895, 0x8780, + 0x882d, 0x7b87, 0x7c50, 0x8ead, 0x9575, 0x65c2, + /* 0x2e */ + 0x5390, 0x79b8, 0x4f15, 0x4f21, 0x4f3b, 0x4fa2, 0x50a4, 0x5092, + 0x530a, 0x51c3, 0x51a8, 0x8d20, 0x5787, 0x579a, 0x5795, 0x57eb, + 0x585d, 0x585a, 0x5871, 0x5895, 0x5c30, 0x5f0c, 0x5f0d, 0x5f0e, + 0x5c72, 0x5cc7, 0x5fac, 0x5f68, 0x5f5f, 0x5a12, 0x5a65, 0x5a84, + 0x5ac4, 0x7394, 0x73ea, 0x73ee, 0x7437, 0x7415, 0x7454, 0x6799, + 0x686c, 0x68f8, 0x69fe, 0x72e2, 0x6667, 0x8d52, 0x89c3, 0x89cd, + 0x6427, 0x6477, 0x6c1d, 0x813f, 0x6b54, 0x98d6, 0x707a, 0x70f1, + 0x7120, 0x6153, 0x6c87, 0x6dad, 0x6e81, 0x6eb5, 0x6f94, 0x6f9b, + 0x793d, 0x794e, 0x7806, 0x7859, 0x7894, 0x78dc, 0x7903, 0x7a16, + 0x7a5e, 0x75e0, 0x7adc, 0x7676, 0x9892, 0x7bf2, 0x7c30, 0x7c5d, + 0x9c9d, 0x7cac, 0x8278, 0x83d1, 0x84ea, 0x7fc0, 0x7f1e, 0x8e21, + 0x8e53, 0x9754, 0x9f0c, 0x94fb, 0xfffd, 0xfffd, + /* 0x2f */ + 0x32c0, 0x32c1, 0x32c2, 0x32c3, 0x32c4, 0x32c5, 0x32c6, 0x32c7, + 0x32c8, 0x32c9, 0x32ca, 0x32cb, 0x33e0, 0x33e1, 0x33e2, 0x33e3, + 0x33e4, 0x33e5, 0x33e6, 0x33e7, 0x33e8, 0x33e9, 0x33ea, 0x33eb, + 0x33ec, 0x33ed, 0x33ee, 0x33ef, 0x33f0, 0x33f1, 0x33f2, 0x33f3, + 0x33f4, 0x33f5, 0x33f6, 0x33f7, 0x33f8, 0x33f9, 0x33fa, 0x33fb, + 0x33fc, 0x33fd, 0x33fe, 0x3358, 0x3359, 0x335a, 0x335b, 0x335c, + 0x335d, 0x335e, 0x335f, 0x3360, 0x3361, 0x3362, 0x3363, 0x3364, + 0x3365, 0x3366, 0x3367, 0x3368, 0x3369, 0x336a, 0x336b, 0x336c, + 0x336d, 0x336e, 0x336f, 0x3370, 0x3037, 0x90a8, 0x965e, 0x5842, + 0x5803, 0x6c3e, 0x6d29, 0x6ee7, 0x8534, 0x84c6, 0x633c, 0x5d05, + 0x7f10, 0x7eec, 0x7287, 0x712e, 0x8218, 0x8216, 0x756c, 0x75f3, + 0x9b25, 0x8980, 0x7ca6, 0x4e85, 0x5570, 0x91c6, +}; +static const unsigned short isoir165ext_2uni_page7a[470] = { + /* 0x7a */ + 0x4e0f, 0x673f, 0x4e42, 0x752a, 0x592c, 0x9ee1, 0x8652, 0x531c, + 0x5187, 0x518f, 0x50f0, 0x4f0b, 0x4f23, 0x4f03, 0x4f61, 0x4f7a, + 0x4f6b, 0x4feb, 0x4ff5, 0x5034, 0x5022, 0x4ff6, 0x5072, 0x4eb6, + 0x51ae, 0x5910, 0x6bda, 0x522c, 0x5232, 0x4fb4, 0x5298, 0x52bb, + 0x52bc, 0x52cd, 0x52da, 0x52f7, 0x53c6, 0x53c7, 0x5770, 0x576c, + 0x57b1, 0x579f, 0x579e, 0x57be, 0x57cc, 0x580e, 0x580c, 0x57f5, + 0x5809, 0x583c, 0x5843, 0x5845, 0x5846, 0x583d, 0x5853, 0x5888, + 0x5884, 0x58f8, 0x56ad, 0x5940, 0x5953, 0x596d, 0x5c2a, 0x54a5, + 0x551d, 0x5536, 0x556f, 0x554d, 0x569a, 0x569c, 0x56f7, 0x5710, + 0x5719, 0x5e17, 0x5e21, 0x5e28, 0x5e6a, 0x5c74, 0x5c7c, 0x5ca8, + 0x5c9e, 0x5cc3, 0x5cd3, 0x5ce3, 0x5ce7, 0x5cff, 0x5d04, 0x5d00, + 0x5d1a, 0x5d0c, 0x5d4e, 0x5d5a, 0x5d85, 0x5d93, + /* 0x7b */ + 0x5d92, 0x5dc2, 0x5dc9, 0x8852, 0x5faf, 0x5906, 0x65a8, 0x7241, + 0x7242, 0x5ebc, 0x5ecb, 0x95ec, 0x95ff, 0x8a1a, 0x9607, 0x9613, + 0x961b, 0x5bac, 0x5ba7, 0x5c5d, 0x5f22, 0x59ee, 0x5a7c, 0x5a96, + 0x5a73, 0x5a9e, 0x5aad, 0x5ada, 0x5aea, 0x5b1b, 0x5b56, 0x9a72, + 0x9a83, 0x9a89, 0x9a8d, 0x9a8e, 0x9a95, 0x9aa6, 0x7395, 0x7399, + 0x73a0, 0x73b1, 0x73a5, 0x73a6, 0x73d6, 0x73f0, 0x73fd, 0x73e3, + 0x7424, 0x740e, 0x7407, 0x73f6, 0x73fa, 0x7432, 0x742f, 0x7444, + 0x7442, 0x7471, 0x7478, 0x7462, 0x7486, 0x749f, 0x74a0, 0x7498, + 0x74b2, 0x97e8, 0x6745, 0x679f, 0x677b, 0x67c8, 0x67ee, 0x684b, + 0x68a0, 0x6812, 0x681f, 0x686a, 0x68bc, 0x68fb, 0x686f, 0x68b1, + 0x68c1, 0x68eb, 0x6913, 0x68d1, 0x6911, 0x68d3, 0x68ec, 0x692b, + 0x68e8, 0x69be, 0x6969, 0x6940, 0x696f, 0x695f, + /* 0x7c */ + 0x6962, 0x6935, 0x6959, 0x69bc, 0x69c5, 0x69da, 0x69dc, 0x6a0b, + 0x69e5, 0x6a66, 0x6a96, 0x6ab4, 0x72dd, 0x5cf1, 0x7314, 0x733a, + 0x6b95, 0x5f67, 0x80fe, 0x74fb, 0x7503, 0x655c, 0x6569, 0x6f26, + 0x65f8, 0x65fb, 0x6609, 0x663d, 0x6662, 0x665e, 0x666c, 0x668d, + 0x668b, 0x8d51, 0x8d57, 0x7263, 0x7277, 0x63b1, 0x6261, 0x6260, + 0x6283, 0x62e4, 0x62c3, 0x631c, 0x6326, 0x63af, 0x63fe, 0x6422, + 0x6412, 0x64ed, 0x6713, 0x6718, 0x8158, 0x81d1, 0x98cf, 0x98d4, + 0x98d7, 0x6996, 0x7098, 0x70dc, 0x70fa, 0x710c, 0x711c, 0x71cb, + 0x721f, 0x70dd, 0x659d, 0x6246, 0x6017, 0x60c7, 0x60d3, 0x60b0, + 0x60d9, 0x6114, 0x6c3f, 0x6c67, 0x6c84, 0x6c9a, 0x6c6d, 0x6ca8, + 0x6cc6, 0x6cb5, 0x6d49, 0x6d38, 0x6d11, 0x6d3a, 0x6d28, 0x6d50, + 0x6d34, 0x6d55, 0x6d61, 0x6da2, 0x6d65, 0x6d5b, + /* 0x7d */ + 0x6d64, 0x6db4, 0x6e9a, 0x6e5c, 0x6e72, 0x6ea0, 0x6e87, 0x6e8e, + 0x6ec9, 0x6ec3, 0x6f37, 0x6ed8, 0x6eea, 0x6f56, 0x6f75, 0x6f5f, + 0x6fb4, 0x6fbc, 0x7014, 0x700d, 0x700c, 0x703c, 0x7943, 0x7947, + 0x794a, 0x7950, 0x7972, 0x7998, 0x79a0, 0x79a4, 0x77fc, 0x77fb, + 0x7822, 0x7820, 0x7841, 0x785a, 0x7875, 0x78b6, 0x78e1, 0x7933, + 0x8a5f, 0x76fb, 0x771b, 0x772c, 0x7786, 0x77ab, 0x77ad, 0x7564, + 0x756f, 0x6983, 0x7f7d, 0x76dd, 0x76e6, 0x76ec, 0x7521, 0x79fe, + 0x7a44, 0x767f, 0x769e, 0x9e27, 0x9e2e, 0x9e30, 0x9e34, 0x9e4d, + 0x9e52, 0x9e53, 0x9e54, 0x9e56, 0x9e59, 0x9e61, 0x9e62, 0x9e65, + 0x9e6f, 0x9e74, 0x75a2, 0x7604, 0x7608, 0x761d, 0x7ad1, 0x7a85, + 0x7a8e, 0x7aa3, 0x7ab8, 0x7abe, 0x77de, 0x8030, 0x988b, 0x988e, + 0x9899, 0x98a3, 0x8683, 0x8705, 0x8758, 0x87cf, + /* 0x7e */ + 0x87e2, 0x880b, 0x80d4, 0x7f4d, 0x7b4a, 0x7b4e, 0x7b7f, 0x7b93, + 0x7bef, 0x7c09, 0x7bf0, 0x7c15, 0x7c03, 0x7c20, 0x823a, 0x8886, + 0x88aa, 0x88c0, 0x88c8, 0x8926, 0x8976, 0x7f91, 0x8283, 0x82bc, + 0x82a7, 0x8313, 0x82fe, 0x8300, 0x835d, 0x8345, 0x8344, 0x831d, + 0x83a6, 0x8399, 0x83fe, 0x841a, 0x83fc, 0x8429, 0x8439, 0x84a8, + 0x84cf, 0x849f, 0x84c2, 0x84f7, 0x8570, 0x85b3, 0x85a2, 0x96d8, + 0x85b8, 0x85e0, 0x7fda, 0x7eae, 0x7eb4, 0x7ebc, 0x7ed6, 0x7f0a, + 0x5b43, 0x8d6a, 0x5245, 0x8c68, 0x8c6e, 0x8c6d, 0x8e16, 0x8e26, + 0x8e27, 0x8e50, 0x9098, 0x90a0, 0x90bd, 0x90c8, 0x90c3, 0x90da, + 0x90ff, 0x911a, 0x910c, 0x9120, 0x9142, 0x8fb5, 0x90e4, 0x8c86, + 0x89f1, 0x8bb1, 0x8bbb, 0x8bc7, 0x8bea, 0x8c09, 0x8c1e, 0x9702, + 0x68d0, 0x7306, 0x9f81, 0x9f82, 0x92c6, 0x9491, +}; + +static int +isoir165ext_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x2b && c1 <= 0x2f) || (c1 >= 0x7a && c1 <= 0x7e)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + unsigned short wc = 0xfffd; + if (i < 8366) { + if (i < 1410) + wc = isoir165ext_2uni_page2b[i-940]; + } else { + if (i < 8836) + wc = isoir165ext_2uni_page7a[i-8366]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short isoir165ext_2charset[876] = { + 0x2b28, 0x2b26, 0x2b3a, 0x2b2c, 0x2b2a, 0x2b30, 0x2b2e, 0x2b34, + 0x2b32, 0x2b39, 0x2b25, 0x2b27, 0x2b29, 0x2b3d, 0x2b3e, 0x2b2d, + 0x2b31, 0x2b2b, 0x2b2f, 0x2b33, 0x2b35, 0x2b36, 0x2b37, 0x2b38, + 0x2b3f, 0x2b22, 0x2b3b, 0x2b3c, 0x2b24, 0x2b23, 0x2b21, 0x2f65, + 0x2f21, 0x2f22, 0x2f23, 0x2f24, 0x2f25, 0x2f26, 0x2f27, 0x2f28, + 0x2f29, 0x2f2a, 0x2f2b, 0x2f2c, 0x2f4c, 0x2f4d, 0x2f4e, 0x2f4f, + 0x2f50, 0x2f51, 0x2f52, 0x2f53, 0x2f54, 0x2f55, 0x2f56, 0x2f57, + 0x2f58, 0x2f59, 0x2f5a, 0x2f5b, 0x2f5c, 0x2f5d, 0x2f5e, 0x2f5f, + 0x2f60, 0x2f61, 0x2f62, 0x2f63, 0x2f64, 0x2f2d, 0x2f2e, 0x2f2f, + 0x2f30, 0x2f31, 0x2f32, 0x2f33, 0x2f34, 0x2f35, 0x2f36, 0x2f37, + 0x2f38, 0x2f39, 0x2f3a, 0x2f3b, 0x2f3c, 0x2f3d, 0x2f3e, 0x2f3f, + 0x2f40, 0x2f41, 0x2f42, 0x2f43, 0x2f44, 0x2f45, 0x2f46, 0x2f47, + 0x2f48, 0x2f49, 0x2f4a, 0x2f4b, 0x7a21, 0x2c76, 0x7a23, 0x2f7c, + 0x7a38, 0x2c22, 0x7a2e, 0x7a2c, 0x2e23, 0x2e24, 0x7a2d, 0x2e25, + 0x2c23, 0x7a2f, 0x7a31, 0x7a30, 0x2e26, 0x7a3e, 0x7a32, 0x7a33, + 0x7a36, 0x2c24, 0x7a35, 0x7a34, 0x7a37, 0x2c79, 0x2e28, 0x2e27, + 0x2c25, 0x2c7a, 0x7a2b, 0x7a29, 0x7a2a, 0x2e2b, 0x7a39, 0x2e2a, + 0x7a3c, 0x7a3d, 0x7e5b, 0x7a3f, 0x2c7b, 0x7a40, 0x7a41, 0x7a42, + 0x7a43, 0x2d53, 0x7a44, 0x2e29, 0x7a28, 0x2e21, 0x2c21, 0x7a45, + 0x7a46, 0x7a60, 0x7a61, 0x7a62, 0x7a64, 0x2c7d, 0x7a63, 0x2f7d, + 0x2c38, 0x2d5e, 0x2c39, 0x2c3a, 0x2c3b, 0x7a65, 0x7a66, 0x7a5b, + 0x7a67, 0x7a68, 0x7a69, 0x7a48, 0x7a47, 0x2d5d, 0x2e2d, 0x2e2f, + 0x2e2e, 0x7a4b, 0x7a4a, 0x7a49, 0x7a4c, 0x7a4d, 0x2e30, 0x7a50, + 0x2f69, 0x7a51, 0x7a4f, 0x7a4e, 0x7a52, 0x7a56, 0x2f68, 0x7a53, + 0x7a54, 0x7a55, 0x2c31, 0x7a57, 0x2e32, 0x2e31, 0x2e33, 0x7a59, + 0x7a58, 0x2e34, 0x7a5a, 0x7b26, 0x7a3a, 0x7a25, 0x7a5c, 0x7a5d, + 0x7a5e, 0x2d66, 0x2c3f, 0x7b36, 0x2c40, 0x2e3e, 0x2c41, 0x2e3f, + 0x7b39, 0x7b37, 0x2e40, 0x7b38, 0x7b3a, 0x7b3b, 0x2d67, 0x2e41, + 0x7b3c, 0x7b3d, 0x7b3e, 0x7e59, 0x7b3f, 0x7b33, 0x7b32, 0x2d61, + 0x7a5f, 0x2e35, 0x7b34, 0x2e39, 0x7a6e, 0x7a6f, 0x7a71, 0x7a70, + 0x7a72, 0x2e3a, 0x7a73, 0x7a74, 0x7a75, 0x7c2e, 0x7a76, 0x7a78, + 0x7a77, 0x2f70, 0x7a7a, 0x2d63, 0x2d64, 0x7a79, 0x2c3c, 0x7a7b, + 0x7a7c, 0x7a7d, 0x7b21, 0x7a7e, 0x7b22, 0x7b23, 0x2d65, 0x2d62, + 0x7a6a, 0x7a6b, 0x7a6c, 0x7a6d, 0x2c2f, 0x7b2a, 0x2d5b, 0x7b2b, + 0x2c34, 0x2e36, 0x2e37, 0x2e38, 0x7b35, 0x2e3d, 0x7c32, 0x2e3c, + 0x2e3b, 0x7b25, 0x7c65, 0x2d5a, 0x7c68, 0x7c66, 0x7c67, 0x7c69, + 0x7c6a, 0x2e5a, 0x2c2e, 0x2c47, 0x7c64, 0x2c48, 0x7c48, 0x7c47, + 0x7c49, 0x2c35, 0x7c4b, 0x7c4a, 0x7c4c, 0x7c4d, 0x2f6f, 0x7c4e, + 0x7c46, 0x7c4f, 0x7c51, 0x7c50, 0x2e51, 0x2e52, 0x2c36, 0x7c52, + 0x7c36, 0x7c37, 0x2d69, 0x7c63, 0x2d4e, 0x7b27, 0x2d7e, 0x7c39, + 0x7c3a, 0x2d70, 0x7c3b, 0x7c3c, 0x7c3e, 0x7c3d, 0x2e4d, 0x7c3f, + 0x2d72, 0x7c41, 0x7c40, 0x2d71, 0x7c53, 0x7c54, 0x7a22, 0x7b63, + 0x2c4f, 0x7b65, 0x2e48, 0x7b64, 0x7b66, 0x7b67, 0x7b6a, 0x7b6b, + 0x7b68, 0x7b6c, 0x2e49, 0x7b6f, 0x7b69, 0x7b70, 0x7b6d, 0x2d6f, + 0x7b71, 0x7e79, 0x7b74, 0x7b76, 0x7b79, 0x7b72, 0x7b77, 0x2e4a, + 0x7b6e, 0x7b75, 0x7b73, 0x2d6d, 0x7b78, 0x7c22, 0x7b7c, 0x7c23, + 0x7b7e, 0x7c21, 0x7b7b, 0x7b7d, 0x7d52, 0x7c5a, 0x7c24, 0x7b7a, + 0x7c25, 0x7c26, 0x7c27, 0x7c29, 0x2e4b, 0x7c28, 0x2d6e, 0x7c2a, + 0x7c2b, 0x7c2c, 0x2c50, 0x2c5a, 0x2e55, 0x7c31, 0x2c52, 0x7a3b, + 0x2e53, 0x2d73, 0x2f6a, 0x7c6b, 0x7c6c, 0x7c6f, 0x7c6d, 0x2e5b, + 0x2d54, 0x2c27, 0x7c6e, 0x7c70, 0x7c72, 0x2c29, 0x7c71, 0x2c28, + 0x7c75, 0x7c77, 0x2f6b, 0x7c79, 0x7c74, 0x7c76, 0x2d55, 0x7c73, + 0x7c78, 0x7c7a, 0x7c7e, 0x7c7b, 0x7d21, 0x7c7d, 0x7c7c, 0x2e5c, + 0x7d22, 0x2d56, 0x7d24, 0x2c2a, 0x2d57, 0x7d25, 0x2e5d, 0x7d27, + 0x7d28, 0x7d23, 0x7d26, 0x2c2b, 0x2e5e, 0x7d2a, 0x7d29, 0x7d2c, + 0x2f6c, 0x7d2d, 0x2c2c, 0x7c38, 0x7d2b, 0x7d2e, 0x7d30, 0x7d2f, + 0x2d58, 0x2e5f, 0x2e60, 0x2c2d, 0x7d31, 0x7d32, 0x2d59, 0x7d35, + 0x7d34, 0x7d33, 0x7d36, 0x2e57, 0x7c5b, 0x2d6a, 0x7c5c, 0x7c62, + 0x2e58, 0x7c5d, 0x7c5e, 0x7c5f, 0x2e59, 0x2f74, 0x2c51, 0x7c60, + 0x2c46, 0x2d6c, 0x7c61, 0x7b28, 0x7b29, 0x2c37, 0x7c44, 0x7c45, + 0x2f73, 0x2c57, 0x2c3d, 0x7c2d, 0x2e4c, 0x7e7a, 0x7c2f, 0x7c30, + 0x2e42, 0x7b47, 0x7b48, 0x2c4a, 0x7b49, 0x7b4b, 0x7b4c, 0x7b4a, + 0x7b4d, 0x7b50, 0x2e43, 0x2e44, 0x7b4e, 0x7b54, 0x7b55, 0x7b4f, + 0x7b53, 0x7b52, 0x2e46, 0x7b51, 0x2c4b, 0x7b57, 0x7b56, 0x2e45, + 0x7b59, 0x7b58, 0x2e47, 0x7b5c, 0x7b5a, 0x7b5b, 0x7b5d, 0x2c4c, + 0x7b60, 0x7b5e, 0x7b5f, 0x2c4d, 0x7b61, 0x2c4e, 0x7c34, 0x7c35, + 0x7d57, 0x2c75, 0x7a24, 0x2d6b, 0x7d50, 0x2f77, 0x7d51, 0x7d6b, + 0x2e6a, 0x2f78, 0x7d6c, 0x7d6d, 0x7d6e, 0x2d74, 0x2e6c, 0x7d5a, + 0x7d5b, 0x7d54, 0x7d55, 0x2d76, 0x7d56, 0x7d4a, 0x2c5f, 0x7d4b, + 0x7d4c, 0x7d4d, 0x2d75, 0x7d4e, 0x7d4f, 0x7d75, 0x7d40, 0x7d3f, + 0x2e63, 0x7d42, 0x7d41, 0x7d43, 0x2e64, 0x7d44, 0x7d45, 0x2e65, + 0x7d46, 0x2e66, 0x7d47, 0x2e67, 0x7d48, 0x2e61, 0x7d37, 0x7d38, + 0x7d39, 0x2e62, 0x7d3a, 0x7d3b, 0x2c49, 0x7d3c, 0x7d3d, 0x7d3e, + 0x2e22, 0x7d58, 0x2e68, 0x7d59, 0x2e69, 0x7d70, 0x7d71, 0x7d72, + 0x7d73, 0x7d74, 0x7d6f, 0x2e6b, 0x7e25, 0x7e26, 0x2c69, 0x7e27, + 0x2d7a, 0x7e28, 0x7e29, 0x7e2b, 0x2e6e, 0x7e2d, 0x7e2a, 0x7e2c, + 0x7e2e, 0x2e6f, 0x2d7b, 0x2e70, 0x2f7b, 0x2e72, 0x2c33, 0x2c6c, + 0x7e54, 0x7e55, 0x2c42, 0x7e56, 0x7e57, 0x2c43, 0x2f72, 0x2c44, + 0x7e58, 0x2f71, 0x2e77, 0x7e24, 0x7d53, 0x7e36, 0x2e76, 0x2c6a, + 0x7e53, 0x2c6b, 0x7d76, 0x7e23, 0x7c33, 0x2c78, 0x2e54, 0x2c59, + 0x7c55, 0x7c56, 0x2f76, 0x2f75, 0x7e2f, 0x2e73, 0x7e37, 0x7e39, + 0x7e38, 0x7e3b, 0x7e3c, 0x7e3a, 0x7e40, 0x7e3f, 0x7e3e, 0x7e3d, + 0x7e42, 0x7e41, 0x2e74, 0x7e45, 0x7e43, 0x7e44, 0x7e46, 0x7e47, + 0x2c32, 0x2d60, 0x2d5f, 0x7e4a, 0x7e48, 0x7e4b, 0x2f6e, 0x7e49, + 0x2e75, 0x7e4c, 0x2f6d, 0x7e4d, 0x7e4f, 0x7e4e, 0x7e51, 0x7e52, + 0x7a27, 0x7d7b, 0x7d7c, 0x2c68, 0x7d7d, 0x2d78, 0x2c58, 0x7d7e, + 0x7e21, 0x7e22, 0x2d79, 0x7b24, 0x7e30, 0x2c5c, 0x7e31, 0x2c5d, + 0x7e32, 0x7e33, 0x7e34, 0x2c5e, 0x7e35, 0x2f7a, 0x2e4f, 0x2e50, + 0x2c7c, 0x7e71, 0x7b2e, 0x7d49, 0x2c77, 0x7e72, 0x7e73, 0x7e74, + 0x7e75, 0x7e76, 0x7e77, 0x7e5c, 0x7e5e, 0x7e5d, 0x7e70, 0x2e2c, + 0x7c42, 0x2e4e, 0x7c43, 0x2c55, 0x7e5a, 0x7e5f, 0x2e78, 0x7e60, + 0x7e61, 0x2c6e, 0x2c6d, 0x7e62, 0x2e79, 0x2c70, 0x2c6f, 0x2d7c, + 0x2c53, 0x2c54, 0x7e6e, 0x2d5c, 0x7e63, 0x7e64, 0x2f66, 0x7e65, + 0x7e67, 0x7e66, 0x7e68, 0x7e6f, 0x7e69, 0x7e6b, 0x2c26, 0x7e6a, + 0x2d50, 0x7e6c, 0x7e6d, 0x2f7e, 0x7e7d, 0x7e7e, 0x2d21, 0x2d22, + 0x2c7e, 0x2d23, 0x2d24, 0x2d25, 0x2c60, 0x2d26, 0x2e7c, 0x2d28, + 0x2d29, 0x2d2a, 0x2d27, 0x2d2b, 0x2d2c, 0x2c61, 0x2c62, 0x2d2d, + 0x2d2e, 0x2d7d, 0x7b2c, 0x7b2d, 0x7b2f, 0x7b30, 0x2c30, 0x7b31, + 0x2f67, 0x7e50, 0x7e78, 0x2e7a, 0x2d3e, 0x2c71, 0x2d3f, 0x2d40, + 0x2d42, 0x2d41, 0x7b62, 0x7d77, 0x7d78, 0x2e6d, 0x2d77, 0x7d79, + 0x7d7a, 0x7c57, 0x2c5b, 0x7c58, 0x2e56, 0x7c59, 0x2d43, 0x2d44, + 0x2d45, 0x2d46, 0x2d47, 0x2d48, 0x2d49, 0x2d4a, 0x2c3e, 0x2d4b, + 0x7b40, 0x7b41, 0x7b42, 0x7b43, 0x7b44, 0x2d68, 0x7b45, 0x2c45, + 0x7b46, 0x2d4c, 0x2d4d, 0x2f79, 0x2c56, 0x2c72, 0x2d2f, 0x2d30, + 0x2d31, 0x2d32, 0x2d33, 0x2d34, 0x2d35, 0x2d36, 0x2e71, 0x2d37, + 0x2d38, 0x2d39, 0x2d3a, 0x2d3b, 0x2d3c, 0x2d3d, 0x2c63, 0x7d5c, + 0x7d5d, 0x7d5e, 0x7d5f, 0x2c64, 0x7d60, 0x2c65, 0x7d61, 0x7d62, + 0x7d63, 0x7d64, 0x7d65, 0x2c66, 0x2c67, 0x7d66, 0x7d67, 0x7d68, + 0x7d69, 0x7d6a, 0x2d4f, 0x2d51, 0x7a26, 0x2e7b, 0x2d52, 0x2c73, + 0x2c74, 0x7e7b, 0x7e7c, 0x2b40, +}; + +static const Summary16 isoir165ext_uni2indx_page00[32] = { + /* 0x0000 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x3700 }, { 5, 0x160c }, + /* 0x0100 */ + { 10, 0x0000 }, { 10, 0x0808 }, { 12, 0x0800 }, { 13, 0x0000 }, + { 13, 0x2110 }, { 16, 0x0000 }, { 16, 0x0800 }, { 17, 0x0000 }, + { 17, 0x0000 }, { 17, 0x0000 }, { 17, 0x0000 }, { 17, 0x0000 }, + { 17, 0x0000 }, { 17, 0x1555 }, { 24, 0x0000 }, { 24, 0x0200 }, +}; +static const Summary16 isoir165ext_uni2indx_page03[12] = { + /* 0x0300 */ + { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, + { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x0000 }, + { 25, 0x0000 }, { 25, 0x0000 }, { 25, 0x1000 }, { 26, 0x0002 }, +}; +static const Summary16 isoir165ext_uni2indx_page1e[28] = { + /* 0x1e00 */ + { 27, 0x0000 }, { 27, 0x0000 }, { 27, 0x0000 }, { 27, 0x8000 }, + { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0000 }, + { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0000 }, + { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0000 }, + /* 0x1f00 */ + { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0000 }, + { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0000 }, { 28, 0x0001 }, + { 29, 0x0000 }, { 29, 0x0000 }, { 29, 0x0000 }, { 29, 0x0003 }, +}; +static const Summary16 isoir165ext_uni2indx_page30[4] = { + /* 0x3000 */ + { 31, 0x0000 }, { 31, 0x0000 }, { 31, 0x0000 }, { 31, 0x0080 }, +}; +static const Summary16 isoir165ext_uni2indx_page32[32] = { + /* 0x3200 */ + { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0000 }, + { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0000 }, + { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0000 }, { 32, 0x0000 }, + { 32, 0x0fff }, { 44, 0x0000 }, { 44, 0x0000 }, { 44, 0x0000 }, + /* 0x3300 */ + { 44, 0x0000 }, { 44, 0x0000 }, { 44, 0x0000 }, { 44, 0x0000 }, + { 44, 0x0000 }, { 44, 0xff00 }, { 52, 0xffff }, { 68, 0x0001 }, + { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0x0000 }, + { 69, 0x0000 }, { 69, 0x0000 }, { 69, 0xffff }, { 85, 0x7fff }, +}; +static const Summary16 isoir165ext_uni2indx_page4e[752] = { + /* 0x4e00 */ + { 100, 0x8000 }, { 101, 0x0000 }, { 101, 0x0040 }, { 102, 0x0000 }, + { 102, 0x0004 }, { 103, 0x0000 }, { 103, 0x0000 }, { 103, 0x0000 }, + { 103, 0x0020 }, { 104, 0x0000 }, { 104, 0x0000 }, { 104, 0x0140 }, + { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x0000 }, { 106, 0x0000 }, + /* 0x4f00 */ + { 106, 0x0808 }, { 108, 0x0020 }, { 109, 0x000a }, { 111, 0x4800 }, + { 113, 0x0000 }, { 113, 0x0000 }, { 113, 0x0802 }, { 115, 0x0400 }, + { 116, 0x0000 }, { 116, 0x0000 }, { 116, 0x0004 }, { 117, 0x0010 }, + { 118, 0x0000 }, { 118, 0x0000 }, { 118, 0x0800 }, { 119, 0x0060 }, + /* 0x5000 */ + { 121, 0x0000 }, { 121, 0x4000 }, { 122, 0x0004 }, { 123, 0x0010 }, + { 124, 0x0000 }, { 124, 0x0000 }, { 124, 0x0000 }, { 124, 0x0004 }, + { 125, 0x0000 }, { 125, 0x0006 }, { 127, 0x0010 }, { 128, 0x0000 }, + { 128, 0x2080 }, { 130, 0x0000 }, { 130, 0x0000 }, { 130, 0x0001 }, + /* 0x5100 */ + { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, + { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, { 131, 0x0000 }, + { 131, 0x8080 }, { 133, 0x0000 }, { 133, 0x4100 }, { 135, 0x0000 }, + { 135, 0x0008 }, { 136, 0x0000 }, { 136, 0x0000 }, { 136, 0x0000 }, + /* 0x5200 */ + { 136, 0x0000 }, { 136, 0x0000 }, { 136, 0x1000 }, { 137, 0x0004 }, + { 138, 0x0020 }, { 139, 0x0000 }, { 139, 0x0000 }, { 139, 0x0000 }, + { 139, 0x0000 }, { 139, 0x0100 }, { 140, 0x0000 }, { 140, 0x1a00 }, + { 143, 0x2000 }, { 144, 0x0400 }, { 145, 0x0000 }, { 145, 0x0088 }, + /* 0x5300 */ + { 147, 0x0400 }, { 148, 0x1000 }, { 149, 0x0000 }, { 149, 0x0000 }, + { 149, 0x0000 }, { 149, 0x0000 }, { 149, 0x0000 }, { 149, 0x0000 }, + { 149, 0x0000 }, { 149, 0x0001 }, { 150, 0x0000 }, { 150, 0x4000 }, + { 151, 0x00c0 }, { 153, 0x0000 }, { 153, 0x0000 }, { 153, 0x0000 }, + /* 0x5400 */ + { 153, 0x0000 }, { 153, 0x0000 }, { 153, 0x0000 }, { 153, 0x0000 }, + { 153, 0x0000 }, { 153, 0x0000 }, { 153, 0x0000 }, { 153, 0x0000 }, + { 153, 0x0000 }, { 153, 0x0000 }, { 153, 0x0020 }, { 154, 0x0000 }, + { 154, 0x0000 }, { 154, 0x0000 }, { 154, 0x0000 }, { 154, 0x0000 }, + /* 0x5500 */ + { 154, 0x0000 }, { 154, 0x2000 }, { 155, 0x0000 }, { 155, 0x0040 }, + { 156, 0x2000 }, { 157, 0x0080 }, { 158, 0x8000 }, { 159, 0x0011 }, + { 161, 0x0040 }, { 162, 0x0000 }, { 162, 0x0010 }, { 163, 0x0000 }, + { 163, 0x0000 }, { 163, 0x0000 }, { 163, 0x0000 }, { 163, 0x0000 }, + /* 0x5600 */ + { 163, 0x0000 }, { 163, 0x0000 }, { 163, 0x0000 }, { 163, 0x0000 }, + { 163, 0x0001 }, { 164, 0x0000 }, { 164, 0x0000 }, { 164, 0x0000 }, + { 164, 0x0010 }, { 165, 0x1400 }, { 167, 0x2000 }, { 168, 0x0000 }, + { 168, 0x0000 }, { 168, 0x0000 }, { 168, 0x0000 }, { 168, 0x0080 }, + /* 0x5700 */ + { 169, 0x0000 }, { 169, 0x0201 }, { 171, 0x0000 }, { 171, 0x0000 }, + { 171, 0x0000 }, { 171, 0x0000 }, { 171, 0x1000 }, { 172, 0x8001 }, + { 174, 0x0080 }, { 175, 0xc420 }, { 179, 0x0000 }, { 179, 0x4002 }, + { 181, 0x1000 }, { 182, 0x0000 }, { 182, 0x0800 }, { 183, 0x0020 }, + /* 0x5800 */ + { 184, 0x5208 }, { 188, 0x0000 }, { 188, 0x0000 }, { 188, 0x3000 }, + { 190, 0x016c }, { 195, 0x2408 }, { 198, 0x0000 }, { 198, 0x0002 }, + { 199, 0x0110 }, { 201, 0x0020 }, { 202, 0x0000 }, { 202, 0x0000 }, + { 202, 0x0000 }, { 202, 0x0000 }, { 202, 0x0000 }, { 202, 0x0100 }, + /* 0x5900 */ + { 203, 0x0040 }, { 204, 0x0001 }, { 205, 0x1000 }, { 206, 0x0000 }, + { 206, 0x0001 }, { 207, 0x0008 }, { 208, 0x2000 }, { 209, 0x0000 }, + { 209, 0x0000 }, { 209, 0x0000 }, { 209, 0x0000 }, { 209, 0x0008 }, + { 210, 0x0000 }, { 210, 0x4000 }, { 211, 0x4000 }, { 212, 0x2000 }, + /* 0x5a00 */ + { 213, 0x0000 }, { 213, 0x0004 }, { 214, 0x0000 }, { 214, 0x0000 }, + { 214, 0x0000 }, { 214, 0x4000 }, { 215, 0x0020 }, { 216, 0x1008 }, + { 218, 0x0010 }, { 219, 0x4040 }, { 221, 0x6000 }, { 223, 0x0000 }, + { 223, 0x0010 }, { 224, 0x0400 }, { 225, 0x0400 }, { 226, 0x0000 }, + /* 0x5b00 */ + { 226, 0x0000 }, { 226, 0x0800 }, { 227, 0x0000 }, { 227, 0x0000 }, + { 227, 0x0008 }, { 228, 0x0040 }, { 229, 0x0000 }, { 229, 0x0000 }, + { 229, 0x0000 }, { 229, 0x0000 }, { 229, 0x1080 }, { 231, 0x0000 }, + { 231, 0x0000 }, { 231, 0x0000 }, { 231, 0x0000 }, { 231, 0x0000 }, + /* 0x5c00 */ + { 231, 0x0020 }, { 232, 0x0000 }, { 232, 0x0400 }, { 233, 0x0001 }, + { 234, 0x0000 }, { 234, 0x2000 }, { 235, 0x0000 }, { 235, 0x1014 }, + { 238, 0x0000 }, { 238, 0x4000 }, { 239, 0x0100 }, { 240, 0x0000 }, + { 240, 0x0088 }, { 242, 0x0008 }, { 243, 0x0088 }, { 245, 0x8002 }, + /* 0x5d00 */ + { 247, 0x1031 }, { 251, 0x8602 }, { 255, 0x0000 }, { 255, 0x0000 }, + { 255, 0x4000 }, { 256, 0x0400 }, { 257, 0x0000 }, { 257, 0x0000 }, + { 257, 0x0020 }, { 258, 0x000c }, { 260, 0x0000 }, { 260, 0x0000 }, + { 260, 0x0204 }, { 262, 0x0040 }, { 263, 0x0000 }, { 263, 0x0000 }, + /* 0x5e00 */ + { 263, 0x0800 }, { 264, 0x0080 }, { 265, 0x0102 }, { 267, 0x0000 }, + { 267, 0x0000 }, { 267, 0x0000 }, { 267, 0x0400 }, { 268, 0x0000 }, + { 268, 0x0000 }, { 268, 0x0000 }, { 268, 0x0010 }, { 269, 0x1000 }, + { 270, 0x0900 }, { 272, 0x0000 }, { 272, 0x0000 }, { 272, 0x0000 }, + /* 0x5f00 */ + { 272, 0x7080 }, { 276, 0x0000 }, { 276, 0x0004 }, { 277, 0x0000 }, + { 277, 0x0000 }, { 277, 0x8000 }, { 278, 0x0180 }, { 280, 0x0000 }, + { 280, 0x0000 }, { 280, 0x0000 }, { 280, 0x9000 }, { 282, 0x0000 }, + { 282, 0x0000 }, { 282, 0x0000 }, { 282, 0x0000 }, { 282, 0x0000 }, + /* 0x6000 */ + { 282, 0x0000 }, { 282, 0x0080 }, { 283, 0x0000 }, { 283, 0x0000 }, + { 283, 0x0000 }, { 283, 0x0000 }, { 283, 0x0000 }, { 283, 0x0000 }, + { 283, 0x0000 }, { 283, 0x0000 }, { 283, 0x4000 }, { 284, 0x0001 }, + { 285, 0x0080 }, { 286, 0x0208 }, { 288, 0x0000 }, { 288, 0x0000 }, + /* 0x6100 */ + { 288, 0x0000 }, { 288, 0x0010 }, { 289, 0x0000 }, { 289, 0x0000 }, + { 289, 0x0000 }, { 289, 0x0008 }, { 290, 0x0020 }, { 291, 0x0000 }, + { 291, 0x0000 }, { 291, 0x0000 }, { 291, 0x0000 }, { 291, 0x0000 }, + { 291, 0x0000 }, { 291, 0x0000 }, { 291, 0x0000 }, { 291, 0x0000 }, + /* 0x6200 */ + { 291, 0x0000 }, { 291, 0x0000 }, { 291, 0x0000 }, { 291, 0x0000 }, + { 291, 0x0460 }, { 294, 0x0000 }, { 294, 0x0003 }, { 296, 0x0000 }, + { 296, 0x0008 }, { 297, 0x0010 }, { 298, 0x0000 }, { 298, 0x0000 }, + { 298, 0x0008 }, { 299, 0x0000 }, { 299, 0x0010 }, { 300, 0x0000 }, + /* 0x6300 */ + { 300, 0x0000 }, { 300, 0x1000 }, { 301, 0x0040 }, { 302, 0x1000 }, + { 303, 0x0000 }, { 303, 0x0000 }, { 303, 0x0000 }, { 303, 0x0000 }, + { 303, 0x0000 }, { 303, 0x0000 }, { 303, 0x8000 }, { 304, 0x0002 }, + { 305, 0x0000 }, { 305, 0x0000 }, { 305, 0x0000 }, { 305, 0x4000 }, + /* 0x6400 */ + { 306, 0x0000 }, { 306, 0x0004 }, { 307, 0x0084 }, { 309, 0x0000 }, + { 309, 0x0000 }, { 309, 0x0000 }, { 309, 0x0000 }, { 309, 0x2080 }, + { 311, 0x0000 }, { 311, 0x0000 }, { 311, 0x0000 }, { 311, 0x0000 }, + { 311, 0x0000 }, { 311, 0x0000 }, { 311, 0x2000 }, { 312, 0x0000 }, + /* 0x6500 */ + { 312, 0x0000 }, { 312, 0x0000 }, { 312, 0x0000 }, { 312, 0x0000 }, + { 312, 0x0000 }, { 312, 0x1000 }, { 313, 0x0200 }, { 314, 0x0000 }, + { 314, 0x8000 }, { 315, 0x2000 }, { 316, 0x0104 }, { 318, 0x0000 }, + { 318, 0x0004 }, { 319, 0x0000 }, { 319, 0x0000 }, { 319, 0x0900 }, + /* 0x6600 */ + { 321, 0x0280 }, { 323, 0x0000 }, { 323, 0x0000 }, { 323, 0x2000 }, + { 324, 0x0000 }, { 324, 0x4000 }, { 325, 0x1084 }, { 328, 0x0008 }, + { 329, 0x6800 }, { 332, 0x0000 }, { 332, 0x0000 }, { 332, 0x0000 }, + { 332, 0x0000 }, { 332, 0x0000 }, { 332, 0x0000 }, { 332, 0x0000 }, + /* 0x6700 */ + { 332, 0x0000 }, { 332, 0x0108 }, { 334, 0x0000 }, { 334, 0x8000 }, + { 335, 0x0020 }, { 336, 0x0000 }, { 336, 0x0080 }, { 337, 0x0800 }, + { 338, 0x0000 }, { 338, 0x8200 }, { 340, 0x0000 }, { 340, 0x0000 }, + { 340, 0x0100 }, { 341, 0x0000 }, { 341, 0x4000 }, { 342, 0x0000 }, + /* 0x6800 */ + { 342, 0x0000 }, { 342, 0x8004 }, { 344, 0x0000 }, { 344, 0x0000 }, + { 344, 0x0800 }, { 345, 0x0000 }, { 345, 0x9400 }, { 348, 0x0000 }, + { 348, 0x0000 }, { 348, 0x0000 }, { 348, 0x0001 }, { 349, 0x9002 }, + { 352, 0x0002 }, { 353, 0x000b }, { 356, 0x1900 }, { 359, 0x0900 }, + /* 0x6900 */ + { 361, 0x0000 }, { 361, 0x200a }, { 364, 0x0800 }, { 365, 0x0020 }, + { 366, 0x0001 }, { 367, 0x8200 }, { 369, 0x8204 }, { 372, 0x0000 }, + { 372, 0x0008 }, { 373, 0x0040 }, { 374, 0x0000 }, { 374, 0x5000 }, + { 376, 0x0020 }, { 377, 0x1400 }, { 379, 0x0020 }, { 380, 0x4000 }, + /* 0x6a00 */ + { 381, 0x0800 }, { 382, 0x0002 }, { 383, 0x0000 }, { 383, 0x0000 }, + { 383, 0x0000 }, { 383, 0x0000 }, { 383, 0x0040 }, { 384, 0x0000 }, + { 384, 0x0000 }, { 384, 0x0040 }, { 385, 0x0000 }, { 385, 0x0030 }, + { 387, 0x0000 }, { 387, 0x0000 }, { 387, 0x0000 }, { 387, 0x0000 }, + /* 0x6b00 */ + { 387, 0x0000 }, { 387, 0x0000 }, { 387, 0x0000 }, { 387, 0x0100 }, + { 388, 0x0000 }, { 388, 0x0010 }, { 389, 0x0000 }, { 389, 0x0000 }, + { 389, 0x0000 }, { 389, 0x0020 }, { 390, 0x0008 }, { 391, 0x0000 }, + { 391, 0x0000 }, { 391, 0x0400 }, { 392, 0x0000 }, { 392, 0x0000 }, + /* 0x6c00 */ + { 392, 0x0000 }, { 392, 0x2000 }, { 393, 0x0020 }, { 394, 0xc000 }, + { 396, 0x0000 }, { 396, 0x0000 }, { 396, 0x2080 }, { 398, 0x0000 }, + { 398, 0x0090 }, { 400, 0x0540 }, { 403, 0x0100 }, { 404, 0x0020 }, + { 405, 0x0048 }, { 407, 0x1000 }, { 408, 0x0000 }, { 408, 0x0000 }, + /* 0x6d00 */ + { 408, 0x0000 }, { 408, 0x0002 }, { 409, 0x0300 }, { 411, 0x0510 }, + { 414, 0x0210 }, { 416, 0x0821 }, { 419, 0x0032 }, { 422, 0x0000 }, + { 422, 0x0000 }, { 422, 0x0000 }, { 422, 0x2004 }, { 424, 0x0010 }, + { 425, 0x0000 }, { 425, 0x0000 }, { 425, 0x0000 }, { 425, 0x0000 }, + /* 0x6e00 */ + { 425, 0x0000 }, { 425, 0x0800 }, { 426, 0x0000 }, { 426, 0x0000 }, + { 426, 0x0000 }, { 426, 0x3000 }, { 428, 0x0080 }, { 429, 0x0004 }, + { 430, 0x4082 }, { 433, 0x0400 }, { 434, 0x0041 }, { 436, 0x0020 }, + { 437, 0x0208 }, { 439, 0x0100 }, { 440, 0x0c80 }, { 443, 0x0000 }, + /* 0x6f00 */ + { 443, 0x0000 }, { 443, 0x0000 }, { 443, 0x0040 }, { 444, 0x0080 }, + { 445, 0x0000 }, { 445, 0x8040 }, { 447, 0x0000 }, { 447, 0x0020 }, + { 448, 0x0004 }, { 449, 0x0810 }, { 451, 0x0020 }, { 452, 0x1010 }, + { 454, 0x0000 }, { 454, 0x0000 }, { 454, 0x1000 }, { 455, 0x0000 }, + /* 0x7000 */ + { 455, 0x3000 }, { 457, 0x0010 }, { 458, 0x0000 }, { 458, 0x1000 }, + { 459, 0x0000 }, { 459, 0x0000 }, { 459, 0x0000 }, { 459, 0x0400 }, + { 460, 0x0000 }, { 460, 0x4100 }, { 462, 0x0000 }, { 462, 0x0000 }, + { 462, 0x0000 }, { 462, 0x3000 }, { 464, 0x0000 }, { 464, 0x0402 }, + /* 0x7100 */ + { 466, 0x1000 }, { 467, 0x1000 }, { 468, 0x4001 }, { 470, 0x0000 }, + { 470, 0x0000 }, { 470, 0x0000 }, { 470, 0x0000 }, { 470, 0x0000 }, + { 470, 0x0000 }, { 470, 0x0000 }, { 470, 0x0000 }, { 470, 0x0000 }, + { 470, 0x8c00 }, { 473, 0x0000 }, { 473, 0x0000 }, { 473, 0x8000 }, + /* 0x7200 */ + { 474, 0x0000 }, { 474, 0x8000 }, { 475, 0x0000 }, { 475, 0x0000 }, + { 475, 0x0006 }, { 477, 0x0400 }, { 478, 0x0008 }, { 479, 0x0080 }, + { 480, 0x0080 }, { 481, 0x0000 }, { 481, 0x0100 }, { 482, 0x0000 }, + { 482, 0x0200 }, { 483, 0x2000 }, { 484, 0x0004 }, { 485, 0x0000 }, + /* 0x7300 */ + { 485, 0x0040 }, { 486, 0x0010 }, { 487, 0x0000 }, { 487, 0x0400 }, + { 488, 0x0000 }, { 488, 0x0000 }, { 488, 0x0000 }, { 488, 0x0000 }, + { 488, 0x0000 }, { 488, 0x0630 }, { 492, 0x0061 }, { 495, 0x0002 }, + { 496, 0x0000 }, { 496, 0x0040 }, { 497, 0x4408 }, { 500, 0x2441 }, + /* 0x7400 */ + { 504, 0x4080 }, { 506, 0x0020 }, { 507, 0x8810 }, { 510, 0x0084 }, + { 512, 0x0014 }, { 514, 0x0010 }, { 515, 0x0004 }, { 516, 0x0102 }, + { 518, 0x0140 }, { 520, 0x8100 }, { 522, 0x0401 }, { 524, 0x0004 }, + { 525, 0x0000 }, { 525, 0x0100 }, { 526, 0x0000 }, { 526, 0x0800 }, + /* 0x7500 */ + { 527, 0x0008 }, { 528, 0x0000 }, { 528, 0x0442 }, { 531, 0x0000 }, + { 531, 0x0000 }, { 531, 0x0002 }, { 532, 0x9010 }, { 535, 0x0000 }, + { 535, 0x0000 }, { 535, 0x0000 }, { 535, 0x0004 }, { 536, 0x0000 }, + { 536, 0x0000 }, { 536, 0x0000 }, { 536, 0x0001 }, { 537, 0x0008 }, + /* 0x7600 */ + { 538, 0x0110 }, { 540, 0x2000 }, { 541, 0x0000 }, { 541, 0x0000 }, + { 541, 0x0000 }, { 541, 0x0004 }, { 542, 0x0000 }, { 542, 0x8040 }, + { 544, 0x0000 }, { 544, 0x4000 }, { 545, 0x0000 }, { 545, 0x0000 }, + { 545, 0x0000 }, { 545, 0x2000 }, { 546, 0x1440 }, { 549, 0x0800 }, + /* 0x7700 */ + { 550, 0x0400 }, { 551, 0x0800 }, { 552, 0x1000 }, { 553, 0x0000 }, + { 553, 0x0000 }, { 553, 0x0000 }, { 553, 0x0000 }, { 553, 0x0000 }, + { 553, 0x0840 }, { 555, 0x0000 }, { 555, 0x2800 }, { 557, 0x0000 }, + { 557, 0x0000 }, { 557, 0x4000 }, { 558, 0x0000 }, { 558, 0x1800 }, + /* 0x7800 */ + { 560, 0x0040 }, { 561, 0x0000 }, { 561, 0x0005 }, { 563, 0x0000 }, + { 563, 0x0002 }, { 564, 0x0600 }, { 566, 0x0000 }, { 566, 0x0020 }, + { 567, 0x0000 }, { 567, 0x0010 }, { 568, 0x0000 }, { 568, 0x0040 }, + { 569, 0x0000 }, { 569, 0x1000 }, { 570, 0x0002 }, { 571, 0x0000 }, + /* 0x7900 */ + { 571, 0x0008 }, { 572, 0x0000 }, { 572, 0x0000 }, { 572, 0x2008 }, + { 574, 0x4488 }, { 578, 0x0001 }, { 579, 0x0000 }, { 579, 0x1004 }, + { 581, 0x0000 }, { 581, 0x0100 }, { 582, 0x0011 }, { 584, 0x0100 }, + { 585, 0x0000 }, { 585, 0x0000 }, { 585, 0x0000 }, { 585, 0x4000 }, + /* 0x7a00 */ + { 586, 0x0000 }, { 586, 0x0040 }, { 587, 0x0000 }, { 587, 0x0000 }, + { 587, 0x0010 }, { 588, 0x4000 }, { 589, 0x0000 }, { 589, 0x0000 }, + { 589, 0x4020 }, { 591, 0x0000 }, { 591, 0x0008 }, { 592, 0x4100 }, + { 594, 0x0000 }, { 594, 0x1002 }, { 596, 0x0000 }, { 596, 0x0000 }, + /* 0x7b00 */ + { 596, 0x0000 }, { 596, 0x0000 }, { 596, 0x0000 }, { 596, 0x0000 }, + { 596, 0x4400 }, { 598, 0x1000 }, { 599, 0x0000 }, { 599, 0x8000 }, + { 600, 0x0080 }, { 601, 0x0008 }, { 602, 0x0000 }, { 602, 0x0000 }, + { 602, 0x0000 }, { 602, 0x0000 }, { 602, 0x8000 }, { 603, 0x0005 }, + /* 0x7c00 */ + { 605, 0x0208 }, { 607, 0x0020 }, { 608, 0x0001 }, { 609, 0x0001 }, + { 610, 0x0000 }, { 610, 0x2001 }, { 612, 0x0000 }, { 612, 0x0000 }, + { 612, 0x0000 }, { 612, 0x0000 }, { 612, 0x1040 }, { 614, 0x0000 }, + { 614, 0x0000 }, { 614, 0x0000 }, { 614, 0x0000 }, { 614, 0x0020 }, +}; +static const Summary16 isoir165ext_uni2indx_page7e[333] = { + /* 0x7e00 */ + { 615, 0x0000 }, { 615, 0x0000 }, { 615, 0x0000 }, { 615, 0x0000 }, + { 615, 0x0010 }, { 616, 0x0000 }, { 616, 0x0000 }, { 616, 0x0000 }, + { 616, 0x0000 }, { 616, 0x0000 }, { 616, 0x4000 }, { 617, 0x1810 }, + { 620, 0x0000 }, { 620, 0x0040 }, { 621, 0x1010 }, { 623, 0x0200 }, + /* 0x7f00 */ + { 624, 0x0400 }, { 625, 0x4001 }, { 627, 0x0000 }, { 627, 0x0000 }, + { 627, 0x2000 }, { 628, 0x0000 }, { 628, 0x0000 }, { 628, 0x2000 }, + { 629, 0x0000 }, { 629, 0x0002 }, { 630, 0x0000 }, { 630, 0x0000 }, + { 630, 0x0001 }, { 631, 0x0600 }, { 633, 0x8000 }, { 634, 0x0000 }, + /* 0x8000 */ + { 634, 0x0000 }, { 634, 0x0000 }, { 634, 0x0000 }, { 634, 0x0001 }, + { 635, 0x0000 }, { 635, 0x0000 }, { 635, 0x0000 }, { 635, 0x0000 }, + { 635, 0x0000 }, { 635, 0x0000 }, { 635, 0x0000 }, { 635, 0x0000 }, + { 635, 0x0000 }, { 635, 0x0010 }, { 636, 0x0000 }, { 636, 0x4000 }, + /* 0x8100 */ + { 637, 0x0000 }, { 637, 0x0000 }, { 637, 0x0200 }, { 638, 0x8000 }, + { 639, 0x0000 }, { 639, 0x0104 }, { 641, 0x0000 }, { 641, 0x0000 }, + { 641, 0x0000 }, { 641, 0x0000 }, { 641, 0x0000 }, { 641, 0x0000 }, + { 641, 0x0000 }, { 641, 0x0002 }, { 642, 0x0000 }, { 642, 0x0000 }, + /* 0x8200 */ + { 642, 0x0000 }, { 642, 0x0140 }, { 644, 0x0000 }, { 644, 0x0400 }, + { 645, 0x0000 }, { 645, 0x0000 }, { 645, 0x0000 }, { 645, 0x0100 }, + { 646, 0x0008 }, { 647, 0x0000 }, { 647, 0x0080 }, { 648, 0x1000 }, + { 649, 0x0000 }, { 649, 0x0000 }, { 649, 0x0000 }, { 649, 0x4000 }, + /* 0x8300 */ + { 650, 0x0001 }, { 651, 0x2008 }, { 653, 0x0000 }, { 653, 0x0000 }, + { 653, 0x0030 }, { 655, 0x2000 }, { 656, 0x0000 }, { 656, 0x0000 }, + { 656, 0x0000 }, { 656, 0x0200 }, { 657, 0x0040 }, { 658, 0x0000 }, + { 658, 0x0000 }, { 658, 0x0002 }, { 659, 0x0000 }, { 659, 0x5000 }, + /* 0x8400 */ + { 661, 0x0000 }, { 661, 0x0400 }, { 662, 0x0200 }, { 663, 0x0200 }, + { 664, 0x0000 }, { 664, 0x0008 }, { 665, 0x0001 }, { 666, 0x0000 }, + { 666, 0x0000 }, { 666, 0xc000 }, { 668, 0x0100 }, { 669, 0x0000 }, + { 669, 0x8044 }, { 672, 0x0000 }, { 672, 0x0400 }, { 673, 0x0080 }, + /* 0x8500 */ + { 674, 0x0000 }, { 674, 0x0000 }, { 674, 0x0000 }, { 674, 0x0010 }, + { 675, 0x0000 }, { 675, 0x0000 }, { 675, 0x0000 }, { 675, 0x0001 }, + { 676, 0x0000 }, { 676, 0x0000 }, { 676, 0x0004 }, { 677, 0x0108 }, + { 679, 0x0000 }, { 679, 0x0000 }, { 679, 0x0001 }, { 680, 0x0000 }, + /* 0x8600 */ + { 680, 0x0000 }, { 680, 0x0000 }, { 680, 0x0000 }, { 680, 0x0000 }, + { 680, 0x0000 }, { 680, 0x0004 }, { 681, 0x0000 }, { 681, 0x0000 }, + { 681, 0x0008 }, { 682, 0x0000 }, { 682, 0x0000 }, { 682, 0x0000 }, + { 682, 0x0000 }, { 682, 0x0000 }, { 682, 0x0000 }, { 682, 0x0000 }, + /* 0x8700 */ + { 682, 0x4020 }, { 684, 0x0000 }, { 684, 0x0000 }, { 684, 0x0000 }, + { 684, 0x0000 }, { 684, 0x0100 }, { 685, 0x0000 }, { 685, 0x0000 }, + { 685, 0x0001 }, { 686, 0x0000 }, { 686, 0x0008 }, { 687, 0x0000 }, + { 687, 0x8000 }, { 688, 0x0000 }, { 688, 0x0004 }, { 689, 0x0000 }, + /* 0x8800 */ + { 689, 0x0800 }, { 690, 0x0000 }, { 690, 0x2000 }, { 691, 0x0000 }, + { 691, 0x0000 }, { 691, 0x0004 }, { 692, 0x0000 }, { 692, 0x0000 }, + { 692, 0x0040 }, { 693, 0x0080 }, { 694, 0x8400 }, { 696, 0x0000 }, + { 696, 0x0101 }, { 698, 0x0000 }, { 698, 0x0000 }, { 698, 0x0000 }, + /* 0x8900 */ + { 698, 0x0000 }, { 698, 0x0000 }, { 698, 0x0040 }, { 699, 0x0000 }, + { 699, 0x0000 }, { 699, 0x0020 }, { 700, 0x0000 }, { 700, 0x0040 }, + { 701, 0x0001 }, { 702, 0x0000 }, { 702, 0x0000 }, { 702, 0x0000 }, + { 702, 0x2008 }, { 704, 0x0010 }, { 705, 0x0000 }, { 705, 0x0002 }, + /* 0x8a00 */ + { 706, 0x0000 }, { 706, 0x0400 }, { 707, 0x0000 }, { 707, 0x0000 }, + { 707, 0x0000 }, { 707, 0x8000 }, { 708, 0x0000 }, { 708, 0x0000 }, + { 708, 0x0000 }, { 708, 0x0000 }, { 708, 0x0000 }, { 708, 0x0000 }, + { 708, 0x0000 }, { 708, 0x0000 }, { 708, 0x0000 }, { 708, 0x0000 }, + /* 0x8b00 */ + { 708, 0x0000 }, { 708, 0x0000 }, { 708, 0x0000 }, { 708, 0x0000 }, + { 708, 0x0000 }, { 708, 0x0000 }, { 708, 0x0000 }, { 708, 0x0000 }, + { 708, 0x0000 }, { 708, 0x0000 }, { 708, 0x1000 }, { 709, 0x0802 }, + { 711, 0x0080 }, { 712, 0x0000 }, { 712, 0x0400 }, { 713, 0x0000 }, + /* 0x8c00 */ + { 713, 0x0200 }, { 714, 0x4000 }, { 715, 0x0000 }, { 715, 0x0000 }, + { 715, 0x0000 }, { 715, 0x0000 }, { 715, 0x6100 }, { 718, 0x0000 }, + { 718, 0x0040 }, { 719, 0x0000 }, { 719, 0x0000 }, { 719, 0x0000 }, + { 719, 0x0000 }, { 719, 0x0000 }, { 719, 0x0000 }, { 719, 0x0000 }, + /* 0x8d00 */ + { 719, 0x0000 }, { 719, 0x0000 }, { 719, 0x0001 }, { 720, 0x0000 }, + { 720, 0x0000 }, { 720, 0x8086 }, { 724, 0x0400 }, { 725, 0x0000 }, + { 725, 0x0000 }, { 725, 0x0000 }, { 725, 0x0000 }, { 725, 0x0000 }, + { 725, 0x0000 }, { 725, 0x0000 }, { 725, 0x0000 }, { 725, 0x0000 }, + /* 0x8e00 */ + { 725, 0x0000 }, { 725, 0x0040 }, { 726, 0x00c2 }, { 729, 0x0040 }, + { 730, 0x0020 }, { 731, 0x1009 }, { 734, 0x0004 }, { 735, 0x0000 }, + { 735, 0x0000 }, { 735, 0x0000 }, { 735, 0x2000 }, { 736, 0x0000 }, + { 736, 0x0000 }, { 736, 0x0000 }, { 736, 0x0000 }, { 736, 0x0000 }, + /* 0x8f00 */ + { 736, 0x0000 }, { 736, 0x0000 }, { 736, 0x0000 }, { 736, 0x0000 }, + { 736, 0x0000 }, { 736, 0x0000 }, { 736, 0x0000 }, { 736, 0x0000 }, + { 736, 0x0001 }, { 737, 0x0004 }, { 738, 0x0000 }, { 738, 0x0020 }, + { 739, 0x0000 }, { 739, 0x0000 }, { 739, 0x0000 }, { 739, 0x0400 }, + /* 0x9000 */ + { 740, 0x0000 }, { 740, 0x0000 }, { 740, 0x0000 }, { 740, 0x0000 }, + { 740, 0x0000 }, { 740, 0x0000 }, { 740, 0x0000 }, { 740, 0x0000 }, + { 740, 0x0000 }, { 740, 0x0100 }, { 741, 0x0101 }, { 743, 0x2000 }, + { 744, 0x0108 }, { 746, 0x0400 }, { 747, 0x0010 }, { 748, 0x8000 }, + /* 0x9100 */ + { 749, 0x1000 }, { 750, 0x1500 }, { 753, 0x0001 }, { 754, 0x0000 }, + { 754, 0x0004 }, { 755, 0x0000 }, { 755, 0x0000 }, { 755, 0x0000 }, + { 755, 0x0000 }, { 755, 0x0000 }, { 755, 0x0000 }, { 755, 0x0000 }, + { 755, 0x0040 }, { 756, 0x0000 }, { 756, 0x0000 }, { 756, 0x0000 }, + /* 0x9200 */ + { 756, 0x0000 }, { 756, 0x0000 }, { 756, 0x0000 }, { 756, 0x0000 }, + { 756, 0x0000 }, { 756, 0x0000 }, { 756, 0x0000 }, { 756, 0x0000 }, + { 756, 0x0000 }, { 756, 0x0000 }, { 756, 0x0000 }, { 756, 0x0000 }, + { 756, 0x0040 }, +}; +static const Summary16 isoir165ext_uni2indx_page94[143] = { + /* 0x9400 */ + { 757, 0x0000 }, { 757, 0x0000 }, { 757, 0x0000 }, { 757, 0x0000 }, + { 757, 0x0000 }, { 757, 0x0000 }, { 757, 0x0000 }, { 757, 0x0000 }, + { 757, 0x0000 }, { 757, 0x0142 }, { 760, 0x0000 }, { 760, 0x0000 }, + { 760, 0x8080 }, { 762, 0x0418 }, { 765, 0x0040 }, { 766, 0x0800 }, + /* 0x9500 */ + { 767, 0x0000 }, { 767, 0x1000 }, { 768, 0x0081 }, { 770, 0x2008 }, + { 772, 0x0008 }, { 773, 0x0400 }, { 774, 0x4001 }, { 776, 0x0030 }, + { 778, 0x0000 }, { 778, 0x0000 }, { 778, 0x0000 }, { 778, 0x0000 }, + { 778, 0x0000 }, { 778, 0x0000 }, { 778, 0x1000 }, { 779, 0x8000 }, + /* 0x9600 */ + { 780, 0x0080 }, { 781, 0x0908 }, { 784, 0x0000 }, { 784, 0x0000 }, + { 784, 0x0000 }, { 784, 0x4000 }, { 785, 0x0000 }, { 785, 0x0000 }, + { 785, 0x0000 }, { 785, 0x0000 }, { 785, 0x0000 }, { 785, 0x0000 }, + { 785, 0x0000 }, { 785, 0x0100 }, { 786, 0x0000 }, { 786, 0x0000 }, + /* 0x9700 */ + { 786, 0x0004 }, { 787, 0x0000 }, { 787, 0x0000 }, { 787, 0x0000 }, + { 787, 0x0000 }, { 787, 0x0010 }, { 788, 0x0000 }, { 788, 0x0501 }, + { 791, 0x0000 }, { 791, 0x0000 }, { 791, 0x4102 }, { 794, 0x0000 }, + { 794, 0x0000 }, { 794, 0x0000 }, { 794, 0x0100 }, { 795, 0x0000 }, + /* 0x9800 */ + { 795, 0x0000 }, { 795, 0x0000 }, { 795, 0x0000 }, { 795, 0x0000 }, + { 795, 0x0000 }, { 795, 0x0000 }, { 795, 0x0000 }, { 795, 0x0000 }, + { 795, 0x4800 }, { 797, 0x0224 }, { 800, 0x0008 }, { 801, 0x0000 }, + { 801, 0x8000 }, { 802, 0x00d1 }, { 806, 0x0000 }, { 806, 0x0000 }, + /* 0x9900 */ + { 806, 0x0000 }, { 806, 0x0000 }, { 806, 0x0000 }, { 806, 0x0000 }, + { 806, 0x0000 }, { 806, 0x0000 }, { 806, 0x0050 }, { 808, 0x4b00 }, + { 812, 0x500c }, { 816, 0x0000 }, { 816, 0x0000 }, { 816, 0x0000 }, + { 816, 0x0000 }, { 816, 0x0000 }, { 816, 0x0000 }, { 816, 0x0000 }, + /* 0x9a00 */ + { 816, 0x0000 }, { 816, 0x0000 }, { 816, 0x0000 }, { 816, 0x0000 }, + { 816, 0x0000 }, { 816, 0x0000 }, { 816, 0x0000 }, { 816, 0x0004 }, + { 817, 0x6208 }, { 821, 0x0230 }, { 824, 0x0040 }, { 825, 0x0000 }, + { 825, 0x0000 }, { 825, 0x0000 }, { 825, 0x0000 }, { 825, 0x0000 }, + /* 0x9b00 */ + { 825, 0x0000 }, { 825, 0x0101 }, { 827, 0x0020 }, { 828, 0x0040 }, + { 829, 0x0040 }, { 830, 0x0000 }, { 830, 0x0000 }, { 830, 0x0000 }, + { 830, 0x0000 }, { 830, 0x0000 }, { 830, 0x0000 }, { 830, 0x0000 }, + { 830, 0x0000 }, { 830, 0x0000 }, { 830, 0x0000 }, { 830, 0x0000 }, + /* 0x9c00 */ + { 830, 0x0000 }, { 830, 0x0000 }, { 830, 0x0000 }, { 830, 0x0000 }, + { 830, 0x0000 }, { 830, 0x0000 }, { 830, 0x0000 }, { 830, 0x0000 }, + { 830, 0x0411 }, { 833, 0x23c8 }, { 839, 0x0000 }, { 839, 0x8000 }, + { 840, 0x0003 }, { 842, 0x0804 }, { 844, 0x0009 }, +}; +static const Summary16 isoir165ext_uni2indx_page9e[25] = { + /* 0x9e00 */ + { 846, 0x0000 }, { 846, 0x0000 }, { 846, 0x4090 }, { 849, 0x0011 }, + { 851, 0x2001 }, { 853, 0x225d }, { 860, 0x8027 }, { 865, 0x0010 }, + { 866, 0x0001 }, { 867, 0x0002 }, { 868, 0x0000 }, { 868, 0x0000 }, + { 868, 0x0000 }, { 868, 0x0000 }, { 868, 0x0002 }, { 869, 0x0000 }, + /* 0x9f00 */ + { 869, 0x1000 }, { 870, 0x0004 }, { 871, 0x0800 }, { 872, 0x0000 }, + { 872, 0x0002 }, { 873, 0x0000 }, { 873, 0x0000 }, { 873, 0x0000 }, + { 873, 0x0006 }, +}; +static const Summary16 isoir165ext_uni2indx_pageff[5] = { + /* 0xff00 */ + { 875, 0x0000 }, { 875, 0x0000 }, { 875, 0x0000 }, { 875, 0x0000 }, + { 875, 0x0080 }, +}; + +static int +isoir165ext_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc >= 0x0000 && wc < 0x0200) + summary = &isoir165ext_uni2indx_page00[(wc>>4)]; + else if (wc >= 0x0300 && wc < 0x03c0) + summary = &isoir165ext_uni2indx_page03[(wc>>4)-0x030]; + else if (wc >= 0x1e00 && wc < 0x1fc0) + summary = &isoir165ext_uni2indx_page1e[(wc>>4)-0x1e0]; + else if (wc >= 0x3000 && wc < 0x3040) + summary = &isoir165ext_uni2indx_page30[(wc>>4)-0x300]; + else if (wc >= 0x3200 && wc < 0x3400) + summary = &isoir165ext_uni2indx_page32[(wc>>4)-0x320]; + else if (wc >= 0x4e00 && wc < 0x7d00) + summary = &isoir165ext_uni2indx_page4e[(wc>>4)-0x4e0]; + else if (wc >= 0x7e00 && wc < 0x92d0) + summary = &isoir165ext_uni2indx_page7e[(wc>>4)-0x7e0]; + else if (wc >= 0x9400 && wc < 0x9cf0) + summary = &isoir165ext_uni2indx_page94[(wc>>4)-0x940]; + else if (wc >= 0x9e00 && wc < 0x9f90) + summary = &isoir165ext_uni2indx_page9e[(wc>>4)-0x9e0]; + else if (wc >= 0xff00 && wc < 0xff50) + summary = &isoir165ext_uni2indx_pageff[(wc>>4)-0xff0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = isoir165ext_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/java.h b/libs/libiconv/lib/java.h new file mode 100644 index 00000000..4d4485f5 --- /dev/null +++ b/libs/libiconv/lib/java.h @@ -0,0 +1,137 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * JAVA + * This is ISO 8859-1 with \uXXXX escape sequences, denoting Unicode BMP + * characters. Consecutive pairs of \uXXXX escape sequences in the surrogate + * range, as in UTF-16, denote Unicode characters outside the BMP. + */ + +static int +java_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c; + ucs4_t wc, wc2; + int i; + + c = s[0]; + if (c != '\\') { + *pwc = c; + return 1; + } + if (n < 2) + return RET_TOOFEW(0); + if (s[1] != 'u') + goto simply_backslash; + wc = 0; + for (i = 2; i < 6; i++) { + if (n <= i) + return RET_TOOFEW(0); + c = s[i]; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A'-10; + else if (c >= 'a' && c <= 'z') + c -= 'a'-10; + else + goto simply_backslash; + wc |= (ucs4_t) c << (4 * (5-i)); + } + if (!(wc >= 0xd800 && wc < 0xe000)) { + *pwc = wc; + return 6; + } + if (wc >= 0xdc00) + goto simply_backslash; + if (n < 7) + return RET_TOOFEW(0); + if (s[6] != '\\') + goto simply_backslash; + if (n < 8) + return RET_TOOFEW(0); + if (s[7] != 'u') + goto simply_backslash; + wc2 = 0; + for (i = 8; i < 12; i++) { + if (n <= i) + return RET_TOOFEW(0); + c = s[i]; + if (c >= '0' && c <= '9') + c -= '0'; + else if (c >= 'A' && c <= 'Z') + c -= 'A'-10; + else if (c >= 'a' && c <= 'z') + c -= 'a'-10; + else + goto simply_backslash; + wc2 |= (ucs4_t) c << (4 * (11-i)); + } + if (!(wc2 >= 0xdc00 && wc2 < 0xe000)) + goto simply_backslash; + *pwc = 0x10000 + ((wc - 0xd800) << 10) + (wc2 - 0xdc00); + return 12; +simply_backslash: + *pwc = '\\'; + return 1; +} + +static int +java_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x80) { + *r = wc; + return 1; + } else if (wc < 0x10000) { + if (n >= 6) { + unsigned int i; + r[0] = '\\'; + r[1] = 'u'; + i = (wc >> 12) & 0x0f; r[2] = (i < 10 ? '0'+i : 'a'-10+i); + i = (wc >> 8) & 0x0f; r[3] = (i < 10 ? '0'+i : 'a'-10+i); + i = (wc >> 4) & 0x0f; r[4] = (i < 10 ? '0'+i : 'a'-10+i); + i = wc & 0x0f; r[5] = (i < 10 ? '0'+i : 'a'-10+i); + return 6; + } else + return RET_TOOSMALL; + } else if (wc < 0x110000) { + if (n >= 12) { + ucs4_t wc1 = 0xd800 + ((wc - 0x10000) >> 10); + ucs4_t wc2 = 0xdc00 + ((wc - 0x10000) & 0x3ff); + unsigned int i; + r[0] = '\\'; + r[1] = 'u'; + i = (wc1 >> 12) & 0x0f; r[2] = (i < 10 ? '0'+i : 'a'-10+i); + i = (wc1 >> 8) & 0x0f; r[3] = (i < 10 ? '0'+i : 'a'-10+i); + i = (wc1 >> 4) & 0x0f; r[4] = (i < 10 ? '0'+i : 'a'-10+i); + i = wc1 & 0x0f; r[5] = (i < 10 ? '0'+i : 'a'-10+i); + r[6] = '\\'; + r[7] = 'u'; + i = (wc2 >> 12) & 0x0f; r[8] = (i < 10 ? '0'+i : 'a'-10+i); + i = (wc2 >> 8) & 0x0f; r[9] = (i < 10 ? '0'+i : 'a'-10+i); + i = (wc2 >> 4) & 0x0f; r[10] = (i < 10 ? '0'+i : 'a'-10+i); + i = wc2 & 0x0f; r[11] = (i < 10 ? '0'+i : 'a'-10+i); + return 12; + } else + return RET_TOOSMALL; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/jisx0201.h b/libs/libiconv/lib/jisx0201.h new file mode 100644 index 00000000..d58c1d59 --- /dev/null +++ b/libs/libiconv/lib/jisx0201.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * JISX0201.1976-0 + */ + +static int +jisx0201_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + if (c == 0x5c) + *pwc = (ucs4_t) 0x00a5; + else if (c == 0x7e) + *pwc = (ucs4_t) 0x203e; + else + *pwc = (ucs4_t) c; + return 1; + } else { + if (c >= 0xa1 && c < 0xe0) { + *pwc = (ucs4_t) c + 0xfec0; + return 1; + } + } + return RET_ILSEQ; +} + +static int +jisx0201_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x0080 && !(wc == 0x005c || wc == 0x007e)) { + *r = wc; + return 1; + } + if (wc == 0x00a5) { + *r = 0x5c; + return 1; + } + if (wc == 0x203e) { + *r = 0x7e; + return 1; + } + if (wc >= 0xff61 && wc < 0xffa0) { + *r = wc - 0xfec0; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/jisx0208.h b/libs/libiconv/lib/jisx0208.h new file mode 100644 index 00000000..755b8ba6 --- /dev/null +++ b/libs/libiconv/lib/jisx0208.h @@ -0,0 +1,2415 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * JISX0208.1990-0 + */ + +static const unsigned short jisx0208_2uni_page21[690] = { + /* 0x21 */ + 0x3000, 0x3001, 0x3002, 0xff0c, 0xff0e, 0x30fb, 0xff1a, 0xff1b, + 0xff1f, 0xff01, 0x309b, 0x309c, 0x00b4, 0xff40, 0x00a8, 0xff3e, + 0xffe3, 0xff3f, 0x30fd, 0x30fe, 0x309d, 0x309e, 0x3003, 0x4edd, + 0x3005, 0x3006, 0x3007, 0x30fc, 0x2015, 0x2010, 0xff0f, 0xff3c, + 0x301c, 0x2016, 0xff5c, 0x2026, 0x2025, 0x2018, 0x2019, 0x201c, + 0x201d, 0xff08, 0xff09, 0x3014, 0x3015, 0xff3b, 0xff3d, 0xff5b, + 0xff5d, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c, 0x300d, 0x300e, + 0x300f, 0x3010, 0x3011, 0xff0b, 0x2212, 0x00b1, 0x00d7, 0x00f7, + 0xff1d, 0x2260, 0xff1c, 0xff1e, 0x2266, 0x2267, 0x221e, 0x2234, + 0x2642, 0x2640, 0x00b0, 0x2032, 0x2033, 0x2103, 0xffe5, 0xff04, + 0x00a2, 0x00a3, 0xff05, 0xff03, 0xff06, 0xff0a, 0xff20, 0x00a7, + 0x2606, 0x2605, 0x25cb, 0x25cf, 0x25ce, 0x25c7, + /* 0x22 */ + 0x25c6, 0x25a1, 0x25a0, 0x25b3, 0x25b2, 0x25bd, 0x25bc, 0x203b, + 0x3012, 0x2192, 0x2190, 0x2191, 0x2193, 0x3013, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x2208, 0x220b, 0x2286, 0x2287, 0x2282, 0x2283, 0x222a, + 0x2229, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x2227, 0x2228, 0x00ac, 0x21d2, 0x21d4, 0x2200, 0x2203, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0x2220, 0x22a5, 0x2312, 0x2202, 0x2207, + 0x2261, 0x2252, 0x226a, 0x226b, 0x221a, 0x223d, 0x221d, 0x2235, + 0x222b, 0x222c, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x212b, 0x2030, 0x266f, 0x266d, 0x266a, 0x2020, 0x2021, + 0x00b6, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x25ef, + /* 0x23 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xff10, + 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18, + 0xff19, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, + 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, + 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, + 0xff39, 0xff3a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, + 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, + 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, 0xff58, + 0xff59, 0xff5a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x24 */ + 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, + 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, 0x3050, + 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, + 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, 0x3060, + 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, + 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3070, + 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, + 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x307f, 0x3080, + 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, + 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, 0x308e, 0x308f, 0x3090, + 0x3091, 0x3092, 0x3093, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x25 */ + 0x30a1, 0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, 0x30a8, + 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0, + 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8, + 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0, + 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7, 0x30c8, + 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d0, + 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7, 0x30d8, + 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, 0x30e0, + 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7, 0x30e8, + 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef, 0x30f0, + 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x26 */ + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, + 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, + 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, + 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x27 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, + 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, + 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, + 0x042f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, + 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, + 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, + 0x044f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x28 */ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2518, 0x2514, 0x251c, 0x252c, + 0x2524, 0x2534, 0x253c, 0x2501, 0x2503, 0x250f, 0x2513, 0x251b, + 0x2517, 0x2523, 0x2533, 0x252b, 0x253b, 0x254b, 0x2520, 0x252f, + 0x2528, 0x2537, 0x253f, 0x251d, 0x2530, 0x2525, 0x2538, 0x2542, +}; +static const unsigned short jisx0208_2uni_page30[6398] = { + /* 0x30 */ + 0x4e9c, 0x5516, 0x5a03, 0x963f, 0x54c0, 0x611b, 0x6328, 0x59f6, + 0x9022, 0x8475, 0x831c, 0x7a50, 0x60aa, 0x63e1, 0x6e25, 0x65ed, + 0x8466, 0x82a6, 0x9bf5, 0x6893, 0x5727, 0x65a1, 0x6271, 0x5b9b, + 0x59d0, 0x867b, 0x98f4, 0x7d62, 0x7dbe, 0x9b8e, 0x6216, 0x7c9f, + 0x88b7, 0x5b89, 0x5eb5, 0x6309, 0x6697, 0x6848, 0x95c7, 0x978d, + 0x674f, 0x4ee5, 0x4f0a, 0x4f4d, 0x4f9d, 0x5049, 0x56f2, 0x5937, + 0x59d4, 0x5a01, 0x5c09, 0x60df, 0x610f, 0x6170, 0x6613, 0x6905, + 0x70ba, 0x754f, 0x7570, 0x79fb, 0x7dad, 0x7def, 0x80c3, 0x840e, + 0x8863, 0x8b02, 0x9055, 0x907a, 0x533b, 0x4e95, 0x4ea5, 0x57df, + 0x80b2, 0x90c1, 0x78ef, 0x4e00, 0x58f1, 0x6ea2, 0x9038, 0x7a32, + 0x8328, 0x828b, 0x9c2f, 0x5141, 0x5370, 0x54bd, 0x54e1, 0x56e0, + 0x59fb, 0x5f15, 0x98f2, 0x6deb, 0x80e4, 0x852d, + /* 0x31 */ + 0x9662, 0x9670, 0x96a0, 0x97fb, 0x540b, 0x53f3, 0x5b87, 0x70cf, + 0x7fbd, 0x8fc2, 0x96e8, 0x536f, 0x9d5c, 0x7aba, 0x4e11, 0x7893, + 0x81fc, 0x6e26, 0x5618, 0x5504, 0x6b1d, 0x851a, 0x9c3b, 0x59e5, + 0x53a9, 0x6d66, 0x74dc, 0x958f, 0x5642, 0x4e91, 0x904b, 0x96f2, + 0x834f, 0x990c, 0x53e1, 0x55b6, 0x5b30, 0x5f71, 0x6620, 0x66f3, + 0x6804, 0x6c38, 0x6cf3, 0x6d29, 0x745b, 0x76c8, 0x7a4e, 0x9834, + 0x82f1, 0x885b, 0x8a60, 0x92ed, 0x6db2, 0x75ab, 0x76ca, 0x99c5, + 0x60a6, 0x8b01, 0x8d8a, 0x95b2, 0x698e, 0x53ad, 0x5186, 0x5712, + 0x5830, 0x5944, 0x5bb4, 0x5ef6, 0x6028, 0x63a9, 0x63f4, 0x6cbf, + 0x6f14, 0x708e, 0x7114, 0x7159, 0x71d5, 0x733f, 0x7e01, 0x8276, + 0x82d1, 0x8597, 0x9060, 0x925b, 0x9d1b, 0x5869, 0x65bc, 0x6c5a, + 0x7525, 0x51f9, 0x592e, 0x5965, 0x5f80, 0x5fdc, + /* 0x32 */ + 0x62bc, 0x65fa, 0x6a2a, 0x6b27, 0x6bb4, 0x738b, 0x7fc1, 0x8956, + 0x9d2c, 0x9d0e, 0x9ec4, 0x5ca1, 0x6c96, 0x837b, 0x5104, 0x5c4b, + 0x61b6, 0x81c6, 0x6876, 0x7261, 0x4e59, 0x4ffa, 0x5378, 0x6069, + 0x6e29, 0x7a4f, 0x97f3, 0x4e0b, 0x5316, 0x4eee, 0x4f55, 0x4f3d, + 0x4fa1, 0x4f73, 0x52a0, 0x53ef, 0x5609, 0x590f, 0x5ac1, 0x5bb6, + 0x5be1, 0x79d1, 0x6687, 0x679c, 0x67b6, 0x6b4c, 0x6cb3, 0x706b, + 0x73c2, 0x798d, 0x79be, 0x7a3c, 0x7b87, 0x82b1, 0x82db, 0x8304, + 0x8377, 0x83ef, 0x83d3, 0x8766, 0x8ab2, 0x5629, 0x8ca8, 0x8fe6, + 0x904e, 0x971e, 0x868a, 0x4fc4, 0x5ce8, 0x6211, 0x7259, 0x753b, + 0x81e5, 0x82bd, 0x86fe, 0x8cc0, 0x96c5, 0x9913, 0x99d5, 0x4ecb, + 0x4f1a, 0x89e3, 0x56de, 0x584a, 0x58ca, 0x5efb, 0x5feb, 0x602a, + 0x6094, 0x6062, 0x61d0, 0x6212, 0x62d0, 0x6539, + /* 0x33 */ + 0x9b41, 0x6666, 0x68b0, 0x6d77, 0x7070, 0x754c, 0x7686, 0x7d75, + 0x82a5, 0x87f9, 0x958b, 0x968e, 0x8c9d, 0x51f1, 0x52be, 0x5916, + 0x54b3, 0x5bb3, 0x5d16, 0x6168, 0x6982, 0x6daf, 0x788d, 0x84cb, + 0x8857, 0x8a72, 0x93a7, 0x9ab8, 0x6d6c, 0x99a8, 0x86d9, 0x57a3, + 0x67ff, 0x86ce, 0x920e, 0x5283, 0x5687, 0x5404, 0x5ed3, 0x62e1, + 0x64b9, 0x683c, 0x6838, 0x6bbb, 0x7372, 0x78ba, 0x7a6b, 0x899a, + 0x89d2, 0x8d6b, 0x8f03, 0x90ed, 0x95a3, 0x9694, 0x9769, 0x5b66, + 0x5cb3, 0x697d, 0x984d, 0x984e, 0x639b, 0x7b20, 0x6a2b, 0x6a7f, + 0x68b6, 0x9c0d, 0x6f5f, 0x5272, 0x559d, 0x6070, 0x62ec, 0x6d3b, + 0x6e07, 0x6ed1, 0x845b, 0x8910, 0x8f44, 0x4e14, 0x9c39, 0x53f6, + 0x691b, 0x6a3a, 0x9784, 0x682a, 0x515c, 0x7ac3, 0x84b2, 0x91dc, + 0x938c, 0x565b, 0x9d28, 0x6822, 0x8305, 0x8431, + /* 0x34 */ + 0x7ca5, 0x5208, 0x82c5, 0x74e6, 0x4e7e, 0x4f83, 0x51a0, 0x5bd2, + 0x520a, 0x52d8, 0x52e7, 0x5dfb, 0x559a, 0x582a, 0x59e6, 0x5b8c, + 0x5b98, 0x5bdb, 0x5e72, 0x5e79, 0x60a3, 0x611f, 0x6163, 0x61be, + 0x63db, 0x6562, 0x67d1, 0x6853, 0x68fa, 0x6b3e, 0x6b53, 0x6c57, + 0x6f22, 0x6f97, 0x6f45, 0x74b0, 0x7518, 0x76e3, 0x770b, 0x7aff, + 0x7ba1, 0x7c21, 0x7de9, 0x7f36, 0x7ff0, 0x809d, 0x8266, 0x839e, + 0x89b3, 0x8acc, 0x8cab, 0x9084, 0x9451, 0x9593, 0x9591, 0x95a2, + 0x9665, 0x97d3, 0x9928, 0x8218, 0x4e38, 0x542b, 0x5cb8, 0x5dcc, + 0x73a9, 0x764c, 0x773c, 0x5ca9, 0x7feb, 0x8d0b, 0x96c1, 0x9811, + 0x9854, 0x9858, 0x4f01, 0x4f0e, 0x5371, 0x559c, 0x5668, 0x57fa, + 0x5947, 0x5b09, 0x5bc4, 0x5c90, 0x5e0c, 0x5e7e, 0x5fcc, 0x63ee, + 0x673a, 0x65d7, 0x65e2, 0x671f, 0x68cb, 0x68c4, + /* 0x35 */ + 0x6a5f, 0x5e30, 0x6bc5, 0x6c17, 0x6c7d, 0x757f, 0x7948, 0x5b63, + 0x7a00, 0x7d00, 0x5fbd, 0x898f, 0x8a18, 0x8cb4, 0x8d77, 0x8ecc, + 0x8f1d, 0x98e2, 0x9a0e, 0x9b3c, 0x4e80, 0x507d, 0x5100, 0x5993, + 0x5b9c, 0x622f, 0x6280, 0x64ec, 0x6b3a, 0x72a0, 0x7591, 0x7947, + 0x7fa9, 0x87fb, 0x8abc, 0x8b70, 0x63ac, 0x83ca, 0x97a0, 0x5409, + 0x5403, 0x55ab, 0x6854, 0x6a58, 0x8a70, 0x7827, 0x6775, 0x9ecd, + 0x5374, 0x5ba2, 0x811a, 0x8650, 0x9006, 0x4e18, 0x4e45, 0x4ec7, + 0x4f11, 0x53ca, 0x5438, 0x5bae, 0x5f13, 0x6025, 0x6551, 0x673d, + 0x6c42, 0x6c72, 0x6ce3, 0x7078, 0x7403, 0x7a76, 0x7aae, 0x7b08, + 0x7d1a, 0x7cfe, 0x7d66, 0x65e7, 0x725b, 0x53bb, 0x5c45, 0x5de8, + 0x62d2, 0x62e0, 0x6319, 0x6e20, 0x865a, 0x8a31, 0x8ddd, 0x92f8, + 0x6f01, 0x79a6, 0x9b5a, 0x4ea8, 0x4eab, 0x4eac, + /* 0x36 */ + 0x4f9b, 0x4fa0, 0x50d1, 0x5147, 0x7af6, 0x5171, 0x51f6, 0x5354, + 0x5321, 0x537f, 0x53eb, 0x55ac, 0x5883, 0x5ce1, 0x5f37, 0x5f4a, + 0x602f, 0x6050, 0x606d, 0x631f, 0x6559, 0x6a4b, 0x6cc1, 0x72c2, + 0x72ed, 0x77ef, 0x80f8, 0x8105, 0x8208, 0x854e, 0x90f7, 0x93e1, + 0x97ff, 0x9957, 0x9a5a, 0x4ef0, 0x51dd, 0x5c2d, 0x6681, 0x696d, + 0x5c40, 0x66f2, 0x6975, 0x7389, 0x6850, 0x7c81, 0x50c5, 0x52e4, + 0x5747, 0x5dfe, 0x9326, 0x65a4, 0x6b23, 0x6b3d, 0x7434, 0x7981, + 0x79bd, 0x7b4b, 0x7dca, 0x82b9, 0x83cc, 0x887f, 0x895f, 0x8b39, + 0x8fd1, 0x91d1, 0x541f, 0x9280, 0x4e5d, 0x5036, 0x53e5, 0x533a, + 0x72d7, 0x7396, 0x77e9, 0x82e6, 0x8eaf, 0x99c6, 0x99c8, 0x99d2, + 0x5177, 0x611a, 0x865e, 0x55b0, 0x7a7a, 0x5076, 0x5bd3, 0x9047, + 0x9685, 0x4e32, 0x6adb, 0x91e7, 0x5c51, 0x5c48, + /* 0x37 */ + 0x6398, 0x7a9f, 0x6c93, 0x9774, 0x8f61, 0x7aaa, 0x718a, 0x9688, + 0x7c82, 0x6817, 0x7e70, 0x6851, 0x936c, 0x52f2, 0x541b, 0x85ab, + 0x8a13, 0x7fa4, 0x8ecd, 0x90e1, 0x5366, 0x8888, 0x7941, 0x4fc2, + 0x50be, 0x5211, 0x5144, 0x5553, 0x572d, 0x73ea, 0x578b, 0x5951, + 0x5f62, 0x5f84, 0x6075, 0x6176, 0x6167, 0x61a9, 0x63b2, 0x643a, + 0x656c, 0x666f, 0x6842, 0x6e13, 0x7566, 0x7a3d, 0x7cfb, 0x7d4c, + 0x7d99, 0x7e4b, 0x7f6b, 0x830e, 0x834a, 0x86cd, 0x8a08, 0x8a63, + 0x8b66, 0x8efd, 0x981a, 0x9d8f, 0x82b8, 0x8fce, 0x9be8, 0x5287, + 0x621f, 0x6483, 0x6fc0, 0x9699, 0x6841, 0x5091, 0x6b20, 0x6c7a, + 0x6f54, 0x7a74, 0x7d50, 0x8840, 0x8a23, 0x6708, 0x4ef6, 0x5039, + 0x5026, 0x5065, 0x517c, 0x5238, 0x5263, 0x55a7, 0x570f, 0x5805, + 0x5acc, 0x5efa, 0x61b2, 0x61f8, 0x62f3, 0x6372, + /* 0x38 */ + 0x691c, 0x6a29, 0x727d, 0x72ac, 0x732e, 0x7814, 0x786f, 0x7d79, + 0x770c, 0x80a9, 0x898b, 0x8b19, 0x8ce2, 0x8ed2, 0x9063, 0x9375, + 0x967a, 0x9855, 0x9a13, 0x9e78, 0x5143, 0x539f, 0x53b3, 0x5e7b, + 0x5f26, 0x6e1b, 0x6e90, 0x7384, 0x73fe, 0x7d43, 0x8237, 0x8a00, + 0x8afa, 0x9650, 0x4e4e, 0x500b, 0x53e4, 0x547c, 0x56fa, 0x59d1, + 0x5b64, 0x5df1, 0x5eab, 0x5f27, 0x6238, 0x6545, 0x67af, 0x6e56, + 0x72d0, 0x7cca, 0x88b4, 0x80a1, 0x80e1, 0x83f0, 0x864e, 0x8a87, + 0x8de8, 0x9237, 0x96c7, 0x9867, 0x9f13, 0x4e94, 0x4e92, 0x4f0d, + 0x5348, 0x5449, 0x543e, 0x5a2f, 0x5f8c, 0x5fa1, 0x609f, 0x68a7, + 0x6a8e, 0x745a, 0x7881, 0x8a9e, 0x8aa4, 0x8b77, 0x9190, 0x4e5e, + 0x9bc9, 0x4ea4, 0x4f7c, 0x4faf, 0x5019, 0x5016, 0x5149, 0x516c, + 0x529f, 0x52b9, 0x52fe, 0x539a, 0x53e3, 0x5411, + /* 0x39 */ + 0x540e, 0x5589, 0x5751, 0x57a2, 0x597d, 0x5b54, 0x5b5d, 0x5b8f, + 0x5de5, 0x5de7, 0x5df7, 0x5e78, 0x5e83, 0x5e9a, 0x5eb7, 0x5f18, + 0x6052, 0x614c, 0x6297, 0x62d8, 0x63a7, 0x653b, 0x6602, 0x6643, + 0x66f4, 0x676d, 0x6821, 0x6897, 0x69cb, 0x6c5f, 0x6d2a, 0x6d69, + 0x6e2f, 0x6e9d, 0x7532, 0x7687, 0x786c, 0x7a3f, 0x7ce0, 0x7d05, + 0x7d18, 0x7d5e, 0x7db1, 0x8015, 0x8003, 0x80af, 0x80b1, 0x8154, + 0x818f, 0x822a, 0x8352, 0x884c, 0x8861, 0x8b1b, 0x8ca2, 0x8cfc, + 0x90ca, 0x9175, 0x9271, 0x783f, 0x92fc, 0x95a4, 0x964d, 0x9805, + 0x9999, 0x9ad8, 0x9d3b, 0x525b, 0x52ab, 0x53f7, 0x5408, 0x58d5, + 0x62f7, 0x6fe0, 0x8c6a, 0x8f5f, 0x9eb9, 0x514b, 0x523b, 0x544a, + 0x56fd, 0x7a40, 0x9177, 0x9d60, 0x9ed2, 0x7344, 0x6f09, 0x8170, + 0x7511, 0x5ffd, 0x60da, 0x9aa8, 0x72db, 0x8fbc, + /* 0x3a */ + 0x6b64, 0x9803, 0x4eca, 0x56f0, 0x5764, 0x58be, 0x5a5a, 0x6068, + 0x61c7, 0x660f, 0x6606, 0x6839, 0x68b1, 0x6df7, 0x75d5, 0x7d3a, + 0x826e, 0x9b42, 0x4e9b, 0x4f50, 0x53c9, 0x5506, 0x5d6f, 0x5de6, + 0x5dee, 0x67fb, 0x6c99, 0x7473, 0x7802, 0x8a50, 0x9396, 0x88df, + 0x5750, 0x5ea7, 0x632b, 0x50b5, 0x50ac, 0x518d, 0x6700, 0x54c9, + 0x585e, 0x59bb, 0x5bb0, 0x5f69, 0x624d, 0x63a1, 0x683d, 0x6b73, + 0x6e08, 0x707d, 0x91c7, 0x7280, 0x7815, 0x7826, 0x796d, 0x658e, + 0x7d30, 0x83dc, 0x88c1, 0x8f09, 0x969b, 0x5264, 0x5728, 0x6750, + 0x7f6a, 0x8ca1, 0x51b4, 0x5742, 0x962a, 0x583a, 0x698a, 0x80b4, + 0x54b2, 0x5d0e, 0x57fc, 0x7895, 0x9dfa, 0x4f5c, 0x524a, 0x548b, + 0x643e, 0x6628, 0x6714, 0x67f5, 0x7a84, 0x7b56, 0x7d22, 0x932f, + 0x685c, 0x9bad, 0x7b39, 0x5319, 0x518a, 0x5237, + /* 0x3b */ + 0x5bdf, 0x62f6, 0x64ae, 0x64e6, 0x672d, 0x6bba, 0x85a9, 0x96d1, + 0x7690, 0x9bd6, 0x634c, 0x9306, 0x9bab, 0x76bf, 0x6652, 0x4e09, + 0x5098, 0x53c2, 0x5c71, 0x60e8, 0x6492, 0x6563, 0x685f, 0x71e6, + 0x73ca, 0x7523, 0x7b97, 0x7e82, 0x8695, 0x8b83, 0x8cdb, 0x9178, + 0x9910, 0x65ac, 0x66ab, 0x6b8b, 0x4ed5, 0x4ed4, 0x4f3a, 0x4f7f, + 0x523a, 0x53f8, 0x53f2, 0x55e3, 0x56db, 0x58eb, 0x59cb, 0x59c9, + 0x59ff, 0x5b50, 0x5c4d, 0x5e02, 0x5e2b, 0x5fd7, 0x601d, 0x6307, + 0x652f, 0x5b5c, 0x65af, 0x65bd, 0x65e8, 0x679d, 0x6b62, 0x6b7b, + 0x6c0f, 0x7345, 0x7949, 0x79c1, 0x7cf8, 0x7d19, 0x7d2b, 0x80a2, + 0x8102, 0x81f3, 0x8996, 0x8a5e, 0x8a69, 0x8a66, 0x8a8c, 0x8aee, + 0x8cc7, 0x8cdc, 0x96cc, 0x98fc, 0x6b6f, 0x4e8b, 0x4f3c, 0x4f8d, + 0x5150, 0x5b57, 0x5bfa, 0x6148, 0x6301, 0x6642, + /* 0x3c */ + 0x6b21, 0x6ecb, 0x6cbb, 0x723e, 0x74bd, 0x75d4, 0x78c1, 0x793a, + 0x800c, 0x8033, 0x81ea, 0x8494, 0x8f9e, 0x6c50, 0x9e7f, 0x5f0f, + 0x8b58, 0x9d2b, 0x7afa, 0x8ef8, 0x5b8d, 0x96eb, 0x4e03, 0x53f1, + 0x57f7, 0x5931, 0x5ac9, 0x5ba4, 0x6089, 0x6e7f, 0x6f06, 0x75be, + 0x8cea, 0x5b9f, 0x8500, 0x7be0, 0x5072, 0x67f4, 0x829d, 0x5c61, + 0x854a, 0x7e1e, 0x820e, 0x5199, 0x5c04, 0x6368, 0x8d66, 0x659c, + 0x716e, 0x793e, 0x7d17, 0x8005, 0x8b1d, 0x8eca, 0x906e, 0x86c7, + 0x90aa, 0x501f, 0x52fa, 0x5c3a, 0x6753, 0x707c, 0x7235, 0x914c, + 0x91c8, 0x932b, 0x82e5, 0x5bc2, 0x5f31, 0x60f9, 0x4e3b, 0x53d6, + 0x5b88, 0x624b, 0x6731, 0x6b8a, 0x72e9, 0x73e0, 0x7a2e, 0x816b, + 0x8da3, 0x9152, 0x9996, 0x5112, 0x53d7, 0x546a, 0x5bff, 0x6388, + 0x6a39, 0x7dac, 0x9700, 0x56da, 0x53ce, 0x5468, + /* 0x3d */ + 0x5b97, 0x5c31, 0x5dde, 0x4fee, 0x6101, 0x62fe, 0x6d32, 0x79c0, + 0x79cb, 0x7d42, 0x7e4d, 0x7fd2, 0x81ed, 0x821f, 0x8490, 0x8846, + 0x8972, 0x8b90, 0x8e74, 0x8f2f, 0x9031, 0x914b, 0x916c, 0x96c6, + 0x919c, 0x4ec0, 0x4f4f, 0x5145, 0x5341, 0x5f93, 0x620e, 0x67d4, + 0x6c41, 0x6e0b, 0x7363, 0x7e26, 0x91cd, 0x9283, 0x53d4, 0x5919, + 0x5bbf, 0x6dd1, 0x795d, 0x7e2e, 0x7c9b, 0x587e, 0x719f, 0x51fa, + 0x8853, 0x8ff0, 0x4fca, 0x5cfb, 0x6625, 0x77ac, 0x7ae3, 0x821c, + 0x99ff, 0x51c6, 0x5faa, 0x65ec, 0x696f, 0x6b89, 0x6df3, 0x6e96, + 0x6f64, 0x76fe, 0x7d14, 0x5de1, 0x9075, 0x9187, 0x9806, 0x51e6, + 0x521d, 0x6240, 0x6691, 0x66d9, 0x6e1a, 0x5eb6, 0x7dd2, 0x7f72, + 0x66f8, 0x85af, 0x85f7, 0x8af8, 0x52a9, 0x53d9, 0x5973, 0x5e8f, + 0x5f90, 0x6055, 0x92e4, 0x9664, 0x50b7, 0x511f, + /* 0x3e */ + 0x52dd, 0x5320, 0x5347, 0x53ec, 0x54e8, 0x5546, 0x5531, 0x5617, + 0x5968, 0x59be, 0x5a3c, 0x5bb5, 0x5c06, 0x5c0f, 0x5c11, 0x5c1a, + 0x5e84, 0x5e8a, 0x5ee0, 0x5f70, 0x627f, 0x6284, 0x62db, 0x638c, + 0x6377, 0x6607, 0x660c, 0x662d, 0x6676, 0x677e, 0x68a2, 0x6a1f, + 0x6a35, 0x6cbc, 0x6d88, 0x6e09, 0x6e58, 0x713c, 0x7126, 0x7167, + 0x75c7, 0x7701, 0x785d, 0x7901, 0x7965, 0x79f0, 0x7ae0, 0x7b11, + 0x7ca7, 0x7d39, 0x8096, 0x83d6, 0x848b, 0x8549, 0x885d, 0x88f3, + 0x8a1f, 0x8a3c, 0x8a54, 0x8a73, 0x8c61, 0x8cde, 0x91a4, 0x9266, + 0x937e, 0x9418, 0x969c, 0x9798, 0x4e0a, 0x4e08, 0x4e1e, 0x4e57, + 0x5197, 0x5270, 0x57ce, 0x5834, 0x58cc, 0x5b22, 0x5e38, 0x60c5, + 0x64fe, 0x6761, 0x6756, 0x6d44, 0x72b6, 0x7573, 0x7a63, 0x84b8, + 0x8b72, 0x91b8, 0x9320, 0x5631, 0x57f4, 0x98fe, + /* 0x3f */ + 0x62ed, 0x690d, 0x6b96, 0x71ed, 0x7e54, 0x8077, 0x8272, 0x89e6, + 0x98df, 0x8755, 0x8fb1, 0x5c3b, 0x4f38, 0x4fe1, 0x4fb5, 0x5507, + 0x5a20, 0x5bdd, 0x5be9, 0x5fc3, 0x614e, 0x632f, 0x65b0, 0x664b, + 0x68ee, 0x699b, 0x6d78, 0x6df1, 0x7533, 0x75b9, 0x771f, 0x795e, + 0x79e6, 0x7d33, 0x81e3, 0x82af, 0x85aa, 0x89aa, 0x8a3a, 0x8eab, + 0x8f9b, 0x9032, 0x91dd, 0x9707, 0x4eba, 0x4ec1, 0x5203, 0x5875, + 0x58ec, 0x5c0b, 0x751a, 0x5c3d, 0x814e, 0x8a0a, 0x8fc5, 0x9663, + 0x976d, 0x7b25, 0x8acf, 0x9808, 0x9162, 0x56f3, 0x53a8, 0x9017, + 0x5439, 0x5782, 0x5e25, 0x63a8, 0x6c34, 0x708a, 0x7761, 0x7c8b, + 0x7fe0, 0x8870, 0x9042, 0x9154, 0x9310, 0x9318, 0x968f, 0x745e, + 0x9ac4, 0x5d07, 0x5d69, 0x6570, 0x67a2, 0x8da8, 0x96db, 0x636e, + 0x6749, 0x6919, 0x83c5, 0x9817, 0x96c0, 0x88fe, + /* 0x40 */ + 0x6f84, 0x647a, 0x5bf8, 0x4e16, 0x702c, 0x755d, 0x662f, 0x51c4, + 0x5236, 0x52e2, 0x59d3, 0x5f81, 0x6027, 0x6210, 0x653f, 0x6574, + 0x661f, 0x6674, 0x68f2, 0x6816, 0x6b63, 0x6e05, 0x7272, 0x751f, + 0x76db, 0x7cbe, 0x8056, 0x58f0, 0x88fd, 0x897f, 0x8aa0, 0x8a93, + 0x8acb, 0x901d, 0x9192, 0x9752, 0x9759, 0x6589, 0x7a0e, 0x8106, + 0x96bb, 0x5e2d, 0x60dc, 0x621a, 0x65a5, 0x6614, 0x6790, 0x77f3, + 0x7a4d, 0x7c4d, 0x7e3e, 0x810a, 0x8cac, 0x8d64, 0x8de1, 0x8e5f, + 0x78a9, 0x5207, 0x62d9, 0x63a5, 0x6442, 0x6298, 0x8a2d, 0x7a83, + 0x7bc0, 0x8aac, 0x96ea, 0x7d76, 0x820c, 0x8749, 0x4ed9, 0x5148, + 0x5343, 0x5360, 0x5ba3, 0x5c02, 0x5c16, 0x5ddd, 0x6226, 0x6247, + 0x64b0, 0x6813, 0x6834, 0x6cc9, 0x6d45, 0x6d17, 0x67d3, 0x6f5c, + 0x714e, 0x717d, 0x65cb, 0x7a7f, 0x7bad, 0x7dda, + /* 0x41 */ + 0x7e4a, 0x7fa8, 0x817a, 0x821b, 0x8239, 0x85a6, 0x8a6e, 0x8cce, + 0x8df5, 0x9078, 0x9077, 0x92ad, 0x9291, 0x9583, 0x9bae, 0x524d, + 0x5584, 0x6f38, 0x7136, 0x5168, 0x7985, 0x7e55, 0x81b3, 0x7cce, + 0x564c, 0x5851, 0x5ca8, 0x63aa, 0x66fe, 0x66fd, 0x695a, 0x72d9, + 0x758f, 0x758e, 0x790e, 0x7956, 0x79df, 0x7c97, 0x7d20, 0x7d44, + 0x8607, 0x8a34, 0x963b, 0x9061, 0x9f20, 0x50e7, 0x5275, 0x53cc, + 0x53e2, 0x5009, 0x55aa, 0x58ee, 0x594f, 0x723d, 0x5b8b, 0x5c64, + 0x531d, 0x60e3, 0x60f3, 0x635c, 0x6383, 0x633f, 0x63bb, 0x64cd, + 0x65e9, 0x66f9, 0x5de3, 0x69cd, 0x69fd, 0x6f15, 0x71e5, 0x4e89, + 0x75e9, 0x76f8, 0x7a93, 0x7cdf, 0x7dcf, 0x7d9c, 0x8061, 0x8349, + 0x8358, 0x846c, 0x84bc, 0x85fb, 0x88c5, 0x8d70, 0x9001, 0x906d, + 0x9397, 0x971c, 0x9a12, 0x50cf, 0x5897, 0x618e, + /* 0x42 */ + 0x81d3, 0x8535, 0x8d08, 0x9020, 0x4fc3, 0x5074, 0x5247, 0x5373, + 0x606f, 0x6349, 0x675f, 0x6e2c, 0x8db3, 0x901f, 0x4fd7, 0x5c5e, + 0x8cca, 0x65cf, 0x7d9a, 0x5352, 0x8896, 0x5176, 0x63c3, 0x5b58, + 0x5b6b, 0x5c0a, 0x640d, 0x6751, 0x905c, 0x4ed6, 0x591a, 0x592a, + 0x6c70, 0x8a51, 0x553e, 0x5815, 0x59a5, 0x60f0, 0x6253, 0x67c1, + 0x8235, 0x6955, 0x9640, 0x99c4, 0x9a28, 0x4f53, 0x5806, 0x5bfe, + 0x8010, 0x5cb1, 0x5e2f, 0x5f85, 0x6020, 0x614b, 0x6234, 0x66ff, + 0x6cf0, 0x6ede, 0x80ce, 0x817f, 0x82d4, 0x888b, 0x8cb8, 0x9000, + 0x902e, 0x968a, 0x9edb, 0x9bdb, 0x4ee3, 0x53f0, 0x5927, 0x7b2c, + 0x918d, 0x984c, 0x9df9, 0x6edd, 0x7027, 0x5353, 0x5544, 0x5b85, + 0x6258, 0x629e, 0x62d3, 0x6ca2, 0x6fef, 0x7422, 0x8a17, 0x9438, + 0x6fc1, 0x8afe, 0x8338, 0x51e7, 0x86f8, 0x53ea, + /* 0x43 */ + 0x53e9, 0x4f46, 0x9054, 0x8fb0, 0x596a, 0x8131, 0x5dfd, 0x7aea, + 0x8fbf, 0x68da, 0x8c37, 0x72f8, 0x9c48, 0x6a3d, 0x8ab0, 0x4e39, + 0x5358, 0x5606, 0x5766, 0x62c5, 0x63a2, 0x65e6, 0x6b4e, 0x6de1, + 0x6e5b, 0x70ad, 0x77ed, 0x7aef, 0x7baa, 0x7dbb, 0x803d, 0x80c6, + 0x86cb, 0x8a95, 0x935b, 0x56e3, 0x58c7, 0x5f3e, 0x65ad, 0x6696, + 0x6a80, 0x6bb5, 0x7537, 0x8ac7, 0x5024, 0x77e5, 0x5730, 0x5f1b, + 0x6065, 0x667a, 0x6c60, 0x75f4, 0x7a1a, 0x7f6e, 0x81f4, 0x8718, + 0x9045, 0x99b3, 0x7bc9, 0x755c, 0x7af9, 0x7b51, 0x84c4, 0x9010, + 0x79e9, 0x7a92, 0x8336, 0x5ae1, 0x7740, 0x4e2d, 0x4ef2, 0x5b99, + 0x5fe0, 0x62bd, 0x663c, 0x67f1, 0x6ce8, 0x866b, 0x8877, 0x8a3b, + 0x914e, 0x92f3, 0x99d0, 0x6a17, 0x7026, 0x732a, 0x82e7, 0x8457, + 0x8caf, 0x4e01, 0x5146, 0x51cb, 0x558b, 0x5bf5, + /* 0x44 */ + 0x5e16, 0x5e33, 0x5e81, 0x5f14, 0x5f35, 0x5f6b, 0x5fb4, 0x61f2, + 0x6311, 0x66a2, 0x671d, 0x6f6e, 0x7252, 0x753a, 0x773a, 0x8074, + 0x8139, 0x8178, 0x8776, 0x8abf, 0x8adc, 0x8d85, 0x8df3, 0x929a, + 0x9577, 0x9802, 0x9ce5, 0x52c5, 0x6357, 0x76f4, 0x6715, 0x6c88, + 0x73cd, 0x8cc3, 0x93ae, 0x9673, 0x6d25, 0x589c, 0x690e, 0x69cc, + 0x8ffd, 0x939a, 0x75db, 0x901a, 0x585a, 0x6802, 0x63b4, 0x69fb, + 0x4f43, 0x6f2c, 0x67d8, 0x8fbb, 0x8526, 0x7db4, 0x9354, 0x693f, + 0x6f70, 0x576a, 0x58f7, 0x5b2c, 0x7d2c, 0x722a, 0x540a, 0x91e3, + 0x9db4, 0x4ead, 0x4f4e, 0x505c, 0x5075, 0x5243, 0x8c9e, 0x5448, + 0x5824, 0x5b9a, 0x5e1d, 0x5e95, 0x5ead, 0x5ef7, 0x5f1f, 0x608c, + 0x62b5, 0x633a, 0x63d0, 0x68af, 0x6c40, 0x7887, 0x798e, 0x7a0b, + 0x7de0, 0x8247, 0x8a02, 0x8ae6, 0x8e44, 0x9013, + /* 0x45 */ + 0x90b8, 0x912d, 0x91d8, 0x9f0e, 0x6ce5, 0x6458, 0x64e2, 0x6575, + 0x6ef4, 0x7684, 0x7b1b, 0x9069, 0x93d1, 0x6eba, 0x54f2, 0x5fb9, + 0x64a4, 0x8f4d, 0x8fed, 0x9244, 0x5178, 0x586b, 0x5929, 0x5c55, + 0x5e97, 0x6dfb, 0x7e8f, 0x751c, 0x8cbc, 0x8ee2, 0x985b, 0x70b9, + 0x4f1d, 0x6bbf, 0x6fb1, 0x7530, 0x96fb, 0x514e, 0x5410, 0x5835, + 0x5857, 0x59ac, 0x5c60, 0x5f92, 0x6597, 0x675c, 0x6e21, 0x767b, + 0x83df, 0x8ced, 0x9014, 0x90fd, 0x934d, 0x7825, 0x783a, 0x52aa, + 0x5ea6, 0x571f, 0x5974, 0x6012, 0x5012, 0x515a, 0x51ac, 0x51cd, + 0x5200, 0x5510, 0x5854, 0x5858, 0x5957, 0x5b95, 0x5cf6, 0x5d8b, + 0x60bc, 0x6295, 0x642d, 0x6771, 0x6843, 0x68bc, 0x68df, 0x76d7, + 0x6dd8, 0x6e6f, 0x6d9b, 0x706f, 0x71c8, 0x5f53, 0x75d8, 0x7977, + 0x7b49, 0x7b54, 0x7b52, 0x7cd6, 0x7d71, 0x5230, + /* 0x46 */ + 0x8463, 0x8569, 0x85e4, 0x8a0e, 0x8b04, 0x8c46, 0x8e0f, 0x9003, + 0x900f, 0x9419, 0x9676, 0x982d, 0x9a30, 0x95d8, 0x50cd, 0x52d5, + 0x540c, 0x5802, 0x5c0e, 0x61a7, 0x649e, 0x6d1e, 0x77b3, 0x7ae5, + 0x80f4, 0x8404, 0x9053, 0x9285, 0x5ce0, 0x9d07, 0x533f, 0x5f97, + 0x5fb3, 0x6d9c, 0x7279, 0x7763, 0x79bf, 0x7be4, 0x6bd2, 0x72ec, + 0x8aad, 0x6803, 0x6a61, 0x51f8, 0x7a81, 0x6934, 0x5c4a, 0x9cf6, + 0x82eb, 0x5bc5, 0x9149, 0x701e, 0x5678, 0x5c6f, 0x60c7, 0x6566, + 0x6c8c, 0x8c5a, 0x9041, 0x9813, 0x5451, 0x66c7, 0x920d, 0x5948, + 0x90a3, 0x5185, 0x4e4d, 0x51ea, 0x8599, 0x8b0e, 0x7058, 0x637a, + 0x934b, 0x6962, 0x99b4, 0x7e04, 0x7577, 0x5357, 0x6960, 0x8edf, + 0x96e3, 0x6c5d, 0x4e8c, 0x5c3c, 0x5f10, 0x8fe9, 0x5302, 0x8cd1, + 0x8089, 0x8679, 0x5eff, 0x65e5, 0x4e73, 0x5165, + /* 0x47 */ + 0x5982, 0x5c3f, 0x97ee, 0x4efb, 0x598a, 0x5fcd, 0x8a8d, 0x6fe1, + 0x79b0, 0x7962, 0x5be7, 0x8471, 0x732b, 0x71b1, 0x5e74, 0x5ff5, + 0x637b, 0x649a, 0x71c3, 0x7c98, 0x4e43, 0x5efc, 0x4e4b, 0x57dc, + 0x56a2, 0x60a9, 0x6fc3, 0x7d0d, 0x80fd, 0x8133, 0x81bf, 0x8fb2, + 0x8997, 0x86a4, 0x5df4, 0x628a, 0x64ad, 0x8987, 0x6777, 0x6ce2, + 0x6d3e, 0x7436, 0x7834, 0x5a46, 0x7f75, 0x82ad, 0x99ac, 0x4ff3, + 0x5ec3, 0x62dd, 0x6392, 0x6557, 0x676f, 0x76c3, 0x724c, 0x80cc, + 0x80ba, 0x8f29, 0x914d, 0x500d, 0x57f9, 0x5a92, 0x6885, 0x6973, + 0x7164, 0x72fd, 0x8cb7, 0x58f2, 0x8ce0, 0x966a, 0x9019, 0x877f, + 0x79e4, 0x77e7, 0x8429, 0x4f2f, 0x5265, 0x535a, 0x62cd, 0x67cf, + 0x6cca, 0x767d, 0x7b94, 0x7c95, 0x8236, 0x8584, 0x8feb, 0x66dd, + 0x6f20, 0x7206, 0x7e1b, 0x83ab, 0x99c1, 0x9ea6, + /* 0x48 */ + 0x51fd, 0x7bb1, 0x7872, 0x7bb8, 0x8087, 0x7b48, 0x6ae8, 0x5e61, + 0x808c, 0x7551, 0x7560, 0x516b, 0x9262, 0x6e8c, 0x767a, 0x9197, + 0x9aea, 0x4f10, 0x7f70, 0x629c, 0x7b4f, 0x95a5, 0x9ce9, 0x567a, + 0x5859, 0x86e4, 0x96bc, 0x4f34, 0x5224, 0x534a, 0x53cd, 0x53db, + 0x5e06, 0x642c, 0x6591, 0x677f, 0x6c3e, 0x6c4e, 0x7248, 0x72af, + 0x73ed, 0x7554, 0x7e41, 0x822c, 0x85e9, 0x8ca9, 0x7bc4, 0x91c6, + 0x7169, 0x9812, 0x98ef, 0x633d, 0x6669, 0x756a, 0x76e4, 0x78d0, + 0x8543, 0x86ee, 0x532a, 0x5351, 0x5426, 0x5983, 0x5e87, 0x5f7c, + 0x60b2, 0x6249, 0x6279, 0x62ab, 0x6590, 0x6bd4, 0x6ccc, 0x75b2, + 0x76ae, 0x7891, 0x79d8, 0x7dcb, 0x7f77, 0x80a5, 0x88ab, 0x8ab9, + 0x8cbb, 0x907f, 0x975e, 0x98db, 0x6a0b, 0x7c38, 0x5099, 0x5c3e, + 0x5fae, 0x6787, 0x6bd8, 0x7435, 0x7709, 0x7f8e, + /* 0x49 */ + 0x9f3b, 0x67ca, 0x7a17, 0x5339, 0x758b, 0x9aed, 0x5f66, 0x819d, + 0x83f1, 0x8098, 0x5f3c, 0x5fc5, 0x7562, 0x7b46, 0x903c, 0x6867, + 0x59eb, 0x5a9b, 0x7d10, 0x767e, 0x8b2c, 0x4ff5, 0x5f6a, 0x6a19, + 0x6c37, 0x6f02, 0x74e2, 0x7968, 0x8868, 0x8a55, 0x8c79, 0x5edf, + 0x63cf, 0x75c5, 0x79d2, 0x82d7, 0x9328, 0x92f2, 0x849c, 0x86ed, + 0x9c2d, 0x54c1, 0x5f6c, 0x658c, 0x6d5c, 0x7015, 0x8ca7, 0x8cd3, + 0x983b, 0x654f, 0x74f6, 0x4e0d, 0x4ed8, 0x57e0, 0x592b, 0x5a66, + 0x5bcc, 0x51a8, 0x5e03, 0x5e9c, 0x6016, 0x6276, 0x6577, 0x65a7, + 0x666e, 0x6d6e, 0x7236, 0x7b26, 0x8150, 0x819a, 0x8299, 0x8b5c, + 0x8ca0, 0x8ce6, 0x8d74, 0x961c, 0x9644, 0x4fae, 0x64ab, 0x6b66, + 0x821e, 0x8461, 0x856a, 0x90e8, 0x5c01, 0x6953, 0x98a8, 0x847a, + 0x8557, 0x4f0f, 0x526f, 0x5fa9, 0x5e45, 0x670d, + /* 0x4a */ + 0x798f, 0x8179, 0x8907, 0x8986, 0x6df5, 0x5f17, 0x6255, 0x6cb8, + 0x4ecf, 0x7269, 0x9b92, 0x5206, 0x543b, 0x5674, 0x58b3, 0x61a4, + 0x626e, 0x711a, 0x596e, 0x7c89, 0x7cde, 0x7d1b, 0x96f0, 0x6587, + 0x805e, 0x4e19, 0x4f75, 0x5175, 0x5840, 0x5e63, 0x5e73, 0x5f0a, + 0x67c4, 0x4e26, 0x853d, 0x9589, 0x965b, 0x7c73, 0x9801, 0x50fb, + 0x58c1, 0x7656, 0x78a7, 0x5225, 0x77a5, 0x8511, 0x7b86, 0x504f, + 0x5909, 0x7247, 0x7bc7, 0x7de8, 0x8fba, 0x8fd4, 0x904d, 0x4fbf, + 0x52c9, 0x5a29, 0x5f01, 0x97ad, 0x4fdd, 0x8217, 0x92ea, 0x5703, + 0x6355, 0x6b69, 0x752b, 0x88dc, 0x8f14, 0x7a42, 0x52df, 0x5893, + 0x6155, 0x620a, 0x66ae, 0x6bcd, 0x7c3f, 0x83e9, 0x5023, 0x4ff8, + 0x5305, 0x5446, 0x5831, 0x5949, 0x5b9d, 0x5cf0, 0x5cef, 0x5d29, + 0x5e96, 0x62b1, 0x6367, 0x653e, 0x65b9, 0x670b, + /* 0x4b */ + 0x6cd5, 0x6ce1, 0x70f9, 0x7832, 0x7e2b, 0x80de, 0x82b3, 0x840c, + 0x84ec, 0x8702, 0x8912, 0x8a2a, 0x8c4a, 0x90a6, 0x92d2, 0x98fd, + 0x9cf3, 0x9d6c, 0x4e4f, 0x4ea1, 0x508d, 0x5256, 0x574a, 0x59a8, + 0x5e3d, 0x5fd8, 0x5fd9, 0x623f, 0x66b4, 0x671b, 0x67d0, 0x68d2, + 0x5192, 0x7d21, 0x80aa, 0x81a8, 0x8b00, 0x8c8c, 0x8cbf, 0x927e, + 0x9632, 0x5420, 0x982c, 0x5317, 0x50d5, 0x535c, 0x58a8, 0x64b2, + 0x6734, 0x7267, 0x7766, 0x7a46, 0x91e6, 0x52c3, 0x6ca1, 0x6b86, + 0x5800, 0x5e4c, 0x5954, 0x672c, 0x7ffb, 0x51e1, 0x76c6, 0x6469, + 0x78e8, 0x9b54, 0x9ebb, 0x57cb, 0x59b9, 0x6627, 0x679a, 0x6bce, + 0x54e9, 0x69d9, 0x5e55, 0x819c, 0x6795, 0x9baa, 0x67fe, 0x9c52, + 0x685d, 0x4ea6, 0x4fe3, 0x53c8, 0x62b9, 0x672b, 0x6cab, 0x8fc4, + 0x4fad, 0x7e6d, 0x9ebf, 0x4e07, 0x6162, 0x6e80, + /* 0x4c */ + 0x6f2b, 0x8513, 0x5473, 0x672a, 0x9b45, 0x5df3, 0x7b95, 0x5cac, + 0x5bc6, 0x871c, 0x6e4a, 0x84d1, 0x7a14, 0x8108, 0x5999, 0x7c8d, + 0x6c11, 0x7720, 0x52d9, 0x5922, 0x7121, 0x725f, 0x77db, 0x9727, + 0x9d61, 0x690b, 0x5a7f, 0x5a18, 0x51a5, 0x540d, 0x547d, 0x660e, + 0x76df, 0x8ff7, 0x9298, 0x9cf4, 0x59ea, 0x725d, 0x6ec5, 0x514d, + 0x68c9, 0x7dbf, 0x7dec, 0x9762, 0x9eba, 0x6478, 0x6a21, 0x8302, + 0x5984, 0x5b5f, 0x6bdb, 0x731b, 0x76f2, 0x7db2, 0x8017, 0x8499, + 0x5132, 0x6728, 0x9ed9, 0x76ee, 0x6762, 0x52ff, 0x9905, 0x5c24, + 0x623b, 0x7c7e, 0x8cb0, 0x554f, 0x60b6, 0x7d0b, 0x9580, 0x5301, + 0x4e5f, 0x51b6, 0x591c, 0x723a, 0x8036, 0x91ce, 0x5f25, 0x77e2, + 0x5384, 0x5f79, 0x7d04, 0x85ac, 0x8a33, 0x8e8d, 0x9756, 0x67f3, + 0x85ae, 0x9453, 0x6109, 0x6108, 0x6cb9, 0x7652, + /* 0x4d */ + 0x8aed, 0x8f38, 0x552f, 0x4f51, 0x512a, 0x52c7, 0x53cb, 0x5ba5, + 0x5e7d, 0x60a0, 0x6182, 0x63d6, 0x6709, 0x67da, 0x6e67, 0x6d8c, + 0x7336, 0x7337, 0x7531, 0x7950, 0x88d5, 0x8a98, 0x904a, 0x9091, + 0x90f5, 0x96c4, 0x878d, 0x5915, 0x4e88, 0x4f59, 0x4e0e, 0x8a89, + 0x8f3f, 0x9810, 0x50ad, 0x5e7c, 0x5996, 0x5bb9, 0x5eb8, 0x63da, + 0x63fa, 0x64c1, 0x66dc, 0x694a, 0x69d8, 0x6d0b, 0x6eb6, 0x7194, + 0x7528, 0x7aaf, 0x7f8a, 0x8000, 0x8449, 0x84c9, 0x8981, 0x8b21, + 0x8e0a, 0x9065, 0x967d, 0x990a, 0x617e, 0x6291, 0x6b32, 0x6c83, + 0x6d74, 0x7fcc, 0x7ffc, 0x6dc0, 0x7f85, 0x87ba, 0x88f8, 0x6765, + 0x83b1, 0x983c, 0x96f7, 0x6d1b, 0x7d61, 0x843d, 0x916a, 0x4e71, + 0x5375, 0x5d50, 0x6b04, 0x6feb, 0x85cd, 0x862d, 0x89a7, 0x5229, + 0x540f, 0x5c65, 0x674e, 0x68a8, 0x7406, 0x7483, + /* 0x4e */ + 0x75e2, 0x88cf, 0x88e1, 0x91cc, 0x96e2, 0x9678, 0x5f8b, 0x7387, + 0x7acb, 0x844e, 0x63a0, 0x7565, 0x5289, 0x6d41, 0x6e9c, 0x7409, + 0x7559, 0x786b, 0x7c92, 0x9686, 0x7adc, 0x9f8d, 0x4fb6, 0x616e, + 0x65c5, 0x865c, 0x4e86, 0x4eae, 0x50da, 0x4e21, 0x51cc, 0x5bee, + 0x6599, 0x6881, 0x6dbc, 0x731f, 0x7642, 0x77ad, 0x7a1c, 0x7ce7, + 0x826f, 0x8ad2, 0x907c, 0x91cf, 0x9675, 0x9818, 0x529b, 0x7dd1, + 0x502b, 0x5398, 0x6797, 0x6dcb, 0x71d0, 0x7433, 0x81e8, 0x8f2a, + 0x96a3, 0x9c57, 0x9e9f, 0x7460, 0x5841, 0x6d99, 0x7d2f, 0x985e, + 0x4ee4, 0x4f36, 0x4f8b, 0x51b7, 0x52b1, 0x5dba, 0x601c, 0x73b2, + 0x793c, 0x82d3, 0x9234, 0x96b7, 0x96f6, 0x970a, 0x9e97, 0x9f62, + 0x66a6, 0x6b74, 0x5217, 0x52a3, 0x70c8, 0x88c2, 0x5ec9, 0x604b, + 0x6190, 0x6f23, 0x7149, 0x7c3e, 0x7df4, 0x806f, + /* 0x4f */ + 0x84ee, 0x9023, 0x932c, 0x5442, 0x9b6f, 0x6ad3, 0x7089, 0x8cc2, + 0x8def, 0x9732, 0x52b4, 0x5a41, 0x5eca, 0x5f04, 0x6717, 0x697c, + 0x6994, 0x6d6a, 0x6f0f, 0x7262, 0x72fc, 0x7bed, 0x8001, 0x807e, + 0x874b, 0x90ce, 0x516d, 0x9e93, 0x7984, 0x808b, 0x9332, 0x8ad6, + 0x502d, 0x548c, 0x8a71, 0x6b6a, 0x8cc4, 0x8107, 0x60d1, 0x67a0, + 0x9df2, 0x4e99, 0x4e98, 0x9c10, 0x8a6b, 0x85c1, 0x8568, 0x6900, + 0x6e7e, 0x7897, 0x8155, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x50 */ + 0x5f0c, 0x4e10, 0x4e15, 0x4e2a, 0x4e31, 0x4e36, 0x4e3c, 0x4e3f, + 0x4e42, 0x4e56, 0x4e58, 0x4e82, 0x4e85, 0x8c6b, 0x4e8a, 0x8212, + 0x5f0d, 0x4e8e, 0x4e9e, 0x4e9f, 0x4ea0, 0x4ea2, 0x4eb0, 0x4eb3, + 0x4eb6, 0x4ece, 0x4ecd, 0x4ec4, 0x4ec6, 0x4ec2, 0x4ed7, 0x4ede, + 0x4eed, 0x4edf, 0x4ef7, 0x4f09, 0x4f5a, 0x4f30, 0x4f5b, 0x4f5d, + 0x4f57, 0x4f47, 0x4f76, 0x4f88, 0x4f8f, 0x4f98, 0x4f7b, 0x4f69, + 0x4f70, 0x4f91, 0x4f6f, 0x4f86, 0x4f96, 0x5118, 0x4fd4, 0x4fdf, + 0x4fce, 0x4fd8, 0x4fdb, 0x4fd1, 0x4fda, 0x4fd0, 0x4fe4, 0x4fe5, + 0x501a, 0x5028, 0x5014, 0x502a, 0x5025, 0x5005, 0x4f1c, 0x4ff6, + 0x5021, 0x5029, 0x502c, 0x4ffe, 0x4fef, 0x5011, 0x5006, 0x5043, + 0x5047, 0x6703, 0x5055, 0x5050, 0x5048, 0x505a, 0x5056, 0x506c, + 0x5078, 0x5080, 0x509a, 0x5085, 0x50b4, 0x50b2, + /* 0x51 */ + 0x50c9, 0x50ca, 0x50b3, 0x50c2, 0x50d6, 0x50de, 0x50e5, 0x50ed, + 0x50e3, 0x50ee, 0x50f9, 0x50f5, 0x5109, 0x5101, 0x5102, 0x5116, + 0x5115, 0x5114, 0x511a, 0x5121, 0x513a, 0x5137, 0x513c, 0x513b, + 0x513f, 0x5140, 0x5152, 0x514c, 0x5154, 0x5162, 0x7af8, 0x5169, + 0x516a, 0x516e, 0x5180, 0x5182, 0x56d8, 0x518c, 0x5189, 0x518f, + 0x5191, 0x5193, 0x5195, 0x5196, 0x51a4, 0x51a6, 0x51a2, 0x51a9, + 0x51aa, 0x51ab, 0x51b3, 0x51b1, 0x51b2, 0x51b0, 0x51b5, 0x51bd, + 0x51c5, 0x51c9, 0x51db, 0x51e0, 0x8655, 0x51e9, 0x51ed, 0x51f0, + 0x51f5, 0x51fe, 0x5204, 0x520b, 0x5214, 0x520e, 0x5227, 0x522a, + 0x522e, 0x5233, 0x5239, 0x524f, 0x5244, 0x524b, 0x524c, 0x525e, + 0x5254, 0x526a, 0x5274, 0x5269, 0x5273, 0x527f, 0x527d, 0x528d, + 0x5294, 0x5292, 0x5271, 0x5288, 0x5291, 0x8fa8, + /* 0x52 */ + 0x8fa7, 0x52ac, 0x52ad, 0x52bc, 0x52b5, 0x52c1, 0x52cd, 0x52d7, + 0x52de, 0x52e3, 0x52e6, 0x98ed, 0x52e0, 0x52f3, 0x52f5, 0x52f8, + 0x52f9, 0x5306, 0x5308, 0x7538, 0x530d, 0x5310, 0x530f, 0x5315, + 0x531a, 0x5323, 0x532f, 0x5331, 0x5333, 0x5338, 0x5340, 0x5346, + 0x5345, 0x4e17, 0x5349, 0x534d, 0x51d6, 0x535e, 0x5369, 0x536e, + 0x5918, 0x537b, 0x5377, 0x5382, 0x5396, 0x53a0, 0x53a6, 0x53a5, + 0x53ae, 0x53b0, 0x53b6, 0x53c3, 0x7c12, 0x96d9, 0x53df, 0x66fc, + 0x71ee, 0x53ee, 0x53e8, 0x53ed, 0x53fa, 0x5401, 0x543d, 0x5440, + 0x542c, 0x542d, 0x543c, 0x542e, 0x5436, 0x5429, 0x541d, 0x544e, + 0x548f, 0x5475, 0x548e, 0x545f, 0x5471, 0x5477, 0x5470, 0x5492, + 0x547b, 0x5480, 0x5476, 0x5484, 0x5490, 0x5486, 0x54c7, 0x54a2, + 0x54b8, 0x54a5, 0x54ac, 0x54c4, 0x54c8, 0x54a8, + /* 0x53 */ + 0x54ab, 0x54c2, 0x54a4, 0x54be, 0x54bc, 0x54d8, 0x54e5, 0x54e6, + 0x550f, 0x5514, 0x54fd, 0x54ee, 0x54ed, 0x54fa, 0x54e2, 0x5539, + 0x5540, 0x5563, 0x554c, 0x552e, 0x555c, 0x5545, 0x5556, 0x5557, + 0x5538, 0x5533, 0x555d, 0x5599, 0x5580, 0x54af, 0x558a, 0x559f, + 0x557b, 0x557e, 0x5598, 0x559e, 0x55ae, 0x557c, 0x5583, 0x55a9, + 0x5587, 0x55a8, 0x55da, 0x55c5, 0x55df, 0x55c4, 0x55dc, 0x55e4, + 0x55d4, 0x5614, 0x55f7, 0x5616, 0x55fe, 0x55fd, 0x561b, 0x55f9, + 0x564e, 0x5650, 0x71df, 0x5634, 0x5636, 0x5632, 0x5638, 0x566b, + 0x5664, 0x562f, 0x566c, 0x566a, 0x5686, 0x5680, 0x568a, 0x56a0, + 0x5694, 0x568f, 0x56a5, 0x56ae, 0x56b6, 0x56b4, 0x56c2, 0x56bc, + 0x56c1, 0x56c3, 0x56c0, 0x56c8, 0x56ce, 0x56d1, 0x56d3, 0x56d7, + 0x56ee, 0x56f9, 0x5700, 0x56ff, 0x5704, 0x5709, + /* 0x54 */ + 0x5708, 0x570b, 0x570d, 0x5713, 0x5718, 0x5716, 0x55c7, 0x571c, + 0x5726, 0x5737, 0x5738, 0x574e, 0x573b, 0x5740, 0x574f, 0x5769, + 0x57c0, 0x5788, 0x5761, 0x577f, 0x5789, 0x5793, 0x57a0, 0x57b3, + 0x57a4, 0x57aa, 0x57b0, 0x57c3, 0x57c6, 0x57d4, 0x57d2, 0x57d3, + 0x580a, 0x57d6, 0x57e3, 0x580b, 0x5819, 0x581d, 0x5872, 0x5821, + 0x5862, 0x584b, 0x5870, 0x6bc0, 0x5852, 0x583d, 0x5879, 0x5885, + 0x58b9, 0x589f, 0x58ab, 0x58ba, 0x58de, 0x58bb, 0x58b8, 0x58ae, + 0x58c5, 0x58d3, 0x58d1, 0x58d7, 0x58d9, 0x58d8, 0x58e5, 0x58dc, + 0x58e4, 0x58df, 0x58ef, 0x58fa, 0x58f9, 0x58fb, 0x58fc, 0x58fd, + 0x5902, 0x590a, 0x5910, 0x591b, 0x68a6, 0x5925, 0x592c, 0x592d, + 0x5932, 0x5938, 0x593e, 0x7ad2, 0x5955, 0x5950, 0x594e, 0x595a, + 0x5958, 0x5962, 0x5960, 0x5967, 0x596c, 0x5969, + /* 0x55 */ + 0x5978, 0x5981, 0x599d, 0x4f5e, 0x4fab, 0x59a3, 0x59b2, 0x59c6, + 0x59e8, 0x59dc, 0x598d, 0x59d9, 0x59da, 0x5a25, 0x5a1f, 0x5a11, + 0x5a1c, 0x5a09, 0x5a1a, 0x5a40, 0x5a6c, 0x5a49, 0x5a35, 0x5a36, + 0x5a62, 0x5a6a, 0x5a9a, 0x5abc, 0x5abe, 0x5acb, 0x5ac2, 0x5abd, + 0x5ae3, 0x5ad7, 0x5ae6, 0x5ae9, 0x5ad6, 0x5afa, 0x5afb, 0x5b0c, + 0x5b0b, 0x5b16, 0x5b32, 0x5ad0, 0x5b2a, 0x5b36, 0x5b3e, 0x5b43, + 0x5b45, 0x5b40, 0x5b51, 0x5b55, 0x5b5a, 0x5b5b, 0x5b65, 0x5b69, + 0x5b70, 0x5b73, 0x5b75, 0x5b78, 0x6588, 0x5b7a, 0x5b80, 0x5b83, + 0x5ba6, 0x5bb8, 0x5bc3, 0x5bc7, 0x5bc9, 0x5bd4, 0x5bd0, 0x5be4, + 0x5be6, 0x5be2, 0x5bde, 0x5be5, 0x5beb, 0x5bf0, 0x5bf6, 0x5bf3, + 0x5c05, 0x5c07, 0x5c08, 0x5c0d, 0x5c13, 0x5c20, 0x5c22, 0x5c28, + 0x5c38, 0x5c39, 0x5c41, 0x5c46, 0x5c4e, 0x5c53, + /* 0x56 */ + 0x5c50, 0x5c4f, 0x5b71, 0x5c6c, 0x5c6e, 0x4e62, 0x5c76, 0x5c79, + 0x5c8c, 0x5c91, 0x5c94, 0x599b, 0x5cab, 0x5cbb, 0x5cb6, 0x5cbc, + 0x5cb7, 0x5cc5, 0x5cbe, 0x5cc7, 0x5cd9, 0x5ce9, 0x5cfd, 0x5cfa, + 0x5ced, 0x5d8c, 0x5cea, 0x5d0b, 0x5d15, 0x5d17, 0x5d5c, 0x5d1f, + 0x5d1b, 0x5d11, 0x5d14, 0x5d22, 0x5d1a, 0x5d19, 0x5d18, 0x5d4c, + 0x5d52, 0x5d4e, 0x5d4b, 0x5d6c, 0x5d73, 0x5d76, 0x5d87, 0x5d84, + 0x5d82, 0x5da2, 0x5d9d, 0x5dac, 0x5dae, 0x5dbd, 0x5d90, 0x5db7, + 0x5dbc, 0x5dc9, 0x5dcd, 0x5dd3, 0x5dd2, 0x5dd6, 0x5ddb, 0x5deb, + 0x5df2, 0x5df5, 0x5e0b, 0x5e1a, 0x5e19, 0x5e11, 0x5e1b, 0x5e36, + 0x5e37, 0x5e44, 0x5e43, 0x5e40, 0x5e4e, 0x5e57, 0x5e54, 0x5e5f, + 0x5e62, 0x5e64, 0x5e47, 0x5e75, 0x5e76, 0x5e7a, 0x9ebc, 0x5e7f, + 0x5ea0, 0x5ec1, 0x5ec2, 0x5ec8, 0x5ed0, 0x5ecf, + /* 0x57 */ + 0x5ed6, 0x5ee3, 0x5edd, 0x5eda, 0x5edb, 0x5ee2, 0x5ee1, 0x5ee8, + 0x5ee9, 0x5eec, 0x5ef1, 0x5ef3, 0x5ef0, 0x5ef4, 0x5ef8, 0x5efe, + 0x5f03, 0x5f09, 0x5f5d, 0x5f5c, 0x5f0b, 0x5f11, 0x5f16, 0x5f29, + 0x5f2d, 0x5f38, 0x5f41, 0x5f48, 0x5f4c, 0x5f4e, 0x5f2f, 0x5f51, + 0x5f56, 0x5f57, 0x5f59, 0x5f61, 0x5f6d, 0x5f73, 0x5f77, 0x5f83, + 0x5f82, 0x5f7f, 0x5f8a, 0x5f88, 0x5f91, 0x5f87, 0x5f9e, 0x5f99, + 0x5f98, 0x5fa0, 0x5fa8, 0x5fad, 0x5fbc, 0x5fd6, 0x5ffb, 0x5fe4, + 0x5ff8, 0x5ff1, 0x5fdd, 0x60b3, 0x5fff, 0x6021, 0x6060, 0x6019, + 0x6010, 0x6029, 0x600e, 0x6031, 0x601b, 0x6015, 0x602b, 0x6026, + 0x600f, 0x603a, 0x605a, 0x6041, 0x606a, 0x6077, 0x605f, 0x604a, + 0x6046, 0x604d, 0x6063, 0x6043, 0x6064, 0x6042, 0x606c, 0x606b, + 0x6059, 0x6081, 0x608d, 0x60e7, 0x6083, 0x609a, + /* 0x58 */ + 0x6084, 0x609b, 0x6096, 0x6097, 0x6092, 0x60a7, 0x608b, 0x60e1, + 0x60b8, 0x60e0, 0x60d3, 0x60b4, 0x5ff0, 0x60bd, 0x60c6, 0x60b5, + 0x60d8, 0x614d, 0x6115, 0x6106, 0x60f6, 0x60f7, 0x6100, 0x60f4, + 0x60fa, 0x6103, 0x6121, 0x60fb, 0x60f1, 0x610d, 0x610e, 0x6147, + 0x613e, 0x6128, 0x6127, 0x614a, 0x613f, 0x613c, 0x612c, 0x6134, + 0x613d, 0x6142, 0x6144, 0x6173, 0x6177, 0x6158, 0x6159, 0x615a, + 0x616b, 0x6174, 0x616f, 0x6165, 0x6171, 0x615f, 0x615d, 0x6153, + 0x6175, 0x6199, 0x6196, 0x6187, 0x61ac, 0x6194, 0x619a, 0x618a, + 0x6191, 0x61ab, 0x61ae, 0x61cc, 0x61ca, 0x61c9, 0x61f7, 0x61c8, + 0x61c3, 0x61c6, 0x61ba, 0x61cb, 0x7f79, 0x61cd, 0x61e6, 0x61e3, + 0x61f6, 0x61fa, 0x61f4, 0x61ff, 0x61fd, 0x61fc, 0x61fe, 0x6200, + 0x6208, 0x6209, 0x620d, 0x620c, 0x6214, 0x621b, + /* 0x59 */ + 0x621e, 0x6221, 0x622a, 0x622e, 0x6230, 0x6232, 0x6233, 0x6241, + 0x624e, 0x625e, 0x6263, 0x625b, 0x6260, 0x6268, 0x627c, 0x6282, + 0x6289, 0x627e, 0x6292, 0x6293, 0x6296, 0x62d4, 0x6283, 0x6294, + 0x62d7, 0x62d1, 0x62bb, 0x62cf, 0x62ff, 0x62c6, 0x64d4, 0x62c8, + 0x62dc, 0x62cc, 0x62ca, 0x62c2, 0x62c7, 0x629b, 0x62c9, 0x630c, + 0x62ee, 0x62f1, 0x6327, 0x6302, 0x6308, 0x62ef, 0x62f5, 0x6350, + 0x633e, 0x634d, 0x641c, 0x634f, 0x6396, 0x638e, 0x6380, 0x63ab, + 0x6376, 0x63a3, 0x638f, 0x6389, 0x639f, 0x63b5, 0x636b, 0x6369, + 0x63be, 0x63e9, 0x63c0, 0x63c6, 0x63e3, 0x63c9, 0x63d2, 0x63f6, + 0x63c4, 0x6416, 0x6434, 0x6406, 0x6413, 0x6426, 0x6436, 0x651d, + 0x6417, 0x6428, 0x640f, 0x6467, 0x646f, 0x6476, 0x644e, 0x652a, + 0x6495, 0x6493, 0x64a5, 0x64a9, 0x6488, 0x64bc, + /* 0x5a */ + 0x64da, 0x64d2, 0x64c5, 0x64c7, 0x64bb, 0x64d8, 0x64c2, 0x64f1, + 0x64e7, 0x8209, 0x64e0, 0x64e1, 0x62ac, 0x64e3, 0x64ef, 0x652c, + 0x64f6, 0x64f4, 0x64f2, 0x64fa, 0x6500, 0x64fd, 0x6518, 0x651c, + 0x6505, 0x6524, 0x6523, 0x652b, 0x6534, 0x6535, 0x6537, 0x6536, + 0x6538, 0x754b, 0x6548, 0x6556, 0x6555, 0x654d, 0x6558, 0x655e, + 0x655d, 0x6572, 0x6578, 0x6582, 0x6583, 0x8b8a, 0x659b, 0x659f, + 0x65ab, 0x65b7, 0x65c3, 0x65c6, 0x65c1, 0x65c4, 0x65cc, 0x65d2, + 0x65db, 0x65d9, 0x65e0, 0x65e1, 0x65f1, 0x6772, 0x660a, 0x6603, + 0x65fb, 0x6773, 0x6635, 0x6636, 0x6634, 0x661c, 0x664f, 0x6644, + 0x6649, 0x6641, 0x665e, 0x665d, 0x6664, 0x6667, 0x6668, 0x665f, + 0x6662, 0x6670, 0x6683, 0x6688, 0x668e, 0x6689, 0x6684, 0x6698, + 0x669d, 0x66c1, 0x66b9, 0x66c9, 0x66be, 0x66bc, + /* 0x5b */ + 0x66c4, 0x66b8, 0x66d6, 0x66da, 0x66e0, 0x663f, 0x66e6, 0x66e9, + 0x66f0, 0x66f5, 0x66f7, 0x670f, 0x6716, 0x671e, 0x6726, 0x6727, + 0x9738, 0x672e, 0x673f, 0x6736, 0x6741, 0x6738, 0x6737, 0x6746, + 0x675e, 0x6760, 0x6759, 0x6763, 0x6764, 0x6789, 0x6770, 0x67a9, + 0x677c, 0x676a, 0x678c, 0x678b, 0x67a6, 0x67a1, 0x6785, 0x67b7, + 0x67ef, 0x67b4, 0x67ec, 0x67b3, 0x67e9, 0x67b8, 0x67e4, 0x67de, + 0x67dd, 0x67e2, 0x67ee, 0x67b9, 0x67ce, 0x67c6, 0x67e7, 0x6a9c, + 0x681e, 0x6846, 0x6829, 0x6840, 0x684d, 0x6832, 0x684e, 0x68b3, + 0x682b, 0x6859, 0x6863, 0x6877, 0x687f, 0x689f, 0x688f, 0x68ad, + 0x6894, 0x689d, 0x689b, 0x6883, 0x6aae, 0x68b9, 0x6874, 0x68b5, + 0x68a0, 0x68ba, 0x690f, 0x688d, 0x687e, 0x6901, 0x68ca, 0x6908, + 0x68d8, 0x6922, 0x6926, 0x68e1, 0x690c, 0x68cd, + /* 0x5c */ + 0x68d4, 0x68e7, 0x68d5, 0x6936, 0x6912, 0x6904, 0x68d7, 0x68e3, + 0x6925, 0x68f9, 0x68e0, 0x68ef, 0x6928, 0x692a, 0x691a, 0x6923, + 0x6921, 0x68c6, 0x6979, 0x6977, 0x695c, 0x6978, 0x696b, 0x6954, + 0x697e, 0x696e, 0x6939, 0x6974, 0x693d, 0x6959, 0x6930, 0x6961, + 0x695e, 0x695d, 0x6981, 0x696a, 0x69b2, 0x69ae, 0x69d0, 0x69bf, + 0x69c1, 0x69d3, 0x69be, 0x69ce, 0x5be8, 0x69ca, 0x69dd, 0x69bb, + 0x69c3, 0x69a7, 0x6a2e, 0x6991, 0x69a0, 0x699c, 0x6995, 0x69b4, + 0x69de, 0x69e8, 0x6a02, 0x6a1b, 0x69ff, 0x6b0a, 0x69f9, 0x69f2, + 0x69e7, 0x6a05, 0x69b1, 0x6a1e, 0x69ed, 0x6a14, 0x69eb, 0x6a0a, + 0x6a12, 0x6ac1, 0x6a23, 0x6a13, 0x6a44, 0x6a0c, 0x6a72, 0x6a36, + 0x6a78, 0x6a47, 0x6a62, 0x6a59, 0x6a66, 0x6a48, 0x6a38, 0x6a22, + 0x6a90, 0x6a8d, 0x6aa0, 0x6a84, 0x6aa2, 0x6aa3, + /* 0x5d */ + 0x6a97, 0x8617, 0x6abb, 0x6ac3, 0x6ac2, 0x6ab8, 0x6ab3, 0x6aac, + 0x6ade, 0x6ad1, 0x6adf, 0x6aaa, 0x6ada, 0x6aea, 0x6afb, 0x6b05, + 0x8616, 0x6afa, 0x6b12, 0x6b16, 0x9b31, 0x6b1f, 0x6b38, 0x6b37, + 0x76dc, 0x6b39, 0x98ee, 0x6b47, 0x6b43, 0x6b49, 0x6b50, 0x6b59, + 0x6b54, 0x6b5b, 0x6b5f, 0x6b61, 0x6b78, 0x6b79, 0x6b7f, 0x6b80, + 0x6b84, 0x6b83, 0x6b8d, 0x6b98, 0x6b95, 0x6b9e, 0x6ba4, 0x6baa, + 0x6bab, 0x6baf, 0x6bb2, 0x6bb1, 0x6bb3, 0x6bb7, 0x6bbc, 0x6bc6, + 0x6bcb, 0x6bd3, 0x6bdf, 0x6bec, 0x6beb, 0x6bf3, 0x6bef, 0x9ebe, + 0x6c08, 0x6c13, 0x6c14, 0x6c1b, 0x6c24, 0x6c23, 0x6c5e, 0x6c55, + 0x6c62, 0x6c6a, 0x6c82, 0x6c8d, 0x6c9a, 0x6c81, 0x6c9b, 0x6c7e, + 0x6c68, 0x6c73, 0x6c92, 0x6c90, 0x6cc4, 0x6cf1, 0x6cd3, 0x6cbd, + 0x6cd7, 0x6cc5, 0x6cdd, 0x6cae, 0x6cb1, 0x6cbe, + /* 0x5e */ + 0x6cba, 0x6cdb, 0x6cef, 0x6cd9, 0x6cea, 0x6d1f, 0x884d, 0x6d36, + 0x6d2b, 0x6d3d, 0x6d38, 0x6d19, 0x6d35, 0x6d33, 0x6d12, 0x6d0c, + 0x6d63, 0x6d93, 0x6d64, 0x6d5a, 0x6d79, 0x6d59, 0x6d8e, 0x6d95, + 0x6fe4, 0x6d85, 0x6df9, 0x6e15, 0x6e0a, 0x6db5, 0x6dc7, 0x6de6, + 0x6db8, 0x6dc6, 0x6dec, 0x6dde, 0x6dcc, 0x6de8, 0x6dd2, 0x6dc5, + 0x6dfa, 0x6dd9, 0x6de4, 0x6dd5, 0x6dea, 0x6dee, 0x6e2d, 0x6e6e, + 0x6e2e, 0x6e19, 0x6e72, 0x6e5f, 0x6e3e, 0x6e23, 0x6e6b, 0x6e2b, + 0x6e76, 0x6e4d, 0x6e1f, 0x6e43, 0x6e3a, 0x6e4e, 0x6e24, 0x6eff, + 0x6e1d, 0x6e38, 0x6e82, 0x6eaa, 0x6e98, 0x6ec9, 0x6eb7, 0x6ed3, + 0x6ebd, 0x6eaf, 0x6ec4, 0x6eb2, 0x6ed4, 0x6ed5, 0x6e8f, 0x6ea5, + 0x6ec2, 0x6e9f, 0x6f41, 0x6f11, 0x704c, 0x6eec, 0x6ef8, 0x6efe, + 0x6f3f, 0x6ef2, 0x6f31, 0x6eef, 0x6f32, 0x6ecc, + /* 0x5f */ + 0x6f3e, 0x6f13, 0x6ef7, 0x6f86, 0x6f7a, 0x6f78, 0x6f81, 0x6f80, + 0x6f6f, 0x6f5b, 0x6ff3, 0x6f6d, 0x6f82, 0x6f7c, 0x6f58, 0x6f8e, + 0x6f91, 0x6fc2, 0x6f66, 0x6fb3, 0x6fa3, 0x6fa1, 0x6fa4, 0x6fb9, + 0x6fc6, 0x6faa, 0x6fdf, 0x6fd5, 0x6fec, 0x6fd4, 0x6fd8, 0x6ff1, + 0x6fee, 0x6fdb, 0x7009, 0x700b, 0x6ffa, 0x7011, 0x7001, 0x700f, + 0x6ffe, 0x701b, 0x701a, 0x6f74, 0x701d, 0x7018, 0x701f, 0x7030, + 0x703e, 0x7032, 0x7051, 0x7063, 0x7099, 0x7092, 0x70af, 0x70f1, + 0x70ac, 0x70b8, 0x70b3, 0x70ae, 0x70df, 0x70cb, 0x70dd, 0x70d9, + 0x7109, 0x70fd, 0x711c, 0x7119, 0x7165, 0x7155, 0x7188, 0x7166, + 0x7162, 0x714c, 0x7156, 0x716c, 0x718f, 0x71fb, 0x7184, 0x7195, + 0x71a8, 0x71ac, 0x71d7, 0x71b9, 0x71be, 0x71d2, 0x71c9, 0x71d4, + 0x71ce, 0x71e0, 0x71ec, 0x71e7, 0x71f5, 0x71fc, + /* 0x60 */ + 0x71f9, 0x71ff, 0x720d, 0x7210, 0x721b, 0x7228, 0x722d, 0x722c, + 0x7230, 0x7232, 0x723b, 0x723c, 0x723f, 0x7240, 0x7246, 0x724b, + 0x7258, 0x7274, 0x727e, 0x7282, 0x7281, 0x7287, 0x7292, 0x7296, + 0x72a2, 0x72a7, 0x72b9, 0x72b2, 0x72c3, 0x72c6, 0x72c4, 0x72ce, + 0x72d2, 0x72e2, 0x72e0, 0x72e1, 0x72f9, 0x72f7, 0x500f, 0x7317, + 0x730a, 0x731c, 0x7316, 0x731d, 0x7334, 0x732f, 0x7329, 0x7325, + 0x733e, 0x734e, 0x734f, 0x9ed8, 0x7357, 0x736a, 0x7368, 0x7370, + 0x7378, 0x7375, 0x737b, 0x737a, 0x73c8, 0x73b3, 0x73ce, 0x73bb, + 0x73c0, 0x73e5, 0x73ee, 0x73de, 0x74a2, 0x7405, 0x746f, 0x7425, + 0x73f8, 0x7432, 0x743a, 0x7455, 0x743f, 0x745f, 0x7459, 0x7441, + 0x745c, 0x7469, 0x7470, 0x7463, 0x746a, 0x7476, 0x747e, 0x748b, + 0x749e, 0x74a7, 0x74ca, 0x74cf, 0x74d4, 0x73f1, + /* 0x61 */ + 0x74e0, 0x74e3, 0x74e7, 0x74e9, 0x74ee, 0x74f2, 0x74f0, 0x74f1, + 0x74f8, 0x74f7, 0x7504, 0x7503, 0x7505, 0x750c, 0x750e, 0x750d, + 0x7515, 0x7513, 0x751e, 0x7526, 0x752c, 0x753c, 0x7544, 0x754d, + 0x754a, 0x7549, 0x755b, 0x7546, 0x755a, 0x7569, 0x7564, 0x7567, + 0x756b, 0x756d, 0x7578, 0x7576, 0x7586, 0x7587, 0x7574, 0x758a, + 0x7589, 0x7582, 0x7594, 0x759a, 0x759d, 0x75a5, 0x75a3, 0x75c2, + 0x75b3, 0x75c3, 0x75b5, 0x75bd, 0x75b8, 0x75bc, 0x75b1, 0x75cd, + 0x75ca, 0x75d2, 0x75d9, 0x75e3, 0x75de, 0x75fe, 0x75ff, 0x75fc, + 0x7601, 0x75f0, 0x75fa, 0x75f2, 0x75f3, 0x760b, 0x760d, 0x7609, + 0x761f, 0x7627, 0x7620, 0x7621, 0x7622, 0x7624, 0x7634, 0x7630, + 0x763b, 0x7647, 0x7648, 0x7646, 0x765c, 0x7658, 0x7661, 0x7662, + 0x7668, 0x7669, 0x766a, 0x7667, 0x766c, 0x7670, + /* 0x62 */ + 0x7672, 0x7676, 0x7678, 0x767c, 0x7680, 0x7683, 0x7688, 0x768b, + 0x768e, 0x7696, 0x7693, 0x7699, 0x769a, 0x76b0, 0x76b4, 0x76b8, + 0x76b9, 0x76ba, 0x76c2, 0x76cd, 0x76d6, 0x76d2, 0x76de, 0x76e1, + 0x76e5, 0x76e7, 0x76ea, 0x862f, 0x76fb, 0x7708, 0x7707, 0x7704, + 0x7729, 0x7724, 0x771e, 0x7725, 0x7726, 0x771b, 0x7737, 0x7738, + 0x7747, 0x775a, 0x7768, 0x776b, 0x775b, 0x7765, 0x777f, 0x777e, + 0x7779, 0x778e, 0x778b, 0x7791, 0x77a0, 0x779e, 0x77b0, 0x77b6, + 0x77b9, 0x77bf, 0x77bc, 0x77bd, 0x77bb, 0x77c7, 0x77cd, 0x77d7, + 0x77da, 0x77dc, 0x77e3, 0x77ee, 0x77fc, 0x780c, 0x7812, 0x7926, + 0x7820, 0x792a, 0x7845, 0x788e, 0x7874, 0x7886, 0x787c, 0x789a, + 0x788c, 0x78a3, 0x78b5, 0x78aa, 0x78af, 0x78d1, 0x78c6, 0x78cb, + 0x78d4, 0x78be, 0x78bc, 0x78c5, 0x78ca, 0x78ec, + /* 0x63 */ + 0x78e7, 0x78da, 0x78fd, 0x78f4, 0x7907, 0x7912, 0x7911, 0x7919, + 0x792c, 0x792b, 0x7940, 0x7960, 0x7957, 0x795f, 0x795a, 0x7955, + 0x7953, 0x797a, 0x797f, 0x798a, 0x799d, 0x79a7, 0x9f4b, 0x79aa, + 0x79ae, 0x79b3, 0x79b9, 0x79ba, 0x79c9, 0x79d5, 0x79e7, 0x79ec, + 0x79e1, 0x79e3, 0x7a08, 0x7a0d, 0x7a18, 0x7a19, 0x7a20, 0x7a1f, + 0x7980, 0x7a31, 0x7a3b, 0x7a3e, 0x7a37, 0x7a43, 0x7a57, 0x7a49, + 0x7a61, 0x7a62, 0x7a69, 0x9f9d, 0x7a70, 0x7a79, 0x7a7d, 0x7a88, + 0x7a97, 0x7a95, 0x7a98, 0x7a96, 0x7aa9, 0x7ac8, 0x7ab0, 0x7ab6, + 0x7ac5, 0x7ac4, 0x7abf, 0x9083, 0x7ac7, 0x7aca, 0x7acd, 0x7acf, + 0x7ad5, 0x7ad3, 0x7ad9, 0x7ada, 0x7add, 0x7ae1, 0x7ae2, 0x7ae6, + 0x7aed, 0x7af0, 0x7b02, 0x7b0f, 0x7b0a, 0x7b06, 0x7b33, 0x7b18, + 0x7b19, 0x7b1e, 0x7b35, 0x7b28, 0x7b36, 0x7b50, + /* 0x64 */ + 0x7b7a, 0x7b04, 0x7b4d, 0x7b0b, 0x7b4c, 0x7b45, 0x7b75, 0x7b65, + 0x7b74, 0x7b67, 0x7b70, 0x7b71, 0x7b6c, 0x7b6e, 0x7b9d, 0x7b98, + 0x7b9f, 0x7b8d, 0x7b9c, 0x7b9a, 0x7b8b, 0x7b92, 0x7b8f, 0x7b5d, + 0x7b99, 0x7bcb, 0x7bc1, 0x7bcc, 0x7bcf, 0x7bb4, 0x7bc6, 0x7bdd, + 0x7be9, 0x7c11, 0x7c14, 0x7be6, 0x7be5, 0x7c60, 0x7c00, 0x7c07, + 0x7c13, 0x7bf3, 0x7bf7, 0x7c17, 0x7c0d, 0x7bf6, 0x7c23, 0x7c27, + 0x7c2a, 0x7c1f, 0x7c37, 0x7c2b, 0x7c3d, 0x7c4c, 0x7c43, 0x7c54, + 0x7c4f, 0x7c40, 0x7c50, 0x7c58, 0x7c5f, 0x7c64, 0x7c56, 0x7c65, + 0x7c6c, 0x7c75, 0x7c83, 0x7c90, 0x7ca4, 0x7cad, 0x7ca2, 0x7cab, + 0x7ca1, 0x7ca8, 0x7cb3, 0x7cb2, 0x7cb1, 0x7cae, 0x7cb9, 0x7cbd, + 0x7cc0, 0x7cc5, 0x7cc2, 0x7cd8, 0x7cd2, 0x7cdc, 0x7ce2, 0x9b3b, + 0x7cef, 0x7cf2, 0x7cf4, 0x7cf6, 0x7cfa, 0x7d06, + /* 0x65 */ + 0x7d02, 0x7d1c, 0x7d15, 0x7d0a, 0x7d45, 0x7d4b, 0x7d2e, 0x7d32, + 0x7d3f, 0x7d35, 0x7d46, 0x7d73, 0x7d56, 0x7d4e, 0x7d72, 0x7d68, + 0x7d6e, 0x7d4f, 0x7d63, 0x7d93, 0x7d89, 0x7d5b, 0x7d8f, 0x7d7d, + 0x7d9b, 0x7dba, 0x7dae, 0x7da3, 0x7db5, 0x7dc7, 0x7dbd, 0x7dab, + 0x7e3d, 0x7da2, 0x7daf, 0x7ddc, 0x7db8, 0x7d9f, 0x7db0, 0x7dd8, + 0x7ddd, 0x7de4, 0x7dde, 0x7dfb, 0x7df2, 0x7de1, 0x7e05, 0x7e0a, + 0x7e23, 0x7e21, 0x7e12, 0x7e31, 0x7e1f, 0x7e09, 0x7e0b, 0x7e22, + 0x7e46, 0x7e66, 0x7e3b, 0x7e35, 0x7e39, 0x7e43, 0x7e37, 0x7e32, + 0x7e3a, 0x7e67, 0x7e5d, 0x7e56, 0x7e5e, 0x7e59, 0x7e5a, 0x7e79, + 0x7e6a, 0x7e69, 0x7e7c, 0x7e7b, 0x7e83, 0x7dd5, 0x7e7d, 0x8fae, + 0x7e7f, 0x7e88, 0x7e89, 0x7e8c, 0x7e92, 0x7e90, 0x7e93, 0x7e94, + 0x7e96, 0x7e8e, 0x7e9b, 0x7e9c, 0x7f38, 0x7f3a, + /* 0x66 */ + 0x7f45, 0x7f4c, 0x7f4d, 0x7f4e, 0x7f50, 0x7f51, 0x7f55, 0x7f54, + 0x7f58, 0x7f5f, 0x7f60, 0x7f68, 0x7f69, 0x7f67, 0x7f78, 0x7f82, + 0x7f86, 0x7f83, 0x7f88, 0x7f87, 0x7f8c, 0x7f94, 0x7f9e, 0x7f9d, + 0x7f9a, 0x7fa3, 0x7faf, 0x7fb2, 0x7fb9, 0x7fae, 0x7fb6, 0x7fb8, + 0x8b71, 0x7fc5, 0x7fc6, 0x7fca, 0x7fd5, 0x7fd4, 0x7fe1, 0x7fe6, + 0x7fe9, 0x7ff3, 0x7ff9, 0x98dc, 0x8006, 0x8004, 0x800b, 0x8012, + 0x8018, 0x8019, 0x801c, 0x8021, 0x8028, 0x803f, 0x803b, 0x804a, + 0x8046, 0x8052, 0x8058, 0x805a, 0x805f, 0x8062, 0x8068, 0x8073, + 0x8072, 0x8070, 0x8076, 0x8079, 0x807d, 0x807f, 0x8084, 0x8086, + 0x8085, 0x809b, 0x8093, 0x809a, 0x80ad, 0x5190, 0x80ac, 0x80db, + 0x80e5, 0x80d9, 0x80dd, 0x80c4, 0x80da, 0x80d6, 0x8109, 0x80ef, + 0x80f1, 0x811b, 0x8129, 0x8123, 0x812f, 0x814b, + /* 0x67 */ + 0x968b, 0x8146, 0x813e, 0x8153, 0x8151, 0x80fc, 0x8171, 0x816e, + 0x8165, 0x8166, 0x8174, 0x8183, 0x8188, 0x818a, 0x8180, 0x8182, + 0x81a0, 0x8195, 0x81a4, 0x81a3, 0x815f, 0x8193, 0x81a9, 0x81b0, + 0x81b5, 0x81be, 0x81b8, 0x81bd, 0x81c0, 0x81c2, 0x81ba, 0x81c9, + 0x81cd, 0x81d1, 0x81d9, 0x81d8, 0x81c8, 0x81da, 0x81df, 0x81e0, + 0x81e7, 0x81fa, 0x81fb, 0x81fe, 0x8201, 0x8202, 0x8205, 0x8207, + 0x820a, 0x820d, 0x8210, 0x8216, 0x8229, 0x822b, 0x8238, 0x8233, + 0x8240, 0x8259, 0x8258, 0x825d, 0x825a, 0x825f, 0x8264, 0x8262, + 0x8268, 0x826a, 0x826b, 0x822e, 0x8271, 0x8277, 0x8278, 0x827e, + 0x828d, 0x8292, 0x82ab, 0x829f, 0x82bb, 0x82ac, 0x82e1, 0x82e3, + 0x82df, 0x82d2, 0x82f4, 0x82f3, 0x82fa, 0x8393, 0x8303, 0x82fb, + 0x82f9, 0x82de, 0x8306, 0x82dc, 0x8309, 0x82d9, + /* 0x68 */ + 0x8335, 0x8334, 0x8316, 0x8332, 0x8331, 0x8340, 0x8339, 0x8350, + 0x8345, 0x832f, 0x832b, 0x8317, 0x8318, 0x8385, 0x839a, 0x83aa, + 0x839f, 0x83a2, 0x8396, 0x8323, 0x838e, 0x8387, 0x838a, 0x837c, + 0x83b5, 0x8373, 0x8375, 0x83a0, 0x8389, 0x83a8, 0x83f4, 0x8413, + 0x83eb, 0x83ce, 0x83fd, 0x8403, 0x83d8, 0x840b, 0x83c1, 0x83f7, + 0x8407, 0x83e0, 0x83f2, 0x840d, 0x8422, 0x8420, 0x83bd, 0x8438, + 0x8506, 0x83fb, 0x846d, 0x842a, 0x843c, 0x855a, 0x8484, 0x8477, + 0x846b, 0x84ad, 0x846e, 0x8482, 0x8469, 0x8446, 0x842c, 0x846f, + 0x8479, 0x8435, 0x84ca, 0x8462, 0x84b9, 0x84bf, 0x849f, 0x84d9, + 0x84cd, 0x84bb, 0x84da, 0x84d0, 0x84c1, 0x84c6, 0x84d6, 0x84a1, + 0x8521, 0x84ff, 0x84f4, 0x8517, 0x8518, 0x852c, 0x851f, 0x8515, + 0x8514, 0x84fc, 0x8540, 0x8563, 0x8558, 0x8548, + /* 0x69 */ + 0x8541, 0x8602, 0x854b, 0x8555, 0x8580, 0x85a4, 0x8588, 0x8591, + 0x858a, 0x85a8, 0x856d, 0x8594, 0x859b, 0x85ea, 0x8587, 0x859c, + 0x8577, 0x857e, 0x8590, 0x85c9, 0x85ba, 0x85cf, 0x85b9, 0x85d0, + 0x85d5, 0x85dd, 0x85e5, 0x85dc, 0x85f9, 0x860a, 0x8613, 0x860b, + 0x85fe, 0x85fa, 0x8606, 0x8622, 0x861a, 0x8630, 0x863f, 0x864d, + 0x4e55, 0x8654, 0x865f, 0x8667, 0x8671, 0x8693, 0x86a3, 0x86a9, + 0x86aa, 0x868b, 0x868c, 0x86b6, 0x86af, 0x86c4, 0x86c6, 0x86b0, + 0x86c9, 0x8823, 0x86ab, 0x86d4, 0x86de, 0x86e9, 0x86ec, 0x86df, + 0x86db, 0x86ef, 0x8712, 0x8706, 0x8708, 0x8700, 0x8703, 0x86fb, + 0x8711, 0x8709, 0x870d, 0x86f9, 0x870a, 0x8734, 0x873f, 0x8737, + 0x873b, 0x8725, 0x8729, 0x871a, 0x8760, 0x875f, 0x8778, 0x874c, + 0x874e, 0x8774, 0x8757, 0x8768, 0x876e, 0x8759, + /* 0x6a */ + 0x8753, 0x8763, 0x876a, 0x8805, 0x87a2, 0x879f, 0x8782, 0x87af, + 0x87cb, 0x87bd, 0x87c0, 0x87d0, 0x96d6, 0x87ab, 0x87c4, 0x87b3, + 0x87c7, 0x87c6, 0x87bb, 0x87ef, 0x87f2, 0x87e0, 0x880f, 0x880d, + 0x87fe, 0x87f6, 0x87f7, 0x880e, 0x87d2, 0x8811, 0x8816, 0x8815, + 0x8822, 0x8821, 0x8831, 0x8836, 0x8839, 0x8827, 0x883b, 0x8844, + 0x8842, 0x8852, 0x8859, 0x885e, 0x8862, 0x886b, 0x8881, 0x887e, + 0x889e, 0x8875, 0x887d, 0x88b5, 0x8872, 0x8882, 0x8897, 0x8892, + 0x88ae, 0x8899, 0x88a2, 0x888d, 0x88a4, 0x88b0, 0x88bf, 0x88b1, + 0x88c3, 0x88c4, 0x88d4, 0x88d8, 0x88d9, 0x88dd, 0x88f9, 0x8902, + 0x88fc, 0x88f4, 0x88e8, 0x88f2, 0x8904, 0x890c, 0x890a, 0x8913, + 0x8943, 0x891e, 0x8925, 0x892a, 0x892b, 0x8941, 0x8944, 0x893b, + 0x8936, 0x8938, 0x894c, 0x891d, 0x8960, 0x895e, + /* 0x6b */ + 0x8966, 0x8964, 0x896d, 0x896a, 0x896f, 0x8974, 0x8977, 0x897e, + 0x8983, 0x8988, 0x898a, 0x8993, 0x8998, 0x89a1, 0x89a9, 0x89a6, + 0x89ac, 0x89af, 0x89b2, 0x89ba, 0x89bd, 0x89bf, 0x89c0, 0x89da, + 0x89dc, 0x89dd, 0x89e7, 0x89f4, 0x89f8, 0x8a03, 0x8a16, 0x8a10, + 0x8a0c, 0x8a1b, 0x8a1d, 0x8a25, 0x8a36, 0x8a41, 0x8a5b, 0x8a52, + 0x8a46, 0x8a48, 0x8a7c, 0x8a6d, 0x8a6c, 0x8a62, 0x8a85, 0x8a82, + 0x8a84, 0x8aa8, 0x8aa1, 0x8a91, 0x8aa5, 0x8aa6, 0x8a9a, 0x8aa3, + 0x8ac4, 0x8acd, 0x8ac2, 0x8ada, 0x8aeb, 0x8af3, 0x8ae7, 0x8ae4, + 0x8af1, 0x8b14, 0x8ae0, 0x8ae2, 0x8af7, 0x8ade, 0x8adb, 0x8b0c, + 0x8b07, 0x8b1a, 0x8ae1, 0x8b16, 0x8b10, 0x8b17, 0x8b20, 0x8b33, + 0x97ab, 0x8b26, 0x8b2b, 0x8b3e, 0x8b28, 0x8b41, 0x8b4c, 0x8b4f, + 0x8b4e, 0x8b49, 0x8b56, 0x8b5b, 0x8b5a, 0x8b6b, + /* 0x6c */ + 0x8b5f, 0x8b6c, 0x8b6f, 0x8b74, 0x8b7d, 0x8b80, 0x8b8c, 0x8b8e, + 0x8b92, 0x8b93, 0x8b96, 0x8b99, 0x8b9a, 0x8c3a, 0x8c41, 0x8c3f, + 0x8c48, 0x8c4c, 0x8c4e, 0x8c50, 0x8c55, 0x8c62, 0x8c6c, 0x8c78, + 0x8c7a, 0x8c82, 0x8c89, 0x8c85, 0x8c8a, 0x8c8d, 0x8c8e, 0x8c94, + 0x8c7c, 0x8c98, 0x621d, 0x8cad, 0x8caa, 0x8cbd, 0x8cb2, 0x8cb3, + 0x8cae, 0x8cb6, 0x8cc8, 0x8cc1, 0x8ce4, 0x8ce3, 0x8cda, 0x8cfd, + 0x8cfa, 0x8cfb, 0x8d04, 0x8d05, 0x8d0a, 0x8d07, 0x8d0f, 0x8d0d, + 0x8d10, 0x9f4e, 0x8d13, 0x8ccd, 0x8d14, 0x8d16, 0x8d67, 0x8d6d, + 0x8d71, 0x8d73, 0x8d81, 0x8d99, 0x8dc2, 0x8dbe, 0x8dba, 0x8dcf, + 0x8dda, 0x8dd6, 0x8dcc, 0x8ddb, 0x8dcb, 0x8dea, 0x8deb, 0x8ddf, + 0x8de3, 0x8dfc, 0x8e08, 0x8e09, 0x8dff, 0x8e1d, 0x8e1e, 0x8e10, + 0x8e1f, 0x8e42, 0x8e35, 0x8e30, 0x8e34, 0x8e4a, + /* 0x6d */ + 0x8e47, 0x8e49, 0x8e4c, 0x8e50, 0x8e48, 0x8e59, 0x8e64, 0x8e60, + 0x8e2a, 0x8e63, 0x8e55, 0x8e76, 0x8e72, 0x8e7c, 0x8e81, 0x8e87, + 0x8e85, 0x8e84, 0x8e8b, 0x8e8a, 0x8e93, 0x8e91, 0x8e94, 0x8e99, + 0x8eaa, 0x8ea1, 0x8eac, 0x8eb0, 0x8ec6, 0x8eb1, 0x8ebe, 0x8ec5, + 0x8ec8, 0x8ecb, 0x8edb, 0x8ee3, 0x8efc, 0x8efb, 0x8eeb, 0x8efe, + 0x8f0a, 0x8f05, 0x8f15, 0x8f12, 0x8f19, 0x8f13, 0x8f1c, 0x8f1f, + 0x8f1b, 0x8f0c, 0x8f26, 0x8f33, 0x8f3b, 0x8f39, 0x8f45, 0x8f42, + 0x8f3e, 0x8f4c, 0x8f49, 0x8f46, 0x8f4e, 0x8f57, 0x8f5c, 0x8f62, + 0x8f63, 0x8f64, 0x8f9c, 0x8f9f, 0x8fa3, 0x8fad, 0x8faf, 0x8fb7, + 0x8fda, 0x8fe5, 0x8fe2, 0x8fea, 0x8fef, 0x9087, 0x8ff4, 0x9005, + 0x8ff9, 0x8ffa, 0x9011, 0x9015, 0x9021, 0x900d, 0x901e, 0x9016, + 0x900b, 0x9027, 0x9036, 0x9035, 0x9039, 0x8ff8, + /* 0x6e */ + 0x904f, 0x9050, 0x9051, 0x9052, 0x900e, 0x9049, 0x903e, 0x9056, + 0x9058, 0x905e, 0x9068, 0x906f, 0x9076, 0x96a8, 0x9072, 0x9082, + 0x907d, 0x9081, 0x9080, 0x908a, 0x9089, 0x908f, 0x90a8, 0x90af, + 0x90b1, 0x90b5, 0x90e2, 0x90e4, 0x6248, 0x90db, 0x9102, 0x9112, + 0x9119, 0x9132, 0x9130, 0x914a, 0x9156, 0x9158, 0x9163, 0x9165, + 0x9169, 0x9173, 0x9172, 0x918b, 0x9189, 0x9182, 0x91a2, 0x91ab, + 0x91af, 0x91aa, 0x91b5, 0x91b4, 0x91ba, 0x91c0, 0x91c1, 0x91c9, + 0x91cb, 0x91d0, 0x91d6, 0x91df, 0x91e1, 0x91db, 0x91fc, 0x91f5, + 0x91f6, 0x921e, 0x91ff, 0x9214, 0x922c, 0x9215, 0x9211, 0x925e, + 0x9257, 0x9245, 0x9249, 0x9264, 0x9248, 0x9295, 0x923f, 0x924b, + 0x9250, 0x929c, 0x9296, 0x9293, 0x929b, 0x925a, 0x92cf, 0x92b9, + 0x92b7, 0x92e9, 0x930f, 0x92fa, 0x9344, 0x932e, + /* 0x6f */ + 0x9319, 0x9322, 0x931a, 0x9323, 0x933a, 0x9335, 0x933b, 0x935c, + 0x9360, 0x937c, 0x936e, 0x9356, 0x93b0, 0x93ac, 0x93ad, 0x9394, + 0x93b9, 0x93d6, 0x93d7, 0x93e8, 0x93e5, 0x93d8, 0x93c3, 0x93dd, + 0x93d0, 0x93c8, 0x93e4, 0x941a, 0x9414, 0x9413, 0x9403, 0x9407, + 0x9410, 0x9436, 0x942b, 0x9435, 0x9421, 0x943a, 0x9441, 0x9452, + 0x9444, 0x945b, 0x9460, 0x9462, 0x945e, 0x946a, 0x9229, 0x9470, + 0x9475, 0x9477, 0x947d, 0x945a, 0x947c, 0x947e, 0x9481, 0x947f, + 0x9582, 0x9587, 0x958a, 0x9594, 0x9596, 0x9598, 0x9599, 0x95a0, + 0x95a8, 0x95a7, 0x95ad, 0x95bc, 0x95bb, 0x95b9, 0x95be, 0x95ca, + 0x6ff6, 0x95c3, 0x95cd, 0x95cc, 0x95d5, 0x95d4, 0x95d6, 0x95dc, + 0x95e1, 0x95e5, 0x95e2, 0x9621, 0x9628, 0x962e, 0x962f, 0x9642, + 0x964c, 0x964f, 0x964b, 0x9677, 0x965c, 0x965e, + /* 0x70 */ + 0x965d, 0x965f, 0x9666, 0x9672, 0x966c, 0x968d, 0x9698, 0x9695, + 0x9697, 0x96aa, 0x96a7, 0x96b1, 0x96b2, 0x96b0, 0x96b4, 0x96b6, + 0x96b8, 0x96b9, 0x96ce, 0x96cb, 0x96c9, 0x96cd, 0x894d, 0x96dc, + 0x970d, 0x96d5, 0x96f9, 0x9704, 0x9706, 0x9708, 0x9713, 0x970e, + 0x9711, 0x970f, 0x9716, 0x9719, 0x9724, 0x972a, 0x9730, 0x9739, + 0x973d, 0x973e, 0x9744, 0x9746, 0x9748, 0x9742, 0x9749, 0x975c, + 0x9760, 0x9764, 0x9766, 0x9768, 0x52d2, 0x976b, 0x9771, 0x9779, + 0x9785, 0x977c, 0x9781, 0x977a, 0x9786, 0x978b, 0x978f, 0x9790, + 0x979c, 0x97a8, 0x97a6, 0x97a3, 0x97b3, 0x97b4, 0x97c3, 0x97c6, + 0x97c8, 0x97cb, 0x97dc, 0x97ed, 0x9f4f, 0x97f2, 0x7adf, 0x97f6, + 0x97f5, 0x980f, 0x980c, 0x9838, 0x9824, 0x9821, 0x9837, 0x983d, + 0x9846, 0x984f, 0x984b, 0x986b, 0x986f, 0x9870, + /* 0x71 */ + 0x9871, 0x9874, 0x9873, 0x98aa, 0x98af, 0x98b1, 0x98b6, 0x98c4, + 0x98c3, 0x98c6, 0x98e9, 0x98eb, 0x9903, 0x9909, 0x9912, 0x9914, + 0x9918, 0x9921, 0x991d, 0x991e, 0x9924, 0x9920, 0x992c, 0x992e, + 0x993d, 0x993e, 0x9942, 0x9949, 0x9945, 0x9950, 0x994b, 0x9951, + 0x9952, 0x994c, 0x9955, 0x9997, 0x9998, 0x99a5, 0x99ad, 0x99ae, + 0x99bc, 0x99df, 0x99db, 0x99dd, 0x99d8, 0x99d1, 0x99ed, 0x99ee, + 0x99f1, 0x99f2, 0x99fb, 0x99f8, 0x9a01, 0x9a0f, 0x9a05, 0x99e2, + 0x9a19, 0x9a2b, 0x9a37, 0x9a45, 0x9a42, 0x9a40, 0x9a43, 0x9a3e, + 0x9a55, 0x9a4d, 0x9a5b, 0x9a57, 0x9a5f, 0x9a62, 0x9a65, 0x9a64, + 0x9a69, 0x9a6b, 0x9a6a, 0x9aad, 0x9ab0, 0x9abc, 0x9ac0, 0x9acf, + 0x9ad1, 0x9ad3, 0x9ad4, 0x9ade, 0x9adf, 0x9ae2, 0x9ae3, 0x9ae6, + 0x9aef, 0x9aeb, 0x9aee, 0x9af4, 0x9af1, 0x9af7, + /* 0x72 */ + 0x9afb, 0x9b06, 0x9b18, 0x9b1a, 0x9b1f, 0x9b22, 0x9b23, 0x9b25, + 0x9b27, 0x9b28, 0x9b29, 0x9b2a, 0x9b2e, 0x9b2f, 0x9b32, 0x9b44, + 0x9b43, 0x9b4f, 0x9b4d, 0x9b4e, 0x9b51, 0x9b58, 0x9b74, 0x9b93, + 0x9b83, 0x9b91, 0x9b96, 0x9b97, 0x9b9f, 0x9ba0, 0x9ba8, 0x9bb4, + 0x9bc0, 0x9bca, 0x9bb9, 0x9bc6, 0x9bcf, 0x9bd1, 0x9bd2, 0x9be3, + 0x9be2, 0x9be4, 0x9bd4, 0x9be1, 0x9c3a, 0x9bf2, 0x9bf1, 0x9bf0, + 0x9c15, 0x9c14, 0x9c09, 0x9c13, 0x9c0c, 0x9c06, 0x9c08, 0x9c12, + 0x9c0a, 0x9c04, 0x9c2e, 0x9c1b, 0x9c25, 0x9c24, 0x9c21, 0x9c30, + 0x9c47, 0x9c32, 0x9c46, 0x9c3e, 0x9c5a, 0x9c60, 0x9c67, 0x9c76, + 0x9c78, 0x9ce7, 0x9cec, 0x9cf0, 0x9d09, 0x9d08, 0x9ceb, 0x9d03, + 0x9d06, 0x9d2a, 0x9d26, 0x9daf, 0x9d23, 0x9d1f, 0x9d44, 0x9d15, + 0x9d12, 0x9d41, 0x9d3f, 0x9d3e, 0x9d46, 0x9d48, + /* 0x73 */ + 0x9d5d, 0x9d5e, 0x9d64, 0x9d51, 0x9d50, 0x9d59, 0x9d72, 0x9d89, + 0x9d87, 0x9dab, 0x9d6f, 0x9d7a, 0x9d9a, 0x9da4, 0x9da9, 0x9db2, + 0x9dc4, 0x9dc1, 0x9dbb, 0x9db8, 0x9dba, 0x9dc6, 0x9dcf, 0x9dc2, + 0x9dd9, 0x9dd3, 0x9df8, 0x9de6, 0x9ded, 0x9def, 0x9dfd, 0x9e1a, + 0x9e1b, 0x9e1e, 0x9e75, 0x9e79, 0x9e7d, 0x9e81, 0x9e88, 0x9e8b, + 0x9e8c, 0x9e92, 0x9e95, 0x9e91, 0x9e9d, 0x9ea5, 0x9ea9, 0x9eb8, + 0x9eaa, 0x9ead, 0x9761, 0x9ecc, 0x9ece, 0x9ecf, 0x9ed0, 0x9ed4, + 0x9edc, 0x9ede, 0x9edd, 0x9ee0, 0x9ee5, 0x9ee8, 0x9eef, 0x9ef4, + 0x9ef6, 0x9ef7, 0x9ef9, 0x9efb, 0x9efc, 0x9efd, 0x9f07, 0x9f08, + 0x76b7, 0x9f15, 0x9f21, 0x9f2c, 0x9f3e, 0x9f4a, 0x9f52, 0x9f54, + 0x9f63, 0x9f5f, 0x9f60, 0x9f61, 0x9f66, 0x9f67, 0x9f6c, 0x9f6a, + 0x9f77, 0x9f72, 0x9f76, 0x9f95, 0x9f9c, 0x9fa0, + /* 0x74 */ + 0x582f, 0x69c7, 0x9059, 0x7464, 0x51dc, 0x7199, +}; + +static int +jisx0208_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x21 && c1 <= 0x28) || (c1 >= 0x30 && c1 <= 0x74)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + unsigned short wc = 0xfffd; + if (i < 1410) { + if (i < 690) + wc = jisx0208_2uni_page21[i]; + } else { + if (i < 7808) + wc = jisx0208_2uni_page30[i-1410]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short jisx0208_2charset[6879] = { + 0x2171, 0x2172, 0x2178, 0x212f, 0x224c, 0x216b, 0x215e, 0x212d, + 0x2279, 0x215f, 0x2160, 0x2621, 0x2622, 0x2623, 0x2624, 0x2625, + 0x2626, 0x2627, 0x2628, 0x2629, 0x262a, 0x262b, 0x262c, 0x262d, + 0x262e, 0x262f, 0x2630, 0x2631, 0x2632, 0x2633, 0x2634, 0x2635, + 0x2636, 0x2637, 0x2638, 0x2641, 0x2642, 0x2643, 0x2644, 0x2645, + 0x2646, 0x2647, 0x2648, 0x2649, 0x264a, 0x264b, 0x264c, 0x264d, + 0x264e, 0x264f, 0x2650, 0x2651, 0x2652, 0x2653, 0x2654, 0x2655, + 0x2656, 0x2657, 0x2658, 0x2727, 0x2721, 0x2722, 0x2723, 0x2724, + 0x2725, 0x2726, 0x2728, 0x2729, 0x272a, 0x272b, 0x272c, 0x272d, + 0x272e, 0x272f, 0x2730, 0x2731, 0x2732, 0x2733, 0x2734, 0x2735, + 0x2736, 0x2737, 0x2738, 0x2739, 0x273a, 0x273b, 0x273c, 0x273d, + 0x273e, 0x273f, 0x2740, 0x2741, 0x2751, 0x2752, 0x2753, 0x2754, + 0x2755, 0x2756, 0x2758, 0x2759, 0x275a, 0x275b, 0x275c, 0x275d, + 0x275e, 0x275f, 0x2760, 0x2761, 0x2762, 0x2763, 0x2764, 0x2765, + 0x2766, 0x2767, 0x2768, 0x2769, 0x276a, 0x276b, 0x276c, 0x276d, + 0x276e, 0x276f, 0x2770, 0x2771, 0x2757, 0x213e, 0x213d, 0x2142, + 0x2146, 0x2147, 0x2148, 0x2149, 0x2277, 0x2278, 0x2145, 0x2144, + 0x2273, 0x216c, 0x216d, 0x2228, 0x216e, 0x2272, 0x222b, 0x222c, + 0x222a, 0x222d, 0x224d, 0x224e, 0x224f, 0x225f, 0x2250, 0x2260, + 0x223a, 0x223b, 0x215d, 0x2265, 0x2267, 0x2167, 0x225c, 0x224a, + 0x224b, 0x2241, 0x2240, 0x2269, 0x226a, 0x2168, 0x2268, 0x2266, + 0x2262, 0x2162, 0x2261, 0x2165, 0x2166, 0x2263, 0x2264, 0x223e, + 0x223f, 0x223c, 0x223d, 0x225d, 0x225e, 0x2821, 0x282c, 0x2822, + 0x282d, 0x2823, 0x282e, 0x2824, 0x282f, 0x2826, 0x2831, 0x2825, + 0x2830, 0x2827, 0x283c, 0x2837, 0x2832, 0x2829, 0x283e, 0x2839, + 0x2834, 0x2828, 0x2838, 0x283d, 0x2833, 0x282a, 0x283a, 0x283f, + 0x2835, 0x282b, 0x283b, 0x2840, 0x2836, 0x2223, 0x2222, 0x2225, + 0x2224, 0x2227, 0x2226, 0x2221, 0x217e, 0x217b, 0x217d, 0x217c, + 0x227e, 0x217a, 0x2179, 0x216a, 0x2169, 0x2276, 0x2275, 0x2274, + 0x2121, 0x2122, 0x2123, 0x2137, 0x2139, 0x213a, 0x213b, 0x2152, + 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, + 0x215b, 0x2229, 0x222e, 0x214c, 0x214d, 0x2141, 0x2421, 0x2422, + 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, 0x2428, 0x2429, 0x242a, + 0x242b, 0x242c, 0x242d, 0x242e, 0x242f, 0x2430, 0x2431, 0x2432, + 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, 0x2438, 0x2439, 0x243a, + 0x243b, 0x243c, 0x243d, 0x243e, 0x243f, 0x2440, 0x2441, 0x2442, + 0x2443, 0x2444, 0x2445, 0x2446, 0x2447, 0x2448, 0x2449, 0x244a, + 0x244b, 0x244c, 0x244d, 0x244e, 0x244f, 0x2450, 0x2451, 0x2452, + 0x2453, 0x2454, 0x2455, 0x2456, 0x2457, 0x2458, 0x2459, 0x245a, + 0x245b, 0x245c, 0x245d, 0x245e, 0x245f, 0x2460, 0x2461, 0x2462, + 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, 0x246a, + 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, 0x2470, 0x2471, 0x2472, + 0x2473, 0x212b, 0x212c, 0x2135, 0x2136, 0x2521, 0x2522, 0x2523, + 0x2524, 0x2525, 0x2526, 0x2527, 0x2528, 0x2529, 0x252a, 0x252b, + 0x252c, 0x252d, 0x252e, 0x252f, 0x2530, 0x2531, 0x2532, 0x2533, + 0x2534, 0x2535, 0x2536, 0x2537, 0x2538, 0x2539, 0x253a, 0x253b, + 0x253c, 0x253d, 0x253e, 0x253f, 0x2540, 0x2541, 0x2542, 0x2543, + 0x2544, 0x2545, 0x2546, 0x2547, 0x2548, 0x2549, 0x254a, 0x254b, + 0x254c, 0x254d, 0x254e, 0x254f, 0x2550, 0x2551, 0x2552, 0x2553, + 0x2554, 0x2555, 0x2556, 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, + 0x255c, 0x255d, 0x255e, 0x255f, 0x2560, 0x2561, 0x2562, 0x2563, + 0x2564, 0x2565, 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, + 0x256c, 0x256d, 0x256e, 0x256f, 0x2570, 0x2571, 0x2572, 0x2573, + 0x2574, 0x2575, 0x2576, 0x2126, 0x213c, 0x2133, 0x2134, 0x306c, + 0x437a, 0x3c37, 0x4b7c, 0x3e66, 0x3b30, 0x3e65, 0x323c, 0x4954, + 0x4d3f, 0x5022, 0x312f, 0x336e, 0x5023, 0x4024, 0x5242, 0x3556, + 0x4a3a, 0x3e67, 0x4e3e, 0x4a42, 0x5024, 0x4366, 0x5025, 0x367a, + 0x5026, 0x345d, 0x4330, 0x3c67, 0x5027, 0x5028, 0x5029, 0x4735, + 0x3557, 0x4737, 0x4663, 0x3843, 0x4b33, 0x6949, 0x502a, 0x3e68, + 0x502b, 0x3235, 0x3665, 0x3870, 0x4c69, 0x5626, 0x4d70, 0x467d, + 0x3425, 0x3535, 0x502c, 0x502d, 0x4e3b, 0x4d3d, 0x4168, 0x502f, + 0x3b76, 0x4673, 0x5032, 0x313e, 0x385f, 0x385e, 0x3066, 0x4f4b, + 0x4f4a, 0x3a33, 0x3021, 0x5033, 0x5034, 0x5035, 0x4b34, 0x5036, + 0x3872, 0x3067, 0x4b72, 0x357c, 0x357d, 0x357e, 0x4462, 0x4e3c, + 0x5037, 0x5038, 0x5039, 0x3f4d, 0x3d3a, 0x3f4e, 0x503e, 0x503c, + 0x503d, 0x3558, 0x3a23, 0x3270, 0x503b, 0x503a, 0x4a29, 0x3b46, + 0x3b45, 0x423e, 0x503f, 0x4955, 0x4067, 0x2138, 0x5040, 0x5042, + 0x4265, 0x4e61, 0x304a, 0x5041, 0x323e, 0x3644, 0x4367, 0x376f, + 0x5043, 0x4724, 0x346b, 0x5044, 0x304b, 0x3860, 0x346c, 0x497a, + 0x4832, 0x3559, 0x3271, 0x5067, 0x4541, 0x476c, 0x5046, 0x483c, + 0x4e62, 0x3f2d, 0x3b47, 0x3b77, 0x3240, 0x4451, 0x4322, 0x504a, + 0x304c, 0x4463, 0x3d3b, 0x3a34, 0x4d24, 0x424e, 0x323f, 0x5049, + 0x4d3e, 0x5045, 0x5047, 0x3a6e, 0x5048, 0x5524, 0x5050, 0x5053, + 0x5051, 0x3242, 0x4a3b, 0x504b, 0x504f, 0x3873, 0x3b48, 0x3426, + 0x5054, 0x504c, 0x4e63, 0x3b78, 0x504d, 0x5052, 0x5055, 0x504e, + 0x3621, 0x304d, 0x3622, 0x3241, 0x5525, 0x4b79, 0x496e, 0x3874, + 0x3f2f, 0x4e37, 0x4a58, 0x3738, 0x4225, 0x3264, 0x3d53, 0x5059, + 0x505e, 0x505c, 0x5057, 0x422f, 0x505a, 0x505d, 0x505b, 0x4a5d, + 0x5058, 0x3f2e, 0x4b73, 0x505f, 0x5060, 0x3d24, 0x506d, 0x4750, + 0x4936, 0x5068, 0x4a70, 0x3236, 0x506c, 0x5066, 0x506f, 0x4152, + 0x3844, 0x475c, 0x6047, 0x506e, 0x455d, 0x5063, 0x3876, 0x3875, + 0x5061, 0x3c5a, 0x5069, 0x4a6f, 0x434d, 0x5065, 0x3771, 0x5062, + 0x506a, 0x5064, 0x4e51, 0x506b, 0x4f41, 0x3666, 0x3770, 0x5070, + 0x5071, 0x5075, 0x304e, 0x4a50, 0x5074, 0x5073, 0x5077, 0x5076, + 0x4464, 0x3772, 0x5078, 0x3c45, 0x4226, 0x4465, 0x3676, 0x5079, + 0x3536, 0x507a, 0x507c, 0x4b35, 0x3766, 0x3b31, 0x4877, 0x507b, + 0x3a45, 0x4d43, 0x507e, 0x5123, 0x507d, 0x3a44, 0x3d7d, 0x3739, + 0x5124, 0x364f, 0x5121, 0x5122, 0x462f, 0x417c, 0x3623, 0x4b4d, + 0x5125, 0x4e3d, 0x5126, 0x5129, 0x5127, 0x414e, 0x5128, 0x512a, + 0x512c, 0x512b, 0x4a48, 0x3537, 0x512e, 0x512f, 0x322f, 0x512d, + 0x3c74, 0x5132, 0x5131, 0x5130, 0x5056, 0x5133, 0x3d7e, 0x5134, + 0x4d25, 0x4c59, 0x5136, 0x5135, 0x5138, 0x5137, 0x5139, 0x513a, + 0x3074, 0x3835, 0x373b, 0x3d3c, 0x437b, 0x3624, 0x4068, 0x3877, + 0x396e, 0x513c, 0x4c48, 0x4546, 0x3b79, 0x513b, 0x513d, 0x455e, + 0x3375, 0x513e, 0x467e, 0x4134, 0x5140, 0x5141, 0x482c, 0x3878, + 0x4f3b, 0x5142, 0x3626, 0x4a3c, 0x4236, 0x3671, 0x4535, 0x3773, + 0x5143, 0x5144, 0x4662, 0x315f, 0x5147, 0x3a7d, 0x5146, 0x3a46, + 0x5148, 0x666e, 0x5149, 0x4b41, 0x514a, 0x514b, 0x514c, 0x3e69, + 0x3c4c, 0x3427, 0x514f, 0x514d, 0x4c3d, 0x514e, 0x495a, 0x5150, + 0x5151, 0x5152, 0x455f, 0x5156, 0x5154, 0x5155, 0x5153, 0x3a63, + 0x5157, 0x4c6a, 0x4e64, 0x5158, 0x4028, 0x5159, 0x3d5a, 0x515a, + 0x437c, 0x4e3f, 0x4560, 0x5245, 0x515b, 0x7425, 0x3645, 0x515c, + 0x4b5e, 0x3d68, 0x427c, 0x515e, 0x4664, 0x515f, 0x5160, 0x332e, + 0x5161, 0x3627, 0x464c, 0x317a, 0x3d50, 0x4821, 0x5162, 0x4561, + 0x3f4f, 0x5163, 0x4a2c, 0x405a, 0x3422, 0x3429, 0x5164, 0x5166, + 0x373a, 0x5165, 0x4e73, 0x3d69, 0x483d, 0x4a4c, 0x5167, 0x4d78, + 0x5168, 0x5169, 0x457e, 0x516a, 0x4029, 0x3a7e, 0x3774, 0x516b, + 0x3b49, 0x396f, 0x4466, 0x516d, 0x4227, 0x3a6f, 0x516e, 0x516f, + 0x4130, 0x516c, 0x5171, 0x4b36, 0x3964, 0x5170, 0x3775, 0x3a5e, + 0x476d, 0x5174, 0x5172, 0x497b, 0x3e6a, 0x517b, 0x3364, 0x5175, + 0x5173, 0x414f, 0x5177, 0x5176, 0x3344, 0x3760, 0x517c, 0x4e2d, + 0x5178, 0x517d, 0x517a, 0x5179, 0x4e4f, 0x3879, 0x3243, 0x4e74, + 0x3d75, 0x4558, 0x3965, 0x5222, 0x5223, 0x4e65, 0x4f2b, 0x5225, + 0x387a, 0x5224, 0x332f, 0x5226, 0x4b56, 0x443c, 0x4d26, 0x4a59, + 0x5227, 0x7055, 0x4630, 0x5228, 0x342a, 0x4c33, 0x3e21, 0x5229, + 0x4a67, 0x522d, 0x402a, 0x522a, 0x3650, 0x522b, 0x342b, 0x372e, + 0x522e, 0x522f, 0x5230, 0x5231, 0x3c5b, 0x387b, 0x4c5e, 0x4c68, + 0x4677, 0x4a71, 0x5232, 0x5233, 0x5235, 0x5237, 0x5236, 0x5238, + 0x323d, 0x4b4c, 0x3a7c, 0x5239, 0x4159, 0x3e22, 0x3629, 0x523a, + 0x485b, 0x523b, 0x523c, 0x523d, 0x523e, 0x4924, 0x3668, 0x3065, + 0x463f, 0x523f, 0x3d3d, 0x4069, 0x5241, 0x5240, 0x3e23, 0x3861, + 0x5243, 0x483e, 0x5244, 0x485c, 0x4234, 0x426e, 0x3628, 0x466e, + 0x4331, 0x476e, 0x4b4e, 0x5246, 0x406a, 0x3735, 0x5247, 0x5248, + 0x312c, 0x3075, 0x346d, 0x4228, 0x3551, 0x4d71, 0x524b, 0x3237, + 0x524a, 0x362a, 0x524c, 0x4c71, 0x524d, 0x4e52, 0x387c, 0x3836, + 0x524e, 0x5250, 0x524f, 0x3f5f, 0x3139, 0x315e, 0x5251, 0x5252, + 0x3837, 0x5253, 0x356e, 0x3b32, 0x5254, 0x4b74, 0x3a35, 0x355a, + 0x4d27, 0x4150, 0x483f, 0x3c7d, 0x3d47, 0x3c68, 0x3c75, 0x3d76, + 0x4840, 0x5257, 0x3143, 0x4151, 0x387d, 0x3845, 0x3667, 0x525b, + 0x4321, 0x427e, 0x362b, 0x3e24, 0x525c, 0x525a, 0x3244, 0x4266, + 0x3c38, 0x3b4b, 0x3126, 0x3370, 0x3966, 0x3b4a, 0x525d, 0x525e, + 0x3549, 0x3346, 0x3967, 0x3548, 0x445f, 0x3125, 0x4631, 0x4c3e, + 0x3921, 0x4d79, 0x4547, 0x387e, 0x372f, 0x5267, 0x3663, 0x4b4a, + 0x485d, 0x5266, 0x345e, 0x5261, 0x5262, 0x5264, 0x5265, 0x355b, + 0x3f61, 0x4a2d, 0x5263, 0x525f, 0x3863, 0x5260, 0x4f24, 0x4a72, + 0x4468, 0x3862, 0x3970, 0x5268, 0x465d, 0x526c, 0x3c7e, 0x3c76, + 0x526f, 0x526d, 0x4c23, 0x526a, 0x5273, 0x526e, 0x5271, 0x3846, + 0x4c3f, 0x5272, 0x5274, 0x5276, 0x3a70, 0x4f42, 0x526b, 0x5269, + 0x5275, 0x5270, 0x5278, 0x5323, 0x527a, 0x527e, 0x5321, 0x527b, + 0x533e, 0x3a69, 0x3331, 0x5279, 0x5325, 0x3076, 0x5324, 0x3025, + 0x494a, 0x5322, 0x527c, 0x5277, 0x527d, 0x3a48, 0x5326, 0x3077, + 0x532f, 0x5327, 0x5328, 0x3e25, 0x4b69, 0x532d, 0x532c, 0x452f, + 0x532e, 0x532b, 0x3134, 0x3a36, 0x3f30, 0x5329, 0x4562, 0x532a, + 0x3022, 0x5334, 0x4d23, 0x3e27, 0x533a, 0x5339, 0x5330, 0x4243, + 0x5331, 0x426f, 0x5336, 0x3e26, 0x5333, 0x4c64, 0x373c, 0x5337, + 0x5338, 0x5335, 0x533b, 0x5332, 0x5341, 0x5346, 0x5342, 0x533d, + 0x5347, 0x4131, 0x5349, 0x3922, 0x533f, 0x437d, 0x5343, 0x533c, + 0x342d, 0x346e, 0x3365, 0x5344, 0x5340, 0x3776, 0x534a, 0x5348, + 0x4153, 0x354a, 0x362c, 0x5345, 0x3674, 0x3144, 0x534e, 0x534c, + 0x5427, 0x5351, 0x534b, 0x534f, 0x534d, 0x3b4c, 0x5350, 0x5353, + 0x5358, 0x5356, 0x5355, 0x4332, 0x3245, 0x5352, 0x5354, 0x3e28, + 0x3133, 0x5357, 0x325e, 0x5362, 0x3e7c, 0x535e, 0x535c, 0x535d, + 0x535f, 0x313d, 0x4139, 0x5359, 0x535a, 0x337a, 0x5361, 0x346f, + 0x5364, 0x5360, 0x5363, 0x4a2e, 0x4655, 0x4838, 0x5366, 0x5365, + 0x3345, 0x5367, 0x536a, 0x5369, 0x5368, 0x4739, 0x536b, 0x536c, + 0x536e, 0x536d, 0x5370, 0x5373, 0x5371, 0x536f, 0x5372, 0x5374, + 0x5375, 0x5376, 0x5377, 0x5378, 0x5145, 0x3c7c, 0x3b4d, 0x3273, + 0x3078, 0x4344, 0x5379, 0x3a24, 0x304f, 0x3f5e, 0x537a, 0x3847, + 0x3971, 0x537c, 0x537b, 0x4a60, 0x537d, 0x5421, 0x537e, 0x5422, + 0x5423, 0x3777, 0x3160, 0x5424, 0x5426, 0x5425, 0x5428, 0x455a, + 0x5429, 0x3035, 0x3a5f, 0x373d, 0x434f, 0x542a, 0x542b, 0x542d, + 0x542e, 0x3a64, 0x3651, 0x4b37, 0x542c, 0x542f, 0x3a41, 0x3923, + 0x5433, 0x3a25, 0x4333, 0x5430, 0x445a, 0x5434, 0x3f62, 0x5432, + 0x5435, 0x373f, 0x5436, 0x5437, 0x3924, 0x3340, 0x5439, 0x543a, + 0x543b, 0x5438, 0x5431, 0x543c, 0x543d, 0x4b64, 0x3e6b, 0x543f, + 0x5440, 0x543e, 0x5442, 0x4738, 0x3068, 0x4956, 0x5443, 0x3e7d, + 0x3c39, 0x475d, 0x3470, 0x3a6b, 0x4b59, 0x4632, 0x3778, 0x424f, + 0x5441, 0x5444, 0x4244, 0x5445, 0x5446, 0x5448, 0x4469, 0x342e, + 0x7421, 0x3161, 0x4a73, 0x3e6c, 0x4548, 0x3a66, 0x544e, 0x4a3d, + 0x4e5d, 0x3274, 0x544a, 0x413a, 0x544d, 0x4563, 0x4549, 0x4564, + 0x4839, 0x444d, 0x3a49, 0x5449, 0x3176, 0x4536, 0x544b, 0x5447, + 0x3f50, 0x544f, 0x3d4e, 0x362d, 0x5450, 0x4a68, 0x417d, 0x4446, + 0x5452, 0x4b4f, 0x5453, 0x5458, 0x4a2f, 0x5457, 0x5451, 0x5454, + 0x5456, 0x3a26, 0x4a49, 0x5459, 0x4345, 0x3275, 0x3e6d, 0x545b, + 0x545a, 0x3968, 0x545c, 0x545e, 0x545d, 0x5460, 0x5455, 0x5462, + 0x5461, 0x545f, 0x3b4e, 0x3f51, 0x4154, 0x5463, 0x403c, 0x306d, + 0x4764, 0x445b, 0x5465, 0x5464, 0x5466, 0x5467, 0x5468, 0x5469, + 0x4a51, 0x546a, 0x3246, 0x546b, 0x4d3c, 0x3330, 0x5249, 0x3d48, + 0x423f, 0x546c, 0x4c6b, 0x4c34, 0x546e, 0x4267, 0x4537, 0x4240, + 0x4957, 0x546f, 0x5470, 0x317b, 0x3c3a, 0x5471, 0x3050, 0x5472, + 0x5473, 0x3162, 0x3471, 0x4660, 0x4a74, 0x5477, 0x4155, 0x5476, + 0x3740, 0x4b5b, 0x5475, 0x4565, 0x5479, 0x5478, 0x547b, 0x547a, + 0x317c, 0x547c, 0x3e29, 0x547e, 0x4325, 0x547d, 0x4a33, 0x3d77, + 0x455b, 0x5521, 0x3925, 0x5522, 0x4721, 0x485e, 0x4c51, 0x4725, + 0x552b, 0x3538, 0x4d45, 0x4c2f, 0x562c, 0x5523, 0x5526, 0x4245, + 0x4b38, 0x454a, 0x5527, 0x4b65, 0x3a4a, 0x3e2a, 0x5528, 0x3b50, + 0x3b4f, 0x3039, 0x3848, 0x402b, 0x3051, 0x552c, 0x552d, 0x552a, + 0x3138, 0x342f, 0x5529, 0x4c45, 0x4931, 0x3028, 0x3079, 0x3b51, + 0x3052, 0x3023, 0x5532, 0x5530, 0x4c3c, 0x5533, 0x5531, 0x552f, + 0x3f31, 0x552e, 0x4a5a, 0x3864, 0x5537, 0x5538, 0x3e2b, 0x5534, + 0x4f2c, 0x474c, 0x5536, 0x3a27, 0x5539, 0x4958, 0x553a, 0x5535, + 0x4c3b, 0x475e, 0x553b, 0x4932, 0x553c, 0x5540, 0x553d, 0x3247, + 0x553f, 0x3c3b, 0x553e, 0x3779, 0x554c, 0x5545, 0x5542, 0x4364, + 0x5541, 0x5543, 0x5544, 0x5546, 0x5547, 0x3472, 0x5549, 0x5548, + 0x554a, 0x3e6e, 0x554d, 0x445c, 0x3145, 0x554b, 0x554e, 0x554f, + 0x5552, 0x5550, 0x5551, 0x3b52, 0x5553, 0x3926, 0x5554, 0x3b7a, + 0x4238, 0x5555, 0x5556, 0x3b5a, 0x3927, 0x4c52, 0x3528, 0x3849, + 0x5557, 0x3358, 0x5558, 0x4239, 0x5559, 0x5623, 0x555a, 0x555b, + 0x555c, 0x555e, 0x555f, 0x5560, 0x4270, 0x3127, 0x3c69, 0x3042, + 0x4157, 0x3430, 0x3c35, 0x3928, 0x4566, 0x3d21, 0x3431, 0x4368, + 0x446a, 0x3038, 0x3539, 0x4a75, 0x3c42, 0x3552, 0x406b, 0x3c3c, + 0x4d28, 0x5561, 0x355c, 0x3a4b, 0x3332, 0x3163, 0x3e2c, 0x3248, + 0x5562, 0x4d46, 0x3d49, 0x3c64, 0x5563, 0x3473, 0x4652, 0x4c29, + 0x5564, 0x5565, 0x4959, 0x5567, 0x3428, 0x3677, 0x5566, 0x3432, + 0x3f32, 0x556b, 0x3b21, 0x3249, 0x556a, 0x5568, 0x556c, 0x5569, + 0x472b, 0x5c4d, 0x3f33, 0x556d, 0x4e40, 0x556e, 0x5570, 0x437e, + 0x556f, 0x4023, 0x3b7b, 0x4250, 0x3c77, 0x4975, 0x406c, 0x3c4d, + 0x5571, 0x3e2d, 0x5572, 0x5573, 0x3053, 0x423a, 0x3f52, 0x5574, + 0x4633, 0x3e2e, 0x3e2f, 0x5575, 0x406d, 0x3e30, 0x5576, 0x5577, + 0x4c60, 0x5578, 0x3646, 0x3d22, 0x5579, 0x557a, 0x3c5c, 0x3f2c, + 0x4674, 0x3f54, 0x4878, 0x4722, 0x3649, 0x557b, 0x356f, 0x557c, + 0x367e, 0x464f, 0x3230, 0x3b53, 0x557d, 0x5622, 0x5621, 0x367d, + 0x557e, 0x4538, 0x4230, 0x454b, 0x3c48, 0x4158, 0x4d7a, 0x5624, + 0x5625, 0x4656, 0x3b33, 0x5627, 0x5628, 0x5629, 0x3474, 0x562a, + 0x562b, 0x322c, 0x413b, 0x3464, 0x562d, 0x4c28, 0x4252, 0x3359, + 0x562f, 0x5631, 0x345f, 0x562e, 0x5630, 0x5633, 0x5632, 0x5634, + 0x5635, 0x463d, 0x362e, 0x3265, 0x5636, 0x563b, 0x5639, 0x4a77, + 0x4a76, 0x4567, 0x5638, 0x3d54, 0x5637, 0x3f72, 0x563c, 0x3a6a, + 0x5642, 0x5643, 0x563d, 0x3333, 0x563e, 0x5647, 0x5646, 0x5645, + 0x5641, 0x5640, 0x5644, 0x4a78, 0x564b, 0x5648, 0x564a, 0x4d72, + 0x5649, 0x563f, 0x3f73, 0x564c, 0x3a37, 0x564d, 0x564e, 0x5651, + 0x5650, 0x564f, 0x4568, 0x563a, 0x5657, 0x5653, 0x5652, 0x5654, + 0x5655, 0x5658, 0x4e66, 0x5659, 0x5656, 0x565a, 0x3460, 0x565b, + 0x565d, 0x565c, 0x565e, 0x565f, 0x406e, 0x3d23, 0x3d64, 0x4163, + 0x3929, 0x3a38, 0x392a, 0x3570, 0x5660, 0x3a39, 0x384a, 0x5661, + 0x4c26, 0x4743, 0x5662, 0x392b, 0x342c, 0x4327, 0x3652, 0x3b54, + 0x495b, 0x4841, 0x5663, 0x3475, 0x5666, 0x4421, 0x5665, 0x5664, + 0x5667, 0x446b, 0x3f63, 0x3b55, 0x404a, 0x4253, 0x3522, 0x4422, + 0x5668, 0x5669, 0x3e6f, 0x4b39, 0x566c, 0x566b, 0x566a, 0x497d, + 0x5673, 0x4b5a, 0x566d, 0x566f, 0x4b6b, 0x566e, 0x5670, 0x4828, + 0x5671, 0x4a3e, 0x5672, 0x3433, 0x4a3f, 0x472f, 0x5674, 0x5675, + 0x392c, 0x3434, 0x5676, 0x3838, 0x4d44, 0x4d29, 0x3476, 0x5678, + 0x4423, 0x392d, 0x3e31, 0x485f, 0x3e32, 0x3d78, 0x446c, 0x4a79, + 0x4539, 0x392e, 0x495c, 0x5679, 0x4559, 0x3a42, 0x384b, 0x446d, + 0x3043, 0x3d6e, 0x392f, 0x4d47, 0x567a, 0x567b, 0x4751, 0x567c, + 0x4e77, 0x4f2d, 0x567e, 0x567d, 0x3347, 0x5721, 0x5724, 0x5725, + 0x5723, 0x4940, 0x3e33, 0x5727, 0x5726, 0x5722, 0x5728, 0x5729, + 0x572a, 0x572d, 0x572b, 0x572c, 0x572e, 0x3164, 0x446e, 0x572f, + 0x377a, 0x3276, 0x4736, 0x5730, 0x467b, 0x4a5b, 0x5731, 0x4f2e, + 0x5732, 0x4a40, 0x5735, 0x5021, 0x5031, 0x3c30, 0x4675, 0x5736, + 0x355d, 0x4424, 0x307a, 0x5737, 0x4a26, 0x3930, 0x4350, 0x446f, + 0x4c6f, 0x3839, 0x384c, 0x5738, 0x5739, 0x573f, 0x3c65, 0x4425, + 0x362f, 0x573a, 0x492b, 0x4346, 0x573b, 0x573c, 0x3630, 0x573d, + 0x573e, 0x5740, 0x4576, 0x5741, 0x5742, 0x5743, 0x5734, 0x5733, + 0x5744, 0x3741, 0x4927, 0x3a4c, 0x4937, 0x4426, 0x494b, 0x5745, + 0x3e34, 0x3146, 0x5746, 0x5747, 0x4c72, 0x4860, 0x574a, 0x317d, + 0x402c, 0x5749, 0x5748, 0x3742, 0x4254, 0x574e, 0x574c, 0x574b, + 0x4e27, 0x3865, 0x3d79, 0x574d, 0x454c, 0x3d3e, 0x4640, 0x5751, + 0x5750, 0x574f, 0x5752, 0x3866, 0x5753, 0x497c, 0x3d5b, 0x5754, + 0x4879, 0x4641, 0x4427, 0x4530, 0x5755, 0x352b, 0x3f34, 0x492c, + 0x3477, 0x4726, 0x5756, 0x3b56, 0x4b3a, 0x4b3b, 0x317e, 0x575b, + 0x4369, 0x5758, 0x3277, 0x582d, 0x575a, 0x4730, 0x5759, 0x5757, + 0x397a, 0x575d, 0x5763, 0x5769, 0x5761, 0x455c, 0x5766, 0x495d, + 0x5760, 0x5765, 0x4e67, 0x3b57, 0x4255, 0x575e, 0x355e, 0x5768, + 0x402d, 0x3165, 0x5762, 0x3278, 0x5767, 0x3631, 0x5764, 0x576a, + 0x576c, 0x5776, 0x5774, 0x5771, 0x5770, 0x4e78, 0x5772, 0x3632, + 0x3931, 0x3d7a, 0x5779, 0x576b, 0x576f, 0x575f, 0x327a, 0x5773, + 0x5775, 0x4351, 0x3a28, 0x3238, 0x576d, 0x5778, 0x5777, 0x3633, + 0x4229, 0x3366, 0x3743, 0x576e, 0x577a, 0x577d, 0x5821, 0x3c3d, + 0x5827, 0x4470, 0x577b, 0x5825, 0x3279, 0x5823, 0x5824, 0x577e, + 0x5822, 0x3867, 0x4d2a, 0x3435, 0x3159, 0x5826, 0x473a, 0x302d, + 0x4861, 0x575c, 0x582c, 0x5830, 0x4c65, 0x5829, 0x4569, 0x582e, + 0x3e70, 0x582f, 0x4657, 0x4f47, 0x582b, 0x5831, 0x397b, 0x404b, + 0x3054, 0x582a, 0x5828, 0x415a, 0x577c, 0x3b34, 0x4246, 0x583d, + 0x415b, 0x5838, 0x5835, 0x5836, 0x3c66, 0x5839, 0x583c, 0x5837, + 0x3d25, 0x583a, 0x5834, 0x4c7c, 0x4c7b, 0x583e, 0x583f, 0x3055, + 0x5833, 0x3672, 0x3026, 0x3436, 0x583b, 0x5843, 0x5842, 0x5847, + 0x5848, 0x5846, 0x5849, 0x5841, 0x5845, 0x584a, 0x584b, 0x5840, + 0x3b7c, 0x5844, 0x4256, 0x3932, 0x5832, 0x3f35, 0x5858, 0x4a69, + 0x584e, 0x584f, 0x5850, 0x5857, 0x5856, 0x4b7d, 0x3437, 0x5854, + 0x3745, 0x3334, 0x5851, 0x4e38, 0x5853, 0x3056, 0x5855, 0x584c, + 0x5852, 0x5859, 0x3744, 0x584d, 0x4d5d, 0x4d2b, 0x585c, 0x5860, + 0x417e, 0x4e79, 0x5861, 0x585e, 0x585b, 0x585a, 0x585f, 0x4a30, + 0x4634, 0x3746, 0x5862, 0x585d, 0x5863, 0x377b, 0x3231, 0x586b, + 0x3438, 0x5869, 0x586a, 0x3a29, 0x5868, 0x5866, 0x5865, 0x586c, + 0x5864, 0x586e, 0x327b, 0x5870, 0x586f, 0x4428, 0x5873, 0x5871, + 0x5867, 0x377c, 0x5872, 0x5876, 0x5875, 0x5877, 0x5874, 0x5878, + 0x5879, 0x587a, 0x4a6a, 0x587c, 0x587b, 0x3d3f, 0x402e, 0x3266, + 0x327c, 0x587d, 0x303f, 0x404c, 0x587e, 0x6c43, 0x5921, 0x3761, + 0x5922, 0x406f, 0x5923, 0x5924, 0x353a, 0x5925, 0x5926, 0x5927, + 0x4257, 0x384d, 0x4c61, 0x4b3c, 0x3d6a, 0x5928, 0x4070, 0x6e3d, + 0x4862, 0x3c6a, 0x3a4d, 0x5929, 0x4247, 0x4a27, 0x4271, 0x592c, + 0x592a, 0x592d, 0x592b, 0x592e, 0x4a31, 0x3037, 0x495e, 0x4863, + 0x592f, 0x5932, 0x3e35, 0x353b, 0x5930, 0x5937, 0x3e36, 0x5931, + 0x4744, 0x4d5e, 0x5933, 0x5934, 0x5938, 0x456a, 0x5935, 0x3933, + 0x405e, 0x5946, 0x4834, 0x4272, 0x4864, 0x5a2d, 0x4a7a, 0x4471, + 0x4b75, 0x593b, 0x3221, 0x436a, 0x5944, 0x4334, 0x593e, 0x5945, + 0x5940, 0x5947, 0x5943, 0x5942, 0x476f, 0x593c, 0x327d, 0x593a, + 0x3571, 0x4273, 0x5936, 0x5939, 0x3934, 0x405b, 0x3e37, 0x5941, + 0x4752, 0x3572, 0x3348, 0x3367, 0x3f21, 0x5949, 0x594e, 0x594a, + 0x377d, 0x594f, 0x3b22, 0x3969, 0x3d26, 0x593d, 0x3b7d, 0x594c, + 0x3b58, 0x594d, 0x3044, 0x5948, 0x4429, 0x3573, 0x3634, 0x594b, + 0x3027, 0x3a43, 0x3f36, 0x4472, 0x4854, 0x5951, 0x415e, 0x422a, + 0x3b2b, 0x5952, 0x5954, 0x5950, 0x4a61, 0x443d, 0x415c, 0x4a7b, + 0x3c4e, 0x5960, 0x595f, 0x3f78, 0x377e, 0x5959, 0x3e39, 0x4668, + 0x4731, 0x5957, 0x415d, 0x3c78, 0x595c, 0x3e38, 0x5956, 0x595b, + 0x4753, 0x5955, 0x3721, 0x335d, 0x595d, 0x4e2b, 0x3a4e, 0x4335, + 0x595a, 0x405c, 0x3935, 0x3f64, 0x3166, 0x413c, 0x5958, 0x3545, + 0x3747, 0x444f, 0x595e, 0x415f, 0x5961, 0x5963, 0x4237, 0x5969, + 0x5964, 0x5966, 0x4941, 0x4473, 0x5967, 0x4d2c, 0x4d48, 0x3439, + 0x302e, 0x5965, 0x5962, 0x3478, 0x3167, 0x5968, 0x4d49, 0x596c, + 0x423b, 0x5973, 0x596d, 0x596a, 0x5971, 0x5953, 0x596e, 0x5972, + 0x4842, 0x456b, 0x596b, 0x596f, 0x3748, 0x3a71, 0x405d, 0x5977, + 0x4526, 0x5974, 0x4b60, 0x5975, 0x5976, 0x4c4e, 0x4022, 0x3762, + 0x597d, 0x3b35, 0x597a, 0x5979, 0x4732, 0x4635, 0x4531, 0x597b, + 0x597c, 0x496f, 0x4745, 0x3b23, 0x4071, 0x4b50, 0x3349, 0x5a25, + 0x597e, 0x4d4a, 0x5a27, 0x5a23, 0x5a24, 0x4160, 0x5a22, 0x593f, + 0x5a26, 0x5a21, 0x5a2b, 0x5a2c, 0x4527, 0x5a2e, 0x3b24, 0x5a29, + 0x353c, 0x5a2f, 0x5a28, 0x5a33, 0x5a32, 0x5a31, 0x5a34, 0x5a36, + 0x3e71, 0x5a35, 0x5a39, 0x5a37, 0x5a38, 0x5970, 0x5a3b, 0x5a3a, + 0x5978, 0x5a3c, 0x5a30, 0x3b59, 0x5a3d, 0x5a3e, 0x5a40, 0x5a3f, + 0x5a41, 0x327e, 0x3936, 0x4a7c, 0x402f, 0x384e, 0x5a43, 0x5a46, + 0x4952, 0x355f, 0x5a45, 0x5a44, 0x4754, 0x5a47, 0x3635, 0x5a49, + 0x5a48, 0x343a, 0x3b36, 0x4658, 0x3749, 0x3f74, 0x5a4a, 0x4030, + 0x4528, 0x495f, 0x5a4b, 0x5a4c, 0x5a4d, 0x4a38, 0x555d, 0x4046, + 0x494c, 0x3a58, 0x4865, 0x4843, 0x454d, 0x4e41, 0x5a4f, 0x3c50, + 0x5a50, 0x3036, 0x3654, 0x404d, 0x4960, 0x5a51, 0x3b42, 0x4347, + 0x3b5b, 0x3f37, 0x5a52, 0x4a7d, 0x3177, 0x3b5c, 0x5a55, 0x5a53, + 0x5a56, 0x4e39, 0x5a54, 0x407b, 0x5a57, 0x4232, 0x5a58, 0x347a, + 0x5a5a, 0x5a59, 0x5a5b, 0x5a5c, 0x347b, 0x467c, 0x4336, 0x356c, + 0x3b5d, 0x4161, 0x3d5c, 0x3030, 0x5a5d, 0x3222, 0x5a61, 0x3937, + 0x5a60, 0x3a2b, 0x3e3a, 0x5a5f, 0x3e3b, 0x4c40, 0x3a2a, 0x3057, + 0x404e, 0x5a66, 0x4031, 0x3147, 0x3d55, 0x4b66, 0x3a72, 0x3e3c, + 0x4027, 0x5a65, 0x5a63, 0x5a64, 0x436b, 0x5b26, 0x5a6a, 0x3b7e, + 0x3938, 0x5a68, 0x5a69, 0x3f38, 0x5a67, 0x3b2f, 0x5a6c, 0x5a6b, + 0x5a70, 0x5a71, 0x5a6d, 0x3322, 0x5a6e, 0x5a6f, 0x4855, 0x4961, + 0x374a, 0x5a72, 0x4032, 0x3e3d, 0x4352, 0x3647, 0x5a73, 0x5a77, + 0x324b, 0x5a74, 0x5a76, 0x5a75, 0x3d6b, 0x4348, 0x3045, 0x5a78, + 0x5a79, 0x442a, 0x4e71, 0x3b43, 0x4a6b, 0x4b3d, 0x5b22, 0x5a7b, + 0x5a7e, 0x5a7d, 0x5a7a, 0x5b21, 0x465e, 0x5a7c, 0x5b23, 0x3d6c, + 0x5b24, 0x4d4b, 0x4778, 0x5b25, 0x5b27, 0x5b28, 0x5b29, 0x364a, + 0x3148, 0x3939, 0x5b2a, 0x5b2b, 0x3d71, 0x4162, 0x5258, 0x413e, + 0x413d, 0x4258, 0x3a47, 0x5072, 0x376e, 0x4d2d, 0x4a7e, 0x497e, + 0x5b2c, 0x3a73, 0x443f, 0x5b2d, 0x4f2f, 0x4b3e, 0x442b, 0x5b2e, + 0x347c, 0x5b2f, 0x5b30, 0x4c5a, 0x4c24, 0x4b76, 0x4b5c, 0x3b25, + 0x5b32, 0x3c6b, 0x4b51, 0x5b34, 0x5b37, 0x5b36, 0x3479, 0x3560, + 0x5b33, 0x5b35, 0x5b38, 0x3f79, 0x4d7b, 0x3049, 0x3a60, 0x423c, + 0x3c5d, 0x3e73, 0x5b3b, 0x454e, 0x5b39, 0x422b, 0x5b3a, 0x3e72, + 0x4c5d, 0x5b3c, 0x5b3d, 0x4d68, 0x5b42, 0x393a, 0x4755, 0x5b3f, + 0x456c, 0x5a5e, 0x5a62, 0x354f, 0x4747, 0x5b41, 0x3e3e, 0x4844, + 0x5b47, 0x487a, 0x5b3e, 0x5b44, 0x5b43, 0x404f, 0x4b6d, 0x4e53, + 0x4b67, 0x324c, 0x3b5e, 0x4f48, 0x5b46, 0x3f75, 0x5b45, 0x5b40, + 0x384f, 0x5b4c, 0x5b4a, 0x324d, 0x5b48, 0x5b4e, 0x5b54, 0x4248, + 0x4a41, 0x5b56, 0x4922, 0x5b55, 0x4770, 0x4b3f, 0x343b, 0x4077, + 0x3d40, 0x4453, 0x4d2e, 0x5b51, 0x5b50, 0x5b52, 0x5b4f, 0x5b57, + 0x5b4d, 0x5b4b, 0x5b53, 0x5b49, 0x436c, 0x4c78, 0x3c46, 0x3a74, + 0x3a3a, 0x4b6f, 0x3341, 0x444e, 0x464a, 0x3149, 0x4072, 0x4034, + 0x372a, 0x5b59, 0x393b, 0x337c, 0x5b5b, 0x3374, 0x5b61, 0x5b5e, + 0x4073, 0x334b, 0x3a2c, 0x334a, 0x3a4f, 0x5b5c, 0x3765, 0x374b, + 0x456d, 0x5b5a, 0x3046, 0x5b5d, 0x5b5f, 0x364d, 0x372c, 0x343c, + 0x354b, 0x5b62, 0x3a79, 0x4b71, 0x3b37, 0x5b63, 0x4930, 0x5b6f, + 0x3233, 0x5b64, 0x5b75, 0x5b65, 0x4e42, 0x5b6c, 0x475f, 0x5b74, + 0x5b67, 0x3034, 0x5b69, 0x393c, 0x5b6b, 0x5b6a, 0x5b66, 0x5b71, + 0x3e3f, 0x546d, 0x3868, 0x4d7c, 0x5b68, 0x4474, 0x3323, 0x3a2d, + 0x5b60, 0x5b70, 0x3361, 0x5b6e, 0x5b72, 0x456e, 0x347e, 0x5c32, + 0x4c49, 0x5b77, 0x347d, 0x5b7e, 0x4b40, 0x5c21, 0x5c23, 0x5c27, + 0x5b79, 0x432a, 0x456f, 0x5c2b, 0x5b7c, 0x5c28, 0x5c22, 0x3f39, + 0x5c2c, 0x4033, 0x5c2a, 0x343d, 0x4f50, 0x5b76, 0x5c26, 0x3058, + 0x5b78, 0x4c3a, 0x5b7d, 0x3f22, 0x4447, 0x5b73, 0x5c25, 0x3f7a, + 0x5c2f, 0x3371, 0x3821, 0x5c31, 0x5b7a, 0x5c30, 0x5c29, 0x5b7b, + 0x5c2d, 0x5c2e, 0x5c3f, 0x464e, 0x5c24, 0x5c3b, 0x5c3d, 0x4458, + 0x4d4c, 0x4976, 0x5c38, 0x424a, 0x5c3e, 0x413f, 0x5c35, 0x5c42, + 0x5c41, 0x466f, 0x5c40, 0x466a, 0x5c44, 0x5c37, 0x3648, 0x5c3a, + 0x3d5d, 0x4760, 0x5c3c, 0x364b, 0x5c34, 0x5c36, 0x5c33, 0x4f30, + 0x335a, 0x5c39, 0x5c43, 0x3335, 0x3a67, 0x315d, 0x5c54, 0x4f31, + 0x5c57, 0x3f3a, 0x5c56, 0x5c55, 0x5c52, 0x5c46, 0x5c63, 0x5c45, + 0x5c58, 0x5c50, 0x5c4b, 0x5c48, 0x5c49, 0x5c51, 0x7422, 0x5c4e, + 0x393d, 0x4448, 0x4164, 0x5c4c, 0x5c47, 0x5c4a, 0x4d4d, 0x4b6a, + 0x5c4f, 0x5c59, 0x5c61, 0x5c5a, 0x5c67, 0x5c65, 0x5c60, 0x5c5f, + 0x4450, 0x4165, 0x5c5d, 0x5c5b, 0x5c62, 0x5c68, 0x4875, 0x5c6e, + 0x5c69, 0x5c6c, 0x5c66, 0x4374, 0x4938, 0x5c5c, 0x5c64, 0x3e40, + 0x4c4f, 0x5c78, 0x5c6b, 0x3822, 0x3223, 0x335f, 0x5c53, 0x3e41, + 0x5c70, 0x5c77, 0x3c79, 0x3372, 0x432e, 0x5c6d, 0x5c72, 0x5c76, + 0x3636, 0x354c, 0x5c74, 0x3521, 0x464b, 0x5c73, 0x5c75, 0x5c6f, + 0x5c71, 0x3360, 0x4349, 0x5c7c, 0x5c7a, 0x3869, 0x5c79, 0x5d21, + 0x5b58, 0x5c7b, 0x5c7d, 0x5c7e, 0x5d2c, 0x5d28, 0x5b6d, 0x5d27, + 0x5d26, 0x5d23, 0x5c6a, 0x5d25, 0x5d24, 0x5d2a, 0x4f26, 0x5d2d, + 0x367b, 0x5d29, 0x5d2b, 0x4827, 0x5d2e, 0x5d32, 0x5d2f, 0x4d73, + 0x5d30, 0x5c5e, 0x5d33, 0x5d34, 0x3135, 0x5d36, 0x3767, 0x3c21, + 0x3655, 0x3224, 0x4d5f, 0x5d38, 0x5d37, 0x5d3a, 0x353d, 0x3656, + 0x343e, 0x5d3d, 0x5d3c, 0x5d3e, 0x324e, 0x4337, 0x5d3f, 0x343f, + 0x5d41, 0x5d40, 0x5d42, 0x5d43, 0x5d44, 0x3b5f, 0x4035, 0x3a21, + 0x4970, 0x4a62, 0x4f44, 0x3b75, 0x3a50, 0x4e72, 0x5d45, 0x5d46, + 0x3b60, 0x5d47, 0x5d48, 0x5d4a, 0x5d49, 0x4b58, 0x3d5e, 0x3c6c, + 0x3b44, 0x5d4b, 0x5d4d, 0x3f23, 0x5d4c, 0x5d4e, 0x5d4f, 0x5d50, + 0x5d51, 0x5d52, 0x5d54, 0x5d53, 0x5d55, 0x3225, 0x434a, 0x5d56, + 0x3b26, 0x334c, 0x5d57, 0x4542, 0x544c, 0x3523, 0x5d58, 0x5d59, + 0x4a6c, 0x4b68, 0x4647, 0x5d5a, 0x4866, 0x487b, 0x4c53, 0x5d5b, + 0x5d5d, 0x5d5c, 0x5d5f, 0x5d5e, 0x5d61, 0x3b61, 0x4c31, 0x5d62, + 0x5d63, 0x3524, 0x5d64, 0x5d66, 0x5d65, 0x3f65, 0x4939, 0x314a, + 0x4845, 0x4475, 0x3d41, 0x3561, 0x4846, 0x3c2e, 0x5d68, 0x3440, + 0x3178, 0x4672, 0x5d67, 0x393e, 0x4353, 0x5d69, 0x5d71, 0x5d6a, + 0x4241, 0x3562, 0x5d72, 0x3768, 0x3525, 0x5d70, 0x5d6e, 0x5d6b, + 0x4d60, 0x4440, 0x4659, 0x5d6c, 0x5d74, 0x5d73, 0x3723, 0x322d, + 0x3a3b, 0x5d6d, 0x5d6f, 0x4b57, 0x4274, 0x4b77, 0x5d7c, 0x5d7d, + 0x324f, 0x4a28, 0x4c7d, 0x5e21, 0x3c23, 0x3e42, 0x5d78, 0x5d7e, + 0x3168, 0x3637, 0x5d75, 0x5d7a, 0x4074, 0x4771, 0x4867, 0x5d77, + 0x4b21, 0x5d79, 0x5e24, 0x5e22, 0x5d7b, 0x4b22, 0x4748, 0x3563, + 0x4525, 0x436d, 0x5e25, 0x5e23, 0x4259, 0x5d76, 0x314b, 0x4d4e, + 0x5e30, 0x5e2f, 0x4076, 0x5e2c, 0x4d6c, 0x4636, 0x5e26, 0x4445, + 0x314c, 0x393f, 0x5e29, 0x3d27, 0x5e2e, 0x5e2d, 0x5e28, 0x5e2b, + 0x3368, 0x5e2a, 0x4749, 0x4e2e, 0x3e74, 0x4075, 0x5e36, 0x5e34, + 0x494d, 0x5e31, 0x5e33, 0x313a, 0x3940, 0x4f32, 0x333d, 0x4962, + 0x4d61, 0x3324, 0x3f3b, 0x5e35, 0x5e3a, 0x3e43, 0x4d30, 0x5e37, + 0x5e32, 0x5e38, 0x4e5e, 0x4573, 0x4642, 0x3336, 0x3155, 0x5e3e, + 0x5e41, 0x4e43, 0x4d64, 0x5e48, 0x5e42, 0x5e3f, 0x4e54, 0x5e45, + 0x3d4a, 0x5e47, 0x5e4c, 0x4571, 0x5e4a, 0x5e44, 0x4338, 0x5e4b, + 0x5e40, 0x5e46, 0x5e4d, 0x307c, 0x5e43, 0x5e4e, 0x3f3c, 0x3d5f, + 0x4a25, 0x3a2e, 0x5e3b, 0x5e49, 0x453a, 0x4036, 0x3369, 0x3a51, + 0x3e44, 0x5e3d, 0x3d42, 0x374c, 0x5e3c, 0x5e52, 0x3d6d, 0x383a, + 0x5e61, 0x5e5b, 0x3574, 0x454f, 0x5e56, 0x5e5f, 0x302f, 0x3132, + 0x3239, 0x5e58, 0x422c, 0x5e4f, 0x5e51, 0x3941, 0x5e62, 0x5e5d, + 0x5e55, 0x5e5c, 0x4c2b, 0x5e5a, 0x5e5e, 0x3850, 0x3e45, 0x4339, + 0x5e54, 0x4d2f, 0x5e57, 0x5e50, 0x4572, 0x5e53, 0x5e59, 0x4f51, + 0x3c3e, 0x4b7e, 0x5e63, 0x482e, 0x5e6f, 0x383b, 0x3d60, 0x5e65, + 0x4e2f, 0x3942, 0x5e72, 0x306e, 0x5e70, 0x5e64, 0x5e6a, 0x5e6c, + 0x4d4f, 0x5e67, 0x452e, 0x5e69, 0x5e71, 0x5e6b, 0x4c47, 0x5e66, + 0x3c22, 0x5e7e, 0x336a, 0x5e68, 0x5e6d, 0x5e6e, 0x426c, 0x425a, + 0x5e76, 0x5e7c, 0x5e7a, 0x4529, 0x5f23, 0x5e77, 0x5e78, 0x5e60, + 0x3579, 0x493a, 0x3c3f, 0x3977, 0x4f33, 0x5e74, 0x5f22, 0x3169, + 0x4166, 0x4779, 0x3441, 0x4e7a, 0x4c21, 0x4452, 0x5e7b, 0x5e7d, + 0x4132, 0x5f21, 0x5e79, 0x5e73, 0x3443, 0x3769, 0x5f2f, 0x5f2a, + 0x4078, 0x3363, 0x3d61, 0x5f33, 0x5f2c, 0x442c, 0x5f29, 0x4459, + 0x5f4c, 0x5f26, 0x5f25, 0x5f2e, 0x5f28, 0x5f27, 0x5f2d, 0x4021, + 0x5f24, 0x5f30, 0x5f31, 0x3442, 0x5f36, 0x5f35, 0x5f37, 0x5f3a, + 0x4543, 0x5f34, 0x5f38, 0x3763, 0x4279, 0x5f32, 0x473b, 0x5f39, + 0x5f3e, 0x5f3c, 0x5f3f, 0x5f42, 0x5f3b, 0x396a, 0x4728, 0x5e39, + 0x4d74, 0x5f3d, 0x5f41, 0x4275, 0x5f40, 0x5f2b, 0x6f69, 0x5f45, + 0x5f49, 0x5f47, 0x5f43, 0x5f44, 0x5f48, 0x5f46, 0x494e, 0x5f4e, + 0x5f4b, 0x5f4a, 0x5f4d, 0x4654, 0x5f4f, 0x4375, 0x426d, 0x4025, + 0x5f50, 0x5f52, 0x5f51, 0x5e75, 0x5f53, 0x4667, 0x5f54, 0x3250, + 0x4574, 0x3325, 0x3564, 0x3c5e, 0x3a52, 0x4f27, 0x3f66, 0x316a, + 0x5f56, 0x5f55, 0x5f59, 0x433a, 0x5f5c, 0x5f57, 0x5f5b, 0x5f5a, + 0x4540, 0x3059, 0x4e75, 0x5f5e, 0x3128, 0x5f60, 0x5f5f, 0x5f5d, + 0x5f58, 0x4b23, 0x5f62, 0x5f61, 0x316b, 0x5f64, 0x4a32, 0x5f63, + 0x4c35, 0x3e47, 0x4133, 0x3e46, 0x4e7b, 0x5f6a, 0x4079, 0x5f66, + 0x5f6b, 0x316c, 0x5f69, 0x4761, 0x5f65, 0x5f68, 0x3e48, 0x4851, + 0x5f6c, 0x3c51, 0x407a, 0x5f6f, 0x5f67, 0x3727, 0x5f6d, 0x4d50, + 0x5f70, 0x7426, 0x3d4f, 0x5f71, 0x5f72, 0x472e, 0x5f74, 0x5f75, + 0x4733, 0x4575, 0x5f77, 0x5f79, 0x4e55, 0x5f76, 0x5f78, 0x316d, + 0x5f73, 0x535b, 0x5f7a, 0x4167, 0x3b38, 0x5f7c, 0x5f7b, 0x3f24, + 0x5259, 0x5f7d, 0x6021, 0x5f6e, 0x5f7e, 0x6022, 0x477a, 0x6023, + 0x6024, 0x6025, 0x6026, 0x445e, 0x6028, 0x6027, 0x6029, 0x602a, + 0x3c5f, 0x4963, 0x4c6c, 0x602b, 0x602c, 0x4156, 0x3c24, 0x602d, + 0x602e, 0x602f, 0x4a52, 0x4847, 0x6030, 0x4757, 0x442d, 0x6031, + 0x3267, 0x356d, 0x4c46, 0x4c36, 0x3234, 0x4f34, 0x4b52, 0x4a2a, + 0x4037, 0x6032, 0x4643, 0x3823, 0x6033, 0x3a54, 0x6035, 0x6034, + 0x6036, 0x6037, 0x6038, 0x353e, 0x6039, 0x603a, 0x3824, 0x4848, + 0x603c, 0x3e75, 0x603b, 0x3638, 0x603d, 0x603f, 0x603e, 0x6040, + 0x3851, 0x6041, 0x3669, 0x4140, 0x397d, 0x6043, 0x6044, 0x6042, + 0x3c6d, 0x4648, 0x3639, 0x6046, 0x432c, 0x6045, 0x4f35, 0x4762, + 0x6049, 0x604b, 0x6048, 0x4c54, 0x604a, 0x604c, 0x4e44, 0x6050, + 0x604f, 0x4376, 0x472d, 0x3825, 0x604e, 0x604d, 0x4d31, 0x4d32, + 0x6051, 0x316e, 0x3976, 0x3b62, 0x6052, 0x6053, 0x6055, 0x3d43, + 0x6057, 0x6056, 0x6058, 0x334d, 0x605a, 0x6059, 0x605c, 0x605b, + 0x383c, 0x4e28, 0x364c, 0x3226, 0x366a, 0x3461, 0x4e68, 0x605e, + 0x6060, 0x6061, 0x3251, 0x605d, 0x3b39, 0x4441, 0x605f, 0x6064, + 0x3c6e, 0x6062, 0x373e, 0x4849, 0x6063, 0x607e, 0x6069, 0x383d, + 0x3565, 0x6066, 0x4d7d, 0x4e30, 0x4276, 0x6068, 0x606a, 0x4e56, + 0x3657, 0x487c, 0x474a, 0x606b, 0x606d, 0x6070, 0x606c, 0x606f, + 0x386a, 0x314d, 0x6071, 0x3f70, 0x606e, 0x4e5c, 0x6074, 0x7424, + 0x6072, 0x6075, 0x6067, 0x6073, 0x3a3c, 0x6076, 0x6077, 0x4d7e, + 0x6078, 0x6079, 0x6065, 0x607a, 0x3444, 0x3c25, 0x607b, 0x607c, + 0x607d, 0x313b, 0x6121, 0x493b, 0x6122, 0x3424, 0x6123, 0x6124, + 0x6125, 0x6127, 0x6128, 0x6126, 0x4953, 0x612a, 0x6129, 0x612c, + 0x612b, 0x612d, 0x612e, 0x6130, 0x612f, 0x3979, 0x6132, 0x6131, + 0x3445, 0x3f53, 0x453c, 0x6133, 0x4038, 0x3b3a, 0x3179, 0x6134, + 0x4d51, 0x4a63, 0x6135, 0x4544, 0x4d33, 0x3943, 0x3f3d, 0x434b, + 0x5234, 0x442e, 0x3268, 0x6136, 0x6137, 0x613c, 0x613a, 0x6139, + 0x5a42, 0x3326, 0x6138, 0x305a, 0x482a, 0x484a, 0x4e31, 0x613d, + 0x613b, 0x435c, 0x4026, 0x482b, 0x492d, 0x613f, 0x4e2c, 0x374d, + 0x6140, 0x613e, 0x4856, 0x6141, 0x6142, 0x305b, 0x3e76, 0x6147, + 0x6144, 0x466d, 0x6143, 0x3526, 0x614a, 0x6145, 0x6146, 0x6149, + 0x6148, 0x4925, 0x4142, 0x4141, 0x353f, 0x614b, 0x614c, 0x614d, + 0x614f, 0x614e, 0x3156, 0x6157, 0x4868, 0x6151, 0x6153, 0x6155, + 0x3f3e, 0x6156, 0x6154, 0x3c40, 0x6150, 0x6152, 0x4942, 0x3e49, + 0x6159, 0x6158, 0x615a, 0x3c26, 0x3a2f, 0x4577, 0x615b, 0x444b, + 0x615d, 0x4e21, 0x615c, 0x4169, 0x6162, 0x6164, 0x6165, 0x4354, + 0x6163, 0x6160, 0x615e, 0x615f, 0x6161, 0x6168, 0x6166, 0x6167, + 0x6169, 0x616b, 0x616c, 0x616d, 0x616e, 0x616a, 0x6170, 0x616f, + 0x6171, 0x4e45, 0x6174, 0x6172, 0x6173, 0x3462, 0x4c7e, 0x4a4a, + 0x6176, 0x6175, 0x6177, 0x6178, 0x617c, 0x6179, 0x617a, 0x617b, + 0x617d, 0x617e, 0x6221, 0x6222, 0x6223, 0x482f, 0x4550, 0x6224, + 0x4772, 0x4934, 0x6225, 0x6226, 0x452a, 0x3327, 0x3944, 0x6227, + 0x6228, 0x6229, 0x3b29, 0x622b, 0x622a, 0x622c, 0x622d, 0x4869, + 0x622e, 0x622f, 0x7369, 0x6230, 0x6231, 0x6232, 0x3b2e, 0x6233, + 0x4756, 0x4b5f, 0x314e, 0x3157, 0x6234, 0x6236, 0x6235, 0x4570, + 0x4039, 0x5d39, 0x6237, 0x4c41, 0x6238, 0x3446, 0x4857, 0x6239, + 0x623a, 0x623b, 0x4c5c, 0x4c55, 0x443e, 0x416a, 0x623d, 0x3d62, + 0x3e4a, 0x6240, 0x623f, 0x623e, 0x487d, 0x3447, 0x3829, 0x6246, + 0x6243, 0x3f3f, 0x4c32, 0x6242, 0x6244, 0x6245, 0x6241, 0x6247, + 0x6248, 0x442f, 0x3463, 0x4365, 0x6249, 0x624a, 0x624d, 0x3f67, + 0x4644, 0x624e, 0x4b53, 0x624b, 0x624c, 0x6251, 0x6250, 0x624f, + 0x6253, 0x6252, 0x6254, 0x6256, 0x6255, 0x4a4d, 0x3d56, 0x4e46, + 0x6257, 0x4637, 0x6258, 0x6259, 0x625d, 0x625b, 0x625c, 0x625a, + 0x625e, 0x625f, 0x6260, 0x6261, 0x4c37, 0x6262, 0x4c70, 0x6263, + 0x434e, 0x476a, 0x366b, 0x433b, 0x6264, 0x363a, 0x4050, 0x6265, + 0x3a3d, 0x6266, 0x6267, 0x3826, 0x3a55, 0x6269, 0x4556, 0x3a56, + 0x354e, 0x4b24, 0x474b, 0x4557, 0x395c, 0x626b, 0x3e4b, 0x4e32, + 0x3945, 0x3827, 0x4823, 0x626d, 0x626f, 0x386b, 0x626e, 0x4476, + 0x6271, 0x3337, 0x626c, 0x486a, 0x3130, 0x3a6c, 0x4f52, 0x6270, + 0x6272, 0x4a4b, 0x4059, 0x6274, 0x6275, 0x6273, 0x334e, 0x627b, + 0x627a, 0x3c27, 0x627c, 0x6277, 0x627d, 0x6278, 0x4858, 0x6276, + 0x6279, 0x6322, 0x6321, 0x4b61, 0x627e, 0x306b, 0x6324, 0x6323, + 0x3e4c, 0x6325, 0x4143, 0x6327, 0x6326, 0x6328, 0x6268, 0x626a, + 0x632a, 0x6329, 0x3c28, 0x4e69, 0x3c52, 0x632b, 0x3737, 0x3540, + 0x3527, 0x3b63, 0x4d34, 0x6331, 0x6330, 0x4144, 0x632d, 0x632f, + 0x3d4b, 0x3f40, 0x632e, 0x632c, 0x472a, 0x3e4d, 0x493c, 0x3a57, + 0x4578, 0x6332, 0x6333, 0x6349, 0x3658, 0x4f3d, 0x4135, 0x6334, + 0x3252, 0x4477, 0x4a21, 0x6335, 0x357a, 0x6336, 0x6338, 0x6339, + 0x4729, 0x633a, 0x633b, 0x633c, 0x3659, 0x3253, 0x4645, 0x3d28, + 0x3b64, 0x633d, 0x3d29, 0x324a, 0x4943, 0x633e, 0x486b, 0x4145, + 0x6341, 0x6342, 0x4769, 0x3f41, 0x633f, 0x4361, 0x6340, 0x3e4e, + 0x305c, 0x3529, 0x6343, 0x4478, 0x6344, 0x4047, 0x4c2d, 0x4923, + 0x6345, 0x6346, 0x4355, 0x4e47, 0x6348, 0x6347, 0x3c6f, 0x634a, + 0x3070, 0x634d, 0x634b, 0x3254, 0x374e, 0x634c, 0x3946, 0x3972, + 0x4a66, 0x634e, 0x4b54, 0x6350, 0x4051, 0x314f, 0x323a, 0x302c, + 0x634f, 0x6351, 0x6352, 0x3e77, 0x6353, 0x334f, 0x6355, 0x376a, + 0x3566, 0x6356, 0x3675, 0x6357, 0x407c, 0x464d, 0x4060, 0x3a75, + 0x6358, 0x4362, 0x416b, 0x635a, 0x635c, 0x6359, 0x635b, 0x3722, + 0x635d, 0x3726, 0x3567, 0x4d52, 0x635f, 0x6360, 0x312e, 0x6363, + 0x3376, 0x6362, 0x6361, 0x6365, 0x635e, 0x6366, 0x4e29, 0x6367, + 0x6368, 0x5474, 0x636a, 0x6369, 0x636b, 0x636c, 0x4e35, 0x636d, + 0x706f, 0x3e4f, 0x636e, 0x636f, 0x3d57, 0x4638, 0x6370, 0x4328, + 0x6371, 0x433c, 0x6372, 0x3625, 0x513f, 0x435d, 0x3c33, 0x3448, + 0x6373, 0x6422, 0x6376, 0x3568, 0x6375, 0x6424, 0x6374, 0x3e50, + 0x6378, 0x6379, 0x452b, 0x637a, 0x335e, 0x3f5a, 0x4964, 0x637c, + 0x4268, 0x6377, 0x637b, 0x637d, 0x3a7b, 0x6426, 0x492e, 0x4826, + 0x4579, 0x365a, 0x6425, 0x6423, 0x4835, 0x637e, 0x435e, 0x457b, + 0x457a, 0x3a76, 0x6438, 0x6428, 0x642a, 0x642d, 0x642e, 0x642b, + 0x642c, 0x6429, 0x6427, 0x6421, 0x4a4f, 0x3255, 0x6435, 0x6432, + 0x6437, 0x6436, 0x4773, 0x4c27, 0x3b3b, 0x6430, 0x6439, 0x6434, + 0x6433, 0x642f, 0x6431, 0x3449, 0x433d, 0x407d, 0x4822, 0x643e, + 0x4824, 0x4061, 0x643b, 0x484f, 0x643f, 0x4a53, 0x435b, 0x643a, + 0x643c, 0x643d, 0x6440, 0x3c44, 0x4646, 0x6445, 0x6444, 0x6441, + 0x4f36, 0x644a, 0x644e, 0x644b, 0x6447, 0x6448, 0x644d, 0x6442, + 0x5255, 0x6449, 0x6443, 0x644c, 0x6452, 0x344a, 0x644f, 0x6450, + 0x6451, 0x6454, 0x6453, 0x4876, 0x6455, 0x4e7c, 0x4a6d, 0x645a, + 0x6457, 0x6456, 0x4052, 0x6459, 0x645b, 0x6458, 0x645f, 0x645c, + 0x645d, 0x6446, 0x645e, 0x6460, 0x6461, 0x4a46, 0x6462, 0x4c62, + 0x364e, 0x3729, 0x6463, 0x4a34, 0x3f68, 0x4c30, 0x6464, 0x4e33, + 0x4774, 0x4146, 0x4734, 0x3d4d, 0x3040, 0x6469, 0x6467, 0x6465, + 0x3421, 0x3e51, 0x646a, 0x6468, 0x6466, 0x646e, 0x646d, 0x646c, + 0x646b, 0x646f, 0x6470, 0x403a, 0x6471, 0x6473, 0x6472, 0x3852, + 0x4138, 0x6475, 0x457c, 0x6474, 0x6476, 0x4a35, 0x416c, 0x3947, + 0x6477, 0x4e48, 0x6479, 0x647a, 0x647b, 0x647c, 0x3b65, 0x647d, + 0x374f, 0x356a, 0x352a, 0x6521, 0x4c73, 0x3948, 0x647e, 0x6524, + 0x4c66, 0x473c, 0x4933, 0x3d63, 0x6523, 0x3c53, 0x3949, 0x3b66, + 0x3569, 0x4a36, 0x6522, 0x4147, 0x4b42, 0x3a77, 0x3b67, 0x445d, + 0x6527, 0x4e5f, 0x3a59, 0x6528, 0x3f42, 0x652a, 0x3e52, 0x3a30, + 0x6529, 0x3d2a, 0x383e, 0x4148, 0x6525, 0x652b, 0x6526, 0x3750, + 0x652e, 0x6532, 0x376b, 0x652d, 0x6536, 0x394a, 0x4d6d, 0x303c, + 0x6533, 0x356b, 0x6530, 0x6531, 0x457d, 0x652f, 0x652c, 0x3328, + 0x4064, 0x3828, 0x6538, 0x6535, 0x6537, 0x6534, 0x3751, 0x4233, + 0x6539, 0x416e, 0x6546, 0x6542, 0x653c, 0x6540, 0x3c7a, 0x305d, + 0x653b, 0x6543, 0x6547, 0x394b, 0x4c56, 0x4456, 0x653d, 0x6545, + 0x653a, 0x433e, 0x653f, 0x303d, 0x4c4a, 0x653e, 0x365b, 0x486c, + 0x416d, 0x4e50, 0x3d6f, 0x656e, 0x6548, 0x407e, 0x6544, 0x6549, + 0x654b, 0x4479, 0x654e, 0x654a, 0x4a54, 0x344b, 0x4c4b, 0x305e, + 0x654d, 0x4e7d, 0x654c, 0x316f, 0x466c, 0x654f, 0x6556, 0x6550, + 0x6557, 0x6553, 0x477b, 0x3c4a, 0x6555, 0x6552, 0x6558, 0x6551, + 0x3d44, 0x4b25, 0x3d4c, 0x6554, 0x6560, 0x655c, 0x655f, 0x655d, + 0x6561, 0x655b, 0x6541, 0x4053, 0x484b, 0x655e, 0x6559, 0x4121, + 0x3752, 0x3d2b, 0x3f25, 0x4136, 0x6564, 0x6566, 0x6567, 0x6563, + 0x6565, 0x655a, 0x6562, 0x656a, 0x6569, 0x4b7a, 0x372b, 0x6568, + 0x656c, 0x656b, 0x656f, 0x6571, 0x3b3c, 0x656d, 0x6572, 0x6573, + 0x6574, 0x657a, 0x453b, 0x6576, 0x6575, 0x6577, 0x6578, 0x6579, + 0x657b, 0x657c, 0x344c, 0x657d, 0x657e, 0x6621, 0x6622, 0x6623, + 0x6624, 0x6625, 0x6626, 0x6628, 0x6627, 0x6629, 0x662a, 0x662b, + 0x662e, 0x662c, 0x662d, 0x3a61, 0x3753, 0x4356, 0x4833, 0x3d70, + 0x474d, 0x486d, 0x662f, 0x586d, 0x6630, 0x6632, 0x4d65, 0x6631, + 0x6634, 0x6633, 0x4d53, 0x6635, 0x487e, 0x6636, 0x6639, 0x6638, + 0x6637, 0x663a, 0x3732, 0x4122, 0x3541, 0x663e, 0x663b, 0x663c, + 0x663f, 0x6640, 0x663d, 0x3129, 0x3227, 0x6642, 0x6643, 0x6644, + 0x4d62, 0x3d2c, 0x6646, 0x6645, 0x3f69, 0x6647, 0x6648, 0x6649, + 0x3465, 0x344d, 0x664a, 0x664b, 0x4b5d, 0x4d63, 0x4d54, 0x4f37, + 0x394d, 0x664e, 0x3c54, 0x664d, 0x664f, 0x3c29, 0x4251, 0x6650, + 0x394c, 0x4c57, 0x6651, 0x6652, 0x6653, 0x6654, 0x6655, 0x3c2a, + 0x4c6d, 0x6657, 0x433f, 0x6656, 0x6659, 0x6658, 0x665a, 0x403b, + 0x665b, 0x665c, 0x4a39, 0x665d, 0x416f, 0x665e, 0x665f, 0x4e7e, + 0x6662, 0x6661, 0x6660, 0x4430, 0x6663, 0x3f26, 0x6664, 0x6665, + 0x4f38, 0x6666, 0x6667, 0x6669, 0x6668, 0x4825, 0x4679, 0x4f3e, + 0x4829, 0x666b, 0x3e53, 0x492a, 0x666c, 0x666a, 0x344e, 0x3854, + 0x3b68, 0x486e, 0x382a, 0x4b43, 0x666f, 0x666d, 0x394e, 0x394f, + 0x3069, 0x3a68, 0x4759, 0x305f, 0x6674, 0x4340, 0x4758, 0x425b, + 0x6676, 0x6672, 0x6675, 0x6670, 0x6673, 0x4b26, 0x3855, 0x307d, + 0x6671, 0x6678, 0x6679, 0x4639, 0x363b, 0x6726, 0x473d, 0x3b69, + 0x363c, 0x4048, 0x4f46, 0x4c2e, 0x6677, 0x4054, 0x3553, 0x667a, + 0x667c, 0x667b, 0x667d, 0x4326, 0x473e, 0x4431, 0x6723, 0x6722, + 0x667e, 0x3f55, 0x4965, 0x6725, 0x6724, 0x3950, 0x4f53, 0x6735, + 0x6729, 0x672a, 0x3c70, 0x6728, 0x3978, 0x6727, 0x672b, 0x4432, + 0x4a22, 0x4123, 0x425c, 0x672f, 0x6730, 0x672c, 0x672d, 0x672e, + 0x3951, 0x6736, 0x6732, 0x4966, 0x4b6c, 0x4928, 0x6731, 0x6734, + 0x6733, 0x4b44, 0x6737, 0x6738, 0x4137, 0x6739, 0x673b, 0x673f, + 0x673c, 0x673a, 0x473f, 0x673d, 0x673e, 0x3232, 0x6745, 0x6740, + 0x6741, 0x6742, 0x4221, 0x6744, 0x6743, 0x6746, 0x6747, 0x6748, + 0x3f43, 0x3269, 0x6749, 0x4e57, 0x3c2b, 0x3d2d, 0x3b6a, 0x4357, + 0x674a, 0x674b, 0x3131, 0x674c, 0x674d, 0x674e, 0x674f, 0x6750, + 0x363d, 0x5a2a, 0x6751, 0x4065, 0x6752, 0x3c4b, 0x6753, 0x5030, + 0x6754, 0x4a5e, 0x345c, 0x4124, 0x3d58, 0x4971, 0x3d2e, 0x6755, + 0x3952, 0x6756, 0x484c, 0x6764, 0x6758, 0x4249, 0x4775, 0x383f, + 0x6757, 0x4125, 0x6759, 0x447a, 0x675b, 0x675a, 0x675d, 0x675c, + 0x675e, 0x6760, 0x675f, 0x344f, 0x6761, 0x6762, 0x6763, 0x3a31, + 0x4e49, 0x6765, 0x3f27, 0x3170, 0x6766, 0x6767, 0x6768, 0x3072, + 0x6769, 0x676a, 0x4967, 0x3c47, 0x676c, 0x3329, 0x3032, 0x676b, + 0x676e, 0x474e, 0x3f44, 0x3256, 0x4b27, 0x375d, 0x365c, 0x676d, + 0x326a, 0x3423, 0x3171, 0x6772, 0x4e6a, 0x425d, 0x4944, 0x677e, + 0x3257, 0x677c, 0x677a, 0x6771, 0x676f, 0x6770, 0x3c63, 0x366c, + 0x4377, 0x4651, 0x3151, 0x6774, 0x6773, 0x6779, 0x6775, 0x6778, + 0x4c50, 0x6777, 0x3258, 0x337d, 0x677b, 0x677d, 0x3754, 0x6823, + 0x682c, 0x682d, 0x302b, 0x6834, 0x3071, 0x682b, 0x682a, 0x6825, + 0x6824, 0x6822, 0x6821, 0x4363, 0x427b, 0x6827, 0x6826, 0x6829, + 0x4170, 0x3755, 0x3141, 0x6828, 0x3953, 0x4171, 0x683a, 0x683b, + 0x3259, 0x322e, 0x6838, 0x682e, 0x6836, 0x683d, 0x6837, 0x6835, + 0x6776, 0x6833, 0x682f, 0x3450, 0x6831, 0x683c, 0x6832, 0x683e, + 0x6830, 0x477c, 0x4d69, 0x6839, 0x684f, 0x6847, 0x3f7b, 0x3546, + 0x365d, 0x6842, 0x325b, 0x3e54, 0x6845, 0x3a5a, 0x4551, 0x684a, + 0x4a6e, 0x6841, 0x325a, 0x3856, 0x4929, 0x684b, 0x683f, 0x6848, + 0x6852, 0x6843, 0x6844, 0x463a, 0x6849, 0x6846, 0x4b28, 0x684c, + 0x3060, 0x6840, 0x684e, 0x684d, 0x476b, 0x6854, 0x685f, 0x337e, + 0x6862, 0x6850, 0x6855, 0x4d6e, 0x685e, 0x4d55, 0x4e2a, 0x4378, + 0x336b, 0x4972, 0x6864, 0x4621, 0x3031, 0x685d, 0x6859, 0x4172, + 0x6853, 0x685b, 0x6860, 0x472c, 0x302a, 0x6858, 0x6861, 0x4978, + 0x685c, 0x6857, 0x3e55, 0x3d2f, 0x3c2c, 0x4c58, 0x4947, 0x6867, + 0x6870, 0x685a, 0x3377, 0x3e78, 0x6865, 0x686a, 0x4173, 0x6866, + 0x686d, 0x435f, 0x686e, 0x4d56, 0x6863, 0x3338, 0x6869, 0x686c, + 0x4c2c, 0x686f, 0x6868, 0x686b, 0x4b29, 0x4f21, 0x6873, 0x687a, + 0x6872, 0x3c43, 0x6851, 0x4a4e, 0x4c22, 0x6879, 0x6878, 0x6874, + 0x6875, 0x3136, 0x6877, 0x6871, 0x4455, 0x6876, 0x307e, 0x4222, + 0x4a43, 0x687b, 0x6921, 0x4859, 0x687e, 0x3e56, 0x3c49, 0x6923, + 0x363e, 0x6924, 0x4979, 0x687d, 0x6856, 0x687c, 0x4f4f, 0x4622, + 0x4973, 0x692b, 0x6931, 0x6932, 0x6925, 0x4776, 0x692f, 0x6927, + 0x6929, 0x6933, 0x6928, 0x692c, 0x3172, 0x4665, 0x692d, 0x6930, + 0x6926, 0x4126, 0x692a, 0x3b27, 0x3f45, 0x3730, 0x4c74, 0x4c79, + 0x3d72, 0x6937, 0x6935, 0x4f4e, 0x6934, 0x4d75, 0x6936, 0x6938, + 0x6939, 0x693c, 0x693a, 0x4623, 0x693b, 0x484d, 0x692e, 0x3d73, + 0x693d, 0x6942, 0x4174, 0x6941, 0x6922, 0x6943, 0x4149, 0x693e, + 0x6940, 0x693f, 0x5d31, 0x5d22, 0x6945, 0x6944, 0x4d76, 0x623c, + 0x6946, 0x6947, 0x6948, 0x3857, 0x3554, 0x694a, 0x515d, 0x3575, + 0x4e3a, 0x3673, 0x694b, 0x694c, 0x436e, 0x694d, 0x467a, 0x303a, + 0x3263, 0x6952, 0x6953, 0x694e, 0x3b3d, 0x694f, 0x4742, 0x6950, + 0x6951, 0x695b, 0x6955, 0x6958, 0x6954, 0x6956, 0x6957, 0x3c58, + 0x6959, 0x4341, 0x3756, 0x3342, 0x695c, 0x333f, 0x6961, 0x695d, + 0x6960, 0x483a, 0x695e, 0x695f, 0x4948, 0x485a, 0x6962, 0x427d, + 0x696c, 0x6968, 0x326b, 0x6966, 0x4b2a, 0x6967, 0x6964, 0x6965, + 0x696a, 0x696d, 0x696b, 0x6969, 0x6963, 0x4358, 0x6974, 0x4c2a, + 0x6972, 0x6973, 0x696e, 0x6970, 0x6971, 0x696f, 0x4066, 0x4f39, + 0x6978, 0x6979, 0x6a21, 0x3f2a, 0x697b, 0x697e, 0x6976, 0x6975, + 0x6a22, 0x325c, 0x697c, 0x6a23, 0x697d, 0x697a, 0x4433, 0x6977, + 0x4768, 0x6a27, 0x4d3b, 0x6a26, 0x6a25, 0x6a2e, 0x6a28, 0x6a30, + 0x4d66, 0x6a33, 0x6a2a, 0x6a2b, 0x6a2f, 0x6a32, 0x6a31, 0x6a29, + 0x6a2c, 0x6a3d, 0x6a36, 0x6a34, 0x6a35, 0x6a3a, 0x6a3b, 0x332a, + 0x3542, 0x6a39, 0x6a24, 0x6a38, 0x6a3c, 0x6a37, 0x6a3e, 0x6a40, + 0x6a3f, 0x6a42, 0x6a41, 0x695a, 0x6a46, 0x6a43, 0x6a44, 0x6a45, + 0x6a47, 0x376c, 0x6a49, 0x6a48, 0x3d30, 0x3954, 0x5e27, 0x6a4a, + 0x3d51, 0x3339, 0x6a4b, 0x3152, 0x3e57, 0x6a4c, 0x3955, 0x6a4d, + 0x3061, 0x493d, 0x6a4e, 0x3f6a, 0x6a55, 0x6a52, 0x436f, 0x6a53, + 0x6a50, 0x365e, 0x6a4f, 0x6a56, 0x3736, 0x425e, 0x6a5c, 0x6a58, + 0x4235, 0x6a57, 0x6a5a, 0x6a51, 0x6a5b, 0x6a5d, 0x486f, 0x6a59, + 0x6a5e, 0x6a60, 0x3853, 0x6a54, 0x3041, 0x6a5f, 0x3a5b, 0x4e76, + 0x6a61, 0x6a62, 0x4175, 0x4e22, 0x6a63, 0x4d35, 0x6a64, 0x6a65, + 0x4a64, 0x6a66, 0x3a40, 0x4e23, 0x6a6b, 0x6a6c, 0x3e58, 0x6a6a, + 0x4d67, 0x6a67, 0x6a69, 0x403d, 0x3f7e, 0x6a68, 0x6a6d, 0x4a23, + 0x6a6f, 0x6a6e, 0x336c, 0x4b2b, 0x6a70, 0x6a7c, 0x6a72, 0x6a73, + 0x6a74, 0x6a75, 0x6a79, 0x6a7a, 0x6a78, 0x6a76, 0x6a71, 0x6a77, + 0x6a7b, 0x7037, 0x3228, 0x6a7e, 0x365f, 0x6a7d, 0x6b22, 0x6b21, + 0x6b24, 0x6b23, 0x6b25, 0x3d31, 0x6b26, 0x6b27, 0x6b28, 0x403e, + 0x4d57, 0x6b29, 0x4a24, 0x4746, 0x6b2a, 0x6b2b, 0x382b, 0x352c, + 0x6b2c, 0x3b6b, 0x4741, 0x6b2d, 0x3350, 0x6b2e, 0x6b30, 0x4d77, + 0x6b2f, 0x3f46, 0x6b31, 0x6b32, 0x6b33, 0x3451, 0x6b34, 0x6b35, + 0x6b36, 0x6b37, 0x3351, 0x6b38, 0x6b39, 0x6b3a, 0x3272, 0x3f28, + 0x6b3b, 0x6b3c, 0x6b3d, 0x3840, 0x447b, 0x6b3e, 0x3757, 0x3f56, + 0x6b41, 0x4624, 0x6b40, 0x3731, 0x6b3f, 0x4277, 0x352d, 0x6b42, + 0x6b43, 0x3e59, 0x376d, 0x6b44, 0x4b2c, 0x405f, 0x3576, 0x4c75, + 0x414a, 0x6b45, 0x3f47, 0x4370, 0x3e5a, 0x6b46, 0x6b49, 0x6b4a, + 0x3a3e, 0x4242, 0x6b48, 0x3e5b, 0x493e, 0x6b47, 0x3b6c, 0x3153, + 0x6b4e, 0x3758, 0x3b6e, 0x3b6d, 0x4f4d, 0x6b4d, 0x6b4c, 0x4127, + 0x354d, 0x4f43, 0x333a, 0x3e5c, 0x6b4b, 0x6b50, 0x6b51, 0x6b4f, + 0x3858, 0x4d40, 0x3b6f, 0x4727, 0x6b54, 0x4040, 0x4342, 0x4d36, + 0x6b57, 0x386c, 0x403f, 0x6b53, 0x6b58, 0x386d, 0x6b55, 0x6b56, + 0x6b52, 0x4062, 0x4649, 0x432f, 0x325d, 0x4870, 0x3543, 0x4434, + 0x6b5b, 0x6b59, 0x434c, 0x4041, 0x3452, 0x6b5a, 0x3f5b, 0x4e4a, + 0x4f40, 0x6b5c, 0x6b67, 0x4435, 0x6b66, 0x6b63, 0x6b6b, 0x6b64, + 0x6b60, 0x447c, 0x6b5f, 0x6b5d, 0x4d21, 0x3b70, 0x6b61, 0x6b5e, + 0x6b65, 0x3d74, 0x3841, 0x427a, 0x4b45, 0x315a, 0x3062, 0x4625, + 0x6b69, 0x6b68, 0x4666, 0x6b6d, 0x6b62, 0x6b6c, 0x6b6e, 0x382c, + 0x6b6a, 0x3956, 0x3c55, 0x6b6f, 0x4d58, 0x6b72, 0x6b75, 0x6b73, + 0x4935, 0x6b70, 0x3660, 0x6b74, 0x6b76, 0x6b7a, 0x6b77, 0x6b79, + 0x6b78, 0x6b7b, 0x3c31, 0x6b7d, 0x6b7c, 0x4968, 0x6c21, 0x3759, + 0x6b7e, 0x6c22, 0x6c23, 0x3544, 0x6641, 0x3e79, 0x6c24, 0x386e, + 0x6c25, 0x6c26, 0x3b3e, 0x5a4e, 0x6c27, 0x6c28, 0x3d32, 0x6c29, + 0x6c2a, 0x6c2b, 0x6c2c, 0x6c2d, 0x432b, 0x6c2e, 0x6c30, 0x6c2f, + 0x4626, 0x6c31, 0x4b2d, 0x6c32, 0x6c33, 0x6c34, 0x6c35, 0x465a, + 0x3e5d, 0x6c36, 0x396b, 0x502e, 0x6c37, 0x6c38, 0x493f, 0x6c39, + 0x6c41, 0x6c3a, 0x6c3c, 0x6c3b, 0x6c3d, 0x4b46, 0x6c3e, 0x6c3f, + 0x6c40, 0x6c42, 0x332d, 0x4467, 0x4969, 0x3a62, 0x3957, 0x494f, + 0x325f, 0x484e, 0x6c45, 0x3453, 0x4055, 0x6c44, 0x6c49, 0x4379, + 0x4c63, 0x6c47, 0x6c48, 0x352e, 0x6c4a, 0x4763, 0x425f, 0x4871, + 0x453d, 0x6c46, 0x4b47, 0x326c, 0x6c4c, 0x4f28, 0x4442, 0x4f45, + 0x3b71, 0x6c4b, 0x4231, 0x6c5c, 0x4128, 0x4678, 0x4950, 0x6c4f, + 0x3b3f, 0x3b72, 0x3e5e, 0x4765, 0x382d, 0x6c4e, 0x6c4d, 0x496a, + 0x3c41, 0x4552, 0x6c51, 0x6c52, 0x3958, 0x6c50, 0x6c53, 0x6c54, + 0x6c56, 0x4223, 0x6c55, 0x3466, 0x6c58, 0x6c57, 0x6c59, 0x6c5b, + 0x6c5d, 0x6c5e, 0x4056, 0x3c4f, 0x6c5f, 0x3352, 0x6c60, 0x4176, + 0x6c61, 0x6c62, 0x496b, 0x352f, 0x6c63, 0x4436, 0x315b, 0x6c64, + 0x3c71, 0x3f76, 0x422d, 0x6c67, 0x6c66, 0x6c65, 0x6c6d, 0x6c6b, + 0x6c68, 0x6c6a, 0x6c69, 0x6c6c, 0x3577, 0x6c70, 0x4057, 0x6c71, + 0x3859, 0x6c6e, 0x6c6f, 0x4f29, 0x4437, 0x4129, 0x6c72, 0x6c75, + 0x6c73, 0x6c74, 0x4d59, 0x4627, 0x6c78, 0x6c76, 0x6c77, 0x6c79, + 0x6d29, 0x6c7c, 0x6c7d, 0x6c7b, 0x6c7a, 0x447d, 0x6d21, 0x6d25, + 0x6d22, 0x6c7e, 0x6d23, 0x6d24, 0x6d2b, 0x6d26, 0x4058, 0x6d28, + 0x6d2a, 0x6d27, 0x6d2d, 0x3d33, 0x6d2c, 0x6d2e, 0x6d2f, 0x6d32, + 0x6d31, 0x6d30, 0x6d34, 0x6d33, 0x4c76, 0x6d36, 0x6d35, 0x6d37, + 0x6d38, 0x6d3a, 0x6d39, 0x3f48, 0x6d3b, 0x366d, 0x6d3c, 0x6d3e, + 0x6d3f, 0x6d40, 0x6d3d, 0x6d41, 0x3c56, 0x6d42, 0x3530, 0x3733, + 0x382e, 0x6d43, 0x4670, 0x453e, 0x6d44, 0x6d47, 0x3c34, 0x6d46, + 0x6d45, 0x375a, 0x6d48, 0x3353, 0x6d4a, 0x3a5c, 0x6d49, 0x6d52, + 0x6d4c, 0x6d4e, 0x4a65, 0x6d4b, 0x6d4d, 0x6d51, 0x6d4f, 0x3531, + 0x6d50, 0x6d53, 0x475a, 0x4e58, 0x3d34, 0x6d54, 0x4d22, 0x6d56, + 0x6d55, 0x6d59, 0x4d41, 0x6d58, 0x336d, 0x6d57, 0x6d5c, 0x6d5b, + 0x6d5a, 0x4532, 0x6d5d, 0x6d5e, 0x6d5f, 0x396c, 0x3725, 0x6d60, + 0x6d61, 0x6d62, 0x3f49, 0x6d63, 0x3c2d, 0x6d64, 0x6d65, 0x5221, + 0x517e, 0x6d66, 0x6570, 0x6d67, 0x4324, 0x3f2b, 0x4740, 0x6d68, + 0x4a55, 0x4454, 0x397e, 0x4329, 0x312a, 0x4b78, 0x3f57, 0x375e, + 0x3661, 0x4a56, 0x6d69, 0x6d6b, 0x6d6a, 0x3260, 0x4676, 0x6d6c, + 0x4777, 0x4533, 0x6d6d, 0x3d52, 0x6d6f, 0x4c42, 0x6d7e, 0x6d71, + 0x6d72, 0x4449, 0x4260, 0x4177, 0x4628, 0x6d70, 0x3555, 0x6d79, + 0x6d76, 0x6e25, 0x4629, 0x4360, 0x6d73, 0x447e, 0x4553, 0x6d74, + 0x6d78, 0x3f60, 0x4767, 0x444c, 0x4042, 0x6d77, 0x422e, 0x4224, + 0x6d75, 0x3029, 0x4f22, 0x6d7a, 0x4261, 0x3d35, 0x3f4a, 0x6d7c, + 0x6d7b, 0x306f, 0x6d7d, 0x492f, 0x6e27, 0x465b, 0x3f6b, 0x4359, + 0x3678, 0x6e26, 0x4d37, 0x313f, 0x4a57, 0x3261, 0x6e21, 0x6e22, + 0x6e23, 0x6e24, 0x463b, 0x4323, 0x3063, 0x6e28, 0x6e29, 0x7423, + 0x423d, 0x6e2a, 0x3173, 0x414c, 0x382f, 0x4d5a, 0x6e2b, 0x452c, + 0x4178, 0x3c57, 0x6e2c, 0x6e2f, 0x3d65, 0x6e2d, 0x412b, 0x412a, + 0x3064, 0x4e4b, 0x6e31, 0x4872, 0x6e33, 0x6e32, 0x6e30, 0x6364, + 0x3454, 0x6d6e, 0x6e35, 0x6e34, 0x6e36, 0x4d38, 0x4661, 0x4b2e, + 0x6e37, 0x3c59, 0x6e38, 0x6e39, 0x6e3a, 0x4521, 0x306a, 0x3959, + 0x4f3a, 0x6e3e, 0x3734, 0x6e3b, 0x6e3c, 0x4974, 0x3354, 0x4d39, + 0x363f, 0x4554, 0x6e3f, 0x6e40, 0x6e41, 0x4522, 0x6e43, 0x6e42, + 0x4653, 0x6e44, 0x3d36, 0x3c60, 0x475b, 0x4371, 0x3c72, 0x3f6c, + 0x6e45, 0x6e46, 0x3f5d, 0x6e47, 0x6e48, 0x6e49, 0x4d6f, 0x3d37, + 0x6e4b, 0x6e4a, 0x395a, 0x3973, 0x3b40, 0x6e4e, 0x3d66, 0x6e4d, + 0x6e4c, 0x4269, 0x386f, 0x4043, 0x4830, 0x3d39, 0x6e4f, 0x3e5f, + 0x6e52, 0x6e50, 0x6e51, 0x6e54, 0x6e53, 0x3e7a, 0x6e55, 0x6e56, + 0x6e57, 0x4850, 0x3a53, 0x3c61, 0x6e58, 0x6e59, 0x4e24, 0x3d45, + 0x4c6e, 0x4e4c, 0x6e5a, 0x3662, 0x6e5b, 0x4523, 0x6e5e, 0x3378, + 0x3f4b, 0x6e5c, 0x6e5d, 0x4460, 0x4b55, 0x367c, 0x6e60, 0x6e61, + 0x6e5f, 0x6e63, 0x465f, 0x3343, 0x6e67, 0x6e64, 0x6e66, 0x6e62, + 0x6f4f, 0x6e65, 0x4e6b, 0x385a, 0x6e6f, 0x4534, 0x6e6a, 0x6e6d, + 0x6e6b, 0x6e70, 0x6e71, 0x6e69, 0x6e76, 0x3174, 0x6e68, 0x482d, + 0x6e6c, 0x3e60, 0x395b, 0x4b48, 0x3664, 0x3d46, 0x463c, 0x412d, + 0x6e74, 0x6e6e, 0x6e73, 0x4c43, 0x4438, 0x6e75, 0x6e72, 0x412c, + 0x6e79, 0x6e78, 0x6e77, 0x4b2f, 0x3d7b, 0x6e7a, 0x4a5f, 0x3154, + 0x4946, 0x4372, 0x3578, 0x6e7c, 0x395d, 0x3b2c, 0x6e7b, 0x3f6d, + 0x3f6e, 0x6f21, 0x6f23, 0x3e7b, 0x6f22, 0x6f24, 0x3653, 0x4945, + 0x3c62, 0x4f23, 0x6e7e, 0x3a78, 0x4f3f, 0x6f26, 0x6f25, 0x6f27, + 0x6e7d, 0x4669, 0x4555, 0x4457, 0x6f2c, 0x4343, 0x6f28, 0x6f29, + 0x372d, 0x6f2b, 0x3830, 0x6f2a, 0x3e61, 0x3379, 0x6f30, 0x3a3f, + 0x4179, 0x444a, 0x333b, 0x6f2e, 0x6f2f, 0x4443, 0x6f2d, 0x6f31, + 0x6f37, 0x6f3a, 0x6f39, 0x452d, 0x6f32, 0x6f33, 0x6f36, 0x6f38, + 0x3640, 0x6f3b, 0x6f35, 0x6f34, 0x6f3f, 0x6f40, 0x6f41, 0x6f3e, + 0x6f3d, 0x3e62, 0x462a, 0x6f3c, 0x6f45, 0x6f43, 0x6f44, 0x6f42, + 0x4278, 0x6f46, 0x6f47, 0x6f49, 0x3455, 0x6f48, 0x4c7a, 0x6f54, + 0x6f4a, 0x6f4d, 0x6f4b, 0x6f4c, 0x6f4e, 0x6f50, 0x6f51, 0x6f52, + 0x6f55, 0x6f53, 0x6f56, 0x6f58, 0x6f57, 0x4439, 0x4c67, 0x6f59, + 0x412e, 0x6f5a, 0x4a44, 0x6f5b, 0x332b, 0x313c, 0x3457, 0x3456, + 0x6f5c, 0x6f5d, 0x6f5e, 0x6f5f, 0x6f60, 0x3458, 0x3355, 0x395e, + 0x4836, 0x6f62, 0x6f61, 0x6f63, 0x315c, 0x6f66, 0x6f65, 0x6f64, + 0x6f67, 0x6f6a, 0x3047, 0x6f68, 0x6f6c, 0x6f6b, 0x6f6e, 0x6f6d, + 0x6f6f, 0x462e, 0x6f70, 0x6f71, 0x6f73, 0x6f72, 0x496c, 0x6f74, + 0x6f75, 0x3a65, 0x6f76, 0x6f77, 0x4b49, 0x414b, 0x3024, 0x424b, + 0x6f78, 0x496d, 0x6f7b, 0x6f79, 0x395f, 0x6f7a, 0x3842, 0x4a45, + 0x6f7d, 0x7021, 0x6f7e, 0x7022, 0x3121, 0x3f58, 0x3d7c, 0x3459, + 0x7023, 0x4766, 0x7025, 0x3122, 0x7024, 0x4444, 0x4e4d, 0x462b, + 0x6f7c, 0x4e26, 0x3831, 0x4d5b, 0x3679, 0x4e34, 0x3728, 0x4262, + 0x6721, 0x7026, 0x332c, 0x3f6f, 0x3356, 0x7028, 0x7029, 0x7027, + 0x3764, 0x3a5d, 0x3e63, 0x3123, 0x4e59, 0x702b, 0x6e2e, 0x702a, + 0x702e, 0x702c, 0x702d, 0x702f, 0x7030, 0x4e6c, 0x7031, 0x7032, + 0x4049, 0x483b, 0x3f7d, 0x3467, 0x4d3a, 0x326d, 0x3d38, 0x385b, + 0x7035, 0x7034, 0x3b73, 0x7036, 0x7033, 0x3b28, 0x703a, 0x6a2d, + 0x5256, 0x3f77, 0x7038, 0x4e25, 0x4671, 0x312b, 0x4063, 0x3c36, + 0x4a37, 0x3140, 0x4e6d, 0x4d6b, 0x703b, 0x4545, 0x3c7b, 0x703c, + 0x703d, 0x3f4c, 0x703e, 0x4e6e, 0x7039, 0x7040, 0x7042, 0x7041, + 0x703f, 0x7043, 0x7044, 0x417a, 0x3262, 0x7045, 0x4c38, 0x7046, + 0x7047, 0x4f2a, 0x5b31, 0x7048, 0x7049, 0x704a, 0x704e, 0x704b, + 0x704c, 0x704d, 0x704f, 0x4044, 0x4c77, 0x4045, 0x7050, 0x4873, + 0x7051, 0x7353, 0x4c4c, 0x7052, 0x7053, 0x7054, 0x3357, 0x7056, + 0x3f59, 0x7057, 0x3724, 0x7058, 0x705c, 0x705a, 0x705b, 0x3373, + 0x7059, 0x705d, 0x705e, 0x3048, 0x705f, 0x7060, 0x3e64, 0x7061, + 0x3547, 0x7064, 0x7063, 0x7062, 0x6b71, 0x4a5c, 0x7065, 0x7066, + 0x7067, 0x7068, 0x7069, 0x706a, 0x345a, 0x706b, 0x706c, 0x4723, + 0x706e, 0x323b, 0x7071, 0x7070, 0x3124, 0x3641, 0x4a47, 0x443a, + 0x3a22, 0x3960, 0x3d67, 0x3f5c, 0x7073, 0x7072, 0x4d42, 0x3468, + 0x4852, 0x465c, 0x3f7c, 0x4e4e, 0x375b, 0x7076, 0x7075, 0x4b4b, + 0x462c, 0x3150, 0x7077, 0x7074, 0x4951, 0x4d6a, 0x7078, 0x7079, + 0x707b, 0x426a, 0x335b, 0x335c, 0x707a, 0x3469, 0x3832, 0x346a, + 0x453f, 0x4e60, 0x385c, 0x707c, 0x707d, 0x707e, 0x7121, 0x7123, + 0x7122, 0x4977, 0x7124, 0x7125, 0x7126, 0x7127, 0x7129, 0x7128, + 0x712a, 0x4874, 0x664c, 0x3f29, 0x3532, 0x712b, 0x712c, 0x522c, + 0x5d3b, 0x4853, 0x307b, 0x303b, 0x3b74, 0x4b30, 0x3e7e, 0x712d, + 0x4c5f, 0x712e, 0x4d5c, 0x3142, 0x3b41, 0x712f, 0x326e, 0x7130, + 0x7131, 0x7133, 0x7134, 0x7136, 0x7132, 0x7135, 0x345b, 0x7137, + 0x7138, 0x7139, 0x713a, 0x713b, 0x713d, 0x713c, 0x713f, 0x7142, + 0x713e, 0x7140, 0x7141, 0x7143, 0x3642, 0x3c73, 0x7144, 0x7145, + 0x3961, 0x7146, 0x333e, 0x474f, 0x7147, 0x7148, 0x435a, 0x466b, + 0x7149, 0x477d, 0x424c, 0x3158, 0x366e, 0x366f, 0x4373, 0x714e, + 0x3670, 0x326f, 0x714d, 0x714b, 0x714c, 0x714a, 0x7158, 0x714f, + 0x7150, 0x7151, 0x7152, 0x7154, 0x7153, 0x3d59, 0x7155, 0x7157, + 0x3533, 0x7156, 0x417b, 0x3833, 0x7159, 0x424d, 0x715a, 0x462d, + 0x715b, 0x7160, 0x715e, 0x715d, 0x715f, 0x715c, 0x7162, 0x7161, + 0x7164, 0x3643, 0x7163, 0x7165, 0x7166, 0x7168, 0x7167, 0x7169, + 0x716b, 0x716a, 0x397c, 0x716c, 0x716d, 0x333c, 0x716e, 0x716f, + 0x3f71, 0x7170, 0x7171, 0x7172, 0x7173, 0x3962, 0x7174, 0x7175, + 0x7176, 0x7177, 0x7178, 0x4831, 0x717a, 0x4926, 0x717b, 0x7179, + 0x717d, 0x717c, 0x717e, 0x7221, 0x7222, 0x7223, 0x7224, 0x7225, + 0x7226, 0x7227, 0x7228, 0x7229, 0x722a, 0x722b, 0x722c, 0x722d, + 0x722e, 0x5d35, 0x722f, 0x6478, 0x3534, 0x3321, 0x3a32, 0x7231, + 0x7230, 0x4c25, 0x7233, 0x7234, 0x7232, 0x7235, 0x4b62, 0x7236, + 0x357b, 0x4f25, 0x7237, 0x7239, 0x303e, 0x723a, 0x4a2b, 0x7238, + 0x723b, 0x723c, 0x723d, 0x723e, 0x723f, 0x4b6e, 0x3b2d, 0x3a7a, + 0x412f, 0x7240, 0x7243, 0x7241, 0x7244, 0x3871, 0x7242, 0x7245, + 0x7246, 0x7247, 0x724b, 0x3b2a, 0x4264, 0x724c, 0x7249, 0x7248, + 0x724a, 0x375f, 0x7250, 0x724f, 0x724e, 0x3033, 0x725a, 0x7256, + 0x7257, 0x7253, 0x7259, 0x7255, 0x3362, 0x4f4c, 0x7258, 0x7254, + 0x7252, 0x7251, 0x725c, 0x725f, 0x725e, 0x725d, 0x4949, 0x725b, + 0x3073, 0x7260, 0x7262, 0x336f, 0x724d, 0x3137, 0x7264, 0x7263, + 0x7261, 0x432d, 0x4b70, 0x4e5a, 0x7265, 0x7266, 0x7267, 0x7268, + 0x7269, 0x443b, 0x726a, 0x4837, 0x726f, 0x726b, 0x726c, 0x4b31, + 0x4c44, 0x4650, 0x7270, 0x7271, 0x463e, 0x726e, 0x726d, 0x322a, + 0x7279, 0x7278, 0x3175, 0x7276, 0x7275, 0x7273, 0x337b, 0x7272, + 0x3c32, 0x3229, 0x3963, 0x727c, 0x727b, 0x727a, 0x7277, 0x727d, + 0x727e, 0x7325, 0x7324, 0x7326, 0x312d, 0x7321, 0x7322, 0x3974, + 0x4c39, 0x7323, 0x4b32, 0x732b, 0x7327, 0x732c, 0x7329, 0x7328, + 0x375c, 0x732d, 0x732e, 0x732f, 0x732a, 0x7274, 0x7330, 0x4461, + 0x7334, 0x7335, 0x7333, 0x7332, 0x7338, 0x7331, 0x7336, 0x7337, + 0x733a, 0x7339, 0x733c, 0x733d, 0x733e, 0x4f49, 0x733b, 0x426b, + 0x3a6d, 0x733f, 0x7340, 0x7341, 0x7342, 0x7343, 0x3834, 0x7344, + 0x7345, 0x3c2f, 0x7346, 0x7347, 0x7348, 0x7349, 0x734c, 0x734a, + 0x4f3c, 0x734b, 0x4e6f, 0x734d, 0x4e5b, 0x734e, 0x477e, 0x734f, + 0x7351, 0x7352, 0x7350, 0x396d, 0x4c4d, 0x4b63, 0x5677, 0x5d60, + 0x4b7b, 0x322b, 0x7354, 0x3550, 0x7355, 0x7356, 0x7357, 0x3975, + 0x7358, 0x6054, 0x4c5b, 0x4263, 0x7359, 0x735b, 0x735a, 0x735c, + 0x735d, 0x735e, 0x735f, 0x7360, 0x7361, 0x7362, 0x7363, 0x7364, + 0x7365, 0x7366, 0x7367, 0x7368, 0x4524, 0x385d, 0x736a, 0x414d, + 0x736b, 0x736c, 0x4921, 0x736d, 0x736e, 0x6337, 0x6c5a, 0x706d, + 0x736f, 0x7370, 0x7372, 0x7373, 0x7374, 0x4e70, 0x7371, 0x7375, + 0x7376, 0x7378, 0x7377, 0x737a, 0x737b, 0x7379, 0x4e36, 0x737c, + 0x737d, 0x6354, 0x737e, 0x212a, 0x2174, 0x2170, 0x2173, 0x2175, + 0x214a, 0x214b, 0x2176, 0x215c, 0x2124, 0x2125, 0x213f, 0x2330, + 0x2331, 0x2332, 0x2333, 0x2334, 0x2335, 0x2336, 0x2337, 0x2338, + 0x2339, 0x2127, 0x2128, 0x2163, 0x2161, 0x2164, 0x2129, 0x2177, + 0x2341, 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, 0x2347, 0x2348, + 0x2349, 0x234a, 0x234b, 0x234c, 0x234d, 0x234e, 0x234f, 0x2350, + 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, 0x2356, 0x2357, 0x2358, + 0x2359, 0x235a, 0x214e, 0x2140, 0x214f, 0x2130, 0x2132, 0x212e, + 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, 0x2366, 0x2367, 0x2368, + 0x2369, 0x236a, 0x236b, 0x236c, 0x236d, 0x236e, 0x236f, 0x2370, + 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, 0x2376, 0x2377, 0x2378, + 0x2379, 0x237a, 0x2150, 0x2143, 0x2151, 0x2131, 0x216f, +}; + +static const Summary16 jisx0208_uni2indx_page00[16] = { + /* 0x0000 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x118c }, { 5, 0x0053 }, + { 9, 0x0000 }, { 9, 0x0080 }, { 10, 0x0000 }, { 10, 0x0080 }, +}; +static const Summary16 jisx0208_uni2indx_page03[22] = { + /* 0x0300 */ + { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, + { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, { 11, 0x0000 }, + { 11, 0x0000 }, { 11, 0xfffe }, { 26, 0x03fb }, { 35, 0xfffe }, + { 50, 0x03fb }, { 59, 0x0000 }, { 59, 0x0000 }, { 59, 0x0000 }, + /* 0x0400 */ + { 59, 0x0002 }, { 60, 0xffff }, { 76, 0xffff }, { 92, 0xffff }, + { 108, 0xffff }, { 124, 0x0002 }, +}; +static const Summary16 jisx0208_uni2indx_page20[50] = { + /* 0x2000 */ + { 125, 0x0000 }, { 125, 0x3361 }, { 132, 0x0063 }, { 136, 0x080d }, + { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x0000 }, + { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x0000 }, + { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x0000 }, { 140, 0x0000 }, + /* 0x2100 */ + { 140, 0x0008 }, { 141, 0x0000 }, { 141, 0x0800 }, { 142, 0x0000 }, + { 142, 0x0000 }, { 142, 0x0000 }, { 142, 0x0000 }, { 142, 0x0000 }, + { 142, 0x0000 }, { 142, 0x000f }, { 146, 0x0000 }, { 146, 0x0000 }, + { 146, 0x0000 }, { 146, 0x0014 }, { 148, 0x0000 }, { 148, 0x0000 }, + /* 0x2200 */ + { 148, 0x098d }, { 154, 0x6404 }, { 158, 0x1f81 }, { 165, 0x2030 }, + { 168, 0x0000 }, { 168, 0x0004 }, { 169, 0x0cc3 }, { 175, 0x0000 }, + { 175, 0x00cc }, { 179, 0x0000 }, { 179, 0x0020 }, { 180, 0x0000 }, + { 180, 0x0000 }, { 180, 0x0000 }, { 180, 0x0000 }, { 180, 0x0000 }, + /* 0x2300 */ + { 180, 0x0000 }, { 180, 0x0004 }, +}; +static const Summary16 jisx0208_uni2indx_page25[23] = { + /* 0x2500 */ + { 181, 0x900f }, { 187, 0x3999 }, { 195, 0x9939 }, { 203, 0x9999 }, + { 211, 0x0804 }, { 213, 0x0000 }, { 213, 0x0000 }, { 213, 0x0000 }, + { 213, 0x0000 }, { 213, 0x0000 }, { 213, 0x0003 }, { 215, 0x300c }, + { 219, 0xc8c0 }, { 224, 0x0000 }, { 224, 0x8000 }, { 225, 0x0000 }, + /* 0x2600 */ + { 225, 0x0060 }, { 227, 0x0000 }, { 227, 0x0000 }, { 227, 0x0000 }, + { 227, 0x0005 }, { 229, 0x0000 }, { 229, 0xa400 }, +}; +static const Summary16 jisx0208_uni2indx_page30[16] = { + /* 0x3000 */ + { 232, 0xffef }, { 247, 0x103f }, { 254, 0x0000 }, { 254, 0x0000 }, + { 254, 0xfffe }, { 269, 0xffff }, { 285, 0xffff }, { 301, 0xffff }, + { 317, 0xffff }, { 333, 0x780f }, { 341, 0xfffe }, { 356, 0xffff }, + { 372, 0xffff }, { 388, 0xffff }, { 404, 0xffff }, { 420, 0x787f }, +}; +static const Summary16 jisx0208_uni2indx_page4e[1307] = { + /* 0x4e00 */ + { 431, 0x6f8b }, { 441, 0x43f3 }, { 450, 0x2442 }, { 454, 0x9b46 }, + { 462, 0xe82c }, { 469, 0xe3e0 }, { 477, 0x0004 }, { 478, 0x400a }, + { 481, 0x5f65 }, { 491, 0xdb36 }, { 501, 0x7977 }, { 512, 0x0449 }, + { 516, 0xecd7 }, { 527, 0xe3f0 }, { 536, 0x6038 }, { 541, 0x08c5 }, + /* 0x4f00 */ + { 546, 0xe602 }, { 552, 0x3403 }, { 557, 0x8000 }, { 558, 0x3551 }, + { 565, 0xe0c8 }, { 571, 0x7eab }, { 582, 0x8200 }, { 584, 0x9869 }, + { 591, 0xa948 }, { 597, 0x2942 }, { 602, 0xe803 }, { 608, 0x8060 }, + { 611, 0x441c }, { 616, 0xad93 }, { 625, 0xc03a }, { 631, 0x4568 }, + /* 0x5000 */ + { 637, 0xaa60 }, { 643, 0x8656 }, { 650, 0x3f7a }, { 661, 0x0240 }, + { 663, 0x8388 }, { 668, 0x1461 }, { 673, 0x1020 }, { 675, 0x2174 }, + { 681, 0x2021 }, { 684, 0x0702 }, { 688, 0x3000 }, { 690, 0x40bc }, + { 696, 0xa624 }, { 702, 0x4462 }, { 707, 0x60a8 }, { 712, 0x0a20 }, + /* 0x5100 */ + { 715, 0x0217 }, { 720, 0x8574 }, { 727, 0x0402 }, { 729, 0x9c84 }, + { 735, 0x7bfb }, { 748, 0x1415 }, { 753, 0x7f24 }, { 762, 0x11e2 }, + { 768, 0xb665 }, { 777, 0x02ef }, { 785, 0x1f75 }, { 795, 0x20ff }, + { 804, 0x3a70 }, { 811, 0x3840 }, { 815, 0x26c3 }, { 822, 0x6763 }, + /* 0x5200 */ + { 831, 0x4dd9 }, { 840, 0x2092 }, { 844, 0x46b0 }, { 850, 0x0fc9 }, + { 858, 0xbc98 }, { 866, 0x4850 }, { 870, 0x8638 }, { 876, 0xa03f }, + { 884, 0x2388 }, { 889, 0x8816 }, { 894, 0x3e09 }, { 901, 0x5232 }, + { 907, 0x22aa }, { 913, 0xe3a4 }, { 921, 0x00dd }, { 927, 0xc72c }, + /* 0x5300 */ + { 935, 0xa166 }, { 942, 0x26e1 }, { 949, 0x840b }, { 954, 0x8f0a }, + { 961, 0x27eb }, { 971, 0x559e }, { 980, 0xc241 }, { 985, 0x89bb }, + { 994, 0x0014 }, { 996, 0x8540 }, { 1000, 0x6361 }, { 1007, 0x0849 }, + { 1011, 0x7f0c }, { 1020, 0x8ad0 }, { 1026, 0xff3e }, { 1039, 0x05cf }, + /* 0x5400 */ + { 1047, 0xff1a }, { 1058, 0xa803 }, { 1063, 0x7a41 }, { 1070, 0x7b40 }, + { 1077, 0x4745 }, { 1084, 0x8002 }, { 1086, 0x0500 }, { 1088, 0x38eb }, + { 1097, 0xd851 }, { 1104, 0x0005 }, { 1106, 0x9934 }, { 1113, 0x710c }, + { 1119, 0x0397 }, { 1126, 0x0100 }, { 1127, 0x6366 }, { 1135, 0x2404 }, + /* 0x5500 */ + { 1138, 0x80d0 }, { 1142, 0x0051 }, { 1145, 0xc000 }, { 1147, 0x430a }, + { 1152, 0x9071 }, { 1158, 0x30c8 }, { 1163, 0x0008 }, { 1164, 0x5800 }, + { 1167, 0x0e99 }, { 1174, 0xf700 }, { 1181, 0x5f80 }, { 1188, 0x0041 }, + { 1190, 0x00b0 }, { 1193, 0x9410 }, { 1197, 0x0018 }, { 1199, 0x6280 }, + /* 0x5600 */ + { 1203, 0x0240 }, { 1205, 0x09d0 }, { 1210, 0x8200 }, { 1212, 0x0156 }, + { 1217, 0x5004 }, { 1220, 0x0801 }, { 1222, 0x1d10 }, { 1227, 0x0510 }, + { 1230, 0x84c1 }, { 1235, 0x0010 }, { 1236, 0x4025 }, { 1240, 0x1050 }, + { 1243, 0x410f }, { 1249, 0x4d8a }, { 1256, 0x4009 }, { 1259, 0xa60d }, + /* 0x5700 */ + { 1266, 0xab19 }, { 1274, 0x914c }, { 1280, 0x21c0 }, { 1284, 0x0981 }, + { 1288, 0xc485 }, { 1294, 0x0003 }, { 1296, 0x0652 }, { 1301, 0x8000 }, + { 1302, 0x0b04 }, { 1306, 0x0008 }, { 1307, 0x041d }, { 1312, 0x0009 }, + { 1314, 0x4849 }, { 1319, 0x905c }, { 1325, 0x0009 }, { 1327, 0x1690 }, + /* 0x5800 */ + { 1332, 0x0c65 }, { 1338, 0x2220 }, { 1341, 0x8412 }, { 1345, 0x2433 }, + { 1351, 0x0c03 }, { 1355, 0x4796 }, { 1363, 0x0a04 }, { 1366, 0x4225 }, + { 1371, 0x0028 }, { 1373, 0x9088 }, { 1377, 0x4900 }, { 1380, 0x4f08 }, + { 1386, 0x14a2 }, { 1391, 0xd3aa }, { 1400, 0xd830 }, { 1406, 0x3e87 }, + /* 0x5900 */ + { 1415, 0x8604 }, { 1419, 0x1f61 }, { 1427, 0x7ea4 }, { 1436, 0x4186 }, + { 1441, 0xc390 }, { 1447, 0x05b3 }, { 1454, 0x57a5 }, { 1463, 0x2118 }, + { 1467, 0x241e }, { 1473, 0x2a48 }, { 1478, 0x1128 }, { 1482, 0x4a04 }, + { 1486, 0x0a40 }, { 1489, 0x161b }, { 1496, 0x0d60 }, { 1501, 0x8840 }, + /* 0x5a00 */ + { 1504, 0x020a }, { 1507, 0x9502 }, { 1512, 0x8221 }, { 1516, 0x1060 }, + { 1519, 0x0243 }, { 1523, 0x0400 }, { 1524, 0x1444 }, { 1528, 0x8000 }, + { 1529, 0x0000 }, { 1529, 0x0c04 }, { 1532, 0x0000 }, { 1532, 0x7000 }, + { 1535, 0x1a06 }, { 1540, 0x00c1 }, { 1543, 0x024a }, { 1547, 0x0c00 }, + /* 0x5b00 */ + { 1549, 0x1a00 }, { 1552, 0x0040 }, { 1553, 0x1404 }, { 1556, 0x4045 }, + { 1560, 0x0029 }, { 1563, 0xbdb3 }, { 1574, 0x0a78 }, { 1580, 0x052b }, + { 1586, 0xbba9 }, { 1596, 0xbfa0 }, { 1605, 0x407c }, { 1611, 0x8379 }, + { 1619, 0x12fc }, { 1627, 0xe81d }, { 1635, 0x4bf6 }, { 1645, 0xc569 }, + /* 0x5c00 */ + { 1653, 0xeff6 }, { 1666, 0x044a }, { 1670, 0x2115 }, { 1675, 0xff02 }, + { 1684, 0xed63 }, { 1694, 0x402b }, { 1699, 0xd033 }, { 1706, 0x0242 }, + { 1709, 0x1000 }, { 1710, 0x0013 }, { 1713, 0x1b02 }, { 1718, 0x59ca }, + { 1726, 0x00a0 }, { 1728, 0x0200 }, { 1729, 0xa703 }, { 1736, 0x2c41 }, + /* 0x5d00 */ + { 1741, 0x4880 }, { 1744, 0x8ff2 }, { 1754, 0x0204 }, { 1756, 0x0000 }, + { 1756, 0x5800 }, { 1759, 0x1005 }, { 1762, 0x9200 }, { 1765, 0x0048 }, + { 1767, 0x1894 }, { 1772, 0x2001 }, { 1774, 0x5004 }, { 1777, 0x3480 }, + { 1781, 0x3200 }, { 1784, 0x684c }, { 1790, 0x49ea }, { 1798, 0x68be }, + /* 0x5e00 */ + { 1807, 0x184c }, { 1812, 0x2e42 }, { 1818, 0xa820 }, { 1822, 0x21c9 }, + { 1828, 0x50b9 }, { 1835, 0x80b0 }, { 1839, 0x001e }, { 1843, 0xff7c }, + { 1856, 0x849a }, { 1862, 0x14e0 }, { 1867, 0x28c1 }, { 1872, 0x01e0 }, + { 1876, 0x870e }, { 1883, 0xac49 }, { 1890, 0x130f }, { 1897, 0xdddb }, + /* 0x5f00 */ + { 1909, 0xbe1a }, { 1918, 0x89fb }, { 1928, 0xa2e0 }, { 1934, 0x51a2 }, + { 1940, 0x5502 }, { 1945, 0x32ca }, { 1952, 0x3e46 }, { 1960, 0x928b }, + { 1967, 0x1dbf }, { 1978, 0x438f }, { 1986, 0x6703 }, { 1993, 0x3218 }, + { 1998, 0x3028 }, { 2002, 0x33c0 }, { 2008, 0x0811 }, { 2011, 0xa923 }, + /* 0x6000 */ + { 2018, 0xc000 }, { 2020, 0x3a65 }, { 2028, 0x8fe3 }, { 2038, 0x0402 }, + { 2040, 0x2c4e }, { 2047, 0x8625 }, { 2053, 0xbf3d }, { 2065, 0x00a1 }, + { 2068, 0x3a1a }, { 2075, 0x8cd4 }, { 2082, 0x06c9 }, { 2088, 0x317c }, + { 2096, 0x00e0 }, { 2099, 0x950a }, { 2105, 0x018b }, { 2110, 0x0edb }, + /* 0x6100 */ + { 2119, 0xe34b }, { 2128, 0x8c20 }, { 2132, 0x1182 }, { 2136, 0xf010 }, + { 2141, 0x7d94 }, { 2150, 0xa728 }, { 2157, 0xc9ac }, { 2165, 0x40fb }, + { 2173, 0x4484 }, { 2177, 0x0653 }, { 2183, 0x5a90 }, { 2189, 0x4444 }, + { 2193, 0x3fc8 }, { 2202, 0x0001 }, { 2203, 0x0048 }, { 2205, 0xf5d4 }, + /* 0x6200 */ + { 2215, 0x7701 }, { 2222, 0xec57 }, { 2232, 0xc442 }, { 2237, 0x891d }, + { 2244, 0x6b83 }, { 2252, 0x4928 }, { 2257, 0x4109 }, { 2261, 0xd242 }, + { 2267, 0x061d }, { 2273, 0x59fe }, { 2284, 0x1800 }, { 2286, 0x3a22 }, + { 2292, 0xb7e4 }, { 2302, 0x3b9f }, { 2313, 0xf003 }, { 2319, 0xc0ea }, + /* 0x6300 */ + { 2326, 0x1386 }, { 2332, 0x8202 }, { 2335, 0x8980 }, { 2339, 0xe400 }, + { 2343, 0xb200 }, { 2347, 0x10a1 }, { 2351, 0x4b80 }, { 2356, 0x0cc4 }, + { 2361, 0xd309 }, { 2368, 0x8944 }, { 2373, 0x1faf }, { 2384, 0x4834 }, + { 2389, 0x8259 }, { 2395, 0x0c45 }, { 2400, 0x420a }, { 2404, 0x0450 }, + /* 0x6400 */ + { 2407, 0xa040 }, { 2410, 0x10c8 }, { 2414, 0x3140 }, { 2418, 0x4450 }, + { 2422, 0x4004 }, { 2424, 0x0100 }, { 2425, 0x8280 }, { 2428, 0x0540 }, + { 2431, 0x0108 }, { 2433, 0x442c }, { 2438, 0x6a30 }, { 2444, 0x1a05 }, + { 2449, 0x20a6 }, { 2454, 0x0514 }, { 2458, 0x90cf }, { 2466, 0x6456 }, + /* 0x6500 */ + { 2473, 0x0021 }, { 2475, 0x3100 }, { 2478, 0x9c18 }, { 2484, 0xcbf0 }, + { 2493, 0xa120 }, { 2497, 0x63e2 }, { 2505, 0x104c }, { 2509, 0x01b5 }, + { 2515, 0x538c }, { 2522, 0x9a83 }, { 2529, 0xb8b2 }, { 2537, 0x3281 }, + { 2542, 0x987a }, { 2550, 0x0a84 }, { 2554, 0x33e7 }, { 2564, 0x0c02 }, + /* 0x6600 */ + { 2567, 0xd4cc }, { 2575, 0x9018 }, { 2579, 0xa1a1 }, { 2585, 0x9070 }, + { 2590, 0x8a1e }, { 2597, 0xe004 }, { 2601, 0xc3d4 }, { 2609, 0x0451 }, + { 2613, 0x439a }, { 2620, 0x21c2 }, { 2625, 0x4844 }, { 2629, 0x5310 }, + { 2634, 0x0292 }, { 2638, 0x3640 }, { 2643, 0x0241 }, { 2646, 0xf3bd }, + /* 0x6700 */ + { 2658, 0xab09 }, { 2665, 0xe8f0 }, { 2673, 0x7dc0 }, { 2681, 0xa5d2 }, + { 2689, 0xc242 }, { 2694, 0xd24b }, { 2702, 0xa43f }, { 2711, 0xd0af }, + { 2720, 0x1aa0 }, { 2725, 0x34a1 }, { 2731, 0x8247 }, { 2737, 0x03d8 }, + { 2743, 0xc452 }, { 2749, 0x651b }, { 2757, 0xd294 }, { 2764, 0xc83a }, + /* 0x6800 */ + { 2771, 0x001c }, { 2774, 0x40c8 }, { 2778, 0x0e06 }, { 2783, 0x3314 }, + { 2789, 0x614f }, { 2797, 0xb21b }, { 2805, 0x0088 }, { 2807, 0xc0d0 }, + { 2812, 0xa02a }, { 2817, 0xa898 }, { 2823, 0xa1c5 }, { 2830, 0x166b }, + { 2838, 0x2e50 }, { 2844, 0x85b4 }, { 2851, 0xc08b }, { 2857, 0x0604 }, + /* 0x6900 */ + { 2860, 0xf933 }, { 2870, 0x1e04 }, { 2875, 0x056e }, { 2882, 0xa251 }, + { 2888, 0x0400 }, { 2889, 0x7638 }, { 2897, 0xec07 }, { 2905, 0x73b8 }, + { 2914, 0x4406 }, { 2918, 0x1832 }, { 2923, 0x4081 }, { 2926, 0xc816 }, + { 2932, 0x7c8a }, { 2940, 0x6309 }, { 2946, 0x2980 }, { 2950, 0xaa04 }, + /* 0x6a00 */ + { 2955, 0x1c24 }, { 2960, 0xca9c }, { 2968, 0x4e0e }, { 2975, 0x2760 }, + { 2981, 0x0990 }, { 2985, 0x8300 }, { 2988, 0x0046 }, { 2991, 0x8104 }, + { 2994, 0x6011 }, { 2998, 0x1081 }, { 3001, 0x540d }, { 3007, 0x0908 }, + { 3010, 0x000e }, { 3013, 0xcc0a }, { 3019, 0x0500 }, { 3021, 0x0c00 }, + /* 0x6b00 */ + { 3023, 0x0430 }, { 3026, 0xa044 }, { 3030, 0x008b }, { 3034, 0x6784 }, + { 3041, 0x5288 }, { 3046, 0x8a19 }, { 3052, 0x865e }, { 3060, 0x8b18 }, + { 3066, 0x2e59 }, { 3074, 0x4160 }, { 3078, 0x8c10 }, { 3082, 0x9cbe }, + { 3092, 0x6861 }, { 3098, 0x891c }, { 3104, 0x9800 }, { 3107, 0x0008 }, + /* 0x6c00 */ + { 3108, 0x8100 }, { 3110, 0x089a }, { 3115, 0x0018 }, { 3117, 0x4190 }, + { 3121, 0x4007 }, { 3125, 0xe4a1 }, { 3132, 0x0505 }, { 3136, 0x640d }, + { 3142, 0x310e }, { 3148, 0x0e4d }, { 3155, 0x4806 }, { 3159, 0xff0a }, + { 3169, 0x1632 }, { 3175, 0x2aa8 }, { 3181, 0x852e }, { 3188, 0x000b }, + /* 0x6d00 */ + { 3191, 0x1800 }, { 3193, 0xca84 }, { 3199, 0x0e20 }, { 3203, 0x696c }, + { 3211, 0x0032 }, { 3214, 0x1600 }, { 3217, 0x5658 }, { 3224, 0x0390 }, + { 3228, 0x5120 }, { 3232, 0x1a28 }, { 3237, 0x8000 }, { 3238, 0x1124 }, + { 3242, 0x18e1 }, { 3248, 0x4326 }, { 3254, 0x5d52 }, { 3262, 0x0eaa }, + /* 0x6e00 */ + { 3269, 0x0fa0 }, { 3275, 0xae28 }, { 3282, 0xfa7b }, { 3294, 0x4500 }, + { 3297, 0x6408 }, { 3301, 0x8940 }, { 3305, 0xc880 }, { 3309, 0xc044 }, + { 3313, 0x9005 }, { 3317, 0xb141 }, { 3323, 0x8424 }, { 3327, 0x24c4 }, + { 3332, 0x1a34 }, { 3338, 0x603a }, { 3344, 0x9000 }, { 3346, 0xc194 }, + /* 0x6f00 */ + { 3352, 0x8246 }, { 3357, 0x003a }, { 3361, 0x180d }, { 3366, 0xc106 }, + { 3371, 0x0022 }, { 3373, 0x9910 }, { 3378, 0xe050 }, { 3383, 0x1511 }, + { 3388, 0x4057 }, { 3394, 0x0082 }, { 3396, 0x041a }, { 3400, 0x020a }, + { 3403, 0x004f }, { 3408, 0x8930 }, { 3413, 0xd813 }, { 3420, 0x444a }, + /* 0x7000 */ + { 3425, 0x8a02 }, { 3429, 0xed22 }, { 3437, 0x10c0 }, { 3440, 0x4005 }, + { 3443, 0x1000 }, { 3444, 0x0102 }, { 3446, 0x8808 }, { 3449, 0x3101 }, + { 3453, 0x4600 }, { 3456, 0x0204 }, { 3458, 0xf000 }, { 3462, 0x0708 }, + { 3466, 0x8900 }, { 3469, 0xa200 }, { 3472, 0x0000 }, { 3472, 0x2202 }, + /* 0x7100 */ + { 3475, 0x0200 }, { 3476, 0x1610 }, { 3480, 0x0042 }, { 3482, 0x1040 }, + { 3484, 0x5200 }, { 3487, 0x0260 }, { 3490, 0x52f4 }, { 3498, 0x2000 }, + { 3499, 0x8510 }, { 3503, 0x8230 }, { 3507, 0x1100 }, { 3509, 0x4202 }, + { 3512, 0x4308 }, { 3516, 0x80b5 }, { 3522, 0x70e1 }, { 3529, 0x9a20 }, + /* 0x7200 */ + { 3534, 0x2040 }, { 3536, 0x0801 }, { 3538, 0x3500 }, { 3542, 0xfc65 }, + { 3552, 0x19c1 }, { 3558, 0xab04 }, { 3564, 0x0286 }, { 3568, 0x6214 }, + { 3573, 0x0087 }, { 3577, 0x0044 }, { 3579, 0x9085 }, { 3584, 0x0244 }, + { 3587, 0x405c }, { 3592, 0x0a85 }, { 3597, 0x3207 }, { 3603, 0x3380 }, + /* 0x7300 */ + { 3608, 0x0400 }, { 3609, 0xb8c0 }, { 3615, 0xce20 }, { 3621, 0xc0d0 }, + { 3626, 0xc030 }, { 3630, 0x0080 }, { 3631, 0x0508 }, { 3634, 0x0d25 }, + { 3640, 0x0a90 }, { 3644, 0x0040 }, { 3645, 0x0200 }, { 3646, 0x080c }, + { 3649, 0x6505 }, { 3655, 0x4000 }, { 3656, 0x6421 }, { 3661, 0x4102 }, + /* 0x7400 */ + { 3664, 0x0268 }, { 3668, 0x0000 }, { 3668, 0x0024 }, { 3670, 0x847c }, + { 3677, 0x0002 }, { 3678, 0xde20 }, { 3685, 0x8619 }, { 3691, 0x4049 }, + { 3695, 0x0808 }, { 3697, 0x4000 }, { 3698, 0x0084 }, { 3700, 0x2001 }, + { 3702, 0x8400 }, { 3704, 0x1010 }, { 3706, 0x42cd }, { 3713, 0x01c7 }, + /* 0x7500 */ + { 3719, 0x7038 }, { 3725, 0xd52a }, { 3733, 0x1968 }, { 3739, 0x1d8f }, + { 3748, 0xbe50 }, { 3756, 0x3e12 }, { 3763, 0x2ef5 }, { 3773, 0x81d9 }, + { 3780, 0xcec4 }, { 3788, 0x2412 }, { 3792, 0x0828 }, { 3795, 0x732e }, + { 3804, 0x24ac }, { 3810, 0x4b34 }, { 3817, 0x020c }, { 3820, 0xd41d }, + /* 0x7600 */ + { 3828, 0x2a02 }, { 3832, 0x8000 }, { 3833, 0x0097 }, { 3838, 0x0811 }, + { 3841, 0x11c4 }, { 3846, 0x1144 }, { 3850, 0x1786 }, { 3857, 0x7d45 }, + { 3866, 0x49d9 }, { 3874, 0x0649 }, { 3879, 0x4000 }, { 3880, 0x8791 }, + { 3887, 0x254c }, { 3893, 0xd8c4 }, { 3900, 0x44ba }, { 3907, 0x4914 }, + /* 0x7700 */ + { 3912, 0x1b92 }, { 3919, 0xc800 }, { 3922, 0x0271 }, { 3927, 0x1580 }, + { 3931, 0x0081 }, { 3933, 0x0c00 }, { 3935, 0x096a }, { 3941, 0xc200 }, + { 3944, 0x4800 }, { 3946, 0x4002 }, { 3948, 0x3021 }, { 3952, 0xba49 }, + { 3960, 0x2080 }, { 3962, 0x1c80 }, { 3966, 0xe2ac }, { 3974, 0x1008 }, + /* 0x7800 */ + { 3976, 0x1004 }, { 3978, 0x0034 }, { 3981, 0x00e1 }, { 3985, 0x8414 }, + { 3989, 0x0020 }, { 3990, 0x2000 }, { 3991, 0x9800 }, { 3994, 0x1014 }, + { 3997, 0x70c2 }, { 4003, 0x04aa }, { 4008, 0x8688 }, { 4013, 0x5420 }, + { 4017, 0x0c62 }, { 4022, 0x0413 }, { 4026, 0x9180 }, { 4030, 0x2010 }, + /* 0x7900 */ + { 4032, 0x4082 }, { 4035, 0x0206 }, { 4038, 0x1c40 }, { 4042, 0x5400 }, + { 4045, 0x0383 }, { 4050, 0xe4e9 }, { 4059, 0x2125 }, { 4064, 0x8480 }, + { 4067, 0xe433 }, { 4075, 0x2000 }, { 4076, 0x44c0 }, { 4080, 0xe609 }, + { 4087, 0x0a03 }, { 4091, 0x8126 }, { 4096, 0x12da }, { 4103, 0x0801 }, + /* 0x7a00 */ + { 4105, 0x6901 }, { 4110, 0x9790 }, { 4117, 0x4001 }, { 4119, 0xf886 }, + { 4127, 0xe24d }, { 4135, 0x0081 }, { 4137, 0x0a0e }, { 4142, 0xa651 }, + { 4149, 0x011a }, { 4153, 0x81ec }, { 4160, 0xc600 }, { 4164, 0x8441 }, + { 4168, 0xadb8 }, { 4177, 0xb62c }, { 4185, 0xa46f }, { 4194, 0x8741 }, + /* 0x7b00 */ + { 4200, 0x8d54 }, { 4207, 0x4b02 }, { 4212, 0x1161 }, { 4217, 0x0268 }, + { 4221, 0xbb60 }, { 4229, 0x2057 }, { 4235, 0x50a0 }, { 4239, 0x0433 }, + { 4244, 0xa8c0 }, { 4249, 0xb7b4 }, { 4259, 0x2402 }, { 4262, 0x0112 }, + { 4265, 0x9ad3 }, { 4274, 0x2000 }, { 4275, 0x2271 }, { 4281, 0x00c8 }, + /* 0x7c00 */ + { 4284, 0x2081 }, { 4287, 0x809e }, { 4293, 0x0c8a }, { 4298, 0xe180 }, + { 4303, 0xb009 }, { 4308, 0x8151 }, { 4313, 0x1031 }, { 4317, 0x4028 }, + { 4320, 0x2a0e }, { 4326, 0x89a5 }, { 4333, 0x69b6 }, { 4342, 0x620e }, + { 4348, 0x4425 }, { 4353, 0xd144 }, { 4359, 0x8085 }, { 4363, 0x4d54 }, + /* 0x7d00 */ + { 4370, 0x2c75 }, { 4378, 0x1fb1 }, { 4387, 0xd807 }, { 4394, 0x862d }, + { 4401, 0xd87c }, { 4410, 0x4841 }, { 4414, 0x414e }, { 4420, 0x226e }, + { 4427, 0x8200 }, { 4429, 0x9e08 }, { 4435, 0xf80c }, { 4442, 0xed37 }, + { 4453, 0x8c80 }, { 4457, 0x7526 }, { 4465, 0x9313 }, { 4472, 0x0814 }, + /* 0x7e00 */ + { 4475, 0x0e32 }, { 4481, 0xc804 }, { 4485, 0x484e }, { 4491, 0x6ea6 }, + { 4500, 0x2c4a }, { 4506, 0x6670 }, { 4513, 0x26c0 }, { 4518, 0xba01 }, + { 4524, 0xd30c }, { 4531, 0x185d }, { 4538, 0x0000 }, { 4538, 0x0000 }, + { 4538, 0x0000 }, { 4538, 0x0000 }, { 4538, 0x0000 }, { 4538, 0x0000 }, + /* 0x7f00 */ + { 4538, 0x0000 }, { 4538, 0x0000 }, { 4538, 0x0000 }, { 4538, 0x0540 }, + { 4541, 0x7020 }, { 4545, 0x8133 }, { 4551, 0x4f81 }, { 4558, 0x03a5 }, + { 4564, 0x55ec }, { 4573, 0x6410 }, { 4577, 0xc318 }, { 4583, 0x2344 }, + { 4588, 0x1462 }, { 4593, 0x0034 }, { 4596, 0x0a43 }, { 4601, 0x1a09 }, + /* 0x8000 */ + { 4606, 0x187b }, { 4614, 0x13a5 }, { 4621, 0x0102 }, { 4623, 0xa848 }, + { 4628, 0x0440 }, { 4630, 0xc544 }, { 4636, 0x8106 }, { 4640, 0xe2dd }, + { 4650, 0x1af0 }, { 4657, 0x2d48 }, { 4663, 0xb626 }, { 4671, 0x0416 }, + { 4675, 0x5058 }, { 4680, 0x6e40 }, { 4686, 0x8032 }, { 4690, 0x3112 }, + /* 0x8100 */ + { 4695, 0x07e4 }, { 4702, 0x0c00 }, { 4704, 0x8208 }, { 4707, 0x420a }, + { 4711, 0x4840 }, { 4714, 0x803b }, { 4720, 0x4860 }, { 4724, 0x8713 }, + { 4731, 0x850d }, { 4737, 0x3428 }, { 4742, 0x0319 }, { 4747, 0xe529 }, + { 4755, 0x2345 }, { 4761, 0x870a }, { 4767, 0x25a9 }, { 4774, 0x5c18 }, + /* 0x8200 */ + { 4780, 0x77a6 }, { 4790, 0xd9c5 }, { 4799, 0x5e00 }, { 4804, 0x03e8 }, + { 4810, 0x0081 }, { 4812, 0xa700 }, { 4817, 0xcd54 }, { 4825, 0x41c6 }, + { 4831, 0x2800 }, { 4833, 0xa204 }, { 4837, 0xb860 }, { 4843, 0x2b0a }, + { 4849, 0x0020 }, { 4850, 0xda9e }, { 4860, 0x08ea }, { 4866, 0x0e1a }, + /* 0x8300 */ + { 4872, 0x427c }, { 4879, 0x11c0 }, { 4883, 0x8908 }, { 4887, 0x0376 }, + { 4894, 0x8621 }, { 4899, 0x0105 }, { 4902, 0x0000 }, { 4902, 0x18a8 }, + { 4907, 0x46a0 }, { 4912, 0xc448 }, { 4917, 0x0d05 }, { 4922, 0x2022 }, + { 4925, 0x5422 }, { 4930, 0x9148 }, { 4935, 0x8a01 }, { 4939, 0x2897 }, + /* 0x8400 */ + { 4946, 0x7898 }, { 4953, 0x0008 }, { 4954, 0x1605 }, { 4959, 0x3122 }, + { 4964, 0x4240 }, { 4967, 0x0880 }, { 4969, 0xfa4e }, { 4979, 0x06a2 }, + { 4984, 0x0814 }, { 4987, 0x9211 }, { 4992, 0x2002 }, { 4994, 0x9b04 }, + { 5000, 0x2e52 }, { 5007, 0x0643 }, { 5012, 0x5000 }, { 5014, 0x9010 }, + /* 0x8500 */ + { 5017, 0x0041 }, { 5019, 0x85ba }, { 5027, 0x3042 }, { 5031, 0x2020 }, + { 5033, 0x4f0b }, { 5041, 0x05a0 }, { 5045, 0x2708 }, { 5050, 0x4080 }, + { 5052, 0x0591 }, { 5057, 0x1a93 }, { 5064, 0xdf50 }, { 5073, 0x0600 }, + { 5075, 0xa202 }, { 5079, 0x3021 }, { 5083, 0x0630 }, { 5087, 0x4e80 }, + /* 0x8600 */ + { 5092, 0x0cc4 }, { 5097, 0x04c8 }, { 5101, 0xa004 }, { 5104, 0x8001 }, + { 5106, 0x6000 }, { 5108, 0xd431 }, { 5115, 0x0880 }, { 5117, 0x0a02 }, + { 5120, 0x1c00 }, { 5123, 0x0028 }, { 5125, 0x8e18 }, { 5131, 0x0041 }, + { 5133, 0x6ad0 }, { 5140, 0xca10 }, { 5145, 0xf210 }, { 5151, 0x4b00 }, + /* 0x8700 */ + { 5155, 0x274d }, { 5163, 0x1506 }, { 5168, 0x0220 }, { 5170, 0x8890 }, + { 5174, 0x5a00 }, { 5178, 0x82a8 }, { 5183, 0x4549 }, { 5189, 0x8150 }, + { 5193, 0x2004 }, { 5195, 0x8000 }, { 5196, 0x8804 }, { 5199, 0x2c08 }, + { 5203, 0x08d1 }, { 5208, 0x0005 }, { 5210, 0x8001 }, { 5212, 0x4ac4 }, + /* 0x8800 */ + { 5218, 0xe020 }, { 5222, 0x0062 }, { 5225, 0x008e }, { 5229, 0x0a42 }, + { 5233, 0x3055 }, { 5239, 0x6a8c }, { 5246, 0x090e }, { 5251, 0xe0a5 }, + { 5258, 0x2906 }, { 5263, 0x42c4 }, { 5268, 0x4814 }, { 5272, 0x80b3 }, + { 5278, 0x803e }, { 5284, 0xb330 }, { 5291, 0x0102 }, { 5293, 0x731c }, + /* 0x8900 */ + { 5301, 0x1494 }, { 5306, 0x600d }, { 5311, 0x0c20 }, { 5314, 0x0940 }, + { 5317, 0x301a }, { 5322, 0xc040 }, { 5325, 0xa451 }, { 5331, 0xc094 }, + { 5336, 0x8dca }, { 5344, 0x05c8 }, { 5349, 0x96c2 }, { 5356, 0xa40c }, + { 5361, 0x0001 }, { 5362, 0x3404 }, { 5366, 0x00c8 }, { 5369, 0x0110 }, + /* 0x8a00 */ + { 5371, 0x550d }, { 5378, 0xa9c9 }, { 5386, 0x2428 }, { 5390, 0x1c5a }, + { 5397, 0x0142 }, { 5400, 0x4837 }, { 5407, 0x7a4d }, { 5416, 0x100f }, + { 5421, 0x32b4 }, { 5428, 0x452a }, { 5434, 0x317b }, { 5443, 0x9205 }, + { 5448, 0xb894 }, { 5455, 0x5c44 }, { 5461, 0x68d7 }, { 5470, 0x458a }, + /* 0x8b00 */ + { 5476, 0x5097 }, { 5483, 0x2ed1 }, { 5491, 0x1943 }, { 5497, 0x4208 }, + { 5500, 0xd202 }, { 5505, 0x9d40 }, { 5511, 0x9840 }, { 5515, 0x2097 }, + { 5521, 0x5409 }, { 5526, 0x064d }, { 5532, 0x0000 }, { 5532, 0x0000 }, + { 5532, 0x0000 }, { 5532, 0x0000 }, { 5532, 0x0000 }, { 5532, 0x0000 }, + /* 0x8c00 */ + { 5532, 0x0000 }, { 5532, 0x0000 }, { 5532, 0x0000 }, { 5532, 0x8480 }, + { 5535, 0x5542 }, { 5541, 0x0421 }, { 5544, 0x1c06 }, { 5549, 0x1700 }, + { 5553, 0x7624 }, { 5560, 0x6110 }, { 5564, 0xff87 }, { 5576, 0xb9dd }, + { 5587, 0x659f }, { 5597, 0x5c0a }, { 5603, 0x245d }, { 5610, 0x3c00 }, + /* 0x8d00 */ + { 5614, 0xadb0 }, { 5622, 0x0059 }, { 5626, 0x0000 }, { 5626, 0x0000 }, + { 5626, 0x0000 }, { 5626, 0x0000 }, { 5626, 0x28d0 }, { 5631, 0x009b }, + { 5636, 0x0422 }, { 5639, 0x0200 }, { 5640, 0x0108 }, { 5642, 0x4408 }, + { 5645, 0x9804 }, { 5649, 0xac40 }, { 5654, 0x8d0a }, { 5660, 0x9028 }, + /* 0x8e00 */ + { 5664, 0x8700 }, { 5668, 0xe001 }, { 5672, 0x0400 }, { 5673, 0x0031 }, + { 5676, 0x1794 }, { 5683, 0x8221 }, { 5687, 0x0019 }, { 5690, 0x1054 }, + { 5694, 0x2cb2 }, { 5701, 0x021a }, { 5705, 0x9c02 }, { 5710, 0x4003 }, + { 5713, 0x3d60 }, { 5720, 0x8804 }, { 5723, 0x080c }, { 5726, 0x7900 }, + /* 0x8f00 */ + { 5731, 0x1628 }, { 5736, 0xba3c }, { 5745, 0x8640 }, { 5749, 0xcb08 }, + { 5755, 0x7274 }, { 5763, 0x9080 }, { 5766, 0x001e }, { 5770, 0x0000 }, + { 5770, 0x0000 }, { 5770, 0xd800 }, { 5774, 0xe188 }, { 5780, 0x9c87 }, + { 5788, 0x4034 }, { 5792, 0x0412 }, { 5795, 0xae64 }, { 5803, 0x2791 }, + /* 0x9000 */ + { 5810, 0xe86b }, { 5819, 0xe6fb }, { 5831, 0x408f }, { 5837, 0x5366 }, + { 5845, 0xeea6 }, { 5855, 0x537f }, { 5866, 0xe32b }, { 5875, 0xb5e4 }, + { 5884, 0x869f }, { 5893, 0x0002 }, { 5894, 0x8548 }, { 5899, 0x0122 }, + { 5902, 0x4402 }, { 5905, 0x0800 }, { 5906, 0x2116 }, { 5911, 0x20a0 }, + /* 0x9100 */ + { 5914, 0x0004 }, { 5915, 0x0204 }, { 5917, 0x2000 }, { 5918, 0x0005 }, + { 5920, 0x7e00 }, { 5926, 0x0154 }, { 5930, 0x162c }, { 5936, 0x01ac }, + { 5941, 0x2a84 }, { 5946, 0x1085 }, { 5950, 0x8c14 }, { 5955, 0x0530 }, + { 5959, 0xfbc3 }, { 5970, 0xb943 }, { 5978, 0x00ca }, { 5982, 0x9060 }, + /* 0x9200 */ + { 5986, 0x6000 }, { 5988, 0x4032 }, { 5992, 0x1200 }, { 5994, 0x8090 }, + { 5997, 0x0b30 }, { 6002, 0x4c81 }, { 6007, 0x0054 }, { 6010, 0x4002 }, + { 6012, 0x0029 }, { 6015, 0x1d6a }, { 6023, 0x2000 }, { 6024, 0x0280 }, + { 6026, 0x8000 }, { 6027, 0x0004 }, { 6028, 0x2610 }, { 6032, 0x150c }, + /* 0x9300 */ + { 6037, 0x8040 }, { 6039, 0x0701 }, { 6043, 0xd94d }, { 6052, 0x0c24 }, + { 6056, 0x2810 }, { 6059, 0x1850 }, { 6063, 0x5001 }, { 6066, 0x5020 }, + { 6069, 0x1000 }, { 6070, 0x04d0 }, { 6074, 0x7080 }, { 6078, 0x0201 }, + { 6080, 0x0108 }, { 6082, 0x21c3 }, { 6088, 0x0132 }, { 6092, 0x0000 }, + /* 0x9400 */ + { 6092, 0x0088 }, { 6094, 0x0719 }, { 6100, 0x0802 }, { 6102, 0x0560 }, + { 6106, 0x0012 }, { 6108, 0x4c0e }, { 6114, 0x0405 }, { 6117, 0xf0a1 }, + { 6124, 0x0002 }, { 6125, 0x0000 }, { 6125, 0x0000 }, { 6125, 0x0000 }, + { 6125, 0x0000 }, { 6125, 0x0000 }, { 6125, 0x0000 }, { 6125, 0x0000 }, + /* 0x9500 */ + { 6125, 0x0000 }, { 6125, 0x0000 }, { 6125, 0x0000 }, { 6125, 0x0000 }, + { 6125, 0x0000 }, { 6125, 0x0000 }, { 6125, 0x0000 }, { 6125, 0x0080 }, + { 6126, 0x8e8d }, { 6134, 0x035a }, { 6140, 0x21bd }, { 6148, 0x5a04 }, + { 6153, 0x3488 }, { 6158, 0x1170 }, { 6163, 0x0026 }, { 6166, 0x0000 }, + /* 0x9600 */ + { 6166, 0x0000 }, { 6166, 0x1000 }, { 6167, 0xc502 }, { 6172, 0x8804 }, + { 6175, 0xb815 }, { 6182, 0xf801 }, { 6188, 0x147c }, { 6195, 0x25ed }, + { 6204, 0xed60 }, { 6212, 0x1bb0 }, { 6219, 0x0589 }, { 6224, 0x1bd7 }, + { 6234, 0x7af3 }, { 6245, 0x1a62 }, { 6251, 0x0d0c }, { 6256, 0x0ac5 }, + /* 0x9700 */ + { 6262, 0xe5d1 }, { 6271, 0x524a }, { 6277, 0x0490 }, { 6280, 0x6305 }, + { 6286, 0x0354 }, { 6291, 0x5244 }, { 6296, 0x2b57 }, { 6305, 0x1612 }, + { 6310, 0xa872 }, { 6317, 0x1101 }, { 6320, 0x2949 }, { 6326, 0x0018 }, + { 6328, 0x0948 }, { 6332, 0x1008 }, { 6334, 0x6000 }, { 6336, 0x886c }, + /* 0x9800 */ + { 6342, 0x916e }, { 6350, 0x058f }, { 6357, 0x3012 }, { 6361, 0x3990 }, + { 6367, 0xf840 }, { 6373, 0x4930 }, { 6378, 0x8880 }, { 6381, 0x001b }, + { 6385, 0x0000 }, { 6385, 0x0000 }, { 6385, 0x8500 }, { 6388, 0x0042 }, + { 6390, 0x0058 }, { 6393, 0x9800 }, { 6396, 0xea04 }, { 6402, 0x7014 }, + /* 0x9900 */ + { 6407, 0x1628 }, { 6412, 0x611d }, { 6419, 0x5113 }, { 6425, 0x6000 }, + { 6427, 0x1a24 }, { 6432, 0x00a7 }, { 6437, 0x0000 }, { 6437, 0x0000 }, + { 6437, 0x0000 }, { 6437, 0x03c0 }, { 6441, 0x7120 }, { 6446, 0x1018 }, + { 6449, 0x0172 }, { 6454, 0xa927 }, { 6462, 0x6004 }, { 6465, 0x8906 }, + /* 0x9a00 */ + { 6470, 0xc022 }, { 6474, 0x020c }, { 6477, 0x0900 }, { 6479, 0x4081 }, + { 6482, 0x202d }, { 6487, 0x8ca0 }, { 6492, 0x0e34 }, { 6498, 0x0000 }, + { 6498, 0x0000 }, { 6498, 0x0000 }, { 6498, 0x2100 }, { 6500, 0x1101 }, + { 6503, 0x8011 }, { 6506, 0xc11a }, { 6512, 0xec4c }, { 6520, 0x0892 }, + /* 0x9b00 */ + { 6524, 0x0040 }, { 6525, 0x8500 }, { 6528, 0xc7ac }, { 6537, 0x1806 }, + { 6541, 0xe03e }, { 6549, 0x0512 }, { 6553, 0x8000 }, { 6554, 0x0010 }, + { 6555, 0x4008 }, { 6557, 0x80ce }, { 6563, 0x6d01 }, { 6569, 0x0210 }, + { 6571, 0x8641 }, { 6576, 0x0856 }, { 6581, 0x011e }, { 6586, 0x0027 }, + /* 0x9c00 */ + { 6590, 0x3750 }, { 6597, 0x083d }, { 6603, 0xe032 }, { 6609, 0x4e05 }, + { 6615, 0x01c0 }, { 6618, 0x0484 }, { 6621, 0x0081 }, { 6623, 0x0140 }, + { 6625, 0x0000 }, { 6625, 0x0000 }, { 6625, 0x0000 }, { 6625, 0x0000 }, + { 6625, 0x0000 }, { 6625, 0x0000 }, { 6625, 0x1aa0 }, { 6630, 0x0059 }, + /* 0x9d00 */ + { 6634, 0x43c8 }, { 6640, 0x8824 }, { 6644, 0x1d48 }, { 6650, 0xc800 }, + { 6653, 0x0152 }, { 6657, 0x7203 }, { 6663, 0x9013 }, { 6668, 0x0404 }, + { 6670, 0x8280 }, { 6673, 0x0400 }, { 6674, 0x8a10 }, { 6678, 0x0d14 }, + { 6683, 0x8056 }, { 6688, 0x0208 }, { 6690, 0xa040 }, { 6693, 0x2704 }, + /* 0x9e00 */ + { 6698, 0x0000 }, { 6698, 0x4c00 }, { 6701, 0x0000 }, { 6701, 0x0000 }, + { 6701, 0x0000 }, { 6701, 0x0000 }, { 6701, 0x0000 }, { 6701, 0xa320 }, + { 6706, 0x1902 }, { 6710, 0xa0ae }, { 6717, 0x2660 }, { 6722, 0xdf00 }, + { 6729, 0xf010 }, { 6734, 0x7b15 }, { 6743, 0x8121 }, { 6747, 0x3ad0 }, + /* 0x9f00 */ + { 6754, 0x4180 }, { 6757, 0x0028 }, { 6759, 0x1003 }, { 6762, 0x4800 }, + { 6764, 0xcc00 }, { 6768, 0x8014 }, { 6771, 0x14cf }, { 6779, 0x00c4 }, + { 6782, 0x2000 }, { 6783, 0x3020 }, { 6786, 0x0001 }, +}; +static const Summary16 jisx0208_uni2indx_pageff[15] = { + /* 0xff00 */ + { 6787, 0xdf7a }, { 6799, 0xffff }, { 6815, 0xffff }, { 6831, 0xffff }, + { 6847, 0xffff }, { 6863, 0x3fff }, { 6877, 0x0000 }, { 6877, 0x0000 }, + { 6877, 0x0000 }, { 6877, 0x0000 }, { 6877, 0x0000 }, { 6877, 0x0000 }, + { 6877, 0x0000 }, { 6877, 0x0000 }, { 6877, 0x0028 }, +}; + +static int +jisx0208_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc >= 0x0000 && wc < 0x0100) + summary = &jisx0208_uni2indx_page00[(wc>>4)]; + else if (wc >= 0x0300 && wc < 0x0460) + summary = &jisx0208_uni2indx_page03[(wc>>4)-0x030]; + else if (wc >= 0x2000 && wc < 0x2320) + summary = &jisx0208_uni2indx_page20[(wc>>4)-0x200]; + else if (wc >= 0x2500 && wc < 0x2670) + summary = &jisx0208_uni2indx_page25[(wc>>4)-0x250]; + else if (wc >= 0x3000 && wc < 0x3100) + summary = &jisx0208_uni2indx_page30[(wc>>4)-0x300]; + else if (wc >= 0x4e00 && wc < 0x9fb0) + summary = &jisx0208_uni2indx_page4e[(wc>>4)-0x4e0]; + else if (wc >= 0xff00 && wc < 0xfff0) + summary = &jisx0208_uni2indx_pageff[(wc>>4)-0xff0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = jisx0208_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/jisx0212.h b/libs/libiconv/lib/jisx0212.h new file mode 100644 index 00000000..371dbb15 --- /dev/null +++ b/libs/libiconv/lib/jisx0212.h @@ -0,0 +1,2189 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * JISX0212.1990-0 + */ + +static const unsigned short jisx0212_2uni_page22[81] = { + /* 0x22 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x02d8, 0x02c7, + 0x00b8, 0x02d9, 0x02dd, 0x00af, 0x02db, 0x02da, 0xff5e, 0x0384, + 0x0385, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x00a1, 0x00a6, 0x00bf, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0x00ba, 0x00aa, 0x00a9, 0x00ae, 0x2122, 0x00a4, + 0x2116, +}; +static const unsigned short jisx0212_2uni_page26[188] = { + /* 0x26 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x0386, 0x0388, 0x0389, 0x038a, 0x03aa, 0xfffd, 0x038c, 0xfffd, + 0x038e, 0x03ab, 0xfffd, 0x038f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x03ac, 0x03ad, 0x03ae, 0x03af, 0x03ca, 0x0390, 0x03cc, 0x03c2, + 0x03cd, 0x03cb, 0x03b0, 0x03ce, 0xfffd, 0xfffd, + /* 0x27 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, + 0x0409, 0x040a, 0x040b, 0x040c, 0x040e, 0x040f, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, + 0x0459, 0x045a, 0x045b, 0x045c, 0x045e, 0x045f, +}; +static const unsigned short jisx0212_2uni_page29[275] = { + /* 0x29 */ + 0x00c6, 0x0110, 0xfffd, 0x0126, 0xfffd, 0x0132, 0xfffd, 0x0141, + 0x013f, 0xfffd, 0x014a, 0x00d8, 0x0152, 0xfffd, 0x0166, 0x00de, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0138, 0x0142, + 0x0140, 0x0149, 0x014b, 0x00f8, 0x0153, 0x00df, 0x0167, 0x00fe, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x2a */ + 0x00c1, 0x00c0, 0x00c4, 0x00c2, 0x0102, 0x01cd, 0x0100, 0x0104, + 0x00c5, 0x00c3, 0x0106, 0x0108, 0x010c, 0x00c7, 0x010a, 0x010e, + 0x00c9, 0x00c8, 0x00cb, 0x00ca, 0x011a, 0x0116, 0x0112, 0x0118, + 0xfffd, 0x011c, 0x011e, 0x0122, 0x0120, 0x0124, 0x00cd, 0x00cc, + 0x00cf, 0x00ce, 0x01cf, 0x0130, 0x012a, 0x012e, 0x0128, 0x0134, + 0x0136, 0x0139, 0x013d, 0x013b, 0x0143, 0x0147, 0x0145, 0x00d1, + 0x00d3, 0x00d2, 0x00d6, 0x00d4, 0x01d1, 0x0150, 0x014c, 0x00d5, + 0x0154, 0x0158, 0x0156, 0x015a, 0x015c, 0x0160, 0x015e, 0x0164, + 0x0162, 0x00da, 0x00d9, 0x00dc, 0x00db, 0x016c, 0x01d3, 0x0170, + 0x016a, 0x0172, 0x016e, 0x0168, 0x01d7, 0x01db, 0x01d9, 0x01d5, + 0x0174, 0x00dd, 0x0178, 0x0176, 0x0179, 0x017d, 0x017b, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x2b */ + 0x00e1, 0x00e0, 0x00e4, 0x00e2, 0x0103, 0x01ce, 0x0101, 0x0105, + 0x00e5, 0x00e3, 0x0107, 0x0109, 0x010d, 0x00e7, 0x010b, 0x010f, + 0x00e9, 0x00e8, 0x00eb, 0x00ea, 0x011b, 0x0117, 0x0113, 0x0119, + 0x01f5, 0x011d, 0x011f, 0xfffd, 0x0121, 0x0125, 0x00ed, 0x00ec, + 0x00ef, 0x00ee, 0x01d0, 0xfffd, 0x012b, 0x012f, 0x0129, 0x0135, + 0x0137, 0x013a, 0x013e, 0x013c, 0x0144, 0x0148, 0x0146, 0x00f1, + 0x00f3, 0x00f2, 0x00f6, 0x00f4, 0x01d2, 0x0151, 0x014d, 0x00f5, + 0x0155, 0x0159, 0x0157, 0x015b, 0x015d, 0x0161, 0x015f, 0x0165, + 0x0163, 0x00fa, 0x00f9, 0x00fc, 0x00fb, 0x016d, 0x01d4, 0x0171, + 0x016b, 0x0173, 0x016f, 0x0169, 0x01d8, 0x01dc, 0x01da, 0x01d6, + 0x0175, 0x00fd, 0x00ff, 0x0177, 0x017a, 0x017e, 0x017c, +}; +static const unsigned short jisx0212_2uni_page30[5801] = { + /* 0x30 */ + 0x4e02, 0x4e04, 0x4e05, 0x4e0c, 0x4e12, 0x4e1f, 0x4e23, 0x4e24, + 0x4e28, 0x4e2b, 0x4e2e, 0x4e2f, 0x4e30, 0x4e35, 0x4e40, 0x4e41, + 0x4e44, 0x4e47, 0x4e51, 0x4e5a, 0x4e5c, 0x4e63, 0x4e68, 0x4e69, + 0x4e74, 0x4e75, 0x4e79, 0x4e7f, 0x4e8d, 0x4e96, 0x4e97, 0x4e9d, + 0x4eaf, 0x4eb9, 0x4ec3, 0x4ed0, 0x4eda, 0x4edb, 0x4ee0, 0x4ee1, + 0x4ee2, 0x4ee8, 0x4eef, 0x4ef1, 0x4ef3, 0x4ef5, 0x4efd, 0x4efe, + 0x4eff, 0x4f00, 0x4f02, 0x4f03, 0x4f08, 0x4f0b, 0x4f0c, 0x4f12, + 0x4f15, 0x4f16, 0x4f17, 0x4f19, 0x4f2e, 0x4f31, 0x4f60, 0x4f33, + 0x4f35, 0x4f37, 0x4f39, 0x4f3b, 0x4f3e, 0x4f40, 0x4f42, 0x4f48, + 0x4f49, 0x4f4b, 0x4f4c, 0x4f52, 0x4f54, 0x4f56, 0x4f58, 0x4f5f, + 0x4f63, 0x4f6a, 0x4f6c, 0x4f6e, 0x4f71, 0x4f77, 0x4f78, 0x4f79, + 0x4f7a, 0x4f7d, 0x4f7e, 0x4f81, 0x4f82, 0x4f84, + /* 0x31 */ + 0x4f85, 0x4f89, 0x4f8a, 0x4f8c, 0x4f8e, 0x4f90, 0x4f92, 0x4f93, + 0x4f94, 0x4f97, 0x4f99, 0x4f9a, 0x4f9e, 0x4f9f, 0x4fb2, 0x4fb7, + 0x4fb9, 0x4fbb, 0x4fbc, 0x4fbd, 0x4fbe, 0x4fc0, 0x4fc1, 0x4fc5, + 0x4fc6, 0x4fc8, 0x4fc9, 0x4fcb, 0x4fcc, 0x4fcd, 0x4fcf, 0x4fd2, + 0x4fdc, 0x4fe0, 0x4fe2, 0x4ff0, 0x4ff2, 0x4ffc, 0x4ffd, 0x4fff, + 0x5000, 0x5001, 0x5004, 0x5007, 0x500a, 0x500c, 0x500e, 0x5010, + 0x5013, 0x5017, 0x5018, 0x501b, 0x501c, 0x501d, 0x501e, 0x5022, + 0x5027, 0x502e, 0x5030, 0x5032, 0x5033, 0x5035, 0x5040, 0x5041, + 0x5042, 0x5045, 0x5046, 0x504a, 0x504c, 0x504e, 0x5051, 0x5052, + 0x5053, 0x5057, 0x5059, 0x505f, 0x5060, 0x5062, 0x5063, 0x5066, + 0x5067, 0x506a, 0x506d, 0x5070, 0x5071, 0x503b, 0x5081, 0x5083, + 0x5084, 0x5086, 0x508a, 0x508e, 0x508f, 0x5090, + /* 0x32 */ + 0x5092, 0x5093, 0x5094, 0x5096, 0x509b, 0x509c, 0x509e, 0x509f, + 0x50a0, 0x50a1, 0x50a2, 0x50aa, 0x50af, 0x50b0, 0x50b9, 0x50ba, + 0x50bd, 0x50c0, 0x50c3, 0x50c4, 0x50c7, 0x50cc, 0x50ce, 0x50d0, + 0x50d3, 0x50d4, 0x50d8, 0x50dc, 0x50dd, 0x50df, 0x50e2, 0x50e4, + 0x50e6, 0x50e8, 0x50e9, 0x50ef, 0x50f1, 0x50f6, 0x50fa, 0x50fe, + 0x5103, 0x5106, 0x5107, 0x5108, 0x510b, 0x510c, 0x510d, 0x510e, + 0x50f2, 0x5110, 0x5117, 0x5119, 0x511b, 0x511c, 0x511d, 0x511e, + 0x5123, 0x5127, 0x5128, 0x512c, 0x512d, 0x512f, 0x5131, 0x5133, + 0x5134, 0x5135, 0x5138, 0x5139, 0x5142, 0x514a, 0x514f, 0x5153, + 0x5155, 0x5157, 0x5158, 0x515f, 0x5164, 0x5166, 0x517e, 0x5183, + 0x5184, 0x518b, 0x518e, 0x5198, 0x519d, 0x51a1, 0x51a3, 0x51ad, + 0x51b8, 0x51ba, 0x51bc, 0x51be, 0x51bf, 0x51c2, + /* 0x33 */ + 0x51c8, 0x51cf, 0x51d1, 0x51d2, 0x51d3, 0x51d5, 0x51d8, 0x51de, + 0x51e2, 0x51e5, 0x51ee, 0x51f2, 0x51f3, 0x51f4, 0x51f7, 0x5201, + 0x5202, 0x5205, 0x5212, 0x5213, 0x5215, 0x5216, 0x5218, 0x5222, + 0x5228, 0x5231, 0x5232, 0x5235, 0x523c, 0x5245, 0x5249, 0x5255, + 0x5257, 0x5258, 0x525a, 0x525c, 0x525f, 0x5260, 0x5261, 0x5266, + 0x526e, 0x5277, 0x5278, 0x5279, 0x5280, 0x5282, 0x5285, 0x528a, + 0x528c, 0x5293, 0x5295, 0x5296, 0x5297, 0x5298, 0x529a, 0x529c, + 0x52a4, 0x52a5, 0x52a6, 0x52a7, 0x52af, 0x52b0, 0x52b6, 0x52b7, + 0x52b8, 0x52ba, 0x52bb, 0x52bd, 0x52c0, 0x52c4, 0x52c6, 0x52c8, + 0x52cc, 0x52cf, 0x52d1, 0x52d4, 0x52d6, 0x52db, 0x52dc, 0x52e1, + 0x52e5, 0x52e8, 0x52e9, 0x52ea, 0x52ec, 0x52f0, 0x52f1, 0x52f4, + 0x52f6, 0x52f7, 0x5300, 0x5303, 0x530a, 0x530b, + /* 0x34 */ + 0x530c, 0x5311, 0x5313, 0x5318, 0x531b, 0x531c, 0x531e, 0x531f, + 0x5325, 0x5327, 0x5328, 0x5329, 0x532b, 0x532c, 0x532d, 0x5330, + 0x5332, 0x5335, 0x533c, 0x533d, 0x533e, 0x5342, 0x534c, 0x534b, + 0x5359, 0x535b, 0x5361, 0x5363, 0x5365, 0x536c, 0x536d, 0x5372, + 0x5379, 0x537e, 0x5383, 0x5387, 0x5388, 0x538e, 0x5393, 0x5394, + 0x5399, 0x539d, 0x53a1, 0x53a4, 0x53aa, 0x53ab, 0x53af, 0x53b2, + 0x53b4, 0x53b5, 0x53b7, 0x53b8, 0x53ba, 0x53bd, 0x53c0, 0x53c5, + 0x53cf, 0x53d2, 0x53d3, 0x53d5, 0x53da, 0x53dd, 0x53de, 0x53e0, + 0x53e6, 0x53e7, 0x53f5, 0x5402, 0x5413, 0x541a, 0x5421, 0x5427, + 0x5428, 0x542a, 0x542f, 0x5431, 0x5434, 0x5435, 0x5443, 0x5444, + 0x5447, 0x544d, 0x544f, 0x545e, 0x5462, 0x5464, 0x5466, 0x5467, + 0x5469, 0x546b, 0x546d, 0x546e, 0x5474, 0x547f, + /* 0x35 */ + 0x5481, 0x5483, 0x5485, 0x5488, 0x5489, 0x548d, 0x5491, 0x5495, + 0x5496, 0x549c, 0x549f, 0x54a1, 0x54a6, 0x54a7, 0x54a9, 0x54aa, + 0x54ad, 0x54ae, 0x54b1, 0x54b7, 0x54b9, 0x54ba, 0x54bb, 0x54bf, + 0x54c6, 0x54ca, 0x54cd, 0x54ce, 0x54e0, 0x54ea, 0x54ec, 0x54ef, + 0x54f6, 0x54fc, 0x54fe, 0x54ff, 0x5500, 0x5501, 0x5505, 0x5508, + 0x5509, 0x550c, 0x550d, 0x550e, 0x5515, 0x552a, 0x552b, 0x5532, + 0x5535, 0x5536, 0x553b, 0x553c, 0x553d, 0x5541, 0x5547, 0x5549, + 0x554a, 0x554d, 0x5550, 0x5551, 0x5558, 0x555a, 0x555b, 0x555e, + 0x5560, 0x5561, 0x5564, 0x5566, 0x557f, 0x5581, 0x5582, 0x5586, + 0x5588, 0x558e, 0x558f, 0x5591, 0x5592, 0x5593, 0x5594, 0x5597, + 0x55a3, 0x55a4, 0x55ad, 0x55b2, 0x55bf, 0x55c1, 0x55c3, 0x55c6, + 0x55c9, 0x55cb, 0x55cc, 0x55ce, 0x55d1, 0x55d2, + /* 0x36 */ + 0x55d3, 0x55d7, 0x55d8, 0x55db, 0x55de, 0x55e2, 0x55e9, 0x55f6, + 0x55ff, 0x5605, 0x5608, 0x560a, 0x560d, 0x560e, 0x560f, 0x5610, + 0x5611, 0x5612, 0x5619, 0x562c, 0x5630, 0x5633, 0x5635, 0x5637, + 0x5639, 0x563b, 0x563c, 0x563d, 0x563f, 0x5640, 0x5641, 0x5643, + 0x5644, 0x5646, 0x5649, 0x564b, 0x564d, 0x564f, 0x5654, 0x565e, + 0x5660, 0x5661, 0x5662, 0x5663, 0x5666, 0x5669, 0x566d, 0x566f, + 0x5671, 0x5672, 0x5675, 0x5684, 0x5685, 0x5688, 0x568b, 0x568c, + 0x5695, 0x5699, 0x569a, 0x569d, 0x569e, 0x569f, 0x56a6, 0x56a7, + 0x56a8, 0x56a9, 0x56ab, 0x56ac, 0x56ad, 0x56b1, 0x56b3, 0x56b7, + 0x56be, 0x56c5, 0x56c9, 0x56ca, 0x56cb, 0x56cf, 0x56d0, 0x56cc, + 0x56cd, 0x56d9, 0x56dc, 0x56dd, 0x56df, 0x56e1, 0x56e4, 0x56e5, + 0x56e6, 0x56e7, 0x56e8, 0x56f1, 0x56eb, 0x56ed, + /* 0x37 */ + 0x56f6, 0x56f7, 0x5701, 0x5702, 0x5707, 0x570a, 0x570c, 0x5711, + 0x5715, 0x571a, 0x571b, 0x571d, 0x5720, 0x5722, 0x5723, 0x5724, + 0x5725, 0x5729, 0x572a, 0x572c, 0x572e, 0x572f, 0x5733, 0x5734, + 0x573d, 0x573e, 0x573f, 0x5745, 0x5746, 0x574c, 0x574d, 0x5752, + 0x5762, 0x5765, 0x5767, 0x5768, 0x576b, 0x576d, 0x576e, 0x576f, + 0x5770, 0x5771, 0x5773, 0x5774, 0x5775, 0x5777, 0x5779, 0x577a, + 0x577b, 0x577c, 0x577e, 0x5781, 0x5783, 0x578c, 0x5794, 0x5797, + 0x5799, 0x579a, 0x579c, 0x579d, 0x579e, 0x579f, 0x57a1, 0x5795, + 0x57a7, 0x57a8, 0x57a9, 0x57ac, 0x57b8, 0x57bd, 0x57c7, 0x57c8, + 0x57cc, 0x57cf, 0x57d5, 0x57dd, 0x57de, 0x57e4, 0x57e6, 0x57e7, + 0x57e9, 0x57ed, 0x57f0, 0x57f5, 0x57f6, 0x57f8, 0x57fd, 0x57fe, + 0x57ff, 0x5803, 0x5804, 0x5808, 0x5809, 0x57e1, + /* 0x38 */ + 0x580c, 0x580d, 0x581b, 0x581e, 0x581f, 0x5820, 0x5826, 0x5827, + 0x582d, 0x5832, 0x5839, 0x583f, 0x5849, 0x584c, 0x584d, 0x584f, + 0x5850, 0x5855, 0x585f, 0x5861, 0x5864, 0x5867, 0x5868, 0x5878, + 0x587c, 0x587f, 0x5880, 0x5881, 0x5887, 0x5888, 0x5889, 0x588a, + 0x588c, 0x588d, 0x588f, 0x5890, 0x5894, 0x5896, 0x589d, 0x58a0, + 0x58a1, 0x58a2, 0x58a6, 0x58a9, 0x58b1, 0x58b2, 0x58c4, 0x58bc, + 0x58c2, 0x58c8, 0x58cd, 0x58ce, 0x58d0, 0x58d2, 0x58d4, 0x58d6, + 0x58da, 0x58dd, 0x58e1, 0x58e2, 0x58e9, 0x58f3, 0x5905, 0x5906, + 0x590b, 0x590c, 0x5912, 0x5913, 0x5914, 0x8641, 0x591d, 0x5921, + 0x5923, 0x5924, 0x5928, 0x592f, 0x5930, 0x5933, 0x5935, 0x5936, + 0x593f, 0x5943, 0x5946, 0x5952, 0x5953, 0x5959, 0x595b, 0x595d, + 0x595e, 0x595f, 0x5961, 0x5963, 0x596b, 0x596d, + /* 0x39 */ + 0x596f, 0x5972, 0x5975, 0x5976, 0x5979, 0x597b, 0x597c, 0x598b, + 0x598c, 0x598e, 0x5992, 0x5995, 0x5997, 0x599f, 0x59a4, 0x59a7, + 0x59ad, 0x59ae, 0x59af, 0x59b0, 0x59b3, 0x59b7, 0x59ba, 0x59bc, + 0x59c1, 0x59c3, 0x59c4, 0x59c8, 0x59ca, 0x59cd, 0x59d2, 0x59dd, + 0x59de, 0x59df, 0x59e3, 0x59e4, 0x59e7, 0x59ee, 0x59ef, 0x59f1, + 0x59f2, 0x59f4, 0x59f7, 0x5a00, 0x5a04, 0x5a0c, 0x5a0d, 0x5a0e, + 0x5a12, 0x5a13, 0x5a1e, 0x5a23, 0x5a24, 0x5a27, 0x5a28, 0x5a2a, + 0x5a2d, 0x5a30, 0x5a44, 0x5a45, 0x5a47, 0x5a48, 0x5a4c, 0x5a50, + 0x5a55, 0x5a5e, 0x5a63, 0x5a65, 0x5a67, 0x5a6d, 0x5a77, 0x5a7a, + 0x5a7b, 0x5a7e, 0x5a8b, 0x5a90, 0x5a93, 0x5a96, 0x5a99, 0x5a9c, + 0x5a9e, 0x5a9f, 0x5aa0, 0x5aa2, 0x5aa7, 0x5aac, 0x5ab1, 0x5ab2, + 0x5ab3, 0x5ab5, 0x5ab8, 0x5aba, 0x5abb, 0x5abf, + /* 0x3a */ + 0x5ac4, 0x5ac6, 0x5ac8, 0x5acf, 0x5ada, 0x5adc, 0x5ae0, 0x5ae5, + 0x5aea, 0x5aee, 0x5af5, 0x5af6, 0x5afd, 0x5b00, 0x5b01, 0x5b08, + 0x5b17, 0x5b34, 0x5b19, 0x5b1b, 0x5b1d, 0x5b21, 0x5b25, 0x5b2d, + 0x5b38, 0x5b41, 0x5b4b, 0x5b4c, 0x5b52, 0x5b56, 0x5b5e, 0x5b68, + 0x5b6e, 0x5b6f, 0x5b7c, 0x5b7d, 0x5b7e, 0x5b7f, 0x5b81, 0x5b84, + 0x5b86, 0x5b8a, 0x5b8e, 0x5b90, 0x5b91, 0x5b93, 0x5b94, 0x5b96, + 0x5ba8, 0x5ba9, 0x5bac, 0x5bad, 0x5baf, 0x5bb1, 0x5bb2, 0x5bb7, + 0x5bba, 0x5bbc, 0x5bc0, 0x5bc1, 0x5bcd, 0x5bcf, 0x5bd6, 0x5bd7, + 0x5bd8, 0x5bd9, 0x5bda, 0x5be0, 0x5bef, 0x5bf1, 0x5bf4, 0x5bfd, + 0x5c0c, 0x5c17, 0x5c1e, 0x5c1f, 0x5c23, 0x5c26, 0x5c29, 0x5c2b, + 0x5c2c, 0x5c2e, 0x5c30, 0x5c32, 0x5c35, 0x5c36, 0x5c59, 0x5c5a, + 0x5c5c, 0x5c62, 0x5c63, 0x5c67, 0x5c68, 0x5c69, + /* 0x3b */ + 0x5c6d, 0x5c70, 0x5c74, 0x5c75, 0x5c7a, 0x5c7b, 0x5c7c, 0x5c7d, + 0x5c87, 0x5c88, 0x5c8a, 0x5c8f, 0x5c92, 0x5c9d, 0x5c9f, 0x5ca0, + 0x5ca2, 0x5ca3, 0x5ca6, 0x5caa, 0x5cb2, 0x5cb4, 0x5cb5, 0x5cba, + 0x5cc9, 0x5ccb, 0x5cd2, 0x5cdd, 0x5cd7, 0x5cee, 0x5cf1, 0x5cf2, + 0x5cf4, 0x5d01, 0x5d06, 0x5d0d, 0x5d12, 0x5d2b, 0x5d23, 0x5d24, + 0x5d26, 0x5d27, 0x5d31, 0x5d34, 0x5d39, 0x5d3d, 0x5d3f, 0x5d42, + 0x5d43, 0x5d46, 0x5d48, 0x5d55, 0x5d51, 0x5d59, 0x5d4a, 0x5d5f, + 0x5d60, 0x5d61, 0x5d62, 0x5d64, 0x5d6a, 0x5d6d, 0x5d70, 0x5d79, + 0x5d7a, 0x5d7e, 0x5d7f, 0x5d81, 0x5d83, 0x5d88, 0x5d8a, 0x5d92, + 0x5d93, 0x5d94, 0x5d95, 0x5d99, 0x5d9b, 0x5d9f, 0x5da0, 0x5da7, + 0x5dab, 0x5db0, 0x5db4, 0x5db8, 0x5db9, 0x5dc3, 0x5dc7, 0x5dcb, + 0x5dd0, 0x5dce, 0x5dd8, 0x5dd9, 0x5de0, 0x5de4, + /* 0x3c */ + 0x5de9, 0x5df8, 0x5df9, 0x5e00, 0x5e07, 0x5e0d, 0x5e12, 0x5e14, + 0x5e15, 0x5e18, 0x5e1f, 0x5e20, 0x5e2e, 0x5e28, 0x5e32, 0x5e35, + 0x5e3e, 0x5e4b, 0x5e50, 0x5e49, 0x5e51, 0x5e56, 0x5e58, 0x5e5b, + 0x5e5c, 0x5e5e, 0x5e68, 0x5e6a, 0x5e6b, 0x5e6c, 0x5e6d, 0x5e6e, + 0x5e70, 0x5e80, 0x5e8b, 0x5e8e, 0x5ea2, 0x5ea4, 0x5ea5, 0x5ea8, + 0x5eaa, 0x5eac, 0x5eb1, 0x5eb3, 0x5ebd, 0x5ebe, 0x5ebf, 0x5ec6, + 0x5ecc, 0x5ecb, 0x5ece, 0x5ed1, 0x5ed2, 0x5ed4, 0x5ed5, 0x5edc, + 0x5ede, 0x5ee5, 0x5eeb, 0x5f02, 0x5f06, 0x5f07, 0x5f08, 0x5f0e, + 0x5f19, 0x5f1c, 0x5f1d, 0x5f21, 0x5f22, 0x5f23, 0x5f24, 0x5f28, + 0x5f2b, 0x5f2c, 0x5f2e, 0x5f30, 0x5f34, 0x5f36, 0x5f3b, 0x5f3d, + 0x5f3f, 0x5f40, 0x5f44, 0x5f45, 0x5f47, 0x5f4d, 0x5f50, 0x5f54, + 0x5f58, 0x5f5b, 0x5f60, 0x5f63, 0x5f64, 0x5f67, + /* 0x3d */ + 0x5f6f, 0x5f72, 0x5f74, 0x5f75, 0x5f78, 0x5f7a, 0x5f7d, 0x5f7e, + 0x5f89, 0x5f8d, 0x5f8f, 0x5f96, 0x5f9c, 0x5f9d, 0x5fa2, 0x5fa7, + 0x5fab, 0x5fa4, 0x5fac, 0x5faf, 0x5fb0, 0x5fb1, 0x5fb8, 0x5fc4, + 0x5fc7, 0x5fc8, 0x5fc9, 0x5fcb, 0x5fd0, 0x5fd1, 0x5fd2, 0x5fd3, + 0x5fd4, 0x5fde, 0x5fe1, 0x5fe2, 0x5fe8, 0x5fe9, 0x5fea, 0x5fec, + 0x5fed, 0x5fee, 0x5fef, 0x5ff2, 0x5ff3, 0x5ff6, 0x5ffa, 0x5ffc, + 0x6007, 0x600a, 0x600d, 0x6013, 0x6014, 0x6017, 0x6018, 0x601a, + 0x601f, 0x6024, 0x602d, 0x6033, 0x6035, 0x6040, 0x6047, 0x6048, + 0x6049, 0x604c, 0x6051, 0x6054, 0x6056, 0x6057, 0x605d, 0x6061, + 0x6067, 0x6071, 0x607e, 0x607f, 0x6082, 0x6086, 0x6088, 0x608a, + 0x608e, 0x6091, 0x6093, 0x6095, 0x6098, 0x609d, 0x609e, 0x60a2, + 0x60a4, 0x60a5, 0x60a8, 0x60b0, 0x60b1, 0x60b7, + /* 0x3e */ + 0x60bb, 0x60be, 0x60c2, 0x60c4, 0x60c8, 0x60c9, 0x60ca, 0x60cb, + 0x60ce, 0x60cf, 0x60d4, 0x60d5, 0x60d9, 0x60db, 0x60dd, 0x60de, + 0x60e2, 0x60e5, 0x60f2, 0x60f5, 0x60f8, 0x60fc, 0x60fd, 0x6102, + 0x6107, 0x610a, 0x610c, 0x6110, 0x6111, 0x6112, 0x6113, 0x6114, + 0x6116, 0x6117, 0x6119, 0x611c, 0x611e, 0x6122, 0x612a, 0x612b, + 0x6130, 0x6131, 0x6135, 0x6136, 0x6137, 0x6139, 0x6141, 0x6145, + 0x6146, 0x6149, 0x615e, 0x6160, 0x616c, 0x6172, 0x6178, 0x617b, + 0x617c, 0x617f, 0x6180, 0x6181, 0x6183, 0x6184, 0x618b, 0x618d, + 0x6192, 0x6193, 0x6197, 0x6198, 0x619c, 0x619d, 0x619f, 0x61a0, + 0x61a5, 0x61a8, 0x61aa, 0x61ad, 0x61b8, 0x61b9, 0x61bc, 0x61c0, + 0x61c1, 0x61c2, 0x61ce, 0x61cf, 0x61d5, 0x61dc, 0x61dd, 0x61de, + 0x61df, 0x61e1, 0x61e2, 0x61e7, 0x61e9, 0x61e5, + /* 0x3f */ + 0x61ec, 0x61ed, 0x61ef, 0x6201, 0x6203, 0x6204, 0x6207, 0x6213, + 0x6215, 0x621c, 0x6220, 0x6222, 0x6223, 0x6227, 0x6229, 0x622b, + 0x6239, 0x623d, 0x6242, 0x6243, 0x6244, 0x6246, 0x624c, 0x6250, + 0x6251, 0x6252, 0x6254, 0x6256, 0x625a, 0x625c, 0x6264, 0x626d, + 0x626f, 0x6273, 0x627a, 0x627d, 0x628d, 0x628e, 0x628f, 0x6290, + 0x62a6, 0x62a8, 0x62b3, 0x62b6, 0x62b7, 0x62ba, 0x62be, 0x62bf, + 0x62c4, 0x62ce, 0x62d5, 0x62d6, 0x62da, 0x62ea, 0x62f2, 0x62f4, + 0x62fc, 0x62fd, 0x6303, 0x6304, 0x630a, 0x630b, 0x630d, 0x6310, + 0x6313, 0x6316, 0x6318, 0x6329, 0x632a, 0x632d, 0x6335, 0x6336, + 0x6339, 0x633c, 0x6341, 0x6342, 0x6343, 0x6344, 0x6346, 0x634a, + 0x634b, 0x634e, 0x6352, 0x6353, 0x6354, 0x6358, 0x635b, 0x6365, + 0x6366, 0x636c, 0x636d, 0x6371, 0x6374, 0x6375, + /* 0x40 */ + 0x6378, 0x637c, 0x637d, 0x637f, 0x6382, 0x6384, 0x6387, 0x638a, + 0x6390, 0x6394, 0x6395, 0x6399, 0x639a, 0x639e, 0x63a4, 0x63a6, + 0x63ad, 0x63ae, 0x63af, 0x63bd, 0x63c1, 0x63c5, 0x63c8, 0x63ce, + 0x63d1, 0x63d3, 0x63d4, 0x63d5, 0x63dc, 0x63e0, 0x63e5, 0x63ea, + 0x63ec, 0x63f2, 0x63f3, 0x63f5, 0x63f8, 0x63f9, 0x6409, 0x640a, + 0x6410, 0x6412, 0x6414, 0x6418, 0x641e, 0x6420, 0x6422, 0x6424, + 0x6425, 0x6429, 0x642a, 0x642f, 0x6430, 0x6435, 0x643d, 0x643f, + 0x644b, 0x644f, 0x6451, 0x6452, 0x6453, 0x6454, 0x645a, 0x645b, + 0x645c, 0x645d, 0x645f, 0x6460, 0x6461, 0x6463, 0x646d, 0x6473, + 0x6474, 0x647b, 0x647d, 0x6485, 0x6487, 0x648f, 0x6490, 0x6491, + 0x6498, 0x6499, 0x649b, 0x649d, 0x649f, 0x64a1, 0x64a3, 0x64a6, + 0x64a8, 0x64ac, 0x64b3, 0x64bd, 0x64be, 0x64bf, + /* 0x41 */ + 0x64c4, 0x64c9, 0x64ca, 0x64cb, 0x64cc, 0x64ce, 0x64d0, 0x64d1, + 0x64d5, 0x64d7, 0x64e4, 0x64e5, 0x64e9, 0x64ea, 0x64ed, 0x64f0, + 0x64f5, 0x64f7, 0x64fb, 0x64ff, 0x6501, 0x6504, 0x6508, 0x6509, + 0x650a, 0x650f, 0x6513, 0x6514, 0x6516, 0x6519, 0x651b, 0x651e, + 0x651f, 0x6522, 0x6526, 0x6529, 0x652e, 0x6531, 0x653a, 0x653c, + 0x653d, 0x6543, 0x6547, 0x6549, 0x6550, 0x6552, 0x6554, 0x655f, + 0x6560, 0x6567, 0x656b, 0x657a, 0x657d, 0x6581, 0x6585, 0x658a, + 0x6592, 0x6595, 0x6598, 0x659d, 0x65a0, 0x65a3, 0x65a6, 0x65ae, + 0x65b2, 0x65b3, 0x65b4, 0x65bf, 0x65c2, 0x65c8, 0x65c9, 0x65ce, + 0x65d0, 0x65d4, 0x65d6, 0x65d8, 0x65df, 0x65f0, 0x65f2, 0x65f4, + 0x65f5, 0x65f9, 0x65fe, 0x65ff, 0x6600, 0x6604, 0x6608, 0x6609, + 0x660d, 0x6611, 0x6612, 0x6615, 0x6616, 0x661d, + /* 0x42 */ + 0x661e, 0x6621, 0x6622, 0x6623, 0x6624, 0x6626, 0x6629, 0x662a, + 0x662b, 0x662c, 0x662e, 0x6630, 0x6631, 0x6633, 0x6639, 0x6637, + 0x6640, 0x6645, 0x6646, 0x664a, 0x664c, 0x6651, 0x664e, 0x6657, + 0x6658, 0x6659, 0x665b, 0x665c, 0x6660, 0x6661, 0x66fb, 0x666a, + 0x666b, 0x666c, 0x667e, 0x6673, 0x6675, 0x667f, 0x6677, 0x6678, + 0x6679, 0x667b, 0x6680, 0x667c, 0x668b, 0x668c, 0x668d, 0x6690, + 0x6692, 0x6699, 0x669a, 0x669b, 0x669c, 0x669f, 0x66a0, 0x66a4, + 0x66ad, 0x66b1, 0x66b2, 0x66b5, 0x66bb, 0x66bf, 0x66c0, 0x66c2, + 0x66c3, 0x66c8, 0x66cc, 0x66ce, 0x66cf, 0x66d4, 0x66db, 0x66df, + 0x66e8, 0x66eb, 0x66ec, 0x66ee, 0x66fa, 0x6705, 0x6707, 0x670e, + 0x6713, 0x6719, 0x671c, 0x6720, 0x6722, 0x6733, 0x673e, 0x6745, + 0x6747, 0x6748, 0x674c, 0x6754, 0x6755, 0x675d, + /* 0x43 */ + 0x6766, 0x676c, 0x676e, 0x6774, 0x6776, 0x677b, 0x6781, 0x6784, + 0x678e, 0x678f, 0x6791, 0x6793, 0x6796, 0x6798, 0x6799, 0x679b, + 0x67b0, 0x67b1, 0x67b2, 0x67b5, 0x67bb, 0x67bc, 0x67bd, 0x67f9, + 0x67c0, 0x67c2, 0x67c3, 0x67c5, 0x67c8, 0x67c9, 0x67d2, 0x67d7, + 0x67d9, 0x67dc, 0x67e1, 0x67e6, 0x67f0, 0x67f2, 0x67f6, 0x67f7, + 0x6852, 0x6814, 0x6819, 0x681d, 0x681f, 0x6828, 0x6827, 0x682c, + 0x682d, 0x682f, 0x6830, 0x6831, 0x6833, 0x683b, 0x683f, 0x6844, + 0x6845, 0x684a, 0x684c, 0x6855, 0x6857, 0x6858, 0x685b, 0x686b, + 0x686e, 0x686f, 0x6870, 0x6871, 0x6872, 0x6875, 0x6879, 0x687a, + 0x687b, 0x687c, 0x6882, 0x6884, 0x6886, 0x6888, 0x6896, 0x6898, + 0x689a, 0x689c, 0x68a1, 0x68a3, 0x68a5, 0x68a9, 0x68aa, 0x68ae, + 0x68b2, 0x68bb, 0x68c5, 0x68c8, 0x68cc, 0x68cf, + /* 0x44 */ + 0x68d0, 0x68d1, 0x68d3, 0x68d6, 0x68d9, 0x68dc, 0x68dd, 0x68e5, + 0x68e8, 0x68ea, 0x68eb, 0x68ec, 0x68ed, 0x68f0, 0x68f1, 0x68f5, + 0x68f6, 0x68fb, 0x68fc, 0x68fd, 0x6906, 0x6909, 0x690a, 0x6910, + 0x6911, 0x6913, 0x6916, 0x6917, 0x6931, 0x6933, 0x6935, 0x6938, + 0x693b, 0x6942, 0x6945, 0x6949, 0x694e, 0x6957, 0x695b, 0x6963, + 0x6964, 0x6965, 0x6966, 0x6968, 0x6969, 0x696c, 0x6970, 0x6971, + 0x6972, 0x697a, 0x697b, 0x697f, 0x6980, 0x698d, 0x6992, 0x6996, + 0x6998, 0x69a1, 0x69a5, 0x69a6, 0x69a8, 0x69ab, 0x69ad, 0x69af, + 0x69b7, 0x69b8, 0x69ba, 0x69bc, 0x69c5, 0x69c8, 0x69d1, 0x69d6, + 0x69d7, 0x69e2, 0x69e5, 0x69ee, 0x69ef, 0x69f1, 0x69f3, 0x69f5, + 0x69fe, 0x6a00, 0x6a01, 0x6a03, 0x6a0f, 0x6a11, 0x6a15, 0x6a1a, + 0x6a1d, 0x6a20, 0x6a24, 0x6a28, 0x6a30, 0x6a32, + /* 0x45 */ + 0x6a34, 0x6a37, 0x6a3b, 0x6a3e, 0x6a3f, 0x6a45, 0x6a46, 0x6a49, + 0x6a4a, 0x6a4e, 0x6a50, 0x6a51, 0x6a52, 0x6a55, 0x6a56, 0x6a5b, + 0x6a64, 0x6a67, 0x6a6a, 0x6a71, 0x6a73, 0x6a7e, 0x6a81, 0x6a83, + 0x6a86, 0x6a87, 0x6a89, 0x6a8b, 0x6a91, 0x6a9b, 0x6a9d, 0x6a9e, + 0x6a9f, 0x6aa5, 0x6aab, 0x6aaf, 0x6ab0, 0x6ab1, 0x6ab4, 0x6abd, + 0x6abe, 0x6abf, 0x6ac6, 0x6ac9, 0x6ac8, 0x6acc, 0x6ad0, 0x6ad4, + 0x6ad5, 0x6ad6, 0x6adc, 0x6add, 0x6ae4, 0x6ae7, 0x6aec, 0x6af0, + 0x6af1, 0x6af2, 0x6afc, 0x6afd, 0x6b02, 0x6b03, 0x6b06, 0x6b07, + 0x6b09, 0x6b0f, 0x6b10, 0x6b11, 0x6b17, 0x6b1b, 0x6b1e, 0x6b24, + 0x6b28, 0x6b2b, 0x6b2c, 0x6b2f, 0x6b35, 0x6b36, 0x6b3b, 0x6b3f, + 0x6b46, 0x6b4a, 0x6b4d, 0x6b52, 0x6b56, 0x6b58, 0x6b5d, 0x6b60, + 0x6b67, 0x6b6b, 0x6b6e, 0x6b70, 0x6b75, 0x6b7d, + /* 0x46 */ + 0x6b7e, 0x6b82, 0x6b85, 0x6b97, 0x6b9b, 0x6b9f, 0x6ba0, 0x6ba2, + 0x6ba3, 0x6ba8, 0x6ba9, 0x6bac, 0x6bad, 0x6bae, 0x6bb0, 0x6bb8, + 0x6bb9, 0x6bbd, 0x6bbe, 0x6bc3, 0x6bc4, 0x6bc9, 0x6bcc, 0x6bd6, + 0x6bda, 0x6be1, 0x6be3, 0x6be6, 0x6be7, 0x6bee, 0x6bf1, 0x6bf7, + 0x6bf9, 0x6bff, 0x6c02, 0x6c04, 0x6c05, 0x6c09, 0x6c0d, 0x6c0e, + 0x6c10, 0x6c12, 0x6c19, 0x6c1f, 0x6c26, 0x6c27, 0x6c28, 0x6c2c, + 0x6c2e, 0x6c33, 0x6c35, 0x6c36, 0x6c3a, 0x6c3b, 0x6c3f, 0x6c4a, + 0x6c4b, 0x6c4d, 0x6c4f, 0x6c52, 0x6c54, 0x6c59, 0x6c5b, 0x6c5c, + 0x6c6b, 0x6c6d, 0x6c6f, 0x6c74, 0x6c76, 0x6c78, 0x6c79, 0x6c7b, + 0x6c85, 0x6c86, 0x6c87, 0x6c89, 0x6c94, 0x6c95, 0x6c97, 0x6c98, + 0x6c9c, 0x6c9f, 0x6cb0, 0x6cb2, 0x6cb4, 0x6cc2, 0x6cc6, 0x6ccd, + 0x6ccf, 0x6cd0, 0x6cd1, 0x6cd2, 0x6cd4, 0x6cd6, + /* 0x47 */ + 0x6cda, 0x6cdc, 0x6ce0, 0x6ce7, 0x6ce9, 0x6ceb, 0x6cec, 0x6cee, + 0x6cf2, 0x6cf4, 0x6d04, 0x6d07, 0x6d0a, 0x6d0e, 0x6d0f, 0x6d11, + 0x6d13, 0x6d1a, 0x6d26, 0x6d27, 0x6d28, 0x6c67, 0x6d2e, 0x6d2f, + 0x6d31, 0x6d39, 0x6d3c, 0x6d3f, 0x6d57, 0x6d5e, 0x6d5f, 0x6d61, + 0x6d65, 0x6d67, 0x6d6f, 0x6d70, 0x6d7c, 0x6d82, 0x6d87, 0x6d91, + 0x6d92, 0x6d94, 0x6d96, 0x6d97, 0x6d98, 0x6daa, 0x6dac, 0x6db4, + 0x6db7, 0x6db9, 0x6dbd, 0x6dbf, 0x6dc4, 0x6dc8, 0x6dca, 0x6dce, + 0x6dcf, 0x6dd6, 0x6ddb, 0x6ddd, 0x6ddf, 0x6de0, 0x6de2, 0x6de5, + 0x6de9, 0x6def, 0x6df0, 0x6df4, 0x6df6, 0x6dfc, 0x6e00, 0x6e04, + 0x6e1e, 0x6e22, 0x6e27, 0x6e32, 0x6e36, 0x6e39, 0x6e3b, 0x6e3c, + 0x6e44, 0x6e45, 0x6e48, 0x6e49, 0x6e4b, 0x6e4f, 0x6e51, 0x6e52, + 0x6e53, 0x6e54, 0x6e57, 0x6e5c, 0x6e5d, 0x6e5e, + /* 0x48 */ + 0x6e62, 0x6e63, 0x6e68, 0x6e73, 0x6e7b, 0x6e7d, 0x6e8d, 0x6e93, + 0x6e99, 0x6ea0, 0x6ea7, 0x6ead, 0x6eae, 0x6eb1, 0x6eb3, 0x6ebb, + 0x6ebf, 0x6ec0, 0x6ec1, 0x6ec3, 0x6ec7, 0x6ec8, 0x6eca, 0x6ecd, + 0x6ece, 0x6ecf, 0x6eeb, 0x6eed, 0x6eee, 0x6ef9, 0x6efb, 0x6efd, + 0x6f04, 0x6f08, 0x6f0a, 0x6f0c, 0x6f0d, 0x6f16, 0x6f18, 0x6f1a, + 0x6f1b, 0x6f26, 0x6f29, 0x6f2a, 0x6f2f, 0x6f30, 0x6f33, 0x6f36, + 0x6f3b, 0x6f3c, 0x6f2d, 0x6f4f, 0x6f51, 0x6f52, 0x6f53, 0x6f57, + 0x6f59, 0x6f5a, 0x6f5d, 0x6f5e, 0x6f61, 0x6f62, 0x6f68, 0x6f6c, + 0x6f7d, 0x6f7e, 0x6f83, 0x6f87, 0x6f88, 0x6f8b, 0x6f8c, 0x6f8d, + 0x6f90, 0x6f92, 0x6f93, 0x6f94, 0x6f96, 0x6f9a, 0x6f9f, 0x6fa0, + 0x6fa5, 0x6fa6, 0x6fa7, 0x6fa8, 0x6fae, 0x6faf, 0x6fb0, 0x6fb5, + 0x6fb6, 0x6fbc, 0x6fc5, 0x6fc7, 0x6fc8, 0x6fca, + /* 0x49 */ + 0x6fda, 0x6fde, 0x6fe8, 0x6fe9, 0x6ff0, 0x6ff5, 0x6ff9, 0x6ffc, + 0x6ffd, 0x7000, 0x7005, 0x7006, 0x7007, 0x700d, 0x7017, 0x7020, + 0x7023, 0x702f, 0x7034, 0x7037, 0x7039, 0x703c, 0x7043, 0x7044, + 0x7048, 0x7049, 0x704a, 0x704b, 0x7054, 0x7055, 0x705d, 0x705e, + 0x704e, 0x7064, 0x7065, 0x706c, 0x706e, 0x7075, 0x7076, 0x707e, + 0x7081, 0x7085, 0x7086, 0x7094, 0x7095, 0x7096, 0x7097, 0x7098, + 0x709b, 0x70a4, 0x70ab, 0x70b0, 0x70b1, 0x70b4, 0x70b7, 0x70ca, + 0x70d1, 0x70d3, 0x70d4, 0x70d5, 0x70d6, 0x70d8, 0x70dc, 0x70e4, + 0x70fa, 0x7103, 0x7104, 0x7105, 0x7106, 0x7107, 0x710b, 0x710c, + 0x710f, 0x711e, 0x7120, 0x712b, 0x712d, 0x712f, 0x7130, 0x7131, + 0x7138, 0x7141, 0x7145, 0x7146, 0x7147, 0x714a, 0x714b, 0x7150, + 0x7152, 0x7157, 0x715a, 0x715c, 0x715e, 0x7160, + /* 0x4a */ + 0x7168, 0x7179, 0x7180, 0x7185, 0x7187, 0x718c, 0x7192, 0x719a, + 0x719b, 0x71a0, 0x71a2, 0x71af, 0x71b0, 0x71b2, 0x71b3, 0x71ba, + 0x71bf, 0x71c0, 0x71c1, 0x71c4, 0x71cb, 0x71cc, 0x71d3, 0x71d6, + 0x71d9, 0x71da, 0x71dc, 0x71f8, 0x71fe, 0x7200, 0x7207, 0x7208, + 0x7209, 0x7213, 0x7217, 0x721a, 0x721d, 0x721f, 0x7224, 0x722b, + 0x722f, 0x7234, 0x7238, 0x7239, 0x7241, 0x7242, 0x7243, 0x7245, + 0x724e, 0x724f, 0x7250, 0x7253, 0x7255, 0x7256, 0x725a, 0x725c, + 0x725e, 0x7260, 0x7263, 0x7268, 0x726b, 0x726e, 0x726f, 0x7271, + 0x7277, 0x7278, 0x727b, 0x727c, 0x727f, 0x7284, 0x7289, 0x728d, + 0x728e, 0x7293, 0x729b, 0x72a8, 0x72ad, 0x72ae, 0x72b1, 0x72b4, + 0x72be, 0x72c1, 0x72c7, 0x72c9, 0x72cc, 0x72d5, 0x72d6, 0x72d8, + 0x72df, 0x72e5, 0x72f3, 0x72f4, 0x72fa, 0x72fb, + /* 0x4b */ + 0x72fe, 0x7302, 0x7304, 0x7305, 0x7307, 0x730b, 0x730d, 0x7312, + 0x7313, 0x7318, 0x7319, 0x731e, 0x7322, 0x7324, 0x7327, 0x7328, + 0x732c, 0x7331, 0x7332, 0x7335, 0x733a, 0x733b, 0x733d, 0x7343, + 0x734d, 0x7350, 0x7352, 0x7356, 0x7358, 0x735d, 0x735e, 0x735f, + 0x7360, 0x7366, 0x7367, 0x7369, 0x736b, 0x736c, 0x736e, 0x736f, + 0x7371, 0x7377, 0x7379, 0x737c, 0x7380, 0x7381, 0x7383, 0x7385, + 0x7386, 0x738e, 0x7390, 0x7393, 0x7395, 0x7397, 0x7398, 0x739c, + 0x739e, 0x739f, 0x73a0, 0x73a2, 0x73a5, 0x73a6, 0x73aa, 0x73ab, + 0x73ad, 0x73b5, 0x73b7, 0x73b9, 0x73bc, 0x73bd, 0x73bf, 0x73c5, + 0x73c6, 0x73c9, 0x73cb, 0x73cc, 0x73cf, 0x73d2, 0x73d3, 0x73d6, + 0x73d9, 0x73dd, 0x73e1, 0x73e3, 0x73e6, 0x73e7, 0x73e9, 0x73f4, + 0x73f5, 0x73f7, 0x73f9, 0x73fa, 0x73fb, 0x73fd, + /* 0x4c */ + 0x73ff, 0x7400, 0x7401, 0x7404, 0x7407, 0x740a, 0x7411, 0x741a, + 0x741b, 0x7424, 0x7426, 0x7428, 0x7429, 0x742a, 0x742b, 0x742c, + 0x742d, 0x742e, 0x742f, 0x7430, 0x7431, 0x7439, 0x7440, 0x7443, + 0x7444, 0x7446, 0x7447, 0x744b, 0x744d, 0x7451, 0x7452, 0x7457, + 0x745d, 0x7462, 0x7466, 0x7467, 0x7468, 0x746b, 0x746d, 0x746e, + 0x7471, 0x7472, 0x7480, 0x7481, 0x7485, 0x7486, 0x7487, 0x7489, + 0x748f, 0x7490, 0x7491, 0x7492, 0x7498, 0x7499, 0x749a, 0x749c, + 0x749f, 0x74a0, 0x74a1, 0x74a3, 0x74a6, 0x74a8, 0x74a9, 0x74aa, + 0x74ab, 0x74ae, 0x74af, 0x74b1, 0x74b2, 0x74b5, 0x74b9, 0x74bb, + 0x74bf, 0x74c8, 0x74c9, 0x74cc, 0x74d0, 0x74d3, 0x74d8, 0x74da, + 0x74db, 0x74de, 0x74df, 0x74e4, 0x74e8, 0x74ea, 0x74eb, 0x74ef, + 0x74f4, 0x74fa, 0x74fb, 0x74fc, 0x74ff, 0x7506, + /* 0x4d */ + 0x7512, 0x7516, 0x7517, 0x7520, 0x7521, 0x7524, 0x7527, 0x7529, + 0x752a, 0x752f, 0x7536, 0x7539, 0x753d, 0x753e, 0x753f, 0x7540, + 0x7543, 0x7547, 0x7548, 0x754e, 0x7550, 0x7552, 0x7557, 0x755e, + 0x755f, 0x7561, 0x756f, 0x7571, 0x7579, 0x757a, 0x757b, 0x757c, + 0x757d, 0x757e, 0x7581, 0x7585, 0x7590, 0x7592, 0x7593, 0x7595, + 0x7599, 0x759c, 0x75a2, 0x75a4, 0x75b4, 0x75ba, 0x75bf, 0x75c0, + 0x75c1, 0x75c4, 0x75c6, 0x75cc, 0x75ce, 0x75cf, 0x75d7, 0x75dc, + 0x75df, 0x75e0, 0x75e1, 0x75e4, 0x75e7, 0x75ec, 0x75ee, 0x75ef, + 0x75f1, 0x75f9, 0x7600, 0x7602, 0x7603, 0x7604, 0x7607, 0x7608, + 0x760a, 0x760c, 0x760f, 0x7612, 0x7613, 0x7615, 0x7616, 0x7619, + 0x761b, 0x761c, 0x761d, 0x761e, 0x7623, 0x7625, 0x7626, 0x7629, + 0x762d, 0x7632, 0x7633, 0x7635, 0x7638, 0x7639, + /* 0x4e */ + 0x763a, 0x763c, 0x764a, 0x7640, 0x7641, 0x7643, 0x7644, 0x7645, + 0x7649, 0x764b, 0x7655, 0x7659, 0x765f, 0x7664, 0x7665, 0x766d, + 0x766e, 0x766f, 0x7671, 0x7674, 0x7681, 0x7685, 0x768c, 0x768d, + 0x7695, 0x769b, 0x769c, 0x769d, 0x769f, 0x76a0, 0x76a2, 0x76a3, + 0x76a4, 0x76a5, 0x76a6, 0x76a7, 0x76a8, 0x76aa, 0x76ad, 0x76bd, + 0x76c1, 0x76c5, 0x76c9, 0x76cb, 0x76cc, 0x76ce, 0x76d4, 0x76d9, + 0x76e0, 0x76e6, 0x76e8, 0x76ec, 0x76f0, 0x76f1, 0x76f6, 0x76f9, + 0x76fc, 0x7700, 0x7706, 0x770a, 0x770e, 0x7712, 0x7714, 0x7715, + 0x7717, 0x7719, 0x771a, 0x771c, 0x7722, 0x7728, 0x772d, 0x772e, + 0x772f, 0x7734, 0x7735, 0x7736, 0x7739, 0x773d, 0x773e, 0x7742, + 0x7745, 0x7746, 0x774a, 0x774d, 0x774e, 0x774f, 0x7752, 0x7756, + 0x7757, 0x775c, 0x775e, 0x775f, 0x7760, 0x7762, + /* 0x4f */ + 0x7764, 0x7767, 0x776a, 0x776c, 0x7770, 0x7772, 0x7773, 0x7774, + 0x777a, 0x777d, 0x7780, 0x7784, 0x778c, 0x778d, 0x7794, 0x7795, + 0x7796, 0x779a, 0x779f, 0x77a2, 0x77a7, 0x77aa, 0x77ae, 0x77af, + 0x77b1, 0x77b5, 0x77be, 0x77c3, 0x77c9, 0x77d1, 0x77d2, 0x77d5, + 0x77d9, 0x77de, 0x77df, 0x77e0, 0x77e4, 0x77e6, 0x77ea, 0x77ec, + 0x77f0, 0x77f1, 0x77f4, 0x77f8, 0x77fb, 0x7805, 0x7806, 0x7809, + 0x780d, 0x780e, 0x7811, 0x781d, 0x7821, 0x7822, 0x7823, 0x782d, + 0x782e, 0x7830, 0x7835, 0x7837, 0x7843, 0x7844, 0x7847, 0x7848, + 0x784c, 0x784e, 0x7852, 0x785c, 0x785e, 0x7860, 0x7861, 0x7863, + 0x7864, 0x7868, 0x786a, 0x786e, 0x787a, 0x787e, 0x788a, 0x788f, + 0x7894, 0x7898, 0x78a1, 0x789d, 0x789e, 0x789f, 0x78a4, 0x78a8, + 0x78ac, 0x78ad, 0x78b0, 0x78b1, 0x78b2, 0x78b3, + /* 0x50 */ + 0x78bb, 0x78bd, 0x78bf, 0x78c7, 0x78c8, 0x78c9, 0x78cc, 0x78ce, + 0x78d2, 0x78d3, 0x78d5, 0x78d6, 0x78e4, 0x78db, 0x78df, 0x78e0, + 0x78e1, 0x78e6, 0x78ea, 0x78f2, 0x78f3, 0x7900, 0x78f6, 0x78f7, + 0x78fa, 0x78fb, 0x78ff, 0x7906, 0x790c, 0x7910, 0x791a, 0x791c, + 0x791e, 0x791f, 0x7920, 0x7925, 0x7927, 0x7929, 0x792d, 0x7931, + 0x7934, 0x7935, 0x793b, 0x793d, 0x793f, 0x7944, 0x7945, 0x7946, + 0x794a, 0x794b, 0x794f, 0x7951, 0x7954, 0x7958, 0x795b, 0x795c, + 0x7967, 0x7969, 0x796b, 0x7972, 0x7979, 0x797b, 0x797c, 0x797e, + 0x798b, 0x798c, 0x7991, 0x7993, 0x7994, 0x7995, 0x7996, 0x7998, + 0x799b, 0x799c, 0x79a1, 0x79a8, 0x79a9, 0x79ab, 0x79af, 0x79b1, + 0x79b4, 0x79b8, 0x79bb, 0x79c2, 0x79c4, 0x79c7, 0x79c8, 0x79ca, + 0x79cf, 0x79d4, 0x79d6, 0x79da, 0x79dd, 0x79de, + /* 0x51 */ + 0x79e0, 0x79e2, 0x79e5, 0x79ea, 0x79eb, 0x79ed, 0x79f1, 0x79f8, + 0x79fc, 0x7a02, 0x7a03, 0x7a07, 0x7a09, 0x7a0a, 0x7a0c, 0x7a11, + 0x7a15, 0x7a1b, 0x7a1e, 0x7a21, 0x7a27, 0x7a2b, 0x7a2d, 0x7a2f, + 0x7a30, 0x7a34, 0x7a35, 0x7a38, 0x7a39, 0x7a3a, 0x7a44, 0x7a45, + 0x7a47, 0x7a48, 0x7a4c, 0x7a55, 0x7a56, 0x7a59, 0x7a5c, 0x7a5d, + 0x7a5f, 0x7a60, 0x7a65, 0x7a67, 0x7a6a, 0x7a6d, 0x7a75, 0x7a78, + 0x7a7e, 0x7a80, 0x7a82, 0x7a85, 0x7a86, 0x7a8a, 0x7a8b, 0x7a90, + 0x7a91, 0x7a94, 0x7a9e, 0x7aa0, 0x7aa3, 0x7aac, 0x7ab3, 0x7ab5, + 0x7ab9, 0x7abb, 0x7abc, 0x7ac6, 0x7ac9, 0x7acc, 0x7ace, 0x7ad1, + 0x7adb, 0x7ae8, 0x7ae9, 0x7aeb, 0x7aec, 0x7af1, 0x7af4, 0x7afb, + 0x7afd, 0x7afe, 0x7b07, 0x7b14, 0x7b1f, 0x7b23, 0x7b27, 0x7b29, + 0x7b2a, 0x7b2b, 0x7b2d, 0x7b2e, 0x7b2f, 0x7b30, + /* 0x52 */ + 0x7b31, 0x7b34, 0x7b3d, 0x7b3f, 0x7b40, 0x7b41, 0x7b47, 0x7b4e, + 0x7b55, 0x7b60, 0x7b64, 0x7b66, 0x7b69, 0x7b6a, 0x7b6d, 0x7b6f, + 0x7b72, 0x7b73, 0x7b77, 0x7b84, 0x7b89, 0x7b8e, 0x7b90, 0x7b91, + 0x7b96, 0x7b9b, 0x7b9e, 0x7ba0, 0x7ba5, 0x7bac, 0x7baf, 0x7bb0, + 0x7bb2, 0x7bb5, 0x7bb6, 0x7bba, 0x7bbb, 0x7bbc, 0x7bbd, 0x7bc2, + 0x7bc5, 0x7bc8, 0x7bca, 0x7bd4, 0x7bd6, 0x7bd7, 0x7bd9, 0x7bda, + 0x7bdb, 0x7be8, 0x7bea, 0x7bf2, 0x7bf4, 0x7bf5, 0x7bf8, 0x7bf9, + 0x7bfa, 0x7bfc, 0x7bfe, 0x7c01, 0x7c02, 0x7c03, 0x7c04, 0x7c06, + 0x7c09, 0x7c0b, 0x7c0c, 0x7c0e, 0x7c0f, 0x7c19, 0x7c1b, 0x7c20, + 0x7c25, 0x7c26, 0x7c28, 0x7c2c, 0x7c31, 0x7c33, 0x7c34, 0x7c36, + 0x7c39, 0x7c3a, 0x7c46, 0x7c4a, 0x7c55, 0x7c51, 0x7c52, 0x7c53, + 0x7c59, 0x7c5a, 0x7c5b, 0x7c5c, 0x7c5d, 0x7c5e, + /* 0x53 */ + 0x7c61, 0x7c63, 0x7c67, 0x7c69, 0x7c6d, 0x7c6e, 0x7c70, 0x7c72, + 0x7c79, 0x7c7c, 0x7c7d, 0x7c86, 0x7c87, 0x7c8f, 0x7c94, 0x7c9e, + 0x7ca0, 0x7ca6, 0x7cb0, 0x7cb6, 0x7cb7, 0x7cba, 0x7cbb, 0x7cbc, + 0x7cbf, 0x7cc4, 0x7cc7, 0x7cc8, 0x7cc9, 0x7ccd, 0x7ccf, 0x7cd3, + 0x7cd4, 0x7cd5, 0x7cd7, 0x7cd9, 0x7cda, 0x7cdd, 0x7ce6, 0x7ce9, + 0x7ceb, 0x7cf5, 0x7d03, 0x7d07, 0x7d08, 0x7d09, 0x7d0f, 0x7d11, + 0x7d12, 0x7d13, 0x7d16, 0x7d1d, 0x7d1e, 0x7d23, 0x7d26, 0x7d2a, + 0x7d2d, 0x7d31, 0x7d3c, 0x7d3d, 0x7d3e, 0x7d40, 0x7d41, 0x7d47, + 0x7d48, 0x7d4d, 0x7d51, 0x7d53, 0x7d57, 0x7d59, 0x7d5a, 0x7d5c, + 0x7d5d, 0x7d65, 0x7d67, 0x7d6a, 0x7d70, 0x7d78, 0x7d7a, 0x7d7b, + 0x7d7f, 0x7d81, 0x7d82, 0x7d83, 0x7d85, 0x7d86, 0x7d88, 0x7d8b, + 0x7d8c, 0x7d8d, 0x7d91, 0x7d96, 0x7d97, 0x7d9d, + /* 0x54 */ + 0x7d9e, 0x7da6, 0x7da7, 0x7daa, 0x7db3, 0x7db6, 0x7db7, 0x7db9, + 0x7dc2, 0x7dc3, 0x7dc4, 0x7dc5, 0x7dc6, 0x7dcc, 0x7dcd, 0x7dce, + 0x7dd7, 0x7dd9, 0x7e00, 0x7de2, 0x7de5, 0x7de6, 0x7dea, 0x7deb, + 0x7ded, 0x7df1, 0x7df5, 0x7df6, 0x7df9, 0x7dfa, 0x7e08, 0x7e10, + 0x7e11, 0x7e15, 0x7e17, 0x7e1c, 0x7e1d, 0x7e20, 0x7e27, 0x7e28, + 0x7e2c, 0x7e2d, 0x7e2f, 0x7e33, 0x7e36, 0x7e3f, 0x7e44, 0x7e45, + 0x7e47, 0x7e4e, 0x7e50, 0x7e52, 0x7e58, 0x7e5f, 0x7e61, 0x7e62, + 0x7e65, 0x7e6b, 0x7e6e, 0x7e6f, 0x7e73, 0x7e78, 0x7e7e, 0x7e81, + 0x7e86, 0x7e87, 0x7e8a, 0x7e8d, 0x7e91, 0x7e95, 0x7e98, 0x7e9a, + 0x7e9d, 0x7e9e, 0x7f3c, 0x7f3b, 0x7f3d, 0x7f3e, 0x7f3f, 0x7f43, + 0x7f44, 0x7f47, 0x7f4f, 0x7f52, 0x7f53, 0x7f5b, 0x7f5c, 0x7f5d, + 0x7f61, 0x7f63, 0x7f64, 0x7f65, 0x7f66, 0x7f6d, + /* 0x55 */ + 0x7f71, 0x7f7d, 0x7f7e, 0x7f7f, 0x7f80, 0x7f8b, 0x7f8d, 0x7f8f, + 0x7f90, 0x7f91, 0x7f96, 0x7f97, 0x7f9c, 0x7fa1, 0x7fa2, 0x7fa6, + 0x7faa, 0x7fad, 0x7fb4, 0x7fbc, 0x7fbf, 0x7fc0, 0x7fc3, 0x7fc8, + 0x7fce, 0x7fcf, 0x7fdb, 0x7fdf, 0x7fe3, 0x7fe5, 0x7fe8, 0x7fec, + 0x7fee, 0x7fef, 0x7ff2, 0x7ffa, 0x7ffd, 0x7ffe, 0x7fff, 0x8007, + 0x8008, 0x800a, 0x800d, 0x800e, 0x800f, 0x8011, 0x8013, 0x8014, + 0x8016, 0x801d, 0x801e, 0x801f, 0x8020, 0x8024, 0x8026, 0x802c, + 0x802e, 0x8030, 0x8034, 0x8035, 0x8037, 0x8039, 0x803a, 0x803c, + 0x803e, 0x8040, 0x8044, 0x8060, 0x8064, 0x8066, 0x806d, 0x8071, + 0x8075, 0x8081, 0x8088, 0x808e, 0x809c, 0x809e, 0x80a6, 0x80a7, + 0x80ab, 0x80b8, 0x80b9, 0x80c8, 0x80cd, 0x80cf, 0x80d2, 0x80d4, + 0x80d5, 0x80d7, 0x80d8, 0x80e0, 0x80ed, 0x80ee, + /* 0x56 */ + 0x80f0, 0x80f2, 0x80f3, 0x80f6, 0x80f9, 0x80fa, 0x80fe, 0x8103, + 0x810b, 0x8116, 0x8117, 0x8118, 0x811c, 0x811e, 0x8120, 0x8124, + 0x8127, 0x812c, 0x8130, 0x8135, 0x813a, 0x813c, 0x8145, 0x8147, + 0x814a, 0x814c, 0x8152, 0x8157, 0x8160, 0x8161, 0x8167, 0x8168, + 0x8169, 0x816d, 0x816f, 0x8177, 0x8181, 0x8190, 0x8184, 0x8185, + 0x8186, 0x818b, 0x818e, 0x8196, 0x8198, 0x819b, 0x819e, 0x81a2, + 0x81ae, 0x81b2, 0x81b4, 0x81bb, 0x81cb, 0x81c3, 0x81c5, 0x81ca, + 0x81ce, 0x81cf, 0x81d5, 0x81d7, 0x81db, 0x81dd, 0x81de, 0x81e1, + 0x81e4, 0x81eb, 0x81ec, 0x81f0, 0x81f1, 0x81f2, 0x81f5, 0x81f6, + 0x81f8, 0x81f9, 0x81fd, 0x81ff, 0x8200, 0x8203, 0x820f, 0x8213, + 0x8214, 0x8219, 0x821a, 0x821d, 0x8221, 0x8222, 0x8228, 0x8232, + 0x8234, 0x823a, 0x8243, 0x8244, 0x8245, 0x8246, + /* 0x57 */ + 0x824b, 0x824e, 0x824f, 0x8251, 0x8256, 0x825c, 0x8260, 0x8263, + 0x8267, 0x826d, 0x8274, 0x827b, 0x827d, 0x827f, 0x8280, 0x8281, + 0x8283, 0x8284, 0x8287, 0x8289, 0x828a, 0x828e, 0x8291, 0x8294, + 0x8296, 0x8298, 0x829a, 0x829b, 0x82a0, 0x82a1, 0x82a3, 0x82a4, + 0x82a7, 0x82a8, 0x82a9, 0x82aa, 0x82ae, 0x82b0, 0x82b2, 0x82b4, + 0x82b7, 0x82ba, 0x82bc, 0x82be, 0x82bf, 0x82c6, 0x82d0, 0x82d5, + 0x82da, 0x82e0, 0x82e2, 0x82e4, 0x82e8, 0x82ea, 0x82ed, 0x82ef, + 0x82f6, 0x82f7, 0x82fd, 0x82fe, 0x8300, 0x8301, 0x8307, 0x8308, + 0x830a, 0x830b, 0x8354, 0x831b, 0x831d, 0x831e, 0x831f, 0x8321, + 0x8322, 0x832c, 0x832d, 0x832e, 0x8330, 0x8333, 0x8337, 0x833a, + 0x833c, 0x833d, 0x8342, 0x8343, 0x8344, 0x8347, 0x834d, 0x834e, + 0x8351, 0x8355, 0x8356, 0x8357, 0x8370, 0x8378, + /* 0x58 */ + 0x837d, 0x837f, 0x8380, 0x8382, 0x8384, 0x8386, 0x838d, 0x8392, + 0x8394, 0x8395, 0x8398, 0x8399, 0x839b, 0x839c, 0x839d, 0x83a6, + 0x83a7, 0x83a9, 0x83ac, 0x83be, 0x83bf, 0x83c0, 0x83c7, 0x83c9, + 0x83cf, 0x83d0, 0x83d1, 0x83d4, 0x83dd, 0x8353, 0x83e8, 0x83ea, + 0x83f6, 0x83f8, 0x83f9, 0x83fc, 0x8401, 0x8406, 0x840a, 0x840f, + 0x8411, 0x8415, 0x8419, 0x83ad, 0x842f, 0x8439, 0x8445, 0x8447, + 0x8448, 0x844a, 0x844d, 0x844f, 0x8451, 0x8452, 0x8456, 0x8458, + 0x8459, 0x845a, 0x845c, 0x8460, 0x8464, 0x8465, 0x8467, 0x846a, + 0x8470, 0x8473, 0x8474, 0x8476, 0x8478, 0x847c, 0x847d, 0x8481, + 0x8485, 0x8492, 0x8493, 0x8495, 0x849e, 0x84a6, 0x84a8, 0x84a9, + 0x84aa, 0x84af, 0x84b1, 0x84b4, 0x84ba, 0x84bd, 0x84be, 0x84c0, + 0x84c2, 0x84c7, 0x84c8, 0x84cc, 0x84cf, 0x84d3, + /* 0x59 */ + 0x84dc, 0x84e7, 0x84ea, 0x84ef, 0x84f0, 0x84f1, 0x84f2, 0x84f7, + 0x8532, 0x84fa, 0x84fb, 0x84fd, 0x8502, 0x8503, 0x8507, 0x850c, + 0x850e, 0x8510, 0x851c, 0x851e, 0x8522, 0x8523, 0x8524, 0x8525, + 0x8527, 0x852a, 0x852b, 0x852f, 0x8533, 0x8534, 0x8536, 0x853f, + 0x8546, 0x854f, 0x8550, 0x8551, 0x8552, 0x8553, 0x8556, 0x8559, + 0x855c, 0x855d, 0x855e, 0x855f, 0x8560, 0x8561, 0x8562, 0x8564, + 0x856b, 0x856f, 0x8579, 0x857a, 0x857b, 0x857d, 0x857f, 0x8581, + 0x8585, 0x8586, 0x8589, 0x858b, 0x858c, 0x858f, 0x8593, 0x8598, + 0x859d, 0x859f, 0x85a0, 0x85a2, 0x85a5, 0x85a7, 0x85b4, 0x85b6, + 0x85b7, 0x85b8, 0x85bc, 0x85bd, 0x85be, 0x85bf, 0x85c2, 0x85c7, + 0x85ca, 0x85cb, 0x85ce, 0x85ad, 0x85d8, 0x85da, 0x85df, 0x85e0, + 0x85e6, 0x85e8, 0x85ed, 0x85f3, 0x85f6, 0x85fc, + /* 0x5a */ + 0x85ff, 0x8600, 0x8604, 0x8605, 0x860d, 0x860e, 0x8610, 0x8611, + 0x8612, 0x8618, 0x8619, 0x861b, 0x861e, 0x8621, 0x8627, 0x8629, + 0x8636, 0x8638, 0x863a, 0x863c, 0x863d, 0x8640, 0x8642, 0x8646, + 0x8652, 0x8653, 0x8656, 0x8657, 0x8658, 0x8659, 0x865d, 0x8660, + 0x8661, 0x8662, 0x8663, 0x8664, 0x8669, 0x866c, 0x866f, 0x8675, + 0x8676, 0x8677, 0x867a, 0x868d, 0x8691, 0x8696, 0x8698, 0x869a, + 0x869c, 0x86a1, 0x86a6, 0x86a7, 0x86a8, 0x86ad, 0x86b1, 0x86b3, + 0x86b4, 0x86b5, 0x86b7, 0x86b8, 0x86b9, 0x86bf, 0x86c0, 0x86c1, + 0x86c3, 0x86c5, 0x86d1, 0x86d2, 0x86d5, 0x86d7, 0x86da, 0x86dc, + 0x86e0, 0x86e3, 0x86e5, 0x86e7, 0x8688, 0x86fa, 0x86fc, 0x86fd, + 0x8704, 0x8705, 0x8707, 0x870b, 0x870e, 0x870f, 0x8710, 0x8713, + 0x8714, 0x8719, 0x871e, 0x871f, 0x8721, 0x8723, + /* 0x5b */ + 0x8728, 0x872e, 0x872f, 0x8731, 0x8732, 0x8739, 0x873a, 0x873c, + 0x873d, 0x873e, 0x8740, 0x8743, 0x8745, 0x874d, 0x8758, 0x875d, + 0x8761, 0x8764, 0x8765, 0x876f, 0x8771, 0x8772, 0x877b, 0x8783, + 0x8784, 0x8785, 0x8786, 0x8787, 0x8788, 0x8789, 0x878b, 0x878c, + 0x8790, 0x8793, 0x8795, 0x8797, 0x8798, 0x8799, 0x879e, 0x87a0, + 0x87a3, 0x87a7, 0x87ac, 0x87ad, 0x87ae, 0x87b1, 0x87b5, 0x87be, + 0x87bf, 0x87c1, 0x87c8, 0x87c9, 0x87ca, 0x87ce, 0x87d5, 0x87d6, + 0x87d9, 0x87da, 0x87dc, 0x87df, 0x87e2, 0x87e3, 0x87e4, 0x87ea, + 0x87eb, 0x87ed, 0x87f1, 0x87f3, 0x87f8, 0x87fa, 0x87ff, 0x8801, + 0x8803, 0x8806, 0x8809, 0x880a, 0x880b, 0x8810, 0x8819, 0x8812, + 0x8813, 0x8814, 0x8818, 0x881a, 0x881b, 0x881c, 0x881e, 0x881f, + 0x8828, 0x882d, 0x882e, 0x8830, 0x8832, 0x8835, + /* 0x5c */ + 0x883a, 0x883c, 0x8841, 0x8843, 0x8845, 0x8848, 0x8849, 0x884a, + 0x884b, 0x884e, 0x8851, 0x8855, 0x8856, 0x8858, 0x885a, 0x885c, + 0x885f, 0x8860, 0x8864, 0x8869, 0x8871, 0x8879, 0x887b, 0x8880, + 0x8898, 0x889a, 0x889b, 0x889c, 0x889f, 0x88a0, 0x88a8, 0x88aa, + 0x88ba, 0x88bd, 0x88be, 0x88c0, 0x88ca, 0x88cb, 0x88cc, 0x88cd, + 0x88ce, 0x88d1, 0x88d2, 0x88d3, 0x88db, 0x88de, 0x88e7, 0x88ef, + 0x88f0, 0x88f1, 0x88f5, 0x88f7, 0x8901, 0x8906, 0x890d, 0x890e, + 0x890f, 0x8915, 0x8916, 0x8918, 0x8919, 0x891a, 0x891c, 0x8920, + 0x8926, 0x8927, 0x8928, 0x8930, 0x8931, 0x8932, 0x8935, 0x8939, + 0x893a, 0x893e, 0x8940, 0x8942, 0x8945, 0x8946, 0x8949, 0x894f, + 0x8952, 0x8957, 0x895a, 0x895b, 0x895c, 0x8961, 0x8962, 0x8963, + 0x896b, 0x896e, 0x8970, 0x8973, 0x8975, 0x897a, + /* 0x5d */ + 0x897b, 0x897c, 0x897d, 0x8989, 0x898d, 0x8990, 0x8994, 0x8995, + 0x899b, 0x899c, 0x899f, 0x89a0, 0x89a5, 0x89b0, 0x89b4, 0x89b5, + 0x89b6, 0x89b7, 0x89bc, 0x89d4, 0x89d5, 0x89d6, 0x89d7, 0x89d8, + 0x89e5, 0x89e9, 0x89eb, 0x89ed, 0x89f1, 0x89f3, 0x89f6, 0x89f9, + 0x89fd, 0x89ff, 0x8a04, 0x8a05, 0x8a07, 0x8a0f, 0x8a11, 0x8a12, + 0x8a14, 0x8a15, 0x8a1e, 0x8a20, 0x8a22, 0x8a24, 0x8a26, 0x8a2b, + 0x8a2c, 0x8a2f, 0x8a35, 0x8a37, 0x8a3d, 0x8a3e, 0x8a40, 0x8a43, + 0x8a45, 0x8a47, 0x8a49, 0x8a4d, 0x8a4e, 0x8a53, 0x8a56, 0x8a57, + 0x8a58, 0x8a5c, 0x8a5d, 0x8a61, 0x8a65, 0x8a67, 0x8a75, 0x8a76, + 0x8a77, 0x8a79, 0x8a7a, 0x8a7b, 0x8a7e, 0x8a7f, 0x8a80, 0x8a83, + 0x8a86, 0x8a8b, 0x8a8f, 0x8a90, 0x8a92, 0x8a96, 0x8a97, 0x8a99, + 0x8a9f, 0x8aa7, 0x8aa9, 0x8aae, 0x8aaf, 0x8ab3, + /* 0x5e */ + 0x8ab6, 0x8ab7, 0x8abb, 0x8abe, 0x8ac3, 0x8ac6, 0x8ac8, 0x8ac9, + 0x8aca, 0x8ad1, 0x8ad3, 0x8ad4, 0x8ad5, 0x8ad7, 0x8add, 0x8adf, + 0x8aec, 0x8af0, 0x8af4, 0x8af5, 0x8af6, 0x8afc, 0x8aff, 0x8b05, + 0x8b06, 0x8b0b, 0x8b11, 0x8b1c, 0x8b1e, 0x8b1f, 0x8b0a, 0x8b2d, + 0x8b30, 0x8b37, 0x8b3c, 0x8b42, 0x8b43, 0x8b44, 0x8b45, 0x8b46, + 0x8b48, 0x8b52, 0x8b53, 0x8b54, 0x8b59, 0x8b4d, 0x8b5e, 0x8b63, + 0x8b6d, 0x8b76, 0x8b78, 0x8b79, 0x8b7c, 0x8b7e, 0x8b81, 0x8b84, + 0x8b85, 0x8b8b, 0x8b8d, 0x8b8f, 0x8b94, 0x8b95, 0x8b9c, 0x8b9e, + 0x8b9f, 0x8c38, 0x8c39, 0x8c3d, 0x8c3e, 0x8c45, 0x8c47, 0x8c49, + 0x8c4b, 0x8c4f, 0x8c51, 0x8c53, 0x8c54, 0x8c57, 0x8c58, 0x8c5b, + 0x8c5d, 0x8c59, 0x8c63, 0x8c64, 0x8c66, 0x8c68, 0x8c69, 0x8c6d, + 0x8c73, 0x8c75, 0x8c76, 0x8c7b, 0x8c7e, 0x8c86, + /* 0x5f */ + 0x8c87, 0x8c8b, 0x8c90, 0x8c92, 0x8c93, 0x8c99, 0x8c9b, 0x8c9c, + 0x8ca4, 0x8cb9, 0x8cba, 0x8cc5, 0x8cc6, 0x8cc9, 0x8ccb, 0x8ccf, + 0x8cd6, 0x8cd5, 0x8cd9, 0x8cdd, 0x8ce1, 0x8ce8, 0x8cec, 0x8cef, + 0x8cf0, 0x8cf2, 0x8cf5, 0x8cf7, 0x8cf8, 0x8cfe, 0x8cff, 0x8d01, + 0x8d03, 0x8d09, 0x8d12, 0x8d17, 0x8d1b, 0x8d65, 0x8d69, 0x8d6c, + 0x8d6e, 0x8d7f, 0x8d82, 0x8d84, 0x8d88, 0x8d8d, 0x8d90, 0x8d91, + 0x8d95, 0x8d9e, 0x8d9f, 0x8da0, 0x8da6, 0x8dab, 0x8dac, 0x8daf, + 0x8db2, 0x8db5, 0x8db7, 0x8db9, 0x8dbb, 0x8dc0, 0x8dc5, 0x8dc6, + 0x8dc7, 0x8dc8, 0x8dca, 0x8dce, 0x8dd1, 0x8dd4, 0x8dd5, 0x8dd7, + 0x8dd9, 0x8de4, 0x8de5, 0x8de7, 0x8dec, 0x8df0, 0x8dbc, 0x8df1, + 0x8df2, 0x8df4, 0x8dfd, 0x8e01, 0x8e04, 0x8e05, 0x8e06, 0x8e0b, + 0x8e11, 0x8e14, 0x8e16, 0x8e20, 0x8e21, 0x8e22, + /* 0x60 */ + 0x8e23, 0x8e26, 0x8e27, 0x8e31, 0x8e33, 0x8e36, 0x8e37, 0x8e38, + 0x8e39, 0x8e3d, 0x8e40, 0x8e41, 0x8e4b, 0x8e4d, 0x8e4e, 0x8e4f, + 0x8e54, 0x8e5b, 0x8e5c, 0x8e5d, 0x8e5e, 0x8e61, 0x8e62, 0x8e69, + 0x8e6c, 0x8e6d, 0x8e6f, 0x8e70, 0x8e71, 0x8e79, 0x8e7a, 0x8e7b, + 0x8e82, 0x8e83, 0x8e89, 0x8e90, 0x8e92, 0x8e95, 0x8e9a, 0x8e9b, + 0x8e9d, 0x8e9e, 0x8ea2, 0x8ea7, 0x8ea9, 0x8ead, 0x8eae, 0x8eb3, + 0x8eb5, 0x8eba, 0x8ebb, 0x8ec0, 0x8ec1, 0x8ec3, 0x8ec4, 0x8ec7, + 0x8ecf, 0x8ed1, 0x8ed4, 0x8edc, 0x8ee8, 0x8eee, 0x8ef0, 0x8ef1, + 0x8ef7, 0x8ef9, 0x8efa, 0x8eed, 0x8f00, 0x8f02, 0x8f07, 0x8f08, + 0x8f0f, 0x8f10, 0x8f16, 0x8f17, 0x8f18, 0x8f1e, 0x8f20, 0x8f21, + 0x8f23, 0x8f25, 0x8f27, 0x8f28, 0x8f2c, 0x8f2d, 0x8f2e, 0x8f34, + 0x8f35, 0x8f36, 0x8f37, 0x8f3a, 0x8f40, 0x8f41, + /* 0x61 */ + 0x8f43, 0x8f47, 0x8f4f, 0x8f51, 0x8f52, 0x8f53, 0x8f54, 0x8f55, + 0x8f58, 0x8f5d, 0x8f5e, 0x8f65, 0x8f9d, 0x8fa0, 0x8fa1, 0x8fa4, + 0x8fa5, 0x8fa6, 0x8fb5, 0x8fb6, 0x8fb8, 0x8fbe, 0x8fc0, 0x8fc1, + 0x8fc6, 0x8fca, 0x8fcb, 0x8fcd, 0x8fd0, 0x8fd2, 0x8fd3, 0x8fd5, + 0x8fe0, 0x8fe3, 0x8fe4, 0x8fe8, 0x8fee, 0x8ff1, 0x8ff5, 0x8ff6, + 0x8ffb, 0x8ffe, 0x9002, 0x9004, 0x9008, 0x900c, 0x9018, 0x901b, + 0x9028, 0x9029, 0x902f, 0x902a, 0x902c, 0x902d, 0x9033, 0x9034, + 0x9037, 0x903f, 0x9043, 0x9044, 0x904c, 0x905b, 0x905d, 0x9062, + 0x9066, 0x9067, 0x906c, 0x9070, 0x9074, 0x9079, 0x9085, 0x9088, + 0x908b, 0x908c, 0x908e, 0x9090, 0x9095, 0x9097, 0x9098, 0x9099, + 0x909b, 0x90a0, 0x90a1, 0x90a2, 0x90a5, 0x90b0, 0x90b2, 0x90b3, + 0x90b4, 0x90b6, 0x90bd, 0x90cc, 0x90be, 0x90c3, + /* 0x62 */ + 0x90c4, 0x90c5, 0x90c7, 0x90c8, 0x90d5, 0x90d7, 0x90d8, 0x90d9, + 0x90dc, 0x90dd, 0x90df, 0x90e5, 0x90d2, 0x90f6, 0x90eb, 0x90ef, + 0x90f0, 0x90f4, 0x90fe, 0x90ff, 0x9100, 0x9104, 0x9105, 0x9106, + 0x9108, 0x910d, 0x9110, 0x9114, 0x9116, 0x9117, 0x9118, 0x911a, + 0x911c, 0x911e, 0x9120, 0x9125, 0x9122, 0x9123, 0x9127, 0x9129, + 0x912e, 0x912f, 0x9131, 0x9134, 0x9136, 0x9137, 0x9139, 0x913a, + 0x913c, 0x913d, 0x9143, 0x9147, 0x9148, 0x914f, 0x9153, 0x9157, + 0x9159, 0x915a, 0x915b, 0x9161, 0x9164, 0x9167, 0x916d, 0x9174, + 0x9179, 0x917a, 0x917b, 0x9181, 0x9183, 0x9185, 0x9186, 0x918a, + 0x918e, 0x9191, 0x9193, 0x9194, 0x9195, 0x9198, 0x919e, 0x91a1, + 0x91a6, 0x91a8, 0x91ac, 0x91ad, 0x91ae, 0x91b0, 0x91b1, 0x91b2, + 0x91b3, 0x91b6, 0x91bb, 0x91bc, 0x91bd, 0x91bf, + /* 0x63 */ + 0x91c2, 0x91c3, 0x91c5, 0x91d3, 0x91d4, 0x91d7, 0x91d9, 0x91da, + 0x91de, 0x91e4, 0x91e5, 0x91e9, 0x91ea, 0x91ec, 0x91ed, 0x91ee, + 0x91ef, 0x91f0, 0x91f1, 0x91f7, 0x91f9, 0x91fb, 0x91fd, 0x9200, + 0x9201, 0x9204, 0x9205, 0x9206, 0x9207, 0x9209, 0x920a, 0x920c, + 0x9210, 0x9212, 0x9213, 0x9216, 0x9218, 0x921c, 0x921d, 0x9223, + 0x9224, 0x9225, 0x9226, 0x9228, 0x922e, 0x922f, 0x9230, 0x9233, + 0x9235, 0x9236, 0x9238, 0x9239, 0x923a, 0x923c, 0x923e, 0x9240, + 0x9242, 0x9243, 0x9246, 0x9247, 0x924a, 0x924d, 0x924e, 0x924f, + 0x9251, 0x9258, 0x9259, 0x925c, 0x925d, 0x9260, 0x9261, 0x9265, + 0x9267, 0x9268, 0x9269, 0x926e, 0x926f, 0x9270, 0x9275, 0x9276, + 0x9277, 0x9278, 0x9279, 0x927b, 0x927c, 0x927d, 0x927f, 0x9288, + 0x9289, 0x928a, 0x928d, 0x928e, 0x9292, 0x9297, + /* 0x64 */ + 0x9299, 0x929f, 0x92a0, 0x92a4, 0x92a5, 0x92a7, 0x92a8, 0x92ab, + 0x92af, 0x92b2, 0x92b6, 0x92b8, 0x92ba, 0x92bb, 0x92bc, 0x92bd, + 0x92bf, 0x92c0, 0x92c1, 0x92c2, 0x92c3, 0x92c5, 0x92c6, 0x92c7, + 0x92c8, 0x92cb, 0x92cc, 0x92cd, 0x92ce, 0x92d0, 0x92d3, 0x92d5, + 0x92d7, 0x92d8, 0x92d9, 0x92dc, 0x92dd, 0x92df, 0x92e0, 0x92e1, + 0x92e3, 0x92e5, 0x92e7, 0x92e8, 0x92ec, 0x92ee, 0x92f0, 0x92f9, + 0x92fb, 0x92ff, 0x9300, 0x9302, 0x9308, 0x930d, 0x9311, 0x9314, + 0x9315, 0x931c, 0x931d, 0x931e, 0x931f, 0x9321, 0x9324, 0x9325, + 0x9327, 0x9329, 0x932a, 0x9333, 0x9334, 0x9336, 0x9337, 0x9347, + 0x9348, 0x9349, 0x9350, 0x9351, 0x9352, 0x9355, 0x9357, 0x9358, + 0x935a, 0x935e, 0x9364, 0x9365, 0x9367, 0x9369, 0x936a, 0x936d, + 0x936f, 0x9370, 0x9371, 0x9373, 0x9374, 0x9376, + /* 0x65 */ + 0x937a, 0x937d, 0x937f, 0x9380, 0x9381, 0x9382, 0x9388, 0x938a, + 0x938b, 0x938d, 0x938f, 0x9392, 0x9395, 0x9398, 0x939b, 0x939e, + 0x93a1, 0x93a3, 0x93a4, 0x93a6, 0x93a8, 0x93ab, 0x93b4, 0x93b5, + 0x93b6, 0x93ba, 0x93a9, 0x93c1, 0x93c4, 0x93c5, 0x93c6, 0x93c7, + 0x93c9, 0x93ca, 0x93cb, 0x93cc, 0x93cd, 0x93d3, 0x93d9, 0x93dc, + 0x93de, 0x93df, 0x93e2, 0x93e6, 0x93e7, 0x93f9, 0x93f7, 0x93f8, + 0x93fa, 0x93fb, 0x93fd, 0x9401, 0x9402, 0x9404, 0x9408, 0x9409, + 0x940d, 0x940e, 0x940f, 0x9415, 0x9416, 0x9417, 0x941f, 0x942e, + 0x942f, 0x9431, 0x9432, 0x9433, 0x9434, 0x943b, 0x943f, 0x943d, + 0x9443, 0x9445, 0x9448, 0x944a, 0x944c, 0x9455, 0x9459, 0x945c, + 0x945f, 0x9461, 0x9463, 0x9468, 0x946b, 0x946d, 0x946e, 0x946f, + 0x9471, 0x9472, 0x9484, 0x9483, 0x9578, 0x9579, + /* 0x66 */ + 0x957e, 0x9584, 0x9588, 0x958c, 0x958d, 0x958e, 0x959d, 0x959e, + 0x959f, 0x95a1, 0x95a6, 0x95a9, 0x95ab, 0x95ac, 0x95b4, 0x95b6, + 0x95ba, 0x95bd, 0x95bf, 0x95c6, 0x95c8, 0x95c9, 0x95cb, 0x95d0, + 0x95d1, 0x95d2, 0x95d3, 0x95d9, 0x95da, 0x95dd, 0x95de, 0x95df, + 0x95e0, 0x95e4, 0x95e6, 0x961d, 0x961e, 0x9622, 0x9624, 0x9625, + 0x9626, 0x962c, 0x9631, 0x9633, 0x9637, 0x9638, 0x9639, 0x963a, + 0x963c, 0x963d, 0x9641, 0x9652, 0x9654, 0x9656, 0x9657, 0x9658, + 0x9661, 0x966e, 0x9674, 0x967b, 0x967c, 0x967e, 0x967f, 0x9681, + 0x9682, 0x9683, 0x9684, 0x9689, 0x9691, 0x9696, 0x969a, 0x969d, + 0x969f, 0x96a4, 0x96a5, 0x96a6, 0x96a9, 0x96ae, 0x96af, 0x96b3, + 0x96ba, 0x96ca, 0x96d2, 0x5db2, 0x96d8, 0x96da, 0x96dd, 0x96de, + 0x96df, 0x96e9, 0x96ef, 0x96f1, 0x96fa, 0x9702, + /* 0x67 */ + 0x9703, 0x9705, 0x9709, 0x971a, 0x971b, 0x971d, 0x9721, 0x9722, + 0x9723, 0x9728, 0x9731, 0x9733, 0x9741, 0x9743, 0x974a, 0x974e, + 0x974f, 0x9755, 0x9757, 0x9758, 0x975a, 0x975b, 0x9763, 0x9767, + 0x976a, 0x976e, 0x9773, 0x9776, 0x9777, 0x9778, 0x977b, 0x977d, + 0x977f, 0x9780, 0x9789, 0x9795, 0x9796, 0x9797, 0x9799, 0x979a, + 0x979e, 0x979f, 0x97a2, 0x97ac, 0x97ae, 0x97b1, 0x97b2, 0x97b5, + 0x97b6, 0x97b8, 0x97b9, 0x97ba, 0x97bc, 0x97be, 0x97bf, 0x97c1, + 0x97c4, 0x97c5, 0x97c7, 0x97c9, 0x97ca, 0x97cc, 0x97cd, 0x97ce, + 0x97d0, 0x97d1, 0x97d4, 0x97d7, 0x97d8, 0x97d9, 0x97dd, 0x97de, + 0x97e0, 0x97db, 0x97e1, 0x97e4, 0x97ef, 0x97f1, 0x97f4, 0x97f7, + 0x97f8, 0x97fa, 0x9807, 0x980a, 0x9819, 0x980d, 0x980e, 0x9814, + 0x9816, 0x981c, 0x981e, 0x9820, 0x9823, 0x9826, + /* 0x68 */ + 0x982b, 0x982e, 0x982f, 0x9830, 0x9832, 0x9833, 0x9835, 0x9825, + 0x983e, 0x9844, 0x9847, 0x984a, 0x9851, 0x9852, 0x9853, 0x9856, + 0x9857, 0x9859, 0x985a, 0x9862, 0x9863, 0x9865, 0x9866, 0x986a, + 0x986c, 0x98ab, 0x98ad, 0x98ae, 0x98b0, 0x98b4, 0x98b7, 0x98b8, + 0x98ba, 0x98bb, 0x98bf, 0x98c2, 0x98c5, 0x98c8, 0x98cc, 0x98e1, + 0x98e3, 0x98e5, 0x98e6, 0x98e7, 0x98ea, 0x98f3, 0x98f6, 0x9902, + 0x9907, 0x9908, 0x9911, 0x9915, 0x9916, 0x9917, 0x991a, 0x991b, + 0x991c, 0x991f, 0x9922, 0x9926, 0x9927, 0x992b, 0x9931, 0x9932, + 0x9933, 0x9934, 0x9935, 0x9939, 0x993a, 0x993b, 0x993c, 0x9940, + 0x9941, 0x9946, 0x9947, 0x9948, 0x994d, 0x994e, 0x9954, 0x9958, + 0x9959, 0x995b, 0x995c, 0x995e, 0x995f, 0x9960, 0x999b, 0x999d, + 0x999f, 0x99a6, 0x99b0, 0x99b1, 0x99b2, 0x99b5, + /* 0x69 */ + 0x99b9, 0x99ba, 0x99bd, 0x99bf, 0x99c3, 0x99c9, 0x99d3, 0x99d4, + 0x99d9, 0x99da, 0x99dc, 0x99de, 0x99e7, 0x99ea, 0x99eb, 0x99ec, + 0x99f0, 0x99f4, 0x99f5, 0x99f9, 0x99fd, 0x99fe, 0x9a02, 0x9a03, + 0x9a04, 0x9a0b, 0x9a0c, 0x9a10, 0x9a11, 0x9a16, 0x9a1e, 0x9a20, + 0x9a22, 0x9a23, 0x9a24, 0x9a27, 0x9a2d, 0x9a2e, 0x9a33, 0x9a35, + 0x9a36, 0x9a38, 0x9a47, 0x9a41, 0x9a44, 0x9a4a, 0x9a4b, 0x9a4c, + 0x9a4e, 0x9a51, 0x9a54, 0x9a56, 0x9a5d, 0x9aaa, 0x9aac, 0x9aae, + 0x9aaf, 0x9ab2, 0x9ab4, 0x9ab5, 0x9ab6, 0x9ab9, 0x9abb, 0x9abe, + 0x9abf, 0x9ac1, 0x9ac3, 0x9ac6, 0x9ac8, 0x9ace, 0x9ad0, 0x9ad2, + 0x9ad5, 0x9ad6, 0x9ad7, 0x9adb, 0x9adc, 0x9ae0, 0x9ae4, 0x9ae5, + 0x9ae7, 0x9ae9, 0x9aec, 0x9af2, 0x9af3, 0x9af5, 0x9af9, 0x9afa, + 0x9afd, 0x9aff, 0x9b00, 0x9b01, 0x9b02, 0x9b03, + /* 0x6a */ + 0x9b04, 0x9b05, 0x9b08, 0x9b09, 0x9b0b, 0x9b0c, 0x9b0d, 0x9b0e, + 0x9b10, 0x9b12, 0x9b16, 0x9b19, 0x9b1b, 0x9b1c, 0x9b20, 0x9b26, + 0x9b2b, 0x9b2d, 0x9b33, 0x9b34, 0x9b35, 0x9b37, 0x9b39, 0x9b3a, + 0x9b3d, 0x9b48, 0x9b4b, 0x9b4c, 0x9b55, 0x9b56, 0x9b57, 0x9b5b, + 0x9b5e, 0x9b61, 0x9b63, 0x9b65, 0x9b66, 0x9b68, 0x9b6a, 0x9b6b, + 0x9b6c, 0x9b6d, 0x9b6e, 0x9b73, 0x9b75, 0x9b77, 0x9b78, 0x9b79, + 0x9b7f, 0x9b80, 0x9b84, 0x9b85, 0x9b86, 0x9b87, 0x9b89, 0x9b8a, + 0x9b8b, 0x9b8d, 0x9b8f, 0x9b90, 0x9b94, 0x9b9a, 0x9b9d, 0x9b9e, + 0x9ba6, 0x9ba7, 0x9ba9, 0x9bac, 0x9bb0, 0x9bb1, 0x9bb2, 0x9bb7, + 0x9bb8, 0x9bbb, 0x9bbc, 0x9bbe, 0x9bbf, 0x9bc1, 0x9bc7, 0x9bc8, + 0x9bce, 0x9bd0, 0x9bd7, 0x9bd8, 0x9bdd, 0x9bdf, 0x9be5, 0x9be7, + 0x9bea, 0x9beb, 0x9bef, 0x9bf3, 0x9bf7, 0x9bf8, + /* 0x6b */ + 0x9bf9, 0x9bfa, 0x9bfd, 0x9bff, 0x9c00, 0x9c02, 0x9c0b, 0x9c0f, + 0x9c11, 0x9c16, 0x9c18, 0x9c19, 0x9c1a, 0x9c1c, 0x9c1e, 0x9c22, + 0x9c23, 0x9c26, 0x9c27, 0x9c28, 0x9c29, 0x9c2a, 0x9c31, 0x9c35, + 0x9c36, 0x9c37, 0x9c3d, 0x9c41, 0x9c43, 0x9c44, 0x9c45, 0x9c49, + 0x9c4a, 0x9c4e, 0x9c4f, 0x9c50, 0x9c53, 0x9c54, 0x9c56, 0x9c58, + 0x9c5b, 0x9c5d, 0x9c5e, 0x9c5f, 0x9c63, 0x9c69, 0x9c6a, 0x9c5c, + 0x9c6b, 0x9c68, 0x9c6e, 0x9c70, 0x9c72, 0x9c75, 0x9c77, 0x9c7b, + 0x9ce6, 0x9cf2, 0x9cf7, 0x9cf9, 0x9d0b, 0x9d02, 0x9d11, 0x9d17, + 0x9d18, 0x9d1c, 0x9d1d, 0x9d1e, 0x9d2f, 0x9d30, 0x9d32, 0x9d33, + 0x9d34, 0x9d3a, 0x9d3c, 0x9d45, 0x9d3d, 0x9d42, 0x9d43, 0x9d47, + 0x9d4a, 0x9d53, 0x9d54, 0x9d5f, 0x9d63, 0x9d62, 0x9d65, 0x9d69, + 0x9d6a, 0x9d6b, 0x9d70, 0x9d76, 0x9d77, 0x9d7b, + /* 0x6c */ + 0x9d7c, 0x9d7e, 0x9d83, 0x9d84, 0x9d86, 0x9d8a, 0x9d8d, 0x9d8e, + 0x9d92, 0x9d93, 0x9d95, 0x9d96, 0x9d97, 0x9d98, 0x9da1, 0x9daa, + 0x9dac, 0x9dae, 0x9db1, 0x9db5, 0x9db9, 0x9dbc, 0x9dbf, 0x9dc3, + 0x9dc7, 0x9dc9, 0x9dca, 0x9dd4, 0x9dd5, 0x9dd6, 0x9dd7, 0x9dda, + 0x9dde, 0x9ddf, 0x9de0, 0x9de5, 0x9de7, 0x9de9, 0x9deb, 0x9dee, + 0x9df0, 0x9df3, 0x9df4, 0x9dfe, 0x9e0a, 0x9e02, 0x9e07, 0x9e0e, + 0x9e10, 0x9e11, 0x9e12, 0x9e15, 0x9e16, 0x9e19, 0x9e1c, 0x9e1d, + 0x9e7a, 0x9e7b, 0x9e7c, 0x9e80, 0x9e82, 0x9e83, 0x9e84, 0x9e85, + 0x9e87, 0x9e8e, 0x9e8f, 0x9e96, 0x9e98, 0x9e9b, 0x9e9e, 0x9ea4, + 0x9ea8, 0x9eac, 0x9eae, 0x9eaf, 0x9eb0, 0x9eb3, 0x9eb4, 0x9eb5, + 0x9ec6, 0x9ec8, 0x9ecb, 0x9ed5, 0x9edf, 0x9ee4, 0x9ee7, 0x9eec, + 0x9eed, 0x9eee, 0x9ef0, 0x9ef1, 0x9ef2, 0x9ef5, + /* 0x6d */ + 0x9ef8, 0x9eff, 0x9f02, 0x9f03, 0x9f09, 0x9f0f, 0x9f10, 0x9f11, + 0x9f12, 0x9f14, 0x9f16, 0x9f17, 0x9f19, 0x9f1a, 0x9f1b, 0x9f1f, + 0x9f22, 0x9f26, 0x9f2a, 0x9f2b, 0x9f2f, 0x9f31, 0x9f32, 0x9f34, + 0x9f37, 0x9f39, 0x9f3a, 0x9f3c, 0x9f3d, 0x9f3f, 0x9f41, 0x9f43, + 0x9f44, 0x9f45, 0x9f46, 0x9f47, 0x9f53, 0x9f55, 0x9f56, 0x9f57, + 0x9f58, 0x9f5a, 0x9f5d, 0x9f5e, 0x9f68, 0x9f69, 0x9f6d, 0x9f6e, + 0x9f6f, 0x9f70, 0x9f71, 0x9f73, 0x9f75, 0x9f7a, 0x9f7d, 0x9f8f, + 0x9f90, 0x9f91, 0x9f92, 0x9f94, 0x9f96, 0x9f97, 0x9f9e, 0x9fa1, + 0x9fa2, 0x9fa3, 0x9fa5, +}; + +static int +jisx0212_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 == 0x22) || (c1 >= 0x26 && c1 <= 0x27) || (c1 >= 0x29 && c1 <= 0x2b) || (c1 >= 0x30 && c1 <= 0x6d)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + unsigned short wc = 0xfffd; + if (i < 470) { + if (i < 175) + wc = jisx0212_2uni_page22[i-94]; + } else if (i < 752) { + if (i < 658) + wc = jisx0212_2uni_page26[i-470]; + } else if (i < 1410) { + if (i < 1027) + wc = jisx0212_2uni_page29[i-752]; + } else { + if (i < 7211) + wc = jisx0212_2uni_page30[i-1410]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short jisx0212_2charset[6067] = { + 0x2242, 0x2270, 0x2243, 0x226d, 0x226c, 0x226e, 0x2234, 0x2231, + 0x226b, 0x2244, 0x2a22, 0x2a21, 0x2a24, 0x2a2a, 0x2a23, 0x2a29, + 0x2921, 0x2a2e, 0x2a32, 0x2a31, 0x2a34, 0x2a33, 0x2a40, 0x2a3f, + 0x2a42, 0x2a41, 0x2a50, 0x2a52, 0x2a51, 0x2a54, 0x2a58, 0x2a53, + 0x292c, 0x2a63, 0x2a62, 0x2a65, 0x2a64, 0x2a72, 0x2930, 0x294e, + 0x2b22, 0x2b21, 0x2b24, 0x2b2a, 0x2b23, 0x2b29, 0x2941, 0x2b2e, + 0x2b32, 0x2b31, 0x2b34, 0x2b33, 0x2b40, 0x2b3f, 0x2b42, 0x2b41, + 0x2943, 0x2b50, 0x2b52, 0x2b51, 0x2b54, 0x2b58, 0x2b53, 0x294c, + 0x2b63, 0x2b62, 0x2b65, 0x2b64, 0x2b72, 0x2950, 0x2b73, 0x2a27, + 0x2b27, 0x2a25, 0x2b25, 0x2a28, 0x2b28, 0x2a2b, 0x2b2b, 0x2a2c, + 0x2b2c, 0x2a2f, 0x2b2f, 0x2a2d, 0x2b2d, 0x2a30, 0x2b30, 0x2922, + 0x2942, 0x2a37, 0x2b37, 0x2a36, 0x2b36, 0x2a38, 0x2b38, 0x2a35, + 0x2b35, 0x2a3a, 0x2b3a, 0x2a3b, 0x2b3b, 0x2a3d, 0x2b3d, 0x2a3c, + 0x2a3e, 0x2b3e, 0x2924, 0x2944, 0x2a47, 0x2b47, 0x2a45, 0x2b45, + 0x2a46, 0x2b46, 0x2a44, 0x2945, 0x2926, 0x2946, 0x2a48, 0x2b48, + 0x2a49, 0x2b49, 0x2947, 0x2a4a, 0x2b4a, 0x2a4c, 0x2b4c, 0x2a4b, + 0x2b4b, 0x2929, 0x2949, 0x2928, 0x2948, 0x2a4d, 0x2b4d, 0x2a4f, + 0x2b4f, 0x2a4e, 0x2b4e, 0x294a, 0x292b, 0x294b, 0x2a57, 0x2b57, + 0x2a56, 0x2b56, 0x292d, 0x294d, 0x2a59, 0x2b59, 0x2a5b, 0x2b5b, + 0x2a5a, 0x2b5a, 0x2a5c, 0x2b5c, 0x2a5d, 0x2b5d, 0x2a5f, 0x2b5f, + 0x2a5e, 0x2b5e, 0x2a61, 0x2b61, 0x2a60, 0x2b60, 0x292f, 0x294f, + 0x2a6c, 0x2b6c, 0x2a69, 0x2b69, 0x2a66, 0x2b66, 0x2a6b, 0x2b6b, + 0x2a68, 0x2b68, 0x2a6a, 0x2b6a, 0x2a71, 0x2b71, 0x2a74, 0x2b74, + 0x2a73, 0x2a75, 0x2b75, 0x2a77, 0x2b77, 0x2a76, 0x2b76, 0x2a26, + 0x2b26, 0x2a43, 0x2b43, 0x2a55, 0x2b55, 0x2a67, 0x2b67, 0x2a70, + 0x2b70, 0x2a6d, 0x2b6d, 0x2a6f, 0x2b6f, 0x2a6e, 0x2b6e, 0x2b39, + 0x2230, 0x222f, 0x2232, 0x2236, 0x2235, 0x2233, 0x2238, 0x2239, + 0x2661, 0x2662, 0x2663, 0x2664, 0x2667, 0x2669, 0x266c, 0x2676, + 0x2665, 0x266a, 0x2671, 0x2672, 0x2673, 0x2674, 0x267b, 0x2678, + 0x2675, 0x267a, 0x2677, 0x2679, 0x267c, 0x2742, 0x2743, 0x2744, + 0x2745, 0x2746, 0x2747, 0x2748, 0x2749, 0x274a, 0x274b, 0x274c, + 0x274d, 0x274e, 0x2772, 0x2773, 0x2774, 0x2775, 0x2776, 0x2777, + 0x2778, 0x2779, 0x277a, 0x277b, 0x277c, 0x277d, 0x277e, 0x2271, + 0x226f, 0x3021, 0x3022, 0x3023, 0x3024, 0x3025, 0x3026, 0x3027, + 0x3028, 0x3029, 0x302a, 0x302b, 0x302c, 0x302d, 0x302e, 0x302f, + 0x3030, 0x3031, 0x3032, 0x3033, 0x3034, 0x3035, 0x3036, 0x3037, + 0x3038, 0x3039, 0x303a, 0x303b, 0x303c, 0x303d, 0x303e, 0x303f, + 0x3040, 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, + 0x3048, 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, + 0x3050, 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, + 0x3058, 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x3060, + 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, + 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3070, + 0x305f, 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, + 0x3078, 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x3121, + 0x3122, 0x3123, 0x3124, 0x3125, 0x3126, 0x3127, 0x3128, 0x3129, + 0x312a, 0x312b, 0x312c, 0x312d, 0x312e, 0x312f, 0x3130, 0x3131, + 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3138, 0x3139, + 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, 0x3140, 0x3141, + 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147, 0x3148, 0x3149, + 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f, 0x3150, 0x3151, + 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, 0x3159, + 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x3176, 0x315f, 0x3160, + 0x3161, 0x3162, 0x3163, 0x3164, 0x3165, 0x3166, 0x3167, 0x3168, + 0x3169, 0x316a, 0x316b, 0x316c, 0x316d, 0x316e, 0x316f, 0x3170, + 0x3171, 0x3172, 0x3173, 0x3174, 0x3175, 0x3177, 0x3178, 0x3179, + 0x317a, 0x317b, 0x317c, 0x317d, 0x317e, 0x3221, 0x3222, 0x3223, + 0x3224, 0x3225, 0x3226, 0x3227, 0x3228, 0x3229, 0x322a, 0x322b, + 0x322c, 0x322d, 0x322e, 0x322f, 0x3230, 0x3231, 0x3232, 0x3233, + 0x3234, 0x3235, 0x3236, 0x3237, 0x3238, 0x3239, 0x323a, 0x323b, + 0x323c, 0x323d, 0x323e, 0x323f, 0x3240, 0x3241, 0x3242, 0x3243, + 0x3244, 0x3245, 0x3251, 0x3246, 0x3247, 0x3248, 0x3249, 0x324a, + 0x324b, 0x324c, 0x324d, 0x324e, 0x324f, 0x3250, 0x3252, 0x3253, + 0x3254, 0x3255, 0x3256, 0x3257, 0x3258, 0x3259, 0x325a, 0x325b, + 0x325c, 0x325d, 0x325e, 0x325f, 0x3260, 0x3261, 0x3262, 0x3263, + 0x3264, 0x3265, 0x3266, 0x3267, 0x3268, 0x3269, 0x326a, 0x326b, + 0x326c, 0x326d, 0x326e, 0x326f, 0x3270, 0x3271, 0x3272, 0x3273, + 0x3274, 0x3275, 0x3276, 0x3277, 0x3278, 0x3279, 0x327a, 0x327b, + 0x327c, 0x327d, 0x327e, 0x3321, 0x3322, 0x3323, 0x3324, 0x3325, + 0x3326, 0x3327, 0x3328, 0x3329, 0x332a, 0x332b, 0x332c, 0x332d, + 0x332e, 0x332f, 0x3330, 0x3331, 0x3332, 0x3333, 0x3334, 0x3335, + 0x3336, 0x3337, 0x3338, 0x3339, 0x333a, 0x333b, 0x333c, 0x333d, + 0x333e, 0x333f, 0x3340, 0x3341, 0x3342, 0x3343, 0x3344, 0x3345, + 0x3346, 0x3347, 0x3348, 0x3349, 0x334a, 0x334b, 0x334c, 0x334d, + 0x334e, 0x334f, 0x3350, 0x3351, 0x3352, 0x3353, 0x3354, 0x3355, + 0x3356, 0x3357, 0x3358, 0x3359, 0x335a, 0x335b, 0x335c, 0x335d, + 0x335e, 0x335f, 0x3360, 0x3361, 0x3362, 0x3363, 0x3364, 0x3365, + 0x3366, 0x3367, 0x3368, 0x3369, 0x336a, 0x336b, 0x336c, 0x336d, + 0x336e, 0x336f, 0x3370, 0x3371, 0x3372, 0x3373, 0x3374, 0x3375, + 0x3376, 0x3377, 0x3378, 0x3379, 0x337a, 0x337b, 0x337c, 0x337d, + 0x337e, 0x3421, 0x3422, 0x3423, 0x3424, 0x3425, 0x3426, 0x3427, + 0x3428, 0x3429, 0x342a, 0x342b, 0x342c, 0x342d, 0x342e, 0x342f, + 0x3430, 0x3431, 0x3432, 0x3433, 0x3434, 0x3435, 0x3436, 0x3438, + 0x3437, 0x3439, 0x343a, 0x343b, 0x343c, 0x343d, 0x343e, 0x343f, + 0x3440, 0x3441, 0x3442, 0x3443, 0x3444, 0x3445, 0x3446, 0x3447, + 0x3448, 0x3449, 0x344a, 0x344b, 0x344c, 0x344d, 0x344e, 0x344f, + 0x3450, 0x3451, 0x3452, 0x3453, 0x3454, 0x3455, 0x3456, 0x3457, + 0x3458, 0x3459, 0x345a, 0x345b, 0x345c, 0x345d, 0x345e, 0x345f, + 0x3460, 0x3461, 0x3462, 0x3463, 0x3464, 0x3465, 0x3466, 0x3467, + 0x3468, 0x3469, 0x346a, 0x346b, 0x346c, 0x346d, 0x346e, 0x346f, + 0x3470, 0x3471, 0x3472, 0x3473, 0x3474, 0x3475, 0x3476, 0x3477, + 0x3478, 0x3479, 0x347a, 0x347b, 0x347c, 0x347d, 0x347e, 0x3521, + 0x3522, 0x3523, 0x3524, 0x3525, 0x3526, 0x3527, 0x3528, 0x3529, + 0x352a, 0x352b, 0x352c, 0x352d, 0x352e, 0x352f, 0x3530, 0x3531, + 0x3532, 0x3533, 0x3534, 0x3535, 0x3536, 0x3537, 0x3538, 0x3539, + 0x353a, 0x353b, 0x353c, 0x353d, 0x353e, 0x353f, 0x3540, 0x3541, + 0x3542, 0x3543, 0x3544, 0x3545, 0x3546, 0x3547, 0x3548, 0x3549, + 0x354a, 0x354b, 0x354c, 0x354d, 0x354e, 0x354f, 0x3550, 0x3551, + 0x3552, 0x3553, 0x3554, 0x3555, 0x3556, 0x3557, 0x3558, 0x3559, + 0x355a, 0x355b, 0x355c, 0x355d, 0x355e, 0x355f, 0x3560, 0x3561, + 0x3562, 0x3563, 0x3564, 0x3565, 0x3566, 0x3567, 0x3568, 0x3569, + 0x356a, 0x356b, 0x356c, 0x356d, 0x356e, 0x356f, 0x3570, 0x3571, + 0x3572, 0x3573, 0x3574, 0x3575, 0x3576, 0x3577, 0x3578, 0x3579, + 0x357a, 0x357b, 0x357c, 0x357d, 0x357e, 0x3621, 0x3622, 0x3623, + 0x3624, 0x3625, 0x3626, 0x3627, 0x3628, 0x3629, 0x362a, 0x362b, + 0x362c, 0x362d, 0x362e, 0x362f, 0x3630, 0x3631, 0x3632, 0x3633, + 0x3634, 0x3635, 0x3636, 0x3637, 0x3638, 0x3639, 0x363a, 0x363b, + 0x363c, 0x363d, 0x363e, 0x363f, 0x3640, 0x3641, 0x3642, 0x3643, + 0x3644, 0x3645, 0x3646, 0x3647, 0x3648, 0x3649, 0x364a, 0x364b, + 0x364c, 0x364d, 0x364e, 0x364f, 0x3650, 0x3651, 0x3652, 0x3653, + 0x3654, 0x3655, 0x3656, 0x3657, 0x3658, 0x3659, 0x365a, 0x365b, + 0x365c, 0x365d, 0x365e, 0x365f, 0x3660, 0x3661, 0x3662, 0x3663, + 0x3664, 0x3665, 0x3666, 0x3667, 0x3668, 0x3669, 0x366a, 0x366b, + 0x366c, 0x366d, 0x3670, 0x3671, 0x366e, 0x366f, 0x3672, 0x3673, + 0x3674, 0x3675, 0x3676, 0x3677, 0x3678, 0x3679, 0x367a, 0x367b, + 0x367d, 0x367e, 0x367c, 0x3721, 0x3722, 0x3723, 0x3724, 0x3725, + 0x3726, 0x3727, 0x3728, 0x3729, 0x372a, 0x372b, 0x372c, 0x372d, + 0x372e, 0x372f, 0x3730, 0x3731, 0x3732, 0x3733, 0x3734, 0x3735, + 0x3736, 0x3737, 0x3738, 0x3739, 0x373a, 0x373b, 0x373c, 0x373d, + 0x373e, 0x373f, 0x3740, 0x3741, 0x3742, 0x3743, 0x3744, 0x3745, + 0x3746, 0x3747, 0x3748, 0x3749, 0x374a, 0x374b, 0x374c, 0x374d, + 0x374e, 0x374f, 0x3750, 0x3751, 0x3752, 0x3753, 0x3754, 0x3755, + 0x3756, 0x3757, 0x3760, 0x3758, 0x3759, 0x375a, 0x375b, 0x375c, + 0x375d, 0x375e, 0x375f, 0x3761, 0x3762, 0x3763, 0x3764, 0x3765, + 0x3766, 0x3767, 0x3768, 0x3769, 0x376a, 0x376b, 0x376c, 0x376d, + 0x377e, 0x376e, 0x376f, 0x3770, 0x3771, 0x3772, 0x3773, 0x3774, + 0x3775, 0x3776, 0x3777, 0x3778, 0x3779, 0x377a, 0x377b, 0x377c, + 0x377d, 0x3821, 0x3822, 0x3823, 0x3824, 0x3825, 0x3826, 0x3827, + 0x3828, 0x3829, 0x382a, 0x382b, 0x382c, 0x382d, 0x382e, 0x382f, + 0x3830, 0x3831, 0x3832, 0x3833, 0x3834, 0x3835, 0x3836, 0x3837, + 0x3838, 0x3839, 0x383a, 0x383b, 0x383c, 0x383d, 0x383e, 0x383f, + 0x3840, 0x3841, 0x3842, 0x3843, 0x3844, 0x3845, 0x3846, 0x3847, + 0x3848, 0x3849, 0x384a, 0x384b, 0x384c, 0x384d, 0x384e, 0x3850, + 0x3851, 0x384f, 0x3852, 0x3853, 0x3854, 0x3855, 0x3856, 0x3857, + 0x3858, 0x3859, 0x385a, 0x385b, 0x385c, 0x385d, 0x385e, 0x385f, + 0x3860, 0x3861, 0x3862, 0x3863, 0x3864, 0x3865, 0x3867, 0x3868, + 0x3869, 0x386a, 0x386b, 0x386c, 0x386d, 0x386e, 0x386f, 0x3870, + 0x3871, 0x3872, 0x3873, 0x3874, 0x3875, 0x3876, 0x3877, 0x3878, + 0x3879, 0x387a, 0x387b, 0x387c, 0x387d, 0x387e, 0x3921, 0x3922, + 0x3923, 0x3924, 0x3925, 0x3926, 0x3927, 0x3928, 0x3929, 0x392a, + 0x392b, 0x392c, 0x392d, 0x392e, 0x392f, 0x3930, 0x3931, 0x3932, + 0x3933, 0x3934, 0x3935, 0x3936, 0x3937, 0x3938, 0x3939, 0x393a, + 0x393b, 0x393c, 0x393d, 0x393e, 0x393f, 0x3940, 0x3941, 0x3942, + 0x3943, 0x3944, 0x3945, 0x3946, 0x3947, 0x3948, 0x3949, 0x394a, + 0x394b, 0x394c, 0x394d, 0x394e, 0x394f, 0x3950, 0x3951, 0x3952, + 0x3953, 0x3954, 0x3955, 0x3956, 0x3957, 0x3958, 0x3959, 0x395a, + 0x395b, 0x395c, 0x395d, 0x395e, 0x395f, 0x3960, 0x3961, 0x3962, + 0x3963, 0x3964, 0x3965, 0x3966, 0x3967, 0x3968, 0x3969, 0x396a, + 0x396b, 0x396c, 0x396d, 0x396e, 0x396f, 0x3970, 0x3971, 0x3972, + 0x3973, 0x3974, 0x3975, 0x3976, 0x3977, 0x3978, 0x3979, 0x397a, + 0x397b, 0x397c, 0x397d, 0x397e, 0x3a21, 0x3a22, 0x3a23, 0x3a24, + 0x3a25, 0x3a26, 0x3a27, 0x3a28, 0x3a29, 0x3a2a, 0x3a2b, 0x3a2c, + 0x3a2d, 0x3a2e, 0x3a2f, 0x3a30, 0x3a31, 0x3a33, 0x3a34, 0x3a35, + 0x3a36, 0x3a37, 0x3a38, 0x3a32, 0x3a39, 0x3a3a, 0x3a3b, 0x3a3c, + 0x3a3d, 0x3a3e, 0x3a3f, 0x3a40, 0x3a41, 0x3a42, 0x3a43, 0x3a44, + 0x3a45, 0x3a46, 0x3a47, 0x3a48, 0x3a49, 0x3a4a, 0x3a4b, 0x3a4c, + 0x3a4d, 0x3a4e, 0x3a4f, 0x3a50, 0x3a51, 0x3a52, 0x3a53, 0x3a54, + 0x3a55, 0x3a56, 0x3a57, 0x3a58, 0x3a59, 0x3a5a, 0x3a5b, 0x3a5c, + 0x3a5d, 0x3a5e, 0x3a5f, 0x3a60, 0x3a61, 0x3a62, 0x3a63, 0x3a64, + 0x3a65, 0x3a66, 0x3a67, 0x3a68, 0x3a69, 0x3a6a, 0x3a6b, 0x3a6c, + 0x3a6d, 0x3a6e, 0x3a6f, 0x3a70, 0x3a71, 0x3a72, 0x3a73, 0x3a74, + 0x3a75, 0x3a76, 0x3a77, 0x3a78, 0x3a79, 0x3a7a, 0x3a7b, 0x3a7c, + 0x3a7d, 0x3a7e, 0x3b21, 0x3b22, 0x3b23, 0x3b24, 0x3b25, 0x3b26, + 0x3b27, 0x3b28, 0x3b29, 0x3b2a, 0x3b2b, 0x3b2c, 0x3b2d, 0x3b2e, + 0x3b2f, 0x3b30, 0x3b31, 0x3b32, 0x3b33, 0x3b34, 0x3b35, 0x3b36, + 0x3b37, 0x3b38, 0x3b39, 0x3b3a, 0x3b3b, 0x3b3d, 0x3b3c, 0x3b3e, + 0x3b3f, 0x3b40, 0x3b41, 0x3b42, 0x3b43, 0x3b44, 0x3b45, 0x3b47, + 0x3b48, 0x3b49, 0x3b4a, 0x3b46, 0x3b4b, 0x3b4c, 0x3b4d, 0x3b4e, + 0x3b4f, 0x3b50, 0x3b51, 0x3b52, 0x3b53, 0x3b57, 0x3b55, 0x3b54, + 0x3b56, 0x3b58, 0x3b59, 0x3b5a, 0x3b5b, 0x3b5c, 0x3b5d, 0x3b5e, + 0x3b5f, 0x3b60, 0x3b61, 0x3b62, 0x3b63, 0x3b64, 0x3b65, 0x3b66, + 0x3b67, 0x3b68, 0x3b69, 0x3b6a, 0x3b6b, 0x3b6c, 0x3b6d, 0x3b6e, + 0x3b6f, 0x3b70, 0x3b71, 0x3b72, 0x6674, 0x3b73, 0x3b74, 0x3b75, + 0x3b76, 0x3b77, 0x3b78, 0x3b7a, 0x3b79, 0x3b7b, 0x3b7c, 0x3b7d, + 0x3b7e, 0x3c21, 0x3c22, 0x3c23, 0x3c24, 0x3c25, 0x3c26, 0x3c27, + 0x3c28, 0x3c29, 0x3c2a, 0x3c2b, 0x3c2c, 0x3c2e, 0x3c2d, 0x3c2f, + 0x3c30, 0x3c31, 0x3c34, 0x3c32, 0x3c33, 0x3c35, 0x3c36, 0x3c37, + 0x3c38, 0x3c39, 0x3c3a, 0x3c3b, 0x3c3c, 0x3c3d, 0x3c3e, 0x3c3f, + 0x3c40, 0x3c41, 0x3c42, 0x3c43, 0x3c44, 0x3c45, 0x3c46, 0x3c47, + 0x3c48, 0x3c49, 0x3c4a, 0x3c4b, 0x3c4c, 0x3c4d, 0x3c4e, 0x3c4f, + 0x3c50, 0x3c52, 0x3c51, 0x3c53, 0x3c54, 0x3c55, 0x3c56, 0x3c57, + 0x3c58, 0x3c59, 0x3c5a, 0x3c5b, 0x3c5c, 0x3c5d, 0x3c5e, 0x3c5f, + 0x3c60, 0x3c61, 0x3c62, 0x3c63, 0x3c64, 0x3c65, 0x3c66, 0x3c67, + 0x3c68, 0x3c69, 0x3c6a, 0x3c6b, 0x3c6c, 0x3c6d, 0x3c6e, 0x3c6f, + 0x3c70, 0x3c71, 0x3c72, 0x3c73, 0x3c74, 0x3c75, 0x3c76, 0x3c77, + 0x3c78, 0x3c79, 0x3c7a, 0x3c7b, 0x3c7c, 0x3c7d, 0x3c7e, 0x3d21, + 0x3d22, 0x3d23, 0x3d24, 0x3d25, 0x3d26, 0x3d27, 0x3d28, 0x3d29, + 0x3d2a, 0x3d2b, 0x3d2c, 0x3d2d, 0x3d2e, 0x3d2f, 0x3d32, 0x3d30, + 0x3d31, 0x3d33, 0x3d34, 0x3d35, 0x3d36, 0x3d37, 0x3d38, 0x3d39, + 0x3d3a, 0x3d3b, 0x3d3c, 0x3d3d, 0x3d3e, 0x3d3f, 0x3d40, 0x3d41, + 0x3d42, 0x3d43, 0x3d44, 0x3d45, 0x3d46, 0x3d47, 0x3d48, 0x3d49, + 0x3d4a, 0x3d4b, 0x3d4c, 0x3d4d, 0x3d4e, 0x3d4f, 0x3d50, 0x3d51, + 0x3d52, 0x3d53, 0x3d54, 0x3d55, 0x3d56, 0x3d57, 0x3d58, 0x3d59, + 0x3d5a, 0x3d5b, 0x3d5c, 0x3d5d, 0x3d5e, 0x3d5f, 0x3d60, 0x3d61, + 0x3d62, 0x3d63, 0x3d64, 0x3d65, 0x3d66, 0x3d67, 0x3d68, 0x3d69, + 0x3d6a, 0x3d6b, 0x3d6c, 0x3d6d, 0x3d6e, 0x3d6f, 0x3d70, 0x3d71, + 0x3d72, 0x3d73, 0x3d74, 0x3d75, 0x3d76, 0x3d77, 0x3d78, 0x3d79, + 0x3d7a, 0x3d7b, 0x3d7c, 0x3d7d, 0x3d7e, 0x3e21, 0x3e22, 0x3e23, + 0x3e24, 0x3e25, 0x3e26, 0x3e27, 0x3e28, 0x3e29, 0x3e2a, 0x3e2b, + 0x3e2c, 0x3e2d, 0x3e2e, 0x3e2f, 0x3e30, 0x3e31, 0x3e32, 0x3e33, + 0x3e34, 0x3e35, 0x3e36, 0x3e37, 0x3e38, 0x3e39, 0x3e3a, 0x3e3b, + 0x3e3c, 0x3e3d, 0x3e3e, 0x3e3f, 0x3e40, 0x3e41, 0x3e42, 0x3e43, + 0x3e44, 0x3e45, 0x3e46, 0x3e47, 0x3e48, 0x3e49, 0x3e4a, 0x3e4b, + 0x3e4c, 0x3e4d, 0x3e4e, 0x3e4f, 0x3e50, 0x3e51, 0x3e52, 0x3e53, + 0x3e54, 0x3e55, 0x3e56, 0x3e57, 0x3e58, 0x3e59, 0x3e5a, 0x3e5b, + 0x3e5c, 0x3e5d, 0x3e5e, 0x3e5f, 0x3e60, 0x3e61, 0x3e62, 0x3e63, + 0x3e64, 0x3e65, 0x3e66, 0x3e67, 0x3e68, 0x3e69, 0x3e6a, 0x3e6b, + 0x3e6c, 0x3e6d, 0x3e6e, 0x3e6f, 0x3e70, 0x3e71, 0x3e72, 0x3e73, + 0x3e74, 0x3e75, 0x3e76, 0x3e77, 0x3e78, 0x3e79, 0x3e7a, 0x3e7b, + 0x3e7e, 0x3e7c, 0x3e7d, 0x3f21, 0x3f22, 0x3f23, 0x3f24, 0x3f25, + 0x3f26, 0x3f27, 0x3f28, 0x3f29, 0x3f2a, 0x3f2b, 0x3f2c, 0x3f2d, + 0x3f2e, 0x3f2f, 0x3f30, 0x3f31, 0x3f32, 0x3f33, 0x3f34, 0x3f35, + 0x3f36, 0x3f37, 0x3f38, 0x3f39, 0x3f3a, 0x3f3b, 0x3f3c, 0x3f3d, + 0x3f3e, 0x3f3f, 0x3f40, 0x3f41, 0x3f42, 0x3f43, 0x3f44, 0x3f45, + 0x3f46, 0x3f47, 0x3f48, 0x3f49, 0x3f4a, 0x3f4b, 0x3f4c, 0x3f4d, + 0x3f4e, 0x3f4f, 0x3f50, 0x3f51, 0x3f52, 0x3f53, 0x3f54, 0x3f55, + 0x3f56, 0x3f57, 0x3f58, 0x3f59, 0x3f5a, 0x3f5b, 0x3f5c, 0x3f5d, + 0x3f5e, 0x3f5f, 0x3f60, 0x3f61, 0x3f62, 0x3f63, 0x3f64, 0x3f65, + 0x3f66, 0x3f67, 0x3f68, 0x3f69, 0x3f6a, 0x3f6b, 0x3f6c, 0x3f6d, + 0x3f6e, 0x3f6f, 0x3f70, 0x3f71, 0x3f72, 0x3f73, 0x3f74, 0x3f75, + 0x3f76, 0x3f77, 0x3f78, 0x3f79, 0x3f7a, 0x3f7b, 0x3f7c, 0x3f7d, + 0x3f7e, 0x4021, 0x4022, 0x4023, 0x4024, 0x4025, 0x4026, 0x4027, + 0x4028, 0x4029, 0x402a, 0x402b, 0x402c, 0x402d, 0x402e, 0x402f, + 0x4030, 0x4031, 0x4032, 0x4033, 0x4034, 0x4035, 0x4036, 0x4037, + 0x4038, 0x4039, 0x403a, 0x403b, 0x403c, 0x403d, 0x403e, 0x403f, + 0x4040, 0x4041, 0x4042, 0x4043, 0x4044, 0x4045, 0x4046, 0x4047, + 0x4048, 0x4049, 0x404a, 0x404b, 0x404c, 0x404d, 0x404e, 0x404f, + 0x4050, 0x4051, 0x4052, 0x4053, 0x4054, 0x4055, 0x4056, 0x4057, + 0x4058, 0x4059, 0x405a, 0x405b, 0x405c, 0x405d, 0x405e, 0x405f, + 0x4060, 0x4061, 0x4062, 0x4063, 0x4064, 0x4065, 0x4066, 0x4067, + 0x4068, 0x4069, 0x406a, 0x406b, 0x406c, 0x406d, 0x406e, 0x406f, + 0x4070, 0x4071, 0x4072, 0x4073, 0x4074, 0x4075, 0x4076, 0x4077, + 0x4078, 0x4079, 0x407a, 0x407b, 0x407c, 0x407d, 0x407e, 0x4121, + 0x4122, 0x4123, 0x4124, 0x4125, 0x4126, 0x4127, 0x4128, 0x4129, + 0x412a, 0x412b, 0x412c, 0x412d, 0x412e, 0x412f, 0x4130, 0x4131, + 0x4132, 0x4133, 0x4134, 0x4135, 0x4136, 0x4137, 0x4138, 0x4139, + 0x413a, 0x413b, 0x413c, 0x413d, 0x413e, 0x413f, 0x4140, 0x4141, + 0x4142, 0x4143, 0x4144, 0x4145, 0x4146, 0x4147, 0x4148, 0x4149, + 0x414a, 0x414b, 0x414c, 0x414d, 0x414e, 0x414f, 0x4150, 0x4151, + 0x4152, 0x4153, 0x4154, 0x4155, 0x4156, 0x4157, 0x4158, 0x4159, + 0x415a, 0x415b, 0x415c, 0x415d, 0x415e, 0x415f, 0x4160, 0x4161, + 0x4162, 0x4163, 0x4164, 0x4165, 0x4166, 0x4167, 0x4168, 0x4169, + 0x416a, 0x416b, 0x416c, 0x416d, 0x416e, 0x416f, 0x4170, 0x4171, + 0x4172, 0x4173, 0x4174, 0x4175, 0x4176, 0x4177, 0x4178, 0x4179, + 0x417a, 0x417b, 0x417c, 0x417d, 0x417e, 0x4221, 0x4222, 0x4223, + 0x4224, 0x4225, 0x4226, 0x4227, 0x4228, 0x4229, 0x422a, 0x422b, + 0x422c, 0x422d, 0x422e, 0x4230, 0x422f, 0x4231, 0x4232, 0x4233, + 0x4234, 0x4235, 0x4237, 0x4236, 0x4238, 0x4239, 0x423a, 0x423b, + 0x423c, 0x423d, 0x423e, 0x4240, 0x4241, 0x4242, 0x4244, 0x4245, + 0x4247, 0x4248, 0x4249, 0x424a, 0x424c, 0x4243, 0x4246, 0x424b, + 0x424d, 0x424e, 0x424f, 0x4250, 0x4251, 0x4252, 0x4253, 0x4254, + 0x4255, 0x4256, 0x4257, 0x4258, 0x4259, 0x425a, 0x425b, 0x425c, + 0x425d, 0x425e, 0x425f, 0x4260, 0x4261, 0x4262, 0x4263, 0x4264, + 0x4265, 0x4266, 0x4267, 0x4268, 0x4269, 0x426a, 0x426b, 0x426c, + 0x426d, 0x423f, 0x426e, 0x426f, 0x4270, 0x4271, 0x4272, 0x4273, + 0x4274, 0x4275, 0x4276, 0x4277, 0x4278, 0x4279, 0x427a, 0x427b, + 0x427c, 0x427d, 0x427e, 0x4321, 0x4322, 0x4323, 0x4324, 0x4325, + 0x4326, 0x4327, 0x4328, 0x4329, 0x432a, 0x432b, 0x432c, 0x432d, + 0x432e, 0x432f, 0x4330, 0x4331, 0x4332, 0x4333, 0x4334, 0x4335, + 0x4336, 0x4337, 0x4339, 0x433a, 0x433b, 0x433c, 0x433d, 0x433e, + 0x433f, 0x4340, 0x4341, 0x4342, 0x4343, 0x4344, 0x4345, 0x4346, + 0x4347, 0x4348, 0x4338, 0x434a, 0x434b, 0x434c, 0x434d, 0x434f, + 0x434e, 0x4350, 0x4351, 0x4352, 0x4353, 0x4354, 0x4355, 0x4356, + 0x4357, 0x4358, 0x4359, 0x435a, 0x435b, 0x4349, 0x435c, 0x435d, + 0x435e, 0x435f, 0x4360, 0x4361, 0x4362, 0x4363, 0x4364, 0x4365, + 0x4366, 0x4367, 0x4368, 0x4369, 0x436a, 0x436b, 0x436c, 0x436d, + 0x436e, 0x436f, 0x4370, 0x4371, 0x4372, 0x4373, 0x4374, 0x4375, + 0x4376, 0x4377, 0x4378, 0x4379, 0x437a, 0x437b, 0x437c, 0x437d, + 0x437e, 0x4421, 0x4422, 0x4423, 0x4424, 0x4425, 0x4426, 0x4427, + 0x4428, 0x4429, 0x442a, 0x442b, 0x442c, 0x442d, 0x442e, 0x442f, + 0x4430, 0x4431, 0x4432, 0x4433, 0x4434, 0x4435, 0x4436, 0x4437, + 0x4438, 0x4439, 0x443a, 0x443b, 0x443c, 0x443d, 0x443e, 0x443f, + 0x4440, 0x4441, 0x4442, 0x4443, 0x4444, 0x4445, 0x4446, 0x4447, + 0x4448, 0x4449, 0x444a, 0x444b, 0x444c, 0x444d, 0x444e, 0x444f, + 0x4450, 0x4451, 0x4452, 0x4453, 0x4454, 0x4455, 0x4456, 0x4457, + 0x4458, 0x4459, 0x445a, 0x445b, 0x445c, 0x445d, 0x445e, 0x445f, + 0x4460, 0x4461, 0x4462, 0x4463, 0x4464, 0x4465, 0x4466, 0x4467, + 0x4468, 0x4469, 0x446a, 0x446b, 0x446c, 0x446d, 0x446e, 0x446f, + 0x4470, 0x4471, 0x4472, 0x4473, 0x4474, 0x4475, 0x4476, 0x4477, + 0x4478, 0x4479, 0x447a, 0x447b, 0x447c, 0x447d, 0x447e, 0x4521, + 0x4522, 0x4523, 0x4524, 0x4525, 0x4526, 0x4527, 0x4528, 0x4529, + 0x452a, 0x452b, 0x452c, 0x452d, 0x452e, 0x452f, 0x4530, 0x4531, + 0x4532, 0x4533, 0x4534, 0x4535, 0x4536, 0x4537, 0x4538, 0x4539, + 0x453a, 0x453b, 0x453c, 0x453d, 0x453e, 0x453f, 0x4540, 0x4541, + 0x4542, 0x4543, 0x4544, 0x4545, 0x4546, 0x4547, 0x4548, 0x4549, + 0x454a, 0x454b, 0x454d, 0x454c, 0x454e, 0x454f, 0x4550, 0x4551, + 0x4552, 0x4553, 0x4554, 0x4555, 0x4556, 0x4557, 0x4558, 0x4559, + 0x455a, 0x455b, 0x455c, 0x455d, 0x455e, 0x455f, 0x4560, 0x4561, + 0x4562, 0x4563, 0x4564, 0x4565, 0x4566, 0x4567, 0x4568, 0x4569, + 0x456a, 0x456b, 0x456c, 0x456d, 0x456e, 0x456f, 0x4570, 0x4571, + 0x4572, 0x4573, 0x4574, 0x4575, 0x4576, 0x4577, 0x4578, 0x4579, + 0x457a, 0x457b, 0x457c, 0x457d, 0x457e, 0x4621, 0x4622, 0x4623, + 0x4624, 0x4625, 0x4626, 0x4627, 0x4628, 0x4629, 0x462a, 0x462b, + 0x462c, 0x462d, 0x462e, 0x462f, 0x4630, 0x4631, 0x4632, 0x4633, + 0x4634, 0x4635, 0x4636, 0x4637, 0x4638, 0x4639, 0x463a, 0x463b, + 0x463c, 0x463d, 0x463e, 0x463f, 0x4640, 0x4641, 0x4642, 0x4643, + 0x4644, 0x4645, 0x4646, 0x4647, 0x4648, 0x4649, 0x464a, 0x464b, + 0x464c, 0x464d, 0x464e, 0x464f, 0x4650, 0x4651, 0x4652, 0x4653, + 0x4654, 0x4655, 0x4656, 0x4657, 0x4658, 0x4659, 0x465a, 0x465b, + 0x465c, 0x465d, 0x465e, 0x465f, 0x4660, 0x4736, 0x4661, 0x4662, + 0x4663, 0x4664, 0x4665, 0x4666, 0x4667, 0x4668, 0x4669, 0x466a, + 0x466b, 0x466c, 0x466d, 0x466e, 0x466f, 0x4670, 0x4671, 0x4672, + 0x4673, 0x4674, 0x4675, 0x4676, 0x4677, 0x4678, 0x4679, 0x467a, + 0x467b, 0x467c, 0x467d, 0x467e, 0x4721, 0x4722, 0x4723, 0x4724, + 0x4725, 0x4726, 0x4727, 0x4728, 0x4729, 0x472a, 0x472b, 0x472c, + 0x472d, 0x472e, 0x472f, 0x4730, 0x4731, 0x4732, 0x4733, 0x4734, + 0x4735, 0x4737, 0x4738, 0x4739, 0x473a, 0x473b, 0x473c, 0x473d, + 0x473e, 0x473f, 0x4740, 0x4741, 0x4742, 0x4743, 0x4744, 0x4745, + 0x4746, 0x4747, 0x4748, 0x4749, 0x474a, 0x474b, 0x474c, 0x474d, + 0x474e, 0x474f, 0x4750, 0x4751, 0x4752, 0x4753, 0x4754, 0x4755, + 0x4756, 0x4757, 0x4758, 0x4759, 0x475a, 0x475b, 0x475c, 0x475d, + 0x475e, 0x475f, 0x4760, 0x4761, 0x4762, 0x4763, 0x4764, 0x4765, + 0x4766, 0x4767, 0x4768, 0x4769, 0x476a, 0x476b, 0x476c, 0x476d, + 0x476e, 0x476f, 0x4770, 0x4771, 0x4772, 0x4773, 0x4774, 0x4775, + 0x4776, 0x4777, 0x4778, 0x4779, 0x477a, 0x477b, 0x477c, 0x477d, + 0x477e, 0x4821, 0x4822, 0x4823, 0x4824, 0x4825, 0x4826, 0x4827, + 0x4828, 0x4829, 0x482a, 0x482b, 0x482c, 0x482d, 0x482e, 0x482f, + 0x4830, 0x4831, 0x4832, 0x4833, 0x4834, 0x4835, 0x4836, 0x4837, + 0x4838, 0x4839, 0x483a, 0x483b, 0x483c, 0x483d, 0x483e, 0x483f, + 0x4840, 0x4841, 0x4842, 0x4843, 0x4844, 0x4845, 0x4846, 0x4847, + 0x4848, 0x4849, 0x484a, 0x484b, 0x484c, 0x4853, 0x484d, 0x484e, + 0x484f, 0x4850, 0x4851, 0x4852, 0x4854, 0x4855, 0x4856, 0x4857, + 0x4858, 0x4859, 0x485a, 0x485b, 0x485c, 0x485d, 0x485e, 0x485f, + 0x4860, 0x4861, 0x4862, 0x4863, 0x4864, 0x4865, 0x4866, 0x4867, + 0x4868, 0x4869, 0x486a, 0x486b, 0x486c, 0x486d, 0x486e, 0x486f, + 0x4870, 0x4871, 0x4872, 0x4873, 0x4874, 0x4875, 0x4876, 0x4877, + 0x4878, 0x4879, 0x487a, 0x487b, 0x487c, 0x487d, 0x487e, 0x4921, + 0x4922, 0x4923, 0x4924, 0x4925, 0x4926, 0x4927, 0x4928, 0x4929, + 0x492a, 0x492b, 0x492c, 0x492d, 0x492e, 0x492f, 0x4930, 0x4931, + 0x4932, 0x4933, 0x4934, 0x4935, 0x4936, 0x4937, 0x4938, 0x4939, + 0x493a, 0x493b, 0x493c, 0x4941, 0x493d, 0x493e, 0x493f, 0x4940, + 0x4942, 0x4943, 0x4944, 0x4945, 0x4946, 0x4947, 0x4948, 0x4949, + 0x494a, 0x494b, 0x494c, 0x494d, 0x494e, 0x494f, 0x4950, 0x4951, + 0x4952, 0x4953, 0x4954, 0x4955, 0x4956, 0x4957, 0x4958, 0x4959, + 0x495a, 0x495b, 0x495c, 0x495d, 0x495e, 0x495f, 0x4960, 0x4961, + 0x4962, 0x4963, 0x4964, 0x4965, 0x4966, 0x4967, 0x4968, 0x4969, + 0x496a, 0x496b, 0x496c, 0x496d, 0x496e, 0x496f, 0x4970, 0x4971, + 0x4972, 0x4973, 0x4974, 0x4975, 0x4976, 0x4977, 0x4978, 0x4979, + 0x497a, 0x497b, 0x497c, 0x497d, 0x497e, 0x4a21, 0x4a22, 0x4a23, + 0x4a24, 0x4a25, 0x4a26, 0x4a27, 0x4a28, 0x4a29, 0x4a2a, 0x4a2b, + 0x4a2c, 0x4a2d, 0x4a2e, 0x4a2f, 0x4a30, 0x4a31, 0x4a32, 0x4a33, + 0x4a34, 0x4a35, 0x4a36, 0x4a37, 0x4a38, 0x4a39, 0x4a3a, 0x4a3b, + 0x4a3c, 0x4a3d, 0x4a3e, 0x4a3f, 0x4a40, 0x4a41, 0x4a42, 0x4a43, + 0x4a44, 0x4a45, 0x4a46, 0x4a47, 0x4a48, 0x4a49, 0x4a4a, 0x4a4b, + 0x4a4c, 0x4a4d, 0x4a4e, 0x4a4f, 0x4a50, 0x4a51, 0x4a52, 0x4a53, + 0x4a54, 0x4a55, 0x4a56, 0x4a57, 0x4a58, 0x4a59, 0x4a5a, 0x4a5b, + 0x4a5c, 0x4a5d, 0x4a5e, 0x4a5f, 0x4a60, 0x4a61, 0x4a62, 0x4a63, + 0x4a64, 0x4a65, 0x4a66, 0x4a67, 0x4a68, 0x4a69, 0x4a6a, 0x4a6b, + 0x4a6c, 0x4a6d, 0x4a6e, 0x4a6f, 0x4a70, 0x4a71, 0x4a72, 0x4a73, + 0x4a74, 0x4a75, 0x4a76, 0x4a77, 0x4a78, 0x4a79, 0x4a7a, 0x4a7b, + 0x4a7c, 0x4a7d, 0x4a7e, 0x4b21, 0x4b22, 0x4b23, 0x4b24, 0x4b25, + 0x4b26, 0x4b27, 0x4b28, 0x4b29, 0x4b2a, 0x4b2b, 0x4b2c, 0x4b2d, + 0x4b2e, 0x4b2f, 0x4b30, 0x4b31, 0x4b32, 0x4b33, 0x4b34, 0x4b35, + 0x4b36, 0x4b37, 0x4b38, 0x4b39, 0x4b3a, 0x4b3b, 0x4b3c, 0x4b3d, + 0x4b3e, 0x4b3f, 0x4b40, 0x4b41, 0x4b42, 0x4b43, 0x4b44, 0x4b45, + 0x4b46, 0x4b47, 0x4b48, 0x4b49, 0x4b4a, 0x4b4b, 0x4b4c, 0x4b4d, + 0x4b4e, 0x4b4f, 0x4b50, 0x4b51, 0x4b52, 0x4b53, 0x4b54, 0x4b55, + 0x4b56, 0x4b57, 0x4b58, 0x4b59, 0x4b5a, 0x4b5b, 0x4b5c, 0x4b5d, + 0x4b5e, 0x4b5f, 0x4b60, 0x4b61, 0x4b62, 0x4b63, 0x4b64, 0x4b65, + 0x4b66, 0x4b67, 0x4b68, 0x4b69, 0x4b6a, 0x4b6b, 0x4b6c, 0x4b6d, + 0x4b6e, 0x4b6f, 0x4b70, 0x4b71, 0x4b72, 0x4b73, 0x4b74, 0x4b75, + 0x4b76, 0x4b77, 0x4b78, 0x4b79, 0x4b7a, 0x4b7b, 0x4b7c, 0x4b7d, + 0x4b7e, 0x4c21, 0x4c22, 0x4c23, 0x4c24, 0x4c25, 0x4c26, 0x4c27, + 0x4c28, 0x4c29, 0x4c2a, 0x4c2b, 0x4c2c, 0x4c2d, 0x4c2e, 0x4c2f, + 0x4c30, 0x4c31, 0x4c32, 0x4c33, 0x4c34, 0x4c35, 0x4c36, 0x4c37, + 0x4c38, 0x4c39, 0x4c3a, 0x4c3b, 0x4c3c, 0x4c3d, 0x4c3e, 0x4c3f, + 0x4c40, 0x4c41, 0x4c42, 0x4c43, 0x4c44, 0x4c45, 0x4c46, 0x4c47, + 0x4c48, 0x4c49, 0x4c4a, 0x4c4b, 0x4c4c, 0x4c4d, 0x4c4e, 0x4c4f, + 0x4c50, 0x4c51, 0x4c52, 0x4c53, 0x4c54, 0x4c55, 0x4c56, 0x4c57, + 0x4c58, 0x4c59, 0x4c5a, 0x4c5b, 0x4c5c, 0x4c5d, 0x4c5e, 0x4c5f, + 0x4c60, 0x4c61, 0x4c62, 0x4c63, 0x4c64, 0x4c65, 0x4c66, 0x4c67, + 0x4c68, 0x4c69, 0x4c6a, 0x4c6b, 0x4c6c, 0x4c6d, 0x4c6e, 0x4c6f, + 0x4c70, 0x4c71, 0x4c72, 0x4c73, 0x4c74, 0x4c75, 0x4c76, 0x4c77, + 0x4c78, 0x4c79, 0x4c7a, 0x4c7b, 0x4c7c, 0x4c7d, 0x4c7e, 0x4d21, + 0x4d22, 0x4d23, 0x4d24, 0x4d25, 0x4d26, 0x4d27, 0x4d28, 0x4d29, + 0x4d2a, 0x4d2b, 0x4d2c, 0x4d2d, 0x4d2e, 0x4d2f, 0x4d30, 0x4d31, + 0x4d32, 0x4d33, 0x4d34, 0x4d35, 0x4d36, 0x4d37, 0x4d38, 0x4d39, + 0x4d3a, 0x4d3b, 0x4d3c, 0x4d3d, 0x4d3e, 0x4d3f, 0x4d40, 0x4d41, + 0x4d42, 0x4d43, 0x4d44, 0x4d45, 0x4d46, 0x4d47, 0x4d48, 0x4d49, + 0x4d4a, 0x4d4b, 0x4d4c, 0x4d4d, 0x4d4e, 0x4d4f, 0x4d50, 0x4d51, + 0x4d52, 0x4d53, 0x4d54, 0x4d55, 0x4d56, 0x4d57, 0x4d58, 0x4d59, + 0x4d5a, 0x4d5b, 0x4d5c, 0x4d5d, 0x4d5e, 0x4d5f, 0x4d60, 0x4d61, + 0x4d62, 0x4d63, 0x4d64, 0x4d65, 0x4d66, 0x4d67, 0x4d68, 0x4d69, + 0x4d6a, 0x4d6b, 0x4d6c, 0x4d6d, 0x4d6e, 0x4d6f, 0x4d70, 0x4d71, + 0x4d72, 0x4d73, 0x4d74, 0x4d75, 0x4d76, 0x4d77, 0x4d78, 0x4d79, + 0x4d7a, 0x4d7b, 0x4d7c, 0x4d7d, 0x4d7e, 0x4e21, 0x4e22, 0x4e24, + 0x4e25, 0x4e26, 0x4e27, 0x4e28, 0x4e29, 0x4e23, 0x4e2a, 0x4e2b, + 0x4e2c, 0x4e2d, 0x4e2e, 0x4e2f, 0x4e30, 0x4e31, 0x4e32, 0x4e33, + 0x4e34, 0x4e35, 0x4e36, 0x4e37, 0x4e38, 0x4e39, 0x4e3a, 0x4e3b, + 0x4e3c, 0x4e3d, 0x4e3e, 0x4e3f, 0x4e40, 0x4e41, 0x4e42, 0x4e43, + 0x4e44, 0x4e45, 0x4e46, 0x4e47, 0x4e48, 0x4e49, 0x4e4a, 0x4e4b, + 0x4e4c, 0x4e4d, 0x4e4e, 0x4e4f, 0x4e50, 0x4e51, 0x4e52, 0x4e53, + 0x4e54, 0x4e55, 0x4e56, 0x4e57, 0x4e58, 0x4e59, 0x4e5a, 0x4e5b, + 0x4e5c, 0x4e5d, 0x4e5e, 0x4e5f, 0x4e60, 0x4e61, 0x4e62, 0x4e63, + 0x4e64, 0x4e65, 0x4e66, 0x4e67, 0x4e68, 0x4e69, 0x4e6a, 0x4e6b, + 0x4e6c, 0x4e6d, 0x4e6e, 0x4e6f, 0x4e70, 0x4e71, 0x4e72, 0x4e73, + 0x4e74, 0x4e75, 0x4e76, 0x4e77, 0x4e78, 0x4e79, 0x4e7a, 0x4e7b, + 0x4e7c, 0x4e7d, 0x4e7e, 0x4f21, 0x4f22, 0x4f23, 0x4f24, 0x4f25, + 0x4f26, 0x4f27, 0x4f28, 0x4f29, 0x4f2a, 0x4f2b, 0x4f2c, 0x4f2d, + 0x4f2e, 0x4f2f, 0x4f30, 0x4f31, 0x4f32, 0x4f33, 0x4f34, 0x4f35, + 0x4f36, 0x4f37, 0x4f38, 0x4f39, 0x4f3a, 0x4f3b, 0x4f3c, 0x4f3d, + 0x4f3e, 0x4f3f, 0x4f40, 0x4f41, 0x4f42, 0x4f43, 0x4f44, 0x4f45, + 0x4f46, 0x4f47, 0x4f48, 0x4f49, 0x4f4a, 0x4f4b, 0x4f4c, 0x4f4d, + 0x4f4e, 0x4f4f, 0x4f50, 0x4f51, 0x4f52, 0x4f53, 0x4f54, 0x4f55, + 0x4f56, 0x4f57, 0x4f58, 0x4f59, 0x4f5a, 0x4f5b, 0x4f5c, 0x4f5d, + 0x4f5e, 0x4f5f, 0x4f60, 0x4f61, 0x4f62, 0x4f63, 0x4f64, 0x4f65, + 0x4f66, 0x4f67, 0x4f68, 0x4f69, 0x4f6a, 0x4f6b, 0x4f6c, 0x4f6d, + 0x4f6e, 0x4f6f, 0x4f70, 0x4f71, 0x4f72, 0x4f74, 0x4f75, 0x4f76, + 0x4f73, 0x4f77, 0x4f78, 0x4f79, 0x4f7a, 0x4f7b, 0x4f7c, 0x4f7d, + 0x4f7e, 0x5021, 0x5022, 0x5023, 0x5024, 0x5025, 0x5026, 0x5027, + 0x5028, 0x5029, 0x502a, 0x502b, 0x502c, 0x502e, 0x502f, 0x5030, + 0x5031, 0x502d, 0x5032, 0x5033, 0x5034, 0x5035, 0x5037, 0x5038, + 0x5039, 0x503a, 0x503b, 0x5036, 0x503c, 0x503d, 0x503e, 0x503f, + 0x5040, 0x5041, 0x5042, 0x5043, 0x5044, 0x5045, 0x5046, 0x5047, + 0x5048, 0x5049, 0x504a, 0x504b, 0x504c, 0x504d, 0x504e, 0x504f, + 0x5050, 0x5051, 0x5052, 0x5053, 0x5054, 0x5055, 0x5056, 0x5057, + 0x5058, 0x5059, 0x505a, 0x505b, 0x505c, 0x505d, 0x505e, 0x505f, + 0x5060, 0x5061, 0x5062, 0x5063, 0x5064, 0x5065, 0x5066, 0x5067, + 0x5068, 0x5069, 0x506a, 0x506b, 0x506c, 0x506d, 0x506e, 0x506f, + 0x5070, 0x5071, 0x5072, 0x5073, 0x5074, 0x5075, 0x5076, 0x5077, + 0x5078, 0x5079, 0x507a, 0x507b, 0x507c, 0x507d, 0x507e, 0x5121, + 0x5122, 0x5123, 0x5124, 0x5125, 0x5126, 0x5127, 0x5128, 0x5129, + 0x512a, 0x512b, 0x512c, 0x512d, 0x512e, 0x512f, 0x5130, 0x5131, + 0x5132, 0x5133, 0x5134, 0x5135, 0x5136, 0x5137, 0x5138, 0x5139, + 0x513a, 0x513b, 0x513c, 0x513d, 0x513e, 0x513f, 0x5140, 0x5141, + 0x5142, 0x5143, 0x5144, 0x5145, 0x5146, 0x5147, 0x5148, 0x5149, + 0x514a, 0x514b, 0x514c, 0x514d, 0x514e, 0x514f, 0x5150, 0x5151, + 0x5152, 0x5153, 0x5154, 0x5155, 0x5156, 0x5157, 0x5158, 0x5159, + 0x515a, 0x515b, 0x515c, 0x515d, 0x515e, 0x515f, 0x5160, 0x5161, + 0x5162, 0x5163, 0x5164, 0x5165, 0x5166, 0x5167, 0x5168, 0x5169, + 0x516a, 0x516b, 0x516c, 0x516d, 0x516e, 0x516f, 0x5170, 0x5171, + 0x5172, 0x5173, 0x5174, 0x5175, 0x5176, 0x5177, 0x5178, 0x5179, + 0x517a, 0x517b, 0x517c, 0x517d, 0x517e, 0x5221, 0x5222, 0x5223, + 0x5224, 0x5225, 0x5226, 0x5227, 0x5228, 0x5229, 0x522a, 0x522b, + 0x522c, 0x522d, 0x522e, 0x522f, 0x5230, 0x5231, 0x5232, 0x5233, + 0x5234, 0x5235, 0x5236, 0x5237, 0x5238, 0x5239, 0x523a, 0x523b, + 0x523c, 0x523d, 0x523e, 0x523f, 0x5240, 0x5241, 0x5242, 0x5243, + 0x5244, 0x5245, 0x5246, 0x5247, 0x5248, 0x5249, 0x524a, 0x524b, + 0x524c, 0x524d, 0x524e, 0x524f, 0x5250, 0x5251, 0x5252, 0x5253, + 0x5254, 0x5255, 0x5256, 0x5257, 0x5258, 0x5259, 0x525a, 0x525b, + 0x525c, 0x525d, 0x525e, 0x525f, 0x5260, 0x5261, 0x5262, 0x5263, + 0x5264, 0x5265, 0x5266, 0x5267, 0x5268, 0x5269, 0x526a, 0x526b, + 0x526c, 0x526d, 0x526e, 0x526f, 0x5270, 0x5271, 0x5272, 0x5273, + 0x5274, 0x5276, 0x5277, 0x5278, 0x5275, 0x5279, 0x527a, 0x527b, + 0x527c, 0x527d, 0x527e, 0x5321, 0x5322, 0x5323, 0x5324, 0x5325, + 0x5326, 0x5327, 0x5328, 0x5329, 0x532a, 0x532b, 0x532c, 0x532d, + 0x532e, 0x532f, 0x5330, 0x5331, 0x5332, 0x5333, 0x5334, 0x5335, + 0x5336, 0x5337, 0x5338, 0x5339, 0x533a, 0x533b, 0x533c, 0x533d, + 0x533e, 0x533f, 0x5340, 0x5341, 0x5342, 0x5343, 0x5344, 0x5345, + 0x5346, 0x5347, 0x5348, 0x5349, 0x534a, 0x534b, 0x534c, 0x534d, + 0x534e, 0x534f, 0x5350, 0x5351, 0x5352, 0x5353, 0x5354, 0x5355, + 0x5356, 0x5357, 0x5358, 0x5359, 0x535a, 0x535b, 0x535c, 0x535d, + 0x535e, 0x535f, 0x5360, 0x5361, 0x5362, 0x5363, 0x5364, 0x5365, + 0x5366, 0x5367, 0x5368, 0x5369, 0x536a, 0x536b, 0x536c, 0x536d, + 0x536e, 0x536f, 0x5370, 0x5371, 0x5372, 0x5373, 0x5374, 0x5375, + 0x5376, 0x5377, 0x5378, 0x5379, 0x537a, 0x537b, 0x537c, 0x537d, + 0x537e, 0x5421, 0x5422, 0x5423, 0x5424, 0x5425, 0x5426, 0x5427, + 0x5428, 0x5429, 0x542a, 0x542b, 0x542c, 0x542d, 0x542e, 0x542f, + 0x5430, 0x5431, 0x5432, 0x5434, 0x5435, 0x5436, 0x5437, 0x5438, + 0x5439, 0x543a, 0x543b, 0x543c, 0x543d, 0x543e, 0x5433, 0x543f, + 0x5440, 0x5441, 0x5442, 0x5443, 0x5444, 0x5445, 0x5446, 0x5447, + 0x5448, 0x5449, 0x544a, 0x544b, 0x544c, 0x544d, 0x544e, 0x544f, + 0x5450, 0x5451, 0x5452, 0x5453, 0x5454, 0x5455, 0x5456, 0x5457, + 0x5458, 0x5459, 0x545a, 0x545b, 0x545c, 0x545d, 0x545e, 0x545f, + 0x5460, 0x5461, 0x5462, 0x5463, 0x5464, 0x5465, 0x5466, 0x5467, + 0x5468, 0x5469, 0x546a, 0x546c, 0x546b, 0x546d, 0x546e, 0x546f, + 0x5470, 0x5471, 0x5472, 0x5473, 0x5474, 0x5475, 0x5476, 0x5477, + 0x5478, 0x5479, 0x547a, 0x547b, 0x547c, 0x547d, 0x547e, 0x5521, + 0x5522, 0x5523, 0x5524, 0x5525, 0x5526, 0x5527, 0x5528, 0x5529, + 0x552a, 0x552b, 0x552c, 0x552d, 0x552e, 0x552f, 0x5530, 0x5531, + 0x5532, 0x5533, 0x5534, 0x5535, 0x5536, 0x5537, 0x5538, 0x5539, + 0x553a, 0x553b, 0x553c, 0x553d, 0x553e, 0x553f, 0x5540, 0x5541, + 0x5542, 0x5543, 0x5544, 0x5545, 0x5546, 0x5547, 0x5548, 0x5549, + 0x554a, 0x554b, 0x554c, 0x554d, 0x554e, 0x554f, 0x5550, 0x5551, + 0x5552, 0x5553, 0x5554, 0x5555, 0x5556, 0x5557, 0x5558, 0x5559, + 0x555a, 0x555b, 0x555c, 0x555d, 0x555e, 0x555f, 0x5560, 0x5561, + 0x5562, 0x5563, 0x5564, 0x5565, 0x5566, 0x5567, 0x5568, 0x5569, + 0x556a, 0x556b, 0x556c, 0x556d, 0x556e, 0x556f, 0x5570, 0x5571, + 0x5572, 0x5573, 0x5574, 0x5575, 0x5576, 0x5577, 0x5578, 0x5579, + 0x557a, 0x557b, 0x557c, 0x557d, 0x557e, 0x5621, 0x5622, 0x5623, + 0x5624, 0x5625, 0x5626, 0x5627, 0x5628, 0x5629, 0x562a, 0x562b, + 0x562c, 0x562d, 0x562e, 0x562f, 0x5630, 0x5631, 0x5632, 0x5633, + 0x5634, 0x5635, 0x5636, 0x5637, 0x5638, 0x5639, 0x563a, 0x563b, + 0x563c, 0x563d, 0x563e, 0x563f, 0x5640, 0x5641, 0x5642, 0x5643, + 0x5644, 0x5645, 0x5647, 0x5648, 0x5649, 0x564a, 0x564b, 0x5646, + 0x564c, 0x564d, 0x564e, 0x564f, 0x5650, 0x5651, 0x5652, 0x5653, + 0x5654, 0x5656, 0x5657, 0x5658, 0x5655, 0x5659, 0x565a, 0x565b, + 0x565c, 0x565d, 0x565e, 0x565f, 0x5660, 0x5661, 0x5662, 0x5663, + 0x5664, 0x5665, 0x5666, 0x5667, 0x5668, 0x5669, 0x566a, 0x566b, + 0x566c, 0x566d, 0x566e, 0x566f, 0x5670, 0x5671, 0x5672, 0x5673, + 0x5674, 0x5675, 0x5676, 0x5677, 0x5678, 0x5679, 0x567a, 0x567b, + 0x567c, 0x567d, 0x567e, 0x5721, 0x5722, 0x5723, 0x5724, 0x5725, + 0x5726, 0x5727, 0x5728, 0x5729, 0x572a, 0x572b, 0x572c, 0x572d, + 0x572e, 0x572f, 0x5730, 0x5731, 0x5732, 0x5733, 0x5734, 0x5735, + 0x5736, 0x5737, 0x5738, 0x5739, 0x573a, 0x573b, 0x573c, 0x573d, + 0x573e, 0x573f, 0x5740, 0x5741, 0x5742, 0x5743, 0x5744, 0x5745, + 0x5746, 0x5747, 0x5748, 0x5749, 0x574a, 0x574b, 0x574c, 0x574d, + 0x574e, 0x574f, 0x5750, 0x5751, 0x5752, 0x5753, 0x5754, 0x5755, + 0x5756, 0x5757, 0x5758, 0x5759, 0x575a, 0x575b, 0x575c, 0x575d, + 0x575e, 0x575f, 0x5760, 0x5761, 0x5762, 0x5764, 0x5765, 0x5766, + 0x5767, 0x5768, 0x5769, 0x576a, 0x576b, 0x576c, 0x576d, 0x576e, + 0x576f, 0x5770, 0x5771, 0x5772, 0x5773, 0x5774, 0x5775, 0x5776, + 0x5777, 0x5778, 0x5779, 0x583e, 0x5763, 0x577a, 0x577b, 0x577c, + 0x577d, 0x577e, 0x5821, 0x5822, 0x5823, 0x5824, 0x5825, 0x5826, + 0x5827, 0x5828, 0x5829, 0x582a, 0x582b, 0x582c, 0x582d, 0x582e, + 0x582f, 0x5830, 0x5831, 0x5832, 0x5833, 0x584c, 0x5834, 0x5835, + 0x5836, 0x5837, 0x5838, 0x5839, 0x583a, 0x583b, 0x583c, 0x583d, + 0x583f, 0x5840, 0x5841, 0x5842, 0x5843, 0x5844, 0x5845, 0x5846, + 0x5847, 0x5848, 0x5849, 0x584a, 0x584b, 0x584d, 0x584e, 0x584f, + 0x5850, 0x5851, 0x5852, 0x5853, 0x5854, 0x5855, 0x5856, 0x5857, + 0x5858, 0x5859, 0x585a, 0x585b, 0x585c, 0x585d, 0x585e, 0x585f, + 0x5860, 0x5861, 0x5862, 0x5863, 0x5864, 0x5865, 0x5866, 0x5867, + 0x5868, 0x5869, 0x586a, 0x586b, 0x586c, 0x586d, 0x586e, 0x586f, + 0x5870, 0x5871, 0x5872, 0x5873, 0x5874, 0x5875, 0x5876, 0x5877, + 0x5878, 0x5879, 0x587a, 0x587b, 0x587c, 0x587d, 0x587e, 0x5921, + 0x5922, 0x5923, 0x5924, 0x5925, 0x5926, 0x5927, 0x5928, 0x592a, + 0x592b, 0x592c, 0x592d, 0x592e, 0x592f, 0x5930, 0x5931, 0x5932, + 0x5933, 0x5934, 0x5935, 0x5936, 0x5937, 0x5938, 0x5939, 0x593a, + 0x593b, 0x593c, 0x5929, 0x593d, 0x593e, 0x593f, 0x5940, 0x5941, + 0x5942, 0x5943, 0x5944, 0x5945, 0x5946, 0x5947, 0x5948, 0x5949, + 0x594a, 0x594b, 0x594c, 0x594d, 0x594e, 0x594f, 0x5950, 0x5951, + 0x5952, 0x5953, 0x5954, 0x5955, 0x5956, 0x5957, 0x5958, 0x5959, + 0x595a, 0x595b, 0x595c, 0x595d, 0x595e, 0x595f, 0x5960, 0x5961, + 0x5962, 0x5963, 0x5964, 0x5965, 0x5966, 0x5974, 0x5967, 0x5968, + 0x5969, 0x596a, 0x596b, 0x596c, 0x596d, 0x596e, 0x596f, 0x5970, + 0x5971, 0x5972, 0x5973, 0x5975, 0x5976, 0x5977, 0x5978, 0x5979, + 0x597a, 0x597b, 0x597c, 0x597d, 0x597e, 0x5a21, 0x5a22, 0x5a23, + 0x5a24, 0x5a25, 0x5a26, 0x5a27, 0x5a28, 0x5a29, 0x5a2a, 0x5a2b, + 0x5a2c, 0x5a2d, 0x5a2e, 0x5a2f, 0x5a30, 0x5a31, 0x5a32, 0x5a33, + 0x5a34, 0x5a35, 0x5a36, 0x3866, 0x5a37, 0x5a38, 0x5a39, 0x5a3a, + 0x5a3b, 0x5a3c, 0x5a3d, 0x5a3e, 0x5a3f, 0x5a40, 0x5a41, 0x5a42, + 0x5a43, 0x5a44, 0x5a45, 0x5a46, 0x5a47, 0x5a48, 0x5a49, 0x5a4a, + 0x5a4b, 0x5a6d, 0x5a4c, 0x5a4d, 0x5a4e, 0x5a4f, 0x5a50, 0x5a51, + 0x5a52, 0x5a53, 0x5a54, 0x5a55, 0x5a56, 0x5a57, 0x5a58, 0x5a59, + 0x5a5a, 0x5a5b, 0x5a5c, 0x5a5d, 0x5a5e, 0x5a5f, 0x5a60, 0x5a61, + 0x5a62, 0x5a63, 0x5a64, 0x5a65, 0x5a66, 0x5a67, 0x5a68, 0x5a69, + 0x5a6a, 0x5a6b, 0x5a6c, 0x5a6e, 0x5a6f, 0x5a70, 0x5a71, 0x5a72, + 0x5a73, 0x5a74, 0x5a75, 0x5a76, 0x5a77, 0x5a78, 0x5a79, 0x5a7a, + 0x5a7b, 0x5a7c, 0x5a7d, 0x5a7e, 0x5b21, 0x5b22, 0x5b23, 0x5b24, + 0x5b25, 0x5b26, 0x5b27, 0x5b28, 0x5b29, 0x5b2a, 0x5b2b, 0x5b2c, + 0x5b2d, 0x5b2e, 0x5b2f, 0x5b30, 0x5b31, 0x5b32, 0x5b33, 0x5b34, + 0x5b35, 0x5b36, 0x5b37, 0x5b38, 0x5b39, 0x5b3a, 0x5b3b, 0x5b3c, + 0x5b3d, 0x5b3e, 0x5b3f, 0x5b40, 0x5b41, 0x5b42, 0x5b43, 0x5b44, + 0x5b45, 0x5b46, 0x5b47, 0x5b48, 0x5b49, 0x5b4a, 0x5b4b, 0x5b4c, + 0x5b4d, 0x5b4e, 0x5b4f, 0x5b50, 0x5b51, 0x5b52, 0x5b53, 0x5b54, + 0x5b55, 0x5b56, 0x5b57, 0x5b58, 0x5b59, 0x5b5a, 0x5b5b, 0x5b5c, + 0x5b5d, 0x5b5e, 0x5b5f, 0x5b60, 0x5b61, 0x5b62, 0x5b63, 0x5b64, + 0x5b65, 0x5b66, 0x5b67, 0x5b68, 0x5b69, 0x5b6a, 0x5b6b, 0x5b6c, + 0x5b6d, 0x5b6e, 0x5b70, 0x5b71, 0x5b72, 0x5b73, 0x5b6f, 0x5b74, + 0x5b75, 0x5b76, 0x5b77, 0x5b78, 0x5b79, 0x5b7a, 0x5b7b, 0x5b7c, + 0x5b7d, 0x5b7e, 0x5c21, 0x5c22, 0x5c23, 0x5c24, 0x5c25, 0x5c26, + 0x5c27, 0x5c28, 0x5c29, 0x5c2a, 0x5c2b, 0x5c2c, 0x5c2d, 0x5c2e, + 0x5c2f, 0x5c30, 0x5c31, 0x5c32, 0x5c33, 0x5c34, 0x5c35, 0x5c36, + 0x5c37, 0x5c38, 0x5c39, 0x5c3a, 0x5c3b, 0x5c3c, 0x5c3d, 0x5c3e, + 0x5c3f, 0x5c40, 0x5c41, 0x5c42, 0x5c43, 0x5c44, 0x5c45, 0x5c46, + 0x5c47, 0x5c48, 0x5c49, 0x5c4a, 0x5c4b, 0x5c4c, 0x5c4d, 0x5c4e, + 0x5c4f, 0x5c50, 0x5c51, 0x5c52, 0x5c53, 0x5c54, 0x5c55, 0x5c56, + 0x5c57, 0x5c58, 0x5c59, 0x5c5a, 0x5c5b, 0x5c5c, 0x5c5d, 0x5c5e, + 0x5c5f, 0x5c60, 0x5c61, 0x5c62, 0x5c63, 0x5c64, 0x5c65, 0x5c66, + 0x5c67, 0x5c68, 0x5c69, 0x5c6a, 0x5c6b, 0x5c6c, 0x5c6d, 0x5c6e, + 0x5c6f, 0x5c70, 0x5c71, 0x5c72, 0x5c73, 0x5c74, 0x5c75, 0x5c76, + 0x5c77, 0x5c78, 0x5c79, 0x5c7a, 0x5c7b, 0x5c7c, 0x5c7d, 0x5c7e, + 0x5d21, 0x5d22, 0x5d23, 0x5d24, 0x5d25, 0x5d26, 0x5d27, 0x5d28, + 0x5d29, 0x5d2a, 0x5d2b, 0x5d2c, 0x5d2d, 0x5d2e, 0x5d2f, 0x5d30, + 0x5d31, 0x5d32, 0x5d33, 0x5d34, 0x5d35, 0x5d36, 0x5d37, 0x5d38, + 0x5d39, 0x5d3a, 0x5d3b, 0x5d3c, 0x5d3d, 0x5d3e, 0x5d3f, 0x5d40, + 0x5d41, 0x5d42, 0x5d43, 0x5d44, 0x5d45, 0x5d46, 0x5d47, 0x5d48, + 0x5d49, 0x5d4a, 0x5d4b, 0x5d4c, 0x5d4d, 0x5d4e, 0x5d4f, 0x5d50, + 0x5d51, 0x5d52, 0x5d53, 0x5d54, 0x5d55, 0x5d56, 0x5d57, 0x5d58, + 0x5d59, 0x5d5a, 0x5d5b, 0x5d5c, 0x5d5d, 0x5d5e, 0x5d5f, 0x5d60, + 0x5d61, 0x5d62, 0x5d63, 0x5d64, 0x5d65, 0x5d66, 0x5d67, 0x5d68, + 0x5d69, 0x5d6a, 0x5d6b, 0x5d6c, 0x5d6d, 0x5d6e, 0x5d6f, 0x5d70, + 0x5d71, 0x5d72, 0x5d73, 0x5d74, 0x5d75, 0x5d76, 0x5d77, 0x5d78, + 0x5d79, 0x5d7a, 0x5d7b, 0x5d7c, 0x5d7d, 0x5d7e, 0x5e21, 0x5e22, + 0x5e23, 0x5e24, 0x5e25, 0x5e26, 0x5e27, 0x5e28, 0x5e29, 0x5e2a, + 0x5e2b, 0x5e2c, 0x5e2d, 0x5e2e, 0x5e2f, 0x5e30, 0x5e31, 0x5e32, + 0x5e33, 0x5e34, 0x5e35, 0x5e36, 0x5e37, 0x5e38, 0x5e39, 0x5e3f, + 0x5e3a, 0x5e3b, 0x5e3c, 0x5e3d, 0x5e3e, 0x5e40, 0x5e41, 0x5e42, + 0x5e43, 0x5e44, 0x5e45, 0x5e46, 0x5e47, 0x5e48, 0x5e49, 0x5e4e, + 0x5e4a, 0x5e4b, 0x5e4c, 0x5e4d, 0x5e4f, 0x5e50, 0x5e51, 0x5e52, + 0x5e53, 0x5e54, 0x5e55, 0x5e56, 0x5e57, 0x5e58, 0x5e59, 0x5e5a, + 0x5e5b, 0x5e5c, 0x5e5d, 0x5e5e, 0x5e5f, 0x5e60, 0x5e61, 0x5e62, + 0x5e63, 0x5e64, 0x5e65, 0x5e66, 0x5e67, 0x5e68, 0x5e69, 0x5e6a, + 0x5e6b, 0x5e6c, 0x5e6d, 0x5e6e, 0x5e6f, 0x5e72, 0x5e70, 0x5e71, + 0x5e73, 0x5e74, 0x5e75, 0x5e76, 0x5e77, 0x5e78, 0x5e79, 0x5e7a, + 0x5e7b, 0x5e7c, 0x5e7d, 0x5e7e, 0x5f21, 0x5f22, 0x5f23, 0x5f24, + 0x5f25, 0x5f26, 0x5f27, 0x5f28, 0x5f29, 0x5f2a, 0x5f2b, 0x5f2c, + 0x5f2d, 0x5f2e, 0x5f2f, 0x5f30, 0x5f32, 0x5f31, 0x5f33, 0x5f34, + 0x5f35, 0x5f36, 0x5f37, 0x5f38, 0x5f39, 0x5f3a, 0x5f3b, 0x5f3c, + 0x5f3d, 0x5f3e, 0x5f3f, 0x5f40, 0x5f41, 0x5f42, 0x5f43, 0x5f44, + 0x5f45, 0x5f46, 0x5f47, 0x5f48, 0x5f49, 0x5f4a, 0x5f4b, 0x5f4c, + 0x5f4d, 0x5f4e, 0x5f4f, 0x5f50, 0x5f51, 0x5f52, 0x5f53, 0x5f54, + 0x5f55, 0x5f56, 0x5f57, 0x5f58, 0x5f59, 0x5f5a, 0x5f5b, 0x5f5c, + 0x5f5d, 0x5f6f, 0x5f5e, 0x5f5f, 0x5f60, 0x5f61, 0x5f62, 0x5f63, + 0x5f64, 0x5f65, 0x5f66, 0x5f67, 0x5f68, 0x5f69, 0x5f6a, 0x5f6b, + 0x5f6c, 0x5f6d, 0x5f6e, 0x5f70, 0x5f71, 0x5f72, 0x5f73, 0x5f74, + 0x5f75, 0x5f76, 0x5f77, 0x5f78, 0x5f79, 0x5f7a, 0x5f7b, 0x5f7c, + 0x5f7d, 0x5f7e, 0x6021, 0x6022, 0x6023, 0x6024, 0x6025, 0x6026, + 0x6027, 0x6028, 0x6029, 0x602a, 0x602b, 0x602c, 0x602d, 0x602e, + 0x602f, 0x6030, 0x6031, 0x6032, 0x6033, 0x6034, 0x6035, 0x6036, + 0x6037, 0x6038, 0x6039, 0x603a, 0x603b, 0x603c, 0x603d, 0x603e, + 0x603f, 0x6040, 0x6041, 0x6042, 0x6043, 0x6044, 0x6045, 0x6046, + 0x6047, 0x6048, 0x6049, 0x604a, 0x604b, 0x604c, 0x604d, 0x604e, + 0x604f, 0x6050, 0x6051, 0x6052, 0x6053, 0x6054, 0x6055, 0x6056, + 0x6057, 0x6058, 0x6059, 0x605a, 0x605b, 0x605c, 0x605d, 0x6064, + 0x605e, 0x605f, 0x6060, 0x6061, 0x6062, 0x6063, 0x6065, 0x6066, + 0x6067, 0x6068, 0x6069, 0x606a, 0x606b, 0x606c, 0x606d, 0x606e, + 0x606f, 0x6070, 0x6071, 0x6072, 0x6073, 0x6074, 0x6075, 0x6076, + 0x6077, 0x6078, 0x6079, 0x607a, 0x607b, 0x607c, 0x607d, 0x607e, + 0x6121, 0x6122, 0x6123, 0x6124, 0x6125, 0x6126, 0x6127, 0x6128, + 0x6129, 0x612a, 0x612b, 0x612c, 0x612d, 0x612e, 0x612f, 0x6130, + 0x6131, 0x6132, 0x6133, 0x6134, 0x6135, 0x6136, 0x6137, 0x6138, + 0x6139, 0x613a, 0x613b, 0x613c, 0x613d, 0x613e, 0x613f, 0x6140, + 0x6141, 0x6142, 0x6143, 0x6144, 0x6145, 0x6146, 0x6147, 0x6148, + 0x6149, 0x614a, 0x614b, 0x614c, 0x614d, 0x614e, 0x614f, 0x6150, + 0x6151, 0x6152, 0x6154, 0x6155, 0x6156, 0x6153, 0x6157, 0x6158, + 0x6159, 0x615a, 0x615b, 0x615c, 0x615d, 0x615e, 0x615f, 0x6160, + 0x6161, 0x6162, 0x6163, 0x6164, 0x6165, 0x6166, 0x6167, 0x6168, + 0x6169, 0x616a, 0x616b, 0x616c, 0x616d, 0x616e, 0x616f, 0x6170, + 0x6171, 0x6172, 0x6173, 0x6174, 0x6175, 0x6176, 0x6177, 0x6178, + 0x6179, 0x617a, 0x617b, 0x617d, 0x617e, 0x6221, 0x6222, 0x6223, + 0x6224, 0x617c, 0x622d, 0x6225, 0x6226, 0x6227, 0x6228, 0x6229, + 0x622a, 0x622b, 0x622c, 0x622f, 0x6230, 0x6231, 0x6232, 0x622e, + 0x6233, 0x6234, 0x6235, 0x6236, 0x6237, 0x6238, 0x6239, 0x623a, + 0x623b, 0x623c, 0x623d, 0x623e, 0x623f, 0x6240, 0x6241, 0x6242, + 0x6243, 0x6245, 0x6246, 0x6244, 0x6247, 0x6248, 0x6249, 0x624a, + 0x624b, 0x624c, 0x624d, 0x624e, 0x624f, 0x6250, 0x6251, 0x6252, + 0x6253, 0x6254, 0x6255, 0x6256, 0x6257, 0x6258, 0x6259, 0x625a, + 0x625b, 0x625c, 0x625d, 0x625e, 0x625f, 0x6260, 0x6261, 0x6262, + 0x6263, 0x6264, 0x6265, 0x6266, 0x6267, 0x6268, 0x6269, 0x626a, + 0x626b, 0x626c, 0x626d, 0x626e, 0x626f, 0x6270, 0x6271, 0x6272, + 0x6273, 0x6274, 0x6275, 0x6276, 0x6277, 0x6278, 0x6279, 0x627a, + 0x627b, 0x627c, 0x627d, 0x627e, 0x6321, 0x6322, 0x6323, 0x6324, + 0x6325, 0x6326, 0x6327, 0x6328, 0x6329, 0x632a, 0x632b, 0x632c, + 0x632d, 0x632e, 0x632f, 0x6330, 0x6331, 0x6332, 0x6333, 0x6334, + 0x6335, 0x6336, 0x6337, 0x6338, 0x6339, 0x633a, 0x633b, 0x633c, + 0x633d, 0x633e, 0x633f, 0x6340, 0x6341, 0x6342, 0x6343, 0x6344, + 0x6345, 0x6346, 0x6347, 0x6348, 0x6349, 0x634a, 0x634b, 0x634c, + 0x634d, 0x634e, 0x634f, 0x6350, 0x6351, 0x6352, 0x6353, 0x6354, + 0x6355, 0x6356, 0x6357, 0x6358, 0x6359, 0x635a, 0x635b, 0x635c, + 0x635d, 0x635e, 0x635f, 0x6360, 0x6361, 0x6362, 0x6363, 0x6364, + 0x6365, 0x6366, 0x6367, 0x6368, 0x6369, 0x636a, 0x636b, 0x636c, + 0x636d, 0x636e, 0x636f, 0x6370, 0x6371, 0x6372, 0x6373, 0x6374, + 0x6375, 0x6376, 0x6377, 0x6378, 0x6379, 0x637a, 0x637b, 0x637c, + 0x637d, 0x637e, 0x6421, 0x6422, 0x6423, 0x6424, 0x6425, 0x6426, + 0x6427, 0x6428, 0x6429, 0x642a, 0x642b, 0x642c, 0x642d, 0x642e, + 0x642f, 0x6430, 0x6431, 0x6432, 0x6433, 0x6434, 0x6435, 0x6436, + 0x6437, 0x6438, 0x6439, 0x643a, 0x643b, 0x643c, 0x643d, 0x643e, + 0x643f, 0x6440, 0x6441, 0x6442, 0x6443, 0x6444, 0x6445, 0x6446, + 0x6447, 0x6448, 0x6449, 0x644a, 0x644b, 0x644c, 0x644d, 0x644e, + 0x644f, 0x6450, 0x6451, 0x6452, 0x6453, 0x6454, 0x6455, 0x6456, + 0x6457, 0x6458, 0x6459, 0x645a, 0x645b, 0x645c, 0x645d, 0x645e, + 0x645f, 0x6460, 0x6461, 0x6462, 0x6463, 0x6464, 0x6465, 0x6466, + 0x6467, 0x6468, 0x6469, 0x646a, 0x646b, 0x646c, 0x646d, 0x646e, + 0x646f, 0x6470, 0x6471, 0x6472, 0x6473, 0x6474, 0x6475, 0x6476, + 0x6477, 0x6478, 0x6479, 0x647a, 0x647b, 0x647c, 0x647d, 0x647e, + 0x6521, 0x6522, 0x6523, 0x6524, 0x6525, 0x6526, 0x6527, 0x6528, + 0x6529, 0x652a, 0x652b, 0x652c, 0x652d, 0x652e, 0x652f, 0x6530, + 0x6531, 0x6532, 0x6533, 0x6534, 0x6535, 0x653b, 0x6536, 0x6537, + 0x6538, 0x6539, 0x653a, 0x653c, 0x653d, 0x653e, 0x653f, 0x6540, + 0x6541, 0x6542, 0x6543, 0x6544, 0x6545, 0x6546, 0x6547, 0x6548, + 0x6549, 0x654a, 0x654b, 0x654c, 0x654d, 0x654f, 0x6550, 0x654e, + 0x6551, 0x6552, 0x6553, 0x6554, 0x6555, 0x6556, 0x6557, 0x6558, + 0x6559, 0x655a, 0x655b, 0x655c, 0x655d, 0x655e, 0x655f, 0x6560, + 0x6561, 0x6562, 0x6563, 0x6564, 0x6565, 0x6566, 0x6568, 0x6567, + 0x6569, 0x656a, 0x656b, 0x656c, 0x656d, 0x656e, 0x656f, 0x6570, + 0x6571, 0x6572, 0x6573, 0x6574, 0x6575, 0x6576, 0x6577, 0x6578, + 0x6579, 0x657a, 0x657c, 0x657b, 0x657d, 0x657e, 0x6621, 0x6622, + 0x6623, 0x6624, 0x6625, 0x6626, 0x6627, 0x6628, 0x6629, 0x662a, + 0x662b, 0x662c, 0x662d, 0x662e, 0x662f, 0x6630, 0x6631, 0x6632, + 0x6633, 0x6634, 0x6635, 0x6636, 0x6637, 0x6638, 0x6639, 0x663a, + 0x663b, 0x663c, 0x663d, 0x663e, 0x663f, 0x6640, 0x6641, 0x6642, + 0x6643, 0x6644, 0x6645, 0x6646, 0x6647, 0x6648, 0x6649, 0x664a, + 0x664b, 0x664c, 0x664d, 0x664e, 0x664f, 0x6650, 0x6651, 0x6652, + 0x6653, 0x6654, 0x6655, 0x6656, 0x6657, 0x6658, 0x6659, 0x665a, + 0x665b, 0x665c, 0x665d, 0x665e, 0x665f, 0x6660, 0x6661, 0x6662, + 0x6663, 0x6664, 0x6665, 0x6666, 0x6667, 0x6668, 0x6669, 0x666a, + 0x666b, 0x666c, 0x666d, 0x666e, 0x666f, 0x6670, 0x6671, 0x6672, + 0x6673, 0x6675, 0x6676, 0x6677, 0x6678, 0x6679, 0x667a, 0x667b, + 0x667c, 0x667d, 0x667e, 0x6721, 0x6722, 0x6723, 0x6724, 0x6725, + 0x6726, 0x6727, 0x6728, 0x6729, 0x672a, 0x672b, 0x672c, 0x672d, + 0x672e, 0x672f, 0x6730, 0x6731, 0x6732, 0x6733, 0x6734, 0x6735, + 0x6736, 0x6737, 0x6738, 0x6739, 0x673a, 0x673b, 0x673c, 0x673d, + 0x673e, 0x673f, 0x6740, 0x6741, 0x6742, 0x6743, 0x6744, 0x6745, + 0x6746, 0x6747, 0x6748, 0x6749, 0x674a, 0x674b, 0x674c, 0x674d, + 0x674e, 0x674f, 0x6750, 0x6751, 0x6752, 0x6753, 0x6754, 0x6755, + 0x6756, 0x6757, 0x6758, 0x6759, 0x675a, 0x675b, 0x675c, 0x675d, + 0x675e, 0x675f, 0x6760, 0x6761, 0x6762, 0x6763, 0x6764, 0x6765, + 0x6766, 0x676a, 0x6767, 0x6768, 0x6769, 0x676b, 0x676c, 0x676d, + 0x676e, 0x676f, 0x6770, 0x6771, 0x6772, 0x6773, 0x6774, 0x6776, + 0x6777, 0x6778, 0x6779, 0x6775, 0x677a, 0x677b, 0x677c, 0x677d, + 0x6828, 0x677e, 0x6821, 0x6822, 0x6823, 0x6824, 0x6825, 0x6826, + 0x6827, 0x6829, 0x682a, 0x682b, 0x682c, 0x682d, 0x682e, 0x682f, + 0x6830, 0x6831, 0x6832, 0x6833, 0x6834, 0x6835, 0x6836, 0x6837, + 0x6838, 0x6839, 0x683a, 0x683b, 0x683c, 0x683d, 0x683e, 0x683f, + 0x6840, 0x6841, 0x6842, 0x6843, 0x6844, 0x6845, 0x6846, 0x6847, + 0x6848, 0x6849, 0x684a, 0x684b, 0x684c, 0x684d, 0x684e, 0x684f, + 0x6850, 0x6851, 0x6852, 0x6853, 0x6854, 0x6855, 0x6856, 0x6857, + 0x6858, 0x6859, 0x685a, 0x685b, 0x685c, 0x685d, 0x685e, 0x685f, + 0x6860, 0x6861, 0x6862, 0x6863, 0x6864, 0x6865, 0x6866, 0x6867, + 0x6868, 0x6869, 0x686a, 0x686b, 0x686c, 0x686d, 0x686e, 0x686f, + 0x6870, 0x6871, 0x6872, 0x6873, 0x6874, 0x6875, 0x6876, 0x6877, + 0x6878, 0x6879, 0x687a, 0x687b, 0x687c, 0x687d, 0x687e, 0x6921, + 0x6922, 0x6923, 0x6924, 0x6925, 0x6926, 0x6927, 0x6928, 0x6929, + 0x692a, 0x692b, 0x692c, 0x692d, 0x692e, 0x692f, 0x6930, 0x6931, + 0x6932, 0x6933, 0x6934, 0x6935, 0x6936, 0x6937, 0x6938, 0x6939, + 0x693a, 0x693b, 0x693c, 0x693d, 0x693e, 0x693f, 0x6940, 0x6941, + 0x6942, 0x6943, 0x6944, 0x6945, 0x6946, 0x6947, 0x6948, 0x6949, + 0x694a, 0x694c, 0x694d, 0x694b, 0x694e, 0x694f, 0x6950, 0x6951, + 0x6952, 0x6953, 0x6954, 0x6955, 0x6956, 0x6957, 0x6958, 0x6959, + 0x695a, 0x695b, 0x695c, 0x695d, 0x695e, 0x695f, 0x6960, 0x6961, + 0x6962, 0x6963, 0x6964, 0x6965, 0x6966, 0x6967, 0x6968, 0x6969, + 0x696a, 0x696b, 0x696c, 0x696d, 0x696e, 0x696f, 0x6970, 0x6971, + 0x6972, 0x6973, 0x6974, 0x6975, 0x6976, 0x6977, 0x6978, 0x6979, + 0x697a, 0x697b, 0x697c, 0x697d, 0x697e, 0x6a21, 0x6a22, 0x6a23, + 0x6a24, 0x6a25, 0x6a26, 0x6a27, 0x6a28, 0x6a29, 0x6a2a, 0x6a2b, + 0x6a2c, 0x6a2d, 0x6a2e, 0x6a2f, 0x6a30, 0x6a31, 0x6a32, 0x6a33, + 0x6a34, 0x6a35, 0x6a36, 0x6a37, 0x6a38, 0x6a39, 0x6a3a, 0x6a3b, + 0x6a3c, 0x6a3d, 0x6a3e, 0x6a3f, 0x6a40, 0x6a41, 0x6a42, 0x6a43, + 0x6a44, 0x6a45, 0x6a46, 0x6a47, 0x6a48, 0x6a49, 0x6a4a, 0x6a4b, + 0x6a4c, 0x6a4d, 0x6a4e, 0x6a4f, 0x6a50, 0x6a51, 0x6a52, 0x6a53, + 0x6a54, 0x6a55, 0x6a56, 0x6a57, 0x6a58, 0x6a59, 0x6a5a, 0x6a5b, + 0x6a5c, 0x6a5d, 0x6a5e, 0x6a5f, 0x6a60, 0x6a61, 0x6a62, 0x6a63, + 0x6a64, 0x6a65, 0x6a66, 0x6a67, 0x6a68, 0x6a69, 0x6a6a, 0x6a6b, + 0x6a6c, 0x6a6d, 0x6a6e, 0x6a6f, 0x6a70, 0x6a71, 0x6a72, 0x6a73, + 0x6a74, 0x6a75, 0x6a76, 0x6a77, 0x6a78, 0x6a79, 0x6a7a, 0x6a7b, + 0x6a7c, 0x6a7d, 0x6a7e, 0x6b21, 0x6b22, 0x6b23, 0x6b24, 0x6b25, + 0x6b26, 0x6b27, 0x6b28, 0x6b29, 0x6b2a, 0x6b2b, 0x6b2c, 0x6b2d, + 0x6b2e, 0x6b2f, 0x6b30, 0x6b31, 0x6b32, 0x6b33, 0x6b34, 0x6b35, + 0x6b36, 0x6b37, 0x6b38, 0x6b39, 0x6b3a, 0x6b3b, 0x6b3c, 0x6b3d, + 0x6b3e, 0x6b3f, 0x6b40, 0x6b41, 0x6b42, 0x6b43, 0x6b44, 0x6b45, + 0x6b46, 0x6b47, 0x6b48, 0x6b49, 0x6b50, 0x6b4a, 0x6b4b, 0x6b4c, + 0x6b4d, 0x6b52, 0x6b4e, 0x6b4f, 0x6b51, 0x6b53, 0x6b54, 0x6b55, + 0x6b56, 0x6b57, 0x6b58, 0x6b59, 0x6b5a, 0x6b5b, 0x6b5c, 0x6b5e, + 0x6b5d, 0x6b5f, 0x6b60, 0x6b61, 0x6b62, 0x6b63, 0x6b64, 0x6b65, + 0x6b66, 0x6b67, 0x6b68, 0x6b69, 0x6b6a, 0x6b6b, 0x6b6d, 0x6b6e, + 0x6b6f, 0x6b6c, 0x6b70, 0x6b71, 0x6b72, 0x6b73, 0x6b74, 0x6b76, + 0x6b75, 0x6b77, 0x6b78, 0x6b79, 0x6b7a, 0x6b7b, 0x6b7c, 0x6b7d, + 0x6b7e, 0x6c21, 0x6c22, 0x6c23, 0x6c24, 0x6c25, 0x6c26, 0x6c27, + 0x6c28, 0x6c29, 0x6c2a, 0x6c2b, 0x6c2c, 0x6c2d, 0x6c2e, 0x6c2f, + 0x6c30, 0x6c31, 0x6c32, 0x6c33, 0x6c34, 0x6c35, 0x6c36, 0x6c37, + 0x6c38, 0x6c39, 0x6c3a, 0x6c3b, 0x6c3c, 0x6c3d, 0x6c3e, 0x6c3f, + 0x6c40, 0x6c41, 0x6c42, 0x6c43, 0x6c44, 0x6c45, 0x6c46, 0x6c47, + 0x6c48, 0x6c49, 0x6c4a, 0x6c4b, 0x6c4c, 0x6c4e, 0x6c4f, 0x6c4d, + 0x6c50, 0x6c51, 0x6c52, 0x6c53, 0x6c54, 0x6c55, 0x6c56, 0x6c57, + 0x6c58, 0x6c59, 0x6c5a, 0x6c5b, 0x6c5c, 0x6c5d, 0x6c5e, 0x6c5f, + 0x6c60, 0x6c61, 0x6c62, 0x6c63, 0x6c64, 0x6c65, 0x6c66, 0x6c67, + 0x6c68, 0x6c69, 0x6c6a, 0x6c6b, 0x6c6c, 0x6c6d, 0x6c6e, 0x6c6f, + 0x6c70, 0x6c71, 0x6c72, 0x6c73, 0x6c74, 0x6c75, 0x6c76, 0x6c77, + 0x6c78, 0x6c79, 0x6c7a, 0x6c7b, 0x6c7c, 0x6c7d, 0x6c7e, 0x6d21, + 0x6d22, 0x6d23, 0x6d24, 0x6d25, 0x6d26, 0x6d27, 0x6d28, 0x6d29, + 0x6d2a, 0x6d2b, 0x6d2c, 0x6d2d, 0x6d2e, 0x6d2f, 0x6d30, 0x6d31, + 0x6d32, 0x6d33, 0x6d34, 0x6d35, 0x6d36, 0x6d37, 0x6d38, 0x6d39, + 0x6d3a, 0x6d3b, 0x6d3c, 0x6d3d, 0x6d3e, 0x6d3f, 0x6d40, 0x6d41, + 0x6d42, 0x6d43, 0x6d44, 0x6d45, 0x6d46, 0x6d47, 0x6d48, 0x6d49, + 0x6d4a, 0x6d4b, 0x6d4c, 0x6d4d, 0x6d4e, 0x6d4f, 0x6d50, 0x6d51, + 0x6d52, 0x6d53, 0x6d54, 0x6d55, 0x6d56, 0x6d57, 0x6d58, 0x6d59, + 0x6d5a, 0x6d5b, 0x6d5c, 0x6d5d, 0x6d5e, 0x6d5f, 0x6d60, 0x6d61, + 0x6d62, 0x6d63, 0x2237, +}; + +static const Summary16 jisx0212_uni2indx_page00[70] = { + /* 0x0000 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0xc652 }, { 7, 0x8500 }, + { 10, 0xffff }, { 26, 0xff7e }, { 40, 0xffff }, { 56, 0xff7f }, + /* 0x0100 */ + { 71, 0xffff }, { 87, 0xffcf }, { 101, 0xcff7 }, { 114, 0xffff }, + { 130, 0x3fff }, { 144, 0xffff }, { 160, 0xffff }, { 176, 0x7fff }, + { 191, 0x0000 }, { 191, 0x0000 }, { 191, 0x0000 }, { 191, 0x0000 }, + { 191, 0xe000 }, { 194, 0x1fff }, { 207, 0x0000 }, { 207, 0x0020 }, + /* 0x0200 */ + { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, + { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, + { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, { 208, 0x0000 }, + { 208, 0x0080 }, { 209, 0x2f00 }, { 214, 0x0000 }, { 214, 0x0000 }, + /* 0x0300 */ + { 214, 0x0000 }, { 214, 0x0000 }, { 214, 0x0000 }, { 214, 0x0000 }, + { 214, 0x0000 }, { 214, 0x0000 }, { 214, 0x0000 }, { 214, 0x0000 }, + { 214, 0xd770 }, { 223, 0x0001 }, { 224, 0xfc00 }, { 230, 0x0001 }, + { 231, 0x7c04 }, { 237, 0x0000 }, { 237, 0x0000 }, { 237, 0x0000 }, + /* 0x0400 */ + { 237, 0xdffc }, { 250, 0x0000 }, { 250, 0x0000 }, { 250, 0x0000 }, + { 250, 0x0000 }, { 250, 0xdffc }, +}; +static const Summary16 jisx0212_uni2indx_page21[3] = { + /* 0x2100 */ + { 263, 0x0000 }, { 263, 0x0040 }, { 264, 0x0004 }, +}; +static const Summary16 jisx0212_uni2indx_page4e[1307] = { + /* 0x4e00 */ + { 265, 0x1034 }, { 269, 0x8004 }, { 271, 0xc918 }, { 277, 0x0021 }, + { 279, 0x0093 }, { 283, 0x1402 }, { 286, 0x0308 }, { 289, 0x8230 }, + { 293, 0x2000 }, { 294, 0x20c0 }, { 297, 0x8000 }, { 298, 0x0200 }, + { 299, 0x0008 }, { 300, 0x0c01 }, { 303, 0x8107 }, { 308, 0xe02a }, + /* 0x4f00 */ + { 314, 0x190d }, { 320, 0x02e4 }, { 325, 0x4000 }, { 326, 0x4aaa }, + { 333, 0x1b05 }, { 339, 0x8154 }, { 344, 0x5409 }, { 349, 0x6782 }, + { 356, 0x5636 }, { 364, 0xc69d }, { 373, 0x0000 }, { 373, 0x7a84 }, + { 380, 0xbb63 }, { 390, 0x1004 }, { 392, 0x0005 }, { 394, 0xb005 }, + /* 0x5000 */ + { 399, 0x5493 }, { 406, 0x7989 }, { 414, 0x4084 }, { 417, 0x082d }, + { 422, 0x5467 }, { 430, 0x828e }, { 436, 0x24cd }, { 443, 0x0003 }, + { 445, 0xc45a }, { 452, 0xd85d }, { 461, 0x8407 }, { 466, 0x2601 }, + { 470, 0x5099 }, { 476, 0xb119 }, { 483, 0x8354 }, { 489, 0x4446 }, + /* 0x5100 */ + { 494, 0x79c8 }, { 502, 0x7a81 }, { 509, 0xb188 }, { 515, 0x033a }, + { 521, 0x8404 }, { 524, 0x81a8 }, { 529, 0x0050 }, { 531, 0x4000 }, + { 532, 0x4818 }, { 536, 0x2100 }, { 538, 0x200a }, { 541, 0xd500 }, + { 546, 0x8104 }, { 549, 0x412e }, { 555, 0x4024 }, { 558, 0x009c }, + /* 0x5200 */ + { 562, 0x0026 }, { 565, 0x016c }, { 570, 0x0104 }, { 572, 0x1026 }, + { 576, 0x0220 }, { 578, 0x95a0 }, { 584, 0x4043 }, { 588, 0x0380 }, + { 591, 0x1425 }, { 596, 0x15e8 }, { 603, 0x80f0 }, { 608, 0x2dc1 }, + { 615, 0x9151 }, { 621, 0x1852 }, { 626, 0x1722 }, { 632, 0x00d3 }, + /* 0x5300 */ + { 637, 0x1c09 }, { 642, 0xd90a }, { 649, 0x3ba0 }, { 656, 0x7025 }, + { 662, 0x1804 }, { 665, 0x0a00 }, { 667, 0x302a }, { 672, 0x4204 }, + { 675, 0x4188 }, { 679, 0x2218 }, { 683, 0x8c12 }, { 688, 0x25b4 }, + { 695, 0x8021 }, { 698, 0x642c }, { 704, 0x00c1 }, { 707, 0x0020 }, + /* 0x5400 */ + { 708, 0x0004 }, { 709, 0x0408 }, { 711, 0x8582 }, { 716, 0x0032 }, + { 719, 0xa098 }, { 724, 0x4000 }, { 725, 0x6ad4 }, { 733, 0x8010 }, + { 735, 0x232a }, { 741, 0x9062 }, { 746, 0x66c2 }, { 753, 0x8e82 }, + { 759, 0x6440 }, { 763, 0x0000 }, { 763, 0x9401 }, { 767, 0xd040 }, + /* 0x5500 */ + { 771, 0x7323 }, { 779, 0x0020 }, { 780, 0x0c00 }, { 782, 0x3864 }, + { 788, 0x2682 }, { 793, 0x4d03 }, { 799, 0x0053 }, { 803, 0x8000 }, + { 804, 0xc146 }, { 810, 0x009e }, { 815, 0x2018 }, { 818, 0x8004 }, + { 820, 0x5a4a }, { 827, 0x498e }, { 834, 0x0204 }, { 836, 0x8040 }, + /* 0x5600 */ + { 838, 0xe520 }, { 844, 0x0207 }, { 848, 0x1000 }, { 849, 0xbaa9 }, + { 858, 0xaa5b }, { 867, 0x4010 }, { 869, 0xa24f }, { 877, 0x0026 }, + { 880, 0x1930 }, { 885, 0xe620 }, { 891, 0x3bc0 }, { 898, 0x408a }, + { 902, 0xbe20 }, { 909, 0xb201 }, { 914, 0x29f2 }, { 922, 0x00c2 }, + /* 0x5700 */ + { 925, 0x1486 }, { 930, 0x2c22 }, { 935, 0xd63d }, { 945, 0xe018 }, + { 950, 0x3060 }, { 954, 0x0004 }, { 955, 0xe9a4 }, { 963, 0x5ebb }, + { 974, 0x100a }, { 977, 0xf6b0 }, { 986, 0x1382 }, { 991, 0x2100 }, + { 993, 0x9180 }, { 997, 0x6020 }, { 1000, 0x22d2 }, { 1006, 0xe161 }, + /* 0x5800 */ + { 1013, 0x3318 }, { 1019, 0xc800 }, { 1022, 0x20c1 }, { 1026, 0x8204 }, + { 1029, 0xb200 }, { 1033, 0x8021 }, { 1036, 0x0192 }, { 1040, 0x9100 }, + { 1043, 0xb783 }, { 1052, 0x2051 }, { 1056, 0x0247 }, { 1061, 0x1006 }, + { 1064, 0x6114 }, { 1069, 0x2455 }, { 1075, 0x0206 }, { 1078, 0x0008 }, + /* 0x5900 */ + { 1079, 0x1860 }, { 1083, 0x201c }, { 1087, 0x811a }, { 1092, 0x8069 }, + { 1097, 0x0048 }, { 1099, 0xea0c }, { 1106, 0xa80a }, { 1111, 0x1a64 }, + { 1117, 0x5800 }, { 1120, 0x80a4 }, { 1124, 0xe090 }, { 1129, 0x1489 }, + { 1134, 0x251a }, { 1140, 0xe004 }, { 1144, 0xc098 }, { 1149, 0x0096 }, + /* 0x5a00 */ + { 1153, 0x7011 }, { 1158, 0x400c }, { 1161, 0x2598 }, { 1167, 0x0001 }, + { 1168, 0x11b0 }, { 1173, 0x4021 }, { 1176, 0x20a8 }, { 1180, 0x4c80 }, + { 1184, 0x0800 }, { 1185, 0xd249 }, { 1192, 0x1085 }, { 1196, 0x8d2e }, + { 1204, 0x8150 }, { 1208, 0x1400 }, { 1210, 0x4421 }, { 1214, 0x2060 }, + /* 0x5b00 */ + { 1217, 0x0103 }, { 1220, 0x2a80 }, { 1224, 0x2022 }, { 1227, 0x0110 }, + { 1229, 0x1802 }, { 1232, 0x4044 }, { 1235, 0xc100 }, { 1238, 0xf000 }, + { 1242, 0x4452 }, { 1247, 0x005b }, { 1252, 0xb300 }, { 1257, 0x1486 }, + { 1262, 0xa003 }, { 1266, 0x07c0 }, { 1271, 0x8001 }, { 1273, 0x2012 }, + /* 0x5c00 */ + { 1276, 0x1000 }, { 1277, 0xc080 }, { 1280, 0x5a48 }, { 1286, 0x0065 }, + { 1290, 0x0000 }, { 1290, 0x1600 }, { 1293, 0x238c }, { 1299, 0x3c31 }, + { 1306, 0x8580 }, { 1310, 0xa004 }, { 1313, 0x044d }, { 1318, 0x0434 }, + { 1322, 0x0a00 }, { 1324, 0x2084 }, { 1327, 0x4000 }, { 1328, 0x0016 }, + /* 0x5d00 */ + { 1331, 0x2042 }, { 1334, 0x0004 }, { 1335, 0x08d8 }, { 1340, 0xa212 }, + { 1345, 0x054c }, { 1350, 0x8222 }, { 1354, 0x2417 }, { 1360, 0xc601 }, + { 1365, 0x050a }, { 1369, 0x8a3c }, { 1376, 0x0881 }, { 1379, 0x0315 }, + { 1384, 0x4888 }, { 1388, 0x0301 }, { 1391, 0x0211 }, { 1394, 0x0300 }, + /* 0x5e00 */ + { 1396, 0x2081 }, { 1399, 0x8134 }, { 1404, 0x4101 }, { 1407, 0x4024 }, + { 1410, 0x0a00 }, { 1412, 0x5943 }, { 1419, 0x7d00 }, { 1425, 0x0001 }, + { 1426, 0x4801 }, { 1429, 0x0000 }, { 1429, 0x1534 }, { 1435, 0xe00a }, + { 1440, 0x5840 }, { 1444, 0x5036 }, { 1450, 0x0820 }, { 1452, 0x0000 }, + /* 0x5f00 */ + { 1452, 0x41c4 }, { 1457, 0x3200 }, { 1460, 0x591e }, { 1468, 0xa851 }, + { 1474, 0x20b1 }, { 1479, 0x0911 }, { 1483, 0x8099 }, { 1488, 0x6534 }, + { 1495, 0xa200 }, { 1498, 0x3040 }, { 1501, 0x9894 }, { 1507, 0x0103 }, + { 1510, 0x0b90 }, { 1515, 0x401f }, { 1521, 0xf706 }, { 1530, 0x144c }, + /* 0x6000 */ + { 1535, 0x2480 }, { 1538, 0x8598 }, { 1544, 0x2010 }, { 1546, 0x0028 }, + { 1548, 0x1381 }, { 1553, 0x20d2 }, { 1558, 0x0082 }, { 1560, 0xc002 }, + { 1563, 0x4544 }, { 1568, 0x612a }, { 1574, 0x0134 }, { 1578, 0x4883 }, + { 1583, 0xcf14 }, { 1591, 0x6a30 }, { 1597, 0x0024 }, { 1599, 0x3124 }, + /* 0x6100 */ + { 1604, 0x1484 }, { 1608, 0x52df }, { 1618, 0x0c04 }, { 1621, 0x02e3 }, + { 1627, 0x0262 }, { 1631, 0x4000 }, { 1632, 0x1001 }, { 1634, 0x9904 }, + { 1639, 0x281b }, { 1645, 0xb18c }, { 1652, 0x2521 }, { 1657, 0x1300 }, + { 1660, 0xc007 }, { 1665, 0xf020 }, { 1670, 0xb2a6 }, { 1678, 0x0000 }, + /* 0x6200 */ + { 1678, 0x009a }, { 1682, 0x1028 }, { 1685, 0x0a8d }, { 1691, 0x2200 }, + { 1693, 0x105c }, { 1698, 0x1457 }, { 1705, 0xa010 }, { 1708, 0x2408 }, + { 1711, 0xe000 }, { 1714, 0x0001 }, { 1715, 0x0140 }, { 1717, 0xc4c8 }, + { 1723, 0x4010 }, { 1725, 0x0460 }, { 1728, 0x0400 }, { 1729, 0x3014 }, + /* 0x6300 */ + { 1733, 0x2c18 }, { 1738, 0x0149 }, { 1742, 0x2600 }, { 1745, 0x1260 }, + { 1749, 0x4c5e }, { 1757, 0x091c }, { 1762, 0x3060 }, { 1766, 0xb132 }, + { 1773, 0x0494 }, { 1777, 0x4631 }, { 1783, 0xe050 }, { 1788, 0x2000 }, + { 1789, 0x4122 }, { 1793, 0x103a }, { 1798, 0x1421 }, { 1802, 0x032c }, + /* 0x6400 */ + { 1807, 0x0600 }, { 1809, 0x4115 }, { 1814, 0x8635 }, { 1821, 0xa021 }, + { 1825, 0x8800 }, { 1827, 0xbc1e }, { 1836, 0x200b }, { 1840, 0x2818 }, + { 1844, 0x80a0 }, { 1847, 0xab03 }, { 1854, 0x114a }, { 1859, 0xe008 }, + { 1863, 0x5e10 }, { 1869, 0x00a3 }, { 1873, 0x2630 }, { 1878, 0x88a1 }, + /* 0x6500 */ + { 1883, 0x8712 }, { 1889, 0xca58 }, { 1896, 0x4244 }, { 1900, 0x3402 }, + { 1904, 0x0288 }, { 1907, 0x8015 }, { 1911, 0x0881 }, { 1914, 0x2400 }, + { 1916, 0x0422 }, { 1919, 0x2124 }, { 1923, 0x4049 }, { 1927, 0x801c }, + { 1931, 0x4304 }, { 1935, 0x8151 }, { 1940, 0x0000 }, { 1940, 0xc235 }, + /* 0x6600 */ + { 1947, 0x2311 }, { 1952, 0x6066 }, { 1958, 0x5e5e }, { 1968, 0x028b }, + { 1973, 0x5461 }, { 1979, 0x1b82 }, { 1985, 0x1c03 }, { 1990, 0xdba8 }, + { 1999, 0x3801 }, { 2003, 0x9e05 }, { 2010, 0x2011 }, { 2013, 0x8826 }, + { 2018, 0xd10d }, { 2025, 0x8810 }, { 2028, 0x5900 }, { 2032, 0x0c00 }, + /* 0x6700 */ + { 2034, 0x40a0 }, { 2037, 0x1208 }, { 2040, 0x0005 }, { 2042, 0x4008 }, + { 2044, 0x11a0 }, { 2048, 0x2030 }, { 2051, 0x5040 }, { 2054, 0x0850 }, + { 2057, 0xc012 }, { 2061, 0x0b4a }, { 2067, 0x0000 }, { 2067, 0x3827 }, + { 2074, 0x032d }, { 2080, 0x1284 }, { 2084, 0x0042 }, { 2086, 0x02c5 }, + /* 0x6800 */ + { 2091, 0x0000 }, { 2091, 0xa210 }, { 2095, 0xb180 }, { 2100, 0x880b }, + { 2105, 0x1430 }, { 2109, 0x09a4 }, { 2114, 0xc800 }, { 2117, 0x1e27 }, + { 2125, 0x0154 }, { 2129, 0x1540 }, { 2133, 0x462a }, { 2139, 0x0804 }, + { 2141, 0x9120 }, { 2145, 0x324b }, { 2152, 0x3d20 }, { 2158, 0x3863 }, + /* 0x6900 */ + { 2165, 0x0640 }, { 2168, 0x00cb }, { 2173, 0x0000 }, { 2173, 0x092a }, + { 2178, 0x4224 }, { 2182, 0x0880 }, { 2184, 0x1378 }, { 2191, 0x8c07 }, + { 2197, 0x2001 }, { 2199, 0x0144 }, { 2202, 0xa962 }, { 2209, 0x1580 }, + { 2213, 0x0120 }, { 2215, 0x00c2 }, { 2218, 0xc024 }, { 2222, 0x402a }, + /* 0x6a00 */ + { 2226, 0x800b }, { 2230, 0x2422 }, { 2234, 0x0111 }, { 2237, 0xc895 }, + { 2244, 0x4660 }, { 2249, 0x0867 }, { 2255, 0x0490 }, { 2258, 0x400a }, + { 2261, 0x0aca }, { 2267, 0xe802 }, { 2272, 0x8820 }, { 2275, 0xe013 }, + { 2281, 0x1340 }, { 2285, 0x3071 }, { 2291, 0x1090 }, { 2294, 0x3007 }, + /* 0x6b00 */ + { 2299, 0x82cc }, { 2305, 0x4883 }, { 2310, 0x9910 }, { 2315, 0x8860 }, + { 2319, 0x2440 }, { 2322, 0x2144 }, { 2326, 0x4881 }, { 2330, 0x6021 }, + { 2334, 0x0024 }, { 2336, 0x8880 }, { 2339, 0x730d }, { 2347, 0x6301 }, + { 2352, 0x1218 }, { 2356, 0x0440 }, { 2358, 0x40ca }, { 2363, 0x8282 }, + /* 0x6c00 */ + { 2367, 0x6234 }, { 2373, 0x8205 }, { 2377, 0x51c0 }, { 2382, 0x8c68 }, + { 2388, 0xac00 }, { 2392, 0x1a14 }, { 2397, 0xa880 }, { 2401, 0x0b50 }, + { 2406, 0x02e0 }, { 2410, 0x91b0 }, { 2416, 0x0000 }, { 2416, 0x0015 }, + { 2419, 0xa044 }, { 2423, 0x1457 }, { 2430, 0x5a81 }, { 2436, 0x0014 }, + /* 0x6d00 */ + { 2438, 0xc490 }, { 2443, 0x040a }, { 2446, 0xc1c0 }, { 2451, 0x9202 }, + { 2455, 0x0000 }, { 2455, 0xc080 }, { 2458, 0x80a2 }, { 2462, 0x1001 }, + { 2464, 0x0084 }, { 2466, 0x01d6 }, { 2472, 0x1400 }, { 2474, 0xa290 }, + { 2479, 0xc510 }, { 2484, 0xa840 }, { 2488, 0x8225 }, { 2493, 0x1051 }, + /* 0x6e00 */ + { 2497, 0x0011 }, { 2499, 0x4000 }, { 2500, 0x0084 }, { 2502, 0x1a44 }, + { 2507, 0x8b30 }, { 2513, 0x709e }, { 2521, 0x010c }, { 2524, 0x2808 }, + { 2527, 0x2000 }, { 2528, 0x0208 }, { 2530, 0x6081 }, { 2534, 0x880a }, + { 2538, 0xe58b }, { 2547, 0x0000 }, { 2547, 0x6800 }, { 2550, 0x2a00 }, + /* 0x6f00 */ + { 2553, 0x3510 }, { 2558, 0x0d40 }, { 2562, 0xa640 }, { 2567, 0x1849 }, + { 2572, 0x8000 }, { 2573, 0x668e }, { 2581, 0x1106 }, { 2585, 0x6000 }, + { 2587, 0x3988 }, { 2593, 0x845d }, { 2600, 0xc1e1 }, { 2607, 0x1061 }, + { 2611, 0x05a0 }, { 2615, 0x4400 }, { 2617, 0x0300 }, { 2619, 0x3221 }, + /* 0x7000 */ + { 2624, 0x20e1 }, { 2629, 0x0080 }, { 2630, 0x8009 }, { 2633, 0x1290 }, + { 2637, 0x4f18 }, { 2644, 0x6030 }, { 2648, 0x5030 }, { 2652, 0x4060 }, + { 2655, 0x0062 }, { 2658, 0x09f0 }, { 2664, 0x0810 }, { 2666, 0x0093 }, + { 2670, 0x0400 }, { 2671, 0x117a }, { 2678, 0x0010 }, { 2679, 0x0400 }, + /* 0x7100 */ + { 2680, 0x98f8 }, { 2688, 0x4000 }, { 2689, 0xa801 }, { 2693, 0x0103 }, + { 2696, 0x0ce2 }, { 2702, 0x5485 }, { 2708, 0x0101 }, { 2710, 0x0200 }, + { 2711, 0x10a1 }, { 2715, 0x0c04 }, { 2718, 0x8005 }, { 2721, 0x840d }, + { 2726, 0x1813 }, { 2731, 0x1648 }, { 2736, 0x0000 }, { 2736, 0x4100 }, + /* 0x7200 */ + { 2738, 0x0381 }, { 2742, 0xa488 }, { 2747, 0x8810 }, { 2750, 0x0310 }, + { 2753, 0xc02e }, { 2759, 0x5469 }, { 2766, 0xc909 }, { 2772, 0x9982 }, + { 2778, 0x6210 }, { 2782, 0x0808 }, { 2784, 0x6100 }, { 2787, 0x4012 }, + { 2790, 0x1282 }, { 2794, 0x8160 }, { 2798, 0x0020 }, { 2799, 0x4c18 }, + /* 0x7300 */ + { 2804, 0x28b4 }, { 2810, 0x430c }, { 2815, 0x1194 }, { 2820, 0x2c26 }, + { 2826, 0x2008 }, { 2828, 0xe145 }, { 2835, 0xdac1 }, { 2843, 0x1282 }, + { 2847, 0x406b }, { 2853, 0xd1a9 }, { 2861, 0x2c65 }, { 2868, 0xb2a0 }, + { 2874, 0x9a60 }, { 2880, 0x224c }, { 2885, 0x02ca }, { 2890, 0xaeb0 }, + /* 0x7400 */ + { 2898, 0x0493 }, { 2903, 0x0c02 }, { 2906, 0xff50 }, { 2916, 0x0203 }, + { 2919, 0x28d9 }, { 2926, 0x2086 }, { 2930, 0x69c4 }, { 2937, 0x0006 }, + { 2939, 0x82e3 }, { 2946, 0x9707 }, { 2954, 0xcf4b }, { 2964, 0x8a26 }, + { 2970, 0x1300 }, { 2973, 0xcd09 }, { 2980, 0x8d10 }, { 2985, 0x9c10 }, + /* 0x7500 */ + { 2990, 0x0040 }, { 2991, 0x00c4 }, { 2994, 0x8693 }, { 3001, 0xe240 }, + { 3006, 0x4189 }, { 3011, 0xc085 }, { 3016, 0x8002 }, { 3018, 0x7e02 }, + { 3025, 0x0022 }, { 3027, 0x122d }, { 3033, 0x0014 }, { 3035, 0x8410 }, + { 3038, 0xd053 }, { 3045, 0x9080 }, { 3048, 0xd093 }, { 3055, 0x0202 }, + /* 0x7600 */ + { 3057, 0x959d }, { 3066, 0x7a6c }, { 3075, 0x2268 }, { 3080, 0x172c }, + { 3087, 0x0e3b }, { 3095, 0x8220 }, { 3098, 0xe030 }, { 3103, 0x0012 }, + { 3105, 0x3022 }, { 3109, 0xb820 }, { 3114, 0x25fd }, { 3124, 0x2000 }, + { 3125, 0x5a22 }, { 3131, 0x0210 }, { 3133, 0x1141 }, { 3137, 0x1243 }, + /* 0x7700 */ + { 3142, 0x4441 }, { 3146, 0x16b4 }, { 3153, 0xe104 }, { 3158, 0x6270 }, + { 3164, 0xe464 }, { 3171, 0xd0c4 }, { 3177, 0x1495 }, { 3183, 0x241d }, + { 3189, 0x3011 }, { 3193, 0x8470 }, { 3198, 0xc484 }, { 3203, 0x4022 }, + { 3206, 0x0208 }, { 3208, 0xc226 }, { 3214, 0x1451 }, { 3219, 0x0913 }, + /* 0x7800 */ + { 3224, 0x6260 }, { 3229, 0x2002 }, { 3231, 0x600e }, { 3236, 0x00a1 }, + { 3239, 0x5198 }, { 3245, 0x5004 }, { 3248, 0x451b }, { 3255, 0x4400 }, + { 3257, 0x8400 }, { 3259, 0xe110 }, { 3264, 0x3112 }, { 3269, 0xa80f }, + { 3276, 0x5380 }, { 3281, 0x886c }, { 3287, 0x0453 }, { 3292, 0x8ccc }, + /* 0x7900 */ + { 3299, 0x1041 }, { 3302, 0xd401 }, { 3307, 0x22a1 }, { 3312, 0xa832 }, + { 3318, 0x8c70 }, { 3324, 0x1912 }, { 3329, 0x0a80 }, { 3332, 0x5a04 }, + { 3337, 0x1800 }, { 3339, 0x197a }, { 3347, 0x8b02 }, { 3352, 0x0912 }, + { 3356, 0x8594 }, { 3362, 0x6450 }, { 3367, 0x2c25 }, { 3373, 0x1102 }, + /* 0x7a00 */ + { 3376, 0x168c }, { 3382, 0x4822 }, { 3386, 0xa882 }, { 3391, 0x0731 }, + { 3397, 0x11b0 }, { 3402, 0xb260 }, { 3408, 0x24a1 }, { 3413, 0x4120 }, + { 3416, 0x0c65 }, { 3422, 0x4013 }, { 3426, 0x1009 }, { 3429, 0x1a28 }, + { 3434, 0x5240 }, { 3438, 0x0802 }, { 3440, 0x1b00 }, { 3444, 0x6812 }, + /* 0x7b00 */ + { 3449, 0x0080 }, { 3450, 0x8010 }, { 3452, 0xee88 }, { 3460, 0xa013 }, + { 3465, 0x4083 }, { 3469, 0x0020 }, { 3470, 0xa651 }, { 3477, 0x008c }, + { 3480, 0x4210 }, { 3483, 0x4843 }, { 3488, 0x9021 }, { 3492, 0x3c65 }, + { 3500, 0x0524 }, { 3504, 0x0ed0 }, { 3510, 0x0500 }, { 3512, 0x5734 }, + /* 0x7c00 */ + { 3520, 0xda5e }, { 3530, 0x0a00 }, { 3532, 0x1161 }, { 3537, 0x065a }, + { 3543, 0x0440 }, { 3545, 0x7e2e }, { 3555, 0x628a }, { 3561, 0x3205 }, + { 3566, 0x80c0 }, { 3569, 0x4010 }, { 3571, 0x0041 }, { 3573, 0x9cc1 }, + { 3580, 0xa390 }, { 3586, 0x26b8 }, { 3593, 0x0a40 }, { 3596, 0x0020 }, + /* 0x7d00 */ + { 3597, 0x8388 }, { 3602, 0x604e }, { 3608, 0x2448 }, { 3612, 0x7002 }, + { 3616, 0x2183 }, { 3621, 0x368a }, { 3628, 0x04a0 }, { 3631, 0x8d01 }, + { 3636, 0x396e }, { 3645, 0x60c2 }, { 3650, 0x04c0 }, { 3653, 0x02c8 }, + { 3657, 0x707c }, { 3665, 0x0280 }, { 3667, 0x2c64 }, { 3673, 0x0662 }, + /* 0x7e00 */ + { 3678, 0x0101 }, { 3680, 0x30a3 }, { 3686, 0xb181 }, { 3692, 0x8048 }, + { 3695, 0x40b0 }, { 3699, 0x8105 }, { 3703, 0xc826 }, { 3709, 0x4108 }, + { 3712, 0x24c2 }, { 3717, 0x6522 }, { 3723, 0x0000 }, { 3723, 0x0000 }, + { 3723, 0x0000 }, { 3723, 0x0000 }, { 3723, 0x0000 }, { 3723, 0x0000 }, + /* 0x7f00 */ + { 3723, 0x0000 }, { 3723, 0x0000 }, { 3723, 0x0000 }, { 3723, 0xf800 }, + { 3728, 0x8098 }, { 3732, 0x380c }, { 3737, 0x207a }, { 3743, 0xe002 }, + { 3747, 0xa801 }, { 3751, 0x10c3 }, { 3756, 0x2446 }, { 3761, 0x9010 }, + { 3764, 0xc109 }, { 3769, 0x8800 }, { 3771, 0xd128 }, { 3777, 0xe404 }, + /* 0x8000 */ + { 3782, 0xe580 }, { 3788, 0xe05a }, { 3795, 0x5051 }, { 3800, 0x56b1 }, + { 3808, 0x0011 }, { 3810, 0x0000 }, { 3810, 0x2051 }, { 3814, 0x0022 }, + { 3816, 0x4102 }, { 3819, 0x5000 }, { 3821, 0x08c0 }, { 3824, 0x0300 }, + { 3826, 0xa100 }, { 3829, 0x01b4 }, { 3834, 0x6001 }, { 3837, 0x464d }, + /* 0x8100 */ + { 3844, 0x0808 }, { 3846, 0x51c0 }, { 3851, 0x1091 }, { 3855, 0x1421 }, + { 3859, 0x14a0 }, { 3863, 0x0084 }, { 3865, 0xa383 }, { 3872, 0x0080 }, + { 3873, 0x4872 }, { 3879, 0x4941 }, { 3884, 0x4004 }, { 3886, 0x0814 }, + { 3889, 0xcc28 }, { 3895, 0x68a0 }, { 3900, 0x1812 }, { 3904, 0xa367 }, + /* 0x8200 */ + { 3913, 0x8009 }, { 3916, 0x2618 }, { 3921, 0x0106 }, { 3924, 0x0414 }, + { 3927, 0xc878 }, { 3934, 0x1042 }, { 3937, 0x2089 }, { 3941, 0xa810 }, + { 3945, 0x469b }, { 3953, 0x0d52 }, { 3959, 0x479b }, { 3968, 0xd495 }, + { 3976, 0x0040 }, { 3977, 0x0421 }, { 3980, 0xa515 }, { 3987, 0x60c0 }, + /* 0x8300 */ + { 3991, 0x0d83 }, { 3997, 0xe800 }, { 4001, 0x7006 }, { 4006, 0x3489 }, + { 4012, 0x609c }, { 4018, 0x00fa }, { 4024, 0x0000 }, { 4024, 0xa101 }, + { 4028, 0x2055 }, { 4033, 0x3b34 }, { 4041, 0x32c0 }, { 4046, 0xc000 }, + { 4048, 0x8281 }, { 4052, 0x2013 }, { 4056, 0x0500 }, { 4058, 0x1340 }, + /* 0x8400 */ + { 4062, 0x8442 }, { 4066, 0x0222 }, { 4069, 0x8000 }, { 4070, 0x0200 }, + { 4071, 0xa5a0 }, { 4077, 0x1746 }, { 4084, 0x04b1 }, { 4089, 0x3159 }, + { 4096, 0x0022 }, { 4098, 0x402c }, { 4102, 0x8740 }, { 4107, 0x6412 }, + { 4112, 0x9185 }, { 4118, 0x1008 }, { 4120, 0x8480 }, { 4123, 0x2c87 }, + /* 0x8500 */ + { 4130, 0x508c }, { 4135, 0x5001 }, { 4138, 0x8cbc }, { 4146, 0x805c }, + { 4151, 0x8040 }, { 4153, 0xf24f }, { 4163, 0x8817 }, { 4169, 0xae00 }, + { 4174, 0x9a62 }, { 4181, 0xa108 }, { 4185, 0x20a5 }, { 4190, 0xf1d0 }, + { 4198, 0x4c84 }, { 4203, 0x8500 }, { 4206, 0x2141 }, { 4210, 0x9048 }, + /* 0x8600 */ + { 4214, 0x6031 }, { 4219, 0x4b07 }, { 4226, 0x0282 }, { 4229, 0x3540 }, + { 4234, 0x0047 }, { 4238, 0x23cc }, { 4245, 0x921f }, { 4253, 0x04e0 }, + { 4257, 0x2100 }, { 4259, 0x1542 }, { 4264, 0x21c2 }, { 4269, 0x83ba }, + { 4277, 0x002b }, { 4281, 0x14a6 }, { 4287, 0x00a9 }, { 4291, 0x3400 }, + /* 0x8700 */ + { 4294, 0xc8b0 }, { 4300, 0xc219 }, { 4306, 0xc10a }, { 4311, 0x7606 }, + { 4318, 0x2029 }, { 4322, 0x2100 }, { 4324, 0x8032 }, { 4328, 0x0806 }, + { 4331, 0x1bf8 }, { 4340, 0x43a9 }, { 4347, 0x7089 }, { 4353, 0xc022 }, + { 4357, 0x4702 }, { 4362, 0x9660 }, { 4368, 0x2c1c }, { 4374, 0x850a }, + /* 0x8800 */ + { 4379, 0x0e4a }, { 4385, 0xdf1d }, { 4396, 0x6100 }, { 4399, 0x1425 }, + { 4404, 0x4f2a }, { 4412, 0x9562 }, { 4419, 0x0211 }, { 4422, 0x0a02 }, + { 4425, 0x0001 }, { 4426, 0x9d00 }, { 4431, 0x0501 }, { 4434, 0x6400 }, + { 4437, 0x7c01 }, { 4443, 0x480e }, { 4448, 0x8080 }, { 4450, 0x00a3 }, + /* 0x8900 */ + { 4454, 0xe042 }, { 4459, 0x1760 }, { 4465, 0x01c1 }, { 4469, 0x4627 }, + { 4476, 0x8265 }, { 4482, 0x1c84 }, { 4487, 0x480e }, { 4492, 0x3c29 }, + { 4499, 0x2200 }, { 4501, 0x9831 }, { 4507, 0x0021 }, { 4509, 0x10f1 }, + { 4515, 0x0000 }, { 4515, 0x01f0 }, { 4520, 0x2a20 }, { 4524, 0xa24a }, + /* 0x8a00 */ + { 4530, 0x80b0 }, { 4534, 0x4036 }, { 4539, 0x9855 }, { 4546, 0x60a0 }, + { 4550, 0x62a9 }, { 4557, 0x31c8 }, { 4563, 0x00a2 }, { 4566, 0xcee0 }, + { 4574, 0x8849 }, { 4579, 0x82c5 }, { 4585, 0xc280 }, { 4589, 0x48c8 }, + { 4594, 0x0748 }, { 4599, 0xa0ba }, { 4606, 0x1000 }, { 4607, 0x9071 }, + /* 0x8b00 */ + { 4613, 0x0c60 }, { 4617, 0xd002 }, { 4621, 0x2000 }, { 4622, 0x1081 }, + { 4625, 0x217c }, { 4632, 0x421c }, { 4637, 0x2008 }, { 4639, 0x5340 }, + { 4644, 0xa832 }, { 4650, 0xd030 }, { 4655, 0x0000 }, { 4655, 0x0000 }, + { 4655, 0x0000 }, { 4655, 0x0000 }, { 4655, 0x0000 }, { 4655, 0x0000 }, + /* 0x8c00 */ + { 4655, 0x0000 }, { 4655, 0x0000 }, { 4655, 0x0000 }, { 4655, 0x6300 }, + { 4659, 0x8aa0 }, { 4664, 0x2b9a }, { 4672, 0x2358 }, { 4678, 0x4868 }, + { 4683, 0x08c0 }, { 4686, 0x1a0d }, { 4692, 0x0010 }, { 4693, 0x0600 }, + { 4695, 0x8a60 }, { 4700, 0x2260 }, { 4704, 0x9102 }, { 4708, 0xc1a5 }, + /* 0x8d00 */ + { 4715, 0x020a }, { 4718, 0x0884 }, { 4721, 0x0000 }, { 4721, 0x0000 }, + { 4721, 0x0000 }, { 4721, 0x0000 }, { 4721, 0x5220 }, { 4725, 0x8000 }, + { 4726, 0x2114 }, { 4730, 0xc023 }, { 4735, 0x9841 }, { 4740, 0x1aa4 }, + { 4746, 0x45e1 }, { 4753, 0x02b2 }, { 4758, 0x10b0 }, { 4762, 0x2017 }, + /* 0x8e00 */ + { 4767, 0x0872 }, { 4772, 0x0052 }, { 4775, 0x00cf }, { 4781, 0x23ca }, + { 4788, 0xe803 }, { 4794, 0x7810 }, { 4799, 0xb206 }, { 4805, 0x0e03 }, + { 4810, 0x020c }, { 4813, 0x6c25 }, { 4820, 0x6284 }, { 4825, 0x0c28 }, + { 4829, 0x809b }, { 4835, 0x1012 }, { 4838, 0x6100 }, { 4841, 0x0683 }, + /* 0x8f00 */ + { 4846, 0x8185 }, { 4851, 0x41c1 }, { 4856, 0x71ab }, { 4865, 0x04f0 }, + { 4870, 0x808b }, { 4875, 0x613e }, { 4883, 0x0020 }, { 4884, 0x0000 }, + { 4884, 0x0000 }, { 4884, 0x2000 }, { 4885, 0x0073 }, { 4890, 0x4160 }, + { 4894, 0x2c43 }, { 4900, 0x002d }, { 4904, 0x4119 }, { 4909, 0x4862 }, + /* 0x9000 */ + { 4914, 0x1114 }, { 4918, 0x0900 }, { 4920, 0xb700 }, { 4926, 0x8098 }, + { 4930, 0x1018 }, { 4933, 0x2800 }, { 4935, 0x10c4 }, { 4939, 0x0211 }, + { 4942, 0x5920 }, { 4947, 0x0ba1 }, { 4953, 0x0027 }, { 4957, 0x605d }, + { 4964, 0x11b8 }, { 4970, 0xb3a4 }, { 4978, 0x8820 }, { 4981, 0xc051 }, + /* 0x9100 */ + { 4986, 0x2171 }, { 4992, 0x55d1 }, { 5000, 0xc2ad }, { 5008, 0x36d2 }, + { 5016, 0x8188 }, { 5020, 0x0e88 }, { 5025, 0x2092 }, { 5029, 0x0e10 }, + { 5033, 0x446a }, { 5039, 0x413a }, { 5045, 0x7142 }, { 5051, 0xb84f }, + { 5060, 0x002c }, { 5063, 0x4698 }, { 5069, 0xf630 }, { 5077, 0x2a83 }, + /* 0x9200 */ + { 5083, 0x16f3 }, { 5092, 0x314d }, { 5099, 0xc178 }, { 5106, 0x5769 }, + { 5115, 0xe4cd }, { 5124, 0x3302 }, { 5129, 0xc3a3 }, { 5137, 0xbbe1 }, + { 5147, 0x6700 }, { 5152, 0x8284 }, { 5156, 0x89b1 }, { 5163, 0xbd44 }, + { 5171, 0x79ef }, { 5183, 0xb3a9 }, { 5192, 0x51ab }, { 5200, 0x8a01 }, + /* 0x9300 */ + { 5204, 0x2105 }, { 5208, 0xf032 }, { 5215, 0x06b2 }, { 5221, 0x00d8 }, + { 5225, 0x0380 }, { 5228, 0x45a7 }, { 5236, 0xa6b0 }, { 5243, 0xa45b }, + { 5251, 0xad07 }, { 5259, 0x4924 }, { 5264, 0x0b5a }, { 5271, 0x0470 }, + { 5275, 0x3ef2 }, { 5285, 0xd208 }, { 5290, 0x00c4 }, { 5293, 0x2f80 }, + /* 0x9400 */ + { 5299, 0xe316 }, { 5307, 0x80e0 }, { 5311, 0xc000 }, { 5313, 0xa81e }, + { 5320, 0x1528 }, { 5325, 0x9220 }, { 5329, 0xe90a }, { 5336, 0x0006 }, + { 5338, 0x0018 }, { 5340, 0x0000 }, { 5340, 0x0000 }, { 5340, 0x0000 }, + { 5340, 0x0000 }, { 5340, 0x0000 }, { 5340, 0x0000 }, { 5340, 0x0000 }, + /* 0x9500 */ + { 5340, 0x0000 }, { 5340, 0x0000 }, { 5340, 0x0000 }, { 5340, 0x0000 }, + { 5340, 0x0000 }, { 5340, 0x0000 }, { 5340, 0x0000 }, { 5340, 0x4300 }, + { 5343, 0x7110 }, { 5348, 0xe000 }, { 5351, 0x1a42 }, { 5356, 0xa450 }, + { 5361, 0x0b40 }, { 5365, 0xe60f }, { 5374, 0x0051 }, { 5377, 0x0000 }, + /* 0x9600 */ + { 5377, 0x0000 }, { 5377, 0x6000 }, { 5379, 0x1074 }, { 5384, 0x378a }, + { 5392, 0x0002 }, { 5393, 0x01d4 }, { 5398, 0x4002 }, { 5400, 0xd810 }, + { 5405, 0x021e }, { 5410, 0xa442 }, { 5415, 0xc270 }, { 5421, 0x0408 }, + { 5423, 0x0400 }, { 5424, 0xe504 }, { 5430, 0x8200 }, { 5432, 0x0402 }, + /* 0x9700 */ + { 5434, 0x022c }, { 5438, 0x2c00 }, { 5441, 0x010e }, { 5445, 0x000a }, + { 5447, 0xc40a }, { 5452, 0x0da0 }, { 5457, 0x4488 }, { 5461, 0xa9c8 }, + { 5468, 0x0201 }, { 5470, 0xc6e0 }, { 5477, 0x5004 }, { 5480, 0xd766 }, + { 5490, 0x76b2 }, { 5499, 0x6b93 }, { 5508, 0x8013 }, { 5512, 0x0592 }, + /* 0x9800 */ + { 5517, 0x6480 }, { 5521, 0x5250 }, { 5526, 0xc869 }, { 5533, 0x402d }, + { 5538, 0x0490 }, { 5541, 0x06ce }, { 5548, 0x146c }, { 5554, 0x0000 }, + { 5554, 0x0000 }, { 5554, 0x0000 }, { 5554, 0x6800 }, { 5557, 0x8d91 }, + { 5564, 0x1124 }, { 5568, 0x0000 }, { 5568, 0x04ea }, { 5574, 0x0048 }, + /* 0x9900 */ + { 5576, 0x0184 }, { 5579, 0x9ce2 }, { 5587, 0x08c4 }, { 5591, 0x1e3e }, + { 5600, 0x61c3 }, { 5607, 0xdb10 }, { 5614, 0x0001 }, { 5615, 0x0000 }, + { 5615, 0x0000 }, { 5615, 0xa800 }, { 5618, 0x0040 }, { 5619, 0xa627 }, + { 5627, 0x0208 }, { 5629, 0x5618 }, { 5635, 0x1c80 }, { 5639, 0x6231 }, + /* 0x9a00 */ + { 5645, 0x181c }, { 5650, 0x4043 }, { 5654, 0x609d }, { 5661, 0x0168 }, + { 5665, 0x5c92 }, { 5672, 0x2052 }, { 5676, 0x0000 }, { 5676, 0x0000 }, + { 5676, 0x0000 }, { 5676, 0x0000 }, { 5676, 0xd400 }, { 5680, 0xca74 }, + { 5688, 0x414a }, { 5693, 0x18e5 }, { 5700, 0x12b1 }, { 5706, 0xa62c }, + /* 0x9b00 */ + { 5713, 0x7b3f }, { 5725, 0x1a45 }, { 5731, 0x2841 }, { 5735, 0x26b8 }, + { 5742, 0x1900 }, { 5745, 0x48e0 }, { 5750, 0x7d6a }, { 5760, 0x83a8 }, + { 5766, 0xaef1 }, { 5776, 0x6411 }, { 5781, 0x12c0 }, { 5785, 0xd987 }, + { 5794, 0x4182 }, { 5798, 0xa181 }, { 5803, 0x8ca0 }, { 5808, 0xa788 }, + /* 0x9c00 */ + { 5815, 0x8805 }, { 5819, 0x5742 }, { 5826, 0x07cc }, { 5833, 0x20e2 }, + { 5838, 0xc63a }, { 5846, 0xf959 }, { 5856, 0x4f08 }, { 5862, 0x08a5 }, + { 5867, 0x0000 }, { 5867, 0x0000 }, { 5867, 0x0000 }, { 5867, 0x0000 }, + { 5867, 0x0000 }, { 5867, 0x0000 }, { 5867, 0x0040 }, { 5868, 0x0284 }, + /* 0x9d00 */ + { 5871, 0x0804 }, { 5873, 0x7182 }, { 5879, 0x8000 }, { 5880, 0x341d }, + { 5887, 0x04ac }, { 5892, 0x8018 }, { 5895, 0x0e2c }, { 5901, 0x58c1 }, + { 5907, 0x6458 }, { 5913, 0x01ec }, { 5919, 0x5402 }, { 5923, 0x9222 }, + { 5928, 0x0688 }, { 5932, 0xc4f0 }, { 5939, 0x4aa1 }, { 5945, 0x4019 }, + /* 0x9e00 */ + { 5949, 0x4484 }, { 5953, 0x3267 }, { 5961, 0x0000 }, { 5961, 0x0000 }, + { 5961, 0x0000 }, { 5961, 0x0000 }, { 5961, 0x0000 }, { 5961, 0x1c00 }, + { 5964, 0xc0bd }, { 5972, 0x4940 }, { 5976, 0xd110 }, { 5981, 0x0039 }, + { 5985, 0x0940 }, { 5988, 0x8020 }, { 5990, 0x7090 }, { 5995, 0x8127 }, + /* 0x9f00 */ + { 6001, 0x820c }, { 6005, 0x8ed7 }, { 6015, 0x8c44 }, { 6020, 0xb696 }, + { 6029, 0x00fa }, { 6035, 0x65e8 }, { 6043, 0xe300 }, { 6048, 0x242b }, + { 6054, 0x8000 }, { 6055, 0x40d7 }, { 6062, 0x002e }, +}; +static const Summary16 jisx0212_uni2indx_pageff[6] = { + /* 0xff00 */ + { 6066, 0x0000 }, { 6066, 0x0000 }, { 6066, 0x0000 }, { 6066, 0x0000 }, + { 6066, 0x0000 }, { 6066, 0x4000 }, +}; + +static int +jisx0212_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc >= 0x0000 && wc < 0x0460) + summary = &jisx0212_uni2indx_page00[(wc>>4)]; + else if (wc >= 0x2100 && wc < 0x2130) + summary = &jisx0212_uni2indx_page21[(wc>>4)-0x210]; + else if (wc >= 0x4e00 && wc < 0x9fb0) + summary = &jisx0212_uni2indx_page4e[(wc>>4)-0x4e0]; + else if (wc >= 0xff00 && wc < 0xff60) + summary = &jisx0212_uni2indx_pageff[(wc>>4)-0xff0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = jisx0212_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/jisx0213.h b/libs/libiconv/lib/jisx0213.h new file mode 100644 index 00000000..98468c46 --- /dev/null +++ b/libs/libiconv/lib/jisx0213.h @@ -0,0 +1,5924 @@ +/* + * Copyright (C) 1999-2004 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * JISX0213:2000 + */ + +#ifndef _JISX0213_H +#define _JISX0213_H + +/* JISX0213 plane 1 (= ISO-IR-233) characters are in the range + 0x{21..7E}{21..7E}. + JISX0213 plane 2 (= ISO-IR-229) characters are in the range + 0x{21,23..25,28,2C..2F,6E..7E}{21..7E}. + Together this makes 120 rows of 94 characters. +*/ + +static const unsigned short jisx0213_to_ucs_combining[][2] = { + { 0x304b, 0x309a }, + { 0x304d, 0x309a }, + { 0x304f, 0x309a }, + { 0x3051, 0x309a }, + { 0x3053, 0x309a }, + { 0x30ab, 0x309a }, + { 0x30ad, 0x309a }, + { 0x30af, 0x309a }, + { 0x30b1, 0x309a }, + { 0x30b3, 0x309a }, + { 0x30bb, 0x309a }, + { 0x30c4, 0x309a }, + { 0x30c8, 0x309a }, + { 0x31f7, 0x309a }, + { 0x00e6, 0x0300 }, + { 0x0254, 0x0300 }, + { 0x0254, 0x0301 }, + { 0x028c, 0x0300 }, + { 0x028c, 0x0301 }, + { 0x0259, 0x0300 }, + { 0x0259, 0x0301 }, + { 0x025a, 0x0300 }, + { 0x025a, 0x0301 }, + { 0x02e9, 0x02e5 }, + { 0x02e5, 0x02e9 }, +}; + +static const unsigned short jisx0213_to_ucs_main[120 * 94] = { + /* 0x12121..0x1217E */ + 0x1000, 0x1001, 0x1002, 0x830c, 0x830e, 0x10fb, 0x831a, 0x831b, + 0x831f, 0x8301, 0x109b, 0x109c, 0x00b4, 0x8340, 0x00a8, 0x833e, + 0x83e3, 0x833f, 0x10fd, 0x10fe, 0x109d, 0x109e, 0x1003, 0x2edd, + 0x1005, 0x1006, 0x1007, 0x10fc, 0x0714, 0x0710, 0x830f, 0x833c, + 0x101c, 0x0716, 0x835c, 0x0726, 0x0725, 0x0718, 0x0719, 0x071c, + 0x071d, 0x8308, 0x8309, 0x1014, 0x1015, 0x833b, 0x833d, 0x835b, + 0x835d, 0x1008, 0x1009, 0x100a, 0x100b, 0x100c, 0x100d, 0x100e, + 0x100f, 0x1010, 0x1011, 0x830b, 0x0912, 0x00b1, 0x00d7, 0x00f7, + 0x831d, 0x0960, 0x831c, 0x831e, 0x0966, 0x0967, 0x091e, 0x0934, + 0x0d42, 0x0d40, 0x00b0, 0x0732, 0x0733, 0x0803, 0x83e5, 0x8304, + 0x00a2, 0x00a3, 0x8305, 0x8303, 0x8306, 0x830a, 0x8320, 0x00a7, + 0x0d06, 0x0d05, 0x0ccb, 0x0ccf, 0x0cce, 0x0cc7, + /* 0x12221..0x1227E */ + 0x0cc6, 0x0ca1, 0x0ca0, 0x0cb3, 0x0cb2, 0x0cbd, 0x0cbc, 0x073b, + 0x1012, 0x0892, 0x0890, 0x0891, 0x0893, 0x1013, 0x8307, 0x8302, + 0x830d, 0x835e, 0x1033, 0x1034, 0x1035, 0x103b, 0x103c, 0x10ff, + 0x109f, 0x0908, 0x090b, 0x0986, 0x0987, 0x0982, 0x0983, 0x092a, + 0x0929, 0x0984, 0x0985, 0x098a, 0x098b, 0x0909, 0x0905, 0x0a05, + 0x0a06, 0x0927, 0x0928, 0x00ac, 0x08d2, 0x08d4, 0x0900, 0x0903, + 0x0995, 0x0996, 0x0997, 0x0925, 0x0926, 0x835f, 0x8360, 0x1018, + 0x1019, 0x1016, 0x1017, 0x0920, 0x09a5, 0x0a12, 0x0902, 0x0907, + 0x0961, 0x0952, 0x096a, 0x096b, 0x091a, 0x093d, 0x091d, 0x0935, + 0x092b, 0x092c, 0x0962, 0x0943, 0x0945, 0x0948, 0x0976, 0x0977, + 0x0894, 0x082b, 0x0730, 0x0d6f, 0x0d6d, 0x0d6a, 0x0720, 0x0721, + 0x00b6, 0x0d6e, 0x0d6b, 0x0d6c, 0x0d69, 0x0cef, + /* 0x12321..0x1237E */ + 0x0cb7, 0x0cb6, 0x0cc1, 0x0cc0, 0x0897, 0x0898, 0x0896, 0x0899, + 0x08c4, 0x08e8, 0x08e6, 0x08e7, 0x08e9, 0x0f34, 0x0f35, 0x8310, + 0x8311, 0x8312, 0x8313, 0x8314, 0x8315, 0x8316, 0x8317, 0x8318, + 0x8319, 0x0fbf, 0x0cc9, 0x103d, 0x8246, 0x8245, 0x0ce6, 0x0722, + 0x8321, 0x8322, 0x8323, 0x8324, 0x8325, 0x8326, 0x8327, 0x8328, + 0x8329, 0x832a, 0x832b, 0x832c, 0x832d, 0x832e, 0x832f, 0x8330, + 0x8331, 0x8332, 0x8333, 0x8334, 0x8335, 0x8336, 0x8337, 0x8338, + 0x8339, 0x833a, 0x0913, 0x0835, 0x080f, 0x13cb, 0x0813, 0x0827, + 0x8341, 0x8342, 0x8343, 0x8344, 0x8345, 0x8346, 0x8347, 0x8348, + 0x8349, 0x834a, 0x834b, 0x834c, 0x834d, 0x834e, 0x834f, 0x8350, + 0x8351, 0x8352, 0x8353, 0x8354, 0x8355, 0x8356, 0x8357, 0x8358, + 0x8359, 0x835a, 0x10a0, 0x0713, 0x0ffa, 0x0ffb, + /* 0x12421..0x1247E */ + 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047, 0x1048, + 0x1049, 0x104a, 0x104b, 0x104c, 0x104d, 0x104e, 0x104f, 0x1050, + 0x1051, 0x1052, 0x1053, 0x1054, 0x1055, 0x1056, 0x1057, 0x1058, + 0x1059, 0x105a, 0x105b, 0x105c, 0x105d, 0x105e, 0x105f, 0x1060, + 0x1061, 0x1062, 0x1063, 0x1064, 0x1065, 0x1066, 0x1067, 0x1068, + 0x1069, 0x106a, 0x106b, 0x106c, 0x106d, 0x106e, 0x106f, 0x1070, + 0x1071, 0x1072, 0x1073, 0x1074, 0x1075, 0x1076, 0x1077, 0x1078, + 0x1079, 0x107a, 0x107b, 0x107c, 0x107d, 0x107e, 0x107f, 0x1080, + 0x1081, 0x1082, 0x1083, 0x1084, 0x1085, 0x1086, 0x1087, 0x1088, + 0x1089, 0x108a, 0x108b, 0x108c, 0x108d, 0x108e, 0x108f, 0x1090, + 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x0001, 0x0002, + 0x0003, 0x0004, 0x0005, 0x0000, 0x0000, 0x0000, + /* 0x12521..0x1257E */ + 0x10a1, 0x10a2, 0x10a3, 0x10a4, 0x10a5, 0x10a6, 0x10a7, 0x10a8, + 0x10a9, 0x10aa, 0x10ab, 0x10ac, 0x10ad, 0x10ae, 0x10af, 0x10b0, + 0x10b1, 0x10b2, 0x10b3, 0x10b4, 0x10b5, 0x10b6, 0x10b7, 0x10b8, + 0x10b9, 0x10ba, 0x10bb, 0x10bc, 0x10bd, 0x10be, 0x10bf, 0x10c0, + 0x10c1, 0x10c2, 0x10c3, 0x10c4, 0x10c5, 0x10c6, 0x10c7, 0x10c8, + 0x10c9, 0x10ca, 0x10cb, 0x10cc, 0x10cd, 0x10ce, 0x10cf, 0x10d0, + 0x10d1, 0x10d2, 0x10d3, 0x10d4, 0x10d5, 0x10d6, 0x10d7, 0x10d8, + 0x10d9, 0x10da, 0x10db, 0x10dc, 0x10dd, 0x10de, 0x10df, 0x10e0, + 0x10e1, 0x10e2, 0x10e3, 0x10e4, 0x10e5, 0x10e6, 0x10e7, 0x10e8, + 0x10e9, 0x10ea, 0x10eb, 0x10ec, 0x10ed, 0x10ee, 0x10ef, 0x10f0, + 0x10f1, 0x10f2, 0x10f3, 0x10f4, 0x10f5, 0x10f6, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, + /* 0x12621..0x1267E */ + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, + 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, + 0x0d64, 0x0d60, 0x0d62, 0x0d66, 0x0d61, 0x0d65, 0x0d67, 0x0d63, + 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, + 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, + 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, + 0x03c2, 0x0bf5, 0x0bf6, 0x0bf7, 0x0bf8, 0x0bf9, 0x0bfa, 0x0bfb, + 0x0bfc, 0x0bfd, 0x0bfe, 0x0d16, 0x0d17, 0x1020, 0x0d0e, 0x0d00, + 0x0d01, 0x0d02, 0x0d03, 0x0d68, 0x0cb1, 0x11f0, 0x11f1, 0x11f2, + 0x11f3, 0x11f4, 0x11f5, 0x11f6, 0x11f7, 0x11f8, 0x11f9, 0x000e, + 0x11fa, 0x11fb, 0x11fc, 0x11fd, 0x11fe, 0x11ff, + /* 0x12721..0x1277E */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, + 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, + 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, + 0x042f, 0x0abe, 0x0abf, 0x0ac0, 0x0ac1, 0x0ac2, 0x0ac3, 0x0ac4, + 0x0ac5, 0x0ac6, 0x0ac7, 0x0ac8, 0x0ac9, 0x0aca, 0x0acb, 0x0acc, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, + 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, + 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, + 0x044f, 0x10f7, 0x10f8, 0x10f9, 0x10fa, 0x09da, 0x09db, 0x0853, + 0x0854, 0x0855, 0x0e13, 0x0a18, 0x0b23, 0x0ace, + /* 0x12821..0x1287E */ + 0x0c00, 0x0c02, 0x0c0c, 0x0c10, 0x0c18, 0x0c14, 0x0c1c, 0x0c2c, + 0x0c24, 0x0c34, 0x0c3c, 0x0c01, 0x0c03, 0x0c0f, 0x0c13, 0x0c1b, + 0x0c17, 0x0c23, 0x0c33, 0x0c2b, 0x0c3b, 0x0c4b, 0x0c20, 0x0c2f, + 0x0c28, 0x0c37, 0x0c3f, 0x0c1d, 0x0c30, 0x0c25, 0x0c38, 0x0c42, + 0x1251, 0x1252, 0x1253, 0x1254, 0x1255, 0x1256, 0x1257, 0x1258, + 0x1259, 0x125a, 0x125b, 0x125c, 0x125d, 0x125e, 0x125f, 0x12b1, + 0x12b2, 0x12b3, 0x12b4, 0x12b5, 0x12b6, 0x12b7, 0x12b8, 0x12b9, + 0x12ba, 0x12bb, 0x12bc, 0x12bd, 0x12be, 0x12bf, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0cd0, 0x0cd1, + 0x0cd2, 0x0cd3, 0x073c, 0x0747, 0x0748, 0x0749, 0x01cd, 0x01ce, + 0x01d0, 0x053e, 0x053f, 0x01f8, 0x01f9, 0x01d1, 0x01d2, 0x01d4, + 0x01d6, 0x01d8, 0x01da, 0x01dc, 0x0000, 0x0000, + /* 0x12921..0x1297E */ + 0x07ac, 0x00a0, 0x00a1, 0x00a4, 0x00a6, 0x00a9, 0x00aa, 0x00ab, + 0x00ad, 0x00ae, 0x00af, 0x00b2, 0x00b3, 0x00b7, 0x00b8, 0x00b9, + 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, 0x00c0, 0x00c1, + 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 0x00c9, + 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1, + 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d8, 0x00d9, 0x00da, + 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, 0x00e0, 0x00e1, 0x00e2, + 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, + 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, 0x00f0, 0x00f1, 0x00f2, + 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f8, 0x00f9, 0x00fa, 0x00fb, + 0x00fc, 0x00fd, 0x00fe, 0x00ff, 0x0100, 0x012a, 0x016a, 0x0112, + 0x014c, 0x0101, 0x012b, 0x016b, 0x0113, 0x014d, + /* 0x12A21..0x12A7E */ + 0x0104, 0x02d8, 0x0141, 0x013d, 0x015a, 0x0160, 0x015e, 0x0164, + 0x0179, 0x017d, 0x017b, 0x0105, 0x02db, 0x0142, 0x013e, 0x015b, + 0x02c7, 0x0161, 0x015f, 0x0165, 0x017a, 0x02dd, 0x017e, 0x017c, + 0x0154, 0x0102, 0x0139, 0x0106, 0x010c, 0x0118, 0x011a, 0x010e, + 0x0143, 0x0147, 0x0150, 0x0158, 0x016e, 0x0170, 0x0162, 0x0155, + 0x0103, 0x013a, 0x0107, 0x010d, 0x0119, 0x011b, 0x010f, 0x0111, + 0x0144, 0x0148, 0x0151, 0x0159, 0x016f, 0x0171, 0x0163, 0x02d9, + 0x0108, 0x011c, 0x0124, 0x0134, 0x015c, 0x016c, 0x0109, 0x011d, + 0x0125, 0x0135, 0x015d, 0x016d, 0x0271, 0x028b, 0x027e, 0x0283, + 0x0292, 0x026c, 0x026e, 0x0279, 0x0288, 0x0256, 0x0273, 0x027d, + 0x0282, 0x0290, 0x027b, 0x026d, 0x025f, 0x0272, 0x029d, 0x028e, + 0x0261, 0x014b, 0x0270, 0x0281, 0x0127, 0x0295, + /* 0x12B21..0x12B7E */ + 0x0294, 0x0266, 0x0298, 0x01c2, 0x0253, 0x0257, 0x0284, 0x0260, + 0x0193, 0x0153, 0x0152, 0x0268, 0x0289, 0x0258, 0x0275, 0x0259, + 0x025c, 0x025e, 0x0250, 0x026f, 0x028a, 0x0264, 0x028c, 0x0254, + 0x0251, 0x0252, 0x028d, 0x0265, 0x02a2, 0x02a1, 0x0255, 0x0291, + 0x027a, 0x0267, 0x025a, 0x000f, 0x01fd, 0x0670, 0x0671, 0x0010, + 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0672, + 0x0673, 0x0361, 0x02c8, 0x02cc, 0x02d0, 0x02d1, 0x0306, 0x073f, + 0x030b, 0x0301, 0x0304, 0x0300, 0x030f, 0x030c, 0x0302, 0x02e5, + 0x02e6, 0x02e7, 0x02e8, 0x02e9, 0x0018, 0x0019, 0x0325, 0x032c, + 0x0339, 0x031c, 0x031f, 0x0320, 0x0308, 0x033d, 0x0329, 0x032f, + 0x02de, 0x0324, 0x0330, 0x033c, 0x0334, 0x031d, 0x031e, 0x0318, + 0x0319, 0x032a, 0x033a, 0x033b, 0x0303, 0x031a, + /* 0x12C21..0x12C7E */ + 0x0e76, 0x0e77, 0x0e78, 0x0e79, 0x0e7a, 0x0e7b, 0x0e7c, 0x0e7d, + 0x0e7e, 0x0e7f, 0x0beb, 0x0bec, 0x0bed, 0x0bee, 0x0bef, 0x0bf0, + 0x0bf1, 0x0bf2, 0x0bf3, 0x0bf4, 0x0870, 0x0871, 0x0872, 0x0873, + 0x0874, 0x0875, 0x0876, 0x0877, 0x0878, 0x0879, 0x087a, 0x087b, + 0x0bd0, 0x0bd1, 0x0bd2, 0x0bd3, 0x0bd4, 0x0bd5, 0x0bd6, 0x0bd7, + 0x0bd8, 0x0bd9, 0x0bda, 0x0bdb, 0x0bdc, 0x0bdd, 0x0bde, 0x0bdf, + 0x0be0, 0x0be1, 0x0be2, 0x0be3, 0x0be4, 0x0be5, 0x0be6, 0x0be7, + 0x0be8, 0x0be9, 0x12d0, 0x12d1, 0x12d2, 0x12d3, 0x12d4, 0x12d5, + 0x12d6, 0x12d7, 0x12d8, 0x12d9, 0x12da, 0x12db, 0x12dc, 0x12dd, + 0x12de, 0x12df, 0x12e0, 0x12e1, 0x12e2, 0x12e3, 0x12fa, 0x12e9, + 0x12e5, 0x12ed, 0x12ec, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0751, 0x0742, + /* 0x12D21..0x12D7E */ + 0x0b60, 0x0b61, 0x0b62, 0x0b63, 0x0b64, 0x0b65, 0x0b66, 0x0b67, + 0x0b68, 0x0b69, 0x0b6a, 0x0b6b, 0x0b6c, 0x0b6d, 0x0b6e, 0x0b6f, + 0x0b70, 0x0b71, 0x0b72, 0x0b73, 0x0860, 0x0861, 0x0862, 0x0863, + 0x0864, 0x0865, 0x0866, 0x0867, 0x0868, 0x0869, 0x086a, 0x1349, + 0x1314, 0x1322, 0x134d, 0x1318, 0x1327, 0x1303, 0x1336, 0x1351, + 0x1357, 0x130d, 0x1326, 0x1323, 0x132b, 0x134a, 0x133b, 0x139c, + 0x139d, 0x139e, 0x138e, 0x138f, 0x13c4, 0x13a1, 0x086b, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x137b, 0x101d, + 0x101f, 0x0816, 0x13cd, 0x0821, 0x12a4, 0x12a5, 0x12a6, 0x12a7, + 0x12a8, 0x1231, 0x1232, 0x1239, 0x137e, 0x137d, 0x137c, 0x0000, + 0x0000, 0x0000, 0x092e, 0x0000, 0x0000, 0x0000, 0x0000, 0x091f, + 0x09bf, 0x0000, 0x0000, 0x0000, 0x0e56, 0x0d1e, + /* 0x12E21..0x12E7E */ + 0x2ff1, 0x840b, 0x1402, 0x2e28, 0x2e2f, 0x2e30, 0x2e8d, 0x2ee1, + 0x2efd, 0x2eff, 0x2f03, 0x2f0b, 0x2f60, 0x2f48, 0x2f49, 0x2f56, + 0x2f5f, 0x2f6a, 0x2f6c, 0x2f7e, 0x2f8a, 0x2f94, 0x2f97, 0x8130, + 0x2fc9, 0x2fe0, 0x3001, 0x3002, 0x300e, 0x3018, 0x3027, 0x302e, + 0x3040, 0x303b, 0x3041, 0x3094, 0x30cc, 0x30f2, 0x30d0, 0x30e6, + 0x8131, 0x3106, 0x3103, 0x310b, 0x311e, 0x3135, 0x314a, 0x8132, + 0x3155, 0x3157, 0x14b5, 0x319d, 0x31c3, 0x31ca, 0x31de, 0x31e2, + 0x31ee, 0x3201, 0x14db, 0x3213, 0x3215, 0x3249, 0x3257, 0x3261, + 0x3293, 0x32c8, 0x8133, 0x32cc, 0x32d0, 0x32d6, 0x32db, 0x8134, + 0x32f0, 0x32fb, 0x3300, 0x3307, 0x331c, 0x8135, 0x3361, 0x3363, + 0x337d, 0x3393, 0x339d, 0x33b2, 0x3412, 0x3427, 0x344d, 0x349c, + 0x346b, 0x3474, 0x347f, 0x3488, 0x3496, 0x34a1, + /* 0x12F21..0x12F7E */ + 0x34a9, 0x34c6, 0x34ff, 0x350e, 0x352b, 0x3535, 0x3550, 0x355e, + 0x3581, 0x3586, 0x358e, 0x8136, 0x35ad, 0x35ce, 0x8137, 0x3608, + 0x360e, 0x363b, 0x3649, 0x3676, 0x3666, 0x8138, 0x366f, 0x3671, + 0x3672, 0x3699, 0x369e, 0x36a9, 0x36ac, 0x36b3, 0x36c9, 0x36ca, + 0x370a, 0x923d, 0x3721, 0x372f, 0x3733, 0x3734, 0x3770, 0x3777, + 0x377c, 0x379c, 0x810f, 0x931b, 0x37b8, 0x37c7, 0x37c8, 0x37cf, + 0x37e4, 0x37ed, 0x37f5, 0x37f6, 0x37ff, 0x3809, 0x8110, 0x3861, + 0x3864, 0x8139, 0x387c, 0x3889, 0x389e, 0x813a, 0x38a9, 0x946e, + 0x38d2, 0x38ce, 0x38d4, 0x38da, 0x38e0, 0x38e9, 0x390c, 0x6641, + 0x395d, 0x396d, 0x398b, 0x3992, 0x39a4, 0x39c3, 0x39d2, 0x39dd, + 0x3a13, 0x3a23, 0x3a67, 0x3a6d, 0x3a77, 0x3a7e, 0x3a84, 0x3a9e, + 0x3aa7, 0x3ac4, 0x98bd, 0x3b19, 0x3b25, 0x325d, + /* 0x13021..0x1307E */ + 0x2e9c, 0x3516, 0x3a03, 0x763f, 0x34c0, 0x411b, 0x4328, 0x39f6, + 0x7022, 0x6475, 0x631c, 0x5a50, 0x40aa, 0x43e1, 0x4e25, 0x45ed, + 0x6466, 0x62a6, 0x7bf5, 0x4893, 0x3727, 0x45a1, 0x4271, 0x3b9b, + 0x39d0, 0x667b, 0x78f4, 0x5d62, 0x5dbe, 0x7b8e, 0x4216, 0x5c9f, + 0x68b7, 0x3b89, 0x3eb5, 0x4309, 0x4697, 0x4848, 0x75c7, 0x778d, + 0x474f, 0x2ee5, 0x2f0a, 0x2f4d, 0x2f9d, 0x3049, 0x36f2, 0x3937, + 0x39d4, 0x3a01, 0x3c09, 0x40df, 0x410f, 0x4170, 0x4613, 0x4905, + 0x50ba, 0x554f, 0x5570, 0x59fb, 0x5dad, 0x5def, 0x60c3, 0x640e, + 0x6863, 0x6b02, 0x7055, 0x707a, 0x333b, 0x2e95, 0x2ea5, 0x37df, + 0x60b2, 0x70c1, 0x58ef, 0x2e00, 0x38f1, 0x4ea2, 0x7038, 0x5a32, + 0x6328, 0x628b, 0x7c2f, 0x3141, 0x3370, 0x34bd, 0x34e1, 0x36e0, + 0x39fb, 0x3f15, 0x78f2, 0x4deb, 0x60e4, 0x652d, + /* 0x13121..0x1317E */ + 0x7662, 0x7670, 0x76a0, 0x77fb, 0x340b, 0x33f3, 0x3b87, 0x50cf, + 0x5fbd, 0x6fc2, 0x76e8, 0x336f, 0x7d5c, 0x5aba, 0x2e11, 0x5893, + 0x61fc, 0x4e26, 0x3618, 0x3504, 0x4b1d, 0x651a, 0x7c3b, 0x39e5, + 0x33a9, 0x4d66, 0x54dc, 0x758f, 0x3642, 0x2e91, 0x704b, 0x76f2, + 0x634f, 0x790c, 0x33e1, 0x35b6, 0x3b30, 0x3f71, 0x4620, 0x46f3, + 0x4804, 0x4c38, 0x4cf3, 0x4d29, 0x545b, 0x56c8, 0x5a4e, 0x7834, + 0x62f1, 0x685b, 0x6a60, 0x72ed, 0x4db2, 0x55ab, 0x56ca, 0x79c5, + 0x40a6, 0x6b01, 0x6d8a, 0x75b2, 0x498e, 0x33ad, 0x3186, 0x3712, + 0x3830, 0x3944, 0x3bb4, 0x3ef6, 0x4028, 0x43a9, 0x43f4, 0x4cbf, + 0x4f14, 0x508e, 0x5114, 0x5159, 0x51d5, 0x533f, 0x5e01, 0x6276, + 0x62d1, 0x6597, 0x7060, 0x725b, 0x7d1b, 0x3869, 0x45bc, 0x4c5a, + 0x5525, 0x31f9, 0x392e, 0x3965, 0x3f80, 0x3fdc, + /* 0x13221..0x1327E */ + 0x42bc, 0x45fa, 0x4a2a, 0x4b27, 0x4bb4, 0x538b, 0x5fc1, 0x6956, + 0x7d2c, 0x7d0e, 0x7ec4, 0x3ca1, 0x4c96, 0x637b, 0x3104, 0x3c4b, + 0x41b6, 0x61c6, 0x4876, 0x5261, 0x2e59, 0x2ffa, 0x3378, 0x4069, + 0x4e29, 0x5a4f, 0x77f3, 0x2e0b, 0x3316, 0x2eee, 0x2f55, 0x2f3d, + 0x2fa1, 0x2f73, 0x32a0, 0x33ef, 0x3609, 0x390f, 0x3ac1, 0x3bb6, + 0x3be1, 0x59d1, 0x4687, 0x479c, 0x47b6, 0x4b4c, 0x4cb3, 0x506b, + 0x53c2, 0x598d, 0x59be, 0x5a3c, 0x5b87, 0x62b1, 0x62db, 0x6304, + 0x6377, 0x63ef, 0x63d3, 0x6766, 0x6ab2, 0x3629, 0x6ca8, 0x6fe6, + 0x704e, 0x771e, 0x668a, 0x2fc4, 0x3ce8, 0x4211, 0x5259, 0x553b, + 0x61e5, 0x62bd, 0x66fe, 0x6cc0, 0x76c5, 0x7913, 0x79d5, 0x2ecb, + 0x2f1a, 0x69e3, 0x36de, 0x384a, 0x38ca, 0x3efb, 0x3feb, 0x402a, + 0x4094, 0x4062, 0x41d0, 0x4212, 0x42d0, 0x4539, + /* 0x13321..0x1337E */ + 0x7b41, 0x4666, 0x48b0, 0x4d77, 0x5070, 0x554c, 0x5686, 0x5d75, + 0x62a5, 0x67f9, 0x758b, 0x768e, 0x6c9d, 0x31f1, 0x32be, 0x3916, + 0x34b3, 0x3bb3, 0x3d16, 0x4168, 0x4982, 0x4daf, 0x588d, 0x64cb, + 0x6857, 0x6a72, 0x73a7, 0x7ab8, 0x4d6c, 0x79a8, 0x66d9, 0x37a3, + 0x47ff, 0x66ce, 0x720e, 0x3283, 0x3687, 0x3404, 0x3ed3, 0x42e1, + 0x44b9, 0x483c, 0x4838, 0x4bbb, 0x5372, 0x58ba, 0x5a6b, 0x699a, + 0x69d2, 0x6d6b, 0x6f03, 0x70ed, 0x75a3, 0x7694, 0x7769, 0x3b66, + 0x3cb3, 0x497d, 0x784d, 0x784e, 0x439b, 0x5b20, 0x4a2b, 0x4a7f, + 0x48b6, 0x7c0d, 0x4f5f, 0x3272, 0x359d, 0x4070, 0x42ec, 0x4d3b, + 0x4e07, 0x4ed1, 0x645b, 0x6910, 0x6f44, 0x2e14, 0x7c39, 0x33f6, + 0x491b, 0x4a3a, 0x7784, 0x482a, 0x315c, 0x5ac3, 0x64b2, 0x71dc, + 0x738c, 0x365b, 0x7d28, 0x4822, 0x6305, 0x6431, + /* 0x13421..0x1347E */ + 0x5ca5, 0x3208, 0x62c5, 0x54e6, 0x2e7e, 0x2f83, 0x31a0, 0x3bd2, + 0x320a, 0x32d8, 0x32e7, 0x3dfb, 0x359a, 0x382a, 0x39e6, 0x3b8c, + 0x3b98, 0x3bdb, 0x3e72, 0x3e79, 0x40a3, 0x411f, 0x4163, 0x41be, + 0x43db, 0x4562, 0x47d1, 0x4853, 0x48fa, 0x4b3e, 0x4b53, 0x4c57, + 0x4f22, 0x4f97, 0x4f45, 0x54b0, 0x5518, 0x56e3, 0x570b, 0x5aff, + 0x5ba1, 0x5c21, 0x5de9, 0x5f36, 0x5ff0, 0x609d, 0x6266, 0x639e, + 0x69b3, 0x6acc, 0x6cab, 0x7084, 0x7451, 0x7593, 0x7591, 0x75a2, + 0x7665, 0x77d3, 0x7928, 0x6218, 0x2e38, 0x342b, 0x3cb8, 0x3dcc, + 0x53a9, 0x564c, 0x573c, 0x3ca9, 0x5feb, 0x6d0b, 0x76c1, 0x7811, + 0x7854, 0x7858, 0x2f01, 0x2f0e, 0x3371, 0x359c, 0x3668, 0x37fa, + 0x3947, 0x3b09, 0x3bc4, 0x3c90, 0x3e0c, 0x3e7e, 0x3fcc, 0x43ee, + 0x473a, 0x45d7, 0x45e2, 0x471f, 0x48cb, 0x48c4, + /* 0x13521..0x1357E */ + 0x4a5f, 0x3e30, 0x4bc5, 0x4c17, 0x4c7d, 0x557f, 0x5948, 0x3b63, + 0x5a00, 0x5d00, 0x3fbd, 0x698f, 0x6a18, 0x6cb4, 0x6d77, 0x6ecc, + 0x6f1d, 0x78e2, 0x7a0e, 0x7b3c, 0x2e80, 0x307d, 0x3100, 0x3993, + 0x3b9c, 0x422f, 0x4280, 0x44ec, 0x4b3a, 0x52a0, 0x5591, 0x5947, + 0x5fa9, 0x67fb, 0x6abc, 0x6b70, 0x43ac, 0x63ca, 0x77a0, 0x3409, + 0x3403, 0x35ab, 0x4854, 0x4a58, 0x6a70, 0x5827, 0x4775, 0x7ecd, + 0x3374, 0x3ba2, 0x611a, 0x6650, 0x7006, 0x2e18, 0x2e45, 0x2ec7, + 0x2f11, 0x33ca, 0x3438, 0x3bae, 0x3f13, 0x4025, 0x4551, 0x473d, + 0x4c42, 0x4c72, 0x4ce3, 0x5078, 0x5403, 0x5a76, 0x5aae, 0x5b08, + 0x5d1a, 0x5cfe, 0x5d66, 0x45e7, 0x525b, 0x33bb, 0x3c45, 0x3de8, + 0x42d2, 0x42e0, 0x4319, 0x4e20, 0x665a, 0x6a31, 0x6ddd, 0x72f8, + 0x4f01, 0x59a6, 0x7b5a, 0x2ea8, 0x2eab, 0x2eac, + /* 0x13621..0x1367E */ + 0x2f9b, 0x2fa0, 0x30d1, 0x3147, 0x5af6, 0x3171, 0x31f6, 0x3354, + 0x3321, 0x337f, 0x33eb, 0x35ac, 0x3883, 0x3ce1, 0x3f37, 0x3f4a, + 0x402f, 0x4050, 0x406d, 0x431f, 0x4559, 0x4a4b, 0x4cc1, 0x52c2, + 0x52ed, 0x57ef, 0x60f8, 0x6105, 0x6208, 0x654e, 0x70f7, 0x73e1, + 0x77ff, 0x7957, 0x7a5a, 0x2ef0, 0x31dd, 0x3c2d, 0x4681, 0x496d, + 0x3c40, 0x46f2, 0x4975, 0x5389, 0x4850, 0x5c81, 0x30c5, 0x32e4, + 0x3747, 0x3dfe, 0x7326, 0x45a4, 0x4b23, 0x4b3d, 0x5434, 0x5981, + 0x59bd, 0x5b4b, 0x5dca, 0x62b9, 0x63cc, 0x687f, 0x695f, 0x6b39, + 0x6fd1, 0x71d1, 0x341f, 0x7280, 0x2e5d, 0x3036, 0x33e5, 0x333a, + 0x52d7, 0x5396, 0x57e9, 0x62e6, 0x6eaf, 0x79c6, 0x79c8, 0x79d2, + 0x3177, 0x411a, 0x665e, 0x35b0, 0x5a7a, 0x3076, 0x3bd3, 0x7047, + 0x7685, 0x2e32, 0x4adb, 0x71e7, 0x3c51, 0x3c48, + /* 0x13721..0x1377E */ + 0x4398, 0x5a9f, 0x4c93, 0x7774, 0x6f61, 0x5aaa, 0x518a, 0x7688, + 0x5c82, 0x4817, 0x5e70, 0x4851, 0x736c, 0x32f2, 0x341b, 0x65ab, + 0x6a13, 0x5fa4, 0x6ecd, 0x70e1, 0x3366, 0x6888, 0x5941, 0x2fc2, + 0x30be, 0x3211, 0x3144, 0x3553, 0x372d, 0x53ea, 0x378b, 0x3951, + 0x3f62, 0x3f84, 0x4075, 0x4176, 0x4167, 0x41a9, 0x43b2, 0x443a, + 0x456c, 0x466f, 0x4842, 0x4e13, 0x5566, 0x5a3d, 0x5cfb, 0x5d4c, + 0x5d99, 0x5e4b, 0x5f6b, 0x630e, 0x634a, 0x66cd, 0x6a08, 0x6a63, + 0x6b66, 0x6efd, 0x781a, 0x7d8f, 0x62b8, 0x6fce, 0x7be8, 0x3287, + 0x421f, 0x4483, 0x4fc0, 0x7699, 0x4841, 0x3091, 0x4b20, 0x4c7a, + 0x4f54, 0x5a74, 0x5d50, 0x6840, 0x6a23, 0x4708, 0x2ef6, 0x3039, + 0x3026, 0x3065, 0x317c, 0x3238, 0x3263, 0x35a7, 0x370f, 0x3805, + 0x3acc, 0x3efa, 0x41b2, 0x41f8, 0x42f3, 0x4372, + /* 0x13821..0x1387E */ + 0x491c, 0x4a29, 0x527d, 0x52ac, 0x532e, 0x5814, 0x586f, 0x5d79, + 0x570c, 0x60a9, 0x698b, 0x6b19, 0x6ce2, 0x6ed2, 0x7063, 0x7375, + 0x767a, 0x7855, 0x7a13, 0x7e78, 0x3143, 0x339f, 0x33b3, 0x3e7b, + 0x3f26, 0x4e1b, 0x4e90, 0x5384, 0x53fe, 0x5d43, 0x6237, 0x6a00, + 0x6afa, 0x7650, 0x2e4e, 0x300b, 0x33e4, 0x347c, 0x36fa, 0x39d1, + 0x3b64, 0x3df1, 0x3eab, 0x3f27, 0x4238, 0x4545, 0x47af, 0x4e56, + 0x52d0, 0x5cca, 0x68b4, 0x60a1, 0x60e1, 0x63f0, 0x664e, 0x6a87, + 0x6de8, 0x7237, 0x76c7, 0x7867, 0x7f13, 0x2e94, 0x2e92, 0x2f0d, + 0x3348, 0x3449, 0x343e, 0x3a2f, 0x3f8c, 0x3fa1, 0x409f, 0x48a7, + 0x4a8e, 0x545a, 0x5881, 0x6a9e, 0x6aa4, 0x6b77, 0x7190, 0x2e5e, + 0x7bc9, 0x2ea4, 0x2f7c, 0x2faf, 0x3019, 0x3016, 0x3149, 0x316c, + 0x329f, 0x32b9, 0x32fe, 0x339a, 0x33e3, 0x3411, + /* 0x13921..0x1397E */ + 0x340e, 0x3589, 0x3751, 0x37a2, 0x397d, 0x3b54, 0x3b5d, 0x3b8f, + 0x3de5, 0x3de7, 0x3df7, 0x3e78, 0x3e83, 0x3e9a, 0x3eb7, 0x3f18, + 0x4052, 0x414c, 0x4297, 0x42d8, 0x43a7, 0x453b, 0x4602, 0x4643, + 0x46f4, 0x476d, 0x4821, 0x4897, 0x49cb, 0x4c5f, 0x4d2a, 0x4d69, + 0x4e2f, 0x4e9d, 0x5532, 0x5687, 0x586c, 0x5a3f, 0x5ce0, 0x5d05, + 0x5d18, 0x5d5e, 0x5db1, 0x6015, 0x6003, 0x60af, 0x60b1, 0x6154, + 0x618f, 0x622a, 0x6352, 0x684c, 0x6861, 0x6b1b, 0x6ca2, 0x6cfc, + 0x70ca, 0x7175, 0x7271, 0x583f, 0x72fc, 0x75a4, 0x764d, 0x7805, + 0x7999, 0x7ad8, 0x7d3b, 0x325b, 0x32ab, 0x33f7, 0x3408, 0x38d5, + 0x42f7, 0x4fe0, 0x6c6a, 0x6f5f, 0x7eb9, 0x314b, 0x323b, 0x344a, + 0x36fd, 0x5a40, 0x7177, 0x7d60, 0x7ed2, 0x5344, 0x4f09, 0x6170, + 0x5511, 0x3ffd, 0x40da, 0x7aa8, 0x52db, 0x6fbc, + /* 0x13A21..0x13A7E */ + 0x4b64, 0x7803, 0x2eca, 0x36f0, 0x3764, 0x38be, 0x3a5a, 0x4068, + 0x41c7, 0x460f, 0x4606, 0x4839, 0x48b1, 0x4df7, 0x55d5, 0x5d3a, + 0x626e, 0x7b42, 0x2e9b, 0x2f50, 0x33c9, 0x3506, 0x3d6f, 0x3de6, + 0x3dee, 0x47fb, 0x4c99, 0x5473, 0x5802, 0x6a50, 0x7396, 0x68df, + 0x3750, 0x3ea7, 0x432b, 0x30b5, 0x30ac, 0x318d, 0x4700, 0x34c9, + 0x385e, 0x39bb, 0x3bb0, 0x3f69, 0x424d, 0x43a1, 0x483d, 0x4b73, + 0x4e08, 0x507d, 0x71c7, 0x5280, 0x5815, 0x5826, 0x596d, 0x458e, + 0x5d30, 0x63dc, 0x68c1, 0x6f09, 0x769b, 0x3264, 0x3728, 0x4750, + 0x5f6a, 0x6ca1, 0x31b4, 0x3742, 0x762a, 0x383a, 0x498a, 0x60b4, + 0x34b2, 0x3d0e, 0x37fc, 0x5895, 0x7dfa, 0x2f5c, 0x324a, 0x348b, + 0x443e, 0x4628, 0x4714, 0x47f5, 0x5a84, 0x5b56, 0x5d22, 0x732f, + 0x485c, 0x7bad, 0x5b39, 0x3319, 0x318a, 0x3237, + /* 0x13B21..0x13B7E */ + 0x3bdf, 0x42f6, 0x44ae, 0x44e6, 0x472d, 0x4bba, 0x65a9, 0x76d1, + 0x5690, 0x7bd6, 0x434c, 0x7306, 0x7bab, 0x56bf, 0x4652, 0x2e09, + 0x3098, 0x33c2, 0x3c71, 0x40e8, 0x4492, 0x4563, 0x485f, 0x51e6, + 0x53ca, 0x5523, 0x5b97, 0x5e82, 0x6695, 0x6b83, 0x6cdb, 0x7178, + 0x7910, 0x45ac, 0x46ab, 0x4b8b, 0x2ed5, 0x2ed4, 0x2f3a, 0x2f7f, + 0x323a, 0x33f8, 0x33f2, 0x35e3, 0x36db, 0x38eb, 0x39cb, 0x39c9, + 0x39ff, 0x3b50, 0x3c4d, 0x3e02, 0x3e2b, 0x3fd7, 0x401d, 0x4307, + 0x452f, 0x3b5c, 0x45af, 0x45bd, 0x45e8, 0x479d, 0x4b62, 0x4b7b, + 0x4c0f, 0x5345, 0x5949, 0x59c1, 0x5cf8, 0x5d19, 0x5d2b, 0x60a2, + 0x6102, 0x61f3, 0x6996, 0x6a5e, 0x6a69, 0x6a66, 0x6a8c, 0x6aee, + 0x6cc7, 0x6cdc, 0x76cc, 0x78fc, 0x4b6f, 0x2e8b, 0x2f3c, 0x2f8d, + 0x3150, 0x3b57, 0x3bfa, 0x4148, 0x4301, 0x4642, + /* 0x13C21..0x13C7E */ + 0x4b21, 0x4ecb, 0x4cbb, 0x523e, 0x54bd, 0x55d4, 0x58c1, 0x593a, + 0x600c, 0x6033, 0x61ea, 0x6494, 0x6f9e, 0x4c50, 0x7e7f, 0x3f0f, + 0x6b58, 0x7d2b, 0x5afa, 0x6ef8, 0x3b8d, 0x76eb, 0x2e03, 0x33f1, + 0x37f7, 0x3931, 0x3ac9, 0x3ba4, 0x4089, 0x4e7f, 0x4f06, 0x55be, + 0x6cea, 0x3b9f, 0x6500, 0x5be0, 0x3072, 0x47f4, 0x629d, 0x3c61, + 0x654a, 0x5e1e, 0x620e, 0x3199, 0x3c04, 0x4368, 0x6d66, 0x459c, + 0x516e, 0x593e, 0x5d17, 0x6005, 0x6b1d, 0x6eca, 0x706e, 0x66c7, + 0x70aa, 0x301f, 0x32fa, 0x3c3a, 0x4753, 0x507c, 0x5235, 0x714c, + 0x71c8, 0x732b, 0x62e5, 0x3bc2, 0x3f31, 0x40f9, 0x2e3b, 0x33d6, + 0x3b88, 0x424b, 0x4731, 0x4b8a, 0x52e9, 0x53e0, 0x5a2e, 0x616b, + 0x6da3, 0x7152, 0x7996, 0x3112, 0x33d7, 0x346a, 0x3bff, 0x4388, + 0x4a39, 0x5dac, 0x7700, 0x36da, 0x33ce, 0x3468, + /* 0x13D21..0x13D7E */ + 0x3b97, 0x3c31, 0x3dde, 0x2fee, 0x4101, 0x42fe, 0x4d32, 0x59c0, + 0x59cb, 0x5d42, 0x5e4d, 0x5fd2, 0x61ed, 0x621f, 0x6490, 0x6846, + 0x6972, 0x6b90, 0x6e74, 0x6f2f, 0x7031, 0x714b, 0x716c, 0x76c6, + 0x719c, 0x2ec0, 0x2f4f, 0x3145, 0x3341, 0x3f93, 0x420e, 0x47d4, + 0x4c41, 0x4e0b, 0x5363, 0x5e26, 0x71cd, 0x7283, 0x33d4, 0x3919, + 0x3bbf, 0x4dd1, 0x595d, 0x5e2e, 0x5c9b, 0x387e, 0x519f, 0x31fa, + 0x6853, 0x6ff0, 0x2fca, 0x3cfb, 0x4625, 0x57ac, 0x5ae3, 0x621c, + 0x79ff, 0x31c6, 0x3faa, 0x45ec, 0x496f, 0x4b89, 0x4df3, 0x4e96, + 0x4f64, 0x56fe, 0x5d14, 0x3de1, 0x7075, 0x7187, 0x7806, 0x31e6, + 0x321d, 0x4240, 0x4691, 0x46d9, 0x4e1a, 0x3eb6, 0x5dd2, 0x5f72, + 0x46f8, 0x65af, 0x65f7, 0x6af8, 0x32a9, 0x33d9, 0x3973, 0x3e8f, + 0x3f90, 0x4055, 0x72e4, 0x7664, 0x30b7, 0x311f, + /* 0x13E21..0x13E7E */ + 0x32dd, 0x3320, 0x3347, 0x33ec, 0x34e8, 0x3546, 0x3531, 0x3617, + 0x3968, 0x39be, 0x3a3c, 0x3bb5, 0x3c06, 0x3c0f, 0x3c11, 0x3c1a, + 0x3e84, 0x3e8a, 0x3ee0, 0x3f70, 0x427f, 0x4284, 0x42db, 0x438c, + 0x4377, 0x4607, 0x460c, 0x462d, 0x4676, 0x477e, 0x48a2, 0x4a1f, + 0x4a35, 0x4cbc, 0x4d88, 0x4e09, 0x4e58, 0x513c, 0x5126, 0x5167, + 0x55c7, 0x5701, 0x585d, 0x5901, 0x5965, 0x59f0, 0x5ae0, 0x5b11, + 0x5ca7, 0x5d39, 0x6096, 0x63d6, 0x648b, 0x6549, 0x685d, 0x68f3, + 0x6a1f, 0x6a3c, 0x6a54, 0x6a73, 0x6c61, 0x6cde, 0x71a4, 0x7266, + 0x737e, 0x7418, 0x769c, 0x7798, 0x2e0a, 0x2e08, 0x2e1e, 0x2e57, + 0x3197, 0x3270, 0x37ce, 0x3834, 0x38cc, 0x3b22, 0x3e38, 0x40c5, + 0x44fe, 0x4761, 0x4756, 0x4d44, 0x52b6, 0x5573, 0x5a63, 0x64b8, + 0x6b72, 0x71b8, 0x7320, 0x3631, 0x37f4, 0x78fe, + /* 0x13F21..0x13F7E */ + 0x42ed, 0x490d, 0x4b96, 0x51ed, 0x5e54, 0x6077, 0x6272, 0x69e6, + 0x78df, 0x6755, 0x6fb1, 0x3c3b, 0x2f38, 0x2fe1, 0x2fb5, 0x3507, + 0x3a20, 0x3bdd, 0x3be9, 0x3fc3, 0x414e, 0x432f, 0x45b0, 0x464b, + 0x48ee, 0x499b, 0x4d78, 0x4df1, 0x5533, 0x55b9, 0x571f, 0x595e, + 0x59e6, 0x5d33, 0x61e3, 0x62af, 0x65aa, 0x69aa, 0x6a3a, 0x6eab, + 0x6f9b, 0x7032, 0x71dd, 0x7707, 0x2eba, 0x2ec1, 0x3203, 0x3875, + 0x38ec, 0x3c0b, 0x551a, 0x3c3d, 0x614e, 0x6a0a, 0x6fc5, 0x7663, + 0x776d, 0x5b25, 0x6acf, 0x7808, 0x7162, 0x36f3, 0x33a8, 0x7017, + 0x3439, 0x3782, 0x3e25, 0x43a8, 0x4c34, 0x508a, 0x5761, 0x5c8b, + 0x5fe0, 0x6870, 0x7042, 0x7154, 0x7310, 0x7318, 0x768f, 0x545e, + 0x7ac4, 0x3d07, 0x3d69, 0x4570, 0x47a2, 0x6da8, 0x76db, 0x436e, + 0x4749, 0x4919, 0x63c5, 0x7817, 0x76c0, 0x68fe, + /* 0x14021..0x1407E */ + 0x4f84, 0x447a, 0x3bf8, 0x2e16, 0x502c, 0x555d, 0x462f, 0x31c4, + 0x3236, 0x32e2, 0x39d3, 0x3f81, 0x4027, 0x4210, 0x453f, 0x4574, + 0x461f, 0x4674, 0x48f2, 0x4816, 0x4b63, 0x4e05, 0x5272, 0x551f, + 0x56db, 0x5cbe, 0x6056, 0x38f0, 0x68fd, 0x697f, 0x6aa0, 0x6a93, + 0x6acb, 0x701d, 0x7192, 0x7752, 0x7759, 0x4589, 0x5a0e, 0x6106, + 0x76bb, 0x3e2d, 0x40dc, 0x421a, 0x45a5, 0x4614, 0x4790, 0x57f3, + 0x5a4d, 0x5c4d, 0x5e3e, 0x610a, 0x6cac, 0x6d64, 0x6de1, 0x6e5f, + 0x58a9, 0x3207, 0x42d9, 0x43a5, 0x4442, 0x4298, 0x6a2d, 0x5a83, + 0x5bc0, 0x6aac, 0x76ea, 0x5d76, 0x620c, 0x6749, 0x2ed9, 0x3148, + 0x3343, 0x3360, 0x3ba3, 0x3c02, 0x3c16, 0x3ddd, 0x4226, 0x4247, + 0x44b0, 0x4813, 0x4834, 0x4cc9, 0x4d45, 0x4d17, 0x47d3, 0x4f5c, + 0x514e, 0x517d, 0x45cb, 0x5a7f, 0x5bad, 0x5dda, + /* 0x14121..0x1417E */ + 0x5e4a, 0x5fa8, 0x617a, 0x621b, 0x6239, 0x65a6, 0x6a6e, 0x6cce, + 0x6df5, 0x7078, 0x7077, 0x72ad, 0x7291, 0x7583, 0x7bae, 0x324d, + 0x3584, 0x4f38, 0x5136, 0x3168, 0x5985, 0x5e55, 0x61b3, 0x5cce, + 0x364c, 0x3851, 0x3ca8, 0x43aa, 0x46fe, 0x46fd, 0x495a, 0x52d9, + 0x558f, 0x558e, 0x590e, 0x5956, 0x59df, 0x5c97, 0x5d20, 0x5d44, + 0x6607, 0x6a34, 0x763b, 0x7061, 0x7f20, 0x30e7, 0x3275, 0x33cc, + 0x33e2, 0x3009, 0x35aa, 0x38ee, 0x394f, 0x523d, 0x3b8b, 0x3c64, + 0x331d, 0x40e3, 0x40f3, 0x435c, 0x4383, 0x433f, 0x43bb, 0x44cd, + 0x45e9, 0x46f9, 0x3de3, 0x49cd, 0x49fd, 0x4f15, 0x51e5, 0x2e89, + 0x55e9, 0x56f8, 0x5a93, 0x5cdf, 0x5dcf, 0x5d9c, 0x6061, 0x6349, + 0x6358, 0x646c, 0x64bc, 0x65fb, 0x68c5, 0x6d70, 0x7001, 0x706d, + 0x7397, 0x771c, 0x7a12, 0x30cf, 0x3897, 0x418e, + /* 0x14221..0x1427E */ + 0x61d3, 0x6535, 0x6d08, 0x7020, 0x2fc3, 0x3074, 0x3247, 0x3373, + 0x406f, 0x4349, 0x475f, 0x4e2c, 0x6db3, 0x701f, 0x2fd7, 0x3c5e, + 0x6cca, 0x45cf, 0x5d9a, 0x3352, 0x6896, 0x3176, 0x43c3, 0x3b58, + 0x3b6b, 0x3c0a, 0x440d, 0x4751, 0x705c, 0x2ed6, 0x391a, 0x392a, + 0x4c70, 0x6a51, 0x353e, 0x3815, 0x39a5, 0x40f0, 0x4253, 0x47c1, + 0x6235, 0x4955, 0x7640, 0x79c4, 0x7a28, 0x2f53, 0x3806, 0x3bfe, + 0x6010, 0x3cb1, 0x3e2f, 0x3f85, 0x4020, 0x414b, 0x4234, 0x46ff, + 0x4cf0, 0x4ede, 0x60ce, 0x617f, 0x62d4, 0x688b, 0x6cb8, 0x7000, + 0x702e, 0x768a, 0x7edb, 0x7bdb, 0x2ee3, 0x33f0, 0x3927, 0x5b2c, + 0x718d, 0x784c, 0x7df9, 0x4edd, 0x5027, 0x3353, 0x3544, 0x3b85, + 0x4258, 0x429e, 0x42d3, 0x4ca2, 0x4fef, 0x5422, 0x6a17, 0x7438, + 0x4fc1, 0x6afe, 0x6338, 0x31e7, 0x66f8, 0x33ea, + /* 0x14321..0x1437E */ + 0x33e9, 0x2f46, 0x7054, 0x6fb0, 0x396a, 0x6131, 0x3dfd, 0x5aea, + 0x6fbf, 0x48da, 0x6c37, 0x52f8, 0x7c48, 0x4a3d, 0x6ab0, 0x2e39, + 0x3358, 0x3606, 0x3766, 0x42c5, 0x43a2, 0x45e6, 0x4b4e, 0x4de1, + 0x4e5b, 0x50ad, 0x57ed, 0x5aef, 0x5baa, 0x5dbb, 0x603d, 0x60c6, + 0x66cb, 0x6a95, 0x735b, 0x36e3, 0x38c7, 0x3f3e, 0x45ad, 0x4696, + 0x4a80, 0x4bb5, 0x5537, 0x6ac7, 0x3024, 0x57e5, 0x3730, 0x3f1b, + 0x4065, 0x467a, 0x4c60, 0x55f4, 0x5a1a, 0x5f6e, 0x61f4, 0x6718, + 0x7045, 0x79b3, 0x5bc9, 0x555c, 0x5af9, 0x5b51, 0x64c4, 0x7010, + 0x59e9, 0x5a92, 0x6336, 0x3ae1, 0x5740, 0x2e2d, 0x2ef2, 0x3b99, + 0x3fe0, 0x42bd, 0x463c, 0x47f1, 0x4ce8, 0x666b, 0x6877, 0x6a3b, + 0x714e, 0x72f3, 0x79d0, 0x4a17, 0x5026, 0x532a, 0x62e7, 0x6457, + 0x6caf, 0x2e01, 0x3146, 0x31cb, 0x358b, 0x3bf5, + /* 0x14421..0x1447E */ + 0x3e16, 0x3e33, 0x3e81, 0x3f14, 0x3f35, 0x3f6b, 0x3fb4, 0x41f2, + 0x4311, 0x46a2, 0x471d, 0x4f6e, 0x5252, 0x553a, 0x573a, 0x6074, + 0x6139, 0x6178, 0x6776, 0x6abf, 0x6adc, 0x6d85, 0x6df3, 0x729a, + 0x7577, 0x7802, 0x7ce5, 0x32c5, 0x4357, 0x56f4, 0x4715, 0x4c88, + 0x53cd, 0x6cc3, 0x73ae, 0x7673, 0x4d25, 0x389c, 0x490e, 0x49cc, + 0x6ffd, 0x739a, 0x55db, 0x701a, 0x385a, 0x4802, 0x43b4, 0x49fb, + 0x2f43, 0x4f2c, 0x47d8, 0x6fbb, 0x6526, 0x5db4, 0x7354, 0x493f, + 0x4f70, 0x376a, 0x38f7, 0x3b2c, 0x5d2c, 0x522a, 0x340a, 0x71e3, + 0x7db4, 0x2ead, 0x2f4e, 0x305c, 0x3075, 0x3243, 0x6c9e, 0x3448, + 0x3824, 0x3b9a, 0x3e1d, 0x3e95, 0x3ead, 0x3ef7, 0x3f1f, 0x408c, + 0x42b5, 0x433a, 0x43d0, 0x48af, 0x4c40, 0x5887, 0x598e, 0x5a0b, + 0x5de0, 0x6247, 0x6a02, 0x6ae6, 0x6e44, 0x7013, + /* 0x14521..0x1457E */ + 0x70b8, 0x712d, 0x71d8, 0x7f0e, 0x4ce5, 0x4458, 0x44e2, 0x4575, + 0x4ef4, 0x5684, 0x5b1b, 0x7069, 0x73d1, 0x4eba, 0x34f2, 0x3fb9, + 0x44a4, 0x6f4d, 0x6fed, 0x7244, 0x3178, 0x386b, 0x3929, 0x3c55, + 0x3e97, 0x4dfb, 0x5e8f, 0x551c, 0x6cbc, 0x6ee2, 0x785b, 0x50b9, + 0x2f1d, 0x4bbf, 0x4fb1, 0x5530, 0x76fb, 0x314e, 0x3410, 0x3835, + 0x3857, 0x39ac, 0x3c60, 0x3f92, 0x4597, 0x475c, 0x4e21, 0x567b, + 0x63df, 0x6ced, 0x7014, 0x70fd, 0x734d, 0x5825, 0x583a, 0x32aa, + 0x3ea6, 0x371f, 0x3974, 0x4012, 0x3012, 0x315a, 0x31ac, 0x31cd, + 0x3200, 0x3510, 0x3854, 0x3858, 0x3957, 0x3b95, 0x3cf6, 0x3d8b, + 0x40bc, 0x4295, 0x442d, 0x4771, 0x4843, 0x48bc, 0x48df, 0x56d7, + 0x4dd8, 0x4e6f, 0x4d9b, 0x506f, 0x51c8, 0x3f53, 0x55d8, 0x5977, + 0x5b49, 0x5b54, 0x5b52, 0x5cd6, 0x5d71, 0x3230, + /* 0x14621..0x1467E */ + 0x6463, 0x6569, 0x65e4, 0x6a0e, 0x6b04, 0x6c46, 0x6e0f, 0x7003, + 0x700f, 0x7419, 0x7676, 0x782d, 0x7a30, 0x75d8, 0x30cd, 0x32d5, + 0x340c, 0x3802, 0x3c0e, 0x41a7, 0x449e, 0x4d1e, 0x57b3, 0x5ae5, + 0x60f4, 0x6404, 0x7053, 0x7285, 0x3ce0, 0x7d07, 0x333f, 0x3f97, + 0x3fb3, 0x4d9c, 0x5279, 0x5763, 0x59bf, 0x5be4, 0x4bd2, 0x52ec, + 0x6aad, 0x4803, 0x4a61, 0x31f8, 0x5a81, 0x4934, 0x3c4a, 0x7cf6, + 0x62eb, 0x3bc5, 0x7149, 0x501e, 0x3678, 0x3c6f, 0x40c7, 0x4566, + 0x4c8c, 0x6c5a, 0x7041, 0x7813, 0x3451, 0x46c7, 0x720d, 0x3948, + 0x70a3, 0x3185, 0x2e4d, 0x31ea, 0x6599, 0x6b0e, 0x5058, 0x437a, + 0x734b, 0x4962, 0x79b4, 0x5e04, 0x5577, 0x3357, 0x4960, 0x6edf, + 0x76e3, 0x4c5d, 0x2e8c, 0x3c3c, 0x3f10, 0x6fe9, 0x3302, 0x6cd1, + 0x6089, 0x6679, 0x3eff, 0x45e5, 0x2e73, 0x3165, + /* 0x14721..0x1477E */ + 0x3982, 0x3c3f, 0x77ee, 0x2efb, 0x398a, 0x3fcd, 0x6a8d, 0x4fe1, + 0x59b0, 0x5962, 0x3be7, 0x6471, 0x532b, 0x51b1, 0x3e74, 0x3ff5, + 0x437b, 0x449a, 0x51c3, 0x5c98, 0x2e43, 0x3efc, 0x2e4b, 0x37dc, + 0x36a2, 0x40a9, 0x4fc3, 0x5d0d, 0x60fd, 0x6133, 0x61bf, 0x6fb2, + 0x6997, 0x66a4, 0x3df4, 0x428a, 0x44ad, 0x6987, 0x4777, 0x4ce2, + 0x4d3e, 0x5436, 0x5834, 0x3a46, 0x5f75, 0x62ad, 0x79ac, 0x2ff3, + 0x3ec3, 0x42dd, 0x4392, 0x4557, 0x476f, 0x56c3, 0x524c, 0x60cc, + 0x60ba, 0x6f29, 0x714d, 0x300d, 0x37f9, 0x3a92, 0x4885, 0x4973, + 0x5164, 0x52fd, 0x6cb7, 0x38f2, 0x6ce0, 0x766a, 0x7019, 0x677f, + 0x59e4, 0x57e7, 0x6429, 0x2f2f, 0x3265, 0x335a, 0x42cd, 0x47cf, + 0x4cca, 0x567d, 0x5b94, 0x5c95, 0x6236, 0x6584, 0x6feb, 0x46dd, + 0x4f20, 0x5206, 0x5e1b, 0x63ab, 0x79c1, 0x7ea6, + /* 0x14821..0x1487E */ + 0x31fd, 0x5bb1, 0x5872, 0x5bb8, 0x6087, 0x5b48, 0x4ae8, 0x3e61, + 0x608c, 0x5551, 0x5560, 0x316b, 0x7262, 0x4e8c, 0x567a, 0x7197, + 0x7aea, 0x2f10, 0x5f70, 0x429c, 0x5b4f, 0x75a5, 0x7ce9, 0x367a, + 0x3859, 0x66e4, 0x76bc, 0x2f34, 0x3224, 0x334a, 0x33cd, 0x33db, + 0x3e06, 0x442c, 0x4591, 0x477f, 0x4c3e, 0x4c4e, 0x5248, 0x52af, + 0x53ed, 0x5554, 0x5e41, 0x622c, 0x65e9, 0x6ca9, 0x5bc4, 0x71c6, + 0x5169, 0x7812, 0x78ef, 0x433d, 0x4669, 0x556a, 0x56e4, 0x58d0, + 0x6543, 0x66ee, 0x332a, 0x3351, 0x3426, 0x3983, 0x3e87, 0x3f7c, + 0x40b2, 0x4249, 0x4279, 0x42ab, 0x4590, 0x4bd4, 0x4ccc, 0x55b2, + 0x56ae, 0x5891, 0x59d8, 0x5dcb, 0x5f77, 0x60a5, 0x68ab, 0x6ab9, + 0x6cbb, 0x707f, 0x775e, 0x78db, 0x4a0b, 0x5c38, 0x3099, 0x3c3e, + 0x3fae, 0x4787, 0x4bd8, 0x5435, 0x5709, 0x5f8e, + /* 0x14921..0x1497E */ + 0x7f3b, 0x47ca, 0x5a17, 0x3339, 0x558b, 0x7aed, 0x3f66, 0x619d, + 0x63f1, 0x6098, 0x3f3c, 0x3fc5, 0x5562, 0x5b46, 0x703c, 0x4867, + 0x39eb, 0x3a9b, 0x5d10, 0x567e, 0x6b2c, 0x2ff5, 0x3f6a, 0x4a19, + 0x4c37, 0x4f02, 0x54e2, 0x5968, 0x6868, 0x6a55, 0x6c79, 0x3edf, + 0x43cf, 0x55c5, 0x59d2, 0x62d7, 0x7328, 0x72f2, 0x649c, 0x66ed, + 0x7c2d, 0x34c1, 0x3f6c, 0x458c, 0x4d5c, 0x5015, 0x6ca7, 0x6cd3, + 0x783b, 0x454f, 0x54f6, 0x2e0d, 0x2ed8, 0x37e0, 0x392b, 0x3a66, + 0x3bcc, 0x31a8, 0x3e03, 0x3e9c, 0x4016, 0x4276, 0x4577, 0x45a7, + 0x466e, 0x4d6e, 0x5236, 0x5b26, 0x6150, 0x619a, 0x6299, 0x6b5c, + 0x6ca0, 0x6ce6, 0x6d74, 0x761c, 0x7644, 0x2fae, 0x44ab, 0x4b66, + 0x621e, 0x6461, 0x656a, 0x70e8, 0x3c01, 0x4953, 0x78a8, 0x647a, + 0x6557, 0x2f0f, 0x326f, 0x3fa9, 0x3e45, 0x470d, + /* 0x14A21..0x14A7E */ + 0x598f, 0x6179, 0x6907, 0x6986, 0x4df5, 0x3f17, 0x4255, 0x4cb8, + 0x2ecf, 0x5269, 0x7b92, 0x3206, 0x343b, 0x3674, 0x38b3, 0x41a4, + 0x426e, 0x511a, 0x396e, 0x5c89, 0x5cde, 0x5d1b, 0x76f0, 0x4587, + 0x605e, 0x2e19, 0x2f75, 0x3175, 0x3840, 0x3e63, 0x3e73, 0x3f0a, + 0x47c4, 0x2e26, 0x653d, 0x7589, 0x765b, 0x5c73, 0x7801, 0x30fb, + 0x38c1, 0x5656, 0x58a7, 0x3225, 0x57a5, 0x6511, 0x5b86, 0x304f, + 0x3909, 0x5247, 0x5bc7, 0x5de8, 0x6fba, 0x6fd4, 0x704d, 0x2fbf, + 0x32c9, 0x3a29, 0x3f01, 0x77ad, 0x2fdd, 0x6217, 0x72ea, 0x3703, + 0x4355, 0x4b69, 0x552b, 0x68dc, 0x6f14, 0x5a42, 0x32df, 0x3893, + 0x4155, 0x420a, 0x46ae, 0x4bcd, 0x5c3f, 0x63e9, 0x3023, 0x2ff8, + 0x3305, 0x3446, 0x3831, 0x3949, 0x3b9d, 0x3cf0, 0x3cef, 0x3d29, + 0x3e96, 0x42b1, 0x4367, 0x453e, 0x45b9, 0x470b, + /* 0x14B21..0x14B7E */ + 0x4cd5, 0x4ce1, 0x50f9, 0x5832, 0x5e2b, 0x60de, 0x62b3, 0x640c, + 0x64ec, 0x6702, 0x6912, 0x6a2a, 0x6c4a, 0x70a6, 0x72d2, 0x78fd, + 0x7cf3, 0x7d6c, 0x2e4f, 0x2ea1, 0x308d, 0x3256, 0x374a, 0x39a8, + 0x3e3d, 0x3fd8, 0x3fd9, 0x423f, 0x46b4, 0x471b, 0x47d0, 0x48d2, + 0x3192, 0x5d21, 0x60aa, 0x61a8, 0x6b00, 0x6c8c, 0x6cbf, 0x727e, + 0x7632, 0x3420, 0x782c, 0x3317, 0x30d5, 0x335c, 0x38a8, 0x44b2, + 0x4734, 0x5267, 0x5766, 0x5a46, 0x71e6, 0x32c3, 0x4ca1, 0x4b86, + 0x3800, 0x3e4c, 0x3954, 0x472c, 0x5ffb, 0x31e1, 0x56c6, 0x4469, + 0x58e8, 0x7b54, 0x7ebb, 0x37cb, 0x39b9, 0x4627, 0x479a, 0x4bce, + 0x34e9, 0x49d9, 0x3e55, 0x619c, 0x4795, 0x7baa, 0x47fe, 0x7c52, + 0x485d, 0x2ea6, 0x2fe3, 0x33c8, 0x42b9, 0x472b, 0x4cab, 0x6fc4, + 0x2fad, 0x5e6d, 0x7ebf, 0x2e07, 0x4162, 0x4e80, + /* 0x14C21..0x14C7E */ + 0x4f2b, 0x6513, 0x3473, 0x472a, 0x7b45, 0x3df3, 0x5b95, 0x3cac, + 0x3bc6, 0x671c, 0x4e4a, 0x64d1, 0x5a14, 0x6108, 0x3999, 0x5c8d, + 0x4c11, 0x5720, 0x32d9, 0x3922, 0x5121, 0x525f, 0x57db, 0x7727, + 0x7d61, 0x490b, 0x3a7f, 0x3a18, 0x31a5, 0x340d, 0x347d, 0x460e, + 0x56df, 0x6ff7, 0x7298, 0x7cf4, 0x39ea, 0x525d, 0x4ec5, 0x314d, + 0x48c9, 0x5dbf, 0x5dec, 0x7762, 0x7eba, 0x4478, 0x4a21, 0x6302, + 0x3984, 0x3b5f, 0x4bdb, 0x531b, 0x56f2, 0x5db2, 0x6017, 0x6499, + 0x3132, 0x4728, 0x7ed9, 0x56ee, 0x4762, 0x32ff, 0x7905, 0x3c24, + 0x423b, 0x5c7e, 0x6cb0, 0x354f, 0x40b6, 0x5d0b, 0x7580, 0x3301, + 0x2e5f, 0x31b6, 0x391c, 0x523a, 0x6036, 0x71ce, 0x3f25, 0x57e2, + 0x3384, 0x3f79, 0x5d04, 0x65ac, 0x6a33, 0x6e8d, 0x7756, 0x47f3, + 0x65ae, 0x7453, 0x4109, 0x4108, 0x4cb9, 0x5652, + /* 0x14D21..0x14D7E */ + 0x6aed, 0x6f38, 0x352f, 0x2f51, 0x312a, 0x32c7, 0x33cb, 0x3ba5, + 0x3e7d, 0x40a0, 0x4182, 0x43d6, 0x4709, 0x47da, 0x4e67, 0x4d8c, + 0x5336, 0x5337, 0x5531, 0x5950, 0x68d5, 0x6a98, 0x704a, 0x7091, + 0x70f5, 0x76c4, 0x678d, 0x3915, 0x2e88, 0x2f59, 0x2e0e, 0x6a89, + 0x6f3f, 0x7810, 0x30ad, 0x3e7c, 0x3996, 0x3bb9, 0x3eb8, 0x43da, + 0x43fa, 0x44c1, 0x46dc, 0x494a, 0x49d8, 0x4d0b, 0x4eb6, 0x5194, + 0x5528, 0x5aaf, 0x5f8a, 0x6000, 0x6449, 0x64c9, 0x6981, 0x6b21, + 0x6e0a, 0x7065, 0x767d, 0x790a, 0x417e, 0x4291, 0x4b32, 0x4c83, + 0x4d74, 0x5fcc, 0x5ffc, 0x4dc0, 0x5f85, 0x67ba, 0x68f8, 0x4765, + 0x63b1, 0x783c, 0x76f7, 0x4d1b, 0x5d61, 0x643d, 0x716a, 0x2e71, + 0x3375, 0x3d50, 0x4b04, 0x4feb, 0x65cd, 0x662d, 0x69a7, 0x3229, + 0x340f, 0x3c65, 0x474e, 0x48a8, 0x5406, 0x5483, + /* 0x14E21..0x14E7E */ + 0x55e2, 0x68cf, 0x68e1, 0x71cc, 0x76e2, 0x7678, 0x3f8b, 0x5387, + 0x5acb, 0x644e, 0x43a0, 0x5565, 0x3289, 0x4d41, 0x4e9c, 0x5409, + 0x5559, 0x586b, 0x5c92, 0x7686, 0x5adc, 0x7f8d, 0x2fb6, 0x416e, + 0x45c5, 0x665c, 0x2e86, 0x2eae, 0x30da, 0x2e21, 0x31cc, 0x3bee, + 0x4599, 0x4881, 0x4dbc, 0x531f, 0x5642, 0x57ad, 0x5a1c, 0x5ce7, + 0x626f, 0x6ad2, 0x707c, 0x71cf, 0x7675, 0x7818, 0x329b, 0x5dd1, + 0x302b, 0x3398, 0x4797, 0x4dcb, 0x51d0, 0x5433, 0x61e8, 0x6f2a, + 0x76a3, 0x7c57, 0x7e9f, 0x5460, 0x3841, 0x4d99, 0x5d2f, 0x785e, + 0x2ee4, 0x2f36, 0x2f8b, 0x31b7, 0x32b1, 0x3dba, 0x401c, 0x53b2, + 0x593c, 0x62d3, 0x7234, 0x76b7, 0x76f6, 0x770a, 0x7e97, 0x7f62, + 0x46a6, 0x4b74, 0x3217, 0x32a3, 0x50c8, 0x68c2, 0x3ec9, 0x404b, + 0x4190, 0x4f23, 0x5149, 0x5c3e, 0x5df4, 0x606f, + /* 0x14F21..0x14F7E */ + 0x64ee, 0x7023, 0x732c, 0x3442, 0x7b6f, 0x4ad3, 0x5089, 0x6cc2, + 0x6def, 0x7732, 0x32b4, 0x3a41, 0x3eca, 0x3f04, 0x4717, 0x497c, + 0x4994, 0x4d6a, 0x4f0f, 0x5262, 0x52fc, 0x5bed, 0x6001, 0x607e, + 0x674b, 0x70ce, 0x316d, 0x7e93, 0x5984, 0x608b, 0x7332, 0x6ad6, + 0x302d, 0x348c, 0x6a71, 0x4b6a, 0x6cc4, 0x6107, 0x40d1, 0x47a0, + 0x7df2, 0x2e99, 0x2e98, 0x7c10, 0x6a6b, 0x65c1, 0x6568, 0x4900, + 0x4e7e, 0x5897, 0x6155, 0x8e9f, 0x3b41, 0x3b56, 0x3b7d, 0x3b93, + 0x3bd8, 0x3bec, 0x3c12, 0x3c1e, 0x3c23, 0x3c2b, 0x178d, 0x3c62, + 0x813b, 0x813c, 0x96b4, 0x3c7a, 0x3c8f, 0x3c9f, 0x3ca3, 0x3caa, + 0x3cba, 0x3ccb, 0x3cd0, 0x3cd2, 0x3cf4, 0x9c34, 0x17e2, 0x3d0d, + 0x3d27, 0x8111, 0x3d46, 0x3d47, 0x3d53, 0x3d4a, 0x3d6d, 0x3d81, + 0x3da0, 0x3da4, 0x3da7, 0x3db8, 0x3dcb, 0x341e, + /* 0x15021..0x1507E */ + 0x3f0c, 0x2e10, 0x2e15, 0x2e2a, 0x2e31, 0x2e36, 0x2e3c, 0x2e3f, + 0x2e42, 0x2e56, 0x2e58, 0x2e82, 0x2e85, 0x6c6b, 0x2e8a, 0x6212, + 0x3f0d, 0x2e8e, 0x2e9e, 0x2e9f, 0x2ea0, 0x2ea2, 0x2eb0, 0x2eb3, + 0x2eb6, 0x2ece, 0x2ecd, 0x2ec4, 0x2ec6, 0x2ec2, 0x2ed7, 0x2ede, + 0x2eed, 0x2edf, 0x2ef7, 0x2f09, 0x2f5a, 0x2f30, 0x2f5b, 0x2f5d, + 0x2f57, 0x2f47, 0x2f76, 0x2f88, 0x2f8f, 0x2f98, 0x2f7b, 0x2f69, + 0x2f70, 0x2f91, 0x2f6f, 0x2f86, 0x2f96, 0x3118, 0x2fd4, 0x2fdf, + 0x2fce, 0x2fd8, 0x2fdb, 0x2fd1, 0x2fda, 0x2fd0, 0x2fe4, 0x2fe5, + 0x301a, 0x3028, 0x3014, 0x302a, 0x3025, 0x3005, 0x2f1c, 0x2ff6, + 0x3021, 0x3029, 0x302c, 0x2ffe, 0x2fef, 0x3011, 0x3006, 0x3043, + 0x3047, 0x4703, 0x3055, 0x3050, 0x3048, 0x305a, 0x3056, 0x306c, + 0x3078, 0x3080, 0x309a, 0x3085, 0x30b4, 0x30b2, + /* 0x15121..0x1517E */ + 0x30c9, 0x30ca, 0x30b3, 0x30c2, 0x30d6, 0x30de, 0x30e5, 0x30ed, + 0x30e3, 0x30ee, 0x30f9, 0x30f5, 0x3109, 0x3101, 0x3102, 0x3116, + 0x3115, 0x3114, 0x311a, 0x3121, 0x313a, 0x3137, 0x313c, 0x313b, + 0x313f, 0x3140, 0x3152, 0x314c, 0x3154, 0x3162, 0x5af8, 0x3169, + 0x316a, 0x316e, 0x3180, 0x3182, 0x36d8, 0x318c, 0x3189, 0x318f, + 0x3191, 0x3193, 0x3195, 0x3196, 0x31a4, 0x31a6, 0x31a2, 0x31a9, + 0x31aa, 0x31ab, 0x31b3, 0x31b1, 0x31b2, 0x31b0, 0x31b5, 0x31bd, + 0x31c5, 0x31c9, 0x31db, 0x31e0, 0x6655, 0x31e9, 0x31ed, 0x31f0, + 0x31f5, 0x31fe, 0x3204, 0x320b, 0x3214, 0x320e, 0x3227, 0x322a, + 0x322e, 0x3233, 0x3239, 0x324f, 0x3244, 0x324b, 0x324c, 0x325e, + 0x3254, 0x326a, 0x3274, 0x3269, 0x3273, 0x327f, 0x327d, 0x328d, + 0x3294, 0x3292, 0x3271, 0x3288, 0x3291, 0x6fa8, + /* 0x15221..0x1527E */ + 0x6fa7, 0x32ac, 0x32ad, 0x32bc, 0x32b5, 0x32c1, 0x32cd, 0x32d7, + 0x32de, 0x32e3, 0x32e6, 0x78ed, 0x32e0, 0x32f3, 0x32f5, 0x32f8, + 0x32f9, 0x3306, 0x3308, 0x5538, 0x330d, 0x3310, 0x330f, 0x3315, + 0x331a, 0x3323, 0x332f, 0x3331, 0x3333, 0x3338, 0x3340, 0x3346, + 0x3345, 0x2e17, 0x3349, 0x334d, 0x31d6, 0x335e, 0x3369, 0x336e, + 0x3918, 0x337b, 0x3377, 0x3382, 0x3396, 0x33a0, 0x33a6, 0x33a5, + 0x33ae, 0x33b0, 0x33b6, 0x33c3, 0x5c12, 0x76d9, 0x33df, 0x46fc, + 0x51ee, 0x33ee, 0x33e8, 0x33ed, 0x33fa, 0x3401, 0x343d, 0x3440, + 0x342c, 0x342d, 0x343c, 0x342e, 0x3436, 0x3429, 0x341d, 0x344e, + 0x348f, 0x3475, 0x348e, 0x345f, 0x3471, 0x3477, 0x3470, 0x3492, + 0x347b, 0x3480, 0x3476, 0x3484, 0x3490, 0x3486, 0x34c7, 0x34a2, + 0x34b8, 0x34a5, 0x34ac, 0x34c4, 0x34c8, 0x34a8, + /* 0x15321..0x1537E */ + 0x34ab, 0x34c2, 0x34a4, 0x34be, 0x34bc, 0x34d8, 0x34e5, 0x34e6, + 0x350f, 0x3514, 0x34fd, 0x34ee, 0x34ed, 0x34fa, 0x34e2, 0x3539, + 0x3540, 0x3563, 0x354c, 0x352e, 0x355c, 0x3545, 0x3556, 0x3557, + 0x3538, 0x3533, 0x355d, 0x3599, 0x3580, 0x34af, 0x358a, 0x359f, + 0x357b, 0x357e, 0x3598, 0x359e, 0x35ae, 0x357c, 0x3583, 0x35a9, + 0x3587, 0x35a8, 0x35da, 0x35c5, 0x35df, 0x35c4, 0x35dc, 0x35e4, + 0x35d4, 0x3614, 0x35f7, 0x3616, 0x35fe, 0x35fd, 0x361b, 0x35f9, + 0x364e, 0x3650, 0x51df, 0x3634, 0x3636, 0x3632, 0x3638, 0x366b, + 0x3664, 0x362f, 0x366c, 0x366a, 0x3686, 0x3680, 0x368a, 0x36a0, + 0x3694, 0x368f, 0x36a5, 0x36ae, 0x36b6, 0x36b4, 0x36c2, 0x36bc, + 0x36c1, 0x36c3, 0x36c0, 0x36c8, 0x36ce, 0x36d1, 0x36d3, 0x36d7, + 0x36ee, 0x36f9, 0x3700, 0x36ff, 0x3704, 0x3709, + /* 0x15421..0x1547E */ + 0x3708, 0x370b, 0x370d, 0x3713, 0x3718, 0x3716, 0x35c7, 0x371c, + 0x3726, 0x3737, 0x3738, 0x374e, 0x373b, 0x3740, 0x374f, 0x3769, + 0x37c0, 0x3788, 0x3761, 0x377f, 0x3789, 0x3793, 0x37a0, 0x37b3, + 0x37a4, 0x37aa, 0x37b0, 0x37c3, 0x37c6, 0x37d4, 0x37d2, 0x37d3, + 0x380a, 0x37d6, 0x37e3, 0x380b, 0x3819, 0x381d, 0x3872, 0x3821, + 0x3862, 0x384b, 0x3870, 0x4bc0, 0x3852, 0x383d, 0x3879, 0x3885, + 0x38b9, 0x389f, 0x38ab, 0x38ba, 0x38de, 0x38bb, 0x38b8, 0x38ae, + 0x38c5, 0x38d3, 0x38d1, 0x38d7, 0x38d9, 0x38d8, 0x38e5, 0x38dc, + 0x38e4, 0x38df, 0x38ef, 0x38fa, 0x38f9, 0x38fb, 0x38fc, 0x38fd, + 0x3902, 0x390a, 0x3910, 0x391b, 0x48a6, 0x3925, 0x392c, 0x392d, + 0x3932, 0x3938, 0x393e, 0x5ad2, 0x3955, 0x3950, 0x394e, 0x395a, + 0x3958, 0x3962, 0x3960, 0x3967, 0x396c, 0x3969, + /* 0x15521..0x1557E */ + 0x3978, 0x3981, 0x399d, 0x2f5e, 0x2fab, 0x39a3, 0x39b2, 0x39c6, + 0x39e8, 0x39dc, 0x398d, 0x39d9, 0x39da, 0x3a25, 0x3a1f, 0x3a11, + 0x3a1c, 0x3a09, 0x3a1a, 0x3a40, 0x3a6c, 0x3a49, 0x3a35, 0x3a36, + 0x3a62, 0x3a6a, 0x3a9a, 0x3abc, 0x3abe, 0x3acb, 0x3ac2, 0x3abd, + 0x3ae3, 0x3ad7, 0x3ae6, 0x3ae9, 0x3ad6, 0x3afa, 0x3afb, 0x3b0c, + 0x3b0b, 0x3b16, 0x3b32, 0x3ad0, 0x3b2a, 0x3b36, 0x3b3e, 0x3b43, + 0x3b45, 0x3b40, 0x3b51, 0x3b55, 0x3b5a, 0x3b5b, 0x3b65, 0x3b69, + 0x3b70, 0x3b73, 0x3b75, 0x3b78, 0x4588, 0x3b7a, 0x3b80, 0x3b83, + 0x3ba6, 0x3bb8, 0x3bc3, 0x3bc7, 0x3bc9, 0x3bd4, 0x3bd0, 0x3be4, + 0x3be6, 0x3be2, 0x3bde, 0x3be5, 0x3beb, 0x3bf0, 0x3bf6, 0x3bf3, + 0x3c05, 0x3c07, 0x3c08, 0x3c0d, 0x3c13, 0x3c20, 0x3c22, 0x3c28, + 0x3c38, 0x3c39, 0x3c41, 0x3c46, 0x3c4e, 0x3c53, + /* 0x15621..0x1567E */ + 0x3c50, 0x3c4f, 0x3b71, 0x3c6c, 0x3c6e, 0x2e62, 0x3c76, 0x3c79, + 0x3c8c, 0x3c91, 0x3c94, 0x399b, 0x3cab, 0x3cbb, 0x3cb6, 0x3cbc, + 0x3cb7, 0x3cc5, 0x3cbe, 0x3cc7, 0x3cd9, 0x3ce9, 0x3cfd, 0x3cfa, + 0x3ced, 0x3d8c, 0x3cea, 0x3d0b, 0x3d15, 0x3d17, 0x3d5c, 0x3d1f, + 0x3d1b, 0x3d11, 0x3d14, 0x3d22, 0x3d1a, 0x3d19, 0x3d18, 0x3d4c, + 0x3d52, 0x3d4e, 0x3d4b, 0x3d6c, 0x3d73, 0x3d76, 0x3d87, 0x3d84, + 0x3d82, 0x3da2, 0x3d9d, 0x3dac, 0x3dae, 0x3dbd, 0x3d90, 0x3db7, + 0x3dbc, 0x3dc9, 0x3dcd, 0x3dd3, 0x3dd2, 0x3dd6, 0x3ddb, 0x3deb, + 0x3df2, 0x3df5, 0x3e0b, 0x3e1a, 0x3e19, 0x3e11, 0x3e1b, 0x3e36, + 0x3e37, 0x3e44, 0x3e43, 0x3e40, 0x3e4e, 0x3e57, 0x3e54, 0x3e5f, + 0x3e62, 0x3e64, 0x3e47, 0x3e75, 0x3e76, 0x3e7a, 0x7ebc, 0x3e7f, + 0x3ea0, 0x3ec1, 0x3ec2, 0x3ec8, 0x3ed0, 0x3ecf, + /* 0x15721..0x1577E */ + 0x3ed6, 0x3ee3, 0x3edd, 0x3eda, 0x3edb, 0x3ee2, 0x3ee1, 0x3ee8, + 0x3ee9, 0x3eec, 0x3ef1, 0x3ef3, 0x3ef0, 0x3ef4, 0x3ef8, 0x3efe, + 0x3f03, 0x3f09, 0x3f5d, 0x3f5c, 0x3f0b, 0x3f11, 0x3f16, 0x3f29, + 0x3f2d, 0x3f38, 0x3f41, 0x3f48, 0x3f4c, 0x3f4e, 0x3f2f, 0x3f51, + 0x3f56, 0x3f57, 0x3f59, 0x3f61, 0x3f6d, 0x3f73, 0x3f77, 0x3f83, + 0x3f82, 0x3f7f, 0x3f8a, 0x3f88, 0x3f91, 0x3f87, 0x3f9e, 0x3f99, + 0x3f98, 0x3fa0, 0x3fa8, 0x3fad, 0x3fbc, 0x3fd6, 0x3ffb, 0x3fe4, + 0x3ff8, 0x3ff1, 0x3fdd, 0x40b3, 0x3fff, 0x4021, 0x4060, 0x4019, + 0x4010, 0x4029, 0x400e, 0x4031, 0x401b, 0x4015, 0x402b, 0x4026, + 0x400f, 0x403a, 0x405a, 0x4041, 0x406a, 0x4077, 0x405f, 0x404a, + 0x4046, 0x404d, 0x4063, 0x4043, 0x4064, 0x4042, 0x406c, 0x406b, + 0x4059, 0x4081, 0x408d, 0x40e7, 0x4083, 0x409a, + /* 0x15821..0x1587E */ + 0x4084, 0x409b, 0x4096, 0x4097, 0x4092, 0x40a7, 0x408b, 0x40e1, + 0x40b8, 0x40e0, 0x40d3, 0x40b4, 0x3ff0, 0x40bd, 0x40c6, 0x40b5, + 0x40d8, 0x414d, 0x4115, 0x4106, 0x40f6, 0x40f7, 0x4100, 0x40f4, + 0x40fa, 0x4103, 0x4121, 0x40fb, 0x40f1, 0x410d, 0x410e, 0x4147, + 0x413e, 0x4128, 0x4127, 0x414a, 0x413f, 0x413c, 0x412c, 0x4134, + 0x413d, 0x4142, 0x4144, 0x4173, 0x4177, 0x4158, 0x4159, 0x415a, + 0x416b, 0x4174, 0x416f, 0x4165, 0x4171, 0x415f, 0x415d, 0x4153, + 0x4175, 0x4199, 0x4196, 0x4187, 0x41ac, 0x4194, 0x419a, 0x418a, + 0x4191, 0x41ab, 0x41ae, 0x41cc, 0x41ca, 0x41c9, 0x41f7, 0x41c8, + 0x41c3, 0x41c6, 0x41ba, 0x41cb, 0x5f79, 0x41cd, 0x41e6, 0x41e3, + 0x41f6, 0x41fa, 0x41f4, 0x41ff, 0x41fd, 0x41fc, 0x41fe, 0x4200, + 0x4208, 0x4209, 0x420d, 0x420c, 0x4214, 0x421b, + /* 0x15921..0x1597E */ + 0x421e, 0x4221, 0x422a, 0x422e, 0x4230, 0x4232, 0x4233, 0x4241, + 0x424e, 0x425e, 0x4263, 0x425b, 0x4260, 0x4268, 0x427c, 0x4282, + 0x4289, 0x427e, 0x4292, 0x4293, 0x4296, 0x42d4, 0x4283, 0x4294, + 0x42d7, 0x42d1, 0x42bb, 0x42cf, 0x42ff, 0x42c6, 0x44d4, 0x42c8, + 0x42dc, 0x42cc, 0x42ca, 0x42c2, 0x42c7, 0x429b, 0x42c9, 0x430c, + 0x42ee, 0x42f1, 0x4327, 0x4302, 0x4308, 0x42ef, 0x42f5, 0x4350, + 0x433e, 0x434d, 0x441c, 0x434f, 0x4396, 0x438e, 0x4380, 0x43ab, + 0x4376, 0x43a3, 0x438f, 0x4389, 0x439f, 0x43b5, 0x436b, 0x4369, + 0x43be, 0x43e9, 0x43c0, 0x43c6, 0x43e3, 0x43c9, 0x43d2, 0x43f6, + 0x43c4, 0x4416, 0x4434, 0x4406, 0x4413, 0x4426, 0x4436, 0x451d, + 0x4417, 0x4428, 0x440f, 0x4467, 0x446f, 0x4476, 0x444e, 0x452a, + 0x4495, 0x4493, 0x44a5, 0x44a9, 0x4488, 0x44bc, + /* 0x15A21..0x15A7E */ + 0x44da, 0x44d2, 0x44c5, 0x44c7, 0x44bb, 0x44d8, 0x44c2, 0x44f1, + 0x44e7, 0x6209, 0x44e0, 0x44e1, 0x42ac, 0x44e3, 0x44ef, 0x452c, + 0x44f6, 0x44f4, 0x44f2, 0x44fa, 0x4500, 0x44fd, 0x4518, 0x451c, + 0x4505, 0x4524, 0x4523, 0x452b, 0x4534, 0x4535, 0x4537, 0x4536, + 0x4538, 0x554b, 0x4548, 0x4556, 0x4555, 0x454d, 0x4558, 0x455e, + 0x455d, 0x4572, 0x4578, 0x4582, 0x4583, 0x6b8a, 0x459b, 0x459f, + 0x45ab, 0x45b7, 0x45c3, 0x45c6, 0x45c1, 0x45c4, 0x45cc, 0x45d2, + 0x45db, 0x45d9, 0x45e0, 0x45e1, 0x45f1, 0x4772, 0x460a, 0x4603, + 0x45fb, 0x4773, 0x4635, 0x4636, 0x4634, 0x461c, 0x464f, 0x4644, + 0x4649, 0x4641, 0x465e, 0x465d, 0x4664, 0x4667, 0x4668, 0x465f, + 0x4662, 0x4670, 0x4683, 0x4688, 0x468e, 0x4689, 0x4684, 0x4698, + 0x469d, 0x46c1, 0x46b9, 0x46c9, 0x46be, 0x46bc, + /* 0x15B21..0x15B7E */ + 0x46c4, 0x46b8, 0x46d6, 0x46da, 0x46e0, 0x463f, 0x46e6, 0x46e9, + 0x46f0, 0x46f5, 0x46f7, 0x470f, 0x4716, 0x471e, 0x4726, 0x4727, + 0x7738, 0x472e, 0x473f, 0x4736, 0x4741, 0x4738, 0x4737, 0x4746, + 0x475e, 0x4760, 0x4759, 0x4763, 0x4764, 0x4789, 0x4770, 0x47a9, + 0x477c, 0x476a, 0x478c, 0x478b, 0x47a6, 0x47a1, 0x4785, 0x47b7, + 0x47ef, 0x47b4, 0x47ec, 0x47b3, 0x47e9, 0x47b8, 0x47e4, 0x47de, + 0x47dd, 0x47e2, 0x47ee, 0x47b9, 0x47ce, 0x47c6, 0x47e7, 0x4a9c, + 0x481e, 0x4846, 0x4829, 0x4840, 0x484d, 0x4832, 0x484e, 0x48b3, + 0x482b, 0x4859, 0x4863, 0x4877, 0x487f, 0x489f, 0x488f, 0x48ad, + 0x4894, 0x489d, 0x489b, 0x4883, 0x4aae, 0x48b9, 0x4874, 0x48b5, + 0x48a0, 0x48ba, 0x490f, 0x488d, 0x487e, 0x4901, 0x48ca, 0x4908, + 0x48d8, 0x4922, 0x4926, 0x48e1, 0x490c, 0x48cd, + /* 0x15C21..0x15C7E */ + 0x48d4, 0x48e7, 0x48d5, 0x4936, 0x4912, 0x4904, 0x48d7, 0x48e3, + 0x4925, 0x48f9, 0x48e0, 0x48ef, 0x4928, 0x492a, 0x491a, 0x4923, + 0x4921, 0x48c6, 0x4979, 0x4977, 0x495c, 0x4978, 0x496b, 0x4954, + 0x497e, 0x496e, 0x4939, 0x4974, 0x493d, 0x4959, 0x4930, 0x4961, + 0x495e, 0x495d, 0x4981, 0x496a, 0x49b2, 0x49ae, 0x49d0, 0x49bf, + 0x49c1, 0x49d3, 0x49be, 0x49ce, 0x3be8, 0x49ca, 0x49dd, 0x49bb, + 0x49c3, 0x49a7, 0x4a2e, 0x4991, 0x49a0, 0x499c, 0x4995, 0x49b4, + 0x49de, 0x49e8, 0x4a02, 0x4a1b, 0x49ff, 0x4b0a, 0x49f9, 0x49f2, + 0x49e7, 0x4a05, 0x49b1, 0x4a1e, 0x49ed, 0x4a14, 0x49eb, 0x4a0a, + 0x4a12, 0x4ac1, 0x4a23, 0x4a13, 0x4a44, 0x4a0c, 0x4a72, 0x4a36, + 0x4a78, 0x4a47, 0x4a62, 0x4a59, 0x4a66, 0x4a48, 0x4a38, 0x4a22, + 0x4a90, 0x4a8d, 0x4aa0, 0x4a84, 0x4aa2, 0x4aa3, + /* 0x15D21..0x15D7E */ + 0x4a97, 0x6617, 0x4abb, 0x4ac3, 0x4ac2, 0x4ab8, 0x4ab3, 0x4aac, + 0x4ade, 0x4ad1, 0x4adf, 0x4aaa, 0x4ada, 0x4aea, 0x4afb, 0x4b05, + 0x6616, 0x4afa, 0x4b12, 0x4b16, 0x7b31, 0x4b1f, 0x4b38, 0x4b37, + 0x56dc, 0x4b39, 0x78ee, 0x4b47, 0x4b43, 0x4b49, 0x4b50, 0x4b59, + 0x4b54, 0x4b5b, 0x4b5f, 0x4b61, 0x4b78, 0x4b79, 0x4b7f, 0x4b80, + 0x4b84, 0x4b83, 0x4b8d, 0x4b98, 0x4b95, 0x4b9e, 0x4ba4, 0x4baa, + 0x4bab, 0x4baf, 0x4bb2, 0x4bb1, 0x4bb3, 0x4bb7, 0x4bbc, 0x4bc6, + 0x4bcb, 0x4bd3, 0x4bdf, 0x4bec, 0x4beb, 0x4bf3, 0x4bef, 0x7ebe, + 0x4c08, 0x4c13, 0x4c14, 0x4c1b, 0x4c24, 0x4c23, 0x4c5e, 0x4c55, + 0x4c62, 0x4c6a, 0x4c82, 0x4c8d, 0x4c9a, 0x4c81, 0x4c9b, 0x4c7e, + 0x4c68, 0x4c73, 0x4c92, 0x4c90, 0x4cc4, 0x4cf1, 0x4cd3, 0x4cbd, + 0x4cd7, 0x4cc5, 0x4cdd, 0x4cae, 0x4cb1, 0x4cbe, + /* 0x15E21..0x15E7E */ + 0x4cba, 0x4cdb, 0x4cef, 0x4cd9, 0x4cea, 0x4d1f, 0x684d, 0x4d36, + 0x4d2b, 0x4d3d, 0x4d38, 0x4d19, 0x4d35, 0x4d33, 0x4d12, 0x4d0c, + 0x4d63, 0x4d93, 0x4d64, 0x4d5a, 0x4d79, 0x4d59, 0x4d8e, 0x4d95, + 0x4fe4, 0x4d85, 0x4df9, 0x4e15, 0x4e0a, 0x4db5, 0x4dc7, 0x4de6, + 0x4db8, 0x4dc6, 0x4dec, 0x4dde, 0x4dcc, 0x4de8, 0x4dd2, 0x4dc5, + 0x4dfa, 0x4dd9, 0x4de4, 0x4dd5, 0x4dea, 0x4dee, 0x4e2d, 0x4e6e, + 0x4e2e, 0x4e19, 0x4e72, 0x4e5f, 0x4e3e, 0x4e23, 0x4e6b, 0x4e2b, + 0x4e76, 0x4e4d, 0x4e1f, 0x4e43, 0x4e3a, 0x4e4e, 0x4e24, 0x4eff, + 0x4e1d, 0x4e38, 0x4e82, 0x4eaa, 0x4e98, 0x4ec9, 0x4eb7, 0x4ed3, + 0x4ebd, 0x4eaf, 0x4ec4, 0x4eb2, 0x4ed4, 0x4ed5, 0x4e8f, 0x4ea5, + 0x4ec2, 0x4e9f, 0x4f41, 0x4f11, 0x504c, 0x4eec, 0x4ef8, 0x4efe, + 0x4f3f, 0x4ef2, 0x4f31, 0x4eef, 0x4f32, 0x4ecc, + /* 0x15F21..0x15F7E */ + 0x4f3e, 0x4f13, 0x4ef7, 0x4f86, 0x4f7a, 0x4f78, 0x4f81, 0x4f80, + 0x4f6f, 0x4f5b, 0x4ff3, 0x4f6d, 0x4f82, 0x4f7c, 0x4f58, 0x4f8e, + 0x4f91, 0x4fc2, 0x4f66, 0x4fb3, 0x4fa3, 0x4fa1, 0x4fa4, 0x4fb9, + 0x4fc6, 0x4faa, 0x4fdf, 0x4fd5, 0x4fec, 0x4fd4, 0x4fd8, 0x4ff1, + 0x4fee, 0x4fdb, 0x5009, 0x500b, 0x4ffa, 0x5011, 0x5001, 0x500f, + 0x4ffe, 0x501b, 0x501a, 0x4f74, 0x501d, 0x5018, 0x501f, 0x5030, + 0x503e, 0x5032, 0x5051, 0x5063, 0x5099, 0x5092, 0x50af, 0x50f1, + 0x50ac, 0x50b8, 0x50b3, 0x50ae, 0x50df, 0x50cb, 0x50dd, 0x50d9, + 0x5109, 0x50fd, 0x511c, 0x5119, 0x5165, 0x5155, 0x5188, 0x5166, + 0x5162, 0x514c, 0x5156, 0x516c, 0x518f, 0x51fb, 0x5184, 0x5195, + 0x51a8, 0x51ac, 0x51d7, 0x51b9, 0x51be, 0x51d2, 0x51c9, 0x51d4, + 0x51ce, 0x51e0, 0x51ec, 0x51e7, 0x51f5, 0x51fc, + /* 0x16021..0x1607E */ + 0x51f9, 0x51ff, 0x520d, 0x5210, 0x521b, 0x5228, 0x522d, 0x522c, + 0x5230, 0x5232, 0x523b, 0x523c, 0x523f, 0x5240, 0x5246, 0x524b, + 0x5258, 0x5274, 0x527e, 0x5282, 0x5281, 0x5287, 0x5292, 0x5296, + 0x52a2, 0x52a7, 0x52b9, 0x52b2, 0x52c3, 0x52c6, 0x52c4, 0x52ce, + 0x52d2, 0x52e2, 0x52e0, 0x52e1, 0x52f9, 0x52f7, 0x300f, 0x5317, + 0x530a, 0x531c, 0x5316, 0x531d, 0x5334, 0x532f, 0x5329, 0x5325, + 0x533e, 0x534e, 0x534f, 0x7ed8, 0x5357, 0x536a, 0x5368, 0x5370, + 0x5378, 0x5375, 0x537b, 0x537a, 0x53c8, 0x53b3, 0x53ce, 0x53bb, + 0x53c0, 0x53e5, 0x53ee, 0x53de, 0x54a2, 0x5405, 0x546f, 0x5425, + 0x53f8, 0x5432, 0x543a, 0x5455, 0x543f, 0x545f, 0x5459, 0x5441, + 0x545c, 0x5469, 0x5470, 0x5463, 0x546a, 0x5476, 0x547e, 0x548b, + 0x549e, 0x54a7, 0x54ca, 0x54cf, 0x54d4, 0x53f1, + /* 0x16121..0x1617E */ + 0x54e0, 0x54e3, 0x54e7, 0x54e9, 0x54ee, 0x54f2, 0x54f0, 0x54f1, + 0x54f8, 0x54f7, 0x5504, 0x5503, 0x5505, 0x550c, 0x550e, 0x550d, + 0x5515, 0x5513, 0x551e, 0x5526, 0x552c, 0x553c, 0x5544, 0x554d, + 0x554a, 0x5549, 0x555b, 0x5546, 0x555a, 0x5569, 0x5564, 0x5567, + 0x556b, 0x556d, 0x5578, 0x5576, 0x5586, 0x5587, 0x5574, 0x558a, + 0x5589, 0x5582, 0x5594, 0x559a, 0x559d, 0x55a5, 0x55a3, 0x55c2, + 0x55b3, 0x55c3, 0x55b5, 0x55bd, 0x55b8, 0x55bc, 0x55b1, 0x55cd, + 0x55ca, 0x55d2, 0x55d9, 0x55e3, 0x55de, 0x55fe, 0x55ff, 0x55fc, + 0x5601, 0x55f0, 0x55fa, 0x55f2, 0x55f3, 0x560b, 0x560d, 0x5609, + 0x561f, 0x5627, 0x5620, 0x5621, 0x5622, 0x5624, 0x5634, 0x5630, + 0x563b, 0x5647, 0x5648, 0x5646, 0x565c, 0x5658, 0x5661, 0x5662, + 0x5668, 0x5669, 0x566a, 0x5667, 0x566c, 0x5670, + /* 0x16221..0x1627E */ + 0x5672, 0x5676, 0x5678, 0x567c, 0x5680, 0x5683, 0x5688, 0x568b, + 0x568e, 0x5696, 0x5693, 0x5699, 0x569a, 0x56b0, 0x56b4, 0x56b8, + 0x56b9, 0x56ba, 0x56c2, 0x56cd, 0x56d6, 0x56d2, 0x56de, 0x56e1, + 0x56e5, 0x56e7, 0x56ea, 0x662f, 0x56fb, 0x5708, 0x5707, 0x5704, + 0x5729, 0x5724, 0x571e, 0x5725, 0x5726, 0x571b, 0x5737, 0x5738, + 0x5747, 0x575a, 0x5768, 0x576b, 0x575b, 0x5765, 0x577f, 0x577e, + 0x5779, 0x578e, 0x578b, 0x5791, 0x57a0, 0x579e, 0x57b0, 0x57b6, + 0x57b9, 0x57bf, 0x57bc, 0x57bd, 0x57bb, 0x57c7, 0x57cd, 0x57d7, + 0x57da, 0x57dc, 0x57e3, 0x57ee, 0x57fc, 0x580c, 0x5812, 0x5926, + 0x5820, 0x592a, 0x5845, 0x588e, 0x5874, 0x5886, 0x587c, 0x589a, + 0x588c, 0x58a3, 0x58b5, 0x58aa, 0x58af, 0x58d1, 0x58c6, 0x58cb, + 0x58d4, 0x58be, 0x58bc, 0x58c5, 0x58ca, 0x58ec, + /* 0x16321..0x1637E */ + 0x58e7, 0x58da, 0x58fd, 0x58f4, 0x5907, 0x5912, 0x5911, 0x5919, + 0x592c, 0x592b, 0x5940, 0x5960, 0x5957, 0x595f, 0x595a, 0x5955, + 0x5953, 0x597a, 0x597f, 0x598a, 0x599d, 0x59a7, 0x7f4b, 0x59aa, + 0x59ae, 0x59b3, 0x59b9, 0x59ba, 0x59c9, 0x59d5, 0x59e7, 0x59ec, + 0x59e1, 0x59e3, 0x5a08, 0x5a0d, 0x5a18, 0x5a19, 0x5a20, 0x5a1f, + 0x5980, 0x5a31, 0x5a3b, 0x5a3e, 0x5a37, 0x5a43, 0x5a57, 0x5a49, + 0x5a61, 0x5a62, 0x5a69, 0x7f9d, 0x5a70, 0x5a79, 0x5a7d, 0x5a88, + 0x5a97, 0x5a95, 0x5a98, 0x5a96, 0x5aa9, 0x5ac8, 0x5ab0, 0x5ab6, + 0x5ac5, 0x5ac4, 0x5abf, 0x7083, 0x5ac7, 0x5aca, 0x5acd, 0x5acf, + 0x5ad5, 0x5ad3, 0x5ad9, 0x5ada, 0x5add, 0x5ae1, 0x5ae2, 0x5ae6, + 0x5aed, 0x5af0, 0x5b02, 0x5b0f, 0x5b0a, 0x5b06, 0x5b33, 0x5b18, + 0x5b19, 0x5b1e, 0x5b35, 0x5b28, 0x5b36, 0x5b50, + /* 0x16421..0x1647E */ + 0x5b7a, 0x5b04, 0x5b4d, 0x5b0b, 0x5b4c, 0x5b45, 0x5b75, 0x5b65, + 0x5b74, 0x5b67, 0x5b70, 0x5b71, 0x5b6c, 0x5b6e, 0x5b9d, 0x5b98, + 0x5b9f, 0x5b8d, 0x5b9c, 0x5b9a, 0x5b8b, 0x5b92, 0x5b8f, 0x5b5d, + 0x5b99, 0x5bcb, 0x5bc1, 0x5bcc, 0x5bcf, 0x5bb4, 0x5bc6, 0x5bdd, + 0x5be9, 0x5c11, 0x5c14, 0x5be6, 0x5be5, 0x5c60, 0x5c00, 0x5c07, + 0x5c13, 0x5bf3, 0x5bf7, 0x5c17, 0x5c0d, 0x5bf6, 0x5c23, 0x5c27, + 0x5c2a, 0x5c1f, 0x5c37, 0x5c2b, 0x5c3d, 0x5c4c, 0x5c43, 0x5c54, + 0x5c4f, 0x5c40, 0x5c50, 0x5c58, 0x5c5f, 0x5c64, 0x5c56, 0x5c65, + 0x5c6c, 0x5c75, 0x5c83, 0x5c90, 0x5ca4, 0x5cad, 0x5ca2, 0x5cab, + 0x5ca1, 0x5ca8, 0x5cb3, 0x5cb2, 0x5cb1, 0x5cae, 0x5cb9, 0x5cbd, + 0x5cc0, 0x5cc5, 0x5cc2, 0x5cd8, 0x5cd2, 0x5cdc, 0x5ce2, 0x7b3b, + 0x5cef, 0x5cf2, 0x5cf4, 0x5cf6, 0x5cfa, 0x5d06, + /* 0x16521..0x1657E */ + 0x5d02, 0x5d1c, 0x5d15, 0x5d0a, 0x5d45, 0x5d4b, 0x5d2e, 0x5d32, + 0x5d3f, 0x5d35, 0x5d46, 0x5d73, 0x5d56, 0x5d4e, 0x5d72, 0x5d68, + 0x5d6e, 0x5d4f, 0x5d63, 0x5d93, 0x5d89, 0x5d5b, 0x5d8f, 0x5d7d, + 0x5d9b, 0x5dba, 0x5dae, 0x5da3, 0x5db5, 0x5dc7, 0x5dbd, 0x5dab, + 0x5e3d, 0x5da2, 0x5daf, 0x5ddc, 0x5db8, 0x5d9f, 0x5db0, 0x5dd8, + 0x5ddd, 0x5de4, 0x5dde, 0x5dfb, 0x5df2, 0x5de1, 0x5e05, 0x5e0a, + 0x5e23, 0x5e21, 0x5e12, 0x5e31, 0x5e1f, 0x5e09, 0x5e0b, 0x5e22, + 0x5e46, 0x5e66, 0x5e3b, 0x5e35, 0x5e39, 0x5e43, 0x5e37, 0x5e32, + 0x5e3a, 0x5e67, 0x5e5d, 0x5e56, 0x5e5e, 0x5e59, 0x5e5a, 0x5e79, + 0x5e6a, 0x5e69, 0x5e7c, 0x5e7b, 0x5e83, 0x5dd5, 0x5e7d, 0x6fae, + 0x5e7f, 0x5e88, 0x5e89, 0x5e8c, 0x5e92, 0x5e90, 0x5e93, 0x5e94, + 0x5e96, 0x5e8e, 0x5e9b, 0x5e9c, 0x5f38, 0x5f3a, + /* 0x16621..0x1667E */ + 0x5f45, 0x5f4c, 0x5f4d, 0x5f4e, 0x5f50, 0x5f51, 0x5f55, 0x5f54, + 0x5f58, 0x5f5f, 0x5f60, 0x5f68, 0x5f69, 0x5f67, 0x5f78, 0x5f82, + 0x5f86, 0x5f83, 0x5f88, 0x5f87, 0x5f8c, 0x5f94, 0x5f9e, 0x5f9d, + 0x5f9a, 0x5fa3, 0x5faf, 0x5fb2, 0x5fb9, 0x5fae, 0x5fb6, 0x5fb8, + 0x6b71, 0x5fc5, 0x5fc6, 0x5fca, 0x5fd5, 0x5fd4, 0x5fe1, 0x5fe6, + 0x5fe9, 0x5ff3, 0x5ff9, 0x78dc, 0x6006, 0x6004, 0x600b, 0x6012, + 0x6018, 0x6019, 0x601c, 0x6021, 0x6028, 0x603f, 0x603b, 0x604a, + 0x6046, 0x6052, 0x6058, 0x605a, 0x605f, 0x6062, 0x6068, 0x6073, + 0x6072, 0x6070, 0x6076, 0x6079, 0x607d, 0x607f, 0x6084, 0x6086, + 0x6085, 0x609b, 0x6093, 0x609a, 0x60ad, 0x3190, 0x60ac, 0x60db, + 0x60e5, 0x60d9, 0x60dd, 0x60c4, 0x60da, 0x60d6, 0x6109, 0x60ef, + 0x60f1, 0x611b, 0x6129, 0x6123, 0x612f, 0x614b, + /* 0x16721..0x1677E */ + 0x768b, 0x6146, 0x613e, 0x6153, 0x6151, 0x60fc, 0x6171, 0x616e, + 0x6165, 0x6166, 0x6174, 0x6183, 0x6188, 0x618a, 0x6180, 0x6182, + 0x61a0, 0x6195, 0x61a4, 0x61a3, 0x615f, 0x6193, 0x61a9, 0x61b0, + 0x61b5, 0x61be, 0x61b8, 0x61bd, 0x61c0, 0x61c2, 0x61ba, 0x61c9, + 0x61cd, 0x61d1, 0x61d9, 0x61d8, 0x61c8, 0x61da, 0x61df, 0x61e0, + 0x61e7, 0x61fa, 0x61fb, 0x61fe, 0x6201, 0x6202, 0x6205, 0x6207, + 0x620a, 0x620d, 0x6210, 0x6216, 0x6229, 0x622b, 0x6238, 0x6233, + 0x6240, 0x6259, 0x6258, 0x625d, 0x625a, 0x625f, 0x6264, 0x6262, + 0x6268, 0x626a, 0x626b, 0x622e, 0x6271, 0x6277, 0x6278, 0x627e, + 0x628d, 0x6292, 0x62ab, 0x629f, 0x62bb, 0x62ac, 0x62e1, 0x62e3, + 0x62df, 0x62d2, 0x62f4, 0x62f3, 0x62fa, 0x6393, 0x6303, 0x62fb, + 0x62f9, 0x62de, 0x6306, 0x62dc, 0x6309, 0x62d9, + /* 0x16821..0x1687E */ + 0x6335, 0x6334, 0x6316, 0x6332, 0x6331, 0x6340, 0x6339, 0x6350, + 0x6345, 0x632f, 0x632b, 0x6317, 0x6318, 0x6385, 0x639a, 0x63aa, + 0x639f, 0x63a2, 0x6396, 0x6323, 0x638e, 0x6387, 0x638a, 0x637c, + 0x63b5, 0x6373, 0x6375, 0x63a0, 0x6389, 0x63a8, 0x63f4, 0x6413, + 0x63eb, 0x63ce, 0x63fd, 0x6403, 0x63d8, 0x640b, 0x63c1, 0x63f7, + 0x6407, 0x63e0, 0x63f2, 0x640d, 0x6422, 0x6420, 0x63bd, 0x6438, + 0x6506, 0x63fb, 0x646d, 0x642a, 0x643c, 0x655a, 0x6484, 0x6477, + 0x646b, 0x64ad, 0x646e, 0x6482, 0x6469, 0x6446, 0x642c, 0x646f, + 0x6479, 0x6435, 0x64ca, 0x6462, 0x64b9, 0x64bf, 0x649f, 0x64d9, + 0x64cd, 0x64bb, 0x64da, 0x64d0, 0x64c1, 0x64c6, 0x64d6, 0x64a1, + 0x6521, 0x64ff, 0x64f4, 0x6517, 0x6518, 0x652c, 0x651f, 0x6515, + 0x6514, 0x64fc, 0x6540, 0x6563, 0x6558, 0x6548, + /* 0x16921..0x1697E */ + 0x6541, 0x6602, 0x654b, 0x6555, 0x6580, 0x65a4, 0x6588, 0x6591, + 0x658a, 0x65a8, 0x656d, 0x6594, 0x659b, 0x65ea, 0x6587, 0x659c, + 0x6577, 0x657e, 0x6590, 0x65c9, 0x65ba, 0x65cf, 0x65b9, 0x65d0, + 0x65d5, 0x65dd, 0x65e5, 0x65dc, 0x65f9, 0x660a, 0x6613, 0x660b, + 0x65fe, 0x65fa, 0x6606, 0x6622, 0x661a, 0x6630, 0x663f, 0x664d, + 0x2e55, 0x6654, 0x665f, 0x6667, 0x6671, 0x6693, 0x66a3, 0x66a9, + 0x66aa, 0x668b, 0x668c, 0x66b6, 0x66af, 0x66c4, 0x66c6, 0x66b0, + 0x66c9, 0x6823, 0x66ab, 0x66d4, 0x66de, 0x66e9, 0x66ec, 0x66df, + 0x66db, 0x66ef, 0x6712, 0x6706, 0x6708, 0x6700, 0x6703, 0x66fb, + 0x6711, 0x6709, 0x670d, 0x66f9, 0x670a, 0x6734, 0x673f, 0x6737, + 0x673b, 0x6725, 0x6729, 0x671a, 0x6760, 0x675f, 0x6778, 0x674c, + 0x674e, 0x6774, 0x6757, 0x6768, 0x676e, 0x6759, + /* 0x16A21..0x16A7E */ + 0x6753, 0x6763, 0x676a, 0x6805, 0x67a2, 0x679f, 0x6782, 0x67af, + 0x67cb, 0x67bd, 0x67c0, 0x67d0, 0x76d6, 0x67ab, 0x67c4, 0x67b3, + 0x67c7, 0x67c6, 0x67bb, 0x67ef, 0x67f2, 0x67e0, 0x680f, 0x680d, + 0x67fe, 0x67f6, 0x67f7, 0x680e, 0x67d2, 0x6811, 0x6816, 0x6815, + 0x6822, 0x6821, 0x6831, 0x6836, 0x6839, 0x6827, 0x683b, 0x6844, + 0x6842, 0x6852, 0x6859, 0x685e, 0x6862, 0x686b, 0x6881, 0x687e, + 0x689e, 0x6875, 0x687d, 0x68b5, 0x6872, 0x6882, 0x6897, 0x6892, + 0x68ae, 0x6899, 0x68a2, 0x688d, 0x68a4, 0x68b0, 0x68bf, 0x68b1, + 0x68c3, 0x68c4, 0x68d4, 0x68d8, 0x68d9, 0x68dd, 0x68f9, 0x6902, + 0x68fc, 0x68f4, 0x68e8, 0x68f2, 0x6904, 0x690c, 0x690a, 0x6913, + 0x6943, 0x691e, 0x6925, 0x692a, 0x692b, 0x6941, 0x6944, 0x693b, + 0x6936, 0x6938, 0x694c, 0x691d, 0x6960, 0x695e, + /* 0x16B21..0x16B7E */ + 0x6966, 0x6964, 0x696d, 0x696a, 0x696f, 0x6974, 0x6977, 0x697e, + 0x6983, 0x6988, 0x698a, 0x6993, 0x6998, 0x69a1, 0x69a9, 0x69a6, + 0x69ac, 0x69af, 0x69b2, 0x69ba, 0x69bd, 0x69bf, 0x69c0, 0x69da, + 0x69dc, 0x69dd, 0x69e7, 0x69f4, 0x69f8, 0x6a03, 0x6a16, 0x6a10, + 0x6a0c, 0x6a1b, 0x6a1d, 0x6a25, 0x6a36, 0x6a41, 0x6a5b, 0x6a52, + 0x6a46, 0x6a48, 0x6a7c, 0x6a6d, 0x6a6c, 0x6a62, 0x6a85, 0x6a82, + 0x6a84, 0x6aa8, 0x6aa1, 0x6a91, 0x6aa5, 0x6aa6, 0x6a9a, 0x6aa3, + 0x6ac4, 0x6acd, 0x6ac2, 0x6ada, 0x6aeb, 0x6af3, 0x6ae7, 0x6ae4, + 0x6af1, 0x6b14, 0x6ae0, 0x6ae2, 0x6af7, 0x6ade, 0x6adb, 0x6b0c, + 0x6b07, 0x6b1a, 0x6ae1, 0x6b16, 0x6b10, 0x6b17, 0x6b20, 0x6b33, + 0x77ab, 0x6b26, 0x6b2b, 0x6b3e, 0x6b28, 0x6b41, 0x6b4c, 0x6b4f, + 0x6b4e, 0x6b49, 0x6b56, 0x6b5b, 0x6b5a, 0x6b6b, + /* 0x16C21..0x16C7E */ + 0x6b5f, 0x6b6c, 0x6b6f, 0x6b74, 0x6b7d, 0x6b80, 0x6b8c, 0x6b8e, + 0x6b92, 0x6b93, 0x6b96, 0x6b99, 0x6b9a, 0x6c3a, 0x6c41, 0x6c3f, + 0x6c48, 0x6c4c, 0x6c4e, 0x6c50, 0x6c55, 0x6c62, 0x6c6c, 0x6c78, + 0x6c7a, 0x6c82, 0x6c89, 0x6c85, 0x6c8a, 0x6c8d, 0x6c8e, 0x6c94, + 0x6c7c, 0x6c98, 0x421d, 0x6cad, 0x6caa, 0x6cbd, 0x6cb2, 0x6cb3, + 0x6cae, 0x6cb6, 0x6cc8, 0x6cc1, 0x6ce4, 0x6ce3, 0x6cda, 0x6cfd, + 0x6cfa, 0x6cfb, 0x6d04, 0x6d05, 0x6d0a, 0x6d07, 0x6d0f, 0x6d0d, + 0x6d10, 0x7f4e, 0x6d13, 0x6ccd, 0x6d14, 0x6d16, 0x6d67, 0x6d6d, + 0x6d71, 0x6d73, 0x6d81, 0x6d99, 0x6dc2, 0x6dbe, 0x6dba, 0x6dcf, + 0x6dda, 0x6dd6, 0x6dcc, 0x6ddb, 0x6dcb, 0x6dea, 0x6deb, 0x6ddf, + 0x6de3, 0x6dfc, 0x6e08, 0x6e09, 0x6dff, 0x6e1d, 0x6e1e, 0x6e10, + 0x6e1f, 0x6e42, 0x6e35, 0x6e30, 0x6e34, 0x6e4a, + /* 0x16D21..0x16D7E */ + 0x6e47, 0x6e49, 0x6e4c, 0x6e50, 0x6e48, 0x6e59, 0x6e64, 0x6e60, + 0x6e2a, 0x6e63, 0x6e55, 0x6e76, 0x6e72, 0x6e7c, 0x6e81, 0x6e87, + 0x6e85, 0x6e84, 0x6e8b, 0x6e8a, 0x6e93, 0x6e91, 0x6e94, 0x6e99, + 0x6eaa, 0x6ea1, 0x6eac, 0x6eb0, 0x6ec6, 0x6eb1, 0x6ebe, 0x6ec5, + 0x6ec8, 0x6ecb, 0x6edb, 0x6ee3, 0x6efc, 0x6efb, 0x6eeb, 0x6efe, + 0x6f0a, 0x6f05, 0x6f15, 0x6f12, 0x6f19, 0x6f13, 0x6f1c, 0x6f1f, + 0x6f1b, 0x6f0c, 0x6f26, 0x6f33, 0x6f3b, 0x6f39, 0x6f45, 0x6f42, + 0x6f3e, 0x6f4c, 0x6f49, 0x6f46, 0x6f4e, 0x6f57, 0x6f5c, 0x6f62, + 0x6f63, 0x6f64, 0x6f9c, 0x6f9f, 0x6fa3, 0x6fad, 0x6faf, 0x6fb7, + 0x6fda, 0x6fe5, 0x6fe2, 0x6fea, 0x6fef, 0x7087, 0x6ff4, 0x7005, + 0x6ff9, 0x6ffa, 0x7011, 0x7015, 0x7021, 0x700d, 0x701e, 0x7016, + 0x700b, 0x7027, 0x7036, 0x7035, 0x7039, 0x6ff8, + /* 0x16E21..0x16E7E */ + 0x704f, 0x7050, 0x7051, 0x7052, 0x700e, 0x7049, 0x703e, 0x7056, + 0x7058, 0x705e, 0x7068, 0x706f, 0x7076, 0x76a8, 0x7072, 0x7082, + 0x707d, 0x7081, 0x7080, 0x708a, 0x7089, 0x708f, 0x70a8, 0x70af, + 0x70b1, 0x70b5, 0x70e2, 0x70e4, 0x4248, 0x70db, 0x7102, 0x7112, + 0x7119, 0x7132, 0x7130, 0x714a, 0x7156, 0x7158, 0x7163, 0x7165, + 0x7169, 0x7173, 0x7172, 0x718b, 0x7189, 0x7182, 0x71a2, 0x71ab, + 0x71af, 0x71aa, 0x71b5, 0x71b4, 0x71ba, 0x71c0, 0x71c1, 0x71c9, + 0x71cb, 0x71d0, 0x71d6, 0x71df, 0x71e1, 0x71db, 0x71fc, 0x71f5, + 0x71f6, 0x721e, 0x71ff, 0x7214, 0x722c, 0x7215, 0x7211, 0x725e, + 0x7257, 0x7245, 0x7249, 0x7264, 0x7248, 0x7295, 0x723f, 0x724b, + 0x7250, 0x729c, 0x7296, 0x7293, 0x729b, 0x725a, 0x72cf, 0x72b9, + 0x72b7, 0x72e9, 0x730f, 0x72fa, 0x7344, 0x732e, + /* 0x16F21..0x16F7E */ + 0x7319, 0x7322, 0x731a, 0x7323, 0x733a, 0x7335, 0x733b, 0x735c, + 0x7360, 0x737c, 0x736e, 0x7356, 0x73b0, 0x73ac, 0x73ad, 0x7394, + 0x73b9, 0x73d6, 0x73d7, 0x73e8, 0x73e5, 0x73d8, 0x73c3, 0x73dd, + 0x73d0, 0x73c8, 0x73e4, 0x741a, 0x7414, 0x7413, 0x7403, 0x7407, + 0x7410, 0x7436, 0x742b, 0x7435, 0x7421, 0x743a, 0x7441, 0x7452, + 0x7444, 0x745b, 0x7460, 0x7462, 0x745e, 0x746a, 0x7229, 0x7470, + 0x7475, 0x7477, 0x747d, 0x745a, 0x747c, 0x747e, 0x7481, 0x747f, + 0x7582, 0x7587, 0x758a, 0x7594, 0x7596, 0x7598, 0x7599, 0x75a0, + 0x75a8, 0x75a7, 0x75ad, 0x75bc, 0x75bb, 0x75b9, 0x75be, 0x75ca, + 0x4ff6, 0x75c3, 0x75cd, 0x75cc, 0x75d5, 0x75d4, 0x75d6, 0x75dc, + 0x75e1, 0x75e5, 0x75e2, 0x7621, 0x7628, 0x762e, 0x762f, 0x7642, + 0x764c, 0x764f, 0x764b, 0x7677, 0x765c, 0x765e, + /* 0x17021..0x1707E */ + 0x765d, 0x765f, 0x7666, 0x7672, 0x766c, 0x768d, 0x7698, 0x7695, + 0x7697, 0x76aa, 0x76a7, 0x76b1, 0x76b2, 0x76b0, 0x76b4, 0x76b6, + 0x76b8, 0x76b9, 0x76ce, 0x76cb, 0x76c9, 0x76cd, 0x694d, 0x76dc, + 0x770d, 0x76d5, 0x76f9, 0x7704, 0x7706, 0x7708, 0x7713, 0x770e, + 0x7711, 0x770f, 0x7716, 0x7719, 0x7724, 0x772a, 0x7730, 0x7739, + 0x773d, 0x773e, 0x7744, 0x7746, 0x7748, 0x7742, 0x7749, 0x775c, + 0x7760, 0x7764, 0x7766, 0x7768, 0x32d2, 0x776b, 0x7771, 0x7779, + 0x7785, 0x777c, 0x7781, 0x777a, 0x7786, 0x778b, 0x778f, 0x7790, + 0x779c, 0x77a8, 0x77a6, 0x77a3, 0x77b3, 0x77b4, 0x77c3, 0x77c6, + 0x77c8, 0x77cb, 0x77dc, 0x77ed, 0x7f4f, 0x77f2, 0x5adf, 0x77f6, + 0x77f5, 0x780f, 0x780c, 0x7838, 0x7824, 0x7821, 0x7837, 0x783d, + 0x7846, 0x784f, 0x784b, 0x786b, 0x786f, 0x7870, + /* 0x17121..0x1717E */ + 0x7871, 0x7874, 0x7873, 0x78aa, 0x78af, 0x78b1, 0x78b6, 0x78c4, + 0x78c3, 0x78c6, 0x78e9, 0x78eb, 0x7903, 0x7909, 0x7912, 0x7914, + 0x7918, 0x7921, 0x791d, 0x791e, 0x7924, 0x7920, 0x792c, 0x792e, + 0x793d, 0x793e, 0x7942, 0x7949, 0x7945, 0x7950, 0x794b, 0x7951, + 0x7952, 0x794c, 0x7955, 0x7997, 0x7998, 0x79a5, 0x79ad, 0x79ae, + 0x79bc, 0x79df, 0x79db, 0x79dd, 0x79d8, 0x79d1, 0x79ed, 0x79ee, + 0x79f1, 0x79f2, 0x79fb, 0x79f8, 0x7a01, 0x7a0f, 0x7a05, 0x79e2, + 0x7a19, 0x7a2b, 0x7a37, 0x7a45, 0x7a42, 0x7a40, 0x7a43, 0x7a3e, + 0x7a55, 0x7a4d, 0x7a5b, 0x7a57, 0x7a5f, 0x7a62, 0x7a65, 0x7a64, + 0x7a69, 0x7a6b, 0x7a6a, 0x7aad, 0x7ab0, 0x7abc, 0x7ac0, 0x7acf, + 0x7ad1, 0x7ad3, 0x7ad4, 0x7ade, 0x7adf, 0x7ae2, 0x7ae3, 0x7ae6, + 0x7aef, 0x7aeb, 0x7aee, 0x7af4, 0x7af1, 0x7af7, + /* 0x17221..0x1727E */ + 0x7afb, 0x7b06, 0x7b18, 0x7b1a, 0x7b1f, 0x7b22, 0x7b23, 0x7b25, + 0x7b27, 0x7b28, 0x7b29, 0x7b2a, 0x7b2e, 0x7b2f, 0x7b32, 0x7b44, + 0x7b43, 0x7b4f, 0x7b4d, 0x7b4e, 0x7b51, 0x7b58, 0x7b74, 0x7b93, + 0x7b83, 0x7b91, 0x7b96, 0x7b97, 0x7b9f, 0x7ba0, 0x7ba8, 0x7bb4, + 0x7bc0, 0x7bca, 0x7bb9, 0x7bc6, 0x7bcf, 0x7bd1, 0x7bd2, 0x7be3, + 0x7be2, 0x7be4, 0x7bd4, 0x7be1, 0x7c3a, 0x7bf2, 0x7bf1, 0x7bf0, + 0x7c15, 0x7c14, 0x7c09, 0x7c13, 0x7c0c, 0x7c06, 0x7c08, 0x7c12, + 0x7c0a, 0x7c04, 0x7c2e, 0x7c1b, 0x7c25, 0x7c24, 0x7c21, 0x7c30, + 0x7c47, 0x7c32, 0x7c46, 0x7c3e, 0x7c5a, 0x7c60, 0x7c67, 0x7c76, + 0x7c78, 0x7ce7, 0x7cec, 0x7cf0, 0x7d09, 0x7d08, 0x7ceb, 0x7d03, + 0x7d06, 0x7d2a, 0x7d26, 0x7daf, 0x7d23, 0x7d1f, 0x7d44, 0x7d15, + 0x7d12, 0x7d41, 0x7d3f, 0x7d3e, 0x7d46, 0x7d48, + /* 0x17321..0x1737E */ + 0x7d5d, 0x7d5e, 0x7d64, 0x7d51, 0x7d50, 0x7d59, 0x7d72, 0x7d89, + 0x7d87, 0x7dab, 0x7d6f, 0x7d7a, 0x7d9a, 0x7da4, 0x7da9, 0x7db2, + 0x7dc4, 0x7dc1, 0x7dbb, 0x7db8, 0x7dba, 0x7dc6, 0x7dcf, 0x7dc2, + 0x7dd9, 0x7dd3, 0x7df8, 0x7de6, 0x7ded, 0x7def, 0x7dfd, 0x7e1a, + 0x7e1b, 0x7e1e, 0x7e75, 0x7e79, 0x7e7d, 0x7e81, 0x7e88, 0x7e8b, + 0x7e8c, 0x7e92, 0x7e95, 0x7e91, 0x7e9d, 0x7ea5, 0x7ea9, 0x7eb8, + 0x7eaa, 0x7ead, 0x7761, 0x7ecc, 0x7ece, 0x7ecf, 0x7ed0, 0x7ed4, + 0x7edc, 0x7ede, 0x7edd, 0x7ee0, 0x7ee5, 0x7ee8, 0x7eef, 0x7ef4, + 0x7ef6, 0x7ef7, 0x7ef9, 0x7efb, 0x7efc, 0x7efd, 0x7f07, 0x7f08, + 0x56b7, 0x7f15, 0x7f21, 0x7f2c, 0x7f3e, 0x7f4a, 0x7f52, 0x7f54, + 0x7f63, 0x7f5f, 0x7f60, 0x7f61, 0x7f66, 0x7f67, 0x7f6c, 0x7f6a, + 0x7f77, 0x7f72, 0x7f76, 0x7f95, 0x7f9c, 0x7fa0, + /* 0x17421..0x1747E */ + 0x382f, 0x49c7, 0x7059, 0x5464, 0x31dc, 0x5199, 0x3653, 0x3de2, + 0x3e14, 0x3e18, 0x3e58, 0x3e5e, 0x3ebe, 0x8028, 0x3ecb, 0x3ef9, + 0x3f00, 0x3f02, 0x3f07, 0x3f1d, 0x3f23, 0x3f34, 0x3f36, 0x3f3d, + 0x3f40, 0x3f45, 0x3f54, 0x3f58, 0x3f64, 0x3f67, 0x3f7d, 0x3f89, + 0x3f9c, 0x3fa7, 0x3faf, 0x3fb5, 0x3fb7, 0x3fc9, 0x3fde, 0x3fe1, + 0x3fe9, 0x400d, 0x4014, 0x4018, 0x4033, 0x4035, 0x4047, 0x813d, + 0x409d, 0x409e, 0x40cb, 0x40d4, 0x40d5, 0x40dd, 0x40f8, 0x411c, + 0x412b, 0x4130, 0x4137, 0x813e, 0x418d, 0x813f, 0x41bc, 0x41b9, + 0x8140, 0x4222, 0x423e, 0x4243, 0x4256, 0x425a, 0x426f, 0x4285, + 0x42c4, 0x42d6, 0x42fc, 0x430a, 0x4318, 0x4339, 0x4343, 0x4365, + 0x437c, 0x43e5, 0x43ed, 0x43f5, 0x4410, 0x4414, 0x4422, 0x4479, + 0x4451, 0x4460, 0x446d, 0x44ce, 0x44be, 0x44bf, + /* 0x17521..0x1757E */ + 0x44c4, 0x44ca, 0x44d0, 0x44f7, 0x44fb, 0x4522, 0x4529, 0x8141, + 0x4567, 0x459d, 0x8142, 0x4600, 0x4609, 0x4615, 0x461e, 0x463a, + 0x4622, 0x4624, 0x462b, 0x4630, 0x4631, 0x4633, 0x46fb, 0x4648, + 0x464c, 0xa8c4, 0x4659, 0x465a, 0x4661, 0x4665, 0x4673, 0x4677, + 0x4678, 0x468d, 0x8143, 0x46a0, 0x46b2, 0x46bb, 0x46c6, 0x46c8, + 0x1b22, 0x46db, 0x46e8, 0x46fa, 0x4713, 0x8029, 0x4733, 0x4766, + 0x4747, 0x4748, 0x477b, 0x4781, 0x4793, 0x4798, 0x479b, 0x47bb, + 0x47f9, 0x47c0, 0x47d7, 0x47fc, 0x4801, 0x4852, 0x481d, 0x482c, + 0x4831, 0x485b, 0x4872, 0x4875, 0x8144, 0x48a3, 0x48a5, 0x48b2, + 0x48c8, 0x48d0, 0x48e8, 0x48ed, 0x48f0, 0x48f1, 0x48fc, 0x490a, + 0x4949, 0xabc4, 0x4935, 0x4942, 0x4957, 0x4963, 0x4964, 0x4968, + 0x4980, 0x8114, 0x49a5, 0x49ad, 0x49cf, 0x1bb6, + /* 0x17621..0x1767E */ + 0x1bc3, 0x49e2, 0x49e9, 0x49ea, 0x49f5, 0x49f6, 0x4a0f, 0x4a15, + 0xad3f, 0x4a3b, 0x4a3e, 0x4a45, 0x4a50, 0x4a56, 0x4a5b, 0x4a6b, + 0x4a73, 0xad63, 0x4a89, 0x4a94, 0x4a9d, 0x4a9e, 0x4aa5, 0x4ae4, + 0x4ae7, 0x1c0f, 0x801d, 0x4b1b, 0x4b1e, 0x4b2c, 0x4b35, 0x4b46, + 0x4b56, 0x4b60, 0x4b65, 0x4b67, 0x4b77, 0x4b82, 0x4ba9, 0x4bad, + 0x8070, 0x4bcf, 0x4bd6, 0x4bd7, 0x4bff, 0x4c05, 0x4c10, 0x4c33, + 0x4c59, 0x4c5c, 0x4caa, 0x4c74, 0x4c76, 0x4c85, 0x4c86, 0x4c98, + 0x4c9c, 0x4cfb, 0x4cc6, 0x4cd4, 0x4ce0, 0x4ceb, 0x4cee, 0xb0fe, + 0x4d04, 0x4d0e, 0x4d2e, 0x4d31, 0x4d39, 0x4d3f, 0x4d58, 0x4d65, + 0x8145, 0x4d82, 0x4d87, 0x4d89, 0x4d94, 0x4daa, 0x4dac, 0x4dbf, + 0x4dc4, 0x4dd6, 0x4dda, 0x4ddb, 0x4ddd, 0x4dfc, 0x8146, 0x4e34, + 0x4e44, 0x4e5c, 0x4e5e, 0x4eab, 0x4eb1, 0x4ec1, + /* 0x17721..0x1777E */ + 0x4ec7, 0x4ece, 0x4f10, 0x4f1a, 0x8147, 0x4f2a, 0x4f2f, 0x4f33, + 0x4f51, 0x4f59, 0x4f5e, 0x4f61, 0x4f62, 0x4f7e, 0x4f88, 0x4f8c, + 0x4f8d, 0x4f94, 0x4fa0, 0x4fa7, 0x4fb6, 0x4fbc, 0x4fc7, 0x4fca, + 0x4ff9, 0x4ff0, 0x4ff5, 0x5005, 0x5006, 0x5028, 0x504a, 0x505d, + 0x505e, 0x504e, 0x5064, 0x5075, 0x5085, 0x50a4, 0x50ab, 0x50b7, + 0x50d4, 0x50d8, 0x50e4, 0x510f, 0x512b, 0x511e, 0x5120, 0x512e, + 0x5130, 0x5146, 0x5147, 0x5151, 0x8148, 0x5152, 0x515c, 0x5160, + 0x5168, 0x8115, 0x5185, 0x5187, 0x5192, 0x51c1, 0x51ba, 0x51c4, + 0x51fe, 0x5200, 0x5215, 0x5255, 0x5256, 0x1e3f, 0x528d, 0x529b, + 0x52be, 0x52c0, 0x52fb, 0xb7f1, 0x5327, 0x5328, 0x8116, 0x5350, + 0x5366, 0x537c, 0x5395, 0x539f, 0x53a0, 0x53a2, 0x53a6, 0x53ab, + 0x53c9, 0x53cf, 0x53d6, 0x53d9, 0x53e3, 0x53e9, + /* 0x17821..0x1787E */ + 0x5407, 0x540a, 0x541a, 0x541b, 0x814a, 0x5426, 0x5428, 0x542a, + 0x542b, 0x542c, 0x542e, 0x542f, 0x5430, 0x5444, 0x5446, 0x5447, + 0x544b, 0x5457, 0x5462, 0x546b, 0x546d, 0x5486, 0x5487, 0x5489, + 0x5498, 0x549c, 0x549f, 0x54a3, 0x5490, 0x54a6, 0x54a8, 0x54a9, + 0x54b5, 0x54bf, 0x54c8, 0x54c9, 0x54da, 0x54ff, 0x5501, 0x5517, + 0x552f, 0x556f, 0x5579, 0x5592, 0x1f72, 0x55ce, 0x55e4, 0x5600, + 0x5602, 0x5608, 0x5615, 0x5616, 0x5619, 0x561e, 0x562d, 0x5635, + 0x5643, 0x564b, 0x5664, 0x5665, 0x566d, 0x566f, 0x5671, 0x5681, + 0x569b, 0x569d, 0x569e, 0x56a6, 0x56aa, 0x56b6, 0x56c5, 0x56cc, + 0x56ce, 0x56d4, 0x56e6, 0x56f1, 0x56fc, 0x570a, 0x5719, 0x5734, + 0x5736, 0x5746, 0x574d, 0x574e, 0x575c, 0x575f, 0x5762, 0x577a, + 0x5780, 0x5794, 0x57aa, 0x57e0, 0x582d, 0xc18e, + /* 0x17921..0x1797E */ + 0x5843, 0x584e, 0x584f, 0x5851, 0x5868, 0x586e, 0x814b, 0x58b0, + 0xc20e, 0x58ad, 0x58e4, 0x58f2, 0x5900, 0x58f7, 0x591c, 0x592e, + 0x5931, 0x5934, 0x814c, 0x814d, 0x5945, 0x5946, 0x814e, 0x814f, + 0x8150, 0x595c, 0x8151, 0x8119, 0x811a, 0x5979, 0x8152, 0x8153, + 0x811b, 0x5998, 0x59b1, 0x59b8, 0x59c8, 0x59ca, 0xc371, 0x59d4, + 0x59de, 0x59eb, 0x59ed, 0x5a03, 0x8154, 0x5a39, 0x5a5d, 0x5a6d, + 0x8155, 0x5a85, 0x5aa0, 0xc4c4, 0x5ab3, 0x5abb, 0x5ace, 0x5aeb, + 0x5afd, 0x5b12, 0x5b2d, 0x5b3b, 0x5b47, 0x5b4e, 0x5b60, 0x5b6d, + 0x5b6f, 0x5b72, 0x5b9e, 0x8156, 0x5bd7, 0x5bd9, 0x5c01, 0x5c31, + 0x5c1e, 0x5c20, 0x5c33, 0x5c36, 0x2264, 0xc7a1, 0x5c59, 0x5c6d, + 0x5c79, 0x5c8f, 0x5c94, 0x5ca0, 0x5cbc, 0x5cd5, 0x5cd9, 0x5cdd, + 0x5d07, 0x5d08, 0x5d13, 0x5d1d, 0x5d23, 0x5d31, + /* 0x17A21..0x17A7E */ + 0x5d41, 0x5d48, 0x5d53, 0x5d5c, 0x5d7a, 0x5d83, 0x5d8b, 0x5da0, + 0x5da6, 0x5dc2, 0x5dcc, 0x5dd6, 0x5de3, 0x8157, 0x5e28, 0x5e08, + 0x5e11, 0x5e15, 0x8159, 0x5e47, 0x5e52, 0x5e61, 0x5e8a, 0x5e8d, + 0x5f47, 0x815a, 0x5f91, 0x5f97, 0x5fbf, 0x5fce, 0x5fdb, 0x5fdf, + 0x5fec, 0x5fee, 0x5ffa, 0x815b, 0x6014, 0x6026, 0x6035, 0x6037, + 0x603c, 0x60ca, 0x60d7, 0x60e0, 0x60f3, 0x6118, 0x614a, 0x6160, + 0x6167, 0x6168, 0x616d, 0x61bb, 0x61ca, 0x61cf, 0x61d7, 0x815c, + 0x2453, 0x245b, 0x6260, 0x6274, 0xd2ff, 0x628e, 0x62a1, 0x62a3, + 0x62a4, 0x62a9, 0x62ae, 0x62b7, 0x62be, 0x62bf, 0x62c6, 0x62d5, + 0x62fd, 0x62fe, 0x6300, 0x6301, 0x6362, 0x6322, 0x632d, 0x633a, + 0x6343, 0x6347, 0x6351, 0x6355, 0x637d, 0x6386, 0x6392, 0x6398, + 0x63a7, 0x63a9, 0x63bf, 0x63c0, 0x63c7, 0x63cf, + /* 0x17B21..0x17B7E */ + 0x63d1, 0x63e1, 0x63ea, 0x6401, 0x6406, 0x640a, 0x815f, 0x6448, + 0x645f, 0x6470, 0x6473, 0x6485, 0x649e, 0x64af, 0x64b4, 0x64ba, + 0x64c0, 0x64c2, 0xd440, 0x6532, 0x651e, 0x6523, 0x652f, 0x6559, + 0x6564, 0x811f, 0x65ad, 0x657a, 0x658c, 0x658f, 0x65a2, 0x65b0, + 0x65cb, 0x65ce, 0x65ed, 0x6612, 0x65ff, 0x6604, 0x6605, 0x6610, + 0xd674, 0x6618, 0x6629, 0x6638, 0x6657, 0x665b, 0x8036, 0x6662, + 0x259d, 0x666c, 0x6675, 0x6698, 0x66b8, 0x66fa, 0x66fc, 0x66fd, + 0x670b, 0x6771, 0x6787, 0x6788, 0x67ac, 0x67ad, 0x67b5, 0x25ea, + 0x67d6, 0x67ec, 0x6806, 0x680a, 0x6810, 0x6814, 0x681f, 0x6898, + 0x68aa, 0x68ca, 0x68ce, 0xd884, 0x68f5, 0x691c, 0x8160, 0x6918, + 0x6919, 0x691a, 0x6927, 0x6930, 0x6932, 0x6939, 0x6940, 0x6994, + 0x8161, 0x69d4, 0x69e5, 0x69f6, 0x6a12, 0x6a15, + /* 0x17C21..0x17C7E */ + 0x6a22, 0x6a37, 0x6a47, 0x6a4e, 0x6a5d, 0x6a61, 0x6a75, 0x6a79, + 0x6aa7, 0x6ad0, 0x6adf, 0x6af4, 0x6af6, 0x8122, 0x8162, 0x8163, + 0x6b46, 0x6b54, 0x6b59, 0x6b69, 0x6b9d, 0x6c49, 0x6c68, 0x8164, + 0x6ce1, 0x6cf4, 0x6cf8, 0x6cfe, 0x8165, 0x6d12, 0x6d1b, 0x6daf, + 0x6dce, 0x6dd1, 0x6dd7, 0x6e20, 0x6e23, 0x6e3d, 0x6e70, 0x6e7b, + 0xe177, 0x6ec0, 0x2844, 0x6efa, 0x6f1e, 0x6f2d, 0x6f36, 0x6f54, + 0xe24d, 0x6fa6, 0x6fb5, 0x6fe4, 0x6fe8, 0x6fee, 0x7008, 0x702d, + 0x8167, 0x7088, 0x7095, 0x7097, 0x7099, 0x709b, 0x70a2, 0x70b3, + 0x70be, 0x70c4, 0x70c5, 0x70c7, 0x70d7, 0x70dd, 0x70de, 0x70ef, + 0x70f4, 0x8126, 0x7114, 0x7115, 0x7116, 0x7122, 0x7123, 0x7127, + 0x712f, 0x7131, 0x7134, 0x713d, 0x7148, 0x715b, 0x7183, 0x719e, + 0x71ac, 0x71b1, 0x71bc, 0x71d7, 0x71fb, 0x71e4, + /* 0x17D21..0x17D7E */ + 0x71e5, 0x71ed, 0x71f1, 0x7207, 0x7210, 0x7238, 0x7239, 0x723a, + 0x723c, 0x7240, 0x7243, 0x724f, 0x7278, 0x7288, 0x72c2, 0x72cb, + 0x72cc, 0x72d3, 0x72e0, 0x72ff, 0x7304, 0x731f, 0x7321, 0x7325, + 0x7348, 0x7349, 0x734a, 0x7364, 0x7365, 0x736a, 0x7370, 0x739b, + 0x73a3, 0x73ba, 0x73c6, 0x73de, 0x73df, 0x7404, 0x73fd, 0x7433, + 0x744a, 0x7463, 0x746b, 0x7471, 0x7472, 0x758e, 0x759f, 0x75a6, + 0x75a9, 0x75ac, 0x75b6, 0x75bd, 0x75cb, 0x75d0, 0x75d3, 0x29b0, + 0x75da, 0x75de, 0x7658, 0x7684, 0x80dc, 0x769d, 0x76a4, 0x76a5, + 0x76d2, 0x76de, 0x8168, 0x76e9, 0x76ef, 0x7733, 0x773b, 0x774d, + 0x774e, 0x774f, 0x775a, 0x776e, 0x7773, 0x7795, 0x77ae, 0x77ba, + 0x77c1, 0x77c9, 0x77de, 0x77db, 0x77f4, 0x8169, 0x780a, 0x781e, + 0x782b, 0x7830, 0x816a, 0x7852, 0x7853, 0x7856, + /* 0x17E21..0x17E7E */ + 0x7857, 0x7859, 0x785a, 0x80d0, 0x7865, 0x786c, 0x78ba, 0x78c8, + 0x78e7, 0x7958, 0x799e, 0x7a02, 0x7a03, 0x7a24, 0x7a2d, 0x7a2e, + 0x7a38, 0x7a4a, 0x7a4e, 0x7a52, 0x7ab6, 0x7ac1, 0x7ac3, 0x7ace, + 0x7ad6, 0x7af9, 0x7b02, 0x7b08, 0x7b20, 0x2c17, 0x7b2d, 0x7b5e, + 0x7b79, 0x7b66, 0x7b72, 0x7b75, 0x7b84, 0x7b8a, 0x7b8f, 0x7b9e, + 0x7ba7, 0x7bc1, 0x7bce, 0x7be5, 0x7bf8, 0x7bfd, 0x7c00, 0x7c23, + 0x7c41, 0x7c4f, 0x7c50, 0x7c53, 0x7c63, 0x7c65, 0x7c77, 0x7d1d, + 0x7d1e, 0x7d43, 0x7d47, 0x7d52, 0x7d63, 0x7d70, 0x7d7c, 0x7d8a, + 0x7d96, 0x7dc0, 0x7dac, 0x7dbc, 0x7dd7, 0xf690, 0x7de7, 0x7e07, + 0x7e15, 0x7e7c, 0x7e9e, 0x7ea4, 0x7eac, 0x7eaf, 0x7eb4, 0x7eb5, + 0x7ec3, 0x7ed1, 0x7f10, 0x7f39, 0x7f57, 0x7f90, 0x7f94, 0x7f97, + 0x7fa2, 0x39f8, 0x3c5b, 0x3e77, 0x5626, 0x5e6b, + /* 0x22121..0x2217E */ + 0x8489, 0x2e02, 0x2e0f, 0x2e12, 0x2e29, 0x2e2b, 0x2e2e, 0x2e40, + 0x2e47, 0x2e48, 0x84a2, 0x2e51, 0x1406, 0x84a4, 0x2e5a, 0x2e69, + 0x2e9d, 0x142c, 0x142e, 0x2eb9, 0x2ebb, 0x8522, 0x2ebc, 0x2ec3, + 0x2ec8, 0x2ed0, 0x2eeb, 0x2eda, 0x2ef1, 0x2ef5, 0x2f00, 0x2f16, + 0x2f64, 0x2f37, 0x2f3e, 0x2f54, 0x2f58, 0x8593, 0x2f77, 0x2f78, + 0x2f7a, 0x2f7d, 0x2f82, 0x2f85, 0x2f92, 0x2f9a, 0x2fe6, 0x2fb2, + 0x2fbe, 0x2fc5, 0x2fcb, 0x2fcf, 0x2fd2, 0x146a, 0x2ff2, 0x3000, + 0x3010, 0x3013, 0x301c, 0x301e, 0x3022, 0x1468, 0x3042, 0x3046, + 0x304e, 0x3053, 0x3057, 0x3063, 0x3066, 0x306a, 0x3070, 0x30a3, + 0x3088, 0x3092, 0x3093, 0x3095, 0x3096, 0x309c, 0x30aa, 0x862b, + 0x30b1, 0x30ba, 0x30bb, 0x30c4, 0x30c7, 0x30f3, 0x8681, 0x30ce, + 0x8671, 0x30d4, 0x30d9, 0x30e1, 0x30e9, 0x1492, + /* 0x22321..0x2237E */ + 0x3108, 0x86f9, 0x3117, 0x311b, 0x874a, 0x3160, 0x8809, 0x3173, + 0x3183, 0x318b, 0x14bc, 0x3198, 0x31a3, 0x31ad, 0x14c7, 0x31bc, + 0x88d6, 0x8928, 0x31f3, 0x31f4, 0x3202, 0x3212, 0x3216, 0x8a4f, + 0x3255, 0x325c, 0x326c, 0x3277, 0x3284, 0x3282, 0x8b07, 0x3298, + 0x8b3a, 0x32a4, 0x32a6, 0x32af, 0x32ba, 0x32bb, 0x32ca, 0x151f, + 0x32d1, 0x8bb9, 0x32f7, 0x330a, 0x330b, 0x3324, 0x3335, 0x333e, + 0x3342, 0x8c7c, 0x8c9d, 0x3367, 0x336c, 0x337a, 0x33a4, 0x33b4, + 0x8dd3, 0x33b7, 0x33c0, 0x8e1d, 0x155d, 0x155e, 0x33d5, 0x33da, + 0x1563, 0x33f4, 0x33f5, 0x3455, 0x3424, 0x3428, 0x156e, 0x3443, + 0x3462, 0x3466, 0x346c, 0x348a, 0x348d, 0x3495, 0x34a0, 0x34a6, + 0x34ad, 0x34ae, 0x34b7, 0x34ba, 0x34bf, 0x34c3, 0x8f45, 0x34ec, + 0x34ef, 0x34f1, 0x34f3, 0x3500, 0x3501, 0x3509, + /* 0x22421..0x2247E */ + 0x353c, 0x3541, 0x15a6, 0x3547, 0x354a, 0x15a8, 0x3560, 0x3561, + 0x3564, 0x8fe1, 0x357d, 0x3582, 0x3588, 0x3591, 0x15c5, 0x35d2, + 0x9095, 0x906d, 0x35bf, 0x35c9, 0x35cc, 0x35d1, 0x35dd, 0x15da, + 0x35e2, 0x9064, 0x35e9, 0x3628, 0x915f, 0x3607, 0x3610, 0x3630, + 0x3637, 0x15f4, 0x363d, 0x363f, 0x3640, 0x3647, 0x365e, 0x3660, + 0x366d, 0x1605, 0x3688, 0x368c, 0x3695, 0x369a, 0x369d, 0x36a8, + 0x36ad, 0x36b2, 0x36c5, 0x36cd, 0x36df, 0x36e8, 0x36f6, 0x36f7, + 0x9201, 0x3715, 0x3723, 0x9255, 0x3729, 0x927b, 0x3745, 0x3746, + 0x374c, 0x374d, 0x9274, 0x3768, 0x376f, 0x3773, 0x3774, 0x3775, + 0x377b, 0x92e4, 0x92d7, 0x37ac, 0x379a, 0x379d, 0x379e, 0x37a8, + 0x37d7, 0x92fd, 0x37cc, 0x9336, 0x9344, 0x37de, 0x37e6, 0x37f0, + 0x164a, 0x37f8, 0x37fb, 0x37fd, 0x3804, 0x381e, + /* 0x22521..0x2257E */ + 0x3820, 0x3827, 0x3832, 0x3839, 0x93c4, 0x3849, 0x384c, 0x3867, + 0x388a, 0x388b, 0x388d, 0x388f, 0x3890, 0x3894, 0x389d, 0x38aa, + 0x38b1, 0x946d, 0x38c3, 0x38cd, 0x38e2, 0x38f3, 0x38f4, 0x3905, + 0x3906, 0x390b, 0x390d, 0x3914, 0x3924, 0x95d7, 0x1691, 0x393d, + 0x1699, 0x3946, 0x1696, 0xd329, 0x395b, 0x395f, 0x9647, 0x3975, + 0x3976, 0x397c, 0x399f, 0x39ae, 0x39bc, 0x39c8, 0x39cd, 0x39de, + 0x39e3, 0x39e4, 0x39e7, 0x39ee, 0x9706, 0x9742, 0x16cf, 0x3a0c, + 0x3a0d, 0x3a17, 0x3a27, 0x3a2d, 0x3a55, 0x3a65, 0x3a7a, 0x3a8b, + 0x3a9c, 0x3a9f, 0x3aa0, 0x3aa2, 0x3ab1, 0x3ab3, 0x3ab5, 0x3aba, + 0x3abf, 0x3ada, 0x3adc, 0x3ae0, 0x3ae5, 0x3af0, 0x3aee, 0x3af5, + 0x3b00, 0x3b08, 0x3b17, 0x3b34, 0x3b2d, 0x3b4c, 0x3b52, 0x3b68, + 0x3b6f, 0x3b7c, 0x3b7f, 0x3b81, 0x3b84, 0x99c3, + /* 0x22821..0x2287E */ + 0x3b96, 0x3bac, 0x1761, 0x3bc0, 0x1762, 0x3bce, 0x3bd6, 0x176c, + 0x176b, 0x3bf1, 0x3bfd, 0x1775, 0x3c03, 0x3c29, 0x3c30, 0x9a56, + 0x3c5f, 0x3c63, 0x3c67, 0x3c68, 0x3c69, 0x3c70, 0x9b2d, 0x9b45, + 0x3c7c, 0x9b78, 0x9b62, 0x3c88, 0x3c8a, 0x17c1, 0x9ba1, 0x9b9c, + 0x3ca0, 0x3ca2, 0x3ca6, 0x3ca7, 0x9b92, 0x3cad, 0x3cb5, 0x9bb7, + 0x3cc9, 0x9be0, 0x9c33, 0x3d06, 0x3d10, 0x3d2b, 0x3d1d, 0x3d20, + 0x3d24, 0x3d26, 0x3d31, 0x3d39, 0x3d42, 0x17e8, 0x3d61, 0x3d6a, + 0x17f4, 0x3d70, 0x9d1e, 0x17fd, 0x3d88, 0x1800, 0x3d92, 0x3d94, + 0x3d97, 0x3d99, 0x3db0, 0x3db2, 0x3db4, 0x9d76, 0x3db9, 0x3dd1, + 0x3dd7, 0x3dd8, 0x3de0, 0x9dfa, 0x3de4, 0x3de9, 0x182f, 0x3e00, + 0x1836, 0x3e12, 0x3e15, 0x1840, 0x3e1f, 0x3e2e, 0x3e3e, 0x3e49, + 0x185c, 0x3e56, 0x1861, 0x3e6b, 0x3e6c, 0x3e6d, + /* 0x22C21..0x22C7E */ + 0x3e6e, 0x9e7b, 0x3ea5, 0x3eaa, 0x3eac, 0x3eb9, 0x3ebf, 0x3ec6, + 0x3ed2, 0x3ed9, 0xa01e, 0x3efd, 0x3f08, 0x3f0e, 0x3f1c, 0xa0ad, + 0x3f1e, 0x3f47, 0x3f63, 0x3f72, 0x3f7e, 0x3f8f, 0x3fa2, 0x3fa4, + 0x3fb8, 0x3fc4, 0x18fa, 0x3fc7, 0x3fcb, 0x3fd2, 0x3fd3, 0x3fd4, + 0x3fe2, 0x3fee, 0x3fef, 0x3ff3, 0x3ffc, 0x1917, 0x4017, 0x4022, + 0x4024, 0x191a, 0x404c, 0x407f, 0x408a, 0x4095, 0x40a8, 0xa1f3, + 0x40b0, 0x40b1, 0x40be, 0x40c8, 0x40d9, 0x40db, 0x40ee, 0x40f2, + 0x40f5, 0x4110, 0x4112, 0x4113, 0x4119, 0x411e, 0x413a, 0x196f, + 0x4141, 0x4146, 0x4160, 0x417c, 0xa25b, 0x4192, 0x4193, 0x4197, + 0x4198, 0x41a5, 0x41a8, 0x41ad, 0xa2ab, 0x41d5, 0x41dd, 0x41df, + 0x41f5, 0xa38f, 0x4215, 0x4223, 0x4229, 0x4246, 0x424c, 0x4251, + 0x4252, 0x4261, 0x4264, 0x427b, 0x426d, 0x4273, + /* 0x22D21..0x22D7E */ + 0x4299, 0x42a6, 0x42d5, 0xa4b8, 0x42fd, 0x4303, 0x430d, 0x4310, + 0xa54f, 0xa550, 0x4332, 0x4335, 0x433b, 0x433c, 0x4341, 0x4344, + 0x434e, 0xa546, 0x4359, 0xa61d, 0xa5a6, 0x436c, 0x4384, 0x4399, + 0xa624, 0x4394, 0x43bd, 0x43f7, 0x43d4, 0x43d5, 0x43dc, 0x43e0, + 0x43eb, 0x43ec, 0x43f2, 0x4409, 0x441e, 0x4425, 0x4429, 0x442f, + 0x445a, 0x445b, 0x445d, 0x4473, 0x447d, 0x4487, 0x4491, 0x449d, + 0x449f, 0x44cb, 0x44cc, 0x44d5, 0x44d7, 0xa7e1, 0x44e4, 0x44e5, + 0x44ff, 0x4504, 0x1a6e, 0x450f, 0x4514, 0x4516, 0x1a73, 0x451e, + 0x4532, 0x4544, 0x4554, 0x456b, 0x457a, 0x4581, 0x4584, 0x4585, + 0x458a, 0x45b2, 0x45b5, 0x45b8, 0x45bf, 0x45c2, 0x45c9, 0x45d4, + 0x1ad6, 0x45f2, 0x45f9, 0x45fc, 0x4604, 0x4608, 0x4621, 0x462a, + 0x4645, 0x4651, 0x464e, 0x1aea, 0xa8c3, 0x4657, + /* 0x22E21..0x22E7E */ + 0x465b, 0x4663, 0xa8f5, 0xa8b6, 0x466a, 0x466b, 0x466c, 0x466d, + 0x467b, 0x4680, 0x4690, 0x4692, 0x4699, 0x1b0e, 0x46ad, 0x46b1, + 0x46b5, 0x1b1a, 0x46bf, 0x1b1c, 0x46ec, 0x1ad7, 0x4701, 0x4705, + 0x4712, 0xa972, 0x4719, 0xa9d3, 0xa9d2, 0x474c, 0x474d, 0x4754, + 0x475d, 0xa9d0, 0xa9e4, 0xa9d5, 0x4774, 0x4776, 0xa9da, 0x4792, + 0xa9df, 0x6363, 0x4810, 0x47b0, 0x47b2, 0x47c3, 0x47c8, 0x47d2, + 0x47d9, 0x47db, 0x47f0, 0x47f7, 0xaa4a, 0xaa51, 0xaa4b, 0x4818, + 0x481f, 0x482d, 0xaa65, 0x4833, 0x483b, 0x483e, 0x4844, 0x4845, + 0x4849, 0x484c, 0x4855, 0x4857, 0x1b77, 0x486b, 0x486e, 0x487a, + 0x487c, 0x4882, 0x4890, 0x4896, 0x1b6d, 0x4898, 0x4899, 0x489a, + 0x489c, 0x48aa, 0x48ab, 0x48b4, 0x48bb, 0x48fb, 0xaae4, 0xab5a, + 0x8113, 0x48c3, 0x48c5, 0x48cc, 0x48cf, 0x48d6, + /* 0x22F21..0x22F7E */ + 0x48d9, 0x48e4, 0x48e5, 0x48ec, 0x48f7, 0x4903, 0x4907, 0x1b87, + 0x1b88, 0xab94, 0x493b, 0x1b8d, 0x4946, 0x4969, 0x496c, 0x4972, + 0x497a, 0x497f, 0x4992, 0x1ba4, 0x4996, 0x4998, 0x49a6, 0x49b0, + 0x49b7, 0x49ba, 0x49bc, 0x49c0, 0x49d1, 0x49d6, 0xac39, 0xac47, + 0x4a30, 0xac38, 0xac3a, 0x49e3, 0x49ee, 0x49ef, 0x49f3, 0x1bcd, + 0x49f4, 0x49fe, 0x4a11, 0x4a1a, 0x4a1d, 0xad1c, 0x4a32, 0x4a33, + 0x4a34, 0x4a3f, 0x4a46, 0x4a49, 0x4a7a, 0x4a4e, 0x4a52, 0x4a64, + 0xad0c, 0x4a7e, 0x4a83, 0x4a8b, 0x1bf0, 0x4a91, 0x4a9f, 0x4aa1, + 0xad64, 0x4aab, 0x4abd, 0x4ac6, 0x4ad4, 0x4ad0, 0x4adc, 0x4add, + 0xadff, 0xade7, 0x4aec, 0x4af1, 0x4af2, 0x4af3, 0x4afd, 0xae24, + 0x4b0b, 0x4b0f, 0x4b10, 0x4b11, 0xae3d, 0x4b17, 0x1c26, 0x4b2f, + 0x4b4a, 0x4b58, 0x4b6c, 0x4b75, 0x4b7a, 0x4b81, + /* 0x26E21..0x26E7E */ + 0x4b9b, 0x4bae, 0xaf98, 0x4bbd, 0x4bbe, 0x4bc7, 0x4bc8, 0x4bc9, + 0x4bda, 0x4be6, 0x4be7, 0x4bee, 0x4bf1, 0x4c02, 0x4c0a, 0x4c0e, + 0x4c35, 0x4c36, 0x4c3a, 0xb07f, 0x4c3f, 0x4c4d, 0x4c5b, 0x4c6d, + 0x4c84, 0x4c89, 0x1cc3, 0x4c94, 0x4c95, 0x4c97, 0x4cad, 0x4cc2, + 0x4cd0, 0x1cd2, 0x4cd6, 0x4cda, 0x4cdc, 0x4ce9, 0x4cec, 0x4ced, + 0xb100, 0x4d00, 0x4d0a, 0x4d24, 0x4d26, 0x4d27, 0x4c67, 0x4d2f, + 0x4d3c, 0x4d5b, 0x4d5e, 0x4d60, 0x4d70, 0x4d80, 0x4d81, 0x4d8a, + 0x4d8d, 0x4d91, 0x4d98, 0xb140, 0x4e17, 0xb1fa, 0xb1f9, 0xb1d3, + 0x4dab, 0x4dae, 0x4db4, 0x4dc2, 0x4d34, 0x4dc8, 0x4dce, 0x4dcf, + 0x4dd0, 0x4ddf, 0x4de9, 0x4df6, 0x4e36, 0x4e1e, 0x4e22, 0x4e27, + 0x1d11, 0x4e32, 0x4e3c, 0x4e48, 0x4e49, 0x4e4b, 0x4e4c, 0x4e4f, + 0x4e51, 0x4e53, 0x4e54, 0x4e57, 0x4e63, 0x1d1e, + /* 0x26F21..0x26F7E */ + 0x4e93, 0x4ea7, 0x4eb4, 0x4ebf, 0x4ec3, 0x4eca, 0x4ed9, 0x4f35, + 0x4eeb, 0x4ef9, 0x4efb, 0x4f0a, 0x4f0c, 0x4f18, 0x4f25, 0x4f36, + 0x4f3c, 0xb27e, 0x4f52, 0x4f57, 0x4f5a, 0x4f60, 0x4f68, 0x4f98, + 0x4f7d, 0x4f90, 0x4f96, 0x4fbe, 0x4f9f, 0x4fa5, 0x4faf, 0x1d64, + 0x4fb5, 0x4fc8, 0x4fc9, 0x4fda, 0x4fde, 0x4fe9, 0xb396, 0x4ffc, + 0x5000, 0x5007, 0x500a, 0x5023, 0xb403, 0x5039, 0x503a, 0x503c, + 0x5043, 0x5047, 0x504b, 0x1d9a, 0x5054, 0x5065, 0x5069, 0x506c, + 0x506e, 0x5076, 0x507e, 0x5081, 0x5086, 0x5095, 0x5097, 0x50bb, + 0xb4c6, 0x509f, 0x50b1, 0xb4fe, 0x50ec, 0x50ca, 0x50d1, 0x50d3, + 0x50dc, 0x5103, 0x5104, 0x5106, 0x5107, 0x5108, 0x510c, 0x1dc0, + 0x512f, 0x5131, 0x5150, 0x514a, 0x5153, 0x515e, 0x1dd4, 0x5196, + 0x5180, 0x519b, 0x51a0, 0x51a2, 0x51ae, 0x51af, + /* 0x27021..0x2707E */ + 0x51b3, 0xb5bc, 0x51cb, 0x51d3, 0x51d9, 0x51dc, 0x5207, 0x1e05, + 0x8149, 0x522b, 0x5234, 0x5238, 0x5239, 0x2e2c, 0x5242, 0x5253, + 0x5257, 0x5263, 0xb629, 0x526e, 0x526f, 0x5278, 0x527f, 0x528e, + 0xb6a5, 0x52ad, 0x52ae, 0x52b0, 0x52b1, 0x52c1, 0x1e60, 0x52cc, + 0x1e66, 0x1e68, 0x52f3, 0x52fa, 0x5307, 0x5312, 0x5318, 0x5319, + 0x1e83, 0x5339, 0x532c, 0x5331, 0x5333, 0x533d, 0x5352, 0x1e94, + 0x536b, 0x536c, 0xb896, 0x536e, 0x536f, 0x5371, 0x5377, 0x5381, + 0x5385, 0x538a, 0x5394, 0x5398, 0x539c, 0x539e, 0x53a5, 0x53a8, + 0x53b5, 0x53b7, 0x53b9, 0x53bc, 0x53bf, 0x53c5, 0x53cb, 0x53e1, + 0x53e7, 0x53f9, 0x5413, 0x53fa, 0x5401, 0x5424, 0x5431, 0x5439, + 0x5453, 0x5440, 0x5443, 0x544d, 0x5452, 0x545d, 0x5471, 0x5481, + 0x5485, 0x5488, 0xb94d, 0x5492, 0x5497, 0x5499, + /* 0x27121..0x2717E */ + 0x54a0, 0x54a1, 0x54a5, 0x54aa, 0x54ab, 0x54b9, 0x54bb, 0x54ba, + 0x54d6, 0x54d8, 0x54de, 0x54ef, 0x54eb, 0xba56, 0x54fa, 0xba6f, + 0x5520, 0x5524, 0x552a, 0x1f57, 0xbb16, 0x553d, 0x553e, 0x5540, + 0x5548, 0x554e, 0x5550, 0x5552, 0x556c, 0x5572, 0x5571, 0x557a, + 0x557d, 0x557e, 0x5581, 0xbc14, 0x558c, 0x1f75, 0x55a2, 0x1f77, + 0x55b0, 0x55b7, 0x55bf, 0x55c0, 0x55c6, 0x55cf, 0x55d3, 0x55dd, + 0x55df, 0x55e0, 0x55e7, 0x55ec, 0x55ee, 0x55f1, 0x55f9, 0x5603, + 0x5618, 0x5607, 0x560f, 0x1fae, 0xbd0e, 0x5613, 0x561b, 0x561c, + 0xbd37, 0x5625, 0x5628, 0x563c, 0x5633, 0xbd6a, 0x1fc9, 0x5641, + 0xbd8b, 0x5649, 0x5655, 0x1fd7, 0x566e, 0x5695, 0x569c, 0x56a1, + 0x56a0, 0x56a7, 0x56a8, 0x56af, 0xbe4a, 0x56c9, 0xbe55, 0x56e8, + 0x56ec, 0xbf22, 0x5717, 0x571a, 0x572d, 0x5735, + /* 0x27221..0x2727E */ + 0xbfa9, 0x2039, 0xbfe5, 0xbfcd, 0x5758, 0x5760, 0x576a, 0xc01e, + 0x5772, 0x577c, 0x577d, 0xc04c, 0x2058, 0x579a, 0x579f, 0x57a2, + 0x57a4, 0x57a9, 0x57de, 0x57df, 0x57e4, 0x57e6, 0x57ea, 0x57ec, + 0x2093, 0x57f0, 0x57f4, 0x57fb, 0xc12e, 0x5805, 0x5806, 0x5809, + 0x580d, 0x5819, 0x5821, 0x582c, 0x5847, 0x5864, 0x586a, 0xc1d9, + 0x588a, 0x5894, 0x58a4, 0x589d, 0x589e, 0x589f, 0x58bb, 0x58c8, + 0x58cc, 0x58ce, 0x58d5, 0x58e0, 0x58e1, 0x58e6, 0x58f9, 0x58fa, + 0x58fb, 0x58fe, 0xc2a7, 0x5910, 0x591b, 0x5930, 0x5925, 0x593b, + 0x594a, 0x5958, 0x595b, 0x2105, 0x5967, 0x5972, 0x5994, 0x5995, + 0x5996, 0x599b, 0x59a1, 0x59a9, 0x59b4, 0x59bb, 0x59c2, 0x59c7, + 0x59cc, 0x59cd, 0x59d6, 0x2148, 0xc3a9, 0xc3b4, 0x214f, 0x5a0a, + 0x5a11, 0x5a15, 0x5a1b, 0x5a1e, 0x2163, 0x5a2d, + /* 0x27321..0x2737E */ + 0x5a38, 0x5a47, 0x5a4c, 0x5a56, 0x5a59, 0x5a5c, 0x5a5f, 0x5a60, + 0x5a67, 0x5a6a, 0x5a75, 0x5a78, 0x5a82, 0x5a8a, 0x5a90, 0x5aa3, + 0x5aac, 0xc4d4, 0x21b4, 0x5ab9, 0x5abc, 0x5abe, 0x21bf, 0x5acc, + 0x5ad1, 0x5ae7, 0x5ae8, 0x5af4, 0xc5e4, 0xc5e3, 0x5b07, 0xc5f1, + 0x5b3d, 0x5b27, 0x5b2a, 0x5b2e, 0x5b2f, 0x5b31, 0x21e6, 0x21f3, + 0x5b7f, 0x5b41, 0x21ee, 0x5b55, 0x5b79, 0x5b64, 0x5b66, 0x5b69, + 0x5b73, 0xc632, 0x2207, 0x5b90, 0x5b91, 0x5b9b, 0x220e, 0x5baf, + 0x5bb5, 0x5bbc, 0x5bc5, 0x5bca, 0xc6cb, 0xc6e4, 0x5bd4, 0x5bd6, + 0x5bda, 0x5bea, 0x5bf0, 0x5c03, 0x5c0b, 0x5c0e, 0x5c0f, 0x5c26, + 0x5c45, 0x5c4a, 0x5c51, 0x5c57, 0x5c5e, 0x5c61, 0x5c69, 0x5c6e, + 0x5c6f, 0x5c70, 0xc82e, 0xc856, 0xc865, 0x5ca6, 0xc862, 0x5cb6, + 0x5cb7, 0x5cbf, 0xc8d8, 0x5cc4, 0xc8c2, 0x5cc8, + /* 0x27421..0x2747E */ + 0x5ccd, 0xc8e8, 0x5cd7, 0xc923, 0x5ce6, 0x5ceb, 0xc95c, 0x5cf5, + 0x5d03, 0x5d09, 0x22c6, 0x5d12, 0x5d1e, 0xc9e0, 0xc9d4, 0x5d3d, + 0x5d3e, 0x5d40, 0x5d47, 0xca0c, 0xc9fb, 0x22d6, 0x5d59, 0x5d5a, + 0x5d6a, 0x5d70, 0x22dd, 0x5d7f, 0xca17, 0x5d86, 0x5d88, 0x5d8c, + 0x5d97, 0xca60, 0x5d9d, 0x5da7, 0x5daa, 0x5db6, 0x5db7, 0x5dc0, + 0x5dd7, 0x5dd9, 0x5de6, 0x5df1, 0x5df9, 0x2302, 0xcaed, 0x8158, + 0x5e10, 0x5e17, 0x5e1d, 0x5e20, 0x5e27, 0x5e2c, 0x5e45, 0x5e73, + 0x5e75, 0x5e7e, 0x5e86, 0x5e87, 0x232b, 0x5e91, 0x5e98, 0x5e9a, + 0x2343, 0x5f3c, 0x5f3b, 0x5f3e, 0x5f43, 0x5f44, 0x5f4f, 0x14c1, + 0xcb70, 0x5f52, 0xcb86, 0x5f61, 0x5f63, 0x5f64, 0x5f6d, 0x5f7d, + 0x5f7e, 0xcc4c, 0x5f90, 0x317b, 0xb10e, 0x5f96, 0x5f9c, 0x5fad, + 0xcd02, 0x5fc3, 0x5fcf, 0x5fe3, 0x5fe5, 0x5fef, + /* 0x27521..0x2757E */ + 0x5ff2, 0x6002, 0x600a, 0x6008, 0x600e, 0x6011, 0x6016, 0x6024, + 0x602c, 0x6030, 0x6043, 0x6066, 0x6071, 0x6075, 0x607b, 0x6099, + 0x609c, 0x60a4, 0x60a7, 0x60b8, 0xce7e, 0x60c5, 0x60d5, 0x60d8, + 0x60e6, 0xceb0, 0x610d, 0x60f5, 0x60fb, 0x23ee, 0x6135, 0x6116, + 0x611e, 0x23f0, 0x6124, 0x6127, 0x612c, 0xcf1d, 0x613d, 0x2408, + 0x6169, 0x2417, 0x6181, 0x241c, 0x6184, 0x6185, 0x2422, 0x6198, + 0x61b2, 0x61c1, 0x61c3, 0x61d6, 0x61db, 0xd0dd, 0x61e4, 0xd0ea, + 0x61ec, 0xd151, 0x61fd, 0x61ff, 0xd16f, 0x6204, 0xd1dd, 0x6219, + 0x6221, 0x6222, 0xd21e, 0x6232, 0x6234, 0x623c, 0x6246, 0x6249, + 0x6245, 0xd258, 0x624b, 0x2476, 0x624f, 0x247a, 0x6257, 0xd28c, + 0x625c, 0x6263, 0xd2b7, 0x815d, 0x815e, 0x6279, 0x2491, 0x627d, + 0x627f, 0x6283, 0x628a, 0x6293, 0x62a7, 0x62a8, + /* 0x27621..0x2767E */ + 0x62b2, 0x62b4, 0x62ba, 0x62bc, 0x62e2, 0x62e8, 0x62f7, 0x6307, + 0x6308, 0x630c, 0x6354, 0x631b, 0x631d, 0x6330, 0x633c, 0x6344, + 0x6357, 0x24be, 0x637f, 0x24d4, 0x24b3, 0x638d, 0x6394, 0x6395, + 0x639b, 0x639d, 0x63c9, 0x63d0, 0x63d4, 0x63dd, 0x63e5, 0x63f9, + 0x640f, 0x6411, 0x6415, 0xd373, 0x6417, 0x6439, 0x644a, 0x644f, + 0x6451, 0x6452, 0x6459, 0x645a, 0x645c, 0xd3dd, 0x6465, 0x6476, + 0x6478, 0x647c, 0x6481, 0x250d, 0x64dc, 0x6497, 0x64a6, 0x64be, + 0x2508, 0x64ce, 0x64cf, 0x64d3, 0xd465, 0x64e7, 0x64ea, 0x64ef, + 0x64f0, 0x64f1, 0x64fa, 0x64fd, 0x650c, 0x651b, 0x6524, 0x6525, + 0x652b, 0x6534, 0x654f, 0x656f, 0x2525, 0x2543, 0x653e, 0x6551, + 0x6553, 0x655e, 0x6561, 0x6562, 0xd594, 0x657b, 0x657d, 0x657f, + 0x6581, 0x6586, 0x6593, 0x659d, 0x659f, 0xd5f8, + /* 0x27721..0x2777E */ + 0xd5f6, 0xd5f7, 0x65b7, 0x65bc, 0x65c7, 0x65ca, 0x65d8, 0x65d9, + 0x65df, 0x65e1, 0x65e6, 0x65f6, 0x6600, 0x6611, 0x661e, 0x6621, + 0x6624, 0x6627, 0xd68d, 0x6639, 0x663c, 0xd6b9, 0x6640, 0x8120, + 0x6653, 0x6656, 0x666f, 0x6677, 0x667a, 0x6687, 0x6689, 0x668d, + 0x6691, 0x669c, 0x669d, 0x66a8, 0x8121, 0x66b1, 0x66b3, 0x66c1, + 0x66c3, 0x66d1, 0x66d5, 0x66d7, 0x66e3, 0x66e6, 0x25b8, 0x6705, + 0x6707, 0x670e, 0x6710, 0x6713, 0x6719, 0x671f, 0x6721, 0x6723, + 0x6731, 0x673a, 0x673e, 0x6740, 0x6743, 0x6751, 0x6758, 0x6764, + 0x6765, 0x6772, 0x677c, 0xd75b, 0xd75a, 0x67a7, 0x6789, 0x678b, + 0x6793, 0x67a0, 0xd77e, 0x25e5, 0x67be, 0xd790, 0x67c1, 0x67ce, + 0x67f5, 0x67df, 0xd7c9, 0x67e3, 0x67e5, 0x67e6, 0x67ea, 0x67eb, + 0x67ed, 0x6801, 0x6803, 0x680b, 0x6813, 0x6828, + /* 0x27821..0x2787E */ + 0x682e, 0x6832, 0x683c, 0x260f, 0x684a, 0x6858, 0x685f, 0x6864, + 0xd815, 0xd814, 0x6869, 0xd831, 0x686f, 0x68a0, 0x68bc, 0x68bd, + 0x68be, 0x68c0, 0x68d2, 0xd893, 0x68d1, 0x68d3, 0x68db, 0x68f0, + 0x68f1, 0x2641, 0x6901, 0xd90e, 0x6937, 0xd923, 0x6942, 0x6945, + 0x6949, 0xd952, 0x2665, 0x6962, 0x6980, 0x6989, 0x6990, 0x699f, + 0x69b0, 0x69b7, 0x69d6, 0x69d8, 0x69eb, 0x26a1, 0x69f1, 0x69f3, + 0x69fd, 0x69ff, 0x26af, 0x6a11, 0x6a14, 0xda85, 0x6a21, 0x6a35, + 0x6a3e, 0x6a45, 0x6a4d, 0x6a58, 0x6aae, 0x6a90, 0x6ab7, 0x6abe, + 0x6ad7, 0x6afc, 0xdb84, 0x6b0a, 0x6b05, 0x6b0d, 0x6b1c, 0x6b1f, + 0x6b2d, 0x6b43, 0x270c, 0x6b51, 0x6b5e, 0x6b76, 0x6b7f, 0x6b81, + 0x6b8b, 0x6b94, 0x6b95, 0x6b9c, 0x6b9e, 0x6c39, 0xdcb3, 0x6c3d, + 0xdcbe, 0xdcc7, 0x6c45, 0x6c47, 0x6c4f, 0x6c54, + /* 0x27921..0x2797E */ + 0x6c57, 0x6c69, 0x6c6d, 0x6c73, 0xddb8, 0x6c93, 0x6c92, 0x6c99, + 0x2764, 0x6c9b, 0x6ca4, 0x6cd6, 0x6cd5, 0x6cd9, 0xde20, 0x6cf0, + 0x6cf1, 0xde90, 0x6d09, 0x6d0e, 0x6d6c, 0x6d84, 0x6d95, 0x6da6, + 0xdfb7, 0x6dc6, 0x6dc8, 0x6dd9, 0x6dec, 0x6e0c, 0x27fd, 0x6dfd, + 0x6e06, 0xe08a, 0x6e14, 0x6e16, 0x6e21, 0x6e22, 0x6e27, 0xe0bb, + 0x2816, 0x6e36, 0x6e39, 0x6e4b, 0x6e54, 0x6e62, 0x6e6c, 0x6e6d, + 0x6e6f, 0x6e98, 0x6e9e, 0x6eae, 0x6eb3, 0x6eb5, 0x6eb6, 0x6ebb, + 0xe182, 0x6ed1, 0x6ed4, 0x284e, 0x6ef9, 0xe1f3, 0x6f00, 0x6f08, + 0x6f17, 0x6f2b, 0x6f40, 0x6f4a, 0x6f58, 0xe28c, 0x6fa4, 0x6fb4, + 0x8166, 0x6fb6, 0xe2d5, 0x6fc1, 0x6fc6, 0x8124, 0x6fca, 0x6fcd, + 0x6fd3, 0x6fd5, 0x6fe0, 0x6ff1, 0x6ff5, 0x6ffb, 0x7002, 0x700c, + 0x7037, 0xe36b, 0x7043, 0x7044, 0x705d, 0xe3c8, + /* 0x27A21..0x27A7E */ + 0xe3c9, 0x7085, 0x708c, 0x7090, 0x761d, 0x70a1, 0x28b5, 0x70b0, + 0x70b6, 0x70c3, 0x70c8, 0xe4d7, 0x70dc, 0x70df, 0xe4fa, 0x70f6, + 0x70f2, 0x7100, 0x70eb, 0x70fe, 0x70ff, 0x7104, 0x7106, 0x7118, + 0x711c, 0x711e, 0x7137, 0x7139, 0x713a, 0x7146, 0x7147, 0x7157, + 0x7159, 0x7161, 0x7164, 0x7174, 0x7179, 0x7185, 0x718e, 0x71a8, + 0x71ae, 0x71b3, 0x71b6, 0x71c3, 0x71c4, 0x71da, 0xe549, 0xe546, + 0x71ec, 0x71ee, 0x7201, 0x720a, 0x7216, 0x7217, 0xe56b, 0x7233, + 0x7242, 0x7247, 0x724a, 0x724e, 0x7251, 0x7256, 0x7259, 0x7260, + 0x7261, 0x7265, 0x7267, 0x7268, 0xe587, 0xe588, 0x727c, 0x727d, + 0x727f, 0x7289, 0x728d, 0x7297, 0x7299, 0x729f, 0x72a7, 0x72ab, + 0xe5ba, 0xe5bb, 0x72b2, 0x72bf, 0x72c0, 0x72c6, 0x72ce, 0x72d0, + 0x72d7, 0x72d9, 0x72e5, 0x72e7, 0x7311, 0xe61e, + /* 0x27B21..0x27B7E */ + 0xe629, 0x72f7, 0x72f9, 0x72fb, 0x7302, 0x730d, 0x7315, 0x731d, + 0x731e, 0x7327, 0x7329, 0xe671, 0xe643, 0x7347, 0x7351, 0x7357, + 0x735a, 0x736b, 0x7371, 0x7373, 0x73a1, 0xe699, 0xe6cd, 0x7388, + 0x738b, 0x738f, 0x739e, 0x73f5, 0xe6e4, 0xe6dd, 0x73f1, 0x73c1, + 0x73c7, 0x73dc, 0x73e2, 0x73e7, 0x7409, 0x740f, 0x7416, 0x7417, + 0x73fb, 0x7432, 0x7434, 0x743b, 0x7445, 0xe7c1, 0xe7ef, 0x746d, + 0x746f, 0x7578, 0x7579, 0x7586, 0x758c, 0x758d, 0xe810, 0x75ab, + 0x75b4, 0xe871, 0x75c8, 0xe8fb, 0xe91f, 0x762c, 0x7633, 0x7634, + 0xe936, 0x763c, 0x7641, 0x7661, 0xe989, 0x7682, 0xe9eb, 0x769a, + 0xea32, 0x29e7, 0x76a9, 0x76af, 0x76b3, 0x76ba, 0x76bd, 0x29fa, + 0xeaf8, 0x76d8, 0x76da, 0x76dd, 0x2a04, 0x7714, 0x7723, 0x2a29, + 0x7736, 0x7741, 0x7747, 0x7755, 0x7757, 0x775b, + /* 0x27C21..0x27C7E */ + 0x776a, 0xeba0, 0xebb1, 0x7796, 0x779a, 0x779e, 0x77a2, 0x77b1, + 0x77b2, 0x77be, 0x77cc, 0x77d1, 0x77d4, 0x77d8, 0x77d9, 0x77e1, + 0x77f1, 0x7804, 0x780d, 0x780e, 0x7814, 0x7816, 0x2abc, 0xec90, + 0x7823, 0x7832, 0x7833, 0x7825, 0x7847, 0x7866, 0x78ab, 0x78ad, + 0x78b0, 0xedcf, 0x78b7, 0x78b8, 0x78bb, 0x78bc, 0x78bf, 0x78c2, + 0x78c7, 0x78cb, 0x78e0, 0xee7f, 0x78e1, 0x78e3, 0x78e5, 0x78ea, + 0x78f0, 0x78f1, 0x78f3, 0x7908, 0x2b3b, 0xeef0, 0x7916, 0x7917, + 0xef19, 0x791a, 0x791b, 0x791c, 0xef50, 0x7931, 0x7932, 0x7933, + 0x793a, 0x793b, 0x793c, 0x7940, 0x7941, 0x7946, 0x794d, 0x794e, + 0x795c, 0x795f, 0x7960, 0x79a3, 0x79a6, 0x79b9, 0x79bd, 0x79bf, + 0x79c3, 0x79c9, 0x79d4, 0x79d9, 0x79de, 0xf0c6, 0x79f0, 0x79f9, + 0x79fc, 0x7a0a, 0x7a11, 0x7a16, 0x7a1a, 0x7a20, + /* 0x27D21..0x27D7E */ + 0x7a31, 0x7a36, 0x7a44, 0x7a4c, 0x7a58, 0x2bc2, 0x7aaf, 0x2bca, + 0x7ab7, 0x2bd2, 0x7ab9, 0xf172, 0x7ac6, 0x7ad0, 0x7ad2, 0x7ad5, + 0x2be8, 0x7adc, 0x7ae0, 0x7ae5, 0x7ae9, 0x7b03, 0x7b0c, 0x7b10, + 0x7b12, 0x7b16, 0x7b1c, 0x7b2b, 0x7b33, 0x7b3d, 0x2c20, 0x7b4b, + 0x7b63, 0x7b65, 0x7b6b, 0x7b6c, 0x7b73, 0x7b76, 0x7b77, 0x7ba6, + 0x7bac, 0x7bb1, 0xf2db, 0xf33d, 0x7bb2, 0x7bb8, 0x7bbe, 0x7bc7, + 0x7bf3, 0x7bd8, 0x7bdd, 0x7be7, 0x7bea, 0x7beb, 0x7bef, 0x7bee, + 0xf315, 0x7bfa, 0xf38a, 0x7bf7, 0xf349, 0x7c16, 0x7c18, 0x7c19, + 0x7c1a, 0x7c1d, 0x7c22, 0x7c27, 0x7c29, 0x7c2a, 0xf3c4, 0x7c31, + 0x7c36, 0x7c37, 0x7c45, 0x7c5c, 0xf3e9, 0x7c49, 0x7c4a, 0xf3db, + 0x7c54, 0x7c58, 0x7c5b, 0x7c5d, 0x7c5f, 0x7c69, 0x7c6a, 0x7c6b, + 0x7c6d, 0x7c6e, 0x7c70, 0x7c72, 0x7c75, 0x7c7a, + /* 0x27E21..0x27E7E */ + 0x7ce6, 0x7cf2, 0x7d0b, 0x7d02, 0xf4ce, 0x7d11, 0x7d17, 0x7d18, + 0xf52f, 0x2cc4, 0xf51a, 0x7d32, 0x2cd1, 0x7d42, 0x7d4a, 0x7d5f, + 0x7d62, 0xf5f9, 0x7d69, 0x7d6b, 0xf582, 0x7d73, 0x7d76, 0x7d77, + 0x7d7e, 0x7d84, 0x7d8d, 0x7d99, 0x7da1, 0x7dbf, 0x7db5, 0x7db9, + 0x7dbd, 0x7dc3, 0x7dc7, 0x7dc9, 0x7dd6, 0x7dda, 0x7ddf, 0x7de0, + 0x7de3, 0x7df4, 0x2d07, 0x7e0a, 0x7e02, 0x7e0d, 0x7e19, 0x7e1c, + 0x7e1d, 0x7e7b, 0x9f18, 0x7e80, 0x7e85, 0x7e9b, 0x7ea8, 0xf70c, + 0x7ebd, 0xf7b7, 0x7edf, 0x7ee7, 0x7eee, 0x7eff, 0x7f02, 0x2d77, + 0x7f03, 0x7f17, 0x7f19, 0x7f2f, 0x7f37, 0x7f3a, 0x7f3d, 0x7f41, + 0x7f45, 0x7f46, 0x7f53, 0x7f55, 0x7f58, 0xf8f1, 0x7f5d, 0xf902, + 0x7f69, 0xf91a, 0x7f6d, 0x7f70, 0x7f75, 0xf9b2, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +}; + +static const ucs4_t jisx0213_to_ucs_pagestart[] = { + 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x1e00, 0x1f00, 0x2000, + 0x2100, 0x2200, 0x2300, 0x2400, 0x2500, 0x2600, 0x2700, 0x2900, + 0x3000, 0x3100, 0x3200, 0x3300, 0x3400, 0x3500, 0x3600, 0x3700, + 0x3800, 0x3900, 0x3a00, 0x3b00, 0x3c00, 0x3d00, 0x3e00, 0x3f00, + 0x4000, 0x4100, 0x4200, 0x4300, 0x4400, 0x4500, 0x4600, 0x4700, + 0x4800, 0x4900, 0x4a00, 0x4b00, 0x4c00, 0x4d00, 0x4e00, 0x4f00, + 0x5000, 0x5100, 0x5200, 0x5300, 0x5400, 0x5500, 0x5600, 0x5700, + 0x5800, 0x5900, 0x5a00, 0x5b00, 0x5c00, 0x5d00, 0x5e00, 0x5f00, + 0x6000, 0x6100, 0x6200, 0x6300, 0x6400, 0x6500, 0x6600, 0x6700, + 0x6800, 0x6900, 0x6a00, 0x6b00, 0x6c00, 0x6d00, 0x6e00, 0x6f00, + 0x7000, 0x7100, 0x7200, 0x7300, 0x7400, 0x7500, 0x7600, 0x7700, + 0x7800, 0x7900, 0x7a00, 0x7b00, 0x7c00, 0x7d00, 0x7e00, 0x7f00, + 0x8000, 0x8100, 0x8200, 0x8300, 0x8400, 0x8500, 0x8600, 0x8700, + 0x8800, 0x8900, 0x8a00, 0x8b00, 0x8c00, 0x8d00, 0x8e00, 0x8f00, + 0x9000, 0x9100, 0x9200, 0x9300, 0x9400, 0x9500, 0x9600, 0x9700, + 0x9800, 0x9900, 0x9a00, 0x9b00, 0x9c00, 0x9d00, 0x9e00, 0x9f00, + 0xf900, 0xfa00, 0xfe00, 0xff00, 0x20000, 0x20180, 0x20300, 0x20400, + 0x20500, 0x20600, 0x20700, 0x20800, 0x20900, 0x20a00, 0x20b00, 0x20d00, + 0x20e00, 0x20f00, 0x21200, 0x21300, 0x21400, 0x21500, 0x21600, 0x21700, + 0x21800, 0x21900, 0x21c00, 0x21d00, 0x21e00, 0x21f00, 0x22100, 0x22200, + 0x22300, 0x22600, 0x22800, 0x22900, 0x22a00, 0x22b00, 0x22c00, 0x22d00, + 0x23100, 0x23300, 0x23400, 0x23500, 0x23600, 0x23700, 0x23800, 0x23a00, + 0x23c00, 0x23d00, 0x23f00, 0x24000, 0x24100, 0x24300, 0x24600, 0x24700, + 0x24800, 0x24a00, 0x24b00, 0x24c00, 0x24d00, 0x24e00, 0x25000, 0x25100, + 0x25200, 0x25400, 0x25500, 0x25700, 0x25900, 0x25a00, 0x25b80, 0x25d00, + 0x25e00, 0x25f00, 0x26000, 0x26200, 0x26300, 0x26400, 0x26600, 0x26700, + 0x26800, 0x26900, 0x26a00, 0x26c00, 0x26e00, 0x26f00, 0x27080, 0x27380, + 0x27600, 0x27700, 0x27900, 0x27a00, 0x27b00, 0x27c00, 0x27d80, 0x27f00, + 0x28000, 0x28200, 0x28380, 0x28500, 0x28600, 0x28900, 0x28a00, 0x28b00, + 0x28d00, 0x28e00, 0x28f00, 0x29200, 0x29400, 0x29500, 0x29600, 0x29700, + 0x29800, 0x29a00, 0x29d00, 0x29e00, 0x29f00, 0x2a000, 0x2a100, 0x2a380, + 0x2a500, 0x2a600, +}; + +static const short jisx0213_from_ucs_level1[2715] = { + -1, -1, 0, 1, 2, 3, 4, 5, + -1, 6, 7, 8, 9, 10, 11, 12, + 13, 14, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 15, -1, -1, -1, -1, 16, -1, -1, + 17, 18, 19, -1, 20, 21, 22, 23, + 24, 25, 26, 27, 28, -1, 29, 30, + 31, 32, -1, 33, 34, 35, 36, 37, + 38, 39, -1, -1, 40, 41, -1, -1, + -1, -1, -1, -1, 42, -1, 43, 44, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 45, 46, 47, 48, -1, -1, -1, 49, + 50, 51, 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 62, 63, 64, 65, + 66, 67, 68, 69, -1, 70, 71, 72, + 73, 74, -1, 75, 76, 77, -1, -1, + -1, 78, -1, 79, 80, 81, 82, 83, + 84, -1, -1, 85, 86, 87, 88, 89, + 90, 91, 92, -1, -1, 93, 94, 95, + 96, 97, 98, -1, 99, 100, 101, 102, + 103, 104, -1, 105, 106, 107, -1, 108, + 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, -1, 120, 121, -1, 122, + 123, 124, 125, -1, -1, -1, 126, 127, + 128, -1, 129, -1, 130, -1, -1, 131, + 132, -1, -1, 133, 134, 135, -1, -1, + 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, + 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, + 208, 209, 210, 211, 212, 213, 214, 215, + 216, 217, 218, 219, 220, 221, 222, 223, + 224, 225, 226, 227, 228, 229, 230, 231, + 232, 233, 234, 235, 236, 237, 238, 239, + 240, 241, 242, 243, 244, 245, 246, 247, + 248, 249, 250, 251, 252, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 271, + 272, 273, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 284, 285, 286, 287, + 288, 289, 290, 291, 292, 293, 294, 295, + 296, 297, 298, 299, 300, 301, 302, 303, + 304, 305, 306, 307, 308, 309, 310, 311, + 312, 313, 314, 315, 316, 317, 318, 319, + 320, 321, 322, 323, 324, 325, 326, 327, + 328, 329, 330, -1, 331, 332, 333, 334, + 335, 336, 337, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, + 351, 352, 353, 354, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, + 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376, 377, 378, 379, 380, 381, -1, + 382, 383, 384, 385, 386, 387, 388, 389, + 390, 391, 392, 393, 394, 395, 396, 397, + 398, 399, 400, 401, 402, 403, 404, 405, + 406, 407, 408, 409, 410, 411, 412, 413, + 414, 415, 416, -1, -1, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 426, 427, + 428, 429, 430, 431, 432, 433, 434, 435, + 436, 437, 438, 439, 440, 441, 442, 443, + 444, 445, -1, 446, 447, 448, 449, 450, + 451, 452, 453, 454, 455, 456, 457, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 458, 459, -1, 460, + 461, 462, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 463, -1, -1, 464, 465, -1, 466, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 467, -1, 468, -1, -1, -1, 469, -1, + 470, -1, -1, -1, 471, 472, 473, 474, + -1, 475, -1, -1, 476, -1, -1, 477, + 478, -1, -1, -1, -1, 479, -1, -1, + 480, -1, 481, -1, -1, 482, 483, -1, + -1, -1, -1, 484, 485, -1, 486, -1, + -1, -1, -1, -1, -1, 487, -1, 488, + -1, 489, 490, -1, -1, 491, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 492, 493, -1, 494, 495, 496, -1, 497, + -1, 498, -1, -1, -1, -1, -1, 499, + -1, 500, 501, -1, 502, 503, -1, -1, + -1, -1, 504, -1, -1, -1, -1, 505, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, 506, -1, -1, 507, 508, 509, 510, + 511, -1, -1, -1, 512, 513, -1, 514, + -1, -1, -1, -1, -1, 515, -1, -1, + 516, -1, -1, -1, 517, -1, 518, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 519, -1, -1, -1, -1, + -1, 520, 521, -1, -1, -1, 522, -1, + -1, -1, 523, -1, -1, 524, 525, -1, + 526, -1, -1, -1, -1, -1, -1, 527, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 528, 529, + -1, -1, -1, -1, -1, 530, -1, 531, + -1, 532, -1, 533, -1, 534, 535, 536, + 537, 538, -1, -1, 539, 540, -1, 541, + 542, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 543, -1, -1, -1, -1, -1, + -1, 544, -1, 545, 546, 547, -1, 548, + -1, -1, -1, -1, -1, 549, -1, -1, + -1, -1, 550, -1, 551, -1, -1, 552, + -1, -1, -1, -1, -1, -1, 553, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + 554, -1, 555, -1, -1, -1, -1, 556, + -1, -1, 557, -1, -1, -1, -1, -1, + -1, 558, -1, -1, -1, 559, -1, -1, + 560, -1, -1, -1, 561, -1, -1, -1, + 562, 563, 564, -1, -1, -1, -1, -1, + -1, 565, -1, -1, 566, -1, 567, 568, + 569, 570, -1, -1, -1, -1, -1, -1, + 571, -1, 572, 573, 574, -1, 575, -1, + -1, -1, -1, -1, -1, 576, 577, -1, + -1, -1, -1, -1, -1, -1, -1, 578, + -1, -1, -1, 579, -1, -1, 580, -1, + -1, 581, -1, -1, -1, -1, 582, -1, + 583, 584, -1, 585, 586, 587, -1, 588, + 589, 590, -1, 591, -1, -1, -1, -1, + -1, 592, 593, -1, -1, 594, -1, -1, + 595, -1, -1, -1, -1, -1, -1, -1, + -1, 596, 597, -1, 598, -1, -1, -1, + -1, -1, -1, 599, -1, 600, -1, 601, + 602, 603, 604, 605, -1, -1, -1, -1, + 606, 607, -1, 608, -1, -1, -1, -1, + -1, 609, -1, -1, -1, -1, 610, 611, + -1, -1, -1, 612, 613, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 614, + 615, 616, -1, -1, -1, -1, -1, -1, + 617, -1, 618, -1, 619, 620, -1, -1, + -1, -1, -1, -1, -1, -1, 621, -1, + -1, -1, 622, -1, -1, -1, 623, 624, + -1, -1, 625, -1, -1, -1, 626, -1, + 627, -1, -1, -1, -1, -1, 628, -1, + -1, -1, 629, -1, -1, -1, -1, -1, + -1, 630, 631, 632, -1, -1, -1, 633, + 634, 635, -1, -1, -1, 636, -1, 637, + -1, -1, -1, 638, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 639, 640, -1, + 641, 642, 643, 644, -1, -1, -1, 645, + -1, -1, -1, -1, 646, 647, -1, 648, + 649, -1, 650, 651, 652, -1, -1, 653, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 654, -1, -1, -1, -1, -1, + -1, -1, 655, -1, -1, -1, -1, 656, + -1, 657, -1, 658, 659, 660, -1, -1, + -1, -1, -1, 661, -1, -1, -1, -1, + -1, 662, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 663, + 664, 665, 666, 667, -1, -1, -1, 668, + 669, -1, 670, 671, -1, -1, 672, -1, + -1, -1, -1, -1, -1, -1, 673, -1, + 674, -1, -1, -1, -1, -1, -1, 675, + 676, -1, 677, +}; + +static const unsigned short jisx0213_from_ucs_level2_data[] = { + /* 0x0080 */ + 0x2922, 0x2923, 0x2171, 0x2172, 0x2924, 0x2925, 0x2178, 0x212f, + 0x2926, 0x2927, 0x2928, 0x224c, 0x2929, 0x292a, 0x292b, 0x216b, + 0x215e, 0x292c, 0x292d, 0x212d, 0x2279, 0x292e, 0x292f, 0x2930, + 0x2931, 0x2932, 0x2933, 0x2934, 0x2935, 0x2936, + /* 0x00C0 */ + 0x2937, 0x2938, 0x2939, 0x293a, 0x293b, 0x293c, 0x293d, 0x293e, + 0x293f, 0x2940, 0x2941, 0x2942, 0x2943, 0x2944, 0x2945, 0x2946, + 0x2947, 0x2948, 0x2949, 0x294a, 0x294b, 0x294c, 0x294d, 0x215f, + 0x294e, 0x294f, 0x2950, 0x2951, 0x2952, 0x2953, 0x2954, 0x2955, + 0x2956, 0x2957, 0x2958, 0x2959, 0x295a, 0x295b, 0x29dc, 0x295d, + 0x295e, 0x295f, 0x2960, 0x2961, 0x2962, 0x2963, 0x2964, 0x2965, + 0x2966, 0x2967, 0x2968, 0x2969, 0x296a, 0x296b, 0x296c, 0x2160, + 0x296d, 0x296e, 0x296f, 0x2970, 0x2971, 0x2972, 0x2973, 0x2974, + /* 0x0100 */ + 0x2975, 0x297a, 0x2a3a, 0x2a49, 0x2a21, 0x2a2c, 0x2a3c, 0x2a4b, + 0x2a59, 0x2a5f, 0x2a3d, 0x2a4c, 0x2a40, 0x2a4f, 0x2a50, 0x2978, + 0x297d, 0x2a3e, 0x2a4d, 0x2a3f, 0x2a4e, 0x2a5a, 0x2a60, 0x2a5b, + 0x2a61, 0x2a7d, 0x2976, 0x297b, 0x2a5c, 0x2a62, 0x2a3b, 0x2a4a, + 0x2a24, 0x2a2f, + /* 0x0140 */ + 0x2a23, 0x2a2e, 0x2a41, 0x2a51, 0x2a42, 0x2a52, 0x2a7a, 0x2979, + 0x297e, 0x2a43, 0x2a53, 0x2b2b, 0x2b2a, 0x2a39, 0x2a48, 0x2a44, + 0x2a54, 0x2a25, 0x2a30, 0x2a5d, 0x2a63, 0x2a27, 0x2a33, 0x2a26, + 0x2a32, 0x2a47, 0x2a57, 0x2a28, 0x2a34, 0x2977, 0x297c, 0x2a5e, + 0x2a64, 0x2a45, 0x2a55, 0x2a46, 0x2a56, 0x2a29, 0x2a35, 0x2a2b, + 0x2a38, 0x2a2a, 0x2a37, + /* 0x0180 */ + 0x2b29, + /* 0x01C0 */ + 0x2b24, 0x286f, 0x2870, 0x2871, 0x2876, 0x2877, 0x2878, 0x2879, + 0x287a, 0x287b, 0x287c, 0x2874, 0x2875, 0x2b45, + /* 0x0240 */ + 0x2b33, 0x2b39, 0x2b3a, 0x2b25, 0x2bb8, 0x2b3f, 0x2a6e, 0x2b26, + 0x2b2e, 0x2bb0, 0x2bc3, 0x2b31, 0x2b32, 0x2a75, 0x2b28, 0x2a79, + 0x2b36, 0x2b3c, 0x2b22, 0x2b42, 0x2b2c, 0x2a6a, 0x2a74, 0x2a6b, + 0x2b34, 0x2a7b, 0x2a65, 0x2a76, 0x2a6f, 0x2b2f, 0x2a6c, 0x2b41, + 0x2a73, 0x2a70, 0x2a67, + /* 0x0280 */ + 0x2a7c, 0x2a71, 0x2a68, 0x2b27, 0x2a6d, 0x2b2d, 0x2b35, 0x2a66, + 0x2bb7, 0x2b3b, 0x2a78, 0x2a72, 0x2b40, 0x2a69, 0x2b21, 0x2a7e, + 0x2b23, 0x2a77, 0x2b3e, 0x2b3d, + /* 0x02C0 */ + 0x2a31, 0x2b53, 0x2b54, 0x2b55, 0x2b56, 0x2a22, 0x2a58, 0x2a2d, + 0x2a36, 0x2b71, 0x2be0, 0x2b61, 0x2b62, 0x2b63, 0x2be4, + /* 0x0300 */ + 0x2b5c, 0x2b5a, 0x2b5f, 0x2b7d, 0x2b5b, 0x2b57, 0x2b6d, 0x2b59, + 0x2b5e, 0x2b5d, 0x2b78, 0x2b79, 0x2b7e, 0x2b6a, 0x2b76, 0x2b77, + 0x2b6b, 0x2b6c, 0x2b72, 0x2b67, 0x2b6f, 0x2b7a, 0x2b68, 0x2b70, + 0x2b73, 0x2b75, 0x2b69, 0x2b7b, 0x2b7c, 0x2b74, 0x2b6e, + /* 0x0340 */ + 0x2b52, + /* 0x0380 */ + 0x2621, 0x2622, 0x2623, 0x2624, 0x2625, 0x2626, 0x2627, 0x2628, + 0x2629, 0x262a, 0x262b, 0x262c, 0x262d, 0x262e, 0x262f, 0x2630, + 0x2631, 0x2632, 0x2633, 0x2634, 0x2635, 0x2636, 0x2637, 0x2638, + 0x2641, 0x2642, 0x2643, 0x2644, 0x2645, 0x2646, 0x2647, 0x2648, + 0x2649, 0x264a, 0x264b, 0x264c, 0x264d, 0x264e, 0x264f, + /* 0x03C0 */ + 0x2650, 0x2651, 0x2659, 0x2652, 0x2653, 0x2654, 0x2655, 0x2656, + 0x2657, 0x2658, + /* 0x0400 */ + 0x2727, 0x2721, 0x2722, 0x2723, 0x2724, 0x2725, 0x2726, 0x2728, + 0x2729, 0x272a, 0x272b, 0x272c, 0x272d, 0x272e, 0x272f, 0x2730, + 0x2731, 0x2732, 0x2733, 0x2734, 0x2735, 0x2736, 0x2737, 0x2738, + 0x2739, 0x273a, 0x273b, 0x273c, 0x273d, 0x273e, 0x273f, 0x2740, + 0x2741, 0x2751, 0x2752, 0x2753, 0x2754, 0x2755, 0x2756, 0x2758, + 0x2759, 0x275a, 0x275b, 0x275c, 0x275d, 0x275e, 0x275f, 0x2760, + 0x2761, + /* 0x0440 */ + 0x2762, 0x2763, 0x2764, 0x2765, 0x2766, 0x2767, 0x2768, 0x2769, + 0x276a, 0x276b, 0x276c, 0x276d, 0x276e, 0x276f, 0x2770, 0x2771, + 0x2757, + /* 0x1E00 */ + 0x2872, 0x2873, + /* 0x1F40 */ + 0x2b46, 0x2b47, 0x2b50, 0x2b51, + /* 0x2000 */ + 0x213e, 0x237c, 0x213d, 0x2142, 0x2146, 0x2147, 0x2148, 0x2149, + 0x2277, 0x2278, 0x2340, 0x2145, 0x2144, 0x2273, 0x216c, 0x216d, + 0x2228, 0x286b, 0x2b58, + /* 0x2040 */ + 0x2c7e, 0x286c, 0x286d, 0x286e, 0x2c7d, + /* 0x2080 */ + 0x2921, + /* 0x2100 */ + 0x216e, 0x235d, 0x235f, 0x2d62, 0x2d64, 0x2360, 0x2272, 0x235c, + /* 0x2140 */ + 0x2778, 0x2779, 0x277a, 0x2d35, 0x2d36, 0x2d37, 0x2d38, 0x2d39, + 0x2d3a, 0x2d3b, 0x2d3c, 0x2d3d, 0x2d3e, 0x2d3f, 0x2d57, 0x2c35, + 0x2c36, 0x2c37, 0x2c38, 0x2c39, 0x2c3a, 0x2c3b, 0x2c3c, 0x2c3d, + 0x2c3e, 0x2c3f, 0x2c40, + /* 0x2180 */ + 0x222b, 0x222c, 0x222a, 0x222d, 0x2271, 0x2327, 0x2325, 0x2326, + 0x2328, + /* 0x21C0 */ + 0x2329, 0x224d, 0x224e, 0x232b, 0x232c, 0x232a, 0x232d, + /* 0x2200 */ + 0x224f, 0x225f, 0x2250, 0x2247, 0x2260, 0x223a, 0x2246, 0x223b, + 0x215d, 0x235b, 0x2265, 0x2267, 0x2167, 0x2d78, 0x225c, 0x2254, + 0x2255, 0x224a, 0x224b, 0x2241, 0x2240, 0x2269, 0x226a, 0x2d73, + 0x2168, 0x2268, 0x2266, + /* 0x2240 */ + 0x226c, 0x226d, 0x226e, 0x2262, 0x2162, 0x2261, 0x226b, 0x2165, + 0x2166, 0x2263, 0x2264, 0x226f, 0x2270, + /* 0x2280 */ + 0x223e, 0x223f, 0x2242, 0x2243, 0x223c, 0x223d, 0x2244, 0x2245, + 0x2251, 0x2252, 0x2253, 0x225d, 0x2d79, + /* 0x22C0 */ + 0x2776, 0x2777, + /* 0x2300 */ + 0x2248, 0x2249, 0x225e, 0x277c, + /* 0x2380 */ + 0x2742, 0x2743, + /* 0x23C0 */ + 0x2744, 0x2745, 0x2746, 0x2747, 0x2748, 0x2749, 0x274a, 0x274b, + 0x274c, 0x274d, 0x274e, 0x274f, 0x2750, 0x277e, + /* 0x2400 */ + 0x277d, + /* 0x2440 */ + 0x2d21, 0x2d22, 0x2d23, 0x2d24, 0x2d25, 0x2d26, 0x2d27, 0x2d28, + 0x2d29, 0x2d2a, 0x2d2b, 0x2d2c, 0x2d2d, 0x2d2e, 0x2d2f, 0x2d30, + 0x2d31, 0x2d32, 0x2d33, 0x2d34, + /* 0x24C0 */ + 0x2c41, 0x2c42, 0x2c43, 0x2c44, 0x2c45, 0x2c46, 0x2c47, 0x2c48, + 0x2c49, 0x2c4a, 0x2c4b, 0x2c4c, 0x2c4d, 0x2c4e, 0x2c4f, 0x2c50, + 0x2c51, 0x2c52, 0x2c53, 0x2c54, 0x2c55, 0x2c56, 0x2c57, 0x2c58, + 0x2c59, 0x2c5a, 0x2c2b, 0x2c2c, 0x2c2d, 0x2c2e, 0x2c2f, 0x2c30, + 0x2c31, 0x2c32, 0x2c33, 0x2c34, 0x265a, 0x265b, 0x265c, 0x265d, + 0x265e, 0x265f, 0x2660, 0x2661, 0x2662, 0x2663, + /* 0x2500 */ + 0x2821, 0x282c, 0x2822, 0x282d, 0x2823, 0x282e, 0x2824, 0x282f, + 0x2826, 0x2831, 0x2825, 0x2830, 0x2827, 0x283c, 0x2837, 0x2832, + 0x2829, 0x283e, 0x2839, 0x2834, 0x2828, 0x2838, 0x283d, 0x2833, + 0x282a, 0x283a, 0x283f, 0x2835, 0x282b, 0x283b, + /* 0x2540 */ + 0x2840, 0x2836, + /* 0x2580 */ + 0x2223, 0x2222, 0x266d, 0x2225, 0x2224, 0x2322, 0x2321, 0x2227, + 0x2226, + /* 0x25C0 */ + 0x2324, 0x2323, 0x2221, 0x217e, 0x233b, 0x217b, 0x217d, 0x217c, + 0x2867, 0x2868, 0x2869, 0x286a, 0x233f, 0x227e, + /* 0x2600 */ + 0x2668, 0x2669, 0x266a, 0x266b, 0x217a, 0x2179, 0x2667, 0x2664, + 0x2665, 0x2d7e, + /* 0x2640 */ + 0x216a, 0x2169, 0x263a, 0x263d, 0x263b, 0x2640, 0x2639, 0x263e, + 0x263c, 0x263f, 0x266c, 0x227d, 0x2276, 0x227b, 0x227c, 0x2275, + 0x227a, 0x2274, + /* 0x2700 */ + 0x277b, + /* 0x2740 */ + 0x2d7d, 0x2c21, 0x2c22, 0x2c23, 0x2c24, 0x2c25, 0x2c26, 0x2c27, + 0x2c28, 0x2c29, 0x2c2a, + /* 0x2900 */ + 0x232e, 0x232f, + /* 0x2980 */ + 0x233a, + /* 0x29C0 */ + 0x237d, 0x237e, + /* 0x3000 */ + 0x2121, 0x2122, 0x2123, 0x2137, 0x2139, 0x213a, 0x213b, 0x2152, + 0x2153, 0x2154, 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, + 0x215b, 0x2229, 0x222e, 0x214c, 0x214d, 0x225a, 0x225b, 0x2258, + 0x2259, 0x2141, 0x2d60, 0x2d61, 0x2666, 0x2233, 0x2234, 0x2235, + 0x2236, 0x2237, 0x233c, + /* 0x3040 */ + 0x2421, 0x2422, 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, 0x2428, + 0x2429, 0x242a, 0x24ab, 0x242c, 0x24ad, 0x242e, 0x24af, 0x2430, + 0x24b1, 0x2432, 0x24b3, 0x2434, 0x2435, 0x2436, 0x2437, 0x2438, + 0x2439, 0x243a, 0x243b, 0x243c, 0x243d, 0x243e, 0x243f, 0x2440, + 0x2441, 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, 0x2447, 0x2448, + 0x2449, 0x244a, 0x244b, 0x244c, 0x244d, 0x244e, 0x244f, 0x2450, + 0x2451, 0x2452, 0x2453, 0x2454, 0x2455, 0x2456, 0x2457, 0x2458, + 0x2459, 0x245a, 0x245b, 0x245c, 0x245d, 0x245e, 0x245f, + /* 0x3080 */ + 0x2460, 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, + 0x2468, 0x2469, 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, + 0x2470, 0x2471, 0x2472, 0x2473, 0x2474, 0x2475, 0x2476, 0x212b, + 0x212c, 0x2135, 0x2136, 0x2239, 0x237b, 0x2521, 0x2522, 0x2523, + 0x2524, 0x2525, 0x2526, 0x2527, 0x2528, 0x2529, 0x252a, 0x25ab, + 0x252c, 0x25ad, 0x252e, 0x25af, 0x2530, 0x25b1, 0x2532, 0x25b3, + 0x2534, 0x2535, 0x2536, 0x2537, 0x2538, 0x2539, 0x253a, 0x25bb, + 0x253c, 0x253d, 0x253e, 0x253f, + /* 0x30C0 */ + 0x2540, 0x2541, 0x2542, 0x2543, 0x25c4, 0x2545, 0x2546, 0x2547, + 0x25c8, 0x2549, 0x254a, 0x254b, 0x254c, 0x254d, 0x254e, 0x254f, + 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, 0x2556, 0x2557, + 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, 0x255f, + 0x2560, 0x2561, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567, + 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x256d, 0x256e, 0x256f, + 0x2570, 0x2571, 0x2572, 0x2573, 0x2574, 0x2575, 0x2576, 0x2772, + 0x2773, 0x2774, 0x2775, 0x2126, 0x213c, 0x2133, 0x2134, 0x2238, + /* 0x31C0 */ + 0x266e, 0x266f, 0x2670, 0x2671, 0x2672, 0x2673, 0x2674, 0x26f5, + 0x2676, 0x2677, 0x2679, 0x267a, 0x267b, 0x267c, 0x267d, 0x267e, + /* 0x3200 */ + 0x2d6a, 0x2d6b, 0x2d6c, + /* 0x3240 */ + 0x2841, 0x2842, 0x2843, 0x2844, 0x2845, 0x2846, 0x2847, 0x2848, + 0x2849, 0x284a, 0x284b, 0x284c, 0x284d, 0x284e, 0x284f, + /* 0x3280 */ + 0x2d65, 0x2d66, 0x2d67, 0x2d68, 0x2d69, 0x2850, 0x2851, 0x2852, + 0x2853, 0x2854, 0x2855, 0x2856, 0x2857, 0x2858, 0x2859, 0x285a, + 0x285b, 0x285c, 0x285d, 0x285e, + /* 0x32C0 */ + 0x2c5b, 0x2c5c, 0x2c5d, 0x2c5e, 0x2c5f, 0x2c60, 0x2c61, 0x2c62, + 0x2c63, 0x2c64, 0x2c65, 0x2c66, 0x2c67, 0x2c68, 0x2c69, 0x2c6a, + 0x2c6b, 0x2c6c, 0x2c6d, 0x2c6e, 0x2c71, 0x2c70, 0x2c73, 0x2c72, + 0x2c6f, + /* 0x3300 */ + 0x2d46, 0x2d4a, 0x2d41, 0x2d44, 0x2d42, 0x2d4c, 0x2d4b, 0x2d45, + 0x2d4d, 0x2d47, 0x2d4f, + /* 0x3340 */ + 0x2d40, 0x2d4e, 0x2d43, 0x2d48, 0x2d49, 0x2d5f, 0x2d6f, 0x2d6e, + 0x2d6d, + /* 0x3380 */ + 0x2d53, 0x2d54, 0x2d50, 0x2d51, 0x2d52, 0x2d56, + /* 0x33C0 */ + 0x2d55, 0x235e, 0x2d63, + /* 0x3400 */ + 0x2e23, 0xa12d, 0xa132, 0xa133, + /* 0x3440 */ + 0xa15e, 0xa156, + /* 0x3480 */ + 0xa17e, 0x2e53, 0xa32b, + /* 0x34C0 */ + 0xf468, 0xa32f, 0x2e5b, + /* 0x3500 */ + 0xa348, + /* 0x3540 */ + 0xa35d, 0xa35e, 0xa361, 0xa367, + /* 0x3580 */ + 0xa423, 0xa426, + /* 0x35C0 */ + 0xa42f, 0xa438, 0xa442, + /* 0x3600 */ + 0xa44a, + /* 0x3640 */ + 0xa479, + /* 0x3680 */ + 0xa53f, 0xa543, 0xa541, + /* 0x36C0 */ + 0xa557, + /* 0x3740 */ + 0xa823, 0xa825, 0xa829, 0xa828, 0xa82c, + /* 0x3780 */ + 0x4f5f, + /* 0x37C0 */ + 0xa83e, 0x4f6f, 0xa856, 0xa859, 0xa85c, + /* 0x3800 */ + 0xa85e, 0xa86f, 0xa871, + /* 0x3840 */ + 0xa874, 0xa879, 0xa87b, + /* 0x38C0 */ + 0xac3b, + /* 0x3900 */ + 0xac46, 0xac4a, + /* 0x3940 */ + 0xac60, + /* 0x3A40 */ + 0xad5b, 0xad5f, + /* 0x3AC0 */ + 0xad71, 0xae36, 0xad7c, + /* 0x3B00 */ + 0xae2e, 0xae32, 0xae34, 0x7549, + /* 0x3B40 */ + 0xae6d, 0xae65, + /* 0x3B80 */ + 0xaf28, 0xaf29, 0xaf2c, 0xaf34, 0x757e, + /* 0x3BC0 */ + 0x7621, 0xaf48, 0xaf5d, + /* 0x3C00 */ + 0x763a, 0xaf77, + /* 0x3CC0 */ + 0xee3b, 0xee42, + /* 0x3D00 */ + 0xee71, 0xee7e, + /* 0x3D40 */ + 0xef40, + /* 0x3D80 */ + 0xef54, + /* 0x3DC0 */ + 0xef70, 0xef77, + /* 0x3E00 */ + 0xf028, 0x7766, + /* 0x3E40 */ + 0xf03f, 0xf041, 0xf042, + /* 0x3E80 */ + 0xf049, 0xf050, + /* 0x3F40 */ + 0xf134, 0x784d, 0xf146, 0xf148, + /* 0x3F80 */ + 0xf15c, + /* 0x3FC0 */ + 0xf167, 0xf16c, + /* 0x4000 */ + 0xf222, + /* 0x4040 */ + 0xf22d, + /* 0x4080 */ + 0xf239, + /* 0x4100 */ + 0xf264, + /* 0x4140 */ + 0xf274, 0xf277, 0xf27d, + /* 0x4180 */ + 0xf333, 0xf337, + /* 0x41C0 */ + 0xf347, 0xf34b, 0xf348, + /* 0x4200 */ + 0xf353, 0xf357, + /* 0x4240 */ + 0x796d, + /* 0x42C0 */ + 0xf42b, 0xf436, 0xf43b, + /* 0x4300 */ + 0xf44e, 0xf45d, + /* 0x4340 */ + 0xf461, + /* 0x43C0 */ + 0xf53e, 0xf542, + /* 0x4400 */ + 0xf548, 0xf54a, 0xf54c, 0xf54f, + /* 0x4440 */ + 0x7a59, 0x7a5a, 0xf56c, 0xf56e, + /* 0x4480 */ + 0xf577, 0xf635, 0xf632, + /* 0x44C0 */ + 0xf634, + /* 0x4500 */ + 0xf659, 0xf654, 0xf66d, + /* 0x4540 */ + 0xf66e, + /* 0x4580 */ + 0x7b51, 0xf74f, + /* 0x45C0 */ + 0xf76c, 0x7b60, + /* 0x4600 */ + 0xf824, + /* 0x4640 */ + 0xf83a, 0xf843, + /* 0x4680 */ + 0xf84e, 0xf853, + /* 0x4700 */ + 0xf86b, + /* 0x4740 */ + 0xf929, + /* 0x47C0 */ + 0xf93f, + /* 0x4800 */ + 0xf949, + /* 0x4840 */ + 0x7c4b, 0xf95c, + /* 0x4880 */ + 0xfa27, + /* 0x4980 */ + 0x7d58, + /* 0x49C0 */ + 0xfb6a, 0xfb70, + /* 0x4A00 */ + 0xfb75, 0xfb78, + /* 0x4A80 */ + 0xfc37, + /* 0x4B00 */ + 0xfc55, + /* 0x4BC0 */ + 0xfd26, 0xfd28, 0xfd2a, 0xfd31, + /* 0x4C00 */ + 0x7e3e, 0xfd3f, + /* 0x4CC0 */ + 0xfe2a, 0xfe2d, + /* 0x4D00 */ + 0xfe4b, + /* 0x4D40 */ + 0xfe60, + /* 0x4E00 */ + 0x306c, 0x437a, 0xa122, 0x3c37, 0x4b7c, 0x3e66, 0x3b30, 0x3e65, + 0x323c, 0x4954, 0x4d3f, 0xa123, 0x5022, 0x312f, 0xa124, 0x336e, + 0x5023, 0x4024, 0x5242, 0x3556, 0x4a3a, 0x3e67, 0x4e3e, 0x4a42, + 0x2e24, 0xa125, 0x5024, 0xa126, 0xf02e, 0x4366, 0xa127, 0x2e25, + 0x2e26, 0x5025, 0x367a, 0x5026, 0x345d, 0x4330, 0x3c67, 0x5027, + 0x5028, + /* 0x4E40 */ + 0xa128, 0x5029, 0x4735, 0x3557, 0xa129, 0xa12a, 0x4737, 0x4663, + 0x3843, 0x4b33, 0xa12c, 0x6949, 0x502a, 0x3e68, 0x502b, 0x3235, + 0xa12f, 0x3665, 0x3870, 0x4c69, 0x5626, 0xa130, 0x4d70, 0x467d, + 0x3425, + /* 0x4E80 */ + 0x3535, 0x502c, 0x502d, 0x4e3b, 0x4d3d, 0x4168, 0x502f, 0x3b76, + 0x4673, 0x2e27, 0x5032, 0x313e, 0x385f, 0x385e, 0x3066, 0x4f4b, + 0x4f4a, 0x3a33, 0x3021, 0xa131, 0x5033, 0x5034, 0x5035, 0x4b34, + 0x5036, 0x3872, 0x3067, 0x4b72, 0x357c, 0x357d, 0x357e, 0x4462, + 0x4e3c, 0x5037, 0x5038, 0x5039, 0xa134, 0x3f4d, 0xa135, 0xa137, + /* 0x4EC0 */ + 0x3d3a, 0x3f4e, 0x503e, 0xa138, 0x503c, 0x503d, 0x3558, 0xa139, + 0x3a23, 0x3270, 0x503b, 0x503a, 0x4a29, 0xa13a, 0x3b46, 0x3b45, + 0x423e, 0x503f, 0x4955, 0x4067, 0xa13c, 0x2138, 0x5040, 0x5042, + 0x2e28, 0x4265, 0x4e61, 0x304a, 0xa13b, 0x5041, 0x323e, 0x3644, + 0xa13d, 0x4367, 0xa13e, 0x376f, 0x5043, 0x4724, 0x2e29, 0x2e2a, + /* 0x4F00 */ + 0xa13f, 0x346b, 0x2e2b, 0x5044, 0x304b, 0x2e2c, 0x3860, 0x346c, + 0x497a, 0x4832, 0x3559, 0xa140, 0x3271, 0x5067, 0x4541, 0x476c, + 0x5046, 0x483c, 0x4e62, 0xa142, 0x3f2d, 0x3b47, 0x3b77, 0x3240, + 0xa143, + /* 0x4F40 */ + 0x4451, 0x4322, 0x504a, 0x2e2e, 0x2e2f, 0x304c, 0x4463, 0x3d3b, + 0x3a34, 0x4d24, 0x424e, 0xa144, 0x323f, 0x2e30, 0x5049, 0xa145, + 0x4d3e, 0x5045, 0x5047, 0x3a6e, 0x5048, 0x5524, 0x2e31, 0x2e2d, + 0xa141, 0x5050, 0x2e32, 0x2e33, 0x5053, 0x5051, 0x3242, 0x4a3b, + 0x504b, 0xa147, 0xa148, 0xa149, 0x504f, 0x3873, 0xa14a, 0x2e34, + 0x3b48, + /* 0x4F80 */ + 0xa14b, 0x3426, 0xa14c, 0x5054, 0x504c, 0x2e35, 0x4e63, 0x3b78, + 0x504d, 0x5052, 0xa14d, 0x2e36, 0x5055, 0x2e37, 0x504e, 0xa14e, + 0x3621, 0x304d, 0x3622, 0x3241, 0x5525, 0x4b79, 0x496e, 0x3874, + 0xa150, 0x3f2f, 0x4e37, 0xa151, 0x4a58, + /* 0x4FC0 */ + 0x3738, 0x4225, 0x3264, 0xa152, 0x2e39, 0x3d53, 0xa153, 0x5059, + 0xa154, 0x505e, 0x505c, 0xa155, 0x5057, 0x422f, 0x505a, 0x505d, + 0x505b, 0x4a5d, 0x5058, 0x2e3a, 0x3f2e, 0x4b73, 0x505f, 0x5060, + 0xa14f, 0x3d24, 0x506d, 0x2e21, 0xa157, 0x4750, 0x4936, 0x5068, + 0x4a70, 0x3236, 0x506c, + /* 0x5000 */ + 0xa158, 0x2e3b, 0x2e3c, 0x5066, 0x506f, 0x4152, 0x3844, 0x475c, + 0x2e3d, 0x6047, 0xa159, 0x506e, 0x455d, 0xa15a, 0x5063, 0x3876, + 0x2e3e, 0x3875, 0x5061, 0xa15b, 0xa15c, 0x3c5a, 0x5069, 0xa15d, + 0x4a6f, 0x434d, 0x5065, 0x3771, 0x2e3f, 0x5062, 0x506a, 0x5064, + 0x4e51, 0x506b, 0x4f41, 0x2e40, 0x3666, 0x3770, 0x2e42, + /* 0x5040 */ + 0x2e41, 0x2e43, 0xa15f, 0x5070, 0xa160, 0x5071, 0x5075, 0x304e, + 0xa161, 0x4a50, 0x5074, 0xa162, 0x5073, 0x5077, 0xa163, 0x5076, + 0x4464, 0xa164, 0x3772, 0xa165, 0xa166, 0x5078, 0xa167, 0x3c45, + 0x4226, 0x4465, 0x3676, 0x5079, 0x3536, + /* 0x5080 */ + 0x507a, 0x507c, 0xa169, 0x4b35, 0x3766, 0xa16a, 0xa16b, 0x2e44, + 0xa16c, 0xa16d, 0x3b31, 0x4877, 0x507b, 0xa16e, 0xa168, 0xa16f, + 0x3a45, 0x4d43, 0xa171, 0x507e, 0x5123, 0x507d, 0x3a44, 0x3d7d, + 0xa172, 0xa173, 0x3739, + /* 0x50C0 */ + 0x5124, 0xa174, 0x364f, 0xa175, 0x5121, 0x5122, 0x2e45, 0x462f, + 0xa178, 0x417c, 0x2e47, 0x3623, 0xa17a, 0x4b4d, 0x5125, 0xa17b, + 0x4e3d, 0x5126, 0xa17c, 0x5129, 0x5127, 0x2e48, 0x414e, 0xa17d, + 0x5128, 0x512a, 0x2e46, 0xa176, 0x512c, 0x512b, 0x4a48, + /* 0x5100 */ + 0x3537, 0x512e, 0x512f, 0x2e4b, 0x322f, 0x2e4a, 0xa321, 0x512d, + 0x2e4c, 0x3c74, 0x5132, 0x5131, 0x5130, 0xa323, 0x5056, 0x5133, + 0xa324, 0x2e4d, 0x3d7e, 0x5134, 0x4d25, 0x4c59, 0x2e4e, 0x5136, + 0x5135, 0x5138, 0x5137, 0x5139, + /* 0x5140 */ + 0x513a, 0x3074, 0x3835, 0x373b, 0x3d3c, 0x437b, 0x3624, 0x4068, + 0x3877, 0x2e4f, 0x396e, 0x513c, 0x4c48, 0x4546, 0x3b79, 0x513b, + 0x513d, 0x2e51, 0x2e52, 0x455e, 0x3375, 0xa326, 0x513e, 0x467e, + 0x4134, 0x5140, 0x5141, 0x482c, 0x3878, 0x4f3b, 0x5142, 0x3626, + 0xa328, 0x4a3c, 0x4236, 0x3671, 0x4535, 0xf474, 0x3773, + /* 0x5180 */ + 0x5143, 0x5144, 0xa329, 0x4662, 0x315f, 0x5147, 0x3a7d, 0xa32a, + 0x5146, 0x3a46, 0x5148, 0x666e, 0x5149, 0x4b41, 0x514a, 0x514b, + 0x514c, 0x3e69, 0xa32c, 0x3c4c, 0x2e54, 0x3427, 0x514f, 0xa32d, + 0x514d, 0x4c3d, 0x514e, 0x495a, 0x5150, 0x5151, 0x5152, 0x455f, + 0xa32e, 0x5156, 0x5154, 0x5155, 0x5153, 0x3a63, 0x5157, 0x4c6a, + 0x4e64, 0xa330, 0x5158, + /* 0x51C0 */ + 0x2e55, 0x4028, 0x5159, 0x3d5a, 0x515a, 0x2e56, 0x437c, 0x4e3f, + 0x4560, 0x5245, 0x515b, 0x7425, 0x3645, 0x2e57, 0x515c, 0x4b5e, + 0x2e58, 0x3d68, 0x427c, 0x515e, 0x4664, 0x515f, 0x2e59, 0x5160, + 0x332e, 0xa333, 0xa334, 0x5161, 0x3627, 0x464c, 0x317a, 0x3d50, + 0x4821, 0x5162, + /* 0x5200 */ + 0x4561, 0x2e5a, 0xa335, 0x3f4f, 0x5163, 0x4a2c, 0x405a, 0x3422, + 0x3429, 0x5164, 0x5166, 0x373a, 0xa336, 0x2e5c, 0x5165, 0x2e5d, + 0xa337, 0x4e73, 0x3d69, 0x483d, 0x4a4c, 0x5167, 0x4d78, 0x5168, + 0x5169, 0x457e, 0x516a, 0x4029, 0x3a7e, 0x3774, 0x516b, 0x3b49, + 0x396f, + /* 0x5240 */ + 0x4466, 0x516d, 0x4227, 0x2e5e, 0x3a6f, 0x516e, 0x516f, 0x4130, + 0x516c, 0x5171, 0xa339, 0x4b36, 0x2e5f, 0x3964, 0xa33a, 0x2f7e, + 0x5170, 0x2e60, 0x3775, 0x3a5e, 0x476d, 0x5174, 0x5172, 0xa33b, + 0x497b, 0x3e6a, 0x517b, 0x3364, 0x5175, 0x5173, 0x414f, 0xa33c, + 0x5177, 0x5176, + /* 0x5280 */ + 0xa33e, 0x3344, 0xa33d, 0x3760, 0x517c, 0x4e2d, 0x5178, 0x517d, + 0x517a, 0x2e61, 0x5179, 0xa340, 0x4e4f, 0x3879, 0x3243, 0x4e74, + 0xa342, 0xa343, 0x3d75, 0x4558, 0x3965, 0x5222, 0x5223, 0xa344, + 0x4e65, 0x4f2b, 0x5225, 0x387a, 0xa345, 0xa346, 0x5224, 0x332f, + /* 0x52C0 */ + 0x5226, 0x4b56, 0x443c, 0x4d26, 0x2e62, 0x4a59, 0xa347, 0x2e64, + 0x5227, 0x2e65, 0xa349, 0x7055, 0x4630, 0x2e66, 0x5228, 0x342a, + 0x4c33, 0x2e67, 0x3e21, 0x5229, 0x4a67, 0x522d, 0x402a, 0x522a, + 0x3650, 0x522b, 0x342b, 0x2e69, 0x372e, 0x522e, 0x522f, 0xa34b, + 0x5230, 0x5231, 0x3c5b, 0x2e6a, 0x387b, 0x4c5e, + /* 0x5300 */ + 0x2e6b, 0x4c68, 0x4677, 0x4a71, 0x5232, 0x2e6c, 0x5233, 0xa34c, + 0xa34d, 0x5235, 0x5237, 0x5236, 0x5238, 0x323d, 0x4b4c, 0x3a7c, + 0x5239, 0x2e6d, 0x4159, 0x3e22, 0x3629, 0x523a, 0xa34e, 0x485b, + 0x523b, 0x523c, 0x523d, 0xa34f, 0x523e, 0x4924, 0x3668, 0x3065, + 0xa350, 0x463f, + /* 0x5340 */ + 0x523f, 0x3d3d, 0xa351, 0x4069, 0x5241, 0x5240, 0x3e23, 0x3861, + 0x5243, 0x483e, 0x5244, 0x485c, 0x4234, 0x426e, 0x3628, 0x466e, + 0x4331, 0x476e, 0x4b4e, 0x5246, 0x406a, 0x2e6f, 0x2e70, 0x3735, + 0xa354, 0x5247, 0xa355, 0x5248, 0x312c, 0x3075, 0x346d, 0x4228, + 0x3551, 0x4d71, 0x524b, 0x3237, 0xa356, 0x524a, 0x2e71, 0x362a, + /* 0x5380 */ + 0x524c, 0x4c71, 0x2e72, 0x524d, 0x4e52, 0x387c, 0x2e73, 0x3836, + 0x524e, 0xa357, 0x5250, 0x524f, 0x3f5f, 0x3139, 0x315e, 0x5251, + 0x5252, 0x2e74, 0x3837, 0xa358, 0x5253, 0xa35a, 0x356e, + /* 0x53C0 */ + 0xa35b, 0x3b32, 0x5254, 0x4b74, 0x3a35, 0x355a, 0x4d27, 0x4150, + 0x483f, 0x3c7d, 0x3d47, 0xa35f, 0x3c68, 0x3c75, 0x3d76, 0xa360, + 0x4840, 0x5257, 0x3143, 0x4151, 0x387d, 0x3845, 0x3667, 0x525b, + 0x4321, 0x427e, 0x362b, 0x3e24, 0x525c, 0x525a, 0x3244, 0x4266, + 0x3c38, 0x3b4b, 0x3126, 0xa362, 0xa363, 0x3370, 0x3966, 0x3b4a, + 0x525d, + /* 0x5400 */ + 0x525e, 0x3549, 0x3346, 0x3967, 0x3548, 0x445f, 0x3125, 0x4631, + 0x4c3e, 0x3921, 0x4d79, 0x4547, 0x387e, 0x2e75, 0x372f, 0x5267, + 0x4f7e, 0x3663, 0x4b4a, 0xa365, 0x485d, 0x2e76, 0xa366, 0x5266, + 0x345e, 0x5261, 0x5262, 0x5264, 0x5265, 0x355b, 0x3f61, 0x4a2d, + 0x5263, 0x525f, 0x3863, + /* 0x5440 */ + 0x5260, 0x4f24, 0xa368, 0x4a72, 0x4468, 0x3862, 0x3970, 0x2e77, + 0x5268, 0x465d, 0xa364, 0x526c, 0xa369, 0xa36a, 0x3c7e, 0x3c76, + 0x2e79, 0xa36b, 0x526f, 0x526d, 0x4c23, 0x2e7a, 0x526a, 0x5273, + 0x526e, 0x5271, 0x3846, 0x4c3f, 0x2e7b, + /* 0x5480 */ + 0x5272, 0x5274, 0x5276, 0x2e7c, 0xa36c, 0x3a70, 0x4f42, 0xa36d, + 0x526b, 0x5269, 0x5275, 0x5270, 0xa36e, 0x2e7d, 0x2e78, 0xa36f, + 0x2e7e, 0x5278, 0x5323, 0x527a, 0xa370, 0x527e, 0x2f21, 0x5321, + 0x527b, 0xa371, 0xa372, 0x533e, 0x3a69, 0x3331, 0xa373, 0x5279, + 0xa374, 0x5325, 0x3076, 0x5324, 0xa375, + /* 0x54C0 */ + 0x3025, 0x494a, 0x5322, 0xa376, 0x527c, 0x2f22, 0x5277, 0x527d, + 0x3a48, 0x5326, 0x3077, 0x532f, 0x5327, 0x5328, 0x3e25, 0x4b69, + 0xa378, 0x532d, 0x532c, 0xa379, 0xa37a, 0x452f, 0xa37b, 0x532e, + 0x532b, 0x2f23, + /* 0x5500 */ + 0xa37c, 0xa37d, 0x3134, 0x3a36, 0x3f30, 0xa37e, 0x2f24, 0x5329, + 0x4562, 0x532a, 0x3022, 0x2f25, 0x5334, 0x4d23, 0x3e27, 0x533a, + 0x2f26, 0x5339, 0x5330, 0xa421, 0x4243, + /* 0x5540 */ + 0x5331, 0xa422, 0x426f, 0x5336, 0x3e26, 0xa424, 0xa425, 0x5333, + 0x4c64, 0x2f27, 0x373c, 0x5337, 0x5338, 0x5335, 0x533b, 0x2f28, + 0xa427, 0xa428, 0x5332, 0xa429, 0x5341, 0x5346, 0xa42b, 0x5342, + /* 0x5580 */ + 0x533d, 0x2f29, 0xa42c, 0x5347, 0x4131, 0x2f2a, 0x5349, 0xa42d, + 0x3922, 0x533f, 0x437d, 0x2f2b, 0xa42e, 0x5343, 0x533c, 0x342d, + 0x346e, 0x3365, 0x5344, 0x5340, 0x3776, 0x534a, 0x5348, 0x4153, + 0x354a, 0x362c, 0x2f2d, 0x5345, 0x3674, 0x3144, 0xa433, + /* 0x55C0 */ + 0x534e, 0x534c, 0x5427, 0xa434, 0xa435, 0x2f2e, 0xa436, 0xa430, + 0x5351, 0x534b, 0x534f, 0xa437, 0x534d, 0xa439, 0x3b4c, 0x5350, + 0xa43b, 0x5353, 0x5358, 0x5356, 0x5355, + /* 0x5600 */ + 0x4332, 0xa43e, 0x2f30, 0x3245, 0x2f31, 0xa43f, 0x5352, 0x5354, + 0x3e28, 0x3133, 0x5357, 0xa43c, 0x325e, 0x5362, 0xa440, 0x3e7c, + 0x535e, 0x535c, 0x535d, 0xa441, 0x535f, 0x2f32, 0xa443, 0xa444, + /* 0x5640 */ + 0xa445, 0x313d, 0xa446, 0x2f33, 0x4139, 0x5359, 0x535a, 0x7427, + 0x337a, 0xa447, 0xa448, 0x5361, 0x2f35, 0x346f, 0x5364, 0x5360, + 0x5363, 0xa449, 0x2f37, 0x2f38, 0x2f39, 0x4a2e, 0x2f34, 0x4655, + 0x4838, + /* 0x5680 */ + 0x5366, 0x5365, 0x3345, 0xa44b, 0x5367, 0xa44c, 0x536a, 0x5369, + 0xa44d, 0x2f3a, 0xa44e, 0xa44f, 0x2f3b, 0x5368, 0x4739, 0x536b, + 0xa450, 0x2f3c, 0x2f3d, 0xa451, 0x536c, 0xa452, 0x2f3e, 0x536e, + 0x536d, 0x5370, + /* 0x56C0 */ + 0x5373, 0x5371, 0x536f, 0x5372, 0xa453, 0x5374, 0x2f3f, 0x2f40, + 0xa454, 0x5375, 0x5376, 0x5377, 0x5378, 0x5145, 0x3c7c, 0x3b4d, + 0x3273, 0xa455, 0x3078, 0x4344, 0xa456, 0x5379, 0x3a24, 0x304f, + 0x3f5e, 0xa457, 0xa458, 0x537a, 0x3847, 0x3971, 0x537c, + /* 0x5700 */ + 0x537b, 0x4a60, 0x537d, 0x5421, 0x537e, 0x2f41, 0x5422, 0x5423, + 0x3777, 0x3160, 0x5424, 0xa45a, 0x5426, 0x5425, 0x5428, 0x455a, + 0x2f43, 0xa45b, 0x5429, 0x3035, 0x3a5f, 0xa45d, 0x373d, 0x2f44, + 0x434f, 0x2f45, 0x2f46, 0x542a, 0x542b, 0x542d, + /* 0x5740 */ + 0x542e, 0x3a64, 0xa45f, 0xa460, 0x3651, 0x4b37, 0xa461, 0xa462, + 0x542c, 0x542f, 0x3a41, 0x3923, 0x5433, 0x3a25, 0x4333, 0xa464, + 0x5430, 0x445a, 0xa465, 0x2f47, 0xa466, 0xa467, 0xa468, 0x2f48, + 0xa469, 0x2f49, 0x5434, + /* 0x5780 */ + 0x3f62, 0x5432, 0x5435, 0x373f, 0x5436, 0xa46d, 0x2f4a, 0xa46e, + 0xa46f, 0x5437, 0x3924, 0x3340, 0x5439, 0xa470, 0x543a, 0xa46c, + 0x543b, 0x5438, 0x2f4d, + /* 0x57C0 */ + 0x5431, 0x543c, 0x543d, 0x2f4e, 0x2f4f, 0x4b64, 0xa473, 0x3e6b, + 0x2f50, 0x543f, 0x5440, 0x543e, 0x5442, 0xa471, 0x4738, 0xa476, + 0x3068, 0x4956, 0x5443, 0x2f51, 0xa477, 0x2f52, 0xa478, 0x3e7d, + 0x2f53, 0x2f54, 0x3c39, 0xa47a, 0x475d, 0x3470, 0xa47b, 0x3a6b, + 0xa47c, 0x2f55, + /* 0x5800 */ + 0x4b59, 0x4632, 0xa47d, 0x3778, 0x424f, 0x2f56, 0x5441, 0x5444, + 0x4244, 0x5445, 0x5446, 0xa47e, 0xa521, 0x5448, 0x4469, 0xa522, + 0x342e, 0x7421, 0x3161, 0x4a73, 0xa523, 0x3e6c, 0x4548, 0xa524, + 0x3a66, 0x544e, + /* 0x5840 */ + 0x4a3d, 0x4e5d, 0xa526, 0x3274, 0x544a, 0xa527, 0x413a, 0x544d, + 0x4563, 0x4549, 0x4564, 0x4839, 0x444d, 0x3a49, 0x2f58, 0x5449, + 0x2f59, 0xa528, 0x3176, 0x4536, 0x544b, 0x5447, 0x3f50, 0x544f, + 0x2f5b, 0x3d4e, + /* 0x5880 */ + 0x362d, 0x5450, 0x2f5c, 0xa529, 0xa52a, 0xa52b, 0xa52c, 0xa52d, + 0x4a68, 0xa52e, 0x417d, 0x4446, 0xa52f, 0x2f5d, 0x5452, 0x4b4f, + 0x2f5f, 0xa530, 0x5453, 0x5458, 0xa531, 0x4a2f, 0x5457, 0x5451, + 0x5454, 0x5456, 0x3a26, + /* 0x58C0 */ + 0x4a49, 0xa533, 0x5459, 0x4345, 0x3275, 0x3e6d, 0xa534, 0x2f62, + 0x545b, 0x2f61, 0x545a, 0x2f63, 0x3968, 0x545c, 0x545e, 0x545d, + 0x2f64, 0x5460, 0x5455, 0x5462, 0x2f65, 0xa535, 0x5461, 0x545f, + 0x2f66, 0x3b4e, 0x3f51, 0x4154, 0x5463, 0x403c, 0x306d, 0x4764, + 0xa536, 0xa537, 0x445b, 0x5465, 0x5464, 0x5466, 0x5467, 0x5468, + /* 0x5900 */ + 0x5469, 0xa538, 0xa539, 0x4a51, 0x546a, 0xa53a, 0x2f67, 0xa53b, + 0x3246, 0x546b, 0xa53c, 0x4d3c, 0x3330, 0x5249, 0x3d48, 0x423f, + 0x546c, 0x4c6b, 0x4c34, 0xa53d, 0x546e, 0x4267, 0x4537, 0x4240, + 0x4957, 0x546f, 0x5470, 0x317b, 0x3c3a, 0x5471, 0x3050, 0x5472, + 0xa540, 0x5473, + /* 0x5940 */ + 0x3162, 0xa542, 0x3471, 0x4660, 0x4a74, 0x5477, 0x4155, 0x5476, + 0x3740, 0x4b5b, 0x5475, 0x4565, 0x5479, 0x5478, 0xa545, 0x2f69, + 0xa546, 0x547b, 0x547a, 0x317c, 0x547c, 0x3e29, 0x547e, 0x4325, + 0x547d, 0x2f6a, 0x4a33, 0x3d77, 0x455b, 0xa548, 0xa549, 0x5521, + 0xa54a, 0x3925, + /* 0x5980 */ + 0x5522, 0x4721, 0x485e, 0x4c51, 0x4725, 0x2f6b, 0x552b, 0x2f6c, + 0x3538, 0x4d45, 0x4c2f, 0x562c, 0x5523, 0xa54b, 0x5526, 0x2f6d, + 0x4245, 0x4b38, 0x454a, 0xa54c, 0x5527, 0x4b65, 0x3a4a, 0xa54d, + 0x3e2a, + /* 0x59C0 */ + 0x2f6e, 0x5528, 0xa54e, 0x3b50, 0x3b4f, 0xa54f, 0x3039, 0x3848, + 0x2f6f, 0x402b, 0x3051, 0x552c, 0x552d, 0x552a, 0x2f70, 0xa550, + 0xa551, 0xa552, 0x3138, 0x342f, 0xa553, 0x5529, 0x4c45, 0x4931, + 0xa554, 0x3028, 0x7e7a, 0x3079, 0x3b51, + /* 0x5A00 */ + 0x3052, 0x3023, 0x5532, 0xa558, 0xa559, 0x5530, 0x2f71, 0xa55a, + 0x4c3c, 0x5533, 0x5531, 0x552f, 0x3f31, 0x2f72, 0x552e, 0xa55b, + 0x4a5a, 0xa55c, 0x3864, 0x5537, 0x5538, 0x3e2b, + /* 0x5A40 */ + 0x5534, 0x4f2c, 0x474c, 0x5536, 0xa55d, 0x3a27, 0x5539, 0xa55e, + 0x4958, 0x2f73, 0x553a, 0x5535, 0x2f74, 0x2f75, 0xa55f, 0x2f76, + 0x4c3b, + /* 0x5A80 */ + 0x2f77, 0xa560, 0x475e, 0x553b, 0x4932, 0xa561, 0x2f78, 0xa562, + 0xa563, 0xa564, 0x2f79, 0xa565, 0xa566, 0xa567, 0xa568, 0x553c, + 0x5540, 0x553d, 0xa569, + /* 0x5AC0 */ + 0x3247, 0x553f, 0x2f7a, 0x3c3b, 0x553e, 0x3779, 0x554c, 0x5545, + 0x5542, 0xa56a, 0xa56b, 0xa56c, 0x4364, 0x5541, 0xa56d, 0x5543, + 0x5544, 0xa56f, 0xa56e, 0xa570, 0x5546, 0x5547, + /* 0x5B00 */ + 0xa571, 0xa572, 0x3472, 0x5549, 0x5548, 0x554a, 0xa573, 0x2f7c, + 0x3e6e, 0x2f7d, 0x554d, 0x445c, 0xa575, 0x3145, 0x554b, 0xa574, + 0x554e, 0x554f, + /* 0x5B40 */ + 0x5552, 0x4f55, 0x5550, 0x5551, 0xa576, 0x3b52, 0x5553, 0xa577, + 0x3926, 0x5554, 0x4f56, 0x3b7a, 0x4238, 0x5555, 0x5556, 0x3b5a, + 0x3927, 0x4c52, 0x3528, 0x3849, 0x5557, 0x3358, 0xa578, 0x5558, + 0x4239, 0xa579, 0x5559, 0x5623, 0x555a, 0x555b, 0x555c, 0x555e, + 0xa57a, 0x4f57, 0xa57b, + /* 0x5B80 */ + 0x555f, 0xa57c, 0x5560, 0xa57d, 0x4270, 0x3127, 0x3c69, 0x3042, + 0x4157, 0x3430, 0x3c35, 0x3928, 0x4f58, 0x4566, 0xa821, 0x3d21, + 0x3431, 0x4368, 0x446a, 0x3038, 0x3539, 0x4a75, 0x3c42, 0x3552, + 0x406b, 0x3c3c, 0x4d28, 0x5561, 0xa822, 0x355c, 0x3a4b, 0x3332, + 0x3163, 0x3e2c, 0x3248, 0x5562, 0x4d46, 0x3d49, + /* 0x5BC0 */ + 0xa824, 0x3c64, 0x5563, 0x3473, 0x4652, 0x4c29, 0x5564, 0x5565, + 0x4959, 0xa826, 0x5567, 0x3428, 0x3677, 0x5566, 0xa827, 0x4f59, + 0x3432, 0x3f32, 0x556b, 0x3b21, 0x3249, 0x556a, 0x5568, 0x556c, + 0x5569, 0x472b, 0x5c4d, 0x3f33, 0x556d, 0x4f5a, 0x4e40, 0x556e, + 0xa82a, 0x5570, 0x437e, 0x556f, 0x4023, 0x3b7b, 0xa82b, 0x4250, + 0x3c77, + /* 0x5C00 */ + 0x4975, 0x406c, 0xa82d, 0x3c4d, 0x5571, 0x3e2d, 0x5572, 0x5573, + 0x3053, 0x423a, 0x3f52, 0x5574, 0x4633, 0x3e2e, 0x3e2f, 0x4f5b, + 0x5575, 0x406d, 0x3e30, 0x4f5c, 0x5576, 0x5577, 0x4f5d, 0x4c60, + 0x5578, 0xa82e, 0x4f5e, 0x3646, 0xa82f, 0x3d22, 0x5579, 0x557a, + 0x3c5c, 0x3f2c, 0x4674, 0x3f54, 0x4878, 0x4722, + /* 0x5C40 */ + 0x3649, 0x557b, 0x356f, 0x557c, 0x367e, 0x464f, 0x3230, 0x3b53, + 0x557d, 0x5622, 0x5621, 0x367d, 0x557e, 0x4538, 0x7e7b, 0x4230, + 0xa831, 0x454b, 0x3c48, 0x4f60, 0xa832, 0x4158, 0x4d7a, 0xa833, + 0xa834, 0xa835, 0x5624, 0x5625, 0x4656, 0xa836, 0x3b33, 0x5627, + 0x5628, 0x4f64, 0xa839, + /* 0x5C80 */ + 0xa83c, 0xa83d, 0x5629, 0x4f65, 0x3474, 0x562a, 0x562b, 0x4f66, + 0xa841, 0x322c, 0xa842, 0x4f67, 0xa843, 0xa844, 0x413b, 0x3464, + 0x4f68, 0x562d, 0x4c28, 0xa846, 0x4252, 0x3359, 0xa847, 0x562f, + 0x5631, 0x345f, 0x4f69, 0x562e, 0x5630, 0x5633, + /* 0x5CC0 */ + 0x5632, 0x5634, 0xa849, 0x4f6a, 0x4f6b, 0x4f6c, 0x5635, 0x463d, + 0x362e, 0x3265, 0x5636, 0x563b, 0x5639, 0x4a77, 0x4a76, 0x4f6d, + 0x4567, 0x5638, 0x3d54, 0x5637, + /* 0x5D00 */ + 0xa84c, 0x3f72, 0x563c, 0x4f70, 0x3a6a, 0xa84d, 0x5642, 0x5643, + 0x563d, 0x3333, 0x563e, 0x5647, 0x5646, 0x5645, 0x5641, 0xa84f, + 0x5640, 0xa850, 0x5644, 0xa851, 0xa852, 0x4f71, 0x4a78, 0xa84e, + 0xa853, 0xa854, + /* 0x5D40 */ + 0xa855, 0x4f73, 0x4f74, 0x4f76, 0x564b, 0x5648, 0x564a, 0x4d72, + 0x5649, 0x4f75, 0x563f, 0xa857, 0x3f73, 0xa858, 0x564c, 0x4f77, + 0x3a37, 0xa85a, 0x564d, 0x564e, + /* 0x5D80 */ + 0x4f78, 0x5651, 0x5650, 0x564f, 0xa85d, 0x4568, 0x563a, 0x5657, + 0xa85f, 0xa860, 0xa861, 0xa862, 0x5653, 0x4f79, 0x5652, 0x4f7a, + 0x4f7b, 0x5654, 0x5655, 0xa863, 0xa864, 0xa865, 0x5658, 0x4f7c, + 0xa867, 0x4e66, 0x5659, 0x5656, + /* 0x5DC0 */ + 0x565a, 0x4f7d, 0x3460, 0x565b, 0xa868, 0x565d, 0x565c, 0x565e, + 0xa869, 0xa86a, 0x565f, 0x406e, 0x3d23, 0xa86b, 0x3d64, 0x7428, + 0x4163, 0xa86d, 0x3929, 0x3a38, 0x392a, 0x3570, 0xa86e, 0x5660, + 0x3a39, 0x384a, 0x5661, 0x4c26, 0x4743, 0x5662, 0x392b, 0x342c, + 0x4327, 0x3652, + /* 0x5E00 */ + 0xa870, 0x3b54, 0x495b, 0x4841, 0x5663, 0x3475, 0x5666, 0xa872, + 0x7429, 0xa873, 0x4421, 0x742a, 0x5665, 0x5664, 0x5667, 0x446b, + 0xa875, 0x3f63, 0x3b55, 0x404a, 0xa876, 0x4253, 0x3522, 0x4422, + 0x5668, 0x5669, 0x3e6f, 0x4b39, 0xa877, + /* 0x5E40 */ + 0x566c, 0x566b, 0x566a, 0x497d, 0x5673, 0xa878, 0x4b5a, 0x566d, + 0x566f, 0x4b6b, 0xa87a, 0x566e, 0x742b, 0x742c, 0x5670, 0x4828, + 0x5671, 0x4a3e, 0x5672, 0xa87c, 0xa87d, 0xa87e, 0xac21, 0x3433, + 0x4a3f, 0x472f, 0x5674, 0x5675, 0x7e7c, 0x392c, 0x3434, 0x5676, + 0x3838, 0x4d44, 0x4d29, 0x3476, 0x5678, + /* 0x5E80 */ + 0x4423, 0x392d, 0x3e31, 0x485f, 0x3e32, 0x3d78, 0x446c, 0x4a79, + 0x4539, 0x392e, 0x495c, 0x5679, 0xac23, 0x4559, 0x3a42, 0xac24, + 0x384b, 0xac25, 0x446d, 0x3043, 0x3d6e, 0x392f, 0x4d47, 0xac26, + 0x742d, 0xac27, + /* 0x5EC0 */ + 0x567a, 0x567b, 0x4751, 0xac28, 0x567c, 0x4e77, 0x4f2d, 0x742f, + 0x567e, 0x567d, 0xac29, 0x3347, 0x5721, 0xac2a, 0x5724, 0x5725, + 0x5723, 0x4940, 0x3e33, 0x5727, 0x5726, 0x5722, 0x5728, 0x5729, + 0x572a, 0x572d, 0x572b, 0x572c, 0x572e, 0x3164, 0x446e, 0x572f, + 0x7430, 0x377a, 0x3276, 0x4736, 0xac2c, 0x5730, 0x467b, + /* 0x5F00 */ + 0x7431, 0x4a5b, 0x7432, 0x5731, 0x4f2e, 0x7433, 0xac2d, 0x5732, + 0x4a40, 0x5735, 0x5021, 0x5031, 0xac2e, 0x3c30, 0x4675, 0x5736, + 0x355d, 0x4424, 0x307a, 0x5737, 0x4a26, 0x3930, 0x4350, 0xac2f, + 0x7434, 0xac31, 0x446f, 0x7435, 0x4c6f, 0x3839, 0x384c, 0x5738, + 0x5739, 0x573f, 0x3c65, 0x7436, 0x4425, 0x7437, 0x362f, 0x573a, + 0x492b, 0x7438, 0x4346, + /* 0x5F40 */ + 0x7439, 0x573b, 0x743a, 0xac32, 0x573c, 0x3630, 0x573d, 0x573e, + 0x5740, 0x4576, 0x743b, 0x5741, 0x5742, 0x743c, 0x5743, 0x5734, + 0x5733, 0x5744, 0x3741, 0xac33, 0x743d, 0x4927, 0x743e, 0x3a4c, + 0x4937, 0x4426, 0x494b, 0x5745, 0x3e34, 0x3146, 0xac34, 0x5746, + 0x5747, 0x4c72, 0x4860, 0x743f, 0xac35, 0x574a, + /* 0x5F80 */ + 0x317d, 0x402c, 0x5749, 0x5748, 0x3742, 0x4254, 0x574e, 0x574c, + 0x7440, 0x574b, 0x4e27, 0x3865, 0xac36, 0x3d79, 0x574d, 0x454c, + 0x3d3e, 0x4640, 0x5751, 0x5750, 0x7441, 0x574f, 0x5752, 0x3866, + 0xac37, 0xac38, 0x7442, 0x5753, 0x497c, 0x3d5b, 0x5754, 0x4879, + 0x7443, 0x4641, 0x4427, 0x7444, 0x7445, 0xac39, 0x4530, 0x5755, + 0x352b, + /* 0x5FC0 */ + 0x3f34, 0xac3a, 0x492c, 0xac3c, 0x7446, 0xac3d, 0x3477, 0x4726, + 0xac3e, 0xac3f, 0xac40, 0x5756, 0x3b56, 0x4b3a, 0x4b3b, 0x317e, + 0x575b, 0x7447, 0x4369, 0x7448, 0xac41, 0x5758, 0x7449, 0x3277, + 0xac42, 0xac43, 0x582d, 0x575a, 0xac44, 0x4730, 0x5759, 0x5757, + 0xac45, 0x397a, 0x575d, + /* 0x6000 */ + 0x744a, 0x5763, 0x5769, 0x5761, 0x455c, 0x744b, 0x5766, 0x495d, + 0xac47, 0x744c, 0x5760, 0x5765, 0x4e67, 0x3b57, 0x4255, 0x575e, + 0xac48, 0xac49, 0x355e, 0x5768, 0x402d, 0x3165, 0x5762, 0x3278, + 0x5767, 0x3631, 0x5764, 0x744d, 0x744e, 0x576a, + /* 0x6040 */ + 0x576c, 0x5776, 0x5774, 0x5771, 0x744f, 0x5770, 0x4e78, 0xac4b, + 0x5772, 0x3632, 0x3931, 0x3d7a, 0x5779, 0x576b, 0x576f, 0x575f, + 0x327a, 0x5773, 0x5775, 0x4351, 0x3a28, 0x3238, 0x576d, 0x5778, + 0x5777, 0x3633, 0x4229, 0x3366, 0x3743, 0x576e, 0xac4c, + /* 0x6080 */ + 0x577a, 0x577d, 0x5821, 0x3c3d, 0xac4d, 0x5827, 0x4470, 0x577b, + 0x5825, 0x3279, 0xac4e, 0x5823, 0x5824, 0x577e, 0x5822, 0x7451, + 0x7452, 0x3867, 0x4d2a, 0x3435, 0x3159, 0x5826, 0xac4f, 0x473a, + 0x302d, 0xac51, 0xac52, 0x4861, 0x575c, 0x582c, 0x5830, 0x4c65, + 0x5829, 0x4569, 0x582e, 0xac53, + /* 0x60C0 */ + 0x3e70, 0x582f, 0x4657, 0xac54, 0x7453, 0x4f47, 0x582b, 0x7454, + 0x7455, 0x5831, 0xac55, 0x397b, 0xac56, 0x404b, 0x7456, 0x3054, + 0x582a, 0x5828, 0x415a, 0x577c, 0x3b34, 0xac57, 0x4246, 0x583d, + 0xac58, 0x415b, 0x5838, 0xac59, 0x5835, 0x5836, 0x7457, 0x3c66, + 0x5839, 0x583c, + /* 0x6100 */ + 0x5837, 0x3d25, 0x583a, 0x5834, 0x4c7c, 0x4c7b, 0x583e, 0x583f, + 0x3055, 0xac5a, 0xac5b, 0xac5c, 0x5833, 0xac5d, 0x3672, 0x3026, + 0x7458, 0xac5e, 0x3436, 0x583b, 0x5843, 0x5842, 0x7459, 0x5847, + 0x745a, 0x5848, 0x745b, 0xac5f, 0x5846, 0x5849, 0x5841, 0x5845, + /* 0x6140 */ + 0xac61, 0x584a, 0x584b, 0xac62, 0x5840, 0x3b7c, 0x5844, 0x4256, + 0x3932, 0x5832, 0x3f35, 0x5858, 0x4a69, 0x584e, 0x584f, 0x5850, + 0x5857, 0x5856, 0xac63, 0x4b7d, 0x3437, 0x5854, 0x3745, 0x3334, + 0x5851, 0x4e38, 0x5853, 0x3056, 0x5855, 0x584c, 0x5852, 0x5859, + 0x3744, 0x584d, 0xac64, 0x4d5d, + /* 0x6180 */ + 0x4d2b, 0x585c, 0x5860, 0x745d, 0x417e, 0x4e79, 0x5861, 0xac66, + 0xac67, 0x585e, 0x585b, 0xac68, 0xac69, 0x585a, 0x585f, 0x4a30, + 0xac6a, 0x4634, 0xac6b, 0x3746, 0x5862, 0x585d, 0xac6c, 0x5863, + 0x377b, 0x3231, 0x7460, 0x586b, 0x745f, 0x3438, + /* 0x61C0 */ + 0x5869, 0x586a, 0x3a29, 0x5868, 0x5866, 0x5865, 0x586c, 0x5864, + 0x586e, 0x327b, 0xac6e, 0xac6f, 0xac70, 0x5870, 0x586f, 0x4428, + 0x5873, 0xac71, 0x5871, 0x5867, 0x377c, 0x5872, 0x5876, 0x5875, + 0x5877, 0x5874, + /* 0x6200 */ + 0x5878, 0x5879, 0x587a, 0x4a6a, 0x587c, 0x587b, 0x3d3f, 0x402e, + 0x3266, 0x327c, 0x587d, 0xac73, 0x303f, 0x404c, 0x587e, 0x6c43, + 0x5921, 0x3761, 0x5922, 0x7462, 0xac74, 0x406f, 0xac75, 0x5923, + 0x5924, 0x353a, 0x5925, 0x5926, 0x5927, 0x4257, 0x384d, 0x4c61, + 0x7463, 0x4b3c, + /* 0x6240 */ + 0x3d6a, 0x5928, 0x7464, 0xac76, 0x4070, 0x6e3d, 0x4862, 0x3c6a, + 0xac77, 0x3a4d, 0x5929, 0xac78, 0xac79, 0x4247, 0x4a27, 0x7465, + 0x4271, 0x7466, 0x592c, 0x592a, 0x592d, 0xac7a, 0x592b, 0xac7b, + 0x592e, 0xac7d, 0x4a31, 0x7467, 0x3037, 0xac7e, 0x495e, 0x4863, + 0xac7c, 0x592f, 0x5932, 0x3e35, + /* 0x6280 */ + 0x353b, 0x5930, 0x5937, 0x3e36, 0x7468, 0x5931, 0x4744, 0x4d5e, + 0x5933, 0x5934, 0x5938, 0x456a, 0x5935, 0x3933, 0x405e, 0xad21, + 0x5946, 0x4834, 0x4272, 0xad22, 0x4864, 0x5a2d, 0x4a7a, 0x4471, + 0x4b75, 0x593b, 0x3221, 0x436a, + /* 0x62C0 */ + 0x5944, 0x7469, 0x4334, 0x593e, 0x5945, 0x5940, 0x5947, 0x5943, + 0x5942, 0x476f, 0x593c, 0x327d, 0x593a, 0x3571, 0x4273, 0x5936, + 0xad23, 0x746a, 0x5939, 0x3934, 0x405b, 0x3e37, 0x5941, 0x4752, + 0x3572, 0x3348, 0x3367, 0x3f21, 0x5949, 0x594e, 0x594a, 0x377d, + 0x594f, 0x3b22, 0x3969, 0x746b, 0xad25, 0x3d26, 0x593d, + /* 0x6300 */ + 0x3b7d, 0x594c, 0xad26, 0x3b58, 0x594d, 0x3044, 0x746c, 0x5948, + 0xad27, 0xad28, 0x4429, 0x746d, 0x3573, 0x3634, 0x594b, 0x3027, + 0x3a43, 0x3f36, 0xad2b, 0xad2c, 0x746e, 0x4472, 0xad2d, 0xad2e, + 0x4854, 0x5951, 0x415e, + /* 0x6340 */ + 0xad2f, 0x746f, 0xad30, 0x422a, 0x3b2b, 0x5952, 0xad31, 0x5954, + 0x5950, 0x4a61, 0x443d, 0xad33, 0x415c, 0x7470, 0x4a7b, 0x3c4e, + 0x5960, 0x595f, 0xad36, 0x3f78, 0x377e, 0x5959, 0x3e39, 0x4668, + 0x4731, 0x7471, + /* 0x6380 */ + 0x5957, 0x415d, 0xad37, 0x3c78, 0x595c, 0x3e38, 0x5956, 0x595b, + 0x4753, 0xad3a, 0x5955, 0x3721, 0xad38, 0x335d, 0x595d, 0x4e2b, + 0x3a4e, 0x4335, 0x595a, 0x405c, 0x3935, 0x3f64, 0x3166, 0x413c, + 0x5958, 0x3545, 0x3747, 0x444f, 0x595e, 0x415f, 0xad3b, 0x5961, + /* 0x63C0 */ + 0x5963, 0x4237, 0x5969, 0x5964, 0x5966, 0x4941, 0x4473, 0x5967, + 0xad3d, 0xad3e, 0x4d2c, 0x4d48, 0x3439, 0xad3f, 0xad40, 0x302e, + 0x5965, 0x7472, 0x5962, 0xad41, 0xad42, 0x7473, 0x3478, 0xad43, + 0x3167, 0x7474, 0x5968, 0xad3c, 0x4d49, + /* 0x6400 */ + 0x596c, 0xad44, 0x423b, 0x5973, 0x7475, 0x596d, 0x7476, 0x596a, + 0x5971, 0x5953, 0xad45, 0x7477, 0xad46, 0x596e, 0x5972, 0xad47, + 0x4842, 0x456b, 0xad48, 0x596b, 0x596f, 0x3748, 0x3a71, + /* 0x6440 */ + 0x405d, 0x5977, 0x7479, 0x4526, 0xad49, 0xad4a, 0xad4b, 0x747a, + 0x5974, 0x4b60, 0x747b, 0x5975, 0xad4c, 0x5976, 0x4c4e, 0x7478, + 0x4022, 0xad4d, + /* 0x6480 */ + 0x3762, 0xad4e, 0x597d, 0xad4f, 0x3b35, 0x597a, 0x5979, 0x4732, + 0xad50, 0x4635, 0xad51, 0x4531, 0x597b, 0x597c, 0x496f, 0x4745, + 0x3b23, 0x4071, 0x4b50, 0x3349, 0x5a25, 0x597e, 0x747d, 0x747e, + /* 0x64C0 */ + 0x4d4a, 0x5a27, 0x7521, 0x5a23, 0x5a24, 0x7522, 0xad52, 0xad53, + 0x4160, 0x747c, 0x7523, 0x5a22, 0x593f, 0xad54, 0xad55, 0x5a26, + 0x5a21, 0x5a2b, 0x5a2c, 0x4527, 0x5a2e, 0xad57, 0xad58, 0x3b24, + 0x5a29, 0x353c, 0x5a2f, 0x5a28, 0x5a33, 0x5a32, 0x5a31, 0x7524, + 0x5a34, 0x7525, 0x5a36, 0x3e71, 0xad59, + /* 0x6500 */ + 0x5a35, 0xad5a, 0x5a39, 0xad5c, 0xad5d, 0xad5e, 0x5a37, 0x5a38, + 0x5970, 0xad60, 0x7526, 0x5a3b, 0x5a3a, 0x7527, 0x5978, 0x5a3c, + 0x5a30, 0x3b59, 0xad61, 0x5a3d, 0x5a3e, 0x5a40, 0x5a3f, 0x5a41, + 0x327e, 0x3936, 0x4a7c, 0x402f, + /* 0x6540 */ + 0xad62, 0x384e, 0x5a43, 0x5a46, 0x4952, 0x355f, 0xad63, 0x5a45, + 0x5a44, 0x4754, 0x5a47, 0x3635, 0x5a49, 0x5a48, 0x343a, 0x3b36, + 0x4658, 0x7529, 0xad64, 0x3749, 0x3f74, 0x5a4a, 0x4030, 0x4528, + 0x495f, 0x5a4b, 0xad65, + /* 0x6580 */ + 0xad66, 0x5a4c, 0x5a4d, 0xad67, 0xad68, 0x4a38, 0x555d, 0x4046, + 0xad69, 0x494c, 0x3a58, 0x4865, 0x4843, 0x454d, 0x4e41, 0x5a4f, + 0x3c50, 0x752a, 0x5a50, 0x3036, 0x3654, 0x404d, 0x4960, 0x5a51, + 0x3b42, 0x4347, 0x3b5b, 0x3f37, 0xad6a, 0xad6b, 0x5a52, 0xad6c, + 0x4a7d, 0x3177, 0x3b5c, 0xad6d, + /* 0x65C0 */ + 0x5a55, 0xad6e, 0x5a53, 0x5a56, 0x4e39, 0x5a54, 0xad6f, 0x407b, + 0x5a57, 0x4232, 0x5a58, 0xad70, 0x347a, 0x5a5a, 0x5a59, 0x5a5b, + 0x5a5c, 0x347b, 0x467c, 0x4336, 0x356c, 0x3b5d, 0x4161, 0x3d5c, + 0x3030, 0x5a5d, 0xad72, 0xad73, 0x3222, 0x5a61, 0xad74, + /* 0x6600 */ + 0x752c, 0x3937, 0x5a60, 0xad75, 0x3a2b, 0x3e3a, 0xad76, 0x752d, + 0x5a5f, 0x3e3b, 0x4c40, 0x3a2a, 0x3057, 0x404e, 0x752e, 0x5a66, + 0x752f, 0x4031, 0x3147, 0xad77, 0x7531, 0x7532, 0x3d55, 0x4b66, + 0x3a72, 0xad78, 0x7533, 0x3e3c, 0x4027, 0x7534, 0x7535, 0x7536, + 0x5a65, 0x5a63, 0x5a64, 0x7530, 0x436b, 0x5b26, + /* 0x6640 */ + 0x5a6a, 0x3b7e, 0x3938, 0x5a68, 0xad79, 0x7538, 0x5a69, 0x3f38, + 0x7539, 0xad7b, 0x5a67, 0xad7a, 0x3b2f, 0xad7e, 0x753b, 0x753c, + 0xae21, 0x5a6c, 0x5a6b, 0x5a70, 0x753d, 0x5a71, 0xae22, 0x5a6d, + 0x753e, 0x3322, 0x5a6e, 0x5a6f, 0x4855, 0xae25, 0xae26, 0xae27, + 0xae28, 0x4961, 0x374a, 0x5a72, 0x753f, 0x4032, 0x3e3d, 0x7540, + 0x7541, 0x4352, 0xae29, + /* 0x6680 */ + 0xae2a, 0x3647, 0x5a73, 0x5a77, 0x324b, 0x5a74, 0x5a76, 0x7542, + 0x5a75, 0xae2b, 0x3d6b, 0xae2c, 0x4348, 0x3045, 0x5a78, 0xae2d, + 0x5a79, 0x7544, 0x442a, 0x4e71, 0x3b43, 0xae2f, 0x4a6b, 0xae30, + 0x7545, 0x4b3d, 0xae31, 0x5b22, 0x5a7b, 0x7546, 0x5a7e, 0x5a7d, + 0xae33, + /* 0x66C0 */ + 0x5a7a, 0x5b21, 0x7547, 0x465e, 0x7548, 0x5a7c, 0x5b23, 0x3d6c, + 0x5b24, 0x754a, 0x4d4b, 0x4778, 0x5b25, 0x5b27, 0x754b, 0x5b28, + 0xae35, 0x5b29, 0x364a, 0x3148, 0x3939, 0x5b2a, 0x5b2b, 0x3d71, + 0x4162, 0x754c, 0x7537, 0x5258, 0x413e, 0x413d, 0x4258, + /* 0x6700 */ + 0x3a47, 0xae37, 0x5072, 0xae38, 0x376e, 0x4d2d, 0x4a7e, 0x497e, + 0x5b2c, 0xae39, 0x754d, 0x3a73, 0x443f, 0x5b2d, 0x4f2f, 0xae3b, + 0x4b3e, 0x442b, 0x5b2e, 0x347c, 0x5b2f, 0x5b30, 0x4c5a, 0x4c24, + 0x4b76, 0x4b5c, 0x3b25, 0x5b32, 0x3c6b, 0x754f, 0x4b51, 0x5b34, + 0x5b37, 0x5b36, 0x3479, 0x3560, 0x5b33, + /* 0x6740 */ + 0x5b35, 0x5b38, 0x7551, 0x7552, 0x3f79, 0xae3e, 0xae3f, 0x4d7b, + 0x3049, 0x3a60, 0x423c, 0x3c5d, 0xae40, 0x3e73, 0x5b3b, 0x454e, + 0xae41, 0x5b39, 0x422b, 0x5b3a, 0x3e72, 0x4c5d, 0x5b3c, 0x5b3d, + 0x4d68, 0x7550, 0x5b42, 0x393a, 0x4755, 0x5b3f, 0x456c, 0x5a5e, + 0x5a62, 0xae45, 0x354f, 0xae46, 0x4747, 0x7553, 0x5b41, 0x3e3e, + 0x4844, + /* 0x6780 */ + 0x7554, 0x5b47, 0x487a, 0x5b3e, 0x5b44, 0x5b43, 0x404f, 0xae48, + 0x7555, 0x4b6d, 0x4e53, 0x7556, 0x4b67, 0x7557, 0x324c, 0x3b5e, + 0x4f48, 0x5b46, 0x3f75, 0x5b45, 0x5b40, 0x384f, 0xae4c, 0xae4d, + 0x5b4c, 0x5b4a, 0x324d, 0x5b48, 0x5b4e, 0x5b54, 0x7558, + /* 0x67C0 */ + 0x755a, 0x4248, 0xae4e, 0x4a41, 0x5b56, 0xae4f, 0x4922, 0x5b55, + 0x4770, 0x4b3f, 0x343b, 0xae50, 0x4077, 0x3d40, 0x755b, 0x4453, + 0xae51, 0x4d2e, 0xae52, 0x5b51, 0x5b50, 0x5b52, 0x5b4f, 0x5b57, + 0x5b4d, 0x5b4b, 0x5b53, 0x5b49, 0xae53, 0x436c, 0x4c78, 0x3c46, + 0x3a74, 0xae54, 0x7559, 0x3a3a, 0x755c, 0x4b6f, 0x3341, + /* 0x6800 */ + 0x755d, 0x444e, 0x464a, 0x3149, 0xae4b, 0x4072, 0x4034, 0x372a, + 0xae58, 0x755f, 0x5b59, 0xae59, 0x393b, 0x337c, 0x5b5b, 0x3374, + 0x5b61, 0x7560, 0xae5a, 0x7561, 0x5b5e, 0xae5c, 0x4073, 0x334b, + 0x3a2c, 0xae5d, 0x334a, 0x3a4f, 0xae5e, + /* 0x6840 */ + 0x5b5c, 0x3765, 0x374b, 0x456d, 0xae5f, 0xae60, 0x5b5a, 0x3046, + 0xae61, 0xae62, 0x5b5d, 0x5b5f, 0x364d, 0x372c, 0x755e, 0x343c, + 0x354b, 0xae63, 0xae64, 0x5b62, 0x7562, 0x3a79, 0x4b71, 0x3b37, + 0x5b63, 0x4930, 0xae66, 0xae67, 0x7563, 0x5b6f, 0x7564, 0x3233, + 0x5b64, 0xae68, 0xae69, 0x5b75, 0x5b65, + /* 0x6880 */ + 0x4e42, 0xae6a, 0x5b6c, 0x475f, 0x5b74, 0x5b67, 0xae6b, 0x3034, + 0x5b69, 0xae6c, 0x393c, 0xae6e, 0xae6f, 0xae70, 0x5b6b, 0xae71, + 0x5b6a, 0x5b66, 0x5b71, 0x3e3f, 0x7566, 0x7567, 0x546d, 0x3868, + 0x4d7c, 0xae72, 0xae73, 0x5b68, 0x4474, 0x3323, 0x3a2d, 0x7568, + 0x5b60, 0xae74, 0x5b70, 0x3361, 0x5b6e, 0x5b72, 0xae75, 0x456e, + /* 0x68C0 */ + 0xae7a, 0x347e, 0xae7b, 0x5c32, 0x7569, 0x4c49, 0x5b77, 0x347d, + 0xae7c, 0x5b7e, 0xae7d, 0x756a, 0x4b40, 0x5c21, 0x5c23, 0xae7e, + 0x5c27, 0x5b79, 0xaf21, 0x432a, 0x456f, 0x5c2b, 0x5b7c, 0x5c28, + 0xaf22, 0xaf23, 0x5c22, 0x756b, 0xaf24, 0x756c, 0x3f39, 0x5c2c, + 0x756d, 0x756e, 0x4033, 0xaf25, 0x5c2a, 0x343d, 0xae76, 0x756f, + /* 0x6900 */ + 0x4f50, 0x5b76, 0xaf26, 0x5c26, 0x3058, 0xaf27, 0x5b78, 0x7570, + 0x4c3a, 0x5b7d, 0x3f22, 0x4447, 0x5b73, 0x5c25, 0x3f7a, 0x5c2f, + 0x3371, 0x3821, 0x5c31, 0x5b7a, 0x5c30, 0x5c29, 0x5b7b, 0x5c2d, + 0x5c2e, 0x5c3f, 0x464e, 0x7573, 0x5c24, 0x5c3b, 0xaf2b, 0x5c3d, + 0x4458, + /* 0x6940 */ + 0x7574, 0xaf2d, 0x7571, 0x4d4c, 0x4976, 0x5c38, 0x424a, 0x7575, + 0x5c3e, 0x413f, 0x5c35, 0x5c42, 0x5c41, 0x466f, 0x5c40, 0x466a, + 0x7576, 0x7577, 0x7578, 0xaf2e, 0x5c44, 0x5c37, 0xaf2f, 0x3648, + 0x5c3a, 0x3d5d, 0xaf30, 0x4760, 0x5c3c, 0x364b, 0x5c34, 0x5c36, + 0x5c33, 0xaf31, 0x4f30, 0x335a, 0x5c39, 0xaf32, + /* 0x6980 */ + 0x7579, 0x5c43, 0x3335, 0x3a67, 0x315d, 0x5c54, 0xaf33, 0x4f31, + 0x5c57, 0xaf35, 0xaf36, 0x3f3a, 0x5c56, 0x5c55, 0x757b, 0xaf37, + 0x5c52, 0x757c, 0x5c46, 0xaf38, 0x5c63, 0x5c45, 0x5c58, 0xaf39, + 0xaf3a, 0x5c50, 0xaf3b, 0x5c4b, 0x5c48, + /* 0x69C0 */ + 0xaf3c, 0x5c49, 0x5c51, 0x7422, 0x5c4e, 0x393d, 0x4448, 0x4164, + 0x5c4c, 0x757d, 0x5c47, 0xaf3d, 0x5c4a, 0xaf3e, 0x4d4d, 0x4b6a, + 0x5c4f, 0x5c59, 0x7622, 0xaf44, 0x5c61, 0x5c5a, 0x7623, 0x7624, + 0x5c67, 0x5c65, 0xaf45, 0xaf46, 0x5c60, 0xaf47, 0xaf49, 0x7625, + 0x7626, 0x5c5f, 0x4450, 0x4165, 0xaf4a, 0x5c5d, + /* 0x6A00 */ + 0x5c5b, 0x5c62, 0x5c68, 0x4875, 0x5c6e, 0x7627, 0xaf4b, 0x5c69, + 0x5c6c, 0x5c66, 0x7628, 0x4374, 0x4938, 0xaf4c, 0x5c5c, 0xaf4d, + 0x5c64, 0x3e40, 0x4c4f, 0x5c78, 0x5c6b, 0x3822, 0x3223, 0x335f, + 0x5c53, 0xaf41, 0xaf4f, 0xaf50, 0xaf51, 0x3e41, 0x5c70, 0x5c77, + 0x3c79, 0x3372, 0x762a, 0x432e, 0x762b, 0xaf52, + /* 0x6A40 */ + 0x5c6d, 0x762c, 0xaf53, 0x5c72, 0x5c76, 0xaf54, 0x3636, 0xaf56, + 0x762d, 0xaf57, 0x762e, 0x354c, 0x5c74, 0x762f, 0x3521, 0x464b, + 0x5c73, 0xaf58, 0x5c75, 0x7630, 0x5c6f, 0x7631, 0x5c71, 0xaf55, + 0xaf5a, 0x3360, + /* 0x6A80 */ + 0x4349, 0xaf5b, 0x5c7c, 0x7633, 0xaf5c, 0x5c7a, 0x3869, 0x5c79, + 0xaf5e, 0x7634, 0x5d21, 0x5b58, 0x7635, 0x7636, 0xaf5f, 0x5c7b, + 0xaf60, 0x5c7d, 0x5c7e, 0x7637, 0x5d2c, 0xaf62, 0x5d28, 0x5b6d, + 0x5d27, 0x5d26, 0x5d23, 0xaf63, + /* 0x6AC0 */ + 0x5c6a, 0x5d25, 0x5d24, 0xaf64, 0xaf66, 0x5d2a, 0x4f26, 0xaf65, + 0x5d2d, 0x367b, 0xaf67, 0xaf68, 0x5d29, 0x5d2b, 0x7638, 0x7639, + 0x4827, 0x5d2e, 0xaf6b, 0xaf6c, 0xaf6d, 0xaf6e, 0x5d32, 0x5d2f, + 0xaf6f, + /* 0x6B00 */ + 0x4d73, 0x5d30, 0x5c5e, 0xaf71, 0xaf72, 0xaf73, 0xaf74, 0x5d33, + 0x5d34, 0xaf76, 0x763c, 0x3135, 0x763d, 0x5d36, 0x3767, 0x3c21, + 0x3655, 0x3224, 0x763e, 0xaf78, 0x4d5f, 0x763f, 0x5d38, 0x5d37, + 0x5d3a, 0x353d, 0x3656, 0x343e, + /* 0x6B40 */ + 0x5d3d, 0x7640, 0x5d3c, 0x5d3e, 0xaf79, 0x324e, 0x4337, 0x5d3f, + 0x343f, 0x5d41, 0x7641, 0xaf7a, 0x5d40, 0x5d42, 0x5d43, 0x7642, + 0x5d44, 0x3b5f, 0x4035, 0x3a21, 0x7643, 0x4970, 0x7644, 0x4a62, + 0x4f44, 0xaf7b, 0x3b75, 0x3a50, 0x4e72, 0xaf7c, 0x7645, 0x5d45, + 0x5d46, 0xaf7d, 0x3b60, 0x5d47, + /* 0x6B80 */ + 0x5d48, 0xaf7e, 0x7646, 0x5d4a, 0x5d49, 0x4b58, 0x3d5e, 0x3c6c, + 0x3b44, 0x5d4b, 0x5d4d, 0x3f23, 0x5d4c, 0xee21, 0x5d4e, 0x5d4f, + 0x7647, 0x5d50, 0x5d51, 0x7648, 0xee22, 0x5d52, 0x5d54, 0x5d53, + 0x5d55, 0x3225, 0x434a, 0x5d56, 0x3b26, 0x334c, 0x5d57, 0xee24, + 0xee25, 0x4542, + /* 0x6BC0 */ + 0x544c, 0x3523, 0x5d58, 0xee26, 0xee27, 0xee28, 0x5d59, 0x4a6c, + 0x4b68, 0x764a, 0x4647, 0x5d5a, 0x4866, 0x764b, 0x764c, 0x487b, + 0xee29, 0x4c53, 0x5d5b, 0xee2a, 0xee2b, 0x5d5d, 0x5d5c, 0xee2c, + 0x5d5f, 0xee2d, 0x5d5e, 0x764d, + /* 0x6C00 */ + 0xee2e, 0x764e, 0x5d61, 0xee2f, 0xee30, 0x3b61, 0x764f, 0x4c31, + 0x5d62, 0x5d63, 0x3524, 0x5d64, 0x5d66, 0x5d65, 0x7650, 0x3f65, + 0xee31, 0xee32, 0x4939, 0x314a, 0xee33, 0x4845, 0xee35, + /* 0x6C40 */ + 0x4475, 0x3d41, 0x3561, 0xee36, 0x4846, 0x3c2e, 0x5d68, 0x3440, + 0x7651, 0x3178, 0xee37, 0x7652, 0x4672, 0x5d67, 0x393e, 0x4353, + 0x5d69, 0xee4f, 0x5d71, 0x5d6a, 0xee38, 0x4241, 0x3562, 0x5d72, + 0x7654, 0x7655, 0x3768, 0x3525, 0x5d70, + /* 0x6C80 */ + 0x5d6e, 0x5d6b, 0x4d60, 0xee39, 0x7656, 0x7657, 0x4440, 0xee3a, + 0x4659, 0x5d6c, 0x5d74, 0x5d73, 0x3723, 0xee3c, 0xee3d, 0x322d, + 0xee3e, 0x7658, 0x3a3b, 0x5d6d, 0x5d6f, 0x7659, 0x4b57, 0x4274, + 0x7653, 0x4b77, 0xee3f, 0x5d7c, 0x5d7d, 0x324f, 0x4a28, 0x4c7d, + 0x5e21, 0x3c23, 0x3e42, 0x5d78, 0x5d7e, 0x3168, + /* 0x6CC0 */ + 0x3637, 0xee40, 0x5d75, 0x5d7a, 0x765b, 0x4074, 0x4771, 0x4867, + 0xee41, 0x5d77, 0x765c, 0x4b21, 0xee43, 0x5d79, 0x5e24, 0xee44, + 0x5e22, 0xee45, 0x5d7b, 0x765d, 0x4b22, 0x4748, 0x3563, 0x4525, + 0x436d, 0xee46, 0x5e25, 0x765e, 0xee47, 0xee48, 0x765f, 0x5e23, + 0x4259, 0x5d76, 0x314b, 0x765a, + /* 0x6D00 */ + 0xee4a, 0x7661, 0xee4b, 0x4d4e, 0x5e30, 0x7662, 0x5e2f, 0x4076, + 0x5e2c, 0x4d6c, 0x4636, 0x5e26, 0xee4c, 0x4445, 0xee4d, 0xee4e, + 0x314c, 0x393f, 0x5e29, 0x7663, 0xee50, 0x7664, 0x3d27, 0x5e2e, + 0xee65, 0x5e2d, 0x5e28, 0x5e2b, 0x7665, 0x3368, 0xee51, 0x5e2a, + 0x4749, 0x7666, + /* 0x6D40 */ + 0x4e2e, 0x3e74, 0x4075, 0x7667, 0x5e36, 0x5e34, 0xee52, 0x494d, + 0xee53, 0xee54, 0x5e31, 0x5e33, 0x7668, 0x313a, 0x3940, 0x4f32, + 0x333d, 0x4962, 0xee55, 0x4d61, 0x3324, 0x3f3b, 0x5e35, + /* 0x6D80 */ + 0xee56, 0xee57, 0x766a, 0x5e3a, 0x766b, 0x3e43, 0x766c, 0xee58, + 0x4d30, 0xee59, 0x5e37, 0xee5a, 0x5e32, 0x766d, 0x5e38, 0xee5b, + 0x4e5e, 0x4573, 0x4642, 0x766e, 0xee61, 0x766f, 0xee62, 0x3336, + 0x3155, 0xee63, 0x5e3e, 0x5e41, 0x4e43, 0x7670, + /* 0x6DC0 */ + 0x4d64, 0xee64, 0x7671, 0x5e48, 0x5e42, 0x5e3f, 0xee66, 0x4e54, + 0x5e45, 0xee67, 0xee68, 0xee69, 0x3d4a, 0x5e47, 0x5e4c, 0x7672, + 0x4571, 0x5e4a, 0x7673, 0x7674, 0x7675, 0x5e44, 0xee6a, 0x4338, + 0x5e4b, 0x5e40, 0x5e46, 0xee6b, 0x5e4d, 0x307c, 0x5e43, 0x5e4e, + 0x3f3c, 0x3d5f, 0x4a25, 0xee6c, 0x3a2e, 0x5e3b, 0x5e49, 0x453a, + 0x7676, + /* 0x6E00 */ + 0x4036, 0x3369, 0x3a51, 0x3e44, 0x5e3d, 0x3d42, 0x374c, 0x5e3c, + 0xee5d, 0x5e52, 0x3d6d, 0x383a, 0x5e61, 0xee6e, 0x5e5b, 0x3574, + 0x454f, 0xee6f, 0x5e56, 0x5e5f, 0x302f, 0x3132, 0xee70, 0x3239, + 0x5e58, 0x422c, 0x5e4f, 0x5e51, 0x3941, 0xee72, 0x7678, 0xee6d, + 0x5e62, 0x5e5d, 0xee73, 0x5e55, + /* 0x6E40 */ + 0x5e5c, 0x7679, 0xee74, 0xee75, 0x4c2b, 0xee76, 0xee77, 0x5e5a, + 0x5e5e, 0xee78, 0xee79, 0xee7a, 0xee7b, 0x3850, 0xee7c, 0x3e45, + 0x4339, 0x767a, 0x767b, 0x5e54, 0xee7d, 0x4d2f, 0x5e57, 0x5e50, + 0x4572, 0x5e53, 0x5e59, 0x4f51, 0x3c3e, + /* 0x6E80 */ + 0x4b7e, 0x5e63, 0x482e, 0x5e6f, 0x383b, 0xef21, 0x3d60, 0x5e65, + 0x4e2f, 0x3942, 0x5e72, 0x306e, 0x5e70, 0xef22, 0x5e64, 0x767c, + 0x5e6a, 0x767d, 0x5e6c, 0xef23, 0x4d4f, 0x5e67, 0x452e, 0x5e69, + 0xef24, + /* 0x6EC0 */ + 0x767e, 0x5e71, 0xef25, 0x5e6b, 0x4c47, 0x7721, 0x5e66, 0xef26, + 0x3c22, 0x5e7e, 0x7722, 0x336a, 0x5e68, 0x5e6d, 0x5e6e, 0xef27, + 0x426c, 0x425a, 0xef29, 0x5e76, 0x5e7c, 0x5e7a, 0x4529, 0x5f23, + 0x5e77, 0xef2a, 0xef2b, 0x5e78, 0x5e60, + /* 0x6F00 */ + 0x3579, 0x493a, 0x3c3f, 0x3977, 0xef2c, 0xef2d, 0x4f33, 0x7723, + 0x5e74, 0x5f22, 0x3169, 0x4166, 0xef2e, 0x7724, 0x4779, 0x3441, + 0x4e7a, 0xef2f, 0x7726, 0x4c21, 0x4452, 0x7727, 0x5e7b, 0x5e7d, + 0x7728, 0xef28, 0xef30, 0x4132, 0xef31, 0x5f21, 0x5e79, + /* 0x6F40 */ + 0x5e73, 0x3443, 0x7729, 0xef33, 0x3769, 0xef34, 0x5f2f, 0x772a, + 0xef35, 0x5f2a, 0x4078, 0x772b, 0x3363, 0xef36, 0x772c, 0x772d, + 0x3d61, 0x5f33, 0xef37, 0x5f2c, 0x442c, 0x5f29, 0x4459, 0x5f4c, + 0x5f26, 0x5f25, 0x5f2e, 0xef39, 0x772e, + /* 0x6F80 */ + 0x5f28, 0x5f27, 0x5f2d, 0x4021, 0x5f24, 0x772f, 0x7730, 0x7731, + 0x5f30, 0xef3a, 0x5f31, 0x7732, 0xef3b, 0x3442, 0xef38, 0xef3d, + 0x7733, 0x5f36, 0x5f35, 0x5f37, 0xef3e, 0x7734, 0x5f3a, 0xef3f, + 0x4543, 0x5f34, 0xef41, 0x7735, 0x5f38, 0x7736, 0xef3c, + /* 0x6FC0 */ + 0x3763, 0x4279, 0x5f32, 0x473b, 0x5f39, 0x7737, 0xef42, 0xef43, + 0x7738, 0x5f3e, 0x5f3c, 0x5f3f, 0xef44, 0x5f42, 0xef45, 0x5f3b, + 0x396a, 0x4728, 0x5e39, 0xef46, 0x4d74, 0x5f3d, 0x5f41, 0x4275, + 0x773a, 0x5f40, 0x5f2b, 0x773b, 0x6f69, 0x7739, 0x5f45, 0xef48, + 0x5f49, + /* 0x7000 */ + 0xef49, 0x5f47, 0x773c, 0x773d, 0xef4a, 0x5f43, 0xef4b, 0x5f44, + 0x5f48, 0x5f46, 0x494e, 0x5f4e, 0x5f4b, 0x5f4a, 0x5f4d, 0x4654, + 0x5f4f, 0xef4c, 0x4375, 0x426d, 0x773e, 0x4025, 0x5f50, 0x5f52, + 0xef4e, 0xef4f, 0xef50, 0x5f51, + /* 0x7040 */ + 0xef51, 0xef52, 0x773f, 0xef53, 0x5e75, 0x7742, 0x5f53, 0xef55, + 0x4667, 0x7740, 0x7741, 0x5f54, 0x7743, 0xef56, 0xef57, 0x3250, + 0xef58, 0xef59, 0x4574, 0x3325, 0x7744, 0xef5a, 0x3564, 0x3c5e, + 0x3a52, 0xef5b, + /* 0x7080 */ + 0xef5c, 0x7745, 0xef5d, 0x4f27, 0x3f66, 0x316a, 0x5f56, 0xef5e, + 0xef5f, 0x5f55, 0xef62, 0x7746, 0x7747, 0x5f59, 0x433a, 0x5f5c, + 0x5f57, 0xef63, 0x5f5b, 0x7748, 0x5f5a, 0x4540, 0x3059, 0xef60, + /* 0x70C0 */ + 0x4e75, 0xef66, 0x5f5e, 0x3128, 0xef67, 0xef68, 0x7749, 0x774a, + 0x5f60, 0xef69, 0x5f5f, 0x5f5d, 0x774b, 0xef65, 0x5f58, 0x4b23, + 0x5f62, + /* 0x7100 */ + 0xef6a, 0xef6b, 0xef6c, 0xef6d, 0xef6e, 0x5f61, 0xef6f, 0x774c, + 0x316b, 0x5f64, 0x4a32, 0x5f63, 0x774e, 0x774f, 0x4c35, 0x3e47, + 0x774d, 0x7750, 0xef71, 0x7751, 0xef72, 0x4133, 0x3e46, + /* 0x7140 */ + 0x7752, 0x7753, 0x4e7b, 0xef74, 0x5f6a, 0x4079, 0xef73, 0x7754, + 0x7756, 0xef75, 0x5f66, 0x5f6b, 0x316c, 0x7757, 0xef76, 0x7758, + 0x5f69, 0x4761, 0x5f65, 0x5f68, 0x3e48, 0x7759, 0x4851, 0x5f6c, + 0x3c51, 0x407a, + /* 0x7180 */ + 0xef79, 0x5f6f, 0x775b, 0x775c, 0x5f67, 0x3727, 0x5f6d, 0x775d, + 0x4d50, 0x5f70, 0xef78, 0x7426, 0xef7a, 0x3d4f, 0xef7b, 0xef7c, + 0x5f71, 0x5f72, 0xef7d, 0xef7e, 0x472e, 0xf021, 0x5f74, 0x775f, + 0x5f75, + /* 0x71C0 */ + 0x775e, 0x4733, 0x7760, 0x4575, 0x5f77, 0xf023, 0x5f79, 0x4e55, + 0x5f76, 0xf024, 0x5f78, 0x316d, 0x5f73, 0xf025, 0xf026, 0x535b, + 0x5f7a, 0x4167, 0x3b38, 0x5f7c, 0x5f7b, 0x3f24, 0x5259, 0x5f7d, + 0x6021, 0x5f6e, 0x5f7e, 0x7761, 0x6022, + /* 0x7200 */ + 0x7762, 0x477a, 0xf027, 0x6023, 0x6024, 0x7763, 0x6025, 0x6026, + 0x445e, 0xf02a, 0x6028, 0x6027, 0x6029, 0x602a, 0xf02b, 0x3c5f, + 0x4963, 0xf02c, 0xf02d, 0x4c6c, 0x602b, 0x602c, 0x4156, 0x3c24, + 0x602d, + /* 0x7240 */ + 0x602e, 0xf02f, 0x602f, 0x4a52, 0x4847, 0x6030, 0x4757, 0x442d, + 0xf030, 0x7764, 0x7765, 0xf031, 0x6031, 0x3267, 0x356d, 0x4c46, + 0x4c36, 0x3234, 0x4f34, 0xf032, 0x4b52, 0x4a2a, 0xf034, 0xf035, + 0x4037, 0x6032, 0xf036, 0x4643, 0x3823, 0x6033, 0xf037, + /* 0x7280 */ + 0x3a54, 0x6035, 0x6034, 0x6036, 0x7767, 0xf038, 0x6037, 0x6038, + 0x7768, 0x353e, 0x6039, 0x603a, 0x3824, 0xf03a, 0xf03b, 0x4848, + 0xf03c, 0xf03d, 0x603c, 0x3e75, 0x603b, 0x7769, + /* 0x72C0 */ + 0x776a, 0xf03e, 0x3638, 0x603d, 0x603f, 0x603e, 0xf040, 0x6040, + 0x3851, 0x6041, 0x3669, 0x4140, 0x397d, 0x6043, 0x6044, 0x6042, + 0x3c6d, 0x4648, 0x3639, 0xf043, 0x6046, 0x432c, 0x6045, 0xf044, + 0x776b, 0x4f35, 0x4762, + /* 0x7300 */ + 0xf045, 0x6049, 0xf046, 0x604b, 0x6048, 0xf047, 0xf048, 0x4c54, + 0x604a, 0x604c, 0x4e44, 0x6050, 0x776d, 0x776e, 0x604f, 0x4376, + 0x472d, 0xf04b, 0x3825, 0x604e, 0xf04c, 0xf04d, 0x604d, 0x4d31, + 0x4d32, 0xf04a, 0xf04e, 0x6051, 0x316e, + /* 0x7340 */ + 0x3976, 0x3b62, 0x6052, 0x6053, 0x7770, 0xf04f, 0x6055, 0x3d43, + 0x7771, 0x6057, 0x6056, 0xf051, 0xf052, 0xf054, 0xf055, 0x6058, + 0xf056, 0x334d, 0x605a, 0xf057, 0x6059, 0x605c, 0x605b, 0x7772, + /* 0x7380 */ + 0xf058, 0x383c, 0xf059, 0x4e28, 0x364c, 0xf05a, 0x3226, 0xf05b, + 0x7773, 0x366a, 0xf05c, 0xf05d, 0xf05e, 0x7774, 0x7775, 0x7776, + 0xf05f, 0x7777, 0xf060, 0x3461, 0x7778, 0x4e68, 0x605e, 0xf061, + 0xf062, 0xf063, 0x6060, 0xf064, 0xf065, + /* 0x73C0 */ + 0x6061, 0x3251, 0xf066, 0x605d, 0x7779, 0x3b39, 0xf067, 0x4441, + 0x605f, 0x777a, 0x777b, 0x777c, 0x6064, 0x3c6e, 0xf068, 0x777d, + 0x6062, 0xf069, 0x777e, 0x373e, 0x4849, 0x6063, 0x607e, 0x6069, + 0xf06a, 0xf06c, 0x383d, + /* 0x7400 */ + 0xf06d, 0x3565, 0x6066, 0x4d7d, 0x7821, 0x4e30, 0x7822, 0xf06b, + 0x7823, 0x7824, 0x4276, 0xf06e, 0x6068, 0x7826, 0x7827, 0x7828, + 0x7829, 0x782a, 0x782b, 0x782c, 0x782d, 0xf06f, 0x606a, 0x4e56, + 0x3657, 0x487c, 0x474a, 0xf070, 0x606b, 0x606d, + /* 0x7440 */ + 0xf072, 0x6070, 0xf073, 0x782e, 0x782f, 0x7830, 0x7831, 0xf074, + 0xf075, 0xf071, 0x606c, 0x7832, 0x606f, 0x386a, 0x314d, 0x6071, + 0xf076, 0x3f70, 0x606e, 0x4e5c, 0x7833, 0x6074, 0x7424, 0x6072, + 0x6075, 0x7834, 0x7835, 0x6067, 0x6073, 0xf077, 0x3a3c, 0x6076, + 0x6077, + /* 0x7480 */ + 0xf078, 0x4d7e, 0xf079, 0x7836, 0x7837, 0xf07a, 0x7838, 0x6078, + 0x783d, 0xf07c, 0xf07d, 0x7839, 0xf07e, 0x783a, 0x6079, 0x783b, + 0xf121, 0xf122, 0x6065, 0x783c, 0xf123, 0x783e, 0x607a, 0x783f, + 0x7840, 0xf124, 0xf125, 0x3444, 0x7841, 0xf126, 0xf128, 0xf127, + 0x3c25, 0x7842, + /* 0x74C0 */ + 0x7843, 0x7844, 0x607b, 0x607c, 0x607d, 0xf129, 0xf12a, 0x7845, + 0x313b, 0xf12b, 0x6121, 0x493b, 0x6122, 0x3424, 0x6123, 0x6124, + 0xf12d, 0x6125, 0xf12c, 0x6127, 0x6128, 0x6126, 0x4953, 0x612a, + 0x6129, 0xf12f, 0x7846, + /* 0x7500 */ + 0x7847, 0x612c, 0x612b, 0x612d, 0x612e, 0x6130, 0x612f, 0x3979, + 0x6132, 0x6131, 0x7848, 0x3445, 0x3f53, 0x453c, 0x6133, 0x4038, + 0xf131, 0x3b3a, 0xf132, 0x3179, 0x6134, 0x4d51, 0xf133, 0x4a63, + 0x6135, 0x7849, 0x4544, 0x4d33, 0x3943, 0x3f3d, 0x434b, 0x5234, + 0x442e, 0x3268, 0x6136, 0xf136, 0xf137, + /* 0x7540 */ + 0xf138, 0x6137, 0x613c, 0xf139, 0x613a, 0x6139, 0x5a42, 0x3326, + 0x6138, 0xf13a, 0x305a, 0xf13b, 0x482a, 0xf13c, 0x484a, 0x4e31, + 0x613d, 0x613b, 0x435c, 0x4026, 0x482b, 0x492d, 0x613f, 0x4e2c, + 0x374d, 0x6140, 0x613e, 0x4856, 0x6141, 0xf13d, 0x6142, 0x784a, + 0x305b, 0xf13f, 0xf13e, 0x3e76, 0x6147, 0x6144, 0x466d, 0x6143, + 0x784b, 0xf140, 0xf141, 0xf142, 0x3526, + /* 0x7580 */ + 0xf143, 0x614a, 0x6145, 0x6146, 0x6149, 0x6148, 0x4925, 0xf145, + 0x4142, 0x4141, 0x353f, 0x784c, 0x614b, 0x614c, 0x614d, 0xf147, + 0x614f, 0x614e, 0x3156, 0xf149, 0x6157, 0x4868, 0x6151, 0x6153, + 0xf14a, 0x6155, 0x3f3e, 0x6156, 0x6154, 0x3c40, 0xf14b, + /* 0x75C0 */ + 0xf14c, 0x6150, 0x6152, 0x4942, 0xf14d, 0x3e49, 0x6159, 0x6158, + 0x784e, 0xf14e, 0x615a, 0xf14f, 0x3c26, 0x3a2f, 0x4577, 0x615b, + 0x444b, 0xf150, 0x615d, 0xf151, 0xf152, 0x4e21, 0x615c, 0x784f, + 0xf153, 0x4169, 0xf154, 0xf155, 0x6162, 0xf156, 0x6164, 0x6165, + 0x4354, 0xf157, 0x6163, 0x6160, 0x615e, 0x615f, + /* 0x7600 */ + 0x7850, 0x6161, 0x7851, 0xf158, 0xf15a, 0x7852, 0x6168, 0x6166, + 0x6167, 0xf15b, 0xf15e, 0x7853, 0x7854, 0xf159, 0x7855, 0xf15f, + 0xf160, 0x7856, 0x6169, 0x616b, 0x616c, 0x616d, 0x616e, 0xf162, + 0x7e7d, 0x616a, 0xf163, 0x7857, 0x6170, 0xf165, 0x616f, 0x7858, + 0x6171, 0xf164, + /* 0x7640 */ + 0xf168, 0x4e45, 0x7859, 0x6174, 0x6172, 0x6173, 0xf16a, 0x785a, + 0x3462, 0x4c7e, 0xf16b, 0x4a4a, 0x6176, 0x6175, 0x6177, 0x6178, + 0x785b, 0x785c, 0x617c, 0x6179, 0x617a, 0x617b, 0x617d, 0x785d, + 0xf16d, 0x785e, 0x617e, 0x785f, 0x6221, 0x6222, 0x6223, 0x482f, + 0x4550, 0x6224, 0x4772, 0x4934, + /* 0x7680 */ + 0x6225, 0x7860, 0x6226, 0x452a, 0x3327, 0x3944, 0x6227, 0x6228, + 0x6229, 0x3b29, 0x622b, 0xf16e, 0x622a, 0x622c, 0x622d, 0x7861, + 0xf16f, 0x7862, 0x7863, 0xf171, 0xf170, 0x7864, 0xf172, 0xf173, + 0x7865, 0x4869, 0xf174, 0x622e, 0x622f, 0x7866, 0x7369, 0x6230, + 0x6231, 0x6232, 0x3b2e, + /* 0x76C0 */ + 0x6233, 0x4756, 0x7867, 0x4b5f, 0x314e, 0xf176, 0x3157, 0x7868, + 0x6234, 0x7869, 0x6236, 0x786a, 0x6235, 0x4570, 0x4039, 0x5d39, + 0x6237, 0x4c41, 0x6238, 0x3446, 0x4857, 0x6239, 0x786b, 0x623a, + 0xf178, 0x623b, 0xf179, 0x4c5c, 0x786c, 0x4c55, 0x443e, 0x416a, + 0x623d, 0x786d, 0x3d62, + /* 0x7700 */ + 0x3e4a, 0x6240, 0x623f, 0x623e, 0x487d, 0x786e, 0x3447, 0x3829, + 0xf17b, 0x786f, 0xf17c, 0x6246, 0x6243, 0x3f3f, 0x4c32, 0x6242, + 0x6244, 0x6245, 0x6241, 0xf17d, 0x7870, 0xf17e, 0x7871, 0x6247, + 0x6248, 0x442f, 0x3463, + /* 0x7740 */ + 0x4365, 0x7872, 0x6249, 0x7873, 0x7874, 0xf225, 0x624a, 0x624d, + 0x7875, 0x7876, 0xf226, 0x3f67, 0x7877, 0x4644, 0x624e, 0x4b53, + 0x624b, 0xf227, 0x624c, 0xf229, 0x6251, 0x7878, 0xf22a, 0xf22b, + 0x6250, 0x624f, + /* 0x7780 */ + 0x7879, 0x6253, 0x6252, 0x6254, 0x787a, 0xf22e, 0x6256, 0xf22f, + 0x6255, 0xf230, 0xf231, 0x4a4d, 0xf232, 0x787b, 0x3d56, 0x4e46, + 0x6257, 0x4637, 0x6258, 0x6259, 0x625d, 0x625b, 0x625c, 0x625a, + /* 0x77C0 */ + 0x625e, 0x625f, 0x6260, 0x6261, 0x4c37, 0x6262, 0xf233, 0xf234, + 0x787c, 0x4c70, 0x6263, 0xf235, 0x434e, 0xf236, 0x476a, 0x366b, + 0xf237, 0xf238, 0x433b, 0x6264, 0x363a, 0xf23a, 0x4050, 0xf23b, + 0xf23c, 0x6265, + /* 0x7800 */ + 0x3a3d, 0xf23e, 0xf23f, 0xf240, 0x6266, 0xf241, 0x6267, 0x3826, + 0x3a55, 0xf242, 0x6269, 0xf243, 0x4556, 0x3a56, 0x354e, 0xf244, + 0x787d, 0x4b24, 0x474b, 0x4557, 0x395c, + /* 0x7840 */ + 0x7921, 0x626b, 0xf245, 0x7922, 0x7923, 0x7924, 0x3e4b, 0xf246, + 0x7925, 0xf247, 0x4e32, 0x3945, 0x7926, 0x3827, 0x4823, 0x626d, + 0x626f, + /* 0x7880 */ + 0x386b, 0x626e, 0x4476, 0xf249, 0x6271, 0x3337, 0x626c, 0x486a, + 0x3130, 0xf24a, 0x3a6c, 0x4f52, 0x6270, 0xf24c, 0xf24d, 0xf24e, + 0x6272, 0xf24b, 0x4a4b, 0x4059, 0x6274, 0x792a, 0x6275, 0x7928, + 0x6273, 0x334e, 0xf24f, 0x627b, 0x627a, + /* 0x78C0 */ + 0x3c27, 0x627c, 0x6277, 0xf250, 0x627d, 0x6278, 0xf251, 0xf252, + 0x4858, 0x6276, 0x6279, 0xf253, 0x6322, 0xf254, 0xf255, 0x792b, + 0xf256, 0x6321, 0x4b61, 0x627e, 0x306b, 0x792c, 0x6324, 0x792e, + 0xf257, 0xf258, 0xf259, 0x6323, 0xf25a, + /* 0x7900 */ + 0x792d, 0x3e4c, 0x6325, 0x4143, 0xf25c, 0x6327, 0x6326, 0x6328, + 0xf25d, 0x792f, 0xf25f, 0x6268, 0x626a, 0x632a, 0x6329, 0x7930, + 0xf25e, 0x7931, 0x7932, 0x3c28, 0xf260, 0x4e69, 0x3c52, + /* 0x7940 */ + 0x632b, 0x3737, 0x7935, 0x7936, 0x3540, 0x3527, 0x3b63, 0xf261, + 0x4d34, 0x6331, 0x6330, 0x4144, 0x632d, 0xf262, 0x632f, 0xf263, + 0x793a, 0x3d4b, 0x3f40, 0x632e, 0x632c, 0x472a, 0x3e4d, 0xf265, + 0x493c, 0x3a57, 0xf266, 0x4578, 0x793e, 0x6332, 0x6333, + /* 0x7980 */ + 0x6349, 0x3658, 0x4f3d, 0x4135, 0x6334, 0x3252, 0x4477, 0x4a21, + 0xf267, 0xf268, 0xf269, 0x7942, 0xf26a, 0x6335, 0xf26b, 0x357a, + 0x6336, 0xf26c, 0x6338, 0x6339, 0x4729, 0x7943, 0x633a, 0xf26d, + 0x7944, 0x633b, 0x633c, 0xf26e, 0x3659, 0x3253, 0x4645, + /* 0x79C0 */ + 0x3d28, 0x3b64, 0xf26f, 0xf270, 0x7945, 0x633d, 0x7946, 0x3d29, + 0xf271, 0xf272, 0x324a, 0x4943, 0x7948, 0x633e, 0xf273, 0x486b, + 0x7949, 0x4145, 0x6341, 0x6342, 0x4769, 0x3f41, 0x633f, 0x4361, + 0x794a, 0x6340, 0x794b, 0x3e4e, 0x305c, + /* 0x7A00 */ + 0x3529, 0x794c, 0x6343, 0xf278, 0x4478, 0x6344, 0x4047, 0xf279, + 0x4c2d, 0xf27a, 0x4923, 0x6345, 0x6346, 0x4355, 0xf27b, 0x4e47, + 0xf27c, 0x6348, 0x6347, 0xf27e, 0x3c6f, 0x634a, 0x3070, 0x634d, + 0xf321, 0x794e, 0x634b, 0x3254, 0x374e, 0x634c, 0x3946, + /* 0x7A40 */ + 0x3972, 0x4a66, 0x634e, 0x4b54, 0xf322, 0x6350, 0xf323, 0x4051, + 0x314f, 0x323a, 0x302c, 0xf324, 0x634f, 0xf325, 0xf326, 0x794f, + 0xf327, 0xf328, 0x6351, 0x6352, 0x3e77, 0xf329, 0x6353, 0xf32a, + 0x334f, 0x7950, 0x6355, 0x376a, 0xf32b, 0x3566, 0xf32c, 0x6356, + 0x3675, 0x6357, 0x407c, + /* 0x7A80 */ + 0x464d, 0xf32d, 0x4060, 0x3a75, 0x7952, 0x6358, 0xf32e, 0xf32f, + 0x4362, 0x416b, 0x635a, 0x635c, 0x6359, 0x635b, 0x3722, 0x7953, + 0xf330, 0x635d, 0x3726, 0xf331, 0x3567, 0x4d52, 0x635f, 0x7955, + 0x6360, 0xf334, 0x312e, 0x7956, 0xf335, 0xf336, 0x6363, + /* 0x7AC0 */ + 0x3376, 0x6362, 0x6361, 0x6365, 0x635e, 0x6366, 0x4e29, 0xf338, + 0x6367, 0x7957, 0x6368, 0xf339, 0x5474, 0x636a, 0x6369, 0x636b, + 0x636c, 0x4e35, 0x636d, 0x706f, 0x3e4f, 0x636e, 0x636f, 0x3d57, + 0x4638, 0x6370, 0xf33a, 0xf33b, 0x4328, 0x7958, 0x6371, 0x433c, + 0x6372, 0xf33c, 0x3625, 0x513f, 0x435d, 0x3c33, 0x7959, 0x3448, + /* 0x7B00 */ + 0x6373, 0x6422, 0x6376, 0xf33f, 0x3568, 0x6375, 0x6424, 0x6374, + 0x3e50, 0x795a, 0x6378, 0x6379, 0x452b, 0x637a, 0x335e, 0x3f5a, + 0x4964, 0xf342, 0x637c, 0xf343, 0x4268, 0x795b, 0xf344, 0xf345, + 0xf346, 0x6377, 0x637b, 0x637d, 0x3a7b, 0x795c, 0xf341, + /* 0x7B40 */ + 0xf34a, 0x6426, 0x492e, 0x795d, 0x4826, 0x4579, 0x365a, 0x6425, + 0x6423, 0x795e, 0x4835, 0x637e, 0x435e, 0x457b, 0x457a, 0xf34c, + 0x3a76, 0x6438, 0x795f, 0xf34e, 0x6428, 0xf34f, 0x642a, 0xf350, + 0x642d, 0x7960, 0x642e, 0x7961, 0x642b, 0x642c, 0x7962, 0xf351, + 0x6429, 0x6427, 0xf34d, 0x6421, 0xf349, + /* 0x7B80 */ + 0x4a4f, 0x3255, 0x6435, 0x6432, 0x6437, 0xf354, 0xf355, 0x6436, + 0x4773, 0x4c27, 0x3b3b, 0x6430, 0x6439, 0x6434, 0xf356, 0x6433, + 0x642f, 0x7963, 0x6431, 0x3449, 0x433d, 0x407d, 0xf358, 0x4822, + 0x643e, 0xf359, 0x4824, 0xf35a, + /* 0x7BC0 */ + 0x4061, 0x643b, 0x484f, 0xf35b, 0x643f, 0x4a53, 0x435b, 0xf35c, + 0x643a, 0x643c, 0x643d, 0xf35f, 0xf360, 0x7965, 0x7966, 0xf361, + 0x6440, 0x3c44, 0x4646, 0x6445, 0x6444, 0x6441, 0xf362, 0x4f36, + 0xf363, 0x644a, 0x644e, 0x644b, + /* 0x7C00 */ + 0x6447, 0x7967, 0xf364, 0x6448, 0xf365, 0x644d, 0xf366, 0xf367, + 0x6442, 0x5255, 0x6449, 0x6443, 0x644c, 0x7969, 0x6452, 0x796a, + 0x344a, 0x644f, 0xf368, 0x6450, 0x6451, 0x6454, 0x7968, 0x796b, + 0x796c, 0x6453, 0x4876, 0x6455, 0x4e7c, 0x4a6d, + /* 0x7C40 */ + 0x645a, 0x6457, 0xf369, 0xf36a, 0x6456, 0x4052, 0x6459, 0x645b, + 0xf36b, 0x6458, 0x645f, 0xf36c, 0x645c, 0x796f, 0xf36d, 0x645d, + 0x6446, 0xf36e, 0x645e, 0x6460, 0xf36f, 0x6461, 0x7970, 0xf370, + 0xf371, 0xf372, 0x4a46, 0x6462, 0x7971, 0x4c62, + /* 0x7C80 */ + 0x364e, 0x3729, 0x6463, 0x4a34, 0x3f68, 0x4c30, 0x7972, 0x6464, + 0x4e33, 0x7973, 0x4774, 0x4146, 0x4734, 0x3d4d, 0x3040, 0x7974, + 0x6469, 0x6467, 0x6465, 0x3421, 0xf376, 0x3e51, 0x646a, 0x6468, + 0x6466, 0x646e, 0x646d, 0x646c, 0x646b, 0xf378, 0xf379, 0x646f, + 0x7975, 0x6470, 0x403a, 0xf37a, + /* 0x7CC0 */ + 0x6471, 0x6473, 0xf37c, 0x6472, 0xf37e, 0x3852, 0xf421, 0x4138, + 0x6475, 0x7976, 0x457c, 0xf423, 0x6474, 0x7977, 0x6476, 0x7978, + 0x4a35, 0x416c, 0x3947, 0x6477, 0xf425, 0x4e48, 0xf426, 0x6479, + 0x647a, 0x647b, 0xf428, 0x647c, 0x3b65, 0x647d, 0x374f, 0x356a, + /* 0x7D00 */ + 0x352a, 0x6521, 0xf429, 0x4c73, 0x3948, 0x647e, 0x7979, 0x797a, + 0xf42a, 0x6524, 0x4c66, 0x473c, 0x4933, 0xf42c, 0x797b, 0x3d63, + 0x6523, 0x3c53, 0x3949, 0x3b66, 0x3569, 0x4a36, 0x6522, 0x797c, + 0xf42d, 0x4147, 0x4b42, 0x3a77, 0x797d, 0x3b67, 0x445d, 0x6527, + 0x4e5f, 0x3a59, 0x797e, 0x6528, 0x3f42, 0x652a, 0x3e52, 0x3a30, + 0xf430, 0xf431, 0x6529, + /* 0x7D40 */ + 0xf432, 0x7a21, 0x3d2a, 0x383e, 0x4148, 0x6525, 0x652b, 0xf433, + 0x7a22, 0x6526, 0x3750, 0x652e, 0x6532, 0x376b, 0x7a23, 0x652d, + 0xf437, 0xf438, 0x6536, 0x7a24, 0x394a, 0x4d6d, 0x303c, 0x6533, + 0x356b, 0x6530, 0xf439, 0x6531, 0xf43a, 0x457d, 0x652f, 0x652c, + 0x3328, 0x4064, 0x3828, 0x7a25, 0x6538, 0xf43c, + /* 0x7D80 */ + 0x7a26, 0xf43e, 0xf43f, 0x6535, 0x7a27, 0xf440, 0x6537, 0x6534, + 0xf441, 0x3751, 0x4233, 0x6539, 0x416e, 0xf443, 0x6546, 0x7a28, + 0x6542, 0x653c, 0x7a29, 0xf444, 0xf445, 0x6540, 0x3c7a, 0x305d, + 0x653b, 0x6543, 0x6547, 0x394b, 0x4c56, 0x4456, 0x653d, 0xf446, + 0xf447, 0x6545, 0x653a, 0x433e, 0x653f, 0x303d, 0x4c4a, + /* 0x7DC0 */ + 0xf448, 0x7a2a, 0x653e, 0x365b, 0x486c, 0x7a2b, 0x416d, 0x4e50, + 0x3d6f, 0x656e, 0x7a2c, 0xf449, 0x6548, 0xf44a, 0x407e, 0x6544, + 0x6549, 0x654b, 0x4479, 0x654e, 0x7a2d, 0x654a, 0xf44b, 0x4a54, + 0x344b, 0x4c4b, 0x305e, 0xf44c, 0x654d, 0x4e7d, 0xf44d, 0x654c, + /* 0x7E00 */ + 0x316f, 0x466c, 0x654f, 0x7a30, 0x6556, 0x6550, 0x6557, 0xf451, + 0x7a31, 0x6553, 0x7a32, 0xf452, 0x477b, 0xf453, 0x3c4a, 0x6555, + 0xf454, 0x6552, 0x6558, 0x6551, 0x3d44, 0xf455, 0x7a2f, 0x4b25, + 0xf456, 0x3d4c, 0x6554, 0x6560, 0x655c, 0x655f, 0x655d, 0x6561, + 0x655b, 0x6541, 0x4053, + /* 0x7E40 */ + 0x484b, 0x655e, 0xf457, 0x6559, 0x7a34, 0x4121, 0x3752, 0x3d2b, + 0x7a35, 0x3f25, 0x4136, 0x6564, 0x6566, 0x6567, 0x6563, 0x6565, + 0x7a36, 0x655a, 0x6562, 0x656a, 0x6569, 0x7e7e, 0x4b7a, 0x372b, + 0xf458, 0xf459, 0x6568, 0x656c, 0x656b, 0x656f, 0xf45a, 0x6571, + /* 0x7E80 */ + 0x3b3c, 0x656d, 0xf45b, 0xf45c, 0x6572, 0x6573, 0x7a37, 0x6574, + 0x7a38, 0x657a, 0x453b, 0x6576, 0xf45e, 0x6575, 0x6577, 0x6578, + 0x6579, 0xf45f, 0xf460, 0x657b, 0x657c, + /* 0x7F00 */ + 0x344c, 0x657d, 0x657e, 0xf463, 0xf462, 0xf464, + /* 0x7F40 */ + 0xf465, 0xf466, 0x6621, 0x7a39, 0x6622, 0x6623, 0x6624, 0xf467, + 0x6625, 0x6626, 0xf46a, 0x6628, 0x6627, 0x6629, 0x662a, 0x662b, + 0xf46c, 0xf46d, 0xf46e, 0x662e, 0x662c, 0x662d, 0x3a61, 0x3753, + 0xf46f, 0x4356, 0x4833, 0x3d70, 0x474d, 0x486d, 0x662f, 0x586d, + 0xf470, 0xf471, + /* 0x7F80 */ + 0x6630, 0x6632, 0x4d65, 0x6631, 0x6634, 0x6633, 0x4d53, 0x6635, + 0x487e, 0xf473, 0x7a3b, 0x6636, 0xf476, 0x7a3c, 0x6639, 0xf477, + 0x6638, 0x6637, 0x663a, 0x3732, 0x4122, 0x3541, 0xf478, 0x663e, + 0x663b, 0x663c, 0x663f, 0x6640, 0x663d, 0x3129, 0x7a3d, + /* 0x7FC0 */ + 0x3227, 0xf47a, 0x6642, 0x6643, 0x6644, 0x4d62, 0x7a3e, 0xf47b, + 0x3d2c, 0x6646, 0x6645, 0x7a3f, 0x7a40, 0x3f69, 0x6647, 0xf47c, + 0xf47d, 0x6648, 0x6649, 0x3465, 0x7a41, 0x7a42, 0xf47e, 0x344d, + 0xf521, 0x664a, 0x664b, 0x7a43, 0x4b5d, 0x4d63, + /* 0x8000 */ + 0x4d54, 0x4f37, 0xf522, 0x394d, 0x664e, 0x3c54, 0x664d, 0xf524, + 0xf523, 0x664f, 0x3c29, 0xf525, 0x4251, 0xf526, 0x6650, 0x7a45, + 0x394c, 0xf527, 0x4c57, 0x6651, 0x6652, 0x6653, 0x6654, 0xf528, + 0x7a46, 0x6655, 0xf529, 0xf52a, 0x3c2a, 0x7a47, 0x4c6d, 0x7a48, + 0x6657, 0x7a49, 0x433f, 0x6656, + /* 0x8040 */ + 0xf52b, 0x6659, 0x6658, 0x665a, 0x403b, 0x665b, 0x665c, 0x4a39, + 0x665d, 0x416f, 0x665e, 0xf52c, 0x665f, 0x4e7e, 0x6662, 0xf52d, + 0x6661, 0x6660, 0x4430, 0xf52e, 0x6663, 0x3f26, 0x6664, 0xf52f, + 0x6665, 0x4f38, 0x6666, + /* 0x8080 */ + 0x6667, 0x6669, 0x6668, 0x4825, 0x4679, 0x4f3e, 0x4829, 0x666b, + 0x3e53, 0x492a, 0xf530, 0x666c, 0x666a, 0xf531, 0x344e, 0x3854, + 0x3b68, 0xf532, 0x486e, 0xf533, 0x382a, 0x4b43, 0x666f, 0x666d, + 0x394e, 0x394f, 0x3069, 0x3a68, 0xf534, 0x4759, + /* 0x80C0 */ + 0x305f, 0x6674, 0xf536, 0x4340, 0x7a4a, 0x4758, 0x425b, 0xf537, + 0x6676, 0x7a4b, 0xf538, 0x6672, 0x6675, 0x6670, 0x6673, 0x4b26, + 0x7a4c, 0x3855, 0x307d, 0x6671, 0xf539, 0x6678, 0x6679, 0x7a4d, + 0x4639, 0xf53c, 0x363b, 0xf53d, 0x6726, 0x473d, + /* 0x8100 */ + 0x3b69, 0x363c, 0x4048, 0x4f46, 0x4c2e, 0x6677, 0x4054, 0xf53b, + 0xf540, 0x7a4e, 0x3553, 0x667a, 0xf541, 0x667c, 0xf543, 0xf544, + 0x667b, 0xf545, 0x667d, 0x4326, 0x473e, 0xf53f, 0x4431, 0xf547, + 0x6723, + /* 0x8140 */ + 0x6722, 0x7a4f, 0x667e, 0x3f55, 0x4965, 0x6725, 0x6724, 0x3950, + 0x4f53, 0x6735, 0x7a50, 0x6729, 0x672a, 0x7a51, 0x7a52, 0xf549, + 0x3c70, 0x7a53, 0x6728, 0x3978, 0x6727, 0x672b, 0x4432, 0x4a22, + 0x4123, 0x425c, + /* 0x8180 */ + 0x672f, 0xf54b, 0x6730, 0x672c, 0xf54d, 0xf54e, 0x672d, 0x672e, + 0x3951, 0x6736, 0x6732, 0xf550, 0x4966, 0x4b6c, 0x4928, 0x6731, + 0x6734, 0x6733, 0x4b44, 0x6737, 0x6738, 0xf551, 0x4137, 0x6739, + 0x673b, 0x673f, 0x7a54, 0x673c, 0x673a, 0x473f, + /* 0x81C0 */ + 0x673d, 0xf552, 0x673e, 0xf553, 0x3232, 0x6745, 0x6740, 0x7a55, + 0x6741, 0x7a56, 0x6742, 0x4221, 0xf554, 0x7a57, 0x6744, 0x6743, + 0x6746, 0xf555, 0x6747, 0x6748, 0x3f43, 0xf557, 0x3269, 0x6749, + 0x4e57, 0x3c2b, 0xf559, 0x3d2d, 0x3b6a, 0x4357, 0x674a, 0x674b, + 0x3131, 0xf55b, 0x674c, 0xf55c, + /* 0x8200 */ + 0x674d, 0x674e, 0xf55e, 0x674f, 0x6750, 0x363d, 0x5a2a, 0x6751, + 0x4065, 0x6752, 0x3c4b, 0x6753, 0x5030, 0x6754, 0x4a5e, 0x345c, + 0xf560, 0x4124, 0x3d58, 0x4971, 0x3d2e, 0xf561, 0xf562, 0x6755, + 0x3952, 0x6756, 0x484c, 0x6764, 0xf564, 0x6758, 0xf565, 0x4249, + 0x4775, 0x383f, 0x6757, 0x4125, 0xf566, + /* 0x8240 */ + 0x6759, 0xf569, 0xf567, 0x447a, 0xf568, 0xf56b, 0xf56d, 0xf56f, + 0x675b, 0x675a, 0x675d, 0xf571, 0x675c, 0x675e, 0x7a5b, 0x6760, + 0xf572, 0x675f, 0x344f, 0x6761, 0x6762, 0x6763, 0x3a31, 0x4e49, + 0x6765, 0x3f27, 0x7a5c, 0x3170, 0x6766, 0x6767, 0xf576, 0xf578, + 0x6768, 0xf579, + /* 0x8280 */ + 0xf57a, 0xf57b, 0x3072, 0x6769, 0x7a5e, 0x676a, 0xf57c, 0x4967, + 0x3c47, 0x676c, 0x7a5f, 0x7a60, 0x7a61, 0x3329, 0x3032, 0xf57d, + 0xf57e, 0x7a62, 0x676b, 0x676e, 0x474e, 0x7a63, 0x3f44, 0x3256, + 0xf621, 0x4b27, 0xf622, 0x7a64, 0x375d, 0x365c, 0xf623, 0x676d, + 0xf624, 0x326a, 0x7a65, 0x7a66, + /* 0x82C0 */ + 0x3423, 0x7a67, 0x3171, 0x6772, 0x4e6a, 0x425d, 0x7a68, 0x4944, + 0x677e, 0x3257, 0x677c, 0x677a, 0x6771, 0x676f, 0xf625, 0x6770, + 0x3c63, 0x366c, 0x4377, 0xf626, 0x4651, 0x3151, 0x6774, 0x6773, + 0xf627, 0x6779, 0x6775, 0x6778, 0x7a69, 0x7a6a, + /* 0x8300 */ + 0x7a6b, 0x7a6c, 0x4c50, 0x6777, 0x3258, 0x337d, 0x677b, 0xf628, + 0xf629, 0x677d, 0xf62a, 0x3754, 0x6823, 0x682c, 0x682d, 0xf62c, + 0x302b, 0xf62d, 0x7a6e, 0x6834, 0x3071, 0x682b, 0x7a6f, 0x682a, + 0xf62e, 0x6825, 0x6824, 0x6822, 0x6821, 0x4363, 0x427b, 0x6827, + 0x7a70, 0xf62f, + /* 0x8340 */ + 0x6826, 0x7a71, 0xf630, 0x6829, 0x7a72, 0x4170, 0x3755, 0x3141, + 0x6828, 0x7a73, 0x3953, 0xf62b, 0x7a74, 0xf631, 0x4171, 0x7a6d, + 0xae4a, 0x683a, 0x683b, 0x3259, 0x322e, 0x6838, 0x7a75, 0xf633, + /* 0x8380 */ + 0x682e, 0x7a76, 0x6836, 0x683d, 0x6837, 0xf636, 0x6835, 0x7a77, + 0x6776, 0xf637, 0xf638, 0x6833, 0x7a78, 0x682f, 0xf639, 0xf63a, + 0x3450, 0x6831, 0x683c, 0x6832, 0x7a79, 0x683e, 0x7a7a, 0x6830, + 0x477c, 0x4d69, 0x6839, 0x684f, 0x7a7b, + /* 0x83C0 */ + 0x7a7c, 0x6847, 0x3f7b, 0x7a7d, 0xf63b, 0x3546, 0x365d, 0x6842, + 0x7a7e, 0xf63c, 0x7b21, 0x325b, 0xf63d, 0x3e54, 0x6845, 0x3a5a, + 0xf63e, 0x4551, 0x684a, 0x7b22, 0xf63f, 0x4a6e, 0x7b23, 0x6841, + 0x325a, 0x3856, 0x4929, 0x684b, 0x683f, 0x6848, 0xf640, 0x6852, + 0x6843, + /* 0x8400 */ + 0x7b24, 0x6844, 0x463a, 0x7b25, 0x6849, 0x7b26, 0x6846, 0x4b28, + 0x684c, 0x3060, 0xf641, 0xf642, 0x6840, 0xf643, 0xf645, 0x684e, + 0x684d, 0x476b, 0x6854, 0x685f, 0x337e, 0x6862, 0x6850, 0xf646, + 0x6855, 0x4d6e, + /* 0x8440 */ + 0x685e, 0x7b28, 0x4d55, 0xf647, 0x4e2a, 0xf648, 0xf649, 0xf64a, + 0x4378, 0xf64b, 0xf64c, 0x336b, 0xf64d, 0x7b29, 0x4972, 0x6864, + 0x4621, 0xf64f, 0x3031, 0x685d, 0x6859, 0x4172, 0x6853, 0x685b, + 0x6860, 0x7b2a, 0x472c, 0x7b2b, 0x302a, 0xf650, 0x6858, 0xf651, + 0x6861, 0x4978, 0xf652, + /* 0x8480 */ + 0xf653, 0x685c, 0x6857, 0x7b2c, 0x3e55, 0x3d2f, 0x3c2c, 0xf656, + 0x4c58, 0x4947, 0x7b2d, 0x6867, 0x6870, 0xf657, 0x685a, 0x7b2e, + 0x3377, 0x7b2f, 0x3e78, 0x6865, 0x7b30, 0x686a, 0x4173, 0xf658, + 0x6866, + /* 0x84C0 */ + 0x7b31, 0x686d, 0x7b32, 0x435f, 0x686e, 0x4d56, 0x6863, 0x3338, + 0x6869, 0xf65a, 0xf65b, 0x686c, 0x4c2c, 0xf65c, 0x686f, 0x6868, + 0x686b, 0xf655, 0xf65e, 0xf65f, 0x4b29, 0x4f21, 0xf660, 0xf661, + 0xf662, 0x6873, 0xf663, 0x687a, 0xf664, 0x6872, + /* 0x8500 */ + 0x3c43, 0x6851, 0xf665, 0x4a4e, 0x4c22, 0x6879, 0x6878, 0x6874, + 0x6875, 0x3136, 0xf666, 0x7b35, 0x6877, 0x6871, 0x7b36, 0xf667, + 0xf668, 0x4455, 0xf669, 0x6876, 0x307e, 0x7b37, 0x7b34, 0xf66a, + 0x4222, 0x4a43, 0xf66f, + /* 0x8540 */ + 0x687b, 0x6921, 0x4859, 0x687e, 0x3e56, 0x3c49, 0x6923, 0x363e, + 0xf66b, 0xf670, 0xf671, 0x6924, 0x4979, 0x687d, 0x7b38, 0x6856, + 0xf672, 0xf673, 0xf674, 0x687c, 0x7b39, 0x4f4f, 0x4622, 0x4973, + 0x692b, 0xf66c, 0x6931, 0x7b3c, 0xf676, 0xf677, 0x6932, 0xf678, + /* 0x8580 */ + 0x6925, 0xf679, 0x4776, 0xf67a, 0x692f, 0x6927, 0x6929, 0x7b3d, + 0x7b3e, 0x6933, 0x6928, 0xf67b, 0x692c, 0x3172, 0x4665, 0x692d, + 0x6930, 0xf67c, 0xf67d, 0x7b3f, 0x6926, 0x4126, 0x692a, 0x3b27, + 0x3f45, 0x3730, 0x4c74, 0x7b3b, 0x4c79, 0x3d72, 0x7b40, 0xf723, + 0x6937, 0x6935, 0xf724, + /* 0x85C0 */ + 0x4f4e, 0xf725, 0x6934, 0xf726, 0x7b41, 0x4d75, 0x7b42, 0x6936, + 0x6938, 0x6939, 0xf727, 0xf728, 0x693c, 0x693a, 0xf729, 0xf72a, + 0x4623, 0x693b, 0xf72b, 0x484d, 0x692e, 0x7b43, 0xf72c, 0x3d73, + 0x693d, 0x6942, 0x4174, 0x6941, 0x7b45, + /* 0x8600 */ + 0xf72d, 0x6922, 0x7b46, 0x7b47, 0x6943, 0x4149, 0x693e, 0x6940, + 0x7b48, 0xf72e, 0x7b44, 0x693f, 0x5d31, 0x5d22, 0x7b4a, 0x6945, + 0xf72f, 0xf730, 0x6944, 0xf731, 0xf732, 0x7b4b, 0x4d76, 0x623c, + 0x6946, 0x7b4c, 0xf734, 0xf735, 0x6947, + /* 0x8640 */ + 0xf737, 0x2f68, 0x6948, 0x3857, 0x3554, 0xf739, 0x694a, 0x515d, + 0xf73a, 0x7b4d, 0x3575, 0x7b4e, 0x4e3a, 0x3673, 0x694b, 0x7b50, + 0x694c, 0x436e, 0x7b52, 0xf73b, 0x694d, 0x7b53, 0xf73c, 0x467a, + 0xf73d, 0x303a, + /* 0x8680 */ + 0xf73e, 0xf73f, 0x3263, 0x6952, 0x6953, 0xf740, 0xf741, 0x694e, + 0x3b3d, 0x7b54, 0xf742, 0xf743, 0x694f, 0x4742, 0xf744, 0x6950, + 0x6951, 0x695b, 0x6955, 0x6958, 0xf746, 0xf747, 0x6954, 0x7b55, + /* 0x86C0 */ + 0xf748, 0xf749, 0x6956, 0x6957, 0x3c58, 0x6959, 0x4341, 0x3756, + 0x3342, 0xf74a, 0x695c, 0xf74b, 0xf74c, 0x333f, 0x6961, 0x695d, + 0x6960, 0xf74d, 0x483a, 0xf74e, 0x695e, 0x695f, 0x4948, 0x485a, + 0x6962, 0x427d, 0x696c, 0x7b56, 0x6968, 0x7b57, 0x7b58, 0x326b, + /* 0x8700 */ + 0x6966, 0x4b2a, 0x6967, 0xf750, 0x6964, 0xf751, 0x6965, 0x696a, + 0x696d, 0x7b59, 0x696b, 0xf752, 0xf753, 0x6969, 0x6963, 0xf754, + 0x4358, 0xf755, 0x6974, 0x4c2a, 0xf756, 0xf757, 0xf758, 0x6972, + 0x6973, 0xf759, 0x696e, 0x6970, 0xf75a, 0x6971, 0xf75b, 0x696f, + /* 0x8740 */ + 0xf75c, 0xf75d, 0x4066, 0x4f39, 0x6978, 0x6979, 0xf75e, 0x6a21, + 0x3f2a, 0x697b, 0xf75f, 0x697e, 0x6976, 0x6975, 0x6a22, 0xf760, + 0xf761, 0x325c, 0x697c, 0x6a23, 0x697d, 0x7b5a, 0xf762, 0x697a, + 0x4433, 0x6977, 0xf763, 0x4768, + /* 0x8780 */ + 0x6a27, 0x7b5b, 0x7b5c, 0xf767, 0xf768, 0x4d3b, 0xf769, 0x6a26, + 0xf76a, 0x6a25, 0xf766, 0x6a2e, 0x7b5d, 0x7b5e, 0x6a28, 0x6a30, + 0x7b5f, 0x4d66, 0x6a33, 0x6a2a, 0xf76d, + /* 0x87C0 */ + 0x6a2b, 0xf76f, 0x6a2f, 0x6a32, 0x6a31, 0x6a29, 0xf770, 0x6a2c, + 0x6a3d, 0x7b61, 0xf772, 0x6a36, 0xf774, 0xf775, 0xf776, 0xf777, + 0xf778, 0x7b62, 0xf779, 0x6a34, 0x6a35, 0xf771, 0x6a3a, 0x6a3b, + 0x332a, 0x3542, 0x6a39, + /* 0x8800 */ + 0xf77a, 0xf77b, 0x6a24, 0x7b63, 0x7b64, 0xf77c, 0x6a38, 0x6a3c, + 0x6a37, 0x7b65, 0x6a3e, 0xf77d, 0x7b66, 0x6a40, 0x6a3f, 0x7b67, + 0x6a42, 0x6a41, 0x695a, 0x6a46, 0xf77e, 0xf821, 0x6a43, 0xf822, + 0x6a44, 0x6a45, 0x6a47, 0xf823, + /* 0x8840 */ + 0x376c, 0x6a49, 0x6a48, 0x3d30, 0xf825, 0x3954, 0x5e27, 0x6a4a, + 0x3d51, 0x3339, 0xf826, 0x6a4b, 0x3152, 0x3e57, 0x6a4c, 0xf827, + 0x3955, 0x6a4d, 0x3061, 0xf828, 0x493d, 0xf82b, 0x6a4e, 0xf82d, + 0x3f6a, 0x6a55, 0x6a52, 0x436f, 0x6a53, 0x6a50, 0x365e, + /* 0x8880 */ + 0x6a4f, 0x6a56, 0x3736, 0x425e, 0x6a5c, 0x6a58, 0x4235, 0x6a57, + 0x7b68, 0x6a5a, 0x6a51, 0xf82e, 0x6a5b, 0x6a5d, 0x7b69, 0x486f, + 0x6a59, 0x6a5e, 0x6a60, 0x3853, 0x6a54, 0x3041, 0xf82f, 0xf830, + 0xf831, 0x6a5f, + /* 0x88C0 */ + 0xf832, 0x3a5b, 0x4e76, 0x6a61, 0x6a62, 0x4175, 0x7b6a, 0x7b6b, + 0x4e22, 0xf835, 0xf833, 0xf836, 0x6a63, 0x4d35, 0x6a64, 0x6a65, + 0xf837, 0x4a64, 0x6a66, 0x3a40, 0x4e23, 0x6a6b, 0xf838, 0xf839, + 0x6a6c, 0x3e58, 0x6a6a, 0x7b6d, 0x4d67, 0x6a67, 0x6a69, 0x403d, + 0x3f7e, + /* 0x8900 */ + 0xf83b, 0x6a68, 0x6a6d, 0x4a23, 0x6a6f, 0x6a6e, 0x336c, 0x4b2b, + 0x6a70, 0x7b70, 0x7b71, 0x7b72, 0x7b6e, 0x6a7c, 0x6a72, 0x6a73, + 0x7b73, 0x6a74, 0x6a75, 0x7b74, 0x7b75, 0x6a79, 0xf83d, 0x6a7a, + 0x7b76, 0x6a78, + /* 0x8940 */ + 0x7b77, 0x6a76, 0xf83f, 0x6a71, 0x6a77, 0xf840, 0xf841, 0x6a7b, + 0x7037, 0x3228, 0x6a7e, 0x365f, 0x6a7d, 0xf844, 0x6b22, 0x6b21, + 0x6b24, 0x6b23, 0x6b25, 0x3d31, 0x6b26, 0x6b27, 0x6b28, 0x403e, + /* 0x8980 */ + 0xf845, 0x4d57, 0x6b29, 0x4a24, 0x4746, 0x6b2a, 0xf846, 0x6b2b, + 0x382b, 0x352c, 0xf847, 0x6b2c, 0x7b78, 0x3b6b, 0x4741, 0x6b2d, + 0x3350, 0xf848, 0x6b2e, 0x6b30, 0x4d77, 0x6b2f, 0x3f46, 0x6b31, + 0x6b32, 0xf849, 0x6b33, 0x3451, 0xf84a, 0x6b34, 0x6b35, 0x6b36, + /* 0x89C0 */ + 0x6b37, 0x3351, 0x7b7a, 0xf84b, 0xf84c, 0x6b38, 0x6b39, 0x6b3a, + 0x3272, 0x7b7b, 0x3f28, 0x6b3b, 0xf84d, 0xf84f, 0xf850, 0x6b3c, + 0x7b7c, 0x6b3d, 0xf851, 0xf852, + /* 0x8A00 */ + 0x3840, 0x447b, 0x6b3e, 0x3757, 0x3f56, 0x6b41, 0x4624, 0x6b40, + 0xf854, 0x7b7d, 0x3731, 0xf855, 0x7b7e, 0x6b3f, 0x4277, 0x352d, + 0x6b42, 0x6b43, 0x3e59, 0xf857, 0x7c21, 0x376d, 0x6b44, 0x4b2c, + 0x405f, 0x3576, 0x4c75, 0x414a, 0xf858, 0x6b45, 0x7c22, 0x3f47, + 0x4370, 0x3e5a, 0xf859, + /* 0x8A40 */ + 0x6b46, 0xf85a, 0x6b49, 0x7c23, 0x6b4a, 0xf85b, 0x7c24, 0x3a3e, + 0x4242, 0x6b48, 0x3e5b, 0x493e, 0xf85c, 0x6b47, 0x7c25, 0x3b6c, + 0x3153, 0x7c26, 0x6b4e, 0x3758, 0x3b6e, 0x3b6d, 0x4f4d, 0x6b4d, + 0x6b4c, 0x4127, 0x354d, 0x4f43, 0x333a, 0x3e5c, 0x7c27, 0x7c28, + 0x6b4b, + /* 0x8A80 */ + 0x6b50, 0x6b51, 0x6b4f, 0x3858, 0x4d40, 0x3b6f, 0x4727, 0xf85e, + 0x6b54, 0x4040, 0x4342, 0x4d36, 0x6b57, 0x386c, 0x403f, 0x6b53, + 0x6b58, 0x386d, 0x6b55, 0x6b56, 0x7c29, 0x6b52, 0x4062, 0x4649, + 0xf85d, 0x432f, 0x325d, 0xf85f, 0x4870, 0x3543, 0xf860, 0x4434, + /* 0x8AC0 */ + 0x6b5b, 0x6b59, 0x434c, 0x4041, 0x3452, 0x6b5a, 0x3f5b, 0x7c2a, + 0x4e4a, 0x4f40, 0xf861, 0x6b5c, 0x6b67, 0x4435, 0x6b66, 0x7c2b, + 0x6b63, 0x6b6b, 0x6b64, 0x6b60, 0x447c, 0x6b5f, 0x6b5d, 0x4d21, + 0x3b70, 0x6b61, 0x6b5e, 0x7c2c, 0x7c2d, 0x6b65, 0x3d74, 0x3841, + 0xf862, 0x427a, + /* 0x8B00 */ + 0x4b45, 0x315a, 0x3062, 0x4625, 0xf865, 0x6b69, 0xf864, 0x6b68, + 0xf866, 0x4666, 0x6b6d, 0x6b62, 0x6b6c, 0x6b6e, 0x382c, 0x6b6a, + 0x3956, 0xf867, 0x3c55, 0xf868, 0x6b6f, 0x4d58, 0x6b72, 0x6b75, + 0x6b73, 0x4935, 0xf869, 0x6b70, 0x3660, 0x6b74, + /* 0x8B40 */ + 0x6b76, 0xf86a, 0x7c31, 0x6b7a, 0x6b77, 0x6b79, 0x6b78, 0xf86c, + 0x7c32, 0x6b7b, 0x3c31, 0x7c33, 0x6b7d, 0x6b7c, 0x4968, 0xf86d, + 0x6c21, 0x3759, 0x7c34, 0x6b7e, 0x6c22, 0x6c23, 0x3544, 0x6641, + 0x3e79, 0x6c24, 0xf86e, 0x386e, 0x6c25, 0xf86f, + /* 0x8B80 */ + 0x6c26, 0xf870, 0x3b3e, 0x5a4e, 0xf871, 0x6c27, 0x6c28, 0x3d32, + 0x6c29, 0x6c2a, 0xf872, 0xf873, 0x6c2b, 0x6c2c, 0x6c2d, 0xf874, + 0x7c35, 0xf875, + /* 0x8C00 */ + 0x432b, 0xf876, 0x6c2e, 0xf878, 0x6c30, + /* 0x8C40 */ + 0x6c2f, 0xf87b, 0x4626, 0xf87c, 0x6c31, 0x7c36, 0x4b2d, 0x6c32, + 0x6c33, 0xf87d, 0x6c34, 0xf87e, 0x6c35, 0xf921, 0x465a, 0x3e5d, + 0x6c36, 0x7c37, 0xf922, 0x396b, 0x502e, 0x6c37, 0xf923, 0xf924, + 0x6c38, 0x493f, 0x6c39, 0x6c41, + /* 0x8C80 */ + 0x6c3a, 0x6c3c, 0x6c3b, 0x6c3d, 0x4b46, 0x6c3e, 0x6c3f, 0xf927, + 0xf926, 0x6c40, 0x6c42, 0xf928, 0xf92a, 0x332d, 0x4467, 0x4969, + 0x3a62, 0x3957, 0xf92b, 0x494f, 0x325f, 0x484e, 0x6c45, 0x3453, + 0x4055, 0x6c44, 0x6c49, 0x4379, 0x4c63, 0x6c47, 0x6c48, 0x352e, + 0x6c4a, 0x4763, 0x425f, 0x4871, 0x453d, 0x6c46, 0x4b47, + /* 0x8CC0 */ + 0x326c, 0x6c4c, 0x4f28, 0x4442, 0x4f45, 0x3b71, 0x6c4b, 0x4231, + 0x6c5c, 0x4128, 0x4678, 0x4950, 0xf92d, 0xf92c, 0xf92e, 0x6c4f, + 0x3b3f, 0x3b72, 0x3e5e, 0x4765, 0x7c39, 0x382d, 0x6c4e, 0x6c4d, + 0x496a, 0x3c41, 0x4552, 0xf930, 0xf931, 0x7c3a, 0x7c3b, 0x6c51, + 0x6c52, 0x3958, 0x6c50, 0x7c3c, + /* 0x8D00 */ + 0x6c53, 0x6c54, 0x6c56, 0x4223, 0xf933, 0x6c55, 0x3466, 0x6c58, + 0xf934, 0x6c57, 0x6c59, 0x7c3e, 0x6c5b, 0x6c5d, 0x6c5e, 0x7c3f, + /* 0x8D40 */ + 0x4056, 0x3c4f, 0x6c5f, 0x3352, 0xf935, 0x6c60, 0x4176, 0x6c61, + 0x6c62, 0x496b, 0x352f, + /* 0x8D80 */ + 0x6c63, 0xf936, 0x4436, 0x315b, 0xf937, 0x6c64, 0x3c71, 0xf938, + 0x3f76, 0x7c40, 0x422d, 0x6c67, 0x6c66, + /* 0x8DC0 */ + 0x6c65, 0xf93a, 0xf93b, 0x6c6d, 0x6c6b, 0x7c41, 0x6c68, 0x7c42, + 0x6c6a, 0x7c43, 0xf93c, 0x6c69, 0x6c6c, 0x3577, 0x6c70, 0x4057, + 0x6c71, 0x3859, 0x6c6e, 0x6c6f, 0xf93d, 0x4f29, 0x4437, 0x4129, + 0x6c72, 0xf940, 0x6c75, + /* 0x8E00 */ + 0xf941, 0x6c73, 0x6c74, 0x4d59, 0xf93e, 0x4627, 0x6c78, 0xf943, + 0xf944, 0x6c76, 0x6c77, 0x6c79, 0x7c44, 0xf945, 0xf946, 0x7c45, + 0xf947, 0x6d29, 0x6c7c, 0x6c7d, 0x6c7b, 0xf94a, 0xf94b, 0x7c46, + /* 0x8E40 */ + 0x6c7a, 0x447d, 0x6d21, 0x6d25, 0x6d22, 0x6c7e, 0xf94c, 0x6d23, + 0x6d24, 0xf94d, 0x6d2b, 0x6d26, 0x4058, 0x6d28, 0xf94e, 0x6d2a, + 0x6d27, 0xf94f, 0xf950, 0xf951, 0x7c47, 0x6d2d, 0x3d33, 0x6d2c, + 0x7c48, 0x6d2e, + /* 0x8E80 */ + 0x6d2f, 0x6d32, 0x6d31, 0x6d30, 0x6d34, 0x6d33, 0x4c76, 0x6d36, + 0x6d35, 0x6d37, 0xf952, 0x6d38, 0xf953, 0x6d3a, 0x6d39, 0x3f48, + 0x6d3b, 0xf954, 0x366d, 0x6d3c, 0x6d3e, 0xf955, 0xf956, 0xf957, + 0xf958, 0x6d3f, + /* 0x8EC0 */ + 0x7c4a, 0x6d40, 0x6d3d, 0x6d41, 0x3c56, 0x6d42, 0x3530, 0x3733, + 0xf95a, 0x382e, 0xf95b, 0x6d43, 0x4670, 0x453e, 0x6d44, 0x6d47, + 0x3c34, 0xf95d, 0x7c4c, 0x6d46, 0x6d45, 0x375a, 0x6d48, + /* 0x8F00 */ + 0xf95f, 0x3353, 0x6d4a, 0xf960, 0x3a5c, 0x6d49, 0x6d52, 0x6d4c, + 0x6d4e, 0x4a65, 0x6d4b, 0xf961, 0x6d4d, 0x6d51, 0x6d4f, 0x3531, + 0x7c4d, 0x6d50, 0x6d53, 0x475a, 0x4e58, 0xf962, 0x7c4e, 0x3d34, + 0x6d54, 0x7c4f, 0x4d22, 0x6d56, 0x6d55, 0x6d59, 0x4d41, + /* 0x8F40 */ + 0xf963, 0x6d58, 0x336d, 0x6d57, 0x6d5c, 0x6d5b, 0xf964, 0x6d5a, + 0x4532, 0x6d5d, 0x7c50, 0x6d5e, 0xf965, 0x6d5f, 0x396c, 0x3725, + 0x6d60, 0x6d61, 0x6d62, + /* 0x8F80 */ + 0x3f49, 0x6d63, 0x3c2d, 0x6d64, 0x6d65, 0xf967, 0x7c52, 0x5221, + 0x517e, 0x6d66, 0x6570, 0x6d67, 0x4324, 0x3f2b, 0x4740, 0xf968, + 0x7c53, 0xf96a, 0x6d68, 0x4a55, 0x4454, 0x397e, 0x4329, + /* 0x8FC0 */ + 0xf96c, 0x312a, 0x4b78, 0x3f57, 0xf96d, 0xf96f, 0xf970, 0x375e, + 0x3661, 0xf971, 0x4a56, 0xf972, 0x6d69, 0xf973, 0x6d6b, 0x7c54, + 0x6d6a, 0x3260, 0x7c55, 0x4676, 0x6d6c, 0x4777, 0x4533, 0x7c56, + 0x6d6d, 0x3d52, 0xf974, 0x6d6f, 0xf975, 0x4c42, 0x6d7e, 0x6d71, + 0x6d72, 0xf976, 0x4449, + /* 0x9000 */ + 0x4260, 0x4177, 0xf977, 0x4628, 0x6d70, 0x3555, 0x7c57, 0x6d79, + 0xf978, 0x6d76, 0x6e25, 0x4629, 0x4360, 0x6d73, 0x447e, 0x4553, + 0x6d74, 0x6d78, 0x3f60, 0x4767, 0x444c, 0x4042, 0x6d77, 0x422e, + 0x4224, 0x6d75, 0x3029, 0x4f22, 0x6d7a, 0x7c58, 0x4261, 0x3d35, + 0x3f4a, 0x6d7c, 0x6d7b, 0xf979, 0x306f, 0x6d7d, 0x492f, 0x6e27, + /* 0x9040 */ + 0x465b, 0x3f6b, 0xf97b, 0xf97c, 0x4359, 0x3678, 0x6e26, 0x4d37, + 0x313f, 0x4a57, 0x3261, 0x6e21, 0x6e22, 0x6e23, 0x6e24, 0x463b, + 0x4323, 0x3063, 0x6e28, 0x6e29, 0x7423, 0x423d, 0xf97d, 0x6e2a, + 0x3173, 0x414c, 0x382f, 0x4d5a, 0x6e2b, 0x452c, 0x4178, 0x3c57, + 0x6e2c, 0x6e2f, 0x3d65, 0x6e2d, 0x412b, 0x412a, 0x3064, 0x4e4b, + 0x6e31, 0x4872, + /* 0x9080 */ + 0x6e33, 0x6e32, 0x6e30, 0x6364, 0x3454, 0xfa22, 0x6d6e, 0x7c5a, + 0x6e35, 0x6e34, 0xfa23, 0x6e36, 0xfa24, 0x4d38, 0x7c5b, 0x7c5c, + 0x7c5d, 0x7c5e, 0xfa26, 0x7c5f, 0x4661, 0x4b2e, 0x6e37, 0x3c59, + 0x6e38, 0xfa28, 0x6e39, 0x7c60, 0x6e3a, 0xfa29, 0x4521, 0x7c61, + /* 0x90C0 */ + 0x306a, 0xfa2a, 0x7c62, 0x7c63, 0x7c64, 0xfa2b, 0x3959, 0x4f3a, + 0x7c65, 0x6e3e, 0xfa2d, 0x7c66, 0x7c67, 0xfa2e, 0x3734, 0x6e3b, + 0x6e3c, 0x4974, 0xfa33, 0x3354, 0x7c68, 0xfa31, 0x7c69, 0x4d39, + 0xfa30, 0x363f, 0x4554, 0xfa34, 0xfa35, + /* 0x9100 */ + 0xfa32, 0x6e3f, 0xfa36, 0xfa37, 0x6e40, 0x7c6b, 0x7c6c, 0x7c6d, + 0xfa38, 0x6e41, 0xfa39, 0xfa3a, 0x7c6e, 0x7c6f, 0x7c70, 0x4522, + 0x7c71, 0x6e43, 0x7c72, 0x6e42, 0x7c73, 0xfa3b, 0xfa3c, 0xfa3d, + 0x7c74, + /* 0x9140 */ + 0xfa3e, 0xfa3f, 0x7c75, 0x4653, 0x6e44, 0x3d36, 0x3c60, 0x475b, + 0x4371, 0x3c72, 0x3f6c, 0x6e45, 0xfa40, 0x6e46, 0xfa41, 0x7c76, + 0xfa42, 0x3f5d, 0x6e47, 0xfa43, 0x6e48, 0x6e49, 0x4d6f, 0x3d37, + 0x6e4b, 0x6e4a, 0xfa44, 0x395a, 0x3973, 0x3b40, 0xfa45, + /* 0x9180 */ + 0x6e4e, 0x7c77, 0xfa46, 0x3d66, 0x6e4d, 0x6e4c, 0x4269, 0xfa47, + 0x386f, 0x4043, 0x4830, 0x3d39, 0x7c78, 0x6e4f, 0x3e5f, 0xfa48, + 0x6e52, 0x6e50, 0x7c79, 0xfa49, 0x6e51, 0x7c7a, 0xfa4a, 0x6e54, + 0x6e53, 0xfa4b, 0x3e7a, 0x6e55, 0x7c7b, + /* 0x91C0 */ + 0x6e56, 0x6e57, 0xfa4c, 0xfa4d, 0x4850, 0x3a53, 0x3c61, 0x6e58, + 0x6e59, 0x4e24, 0x3d45, 0x4c6e, 0x4e4c, 0x6e5a, 0x3662, 0x6e5b, + 0x7c7c, 0x4523, 0xfa4e, 0x6e5e, 0x3378, 0x3f4b, 0x6e5c, 0x6e5d, + 0x4460, 0x7c7e, 0x7d21, 0x4b55, 0x367c, 0xfa51, 0x7d22, 0xfa52, + 0x7d23, 0x6e60, 0x6e61, 0x7c7d, 0x6e5f, 0x6e63, + /* 0x9200 */ + 0xfa53, 0x7d24, 0xfa54, 0x465f, 0x3343, 0x7d25, 0x6e67, 0x6e64, + 0x6e66, 0xfa55, 0xfa56, 0x6e62, 0x6f4f, 0x6e65, 0xfa58, 0x4e6b, + 0x385a, 0x7d26, 0x7d27, 0x7d28, 0x7d29, 0x6e6f, + /* 0x9240 */ + 0x7d2a, 0xfa59, 0x7d2b, 0x4534, 0x6e6a, 0xfa5a, 0x6e6d, 0x6e6b, + 0xfa5b, 0x6e70, 0xfa5c, 0x7d2c, 0x6e71, 0xfa5d, 0xfa5e, 0x6e69, + 0xfa5f, 0x6e76, 0x3174, 0x6e68, 0xfa60, 0xfa61, 0x482d, 0x6e6c, + 0xfa62, 0x3e60, 0xfa63, 0xfa64, 0x395b, 0x7d2d, 0xfa67, 0xfa68, + 0x4b48, 0xfa69, + /* 0x9280 */ + 0x3664, 0x3d46, 0x463c, 0x7d2e, 0xfa6a, 0xfa6b, 0x412d, 0x6e74, + 0x6e6e, 0x6e73, 0xfa6c, 0x4c43, 0xfa6d, 0x4438, 0x6e75, 0x6e72, + 0xfa6e, 0xfa6f, 0xfa70, 0x412c, 0xfa73, 0x6e79, 0x6e78, 0xfa74, + /* 0x92C0 */ + 0xfa75, 0x7d2f, 0xfa76, 0x7d30, 0x7d31, 0xfa77, 0x6e77, 0xfa78, + 0x4b2f, 0x7d32, 0xfa79, 0xfa7a, 0x7d33, 0x3d7b, 0xfa7b, 0xfa7c, + 0x6e7a, 0x4a5f, 0x3154, 0x4946, 0x4372, 0xfb22, 0x3578, 0xfb23, + 0x6e7c, 0xfb24, 0x395d, 0x7d34, + /* 0x9300 */ + 0xfb25, 0x7d35, 0x3b2c, 0xfb26, 0x6e7b, 0x3f6d, 0xfa7d, 0xfb27, + 0x3f6e, 0x6f21, 0x6f23, 0xfb28, 0xfb29, 0x7d36, 0x3e7b, 0x7d37, + 0x6f22, 0x6f24, 0x7d38, 0x3653, 0xfb2a, 0x4945, 0xfb2b, 0x3c62, + 0x4f23, 0x6e7e, 0x3a78, 0x4f3f, 0x6f26, 0x6f25, 0x6f27, + /* 0x9340 */ + 0x6e7d, 0xfb2e, 0x7d39, 0x7d3a, 0x7d3b, 0x4669, 0x4555, 0xfb2f, + 0x4457, 0x6f2c, 0xfb30, 0xfb31, 0x4343, 0x6f28, 0x6f29, 0x7d3c, + 0x7d3d, 0x7d3e, 0xfb32, 0x372d, 0x6f2b, 0x7d3f, 0xfb33, 0xfb34, + 0x3830, 0x6f2a, 0x3e61, + /* 0x9380 */ + 0xfb38, 0xfb39, 0x3379, 0xfb3a, 0x6f30, 0x3a3f, 0x4179, 0x444a, + 0x7d40, 0xfb3b, 0xfb35, 0x7d41, 0x333b, 0x6f2e, 0x6f2f, 0x4443, + 0x6f2d, 0x6f31, 0x7d42, + /* 0x93C0 */ + 0xfb40, 0x6f37, 0x7d43, 0xfb41, 0x6f3a, 0x6f39, 0x452d, 0x6f32, + 0x6f33, 0x6f36, 0xfb42, 0x6f38, 0x7d44, 0x7d45, 0x3640, 0xfb43, + 0x6f3b, 0x6f35, 0xfb44, 0x6f34, 0xfb3f, 0xfb3c, 0xfb49, 0x7d47, + /* 0x9400 */ + 0x6f3f, 0x7d46, 0x6f40, 0xfb45, 0xfb46, 0x6f41, 0x6f3e, 0x6f3d, + 0xfb47, 0xfb48, 0x3e62, 0x462a, 0x6f3c, 0x6f45, 0x6f43, 0xfb4a, + 0x7d48, 0xfb4b, 0x6f44, 0x6f42, 0x4278, 0x6f46, 0xfb4c, + /* 0x9440 */ + 0x6f47, 0x6f49, 0xfb4d, 0x7d49, 0x3455, 0x6f48, 0x4c7a, 0x6f54, + 0x6f4a, 0x6f4d, 0x6f4b, 0x6f4c, 0x7d4a, 0x6f4e, 0x7d4b, 0xfb50, + 0xfb51, 0x6f50, 0x7d4c, 0x7d4d, 0x6f51, 0x6f52, 0x6f55, 0x6f53, + 0x6f56, 0x6f58, + /* 0x9480 */ + 0x6f57, + /* 0x9540 */ + 0x4439, 0xfb52, 0xfb53, + /* 0x9580 */ + 0x4c67, 0x6f59, 0x412e, 0xfb54, 0x6f5a, 0x4a44, 0x6f5b, 0x332b, + 0xfb55, 0xfb56, 0x7d4e, 0x313c, 0x3457, 0x3456, 0x6f5c, 0x6f5d, + 0x6f5e, 0x6f5f, 0x7d4f, 0x6f60, 0x3458, 0x3355, 0x395e, 0x4836, + 0x7d50, 0x6f62, 0x6f61, 0x7d51, 0xfb58, 0x7d52, 0x6f63, 0x315c, + 0xfb59, 0x7d53, 0x6f66, 0x6f65, 0x6f64, 0x7d54, 0x6f67, + /* 0x95C0 */ + 0x6f6a, 0x3047, 0xfb5b, 0x6f68, 0x7d55, 0x6f6c, 0x6f6b, 0x7d56, + 0x7d57, 0x6f6e, 0x6f6d, 0x6f6f, 0x462e, 0x7d59, 0x6f70, 0x7d5a, + 0x6f71, 0x6f73, 0x6f72, + /* 0x9600 */ + 0x496c, 0xfa25, 0x6f74, 0x6f75, 0x3a65, 0xfb5e, 0x6f76, 0x6f77, + 0x4b49, 0xfb5f, 0xfb60, 0x414b, 0xfb62, 0x3024, + /* 0x9640 */ + 0x424b, 0xfb63, 0x6f78, 0x496d, 0x6f7b, 0x6f79, 0x395f, 0x6f7a, + 0x3842, 0x7d5b, 0x4a45, 0x6f7d, 0x7021, 0x6f7e, 0x7022, 0xfb64, + 0x3121, 0x3f58, 0x3d7c, 0x3459, 0x7023, 0x4766, 0x7025, 0x3122, + 0x7024, 0x4444, 0x4e4d, 0x462b, 0x6f7c, 0x4e26, 0x3831, 0x4d5b, + /* 0x9680 */ + 0xfb66, 0x7d5c, 0x3679, 0x4e34, 0x3728, 0x4262, 0x6721, 0x7026, + 0x332c, 0x3f6f, 0x3356, 0x7028, 0x7029, 0x7027, 0x3764, 0xfb68, + 0x3a5d, 0x3e63, 0x7d5e, 0x3123, 0x4e59, 0x7d5f, 0x7d60, 0x702b, + 0x6e2e, 0xfb6b, 0x702a, 0xfb6c, 0x702e, 0x702c, 0x702d, 0xfb6d, + 0x702f, 0x7030, 0x4e6c, 0x7031, 0x7032, 0xfb6e, 0x4049, 0x483b, + 0xfb6f, + /* 0x96C0 */ + 0x3f7d, 0x3467, 0x4d3a, 0x326d, 0x3d38, 0x385b, 0x7035, 0x7034, + 0x3b73, 0x7036, 0x7033, 0x3b28, 0x7d61, 0x703a, 0x6a2d, 0xfb72, + 0x5256, 0xfb73, 0x3f77, 0x7038, 0xfb74, 0x7d62, 0x4e25, 0x4671, + 0x312b, 0x7d64, 0x4063, 0x3c36, 0x7d65, 0x4a37, 0x3140, 0x4e6d, + 0x4d6b, 0x703b, 0x4545, + /* 0x9700 */ + 0x3c7b, 0x703c, 0x703d, 0x3f4c, 0x703e, 0x4e6e, 0x7039, 0x7040, + 0x7042, 0x7041, 0x703f, 0xfb76, 0x7043, 0x7044, 0x417a, 0x3262, + 0xfb77, 0x7045, 0x4c38, 0x7046, 0x7047, 0x4f2a, 0x7d66, 0xfb79, + 0x5b31, 0x7048, 0x7d67, 0x7049, 0x704a, + /* 0x9740 */ + 0xfb7a, 0x704e, 0x704b, 0x704c, 0xfb7b, 0x704d, 0x704f, 0x7d68, + 0x7d69, 0x7d6a, 0x4044, 0xfb7c, 0x4c77, 0xfb7d, 0x4045, 0x7d6b, + 0xfb7e, 0x7050, 0x4873, 0x7051, 0x7353, 0x4c4c, 0x7052, 0x7053, + 0x7054, 0x3357, 0xfc21, 0x7056, 0x3f59, 0x7d6c, 0x7057, 0x7d6d, + 0x3724, 0x7058, 0x705c, 0x705a, + /* 0x9780 */ + 0x705b, 0x3373, 0x7059, 0x705d, 0x705e, 0x3048, 0x705f, 0x7060, + 0x7d6e, 0xfc24, 0x3e64, 0xfc25, 0x7061, 0xfc26, 0x3547, 0xfc27, + 0x7064, 0x7063, 0x7062, 0x6b71, 0x4a5c, 0x7d6f, 0xfc28, 0xfc29, + 0x7065, 0x7066, 0x7d70, 0xfc2a, + /* 0x97C0 */ + 0x7d71, 0x7067, 0x7068, 0x7069, 0x7d72, 0x706a, 0xfc2b, 0xfc2c, + 0x345a, 0xfc2d, 0xfc2e, 0xfc2f, 0x7d74, 0x706b, 0x7d73, 0xfc30, + 0x706c, 0x4723, 0xfc31, 0x706e, 0x323b, 0x7d75, 0x7071, 0x7070, + 0x3124, 0x3641, + /* 0x9800 */ + 0x4a47, 0x443a, 0x3a22, 0xfc32, 0x3960, 0x3d67, 0x3f5c, 0x7d77, + 0x7073, 0xfc33, 0xfc34, 0x7072, 0x4d42, 0x3468, 0x4852, 0x465c, + 0xfc35, 0xfc36, 0x3f7c, 0x4e4e, 0x375b, 0x7d78, 0x7076, 0xfc39, + 0x7075, 0xfc3c, 0x7d79, 0x4b4b, 0x462c, 0x7d7a, 0xfc3a, 0xfc3b, + 0x3150, 0x7077, 0x7074, 0x4951, 0x4d6a, 0x7078, + /* 0x9840 */ + 0x7079, 0xfc3d, 0x707b, 0x426a, 0x335b, 0x335c, 0x707a, 0x7d7c, + 0x7d7d, 0x3469, 0x3832, 0x7d7e, 0x7e21, 0x346a, 0x7e22, 0x7e23, + 0x453f, 0x4e60, 0x7e25, 0xfc3e, 0x385c, 0x707c, 0x7e26, 0x707d, + 0x707e, 0x7121, 0x7123, 0x7122, + /* 0x9880 */ + 0x4977, 0x7124, 0xfc3f, 0xfc40, 0x7125, 0xfc41, 0x7126, 0x7127, + 0xfc43, 0xfc44, 0x7e27, 0xfc45, 0xfc46, 0xfc47, + /* 0x98C0 */ + 0xfc48, 0x7129, 0x7128, 0x712a, 0xfc49, 0x7e28, 0xfc4a, 0x4874, + 0x664c, 0x3f29, 0xfc4b, 0xfc4d, 0x3532, 0xfc4e, 0xfc4f, 0x7e29, + 0x712b, 0xfc50, 0x712c, 0x522c, 0x5d3b, 0x4853, 0xfc51, 0xfc52, + 0x307b, 0xfc53, 0x303b, 0x3b74, 0x4b30, 0x3e7e, + /* 0x9900 */ + 0x712d, 0x4c5f, 0xfc54, 0x712e, 0x4d5c, 0x3142, 0x3b41, 0x712f, + 0x326e, 0x7130, 0xfc57, 0xfc58, 0x7131, 0xfc5a, 0xfc5b, 0xfc5c, + 0x7133, 0x7134, 0x7136, 0x7132, 0x7135, 0x345b, 0x7137, 0x7138, + 0xfc5e, 0xfc5f, 0xfc60, 0xfc61, 0xfc62, 0xfc63, 0x7139, 0x713a, + /* 0x9940 */ + 0xfc64, 0xfc65, 0x713b, 0x713d, 0xfc66, 0x713c, 0x713f, 0x7142, + 0xfc67, 0xfc68, 0x713e, 0x7140, 0x7141, 0x7143, 0x3642, 0x7e2a, + 0xfc69, 0xfc6a, 0xfc6b, + /* 0x9980 */ + 0x3c73, 0x7144, 0x7145, 0x3961, 0x7e2b, 0xfc6c, 0x7146, 0xfc6d, + 0x333e, 0x474f, 0x7147, 0x7148, 0x435a, 0x466b, 0xfc6e, 0x7149, + 0xfc6f, 0xfc70, + /* 0x99C0 */ + 0x477d, 0xfc71, 0x424c, 0x3158, 0x366e, 0x366f, 0xfc72, 0x4373, + 0x714e, 0x3670, 0xfc73, 0x326f, 0x714d, 0xfc74, 0x714b, 0x714c, + 0xfc75, 0x714a, 0x7158, 0x714f, 0x7150, 0xfc77, 0x7151, 0x7152, + 0x7154, 0xfc78, 0x7153, 0xfc79, 0x3d59, + /* 0x9A00 */ + 0x7155, 0x7e2c, 0x7e2d, 0x7157, 0xfc7a, 0x3533, 0x7156, 0xfc7b, + 0x417b, 0x3833, 0xfc7c, 0x7159, 0xfc7d, 0xfc7e, 0x7e2e, 0x424d, + 0x715a, 0x7e2f, 0x7e30, 0x462d, 0xfd21, 0xfd22, 0x715b, 0x7e31, + 0x7160, + /* 0x9A40 */ + 0x715e, 0x715d, 0x715f, 0xfd23, 0x715c, 0x7e32, 0xfd24, 0x7162, + 0x7e33, 0x7e34, 0x7161, 0x7164, 0xfd25, 0x3643, 0x7163, 0x7165, + 0x7166, 0x7168, 0x7167, 0x7169, 0x716b, 0x716a, + /* 0x9A80 */ + 0x397c, 0x716c, 0xfd27, 0x716d, 0x7e35, 0xfd29, 0x333c, 0xfd2b, + 0x716e, + /* 0x9AC0 */ + 0x716f, 0x7e36, 0x7e37, 0x3f71, 0xfd2d, 0x7e38, 0x7170, 0xfd2e, + 0x7171, 0xfd2f, 0x7172, 0x7173, 0xfd30, 0x7e39, 0x3962, 0xfd32, + 0x7174, 0x7175, 0xfd33, 0x7176, 0x7177, 0xfd34, 0x7178, 0xfd35, + 0x4831, 0x717a, 0x4926, 0x717b, 0x7179, 0x717d, 0x717c, 0x717e, + 0x7e3a, 0x7221, + /* 0x9B00 */ + 0x7e3b, 0xfd36, 0x7222, 0x7e3c, 0xfd37, 0xfd38, 0xfd39, 0xfd3a, + 0x7223, 0x7224, 0xfd3b, 0x7225, 0x7e3d, 0x7226, 0x7227, 0x7228, + 0x7229, 0x722a, 0x722b, 0x722c, 0xfd3c, 0x7e3f, 0x722d, 0x722e, + 0x5d35, 0x722f, 0xfd3d, 0x6478, 0x3534, 0xfd3e, + /* 0x9B40 */ + 0x3321, 0x3a32, 0x7231, 0x7230, 0x4c25, 0xfd40, 0x7233, 0x7234, + 0x7232, 0x7235, 0x4b62, 0x7236, 0x357b, 0x7e40, 0xfd41, 0xfd42, + 0x7e42, 0xfd43, 0xfd44, 0x4f25, 0x7e43, 0xfd45, 0x7237, 0x7e44, + 0xfd46, 0xfd47, 0x7e41, + /* 0x9B80 */ + 0x7239, 0x7e45, 0x7e46, 0x303e, 0x7e47, 0x723a, 0x4a2b, 0x7238, + 0x723b, 0x723c, 0x7e48, 0x723d, 0x723e, 0xfd48, 0x7e49, 0x723f, + 0x4b6e, 0x3b2d, 0xfd49, 0x3a7a, 0x412f, 0xfd4a, 0xfd4d, 0x7240, + 0xfd4e, 0x7243, 0xfd4f, + /* 0x9BC0 */ + 0x7241, 0x7e4a, 0x7244, 0xfd50, 0x3871, 0x7242, 0x7e4b, 0x7245, + 0x7246, 0x7247, 0x724b, 0x3b2a, 0xfd52, 0x4264, 0xfd53, 0x724c, + 0x7249, 0x7248, 0x724a, 0x7e4c, 0xfd54, 0x375f, 0xfd55, 0xfd56, + 0xfd58, 0xfd57, 0x7250, 0x724f, 0x724e, 0xfd51, 0x3033, 0xfd5c, + 0x7e4d, 0xfd5a, 0x7e4e, + /* 0x9C00 */ + 0x7e4f, 0x725a, 0x7256, 0x7257, 0x7253, 0x7259, 0x7255, 0x3362, + 0x4f4c, 0x7258, 0x7254, 0x7252, 0x7251, 0xfd5e, 0xfd5f, 0xfd60, + 0xfd61, 0x725c, 0xfd62, 0x725f, 0xfd63, 0x7e50, 0x725e, 0x725d, + 0xfd64, 0xfd65, 0xfd66, 0x4949, 0x725b, 0x3073, 0x7260, 0xfd68, + 0x7262, 0xfd69, 0xfd6a, 0x336f, 0x724d, 0x3137, 0x7264, + /* 0x9C40 */ + 0x7e51, 0xfd6b, 0x7263, 0x7261, 0x432d, 0xfd6e, 0xfd6f, 0x7e52, + 0x7e53, 0x4b70, 0x7e54, 0xfd71, 0x4e5a, 0xfd72, 0x7265, 0xfd73, + 0xfd6c, 0xfd74, 0xfd75, 0x7266, 0x7e55, 0x7e56, 0x7267, 0xfd76, + 0xfd77, 0xfd78, 0xfd79, 0xfd7a, 0xfd7b, 0xfd7c, 0xfd7d, 0x7268, + 0x7e57, 0x7269, 0xfd7e, + /* 0x9CC0 */ + 0x443b, 0xfe21, 0x726a, 0x4837, 0x726f, 0x726b, 0x726c, 0xfe22, + 0x4b31, 0x4c44, 0x4650, + /* 0x9D00 */ + 0xfe24, 0x7270, 0x7271, 0x463e, 0x726e, 0x726d, 0xfe23, 0x322a, + 0xfe26, 0x7279, 0x7278, 0xfe27, 0xfe28, 0x3175, 0x7e58, 0x7e59, + 0x7276, 0x7275, 0x7273, 0x337b, 0x7272, 0x3c32, 0x3229, 0xfe2c, + 0x3963, 0x727c, 0x727b, + /* 0x9D40 */ + 0x727a, 0xfe2e, 0x7e5a, 0x7277, 0x727d, 0x7e5b, 0x727e, 0xfe2f, + 0x7325, 0x7324, 0x7e5c, 0x7326, 0x312d, 0x7321, 0x7322, 0xfe30, + 0x3974, 0x4c39, 0xfe31, 0x7e5d, 0x7323, 0xfe33, 0xfe34, 0x4b32, + 0x732b, 0x7e5e, 0x7327, 0xfe36, 0xfe37, 0xfe38, 0x732c, 0x7e5f, + 0xfe39, + /* 0x9D80 */ + 0xfe3a, 0x7329, 0x7328, 0x7e60, 0xfe3b, 0x375c, 0x7e61, 0xfe3c, + 0x732d, 0xfe3d, 0x732e, 0x732f, 0x732a, 0x7e63, 0x7274, 0x7330, + 0x4461, 0xfe3f, 0x7334, 0xfe40, 0x7335, 0x7333, 0x7e64, 0xfe41, + 0xfe3e, + /* 0x9DC0 */ + 0x7e62, 0x7332, 0x7338, 0xfe42, 0x7331, 0x7336, 0xfe43, 0xfe44, + 0x7337, 0x733a, 0xfe45, 0x7e65, 0x7339, 0xfe46, 0xfe47, 0xfe48, + 0xfe49, 0x733c, 0x7e67, 0x733d, 0x733e, 0x4f49, 0xfe4a, 0x733b, + 0x426b, 0x3a6d, 0x733f, + /* 0x9E00 */ + 0xfe4d, 0x7e68, 0xfe4c, 0xfe4e, 0x7e69, 0xfe4f, 0x7340, 0x7341, + 0xfe50, 0xfe51, 0x7342, + /* 0x9E40 */ + 0x7343, 0x3834, 0x7344, 0xfe52, 0x7e6a, 0x7345, 0x3c2f, + /* 0x9E80 */ + 0xfe54, 0x7346, 0xfe55, 0x7347, 0x7348, 0x7349, 0x734c, 0x734a, + 0x4f3c, 0x734b, 0x4e6f, 0xfe56, 0x734d, 0x7e6b, 0x4e5b, 0x7e6c, + 0x734e, 0x477e, 0xfe57, 0x734f, 0x7351, 0x7e6d, 0x7352, 0x7e6e, + 0x7e6f, 0x7e70, 0x7350, 0x396d, 0x4c4d, 0x4b63, 0x5677, 0xfe59, + 0x5d60, 0x4b7b, + /* 0x9EC0 */ + 0x7e71, 0x322b, 0x7354, 0x3550, 0x7355, 0x7356, 0x7357, 0x7e72, + 0x3975, 0x7358, 0x6054, 0x4c5b, 0x4263, 0x7359, 0x735b, 0x735a, + 0xfe5b, 0x735c, 0x735d, 0xfe5c, 0x735e, 0xfe5d, 0x735f, 0x7360, + 0x7361, 0x7362, 0x7363, 0x7364, 0x7365, 0x7366, 0xfe5e, + /* 0x9F00 */ + 0xfe5f, 0xfe61, 0x7367, 0x7368, 0x4524, 0x7e73, 0x385d, 0x736a, + 0xfe62, 0xfe63, 0x414d, 0x736b, 0x736c, 0xfe64, 0xfe65, 0x7e74, + 0xfe66, 0x4921, 0xfe67, 0x736d, + /* 0x9F40 */ + 0xfe68, 0xfe69, 0xfe6a, 0x736e, 0x6337, 0x6c5a, 0x706d, 0x736f, + 0xfe6b, 0x7370, 0xfe6c, 0x7e75, 0xfe6d, 0xfe6f, 0x7372, 0x7373, + 0x7374, 0x4e70, 0x7371, 0x7375, 0x7376, 0xfe71, 0x7378, 0x7377, + 0xfe73, 0xfe74, 0x737a, 0xfe75, 0x737b, 0x7379, + /* 0x9F80 */ + 0x4e36, 0x7e76, 0x7e77, 0x737c, 0x7e78, 0x737d, 0x6354, 0x737e, + 0x7e79, + /* 0xF900 */ + 0x763b, 0x742e, 0x754e, 0x7b4f, + /* 0xF940 */ + 0x7649, + /* 0xF9C0 */ + 0x7e24, 0x7d5d, + /* 0xFA00 */ + 0x2f4b, 0x2f57, 0x4f72, 0xae79, 0x757a, 0x775a, 0x776f, 0x793c, + 0x793d, 0x7941, 0x7b3a, 0xf738, 0xf745, 0x7c2e, 0xf96e, 0x7c6a, + 0x2e38, 0x2e49, 0x2e50, 0x2e63, 0x2e68, 0x2e6e, 0x2f2c, 0x2f2f, + 0x2f36, 0x2f5a, 0x2f5e, 0x4f61, 0x4f62, 0x7450, 0x745c, 0x745e, + /* 0xFA40 */ + 0x7461, 0x7528, 0x752b, 0x7543, 0x7565, 0x7669, 0x7677, 0x7725, + 0x7755, 0xf029, 0x7825, 0x7927, 0x7933, 0x7934, 0x7937, 0x7938, + 0x7939, 0x793b, 0x793f, 0x7940, 0x794d, 0x7951, 0x7964, 0x7a2e, + 0xf450, 0x7a33, 0x7a3a, 0x7a44, 0x7a58, 0xf574, 0xf575, 0x7b27, + 0x7b6f, 0x7b79, 0x7c2f, 0x7c30, 0x7c38, 0x7c3d, 0xf969, 0x7c59, + 0x7d63, 0x7d76, 0x7d7b, + /* 0xFE40 */ + 0x233e, 0x233d, + /* 0xFF00 */ + 0x212a, 0x2230, 0x2174, 0x2170, 0x2173, 0x2175, 0x222f, 0x214a, + 0x214b, 0x2176, 0x215c, 0x2124, 0x2231, 0x2125, 0x213f, 0x2330, + 0x2331, 0x2332, 0x2333, 0x2334, 0x2335, 0x2336, 0x2337, 0x2338, + 0x2339, 0x2127, 0x2128, 0x2163, 0x2161, 0x2164, 0x2129, 0x2177, + 0x2341, 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, 0x2347, 0x2348, + 0x2349, 0x234a, 0x234b, 0x234c, 0x234d, 0x234e, 0x234f, 0x2350, + 0x2351, 0x2352, 0x2353, 0x2354, 0x2355, 0x2356, 0x2357, 0x2358, + 0x2359, 0x235a, 0x214e, 0x2140, 0x214f, 0x2130, 0x2132, + /* 0xFF40 */ + 0x212e, 0x2361, 0x2362, 0x2363, 0x2364, 0x2365, 0x2366, 0x2367, + 0x2368, 0x2369, 0x236a, 0x236b, 0x236c, 0x236d, 0x236e, 0x236f, + 0x2370, 0x2371, 0x2372, 0x2373, 0x2374, 0x2375, 0x2376, 0x2377, + 0x2378, 0x2379, 0x237a, 0x2150, 0x2143, 0x2151, 0x2232, 0x2256, + 0x2257, + /* 0xFFC0 */ + 0x2131, 0x216f, + /* 0x20000 */ + 0x2e22, + /* 0x20080 */ + 0xa121, 0xa12b, 0xa12e, + /* 0x20180 */ + 0xa136, + /* 0x20200 */ + 0xa146, + /* 0x20300 */ + 0xa170, + /* 0x20340 */ + 0xa179, + /* 0x20380 */ + 0xa177, + /* 0x203C0 */ + 0xa322, + /* 0x20440 */ + 0xa325, + /* 0x20500 */ + 0xa327, + /* 0x205C0 */ + 0xa331, + /* 0x20600 */ + 0xa332, + /* 0x20740 */ + 0xa338, + /* 0x20800 */ + 0xa33f, 0xa341, + /* 0x20880 */ + 0xa34a, + /* 0x20940 */ + 0xa352, + /* 0x20980 */ + 0xa353, + /* 0x20AC0 */ + 0xa359, + /* 0x20B00 */ + 0xa35c, + /* 0x20B80 */ + 0x4f54, + /* 0x20D40 */ + 0xa377, + /* 0x20DC0 */ + 0xa42a, + /* 0x20E40 */ + 0xa43a, 0xa432, + /* 0x20E80 */ + 0xa431, + /* 0x20F40 */ + 0xa43d, + /* 0x21200 */ + 0xa459, 0x2f42, + /* 0x21240 */ + 0xa45c, 0xa463, 0xa45e, + /* 0x212C0 */ + 0xa46b, 0xa46a, 0xa472, + /* 0x21300 */ + 0x2f4c, 0xa474, + /* 0x21340 */ + 0xa475, + /* 0x213C0 */ + 0xa525, + /* 0x21440 */ + 0xa532, 0x2f60, + /* 0x215C0 */ + 0xa53e, + /* 0x21640 */ + 0xa547, + /* 0x21680 */ + 0x4f63, + /* 0x21700 */ + 0xa555, + /* 0x21740 */ + 0xa556, + /* 0x21880 */ + 0x2f7b, + /* 0x219C0 */ + 0xa57e, + /* 0x21C40 */ + 0xa830, + /* 0x21D00 */ + 0xa837, + /* 0x21D40 */ + 0xa838, 0xa83b, 0xa83a, + /* 0x21D80 */ + 0xa845, 0xa840, 0xa83f, 0xa848, + /* 0x21DC0 */ + 0xa84a, + /* 0x21E00 */ + 0xa84b, 0x4f6e, + /* 0x21F00 */ + 0xa85b, + /* 0x21F40 */ + 0xa866, + /* 0x21FC0 */ + 0xa86c, + /* 0x22140 */ + 0xac22, + /* 0x22200 */ + 0xfe53, + /* 0x22300 */ + 0xac2b, + /* 0x22380 */ + 0xac30, + /* 0x226C0 */ + 0xac50, + /* 0x22840 */ + 0xac65, + /* 0x22880 */ + 0xac6d, + /* 0x22980 */ + 0xac72, + /* 0x22A80 */ + 0xad24, + /* 0x22B40 */ + 0xad32, 0xad29, 0xad2a, + /* 0x22B80 */ + 0xad35, + /* 0x22C00 */ + 0xad34, 0xad39, + /* 0x22DC0 */ + 0xad56, + /* 0x23180 */ + 0xae24, + /* 0x231C0 */ + 0xad7d, 0x753a, 0xae23, + /* 0x23340 */ + 0xae3a, + /* 0x233C0 */ + 0xae42, 0xae3d, 0xae3c, 0xae44, 0xae47, 0xae49, 0xae43, + /* 0x23440 */ + 0xae55, 0xae57, 0xae56, 0xae5b, + /* 0x234C0 */ + 0xae77, + /* 0x23540 */ + 0xae78, + /* 0x23580 */ + 0xaf2a, + /* 0x235C0 */ + 0x7572, + /* 0x23600 */ + 0xaf42, 0xaf3f, 0xaf43, + /* 0x23640 */ + 0xaf40, + /* 0x23700 */ + 0xaf59, 0xaf4e, 0x7629, + /* 0x23740 */ + 0x7632, 0xaf61, + /* 0x237C0 */ + 0xaf6a, 0xaf69, + /* 0x23800 */ + 0xaf70, 0xaf75, + /* 0x23A80 */ + 0xee23, + /* 0x23C40 */ + 0xee34, + /* 0x23CC0 */ + 0x7660, + /* 0x23D00 */ + 0xee49, 0xf475, + /* 0x23D40 */ + 0xee5c, + /* 0x23DC0 */ + 0xee60, 0xee5f, 0xee5e, + /* 0x23F40 */ + 0xef32, + /* 0x24080 */ + 0xef47, + /* 0x24100 */ + 0xef4d, + /* 0x241C0 */ + 0xef61, 0xef64, + /* 0x24380 */ + 0xf022, + /* 0x24600 */ + 0xf033, + /* 0x24680 */ + 0xf039, + /* 0x247C0 */ + 0x776c, + /* 0x24880 */ + 0xf053, + /* 0x24A40 */ + 0xf07b, + /* 0x24B40 */ + 0xf12e, 0xf130, + /* 0x24C00 */ + 0xf135, + /* 0x24D00 */ + 0xf144, + /* 0x24E00 */ + 0xf15d, 0xf161, + /* 0x24E40 */ + 0xf166, + /* 0x24E80 */ + 0xf169, + /* 0x25040 */ + 0xf175, 0xf177, + /* 0x25100 */ + 0xf17a, + /* 0x25180 */ + 0xf221, + /* 0x251C0 */ + 0xf224, 0xf223, + /* 0x25200 */ + 0xf228, + /* 0x25240 */ + 0xf22c, + /* 0x25400 */ + 0xf23d, + /* 0x25480 */ + 0x787e, + /* 0x254C0 */ + 0xf248, + /* 0x25500 */ + 0x7929, + /* 0x25580 */ + 0xf25b, + /* 0x25740 */ + 0x7947, + /* 0x25780 */ + 0xf275, 0xf276, + /* 0x259C0 */ + 0x7954, 0xf332, + /* 0x25AC0 */ + 0xf33e, 0xf33d, 0xf340, + /* 0x25B80 */ + 0xf352, + /* 0x25C40 */ + 0xf35d, 0xf35e, + /* 0x25D80 */ + 0x796e, + /* 0x25E00 */ + 0xf373, + /* 0x25E40 */ + 0xf374, 0xf377, 0xf375, + /* 0x25EC0 */ + 0xf37d, 0xf37b, 0xf422, + /* 0x25F00 */ + 0xf424, + /* 0x25F40 */ + 0xf427, + /* 0x25FC0 */ + 0xf42f, 0xf42e, 0xf435, + /* 0x26000 */ + 0xf434, 0xf43d, + /* 0x26040 */ + 0xf442, + /* 0x260C0 */ + 0xf44f, + /* 0x26240 */ + 0xf469, + /* 0x26280 */ + 0xf46b, + /* 0x26340 */ + 0xf472, + /* 0x26400 */ + 0xf479, + /* 0x26640 */ + 0xf535, + /* 0x26680 */ + 0xf53a, + /* 0x26700 */ + 0xf546, + /* 0x268C0 */ + 0xf556, 0xf558, + /* 0x26940 */ + 0xf55a, 0xf55d, + /* 0x269C0 */ + 0xf55f, + /* 0x26A00 */ + 0xf563, + /* 0x26A40 */ + 0xf56a, + /* 0x26A80 */ + 0xf570, 0xf573, + /* 0x26AC0 */ + 0x7a5d, + /* 0x26C00 */ + 0xa544, + /* 0x26C40 */ + 0xf644, + /* 0x26CC0 */ + 0xf64e, + /* 0x26E40 */ + 0x7b33, 0xf65d, + /* 0x26F80 */ + 0xf675, + /* 0x26FC0 */ + 0xf721, 0xf722, 0xf67e, + /* 0x270C0 */ + 0x7b49, + /* 0x27100 */ + 0xf733, 0xf736, + /* 0x273C0 */ + 0xf765, 0xf764, 0xf76b, + /* 0x27400 */ + 0xf76e, + /* 0x27440 */ + 0xf773, + /* 0x27600 */ + 0xf82a, 0xf829, 0xf82c, + /* 0x27680 */ + 0x7b6c, 0xf834, + /* 0x27700 */ + 0xf83c, 0xf83e, + /* 0x27740 */ + 0xf842, + /* 0x27980 */ + 0xf856, + /* 0x27A80 */ + 0xf863, + /* 0x27B80 */ + 0xf877, 0xf879, + /* 0x27BC0 */ + 0xf87a, + /* 0x27C80 */ + 0xf925, + /* 0x27D80 */ + 0xf92f, + /* 0x27E00 */ + 0xf932, + /* 0x27F80 */ + 0xf939, + /* 0x28080 */ + 0xf942, 0xf948, + /* 0x28240 */ + 0x7c49, + /* 0x28280 */ + 0xf959, + /* 0x282C0 */ + 0xf95e, + /* 0x283C0 */ + 0x7c51, + /* 0x28400 */ + 0xf966, + /* 0x28440 */ + 0xf96b, + /* 0x28540 */ + 0xf97a, + /* 0x285C0 */ + 0xf97e, 0xfa21, + /* 0x286C0 */ + 0xfa2c, 0xfa2f, + /* 0x28940 */ + 0xfa50, 0xfa4f, 0xfa57, + /* 0x28980 */ + 0xfa65, 0xfa66, 0xfa71, 0xfa72, + /* 0x28A00 */ + 0xfa7e, 0xfb21, + /* 0x28A40 */ + 0xfb2d, 0xfb2c, + /* 0x28A80 */ + 0xfb36, + /* 0x28AC0 */ + 0xfb37, 0xfb3e, 0xfb3d, + /* 0x28BC0 */ + 0xfb4e, 0xfb4f, + /* 0x28D00 */ + 0xfb57, + /* 0x28D40 */ + 0xfb5a, + /* 0x28DC0 */ + 0xfb5c, + /* 0x28E00 */ + 0xfb5d, 0xfb61, + /* 0x28E80 */ + 0xfb65, + /* 0x28EC0 */ + 0xfb67, + /* 0x28F00 */ + 0xfb69, + /* 0x28FC0 */ + 0xfb71, + /* 0x29280 */ + 0xfc22, 0xfc23, + /* 0x29480 */ + 0xfc38, + /* 0x295C0 */ + 0xfc42, + /* 0x29640 */ + 0xfc4c, + /* 0x296C0 */ + 0xfc56, + /* 0x29700 */ + 0xfc59, + /* 0x29740 */ + 0xfc5d, + /* 0x298C0 */ + 0xfc76, + /* 0x29A40 */ + 0xfd2c, + /* 0x29DC0 */ + 0xfd4b, + /* 0x29E00 */ + 0xfd59, 0xfd4c, + /* 0x29E40 */ + 0xfd5d, + /* 0x29E80 */ + 0xfd5b, + /* 0x29EC0 */ + 0xfd67, 0xfd70, 0xfd6d, + /* 0x29FC0 */ + 0xfe25, + /* 0x2A000 */ + 0xfe2b, 0xfe29, + /* 0x2A080 */ + 0xfe35, + /* 0x2A0C0 */ + 0xfe32, + /* 0x2A180 */ + 0x7e66, + /* 0x2A380 */ + 0xfe58, + /* 0x2A400 */ + 0xfe5a, + /* 0x2A5C0 */ + 0xfe6e, + /* 0x2A600 */ + 0xfe70, 0xfe72, + /* 0x2A680 */ + 0xfe76, +}; + +static const Summary16 jisx0213_from_ucs_level2_2indx[] = { + /* 0x0080 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0xffdf }, { 15, 0xffdf }, + /* 0x00C0 */ + { 30, 0xffff }, { 46, 0xffff }, { 62, 0xffff }, { 78, 0xffff }, + /* 0x0100 */ + { 94, 0xf3ff }, { 108, 0x3f0e }, { 117, 0x0cb0 }, { 122, 0x6630 }, + /* 0x0140 */ + { 128, 0x399e }, { 137, 0xff3f }, { 151, 0xfc3f }, { 163, 0x7e03 }, + /* 0x0180 */ + { 171, 0x0000 }, { 171, 0x0008 }, { 172, 0x0000 }, { 172, 0x0000 }, + /* 0x01C0 */ + { 172, 0x6004 }, { 175, 0x1557 }, { 183, 0x0000 }, { 183, 0x2300 }, + /* 0x0240 */ + { 186, 0x0000 }, { 186, 0xd7ff }, { 200, 0xf1f3 }, { 211, 0x6e2f }, + /* 0x0280 */ + { 221, 0x7f1e }, { 232, 0x2137 }, { 239, 0x0006 }, { 241, 0x0000 }, + /* 0x02C0 */ + { 241, 0x1180 }, { 244, 0x6b03 }, { 251, 0x03e0 }, { 256, 0x0000 }, + /* 0x0300 */ + { 256, 0x995f }, { 266, 0xf700 }, { 273, 0x9631 }, { 280, 0x3e11 }, + /* 0x0340 */ + { 287, 0x0000 }, { 287, 0x0000 }, { 287, 0x0002 }, { 288, 0x0000 }, + /* 0x0380 */ + { 288, 0x0000 }, { 288, 0xfffe }, { 303, 0x03fb }, { 312, 0xfffe }, + /* 0x03C0 */ + { 327, 0x03ff }, { 337, 0x0000 }, { 337, 0x0000 }, { 337, 0x0000 }, + /* 0x0400 */ + { 337, 0x0002 }, { 338, 0xffff }, { 354, 0xffff }, { 370, 0xffff }, + /* 0x0440 */ + { 386, 0xffff }, { 402, 0x0002 }, { 403, 0x0000 }, { 403, 0x0000 }, + /* 0x1E00 */ + { 403, 0x0000 }, { 403, 0x0000 }, { 403, 0x0000 }, { 403, 0xc000 }, + /* 0x1F40 */ + { 405, 0x0000 }, { 405, 0x0000 }, { 405, 0x0000 }, { 405, 0x000f }, + /* 0x2000 */ + { 409, 0x0000 }, { 409, 0x3359 }, { 417, 0x0067 }, { 422, 0x980d }, + /* 0x2040 */ + { 428, 0x0384 }, { 432, 0x0002 }, { 433, 0x0000 }, { 433, 0x0000 }, + /* 0x2080 */ + { 433, 0x0000 }, { 433, 0x0000 }, { 433, 0x1000 }, { 434, 0x0000 }, + /* 0x2100 */ + { 434, 0x8008 }, { 436, 0x0048 }, { 438, 0x0882 }, { 441, 0x0020 }, + /* 0x2140 */ + { 442, 0x0000 }, { 442, 0x0038 }, { 445, 0x0fff }, { 457, 0x0fff }, + /* 0x2180 */ + { 469, 0x0000 }, { 469, 0x03df }, { 478, 0x0000 }, { 478, 0x0000 }, + /* 0x21C0 */ + { 478, 0x0010 }, { 479, 0x0014 }, { 481, 0x03c0 }, { 485, 0x0000 }, + /* 0x2200 */ + { 485, 0x0bad }, { 493, 0xe40c }, { 499, 0x5fe1 }, { 509, 0x2030 }, + /* 0x2240 */ + { 512, 0x0128 }, { 515, 0x0004 }, { 516, 0x0cc7 }, { 523, 0x00c0 }, + /* 0x2280 */ + { 525, 0x0cfc }, { 533, 0x00e0 }, { 536, 0x0020 }, { 537, 0x8000 }, + /* 0x22C0 */ + { 538, 0x0000 }, { 538, 0x0c00 }, { 540, 0x0000 }, { 540, 0x0000 }, + /* 0x2300 */ + { 540, 0x0060 }, { 542, 0x0104 }, { 544, 0x0000 }, { 544, 0x0000 }, + /* 0x2380 */ + { 544, 0x0000 }, { 544, 0x0000 }, { 544, 0x0000 }, { 544, 0xc000 }, + /* 0x23C0 */ + { 546, 0x5fff }, { 560, 0x0000 }, { 560, 0x0000 }, { 560, 0x0000 }, + /* 0x2400 */ + { 560, 0x0000 }, { 560, 0x0000 }, { 560, 0x0008 }, { 561, 0x0000 }, + /* 0x2440 */ + { 561, 0x0000 }, { 561, 0x0000 }, { 561, 0xffff }, { 577, 0x000f }, + /* 0x24C0 */ + { 581, 0x0000 }, { 581, 0xffff }, { 597, 0xfbff }, { 612, 0x7fff }, + /* 0x2500 */ + { 627, 0x900f }, { 633, 0x3999 }, { 641, 0x9939 }, { 649, 0x9999 }, + /* 0x2540 */ + { 657, 0x0804 }, { 659, 0x0000 }, { 659, 0x0000 }, { 659, 0x0000 }, + /* 0x2580 */ + { 659, 0x0000 }, { 659, 0x0000 }, { 659, 0x0003 }, { 661, 0x30ce }, + /* 0x25C0 */ + { 668, 0xcac3 }, { 676, 0x000f }, { 680, 0x8040 }, { 682, 0x0000 }, + /* 0x2600 */ + { 682, 0x406f }, { 689, 0x40c0 }, { 692, 0x0000 }, { 692, 0x0000 }, + /* 0x2640 */ + { 692, 0x0005 }, { 694, 0x0000 }, { 694, 0xffff }, { 710, 0x0000 }, + /* 0x2700 */ + { 710, 0x0000 }, { 710, 0x0008 }, { 711, 0x0000 }, { 711, 0x0000 }, + /* 0x2740 */ + { 711, 0x0000 }, { 711, 0x0040 }, { 712, 0x0000 }, { 712, 0xffc0 }, + /* 0x2900 */ + { 722, 0x0000 }, { 722, 0x0000 }, { 722, 0x0000 }, { 722, 0x0030 }, + /* 0x2980 */ + { 724, 0x0000 }, { 724, 0x0000 }, { 724, 0x0000 }, { 724, 0x8000 }, + /* 0x29C0 */ + { 725, 0x0000 }, { 725, 0x0000 }, { 725, 0x0000 }, { 725, 0x0c00 }, + /* 0x3000 */ + { 727, 0xffef }, { 742, 0xb3ff }, { 755, 0x0001 }, { 756, 0x3838 }, + /* 0x3040 */ + { 762, 0xfffe }, { 777, 0xffff }, { 793, 0xffff }, { 809, 0xffff }, + /* 0x3080 */ + { 825, 0xffff }, { 841, 0xf87f }, { 853, 0xffff }, { 869, 0xffff }, + /* 0x30C0 */ + { 885, 0xffff }, { 901, 0xffff }, { 917, 0xffff }, { 933, 0xffff }, + /* 0x31C0 */ + { 949, 0x0000 }, { 949, 0x0000 }, { 949, 0x0000 }, { 949, 0xffff }, + /* 0x3200 */ + { 965, 0x0000 }, { 965, 0x0000 }, { 965, 0x0000 }, { 965, 0x0206 }, + /* 0x3240 */ + { 968, 0x0000 }, { 968, 0xfffe }, { 983, 0x0000 }, { 983, 0x0000 }, + /* 0x3280 */ + { 983, 0x0000 }, { 983, 0x0000 }, { 983, 0x01f0 }, { 988, 0xfffe }, + /* 0x32C0 */ + { 1003, 0x0000 }, { 1003, 0xffff }, { 1019, 0x322f }, { 1027, 0x0400 }, + /* 0x3300 */ + { 1028, 0x2008 }, { 1030, 0x0110 }, { 1032, 0x08cc }, { 1037, 0x0840 }, + /* 0x3340 */ + { 1039, 0x2600 }, { 1042, 0x0082 }, { 1044, 0x0000 }, { 1044, 0x7800 }, + /* 0x3380 */ + { 1048, 0xc000 }, { 1050, 0x7000 }, { 1053, 0x0002 }, { 1054, 0x0000 }, + /* 0x33C0 */ + { 1054, 0x2810 }, { 1057, 0x0000 }, { 1057, 0x0000 }, { 1057, 0x0000 }, + /* 0x3400 */ + { 1057, 0x0044 }, { 1059, 0x0000 }, { 1059, 0x5000 }, { 1061, 0x0000 }, + /* 0x3440 */ + { 1061, 0x0000 }, { 1061, 0x0000 }, { 1061, 0x0500 }, { 1063, 0x0000 }, + /* 0x3480 */ + { 1063, 0x0000 }, { 1063, 0x0004 }, { 1064, 0x0000 }, { 1064, 0x1020 }, + /* 0x34C0 */ + { 1066, 0x0082 }, { 1068, 0x0800 }, { 1069, 0x0000 }, { 1069, 0x0000 }, + /* 0x3500 */ + { 1069, 0x0000 }, { 1069, 0x8000 }, { 1070, 0x0000 }, { 1070, 0x0000 }, + /* 0x3540 */ + { 1070, 0x0000 }, { 1070, 0x6000 }, { 1072, 0x4008 }, { 1074, 0x0000 }, + /* 0x3580 */ + { 1074, 0x0000 }, { 1074, 0x0000 }, { 1074, 0x0140 }, { 1076, 0x0000 }, + /* 0x35C0 */ + { 1076, 0x0020 }, { 1077, 0x0400 }, { 1078, 0x0000 }, { 1078, 0x0010 }, + /* 0x3600 */ + { 1079, 0x0020 }, { 1080, 0x0000 }, { 1080, 0x0000 }, { 1080, 0x0000 }, + /* 0x3640 */ + { 1080, 0x0400 }, { 1081, 0x0000 }, { 1081, 0x0000 }, { 1081, 0x0000 }, + /* 0x3680 */ + { 1081, 0x0000 }, { 1081, 0x0242 }, { 1084, 0x0000 }, { 1084, 0x0000 }, + /* 0x36C0 */ + { 1084, 0x8000 }, { 1085, 0x0000 }, { 1085, 0x0000 }, { 1085, 0x0000 }, + /* 0x3740 */ + { 1085, 0x0000 }, { 1085, 0x0000 }, { 1085, 0x1806 }, { 1089, 0x0020 }, + /* 0x3780 */ + { 1090, 0x2000 }, { 1091, 0x0000 }, { 1091, 0x0000 }, { 1091, 0x0000 }, + /* 0x37C0 */ + { 1091, 0x0002 }, { 1092, 0x0000 }, { 1092, 0x0104 }, { 1094, 0x2010 }, + /* 0x3800 */ + { 1096, 0x0001 }, { 1097, 0x0000 }, { 1097, 0x8000 }, { 1098, 0x0040 }, + /* 0x3840 */ + { 1099, 0x0001 }, { 1100, 0x1000 }, { 1101, 0x0002 }, { 1102, 0x0000 }, + /* 0x38C0 */ + { 1102, 0x0000 }, { 1102, 0x0000 }, { 1102, 0x0000 }, { 1102, 0x0400 }, + /* 0x3900 */ + { 1103, 0x0000 }, { 1103, 0x0480 }, { 1105, 0x0000 }, { 1105, 0x0000 }, + /* 0x3940 */ + { 1105, 0x0000 }, { 1105, 0x0000 }, { 1105, 0x8000 }, { 1106, 0x0000 }, + /* 0x3A40 */ + { 1106, 0x0000 }, { 1106, 0x0000 }, { 1106, 0x4000 }, { 1107, 0x0008 }, + /* 0x3AC0 */ + { 1108, 0x0000 }, { 1108, 0x00c0 }, { 1110, 0x0400 }, { 1111, 0x0000 }, + /* 0x3B00 */ + { 1111, 0x4000 }, { 1112, 0x1400 }, { 1114, 0x0004 }, { 1115, 0x0000 }, + /* 0x3B40 */ + { 1115, 0x0000 }, { 1115, 0x0000 }, { 1115, 0x2000 }, { 1116, 0x0080 }, + /* 0x3B80 */ + { 1117, 0x2180 }, { 1120, 0x0000 }, { 1120, 0x0010 }, { 1121, 0x0040 }, + /* 0x3BC0 */ + { 1122, 0x2008 }, { 1124, 0x0000 }, { 1124, 0x0000 }, { 1124, 0x0001 }, + /* 0x3C00 */ + { 1125, 0x8000 }, { 1126, 0x0000 }, { 1126, 0x0040 }, { 1127, 0x0000 }, + /* 0x3CC0 */ + { 1127, 0x0008 }, { 1128, 0x0004 }, { 1129, 0x0000 }, { 1129, 0x0000 }, + /* 0x3D00 */ + { 1129, 0x0000 }, { 1129, 0x4002 }, { 1131, 0x0000 }, { 1131, 0x0000 }, + /* 0x3D40 */ + { 1131, 0x0000 }, { 1131, 0x0000 }, { 1131, 0x0010 }, { 1132, 0x0000 }, + /* 0x3D80 */ + { 1132, 0x0000 }, { 1132, 0x0400 }, { 1133, 0x0000 }, { 1133, 0x0000 }, + /* 0x3DC0 */ + { 1133, 0x0001 }, { 1134, 0x0010 }, { 1135, 0x0000 }, { 1135, 0x0000 }, + /* 0x3E00 */ + { 1135, 0x0020 }, { 1136, 0x0000 }, { 1136, 0x0000 }, { 1136, 0x8000 }, + /* 0x3E40 */ + { 1137, 0x0000 }, { 1137, 0x0000 }, { 1137, 0x0141 }, { 1140, 0x0000 }, + /* 0x3E80 */ + { 1140, 0x0008 }, { 1141, 0x0010 }, { 1142, 0x0000 }, { 1142, 0x0000 }, + /* 0x3F40 */ + { 1142, 0x0000 }, { 1142, 0x0080 }, { 1143, 0x0000 }, { 1143, 0x00a4 }, + /* 0x3F80 */ + { 1146, 0x0000 }, { 1146, 0x0000 }, { 1146, 0x4000 }, { 1147, 0x0000 }, + /* 0x3FC0 */ + { 1147, 0x0200 }, { 1148, 0x0080 }, { 1149, 0x0000 }, { 1149, 0x0000 }, + /* 0x4000 */ + { 1149, 0x0000 }, { 1149, 0x0000 }, { 1149, 0x0000 }, { 1149, 0x0200 }, + /* 0x4040 */ + { 1150, 0x0000 }, { 1150, 0x0100 }, { 1151, 0x0000 }, { 1151, 0x0000 }, + /* 0x4080 */ + { 1151, 0x0000 }, { 1151, 0x0008 }, { 1152, 0x0000 }, { 1152, 0x0000 }, + /* 0x4100 */ + { 1152, 0x0020 }, { 1153, 0x0000 }, { 1153, 0x0000 }, { 1153, 0x0000 }, + /* 0x4140 */ + { 1153, 0x8100 }, { 1155, 0x0000 }, { 1155, 0x0008 }, { 1156, 0x0000 }, + /* 0x4180 */ + { 1156, 0x0000 }, { 1156, 0x0000 }, { 1156, 0x0000 }, { 1156, 0x8010 }, + /* 0x41C0 */ + { 1158, 0x0000 }, { 1158, 0x0000 }, { 1158, 0x4040 }, { 1160, 0x0008 }, + /* 0x4200 */ + { 1161, 0x4080 }, { 1163, 0x0000 }, { 1163, 0x0000 }, { 1163, 0x0000 }, + /* 0x4240 */ + { 1163, 0x0000 }, { 1163, 0x0000 }, { 1163, 0x0010 }, { 1164, 0x0000 }, + /* 0x42C0 */ + { 1164, 0x0040 }, { 1165, 0x2040 }, { 1167, 0x0000 }, { 1167, 0x0000 }, + /* 0x4300 */ + { 1167, 0x0004 }, { 1168, 0x0000 }, { 1168, 0x0800 }, { 1169, 0x0000 }, + /* 0x4340 */ + { 1169, 0x0008 }, { 1170, 0x0000 }, { 1170, 0x0000 }, { 1170, 0x0000 }, + /* 0x43C0 */ + { 1170, 0x0000 }, { 1170, 0x0000 }, { 1170, 0x4000 }, { 1171, 0x0001 }, + /* 0x4400 */ + { 1172, 0x0100 }, { 1173, 0x1080 }, { 1175, 0x0004 }, { 1176, 0x0000 }, + /* 0x4440 */ + { 1176, 0x0000 }, { 1176, 0x0808 }, { 1178, 0x0000 }, { 1178, 0x0440 }, + /* 0x4480 */ + { 1180, 0x0000 }, { 1180, 0x0002 }, { 1181, 0x0000 }, { 1181, 0x4008 }, + /* 0x44C0 */ + { 1183, 0x0000 }, { 1183, 0x0010 }, { 1184, 0x0000 }, { 1184, 0x0000 }, + /* 0x4500 */ + { 1184, 0x2100 }, { 1186, 0x0000 }, { 1186, 0x0020 }, { 1187, 0x0000 }, + /* 0x4540 */ + { 1187, 0x0008 }, { 1188, 0x0000 }, { 1188, 0x0000 }, { 1188, 0x0000 }, + /* 0x4580 */ + { 1188, 0x0000 }, { 1188, 0x2000 }, { 1189, 0x0000 }, { 1189, 0x0100 }, + /* 0x45C0 */ + { 1190, 0x0000 }, { 1190, 0x0000 }, { 1190, 0x0420 }, { 1192, 0x0000 }, + /* 0x4600 */ + { 1192, 0x8000 }, { 1193, 0x0000 }, { 1193, 0x0000 }, { 1193, 0x0000 }, + /* 0x4640 */ + { 1193, 0x0002 }, { 1194, 0x0000 }, { 1194, 0x0020 }, { 1195, 0x0000 }, + /* 0x4680 */ + { 1195, 0x0000 }, { 1195, 0x0000 }, { 1195, 0x8002 }, { 1197, 0x0000 }, + /* 0x4700 */ + { 1197, 0x1000 }, { 1198, 0x0000 }, { 1198, 0x0000 }, { 1198, 0x0000 }, + /* 0x4740 */ + { 1198, 0x0000 }, { 1198, 0x0000 }, { 1198, 0x0010 }, { 1199, 0x0000 }, + /* 0x47C0 */ + { 1199, 0x0000 }, { 1199, 0x0000 }, { 1199, 0x0000 }, { 1199, 0x2000 }, + /* 0x4800 */ + { 1200, 0x0000 }, { 1200, 0x0040 }, { 1201, 0x0000 }, { 1201, 0x0000 }, + /* 0x4840 */ + { 1201, 0x4010 }, { 1203, 0x0000 }, { 1203, 0x0000 }, { 1203, 0x0000 }, + /* 0x4880 */ + { 1203, 0x0000 }, { 1203, 0x0000 }, { 1203, 0x0000 }, { 1203, 0x0020 }, + /* 0x4980 */ + { 1204, 0x0000 }, { 1204, 0x0000 }, { 1204, 0x0000 }, { 1204, 0x0001 }, + /* 0x49C0 */ + { 1205, 0x0000 }, { 1205, 0x0000 }, { 1205, 0x0080 }, { 1206, 0x0400 }, + /* 0x4A00 */ + { 1207, 0x0010 }, { 1208, 0x0000 }, { 1208, 0x0200 }, { 1209, 0x0000 }, + /* 0x4A80 */ + { 1209, 0x0000 }, { 1209, 0x0000 }, { 1209, 0x0000 }, { 1209, 0x1000 }, + /* 0x4B00 */ + { 1210, 0x0000 }, { 1210, 0x0000 }, { 1210, 0x0000 }, { 1210, 0x0800 }, + /* 0x4BC0 */ + { 1211, 0x0404 }, { 1213, 0x0004 }, { 1214, 0x0100 }, { 1215, 0x0000 }, + /* 0x4C00 */ + { 1215, 0x0000 }, { 1215, 0x0080 }, { 1216, 0x0001 }, { 1217, 0x0000 }, + /* 0x4CC0 */ + { 1217, 0x0010 }, { 1218, 0x0002 }, { 1219, 0x0000 }, { 1219, 0x0000 }, + /* 0x4D00 */ + { 1219, 0x0080 }, { 1220, 0x0000 }, { 1220, 0x0000 }, { 1220, 0x0000 }, + /* 0x4D40 */ + { 1220, 0x0000 }, { 1220, 0x0000 }, { 1220, 0x0000 }, { 1220, 0x0080 }, + /* 0x4E00 */ + { 1221, 0xef8f }, { 1233, 0x43f7 }, { 1243, 0xff42 }, { 1253, 0x9b47 }, + /* 0x4E40 */ + { 1262, 0xe9ad }, { 1272, 0xe7e2 }, { 1282, 0x0204 }, { 1284, 0x400a }, + /* 0x4E80 */ + { 1287, 0x7f65 }, { 1298, 0xfb36 }, { 1309, 0x7977 }, { 1320, 0x1e49 }, + /* 0x4EC0 */ + { 1327, 0xeddf }, { 1340, 0xe7f1 }, { 1351, 0x683a }, { 1358, 0xa8e7 }, + /* 0x4F00 */ + { 1367, 0xee0b }, { 1376, 0x3443 }, { 1382, 0x8000 }, { 1383, 0x75d1 }, + /* 0x4F40 */ + { 1392, 0xe3c8 }, { 1400, 0xfffb }, { 1415, 0x9611 }, { 1421, 0xfde9 }, + /* 0x4F80 */ + { 1433, 0xad6c }, { 1442, 0x2dd6 }, { 1451, 0xe803 }, { 1457, 0xc064 }, + /* 0x4FC0 */ + { 1462, 0xce3c }, { 1471, 0xad97 }, { 1481, 0xc07b }, { 1489, 0x456e }, + /* 0x5000 */ + { 1497, 0xea67 }, { 1507, 0xd75f }, { 1519, 0x7ffe }, { 1533, 0x0a40 }, + /* 0x5040 */ + { 1536, 0xc3cf }, { 1546, 0x14e9 }, { 1553, 0x1468 }, { 1558, 0x2175 }, + /* 0x5080 */ + { 1565, 0x2121 }, { 1569, 0x177e }, { 1579, 0x3408 }, { 1583, 0x4cbe }, + /* 0x50C0 */ + { 1592, 0xf6b4 }, { 1602, 0x4673 }, { 1610, 0x62ea }, { 1618, 0x0a2c }, + /* 0x5100 */ + { 1623, 0x0b5f }, { 1632, 0xcdf4 }, { 1642, 0x0402 }, { 1644, 0x9ca4 }, + /* 0x5140 */ + { 1651, 0x7ffb }, { 1665, 0x14b5 }, { 1672, 0x7f25 }, { 1682, 0x19ea }, + /* 0x5180 */ + { 1690, 0xbe6d }, { 1701, 0x23ef }, { 1711, 0x3f7d }, { 1723, 0x30ff }, + /* 0x51C0 */ + { 1733, 0x3e78 }, { 1742, 0x7840 }, { 1747, 0x66c7 }, { 1756, 0x677b }, + /* 0x5200 */ + { 1767, 0x4ddf }, { 1778, 0x20fe }, { 1786, 0x46b0 }, { 1792, 0x0fc9 }, + /* 0x5240 */ + { 1800, 0xbe98 }, { 1809, 0x78f0 }, { 1817, 0x963a }, { 1825, 0xa0bf }, + /* 0x5280 */ + { 1834, 0x239c }, { 1841, 0x891e }, { 1848, 0xbe59 }, { 1858, 0x5e32 }, + /* 0x52C0 */ + { 1866, 0x37aa }, { 1875, 0xebe7 }, { 1887, 0x00dd }, { 1893, 0xcfad }, + /* 0x5300 */ + { 1904, 0xade7 }, { 1915, 0x36e1 }, { 1923, 0x841b }, { 1929, 0xcf2a }, + /* 0x5340 */ + { 1938, 0x27ef }, { 1949, 0x559e }, { 1958, 0xd2cb }, { 1967, 0xadbb }, + /* 0x5380 */ + { 1978, 0x0014 }, { 1980, 0xa548 }, { 1986, 0x6371 }, { 1994, 0x08dd }, + /* 0x53C0 */ + { 2001, 0x7f0d }, { 2011, 0x8ef0 }, { 2019, 0xff3e }, { 2032, 0x05ff }, + /* 0x5400 */ + { 2042, 0xff1a }, { 2053, 0xe807 }, { 2060, 0x7bd1 }, { 2070, 0x7b40 }, + /* 0x5440 */ + { 2077, 0x674d }, { 2086, 0x8022 }, { 2089, 0x1d44 }, { 2095, 0xb8fb }, + /* 0x5480 */ + { 2106, 0xfd51 }, { 2116, 0x1065 }, { 2121, 0xfb77 }, { 2134, 0xf58c }, + /* 0x54C0 */ + { 2143, 0x03df }, { 2152, 0x0100 }, { 2153, 0xf366 }, { 2163, 0xa40e }, + /* 0x5500 */ + { 2169, 0xc2d3 }, { 2177, 0x0051 }, { 2180, 0xc800 }, { 2183, 0x532a }, + /* 0x5540 */ + { 2190, 0x94f3 }, { 2199, 0x70c9 }, { 2206, 0x001b }, { 2210, 0x7800 }, + /* 0x5580 */ + { 2214, 0x4fdf }, { 2226, 0xf702 }, { 2234, 0x7f80 }, { 2242, 0x8041 }, + /* 0x55C0 */ + { 2245, 0x52b0 }, { 2251, 0xb416 }, { 2258, 0x021c }, { 2262, 0x6280 }, + /* 0x5600 */ + { 2266, 0x43c0 }, { 2271, 0x09d1 }, { 2277, 0x8300 }, { 2280, 0xa9d7 }, + /* 0x5640 */ + { 2290, 0x5285 }, { 2296, 0x4809 }, { 2300, 0xbd51 }, { 2309, 0x0556 }, + /* 0x5680 */ + { 2315, 0x95c1 }, { 2322, 0x6630 }, { 2328, 0x7325 }, { 2336, 0x105c }, + /* 0x56C0 */ + { 2341, 0x672f }, { 2351, 0xcd8a }, { 2359, 0x4109 }, { 2363, 0xa6cd }, + /* 0x5700 */ + { 2372, 0xaf19 }, { 2381, 0x916c }, { 2388, 0xa3ca }, { 2396, 0x0999 }, + /* 0x5740 */ + { 2402, 0xf4e5 }, { 2412, 0x0003 }, { 2414, 0x8752 }, { 2421, 0x98b9 }, + /* 0x5780 */ + { 2429, 0x0b04 }, { 2433, 0x7408 }, { 2438, 0x151d }, { 2445, 0x0109 }, + /* 0x57C0 */ + { 2448, 0xd9c9 }, { 2457, 0xd0dc }, { 2465, 0x2059 }, { 2470, 0xbff1 }, + /* 0x5800 */ + { 2482, 0x0e75 }, { 2490, 0x6220 }, { 2494, 0x8493 }, { 2500, 0x2637 }, + /* 0x5840 */ + { 2508, 0x1e03 }, { 2514, 0x4796 }, { 2522, 0x0a96 }, { 2528, 0x5225 }, + /* 0x5880 */ + { 2534, 0xae28 }, { 2541, 0xf099 }, { 2549, 0x4f00 }, { 2554, 0x4f0a }, + /* 0x58C0 */ + { 2561, 0x74aa }, { 2569, 0xd7be }, { 2581, 0xda35 }, { 2590, 0x3e9f }, + /* 0x5900 */ + { 2601, 0xbe64 }, { 2610, 0x1f71 }, { 2619, 0x7eb4 }, { 2629, 0x6186 }, + /* 0x5940 */ + { 2635, 0xc3d0 }, { 2642, 0xadb3 }, { 2652, 0x77a5 }, { 2662, 0x3178 }, + /* 0x5980 */ + { 2669, 0x2c1e }, { 2676, 0xaa4c }, { 2683, 0x5138 }, { 2689, 0x5a04 }, + /* 0x59C0 */ + { 2694, 0x2b48 }, { 2700, 0x761f }, { 2710, 0x4df8 }, { 2719, 0x8940 }, + /* 0x5A00 */ + { 2723, 0x320a }, { 2728, 0x958a }, { 2735, 0xa2a9 }, { 2742, 0x1060 }, + /* 0x5A40 */ + { 2745, 0x0243 }, { 2749, 0x0420 }, { 2751, 0x34e4 }, { 2758, 0xc480 }, + /* 0x5A80 */ + { 2762, 0x0810 }, { 2764, 0xdc04 }, { 2770, 0x0085 }, { 2773, 0xf42a }, + /* 0x5AC0 */ + { 2781, 0x1a16 }, { 2787, 0x14c1 }, { 2792, 0x426b }, { 2799, 0x0c21 }, + /* 0x5B00 */ + { 2803, 0x1b01 }, { 2808, 0x02c0 }, { 2811, 0x3424 }, { 2816, 0x4055 }, + /* 0x5B40 */ + { 2821, 0x102b }, { 2826, 0xbdf7 }, { 2839, 0x8b78 }, { 2847, 0xb52b }, + /* 0x5B80 */ + { 2856, 0xbbbb }, { 2868, 0xbfe8 }, { 2879, 0x507c }, { 2886, 0x8379 }, + /* 0x5BC0 */ + { 2894, 0x52fd }, { 2904, 0xe95d }, { 2914, 0x5bf6 }, { 2925, 0xe56b }, + /* 0x5C00 */ + { 2935, 0xeffe }, { 2949, 0x444e }, { 2955, 0x2b1d }, { 2963, 0xff03 }, + /* 0x5C40 */ + { 2973, 0xed63 }, { 2983, 0xc82b }, { 2990, 0xd3bf }, { 3002, 0x1643 }, + /* 0x5C80 */ + { 3008, 0x9500 }, { 3012, 0x8013 }, { 3016, 0x3fcf }, { 3028, 0x5dea }, + /* 0x5CC0 */ + { 3038, 0x0aa0 }, { 3042, 0x0205 }, { 3045, 0xa703 }, { 3052, 0x2c51 }, + /* 0x5D00 */ + { 3058, 0x68c0 }, { 3063, 0xaff3 }, { 3075, 0x0ad5 }, { 3082, 0x0202 }, + /* 0x5D40 */ + { 3084, 0x5cc4 }, { 3091, 0x100d }, { 3095, 0xb602 }, { 3101, 0x0049 }, + /* 0x5D80 */ + { 3104, 0x1996 }, { 3111, 0x2295 }, { 3117, 0x5095 }, { 3123, 0x3795 }, + /* 0x5DC0 */ + { 3132, 0x3a00 }, { 3136, 0x69ce }, { 3145, 0x4bff }, { 3157, 0x68be }, + /* 0x5E00 */ + { 3166, 0x184d }, { 3172, 0xaf76 }, { 3183, 0xe820 }, { 3188, 0x61c9 }, + /* 0x5E40 */ + { 3195, 0x52b9 }, { 3203, 0xc1f0 }, { 3210, 0x781e }, { 3218, 0xfffc }, + /* 0x5E80 */ + { 3232, 0x849a }, { 3238, 0x14e0 }, { 3243, 0x3ce1 }, { 3251, 0xc3e0 }, + /* 0x5EC0 */ + { 3258, 0x8f4e }, { 3267, 0xae4d }, { 3276, 0x130f }, { 3283, 0xffdb }, + /* 0x5F00 */ + { 3297, 0xff9f }, { 3311, 0xf9fb }, { 3324, 0xa2e8 }, { 3331, 0x71f2 }, + /* 0x5F40 */ + { 3340, 0x55a3 }, { 3348, 0x33da }, { 3357, 0x3ede }, { 3368, 0xf28f }, + /* 0x5F80 */ + { 3378, 0x9fbf }, { 3391, 0x538f }, { 3400, 0xe797 }, { 3411, 0x33b8 }, + /* 0x5FC0 */ + { 3419, 0x3ab8 }, { 3427, 0x73dc }, { 3437, 0xca17 }, { 3445, 0xb92b }, + /* 0x6000 */ + { 3454, 0xe000 }, { 3457, 0x3bf5 }, { 3468, 0x8ff7 }, { 3480, 0x042a }, + /* 0x6040 */ + { 3484, 0x3cce }, { 3493, 0x8625 }, { 3499, 0xbf3d }, { 3511, 0x80a1 }, + /* 0x6080 */ + { 3515, 0x3e1a }, { 3523, 0xecf4 }, { 3533, 0x07c9 }, { 3540, 0x717f }, + /* 0x60C0 */ + { 3551, 0x09e0 }, { 3556, 0xbf3a }, { 3567, 0x418b }, { 3573, 0x0fff }, + /* 0x6100 */ + { 3585, 0xe34b }, { 3594, 0xde2d }, { 3604, 0x1982 }, { 3609, 0xf491 }, + /* 0x6140 */ + { 3617, 0x7dd6 }, { 3628, 0xa728 }, { 3635, 0xc9ad }, { 3644, 0x50fb }, + /* 0x6180 */ + { 3653, 0x6484 }, { 3658, 0x07df }, { 3668, 0x7bb0 }, { 3677, 0x5644 }, + /* 0x61C0 */ + { 3683, 0x3fc8 }, { 3692, 0xa021 }, { 3696, 0x0048 }, { 3698, 0xf5f4 }, + /* 0x6200 */ + { 3709, 0x7701 }, { 3716, 0xec77 }, { 3727, 0xc64e }, { 3735, 0xc91d }, + /* 0x6240 */ + { 3743, 0x7bcb }, { 3754, 0x4d6e }, { 3763, 0xe11b }, { 3771, 0xda4a }, + /* 0x6280 */ + { 3779, 0x063d }, { 3786, 0x5bfe }, { 3798, 0x1840 }, { 3801, 0x3a22 }, + /* 0x62C0 */ + { 3807, 0xb7f4 }, { 3818, 0x3bff }, { 3831, 0xf003 }, { 3837, 0xf0ea }, + /* 0x6300 */ + { 3846, 0x378e }, { 3855, 0x8303 }, { 3860, 0x8980 }, { 3864, 0xfe24 }, + /* 0x6340 */ + { 3873, 0xf21a }, { 3881, 0x12a1 }, { 3886, 0x5ba0 }, { 3893, 0x1cc4 }, + /* 0x6380 */ + { 3899, 0xd319 }, { 3907, 0x8b54 }, { 3914, 0x1faf }, { 3925, 0x6834 }, + /* 0x63C0 */ + { 3931, 0x8259 }, { 3937, 0x1c75 }, { 3945, 0x7a2b }, { 3954, 0x04f4 }, + /* 0x6400 */ + { 3960, 0xa240 }, { 3964, 0x50d9 }, { 3971, 0xb364 }, { 3979, 0x4450 }, + /* 0x6440 */ + { 3983, 0x4004 }, { 3985, 0x2d02 }, { 3990, 0xa281 }, { 3995, 0x2748 }, + /* 0x6480 */ + { 4001, 0x0188 }, { 4004, 0xe42e }, { 4012, 0x6a30 }, { 4018, 0xda05 }, + /* 0x64C0 */ + { 4025, 0x7cb6 }, { 4035, 0x05b5 }, { 4042, 0x90ff }, { 4052, 0xecd6 }, + /* 0x6500 */ + { 4062, 0x8031 }, { 4066, 0x7150 }, { 4072, 0x9e1c }, { 4080, 0xcbf4 }, + /* 0x6540 */ + { 4090, 0xa130 }, { 4095, 0x63f2 }, { 4104, 0x18cc }, { 4110, 0x05b5 }, + /* 0x6580 */ + { 4117, 0x57be }, { 4128, 0xba83 }, { 4136, 0xb8b2 }, { 4144, 0xb3a5 }, + /* 0x65C0 */ + { 4153, 0x9a7e }, { 4163, 0x0a94 }, { 4168, 0x33e7 }, { 4178, 0x1e06 }, + /* 0x6600 */ + { 4184, 0xd7dd }, { 4196, 0xd038 }, { 4202, 0xadb7 }, { 4213, 0x947b }, + /* 0x6640 */ + { 4222, 0xdb3e }, { 4233, 0xee86 }, { 4242, 0xfffe }, { 4257, 0x0dd9 }, + /* 0x6680 */ + { 4265, 0x639b }, { 4274, 0x23c7 }, { 4282, 0x6845 }, { 4288, 0xdb36 }, + /* 0x66C0 */ + { 4298, 0x03d2 }, { 4304, 0x3e40 }, { 4310, 0x1341 }, { 4315, 0xffbd }, + /* 0x6700 */ + { 4329, 0xab2b }, { 4338, 0xeafc }, { 4349, 0x7dc0 }, { 4357, 0xa5da }, + /* 0x6740 */ + { 4366, 0xf3c2 }, { 4375, 0xf25b }, { 4385, 0xa47f }, { 4395, 0xd8ff }, + /* 0x6780 */ + { 4407, 0x1aa2 }, { 4413, 0x3dad }, { 4423, 0x8247 }, { 4429, 0x0bdd }, + /* 0x67C0 */ + { 4438, 0xc55b }, { 4447, 0x6f9f }, { 4459, 0xd294 }, { 4466, 0xdabb }, + /* 0x6800 */ + { 4477, 0x001e }, { 4481, 0xe1c9 }, { 4489, 0x3e06 }, { 4496, 0x7b1e }, + /* 0x6840 */ + { 4506, 0x737f }, { 4518, 0xbabf }, { 4530, 0x4888 }, { 4534, 0xd4f4 }, + /* 0x6880 */ + { 4543, 0xa02e }, { 4549, 0xbfd9 }, { 4561, 0xaded }, { 4572, 0x1e7f }, + /* 0x68C0 */ + { 4583, 0xbf78 }, { 4594, 0x87f5 }, { 4604, 0xf1bb }, { 4615, 0x1e87 }, + /* 0x6900 */ + { 4623, 0xfdbb }, { 4636, 0x1e04 }, { 4641, 0x056e }, { 4648, 0xaa71 }, + /* 0x6940 */ + { 4656, 0x0644 }, { 4660, 0x76b8 }, { 4669, 0xff1f }, { 4682, 0xf7bc }, + /* 0x6980 */ + { 4694, 0x4407 }, { 4699, 0x1976 }, { 4707, 0x60e1 }, { 4713, 0xdc97 }, + /* 0x69C0 */ + { 4723, 0xfc8b }, { 4733, 0x634b }, { 4741, 0xef8c }, { 4751, 0xea7c }, + /* 0x6A00 */ + { 4761, 0x9c24 }, { 4767, 0xeebe }, { 4779, 0x4e0e }, { 4786, 0xef7d }, + /* 0x6A40 */ + { 4799, 0x4bf0 }, { 4807, 0x8b45 }, { 4814, 0x0856 }, { 4819, 0xc50c }, + /* 0x6A80 */ + { 4825, 0x6a19 }, { 4832, 0xf093 }, { 4840, 0x5c2f }, { 4849, 0x2908 }, + /* 0x6AC0 */ + { 4853, 0x004e }, { 4857, 0xfc1b }, { 4867, 0x1590 }, { 4872, 0x2c0e }, + /* 0x6B00 */ + { 4878, 0x8c30 }, { 4883, 0xe8c7 }, { 4892, 0x908b }, { 4898, 0x67a4 }, + /* 0x6B40 */ + { 4906, 0x56c8 }, { 4913, 0x8b59 }, { 4921, 0x96ff }, { 4933, 0x8fb8 }, + /* 0x6B80 */ + { 4942, 0x2e5f }, { 4952, 0x4960 }, { 4957, 0xee10 }, { 4964, 0xfcbe }, + /* 0x6BC0 */ + { 4976, 0xebe1 }, { 4986, 0x8ddc }, { 4995, 0xd8c0 }, { 5001, 0x800a }, + /* 0x6C00 */ + { 5004, 0xc524 }, { 5010, 0x089b }, { 5016, 0x0018 }, { 5018, 0xc5f8 }, + /* 0x6C40 */ + { 5027, 0x6007 }, { 5032, 0xfea1 }, { 5042, 0x2585 }, { 5048, 0x645d }, + /* 0x6C80 */ + { 5056, 0x337e }, { 5066, 0x1ffd }, { 5078, 0x6c06 }, { 5084, 0xff0a }, + /* 0x6CC0 */ + { 5094, 0x1676 }, { 5102, 0x3ef9 }, { 5113, 0xff2f }, { 5126, 0x080b }, + /* 0x6D00 */ + { 5130, 0x5c11 }, { 5136, 0xca84 }, { 5142, 0xcef0 }, { 5151, 0xfb7e }, + /* 0x6D40 */ + { 5164, 0x0032 }, { 5167, 0x5f00 }, { 5173, 0x5679 }, { 5182, 0x0391 }, + /* 0x6D80 */ + { 5187, 0x77a7 }, { 5198, 0x1b3a }, { 5206, 0xdc00 }, { 5211, 0x9134 }, + /* 0x6DC0 */ + { 5217, 0xd9f5 }, { 5228, 0xef67 }, { 5240, 0x5f52 }, { 5249, 0x1eea }, + /* 0x6E00 */ + { 5258, 0x0fa0 }, { 5264, 0xeea8 }, { 5273, 0xfaff }, { 5287, 0x5554 }, + /* 0x6E40 */ + { 5294, 0xff18 }, { 5304, 0xd9da }, { 5314, 0xc888 }, { 5319, 0xc044 }, + /* 0x6E80 */ + { 5323, 0x9005 }, { 5327, 0xb149 }, { 5334, 0x8ca4 }, { 5340, 0xa4d6 }, + /* 0x6EC0 */ + { 5348, 0x5ebe }, { 5359, 0x623a }, { 5366, 0x9800 }, { 5369, 0xcb94 }, + /* 0x6F00 */ + { 5377, 0x9646 }, { 5384, 0x053b }, { 5391, 0x9c2d }, { 5399, 0xd16e }, + /* 0x6F40 */ + { 5408, 0x0022 }, { 5410, 0xdf96 }, { 5421, 0xe157 }, { 5430, 0x7511 }, + /* 0x6F80 */ + { 5437, 0x7157 }, { 5446, 0x81d3 }, { 5453, 0x84bb }, { 5461, 0x526a }, + /* 0x6FC0 */ + { 5468, 0x07cf }, { 5477, 0xcd30 }, { 5484, 0xda13 }, { 5492, 0x566b }, + /* 0x7000 */ + { 5501, 0x8ee3 }, { 5510, 0xed22 }, { 5518, 0x11c8 }, { 5523, 0x5605 }, + /* 0x7040 */ + { 5529, 0x5c88 }, { 5535, 0x6112 }, { 5540, 0xda38 }, { 5548, 0x7161 }, + /* 0x7080 */ + { 5555, 0x4662 }, { 5561, 0x82a4 }, { 5566, 0xf810 }, { 5572, 0x0f8a }, + /* 0x70C0 */ + { 5579, 0x8d00 }, { 5583, 0xb31a }, { 5591, 0x1010 }, { 5593, 0x2202 }, + /* 0x7100 */ + { 5596, 0x93d8 }, { 5604, 0x5610 }, { 5609, 0xc843 }, { 5615, 0x1043 }, + /* 0x7140 */ + { 5619, 0x56c0 }, { 5625, 0x526f }, { 5634, 0x53f5 }, { 5644, 0x2000 }, + /* 0x7180 */ + { 5645, 0x85b1 }, { 5652, 0x8a74 }, { 5659, 0xd105 }, { 5665, 0x460a }, + /* 0x71C0 */ + { 5670, 0x4b1a }, { 5677, 0x92bd }, { 5686, 0x70e1 }, { 5693, 0xda20 }, + /* 0x7200 */ + { 5699, 0x20c1 }, { 5703, 0x0821 }, { 5706, 0x3d00 }, { 5711, 0xff75 }, + /* 0x7240 */ + { 5724, 0x19c5 }, { 5731, 0xabec }, { 5741, 0xc28e }, { 5748, 0xe314 }, + /* 0x7280 */ + { 5755, 0x6087 }, { 5761, 0x0844 }, { 5764, 0xf085 }, { 5771, 0x4247 }, + /* 0x72C0 */ + { 5777, 0x505f }, { 5785, 0x0a85 }, { 5790, 0x3207 }, { 5796, 0x3f88 }, + /* 0x7300 */ + { 5804, 0x0480 }, { 5806, 0xbbc4 }, { 5815, 0xdfa0 }, { 5824, 0xe2da }, + /* 0x7340 */ + { 5833, 0xc030 }, { 5837, 0x0085 }, { 5840, 0xdd48 }, { 5848, 0x1da7 }, + /* 0x7380 */ + { 5857, 0x0eb2 }, { 5864, 0xd170 }, { 5871, 0x0b65 }, { 5878, 0x9aac }, + /* 0x73C0 */ + { 5886, 0xef25 }, { 5896, 0x4240 }, { 5899, 0x66ab }, { 5908, 0x4702 }, + /* 0x7400 */ + { 5913, 0x06ea }, { 5920, 0x0c08 }, { 5923, 0xdd74 }, { 5933, 0x867f }, + /* 0x7440 */ + { 5943, 0x28db }, { 5951, 0xfeac }, { 5962, 0xae1d }, { 5971, 0x404b }, + /* 0x7480 */ + { 5976, 0x0bea }, { 5984, 0xd385 }, { 5992, 0x0fef }, { 6003, 0xae21 }, + /* 0x74C0 */ + { 6010, 0x8700 }, { 6014, 0x5550 }, { 6020, 0xcacd }, { 6029, 0x85c7 }, + /* 0x7500 */ + { 6037, 0x703a }, { 6044, 0xd5aa }, { 6053, 0x9d79 }, { 6063, 0x7d8f }, + /* 0x7540 */ + { 6074, 0xff51 }, { 6085, 0x3e17 }, { 6094, 0xbef5 }, { 6106, 0xe7df }, + /* 0x7580 */ + { 6119, 0xdec6 }, { 6129, 0x2416 }, { 6134, 0x082c }, { 6138, 0xf3af }, + /* 0x75C0 */ + { 6150, 0xe4ed }, { 6160, 0xeb3c }, { 6170, 0x529d }, { 6178, 0xd61f }, + /* 0x7600 */ + { 6188, 0xab8f }, { 6198, 0xdb68 }, { 6207, 0x21f7 }, { 6216, 0x1839 }, + /* 0x7640 */ + { 6222, 0x1bce }, { 6231, 0x1164 }, { 6236, 0xf7b6 }, { 6248, 0x7d47 }, + /* 0x7680 */ + { 6258, 0x49db }, { 6267, 0x7e69 }, { 6277, 0xc5c3 }, { 6285, 0x87d1 }, + /* 0x76C0 */ + { 6293, 0x776c }, { 6303, 0xd8d4 }, { 6311, 0x55fa }, { 6321, 0x5916 }, + /* 0x7700 */ + { 6328, 0x1f92 }, { 6336, 0xce80 }, { 6342, 0x2271 }, { 6348, 0x15f0 }, + /* 0x7740 */ + { 6355, 0x60c1 }, { 6360, 0x9d00 }, { 6365, 0x0d6f }, { 6374, 0xf604 }, + /* 0x7780 */ + { 6381, 0x4801 }, { 6384, 0xc412 }, { 6389, 0x3635 }, { 6397, 0xba49 }, + /* 0x77C0 */ + { 6405, 0x2080 }, { 6407, 0xdc80 }, { 6413, 0xf6fd }, { 6426, 0x1819 }, + /* 0x7800 */ + { 6431, 0x3264 }, { 6437, 0x0234 }, { 6441, 0x30e3 }, { 6448, 0x8414 }, + /* 0x7840 */ + { 6452, 0xc0a8 }, { 6457, 0x2002 }, { 6459, 0xdd10 }, { 6466, 0x1014 }, + /* 0x7880 */ + { 6469, 0x74c2 }, { 6476, 0xe4ba }, { 6485, 0xa698 }, { 6492, 0x5c21 }, + /* 0x78C0 */ + { 6498, 0x5d62 }, { 6506, 0x0433 }, { 6511, 0x91d3 }, { 6519, 0x6e94 }, + /* 0x7900 */ + { 6527, 0x4083 }, { 6531, 0x1a07 }, { 6537, 0x5c60 }, { 6543, 0x5c13 }, + /* 0x7940 */ + { 6550, 0x07e3 }, { 6558, 0xfde9 }, { 6570, 0x21a5 }, { 6576, 0x8684 }, + /* 0x7980 */ + { 6581, 0xe433 }, { 6589, 0x2970 }, { 6595, 0x46c2 }, { 6601, 0xef1b }, + /* 0x79C0 */ + { 6612, 0x3f87 }, { 6622, 0xc176 }, { 6630, 0x3ada }, { 6639, 0x0801 }, + /* 0x7A00 */ + { 6641, 0x6d09 }, { 6648, 0xdfb2 }, { 6659, 0x6001 }, { 6662, 0xfb86 }, + /* 0x7A40 */ + { 6672, 0xf2cd }, { 6682, 0xb2c1 }, { 6689, 0x2e8f }, { 6698, 0xa771 }, + /* 0x7A80 */ + { 6707, 0x053e }, { 6714, 0x81ed }, { 6722, 0xd609 }, { 6729, 0xde49 }, + /* 0x7AC0 */ + { 6738, 0xfdb8 }, { 6749, 0xb62e }, { 6758, 0xadef }, { 6770, 0xa751 }, + /* 0x7B00 */ + { 6778, 0x8dd4 }, { 6786, 0x4b06 }, { 6792, 0xf5e1 }, { 6802, 0x2a6a }, + /* 0x7B40 */ + { 6809, 0xfbe2 }, { 6820, 0x2077 }, { 6827, 0xf2f1 }, { 6837, 0x863f }, + /* 0x7B80 */ + { 6846, 0xa8c0 }, { 6851, 0xffb7 }, { 6865, 0xa402 }, { 6869, 0x1132 }, + /* 0x7BC0 */ + { 6874, 0x9ef3 }, { 6885, 0x26d0 }, { 6891, 0x2671 }, { 6898, 0x00c9 }, + /* 0x7C00 */ + { 6902, 0xe88b }, { 6910, 0xc09e }, { 6917, 0x0ccb }, { 6924, 0xe1ca }, + /* 0x7C40 */ + { 6932, 0xb429 }, { 6939, 0xc3d3 }, { 6948, 0xf233 }, { 6957, 0x4229 }, + /* 0x7C80 */ + { 6962, 0xaa0e }, { 6969, 0x89b5 }, { 6977, 0x69f7 }, { 6988, 0xf2ce }, + /* 0x7CC0 */ + { 6998, 0x6535 }, { 7006, 0xf3e4 }, { 7016, 0x88c5 }, { 7022, 0x4d74 }, + /* 0x7D00 */ + { 7030, 0x2ffd }, { 7042, 0x7fbd }, { 7055, 0xd80f }, { 7063, 0xe62f }, + /* 0x7D40 */ + { 7073, 0xd9ff }, { 7086, 0x5e49 }, { 7094, 0x454e }, { 7101, 0xa66f }, + /* 0x7D80 */ + { 7111, 0x9b48 }, { 7118, 0xbe88 }, { 7126, 0xfccd }, { 7137, 0xedf7 }, + /* 0x7DC0 */ + { 7150, 0x9c85 }, { 7157, 0x77e6 }, { 7168, 0x935b }, { 7177, 0x0a16 }, + /* 0x7E00 */ + { 7182, 0x0f32 }, { 7189, 0xe8a7 }, { 7198, 0x59cf }, { 7208, 0x6ea6 }, + /* 0x7E40 */ + { 7217, 0x2cea }, { 7225, 0x6674 }, { 7233, 0x2ec2 }, { 7240, 0xfa29 }, + /* 0x7E80 */ + { 7249, 0xf7cc }, { 7260, 0x1d5f }, { 7270, 0x0000 }, { 7270, 0x0000 }, + /* 0x7F00 */ + { 7270, 0x0000 }, { 7270, 0x0000 }, { 7270, 0x0000 }, { 7270, 0x5d40 }, + /* 0x7F40 */ + { 7276, 0xf0b8 }, { 7284, 0x8137 }, { 7291, 0x6f9b }, { 7302, 0x63a5 }, + /* 0x7F80 */ + { 7310, 0x55ec }, { 7319, 0x74d3 }, { 7328, 0xe318 }, { 7335, 0xa344 }, + /* 0x7FC0 */ + { 7341, 0xd46a }, { 7349, 0x8834 }, { 7354, 0xda6b }, { 7364, 0x1e0d }, + /* 0x8000 */ + { 7371, 0x5d7f }, { 7383, 0x13f7 }, { 7393, 0x1152 }, { 7398, 0xb8e9 }, + /* 0x8040 */ + { 7407, 0x0448 }, { 7410, 0xc544 }, { 7416, 0x8146 }, { 7421, 0xeaff }, + /* 0x8080 */ + { 7434, 0x1af0 }, { 7441, 0x3f48 }, { 7449, 0xb6b6 }, { 7459, 0x0516 }, + /* 0x80C0 */ + { 7464, 0x5478 }, { 7471, 0x6fe0 }, { 7480, 0x8073 }, { 7486, 0x393a }, + /* 0x8100 */ + { 7494, 0x27e4 }, { 7502, 0x4d40 }, { 7507, 0x9298 }, { 7513, 0x622a }, + /* 0x8140 */ + { 7519, 0x4c40 }, { 7523, 0x803b }, { 7529, 0x6be1 }, { 7538, 0x8713 }, + /* 0x8180 */ + { 7545, 0x853f }, { 7554, 0x3528 }, { 7560, 0x0319 }, { 7565, 0xed2d }, + /* 0x81C0 */ + { 7575, 0xa74f }, { 7585, 0x8fca }, { 7594, 0x35b9 }, { 7603, 0xfc18 }, + /* 0x8200 */ + { 7611, 0x77b6 }, { 7622, 0xdbc5 }, { 7632, 0x5e06 }, { 7639, 0x13fc }, + /* 0x8240 */ + { 7648, 0x8ae1 }, { 7655, 0xb780 }, { 7662, 0xcd5d }, { 7672, 0xe3d6 }, + /* 0x8280 */ + { 7682, 0x6c08 }, { 7687, 0xa20c }, { 7692, 0xfbfa }, { 7705, 0xff9e }, + /* 0x82C0 */ + { 7718, 0x0060 }, { 7720, 0xdabe }, { 7731, 0x09ee }, { 7739, 0x6e9a }, + /* 0x8300 */ + { 7748, 0x53ff }, { 7760, 0x39c0 }, { 7766, 0xa90c }, { 7772, 0x1777 }, + /* 0x8340 */ + { 7782, 0x86b9 }, { 7790, 0x01b7 }, { 7797, 0x000c }, { 7799, 0xb8a8 }, + /* 0x8380 */ + { 7806, 0x66e0 }, { 7813, 0xed7c }, { 7824, 0x0f85 }, { 7831, 0xa022 }, + /* 0x83C0 */ + { 7835, 0xd6a3 }, { 7844, 0xb15b }, { 7853, 0x8e23 }, { 7860, 0x2a97 }, + /* 0x8400 */ + { 7868, 0xfcda }, { 7879, 0x00aa }, { 7883, 0x1605 }, { 7888, 0x3322 }, + /* 0x8440 */ + { 7894, 0xc740 }, { 7900, 0x9e86 }, { 7908, 0xfa6e }, { 7919, 0x17eb }, + /* 0x8480 */ + { 7929, 0x0836 }, { 7934, 0xd291 }, { 7941, 0xa042 }, { 7945, 0xdf14 }, + /* 0x84C0 */ + { 7954, 0xee57 }, { 7965, 0x164b }, { 7972, 0xd480 }, { 7977, 0xb413 }, + /* 0x8500 */ + { 7984, 0x1041 }, { 7987, 0xcdba }, { 7997, 0xb87a }, { 8006, 0x6034 }, + /* 0x8540 */ + { 8011, 0xcf0b }, { 8020, 0x47aa }, { 8028, 0xa71e }, { 8037, 0xec80 }, + /* 0x8580 */ + { 8043, 0x95d3 }, { 8052, 0xba9b }, { 8062, 0xff54 }, { 8073, 0x1681 }, + /* 0x85C0 */ + { 8078, 0xee82 }, { 8086, 0xb321 }, { 8093, 0x2672 }, { 8100, 0xcec0 }, + /* 0x8600 */ + { 8107, 0x0cf5 }, { 8115, 0x45cf }, { 8124, 0xa296 }, { 8131, 0x9301 }, + /* 0x8640 */ + { 8136, 0x6003 }, { 8140, 0xdcf9 }, { 8151, 0x9884 }, { 8156, 0x0ea2 }, + /* 0x8680 */ + { 8162, 0x3e80 }, { 8168, 0x312a }, { 8174, 0x8f18 }, { 8181, 0x014b }, + /* 0x86C0 */ + { 8186, 0x6ada }, { 8195, 0xcab2 }, { 8203, 0xf258 }, { 8211, 0x7f00 }, + /* 0x8700 */ + { 8218, 0x6fed }, { 8230, 0x970f }, { 8239, 0x022a }, { 8243, 0xcc92 }, + /* 0x8740 */ + { 8250, 0x5a09 }, { 8256, 0x83aa }, { 8263, 0x4579 }, { 8271, 0x9156 }, + /* 0x8780 */ + { 8278, 0x2b84 }, { 8284, 0x8008 }, { 8286, 0xb885 }, { 8293, 0x6c28 }, + /* 0x87C0 */ + { 8299, 0x48d3 }, { 8306, 0x8045 }, { 8310, 0xbc69 }, { 8319, 0x4ae4 }, + /* 0x8800 */ + { 8326, 0xec6a }, { 8335, 0x807b }, { 8342, 0x418e }, { 8348, 0x1a46 }, + /* 0x8840 */ + { 8354, 0x3455 }, { 8361, 0xeb8c }, { 8370, 0x8b1e }, { 8378, 0xe0a5 }, + /* 0x8880 */ + { 8385, 0x2906 }, { 8390, 0x43c4 }, { 8396, 0x4c15 }, { 8402, 0xf0b3 }, + /* 0x88C0 */ + { 8411, 0xc43f }, { 8420, 0xbb3e }, { 8431, 0x0102 }, { 8433, 0x733f }, + /* 0x8900 */ + { 8444, 0x1496 }, { 8450, 0x770d }, { 8459, 0x0ca0 }, { 8463, 0x0bc5 }, + /* 0x8940 */ + { 8470, 0x323f }, { 8479, 0xc040 }, { 8482, 0xa455 }, { 8489, 0xc094 }, + /* 0x8980 */ + { 8494, 0x8fcb }, { 8504, 0x85d9 }, { 8512, 0x96c2 }, { 8519, 0xa48d }, + /* 0x89C0 */ + { 8526, 0x0001 }, { 8527, 0x3554 }, { 8534, 0x08e8 }, { 8539, 0xa15a }, + /* 0x8A00 */ + { 8546, 0x550d }, { 8553, 0xa9ff }, { 8565, 0x242e }, { 8571, 0x5cfa }, + /* 0x8A40 */ + { 8581, 0x61e2 }, { 8588, 0x6937 }, { 8597, 0x7a4f }, { 8607, 0x122f }, + /* 0x8A80 */ + { 8614, 0x32b4 }, { 8621, 0x452b }, { 8628, 0x71fb }, { 8639, 0xd285 }, + /* 0x8AC0 */ + { 8646, 0xb894 }, { 8653, 0xdcc5 }, { 8662, 0x68d7 }, { 8671, 0x55da }, + /* 0x8B00 */ + { 8680, 0x74b7 }, { 8690, 0xbed1 }, { 8700, 0x3943 }, { 8707, 0x4208 }, + /* 0x8B40 */ + { 8710, 0xd24a }, { 8717, 0xdf52 }, { 8727, 0x9a40 }, { 8732, 0xa0d7 }, + /* 0x8B80 */ + { 8740, 0x5c0b }, { 8747, 0x767d }, { 8758, 0x0000 }, { 8758, 0x0000 }, + /* 0x8C00 */ + { 8758, 0x0000 }, { 8758, 0x0000 }, { 8758, 0x0000 }, { 8758, 0xa680 }, + /* 0x8C40 */ + { 8763, 0xd7e2 }, { 8773, 0x04b1 }, { 8778, 0x3f06 }, { 8786, 0x1708 }, + /* 0x8C80 */ + { 8791, 0x7624 }, { 8798, 0x6b1c }, { 8806, 0xff97 }, { 8819, 0xb9dd }, + /* 0x8CC0 */ + { 8830, 0x659f }, { 8840, 0x5e6a }, { 8849, 0x245f }, { 8857, 0x7d13 }, + /* 0x8D00 */ + { 8866, 0xefb0 }, { 8876, 0x085d }, { 8882, 0x0000 }, { 8882, 0x0000 }, + /* 0x8D40 */ + { 8882, 0x0000 }, { 8882, 0x0000 }, { 8882, 0x38d0 }, { 8888, 0x009b }, + /* 0x8D80 */ + { 8893, 0x0432 }, { 8897, 0x0220 }, { 8899, 0x8148 }, { 8903, 0x4408 }, + /* 0x8DC0 */ + { 8906, 0xd944 }, { 8913, 0xaec2 }, { 8921, 0x9d0a }, { 8928, 0xb028 }, + /* 0x8E00 */ + { 8933, 0x9740 }, { 8939, 0xe051 }, { 8945, 0x048f }, { 8951, 0x2271 }, + /* 0x8E40 */ + { 8957, 0x1f94 }, { 8965, 0x8231 }, { 8970, 0xb01d }, { 8977, 0x1855 }, + /* 0x8E80 */ + { 8983, 0x2cb2 }, { 8990, 0x431a }, { 8996, 0xdc02 }, { 9002, 0x486b }, + /* 0x8EC0 */ + { 9009, 0x3d61 }, { 9017, 0x8816 }, { 9022, 0x080c }, { 9025, 0x7f00 }, + /* 0x8F00 */ + { 9032, 0x1729 }, { 9039, 0xfabc }, { 9050, 0xae40 }, { 9056, 0xcb48 }, + /* 0x8F40 */ + { 9063, 0x7675 }, { 9073, 0x9190 }, { 9078, 0x001e }, { 9082, 0x0000 }, + /* 0x8F80 */ + { 9082, 0x0000 }, { 9082, 0xd800 }, { 9086, 0xe1d8 }, { 9094, 0x9cf7 }, + /* 0x8FC0 */ + { 9105, 0x6476 }, { 9113, 0x043a }, { 9118, 0xef75 }, { 9130, 0x2fb3 }, + /* 0x9000 */ + { 9140, 0xf96f }, { 9152, 0xe6fb }, { 9164, 0x608f }, { 9171, 0x53e6 }, + /* 0x9040 */ + { 9180, 0xeebe }, { 9192, 0x737f }, { 9204, 0xe32b }, { 9213, 0xb5e4 }, + /* 0x9080 */ + { 9222, 0x97bf }, { 9234, 0x0aa3 }, { 9240, 0x854e }, { 9247, 0x416b }, + /* 0x90C0 */ + { 9254, 0x45ba }, { 9262, 0xf880 }, { 9268, 0xa916 }, { 9275, 0xe0f4 }, + /* 0x9100 */ + { 9283, 0x0055 }, { 9287, 0x5374 }, { 9295, 0xa08c }, { 9300, 0x2697 }, + /* 0x9140 */ + { 9308, 0x7fc0 }, { 9317, 0x0bd4 }, { 9324, 0x163e }, { 9332, 0x03bc }, + /* 0x9180 */ + { 9339, 0x6aac }, { 9347, 0x5085 }, { 9352, 0xdd14 }, { 9360, 0x157a }, + /* 0x91C0 */ + { 9368, 0xfbdb }, { 9381, 0xbdc3 }, { 9391, 0x70fa }, { 9400, 0x9862 }, + /* 0x9200 */ + { 9406, 0x6482 }, { 9411, 0x40f3 }, { 9418, 0x1200 }, { 9420, 0x9798 }, + /* 0x9240 */ + { 9428, 0xcfbd }, { 9440, 0x4ec3 }, { 9448, 0x01f7 }, { 9456, 0xf102 }, + /* 0x9280 */ + { 9462, 0x2329 }, { 9468, 0x9fea }, { 9479, 0x2880 }, { 9482, 0x8284 }, + /* 0x92C0 */ + { 9486, 0xd845 }, { 9493, 0x028d }, { 9498, 0x26b1 }, { 9505, 0x9f8c }, + /* 0x9300 */ + { 9514, 0xa054 }, { 9519, 0xe723 }, { 9528, 0xdbef }, { 9541, 0x0c24 }, + /* 0x9340 */ + { 9545, 0x2f90 }, { 9552, 0x1cd2 }, { 9559, 0x5c31 }, { 9566, 0x502b }, + /* 0x9380 */ + { 9572, 0x9900 }, { 9576, 0x4cd0 }, { 9582, 0x708a }, { 9588, 0x0601 }, + /* 0x93C0 */ + { 9591, 0x01ca }, { 9596, 0xf1c3 }, { 9605, 0x01b6 }, { 9611, 0x2822 }, + /* 0x9400 */ + { 9615, 0x8298 }, { 9620, 0x07d9 }, { 9628, 0x0802 }, { 9630, 0x0d7c }, + /* 0x9440 */ + { 9638, 0x0432 }, { 9642, 0x4c0e }, { 9648, 0xac0d }, { 9655, 0xf0a7 }, + /* 0x9480 */ + { 9664, 0x0002 }, { 9665, 0x0000 }, { 9665, 0x0000 }, { 9665, 0x0000 }, + /* 0x9540 */ + { 9665, 0x0000 }, { 9665, 0x0000 }, { 9665, 0x0000 }, { 9665, 0x0380 }, + /* 0x9580 */ + { 9668, 0xfecd }, { 9680, 0x835a }, { 9687, 0x3bfd }, { 9699, 0x7a54 }, + /* 0x95C0 */ + { 9707, 0x3d88 }, { 9714, 0x5579 }, { 9723, 0x0026 }, { 9726, 0x0000 }, + /* 0x9600 */ + { 9726, 0x0000 }, { 9726, 0x3000 }, { 9728, 0xd502 }, { 9734, 0x981c }, + /* 0x9640 */ + { 9740, 0xb817 }, { 9748, 0xf901 }, { 9755, 0x147e }, { 9763, 0x25ed }, + /* 0x9680 */ + { 9772, 0xed74 }, { 9782, 0x3fb0 }, { 9791, 0x87b9 }, { 9800, 0x3fdf }, + /* 0x96C0 */ + { 9813, 0x7af3 }, { 9824, 0x7f66 }, { 9835, 0x8f0c }, { 9842, 0x0ac5 }, + /* 0x9700 */ + { 9848, 0xe5d1 }, { 9857, 0x525a }, { 9864, 0x0498 }, { 9868, 0x6b4d }, + /* 0x9740 */ + { 9877, 0xe3d6 }, { 9887, 0x5ee4 }, { 9896, 0x6f57 }, { 9907, 0x161a }, + /* 0x9780 */ + { 9913, 0xa872 }, { 9920, 0x5561 }, { 9927, 0x694d }, { 9935, 0x441e }, + /* 0x97C0 */ + { 9941, 0x1b4a }, { 9948, 0x5b1a }, { 9956, 0x6002 }, { 9959, 0x887e }, + /* 0x9800 */ + { 9967, 0xf57e }, { 9979, 0x45df }, { 9989, 0x383a }, { 9996, 0x399d }, + /* 0x9840 */ + { 10005, 0xf8c0 }, { 10012, 0x4ffc }, { 10023, 0x98e0 }, { 10029, 0x001b }, + /* 0x9880 */ + { 10033, 0x0000 }, { 10033, 0x0000 }, { 10033, 0xad00 }, { 10038, 0x9dc3 }, + /* 0x98C0 */ + { 10047, 0x09dc }, { 10054, 0x9800 }, { 10057, 0xeeaf }, { 10069, 0x701f }, + /* 0x9900 */ + { 10077, 0x1728 }, { 10083, 0x7ddd }, { 10095, 0x5113 }, { 10101, 0x7c0e }, + /* 0x9940 */ + { 10109, 0x7a67 }, { 10119, 0x91a7 }, { 10127, 0x0001 }, { 10128, 0x0000 }, + /* 0x9980 */ + { 10128, 0x0000 }, { 10128, 0x43c0 }, { 10133, 0x7168 }, { 10140, 0xb218 }, + /* 0x99C0 */ + { 10146, 0x037a }, { 10153, 0xeb37 }, { 10164, 0x6004 }, { 10167, 0x9b07 }, + /* 0x9A00 */ + { 10175, 0xc42e }, { 10182, 0x064e }, { 10188, 0x6911 }, { 10194, 0x41c3 }, + /* 0x9A40 */ + { 10200, 0x743d }, { 10209, 0x8da4 }, { 10216, 0x0e34 }, { 10222, 0x0000 }, + /* 0x9A80 */ + { 10222, 0x0000 }, { 10222, 0x0000 }, { 10222, 0xa100 }, { 10225, 0x13c1 }, + /* 0x9AC0 */ + { 10231, 0xc05b }, { 10238, 0xd17f }, { 10249, 0xee6d }, { 10260, 0x0a92 }, + /* 0x9B00 */ + { 10265, 0x114c }, { 10270, 0x9545 }, { 10277, 0xefad }, { 10289, 0x380e }, + /* 0x9B40 */ + { 10295, 0xe83e }, { 10304, 0x4512 }, { 10309, 0x9868 }, { 10315, 0x02fc }, + /* 0x9B80 */ + { 10322, 0xc418 }, { 10327, 0xc0ce }, { 10334, 0x7dc1 }, { 10343, 0x4316 }, + /* 0x9BC0 */ + { 10349, 0xc6c3 }, { 10357, 0x2956 }, { 10364, 0xcdbe }, { 10375, 0x25af }, + /* 0x9C00 */ + { 10384, 0x3751 }, { 10392, 0x2f7d }, { 10403, 0xe6be }, { 10414, 0x4ec7 }, + /* 0x9C40 */ + { 10423, 0x87e2 }, { 10431, 0xbd9d }, { 10442, 0x6ea9 }, { 10451, 0x05e5 }, + /* 0x9CC0 */ + { 10458, 0x0000 }, { 10458, 0x0000 }, { 10458, 0x1ae0 }, { 10464, 0x005d }, + /* 0x9D00 */ + { 10469, 0x4bcc }, { 10477, 0xe9a6 }, { 10486, 0x1d48 }, { 10492, 0xc804 }, + /* 0x9D40 */ + { 10496, 0x05de }, { 10504, 0xf207 }, { 10512, 0x9a1f }, { 10521, 0x54cd }, + /* 0x9D80 */ + { 10529, 0xa690 }, { 10535, 0x0640 }, { 10538, 0x9a12 }, { 10544, 0xbf34 }, + /* 0x9DC0 */ + { 10554, 0x82df }, { 10563, 0x86c8 }, { 10569, 0xa0c9 }, { 10575, 0x2714 }, + /* 0x9E00 */ + { 10581, 0x2484 }, { 10585, 0x7e20 }, { 10592, 0x0000 }, { 10592, 0x0000 }, + /* 0x9E40 */ + { 10592, 0x0000 }, { 10592, 0x0000 }, { 10592, 0x0000 }, { 10592, 0xbb20 }, + /* 0x9E80 */ + { 10599, 0x1923 }, { 10605, 0xe8ae }, { 10614, 0xb770 }, { 10623, 0xff30 }, + /* 0x9EC0 */ + { 10633, 0xf018 }, { 10639, 0xfb17 }, { 10650, 0xc1a1 }, { 10656, 0xbad0 }, + /* 0x9F00 */ + { 10664, 0x418c }, { 10669, 0x02a9 }, { 10674, 0x9003 }, { 10678, 0x6e80 }, + /* 0x9F40 */ + { 10684, 0xcc62 }, { 10691, 0xa1bc }, { 10699, 0x36cf }, { 10709, 0x00e5 }, + /* 0x9F80 */ + { 10714, 0x2000 }, { 10715, 0x30b1 }, { 10721, 0x0005 }, { 10723, 0x0000 }, + /* 0xF900 */ + { 10723, 0x0000 }, { 10723, 0x2000 }, { 10724, 0x0300 }, { 10726, 0x0040 }, + /* 0xF940 */ + { 10727, 0x0000 }, { 10727, 0x0000 }, { 10727, 0x0000 }, { 10727, 0x0001 }, + /* 0xF9C0 */ + { 10728, 0x0000 }, { 10728, 0x1001 }, { 10730, 0x0000 }, { 10730, 0x0000 }, + /* 0xFA00 */ + { 10730, 0x8000 }, { 10731, 0x8e7b }, { 10741, 0x0057 }, { 10746, 0xffff }, + /* 0xFA40 */ + { 10762, 0xffff }, { 10778, 0xffff }, { 10794, 0x07ff }, { 10805, 0x0000 }, + /* 0xFE40 */ + { 10805, 0x0060 }, { 10807, 0x0000 }, { 10807, 0x0000 }, { 10807, 0x0000 }, + /* 0xFF00 */ + { 10807, 0xfffe }, { 10822, 0xffff }, { 10838, 0xffff }, { 10854, 0xffff }, + /* 0xFF40 */ + { 10870, 0xffff }, { 10886, 0xffff }, { 10902, 0x0001 }, { 10903, 0x0000 }, + /* 0xFFC0 */ + { 10903, 0x0000 }, { 10903, 0x0000 }, { 10903, 0x0028 }, { 10905, 0x0000 }, + /* 0x20000 */ + { 10905, 0x0800 }, { 10906, 0x0000 }, { 10906, 0x0000 }, { 10906, 0x0000 }, + /* 0x20080 */ + { 10906, 0x0200 }, { 10907, 0x0000 }, { 10907, 0x0014 }, { 10909, 0x0000 }, + /* 0x20180 */ + { 10909, 0x0000 }, { 10909, 0x0000 }, { 10909, 0x0004 }, { 10910, 0x0000 }, + /* 0x20200 */ + { 10910, 0x0000 }, { 10910, 0x0008 }, { 10911, 0x0000 }, { 10911, 0x0000 }, + /* 0x20300 */ + { 10911, 0x0000 }, { 10911, 0x0000 }, { 10911, 0x0800 }, { 10912, 0x0000 }, + /* 0x20340 */ + { 10912, 0x0000 }, { 10912, 0x0000 }, { 10912, 0x0000 }, { 10912, 0x0002 }, + /* 0x20380 */ + { 10913, 0x0002 }, { 10914, 0x0000 }, { 10914, 0x0000 }, { 10914, 0x0000 }, + /* 0x203C0 */ + { 10914, 0x0000 }, { 10914, 0x0000 }, { 10914, 0x0000 }, { 10914, 0x0200 }, + /* 0x20440 */ + { 10915, 0x0400 }, { 10916, 0x0000 }, { 10916, 0x0000 }, { 10916, 0x0000 }, + /* 0x20500 */ + { 10916, 0x0200 }, { 10917, 0x0000 }, { 10917, 0x0000 }, { 10917, 0x0000 }, + /* 0x205C0 */ + { 10917, 0x0000 }, { 10917, 0x0040 }, { 10918, 0x0000 }, { 10918, 0x0000 }, + /* 0x20600 */ + { 10918, 0x0000 }, { 10918, 0x0000 }, { 10918, 0x0100 }, { 10919, 0x0000 }, + /* 0x20740 */ + { 10919, 0x8000 }, { 10920, 0x0000 }, { 10920, 0x0000 }, { 10920, 0x0000 }, + /* 0x20800 */ + { 10920, 0x0080 }, { 10921, 0x0000 }, { 10921, 0x0000 }, { 10921, 0x0400 }, + /* 0x20880 */ + { 10922, 0x0000 }, { 10922, 0x0000 }, { 10922, 0x0000 }, { 10922, 0x0200 }, + /* 0x20940 */ + { 10923, 0x0000 }, { 10923, 0x0000 }, { 10923, 0x0000 }, { 10923, 0x1000 }, + /* 0x20980 */ + { 10924, 0x0000 }, { 10924, 0x2000 }, { 10925, 0x0000 }, { 10925, 0x0000 }, + /* 0x20AC0 */ + { 10925, 0x0000 }, { 10925, 0x0008 }, { 10926, 0x0000 }, { 10926, 0x0000 }, + /* 0x20B00 */ + { 10926, 0x0000 }, { 10926, 0x2000 }, { 10927, 0x0000 }, { 10927, 0x0000 }, + /* 0x20B80 */ + { 10927, 0x0000 }, { 10927, 0x8000 }, { 10928, 0x0000 }, { 10928, 0x0000 }, + /* 0x20D40 */ + { 10928, 0x0020 }, { 10929, 0x0000 }, { 10929, 0x0000 }, { 10929, 0x0000 }, + /* 0x20DC0 */ + { 10929, 0x0000 }, { 10929, 0x0000 }, { 10929, 0x0002 }, { 10930, 0x0000 }, + /* 0x20E40 */ + { 10930, 0x0000 }, { 10930, 0x0000 }, { 10930, 0x2010 }, { 10932, 0x0000 }, + /* 0x20E80 */ + { 10932, 0x0000 }, { 10932, 0x0020 }, { 10933, 0x0000 }, { 10933, 0x0000 }, + /* 0x20F40 */ + { 10933, 0x0000 }, { 10933, 0x8000 }, { 10934, 0x0000 }, { 10934, 0x0000 }, + /* 0x21200 */ + { 10934, 0x0002 }, { 10935, 0x0000 }, { 10935, 0x0000 }, { 10935, 0x2000 }, + /* 0x21240 */ + { 10936, 0x0000 }, { 10936, 0x0020 }, { 10937, 0x0000 }, { 10937, 0x0810 }, + /* 0x212C0 */ + { 10939, 0x0000 }, { 10939, 0x0080 }, { 10940, 0x0010 }, { 10941, 0x2000 }, + /* 0x21300 */ + { 10942, 0x0000 }, { 10942, 0x0800 }, { 10943, 0x0000 }, { 10943, 0x0040 }, + /* 0x21340 */ + { 10944, 0x0010 }, { 10945, 0x0000 }, { 10945, 0x0000 }, { 10945, 0x0000 }, + /* 0x213C0 */ + { 10945, 0x0010 }, { 10946, 0x0000 }, { 10946, 0x0000 }, { 10946, 0x0000 }, + /* 0x21440 */ + { 10946, 0x0000 }, { 10946, 0x0000 }, { 10946, 0x6000 }, { 10948, 0x0000 }, + /* 0x215C0 */ + { 10948, 0x0000 }, { 10948, 0x0080 }, { 10949, 0x0000 }, { 10949, 0x0000 }, + /* 0x21640 */ + { 10949, 0x0080 }, { 10950, 0x0000 }, { 10950, 0x0000 }, { 10950, 0x0000 }, + /* 0x21680 */ + { 10950, 0x0000 }, { 10950, 0x0000 }, { 10950, 0x0000 }, { 10950, 0x0010 }, + /* 0x21700 */ + { 10951, 0x0040 }, { 10952, 0x0000 }, { 10952, 0x0000 }, { 10952, 0x0000 }, + /* 0x21740 */ + { 10952, 0x0004 }, { 10953, 0x0000 }, { 10953, 0x0000 }, { 10953, 0x0000 }, + /* 0x21880 */ + { 10953, 0x0000 }, { 10953, 0x0000 }, { 10953, 0x0000 }, { 10953, 0x2000 }, + /* 0x219C0 */ + { 10954, 0x0008 }, { 10955, 0x0000 }, { 10955, 0x0000 }, { 10955, 0x0000 }, + /* 0x21C40 */ + { 10955, 0x0000 }, { 10955, 0x0040 }, { 10956, 0x0000 }, { 10956, 0x0000 }, + /* 0x21D00 */ + { 10956, 0x0000 }, { 10956, 0x0000 }, { 10956, 0x2000 }, { 10957, 0x0000 }, + /* 0x21D40 */ + { 10957, 0x0020 }, { 10958, 0x0000 }, { 10958, 0x0004 }, { 10959, 0x0100 }, + /* 0x21D80 */ + { 10960, 0x0000 }, { 10960, 0x1004 }, { 10962, 0x0002 }, { 10963, 0x0080 }, + /* 0x21DC0 */ + { 10964, 0x0000 }, { 10964, 0x0000 }, { 10964, 0x0001 }, { 10965, 0x0000 }, + /* 0x21E00 */ + { 10965, 0x0000 }, { 10965, 0x0000 }, { 10965, 0x0000 }, { 10965, 0x0018 }, + /* 0x21F00 */ + { 10967, 0x0000 }, { 10967, 0x4000 }, { 10968, 0x0000 }, { 10968, 0x0000 }, + /* 0x21F40 */ + { 10968, 0x0000 }, { 10968, 0x0000 }, { 10968, 0x0000 }, { 10968, 0x0040 }, + /* 0x21FC0 */ + { 10969, 0x0000 }, { 10969, 0x0000 }, { 10969, 0x0000 }, { 10969, 0x0400 }, + /* 0x22140 */ + { 10970, 0x0000 }, { 10970, 0x0000 }, { 10970, 0x0000 }, { 10970, 0x0800 }, + /* 0x22200 */ + { 10971, 0x0000 }, { 10971, 0x0100 }, { 10972, 0x0000 }, { 10972, 0x0000 }, + /* 0x22300 */ + { 10972, 0x0000 }, { 10972, 0x4000 }, { 10973, 0x0000 }, { 10973, 0x0000 }, + /* 0x22380 */ + { 10973, 0x0000 }, { 10973, 0x0000 }, { 10973, 0x2000 }, { 10974, 0x0000 }, + /* 0x226C0 */ + { 10974, 0x0000 }, { 10974, 0x0000 }, { 10974, 0x0000 }, { 10974, 0x0008 }, + /* 0x22840 */ + { 10975, 0x0000 }, { 10975, 0x0800 }, { 10976, 0x0000 }, { 10976, 0x0000 }, + /* 0x22880 */ + { 10976, 0x0000 }, { 10976, 0x0000 }, { 10976, 0x0800 }, { 10977, 0x0000 }, + /* 0x22980 */ + { 10977, 0x8000 }, { 10978, 0x0000 }, { 10978, 0x0000 }, { 10978, 0x0000 }, + /* 0x22A80 */ + { 10978, 0x0000 }, { 10978, 0x0000 }, { 10978, 0x0000 }, { 10978, 0x0100 }, + /* 0x22B40 */ + { 10979, 0x8040 }, { 10981, 0x0001 }, { 10982, 0x0000 }, { 10982, 0x0000 }, + /* 0x22B80 */ + { 10982, 0x0000 }, { 10982, 0x0000 }, { 10982, 0x0040 }, { 10983, 0x0000 }, + /* 0x22C00 */ + { 10983, 0x0000 }, { 10983, 0x2000 }, { 10984, 0x0010 }, { 10985, 0x0000 }, + /* 0x22DC0 */ + { 10985, 0x0000 }, { 10985, 0x0000 }, { 10985, 0x0002 }, { 10986, 0x0000 }, + /* 0x23180 */ + { 10986, 0x0000 }, { 10986, 0x0000 }, { 10986, 0x0000 }, { 10986, 0x0040 }, + /* 0x231C0 */ + { 10987, 0x0018 }, { 10989, 0x0000 }, { 10989, 0x0000 }, { 10989, 0x0020 }, + /* 0x23340 */ + { 10990, 0x0000 }, { 10990, 0x0000 }, { 10990, 0x0000 }, { 10990, 0x0004 }, + /* 0x233C0 */ + { 10991, 0x0000 }, { 10991, 0x842d }, { 10997, 0x0010 }, { 10998, 0x0000 }, + /* 0x23440 */ + { 10998, 0x0c00 }, { 11000, 0x0002 }, { 11001, 0x0020 }, { 11002, 0x0000 }, + /* 0x234C0 */ + { 11002, 0x0000 }, { 11002, 0x0000 }, { 11002, 0x0010 }, { 11003, 0x0000 }, + /* 0x23540 */ + { 11003, 0x0000 }, { 11003, 0x0400 }, { 11004, 0x0000 }, { 11004, 0x0000 }, + /* 0x23580 */ + { 11004, 0x0000 }, { 11004, 0x0010 }, { 11005, 0x0000 }, { 11005, 0x0000 }, + /* 0x235C0 */ + { 11005, 0x0010 }, { 11006, 0x0000 }, { 11006, 0x0000 }, { 11006, 0x0000 }, + /* 0x23600 */ + { 11006, 0x0000 }, { 11006, 0x0000 }, { 11006, 0x0000 }, { 11006, 0x0700 }, + /* 0x23640 */ + { 11009, 0x0080 }, { 11010, 0x0000 }, { 11010, 0x0000 }, { 11010, 0x0000 }, + /* 0x23700 */ + { 11010, 0x1000 }, { 11011, 0x1000 }, { 11012, 0x0000 }, { 11012, 0x8000 }, + /* 0x23740 */ + { 11013, 0x0000 }, { 11013, 0x0000 }, { 11013, 0x0018 }, { 11015, 0x0000 }, + /* 0x237C0 */ + { 11015, 0x0000 }, { 11015, 0x0000 }, { 11015, 0x0080 }, { 11016, 0x8000 }, + /* 0x23800 */ + { 11017, 0x0000 }, { 11017, 0x0000 }, { 11017, 0x0010 }, { 11018, 0x2000 }, + /* 0x23A80 */ + { 11019, 0x0000 }, { 11019, 0x0100 }, { 11020, 0x0000 }, { 11020, 0x0000 }, + /* 0x23C40 */ + { 11020, 0x0000 }, { 11020, 0x0000 }, { 11020, 0x0000 }, { 11020, 0x8000 }, + /* 0x23CC0 */ + { 11021, 0x0000 }, { 11021, 0x0000 }, { 11021, 0x0000 }, { 11021, 0x4000 }, + /* 0x23D00 */ + { 11022, 0x4001 }, { 11024, 0x0000 }, { 11024, 0x0000 }, { 11024, 0x0000 }, + /* 0x23D40 */ + { 11024, 0x0001 }, { 11025, 0x0000 }, { 11025, 0x0000 }, { 11025, 0x0000 }, + /* 0x23DC0 */ + { 11025, 0x0000 }, { 11025, 0x0008 }, { 11026, 0x0000 }, { 11026, 0x0600 }, + /* 0x23F40 */ + { 11028, 0x0000 }, { 11028, 0x0000 }, { 11028, 0x0000 }, { 11028, 0x4000 }, + /* 0x24080 */ + { 11029, 0x0000 }, { 11029, 0x0040 }, { 11030, 0x0000 }, { 11030, 0x0000 }, + /* 0x24100 */ + { 11030, 0x0008 }, { 11031, 0x0000 }, { 11031, 0x0000 }, { 11031, 0x0000 }, + /* 0x241C0 */ + { 11031, 0x0040 }, { 11032, 0x0000 }, { 11032, 0x0000 }, { 11032, 0x4000 }, + /* 0x24380 */ + { 11033, 0x0000 }, { 11033, 0x0000 }, { 11033, 0x0000 }, { 11033, 0x1000 }, + /* 0x24600 */ + { 11034, 0x0000 }, { 11034, 0x0000 }, { 11034, 0x0200 }, { 11035, 0x0000 }, + /* 0x24680 */ + { 11035, 0x0000 }, { 11035, 0x0000 }, { 11035, 0x0020 }, { 11036, 0x0000 }, + /* 0x247C0 */ + { 11036, 0x0000 }, { 11036, 0x0000 }, { 11036, 0x0000 }, { 11036, 0x0002 }, + /* 0x24880 */ + { 11037, 0x0000 }, { 11037, 0x0040 }, { 11038, 0x0000 }, { 11038, 0x0000 }, + /* 0x24A40 */ + { 11038, 0x2000 }, { 11039, 0x0000 }, { 11039, 0x0000 }, { 11039, 0x0000 }, + /* 0x24B40 */ + { 11039, 0x0000 }, { 11039, 0x0040 }, { 11040, 0x8000 }, { 11041, 0x0000 }, + /* 0x24C00 */ + { 11041, 0x0000 }, { 11041, 0x0040 }, { 11042, 0x0000 }, { 11042, 0x0000 }, + /* 0x24D00 */ + { 11042, 0x0000 }, { 11042, 0x0010 }, { 11043, 0x0000 }, { 11043, 0x0000 }, + /* 0x24E00 */ + { 11043, 0x4000 }, { 11044, 0x0000 }, { 11044, 0x0000 }, { 11044, 0x0080 }, + /* 0x24E40 */ + { 11045, 0x0000 }, { 11045, 0x0000 }, { 11045, 0x0400 }, { 11046, 0x0000 }, + /* 0x24E80 */ + { 11046, 0x0800 }, { 11047, 0x0000 }, { 11047, 0x0000 }, { 11047, 0x0000 }, + /* 0x25040 */ + { 11047, 0x0400 }, { 11048, 0x0020 }, { 11049, 0x0000 }, { 11049, 0x0000 }, + /* 0x25100 */ + { 11049, 0x0000 }, { 11049, 0x0000 }, { 11049, 0x0004 }, { 11050, 0x0000 }, + /* 0x25180 */ + { 11050, 0x0000 }, { 11050, 0x0000 }, { 11050, 0x0200 }, { 11051, 0x0000 }, + /* 0x251C0 */ + { 11051, 0x2000 }, { 11052, 0x0000 }, { 11052, 0x0020 }, { 11053, 0x0000 }, + /* 0x25200 */ + { 11053, 0x0000 }, { 11053, 0x4000 }, { 11054, 0x0000 }, { 11054, 0x0000 }, + /* 0x25240 */ + { 11054, 0x1000 }, { 11055, 0x0000 }, { 11055, 0x0000 }, { 11055, 0x0000 }, + /* 0x25400 */ + { 11055, 0x0000 }, { 11055, 0x0000 }, { 11055, 0x4000 }, { 11056, 0x0000 }, + /* 0x25480 */ + { 11056, 0x4000 }, { 11057, 0x0000 }, { 11057, 0x0000 }, { 11057, 0x0000 }, + /* 0x254C0 */ + { 11057, 0x0000 }, { 11057, 0x0200 }, { 11058, 0x0000 }, { 11058, 0x0000 }, + /* 0x25500 */ + { 11058, 0x4000 }, { 11059, 0x0000 }, { 11059, 0x0000 }, { 11059, 0x0000 }, + /* 0x25580 */ + { 11059, 0x0000 }, { 11059, 0x0000 }, { 11059, 0x0080 }, { 11060, 0x0000 }, + /* 0x25740 */ + { 11060, 0x0000 }, { 11060, 0x0000 }, { 11060, 0x0000 }, { 11060, 0x0002 }, + /* 0x25780 */ + { 11061, 0x0000 }, { 11061, 0x0000 }, { 11061, 0x0200 }, { 11062, 0x0010 }, + /* 0x259C0 */ + { 11063, 0x0010 }, { 11064, 0x0010 }, { 11065, 0x0000 }, { 11065, 0x0000 }, + /* 0x25AC0 */ + { 11065, 0x0000 }, { 11065, 0x0000 }, { 11065, 0x0018 }, { 11067, 0x0002 }, + /* 0x25B80 */ + { 11068, 0x0000 }, { 11068, 0x0000 }, { 11068, 0x0000 }, { 11068, 0x0004 }, + /* 0x25C40 */ + { 11069, 0x0800 }, { 11070, 0x0000 }, { 11070, 0x0010 }, { 11071, 0x0000 }, + /* 0x25D80 */ + { 11071, 0x0000 }, { 11071, 0x0000 }, { 11071, 0x0002 }, { 11072, 0x0000 }, + /* 0x25E00 */ + { 11072, 0x0000 }, { 11072, 0x0000 }, { 11072, 0x4000 }, { 11073, 0x0000 }, + /* 0x25E40 */ + { 11073, 0x0000 }, { 11073, 0x0040 }, { 11074, 0x0024 }, { 11076, 0x0000 }, + /* 0x25EC0 */ + { 11076, 0x0004 }, { 11077, 0x0100 }, { 11078, 0x0100 }, { 11079, 0x0000 }, + /* 0x25F00 */ + { 11079, 0x0000 }, { 11079, 0x0000 }, { 11079, 0x0008 }, { 11080, 0x0000 }, + /* 0x25F40 */ + { 11080, 0x0000 }, { 11080, 0x1000 }, { 11081, 0x0000 }, { 11081, 0x0000 }, + /* 0x25FC0 */ + { 11081, 0x0000 }, { 11081, 0x0010 }, { 11082, 0x0001 }, { 11083, 0x0800 }, + /* 0x26000 */ + { 11084, 0x1000 }, { 11085, 0x0080 }, { 11086, 0x0000 }, { 11086, 0x0000 }, + /* 0x26040 */ + { 11086, 0x0000 }, { 11086, 0x0000 }, { 11086, 0x0001 }, { 11087, 0x0000 }, + /* 0x260C0 */ + { 11087, 0x0000 }, { 11087, 0x0000 }, { 11087, 0x2000 }, { 11088, 0x0000 }, + /* 0x26240 */ + { 11088, 0x0000 }, { 11088, 0x0000 }, { 11088, 0x0000 }, { 11088, 0x0001 }, + /* 0x26280 */ + { 11089, 0x0040 }, { 11090, 0x0000 }, { 11090, 0x0000 }, { 11090, 0x0000 }, + /* 0x26340 */ + { 11090, 0x1000 }, { 11091, 0x0000 }, { 11091, 0x0000 }, { 11091, 0x0000 }, + /* 0x26400 */ + { 11091, 0x0004 }, { 11092, 0x0000 }, { 11092, 0x0000 }, { 11092, 0x0000 }, + /* 0x26640 */ + { 11092, 0x0000 }, { 11092, 0x0000 }, { 11092, 0x0000 }, { 11092, 0x4000 }, + /* 0x26680 */ + { 11093, 0x0000 }, { 11093, 0x0000 }, { 11093, 0x0000 }, { 11093, 0x0001 }, + /* 0x26700 */ + { 11094, 0x0000 }, { 11094, 0x2000 }, { 11095, 0x0000 }, { 11095, 0x0000 }, + /* 0x268C0 */ + { 11095, 0x0000 }, { 11095, 0x2000 }, { 11096, 0x0400 }, { 11097, 0x0000 }, + /* 0x26940 */ + { 11097, 0x0000 }, { 11097, 0x0002 }, { 11098, 0x8000 }, { 11099, 0x0000 }, + /* 0x269C0 */ + { 11099, 0x0000 }, { 11099, 0x2000 }, { 11100, 0x0000 }, { 11100, 0x0000 }, + /* 0x26A00 */ + { 11100, 0x0000 }, { 11100, 0x4000 }, { 11101, 0x0000 }, { 11101, 0x0000 }, + /* 0x26A40 */ + { 11101, 0x0000 }, { 11101, 0x0100 }, { 11102, 0x0000 }, { 11102, 0x0000 }, + /* 0x26A80 */ + { 11102, 0x1000 }, { 11103, 0x0000 }, { 11103, 0x0000 }, { 11103, 0x0080 }, + /* 0x26AC0 */ + { 11104, 0x0000 }, { 11104, 0x0000 }, { 11104, 0x0000 }, { 11104, 0x8000 }, + /* 0x26C00 */ + { 11105, 0x0000 }, { 11105, 0x0000 }, { 11105, 0x0200 }, { 11106, 0x0000 }, + /* 0x26C40 */ + { 11106, 0x0000 }, { 11106, 0x0000 }, { 11106, 0x0000 }, { 11106, 0x0008 }, + /* 0x26CC0 */ + { 11107, 0x0000 }, { 11107, 0x2000 }, { 11108, 0x0000 }, { 11108, 0x0000 }, + /* 0x26E40 */ + { 11108, 0x0001 }, { 11109, 0x0000 }, { 11109, 0x0020 }, { 11110, 0x0000 }, + /* 0x26F80 */ + { 11110, 0x0000 }, { 11110, 0x0010 }, { 11111, 0x0000 }, { 11111, 0x0000 }, + /* 0x26FC0 */ + { 11111, 0x0000 }, { 11111, 0x0000 }, { 11111, 0x0000 }, { 11111, 0x01c0 }, + /* 0x270C0 */ + { 11114, 0x0000 }, { 11114, 0x0000 }, { 11114, 0x0000 }, { 11114, 0x0010 }, + /* 0x27100 */ + { 11115, 0x2000 }, { 11116, 0x0000 }, { 11116, 0x0000 }, { 11116, 0x0200 }, + /* 0x273C0 */ + { 11117, 0x0000 }, { 11117, 0x0c00 }, { 11119, 0x0000 }, { 11119, 0x4000 }, + /* 0x27400 */ + { 11120, 0x0000 }, { 11120, 0x0001 }, { 11121, 0x0000 }, { 11121, 0x0000 }, + /* 0x27440 */ + { 11121, 0x0200 }, { 11122, 0x0000 }, { 11122, 0x0000 }, { 11122, 0x0000 }, + /* 0x27600 */ + { 11122, 0x0000 }, { 11122, 0x0030 }, { 11124, 0x0000 }, { 11124, 0x0002 }, + /* 0x27680 */ + { 11125, 0x0010 }, { 11126, 0x0008 }, { 11127, 0x0000 }, { 11127, 0x0000 }, + /* 0x27700 */ + { 11127, 0x4000 }, { 11128, 0x0000 }, { 11128, 0x0008 }, { 11129, 0x0000 }, + /* 0x27740 */ + { 11129, 0x0000 }, { 11129, 0x0004 }, { 11130, 0x0000 }, { 11130, 0x0000 }, + /* 0x27980 */ + { 11130, 0x0020 }, { 11131, 0x0000 }, { 11131, 0x0000 }, { 11131, 0x0000 }, + /* 0x27A80 */ + { 11131, 0x0010 }, { 11132, 0x0000 }, { 11132, 0x0000 }, { 11132, 0x0000 }, + /* 0x27B80 */ + { 11132, 0x0000 }, { 11132, 0x0000 }, { 11132, 0x0000 }, { 11132, 0x4008 }, + /* 0x27BC0 */ + { 11134, 0x0080 }, { 11135, 0x0000 }, { 11135, 0x0000 }, { 11135, 0x0000 }, + /* 0x27C80 */ + { 11135, 0x0000 }, { 11135, 0x0000 }, { 11135, 0x0000 }, { 11135, 0x0100 }, + /* 0x27D80 */ + { 11136, 0x0000 }, { 11136, 0x0000 }, { 11136, 0x0001 }, { 11137, 0x0000 }, + /* 0x27E00 */ + { 11137, 0x0000 }, { 11137, 0x0001 }, { 11138, 0x0000 }, { 11138, 0x0000 }, + /* 0x27F80 */ + { 11138, 0x0000 }, { 11138, 0x0000 }, { 11138, 0x0000 }, { 11138, 0x0080 }, + /* 0x28080 */ + { 11139, 0x0400 }, { 11140, 0x0000 }, { 11140, 0x0000 }, { 11140, 0x0800 }, + /* 0x28240 */ + { 11141, 0x0000 }, { 11141, 0x0000 }, { 11141, 0x0000 }, { 11141, 0x0080 }, + /* 0x28280 */ + { 11142, 0x0004 }, { 11143, 0x0000 }, { 11143, 0x0000 }, { 11143, 0x0000 }, + /* 0x282C0 */ + { 11143, 0x0000 }, { 11143, 0x0000 }, { 11143, 0x0000 }, { 11143, 0x0008 }, + /* 0x283C0 */ + { 11144, 0x2000 }, { 11145, 0x0000 }, { 11145, 0x0000 }, { 11145, 0x0000 }, + /* 0x28400 */ + { 11145, 0x1000 }, { 11146, 0x0000 }, { 11146, 0x0000 }, { 11146, 0x0000 }, + /* 0x28440 */ + { 11146, 0x0000 }, { 11146, 0x0020 }, { 11147, 0x0000 }, { 11147, 0x0000 }, + /* 0x28540 */ + { 11147, 0x0000 }, { 11147, 0x0000 }, { 11147, 0x0800 }, { 11148, 0x0000 }, + /* 0x285C0 */ + { 11148, 0x0300 }, { 11150, 0x0000 }, { 11150, 0x0000 }, { 11150, 0x0000 }, + /* 0x286C0 */ + { 11150, 0x0000 }, { 11150, 0x0080 }, { 11151, 0x0000 }, { 11151, 0x0400 }, + /* 0x28940 */ + { 11152, 0x0240 }, { 11154, 0x0000 }, { 11154, 0x0800 }, { 11155, 0x0000 }, + /* 0x28980 */ + { 11155, 0x0180 }, { 11157, 0x0000 }, { 11157, 0x0000 }, { 11157, 0x0c00 }, + /* 0x28A00 */ + { 11159, 0x0000 }, { 11159, 0x4000 }, { 11160, 0x0200 }, { 11161, 0x0000 }, + /* 0x28A40 */ + { 11161, 0x0008 }, { 11162, 0x0000 }, { 11162, 0x0000 }, { 11162, 0x0002 }, + /* 0x28A80 */ + { 11163, 0x0000 }, { 11163, 0x0200 }, { 11164, 0x0000 }, { 11164, 0x0000 }, + /* 0x28AC0 */ + { 11164, 0x2000 }, { 11165, 0x2000 }, { 11166, 0x0010 }, { 11167, 0x0000 }, + /* 0x28BC0 */ + { 11167, 0x0002 }, { 11168, 0x0000 }, { 11168, 0x8000 }, { 11169, 0x0000 }, + /* 0x28D00 */ + { 11169, 0x0000 }, { 11169, 0x0001 }, { 11170, 0x0000 }, { 11170, 0x0000 }, + /* 0x28D40 */ + { 11170, 0x0000 }, { 11170, 0x0000 }, { 11170, 0x0000 }, { 11170, 0x0002 }, + /* 0x28DC0 */ + { 11171, 0x0000 }, { 11171, 0x0000 }, { 11171, 0x0000 }, { 11171, 0x0800 }, + /* 0x28E00 */ + { 11172, 0x0000 }, { 11172, 0x8000 }, { 11173, 0x0000 }, { 11173, 0x0040 }, + /* 0x28E80 */ + { 11174, 0x0200 }, { 11175, 0x0000 }, { 11175, 0x0000 }, { 11175, 0x0000 }, + /* 0x28EC0 */ + { 11175, 0x0000 }, { 11175, 0x0000 }, { 11175, 0x0800 }, { 11176, 0x0000 }, + /* 0x28F00 */ + { 11176, 0x0000 }, { 11176, 0x0000 }, { 11176, 0x0000 }, { 11176, 0x0004 }, + /* 0x28FC0 */ + { 11177, 0x0000 }, { 11177, 0x0000 }, { 11177, 0x0000 }, { 11177, 0x0100 }, + /* 0x29280 */ + { 11178, 0x0000 }, { 11178, 0x0000 }, { 11178, 0x0001 }, { 11179, 0x0002 }, + /* 0x29480 */ + { 11180, 0x0000 }, { 11180, 0x0001 }, { 11181, 0x0000 }, { 11181, 0x0000 }, + /* 0x295C0 */ + { 11181, 0x8000 }, { 11182, 0x0000 }, { 11182, 0x0000 }, { 11182, 0x0000 }, + /* 0x29640 */ + { 11182, 0x0000 }, { 11182, 0x0000 }, { 11182, 0x0000 }, { 11182, 0x8000 }, + /* 0x296C0 */ + { 11183, 0x0000 }, { 11183, 0x0000 }, { 11183, 0x0000 }, { 11183, 0x0001 }, + /* 0x29700 */ + { 11184, 0x0000 }, { 11184, 0x0200 }, { 11185, 0x0000 }, { 11185, 0x0000 }, + /* 0x29740 */ + { 11185, 0x0000 }, { 11185, 0x0001 }, { 11186, 0x0000 }, { 11186, 0x0000 }, + /* 0x298C0 */ + { 11186, 0x0040 }, { 11187, 0x0000 }, { 11187, 0x0000 }, { 11187, 0x0000 }, + /* 0x29A40 */ + { 11187, 0x0000 }, { 11187, 0x0000 }, { 11187, 0x0000 }, { 11187, 0x0004 }, + /* 0x29DC0 */ + { 11188, 0x0000 }, { 11188, 0x0800 }, { 11189, 0x0000 }, { 11189, 0x0000 }, + /* 0x29E00 */ + { 11189, 0x0000 }, { 11189, 0x0020 }, { 11190, 0x0000 }, { 11190, 0x2000 }, + /* 0x29E40 */ + { 11191, 0x0200 }, { 11192, 0x0000 }, { 11192, 0x0000 }, { 11192, 0x0000 }, + /* 0x29E80 */ + { 11192, 0x0400 }, { 11193, 0x0000 }, { 11193, 0x0000 }, { 11193, 0x0000 }, + /* 0x29EC0 */ + { 11193, 0x0010 }, { 11194, 0x0800 }, { 11195, 0x0200 }, { 11196, 0x0000 }, + /* 0x29FC0 */ + { 11196, 0x4000 }, { 11197, 0x0000 }, { 11197, 0x0000 }, { 11197, 0x0000 }, + /* 0x2A000 */ + { 11197, 0x0000 }, { 11197, 0x0400 }, { 11198, 0x8000 }, { 11199, 0x0000 }, + /* 0x2A080 */ + { 11199, 0x0004 }, { 11200, 0x0000 }, { 11200, 0x0000 }, { 11200, 0x0000 }, + /* 0x2A0C0 */ + { 11200, 0x0000 }, { 11200, 0x0000 }, { 11200, 0x0000 }, { 11200, 0x0200 }, + /* 0x2A180 */ + { 11201, 0x0000 }, { 11201, 0x0001 }, { 11202, 0x0000 }, { 11202, 0x0000 }, + /* 0x2A380 */ + { 11202, 0x1000 }, { 11203, 0x0000 }, { 11203, 0x0000 }, { 11203, 0x0000 }, + /* 0x2A400 */ + { 11203, 0x0000 }, { 11203, 0x0000 }, { 11203, 0x0000 }, { 11203, 0x0080 }, + /* 0x2A5C0 */ + { 11204, 0x0000 }, { 11204, 0x0000 }, { 11204, 0x0000 }, { 11204, 0x0002 }, + /* 0x2A600 */ + { 11205, 0x0004 }, { 11206, 0x0400 }, { 11207, 0x0000 }, { 11207, 0x0000 }, + /* 0x2A680 */ + { 11207, 0x0000 }, { 11207, 0x0000 }, { 11207, 0x0000 }, { 11207, 0x0004 }, +}; + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static ucs4_t jisx0213_to_ucs4 (unsigned int row, unsigned int col) +{ + ucs4_t val; + + if (row >= 0x121 && row <= 0x17e) + row -= 289; + else if (row == 0x221) + row -= 451; + else if (row >= 0x223 && row <= 0x225) + row -= 452; + else if (row == 0x228) + row -= 454; + else if (row >= 0x22c && row <= 0x22f) + row -= 457; + else if (row >= 0x26e && row <= 0x27e) + row -= 519; + else + return 0x0000; + + if (col >= 0x21 && col <= 0x7e) + col -= 0x21; + else + return 0x0000; + + val = jisx0213_to_ucs_main[row * 94 + col]; + val = jisx0213_to_ucs_pagestart[val >> 8] + (val & 0xff); + if (val == 0xfffd) + val = 0x0000; + return val; +} + +#ifdef __GNUC__ +__inline +#else +#ifdef __cplusplus +inline +#endif +#endif +static unsigned short ucs4_to_jisx0213 (ucs4_t ucs) +{ + if (ucs < (sizeof(jisx0213_from_ucs_level1)/sizeof(jisx0213_from_ucs_level1[0])) << 6) { + int index1 = jisx0213_from_ucs_level1[ucs >> 6]; + if (index1 >= 0) { + const Summary16 *summary = &jisx0213_from_ucs_level2_2indx[((index1 << 6) + (ucs & 0x3f)) >> 4]; + unsigned short used = summary->used; + unsigned int i = ucs & 0x0f; + if (used & ((unsigned short) 1 << i)) { + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + return jisx0213_from_ucs_level2_data[summary->indx + used]; + }; + }; + } + return 0x0000; +} + +#endif /* _JISX0213_H */ diff --git a/libs/libiconv/lib/johab.h b/libs/libiconv/lib/johab.h new file mode 100644 index 00000000..fb2c17f5 --- /dev/null +++ b/libs/libiconv/lib/johab.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 1999-2001, 2007 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * JOHAB + */ + +/* + Conversion between JOHAB codes (s1,s2) and KSX1001 codes (c1,c2): + Example. (s1,s2) = 0xD931, (c1,c2) = 0x2121. + (s1,s2) = 0xDEF1, (c1,c2) = 0x2C71. + (s1,s2) = 0xE031, (c1,c2) = 0x4A21. + (s1,s2) = 0xF9FE, (c1,c2) = 0x7D7E. + 0xD9 <= s1 <= 0xDE || 0xE0 <= s1 <= 0xF9, + 0x31 <= s2 <= 0x7E || 0x91 <= s2 <= 0xFE, + 0x21 <= c1 <= 0x2C || 0x4A <= c1 <= 0x7D, + 0x21 <= c2 <= 0x7E. + Invariant: + 94*(s1 < 0xE0 ? 2*s1-0x1B2 : 2*s1-0x197) + (s2 < 0x91 ? s2-0x31 : s2-0x43) + = 94*(c1-0x21)+(c2-0x21) + Conversion (s1,s2) -> (c1,c2): + t1 := (s1 < 0xE0 ? 2*s1-0x1B2 : 2*s1-0x197) + t2 := (s2 < 0x91 ? s2-0x31 : s2-0x43) + c1 := t1 + (t2 < 0x5E ? 0 : 1) + 0x21 + c2 := (t2 < 0x5E ? t2 : t2-0x5E) + 0x21 + Conversion (c1,c2) -> (s1,s2): + t := (c1 < 0x4A ? (c1-0x21+0x1B2) : (c1-0x21+0x197)) + s1 := t >> 1 + t2 := (t & 1) * 0x5E + (c2 - 0x21) + s2 := (t2 < 0x4E ? t2+0x31 : t2+0x43) + */ + +static int +johab_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + if (c == 0x5c) + *pwc = (ucs4_t) 0x20a9; + else + *pwc = (ucs4_t) c; + return 1; + } else if (c < 0xd8) { + return johab_hangul_mbtowc(conv,pwc,s,n); + } else { + unsigned char s1, s2; + s1 = c; + if ((s1 >= 0xd9 && s1 <= 0xde) || (s1 >= 0xe0 && s1 <= 0xf9)) { + if (n < 2) + return RET_TOOFEW(0); + s2 = s[1]; + if ((s2 >= 0x31 && s2 <= 0x7e) || (s2 >= 0x91 && s2 <= 0xfe)) { + /* In KSC 5601, now KS X 1001, the region s1 = 0xDA, 0xA1 <= s2 <= 0xD3 + contains the 51 Jamo (Hangul letters). But in the Johab encoding, + they have been moved to the Hangul section, see + johab_hangul_page31. */ + if (!(s1 == 0xda && (s2 >= 0xa1 && s2 <= 0xd3))) { + unsigned char t1 = (s1 < 0xe0 ? 2*(s1-0xd9) : 2*s1-0x197); + unsigned char t2 = (s2 < 0x91 ? s2-0x31 : s2-0x43); + unsigned char buf[2]; + buf[0] = t1 + (t2 < 0x5e ? 0 : 1) + 0x21; + buf[1] = (t2 < 0x5e ? t2 : t2-0x5e) + 0x21; + return ksc5601_mbtowc(conv,pwc,buf,2); + } + } + } + return RET_ILSEQ; + } +} + +static int +johab_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[2]; + int ret; + + /* Try ASCII variation. */ + if (wc < 0x0080 && wc != 0x005c) { + *r = wc; + return 1; + } + if (wc == 0x20a9) { + *r = 0x5c; + return 1; + } + + /* Try JOHAB Hangul table before KSC5601 table, because the KSC5601 table + contains some (2350 out of 11172) Hangul syllables (rows 0x30XX..0x48XX), + and we want the search to return the JOHAB Hangul table entry. */ + + /* Try JOHAB Hangul. */ + ret = johab_hangul_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + r[0] = buf[0]; + r[1] = buf[1]; + return 2; + } + + /* Try KSC5601, now KS X 1001. */ + ret = ksc5601_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + unsigned char c1, c2; + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + c1 = buf[0]; + c2 = buf[1]; + if (((c1 >= 0x21 && c1 <= 0x2c) || (c1 >= 0x4a && c1 <= 0x7d)) + && (c2 >= 0x21 && c2 <= 0x7e)) { + unsigned int t = (c1 < 0x4A ? (c1-0x21+0x1B2) : (c1-0x21+0x197)); + unsigned char t2 = ((t & 1) ? 0x5e : 0) + (c2 - 0x21); + r[0] = t >> 1; + r[1] = (t2 < 0x4e ? t2+0x31 : t2+0x43); + return 2; + } + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/johab_hangul.h b/libs/libiconv/lib/johab_hangul.h new file mode 100644 index 00000000..68368dff --- /dev/null +++ b/libs/libiconv/lib/johab_hangul.h @@ -0,0 +1,262 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * JOHAB Hangul + * + * Ken Lunde writes in his "CJKV Information Processing" book, p. 114: + * "Hangul can be composed of two or three jamo (some jamo are considered + * compound). Johab uses 19 initial jamo (consonants), 21 medial jamo (vowels) + * and 27 final jamo (consonants; 28 when you include the "fill" character + * for Hangul containing only two jamo). Multiplying these numbers results in + * 11172." + * + * Structure of the Johab encoding (see p. 181-184): + * bit 15 = 1 + * bit 14..10 = initial jamo, only 19+1 out of 32 possible values are used + * bit 9..5 = medial jamo, only 21+1 out of 32 possible values are used + * bit 4..0 = final jamo, only 27+1 out of 32 possible values are used + * + * Structure of the Unicode encoding: + * grep '^0x\([8-C]...\|D[0-7]..\)' unicode.org-mappings/EASTASIA/KSC/JOHAB.TXT + * You see that all characters there are marked "HANGUL LETTER" or "HANGUL + * SYLLABLE". If you eliminate the "HANGUL LETTER"s, the table is sorted + * in ascending order according to Johab encoding and according to the Unicode + * encoding. Now look a little more carefully, and you see that the following + * formula holds: + * unicode == 0xAC00 + * + 21 * 28 * (jamo_initial_index[(johab >> 10) & 31] - 1) + * + 28 * (jamo_medial_index[(johab >> 5) & 31] - 1) + * + jamo_final_index[johab & 31] + * where the index tables are defined as below. + */ + +/* Tables mapping 5-bit groups to jamo letters. */ +/* Note that Jamo XX = UHC 0xA4A0+XX = Unicode 0x3130+XX */ +#define NONE 0xfd +#define FILL 0xff +static const unsigned char jamo_initial[32] = { + NONE, FILL, 0x01, 0x02, 0x04, 0x07, 0x08, 0x09, + 0x11, 0x12, 0x13, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, +}; +static const unsigned char jamo_medial[32] = { + NONE, NONE, FILL, 0x1f, 0x20, 0x21, 0x22, 0x23, + NONE, NONE, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + NONE, NONE, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + NONE, NONE, 0x30, 0x31, 0x32, 0x33, NONE, NONE, +}; +static const unsigned char jamo_final[32] = { + NONE, FILL, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, NONE, 0x12, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, NONE, NONE, +}; +/* Same as jamo_final, except that it excludes characters already + contained in jamo_initial. 11 characters instead of 27. */ +static const unsigned char jamo_final_notinitial[32] = { + NONE, NONE, NONE, NONE, 0x03, NONE, 0x05, 0x06, + NONE, NONE, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, NONE, NONE, NONE, 0x14, NONE, NONE, NONE, + NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, +}; + +/* Tables mapping 5-bit groups to packed indices. */ +#define none -1 +#define fill 0 +static const signed char jamo_initial_index[32] = { + none, fill, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, none, none, none, + none, none, none, none, none, none, none, none, +}; +static const signed char jamo_medial_index[32] = { + none, none, fill, 0x01, 0x02, 0x03, 0x04, 0x05, + none, none, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, + none, none, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + none, none, 0x12, 0x13, 0x14, 0x15, none, none, +}; +static const signed char jamo_final_index[32] = { + none, fill, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, none, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, none, none, +}; + +static int +johab_hangul_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x84 && c1 <= 0xd3)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x41 && c2 < 0x7f) || (c2 >= 0x81 && c2 < 0xff)) { + unsigned int johab = (c1 << 8) | c2; + unsigned int bitspart1 = (johab >> 10) & 31; + unsigned int bitspart2 = (johab >> 5) & 31; + unsigned int bitspart3 = johab & 31; + int index1 = jamo_initial_index[bitspart1]; + int index2 = jamo_medial_index[bitspart2]; + int index3 = jamo_final_index[bitspart3]; + /* Exclude "none" values. */ + if (index1 >= 0 && index2 >= 0 && index3 >= 0) { + /* Deal with "fill" values in initial or medial position. */ + if (index1 == fill) { + if (index2 == fill) { + unsigned char jamo3 = jamo_final_notinitial[bitspart3]; + if (jamo3 != NONE) { + *pwc = (ucs4_t) 0x3130 + jamo3; + return 2; + } + } else if (index3 == fill) { + unsigned char jamo2 = jamo_medial[bitspart2]; + if (jamo2 != NONE && jamo2 != FILL) { + *pwc = (ucs4_t) 0x3130 + jamo2; + return 2; + } + } + /* Syllables composed only of medial and final don't exist. */ + } else if (index2 == fill) { + if (index3 == fill) { + unsigned char jamo1 = jamo_initial[bitspart1]; + if (jamo1 != NONE && jamo1 != FILL) { + *pwc = (ucs4_t) 0x3130 + jamo1; + return 2; + } + } + /* Syllables composed only of initial and final don't exist. */ + } else { + /* index1 and index2 are not fill, but index3 may be fill. */ + /* Nothing more to exclude. All 11172 code points are valid. */ + *pwc = 0xac00 + ((index1 - 1) * 21 + (index2 - 1)) * 28 + index3; + return 2; + } + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +/* 51 Jamo: 19 initial, 21 medial, 11 final not initial. */ +static const unsigned short johab_hangul_page31[51] = { + 0x8841, 0x8c41, 0x8444, 0x9041, 0x8446, 0x8447, 0x9441, /*0x30-0x37*/ + 0x9841, 0x9c41, 0x844a, 0x844b, 0x844c, 0x844d, 0x844e, 0x844f, /*0x38-0x3f*/ + 0x8450, 0xa041, 0xa441, 0xa841, 0x8454, 0xac41, 0xb041, 0xb441, /*0x40-0x47*/ + 0xb841, 0xbc41, 0xc041, 0xc441, 0xc841, 0xcc41, 0xd041, 0x8461, /*0x48-0x4f*/ + 0x8481, 0x84a1, 0x84c1, 0x84e1, 0x8541, 0x8561, 0x8581, 0x85a1, /*0x50-0x57*/ + 0x85c1, 0x85e1, 0x8641, 0x8661, 0x8681, 0x86a1, 0x86c1, 0x86e1, /*0x58-0x5f*/ + 0x8741, 0x8761, 0x8781, 0x87a1, /*0x60-0x67*/ +}; + +/* Tables mapping packed indices to 5-bit groups. */ +/* index1+1 = jamo_initial_index[bitspart1] <==> + bitspart1 = jamo_initial_index_inverse[index1] */ +static const char jamo_initial_index_inverse[19] = { + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, +}; +/* index2+1 = jamo_medial_index[bitspart2] <==> + bitspart2 = jamo_medial_index_inverse[index2] */ +static const char jamo_medial_index_inverse[21] = { + 0x03, 0x04, 0x05, 0x06, 0x07, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x1a, 0x1b, 0x1c, 0x1d, +}; +/* index3 = jamo_final_index[bitspart3] <==> + bitspart3 = jamo_final_index_inverse[index3] */ +static const char jamo_final_index_inverse[28] = { + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, +}; + +static int +johab_hangul_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + if (wc >= 0x3131 && wc < 0x3164) { + unsigned short c = johab_hangul_page31[wc-0x3131]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } else if (wc >= 0xac00 && wc < 0xd7a4) { + unsigned int index1; + unsigned int index2; + unsigned int index3; + unsigned short c; + unsigned int tmp = wc - 0xac00; + index3 = tmp % 28; tmp = tmp / 28; + index2 = tmp % 21; tmp = tmp / 21; + index1 = tmp; + c = (((((1 << 5) + | jamo_initial_index_inverse[index1]) << 5) + | jamo_medial_index_inverse[index2]) << 5) + | jamo_final_index_inverse[index3]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} + +/* + * Decomposition of JOHAB Hangul in one to three Johab Jamo elements. + */ + +/* Decompose wc into r[0..2], and return the number of resulting Jamo elements. + Return RET_ILUNI if decomposition is not possible. */ + +static int johab_hangul_decompose (conv_t conv, ucs4_t* r, ucs4_t wc) +{ + unsigned char buf[2]; + int ret = johab_hangul_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + unsigned int hangul = (buf[0] << 8) | buf[1]; + unsigned char jamo1 = jamo_initial[(hangul >> 10) & 31]; + unsigned char jamo2 = jamo_medial[(hangul >> 5) & 31]; + unsigned char jamo3 = jamo_final[hangul & 31]; + if ((hangul >> 15) != 1) abort(); + if (jamo1 != NONE && jamo2 != NONE && jamo3 != NONE) { + /* They are not all three == FILL because that would correspond to + johab = 0x8441, which doesn't exist. */ + ucs4_t* p = r; + if (jamo1 != FILL) + *p++ = 0x3130 + jamo1; + if (jamo2 != FILL) + *p++ = 0x3130 + jamo2; + if (jamo3 != FILL) + *p++ = 0x3130 + jamo3; + return p-r; + } + } + return RET_ILUNI; +} + +#undef fill +#undef none +#undef FILL +#undef NONE diff --git a/libs/libiconv/lib/koi8_r.h b/libs/libiconv/lib/koi8_r.h new file mode 100644 index 00000000..3e435368 --- /dev/null +++ b/libs/libiconv/lib/koi8_r.h @@ -0,0 +1,153 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * KOI8-R + */ + +/* Specification: RFC 1489 */ + +static const unsigned short koi8_r_2uni[128] = { + /* 0x80 */ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + /* 0x90 */ + 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248, + 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, + /* 0xa0 */ + 0x2550, 0x2551, 0x2552, 0x0451, 0x2553, 0x2554, 0x2555, 0x2556, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x255c, 0x255d, 0x255e, + /* 0xb0 */ + 0x255f, 0x2560, 0x2561, 0x0401, 0x2562, 0x2563, 0x2564, 0x2565, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x00a9, + /* 0xc0 */ + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + /* 0xd0 */ + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + /* 0xe0 */ + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + /* 0xf0 */ + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a, +}; + +static int +koi8_r_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) koi8_r_2uni[c-0x80]; + return 1; +} + +static const unsigned char koi8_r_page00[88] = { + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x9c, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, /* 0xf0-0xf7 */ +}; +static const unsigned char koi8_r_page04[88] = { + 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa, /* 0x10-0x17 */ + 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, /* 0x18-0x1f */ + 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe, /* 0x20-0x27 */ + 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1, /* 0x28-0x2f */ + 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda, /* 0x30-0x37 */ + 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, /* 0x38-0x3f */ + 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde, /* 0x40-0x47 */ + 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1, /* 0x48-0x4f */ + 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ +}; +static const unsigned char koi8_r_page22[80] = { + 0x00, 0x95, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x99, 0x00, 0x00, /* 0x60-0x67 */ +}; +static const unsigned char koi8_r_page23[8] = { + 0x93, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char koi8_r_page25[168] = { + 0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x85, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xa0, 0xa1, 0xa2, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, /* 0x50-0x57 */ + 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, /* 0x58-0x5f */ + 0xb1, 0xb2, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, /* 0x60-0x67 */ + 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x8b, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x8d, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x8f, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +koi8_r_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00f8) + c = koi8_r_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x0458) + c = koi8_r_page04[wc-0x0400]; + else if (wc >= 0x2218 && wc < 0x2268) + c = koi8_r_page22[wc-0x2218]; + else if (wc >= 0x2320 && wc < 0x2328) + c = koi8_r_page23[wc-0x2320]; + else if (wc >= 0x2500 && wc < 0x25a8) + c = koi8_r_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/koi8_ru.h b/libs/libiconv/lib/koi8_ru.h new file mode 100644 index 00000000..e43ae720 --- /dev/null +++ b/libs/libiconv/lib/koi8_ru.h @@ -0,0 +1,159 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * KOI8-RU + */ + +static const unsigned short koi8_ru_2uni[128] = { + /* 0x80 */ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + /* 0x90 */ + 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248, + 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, + /* 0xa0 */ + 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x0491, 0x045e, 0x255e, + /* 0xb0 */ + 0x255f, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x0490, 0x040e, 0x00a9, + /* 0xc0 */ + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + /* 0xd0 */ + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + /* 0xe0 */ + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + /* 0xf0 */ + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a, +}; + +static int +koi8_ru_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) koi8_ru_2uni[c-0x80]; + return 1; +} + +static const unsigned char koi8_ru_page00[88] = { + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x9c, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, /* 0xf0-0xf7 */ +}; +static const unsigned char koi8_ru_page04[152] = { + 0x00, 0xb3, 0x00, 0x00, 0xb4, 0x00, 0xb6, 0xb7, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbe, 0x00, /* 0x08-0x0f */ + 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa, /* 0x10-0x17 */ + 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, /* 0x18-0x1f */ + 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe, /* 0x20-0x27 */ + 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1, /* 0x28-0x2f */ + 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda, /* 0x30-0x37 */ + 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, /* 0x38-0x3f */ + 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde, /* 0x40-0x47 */ + 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1, /* 0x48-0x4f */ + 0x00, 0xa3, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xbd, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char koi8_ru_page22[80] = { + 0x00, 0x95, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x99, 0x00, 0x00, /* 0x60-0x67 */ +}; +static const unsigned char koi8_ru_page23[8] = { + 0x93, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char koi8_ru_page25[168] = { + 0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x85, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xa0, 0xa1, 0xa2, 0x00, 0xa5, 0x00, 0x00, 0xa8, /* 0x50-0x57 */ + 0xa9, 0xaa, 0xab, 0xac, 0x00, 0x00, 0xaf, 0xb0, /* 0x58-0x5f */ + 0xb1, 0xb2, 0x00, 0xb5, 0x00, 0x00, 0xb8, 0xb9, /* 0x60-0x67 */ + 0xba, 0xbb, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x8b, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x8d, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x8f, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +koi8_ru_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00f8) + c = koi8_ru_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x0498) + c = koi8_ru_page04[wc-0x0400]; + else if (wc >= 0x2218 && wc < 0x2268) + c = koi8_ru_page22[wc-0x2218]; + else if (wc >= 0x2320 && wc < 0x2328) + c = koi8_ru_page23[wc-0x2320]; + else if (wc >= 0x2500 && wc < 0x25a8) + c = koi8_ru_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/koi8_t.h b/libs/libiconv/lib/koi8_t.h new file mode 100644 index 00000000..0f7a5685 --- /dev/null +++ b/libs/libiconv/lib/koi8_t.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * KOI8-T + */ + +static const unsigned short koi8_t_2uni[128] = { + /* 0x80 */ + 0x049b, 0x0493, 0x201a, 0x0492, 0x201e, 0x2026, 0x2020, 0x2021, + 0xfffd, 0x2030, 0x04b3, 0x2039, 0x04b2, 0x04b7, 0x04b6, 0xfffd, + /* 0x90 */ + 0x049a, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0xfffd, 0x2122, 0xfffd, 0x203a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xa0 */ + 0xfffd, 0x04ef, 0x04ee, 0x0451, 0x00a4, 0x04e3, 0x00a6, 0x00a7, + 0xfffd, 0xfffd, 0xfffd, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0xfffd, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x00b2, 0x0401, 0xfffd, 0x04e2, 0x00b6, 0x00b7, + 0xfffd, 0x2116, 0xfffd, 0x00bb, 0xfffd, 0xfffd, 0xfffd, 0x00a9, + /* 0xc0 */ + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + /* 0xd0 */ + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + /* 0xe0 */ + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + /* 0xf0 */ + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a, +}; + +static int +koi8_t_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = koi8_t_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char koi8_t_page00[32] = { + 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xbf, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0xb2, 0x00, 0x00, 0x00, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char koi8_t_page04[240] = { + 0x00, 0xb3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa, /* 0x10-0x17 */ + 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, /* 0x18-0x1f */ + 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe, /* 0x20-0x27 */ + 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1, /* 0x28-0x2f */ + 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda, /* 0x30-0x37 */ + 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, /* 0x38-0x3f */ + 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde, /* 0x40-0x47 */ + 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1, /* 0x48-0x4f */ + 0x00, 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x83, 0x81, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x90, 0x80, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x8c, 0x8a, 0x00, 0x00, 0x8e, 0x8d, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0xb5, 0xa5, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0xa1, /* 0xe8-0xef */ +}; +static const unsigned char koi8_t_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; +static const unsigned char koi8_t_page21[24] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; + +static int +koi8_t_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = koi8_t_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x04f0) + c = koi8_t_page04[wc-0x0400]; + else if (wc >= 0x2010 && wc < 0x2040) + c = koi8_t_page20[wc-0x2010]; + else if (wc >= 0x2110 && wc < 0x2128) + c = koi8_t_page21[wc-0x2110]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/koi8_u.h b/libs/libiconv/lib/koi8_u.h new file mode 100644 index 00000000..0637d585 --- /dev/null +++ b/libs/libiconv/lib/koi8_u.h @@ -0,0 +1,161 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * KOI8-U + */ + +/* Specification: RFC 2319 */ + +static const unsigned short koi8_u_2uni[128] = { + /* 0x80 */ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2514, 0x2518, 0x251c, 0x2524, + 0x252c, 0x2534, 0x253c, 0x2580, 0x2584, 0x2588, 0x258c, 0x2590, + /* 0x90 */ + 0x2591, 0x2592, 0x2593, 0x2320, 0x25a0, 0x2219, 0x221a, 0x2248, + 0x2264, 0x2265, 0x00a0, 0x2321, 0x00b0, 0x00b2, 0x00b7, 0x00f7, + /* 0xa0 */ + 0x2550, 0x2551, 0x2552, 0x0451, 0x0454, 0x2554, 0x0456, 0x0457, + 0x2557, 0x2558, 0x2559, 0x255a, 0x255b, 0x0491, 0x255d, 0x255e, + /* 0xb0 */ + 0x255f, 0x2560, 0x2561, 0x0401, 0x0404, 0x2563, 0x0406, 0x0407, + 0x2566, 0x2567, 0x2568, 0x2569, 0x256a, 0x0490, 0x256c, 0x00a9, + /* 0xc0 */ + 0x044e, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, + 0x0445, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + /* 0xd0 */ + 0x043f, 0x044f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, + 0x044c, 0x044b, 0x0437, 0x0448, 0x044d, 0x0449, 0x0447, 0x044a, + /* 0xe0 */ + 0x042e, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, + 0x0425, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + /* 0xf0 */ + 0x041f, 0x042f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, + 0x042c, 0x042b, 0x0417, 0x0428, 0x042d, 0x0429, 0x0427, 0x042a, +}; + +static int +koi8_u_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) koi8_u_2uni[c-0x80]; + return 1; +} + +static const unsigned char koi8_u_page00[88] = { + 0x9a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xbf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x9c, 0x00, 0x9d, 0x00, 0x00, 0x00, 0x00, 0x9e, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, /* 0xf0-0xf7 */ +}; +static const unsigned char koi8_u_page04[152] = { + 0x00, 0xb3, 0x00, 0x00, 0xb4, 0x00, 0xb6, 0xb7, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xe1, 0xe2, 0xf7, 0xe7, 0xe4, 0xe5, 0xf6, 0xfa, /* 0x10-0x17 */ + 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, 0xf0, /* 0x18-0x1f */ + 0xf2, 0xf3, 0xf4, 0xf5, 0xe6, 0xe8, 0xe3, 0xfe, /* 0x20-0x27 */ + 0xfb, 0xfd, 0xff, 0xf9, 0xf8, 0xfc, 0xe0, 0xf1, /* 0x28-0x2f */ + 0xc1, 0xc2, 0xd7, 0xc7, 0xc4, 0xc5, 0xd6, 0xda, /* 0x30-0x37 */ + 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, 0xd0, /* 0x38-0x3f */ + 0xd2, 0xd3, 0xd4, 0xd5, 0xc6, 0xc8, 0xc3, 0xde, /* 0x40-0x47 */ + 0xdb, 0xdd, 0xdf, 0xd9, 0xd8, 0xdc, 0xc0, 0xd1, /* 0x48-0x4f */ + 0x00, 0xa3, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xbd, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char koi8_u_page22[80] = { + 0x00, 0x95, 0x96, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x97, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x98, 0x99, 0x00, 0x00, /* 0x60-0x67 */ +}; +static const unsigned char koi8_u_page23[8] = { + 0x93, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char koi8_u_page25[168] = { + 0x80, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x82, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x85, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x89, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0xa0, 0xa1, 0xa2, 0x00, 0xa5, 0x00, 0x00, 0xa8, /* 0x50-0x57 */ + 0xa9, 0xaa, 0xab, 0xac, 0x00, 0xae, 0xaf, 0xb0, /* 0x58-0x5f */ + 0xb1, 0xb2, 0x00, 0xb5, 0x00, 0x00, 0xb8, 0xb9, /* 0x60-0x67 */ + 0xba, 0xbb, 0xbc, 0x00, 0xbe, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x8b, 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x8d, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x8f, 0x90, 0x91, 0x92, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ +}; + +static int +koi8_u_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00f8) + c = koi8_u_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x0498) + c = koi8_u_page04[wc-0x0400]; + else if (wc >= 0x2218 && wc < 0x2268) + c = koi8_u_page22[wc-0x2218]; + else if (wc >= 0x2320 && wc < 0x2328) + c = koi8_u_page23[wc-0x2320]; + else if (wc >= 0x2500 && wc < 0x25a8) + c = koi8_u_page25[wc-0x2500]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/ksc5601.h b/libs/libiconv/lib/ksc5601.h new file mode 100644 index 00000000..fd166232 --- /dev/null +++ b/libs/libiconv/lib/ksc5601.h @@ -0,0 +1,3022 @@ +/* + * Copyright (C) 1999-2007 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * KSC5601.1987-0, now KS X 1001:2002 + */ + +static const unsigned short ksc5601_2uni_page21[1115] = { + /* 0x21 */ + 0x3000, 0x3001, 0x3002, 0x00b7, 0x2025, 0x2026, 0x00a8, 0x3003, + 0x00ad, 0x2015, 0x2225, 0xff3c, 0x223c, 0x2018, 0x2019, 0x201c, + 0x201d, 0x3014, 0x3015, 0x3008, 0x3009, 0x300a, 0x300b, 0x300c, + 0x300d, 0x300e, 0x300f, 0x3010, 0x3011, 0x00b1, 0x00d7, 0x00f7, + 0x2260, 0x2264, 0x2265, 0x221e, 0x2234, 0x00b0, 0x2032, 0x2033, + 0x2103, 0x212b, 0xffe0, 0xffe1, 0xffe5, 0x2642, 0x2640, 0x2220, + 0x22a5, 0x2312, 0x2202, 0x2207, 0x2261, 0x2252, 0x00a7, 0x203b, + 0x2606, 0x2605, 0x25cb, 0x25cf, 0x25ce, 0x25c7, 0x25c6, 0x25a1, + 0x25a0, 0x25b3, 0x25b2, 0x25bd, 0x25bc, 0x2192, 0x2190, 0x2191, + 0x2193, 0x2194, 0x3013, 0x226a, 0x226b, 0x221a, 0x223d, 0x221d, + 0x2235, 0x222b, 0x222c, 0x2208, 0x220b, 0x2286, 0x2287, 0x2282, + 0x2283, 0x222a, 0x2229, 0x2227, 0x2228, 0xffe2, + /* 0x22 */ + 0x21d2, 0x21d4, 0x2200, 0x2203, 0x00b4, 0xff5e, 0x02c7, 0x02d8, + 0x02dd, 0x02da, 0x02d9, 0x00b8, 0x02db, 0x00a1, 0x00bf, 0x02d0, + 0x222e, 0x2211, 0x220f, 0x00a4, 0x2109, 0x2030, 0x25c1, 0x25c0, + 0x25b7, 0x25b6, 0x2664, 0x2660, 0x2661, 0x2665, 0x2667, 0x2663, + 0x2299, 0x25c8, 0x25a3, 0x25d0, 0x25d1, 0x2592, 0x25a4, 0x25a5, + 0x25a8, 0x25a7, 0x25a6, 0x25a9, 0x2668, 0x260f, 0x260e, 0x261c, + 0x261e, 0x00b6, 0x2020, 0x2021, 0x2195, 0x2197, 0x2199, 0x2196, + 0x2198, 0x266d, 0x2669, 0x266a, 0x266c, 0x327f, 0x321c, 0x2116, + 0x33c7, 0x2122, 0x33c2, 0x33d8, 0x2121, 0x20ac, 0x00ae, 0x327e, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x23 */ + 0xff01, 0xff02, 0xff03, 0xff04, 0xff05, 0xff06, 0xff07, 0xff08, + 0xff09, 0xff0a, 0xff0b, 0xff0c, 0xff0d, 0xff0e, 0xff0f, 0xff10, + 0xff11, 0xff12, 0xff13, 0xff14, 0xff15, 0xff16, 0xff17, 0xff18, + 0xff19, 0xff1a, 0xff1b, 0xff1c, 0xff1d, 0xff1e, 0xff1f, 0xff20, + 0xff21, 0xff22, 0xff23, 0xff24, 0xff25, 0xff26, 0xff27, 0xff28, + 0xff29, 0xff2a, 0xff2b, 0xff2c, 0xff2d, 0xff2e, 0xff2f, 0xff30, + 0xff31, 0xff32, 0xff33, 0xff34, 0xff35, 0xff36, 0xff37, 0xff38, + 0xff39, 0xff3a, 0xff3b, 0xffe6, 0xff3d, 0xff3e, 0xff3f, 0xff40, + 0xff41, 0xff42, 0xff43, 0xff44, 0xff45, 0xff46, 0xff47, 0xff48, + 0xff49, 0xff4a, 0xff4b, 0xff4c, 0xff4d, 0xff4e, 0xff4f, 0xff50, + 0xff51, 0xff52, 0xff53, 0xff54, 0xff55, 0xff56, 0xff57, 0xff58, + 0xff59, 0xff5a, 0xff5b, 0xff5c, 0xff5d, 0xffe3, + /* 0x24 */ + 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, 0x3136, 0x3137, 0x3138, + 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, 0x313e, 0x313f, 0x3140, + 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, 0x3146, 0x3147, 0x3148, + 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, 0x314e, 0x314f, 0x3150, + 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, 0x3156, 0x3157, 0x3158, + 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, 0x315e, 0x315f, 0x3160, + 0x3161, 0x3162, 0x3163, 0x3164, 0x3165, 0x3166, 0x3167, 0x3168, + 0x3169, 0x316a, 0x316b, 0x316c, 0x316d, 0x316e, 0x316f, 0x3170, + 0x3171, 0x3172, 0x3173, 0x3174, 0x3175, 0x3176, 0x3177, 0x3178, + 0x3179, 0x317a, 0x317b, 0x317c, 0x317d, 0x317e, 0x317f, 0x3180, + 0x3181, 0x3182, 0x3183, 0x3184, 0x3185, 0x3186, 0x3187, 0x3188, + 0x3189, 0x318a, 0x318b, 0x318c, 0x318d, 0x318e, + /* 0x25 */ + 0x2170, 0x2171, 0x2172, 0x2173, 0x2174, 0x2175, 0x2176, 0x2177, + 0x2178, 0x2179, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x2160, + 0x2161, 0x2162, 0x2163, 0x2164, 0x2165, 0x2166, 0x2167, 0x2168, + 0x2169, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, 0x0398, + 0x0399, 0x039a, 0x039b, 0x039c, 0x039d, 0x039e, 0x039f, 0x03a0, + 0x03a1, 0x03a3, 0x03a4, 0x03a5, 0x03a6, 0x03a7, 0x03a8, 0x03a9, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 0x03b8, + 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, + 0x03c1, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x26 */ + 0x2500, 0x2502, 0x250c, 0x2510, 0x2518, 0x2514, 0x251c, 0x252c, + 0x2524, 0x2534, 0x253c, 0x2501, 0x2503, 0x250f, 0x2513, 0x251b, + 0x2517, 0x2523, 0x2533, 0x252b, 0x253b, 0x254b, 0x2520, 0x252f, + 0x2528, 0x2537, 0x253f, 0x251d, 0x2530, 0x2525, 0x2538, 0x2542, + 0x2512, 0x2511, 0x251a, 0x2519, 0x2516, 0x2515, 0x250e, 0x250d, + 0x251e, 0x251f, 0x2521, 0x2522, 0x2526, 0x2527, 0x2529, 0x252a, + 0x252d, 0x252e, 0x2531, 0x2532, 0x2535, 0x2536, 0x2539, 0x253a, + 0x253d, 0x253e, 0x2540, 0x2541, 0x2543, 0x2544, 0x2545, 0x2546, + 0x2547, 0x2548, 0x2549, 0x254a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x27 */ + 0x3395, 0x3396, 0x3397, 0x2113, 0x3398, 0x33c4, 0x33a3, 0x33a4, + 0x33a5, 0x33a6, 0x3399, 0x339a, 0x339b, 0x339c, 0x339d, 0x339e, + 0x339f, 0x33a0, 0x33a1, 0x33a2, 0x33ca, 0x338d, 0x338e, 0x338f, + 0x33cf, 0x3388, 0x3389, 0x33c8, 0x33a7, 0x33a8, 0x33b0, 0x33b1, + 0x33b2, 0x33b3, 0x33b4, 0x33b5, 0x33b6, 0x33b7, 0x33b8, 0x33b9, + 0x3380, 0x3381, 0x3382, 0x3383, 0x3384, 0x33ba, 0x33bb, 0x33bc, + 0x33bd, 0x33be, 0x33bf, 0x3390, 0x3391, 0x3392, 0x3393, 0x3394, + 0x2126, 0x33c0, 0x33c1, 0x338a, 0x338b, 0x338c, 0x33d6, 0x33c5, + 0x33ad, 0x33ae, 0x33af, 0x33db, 0x33a9, 0x33aa, 0x33ab, 0x33ac, + 0x33dd, 0x33d0, 0x33d3, 0x33c3, 0x33c9, 0x33dc, 0x33c6, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x28 */ + 0x00c6, 0x00d0, 0x00aa, 0x0126, 0xfffd, 0x0132, 0xfffd, 0x013f, + 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00de, 0x0166, 0x014a, 0xfffd, + 0x3260, 0x3261, 0x3262, 0x3263, 0x3264, 0x3265, 0x3266, 0x3267, + 0x3268, 0x3269, 0x326a, 0x326b, 0x326c, 0x326d, 0x326e, 0x326f, + 0x3270, 0x3271, 0x3272, 0x3273, 0x3274, 0x3275, 0x3276, 0x3277, + 0x3278, 0x3279, 0x327a, 0x327b, 0x24d0, 0x24d1, 0x24d2, 0x24d3, + 0x24d4, 0x24d5, 0x24d6, 0x24d7, 0x24d8, 0x24d9, 0x24da, 0x24db, + 0x24dc, 0x24dd, 0x24de, 0x24df, 0x24e0, 0x24e1, 0x24e2, 0x24e3, + 0x24e4, 0x24e5, 0x24e6, 0x24e7, 0x24e8, 0x24e9, 0x2460, 0x2461, + 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, 0x2469, + 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x00bd, 0x2153, 0x2154, + 0x00bc, 0x00be, 0x215b, 0x215c, 0x215d, 0x215e, + /* 0x29 */ + 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0138, 0x0140, + 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x0167, 0x014b, 0x0149, + 0x3200, 0x3201, 0x3202, 0x3203, 0x3204, 0x3205, 0x3206, 0x3207, + 0x3208, 0x3209, 0x320a, 0x320b, 0x320c, 0x320d, 0x320e, 0x320f, + 0x3210, 0x3211, 0x3212, 0x3213, 0x3214, 0x3215, 0x3216, 0x3217, + 0x3218, 0x3219, 0x321a, 0x321b, 0x249c, 0x249d, 0x249e, 0x249f, + 0x24a0, 0x24a1, 0x24a2, 0x24a3, 0x24a4, 0x24a5, 0x24a6, 0x24a7, + 0x24a8, 0x24a9, 0x24aa, 0x24ab, 0x24ac, 0x24ad, 0x24ae, 0x24af, + 0x24b0, 0x24b1, 0x24b2, 0x24b3, 0x24b4, 0x24b5, 0x2474, 0x2475, + 0x2476, 0x2477, 0x2478, 0x2479, 0x247a, 0x247b, 0x247c, 0x247d, + 0x247e, 0x247f, 0x2480, 0x2481, 0x2482, 0x00b9, 0x00b2, 0x00b3, + 0x2074, 0x207f, 0x2081, 0x2082, 0x2083, 0x2084, + /* 0x2a */ + 0x3041, 0x3042, 0x3043, 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, + 0x3049, 0x304a, 0x304b, 0x304c, 0x304d, 0x304e, 0x304f, 0x3050, + 0x3051, 0x3052, 0x3053, 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, + 0x3059, 0x305a, 0x305b, 0x305c, 0x305d, 0x305e, 0x305f, 0x3060, + 0x3061, 0x3062, 0x3063, 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, + 0x3069, 0x306a, 0x306b, 0x306c, 0x306d, 0x306e, 0x306f, 0x3070, + 0x3071, 0x3072, 0x3073, 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, + 0x3079, 0x307a, 0x307b, 0x307c, 0x307d, 0x307e, 0x307f, 0x3080, + 0x3081, 0x3082, 0x3083, 0x3084, 0x3085, 0x3086, 0x3087, 0x3088, + 0x3089, 0x308a, 0x308b, 0x308c, 0x308d, 0x308e, 0x308f, 0x3090, + 0x3091, 0x3092, 0x3093, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x2b */ + 0x30a1, 0x30a2, 0x30a3, 0x30a4, 0x30a5, 0x30a6, 0x30a7, 0x30a8, + 0x30a9, 0x30aa, 0x30ab, 0x30ac, 0x30ad, 0x30ae, 0x30af, 0x30b0, + 0x30b1, 0x30b2, 0x30b3, 0x30b4, 0x30b5, 0x30b6, 0x30b7, 0x30b8, + 0x30b9, 0x30ba, 0x30bb, 0x30bc, 0x30bd, 0x30be, 0x30bf, 0x30c0, + 0x30c1, 0x30c2, 0x30c3, 0x30c4, 0x30c5, 0x30c6, 0x30c7, 0x30c8, + 0x30c9, 0x30ca, 0x30cb, 0x30cc, 0x30cd, 0x30ce, 0x30cf, 0x30d0, + 0x30d1, 0x30d2, 0x30d3, 0x30d4, 0x30d5, 0x30d6, 0x30d7, 0x30d8, + 0x30d9, 0x30da, 0x30db, 0x30dc, 0x30dd, 0x30de, 0x30df, 0x30e0, + 0x30e1, 0x30e2, 0x30e3, 0x30e4, 0x30e5, 0x30e6, 0x30e7, 0x30e8, + 0x30e9, 0x30ea, 0x30eb, 0x30ec, 0x30ed, 0x30ee, 0x30ef, 0x30f0, + 0x30f1, 0x30f2, 0x30f3, 0x30f4, 0x30f5, 0x30f6, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0x2c */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0401, 0x0416, + 0x0417, 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, + 0x041f, 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, + 0x0427, 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, + 0x042f, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0451, 0x0436, + 0x0437, 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, + 0x043f, 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, + 0x0447, 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, + 0x044f, +}; +static const unsigned short ksc5601_2uni_page30[2350] = { + /* 0x30 */ + 0xac00, 0xac01, 0xac04, 0xac07, 0xac08, 0xac09, 0xac0a, 0xac10, + 0xac11, 0xac12, 0xac13, 0xac14, 0xac15, 0xac16, 0xac17, 0xac19, + 0xac1a, 0xac1b, 0xac1c, 0xac1d, 0xac20, 0xac24, 0xac2c, 0xac2d, + 0xac2f, 0xac30, 0xac31, 0xac38, 0xac39, 0xac3c, 0xac40, 0xac4b, + 0xac4d, 0xac54, 0xac58, 0xac5c, 0xac70, 0xac71, 0xac74, 0xac77, + 0xac78, 0xac7a, 0xac80, 0xac81, 0xac83, 0xac84, 0xac85, 0xac86, + 0xac89, 0xac8a, 0xac8b, 0xac8c, 0xac90, 0xac94, 0xac9c, 0xac9d, + 0xac9f, 0xaca0, 0xaca1, 0xaca8, 0xaca9, 0xacaa, 0xacac, 0xacaf, + 0xacb0, 0xacb8, 0xacb9, 0xacbb, 0xacbc, 0xacbd, 0xacc1, 0xacc4, + 0xacc8, 0xaccc, 0xacd5, 0xacd7, 0xace0, 0xace1, 0xace4, 0xace7, + 0xace8, 0xacea, 0xacec, 0xacef, 0xacf0, 0xacf1, 0xacf3, 0xacf5, + 0xacf6, 0xacfc, 0xacfd, 0xad00, 0xad04, 0xad06, + /* 0x31 */ + 0xad0c, 0xad0d, 0xad0f, 0xad11, 0xad18, 0xad1c, 0xad20, 0xad29, + 0xad2c, 0xad2d, 0xad34, 0xad35, 0xad38, 0xad3c, 0xad44, 0xad45, + 0xad47, 0xad49, 0xad50, 0xad54, 0xad58, 0xad61, 0xad63, 0xad6c, + 0xad6d, 0xad70, 0xad73, 0xad74, 0xad75, 0xad76, 0xad7b, 0xad7c, + 0xad7d, 0xad7f, 0xad81, 0xad82, 0xad88, 0xad89, 0xad8c, 0xad90, + 0xad9c, 0xad9d, 0xada4, 0xadb7, 0xadc0, 0xadc1, 0xadc4, 0xadc8, + 0xadd0, 0xadd1, 0xadd3, 0xaddc, 0xade0, 0xade4, 0xadf8, 0xadf9, + 0xadfc, 0xadff, 0xae00, 0xae01, 0xae08, 0xae09, 0xae0b, 0xae0d, + 0xae14, 0xae30, 0xae31, 0xae34, 0xae37, 0xae38, 0xae3a, 0xae40, + 0xae41, 0xae43, 0xae45, 0xae46, 0xae4a, 0xae4c, 0xae4d, 0xae4e, + 0xae50, 0xae54, 0xae56, 0xae5c, 0xae5d, 0xae5f, 0xae60, 0xae61, + 0xae65, 0xae68, 0xae69, 0xae6c, 0xae70, 0xae78, + /* 0x32 */ + 0xae79, 0xae7b, 0xae7c, 0xae7d, 0xae84, 0xae85, 0xae8c, 0xaebc, + 0xaebd, 0xaebe, 0xaec0, 0xaec4, 0xaecc, 0xaecd, 0xaecf, 0xaed0, + 0xaed1, 0xaed8, 0xaed9, 0xaedc, 0xaee8, 0xaeeb, 0xaeed, 0xaef4, + 0xaef8, 0xaefc, 0xaf07, 0xaf08, 0xaf0d, 0xaf10, 0xaf2c, 0xaf2d, + 0xaf30, 0xaf32, 0xaf34, 0xaf3c, 0xaf3d, 0xaf3f, 0xaf41, 0xaf42, + 0xaf43, 0xaf48, 0xaf49, 0xaf50, 0xaf5c, 0xaf5d, 0xaf64, 0xaf65, + 0xaf79, 0xaf80, 0xaf84, 0xaf88, 0xaf90, 0xaf91, 0xaf95, 0xaf9c, + 0xafb8, 0xafb9, 0xafbc, 0xafc0, 0xafc7, 0xafc8, 0xafc9, 0xafcb, + 0xafcd, 0xafce, 0xafd4, 0xafdc, 0xafe8, 0xafe9, 0xaff0, 0xaff1, + 0xaff4, 0xaff8, 0xb000, 0xb001, 0xb004, 0xb00c, 0xb010, 0xb014, + 0xb01c, 0xb01d, 0xb028, 0xb044, 0xb045, 0xb048, 0xb04a, 0xb04c, + 0xb04e, 0xb053, 0xb054, 0xb055, 0xb057, 0xb059, + /* 0x33 */ + 0xb05d, 0xb07c, 0xb07d, 0xb080, 0xb084, 0xb08c, 0xb08d, 0xb08f, + 0xb091, 0xb098, 0xb099, 0xb09a, 0xb09c, 0xb09f, 0xb0a0, 0xb0a1, + 0xb0a2, 0xb0a8, 0xb0a9, 0xb0ab, 0xb0ac, 0xb0ad, 0xb0ae, 0xb0af, + 0xb0b1, 0xb0b3, 0xb0b4, 0xb0b5, 0xb0b8, 0xb0bc, 0xb0c4, 0xb0c5, + 0xb0c7, 0xb0c8, 0xb0c9, 0xb0d0, 0xb0d1, 0xb0d4, 0xb0d8, 0xb0e0, + 0xb0e5, 0xb108, 0xb109, 0xb10b, 0xb10c, 0xb110, 0xb112, 0xb113, + 0xb118, 0xb119, 0xb11b, 0xb11c, 0xb11d, 0xb123, 0xb124, 0xb125, + 0xb128, 0xb12c, 0xb134, 0xb135, 0xb137, 0xb138, 0xb139, 0xb140, + 0xb141, 0xb144, 0xb148, 0xb150, 0xb151, 0xb154, 0xb155, 0xb158, + 0xb15c, 0xb160, 0xb178, 0xb179, 0xb17c, 0xb180, 0xb182, 0xb188, + 0xb189, 0xb18b, 0xb18d, 0xb192, 0xb193, 0xb194, 0xb198, 0xb19c, + 0xb1a8, 0xb1cc, 0xb1d0, 0xb1d4, 0xb1dc, 0xb1dd, + /* 0x34 */ + 0xb1df, 0xb1e8, 0xb1e9, 0xb1ec, 0xb1f0, 0xb1f9, 0xb1fb, 0xb1fd, + 0xb204, 0xb205, 0xb208, 0xb20b, 0xb20c, 0xb214, 0xb215, 0xb217, + 0xb219, 0xb220, 0xb234, 0xb23c, 0xb258, 0xb25c, 0xb260, 0xb268, + 0xb269, 0xb274, 0xb275, 0xb27c, 0xb284, 0xb285, 0xb289, 0xb290, + 0xb291, 0xb294, 0xb298, 0xb299, 0xb29a, 0xb2a0, 0xb2a1, 0xb2a3, + 0xb2a5, 0xb2a6, 0xb2aa, 0xb2ac, 0xb2b0, 0xb2b4, 0xb2c8, 0xb2c9, + 0xb2cc, 0xb2d0, 0xb2d2, 0xb2d8, 0xb2d9, 0xb2db, 0xb2dd, 0xb2e2, + 0xb2e4, 0xb2e5, 0xb2e6, 0xb2e8, 0xb2eb, 0xb2ec, 0xb2ed, 0xb2ee, + 0xb2ef, 0xb2f3, 0xb2f4, 0xb2f5, 0xb2f7, 0xb2f8, 0xb2f9, 0xb2fa, + 0xb2fb, 0xb2ff, 0xb300, 0xb301, 0xb304, 0xb308, 0xb310, 0xb311, + 0xb313, 0xb314, 0xb315, 0xb31c, 0xb354, 0xb355, 0xb356, 0xb358, + 0xb35b, 0xb35c, 0xb35e, 0xb35f, 0xb364, 0xb365, + /* 0x35 */ + 0xb367, 0xb369, 0xb36b, 0xb36e, 0xb370, 0xb371, 0xb374, 0xb378, + 0xb380, 0xb381, 0xb383, 0xb384, 0xb385, 0xb38c, 0xb390, 0xb394, + 0xb3a0, 0xb3a1, 0xb3a8, 0xb3ac, 0xb3c4, 0xb3c5, 0xb3c8, 0xb3cb, + 0xb3cc, 0xb3ce, 0xb3d0, 0xb3d4, 0xb3d5, 0xb3d7, 0xb3d9, 0xb3db, + 0xb3dd, 0xb3e0, 0xb3e4, 0xb3e8, 0xb3fc, 0xb410, 0xb418, 0xb41c, + 0xb420, 0xb428, 0xb429, 0xb42b, 0xb434, 0xb450, 0xb451, 0xb454, + 0xb458, 0xb460, 0xb461, 0xb463, 0xb465, 0xb46c, 0xb480, 0xb488, + 0xb49d, 0xb4a4, 0xb4a8, 0xb4ac, 0xb4b5, 0xb4b7, 0xb4b9, 0xb4c0, + 0xb4c4, 0xb4c8, 0xb4d0, 0xb4d5, 0xb4dc, 0xb4dd, 0xb4e0, 0xb4e3, + 0xb4e4, 0xb4e6, 0xb4ec, 0xb4ed, 0xb4ef, 0xb4f1, 0xb4f8, 0xb514, + 0xb515, 0xb518, 0xb51b, 0xb51c, 0xb524, 0xb525, 0xb527, 0xb528, + 0xb529, 0xb52a, 0xb530, 0xb531, 0xb534, 0xb538, + /* 0x36 */ + 0xb540, 0xb541, 0xb543, 0xb544, 0xb545, 0xb54b, 0xb54c, 0xb54d, + 0xb550, 0xb554, 0xb55c, 0xb55d, 0xb55f, 0xb560, 0xb561, 0xb5a0, + 0xb5a1, 0xb5a4, 0xb5a8, 0xb5aa, 0xb5ab, 0xb5b0, 0xb5b1, 0xb5b3, + 0xb5b4, 0xb5b5, 0xb5bb, 0xb5bc, 0xb5bd, 0xb5c0, 0xb5c4, 0xb5cc, + 0xb5cd, 0xb5cf, 0xb5d0, 0xb5d1, 0xb5d8, 0xb5ec, 0xb610, 0xb611, + 0xb614, 0xb618, 0xb625, 0xb62c, 0xb634, 0xb648, 0xb664, 0xb668, + 0xb69c, 0xb69d, 0xb6a0, 0xb6a4, 0xb6ab, 0xb6ac, 0xb6b1, 0xb6d4, + 0xb6f0, 0xb6f4, 0xb6f8, 0xb700, 0xb701, 0xb705, 0xb728, 0xb729, + 0xb72c, 0xb72f, 0xb730, 0xb738, 0xb739, 0xb73b, 0xb744, 0xb748, + 0xb74c, 0xb754, 0xb755, 0xb760, 0xb764, 0xb768, 0xb770, 0xb771, + 0xb773, 0xb775, 0xb77c, 0xb77d, 0xb780, 0xb784, 0xb78c, 0xb78d, + 0xb78f, 0xb790, 0xb791, 0xb792, 0xb796, 0xb797, + /* 0x37 */ + 0xb798, 0xb799, 0xb79c, 0xb7a0, 0xb7a8, 0xb7a9, 0xb7ab, 0xb7ac, + 0xb7ad, 0xb7b4, 0xb7b5, 0xb7b8, 0xb7c7, 0xb7c9, 0xb7ec, 0xb7ed, + 0xb7f0, 0xb7f4, 0xb7fc, 0xb7fd, 0xb7ff, 0xb800, 0xb801, 0xb807, + 0xb808, 0xb809, 0xb80c, 0xb810, 0xb818, 0xb819, 0xb81b, 0xb81d, + 0xb824, 0xb825, 0xb828, 0xb82c, 0xb834, 0xb835, 0xb837, 0xb838, + 0xb839, 0xb840, 0xb844, 0xb851, 0xb853, 0xb85c, 0xb85d, 0xb860, + 0xb864, 0xb86c, 0xb86d, 0xb86f, 0xb871, 0xb878, 0xb87c, 0xb88d, + 0xb8a8, 0xb8b0, 0xb8b4, 0xb8b8, 0xb8c0, 0xb8c1, 0xb8c3, 0xb8c5, + 0xb8cc, 0xb8d0, 0xb8d4, 0xb8dd, 0xb8df, 0xb8e1, 0xb8e8, 0xb8e9, + 0xb8ec, 0xb8f0, 0xb8f8, 0xb8f9, 0xb8fb, 0xb8fd, 0xb904, 0xb918, + 0xb920, 0xb93c, 0xb93d, 0xb940, 0xb944, 0xb94c, 0xb94f, 0xb951, + 0xb958, 0xb959, 0xb95c, 0xb960, 0xb968, 0xb969, + /* 0x38 */ + 0xb96b, 0xb96d, 0xb974, 0xb975, 0xb978, 0xb97c, 0xb984, 0xb985, + 0xb987, 0xb989, 0xb98a, 0xb98d, 0xb98e, 0xb9ac, 0xb9ad, 0xb9b0, + 0xb9b4, 0xb9bc, 0xb9bd, 0xb9bf, 0xb9c1, 0xb9c8, 0xb9c9, 0xb9cc, + 0xb9ce, 0xb9cf, 0xb9d0, 0xb9d1, 0xb9d2, 0xb9d8, 0xb9d9, 0xb9db, + 0xb9dd, 0xb9de, 0xb9e1, 0xb9e3, 0xb9e4, 0xb9e5, 0xb9e8, 0xb9ec, + 0xb9f4, 0xb9f5, 0xb9f7, 0xb9f8, 0xb9f9, 0xb9fa, 0xba00, 0xba01, + 0xba08, 0xba15, 0xba38, 0xba39, 0xba3c, 0xba40, 0xba42, 0xba48, + 0xba49, 0xba4b, 0xba4d, 0xba4e, 0xba53, 0xba54, 0xba55, 0xba58, + 0xba5c, 0xba64, 0xba65, 0xba67, 0xba68, 0xba69, 0xba70, 0xba71, + 0xba74, 0xba78, 0xba83, 0xba84, 0xba85, 0xba87, 0xba8c, 0xbaa8, + 0xbaa9, 0xbaab, 0xbaac, 0xbab0, 0xbab2, 0xbab8, 0xbab9, 0xbabb, + 0xbabd, 0xbac4, 0xbac8, 0xbad8, 0xbad9, 0xbafc, + /* 0x39 */ + 0xbb00, 0xbb04, 0xbb0d, 0xbb0f, 0xbb11, 0xbb18, 0xbb1c, 0xbb20, + 0xbb29, 0xbb2b, 0xbb34, 0xbb35, 0xbb36, 0xbb38, 0xbb3b, 0xbb3c, + 0xbb3d, 0xbb3e, 0xbb44, 0xbb45, 0xbb47, 0xbb49, 0xbb4d, 0xbb4f, + 0xbb50, 0xbb54, 0xbb58, 0xbb61, 0xbb63, 0xbb6c, 0xbb88, 0xbb8c, + 0xbb90, 0xbba4, 0xbba8, 0xbbac, 0xbbb4, 0xbbb7, 0xbbc0, 0xbbc4, + 0xbbc8, 0xbbd0, 0xbbd3, 0xbbf8, 0xbbf9, 0xbbfc, 0xbbff, 0xbc00, + 0xbc02, 0xbc08, 0xbc09, 0xbc0b, 0xbc0c, 0xbc0d, 0xbc0f, 0xbc11, + 0xbc14, 0xbc15, 0xbc16, 0xbc17, 0xbc18, 0xbc1b, 0xbc1c, 0xbc1d, + 0xbc1e, 0xbc1f, 0xbc24, 0xbc25, 0xbc27, 0xbc29, 0xbc2d, 0xbc30, + 0xbc31, 0xbc34, 0xbc38, 0xbc40, 0xbc41, 0xbc43, 0xbc44, 0xbc45, + 0xbc49, 0xbc4c, 0xbc4d, 0xbc50, 0xbc5d, 0xbc84, 0xbc85, 0xbc88, + 0xbc8b, 0xbc8c, 0xbc8e, 0xbc94, 0xbc95, 0xbc97, + /* 0x3a */ + 0xbc99, 0xbc9a, 0xbca0, 0xbca1, 0xbca4, 0xbca7, 0xbca8, 0xbcb0, + 0xbcb1, 0xbcb3, 0xbcb4, 0xbcb5, 0xbcbc, 0xbcbd, 0xbcc0, 0xbcc4, + 0xbccd, 0xbccf, 0xbcd0, 0xbcd1, 0xbcd5, 0xbcd8, 0xbcdc, 0xbcf4, + 0xbcf5, 0xbcf6, 0xbcf8, 0xbcfc, 0xbd04, 0xbd05, 0xbd07, 0xbd09, + 0xbd10, 0xbd14, 0xbd24, 0xbd2c, 0xbd40, 0xbd48, 0xbd49, 0xbd4c, + 0xbd50, 0xbd58, 0xbd59, 0xbd64, 0xbd68, 0xbd80, 0xbd81, 0xbd84, + 0xbd87, 0xbd88, 0xbd89, 0xbd8a, 0xbd90, 0xbd91, 0xbd93, 0xbd95, + 0xbd99, 0xbd9a, 0xbd9c, 0xbda4, 0xbdb0, 0xbdb8, 0xbdd4, 0xbdd5, + 0xbdd8, 0xbddc, 0xbde9, 0xbdf0, 0xbdf4, 0xbdf8, 0xbe00, 0xbe03, + 0xbe05, 0xbe0c, 0xbe0d, 0xbe10, 0xbe14, 0xbe1c, 0xbe1d, 0xbe1f, + 0xbe44, 0xbe45, 0xbe48, 0xbe4c, 0xbe4e, 0xbe54, 0xbe55, 0xbe57, + 0xbe59, 0xbe5a, 0xbe5b, 0xbe60, 0xbe61, 0xbe64, + /* 0x3b */ + 0xbe68, 0xbe6a, 0xbe70, 0xbe71, 0xbe73, 0xbe74, 0xbe75, 0xbe7b, + 0xbe7c, 0xbe7d, 0xbe80, 0xbe84, 0xbe8c, 0xbe8d, 0xbe8f, 0xbe90, + 0xbe91, 0xbe98, 0xbe99, 0xbea8, 0xbed0, 0xbed1, 0xbed4, 0xbed7, + 0xbed8, 0xbee0, 0xbee3, 0xbee4, 0xbee5, 0xbeec, 0xbf01, 0xbf08, + 0xbf09, 0xbf18, 0xbf19, 0xbf1b, 0xbf1c, 0xbf1d, 0xbf40, 0xbf41, + 0xbf44, 0xbf48, 0xbf50, 0xbf51, 0xbf55, 0xbf94, 0xbfb0, 0xbfc5, + 0xbfcc, 0xbfcd, 0xbfd0, 0xbfd4, 0xbfdc, 0xbfdf, 0xbfe1, 0xc03c, + 0xc051, 0xc058, 0xc05c, 0xc060, 0xc068, 0xc069, 0xc090, 0xc091, + 0xc094, 0xc098, 0xc0a0, 0xc0a1, 0xc0a3, 0xc0a5, 0xc0ac, 0xc0ad, + 0xc0af, 0xc0b0, 0xc0b3, 0xc0b4, 0xc0b5, 0xc0b6, 0xc0bc, 0xc0bd, + 0xc0bf, 0xc0c0, 0xc0c1, 0xc0c5, 0xc0c8, 0xc0c9, 0xc0cc, 0xc0d0, + 0xc0d8, 0xc0d9, 0xc0db, 0xc0dc, 0xc0dd, 0xc0e4, + /* 0x3c */ + 0xc0e5, 0xc0e8, 0xc0ec, 0xc0f4, 0xc0f5, 0xc0f7, 0xc0f9, 0xc100, + 0xc104, 0xc108, 0xc110, 0xc115, 0xc11c, 0xc11d, 0xc11e, 0xc11f, + 0xc120, 0xc123, 0xc124, 0xc126, 0xc127, 0xc12c, 0xc12d, 0xc12f, + 0xc130, 0xc131, 0xc136, 0xc138, 0xc139, 0xc13c, 0xc140, 0xc148, + 0xc149, 0xc14b, 0xc14c, 0xc14d, 0xc154, 0xc155, 0xc158, 0xc15c, + 0xc164, 0xc165, 0xc167, 0xc168, 0xc169, 0xc170, 0xc174, 0xc178, + 0xc185, 0xc18c, 0xc18d, 0xc18e, 0xc190, 0xc194, 0xc196, 0xc19c, + 0xc19d, 0xc19f, 0xc1a1, 0xc1a5, 0xc1a8, 0xc1a9, 0xc1ac, 0xc1b0, + 0xc1bd, 0xc1c4, 0xc1c8, 0xc1cc, 0xc1d4, 0xc1d7, 0xc1d8, 0xc1e0, + 0xc1e4, 0xc1e8, 0xc1f0, 0xc1f1, 0xc1f3, 0xc1fc, 0xc1fd, 0xc200, + 0xc204, 0xc20c, 0xc20d, 0xc20f, 0xc211, 0xc218, 0xc219, 0xc21c, + 0xc21f, 0xc220, 0xc228, 0xc229, 0xc22b, 0xc22d, + /* 0x3d */ + 0xc22f, 0xc231, 0xc232, 0xc234, 0xc248, 0xc250, 0xc251, 0xc254, + 0xc258, 0xc260, 0xc265, 0xc26c, 0xc26d, 0xc270, 0xc274, 0xc27c, + 0xc27d, 0xc27f, 0xc281, 0xc288, 0xc289, 0xc290, 0xc298, 0xc29b, + 0xc29d, 0xc2a4, 0xc2a5, 0xc2a8, 0xc2ac, 0xc2ad, 0xc2b4, 0xc2b5, + 0xc2b7, 0xc2b9, 0xc2dc, 0xc2dd, 0xc2e0, 0xc2e3, 0xc2e4, 0xc2eb, + 0xc2ec, 0xc2ed, 0xc2ef, 0xc2f1, 0xc2f6, 0xc2f8, 0xc2f9, 0xc2fb, + 0xc2fc, 0xc300, 0xc308, 0xc309, 0xc30c, 0xc30d, 0xc313, 0xc314, + 0xc315, 0xc318, 0xc31c, 0xc324, 0xc325, 0xc328, 0xc329, 0xc345, + 0xc368, 0xc369, 0xc36c, 0xc370, 0xc372, 0xc378, 0xc379, 0xc37c, + 0xc37d, 0xc384, 0xc388, 0xc38c, 0xc3c0, 0xc3d8, 0xc3d9, 0xc3dc, + 0xc3df, 0xc3e0, 0xc3e2, 0xc3e8, 0xc3e9, 0xc3ed, 0xc3f4, 0xc3f5, + 0xc3f8, 0xc408, 0xc410, 0xc424, 0xc42c, 0xc430, + /* 0x3e */ + 0xc434, 0xc43c, 0xc43d, 0xc448, 0xc464, 0xc465, 0xc468, 0xc46c, + 0xc474, 0xc475, 0xc479, 0xc480, 0xc494, 0xc49c, 0xc4b8, 0xc4bc, + 0xc4e9, 0xc4f0, 0xc4f1, 0xc4f4, 0xc4f8, 0xc4fa, 0xc4ff, 0xc500, + 0xc501, 0xc50c, 0xc510, 0xc514, 0xc51c, 0xc528, 0xc529, 0xc52c, + 0xc530, 0xc538, 0xc539, 0xc53b, 0xc53d, 0xc544, 0xc545, 0xc548, + 0xc549, 0xc54a, 0xc54c, 0xc54d, 0xc54e, 0xc553, 0xc554, 0xc555, + 0xc557, 0xc558, 0xc559, 0xc55d, 0xc55e, 0xc560, 0xc561, 0xc564, + 0xc568, 0xc570, 0xc571, 0xc573, 0xc574, 0xc575, 0xc57c, 0xc57d, + 0xc580, 0xc584, 0xc587, 0xc58c, 0xc58d, 0xc58f, 0xc591, 0xc595, + 0xc597, 0xc598, 0xc59c, 0xc5a0, 0xc5a9, 0xc5b4, 0xc5b5, 0xc5b8, + 0xc5b9, 0xc5bb, 0xc5bc, 0xc5bd, 0xc5be, 0xc5c4, 0xc5c5, 0xc5c6, + 0xc5c7, 0xc5c8, 0xc5c9, 0xc5ca, 0xc5cc, 0xc5ce, + /* 0x3f */ + 0xc5d0, 0xc5d1, 0xc5d4, 0xc5d8, 0xc5e0, 0xc5e1, 0xc5e3, 0xc5e5, + 0xc5ec, 0xc5ed, 0xc5ee, 0xc5f0, 0xc5f4, 0xc5f6, 0xc5f7, 0xc5fc, + 0xc5fd, 0xc5fe, 0xc5ff, 0xc600, 0xc601, 0xc605, 0xc606, 0xc607, + 0xc608, 0xc60c, 0xc610, 0xc618, 0xc619, 0xc61b, 0xc61c, 0xc624, + 0xc625, 0xc628, 0xc62c, 0xc62d, 0xc62e, 0xc630, 0xc633, 0xc634, + 0xc635, 0xc637, 0xc639, 0xc63b, 0xc640, 0xc641, 0xc644, 0xc648, + 0xc650, 0xc651, 0xc653, 0xc654, 0xc655, 0xc65c, 0xc65d, 0xc660, + 0xc66c, 0xc66f, 0xc671, 0xc678, 0xc679, 0xc67c, 0xc680, 0xc688, + 0xc689, 0xc68b, 0xc68d, 0xc694, 0xc695, 0xc698, 0xc69c, 0xc6a4, + 0xc6a5, 0xc6a7, 0xc6a9, 0xc6b0, 0xc6b1, 0xc6b4, 0xc6b8, 0xc6b9, + 0xc6ba, 0xc6c0, 0xc6c1, 0xc6c3, 0xc6c5, 0xc6cc, 0xc6cd, 0xc6d0, + 0xc6d4, 0xc6dc, 0xc6dd, 0xc6e0, 0xc6e1, 0xc6e8, + /* 0x40 */ + 0xc6e9, 0xc6ec, 0xc6f0, 0xc6f8, 0xc6f9, 0xc6fd, 0xc704, 0xc705, + 0xc708, 0xc70c, 0xc714, 0xc715, 0xc717, 0xc719, 0xc720, 0xc721, + 0xc724, 0xc728, 0xc730, 0xc731, 0xc733, 0xc735, 0xc737, 0xc73c, + 0xc73d, 0xc740, 0xc744, 0xc74a, 0xc74c, 0xc74d, 0xc74f, 0xc751, + 0xc752, 0xc753, 0xc754, 0xc755, 0xc756, 0xc757, 0xc758, 0xc75c, + 0xc760, 0xc768, 0xc76b, 0xc774, 0xc775, 0xc778, 0xc77c, 0xc77d, + 0xc77e, 0xc783, 0xc784, 0xc785, 0xc787, 0xc788, 0xc789, 0xc78a, + 0xc78e, 0xc790, 0xc791, 0xc794, 0xc796, 0xc797, 0xc798, 0xc79a, + 0xc7a0, 0xc7a1, 0xc7a3, 0xc7a4, 0xc7a5, 0xc7a6, 0xc7ac, 0xc7ad, + 0xc7b0, 0xc7b4, 0xc7bc, 0xc7bd, 0xc7bf, 0xc7c0, 0xc7c1, 0xc7c8, + 0xc7c9, 0xc7cc, 0xc7ce, 0xc7d0, 0xc7d8, 0xc7dd, 0xc7e4, 0xc7e8, + 0xc7ec, 0xc800, 0xc801, 0xc804, 0xc808, 0xc80a, + /* 0x41 */ + 0xc810, 0xc811, 0xc813, 0xc815, 0xc816, 0xc81c, 0xc81d, 0xc820, + 0xc824, 0xc82c, 0xc82d, 0xc82f, 0xc831, 0xc838, 0xc83c, 0xc840, + 0xc848, 0xc849, 0xc84c, 0xc84d, 0xc854, 0xc870, 0xc871, 0xc874, + 0xc878, 0xc87a, 0xc880, 0xc881, 0xc883, 0xc885, 0xc886, 0xc887, + 0xc88b, 0xc88c, 0xc88d, 0xc894, 0xc89d, 0xc89f, 0xc8a1, 0xc8a8, + 0xc8bc, 0xc8bd, 0xc8c4, 0xc8c8, 0xc8cc, 0xc8d4, 0xc8d5, 0xc8d7, + 0xc8d9, 0xc8e0, 0xc8e1, 0xc8e4, 0xc8f5, 0xc8fc, 0xc8fd, 0xc900, + 0xc904, 0xc905, 0xc906, 0xc90c, 0xc90d, 0xc90f, 0xc911, 0xc918, + 0xc92c, 0xc934, 0xc950, 0xc951, 0xc954, 0xc958, 0xc960, 0xc961, + 0xc963, 0xc96c, 0xc970, 0xc974, 0xc97c, 0xc988, 0xc989, 0xc98c, + 0xc990, 0xc998, 0xc999, 0xc99b, 0xc99d, 0xc9c0, 0xc9c1, 0xc9c4, + 0xc9c7, 0xc9c8, 0xc9ca, 0xc9d0, 0xc9d1, 0xc9d3, + /* 0x42 */ + 0xc9d5, 0xc9d6, 0xc9d9, 0xc9da, 0xc9dc, 0xc9dd, 0xc9e0, 0xc9e2, + 0xc9e4, 0xc9e7, 0xc9ec, 0xc9ed, 0xc9ef, 0xc9f0, 0xc9f1, 0xc9f8, + 0xc9f9, 0xc9fc, 0xca00, 0xca08, 0xca09, 0xca0b, 0xca0c, 0xca0d, + 0xca14, 0xca18, 0xca29, 0xca4c, 0xca4d, 0xca50, 0xca54, 0xca5c, + 0xca5d, 0xca5f, 0xca60, 0xca61, 0xca68, 0xca7d, 0xca84, 0xca98, + 0xcabc, 0xcabd, 0xcac0, 0xcac4, 0xcacc, 0xcacd, 0xcacf, 0xcad1, + 0xcad3, 0xcad8, 0xcad9, 0xcae0, 0xcaec, 0xcaf4, 0xcb08, 0xcb10, + 0xcb14, 0xcb18, 0xcb20, 0xcb21, 0xcb41, 0xcb48, 0xcb49, 0xcb4c, + 0xcb50, 0xcb58, 0xcb59, 0xcb5d, 0xcb64, 0xcb78, 0xcb79, 0xcb9c, + 0xcbb8, 0xcbd4, 0xcbe4, 0xcbe7, 0xcbe9, 0xcc0c, 0xcc0d, 0xcc10, + 0xcc14, 0xcc1c, 0xcc1d, 0xcc21, 0xcc22, 0xcc27, 0xcc28, 0xcc29, + 0xcc2c, 0xcc2e, 0xcc30, 0xcc38, 0xcc39, 0xcc3b, + /* 0x43 */ + 0xcc3c, 0xcc3d, 0xcc3e, 0xcc44, 0xcc45, 0xcc48, 0xcc4c, 0xcc54, + 0xcc55, 0xcc57, 0xcc58, 0xcc59, 0xcc60, 0xcc64, 0xcc66, 0xcc68, + 0xcc70, 0xcc75, 0xcc98, 0xcc99, 0xcc9c, 0xcca0, 0xcca8, 0xcca9, + 0xccab, 0xccac, 0xccad, 0xccb4, 0xccb5, 0xccb8, 0xccbc, 0xccc4, + 0xccc5, 0xccc7, 0xccc9, 0xccd0, 0xccd4, 0xcce4, 0xccec, 0xccf0, + 0xcd01, 0xcd08, 0xcd09, 0xcd0c, 0xcd10, 0xcd18, 0xcd19, 0xcd1b, + 0xcd1d, 0xcd24, 0xcd28, 0xcd2c, 0xcd39, 0xcd5c, 0xcd60, 0xcd64, + 0xcd6c, 0xcd6d, 0xcd6f, 0xcd71, 0xcd78, 0xcd88, 0xcd94, 0xcd95, + 0xcd98, 0xcd9c, 0xcda4, 0xcda5, 0xcda7, 0xcda9, 0xcdb0, 0xcdc4, + 0xcdcc, 0xcdd0, 0xcde8, 0xcdec, 0xcdf0, 0xcdf8, 0xcdf9, 0xcdfb, + 0xcdfd, 0xce04, 0xce08, 0xce0c, 0xce14, 0xce19, 0xce20, 0xce21, + 0xce24, 0xce28, 0xce30, 0xce31, 0xce33, 0xce35, + /* 0x44 */ + 0xce58, 0xce59, 0xce5c, 0xce5f, 0xce60, 0xce61, 0xce68, 0xce69, + 0xce6b, 0xce6d, 0xce74, 0xce75, 0xce78, 0xce7c, 0xce84, 0xce85, + 0xce87, 0xce89, 0xce90, 0xce91, 0xce94, 0xce98, 0xcea0, 0xcea1, + 0xcea3, 0xcea4, 0xcea5, 0xceac, 0xcead, 0xcec1, 0xcee4, 0xcee5, + 0xcee8, 0xceeb, 0xceec, 0xcef4, 0xcef5, 0xcef7, 0xcef8, 0xcef9, + 0xcf00, 0xcf01, 0xcf04, 0xcf08, 0xcf10, 0xcf11, 0xcf13, 0xcf15, + 0xcf1c, 0xcf20, 0xcf24, 0xcf2c, 0xcf2d, 0xcf2f, 0xcf30, 0xcf31, + 0xcf38, 0xcf54, 0xcf55, 0xcf58, 0xcf5c, 0xcf64, 0xcf65, 0xcf67, + 0xcf69, 0xcf70, 0xcf71, 0xcf74, 0xcf78, 0xcf80, 0xcf85, 0xcf8c, + 0xcfa1, 0xcfa8, 0xcfb0, 0xcfc4, 0xcfe0, 0xcfe1, 0xcfe4, 0xcfe8, + 0xcff0, 0xcff1, 0xcff3, 0xcff5, 0xcffc, 0xd000, 0xd004, 0xd011, + 0xd018, 0xd02d, 0xd034, 0xd035, 0xd038, 0xd03c, + /* 0x45 */ + 0xd044, 0xd045, 0xd047, 0xd049, 0xd050, 0xd054, 0xd058, 0xd060, + 0xd06c, 0xd06d, 0xd070, 0xd074, 0xd07c, 0xd07d, 0xd081, 0xd0a4, + 0xd0a5, 0xd0a8, 0xd0ac, 0xd0b4, 0xd0b5, 0xd0b7, 0xd0b9, 0xd0c0, + 0xd0c1, 0xd0c4, 0xd0c8, 0xd0c9, 0xd0d0, 0xd0d1, 0xd0d3, 0xd0d4, + 0xd0d5, 0xd0dc, 0xd0dd, 0xd0e0, 0xd0e4, 0xd0ec, 0xd0ed, 0xd0ef, + 0xd0f0, 0xd0f1, 0xd0f8, 0xd10d, 0xd130, 0xd131, 0xd134, 0xd138, + 0xd13a, 0xd140, 0xd141, 0xd143, 0xd144, 0xd145, 0xd14c, 0xd14d, + 0xd150, 0xd154, 0xd15c, 0xd15d, 0xd15f, 0xd161, 0xd168, 0xd16c, + 0xd17c, 0xd184, 0xd188, 0xd1a0, 0xd1a1, 0xd1a4, 0xd1a8, 0xd1b0, + 0xd1b1, 0xd1b3, 0xd1b5, 0xd1ba, 0xd1bc, 0xd1c0, 0xd1d8, 0xd1f4, + 0xd1f8, 0xd207, 0xd209, 0xd210, 0xd22c, 0xd22d, 0xd230, 0xd234, + 0xd23c, 0xd23d, 0xd23f, 0xd241, 0xd248, 0xd25c, + /* 0x46 */ + 0xd264, 0xd280, 0xd281, 0xd284, 0xd288, 0xd290, 0xd291, 0xd295, + 0xd29c, 0xd2a0, 0xd2a4, 0xd2ac, 0xd2b1, 0xd2b8, 0xd2b9, 0xd2bc, + 0xd2bf, 0xd2c0, 0xd2c2, 0xd2c8, 0xd2c9, 0xd2cb, 0xd2d4, 0xd2d8, + 0xd2dc, 0xd2e4, 0xd2e5, 0xd2f0, 0xd2f1, 0xd2f4, 0xd2f8, 0xd300, + 0xd301, 0xd303, 0xd305, 0xd30c, 0xd30d, 0xd30e, 0xd310, 0xd314, + 0xd316, 0xd31c, 0xd31d, 0xd31f, 0xd320, 0xd321, 0xd325, 0xd328, + 0xd329, 0xd32c, 0xd330, 0xd338, 0xd339, 0xd33b, 0xd33c, 0xd33d, + 0xd344, 0xd345, 0xd37c, 0xd37d, 0xd380, 0xd384, 0xd38c, 0xd38d, + 0xd38f, 0xd390, 0xd391, 0xd398, 0xd399, 0xd39c, 0xd3a0, 0xd3a8, + 0xd3a9, 0xd3ab, 0xd3ad, 0xd3b4, 0xd3b8, 0xd3bc, 0xd3c4, 0xd3c5, + 0xd3c8, 0xd3c9, 0xd3d0, 0xd3d8, 0xd3e1, 0xd3e3, 0xd3ec, 0xd3ed, + 0xd3f0, 0xd3f4, 0xd3fc, 0xd3fd, 0xd3ff, 0xd401, + /* 0x47 */ + 0xd408, 0xd41d, 0xd440, 0xd444, 0xd45c, 0xd460, 0xd464, 0xd46d, + 0xd46f, 0xd478, 0xd479, 0xd47c, 0xd47f, 0xd480, 0xd482, 0xd488, + 0xd489, 0xd48b, 0xd48d, 0xd494, 0xd4a9, 0xd4cc, 0xd4d0, 0xd4d4, + 0xd4dc, 0xd4df, 0xd4e8, 0xd4ec, 0xd4f0, 0xd4f8, 0xd4fb, 0xd4fd, + 0xd504, 0xd508, 0xd50c, 0xd514, 0xd515, 0xd517, 0xd53c, 0xd53d, + 0xd540, 0xd544, 0xd54c, 0xd54d, 0xd54f, 0xd551, 0xd558, 0xd559, + 0xd55c, 0xd560, 0xd565, 0xd568, 0xd569, 0xd56b, 0xd56d, 0xd574, + 0xd575, 0xd578, 0xd57c, 0xd584, 0xd585, 0xd587, 0xd588, 0xd589, + 0xd590, 0xd5a5, 0xd5c8, 0xd5c9, 0xd5cc, 0xd5d0, 0xd5d2, 0xd5d8, + 0xd5d9, 0xd5db, 0xd5dd, 0xd5e4, 0xd5e5, 0xd5e8, 0xd5ec, 0xd5f4, + 0xd5f5, 0xd5f7, 0xd5f9, 0xd600, 0xd601, 0xd604, 0xd608, 0xd610, + 0xd611, 0xd613, 0xd614, 0xd615, 0xd61c, 0xd620, + /* 0x48 */ + 0xd624, 0xd62d, 0xd638, 0xd639, 0xd63c, 0xd640, 0xd645, 0xd648, + 0xd649, 0xd64b, 0xd64d, 0xd651, 0xd654, 0xd655, 0xd658, 0xd65c, + 0xd667, 0xd669, 0xd670, 0xd671, 0xd674, 0xd683, 0xd685, 0xd68c, + 0xd68d, 0xd690, 0xd694, 0xd69d, 0xd69f, 0xd6a1, 0xd6a8, 0xd6ac, + 0xd6b0, 0xd6b9, 0xd6bb, 0xd6c4, 0xd6c5, 0xd6c8, 0xd6cc, 0xd6d1, + 0xd6d4, 0xd6d7, 0xd6d9, 0xd6e0, 0xd6e4, 0xd6e8, 0xd6f0, 0xd6f5, + 0xd6fc, 0xd6fd, 0xd700, 0xd704, 0xd711, 0xd718, 0xd719, 0xd71c, + 0xd720, 0xd728, 0xd729, 0xd72b, 0xd72d, 0xd734, 0xd735, 0xd738, + 0xd73c, 0xd744, 0xd747, 0xd749, 0xd750, 0xd751, 0xd754, 0xd756, + 0xd757, 0xd758, 0xd759, 0xd760, 0xd761, 0xd763, 0xd765, 0xd769, + 0xd76c, 0xd770, 0xd774, 0xd77c, 0xd77d, 0xd781, 0xd788, 0xd789, + 0xd78c, 0xd790, 0xd798, 0xd799, 0xd79b, 0xd79d, +}; +static const unsigned short ksc5601_2uni_page4a[4888] = { + /* 0x4a */ + 0x4f3d, 0x4f73, 0x5047, 0x50f9, 0x52a0, 0x53ef, 0x5475, 0x54e5, + 0x5609, 0x5ac1, 0x5bb6, 0x6687, 0x67b6, 0x67b7, 0x67ef, 0x6b4c, + 0x73c2, 0x75c2, 0x7a3c, 0x82db, 0x8304, 0x8857, 0x8888, 0x8a36, + 0x8cc8, 0x8dcf, 0x8efb, 0x8fe6, 0x99d5, 0x523b, 0x5374, 0x5404, + 0x606a, 0x6164, 0x6bbc, 0x73cf, 0x811a, 0x89ba, 0x89d2, 0x95a3, + 0x4f83, 0x520a, 0x58be, 0x5978, 0x59e6, 0x5e72, 0x5e79, 0x61c7, + 0x63c0, 0x6746, 0x67ec, 0x687f, 0x6f97, 0x764e, 0x770b, 0x78f5, + 0x7a08, 0x7aff, 0x7c21, 0x809d, 0x826e, 0x8271, 0x8aeb, 0x9593, + 0x4e6b, 0x559d, 0x66f7, 0x6e34, 0x78a3, 0x7aed, 0x845b, 0x8910, + 0x874e, 0x97a8, 0x52d8, 0x574e, 0x582a, 0x5d4c, 0x611f, 0x61be, + 0x6221, 0x6562, 0x67d1, 0x6a44, 0x6e1b, 0x7518, 0x75b3, 0x76e3, + 0x77b0, 0x7d3a, 0x90af, 0x9451, 0x9452, 0x9f95, + /* 0x4b */ + 0x5323, 0x5cac, 0x7532, 0x80db, 0x9240, 0x9598, 0x525b, 0x5808, + 0x59dc, 0x5ca1, 0x5d17, 0x5eb7, 0x5f3a, 0x5f4a, 0x6177, 0x6c5f, + 0x757a, 0x7586, 0x7ce0, 0x7d73, 0x7db1, 0x7f8c, 0x8154, 0x8221, + 0x8591, 0x8941, 0x8b1b, 0x92fc, 0x964d, 0x9c47, 0x4ecb, 0x4ef7, + 0x500b, 0x51f1, 0x584f, 0x6137, 0x613e, 0x6168, 0x6539, 0x69ea, + 0x6f11, 0x75a5, 0x7686, 0x76d6, 0x7b87, 0x82a5, 0x84cb, 0xf900, + 0x93a7, 0x958b, 0x5580, 0x5ba2, 0x5751, 0xf901, 0x7cb3, 0x7fb9, + 0x91b5, 0x5028, 0x53bb, 0x5c45, 0x5de8, 0x62d2, 0x636e, 0x64da, + 0x64e7, 0x6e20, 0x70ac, 0x795b, 0x8ddd, 0x8e1e, 0xf902, 0x907d, + 0x9245, 0x92f8, 0x4e7e, 0x4ef6, 0x5065, 0x5dfe, 0x5efa, 0x6106, + 0x6957, 0x8171, 0x8654, 0x8e47, 0x9375, 0x9a2b, 0x4e5e, 0x5091, + 0x6770, 0x6840, 0x5109, 0x528d, 0x5292, 0x6aa2, + /* 0x4c */ + 0x77bc, 0x9210, 0x9ed4, 0x52ab, 0x602f, 0x8ff2, 0x5048, 0x61a9, + 0x63ed, 0x64ca, 0x683c, 0x6a84, 0x6fc0, 0x8188, 0x89a1, 0x9694, + 0x5805, 0x727d, 0x72ac, 0x7504, 0x7d79, 0x7e6d, 0x80a9, 0x898b, + 0x8b74, 0x9063, 0x9d51, 0x6289, 0x6c7a, 0x6f54, 0x7d50, 0x7f3a, + 0x8a23, 0x517c, 0x614a, 0x7b9d, 0x8b19, 0x9257, 0x938c, 0x4eac, + 0x4fd3, 0x501e, 0x50be, 0x5106, 0x52c1, 0x52cd, 0x537f, 0x5770, + 0x5883, 0x5e9a, 0x5f91, 0x6176, 0x61ac, 0x64ce, 0x656c, 0x666f, + 0x66bb, 0x66f4, 0x6897, 0x6d87, 0x7085, 0x70f1, 0x749f, 0x74a5, + 0x74ca, 0x75d9, 0x786c, 0x78ec, 0x7adf, 0x7af6, 0x7d45, 0x7d93, + 0x8015, 0x803f, 0x811b, 0x8396, 0x8b66, 0x8f15, 0x9015, 0x93e1, + 0x9803, 0x9838, 0x9a5a, 0x9be8, 0x4fc2, 0x5553, 0x583a, 0x5951, + 0x5b63, 0x5c46, 0x60b8, 0x6212, 0x6842, 0x68b0, + /* 0x4d */ + 0x68e8, 0x6eaa, 0x754c, 0x7678, 0x78ce, 0x7a3d, 0x7cfb, 0x7e6b, + 0x7e7c, 0x8a08, 0x8aa1, 0x8c3f, 0x968e, 0x9dc4, 0x53e4, 0x53e9, + 0x544a, 0x5471, 0x56fa, 0x59d1, 0x5b64, 0x5c3b, 0x5eab, 0x62f7, + 0x6537, 0x6545, 0x6572, 0x66a0, 0x67af, 0x69c1, 0x6cbd, 0x75fc, + 0x7690, 0x777e, 0x7a3f, 0x7f94, 0x8003, 0x80a1, 0x818f, 0x82e6, + 0x82fd, 0x83f0, 0x85c1, 0x8831, 0x88b4, 0x8aa5, 0xf903, 0x8f9c, + 0x932e, 0x96c7, 0x9867, 0x9ad8, 0x9f13, 0x54ed, 0x659b, 0x66f2, + 0x688f, 0x7a40, 0x8c37, 0x9d60, 0x56f0, 0x5764, 0x5d11, 0x6606, + 0x68b1, 0x68cd, 0x6efe, 0x7428, 0x889e, 0x9be4, 0x6c68, 0xf904, + 0x9aa8, 0x4f9b, 0x516c, 0x5171, 0x529f, 0x5b54, 0x5de5, 0x6050, + 0x606d, 0x62f1, 0x63a7, 0x653b, 0x73d9, 0x7a7a, 0x86a3, 0x8ca2, + 0x978f, 0x4e32, 0x5be1, 0x6208, 0x679c, 0x74dc, + /* 0x4e */ + 0x79d1, 0x83d3, 0x8a87, 0x8ab2, 0x8de8, 0x904e, 0x934b, 0x9846, + 0x5ed3, 0x69e8, 0x85ff, 0x90ed, 0xf905, 0x51a0, 0x5b98, 0x5bec, + 0x6163, 0x68fa, 0x6b3e, 0x704c, 0x742f, 0x74d8, 0x7ba1, 0x7f50, + 0x83c5, 0x89c0, 0x8cab, 0x95dc, 0x9928, 0x522e, 0x605d, 0x62ec, + 0x9002, 0x4f8a, 0x5149, 0x5321, 0x58d9, 0x5ee3, 0x66e0, 0x6d38, + 0x709a, 0x72c2, 0x73d6, 0x7b50, 0x80f1, 0x945b, 0x5366, 0x639b, + 0x7f6b, 0x4e56, 0x5080, 0x584a, 0x58de, 0x602a, 0x6127, 0x62d0, + 0x69d0, 0x9b41, 0x5b8f, 0x7d18, 0x80b1, 0x8f5f, 0x4ea4, 0x50d1, + 0x54ac, 0x55ac, 0x5b0c, 0x5da0, 0x5de7, 0x652a, 0x654e, 0x6821, + 0x6a4b, 0x72e1, 0x768e, 0x77ef, 0x7d5e, 0x7ff9, 0x81a0, 0x854e, + 0x86df, 0x8f03, 0x8f4e, 0x90ca, 0x9903, 0x9a55, 0x9bab, 0x4e18, + 0x4e45, 0x4e5d, 0x4ec7, 0x4ff1, 0x5177, 0x52fe, + /* 0x4f */ + 0x5340, 0x53e3, 0x53e5, 0x548e, 0x5614, 0x5775, 0x57a2, 0x5bc7, + 0x5d87, 0x5ed0, 0x61fc, 0x62d8, 0x6551, 0x67b8, 0x67e9, 0x69cb, + 0x6b50, 0x6bc6, 0x6bec, 0x6c42, 0x6e9d, 0x7078, 0x72d7, 0x7396, + 0x7403, 0x77bf, 0x77e9, 0x7a76, 0x7d7f, 0x8009, 0x81fc, 0x8205, + 0x820a, 0x82df, 0x8862, 0x8b33, 0x8cfc, 0x8ec0, 0x9011, 0x90b1, + 0x9264, 0x92b6, 0x99d2, 0x9a45, 0x9ce9, 0x9dd7, 0x9f9c, 0x570b, + 0x5c40, 0x83ca, 0x97a0, 0x97ab, 0x9eb4, 0x541b, 0x7a98, 0x7fa4, + 0x88d9, 0x8ecd, 0x90e1, 0x5800, 0x5c48, 0x6398, 0x7a9f, 0x5bae, + 0x5f13, 0x7a79, 0x7aae, 0x828e, 0x8eac, 0x5026, 0x5238, 0x52f8, + 0x5377, 0x5708, 0x62f3, 0x6372, 0x6b0a, 0x6dc3, 0x7737, 0x53a5, + 0x7357, 0x8568, 0x8e76, 0x95d5, 0x673a, 0x6ac3, 0x6f70, 0x8a6d, + 0x8ecc, 0x994b, 0xf906, 0x6677, 0x6b78, 0x8cb4, + /* 0x50 */ + 0x9b3c, 0xf907, 0x53eb, 0x572d, 0x594e, 0x63c6, 0x69fb, 0x73ea, + 0x7845, 0x7aba, 0x7ac5, 0x7cfe, 0x8475, 0x898f, 0x8d73, 0x9035, + 0x95a8, 0x52fb, 0x5747, 0x7547, 0x7b60, 0x83cc, 0x921e, 0xf908, + 0x6a58, 0x514b, 0x524b, 0x5287, 0x621f, 0x68d8, 0x6975, 0x9699, + 0x50c5, 0x52a4, 0x52e4, 0x61c3, 0x65a4, 0x6839, 0x69ff, 0x747e, + 0x7b4b, 0x82b9, 0x83eb, 0x89b2, 0x8b39, 0x8fd1, 0x9949, 0xf909, + 0x4eca, 0x5997, 0x64d2, 0x6611, 0x6a8e, 0x7434, 0x7981, 0x79bd, + 0x82a9, 0x887e, 0x887f, 0x895f, 0xf90a, 0x9326, 0x4f0b, 0x53ca, + 0x6025, 0x6271, 0x6c72, 0x7d1a, 0x7d66, 0x4e98, 0x5162, 0x77dc, + 0x80af, 0x4f01, 0x4f0e, 0x5176, 0x5180, 0x55dc, 0x5668, 0x573b, + 0x57fa, 0x57fc, 0x5914, 0x5947, 0x5993, 0x5bc4, 0x5c90, 0x5d0e, + 0x5df1, 0x5e7e, 0x5fcc, 0x6280, 0x65d7, 0x65e3, + /* 0x51 */ + 0x671e, 0x671f, 0x675e, 0x68cb, 0x68c4, 0x6a5f, 0x6b3a, 0x6c23, + 0x6c7d, 0x6c82, 0x6dc7, 0x7398, 0x7426, 0x742a, 0x7482, 0x74a3, + 0x7578, 0x757f, 0x7881, 0x78ef, 0x7941, 0x7947, 0x7948, 0x797a, + 0x7b95, 0x7d00, 0x7dba, 0x7f88, 0x8006, 0x802d, 0x808c, 0x8a18, + 0x8b4f, 0x8c48, 0x8d77, 0x9321, 0x9324, 0x98e2, 0x9951, 0x9a0e, + 0x9a0f, 0x9a65, 0x9e92, 0x7dca, 0x4f76, 0x5409, 0x62ee, 0x6854, + 0x91d1, 0x55ab, 0x513a, 0xf90b, 0xf90c, 0x5a1c, 0x61e6, 0xf90d, + 0x62cf, 0x62ff, 0xf90e, 0xf90f, 0xf910, 0xf911, 0xf912, 0xf913, + 0x90a3, 0xf914, 0xf915, 0xf916, 0xf917, 0xf918, 0x8afe, 0xf919, + 0xf91a, 0xf91b, 0xf91c, 0x6696, 0xf91d, 0x7156, 0xf91e, 0xf91f, + 0x96e3, 0xf920, 0x634f, 0x637a, 0x5357, 0xf921, 0x678f, 0x6960, + 0x6e73, 0xf922, 0x7537, 0xf923, 0xf924, 0xf925, + /* 0x52 */ + 0x7d0d, 0xf926, 0xf927, 0x8872, 0x56ca, 0x5a18, 0xf928, 0xf929, + 0xf92a, 0xf92b, 0xf92c, 0x4e43, 0xf92d, 0x5167, 0x5948, 0x67f0, + 0x8010, 0xf92e, 0x5973, 0x5e74, 0x649a, 0x79ca, 0x5ff5, 0x606c, + 0x62c8, 0x637b, 0x5be7, 0x5bd7, 0x52aa, 0xf92f, 0x5974, 0x5f29, + 0x6012, 0xf930, 0xf931, 0xf932, 0x7459, 0xf933, 0xf934, 0xf935, + 0xf936, 0xf937, 0xf938, 0x99d1, 0xf939, 0xf93a, 0xf93b, 0xf93c, + 0xf93d, 0xf93e, 0xf93f, 0xf940, 0xf941, 0xf942, 0xf943, 0x6fc3, + 0xf944, 0xf945, 0x81bf, 0x8fb2, 0x60f1, 0xf946, 0xf947, 0x8166, + 0xf948, 0xf949, 0x5c3f, 0xf94a, 0xf94b, 0xf94c, 0xf94d, 0xf94e, + 0xf94f, 0xf950, 0xf951, 0x5ae9, 0x8a25, 0x677b, 0x7d10, 0xf952, + 0xf953, 0xf954, 0xf955, 0xf956, 0xf957, 0x80fd, 0xf958, 0xf959, + 0x5c3c, 0x6ce5, 0x533f, 0x6eba, 0x591a, 0x8336, + /* 0x53 */ + 0x4e39, 0x4eb6, 0x4f46, 0x55ae, 0x5718, 0x58c7, 0x5f56, 0x65b7, + 0x65e6, 0x6a80, 0x6bb5, 0x6e4d, 0x77ed, 0x7aef, 0x7c1e, 0x7dde, + 0x86cb, 0x8892, 0x9132, 0x935b, 0x64bb, 0x6fbe, 0x737a, 0x75b8, + 0x9054, 0x5556, 0x574d, 0x61ba, 0x64d4, 0x66c7, 0x6de1, 0x6e5b, + 0x6f6d, 0x6fb9, 0x75f0, 0x8043, 0x81bd, 0x8541, 0x8983, 0x8ac7, + 0x8b5a, 0x931f, 0x6c93, 0x7553, 0x7b54, 0x8e0f, 0x905d, 0x5510, + 0x5802, 0x5858, 0x5e62, 0x6207, 0x649e, 0x68e0, 0x7576, 0x7cd6, + 0x87b3, 0x9ee8, 0x4ee3, 0x5788, 0x576e, 0x5927, 0x5c0d, 0x5cb1, + 0x5e36, 0x5f85, 0x6234, 0x64e1, 0x73b3, 0x81fa, 0x888b, 0x8cb8, + 0x968a, 0x9edb, 0x5b85, 0x5fb7, 0x60b3, 0x5012, 0x5200, 0x5230, + 0x5716, 0x5835, 0x5857, 0x5c0e, 0x5c60, 0x5cf6, 0x5d8b, 0x5ea6, + 0x5f92, 0x60bc, 0x6311, 0x6389, 0x6417, 0x6843, + /* 0x54 */ + 0x68f9, 0x6ac2, 0x6dd8, 0x6e21, 0x6ed4, 0x6fe4, 0x71fe, 0x76dc, + 0x7779, 0x79b1, 0x7a3b, 0x8404, 0x89a9, 0x8ced, 0x8df3, 0x8e48, + 0x9003, 0x9014, 0x9053, 0x90fd, 0x934d, 0x9676, 0x97dc, 0x6bd2, + 0x7006, 0x7258, 0x72a2, 0x7368, 0x7763, 0x79bf, 0x7be4, 0x7e9b, + 0x8b80, 0x58a9, 0x60c7, 0x6566, 0x65fd, 0x66be, 0x6c8c, 0x711e, + 0x71c9, 0x8c5a, 0x9813, 0x4e6d, 0x7a81, 0x4edd, 0x51ac, 0x51cd, + 0x52d5, 0x540c, 0x61a7, 0x6771, 0x6850, 0x68df, 0x6d1e, 0x6f7c, + 0x75bc, 0x77b3, 0x7ae5, 0x80f4, 0x8463, 0x9285, 0x515c, 0x6597, + 0x675c, 0x6793, 0x75d8, 0x7ac7, 0x8373, 0xf95a, 0x8c46, 0x9017, + 0x982d, 0x5c6f, 0x81c0, 0x829a, 0x9041, 0x906f, 0x920d, 0x5f97, + 0x5d9d, 0x6a59, 0x71c8, 0x767b, 0x7b49, 0x85e4, 0x8b04, 0x9127, + 0x9a30, 0x5587, 0x61f6, 0xf95b, 0x7669, 0x7f85, + /* 0x55 */ + 0x863f, 0x87ba, 0x88f8, 0x908f, 0xf95c, 0x6d1b, 0x70d9, 0x73de, + 0x7d61, 0x843d, 0xf95d, 0x916a, 0x99f1, 0xf95e, 0x4e82, 0x5375, + 0x6b04, 0x6b12, 0x703e, 0x721b, 0x862d, 0x9e1e, 0x524c, 0x8fa3, + 0x5d50, 0x64e5, 0x652c, 0x6b16, 0x6feb, 0x7c43, 0x7e9c, 0x85cd, + 0x8964, 0x89bd, 0x62c9, 0x81d8, 0x881f, 0x5eca, 0x6717, 0x6d6a, + 0x72fc, 0x7405, 0x746f, 0x8782, 0x90de, 0x4f86, 0x5d0d, 0x5fa0, + 0x840a, 0x51b7, 0x63a0, 0x7565, 0x4eae, 0x5006, 0x5169, 0x51c9, + 0x6881, 0x6a11, 0x7cae, 0x7cb1, 0x7ce7, 0x826f, 0x8ad2, 0x8f1b, + 0x91cf, 0x4fb6, 0x5137, 0x52f5, 0x5442, 0x5eec, 0x616e, 0x623e, + 0x65c5, 0x6ada, 0x6ffe, 0x792a, 0x85dc, 0x8823, 0x95ad, 0x9a62, + 0x9a6a, 0x9e97, 0x9ece, 0x529b, 0x66c6, 0x6b77, 0x701d, 0x792b, + 0x8f62, 0x9742, 0x6190, 0x6200, 0x6523, 0x6f23, + /* 0x56 */ + 0x7149, 0x7489, 0x7df4, 0x806f, 0x84ee, 0x8f26, 0x9023, 0x934a, + 0x51bd, 0x5217, 0x52a3, 0x6d0c, 0x70c8, 0x88c2, 0x5ec9, 0x6582, + 0x6bae, 0x6fc2, 0x7c3e, 0x7375, 0x4ee4, 0x4f36, 0x56f9, 0xf95f, + 0x5cba, 0x5dba, 0x601c, 0x73b2, 0x7b2d, 0x7f9a, 0x7fce, 0x8046, + 0x901e, 0x9234, 0x96f6, 0x9748, 0x9818, 0x9f61, 0x4f8b, 0x6fa7, + 0x79ae, 0x91b4, 0x96b7, 0x52de, 0xf960, 0x6488, 0x64c4, 0x6ad3, + 0x6f5e, 0x7018, 0x7210, 0x76e7, 0x8001, 0x8606, 0x865c, 0x8def, + 0x8f05, 0x9732, 0x9b6f, 0x9dfa, 0x9e75, 0x788c, 0x797f, 0x7da0, + 0x83c9, 0x9304, 0x9e7f, 0x9e93, 0x8ad6, 0x58df, 0x5f04, 0x6727, + 0x7027, 0x74cf, 0x7c60, 0x807e, 0x5121, 0x7028, 0x7262, 0x78ca, + 0x8cc2, 0x8cda, 0x8cf4, 0x96f7, 0x4e86, 0x50da, 0x5bee, 0x5ed6, + 0x6599, 0x71ce, 0x7642, 0x77ad, 0x804a, 0x84fc, + /* 0x57 */ + 0x907c, 0x9b27, 0x9f8d, 0x58d8, 0x5a41, 0x5c62, 0x6a13, 0x6dda, + 0x6f0f, 0x763b, 0x7d2f, 0x7e37, 0x851e, 0x8938, 0x93e4, 0x964b, + 0x5289, 0x65d2, 0x67f3, 0x69b4, 0x6d41, 0x6e9c, 0x700f, 0x7409, + 0x7460, 0x7559, 0x7624, 0x786b, 0x8b2c, 0x985e, 0x516d, 0x622e, + 0x9678, 0x4f96, 0x502b, 0x5d19, 0x6dea, 0x7db8, 0x8f2a, 0x5f8b, + 0x6144, 0x6817, 0xf961, 0x9686, 0x52d2, 0x808b, 0x51dc, 0x51cc, + 0x695e, 0x7a1c, 0x7dbe, 0x83f1, 0x9675, 0x4fda, 0x5229, 0x5398, + 0x540f, 0x550e, 0x5c65, 0x60a7, 0x674e, 0x68a8, 0x6d6c, 0x7281, + 0x72f8, 0x7406, 0x7483, 0xf962, 0x75e2, 0x7c6c, 0x7f79, 0x7fb8, + 0x8389, 0x88cf, 0x88e1, 0x91cc, 0x91d0, 0x96e2, 0x9bc9, 0x541d, + 0x6f7e, 0x71d0, 0x7498, 0x85fa, 0x8eaa, 0x96a3, 0x9c57, 0x9e9f, + 0x6797, 0x6dcb, 0x7433, 0x81e8, 0x9716, 0x782c, + /* 0x58 */ + 0x7acb, 0x7b20, 0x7c92, 0x6469, 0x746a, 0x75f2, 0x78bc, 0x78e8, + 0x99ac, 0x9b54, 0x9ebb, 0x5bde, 0x5e55, 0x6f20, 0x819c, 0x83ab, + 0x9088, 0x4e07, 0x534d, 0x5a29, 0x5dd2, 0x5f4e, 0x6162, 0x633d, + 0x6669, 0x66fc, 0x6eff, 0x6f2b, 0x7063, 0x779e, 0x842c, 0x8513, + 0x883b, 0x8f13, 0x9945, 0x9c3b, 0x551c, 0x62b9, 0x672b, 0x6cab, + 0x8309, 0x896a, 0x977a, 0x4ea1, 0x5984, 0x5fd8, 0x5fd9, 0x671b, + 0x7db2, 0x7f54, 0x8292, 0x832b, 0x83bd, 0x8f1e, 0x9099, 0x57cb, + 0x59b9, 0x5a92, 0x5bd0, 0x6627, 0x679a, 0x6885, 0x6bcf, 0x7164, + 0x7f75, 0x8cb7, 0x8ce3, 0x9081, 0x9b45, 0x8108, 0x8c8a, 0x964c, + 0x9a40, 0x9ea5, 0x5b5f, 0x6c13, 0x731b, 0x76f2, 0x76df, 0x840c, + 0x51aa, 0x8993, 0x514d, 0x5195, 0x52c9, 0x68c9, 0x6c94, 0x7704, + 0x7720, 0x7dbf, 0x7dec, 0x9762, 0x9eb5, 0x6ec5, + /* 0x59 */ + 0x8511, 0x51a5, 0x540d, 0x547d, 0x660e, 0x669d, 0x6927, 0x6e9f, + 0x76bf, 0x7791, 0x8317, 0x84c2, 0x879f, 0x9169, 0x9298, 0x9cf4, + 0x8882, 0x4fae, 0x5192, 0x52df, 0x59c6, 0x5e3d, 0x6155, 0x6478, + 0x6479, 0x66ae, 0x67d0, 0x6a21, 0x6bcd, 0x6bdb, 0x725f, 0x7261, + 0x7441, 0x7738, 0x77db, 0x8017, 0x82bc, 0x8305, 0x8b00, 0x8b28, + 0x8c8c, 0x6728, 0x6c90, 0x7267, 0x76ee, 0x7766, 0x7a46, 0x9da9, + 0x6b7f, 0x6c92, 0x5922, 0x6726, 0x8499, 0x536f, 0x5893, 0x5999, + 0x5edf, 0x63cf, 0x6634, 0x6773, 0x6e3a, 0x732b, 0x7ad7, 0x82d7, + 0x9328, 0x52d9, 0x5deb, 0x61ae, 0x61cb, 0x620a, 0x62c7, 0x64ab, + 0x65e0, 0x6959, 0x6b66, 0x6bcb, 0x7121, 0x73f7, 0x755d, 0x7e46, + 0x821e, 0x8302, 0x856a, 0x8aa3, 0x8cbf, 0x9727, 0x9d61, 0x58a8, + 0x9ed8, 0x5011, 0x520e, 0x543b, 0x554f, 0x6587, + /* 0x5a */ + 0x6c76, 0x7d0a, 0x7d0b, 0x805e, 0x868a, 0x9580, 0x96ef, 0x52ff, + 0x6c95, 0x7269, 0x5473, 0x5a9a, 0x5c3e, 0x5d4b, 0x5f4c, 0x5fae, + 0x672a, 0x68b6, 0x6963, 0x6e3c, 0x6e44, 0x7709, 0x7c73, 0x7f8e, + 0x8587, 0x8b0e, 0x8ff7, 0x9761, 0x9ef4, 0x5cb7, 0x60b6, 0x610d, + 0x61ab, 0x654f, 0x65fb, 0x65fc, 0x6c11, 0x6cef, 0x739f, 0x73c9, + 0x7de1, 0x9594, 0x5bc6, 0x871c, 0x8b10, 0x525d, 0x535a, 0x62cd, + 0x640f, 0x64b2, 0x6734, 0x6a38, 0x6cca, 0x73c0, 0x749e, 0x7b94, + 0x7c95, 0x7e1b, 0x818a, 0x8236, 0x8584, 0x8feb, 0x96f9, 0x99c1, + 0x4f34, 0x534a, 0x53cd, 0x53db, 0x62cc, 0x642c, 0x6500, 0x6591, + 0x69c3, 0x6cee, 0x6f58, 0x73ed, 0x7554, 0x7622, 0x76e4, 0x76fc, + 0x78d0, 0x78fb, 0x792c, 0x7d46, 0x822c, 0x87e0, 0x8fd4, 0x9812, + 0x98ef, 0x52c3, 0x62d4, 0x64a5, 0x6e24, 0x6f51, + /* 0x5b */ + 0x767c, 0x8dcb, 0x91b1, 0x9262, 0x9aee, 0x9b43, 0x5023, 0x508d, + 0x574a, 0x59a8, 0x5c28, 0x5e47, 0x5f77, 0x623f, 0x653e, 0x65b9, + 0x65c1, 0x6609, 0x678b, 0x699c, 0x6ec2, 0x78c5, 0x7d21, 0x80aa, + 0x8180, 0x822b, 0x82b3, 0x84a1, 0x868c, 0x8a2a, 0x8b17, 0x90a6, + 0x9632, 0x9f90, 0x500d, 0x4ff3, 0xf963, 0x57f9, 0x5f98, 0x62dc, + 0x6392, 0x676f, 0x6e43, 0x7119, 0x76c3, 0x80cc, 0x80da, 0x88f4, + 0x88f5, 0x8919, 0x8ce0, 0x8f29, 0x914d, 0x966a, 0x4f2f, 0x4f70, + 0x5e1b, 0x67cf, 0x6822, 0x767d, 0x767e, 0x9b44, 0x5e61, 0x6a0a, + 0x7169, 0x71d4, 0x756a, 0xf964, 0x7e41, 0x8543, 0x85e9, 0x98dc, + 0x4f10, 0x7b4f, 0x7f70, 0x95a5, 0x51e1, 0x5e06, 0x68b5, 0x6c3e, + 0x6c4e, 0x6cdb, 0x72af, 0x7bc4, 0x8303, 0x6cd5, 0x743a, 0x50fb, + 0x5288, 0x58c1, 0x64d8, 0x6a97, 0x74a7, 0x7656, + /* 0x5c */ + 0x78a7, 0x8617, 0x95e2, 0x9739, 0xf965, 0x535e, 0x5f01, 0x8b8a, + 0x8fa8, 0x8faf, 0x908a, 0x5225, 0x77a5, 0x9c49, 0x9f08, 0x4e19, + 0x5002, 0x5175, 0x5c5b, 0x5e77, 0x661e, 0x663a, 0x67c4, 0x68c5, + 0x70b3, 0x7501, 0x75c5, 0x79c9, 0x7add, 0x8f27, 0x9920, 0x9a08, + 0x4fdd, 0x5821, 0x5831, 0x5bf6, 0x666e, 0x6b65, 0x6d11, 0x6e7a, + 0x6f7d, 0x73e4, 0x752b, 0x83e9, 0x88dc, 0x8913, 0x8b5c, 0x8f14, + 0x4f0f, 0x50d5, 0x5310, 0x535c, 0x5b93, 0x5fa9, 0x670d, 0x798f, + 0x8179, 0x832f, 0x8514, 0x8907, 0x8986, 0x8f39, 0x8f3b, 0x99a5, + 0x9c12, 0x672c, 0x4e76, 0x4ff8, 0x5949, 0x5c01, 0x5cef, 0x5cf0, + 0x6367, 0x68d2, 0x70fd, 0x71a2, 0x742b, 0x7e2b, 0x84ec, 0x8702, + 0x9022, 0x92d2, 0x9cf3, 0x4e0d, 0x4ed8, 0x4fef, 0x5085, 0x5256, + 0x526f, 0x5426, 0x5490, 0x57e0, 0x592b, 0x5a66, + /* 0x5d */ + 0x5b5a, 0x5b75, 0x5bcc, 0x5e9c, 0xf966, 0x6276, 0x6577, 0x65a7, + 0x6d6e, 0x6ea5, 0x7236, 0x7b26, 0x7c3f, 0x7f36, 0x8150, 0x8151, + 0x819a, 0x8240, 0x8299, 0x83a9, 0x8a03, 0x8ca0, 0x8ce6, 0x8cfb, + 0x8d74, 0x8dba, 0x90e8, 0x91dc, 0x961c, 0x9644, 0x99d9, 0x9ce7, + 0x5317, 0x5206, 0x5429, 0x5674, 0x58b3, 0x5954, 0x596e, 0x5fff, + 0x61a4, 0x626e, 0x6610, 0x6c7e, 0x711a, 0x76c6, 0x7c89, 0x7cde, + 0x7d1b, 0x82ac, 0x8cc1, 0x96f0, 0xf967, 0x4f5b, 0x5f17, 0x5f7f, + 0x62c2, 0x5d29, 0x670b, 0x68da, 0x787c, 0x7e43, 0x9d6c, 0x4e15, + 0x5099, 0x5315, 0x532a, 0x5351, 0x5983, 0x5a62, 0x5e87, 0x60b2, + 0x618a, 0x6249, 0x6279, 0x6590, 0x6787, 0x69a7, 0x6bd4, 0x6bd6, + 0x6bd7, 0x6bd8, 0x6cb8, 0xf968, 0x7435, 0x75fa, 0x7812, 0x7891, + 0x79d5, 0x79d8, 0x7c83, 0x7dcb, 0x7fe1, 0x80a5, + /* 0x5e */ + 0x813e, 0x81c2, 0x83f2, 0x871a, 0x88e8, 0x8ab9, 0x8b6c, 0x8cbb, + 0x9119, 0x975e, 0x98db, 0x9f3b, 0x56ac, 0x5b2a, 0x5f6c, 0x658c, + 0x6ab3, 0x6baf, 0x6d5c, 0x6ff1, 0x7015, 0x725d, 0x73ad, 0x8ca7, + 0x8cd3, 0x983b, 0x6191, 0x6c37, 0x8058, 0x9a01, 0x4e4d, 0x4e8b, + 0x4e9b, 0x4ed5, 0x4f3a, 0x4f3c, 0x4f7f, 0x4fdf, 0x50ff, 0x53f2, + 0x53f8, 0x5506, 0x55e3, 0x56db, 0x58eb, 0x5962, 0x5a11, 0x5beb, + 0x5bfa, 0x5c04, 0x5df3, 0x5e2b, 0x5f99, 0x601d, 0x6368, 0x659c, + 0x65af, 0x67f6, 0x67fb, 0x68ad, 0x6b7b, 0x6c99, 0x6cd7, 0x6e23, + 0x7009, 0x7345, 0x7802, 0x793e, 0x7940, 0x7960, 0x79c1, 0x7be9, + 0x7d17, 0x7d72, 0x8086, 0x820d, 0x838e, 0x84d1, 0x86c7, 0x88df, + 0x8a50, 0x8a5e, 0x8b1d, 0x8cdc, 0x8d66, 0x8fad, 0x90aa, 0x98fc, + 0x99df, 0x9e9d, 0x524a, 0xf969, 0x6714, 0xf96a, + /* 0x5f */ + 0x5098, 0x522a, 0x5c71, 0x6563, 0x6c55, 0x73ca, 0x7523, 0x759d, + 0x7b97, 0x849c, 0x9178, 0x9730, 0x4e77, 0x6492, 0x6bba, 0x715e, + 0x85a9, 0x4e09, 0xf96b, 0x6749, 0x68ee, 0x6e17, 0x829f, 0x8518, + 0x886b, 0x63f7, 0x6f81, 0x9212, 0x98af, 0x4e0a, 0x50b7, 0x50cf, + 0x511f, 0x5546, 0x55aa, 0x5617, 0x5b40, 0x5c19, 0x5ce0, 0x5e38, + 0x5e8a, 0x5ea0, 0x5ec2, 0x60f3, 0x6851, 0x6a61, 0x6e58, 0x723d, + 0x7240, 0x72c0, 0x76f8, 0x7965, 0x7bb1, 0x7fd4, 0x88f3, 0x89f4, + 0x8a73, 0x8c61, 0x8cde, 0x971c, 0x585e, 0x74bd, 0x8cfd, 0x55c7, + 0xf96c, 0x7a61, 0x7d22, 0x8272, 0x7272, 0x751f, 0x7525, 0xf96d, + 0x7b19, 0x5885, 0x58fb, 0x5dbc, 0x5e8f, 0x5eb6, 0x5f90, 0x6055, + 0x6292, 0x637f, 0x654d, 0x6691, 0x66d9, 0x66f8, 0x6816, 0x68f2, + 0x7280, 0x745e, 0x7b6e, 0x7d6e, 0x7dd6, 0x7f72, + /* 0x60 */ + 0x80e5, 0x8212, 0x85af, 0x897f, 0x8a93, 0x901d, 0x92e4, 0x9ecd, + 0x9f20, 0x5915, 0x596d, 0x5e2d, 0x60dc, 0x6614, 0x6673, 0x6790, + 0x6c50, 0x6dc5, 0x6f5f, 0x77f3, 0x78a9, 0x84c6, 0x91cb, 0x932b, + 0x4ed9, 0x50ca, 0x5148, 0x5584, 0x5b0b, 0x5ba3, 0x6247, 0x657e, + 0x65cb, 0x6e32, 0x717d, 0x7401, 0x7444, 0x7487, 0x74bf, 0x766c, + 0x79aa, 0x7dda, 0x7e55, 0x7fa8, 0x817a, 0x81b3, 0x8239, 0x861a, + 0x87ec, 0x8a75, 0x8de3, 0x9078, 0x9291, 0x9425, 0x994d, 0x9bae, + 0x5368, 0x5c51, 0x6954, 0x6cc4, 0x6d29, 0x6e2b, 0x820c, 0x859b, + 0x893b, 0x8a2d, 0x8aaa, 0x96ea, 0x9f67, 0x5261, 0x66b9, 0x6bb2, + 0x7e96, 0x87fe, 0x8d0d, 0x9583, 0x965d, 0x651d, 0x6d89, 0x71ee, + 0xf96e, 0x57ce, 0x59d3, 0x5bac, 0x6027, 0x60fa, 0x6210, 0x661f, + 0x665f, 0x7329, 0x73f9, 0x76db, 0x7701, 0x7b6c, + /* 0x61 */ + 0x8056, 0x8072, 0x8165, 0x8aa0, 0x9192, 0x4e16, 0x52e2, 0x6b72, + 0x6d17, 0x7a05, 0x7b39, 0x7d30, 0xf96f, 0x8cb0, 0x53ec, 0x562f, + 0x5851, 0x5bb5, 0x5c0f, 0x5c11, 0x5de2, 0x6240, 0x6383, 0x6414, + 0x662d, 0x68b3, 0x6cbc, 0x6d88, 0x6eaf, 0x701f, 0x70a4, 0x71d2, + 0x7526, 0x758f, 0x758e, 0x7619, 0x7b11, 0x7be0, 0x7c2b, 0x7d20, + 0x7d39, 0x852c, 0x856d, 0x8607, 0x8a34, 0x900d, 0x9061, 0x90b5, + 0x92b7, 0x97f6, 0x9a37, 0x4fd7, 0x5c6c, 0x675f, 0x6d91, 0x7c9f, + 0x7e8c, 0x8b16, 0x8d16, 0x901f, 0x5b6b, 0x5dfd, 0x640d, 0x84c0, + 0x905c, 0x98e1, 0x7387, 0x5b8b, 0x609a, 0x677e, 0x6dde, 0x8a1f, + 0x8aa6, 0x9001, 0x980c, 0x5237, 0xf970, 0x7051, 0x788e, 0x9396, + 0x8870, 0x91d7, 0x4fee, 0x53d7, 0x55fd, 0x56da, 0x5782, 0x58fd, + 0x5ac2, 0x5b88, 0x5cab, 0x5cc0, 0x5e25, 0x6101, + /* 0x62 */ + 0x620d, 0x624b, 0x6388, 0x641c, 0x6536, 0x6578, 0x6a39, 0x6b8a, + 0x6c34, 0x6d19, 0x6f31, 0x71e7, 0x72e9, 0x7378, 0x7407, 0x74b2, + 0x7626, 0x7761, 0x79c0, 0x7a57, 0x7aea, 0x7cb9, 0x7d8f, 0x7dac, + 0x7e61, 0x7f9e, 0x8129, 0x8331, 0x8490, 0x84da, 0x85ea, 0x8896, + 0x8ab0, 0x8b90, 0x8f38, 0x9042, 0x9083, 0x916c, 0x9296, 0x92b9, + 0x968b, 0x96a7, 0x96a8, 0x96d6, 0x9700, 0x9808, 0x9996, 0x9ad3, + 0x9b1a, 0x53d4, 0x587e, 0x5919, 0x5b70, 0x5bbf, 0x6dd1, 0x6f5a, + 0x719f, 0x7421, 0x74b9, 0x8085, 0x83fd, 0x5de1, 0x5f87, 0x5faa, + 0x6042, 0x65ec, 0x6812, 0x696f, 0x6a53, 0x6b89, 0x6d35, 0x6df3, + 0x73e3, 0x76fe, 0x77ac, 0x7b4d, 0x7d14, 0x8123, 0x821c, 0x8340, + 0x84f4, 0x8563, 0x8a62, 0x8ac4, 0x9187, 0x931e, 0x9806, 0x99b4, + 0x620c, 0x8853, 0x8ff0, 0x9265, 0x5d07, 0x5d27, + /* 0x63 */ + 0x5d69, 0x745f, 0x819d, 0x8768, 0x6fd5, 0x62fe, 0x7fd2, 0x8936, + 0x8972, 0x4e1e, 0x4e58, 0x50e7, 0x52dd, 0x5347, 0x627f, 0x6607, + 0x7e69, 0x8805, 0x965e, 0x4f8d, 0x5319, 0x5636, 0x59cb, 0x5aa4, + 0x5c38, 0x5c4e, 0x5c4d, 0x5e02, 0x5f11, 0x6043, 0x65bd, 0x662f, + 0x6642, 0x67be, 0x67f4, 0x731c, 0x77e2, 0x793a, 0x7fc5, 0x8494, + 0x84cd, 0x8996, 0x8a66, 0x8a69, 0x8ae1, 0x8c55, 0x8c7a, 0x57f4, + 0x5bd4, 0x5f0f, 0x606f, 0x62ed, 0x690d, 0x6b96, 0x6e5c, 0x7184, + 0x7bd2, 0x8755, 0x8b58, 0x8efe, 0x98df, 0x98fe, 0x4f38, 0x4f81, + 0x4fe1, 0x547b, 0x5a20, 0x5bb8, 0x613c, 0x65b0, 0x6668, 0x71fc, + 0x7533, 0x795e, 0x7d33, 0x814e, 0x81e3, 0x8398, 0x85aa, 0x85ce, + 0x8703, 0x8a0a, 0x8eab, 0x8f9b, 0xf971, 0x8fc5, 0x5931, 0x5ba4, + 0x5be6, 0x6089, 0x5be9, 0x5c0b, 0x5fc3, 0x6c81, + /* 0x64 */ + 0xf972, 0x6df1, 0x700b, 0x751a, 0x82af, 0x8af6, 0x4ec0, 0x5341, + 0xf973, 0x96d9, 0x6c0f, 0x4e9e, 0x4fc4, 0x5152, 0x555e, 0x5a25, + 0x5ce8, 0x6211, 0x7259, 0x82bd, 0x83aa, 0x86fe, 0x8859, 0x8a1d, + 0x963f, 0x96c5, 0x9913, 0x9d09, 0x9d5d, 0x580a, 0x5cb3, 0x5dbd, + 0x5e44, 0x60e1, 0x6115, 0x63e1, 0x6a02, 0x6e25, 0x9102, 0x9354, + 0x984e, 0x9c10, 0x9f77, 0x5b89, 0x5cb8, 0x6309, 0x664f, 0x6848, + 0x773c, 0x96c1, 0x978d, 0x9854, 0x9b9f, 0x65a1, 0x8b01, 0x8ecb, + 0x95bc, 0x5535, 0x5ca9, 0x5dd6, 0x5eb5, 0x6697, 0x764c, 0x83f4, + 0x95c7, 0x58d3, 0x62bc, 0x72ce, 0x9d28, 0x4ef0, 0x592e, 0x600f, + 0x663b, 0x6b83, 0x79e7, 0x9d26, 0x5393, 0x54c0, 0x57c3, 0x5d16, + 0x611b, 0x66d6, 0x6daf, 0x788d, 0x827e, 0x9698, 0x9744, 0x5384, + 0x627c, 0x6396, 0x6db2, 0x7e0a, 0x814b, 0x984d, + /* 0x65 */ + 0x6afb, 0x7f4c, 0x9daf, 0x9e1a, 0x4e5f, 0x503b, 0x51b6, 0x591c, + 0x60f9, 0x63f6, 0x6930, 0x723a, 0x8036, 0xf974, 0x91ce, 0x5f31, + 0xf975, 0xf976, 0x7d04, 0x82e5, 0x846f, 0x84bb, 0x85e5, 0x8e8d, + 0xf977, 0x4f6f, 0xf978, 0xf979, 0x58e4, 0x5b43, 0x6059, 0x63da, + 0x6518, 0x656d, 0x6698, 0xf97a, 0x694a, 0x6a23, 0x6d0b, 0x7001, + 0x716c, 0x75d2, 0x760d, 0x79b3, 0x7a70, 0xf97b, 0x7f8a, 0xf97c, + 0x8944, 0xf97d, 0x8b93, 0x91c0, 0x967d, 0xf97e, 0x990a, 0x5704, + 0x5fa1, 0x65bc, 0x6f01, 0x7600, 0x79a6, 0x8a9e, 0x99ad, 0x9b5a, + 0x9f6c, 0x5104, 0x61b6, 0x6291, 0x6a8d, 0x81c6, 0x5043, 0x5830, + 0x5f66, 0x7109, 0x8a00, 0x8afa, 0x5b7c, 0x8616, 0x4ffa, 0x513c, + 0x56b4, 0x5944, 0x63a9, 0x6df9, 0x5daa, 0x696d, 0x5186, 0x4e88, + 0x4f59, 0xf97f, 0xf980, 0xf981, 0x5982, 0xf982, + /* 0x66 */ + 0xf983, 0x6b5f, 0x6c5d, 0xf984, 0x74b5, 0x7916, 0xf985, 0x8207, + 0x8245, 0x8339, 0x8f3f, 0x8f5d, 0xf986, 0x9918, 0xf987, 0xf988, + 0xf989, 0x4ea6, 0xf98a, 0x57df, 0x5f79, 0x6613, 0xf98b, 0xf98c, + 0x75ab, 0x7e79, 0x8b6f, 0xf98d, 0x9006, 0x9a5b, 0x56a5, 0x5827, + 0x59f8, 0x5a1f, 0x5bb4, 0xf98e, 0x5ef6, 0xf98f, 0xf990, 0x6350, + 0x633b, 0xf991, 0x693d, 0x6c87, 0x6cbf, 0x6d8e, 0x6d93, 0x6df5, + 0x6f14, 0xf992, 0x70df, 0x7136, 0x7159, 0xf993, 0x71c3, 0x71d5, + 0xf994, 0x784f, 0x786f, 0xf995, 0x7b75, 0x7de3, 0xf996, 0x7e2f, + 0xf997, 0x884d, 0x8edf, 0xf998, 0xf999, 0xf99a, 0x925b, 0xf99b, + 0x9cf6, 0xf99c, 0xf99d, 0xf99e, 0x6085, 0x6d85, 0xf99f, 0x71b1, + 0xf9a0, 0xf9a1, 0x95b1, 0x53ad, 0xf9a2, 0xf9a3, 0xf9a4, 0x67d3, + 0xf9a5, 0x708e, 0x7130, 0x7430, 0x8276, 0x82d2, + /* 0x67 */ + 0xf9a6, 0x95bb, 0x9ae5, 0x9e7d, 0x66c4, 0xf9a7, 0x71c1, 0x8449, + 0xf9a8, 0xf9a9, 0x584b, 0xf9aa, 0xf9ab, 0x5db8, 0x5f71, 0xf9ac, + 0x6620, 0x668e, 0x6979, 0x69ae, 0x6c38, 0x6cf3, 0x6e36, 0x6f41, + 0x6fda, 0x701b, 0x702f, 0x7150, 0x71df, 0x7370, 0xf9ad, 0x745b, + 0xf9ae, 0x74d4, 0x76c8, 0x7a4e, 0x7e93, 0xf9af, 0xf9b0, 0x82f1, + 0x8a60, 0x8fce, 0xf9b1, 0x9348, 0xf9b2, 0x9719, 0xf9b3, 0xf9b4, + 0x4e42, 0x502a, 0xf9b5, 0x5208, 0x53e1, 0x66f3, 0x6c6d, 0x6fca, + 0x730a, 0x777f, 0x7a62, 0x82ae, 0x85dd, 0x8602, 0xf9b6, 0x88d4, + 0x8a63, 0x8b7d, 0x8c6b, 0xf9b7, 0x92b3, 0xf9b8, 0x9713, 0x9810, + 0x4e94, 0x4f0d, 0x4fc9, 0x50b2, 0x5348, 0x543e, 0x5433, 0x55da, + 0x5862, 0x58ba, 0x5967, 0x5a1b, 0x5be4, 0x609f, 0xf9b9, 0x61ca, + 0x6556, 0x65ff, 0x6664, 0x68a7, 0x6c5a, 0x6fb3, + /* 0x68 */ + 0x70cf, 0x71ac, 0x7352, 0x7b7d, 0x8708, 0x8aa4, 0x9c32, 0x9f07, + 0x5c4b, 0x6c83, 0x7344, 0x7389, 0x923a, 0x6eab, 0x7465, 0x761f, + 0x7a69, 0x7e15, 0x860a, 0x5140, 0x58c5, 0x64c1, 0x74ee, 0x7515, + 0x7670, 0x7fc1, 0x9095, 0x96cd, 0x9954, 0x6e26, 0x74e6, 0x7aa9, + 0x7aaa, 0x81e5, 0x86d9, 0x8778, 0x8a1b, 0x5a49, 0x5b8c, 0x5b9b, + 0x68a1, 0x6900, 0x6d63, 0x73a9, 0x7413, 0x742c, 0x7897, 0x7de9, + 0x7feb, 0x8118, 0x8155, 0x839e, 0x8c4c, 0x962e, 0x9811, 0x66f0, + 0x5f80, 0x65fa, 0x6789, 0x6c6a, 0x738b, 0x502d, 0x5a03, 0x6b6a, + 0x77ee, 0x5916, 0x5d6c, 0x5dcd, 0x7325, 0x754f, 0xf9ba, 0xf9bb, + 0x50e5, 0x51f9, 0x582f, 0x592d, 0x5996, 0x59da, 0x5be5, 0xf9bc, + 0xf9bd, 0x5da2, 0x62d7, 0x6416, 0x6493, 0x64fe, 0xf9be, 0x66dc, + 0xf9bf, 0x6a48, 0xf9c0, 0x71ff, 0x7464, 0xf9c1, + /* 0x69 */ + 0x7a88, 0x7aaf, 0x7e47, 0x7e5e, 0x8000, 0x8170, 0xf9c2, 0x87ef, + 0x8981, 0x8b20, 0x9059, 0xf9c3, 0x9080, 0x9952, 0x617e, 0x6b32, + 0x6d74, 0x7e1f, 0x8925, 0x8fb1, 0x4fd1, 0x50ad, 0x5197, 0x52c7, + 0x57c7, 0x5889, 0x5bb9, 0x5eb8, 0x6142, 0x6995, 0x6d8c, 0x6e67, + 0x6eb6, 0x7194, 0x7462, 0x7528, 0x752c, 0x8073, 0x8338, 0x84c9, + 0x8e0a, 0x9394, 0x93de, 0xf9c4, 0x4e8e, 0x4f51, 0x5076, 0x512a, + 0x53c8, 0x53cb, 0x53f3, 0x5b87, 0x5bd3, 0x5c24, 0x611a, 0x6182, + 0x65f4, 0x725b, 0x7397, 0x7440, 0x76c2, 0x7950, 0x7991, 0x79b9, + 0x7d06, 0x7fbd, 0x828b, 0x85d5, 0x865e, 0x8fc2, 0x9047, 0x90f5, + 0x91ea, 0x9685, 0x96e8, 0x96e9, 0x52d6, 0x5f67, 0x65ed, 0x6631, + 0x682f, 0x715c, 0x7a36, 0x90c1, 0x980a, 0x4e91, 0xf9c5, 0x6a52, + 0x6b9e, 0x6f90, 0x7189, 0x8018, 0x82b8, 0x8553, + /* 0x6a */ + 0x904b, 0x9695, 0x96f2, 0x97fb, 0x851a, 0x9b31, 0x4e90, 0x718a, + 0x96c4, 0x5143, 0x539f, 0x54e1, 0x5713, 0x5712, 0x57a3, 0x5a9b, + 0x5ac4, 0x5bc3, 0x6028, 0x613f, 0x63f4, 0x6c85, 0x6d39, 0x6e72, + 0x6e90, 0x7230, 0x733f, 0x7457, 0x82d1, 0x8881, 0x8f45, 0x9060, + 0xf9c6, 0x9662, 0x9858, 0x9d1b, 0x6708, 0x8d8a, 0x925e, 0x4f4d, + 0x5049, 0x50de, 0x5371, 0x570d, 0x59d4, 0x5a01, 0x5c09, 0x6170, + 0x6690, 0x6e2d, 0x7232, 0x744b, 0x7def, 0x80c3, 0x840e, 0x8466, + 0x853f, 0x875f, 0x885b, 0x8918, 0x8b02, 0x9055, 0x97cb, 0x9b4f, + 0x4e73, 0x4f91, 0x5112, 0x516a, 0xf9c7, 0x552f, 0x55a9, 0x5b7a, + 0x5ba5, 0x5e7c, 0x5e7d, 0x5ebe, 0x60a0, 0x60df, 0x6108, 0x6109, + 0x63c4, 0x6538, 0x6709, 0xf9c8, 0x67d4, 0x67da, 0xf9c9, 0x6961, + 0x6962, 0x6cb9, 0x6d27, 0xf9ca, 0x6e38, 0xf9cb, + /* 0x6b */ + 0x6fe1, 0x7336, 0x7337, 0xf9cc, 0x745c, 0x7531, 0xf9cd, 0x7652, + 0xf9ce, 0xf9cf, 0x7dad, 0x81fe, 0x8438, 0x88d5, 0x8a98, 0x8adb, + 0x8aed, 0x8e30, 0x8e42, 0x904a, 0x903e, 0x907a, 0x9149, 0x91c9, + 0x936e, 0xf9d0, 0xf9d1, 0x5809, 0xf9d2, 0x6bd3, 0x8089, 0x80b2, + 0xf9d3, 0xf9d4, 0x5141, 0x596b, 0x5c39, 0xf9d5, 0xf9d6, 0x6f64, + 0x73a7, 0x80e4, 0x8d07, 0xf9d7, 0x9217, 0x958f, 0xf9d8, 0xf9d9, + 0xf9da, 0xf9db, 0x807f, 0x620e, 0x701c, 0x7d68, 0x878d, 0xf9dc, + 0x57a0, 0x6069, 0x6147, 0x6bb7, 0x8abe, 0x9280, 0x96b1, 0x4e59, + 0x541f, 0x6deb, 0x852d, 0x9670, 0x97f3, 0x98ee, 0x63d6, 0x6ce3, + 0x9091, 0x51dd, 0x61c9, 0x81ba, 0x9df9, 0x4f9d, 0x501a, 0x5100, + 0x5b9c, 0x610f, 0x61ff, 0x64ec, 0x6905, 0x6bc5, 0x7591, 0x77e3, + 0x7fa9, 0x8264, 0x858f, 0x87fb, 0x8863, 0x8abc, + /* 0x6c */ + 0x8b70, 0x91ab, 0x4e8c, 0x4ee5, 0x4f0a, 0xf9dd, 0xf9de, 0x5937, + 0x59e8, 0xf9df, 0x5df2, 0x5f1b, 0x5f5b, 0x6021, 0xf9e0, 0xf9e1, + 0xf9e2, 0xf9e3, 0x723e, 0x73e5, 0xf9e4, 0x7570, 0x75cd, 0xf9e5, + 0x79fb, 0xf9e6, 0x800c, 0x8033, 0x8084, 0x82e1, 0x8351, 0xf9e7, + 0xf9e8, 0x8cbd, 0x8cb3, 0x9087, 0xf9e9, 0xf9ea, 0x98f4, 0x990c, + 0xf9eb, 0xf9ec, 0x7037, 0x76ca, 0x7fca, 0x7fcc, 0x7ffc, 0x8b1a, + 0x4eba, 0x4ec1, 0x5203, 0x5370, 0xf9ed, 0x54bd, 0x56e0, 0x59fb, + 0x5bc5, 0x5f15, 0x5fcd, 0x6e6e, 0xf9ee, 0xf9ef, 0x7d6a, 0x8335, + 0xf9f0, 0x8693, 0x8a8d, 0xf9f1, 0x976d, 0x9777, 0xf9f2, 0xf9f3, + 0x4e00, 0x4f5a, 0x4f7e, 0x58f9, 0x65e5, 0x6ea2, 0x9038, 0x93b0, + 0x99b9, 0x4efb, 0x58ec, 0x598a, 0x59d9, 0x6041, 0xf9f4, 0xf9f5, + 0x7a14, 0xf9f6, 0x834f, 0x8cc3, 0x5165, 0x5344, + /* 0x6d */ + 0xf9f7, 0xf9f8, 0xf9f9, 0x4ecd, 0x5269, 0x5b55, 0x82bf, 0x4ed4, + 0x523a, 0x54a8, 0x59c9, 0x59ff, 0x5b50, 0x5b57, 0x5b5c, 0x6063, + 0x6148, 0x6ecb, 0x7099, 0x716e, 0x7386, 0x74f7, 0x75b5, 0x78c1, + 0x7d2b, 0x8005, 0x81ea, 0x8328, 0x8517, 0x85c9, 0x8aee, 0x8cc7, + 0x96cc, 0x4f5c, 0x52fa, 0x56bc, 0x65ab, 0x6628, 0x707c, 0x70b8, + 0x7235, 0x7dbd, 0x828d, 0x914c, 0x96c0, 0x9d72, 0x5b71, 0x68e7, + 0x6b98, 0x6f7a, 0x76de, 0x5c91, 0x66ab, 0x6f5b, 0x7bb4, 0x7c2a, + 0x8836, 0x96dc, 0x4e08, 0x4ed7, 0x5320, 0x5834, 0x58bb, 0x58ef, + 0x596c, 0x5c07, 0x5e33, 0x5e84, 0x5f35, 0x638c, 0x66b2, 0x6756, + 0x6a1f, 0x6aa3, 0x6b0c, 0x6f3f, 0x7246, 0xf9fa, 0x7350, 0x748b, + 0x7ae0, 0x7ca7, 0x8178, 0x81df, 0x81e7, 0x838a, 0x846c, 0x8523, + 0x8594, 0x85cf, 0x88dd, 0x8d13, 0x91ac, 0x9577, + /* 0x6e */ + 0x969c, 0x518d, 0x54c9, 0x5728, 0x5bb0, 0x624d, 0x6750, 0x683d, + 0x6893, 0x6e3d, 0x6ed3, 0x707d, 0x7e21, 0x88c1, 0x8ca1, 0x8f09, + 0x9f4b, 0x9f4e, 0x722d, 0x7b8f, 0x8acd, 0x931a, 0x4f47, 0x4f4e, + 0x5132, 0x5480, 0x59d0, 0x5e95, 0x62b5, 0x6775, 0x696e, 0x6a17, + 0x6cae, 0x6e1a, 0x72d9, 0x732a, 0x75bd, 0x7bb8, 0x7d35, 0x82e7, + 0x83f9, 0x8457, 0x85f7, 0x8a5b, 0x8caf, 0x8e87, 0x9019, 0x90b8, + 0x96ce, 0x9f5f, 0x52e3, 0x540a, 0x5ae1, 0x5bc2, 0x6458, 0x6575, + 0x6ef4, 0x72c4, 0xf9fb, 0x7684, 0x7a4d, 0x7b1b, 0x7c4d, 0x7e3e, + 0x7fdf, 0x837b, 0x8b2b, 0x8cca, 0x8d64, 0x8de1, 0x8e5f, 0x8fea, + 0x8ff9, 0x9069, 0x93d1, 0x4f43, 0x4f7a, 0x50b3, 0x5168, 0x5178, + 0x524d, 0x526a, 0x5861, 0x587c, 0x5960, 0x5c08, 0x5c55, 0x5edb, + 0x609b, 0x6230, 0x6813, 0x6bbf, 0x6c08, 0x6fb1, + /* 0x6f */ + 0x714e, 0x7420, 0x7530, 0x7538, 0x7551, 0x7672, 0x7b4c, 0x7b8b, + 0x7bad, 0x7bc6, 0x7e8f, 0x8a6e, 0x8f3e, 0x8f49, 0x923f, 0x9293, + 0x9322, 0x942b, 0x96fb, 0x985a, 0x986b, 0x991e, 0x5207, 0x622a, + 0x6298, 0x6d59, 0x7664, 0x7aca, 0x7bc0, 0x7d76, 0x5360, 0x5cbe, + 0x5e97, 0x6f38, 0x70b9, 0x7c98, 0x9711, 0x9b8e, 0x9ede, 0x63a5, + 0x647a, 0x8776, 0x4e01, 0x4e95, 0x4ead, 0x505c, 0x5075, 0x5448, + 0x59c3, 0x5b9a, 0x5e40, 0x5ead, 0x5ef7, 0x5f81, 0x60c5, 0x633a, + 0x653f, 0x6574, 0x65cc, 0x6676, 0x6678, 0x67fe, 0x6968, 0x6a89, + 0x6b63, 0x6c40, 0x6dc0, 0x6de8, 0x6e1f, 0x6e5e, 0x701e, 0x70a1, + 0x738e, 0x73fd, 0x753a, 0x775b, 0x7887, 0x798e, 0x7a0b, 0x7a7d, + 0x7cbe, 0x7d8e, 0x8247, 0x8a02, 0x8aea, 0x8c9e, 0x912d, 0x914a, + 0x91d8, 0x9266, 0x92cc, 0x9320, 0x9706, 0x9756, + /* 0x70 */ + 0x975c, 0x9802, 0x9f0e, 0x5236, 0x5291, 0x557c, 0x5824, 0x5e1d, + 0x5f1f, 0x608c, 0x63d0, 0x68af, 0x6fdf, 0x796d, 0x7b2c, 0x81cd, + 0x85ba, 0x88fd, 0x8af8, 0x8e44, 0x918d, 0x9664, 0x969b, 0x973d, + 0x984c, 0x9f4a, 0x4fce, 0x5146, 0x51cb, 0x52a9, 0x5632, 0x5f14, + 0x5f6b, 0x63aa, 0x64cd, 0x65e9, 0x6641, 0x66fa, 0x66f9, 0x671d, + 0x689d, 0x68d7, 0x69fd, 0x6f15, 0x6f6e, 0x7167, 0x71e5, 0x722a, + 0x74aa, 0x773a, 0x7956, 0x795a, 0x79df, 0x7a20, 0x7a95, 0x7c97, + 0x7cdf, 0x7d44, 0x7e70, 0x8087, 0x85fb, 0x86a4, 0x8a54, 0x8abf, + 0x8d99, 0x8e81, 0x9020, 0x906d, 0x91e3, 0x963b, 0x96d5, 0x9ce5, + 0x65cf, 0x7c07, 0x8db3, 0x93c3, 0x5b58, 0x5c0a, 0x5352, 0x62d9, + 0x731d, 0x5027, 0x5b97, 0x5f9e, 0x60b0, 0x616b, 0x68d5, 0x6dd9, + 0x742e, 0x7a2e, 0x7d42, 0x7d9c, 0x7e31, 0x816b, + /* 0x71 */ + 0x8e2a, 0x8e35, 0x937e, 0x9418, 0x4f50, 0x5750, 0x5de6, 0x5ea7, + 0x632b, 0x7f6a, 0x4e3b, 0x4f4f, 0x4f8f, 0x505a, 0x59dd, 0x80c4, + 0x546a, 0x5468, 0x55fe, 0x594f, 0x5b99, 0x5dde, 0x5eda, 0x665d, + 0x6731, 0x67f1, 0x682a, 0x6ce8, 0x6d32, 0x6e4a, 0x6f8d, 0x70b7, + 0x73e0, 0x7587, 0x7c4c, 0x7d02, 0x7d2c, 0x7da2, 0x821f, 0x86db, + 0x8a3b, 0x8a85, 0x8d70, 0x8e8a, 0x8f33, 0x9031, 0x914e, 0x9152, + 0x9444, 0x99d0, 0x7af9, 0x7ca5, 0x4fca, 0x5101, 0x51c6, 0x57c8, + 0x5bef, 0x5cfb, 0x6659, 0x6a3d, 0x6d5a, 0x6e96, 0x6fec, 0x710c, + 0x756f, 0x7ae3, 0x8822, 0x9021, 0x9075, 0x96cb, 0x99ff, 0x8301, + 0x4e2d, 0x4ef2, 0x8846, 0x91cd, 0x537d, 0x6adb, 0x696b, 0x6c41, + 0x847a, 0x589e, 0x618e, 0x66fe, 0x62ef, 0x70dd, 0x7511, 0x75c7, + 0x7e52, 0x84b8, 0x8b49, 0x8d08, 0x4e4b, 0x53ea, + /* 0x72 */ + 0x54ab, 0x5730, 0x5740, 0x5fd7, 0x6301, 0x6307, 0x646f, 0x652f, + 0x65e8, 0x667a, 0x679d, 0x67b3, 0x6b62, 0x6c60, 0x6c9a, 0x6f2c, + 0x77e5, 0x7825, 0x7949, 0x7957, 0x7d19, 0x80a2, 0x8102, 0x81f3, + 0x829d, 0x82b7, 0x8718, 0x8a8c, 0xf9fc, 0x8d04, 0x8dbe, 0x9072, + 0x76f4, 0x7a19, 0x7a37, 0x7e54, 0x8077, 0x5507, 0x55d4, 0x5875, + 0x632f, 0x6422, 0x6649, 0x664b, 0x686d, 0x699b, 0x6b84, 0x6d25, + 0x6eb1, 0x73cd, 0x7468, 0x74a1, 0x755b, 0x75b9, 0x76e1, 0x771e, + 0x778b, 0x79e6, 0x7e09, 0x7e1d, 0x81fb, 0x852f, 0x8897, 0x8a3a, + 0x8cd1, 0x8eeb, 0x8fb0, 0x9032, 0x93ad, 0x9663, 0x9673, 0x9707, + 0x4f84, 0x53f1, 0x59ea, 0x5ac9, 0x5e19, 0x684e, 0x74c6, 0x75be, + 0x79e9, 0x7a92, 0x81a3, 0x86ed, 0x8cea, 0x8dcc, 0x8fed, 0x659f, + 0x6715, 0xf9fd, 0x57f7, 0x6f57, 0x7ddd, 0x8f2f, + /* 0x73 */ + 0x93f6, 0x96c6, 0x5fb5, 0x61f2, 0x6f84, 0x4e14, 0x4f98, 0x501f, + 0x53c9, 0x55df, 0x5d6f, 0x5dee, 0x6b21, 0x6b64, 0x78cb, 0x7b9a, + 0xf9fe, 0x8e49, 0x8eca, 0x906e, 0x6349, 0x643e, 0x7740, 0x7a84, + 0x932f, 0x947f, 0x9f6a, 0x64b0, 0x6faf, 0x71e6, 0x74a8, 0x74da, + 0x7ac4, 0x7c12, 0x7e82, 0x7cb2, 0x7e98, 0x8b9a, 0x8d0a, 0x947d, + 0x9910, 0x994c, 0x5239, 0x5bdf, 0x64e6, 0x672d, 0x7d2e, 0x50ed, + 0x53c3, 0x5879, 0x6158, 0x6159, 0x61fa, 0x65ac, 0x7ad9, 0x8b92, + 0x8b96, 0x5009, 0x5021, 0x5275, 0x5531, 0x5a3c, 0x5ee0, 0x5f70, + 0x6134, 0x655e, 0x660c, 0x6636, 0x66a2, 0x69cd, 0x6ec4, 0x6f32, + 0x7316, 0x7621, 0x7a93, 0x8139, 0x8259, 0x83d6, 0x84bc, 0x50b5, + 0x57f0, 0x5bc0, 0x5be8, 0x5f69, 0x63a1, 0x7826, 0x7db5, 0x83dc, + 0x8521, 0x91c7, 0x91f5, 0x518a, 0x67f5, 0x7b56, + /* 0x74 */ + 0x8cac, 0x51c4, 0x59bb, 0x60bd, 0x8655, 0x501c, 0xf9ff, 0x5254, + 0x5c3a, 0x617d, 0x621a, 0x62d3, 0x64f2, 0x65a5, 0x6ecc, 0x7620, + 0x810a, 0x8e60, 0x965f, 0x96bb, 0x4edf, 0x5343, 0x5598, 0x5929, + 0x5ddd, 0x64c5, 0x6cc9, 0x6dfa, 0x7394, 0x7a7f, 0x821b, 0x85a6, + 0x8ce4, 0x8e10, 0x9077, 0x91e7, 0x95e1, 0x9621, 0x97c6, 0x51f8, + 0x54f2, 0x5586, 0x5fb9, 0x64a4, 0x6f88, 0x7db4, 0x8f1f, 0x8f4d, + 0x9435, 0x50c9, 0x5c16, 0x6cbe, 0x6dfb, 0x751b, 0x77bb, 0x7c3d, + 0x7c64, 0x8a79, 0x8ac2, 0x581e, 0x59be, 0x5e16, 0x6377, 0x7252, + 0x758a, 0x776b, 0x8adc, 0x8cbc, 0x8f12, 0x5ef3, 0x6674, 0x6df8, + 0x807d, 0x83c1, 0x8acb, 0x9751, 0x9bd6, 0xfa00, 0x5243, 0x66ff, + 0x6d95, 0x6eef, 0x7de0, 0x8ae6, 0x902e, 0x905e, 0x9ad4, 0x521d, + 0x527f, 0x54e8, 0x6194, 0x6284, 0x62db, 0x68a2, + /* 0x75 */ + 0x6912, 0x695a, 0x6a35, 0x7092, 0x7126, 0x785d, 0x7901, 0x790e, + 0x79d2, 0x7a0d, 0x8096, 0x8278, 0x82d5, 0x8349, 0x8549, 0x8c82, + 0x8d85, 0x9162, 0x918b, 0x91ae, 0x4fc3, 0x56d1, 0x71ed, 0x77d7, + 0x8700, 0x89f8, 0x5bf8, 0x5fd6, 0x6751, 0x90a8, 0x53e2, 0x585a, + 0x5bf5, 0x60a4, 0x6181, 0x6460, 0x7e3d, 0x8070, 0x8525, 0x9283, + 0x64ae, 0x50ac, 0x5d14, 0x6700, 0x589c, 0x62bd, 0x63a8, 0x690e, + 0x6978, 0x6a1e, 0x6e6b, 0x76ba, 0x79cb, 0x82bb, 0x8429, 0x8acf, + 0x8da8, 0x8ffd, 0x9112, 0x914b, 0x919c, 0x9310, 0x9318, 0x939a, + 0x96db, 0x9a36, 0x9c0d, 0x4e11, 0x755c, 0x795d, 0x7afa, 0x7b51, + 0x7bc9, 0x7e2e, 0x84c4, 0x8e59, 0x8e74, 0x8ef8, 0x9010, 0x6625, + 0x693f, 0x7443, 0x51fa, 0x672e, 0x9edc, 0x5145, 0x5fe0, 0x6c96, + 0x87f2, 0x885d, 0x8877, 0x60b4, 0x81b5, 0x8403, + /* 0x76 */ + 0x8d05, 0x53d6, 0x5439, 0x5634, 0x5a36, 0x5c31, 0x708a, 0x7fe0, + 0x805a, 0x8106, 0x81ed, 0x8da3, 0x9189, 0x9a5f, 0x9df2, 0x5074, + 0x4ec4, 0x53a0, 0x60fb, 0x6e2c, 0x5c64, 0x4f88, 0x5024, 0x55e4, + 0x5cd9, 0x5e5f, 0x6065, 0x6894, 0x6cbb, 0x6dc4, 0x71be, 0x75d4, + 0x75f4, 0x7661, 0x7a1a, 0x7a49, 0x7dc7, 0x7dfb, 0x7f6e, 0x81f4, + 0x86a9, 0x8f1c, 0x96c9, 0x99b3, 0x9f52, 0x5247, 0x52c5, 0x98ed, + 0x89aa, 0x4e03, 0x67d2, 0x6f06, 0x4fb5, 0x5be2, 0x6795, 0x6c88, + 0x6d78, 0x741b, 0x7827, 0x91dd, 0x937c, 0x87c4, 0x79e4, 0x7a31, + 0x5feb, 0x4ed6, 0x54a4, 0x553e, 0x58ae, 0x59a5, 0x60f0, 0x6253, + 0x62d6, 0x6736, 0x6955, 0x8235, 0x9640, 0x99b1, 0x99dd, 0x502c, + 0x5353, 0x5544, 0x577c, 0xfa01, 0x6258, 0xfa02, 0x64e2, 0x666b, + 0x67dd, 0x6fc1, 0x6fef, 0x7422, 0x7438, 0x8a17, + /* 0x77 */ + 0x9438, 0x5451, 0x5606, 0x5766, 0x5f48, 0x619a, 0x6b4e, 0x7058, + 0x70ad, 0x7dbb, 0x8a95, 0x596a, 0x812b, 0x63a2, 0x7708, 0x803d, + 0x8caa, 0x5854, 0x642d, 0x69bb, 0x5b95, 0x5e11, 0x6e6f, 0xfa03, + 0x8569, 0x514c, 0x53f0, 0x592a, 0x6020, 0x614b, 0x6b86, 0x6c70, + 0x6cf0, 0x7b1e, 0x80ce, 0x82d4, 0x8dc6, 0x90b0, 0x98b1, 0xfa04, + 0x64c7, 0x6fa4, 0x6491, 0x6504, 0x514e, 0x5410, 0x571f, 0x8a0e, + 0x615f, 0x6876, 0xfa05, 0x75db, 0x7b52, 0x7d71, 0x901a, 0x5806, + 0x69cc, 0x817f, 0x892a, 0x9000, 0x9839, 0x5078, 0x5957, 0x59ac, + 0x6295, 0x900f, 0x9b2a, 0x615d, 0x7279, 0x95d6, 0x5761, 0x5a46, + 0x5df4, 0x628a, 0x64ad, 0x64fa, 0x6777, 0x6ce2, 0x6d3e, 0x722c, + 0x7436, 0x7834, 0x7f77, 0x82ad, 0x8ddb, 0x9817, 0x5224, 0x5742, + 0x677f, 0x7248, 0x74e3, 0x8ca9, 0x8fa6, 0x9211, + /* 0x78 */ + 0x962a, 0x516b, 0x53ed, 0x634c, 0x4f69, 0x5504, 0x6096, 0x6557, + 0x6c9b, 0x6d7f, 0x724c, 0x72fd, 0x7a17, 0x8987, 0x8c9d, 0x5f6d, + 0x6f8e, 0x70f9, 0x81a8, 0x610e, 0x4fbf, 0x504f, 0x6241, 0x7247, + 0x7bc7, 0x7de8, 0x7fe9, 0x904d, 0x97ad, 0x9a19, 0x8cb6, 0x576a, + 0x5e73, 0x67b0, 0x840d, 0x8a55, 0x5420, 0x5b16, 0x5e63, 0x5ee2, + 0x5f0a, 0x6583, 0x80ba, 0x853d, 0x9589, 0x965b, 0x4f48, 0x5305, + 0x530d, 0x530f, 0x5486, 0x54fa, 0x5703, 0x5e03, 0x6016, 0x629b, + 0x62b1, 0x6355, 0xfa06, 0x6ce1, 0x6d66, 0x75b1, 0x7832, 0x80de, + 0x812f, 0x82de, 0x8461, 0x84b2, 0x888d, 0x8912, 0x900b, 0x92ea, + 0x98fd, 0x9b91, 0x5e45, 0x66b4, 0x66dd, 0x7011, 0x7206, 0xfa07, + 0x4ff5, 0x527d, 0x5f6a, 0x6153, 0x6753, 0x6a19, 0x6f02, 0x74e2, + 0x7968, 0x8868, 0x8c79, 0x98c7, 0x98c4, 0x9a43, + /* 0x79 */ + 0x54c1, 0x7a1f, 0x6953, 0x8af7, 0x8c4a, 0x98a8, 0x99ae, 0x5f7c, + 0x62ab, 0x75b2, 0x76ae, 0x88ab, 0x907f, 0x9642, 0x5339, 0x5f3c, + 0x5fc5, 0x6ccc, 0x73cc, 0x7562, 0x758b, 0x7b46, 0x82fe, 0x999d, + 0x4e4f, 0x903c, 0x4e0b, 0x4f55, 0x53a6, 0x590f, 0x5ec8, 0x6630, + 0x6cb3, 0x7455, 0x8377, 0x8766, 0x8cc0, 0x9050, 0x971e, 0x9c15, + 0x58d1, 0x5b78, 0x8650, 0x8b14, 0x9db4, 0x5bd2, 0x6068, 0x608d, + 0x65f1, 0x6c57, 0x6f22, 0x6fa3, 0x701a, 0x7f55, 0x7ff0, 0x9591, + 0x9592, 0x9650, 0x97d3, 0x5272, 0x8f44, 0x51fd, 0x542b, 0x54b8, + 0x5563, 0x558a, 0x6abb, 0x6db5, 0x7dd8, 0x8266, 0x929c, 0x9677, + 0x9e79, 0x5408, 0x54c8, 0x76d2, 0x86e4, 0x95a4, 0x95d4, 0x965c, + 0x4ea2, 0x4f09, 0x59ee, 0x5ae6, 0x5df7, 0x6052, 0x6297, 0x676d, + 0x6841, 0x6c86, 0x6e2f, 0x7f38, 0x809b, 0x822a, + /* 0x7a */ + 0xfa08, 0xfa09, 0x9805, 0x4ea5, 0x5055, 0x54b3, 0x5793, 0x595a, + 0x5b69, 0x5bb3, 0x61c8, 0x6977, 0x6d77, 0x7023, 0x87f9, 0x89e3, + 0x8a72, 0x8ae7, 0x9082, 0x99ed, 0x9ab8, 0x52be, 0x6838, 0x5016, + 0x5e78, 0x674f, 0x8347, 0x884c, 0x4eab, 0x5411, 0x56ae, 0x73e6, + 0x9115, 0x97ff, 0x9909, 0x9957, 0x9999, 0x5653, 0x589f, 0x865b, + 0x8a31, 0x61b2, 0x6af6, 0x737b, 0x8ed2, 0x6b47, 0x96aa, 0x9a57, + 0x5955, 0x7200, 0x8d6b, 0x9769, 0x4fd4, 0x5cf4, 0x5f26, 0x61f8, + 0x665b, 0x6ceb, 0x70ab, 0x7384, 0x73b9, 0x73fe, 0x7729, 0x774d, + 0x7d43, 0x7d62, 0x7e23, 0x8237, 0x8852, 0xfa0a, 0x8ce2, 0x9249, + 0x986f, 0x5b51, 0x7a74, 0x8840, 0x9801, 0x5acc, 0x4fe0, 0x5354, + 0x593e, 0x5cfd, 0x633e, 0x6d79, 0x72f9, 0x8105, 0x8107, 0x83a2, + 0x92cf, 0x9830, 0x4ea8, 0x5144, 0x5211, 0x578b, + /* 0x7b */ + 0x5f62, 0x6cc2, 0x6ece, 0x7005, 0x7050, 0x70af, 0x7192, 0x73e9, + 0x7469, 0x834a, 0x87a2, 0x8861, 0x9008, 0x90a2, 0x93a3, 0x99a8, + 0x516e, 0x5f57, 0x60e0, 0x6167, 0x66b3, 0x8559, 0x8e4a, 0x91af, + 0x978b, 0x4e4e, 0x4e92, 0x547c, 0x58d5, 0x58fa, 0x597d, 0x5cb5, + 0x5f27, 0x6236, 0x6248, 0x660a, 0x6667, 0x6beb, 0x6d69, 0x6dcf, + 0x6e56, 0x6ef8, 0x6f94, 0x6fe0, 0x6fe9, 0x705d, 0x72d0, 0x7425, + 0x745a, 0x74e0, 0x7693, 0x795c, 0x7cca, 0x7e1e, 0x80e1, 0x82a6, + 0x846b, 0x84bf, 0x864e, 0x865f, 0x8774, 0x8b77, 0x8c6a, 0x93ac, + 0x9800, 0x9865, 0x60d1, 0x6216, 0x9177, 0x5a5a, 0x660f, 0x6df7, + 0x6e3e, 0x743f, 0x9b42, 0x5ffd, 0x60da, 0x7b0f, 0x54c4, 0x5f18, + 0x6c5e, 0x6cd3, 0x6d2a, 0x70d8, 0x7d05, 0x8679, 0x8a0c, 0x9d3b, + 0x5316, 0x548c, 0x5b05, 0x6a3a, 0x706b, 0x7575, + /* 0x7c */ + 0x798d, 0x79be, 0x82b1, 0x83ef, 0x8a71, 0x8b41, 0x8ca8, 0x9774, + 0xfa0b, 0x64f4, 0x652b, 0x78ba, 0x78bb, 0x7a6b, 0x4e38, 0x559a, + 0x5950, 0x5ba6, 0x5e7b, 0x60a3, 0x63db, 0x6b61, 0x6665, 0x6853, + 0x6e19, 0x7165, 0x74b0, 0x7d08, 0x9084, 0x9a69, 0x9c25, 0x6d3b, + 0x6ed1, 0x733e, 0x8c41, 0x95ca, 0x51f0, 0x5e4c, 0x5fa8, 0x604d, + 0x60f6, 0x6130, 0x614c, 0x6643, 0x6644, 0x69a5, 0x6cc1, 0x6e5f, + 0x6ec9, 0x6f62, 0x714c, 0x749c, 0x7687, 0x7bc1, 0x7c27, 0x8352, + 0x8757, 0x9051, 0x968d, 0x9ec3, 0x532f, 0x56de, 0x5efb, 0x5f8a, + 0x6062, 0x6094, 0x61f7, 0x6666, 0x6703, 0x6a9c, 0x6dee, 0x6fae, + 0x7070, 0x736a, 0x7e6a, 0x81be, 0x8334, 0x86d4, 0x8aa8, 0x8cc4, + 0x5283, 0x7372, 0x5b96, 0x6a6b, 0x9404, 0x54ee, 0x5686, 0x5b5d, + 0x6548, 0x6585, 0x66c9, 0x689f, 0x6d8d, 0x6dc6, + /* 0x7d */ + 0x723b, 0x80b4, 0x9175, 0x9a4d, 0x4faf, 0x5019, 0x539a, 0x540e, + 0x543c, 0x5589, 0x55c5, 0x5e3f, 0x5f8c, 0x673d, 0x7166, 0x73dd, + 0x9005, 0x52db, 0x52f3, 0x5864, 0x58ce, 0x7104, 0x718f, 0x71fb, + 0x85b0, 0x8a13, 0x6688, 0x85a8, 0x55a7, 0x6684, 0x714a, 0x8431, + 0x5349, 0x5599, 0x6bc1, 0x5f59, 0x5fbd, 0x63ee, 0x6689, 0x7147, + 0x8af1, 0x8f1d, 0x9ebe, 0x4f11, 0x643a, 0x70cb, 0x7566, 0x8667, + 0x6064, 0x8b4e, 0x9df8, 0x5147, 0x51f6, 0x5308, 0x6d36, 0x80f8, + 0x9ed1, 0x6615, 0x6b23, 0x7098, 0x75d5, 0x5403, 0x5c79, 0x7d07, + 0x8a16, 0x6b20, 0x6b3d, 0x6b46, 0x5438, 0x6070, 0x6d3d, 0x7fd5, + 0x8208, 0x50d6, 0x51de, 0x559c, 0x566b, 0x56cd, 0x59ec, 0x5b09, + 0x5e0c, 0x6199, 0x6198, 0x6231, 0x665e, 0x66e6, 0x7199, 0x71b9, + 0x71ba, 0x72a7, 0x79a7, 0x7a00, 0x7fb2, 0x8a70, +}; + +static int +ksc5601_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x21 && c1 <= 0x2c) || (c1 >= 0x30 && c1 <= 0x48) || (c1 >= 0x4a && c1 <= 0x7d)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if (c2 >= 0x21 && c2 < 0x7f) { + unsigned int i = 94 * (c1 - 0x21) + (c2 - 0x21); + unsigned short wc = 0xfffd; + if (i < 1410) { + if (i < 1115) + wc = ksc5601_2uni_page21[i]; + } else if (i < 3854) { + if (i < 3760) + wc = ksc5601_2uni_page30[i-1410]; + } else { + if (i < 8742) + wc = ksc5601_2uni_page4a[i-3854]; + } + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short ksc5601_2charset[8227] = { + 0x222e, 0x2234, 0x2157, 0x2127, 0x2823, 0x2129, 0x2267, 0x2146, + 0x213e, 0x2977, 0x2978, 0x2225, 0x2252, 0x2124, 0x222c, 0x2976, + 0x282c, 0x2879, 0x2876, 0x287a, 0x222f, 0x2821, 0x2822, 0x213f, + 0x282a, 0x282d, 0x292c, 0x2921, 0x2923, 0x2140, 0x292a, 0x292d, + 0x2922, 0x2824, 0x2924, 0x2925, 0x2826, 0x2926, 0x2927, 0x2828, + 0x2928, 0x2829, 0x2929, 0x2930, 0x282f, 0x292f, 0x282b, 0x292b, + 0x282e, 0x292e, 0x2227, 0x2230, 0x2228, 0x222b, 0x222a, 0x222d, + 0x2229, 0x2541, 0x2542, 0x2543, 0x2544, 0x2545, 0x2546, 0x2547, + 0x2548, 0x2549, 0x254a, 0x254b, 0x254c, 0x254d, 0x254e, 0x254f, + 0x2550, 0x2551, 0x2552, 0x2553, 0x2554, 0x2555, 0x2556, 0x2557, + 0x2558, 0x2561, 0x2562, 0x2563, 0x2564, 0x2565, 0x2566, 0x2567, + 0x2568, 0x2569, 0x256a, 0x256b, 0x256c, 0x256d, 0x256e, 0x256f, + 0x2570, 0x2571, 0x2572, 0x2573, 0x2574, 0x2575, 0x2576, 0x2577, + 0x2578, 0x2c27, 0x2c21, 0x2c22, 0x2c23, 0x2c24, 0x2c25, 0x2c26, + 0x2c28, 0x2c29, 0x2c2a, 0x2c2b, 0x2c2c, 0x2c2d, 0x2c2e, 0x2c2f, + 0x2c30, 0x2c31, 0x2c32, 0x2c33, 0x2c34, 0x2c35, 0x2c36, 0x2c37, + 0x2c38, 0x2c39, 0x2c3a, 0x2c3b, 0x2c3c, 0x2c3d, 0x2c3e, 0x2c3f, + 0x2c40, 0x2c41, 0x2c51, 0x2c52, 0x2c53, 0x2c54, 0x2c55, 0x2c56, + 0x2c58, 0x2c59, 0x2c5a, 0x2c5b, 0x2c5c, 0x2c5d, 0x2c5e, 0x2c5f, + 0x2c60, 0x2c61, 0x2c62, 0x2c63, 0x2c64, 0x2c65, 0x2c66, 0x2c67, + 0x2c68, 0x2c69, 0x2c6a, 0x2c6b, 0x2c6c, 0x2c6d, 0x2c6e, 0x2c6f, + 0x2c70, 0x2c71, 0x2c57, 0x212a, 0x212e, 0x212f, 0x2130, 0x2131, + 0x2253, 0x2254, 0x2125, 0x2126, 0x2236, 0x2147, 0x2148, 0x2158, + 0x2979, 0x297a, 0x297b, 0x297c, 0x297d, 0x297e, 0x2266, 0x2149, + 0x2235, 0x2724, 0x2260, 0x2265, 0x2262, 0x2759, 0x214a, 0x2877, + 0x2878, 0x287b, 0x287c, 0x287d, 0x287e, 0x2530, 0x2531, 0x2532, + 0x2533, 0x2534, 0x2535, 0x2536, 0x2537, 0x2538, 0x2539, 0x2521, + 0x2522, 0x2523, 0x2524, 0x2525, 0x2526, 0x2527, 0x2528, 0x2529, + 0x252a, 0x2167, 0x2168, 0x2166, 0x2169, 0x216a, 0x2255, 0x2258, + 0x2256, 0x2259, 0x2257, 0x2221, 0x2222, 0x2223, 0x2153, 0x2224, + 0x2154, 0x2174, 0x2175, 0x2233, 0x2232, 0x216e, 0x2170, 0x2144, + 0x2150, 0x212b, 0x217c, 0x217d, 0x217b, 0x217a, 0x2172, 0x2173, + 0x2231, 0x2145, 0x2171, 0x212d, 0x216f, 0x2156, 0x2141, 0x2155, + 0x2142, 0x2143, 0x216c, 0x216d, 0x2178, 0x2179, 0x2176, 0x2177, + 0x2241, 0x2151, 0x2152, 0x2867, 0x2868, 0x2869, 0x286a, 0x286b, + 0x286c, 0x286d, 0x286e, 0x286f, 0x2870, 0x2871, 0x2872, 0x2873, + 0x2874, 0x2875, 0x2967, 0x2968, 0x2969, 0x296a, 0x296b, 0x296c, + 0x296d, 0x296e, 0x296f, 0x2970, 0x2971, 0x2972, 0x2973, 0x2974, + 0x2975, 0x294d, 0x294e, 0x294f, 0x2950, 0x2951, 0x2952, 0x2953, + 0x2954, 0x2955, 0x2956, 0x2957, 0x2958, 0x2959, 0x295a, 0x295b, + 0x295c, 0x295d, 0x295e, 0x295f, 0x2960, 0x2961, 0x2962, 0x2963, + 0x2964, 0x2965, 0x2966, 0x284d, 0x284e, 0x284f, 0x2850, 0x2851, + 0x2852, 0x2853, 0x2854, 0x2855, 0x2856, 0x2857, 0x2858, 0x2859, + 0x285a, 0x285b, 0x285c, 0x285d, 0x285e, 0x285f, 0x2860, 0x2861, + 0x2862, 0x2863, 0x2864, 0x2865, 0x2866, 0x2621, 0x262c, 0x2622, + 0x262d, 0x2623, 0x2648, 0x2647, 0x262e, 0x2624, 0x2642, 0x2641, + 0x262f, 0x2626, 0x2646, 0x2645, 0x2631, 0x2625, 0x2644, 0x2643, + 0x2630, 0x2627, 0x263c, 0x2649, 0x264a, 0x2637, 0x264b, 0x264c, + 0x2632, 0x2629, 0x263e, 0x264d, 0x264e, 0x2639, 0x264f, 0x2650, + 0x2634, 0x2628, 0x2651, 0x2652, 0x2638, 0x263d, 0x2653, 0x2654, + 0x2633, 0x262a, 0x2655, 0x2656, 0x263a, 0x263f, 0x2657, 0x2658, + 0x2635, 0x262b, 0x2659, 0x265a, 0x263b, 0x265b, 0x265c, 0x2640, + 0x265d, 0x265e, 0x265f, 0x2660, 0x2661, 0x2662, 0x2663, 0x2664, + 0x2636, 0x2246, 0x2161, 0x2160, 0x2243, 0x2247, 0x2248, 0x224b, + 0x224a, 0x2249, 0x224c, 0x2163, 0x2162, 0x223a, 0x2239, 0x2165, + 0x2164, 0x2238, 0x2237, 0x215f, 0x215e, 0x2242, 0x215b, 0x215d, + 0x215c, 0x2244, 0x2245, 0x215a, 0x2159, 0x224f, 0x224e, 0x2250, + 0x2251, 0x214f, 0x214e, 0x223c, 0x223d, 0x2240, 0x223b, 0x223e, + 0x223f, 0x224d, 0x225b, 0x225c, 0x225d, 0x225a, 0x2121, 0x2122, + 0x2123, 0x2128, 0x2134, 0x2135, 0x2136, 0x2137, 0x2138, 0x2139, + 0x213a, 0x213b, 0x213c, 0x213d, 0x216b, 0x2132, 0x2133, 0x2a21, + 0x2a22, 0x2a23, 0x2a24, 0x2a25, 0x2a26, 0x2a27, 0x2a28, 0x2a29, + 0x2a2a, 0x2a2b, 0x2a2c, 0x2a2d, 0x2a2e, 0x2a2f, 0x2a30, 0x2a31, + 0x2a32, 0x2a33, 0x2a34, 0x2a35, 0x2a36, 0x2a37, 0x2a38, 0x2a39, + 0x2a3a, 0x2a3b, 0x2a3c, 0x2a3d, 0x2a3e, 0x2a3f, 0x2a40, 0x2a41, + 0x2a42, 0x2a43, 0x2a44, 0x2a45, 0x2a46, 0x2a47, 0x2a48, 0x2a49, + 0x2a4a, 0x2a4b, 0x2a4c, 0x2a4d, 0x2a4e, 0x2a4f, 0x2a50, 0x2a51, + 0x2a52, 0x2a53, 0x2a54, 0x2a55, 0x2a56, 0x2a57, 0x2a58, 0x2a59, + 0x2a5a, 0x2a5b, 0x2a5c, 0x2a5d, 0x2a5e, 0x2a5f, 0x2a60, 0x2a61, + 0x2a62, 0x2a63, 0x2a64, 0x2a65, 0x2a66, 0x2a67, 0x2a68, 0x2a69, + 0x2a6a, 0x2a6b, 0x2a6c, 0x2a6d, 0x2a6e, 0x2a6f, 0x2a70, 0x2a71, + 0x2a72, 0x2a73, 0x2b21, 0x2b22, 0x2b23, 0x2b24, 0x2b25, 0x2b26, + 0x2b27, 0x2b28, 0x2b29, 0x2b2a, 0x2b2b, 0x2b2c, 0x2b2d, 0x2b2e, + 0x2b2f, 0x2b30, 0x2b31, 0x2b32, 0x2b33, 0x2b34, 0x2b35, 0x2b36, + 0x2b37, 0x2b38, 0x2b39, 0x2b3a, 0x2b3b, 0x2b3c, 0x2b3d, 0x2b3e, + 0x2b3f, 0x2b40, 0x2b41, 0x2b42, 0x2b43, 0x2b44, 0x2b45, 0x2b46, + 0x2b47, 0x2b48, 0x2b49, 0x2b4a, 0x2b4b, 0x2b4c, 0x2b4d, 0x2b4e, + 0x2b4f, 0x2b50, 0x2b51, 0x2b52, 0x2b53, 0x2b54, 0x2b55, 0x2b56, + 0x2b57, 0x2b58, 0x2b59, 0x2b5a, 0x2b5b, 0x2b5c, 0x2b5d, 0x2b5e, + 0x2b5f, 0x2b60, 0x2b61, 0x2b62, 0x2b63, 0x2b64, 0x2b65, 0x2b66, + 0x2b67, 0x2b68, 0x2b69, 0x2b6a, 0x2b6b, 0x2b6c, 0x2b6d, 0x2b6e, + 0x2b6f, 0x2b70, 0x2b71, 0x2b72, 0x2b73, 0x2b74, 0x2b75, 0x2b76, + 0x2421, 0x2422, 0x2423, 0x2424, 0x2425, 0x2426, 0x2427, 0x2428, + 0x2429, 0x242a, 0x242b, 0x242c, 0x242d, 0x242e, 0x242f, 0x2430, + 0x2431, 0x2432, 0x2433, 0x2434, 0x2435, 0x2436, 0x2437, 0x2438, + 0x2439, 0x243a, 0x243b, 0x243c, 0x243d, 0x243e, 0x243f, 0x2440, + 0x2441, 0x2442, 0x2443, 0x2444, 0x2445, 0x2446, 0x2447, 0x2448, + 0x2449, 0x244a, 0x244b, 0x244c, 0x244d, 0x244e, 0x244f, 0x2450, + 0x2451, 0x2452, 0x2453, 0x2454, 0x2455, 0x2456, 0x2457, 0x2458, + 0x2459, 0x245a, 0x245b, 0x245c, 0x245d, 0x245e, 0x245f, 0x2460, + 0x2461, 0x2462, 0x2463, 0x2464, 0x2465, 0x2466, 0x2467, 0x2468, + 0x2469, 0x246a, 0x246b, 0x246c, 0x246d, 0x246e, 0x246f, 0x2470, + 0x2471, 0x2472, 0x2473, 0x2474, 0x2475, 0x2476, 0x2477, 0x2478, + 0x2479, 0x247a, 0x247b, 0x247c, 0x247d, 0x247e, 0x2931, 0x2932, + 0x2933, 0x2934, 0x2935, 0x2936, 0x2937, 0x2938, 0x2939, 0x293a, + 0x293b, 0x293c, 0x293d, 0x293e, 0x293f, 0x2940, 0x2941, 0x2942, + 0x2943, 0x2944, 0x2945, 0x2946, 0x2947, 0x2948, 0x2949, 0x294a, + 0x294b, 0x294c, 0x225f, 0x2831, 0x2832, 0x2833, 0x2834, 0x2835, + 0x2836, 0x2837, 0x2838, 0x2839, 0x283a, 0x283b, 0x283c, 0x283d, + 0x283e, 0x283f, 0x2840, 0x2841, 0x2842, 0x2843, 0x2844, 0x2845, + 0x2846, 0x2847, 0x2848, 0x2849, 0x284a, 0x284b, 0x284c, 0x2268, + 0x225e, 0x2749, 0x274a, 0x274b, 0x274c, 0x274d, 0x273a, 0x273b, + 0x275c, 0x275d, 0x275e, 0x2736, 0x2737, 0x2738, 0x2754, 0x2755, + 0x2756, 0x2757, 0x2758, 0x2721, 0x2722, 0x2723, 0x2725, 0x272b, + 0x272c, 0x272d, 0x272e, 0x272f, 0x2730, 0x2731, 0x2732, 0x2733, + 0x2734, 0x2727, 0x2728, 0x2729, 0x272a, 0x273d, 0x273e, 0x2765, + 0x2766, 0x2767, 0x2768, 0x2761, 0x2762, 0x2763, 0x273f, 0x2740, + 0x2741, 0x2742, 0x2743, 0x2744, 0x2745, 0x2746, 0x2747, 0x2748, + 0x274e, 0x274f, 0x2750, 0x2751, 0x2752, 0x2753, 0x275a, 0x275b, + 0x2263, 0x276c, 0x2726, 0x2760, 0x276f, 0x2261, 0x273c, 0x276d, + 0x2735, 0x2739, 0x276a, 0x276b, 0x275f, 0x2264, 0x2764, 0x276e, + 0x2769, 0x6c69, 0x6f4b, 0x7652, 0x5832, 0x6d5b, 0x5f32, 0x5f3e, + 0x793b, 0x5c74, 0x7564, 0x7326, 0x5d60, 0x6126, 0x4e78, 0x5c30, + 0x632a, 0x7169, 0x4d7a, 0x7c2f, 0x5321, 0x712b, 0x6751, 0x522c, + 0x4e79, 0x717d, 0x5e3f, 0x7b3a, 0x7939, 0x4e52, 0x632b, 0x6b60, + 0x4e7a, 0x4b77, 0x6525, 0x4a61, 0x544c, 0x6a61, 0x5c63, 0x5f2d, + 0x4b6b, 0x552f, 0x5675, 0x6578, 0x5e40, 0x6c23, 0x694d, 0x6a27, + 0x6976, 0x7b3b, 0x6769, 0x6f4c, 0x5066, 0x5e41, 0x642c, 0x584c, + 0x7971, 0x4e5f, 0x7a24, 0x6632, 0x7a7b, 0x7a3d, 0x4c48, 0x6f4d, + 0x5555, 0x5322, 0x6c51, 0x6427, 0x6c52, 0x7631, 0x4e7b, 0x5051, + 0x4b3f, 0x6d24, 0x6d28, 0x5e42, 0x7662, 0x6d5c, 0x5c75, 0x6039, + 0x544e, 0x7435, 0x535b, 0x5635, 0x6c24, 0x6466, 0x716a, 0x4b6c, + 0x4b40, 0x6c72, 0x506a, 0x7972, 0x6c25, 0x505f, 0x676a, 0x506b, + 0x5c51, 0x5b69, 0x7d4c, 0x5b57, 0x5a61, 0x5636, 0x635f, 0x5e43, + 0x5e44, 0x4a21, 0x6e6c, 0x5323, 0x6e37, 0x784f, 0x6a48, 0x6e38, + 0x712c, 0x7125, 0x694e, 0x793c, 0x6579, 0x6c6a, 0x5d56, 0x6d42, + 0x7825, 0x653a, 0x5b58, 0x4a22, 0x514d, 0x6e6d, 0x6c6b, 0x5e45, + 0x6360, 0x4a49, 0x7269, 0x554e, 0x7636, 0x4e42, 0x5647, 0x6334, + 0x712d, 0x6a62, 0x5742, 0x7327, 0x4d6a, 0x6b6e, 0x5932, 0x7d25, + 0x7655, 0x5562, 0x7835, 0x4c75, 0x7535, 0x642d, 0x676b, 0x7155, + 0x703b, 0x6935, 0x4c49, 0x7a55, 0x6154, 0x5756, 0x5c41, 0x5e46, + 0x7a6f, 0x6361, 0x6173, 0x5c76, 0x4e7c, 0x5b44, 0x7871, 0x5c64, + 0x656f, 0x5c31, 0x5556, 0x735a, 0x4b41, 0x5b43, 0x597a, 0x536e, + 0x7a38, 0x7d26, 0x6b6f, 0x7426, 0x4c4a, 0x7328, 0x735b, 0x5b27, + 0x7637, 0x4f66, 0x7072, 0x4b5a, 0x6752, 0x5743, 0x7670, 0x685e, + 0x6526, 0x6567, 0x4a23, 0x4c27, 0x6a49, 0x7836, 0x7a25, 0x712e, + 0x6f4e, 0x4b6d, 0x7630, 0x6f4f, 0x694f, 0x775e, 0x4e53, 0x5c77, + 0x5b28, 0x4b78, 0x5f21, 0x5d61, 0x754a, 0x6936, 0x676c, 0x6e6e, + 0x7370, 0x5f3f, 0x4c4b, 0x5041, 0x7452, 0x603a, 0x5f40, 0x4e60, + 0x5c52, 0x7d6a, 0x5676, 0x6a4a, 0x6869, 0x632c, 0x7350, 0x4a24, + 0x5b78, 0x5e47, 0x6b70, 0x7156, 0x6562, 0x4c4c, 0x4b7b, 0x6a63, + 0x5f41, 0x566d, 0x6950, 0x6e39, 0x5563, 0x5153, 0x6570, 0x6834, + 0x6b43, 0x6a2a, 0x7a7c, 0x7576, 0x703c, 0x7d54, 0x603b, 0x4e43, + 0x503a, 0x773a, 0x5873, 0x774d, 0x642e, 0x545f, 0x5067, 0x6c7d, + 0x522e, 0x6e6f, 0x5557, 0x6a64, 0x7822, 0x4d6b, 0x573f, 0x7b31, + 0x4d6c, 0x5c32, 0x506c, 0x4e7d, 0x6e70, 0x4c42, 0x506d, 0x6577, + 0x737c, 0x6e22, 0x5933, 0x5874, 0x6937, 0x4e2e, 0x5922, 0x5871, + 0x544f, 0x6527, 0x5552, 0x5629, 0x7422, 0x7157, 0x5558, 0x703d, + 0x5750, 0x5450, 0x574f, 0x6b6a, 0x7d6b, 0x5b6d, 0x7c45, 0x4b42, + 0x7d55, 0x7448, 0x686a, 0x7573, 0x795e, 0x536f, 0x6c53, 0x5d42, + 0x6f37, 0x6754, 0x4a4a, 0x597b, 0x7a7d, 0x562a, 0x7478, 0x7777, + 0x5c2c, 0x5757, 0x5f22, 0x4e3e, 0x5370, 0x7024, 0x616c, 0x4f67, + 0x734b, 0x6d29, 0x4a3e, 0x746f, 0x764e, 0x5e7b, 0x503b, 0x5537, + 0x6e71, 0x7428, 0x5c78, 0x4b27, 0x5a4e, 0x6066, 0x6d25, 0x6e72, + 0x5c79, 0x795c, 0x735c, 0x7872, 0x7479, 0x7c71, 0x503c, 0x5b79, + 0x5731, 0x4b7c, 0x7025, 0x4b7d, 0x5574, 0x4d6d, 0x4a25, 0x562b, + 0x5042, 0x703e, 0x523d, 0x4c24, 0x7a36, 0x4c4d, 0x5a7a, 0x764f, + 0x6938, 0x5875, 0x4c4e, 0x574d, 0x5451, 0x696d, 0x4a6b, 0x5962, + 0x7d32, 0x632d, 0x564c, 0x5934, 0x6127, 0x6e53, 0x5043, 0x7d33, + 0x5564, 0x4f68, 0x6d43, 0x5032, 0x4e7e, 0x5a28, 0x7850, 0x7d56, + 0x7851, 0x7852, 0x5c53, 0x5d62, 0x7b79, 0x5d41, 0x6335, 0x6d5d, + 0x4e44, 0x4b21, 0x5d63, 0x7c5d, 0x792f, 0x527b, 0x4f21, 0x6428, + 0x7436, 0x6c7e, 0x632e, 0x676d, 0x7d41, 0x5a62, 0x5833, 0x5d64, + 0x706f, 0x7671, 0x7a70, 0x5175, 0x5a4f, 0x5c54, 0x5c26, 0x6f3f, + 0x4e4f, 0x6059, 0x5956, 0x6c54, 0x6a4b, 0x4a3f, 0x5530, 0x4f69, + 0x716d, 0x4c4f, 0x6478, 0x646d, 0x5758, 0x7d27, 0x6a2b, 0x7632, + 0x4f70, 0x793d, 0x6674, 0x4b5b, 0x7351, 0x6951, 0x7329, 0x5060, + 0x6952, 0x5a63, 0x6252, 0x7622, 0x6174, 0x5a64, 0x6755, 0x753f, + 0x4f22, 0x4d2f, 0x4f23, 0x4d30, 0x717e, 0x5023, 0x612f, 0x7823, + 0x4a26, 0x773b, 0x726a, 0x5e48, 0x6953, 0x5e49, 0x7d5e, 0x4a40, + 0x796a, 0x514e, 0x6e54, 0x5452, 0x5923, 0x7d28, 0x5759, 0x774e, + 0x7a3e, 0x4f56, 0x5770, 0x6b61, 0x7845, 0x5c7a, 0x5d43, 0x795f, + 0x676f, 0x7d65, 0x7623, 0x597c, 0x7d29, 0x676e, 0x5565, 0x6f50, + 0x4d31, 0x7722, 0x7132, 0x7131, 0x4d32, 0x5a2b, 0x4a27, 0x6362, + 0x7b3c, 0x5924, 0x6e3a, 0x7853, 0x7b7a, 0x4f24, 0x5c7b, 0x7663, + 0x6d2a, 0x7221, 0x4e61, 0x7a26, 0x7960, 0x6c56, 0x646e, 0x7921, + 0x7b6f, 0x796b, 0x6e23, 0x6a2c, 0x4a28, 0x747a, 0x4d56, 0x7c76, + 0x7449, 0x7854, 0x7826, 0x5e4a, 0x7246, 0x575a, 0x5350, 0x5845, + 0x6a66, 0x735d, 0x645a, 0x7664, 0x7672, 0x5f42, 0x597d, 0x4c76, + 0x533a, 0x642f, 0x7961, 0x7026, 0x4b53, 0x603c, 0x744a, 0x547a, + 0x7d2a, 0x7962, 0x7437, 0x7d42, 0x7c30, 0x7d6c, 0x4a62, 0x7d3d, + 0x6a67, 0x5f43, 0x5152, 0x4e62, 0x5324, 0x7d2b, 0x5f60, 0x7247, + 0x6770, 0x506e, 0x732a, 0x5e4b, 0x7638, 0x6175, 0x7133, 0x7723, + 0x4a29, 0x4f25, 0x5f44, 0x6130, 0x703f, 0x7624, 0x6336, 0x7a46, + 0x506f, 0x7d6d, 0x5d44, 0x7c77, 0x663f, 0x5e2d, 0x7a3f, 0x6571, + 0x6d44, 0x5225, 0x7d6e, 0x7536, 0x6176, 0x5e4c, 0x7c5e, 0x6c57, + 0x4d5d, 0x5637, 0x4d33, 0x7855, 0x6558, 0x4f6a, 0x4f50, 0x6a4c, + 0x6a2e, 0x6a2d, 0x5371, 0x5325, 0x774f, 0x6e24, 0x5024, 0x7222, + 0x5070, 0x7223, 0x7778, 0x5033, 0x5b29, 0x533b, 0x4a6c, 0x7126, + 0x4b55, 0x7767, 0x4d5e, 0x7724, 0x7840, 0x535d, 0x4c50, 0x4f26, + 0x7673, 0x6177, 0x535c, 0x7a7e, 0x7a27, 0x6b59, 0x4f27, 0x6a2f, + 0x646f, 0x6939, 0x7158, 0x5858, 0x6072, 0x6634, 0x5c7c, 0x7371, + 0x6350, 0x727b, 0x5b46, 0x5071, 0x5072, 0x4f5c, 0x5351, 0x4c31, + 0x7758, 0x4b28, 0x6b3c, 0x643e, 0x745c, 0x5c42, 0x7027, 0x6640, + 0x4a6d, 0x686b, 0x6568, 0x5c43, 0x6d5e, 0x5372, 0x4c77, 0x4e54, + 0x672b, 0x4b43, 0x6131, 0x7732, 0x5373, 0x5352, 0x7540, 0x5f5d, + 0x6e73, 0x6771, 0x7d34, 0x7248, 0x7352, 0x6e74, 0x6253, 0x4c51, + 0x5f6a, 0x693a, 0x5957, 0x754d, 0x7172, 0x7a47, 0x5978, 0x5442, + 0x7665, 0x5d45, 0x6772, 0x6d5f, 0x4a4b, 0x5b7a, 0x6835, 0x5326, + 0x7d35, 0x7949, 0x6462, 0x7b3d, 0x5724, 0x4e45, 0x4e55, 0x5666, + 0x653d, 0x5e4d, 0x6c73, 0x6d60, 0x6c6c, 0x7b3e, 0x5f6b, 0x6178, + 0x793e, 0x5073, 0x602a, 0x6862, 0x6254, 0x527d, 0x6528, 0x5953, + 0x535e, 0x7438, 0x773c, 0x5c7d, 0x686c, 0x6467, 0x6377, 0x6c28, + 0x7a71, 0x6572, 0x5074, 0x522f, 0x5c65, 0x5025, 0x7134, 0x7c31, + 0x4c78, 0x5d46, 0x7a51, 0x775f, 0x7a28, 0x6e75, 0x5e4e, 0x6773, + 0x772c, 0x6b44, 0x6d61, 0x602b, 0x5d47, 0x5233, 0x523f, 0x4a4c, + 0x7b3f, 0x657d, 0x5d65, 0x584d, 0x6c74, 0x5075, 0x686d, 0x5052, + 0x5958, 0x7666, 0x5b2a, 0x7760, 0x5859, 0x7423, 0x745d, 0x6f51, + 0x5935, 0x6d2b, 0x6337, 0x6e3b, 0x4d34, 0x6073, 0x6a4d, 0x6c75, + 0x686e, 0x4b29, 0x712f, 0x4a4d, 0x6c29, 0x726b, 0x7d6f, 0x7973, + 0x6641, 0x6c58, 0x6d2c, 0x6a4e, 0x685f, 0x5e4f, 0x5226, 0x6774, + 0x5156, 0x6642, 0x6363, 0x6430, 0x5834, 0x7625, 0x735e, 0x5725, + 0x7768, 0x6846, 0x7b66, 0x5d66, 0x5c7e, 0x585a, 0x5a2c, 0x6a30, + 0x6338, 0x4a2a, 0x6179, 0x6a31, 0x726c, 0x7a6e, 0x6e55, 0x7974, + 0x526c, 0x7b7b, 0x7d70, 0x603d, 0x4e63, 0x7846, 0x5e2e, 0x5f45, + 0x653e, 0x6d2d, 0x7a6a, 0x4d6e, 0x6d26, 0x6d2e, 0x706d, 0x5d21, + 0x6d2f, 0x7c78, 0x586b, 0x4c79, 0x4d35, 0x7a29, 0x615d, 0x6255, + 0x6d4f, 0x5d22, 0x794a, 0x6a68, 0x656d, 0x536b, 0x6954, 0x617a, + 0x644c, 0x6164, 0x6847, 0x4e5b, 0x5c55, 0x7735, 0x7c73, 0x7073, + 0x4e2f, 0x7135, 0x6f52, 0x6848, 0x6b71, 0x4b54, 0x603e, 0x6378, + 0x6a69, 0x7c32, 0x6074, 0x4f60, 0x6e25, 0x7a2a, 0x6643, 0x6132, + 0x4a2b, 0x6364, 0x693b, 0x6256, 0x7372, 0x6e56, 0x6a32, 0x5076, + 0x6c59, 0x5a4b, 0x4f28, 0x5d23, 0x585b, 0x794e, 0x6955, 0x6351, + 0x523c, 0x582c, 0x734c, 0x4d7b, 0x7656, 0x6775, 0x686f, 0x6379, + 0x523b, 0x7373, 0x637b, 0x5e50, 0x4e30, 0x5677, 0x7159, 0x7541, + 0x5c44, 0x753b, 0x5e51, 0x5c66, 0x5e52, 0x6d62, 0x6e76, 0x6a4f, + 0x706e, 0x637c, 0x535f, 0x5374, 0x6133, 0x6134, 0x7453, 0x5f46, + 0x6956, 0x5b2b, 0x7626, 0x6339, 0x6b45, 0x7429, 0x4d36, 0x5279, + 0x5a2d, 0x5263, 0x4f51, 0x4b5c, 0x4c7a, 0x4f5d, 0x6829, 0x633b, + 0x633a, 0x605a, 0x6e77, 0x5c33, 0x5375, 0x5726, 0x7635, 0x575b, + 0x6155, 0x546a, 0x5f23, 0x7d5f, 0x5077, 0x6d54, 0x4b2a, 0x645b, + 0x617b, 0x4b22, 0x5360, 0x643f, 0x7b40, 0x5a3e, 0x644d, 0x5639, + 0x6f40, 0x617c, 0x7639, 0x5f47, 0x6431, 0x5c67, 0x5c68, 0x7a56, + 0x5376, 0x715a, 0x7a72, 0x627d, 0x554f, 0x5078, 0x4d5f, 0x754b, + 0x6470, 0x4b2b, 0x5744, 0x627e, 0x5d5a, 0x5a2e, 0x4a6e, 0x5539, + 0x6321, 0x6863, 0x732b, 0x4f29, 0x5377, 0x5471, 0x4e64, 0x6872, + 0x6575, 0x672e, 0x563a, 0x5f6c, 0x6440, 0x6864, 0x5835, 0x645c, + 0x7439, 0x7136, 0x625e, 0x6135, 0x4d6f, 0x7127, 0x4e65, 0x4b5d, + 0x5963, 0x732c, 0x5079, 0x6c2b, 0x5e53, 0x7769, 0x7975, 0x615e, + 0x4b6e, 0x633c, 0x7856, 0x5b6e, 0x7d71, 0x7736, 0x745e, 0x726d, + 0x5b59, 0x7028, 0x617d, 0x5e54, 0x602c, 0x6d63, 0x5361, 0x5f48, + 0x5936, 0x7d2c, 0x6f53, 0x6441, 0x786b, 0x5b2c, 0x7c46, 0x582d, + 0x763a, 0x5b5f, 0x5353, 0x7847, 0x4a4e, 0x7841, 0x5234, 0x5c34, + 0x7a39, 0x4a4f, 0x7c33, 0x6a6a, 0x6a6b, 0x507a, 0x6d64, 0x5d67, + 0x5f49, 0x5f6d, 0x6e3c, 0x6f41, 0x4c52, 0x5d24, 0x5f4a, 0x5378, + 0x7128, 0x4d37, 0x6f54, 0x645d, 0x5f6e, 0x4b2c, 0x693c, 0x6a6c, + 0x5f4b, 0x793f, 0x562f, 0x5546, 0x4f2a, 0x4e29, 0x5678, 0x7137, + 0x6e78, 0x5959, 0x735f, 0x7848, 0x4e46, 0x5566, 0x7466, 0x6645, + 0x6f55, 0x4b6f, 0x7c5f, 0x5c27, 0x5667, 0x7849, 0x6352, 0x633d, + 0x4f61, 0x7040, 0x6c5a, 0x5d57, 0x7b70, 0x6c2c, 0x7029, 0x7a57, + 0x7b41, 0x5240, 0x6530, 0x6d65, 0x4b2d, 0x7930, 0x7725, 0x4b2e, + 0x5a2f, 0x5836, 0x5327, 0x7b32, 0x7d44, 0x6c2d, 0x7b21, 0x6569, + 0x696e, 0x7374, 0x7873, 0x7041, 0x5e2f, 0x7830, 0x7360, 0x672f, + 0x5b2d, 0x6635, 0x7928, 0x5d58, 0x6859, 0x6f56, 0x5362, 0x625f, + 0x7c60, 0x5748, 0x7d2d, 0x5f6f, 0x4c53, 0x5379, 0x5470, 0x5b47, + 0x5e55, 0x7074, 0x5550, 0x6559, 0x7c47, 0x5c56, 0x6260, 0x5a30, + 0x7323, 0x536c, 0x744b, 0x7d45, 0x637d, 0x7931, 0x507b, 0x6c5b, + 0x753c, 0x7224, 0x584e, 0x584f, 0x7577, 0x7661, 0x5237, 0x7b6c, + 0x5d48, 0x6468, 0x5241, 0x7857, 0x563b, 0x5e56, 0x773d, 0x6c2e, + 0x5061, 0x6075, 0x6a33, 0x4e56, 0x4c25, 0x6c76, 0x6261, 0x633e, + 0x7c48, 0x4d70, 0x7976, 0x5f70, 0x653f, 0x4e3f, 0x7c61, 0x6d30, + 0x7d51, 0x763b, 0x794f, 0x6b5a, 0x4a41, 0x5238, 0x4d71, 0x6353, + 0x7d66, 0x666d, 0x637a, 0x702a, 0x7950, 0x7c62, 0x7827, 0x6165, + 0x6e79, 0x6776, 0x6a6d, 0x7c34, 0x7542, 0x575c, 0x7075, 0x5d68, + 0x536d, 0x757c, 0x5a3f, 0x4c7b, 0x537a, 0x7424, 0x6f57, 0x5443, + 0x7b63, 0x7b6d, 0x602d, 0x6a6e, 0x7b33, 0x6442, 0x7667, 0x525d, + 0x5f4c, 0x7c49, 0x6529, 0x6076, 0x7633, 0x617e, 0x4b70, 0x6a6f, + 0x6a70, 0x5a40, 0x7834, 0x6b72, 0x6443, 0x6957, 0x6471, 0x4a6f, + 0x4e57, 0x7c4a, 0x7361, 0x4b44, 0x6365, 0x4b45, 0x6a34, 0x693d, + 0x5749, 0x6b5b, 0x6d31, 0x4c43, 0x773e, 0x7c4b, 0x7874, 0x5937, + 0x7353, 0x7354, 0x7764, 0x7751, 0x5837, 0x4e31, 0x4a42, 0x7b34, + 0x4b46, 0x7076, 0x5567, 0x6a50, 0x4c54, 0x4b2f, 0x742a, 0x692f, + 0x7543, 0x6958, 0x5d69, 0x7173, 0x557b, 0x5e3b, 0x747b, 0x7d73, + 0x7d72, 0x7726, 0x5d49, 0x5453, 0x4c28, 0x5a41, 0x4c55, 0x5964, + 0x7a4a, 0x6563, 0x533c, 0x4a70, 0x5044, 0x4a50, 0x7a2b, 0x6b6b, + 0x6778, 0x5965, 0x5157, 0x7324, 0x547b, 0x7c63, 0x7a58, 0x7355, + 0x4f2b, 0x6b73, 0x557c, 0x5354, 0x4d7c, 0x5966, 0x6279, 0x6221, + 0x6b54, 0x6077, 0x6432, 0x4c7c, 0x7b64, 0x742b, 0x503d, 0x4a71, + 0x6f38, 0x5740, 0x6e7a, 0x7d74, 0x5363, 0x7b42, 0x5568, 0x5b2e, + 0x6136, 0x7837, 0x603f, 0x7b43, 0x5d6a, 0x6222, 0x6e26, 0x7668, + 0x7675, 0x5d4a, 0x5062, 0x5d26, 0x5d6b, 0x6479, 0x632f, 0x507c, + 0x747c, 0x4c3c, 0x776a, 0x6564, 0x5f71, 0x7761, 0x7977, 0x6f39, + 0x7858, 0x7929, 0x7859, 0x6e3d, 0x5846, 0x6463, 0x754e, 0x5d59, + 0x5967, 0x5239, 0x5543, 0x5a65, 0x5a50, 0x5159, 0x4e58, 0x4b5e, + 0x742c, 0x5a7b, 0x7669, 0x6873, 0x4f2c, 0x7070, 0x747d, 0x5b48, + 0x4e40, 0x6354, 0x514f, 0x7175, 0x4d72, 0x4f6b, 0x4d38, 0x6326, + 0x515a, 0x7225, 0x7226, 0x644e, 0x537b, 0x7129, 0x7249, 0x6f58, + 0x6649, 0x5838, 0x7a73, 0x7335, 0x7824, 0x5173, 0x6648, 0x785a, + 0x5c69, 0x5e57, 0x4b5f, 0x4f6c, 0x745f, 0x5174, 0x523a, 0x5f72, + 0x6137, 0x6223, 0x537c, 0x6d66, 0x5b49, 0x647a, 0x4f5e, 0x4e50, + 0x5553, 0x7375, 0x772e, 0x6f48, 0x4d73, 0x754f, 0x6573, 0x7042, + 0x4a51, 0x6a71, 0x5026, 0x595a, 0x702b, 0x6b67, 0x6540, 0x7c35, + 0x6444, 0x4c29, 0x7d46, 0x6a35, 0x652a, 0x5f3a, 0x615f, 0x5a51, + 0x6138, 0x6874, 0x537d, 0x6224, 0x724a, 0x5a66, 0x7733, 0x7d4d, + 0x7336, 0x6e57, 0x7544, 0x5824, 0x7227, 0x5938, 0x5939, 0x6f49, + 0x564e, 0x774b, 0x5f2e, 0x6875, 0x5235, 0x5355, 0x744c, 0x5a7c, + 0x5968, 0x776b, 0x7549, 0x733c, 0x5a52, 0x5335, 0x6836, 0x564f, + 0x743a, 0x7749, 0x4c2a, 0x7043, 0x4c56, 0x5053, 0x533d, 0x5b7b, + 0x4b60, 0x5364, 0x7677, 0x553a, 0x734d, 0x4b61, 0x6b74, 0x742d, + 0x7c2a, 0x776c, 0x6876, 0x5a67, 0x774c, 0x6541, 0x606e, 0x557d, + 0x4e66, 0x7c2b, 0x553b, 0x7228, 0x6225, 0x4d39, 0x6a72, 0x4b47, + 0x4d74, 0x5b2f, 0x6f59, 0x4d3a, 0x7c79, 0x5f73, 0x4e67, 0x5a42, + 0x4f2d, 0x6779, 0x7828, 0x7362, 0x4a72, 0x5f24, 0x5444, 0x4c57, + 0x6542, 0x4d3b, 0x6f5a, 0x6e58, 0x5d27, 0x6226, 0x6040, 0x5630, + 0x784a, 0x7c7a, 0x597e, 0x5e30, 0x5d6c, 0x5a68, 0x5460, 0x5679, + 0x4d57, 0x5e58, 0x7278, 0x6456, 0x5045, 0x742e, 0x5d28, 0x6d45, + 0x7356, 0x5e59, 0x6366, 0x5328, 0x5b30, 0x655a, 0x633f, 0x5b31, + 0x5569, 0x6041, 0x6f5b, 0x7069, 0x5732, 0x507d, 0x5969, 0x507e, + 0x6c6d, 0x5329, 0x7229, 0x7044, 0x6262, 0x696f, 0x7951, 0x6959, + 0x685a, 0x5a43, 0x5a44, 0x5445, 0x677a, 0x4d60, 0x6330, 0x5b32, + 0x7b44, 0x7363, 0x5925, 0x7b67, 0x5d4b, 0x5054, 0x6636, 0x602e, + 0x7d5a, 0x5c35, 0x6078, 0x6731, 0x7570, 0x585c, 0x6d46, 0x6139, + 0x6340, 0x7940, 0x6970, 0x595b, 0x7364, 0x5c36, 0x6469, 0x7045, + 0x6341, 0x7c4c, 0x7c4d, 0x724b, 0x724c, 0x644f, 0x715b, 0x7a59, + 0x7138, 0x7d75, 0x6079, 0x677b, 0x7c37, 0x7c64, 0x7b45, 0x6367, + 0x5839, 0x7678, 0x5c45, 0x4c58, 0x602f, 0x7467, 0x6f5c, 0x4f7c, + 0x6f5d, 0x722a, 0x7d3e, 0x4a2c, 0x7d3b, 0x7d47, 0x6732, 0x6a51, + 0x5f74, 0x516c, 0x645e, 0x6543, 0x5926, 0x4d3c, 0x7365, 0x6d55, + 0x593a, 0x6d67, 0x7b35, 0x786c, 0x6067, 0x4c59, 0x5446, 0x6725, + 0x5575, 0x533e, 0x7c7b, 0x6472, 0x5f75, 0x6878, 0x786d, 0x4e47, + 0x7d76, 0x6858, 0x4d58, 0x6756, 0x4c5a, 0x4a63, 0x5f76, 0x7047, + 0x7046, 0x583a, 0x7174, 0x7470, 0x754c, 0x7c65, 0x6a45, 0x6a73, + 0x5d5b, 0x5c57, 0x5e7d, 0x7279, 0x5547, 0x5850, 0x7048, 0x5121, + 0x5122, 0x5954, 0x5668, 0x594a, 0x5a31, 0x5847, 0x5c62, 0x734e, + 0x7574, 0x7139, 0x5a53, 0x766a, 0x4f75, 0x7d2e, 0x4a52, 0x5f34, + 0x575d, 0x7a3a, 0x6e27, 0x753d, 0x7875, 0x6d68, 0x5461, 0x5123, + 0x6156, 0x7978, 0x5b4a, 0x4b79, 0x5454, 0x595c, 0x6e3e, 0x776d, + 0x526e, 0x6166, 0x7779, 0x5d6d, 0x685b, 0x5b33, 0x5177, 0x6030, + 0x5462, 0x7657, 0x5779, 0x585d, 0x4d7d, 0x722b, 0x4d3d, 0x7842, + 0x722c, 0x4a2d, 0x4a2e, 0x4f2e, 0x6342, 0x5c37, 0x5b5a, 0x593b, + 0x4a73, 0x7653, 0x6678, 0x6a75, 0x6a76, 0x7679, 0x4f2f, 0x4a53, + 0x4a2f, 0x5230, 0x713a, 0x5733, 0x6343, 0x737d, 0x5e5a, 0x5e5b, + 0x6f5e, 0x6263, 0x6e7b, 0x5f77, 0x574a, 0x4e68, 0x5b5b, 0x713b, + 0x6971, 0x7a37, 0x5046, 0x4c2b, 0x6e28, 0x4b7a, 0x7979, 0x4c7d, + 0x537e, 0x6450, 0x726e, 0x5455, 0x5f4d, 0x7c38, 0x5150, 0x724d, + 0x7752, 0x4a54, 0x5559, 0x585e, 0x4d59, 0x6e29, 0x763c, 0x4c5b, + 0x7049, 0x7c7c, 0x6849, 0x747e, 0x677c, 0x575e, 0x5e5c, 0x702c, + 0x4c7e, 0x4d61, 0x613a, 0x5b6f, 0x5a32, 0x5125, 0x5c38, 0x5876, + 0x5124, 0x4d62, 0x5c6a, 0x7077, 0x704a, 0x503e, 0x5d5c, 0x5456, + 0x5356, 0x6d50, 0x4d21, 0x5f35, 0x5f78, 0x5421, 0x4e32, 0x684a, + 0x6b75, 0x6355, 0x7550, 0x7521, 0x5927, 0x652b, 0x664b, 0x7571, + 0x6545, 0x7923, 0x605b, 0x766b, 0x4b71, 0x596a, 0x7522, 0x5751, + 0x5178, 0x6a78, 0x6a79, 0x5a33, 0x6f5f, 0x716f, 0x6576, 0x6e3f, + 0x6264, 0x503f, 0x7a2c, 0x7551, 0x6733, 0x693e, 0x724e, 0x5b34, + 0x7c4e, 0x5d6e, 0x6734, 0x5734, 0x7734, 0x4d3e, 0x5a69, 0x4f30, + 0x7759, 0x7366, 0x4e59, 0x4e2a, 0x4b48, 0x5027, 0x704b, 0x5047, + 0x6445, 0x5b60, 0x555a, 0x5727, 0x6e40, 0x7876, 0x7552, 0x6d69, + 0x593c, 0x6546, 0x7523, 0x5a54, 0x6227, 0x7b7c, 0x715c, 0x4a74, + 0x687a, 0x4e69, 0x6978, 0x6265, 0x5039, 0x5472, 0x5126, 0x5f4e, + 0x7c74, 0x532a, 0x4c2c, 0x6f60, 0x6565, 0x5055, 0x5b7c, 0x7c66, + 0x4b7e, 0x6d6a, 0x5e31, 0x7963, 0x5422, 0x4f76, 0x5650, 0x556a, + 0x716e, 0x7a4b, 0x6521, 0x5531, 0x4f6d, 0x6d6b, 0x5532, 0x553c, + 0x7d62, 0x732d, 0x7d5b, 0x6930, 0x5127, 0x7d63, 0x4e33, 0x7d64, + 0x7a4e, 0x4a30, 0x7727, 0x4f31, 0x6622, 0x7c36, 0x722d, 0x6f61, + 0x732e, 0x5c46, 0x596b, 0x6860, 0x6128, 0x5576, 0x4f7d, 0x5e5d, + 0x5951, 0x646a, 0x724f, 0x773f, 0x6266, 0x6228, 0x6356, 0x6d51, + 0x6979, 0x5631, 0x5e32, 0x6068, 0x532b, 0x6b5c, 0x5f2f, 0x4a43, + 0x6e7c, 0x7d43, 0x6b76, 0x4f32, 0x596c, 0x593d, 0x585f, 0x5438, + 0x6b3e, 0x5d6f, 0x5d70, 0x5d71, 0x5d72, 0x593e, 0x7b46, 0x4f33, + 0x6e7d, 0x642b, 0x5a45, 0x586c, 0x5128, 0x6229, 0x5e3c, 0x6735, + 0x5b70, 0x6f62, 0x7170, 0x4f34, 0x5b71, 0x6031, 0x5f25, 0x7952, + 0x677d, 0x6623, 0x7b71, 0x4b30, 0x722e, 0x4d67, 0x685c, 0x6757, + 0x7740, 0x5063, 0x5a21, 0x4c3d, 0x5129, 0x5d4c, 0x637e, 0x512a, + 0x682a, 0x6a36, 0x797a, 0x664c, 0x7658, 0x5447, 0x594b, 0x5952, + 0x534b, 0x5877, 0x5a29, 0x7578, 0x5e5e, 0x722f, 0x7829, 0x5848, + 0x6e41, 0x7941, 0x5d73, 0x6a7a, 0x763d, 0x613b, 0x4d3f, 0x7454, + 0x664d, 0x7c4f, 0x7b22, 0x605c, 0x743b, 0x5a55, 0x7932, 0x7b72, + 0x5b76, 0x5e5f, 0x5b72, 0x785c, 0x776e, 0x6b68, 0x527a, 0x713c, + 0x7a5a, 0x5a6a, 0x5a46, 0x7741, 0x6736, 0x6547, 0x562c, 0x5c47, + 0x6129, 0x622a, 0x5526, 0x5457, 0x7250, 0x6a7b, 0x605d, 0x7b73, + 0x713d, 0x6267, 0x7d57, 0x4e48, 0x6a37, 0x7c40, 0x7d67, 0x776f, + 0x5735, 0x6f3a, 0x715d, 0x5e33, 0x684b, 0x785d, 0x7b47, 0x5548, + 0x575f, 0x5d29, 0x6931, 0x7a2d, 0x7659, 0x7a74, 0x782a, 0x666e, + 0x4c5c, 0x613c, 0x606f, 0x693f, 0x7c7d, 0x664e, 0x6157, 0x664f, + 0x7471, 0x6473, 0x647b, 0x7964, 0x6f63, 0x4f6e, 0x763e, 0x6032, + 0x7c7e, 0x512b, 0x577a, 0x7b48, 0x6257, 0x5423, 0x7078, 0x5728, + 0x6167, 0x533f, 0x6f64, 0x5745, 0x6b62, 0x7c67, 0x6422, 0x6268, + 0x6650, 0x7b68, 0x7468, 0x6574, 0x743c, 0x7455, 0x5f36, 0x7c39, + 0x6e42, 0x4a75, 0x6f65, 0x4b62, 0x5424, 0x5e60, 0x5a7d, 0x6446, + 0x683e, 0x605e, 0x7634, 0x6a52, 0x797b, 0x6042, 0x4a64, 0x6737, + 0x6a7d, 0x595d, 0x5a34, 0x6e2a, 0x7b69, 0x5b4b, 0x5a35, 0x713e, + 0x532c, 0x7b49, 0x5f4f, 0x5340, 0x6357, 0x6f66, 0x7c50, 0x6940, + 0x7553, 0x6c5c, 0x7737, 0x6a38, 0x5179, 0x5c48, 0x6a39, 0x715e, + 0x5736, 0x4f35, 0x5928, 0x6c6e, 0x5d2a, 0x4d22, 0x682e, 0x613d, + 0x7251, 0x6941, 0x527c, 0x5b35, 0x7367, 0x587e, 0x7c51, 0x6d32, + 0x742f, 0x7b23, 0x7c41, 0x6e2b, 0x5425, 0x7472, 0x6e59, 0x7b4a, + 0x4d63, 0x583b, 0x655b, 0x7877, 0x7654, 0x5729, 0x4b49, 0x6651, + 0x704c, 0x582e, 0x7953, 0x557e, 0x583c, 0x7230, 0x622b, 0x7368, + 0x6f42, 0x6d6c, 0x6738, 0x5a7e, 0x4c3e, 0x727c, 0x5a6b, 0x6258, + 0x6d56, 0x5651, 0x6033, 0x7c52, 0x6b48, 0x5341, 0x704d, 0x4f77, + 0x6d52, 0x5458, 0x5c49, 0x5771, 0x5f3b, 0x7325, 0x744d, 0x713f, + 0x7831, 0x697a, 0x7b4b, 0x4a55, 0x7954, 0x774a, 0x5648, 0x7c68, + 0x733d, 0x6e7e, 0x677e, 0x5342, 0x5336, 0x4c2d, 0x767a, 0x5632, + 0x5258, 0x6758, 0x6325, 0x6739, 0x702d, 0x7b4c, 0x6b21, 0x5426, + 0x7b4d, 0x553d, 0x715f, 0x767b, 0x5e34, 0x556b, 0x6548, 0x7b24, + 0x5439, 0x5e61, 0x6423, 0x5737, 0x786e, 0x5e35, 0x5652, 0x7955, + 0x673a, 0x6b55, 0x5577, 0x6f67, 0x613e, 0x7a2e, 0x5669, 0x566e, + 0x673b, 0x6c4b, 0x5533, 0x4e34, 0x7b25, 0x616e, 0x7728, 0x7b4e, + 0x583d, 0x7b7d, 0x7c69, 0x4f36, 0x6d47, 0x6e2c, 0x4c5d, 0x7627, + 0x667a, 0x7524, 0x7d5c, 0x6d33, 0x4e49, 0x6f68, 0x613f, 0x7a5b, + 0x4b63, 0x7729, 0x7b26, 0x5c39, 0x7140, 0x6d48, 0x6f43, 0x562d, + 0x7d4e, 0x6821, 0x7b74, 0x5527, 0x7176, 0x6653, 0x4c5e, 0x7832, + 0x5c6b, 0x7d36, 0x656a, 0x7160, 0x5b4c, 0x5d4d, 0x5448, 0x596d, + 0x7525, 0x667b, 0x6654, 0x7d48, 0x5621, 0x7d3f, 0x7c53, 0x6f21, + 0x673c, 0x516e, 0x6655, 0x6972, 0x5f30, 0x5860, 0x7c3a, 0x7d2f, + 0x704e, 0x5b61, 0x6549, 0x6d34, 0x6043, 0x6358, 0x697b, 0x6a28, + 0x7d37, 0x7b27, 0x6942, 0x7d77, 0x6259, 0x5c6c, 0x6822, 0x6670, + 0x7d78, 0x7d79, 0x763f, 0x6727, 0x6657, 0x5473, 0x5449, 0x567a, + 0x5772, 0x6140, 0x5b62, 0x6658, 0x673d, 0x704f, 0x733e, 0x622c, + 0x7537, 0x6070, 0x7d38, 0x6368, 0x5427, 0x687c, 0x7a52, 0x786f, + 0x5653, 0x5534, 0x7050, 0x7770, 0x6e33, 0x6a3a, 0x6a53, 0x6d49, + 0x5d2b, 0x652c, 0x7d21, 0x5f50, 0x6c33, 0x5f51, 0x6d6d, 0x7838, + 0x777a, 0x782b, 0x7460, 0x543a, 0x6433, 0x695a, 0x5e36, 0x593f, + 0x5940, 0x566f, 0x594c, 0x5a2a, 0x5f65, 0x7765, 0x4c32, 0x5f79, + 0x5760, 0x543b, 0x7d7a, 0x4c33, 0x5b73, 0x5f52, 0x4e4a, 0x6e5a, + 0x6464, 0x7b4f, 0x4f37, 0x6e43, 0x4e6a, 0x622d, 0x5761, 0x7a75, + 0x5549, 0x782c, 0x6759, 0x7369, 0x586d, 0x6344, 0x7071, 0x6865, + 0x607a, 0x6e44, 0x595e, 0x6b22, 0x6b23, 0x7c42, 0x6a3b, 0x682b, + 0x5e62, 0x6d6f, 0x6823, 0x4f71, 0x543c, 0x7c6a, 0x673e, 0x7c72, + 0x5634, 0x622e, 0x5337, 0x7a4c, 0x7a5c, 0x6d35, 0x6163, 0x682c, + 0x685d, 0x6f69, 0x743d, 0x4f38, 0x695b, 0x512c, 0x5a47, 0x6b49, + 0x684c, 0x5e37, 0x563c, 0x5365, 0x7a5d, 0x5a56, 0x4a31, 0x5a48, + 0x5f26, 0x7933, 0x7252, 0x4a44, 0x4e4b, 0x4d75, 0x7d30, 0x5528, + 0x7141, 0x6269, 0x5c4a, 0x6c34, 0x7a40, 0x7b28, 0x5028, 0x5a6c, + 0x596e, 0x607b, 0x6f6a, 0x7a5e, 0x6044, 0x4f39, 0x554a, 0x5762, + 0x622f, 0x5738, 0x684d, 0x765a, 0x6f22, 0x625a, 0x767c, 0x7b50, + 0x512d, 0x4d64, 0x512e, 0x5c6d, 0x684e, 0x7079, 0x4e35, 0x667c, + 0x577b, 0x5056, 0x5d75, 0x7771, 0x767d, 0x5b77, 0x7b6a, 0x695c, + 0x5941, 0x7572, 0x6045, 0x6a54, 0x7942, 0x6a3c, 0x5245, 0x7b51, + 0x6740, 0x6b25, 0x5f7a, 0x6322, 0x5739, 0x6943, 0x687d, 0x682f, + 0x7253, 0x7b29, 0x5825, 0x554b, 0x5048, 0x512f, 0x5763, 0x6046, + 0x5622, 0x6d70, 0x5773, 0x7c54, 0x5a57, 0x4c5f, 0x7254, 0x5130, + 0x4c60, 0x5b7d, 0x733f, 0x7051, 0x7c3b, 0x6230, 0x6625, 0x625b, + 0x5f5e, 0x6047, 0x726f, 0x4c61, 0x566a, 0x6742, 0x4e36, 0x7340, + 0x4d7e, 0x7b52, 0x7878, 0x777b, 0x683f, 0x6837, 0x6d36, 0x5c3a, + 0x4c34, 0x7177, 0x6838, 0x4a76, 0x6424, 0x7456, 0x5f66, 0x5f27, + 0x5f67, 0x6141, 0x6944, 0x5c4b, 0x6945, 0x6f23, 0x6b26, 0x4b23, + 0x6369, 0x517b, 0x6f24, 0x6f6b, 0x5034, 0x4d23, 0x6866, 0x6f25, + 0x534c, 0x5a6d, 0x573a, 0x7255, 0x7565, 0x596f, 0x7934, 0x5554, + 0x7d4f, 0x5b63, 0x7161, 0x6c36, 0x7b7e, 0x5357, 0x5131, 0x4b31, + 0x5132, 0x4b32, 0x7142, 0x7461, 0x7935, 0x6143, 0x6142, 0x6b77, + 0x5f28, 0x4b4a, 0x6639, 0x785e, 0x792a, 0x4a77, 0x6d37, 0x5338, + 0x7256, 0x5459, 0x6e45, 0x7270, 0x4a32, 0x5c3b, 0x7178, 0x6c37, + 0x654a, 0x7640, 0x7d5d, 0x5463, 0x4c62, 0x7754, 0x5765, 0x5343, + 0x5826, 0x7641, 0x5d76, 0x4d40, 0x655c, 0x654b, 0x6144, 0x6830, + 0x7430, 0x736a, 0x5a6e, 0x573b, 0x6231, 0x572a, 0x567b, 0x645f, + 0x4a56, 0x6b28, 0x5b7e, 0x7642, 0x6f3b, 0x547d, 0x6048, 0x6839, + 0x6f26, 0x4d24, 0x5474, 0x5b21, 0x5b5c, 0x5b5d, 0x6e5c, 0x4b4b, + 0x7c55, 0x4e6b, 0x4d41, 0x7b53, 0x792b, 0x7554, 0x5929, 0x695d, + 0x5b4d, 0x5d4e, 0x6743, 0x6c4c, 0x796c, 0x4b4c, 0x607c, 0x5428, + 0x6d53, 0x586f, 0x7257, 0x4a78, 0x5a6f, 0x5654, 0x594d, 0x586e, + 0x7241, 0x5f53, 0x5a70, 0x626a, 0x607d, 0x5878, 0x772f, 0x5a36, + 0x4a57, 0x7258, 0x5879, 0x7a5f, 0x4f6f, 0x5942, 0x7052, 0x6451, + 0x7337, 0x7a60, 0x6f6c, 0x6232, 0x543d, 0x594e, 0x7462, 0x5429, + 0x4d42, 0x675a, 0x7259, 0x592a, 0x583e, 0x5c2d, 0x626b, 0x567c, + 0x4a79, 0x545a, 0x7457, 0x4c21, 0x4f3a, 0x7538, 0x5943, 0x5068, + 0x6345, 0x6b78, 0x7231, 0x4f3b, 0x532d, 0x6861, 0x4e6c, 0x6034, + 0x5e63, 0x5d77, 0x7232, 0x7376, 0x765b, 0x577e, 0x785f, 0x7772, + 0x5029, 0x665a, 0x7526, 0x573c, 0x4c63, 0x665b, 0x5d5d, 0x5133, + 0x6f6d, 0x565e, 0x6474, 0x616f, 0x5d78, 0x684f, 0x4a65, 0x5c21, + 0x6035, 0x7c2c, 0x7c2d, 0x5827, 0x6d38, 0x5b36, 0x5670, 0x732f, + 0x4d25, 0x5a71, 0x5828, 0x4c64, 0x5134, 0x4a58, 0x5a72, 0x7527, + 0x7528, 0x6626, 0x556c, 0x5578, 0x5a73, 0x6346, 0x5e64, 0x5e65, + 0x5135, 0x5136, 0x5137, 0x7233, 0x695e, 0x7053, 0x7234, 0x7054, + 0x4b64, 0x7b54, 0x7566, 0x636a, 0x5e66, 0x5f54, 0x7879, 0x702e, + 0x5138, 0x565f, 0x5057, 0x7c21, 0x6f6e, 0x5c58, 0x695f, 0x655d, + 0x7d7b, 0x6049, 0x5649, 0x542a, 0x654c, 0x6960, 0x5058, 0x7c22, + 0x543e, 0x6233, 0x5e67, 0x5c3c, 0x5236, 0x7555, 0x4e21, 0x7529, + 0x5d79, 0x5d7a, 0x7055, 0x765f, 0x725a, 0x646b, 0x7271, 0x6c39, + 0x7d7c, 0x612a, 0x4a59, 0x6f6f, 0x752a, 0x6c79, 0x782d, 0x7242, + 0x7643, 0x5752, 0x7922, 0x7056, 0x707a, 0x7660, 0x6973, 0x7243, + 0x542b, 0x4a33, 0x4d26, 0x4d43, 0x4d5a, 0x594f, 0x7644, 0x6e5d, + 0x6744, 0x6234, 0x5f62, 0x675b, 0x6831, 0x7c2e, 0x654d, 0x7a6b, + 0x4f3c, 0x4f62, 0x4d76, 0x6f70, 0x743e, 0x544d, 0x7338, 0x6921, + 0x7272, 0x736b, 0x7057, 0x4f57, 0x4f5f, 0x6840, 0x6841, 0x4f63, + 0x6922, 0x502a, 0x7341, 0x502b, 0x5464, 0x6f3c, 0x5821, 0x595f, + 0x7357, 0x5c3d, 0x4c65, 0x6d71, 0x7162, 0x545b, 0x6235, 0x4a66, + 0x532e, 0x4c66, 0x7153, 0x7567, 0x4a5a, 0x7b6e, 0x6145, 0x5f69, + 0x6e5e, 0x7742, 0x5822, 0x5d2c, 0x702f, 0x563d, 0x612b, 0x7936, + 0x5475, 0x5049, 0x6f27, 0x626c, 0x5b6a, 0x4e4c, 0x7568, 0x7755, + 0x534d, 0x737e, 0x5035, 0x607e, 0x5f7b, 0x665d, 0x6824, 0x4b4d, + 0x6f28, 0x6e34, 0x5a58, 0x5139, 0x5f29, 0x7330, 0x4c44, 0x4e37, + 0x6f29, 0x5f55, 0x6d57, 0x6e46, 0x6f3d, 0x7c56, 0x5b74, 0x6f2a, + 0x7839, 0x7569, 0x6359, 0x6146, 0x543f, 0x5e68, 0x706a, 0x7342, + 0x532f, 0x4a5b, 0x7c57, 0x6d58, 0x6147, 0x7458, 0x5633, 0x5d2d, + 0x553e, 0x7143, 0x6e5f, 0x566b, 0x7459, 0x5766, 0x5a37, 0x5d7b, + 0x5d4f, 0x5823, 0x5a59, 0x7058, 0x6f44, 0x6158, 0x7154, 0x6d72, + 0x555b, 0x555c, 0x7344, 0x4b57, 0x6236, 0x6f71, 0x7b55, 0x5358, + 0x5d50, 0x7059, 0x4b33, 0x555d, 0x4d27, 0x502c, 0x513a, 0x7144, + 0x6533, 0x7b75, 0x6961, 0x7d60, 0x7c3c, 0x5a22, 0x5a23, 0x5221, + 0x526f, 0x626d, 0x5e69, 0x4e5c, 0x7235, 0x5064, 0x5d51, 0x6148, + 0x5b37, 0x5f63, 0x6d39, 0x7145, 0x734f, 0x572b, 0x612c, 0x636b, + 0x6e47, 0x6149, 0x4a7a, 0x707b, 0x7a61, 0x705a, 0x4c67, 0x5a74, + 0x4c3f, 0x4e6d, 0x5529, 0x7a62, 0x5065, 0x6b56, 0x6c5f, 0x5f7c, + 0x7756, 0x5e6a, 0x4b34, 0x6f3e, 0x4c35, 0x4f3d, 0x6f72, 0x6237, + 0x4c68, 0x707c, 0x5660, 0x7146, 0x6238, 0x6b2b, 0x4b35, 0x5851, + 0x744e, 0x7377, 0x5746, 0x513b, 0x772a, 0x6d4a, 0x5753, 0x587a, + 0x7645, 0x514c, 0x5d7c, 0x5f7d, 0x7965, 0x604a, 0x727d, 0x5330, + 0x7473, 0x5a49, 0x665e, 0x783a, 0x6850, 0x587b, 0x6a55, 0x5623, + 0x7646, 0x725b, 0x647c, 0x6832, 0x5a5a, 0x725c, 0x7b56, 0x6932, + 0x6e2d, 0x7a63, 0x5c6e, 0x756a, 0x6660, 0x707d, 0x572c, 0x7545, + 0x6e60, 0x5b65, 0x5d5e, 0x5970, 0x6923, 0x7179, 0x7244, 0x604b, + 0x6924, 0x6239, 0x6331, 0x7c6b, 0x4d28, 0x4c36, 0x705b, 0x663a, + 0x4d29, 0x7343, 0x6159, 0x6f2b, 0x6745, 0x6069, 0x7345, 0x5440, + 0x553f, 0x5d2e, 0x797c, 0x4c40, 0x6522, 0x4e38, 0x5852, 0x7956, + 0x712a, 0x4e51, 0x7647, 0x5b6b, 0x5f7e, 0x5861, 0x7773, 0x5767, + 0x547e, 0x513c, 0x654f, 0x4b36, 0x5a38, 0x4d44, 0x563e, 0x623a, + 0x4f58, 0x604c, 0x6b79, 0x7d7d, 0x5768, 0x4b58, 0x6962, 0x683a, + 0x6347, 0x6c4d, 0x6c4e, 0x563f, 0x6327, 0x5f56, 0x7d68, 0x6e61, + 0x7628, 0x5d7d, 0x783b, 0x6851, 0x7957, 0x4e6e, 0x6c4f, 0x6925, + 0x5655, 0x4d45, 0x6d3a, 0x513d, 0x4f3e, 0x6c3b, 0x5231, 0x4c69, + 0x5944, 0x697c, 0x513e, 0x6c3c, 0x652d, 0x7730, 0x4c6a, 0x5344, + 0x5640, 0x567d, 0x6121, 0x5e3d, 0x7629, 0x5a24, 0x5624, 0x7546, + 0x6122, 0x6946, 0x7245, 0x7469, 0x566c, 0x6b53, 0x6c3d, 0x625c, + 0x5e6b, 0x705c, 0x6b3f, 0x574e, 0x513f, 0x752b, 0x797d, 0x4a5c, + 0x4d46, 0x7236, 0x5d7e, 0x4c37, 0x5b38, 0x5069, 0x4e5d, 0x6b40, + 0x7d22, 0x784b, 0x6a56, 0x7130, 0x5b4e, 0x7743, 0x5b4f, 0x4b24, + 0x7860, 0x7b57, 0x6b4a, 0x6021, 0x4e4d, 0x545c, 0x7d58, 0x5276, + 0x7237, 0x7a76, 0x762a, 0x7a77, 0x5866, 0x7431, 0x6852, 0x4a45, + 0x4c6b, 0x626e, 0x623b, 0x772d, 0x7861, 0x736c, 0x5e21, 0x647d, + 0x636c, 0x5d2f, 0x5d30, 0x4b37, 0x6853, 0x6123, 0x5260, 0x707e, + 0x6926, 0x4b72, 0x6d73, 0x5c59, 0x604d, 0x775a, 0x5b39, 0x4c2e, + 0x5a5b, 0x4d47, 0x5d31, 0x582f, 0x6323, 0x4e6f, 0x7273, 0x7833, + 0x604e, 0x757d, 0x6b6c, 0x5345, 0x7c6c, 0x525b, 0x546b, 0x5e22, + 0x6566, 0x7030, 0x5544, 0x6d74, 0x636d, 0x6842, 0x6d75, 0x577c, + 0x6d3b, 0x762b, 0x7238, 0x7648, 0x5366, 0x725d, 0x4f3f, 0x6b2c, + 0x4f40, 0x6628, 0x7d69, 0x4f41, 0x605f, 0x5e6c, 0x6022, 0x743f, + 0x626f, 0x5971, 0x7147, 0x4b38, 0x797e, 0x5b3a, 0x5a75, 0x766c, + 0x5a5c, 0x7a64, 0x604f, 0x5d32, 0x6629, 0x6f73, 0x736d, 0x6b7a, + 0x7966, 0x4a5d, 0x555e, 0x4a5e, 0x5f64, 0x667d, 0x752c, 0x6475, + 0x6963, 0x6d4b, 0x4f64, 0x5853, 0x5d33, 0x546c, 0x7239, 0x5f37, + 0x4b4e, 0x7b58, 0x5059, 0x5d52, 0x7774, 0x675c, 0x6425, 0x7c23, + 0x5b3b, 0x723a, 0x697d, 0x504a, 0x7556, 0x5945, 0x6434, 0x6d27, + 0x6a3d, 0x667e, 0x7744, 0x752d, 0x5960, 0x4a34, 0x7862, 0x4f42, + 0x6c3e, 0x6534, 0x4d48, 0x6e48, 0x6748, 0x4d49, 0x7937, 0x7168, + 0x5972, 0x5b75, 0x4a35, 0x5946, 0x5849, 0x592b, 0x6d3c, 0x5854, + 0x5c5a, 0x623c, 0x7c6d, 0x6c60, 0x527e, 0x6947, 0x662a, 0x6270, + 0x7a3b, 0x752e, 0x7b2a, 0x6c7b, 0x6c3f, 0x7c58, 0x5465, 0x7943, + 0x6e62, 0x5769, 0x6d76, 0x5e6d, 0x4c6c, 0x636e, 0x6854, 0x7a78, + 0x5d34, 0x6435, 0x5830, 0x5855, 0x746a, 0x4e39, 0x5661, 0x4f52, + 0x5036, 0x4e22, 0x736e, 0x7378, 0x5c4c, 0x504b, 0x7c24, 0x4d4a, + 0x5754, 0x5e23, 0x6460, 0x6e49, 0x625d, 0x757e, 0x542c, 0x5551, + 0x5870, 0x7843, 0x6a57, 0x7557, 0x583f, 0x7d40, 0x6b2d, 0x552a, + 0x6728, 0x6e4a, 0x4a67, 0x7863, 0x545d, 0x6a58, 0x7b59, 0x6d77, + 0x6535, 0x502d, 0x7171, 0x623d, 0x6348, 0x5955, 0x5f2a, 0x5b3c, + 0x7864, 0x717a, 0x6536, 0x736f, 0x7b5a, 0x6160, 0x592c, 0x756b, + 0x6036, 0x6948, 0x4b4f, 0x6349, 0x5e6e, 0x623e, 0x5c6f, 0x5625, + 0x6271, 0x567e, 0x5921, 0x5840, 0x5c5b, 0x6d3d, 0x5f38, 0x6a25, + 0x572d, 0x7379, 0x6d78, 0x7547, 0x614a, 0x6b63, 0x725e, 0x784c, + 0x6a59, 0x5346, 0x5b66, 0x752f, 0x4e70, 0x697e, 0x7b36, 0x6272, + 0x4f72, 0x7739, 0x5973, 0x614b, 0x5a5d, 0x5a39, 0x6b7b, 0x4b39, + 0x6d79, 0x6060, 0x7440, 0x7d3c, 0x5f31, 0x636f, 0x6023, 0x7d39, + 0x7031, 0x4d4b, 0x6d3e, 0x5540, 0x6370, 0x6d7a, 0x6964, 0x556d, + 0x675d, 0x5476, 0x6537, 0x5b67, 0x623f, 0x6e4b, 0x5774, 0x705d, + 0x4e2b, 0x675e, 0x5656, 0x614c, 0x6833, 0x656e, 0x5c22, 0x6050, + 0x5535, 0x5521, 0x7b5b, 0x794b, 0x4b73, 0x7425, 0x7a48, 0x5657, + 0x6965, 0x7b5c, 0x7d50, 0x7b76, 0x5a25, 0x5b3d, 0x6c62, 0x4d77, + 0x705e, 0x7649, 0x5e6f, 0x5331, 0x7c6e, 0x6843, 0x7148, 0x4e71, + 0x796d, 0x7274, 0x6436, 0x7539, 0x5c70, 0x6371, 0x6825, 0x723b, + 0x5e24, 0x5a4c, 0x4a69, 0x635a, 0x7c59, 0x6a5a, 0x7944, 0x6324, + 0x7b5d, 0x6f4a, 0x6844, 0x554c, 0x6b57, 0x592d, 0x7b2b, 0x5359, + 0x5522, 0x765e, 0x5a76, 0x6051, 0x6928, 0x7579, 0x7a2f, 0x6b7c, + 0x606a, 0x6332, 0x5545, 0x7163, 0x556e, 0x4d4c, 0x6d59, 0x5841, + 0x7a6c, 0x716b, 0x7a3c, 0x6662, 0x7a65, 0x627a, 0x4a36, 0x6437, + 0x6a5b, 0x757a, 0x7b2c, 0x4f43, 0x6b7d, 0x787a, 0x5f39, 0x6171, + 0x5224, 0x757b, 0x505a, 0x505b, 0x6a3e, 0x5931, 0x4a37, 0x5367, + 0x7865, 0x5332, 0x6240, 0x725f, 0x4d65, 0x792c, 0x4d4d, 0x6e2e, + 0x562e, 0x576a, 0x6760, 0x6b2e, 0x4f59, 0x5c4d, 0x6d7b, 0x5e70, + 0x576b, 0x5e25, 0x5f57, 0x5b50, 0x5b51, 0x5523, 0x7032, 0x5c5c, + 0x4a68, 0x7866, 0x5c4e, 0x6a5c, 0x5b52, 0x6933, 0x775b, 0x6328, + 0x572e, 0x6061, 0x4b3a, 0x6551, 0x505c, 0x5541, 0x584a, 0x6329, + 0x6024, 0x6929, 0x5347, 0x5c5d, 0x782e, 0x4c38, 0x502e, 0x5872, + 0x634a, 0x4c2f, 0x542d, 0x7651, 0x504c, 0x4a46, 0x5542, 0x4e3a, + 0x4a47, 0x7a30, 0x5f58, 0x753a, 0x656b, 0x6f74, 0x5d35, 0x4d2a, + 0x6372, 0x7b77, 0x7750, 0x7d3a, 0x7d61, 0x767e, 0x5140, 0x6845, + 0x6438, 0x6168, 0x4c41, 0x526d, 0x5b3e, 0x6062, 0x7a49, 0x614d, + 0x4a38, 0x7260, 0x7149, 0x5e71, 0x705f, 0x7844, 0x6e4c, 0x5e72, + 0x6749, 0x6273, 0x6761, 0x634b, 0x634c, 0x4f78, 0x6f2c, 0x7d7e, + 0x7c25, 0x7a31, 0x5f59, 0x6052, 0x745a, 0x714a, 0x4e23, 0x723c, + 0x6c63, 0x6025, 0x772b, 0x6b2f, 0x655e, 0x6124, 0x4d2b, 0x5974, + 0x6826, 0x4d4e, 0x6169, 0x7c6f, 0x6063, 0x6241, 0x4e24, 0x5e26, + 0x6b7e, 0x6b5d, 0x7060, 0x745b, 0x6274, 0x5348, 0x746b, 0x6e35, + 0x7558, 0x555f, 0x5665, 0x6b30, 0x7463, 0x634d, 0x7474, 0x7a32, + 0x6f75, 0x4a5f, 0x6b31, 0x6d3f, 0x7d49, 0x6426, 0x7924, 0x7033, + 0x656c, 0x5167, 0x5947, 0x6457, 0x6a5d, 0x5477, 0x5a3a, 0x5a4d, + 0x794c, 0x615a, 0x5b3f, 0x4c45, 0x6c50, 0x4b3b, 0x5e73, 0x692a, + 0x5948, 0x6e63, 0x573d, 0x4f44, 0x504d, 0x7c26, 0x717b, 0x7d52, + 0x5141, 0x635b, 0x5349, 0x5c4f, 0x4c6d, 0x5e27, 0x663b, 0x6c21, + 0x4c39, 0x7b5e, 0x6762, 0x5441, 0x5c28, 0x6242, 0x7358, 0x6553, + 0x7359, 0x7346, 0x4d5b, 0x4d2c, 0x7c43, 0x5467, 0x5142, 0x7925, + 0x6855, 0x634e, 0x544a, 0x5f5a, 0x7b5f, 0x6763, 0x787b, 0x634f, + 0x7530, 0x5867, 0x5949, 0x782f, 0x6f76, 0x5d36, 0x6e2f, 0x4d78, + 0x5e38, 0x7c27, 0x777c, 0x7731, 0x4e3b, 0x7421, 0x6e4d, 0x612e, + 0x6c43, 0x4f7e, 0x783f, 0x5862, 0x5368, 0x5e28, 0x7464, 0x6c42, + 0x5975, 0x7945, 0x5d53, 0x5671, 0x6c7c, 0x7c70, 0x6d40, 0x4a39, + 0x6e64, 0x7261, 0x5e39, 0x5672, 0x5e74, 0x5f5b, 0x5b53, 0x7a67, + 0x5863, 0x7441, 0x5d37, 0x7275, 0x542e, 0x5673, 0x5d38, 0x4f45, + 0x5f5f, 0x723e, 0x7621, 0x6b4b, 0x717c, 0x7347, 0x606b, 0x6d7c, + 0x615b, 0x6e65, 0x5e75, 0x7a53, 0x714b, 0x502f, 0x5d39, 0x5143, + 0x7531, 0x6a46, 0x7061, 0x762c, 0x7559, 0x706b, 0x5d3a, 0x723f, + 0x7745, 0x5b22, 0x7276, 0x4a3a, 0x7775, 0x4b65, 0x6e66, 0x6053, + 0x4e25, 0x5658, 0x542f, 0x6949, 0x534e, 0x7442, 0x4b66, 0x7121, + 0x6b32, 0x7122, 0x6b33, 0x7034, 0x4b74, 0x5430, 0x7332, 0x7b37, + 0x756c, 0x6e67, 0x7432, 0x756d, 0x4f73, 0x7062, 0x6e4e, 0x714c, + 0x6538, 0x5775, 0x6373, 0x4f65, 0x4f46, 0x7333, 0x6458, 0x4f79, + 0x4f5a, 0x7a4d, 0x6663, 0x7262, 0x756e, 0x4a3b, 0x635c, 0x4e72, + 0x5659, 0x6e30, 0x7465, 0x5842, 0x5c50, 0x4c6e, 0x5560, 0x764a, + 0x7d4a, 0x5856, 0x744f, 0x5626, 0x5c3e, 0x5b54, 0x5747, 0x727e, + 0x714d, 0x6243, 0x5c5e, 0x5c5f, 0x6f2d, 0x662b, 0x795d, 0x6a3f, + 0x6f2e, 0x7450, 0x4e73, 0x662c, 0x4e5e, 0x5579, 0x6374, 0x4d50, + 0x5538, 0x777d, 0x5c29, 0x5e76, 0x5c2a, 0x7263, 0x6934, 0x525c, + 0x6966, 0x6376, 0x674a, 0x504e, 0x5a77, 0x4a3c, 0x6e68, 0x5a5e, + 0x7277, 0x627b, 0x4c26, 0x5a3b, 0x6e69, 0x755a, 0x775c, 0x616a, + 0x4e41, 0x5431, 0x7d31, 0x663d, 0x7b2d, 0x7867, 0x614e, 0x7762, + 0x756f, 0x4f47, 0x5432, 0x4c6f, 0x5468, 0x6e4f, 0x7757, 0x6026, + 0x5641, 0x615c, 0x7063, 0x7164, 0x5c71, 0x5627, 0x7475, 0x714e, + 0x7264, 0x5030, 0x6c6f, 0x793a, 0x6b35, 0x546d, 0x6244, 0x6967, + 0x6b34, 0x6a21, 0x783c, 0x4e26, 0x7946, 0x7c5a, 0x5433, 0x5339, + 0x6a5e, 0x692b, 0x6161, 0x534f, 0x7476, 0x6a40, 0x614f, 0x4c3a, + 0x6e6a, 0x7064, 0x7334, 0x546e, 0x7240, 0x7165, 0x7443, 0x6054, + 0x6b36, 0x5721, 0x4b68, 0x792d, 0x692d, 0x5864, 0x7a33, 0x6245, + 0x7c3d, 0x6c44, 0x5831, 0x5c2b, 0x5524, 0x6b69, 0x683b, 0x5857, + 0x7b2e, 0x5161, 0x5b40, 0x753e, 0x5e77, 0x4a7b, 0x7746, 0x4f48, + 0x6150, 0x6e50, 0x6974, 0x4e74, 0x554d, 0x4f5b, 0x5d3b, 0x4e2c, + 0x6968, 0x5434, 0x6447, 0x755b, 0x7a41, 0x5e29, 0x5478, 0x6f77, + 0x5333, 0x6b37, 0x6f78, 0x755c, 0x6d4c, 0x5b55, 0x714f, 0x7150, + 0x7532, 0x592e, 0x552c, 0x6246, 0x7d23, 0x7b65, 0x5f2b, 0x6275, + 0x762d, 0x7533, 0x7035, 0x6125, 0x755d, 0x6c22, 0x6d7d, 0x7534, + 0x7b38, 0x5b23, 0x564a, 0x4b59, 0x6554, 0x737a, 0x6b38, 0x6037, + 0x576c, 0x716c, 0x652f, 0x5561, 0x576d, 0x5151, 0x6172, 0x6f79, + 0x5d3c, 0x765c, 0x7065, 0x7444, 0x6969, 0x737b, 0x546f, 0x4c22, + 0x777e, 0x5f3c, 0x6b4d, 0x5037, 0x5642, 0x682d, 0x6f2f, 0x4b25, + 0x4b69, 0x7a68, 0x4c46, 0x6667, 0x6a47, 0x5b24, 0x4f49, 0x627c, + 0x6f7a, 0x6b5e, 0x7548, 0x545e, 0x6055, 0x6f30, 0x6247, 0x592f, + 0x7967, 0x6765, 0x4f4a, 0x6151, 0x6248, 0x6f7b, 0x7a79, 0x5c72, + 0x6027, 0x7868, 0x4b6a, 0x4b3c, 0x5662, 0x755e, 0x755f, 0x6e36, + 0x6276, 0x534a, 0x6f7c, 0x5144, 0x6f31, 0x5145, 0x505e, 0x5961, + 0x6038, 0x4d51, 0x7339, 0x674c, 0x5628, 0x4e27, 0x5435, 0x6448, + 0x5334, 0x6b39, 0x4b75, 0x765d, 0x7123, 0x4c47, 0x694a, 0x6170, + 0x7560, 0x7b2f, 0x4b51, 0x7b60, 0x7265, 0x6c70, 0x706c, 0x6e6b, + 0x694b, 0x4c70, 0x572f, 0x7321, 0x7c75, 0x7124, 0x6056, 0x6f32, + 0x7451, 0x7721, 0x7151, 0x4a7c, 0x4a7d, 0x4e4e, 0x7348, 0x733a, + 0x6d7e, 0x5a26, 0x606c, 0x784d, 0x4b52, 0x6b4e, 0x7958, 0x7959, + 0x4a60, 0x5a4a, 0x4b26, 0x4a48, 0x796e, 0x5b6c, 0x5031, 0x556f, + 0x6673, 0x6722, 0x6459, 0x6461, 0x7c44, 0x796f, 0x4f74, 0x7766, + 0x4e3c, 0x7445, 0x5c23, 0x5d3d, 0x7446, 0x7821, 0x6856, 0x5b41, + 0x7066, 0x6439, 0x766d, 0x792e, 0x5d3e, 0x5730, 0x5868, 0x4b3d, + 0x795a, 0x784e, 0x7970, 0x606d, 0x6333, 0x7433, 0x6a42, 0x7266, + 0x7036, 0x5b56, 0x6b64, 0x7267, 0x5755, 0x5436, 0x7968, 0x5741, + 0x6555, 0x696a, 0x574c, 0x5369, 0x6249, 0x7c5b, 0x4d2d, 0x4c30, + 0x6a22, 0x6476, 0x5040, 0x7037, 0x6e21, 0x5776, 0x624a, 0x624b, + 0x7a4f, 0x6b5f, 0x564b, 0x7434, 0x6d4d, 0x6452, 0x6a29, 0x643a, + 0x7322, 0x4d52, 0x764b, 0x7166, 0x6d41, 0x683c, 0x6e51, 0x7067, + 0x624c, 0x642a, 0x7561, 0x6d5a, 0x576e, 0x5171, 0x696b, 0x696c, + 0x6064, 0x5a27, 0x5d54, 0x6a23, 0x5643, 0x5674, 0x5a5f, 0x6f33, + 0x624d, 0x6f7d, 0x7268, 0x6f45, 0x6767, 0x577d, 0x674e, 0x5f5c, + 0x7947, 0x5976, 0x5f2c, 0x565a, 0x5c24, 0x7038, 0x557a, 0x6477, + 0x5644, 0x746c, 0x6f7e, 0x7021, 0x5e2a, 0x5a3c, 0x587c, 0x7a54, + 0x6c65, 0x7c28, 0x6c66, 0x584b, 0x7b39, 0x6453, 0x4d79, 0x4f53, + 0x4a6a, 0x4f54, 0x783d, 0x7447, 0x6a5f, 0x795b, 0x5437, 0x6b65, + 0x6152, 0x6a24, 0x7a42, 0x7b61, 0x7a6d, 0x7022, 0x4c71, 0x7a23, + 0x6277, 0x624e, 0x6975, 0x616b, 0x6768, 0x6857, 0x5a78, 0x544b, + 0x7776, 0x5645, 0x5469, 0x7a7a, 0x4c72, 0x775d, 0x5e3a, 0x4e28, + 0x7039, 0x647e, 0x6449, 0x6454, 0x6a43, 0x6f34, 0x573e, 0x7b62, + 0x4d53, 0x6f35, 0x7a69, 0x7926, 0x5f3d, 0x7747, 0x787d, 0x787c, + 0x5e2b, 0x5b68, 0x635d, 0x6162, 0x5146, 0x7650, 0x6b66, 0x5a79, + 0x6c47, 0x5e78, 0x7869, 0x635e, 0x4e75, 0x7a43, 0x6557, 0x6c48, + 0x7349, 0x643b, 0x662e, 0x6f36, 0x5c3f, 0x4e3d, 0x5843, 0x504f, + 0x4f7a, 0x734a, 0x6057, 0x5147, 0x692e, 0x683d, 0x7a44, 0x624f, + 0x7a45, 0x7938, 0x5c60, 0x7b30, 0x5829, 0x655f, 0x7927, 0x766e, + 0x764c, 0x6278, 0x6c71, 0x5a60, 0x7152, 0x524c, 0x4f4b, 0x4a3d, + 0x5d3f, 0x766f, 0x5e79, 0x7a34, 0x552d, 0x7167, 0x5e3e, 0x5c40, + 0x5148, 0x5149, 0x783e, 0x4b76, 0x5479, 0x7562, 0x6153, 0x5869, + 0x787e, 0x4f4c, 0x7d24, 0x4e76, 0x7a50, 0x4c73, 0x663e, 0x762e, + 0x5570, 0x514a, 0x7c3e, 0x5571, 0x4d69, 0x7a35, 0x6250, 0x7477, + 0x4d54, 0x6723, 0x5b25, 0x6251, 0x5722, 0x7763, 0x6a26, 0x5021, + 0x4e5a, 0x7b6b, 0x5b26, 0x5b5e, 0x5865, 0x6a60, 0x582a, 0x6560, + 0x565b, 0x6f46, 0x786a, 0x6455, 0x4e77, 0x6058, 0x576f, 0x746d, + 0x4d66, 0x4c74, 0x7563, 0x644a, 0x5c61, 0x7948, 0x7c3f, 0x6827, + 0x5844, 0x4b3e, 0x5c2e, 0x5777, 0x7068, 0x5d40, 0x4f4d, 0x5c73, + 0x5930, 0x6669, 0x643c, 0x6a44, 0x646c, 0x6465, 0x7b78, 0x4c3b, + 0x643d, 0x4d5c, 0x5977, 0x5d5f, 0x6d4e, 0x5950, 0x6523, 0x794d, + 0x4d2e, 0x4f4e, 0x762f, 0x7d53, 0x6b6d, 0x565c, 0x6524, 0x5536, + 0x565d, 0x7969, 0x6724, 0x5663, 0x514b, 0x5664, 0x5572, 0x5e7a, + 0x5778, 0x586a, 0x4f55, 0x587d, 0x582b, 0x7d4b, 0x7c5c, 0x6028, + 0x5573, 0x7d59, 0x4c23, 0x5979, 0x536a, 0x7575, 0x6f47, 0x535a, + 0x5a3d, 0x6828, 0x5c2f, 0x7023, 0x4d55, 0x6029, 0x5e2c, 0x703a, + 0x6e31, 0x6e32, 0x764d, 0x6e52, 0x5646, 0x6065, 0x733b, 0x6561, + 0x644b, 0x5723, 0x5b42, 0x4a7e, 0x4f4f, 0x3021, 0x3022, 0x3023, + 0x3024, 0x3025, 0x3026, 0x3027, 0x3028, 0x3029, 0x302a, 0x302b, + 0x302c, 0x302d, 0x302e, 0x302f, 0x3030, 0x3031, 0x3032, 0x3033, + 0x3034, 0x3035, 0x3036, 0x3037, 0x3038, 0x3039, 0x303a, 0x303b, + 0x303c, 0x303d, 0x303e, 0x303f, 0x3040, 0x3041, 0x3042, 0x3043, + 0x3044, 0x3045, 0x3046, 0x3047, 0x3048, 0x3049, 0x304a, 0x304b, + 0x304c, 0x304d, 0x304e, 0x304f, 0x3050, 0x3051, 0x3052, 0x3053, + 0x3054, 0x3055, 0x3056, 0x3057, 0x3058, 0x3059, 0x305a, 0x305b, + 0x305c, 0x305d, 0x305e, 0x305f, 0x3060, 0x3061, 0x3062, 0x3063, + 0x3064, 0x3065, 0x3066, 0x3067, 0x3068, 0x3069, 0x306a, 0x306b, + 0x306c, 0x306d, 0x306e, 0x306f, 0x3070, 0x3071, 0x3072, 0x3073, + 0x3074, 0x3075, 0x3076, 0x3077, 0x3078, 0x3079, 0x307a, 0x307b, + 0x307c, 0x307d, 0x307e, 0x3121, 0x3122, 0x3123, 0x3124, 0x3125, + 0x3126, 0x3127, 0x3128, 0x3129, 0x312a, 0x312b, 0x312c, 0x312d, + 0x312e, 0x312f, 0x3130, 0x3131, 0x3132, 0x3133, 0x3134, 0x3135, + 0x3136, 0x3137, 0x3138, 0x3139, 0x313a, 0x313b, 0x313c, 0x313d, + 0x313e, 0x313f, 0x3140, 0x3141, 0x3142, 0x3143, 0x3144, 0x3145, + 0x3146, 0x3147, 0x3148, 0x3149, 0x314a, 0x314b, 0x314c, 0x314d, + 0x314e, 0x314f, 0x3150, 0x3151, 0x3152, 0x3153, 0x3154, 0x3155, + 0x3156, 0x3157, 0x3158, 0x3159, 0x315a, 0x315b, 0x315c, 0x315d, + 0x315e, 0x315f, 0x3160, 0x3161, 0x3162, 0x3163, 0x3164, 0x3165, + 0x3166, 0x3167, 0x3168, 0x3169, 0x316a, 0x316b, 0x316c, 0x316d, + 0x316e, 0x316f, 0x3170, 0x3171, 0x3172, 0x3173, 0x3174, 0x3175, + 0x3176, 0x3177, 0x3178, 0x3179, 0x317a, 0x317b, 0x317c, 0x317d, + 0x317e, 0x3221, 0x3222, 0x3223, 0x3224, 0x3225, 0x3226, 0x3227, + 0x3228, 0x3229, 0x322a, 0x322b, 0x322c, 0x322d, 0x322e, 0x322f, + 0x3230, 0x3231, 0x3232, 0x3233, 0x3234, 0x3235, 0x3236, 0x3237, + 0x3238, 0x3239, 0x323a, 0x323b, 0x323c, 0x323d, 0x323e, 0x323f, + 0x3240, 0x3241, 0x3242, 0x3243, 0x3244, 0x3245, 0x3246, 0x3247, + 0x3248, 0x3249, 0x324a, 0x324b, 0x324c, 0x324d, 0x324e, 0x324f, + 0x3250, 0x3251, 0x3252, 0x3253, 0x3254, 0x3255, 0x3256, 0x3257, + 0x3258, 0x3259, 0x325a, 0x325b, 0x325c, 0x325d, 0x325e, 0x325f, + 0x3260, 0x3261, 0x3262, 0x3263, 0x3264, 0x3265, 0x3266, 0x3267, + 0x3268, 0x3269, 0x326a, 0x326b, 0x326c, 0x326d, 0x326e, 0x326f, + 0x3270, 0x3271, 0x3272, 0x3273, 0x3274, 0x3275, 0x3276, 0x3277, + 0x3278, 0x3279, 0x327a, 0x327b, 0x327c, 0x327d, 0x327e, 0x3321, + 0x3322, 0x3323, 0x3324, 0x3325, 0x3326, 0x3327, 0x3328, 0x3329, + 0x332a, 0x332b, 0x332c, 0x332d, 0x332e, 0x332f, 0x3330, 0x3331, + 0x3332, 0x3333, 0x3334, 0x3335, 0x3336, 0x3337, 0x3338, 0x3339, + 0x333a, 0x333b, 0x333c, 0x333d, 0x333e, 0x333f, 0x3340, 0x3341, + 0x3342, 0x3343, 0x3344, 0x3345, 0x3346, 0x3347, 0x3348, 0x3349, + 0x334a, 0x334b, 0x334c, 0x334d, 0x334e, 0x334f, 0x3350, 0x3351, + 0x3352, 0x3353, 0x3354, 0x3355, 0x3356, 0x3357, 0x3358, 0x3359, + 0x335a, 0x335b, 0x335c, 0x335d, 0x335e, 0x335f, 0x3360, 0x3361, + 0x3362, 0x3363, 0x3364, 0x3365, 0x3366, 0x3367, 0x3368, 0x3369, + 0x336a, 0x336b, 0x336c, 0x336d, 0x336e, 0x336f, 0x3370, 0x3371, + 0x3372, 0x3373, 0x3374, 0x3375, 0x3376, 0x3377, 0x3378, 0x3379, + 0x337a, 0x337b, 0x337c, 0x337d, 0x337e, 0x3421, 0x3422, 0x3423, + 0x3424, 0x3425, 0x3426, 0x3427, 0x3428, 0x3429, 0x342a, 0x342b, + 0x342c, 0x342d, 0x342e, 0x342f, 0x3430, 0x3431, 0x3432, 0x3433, + 0x3434, 0x3435, 0x3436, 0x3437, 0x3438, 0x3439, 0x343a, 0x343b, + 0x343c, 0x343d, 0x343e, 0x343f, 0x3440, 0x3441, 0x3442, 0x3443, + 0x3444, 0x3445, 0x3446, 0x3447, 0x3448, 0x3449, 0x344a, 0x344b, + 0x344c, 0x344d, 0x344e, 0x344f, 0x3450, 0x3451, 0x3452, 0x3453, + 0x3454, 0x3455, 0x3456, 0x3457, 0x3458, 0x3459, 0x345a, 0x345b, + 0x345c, 0x345d, 0x345e, 0x345f, 0x3460, 0x3461, 0x3462, 0x3463, + 0x3464, 0x3465, 0x3466, 0x3467, 0x3468, 0x3469, 0x346a, 0x346b, + 0x346c, 0x346d, 0x346e, 0x346f, 0x3470, 0x3471, 0x3472, 0x3473, + 0x3474, 0x3475, 0x3476, 0x3477, 0x3478, 0x3479, 0x347a, 0x347b, + 0x347c, 0x347d, 0x347e, 0x3521, 0x3522, 0x3523, 0x3524, 0x3525, + 0x3526, 0x3527, 0x3528, 0x3529, 0x352a, 0x352b, 0x352c, 0x352d, + 0x352e, 0x352f, 0x3530, 0x3531, 0x3532, 0x3533, 0x3534, 0x3535, + 0x3536, 0x3537, 0x3538, 0x3539, 0x353a, 0x353b, 0x353c, 0x353d, + 0x353e, 0x353f, 0x3540, 0x3541, 0x3542, 0x3543, 0x3544, 0x3545, + 0x3546, 0x3547, 0x3548, 0x3549, 0x354a, 0x354b, 0x354c, 0x354d, + 0x354e, 0x354f, 0x3550, 0x3551, 0x3552, 0x3553, 0x3554, 0x3555, + 0x3556, 0x3557, 0x3558, 0x3559, 0x355a, 0x355b, 0x355c, 0x355d, + 0x355e, 0x355f, 0x3560, 0x3561, 0x3562, 0x3563, 0x3564, 0x3565, + 0x3566, 0x3567, 0x3568, 0x3569, 0x356a, 0x356b, 0x356c, 0x356d, + 0x356e, 0x356f, 0x3570, 0x3571, 0x3572, 0x3573, 0x3574, 0x3575, + 0x3576, 0x3577, 0x3578, 0x3579, 0x357a, 0x357b, 0x357c, 0x357d, + 0x357e, 0x3621, 0x3622, 0x3623, 0x3624, 0x3625, 0x3626, 0x3627, + 0x3628, 0x3629, 0x362a, 0x362b, 0x362c, 0x362d, 0x362e, 0x362f, + 0x3630, 0x3631, 0x3632, 0x3633, 0x3634, 0x3635, 0x3636, 0x3637, + 0x3638, 0x3639, 0x363a, 0x363b, 0x363c, 0x363d, 0x363e, 0x363f, + 0x3640, 0x3641, 0x3642, 0x3643, 0x3644, 0x3645, 0x3646, 0x3647, + 0x3648, 0x3649, 0x364a, 0x364b, 0x364c, 0x364d, 0x364e, 0x364f, + 0x3650, 0x3651, 0x3652, 0x3653, 0x3654, 0x3655, 0x3656, 0x3657, + 0x3658, 0x3659, 0x365a, 0x365b, 0x365c, 0x365d, 0x365e, 0x365f, + 0x3660, 0x3661, 0x3662, 0x3663, 0x3664, 0x3665, 0x3666, 0x3667, + 0x3668, 0x3669, 0x366a, 0x366b, 0x366c, 0x366d, 0x366e, 0x366f, + 0x3670, 0x3671, 0x3672, 0x3673, 0x3674, 0x3675, 0x3676, 0x3677, + 0x3678, 0x3679, 0x367a, 0x367b, 0x367c, 0x367d, 0x367e, 0x3721, + 0x3722, 0x3723, 0x3724, 0x3725, 0x3726, 0x3727, 0x3728, 0x3729, + 0x372a, 0x372b, 0x372c, 0x372d, 0x372e, 0x372f, 0x3730, 0x3731, + 0x3732, 0x3733, 0x3734, 0x3735, 0x3736, 0x3737, 0x3738, 0x3739, + 0x373a, 0x373b, 0x373c, 0x373d, 0x373e, 0x373f, 0x3740, 0x3741, + 0x3742, 0x3743, 0x3744, 0x3745, 0x3746, 0x3747, 0x3748, 0x3749, + 0x374a, 0x374b, 0x374c, 0x374d, 0x374e, 0x374f, 0x3750, 0x3751, + 0x3752, 0x3753, 0x3754, 0x3755, 0x3756, 0x3757, 0x3758, 0x3759, + 0x375a, 0x375b, 0x375c, 0x375d, 0x375e, 0x375f, 0x3760, 0x3761, + 0x3762, 0x3763, 0x3764, 0x3765, 0x3766, 0x3767, 0x3768, 0x3769, + 0x376a, 0x376b, 0x376c, 0x376d, 0x376e, 0x376f, 0x3770, 0x3771, + 0x3772, 0x3773, 0x3774, 0x3775, 0x3776, 0x3777, 0x3778, 0x3779, + 0x377a, 0x377b, 0x377c, 0x377d, 0x377e, 0x3821, 0x3822, 0x3823, + 0x3824, 0x3825, 0x3826, 0x3827, 0x3828, 0x3829, 0x382a, 0x382b, + 0x382c, 0x382d, 0x382e, 0x382f, 0x3830, 0x3831, 0x3832, 0x3833, + 0x3834, 0x3835, 0x3836, 0x3837, 0x3838, 0x3839, 0x383a, 0x383b, + 0x383c, 0x383d, 0x383e, 0x383f, 0x3840, 0x3841, 0x3842, 0x3843, + 0x3844, 0x3845, 0x3846, 0x3847, 0x3848, 0x3849, 0x384a, 0x384b, + 0x384c, 0x384d, 0x384e, 0x384f, 0x3850, 0x3851, 0x3852, 0x3853, + 0x3854, 0x3855, 0x3856, 0x3857, 0x3858, 0x3859, 0x385a, 0x385b, + 0x385c, 0x385d, 0x385e, 0x385f, 0x3860, 0x3861, 0x3862, 0x3863, + 0x3864, 0x3865, 0x3866, 0x3867, 0x3868, 0x3869, 0x386a, 0x386b, + 0x386c, 0x386d, 0x386e, 0x386f, 0x3870, 0x3871, 0x3872, 0x3873, + 0x3874, 0x3875, 0x3876, 0x3877, 0x3878, 0x3879, 0x387a, 0x387b, + 0x387c, 0x387d, 0x387e, 0x3921, 0x3922, 0x3923, 0x3924, 0x3925, + 0x3926, 0x3927, 0x3928, 0x3929, 0x392a, 0x392b, 0x392c, 0x392d, + 0x392e, 0x392f, 0x3930, 0x3931, 0x3932, 0x3933, 0x3934, 0x3935, + 0x3936, 0x3937, 0x3938, 0x3939, 0x393a, 0x393b, 0x393c, 0x393d, + 0x393e, 0x393f, 0x3940, 0x3941, 0x3942, 0x3943, 0x3944, 0x3945, + 0x3946, 0x3947, 0x3948, 0x3949, 0x394a, 0x394b, 0x394c, 0x394d, + 0x394e, 0x394f, 0x3950, 0x3951, 0x3952, 0x3953, 0x3954, 0x3955, + 0x3956, 0x3957, 0x3958, 0x3959, 0x395a, 0x395b, 0x395c, 0x395d, + 0x395e, 0x395f, 0x3960, 0x3961, 0x3962, 0x3963, 0x3964, 0x3965, + 0x3966, 0x3967, 0x3968, 0x3969, 0x396a, 0x396b, 0x396c, 0x396d, + 0x396e, 0x396f, 0x3970, 0x3971, 0x3972, 0x3973, 0x3974, 0x3975, + 0x3976, 0x3977, 0x3978, 0x3979, 0x397a, 0x397b, 0x397c, 0x397d, + 0x397e, 0x3a21, 0x3a22, 0x3a23, 0x3a24, 0x3a25, 0x3a26, 0x3a27, + 0x3a28, 0x3a29, 0x3a2a, 0x3a2b, 0x3a2c, 0x3a2d, 0x3a2e, 0x3a2f, + 0x3a30, 0x3a31, 0x3a32, 0x3a33, 0x3a34, 0x3a35, 0x3a36, 0x3a37, + 0x3a38, 0x3a39, 0x3a3a, 0x3a3b, 0x3a3c, 0x3a3d, 0x3a3e, 0x3a3f, + 0x3a40, 0x3a41, 0x3a42, 0x3a43, 0x3a44, 0x3a45, 0x3a46, 0x3a47, + 0x3a48, 0x3a49, 0x3a4a, 0x3a4b, 0x3a4c, 0x3a4d, 0x3a4e, 0x3a4f, + 0x3a50, 0x3a51, 0x3a52, 0x3a53, 0x3a54, 0x3a55, 0x3a56, 0x3a57, + 0x3a58, 0x3a59, 0x3a5a, 0x3a5b, 0x3a5c, 0x3a5d, 0x3a5e, 0x3a5f, + 0x3a60, 0x3a61, 0x3a62, 0x3a63, 0x3a64, 0x3a65, 0x3a66, 0x3a67, + 0x3a68, 0x3a69, 0x3a6a, 0x3a6b, 0x3a6c, 0x3a6d, 0x3a6e, 0x3a6f, + 0x3a70, 0x3a71, 0x3a72, 0x3a73, 0x3a74, 0x3a75, 0x3a76, 0x3a77, + 0x3a78, 0x3a79, 0x3a7a, 0x3a7b, 0x3a7c, 0x3a7d, 0x3a7e, 0x3b21, + 0x3b22, 0x3b23, 0x3b24, 0x3b25, 0x3b26, 0x3b27, 0x3b28, 0x3b29, + 0x3b2a, 0x3b2b, 0x3b2c, 0x3b2d, 0x3b2e, 0x3b2f, 0x3b30, 0x3b31, + 0x3b32, 0x3b33, 0x3b34, 0x3b35, 0x3b36, 0x3b37, 0x3b38, 0x3b39, + 0x3b3a, 0x3b3b, 0x3b3c, 0x3b3d, 0x3b3e, 0x3b3f, 0x3b40, 0x3b41, + 0x3b42, 0x3b43, 0x3b44, 0x3b45, 0x3b46, 0x3b47, 0x3b48, 0x3b49, + 0x3b4a, 0x3b4b, 0x3b4c, 0x3b4d, 0x3b4e, 0x3b4f, 0x3b50, 0x3b51, + 0x3b52, 0x3b53, 0x3b54, 0x3b55, 0x3b56, 0x3b57, 0x3b58, 0x3b59, + 0x3b5a, 0x3b5b, 0x3b5c, 0x3b5d, 0x3b5e, 0x3b5f, 0x3b60, 0x3b61, + 0x3b62, 0x3b63, 0x3b64, 0x3b65, 0x3b66, 0x3b67, 0x3b68, 0x3b69, + 0x3b6a, 0x3b6b, 0x3b6c, 0x3b6d, 0x3b6e, 0x3b6f, 0x3b70, 0x3b71, + 0x3b72, 0x3b73, 0x3b74, 0x3b75, 0x3b76, 0x3b77, 0x3b78, 0x3b79, + 0x3b7a, 0x3b7b, 0x3b7c, 0x3b7d, 0x3b7e, 0x3c21, 0x3c22, 0x3c23, + 0x3c24, 0x3c25, 0x3c26, 0x3c27, 0x3c28, 0x3c29, 0x3c2a, 0x3c2b, + 0x3c2c, 0x3c2d, 0x3c2e, 0x3c2f, 0x3c30, 0x3c31, 0x3c32, 0x3c33, + 0x3c34, 0x3c35, 0x3c36, 0x3c37, 0x3c38, 0x3c39, 0x3c3a, 0x3c3b, + 0x3c3c, 0x3c3d, 0x3c3e, 0x3c3f, 0x3c40, 0x3c41, 0x3c42, 0x3c43, + 0x3c44, 0x3c45, 0x3c46, 0x3c47, 0x3c48, 0x3c49, 0x3c4a, 0x3c4b, + 0x3c4c, 0x3c4d, 0x3c4e, 0x3c4f, 0x3c50, 0x3c51, 0x3c52, 0x3c53, + 0x3c54, 0x3c55, 0x3c56, 0x3c57, 0x3c58, 0x3c59, 0x3c5a, 0x3c5b, + 0x3c5c, 0x3c5d, 0x3c5e, 0x3c5f, 0x3c60, 0x3c61, 0x3c62, 0x3c63, + 0x3c64, 0x3c65, 0x3c66, 0x3c67, 0x3c68, 0x3c69, 0x3c6a, 0x3c6b, + 0x3c6c, 0x3c6d, 0x3c6e, 0x3c6f, 0x3c70, 0x3c71, 0x3c72, 0x3c73, + 0x3c74, 0x3c75, 0x3c76, 0x3c77, 0x3c78, 0x3c79, 0x3c7a, 0x3c7b, + 0x3c7c, 0x3c7d, 0x3c7e, 0x3d21, 0x3d22, 0x3d23, 0x3d24, 0x3d25, + 0x3d26, 0x3d27, 0x3d28, 0x3d29, 0x3d2a, 0x3d2b, 0x3d2c, 0x3d2d, + 0x3d2e, 0x3d2f, 0x3d30, 0x3d31, 0x3d32, 0x3d33, 0x3d34, 0x3d35, + 0x3d36, 0x3d37, 0x3d38, 0x3d39, 0x3d3a, 0x3d3b, 0x3d3c, 0x3d3d, + 0x3d3e, 0x3d3f, 0x3d40, 0x3d41, 0x3d42, 0x3d43, 0x3d44, 0x3d45, + 0x3d46, 0x3d47, 0x3d48, 0x3d49, 0x3d4a, 0x3d4b, 0x3d4c, 0x3d4d, + 0x3d4e, 0x3d4f, 0x3d50, 0x3d51, 0x3d52, 0x3d53, 0x3d54, 0x3d55, + 0x3d56, 0x3d57, 0x3d58, 0x3d59, 0x3d5a, 0x3d5b, 0x3d5c, 0x3d5d, + 0x3d5e, 0x3d5f, 0x3d60, 0x3d61, 0x3d62, 0x3d63, 0x3d64, 0x3d65, + 0x3d66, 0x3d67, 0x3d68, 0x3d69, 0x3d6a, 0x3d6b, 0x3d6c, 0x3d6d, + 0x3d6e, 0x3d6f, 0x3d70, 0x3d71, 0x3d72, 0x3d73, 0x3d74, 0x3d75, + 0x3d76, 0x3d77, 0x3d78, 0x3d79, 0x3d7a, 0x3d7b, 0x3d7c, 0x3d7d, + 0x3d7e, 0x3e21, 0x3e22, 0x3e23, 0x3e24, 0x3e25, 0x3e26, 0x3e27, + 0x3e28, 0x3e29, 0x3e2a, 0x3e2b, 0x3e2c, 0x3e2d, 0x3e2e, 0x3e2f, + 0x3e30, 0x3e31, 0x3e32, 0x3e33, 0x3e34, 0x3e35, 0x3e36, 0x3e37, + 0x3e38, 0x3e39, 0x3e3a, 0x3e3b, 0x3e3c, 0x3e3d, 0x3e3e, 0x3e3f, + 0x3e40, 0x3e41, 0x3e42, 0x3e43, 0x3e44, 0x3e45, 0x3e46, 0x3e47, + 0x3e48, 0x3e49, 0x3e4a, 0x3e4b, 0x3e4c, 0x3e4d, 0x3e4e, 0x3e4f, + 0x3e50, 0x3e51, 0x3e52, 0x3e53, 0x3e54, 0x3e55, 0x3e56, 0x3e57, + 0x3e58, 0x3e59, 0x3e5a, 0x3e5b, 0x3e5c, 0x3e5d, 0x3e5e, 0x3e5f, + 0x3e60, 0x3e61, 0x3e62, 0x3e63, 0x3e64, 0x3e65, 0x3e66, 0x3e67, + 0x3e68, 0x3e69, 0x3e6a, 0x3e6b, 0x3e6c, 0x3e6d, 0x3e6e, 0x3e6f, + 0x3e70, 0x3e71, 0x3e72, 0x3e73, 0x3e74, 0x3e75, 0x3e76, 0x3e77, + 0x3e78, 0x3e79, 0x3e7a, 0x3e7b, 0x3e7c, 0x3e7d, 0x3e7e, 0x3f21, + 0x3f22, 0x3f23, 0x3f24, 0x3f25, 0x3f26, 0x3f27, 0x3f28, 0x3f29, + 0x3f2a, 0x3f2b, 0x3f2c, 0x3f2d, 0x3f2e, 0x3f2f, 0x3f30, 0x3f31, + 0x3f32, 0x3f33, 0x3f34, 0x3f35, 0x3f36, 0x3f37, 0x3f38, 0x3f39, + 0x3f3a, 0x3f3b, 0x3f3c, 0x3f3d, 0x3f3e, 0x3f3f, 0x3f40, 0x3f41, + 0x3f42, 0x3f43, 0x3f44, 0x3f45, 0x3f46, 0x3f47, 0x3f48, 0x3f49, + 0x3f4a, 0x3f4b, 0x3f4c, 0x3f4d, 0x3f4e, 0x3f4f, 0x3f50, 0x3f51, + 0x3f52, 0x3f53, 0x3f54, 0x3f55, 0x3f56, 0x3f57, 0x3f58, 0x3f59, + 0x3f5a, 0x3f5b, 0x3f5c, 0x3f5d, 0x3f5e, 0x3f5f, 0x3f60, 0x3f61, + 0x3f62, 0x3f63, 0x3f64, 0x3f65, 0x3f66, 0x3f67, 0x3f68, 0x3f69, + 0x3f6a, 0x3f6b, 0x3f6c, 0x3f6d, 0x3f6e, 0x3f6f, 0x3f70, 0x3f71, + 0x3f72, 0x3f73, 0x3f74, 0x3f75, 0x3f76, 0x3f77, 0x3f78, 0x3f79, + 0x3f7a, 0x3f7b, 0x3f7c, 0x3f7d, 0x3f7e, 0x4021, 0x4022, 0x4023, + 0x4024, 0x4025, 0x4026, 0x4027, 0x4028, 0x4029, 0x402a, 0x402b, + 0x402c, 0x402d, 0x402e, 0x402f, 0x4030, 0x4031, 0x4032, 0x4033, + 0x4034, 0x4035, 0x4036, 0x4037, 0x4038, 0x4039, 0x403a, 0x403b, + 0x403c, 0x403d, 0x403e, 0x403f, 0x4040, 0x4041, 0x4042, 0x4043, + 0x4044, 0x4045, 0x4046, 0x4047, 0x4048, 0x4049, 0x404a, 0x404b, + 0x404c, 0x404d, 0x404e, 0x404f, 0x4050, 0x4051, 0x4052, 0x4053, + 0x4054, 0x4055, 0x4056, 0x4057, 0x4058, 0x4059, 0x405a, 0x405b, + 0x405c, 0x405d, 0x405e, 0x405f, 0x4060, 0x4061, 0x4062, 0x4063, + 0x4064, 0x4065, 0x4066, 0x4067, 0x4068, 0x4069, 0x406a, 0x406b, + 0x406c, 0x406d, 0x406e, 0x406f, 0x4070, 0x4071, 0x4072, 0x4073, + 0x4074, 0x4075, 0x4076, 0x4077, 0x4078, 0x4079, 0x407a, 0x407b, + 0x407c, 0x407d, 0x407e, 0x4121, 0x4122, 0x4123, 0x4124, 0x4125, + 0x4126, 0x4127, 0x4128, 0x4129, 0x412a, 0x412b, 0x412c, 0x412d, + 0x412e, 0x412f, 0x4130, 0x4131, 0x4132, 0x4133, 0x4134, 0x4135, + 0x4136, 0x4137, 0x4138, 0x4139, 0x413a, 0x413b, 0x413c, 0x413d, + 0x413e, 0x413f, 0x4140, 0x4141, 0x4142, 0x4143, 0x4144, 0x4145, + 0x4146, 0x4147, 0x4148, 0x4149, 0x414a, 0x414b, 0x414c, 0x414d, + 0x414e, 0x414f, 0x4150, 0x4151, 0x4152, 0x4153, 0x4154, 0x4155, + 0x4156, 0x4157, 0x4158, 0x4159, 0x415a, 0x415b, 0x415c, 0x415d, + 0x415e, 0x415f, 0x4160, 0x4161, 0x4162, 0x4163, 0x4164, 0x4165, + 0x4166, 0x4167, 0x4168, 0x4169, 0x416a, 0x416b, 0x416c, 0x416d, + 0x416e, 0x416f, 0x4170, 0x4171, 0x4172, 0x4173, 0x4174, 0x4175, + 0x4176, 0x4177, 0x4178, 0x4179, 0x417a, 0x417b, 0x417c, 0x417d, + 0x417e, 0x4221, 0x4222, 0x4223, 0x4224, 0x4225, 0x4226, 0x4227, + 0x4228, 0x4229, 0x422a, 0x422b, 0x422c, 0x422d, 0x422e, 0x422f, + 0x4230, 0x4231, 0x4232, 0x4233, 0x4234, 0x4235, 0x4236, 0x4237, + 0x4238, 0x4239, 0x423a, 0x423b, 0x423c, 0x423d, 0x423e, 0x423f, + 0x4240, 0x4241, 0x4242, 0x4243, 0x4244, 0x4245, 0x4246, 0x4247, + 0x4248, 0x4249, 0x424a, 0x424b, 0x424c, 0x424d, 0x424e, 0x424f, + 0x4250, 0x4251, 0x4252, 0x4253, 0x4254, 0x4255, 0x4256, 0x4257, + 0x4258, 0x4259, 0x425a, 0x425b, 0x425c, 0x425d, 0x425e, 0x425f, + 0x4260, 0x4261, 0x4262, 0x4263, 0x4264, 0x4265, 0x4266, 0x4267, + 0x4268, 0x4269, 0x426a, 0x426b, 0x426c, 0x426d, 0x426e, 0x426f, + 0x4270, 0x4271, 0x4272, 0x4273, 0x4274, 0x4275, 0x4276, 0x4277, + 0x4278, 0x4279, 0x427a, 0x427b, 0x427c, 0x427d, 0x427e, 0x4321, + 0x4322, 0x4323, 0x4324, 0x4325, 0x4326, 0x4327, 0x4328, 0x4329, + 0x432a, 0x432b, 0x432c, 0x432d, 0x432e, 0x432f, 0x4330, 0x4331, + 0x4332, 0x4333, 0x4334, 0x4335, 0x4336, 0x4337, 0x4338, 0x4339, + 0x433a, 0x433b, 0x433c, 0x433d, 0x433e, 0x433f, 0x4340, 0x4341, + 0x4342, 0x4343, 0x4344, 0x4345, 0x4346, 0x4347, 0x4348, 0x4349, + 0x434a, 0x434b, 0x434c, 0x434d, 0x434e, 0x434f, 0x4350, 0x4351, + 0x4352, 0x4353, 0x4354, 0x4355, 0x4356, 0x4357, 0x4358, 0x4359, + 0x435a, 0x435b, 0x435c, 0x435d, 0x435e, 0x435f, 0x4360, 0x4361, + 0x4362, 0x4363, 0x4364, 0x4365, 0x4366, 0x4367, 0x4368, 0x4369, + 0x436a, 0x436b, 0x436c, 0x436d, 0x436e, 0x436f, 0x4370, 0x4371, + 0x4372, 0x4373, 0x4374, 0x4375, 0x4376, 0x4377, 0x4378, 0x4379, + 0x437a, 0x437b, 0x437c, 0x437d, 0x437e, 0x4421, 0x4422, 0x4423, + 0x4424, 0x4425, 0x4426, 0x4427, 0x4428, 0x4429, 0x442a, 0x442b, + 0x442c, 0x442d, 0x442e, 0x442f, 0x4430, 0x4431, 0x4432, 0x4433, + 0x4434, 0x4435, 0x4436, 0x4437, 0x4438, 0x4439, 0x443a, 0x443b, + 0x443c, 0x443d, 0x443e, 0x443f, 0x4440, 0x4441, 0x4442, 0x4443, + 0x4444, 0x4445, 0x4446, 0x4447, 0x4448, 0x4449, 0x444a, 0x444b, + 0x444c, 0x444d, 0x444e, 0x444f, 0x4450, 0x4451, 0x4452, 0x4453, + 0x4454, 0x4455, 0x4456, 0x4457, 0x4458, 0x4459, 0x445a, 0x445b, + 0x445c, 0x445d, 0x445e, 0x445f, 0x4460, 0x4461, 0x4462, 0x4463, + 0x4464, 0x4465, 0x4466, 0x4467, 0x4468, 0x4469, 0x446a, 0x446b, + 0x446c, 0x446d, 0x446e, 0x446f, 0x4470, 0x4471, 0x4472, 0x4473, + 0x4474, 0x4475, 0x4476, 0x4477, 0x4478, 0x4479, 0x447a, 0x447b, + 0x447c, 0x447d, 0x447e, 0x4521, 0x4522, 0x4523, 0x4524, 0x4525, + 0x4526, 0x4527, 0x4528, 0x4529, 0x452a, 0x452b, 0x452c, 0x452d, + 0x452e, 0x452f, 0x4530, 0x4531, 0x4532, 0x4533, 0x4534, 0x4535, + 0x4536, 0x4537, 0x4538, 0x4539, 0x453a, 0x453b, 0x453c, 0x453d, + 0x453e, 0x453f, 0x4540, 0x4541, 0x4542, 0x4543, 0x4544, 0x4545, + 0x4546, 0x4547, 0x4548, 0x4549, 0x454a, 0x454b, 0x454c, 0x454d, + 0x454e, 0x454f, 0x4550, 0x4551, 0x4552, 0x4553, 0x4554, 0x4555, + 0x4556, 0x4557, 0x4558, 0x4559, 0x455a, 0x455b, 0x455c, 0x455d, + 0x455e, 0x455f, 0x4560, 0x4561, 0x4562, 0x4563, 0x4564, 0x4565, + 0x4566, 0x4567, 0x4568, 0x4569, 0x456a, 0x456b, 0x456c, 0x456d, + 0x456e, 0x456f, 0x4570, 0x4571, 0x4572, 0x4573, 0x4574, 0x4575, + 0x4576, 0x4577, 0x4578, 0x4579, 0x457a, 0x457b, 0x457c, 0x457d, + 0x457e, 0x4621, 0x4622, 0x4623, 0x4624, 0x4625, 0x4626, 0x4627, + 0x4628, 0x4629, 0x462a, 0x462b, 0x462c, 0x462d, 0x462e, 0x462f, + 0x4630, 0x4631, 0x4632, 0x4633, 0x4634, 0x4635, 0x4636, 0x4637, + 0x4638, 0x4639, 0x463a, 0x463b, 0x463c, 0x463d, 0x463e, 0x463f, + 0x4640, 0x4641, 0x4642, 0x4643, 0x4644, 0x4645, 0x4646, 0x4647, + 0x4648, 0x4649, 0x464a, 0x464b, 0x464c, 0x464d, 0x464e, 0x464f, + 0x4650, 0x4651, 0x4652, 0x4653, 0x4654, 0x4655, 0x4656, 0x4657, + 0x4658, 0x4659, 0x465a, 0x465b, 0x465c, 0x465d, 0x465e, 0x465f, + 0x4660, 0x4661, 0x4662, 0x4663, 0x4664, 0x4665, 0x4666, 0x4667, + 0x4668, 0x4669, 0x466a, 0x466b, 0x466c, 0x466d, 0x466e, 0x466f, + 0x4670, 0x4671, 0x4672, 0x4673, 0x4674, 0x4675, 0x4676, 0x4677, + 0x4678, 0x4679, 0x467a, 0x467b, 0x467c, 0x467d, 0x467e, 0x4721, + 0x4722, 0x4723, 0x4724, 0x4725, 0x4726, 0x4727, 0x4728, 0x4729, + 0x472a, 0x472b, 0x472c, 0x472d, 0x472e, 0x472f, 0x4730, 0x4731, + 0x4732, 0x4733, 0x4734, 0x4735, 0x4736, 0x4737, 0x4738, 0x4739, + 0x473a, 0x473b, 0x473c, 0x473d, 0x473e, 0x473f, 0x4740, 0x4741, + 0x4742, 0x4743, 0x4744, 0x4745, 0x4746, 0x4747, 0x4748, 0x4749, + 0x474a, 0x474b, 0x474c, 0x474d, 0x474e, 0x474f, 0x4750, 0x4751, + 0x4752, 0x4753, 0x4754, 0x4755, 0x4756, 0x4757, 0x4758, 0x4759, + 0x475a, 0x475b, 0x475c, 0x475d, 0x475e, 0x475f, 0x4760, 0x4761, + 0x4762, 0x4763, 0x4764, 0x4765, 0x4766, 0x4767, 0x4768, 0x4769, + 0x476a, 0x476b, 0x476c, 0x476d, 0x476e, 0x476f, 0x4770, 0x4771, + 0x4772, 0x4773, 0x4774, 0x4775, 0x4776, 0x4777, 0x4778, 0x4779, + 0x477a, 0x477b, 0x477c, 0x477d, 0x477e, 0x4821, 0x4822, 0x4823, + 0x4824, 0x4825, 0x4826, 0x4827, 0x4828, 0x4829, 0x482a, 0x482b, + 0x482c, 0x482d, 0x482e, 0x482f, 0x4830, 0x4831, 0x4832, 0x4833, + 0x4834, 0x4835, 0x4836, 0x4837, 0x4838, 0x4839, 0x483a, 0x483b, + 0x483c, 0x483d, 0x483e, 0x483f, 0x4840, 0x4841, 0x4842, 0x4843, + 0x4844, 0x4845, 0x4846, 0x4847, 0x4848, 0x4849, 0x484a, 0x484b, + 0x484c, 0x484d, 0x484e, 0x484f, 0x4850, 0x4851, 0x4852, 0x4853, + 0x4854, 0x4855, 0x4856, 0x4857, 0x4858, 0x4859, 0x485a, 0x485b, + 0x485c, 0x485d, 0x485e, 0x485f, 0x4860, 0x4861, 0x4862, 0x4863, + 0x4864, 0x4865, 0x4866, 0x4867, 0x4868, 0x4869, 0x486a, 0x486b, + 0x486c, 0x486d, 0x486e, 0x486f, 0x4870, 0x4871, 0x4872, 0x4873, + 0x4874, 0x4875, 0x4876, 0x4877, 0x4878, 0x4879, 0x487a, 0x487b, + 0x487c, 0x487d, 0x487e, 0x4b50, 0x4b56, 0x4b67, 0x4d4f, 0x4d68, + 0x4e2d, 0x4f7b, 0x5022, 0x5038, 0x5050, 0x505d, 0x5154, 0x5155, + 0x5158, 0x515b, 0x515c, 0x515d, 0x515e, 0x515f, 0x5160, 0x5162, + 0x5163, 0x5164, 0x5165, 0x5166, 0x5168, 0x5169, 0x516a, 0x516b, + 0x516d, 0x516f, 0x5170, 0x5172, 0x5176, 0x517a, 0x517c, 0x517d, + 0x517e, 0x5222, 0x5223, 0x5227, 0x5228, 0x5229, 0x522a, 0x522b, + 0x522d, 0x5232, 0x523e, 0x5242, 0x5243, 0x5244, 0x5246, 0x5247, + 0x5248, 0x5249, 0x524a, 0x524b, 0x524d, 0x524e, 0x524f, 0x5250, + 0x5251, 0x5252, 0x5253, 0x5254, 0x5255, 0x5256, 0x5257, 0x5259, + 0x525a, 0x525e, 0x525f, 0x5261, 0x5262, 0x5264, 0x5265, 0x5266, + 0x5267, 0x5268, 0x5269, 0x526a, 0x526b, 0x5270, 0x5271, 0x5272, + 0x5273, 0x5274, 0x5275, 0x5277, 0x5278, 0x5466, 0x547c, 0x5525, + 0x552b, 0x552e, 0x5638, 0x564d, 0x574b, 0x5764, 0x5b45, 0x5b64, + 0x5c25, 0x5d25, 0x5d55, 0x5d74, 0x5e7c, 0x5e7e, 0x5f33, 0x5f61, + 0x5f68, 0x6071, 0x612d, 0x616d, 0x6375, 0x6421, 0x6429, 0x652e, + 0x6531, 0x6532, 0x6539, 0x653b, 0x653c, 0x6544, 0x654e, 0x6550, + 0x6552, 0x6556, 0x657a, 0x657b, 0x657c, 0x657e, 0x6621, 0x6624, + 0x6627, 0x662d, 0x662f, 0x6630, 0x6631, 0x6633, 0x6637, 0x6638, + 0x663c, 0x6644, 0x6646, 0x6647, 0x664a, 0x6652, 0x6656, 0x6659, + 0x665c, 0x665f, 0x6661, 0x6664, 0x6665, 0x6666, 0x6668, 0x666a, + 0x666b, 0x666c, 0x666f, 0x6671, 0x6672, 0x6675, 0x6676, 0x6677, + 0x6679, 0x6721, 0x6726, 0x6729, 0x672a, 0x672c, 0x672d, 0x6730, + 0x673f, 0x6741, 0x6746, 0x6747, 0x674b, 0x674d, 0x674f, 0x6750, + 0x6753, 0x675f, 0x6764, 0x6766, 0x6777, 0x6867, 0x6868, 0x6870, + 0x6871, 0x6877, 0x6879, 0x687b, 0x687e, 0x6927, 0x692c, 0x694c, + 0x6977, 0x6a41, 0x6a65, 0x6a74, 0x6a77, 0x6a7c, 0x6a7e, 0x6b24, + 0x6b27, 0x6b29, 0x6b2a, 0x6b3a, 0x6b3b, 0x6b3d, 0x6b41, 0x6b42, + 0x6b46, 0x6b47, 0x6b4c, 0x6b4f, 0x6b50, 0x6b51, 0x6b52, 0x6b58, + 0x6c26, 0x6c27, 0x6c2a, 0x6c2f, 0x6c30, 0x6c31, 0x6c32, 0x6c35, + 0x6c38, 0x6c3a, 0x6c40, 0x6c41, 0x6c45, 0x6c46, 0x6c49, 0x6c4a, + 0x6c55, 0x6c5d, 0x6c5e, 0x6c61, 0x6c64, 0x6c67, 0x6c68, 0x6c77, + 0x6c78, 0x6c7a, 0x6d21, 0x6d22, 0x6d23, 0x6d6e, 0x6e5b, 0x723d, + 0x727a, 0x7331, 0x7427, 0x746e, 0x7674, 0x7676, 0x7738, 0x7748, + 0x7753, 0x785b, 0x7870, 0x7a21, 0x7a22, 0x7a66, 0x7c29, 0x2321, + 0x2322, 0x2323, 0x2324, 0x2325, 0x2326, 0x2327, 0x2328, 0x2329, + 0x232a, 0x232b, 0x232c, 0x232d, 0x232e, 0x232f, 0x2330, 0x2331, + 0x2332, 0x2333, 0x2334, 0x2335, 0x2336, 0x2337, 0x2338, 0x2339, + 0x233a, 0x233b, 0x233c, 0x233d, 0x233e, 0x233f, 0x2340, 0x2341, + 0x2342, 0x2343, 0x2344, 0x2345, 0x2346, 0x2347, 0x2348, 0x2349, + 0x234a, 0x234b, 0x234c, 0x234d, 0x234e, 0x234f, 0x2350, 0x2351, + 0x2352, 0x2353, 0x2354, 0x2355, 0x2356, 0x2357, 0x2358, 0x2359, + 0x235a, 0x235b, 0x212c, 0x235d, 0x235e, 0x235f, 0x2360, 0x2361, + 0x2362, 0x2363, 0x2364, 0x2365, 0x2366, 0x2367, 0x2368, 0x2369, + 0x236a, 0x236b, 0x236c, 0x236d, 0x236e, 0x236f, 0x2370, 0x2371, + 0x2372, 0x2373, 0x2374, 0x2375, 0x2376, 0x2377, 0x2378, 0x2379, + 0x237a, 0x237b, 0x237c, 0x237d, 0x2226, 0x214b, 0x214c, 0x217e, + 0x237e, 0x214d, 0x235c, +}; + +static const Summary16 ksc5601_uni2indx_page00[70] = { + /* 0x0000 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x6592 }, { 7, 0xf7df }, + { 21, 0x0040 }, { 22, 0xc181 }, { 27, 0x0040 }, { 28, 0x4181 }, + /* 0x0100 */ + { 32, 0x0000 }, { 32, 0x0002 }, { 33, 0x00c0 }, { 35, 0x810e }, + { 40, 0x0e07 }, { 46, 0x000c }, { 48, 0x00c0 }, { 50, 0x0000 }, + { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, + { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, + /* 0x0200 */ + { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, + { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, + { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, { 50, 0x0000 }, + { 50, 0x0080 }, { 51, 0x2f01 }, { 57, 0x0000 }, { 57, 0x0000 }, + /* 0x0300 */ + { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, + { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, { 57, 0x0000 }, + { 57, 0x0000 }, { 57, 0xfffe }, { 72, 0x03fb }, { 81, 0xfffe }, + { 96, 0x03fb }, { 105, 0x0000 }, { 105, 0x0000 }, { 105, 0x0000 }, + /* 0x0400 */ + { 105, 0x0002 }, { 106, 0xffff }, { 122, 0xffff }, { 138, 0xffff }, + { 154, 0xffff }, { 170, 0x0002 }, +}; +static const Summary16 ksc5601_uni2indx_page20[103] = { + /* 0x2000 */ + { 171, 0x0000 }, { 171, 0x3320 }, { 176, 0x0063 }, { 180, 0x080d }, + { 184, 0x0000 }, { 184, 0x0000 }, { 184, 0x0000 }, { 184, 0x8010 }, + { 186, 0x001e }, { 190, 0x0000 }, { 190, 0x1000 }, { 191, 0x0000 }, + { 191, 0x0000 }, { 191, 0x0000 }, { 191, 0x0000 }, { 191, 0x0000 }, + /* 0x2100 */ + { 191, 0x0208 }, { 193, 0x0048 }, { 195, 0x0846 }, { 199, 0x0000 }, + { 199, 0x0000 }, { 199, 0x7818 }, { 205, 0x03ff }, { 215, 0x03ff }, + { 225, 0x0000 }, { 225, 0x03ff }, { 235, 0x0000 }, { 235, 0x0000 }, + { 235, 0x0000 }, { 235, 0x0014 }, { 237, 0x0000 }, { 237, 0x0000 }, + /* 0x2200 */ + { 237, 0x898d }, { 244, 0x6402 }, { 248, 0x5fa1 }, { 257, 0x3030 }, + { 261, 0x0000 }, { 261, 0x0004 }, { 262, 0x0c33 }, { 268, 0x0000 }, + { 268, 0x00cc }, { 272, 0x0200 }, { 273, 0x0020 }, { 274, 0x0000 }, + { 274, 0x0000 }, { 274, 0x0000 }, { 274, 0x0000 }, { 274, 0x0000 }, + /* 0x2300 */ + { 274, 0x0000 }, { 274, 0x0004 }, { 275, 0x0000 }, { 275, 0x0000 }, + { 275, 0x0000 }, { 275, 0x0000 }, { 275, 0x0000 }, { 275, 0x0000 }, + { 275, 0x0000 }, { 275, 0x0000 }, { 275, 0x0000 }, { 275, 0x0000 }, + { 275, 0x0000 }, { 275, 0x0000 }, { 275, 0x0000 }, { 275, 0x0000 }, + /* 0x2400 */ + { 275, 0x0000 }, { 275, 0x0000 }, { 275, 0x0000 }, { 275, 0x0000 }, + { 275, 0x0000 }, { 275, 0x0000 }, { 275, 0x7fff }, { 290, 0xfff0 }, + { 302, 0x0007 }, { 305, 0xf000 }, { 309, 0xffff }, { 325, 0x003f }, + { 331, 0x0000 }, { 331, 0xffff }, { 347, 0x03ff }, { 357, 0x0000 }, + /* 0x2500 */ + { 357, 0xf00f }, { 365, 0xffff }, { 381, 0xffff }, { 397, 0xffff }, + { 413, 0x0fff }, { 425, 0x0000 }, { 425, 0x0000 }, { 425, 0x0000 }, + { 425, 0x0000 }, { 425, 0x0004 }, { 426, 0x03fb }, { 435, 0x30cc }, + { 441, 0xc9c3 }, { 449, 0x0003 }, { 451, 0x0000 }, { 451, 0x0000 }, + /* 0x2600 */ + { 451, 0xc060 }, { 455, 0x5000 }, { 457, 0x0000 }, { 457, 0x0000 }, + { 457, 0x0005 }, { 459, 0x0000 }, { 459, 0x37bb }, +}; +static const Summary16 ksc5601_uni2indx_page30[62] = { + /* 0x3000 */ + { 470, 0xff0f }, { 482, 0x003b }, { 487, 0x0000 }, { 487, 0x0000 }, + { 487, 0xfffe }, { 502, 0xffff }, { 518, 0xffff }, { 534, 0xffff }, + { 550, 0xffff }, { 566, 0x000f }, { 570, 0xfffe }, { 585, 0xffff }, + { 601, 0xffff }, { 617, 0xffff }, { 633, 0xffff }, { 649, 0x007f }, + /* 0x3100 */ + { 656, 0x0000 }, { 656, 0x0000 }, { 656, 0x0000 }, { 656, 0xfffe }, + { 671, 0xffff }, { 687, 0xffff }, { 703, 0xffff }, { 719, 0xffff }, + { 735, 0x7fff }, { 750, 0x0000 }, { 750, 0x0000 }, { 750, 0x0000 }, + { 750, 0x0000 }, { 750, 0x0000 }, { 750, 0x0000 }, { 750, 0x0000 }, + /* 0x3200 */ + { 750, 0xffff }, { 766, 0x1fff }, { 779, 0x0000 }, { 779, 0x0000 }, + { 779, 0x0000 }, { 779, 0x0000 }, { 779, 0xffff }, { 795, 0xcfff }, + { 809, 0x0000 }, { 809, 0x0000 }, { 809, 0x0000 }, { 809, 0x0000 }, + { 809, 0x0000 }, { 809, 0x0000 }, { 809, 0x0000 }, { 809, 0x0000 }, + /* 0x3300 */ + { 809, 0x0000 }, { 809, 0x0000 }, { 809, 0x0000 }, { 809, 0x0000 }, + { 809, 0x0000 }, { 809, 0x0000 }, { 809, 0x0000 }, { 809, 0x0000 }, + { 809, 0xff1f }, { 822, 0xffff }, { 838, 0xffff }, { 854, 0xffff }, + { 870, 0x87ff }, { 882, 0x3949 }, +}; +static const Summary16 ksc5601_uni2indx_page4e[1306] = { + /* 0x4e00 */ + { 889, 0x2f8b }, { 898, 0x4372 }, { 905, 0x2000 }, { 906, 0x0b04 }, + { 910, 0xe82c }, { 917, 0xe340 }, { 923, 0x2800 }, { 925, 0x40c8 }, + { 929, 0x5944 }, { 935, 0x4937 }, { 943, 0x7976 }, { 953, 0x0440 }, + { 955, 0x2c93 }, { 962, 0xa3f0 }, { 970, 0x0038 }, { 973, 0x08c5 }, + /* 0x4f00 */ + { 978, 0xee02 }, { 985, 0x0003 }, { 987, 0x8000 }, { 988, 0x3550 }, + { 994, 0xe1c8 }, { 1001, 0x1e23 }, { 1008, 0x8200 }, { 1010, 0xc449 }, + { 1016, 0xad5a }, { 1025, 0x2942 }, { 1030, 0xc000 }, { 1032, 0x8060 }, + { 1035, 0x461c }, { 1041, 0xa49a }, { 1048, 0xc003 }, { 1052, 0x052a }, + /* 0x5000 */ + { 1057, 0x2a44 }, { 1062, 0xd646 }, { 1070, 0x3dda }, { 1080, 0x0800 }, + { 1081, 0x8388 }, { 1086, 0x1420 }, { 1089, 0x0020 }, { 1090, 0x0170 }, + { 1094, 0x2021 }, { 1097, 0x0302 }, { 1100, 0x3000 }, { 1102, 0x40ac }, + { 1107, 0x8620 }, { 1111, 0x4462 }, { 1116, 0x20a0 }, { 1119, 0x8a00 }, + /* 0x5100 */ + { 1122, 0x0253 }, { 1127, 0x8004 }, { 1129, 0x0402 }, { 1131, 0x1484 }, + { 1135, 0x7bfb }, { 1148, 0x1004 }, { 1150, 0x7fa4 }, { 1160, 0x11e2 }, + { 1166, 0x2441 }, { 1170, 0x00a4 }, { 1173, 0x1421 }, { 1177, 0x20c0 }, + { 1180, 0x3a50 }, { 1186, 0x7000 }, { 1189, 0x0002 }, { 1190, 0x2743 }, + /* 0x5200 */ + { 1197, 0x45c9 }, { 1204, 0x2082 }, { 1207, 0x4630 }, { 1212, 0x0fc1 }, + { 1219, 0x3c88 }, { 1225, 0x2850 }, { 1229, 0x8602 }, { 1233, 0xa024 }, + { 1237, 0x2388 }, { 1242, 0x8806 }, { 1246, 0x0e19 }, { 1252, 0x4000 }, + { 1253, 0x22aa }, { 1259, 0xeb64 }, { 1268, 0x001c }, { 1271, 0xcd28 }, + /* 0x5300 */ + { 1278, 0xa120 }, { 1282, 0x02e1 }, { 1287, 0x840b }, { 1292, 0x8200 }, + { 1294, 0x279b }, { 1303, 0x549e }, { 1311, 0x8141 }, { 1315, 0xa0b3 }, + { 1322, 0x0010 }, { 1323, 0x8508 }, { 1327, 0x2061 }, { 1331, 0x0800 }, + { 1332, 0x2f08 }, { 1338, 0x08d0 }, { 1342, 0xbe3e }, { 1353, 0x010f }, + /* 0x5400 */ + { 1358, 0xf718 }, { 1367, 0xa803 }, { 1372, 0x0a41 }, { 1376, 0x5b08 }, + { 1382, 0x0504 }, { 1385, 0x0002 }, { 1386, 0x0500 }, { 1388, 0x382a }, + { 1394, 0x5041 }, { 1398, 0x0001 }, { 1399, 0x1910 }, { 1403, 0x2108 }, + { 1406, 0x0313 }, { 1411, 0x0000 }, { 1411, 0x6122 }, { 1416, 0x0404 }, + /* 0x5500 */ + { 1418, 0x40d0 }, { 1422, 0x1001 }, { 1424, 0x8000 }, { 1425, 0x4022 }, + { 1428, 0x8050 }, { 1431, 0x4048 }, { 1434, 0x0008 }, { 1435, 0x1000 }, + { 1436, 0x06d1 }, { 1442, 0x3700 }, { 1447, 0x5e80 }, { 1453, 0x0000 }, + { 1453, 0x00a0 }, { 1455, 0x9410 }, { 1459, 0x0018 }, { 1461, 0x6000 }, + /* 0x5600 */ + { 1463, 0x0240 }, { 1465, 0x0090 }, { 1467, 0x8000 }, { 1468, 0x0054 }, + { 1471, 0x0000 }, { 1471, 0x0008 }, { 1472, 0x0900 }, { 1474, 0x0010 }, + { 1475, 0x0040 }, { 1476, 0x0000 }, { 1476, 0x5020 }, { 1479, 0x1010 }, + { 1481, 0x2400 }, { 1483, 0x4c02 }, { 1487, 0x0001 }, { 1488, 0x0601 }, + /* 0x5700 */ + { 1491, 0x2918 }, { 1496, 0x814c }, { 1501, 0x2100 }, { 1503, 0x0801 }, + { 1505, 0x6485 }, { 1511, 0x0003 }, { 1513, 0x4452 }, { 1518, 0x1021 }, + { 1521, 0x0904 }, { 1524, 0x0008 }, { 1525, 0x000d }, { 1528, 0x0000 }, + { 1528, 0x4988 }, { 1533, 0x8000 }, { 1534, 0x0001 }, { 1535, 0x1691 }, + /* 0x5800 */ + { 1541, 0x0765 }, { 1548, 0x4000 }, { 1549, 0x8492 }, { 1554, 0x0433 }, + { 1559, 0x8c00 }, { 1562, 0x4592 }, { 1568, 0x0016 }, { 1571, 0x5220 }, + { 1575, 0x0228 }, { 1578, 0xd008 }, { 1582, 0x4300 }, { 1585, 0x4c08 }, + { 1589, 0x40a2 }, { 1593, 0xc32a }, { 1600, 0x9810 }, { 1604, 0x2e00 }, + /* 0x5900 */ + { 1608, 0x8000 }, { 1609, 0x1670 }, { 1615, 0x6e84 }, { 1622, 0x4082 }, + { 1625, 0xc390 }, { 1631, 0x04b3 }, { 1637, 0x7c85 }, { 1645, 0x2118 }, + { 1649, 0x041c }, { 1653, 0x02c8 }, { 1657, 0x1120 }, { 1660, 0x4a00 }, + { 1663, 0x0a48 }, { 1667, 0x361b }, { 1675, 0x5540 }, { 1680, 0x8900 }, + /* 0x5a00 */ + { 1683, 0x000a }, { 1685, 0x9902 }, { 1690, 0x0221 }, { 1693, 0x1040 }, + { 1695, 0x0242 }, { 1698, 0x0400 }, { 1699, 0x0044 }, { 1701, 0x0000 }, + { 1701, 0x0000 }, { 1701, 0x0c04 }, { 1704, 0x0010 }, { 1705, 0x0000 }, + { 1705, 0x1216 }, { 1710, 0x0000 }, { 1710, 0x0242 }, { 1713, 0x0000 }, + /* 0x5b00 */ + { 1713, 0x1a20 }, { 1717, 0x0040 }, { 1718, 0x0400 }, { 1719, 0x0000 }, + { 1719, 0x0009 }, { 1721, 0xb5b3 }, { 1731, 0x0a18 }, { 1735, 0x1523 }, + { 1741, 0x9ba0 }, { 1748, 0x1fe8 }, { 1757, 0x507c }, { 1764, 0x8379 }, + { 1772, 0x10fd }, { 1780, 0xc09d }, { 1787, 0xdbf6 }, { 1799, 0x0560 }, + /* 0x5c00 */ + { 1803, 0xef92 }, { 1813, 0x0242 }, { 1816, 0x0110 }, { 1818, 0xdf02 }, + { 1826, 0x6961 }, { 1833, 0x0822 }, { 1836, 0x9035 }, { 1842, 0x0202 }, + { 1844, 0x0000 }, { 1844, 0x0003 }, { 1846, 0x1a02 }, { 1850, 0x45aa }, + { 1857, 0x0001 }, { 1858, 0x0200 }, { 1859, 0x8101 }, { 1862, 0x2851 }, + /* 0x5d00 */ + { 1867, 0x6080 }, { 1870, 0x02d2 }, { 1875, 0x0280 }, { 1877, 0x0000 }, + { 1877, 0x1800 }, { 1879, 0x0001 }, { 1880, 0x9200 }, { 1883, 0x0000 }, + { 1883, 0x0880 }, { 1885, 0x2000 }, { 1886, 0x0405 }, { 1889, 0x3500 }, + { 1893, 0x2000 }, { 1894, 0x6044 }, { 1898, 0x49e6 }, { 1906, 0x609e }, + /* 0x5e00 */ + { 1913, 0x104c }, { 1917, 0x2a42 }, { 1922, 0x2820 }, { 1925, 0xa148 }, + { 1930, 0x10b1 }, { 1935, 0x8020 }, { 1937, 0x000e }, { 1940, 0x7b9c }, + { 1950, 0x8490 }, { 1954, 0x14a0 }, { 1958, 0x28c1 }, { 1963, 0x41e0 }, + { 1968, 0x0704 }, { 1972, 0x8c49 }, { 1978, 0x100d }, { 1982, 0x0cc8 }, + /* 0x5f00 */ + { 1987, 0x8412 }, { 1991, 0x89ba }, { 1999, 0x02c0 }, { 2002, 0x1422 }, + { 2006, 0x5500 }, { 2010, 0x0ac0 }, { 2014, 0x3ec4 }, { 2022, 0x9283 }, + { 2028, 0x1ca3 }, { 2035, 0x4387 }, { 2042, 0x4703 }, { 2048, 0x22a0 }, + { 2052, 0x3028 }, { 2056, 0x03c0 }, { 2060, 0x0801 }, { 2062, 0xa020 }, + /* 0x6000 */ + { 2065, 0x8000 }, { 2066, 0x3044 }, { 2070, 0x85a3 }, { 2077, 0x0000 }, + { 2077, 0x200e }, { 2081, 0x2225 }, { 2086, 0xb73c }, { 2096, 0x0001 }, + { 2097, 0x3220 }, { 2101, 0x8c50 }, { 2106, 0x0099 }, { 2110, 0x315d }, + { 2118, 0x00a0 }, { 2120, 0x9402 }, { 2124, 0x0003 }, { 2126, 0x0e4b }, + /* 0x6100 */ + { 2133, 0xe342 }, { 2140, 0x8c20 }, { 2144, 0x0080 }, { 2145, 0xd091 }, + { 2151, 0x1d94 }, { 2158, 0xa328 }, { 2164, 0x499c }, { 2171, 0x60c1 }, + { 2176, 0x4406 }, { 2180, 0x0713 }, { 2186, 0x5a90 }, { 2192, 0x4444 }, + { 2196, 0x0f88 }, { 2202, 0x0000 }, { 2202, 0x0040 }, { 2203, 0x95c4 }, + /* 0x6200 */ + { 2210, 0x7581 }, { 2217, 0x8447 }, { 2223, 0x4402 }, { 2226, 0xc053 }, + { 2232, 0x2b83 }, { 2239, 0x0108 }, { 2241, 0x4000 }, { 2242, 0x9242 }, + { 2247, 0x0611 }, { 2251, 0x09a6 }, { 2257, 0x0800 }, { 2258, 0x3222 }, + { 2263, 0xb384 }, { 2270, 0x1bdd }, { 2280, 0xf000 }, { 2284, 0xc08a }, + /* 0x6300 */ + { 2289, 0x0282 }, { 2292, 0x0002 }, { 2293, 0x8800 }, { 2295, 0x6c00 }, + { 2299, 0x9200 }, { 2302, 0x0021 }, { 2304, 0x4180 }, { 2307, 0x8c84 }, + { 2312, 0x1308 }, { 2316, 0x0944 }, { 2320, 0x07a7 }, { 2328, 0x0000 }, + { 2328, 0x8051 }, { 2332, 0x0c41 }, { 2336, 0x6002 }, { 2339, 0x00d0 }, + /* 0x6400 */ + { 2342, 0xa000 }, { 2344, 0x10d0 }, { 2348, 0x3004 }, { 2351, 0x4400 }, + { 2353, 0x0000 }, { 2353, 0x0100 }, { 2354, 0x8201 }, { 2357, 0x0700 }, + { 2360, 0x0100 }, { 2361, 0x440e }, { 2366, 0x6830 }, { 2371, 0x0805 }, + { 2374, 0x64b2 }, { 2381, 0x0514 }, { 2385, 0x10e6 }, { 2391, 0x4414 }, + /* 0x6500 */ + { 2395, 0x0011 }, { 2397, 0x2100 }, { 2399, 0x9c08 }, { 2404, 0xcbc0 }, + { 2411, 0xe120 }, { 2416, 0x40c2 }, { 2420, 0x304c }, { 2425, 0x41b4 }, + { 2431, 0x10ac }, { 2436, 0x9a83 }, { 2443, 0x98b2 }, { 2450, 0x3281 }, + { 2455, 0x9822 }, { 2460, 0x0084 }, { 2462, 0x3369 }, { 2470, 0xbc12 }, + /* 0x6600 */ + { 2477, 0xd6c0 }, { 2484, 0xc03b }, { 2491, 0xa1a1 }, { 2497, 0x0c53 }, + { 2503, 0x8a1e }, { 2510, 0xea00 }, { 2515, 0xcbf0 }, { 2524, 0x05d8 }, + { 2530, 0x4390 }, { 2535, 0x21c3 }, { 2541, 0x4805 }, { 2545, 0x4a1c }, + { 2551, 0x02d0 }, { 2555, 0x3240 }, { 2559, 0x0041 }, { 2561, 0xd79d }, + /* 0x6700 */ + { 2572, 0x2b09 }, { 2578, 0xe8b0 }, { 2585, 0x7dc0 }, { 2593, 0x2452 }, + { 2598, 0xc240 }, { 2602, 0xd04b }, { 2609, 0xa000 }, { 2611, 0xc8ab }, + { 2619, 0x8a80 }, { 2623, 0x34a9 }, { 2630, 0x8000 }, { 2631, 0x41c9 }, + { 2637, 0x8010 }, { 2639, 0x241f }, { 2646, 0x9200 }, { 2649, 0x487b }, + /* 0x6800 */ + { 2657, 0x0000 }, { 2657, 0x00cc }, { 2661, 0x8406 }, { 2665, 0x3300 }, + { 2669, 0x410f }, { 2675, 0x001b }, { 2679, 0x2000 }, { 2680, 0x8040 }, + { 2682, 0x8022 }, { 2685, 0xa098 }, { 2690, 0xa186 }, { 2696, 0x006b }, + { 2701, 0x2a30 }, { 2706, 0x85a4 }, { 2712, 0x4181 }, { 2716, 0x0604 }, + /* 0x6900 */ + { 2719, 0x6021 }, { 2723, 0x0004 }, { 2724, 0x0080 }, { 2725, 0xa001 }, + { 2728, 0x0400 }, { 2729, 0x46b8 }, { 2736, 0xe90f }, { 2745, 0x03a0 }, + { 2749, 0x0000 }, { 2749, 0x1820 }, { 2752, 0x40a0 }, { 2755, 0x0810 }, + { 2757, 0x380a }, { 2762, 0x0001 }, { 2763, 0x0500 }, { 2765, 0xa800 }, + /* 0x6a00 */ + { 2768, 0x0404 }, { 2770, 0xc28a }, { 2776, 0x000a }, { 2778, 0x2720 }, + { 2783, 0x0910 }, { 2786, 0x830c }, { 2791, 0x0802 }, { 2793, 0x0000 }, + { 2793, 0x6211 }, { 2798, 0x1080 }, { 2800, 0x000c }, { 2802, 0x0808 }, + { 2804, 0x000c }, { 2806, 0x0c08 }, { 2809, 0x0000 }, { 2809, 0x0840 }, + /* 0x6b00 */ + { 2811, 0x1410 }, { 2814, 0x0044 }, { 2816, 0x000b }, { 2819, 0x6404 }, + { 2823, 0x50c0 }, { 2827, 0x8001 }, { 2829, 0x047e }, { 2836, 0x8984 }, + { 2841, 0x0658 }, { 2846, 0x4140 }, { 2849, 0xc000 }, { 2851, 0x94a4 }, + { 2857, 0xa862 }, { 2863, 0x09dc }, { 2870, 0x1800 }, { 2872, 0x0000 }, + /* 0x6c00 */ + { 2872, 0x8100 }, { 2874, 0x000a }, { 2876, 0x0008 }, { 2877, 0x4190 }, + { 2881, 0x4007 }, { 2885, 0xe4a1 }, { 2892, 0x2501 }, { 2896, 0x6445 }, + { 2902, 0x11ee }, { 2910, 0x0e7d }, { 2919, 0x4800 }, { 2921, 0xfb08 }, + { 2929, 0x1616 }, { 2935, 0x08a8 }, { 2939, 0xc92e }, { 2947, 0x0009 }, + /* 0x6d00 */ + { 2949, 0x1800 }, { 2951, 0x4a82 }, { 2956, 0x06a0 }, { 2960, 0x6b64 }, + { 2968, 0x0002 }, { 2969, 0x1600 }, { 2972, 0x5648 }, { 2978, 0x8390 }, + { 2983, 0x73a0 }, { 2990, 0x002a }, { 2993, 0x8000 }, { 2994, 0x0024 }, + { 2996, 0x88f9 }, { 3004, 0x4702 }, { 3009, 0x4d02 }, { 3014, 0x0faa }, + /* 0x6e00 */ + { 3022, 0x0000 }, { 3022, 0x8e80 }, { 3027, 0xb87b }, { 3037, 0x7554 }, + { 3045, 0x2418 }, { 3049, 0xd940 }, { 3055, 0xc880 }, { 3059, 0x040c }, + { 3062, 0x0000 }, { 3062, 0xb041 }, { 3067, 0x8c24 }, { 3072, 0x0442 }, + { 3075, 0x5a34 }, { 3082, 0x001a }, { 3085, 0x8000 }, { 3086, 0xc110 }, + /* 0x6f00 */ + { 3090, 0x8046 }, { 3094, 0x0032 }, { 3097, 0x180d }, { 3102, 0x8106 }, + { 3106, 0x0002 }, { 3107, 0xcd92 }, { 3115, 0x6014 }, { 3119, 0x7401 }, + { 3124, 0x6112 }, { 3129, 0x0091 }, { 3132, 0xc098 }, { 3137, 0x420a }, + { 3141, 0x040f }, { 3146, 0x8420 }, { 3149, 0x9a13 }, { 3156, 0x4002 }, + /* 0x7000 */ + { 3158, 0x8a62 }, { 3164, 0xfd22 }, { 3173, 0x8188 }, { 3177, 0x4080 }, + { 3179, 0x1000 }, { 3180, 0x2103 }, { 3184, 0x0808 }, { 3186, 0x3101 }, + { 3190, 0x4420 }, { 3193, 0x0704 }, { 3197, 0xb812 }, { 3203, 0x0388 }, + { 3207, 0x8900 }, { 3210, 0xa300 }, { 3214, 0x0000 }, { 3214, 0x2202 }, + /* 0x7100 */ + { 3217, 0x1210 }, { 3220, 0x4600 }, { 3223, 0x0042 }, { 3225, 0x0041 }, + { 3227, 0x5680 }, { 3232, 0x5241 }, { 3237, 0x52f0 }, { 3244, 0x2000 }, + { 3245, 0x8610 }, { 3249, 0x8214 }, { 3253, 0x1004 }, { 3255, 0x4602 }, + { 3259, 0x430a }, { 3264, 0x8035 }, { 3269, 0x60e0 }, { 3274, 0xd800 }, + /* 0x7200 */ + { 3278, 0x0041 }, { 3280, 0x0801 }, { 3282, 0x3400 }, { 3285, 0x6c65 }, + { 3293, 0x11c1 }, { 3298, 0xab04 }, { 3304, 0x0286 }, { 3308, 0x2204 }, + { 3311, 0x0003 }, { 3313, 0x0000 }, { 3313, 0x9084 }, { 3317, 0x0000 }, + { 3317, 0x4015 }, { 3321, 0x0281 }, { 3324, 0x0202 }, { 3326, 0x3300 }, + /* 0x7300 */ + { 3330, 0x0400 }, { 3331, 0x3840 }, { 3335, 0x0e20 }, { 3339, 0xc0c0 }, + { 3343, 0x0030 }, { 3345, 0x0085 }, { 3348, 0x0500 }, { 3350, 0x0d25 }, + { 3356, 0x4ad0 }, { 3362, 0x81d0 }, { 3367, 0x2280 }, { 3370, 0x020c }, + { 3373, 0xb605 }, { 3380, 0x6240 }, { 3384, 0x2679 }, { 3392, 0x6280 }, + /* 0x7400 */ + { 3396, 0x02ea }, { 3402, 0x0808 }, { 3404, 0xdd67 }, { 3415, 0x8579 }, + { 3423, 0x081b }, { 3428, 0xdea0 }, { 3436, 0x8735 }, { 3444, 0x4000 }, + { 3445, 0x0a8c }, { 3450, 0xd100 }, { 3454, 0x05aa }, { 3460, 0xa225 }, + { 3466, 0x8440 }, { 3469, 0x1510 }, { 3473, 0x404d }, { 3478, 0x0080 }, + /* 0x7500 */ + { 3479, 0x0012 }, { 3481, 0x8d22 }, { 3487, 0x1968 }, { 3493, 0x058f }, + { 3500, 0x9080 }, { 3503, 0x3a1a }, { 3510, 0x8464 }, { 3515, 0x8561 }, + { 3521, 0xccc0 }, { 3527, 0x2002 }, { 3529, 0x0820 }, { 3531, 0x732e }, + { 3540, 0x20a4 }, { 3544, 0x0b34 }, { 3550, 0x0004 }, { 3551, 0x1415 }, + /* 0x7600 */ + { 3556, 0x2001 }, { 3558, 0x8200 }, { 3560, 0x0057 }, { 3565, 0x0800 }, + { 3566, 0x5004 }, { 3569, 0x0044 }, { 3571, 0x1212 }, { 3575, 0x7905 }, + { 3582, 0x40d0 }, { 3586, 0x0009 }, { 3588, 0x4000 }, { 3589, 0x8400 }, + { 3591, 0x054c }, { 3596, 0xd844 }, { 3602, 0x409a }, { 3607, 0x5114 }, + /* 0x7700 */ + { 3612, 0x0b12 }, { 3617, 0x4000 }, { 3618, 0x0201 }, { 3620, 0x1580 }, + { 3624, 0x2001 }, { 3626, 0x0800 }, { 3627, 0x084a }, { 3631, 0xc200 }, + { 3634, 0x0800 }, { 3635, 0x4002 }, { 3637, 0x3020 }, { 3640, 0x9809 }, + { 3645, 0x0000 }, { 3645, 0x1880 }, { 3648, 0xe22c }, { 3655, 0x0008 }, + /* 0x7800 */ + { 3656, 0x0004 }, { 3657, 0x0004 }, { 3658, 0x10e0 }, { 3662, 0x0014 }, + { 3664, 0x8020 }, { 3666, 0x2000 }, { 3667, 0x9800 }, { 3670, 0x1000 }, + { 3671, 0x7082 }, { 3676, 0x0082 }, { 3678, 0x0288 }, { 3681, 0x1c00 }, + { 3684, 0x4c22 }, { 3689, 0x0001 }, { 3690, 0x9100 }, { 3693, 0x0820 }, + /* 0x7900 */ + { 3695, 0x4002 }, { 3697, 0x0040 }, { 3698, 0x1c00 }, { 3701, 0x4400 }, + { 3703, 0x0383 }, { 3708, 0x7cc1 }, { 3716, 0x2121 }, { 3720, 0x8400 }, + { 3722, 0xe002 }, { 3726, 0x0002 }, { 3727, 0x44c0 }, { 3731, 0xe20a }, + { 3737, 0x0e03 }, { 3742, 0x8126 }, { 3747, 0x02d0 }, { 3751, 0x0800 }, + /* 0x7a00 */ + { 3752, 0x2921 }, { 3757, 0x9690 }, { 3763, 0x4001 }, { 3765, 0xb8c2 }, + { 3772, 0x6241 }, { 3777, 0x0080 }, { 3778, 0x0a06 }, { 3782, 0xa651 }, + { 3789, 0x0112 }, { 3792, 0x812c }, { 3797, 0xc600 }, { 3801, 0x0400 }, + { 3802, 0x0cb0 }, { 3807, 0xa280 }, { 3811, 0xa429 }, { 3817, 0x8640 }, + /* 0x7b00 */ + { 3821, 0x8000 }, { 3822, 0x4a02 }, { 3826, 0x3041 }, { 3830, 0x0200 }, + { 3831, 0xba40 }, { 3837, 0x0057 }, { 3842, 0x5001 }, { 3845, 0x2020 }, + { 3847, 0x8880 }, { 3850, 0x24b0 }, { 3855, 0x2002 }, { 3857, 0x0112 }, + { 3860, 0x02d3 }, { 3866, 0x0004 }, { 3867, 0x0211 }, { 3870, 0x0000 }, + /* 0x7c00 */ + { 3870, 0x0080 }, { 3871, 0x4004 }, { 3873, 0x0c82 }, { 3877, 0xe000 }, + { 3880, 0x3008 }, { 3883, 0x0000 }, { 3883, 0x1011 }, { 3886, 0x0008 }, + { 3887, 0x0208 }, { 3889, 0x81a4 }, { 3894, 0x40a0 }, { 3897, 0x420e }, + { 3902, 0x0400 }, { 3903, 0xc040 }, { 3906, 0x0081 }, { 3908, 0x4800 }, + /* 0x7d00 */ + { 3910, 0x2df5 }, { 3920, 0x0f91 }, { 3927, 0xd807 }, { 3934, 0x0629 }, + { 3939, 0x007c }, { 3944, 0x4001 }, { 3946, 0x4546 }, { 3952, 0x824e }, + { 3958, 0xc000 }, { 3960, 0x1008 }, { 3962, 0x3005 }, { 3966, 0xed36 }, + { 3976, 0x0c80 }, { 3979, 0x6540 }, { 3984, 0x930b }, { 3991, 0x0810 }, + /* 0x7e00 */ + { 3993, 0x0600 }, { 3995, 0xe820 }, { 4000, 0xc80a }, { 4005, 0x6082 }, + { 4009, 0x00ca }, { 4013, 0x4034 }, { 4017, 0x2e02 }, { 4022, 0x1201 }, + { 4025, 0x9004 }, { 4028, 0x1948 }, { 4033, 0x0000 }, { 4033, 0x0000 }, + { 4033, 0x0000 }, { 4033, 0x0000 }, { 4033, 0x0000 }, { 4033, 0x0000 }, + /* 0x7f00 */ + { 4033, 0x0000 }, { 4033, 0x0000 }, { 4033, 0x0000 }, { 4033, 0x0540 }, + { 4036, 0x1000 }, { 4037, 0x0031 }, { 4040, 0x4c00 }, { 4043, 0x02a5 }, + { 4048, 0x5520 }, { 4053, 0x4410 }, { 4056, 0x0310 }, { 4059, 0x2304 }, + { 4063, 0x5422 }, { 4068, 0x8034 }, { 4072, 0x0a03 }, { 4076, 0x1201 }, + /* 0x8000 */ + { 4079, 0x126b }, { 4086, 0x01a1 }, { 4090, 0x2000 }, { 4091, 0xa048 }, + { 4095, 0x0448 }, { 4098, 0x4540 }, { 4102, 0x8000 }, { 4103, 0xe08d }, + { 4110, 0x1af0 }, { 4117, 0x2840 }, { 4120, 0x8626 }, { 4126, 0x0416 }, + { 4130, 0x5018 }, { 4134, 0x4c00 }, { 4137, 0x0032 }, { 4140, 0x2112 }, + /* 0x8100 */ + { 4144, 0x05e4 }, { 4150, 0x0d00 }, { 4153, 0x8a08 }, { 4157, 0x4200 }, + { 4159, 0x4800 }, { 4161, 0x0033 }, { 4165, 0x0860 }, { 4168, 0x8703 }, + { 4174, 0x8501 }, { 4178, 0x3400 }, { 4181, 0x0109 }, { 4184, 0xe428 }, + { 4190, 0x2045 }, { 4194, 0x8100 }, { 4196, 0x25a8 }, { 4202, 0x5c18 }, + /* 0x8200 */ + { 4208, 0x35a0 }, { 4214, 0xd804 }, { 4219, 0x1c02 }, { 4223, 0x02e0 }, + { 4227, 0x00a1 }, { 4230, 0x0200 }, { 4231, 0xc050 }, { 4235, 0x4146 }, + { 4240, 0x6800 }, { 4243, 0xa604 }, { 4248, 0xf260 }, { 4255, 0xbb8a }, + { 4264, 0x0000 }, { 4264, 0xc8b6 }, { 4272, 0x00e2 }, { 4276, 0x6002 }, + /* 0x8300 */ + { 4279, 0x023e }, { 4285, 0x0080 }, { 4286, 0x8900 }, { 4289, 0x0372 }, + { 4295, 0x8681 }, { 4300, 0x0006 }, { 4302, 0x0000 }, { 4302, 0x0888 }, + { 4305, 0x4600 }, { 4308, 0x4140 }, { 4311, 0x0e04 }, { 4315, 0x2000 }, + { 4316, 0x1622 }, { 4321, 0x1048 }, { 4324, 0x8a00 }, { 4327, 0x2217 }, + /* 0x8400 */ + { 4333, 0x7418 }, { 4339, 0x0000 }, { 4339, 0x1200 }, { 4341, 0x2102 }, + { 4344, 0x0200 }, { 4345, 0x0880 }, { 4347, 0x984a }, { 4353, 0x0420 }, + { 4355, 0x0000 }, { 4355, 0x1211 }, { 4359, 0x0002 }, { 4360, 0x9904 }, + { 4365, 0x2a55 }, { 4372, 0x0402 }, { 4374, 0x5000 }, { 4376, 0x1010 }, + /* 0x8500 */ + { 4378, 0x0000 }, { 4378, 0x459a }, { 4385, 0xb02a }, { 4391, 0xa000 }, + { 4393, 0x420a }, { 4397, 0x0208 }, { 4399, 0x2708 }, { 4404, 0x0000 }, + { 4404, 0x8090 }, { 4407, 0x0812 }, { 4410, 0x8740 }, { 4415, 0x0401 }, + { 4417, 0xe202 }, { 4422, 0x3020 }, { 4425, 0x0630 }, { 4429, 0x8c80 }, + /* 0x8600 */ + { 4433, 0x04c4 }, { 4437, 0x04c0 }, { 4440, 0x2000 }, { 4441, 0x8000 }, + { 4442, 0x4000 }, { 4443, 0xd831 }, { 4450, 0x0080 }, { 4451, 0x0200 }, + { 4452, 0x1400 }, { 4454, 0x0008 }, { 4455, 0x0218 }, { 4458, 0x0000 }, + { 4458, 0x0880 }, { 4460, 0x8a10 }, { 4464, 0x2010 }, { 4466, 0x4000 }, + /* 0x8700 */ + { 4467, 0x010d }, { 4471, 0x1500 }, { 4474, 0x0000 }, { 4474, 0x0000 }, + { 4474, 0x4000 }, { 4475, 0x80a0 }, { 4478, 0x0140 }, { 4480, 0x0150 }, + { 4483, 0x2004 }, { 4485, 0x8000 }, { 4486, 0x0004 }, { 4487, 0x0408 }, + { 4489, 0x0010 }, { 4490, 0x0000 }, { 4490, 0x9001 }, { 4493, 0x4a04 }, + /* 0x8800 */ + { 4497, 0x0020 }, { 4498, 0x8000 }, { 4499, 0x000c }, { 4501, 0x0842 }, + { 4504, 0x3041 }, { 4508, 0x2a8c }, { 4514, 0x090e }, { 4519, 0xc085 }, + { 4524, 0x2906 }, { 4529, 0x40c4 }, { 4533, 0x0800 }, { 4534, 0x0010 }, + { 4535, 0x8006 }, { 4538, 0xb230 }, { 4544, 0x0102 }, { 4546, 0x2138 }, + /* 0x8900 */ + { 4551, 0x0080 }, { 4552, 0x030d }, { 4557, 0x0420 }, { 4559, 0x0940 }, + { 4562, 0x0012 }, { 4564, 0x8000 }, { 4565, 0x0410 }, { 4567, 0x8004 }, + { 4569, 0x88ca }, { 4575, 0x0048 }, { 4577, 0x0602 }, { 4580, 0x2404 }, + { 4583, 0x0001 }, { 4584, 0x0004 }, { 4585, 0x0008 }, { 4586, 0x0110 }, + /* 0x8a00 */ + { 4588, 0x550d }, { 4595, 0xa9c8 }, { 4602, 0x2428 }, { 4606, 0x0c52 }, + { 4611, 0x0000 }, { 4611, 0x4831 }, { 4616, 0x624d }, { 4623, 0x022f }, + { 4629, 0x30a0 }, { 4633, 0x4128 }, { 4637, 0x057b }, { 4645, 0xd205 }, + { 4651, 0xa894 }, { 4657, 0x1844 }, { 4661, 0x6cc2 }, { 4668, 0x45c2 }, + /* 0x8b00 */ + { 4674, 0x4017 }, { 4679, 0x2ed1 }, { 4687, 0x1901 }, { 4691, 0x0208 }, + { 4693, 0xc202 }, { 4697, 0x1500 }, { 4700, 0x9040 }, { 4703, 0x2091 }, + { 4707, 0x0401 }, { 4709, 0x044d }, { 4714, 0x0000 }, { 4714, 0x0000 }, + { 4714, 0x0000 }, { 4714, 0x0000 }, { 4714, 0x0000 }, { 4714, 0x0000 }, + /* 0x8c00 */ + { 4714, 0x0000 }, { 4714, 0x0000 }, { 4714, 0x0000 }, { 4714, 0x8080 }, + { 4716, 0x1542 }, { 4721, 0x0420 }, { 4723, 0x0c02 }, { 4726, 0x0600 }, + { 4728, 0x1404 }, { 4731, 0x6000 }, { 4733, 0x9f87 }, { 4743, 0xb9d9 }, + { 4753, 0x059f }, { 4761, 0x540a }, { 4766, 0x245d }, { 4773, 0x3810 }, + /* 0x8d00 */ + { 4777, 0x25b0 }, { 4783, 0x0048 }, { 4785, 0x0000 }, { 4785, 0x0000 }, + { 4785, 0x0000 }, { 4785, 0x0000 }, { 4785, 0x0850 }, { 4788, 0x0099 }, + { 4792, 0x0420 }, { 4794, 0x0200 }, { 4795, 0x0108 }, { 4797, 0x4408 }, + { 4800, 0x9840 }, { 4804, 0x2800 }, { 4806, 0x810a }, { 4810, 0x0008 }, + /* 0x8e00 */ + { 4811, 0x8400 }, { 4813, 0x4001 }, { 4815, 0x0400 }, { 4816, 0x0021 }, + { 4818, 0x0794 }, { 4824, 0x8200 }, { 4826, 0x0001 }, { 4827, 0x0050 }, + { 4829, 0x2482 }, { 4833, 0x0000 }, { 4833, 0x1c00 }, { 4836, 0x0000 }, + { 4836, 0x3c01 }, { 4841, 0x8004 }, { 4843, 0x0800 }, { 4844, 0x4900 }, + /* 0x8f00 */ + { 4847, 0x0228 }, { 4850, 0xf83c }, { 4859, 0x86c0 }, { 4864, 0xcb08 }, + { 4870, 0x6230 }, { 4875, 0xa000 }, { 4877, 0x0004 }, { 4878, 0x0000 }, + { 4878, 0x0000 }, { 4878, 0x1800 }, { 4880, 0xa148 }, { 4885, 0x0007 }, + { 4888, 0x4024 }, { 4891, 0x0012 }, { 4893, 0x2c40 }, { 4897, 0x2285 }, + /* 0x9000 */ + { 4902, 0xa96f }, { 4912, 0xe6b3 }, { 4922, 0x400f }, { 4927, 0x5126 }, + { 4933, 0x6c86 }, { 4940, 0x723b }, { 4949, 0xe20b }, { 4956, 0xb5a4 }, + { 4964, 0x859f }, { 4973, 0x0222 }, { 4976, 0x854c }, { 4982, 0x0123 }, + { 4986, 0x0402 }, { 4988, 0x4000 }, { 4989, 0x2102 }, { 4992, 0x2020 }, + /* 0x9100 */ + { 4994, 0x0004 }, { 4995, 0x0224 }, { 4998, 0x2080 }, { 5000, 0x0004 }, + { 5001, 0x7e00 }, { 5007, 0x0004 }, { 5008, 0x1604 }, { 5012, 0x01a0 }, + { 5015, 0x2a80 }, { 5019, 0x1004 }, { 5021, 0xd800 }, { 5025, 0x0032 }, + { 5028, 0xfa81 }, { 5036, 0x3183 }, { 5042, 0x0488 }, { 5045, 0x0020 }, + /* 0x9200 */ + { 5046, 0x2000 }, { 5047, 0x4087 }, { 5052, 0x0000 }, { 5052, 0x8410 }, + { 5055, 0x0221 }, { 5058, 0x4880 }, { 5061, 0x0074 }, { 5065, 0x0000 }, + { 5065, 0x0029 }, { 5068, 0x114a }, { 5073, 0x0000 }, { 5073, 0x02c8 }, + { 5077, 0x9000 }, { 5079, 0x0004 }, { 5080, 0x0410 }, { 5082, 0x1100 }, + /* 0x9300 */ + { 5084, 0x0010 }, { 5085, 0xc501 }, { 5090, 0xc957 }, { 5099, 0x0000 }, + { 5099, 0x2d00 }, { 5103, 0x0810 }, { 5105, 0x4000 }, { 5106, 0x5020 }, + { 5109, 0x1000 }, { 5110, 0x0450 }, { 5113, 0x3088 }, { 5117, 0x0001 }, + { 5118, 0x0008 }, { 5119, 0x4002 }, { 5121, 0x0012 }, { 5123, 0x0040 }, + /* 0x9400 */ + { 5124, 0x0010 }, { 5125, 0x0100 }, { 5126, 0x0820 }, { 5128, 0x0120 }, + { 5130, 0x0010 }, { 5131, 0x0806 }, { 5134, 0x0000 }, { 5134, 0xa000 }, + { 5136, 0x0000 }, { 5136, 0x0000 }, { 5136, 0x0000 }, { 5136, 0x0000 }, + { 5136, 0x0000 }, { 5136, 0x0000 }, { 5136, 0x0000 }, { 5136, 0x0000 }, + /* 0x9500 */ + { 5136, 0x0000 }, { 5136, 0x0000 }, { 5136, 0x0000 }, { 5136, 0x0000 }, + { 5136, 0x0000 }, { 5136, 0x0000 }, { 5136, 0x0000 }, { 5136, 0x0080 }, + { 5137, 0x8a09 }, { 5142, 0x011e }, { 5147, 0x2138 }, { 5152, 0x1802 }, + { 5155, 0x0480 }, { 5157, 0x1070 }, { 5161, 0x0006 }, { 5163, 0x0000 }, + /* 0x9600 */ + { 5163, 0x0000 }, { 5163, 0x1000 }, { 5164, 0x4402 }, { 5167, 0x8804 }, + { 5170, 0x3815 }, { 5176, 0xf801 }, { 5182, 0x041c }, { 5186, 0x21e9 }, + { 5193, 0x6c60 }, { 5199, 0x1b30 }, { 5205, 0x0588 }, { 5209, 0x0882 }, + { 5212, 0x7af3 }, { 5223, 0x1a60 }, { 5228, 0x870c }, { 5234, 0x0ac5 }, + /* 0x9700 */ + { 5240, 0x00c1 }, { 5243, 0x524a }, { 5249, 0x0080 }, { 5250, 0x2205 }, + { 5254, 0x0114 }, { 5257, 0x5042 }, { 5261, 0x2206 }, { 5265, 0x0490 }, + { 5268, 0xa800 }, { 5271, 0x0000 }, { 5271, 0x2901 }, { 5275, 0x0000 }, + { 5275, 0x0840 }, { 5277, 0x1008 }, { 5279, 0x0000 }, { 5279, 0x8848 }, + /* 0x9800 */ + { 5283, 0x156f }, { 5292, 0x018f }, { 5298, 0x2000 }, { 5299, 0x0b01 }, + { 5303, 0x7040 }, { 5307, 0x4510 }, { 5311, 0x88a0 }, { 5315, 0x0000 }, + { 5315, 0x0000 }, { 5315, 0x0000 }, { 5315, 0x8100 }, { 5317, 0x0002 }, + { 5318, 0x0090 }, { 5320, 0x9800 }, { 5323, 0xe006 }, { 5328, 0x7010 }, + /* 0x9900 */ + { 5332, 0x1608 }, { 5336, 0x4109 }, { 5340, 0x0101 }, { 5342, 0x0000 }, + { 5342, 0x3a20 }, { 5347, 0x0096 }, { 5351, 0x0000 }, { 5351, 0x0000 }, + { 5351, 0x0000 }, { 5351, 0x2240 }, { 5354, 0x7120 }, { 5359, 0x021a }, + { 5363, 0x0002 }, { 5364, 0xa227 }, { 5371, 0x2000 }, { 5372, 0x8002 }, + /* 0x9a00 */ + { 5374, 0xc102 }, { 5378, 0x0200 }, { 5379, 0x0800 }, { 5380, 0x00c1 }, + { 5383, 0x2029 }, { 5387, 0x8ca0 }, { 5392, 0x0624 }, { 5396, 0x0000 }, + { 5396, 0x0000 }, { 5396, 0x0000 }, { 5396, 0x0100 }, { 5397, 0x0100 }, + { 5398, 0x0000 }, { 5398, 0x0118 }, { 5401, 0x4020 }, { 5403, 0x0000 }, + /* 0x9b00 */ + { 5403, 0x0000 }, { 5403, 0x0400 }, { 5404, 0x0480 }, { 5406, 0x1002 }, + { 5408, 0x803e }, { 5414, 0x0410 }, { 5416, 0x8000 }, { 5417, 0x0000 }, + { 5417, 0x4000 }, { 5418, 0x8002 }, { 5420, 0x4800 }, { 5422, 0x0000 }, + { 5422, 0x0200 }, { 5423, 0x0040 }, { 5424, 0x0110 }, { 5426, 0x0000 }, + /* 0x9c00 */ + { 5426, 0x2000 }, { 5427, 0x0025 }, { 5430, 0x0020 }, { 5431, 0x0804 }, + { 5433, 0x0280 }, { 5435, 0x0080 }, { 5436, 0x0000 }, { 5436, 0x0000 }, + { 5436, 0x0000 }, { 5436, 0x0000 }, { 5436, 0x0000 }, { 5436, 0x0000 }, + { 5436, 0x0000 }, { 5436, 0x0000 }, { 5436, 0x02a0 }, { 5439, 0x0058 }, + /* 0x9d00 */ + { 5442, 0x0200 }, { 5443, 0x0800 }, { 5444, 0x0140 }, { 5446, 0x0800 }, + { 5447, 0x0000 }, { 5447, 0x2002 }, { 5449, 0x1003 }, { 5452, 0x0004 }, + { 5453, 0x0000 }, { 5453, 0x0000 }, { 5453, 0x8200 }, { 5455, 0x0010 }, + { 5456, 0x0010 }, { 5457, 0x0080 }, { 5458, 0x0000 }, { 5458, 0x0704 }, + /* 0x9e00 */ + { 5462, 0x0000 }, { 5462, 0x4400 }, { 5464, 0x0000 }, { 5464, 0x0000 }, + { 5464, 0x0000 }, { 5464, 0x0000 }, { 5464, 0x0000 }, { 5464, 0xa220 }, + { 5468, 0x0000 }, { 5468, 0xa08c }, { 5473, 0x0020 }, { 5474, 0x4830 }, + { 5478, 0x6008 }, { 5481, 0x5912 }, { 5487, 0x0100 }, { 5488, 0x0010 }, + /* 0x9f00 */ + { 5489, 0x4180 }, { 5492, 0x0008 }, { 5493, 0x0001 }, { 5494, 0x0800 }, + { 5495, 0x4c00 }, { 5498, 0x8004 }, { 5500, 0x1482 }, { 5504, 0x0080 }, + { 5505, 0x2000 }, { 5506, 0x1021 }, +}; +static const Summary16 ksc5601_uni2indx_pageac[698] = { + /* 0xac00 */ + { 5509, 0x0793 }, { 5516, 0x3eff }, { 5529, 0xb011 }, { 5534, 0x1303 }, + { 5539, 0x2801 }, { 5542, 0x1110 }, { 5545, 0x0000 }, { 5545, 0x0593 }, + { 5551, 0x1e7b }, { 5561, 0xb011 }, { 5566, 0x9703 }, { 5573, 0x3b01 }, + { 5579, 0x1112 }, { 5583, 0x00a0 }, { 5585, 0x9593 }, { 5593, 0x306b }, + /* 0xad00 */ + { 5600, 0xb051 }, { 5606, 0x1102 }, { 5609, 0x3201 }, { 5613, 0x1130 }, + { 5617, 0x02b0 }, { 5621, 0x0111 }, { 5624, 0x300a }, { 5628, 0xb879 }, + { 5637, 0x1306 }, { 5642, 0x3001 }, { 5645, 0x0010 }, { 5646, 0x0080 }, + { 5647, 0x0113 }, { 5651, 0x100b }, { 5655, 0x0011 }, { 5657, 0x9300 }, + /* 0xae00 */ + { 5661, 0x2b03 }, { 5667, 0x0010 }, { 5668, 0x0000 }, { 5668, 0x0593 }, + { 5674, 0x746b }, { 5683, 0xb051 }, { 5689, 0x1323 }, { 5695, 0x3b01 }, + { 5701, 0x1030 }, { 5704, 0x0000 }, { 5704, 0x0000 }, { 5704, 0x7000 }, + { 5707, 0xb011 }, { 5712, 0x1303 }, { 5717, 0x2900 }, { 5720, 0x1110 }, + /* 0xaf00 */ + { 5723, 0x2180 }, { 5726, 0x0001 }, { 5727, 0x3000 }, { 5729, 0xb015 }, + { 5735, 0x030e }, { 5740, 0x3001 }, { 5743, 0x0030 }, { 5745, 0x0200 }, + { 5746, 0x0111 }, { 5749, 0x1023 }, { 5753, 0x0000 }, { 5753, 0x1300 }, + { 5756, 0x6b81 }, { 5763, 0x1010 }, { 5765, 0x0300 }, { 5767, 0x0113 }, + /* 0xb000 */ + { 5771, 0x1013 }, { 5775, 0x3011 }, { 5779, 0x0100 }, { 5780, 0x0000 }, + { 5780, 0x5530 }, { 5786, 0x22b8 }, { 5792, 0x0000 }, { 5792, 0x3000 }, + { 5794, 0xb011 }, { 5799, 0x9702 }, { 5805, 0xfb07 }, { 5815, 0x113a }, + { 5821, 0x03b0 }, { 5826, 0x0113 }, { 5830, 0x0021 }, { 5832, 0x0000 }, + /* 0xb100 */ + { 5832, 0x1b00 }, { 5836, 0x3b0d }, { 5844, 0x1138 }, { 5849, 0x03b0 }, + { 5854, 0x0113 }, { 5858, 0x1133 }, { 5864, 0x0001 }, { 5865, 0x1300 }, + { 5868, 0x2b05 }, { 5874, 0x111c }, { 5879, 0x0100 }, { 5880, 0x0000 }, + { 5880, 0x1000 }, { 5881, 0xb011 }, { 5886, 0x1300 }, { 5889, 0x2a01 }, + /* 0xb200 */ + { 5893, 0x1930 }, { 5898, 0x02b0 }, { 5902, 0x0001 }, { 5903, 0x1010 }, + { 5905, 0x0000 }, { 5905, 0x1100 }, { 5907, 0x0301 }, { 5910, 0x1030 }, + { 5913, 0x0230 }, { 5916, 0x0713 }, { 5922, 0x146b }, { 5929, 0x0011 }, + { 5931, 0x1300 }, { 5934, 0x2b05 }, { 5940, 0xf974 }, { 5950, 0x8fb8 }, + /* 0xb300 */ + { 5959, 0x0113 }, { 5963, 0x103b }, { 5969, 0x0000 }, { 5969, 0x0000 }, + { 5969, 0x0000 }, { 5969, 0xd970 }, { 5977, 0x4ab0 }, { 5983, 0x0113 }, + { 5987, 0x103b }, { 5993, 0x0011 }, { 5995, 0x1103 }, { 5999, 0x0000 }, + { 5999, 0x5930 }, { 6005, 0x2ab1 }, { 6012, 0x0111 }, { 6015, 0x1000 }, + /* 0xb400 */ + { 6016, 0x0000 }, { 6016, 0x1101 }, { 6019, 0x0b01 }, { 6023, 0x0010 }, + { 6024, 0x0000 }, { 6024, 0x0113 }, { 6028, 0x102b }, { 6033, 0x0000 }, + { 6033, 0x0101 }, { 6035, 0x2000 }, { 6036, 0x1110 }, { 6039, 0x02a0 }, + { 6042, 0x0111 }, { 6045, 0x3021 }, { 6049, 0xb059 }, { 6056, 0x0102 }, + /* 0xb500 */ + { 6058, 0x0000 }, { 6058, 0x1930 }, { 6063, 0x07b0 }, { 6069, 0x0113 }, + { 6073, 0x383b }, { 6081, 0xb011 }, { 6086, 0x0003 }, { 6088, 0x0000 }, + { 6088, 0x0000 }, { 6088, 0x0000 }, { 6088, 0x0d13 }, { 6094, 0x383b }, + { 6102, 0xb011 }, { 6107, 0x0103 }, { 6110, 0x1000 }, { 6111, 0x0000 }, + /* 0xb600 */ + { 6111, 0x0000 }, { 6111, 0x0113 }, { 6115, 0x1020 }, { 6117, 0x0010 }, + { 6118, 0x0100 }, { 6119, 0x0000 }, { 6119, 0x0110 }, { 6121, 0x0000 }, + { 6121, 0x0000 }, { 6121, 0x3000 }, { 6123, 0x1811 }, { 6127, 0x0002 }, + { 6128, 0x0000 }, { 6128, 0x0010 }, { 6129, 0x0000 }, { 6129, 0x0111 }, + /* 0xb700 */ + { 6132, 0x0023 }, { 6135, 0x0000 }, { 6135, 0x9300 }, { 6139, 0x0b01 }, + { 6143, 0x1110 }, { 6146, 0x0030 }, { 6148, 0x0111 }, { 6151, 0x302b }, + { 6157, 0xb011 }, { 6162, 0x13c7 }, { 6170, 0x3b01 }, { 6176, 0x0130 }, + { 6179, 0x0280 }, { 6181, 0x0000 }, { 6181, 0x3000 }, { 6183, 0xb011 }, + /* 0xb800 */ + { 6188, 0x1383 }, { 6194, 0x2b01 }, { 6199, 0x1130 }, { 6203, 0x03b0 }, + { 6208, 0x0011 }, { 6210, 0x300a }, { 6214, 0xb011 }, { 6219, 0x1102 }, + { 6222, 0x2000 }, { 6223, 0x0000 }, { 6223, 0x0100 }, { 6224, 0x0111 }, + { 6227, 0x102b }, { 6232, 0xa011 }, { 6236, 0x1302 }, { 6240, 0x2b01 }, + /* 0xb900 */ + { 6245, 0x0010 }, { 6246, 0x0100 }, { 6247, 0x0001 }, { 6248, 0x3000 }, + { 6250, 0x9011 }, { 6254, 0x1302 }, { 6258, 0x2b01 }, { 6263, 0x1130 }, + { 6267, 0x66b0 }, { 6274, 0x0000 }, { 6274, 0x3000 }, { 6276, 0xb011 }, + { 6281, 0xd302 }, { 6287, 0x6b07 }, { 6295, 0x113a }, { 6301, 0x07b0 }, + /* 0xba00 */ + { 6307, 0x0103 }, { 6310, 0x0020 }, { 6311, 0x0000 }, { 6311, 0x1300 }, + { 6314, 0x6b05 }, { 6321, 0x1138 }, { 6326, 0x03b0 }, { 6331, 0x0113 }, + { 6335, 0x10b8 }, { 6340, 0x0000 }, { 6340, 0x1b00 }, { 6344, 0x2b05 }, + { 6350, 0x0110 }, { 6352, 0x0300 }, { 6354, 0x0000 }, { 6354, 0x1000 }, + /* 0xbb00 */ + { 6355, 0xa011 }, { 6359, 0x1102 }, { 6362, 0x0a01 }, { 6365, 0x7970 }, + { 6373, 0xa2b0 }, { 6379, 0x0111 }, { 6382, 0x100a }, { 6385, 0x0000 }, + { 6385, 0x1100 }, { 6387, 0x0001 }, { 6388, 0x1110 }, { 6391, 0x0090 }, + { 6393, 0x0111 }, { 6396, 0x0009 }, { 6398, 0x0000 }, { 6398, 0x9300 }, + /* 0xbc00 */ + { 6402, 0xbb05 }, { 6410, 0xf9f2 }, { 6421, 0x22b0 }, { 6426, 0x0113 }, + { 6430, 0x323b }, { 6438, 0x2001 }, { 6440, 0x0000 }, { 6440, 0x0000 }, + { 6440, 0x5930 }, { 6446, 0x06b0 }, { 6451, 0x0193 }, { 6456, 0x303b }, + { 6463, 0xa011 }, { 6467, 0x1123 }, { 6472, 0x0000 }, { 6472, 0x1170 }, + /* 0xbd00 */ + { 6477, 0x02b0 }, { 6481, 0x0011 }, { 6483, 0x1010 }, { 6485, 0x0000 }, + { 6485, 0x1301 }, { 6489, 0x0301 }, { 6492, 0x0110 }, { 6494, 0x0000 }, + { 6494, 0x0793 }, { 6501, 0x162b }, { 6508, 0x0010 }, { 6509, 0x0101 }, + { 6511, 0x0000 }, { 6511, 0x1130 }, { 6515, 0x0200 }, { 6516, 0x0111 }, + /* 0xbe00 */ + { 6519, 0x3029 }, { 6524, 0xb011 }, { 6529, 0x0000 }, { 6529, 0x0000 }, + { 6529, 0x5130 }, { 6534, 0x0eb0 }, { 6540, 0x0513 }, { 6545, 0x383b }, + { 6553, 0xb011 }, { 6558, 0x0303 }, { 6562, 0x0100 }, { 6563, 0x0000 }, + { 6563, 0x0000 }, { 6563, 0x0193 }, { 6568, 0x1039 }, { 6573, 0x0000 }, + /* 0xbf00 */ + { 6573, 0x0302 }, { 6576, 0x3b00 }, { 6581, 0x0000 }, { 6581, 0x0000 }, + { 6581, 0x0113 }, { 6585, 0x0023 }, { 6588, 0x0000 }, { 6588, 0x0000 }, + { 6588, 0x0000 }, { 6588, 0x0010 }, { 6589, 0x0000 }, { 6589, 0x0001 }, + { 6590, 0x3020 }, { 6593, 0x9011 }, { 6597, 0x0002 }, { 6598, 0x0000 }, + /* 0xc000 */ + { 6598, 0x0000 }, { 6598, 0x0000 }, { 6598, 0x0000 }, { 6598, 0x1000 }, + { 6599, 0x0000 }, { 6599, 0x1102 }, { 6602, 0x0301 }, { 6605, 0x0000 }, + { 6605, 0x0000 }, { 6605, 0x0113 }, { 6609, 0xb02b }, { 6616, 0xb079 }, + { 6624, 0x1323 }, { 6630, 0x3b01 }, { 6636, 0x1130 }, { 6640, 0x02b0 }, + /* 0xc100 */ + { 6644, 0x0111 }, { 6647, 0xf021 }, { 6653, 0xb0d9 }, { 6661, 0x1343 }, + { 6667, 0x3b01 }, { 6673, 0x1130 }, { 6677, 0x03b0 }, { 6682, 0x0111 }, + { 6685, 0x7020 }, { 6689, 0xb051 }, { 6695, 0x1322 }, { 6700, 0x2001 }, + { 6702, 0x1110 }, { 6705, 0x0190 }, { 6708, 0x0111 }, { 6711, 0x300b }, + /* 0xc200 */ + { 6716, 0xb011 }, { 6721, 0x9302 }, { 6726, 0xab01 }, { 6732, 0x0016 }, + { 6735, 0x0100 }, { 6736, 0x0113 }, { 6740, 0x3021 }, { 6744, 0xb011 }, + { 6749, 0x0302 }, { 6752, 0x2901 }, { 6756, 0x3130 }, { 6761, 0x02b0 }, + { 6765, 0x0000 }, { 6765, 0x3000 }, { 6767, 0xb819 }, { 6774, 0x1b42 }, + /* 0xc300 */ + { 6780, 0x3301 }, { 6785, 0x1138 }, { 6790, 0x0330 }, { 6794, 0x0000 }, + { 6794, 0x0020 }, { 6795, 0x0000 }, { 6795, 0x1300 }, { 6798, 0x3305 }, + { 6804, 0x1110 }, { 6807, 0x0000 }, { 6807, 0x0000 }, { 6807, 0x0000 }, + { 6807, 0x0001 }, { 6808, 0x9300 }, { 6812, 0x2305 }, { 6817, 0x0130 }, + /* 0xc400 */ + { 6820, 0x0100 }, { 6821, 0x0001 }, { 6822, 0x1010 }, { 6824, 0x3011 }, + { 6828, 0x0100 }, { 6829, 0x0000 }, { 6829, 0x1130 }, { 6833, 0x0230 }, + { 6836, 0x0001 }, { 6837, 0x1010 }, { 6839, 0x0000 }, { 6839, 0x1100 }, + { 6841, 0x0000 }, { 6841, 0x0000 }, { 6841, 0x0200 }, { 6842, 0x8513 }, + /* 0xc500 */ + { 6848, 0x1003 }, { 6851, 0x1011 }, { 6854, 0x1300 }, { 6857, 0x2b01 }, + { 6862, 0x7730 }, { 6870, 0x63b8 }, { 6878, 0x0113 }, { 6882, 0x303b }, + { 6889, 0xb091 }, { 6895, 0x11a2 }, { 6900, 0x0201 }, { 6902, 0x7b30 }, + { 6910, 0x57f0 }, { 6919, 0x0113 }, { 6923, 0x702b }, { 6930, 0xf0d1 }, + /* 0xc600 */ + { 6938, 0x11e3 }, { 6945, 0x1b01 }, { 6950, 0x7130 }, { 6956, 0x0ab9 }, + { 6963, 0x0113 }, { 6967, 0x303b }, { 6974, 0x9001 }, { 6977, 0x1302 }, + { 6981, 0x2b01 }, { 6986, 0x1130 }, { 6990, 0x02b0 }, { 6994, 0x0713 }, + { 7000, 0x302b }, { 7006, 0x3011 }, { 7010, 0x1303 }, { 7015, 0x2301 }, + /* 0xc700 */ + { 7019, 0x1130 }, { 7023, 0x02b0 }, { 7027, 0x0113 }, { 7031, 0x30ab }, + { 7038, 0xb411 }, { 7044, 0x11fe }, { 7053, 0x0901 }, { 7056, 0x7130 }, + { 7062, 0x47b8 }, { 7070, 0x05d3 }, { 7077, 0x307b }, { 7085, 0xb011 }, + { 7090, 0x5303 }, { 7096, 0x2101 }, { 7099, 0x1110 }, { 7102, 0x0000 }, + /* 0xc800 */ + { 7102, 0x0513 }, { 7107, 0x306b }, { 7114, 0xb011 }, { 7119, 0x1102 }, + { 7122, 0x3301 }, { 7127, 0x0010 }, { 7128, 0x0000 }, { 7128, 0x0513 }, + { 7133, 0x38eb }, { 7142, 0xa010 }, { 7145, 0x0102 }, { 7147, 0x3000 }, + { 7149, 0x1110 }, { 7152, 0x02b0 }, { 7156, 0x0013 }, { 7159, 0x3020 }, + /* 0xc900 */ + { 7162, 0xb071 }, { 7169, 0x0102 }, { 7171, 0x1000 }, { 7172, 0x0010 }, + { 7173, 0x0000 }, { 7173, 0x0113 }, { 7177, 0x100b }, { 7181, 0x1011 }, + { 7184, 0x1300 }, { 7187, 0x2b01 }, { 7192, 0x0000 }, { 7192, 0x0000 }, + { 7192, 0x0593 }, { 7198, 0x366b }, { 7207, 0xb095 }, { 7214, 0x1303 }, + /* 0xca00 */ + { 7219, 0x3b01 }, { 7225, 0x0110 }, { 7227, 0x0200 }, { 7228, 0x0000 }, + { 7228, 0x3000 }, { 7230, 0xb011 }, { 7235, 0x0103 }, { 7238, 0x2000 }, + { 7239, 0x0010 }, { 7240, 0x0100 }, { 7241, 0x0000 }, { 7241, 0x3000 }, + { 7243, 0xb011 }, { 7248, 0x030a }, { 7252, 0x1001 }, { 7254, 0x0010 }, + /* 0xcb00 */ + { 7255, 0x0100 }, { 7256, 0x0111 }, { 7259, 0x0003 }, { 7261, 0x0000 }, + { 7261, 0x1302 }, { 7265, 0x2301 }, { 7269, 0x0010 }, { 7270, 0x0300 }, + { 7272, 0x0000 }, { 7272, 0x1000 }, { 7273, 0x0000 }, { 7273, 0x0100 }, + { 7274, 0x0000 }, { 7274, 0x0010 }, { 7275, 0x0290 }, { 7278, 0x0000 }, + /* 0xcc00 */ + { 7278, 0x3000 }, { 7280, 0x3011 }, { 7284, 0x5386 }, { 7291, 0x7b01 }, + { 7298, 0x1130 }, { 7302, 0x03b0 }, { 7307, 0x0151 }, { 7311, 0x0021 }, + { 7313, 0x0000 }, { 7313, 0x1300 }, { 7316, 0x3b01 }, { 7322, 0x1130 }, + { 7326, 0x02b0 }, { 7330, 0x0011 }, { 7332, 0x1010 }, { 7334, 0x0001 }, + /* 0xcd00 */ + { 7335, 0x1302 }, { 7339, 0x2b01 }, { 7344, 0x1110 }, { 7347, 0x0200 }, + { 7348, 0x0000 }, { 7348, 0x1000 }, { 7349, 0xb011 }, { 7354, 0x0102 }, + { 7356, 0x0100 }, { 7357, 0x1130 }, { 7361, 0x02b0 }, { 7365, 0x0001 }, + { 7366, 0x1010 }, { 7368, 0x0001 }, { 7369, 0x1100 }, { 7371, 0x2b01 }, + /* 0xce00 */ + { 7376, 0x1110 }, { 7379, 0x0210 }, { 7381, 0x0113 }, { 7385, 0x002b }, + { 7389, 0x0000 }, { 7389, 0x9300 }, { 7393, 0x2b03 }, { 7399, 0x1130 }, + { 7403, 0x02b0 }, { 7407, 0x0113 }, { 7411, 0x303b }, { 7418, 0x0000 }, + { 7418, 0x0002 }, { 7419, 0x0000 }, { 7419, 0x1930 }, { 7424, 0x03b0 }, + /* 0xcf00 */ + { 7429, 0x0113 }, { 7433, 0x102b }, { 7438, 0xb011 }, { 7443, 0x0103 }, + { 7446, 0x0000 }, { 7446, 0x1130 }, { 7450, 0x02b0 }, { 7454, 0x0113 }, + { 7458, 0x1021 }, { 7461, 0x0000 }, { 7461, 0x0102 }, { 7463, 0x0001 }, + { 7464, 0x0010 }, { 7465, 0x0000 }, { 7465, 0x0113 }, { 7469, 0x102b }, + /* 0xd000 */ + { 7474, 0x0011 }, { 7476, 0x0102 }, { 7478, 0x2000 }, { 7479, 0x1130 }, + { 7483, 0x02b0 }, { 7487, 0x0111 }, { 7490, 0x3001 }, { 7493, 0x3011 }, + { 7497, 0x0002 }, { 7498, 0x0000 }, { 7498, 0x1130 }, { 7502, 0x02b0 }, + { 7506, 0x0313 }, { 7511, 0x303b }, { 7518, 0xb011 }, { 7523, 0x0103 }, + /* 0xd100 */ + { 7526, 0x2000 }, { 7527, 0x0000 }, { 7527, 0x0000 }, { 7527, 0x0513 }, + { 7532, 0x303b }, { 7539, 0xb011 }, { 7544, 0x1102 }, { 7547, 0x1000 }, + { 7548, 0x0110 }, { 7550, 0x0000 }, { 7550, 0x0113 }, { 7554, 0x142b }, + { 7560, 0x0001 }, { 7561, 0x0100 }, { 7562, 0x0000 }, { 7562, 0x0110 }, + /* 0xd200 */ + { 7564, 0x0280 }, { 7566, 0x0001 }, { 7567, 0x3000 }, { 7569, 0xb011 }, + { 7574, 0x0102 }, { 7576, 0x1000 }, { 7577, 0x0010 }, { 7578, 0x0000 }, + { 7578, 0x0113 }, { 7582, 0x1023 }, { 7586, 0x1011 }, { 7589, 0x9302 }, + { 7594, 0x0b05 }, { 7599, 0x1110 }, { 7602, 0x0030 }, { 7604, 0x0113 }, + /* 0xd300 */ + { 7608, 0x702b }, { 7615, 0xb051 }, { 7621, 0x1323 }, { 7627, 0x3b01 }, + { 7633, 0x0030 }, { 7635, 0x0000 }, { 7635, 0x0000 }, { 7635, 0x3000 }, + { 7637, 0xb011 }, { 7642, 0x1303 }, { 7647, 0x2b01 }, { 7652, 0x1110 }, + { 7655, 0x0330 }, { 7659, 0x0101 }, { 7661, 0x300a }, { 7665, 0xb011 }, + /* 0xd400 */ + { 7670, 0x0102 }, { 7672, 0x2000 }, { 7673, 0x0000 }, { 7673, 0x0000 }, + { 7673, 0x0011 }, { 7675, 0x1000 }, { 7676, 0xa011 }, { 7680, 0x9300 }, + { 7684, 0x2b05 }, { 7690, 0x0010 }, { 7691, 0x0200 }, { 7692, 0x0000 }, + { 7692, 0x1000 }, { 7693, 0x9011 }, { 7697, 0x1100 }, { 7699, 0x2901 }, + /* 0xd500 */ + { 7703, 0x1110 }, { 7706, 0x00b0 }, { 7709, 0x0000 }, { 7709, 0x3000 }, + { 7711, 0xb011 }, { 7716, 0x1302 }, { 7720, 0x2b21 }, { 7726, 0x1130 }, + { 7730, 0x03b0 }, { 7735, 0x0001 }, { 7736, 0x0020 }, { 7737, 0x0000 }, + { 7737, 0x1300 }, { 7740, 0x2b05 }, { 7746, 0x1130 }, { 7750, 0x02b0 }, + /* 0xd600 */ + { 7754, 0x0113 }, { 7758, 0x103b }, { 7764, 0x2011 }, { 7767, 0x1300 }, + { 7770, 0x2b21 }, { 7776, 0x1132 }, { 7781, 0x0280 }, { 7783, 0x0013 }, + { 7786, 0x3028 }, { 7790, 0xa011 }, { 7794, 0x1102 }, { 7797, 0x0a01 }, + { 7800, 0x1130 }, { 7804, 0x0292 }, { 7808, 0x0111 }, { 7811, 0x3021 }, + /* 0xd700 */ + { 7815, 0x0011 }, { 7817, 0x1302 }, { 7821, 0x2b01 }, { 7826, 0x1130 }, + { 7830, 0x0290 }, { 7833, 0x03d3 }, { 7840, 0x122b }, { 7846, 0x3011 }, + { 7850, 0x1302 }, { 7854, 0x2b01 }, +}; +static const Summary16 ksc5601_uni2indx_pagef9[17] = { + /* 0xf900 */ + { 7859, 0xffff }, { 7875, 0xffff }, { 7891, 0xffff }, { 7907, 0xffff }, + { 7923, 0xffff }, { 7939, 0xffff }, { 7955, 0xffff }, { 7971, 0xffff }, + { 7987, 0xffff }, { 8003, 0xffff }, { 8019, 0xffff }, { 8035, 0xffff }, + { 8051, 0xffff }, { 8067, 0xffff }, { 8083, 0xffff }, { 8099, 0xffff }, + /* 0xfa00 */ + { 8115, 0x0fff }, +}; +static const Summary16 ksc5601_uni2indx_pageff[15] = { + /* 0xff00 */ + { 8127, 0xfffe }, { 8142, 0xffff }, { 8158, 0xffff }, { 8174, 0xffff }, + { 8190, 0xffff }, { 8206, 0x7fff }, { 8221, 0x0000 }, { 8221, 0x0000 }, + { 8221, 0x0000 }, { 8221, 0x0000 }, { 8221, 0x0000 }, { 8221, 0x0000 }, + { 8221, 0x0000 }, { 8221, 0x0000 }, { 8221, 0x006f }, +}; + +static int +ksc5601_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + const Summary16 *summary = NULL; + if (wc >= 0x0000 && wc < 0x0460) + summary = &ksc5601_uni2indx_page00[(wc>>4)]; + else if (wc >= 0x2000 && wc < 0x2670) + summary = &ksc5601_uni2indx_page20[(wc>>4)-0x200]; + else if (wc >= 0x3000 && wc < 0x33e0) + summary = &ksc5601_uni2indx_page30[(wc>>4)-0x300]; + else if (wc >= 0x4e00 && wc < 0x9fa0) + summary = &ksc5601_uni2indx_page4e[(wc>>4)-0x4e0]; + else if (wc >= 0xac00 && wc < 0xd7a0) + summary = &ksc5601_uni2indx_pageac[(wc>>4)-0xac0]; + else if (wc >= 0xf900 && wc < 0xfa10) + summary = &ksc5601_uni2indx_pagef9[(wc>>4)-0xf90]; + else if (wc >= 0xff00 && wc < 0xfff0) + summary = &ksc5601_uni2indx_pageff[(wc>>4)-0xff0]; + if (summary) { + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + c = ksc5601_2charset[summary->indx + used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/loop_unicode.h b/libs/libiconv/lib/loop_unicode.h new file mode 100644 index 00000000..1c787b5f --- /dev/null +++ b/libs/libiconv/lib/loop_unicode.h @@ -0,0 +1,527 @@ +/* + * Copyright (C) 1999-2003, 2005-2006, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* This file defines the conversion loop via Unicode as a pivot encoding. */ + +/* Attempt to transliterate wc. Return code as in xxx_wctomb. */ +static int unicode_transliterate (conv_t cd, ucs4_t wc, + unsigned char* outptr, size_t outleft) +{ + if (cd->oflags & HAVE_HANGUL_JAMO) { + /* Decompose Hangul into Jamo. Use double-width Jamo (contained + in all Korean encodings and ISO-2022-JP-2), not half-width Jamo + (contained in Unicode only). */ + ucs4_t buf[3]; + int ret = johab_hangul_decompose(cd,buf,wc); + if (ret != RET_ILUNI) { + /* we know 1 <= ret <= 3 */ + state_t backup_state = cd->ostate; + unsigned char* backup_outptr = outptr; + size_t backup_outleft = outleft; + int i, sub_outcount; + for (i = 0; i < ret; i++) { + if (outleft == 0) { + sub_outcount = RET_TOOSMALL; + goto johab_hangul_failed; + } + sub_outcount = cd->ofuncs.xxx_wctomb(cd,outptr,buf[i],outleft); + if (sub_outcount <= RET_ILUNI) + goto johab_hangul_failed; + if (!(sub_outcount <= outleft)) abort(); + outptr += sub_outcount; outleft -= sub_outcount; + } + return outptr-backup_outptr; + johab_hangul_failed: + cd->ostate = backup_state; + outptr = backup_outptr; + outleft = backup_outleft; + if (sub_outcount != RET_ILUNI) + return RET_TOOSMALL; + } + } + { + /* Try to use a variant, but postfix it with + U+303E IDEOGRAPHIC VARIATION INDICATOR + (cf. Ken Lunde's "CJKV information processing", p. 188). */ + int indx = -1; + if (wc == 0x3006) + indx = 0; + else if (wc == 0x30f6) + indx = 1; + else if (wc >= 0x4e00 && wc < 0xa000) + indx = cjk_variants_indx[wc-0x4e00]; + if (indx >= 0) { + for (;; indx++) { + ucs4_t buf[2]; + unsigned short variant = cjk_variants[indx]; + unsigned short last = variant & 0x8000; + variant &= 0x7fff; + variant += 0x3000; + buf[0] = variant; buf[1] = 0x303e; + { + state_t backup_state = cd->ostate; + unsigned char* backup_outptr = outptr; + size_t backup_outleft = outleft; + int i, sub_outcount; + for (i = 0; i < 2; i++) { + if (outleft == 0) { + sub_outcount = RET_TOOSMALL; + goto variant_failed; + } + sub_outcount = cd->ofuncs.xxx_wctomb(cd,outptr,buf[i],outleft); + if (sub_outcount <= RET_ILUNI) + goto variant_failed; + if (!(sub_outcount <= outleft)) abort(); + outptr += sub_outcount; outleft -= sub_outcount; + } + return outptr-backup_outptr; + variant_failed: + cd->ostate = backup_state; + outptr = backup_outptr; + outleft = backup_outleft; + if (sub_outcount != RET_ILUNI) + return RET_TOOSMALL; + } + if (last) + break; + } + } + } + if (wc >= 0x2018 && wc <= 0x201a) { + /* Special case for quotation marks 0x2018, 0x2019, 0x201a */ + ucs4_t substitute = + (cd->oflags & HAVE_QUOTATION_MARKS + ? (wc == 0x201a ? 0x2018 : wc) + : (cd->oflags & HAVE_ACCENTS + ? (wc==0x2019 ? 0x00b4 : 0x0060) /* use accents */ + : 0x0027 /* use apostrophe */ + ) ); + int outcount = cd->ofuncs.xxx_wctomb(cd,outptr,substitute,outleft); + if (outcount != RET_ILUNI) + return outcount; + } + { + /* Use the transliteration table. */ + int indx = translit_index(wc); + if (indx >= 0) { + const unsigned int * cp = &translit_data[indx]; + unsigned int num = *cp++; + state_t backup_state = cd->ostate; + unsigned char* backup_outptr = outptr; + size_t backup_outleft = outleft; + unsigned int i; + int sub_outcount; + for (i = 0; i < num; i++) { + if (outleft == 0) { + sub_outcount = RET_TOOSMALL; + goto translit_failed; + } + sub_outcount = cd->ofuncs.xxx_wctomb(cd,outptr,cp[i],outleft); + if (sub_outcount == RET_ILUNI) + /* Recursive transliteration. */ + sub_outcount = unicode_transliterate(cd,cp[i],outptr,outleft); + if (sub_outcount <= RET_ILUNI) + goto translit_failed; + if (!(sub_outcount <= outleft)) abort(); + outptr += sub_outcount; outleft -= sub_outcount; + } + return outptr-backup_outptr; + translit_failed: + cd->ostate = backup_state; + outptr = backup_outptr; + outleft = backup_outleft; + if (sub_outcount != RET_ILUNI) + return RET_TOOSMALL; + } + } + return RET_ILUNI; +} + +#ifndef LIBICONV_PLUG + +struct uc_to_mb_fallback_locals { + unsigned char* l_outbuf; + size_t l_outbytesleft; + int l_errno; +}; + +static void uc_to_mb_write_replacement (const char *buf, size_t buflen, + void* callback_arg) +{ + struct uc_to_mb_fallback_locals * plocals = + (struct uc_to_mb_fallback_locals *) callback_arg; + /* Do nothing if already encountered an error in a previous call. */ + if (plocals->l_errno == 0) { + /* Attempt to copy the passed buffer to the output buffer. */ + if (plocals->l_outbytesleft < buflen) + plocals->l_errno = E2BIG; + else { + memcpy(plocals->l_outbuf, buf, buflen); + plocals->l_outbuf += buflen; + plocals->l_outbytesleft -= buflen; + } + } +} + +struct mb_to_uc_fallback_locals { + conv_t l_cd; + unsigned char* l_outbuf; + size_t l_outbytesleft; + int l_errno; +}; + +static void mb_to_uc_write_replacement (const unsigned int *buf, size_t buflen, + void* callback_arg) +{ + struct mb_to_uc_fallback_locals * plocals = + (struct mb_to_uc_fallback_locals *) callback_arg; + /* Do nothing if already encountered an error in a previous call. */ + if (plocals->l_errno == 0) { + /* Attempt to convert the passed buffer to the target encoding. */ + conv_t cd = plocals->l_cd; + unsigned char* outptr = plocals->l_outbuf; + size_t outleft = plocals->l_outbytesleft; + for (; buflen > 0; buf++, buflen--) { + ucs4_t wc = *buf; + int outcount; + if (outleft == 0) { + plocals->l_errno = E2BIG; + break; + } + outcount = cd->ofuncs.xxx_wctomb(cd,outptr,wc,outleft); + if (outcount != RET_ILUNI) + goto outcount_ok; + /* Handle Unicode tag characters (range U+E0000..U+E007F). */ + if ((wc >> 7) == (0xe0000 >> 7)) + goto outcount_zero; + /* Try transliteration. */ + if (cd->transliterate) { + outcount = unicode_transliterate(cd,wc,outptr,outleft); + if (outcount != RET_ILUNI) + goto outcount_ok; + } + if (cd->discard_ilseq) { + outcount = 0; + goto outcount_ok; + } + #ifndef LIBICONV_PLUG + else if (cd->fallbacks.uc_to_mb_fallback != NULL) { + struct uc_to_mb_fallback_locals locals; + locals.l_outbuf = outptr; + locals.l_outbytesleft = outleft; + locals.l_errno = 0; + cd->fallbacks.uc_to_mb_fallback(wc, + uc_to_mb_write_replacement, + &locals, + cd->fallbacks.data); + if (locals.l_errno != 0) { + plocals->l_errno = locals.l_errno; + break; + } + outptr = locals.l_outbuf; + outleft = locals.l_outbytesleft; + outcount = 0; + goto outcount_ok; + } + #endif + outcount = cd->ofuncs.xxx_wctomb(cd,outptr,0xFFFD,outleft); + if (outcount != RET_ILUNI) + goto outcount_ok; + plocals->l_errno = EILSEQ; + break; + outcount_ok: + if (outcount < 0) { + plocals->l_errno = E2BIG; + break; + } + #ifndef LIBICONV_PLUG + if (cd->hooks.uc_hook) + (*cd->hooks.uc_hook)(wc, cd->hooks.data); + #endif + if (!(outcount <= outleft)) abort(); + outptr += outcount; outleft -= outcount; + outcount_zero: ; + } + plocals->l_outbuf = outptr; + plocals->l_outbytesleft = outleft; + } +} + +#endif /* !LIBICONV_PLUG */ + +static size_t unicode_loop_convert (iconv_t icd, + const char* * inbuf, size_t *inbytesleft, + char* * outbuf, size_t *outbytesleft) +{ + conv_t cd = (conv_t) icd; + size_t result = 0; + const unsigned char* inptr = (const unsigned char*) *inbuf; + size_t inleft = *inbytesleft; + unsigned char* outptr = (unsigned char*) *outbuf; + size_t outleft = *outbytesleft; + while (inleft > 0) { + state_t last_istate = cd->istate; + ucs4_t wc; + int incount; + int outcount; + incount = cd->ifuncs.xxx_mbtowc(cd,&wc,inptr,inleft); + if (incount < 0) { + if ((unsigned int)(-1-incount) % 2 == (unsigned int)(-1-RET_ILSEQ) % 2) { + /* Case 1: invalid input, possibly after a shift sequence */ + incount = DECODE_SHIFT_ILSEQ(incount); + if (cd->discard_ilseq) { + switch (cd->iindex) { + case ei_ucs4: case ei_ucs4be: case ei_ucs4le: + case ei_utf32: case ei_utf32be: case ei_utf32le: + case ei_ucs4internal: case ei_ucs4swapped: + incount += 4; break; + case ei_ucs2: case ei_ucs2be: case ei_ucs2le: + case ei_utf16: case ei_utf16be: case ei_utf16le: + case ei_ucs2internal: case ei_ucs2swapped: + incount += 2; break; + default: + incount += 1; break; + } + goto outcount_zero; + } + #ifndef LIBICONV_PLUG + else if (cd->fallbacks.mb_to_uc_fallback != NULL) { + unsigned int incount2; + struct mb_to_uc_fallback_locals locals; + switch (cd->iindex) { + case ei_ucs4: case ei_ucs4be: case ei_ucs4le: + case ei_utf32: case ei_utf32be: case ei_utf32le: + case ei_ucs4internal: case ei_ucs4swapped: + incount2 = 4; break; + case ei_ucs2: case ei_ucs2be: case ei_ucs2le: + case ei_utf16: case ei_utf16be: case ei_utf16le: + case ei_ucs2internal: case ei_ucs2swapped: + incount2 = 2; break; + default: + incount2 = 1; break; + } + locals.l_cd = cd; + locals.l_outbuf = outptr; + locals.l_outbytesleft = outleft; + locals.l_errno = 0; + cd->fallbacks.mb_to_uc_fallback((const char*)inptr+incount, incount2, + mb_to_uc_write_replacement, + &locals, + cd->fallbacks.data); + if (locals.l_errno != 0) { + inptr += incount; inleft -= incount; + errno = locals.l_errno; + result = -1; + break; + } + incount += incount2; + outptr = locals.l_outbuf; + outleft = locals.l_outbytesleft; + result += 1; + goto outcount_zero; + } + #endif + inptr += incount; inleft -= incount; + errno = EILSEQ; + result = -1; + break; + } + if (incount == RET_TOOFEW(0)) { + /* Case 2: not enough bytes available to detect anything */ + errno = EINVAL; + result = -1; + break; + } + /* Case 3: k bytes read, but only a shift sequence */ + incount = DECODE_TOOFEW(incount); + } else { + /* Case 4: k bytes read, making up a wide character */ + if (outleft == 0) { + cd->istate = last_istate; + errno = E2BIG; + result = -1; + break; + } + outcount = cd->ofuncs.xxx_wctomb(cd,outptr,wc,outleft); + if (outcount != RET_ILUNI) + goto outcount_ok; + /* Handle Unicode tag characters (range U+E0000..U+E007F). */ + if ((wc >> 7) == (0xe0000 >> 7)) + goto outcount_zero; + /* Try transliteration. */ + result++; + if (cd->transliterate) { + outcount = unicode_transliterate(cd,wc,outptr,outleft); + if (outcount != RET_ILUNI) + goto outcount_ok; + } + if (cd->discard_ilseq) { + outcount = 0; + goto outcount_ok; + } + #ifndef LIBICONV_PLUG + else if (cd->fallbacks.uc_to_mb_fallback != NULL) { + struct uc_to_mb_fallback_locals locals; + locals.l_outbuf = outptr; + locals.l_outbytesleft = outleft; + locals.l_errno = 0; + cd->fallbacks.uc_to_mb_fallback(wc, + uc_to_mb_write_replacement, + &locals, + cd->fallbacks.data); + if (locals.l_errno != 0) { + cd->istate = last_istate; + errno = locals.l_errno; + return -1; + } + outptr = locals.l_outbuf; + outleft = locals.l_outbytesleft; + outcount = 0; + goto outcount_ok; + } + #endif + outcount = cd->ofuncs.xxx_wctomb(cd,outptr,0xFFFD,outleft); + if (outcount != RET_ILUNI) + goto outcount_ok; + cd->istate = last_istate; + errno = EILSEQ; + result = -1; + break; + outcount_ok: + if (outcount < 0) { + cd->istate = last_istate; + errno = E2BIG; + result = -1; + break; + } + #ifndef LIBICONV_PLUG + if (cd->hooks.uc_hook) + (*cd->hooks.uc_hook)(wc, cd->hooks.data); + #endif + if (!(outcount <= outleft)) abort(); + outptr += outcount; outleft -= outcount; + } + outcount_zero: + if (!(incount <= inleft)) abort(); + inptr += incount; inleft -= incount; + } + *inbuf = (const char*) inptr; + *inbytesleft = inleft; + *outbuf = (char*) outptr; + *outbytesleft = outleft; + return result; +} + +static size_t unicode_loop_reset (iconv_t icd, + char* * outbuf, size_t *outbytesleft) +{ + conv_t cd = (conv_t) icd; + if (outbuf == NULL || *outbuf == NULL) { + /* Reset the states. */ + memset(&cd->istate,'\0',sizeof(state_t)); + memset(&cd->ostate,'\0',sizeof(state_t)); + return 0; + } else { + size_t result = 0; + if (cd->ifuncs.xxx_flushwc) { + state_t last_istate = cd->istate; + ucs4_t wc; + if (cd->ifuncs.xxx_flushwc(cd, &wc)) { + unsigned char* outptr = (unsigned char*) *outbuf; + size_t outleft = *outbytesleft; + int outcount = cd->ofuncs.xxx_wctomb(cd,outptr,wc,outleft); + if (outcount != RET_ILUNI) + goto outcount_ok; + /* Handle Unicode tag characters (range U+E0000..U+E007F). */ + if ((wc >> 7) == (0xe0000 >> 7)) + goto outcount_zero; + /* Try transliteration. */ + result++; + if (cd->transliterate) { + outcount = unicode_transliterate(cd,wc,outptr,outleft); + if (outcount != RET_ILUNI) + goto outcount_ok; + } + if (cd->discard_ilseq) { + outcount = 0; + goto outcount_ok; + } + #ifndef LIBICONV_PLUG + else if (cd->fallbacks.uc_to_mb_fallback != NULL) { + struct uc_to_mb_fallback_locals locals; + locals.l_outbuf = outptr; + locals.l_outbytesleft = outleft; + locals.l_errno = 0; + cd->fallbacks.uc_to_mb_fallback(wc, + uc_to_mb_write_replacement, + &locals, + cd->fallbacks.data); + if (locals.l_errno != 0) { + cd->istate = last_istate; + errno = locals.l_errno; + return -1; + } + outptr = locals.l_outbuf; + outleft = locals.l_outbytesleft; + outcount = 0; + goto outcount_ok; + } + #endif + outcount = cd->ofuncs.xxx_wctomb(cd,outptr,0xFFFD,outleft); + if (outcount != RET_ILUNI) + goto outcount_ok; + cd->istate = last_istate; + errno = EILSEQ; + return -1; + outcount_ok: + if (outcount < 0) { + cd->istate = last_istate; + errno = E2BIG; + return -1; + } + #ifndef LIBICONV_PLUG + if (cd->hooks.uc_hook) + (*cd->hooks.uc_hook)(wc, cd->hooks.data); + #endif + if (!(outcount <= outleft)) abort(); + outptr += outcount; + outleft -= outcount; + outcount_zero: + *outbuf = (char*) outptr; + *outbytesleft = outleft; + } + } + if (cd->ofuncs.xxx_reset) { + unsigned char* outptr = (unsigned char*) *outbuf; + size_t outleft = *outbytesleft; + int outcount = cd->ofuncs.xxx_reset(cd,outptr,outleft); + if (outcount < 0) { + errno = E2BIG; + return -1; + } + if (!(outcount <= outleft)) abort(); + *outbuf = (char*) (outptr + outcount); + *outbytesleft = outleft - outcount; + } + memset(&cd->istate,'\0',sizeof(state_t)); + memset(&cd->ostate,'\0',sizeof(state_t)); + return result; + } +} diff --git a/libs/libiconv/lib/loop_wchar.h b/libs/libiconv/lib/loop_wchar.h new file mode 100644 index 00000000..6dc011b3 --- /dev/null +++ b/libs/libiconv/lib/loop_wchar.h @@ -0,0 +1,474 @@ +/* + * Copyright (C) 2000-2002, 2005-2006, 2008-2009, 2011 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* This file defines three conversion loops: + - from wchar_t to anything else, + - from anything else to wchar_t, + - from wchar_t to wchar_t. + */ + +#if HAVE_WCRTOMB || HAVE_MBRTOWC +/* Tru64 with Desktop Toolkit C has a bug: must be included before + . + BSD/OS 4.0.1 has a bug: , and must be + included before . + In some builds of uClibc, is nonexistent and wchar_t is defined + by . */ +# include +# include +# include +# include +# define BUF_SIZE 64 /* assume MB_LEN_MAX <= 64 */ + /* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */ + extern size_t mbrtowc (); +# ifdef mbstate_t +# define mbrtowc(pwc, s, n, ps) (mbrtowc)(pwc, s, n, 0) +# define mbsinit(ps) 1 +# endif +# ifndef mbsinit +# if !HAVE_MBSINIT +# define mbsinit(ps) 1 +# endif +# endif +#endif + +/* + * The first two conversion loops have an extended conversion descriptor. + */ +struct wchar_conv_struct { + struct conv_struct parent; +#if HAVE_WCRTOMB || HAVE_MBRTOWC + mbstate_t state; +#endif +}; + + +#if HAVE_WCRTOMB + +/* From wchar_t to anything else. */ + +#ifndef LIBICONV_PLUG + +#if 0 + +struct wc_to_mb_fallback_locals { + struct wchar_conv_struct * l_wcd; + char* l_outbuf; + size_t l_outbytesleft; + int l_errno; +}; + +/* A callback that writes a string given in the locale encoding. */ +static void wc_to_mb_write_replacement (const char *buf, size_t buflen, + void* callback_arg) +{ + struct wc_to_mb_fallback_locals * plocals = + (struct wc_to_mb_fallback_locals *) callback_arg; + /* Do nothing if already encountered an error in a previous call. */ + if (plocals->l_errno == 0) { + /* Attempt to convert the passed buffer to the target encoding. + Here we don't support characters split across multiple calls. */ + const char* bufptr = buf; + size_t bufleft = buflen; + size_t res = unicode_loop_convert(&plocals->l_wcd->parent, + &bufptr,&bufleft, + &plocals->l_outbuf,&plocals->l_outbytesleft); + if (res == (size_t)(-1)) { + if (errno == EILSEQ || errno == EINVAL) + /* Invalid buf contents. */ + plocals->l_errno = EILSEQ; + else if (errno == E2BIG) + /* Output buffer too small. */ + plocals->l_errno = E2BIG; + else + abort(); + } else { + /* Successful conversion. */ + if (bufleft > 0) + abort(); + } + } +} + +#else + +struct wc_to_mb_fallback_locals { + char* l_outbuf; + size_t l_outbytesleft; + int l_errno; +}; + +/* A callback that writes a string given in the target encoding. */ +static void wc_to_mb_write_replacement (const char *buf, size_t buflen, + void* callback_arg) +{ + struct wc_to_mb_fallback_locals * plocals = + (struct wc_to_mb_fallback_locals *) callback_arg; + /* Do nothing if already encountered an error in a previous call. */ + if (plocals->l_errno == 0) { + /* Attempt to copy the passed buffer to the output buffer. */ + if (plocals->l_outbytesleft < buflen) + plocals->l_errno = E2BIG; + else { + memcpy(plocals->l_outbuf, buf, buflen); + plocals->l_outbuf += buflen; + plocals->l_outbytesleft -= buflen; + } + } +} + +#endif + +#endif /* !LIBICONV_PLUG */ + +static size_t wchar_from_loop_convert (iconv_t icd, + const char* * inbuf, size_t *inbytesleft, + char* * outbuf, size_t *outbytesleft) +{ + struct wchar_conv_struct * wcd = (struct wchar_conv_struct *) icd; + size_t result = 0; + while (*inbytesleft >= sizeof(wchar_t)) { + const wchar_t * inptr = (const wchar_t *) *inbuf; + size_t inleft = *inbytesleft; + char buf[BUF_SIZE]; + mbstate_t state = wcd->state; + size_t bufcount = 0; + while (inleft >= sizeof(wchar_t)) { + /* Convert one wchar_t to multibyte representation. */ + size_t count = wcrtomb(buf+bufcount,*inptr,&state); + if (count == (size_t)(-1)) { + /* Invalid input. */ + if (wcd->parent.discard_ilseq) { + count = 0; + } + #ifndef LIBICONV_PLUG + else if (wcd->parent.fallbacks.wc_to_mb_fallback != NULL) { + /* Drop the contents of buf[] accumulated so far, and instead + pass all queued wide characters to the fallback handler. */ + struct wc_to_mb_fallback_locals locals; + const wchar_t * fallback_inptr; + #if 0 + locals.l_wcd = wcd; + #endif + locals.l_outbuf = *outbuf; + locals.l_outbytesleft = *outbytesleft; + locals.l_errno = 0; + for (fallback_inptr = (const wchar_t *) *inbuf; + fallback_inptr <= inptr; + fallback_inptr++) + wcd->parent.fallbacks.wc_to_mb_fallback(*fallback_inptr, + wc_to_mb_write_replacement, + &locals, + wcd->parent.fallbacks.data); + if (locals.l_errno != 0) { + errno = locals.l_errno; + return -1; + } + wcd->state = state; + *inbuf = (const char *) (inptr + 1); + *inbytesleft = inleft - sizeof(wchar_t); + *outbuf = locals.l_outbuf; + *outbytesleft = locals.l_outbytesleft; + result += 1; + break; + } + #endif + else { + errno = EILSEQ; + return -1; + } + } + inptr++; + inleft -= sizeof(wchar_t); + bufcount += count; + if (count == 0) { + /* Continue, append next wchar_t. */ + } else { + /* Attempt to convert the accumulated multibyte representations + to the target encoding. */ + const char* bufptr = buf; + size_t bufleft = bufcount; + char* outptr = *outbuf; + size_t outleft = *outbytesleft; + size_t res = unicode_loop_convert(&wcd->parent, + &bufptr,&bufleft, + &outptr,&outleft); + if (res == (size_t)(-1)) { + if (errno == EILSEQ) + /* Invalid input. */ + return -1; + else if (errno == E2BIG) + /* Output buffer too small. */ + return -1; + else if (errno == EINVAL) { + /* Continue, append next wchar_t, but avoid buffer overrun. */ + if (bufcount + MB_CUR_MAX > BUF_SIZE) + abort(); + } else + abort(); + } else { + /* Successful conversion. */ + wcd->state = state; + *inbuf = (const char *) inptr; + *inbytesleft = inleft; + *outbuf = outptr; + *outbytesleft = outleft; + result += res; + break; + } + } + } + } + return result; +} + +static size_t wchar_from_loop_reset (iconv_t icd, + char* * outbuf, size_t *outbytesleft) +{ + struct wchar_conv_struct * wcd = (struct wchar_conv_struct *) icd; + if (outbuf == NULL || *outbuf == NULL) { + /* Reset the states. */ + memset(&wcd->state,'\0',sizeof(mbstate_t)); + return unicode_loop_reset(&wcd->parent,NULL,NULL); + } else { + if (!mbsinit(&wcd->state)) { + mbstate_t state = wcd->state; + char buf[BUF_SIZE]; + size_t bufcount = wcrtomb(buf,(wchar_t)0,&state); + if (bufcount == (size_t)(-1) || bufcount == 0 || buf[bufcount-1] != '\0') + abort(); + else { + const char* bufptr = buf; + size_t bufleft = bufcount-1; + char* outptr = *outbuf; + size_t outleft = *outbytesleft; + size_t res = unicode_loop_convert(&wcd->parent, + &bufptr,&bufleft, + &outptr,&outleft); + if (res == (size_t)(-1)) { + if (errno == E2BIG) + return -1; + else + abort(); + } else { + res = unicode_loop_reset(&wcd->parent,&outptr,&outleft); + if (res == (size_t)(-1)) + return res; + else { + /* Successful. */ + wcd->state = state; + *outbuf = outptr; + *outbytesleft = outleft; + return 0; + } + } + } + } else + return unicode_loop_reset(&wcd->parent,outbuf,outbytesleft); + } +} + +#endif + + +#if HAVE_MBRTOWC + +/* From anything else to wchar_t. */ + +#ifndef LIBICONV_PLUG + +struct mb_to_wc_fallback_locals { + char* l_outbuf; + size_t l_outbytesleft; + int l_errno; +}; + +static void mb_to_wc_write_replacement (const wchar_t *buf, size_t buflen, + void* callback_arg) +{ + struct mb_to_wc_fallback_locals * plocals = + (struct mb_to_wc_fallback_locals *) callback_arg; + /* Do nothing if already encountered an error in a previous call. */ + if (plocals->l_errno == 0) { + /* Attempt to copy the passed buffer to the output buffer. */ + if (plocals->l_outbytesleft < sizeof(wchar_t)*buflen) + plocals->l_errno = E2BIG; + else { + for (; buflen > 0; buf++, buflen--) { + *(wchar_t*) plocals->l_outbuf = *buf; + plocals->l_outbuf += sizeof(wchar_t); + plocals->l_outbytesleft -= sizeof(wchar_t); + } + } + } +} + +#endif /* !LIBICONV_PLUG */ + +static size_t wchar_to_loop_convert (iconv_t icd, + const char* * inbuf, size_t *inbytesleft, + char* * outbuf, size_t *outbytesleft) +{ + struct wchar_conv_struct * wcd = (struct wchar_conv_struct *) icd; + size_t result = 0; + while (*inbytesleft > 0) { + size_t incount; + for (incount = 1; ; ) { + /* Here incount <= *inbytesleft. */ + char buf[BUF_SIZE]; + const char* inptr = *inbuf; + size_t inleft = incount; + char* bufptr = buf; + size_t bufleft = BUF_SIZE; + size_t res = unicode_loop_convert(&wcd->parent, + &inptr,&inleft, + &bufptr,&bufleft); + if (res == (size_t)(-1)) { + if (errno == EILSEQ) + /* Invalid input. */ + return -1; + else if (errno == EINVAL) { + /* Incomplete input. Next try with one more input byte. */ + } else + /* E2BIG shouldn't occur. */ + abort(); + } else { + /* Successful conversion. */ + size_t bufcount = bufptr-buf; /* = BUF_SIZE-bufleft */ + mbstate_t state = wcd->state; + wchar_t wc; + res = mbrtowc(&wc,buf,bufcount,&state); + if (res == (size_t)(-2)) { + /* Next try with one more input byte. */ + } else { + if (res == (size_t)(-1)) { + /* Invalid input. */ + if (wcd->parent.discard_ilseq) { + } + #ifndef LIBICONV_PLUG + else if (wcd->parent.fallbacks.mb_to_wc_fallback != NULL) { + /* Drop the contents of buf[] accumulated so far, and instead + pass all queued chars to the fallback handler. */ + struct mb_to_wc_fallback_locals locals; + locals.l_outbuf = *outbuf; + locals.l_outbytesleft = *outbytesleft; + locals.l_errno = 0; + wcd->parent.fallbacks.mb_to_wc_fallback(*inbuf, incount, + mb_to_wc_write_replacement, + &locals, + wcd->parent.fallbacks.data); + if (locals.l_errno != 0) { + errno = locals.l_errno; + return -1; + } + /* Restoring the state is not needed because it is the initial + state anyway: For all known locale encodings, the multibyte + to wchar_t conversion doesn't have shift state, and we have + excluded partial accumulated characters. */ + /* wcd->state = state; */ + *inbuf += incount; + *inbytesleft -= incount; + *outbuf = locals.l_outbuf; + *outbytesleft = locals.l_outbytesleft; + result += 1; + break; + } + #endif + else + return -1; + } else { + if (*outbytesleft < sizeof(wchar_t)) { + errno = E2BIG; + return -1; + } + *(wchar_t*) *outbuf = wc; + /* Restoring the state is not needed because it is the initial + state anyway: For all known locale encodings, the multibyte + to wchar_t conversion doesn't have shift state, and we have + excluded partial accumulated characters. */ + /* wcd->state = state; */ + *outbuf += sizeof(wchar_t); + *outbytesleft -= sizeof(wchar_t); + } + *inbuf += incount; + *inbytesleft -= incount; + result += res; + break; + } + } + incount++; + if (incount > *inbytesleft) { + /* Incomplete input. */ + errno = EINVAL; + return -1; + } + } + } + return result; +} + +static size_t wchar_to_loop_reset (iconv_t icd, + char* * outbuf, size_t *outbytesleft) +{ + struct wchar_conv_struct * wcd = (struct wchar_conv_struct *) icd; + size_t res = unicode_loop_reset(&wcd->parent,outbuf,outbytesleft); + if (res == (size_t)(-1)) + return res; + memset(&wcd->state,0,sizeof(mbstate_t)); + return 0; +} + +#endif + + +/* From wchar_t to wchar_t. */ + +static size_t wchar_id_loop_convert (iconv_t icd, + const char* * inbuf, size_t *inbytesleft, + char* * outbuf, size_t *outbytesleft) +{ + struct conv_struct * cd = (struct conv_struct *) icd; + const wchar_t* inptr = (const wchar_t*) *inbuf; + size_t inleft = *inbytesleft / sizeof(wchar_t); + wchar_t* outptr = (wchar_t*) *outbuf; + size_t outleft = *outbytesleft / sizeof(wchar_t); + size_t count = (inleft <= outleft ? inleft : outleft); + if (count > 0) { + *inbytesleft -= count * sizeof(wchar_t); + *outbytesleft -= count * sizeof(wchar_t); + do { + wchar_t wc = *inptr++; + *outptr++ = wc; + #ifndef LIBICONV_PLUG + if (cd->hooks.wc_hook) + (*cd->hooks.wc_hook)(wc, cd->hooks.data); + #endif + } while (--count > 0); + *inbuf = (const char*) inptr; + *outbuf = (char*) outptr; + } + return 0; +} + +static size_t wchar_id_loop_reset (iconv_t icd, + char* * outbuf, size_t *outbytesleft) +{ + return 0; +} diff --git a/libs/libiconv/lib/loops.h b/libs/libiconv/lib/loops.h new file mode 100644 index 00000000..782cc092 --- /dev/null +++ b/libs/libiconv/lib/loops.h @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2000 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* This file defines all the loops. */ + +#include "loop_unicode.h" +#include "loop_wchar.h" + diff --git a/libs/libiconv/lib/mac_arabic.h b/libs/libiconv/lib/mac_arabic.h new file mode 100644 index 00000000..9d05a1ab --- /dev/null +++ b/libs/libiconv/lib/mac_arabic.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * MacArabic + */ + +static const unsigned short mac_arabic_2uni[128] = { + /* 0x80 */ + 0x00c4, 0x00a0, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x06ba, 0x00ab, 0x00e7, 0x00e9, 0x00e8, + /* 0x90 */ + 0x00ea, 0x00eb, 0x00ed, 0x2026, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00bb, 0x00f4, 0x00f6, 0x00f7, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + /* 0xa0 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x066a, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x060c, 0xfffd, 0xfffd, 0xfffd, + /* 0xb0 */ + 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, + 0x0668, 0x0669, 0xfffd, 0x061b, 0xfffd, 0xfffd, 0xfffd, 0x061f, + /* 0xc0 */ + 0x066d, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, + 0x0628, 0x0629, 0x062a, 0x062b, 0x062c, 0x062d, 0x062e, 0x062f, + /* 0xd0 */ + 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, + 0x0638, 0x0639, 0x063a, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xe0 */ + 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, + 0x0648, 0x0649, 0x064a, 0x064b, 0x064c, 0x064d, 0x064e, 0x064f, + /* 0xf0 */ + 0x0650, 0x0651, 0x0652, 0x067e, 0x0679, 0x0686, 0x06d5, 0x06a4, + 0x06af, 0x0688, 0x0691, 0xfffd, 0xfffd, 0xfffd, 0x0698, 0x06d2, +}; + +static int +mac_arabic_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = mac_arabic_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char mac_arabic_page00[96] = { + 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x8c, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x82, /* 0xc0-0xc7 */ + 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x88, 0x87, 0x89, 0x00, 0x8a, 0x00, 0x00, 0x8d, /* 0xe0-0xe7 */ + 0x8f, 0x8e, 0x90, 0x91, 0x00, 0x92, 0x94, 0x95, /* 0xe8-0xef */ + 0x00, 0x96, 0x00, 0x97, 0x99, 0x00, 0x9a, 0x9b, /* 0xf0-0xf7 */ + 0x00, 0x9d, 0x9c, 0x9e, 0x9f, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; +static const unsigned char mac_arabic_page06[208] = { + 0x00, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0xbf, /* 0x18-0x1f */ + 0x00, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x30-0x37 */ + 0xd8, 0xd9, 0xda, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x48-0x4f */ + 0xf0, 0xf1, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x60-0x67 */ + 0xb8, 0xb9, 0xa5, 0x00, 0x00, 0xc0, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0xf4, 0x00, 0x00, 0x00, 0x00, 0xf3, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf5, 0x00, /* 0x80-0x87 */ + 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0x00, 0x00, 0xf7, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x8b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0xff, 0x00, 0x00, 0xf6, 0x00, 0x00, /* 0xd0-0xd7 */ +}; + +static int +mac_arabic_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = mac_arabic_page00[wc-0x00a0]; + else if (wc >= 0x0608 && wc < 0x06d8) + c = mac_arabic_page06[wc-0x0608]; + else if (wc == 0x2026) + c = 0x93; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/mac_centraleurope.h b/libs/libiconv/lib/mac_centraleurope.h new file mode 100644 index 00000000..be030cfc --- /dev/null +++ b/libs/libiconv/lib/mac_centraleurope.h @@ -0,0 +1,139 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * MacCentralEurope + */ + +static const unsigned short mac_centraleurope_2uni[128] = { + /* 0x80 */ + 0x00c4, 0x0100, 0x0101, 0x00c9, 0x0104, 0x00d6, 0x00dc, 0x00e1, + 0x0105, 0x010c, 0x00e4, 0x010d, 0x0106, 0x0107, 0x00e9, 0x0179, + /* 0x90 */ + 0x017a, 0x010e, 0x00ed, 0x010f, 0x0112, 0x0113, 0x0116, 0x00f3, + 0x0117, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x011a, 0x011b, 0x00fc, + /* 0xa0 */ + 0x2020, 0x00b0, 0x0118, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x0119, 0x00a8, 0x2260, 0x0123, 0x012e, + /* 0xb0 */ + 0x012f, 0x012a, 0x2264, 0x2265, 0x012b, 0x0136, 0x2202, 0x2211, + 0x0142, 0x013b, 0x013c, 0x013d, 0x013e, 0x0139, 0x013a, 0x0145, + /* 0xc0 */ + 0x0146, 0x0143, 0x00ac, 0x221a, 0x0144, 0x0147, 0x2206, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x0148, 0x0150, 0x00d5, 0x0151, 0x014c, + /* 0xd0 */ + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, + 0x014d, 0x0154, 0x0155, 0x0158, 0x2039, 0x203a, 0x0159, 0x0156, + /* 0xe0 */ + 0x0157, 0x0160, 0x201a, 0x201e, 0x0161, 0x015a, 0x015b, 0x00c1, + 0x0164, 0x0165, 0x00cd, 0x017d, 0x017e, 0x016a, 0x00d3, 0x00d4, + /* 0xf0 */ + 0x016b, 0x016e, 0x00da, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, + 0x00dd, 0x00fd, 0x0137, 0x017b, 0x0141, 0x017c, 0x0122, 0x02c7, +}; + +static int +mac_centraleurope_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) mac_centraleurope_2uni[c-0x80]; + return 1; +} + +static const unsigned char mac_centraleurope_page00[224] = { + 0xca, 0x00, 0x00, 0xa3, 0x00, 0x00, 0x00, 0xa4, /* 0xa0-0xa7 */ + 0xac, 0xa9, 0x00, 0xc7, 0xc2, 0x00, 0xa8, 0x00, /* 0xa8-0xaf */ + 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0xe7, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x83, 0x00, 0x00, 0x00, 0xea, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0xee, 0xef, 0xcd, 0x85, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0xf2, 0x00, 0x86, 0xf8, 0x00, 0xa7, /* 0xd8-0xdf */ + 0x00, 0x87, 0x00, 0x00, 0x8a, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0x00, 0x8e, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x97, 0x99, 0x9b, 0x9a, 0xd6, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x9c, 0x00, 0x9f, 0xf9, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0x81, 0x82, 0x00, 0x00, 0x84, 0x88, 0x8c, 0x8d, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x89, 0x8b, 0x91, 0x93, /* 0x08-0x0f */ + 0x00, 0x00, 0x94, 0x95, 0x00, 0x00, 0x96, 0x98, /* 0x10-0x17 */ + 0xa2, 0xab, 0x9d, 0x9e, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xfe, 0xae, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0xb1, 0xb4, 0x00, 0x00, 0xaf, 0xb0, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb5, 0xfa, /* 0x30-0x37 */ + 0x00, 0xbd, 0xbe, 0xb9, 0xba, 0xbb, 0xbc, 0x00, /* 0x38-0x3f */ + 0x00, 0xfc, 0xb8, 0xc1, 0xc4, 0xbf, 0xc0, 0xc5, /* 0x40-0x47 */ + 0xcb, 0x00, 0x00, 0x00, 0xcf, 0xd8, 0x00, 0x00, /* 0x48-0x4f */ + 0xcc, 0xce, 0x00, 0x00, 0xd9, 0xda, 0xdf, 0xe0, /* 0x50-0x57 */ + 0xdb, 0xde, 0xe5, 0xe6, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xe1, 0xe4, 0x00, 0x00, 0xe8, 0xe9, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0xed, 0xf0, 0x00, 0x00, 0xf1, 0xf3, /* 0x68-0x6f */ + 0xf4, 0xf5, 0xf6, 0xf7, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x8f, 0x90, 0xfb, 0xfd, 0xeb, 0xec, 0x00, /* 0x78-0x7f */ +}; +static const unsigned char mac_centraleurope_page20[48] = { + 0x00, 0x00, 0x00, 0xd0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0xe2, 0x00, 0xd2, 0xd3, 0xe3, 0x00, /* 0x18-0x1f */ + 0xa0, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0xdc, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; +static const unsigned char mac_centraleurope_page22[32] = { + 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xc6, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ +}; +static const unsigned char mac_centraleurope_page22_1[8] = { + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ +}; + +static int +mac_centraleurope_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0180) + c = mac_centraleurope_page00[wc-0x00a0]; + else if (wc == 0x02c7) + c = 0xff; + else if (wc >= 0x2010 && wc < 0x2040) + c = mac_centraleurope_page20[wc-0x2010]; + else if (wc == 0x2122) + c = 0xaa; + else if (wc >= 0x2200 && wc < 0x2220) + c = mac_centraleurope_page22[wc-0x2200]; + else if (wc >= 0x2260 && wc < 0x2268) + c = mac_centraleurope_page22_1[wc-0x2260]; + else if (wc == 0x25ca) + c = 0xd7; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/mac_croatian.h b/libs/libiconv/lib/mac_croatian.h new file mode 100644 index 00000000..582f3e05 --- /dev/null +++ b/libs/libiconv/lib/mac_croatian.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * MacCroatian + */ + +static const unsigned short mac_croatian_2uni[128] = { + /* 0x80 */ + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + /* 0x90 */ + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + /* 0xa0 */ + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x0160, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x017d, 0x00d8, + /* 0xb0 */ + 0x221e, 0x00b1, 0x2264, 0x2265, 0x2206, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x0161, 0x222b, 0x00aa, 0x00ba, 0x2126, 0x017e, 0x00f8, + /* 0xc0 */ + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x0106, 0x00ab, + 0x010c, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, + /* 0xd0 */ + 0x0110, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, + 0xfffd, 0x00a9, 0x2044, 0x00a4, 0x2039, 0x203a, 0x00c6, 0x00bb, + /* 0xe0 */ + 0x2013, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x0107, 0x00c1, + 0x010d, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + /* 0xf0 */ + 0x0111, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc, + 0x00af, 0x03c0, 0x00cb, 0x02da, 0x00b8, 0x00ca, 0x00e6, 0x02c7, +}; + +static int +mac_croatian_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = mac_croatian_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char mac_croatian_page00[248] = { + 0xca, 0xc1, 0xa2, 0xa3, 0xdb, 0x00, 0x00, 0xa4, /* 0xa0-0xa7 */ + 0xac, 0xd9, 0xbb, 0xc7, 0xc2, 0x00, 0xa8, 0xf8, /* 0xa8-0xaf */ + 0xa1, 0xb1, 0x00, 0x00, 0xab, 0xb5, 0xa6, 0xe1, /* 0xb0-0xb7 */ + 0xfc, 0x00, 0xbc, 0xdf, 0x00, 0x00, 0x00, 0xc0, /* 0xb8-0xbf */ + 0xcb, 0xe7, 0xe5, 0xcc, 0x80, 0x81, 0xde, 0x82, /* 0xc0-0xc7 */ + 0xe9, 0x83, 0xfd, 0xfa, 0xed, 0xea, 0xeb, 0xec, /* 0xc8-0xcf */ + 0x00, 0x84, 0xf1, 0xee, 0xef, 0xcd, 0x85, 0x00, /* 0xd0-0xd7 */ + 0xaf, 0xf4, 0xf2, 0xf3, 0x86, 0x00, 0x00, 0xa7, /* 0xd8-0xdf */ + 0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0xfe, 0x8d, /* 0xe0-0xe7 */ + 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, /* 0xe8-0xef */ + 0x00, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0xd6, /* 0xf0-0xf7 */ + 0xbf, 0x9d, 0x9c, 0x9e, 0x9f, 0x00, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xe6, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0xc8, 0xe8, 0x00, 0x00, /* 0x08-0x0f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0xce, 0xcf, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xa9, 0xb9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xae, 0xbe, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char mac_croatian_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xff, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0xfb, 0x00, 0xf7, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char mac_croatian_page20[56] = { + 0x00, 0x00, 0x00, 0xe0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0xe2, 0x00, 0xd2, 0xd3, 0xe3, 0x00, /* 0x18-0x1f */ + 0xa0, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0xdc, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x40-0x47 */ +}; +static const unsigned char mac_croatian_page21[8] = { + 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xbd, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char mac_croatian_page22[104] = { + 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xb4, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, /* 0x08-0x0f */ + 0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xb0, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ +}; + +static int +mac_croatian_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0198) + c = mac_croatian_page00[wc-0x00a0]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = mac_croatian_page02[wc-0x02c0]; + else if (wc == 0x03c0) + c = 0xf9; + else if (wc >= 0x2010 && wc < 0x2048) + c = mac_croatian_page20[wc-0x2010]; + else if (wc >= 0x2120 && wc < 0x2128) + c = mac_croatian_page21[wc-0x2120]; + else if (wc >= 0x2200 && wc < 0x2268) + c = mac_croatian_page22[wc-0x2200]; + else if (wc == 0x25ca) + c = 0xd7; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/mac_cyrillic.h b/libs/libiconv/lib/mac_cyrillic.h new file mode 100644 index 00000000..a5b5972f --- /dev/null +++ b/libs/libiconv/lib/mac_cyrillic.h @@ -0,0 +1,136 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * MacCyrillic + */ + +static const unsigned short mac_cyrillic_2uni[128] = { + /* 0x80 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + /* 0x90 */ + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + /* 0xa0 */ + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x0406, + 0x00ae, 0x00a9, 0x2122, 0x0402, 0x0452, 0x2260, 0x0403, 0x0453, + /* 0xb0 */ + 0x221e, 0x00b1, 0x2264, 0x2265, 0x0456, 0x00b5, 0x2202, 0x0408, + 0x0404, 0x0454, 0x0407, 0x0457, 0x0409, 0x0459, 0x040a, 0x045a, + /* 0xc0 */ + 0x0458, 0x0405, 0x00ac, 0x221a, 0x0192, 0x2248, 0x2206, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x040b, 0x045b, 0x040c, 0x045c, 0x0455, + /* 0xd0 */ + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x201e, + 0x040e, 0x045e, 0x040f, 0x045f, 0x2116, 0x0401, 0x0451, 0x044f, + /* 0xe0 */ + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + /* 0xf0 */ + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x00a4, +}; + +static int +mac_cyrillic_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0x80) + *pwc = (ucs4_t) mac_cyrillic_2uni[c-0x80]; + else + *pwc = (ucs4_t) c; + return 1; +} + +static const unsigned char mac_cyrillic_page00[32] = { + 0xca, 0x00, 0xa2, 0xa3, 0xff, 0x00, 0x00, 0xa4, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xc7, 0xc2, 0x00, 0xa8, 0x00, /* 0xa8-0xaf */ + 0xa1, 0xb1, 0x00, 0x00, 0x00, 0xb5, 0xa6, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char mac_cyrillic_page04[96] = { + 0x00, 0xdd, 0xab, 0xae, 0xb8, 0xc1, 0xa7, 0xba, /* 0x00-0x07 */ + 0xb7, 0xbc, 0xbe, 0xcb, 0xcd, 0x00, 0xd8, 0xda, /* 0x08-0x0f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x10-0x17 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x18-0x1f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x20-0x27 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x28-0x2f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x30-0x37 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x38-0x3f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x40-0x47 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf, /* 0x48-0x4f */ + 0x00, 0xde, 0xac, 0xaf, 0xb9, 0xcf, 0xb4, 0xbb, /* 0x50-0x57 */ + 0xc0, 0xbd, 0xbf, 0xcc, 0xce, 0x00, 0xd9, 0xdb, /* 0x58-0x5f */ +}; +static const unsigned char mac_cyrillic_page20[24] = { + 0x00, 0x00, 0x00, 0xd0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0x00, 0x00, 0xd2, 0xd3, 0xd7, 0x00, /* 0x18-0x1f */ + 0xa0, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char mac_cyrillic_page21[24] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char mac_cyrillic_page22[104] = { + 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xc6, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xb0, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ +}; + +static int +mac_cyrillic_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = mac_cyrillic_page00[wc-0x00a0]; + else if (wc == 0x00f7) + c = 0xd6; + else if (wc == 0x0192) + c = 0xc4; + else if (wc >= 0x0400 && wc < 0x0460) + c = mac_cyrillic_page04[wc-0x0400]; + else if (wc >= 0x2010 && wc < 0x2028) + c = mac_cyrillic_page20[wc-0x2010]; + else if (wc >= 0x2110 && wc < 0x2128) + c = mac_cyrillic_page21[wc-0x2110]; + else if (wc >= 0x2200 && wc < 0x2268) + c = mac_cyrillic_page22[wc-0x2200]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/mac_greek.h b/libs/libiconv/lib/mac_greek.h new file mode 100644 index 00000000..3cc4ac29 --- /dev/null +++ b/libs/libiconv/lib/mac_greek.h @@ -0,0 +1,135 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * MacGreek + */ + +static const unsigned short mac_greek_2uni[128] = { + /* 0x80 */ + 0x00c4, 0x00b9, 0x00b2, 0x00c9, 0x00b3, 0x00d6, 0x00dc, 0x0385, + 0x00e0, 0x00e2, 0x00e4, 0x0384, 0x00a8, 0x00e7, 0x00e9, 0x00e8, + /* 0x90 */ + 0x00ea, 0x00eb, 0x00a3, 0x2122, 0x00ee, 0x00ef, 0x2022, 0x00bd, + 0x2030, 0x00f4, 0x00f6, 0x00a6, 0x00ad, 0x00f9, 0x00fb, 0x00fc, + /* 0xa0 */ + 0x2020, 0x0393, 0x0394, 0x0398, 0x039b, 0x039e, 0x03a0, 0x00df, + 0x00ae, 0x00a9, 0x03a3, 0x03aa, 0x00a7, 0x2260, 0x00b0, 0x0387, + /* 0xb0 */ + 0x0391, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x0392, 0x0395, 0x0396, + 0x0397, 0x0399, 0x039a, 0x039c, 0x03a6, 0x03ab, 0x03a8, 0x03a9, + /* 0xc0 */ + 0x03ac, 0x039d, 0x00ac, 0x039f, 0x03a1, 0x2248, 0x03a4, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x03a5, 0x03a7, 0x0386, 0x0388, 0x0153, + /* 0xd0 */ + 0x2013, 0x2015, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x0389, + 0x038a, 0x038c, 0x038e, 0x03ad, 0x03ae, 0x03af, 0x03cc, 0x038f, + /* 0xe0 */ + 0x03cd, 0x03b1, 0x03b2, 0x03c8, 0x03b4, 0x03b5, 0x03c6, 0x03b3, + 0x03b7, 0x03b9, 0x03be, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03bf, + /* 0xf0 */ + 0x03c0, 0x03ce, 0x03c1, 0x03c3, 0x03c4, 0x03b8, 0x03c9, 0x03c2, + 0x03c7, 0x03c5, 0x03b6, 0x03ca, 0x03cb, 0x0390, 0x03b0, 0xfffd, +}; + +static int +mac_greek_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = mac_greek_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char mac_greek_page00[96] = { + 0xca, 0x00, 0x00, 0x92, 0x00, 0xb4, 0x9b, 0xac, /* 0xa0-0xa7 */ + 0x8c, 0xa9, 0x00, 0xc7, 0xc2, 0x9c, 0xa8, 0x00, /* 0xa8-0xaf */ + 0xae, 0xb1, 0x82, 0x84, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x81, 0x00, 0xc8, 0x00, 0x97, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0xa7, /* 0xd8-0xdf */ + 0x88, 0x00, 0x89, 0x00, 0x8a, 0x00, 0x00, 0x8d, /* 0xe0-0xe7 */ + 0x8f, 0x8e, 0x90, 0x91, 0x00, 0x00, 0x94, 0x95, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x99, 0x00, 0x9a, 0xd6, /* 0xf0-0xf7 */ + 0x00, 0x9d, 0x00, 0x9e, 0x9f, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; +static const unsigned char mac_greek_page03[80] = { + 0x00, 0x00, 0x00, 0x00, 0x8b, 0x87, 0xcd, 0xaf, /* 0x80-0x87 */ + 0xce, 0xd7, 0xd8, 0x00, 0xd9, 0x00, 0xda, 0xdf, /* 0x88-0x8f */ + 0xfd, 0xb0, 0xb5, 0xa1, 0xa2, 0xb6, 0xb7, 0xb8, /* 0x90-0x97 */ + 0xa3, 0xb9, 0xba, 0xa4, 0xbb, 0xc1, 0xa5, 0xc3, /* 0x98-0x9f */ + 0xa6, 0xc4, 0x00, 0xaa, 0xc6, 0xcb, 0xbc, 0xcc, /* 0xa0-0xa7 */ + 0xbe, 0xbf, 0xab, 0xbd, 0xc0, 0xdb, 0xdc, 0xdd, /* 0xa8-0xaf */ + 0xfe, 0xe1, 0xe2, 0xe7, 0xe4, 0xe5, 0xfa, 0xe8, /* 0xb0-0xb7 */ + 0xf5, 0xe9, 0xeb, 0xec, 0xed, 0xee, 0xea, 0xef, /* 0xb8-0xbf */ + 0xf0, 0xf2, 0xf7, 0xf3, 0xf4, 0xf9, 0xe6, 0xf8, /* 0xc0-0xc7 */ + 0xe3, 0xf6, 0xfb, 0xfc, 0xde, 0xe0, 0xf1, 0x00, /* 0xc8-0xcf */ +}; +static const unsigned char mac_greek_page20[40] = { + 0x00, 0x00, 0x00, 0xd0, 0x00, 0xd1, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0x00, 0x00, 0xd2, 0xd3, 0x00, 0x00, /* 0x18-0x1f */ + 0xa0, 0x00, 0x96, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ +}; +static const unsigned char mac_greek_page22[32] = { + 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ +}; + +static int +mac_greek_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = mac_greek_page00[wc-0x00a0]; + else if (wc == 0x0153) + c = 0xcf; + else if (wc >= 0x0380 && wc < 0x03d0) + c = mac_greek_page03[wc-0x0380]; + else if (wc >= 0x2010 && wc < 0x2038) + c = mac_greek_page20[wc-0x2010]; + else if (wc == 0x2122) + c = 0x93; + else if (wc >= 0x2248 && wc < 0x2268) + c = mac_greek_page22[wc-0x2248]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/mac_hebrew.h b/libs/libiconv/lib/mac_hebrew.h new file mode 100644 index 00000000..c7f97bb6 --- /dev/null +++ b/libs/libiconv/lib/mac_hebrew.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * MacHebrew + */ + +static const unsigned short mac_hebrew_2uni[128] = { + /* 0x80 */ + 0x00c4, 0xfb1f, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + /* 0x90 */ + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + /* 0xa0 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x20aa, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xb0 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, + /* 0xc0 */ + 0xfffd, 0x201e, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x05bc, 0xfb4b, + 0xfb35, 0x2026, 0x00a0, 0x05b8, 0x05b7, 0x05b5, 0x05b6, 0x05b4, + /* 0xd0 */ + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0xfb2a, 0xfb2b, + 0x05bf, 0x05b0, 0x05b2, 0x05b1, 0x05bb, 0x05b9, 0xfffd, 0x05b3, + /* 0xe0 */ + 0x05d0, 0x05d1, 0x05d2, 0x05d3, 0x05d4, 0x05d5, 0x05d6, 0x05d7, + 0x05d8, 0x05d9, 0x05da, 0x05db, 0x05dc, 0x05dd, 0x05de, 0x05df, + /* 0xf0 */ + 0x05e0, 0x05e1, 0x05e2, 0x05e3, 0x05e4, 0x05e5, 0x05e6, 0x05e7, + 0x05e8, 0x05e9, 0x05ea, 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0xfffd, +}; + +static int +mac_hebrew_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else if (c >= 0x80) { + unsigned short wc = mac_hebrew_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char mac_hebrew_page00[96] = { + 0xca, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x82, /* 0xc0-0xc7 */ + 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0x00, 0x8d, /* 0xe0-0xe7 */ + 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, /* 0xe8-0xef */ + 0x00, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x9d, 0x9c, 0x9e, 0x9f, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; +static const unsigned char mac_hebrew_page05[64] = { + 0xd9, 0xdb, 0xda, 0xdf, 0xcf, 0xcd, 0xce, 0xcc, /* 0xb0-0xb7 */ + 0xcb, 0xdd, 0x00, 0xdc, 0xc6, 0x00, 0x00, 0xd8, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0xd0-0xd7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0xd8-0xdf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xe0-0xe7 */ + 0xf8, 0xf9, 0xfa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ +}; +static const unsigned char mac_hebrew_page20[24] = { + 0x00, 0x00, 0x00, 0xd0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0x00, 0x00, 0xd2, 0xd3, 0xc1, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char mac_hebrew_pagefb[56] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0xd6, 0xd7, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0xc7, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ +}; + +static int +mac_hebrew_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = mac_hebrew_page00[wc-0x00a0]; + else if (wc >= 0x05b0 && wc < 0x05f0) + c = mac_hebrew_page05[wc-0x05b0]; + else if (wc >= 0x2010 && wc < 0x2028) + c = mac_hebrew_page20[wc-0x2010]; + else if (wc == 0x20aa) + c = 0xa6; + else if (wc >= 0xfb18 && wc < 0xfb50) + c = mac_hebrew_pagefb[wc-0xfb18]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/mac_iceland.h b/libs/libiconv/lib/mac_iceland.h new file mode 100644 index 00000000..b49f1642 --- /dev/null +++ b/libs/libiconv/lib/mac_iceland.h @@ -0,0 +1,162 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * MacIceland + */ + +static const unsigned short mac_iceland_2uni[128] = { + /* 0x80 */ + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + /* 0x90 */ + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + /* 0xa0 */ + 0x00dd, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + /* 0xb0 */ + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x2126, 0x00e6, 0x00f8, + /* 0xc0 */ + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x2206, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, + /* 0xd0 */ + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, + 0x00ff, 0x0178, 0x2044, 0x00a4, 0x00d0, 0x00f0, 0x00de, 0x00fe, + /* 0xe0 */ + 0x00fd, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + /* 0xf0 */ + 0xfffd, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7, +}; + +static int +mac_iceland_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = mac_iceland_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char mac_iceland_page00[96] = { + 0xca, 0xc1, 0xa2, 0xa3, 0xdb, 0xb4, 0x00, 0xa4, /* 0xa0-0xa7 */ + 0xac, 0xa9, 0xbb, 0xc7, 0xc2, 0x00, 0xa8, 0xf8, /* 0xa8-0xaf */ + 0xa1, 0xb1, 0x00, 0x00, 0xab, 0xb5, 0xa6, 0xe1, /* 0xb0-0xb7 */ + 0xfc, 0x00, 0xbc, 0xc8, 0x00, 0x00, 0x00, 0xc0, /* 0xb8-0xbf */ + 0xcb, 0xe7, 0xe5, 0xcc, 0x80, 0x81, 0xae, 0x82, /* 0xc0-0xc7 */ + 0xe9, 0x83, 0xe6, 0xe8, 0xed, 0xea, 0xeb, 0xec, /* 0xc8-0xcf */ + 0xdc, 0x84, 0xf1, 0xee, 0xef, 0xcd, 0x85, 0x00, /* 0xd0-0xd7 */ + 0xaf, 0xf4, 0xf2, 0xf3, 0x86, 0xa0, 0xde, 0xa7, /* 0xd8-0xdf */ + 0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0xbe, 0x8d, /* 0xe0-0xe7 */ + 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, /* 0xe8-0xef */ + 0xdd, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0xd6, /* 0xf0-0xf7 */ + 0xbf, 0x9d, 0x9c, 0x9e, 0x9f, 0xe0, 0xdf, 0xd8, /* 0xf8-0xff */ +}; +static const unsigned char mac_iceland_page01[104] = { + 0x00, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0xce, 0xcf, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char mac_iceland_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xff, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xf9, 0xfa, 0xfb, 0xfe, 0xf7, 0xfd, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char mac_iceland_page20[56] = { + 0x00, 0x00, 0x00, 0xd0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0xe2, 0x00, 0xd2, 0xd3, 0xe3, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x40-0x47 */ +}; +static const unsigned char mac_iceland_page21[8] = { + 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xbd, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char mac_iceland_page22[104] = { + 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xc6, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, /* 0x08-0x0f */ + 0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xb0, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ +}; + +static int +mac_iceland_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = mac_iceland_page00[wc-0x00a0]; + else if (wc >= 0x0130 && wc < 0x0198) + c = mac_iceland_page01[wc-0x0130]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = mac_iceland_page02[wc-0x02c0]; + else if (wc == 0x03c0) + c = 0xb9; + else if (wc >= 0x2010 && wc < 0x2048) + c = mac_iceland_page20[wc-0x2010]; + else if (wc >= 0x2120 && wc < 0x2128) + c = mac_iceland_page21[wc-0x2120]; + else if (wc >= 0x2200 && wc < 0x2268) + c = mac_iceland_page22[wc-0x2200]; + else if (wc == 0x25ca) + c = 0xd7; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/mac_roman.h b/libs/libiconv/lib/mac_roman.h new file mode 100644 index 00000000..7a6d51aa --- /dev/null +++ b/libs/libiconv/lib/mac_roman.h @@ -0,0 +1,167 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * MacRoman + */ + +static const unsigned short mac_roman_2uni[128] = { + /* 0x80 */ + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + /* 0x90 */ + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + /* 0xa0 */ + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + /* 0xb0 */ + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x2126, 0x00e6, 0x00f8, + /* 0xc0 */ + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x2206, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, + /* 0xd0 */ + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, + 0x00ff, 0x0178, 0x2044, 0x00a4, 0x2039, 0x203a, 0xfb01, 0xfb02, + /* 0xe0 */ + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + /* 0xf0 */ + 0xfffd, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7, +}; + +static int +mac_roman_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = mac_roman_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char mac_roman_page00[96] = { + 0xca, 0xc1, 0xa2, 0xa3, 0xdb, 0xb4, 0x00, 0xa4, /* 0xa0-0xa7 */ + 0xac, 0xa9, 0xbb, 0xc7, 0xc2, 0x00, 0xa8, 0xf8, /* 0xa8-0xaf */ + 0xa1, 0xb1, 0x00, 0x00, 0xab, 0xb5, 0xa6, 0xe1, /* 0xb0-0xb7 */ + 0xfc, 0x00, 0xbc, 0xc8, 0x00, 0x00, 0x00, 0xc0, /* 0xb8-0xbf */ + 0xcb, 0xe7, 0xe5, 0xcc, 0x80, 0x81, 0xae, 0x82, /* 0xc0-0xc7 */ + 0xe9, 0x83, 0xe6, 0xe8, 0xed, 0xea, 0xeb, 0xec, /* 0xc8-0xcf */ + 0x00, 0x84, 0xf1, 0xee, 0xef, 0xcd, 0x85, 0x00, /* 0xd0-0xd7 */ + 0xaf, 0xf4, 0xf2, 0xf3, 0x86, 0x00, 0x00, 0xa7, /* 0xd8-0xdf */ + 0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0xbe, 0x8d, /* 0xe0-0xe7 */ + 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, /* 0xe8-0xef */ + 0x00, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0xd6, /* 0xf0-0xf7 */ + 0xbf, 0x9d, 0x9c, 0x9e, 0x9f, 0x00, 0x00, 0xd8, /* 0xf8-0xff */ +}; +static const unsigned char mac_roman_page01[104] = { + 0x00, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0xce, 0xcf, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char mac_roman_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xff, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xf9, 0xfa, 0xfb, 0xfe, 0xf7, 0xfd, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char mac_roman_page20[56] = { + 0x00, 0x00, 0x00, 0xd0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0xe2, 0x00, 0xd2, 0xd3, 0xe3, 0x00, /* 0x18-0x1f */ + 0xa0, 0xe0, 0xa5, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0xdc, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x40-0x47 */ +}; +static const unsigned char mac_roman_page21[8] = { + 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xbd, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char mac_roman_page22[104] = { + 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xc6, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, /* 0x08-0x0f */ + 0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xb0, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ +}; +static const unsigned char mac_roman_pagefb[8] = { + 0x00, 0xde, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ +}; + +static int +mac_roman_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = mac_roman_page00[wc-0x00a0]; + else if (wc >= 0x0130 && wc < 0x0198) + c = mac_roman_page01[wc-0x0130]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = mac_roman_page02[wc-0x02c0]; + else if (wc == 0x03c0) + c = 0xb9; + else if (wc >= 0x2010 && wc < 0x2048) + c = mac_roman_page20[wc-0x2010]; + else if (wc >= 0x2120 && wc < 0x2128) + c = mac_roman_page21[wc-0x2120]; + else if (wc >= 0x2200 && wc < 0x2268) + c = mac_roman_page22[wc-0x2200]; + else if (wc == 0x25ca) + c = 0xd7; + else if (wc >= 0xfb00 && wc < 0xfb08) + c = mac_roman_pagefb[wc-0xfb00]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/mac_romania.h b/libs/libiconv/lib/mac_romania.h new file mode 100644 index 00000000..2d35562d --- /dev/null +++ b/libs/libiconv/lib/mac_romania.h @@ -0,0 +1,165 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * MacRomania + */ + +static const unsigned short mac_romania_2uni[128] = { + /* 0x80 */ + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + /* 0x90 */ + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + /* 0xa0 */ + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x0102, 0x015e, + /* 0xb0 */ + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x2126, 0x0103, 0x015f, + /* 0xc0 */ + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x2206, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, + /* 0xd0 */ + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, + 0x00ff, 0x0178, 0x2044, 0x00a4, 0x2039, 0x203a, 0x0162, 0x0163, + /* 0xe0 */ + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + /* 0xf0 */ + 0xfffd, 0x00d2, 0x00da, 0x00db, 0x00d9, 0x0131, 0x02c6, 0x02dc, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7, +}; + +static int +mac_romania_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = mac_romania_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char mac_romania_page00[248] = { + 0xca, 0xc1, 0xa2, 0xa3, 0xdb, 0xb4, 0x00, 0xa4, /* 0xa0-0xa7 */ + 0xac, 0xa9, 0xbb, 0xc7, 0xc2, 0x00, 0xa8, 0xf8, /* 0xa8-0xaf */ + 0xa1, 0xb1, 0x00, 0x00, 0xab, 0xb5, 0xa6, 0xe1, /* 0xb0-0xb7 */ + 0xfc, 0x00, 0xbc, 0xc8, 0x00, 0x00, 0x00, 0xc0, /* 0xb8-0xbf */ + 0xcb, 0xe7, 0xe5, 0xcc, 0x80, 0x81, 0x00, 0x82, /* 0xc0-0xc7 */ + 0xe9, 0x83, 0xe6, 0xe8, 0xed, 0xea, 0xeb, 0xec, /* 0xc8-0xcf */ + 0x00, 0x84, 0xf1, 0xee, 0xef, 0xcd, 0x85, 0x00, /* 0xd0-0xd7 */ + 0x00, 0xf4, 0xf2, 0xf3, 0x86, 0x00, 0x00, 0xa7, /* 0xd8-0xdf */ + 0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0x00, 0x8d, /* 0xe0-0xe7 */ + 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, /* 0xe8-0xef */ + 0x00, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0xd6, /* 0xf0-0xf7 */ + 0x00, 0x9d, 0x9c, 0x9e, 0x9f, 0x00, 0x00, 0xd8, /* 0xf8-0xff */ + /* 0x0100 */ + 0x00, 0x00, 0xae, 0xbe, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0xce, 0xcf, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0xbf, /* 0x58-0x5f */ + 0x00, 0x00, 0xde, 0xdf, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char mac_romania_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xff, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xf9, 0xfa, 0xfb, 0xfe, 0xf7, 0xfd, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char mac_romania_page20[56] = { + 0x00, 0x00, 0x00, 0xd0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0xe2, 0x00, 0xd2, 0xd3, 0xe3, 0x00, /* 0x18-0x1f */ + 0xa0, 0xe0, 0xa5, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0xdc, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0xda, 0x00, 0x00, 0x00, /* 0x40-0x47 */ +}; +static const unsigned char mac_romania_page21[8] = { + 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xbd, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char mac_romania_page22[104] = { + 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xc6, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, /* 0x08-0x0f */ + 0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xb0, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ +}; + +static int +mac_romania_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0198) + c = mac_romania_page00[wc-0x00a0]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = mac_romania_page02[wc-0x02c0]; + else if (wc == 0x03c0) + c = 0xb9; + else if (wc >= 0x2010 && wc < 0x2048) + c = mac_romania_page20[wc-0x2010]; + else if (wc >= 0x2120 && wc < 0x2128) + c = mac_romania_page21[wc-0x2120]; + else if (wc >= 0x2200 && wc < 0x2268) + c = mac_romania_page22[wc-0x2200]; + else if (wc == 0x25ca) + c = 0xd7; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/mac_thai.h b/libs/libiconv/lib/mac_thai.h new file mode 100644 index 00000000..74d15aaf --- /dev/null +++ b/libs/libiconv/lib/mac_thai.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * MacThai + */ + +static const unsigned short mac_thai_2uni[128] = { + /* 0x80 */ + 0x00ab, 0x00bb, 0x2026, 0xf88c, 0xf88f, 0xf892, 0xf895, 0xf898, + 0xf88b, 0xf88e, 0xf891, 0xf894, 0xf897, 0x201c, 0x201d, 0xf899, + /* 0x90 */ + 0xfffd, 0x2022, 0xf884, 0xf889, 0xf885, 0xf886, 0xf887, 0xf888, + 0xf88a, 0xf88d, 0xf890, 0xf893, 0xf896, 0x2018, 0x2019, 0xfffd, + /* 0xa0 */ + 0x00a0, 0x0e01, 0x0e02, 0x0e03, 0x0e04, 0x0e05, 0x0e06, 0x0e07, + 0x0e08, 0x0e09, 0x0e0a, 0x0e0b, 0x0e0c, 0x0e0d, 0x0e0e, 0x0e0f, + /* 0xb0 */ + 0x0e10, 0x0e11, 0x0e12, 0x0e13, 0x0e14, 0x0e15, 0x0e16, 0x0e17, + 0x0e18, 0x0e19, 0x0e1a, 0x0e1b, 0x0e1c, 0x0e1d, 0x0e1e, 0x0e1f, + /* 0xc0 */ + 0x0e20, 0x0e21, 0x0e22, 0x0e23, 0x0e24, 0x0e25, 0x0e26, 0x0e27, + 0x0e28, 0x0e29, 0x0e2a, 0x0e2b, 0x0e2c, 0x0e2d, 0x0e2e, 0x0e2f, + /* 0xd0 */ + 0x0e30, 0x0e31, 0x0e32, 0x0e33, 0x0e34, 0x0e35, 0x0e36, 0x0e37, + 0x0e38, 0x0e39, 0x0e3a, 0xfeff, 0x200b, 0x2013, 0x2014, 0x0e3f, + /* 0xe0 */ + 0x0e40, 0x0e41, 0x0e42, 0x0e43, 0x0e44, 0x0e45, 0x0e46, 0x0e47, + 0x0e48, 0x0e49, 0x0e4a, 0x0e4b, 0x0e4c, 0x0e4d, 0x2122, 0x0e4f, + /* 0xf0 */ + 0x0e50, 0x0e51, 0x0e52, 0x0e53, 0x0e54, 0x0e55, 0x0e56, 0x0e57, + 0x0e58, 0x0e59, 0x00ae, 0x00a9, 0xfffd, 0xfffd, 0xfffd, 0xfffd, +}; + +static int +mac_thai_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = mac_thai_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char mac_thai_page00[32] = { + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0xfb, 0x00, 0x80, 0x00, 0x00, 0xfa, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x81, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char mac_thai_page0e[96] = { + 0x00, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, /* 0x00-0x07 */ + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, /* 0x08-0x0f */ + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x10-0x17 */ + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0x18-0x1f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x20-0x27 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x28-0x2f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x30-0x37 */ + 0xd8, 0xd9, 0xda, 0x00, 0x00, 0x00, 0x00, 0xdf, /* 0x38-0x3f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x40-0x47 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0x00, 0xef, /* 0x48-0x4f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x50-0x57 */ + 0xf8, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ +}; +static const unsigned char mac_thai_page20[32] = { + 0x00, 0x00, 0x00, 0xdc, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0xdd, 0xde, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x9d, 0x9e, 0x00, 0x00, 0x8d, 0x8e, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x91, 0x00, 0x00, 0x00, 0x82, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char mac_thai_pagef8[32] = { + 0x00, 0x00, 0x00, 0x00, 0x92, 0x94, 0x95, 0x96, /* 0x80-0x87 */ + 0x97, 0x93, 0x98, 0x88, 0x83, 0x99, 0x89, 0x84, /* 0x88-0x8f */ + 0x9a, 0x8a, 0x85, 0x9b, 0x8b, 0x86, 0x9c, 0x8c, /* 0x90-0x97 */ + 0x87, 0x8f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ +}; + +static int +mac_thai_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = mac_thai_page00[wc-0x00a0]; + else if (wc >= 0x0e00 && wc < 0x0e60) + c = mac_thai_page0e[wc-0x0e00]; + else if (wc >= 0x2008 && wc < 0x2028) + c = mac_thai_page20[wc-0x2008]; + else if (wc == 0x2122) + c = 0xee; + else if (wc >= 0xf880 && wc < 0xf8a0) + c = mac_thai_pagef8[wc-0xf880]; + else if (wc == 0xfeff) + c = 0xdb; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/mac_turkish.h b/libs/libiconv/lib/mac_turkish.h new file mode 100644 index 00000000..94f7d376 --- /dev/null +++ b/libs/libiconv/lib/mac_turkish.h @@ -0,0 +1,163 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * MacTurkish + */ + +static const unsigned short mac_turkish_2uni[128] = { + /* 0x80 */ + 0x00c4, 0x00c5, 0x00c7, 0x00c9, 0x00d1, 0x00d6, 0x00dc, 0x00e1, + 0x00e0, 0x00e2, 0x00e4, 0x00e3, 0x00e5, 0x00e7, 0x00e9, 0x00e8, + /* 0x90 */ + 0x00ea, 0x00eb, 0x00ed, 0x00ec, 0x00ee, 0x00ef, 0x00f1, 0x00f3, + 0x00f2, 0x00f4, 0x00f6, 0x00f5, 0x00fa, 0x00f9, 0x00fb, 0x00fc, + /* 0xa0 */ + 0x2020, 0x00b0, 0x00a2, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x00df, + 0x00ae, 0x00a9, 0x2122, 0x00b4, 0x00a8, 0x2260, 0x00c6, 0x00d8, + /* 0xb0 */ + 0x221e, 0x00b1, 0x2264, 0x2265, 0x00a5, 0x00b5, 0x2202, 0x2211, + 0x220f, 0x03c0, 0x222b, 0x00aa, 0x00ba, 0x2126, 0x00e6, 0x00f8, + /* 0xc0 */ + 0x00bf, 0x00a1, 0x00ac, 0x221a, 0x0192, 0x2248, 0x2206, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x00c0, 0x00c3, 0x00d5, 0x0152, 0x0153, + /* 0xd0 */ + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x25ca, + 0x00ff, 0x0178, 0x011e, 0x011f, 0x0130, 0x0131, 0x015e, 0x015f, + /* 0xe0 */ + 0x2021, 0x00b7, 0x201a, 0x201e, 0x2030, 0x00c2, 0x00ca, 0x00c1, + 0x00cb, 0x00c8, 0x00cd, 0x00ce, 0x00cf, 0x00cc, 0x00d3, 0x00d4, + /* 0xf0 */ + 0xfffd, 0x00d2, 0x00da, 0x00db, 0x00d9, 0xfffd, 0x02c6, 0x02dc, + 0x00af, 0x02d8, 0x02d9, 0x02da, 0x00b8, 0x02dd, 0x02db, 0x02c7, +}; + +static int +mac_turkish_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = mac_turkish_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char mac_turkish_page00[96] = { + 0xca, 0xc1, 0xa2, 0xa3, 0x00, 0xb4, 0x00, 0xa4, /* 0xa0-0xa7 */ + 0xac, 0xa9, 0xbb, 0xc7, 0xc2, 0x00, 0xa8, 0xf8, /* 0xa8-0xaf */ + 0xa1, 0xb1, 0x00, 0x00, 0xab, 0xb5, 0xa6, 0xe1, /* 0xb0-0xb7 */ + 0xfc, 0x00, 0xbc, 0xc8, 0x00, 0x00, 0x00, 0xc0, /* 0xb8-0xbf */ + 0xcb, 0xe7, 0xe5, 0xcc, 0x80, 0x81, 0xae, 0x82, /* 0xc0-0xc7 */ + 0xe9, 0x83, 0xe6, 0xe8, 0xed, 0xea, 0xeb, 0xec, /* 0xc8-0xcf */ + 0x00, 0x84, 0xf1, 0xee, 0xef, 0xcd, 0x85, 0x00, /* 0xd0-0xd7 */ + 0xaf, 0xf4, 0xf2, 0xf3, 0x86, 0x00, 0x00, 0xa7, /* 0xd8-0xdf */ + 0x88, 0x87, 0x89, 0x8b, 0x8a, 0x8c, 0xbe, 0x8d, /* 0xe0-0xe7 */ + 0x8f, 0x8e, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95, /* 0xe8-0xef */ + 0x00, 0x96, 0x98, 0x97, 0x99, 0x9b, 0x9a, 0xd6, /* 0xf0-0xf7 */ + 0xbf, 0x9d, 0x9c, 0x9e, 0x9f, 0x00, 0x00, 0xd8, /* 0xf8-0xff */ +}; +static const unsigned char mac_turkish_page01[128] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xda, 0xdb, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xdc, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0xce, 0xcf, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xde, 0xdf, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0xd9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0xc4, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char mac_turkish_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xff, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xf9, 0xfa, 0xfb, 0xfe, 0xf7, 0xfd, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char mac_turkish_page20[40] = { + 0x00, 0x00, 0x00, 0xd0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0xe2, 0x00, 0xd2, 0xd3, 0xe3, 0x00, /* 0x18-0x1f */ + 0xa0, 0xe0, 0xa5, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xe4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ +}; +static const unsigned char mac_turkish_page21[8] = { + 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0xbd, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char mac_turkish_page22[104] = { + 0x00, 0x00, 0xb6, 0x00, 0x00, 0x00, 0xc6, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb8, /* 0x08-0x0f */ + 0x00, 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xb0, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0xba, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ +}; + +static int +mac_turkish_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = mac_turkish_page00[wc-0x00a0]; + else if (wc >= 0x0118 && wc < 0x0198) + c = mac_turkish_page01[wc-0x0118]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = mac_turkish_page02[wc-0x02c0]; + else if (wc == 0x03c0) + c = 0xb9; + else if (wc >= 0x2010 && wc < 0x2038) + c = mac_turkish_page20[wc-0x2010]; + else if (wc >= 0x2120 && wc < 0x2128) + c = mac_turkish_page21[wc-0x2120]; + else if (wc >= 0x2200 && wc < 0x2268) + c = mac_turkish_page22[wc-0x2200]; + else if (wc == 0x25ca) + c = 0xd7; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/mac_ukraine.h b/libs/libiconv/lib/mac_ukraine.h new file mode 100644 index 00000000..8ea17b09 --- /dev/null +++ b/libs/libiconv/lib/mac_ukraine.h @@ -0,0 +1,143 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * MacUkraine + */ + +static const unsigned short mac_ukraine_2uni[128] = { + /* 0x80 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + /* 0x90 */ + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + /* 0xa0 */ + 0x2020, 0x00b0, 0x0490, 0x00a3, 0x00a7, 0x2022, 0x00b6, 0x0406, + 0x00ae, 0x00a9, 0x2122, 0x0402, 0x0452, 0x2260, 0x0403, 0x0453, + /* 0xb0 */ + 0x221e, 0x00b1, 0x2264, 0x2265, 0x0456, 0x00b5, 0x0491, 0x0408, + 0x0404, 0x0454, 0x0407, 0x0457, 0x0409, 0x0459, 0x040a, 0x045a, + /* 0xc0 */ + 0x0458, 0x0405, 0x00ac, 0x221a, 0x0192, 0x2248, 0x2206, 0x00ab, + 0x00bb, 0x2026, 0x00a0, 0x040b, 0x045b, 0x040c, 0x045c, 0x0455, + /* 0xd0 */ + 0x2013, 0x2014, 0x201c, 0x201d, 0x2018, 0x2019, 0x00f7, 0x201e, + 0x040e, 0x045e, 0x040f, 0x045f, 0x2116, 0x0401, 0x0451, 0x044f, + /* 0xe0 */ + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + /* 0xf0 */ + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x00a4, +}; + +static int +mac_ukraine_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0x80) + *pwc = (ucs4_t) mac_ukraine_2uni[c-0x80]; + else + *pwc = (ucs4_t) c; + return 1; +} + +static const unsigned char mac_ukraine_page00[32] = { + 0xca, 0x00, 0x00, 0xa3, 0xff, 0x00, 0x00, 0xa4, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xc7, 0xc2, 0x00, 0xa8, 0x00, /* 0xa8-0xaf */ + 0xa1, 0xb1, 0x00, 0x00, 0x00, 0xb5, 0xa6, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xc8, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char mac_ukraine_page04[152] = { + 0x00, 0xdd, 0xab, 0xae, 0xb8, 0xc1, 0xa7, 0xba, /* 0x00-0x07 */ + 0xb7, 0xbc, 0xbe, 0xcb, 0xcd, 0x00, 0xd8, 0xda, /* 0x08-0x0f */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 0x10-0x17 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0x18-0x1f */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, /* 0x20-0x27 */ + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, /* 0x28-0x2f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x30-0x37 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x38-0x3f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x40-0x47 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xdf, /* 0x48-0x4f */ + 0x00, 0xde, 0xac, 0xaf, 0xb9, 0xcf, 0xb4, 0xbb, /* 0x50-0x57 */ + 0xc0, 0xbd, 0xbf, 0xcc, 0xce, 0x00, 0xd9, 0xdb, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0xa2, 0xb6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char mac_ukraine_page20[24] = { + 0x00, 0x00, 0x00, 0xd0, 0xd1, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0xd4, 0xd5, 0x00, 0x00, 0xd2, 0xd3, 0xd7, 0x00, /* 0x18-0x1f */ + 0xa0, 0x00, 0xa5, 0x00, 0x00, 0x00, 0xc9, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char mac_ukraine_page21[24] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char mac_ukraine_page22[104] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0xc3, 0x00, 0x00, 0x00, 0xb0, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0xc5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0xad, 0x00, 0x00, 0x00, 0xb2, 0xb3, 0x00, 0x00, /* 0x60-0x67 */ +}; + +static int +mac_ukraine_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = mac_ukraine_page00[wc-0x00a0]; + else if (wc == 0x00f7) + c = 0xd6; + else if (wc == 0x0192) + c = 0xc4; + else if (wc >= 0x0400 && wc < 0x0498) + c = mac_ukraine_page04[wc-0x0400]; + else if (wc >= 0x2010 && wc < 0x2028) + c = mac_ukraine_page20[wc-0x2010]; + else if (wc >= 0x2110 && wc < 0x2128) + c = mac_ukraine_page21[wc-0x2110]; + else if (wc >= 0x2200 && wc < 0x2268) + c = mac_ukraine_page22[wc-0x2200]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/mulelao.h b/libs/libiconv/lib/mulelao.h new file mode 100644 index 00000000..abfb5cf0 --- /dev/null +++ b/libs/libiconv/lib/mulelao.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * MULELAO-1 + */ + +static const unsigned short mulelao_2uni[96] = { + /* 0xa0 */ + 0x00a0, 0x0e81, 0x0e82, 0xfffd, 0x0e84, 0xfffd, 0xfffd, 0x0e87, + 0x0e88, 0xfffd, 0x0e8a, 0xfffd, 0xfffd, 0x0e8d, 0xfffd, 0xfffd, + /* 0xb0 */ + 0xfffd, 0xfffd, 0xfffd, 0xfffd, 0x0e94, 0x0e95, 0x0e96, 0x0e97, + 0xfffd, 0x0e99, 0x0e9a, 0x0e9b, 0x0e9c, 0x0e9d, 0x0e9e, 0x0e9f, + /* 0xc0 */ + 0xfffd, 0x0ea1, 0x0ea2, 0x0ea3, 0xfffd, 0x0ea5, 0xfffd, 0x0ea7, + 0xfffd, 0xfffd, 0x0eaa, 0x0eab, 0xfffd, 0x0ead, 0x0eae, 0x0eaf, + /* 0xd0 */ + 0x0eb0, 0x0eb1, 0x0eb2, 0x0eb3, 0x0eb4, 0x0eb5, 0x0eb6, 0x0eb7, + 0x0eb8, 0x0eb9, 0xfffd, 0x0ebb, 0x0ebc, 0x0ebd, 0xfffd, 0xfffd, + /* 0xe0 */ + 0x0ec0, 0x0ec1, 0x0ec2, 0x0ec3, 0x0ec4, 0xfffd, 0x0ec6, 0xfffd, + 0x0ec8, 0x0ec9, 0x0eca, 0x0ecb, 0x0ecc, 0x0ecd, 0xfffd, 0xfffd, + /* 0xf0 */ + 0x0ed0, 0x0ed1, 0x0ed2, 0x0ed3, 0x0ed4, 0x0ed5, 0x0ed6, 0x0ed7, + 0x0ed8, 0x0ed9, 0xfffd, 0xfffd, 0x0edc, 0x0edd, 0xfffd, 0xfffd, +}; + +static int +mulelao_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0xa0) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = mulelao_2uni[c-0xa0]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char mulelao_page0e[96] = { + 0x00, 0xa1, 0xa2, 0x00, 0xa4, 0x00, 0x00, 0xa7, /* 0x80-0x87 */ + 0xa8, 0x00, 0xaa, 0x00, 0x00, 0xad, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0xb4, 0xb5, 0xb6, 0xb7, /* 0x90-0x97 */ + 0x00, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, /* 0x98-0x9f */ + 0x00, 0xc1, 0xc2, 0xc3, 0x00, 0xc5, 0x00, 0xc7, /* 0xa0-0xa7 */ + 0x00, 0x00, 0xca, 0xcb, 0x00, 0xcd, 0xce, 0xcf, /* 0xa8-0xaf */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0xb0-0xb7 */ + 0xd8, 0xd9, 0x00, 0xdb, 0xdc, 0xdd, 0x00, 0x00, /* 0xb8-0xbf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0x00, 0xe6, 0x00, /* 0xc0-0xc7 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0x00, 0x00, /* 0xc8-0xcf */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0xd0-0xd7 */ + 0xf8, 0xf9, 0x00, 0x00, 0xfc, 0xfd, 0x00, 0x00, /* 0xd8-0xdf */ +}; + +static int +mulelao_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x00a0) { + *r = wc; + return 1; + } + else if (wc == 0x00a0) + c = 0xa0; + else if (wc >= 0x0e80 && wc < 0x0ee0) + c = mulelao_page0e[wc-0x0e80]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/nextstep.h b/libs/libiconv/lib/nextstep.h new file mode 100644 index 00000000..ffe41b91 --- /dev/null +++ b/libs/libiconv/lib/nextstep.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * NEXTSTEP + */ + +static const unsigned short nextstep_2uni[128] = { + /* 0x80 */ + 0x00a0, 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + /* 0x90 */ + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d9, + 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00b5, 0x00d7, 0x00f7, + /* 0xa0 */ + 0x00a9, 0x00a1, 0x00a2, 0x00a3, 0x2044, 0x00a5, 0x0192, 0x00a7, + 0x00a4, 0x2019, 0x201c, 0x00ab, 0x2039, 0x203a, 0xfb01, 0xfb02, + /* 0xb0 */ + 0x00ae, 0x2013, 0x2020, 0x2021, 0x00b7, 0x00a6, 0x00b6, 0x2022, + 0x201a, 0x201e, 0x201d, 0x00bb, 0x2026, 0x2030, 0x00ac, 0x00bf, + /* 0xc0 */ + 0x00b9, 0x02cb, 0x00b4, 0x02c6, 0x02dc, 0x00af, 0x02d8, 0x02d9, + 0x00a8, 0x00b2, 0x02da, 0x00b8, 0x00b3, 0x02dd, 0x02db, 0x02c7, + /* 0xd0 */ + 0x2014, 0x00b1, 0x00bc, 0x00bd, 0x00be, 0x00e0, 0x00e1, 0x00e2, + 0x00e3, 0x00e4, 0x00e5, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, + /* 0xe0 */ + 0x00ec, 0x00c6, 0x00ed, 0x00aa, 0x00ee, 0x00ef, 0x00f0, 0x00f1, + 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00f2, 0x00f3, 0x00f4, 0x00f5, + /* 0xf0 */ + 0x00f6, 0x00e6, 0x00f9, 0x00fa, 0x00fb, 0x0131, 0x00fc, 0x00fd, + 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x00ff, 0xfffd, 0xfffd, +}; + +static int +nextstep_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = nextstep_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char nextstep_page00[96] = { + 0x80, 0xa1, 0xa2, 0xa3, 0xa8, 0xa5, 0xb5, 0xa7, /* 0xa0-0xa7 */ + 0xc8, 0xa0, 0xe3, 0xab, 0xbe, 0x00, 0xb0, 0xc5, /* 0xa8-0xaf */ + 0x00, 0xd1, 0xc9, 0xcc, 0xc2, 0x9d, 0xb6, 0xb4, /* 0xb0-0xb7 */ + 0xcb, 0xc0, 0xeb, 0xbb, 0xd2, 0xd3, 0xd4, 0xbf, /* 0xb8-0xbf */ + 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0xe1, 0x87, /* 0xc0-0xc7 */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, /* 0xc8-0xcf */ + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x9e, /* 0xd0-0xd7 */ + 0xe9, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0xfb, /* 0xd8-0xdf */ + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xf1, 0xdb, /* 0xe0-0xe7 */ + 0xdc, 0xdd, 0xde, 0xdf, 0xe0, 0xe2, 0xe4, 0xe5, /* 0xe8-0xef */ + 0xe6, 0xe7, 0xec, 0xed, 0xee, 0xef, 0xf0, 0x9f, /* 0xf0-0xf7 */ + 0xf9, 0xf2, 0xf3, 0xf4, 0xf6, 0xf7, 0xfc, 0xfd, /* 0xf8-0xff */ +}; +static const unsigned char nextstep_page01[104] = { + 0x00, 0xf5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0xe8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0xea, 0xfa, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0xa6, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ +}; +static const unsigned char nextstep_page02[32] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xcf, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0xc1, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xc6, 0xc7, 0xca, 0xce, 0xc4, 0xcd, 0x00, 0x00, /* 0xd8-0xdf */ +}; +static const unsigned char nextstep_page20[56] = { + 0x00, 0x00, 0x00, 0xb1, 0xd0, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0xa9, 0xb8, 0x00, 0xaa, 0xba, 0xb9, 0x00, /* 0x18-0x1f */ + 0xb2, 0xb3, 0xb7, 0x00, 0x00, 0x00, 0xbc, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0xac, 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0xa4, 0x00, 0x00, 0x00, /* 0x40-0x47 */ +}; +static const unsigned char nextstep_pagefb[8] = { + 0x00, 0xae, 0xaf, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ +}; + +static int +nextstep_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x0100) + c = nextstep_page00[wc-0x00a0]; + else if (wc >= 0x0130 && wc < 0x0198) + c = nextstep_page01[wc-0x0130]; + else if (wc >= 0x02c0 && wc < 0x02e0) + c = nextstep_page02[wc-0x02c0]; + else if (wc >= 0x2010 && wc < 0x2048) + c = nextstep_page20[wc-0x2010]; + else if (wc >= 0xfb00 && wc < 0xfb08) + c = nextstep_pagefb[wc-0xfb00]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/pt154.h b/libs/libiconv/lib/pt154.h new file mode 100644 index 00000000..36a5d84f --- /dev/null +++ b/libs/libiconv/lib/pt154.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 1999-2005 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * PT154 + */ + +static const unsigned short pt154_2uni[64] = { + /* 0x80 */ + 0x0496, 0x0492, 0x04ee, 0x0493, 0x201e, 0x2026, 0x04b6, 0x04ae, + 0x04b2, 0x04af, 0x04a0, 0x04e2, 0x04a2, 0x049a, 0x04ba, 0x04b8, + /* 0x90 */ + 0x0497, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x04b3, 0x04b7, 0x04a1, 0x04e3, 0x04a3, 0x049b, 0x04bb, 0x04b9, + /* 0xa0 */ + 0x00a0, 0x040e, 0x045e, 0x0408, 0x04e8, 0x0498, 0x04b0, 0x00a7, + 0x0401, 0x00a9, 0x04d8, 0x00ab, 0x00ac, 0x04ef, 0x00ae, 0x049c, + /* 0xb0 */ + 0x00b0, 0x04b1, 0x0406, 0x0456, 0x0499, 0x04e9, 0x00b6, 0x00b7, + 0x0451, 0x2116, 0x04d9, 0x00bb, 0x0458, 0x04aa, 0x04ab, 0x049d, +}; + +static int +pt154_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) + *pwc = (ucs4_t) c; + else if (c >= 0xc0) + *pwc = (ucs4_t) c + 0x0350; + else + *pwc = (ucs4_t) pt154_2uni[c-0x80]; + return 1; +} + +static const unsigned char pt154_page00[32] = { + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xab, 0xac, 0x00, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char pt154_page04[240] = { + 0x00, 0xa8, 0x00, 0x00, 0x00, 0x00, 0xb2, 0x00, /* 0x00-0x07 */ + 0xa3, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa1, 0x00, /* 0x08-0x0f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x10-0x17 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x18-0x1f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x20-0x27 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0x28-0x2f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x30-0x37 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x38-0x3f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x40-0x47 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0x48-0x4f */ + 0x00, 0xb8, 0x00, 0x00, 0x00, 0x00, 0xb3, 0x00, /* 0x50-0x57 */ + 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa2, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x81, 0x83, 0x00, 0x00, 0x80, 0x90, /* 0x90-0x97 */ + 0xa5, 0xb4, 0x8d, 0x9d, 0xaf, 0xbf, 0x00, 0x00, /* 0x98-0x9f */ + 0x8a, 0x9a, 0x8c, 0x9c, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0xbd, 0xbe, 0x00, 0x00, 0x87, 0x89, /* 0xa8-0xaf */ + 0xa6, 0xb1, 0x88, 0x98, 0x00, 0x00, 0x86, 0x99, /* 0xb0-0xb7 */ + 0x8f, 0x9f, 0x8e, 0x9e, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xaa, 0xba, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0xa4, 0xb5, 0x00, 0x00, 0x00, 0x00, 0x82, 0xad, /* 0xe8-0xef */ +}; +static const unsigned char pt154_page20[24] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x00, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ +}; + +static int +pt154_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = pt154_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x04f0) + c = pt154_page04[wc-0x0400]; + else if (wc >= 0x2010 && wc < 0x2028) + c = pt154_page20[wc-0x2010]; + else if (wc == 0x2116) + c = 0xb9; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/relocatable.c b/libs/libiconv/lib/relocatable.c new file mode 100644 index 00000000..a7bbd99d --- /dev/null +++ b/libs/libiconv/lib/relocatable.c @@ -0,0 +1,483 @@ +/* Provide relocatable packages. + Copyright (C) 2003-2006, 2008-2011 Free Software Foundation, Inc. + Written by Bruno Haible , 2003. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + + +/* Tell glibc's to provide a prototype for getline(). + This must come before because may include + , and once has been included, it's too late. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif + +#define _GL_USE_STDLIB_ALLOC 1 +#include + +/* Specification. */ +#include "relocatable.h" + +#if ENABLE_RELOCATABLE + +#include +#include +#include +#include + +#ifdef NO_XMALLOC +# define xmalloc malloc +#else +# include "xalloc.h" +#endif + +#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ +# define WIN32_LEAN_AND_MEAN +# include +#endif + +#if DEPENDS_ON_LIBCHARSET +# include +#endif +#if DEPENDS_ON_LIBICONV && HAVE_ICONV +# include +#endif +#if DEPENDS_ON_LIBINTL && ENABLE_NLS +# include +#endif + +/* Faked cheap 'bool'. */ +#undef bool +#undef false +#undef true +#define bool int +#define false 0 +#define true 1 + +/* Pathname support. + ISSLASH(C) tests whether C is a directory separator character. + IS_PATH_WITH_DIR(P) tests whether P contains a directory specification. + */ +#if ((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) || defined __EMX__ || defined __DJGPP__ + /* Win32, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +# define HAS_DEVICE(P) \ + ((((P)[0] >= 'A' && (P)[0] <= 'Z') || ((P)[0] >= 'a' && (P)[0] <= 'z')) \ + && (P)[1] == ':') +# define IS_PATH_WITH_DIR(P) \ + (strchr (P, '/') != NULL || strchr (P, '\\') != NULL || HAS_DEVICE (P)) +# define FILE_SYSTEM_PREFIX_LEN(P) (HAS_DEVICE (P) ? 2 : 0) +#else + /* Unix */ +# define ISSLASH(C) ((C) == '/') +# define IS_PATH_WITH_DIR(P) (strchr (P, '/') != NULL) +# define FILE_SYSTEM_PREFIX_LEN(P) 0 +#endif + +/* Original installation prefix. */ +static char *orig_prefix; +static size_t orig_prefix_len; +/* Current installation prefix. */ +static char *curr_prefix; +static size_t curr_prefix_len; +/* These prefixes do not end in a slash. Anything that will be concatenated + to them must start with a slash. */ + +/* Sets the original and the current installation prefix of this module. + Relocation simply replaces a pathname starting with the original prefix + by the corresponding pathname with the current prefix instead. Both + prefixes should be directory names without trailing slash (i.e. use "" + instead of "/"). */ +static void +set_this_relocation_prefix (const char *orig_prefix_arg, + const char *curr_prefix_arg) +{ + if (orig_prefix_arg != NULL && curr_prefix_arg != NULL + /* Optimization: if orig_prefix and curr_prefix are equal, the + relocation is a nop. */ + && strcmp (orig_prefix_arg, curr_prefix_arg) != 0) + { + /* Duplicate the argument strings. */ + char *memory; + + orig_prefix_len = strlen (orig_prefix_arg); + curr_prefix_len = strlen (curr_prefix_arg); + memory = (char *) xmalloc (orig_prefix_len + 1 + curr_prefix_len + 1); +#ifdef NO_XMALLOC + if (memory != NULL) +#endif + { + memcpy (memory, orig_prefix_arg, orig_prefix_len + 1); + orig_prefix = memory; + memory += orig_prefix_len + 1; + memcpy (memory, curr_prefix_arg, curr_prefix_len + 1); + curr_prefix = memory; + return; + } + } + orig_prefix = NULL; + curr_prefix = NULL; + /* Don't worry about wasted memory here - this function is usually only + called once. */ +} + +/* Sets the original and the current installation prefix of the package. + Relocation simply replaces a pathname starting with the original prefix + by the corresponding pathname with the current prefix instead. Both + prefixes should be directory names without trailing slash (i.e. use "" + instead of "/"). */ +void +set_relocation_prefix (const char *orig_prefix_arg, const char *curr_prefix_arg) +{ + set_this_relocation_prefix (orig_prefix_arg, curr_prefix_arg); + + /* Now notify all dependent libraries. */ +#if DEPENDS_ON_LIBCHARSET + libcharset_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg); +#endif +#if DEPENDS_ON_LIBICONV && HAVE_ICONV && _LIBICONV_VERSION >= 0x0109 + libiconv_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg); +#endif +#if DEPENDS_ON_LIBINTL && ENABLE_NLS && defined libintl_set_relocation_prefix + libintl_set_relocation_prefix (orig_prefix_arg, curr_prefix_arg); +#endif +} + +#if !defined IN_LIBRARY || (defined PIC && defined INSTALLDIR) + +/* Convenience function: + Computes the current installation prefix, based on the original + installation prefix, the original installation directory of a particular + file, and the current pathname of this file. + Returns it, freshly allocated. Returns NULL upon failure. */ +#ifdef IN_LIBRARY +#define compute_curr_prefix local_compute_curr_prefix +static +#endif +char * +compute_curr_prefix (const char *orig_installprefix, + const char *orig_installdir, + const char *curr_pathname) +{ + char *curr_installdir; + const char *rel_installdir; + + if (curr_pathname == NULL) + return NULL; + + /* Determine the relative installation directory, relative to the prefix. + This is simply the difference between orig_installprefix and + orig_installdir. */ + if (strncmp (orig_installprefix, orig_installdir, strlen (orig_installprefix)) + != 0) + /* Shouldn't happen - nothing should be installed outside $(prefix). */ + return NULL; + rel_installdir = orig_installdir + strlen (orig_installprefix); + + /* Determine the current installation directory. */ + { + const char *p_base = curr_pathname + FILE_SYSTEM_PREFIX_LEN (curr_pathname); + const char *p = curr_pathname + strlen (curr_pathname); + char *q; + + while (p > p_base) + { + p--; + if (ISSLASH (*p)) + break; + } + + q = (char *) xmalloc (p - curr_pathname + 1); +#ifdef NO_XMALLOC + if (q == NULL) + return NULL; +#endif + memcpy (q, curr_pathname, p - curr_pathname); + q[p - curr_pathname] = '\0'; + curr_installdir = q; + } + + /* Compute the current installation prefix by removing the trailing + rel_installdir from it. */ + { + const char *rp = rel_installdir + strlen (rel_installdir); + const char *cp = curr_installdir + strlen (curr_installdir); + const char *cp_base = + curr_installdir + FILE_SYSTEM_PREFIX_LEN (curr_installdir); + + while (rp > rel_installdir && cp > cp_base) + { + bool same = false; + const char *rpi = rp; + const char *cpi = cp; + + while (rpi > rel_installdir && cpi > cp_base) + { + rpi--; + cpi--; + if (ISSLASH (*rpi) || ISSLASH (*cpi)) + { + if (ISSLASH (*rpi) && ISSLASH (*cpi)) + same = true; + break; + } + /* Do case-insensitive comparison if the file system is always or + often case-insensitive. It's better to accept the comparison + if the difference is only in case, rather than to fail. */ +#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ + /* Win32, Cygwin, OS/2, DOS - case insignificant file system */ + if ((*rpi >= 'a' && *rpi <= 'z' ? *rpi - 'a' + 'A' : *rpi) + != (*cpi >= 'a' && *cpi <= 'z' ? *cpi - 'a' + 'A' : *cpi)) + break; +#else + if (*rpi != *cpi) + break; +#endif + } + if (!same) + break; + /* The last pathname component was the same. opi and cpi now point + to the slash before it. */ + rp = rpi; + cp = cpi; + } + + if (rp > rel_installdir) + { + /* Unexpected: The curr_installdir does not end with rel_installdir. */ + free (curr_installdir); + return NULL; + } + + { + size_t curr_prefix_len = cp - curr_installdir; + char *curr_prefix; + + curr_prefix = (char *) xmalloc (curr_prefix_len + 1); +#ifdef NO_XMALLOC + if (curr_prefix == NULL) + { + free (curr_installdir); + return NULL; + } +#endif + memcpy (curr_prefix, curr_installdir, curr_prefix_len); + curr_prefix[curr_prefix_len] = '\0'; + + free (curr_installdir); + + return curr_prefix; + } + } +} + +#endif /* !IN_LIBRARY || PIC */ + +#if defined PIC && defined INSTALLDIR + +/* Full pathname of shared library, or NULL. */ +static char *shared_library_fullname; + +#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ +/* Native Win32 only. + On Cygwin, it is better to use the Cygwin provided /proc interface, than + to use native Win32 API and cygwin_conv_to_posix_path, because it supports + longer file names + (see ). */ + +/* Determine the full pathname of the shared library when it is loaded. */ + +BOOL WINAPI +DllMain (HINSTANCE module_handle, DWORD event, LPVOID reserved) +{ + (void) reserved; + + if (event == DLL_PROCESS_ATTACH) + { + /* The DLL is being loaded into an application's address range. */ + static char location[MAX_PATH]; + + if (!GetModuleFileName (module_handle, location, sizeof (location))) + /* Shouldn't happen. */ + return FALSE; + + if (!IS_PATH_WITH_DIR (location)) + /* Shouldn't happen. */ + return FALSE; + + shared_library_fullname = strdup (location); + } + + return TRUE; +} + +#else /* Unix */ + +static void +find_shared_library_fullname () +{ +#if (defined __linux__ && (__GLIBC__ >= 2 || defined __UCLIBC__)) || defined __CYGWIN__ + /* Linux has /proc/self/maps. glibc 2 and uClibc have the getline() + function. + Cygwin >= 1.5 has /proc/self/maps and the getline() function too. */ + FILE *fp; + + /* Open the current process' maps file. It describes one VMA per line. */ + fp = fopen ("/proc/self/maps", "r"); + if (fp) + { + unsigned long address = (unsigned long) &find_shared_library_fullname; + for (;;) + { + unsigned long start, end; + int c; + + if (fscanf (fp, "%lx-%lx", &start, &end) != 2) + break; + if (address >= start && address <= end - 1) + { + /* Found it. Now see if this line contains a filename. */ + while (c = getc (fp), c != EOF && c != '\n' && c != '/') + continue; + if (c == '/') + { + size_t size; + int len; + + ungetc (c, fp); + shared_library_fullname = NULL; size = 0; + len = getline (&shared_library_fullname, &size, fp); + if (len >= 0) + { + /* Success: filled shared_library_fullname. */ + if (len > 0 && shared_library_fullname[len - 1] == '\n') + shared_library_fullname[len - 1] = '\0'; + } + } + break; + } + while (c = getc (fp), c != EOF && c != '\n') + continue; + } + fclose (fp); + } +#endif +} + +#endif /* WIN32 / Unix */ + +/* Return the full pathname of the current shared library. + Return NULL if unknown. + Guaranteed to work only on Linux, Cygwin and Woe32. */ +static char * +get_shared_library_fullname () +{ +#if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) + static bool tried_find_shared_library_fullname; + if (!tried_find_shared_library_fullname) + { + find_shared_library_fullname (); + tried_find_shared_library_fullname = true; + } +#endif + return shared_library_fullname; +} + +#endif /* PIC */ + +/* Returns the pathname, relocated according to the current installation + directory. + The returned string is either PATHNAME unmodified or a freshly allocated + string that you can free with free() after casting it to 'char *'. */ +const char * +relocate (const char *pathname) +{ +#if defined PIC && defined INSTALLDIR + static int initialized; + + /* Initialization code for a shared library. */ + if (!initialized) + { + /* At this point, orig_prefix and curr_prefix likely have already been + set through the main program's set_program_name_and_installdir + function. This is sufficient in the case that the library has + initially been installed in the same orig_prefix. But we can do + better, to also cover the cases that 1. it has been installed + in a different prefix before being moved to orig_prefix and (later) + to curr_prefix, 2. unlike the program, it has not moved away from + orig_prefix. */ + const char *orig_installprefix = INSTALLPREFIX; + const char *orig_installdir = INSTALLDIR; + char *curr_prefix_better; + + curr_prefix_better = + compute_curr_prefix (orig_installprefix, orig_installdir, + get_shared_library_fullname ()); + + set_relocation_prefix (orig_installprefix, + curr_prefix_better != NULL + ? curr_prefix_better + : curr_prefix); + + if (curr_prefix_better != NULL) + free (curr_prefix_better); + + initialized = 1; + } +#endif + + /* Note: It is not necessary to perform case insensitive comparison here, + even for DOS-like file systems, because the pathname argument was + typically created from the same Makefile variable as orig_prefix came + from. */ + if (orig_prefix != NULL && curr_prefix != NULL + && strncmp (pathname, orig_prefix, orig_prefix_len) == 0) + { + if (pathname[orig_prefix_len] == '\0') + { + /* pathname equals orig_prefix. */ + char *result = (char *) xmalloc (strlen (curr_prefix) + 1); + +#ifdef NO_XMALLOC + if (result != NULL) +#endif + { + strcpy (result, curr_prefix); + return result; + } + } + else if (ISSLASH (pathname[orig_prefix_len])) + { + /* pathname starts with orig_prefix. */ + const char *pathname_tail = &pathname[orig_prefix_len]; + char *result = + (char *) xmalloc (curr_prefix_len + strlen (pathname_tail) + 1); + +#ifdef NO_XMALLOC + if (result != NULL) +#endif + { + memcpy (result, curr_prefix, curr_prefix_len); + strcpy (result + curr_prefix_len, pathname_tail); + return result; + } + } + } + /* Nothing to relocate. */ + return pathname; +} + +#endif diff --git a/libs/libiconv/lib/relocatable.h b/libs/libiconv/lib/relocatable.h new file mode 100644 index 00000000..68fe83eb --- /dev/null +++ b/libs/libiconv/lib/relocatable.h @@ -0,0 +1,83 @@ +/* Provide relocatable packages. + Copyright (C) 2003, 2005, 2008-2011 Free Software Foundation, Inc. + Written by Bruno Haible , 2003. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +#ifndef _RELOCATABLE_H +#define _RELOCATABLE_H + +#ifdef __cplusplus +extern "C" { +#endif + + +/* This can be enabled through the configure --enable-relocatable option. */ +#if ENABLE_RELOCATABLE + +/* When building a DLL, we must export some functions. Note that because + this is a private .h file, we don't need to use __declspec(dllimport) + in any case. */ +#if HAVE_VISIBILITY && BUILDING_DLL +# define RELOCATABLE_DLL_EXPORTED __attribute__((__visibility__("default"))) +#elif defined _MSC_VER && BUILDING_DLL +# define RELOCATABLE_DLL_EXPORTED __declspec(dllexport) +#else +# define RELOCATABLE_DLL_EXPORTED +#endif + +/* Sets the original and the current installation prefix of the package. + Relocation simply replaces a pathname starting with the original prefix + by the corresponding pathname with the current prefix instead. Both + prefixes should be directory names without trailing slash (i.e. use "" + instead of "/"). */ +extern RELOCATABLE_DLL_EXPORTED void + set_relocation_prefix (const char *orig_prefix, + const char *curr_prefix); + +/* Returns the pathname, relocated according to the current installation + directory. + The returned string is either PATHNAME unmodified or a freshly allocated + string that you can free with free() after casting it to 'char *'. */ +extern const char * relocate (const char *pathname); + +/* Memory management: relocate() potentially allocates memory, because it has + to construct a fresh pathname. If this is a problem because your program + calls relocate() frequently, think about caching the result. Or free the + return value if it was different from the argument pathname. */ + +/* Convenience function: + Computes the current installation prefix, based on the original + installation prefix, the original installation directory of a particular + file, and the current pathname of this file. + Returns it, freshly allocated. Returns NULL upon failure. */ +extern char * compute_curr_prefix (const char *orig_installprefix, + const char *orig_installdir, + const char *curr_pathname); + +#else + +/* By default, we use the hardwired pathnames. */ +#define relocate(pathname) (pathname) + +#endif + + +#ifdef __cplusplus +} +#endif + +#endif /* _RELOCATABLE_H */ diff --git a/libs/libiconv/lib/riscos1.h b/libs/libiconv/lib/riscos1.h new file mode 100644 index 00000000..2ebc7513 --- /dev/null +++ b/libs/libiconv/lib/riscos1.h @@ -0,0 +1,96 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * RISCOS-LATIN1 + */ + +static const unsigned short riscos1_2uni[32] = { + /* 0x80 */ + 0x221a, 0x0174, 0x0175, 0x0083, 0x2573, 0x0176, 0x0177, 0x0087, + 0x21e6, 0x21e8, 0x21e9, 0x21e7, 0x2026, 0x2122, 0x2030, 0x2022, + /* 0x90 */ + 0x2018, 0x2019, 0x2039, 0x203a, 0x201c, 0x201d, 0x201e, 0x2013, + 0x2014, 0x2212, 0x0152, 0x0153, 0x2020, 0x2021, 0xfb01, 0xfb02, +}; + +static int +riscos1_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c >= 0x80 && c < 0xa0) + *pwc = (ucs4_t) riscos1_2uni[c-0x80]; + else + *pwc = (ucs4_t) c; + return 1; +} + +static const unsigned char riscos1_page01[40] = { + 0x00, 0x00, 0x9a, 0x9b, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x81, 0x82, 0x85, 0x86, /* 0x70-0x77 */ +}; +static const unsigned char riscos1_page20[48] = { + 0x00, 0x00, 0x00, 0x97, 0x98, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x90, 0x91, 0x00, 0x00, 0x94, 0x95, 0x96, 0x00, /* 0x18-0x1f */ + 0x9c, 0x9d, 0x8f, 0x00, 0x00, 0x00, 0x8c, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x92, 0x93, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; +static const unsigned char riscos1_page21[16] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8b, /* 0xe0-0xe7 */ + 0x89, 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ +}; +static const unsigned char riscos1_page22[16] = { + 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ +}; + +static int +riscos1_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080 || wc == 0x0083 || wc == 0x0087 || (wc >= 0x00a0 && wc < 0x0100)) { + *r = wc; + return 1; + } + else if (wc >= 0x0150 && wc < 0x0178) + c = riscos1_page01[wc-0x0150]; + else if (wc >= 0x2010 && wc < 0x2040) + c = riscos1_page20[wc-0x2010]; + else if (wc == 0x2122) + c = 0x8d; + else if (wc >= 0x21e0 && wc < 0x21f0) + c = riscos1_page21[wc-0x21e0]; + else if (wc >= 0x2210 && wc < 0x2220) + c = riscos1_page22[wc-0x2210]; + else if (wc == 0x2573) + c = 0x84; + else if (wc >= 0xfb01 && wc < 0xfb03) + c = wc-0xfa63; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/rk1048.h b/libs/libiconv/lib/rk1048.h new file mode 100644 index 00000000..0e1fde89 --- /dev/null +++ b/libs/libiconv/lib/rk1048.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 1999-2007 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * RK1048 + */ + +static const unsigned short rk1048_2uni[128] = { + /* 0x80 */ + 0x0402, 0x0403, 0x201a, 0x0453, 0x201e, 0x2026, 0x2020, 0x2021, + 0x20ac, 0x2030, 0x0409, 0x2039, 0x040a, 0x049a, 0x04ba, 0x040f, + /* 0x90 */ + 0x0452, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0xfffd, 0x2122, 0x0459, 0x203a, 0x045a, 0x049b, 0x04bb, 0x045f, + /* 0xa0 */ + 0x00a0, 0x04b0, 0x04b1, 0x04d8, 0x00a4, 0x04e8, 0x00a6, 0x00a7, + 0x0401, 0x00a9, 0x0492, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x04ae, + /* 0xb0 */ + 0x00b0, 0x00b1, 0x0406, 0x0456, 0x04e9, 0x00b5, 0x00b6, 0x00b7, + 0x0451, 0x2116, 0x0493, 0x00bb, 0x04d9, 0x04a2, 0x04a3, 0x04af, + /* 0xc0 */ + 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, + 0x0418, 0x0419, 0x041a, 0x041b, 0x041c, 0x041d, 0x041e, 0x041f, + /* 0xd0 */ + 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, + 0x0428, 0x0429, 0x042a, 0x042b, 0x042c, 0x042d, 0x042e, 0x042f, + /* 0xe0 */ + 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, + 0x0438, 0x0439, 0x043a, 0x043b, 0x043c, 0x043d, 0x043e, 0x043f, + /* 0xf0 */ + 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, + 0x0448, 0x0449, 0x044a, 0x044b, 0x044c, 0x044d, 0x044e, 0x044f, +}; + +static int +rk1048_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else { + unsigned short wc = rk1048_2uni[c-0x80]; + if (wc != 0xfffd) { + *pwc = (ucs4_t) wc; + return 1; + } + } + return RET_ILSEQ; +} + +static const unsigned char rk1048_page00[32] = { + 0xa0, 0x00, 0x00, 0x00, 0xa4, 0x00, 0xa6, 0xa7, /* 0xa0-0xa7 */ + 0x00, 0xa9, 0x00, 0xab, 0xac, 0xad, 0xae, 0x00, /* 0xa8-0xaf */ + 0xb0, 0xb1, 0x00, 0x00, 0x00, 0xb5, 0xb6, 0xb7, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0xbb, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ +}; +static const unsigned char rk1048_page04[240] = { + 0x00, 0xa8, 0x80, 0x81, 0x00, 0x00, 0xb2, 0x00, /* 0x00-0x07 */ + 0x00, 0x8a, 0x8c, 0x00, 0x00, 0x00, 0x00, 0x8f, /* 0x08-0x0f */ + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 0x10-0x17 */ + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, /* 0x18-0x1f */ + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, /* 0x20-0x27 */ + 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf, /* 0x28-0x2f */ + 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, /* 0x30-0x37 */ + 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef, /* 0x38-0x3f */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 0x40-0x47 */ + 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, /* 0x48-0x4f */ + 0x00, 0xb8, 0x90, 0x83, 0x00, 0x00, 0xb3, 0x00, /* 0x50-0x57 */ + 0x00, 0x9a, 0x9c, 0x00, 0x00, 0x00, 0x00, 0x9f, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0xaa, 0xba, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x8d, 0x9d, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0x00, 0x00, 0xbd, 0xbe, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaf, 0xbf, /* 0xa8-0xaf */ + 0xa1, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x8e, 0x9e, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd0-0xd7 */ + 0xa3, 0xbc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0xa5, 0xb4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ +}; +static const unsigned char rk1048_page20[48] = { + 0x00, 0x00, 0x00, 0x96, 0x97, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x91, 0x92, 0x82, 0x00, 0x93, 0x94, 0x84, 0x00, /* 0x18-0x1f */ + 0x86, 0x87, 0x95, 0x00, 0x00, 0x00, 0x85, 0x00, /* 0x20-0x27 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x8b, 0x9b, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ +}; +static const unsigned char rk1048_page21[24] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb9, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; + +static int +rk1048_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x00c0) + c = rk1048_page00[wc-0x00a0]; + else if (wc >= 0x0400 && wc < 0x04f0) + c = rk1048_page04[wc-0x0400]; + else if (wc >= 0x2010 && wc < 0x2040) + c = rk1048_page20[wc-0x2010]; + else if (wc == 0x20ac) + c = 0x88; + else if (wc >= 0x2110 && wc < 0x2128) + c = rk1048_page21[wc-0x2110]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/shift_jisx0213.h b/libs/libiconv/lib/shift_jisx0213.h new file mode 100644 index 00000000..05f00b00 --- /dev/null +++ b/libs/libiconv/lib/shift_jisx0213.h @@ -0,0 +1,310 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * SHIFT_JISX0213 + */ + +/* The structure of Shift_JISX0213 is as follows: + + 0x00..0x7F: ISO646-JP, an ASCII variant + + 0x{A1..DF}: JISX0201 Katakana. + + 0x{81..9F,E0..EF}{40..7E,80..FC}: JISX0213 plane 1. + + 0x{F0..FC}{40..7E,80..FC}: JISX0213 plane 2, with irregular row mapping. + + Note that some JISX0213 characters are not contained in Unicode 3.2 + and are therefore best represented as sequences of Unicode characters. +*/ + +#include "jisx0213.h" +#include "flushwc.h" + +static int +shift_jisx0213_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + ucs4_t last_wc = conv->istate; + if (last_wc) { + /* Output the buffered character. */ + conv->istate = 0; + *pwc = last_wc; + return 0; /* Don't advance the input pointer. */ + } else { + unsigned char c = *s; + if (c < 0x80) { + /* Plain ISO646-JP character. */ + if (c == 0x5c) + *pwc = (ucs4_t) 0x00a5; + else if (c == 0x7e) + *pwc = (ucs4_t) 0x203e; + else + *pwc = (ucs4_t) c; + return 1; + } else if (c >= 0xa1 && c <= 0xdf) { + *pwc = c + 0xfec0; + return 1; + } else { + if ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc)) { + /* Two byte character. */ + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x40 && c2 <= 0x7e) || (c2 >= 0x80 && c2 <= 0xfc)) { + unsigned int c1; + ucs4_t wc; + /* Convert to row and column. */ + if (c < 0xe0) + c -= 0x81; + else + c -= 0xc1; + if (c2 < 0x80) + c2 -= 0x40; + else + c2 -= 0x41; + /* Now 0 <= c <= 0x3b, 0 <= c2 <= 0xbb. */ + c1 = 2 * c; + if (c2 >= 0x5e) + c2 -= 0x5e, c1++; + c2 += 0x21; + if (c1 >= 0x5e) { + /* Handling of JISX 0213 plane 2 rows. */ + if (c1 >= 0x67) + c1 += 230; + else if (c1 >= 0x63 || c1 == 0x5f) + c1 += 168; + else + c1 += 162; + } + wc = jisx0213_to_ucs4(0x121+c1,c2); + if (wc) { + if (wc < 0x80) { + /* It's a combining character. */ + ucs4_t wc1 = jisx0213_to_ucs_combining[wc - 1][0]; + ucs4_t wc2 = jisx0213_to_ucs_combining[wc - 1][1]; + /* We cannot output two Unicode characters at once. So, + output the first character and buffer the second one. */ + *pwc = wc1; + conv->istate = wc2; + } else + *pwc = wc; + return 2; + } + } + } else + return RET_TOOFEW(0); + } + return RET_ILSEQ; + } + } +} + +#define shift_jisx0213_flushwc normal_flushwc + +/* Composition tables for each of the relevant combining characters. */ +static const struct { unsigned short base; unsigned short composed; } shift_jisx0213_comp_table_data[] = { +#define shift_jisx0213_comp_table02e5_idx 0 +#define shift_jisx0213_comp_table02e5_len 1 + { 0x8684, 0x8685 }, /* 0x12B65 = 0x12B64 U+02E5 */ +#define shift_jisx0213_comp_table02e9_idx (shift_jisx0213_comp_table02e5_idx+shift_jisx0213_comp_table02e5_len) +#define shift_jisx0213_comp_table02e9_len 1 + { 0x8680, 0x8686 }, /* 0x12B66 = 0x12B60 U+02E9 */ +#define shift_jisx0213_comp_table0300_idx (shift_jisx0213_comp_table02e9_idx+shift_jisx0213_comp_table02e9_len) +#define shift_jisx0213_comp_table0300_len 5 + { 0x857b, 0x8663 }, /* 0x12B44 = 0x1295C U+0300 */ + { 0x8657, 0x8667 }, /* 0x12B48 = 0x12B38 U+0300 */ + { 0x8656, 0x8669 }, /* 0x12B4A = 0x12B37 U+0300 */ + { 0x864f, 0x866b }, /* 0x12B4C = 0x12B30 U+0300 */ + { 0x8662, 0x866d }, /* 0x12B4E = 0x12B43 U+0300 */ +#define shift_jisx0213_comp_table0301_idx (shift_jisx0213_comp_table0300_idx+shift_jisx0213_comp_table0300_len) +#define shift_jisx0213_comp_table0301_len 4 + { 0x8657, 0x8668 }, /* 0x12B49 = 0x12B38 U+0301 */ + { 0x8656, 0x866a }, /* 0x12B4B = 0x12B37 U+0301 */ + { 0x864f, 0x866c }, /* 0x12B4D = 0x12B30 U+0301 */ + { 0x8662, 0x866e }, /* 0x12B4F = 0x12B43 U+0301 */ +#define shift_jisx0213_comp_table309a_idx (shift_jisx0213_comp_table0301_idx+shift_jisx0213_comp_table0301_len) +#define shift_jisx0213_comp_table309a_len 14 + { 0x82a9, 0x82f5 }, /* 0x12477 = 0x1242B U+309A */ + { 0x82ab, 0x82f6 }, /* 0x12478 = 0x1242D U+309A */ + { 0x82ad, 0x82f7 }, /* 0x12479 = 0x1242F U+309A */ + { 0x82af, 0x82f8 }, /* 0x1247A = 0x12431 U+309A */ + { 0x82b1, 0x82f9 }, /* 0x1247B = 0x12433 U+309A */ + { 0x834a, 0x8397 }, /* 0x12577 = 0x1252B U+309A */ + { 0x834c, 0x8398 }, /* 0x12578 = 0x1252D U+309A */ + { 0x834e, 0x8399 }, /* 0x12579 = 0x1252F U+309A */ + { 0x8350, 0x839a }, /* 0x1257A = 0x12531 U+309A */ + { 0x8352, 0x839b }, /* 0x1257B = 0x12533 U+309A */ + { 0x835a, 0x839c }, /* 0x1257C = 0x1253B U+309A */ + { 0x8363, 0x839d }, /* 0x1257D = 0x12544 U+309A */ + { 0x8367, 0x839e }, /* 0x1257E = 0x12548 U+309A */ + { 0x83f3, 0x83f6 }, /* 0x12678 = 0x12675 U+309A */ +}; + +static int +shift_jisx0213_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + int count = 0; + unsigned short lasttwo = conv->ostate; + + if (lasttwo) { + /* Attempt to combine the last character with this one. */ + unsigned int idx; + unsigned int len; + + if (wc == 0x02e5) + idx = shift_jisx0213_comp_table02e5_idx, + len = shift_jisx0213_comp_table02e5_len; + else if (wc == 0x02e9) + idx = shift_jisx0213_comp_table02e9_idx, + len = shift_jisx0213_comp_table02e9_len; + else if (wc == 0x0300) + idx = shift_jisx0213_comp_table0300_idx, + len = shift_jisx0213_comp_table0300_len; + else if (wc == 0x0301) + idx = shift_jisx0213_comp_table0301_idx, + len = shift_jisx0213_comp_table0301_len; + else if (wc == 0x309a) + idx = shift_jisx0213_comp_table309a_idx, + len = shift_jisx0213_comp_table309a_len; + else + goto not_combining; + + do + if (shift_jisx0213_comp_table_data[idx].base == lasttwo) + break; + while (++idx, --len > 0); + + if (len > 0) { + /* Output the combined character. */ + if (n >= 2) { + lasttwo = shift_jisx0213_comp_table_data[idx].composed; + r[0] = (lasttwo >> 8) & 0xff; + r[1] = lasttwo & 0xff; + conv->ostate = 0; + return 2; + } else + return RET_TOOSMALL; + } + + not_combining: + /* Output the buffered character. */ + if (n < 2) + return RET_TOOSMALL; + r[0] = (lasttwo >> 8) & 0xff; + r[1] = lasttwo & 0xff; + r += 2; + count = 2; + } + + if (wc < 0x80 && wc != 0x5c && wc != 0x7e) { + /* Plain ISO646-JP character. */ + if (n > count) { + r[0] = (unsigned char) wc; + conv->ostate = 0; + return count+1; + } else + return RET_TOOSMALL; + } else if (wc == 0x00a5) { + if (n > count) { + r[0] = 0x5c; + conv->ostate = 0; + return count+1; + } else + return RET_TOOSMALL; + } else if (wc == 0x203e) { + if (n > count) { + r[0] = 0x7e; + conv->ostate = 0; + return count+1; + } else + return RET_TOOSMALL; + } else if (wc >= 0xff61 && wc <= 0xff9f) { + /* Half-width katakana. */ + if (n > count) { + r[0] = wc - 0xfec0; + conv->ostate = 0; + return count+1; + } else + return RET_TOOSMALL; + } else { + unsigned int s1, s2; + unsigned short jch = ucs4_to_jisx0213(wc); + if (jch != 0) { + /* Convert it to shifted representation. */ + s1 = jch >> 8; + s2 = jch & 0x7f; + s1 -= 0x21; + s2 -= 0x21; + if (s1 >= 0x5e) { + /* Handling of JISX 0213 plane 2 rows. */ + if (s1 >= 0xcd) /* rows 0x26E..0x27E */ + s1 -= 102; + else if (s1 >= 0x8b || s1 == 0x87) /* rows 0x228, 0x22C..0x22F */ + s1 -= 40; + else /* rows 0x221, 0x223..0x225 */ + s1 -= 34; + /* Now 0x5e <= s1 <= 0x77. */ + } + if (s1 & 1) + s2 += 0x5e; + s1 = s1 >> 1; + if (s1 < 0x1f) + s1 += 0x81; + else + s1 += 0xc1; + if (s2 < 0x3f) + s2 += 0x40; + else + s2 += 0x41; + if (jch & 0x0080) { + /* A possible match in comp_table_data. We have to buffer it. */ + /* We know it's a JISX 0213 plane 1 character. */ + if (jch & 0x8000) abort(); + conv->ostate = (s1 << 8) | s2; + return count+0; + } + /* Output the shifted representation. */ + if (n >= count+2) { + r[0] = s1; + r[1] = s2; + conv->ostate = 0; + return count+2; + } else + return RET_TOOSMALL; + } + return RET_ILUNI; + } +} + +static int +shift_jisx0213_reset (conv_t conv, unsigned char *r, int n) +{ + state_t lasttwo = conv->ostate; + + if (lasttwo) { + if (n < 2) + return RET_TOOSMALL; + r[0] = (lasttwo >> 8) & 0xff; + r[1] = lasttwo & 0xff; + /* conv->ostate = 0; will be done by the caller */ + return 2; + } else + return 0; +} diff --git a/libs/libiconv/lib/sjis.h b/libs/libiconv/lib/sjis.h new file mode 100644 index 00000000..8244e3a8 --- /dev/null +++ b/libs/libiconv/lib/sjis.h @@ -0,0 +1,132 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * SHIFT_JIS + */ + +/* + Conversion between SJIS codes (s1,s2) and JISX0208 codes (c1,c2): + Example. (s1,s2) = 0x8140, (c1,c2) = 0x2121. + 0x81 <= s1 <= 0x9F || 0xE0 <= s1 <= 0xEA, + 0x40 <= s2 <= 0x7E || 0x80 <= s2 <= 0xFC, + 0x21 <= c1 <= 0x74, 0x21 <= c2 <= 0x7E. + Invariant: + 94*2*(s1 < 0xE0 ? s1-0x81 : s1-0xC1) + (s2 < 0x80 ? s2-0x40 : s2-0x41) + = 94*(c1-0x21)+(c2-0x21) + Conversion (s1,s2) -> (c1,c2): + t1 := (s1 < 0xE0 ? s1-0x81 : s1-0xC1) + t2 := (s2 < 0x80 ? s2-0x40 : s2-0x41) + c1 := 2*t1 + (t2 < 0x5E ? 0 : 1) + 0x21 + c2 := (t2 < 0x5E ? t2 : t2-0x5E) + 0x21 + Conversion (c1,c2) -> (s1,s2): + t1 := (c1 - 0x21) >> 1 + t2 := ((c1 - 0x21) & 1) * 0x5E + (c2 - 0x21) + s1 := (t1 < 0x1F ? t1+0x81 : t1+0xC1) + s2 := (t2 < 0x3F ? t2+0x40 : t2+0x41) + */ + +static int +sjis_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80 || (c >= 0xa1 && c <= 0xdf)) + return jisx0201_mbtowc(conv,pwc,s,n); + else { + unsigned char s1, s2; + s1 = c; + if ((s1 >= 0x81 && s1 <= 0x9f) || (s1 >= 0xe0 && s1 <= 0xea)) { + if (n < 2) + return RET_TOOFEW(0); + s2 = s[1]; + if ((s2 >= 0x40 && s2 <= 0x7e) || (s2 >= 0x80 && s2 <= 0xfc)) { + unsigned char t1 = (s1 < 0xe0 ? s1-0x81 : s1-0xc1); + unsigned char t2 = (s2 < 0x80 ? s2-0x40 : s2-0x41); + unsigned char buf[2]; + buf[0] = 2*t1 + (t2 < 0x5e ? 0 : 1) + 0x21; + buf[1] = (t2 < 0x5e ? t2 : t2-0x5e) + 0x21; + return jisx0208_mbtowc(conv,pwc,buf,2); + } + } else if (s1 >= 0xf0 && s1 <= 0xf9) { + /* User-defined range. See + * Ken Lunde's "CJKV Information Processing", table 4-66, p. 206. */ + if (n < 2) + return RET_TOOFEW(0); + s2 = s[1]; + if ((s2 >= 0x40 && s2 <= 0x7e) || (s2 >= 0x80 && s2 <= 0xfc)) { + *pwc = 0xe000 + 188*(s1 - 0xf0) + (s2 < 0x80 ? s2-0x40 : s2-0x41); + return 2; + } + } + return RET_ILSEQ; + } +} + +static int +sjis_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char buf[2]; + int ret; + + /* Try JIS X 0201-1976. */ + ret = jisx0201_wctomb(conv,buf,wc,1); + if (ret != RET_ILUNI) { + unsigned char c; + if (ret != 1) abort(); + c = buf[0]; + if (c < 0x80 || (c >= 0xa1 && c <= 0xdf)) { + r[0] = c; + return 1; + } + } + + /* Try JIS X 0208-1990. */ + ret = jisx0208_wctomb(conv,buf,wc,2); + if (ret != RET_ILUNI) { + unsigned char c1, c2; + if (ret != 2) abort(); + if (n < 2) + return RET_TOOSMALL; + c1 = buf[0]; + c2 = buf[1]; + if ((c1 >= 0x21 && c1 <= 0x74) && (c2 >= 0x21 && c2 <= 0x7e)) { + unsigned char t1 = (c1 - 0x21) >> 1; + unsigned char t2 = (((c1 - 0x21) & 1) ? 0x5e : 0) + (c2 - 0x21); + r[0] = (t1 < 0x1f ? t1+0x81 : t1+0xc1); + r[1] = (t2 < 0x3f ? t2+0x40 : t2+0x41); + return 2; + } + } + + /* User-defined range. See + * Ken Lunde's "CJKV Information Processing", table 4-66, p. 206. */ + if (wc >= 0xe000 && wc < 0xe758) { + unsigned char c1, c2; + if (n < 2) + return RET_TOOSMALL; + c1 = (unsigned int) (wc - 0xe000) / 188; + c2 = (unsigned int) (wc - 0xe000) % 188; + r[0] = c1+0xf0; + r[1] = (c2 < 0x3f ? c2+0x40 : c2+0x41); + return 2; + } + + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/stamp-h2 b/libs/libiconv/lib/stamp-h2 new file mode 100644 index 00000000..8ce1fe9c --- /dev/null +++ b/libs/libiconv/lib/stamp-h2 @@ -0,0 +1 @@ +timestamp for lib/config.h diff --git a/libs/libiconv/lib/tcvn.h b/libs/libiconv/lib/tcvn.h new file mode 100644 index 00000000..abd5def2 --- /dev/null +++ b/libs/libiconv/lib/tcvn.h @@ -0,0 +1,291 @@ +/* + * Copyright (C) 1999-2002, 2004 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * TCVN-5712 + */ + +#include "flushwc.h" +#include "vietcomb.h" + +static const unsigned char tcvn_comb_table[] = { + 0xb0, 0xb3, 0xb2, 0xb1, 0xb4, +}; + +/* The possible bases in viet_comp_table_data: + 0x0041..0x0045, 0x0047..0x0049, 0x004B..0x0050, 0x0052..0x0057, + 0x0059..0x005A, 0x0061..0x0065, 0x0067..0x0069, 0x006B..0x0070, + 0x0072..0x0077, 0x0079..0x007A, 0x00A5, 0x00C2, 0x00CA, 0x00D3..0x00D6, + 0x00DA, 0x00E2, 0x00EA, 0x00F3..0x00F6, 0x00FA, 0x0102..0x0103, + 0x0168..0x0169, 0x01A0..0x01A1, 0x01AF..0x01B0. */ +static const unsigned int tcvn_comp_bases[] = { + 0x06fdfbbe, 0x06fdfbbe, 0x00000000, 0x00000020, 0x04780404, 0x04780404, + 0x0000000c, 0x00000000, 0x00000000, 0x00000300, 0x00000000, 0x00018003 +}; + +static const unsigned short tcvn_2uni_1[24] = { + /* 0x00 */ + 0x0000, 0x00da, 0x1ee4, 0x0003, 0x1eea, 0x1eec, 0x1eee, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + /* 0x10 */ + 0x0010, 0x1ee8, 0x1ef0, 0x1ef2, 0x1ef6, 0x1ef8, 0x00dd, 0x1ef4, +}; +static const unsigned short tcvn_2uni_2[128] = { + /* 0x80 */ + 0x00c0, 0x1ea2, 0x00c3, 0x00c1, 0x1ea0, 0x1eb6, 0x1eac, 0x00c8, + 0x1eba, 0x1ebc, 0x00c9, 0x1eb8, 0x1ec6, 0x00cc, 0x1ec8, 0x0128, + /* 0x90 */ + 0x00cd, 0x1eca, 0x00d2, 0x1ece, 0x00d5, 0x00d3, 0x1ecc, 0x1ed8, + 0x1edc, 0x1ede, 0x1ee0, 0x1eda, 0x1ee2, 0x00d9, 0x1ee6, 0x0168, + /* 0xa0 */ + 0x00a0, 0x0102, 0x00c2, 0x00ca, 0x00d4, 0x01a0, 0x01af, 0x0110, + 0x0103, 0x00e2, 0x00ea, 0x00f4, 0x01a1, 0x01b0, 0x0111, 0x1eb0, + /* 0xb0 */ + 0x0300, 0x0309, 0x0303, 0x0301, 0x0323, 0x00e0, 0x1ea3, 0x00e3, + 0x00e1, 0x1ea1, 0x1eb2, 0x1eb1, 0x1eb3, 0x1eb5, 0x1eaf, 0x1eb4, + /* 0xc0 */ + 0x1eae, 0x1ea6, 0x1ea8, 0x1eaa, 0x1ea4, 0x1ec0, 0x1eb7, 0x1ea7, + 0x1ea9, 0x1eab, 0x1ea5, 0x1ead, 0x00e8, 0x1ec2, 0x1ebb, 0x1ebd, + /* 0xd0 */ + 0x00e9, 0x1eb9, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ebf, 0x1ec7, 0x00ec, + 0x1ec9, 0x1ec4, 0x1ebe, 0x1ed2, 0x0129, 0x00ed, 0x1ecb, 0x00f2, + /* 0xe0 */ + 0x1ed4, 0x1ecf, 0x00f5, 0x00f3, 0x1ecd, 0x1ed3, 0x1ed5, 0x1ed7, + 0x1ed1, 0x1ed9, 0x1edd, 0x1edf, 0x1ee1, 0x1edb, 0x1ee3, 0x00f9, + /* 0xf0 */ + 0x1ed6, 0x1ee7, 0x0169, 0x00fa, 0x1ee5, 0x1eeb, 0x1eed, 0x1eef, + 0x1ee9, 0x1ef1, 0x1ef3, 0x1ef7, 0x1ef9, 0x00fd, 0x1ef5, 0x1ed0, +}; + +/* In the TCVN to Unicode direction, the state contains a buffered + character, or 0 if none. */ + +static int +tcvn_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + unsigned short wc; + unsigned short last_wc; + if (c < 0x18) + wc = tcvn_2uni_1[c]; + else if (c < 0x80) + wc = c; + else + wc = tcvn_2uni_2[c-0x80]; + last_wc = conv->istate; + if (last_wc) { + if (wc >= 0x0300 && wc < 0x0340) { + /* See whether last_wc and wc can be combined. */ + unsigned int k; + unsigned int i1, i2; + switch (wc) { + case 0x0300: k = 0; break; + case 0x0301: k = 1; break; + case 0x0303: k = 2; break; + case 0x0309: k = 3; break; + case 0x0323: k = 4; break; + default: abort(); + } + i1 = viet_comp_table[k].idx; + i2 = i1 + viet_comp_table[k].len-1; + if (last_wc >= viet_comp_table_data[i1].base + && last_wc <= viet_comp_table_data[i2].base) { + unsigned int i; + for (;;) { + i = (i1+i2)>>1; + if (last_wc == viet_comp_table_data[i].base) + break; + if (last_wc < viet_comp_table_data[i].base) { + if (i1 == i) + goto not_combining; + i2 = i; + } else { + if (i1 != i) + i1 = i; + else { + i = i2; + if (last_wc == viet_comp_table_data[i].base) + break; + goto not_combining; + } + } + } + last_wc = viet_comp_table_data[i].composed; + /* Output the combined character. */ + conv->istate = 0; + *pwc = (ucs4_t) last_wc; + return 1; + } + } + not_combining: + /* Output the buffered character. */ + conv->istate = 0; + *pwc = (ucs4_t) last_wc; + return 0; /* Don't advance the input pointer. */ + } + if (wc >= 0x0041 && wc <= 0x01b0 + && ((tcvn_comp_bases[(wc - 0x0040) >> 5] >> (wc & 0x1f)) & 1)) { + /* wc is a possible match in viet_comp_table_data. Buffer it. */ + conv->istate = wc; + return RET_TOOFEW(1); + } else { + /* Output wc immediately. */ + *pwc = (ucs4_t) wc; + return 1; + } +} + +#define tcvn_flushwc normal_flushwc + +static const unsigned char tcvn_page00[96+184] = { + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa8-0xaf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb8-0xbf */ + 0x80, 0x83, 0xa2, 0x82, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0x87, 0x8a, 0xa3, 0x00, 0x8d, 0x90, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x92, 0x95, 0xa4, 0x94, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x9d, 0x01, 0x00, 0x00, 0x16, 0x00, 0x00, /* 0xd8-0xdf */ + 0xb5, 0xb8, 0xa9, 0xb7, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0xcc, 0xd0, 0xaa, 0x00, 0xd7, 0xdd, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0xdf, 0xe3, 0xab, 0xe2, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0xef, 0xf3, 0x00, 0x00, 0xfd, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0x00, 0x00, 0xa1, 0xa8, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xa7, 0xae, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0x8f, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x9f, 0xf2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xa5, 0xac, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa6, /* 0xa8-0xaf */ + 0xad, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ +}; +static const unsigned char tcvn_page03[40] = { + 0xb0, 0xb3, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0xb4, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ +}; +static const unsigned char tcvn_page1e[96] = { + 0x84, 0xb9, 0x81, 0xb6, 0xc4, 0xca, 0xc1, 0xc7, /* 0xa0-0xa7 */ + 0xc2, 0xc8, 0xc3, 0xc9, 0x86, 0xcb, 0xc0, 0xbe, /* 0xa8-0xaf */ + 0xaf, 0xbb, 0xba, 0xbc, 0xbf, 0xbd, 0x85, 0xc6, /* 0xb0-0xb7 */ + 0x8b, 0xd1, 0x88, 0xce, 0x89, 0xcf, 0xda, 0xd5, /* 0xb8-0xbf */ + 0xc5, 0xd2, 0xcd, 0xd3, 0xd9, 0xd4, 0x8c, 0xd6, /* 0xc0-0xc7 */ + 0x8e, 0xd8, 0x91, 0xde, 0x96, 0xe4, 0x93, 0xe1, /* 0xc8-0xcf */ + 0xff, 0xe8, 0xdb, 0xe5, 0xe0, 0xe6, 0xf0, 0xe7, /* 0xd0-0xd7 */ + 0x97, 0xe9, 0x9b, 0xed, 0x98, 0xea, 0x99, 0xeb, /* 0xd8-0xdf */ + 0x9a, 0xec, 0x9c, 0xee, 0x02, 0xf4, 0x9e, 0xf1, /* 0xe0-0xe7 */ + 0x11, 0xf8, 0x04, 0xf5, 0x05, 0xf6, 0x06, 0xf7, /* 0xe8-0xef */ + 0x12, 0xf9, 0x13, 0xfa, 0x17, 0xfe, 0x14, 0xfb, /* 0xf0-0xf7 */ + 0x15, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static int +tcvn_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080 && (wc >= 0x0020 || (0x00fe0076 & (1 << wc)) == 0)) { + *r = wc; + return 1; + } + else if (wc >= 0x00a0 && wc < 0x01b8) + c = tcvn_page00[wc-0x00a0]; + else if (wc >= 0x0300 && wc < 0x0328) + c = tcvn_page03[wc-0x0300]; + else if (wc >= 0x0340 && wc < 0x0342) /* deprecated Vietnamese tone marks */ + c = tcvn_page03[wc-0x0340]; + else if (wc >= 0x1ea0 && wc < 0x1f00) + c = tcvn_page1e[wc-0x1ea0]; + if (c != 0) { + *r = c; + return 1; + } + /* Try compatibility or canonical decomposition. */ + { + /* Binary search through viet_decomp_table. */ + unsigned int i1 = 0; + unsigned int i2 = sizeof(viet_decomp_table)/sizeof(viet_decomp_table[0])-1; + if (wc >= viet_decomp_table[i1].composed + && wc <= viet_decomp_table[i2].composed) { + unsigned int i; + for (;;) { + /* Here i2 - i1 > 0. */ + i = (i1+i2)>>1; + if (wc == viet_decomp_table[i].composed) + break; + if (wc < viet_decomp_table[i].composed) { + if (i1 == i) + return RET_ILUNI; + /* Here i1 < i < i2. */ + i2 = i; + } else { + /* Here i1 <= i < i2. */ + if (i1 != i) + i1 = i; + else { + /* Here i2 - i1 = 1. */ + i = i2; + if (wc == viet_decomp_table[i].composed) + break; + else + return RET_ILUNI; + } + } + } + /* Found a compatibility or canonical decomposition. */ + wc = viet_decomp_table[i].base; + /* wc is one of 0x0020, 0x0041..0x005a, 0x0061..0x007a, 0x00a5, 0x00a8, + 0x00c2, 0x00c5..0x00c7, 0x00ca, 0x00cf, 0x00d3, 0x00d4, 0x00d6, + 0x00d8, 0x00da, 0x00dc, 0x00e2, 0x00e5..0x00e7, 0x00ea, 0x00ef, + 0x00f3, 0x00f4, 0x00f6, 0x00f8, 0x00fc, 0x0102, 0x0103, 0x01a0, + 0x01a1, 0x01af, 0x01b0. */ + if (wc < 0x0080) + c = wc; + else { + c = tcvn_page00[wc-0x00a0]; + if (c == 0) + return RET_ILUNI; + } + if (n < 2) + return RET_TOOSMALL; + r[0] = c; + r[1] = tcvn_comb_table[viet_decomp_table[i].comb1]; + return 2; + } + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/tds565.h b/libs/libiconv/lib/tds565.h new file mode 100644 index 00000000..479513fe --- /dev/null +++ b/libs/libiconv/lib/tds565.h @@ -0,0 +1,107 @@ +/* + * Copyright (C) 1999-2002 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * TDS565 + */ + +static const unsigned short tds565_2uni[64] = { + /* 0x40 */ + 0x0040, 0x0041, 0x0042, 0x00c7, 0x0044, 0x0045, 0x00c4, 0x0046, + 0x0047, 0x0048, 0x0049, 0x004a, 0x017d, 0x004b, 0x004c, 0x004d, + /* 0x50 */ + 0x004e, 0x0147, 0x004f, 0x00d6, 0x0050, 0x0052, 0x0053, 0x015e, + 0x0054, 0x0055, 0x00dc, 0x0057, 0x0059, 0x00dd, 0x005a, 0x005f, + /* 0x60 */ + 0x2116, 0x0061, 0x0062, 0x00e7, 0x0064, 0x0065, 0x00e4, 0x0066, + 0x0067, 0x0068, 0x0069, 0x006a, 0x017e, 0x006b, 0x006c, 0x006d, + /* 0x70 */ + 0x006e, 0x0148, 0x006f, 0x00f6, 0x0070, 0x0072, 0x0073, 0x015f, + 0x0074, 0x0075, 0x00fc, 0x0077, 0x0079, 0x00fd, 0x007a, 0x007f, +}; + +static int +tds565_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x40) { + *pwc = (ucs4_t) c; + return 1; + } + else if (c < 0x80) { + *pwc = (ucs4_t) tds565_2uni[c-0x40]; + return 1; + } + return RET_ILSEQ; +} + +static const unsigned char tds565_page00[64] = { + 0x40, 0x41, 0x42, 0x00, 0x44, 0x45, 0x47, 0x48, /* 0x40-0x47 */ + 0x49, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x50, 0x52, /* 0x48-0x4f */ + 0x54, 0x00, 0x55, 0x56, 0x58, 0x59, 0x00, 0x5b, /* 0x50-0x57 */ + 0x00, 0x5c, 0x5e, 0x00, 0x00, 0x00, 0x00, 0x5f, /* 0x58-0x5f */ + 0x00, 0x61, 0x62, 0x00, 0x64, 0x65, 0x67, 0x68, /* 0x60-0x67 */ + 0x69, 0x6a, 0x6b, 0x6d, 0x6e, 0x6f, 0x70, 0x72, /* 0x68-0x6f */ + 0x74, 0x00, 0x75, 0x76, 0x78, 0x79, 0x00, 0x7b, /* 0x70-0x77 */ + 0x00, 0x7c, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x7f, /* 0x78-0x7f */ +}; +static const unsigned char tds565_page00_1[64] = { + 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, 0x00, 0x43, /* 0xc0-0xc7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00, /* 0xd0-0xd7 */ + 0x00, 0x00, 0x00, 0x00, 0x5a, 0x5d, 0x00, 0x00, /* 0xd8-0xdf */ + 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x63, /* 0xe0-0xe7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00, /* 0xf0-0xf7 */ + 0x00, 0x00, 0x00, 0x00, 0x7a, 0x7d, 0x00, 0x00, /* 0xf8-0xff */ +}; +static const unsigned char tds565_page01[64] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, /* 0x40-0x47 */ + 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x77, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x4c, 0x6c, 0x00, /* 0x78-0x7f */ +}; + +static int +tds565_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0040) { + *r = wc; + return 1; + } + else if (wc >= 0x0040 && wc < 0x0080) + c = tds565_page00[wc-0x0040]; + else if (wc >= 0x00c0 && wc < 0x0100) + c = tds565_page00_1[wc-0x00c0]; + else if (wc >= 0x0140 && wc < 0x0180) + c = tds565_page01[wc-0x0140]; + else if (wc == 0x2116) + c = 0x60; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/tis620.h b/libs/libiconv/lib/tis620.h new file mode 100644 index 00000000..125e6dc8 --- /dev/null +++ b/libs/libiconv/lib/tis620.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * TIS620.2533-1 + */ + +static int +tis620_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x80) { + *pwc = (ucs4_t) c; + return 1; + } + else if (c >= 0xa1 && c <= 0xfb && !(c >= 0xdb && c <= 0xde)) { + *pwc = (ucs4_t) (c + 0x0d60); + return 1; + } + return RET_ILSEQ; +} + +static int +tis620_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x0080) { + *r = wc; + return 1; + } + else if (wc >= 0x0e01 && wc <= 0x0e5b && !(wc >= 0x0e3b && wc <= 0x0e3e)) { + *r = wc-0x0d60; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/translit.def b/libs/libiconv/lib/translit.def new file mode 100644 index 00000000..cbd329ee --- /dev/null +++ b/libs/libiconv/lib/translit.def @@ -0,0 +1,3918 @@ +# Copyright (C) 1999-2003 Free Software Foundation, Inc. +# This file is part of the GNU LIBICONV Library. +# +# The GNU LIBICONV Library is free software; you can redistribute it +# and/or modify it under the terms of the GNU Library General Public +# License as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# The GNU LIBICONV Library is distributed in the hope that it will be +# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Library General Public License for more details. +# +# You should have received a copy of the GNU Library General Public +# License along with the GNU LIBICONV Library; see the file COPYING.LIB. +# If not, write to the Free Software Foundation, Inc., 51 Franklin Street, +# Fifth Floor, Boston, MA 02110-1301, USA. +# +# +# Definition of transliteration from Unicode to poorer character sets. +# +# This covers all of Markus Kuhn's TARGET1. +# +# The second column gives the transliteration. It is enclosed between tabs! +# +00A0 # NO-BREAK SPACE +00A1 ! # INVERTED EXCLAMATION MARK +00A2 c # CENT SIGN +00A3 lb # POUND SIGN +00A4 # CURRENCY SIGN +00A5 yen # YEN SIGN +00A6 | # BROKEN BAR +00A7 SS # SECTION SIGN +00A8 " # DIAERESIS +00A9 (c) # COPYRIGHT SIGN +00AA a # FEMININE ORDINAL INDICATOR +00AB << # LEFT-POINTING DOUBLE ANGLE QUOTATION MARK +00AC not # NOT SIGN +00AD - # SOFT HYPHEN +00AE (R) # REGISTERED SIGN +00AF # MACRON +00B0 ^0 # DEGREE SIGN +00B1 +/- # PLUS-MINUS SIGN +00B2 ^2 # SUPERSCRIPT TWO +00B3 ^3 # SUPERSCRIPT THREE +00B4 ' # ACUTE ACCENT +00B5 u # MICRO SIGN +00B6 P # PILCROW SIGN +00B7 . # MIDDLE DOT +00B8 , # CEDILLA +00B9 ^1 # SUPERSCRIPT ONE +00BA o # MASCULINE ORDINAL INDICATOR +00BB >> # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK +00BC 1â„4 # VULGAR FRACTION ONE QUARTER +00BD 1â„2 # VULGAR FRACTION ONE HALF +00BE 3â„4 # VULGAR FRACTION THREE QUARTERS +00BF ? # INVERTED QUESTION MARK +00C0 `A # LATIN CAPITAL LETTER A WITH GRAVE +00C1 ´A # LATIN CAPITAL LETTER A WITH ACUTE +00C2 ^A # LATIN CAPITAL LETTER A WITH CIRCUMFLEX +00C3 ~A # LATIN CAPITAL LETTER A WITH TILDE +00C4 "A # LATIN CAPITAL LETTER A WITH DIAERESIS +00C5 A # LATIN CAPITAL LETTER A WITH RING ABOVE +00C6 AE # LATIN CAPITAL LETTER AE +00C7 C # LATIN CAPITAL LETTER C WITH CEDILLA +00C8 `E # LATIN CAPITAL LETTER E WITH GRAVE +00C9 ´E # LATIN CAPITAL LETTER E WITH ACUTE +00CA ^E # LATIN CAPITAL LETTER E WITH CIRCUMFLEX +00CB "E # LATIN CAPITAL LETTER E WITH DIAERESIS +00CC `I # LATIN CAPITAL LETTER I WITH GRAVE +00CD ´I # LATIN CAPITAL LETTER I WITH ACUTE +00CE ^I # LATIN CAPITAL LETTER I WITH CIRCUMFLEX +00CF "I # LATIN CAPITAL LETTER I WITH DIAERESIS +00D0 D # LATIN CAPITAL LETTER ETH +00D1 ~N # LATIN CAPITAL LETTER N WITH TILDE +00D2 `O # LATIN CAPITAL LETTER O WITH GRAVE +00D3 ´O # LATIN CAPITAL LETTER O WITH ACUTE +00D4 ^O # LATIN CAPITAL LETTER O WITH CIRCUMFLEX +00D5 ~O # LATIN CAPITAL LETTER O WITH TILDE +00D6 "O # LATIN CAPITAL LETTER O WITH DIAERESIS +00D7 x # MULTIPLICATION SIGN +00D8 O # LATIN CAPITAL LETTER O WITH STROKE +00D9 `U # LATIN CAPITAL LETTER U WITH GRAVE +00DA ´U # LATIN CAPITAL LETTER U WITH ACUTE +00DB ^U # LATIN CAPITAL LETTER U WITH CIRCUMFLEX +00DC "U # LATIN CAPITAL LETTER U WITH DIAERESIS +00DD ´Y # LATIN CAPITAL LETTER Y WITH ACUTE +00DE Th # LATIN CAPITAL LETTER THORN +00DF ss # LATIN SMALL LETTER SHARP S +00E0 `a # LATIN SMALL LETTER A WITH GRAVE +00E1 ´a # LATIN SMALL LETTER A WITH ACUTE +00E2 ^a # LATIN SMALL LETTER A WITH CIRCUMFLEX +00E3 ~a # LATIN SMALL LETTER A WITH TILDE +00E4 "a # LATIN SMALL LETTER A WITH DIAERESIS +00E5 a # LATIN SMALL LETTER A WITH RING ABOVE +00E6 ae # LATIN SMALL LETTER AE +00E7 c # LATIN SMALL LETTER C WITH CEDILLA +00E8 `e # LATIN SMALL LETTER E WITH GRAVE +00E9 ´e # LATIN SMALL LETTER E WITH ACUTE +00EA ^e # LATIN SMALL LETTER E WITH CIRCUMFLEX +00EB "e # LATIN SMALL LETTER E WITH DIAERESIS +00EC `i # LATIN SMALL LETTER I WITH GRAVE +00ED ´i # LATIN SMALL LETTER I WITH ACUTE +00EE ^i # LATIN SMALL LETTER I WITH CIRCUMFLEX +00EF "i # LATIN SMALL LETTER I WITH DIAERESIS +00F0 d # LATIN SMALL LETTER ETH +00F1 ~n # LATIN SMALL LETTER N WITH TILDE +00F2 `o # LATIN SMALL LETTER O WITH GRAVE +00F3 ´o # LATIN SMALL LETTER O WITH ACUTE +00F4 ^o # LATIN SMALL LETTER O WITH CIRCUMFLEX +00F5 ~o # LATIN SMALL LETTER O WITH TILDE +00F6 "o # LATIN SMALL LETTER O WITH DIAERESIS +00F7 : # DIVISION SIGN +00F8 o # LATIN SMALL LETTER O WITH STROKE +00F9 `u # LATIN SMALL LETTER U WITH GRAVE +00FA ´u # LATIN SMALL LETTER U WITH ACUTE +00FB ^u # LATIN SMALL LETTER U WITH CIRCUMFLEX +00FC "u # LATIN SMALL LETTER U WITH DIAERESIS +00FD ´y # LATIN SMALL LETTER Y WITH ACUTE +00FE th # LATIN SMALL LETTER THORN +00FF "y # LATIN SMALL LETTER Y WITH DIAERESIS +0100 A # LATIN CAPITAL LETTER A WITH MACRON +0101 a # LATIN SMALL LETTER A WITH MACRON +0102 A # LATIN CAPITAL LETTER A WITH BREVE +0103 a # LATIN SMALL LETTER A WITH BREVE +0104 A # LATIN CAPITAL LETTER A WITH OGONEK +0105 a # LATIN SMALL LETTER A WITH OGONEK +0106 ´C # LATIN CAPITAL LETTER C WITH ACUTE +0107 ´c # LATIN SMALL LETTER C WITH ACUTE +0108 ^C # LATIN CAPITAL LETTER C WITH CIRCUMFLEX +0109 ^c # LATIN SMALL LETTER C WITH CIRCUMFLEX +010A C # LATIN CAPITAL LETTER C WITH DOT ABOVE +010B c # LATIN SMALL LETTER C WITH DOT ABOVE +010C C # LATIN CAPITAL LETTER C WITH CARON +010D c # LATIN SMALL LETTER C WITH CARON +010E D # LATIN CAPITAL LETTER D WITH CARON +010F d # LATIN SMALL LETTER D WITH CARON +0110 D # LATIN CAPITAL LETTER D WITH STROKE +0111 d # LATIN SMALL LETTER D WITH STROKE +0112 E # LATIN CAPITAL LETTER E WITH MACRON +0113 e # LATIN SMALL LETTER E WITH MACRON +0114 E # LATIN CAPITAL LETTER E WITH BREVE +0115 e # LATIN SMALL LETTER E WITH BREVE +0116 E # LATIN CAPITAL LETTER E WITH DOT ABOVE +0117 e # LATIN SMALL LETTER E WITH DOT ABOVE +0118 E # LATIN CAPITAL LETTER E WITH OGONEK +0119 e # LATIN SMALL LETTER E WITH OGONEK +011A E # LATIN CAPITAL LETTER E WITH CARON +011B e # LATIN SMALL LETTER E WITH CARON +011C ^G # LATIN CAPITAL LETTER G WITH CIRCUMFLEX +011D ^g # LATIN SMALL LETTER G WITH CIRCUMFLEX +011E G # LATIN CAPITAL LETTER G WITH BREVE +011F g # LATIN SMALL LETTER G WITH BREVE +0120 G # LATIN CAPITAL LETTER G WITH DOT ABOVE +0121 g # LATIN SMALL LETTER G WITH DOT ABOVE +0122 G # LATIN CAPITAL LETTER G WITH CEDILLA +0123 g # LATIN SMALL LETTER G WITH CEDILLA +0124 ^H # LATIN CAPITAL LETTER H WITH CIRCUMFLEX +0125 ^h # LATIN SMALL LETTER H WITH CIRCUMFLEX +0126 H # LATIN CAPITAL LETTER H WITH STROKE +0127 h # LATIN SMALL LETTER H WITH STROKE +0128 ~I # LATIN CAPITAL LETTER I WITH TILDE +0129 ~i # LATIN SMALL LETTER I WITH TILDE +012A I # LATIN CAPITAL LETTER I WITH MACRON +012B i # LATIN SMALL LETTER I WITH MACRON +012C I # LATIN CAPITAL LETTER I WITH BREVE +012D i # LATIN SMALL LETTER I WITH BREVE +012E I # LATIN CAPITAL LETTER I WITH OGONEK +012F i # LATIN SMALL LETTER I WITH OGONEK +0130 I # LATIN CAPITAL LETTER I WITH DOT ABOVE +0131 i # LATIN SMALL LETTER DOTLESS I +0132 IJ # LATIN CAPITAL LIGATURE IJ +0133 ij # LATIN SMALL LIGATURE IJ +0134 ^J # LATIN CAPITAL LETTER J WITH CIRCUMFLEX +0135 ^j # LATIN SMALL LETTER J WITH CIRCUMFLEX +0136 K # LATIN CAPITAL LETTER K WITH CEDILLA +0137 k # LATIN SMALL LETTER K WITH CEDILLA +0138 # LATIN SMALL LETTER KRA +0139 L # LATIN CAPITAL LETTER L WITH ACUTE +013A l # LATIN SMALL LETTER L WITH ACUTE +013B L # LATIN CAPITAL LETTER L WITH CEDILLA +013C l # LATIN SMALL LETTER L WITH CEDILLA +013D L # LATIN CAPITAL LETTER L WITH CARON +013E l # LATIN SMALL LETTER L WITH CARON +013F L # LATIN CAPITAL LETTER L WITH MIDDLE DOT +0140 l # LATIN SMALL LETTER L WITH MIDDLE DOT +0141 L # LATIN CAPITAL LETTER L WITH STROKE +0142 l # LATIN SMALL LETTER L WITH STROKE +0143 ´N # LATIN CAPITAL LETTER N WITH ACUTE +0144 ´n # LATIN SMALL LETTER N WITH ACUTE +0145 N # LATIN CAPITAL LETTER N WITH CEDILLA +0146 n # LATIN SMALL LETTER N WITH CEDILLA +0147 N # LATIN CAPITAL LETTER N WITH CARON +0148 n # LATIN SMALL LETTER N WITH CARON +0149 'n # LATIN SMALL LETTER N PRECEDED BY APOSTROPHE +014A # LATIN CAPITAL LETTER ENG +014B # LATIN SMALL LETTER ENG +014C O # LATIN CAPITAL LETTER O WITH MACRON +014D o # LATIN SMALL LETTER O WITH MACRON +014E O # LATIN CAPITAL LETTER O WITH BREVE +014F o # LATIN SMALL LETTER O WITH BREVE +0150 "O # LATIN CAPITAL LETTER O WITH DOUBLE ACUTE +0151 "o # LATIN SMALL LETTER O WITH DOUBLE ACUTE +0152 OE # LATIN CAPITAL LIGATURE OE +0153 oe # LATIN SMALL LIGATURE OE +0154 ´R # LATIN CAPITAL LETTER R WITH ACUTE +0155 ´r # LATIN SMALL LETTER R WITH ACUTE +0156 R # LATIN CAPITAL LETTER R WITH CEDILLA +0157 r # LATIN SMALL LETTER R WITH CEDILLA +0158 R # LATIN CAPITAL LETTER R WITH CARON +0159 r # LATIN SMALL LETTER R WITH CARON +015A ´S # LATIN CAPITAL LETTER S WITH ACUTE +015B ´s # LATIN SMALL LETTER S WITH ACUTE +015C ^S # LATIN CAPITAL LETTER S WITH CIRCUMFLEX +015D ^s # LATIN SMALL LETTER S WITH CIRCUMFLEX +015E S # LATIN CAPITAL LETTER S WITH CEDILLA +015F s # LATIN SMALL LETTER S WITH CEDILLA +0160 S # LATIN CAPITAL LETTER S WITH CARON +0161 s # LATIN SMALL LETTER S WITH CARON +0162 T # LATIN CAPITAL LETTER T WITH CEDILLA +0163 t # LATIN SMALL LETTER T WITH CEDILLA +0164 T # LATIN CAPITAL LETTER T WITH CARON +0165 t # LATIN SMALL LETTER T WITH CARON +0166 T # LATIN CAPITAL LETTER T WITH STROKE +0167 t # LATIN SMALL LETTER T WITH STROKE +0168 ~U # LATIN CAPITAL LETTER U WITH TILDE +0169 ~u # LATIN SMALL LETTER U WITH TILDE +016A U # LATIN CAPITAL LETTER U WITH MACRON +016B u # LATIN SMALL LETTER U WITH MACRON +016C U # LATIN CAPITAL LETTER U WITH BREVE +016D u # LATIN SMALL LETTER U WITH BREVE +016E U # LATIN CAPITAL LETTER U WITH RING ABOVE +016F u # LATIN SMALL LETTER U WITH RING ABOVE +0170 "U # LATIN CAPITAL LETTER U WITH DOUBLE ACUTE +0171 "u # LATIN SMALL LETTER U WITH DOUBLE ACUTE +0172 U # LATIN CAPITAL LETTER U WITH OGONEK +0173 u # LATIN SMALL LETTER U WITH OGONEK +0174 ^W # LATIN CAPITAL LETTER W WITH CIRCUMFLEX +0175 ^w # LATIN SMALL LETTER W WITH CIRCUMFLEX +0176 ^Y # LATIN CAPITAL LETTER Y WITH CIRCUMFLEX +0177 ^y # LATIN SMALL LETTER Y WITH CIRCUMFLEX +0178 "Y # LATIN CAPITAL LETTER Y WITH DIAERESIS +0179 ´Z # LATIN CAPITAL LETTER Z WITH ACUTE +017A ´z # LATIN SMALL LETTER Z WITH ACUTE +017B Z # LATIN CAPITAL LETTER Z WITH DOT ABOVE +017C z # LATIN SMALL LETTER Z WITH DOT ABOVE +017D Z # LATIN CAPITAL LETTER Z WITH CARON +017E z # LATIN SMALL LETTER Z WITH CARON +017F s # LATIN SMALL LETTER LONG S +018F # LATIN CAPITAL LETTER SCHWA +0192 f # LATIN SMALL LETTER F WITH HOOK +01C4 DŽ # LATIN CAPITAL LETTER DZ WITH CARON +01C5 Dž # LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON +01C6 dž # LATIN SMALL LETTER DZ WITH CARON +01C7 LJ # LATIN CAPITAL LETTER LJ +01C8 Lj # LATIN CAPITAL LETTER L WITH SMALL LETTER J +01C9 lj # LATIN SMALL LETTER LJ +01CA NJ # LATIN CAPITAL LETTER NJ +01CB Nj # LATIN CAPITAL LETTER N WITH SMALL LETTER J +01CC nj # LATIN SMALL LETTER NJ +01F1 DZ # LATIN CAPITAL LETTER DZ +01F2 Dz # LATIN CAPITAL LETTER D WITH SMALL LETTER Z +01F3 dz # LATIN SMALL LETTER DZ +0218 S # LATIN CAPITAL LETTER S WITH COMMA BELOW +0219 s # LATIN SMALL LETTER S WITH COMMA BELOW +021A T # LATIN CAPITAL LETTER T WITH COMMA BELOW +021B t # LATIN SMALL LETTER T WITH COMMA BELOW +0259 # LATIN SMALL LETTER SCHWA +02B9 ′ # MODIFIER LETTER PRIME +02BA ″ # MODIFIER LETTER DOUBLE PRIME +02BB ‘ # MODIFIER LETTER TURNED COMMA +02BC ’ # MODIFIER LETTER APOSTROPHE +02BD ‛ # MODIFIER LETTER REVERSED COMMA +02C6 ^ # MODIFIER LETTER CIRCUMFLEX ACCENT +02C7 # CARON +02C8 ' # MODIFIER LETTER VERTICAL LINE +02C9 ¯ # MODIFIER LETTER MACRON +02CA ´ # MODIFIER LETTER ACUTE ACCENT +02CB ` # MODIFIER LETTER GRAVE ACCENT +02CD _ # MODIFIER LETTER LOW MACRON +02D8 # BREVE +02D9 # DOT ABOVE +02DA # RING ABOVE +02DB # OGONEK +02DC ~ # SMALL TILDE +02DD " # DOUBLE ACUTE ACCENT +0374 # GREEK NUMERAL SIGN +0375 # GREEK LOWER NUMERAL SIGN +037A # GREEK YPOGEGRAMMENI +037E # GREEK QUESTION MARK +0384 # GREEK TONOS +0385 # GREEK DIALYTIKA TONOS +0386 # GREEK CAPITAL LETTER ALPHA WITH TONOS +0387 # GREEK ANO TELEIA +0388 # GREEK CAPITAL LETTER EPSILON WITH TONOS +0389 # GREEK CAPITAL LETTER ETA WITH TONOS +038A # GREEK CAPITAL LETTER IOTA WITH TONOS +038C # GREEK CAPITAL LETTER OMICRON WITH TONOS +038E # GREEK CAPITAL LETTER UPSILON WITH TONOS +038F # GREEK CAPITAL LETTER OMEGA WITH TONOS +0390 # GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS +0391 # GREEK CAPITAL LETTER ALPHA +0392 # GREEK CAPITAL LETTER BETA +0393 # GREEK CAPITAL LETTER GAMMA +0394 # GREEK CAPITAL LETTER DELTA +0395 # GREEK CAPITAL LETTER EPSILON +0396 # GREEK CAPITAL LETTER ZETA +0397 # GREEK CAPITAL LETTER ETA +0398 # GREEK CAPITAL LETTER THETA +0399 # GREEK CAPITAL LETTER IOTA +039A # GREEK CAPITAL LETTER KAPPA +039B # GREEK CAPITAL LETTER LAMDA +039C # GREEK CAPITAL LETTER MU +039D # GREEK CAPITAL LETTER NU +039E # GREEK CAPITAL LETTER XI +039F # GREEK CAPITAL LETTER OMICRON +03A0 # GREEK CAPITAL LETTER PI +03A1 # GREEK CAPITAL LETTER RHO +03A3 # GREEK CAPITAL LETTER SIGMA +03A4 # GREEK CAPITAL LETTER TAU +03A5 # GREEK CAPITAL LETTER UPSILON +03A6 # GREEK CAPITAL LETTER PHI +03A7 # GREEK CAPITAL LETTER CHI +03A8 # GREEK CAPITAL LETTER PSI +03A9 # GREEK CAPITAL LETTER OMEGA +03AA # GREEK CAPITAL LETTER IOTA WITH DIALYTIKA +03AB # GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA +03AC # GREEK SMALL LETTER ALPHA WITH TONOS +03AD # GREEK SMALL LETTER EPSILON WITH TONOS +03AE # GREEK SMALL LETTER ETA WITH TONOS +03AF # GREEK SMALL LETTER IOTA WITH TONOS +03B0 # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS +03B1 # GREEK SMALL LETTER ALPHA +03B2 # GREEK SMALL LETTER BETA +03B3 # GREEK SMALL LETTER GAMMA +03B4 # GREEK SMALL LETTER DELTA +03B5 # GREEK SMALL LETTER EPSILON +03B6 # GREEK SMALL LETTER ZETA +03B7 # GREEK SMALL LETTER ETA +03B8 # GREEK SMALL LETTER THETA +03B9 # GREEK SMALL LETTER IOTA +03BA # GREEK SMALL LETTER KAPPA +03BB # GREEK SMALL LETTER LAMDA +03BC # GREEK SMALL LETTER MU +03BD # GREEK SMALL LETTER NU +03BE # GREEK SMALL LETTER XI +03BF # GREEK SMALL LETTER OMICRON +03C0 # GREEK SMALL LETTER PI +03C1 # GREEK SMALL LETTER RHO +03C2 # GREEK SMALL LETTER FINAL SIGMA +03C3 # GREEK SMALL LETTER SIGMA +03C4 # GREEK SMALL LETTER TAU +03C5 # GREEK SMALL LETTER UPSILON +03C6 # GREEK SMALL LETTER PHI +03C7 # GREEK SMALL LETTER CHI +03C8 # GREEK SMALL LETTER PSI +03C9 # GREEK SMALL LETTER OMEGA +03CA # GREEK SMALL LETTER IOTA WITH DIALYTIKA +03CB # GREEK SMALL LETTER UPSILON WITH DIALYTIKA +03CC # GREEK SMALL LETTER OMICRON WITH TONOS +03CD # GREEK SMALL LETTER UPSILON WITH TONOS +03CE # GREEK SMALL LETTER OMEGA WITH TONOS +03D0 β # GREEK BETA SYMBOL +03D1 θ # GREEK THETA SYMBOL +03D2 Î¥ # GREEK UPSILON WITH HOOK SYMBOL +03D5 φ # GREEK PHI SYMBOL +03D6 Ï€ # GREEK PI SYMBOL +03F0 κ # GREEK KAPPA SYMBOL +03F1 Ï # GREEK RHO SYMBOL +03F2 Ï‚ # GREEK LUNATE SIGMA SYMBOL +03F4 Θ # GREEK CAPITAL THETA SYMBOL +03F5 ε # GREEK LUNATE EPSILON SYMBOL +03F9 Σ # GREEK CAPITAL LUNATE SIGMA SYMBOL +0401 # CYRILLIC CAPITAL LETTER IO +0402 # CYRILLIC CAPITAL LETTER DJE +0403 # CYRILLIC CAPITAL LETTER GJE +0404 # CYRILLIC CAPITAL LETTER UKRAINIAN IE +0405 # CYRILLIC CAPITAL LETTER DZE +0406 # CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I +0407 # CYRILLIC CAPITAL LETTER YI +0408 # CYRILLIC CAPITAL LETTER JE +0409 # CYRILLIC CAPITAL LETTER LJE +040A # CYRILLIC CAPITAL LETTER NJE +040B # CYRILLIC CAPITAL LETTER TSHE +040C # CYRILLIC CAPITAL LETTER KJE +040E # CYRILLIC CAPITAL LETTER SHORT U +040F # CYRILLIC CAPITAL LETTER DZHE +0410 # CYRILLIC CAPITAL LETTER A +0411 # CYRILLIC CAPITAL LETTER BE +0412 # CYRILLIC CAPITAL LETTER VE +0413 # CYRILLIC CAPITAL LETTER GHE +0414 # CYRILLIC CAPITAL LETTER DE +0415 # CYRILLIC CAPITAL LETTER IE +0416 # CYRILLIC CAPITAL LETTER ZHE +0417 # CYRILLIC CAPITAL LETTER ZE +0418 # CYRILLIC CAPITAL LETTER I +0419 # CYRILLIC CAPITAL LETTER SHORT I +041A # CYRILLIC CAPITAL LETTER KA +041B # CYRILLIC CAPITAL LETTER EL +041C # CYRILLIC CAPITAL LETTER EM +041D # CYRILLIC CAPITAL LETTER EN +041E # CYRILLIC CAPITAL LETTER O +041F # CYRILLIC CAPITAL LETTER PE +0420 # CYRILLIC CAPITAL LETTER ER +0421 # CYRILLIC CAPITAL LETTER ES +0422 # CYRILLIC CAPITAL LETTER TE +0423 # CYRILLIC CAPITAL LETTER U +0424 # CYRILLIC CAPITAL LETTER EF +0425 # CYRILLIC CAPITAL LETTER HA +0426 # CYRILLIC CAPITAL LETTER TSE +0427 # CYRILLIC CAPITAL LETTER CHE +0428 # CYRILLIC CAPITAL LETTER SHA +0429 # CYRILLIC CAPITAL LETTER SHCHA +042A # CYRILLIC CAPITAL LETTER HARD SIGN +042B # CYRILLIC CAPITAL LETTER YERU +042C # CYRILLIC CAPITAL LETTER SOFT SIGN +042D # CYRILLIC CAPITAL LETTER E +042E # CYRILLIC CAPITAL LETTER YU +042F # CYRILLIC CAPITAL LETTER YA +0430 # CYRILLIC SMALL LETTER A +0431 # CYRILLIC SMALL LETTER BE +0432 # CYRILLIC SMALL LETTER VE +0433 # CYRILLIC SMALL LETTER GHE +0434 # CYRILLIC SMALL LETTER DE +0435 # CYRILLIC SMALL LETTER IE +0436 # CYRILLIC SMALL LETTER ZHE +0437 # CYRILLIC SMALL LETTER ZE +0438 # CYRILLIC SMALL LETTER I +0439 # CYRILLIC SMALL LETTER SHORT I +043A # CYRILLIC SMALL LETTER KA +043B # CYRILLIC SMALL LETTER EL +043C # CYRILLIC SMALL LETTER EM +043D # CYRILLIC SMALL LETTER EN +043E # CYRILLIC SMALL LETTER O +043F # CYRILLIC SMALL LETTER PE +0440 # CYRILLIC SMALL LETTER ER +0441 # CYRILLIC SMALL LETTER ES +0442 # CYRILLIC SMALL LETTER TE +0443 # CYRILLIC SMALL LETTER U +0444 # CYRILLIC SMALL LETTER EF +0445 # CYRILLIC SMALL LETTER HA +0446 # CYRILLIC SMALL LETTER TSE +0447 # CYRILLIC SMALL LETTER CHE +0448 # CYRILLIC SMALL LETTER SHA +0449 # CYRILLIC SMALL LETTER SHCHA +044A # CYRILLIC SMALL LETTER HARD SIGN +044B # CYRILLIC SMALL LETTER YERU +044C # CYRILLIC SMALL LETTER SOFT SIGN +044D # CYRILLIC SMALL LETTER E +044E # CYRILLIC SMALL LETTER YU +044F # CYRILLIC SMALL LETTER YA +0451 # CYRILLIC SMALL LETTER IO +0452 # CYRILLIC SMALL LETTER DJE +0453 # CYRILLIC SMALL LETTER GJE +0454 # CYRILLIC SMALL LETTER UKRAINIAN IE +0455 # CYRILLIC SMALL LETTER DZE +0456 # CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I +0457 # CYRILLIC SMALL LETTER YI +0458 # CYRILLIC SMALL LETTER JE +0459 # CYRILLIC SMALL LETTER LJE +045A # CYRILLIC SMALL LETTER NJE +045B # CYRILLIC SMALL LETTER TSHE +045C # CYRILLIC SMALL LETTER KJE +045E # CYRILLIC SMALL LETTER SHORT U +045F # CYRILLIC SMALL LETTER DZHE +0490 # CYRILLIC CAPITAL LETTER GHE WITH UPTURN +0491 # CYRILLIC SMALL LETTER GHE WITH UPTURN +0587 Õ¥Ö‚ # ARMENIAN SMALL LIGATURE ECH YIWN +05D0 # HEBREW LETTER ALEF +05D1 # HEBREW LETTER BET +05D2 # HEBREW LETTER GIMEL +05D3 # HEBREW LETTER DALET +05D4 # HEBREW LETTER HE +05D5 # HEBREW LETTER VAV +05D6 # HEBREW LETTER ZAYIN +05D7 # HEBREW LETTER HET +05D8 # HEBREW LETTER TET +05D9 # HEBREW LETTER YOD +05DA # HEBREW LETTER FINAL KAF +05DB # HEBREW LETTER KAF +05DC # HEBREW LETTER LAMED +05DD # HEBREW LETTER FINAL MEM +05DE # HEBREW LETTER MEM +05DF # HEBREW LETTER FINAL NUN +05E0 # HEBREW LETTER NUN +05E1 # HEBREW LETTER SAMEKH +05E2 # HEBREW LETTER AYIN +05E3 # HEBREW LETTER FINAL PE +05E4 # HEBREW LETTER PE +05E5 # HEBREW LETTER FINAL TSADI +05E6 # HEBREW LETTER TSADI +05E7 # HEBREW LETTER QOF +05E8 # HEBREW LETTER RESH +05E9 # HEBREW LETTER SHIN +05EA # HEBREW LETTER TAV +05F0 וו # HEBREW LIGATURE YIDDISH DOUBLE VAV +05F1 וי # HEBREW LIGATURE YIDDISH VAV YOD +05F2 ×™×™ # HEBREW LIGATURE YIDDISH DOUBLE YOD +0675 اٴ # ARABIC LETTER HIGH HAMZA ALEF +0676 وٴ # ARABIC LETTER HIGH HAMZA WAW +0677 Û‡Ù´ # ARABIC LETTER U WITH HAMZA ABOVE +0678 يٴ # ARABIC LETTER HIGH HAMZA YEH +0E33 à¹à¸² # THAI CHARACTER SARA AM +0EB3 à»àº² # LAO VOWEL SIGN AM +0EDC ຫນ # LAO HO NO +0EDD ຫມ # LAO HO MO +0F77 ྲྠ# TIBETAN VOWEL SIGN VOCALIC RR +0F79 ླྠ# TIBETAN VOWEL SIGN VOCALIC LL +1E02 B # LATIN CAPITAL LETTER B WITH DOT ABOVE +1E03 b # LATIN SMALL LETTER B WITH DOT ABOVE +1E0A D # LATIN CAPITAL LETTER D WITH DOT ABOVE +1E0B d # LATIN SMALL LETTER D WITH DOT ABOVE +1E1E F # LATIN CAPITAL LETTER F WITH DOT ABOVE +1E1F f # LATIN SMALL LETTER F WITH DOT ABOVE +1E40 M # LATIN CAPITAL LETTER M WITH DOT ABOVE +1E41 m # LATIN SMALL LETTER M WITH DOT ABOVE +1E56 P # LATIN CAPITAL LETTER P WITH DOT ABOVE +1E57 p # LATIN SMALL LETTER P WITH DOT ABOVE +1E60 S # LATIN CAPITAL LETTER S WITH DOT ABOVE +1E61 s # LATIN SMALL LETTER S WITH DOT ABOVE +1E6A T # LATIN CAPITAL LETTER T WITH DOT ABOVE +1E6B t # LATIN SMALL LETTER T WITH DOT ABOVE +1E80 `W # LATIN CAPITAL LETTER W WITH GRAVE +1E81 `w # LATIN SMALL LETTER W WITH GRAVE +1E82 ´W # LATIN CAPITAL LETTER W WITH ACUTE +1E83 ´w # LATIN SMALL LETTER W WITH ACUTE +1E84 "W # LATIN CAPITAL LETTER W WITH DIAERESIS +1E85 "w # LATIN SMALL LETTER W WITH DIAERESIS +1E9A aʾ # LATIN SMALL LETTER A WITH RIGHT HALF RING +1EF2 `Y # LATIN CAPITAL LETTER Y WITH GRAVE +1EF3 `y # LATIN SMALL LETTER Y WITH GRAVE +2002 # EN SPACE +2003 # EM SPACE +2004 # THREE-PER-EM SPACE +2005 # FOUR-PER-EM SPACE +2006 # SIX-PER-EM SPACE +2008 # PUNCTUATION SPACE +2009 # THIN SPACE +200A # HAIR SPACE +2010 - # HYPHEN +2011 - # NON-BREAKING HYPHEN +2012 - # FIGURE DASH +2013 - # EN DASH +2014 - # EM DASH +2015 - # HORIZONTAL BAR +2016 # DOUBLE VERTICAL LINE +2017 # DOUBLE LOW LINE +2018 ' # LEFT SINGLE QUOTATION MARK +2019 ' # RIGHT SINGLE QUOTATION MARK +201A , # SINGLE LOW-9 QUOTATION MARK +201B ' # SINGLE HIGH-REVERSED-9 QUOTATION MARK +201C " # LEFT DOUBLE QUOTATION MARK +201D " # RIGHT DOUBLE QUOTATION MARK +201E " # DOUBLE LOW-9 QUOTATION MARK +201F " # DOUBLE HIGH-REVERSED-9 QUOTATION MARK +2020 + # DAGGER +2021 # DOUBLE DAGGER +2022 o # BULLET +2024 . # ONE DOT LEADER +2025 .. # TWO DOT LEADER +2026 ... # HORIZONTAL ELLIPSIS +2030 o/oo # PER MILLE SIGN +2032 ´ # PRIME +2033 ´´ # DOUBLE PRIME +2034 ´´´ # TRIPLE PRIME +2036 ‵‵ # REVERSED DOUBLE PRIME +2037 ‵‵‵ # REVERSED TRIPLE PRIME +2039 < # SINGLE LEFT-POINTING ANGLE QUOTATION MARK +203A > # SINGLE RIGHT-POINTING ANGLE QUOTATION MARK +203C !! # DOUBLE EXCLAMATION MARK +203E # OVERLINE +2044 / # FRACTION SLASH +2047 ?? # DOUBLE QUESTION MARK +2048 ?! # QUESTION EXCLAMATION MARK +2049 !? # EXCLAMATION QUESTION MARK +2057 ´´´´ # QUADRUPLE PRIME +20A8 Rs # RUPEE SIGN +20AB Äồng # DONG SIGN +20AC EUR # EURO SIGN +2100 a/c # ACCOUNT OF +2101 a/s # ADDRESSED TO THE SUBJECT +2102 C # DOUBLE-STRUCK CAPITAL C +2103 °C # DEGREE CELSIUS +2105 c/o # CARE OF +2106 c/u # CADA UNA +2107 Æ # EULER CONSTANT +2109 °F # DEGREE FAHRENHEIT +210A g # SCRIPT SMALL G +210B H # SCRIPT CAPITAL H +210C H # BLACK-LETTER CAPITAL H +210D H # DOUBLE-STRUCK CAPITAL H +210E h # PLANCK CONSTANT +210F ħ # PLANCK CONSTANT OVER TWO PI +2110 I # SCRIPT CAPITAL I +2111 I # BLACK-LETTER CAPITAL I +2112 L # SCRIPT CAPITAL L +2113 l # SCRIPT SMALL L +2115 N # DOUBLE-STRUCK CAPITAL N +2116 No # NUMERO SIGN +2119 P # DOUBLE-STRUCK CAPITAL P +211A Q # DOUBLE-STRUCK CAPITAL Q +211B R # SCRIPT CAPITAL R +211C R # BLACK-LETTER CAPITAL R +211D R # DOUBLE-STRUCK CAPITAL R +2121 TEL # TELEPHONE SIGN +2122 TM # TRADE MARK SIGN +2124 Z # DOUBLE-STRUCK CAPITAL Z +2126 Ohm # OHM SIGN +2128 Z # BLACK-LETTER CAPITAL Z +212C B # SCRIPT CAPITAL B +212D C # BLACK-LETTER CAPITAL C +212E e # ESTIMATED SYMBOL +212F e # SCRIPT SMALL E +2130 E # SCRIPT CAPITAL E +2131 F # SCRIPT CAPITAL F +2133 M # SCRIPT CAPITAL M +2134 o # SCRIPT SMALL O +2135 × # ALEF SYMBOL +2136 ב # BET SYMBOL +2137 ×’ # GIMEL SYMBOL +2138 ד # DALET SYMBOL +2139 i # INFORMATION SOURCE +213B FAX # FACSIMILE SIGN +213D γ # DOUBLE-STRUCK SMALL GAMMA +213E Γ # DOUBLE-STRUCK CAPITAL GAMMA +213F Π # DOUBLE-STRUCK CAPITAL PI +2140 ∑ # DOUBLE-STRUCK N-ARY SUMMATION +2145 D # DOUBLE-STRUCK ITALIC CAPITAL D +2146 d # DOUBLE-STRUCK ITALIC SMALL D +2147 e # DOUBLE-STRUCK ITALIC SMALL E +2148 i # DOUBLE-STRUCK ITALIC SMALL I +2149 j # DOUBLE-STRUCK ITALIC SMALL J +2153 1â„3 # VULGAR FRACTION ONE THIRD +2154 2â„3 # VULGAR FRACTION TWO THIRDS +2155 1â„5 # VULGAR FRACTION ONE FIFTH +2156 2â„5 # VULGAR FRACTION TWO FIFTHS +2157 3â„5 # VULGAR FRACTION THREE FIFTHS +2158 4â„5 # VULGAR FRACTION FOUR FIFTHS +2159 1â„6 # VULGAR FRACTION ONE SIXTH +215A 5â„6 # VULGAR FRACTION FIVE SIXTHS +215B 1â„8 # VULGAR FRACTION ONE EIGHTH +215C 3â„8 # VULGAR FRACTION THREE EIGHTHS +215D 5â„8 # VULGAR FRACTION FIVE EIGHTHS +215E 7â„8 # VULGAR FRACTION SEVEN EIGHTHS +215F 1â„ # FRACTION NUMERATOR ONE +2160 I # ROMAN NUMERAL ONE +2161 II # ROMAN NUMERAL TWO +2162 III # ROMAN NUMERAL THREE +2163 IV # ROMAN NUMERAL FOUR +2164 V # ROMAN NUMERAL FIVE +2165 VI # ROMAN NUMERAL SIX +2166 VII # ROMAN NUMERAL SEVEN +2167 VIII # ROMAN NUMERAL EIGHT +2168 IX # ROMAN NUMERAL NINE +2169 X # ROMAN NUMERAL TEN +216A XI # ROMAN NUMERAL ELEVEN +216B XII # ROMAN NUMERAL TWELVE +216C L # ROMAN NUMERAL FIFTY +216D C # ROMAN NUMERAL ONE HUNDRED +216E D # ROMAN NUMERAL FIVE HUNDRED +216F M # ROMAN NUMERAL ONE THOUSAND +2170 i # SMALL ROMAN NUMERAL ONE +2171 ii # SMALL ROMAN NUMERAL TWO +2172 iii # SMALL ROMAN NUMERAL THREE +2173 iv # SMALL ROMAN NUMERAL FOUR +2174 v # SMALL ROMAN NUMERAL FIVE +2175 vi # SMALL ROMAN NUMERAL SIX +2176 vii # SMALL ROMAN NUMERAL SEVEN +2177 viii # SMALL ROMAN NUMERAL EIGHT +2178 ix # SMALL ROMAN NUMERAL NINE +2179 x # SMALL ROMAN NUMERAL TEN +217A xi # SMALL ROMAN NUMERAL ELEVEN +217B xii # SMALL ROMAN NUMERAL TWELVE +217C l # SMALL ROMAN NUMERAL FIFTY +217D c # SMALL ROMAN NUMERAL ONE HUNDRED +217E d # SMALL ROMAN NUMERAL FIVE HUNDRED +217F m # SMALL ROMAN NUMERAL ONE THOUSAND +2190 <- # LEFTWARDS ARROW +2191 ^ # UPWARDS ARROW +2192 -> # RIGHTWARDS ARROW +2193 V # DOWNWARDS ARROW +2194 <-> # LEFT RIGHT ARROW +21D0 <= # LEFTWARDS DOUBLE ARROW +21D2 => # RIGHTWARDS DOUBLE ARROW +21D4 <=> # LEFT RIGHT DOUBLE ARROW +2212 - # MINUS SIGN +2215 / # DIVISION SLASH +2216 \ # SET MINUS +2217 * # ASTERISK OPERATOR +2219 • # BULLET OPERATOR +2223 | # DIVIDES +222C ∫∫ # DOUBLE INTEGRAL +222D ∫∫∫ # TRIPLE INTEGRAL +222F ∮∮ # SURFACE INTEGRAL +2230 ∮∮∮ # VOLUME INTEGRAL +2236 : # RATIO +223C ~ # TILDE OPERATOR +2260 /= # NOT EQUAL TO +2264 <= # LESS-THAN OR EQUAL TO +2265 >= # GREATER-THAN OR EQUAL TO +226A << # MUCH LESS-THAN +226B >> # MUCH GREATER-THAN +22C5 · # DOT OPERATOR +22D8 <<< # VERY MUCH LESS-THAN +22D9 >>> # VERY MUCH GREATER-THAN +22EF ··· # MIDLINE HORIZONTAL ELLIPSIS +2400 [NUL] # SYMBOL FOR NULL +2401 [SOH] # SYMBOL FOR START OF HEADING +2402 [STX] # SYMBOL FOR START OF TEXT +2403 [ETX] # SYMBOL FOR END OF TEXT +2404 [EOT] # SYMBOL FOR END OF TRANSMISSION +2405 [ENQ] # SYMBOL FOR ENQUIRY +2406 [ACK] # SYMBOL FOR ACKNOWLEDGE +2407 [BEL] # SYMBOL FOR BELL +2408 [BS] # SYMBOL FOR BACKSPACE +2409 [HT] # SYMBOL FOR HORIZONTAL TABULATION +240A [LF] # SYMBOL FOR LINE FEED +240B [VT] # SYMBOL FOR VERTICAL TABULATION +240C [FF] # SYMBOL FOR FORM FEED +240D [CR] # SYMBOL FOR CARRIAGE RETURN +240E [SO] # SYMBOL FOR SHIFT OUT +240F [SI] # SYMBOL FOR SHIFT IN +2410 [DLE] # SYMBOL FOR DATA LINK ESCAPE +2411 [DC1] # SYMBOL FOR DEVICE CONTROL ONE +2412 [DC2] # SYMBOL FOR DEVICE CONTROL TWO +2413 [DC3] # SYMBOL FOR DEVICE CONTROL THREE +2414 [DC4] # SYMBOL FOR DEVICE CONTROL FOUR +2415 [NAK] # SYMBOL FOR NEGATIVE ACKNOWLEDGE +2416 [SYN] # SYMBOL FOR SYNCHRONOUS IDLE +2417 [ETB] # SYMBOL FOR END OF TRANSMISSION BLOCK +2418 [CAN] # SYMBOL FOR CANCEL +2419 [EM] # SYMBOL FOR END OF MEDIUM +241A [SUB] # SYMBOL FOR SUBSTITUTE +241B [ESC] # SYMBOL FOR ESCAPE +241C [FS] # SYMBOL FOR FILE SEPARATOR +241D [GS] # SYMBOL FOR GROUP SEPARATOR +241E [RS] # SYMBOL FOR RECORD SEPARATOR +241F [US] # SYMBOL FOR UNIT SEPARATOR +2420 [SP] # SYMBOL FOR SPACE +2421 [DEL] # SYMBOL FOR DELETE +2424 [NL] # SYMBOL FOR NEWLINE +2460 (1) # CIRCLED DIGIT ONE +2461 (2) # CIRCLED DIGIT TWO +2462 (3) # CIRCLED DIGIT THREE +2463 (4) # CIRCLED DIGIT FOUR +2464 (5) # CIRCLED DIGIT FIVE +2465 (6) # CIRCLED DIGIT SIX +2466 (7) # CIRCLED DIGIT SEVEN +2467 (8) # CIRCLED DIGIT EIGHT +2468 (9) # CIRCLED DIGIT NINE +2469 (10) # CIRCLED NUMBER TEN +246A (11) # CIRCLED NUMBER ELEVEN +246B (12) # CIRCLED NUMBER TWELVE +246C (13) # CIRCLED NUMBER THIRTEEN +246D (14) # CIRCLED NUMBER FOURTEEN +246E (15) # CIRCLED NUMBER FIFTEEN +246F (16) # CIRCLED NUMBER SIXTEEN +2470 (17) # CIRCLED NUMBER SEVENTEEN +2471 (18) # CIRCLED NUMBER EIGHTEEN +2472 (19) # CIRCLED NUMBER NINETEEN +2473 (20) # CIRCLED NUMBER TWENTY +2474 (1) # PARENTHESIZED DIGIT ONE +2475 (2) # PARENTHESIZED DIGIT TWO +2476 (3) # PARENTHESIZED DIGIT THREE +2477 (4) # PARENTHESIZED DIGIT FOUR +2478 (5) # PARENTHESIZED DIGIT FIVE +2479 (6) # PARENTHESIZED DIGIT SIX +247A (7) # PARENTHESIZED DIGIT SEVEN +247B (8) # PARENTHESIZED DIGIT EIGHT +247C (9) # PARENTHESIZED DIGIT NINE +247D (10) # PARENTHESIZED NUMBER TEN +247E (11) # PARENTHESIZED NUMBER ELEVEN +247F (12) # PARENTHESIZED NUMBER TWELVE +2480 (13) # PARENTHESIZED NUMBER THIRTEEN +2481 (14) # PARENTHESIZED NUMBER FOURTEEN +2482 (15) # PARENTHESIZED NUMBER FIFTEEN +2483 (16) # PARENTHESIZED NUMBER SIXTEEN +2484 (17) # PARENTHESIZED NUMBER SEVENTEEN +2485 (18) # PARENTHESIZED NUMBER EIGHTEEN +2486 (19) # PARENTHESIZED NUMBER NINETEEN +2487 (20) # PARENTHESIZED NUMBER TWENTY +2488 1. # DIGIT ONE FULL STOP +2489 2. # DIGIT TWO FULL STOP +248A 3. # DIGIT THREE FULL STOP +248B 4. # DIGIT FOUR FULL STOP +248C 5. # DIGIT FIVE FULL STOP +248D 6. # DIGIT SIX FULL STOP +248E 7. # DIGIT SEVEN FULL STOP +248F 8. # DIGIT EIGHT FULL STOP +2490 9. # DIGIT NINE FULL STOP +2491 10. # NUMBER TEN FULL STOP +2492 11. # NUMBER ELEVEN FULL STOP +2493 12. # NUMBER TWELVE FULL STOP +2494 13. # NUMBER THIRTEEN FULL STOP +2495 14. # NUMBER FOURTEEN FULL STOP +2496 15. # NUMBER FIFTEEN FULL STOP +2497 16. # NUMBER SIXTEEN FULL STOP +2498 17. # NUMBER SEVENTEEN FULL STOP +2499 18. # NUMBER EIGHTEEN FULL STOP +249A 19. # NUMBER NINETEEN FULL STOP +249B 20. # NUMBER TWENTY FULL STOP +249C (a) # PARENTHESIZED LATIN SMALL LETTER A +249D (b) # PARENTHESIZED LATIN SMALL LETTER B +249E (c) # PARENTHESIZED LATIN SMALL LETTER C +249F (d) # PARENTHESIZED LATIN SMALL LETTER D +24A0 (e) # PARENTHESIZED LATIN SMALL LETTER E +24A1 (f) # PARENTHESIZED LATIN SMALL LETTER F +24A2 (g) # PARENTHESIZED LATIN SMALL LETTER G +24A3 (h) # PARENTHESIZED LATIN SMALL LETTER H +24A4 (i) # PARENTHESIZED LATIN SMALL LETTER I +24A5 (j) # PARENTHESIZED LATIN SMALL LETTER J +24A6 (k) # PARENTHESIZED LATIN SMALL LETTER K +24A7 (l) # PARENTHESIZED LATIN SMALL LETTER L +24A8 (m) # PARENTHESIZED LATIN SMALL LETTER M +24A9 (n) # PARENTHESIZED LATIN SMALL LETTER N +24AA (o) # PARENTHESIZED LATIN SMALL LETTER O +24AB (p) # PARENTHESIZED LATIN SMALL LETTER P +24AC (q) # PARENTHESIZED LATIN SMALL LETTER Q +24AD (r) # PARENTHESIZED LATIN SMALL LETTER R +24AE (s) # PARENTHESIZED LATIN SMALL LETTER S +24AF (t) # PARENTHESIZED LATIN SMALL LETTER T +24B0 (u) # PARENTHESIZED LATIN SMALL LETTER U +24B1 (v) # PARENTHESIZED LATIN SMALL LETTER V +24B2 (w) # PARENTHESIZED LATIN SMALL LETTER W +24B3 (x) # PARENTHESIZED LATIN SMALL LETTER X +24B4 (y) # PARENTHESIZED LATIN SMALL LETTER Y +24B5 (z) # PARENTHESIZED LATIN SMALL LETTER Z +24B6 (A) # CIRCLED LATIN CAPITAL LETTER A +24B7 (B) # CIRCLED LATIN CAPITAL LETTER B +24B8 (C) # CIRCLED LATIN CAPITAL LETTER C +24B9 (D) # CIRCLED LATIN CAPITAL LETTER D +24BA (E) # CIRCLED LATIN CAPITAL LETTER E +24BB (F) # CIRCLED LATIN CAPITAL LETTER F +24BC (G) # CIRCLED LATIN CAPITAL LETTER G +24BD (H) # CIRCLED LATIN CAPITAL LETTER H +24BE (I) # CIRCLED LATIN CAPITAL LETTER I +24BF (J) # CIRCLED LATIN CAPITAL LETTER J +24C0 (K) # CIRCLED LATIN CAPITAL LETTER K +24C1 (L) # CIRCLED LATIN CAPITAL LETTER L +24C2 (M) # CIRCLED LATIN CAPITAL LETTER M +24C3 (N) # CIRCLED LATIN CAPITAL LETTER N +24C4 (O) # CIRCLED LATIN CAPITAL LETTER O +24C5 (P) # CIRCLED LATIN CAPITAL LETTER P +24C6 (Q) # CIRCLED LATIN CAPITAL LETTER Q +24C7 (R) # CIRCLED LATIN CAPITAL LETTER R +24C8 (S) # CIRCLED LATIN CAPITAL LETTER S +24C9 (T) # CIRCLED LATIN CAPITAL LETTER T +24CA (U) # CIRCLED LATIN CAPITAL LETTER U +24CB (V) # CIRCLED LATIN CAPITAL LETTER V +24CC (W) # CIRCLED LATIN CAPITAL LETTER W +24CD (X) # CIRCLED LATIN CAPITAL LETTER X +24CE (Y) # CIRCLED LATIN CAPITAL LETTER Y +24CF (Z) # CIRCLED LATIN CAPITAL LETTER Z +24D0 (a) # CIRCLED LATIN SMALL LETTER A +24D1 (b) # CIRCLED LATIN SMALL LETTER B +24D2 (c) # CIRCLED LATIN SMALL LETTER C +24D3 (d) # CIRCLED LATIN SMALL LETTER D +24D4 (e) # CIRCLED LATIN SMALL LETTER E +24D5 (f) # CIRCLED LATIN SMALL LETTER F +24D6 (g) # CIRCLED LATIN SMALL LETTER G +24D7 (h) # CIRCLED LATIN SMALL LETTER H +24D8 (i) # CIRCLED LATIN SMALL LETTER I +24D9 (j) # CIRCLED LATIN SMALL LETTER J +24DA (k) # CIRCLED LATIN SMALL LETTER K +24DB (l) # CIRCLED LATIN SMALL LETTER L +24DC (m) # CIRCLED LATIN SMALL LETTER M +24DD (n) # CIRCLED LATIN SMALL LETTER N +24DE (o) # CIRCLED LATIN SMALL LETTER O +24DF (p) # CIRCLED LATIN SMALL LETTER P +24E0 (q) # CIRCLED LATIN SMALL LETTER Q +24E1 (r) # CIRCLED LATIN SMALL LETTER R +24E2 (s) # CIRCLED LATIN SMALL LETTER S +24E3 (t) # CIRCLED LATIN SMALL LETTER T +24E4 (u) # CIRCLED LATIN SMALL LETTER U +24E5 (v) # CIRCLED LATIN SMALL LETTER V +24E6 (w) # CIRCLED LATIN SMALL LETTER W +24E7 (x) # CIRCLED LATIN SMALL LETTER X +24E8 (y) # CIRCLED LATIN SMALL LETTER Y +24E9 (z) # CIRCLED LATIN SMALL LETTER Z +24EA (0) # CIRCLED DIGIT ZERO +2500 - # BOX DRAWINGS LIGHT HORIZONTAL +2502 | # BOX DRAWINGS LIGHT VERTICAL +250C + # BOX DRAWINGS LIGHT DOWN AND RIGHT +2510 + # BOX DRAWINGS LIGHT DOWN AND LEFT +2514 + # BOX DRAWINGS LIGHT UP AND RIGHT +2518 + # BOX DRAWINGS LIGHT UP AND LEFT +251C + # BOX DRAWINGS LIGHT VERTICAL AND RIGHT +2524 + # BOX DRAWINGS LIGHT VERTICAL AND LEFT +252C + # BOX DRAWINGS LIGHT DOWN AND HORIZONTAL +2534 + # BOX DRAWINGS LIGHT UP AND HORIZONTAL +253C + # BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL +2592 # MEDIUM SHADE +25AE # BLACK VERTICAL RECTANGLE +25C6 # BLACK DIAMOND +25E6 o # WHITE BULLET +266A # EIGHTH NOTE +2A0C ∫∫∫∫ # QUADRUPLE INTEGRAL OPERATOR +2A74 ::= # DOUBLE COLON EQUAL +2A75 == # TWO CONSECUTIVE EQUALS SIGNS +2A76 === # THREE CONSECUTIVE EQUALS SIGNS +2E9F æ¯ # CJK RADICAL MOTHER +2EF3 龟 # CJK RADICAL C-SIMPLIFIED TURTLE +2F00 一 # KANGXI RADICAL ONE +2F01 丨 # KANGXI RADICAL LINE +2F02 丶 # KANGXI RADICAL DOT +2F03 丿 # KANGXI RADICAL SLASH +2F04 ä¹™ # KANGXI RADICAL SECOND +2F05 亅 # KANGXI RADICAL HOOK +2F06 二 # KANGXI RADICAL TWO +2F07 亠 # KANGXI RADICAL LID +2F08 人 # KANGXI RADICAL MAN +2F09 å„¿ # KANGXI RADICAL LEGS +2F0A å…¥ # KANGXI RADICAL ENTER +2F0B å…« # KANGXI RADICAL EIGHT +2F0C 冂 # KANGXI RADICAL DOWN BOX +2F0D 冖 # KANGXI RADICAL COVER +2F0E 冫 # KANGXI RADICAL ICE +2F0F 几 # KANGXI RADICAL TABLE +2F10 凵 # KANGXI RADICAL OPEN BOX +2F11 刀 # KANGXI RADICAL KNIFE +2F12 力 # KANGXI RADICAL POWER +2F13 勹 # KANGXI RADICAL WRAP +2F14 匕 # KANGXI RADICAL SPOON +2F15 匚 # KANGXI RADICAL RIGHT OPEN BOX +2F16 匸 # KANGXI RADICAL HIDING ENCLOSURE +2F17 å # KANGXI RADICAL TEN +2F18 åœ # KANGXI RADICAL DIVINATION +2F19 å© # KANGXI RADICAL SEAL +2F1A 厂 # KANGXI RADICAL CLIFF +2F1B 厶 # KANGXI RADICAL PRIVATE +2F1C åˆ # KANGXI RADICAL AGAIN +2F1D å£ # KANGXI RADICAL MOUTH +2F1E å›— # KANGXI RADICAL ENCLOSURE +2F1F 土 # KANGXI RADICAL EARTH +2F20 士 # KANGXI RADICAL SCHOLAR +2F21 夂 # KANGXI RADICAL GO +2F22 夊 # KANGXI RADICAL GO SLOWLY +2F23 夕 # KANGXI RADICAL EVENING +2F24 大 # KANGXI RADICAL BIG +2F25 女 # KANGXI RADICAL WOMAN +2F26 å­ # KANGXI RADICAL CHILD +2F27 宀 # KANGXI RADICAL ROOF +2F28 寸 # KANGXI RADICAL INCH +2F29 å° # KANGXI RADICAL SMALL +2F2A å°¢ # KANGXI RADICAL LAME +2F2B å°¸ # KANGXI RADICAL CORPSE +2F2C å±® # KANGXI RADICAL SPROUT +2F2D å±± # KANGXI RADICAL MOUNTAIN +2F2E å·› # KANGXI RADICAL RIVER +2F2F å·¥ # KANGXI RADICAL WORK +2F30 å·± # KANGXI RADICAL ONESELF +2F31 å·¾ # KANGXI RADICAL TURBAN +2F32 å¹² # KANGXI RADICAL DRY +2F33 幺 # KANGXI RADICAL SHORT THREAD +2F34 广 # KANGXI RADICAL DOTTED CLIFF +2F35 å»´ # KANGXI RADICAL LONG STRIDE +2F36 廾 # KANGXI RADICAL TWO HANDS +2F37 弋 # KANGXI RADICAL SHOOT +2F38 弓 # KANGXI RADICAL BOW +2F39 å½ # KANGXI RADICAL SNOUT +2F3A 彡 # KANGXI RADICAL BRISTLE +2F3B å½³ # KANGXI RADICAL STEP +2F3C 心 # KANGXI RADICAL HEART +2F3D 戈 # KANGXI RADICAL HALBERD +2F3E 戶 # KANGXI RADICAL DOOR +2F3F 手 # KANGXI RADICAL HAND +2F40 支 # KANGXI RADICAL BRANCH +2F41 æ”´ # KANGXI RADICAL RAP +2F42 æ–‡ # KANGXI RADICAL SCRIPT +2F43 æ–— # KANGXI RADICAL DIPPER +2F44 æ–¤ # KANGXI RADICAL AXE +2F45 æ–¹ # KANGXI RADICAL SQUARE +2F46 æ—  # KANGXI RADICAL NOT +2F47 æ—¥ # KANGXI RADICAL SUN +2F48 æ›° # KANGXI RADICAL SAY +2F49 月 # KANGXI RADICAL MOON +2F4A 木 # KANGXI RADICAL TREE +2F4B 欠 # KANGXI RADICAL LACK +2F4C æ­¢ # KANGXI RADICAL STOP +2F4D æ­¹ # KANGXI RADICAL DEATH +2F4E 殳 # KANGXI RADICAL WEAPON +2F4F 毋 # KANGXI RADICAL DO NOT +2F50 比 # KANGXI RADICAL COMPARE +2F51 毛 # KANGXI RADICAL FUR +2F52 æ° # KANGXI RADICAL CLAN +2F53 æ°” # KANGXI RADICAL STEAM +2F54 æ°´ # KANGXI RADICAL WATER +2F55 ç« # KANGXI RADICAL FIRE +2F56 爪 # KANGXI RADICAL CLAW +2F57 父 # KANGXI RADICAL FATHER +2F58 爻 # KANGXI RADICAL DOUBLE X +2F59 爿 # KANGXI RADICAL HALF TREE TRUNK +2F5A 片 # KANGXI RADICAL SLICE +2F5B 牙 # KANGXI RADICAL FANG +2F5C 牛 # KANGXI RADICAL COW +2F5D 犬 # KANGXI RADICAL DOG +2F5E 玄 # KANGXI RADICAL PROFOUND +2F5F 玉 # KANGXI RADICAL JADE +2F60 瓜 # KANGXI RADICAL MELON +2F61 瓦 # KANGXI RADICAL TILE +2F62 甘 # KANGXI RADICAL SWEET +2F63 生 # KANGXI RADICAL LIFE +2F64 用 # KANGXI RADICAL USE +2F65 ç”° # KANGXI RADICAL FIELD +2F66 ç–‹ # KANGXI RADICAL BOLT OF CLOTH +2F67 ç–’ # KANGXI RADICAL SICKNESS +2F68 ç™¶ # KANGXI RADICAL DOTTED TENT +2F69 白 # KANGXI RADICAL WHITE +2F6A çš® # KANGXI RADICAL SKIN +2F6B çš¿ # KANGXI RADICAL DISH +2F6C ç›® # KANGXI RADICAL EYE +2F6D 矛 # KANGXI RADICAL SPEAR +2F6E 矢 # KANGXI RADICAL ARROW +2F6F 石 # KANGXI RADICAL STONE +2F70 示 # KANGXI RADICAL SPIRIT +2F71 禸 # KANGXI RADICAL TRACK +2F72 禾 # KANGXI RADICAL GRAIN +2F73 ç©´ # KANGXI RADICAL CAVE +2F74 ç«‹ # KANGXI RADICAL STAND +2F75 竹 # KANGXI RADICAL BAMBOO +2F76 ç±³ # KANGXI RADICAL RICE +2F77 糸 # KANGXI RADICAL SILK +2F78 ç¼¶ # KANGXI RADICAL JAR +2F79 网 # KANGXI RADICAL NET +2F7A 羊 # KANGXI RADICAL SHEEP +2F7B ç¾½ # KANGXI RADICAL FEATHER +2F7C è€ # KANGXI RADICAL OLD +2F7D 而 # KANGXI RADICAL AND +2F7E 耒 # KANGXI RADICAL PLOW +2F7F 耳 # KANGXI RADICAL EAR +2F80 è¿ # KANGXI RADICAL BRUSH +2F81 肉 # KANGXI RADICAL MEAT +2F82 臣 # KANGXI RADICAL MINISTER +2F83 自 # KANGXI RADICAL SELF +2F84 至 # KANGXI RADICAL ARRIVE +2F85 臼 # KANGXI RADICAL MORTAR +2F86 舌 # KANGXI RADICAL TONGUE +2F87 舛 # KANGXI RADICAL OPPOSE +2F88 舟 # KANGXI RADICAL BOAT +2F89 艮 # KANGXI RADICAL STOPPING +2F8A 色 # KANGXI RADICAL COLOR +2F8B 艸 # KANGXI RADICAL GRASS +2F8C è™ # KANGXI RADICAL TIGER +2F8D 虫 # KANGXI RADICAL INSECT +2F8E è¡€ # KANGXI RADICAL BLOOD +2F8F 行 # KANGXI RADICAL WALK ENCLOSURE +2F90 è¡£ # KANGXI RADICAL CLOTHES +2F91 襾 # KANGXI RADICAL WEST +2F92 見 # KANGXI RADICAL SEE +2F93 è§’ # KANGXI RADICAL HORN +2F94 言 # KANGXI RADICAL SPEECH +2F95 è°· # KANGXI RADICAL VALLEY +2F96 豆 # KANGXI RADICAL BEAN +2F97 豕 # KANGXI RADICAL PIG +2F98 豸 # KANGXI RADICAL BADGER +2F99 è² # KANGXI RADICAL SHELL +2F9A 赤 # KANGXI RADICAL RED +2F9B èµ° # KANGXI RADICAL RUN +2F9C è¶³ # KANGXI RADICAL FOOT +2F9D 身 # KANGXI RADICAL BODY +2F9E 車 # KANGXI RADICAL CART +2F9F è¾› # KANGXI RADICAL BITTER +2FA0 è¾° # KANGXI RADICAL MORNING +2FA1 è¾µ # KANGXI RADICAL WALK +2FA2 é‚‘ # KANGXI RADICAL CITY +2FA3 é…‰ # KANGXI RADICAL WINE +2FA4 釆 # KANGXI RADICAL DISTINGUISH +2FA5 里 # KANGXI RADICAL VILLAGE +2FA6 金 # KANGXI RADICAL GOLD +2FA7 é•· # KANGXI RADICAL LONG +2FA8 é–€ # KANGXI RADICAL GATE +2FA9 阜 # KANGXI RADICAL MOUND +2FAA éš¶ # KANGXI RADICAL SLAVE +2FAB éš¹ # KANGXI RADICAL SHORT TAILED BIRD +2FAC 雨 # KANGXI RADICAL RAIN +2FAD é‘ # KANGXI RADICAL BLUE +2FAE éž # KANGXI RADICAL WRONG +2FAF é¢ # KANGXI RADICAL FACE +2FB0 é© # KANGXI RADICAL LEATHER +2FB1 韋 # KANGXI RADICAL TANNED LEATHER +2FB2 韭 # KANGXI RADICAL LEEK +2FB3 音 # KANGXI RADICAL SOUND +2FB4 é  # KANGXI RADICAL LEAF +2FB5 風 # KANGXI RADICAL WIND +2FB6 飛 # KANGXI RADICAL FLY +2FB7 食 # KANGXI RADICAL EAT +2FB8 首 # KANGXI RADICAL HEAD +2FB9 香 # KANGXI RADICAL FRAGRANT +2FBA 馬 # KANGXI RADICAL HORSE +2FBB 骨 # KANGXI RADICAL BONE +2FBC 高 # KANGXI RADICAL TALL +2FBD 髟 # KANGXI RADICAL HAIR +2FBE 鬥 # KANGXI RADICAL FIGHT +2FBF 鬯 # KANGXI RADICAL SACRIFICIAL WINE +2FC0 鬲 # KANGXI RADICAL CAULDRON +2FC1 鬼 # KANGXI RADICAL GHOST +2FC2 é­š # KANGXI RADICAL FISH +2FC3 é³¥ # KANGXI RADICAL BIRD +2FC4 é¹µ # KANGXI RADICAL SALT +2FC5 鹿 # KANGXI RADICAL DEER +2FC6 麥 # KANGXI RADICAL WHEAT +2FC7 麻 # KANGXI RADICAL HEMP +2FC8 黃 # KANGXI RADICAL YELLOW +2FC9 é» # KANGXI RADICAL MILLET +2FCA 黑 # KANGXI RADICAL BLACK +2FCB 黹 # KANGXI RADICAL EMBROIDERY +2FCC 黽 # KANGXI RADICAL FROG +2FCD 鼎 # KANGXI RADICAL TRIPOD +2FCE 鼓 # KANGXI RADICAL DRUM +2FCF é¼  # KANGXI RADICAL RAT +2FD0 é¼» # KANGXI RADICAL NOSE +2FD1 齊 # KANGXI RADICAL EVEN +2FD2 é½’ # KANGXI RADICAL TOOTH +2FD3 é¾ # KANGXI RADICAL DRAGON +2FD4 龜 # KANGXI RADICAL TURTLE +2FD5 é¾  # KANGXI RADICAL FLUTE +3000 # IDEOGRAPHIC SPACE +3036 〒 # CIRCLED POSTAL MARK +3038 å # HANGZHOU NUMERAL TEN +3039 å„ # HANGZHOU NUMERAL TWENTY +303A å… # HANGZHOU NUMERAL THIRTY +3041 ã‚ # HIRAGANA LETTER SMALL A +3043 ã„ # HIRAGANA LETTER SMALL I +3045 ㆠ# HIRAGANA LETTER SMALL U +3047 ㈠# HIRAGANA LETTER SMALL E +3049 ㊠# HIRAGANA LETTER SMALL O +3063 㤠# HIRAGANA LETTER SMALL TU +3083 ã‚„ # HIRAGANA LETTER SMALL YA +3085 ゆ # HIRAGANA LETTER SMALL YU +3087 よ # HIRAGANA LETTER SMALL YO +308E ã‚ # HIRAGANA LETTER SMALL WA +3095 ã‹ # HIRAGANA LETTER SMALL KA +3096 ã‘ # HIRAGANA LETTER SMALL KE +309B ã‚™ # KATAKANA-HIRAGANA VOICED SOUND MARK +309C ゚ # KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK +30A0 = # KATAKANA-HIRAGANA DOUBLE HYPHEN +30A1 ã‚¢ # KATAKANA LETTER SMALL A +30A3 イ # KATAKANA LETTER SMALL I +30A5 ウ # KATAKANA LETTER SMALL U +30A7 エ # KATAKANA LETTER SMALL E +30A9 オ # KATAKANA LETTER SMALL O +30C3 ツ # KATAKANA LETTER SMALL TU +30E3 ヤ # KATAKANA LETTER SMALL YA +30E5 ユ # KATAKANA LETTER SMALL YU +30E7 ヨ # KATAKANA LETTER SMALL YO +30EE ワ # KATAKANA LETTER SMALL WA +30F5 ã‚« # KATAKANA LETTER SMALL KA +30F6 ケ # KATAKANA LETTER SMALL KE +3131 á„€ # HANGUL LETTER KIYEOK +3132 á„ # HANGUL LETTER SSANGKIYEOK +3133 ᆪ # HANGUL LETTER KIYEOK-SIOS +3134 á„‚ # HANGUL LETTER NIEUN +3135 ᆬ # HANGUL LETTER NIEUN-CIEUC +3136 ᆭ # HANGUL LETTER NIEUN-HIEUH +3137 ᄃ # HANGUL LETTER TIKEUT +3138 á„„ # HANGUL LETTER SSANGTIKEUT +3139 á„… # HANGUL LETTER RIEUL +313A ᆰ # HANGUL LETTER RIEUL-KIYEOK +313B ᆱ # HANGUL LETTER RIEUL-MIEUM +313C ᆲ # HANGUL LETTER RIEUL-PIEUP +313D ᆳ # HANGUL LETTER RIEUL-SIOS +313E ᆴ # HANGUL LETTER RIEUL-THIEUTH +313F ᆵ # HANGUL LETTER RIEUL-PHIEUPH +3140 ᄚ # HANGUL LETTER RIEUL-HIEUH +3141 ᄆ # HANGUL LETTER MIEUM +3142 ᄇ # HANGUL LETTER PIEUP +3143 ᄈ # HANGUL LETTER SSANGPIEUP +3144 á„¡ # HANGUL LETTER PIEUP-SIOS +3145 ᄉ # HANGUL LETTER SIOS +3146 ᄊ # HANGUL LETTER SSANGSIOS +3147 á„‹ # HANGUL LETTER IEUNG +3148 ᄌ # HANGUL LETTER CIEUC +3149 á„ # HANGUL LETTER SSANGCIEUC +314A ᄎ # HANGUL LETTER CHIEUCH +314B á„ # HANGUL LETTER KHIEUKH +314C á„ # HANGUL LETTER THIEUTH +314D á„‘ # HANGUL LETTER PHIEUPH +314E á„’ # HANGUL LETTER HIEUH +314F á…¡ # HANGUL LETTER A +3150 á…¢ # HANGUL LETTER AE +3151 á…£ # HANGUL LETTER YA +3152 á…¤ # HANGUL LETTER YAE +3153 á…¥ # HANGUL LETTER EO +3154 á…¦ # HANGUL LETTER E +3155 á…§ # HANGUL LETTER YEO +3156 á…¨ # HANGUL LETTER YE +3157 á…© # HANGUL LETTER O +3158 á…ª # HANGUL LETTER WA +3159 á…« # HANGUL LETTER WAE +315A á…¬ # HANGUL LETTER OE +315B á…­ # HANGUL LETTER YO +315C á…® # HANGUL LETTER U +315D á…¯ # HANGUL LETTER WEO +315E á…° # HANGUL LETTER WE +315F á…± # HANGUL LETTER WI +3160 á…² # HANGUL LETTER YU +3161 á…³ # HANGUL LETTER EU +3162 á…´ # HANGUL LETTER YI +3163 á…µ # HANGUL LETTER I +3164 á…  # HANGUL FILLER +3165 á„” # HANGUL LETTER SSANGNIEUN +3166 á„• # HANGUL LETTER NIEUN-TIKEUT +3167 ᇇ # HANGUL LETTER NIEUN-SIOS +3168 ᇈ # HANGUL LETTER NIEUN-PANSIOS +3169 ᇌ # HANGUL LETTER RIEUL-KIYEOK-SIOS +316A ᇎ # HANGUL LETTER RIEUL-TIKEUT +316B ᇓ # HANGUL LETTER RIEUL-PIEUP-SIOS +316C ᇗ # HANGUL LETTER RIEUL-PANSIOS +316D ᇙ # HANGUL LETTER RIEUL-YEORINHIEUH +316E ᄜ # HANGUL LETTER MIEUM-PIEUP +316F ᇠ# HANGUL LETTER MIEUM-SIOS +3170 ᇟ # HANGUL LETTER MIEUM-PANSIOS +3171 á„ # HANGUL LETTER KAPYEOUNMIEUM +3172 ᄞ # HANGUL LETTER PIEUP-KIYEOK +3173 á„  # HANGUL LETTER PIEUP-TIKEUT +3174 á„¢ # HANGUL LETTER PIEUP-SIOS-KIYEOK +3175 á„£ # HANGUL LETTER PIEUP-SIOS-TIKEUT +3176 á„§ # HANGUL LETTER PIEUP-CIEUC +3177 á„© # HANGUL LETTER PIEUP-THIEUTH +3178 á„« # HANGUL LETTER KAPYEOUNPIEUP +3179 ᄬ # HANGUL LETTER KAPYEOUNSSANGPIEUP +317A á„­ # HANGUL LETTER SIOS-KIYEOK +317B á„® # HANGUL LETTER SIOS-NIEUN +317C ᄯ # HANGUL LETTER SIOS-TIKEUT +317D ᄲ # HANGUL LETTER SIOS-PIEUP +317E á„¶ # HANGUL LETTER SIOS-CIEUC +317F á…€ # HANGUL LETTER PANSIOS +3180 á…‡ # HANGUL LETTER SSANGIEUNG +3181 á…Œ # HANGUL LETTER YESIEUNG +3182 ᇱ # HANGUL LETTER YESIEUNG-SIOS +3183 ᇲ # HANGUL LETTER YESIEUNG-PANSIOS +3184 á…— # HANGUL LETTER KAPYEOUNPHIEUPH +3185 á…˜ # HANGUL LETTER SSANGHIEUH +3186 á…™ # HANGUL LETTER YEORINHIEUH +3187 ᆄ # HANGUL LETTER YO-YA +3188 ᆅ # HANGUL LETTER YO-YAE +3189 ᆈ # HANGUL LETTER YO-I +318A ᆑ # HANGUL LETTER YU-YEO +318B ᆒ # HANGUL LETTER YU-YE +318C ᆔ # HANGUL LETTER YU-I +318D ᆞ # HANGUL LETTER ARAEA +318E ᆡ # HANGUL LETTER ARAEAE +31F0 ク # KATAKANA LETTER SMALL KU +31F1 ã‚· # KATAKANA LETTER SMALL SI +31F2 ス # KATAKANA LETTER SMALL SU +31F3 ト # KATAKANA LETTER SMALL TO +31F4 ヌ # KATAKANA LETTER SMALL NU +31F5 ム# KATAKANA LETTER SMALL HA +31F6 ヒ # KATAKANA LETTER SMALL HI +31F7 フ # KATAKANA LETTER SMALL HU +31F8 ヘ # KATAKANA LETTER SMALL HE +31F9 ホ # KATAKANA LETTER SMALL HO +31FA ム # KATAKANA LETTER SMALL MU +31FB ラ # KATAKANA LETTER SMALL RA +31FC リ # KATAKANA LETTER SMALL RI +31FD ル # KATAKANA LETTER SMALL RU +31FE レ # KATAKANA LETTER SMALL RE +31FF ロ # KATAKANA LETTER SMALL RO +3200 (á„€) # PARENTHESIZED HANGUL KIYEOK +3201 (á„‚) # PARENTHESIZED HANGUL NIEUN +3202 (ᄃ) # PARENTHESIZED HANGUL TIKEUT +3203 (á„…) # PARENTHESIZED HANGUL RIEUL +3204 (ᄆ) # PARENTHESIZED HANGUL MIEUM +3205 (ᄇ) # PARENTHESIZED HANGUL PIEUP +3206 (ᄉ) # PARENTHESIZED HANGUL SIOS +3207 (á„‹) # PARENTHESIZED HANGUL IEUNG +3208 (ᄌ) # PARENTHESIZED HANGUL CIEUC +3209 (ᄎ) # PARENTHESIZED HANGUL CHIEUCH +320A (á„) # PARENTHESIZED HANGUL KHIEUKH +320B (á„) # PARENTHESIZED HANGUL THIEUTH +320C (á„‘) # PARENTHESIZED HANGUL PHIEUPH +320D (á„’) # PARENTHESIZED HANGUL HIEUH +320E (가) # PARENTHESIZED HANGUL KIYEOK A +320F (á„‚á…¡) # PARENTHESIZED HANGUL NIEUN A +3210 (다) # PARENTHESIZED HANGUL TIKEUT A +3211 (á„…á…¡) # PARENTHESIZED HANGUL RIEUL A +3212 (마) # PARENTHESIZED HANGUL MIEUM A +3213 (바) # PARENTHESIZED HANGUL PIEUP A +3214 (사) # PARENTHESIZED HANGUL SIOS A +3215 (á„‹á…¡) # PARENTHESIZED HANGUL IEUNG A +3216 (자) # PARENTHESIZED HANGUL CIEUC A +3217 (차) # PARENTHESIZED HANGUL CHIEUCH A +3218 (á„á…¡) # PARENTHESIZED HANGUL KHIEUKH A +3219 (á„á…¡) # PARENTHESIZED HANGUL THIEUTH A +321A (á„‘á…¡) # PARENTHESIZED HANGUL PHIEUPH A +321B (á„’á…¡) # PARENTHESIZED HANGUL HIEUH A +321C (주) # PARENTHESIZED HANGUL CIEUC U +321D (오전) # PARENTHESIZED KOREAN CHARACTER OJEON +321E (á„‹á…©á„’á…®) # PARENTHESIZED KOREAN CHARACTER O HU +3220 (一) # PARENTHESIZED IDEOGRAPH ONE +3221 (二) # PARENTHESIZED IDEOGRAPH TWO +3222 (三) # PARENTHESIZED IDEOGRAPH THREE +3223 (å››) # PARENTHESIZED IDEOGRAPH FOUR +3224 (五) # PARENTHESIZED IDEOGRAPH FIVE +3225 (å…­) # PARENTHESIZED IDEOGRAPH SIX +3226 (七) # PARENTHESIZED IDEOGRAPH SEVEN +3227 (å…«) # PARENTHESIZED IDEOGRAPH EIGHT +3228 (ä¹) # PARENTHESIZED IDEOGRAPH NINE +3229 (å) # PARENTHESIZED IDEOGRAPH TEN +322A (月) # PARENTHESIZED IDEOGRAPH MOON +322B (ç«) # PARENTHESIZED IDEOGRAPH FIRE +322C (æ°´) # PARENTHESIZED IDEOGRAPH WATER +322D (木) # PARENTHESIZED IDEOGRAPH WOOD +322E (金) # PARENTHESIZED IDEOGRAPH METAL +322F (土) # PARENTHESIZED IDEOGRAPH EARTH +3230 (æ—¥) # PARENTHESIZED IDEOGRAPH SUN +3231 (æ ª) # PARENTHESIZED IDEOGRAPH STOCK +3232 (有) # PARENTHESIZED IDEOGRAPH HAVE +3233 (社) # PARENTHESIZED IDEOGRAPH SOCIETY +3234 (å) # PARENTHESIZED IDEOGRAPH NAME +3235 (特) # PARENTHESIZED IDEOGRAPH SPECIAL +3236 (財) # PARENTHESIZED IDEOGRAPH FINANCIAL +3237 (ç¥) # PARENTHESIZED IDEOGRAPH CONGRATULATION +3238 (労) # PARENTHESIZED IDEOGRAPH LABOR +3239 (代) # PARENTHESIZED IDEOGRAPH REPRESENT +323A (呼) # PARENTHESIZED IDEOGRAPH CALL +323B (å­¦) # PARENTHESIZED IDEOGRAPH STUDY +323C (監) # PARENTHESIZED IDEOGRAPH SUPERVISE +323D (ä¼) # PARENTHESIZED IDEOGRAPH ENTERPRISE +323E (資) # PARENTHESIZED IDEOGRAPH RESOURCE +323F (å”) # PARENTHESIZED IDEOGRAPH ALLIANCE +3240 (祭) # PARENTHESIZED IDEOGRAPH FESTIVAL +3241 (休) # PARENTHESIZED IDEOGRAPH REST +3242 (自) # PARENTHESIZED IDEOGRAPH SELF +3243 (至) # PARENTHESIZED IDEOGRAPH REACH +3250 PTE # PARTNERSHIP SIGN +3251 (21) # CIRCLED NUMBER TWENTY ONE +3252 (22) # CIRCLED NUMBER TWENTY TWO +3253 (23) # CIRCLED NUMBER TWENTY THREE +3254 (24) # CIRCLED NUMBER TWENTY FOUR +3255 (25) # CIRCLED NUMBER TWENTY FIVE +3256 (26) # CIRCLED NUMBER TWENTY SIX +3257 (27) # CIRCLED NUMBER TWENTY SEVEN +3258 (28) # CIRCLED NUMBER TWENTY EIGHT +3259 (29) # CIRCLED NUMBER TWENTY NINE +325A (30) # CIRCLED NUMBER THIRTY +325B (31) # CIRCLED NUMBER THIRTY ONE +325C (32) # CIRCLED NUMBER THIRTY TWO +325D (33) # CIRCLED NUMBER THIRTY THREE +325E (34) # CIRCLED NUMBER THIRTY FOUR +325F (35) # CIRCLED NUMBER THIRTY FIVE +3260 (á„€) # CIRCLED HANGUL KIYEOK +3261 (á„‚) # CIRCLED HANGUL NIEUN +3262 (ᄃ) # CIRCLED HANGUL TIKEUT +3263 (á„…) # CIRCLED HANGUL RIEUL +3264 (ᄆ) # CIRCLED HANGUL MIEUM +3265 (ᄇ) # CIRCLED HANGUL PIEUP +3266 (ᄉ) # CIRCLED HANGUL SIOS +3267 (á„‹) # CIRCLED HANGUL IEUNG +3268 (ᄌ) # CIRCLED HANGUL CIEUC +3269 (ᄎ) # CIRCLED HANGUL CHIEUCH +326A (á„) # CIRCLED HANGUL KHIEUKH +326B (á„) # CIRCLED HANGUL THIEUTH +326C (á„‘) # CIRCLED HANGUL PHIEUPH +326D (á„’) # CIRCLED HANGUL HIEUH +326E (가) # CIRCLED HANGUL KIYEOK A +326F (á„‚á…¡) # CIRCLED HANGUL NIEUN A +3270 (다) # CIRCLED HANGUL TIKEUT A +3271 (á„…á…¡) # CIRCLED HANGUL RIEUL A +3272 (마) # CIRCLED HANGUL MIEUM A +3273 (바) # CIRCLED HANGUL PIEUP A +3274 (사) # CIRCLED HANGUL SIOS A +3275 (á„‹á…¡) # CIRCLED HANGUL IEUNG A +3276 (자) # CIRCLED HANGUL CIEUC A +3277 (차) # CIRCLED HANGUL CHIEUCH A +3278 (á„á…¡) # CIRCLED HANGUL KHIEUKH A +3279 (á„á…¡) # CIRCLED HANGUL THIEUTH A +327A (á„‘á…¡) # CIRCLED HANGUL PHIEUPH A +327B (á„’á…¡) # CIRCLED HANGUL HIEUH A +327C (참고) # CIRCLED KOREAN CHARACTER CHAMKO +327D (주의) # CIRCLED KOREAN CHARACTER JUEUI +3280 (一) # CIRCLED IDEOGRAPH ONE +3281 (二) # CIRCLED IDEOGRAPH TWO +3282 (三) # CIRCLED IDEOGRAPH THREE +3283 (å››) # CIRCLED IDEOGRAPH FOUR +3284 (五) # CIRCLED IDEOGRAPH FIVE +3285 (å…­) # CIRCLED IDEOGRAPH SIX +3286 (七) # CIRCLED IDEOGRAPH SEVEN +3287 (å…«) # CIRCLED IDEOGRAPH EIGHT +3288 (ä¹) # CIRCLED IDEOGRAPH NINE +3289 (å) # CIRCLED IDEOGRAPH TEN +328A (月) # CIRCLED IDEOGRAPH MOON +328B (ç«) # CIRCLED IDEOGRAPH FIRE +328C (æ°´) # CIRCLED IDEOGRAPH WATER +328D (木) # CIRCLED IDEOGRAPH WOOD +328E (金) # CIRCLED IDEOGRAPH METAL +328F (土) # CIRCLED IDEOGRAPH EARTH +3290 (æ—¥) # CIRCLED IDEOGRAPH SUN +3291 (æ ª) # CIRCLED IDEOGRAPH STOCK +3292 (有) # CIRCLED IDEOGRAPH HAVE +3293 (社) # CIRCLED IDEOGRAPH SOCIETY +3294 (å) # CIRCLED IDEOGRAPH NAME +3295 (特) # CIRCLED IDEOGRAPH SPECIAL +3296 (財) # CIRCLED IDEOGRAPH FINANCIAL +3297 (ç¥) # CIRCLED IDEOGRAPH CONGRATULATION +3298 (労) # CIRCLED IDEOGRAPH LABOR +3299 (秘) # CIRCLED IDEOGRAPH SECRET +329A (ç”·) # CIRCLED IDEOGRAPH MALE +329B (女) # CIRCLED IDEOGRAPH FEMALE +329C (é©) # CIRCLED IDEOGRAPH SUITABLE +329D (優) # CIRCLED IDEOGRAPH EXCELLENT +329E (å°) # CIRCLED IDEOGRAPH PRINT +329F (注) # CIRCLED IDEOGRAPH ATTENTION +32A0 (é …) # CIRCLED IDEOGRAPH ITEM +32A1 (休) # CIRCLED IDEOGRAPH REST +32A2 (写) # CIRCLED IDEOGRAPH COPY +32A3 (æ­£) # CIRCLED IDEOGRAPH CORRECT +32A4 (上) # CIRCLED IDEOGRAPH HIGH +32A5 (中) # CIRCLED IDEOGRAPH CENTRE +32A6 (下) # CIRCLED IDEOGRAPH LOW +32A7 (å·¦) # CIRCLED IDEOGRAPH LEFT +32A8 (å³) # CIRCLED IDEOGRAPH RIGHT +32A9 (医) # CIRCLED IDEOGRAPH MEDICINE +32AA (å®—) # CIRCLED IDEOGRAPH RELIGION +32AB (å­¦) # CIRCLED IDEOGRAPH STUDY +32AC (監) # CIRCLED IDEOGRAPH SUPERVISE +32AD (ä¼) # CIRCLED IDEOGRAPH ENTERPRISE +32AE (資) # CIRCLED IDEOGRAPH RESOURCE +32AF (å”) # CIRCLED IDEOGRAPH ALLIANCE +32B0 (夜) # CIRCLED IDEOGRAPH NIGHT +32B1 (36) # CIRCLED NUMBER THIRTY SIX +32B2 (37) # CIRCLED NUMBER THIRTY SEVEN +32B3 (38) # CIRCLED NUMBER THIRTY EIGHT +32B4 (39) # CIRCLED NUMBER THIRTY NINE +32B5 (40) # CIRCLED NUMBER FORTY +32B6 (41) # CIRCLED NUMBER FORTY ONE +32B7 (42) # CIRCLED NUMBER FORTY TWO +32B8 (43) # CIRCLED NUMBER FORTY THREE +32B9 (44) # CIRCLED NUMBER FORTY FOUR +32BA (45) # CIRCLED NUMBER FORTY FIVE +32BB (46) # CIRCLED NUMBER FORTY SIX +32BC (47) # CIRCLED NUMBER FORTY SEVEN +32BD (48) # CIRCLED NUMBER FORTY EIGHT +32BE (49) # CIRCLED NUMBER FORTY NINE +32BF (50) # CIRCLED NUMBER FIFTY +32C0 1月 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR JANUARY +32C1 2月 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR FEBRUARY +32C2 3月 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR MARCH +32C3 4月 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR APRIL +32C4 5月 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR MAY +32C5 6月 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR JUNE +32C6 7月 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR JULY +32C7 8月 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR AUGUST +32C8 9月 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR SEPTEMBER +32C9 10月 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR OCTOBER +32CA 11月 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR NOVEMBER +32CB 12月 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DECEMBER +32CC Hg # SQUARE HG +32CD erg # SQUARE ERG +32CE eV # SQUARE EV +32CF LTD # LIMITED LIABILITY SIGN +32D0 (ã‚¢) # CIRCLED KATAKANA A +32D1 (イ) # CIRCLED KATAKANA I +32D2 (ウ) # CIRCLED KATAKANA U +32D3 (エ) # CIRCLED KATAKANA E +32D4 (オ) # CIRCLED KATAKANA O +32D5 (ã‚«) # CIRCLED KATAKANA KA +32D6 (ã‚­) # CIRCLED KATAKANA KI +32D7 (ク) # CIRCLED KATAKANA KU +32D8 (ケ) # CIRCLED KATAKANA KE +32D9 (コ) # CIRCLED KATAKANA KO +32DA (サ) # CIRCLED KATAKANA SA +32DB (ã‚·) # CIRCLED KATAKANA SI +32DC (ス) # CIRCLED KATAKANA SU +32DD (ã‚») # CIRCLED KATAKANA SE +32DE (ソ) # CIRCLED KATAKANA SO +32DF (ã‚¿) # CIRCLED KATAKANA TA +32E0 (ãƒ) # CIRCLED KATAKANA TI +32E1 (ツ) # CIRCLED KATAKANA TU +32E2 (テ) # CIRCLED KATAKANA TE +32E3 (ト) # CIRCLED KATAKANA TO +32E4 (ナ) # CIRCLED KATAKANA NA +32E5 (ニ) # CIRCLED KATAKANA NI +32E6 (ヌ) # CIRCLED KATAKANA NU +32E7 (ãƒ) # CIRCLED KATAKANA NE +32E8 (ノ) # CIRCLED KATAKANA NO +32E9 (ãƒ) # CIRCLED KATAKANA HA +32EA (ヒ) # CIRCLED KATAKANA HI +32EB (フ) # CIRCLED KATAKANA HU +32EC (ヘ) # CIRCLED KATAKANA HE +32ED (ホ) # CIRCLED KATAKANA HO +32EE (マ) # CIRCLED KATAKANA MA +32EF (ミ) # CIRCLED KATAKANA MI +32F0 (ム) # CIRCLED KATAKANA MU +32F1 (メ) # CIRCLED KATAKANA ME +32F2 (モ) # CIRCLED KATAKANA MO +32F3 (ヤ) # CIRCLED KATAKANA YA +32F4 (ユ) # CIRCLED KATAKANA YU +32F5 (ヨ) # CIRCLED KATAKANA YO +32F6 (ラ) # CIRCLED KATAKANA RA +32F7 (リ) # CIRCLED KATAKANA RI +32F8 (ル) # CIRCLED KATAKANA RU +32F9 (レ) # CIRCLED KATAKANA RE +32FA (ロ) # CIRCLED KATAKANA RO +32FB (ワ) # CIRCLED KATAKANA WA +32FC (ヰ) # CIRCLED KATAKANA WI +32FD (ヱ) # CIRCLED KATAKANA WE +32FE (ヲ) # CIRCLED KATAKANA WO +3300 アパート # SQUARE APAATO +3301 アルファ # SQUARE ARUHUA +3302 アンペア # SQUARE ANPEA +3303 アール # SQUARE AARU +3304 イニング # SQUARE ININGU +3305 インム# SQUARE INTI +3306 ウォン # SQUARE UON +3307 エスクード # SQUARE ESUKUUDO +3308 エーカー # SQUARE EEKAA +3309 オンス # SQUARE ONSU +330A オーム # SQUARE OOMU +330B カイリ # SQUARE KAIRI +330C カラット # SQUARE KARATTO +330D カロリー # SQUARE KARORII +330E ガロン # SQUARE GARON +330F ガンマ # SQUARE GANMA +3310 ギガ # SQUARE GIGA +3311 ギニー # SQUARE GINII +3312 キュリー # SQUARE KYURII +3313 ギルダー # SQUARE GIRUDAA +3314 キロ # SQUARE KIRO +3315 キログラム # SQUARE KIROGURAMU +3316 キロメートル # SQUARE KIROMEETORU +3317 キロワット # SQUARE KIROWATTO +3318 グラム # SQUARE GURAMU +3319 グラムトン # SQUARE GURAMUTON +331A クルゼイロ # SQUARE KURUZEIRO +331B クローム# SQUARE KUROONE +331C ケース # SQUARE KEESU +331D コルナ # SQUARE KORUNA +331E コーム# SQUARE KOOPO +331F サイクル # SQUARE SAIKURU +3320 サンãƒãƒ¼ãƒ  # SQUARE SANTIIMU +3321 シリング # SQUARE SIRINGU +3322 センム# SQUARE SENTI +3323 セント # SQUARE SENTO +3324 ダース # SQUARE DAASU +3325 デシ # SQUARE DESI +3326 ドル # SQUARE DORU +3327 トン # SQUARE TON +3328 ナノ # SQUARE NANO +3329 ノット # SQUARE NOTTO +332A ãƒã‚¤ãƒ„ # SQUARE HAITU +332B パーセント # SQUARE PAASENTO +332C パーツ # SQUARE PAATU +332D ãƒãƒ¼ãƒ¬ãƒ« # SQUARE BAARERU +332E ピアストル # SQUARE PIASUTORU +332F ピクル # SQUARE PIKURU +3330 ピコ # SQUARE PIKO +3331 ビル # SQUARE BIRU +3332 ファラッド # SQUARE HUARADDO +3333 フィート # SQUARE HUIITO +3334 ブッシェル # SQUARE BUSSYERU +3335 フラン # SQUARE HURAN +3336 ヘクタール # SQUARE HEKUTAARU +3337 ペソ # SQUARE PESO +3338 ペニヒ # SQUARE PENIHI +3339 ヘルツ # SQUARE HERUTU +333A ペンス # SQUARE PENSU +333B ページ # SQUARE PEEZI +333C ベータ # SQUARE BEETA +333D ãƒã‚¤ãƒ³ãƒˆ # SQUARE POINTO +333E ボルト # SQUARE BORUTO +333F ホン # SQUARE HON +3340 ãƒãƒ³ãƒ‰ # SQUARE PONDO +3341 ホール # SQUARE HOORU +3342 ホーン # SQUARE HOON +3343 マイクロ # SQUARE MAIKURO +3344 マイル # SQUARE MAIRU +3345 マッム# SQUARE MAHHA +3346 マルク # SQUARE MARUKU +3347 マンション # SQUARE MANSYON +3348 ミクロン # SQUARE MIKURON +3349 ミリ # SQUARE MIRI +334A ミリãƒãƒ¼ãƒ« # SQUARE MIRIBAARU +334B メガ # SQUARE MEGA +334C メガトン # SQUARE MEGATON +334D メートル # SQUARE MEETORU +334E ヤード # SQUARE YAADO +334F ヤール # SQUARE YAARU +3350 ユアン # SQUARE YUAN +3351 リットル # SQUARE RITTORU +3352 リラ # SQUARE RIRA +3353 ルピー # SQUARE RUPII +3354 ルーブル # SQUARE RUUBURU +3355 レム # SQUARE REMU +3356 レントゲン # SQUARE RENTOGEN +3357 ワット # SQUARE WATTO +3358 0点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ZERO +3359 1点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ONE +335A 2点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWO +335B 3点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THREE +335C 4点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOUR +335D 5点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIVE +335E 6点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIX +335F 7点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVEN +3360 8点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHT +3361 9点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINE +3362 10点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TEN +3363 11点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR ELEVEN +3364 12点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWELVE +3365 13点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR THIRTEEN +3366 14点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FOURTEEN +3367 15点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR FIFTEEN +3368 16点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SIXTEEN +3369 17点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR SEVENTEEN +336A 18点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR EIGHTEEN +336B 19点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR NINETEEN +336C 20点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY +336D 21点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-ONE +336E 22点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-TWO +336F 23点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-THREE +3370 24点 # IDEOGRAPHIC TELEGRAPH SYMBOL FOR HOUR TWENTY-FOUR +3371 hPa # SQUARE HPA +3372 da # SQUARE DA +3373 AU # SQUARE AU +3374 bar # SQUARE BAR +3375 oV # SQUARE OV +3376 pc # SQUARE PC +3377 dm # SQUARE DM +3378 dm^2 # SQUARE DM SQUARED +3379 dm^3 # SQUARE DM CUBED +337A IU # SQUARE IU +337B å¹³æˆ # SQUARE ERA NAME HEISEI +337C 昭和 # SQUARE ERA NAME SYOUWA +337D 大正 # SQUARE ERA NAME TAISYOU +337E 明治 # SQUARE ERA NAME MEIZI +337F æ ªå¼ä¼šç¤¾ # SQUARE CORPORATION +3380 pA # SQUARE PA AMPS +3381 nA # SQUARE NA +3382 μA # SQUARE MU A +3383 mA # SQUARE MA +3384 kA # SQUARE KA +3385 KB # SQUARE KB +3386 MB # SQUARE MB +3387 GB # SQUARE GB +3388 cal # SQUARE CAL +3389 kcal # SQUARE KCAL +338A pF # SQUARE PF +338B nF # SQUARE NF +338C μF # SQUARE MU F +338D μg # SQUARE MU G +338E mg # SQUARE MG +338F kg # SQUARE KG +3390 Hz # SQUARE HZ +3391 kHz # SQUARE KHZ +3392 MHz # SQUARE MHZ +3393 GHz # SQUARE GHZ +3394 THz # SQUARE THZ +3395 μl # SQUARE MU L +3396 ml # SQUARE ML +3397 dl # SQUARE DL +3398 kl # SQUARE KL +3399 fm # SQUARE FM +339A nm # SQUARE NM +339B μm # SQUARE MU M +339C mm # SQUARE MM +339D cm # SQUARE CM +339E km # SQUARE KM +339F mm^2 # SQUARE MM SQUARED +33A0 cm^2 # SQUARE CM SQUARED +33A1 m^2 # SQUARE M SQUARED +33A2 km^2 # SQUARE KM SQUARED +33A3 mm^3 # SQUARE MM CUBED +33A4 cm^3 # SQUARE CM CUBED +33A5 m^3 # SQUARE M CUBED +33A6 km^3 # SQUARE KM CUBED +33A7 m/s # SQUARE M OVER S +33A8 m/s^2 # SQUARE M OVER S SQUARED +33A9 Pa # SQUARE PA +33AA kPa # SQUARE KPA +33AB MPa # SQUARE MPA +33AC GPa # SQUARE GPA +33AD rad # SQUARE RAD +33AE rad/s # SQUARE RAD OVER S +33AF rad/s^2 # SQUARE RAD OVER S SQUARED +33B0 ps # SQUARE PS +33B1 ns # SQUARE NS +33B2 μs # SQUARE MU S +33B3 ms # SQUARE MS +33B4 pV # SQUARE PV +33B5 nV # SQUARE NV +33B6 μV # SQUARE MU V +33B7 mV # SQUARE MV +33B8 kV # SQUARE KV +33B9 MV # SQUARE MV MEGA +33BA pW # SQUARE PW +33BB nW # SQUARE NW +33BC μW # SQUARE MU W +33BD mW # SQUARE MW +33BE kW # SQUARE KW +33BF MW # SQUARE MW MEGA +33C0 kΩ # SQUARE K OHM +33C1 MΩ # SQUARE M OHM +33C2 a.m. # SQUARE AM +33C3 Bq # SQUARE BQ +33C4 cc # SQUARE CC +33C5 cd # SQUARE CD +33C6 C/kg # SQUARE C OVER KG +33C7 Co. # SQUARE CO +33C8 dB # SQUARE DB +33C9 Gy # SQUARE GY +33CA ha # SQUARE HA +33CB HP # SQUARE HP +33CC in # SQUARE IN +33CD KK # SQUARE KK +33CE KM # SQUARE KM CAPITAL +33CF kt # SQUARE KT +33D0 lm # SQUARE LM +33D1 ln # SQUARE LN +33D2 log # SQUARE LOG +33D3 lx # SQUARE LX +33D4 mb # SQUARE MB SMALL +33D5 mil # SQUARE MIL +33D6 mol # SQUARE MOL +33D7 PH # SQUARE PH +33D8 p.m. # SQUARE PM +33D9 PPM # SQUARE PPM +33DA PR # SQUARE PR +33DB sr # SQUARE SR +33DC Sv # SQUARE SV +33DD Wb # SQUARE WB +33DE V/m # SQUARE V OVER M +33DF A/m # SQUARE A OVER M +33FF gal # SQUARE GAL +33E0 1æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ONE +33E1 2æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWO +33E2 3æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THREE +33E3 4æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOUR +33E4 5æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIVE +33E5 6æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIX +33E6 7æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVEN +33E7 8æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHT +33E8 9æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINE +33E9 10æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TEN +33EA 11æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY ELEVEN +33EB 12æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWELVE +33EC 13æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTEEN +33ED 14æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FOURTEEN +33EE 15æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY FIFTEEN +33EF 16æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SIXTEEN +33F0 17æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY SEVENTEEN +33F1 18æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY EIGHTEEN +33F2 19æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY NINETEEN +33F3 20æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY +33F4 21æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-ONE +33F5 22æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-TWO +33F6 23æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-THREE +33F7 24æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FOUR +33F8 25æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-FIVE +33F9 26æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SIX +33FA 27æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-SEVEN +33FB 28æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-EIGHT +33FC 29æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY TWENTY-NINE +33FD 30æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY +33FE 31æ—¥ # IDEOGRAPHIC TELEGRAPH SYMBOL FOR DAY THIRTY-ONE +F900 豈 # CJK COMPATIBILITY IDEOGRAPH-F900 +F901 æ›´ # CJK COMPATIBILITY IDEOGRAPH-F901 +F902 車 # CJK COMPATIBILITY IDEOGRAPH-F902 +F903 賈 # CJK COMPATIBILITY IDEOGRAPH-F903 +F904 滑 # CJK COMPATIBILITY IDEOGRAPH-F904 +F905 串 # CJK COMPATIBILITY IDEOGRAPH-F905 +F906 å¥ # CJK COMPATIBILITY IDEOGRAPH-F906 +F907 龜 # CJK COMPATIBILITY IDEOGRAPH-F907 +F908 龜 # CJK COMPATIBILITY IDEOGRAPH-F908 +F909 契 # CJK COMPATIBILITY IDEOGRAPH-F909 +F90A 金 # CJK COMPATIBILITY IDEOGRAPH-F90A +F90B å–‡ # CJK COMPATIBILITY IDEOGRAPH-F90B +F90C 奈 # CJK COMPATIBILITY IDEOGRAPH-F90C +F90D 懶 # CJK COMPATIBILITY IDEOGRAPH-F90D +F90E 癩 # CJK COMPATIBILITY IDEOGRAPH-F90E +F90F ç¾… # CJK COMPATIBILITY IDEOGRAPH-F90F +F910 蘿 # CJK COMPATIBILITY IDEOGRAPH-F910 +F911 螺 # CJK COMPATIBILITY IDEOGRAPH-F911 +F912 裸 # CJK COMPATIBILITY IDEOGRAPH-F912 +F913 é‚ # CJK COMPATIBILITY IDEOGRAPH-F913 +F914 樂 # CJK COMPATIBILITY IDEOGRAPH-F914 +F915 æ´› # CJK COMPATIBILITY IDEOGRAPH-F915 +F916 烙 # CJK COMPATIBILITY IDEOGRAPH-F916 +F917 çž # CJK COMPATIBILITY IDEOGRAPH-F917 +F918 è½ # CJK COMPATIBILITY IDEOGRAPH-F918 +F919 é…ª # CJK COMPATIBILITY IDEOGRAPH-F919 +F91A é§± # CJK COMPATIBILITY IDEOGRAPH-F91A +F91B 亂 # CJK COMPATIBILITY IDEOGRAPH-F91B +F91C åµ # CJK COMPATIBILITY IDEOGRAPH-F91C +F91D 欄 # CJK COMPATIBILITY IDEOGRAPH-F91D +F91E 爛 # CJK COMPATIBILITY IDEOGRAPH-F91E +F91F 蘭 # CJK COMPATIBILITY IDEOGRAPH-F91F +F920 鸞 # CJK COMPATIBILITY IDEOGRAPH-F920 +F921 åµ # CJK COMPATIBILITY IDEOGRAPH-F921 +F922 æ¿« # CJK COMPATIBILITY IDEOGRAPH-F922 +F923 è— # CJK COMPATIBILITY IDEOGRAPH-F923 +F924 襤 # CJK COMPATIBILITY IDEOGRAPH-F924 +F925 拉 # CJK COMPATIBILITY IDEOGRAPH-F925 +F926 臘 # CJK COMPATIBILITY IDEOGRAPH-F926 +F927 è Ÿ # CJK COMPATIBILITY IDEOGRAPH-F927 +F928 廊 # CJK COMPATIBILITY IDEOGRAPH-F928 +F929 朗 # CJK COMPATIBILITY IDEOGRAPH-F929 +F92A 浪 # CJK COMPATIBILITY IDEOGRAPH-F92A +F92B 狼 # CJK COMPATIBILITY IDEOGRAPH-F92B +F92C 郎 # CJK COMPATIBILITY IDEOGRAPH-F92C +F92D 來 # CJK COMPATIBILITY IDEOGRAPH-F92D +F92E 冷 # CJK COMPATIBILITY IDEOGRAPH-F92E +F92F 勞 # CJK COMPATIBILITY IDEOGRAPH-F92F +F930 æ“„ # CJK COMPATIBILITY IDEOGRAPH-F930 +F931 æ«“ # CJK COMPATIBILITY IDEOGRAPH-F931 +F932 çˆ # CJK COMPATIBILITY IDEOGRAPH-F932 +F933 ç›§ # CJK COMPATIBILITY IDEOGRAPH-F933 +F934 è€ # CJK COMPATIBILITY IDEOGRAPH-F934 +F935 蘆 # CJK COMPATIBILITY IDEOGRAPH-F935 +F936 虜 # CJK COMPATIBILITY IDEOGRAPH-F936 +F937 è·¯ # CJK COMPATIBILITY IDEOGRAPH-F937 +F938 露 # CJK COMPATIBILITY IDEOGRAPH-F938 +F939 é­¯ # CJK COMPATIBILITY IDEOGRAPH-F939 +F93A é·º # CJK COMPATIBILITY IDEOGRAPH-F93A +F93B 碌 # CJK COMPATIBILITY IDEOGRAPH-F93B +F93C 祿 # CJK COMPATIBILITY IDEOGRAPH-F93C +F93D ç¶  # CJK COMPATIBILITY IDEOGRAPH-F93D +F93E è‰ # CJK COMPATIBILITY IDEOGRAPH-F93E +F93F 錄 # CJK COMPATIBILITY IDEOGRAPH-F93F +F940 鹿 # CJK COMPATIBILITY IDEOGRAPH-F940 +F941 è«– # CJK COMPATIBILITY IDEOGRAPH-F941 +F942 壟 # CJK COMPATIBILITY IDEOGRAPH-F942 +F943 弄 # CJK COMPATIBILITY IDEOGRAPH-F943 +F944 ç±  # CJK COMPATIBILITY IDEOGRAPH-F944 +F945 è¾ # CJK COMPATIBILITY IDEOGRAPH-F945 +F946 牢 # CJK COMPATIBILITY IDEOGRAPH-F946 +F947 磊 # CJK COMPATIBILITY IDEOGRAPH-F947 +F948 賂 # CJK COMPATIBILITY IDEOGRAPH-F948 +F949 é›· # CJK COMPATIBILITY IDEOGRAPH-F949 +F94A 壘 # CJK COMPATIBILITY IDEOGRAPH-F94A +F94B å±¢ # CJK COMPATIBILITY IDEOGRAPH-F94B +F94C 樓 # CJK COMPATIBILITY IDEOGRAPH-F94C +F94D æ·š # CJK COMPATIBILITY IDEOGRAPH-F94D +F94E æ¼ # CJK COMPATIBILITY IDEOGRAPH-F94E +F94F ç´¯ # CJK COMPATIBILITY IDEOGRAPH-F94F +F950 縷 # CJK COMPATIBILITY IDEOGRAPH-F950 +F951 陋 # CJK COMPATIBILITY IDEOGRAPH-F951 +F952 å‹’ # CJK COMPATIBILITY IDEOGRAPH-F952 +F953 è‚‹ # CJK COMPATIBILITY IDEOGRAPH-F953 +F954 凜 # CJK COMPATIBILITY IDEOGRAPH-F954 +F955 凌 # CJK COMPATIBILITY IDEOGRAPH-F955 +F956 稜 # CJK COMPATIBILITY IDEOGRAPH-F956 +F957 ç¶¾ # CJK COMPATIBILITY IDEOGRAPH-F957 +F958 è± # CJK COMPATIBILITY IDEOGRAPH-F958 +F959 陵 # CJK COMPATIBILITY IDEOGRAPH-F959 +F95A 讀 # CJK COMPATIBILITY IDEOGRAPH-F95A +F95B æ‹ # CJK COMPATIBILITY IDEOGRAPH-F95B +F95C 樂 # CJK COMPATIBILITY IDEOGRAPH-F95C +F95D 諾 # CJK COMPATIBILITY IDEOGRAPH-F95D +F95E 丹 # CJK COMPATIBILITY IDEOGRAPH-F95E +F95F 寧 # CJK COMPATIBILITY IDEOGRAPH-F95F +F960 怒 # CJK COMPATIBILITY IDEOGRAPH-F960 +F961 率 # CJK COMPATIBILITY IDEOGRAPH-F961 +F962 ç•° # CJK COMPATIBILITY IDEOGRAPH-F962 +F963 北 # CJK COMPATIBILITY IDEOGRAPH-F963 +F964 磻 # CJK COMPATIBILITY IDEOGRAPH-F964 +F965 便 # CJK COMPATIBILITY IDEOGRAPH-F965 +F966 復 # CJK COMPATIBILITY IDEOGRAPH-F966 +F967 ä¸ # CJK COMPATIBILITY IDEOGRAPH-F967 +F968 泌 # CJK COMPATIBILITY IDEOGRAPH-F968 +F969 數 # CJK COMPATIBILITY IDEOGRAPH-F969 +F96A ç´¢ # CJK COMPATIBILITY IDEOGRAPH-F96A +F96B åƒ # CJK COMPATIBILITY IDEOGRAPH-F96B +F96C 塞 # CJK COMPATIBILITY IDEOGRAPH-F96C +F96D çœ # CJK COMPATIBILITY IDEOGRAPH-F96D +F96E 葉 # CJK COMPATIBILITY IDEOGRAPH-F96E +F96F 說 # CJK COMPATIBILITY IDEOGRAPH-F96F +F970 殺 # CJK COMPATIBILITY IDEOGRAPH-F970 +F971 è¾° # CJK COMPATIBILITY IDEOGRAPH-F971 +F972 沈 # CJK COMPATIBILITY IDEOGRAPH-F972 +F973 拾 # CJK COMPATIBILITY IDEOGRAPH-F973 +F974 è‹¥ # CJK COMPATIBILITY IDEOGRAPH-F974 +F975 掠 # CJK COMPATIBILITY IDEOGRAPH-F975 +F976 ç•¥ # CJK COMPATIBILITY IDEOGRAPH-F976 +F977 亮 # CJK COMPATIBILITY IDEOGRAPH-F977 +F978 å…© # CJK COMPATIBILITY IDEOGRAPH-F978 +F979 凉 # CJK COMPATIBILITY IDEOGRAPH-F979 +F97A æ¢ # CJK COMPATIBILITY IDEOGRAPH-F97A +F97B ç³§ # CJK COMPATIBILITY IDEOGRAPH-F97B +F97C 良 # CJK COMPATIBILITY IDEOGRAPH-F97C +F97D è«’ # CJK COMPATIBILITY IDEOGRAPH-F97D +F97E é‡ # CJK COMPATIBILITY IDEOGRAPH-F97E +F97F 勵 # CJK COMPATIBILITY IDEOGRAPH-F97F +F980 å‘‚ # CJK COMPATIBILITY IDEOGRAPH-F980 +F981 女 # CJK COMPATIBILITY IDEOGRAPH-F981 +F982 廬 # CJK COMPATIBILITY IDEOGRAPH-F982 +F983 æ—… # CJK COMPATIBILITY IDEOGRAPH-F983 +F984 濾 # CJK COMPATIBILITY IDEOGRAPH-F984 +F985 礪 # CJK COMPATIBILITY IDEOGRAPH-F985 +F986 é–­ # CJK COMPATIBILITY IDEOGRAPH-F986 +F987 驪 # CJK COMPATIBILITY IDEOGRAPH-F987 +F988 麗 # CJK COMPATIBILITY IDEOGRAPH-F988 +F989 黎 # CJK COMPATIBILITY IDEOGRAPH-F989 +F98A 力 # CJK COMPATIBILITY IDEOGRAPH-F98A +F98B 曆 # CJK COMPATIBILITY IDEOGRAPH-F98B +F98C æ­· # CJK COMPATIBILITY IDEOGRAPH-F98C +F98D è½¢ # CJK COMPATIBILITY IDEOGRAPH-F98D +F98E å¹´ # CJK COMPATIBILITY IDEOGRAPH-F98E +F98F æ† # CJK COMPATIBILITY IDEOGRAPH-F98F +F990 戀 # CJK COMPATIBILITY IDEOGRAPH-F990 +F991 æ’š # CJK COMPATIBILITY IDEOGRAPH-F991 +F992 æ¼£ # CJK COMPATIBILITY IDEOGRAPH-F992 +F993 ç…‰ # CJK COMPATIBILITY IDEOGRAPH-F993 +F994 ç’‰ # CJK COMPATIBILITY IDEOGRAPH-F994 +F995 ç§Š # CJK COMPATIBILITY IDEOGRAPH-F995 +F996 ç·´ # CJK COMPATIBILITY IDEOGRAPH-F996 +F997 è¯ # CJK COMPATIBILITY IDEOGRAPH-F997 +F998 輦 # CJK COMPATIBILITY IDEOGRAPH-F998 +F999 è“® # CJK COMPATIBILITY IDEOGRAPH-F999 +F99A 連 # CJK COMPATIBILITY IDEOGRAPH-F99A +F99B éŠ # CJK COMPATIBILITY IDEOGRAPH-F99B +F99C 列 # CJK COMPATIBILITY IDEOGRAPH-F99C +F99D 劣 # CJK COMPATIBILITY IDEOGRAPH-F99D +F99E å’½ # CJK COMPATIBILITY IDEOGRAPH-F99E +F99F 烈 # CJK COMPATIBILITY IDEOGRAPH-F99F +F9A0 裂 # CJK COMPATIBILITY IDEOGRAPH-F9A0 +F9A1 說 # CJK COMPATIBILITY IDEOGRAPH-F9A1 +F9A2 廉 # CJK COMPATIBILITY IDEOGRAPH-F9A2 +F9A3 念 # CJK COMPATIBILITY IDEOGRAPH-F9A3 +F9A4 æ» # CJK COMPATIBILITY IDEOGRAPH-F9A4 +F9A5 æ®® # CJK COMPATIBILITY IDEOGRAPH-F9A5 +F9A6 ç°¾ # CJK COMPATIBILITY IDEOGRAPH-F9A6 +F9A7 çµ # CJK COMPATIBILITY IDEOGRAPH-F9A7 +F9A8 令 # CJK COMPATIBILITY IDEOGRAPH-F9A8 +F9A9 囹 # CJK COMPATIBILITY IDEOGRAPH-F9A9 +F9AA 寧 # CJK COMPATIBILITY IDEOGRAPH-F9AA +F9AB 嶺 # CJK COMPATIBILITY IDEOGRAPH-F9AB +F9AC 怜 # CJK COMPATIBILITY IDEOGRAPH-F9AC +F9AD 玲 # CJK COMPATIBILITY IDEOGRAPH-F9AD +F9AE ç‘© # CJK COMPATIBILITY IDEOGRAPH-F9AE +F9AF 羚 # CJK COMPATIBILITY IDEOGRAPH-F9AF +F9B0 è† # CJK COMPATIBILITY IDEOGRAPH-F9B0 +F9B1 鈴 # CJK COMPATIBILITY IDEOGRAPH-F9B1 +F9B2 é›¶ # CJK COMPATIBILITY IDEOGRAPH-F9B2 +F9B3 éˆ # CJK COMPATIBILITY IDEOGRAPH-F9B3 +F9B4 é ˜ # CJK COMPATIBILITY IDEOGRAPH-F9B4 +F9B5 例 # CJK COMPATIBILITY IDEOGRAPH-F9B5 +F9B6 禮 # CJK COMPATIBILITY IDEOGRAPH-F9B6 +F9B7 醴 # CJK COMPATIBILITY IDEOGRAPH-F9B7 +F9B8 隸 # CJK COMPATIBILITY IDEOGRAPH-F9B8 +F9B9 惡 # CJK COMPATIBILITY IDEOGRAPH-F9B9 +F9BA 了 # CJK COMPATIBILITY IDEOGRAPH-F9BA +F9BB 僚 # CJK COMPATIBILITY IDEOGRAPH-F9BB +F9BC 寮 # CJK COMPATIBILITY IDEOGRAPH-F9BC +F9BD å°¿ # CJK COMPATIBILITY IDEOGRAPH-F9BD +F9BE æ–™ # CJK COMPATIBILITY IDEOGRAPH-F9BE +F9BF 樂 # CJK COMPATIBILITY IDEOGRAPH-F9BF +F9C0 燎 # CJK COMPATIBILITY IDEOGRAPH-F9C0 +F9C1 療 # CJK COMPATIBILITY IDEOGRAPH-F9C1 +F9C2 蓼 # CJK COMPATIBILITY IDEOGRAPH-F9C2 +F9C3 é¼ # CJK COMPATIBILITY IDEOGRAPH-F9C3 +F9C4 é¾ # CJK COMPATIBILITY IDEOGRAPH-F9C4 +F9C5 暈 # CJK COMPATIBILITY IDEOGRAPH-F9C5 +F9C6 阮 # CJK COMPATIBILITY IDEOGRAPH-F9C6 +F9C7 劉 # CJK COMPATIBILITY IDEOGRAPH-F9C7 +F9C8 æ» # CJK COMPATIBILITY IDEOGRAPH-F9C8 +F9C9 柳 # CJK COMPATIBILITY IDEOGRAPH-F9C9 +F9CA æµ # CJK COMPATIBILITY IDEOGRAPH-F9CA +F9CB 溜 # CJK COMPATIBILITY IDEOGRAPH-F9CB +F9CC ç‰ # CJK COMPATIBILITY IDEOGRAPH-F9CC +F9CD ç•™ # CJK COMPATIBILITY IDEOGRAPH-F9CD +F9CE ç¡« # CJK COMPATIBILITY IDEOGRAPH-F9CE +F9CF ç´ # CJK COMPATIBILITY IDEOGRAPH-F9CF +F9D0 類 # CJK COMPATIBILITY IDEOGRAPH-F9D0 +F9D1 å…­ # CJK COMPATIBILITY IDEOGRAPH-F9D1 +F9D2 戮 # CJK COMPATIBILITY IDEOGRAPH-F9D2 +F9D3 陸 # CJK COMPATIBILITY IDEOGRAPH-F9D3 +F9D4 倫 # CJK COMPATIBILITY IDEOGRAPH-F9D4 +F9D5 å´™ # CJK COMPATIBILITY IDEOGRAPH-F9D5 +F9D6 æ·ª # CJK COMPATIBILITY IDEOGRAPH-F9D6 +F9D7 輪 # CJK COMPATIBILITY IDEOGRAPH-F9D7 +F9D8 律 # CJK COMPATIBILITY IDEOGRAPH-F9D8 +F9D9 æ…„ # CJK COMPATIBILITY IDEOGRAPH-F9D9 +F9DA æ — # CJK COMPATIBILITY IDEOGRAPH-F9DA +F9DB 率 # CJK COMPATIBILITY IDEOGRAPH-F9DB +F9DC 隆 # CJK COMPATIBILITY IDEOGRAPH-F9DC +F9DD 利 # CJK COMPATIBILITY IDEOGRAPH-F9DD +F9DE å # CJK COMPATIBILITY IDEOGRAPH-F9DE +F9DF å±¥ # CJK COMPATIBILITY IDEOGRAPH-F9DF +F9E0 易 # CJK COMPATIBILITY IDEOGRAPH-F9E0 +F9E1 æŽ # CJK COMPATIBILITY IDEOGRAPH-F9E1 +F9E2 梨 # CJK COMPATIBILITY IDEOGRAPH-F9E2 +F9E3 æ³¥ # CJK COMPATIBILITY IDEOGRAPH-F9E3 +F9E4 ç† # CJK COMPATIBILITY IDEOGRAPH-F9E4 +F9E5 ç—¢ # CJK COMPATIBILITY IDEOGRAPH-F9E5 +F9E6 ç½¹ # CJK COMPATIBILITY IDEOGRAPH-F9E6 +F9E7 è£ # CJK COMPATIBILITY IDEOGRAPH-F9E7 +F9E8 裡 # CJK COMPATIBILITY IDEOGRAPH-F9E8 +F9E9 里 # CJK COMPATIBILITY IDEOGRAPH-F9E9 +F9EA 離 # CJK COMPATIBILITY IDEOGRAPH-F9EA +F9EB 匿 # CJK COMPATIBILITY IDEOGRAPH-F9EB +F9EC 溺 # CJK COMPATIBILITY IDEOGRAPH-F9EC +F9ED å # CJK COMPATIBILITY IDEOGRAPH-F9ED +F9EE ç‡ # CJK COMPATIBILITY IDEOGRAPH-F9EE +F9EF ç’˜ # CJK COMPATIBILITY IDEOGRAPH-F9EF +F9F0 è—º # CJK COMPATIBILITY IDEOGRAPH-F9F0 +F9F1 隣 # CJK COMPATIBILITY IDEOGRAPH-F9F1 +F9F2 é±— # CJK COMPATIBILITY IDEOGRAPH-F9F2 +F9F3 麟 # CJK COMPATIBILITY IDEOGRAPH-F9F3 +F9F4 æž— # CJK COMPATIBILITY IDEOGRAPH-F9F4 +F9F5 æ·‹ # CJK COMPATIBILITY IDEOGRAPH-F9F5 +F9F6 臨 # CJK COMPATIBILITY IDEOGRAPH-F9F6 +F9F7 ç«‹ # CJK COMPATIBILITY IDEOGRAPH-F9F7 +F9F8 笠 # CJK COMPATIBILITY IDEOGRAPH-F9F8 +F9F9 ç²’ # CJK COMPATIBILITY IDEOGRAPH-F9F9 +F9FA ç‹€ # CJK COMPATIBILITY IDEOGRAPH-F9FA +F9FB ç‚™ # CJK COMPATIBILITY IDEOGRAPH-F9FB +F9FC è­˜ # CJK COMPATIBILITY IDEOGRAPH-F9FC +F9FD 什 # CJK COMPATIBILITY IDEOGRAPH-F9FD +F9FE 茶 # CJK COMPATIBILITY IDEOGRAPH-F9FE +F9FF 刺 # CJK COMPATIBILITY IDEOGRAPH-F9FF +FA00 切 # CJK COMPATIBILITY IDEOGRAPH-FA00 +FA01 度 # CJK COMPATIBILITY IDEOGRAPH-FA01 +FA02 æ‹“ # CJK COMPATIBILITY IDEOGRAPH-FA02 +FA03 ç³– # CJK COMPATIBILITY IDEOGRAPH-FA03 +FA04 å®… # CJK COMPATIBILITY IDEOGRAPH-FA04 +FA05 æ´ž # CJK COMPATIBILITY IDEOGRAPH-FA05 +FA06 æš´ # CJK COMPATIBILITY IDEOGRAPH-FA06 +FA07 è¼» # CJK COMPATIBILITY IDEOGRAPH-FA07 +FA08 行 # CJK COMPATIBILITY IDEOGRAPH-FA08 +FA09 é™ # CJK COMPATIBILITY IDEOGRAPH-FA09 +FA0A 見 # CJK COMPATIBILITY IDEOGRAPH-FA0A +FA0B 廓 # CJK COMPATIBILITY IDEOGRAPH-FA0B +FA0C å…€ # CJK COMPATIBILITY IDEOGRAPH-FA0C +FA0D å—€ # CJK COMPATIBILITY IDEOGRAPH-FA0D +FA10 塚 # CJK COMPATIBILITY IDEOGRAPH-FA10 +FA12 æ™´ # CJK COMPATIBILITY IDEOGRAPH-FA12 +FA15 凞 # CJK COMPATIBILITY IDEOGRAPH-FA15 +FA16 猪 # CJK COMPATIBILITY IDEOGRAPH-FA16 +FA17 益 # CJK COMPATIBILITY IDEOGRAPH-FA17 +FA18 礼 # CJK COMPATIBILITY IDEOGRAPH-FA18 +FA19 神 # CJK COMPATIBILITY IDEOGRAPH-FA19 +FA1A 祥 # CJK COMPATIBILITY IDEOGRAPH-FA1A +FA1B ç¦ # CJK COMPATIBILITY IDEOGRAPH-FA1B +FA1C é– # CJK COMPATIBILITY IDEOGRAPH-FA1C +FA1D ç²¾ # CJK COMPATIBILITY IDEOGRAPH-FA1D +FA1E ç¾½ # CJK COMPATIBILITY IDEOGRAPH-FA1E +FA20 蘒 # CJK COMPATIBILITY IDEOGRAPH-FA20 +FA22 諸 # CJK COMPATIBILITY IDEOGRAPH-FA22 +FA25 逸 # CJK COMPATIBILITY IDEOGRAPH-FA25 +FA26 都 # CJK COMPATIBILITY IDEOGRAPH-FA26 +FA2A 飯 # CJK COMPATIBILITY IDEOGRAPH-FA2A +FA2B 飼 # CJK COMPATIBILITY IDEOGRAPH-FA2B +FA2C 館 # CJK COMPATIBILITY IDEOGRAPH-FA2C +FA2D é¶´ # CJK COMPATIBILITY IDEOGRAPH-FA2D +FA30 ä¾® # CJK COMPATIBILITY IDEOGRAPH-FA30 +FA31 僧 # CJK COMPATIBILITY IDEOGRAPH-FA31 +FA32 å… # CJK COMPATIBILITY IDEOGRAPH-FA32 +FA33 勉 # CJK COMPATIBILITY IDEOGRAPH-FA33 +FA34 勤 # CJK COMPATIBILITY IDEOGRAPH-FA34 +FA35 å‘ # CJK COMPATIBILITY IDEOGRAPH-FA35 +FA36 å– # CJK COMPATIBILITY IDEOGRAPH-FA36 +FA37 嘆 # CJK COMPATIBILITY IDEOGRAPH-FA37 +FA38 器 # CJK COMPATIBILITY IDEOGRAPH-FA38 +FA39 å¡€ # CJK COMPATIBILITY IDEOGRAPH-FA39 +FA3A 墨 # CJK COMPATIBILITY IDEOGRAPH-FA3A +FA3B 層 # CJK COMPATIBILITY IDEOGRAPH-FA3B +FA3C å±® # CJK COMPATIBILITY IDEOGRAPH-FA3C +FA3D æ‚” # CJK COMPATIBILITY IDEOGRAPH-FA3D +FA3E æ…¨ # CJK COMPATIBILITY IDEOGRAPH-FA3E +FA3F 憎 # CJK COMPATIBILITY IDEOGRAPH-FA3F +FA40 懲 # CJK COMPATIBILITY IDEOGRAPH-FA40 +FA41 æ• # CJK COMPATIBILITY IDEOGRAPH-FA41 +FA42 æ—¢ # CJK COMPATIBILITY IDEOGRAPH-FA42 +FA43 æš‘ # CJK COMPATIBILITY IDEOGRAPH-FA43 +FA44 梅 # CJK COMPATIBILITY IDEOGRAPH-FA44 +FA45 æµ· # CJK COMPATIBILITY IDEOGRAPH-FA45 +FA46 渚 # CJK COMPATIBILITY IDEOGRAPH-FA46 +FA47 æ¼¢ # CJK COMPATIBILITY IDEOGRAPH-FA47 +FA48 ç…® # CJK COMPATIBILITY IDEOGRAPH-FA48 +FA49 爫 # CJK COMPATIBILITY IDEOGRAPH-FA49 +FA4A ç¢ # CJK COMPATIBILITY IDEOGRAPH-FA4A +FA4B 碑 # CJK COMPATIBILITY IDEOGRAPH-FA4B +FA4C 社 # CJK COMPATIBILITY IDEOGRAPH-FA4C +FA4D 祉 # CJK COMPATIBILITY IDEOGRAPH-FA4D +FA4E 祈 # CJK COMPATIBILITY IDEOGRAPH-FA4E +FA4F ç¥ # CJK COMPATIBILITY IDEOGRAPH-FA4F +FA50 祖 # CJK COMPATIBILITY IDEOGRAPH-FA50 +FA51 ç¥ # CJK COMPATIBILITY IDEOGRAPH-FA51 +FA52 ç¦ # CJK COMPATIBILITY IDEOGRAPH-FA52 +FA53 禎 # CJK COMPATIBILITY IDEOGRAPH-FA53 +FA54 ç©€ # CJK COMPATIBILITY IDEOGRAPH-FA54 +FA55 çª # CJK COMPATIBILITY IDEOGRAPH-FA55 +FA56 節 # CJK COMPATIBILITY IDEOGRAPH-FA56 +FA57 ç·´ # CJK COMPATIBILITY IDEOGRAPH-FA57 +FA58 縉 # CJK COMPATIBILITY IDEOGRAPH-FA58 +FA59 ç¹ # CJK COMPATIBILITY IDEOGRAPH-FA59 +FA5A ç½² # CJK COMPATIBILITY IDEOGRAPH-FA5A +FA5B 者 # CJK COMPATIBILITY IDEOGRAPH-FA5B +FA5C 臭 # CJK COMPATIBILITY IDEOGRAPH-FA5C +FA5D 艹 # CJK COMPATIBILITY IDEOGRAPH-FA5D +FA5E 艹 # CJK COMPATIBILITY IDEOGRAPH-FA5E +FA5F è‘— # CJK COMPATIBILITY IDEOGRAPH-FA5F +FA60 è¤ # CJK COMPATIBILITY IDEOGRAPH-FA60 +FA61 視 # CJK COMPATIBILITY IDEOGRAPH-FA61 +FA62 è¬ # CJK COMPATIBILITY IDEOGRAPH-FA62 +FA63 謹 # CJK COMPATIBILITY IDEOGRAPH-FA63 +FA64 賓 # CJK COMPATIBILITY IDEOGRAPH-FA64 +FA65 è´ˆ # CJK COMPATIBILITY IDEOGRAPH-FA65 +FA66 è¾¶ # CJK COMPATIBILITY IDEOGRAPH-FA66 +FA67 逸 # CJK COMPATIBILITY IDEOGRAPH-FA67 +FA68 難 # CJK COMPATIBILITY IDEOGRAPH-FA68 +FA69 響 # CJK COMPATIBILITY IDEOGRAPH-FA69 +FA6A é » # CJK COMPATIBILITY IDEOGRAPH-FA6A +FB00 ff # LATIN SMALL LIGATURE FF +FB01 fi # LATIN SMALL LIGATURE FI +FB02 fl # LATIN SMALL LIGATURE FL +FB03 ffi # LATIN SMALL LIGATURE FFI +FB04 ffl # LATIN SMALL LIGATURE FFL +FB05 Å¿t # LATIN SMALL LIGATURE LONG S T +FB06 st # LATIN SMALL LIGATURE ST +FB13 Õ´Õ¶ # ARMENIAN SMALL LIGATURE MEN NOW +FB14 Õ´Õ¥ # ARMENIAN SMALL LIGATURE MEN ECH +FB15 Õ´Õ« # ARMENIAN SMALL LIGATURE MEN INI +FB16 Õ¾Õ¶ # ARMENIAN SMALL LIGATURE VEW NOW +FB17 Õ´Õ­ # ARMENIAN SMALL LIGATURE MEN XEH +FB20 ×¢ # HEBREW LETTER ALTERNATIVE AYIN +FB21 × # HEBREW LETTER WIDE ALEF +FB22 ד # HEBREW LETTER WIDE DALET +FB23 ×” # HEBREW LETTER WIDE HE +FB24 ×› # HEBREW LETTER WIDE KAF +FB25 ל # HEBREW LETTER WIDE LAMED +FB26 × # HEBREW LETTER WIDE FINAL MEM +FB27 ר # HEBREW LETTER WIDE RESH +FB28 ת # HEBREW LETTER WIDE TAV +FB29 + # HEBREW LETTER ALTERNATIVE PLUS SIGN +FB4F ×ל # HEBREW LIGATURE ALEF LAMED +FE49 ‾ # DASHED OVERLINE +FE4A ‾ # CENTRELINE OVERLINE +FE4B ‾ # WAVY OVERLINE +FE4C ‾ # DOUBLE WAVY OVERLINE +FE4D _ # DASHED LOW LINE +FE4E _ # CENTRELINE LOW LINE +FE4F _ # WAVY LOW LINE +FE50 , # SMALL COMMA +FE51 〠# SMALL IDEOGRAPHIC COMMA +FE52 . # SMALL FULL STOP +FE54 ; # SMALL SEMICOLON +FE55 : # SMALL COLON +FE56 ? # SMALL QUESTION MARK +FE57 ! # SMALL EXCLAMATION MARK +FE58 — # SMALL EM DASH +FE59 ( # SMALL LEFT PARENTHESIS +FE5A ) # SMALL RIGHT PARENTHESIS +FE5B { # SMALL LEFT CURLY BRACKET +FE5C } # SMALL RIGHT CURLY BRACKET +FE5D 〔 # SMALL LEFT TORTOISE SHELL BRACKET +FE5E 〕 # SMALL RIGHT TORTOISE SHELL BRACKET +FE5F # # SMALL NUMBER SIGN +FE60 & # SMALL AMPERSAND +FE61 * # SMALL ASTERISK +FE62 + # SMALL PLUS SIGN +FE63 - # SMALL HYPHEN-MINUS +FE64 < # SMALL LESS-THAN SIGN +FE65 > # SMALL GREATER-THAN SIGN +FE66 = # SMALL EQUALS SIGN +FE68 \ # SMALL REVERSE SOLIDUS +FE69 $ # SMALL DOLLAR SIGN +FE6A % # SMALL PERCENT SIGN +FE6B @ # SMALL COMMERCIAL AT +FF01 ! # FULLWIDTH EXCLAMATION MARK +FF02 " # FULLWIDTH QUOTATION MARK +FF03 # # FULLWIDTH NUMBER SIGN +FF04 $ # FULLWIDTH DOLLAR SIGN +FF05 % # FULLWIDTH PERCENT SIGN +FF06 & # FULLWIDTH AMPERSAND +FF07 ' # FULLWIDTH APOSTROPHE +FF08 ( # FULLWIDTH LEFT PARENTHESIS +FF09 ) # FULLWIDTH RIGHT PARENTHESIS +FF0A * # FULLWIDTH ASTERISK +FF0B + # FULLWIDTH PLUS SIGN +FF0C , # FULLWIDTH COMMA +FF0D - # FULLWIDTH HYPHEN-MINUS +FF0E . # FULLWIDTH FULL STOP +FF0F / # FULLWIDTH SOLIDUS +FF10 0 # FULLWIDTH DIGIT ZERO +FF11 1 # FULLWIDTH DIGIT ONE +FF12 2 # FULLWIDTH DIGIT TWO +FF13 3 # FULLWIDTH DIGIT THREE +FF14 4 # FULLWIDTH DIGIT FOUR +FF15 5 # FULLWIDTH DIGIT FIVE +FF16 6 # FULLWIDTH DIGIT SIX +FF17 7 # FULLWIDTH DIGIT SEVEN +FF18 8 # FULLWIDTH DIGIT EIGHT +FF19 9 # FULLWIDTH DIGIT NINE +FF1A : # FULLWIDTH COLON +FF1B ; # FULLWIDTH SEMICOLON +FF1C < # FULLWIDTH LESS-THAN SIGN +FF1D = # FULLWIDTH EQUALS SIGN +FF1E > # FULLWIDTH GREATER-THAN SIGN +FF1F ? # FULLWIDTH QUESTION MARK +FF20 @ # FULLWIDTH COMMERCIAL AT +FF21 A # FULLWIDTH LATIN CAPITAL LETTER A +FF22 B # FULLWIDTH LATIN CAPITAL LETTER B +FF23 C # FULLWIDTH LATIN CAPITAL LETTER C +FF24 D # FULLWIDTH LATIN CAPITAL LETTER D +FF25 E # FULLWIDTH LATIN CAPITAL LETTER E +FF26 F # FULLWIDTH LATIN CAPITAL LETTER F +FF27 G # FULLWIDTH LATIN CAPITAL LETTER G +FF28 H # FULLWIDTH LATIN CAPITAL LETTER H +FF29 I # FULLWIDTH LATIN CAPITAL LETTER I +FF2A J # FULLWIDTH LATIN CAPITAL LETTER J +FF2B K # FULLWIDTH LATIN CAPITAL LETTER K +FF2C L # FULLWIDTH LATIN CAPITAL LETTER L +FF2D M # FULLWIDTH LATIN CAPITAL LETTER M +FF2E N # FULLWIDTH LATIN CAPITAL LETTER N +FF2F O # FULLWIDTH LATIN CAPITAL LETTER O +FF30 P # FULLWIDTH LATIN CAPITAL LETTER P +FF31 Q # FULLWIDTH LATIN CAPITAL LETTER Q +FF32 R # FULLWIDTH LATIN CAPITAL LETTER R +FF33 S # FULLWIDTH LATIN CAPITAL LETTER S +FF34 T # FULLWIDTH LATIN CAPITAL LETTER T +FF35 U # FULLWIDTH LATIN CAPITAL LETTER U +FF36 V # FULLWIDTH LATIN CAPITAL LETTER V +FF37 W # FULLWIDTH LATIN CAPITAL LETTER W +FF38 X # FULLWIDTH LATIN CAPITAL LETTER X +FF39 Y # FULLWIDTH LATIN CAPITAL LETTER Y +FF3A Z # FULLWIDTH LATIN CAPITAL LETTER Z +FF3B [ # FULLWIDTH LEFT SQUARE BRACKET +FF3C \ # FULLWIDTH REVERSE SOLIDUS +FF3D ] # FULLWIDTH RIGHT SQUARE BRACKET +FF3E ^ # FULLWIDTH CIRCUMFLEX ACCENT +FF3F _ # FULLWIDTH LOW LINE +FF40 ` # FULLWIDTH GRAVE ACCENT +FF41 a # FULLWIDTH LATIN SMALL LETTER A +FF42 b # FULLWIDTH LATIN SMALL LETTER B +FF43 c # FULLWIDTH LATIN SMALL LETTER C +FF44 d # FULLWIDTH LATIN SMALL LETTER D +FF45 e # FULLWIDTH LATIN SMALL LETTER E +FF46 f # FULLWIDTH LATIN SMALL LETTER F +FF47 g # FULLWIDTH LATIN SMALL LETTER G +FF48 h # FULLWIDTH LATIN SMALL LETTER H +FF49 i # FULLWIDTH LATIN SMALL LETTER I +FF4A j # FULLWIDTH LATIN SMALL LETTER J +FF4B k # FULLWIDTH LATIN SMALL LETTER K +FF4C l # FULLWIDTH LATIN SMALL LETTER L +FF4D m # FULLWIDTH LATIN SMALL LETTER M +FF4E n # FULLWIDTH LATIN SMALL LETTER N +FF4F o # FULLWIDTH LATIN SMALL LETTER O +FF50 p # FULLWIDTH LATIN SMALL LETTER P +FF51 q # FULLWIDTH LATIN SMALL LETTER Q +FF52 r # FULLWIDTH LATIN SMALL LETTER R +FF53 s # FULLWIDTH LATIN SMALL LETTER S +FF54 t # FULLWIDTH LATIN SMALL LETTER T +FF55 u # FULLWIDTH LATIN SMALL LETTER U +FF56 v # FULLWIDTH LATIN SMALL LETTER V +FF57 w # FULLWIDTH LATIN SMALL LETTER W +FF58 x # FULLWIDTH LATIN SMALL LETTER X +FF59 y # FULLWIDTH LATIN SMALL LETTER Y +FF5A z # FULLWIDTH LATIN SMALL LETTER Z +FF5B { # FULLWIDTH LEFT CURLY BRACKET +FF5C | # FULLWIDTH VERTICAL LINE +FF5D } # FULLWIDTH RIGHT CURLY BRACKET +FF5E ~ # FULLWIDTH TILDE +FF5F ⦅ # FULLWIDTH LEFT WHITE PARENTHESIS +FF60 ⦆ # FULLWIDTH RIGHT WHITE PARENTHESIS +FF61 。 # HALFWIDTH IDEOGRAPHIC FULL STOP +FF62 「 # HALFWIDTH LEFT CORNER BRACKET +FF63 〠# HALFWIDTH RIGHT CORNER BRACKET +FF64 〠# HALFWIDTH IDEOGRAPHIC COMMA +FF65 ・ # HALFWIDTH KATAKANA MIDDLE DOT +FF66 ヲ # HALFWIDTH KATAKANA LETTER WO +FF67 ã‚¡ # HALFWIDTH KATAKANA LETTER SMALL A +FF68 ã‚£ # HALFWIDTH KATAKANA LETTER SMALL I +FF69 ã‚¥ # HALFWIDTH KATAKANA LETTER SMALL U +FF6A ã‚§ # HALFWIDTH KATAKANA LETTER SMALL E +FF6B ã‚© # HALFWIDTH KATAKANA LETTER SMALL O +FF6C ャ # HALFWIDTH KATAKANA LETTER SMALL YA +FF6D ュ # HALFWIDTH KATAKANA LETTER SMALL YU +FF6E ョ # HALFWIDTH KATAKANA LETTER SMALL YO +FF6F ッ # HALFWIDTH KATAKANA LETTER SMALL TU +FF70 ー # HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK +FF71 ã‚¢ # HALFWIDTH KATAKANA LETTER A +FF72 イ # HALFWIDTH KATAKANA LETTER I +FF73 ウ # HALFWIDTH KATAKANA LETTER U +FF74 エ # HALFWIDTH KATAKANA LETTER E +FF75 オ # HALFWIDTH KATAKANA LETTER O +FF76 ã‚« # HALFWIDTH KATAKANA LETTER KA +FF77 ã‚­ # HALFWIDTH KATAKANA LETTER KI +FF78 ク # HALFWIDTH KATAKANA LETTER KU +FF79 ケ # HALFWIDTH KATAKANA LETTER KE +FF7A コ # HALFWIDTH KATAKANA LETTER KO +FF7B サ # HALFWIDTH KATAKANA LETTER SA +FF7C ã‚· # HALFWIDTH KATAKANA LETTER SI +FF7D ス # HALFWIDTH KATAKANA LETTER SU +FF7E ã‚» # HALFWIDTH KATAKANA LETTER SE +FF7F ソ # HALFWIDTH KATAKANA LETTER SO +FF80 ã‚¿ # HALFWIDTH KATAKANA LETTER TA +FF81 ム# HALFWIDTH KATAKANA LETTER TI +FF82 ツ # HALFWIDTH KATAKANA LETTER TU +FF83 テ # HALFWIDTH KATAKANA LETTER TE +FF84 ト # HALFWIDTH KATAKANA LETTER TO +FF85 ナ # HALFWIDTH KATAKANA LETTER NA +FF86 ニ # HALFWIDTH KATAKANA LETTER NI +FF87 ヌ # HALFWIDTH KATAKANA LETTER NU +FF88 ム# HALFWIDTH KATAKANA LETTER NE +FF89 ノ # HALFWIDTH KATAKANA LETTER NO +FF8A ム# HALFWIDTH KATAKANA LETTER HA +FF8B ヒ # HALFWIDTH KATAKANA LETTER HI +FF8C フ # HALFWIDTH KATAKANA LETTER HU +FF8D ヘ # HALFWIDTH KATAKANA LETTER HE +FF8E ホ # HALFWIDTH KATAKANA LETTER HO +FF8F マ # HALFWIDTH KATAKANA LETTER MA +FF90 ミ # HALFWIDTH KATAKANA LETTER MI +FF91 ム # HALFWIDTH KATAKANA LETTER MU +FF92 メ # HALFWIDTH KATAKANA LETTER ME +FF93 モ # HALFWIDTH KATAKANA LETTER MO +FF94 ヤ # HALFWIDTH KATAKANA LETTER YA +FF95 ユ # HALFWIDTH KATAKANA LETTER YU +FF96 ヨ # HALFWIDTH KATAKANA LETTER YO +FF97 ラ # HALFWIDTH KATAKANA LETTER RA +FF98 リ # HALFWIDTH KATAKANA LETTER RI +FF99 ル # HALFWIDTH KATAKANA LETTER RU +FF9A レ # HALFWIDTH KATAKANA LETTER RE +FF9B ロ # HALFWIDTH KATAKANA LETTER RO +FF9C ワ # HALFWIDTH KATAKANA LETTER WA +FF9D ン # HALFWIDTH KATAKANA LETTER N +FF9E ã‚™ # HALFWIDTH KATAKANA VOICED SOUND MARK +FF9F ゚ # HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK +FFA0 ã…¤ # HALFWIDTH HANGUL FILLER +FFA1 ㄱ # HALFWIDTH HANGUL LETTER KIYEOK +FFA2 ㄲ # HALFWIDTH HANGUL LETTER SSANGKIYEOK +FFA3 ㄳ # HALFWIDTH HANGUL LETTER KIYEOK-SIOS +FFA4 ã„´ # HALFWIDTH HANGUL LETTER NIEUN +FFA5 ㄵ # HALFWIDTH HANGUL LETTER NIEUN-CIEUC +FFA6 ã„¶ # HALFWIDTH HANGUL LETTER NIEUN-HIEUH +FFA7 ã„· # HALFWIDTH HANGUL LETTER TIKEUT +FFA8 ㄸ # HALFWIDTH HANGUL LETTER SSANGTIKEUT +FFA9 ㄹ # HALFWIDTH HANGUL LETTER RIEUL +FFAA ㄺ # HALFWIDTH HANGUL LETTER RIEUL-KIYEOK +FFAB ã„» # HALFWIDTH HANGUL LETTER RIEUL-MIEUM +FFAC ㄼ # HALFWIDTH HANGUL LETTER RIEUL-PIEUP +FFAD ㄽ # HALFWIDTH HANGUL LETTER RIEUL-SIOS +FFAE ㄾ # HALFWIDTH HANGUL LETTER RIEUL-THIEUTH +FFAF ã„¿ # HALFWIDTH HANGUL LETTER RIEUL-PHIEUPH +FFB0 ã…€ # HALFWIDTH HANGUL LETTER RIEUL-HIEUH +FFB1 ã… # HALFWIDTH HANGUL LETTER MIEUM +FFB2 ã…‚ # HALFWIDTH HANGUL LETTER PIEUP +FFB3 ã…ƒ # HALFWIDTH HANGUL LETTER SSANGPIEUP +FFB4 ã…„ # HALFWIDTH HANGUL LETTER PIEUP-SIOS +FFB5 ã…… # HALFWIDTH HANGUL LETTER SIOS +FFB6 ã…† # HALFWIDTH HANGUL LETTER SSANGSIOS +FFB7 ã…‡ # HALFWIDTH HANGUL LETTER IEUNG +FFB8 ã…ˆ # HALFWIDTH HANGUL LETTER CIEUC +FFB9 ã…‰ # HALFWIDTH HANGUL LETTER SSANGCIEUC +FFBA ã…Š # HALFWIDTH HANGUL LETTER CHIEUCH +FFBB ã…‹ # HALFWIDTH HANGUL LETTER KHIEUKH +FFBC ã…Œ # HALFWIDTH HANGUL LETTER THIEUTH +FFBD ã… # HALFWIDTH HANGUL LETTER PHIEUPH +FFBE ã…Ž # HALFWIDTH HANGUL LETTER HIEUH +FFC2 ã… # HALFWIDTH HANGUL LETTER A +FFC3 ã… # HALFWIDTH HANGUL LETTER AE +FFC4 ã…‘ # HALFWIDTH HANGUL LETTER YA +FFC5 ã…’ # HALFWIDTH HANGUL LETTER YAE +FFC6 ã…“ # HALFWIDTH HANGUL LETTER EO +FFC7 ã…” # HALFWIDTH HANGUL LETTER E +FFCA ã…• # HALFWIDTH HANGUL LETTER YEO +FFCB ã…– # HALFWIDTH HANGUL LETTER YE +FFCC ã…— # HALFWIDTH HANGUL LETTER O +FFCD ã…˜ # HALFWIDTH HANGUL LETTER WA +FFCE ã…™ # HALFWIDTH HANGUL LETTER WAE +FFCF ã…š # HALFWIDTH HANGUL LETTER OE +FFD2 ã…› # HALFWIDTH HANGUL LETTER YO +FFD3 ã…œ # HALFWIDTH HANGUL LETTER U +FFD4 ã… # HALFWIDTH HANGUL LETTER WEO +FFD5 ã…ž # HALFWIDTH HANGUL LETTER WE +FFD6 ã…Ÿ # HALFWIDTH HANGUL LETTER WI +FFD7 ã…  # HALFWIDTH HANGUL LETTER YU +FFDA ã…¡ # HALFWIDTH HANGUL LETTER EU +FFDB ã…¢ # HALFWIDTH HANGUL LETTER YI +FFDC ã…£ # HALFWIDTH HANGUL LETTER I +FFE0 ¢ # FULLWIDTH CENT SIGN +FFE1 £ # FULLWIDTH POUND SIGN +FFE2 ¬ # FULLWIDTH NOT SIGN +FFE3 ¯ # FULLWIDTH MACRON +FFE4 ¦ # FULLWIDTH BROKEN BAR +FFE5 Â¥ # FULLWIDTH YEN SIGN +FFE6 â‚© # FULLWIDTH WON SIGN +FFE8 │ # HALFWIDTH FORMS LIGHT VERTICAL +FFE9 ↠# HALFWIDTH LEFTWARDS ARROW +FFEA ↑ # HALFWIDTH UPWARDS ARROW +FFEB → # HALFWIDTH RIGHTWARDS ARROW +FFEC ↓ # HALFWIDTH DOWNWARDS ARROW +FFED â–  # HALFWIDTH BLACK SQUARE +FFEE â—‹ # HALFWIDTH WHITE CIRCLE +1D400 A # MATHEMATICAL BOLD CAPITAL A +1D401 B # MATHEMATICAL BOLD CAPITAL B +1D402 C # MATHEMATICAL BOLD CAPITAL C +1D403 D # MATHEMATICAL BOLD CAPITAL D +1D404 E # MATHEMATICAL BOLD CAPITAL E +1D405 F # MATHEMATICAL BOLD CAPITAL F +1D406 G # MATHEMATICAL BOLD CAPITAL G +1D407 H # MATHEMATICAL BOLD CAPITAL H +1D408 I # MATHEMATICAL BOLD CAPITAL I +1D409 J # MATHEMATICAL BOLD CAPITAL J +1D40A K # MATHEMATICAL BOLD CAPITAL K +1D40B L # MATHEMATICAL BOLD CAPITAL L +1D40C M # MATHEMATICAL BOLD CAPITAL M +1D40D N # MATHEMATICAL BOLD CAPITAL N +1D40E O # MATHEMATICAL BOLD CAPITAL O +1D40F P # MATHEMATICAL BOLD CAPITAL P +1D410 Q # MATHEMATICAL BOLD CAPITAL Q +1D411 R # MATHEMATICAL BOLD CAPITAL R +1D412 S # MATHEMATICAL BOLD CAPITAL S +1D413 T # MATHEMATICAL BOLD CAPITAL T +1D414 U # MATHEMATICAL BOLD CAPITAL U +1D415 V # MATHEMATICAL BOLD CAPITAL V +1D416 W # MATHEMATICAL BOLD CAPITAL W +1D417 X # MATHEMATICAL BOLD CAPITAL X +1D418 Y # MATHEMATICAL BOLD CAPITAL Y +1D419 Z # MATHEMATICAL BOLD CAPITAL Z +1D41A a # MATHEMATICAL BOLD SMALL A +1D41B b # MATHEMATICAL BOLD SMALL B +1D41C c # MATHEMATICAL BOLD SMALL C +1D41D d # MATHEMATICAL BOLD SMALL D +1D41E e # MATHEMATICAL BOLD SMALL E +1D41F f # MATHEMATICAL BOLD SMALL F +1D420 g # MATHEMATICAL BOLD SMALL G +1D421 h # MATHEMATICAL BOLD SMALL H +1D422 i # MATHEMATICAL BOLD SMALL I +1D423 j # MATHEMATICAL BOLD SMALL J +1D424 k # MATHEMATICAL BOLD SMALL K +1D425 l # MATHEMATICAL BOLD SMALL L +1D426 m # MATHEMATICAL BOLD SMALL M +1D427 n # MATHEMATICAL BOLD SMALL N +1D428 o # MATHEMATICAL BOLD SMALL O +1D429 p # MATHEMATICAL BOLD SMALL P +1D42A q # MATHEMATICAL BOLD SMALL Q +1D42B r # MATHEMATICAL BOLD SMALL R +1D42C s # MATHEMATICAL BOLD SMALL S +1D42D t # MATHEMATICAL BOLD SMALL T +1D42E u # MATHEMATICAL BOLD SMALL U +1D42F v # MATHEMATICAL BOLD SMALL V +1D430 w # MATHEMATICAL BOLD SMALL W +1D431 x # MATHEMATICAL BOLD SMALL X +1D432 y # MATHEMATICAL BOLD SMALL Y +1D433 z # MATHEMATICAL BOLD SMALL Z +1D434 A # MATHEMATICAL ITALIC CAPITAL A +1D435 B # MATHEMATICAL ITALIC CAPITAL B +1D436 C # MATHEMATICAL ITALIC CAPITAL C +1D437 D # MATHEMATICAL ITALIC CAPITAL D +1D438 E # MATHEMATICAL ITALIC CAPITAL E +1D439 F # MATHEMATICAL ITALIC CAPITAL F +1D43A G # MATHEMATICAL ITALIC CAPITAL G +1D43B H # MATHEMATICAL ITALIC CAPITAL H +1D43C I # MATHEMATICAL ITALIC CAPITAL I +1D43D J # MATHEMATICAL ITALIC CAPITAL J +1D43E K # MATHEMATICAL ITALIC CAPITAL K +1D43F L # MATHEMATICAL ITALIC CAPITAL L +1D440 M # MATHEMATICAL ITALIC CAPITAL M +1D441 N # MATHEMATICAL ITALIC CAPITAL N +1D442 O # MATHEMATICAL ITALIC CAPITAL O +1D443 P # MATHEMATICAL ITALIC CAPITAL P +1D444 Q # MATHEMATICAL ITALIC CAPITAL Q +1D445 R # MATHEMATICAL ITALIC CAPITAL R +1D446 S # MATHEMATICAL ITALIC CAPITAL S +1D447 T # MATHEMATICAL ITALIC CAPITAL T +1D448 U # MATHEMATICAL ITALIC CAPITAL U +1D449 V # MATHEMATICAL ITALIC CAPITAL V +1D44A W # MATHEMATICAL ITALIC CAPITAL W +1D44B X # MATHEMATICAL ITALIC CAPITAL X +1D44C Y # MATHEMATICAL ITALIC CAPITAL Y +1D44D Z # MATHEMATICAL ITALIC CAPITAL Z +1D44E a # MATHEMATICAL ITALIC SMALL A +1D44F b # MATHEMATICAL ITALIC SMALL B +1D450 c # MATHEMATICAL ITALIC SMALL C +1D451 d # MATHEMATICAL ITALIC SMALL D +1D452 e # MATHEMATICAL ITALIC SMALL E +1D453 f # MATHEMATICAL ITALIC SMALL F +1D454 g # MATHEMATICAL ITALIC SMALL G +1D456 i # MATHEMATICAL ITALIC SMALL I +1D457 j # MATHEMATICAL ITALIC SMALL J +1D458 k # MATHEMATICAL ITALIC SMALL K +1D459 l # MATHEMATICAL ITALIC SMALL L +1D45A m # MATHEMATICAL ITALIC SMALL M +1D45B n # MATHEMATICAL ITALIC SMALL N +1D45C o # MATHEMATICAL ITALIC SMALL O +1D45D p # MATHEMATICAL ITALIC SMALL P +1D45E q # MATHEMATICAL ITALIC SMALL Q +1D45F r # MATHEMATICAL ITALIC SMALL R +1D460 s # MATHEMATICAL ITALIC SMALL S +1D461 t # MATHEMATICAL ITALIC SMALL T +1D462 u # MATHEMATICAL ITALIC SMALL U +1D463 v # MATHEMATICAL ITALIC SMALL V +1D464 w # MATHEMATICAL ITALIC SMALL W +1D465 x # MATHEMATICAL ITALIC SMALL X +1D466 y # MATHEMATICAL ITALIC SMALL Y +1D467 z # MATHEMATICAL ITALIC SMALL Z +1D468 A # MATHEMATICAL BOLD ITALIC CAPITAL A +1D469 B # MATHEMATICAL BOLD ITALIC CAPITAL B +1D46A C # MATHEMATICAL BOLD ITALIC CAPITAL C +1D46B D # MATHEMATICAL BOLD ITALIC CAPITAL D +1D46C E # MATHEMATICAL BOLD ITALIC CAPITAL E +1D46D F # MATHEMATICAL BOLD ITALIC CAPITAL F +1D46E G # MATHEMATICAL BOLD ITALIC CAPITAL G +1D46F H # MATHEMATICAL BOLD ITALIC CAPITAL H +1D470 I # MATHEMATICAL BOLD ITALIC CAPITAL I +1D471 J # MATHEMATICAL BOLD ITALIC CAPITAL J +1D472 K # MATHEMATICAL BOLD ITALIC CAPITAL K +1D473 L # MATHEMATICAL BOLD ITALIC CAPITAL L +1D474 M # MATHEMATICAL BOLD ITALIC CAPITAL M +1D475 N # MATHEMATICAL BOLD ITALIC CAPITAL N +1D476 O # MATHEMATICAL BOLD ITALIC CAPITAL O +1D477 P # MATHEMATICAL BOLD ITALIC CAPITAL P +1D478 Q # MATHEMATICAL BOLD ITALIC CAPITAL Q +1D479 R # MATHEMATICAL BOLD ITALIC CAPITAL R +1D47A S # MATHEMATICAL BOLD ITALIC CAPITAL S +1D47B T # MATHEMATICAL BOLD ITALIC CAPITAL T +1D47C U # MATHEMATICAL BOLD ITALIC CAPITAL U +1D47D V # MATHEMATICAL BOLD ITALIC CAPITAL V +1D47E W # MATHEMATICAL BOLD ITALIC CAPITAL W +1D47F X # MATHEMATICAL BOLD ITALIC CAPITAL X +1D480 Y # MATHEMATICAL BOLD ITALIC CAPITAL Y +1D481 Z # MATHEMATICAL BOLD ITALIC CAPITAL Z +1D482 a # MATHEMATICAL BOLD ITALIC SMALL A +1D483 b # MATHEMATICAL BOLD ITALIC SMALL B +1D484 c # MATHEMATICAL BOLD ITALIC SMALL C +1D485 d # MATHEMATICAL BOLD ITALIC SMALL D +1D486 e # MATHEMATICAL BOLD ITALIC SMALL E +1D487 f # MATHEMATICAL BOLD ITALIC SMALL F +1D488 g # MATHEMATICAL BOLD ITALIC SMALL G +1D489 h # MATHEMATICAL BOLD ITALIC SMALL H +1D48A i # MATHEMATICAL BOLD ITALIC SMALL I +1D48B j # MATHEMATICAL BOLD ITALIC SMALL J +1D48C k # MATHEMATICAL BOLD ITALIC SMALL K +1D48D l # MATHEMATICAL BOLD ITALIC SMALL L +1D48E m # MATHEMATICAL BOLD ITALIC SMALL M +1D48F n # MATHEMATICAL BOLD ITALIC SMALL N +1D490 o # MATHEMATICAL BOLD ITALIC SMALL O +1D491 p # MATHEMATICAL BOLD ITALIC SMALL P +1D492 q # MATHEMATICAL BOLD ITALIC SMALL Q +1D493 r # MATHEMATICAL BOLD ITALIC SMALL R +1D494 s # MATHEMATICAL BOLD ITALIC SMALL S +1D495 t # MATHEMATICAL BOLD ITALIC SMALL T +1D496 u # MATHEMATICAL BOLD ITALIC SMALL U +1D497 v # MATHEMATICAL BOLD ITALIC SMALL V +1D498 w # MATHEMATICAL BOLD ITALIC SMALL W +1D499 x # MATHEMATICAL BOLD ITALIC SMALL X +1D49A y # MATHEMATICAL BOLD ITALIC SMALL Y +1D49B z # MATHEMATICAL BOLD ITALIC SMALL Z +1D49C A # MATHEMATICAL SCRIPT CAPITAL A +1D49E C # MATHEMATICAL SCRIPT CAPITAL C +1D49F D # MATHEMATICAL SCRIPT CAPITAL D +1D4A2 G # MATHEMATICAL SCRIPT CAPITAL G +1D4A5 J # MATHEMATICAL SCRIPT CAPITAL J +1D4A6 K # MATHEMATICAL SCRIPT CAPITAL K +1D4A9 N # MATHEMATICAL SCRIPT CAPITAL N +1D4AA O # MATHEMATICAL SCRIPT CAPITAL O +1D4AB P # MATHEMATICAL SCRIPT CAPITAL P +1D4AC Q # MATHEMATICAL SCRIPT CAPITAL Q +1D4AE S # MATHEMATICAL SCRIPT CAPITAL S +1D4AF T # MATHEMATICAL SCRIPT CAPITAL T +1D4B0 U # MATHEMATICAL SCRIPT CAPITAL U +1D4B1 V # MATHEMATICAL SCRIPT CAPITAL V +1D4B2 W # MATHEMATICAL SCRIPT CAPITAL W +1D4B3 X # MATHEMATICAL SCRIPT CAPITAL X +1D4B4 Y # MATHEMATICAL SCRIPT CAPITAL Y +1D4B5 Z # MATHEMATICAL SCRIPT CAPITAL Z +1D4B6 a # MATHEMATICAL SCRIPT SMALL A +1D4B7 b # MATHEMATICAL SCRIPT SMALL B +1D4B8 c # MATHEMATICAL SCRIPT SMALL C +1D4B9 d # MATHEMATICAL SCRIPT SMALL D +1D4BB f # MATHEMATICAL SCRIPT SMALL F +1D4BD h # MATHEMATICAL SCRIPT SMALL H +1D4BE i # MATHEMATICAL SCRIPT SMALL I +1D4BF j # MATHEMATICAL SCRIPT SMALL J +1D4C0 k # MATHEMATICAL SCRIPT SMALL K +1D4C1 l # MATHEMATICAL SCRIPT SMALL L +1D4C2 m # MATHEMATICAL SCRIPT SMALL M +1D4C3 n # MATHEMATICAL SCRIPT SMALL N +1D4C5 p # MATHEMATICAL SCRIPT SMALL P +1D4C6 q # MATHEMATICAL SCRIPT SMALL Q +1D4C7 r # MATHEMATICAL SCRIPT SMALL R +1D4C8 s # MATHEMATICAL SCRIPT SMALL S +1D4C9 t # MATHEMATICAL SCRIPT SMALL T +1D4CA u # MATHEMATICAL SCRIPT SMALL U +1D4CB v # MATHEMATICAL SCRIPT SMALL V +1D4CC w # MATHEMATICAL SCRIPT SMALL W +1D4CD x # MATHEMATICAL SCRIPT SMALL X +1D4CE y # MATHEMATICAL SCRIPT SMALL Y +1D4CF z # MATHEMATICAL SCRIPT SMALL Z +1D4D0 A # MATHEMATICAL BOLD SCRIPT CAPITAL A +1D4D1 B # MATHEMATICAL BOLD SCRIPT CAPITAL B +1D4D2 C # MATHEMATICAL BOLD SCRIPT CAPITAL C +1D4D3 D # MATHEMATICAL BOLD SCRIPT CAPITAL D +1D4D4 E # MATHEMATICAL BOLD SCRIPT CAPITAL E +1D4D5 F # MATHEMATICAL BOLD SCRIPT CAPITAL F +1D4D6 G # MATHEMATICAL BOLD SCRIPT CAPITAL G +1D4D7 H # MATHEMATICAL BOLD SCRIPT CAPITAL H +1D4D8 I # MATHEMATICAL BOLD SCRIPT CAPITAL I +1D4D9 J # MATHEMATICAL BOLD SCRIPT CAPITAL J +1D4DA K # MATHEMATICAL BOLD SCRIPT CAPITAL K +1D4DB L # MATHEMATICAL BOLD SCRIPT CAPITAL L +1D4DC M # MATHEMATICAL BOLD SCRIPT CAPITAL M +1D4DD N # MATHEMATICAL BOLD SCRIPT CAPITAL N +1D4DE O # MATHEMATICAL BOLD SCRIPT CAPITAL O +1D4DF P # MATHEMATICAL BOLD SCRIPT CAPITAL P +1D4E0 Q # MATHEMATICAL BOLD SCRIPT CAPITAL Q +1D4E1 R # MATHEMATICAL BOLD SCRIPT CAPITAL R +1D4E2 S # MATHEMATICAL BOLD SCRIPT CAPITAL S +1D4E3 T # MATHEMATICAL BOLD SCRIPT CAPITAL T +1D4E4 U # MATHEMATICAL BOLD SCRIPT CAPITAL U +1D4E5 V # MATHEMATICAL BOLD SCRIPT CAPITAL V +1D4E6 W # MATHEMATICAL BOLD SCRIPT CAPITAL W +1D4E7 X # MATHEMATICAL BOLD SCRIPT CAPITAL X +1D4E8 Y # MATHEMATICAL BOLD SCRIPT CAPITAL Y +1D4E9 Z # MATHEMATICAL BOLD SCRIPT CAPITAL Z +1D4EA a # MATHEMATICAL BOLD SCRIPT SMALL A +1D4EB b # MATHEMATICAL BOLD SCRIPT SMALL B +1D4EC c # MATHEMATICAL BOLD SCRIPT SMALL C +1D4ED d # MATHEMATICAL BOLD SCRIPT SMALL D +1D4EE e # MATHEMATICAL BOLD SCRIPT SMALL E +1D4EF f # MATHEMATICAL BOLD SCRIPT SMALL F +1D4F0 g # MATHEMATICAL BOLD SCRIPT SMALL G +1D4F1 h # MATHEMATICAL BOLD SCRIPT SMALL H +1D4F2 i # MATHEMATICAL BOLD SCRIPT SMALL I +1D4F3 j # MATHEMATICAL BOLD SCRIPT SMALL J +1D4F4 k # MATHEMATICAL BOLD SCRIPT SMALL K +1D4F5 l # MATHEMATICAL BOLD SCRIPT SMALL L +1D4F6 m # MATHEMATICAL BOLD SCRIPT SMALL M +1D4F7 n # MATHEMATICAL BOLD SCRIPT SMALL N +1D4F8 o # MATHEMATICAL BOLD SCRIPT SMALL O +1D4F9 p # MATHEMATICAL BOLD SCRIPT SMALL P +1D4FA q # MATHEMATICAL BOLD SCRIPT SMALL Q +1D4FB r # MATHEMATICAL BOLD SCRIPT SMALL R +1D4FC s # MATHEMATICAL BOLD SCRIPT SMALL S +1D4FD t # MATHEMATICAL BOLD SCRIPT SMALL T +1D4FE u # MATHEMATICAL BOLD SCRIPT SMALL U +1D4FF v # MATHEMATICAL BOLD SCRIPT SMALL V +1D500 w # MATHEMATICAL BOLD SCRIPT SMALL W +1D501 x # MATHEMATICAL BOLD SCRIPT SMALL X +1D502 y # MATHEMATICAL BOLD SCRIPT SMALL Y +1D503 z # MATHEMATICAL BOLD SCRIPT SMALL Z +1D504 A # MATHEMATICAL FRAKTUR CAPITAL A +1D505 B # MATHEMATICAL FRAKTUR CAPITAL B +1D507 D # MATHEMATICAL FRAKTUR CAPITAL D +1D508 E # MATHEMATICAL FRAKTUR CAPITAL E +1D509 F # MATHEMATICAL FRAKTUR CAPITAL F +1D50A G # MATHEMATICAL FRAKTUR CAPITAL G +1D50D J # MATHEMATICAL FRAKTUR CAPITAL J +1D50E K # MATHEMATICAL FRAKTUR CAPITAL K +1D50F L # MATHEMATICAL FRAKTUR CAPITAL L +1D510 M # MATHEMATICAL FRAKTUR CAPITAL M +1D511 N # MATHEMATICAL FRAKTUR CAPITAL N +1D512 O # MATHEMATICAL FRAKTUR CAPITAL O +1D513 P # MATHEMATICAL FRAKTUR CAPITAL P +1D514 Q # MATHEMATICAL FRAKTUR CAPITAL Q +1D516 S # MATHEMATICAL FRAKTUR CAPITAL S +1D517 T # MATHEMATICAL FRAKTUR CAPITAL T +1D518 U # MATHEMATICAL FRAKTUR CAPITAL U +1D519 V # MATHEMATICAL FRAKTUR CAPITAL V +1D51A W # MATHEMATICAL FRAKTUR CAPITAL W +1D51B X # MATHEMATICAL FRAKTUR CAPITAL X +1D51C Y # MATHEMATICAL FRAKTUR CAPITAL Y +1D51E a # MATHEMATICAL FRAKTUR SMALL A +1D51F b # MATHEMATICAL FRAKTUR SMALL B +1D520 c # MATHEMATICAL FRAKTUR SMALL C +1D521 d # MATHEMATICAL FRAKTUR SMALL D +1D522 e # MATHEMATICAL FRAKTUR SMALL E +1D523 f # MATHEMATICAL FRAKTUR SMALL F +1D524 g # MATHEMATICAL FRAKTUR SMALL G +1D525 h # MATHEMATICAL FRAKTUR SMALL H +1D526 i # MATHEMATICAL FRAKTUR SMALL I +1D527 j # MATHEMATICAL FRAKTUR SMALL J +1D528 k # MATHEMATICAL FRAKTUR SMALL K +1D529 l # MATHEMATICAL FRAKTUR SMALL L +1D52A m # MATHEMATICAL FRAKTUR SMALL M +1D52B n # MATHEMATICAL FRAKTUR SMALL N +1D52C o # MATHEMATICAL FRAKTUR SMALL O +1D52D p # MATHEMATICAL FRAKTUR SMALL P +1D52E q # MATHEMATICAL FRAKTUR SMALL Q +1D52F r # MATHEMATICAL FRAKTUR SMALL R +1D530 s # MATHEMATICAL FRAKTUR SMALL S +1D531 t # MATHEMATICAL FRAKTUR SMALL T +1D532 u # MATHEMATICAL FRAKTUR SMALL U +1D533 v # MATHEMATICAL FRAKTUR SMALL V +1D534 w # MATHEMATICAL FRAKTUR SMALL W +1D535 x # MATHEMATICAL FRAKTUR SMALL X +1D536 y # MATHEMATICAL FRAKTUR SMALL Y +1D537 z # MATHEMATICAL FRAKTUR SMALL Z +1D538 A # MATHEMATICAL DOUBLE-STRUCK CAPITAL A +1D539 B # MATHEMATICAL DOUBLE-STRUCK CAPITAL B +1D53B D # MATHEMATICAL DOUBLE-STRUCK CAPITAL D +1D53C E # MATHEMATICAL DOUBLE-STRUCK CAPITAL E +1D53D F # MATHEMATICAL DOUBLE-STRUCK CAPITAL F +1D53E G # MATHEMATICAL DOUBLE-STRUCK CAPITAL G +1D540 I # MATHEMATICAL DOUBLE-STRUCK CAPITAL I +1D541 J # MATHEMATICAL DOUBLE-STRUCK CAPITAL J +1D542 K # MATHEMATICAL DOUBLE-STRUCK CAPITAL K +1D543 L # MATHEMATICAL DOUBLE-STRUCK CAPITAL L +1D544 M # MATHEMATICAL DOUBLE-STRUCK CAPITAL M +1D546 O # MATHEMATICAL DOUBLE-STRUCK CAPITAL O +1D54A S # MATHEMATICAL DOUBLE-STRUCK CAPITAL S +1D54B T # MATHEMATICAL DOUBLE-STRUCK CAPITAL T +1D54C U # MATHEMATICAL DOUBLE-STRUCK CAPITAL U +1D54D V # MATHEMATICAL DOUBLE-STRUCK CAPITAL V +1D54E W # MATHEMATICAL DOUBLE-STRUCK CAPITAL W +1D54F X # MATHEMATICAL DOUBLE-STRUCK CAPITAL X +1D550 Y # MATHEMATICAL DOUBLE-STRUCK CAPITAL Y +1D552 a # MATHEMATICAL DOUBLE-STRUCK SMALL A +1D553 b # MATHEMATICAL DOUBLE-STRUCK SMALL B +1D554 c # MATHEMATICAL DOUBLE-STRUCK SMALL C +1D555 d # MATHEMATICAL DOUBLE-STRUCK SMALL D +1D556 e # MATHEMATICAL DOUBLE-STRUCK SMALL E +1D557 f # MATHEMATICAL DOUBLE-STRUCK SMALL F +1D558 g # MATHEMATICAL DOUBLE-STRUCK SMALL G +1D559 h # MATHEMATICAL DOUBLE-STRUCK SMALL H +1D55A i # MATHEMATICAL DOUBLE-STRUCK SMALL I +1D55B j # MATHEMATICAL DOUBLE-STRUCK SMALL J +1D55C k # MATHEMATICAL DOUBLE-STRUCK SMALL K +1D55D l # MATHEMATICAL DOUBLE-STRUCK SMALL L +1D55E m # MATHEMATICAL DOUBLE-STRUCK SMALL M +1D55F n # MATHEMATICAL DOUBLE-STRUCK SMALL N +1D560 o # MATHEMATICAL DOUBLE-STRUCK SMALL O +1D561 p # MATHEMATICAL DOUBLE-STRUCK SMALL P +1D562 q # MATHEMATICAL DOUBLE-STRUCK SMALL Q +1D563 r # MATHEMATICAL DOUBLE-STRUCK SMALL R +1D564 s # MATHEMATICAL DOUBLE-STRUCK SMALL S +1D565 t # MATHEMATICAL DOUBLE-STRUCK SMALL T +1D566 u # MATHEMATICAL DOUBLE-STRUCK SMALL U +1D567 v # MATHEMATICAL DOUBLE-STRUCK SMALL V +1D568 w # MATHEMATICAL DOUBLE-STRUCK SMALL W +1D569 x # MATHEMATICAL DOUBLE-STRUCK SMALL X +1D56A y # MATHEMATICAL DOUBLE-STRUCK SMALL Y +1D56B z # MATHEMATICAL DOUBLE-STRUCK SMALL Z +1D56C A # MATHEMATICAL BOLD FRAKTUR CAPITAL A +1D56D B # MATHEMATICAL BOLD FRAKTUR CAPITAL B +1D56E C # MATHEMATICAL BOLD FRAKTUR CAPITAL C +1D56F D # MATHEMATICAL BOLD FRAKTUR CAPITAL D +1D570 E # MATHEMATICAL BOLD FRAKTUR CAPITAL E +1D571 F # MATHEMATICAL BOLD FRAKTUR CAPITAL F +1D572 G # MATHEMATICAL BOLD FRAKTUR CAPITAL G +1D573 H # MATHEMATICAL BOLD FRAKTUR CAPITAL H +1D574 I # MATHEMATICAL BOLD FRAKTUR CAPITAL I +1D575 J # MATHEMATICAL BOLD FRAKTUR CAPITAL J +1D576 K # MATHEMATICAL BOLD FRAKTUR CAPITAL K +1D577 L # MATHEMATICAL BOLD FRAKTUR CAPITAL L +1D578 M # MATHEMATICAL BOLD FRAKTUR CAPITAL M +1D579 N # MATHEMATICAL BOLD FRAKTUR CAPITAL N +1D57A O # MATHEMATICAL BOLD FRAKTUR CAPITAL O +1D57B P # MATHEMATICAL BOLD FRAKTUR CAPITAL P +1D57C Q # MATHEMATICAL BOLD FRAKTUR CAPITAL Q +1D57D R # MATHEMATICAL BOLD FRAKTUR CAPITAL R +1D57E S # MATHEMATICAL BOLD FRAKTUR CAPITAL S +1D57F T # MATHEMATICAL BOLD FRAKTUR CAPITAL T +1D580 U # MATHEMATICAL BOLD FRAKTUR CAPITAL U +1D581 V # MATHEMATICAL BOLD FRAKTUR CAPITAL V +1D582 W # MATHEMATICAL BOLD FRAKTUR CAPITAL W +1D583 X # MATHEMATICAL BOLD FRAKTUR CAPITAL X +1D584 Y # MATHEMATICAL BOLD FRAKTUR CAPITAL Y +1D585 Z # MATHEMATICAL BOLD FRAKTUR CAPITAL Z +1D586 a # MATHEMATICAL BOLD FRAKTUR SMALL A +1D587 b # MATHEMATICAL BOLD FRAKTUR SMALL B +1D588 c # MATHEMATICAL BOLD FRAKTUR SMALL C +1D589 d # MATHEMATICAL BOLD FRAKTUR SMALL D +1D58A e # MATHEMATICAL BOLD FRAKTUR SMALL E +1D58B f # MATHEMATICAL BOLD FRAKTUR SMALL F +1D58C g # MATHEMATICAL BOLD FRAKTUR SMALL G +1D58D h # MATHEMATICAL BOLD FRAKTUR SMALL H +1D58E i # MATHEMATICAL BOLD FRAKTUR SMALL I +1D58F j # MATHEMATICAL BOLD FRAKTUR SMALL J +1D590 k # MATHEMATICAL BOLD FRAKTUR SMALL K +1D591 l # MATHEMATICAL BOLD FRAKTUR SMALL L +1D592 m # MATHEMATICAL BOLD FRAKTUR SMALL M +1D593 n # MATHEMATICAL BOLD FRAKTUR SMALL N +1D594 o # MATHEMATICAL BOLD FRAKTUR SMALL O +1D595 p # MATHEMATICAL BOLD FRAKTUR SMALL P +1D596 q # MATHEMATICAL BOLD FRAKTUR SMALL Q +1D597 r # MATHEMATICAL BOLD FRAKTUR SMALL R +1D598 s # MATHEMATICAL BOLD FRAKTUR SMALL S +1D599 t # MATHEMATICAL BOLD FRAKTUR SMALL T +1D59A u # MATHEMATICAL BOLD FRAKTUR SMALL U +1D59B v # MATHEMATICAL BOLD FRAKTUR SMALL V +1D59C w # MATHEMATICAL BOLD FRAKTUR SMALL W +1D59D x # MATHEMATICAL BOLD FRAKTUR SMALL X +1D59E y # MATHEMATICAL BOLD FRAKTUR SMALL Y +1D59F z # MATHEMATICAL BOLD FRAKTUR SMALL Z +1D5A0 A # MATHEMATICAL SANS-SERIF CAPITAL A +1D5A1 B # MATHEMATICAL SANS-SERIF CAPITAL B +1D5A2 C # MATHEMATICAL SANS-SERIF CAPITAL C +1D5A3 D # MATHEMATICAL SANS-SERIF CAPITAL D +1D5A4 E # MATHEMATICAL SANS-SERIF CAPITAL E +1D5A5 F # MATHEMATICAL SANS-SERIF CAPITAL F +1D5A6 G # MATHEMATICAL SANS-SERIF CAPITAL G +1D5A7 H # MATHEMATICAL SANS-SERIF CAPITAL H +1D5A8 I # MATHEMATICAL SANS-SERIF CAPITAL I +1D5A9 J # MATHEMATICAL SANS-SERIF CAPITAL J +1D5AA K # MATHEMATICAL SANS-SERIF CAPITAL K +1D5AB L # MATHEMATICAL SANS-SERIF CAPITAL L +1D5AC M # MATHEMATICAL SANS-SERIF CAPITAL M +1D5AD N # MATHEMATICAL SANS-SERIF CAPITAL N +1D5AE O # MATHEMATICAL SANS-SERIF CAPITAL O +1D5AF P # MATHEMATICAL SANS-SERIF CAPITAL P +1D5B0 Q # MATHEMATICAL SANS-SERIF CAPITAL Q +1D5B1 R # MATHEMATICAL SANS-SERIF CAPITAL R +1D5B2 S # MATHEMATICAL SANS-SERIF CAPITAL S +1D5B3 T # MATHEMATICAL SANS-SERIF CAPITAL T +1D5B4 U # MATHEMATICAL SANS-SERIF CAPITAL U +1D5B5 V # MATHEMATICAL SANS-SERIF CAPITAL V +1D5B6 W # MATHEMATICAL SANS-SERIF CAPITAL W +1D5B7 X # MATHEMATICAL SANS-SERIF CAPITAL X +1D5B8 Y # MATHEMATICAL SANS-SERIF CAPITAL Y +1D5B9 Z # MATHEMATICAL SANS-SERIF CAPITAL Z +1D5BA a # MATHEMATICAL SANS-SERIF SMALL A +1D5BB b # MATHEMATICAL SANS-SERIF SMALL B +1D5BC c # MATHEMATICAL SANS-SERIF SMALL C +1D5BD d # MATHEMATICAL SANS-SERIF SMALL D +1D5BE e # MATHEMATICAL SANS-SERIF SMALL E +1D5BF f # MATHEMATICAL SANS-SERIF SMALL F +1D5C0 g # MATHEMATICAL SANS-SERIF SMALL G +1D5C1 h # MATHEMATICAL SANS-SERIF SMALL H +1D5C2 i # MATHEMATICAL SANS-SERIF SMALL I +1D5C3 j # MATHEMATICAL SANS-SERIF SMALL J +1D5C4 k # MATHEMATICAL SANS-SERIF SMALL K +1D5C5 l # MATHEMATICAL SANS-SERIF SMALL L +1D5C6 m # MATHEMATICAL SANS-SERIF SMALL M +1D5C7 n # MATHEMATICAL SANS-SERIF SMALL N +1D5C8 o # MATHEMATICAL SANS-SERIF SMALL O +1D5C9 p # MATHEMATICAL SANS-SERIF SMALL P +1D5CA q # MATHEMATICAL SANS-SERIF SMALL Q +1D5CB r # MATHEMATICAL SANS-SERIF SMALL R +1D5CC s # MATHEMATICAL SANS-SERIF SMALL S +1D5CD t # MATHEMATICAL SANS-SERIF SMALL T +1D5CE u # MATHEMATICAL SANS-SERIF SMALL U +1D5CF v # MATHEMATICAL SANS-SERIF SMALL V +1D5D0 w # MATHEMATICAL SANS-SERIF SMALL W +1D5D1 x # MATHEMATICAL SANS-SERIF SMALL X +1D5D2 y # MATHEMATICAL SANS-SERIF SMALL Y +1D5D3 z # MATHEMATICAL SANS-SERIF SMALL Z +1D5D4 A # MATHEMATICAL SANS-SERIF BOLD CAPITAL A +1D5D5 B # MATHEMATICAL SANS-SERIF BOLD CAPITAL B +1D5D6 C # MATHEMATICAL SANS-SERIF BOLD CAPITAL C +1D5D7 D # MATHEMATICAL SANS-SERIF BOLD CAPITAL D +1D5D8 E # MATHEMATICAL SANS-SERIF BOLD CAPITAL E +1D5D9 F # MATHEMATICAL SANS-SERIF BOLD CAPITAL F +1D5DA G # MATHEMATICAL SANS-SERIF BOLD CAPITAL G +1D5DB H # MATHEMATICAL SANS-SERIF BOLD CAPITAL H +1D5DC I # MATHEMATICAL SANS-SERIF BOLD CAPITAL I +1D5DD J # MATHEMATICAL SANS-SERIF BOLD CAPITAL J +1D5DE K # MATHEMATICAL SANS-SERIF BOLD CAPITAL K +1D5DF L # MATHEMATICAL SANS-SERIF BOLD CAPITAL L +1D5E0 M # MATHEMATICAL SANS-SERIF BOLD CAPITAL M +1D5E1 N # MATHEMATICAL SANS-SERIF BOLD CAPITAL N +1D5E2 O # MATHEMATICAL SANS-SERIF BOLD CAPITAL O +1D5E3 P # MATHEMATICAL SANS-SERIF BOLD CAPITAL P +1D5E4 Q # MATHEMATICAL SANS-SERIF BOLD CAPITAL Q +1D5E5 R # MATHEMATICAL SANS-SERIF BOLD CAPITAL R +1D5E6 S # MATHEMATICAL SANS-SERIF BOLD CAPITAL S +1D5E7 T # MATHEMATICAL SANS-SERIF BOLD CAPITAL T +1D5E8 U # MATHEMATICAL SANS-SERIF BOLD CAPITAL U +1D5E9 V # MATHEMATICAL SANS-SERIF BOLD CAPITAL V +1D5EA W # MATHEMATICAL SANS-SERIF BOLD CAPITAL W +1D5EB X # MATHEMATICAL SANS-SERIF BOLD CAPITAL X +1D5EC Y # MATHEMATICAL SANS-SERIF BOLD CAPITAL Y +1D5ED Z # MATHEMATICAL SANS-SERIF BOLD CAPITAL Z +1D5EE a # MATHEMATICAL SANS-SERIF BOLD SMALL A +1D5EF b # MATHEMATICAL SANS-SERIF BOLD SMALL B +1D5F0 c # MATHEMATICAL SANS-SERIF BOLD SMALL C +1D5F1 d # MATHEMATICAL SANS-SERIF BOLD SMALL D +1D5F2 e # MATHEMATICAL SANS-SERIF BOLD SMALL E +1D5F3 f # MATHEMATICAL SANS-SERIF BOLD SMALL F +1D5F4 g # MATHEMATICAL SANS-SERIF BOLD SMALL G +1D5F5 h # MATHEMATICAL SANS-SERIF BOLD SMALL H +1D5F6 i # MATHEMATICAL SANS-SERIF BOLD SMALL I +1D5F7 j # MATHEMATICAL SANS-SERIF BOLD SMALL J +1D5F8 k # MATHEMATICAL SANS-SERIF BOLD SMALL K +1D5F9 l # MATHEMATICAL SANS-SERIF BOLD SMALL L +1D5FA m # MATHEMATICAL SANS-SERIF BOLD SMALL M +1D5FB n # MATHEMATICAL SANS-SERIF BOLD SMALL N +1D5FC o # MATHEMATICAL SANS-SERIF BOLD SMALL O +1D5FD p # MATHEMATICAL SANS-SERIF BOLD SMALL P +1D5FE q # MATHEMATICAL SANS-SERIF BOLD SMALL Q +1D5FF r # MATHEMATICAL SANS-SERIF BOLD SMALL R +1D600 s # MATHEMATICAL SANS-SERIF BOLD SMALL S +1D601 t # MATHEMATICAL SANS-SERIF BOLD SMALL T +1D602 u # MATHEMATICAL SANS-SERIF BOLD SMALL U +1D603 v # MATHEMATICAL SANS-SERIF BOLD SMALL V +1D604 w # MATHEMATICAL SANS-SERIF BOLD SMALL W +1D605 x # MATHEMATICAL SANS-SERIF BOLD SMALL X +1D606 y # MATHEMATICAL SANS-SERIF BOLD SMALL Y +1D607 z # MATHEMATICAL SANS-SERIF BOLD SMALL Z +1D608 A # MATHEMATICAL SANS-SERIF ITALIC CAPITAL A +1D609 B # MATHEMATICAL SANS-SERIF ITALIC CAPITAL B +1D60A C # MATHEMATICAL SANS-SERIF ITALIC CAPITAL C +1D60B D # MATHEMATICAL SANS-SERIF ITALIC CAPITAL D +1D60C E # MATHEMATICAL SANS-SERIF ITALIC CAPITAL E +1D60D F # MATHEMATICAL SANS-SERIF ITALIC CAPITAL F +1D60E G # MATHEMATICAL SANS-SERIF ITALIC CAPITAL G +1D60F H # MATHEMATICAL SANS-SERIF ITALIC CAPITAL H +1D610 I # MATHEMATICAL SANS-SERIF ITALIC CAPITAL I +1D611 J # MATHEMATICAL SANS-SERIF ITALIC CAPITAL J +1D612 K # MATHEMATICAL SANS-SERIF ITALIC CAPITAL K +1D613 L # MATHEMATICAL SANS-SERIF ITALIC CAPITAL L +1D614 M # MATHEMATICAL SANS-SERIF ITALIC CAPITAL M +1D615 N # MATHEMATICAL SANS-SERIF ITALIC CAPITAL N +1D616 O # MATHEMATICAL SANS-SERIF ITALIC CAPITAL O +1D617 P # MATHEMATICAL SANS-SERIF ITALIC CAPITAL P +1D618 Q # MATHEMATICAL SANS-SERIF ITALIC CAPITAL Q +1D619 R # MATHEMATICAL SANS-SERIF ITALIC CAPITAL R +1D61A S # MATHEMATICAL SANS-SERIF ITALIC CAPITAL S +1D61B T # MATHEMATICAL SANS-SERIF ITALIC CAPITAL T +1D61C U # MATHEMATICAL SANS-SERIF ITALIC CAPITAL U +1D61D V # MATHEMATICAL SANS-SERIF ITALIC CAPITAL V +1D61E W # MATHEMATICAL SANS-SERIF ITALIC CAPITAL W +1D61F X # MATHEMATICAL SANS-SERIF ITALIC CAPITAL X +1D620 Y # MATHEMATICAL SANS-SERIF ITALIC CAPITAL Y +1D621 Z # MATHEMATICAL SANS-SERIF ITALIC CAPITAL Z +1D622 a # MATHEMATICAL SANS-SERIF ITALIC SMALL A +1D623 b # MATHEMATICAL SANS-SERIF ITALIC SMALL B +1D624 c # MATHEMATICAL SANS-SERIF ITALIC SMALL C +1D625 d # MATHEMATICAL SANS-SERIF ITALIC SMALL D +1D626 e # MATHEMATICAL SANS-SERIF ITALIC SMALL E +1D627 f # MATHEMATICAL SANS-SERIF ITALIC SMALL F +1D628 g # MATHEMATICAL SANS-SERIF ITALIC SMALL G +1D629 h # MATHEMATICAL SANS-SERIF ITALIC SMALL H +1D62A i # MATHEMATICAL SANS-SERIF ITALIC SMALL I +1D62B j # MATHEMATICAL SANS-SERIF ITALIC SMALL J +1D62C k # MATHEMATICAL SANS-SERIF ITALIC SMALL K +1D62D l # MATHEMATICAL SANS-SERIF ITALIC SMALL L +1D62E m # MATHEMATICAL SANS-SERIF ITALIC SMALL M +1D62F n # MATHEMATICAL SANS-SERIF ITALIC SMALL N +1D630 o # MATHEMATICAL SANS-SERIF ITALIC SMALL O +1D631 p # MATHEMATICAL SANS-SERIF ITALIC SMALL P +1D632 q # MATHEMATICAL SANS-SERIF ITALIC SMALL Q +1D633 r # MATHEMATICAL SANS-SERIF ITALIC SMALL R +1D634 s # MATHEMATICAL SANS-SERIF ITALIC SMALL S +1D635 t # MATHEMATICAL SANS-SERIF ITALIC SMALL T +1D636 u # MATHEMATICAL SANS-SERIF ITALIC SMALL U +1D637 v # MATHEMATICAL SANS-SERIF ITALIC SMALL V +1D638 w # MATHEMATICAL SANS-SERIF ITALIC SMALL W +1D639 x # MATHEMATICAL SANS-SERIF ITALIC SMALL X +1D63A y # MATHEMATICAL SANS-SERIF ITALIC SMALL Y +1D63B z # MATHEMATICAL SANS-SERIF ITALIC SMALL Z +1D63C A # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL A +1D63D B # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL B +1D63E C # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL C +1D63F D # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL D +1D640 E # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL E +1D641 F # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL F +1D642 G # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL G +1D643 H # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL H +1D644 I # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL I +1D645 J # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL J +1D646 K # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL K +1D647 L # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL L +1D648 M # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL M +1D649 N # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL N +1D64A O # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL O +1D64B P # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL P +1D64C Q # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Q +1D64D R # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL R +1D64E S # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL S +1D64F T # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL T +1D650 U # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL U +1D651 V # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL V +1D652 W # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL W +1D653 X # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL X +1D654 Y # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Y +1D655 Z # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL Z +1D656 a # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL A +1D657 b # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL B +1D658 c # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL C +1D659 d # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL D +1D65A e # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL E +1D65B f # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL F +1D65C g # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL G +1D65D h # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL H +1D65E i # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL I +1D65F j # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL J +1D660 k # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL K +1D661 l # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL L +1D662 m # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL M +1D663 n # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL N +1D664 o # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL O +1D665 p # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL P +1D666 q # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Q +1D667 r # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL R +1D668 s # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL S +1D669 t # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL T +1D66A u # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL U +1D66B v # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL V +1D66C w # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL W +1D66D x # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL X +1D66E y # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Y +1D66F z # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL Z +1D670 A # MATHEMATICAL MONOSPACE CAPITAL A +1D671 B # MATHEMATICAL MONOSPACE CAPITAL B +1D672 C # MATHEMATICAL MONOSPACE CAPITAL C +1D673 D # MATHEMATICAL MONOSPACE CAPITAL D +1D674 E # MATHEMATICAL MONOSPACE CAPITAL E +1D675 F # MATHEMATICAL MONOSPACE CAPITAL F +1D676 G # MATHEMATICAL MONOSPACE CAPITAL G +1D677 H # MATHEMATICAL MONOSPACE CAPITAL H +1D678 I # MATHEMATICAL MONOSPACE CAPITAL I +1D679 J # MATHEMATICAL MONOSPACE CAPITAL J +1D67A K # MATHEMATICAL MONOSPACE CAPITAL K +1D67B L # MATHEMATICAL MONOSPACE CAPITAL L +1D67C M # MATHEMATICAL MONOSPACE CAPITAL M +1D67D N # MATHEMATICAL MONOSPACE CAPITAL N +1D67E O # MATHEMATICAL MONOSPACE CAPITAL O +1D67F P # MATHEMATICAL MONOSPACE CAPITAL P +1D680 Q # MATHEMATICAL MONOSPACE CAPITAL Q +1D681 R # MATHEMATICAL MONOSPACE CAPITAL R +1D682 S # MATHEMATICAL MONOSPACE CAPITAL S +1D683 T # MATHEMATICAL MONOSPACE CAPITAL T +1D684 U # MATHEMATICAL MONOSPACE CAPITAL U +1D685 V # MATHEMATICAL MONOSPACE CAPITAL V +1D686 W # MATHEMATICAL MONOSPACE CAPITAL W +1D687 X # MATHEMATICAL MONOSPACE CAPITAL X +1D688 Y # MATHEMATICAL MONOSPACE CAPITAL Y +1D689 Z # MATHEMATICAL MONOSPACE CAPITAL Z +1D68A a # MATHEMATICAL MONOSPACE SMALL A +1D68B b # MATHEMATICAL MONOSPACE SMALL B +1D68C c # MATHEMATICAL MONOSPACE SMALL C +1D68D d # MATHEMATICAL MONOSPACE SMALL D +1D68E e # MATHEMATICAL MONOSPACE SMALL E +1D68F f # MATHEMATICAL MONOSPACE SMALL F +1D690 g # MATHEMATICAL MONOSPACE SMALL G +1D691 h # MATHEMATICAL MONOSPACE SMALL H +1D692 i # MATHEMATICAL MONOSPACE SMALL I +1D693 j # MATHEMATICAL MONOSPACE SMALL J +1D694 k # MATHEMATICAL MONOSPACE SMALL K +1D695 l # MATHEMATICAL MONOSPACE SMALL L +1D696 m # MATHEMATICAL MONOSPACE SMALL M +1D697 n # MATHEMATICAL MONOSPACE SMALL N +1D698 o # MATHEMATICAL MONOSPACE SMALL O +1D699 p # MATHEMATICAL MONOSPACE SMALL P +1D69A q # MATHEMATICAL MONOSPACE SMALL Q +1D69B r # MATHEMATICAL MONOSPACE SMALL R +1D69C s # MATHEMATICAL MONOSPACE SMALL S +1D69D t # MATHEMATICAL MONOSPACE SMALL T +1D69E u # MATHEMATICAL MONOSPACE SMALL U +1D69F v # MATHEMATICAL MONOSPACE SMALL V +1D6A0 w # MATHEMATICAL MONOSPACE SMALL W +1D6A1 x # MATHEMATICAL MONOSPACE SMALL X +1D6A2 y # MATHEMATICAL MONOSPACE SMALL Y +1D6A3 z # MATHEMATICAL MONOSPACE SMALL Z +1D6A8 Α # MATHEMATICAL BOLD CAPITAL ALPHA +1D6A9 Î’ # MATHEMATICAL BOLD CAPITAL BETA +1D6AA Γ # MATHEMATICAL BOLD CAPITAL GAMMA +1D6AB Δ # MATHEMATICAL BOLD CAPITAL DELTA +1D6AC Ε # MATHEMATICAL BOLD CAPITAL EPSILON +1D6AD Ζ # MATHEMATICAL BOLD CAPITAL ZETA +1D6AE Η # MATHEMATICAL BOLD CAPITAL ETA +1D6AF Θ # MATHEMATICAL BOLD CAPITAL THETA +1D6B0 Ι # MATHEMATICAL BOLD CAPITAL IOTA +1D6B1 Κ # MATHEMATICAL BOLD CAPITAL KAPPA +1D6B2 Λ # MATHEMATICAL BOLD CAPITAL LAMDA +1D6B3 Μ # MATHEMATICAL BOLD CAPITAL MU +1D6B4 Î # MATHEMATICAL BOLD CAPITAL NU +1D6B5 Ξ # MATHEMATICAL BOLD CAPITAL XI +1D6B6 Ο # MATHEMATICAL BOLD CAPITAL OMICRON +1D6B7 Π # MATHEMATICAL BOLD CAPITAL PI +1D6B8 Ρ # MATHEMATICAL BOLD CAPITAL RHO +1D6B9 Ï´ # MATHEMATICAL BOLD CAPITAL THETA SYMBOL +1D6BA Σ # MATHEMATICAL BOLD CAPITAL SIGMA +1D6BB Τ # MATHEMATICAL BOLD CAPITAL TAU +1D6BC Î¥ # MATHEMATICAL BOLD CAPITAL UPSILON +1D6BD Φ # MATHEMATICAL BOLD CAPITAL PHI +1D6BE Χ # MATHEMATICAL BOLD CAPITAL CHI +1D6BF Ψ # MATHEMATICAL BOLD CAPITAL PSI +1D6C0 Ω # MATHEMATICAL BOLD CAPITAL OMEGA +1D6C1 ∇ # MATHEMATICAL BOLD NABLA +1D6C2 α # MATHEMATICAL BOLD SMALL ALPHA +1D6C3 β # MATHEMATICAL BOLD SMALL BETA +1D6C4 γ # MATHEMATICAL BOLD SMALL GAMMA +1D6C5 δ # MATHEMATICAL BOLD SMALL DELTA +1D6C6 ε # MATHEMATICAL BOLD SMALL EPSILON +1D6C7 ζ # MATHEMATICAL BOLD SMALL ZETA +1D6C8 η # MATHEMATICAL BOLD SMALL ETA +1D6C9 θ # MATHEMATICAL BOLD SMALL THETA +1D6CA ι # MATHEMATICAL BOLD SMALL IOTA +1D6CB κ # MATHEMATICAL BOLD SMALL KAPPA +1D6CC λ # MATHEMATICAL BOLD SMALL LAMDA +1D6CD μ # MATHEMATICAL BOLD SMALL MU +1D6CE ν # MATHEMATICAL BOLD SMALL NU +1D6CF ξ # MATHEMATICAL BOLD SMALL XI +1D6D0 ο # MATHEMATICAL BOLD SMALL OMICRON +1D6D1 Ï€ # MATHEMATICAL BOLD SMALL PI +1D6D2 Ï # MATHEMATICAL BOLD SMALL RHO +1D6D3 Ï‚ # MATHEMATICAL BOLD SMALL FINAL SIGMA +1D6D4 σ # MATHEMATICAL BOLD SMALL SIGMA +1D6D5 Ï„ # MATHEMATICAL BOLD SMALL TAU +1D6D6 Ï… # MATHEMATICAL BOLD SMALL UPSILON +1D6D7 φ # MATHEMATICAL BOLD SMALL PHI +1D6D8 χ # MATHEMATICAL BOLD SMALL CHI +1D6D9 ψ # MATHEMATICAL BOLD SMALL PSI +1D6DA ω # MATHEMATICAL BOLD SMALL OMEGA +1D6DB ∂ # MATHEMATICAL BOLD PARTIAL DIFFERENTIAL +1D6DC ϵ # MATHEMATICAL BOLD EPSILON SYMBOL +1D6DD Ï‘ # MATHEMATICAL BOLD THETA SYMBOL +1D6DE ϰ # MATHEMATICAL BOLD KAPPA SYMBOL +1D6DF Ï• # MATHEMATICAL BOLD PHI SYMBOL +1D6E0 ϱ # MATHEMATICAL BOLD RHO SYMBOL +1D6E1 Ï– # MATHEMATICAL BOLD PI SYMBOL +1D6E2 Α # MATHEMATICAL ITALIC CAPITAL ALPHA +1D6E3 Î’ # MATHEMATICAL ITALIC CAPITAL BETA +1D6E4 Γ # MATHEMATICAL ITALIC CAPITAL GAMMA +1D6E5 Δ # MATHEMATICAL ITALIC CAPITAL DELTA +1D6E6 Ε # MATHEMATICAL ITALIC CAPITAL EPSILON +1D6E7 Ζ # MATHEMATICAL ITALIC CAPITAL ZETA +1D6E8 Η # MATHEMATICAL ITALIC CAPITAL ETA +1D6E9 Θ # MATHEMATICAL ITALIC CAPITAL THETA +1D6EA Ι # MATHEMATICAL ITALIC CAPITAL IOTA +1D6EB Κ # MATHEMATICAL ITALIC CAPITAL KAPPA +1D6EC Λ # MATHEMATICAL ITALIC CAPITAL LAMDA +1D6ED Μ # MATHEMATICAL ITALIC CAPITAL MU +1D6EE Î # MATHEMATICAL ITALIC CAPITAL NU +1D6EF Ξ # MATHEMATICAL ITALIC CAPITAL XI +1D6F0 Ο # MATHEMATICAL ITALIC CAPITAL OMICRON +1D6F1 Π # MATHEMATICAL ITALIC CAPITAL PI +1D6F2 Ρ # MATHEMATICAL ITALIC CAPITAL RHO +1D6F3 Ï´ # MATHEMATICAL ITALIC CAPITAL THETA SYMBOL +1D6F4 Σ # MATHEMATICAL ITALIC CAPITAL SIGMA +1D6F5 Τ # MATHEMATICAL ITALIC CAPITAL TAU +1D6F6 Î¥ # MATHEMATICAL ITALIC CAPITAL UPSILON +1D6F7 Φ # MATHEMATICAL ITALIC CAPITAL PHI +1D6F8 Χ # MATHEMATICAL ITALIC CAPITAL CHI +1D6F9 Ψ # MATHEMATICAL ITALIC CAPITAL PSI +1D6FA Ω # MATHEMATICAL ITALIC CAPITAL OMEGA +1D6FB ∇ # MATHEMATICAL ITALIC NABLA +1D6FC α # MATHEMATICAL ITALIC SMALL ALPHA +1D6FD β # MATHEMATICAL ITALIC SMALL BETA +1D6FE γ # MATHEMATICAL ITALIC SMALL GAMMA +1D6FF δ # MATHEMATICAL ITALIC SMALL DELTA +1D700 ε # MATHEMATICAL ITALIC SMALL EPSILON +1D701 ζ # MATHEMATICAL ITALIC SMALL ZETA +1D702 η # MATHEMATICAL ITALIC SMALL ETA +1D703 θ # MATHEMATICAL ITALIC SMALL THETA +1D704 ι # MATHEMATICAL ITALIC SMALL IOTA +1D705 κ # MATHEMATICAL ITALIC SMALL KAPPA +1D706 λ # MATHEMATICAL ITALIC SMALL LAMDA +1D707 μ # MATHEMATICAL ITALIC SMALL MU +1D708 ν # MATHEMATICAL ITALIC SMALL NU +1D709 ξ # MATHEMATICAL ITALIC SMALL XI +1D70A ο # MATHEMATICAL ITALIC SMALL OMICRON +1D70B Ï€ # MATHEMATICAL ITALIC SMALL PI +1D70C Ï # MATHEMATICAL ITALIC SMALL RHO +1D70D Ï‚ # MATHEMATICAL ITALIC SMALL FINAL SIGMA +1D70E σ # MATHEMATICAL ITALIC SMALL SIGMA +1D70F Ï„ # MATHEMATICAL ITALIC SMALL TAU +1D710 Ï… # MATHEMATICAL ITALIC SMALL UPSILON +1D711 φ # MATHEMATICAL ITALIC SMALL PHI +1D712 χ # MATHEMATICAL ITALIC SMALL CHI +1D713 ψ # MATHEMATICAL ITALIC SMALL PSI +1D714 ω # MATHEMATICAL ITALIC SMALL OMEGA +1D715 ∂ # MATHEMATICAL ITALIC PARTIAL DIFFERENTIAL +1D716 ϵ # MATHEMATICAL ITALIC EPSILON SYMBOL +1D717 Ï‘ # MATHEMATICAL ITALIC THETA SYMBOL +1D718 ϰ # MATHEMATICAL ITALIC KAPPA SYMBOL +1D719 Ï• # MATHEMATICAL ITALIC PHI SYMBOL +1D71A ϱ # MATHEMATICAL ITALIC RHO SYMBOL +1D71B Ï– # MATHEMATICAL ITALIC PI SYMBOL +1D71C Α # MATHEMATICAL BOLD ITALIC CAPITAL ALPHA +1D71D Î’ # MATHEMATICAL BOLD ITALIC CAPITAL BETA +1D71E Γ # MATHEMATICAL BOLD ITALIC CAPITAL GAMMA +1D71F Δ # MATHEMATICAL BOLD ITALIC CAPITAL DELTA +1D720 Ε # MATHEMATICAL BOLD ITALIC CAPITAL EPSILON +1D721 Ζ # MATHEMATICAL BOLD ITALIC CAPITAL ZETA +1D722 Η # MATHEMATICAL BOLD ITALIC CAPITAL ETA +1D723 Θ # MATHEMATICAL BOLD ITALIC CAPITAL THETA +1D724 Ι # MATHEMATICAL BOLD ITALIC CAPITAL IOTA +1D725 Κ # MATHEMATICAL BOLD ITALIC CAPITAL KAPPA +1D726 Λ # MATHEMATICAL BOLD ITALIC CAPITAL LAMDA +1D727 Μ # MATHEMATICAL BOLD ITALIC CAPITAL MU +1D728 Î # MATHEMATICAL BOLD ITALIC CAPITAL NU +1D729 Ξ # MATHEMATICAL BOLD ITALIC CAPITAL XI +1D72A Ο # MATHEMATICAL BOLD ITALIC CAPITAL OMICRON +1D72B Π # MATHEMATICAL BOLD ITALIC CAPITAL PI +1D72C Ρ # MATHEMATICAL BOLD ITALIC CAPITAL RHO +1D72D Ï´ # MATHEMATICAL BOLD ITALIC CAPITAL THETA SYMBOL +1D72E Σ # MATHEMATICAL BOLD ITALIC CAPITAL SIGMA +1D72F Τ # MATHEMATICAL BOLD ITALIC CAPITAL TAU +1D730 Î¥ # MATHEMATICAL BOLD ITALIC CAPITAL UPSILON +1D731 Φ # MATHEMATICAL BOLD ITALIC CAPITAL PHI +1D732 Χ # MATHEMATICAL BOLD ITALIC CAPITAL CHI +1D733 Ψ # MATHEMATICAL BOLD ITALIC CAPITAL PSI +1D734 Ω # MATHEMATICAL BOLD ITALIC CAPITAL OMEGA +1D735 ∇ # MATHEMATICAL BOLD ITALIC NABLA +1D736 α # MATHEMATICAL BOLD ITALIC SMALL ALPHA +1D737 β # MATHEMATICAL BOLD ITALIC SMALL BETA +1D738 γ # MATHEMATICAL BOLD ITALIC SMALL GAMMA +1D739 δ # MATHEMATICAL BOLD ITALIC SMALL DELTA +1D73A ε # MATHEMATICAL BOLD ITALIC SMALL EPSILON +1D73B ζ # MATHEMATICAL BOLD ITALIC SMALL ZETA +1D73C η # MATHEMATICAL BOLD ITALIC SMALL ETA +1D73D θ # MATHEMATICAL BOLD ITALIC SMALL THETA +1D73E ι # MATHEMATICAL BOLD ITALIC SMALL IOTA +1D73F κ # MATHEMATICAL BOLD ITALIC SMALL KAPPA +1D740 λ # MATHEMATICAL BOLD ITALIC SMALL LAMDA +1D741 μ # MATHEMATICAL BOLD ITALIC SMALL MU +1D742 ν # MATHEMATICAL BOLD ITALIC SMALL NU +1D743 ξ # MATHEMATICAL BOLD ITALIC SMALL XI +1D744 ο # MATHEMATICAL BOLD ITALIC SMALL OMICRON +1D745 Ï€ # MATHEMATICAL BOLD ITALIC SMALL PI +1D746 Ï # MATHEMATICAL BOLD ITALIC SMALL RHO +1D747 Ï‚ # MATHEMATICAL BOLD ITALIC SMALL FINAL SIGMA +1D748 σ # MATHEMATICAL BOLD ITALIC SMALL SIGMA +1D749 Ï„ # MATHEMATICAL BOLD ITALIC SMALL TAU +1D74A Ï… # MATHEMATICAL BOLD ITALIC SMALL UPSILON +1D74B φ # MATHEMATICAL BOLD ITALIC SMALL PHI +1D74C χ # MATHEMATICAL BOLD ITALIC SMALL CHI +1D74D ψ # MATHEMATICAL BOLD ITALIC SMALL PSI +1D74E ω # MATHEMATICAL BOLD ITALIC SMALL OMEGA +1D74F ∂ # MATHEMATICAL BOLD ITALIC PARTIAL DIFFERENTIAL +1D750 ϵ # MATHEMATICAL BOLD ITALIC EPSILON SYMBOL +1D751 Ï‘ # MATHEMATICAL BOLD ITALIC THETA SYMBOL +1D752 ϰ # MATHEMATICAL BOLD ITALIC KAPPA SYMBOL +1D753 Ï• # MATHEMATICAL BOLD ITALIC PHI SYMBOL +1D754 ϱ # MATHEMATICAL BOLD ITALIC RHO SYMBOL +1D755 Ï– # MATHEMATICAL BOLD ITALIC PI SYMBOL +1D756 Α # MATHEMATICAL SANS-SERIF BOLD CAPITAL ALPHA +1D757 Î’ # MATHEMATICAL SANS-SERIF BOLD CAPITAL BETA +1D758 Γ # MATHEMATICAL SANS-SERIF BOLD CAPITAL GAMMA +1D759 Δ # MATHEMATICAL SANS-SERIF BOLD CAPITAL DELTA +1D75A Ε # MATHEMATICAL SANS-SERIF BOLD CAPITAL EPSILON +1D75B Ζ # MATHEMATICAL SANS-SERIF BOLD CAPITAL ZETA +1D75C Η # MATHEMATICAL SANS-SERIF BOLD CAPITAL ETA +1D75D Θ # MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA +1D75E Ι # MATHEMATICAL SANS-SERIF BOLD CAPITAL IOTA +1D75F Κ # MATHEMATICAL SANS-SERIF BOLD CAPITAL KAPPA +1D760 Λ # MATHEMATICAL SANS-SERIF BOLD CAPITAL LAMDA +1D761 Μ # MATHEMATICAL SANS-SERIF BOLD CAPITAL MU +1D762 Î # MATHEMATICAL SANS-SERIF BOLD CAPITAL NU +1D763 Ξ # MATHEMATICAL SANS-SERIF BOLD CAPITAL XI +1D764 Ο # MATHEMATICAL SANS-SERIF BOLD CAPITAL OMICRON +1D765 Π # MATHEMATICAL SANS-SERIF BOLD CAPITAL PI +1D766 Ρ # MATHEMATICAL SANS-SERIF BOLD CAPITAL RHO +1D767 Ï´ # MATHEMATICAL SANS-SERIF BOLD CAPITAL THETA SYMBOL +1D768 Σ # MATHEMATICAL SANS-SERIF BOLD CAPITAL SIGMA +1D769 Τ # MATHEMATICAL SANS-SERIF BOLD CAPITAL TAU +1D76A Î¥ # MATHEMATICAL SANS-SERIF BOLD CAPITAL UPSILON +1D76B Φ # MATHEMATICAL SANS-SERIF BOLD CAPITAL PHI +1D76C Χ # MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI +1D76D Ψ # MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI +1D76E Ω # MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA +1D76F ∇ # MATHEMATICAL SANS-SERIF BOLD NABLA +1D770 α # MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA +1D771 β # MATHEMATICAL SANS-SERIF BOLD SMALL BETA +1D772 γ # MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA +1D773 δ # MATHEMATICAL SANS-SERIF BOLD SMALL DELTA +1D774 ε # MATHEMATICAL SANS-SERIF BOLD SMALL EPSILON +1D775 ζ # MATHEMATICAL SANS-SERIF BOLD SMALL ZETA +1D776 η # MATHEMATICAL SANS-SERIF BOLD SMALL ETA +1D777 θ # MATHEMATICAL SANS-SERIF BOLD SMALL THETA +1D778 ι # MATHEMATICAL SANS-SERIF BOLD SMALL IOTA +1D779 κ # MATHEMATICAL SANS-SERIF BOLD SMALL KAPPA +1D77A λ # MATHEMATICAL SANS-SERIF BOLD SMALL LAMDA +1D77B μ # MATHEMATICAL SANS-SERIF BOLD SMALL MU +1D77C ν # MATHEMATICAL SANS-SERIF BOLD SMALL NU +1D77D ξ # MATHEMATICAL SANS-SERIF BOLD SMALL XI +1D77E ο # MATHEMATICAL SANS-SERIF BOLD SMALL OMICRON +1D77F Ï€ # MATHEMATICAL SANS-SERIF BOLD SMALL PI +1D780 Ï # MATHEMATICAL SANS-SERIF BOLD SMALL RHO +1D781 Ï‚ # MATHEMATICAL SANS-SERIF BOLD SMALL FINAL SIGMA +1D782 σ # MATHEMATICAL SANS-SERIF BOLD SMALL SIGMA +1D783 Ï„ # MATHEMATICAL SANS-SERIF BOLD SMALL TAU +1D784 Ï… # MATHEMATICAL SANS-SERIF BOLD SMALL UPSILON +1D785 φ # MATHEMATICAL SANS-SERIF BOLD SMALL PHI +1D786 χ # MATHEMATICAL SANS-SERIF BOLD SMALL CHI +1D787 ψ # MATHEMATICAL SANS-SERIF BOLD SMALL PSI +1D788 ω # MATHEMATICAL SANS-SERIF BOLD SMALL OMEGA +1D789 ∂ # MATHEMATICAL SANS-SERIF BOLD PARTIAL DIFFERENTIAL +1D78A ϵ # MATHEMATICAL SANS-SERIF BOLD EPSILON SYMBOL +1D78B Ï‘ # MATHEMATICAL SANS-SERIF BOLD THETA SYMBOL +1D78C ϰ # MATHEMATICAL SANS-SERIF BOLD KAPPA SYMBOL +1D78D Ï• # MATHEMATICAL SANS-SERIF BOLD PHI SYMBOL +1D78E ϱ # MATHEMATICAL SANS-SERIF BOLD RHO SYMBOL +1D78F Ï– # MATHEMATICAL SANS-SERIF BOLD PI SYMBOL +1D790 Α # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ALPHA +1D791 Î’ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL BETA +1D792 Γ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL GAMMA +1D793 Δ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL DELTA +1D794 Ε # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL EPSILON +1D795 Ζ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ZETA +1D796 Η # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL ETA +1D797 Θ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA +1D798 Ι # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL IOTA +1D799 Κ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL KAPPA +1D79A Λ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL LAMDA +1D79B Μ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL MU +1D79C Î # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL NU +1D79D Ξ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL XI +1D79E Ο # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMICRON +1D79F Π # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PI +1D7A0 Ρ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL RHO +1D7A1 Ï´ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL THETA SYMBOL +1D7A2 Σ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL SIGMA +1D7A3 Τ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL TAU +1D7A4 Î¥ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL UPSILON +1D7A5 Φ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PHI +1D7A6 Χ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI +1D7A7 Ψ # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI +1D7A8 Ω # MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA +1D7A9 ∇ # MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA +1D7AA α # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA +1D7AB β # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA +1D7AC γ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA +1D7AD δ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL DELTA +1D7AE ε # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL EPSILON +1D7AF ζ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ZETA +1D7B0 η # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ETA +1D7B1 θ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL THETA +1D7B2 ι # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL IOTA +1D7B3 κ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL KAPPA +1D7B4 λ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL LAMDA +1D7B5 μ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL MU +1D7B6 ν # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL NU +1D7B7 ξ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL XI +1D7B8 ο # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMICRON +1D7B9 Ï€ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PI +1D7BA Ï # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL RHO +1D7BB Ï‚ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL FINAL SIGMA +1D7BC σ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL SIGMA +1D7BD Ï„ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL TAU +1D7BE Ï… # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL UPSILON +1D7BF φ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PHI +1D7C0 χ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL CHI +1D7C1 ψ # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL PSI +1D7C2 ω # MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL OMEGA +1D7C3 ∂ # MATHEMATICAL SANS-SERIF BOLD ITALIC PARTIAL DIFFERENTIAL +1D7C4 ϵ # MATHEMATICAL SANS-SERIF BOLD ITALIC EPSILON SYMBOL +1D7C5 Ï‘ # MATHEMATICAL SANS-SERIF BOLD ITALIC THETA SYMBOL +1D7C6 ϰ # MATHEMATICAL SANS-SERIF BOLD ITALIC KAPPA SYMBOL +1D7C7 Ï• # MATHEMATICAL SANS-SERIF BOLD ITALIC PHI SYMBOL +1D7C8 ϱ # MATHEMATICAL SANS-SERIF BOLD ITALIC RHO SYMBOL +1D7C9 Ï– # MATHEMATICAL SANS-SERIF BOLD ITALIC PI SYMBOL +1D7CE 0 # MATHEMATICAL BOLD DIGIT ZERO +1D7CF 1 # MATHEMATICAL BOLD DIGIT ONE +1D7D0 2 # MATHEMATICAL BOLD DIGIT TWO +1D7D1 3 # MATHEMATICAL BOLD DIGIT THREE +1D7D2 4 # MATHEMATICAL BOLD DIGIT FOUR +1D7D3 5 # MATHEMATICAL BOLD DIGIT FIVE +1D7D4 6 # MATHEMATICAL BOLD DIGIT SIX +1D7D5 7 # MATHEMATICAL BOLD DIGIT SEVEN +1D7D6 8 # MATHEMATICAL BOLD DIGIT EIGHT +1D7D7 9 # MATHEMATICAL BOLD DIGIT NINE +1D7D8 0 # MATHEMATICAL DOUBLE-STRUCK DIGIT ZERO +1D7D9 1 # MATHEMATICAL DOUBLE-STRUCK DIGIT ONE +1D7DA 2 # MATHEMATICAL DOUBLE-STRUCK DIGIT TWO +1D7DB 3 # MATHEMATICAL DOUBLE-STRUCK DIGIT THREE +1D7DC 4 # MATHEMATICAL DOUBLE-STRUCK DIGIT FOUR +1D7DD 5 # MATHEMATICAL DOUBLE-STRUCK DIGIT FIVE +1D7DE 6 # MATHEMATICAL DOUBLE-STRUCK DIGIT SIX +1D7DF 7 # MATHEMATICAL DOUBLE-STRUCK DIGIT SEVEN +1D7E0 8 # MATHEMATICAL DOUBLE-STRUCK DIGIT EIGHT +1D7E1 9 # MATHEMATICAL DOUBLE-STRUCK DIGIT NINE +1D7E2 0 # MATHEMATICAL SANS-SERIF DIGIT ZERO +1D7E3 1 # MATHEMATICAL SANS-SERIF DIGIT ONE +1D7E4 2 # MATHEMATICAL SANS-SERIF DIGIT TWO +1D7E5 3 # MATHEMATICAL SANS-SERIF DIGIT THREE +1D7E6 4 # MATHEMATICAL SANS-SERIF DIGIT FOUR +1D7E7 5 # MATHEMATICAL SANS-SERIF DIGIT FIVE +1D7E8 6 # MATHEMATICAL SANS-SERIF DIGIT SIX +1D7E9 7 # MATHEMATICAL SANS-SERIF DIGIT SEVEN +1D7EA 8 # MATHEMATICAL SANS-SERIF DIGIT EIGHT +1D7EB 9 # MATHEMATICAL SANS-SERIF DIGIT NINE +1D7EC 0 # MATHEMATICAL SANS-SERIF BOLD DIGIT ZERO +1D7ED 1 # MATHEMATICAL SANS-SERIF BOLD DIGIT ONE +1D7EE 2 # MATHEMATICAL SANS-SERIF BOLD DIGIT TWO +1D7EF 3 # MATHEMATICAL SANS-SERIF BOLD DIGIT THREE +1D7F0 4 # MATHEMATICAL SANS-SERIF BOLD DIGIT FOUR +1D7F1 5 # MATHEMATICAL SANS-SERIF BOLD DIGIT FIVE +1D7F2 6 # MATHEMATICAL SANS-SERIF BOLD DIGIT SIX +1D7F3 7 # MATHEMATICAL SANS-SERIF BOLD DIGIT SEVEN +1D7F4 8 # MATHEMATICAL SANS-SERIF BOLD DIGIT EIGHT +1D7F5 9 # MATHEMATICAL SANS-SERIF BOLD DIGIT NINE +1D7F6 0 # MATHEMATICAL MONOSPACE DIGIT ZERO +1D7F7 1 # MATHEMATICAL MONOSPACE DIGIT ONE +1D7F8 2 # MATHEMATICAL MONOSPACE DIGIT TWO +1D7F9 3 # MATHEMATICAL MONOSPACE DIGIT THREE +1D7FA 4 # MATHEMATICAL MONOSPACE DIGIT FOUR +1D7FB 5 # MATHEMATICAL MONOSPACE DIGIT FIVE +1D7FC 6 # MATHEMATICAL MONOSPACE DIGIT SIX +1D7FD 7 # MATHEMATICAL MONOSPACE DIGIT SEVEN +1D7FE 8 # MATHEMATICAL MONOSPACE DIGIT EIGHT +1D7FF 9 # MATHEMATICAL MONOSPACE DIGIT NINE +2F800 丽 # CJK COMPATIBILITY IDEOGRAPH-2F800 +2F801 丸 # CJK COMPATIBILITY IDEOGRAPH-2F801 +2F802 ä¹ # CJK COMPATIBILITY IDEOGRAPH-2F802 +2F803 ð „¢ # CJK COMPATIBILITY IDEOGRAPH-2F803 +2F804 ä½  # CJK COMPATIBILITY IDEOGRAPH-2F804 +2F805 ä¾® # CJK COMPATIBILITY IDEOGRAPH-2F805 +2F806 ä¾» # CJK COMPATIBILITY IDEOGRAPH-2F806 +2F807 倂 # CJK COMPATIBILITY IDEOGRAPH-2F807 +2F808 åº # CJK COMPATIBILITY IDEOGRAPH-2F808 +2F809 å‚™ # CJK COMPATIBILITY IDEOGRAPH-2F809 +2F80A 僧 # CJK COMPATIBILITY IDEOGRAPH-2F80A +2F80B åƒ # CJK COMPATIBILITY IDEOGRAPH-2F80B +2F80C ã’ž # CJK COMPATIBILITY IDEOGRAPH-2F80C +2F80D 𠘺 # CJK COMPATIBILITY IDEOGRAPH-2F80D +2F80E å… # CJK COMPATIBILITY IDEOGRAPH-2F80E +2F80F å…” # CJK COMPATIBILITY IDEOGRAPH-2F80F +2F810 å…¤ # CJK COMPATIBILITY IDEOGRAPH-2F810 +2F811 å…· # CJK COMPATIBILITY IDEOGRAPH-2F811 +2F812 𠔜 # CJK COMPATIBILITY IDEOGRAPH-2F812 +2F813 ã’¹ # CJK COMPATIBILITY IDEOGRAPH-2F813 +2F814 å…§ # CJK COMPATIBILITY IDEOGRAPH-2F814 +2F815 å† # CJK COMPATIBILITY IDEOGRAPH-2F815 +2F816 ð •‹ # CJK COMPATIBILITY IDEOGRAPH-2F816 +2F817 冗 # CJK COMPATIBILITY IDEOGRAPH-2F817 +2F818 冤 # CJK COMPATIBILITY IDEOGRAPH-2F818 +2F819 仌 # CJK COMPATIBILITY IDEOGRAPH-2F819 +2F81A 冬 # CJK COMPATIBILITY IDEOGRAPH-2F81A +2F81B 况 # CJK COMPATIBILITY IDEOGRAPH-2F81B +2F81C 𩇟 # CJK COMPATIBILITY IDEOGRAPH-2F81C +2F81D 凵 # CJK COMPATIBILITY IDEOGRAPH-2F81D +2F81E 刃 # CJK COMPATIBILITY IDEOGRAPH-2F81E +2F81F 㓟 # CJK COMPATIBILITY IDEOGRAPH-2F81F +2F820 刻 # CJK COMPATIBILITY IDEOGRAPH-2F820 +2F821 剆 # CJK COMPATIBILITY IDEOGRAPH-2F821 +2F822 割 # CJK COMPATIBILITY IDEOGRAPH-2F822 +2F823 剷 # CJK COMPATIBILITY IDEOGRAPH-2F823 +2F824 㔕 # CJK COMPATIBILITY IDEOGRAPH-2F824 +2F825 勇 # CJK COMPATIBILITY IDEOGRAPH-2F825 +2F826 勉 # CJK COMPATIBILITY IDEOGRAPH-2F826 +2F827 勤 # CJK COMPATIBILITY IDEOGRAPH-2F827 +2F828 勺 # CJK COMPATIBILITY IDEOGRAPH-2F828 +2F829 包 # CJK COMPATIBILITY IDEOGRAPH-2F829 +2F82A 匆 # CJK COMPATIBILITY IDEOGRAPH-2F82A +2F82B 北 # CJK COMPATIBILITY IDEOGRAPH-2F82B +2F82C å‰ # CJK COMPATIBILITY IDEOGRAPH-2F82C +2F82D å‘ # CJK COMPATIBILITY IDEOGRAPH-2F82D +2F82E åš # CJK COMPATIBILITY IDEOGRAPH-2F82E +2F82F å³ # CJK COMPATIBILITY IDEOGRAPH-2F82F +2F830 å½ # CJK COMPATIBILITY IDEOGRAPH-2F830 +2F831 å¿ # CJK COMPATIBILITY IDEOGRAPH-2F831 +2F832 å¿ # CJK COMPATIBILITY IDEOGRAPH-2F832 +2F833 å¿ # CJK COMPATIBILITY IDEOGRAPH-2F833 +2F834 𠨬 # CJK COMPATIBILITY IDEOGRAPH-2F834 +2F835 ç° # CJK COMPATIBILITY IDEOGRAPH-2F835 +2F836 åŠ # CJK COMPATIBILITY IDEOGRAPH-2F836 +2F837 åŸ # CJK COMPATIBILITY IDEOGRAPH-2F837 +2F838 ð ­£ # CJK COMPATIBILITY IDEOGRAPH-2F838 +2F839 å« # CJK COMPATIBILITY IDEOGRAPH-2F839 +2F83A å± # CJK COMPATIBILITY IDEOGRAPH-2F83A +2F83B å† # CJK COMPATIBILITY IDEOGRAPH-2F83B +2F83C å’ž # CJK COMPATIBILITY IDEOGRAPH-2F83C +2F83D å¸ # CJK COMPATIBILITY IDEOGRAPH-2F83D +2F83E 呈 # CJK COMPATIBILITY IDEOGRAPH-2F83E +2F83F 周 # CJK COMPATIBILITY IDEOGRAPH-2F83F +2F840 å’¢ # CJK COMPATIBILITY IDEOGRAPH-2F840 +2F841 å“¶ # CJK COMPATIBILITY IDEOGRAPH-2F841 +2F842 å” # CJK COMPATIBILITY IDEOGRAPH-2F842 +2F843 å•“ # CJK COMPATIBILITY IDEOGRAPH-2F843 +2F844 å•£ # CJK COMPATIBILITY IDEOGRAPH-2F844 +2F845 å–„ # CJK COMPATIBILITY IDEOGRAPH-2F845 +2F846 å–„ # CJK COMPATIBILITY IDEOGRAPH-2F846 +2F847 å–™ # CJK COMPATIBILITY IDEOGRAPH-2F847 +2F848 å–« # CJK COMPATIBILITY IDEOGRAPH-2F848 +2F849 å–³ # CJK COMPATIBILITY IDEOGRAPH-2F849 +2F84A å—‚ # CJK COMPATIBILITY IDEOGRAPH-2F84A +2F84B 圖 # CJK COMPATIBILITY IDEOGRAPH-2F84B +2F84C 嘆 # CJK COMPATIBILITY IDEOGRAPH-2F84C +2F84D 圗 # CJK COMPATIBILITY IDEOGRAPH-2F84D +2F84E 噑 # CJK COMPATIBILITY IDEOGRAPH-2F84E +2F84F å™´ # CJK COMPATIBILITY IDEOGRAPH-2F84F +2F850 切 # CJK COMPATIBILITY IDEOGRAPH-2F850 +2F851 壮 # CJK COMPATIBILITY IDEOGRAPH-2F851 +2F852 城 # CJK COMPATIBILITY IDEOGRAPH-2F852 +2F853 埴 # CJK COMPATIBILITY IDEOGRAPH-2F853 +2F854 å  # CJK COMPATIBILITY IDEOGRAPH-2F854 +2F855 åž‹ # CJK COMPATIBILITY IDEOGRAPH-2F855 +2F856 å ² # CJK COMPATIBILITY IDEOGRAPH-2F856 +2F857 å ± # CJK COMPATIBILITY IDEOGRAPH-2F857 +2F858 墬 # CJK COMPATIBILITY IDEOGRAPH-2F858 +2F859 𡓤 # CJK COMPATIBILITY IDEOGRAPH-2F859 +2F85A 売 # CJK COMPATIBILITY IDEOGRAPH-2F85A +2F85B 壷 # CJK COMPATIBILITY IDEOGRAPH-2F85B +2F85C 夆 # CJK COMPATIBILITY IDEOGRAPH-2F85C +2F85D 多 # CJK COMPATIBILITY IDEOGRAPH-2F85D +2F85E 夢 # CJK COMPATIBILITY IDEOGRAPH-2F85E +2F85F 奢 # CJK COMPATIBILITY IDEOGRAPH-2F85F +2F860 𡚨 # CJK COMPATIBILITY IDEOGRAPH-2F860 +2F861 𡛪 # CJK COMPATIBILITY IDEOGRAPH-2F861 +2F862 姬 # CJK COMPATIBILITY IDEOGRAPH-2F862 +2F863 娛 # CJK COMPATIBILITY IDEOGRAPH-2F863 +2F864 娧 # CJK COMPATIBILITY IDEOGRAPH-2F864 +2F865 姘 # CJK COMPATIBILITY IDEOGRAPH-2F865 +2F866 婦 # CJK COMPATIBILITY IDEOGRAPH-2F866 +2F867 ã›® # CJK COMPATIBILITY IDEOGRAPH-2F867 +2F868 㛼 # CJK COMPATIBILITY IDEOGRAPH-2F868 +2F869 嬈 # CJK COMPATIBILITY IDEOGRAPH-2F869 +2F86A 嬾 # CJK COMPATIBILITY IDEOGRAPH-2F86A +2F86B 嬾 # CJK COMPATIBILITY IDEOGRAPH-2F86B +2F86C 𡧈 # CJK COMPATIBILITY IDEOGRAPH-2F86C +2F86D 寃 # CJK COMPATIBILITY IDEOGRAPH-2F86D +2F86E 寘 # CJK COMPATIBILITY IDEOGRAPH-2F86E +2F86F 寧 # CJK COMPATIBILITY IDEOGRAPH-2F86F +2F870 寳 # CJK COMPATIBILITY IDEOGRAPH-2F870 +2F871 𡬘 # CJK COMPATIBILITY IDEOGRAPH-2F871 +2F872 寿 # CJK COMPATIBILITY IDEOGRAPH-2F872 +2F873 å°† # CJK COMPATIBILITY IDEOGRAPH-2F873 +2F874 当 # CJK COMPATIBILITY IDEOGRAPH-2F874 +2F875 å°¢ # CJK COMPATIBILITY IDEOGRAPH-2F875 +2F876 ãž # CJK COMPATIBILITY IDEOGRAPH-2F876 +2F877 å±  # CJK COMPATIBILITY IDEOGRAPH-2F877 +2F878 å±® # CJK COMPATIBILITY IDEOGRAPH-2F878 +2F879 å³€ # CJK COMPATIBILITY IDEOGRAPH-2F879 +2F87A å² # CJK COMPATIBILITY IDEOGRAPH-2F87A +2F87B ð¡·¤ # CJK COMPATIBILITY IDEOGRAPH-2F87B +2F87C 嵃 # CJK COMPATIBILITY IDEOGRAPH-2F87C +2F87D ð¡·¦ # CJK COMPATIBILITY IDEOGRAPH-2F87D +2F87E åµ® # CJK COMPATIBILITY IDEOGRAPH-2F87E +2F87F 嵫 # CJK COMPATIBILITY IDEOGRAPH-2F87F +2F880 åµ¼ # CJK COMPATIBILITY IDEOGRAPH-2F880 +2F881 å·¡ # CJK COMPATIBILITY IDEOGRAPH-2F881 +2F882 å·¢ # CJK COMPATIBILITY IDEOGRAPH-2F882 +2F883 ã ¯ # CJK COMPATIBILITY IDEOGRAPH-2F883 +2F884 å·½ # CJK COMPATIBILITY IDEOGRAPH-2F884 +2F885 帨 # CJK COMPATIBILITY IDEOGRAPH-2F885 +2F886 帽 # CJK COMPATIBILITY IDEOGRAPH-2F886 +2F887 幩 # CJK COMPATIBILITY IDEOGRAPH-2F887 +2F888 ã¡¢ # CJK COMPATIBILITY IDEOGRAPH-2F888 +2F889 𢆃 # CJK COMPATIBILITY IDEOGRAPH-2F889 +2F88A 㡼 # CJK COMPATIBILITY IDEOGRAPH-2F88A +2F88B 庰 # CJK COMPATIBILITY IDEOGRAPH-2F88B +2F88C 庳 # CJK COMPATIBILITY IDEOGRAPH-2F88C +2F88D 庶 # CJK COMPATIBILITY IDEOGRAPH-2F88D +2F88E 廊 # CJK COMPATIBILITY IDEOGRAPH-2F88E +2F88F 𪎒 # CJK COMPATIBILITY IDEOGRAPH-2F88F +2F890 廾 # CJK COMPATIBILITY IDEOGRAPH-2F890 +2F891 𢌱 # CJK COMPATIBILITY IDEOGRAPH-2F891 +2F892 𢌱 # CJK COMPATIBILITY IDEOGRAPH-2F892 +2F893 èˆ # CJK COMPATIBILITY IDEOGRAPH-2F893 +2F894 å¼¢ # CJK COMPATIBILITY IDEOGRAPH-2F894 +2F895 å¼¢ # CJK COMPATIBILITY IDEOGRAPH-2F895 +2F896 㣇 # CJK COMPATIBILITY IDEOGRAPH-2F896 +2F897 𣊸 # CJK COMPATIBILITY IDEOGRAPH-2F897 +2F898 𦇚 # CJK COMPATIBILITY IDEOGRAPH-2F898 +2F899 å½¢ # CJK COMPATIBILITY IDEOGRAPH-2F899 +2F89A 彫 # CJK COMPATIBILITY IDEOGRAPH-2F89A +2F89B 㣣 # CJK COMPATIBILITY IDEOGRAPH-2F89B +2F89C 徚 # CJK COMPATIBILITY IDEOGRAPH-2F89C +2F89D å¿ # CJK COMPATIBILITY IDEOGRAPH-2F89D +2F89E å¿— # CJK COMPATIBILITY IDEOGRAPH-2F89E +2F89F 忹 # CJK COMPATIBILITY IDEOGRAPH-2F89F +2F8A0 æ‚ # CJK COMPATIBILITY IDEOGRAPH-2F8A0 +2F8A1 㤺 # CJK COMPATIBILITY IDEOGRAPH-2F8A1 +2F8A2 㤜 # CJK COMPATIBILITY IDEOGRAPH-2F8A2 +2F8A3 æ‚” # CJK COMPATIBILITY IDEOGRAPH-2F8A3 +2F8A4 𢛔 # CJK COMPATIBILITY IDEOGRAPH-2F8A4 +2F8A5 惇 # CJK COMPATIBILITY IDEOGRAPH-2F8A5 +2F8A6 æ…ˆ # CJK COMPATIBILITY IDEOGRAPH-2F8A6 +2F8A7 æ…Œ # CJK COMPATIBILITY IDEOGRAPH-2F8A7 +2F8A8 æ…Ž # CJK COMPATIBILITY IDEOGRAPH-2F8A8 +2F8A9 æ…Œ # CJK COMPATIBILITY IDEOGRAPH-2F8A9 +2F8AA æ…º # CJK COMPATIBILITY IDEOGRAPH-2F8AA +2F8AB 憎 # CJK COMPATIBILITY IDEOGRAPH-2F8AB +2F8AC 憲 # CJK COMPATIBILITY IDEOGRAPH-2F8AC +2F8AD 憤 # CJK COMPATIBILITY IDEOGRAPH-2F8AD +2F8AE 憯 # CJK COMPATIBILITY IDEOGRAPH-2F8AE +2F8AF 懞 # CJK COMPATIBILITY IDEOGRAPH-2F8AF +2F8B0 懲 # CJK COMPATIBILITY IDEOGRAPH-2F8B0 +2F8B1 懶 # CJK COMPATIBILITY IDEOGRAPH-2F8B1 +2F8B2 æˆ # CJK COMPATIBILITY IDEOGRAPH-2F8B2 +2F8B3 戛 # CJK COMPATIBILITY IDEOGRAPH-2F8B3 +2F8B4 æ‰ # CJK COMPATIBILITY IDEOGRAPH-2F8B4 +2F8B5 抱 # CJK COMPATIBILITY IDEOGRAPH-2F8B5 +2F8B6 æ‹” # CJK COMPATIBILITY IDEOGRAPH-2F8B6 +2F8B7 æ # CJK COMPATIBILITY IDEOGRAPH-2F8B7 +2F8B8 𢬌 # CJK COMPATIBILITY IDEOGRAPH-2F8B8 +2F8B9 挽 # CJK COMPATIBILITY IDEOGRAPH-2F8B9 +2F8BA 拼 # CJK COMPATIBILITY IDEOGRAPH-2F8BA +2F8BB æ¨ # CJK COMPATIBILITY IDEOGRAPH-2F8BB +2F8BC 掃 # CJK COMPATIBILITY IDEOGRAPH-2F8BC +2F8BD æ¤ # CJK COMPATIBILITY IDEOGRAPH-2F8BD +2F8BE 𢯱 # CJK COMPATIBILITY IDEOGRAPH-2F8BE +2F8BF æ¢ # CJK COMPATIBILITY IDEOGRAPH-2F8BF +2F8C0 æ… # CJK COMPATIBILITY IDEOGRAPH-2F8C0 +2F8C1 掩 # CJK COMPATIBILITY IDEOGRAPH-2F8C1 +2F8C2 㨮 # CJK COMPATIBILITY IDEOGRAPH-2F8C2 +2F8C3 æ‘© # CJK COMPATIBILITY IDEOGRAPH-2F8C3 +2F8C4 摾 # CJK COMPATIBILITY IDEOGRAPH-2F8C4 +2F8C5 æ’ # CJK COMPATIBILITY IDEOGRAPH-2F8C5 +2F8C6 æ‘· # CJK COMPATIBILITY IDEOGRAPH-2F8C6 +2F8C7 㩬 # CJK COMPATIBILITY IDEOGRAPH-2F8C7 +2F8C8 æ• # CJK COMPATIBILITY IDEOGRAPH-2F8C8 +2F8C9 敬 # CJK COMPATIBILITY IDEOGRAPH-2F8C9 +2F8CA 𣀊 # CJK COMPATIBILITY IDEOGRAPH-2F8CA +2F8CB æ—£ # CJK COMPATIBILITY IDEOGRAPH-2F8CB +2F8CC 書 # CJK COMPATIBILITY IDEOGRAPH-2F8CC +2F8CD 晉 # CJK COMPATIBILITY IDEOGRAPH-2F8CD +2F8CE 㬙 # CJK COMPATIBILITY IDEOGRAPH-2F8CE +2F8CF æš‘ # CJK COMPATIBILITY IDEOGRAPH-2F8CF +2F8D0 㬈 # CJK COMPATIBILITY IDEOGRAPH-2F8D0 +2F8D1 㫤 # CJK COMPATIBILITY IDEOGRAPH-2F8D1 +2F8D2 冒 # CJK COMPATIBILITY IDEOGRAPH-2F8D2 +2F8D3 冕 # CJK COMPATIBILITY IDEOGRAPH-2F8D3 +2F8D4 最 # CJK COMPATIBILITY IDEOGRAPH-2F8D4 +2F8D5 æšœ # CJK COMPATIBILITY IDEOGRAPH-2F8D5 +2F8D6 è‚­ # CJK COMPATIBILITY IDEOGRAPH-2F8D6 +2F8D7 ä™ # CJK COMPATIBILITY IDEOGRAPH-2F8D7 +2F8D8 朗 # CJK COMPATIBILITY IDEOGRAPH-2F8D8 +2F8D9 望 # CJK COMPATIBILITY IDEOGRAPH-2F8D9 +2F8DA 朡 # CJK COMPATIBILITY IDEOGRAPH-2F8DA +2F8DB æž # CJK COMPATIBILITY IDEOGRAPH-2F8DB +2F8DC æ“ # CJK COMPATIBILITY IDEOGRAPH-2F8DC +2F8DD 𣃠# CJK COMPATIBILITY IDEOGRAPH-2F8DD +2F8DE ã­‰ # CJK COMPATIBILITY IDEOGRAPH-2F8DE +2F8DF 柺 # CJK COMPATIBILITY IDEOGRAPH-2F8DF +2F8E0 æž… # CJK COMPATIBILITY IDEOGRAPH-2F8E0 +2F8E1 æ¡’ # CJK COMPATIBILITY IDEOGRAPH-2F8E1 +2F8E2 梅 # CJK COMPATIBILITY IDEOGRAPH-2F8E2 +2F8E3 𣑭 # CJK COMPATIBILITY IDEOGRAPH-2F8E3 +2F8E4 梎 # CJK COMPATIBILITY IDEOGRAPH-2F8E4 +2F8E5 æ Ÿ # CJK COMPATIBILITY IDEOGRAPH-2F8E5 +2F8E6 椔 # CJK COMPATIBILITY IDEOGRAPH-2F8E6 +2F8E7 ã® # CJK COMPATIBILITY IDEOGRAPH-2F8E7 +2F8E8 楂 # CJK COMPATIBILITY IDEOGRAPH-2F8E8 +2F8E9 榣 # CJK COMPATIBILITY IDEOGRAPH-2F8E9 +2F8EA 槪 # CJK COMPATIBILITY IDEOGRAPH-2F8EA +2F8EB 檨 # CJK COMPATIBILITY IDEOGRAPH-2F8EB +2F8EC 𣚣 # CJK COMPATIBILITY IDEOGRAPH-2F8EC +2F8ED æ«› # CJK COMPATIBILITY IDEOGRAPH-2F8ED +2F8EE ã°˜ # CJK COMPATIBILITY IDEOGRAPH-2F8EE +2F8EF 次 # CJK COMPATIBILITY IDEOGRAPH-2F8EF +2F8F0 𣢧 # CJK COMPATIBILITY IDEOGRAPH-2F8F0 +2F8F1 æ­” # CJK COMPATIBILITY IDEOGRAPH-2F8F1 +2F8F2 㱎 # CJK COMPATIBILITY IDEOGRAPH-2F8F2 +2F8F3 æ­² # CJK COMPATIBILITY IDEOGRAPH-2F8F3 +2F8F4 殟 # CJK COMPATIBILITY IDEOGRAPH-2F8F4 +2F8F5 殺 # CJK COMPATIBILITY IDEOGRAPH-2F8F5 +2F8F6 æ®» # CJK COMPATIBILITY IDEOGRAPH-2F8F6 +2F8F7 𣪠# CJK COMPATIBILITY IDEOGRAPH-2F8F7 +2F8F8 ð¡´‹ # CJK COMPATIBILITY IDEOGRAPH-2F8F8 +2F8F9 𣫺 # CJK COMPATIBILITY IDEOGRAPH-2F8F9 +2F8FA 汎 # CJK COMPATIBILITY IDEOGRAPH-2F8FA +2F8FB 𣲼 # CJK COMPATIBILITY IDEOGRAPH-2F8FB +2F8FC 沿 # CJK COMPATIBILITY IDEOGRAPH-2F8FC +2F8FD æ³ # CJK COMPATIBILITY IDEOGRAPH-2F8FD +2F8FE æ±§ # CJK COMPATIBILITY IDEOGRAPH-2F8FE +2F8FF æ´– # CJK COMPATIBILITY IDEOGRAPH-2F8FF +2F900 æ´¾ # CJK COMPATIBILITY IDEOGRAPH-2F900 +2F901 æµ· # CJK COMPATIBILITY IDEOGRAPH-2F901 +2F902 æµ # CJK COMPATIBILITY IDEOGRAPH-2F902 +2F903 浩 # CJK COMPATIBILITY IDEOGRAPH-2F903 +2F904 浸 # CJK COMPATIBILITY IDEOGRAPH-2F904 +2F905 æ¶… # CJK COMPATIBILITY IDEOGRAPH-2F905 +2F906 𣴞 # CJK COMPATIBILITY IDEOGRAPH-2F906 +2F907 æ´´ # CJK COMPATIBILITY IDEOGRAPH-2F907 +2F908 港 # CJK COMPATIBILITY IDEOGRAPH-2F908 +2F909 æ¹® # CJK COMPATIBILITY IDEOGRAPH-2F909 +2F90A ã´³ # CJK COMPATIBILITY IDEOGRAPH-2F90A +2F90B 滋 # CJK COMPATIBILITY IDEOGRAPH-2F90B +2F90C 滇 # CJK COMPATIBILITY IDEOGRAPH-2F90C +2F90D 𣻑 # CJK COMPATIBILITY IDEOGRAPH-2F90D +2F90E æ·¹ # CJK COMPATIBILITY IDEOGRAPH-2F90E +2F90F æ½® # CJK COMPATIBILITY IDEOGRAPH-2F90F +2F910 𣽞 # CJK COMPATIBILITY IDEOGRAPH-2F910 +2F911 𣾎 # CJK COMPATIBILITY IDEOGRAPH-2F911 +2F912 濆 # CJK COMPATIBILITY IDEOGRAPH-2F912 +2F913 瀹 # CJK COMPATIBILITY IDEOGRAPH-2F913 +2F914 瀞 # CJK COMPATIBILITY IDEOGRAPH-2F914 +2F915 瀛 # CJK COMPATIBILITY IDEOGRAPH-2F915 +2F916 ã¶– # CJK COMPATIBILITY IDEOGRAPH-2F916 +2F917 çŠ # CJK COMPATIBILITY IDEOGRAPH-2F917 +2F918 ç½ # CJK COMPATIBILITY IDEOGRAPH-2F918 +2F919 ç· # CJK COMPATIBILITY IDEOGRAPH-2F919 +2F91A ç‚­ # CJK COMPATIBILITY IDEOGRAPH-2F91A +2F91B 𠔥 # CJK COMPATIBILITY IDEOGRAPH-2F91B +2F91C ç…… # CJK COMPATIBILITY IDEOGRAPH-2F91C +2F91D 𤉣 # CJK COMPATIBILITY IDEOGRAPH-2F91D +2F91E 熜 # CJK COMPATIBILITY IDEOGRAPH-2F91E +2F91F 𤎫 # CJK COMPATIBILITY IDEOGRAPH-2F91F +2F920 爨 # CJK COMPATIBILITY IDEOGRAPH-2F920 +2F921 爵 # CJK COMPATIBILITY IDEOGRAPH-2F921 +2F922 ç‰ # CJK COMPATIBILITY IDEOGRAPH-2F922 +2F923 𤘈 # CJK COMPATIBILITY IDEOGRAPH-2F923 +2F924 犀 # CJK COMPATIBILITY IDEOGRAPH-2F924 +2F925 犕 # CJK COMPATIBILITY IDEOGRAPH-2F925 +2F926 𤜵 # CJK COMPATIBILITY IDEOGRAPH-2F926 +2F927 𤠔 # CJK COMPATIBILITY IDEOGRAPH-2F927 +2F928 çº # CJK COMPATIBILITY IDEOGRAPH-2F928 +2F929 王 # CJK COMPATIBILITY IDEOGRAPH-2F929 +2F92A 㺬 # CJK COMPATIBILITY IDEOGRAPH-2F92A +2F92B 玥 # CJK COMPATIBILITY IDEOGRAPH-2F92B +2F92C 㺸 # CJK COMPATIBILITY IDEOGRAPH-2F92C +2F92D 㺸 # CJK COMPATIBILITY IDEOGRAPH-2F92D +2F92E 瑇 # CJK COMPATIBILITY IDEOGRAPH-2F92E +2F92F 瑜 # CJK COMPATIBILITY IDEOGRAPH-2F92F +2F930 瑱 # CJK COMPATIBILITY IDEOGRAPH-2F930 +2F931 ç’… # CJK COMPATIBILITY IDEOGRAPH-2F931 +2F932 瓊 # CJK COMPATIBILITY IDEOGRAPH-2F932 +2F933 ã¼› # CJK COMPATIBILITY IDEOGRAPH-2F933 +2F934 甤 # CJK COMPATIBILITY IDEOGRAPH-2F934 +2F935 𤰶 # CJK COMPATIBILITY IDEOGRAPH-2F935 +2F936 甾 # CJK COMPATIBILITY IDEOGRAPH-2F936 +2F937 𤲒 # CJK COMPATIBILITY IDEOGRAPH-2F937 +2F938 ç•° # CJK COMPATIBILITY IDEOGRAPH-2F938 +2F939 𢆟 # CJK COMPATIBILITY IDEOGRAPH-2F939 +2F93A ç˜ # CJK COMPATIBILITY IDEOGRAPH-2F93A +2F93B 𤾡 # CJK COMPATIBILITY IDEOGRAPH-2F93B +2F93C 𤾸 # CJK COMPATIBILITY IDEOGRAPH-2F93C +2F93D 𥄠# CJK COMPATIBILITY IDEOGRAPH-2F93D +2F93E 㿼 # CJK COMPATIBILITY IDEOGRAPH-2F93E +2F93F 䀈 # CJK COMPATIBILITY IDEOGRAPH-2F93F +2F940 ç›´ # CJK COMPATIBILITY IDEOGRAPH-2F940 +2F941 𥃳 # CJK COMPATIBILITY IDEOGRAPH-2F941 +2F942 𥃲 # CJK COMPATIBILITY IDEOGRAPH-2F942 +2F943 𥄙 # CJK COMPATIBILITY IDEOGRAPH-2F943 +2F944 𥄳 # CJK COMPATIBILITY IDEOGRAPH-2F944 +2F945 眞 # CJK COMPATIBILITY IDEOGRAPH-2F945 +2F946 真 # CJK COMPATIBILITY IDEOGRAPH-2F946 +2F947 真 # CJK COMPATIBILITY IDEOGRAPH-2F947 +2F948 çŠ # CJK COMPATIBILITY IDEOGRAPH-2F948 +2F949 䀹 # CJK COMPATIBILITY IDEOGRAPH-2F949 +2F94A çž‹ # CJK COMPATIBILITY IDEOGRAPH-2F94A +2F94B ä† # CJK COMPATIBILITY IDEOGRAPH-2F94B +2F94C ä‚– # CJK COMPATIBILITY IDEOGRAPH-2F94C +2F94D ð¥ # CJK COMPATIBILITY IDEOGRAPH-2F94D +2F94E 硎 # CJK COMPATIBILITY IDEOGRAPH-2F94E +2F94F 碌 # CJK COMPATIBILITY IDEOGRAPH-2F94F +2F950 磌 # CJK COMPATIBILITY IDEOGRAPH-2F950 +2F951 䃣 # CJK COMPATIBILITY IDEOGRAPH-2F951 +2F952 𥘦 # CJK COMPATIBILITY IDEOGRAPH-2F952 +2F953 祖 # CJK COMPATIBILITY IDEOGRAPH-2F953 +2F954 𥚚 # CJK COMPATIBILITY IDEOGRAPH-2F954 +2F955 𥛅 # CJK COMPATIBILITY IDEOGRAPH-2F955 +2F956 ç¦ # CJK COMPATIBILITY IDEOGRAPH-2F956 +2F957 ç§« # CJK COMPATIBILITY IDEOGRAPH-2F957 +2F958 䄯 # CJK COMPATIBILITY IDEOGRAPH-2F958 +2F959 ç©€ # CJK COMPATIBILITY IDEOGRAPH-2F959 +2F95A 穊 # CJK COMPATIBILITY IDEOGRAPH-2F95A +2F95B ç© # CJK COMPATIBILITY IDEOGRAPH-2F95B +2F95C 𥥼 # CJK COMPATIBILITY IDEOGRAPH-2F95C +2F95D 𥪧 # CJK COMPATIBILITY IDEOGRAPH-2F95D +2F95E 𥪧 # CJK COMPATIBILITY IDEOGRAPH-2F95E +2F95F ç«® # CJK COMPATIBILITY IDEOGRAPH-2F95F +2F960 䈂 # CJK COMPATIBILITY IDEOGRAPH-2F960 +2F961 𥮫 # CJK COMPATIBILITY IDEOGRAPH-2F961 +2F962 篆 # CJK COMPATIBILITY IDEOGRAPH-2F962 +2F963 築 # CJK COMPATIBILITY IDEOGRAPH-2F963 +2F964 䈧 # CJK COMPATIBILITY IDEOGRAPH-2F964 +2F965 𥲀 # CJK COMPATIBILITY IDEOGRAPH-2F965 +2F966 ç³’ # CJK COMPATIBILITY IDEOGRAPH-2F966 +2F967 䊠 # CJK COMPATIBILITY IDEOGRAPH-2F967 +2F968 糨 # CJK COMPATIBILITY IDEOGRAPH-2F968 +2F969 ç³£ # CJK COMPATIBILITY IDEOGRAPH-2F969 +2F96A ç´€ # CJK COMPATIBILITY IDEOGRAPH-2F96A +2F96B 𥾆 # CJK COMPATIBILITY IDEOGRAPH-2F96B +2F96C çµ£ # CJK COMPATIBILITY IDEOGRAPH-2F96C +2F96D äŒ # CJK COMPATIBILITY IDEOGRAPH-2F96D +2F96E ç·‡ # CJK COMPATIBILITY IDEOGRAPH-2F96E +2F96F 縂 # CJK COMPATIBILITY IDEOGRAPH-2F96F +2F970 ç¹… # CJK COMPATIBILITY IDEOGRAPH-2F970 +2F971 䌴 # CJK COMPATIBILITY IDEOGRAPH-2F971 +2F972 𦈨 # CJK COMPATIBILITY IDEOGRAPH-2F972 +2F973 𦉇 # CJK COMPATIBILITY IDEOGRAPH-2F973 +2F974 ä™ # CJK COMPATIBILITY IDEOGRAPH-2F974 +2F975 𦋙 # CJK COMPATIBILITY IDEOGRAPH-2F975 +2F976 罺 # CJK COMPATIBILITY IDEOGRAPH-2F976 +2F977 𦌾 # CJK COMPATIBILITY IDEOGRAPH-2F977 +2F978 羕 # CJK COMPATIBILITY IDEOGRAPH-2F978 +2F979 翺 # CJK COMPATIBILITY IDEOGRAPH-2F979 +2F97A 者 # CJK COMPATIBILITY IDEOGRAPH-2F97A +2F97B 𦓚 # CJK COMPATIBILITY IDEOGRAPH-2F97B +2F97C 𦔣 # CJK COMPATIBILITY IDEOGRAPH-2F97C +2F97D è  # CJK COMPATIBILITY IDEOGRAPH-2F97D +2F97E 𦖨 # CJK COMPATIBILITY IDEOGRAPH-2F97E +2F97F è° # CJK COMPATIBILITY IDEOGRAPH-2F97F +2F980 𣟠# CJK COMPATIBILITY IDEOGRAPH-2F980 +2F981 ä• # CJK COMPATIBILITY IDEOGRAPH-2F981 +2F982 育 # CJK COMPATIBILITY IDEOGRAPH-2F982 +2F983 脃 # CJK COMPATIBILITY IDEOGRAPH-2F983 +2F984 ä‹ # CJK COMPATIBILITY IDEOGRAPH-2F984 +2F985 脾 # CJK COMPATIBILITY IDEOGRAPH-2F985 +2F986 媵 # CJK COMPATIBILITY IDEOGRAPH-2F986 +2F987 𦞧 # CJK COMPATIBILITY IDEOGRAPH-2F987 +2F988 𦞵 # CJK COMPATIBILITY IDEOGRAPH-2F988 +2F989 𣎓 # CJK COMPATIBILITY IDEOGRAPH-2F989 +2F98A 𣎜 # CJK COMPATIBILITY IDEOGRAPH-2F98A +2F98B èˆ # CJK COMPATIBILITY IDEOGRAPH-2F98B +2F98C 舄 # CJK COMPATIBILITY IDEOGRAPH-2F98C +2F98D 辞 # CJK COMPATIBILITY IDEOGRAPH-2F98D +2F98E ä‘« # CJK COMPATIBILITY IDEOGRAPH-2F98E +2F98F 芑 # CJK COMPATIBILITY IDEOGRAPH-2F98F +2F990 芋 # CJK COMPATIBILITY IDEOGRAPH-2F990 +2F991 èŠ # CJK COMPATIBILITY IDEOGRAPH-2F991 +2F992 劳 # CJK COMPATIBILITY IDEOGRAPH-2F992 +2F993 花 # CJK COMPATIBILITY IDEOGRAPH-2F993 +2F994 芳 # CJK COMPATIBILITY IDEOGRAPH-2F994 +2F995 芽 # CJK COMPATIBILITY IDEOGRAPH-2F995 +2F996 苦 # CJK COMPATIBILITY IDEOGRAPH-2F996 +2F997 𦬼 # CJK COMPATIBILITY IDEOGRAPH-2F997 +2F998 è‹¥ # CJK COMPATIBILITY IDEOGRAPH-2F998 +2F999 èŒ # CJK COMPATIBILITY IDEOGRAPH-2F999 +2F99A è£ # CJK COMPATIBILITY IDEOGRAPH-2F99A +2F99B 莭 # CJK COMPATIBILITY IDEOGRAPH-2F99B +2F99C 茣 # CJK COMPATIBILITY IDEOGRAPH-2F99C +2F99D 莽 # CJK COMPATIBILITY IDEOGRAPH-2F99D +2F99E è§ # CJK COMPATIBILITY IDEOGRAPH-2F99E +2F99F è‘— # CJK COMPATIBILITY IDEOGRAPH-2F99F +2F9A0 è“ # CJK COMPATIBILITY IDEOGRAPH-2F9A0 +2F9A1 èŠ # CJK COMPATIBILITY IDEOGRAPH-2F9A1 +2F9A2 èŒ # CJK COMPATIBILITY IDEOGRAPH-2F9A2 +2F9A3 èœ # CJK COMPATIBILITY IDEOGRAPH-2F9A3 +2F9A4 𦰶 # CJK COMPATIBILITY IDEOGRAPH-2F9A4 +2F9A5 𦵫 # CJK COMPATIBILITY IDEOGRAPH-2F9A5 +2F9A6 𦳕 # CJK COMPATIBILITY IDEOGRAPH-2F9A6 +2F9A7 䔫 # CJK COMPATIBILITY IDEOGRAPH-2F9A7 +2F9A8 蓱 # CJK COMPATIBILITY IDEOGRAPH-2F9A8 +2F9A9 蓳 # CJK COMPATIBILITY IDEOGRAPH-2F9A9 +2F9AA è”– # CJK COMPATIBILITY IDEOGRAPH-2F9AA +2F9AB ð§Š # CJK COMPATIBILITY IDEOGRAPH-2F9AB +2F9AC 蕤 # CJK COMPATIBILITY IDEOGRAPH-2F9AC +2F9AD 𦼬 # CJK COMPATIBILITY IDEOGRAPH-2F9AD +2F9AE ä• # CJK COMPATIBILITY IDEOGRAPH-2F9AE +2F9AF ä•¡ # CJK COMPATIBILITY IDEOGRAPH-2F9AF +2F9B0 𦾱 # CJK COMPATIBILITY IDEOGRAPH-2F9B0 +2F9B1 𧃒 # CJK COMPATIBILITY IDEOGRAPH-2F9B1 +2F9B2 ä•« # CJK COMPATIBILITY IDEOGRAPH-2F9B2 +2F9B3 è™ # CJK COMPATIBILITY IDEOGRAPH-2F9B3 +2F9B4 虜 # CJK COMPATIBILITY IDEOGRAPH-2F9B4 +2F9B5 è™§ # CJK COMPATIBILITY IDEOGRAPH-2F9B5 +2F9B6 虩 # CJK COMPATIBILITY IDEOGRAPH-2F9B6 +2F9B7 èš© # CJK COMPATIBILITY IDEOGRAPH-2F9B7 +2F9B8 蚈 # CJK COMPATIBILITY IDEOGRAPH-2F9B8 +2F9B9 蜎 # CJK COMPATIBILITY IDEOGRAPH-2F9B9 +2F9BA 蛢 # CJK COMPATIBILITY IDEOGRAPH-2F9BA +2F9BB è¹ # CJK COMPATIBILITY IDEOGRAPH-2F9BB +2F9BC 蜨 # CJK COMPATIBILITY IDEOGRAPH-2F9BC +2F9BD è« # CJK COMPATIBILITY IDEOGRAPH-2F9BD +2F9BE 螆 # CJK COMPATIBILITY IDEOGRAPH-2F9BE +2F9BF ä—— # CJK COMPATIBILITY IDEOGRAPH-2F9BF +2F9C0 蟡 # CJK COMPATIBILITY IDEOGRAPH-2F9C0 +2F9C1 è  # CJK COMPATIBILITY IDEOGRAPH-2F9C1 +2F9C2 ä—¹ # CJK COMPATIBILITY IDEOGRAPH-2F9C2 +2F9C3 è¡  # CJK COMPATIBILITY IDEOGRAPH-2F9C3 +2F9C4 è¡£ # CJK COMPATIBILITY IDEOGRAPH-2F9C4 +2F9C5 ð§™§ # CJK COMPATIBILITY IDEOGRAPH-2F9C5 +2F9C6 裗 # CJK COMPATIBILITY IDEOGRAPH-2F9C6 +2F9C7 裞 # CJK COMPATIBILITY IDEOGRAPH-2F9C7 +2F9C8 䘵 # CJK COMPATIBILITY IDEOGRAPH-2F9C8 +2F9C9 裺 # CJK COMPATIBILITY IDEOGRAPH-2F9C9 +2F9CA ã’» # CJK COMPATIBILITY IDEOGRAPH-2F9CA +2F9CB ð§¢® # CJK COMPATIBILITY IDEOGRAPH-2F9CB +2F9CC 𧥦 # CJK COMPATIBILITY IDEOGRAPH-2F9CC +2F9CD äš¾ # CJK COMPATIBILITY IDEOGRAPH-2F9CD +2F9CE 䛇 # CJK COMPATIBILITY IDEOGRAPH-2F9CE +2F9CF 誠 # CJK COMPATIBILITY IDEOGRAPH-2F9CF +2F9D0 è«­ # CJK COMPATIBILITY IDEOGRAPH-2F9D0 +2F9D1 變 # CJK COMPATIBILITY IDEOGRAPH-2F9D1 +2F9D2 豕 # CJK COMPATIBILITY IDEOGRAPH-2F9D2 +2F9D3 𧲨 # CJK COMPATIBILITY IDEOGRAPH-2F9D3 +2F9D4 貫 # CJK COMPATIBILITY IDEOGRAPH-2F9D4 +2F9D5 è³ # CJK COMPATIBILITY IDEOGRAPH-2F9D5 +2F9D6 è´› # CJK COMPATIBILITY IDEOGRAPH-2F9D6 +2F9D7 èµ· # CJK COMPATIBILITY IDEOGRAPH-2F9D7 +2F9D8 𧼯 # CJK COMPATIBILITY IDEOGRAPH-2F9D8 +2F9D9 ð  „ # CJK COMPATIBILITY IDEOGRAPH-2F9D9 +2F9DA è·‹ # CJK COMPATIBILITY IDEOGRAPH-2F9DA +2F9DB è¶¼ # CJK COMPATIBILITY IDEOGRAPH-2F9DB +2F9DC è·° # CJK COMPATIBILITY IDEOGRAPH-2F9DC +2F9DD 𠣞 # CJK COMPATIBILITY IDEOGRAPH-2F9DD +2F9DE è»” # CJK COMPATIBILITY IDEOGRAPH-2F9DE +2F9DF 輸 # CJK COMPATIBILITY IDEOGRAPH-2F9DF +2F9E0 𨗒 # CJK COMPATIBILITY IDEOGRAPH-2F9E0 +2F9E1 𨗭 # CJK COMPATIBILITY IDEOGRAPH-2F9E1 +2F9E2 é‚” # CJK COMPATIBILITY IDEOGRAPH-2F9E2 +2F9E3 郱 # CJK COMPATIBILITY IDEOGRAPH-2F9E3 +2F9E4 é„‘ # CJK COMPATIBILITY IDEOGRAPH-2F9E4 +2F9E5 𨜮 # CJK COMPATIBILITY IDEOGRAPH-2F9E5 +2F9E6 é„› # CJK COMPATIBILITY IDEOGRAPH-2F9E6 +2F9E7 鈸 # CJK COMPATIBILITY IDEOGRAPH-2F9E7 +2F9E8 é‹— # CJK COMPATIBILITY IDEOGRAPH-2F9E8 +2F9E9 鋘 # CJK COMPATIBILITY IDEOGRAPH-2F9E9 +2F9EA 鉼 # CJK COMPATIBILITY IDEOGRAPH-2F9EA +2F9EB é¹ # CJK COMPATIBILITY IDEOGRAPH-2F9EB +2F9EC é• # CJK COMPATIBILITY IDEOGRAPH-2F9EC +2F9ED 𨯺 # CJK COMPATIBILITY IDEOGRAPH-2F9ED +2F9EE é–‹ # CJK COMPATIBILITY IDEOGRAPH-2F9EE +2F9EF 䦕 # CJK COMPATIBILITY IDEOGRAPH-2F9EF +2F9F0 é–· # CJK COMPATIBILITY IDEOGRAPH-2F9F0 +2F9F1 𨵷 # CJK COMPATIBILITY IDEOGRAPH-2F9F1 +2F9F2 䧦 # CJK COMPATIBILITY IDEOGRAPH-2F9F2 +2F9F3 雃 # CJK COMPATIBILITY IDEOGRAPH-2F9F3 +2F9F4 å¶² # CJK COMPATIBILITY IDEOGRAPH-2F9F4 +2F9F5 霣 # CJK COMPATIBILITY IDEOGRAPH-2F9F5 +2F9F6 ð©…… # CJK COMPATIBILITY IDEOGRAPH-2F9F6 +2F9F7 𩈚 # CJK COMPATIBILITY IDEOGRAPH-2F9F7 +2F9F8 ä©® # CJK COMPATIBILITY IDEOGRAPH-2F9F8 +2F9F9 ä©¶ # CJK COMPATIBILITY IDEOGRAPH-2F9F9 +2F9FA 韠 # CJK COMPATIBILITY IDEOGRAPH-2F9FA +2F9FB 𩊠# CJK COMPATIBILITY IDEOGRAPH-2F9FB +2F9FC 䪲 # CJK COMPATIBILITY IDEOGRAPH-2F9FC +2F9FD ð©’– # CJK COMPATIBILITY IDEOGRAPH-2F9FD +2F9FE é ‹ # CJK COMPATIBILITY IDEOGRAPH-2F9FE +2F9FF é ‹ # CJK COMPATIBILITY IDEOGRAPH-2F9FF +2FA00 é © # CJK COMPATIBILITY IDEOGRAPH-2FA00 +2FA01 ð©–¶ # CJK COMPATIBILITY IDEOGRAPH-2FA01 +2FA02 飢 # CJK COMPATIBILITY IDEOGRAPH-2FA02 +2FA03 䬳 # CJK COMPATIBILITY IDEOGRAPH-2FA03 +2FA04 餩 # CJK COMPATIBILITY IDEOGRAPH-2FA04 +2FA05 馧 # CJK COMPATIBILITY IDEOGRAPH-2FA05 +2FA06 é§‚ # CJK COMPATIBILITY IDEOGRAPH-2FA06 +2FA07 é§¾ # CJK COMPATIBILITY IDEOGRAPH-2FA07 +2FA08 䯎 # CJK COMPATIBILITY IDEOGRAPH-2FA08 +2FA09 𩬰 # CJK COMPATIBILITY IDEOGRAPH-2FA09 +2FA0A 鬒 # CJK COMPATIBILITY IDEOGRAPH-2FA0A +2FA0B é±€ # CJK COMPATIBILITY IDEOGRAPH-2FA0B +2FA0C é³½ # CJK COMPATIBILITY IDEOGRAPH-2FA0C +2FA0D 䳎 # CJK COMPATIBILITY IDEOGRAPH-2FA0D +2FA0E ä³­ # CJK COMPATIBILITY IDEOGRAPH-2FA0E +2FA0F éµ§ # CJK COMPATIBILITY IDEOGRAPH-2FA0F +2FA10 𪃎 # CJK COMPATIBILITY IDEOGRAPH-2FA10 +2FA11 䳸 # CJK COMPATIBILITY IDEOGRAPH-2FA11 +2FA12 𪄅 # CJK COMPATIBILITY IDEOGRAPH-2FA12 +2FA13 𪈎 # CJK COMPATIBILITY IDEOGRAPH-2FA13 +2FA14 𪊑 # CJK COMPATIBILITY IDEOGRAPH-2FA14 +2FA15 麻 # CJK COMPATIBILITY IDEOGRAPH-2FA15 +2FA16 äµ– # CJK COMPATIBILITY IDEOGRAPH-2FA16 +2FA17 黹 # CJK COMPATIBILITY IDEOGRAPH-2FA17 +2FA18 黾 # CJK COMPATIBILITY IDEOGRAPH-2FA18 +2FA19 é¼… # CJK COMPATIBILITY IDEOGRAPH-2FA19 +2FA1A é¼ # CJK COMPATIBILITY IDEOGRAPH-2FA1A +2FA1B é¼– # CJK COMPATIBILITY IDEOGRAPH-2FA1B +2FA1C é¼» # CJK COMPATIBILITY IDEOGRAPH-2FA1C +2FA1D 𪘀 # CJK COMPATIBILITY IDEOGRAPH-2FA1D diff --git a/libs/libiconv/lib/translit.h b/libs/libiconv/lib/translit.h new file mode 100644 index 00000000..15aa4472 --- /dev/null +++ b/libs/libiconv/lib/translit.h @@ -0,0 +1,4411 @@ +/* + * Copyright (C) 1999-2003 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * Transliteration table + */ + +static const unsigned int translit_data[9116] = { + 1, ' ', + 1, '!', + 1, 'c', + 2, 'l', 'b', + 3, 'y', 'e', 'n', + 1, '|', + 2, 'S', 'S', + 1, '"', + 3, '(', 'c', ')', + 1, 'a', + 2, '<', '<', + 3, 'n', 'o', 't', + 1, '-', + 3, '(', 'R', ')', + 2, '^', '0', + 3, '+', '/', '-', + 2, '^', '2', + 2, '^', '3', + 1,'\'', + 1, 'u', + 1, 'P', + 1, '.', + 1, ',', + 2, '^', '1', + 1, 'o', + 2, '>', '>', + 5, ' ', '1',0x2044, '4', ' ', + 5, ' ', '1',0x2044, '2', ' ', + 5, ' ', '3',0x2044, '4', ' ', + 1, '?', + 2, '`', 'A', + 2,0xB4, 'A', + 2, '^', 'A', + 2, '~', 'A', + 2, '"', 'A', + 1, 'A', + 2, 'A', 'E', + 1, 'C', + 2, '`', 'E', + 2,0xB4, 'E', + 2, '^', 'E', + 2, '"', 'E', + 2, '`', 'I', + 2,0xB4, 'I', + 2, '^', 'I', + 2, '"', 'I', + 1, 'D', + 2, '~', 'N', + 2, '`', 'O', + 2,0xB4, 'O', + 2, '^', 'O', + 2, '~', 'O', + 2, '"', 'O', + 1, 'x', + 1, 'O', + 2, '`', 'U', + 2,0xB4, 'U', + 2, '^', 'U', + 2, '"', 'U', + 2,0xB4, 'Y', + 2, 'T', 'h', + 2, 's', 's', + 2, '`', 'a', + 2,0xB4, 'a', + 2, '^', 'a', + 2, '~', 'a', + 2, '"', 'a', + 1, 'a', + 2, 'a', 'e', + 1, 'c', + 2, '`', 'e', + 2,0xB4, 'e', + 2, '^', 'e', + 2, '"', 'e', + 2, '`', 'i', + 2,0xB4, 'i', + 2, '^', 'i', + 2, '"', 'i', + 1, 'd', + 2, '~', 'n', + 2, '`', 'o', + 2,0xB4, 'o', + 2, '^', 'o', + 2, '~', 'o', + 2, '"', 'o', + 1, ':', + 1, 'o', + 2, '`', 'u', + 2,0xB4, 'u', + 2, '^', 'u', + 2, '"', 'u', + 2,0xB4, 'y', + 2, 't', 'h', + 2, '"', 'y', + 1, 'A', + 1, 'a', + 1, 'A', + 1, 'a', + 1, 'A', + 1, 'a', + 2,0xB4, 'C', + 2,0xB4, 'c', + 2, '^', 'C', + 2, '^', 'c', + 1, 'C', + 1, 'c', + 1, 'C', + 1, 'c', + 1, 'D', + 1, 'd', + 1, 'D', + 1, 'd', + 1, 'E', + 1, 'e', + 1, 'E', + 1, 'e', + 1, 'E', + 1, 'e', + 1, 'E', + 1, 'e', + 1, 'E', + 1, 'e', + 2, '^', 'G', + 2, '^', 'g', + 1, 'G', + 1, 'g', + 1, 'G', + 1, 'g', + 1, 'G', + 1, 'g', + 2, '^', 'H', + 2, '^', 'h', + 1, 'H', + 1, 'h', + 2, '~', 'I', + 2, '~', 'i', + 1, 'I', + 1, 'i', + 1, 'I', + 1, 'i', + 1, 'I', + 1, 'i', + 1, 'I', + 1, 'i', + 2, 'I', 'J', + 2, 'i', 'j', + 2, '^', 'J', + 2, '^', 'j', + 1, 'K', + 1, 'k', + 1, 'L', + 1, 'l', + 1, 'L', + 1, 'l', + 1, 'L', + 1, 'l', + 1, 'L', + 1, 'l', + 1, 'L', + 1, 'l', + 2,0xB4, 'N', + 2,0xB4, 'n', + 1, 'N', + 1, 'n', + 1, 'N', + 1, 'n', + 2,'\'', 'n', + 1, 'O', + 1, 'o', + 1, 'O', + 1, 'o', + 2, '"', 'O', + 2, '"', 'o', + 2, 'O', 'E', + 2, 'o', 'e', + 2,0xB4, 'R', + 2,0xB4, 'r', + 1, 'R', + 1, 'r', + 1, 'R', + 1, 'r', + 2,0xB4, 'S', + 2,0xB4, 's', + 2, '^', 'S', + 2, '^', 's', + 1, 'S', + 1, 's', + 1, 'S', + 1, 's', + 1, 'T', + 1, 't', + 1, 'T', + 1, 't', + 1, 'T', + 1, 't', + 2, '~', 'U', + 2, '~', 'u', + 1, 'U', + 1, 'u', + 1, 'U', + 1, 'u', + 1, 'U', + 1, 'u', + 2, '"', 'U', + 2, '"', 'u', + 1, 'U', + 1, 'u', + 2, '^', 'W', + 2, '^', 'w', + 2, '^', 'Y', + 2, '^', 'y', + 2, '"', 'Y', + 2,0xB4, 'Z', + 2,0xB4, 'z', + 1, 'Z', + 1, 'z', + 1, 'Z', + 1, 'z', + 1, 's', + 1, 'f', + 2, 'D',0x017D, + 2, 'D',0x017E, + 2, 'd',0x017E, + 2, 'L', 'J', + 2, 'L', 'j', + 2, 'l', 'j', + 2, 'N', 'J', + 2, 'N', 'j', + 2, 'n', 'j', + 2, 'D', 'Z', + 2, 'D', 'z', + 2, 'd', 'z', + 1, 'S', + 1, 's', + 1, 'T', + 1, 't', + 1,0x2032, + 1,0x2033, + 1,0x2018, + 1,0x2019, + 1,0x201B, + 1, '^', + 1,'\'', + 1,0xAF, + 1,0xB4, + 1, '`', + 1, '_', + 1, '~', + 1, '"', + 1,0x03B2, + 1,0x03B8, + 1,0x03A5, + 1,0x03C6, + 1,0x03C0, + 1,0x03BA, + 1,0x03C1, + 1,0x03C2, + 1,0x0398, + 1,0x03B5, + 1,0x03A3, + 2,0x0565,0x0582, + 2,0x05D5,0x05D5, + 2,0x05D5,0x05D9, + 2,0x05D9,0x05D9, + 2,0x0627,0x0674, + 2,0x0648,0x0674, + 2,0x06C7,0x0674, + 2,0x064A,0x0674, + 2,0x0E4D,0x0E32, + 2,0x0ECD,0x0EB2, + 2,0x0EAB,0x0E99, + 2,0x0EAB,0x0EA1, + 2,0x0FB2,0x0F81, + 2,0x0FB3,0x0F81, + 1, 'B', + 1, 'b', + 1, 'D', + 1, 'd', + 1, 'F', + 1, 'f', + 1, 'M', + 1, 'm', + 1, 'P', + 1, 'p', + 1, 'S', + 1, 's', + 1, 'T', + 1, 't', + 2, '`', 'W', + 2, '`', 'w', + 2,0xB4, 'W', + 2,0xB4, 'w', + 2, '"', 'W', + 2, '"', 'w', + 2, 'a',0x02BE, + 2, '`', 'Y', + 2, '`', 'y', + 1, ' ', + 1, ' ', + 1, ' ', + 1, ' ', + 1, ' ', + 1, ' ', + 1, ' ', + 1, ' ', + 1, '-', + 1, '-', + 1, '-', + 1, '-', + 1, '-', + 1, '-', + 1,'\'', + 1,'\'', + 1, ',', + 1,'\'', + 1, '"', + 1, '"', + 1, '"', + 1, '"', + 1, '+', + 1, 'o', + 1, '.', + 2, '.', '.', + 3, '.', '.', '.', + 4, 'o', '/', 'o', 'o', + 1,0xB4, + 2,0xB4,0xB4, + 3,0xB4,0xB4,0xB4, + 2,0x2035,0x2035, + 3,0x2035,0x2035,0x2035, + 1, '<', + 1, '>', + 2, '!', '!', + 1, '/', + 2, '?', '?', + 2, '?', '!', + 2, '!', '?', + 4,0xB4,0xB4,0xB4,0xB4, + 2, 'R', 's', + 4,0x0110,0x1ED3, 'n', 'g', + 3, 'E', 'U', 'R', + 3, 'a', '/', 'c', + 3, 'a', '/', 's', + 1, 'C', + 2,0xB0, 'C', + 3, 'c', '/', 'o', + 3, 'c', '/', 'u', + 1,0x0190, + 2,0xB0, 'F', + 1, 'g', + 1, 'H', + 1, 'H', + 1, 'H', + 1, 'h', + 1,0x0127, + 1, 'I', + 1, 'I', + 1, 'L', + 1, 'l', + 1, 'N', + 2, 'N', 'o', + 1, 'P', + 1, 'Q', + 1, 'R', + 1, 'R', + 1, 'R', + 3, 'T', 'E', 'L', + 2, 'T', 'M', + 1, 'Z', + 3, 'O', 'h', 'm', + 1, 'Z', + 1, 'B', + 1, 'C', + 1, 'e', + 1, 'e', + 1, 'E', + 1, 'F', + 1, 'M', + 1, 'o', + 1,0x05D0, + 1,0x05D1, + 1,0x05D2, + 1,0x05D3, + 1, 'i', + 3, 'F', 'A', 'X', + 1,0x03B3, + 1,0x0393, + 1,0x03A0, + 1,0x2211, + 1, 'D', + 1, 'd', + 1, 'e', + 1, 'i', + 1, 'j', + 5, ' ', '1',0x2044, '3', ' ', + 5, ' ', '2',0x2044, '3', ' ', + 5, ' ', '1',0x2044, '5', ' ', + 5, ' ', '2',0x2044, '5', ' ', + 5, ' ', '3',0x2044, '5', ' ', + 5, ' ', '4',0x2044, '5', ' ', + 5, ' ', '1',0x2044, '6', ' ', + 5, ' ', '5',0x2044, '6', ' ', + 5, ' ', '1',0x2044, '8', ' ', + 5, ' ', '3',0x2044, '8', ' ', + 5, ' ', '5',0x2044, '8', ' ', + 5, ' ', '7',0x2044, '8', ' ', + 3, ' ', '1',0x2044, + 1, 'I', + 2, 'I', 'I', + 3, 'I', 'I', 'I', + 2, 'I', 'V', + 1, 'V', + 2, 'V', 'I', + 3, 'V', 'I', 'I', + 4, 'V', 'I', 'I', 'I', + 2, 'I', 'X', + 1, 'X', + 2, 'X', 'I', + 3, 'X', 'I', 'I', + 1, 'L', + 1, 'C', + 1, 'D', + 1, 'M', + 1, 'i', + 2, 'i', 'i', + 3, 'i', 'i', 'i', + 2, 'i', 'v', + 1, 'v', + 2, 'v', 'i', + 3, 'v', 'i', 'i', + 4, 'v', 'i', 'i', 'i', + 2, 'i', 'x', + 1, 'x', + 2, 'x', 'i', + 3, 'x', 'i', 'i', + 1, 'l', + 1, 'c', + 1, 'd', + 1, 'm', + 2, '<', '-', + 1, '^', + 2, '-', '>', + 1, 'V', + 3, '<', '-', '>', + 2, '<', '=', + 2, '=', '>', + 3, '<', '=', '>', + 1, '-', + 1, '/', + 1,'\\', + 1, '*', + 1,0x2022, + 1, '|', + 2,0x222B,0x222B, + 3,0x222B,0x222B,0x222B, + 2,0x222E,0x222E, + 3,0x222E,0x222E,0x222E, + 1, ':', + 1, '~', + 2, '/', '=', + 2, '<', '=', + 2, '>', '=', + 2, '<', '<', + 2, '>', '>', + 1,0xB7, + 3, '<', '<', '<', + 3, '>', '>', '>', + 3,0xB7,0xB7,0xB7, + 5, '[', 'N', 'U', 'L', ']', + 5, '[', 'S', 'O', 'H', ']', + 5, '[', 'S', 'T', 'X', ']', + 5, '[', 'E', 'T', 'X', ']', + 5, '[', 'E', 'O', 'T', ']', + 5, '[', 'E', 'N', 'Q', ']', + 5, '[', 'A', 'C', 'K', ']', + 5, '[', 'B', 'E', 'L', ']', + 4, '[', 'B', 'S', ']', + 4, '[', 'H', 'T', ']', + 4, '[', 'L', 'F', ']', + 4, '[', 'V', 'T', ']', + 4, '[', 'F', 'F', ']', + 4, '[', 'C', 'R', ']', + 4, '[', 'S', 'O', ']', + 4, '[', 'S', 'I', ']', + 5, '[', 'D', 'L', 'E', ']', + 5, '[', 'D', 'C', '1', ']', + 5, '[', 'D', 'C', '2', ']', + 5, '[', 'D', 'C', '3', ']', + 5, '[', 'D', 'C', '4', ']', + 5, '[', 'N', 'A', 'K', ']', + 5, '[', 'S', 'Y', 'N', ']', + 5, '[', 'E', 'T', 'B', ']', + 5, '[', 'C', 'A', 'N', ']', + 4, '[', 'E', 'M', ']', + 5, '[', 'S', 'U', 'B', ']', + 5, '[', 'E', 'S', 'C', ']', + 4, '[', 'F', 'S', ']', + 4, '[', 'G', 'S', ']', + 4, '[', 'R', 'S', ']', + 4, '[', 'U', 'S', ']', + 4, '[', 'S', 'P', ']', + 5, '[', 'D', 'E', 'L', ']', + 4, '[', 'N', 'L', ']', + 3, '(', '1', ')', + 3, '(', '2', ')', + 3, '(', '3', ')', + 3, '(', '4', ')', + 3, '(', '5', ')', + 3, '(', '6', ')', + 3, '(', '7', ')', + 3, '(', '8', ')', + 3, '(', '9', ')', + 4, '(', '1', '0', ')', + 4, '(', '1', '1', ')', + 4, '(', '1', '2', ')', + 4, '(', '1', '3', ')', + 4, '(', '1', '4', ')', + 4, '(', '1', '5', ')', + 4, '(', '1', '6', ')', + 4, '(', '1', '7', ')', + 4, '(', '1', '8', ')', + 4, '(', '1', '9', ')', + 4, '(', '2', '0', ')', + 3, '(', '1', ')', + 3, '(', '2', ')', + 3, '(', '3', ')', + 3, '(', '4', ')', + 3, '(', '5', ')', + 3, '(', '6', ')', + 3, '(', '7', ')', + 3, '(', '8', ')', + 3, '(', '9', ')', + 4, '(', '1', '0', ')', + 4, '(', '1', '1', ')', + 4, '(', '1', '2', ')', + 4, '(', '1', '3', ')', + 4, '(', '1', '4', ')', + 4, '(', '1', '5', ')', + 4, '(', '1', '6', ')', + 4, '(', '1', '7', ')', + 4, '(', '1', '8', ')', + 4, '(', '1', '9', ')', + 4, '(', '2', '0', ')', + 2, '1', '.', + 2, '2', '.', + 2, '3', '.', + 2, '4', '.', + 2, '5', '.', + 2, '6', '.', + 2, '7', '.', + 2, '8', '.', + 2, '9', '.', + 3, '1', '0', '.', + 3, '1', '1', '.', + 3, '1', '2', '.', + 3, '1', '3', '.', + 3, '1', '4', '.', + 3, '1', '5', '.', + 3, '1', '6', '.', + 3, '1', '7', '.', + 3, '1', '8', '.', + 3, '1', '9', '.', + 3, '2', '0', '.', + 3, '(', 'a', ')', + 3, '(', 'b', ')', + 3, '(', 'c', ')', + 3, '(', 'd', ')', + 3, '(', 'e', ')', + 3, '(', 'f', ')', + 3, '(', 'g', ')', + 3, '(', 'h', ')', + 3, '(', 'i', ')', + 3, '(', 'j', ')', + 3, '(', 'k', ')', + 3, '(', 'l', ')', + 3, '(', 'm', ')', + 3, '(', 'n', ')', + 3, '(', 'o', ')', + 3, '(', 'p', ')', + 3, '(', 'q', ')', + 3, '(', 'r', ')', + 3, '(', 's', ')', + 3, '(', 't', ')', + 3, '(', 'u', ')', + 3, '(', 'v', ')', + 3, '(', 'w', ')', + 3, '(', 'x', ')', + 3, '(', 'y', ')', + 3, '(', 'z', ')', + 3, '(', 'A', ')', + 3, '(', 'B', ')', + 3, '(', 'C', ')', + 3, '(', 'D', ')', + 3, '(', 'E', ')', + 3, '(', 'F', ')', + 3, '(', 'G', ')', + 3, '(', 'H', ')', + 3, '(', 'I', ')', + 3, '(', 'J', ')', + 3, '(', 'K', ')', + 3, '(', 'L', ')', + 3, '(', 'M', ')', + 3, '(', 'N', ')', + 3, '(', 'O', ')', + 3, '(', 'P', ')', + 3, '(', 'Q', ')', + 3, '(', 'R', ')', + 3, '(', 'S', ')', + 3, '(', 'T', ')', + 3, '(', 'U', ')', + 3, '(', 'V', ')', + 3, '(', 'W', ')', + 3, '(', 'X', ')', + 3, '(', 'Y', ')', + 3, '(', 'Z', ')', + 3, '(', 'a', ')', + 3, '(', 'b', ')', + 3, '(', 'c', ')', + 3, '(', 'd', ')', + 3, '(', 'e', ')', + 3, '(', 'f', ')', + 3, '(', 'g', ')', + 3, '(', 'h', ')', + 3, '(', 'i', ')', + 3, '(', 'j', ')', + 3, '(', 'k', ')', + 3, '(', 'l', ')', + 3, '(', 'm', ')', + 3, '(', 'n', ')', + 3, '(', 'o', ')', + 3, '(', 'p', ')', + 3, '(', 'q', ')', + 3, '(', 'r', ')', + 3, '(', 's', ')', + 3, '(', 't', ')', + 3, '(', 'u', ')', + 3, '(', 'v', ')', + 3, '(', 'w', ')', + 3, '(', 'x', ')', + 3, '(', 'y', ')', + 3, '(', 'z', ')', + 3, '(', '0', ')', + 1, '-', + 1, '|', + 1, '+', + 1, '+', + 1, '+', + 1, '+', + 1, '+', + 1, '+', + 1, '+', + 1, '+', + 1, '+', + 1, 'o', + 4,0x222B,0x222B,0x222B,0x222B, + 3, ':', ':', '=', + 2, '=', '=', + 3, '=', '=', '=', + 1,0x6BCD, + 1,0x9F9F, + 1,0x4E00, + 1,0x4E28, + 1,0x4E36, + 1,0x4E3F, + 1,0x4E59, + 1,0x4E85, + 1,0x4E8C, + 1,0x4EA0, + 1,0x4EBA, + 1,0x513F, + 1,0x5165, + 1,0x516B, + 1,0x5182, + 1,0x5196, + 1,0x51AB, + 1,0x51E0, + 1,0x51F5, + 1,0x5200, + 1,0x529B, + 1,0x52F9, + 1,0x5315, + 1,0x531A, + 1,0x5338, + 1,0x5341, + 1,0x535C, + 1,0x5369, + 1,0x5382, + 1,0x53B6, + 1,0x53C8, + 1,0x53E3, + 1,0x56D7, + 1,0x571F, + 1,0x58EB, + 1,0x5902, + 1,0x590A, + 1,0x5915, + 1,0x5927, + 1,0x5973, + 1,0x5B50, + 1,0x5B80, + 1,0x5BF8, + 1,0x5C0F, + 1,0x5C22, + 1,0x5C38, + 1,0x5C6E, + 1,0x5C71, + 1,0x5DDB, + 1,0x5DE5, + 1,0x5DF1, + 1,0x5DFE, + 1,0x5E72, + 1,0x5E7A, + 1,0x5E7F, + 1,0x5EF4, + 1,0x5EFE, + 1,0x5F0B, + 1,0x5F13, + 1,0x5F50, + 1,0x5F61, + 1,0x5F73, + 1,0x5FC3, + 1,0x6208, + 1,0x6236, + 1,0x624B, + 1,0x652F, + 1,0x6534, + 1,0x6587, + 1,0x6597, + 1,0x65A4, + 1,0x65B9, + 1,0x65E0, + 1,0x65E5, + 1,0x66F0, + 1,0x6708, + 1,0x6728, + 1,0x6B20, + 1,0x6B62, + 1,0x6B79, + 1,0x6BB3, + 1,0x6BCB, + 1,0x6BD4, + 1,0x6BDB, + 1,0x6C0F, + 1,0x6C14, + 1,0x6C34, + 1,0x706B, + 1,0x722A, + 1,0x7236, + 1,0x723B, + 1,0x723F, + 1,0x7247, + 1,0x7259, + 1,0x725B, + 1,0x72AC, + 1,0x7384, + 1,0x7389, + 1,0x74DC, + 1,0x74E6, + 1,0x7518, + 1,0x751F, + 1,0x7528, + 1,0x7530, + 1,0x758B, + 1,0x7592, + 1,0x7676, + 1,0x767D, + 1,0x76AE, + 1,0x76BF, + 1,0x76EE, + 1,0x77DB, + 1,0x77E2, + 1,0x77F3, + 1,0x793A, + 1,0x79B8, + 1,0x79BE, + 1,0x7A74, + 1,0x7ACB, + 1,0x7AF9, + 1,0x7C73, + 1,0x7CF8, + 1,0x7F36, + 1,0x7F51, + 1,0x7F8A, + 1,0x7FBD, + 1,0x8001, + 1,0x800C, + 1,0x8012, + 1,0x8033, + 1,0x807F, + 1,0x8089, + 1,0x81E3, + 1,0x81EA, + 1,0x81F3, + 1,0x81FC, + 1,0x820C, + 1,0x821B, + 1,0x821F, + 1,0x826E, + 1,0x8272, + 1,0x8278, + 1,0x864D, + 1,0x866B, + 1,0x8840, + 1,0x884C, + 1,0x8863, + 1,0x897E, + 1,0x898B, + 1,0x89D2, + 1,0x8A00, + 1,0x8C37, + 1,0x8C46, + 1,0x8C55, + 1,0x8C78, + 1,0x8C9D, + 1,0x8D64, + 1,0x8D70, + 1,0x8DB3, + 1,0x8EAB, + 1,0x8ECA, + 1,0x8F9B, + 1,0x8FB0, + 1,0x8FB5, + 1,0x9091, + 1,0x9149, + 1,0x91C6, + 1,0x91CC, + 1,0x91D1, + 1,0x9577, + 1,0x9580, + 1,0x961C, + 1,0x96B6, + 1,0x96B9, + 1,0x96E8, + 1,0x9751, + 1,0x975E, + 1,0x9762, + 1,0x9769, + 1,0x97CB, + 1,0x97ED, + 1,0x97F3, + 1,0x9801, + 1,0x98A8, + 1,0x98DB, + 1,0x98DF, + 1,0x9996, + 1,0x9999, + 1,0x99AC, + 1,0x9AA8, + 1,0x9AD8, + 1,0x9ADF, + 1,0x9B25, + 1,0x9B2F, + 1,0x9B32, + 1,0x9B3C, + 1,0x9B5A, + 1,0x9CE5, + 1,0x9E75, + 1,0x9E7F, + 1,0x9EA5, + 1,0x9EBB, + 1,0x9EC3, + 1,0x9ECD, + 1,0x9ED1, + 1,0x9EF9, + 1,0x9EFD, + 1,0x9F0E, + 1,0x9F13, + 1,0x9F20, + 1,0x9F3B, + 1,0x9F4A, + 1,0x9F52, + 1,0x9F8D, + 1,0x9F9C, + 1,0x9FA0, + 1, ' ', + 1,0x3012, + 1,0x5341, + 1,0x5344, + 1,0x5345, + 1,0x3042, + 1,0x3044, + 1,0x3046, + 1,0x3048, + 1,0x304A, + 1,0x3064, + 1,0x3084, + 1,0x3086, + 1,0x3088, + 1,0x308F, + 1,0x304B, + 1,0x3051, + 2, ' ',0x3099, + 2, ' ',0x309A, + 1, '=', + 1,0x30A2, + 1,0x30A4, + 1,0x30A6, + 1,0x30A8, + 1,0x30AA, + 1,0x30C4, + 1,0x30E4, + 1,0x30E6, + 1,0x30E8, + 1,0x30EF, + 1,0x30AB, + 1,0x30B1, + 1,0x1100, + 1,0x1101, + 1,0x11AA, + 1,0x1102, + 1,0x11AC, + 1,0x11AD, + 1,0x1103, + 1,0x1104, + 1,0x1105, + 1,0x11B0, + 1,0x11B1, + 1,0x11B2, + 1,0x11B3, + 1,0x11B4, + 1,0x11B5, + 1,0x111A, + 1,0x1106, + 1,0x1107, + 1,0x1108, + 1,0x1121, + 1,0x1109, + 1,0x110A, + 1,0x110B, + 1,0x110C, + 1,0x110D, + 1,0x110E, + 1,0x110F, + 1,0x1110, + 1,0x1111, + 1,0x1112, + 1,0x1161, + 1,0x1162, + 1,0x1163, + 1,0x1164, + 1,0x1165, + 1,0x1166, + 1,0x1167, + 1,0x1168, + 1,0x1169, + 1,0x116A, + 1,0x116B, + 1,0x116C, + 1,0x116D, + 1,0x116E, + 1,0x116F, + 1,0x1170, + 1,0x1171, + 1,0x1172, + 1,0x1173, + 1,0x1174, + 1,0x1175, + 1,0x1160, + 1,0x1114, + 1,0x1115, + 1,0x11C7, + 1,0x11C8, + 1,0x11CC, + 1,0x11CE, + 1,0x11D3, + 1,0x11D7, + 1,0x11D9, + 1,0x111C, + 1,0x11DD, + 1,0x11DF, + 1,0x111D, + 1,0x111E, + 1,0x1120, + 1,0x1122, + 1,0x1123, + 1,0x1127, + 1,0x1129, + 1,0x112B, + 1,0x112C, + 1,0x112D, + 1,0x112E, + 1,0x112F, + 1,0x1132, + 1,0x1136, + 1,0x1140, + 1,0x1147, + 1,0x114C, + 1,0x11F1, + 1,0x11F2, + 1,0x1157, + 1,0x1158, + 1,0x1159, + 1,0x1184, + 1,0x1185, + 1,0x1188, + 1,0x1191, + 1,0x1192, + 1,0x1194, + 1,0x119E, + 1,0x11A1, + 1,0x30AF, + 1,0x30B7, + 1,0x30B9, + 1,0x30C8, + 1,0x30CC, + 1,0x30CF, + 1,0x30D2, + 1,0x30D5, + 1,0x30D8, + 1,0x30DB, + 1,0x30E0, + 1,0x30E9, + 1,0x30EA, + 1,0x30EB, + 1,0x30EC, + 1,0x30ED, + 3, '(',0x1100, ')', + 3, '(',0x1102, ')', + 3, '(',0x1103, ')', + 3, '(',0x1105, ')', + 3, '(',0x1106, ')', + 3, '(',0x1107, ')', + 3, '(',0x1109, ')', + 3, '(',0x110B, ')', + 3, '(',0x110C, ')', + 3, '(',0x110E, ')', + 3, '(',0x110F, ')', + 3, '(',0x1110, ')', + 3, '(',0x1111, ')', + 3, '(',0x1112, ')', + 4, '(',0x1100,0x1161, ')', + 4, '(',0x1102,0x1161, ')', + 4, '(',0x1103,0x1161, ')', + 4, '(',0x1105,0x1161, ')', + 4, '(',0x1106,0x1161, ')', + 4, '(',0x1107,0x1161, ')', + 4, '(',0x1109,0x1161, ')', + 4, '(',0x110B,0x1161, ')', + 4, '(',0x110C,0x1161, ')', + 4, '(',0x110E,0x1161, ')', + 4, '(',0x110F,0x1161, ')', + 4, '(',0x1110,0x1161, ')', + 4, '(',0x1111,0x1161, ')', + 4, '(',0x1112,0x1161, ')', + 4, '(',0x110C,0x116E, ')', + 7, '(',0x110B,0x1169,0x110C,0x1165,0x11AB, ')', + 6, '(',0x110B,0x1169,0x1112,0x116E, ')', + 3, '(',0x4E00, ')', + 3, '(',0x4E8C, ')', + 3, '(',0x4E09, ')', + 3, '(',0x56DB, ')', + 3, '(',0x4E94, ')', + 3, '(',0x516D, ')', + 3, '(',0x4E03, ')', + 3, '(',0x516B, ')', + 3, '(',0x4E5D, ')', + 3, '(',0x5341, ')', + 3, '(',0x6708, ')', + 3, '(',0x706B, ')', + 3, '(',0x6C34, ')', + 3, '(',0x6728, ')', + 3, '(',0x91D1, ')', + 3, '(',0x571F, ')', + 3, '(',0x65E5, ')', + 3, '(',0x682A, ')', + 3, '(',0x6709, ')', + 3, '(',0x793E, ')', + 3, '(',0x540D, ')', + 3, '(',0x7279, ')', + 3, '(',0x8CA1, ')', + 3, '(',0x795D, ')', + 3, '(',0x52B4, ')', + 3, '(',0x4EE3, ')', + 3, '(',0x547C, ')', + 3, '(',0x5B66, ')', + 3, '(',0x76E3, ')', + 3, '(',0x4F01, ')', + 3, '(',0x8CC7, ')', + 3, '(',0x5354, ')', + 3, '(',0x796D, ')', + 3, '(',0x4F11, ')', + 3, '(',0x81EA, ')', + 3, '(',0x81F3, ')', + 3, 'P', 'T', 'E', + 4, '(', '2', '1', ')', + 4, '(', '2', '2', ')', + 4, '(', '2', '3', ')', + 4, '(', '2', '4', ')', + 4, '(', '2', '5', ')', + 4, '(', '2', '6', ')', + 4, '(', '2', '7', ')', + 4, '(', '2', '8', ')', + 4, '(', '2', '9', ')', + 4, '(', '3', '0', ')', + 4, '(', '3', '1', ')', + 4, '(', '3', '2', ')', + 4, '(', '3', '3', ')', + 4, '(', '3', '4', ')', + 4, '(', '3', '5', ')', + 3, '(',0x1100, ')', + 3, '(',0x1102, ')', + 3, '(',0x1103, ')', + 3, '(',0x1105, ')', + 3, '(',0x1106, ')', + 3, '(',0x1107, ')', + 3, '(',0x1109, ')', + 3, '(',0x110B, ')', + 3, '(',0x110C, ')', + 3, '(',0x110E, ')', + 3, '(',0x110F, ')', + 3, '(',0x1110, ')', + 3, '(',0x1111, ')', + 3, '(',0x1112, ')', + 4, '(',0x1100,0x1161, ')', + 4, '(',0x1102,0x1161, ')', + 4, '(',0x1103,0x1161, ')', + 4, '(',0x1105,0x1161, ')', + 4, '(',0x1106,0x1161, ')', + 4, '(',0x1107,0x1161, ')', + 4, '(',0x1109,0x1161, ')', + 4, '(',0x110B,0x1161, ')', + 4, '(',0x110C,0x1161, ')', + 4, '(',0x110E,0x1161, ')', + 4, '(',0x110F,0x1161, ')', + 4, '(',0x1110,0x1161, ')', + 4, '(',0x1111,0x1161, ')', + 4, '(',0x1112,0x1161, ')', + 7, '(',0x110E,0x1161,0x11B7,0x1100,0x1169, ')', + 6, '(',0x110C,0x116E,0x110B,0x1174, ')', + 3, '(',0x4E00, ')', + 3, '(',0x4E8C, ')', + 3, '(',0x4E09, ')', + 3, '(',0x56DB, ')', + 3, '(',0x4E94, ')', + 3, '(',0x516D, ')', + 3, '(',0x4E03, ')', + 3, '(',0x516B, ')', + 3, '(',0x4E5D, ')', + 3, '(',0x5341, ')', + 3, '(',0x6708, ')', + 3, '(',0x706B, ')', + 3, '(',0x6C34, ')', + 3, '(',0x6728, ')', + 3, '(',0x91D1, ')', + 3, '(',0x571F, ')', + 3, '(',0x65E5, ')', + 3, '(',0x682A, ')', + 3, '(',0x6709, ')', + 3, '(',0x793E, ')', + 3, '(',0x540D, ')', + 3, '(',0x7279, ')', + 3, '(',0x8CA1, ')', + 3, '(',0x795D, ')', + 3, '(',0x52B4, ')', + 3, '(',0x79D8, ')', + 3, '(',0x7537, ')', + 3, '(',0x5973, ')', + 3, '(',0x9069, ')', + 3, '(',0x512A, ')', + 3, '(',0x5370, ')', + 3, '(',0x6CE8, ')', + 3, '(',0x9805, ')', + 3, '(',0x4F11, ')', + 3, '(',0x5199, ')', + 3, '(',0x6B63, ')', + 3, '(',0x4E0A, ')', + 3, '(',0x4E2D, ')', + 3, '(',0x4E0B, ')', + 3, '(',0x5DE6, ')', + 3, '(',0x53F3, ')', + 3, '(',0x533B, ')', + 3, '(',0x5B97, ')', + 3, '(',0x5B66, ')', + 3, '(',0x76E3, ')', + 3, '(',0x4F01, ')', + 3, '(',0x8CC7, ')', + 3, '(',0x5354, ')', + 3, '(',0x591C, ')', + 4, '(', '3', '6', ')', + 4, '(', '3', '7', ')', + 4, '(', '3', '8', ')', + 4, '(', '3', '9', ')', + 4, '(', '4', '0', ')', + 4, '(', '4', '1', ')', + 4, '(', '4', '2', ')', + 4, '(', '4', '3', ')', + 4, '(', '4', '4', ')', + 4, '(', '4', '5', ')', + 4, '(', '4', '6', ')', + 4, '(', '4', '7', ')', + 4, '(', '4', '8', ')', + 4, '(', '4', '9', ')', + 4, '(', '5', '0', ')', + 2, '1',0x6708, + 2, '2',0x6708, + 2, '3',0x6708, + 2, '4',0x6708, + 2, '5',0x6708, + 2, '6',0x6708, + 2, '7',0x6708, + 2, '8',0x6708, + 2, '9',0x6708, + 3, '1', '0',0x6708, + 3, '1', '1',0x6708, + 3, '1', '2',0x6708, + 2, 'H', 'g', + 3, 'e', 'r', 'g', + 2, 'e', 'V', + 3, 'L', 'T', 'D', + 3, '(',0x30A2, ')', + 3, '(',0x30A4, ')', + 3, '(',0x30A6, ')', + 3, '(',0x30A8, ')', + 3, '(',0x30AA, ')', + 3, '(',0x30AB, ')', + 3, '(',0x30AD, ')', + 3, '(',0x30AF, ')', + 3, '(',0x30B1, ')', + 3, '(',0x30B3, ')', + 3, '(',0x30B5, ')', + 3, '(',0x30B7, ')', + 3, '(',0x30B9, ')', + 3, '(',0x30BB, ')', + 3, '(',0x30BD, ')', + 3, '(',0x30BF, ')', + 3, '(',0x30C1, ')', + 3, '(',0x30C4, ')', + 3, '(',0x30C6, ')', + 3, '(',0x30C8, ')', + 3, '(',0x30CA, ')', + 3, '(',0x30CB, ')', + 3, '(',0x30CC, ')', + 3, '(',0x30CD, ')', + 3, '(',0x30CE, ')', + 3, '(',0x30CF, ')', + 3, '(',0x30D2, ')', + 3, '(',0x30D5, ')', + 3, '(',0x30D8, ')', + 3, '(',0x30DB, ')', + 3, '(',0x30DE, ')', + 3, '(',0x30DF, ')', + 3, '(',0x30E0, ')', + 3, '(',0x30E1, ')', + 3, '(',0x30E2, ')', + 3, '(',0x30E4, ')', + 3, '(',0x30E6, ')', + 3, '(',0x30E8, ')', + 3, '(',0x30E9, ')', + 3, '(',0x30EA, ')', + 3, '(',0x30EB, ')', + 3, '(',0x30EC, ')', + 3, '(',0x30ED, ')', + 3, '(',0x30EF, ')', + 3, '(',0x30F0, ')', + 3, '(',0x30F1, ')', + 3, '(',0x30F2, ')', + 4,0x30A2,0x30D1,0x30FC,0x30C8, + 4,0x30A2,0x30EB,0x30D5,0x30A1, + 4,0x30A2,0x30F3,0x30DA,0x30A2, + 3,0x30A2,0x30FC,0x30EB, + 4,0x30A4,0x30CB,0x30F3,0x30B0, + 3,0x30A4,0x30F3,0x30C1, + 3,0x30A6,0x30A9,0x30F3, + 5,0x30A8,0x30B9,0x30AF,0x30FC,0x30C9, + 4,0x30A8,0x30FC,0x30AB,0x30FC, + 3,0x30AA,0x30F3,0x30B9, + 3,0x30AA,0x30FC,0x30E0, + 3,0x30AB,0x30A4,0x30EA, + 4,0x30AB,0x30E9,0x30C3,0x30C8, + 4,0x30AB,0x30ED,0x30EA,0x30FC, + 3,0x30AC,0x30ED,0x30F3, + 3,0x30AC,0x30F3,0x30DE, + 2,0x30AE,0x30AC, + 3,0x30AE,0x30CB,0x30FC, + 4,0x30AD,0x30E5,0x30EA,0x30FC, + 4,0x30AE,0x30EB,0x30C0,0x30FC, + 2,0x30AD,0x30ED, + 5,0x30AD,0x30ED,0x30B0,0x30E9,0x30E0, + 6,0x30AD,0x30ED,0x30E1,0x30FC,0x30C8,0x30EB, + 5,0x30AD,0x30ED,0x30EF,0x30C3,0x30C8, + 3,0x30B0,0x30E9,0x30E0, + 5,0x30B0,0x30E9,0x30E0,0x30C8,0x30F3, + 5,0x30AF,0x30EB,0x30BC,0x30A4,0x30ED, + 4,0x30AF,0x30ED,0x30FC,0x30CD, + 3,0x30B1,0x30FC,0x30B9, + 3,0x30B3,0x30EB,0x30CA, + 3,0x30B3,0x30FC,0x30DD, + 4,0x30B5,0x30A4,0x30AF,0x30EB, + 5,0x30B5,0x30F3,0x30C1,0x30FC,0x30E0, + 4,0x30B7,0x30EA,0x30F3,0x30B0, + 3,0x30BB,0x30F3,0x30C1, + 3,0x30BB,0x30F3,0x30C8, + 3,0x30C0,0x30FC,0x30B9, + 2,0x30C7,0x30B7, + 2,0x30C9,0x30EB, + 2,0x30C8,0x30F3, + 2,0x30CA,0x30CE, + 3,0x30CE,0x30C3,0x30C8, + 3,0x30CF,0x30A4,0x30C4, + 5,0x30D1,0x30FC,0x30BB,0x30F3,0x30C8, + 3,0x30D1,0x30FC,0x30C4, + 4,0x30D0,0x30FC,0x30EC,0x30EB, + 5,0x30D4,0x30A2,0x30B9,0x30C8,0x30EB, + 3,0x30D4,0x30AF,0x30EB, + 2,0x30D4,0x30B3, + 2,0x30D3,0x30EB, + 5,0x30D5,0x30A1,0x30E9,0x30C3,0x30C9, + 4,0x30D5,0x30A3,0x30FC,0x30C8, + 5,0x30D6,0x30C3,0x30B7,0x30A7,0x30EB, + 3,0x30D5,0x30E9,0x30F3, + 5,0x30D8,0x30AF,0x30BF,0x30FC,0x30EB, + 2,0x30DA,0x30BD, + 3,0x30DA,0x30CB,0x30D2, + 3,0x30D8,0x30EB,0x30C4, + 3,0x30DA,0x30F3,0x30B9, + 3,0x30DA,0x30FC,0x30B8, + 3,0x30D9,0x30FC,0x30BF, + 4,0x30DD,0x30A4,0x30F3,0x30C8, + 3,0x30DC,0x30EB,0x30C8, + 2,0x30DB,0x30F3, + 3,0x30DD,0x30F3,0x30C9, + 3,0x30DB,0x30FC,0x30EB, + 3,0x30DB,0x30FC,0x30F3, + 4,0x30DE,0x30A4,0x30AF,0x30ED, + 3,0x30DE,0x30A4,0x30EB, + 3,0x30DE,0x30C3,0x30CF, + 3,0x30DE,0x30EB,0x30AF, + 5,0x30DE,0x30F3,0x30B7,0x30E7,0x30F3, + 4,0x30DF,0x30AF,0x30ED,0x30F3, + 2,0x30DF,0x30EA, + 5,0x30DF,0x30EA,0x30D0,0x30FC,0x30EB, + 2,0x30E1,0x30AC, + 4,0x30E1,0x30AC,0x30C8,0x30F3, + 4,0x30E1,0x30FC,0x30C8,0x30EB, + 3,0x30E4,0x30FC,0x30C9, + 3,0x30E4,0x30FC,0x30EB, + 3,0x30E6,0x30A2,0x30F3, + 4,0x30EA,0x30C3,0x30C8,0x30EB, + 2,0x30EA,0x30E9, + 3,0x30EB,0x30D4,0x30FC, + 4,0x30EB,0x30FC,0x30D6,0x30EB, + 2,0x30EC,0x30E0, + 5,0x30EC,0x30F3,0x30C8,0x30B2,0x30F3, + 3,0x30EF,0x30C3,0x30C8, + 2, '0',0x70B9, + 2, '1',0x70B9, + 2, '2',0x70B9, + 2, '3',0x70B9, + 2, '4',0x70B9, + 2, '5',0x70B9, + 2, '6',0x70B9, + 2, '7',0x70B9, + 2, '8',0x70B9, + 2, '9',0x70B9, + 3, '1', '0',0x70B9, + 3, '1', '1',0x70B9, + 3, '1', '2',0x70B9, + 3, '1', '3',0x70B9, + 3, '1', '4',0x70B9, + 3, '1', '5',0x70B9, + 3, '1', '6',0x70B9, + 3, '1', '7',0x70B9, + 3, '1', '8',0x70B9, + 3, '1', '9',0x70B9, + 3, '2', '0',0x70B9, + 3, '2', '1',0x70B9, + 3, '2', '2',0x70B9, + 3, '2', '3',0x70B9, + 3, '2', '4',0x70B9, + 3, 'h', 'P', 'a', + 2, 'd', 'a', + 2, 'A', 'U', + 3, 'b', 'a', 'r', + 2, 'o', 'V', + 2, 'p', 'c', + 2, 'd', 'm', + 4, 'd', 'm', '^', '2', + 4, 'd', 'm', '^', '3', + 2, 'I', 'U', + 2,0x5E73,0x6210, + 2,0x662D,0x548C, + 2,0x5927,0x6B63, + 2,0x660E,0x6CBB, + 4,0x682A,0x5F0F,0x4F1A,0x793E, + 2, 'p', 'A', + 2, 'n', 'A', + 2,0x03BC, 'A', + 2, 'm', 'A', + 2, 'k', 'A', + 2, 'K', 'B', + 2, 'M', 'B', + 2, 'G', 'B', + 3, 'c', 'a', 'l', + 4, 'k', 'c', 'a', 'l', + 2, 'p', 'F', + 2, 'n', 'F', + 2,0x03BC, 'F', + 2,0x03BC, 'g', + 2, 'm', 'g', + 2, 'k', 'g', + 2, 'H', 'z', + 3, 'k', 'H', 'z', + 3, 'M', 'H', 'z', + 3, 'G', 'H', 'z', + 3, 'T', 'H', 'z', + 2,0x03BC, 'l', + 2, 'm', 'l', + 2, 'd', 'l', + 2, 'k', 'l', + 2, 'f', 'm', + 2, 'n', 'm', + 2,0x03BC, 'm', + 2, 'm', 'm', + 2, 'c', 'm', + 2, 'k', 'm', + 4, 'm', 'm', '^', '2', + 4, 'c', 'm', '^', '2', + 3, 'm', '^', '2', + 4, 'k', 'm', '^', '2', + 4, 'm', 'm', '^', '3', + 4, 'c', 'm', '^', '3', + 3, 'm', '^', '3', + 4, 'k', 'm', '^', '3', + 3, 'm', '/', 's', + 5, 'm', '/', 's', '^', '2', + 2, 'P', 'a', + 3, 'k', 'P', 'a', + 3, 'M', 'P', 'a', + 3, 'G', 'P', 'a', + 3, 'r', 'a', 'd', + 5, 'r', 'a', 'd', '/', 's', + 7, 'r', 'a', 'd', '/', 's', '^', '2', + 2, 'p', 's', + 2, 'n', 's', + 2,0x03BC, 's', + 2, 'm', 's', + 2, 'p', 'V', + 2, 'n', 'V', + 2,0x03BC, 'V', + 2, 'm', 'V', + 2, 'k', 'V', + 2, 'M', 'V', + 2, 'p', 'W', + 2, 'n', 'W', + 2,0x03BC, 'W', + 2, 'm', 'W', + 2, 'k', 'W', + 2, 'M', 'W', + 2, 'k',0x03A9, + 2, 'M',0x03A9, + 4, 'a', '.', 'm', '.', + 2, 'B', 'q', + 2, 'c', 'c', + 2, 'c', 'd', + 4, 'C', '/', 'k', 'g', + 3, 'C', 'o', '.', + 2, 'd', 'B', + 2, 'G', 'y', + 2, 'h', 'a', + 2, 'H', 'P', + 2, 'i', 'n', + 2, 'K', 'K', + 2, 'K', 'M', + 2, 'k', 't', + 2, 'l', 'm', + 2, 'l', 'n', + 3, 'l', 'o', 'g', + 2, 'l', 'x', + 2, 'm', 'b', + 3, 'm', 'i', 'l', + 3, 'm', 'o', 'l', + 2, 'P', 'H', + 4, 'p', '.', 'm', '.', + 3, 'P', 'P', 'M', + 2, 'P', 'R', + 2, 's', 'r', + 2, 'S', 'v', + 2, 'W', 'b', + 3, 'V', '/', 'm', + 3, 'A', '/', 'm', + 3, 'g', 'a', 'l', + 2, '1',0x65E5, + 2, '2',0x65E5, + 2, '3',0x65E5, + 2, '4',0x65E5, + 2, '5',0x65E5, + 2, '6',0x65E5, + 2, '7',0x65E5, + 2, '8',0x65E5, + 2, '9',0x65E5, + 3, '1', '0',0x65E5, + 3, '1', '1',0x65E5, + 3, '1', '2',0x65E5, + 3, '1', '3',0x65E5, + 3, '1', '4',0x65E5, + 3, '1', '5',0x65E5, + 3, '1', '6',0x65E5, + 3, '1', '7',0x65E5, + 3, '1', '8',0x65E5, + 3, '1', '9',0x65E5, + 3, '2', '0',0x65E5, + 3, '2', '1',0x65E5, + 3, '2', '2',0x65E5, + 3, '2', '3',0x65E5, + 3, '2', '4',0x65E5, + 3, '2', '5',0x65E5, + 3, '2', '6',0x65E5, + 3, '2', '7',0x65E5, + 3, '2', '8',0x65E5, + 3, '2', '9',0x65E5, + 3, '3', '0',0x65E5, + 3, '3', '1',0x65E5, + 1,0x8C48, + 1,0x66F4, + 1,0x8ECA, + 1,0x8CC8, + 1,0x6ED1, + 1,0x4E32, + 1,0x53E5, + 1,0x9F9C, + 1,0x9F9C, + 1,0x5951, + 1,0x91D1, + 1,0x5587, + 1,0x5948, + 1,0x61F6, + 1,0x7669, + 1,0x7F85, + 1,0x863F, + 1,0x87BA, + 1,0x88F8, + 1,0x908F, + 1,0x6A02, + 1,0x6D1B, + 1,0x70D9, + 1,0x73DE, + 1,0x843D, + 1,0x916A, + 1,0x99F1, + 1,0x4E82, + 1,0x5375, + 1,0x6B04, + 1,0x721B, + 1,0x862D, + 1,0x9E1E, + 1,0x5D50, + 1,0x6FEB, + 1,0x85CD, + 1,0x8964, + 1,0x62C9, + 1,0x81D8, + 1,0x881F, + 1,0x5ECA, + 1,0x6717, + 1,0x6D6A, + 1,0x72FC, + 1,0x90CE, + 1,0x4F86, + 1,0x51B7, + 1,0x52DE, + 1,0x64C4, + 1,0x6AD3, + 1,0x7210, + 1,0x76E7, + 1,0x8001, + 1,0x8606, + 1,0x865C, + 1,0x8DEF, + 1,0x9732, + 1,0x9B6F, + 1,0x9DFA, + 1,0x788C, + 1,0x797F, + 1,0x7DA0, + 1,0x83C9, + 1,0x9304, + 1,0x9E7F, + 1,0x8AD6, + 1,0x58DF, + 1,0x5F04, + 1,0x7C60, + 1,0x807E, + 1,0x7262, + 1,0x78CA, + 1,0x8CC2, + 1,0x96F7, + 1,0x58D8, + 1,0x5C62, + 1,0x6A13, + 1,0x6DDA, + 1,0x6F0F, + 1,0x7D2F, + 1,0x7E37, + 1,0x964B, + 1,0x52D2, + 1,0x808B, + 1,0x51DC, + 1,0x51CC, + 1,0x7A1C, + 1,0x7DBE, + 1,0x83F1, + 1,0x9675, + 1,0x8B80, + 1,0x62CF, + 1,0x6A02, + 1,0x8AFE, + 1,0x4E39, + 1,0x5BE7, + 1,0x6012, + 1,0x7387, + 1,0x7570, + 1,0x5317, + 1,0x78FB, + 1,0x4FBF, + 1,0x5FA9, + 1,0x4E0D, + 1,0x6CCC, + 1,0x6578, + 1,0x7D22, + 1,0x53C3, + 1,0x585E, + 1,0x7701, + 1,0x8449, + 1,0x8AAA, + 1,0x6BBA, + 1,0x8FB0, + 1,0x6C88, + 1,0x62FE, + 1,0x82E5, + 1,0x63A0, + 1,0x7565, + 1,0x4EAE, + 1,0x5169, + 1,0x51C9, + 1,0x6881, + 1,0x7CE7, + 1,0x826F, + 1,0x8AD2, + 1,0x91CF, + 1,0x52F5, + 1,0x5442, + 1,0x5973, + 1,0x5EEC, + 1,0x65C5, + 1,0x6FFE, + 1,0x792A, + 1,0x95AD, + 1,0x9A6A, + 1,0x9E97, + 1,0x9ECE, + 1,0x529B, + 1,0x66C6, + 1,0x6B77, + 1,0x8F62, + 1,0x5E74, + 1,0x6190, + 1,0x6200, + 1,0x649A, + 1,0x6F23, + 1,0x7149, + 1,0x7489, + 1,0x79CA, + 1,0x7DF4, + 1,0x806F, + 1,0x8F26, + 1,0x84EE, + 1,0x9023, + 1,0x934A, + 1,0x5217, + 1,0x52A3, + 1,0x54BD, + 1,0x70C8, + 1,0x88C2, + 1,0x8AAA, + 1,0x5EC9, + 1,0x5FF5, + 1,0x637B, + 1,0x6BAE, + 1,0x7C3E, + 1,0x7375, + 1,0x4EE4, + 1,0x56F9, + 1,0x5BE7, + 1,0x5DBA, + 1,0x601C, + 1,0x73B2, + 1,0x7469, + 1,0x7F9A, + 1,0x8046, + 1,0x9234, + 1,0x96F6, + 1,0x9748, + 1,0x9818, + 1,0x4F8B, + 1,0x79AE, + 1,0x91B4, + 1,0x96B8, + 1,0x60E1, + 1,0x4E86, + 1,0x50DA, + 1,0x5BEE, + 1,0x5C3F, + 1,0x6599, + 1,0x6A02, + 1,0x71CE, + 1,0x7642, + 1,0x84FC, + 1,0x907C, + 1,0x9F8D, + 1,0x6688, + 1,0x962E, + 1,0x5289, + 1,0x677B, + 1,0x67F3, + 1,0x6D41, + 1,0x6E9C, + 1,0x7409, + 1,0x7559, + 1,0x786B, + 1,0x7D10, + 1,0x985E, + 1,0x516D, + 1,0x622E, + 1,0x9678, + 1,0x502B, + 1,0x5D19, + 1,0x6DEA, + 1,0x8F2A, + 1,0x5F8B, + 1,0x6144, + 1,0x6817, + 1,0x7387, + 1,0x9686, + 1,0x5229, + 1,0x540F, + 1,0x5C65, + 1,0x6613, + 1,0x674E, + 1,0x68A8, + 1,0x6CE5, + 1,0x7406, + 1,0x75E2, + 1,0x7F79, + 1,0x88CF, + 1,0x88E1, + 1,0x91CC, + 1,0x96E2, + 1,0x533F, + 1,0x6EBA, + 1,0x541D, + 1,0x71D0, + 1,0x7498, + 1,0x85FA, + 1,0x96A3, + 1,0x9C57, + 1,0x9E9F, + 1,0x6797, + 1,0x6DCB, + 1,0x81E8, + 1,0x7ACB, + 1,0x7B20, + 1,0x7C92, + 1,0x72C0, + 1,0x7099, + 1,0x8B58, + 1,0x4EC0, + 1,0x8336, + 1,0x523A, + 1,0x5207, + 1,0x5EA6, + 1,0x62D3, + 1,0x7CD6, + 1,0x5B85, + 1,0x6D1E, + 1,0x66B4, + 1,0x8F3B, + 1,0x884C, + 1,0x964D, + 1,0x898B, + 1,0x5ED3, + 1,0x5140, + 1,0x55C0, + 1,0x585A, + 1,0x6674, + 1,0x51DE, + 1,0x732A, + 1,0x76CA, + 1,0x793C, + 1,0x795E, + 1,0x7965, + 1,0x798F, + 1,0x9756, + 1,0x7CBE, + 1,0x7FBD, + 1,0x8612, + 1,0x8AF8, + 1,0x9038, + 1,0x90FD, + 1,0x98EF, + 1,0x98FC, + 1,0x9928, + 1,0x9DB4, + 1,0x4FAE, + 1,0x50E7, + 1,0x514D, + 1,0x52C9, + 1,0x52E4, + 1,0x5351, + 1,0x559D, + 1,0x5606, + 1,0x5668, + 1,0x5840, + 1,0x58A8, + 1,0x5C64, + 1,0x5C6E, + 1,0x6094, + 1,0x6168, + 1,0x618E, + 1,0x61F2, + 1,0x654F, + 1,0x65E2, + 1,0x6691, + 1,0x6885, + 1,0x6D77, + 1,0x6E1A, + 1,0x6F22, + 1,0x716E, + 1,0x722B, + 1,0x7422, + 1,0x7891, + 1,0x793E, + 1,0x7949, + 1,0x7948, + 1,0x7950, + 1,0x7956, + 1,0x795D, + 1,0x798D, + 1,0x798E, + 1,0x7A40, + 1,0x7A81, + 1,0x7BC0, + 1,0x7DF4, + 1,0x7E09, + 1,0x7E41, + 1,0x7F72, + 1,0x8005, + 1,0x81ED, + 1,0x8279, + 1,0x8279, + 1,0x8457, + 1,0x8910, + 1,0x8996, + 1,0x8B01, + 1,0x8B39, + 1,0x8CD3, + 1,0x8D08, + 1,0x8FB6, + 1,0x9038, + 1,0x96E3, + 1,0x97FF, + 1,0x983B, + 2, 'f', 'f', + 2, 'f', 'i', + 2, 'f', 'l', + 3, 'f', 'f', 'i', + 3, 'f', 'f', 'l', + 2,0x017F, 't', + 2, 's', 't', + 2,0x0574,0x0576, + 2,0x0574,0x0565, + 2,0x0574,0x056B, + 2,0x057E,0x0576, + 2,0x0574,0x056D, + 1,0x05E2, + 1,0x05D0, + 1,0x05D3, + 1,0x05D4, + 1,0x05DB, + 1,0x05DC, + 1,0x05DD, + 1,0x05E8, + 1,0x05EA, + 1, '+', + 2,0x05D0,0x05DC, + 1,0x203E, + 1,0x203E, + 1,0x203E, + 1,0x203E, + 1, '_', + 1, '_', + 1, '_', + 1, ',', + 1,0x3001, + 1, '.', + 1, ';', + 1, ':', + 1, '?', + 1, '!', + 1,0x2014, + 1, '(', + 1, ')', + 1, '{', + 1, '}', + 1,0x3014, + 1,0x3015, + 1, '#', + 1, '&', + 1, '*', + 1, '+', + 1, '-', + 1, '<', + 1, '>', + 1, '=', + 1,'\\', + 1, '$', + 1, '%', + 1, '@', + 1, '!', + 1, '"', + 1, '#', + 1, '$', + 1, '%', + 1, '&', + 1,'\'', + 1, '(', + 1, ')', + 1, '*', + 1, '+', + 1, ',', + 1, '-', + 1, '.', + 1, '/', + 1, '0', + 1, '1', + 1, '2', + 1, '3', + 1, '4', + 1, '5', + 1, '6', + 1, '7', + 1, '8', + 1, '9', + 1, ':', + 1, ';', + 1, '<', + 1, '=', + 1, '>', + 1, '?', + 1, '@', + 1, 'A', + 1, 'B', + 1, 'C', + 1, 'D', + 1, 'E', + 1, 'F', + 1, 'G', + 1, 'H', + 1, 'I', + 1, 'J', + 1, 'K', + 1, 'L', + 1, 'M', + 1, 'N', + 1, 'O', + 1, 'P', + 1, 'Q', + 1, 'R', + 1, 'S', + 1, 'T', + 1, 'U', + 1, 'V', + 1, 'W', + 1, 'X', + 1, 'Y', + 1, 'Z', + 1, '[', + 1,'\\', + 1, ']', + 1, '^', + 1, '_', + 1, '`', + 1, 'a', + 1, 'b', + 1, 'c', + 1, 'd', + 1, 'e', + 1, 'f', + 1, 'g', + 1, 'h', + 1, 'i', + 1, 'j', + 1, 'k', + 1, 'l', + 1, 'm', + 1, 'n', + 1, 'o', + 1, 'p', + 1, 'q', + 1, 'r', + 1, 's', + 1, 't', + 1, 'u', + 1, 'v', + 1, 'w', + 1, 'x', + 1, 'y', + 1, 'z', + 1, '{', + 1, '|', + 1, '}', + 1, '~', + 1,0x2985, + 1,0x2986, + 1,0x3002, + 1,0x300C, + 1,0x300D, + 1,0x3001, + 1,0x30FB, + 1,0x30F2, + 1,0x30A1, + 1,0x30A3, + 1,0x30A5, + 1,0x30A7, + 1,0x30A9, + 1,0x30E3, + 1,0x30E5, + 1,0x30E7, + 1,0x30C3, + 1,0x30FC, + 1,0x30A2, + 1,0x30A4, + 1,0x30A6, + 1,0x30A8, + 1,0x30AA, + 1,0x30AB, + 1,0x30AD, + 1,0x30AF, + 1,0x30B1, + 1,0x30B3, + 1,0x30B5, + 1,0x30B7, + 1,0x30B9, + 1,0x30BB, + 1,0x30BD, + 1,0x30BF, + 1,0x30C1, + 1,0x30C4, + 1,0x30C6, + 1,0x30C8, + 1,0x30CA, + 1,0x30CB, + 1,0x30CC, + 1,0x30CD, + 1,0x30CE, + 1,0x30CF, + 1,0x30D2, + 1,0x30D5, + 1,0x30D8, + 1,0x30DB, + 1,0x30DE, + 1,0x30DF, + 1,0x30E0, + 1,0x30E1, + 1,0x30E2, + 1,0x30E4, + 1,0x30E6, + 1,0x30E8, + 1,0x30E9, + 1,0x30EA, + 1,0x30EB, + 1,0x30EC, + 1,0x30ED, + 1,0x30EF, + 1,0x30F3, + 1,0x3099, + 1,0x309A, + 1,0x3164, + 1,0x3131, + 1,0x3132, + 1,0x3133, + 1,0x3134, + 1,0x3135, + 1,0x3136, + 1,0x3137, + 1,0x3138, + 1,0x3139, + 1,0x313A, + 1,0x313B, + 1,0x313C, + 1,0x313D, + 1,0x313E, + 1,0x313F, + 1,0x3140, + 1,0x3141, + 1,0x3142, + 1,0x3143, + 1,0x3144, + 1,0x3145, + 1,0x3146, + 1,0x3147, + 1,0x3148, + 1,0x3149, + 1,0x314A, + 1,0x314B, + 1,0x314C, + 1,0x314D, + 1,0x314E, + 1,0x314F, + 1,0x3150, + 1,0x3151, + 1,0x3152, + 1,0x3153, + 1,0x3154, + 1,0x3155, + 1,0x3156, + 1,0x3157, + 1,0x3158, + 1,0x3159, + 1,0x315A, + 1,0x315B, + 1,0x315C, + 1,0x315D, + 1,0x315E, + 1,0x315F, + 1,0x3160, + 1,0x3161, + 1,0x3162, + 1,0x3163, + 1,0xA2, + 1,0xA3, + 1,0xAC, + 1,0xAF, + 1,0xA6, + 1,0xA5, + 1,0x20A9, + 1,0x2502, + 1,0x2190, + 1,0x2191, + 1,0x2192, + 1,0x2193, + 1,0x25A0, + 1,0x25CB, + 1, 'A', + 1, 'B', + 1, 'C', + 1, 'D', + 1, 'E', + 1, 'F', + 1, 'G', + 1, 'H', + 1, 'I', + 1, 'J', + 1, 'K', + 1, 'L', + 1, 'M', + 1, 'N', + 1, 'O', + 1, 'P', + 1, 'Q', + 1, 'R', + 1, 'S', + 1, 'T', + 1, 'U', + 1, 'V', + 1, 'W', + 1, 'X', + 1, 'Y', + 1, 'Z', + 1, 'a', + 1, 'b', + 1, 'c', + 1, 'd', + 1, 'e', + 1, 'f', + 1, 'g', + 1, 'h', + 1, 'i', + 1, 'j', + 1, 'k', + 1, 'l', + 1, 'm', + 1, 'n', + 1, 'o', + 1, 'p', + 1, 'q', + 1, 'r', + 1, 's', + 1, 't', + 1, 'u', + 1, 'v', + 1, 'w', + 1, 'x', + 1, 'y', + 1, 'z', + 1, 'A', + 1, 'B', + 1, 'C', + 1, 'D', + 1, 'E', + 1, 'F', + 1, 'G', + 1, 'H', + 1, 'I', + 1, 'J', + 1, 'K', + 1, 'L', + 1, 'M', + 1, 'N', + 1, 'O', + 1, 'P', + 1, 'Q', + 1, 'R', + 1, 'S', + 1, 'T', + 1, 'U', + 1, 'V', + 1, 'W', + 1, 'X', + 1, 'Y', + 1, 'Z', + 1, 'a', + 1, 'b', + 1, 'c', + 1, 'd', + 1, 'e', + 1, 'f', + 1, 'g', + 1, 'i', + 1, 'j', + 1, 'k', + 1, 'l', + 1, 'm', + 1, 'n', + 1, 'o', + 1, 'p', + 1, 'q', + 1, 'r', + 1, 's', + 1, 't', + 1, 'u', + 1, 'v', + 1, 'w', + 1, 'x', + 1, 'y', + 1, 'z', + 1, 'A', + 1, 'B', + 1, 'C', + 1, 'D', + 1, 'E', + 1, 'F', + 1, 'G', + 1, 'H', + 1, 'I', + 1, 'J', + 1, 'K', + 1, 'L', + 1, 'M', + 1, 'N', + 1, 'O', + 1, 'P', + 1, 'Q', + 1, 'R', + 1, 'S', + 1, 'T', + 1, 'U', + 1, 'V', + 1, 'W', + 1, 'X', + 1, 'Y', + 1, 'Z', + 1, 'a', + 1, 'b', + 1, 'c', + 1, 'd', + 1, 'e', + 1, 'f', + 1, 'g', + 1, 'h', + 1, 'i', + 1, 'j', + 1, 'k', + 1, 'l', + 1, 'm', + 1, 'n', + 1, 'o', + 1, 'p', + 1, 'q', + 1, 'r', + 1, 's', + 1, 't', + 1, 'u', + 1, 'v', + 1, 'w', + 1, 'x', + 1, 'y', + 1, 'z', + 1, 'A', + 1, 'C', + 1, 'D', + 1, 'G', + 1, 'J', + 1, 'K', + 1, 'N', + 1, 'O', + 1, 'P', + 1, 'Q', + 1, 'S', + 1, 'T', + 1, 'U', + 1, 'V', + 1, 'W', + 1, 'X', + 1, 'Y', + 1, 'Z', + 1, 'a', + 1, 'b', + 1, 'c', + 1, 'd', + 1, 'f', + 1, 'h', + 1, 'i', + 1, 'j', + 1, 'k', + 1, 'l', + 1, 'm', + 1, 'n', + 1, 'p', + 1, 'q', + 1, 'r', + 1, 's', + 1, 't', + 1, 'u', + 1, 'v', + 1, 'w', + 1, 'x', + 1, 'y', + 1, 'z', + 1, 'A', + 1, 'B', + 1, 'C', + 1, 'D', + 1, 'E', + 1, 'F', + 1, 'G', + 1, 'H', + 1, 'I', + 1, 'J', + 1, 'K', + 1, 'L', + 1, 'M', + 1, 'N', + 1, 'O', + 1, 'P', + 1, 'Q', + 1, 'R', + 1, 'S', + 1, 'T', + 1, 'U', + 1, 'V', + 1, 'W', + 1, 'X', + 1, 'Y', + 1, 'Z', + 1, 'a', + 1, 'b', + 1, 'c', + 1, 'd', + 1, 'e', + 1, 'f', + 1, 'g', + 1, 'h', + 1, 'i', + 1, 'j', + 1, 'k', + 1, 'l', + 1, 'm', + 1, 'n', + 1, 'o', + 1, 'p', + 1, 'q', + 1, 'r', + 1, 's', + 1, 't', + 1, 'u', + 1, 'v', + 1, 'w', + 1, 'x', + 1, 'y', + 1, 'z', + 1, 'A', + 1, 'B', + 1, 'D', + 1, 'E', + 1, 'F', + 1, 'G', + 1, 'J', + 1, 'K', + 1, 'L', + 1, 'M', + 1, 'N', + 1, 'O', + 1, 'P', + 1, 'Q', + 1, 'S', + 1, 'T', + 1, 'U', + 1, 'V', + 1, 'W', + 1, 'X', + 1, 'Y', + 1, 'a', + 1, 'b', + 1, 'c', + 1, 'd', + 1, 'e', + 1, 'f', + 1, 'g', + 1, 'h', + 1, 'i', + 1, 'j', + 1, 'k', + 1, 'l', + 1, 'm', + 1, 'n', + 1, 'o', + 1, 'p', + 1, 'q', + 1, 'r', + 1, 's', + 1, 't', + 1, 'u', + 1, 'v', + 1, 'w', + 1, 'x', + 1, 'y', + 1, 'z', + 1, 'A', + 1, 'B', + 1, 'D', + 1, 'E', + 1, 'F', + 1, 'G', + 1, 'I', + 1, 'J', + 1, 'K', + 1, 'L', + 1, 'M', + 1, 'O', + 1, 'S', + 1, 'T', + 1, 'U', + 1, 'V', + 1, 'W', + 1, 'X', + 1, 'Y', + 1, 'a', + 1, 'b', + 1, 'c', + 1, 'd', + 1, 'e', + 1, 'f', + 1, 'g', + 1, 'h', + 1, 'i', + 1, 'j', + 1, 'k', + 1, 'l', + 1, 'm', + 1, 'n', + 1, 'o', + 1, 'p', + 1, 'q', + 1, 'r', + 1, 's', + 1, 't', + 1, 'u', + 1, 'v', + 1, 'w', + 1, 'x', + 1, 'y', + 1, 'z', + 1, 'A', + 1, 'B', + 1, 'C', + 1, 'D', + 1, 'E', + 1, 'F', + 1, 'G', + 1, 'H', + 1, 'I', + 1, 'J', + 1, 'K', + 1, 'L', + 1, 'M', + 1, 'N', + 1, 'O', + 1, 'P', + 1, 'Q', + 1, 'R', + 1, 'S', + 1, 'T', + 1, 'U', + 1, 'V', + 1, 'W', + 1, 'X', + 1, 'Y', + 1, 'Z', + 1, 'a', + 1, 'b', + 1, 'c', + 1, 'd', + 1, 'e', + 1, 'f', + 1, 'g', + 1, 'h', + 1, 'i', + 1, 'j', + 1, 'k', + 1, 'l', + 1, 'm', + 1, 'n', + 1, 'o', + 1, 'p', + 1, 'q', + 1, 'r', + 1, 's', + 1, 't', + 1, 'u', + 1, 'v', + 1, 'w', + 1, 'x', + 1, 'y', + 1, 'z', + 1, 'A', + 1, 'B', + 1, 'C', + 1, 'D', + 1, 'E', + 1, 'F', + 1, 'G', + 1, 'H', + 1, 'I', + 1, 'J', + 1, 'K', + 1, 'L', + 1, 'M', + 1, 'N', + 1, 'O', + 1, 'P', + 1, 'Q', + 1, 'R', + 1, 'S', + 1, 'T', + 1, 'U', + 1, 'V', + 1, 'W', + 1, 'X', + 1, 'Y', + 1, 'Z', + 1, 'a', + 1, 'b', + 1, 'c', + 1, 'd', + 1, 'e', + 1, 'f', + 1, 'g', + 1, 'h', + 1, 'i', + 1, 'j', + 1, 'k', + 1, 'l', + 1, 'm', + 1, 'n', + 1, 'o', + 1, 'p', + 1, 'q', + 1, 'r', + 1, 's', + 1, 't', + 1, 'u', + 1, 'v', + 1, 'w', + 1, 'x', + 1, 'y', + 1, 'z', + 1, 'A', + 1, 'B', + 1, 'C', + 1, 'D', + 1, 'E', + 1, 'F', + 1, 'G', + 1, 'H', + 1, 'I', + 1, 'J', + 1, 'K', + 1, 'L', + 1, 'M', + 1, 'N', + 1, 'O', + 1, 'P', + 1, 'Q', + 1, 'R', + 1, 'S', + 1, 'T', + 1, 'U', + 1, 'V', + 1, 'W', + 1, 'X', + 1, 'Y', + 1, 'Z', + 1, 'a', + 1, 'b', + 1, 'c', + 1, 'd', + 1, 'e', + 1, 'f', + 1, 'g', + 1, 'h', + 1, 'i', + 1, 'j', + 1, 'k', + 1, 'l', + 1, 'm', + 1, 'n', + 1, 'o', + 1, 'p', + 1, 'q', + 1, 'r', + 1, 's', + 1, 't', + 1, 'u', + 1, 'v', + 1, 'w', + 1, 'x', + 1, 'y', + 1, 'z', + 1, 'A', + 1, 'B', + 1, 'C', + 1, 'D', + 1, 'E', + 1, 'F', + 1, 'G', + 1, 'H', + 1, 'I', + 1, 'J', + 1, 'K', + 1, 'L', + 1, 'M', + 1, 'N', + 1, 'O', + 1, 'P', + 1, 'Q', + 1, 'R', + 1, 'S', + 1, 'T', + 1, 'U', + 1, 'V', + 1, 'W', + 1, 'X', + 1, 'Y', + 1, 'Z', + 1, 'a', + 1, 'b', + 1, 'c', + 1, 'd', + 1, 'e', + 1, 'f', + 1, 'g', + 1, 'h', + 1, 'i', + 1, 'j', + 1, 'k', + 1, 'l', + 1, 'm', + 1, 'n', + 1, 'o', + 1, 'p', + 1, 'q', + 1, 'r', + 1, 's', + 1, 't', + 1, 'u', + 1, 'v', + 1, 'w', + 1, 'x', + 1, 'y', + 1, 'z', + 1, 'A', + 1, 'B', + 1, 'C', + 1, 'D', + 1, 'E', + 1, 'F', + 1, 'G', + 1, 'H', + 1, 'I', + 1, 'J', + 1, 'K', + 1, 'L', + 1, 'M', + 1, 'N', + 1, 'O', + 1, 'P', + 1, 'Q', + 1, 'R', + 1, 'S', + 1, 'T', + 1, 'U', + 1, 'V', + 1, 'W', + 1, 'X', + 1, 'Y', + 1, 'Z', + 1, 'a', + 1, 'b', + 1, 'c', + 1, 'd', + 1, 'e', + 1, 'f', + 1, 'g', + 1, 'h', + 1, 'i', + 1, 'j', + 1, 'k', + 1, 'l', + 1, 'm', + 1, 'n', + 1, 'o', + 1, 'p', + 1, 'q', + 1, 'r', + 1, 's', + 1, 't', + 1, 'u', + 1, 'v', + 1, 'w', + 1, 'x', + 1, 'y', + 1, 'z', + 1, 'A', + 1, 'B', + 1, 'C', + 1, 'D', + 1, 'E', + 1, 'F', + 1, 'G', + 1, 'H', + 1, 'I', + 1, 'J', + 1, 'K', + 1, 'L', + 1, 'M', + 1, 'N', + 1, 'O', + 1, 'P', + 1, 'Q', + 1, 'R', + 1, 'S', + 1, 'T', + 1, 'U', + 1, 'V', + 1, 'W', + 1, 'X', + 1, 'Y', + 1, 'Z', + 1, 'a', + 1, 'b', + 1, 'c', + 1, 'd', + 1, 'e', + 1, 'f', + 1, 'g', + 1, 'h', + 1, 'i', + 1, 'j', + 1, 'k', + 1, 'l', + 1, 'm', + 1, 'n', + 1, 'o', + 1, 'p', + 1, 'q', + 1, 'r', + 1, 's', + 1, 't', + 1, 'u', + 1, 'v', + 1, 'w', + 1, 'x', + 1, 'y', + 1, 'z', + 1,0x0391, + 1,0x0392, + 1,0x0393, + 1,0x0394, + 1,0x0395, + 1,0x0396, + 1,0x0397, + 1,0x0398, + 1,0x0399, + 1,0x039A, + 1,0x039B, + 1,0x039C, + 1,0x039D, + 1,0x039E, + 1,0x039F, + 1,0x03A0, + 1,0x03A1, + 1,0x03F4, + 1,0x03A3, + 1,0x03A4, + 1,0x03A5, + 1,0x03A6, + 1,0x03A7, + 1,0x03A8, + 1,0x03A9, + 1,0x2207, + 1,0x03B1, + 1,0x03B2, + 1,0x03B3, + 1,0x03B4, + 1,0x03B5, + 1,0x03B6, + 1,0x03B7, + 1,0x03B8, + 1,0x03B9, + 1,0x03BA, + 1,0x03BB, + 1,0x03BC, + 1,0x03BD, + 1,0x03BE, + 1,0x03BF, + 1,0x03C0, + 1,0x03C1, + 1,0x03C2, + 1,0x03C3, + 1,0x03C4, + 1,0x03C5, + 1,0x03C6, + 1,0x03C7, + 1,0x03C8, + 1,0x03C9, + 1,0x2202, + 1,0x03F5, + 1,0x03D1, + 1,0x03F0, + 1,0x03D5, + 1,0x03F1, + 1,0x03D6, + 1,0x0391, + 1,0x0392, + 1,0x0393, + 1,0x0394, + 1,0x0395, + 1,0x0396, + 1,0x0397, + 1,0x0398, + 1,0x0399, + 1,0x039A, + 1,0x039B, + 1,0x039C, + 1,0x039D, + 1,0x039E, + 1,0x039F, + 1,0x03A0, + 1,0x03A1, + 1,0x03F4, + 1,0x03A3, + 1,0x03A4, + 1,0x03A5, + 1,0x03A6, + 1,0x03A7, + 1,0x03A8, + 1,0x03A9, + 1,0x2207, + 1,0x03B1, + 1,0x03B2, + 1,0x03B3, + 1,0x03B4, + 1,0x03B5, + 1,0x03B6, + 1,0x03B7, + 1,0x03B8, + 1,0x03B9, + 1,0x03BA, + 1,0x03BB, + 1,0x03BC, + 1,0x03BD, + 1,0x03BE, + 1,0x03BF, + 1,0x03C0, + 1,0x03C1, + 1,0x03C2, + 1,0x03C3, + 1,0x03C4, + 1,0x03C5, + 1,0x03C6, + 1,0x03C7, + 1,0x03C8, + 1,0x03C9, + 1,0x2202, + 1,0x03F5, + 1,0x03D1, + 1,0x03F0, + 1,0x03D5, + 1,0x03F1, + 1,0x03D6, + 1,0x0391, + 1,0x0392, + 1,0x0393, + 1,0x0394, + 1,0x0395, + 1,0x0396, + 1,0x0397, + 1,0x0398, + 1,0x0399, + 1,0x039A, + 1,0x039B, + 1,0x039C, + 1,0x039D, + 1,0x039E, + 1,0x039F, + 1,0x03A0, + 1,0x03A1, + 1,0x03F4, + 1,0x03A3, + 1,0x03A4, + 1,0x03A5, + 1,0x03A6, + 1,0x03A7, + 1,0x03A8, + 1,0x03A9, + 1,0x2207, + 1,0x03B1, + 1,0x03B2, + 1,0x03B3, + 1,0x03B4, + 1,0x03B5, + 1,0x03B6, + 1,0x03B7, + 1,0x03B8, + 1,0x03B9, + 1,0x03BA, + 1,0x03BB, + 1,0x03BC, + 1,0x03BD, + 1,0x03BE, + 1,0x03BF, + 1,0x03C0, + 1,0x03C1, + 1,0x03C2, + 1,0x03C3, + 1,0x03C4, + 1,0x03C5, + 1,0x03C6, + 1,0x03C7, + 1,0x03C8, + 1,0x03C9, + 1,0x2202, + 1,0x03F5, + 1,0x03D1, + 1,0x03F0, + 1,0x03D5, + 1,0x03F1, + 1,0x03D6, + 1,0x0391, + 1,0x0392, + 1,0x0393, + 1,0x0394, + 1,0x0395, + 1,0x0396, + 1,0x0397, + 1,0x0398, + 1,0x0399, + 1,0x039A, + 1,0x039B, + 1,0x039C, + 1,0x039D, + 1,0x039E, + 1,0x039F, + 1,0x03A0, + 1,0x03A1, + 1,0x03F4, + 1,0x03A3, + 1,0x03A4, + 1,0x03A5, + 1,0x03A6, + 1,0x03A7, + 1,0x03A8, + 1,0x03A9, + 1,0x2207, + 1,0x03B1, + 1,0x03B2, + 1,0x03B3, + 1,0x03B4, + 1,0x03B5, + 1,0x03B6, + 1,0x03B7, + 1,0x03B8, + 1,0x03B9, + 1,0x03BA, + 1,0x03BB, + 1,0x03BC, + 1,0x03BD, + 1,0x03BE, + 1,0x03BF, + 1,0x03C0, + 1,0x03C1, + 1,0x03C2, + 1,0x03C3, + 1,0x03C4, + 1,0x03C5, + 1,0x03C6, + 1,0x03C7, + 1,0x03C8, + 1,0x03C9, + 1,0x2202, + 1,0x03F5, + 1,0x03D1, + 1,0x03F0, + 1,0x03D5, + 1,0x03F1, + 1,0x03D6, + 1,0x0391, + 1,0x0392, + 1,0x0393, + 1,0x0394, + 1,0x0395, + 1,0x0396, + 1,0x0397, + 1,0x0398, + 1,0x0399, + 1,0x039A, + 1,0x039B, + 1,0x039C, + 1,0x039D, + 1,0x039E, + 1,0x039F, + 1,0x03A0, + 1,0x03A1, + 1,0x03F4, + 1,0x03A3, + 1,0x03A4, + 1,0x03A5, + 1,0x03A6, + 1,0x03A7, + 1,0x03A8, + 1,0x03A9, + 1,0x2207, + 1,0x03B1, + 1,0x03B2, + 1,0x03B3, + 1,0x03B4, + 1,0x03B5, + 1,0x03B6, + 1,0x03B7, + 1,0x03B8, + 1,0x03B9, + 1,0x03BA, + 1,0x03BB, + 1,0x03BC, + 1,0x03BD, + 1,0x03BE, + 1,0x03BF, + 1,0x03C0, + 1,0x03C1, + 1,0x03C2, + 1,0x03C3, + 1,0x03C4, + 1,0x03C5, + 1,0x03C6, + 1,0x03C7, + 1,0x03C8, + 1,0x03C9, + 1,0x2202, + 1,0x03F5, + 1,0x03D1, + 1,0x03F0, + 1,0x03D5, + 1,0x03F1, + 1,0x03D6, + 1, '0', + 1, '1', + 1, '2', + 1, '3', + 1, '4', + 1, '5', + 1, '6', + 1, '7', + 1, '8', + 1, '9', + 1, '0', + 1, '1', + 1, '2', + 1, '3', + 1, '4', + 1, '5', + 1, '6', + 1, '7', + 1, '8', + 1, '9', + 1, '0', + 1, '1', + 1, '2', + 1, '3', + 1, '4', + 1, '5', + 1, '6', + 1, '7', + 1, '8', + 1, '9', + 1, '0', + 1, '1', + 1, '2', + 1, '3', + 1, '4', + 1, '5', + 1, '6', + 1, '7', + 1, '8', + 1, '9', + 1, '0', + 1, '1', + 1, '2', + 1, '3', + 1, '4', + 1, '5', + 1, '6', + 1, '7', + 1, '8', + 1, '9', + 1,0x4E3D, + 1,0x4E38, + 1,0x4E41, + 1,0x20122, + 1,0x4F60, + 1,0x4FAE, + 1,0x4FBB, + 1,0x5002, + 1,0x507A, + 1,0x5099, + 1,0x50E7, + 1,0x50CF, + 1,0x349E, + 1,0x2063A, + 1,0x514D, + 1,0x5154, + 1,0x5164, + 1,0x5177, + 1,0x2051C, + 1,0x34B9, + 1,0x5167, + 1,0x518D, + 1,0x2054B, + 1,0x5197, + 1,0x51A4, + 1,0x4ECC, + 1,0x51AC, + 1,0x51B5, + 1,0x291DF, + 1,0x51F5, + 1,0x5203, + 1,0x34DF, + 1,0x523B, + 1,0x5246, + 1,0x5272, + 1,0x5277, + 1,0x3515, + 1,0x52C7, + 1,0x52C9, + 1,0x52E4, + 1,0x52FA, + 1,0x5305, + 1,0x5306, + 1,0x5317, + 1,0x5349, + 1,0x5351, + 1,0x535A, + 1,0x5373, + 1,0x537D, + 1,0x537F, + 1,0x537F, + 1,0x537F, + 1,0x20A2C, + 1,0x7070, + 1,0x53CA, + 1,0x53DF, + 1,0x20B63, + 1,0x53EB, + 1,0x53F1, + 1,0x5406, + 1,0x549E, + 1,0x5438, + 1,0x5448, + 1,0x5468, + 1,0x54A2, + 1,0x54F6, + 1,0x5510, + 1,0x5553, + 1,0x5563, + 1,0x5584, + 1,0x5584, + 1,0x5599, + 1,0x55AB, + 1,0x55B3, + 1,0x55C2, + 1,0x5716, + 1,0x5606, + 1,0x5717, + 1,0x5651, + 1,0x5674, + 1,0x5207, + 1,0x58EE, + 1,0x57CE, + 1,0x57F4, + 1,0x580D, + 1,0x578B, + 1,0x5832, + 1,0x5831, + 1,0x58AC, + 1,0x214E4, + 1,0x58F2, + 1,0x58F7, + 1,0x5906, + 1,0x591A, + 1,0x5922, + 1,0x5962, + 1,0x216A8, + 1,0x216EA, + 1,0x59EC, + 1,0x5A1B, + 1,0x5A27, + 1,0x59D8, + 1,0x5A66, + 1,0x36EE, + 1,0x36FC, + 1,0x5B08, + 1,0x5B3E, + 1,0x5B3E, + 1,0x219C8, + 1,0x5BC3, + 1,0x5BD8, + 1,0x5BE7, + 1,0x5BF3, + 1,0x21B18, + 1,0x5BFF, + 1,0x5C06, + 1,0x5F53, + 1,0x5C22, + 1,0x3781, + 1,0x5C60, + 1,0x5C6E, + 1,0x5CC0, + 1,0x5C8D, + 1,0x21DE4, + 1,0x5D43, + 1,0x21DE6, + 1,0x5D6E, + 1,0x5D6B, + 1,0x5D7C, + 1,0x5DE1, + 1,0x5DE2, + 1,0x382F, + 1,0x5DFD, + 1,0x5E28, + 1,0x5E3D, + 1,0x5E69, + 1,0x3862, + 1,0x22183, + 1,0x387C, + 1,0x5EB0, + 1,0x5EB3, + 1,0x5EB6, + 1,0x5ECA, + 1,0x2A392, + 1,0x5EFE, + 1,0x22331, + 1,0x22331, + 1,0x8201, + 1,0x5F22, + 1,0x5F22, + 1,0x38C7, + 1,0x232B8, + 1,0x261DA, + 1,0x5F62, + 1,0x5F6B, + 1,0x38E3, + 1,0x5F9A, + 1,0x5FCD, + 1,0x5FD7, + 1,0x5FF9, + 1,0x6081, + 1,0x393A, + 1,0x391C, + 1,0x6094, + 1,0x226D4, + 1,0x60C7, + 1,0x6148, + 1,0x614C, + 1,0x614E, + 1,0x614C, + 1,0x617A, + 1,0x618E, + 1,0x61B2, + 1,0x61A4, + 1,0x61AF, + 1,0x61DE, + 1,0x61F2, + 1,0x61F6, + 1,0x6210, + 1,0x621B, + 1,0x625D, + 1,0x62B1, + 1,0x62D4, + 1,0x6350, + 1,0x22B0C, + 1,0x633D, + 1,0x62FC, + 1,0x6368, + 1,0x6383, + 1,0x63E4, + 1,0x22BF1, + 1,0x6422, + 1,0x63C5, + 1,0x63A9, + 1,0x3A2E, + 1,0x6469, + 1,0x647E, + 1,0x649D, + 1,0x6477, + 1,0x3A6C, + 1,0x654F, + 1,0x656C, + 1,0x2300A, + 1,0x65E3, + 1,0x66F8, + 1,0x6649, + 1,0x3B19, + 1,0x6691, + 1,0x3B08, + 1,0x3AE4, + 1,0x5192, + 1,0x5195, + 1,0x6700, + 1,0x669C, + 1,0x80AD, + 1,0x43D9, + 1,0x6717, + 1,0x671B, + 1,0x6721, + 1,0x675E, + 1,0x6753, + 1,0x233C3, + 1,0x3B49, + 1,0x67FA, + 1,0x6785, + 1,0x6852, + 1,0x6885, + 1,0x2346D, + 1,0x688E, + 1,0x681F, + 1,0x6914, + 1,0x3B9D, + 1,0x6942, + 1,0x69A3, + 1,0x69EA, + 1,0x6AA8, + 1,0x236A3, + 1,0x6ADB, + 1,0x3C18, + 1,0x6B21, + 1,0x238A7, + 1,0x6B54, + 1,0x3C4E, + 1,0x6B72, + 1,0x6B9F, + 1,0x6BBA, + 1,0x6BBB, + 1,0x23A8D, + 1,0x21D0B, + 1,0x23AFA, + 1,0x6C4E, + 1,0x23CBC, + 1,0x6CBF, + 1,0x6CCD, + 1,0x6C67, + 1,0x6D16, + 1,0x6D3E, + 1,0x6D77, + 1,0x6D41, + 1,0x6D69, + 1,0x6D78, + 1,0x6D85, + 1,0x23D1E, + 1,0x6D34, + 1,0x6E2F, + 1,0x6E6E, + 1,0x3D33, + 1,0x6ECB, + 1,0x6EC7, + 1,0x23ED1, + 1,0x6DF9, + 1,0x6F6E, + 1,0x23F5E, + 1,0x23F8E, + 1,0x6FC6, + 1,0x7039, + 1,0x701E, + 1,0x701B, + 1,0x3D96, + 1,0x704A, + 1,0x707D, + 1,0x7077, + 1,0x70AD, + 1,0x20525, + 1,0x7145, + 1,0x24263, + 1,0x719C, + 1,0x243AB, + 1,0x7228, + 1,0x7235, + 1,0x7250, + 1,0x24608, + 1,0x7280, + 1,0x7295, + 1,0x24735, + 1,0x24814, + 1,0x737A, + 1,0x738B, + 1,0x3EAC, + 1,0x73A5, + 1,0x3EB8, + 1,0x3EB8, + 1,0x7447, + 1,0x745C, + 1,0x7471, + 1,0x7485, + 1,0x74CA, + 1,0x3F1B, + 1,0x7524, + 1,0x24C36, + 1,0x753E, + 1,0x24C92, + 1,0x7570, + 1,0x2219F, + 1,0x7610, + 1,0x24FA1, + 1,0x24FB8, + 1,0x25044, + 1,0x3FFC, + 1,0x4008, + 1,0x76F4, + 1,0x250F3, + 1,0x250F2, + 1,0x25119, + 1,0x25133, + 1,0x771E, + 1,0x771F, + 1,0x771F, + 1,0x774A, + 1,0x4039, + 1,0x778B, + 1,0x4046, + 1,0x4096, + 1,0x2541D, + 1,0x784E, + 1,0x788C, + 1,0x78CC, + 1,0x40E3, + 1,0x25626, + 1,0x7956, + 1,0x2569A, + 1,0x256C5, + 1,0x798F, + 1,0x79EB, + 1,0x412F, + 1,0x7A40, + 1,0x7A4A, + 1,0x7A4F, + 1,0x2597C, + 1,0x25AA7, + 1,0x25AA7, + 1,0x7AEE, + 1,0x4202, + 1,0x25BAB, + 1,0x7BC6, + 1,0x7BC9, + 1,0x4227, + 1,0x25C80, + 1,0x7CD2, + 1,0x42A0, + 1,0x7CE8, + 1,0x7CE3, + 1,0x7D00, + 1,0x25F86, + 1,0x7D63, + 1,0x4301, + 1,0x7DC7, + 1,0x7E02, + 1,0x7E45, + 1,0x4334, + 1,0x26228, + 1,0x26247, + 1,0x4359, + 1,0x262D9, + 1,0x7F7A, + 1,0x2633E, + 1,0x7F95, + 1,0x7FFA, + 1,0x8005, + 1,0x264DA, + 1,0x26523, + 1,0x8060, + 1,0x265A8, + 1,0x8070, + 1,0x2335F, + 1,0x43D5, + 1,0x80B2, + 1,0x8103, + 1,0x440B, + 1,0x813E, + 1,0x5AB5, + 1,0x267A7, + 1,0x267B5, + 1,0x23393, + 1,0x2339C, + 1,0x8201, + 1,0x8204, + 1,0x8F9E, + 1,0x446B, + 1,0x8291, + 1,0x828B, + 1,0x829D, + 1,0x52B3, + 1,0x82B1, + 1,0x82B3, + 1,0x82BD, + 1,0x82E6, + 1,0x26B3C, + 1,0x82E5, + 1,0x831D, + 1,0x8363, + 1,0x83AD, + 1,0x8323, + 1,0x83BD, + 1,0x83E7, + 1,0x8457, + 1,0x8353, + 1,0x83CA, + 1,0x83CC, + 1,0x83DC, + 1,0x26C36, + 1,0x26D6B, + 1,0x26CD5, + 1,0x452B, + 1,0x84F1, + 1,0x84F3, + 1,0x8516, + 1,0x273CA, + 1,0x8564, + 1,0x26F2C, + 1,0x455D, + 1,0x4561, + 1,0x26FB1, + 1,0x270D2, + 1,0x456B, + 1,0x8650, + 1,0x865C, + 1,0x8667, + 1,0x8669, + 1,0x86A9, + 1,0x8688, + 1,0x870E, + 1,0x86E2, + 1,0x8779, + 1,0x8728, + 1,0x876B, + 1,0x8786, + 1,0x45D7, + 1,0x87E1, + 1,0x8801, + 1,0x45F9, + 1,0x8860, + 1,0x8863, + 1,0x27667, + 1,0x88D7, + 1,0x88DE, + 1,0x4635, + 1,0x88FA, + 1,0x34BB, + 1,0x278AE, + 1,0x27966, + 1,0x46BE, + 1,0x46C7, + 1,0x8AA0, + 1,0x8AED, + 1,0x8B8A, + 1,0x8C55, + 1,0x27CA8, + 1,0x8CAB, + 1,0x8CC1, + 1,0x8D1B, + 1,0x8D77, + 1,0x27F2F, + 1,0x20804, + 1,0x8DCB, + 1,0x8DBC, + 1,0x8DF0, + 1,0x208DE, + 1,0x8ED4, + 1,0x8F38, + 1,0x285D2, + 1,0x285ED, + 1,0x9094, + 1,0x90F1, + 1,0x9111, + 1,0x2872E, + 1,0x911B, + 1,0x9238, + 1,0x92D7, + 1,0x92D8, + 1,0x927C, + 1,0x93F9, + 1,0x9415, + 1,0x28BFA, + 1,0x958B, + 1,0x4995, + 1,0x95B7, + 1,0x28D77, + 1,0x49E6, + 1,0x96C3, + 1,0x5DB2, + 1,0x9723, + 1,0x29145, + 1,0x2921A, + 1,0x4A6E, + 1,0x4A76, + 1,0x97E0, + 1,0x2940A, + 1,0x4AB2, + 1,0x29496, + 1,0x980B, + 1,0x980B, + 1,0x9829, + 1,0x295B6, + 1,0x98E2, + 1,0x4B33, + 1,0x9929, + 1,0x99A7, + 1,0x99C2, + 1,0x99FE, + 1,0x4BCE, + 1,0x29B30, + 1,0x9B12, + 1,0x9C40, + 1,0x9CFD, + 1,0x4CCE, + 1,0x4CED, + 1,0x9D67, + 1,0x2A0CE, + 1,0x4CF8, + 1,0x2A105, + 1,0x2A20E, + 1,0x2A291, + 1,0x9EBB, + 1,0x4D56, + 1,0x9EF9, + 1,0x9EFE, + 1,0x9F05, + 1,0x9F0F, + 1,0x9F16, + 1,0x9F3B, + 1,0x2A600, +}; + +static const short translit_page00[344] = { + 0, 2, 4, 6, -1, 9, 13, 15, /* 0xa0-0xa7 */ + 18, 20, 24, 26, 29, 33, 35, -1, /* 0xa8-0xaf */ + 39, 42, 46, 49, 52, 54, 56, 58, /* 0xb0-0xb7 */ + 60, 62, 65, 67, 70, 76, 82, 88, /* 0xb8-0xbf */ + 90, 93, 96, 99, 102, 105, 107, 110, /* 0xc0-0xc7 */ + 112, 115, 118, 121, 124, 127, 130, 133, /* 0xc8-0xcf */ + 136, 138, 141, 144, 147, 150, 153, 156, /* 0xd0-0xd7 */ + 158, 160, 163, 166, 169, 172, 175, 178, /* 0xd8-0xdf */ + 181, 184, 187, 190, 193, 196, 198, 201, /* 0xe0-0xe7 */ + 203, 206, 209, 212, 215, 218, 221, 224, /* 0xe8-0xef */ + 227, 229, 232, 235, 238, 241, 244, 247, /* 0xf0-0xf7 */ + 249, 251, 254, 257, 260, 263, 266, 269, /* 0xf8-0xff */ + /* 0x0100 */ + 272, 274, 276, 278, 280, 282, 284, 287, /* 0x00-0x07 */ + 290, 293, 296, 298, 300, 302, 304, 306, /* 0x08-0x0f */ + 308, 310, 312, 314, 316, 318, 320, 322, /* 0x10-0x17 */ + 324, 326, 328, 330, 332, 335, 338, 340, /* 0x18-0x1f */ + 342, 344, 346, 348, 350, 353, 356, 358, /* 0x20-0x27 */ + 360, 363, 366, 368, 370, 372, 374, 376, /* 0x28-0x2f */ + 378, 380, 382, 385, 388, 391, 394, 396, /* 0x30-0x37 */ + -1, 398, 400, 402, 404, 406, 408, 410, /* 0x38-0x3f */ + 412, 414, 416, 418, 421, 424, 426, 428, /* 0x40-0x47 */ + 430, 432, -1, -1, 435, 437, 439, 441, /* 0x48-0x4f */ + 443, 446, 449, 452, 455, 458, 461, 463, /* 0x50-0x57 */ + 465, 467, 469, 472, 475, 478, 481, 483, /* 0x58-0x5f */ + 485, 487, 489, 491, 493, 495, 497, 499, /* 0x60-0x67 */ + 501, 504, 507, 509, 511, 513, 515, 517, /* 0x68-0x6f */ + 519, 522, 525, 527, 529, 532, 535, 538, /* 0x70-0x77 */ + 541, 544, 547, 550, 552, 554, 556, 558, /* 0x78-0x7f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x80-0x87 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x88-0x8f */ + -1, -1, 560, -1, -1, -1, -1, -1, /* 0x90-0x97 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x98-0x9f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xa0-0xa7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xa8-0xaf */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb0-0xb7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb8-0xbf */ + -1, -1, -1, -1, 562, 565, 568, 571, /* 0xc0-0xc7 */ + 574, 577, 580, 583, 586, -1, -1, -1, /* 0xc8-0xcf */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xd0-0xd7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xd8-0xdf */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xe0-0xe7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xe8-0xef */ + -1, 589, 592, 595, -1, -1, -1, -1, /* 0xf0-0xf7 */ +}; +static const short translit_page02[8] = { + 598, 600, 602, 604, -1, -1, -1, -1, /* 0x18-0x1f */ +}; +static const short translit_page02_1[40] = { + -1, 606, 608, 610, 612, 614, -1, -1, /* 0xb8-0xbf */ + -1, -1, -1, -1, -1, -1, 616, -1, /* 0xc0-0xc7 */ + 618, 620, 622, 624, -1, 626, -1, -1, /* 0xc8-0xcf */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xd0-0xd7 */ + -1, -1, -1, -1, 628, 630, -1, -1, /* 0xd8-0xdf */ +}; +static const short translit_page03[48] = { + 632, 634, 636, -1, -1, 638, 640, -1, /* 0xd0-0xd7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xd8-0xdf */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xe0-0xe7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xe8-0xef */ + 642, 644, 646, -1, 648, 650, -1, -1, /* 0xf0-0xf7 */ + -1, 652, -1, -1, -1, -1, -1, -1, /* 0xf8-0xff */ +}; +static const short translit_page05[8] = { + 657, 660, 663, -1, -1, -1, -1, -1, /* 0xf0-0xf7 */ +}; +static const short translit_page06[16] = { + -1, -1, -1, -1, -1, 666, 669, 672, /* 0x70-0x77 */ + 675, -1, -1, -1, -1, -1, -1, -1, /* 0x78-0x7f */ +}; +static const short translit_page0e[48] = { + -1, -1, -1, 681, -1, -1, -1, -1, /* 0xb0-0xb7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb8-0xbf */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xc0-0xc7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xc8-0xcf */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xd0-0xd7 */ + -1, -1, -1, -1, 684, 687, -1, -1, /* 0xd8-0xdf */ +}; +static const short translit_page0f[16] = { + -1, -1, -1, -1, -1, -1, -1, 690, /* 0x70-0x77 */ + -1, 693, -1, -1, -1, -1, -1, -1, /* 0x78-0x7f */ +}; +static const short translit_page1e[160] = { + -1, -1, 696, 698, -1, -1, -1, -1, /* 0x00-0x07 */ + -1, -1, 700, 702, -1, -1, -1, -1, /* 0x08-0x0f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x17 */ + -1, -1, -1, -1, -1, -1, 704, 706, /* 0x18-0x1f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x20-0x27 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x28-0x2f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x30-0x37 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x38-0x3f */ + 708, 710, -1, -1, -1, -1, -1, -1, /* 0x40-0x47 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x48-0x4f */ + -1, -1, -1, -1, -1, -1, 712, 714, /* 0x50-0x57 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x58-0x5f */ + 716, 718, -1, -1, -1, -1, -1, -1, /* 0x60-0x67 */ + -1, -1, 720, 722, -1, -1, -1, -1, /* 0x68-0x6f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x70-0x77 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x78-0x7f */ + 724, 727, 730, 733, 736, 739, -1, -1, /* 0x80-0x87 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x88-0x8f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x90-0x97 */ + -1, -1, 742, -1, -1, -1, -1, -1, /* 0x98-0x9f */ +}; +static const short translit_page1e_2[8] = { + -1, -1, 745, 748, -1, -1, -1, -1, /* 0xf0-0xf7 */ +}; +static const short translit_page20[88] = { + -1, -1, 751, 753, 755, 757, 759, -1, /* 0x00-0x07 */ + 761, 763, 765, -1, -1, -1, -1, -1, /* 0x08-0x0f */ + 767, 769, 771, 773, 775, 777, -1, -1, /* 0x10-0x17 */ + 779, 781, 783, 785, 787, 789, 791, 793, /* 0x18-0x1f */ + 795, -1, 797, -1, 799, 801, 804, -1, /* 0x20-0x27 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x28-0x2f */ + 808, -1, 813, 815, 818, -1, 822, 825, /* 0x30-0x37 */ + -1, 829, 831, -1, 833, -1, -1, -1, /* 0x38-0x3f */ + -1, -1, -1, -1, 836, -1, -1, 838, /* 0x40-0x47 */ + 841, 844, -1, -1, -1, -1, -1, -1, /* 0x48-0x4f */ + -1, -1, -1, -1, -1, -1, -1, 847, /* 0x50-0x57 */ +}; +static const short translit_page20_3[8] = { + 852, -1, -1, 855, 860, -1, -1, -1, /* 0xa8-0xaf */ +}; +static const short translit_page21[216] = { + 864, 868, 872, 874, -1, 877, 881, 885, /* 0x00-0x07 */ + -1, 887, 890, 892, 894, 896, 898, 900, /* 0x08-0x0f */ + 902, 904, 906, 908, -1, 910, 912, -1, /* 0x10-0x17 */ + -1, 915, 917, 919, 921, 923, -1, -1, /* 0x18-0x1f */ + -1, 925, 929, -1, 932, -1, 934, -1, /* 0x20-0x27 */ + 938, -1, -1, -1, 940, 942, 944, 946, /* 0x28-0x2f */ + 948, 950, -1, 952, 954, 956, 958, 960, /* 0x30-0x37 */ + 962, 964, -1, 966, -1, 970, 972, 974, /* 0x38-0x3f */ + 976, -1, -1, -1, -1, 978, 980, 982, /* 0x40-0x47 */ + 984, 986, -1, -1, -1, -1, -1, -1, /* 0x48-0x4f */ + -1, -1, -1, 988, 994, 1000, 1006, 1012, /* 0x50-0x57 */ + 1018, 1024, 1030, 1036, 1042, 1048, 1054, 1060, /* 0x58-0x5f */ + 1064, 1066, 1069, 1073, 1076, 1078, 1081, 1085, /* 0x60-0x67 */ + 1090, 1093, 1095, 1098, 1102, 1104, 1106, 1108, /* 0x68-0x6f */ + 1110, 1112, 1115, 1119, 1122, 1124, 1127, 1131, /* 0x70-0x77 */ + 1136, 1139, 1141, 1144, 1148, 1150, 1152, 1154, /* 0x78-0x7f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x80-0x87 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x88-0x8f */ + 1156, 1159, 1161, 1164, 1166, -1, -1, -1, /* 0x90-0x97 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x98-0x9f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xa0-0xa7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xa8-0xaf */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb0-0xb7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb8-0xbf */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xc0-0xc7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xc8-0xcf */ + 1170, -1, 1173, -1, 1176, -1, -1, -1, /* 0xd0-0xd7 */ +}; +static const short translit_page22[96] = { + -1, -1, 1180, -1, -1, 1182, 1184, 1186, /* 0x10-0x17 */ + -1, 1188, -1, -1, -1, -1, -1, -1, /* 0x18-0x1f */ + -1, -1, -1, 1190, -1, -1, -1, -1, /* 0x20-0x27 */ + -1, -1, -1, -1, 1192, 1195, -1, 1199, /* 0x28-0x2f */ + 1202, -1, -1, -1, -1, -1, 1206, -1, /* 0x30-0x37 */ + -1, -1, -1, -1, 1208, -1, -1, -1, /* 0x38-0x3f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x40-0x47 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x48-0x4f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x50-0x57 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x58-0x5f */ + 1210, -1, -1, -1, 1213, 1216, -1, -1, /* 0x60-0x67 */ + -1, -1, 1219, 1222, -1, -1, -1, -1, /* 0x68-0x6f */ +}; +static const short translit_page22_4[48] = { + -1, -1, -1, -1, -1, 1225, -1, -1, /* 0xc0-0xc7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xc8-0xcf */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xd0-0xd7 */ + 1227, 1231, -1, -1, -1, -1, -1, -1, /* 0xd8-0xdf */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xe0-0xe7 */ + -1, -1, -1, -1, -1, -1, -1, 1235, /* 0xe8-0xef */ +}; +static const short translit_page24[240] = { + 1239, 1245, 1251, 1257, 1263, 1269, 1275, 1281, /* 0x00-0x07 */ + 1287, 1292, 1297, 1302, 1307, 1312, 1317, 1322, /* 0x08-0x0f */ + 1327, 1333, 1339, 1345, 1351, 1357, 1363, 1369, /* 0x10-0x17 */ + 1375, 1381, 1386, 1392, 1398, 1403, 1408, 1413, /* 0x18-0x1f */ + 1418, 1423, -1, -1, 1429, -1, -1, -1, /* 0x20-0x27 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x28-0x2f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x30-0x37 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x38-0x3f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x40-0x47 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x48-0x4f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x50-0x57 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x58-0x5f */ + 1434, 1438, 1442, 1446, 1450, 1454, 1458, 1462, /* 0x60-0x67 */ + 1466, 1470, 1475, 1480, 1485, 1490, 1495, 1500, /* 0x68-0x6f */ + 1505, 1510, 1515, 1520, 1525, 1529, 1533, 1537, /* 0x70-0x77 */ + 1541, 1545, 1549, 1553, 1557, 1561, 1566, 1571, /* 0x78-0x7f */ + 1576, 1581, 1586, 1591, 1596, 1601, 1606, 1611, /* 0x80-0x87 */ + 1616, 1619, 1622, 1625, 1628, 1631, 1634, 1637, /* 0x88-0x8f */ + 1640, 1643, 1647, 1651, 1655, 1659, 1663, 1667, /* 0x90-0x97 */ + 1671, 1675, 1679, 1683, 1687, 1691, 1695, 1699, /* 0x98-0x9f */ + 1703, 1707, 1711, 1715, 1719, 1723, 1727, 1731, /* 0xa0-0xa7 */ + 1735, 1739, 1743, 1747, 1751, 1755, 1759, 1763, /* 0xa8-0xaf */ + 1767, 1771, 1775, 1779, 1783, 1787, 1791, 1795, /* 0xb0-0xb7 */ + 1799, 1803, 1807, 1811, 1815, 1819, 1823, 1827, /* 0xb8-0xbf */ + 1831, 1835, 1839, 1843, 1847, 1851, 1855, 1859, /* 0xc0-0xc7 */ + 1863, 1867, 1871, 1875, 1879, 1883, 1887, 1891, /* 0xc8-0xcf */ + 1895, 1899, 1903, 1907, 1911, 1915, 1919, 1923, /* 0xd0-0xd7 */ + 1927, 1931, 1935, 1939, 1943, 1947, 1951, 1955, /* 0xd8-0xdf */ + 1959, 1963, 1967, 1971, 1975, 1979, 1983, 1987, /* 0xe0-0xe7 */ + 1991, 1995, 1999, -1, -1, -1, -1, -1, /* 0xe8-0xef */ +}; +static const short translit_page25[64] = { + 2003, -1, 2005, -1, -1, -1, -1, -1, /* 0x00-0x07 */ + -1, -1, -1, -1, 2007, -1, -1, -1, /* 0x08-0x0f */ + 2009, -1, -1, -1, 2011, -1, -1, -1, /* 0x10-0x17 */ + 2013, -1, -1, -1, 2015, -1, -1, -1, /* 0x18-0x1f */ + -1, -1, -1, -1, 2017, -1, -1, -1, /* 0x20-0x27 */ + -1, -1, -1, -1, 2019, -1, -1, -1, /* 0x28-0x2f */ + -1, -1, -1, -1, 2021, -1, -1, -1, /* 0x30-0x37 */ + -1, -1, -1, -1, 2023, -1, -1, -1, /* 0x38-0x3f */ +}; +static const short translit_page2a[8] = { + -1, -1, -1, -1, 2032, 2036, 2039, -1, /* 0x70-0x77 */ +}; +static const short translit_page2f[216] = { + 2047, 2049, 2051, 2053, 2055, 2057, 2059, 2061, /* 0x00-0x07 */ + 2063, 2065, 2067, 2069, 2071, 2073, 2075, 2077, /* 0x08-0x0f */ + 2079, 2081, 2083, 2085, 2087, 2089, 2091, 2093, /* 0x10-0x17 */ + 2095, 2097, 2099, 2101, 2103, 2105, 2107, 2109, /* 0x18-0x1f */ + 2111, 2113, 2115, 2117, 2119, 2121, 2123, 2125, /* 0x20-0x27 */ + 2127, 2129, 2131, 2133, 2135, 2137, 2139, 2141, /* 0x28-0x2f */ + 2143, 2145, 2147, 2149, 2151, 2153, 2155, 2157, /* 0x30-0x37 */ + 2159, 2161, 2163, 2165, 2167, 2169, 2171, 2173, /* 0x38-0x3f */ + 2175, 2177, 2179, 2181, 2183, 2185, 2187, 2189, /* 0x40-0x47 */ + 2191, 2193, 2195, 2197, 2199, 2201, 2203, 2205, /* 0x48-0x4f */ + 2207, 2209, 2211, 2213, 2215, 2217, 2219, 2221, /* 0x50-0x57 */ + 2223, 2225, 2227, 2229, 2231, 2233, 2235, 2237, /* 0x58-0x5f */ + 2239, 2241, 2243, 2245, 2247, 2249, 2251, 2253, /* 0x60-0x67 */ + 2255, 2257, 2259, 2261, 2263, 2265, 2267, 2269, /* 0x68-0x6f */ + 2271, 2273, 2275, 2277, 2279, 2281, 2283, 2285, /* 0x70-0x77 */ + 2287, 2289, 2291, 2293, 2295, 2297, 2299, 2301, /* 0x78-0x7f */ + 2303, 2305, 2307, 2309, 2311, 2313, 2315, 2317, /* 0x80-0x87 */ + 2319, 2321, 2323, 2325, 2327, 2329, 2331, 2333, /* 0x88-0x8f */ + 2335, 2337, 2339, 2341, 2343, 2345, 2347, 2349, /* 0x90-0x97 */ + 2351, 2353, 2355, 2357, 2359, 2361, 2363, 2365, /* 0x98-0x9f */ + 2367, 2369, 2371, 2373, 2375, 2377, 2379, 2381, /* 0xa0-0xa7 */ + 2383, 2385, 2387, 2389, 2391, 2393, 2395, 2397, /* 0xa8-0xaf */ + 2399, 2401, 2403, 2405, 2407, 2409, 2411, 2413, /* 0xb0-0xb7 */ + 2415, 2417, 2419, 2421, 2423, 2425, 2427, 2429, /* 0xb8-0xbf */ + 2431, 2433, 2435, 2437, 2439, 2441, 2443, 2445, /* 0xc0-0xc7 */ + 2447, 2449, 2451, 2453, 2455, 2457, 2459, 2461, /* 0xc8-0xcf */ + 2463, 2465, 2467, 2469, 2471, 2473, -1, -1, /* 0xd0-0xd7 */ +}; +static const short translit_page30[248] = { + 2475, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x07 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x08-0x0f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x17 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x18-0x1f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x20-0x27 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x28-0x2f */ + -1, -1, -1, -1, -1, -1, 2477, -1, /* 0x30-0x37 */ + 2479, 2481, 2483, -1, -1, -1, -1, -1, /* 0x38-0x3f */ + -1, 2485, -1, 2487, -1, 2489, -1, 2491, /* 0x40-0x47 */ + -1, 2493, -1, -1, -1, -1, -1, -1, /* 0x48-0x4f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x50-0x57 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x58-0x5f */ + -1, -1, -1, 2495, -1, -1, -1, -1, /* 0x60-0x67 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x68-0x6f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x70-0x77 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x78-0x7f */ + -1, -1, -1, 2497, -1, 2499, -1, 2501, /* 0x80-0x87 */ + -1, -1, -1, -1, -1, -1, 2503, -1, /* 0x88-0x8f */ + -1, -1, -1, -1, -1, 2505, 2507, -1, /* 0x90-0x97 */ + -1, -1, -1, 2509, 2512, -1, -1, -1, /* 0x98-0x9f */ + 2515, 2517, -1, 2519, -1, 2521, -1, 2523, /* 0xa0-0xa7 */ + -1, 2525, -1, -1, -1, -1, -1, -1, /* 0xa8-0xaf */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb0-0xb7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xb8-0xbf */ + -1, -1, -1, 2527, -1, -1, -1, -1, /* 0xc0-0xc7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xc8-0xcf */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xd0-0xd7 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0xd8-0xdf */ + -1, -1, -1, 2529, -1, 2531, -1, 2533, /* 0xe0-0xe7 */ + -1, -1, -1, -1, -1, -1, 2535, -1, /* 0xe8-0xef */ + -1, -1, -1, -1, -1, 2537, 2539, -1, /* 0xf0-0xf7 */ +}; +static const short translit_page31[96] = { + -1, 2541, 2543, 2545, 2547, 2549, 2551, 2553, /* 0x30-0x37 */ + 2555, 2557, 2559, 2561, 2563, 2565, 2567, 2569, /* 0x38-0x3f */ + 2571, 2573, 2575, 2577, 2579, 2581, 2583, 2585, /* 0x40-0x47 */ + 2587, 2589, 2591, 2593, 2595, 2597, 2599, 2601, /* 0x48-0x4f */ + 2603, 2605, 2607, 2609, 2611, 2613, 2615, 2617, /* 0x50-0x57 */ + 2619, 2621, 2623, 2625, 2627, 2629, 2631, 2633, /* 0x58-0x5f */ + 2635, 2637, 2639, 2641, 2643, 2645, 2647, 2649, /* 0x60-0x67 */ + 2651, 2653, 2655, 2657, 2659, 2661, 2663, 2665, /* 0x68-0x6f */ + 2667, 2669, 2671, 2673, 2675, 2677, 2679, 2681, /* 0x70-0x77 */ + 2683, 2685, 2687, 2689, 2691, 2693, 2695, 2697, /* 0x78-0x7f */ + 2699, 2701, 2703, 2705, 2707, 2709, 2711, 2713, /* 0x80-0x87 */ + 2715, 2717, 2719, 2721, 2723, 2725, 2727, -1, /* 0x88-0x8f */ +}; +static const short translit_page31_5[528] = { + 2729, 2731, 2733, 2735, 2737, 2739, 2741, 2743, /* 0xf0-0xf7 */ + 2745, 2747, 2749, 2751, 2753, 2755, 2757, 2759, /* 0xf8-0xff */ + /* 0x3200 */ + 2761, 2765, 2769, 2773, 2777, 2781, 2785, 2789, /* 0x00-0x07 */ + 2793, 2797, 2801, 2805, 2809, 2813, 2817, 2822, /* 0x08-0x0f */ + 2827, 2832, 2837, 2842, 2847, 2852, 2857, 2862, /* 0x10-0x17 */ + 2867, 2872, 2877, 2882, 2887, 2892, 2900, -1, /* 0x18-0x1f */ + 2907, 2911, 2915, 2919, 2923, 2927, 2931, 2935, /* 0x20-0x27 */ + 2939, 2943, 2947, 2951, 2955, 2959, 2963, 2967, /* 0x28-0x2f */ + 2971, 2975, 2979, 2983, 2987, 2991, 2995, 2999, /* 0x30-0x37 */ + 3003, 3007, 3011, 3015, 3019, 3023, 3027, 3031, /* 0x38-0x3f */ + 3035, 3039, 3043, 3047, -1, -1, -1, -1, /* 0x40-0x47 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x48-0x4f */ + 3051, 3055, 3060, 3065, 3070, 3075, 3080, 3085, /* 0x50-0x57 */ + 3090, 3095, 3100, 3105, 3110, 3115, 3120, 3125, /* 0x58-0x5f */ + 3130, 3134, 3138, 3142, 3146, 3150, 3154, 3158, /* 0x60-0x67 */ + 3162, 3166, 3170, 3174, 3178, 3182, 3186, 3191, /* 0x68-0x6f */ + 3196, 3201, 3206, 3211, 3216, 3221, 3226, 3231, /* 0x70-0x77 */ + 3236, 3241, 3246, 3251, 3256, 3264, -1, -1, /* 0x78-0x7f */ + 3271, 3275, 3279, 3283, 3287, 3291, 3295, 3299, /* 0x80-0x87 */ + 3303, 3307, 3311, 3315, 3319, 3323, 3327, 3331, /* 0x88-0x8f */ + 3335, 3339, 3343, 3347, 3351, 3355, 3359, 3363, /* 0x90-0x97 */ + 3367, 3371, 3375, 3379, 3383, 3387, 3391, 3395, /* 0x98-0x9f */ + 3399, 3403, 3407, 3411, 3415, 3419, 3423, 3427, /* 0xa0-0xa7 */ + 3431, 3435, 3439, 3443, 3447, 3451, 3455, 3459, /* 0xa8-0xaf */ + 3463, 3467, 3472, 3477, 3482, 3487, 3492, 3497, /* 0xb0-0xb7 */ + 3502, 3507, 3512, 3517, 3522, 3527, 3532, 3537, /* 0xb8-0xbf */ + 3542, 3545, 3548, 3551, 3554, 3557, 3560, 3563, /* 0xc0-0xc7 */ + 3566, 3569, 3573, 3577, 3581, 3584, 3588, 3591, /* 0xc8-0xcf */ + 3595, 3599, 3603, 3607, 3611, 3615, 3619, 3623, /* 0xd0-0xd7 */ + 3627, 3631, 3635, 3639, 3643, 3647, 3651, 3655, /* 0xd8-0xdf */ + 3659, 3663, 3667, 3671, 3675, 3679, 3683, 3687, /* 0xe0-0xe7 */ + 3691, 3695, 3699, 3703, 3707, 3711, 3715, 3719, /* 0xe8-0xef */ + 3723, 3727, 3731, 3735, 3739, 3743, 3747, 3751, /* 0xf0-0xf7 */ + 3755, 3759, 3763, 3767, 3771, 3775, 3779, -1, /* 0xf8-0xff */ + /* 0x3300 */ + 3783, 3788, 3793, 3798, 3802, 3807, 3811, 3815, /* 0x00-0x07 */ + 3821, 3826, 3830, 3834, 3838, 3843, 3848, 3852, /* 0x08-0x0f */ + 3856, 3859, 3863, 3868, 3873, 3876, 3882, 3889, /* 0x10-0x17 */ + 3895, 3899, 3905, 3911, 3916, 3920, 3924, 3928, /* 0x18-0x1f */ + 3933, 3939, 3944, 3948, 3952, 3956, 3959, 3962, /* 0x20-0x27 */ + 3965, 3968, 3972, 3976, 3982, 3986, 3991, 3997, /* 0x28-0x2f */ + 4001, 4004, 4007, 4013, 4018, 4024, 4028, 4034, /* 0x30-0x37 */ + 4037, 4041, 4045, 4049, 4053, 4057, 4062, 4066, /* 0x38-0x3f */ + 4069, 4073, 4077, 4081, 4086, 4090, 4094, 4098, /* 0x40-0x47 */ + 4104, 4109, 4112, 4118, 4121, 4126, 4131, 4135, /* 0x48-0x4f */ + 4139, 4143, 4148, 4151, 4155, 4160, 4163, 4169, /* 0x50-0x57 */ + 4173, 4176, 4179, 4182, 4185, 4188, 4191, 4194, /* 0x58-0x5f */ + 4197, 4200, 4203, 4207, 4211, 4215, 4219, 4223, /* 0x60-0x67 */ + 4227, 4231, 4235, 4239, 4243, 4247, 4251, 4255, /* 0x68-0x6f */ + 4259, 4263, 4267, 4270, 4273, 4277, 4280, 4283, /* 0x70-0x77 */ + 4286, 4291, 4296, 4299, 4302, 4305, 4308, 4311, /* 0x78-0x7f */ + 4316, 4319, 4322, 4325, 4328, 4331, 4334, 4337, /* 0x80-0x87 */ + 4340, 4344, 4349, 4352, 4355, 4358, 4361, 4364, /* 0x88-0x8f */ + 4367, 4370, 4374, 4378, 4382, 4386, 4389, 4392, /* 0x90-0x97 */ + 4395, 4398, 4401, 4404, 4407, 4410, 4413, 4416, /* 0x98-0x9f */ + 4421, 4426, 4430, 4435, 4440, 4445, 4449, 4454, /* 0xa0-0xa7 */ + 4458, 4464, 4467, 4471, 4475, 4479, 4483, 4489, /* 0xa8-0xaf */ + 4497, 4500, 4503, 4506, 4509, 4512, 4515, 4518, /* 0xb0-0xb7 */ + 4521, 4524, 4527, 4530, 4533, 4536, 4539, 4542, /* 0xb8-0xbf */ + 4545, 4548, 4551, 4556, 4559, 4562, 4565, 4570, /* 0xc0-0xc7 */ + 4574, 4577, 4580, 4583, 4586, 4589, 4592, 4595, /* 0xc8-0xcf */ + 4598, 4601, 4604, 4608, 4611, 4614, 4618, 4622, /* 0xd0-0xd7 */ + 4625, 4630, 4634, 4637, 4640, 4643, 4646, 4650, /* 0xd8-0xdf */ + 4658, 4661, 4664, 4667, 4670, 4673, 4676, 4679, /* 0xe0-0xe7 */ + 4682, 4685, 4689, 4693, 4697, 4701, 4705, 4709, /* 0xe8-0xef */ + 4713, 4717, 4721, 4725, 4729, 4733, 4737, 4741, /* 0xf0-0xf7 */ + 4745, 4749, 4753, 4757, 4761, 4765, 4769, 4654, /* 0xf8-0xff */ +}; +static const short translit_pagef9[368] = { + 4773, 4775, 4777, 4779, 4781, 4783, 4785, 4787, /* 0x00-0x07 */ + 4789, 4791, 4793, 4795, 4797, 4799, 4801, 4803, /* 0x08-0x0f */ + 4805, 4807, 4809, 4811, 4813, 4815, 4817, 4819, /* 0x10-0x17 */ + 4821, 4823, 4825, 4827, 4829, 4831, 4833, 4835, /* 0x18-0x1f */ + 4837, 4839, 4841, 4843, 4845, 4847, 4849, 4851, /* 0x20-0x27 */ + 4853, 4855, 4857, 4859, 4861, 4863, 4865, 4867, /* 0x28-0x2f */ + 4869, 4871, 4873, 4875, 4877, 4879, 4881, 4883, /* 0x30-0x37 */ + 4885, 4887, 4889, 4891, 4893, 4895, 4897, 4899, /* 0x38-0x3f */ + 4901, 4903, 4905, 4907, 4909, 4911, 4913, 4915, /* 0x40-0x47 */ + 4917, 4919, 4921, 4923, 4925, 4927, 4929, 4931, /* 0x48-0x4f */ + 4933, 4935, 4937, 4939, 4941, 4943, 4945, 4947, /* 0x50-0x57 */ + 4949, 4951, 4953, 4955, 4957, 4959, 4961, 4963, /* 0x58-0x5f */ + 4965, 4967, 4969, 4971, 4973, 4975, 4977, 4979, /* 0x60-0x67 */ + 4981, 4983, 4985, 4987, 4989, 4991, 4993, 4995, /* 0x68-0x6f */ + 4997, 4999, 5001, 5003, 5005, 5007, 5009, 5011, /* 0x70-0x77 */ + 5013, 5015, 5017, 5019, 5021, 5023, 5025, 5027, /* 0x78-0x7f */ + 5029, 5031, 5033, 5035, 5037, 5039, 5041, 5043, /* 0x80-0x87 */ + 5045, 5047, 5049, 5051, 5053, 5055, 5057, 5059, /* 0x88-0x8f */ + 5061, 5063, 5065, 5067, 5069, 5071, 5073, 5075, /* 0x90-0x97 */ + 5077, 5079, 5081, 5083, 5085, 5087, 5089, 5091, /* 0x98-0x9f */ + 5093, 5095, 5097, 5099, 5101, 5103, 5105, 5107, /* 0xa0-0xa7 */ + 5109, 5111, 5113, 5115, 5117, 5119, 5121, 5123, /* 0xa8-0xaf */ + 5125, 5127, 5129, 5131, 5133, 5135, 5137, 5139, /* 0xb0-0xb7 */ + 5141, 5143, 5145, 5147, 5149, 5151, 5153, 5155, /* 0xb8-0xbf */ + 5157, 5159, 5161, 5163, 5165, 5167, 5169, 5171, /* 0xc0-0xc7 */ + 5173, 5175, 5177, 5179, 5181, 5183, 5185, 5187, /* 0xc8-0xcf */ + 5189, 5191, 5193, 5195, 5197, 5199, 5201, 5203, /* 0xd0-0xd7 */ + 5205, 5207, 5209, 5211, 5213, 5215, 5217, 5219, /* 0xd8-0xdf */ + 5221, 5223, 5225, 5227, 5229, 5231, 5233, 5235, /* 0xe0-0xe7 */ + 5237, 5239, 5241, 5243, 5245, 5247, 5249, 5251, /* 0xe8-0xef */ + 5253, 5255, 5257, 5259, 5261, 5263, 5265, 5267, /* 0xf0-0xf7 */ + 5269, 5271, 5273, 5275, 5277, 5279, 5281, 5283, /* 0xf8-0xff */ + /* 0xfa00 */ + 5285, 5287, 5289, 5291, 5293, 5295, 5297, 5299, /* 0x00-0x07 */ + 5301, 5303, 5305, 5307, 5309, 5311, -1, -1, /* 0x08-0x0f */ + 5313, -1, 5315, -1, -1, 5317, 5319, 5321, /* 0x10-0x17 */ + 5323, 5325, 5327, 5329, 5331, 5333, 5335, -1, /* 0x18-0x1f */ + 5337, -1, 5339, -1, -1, 5341, 5343, -1, /* 0x20-0x27 */ + -1, -1, 5345, 5347, 5349, 5351, -1, -1, /* 0x28-0x2f */ + 5353, 5355, 5357, 5359, 5361, 5363, 5365, 5367, /* 0x30-0x37 */ + 5369, 5371, 5373, 5375, 5377, 5379, 5381, 5383, /* 0x38-0x3f */ + 5385, 5387, 5389, 5391, 5393, 5395, 5397, 5399, /* 0x40-0x47 */ + 5401, 5403, 5405, 5407, 5409, 5411, 5413, 5415, /* 0x48-0x4f */ + 5417, 5419, 5421, 5423, 5425, 5427, 5429, 5431, /* 0x50-0x57 */ + 5433, 5435, 5437, 5439, 5441, 5443, 5445, 5447, /* 0x58-0x5f */ + 5449, 5451, 5453, 5455, 5457, 5459, 5461, 5463, /* 0x60-0x67 */ + 5465, 5467, 5469, -1, -1, -1, -1, -1, /* 0x68-0x6f */ +}; +static const short translit_pagefb[80] = { + 5471, 5474, 5477, 5480, 5484, 5488, 5491, -1, /* 0x00-0x07 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x08-0x0f */ + -1, -1, -1, 5494, 5497, 5500, 5503, 5506, /* 0x10-0x17 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x18-0x1f */ + 5509, 5511, 5513, 5515, 5517, 5519, 5521, 5523, /* 0x20-0x27 */ + 5525, 5527, -1, -1, -1, -1, -1, -1, /* 0x28-0x2f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x30-0x37 */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x38-0x3f */ + -1, -1, -1, -1, -1, -1, -1, -1, /* 0x40-0x47 */ + -1, -1, -1, -1, -1, -1, -1, 5529, /* 0x48-0x4f */ +}; +static const short translit_pagefe[40] = { + -1, 5532, 5534, 5536, 5538, 5540, 5542, 5544, /* 0x48-0x4f */ + 5546, 5548, 5550, -1, 5552, 5554, 5556, 5558, /* 0x50-0x57 */ + 5560, 5562, 5564, 5566, 5568, 5570, 5572, 5574, /* 0x58-0x5f */ + 5576, 5578, 5580, 5582, 5584, 5586, 5588, -1, /* 0x60-0x67 */ + 5590, 5592, 5594, 5596, -1, -1, -1, -1, /* 0x68-0x6f */ +}; +static const short translit_pageff[240] = { + -1, 5598, 5600, 5602, 5604, 5606, 5608, 5610, /* 0x00-0x07 */ + 5612, 5614, 5616, 5618, 5620, 5622, 5624, 5626, /* 0x08-0x0f */ + 5628, 5630, 5632, 5634, 5636, 5638, 5640, 5642, /* 0x10-0x17 */ + 5644, 5646, 5648, 5650, 5652, 5654, 5656, 5658, /* 0x18-0x1f */ + 5660, 5662, 5664, 5666, 5668, 5670, 5672, 5674, /* 0x20-0x27 */ + 5676, 5678, 5680, 5682, 5684, 5686, 5688, 5690, /* 0x28-0x2f */ + 5692, 5694, 5696, 5698, 5700, 5702, 5704, 5706, /* 0x30-0x37 */ + 5708, 5710, 5712, 5714, 5716, 5718, 5720, 5722, /* 0x38-0x3f */ + 5724, 5726, 5728, 5730, 5732, 5734, 5736, 5738, /* 0x40-0x47 */ + 5740, 5742, 5744, 5746, 5748, 5750, 5752, 5754, /* 0x48-0x4f */ + 5756, 5758, 5760, 5762, 5764, 5766, 5768, 5770, /* 0x50-0x57 */ + 5772, 5774, 5776, 5778, 5780, 5782, 5784, 5786, /* 0x58-0x5f */ + 5788, 5790, 5792, 5794, 5796, 5798, 5800, 5802, /* 0x60-0x67 */ + 5804, 5806, 5808, 5810, 5812, 5814, 5816, 5818, /* 0x68-0x6f */ + 5820, 5822, 5824, 5826, 5828, 5830, 5832, 5834, /* 0x70-0x77 */ + 5836, 5838, 5840, 5842, 5844, 5846, 5848, 5850, /* 0x78-0x7f */ + 5852, 5854, 5856, 5858, 5860, 5862, 5864, 5866, /* 0x80-0x87 */ + 5868, 5870, 5872, 5874, 5876, 5878, 5880, 5882, /* 0x88-0x8f */ + 5884, 5886, 5888, 5890, 5892, 5894, 5896, 5898, /* 0x90-0x97 */ + 5900, 5902, 5904, 5906, 5908, 5910, 5912, 5914, /* 0x98-0x9f */ + 5916, 5918, 5920, 5922, 5924, 5926, 5928, 5930, /* 0xa0-0xa7 */ + 5932, 5934, 5936, 5938, 5940, 5942, 5944, 5946, /* 0xa8-0xaf */ + 5948, 5950, 5952, 5954, 5956, 5958, 5960, 5962, /* 0xb0-0xb7 */ + 5964, 5966, 5968, 5970, 5972, 5974, 5976, -1, /* 0xb8-0xbf */ + -1, -1, 5978, 5980, 5982, 5984, 5986, 5988, /* 0xc0-0xc7 */ + -1, -1, 5990, 5992, 5994, 5996, 5998, 6000, /* 0xc8-0xcf */ + -1, -1, 6002, 6004, 6006, 6008, 6010, 6012, /* 0xd0-0xd7 */ + -1, -1, 6014, 6016, 6018, -1, -1, -1, /* 0xd8-0xdf */ + 6020, 6022, 6024, 6026, 6028, 6030, 6032, -1, /* 0xe0-0xe7 */ + 6034, 6036, 6038, 6040, 6042, 6044, 6046, -1, /* 0xe8-0xef */ +}; +static const short translit_page1d4[1024] = { + 6048, 6050, 6052, 6054, 6056, 6058, 6060, 6062, /* 0x00-0x07 */ + 6064, 6066, 6068, 6070, 6072, 6074, 6076, 6078, /* 0x08-0x0f */ + 6080, 6082, 6084, 6086, 6088, 6090, 6092, 6094, /* 0x10-0x17 */ + 6096, 6098, 6100, 6102, 6104, 6106, 6108, 6110, /* 0x18-0x1f */ + 6112, 6114, 6116, 6118, 6120, 6122, 6124, 6126, /* 0x20-0x27 */ + 6128, 6130, 6132, 6134, 6136, 6138, 6140, 6142, /* 0x28-0x2f */ + 6144, 6146, 6148, 6150, 6152, 6154, 6156, 6158, /* 0x30-0x37 */ + 6160, 6162, 6164, 6166, 6168, 6170, 6172, 6174, /* 0x38-0x3f */ + 6176, 6178, 6180, 6182, 6184, 6186, 6188, 6190, /* 0x40-0x47 */ + 6192, 6194, 6196, 6198, 6200, 6202, 6204, 6206, /* 0x48-0x4f */ + 6208, 6210, 6212, 6214, 6216, -1, 6218, 6220, /* 0x50-0x57 */ + 6222, 6224, 6226, 6228, 6230, 6232, 6234, 6236, /* 0x58-0x5f */ + 6238, 6240, 6242, 6244, 6246, 6248, 6250, 6252, /* 0x60-0x67 */ + 6254, 6256, 6258, 6260, 6262, 6264, 6266, 6268, /* 0x68-0x6f */ + 6270, 6272, 6274, 6276, 6278, 6280, 6282, 6284, /* 0x70-0x77 */ + 6286, 6288, 6290, 6292, 6294, 6296, 6298, 6300, /* 0x78-0x7f */ + 6302, 6304, 6306, 6308, 6310, 6312, 6314, 6316, /* 0x80-0x87 */ + 6318, 6320, 6322, 6324, 6326, 6328, 6330, 6332, /* 0x88-0x8f */ + 6334, 6336, 6338, 6340, 6342, 6344, 6346, 6348, /* 0x90-0x97 */ + 6350, 6352, 6354, 6356, 6358, -1, 6360, 6362, /* 0x98-0x9f */ + -1, -1, 6364, -1, -1, 6366, 6368, -1, /* 0xa0-0xa7 */ + -1, 6370, 6372, 6374, 6376, -1, 6378, 6380, /* 0xa8-0xaf */ + 6382, 6384, 6386, 6388, 6390, 6392, 6394, 6396, /* 0xb0-0xb7 */ + 6398, 6400, -1, 6402, -1, 6404, 6406, 6408, /* 0xb8-0xbf */ + 6410, 6412, 6414, 6416, -1, 6418, 6420, 6422, /* 0xc0-0xc7 */ + 6424, 6426, 6428, 6430, 6432, 6434, 6436, 6438, /* 0xc8-0xcf */ + 6440, 6442, 6444, 6446, 6448, 6450, 6452, 6454, /* 0xd0-0xd7 */ + 6456, 6458, 6460, 6462, 6464, 6466, 6468, 6470, /* 0xd8-0xdf */ + 6472, 6474, 6476, 6478, 6480, 6482, 6484, 6486, /* 0xe0-0xe7 */ + 6488, 6490, 6492, 6494, 6496, 6498, 6500, 6502, /* 0xe8-0xef */ + 6504, 6506, 6508, 6510, 6512, 6514, 6516, 6518, /* 0xf0-0xf7 */ + 6520, 6522, 6524, 6526, 6528, 6530, 6532, 6534, /* 0xf8-0xff */ + /* 0x1d500 */ + 6536, 6538, 6540, 6542, 6544, 6546, -1, 6548, /* 0x00-0x07 */ + 6550, 6552, 6554, -1, -1, 6556, 6558, 6560, /* 0x08-0x0f */ + 6562, 6564, 6566, 6568, 6570, -1, 6572, 6574, /* 0x10-0x17 */ + 6576, 6578, 6580, 6582, 6584, -1, 6586, 6588, /* 0x18-0x1f */ + 6590, 6592, 6594, 6596, 6598, 6600, 6602, 6604, /* 0x20-0x27 */ + 6606, 6608, 6610, 6612, 6614, 6616, 6618, 6620, /* 0x28-0x2f */ + 6622, 6624, 6626, 6628, 6630, 6632, 6634, 6636, /* 0x30-0x37 */ + 6638, 6640, -1, 6642, 6644, 6646, 6648, -1, /* 0x38-0x3f */ + 6650, 6652, 6654, 6656, 6658, -1, 6660, -1, /* 0x40-0x47 */ + -1, -1, 6662, 6664, 6666, 6668, 6670, 6672, /* 0x48-0x4f */ + 6674, -1, 6676, 6678, 6680, 6682, 6684, 6686, /* 0x50-0x57 */ + 6688, 6690, 6692, 6694, 6696, 6698, 6700, 6702, /* 0x58-0x5f */ + 6704, 6706, 6708, 6710, 6712, 6714, 6716, 6718, /* 0x60-0x67 */ + 6720, 6722, 6724, 6726, 6728, 6730, 6732, 6734, /* 0x68-0x6f */ + 6736, 6738, 6740, 6742, 6744, 6746, 6748, 6750, /* 0x70-0x77 */ + 6752, 6754, 6756, 6758, 6760, 6762, 6764, 6766, /* 0x78-0x7f */ + 6768, 6770, 6772, 6774, 6776, 6778, 6780, 6782, /* 0x80-0x87 */ + 6784, 6786, 6788, 6790, 6792, 6794, 6796, 6798, /* 0x88-0x8f */ + 6800, 6802, 6804, 6806, 6808, 6810, 6812, 6814, /* 0x90-0x97 */ + 6816, 6818, 6820, 6822, 6824, 6826, 6828, 6830, /* 0x98-0x9f */ + 6832, 6834, 6836, 6838, 6840, 6842, 6844, 6846, /* 0xa0-0xa7 */ + 6848, 6850, 6852, 6854, 6856, 6858, 6860, 6862, /* 0xa8-0xaf */ + 6864, 6866, 6868, 6870, 6872, 6874, 6876, 6878, /* 0xb0-0xb7 */ + 6880, 6882, 6884, 6886, 6888, 6890, 6892, 6894, /* 0xb8-0xbf */ + 6896, 6898, 6900, 6902, 6904, 6906, 6908, 6910, /* 0xc0-0xc7 */ + 6912, 6914, 6916, 6918, 6920, 6922, 6924, 6926, /* 0xc8-0xcf */ + 6928, 6930, 6932, 6934, 6936, 6938, 6940, 6942, /* 0xd0-0xd7 */ + 6944, 6946, 6948, 6950, 6952, 6954, 6956, 6958, /* 0xd8-0xdf */ + 6960, 6962, 6964, 6966, 6968, 6970, 6972, 6974, /* 0xe0-0xe7 */ + 6976, 6978, 6980, 6982, 6984, 6986, 6988, 6990, /* 0xe8-0xef */ + 6992, 6994, 6996, 6998, 7000, 7002, 7004, 7006, /* 0xf0-0xf7 */ + 7008, 7010, 7012, 7014, 7016, 7018, 7020, 7022, /* 0xf8-0xff */ + /* 0x1d600 */ + 7024, 7026, 7028, 7030, 7032, 7034, 7036, 7038, /* 0x00-0x07 */ + 7040, 7042, 7044, 7046, 7048, 7050, 7052, 7054, /* 0x08-0x0f */ + 7056, 7058, 7060, 7062, 7064, 7066, 7068, 7070, /* 0x10-0x17 */ + 7072, 7074, 7076, 7078, 7080, 7082, 7084, 7086, /* 0x18-0x1f */ + 7088, 7090, 7092, 7094, 7096, 7098, 7100, 7102, /* 0x20-0x27 */ + 7104, 7106, 7108, 7110, 7112, 7114, 7116, 7118, /* 0x28-0x2f */ + 7120, 7122, 7124, 7126, 7128, 7130, 7132, 7134, /* 0x30-0x37 */ + 7136, 7138, 7140, 7142, 7144, 7146, 7148, 7150, /* 0x38-0x3f */ + 7152, 7154, 7156, 7158, 7160, 7162, 7164, 7166, /* 0x40-0x47 */ + 7168, 7170, 7172, 7174, 7176, 7178, 7180, 7182, /* 0x48-0x4f */ + 7184, 7186, 7188, 7190, 7192, 7194, 7196, 7198, /* 0x50-0x57 */ + 7200, 7202, 7204, 7206, 7208, 7210, 7212, 7214, /* 0x58-0x5f */ + 7216, 7218, 7220, 7222, 7224, 7226, 7228, 7230, /* 0x60-0x67 */ + 7232, 7234, 7236, 7238, 7240, 7242, 7244, 7246, /* 0x68-0x6f */ + 7248, 7250, 7252, 7254, 7256, 7258, 7260, 7262, /* 0x70-0x77 */ + 7264, 7266, 7268, 7270, 7272, 7274, 7276, 7278, /* 0x78-0x7f */ + 7280, 7282, 7284, 7286, 7288, 7290, 7292, 7294, /* 0x80-0x87 */ + 7296, 7298, 7300, 7302, 7304, 7306, 7308, 7310, /* 0x88-0x8f */ + 7312, 7314, 7316, 7318, 7320, 7322, 7324, 7326, /* 0x90-0x97 */ + 7328, 7330, 7332, 7334, 7336, 7338, 7340, 7342, /* 0x98-0x9f */ + 7344, 7346, 7348, 7350, -1, -1, -1, -1, /* 0xa0-0xa7 */ + 7352, 7354, 7356, 7358, 7360, 7362, 7364, 7366, /* 0xa8-0xaf */ + 7368, 7370, 7372, 7374, 7376, 7378, 7380, 7382, /* 0xb0-0xb7 */ + 7384, 7386, 7388, 7390, 7392, 7394, 7396, 7398, /* 0xb8-0xbf */ + 7400, 7402, 7404, 7406, 7408, 7410, 7412, 7414, /* 0xc0-0xc7 */ + 7416, 7418, 7420, 7422, 7424, 7426, 7428, 7430, /* 0xc8-0xcf */ + 7432, 7434, 7436, 7438, 7440, 7442, 7444, 7446, /* 0xd0-0xd7 */ + 7448, 7450, 7452, 7454, 7456, 7458, 7460, 7462, /* 0xd8-0xdf */ + 7464, 7466, 7468, 7470, 7472, 7474, 7476, 7478, /* 0xe0-0xe7 */ + 7480, 7482, 7484, 7486, 7488, 7490, 7492, 7494, /* 0xe8-0xef */ + 7496, 7498, 7500, 7502, 7504, 7506, 7508, 7510, /* 0xf0-0xf7 */ + 7512, 7514, 7516, 7518, 7520, 7522, 7524, 7526, /* 0xf8-0xff */ + /* 0x1d700 */ + 7528, 7530, 7532, 7534, 7536, 7538, 7540, 7542, /* 0x00-0x07 */ + 7544, 7546, 7548, 7550, 7552, 7554, 7556, 7558, /* 0x08-0x0f */ + 7560, 7562, 7564, 7566, 7568, 7570, 7572, 7574, /* 0x10-0x17 */ + 7576, 7578, 7580, 7582, 7584, 7586, 7588, 7590, /* 0x18-0x1f */ + 7592, 7594, 7596, 7598, 7600, 7602, 7604, 7606, /* 0x20-0x27 */ + 7608, 7610, 7612, 7614, 7616, 7618, 7620, 7622, /* 0x28-0x2f */ + 7624, 7626, 7628, 7630, 7632, 7634, 7636, 7638, /* 0x30-0x37 */ + 7640, 7642, 7644, 7646, 7648, 7650, 7652, 7654, /* 0x38-0x3f */ + 7656, 7658, 7660, 7662, 7664, 7666, 7668, 7670, /* 0x40-0x47 */ + 7672, 7674, 7676, 7678, 7680, 7682, 7684, 7686, /* 0x48-0x4f */ + 7688, 7690, 7692, 7694, 7696, 7698, 7700, 7702, /* 0x50-0x57 */ + 7704, 7706, 7708, 7710, 7712, 7714, 7716, 7718, /* 0x58-0x5f */ + 7720, 7722, 7724, 7726, 7728, 7730, 7732, 7734, /* 0x60-0x67 */ + 7736, 7738, 7740, 7742, 7744, 7746, 7748, 7750, /* 0x68-0x6f */ + 7752, 7754, 7756, 7758, 7760, 7762, 7764, 7766, /* 0x70-0x77 */ + 7768, 7770, 7772, 7774, 7776, 7778, 7780, 7782, /* 0x78-0x7f */ + 7784, 7786, 7788, 7790, 7792, 7794, 7796, 7798, /* 0x80-0x87 */ + 7800, 7802, 7804, 7806, 7808, 7810, 7812, 7814, /* 0x88-0x8f */ + 7816, 7818, 7820, 7822, 7824, 7826, 7828, 7830, /* 0x90-0x97 */ + 7832, 7834, 7836, 7838, 7840, 7842, 7844, 7846, /* 0x98-0x9f */ + 7848, 7850, 7852, 7854, 7856, 7858, 7860, 7862, /* 0xa0-0xa7 */ + 7864, 7866, 7868, 7870, 7872, 7874, 7876, 7878, /* 0xa8-0xaf */ + 7880, 7882, 7884, 7886, 7888, 7890, 7892, 7894, /* 0xb0-0xb7 */ + 7896, 7898, 7900, 7902, 7904, 7906, 7908, 7910, /* 0xb8-0xbf */ + 7912, 7914, 7916, 7918, 7920, 7922, 7924, 7926, /* 0xc0-0xc7 */ + 7928, 7930, -1, -1, -1, -1, 7932, 7934, /* 0xc8-0xcf */ + 7936, 7938, 7940, 7942, 7944, 7946, 7948, 7950, /* 0xd0-0xd7 */ + 7952, 7954, 7956, 7958, 7960, 7962, 7964, 7966, /* 0xd8-0xdf */ + 7968, 7970, 7972, 7974, 7976, 7978, 7980, 7982, /* 0xe0-0xe7 */ + 7984, 7986, 7988, 7990, 7992, 7994, 7996, 7998, /* 0xe8-0xef */ + 8000, 8002, 8004, 8006, 8008, 8010, 8012, 8014, /* 0xf0-0xf7 */ + 8016, 8018, 8020, 8022, 8024, 8026, 8028, 8030, /* 0xf8-0xff */ +}; +static const short translit_page2f8[544] = { + 8032, 8034, 8036, 8038, 8040, 8042, 8044, 8046, /* 0x00-0x07 */ + 8048, 8050, 8052, 8054, 8056, 8058, 8060, 8062, /* 0x08-0x0f */ + 8064, 8066, 8068, 8070, 8072, 8074, 8076, 8078, /* 0x10-0x17 */ + 8080, 8082, 8084, 8086, 8088, 8090, 8092, 8094, /* 0x18-0x1f */ + 8096, 8098, 8100, 8102, 8104, 8106, 8108, 8110, /* 0x20-0x27 */ + 8112, 8114, 8116, 8118, 8120, 8122, 8124, 8126, /* 0x28-0x2f */ + 8128, 8130, 8132, 8134, 8136, 8138, 8140, 8142, /* 0x30-0x37 */ + 8144, 8146, 8148, 8150, 8152, 8154, 8156, 8158, /* 0x38-0x3f */ + 8160, 8162, 8164, 8166, 8168, 8170, 8172, 8174, /* 0x40-0x47 */ + 8176, 8178, 8180, 8182, 8184, 8186, 8188, 8190, /* 0x48-0x4f */ + 8192, 8194, 8196, 8198, 8200, 8202, 8204, 8206, /* 0x50-0x57 */ + 8208, 8210, 8212, 8214, 8216, 8218, 8220, 8222, /* 0x58-0x5f */ + 8224, 8226, 8228, 8230, 8232, 8234, 8236, 8238, /* 0x60-0x67 */ + 8240, 8242, 8244, 8246, 8248, 8250, 8252, 8254, /* 0x68-0x6f */ + 8256, 8258, 8260, 8262, 8264, 8266, 8268, 8270, /* 0x70-0x77 */ + 8272, 8274, 8276, 8278, 8280, 8282, 8284, 8286, /* 0x78-0x7f */ + 8288, 8290, 8292, 8294, 8296, 8298, 8300, 8302, /* 0x80-0x87 */ + 8304, 8306, 8308, 8310, 8312, 8314, 8316, 8318, /* 0x88-0x8f */ + 8320, 8322, 8324, 8326, 8328, 8330, 8332, 8334, /* 0x90-0x97 */ + 8336, 8338, 8340, 8342, 8344, 8346, 8348, 8350, /* 0x98-0x9f */ + 8352, 8354, 8356, 8358, 8360, 8362, 8364, 8366, /* 0xa0-0xa7 */ + 8368, 8370, 8372, 8374, 8376, 8378, 8380, 8382, /* 0xa8-0xaf */ + 8384, 8386, 8388, 8390, 8392, 8394, 8396, 8398, /* 0xb0-0xb7 */ + 8400, 8402, 8404, 8406, 8408, 8410, 8412, 8414, /* 0xb8-0xbf */ + 8416, 8418, 8420, 8422, 8424, 8426, 8428, 8430, /* 0xc0-0xc7 */ + 8432, 8434, 8436, 8438, 8440, 8442, 8444, 8446, /* 0xc8-0xcf */ + 8448, 8450, 8452, 8454, 8456, 8458, 8460, 8462, /* 0xd0-0xd7 */ + 8464, 8466, 8468, 8470, 8472, 8474, 8476, 8478, /* 0xd8-0xdf */ + 8480, 8482, 8484, 8486, 8488, 8490, 8492, 8494, /* 0xe0-0xe7 */ + 8496, 8498, 8500, 8502, 8504, 8506, 8508, 8510, /* 0xe8-0xef */ + 8512, 8514, 8516, 8518, 8520, 8522, 8524, 8526, /* 0xf0-0xf7 */ + 8528, 8530, 8532, 8534, 8536, 8538, 8540, 8542, /* 0xf8-0xff */ + /* 0x2f900 */ + 8544, 8546, 8548, 8550, 8552, 8554, 8556, 8558, /* 0x00-0x07 */ + 8560, 8562, 8564, 8566, 8568, 8570, 8572, 8574, /* 0x08-0x0f */ + 8576, 8578, 8580, 8582, 8584, 8586, 8588, 8590, /* 0x10-0x17 */ + 8592, 8594, 8596, 8598, 8600, 8602, 8604, 8606, /* 0x18-0x1f */ + 8608, 8610, 8612, 8614, 8616, 8618, 8620, 8622, /* 0x20-0x27 */ + 8624, 8626, 8628, 8630, 8632, 8634, 8636, 8638, /* 0x28-0x2f */ + 8640, 8642, 8644, 8646, 8648, 8650, 8652, 8654, /* 0x30-0x37 */ + 8656, 8658, 8660, 8662, 8664, 8666, 8668, 8670, /* 0x38-0x3f */ + 8672, 8674, 8676, 8678, 8680, 8682, 8684, 8686, /* 0x40-0x47 */ + 8688, 8690, 8692, 8694, 8696, 8698, 8700, 8702, /* 0x48-0x4f */ + 8704, 8706, 8708, 8710, 8712, 8714, 8716, 8718, /* 0x50-0x57 */ + 8720, 8722, 8724, 8726, 8728, 8730, 8732, 8734, /* 0x58-0x5f */ + 8736, 8738, 8740, 8742, 8744, 8746, 8748, 8750, /* 0x60-0x67 */ + 8752, 8754, 8756, 8758, 8760, 8762, 8764, 8766, /* 0x68-0x6f */ + 8768, 8770, 8772, 8774, 8776, 8778, 8780, 8782, /* 0x70-0x77 */ + 8784, 8786, 8788, 8790, 8792, 8794, 8796, 8798, /* 0x78-0x7f */ + 8800, 8802, 8804, 8806, 8808, 8810, 8812, 8814, /* 0x80-0x87 */ + 8816, 8818, 8820, 8822, 8824, 8826, 8828, 8830, /* 0x88-0x8f */ + 8832, 8834, 8836, 8838, 8840, 8842, 8844, 8846, /* 0x90-0x97 */ + 8848, 8850, 8852, 8854, 8856, 8858, 8860, 8862, /* 0x98-0x9f */ + 8864, 8866, 8868, 8870, 8872, 8874, 8876, 8878, /* 0xa0-0xa7 */ + 8880, 8882, 8884, 8886, 8888, 8890, 8892, 8894, /* 0xa8-0xaf */ + 8896, 8898, 8900, 8902, 8904, 8906, 8908, 8910, /* 0xb0-0xb7 */ + 8912, 8914, 8916, 8918, 8920, 8922, 8924, 8926, /* 0xb8-0xbf */ + 8928, 8930, 8932, 8934, 8936, 8938, 8940, 8942, /* 0xc0-0xc7 */ + 8944, 8946, 8948, 8950, 8952, 8954, 8956, 8958, /* 0xc8-0xcf */ + 8960, 8962, 8964, 8966, 8968, 8970, 8972, 8974, /* 0xd0-0xd7 */ + 8976, 8978, 8980, 8982, 8984, 8986, 8988, 8990, /* 0xd8-0xdf */ + 8992, 8994, 8996, 8998, 9000, 9002, 9004, 9006, /* 0xe0-0xe7 */ + 9008, 9010, 9012, 9014, 9016, 9018, 9020, 9022, /* 0xe8-0xef */ + 9024, 9026, 9028, 9030, 9032, 9034, 9036, 9038, /* 0xf0-0xf7 */ + 9040, 9042, 9044, 9046, 9048, 9050, 9052, 9054, /* 0xf8-0xff */ + /* 0x2fa00 */ + 9056, 9058, 9060, 9062, 9064, 9066, 9068, 9070, /* 0x00-0x07 */ + 9072, 9074, 9076, 9078, 9080, 9082, 9084, 9086, /* 0x08-0x0f */ + 9088, 9090, 9092, 9094, 9096, 9098, 9100, 9102, /* 0x10-0x17 */ + 9104, 9106, 9108, 9110, 9112, 9114, -1, -1, /* 0x18-0x1f */ +}; + +#define translit_index(wc) \ + (wc >= 0x00a0 && wc < 0x01f8 ? translit_page00[wc-0x00a0] : \ + wc >= 0x0218 && wc < 0x0220 ? translit_page02[wc-0x0218] : \ + wc >= 0x02b8 && wc < 0x02e0 ? translit_page02_1[wc-0x02b8] : \ + wc >= 0x03d0 && wc < 0x0400 ? translit_page03[wc-0x03d0] : \ + wc == 0x0587 ? 654 : \ + wc >= 0x05f0 && wc < 0x05f8 ? translit_page05[wc-0x05f0] : \ + wc >= 0x0670 && wc < 0x0680 ? translit_page06[wc-0x0670] : \ + wc == 0x0e33 ? 678 : \ + wc >= 0x0eb0 && wc < 0x0ee0 ? translit_page0e[wc-0x0eb0] : \ + wc >= 0x0f70 && wc < 0x0f80 ? translit_page0f[wc-0x0f70] : \ + wc >= 0x1e00 && wc < 0x1ea0 ? translit_page1e[wc-0x1e00] : \ + wc >= 0x1ef0 && wc < 0x1ef8 ? translit_page1e_2[wc-0x1ef0] : \ + wc >= 0x2000 && wc < 0x2058 ? translit_page20[wc-0x2000] : \ + wc >= 0x20a8 && wc < 0x20b0 ? translit_page20_3[wc-0x20a8] : \ + wc >= 0x2100 && wc < 0x21d8 ? translit_page21[wc-0x2100] : \ + wc >= 0x2210 && wc < 0x2270 ? translit_page22[wc-0x2210] : \ + wc >= 0x22c0 && wc < 0x22f0 ? translit_page22_4[wc-0x22c0] : \ + wc >= 0x2400 && wc < 0x24f0 ? translit_page24[wc-0x2400] : \ + wc >= 0x2500 && wc < 0x2540 ? translit_page25[wc-0x2500] : \ + wc == 0x25e6 ? 2025 : \ + wc == 0x2a0c ? 2027 : \ + wc >= 0x2a70 && wc < 0x2a78 ? translit_page2a[wc-0x2a70] : \ + wc == 0x2e9f ? 2043 : \ + wc == 0x2ef3 ? 2045 : \ + wc >= 0x2f00 && wc < 0x2fd8 ? translit_page2f[wc-0x2f00] : \ + wc >= 0x3000 && wc < 0x30f8 ? translit_page30[wc-0x3000] : \ + wc >= 0x3130 && wc < 0x3190 ? translit_page31[wc-0x3130] : \ + wc >= 0x31f0 && wc < 0x3400 ? translit_page31_5[wc-0x31f0] : \ + wc >= 0xf900 && wc < 0xfa70 ? translit_pagef9[wc-0xf900] : \ + wc >= 0xfb00 && wc < 0xfb50 ? translit_pagefb[wc-0xfb00] : \ + wc >= 0xfe48 && wc < 0xfe70 ? translit_pagefe[wc-0xfe48] : \ + wc >= 0xff00 && wc < 0xfff0 ? translit_pageff[wc-0xff00] : \ + wc >= 0x1d400 && wc < 0x1d800 ? translit_page1d4[wc-0x1d400] : \ + wc >= 0x2f800 && wc < 0x2fa20 ? translit_page2f8[wc-0x2f800] : \ + -1) diff --git a/libs/libiconv/lib/ucs2.h b/libs/libiconv/lib/ucs2.h new file mode 100644 index 00000000..206b8cca --- /dev/null +++ b/libs/libiconv/lib/ucs2.h @@ -0,0 +1,68 @@ +/* + * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UCS-2 + */ + +/* Here we accept FFFE/FEFF marks as endianness indicators everywhere + in the stream, not just at the beginning. The default is big-endian. */ +/* The state is 0 if big-endian, 1 if little-endian. */ +static int +ucs2_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + state_t state = conv->istate; + int count = 0; + for (; n >= 2;) { + ucs4_t wc = (state ? s[0] + (s[1] << 8) : (s[0] << 8) + s[1]); + s += 2; n -= 2; count += 2; + if (wc == 0xfeff) { + } else if (wc == 0xfffe) { + state ^= 1; + } else if (wc >= 0xd800 && wc < 0xe000) { + conv->istate = state; + return RET_SHIFT_ILSEQ(count); + } else { + *pwc = wc; + conv->istate = state; + return count; + } + } + conv->istate = state; + return RET_TOOFEW(count); +} + +/* But we output UCS-2 in big-endian order, without byte-order mark. */ +/* RFC 2152 says: + "ISO/IEC 10646-1:1993(E) specifies that when characters the UCS-2 form are + serialized as octets, that the most significant octet appear first." */ +static int +ucs2_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x10000 && wc != 0xfffe && !(wc >= 0xd800 && wc < 0xe000)) { + if (n >= 2) { + r[0] = (unsigned char) (wc >> 8); + r[1] = (unsigned char) wc; + return 2; + } else + return RET_TOOSMALL; + } else + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/ucs2be.h b/libs/libiconv/lib/ucs2be.h new file mode 100644 index 00000000..150c0a36 --- /dev/null +++ b/libs/libiconv/lib/ucs2be.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UCS-2BE = UCS-2 big endian + */ + +static int +ucs2be_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + if (n >= 2) { + if (s[0] >= 0xd8 && s[0] < 0xe0) { + return RET_ILSEQ; + } else { + *pwc = (s[0] << 8) + s[1]; + return 2; + } + } + return RET_TOOFEW(0); +} + +static int +ucs2be_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x10000 && !(wc >= 0xd800 && wc < 0xe000)) { + if (n >= 2) { + r[0] = (unsigned char) (wc >> 8); + r[1] = (unsigned char) wc; + return 2; + } else + return RET_TOOSMALL; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/ucs2internal.h b/libs/libiconv/lib/ucs2internal.h new file mode 100644 index 00000000..d482aeac --- /dev/null +++ b/libs/libiconv/lib/ucs2internal.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UCS-2-INTERNAL = UCS-2 with machine dependent endianness and alignment + */ + +static int +ucs2internal_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + if (n >= 2) { + unsigned short x = *(const unsigned short *)s; + if (x >= 0xd800 && x < 0xe000) { + return RET_ILSEQ; + } else { + *pwc = x; + return 2; + } + } + return RET_TOOFEW(0); +} + +static int +ucs2internal_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x10000 && !(wc >= 0xd800 && wc < 0xe000)) { + if (n >= 2) { + *(unsigned short *)r = wc; + return 2; + } else + return RET_TOOSMALL; + } else + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/ucs2le.h b/libs/libiconv/lib/ucs2le.h new file mode 100644 index 00000000..49018612 --- /dev/null +++ b/libs/libiconv/lib/ucs2le.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UCS-2LE = UCS-2 little endian + */ + +static int +ucs2le_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + if (n >= 2) { + if (s[1] >= 0xd8 && s[1] < 0xe0) { + return RET_ILSEQ; + } else { + *pwc = s[0] + (s[1] << 8); + return 2; + } + } + return RET_TOOFEW(0); +} + +static int +ucs2le_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x10000 && !(wc >= 0xd800 && wc < 0xe000)) { + if (n >= 2) { + r[0] = (unsigned char) wc; + r[1] = (unsigned char) (wc >> 8); + return 2; + } else + return RET_TOOSMALL; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/ucs2swapped.h b/libs/libiconv/lib/ucs2swapped.h new file mode 100644 index 00000000..f426f406 --- /dev/null +++ b/libs/libiconv/lib/ucs2swapped.h @@ -0,0 +1,60 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UCS-2-SWAPPED = UCS-2-INTERNAL with inverted endianness + */ + +static int +ucs2swapped_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + /* This function assumes that 'unsigned short' has exactly 16 bits. */ + if (sizeof(unsigned short) != 2) abort(); + + if (n >= 2) { + unsigned short x = *(const unsigned short *)s; + x = (x >> 8) | (x << 8); + if (x >= 0xd800 && x < 0xe000) { + return RET_ILSEQ; + } else { + *pwc = x; + return 2; + } + } + return RET_TOOFEW(0); +} + +static int +ucs2swapped_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + /* This function assumes that 'unsigned short' has exactly 16 bits. */ + if (sizeof(unsigned short) != 2) abort(); + + if (wc < 0x10000 && !(wc >= 0xd800 && wc < 0xe000)) { + if (n >= 2) { + unsigned short x = wc; + x = (x >> 8) | (x << 8); + *(unsigned short *)r = x; + return 2; + } else + return RET_TOOSMALL; + } else + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/ucs4.h b/libs/libiconv/lib/ucs4.h new file mode 100644 index 00000000..00d08d25 --- /dev/null +++ b/libs/libiconv/lib/ucs4.h @@ -0,0 +1,69 @@ +/* + * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UCS-4 + */ + +/* Here we accept FFFE0000/0000FEFF marks as endianness indicators everywhere + in the stream, not just at the beginning. The default is big-endian. */ +/* The state is 0 if big-endian, 1 if little-endian. */ +static int +ucs4_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + state_t state = conv->istate; + int count = 0; + for (; n >= 4;) { + ucs4_t wc = (state + ? s[0] + (s[1] << 8) + (s[2] << 16) + (s[3] << 24) + : (s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]); + s += 4; n -= 4; count += 4; + if (wc == 0x0000feff) { + } else if (wc == 0xfffe0000u) { + state ^= 1; + } else if (wc <= 0x7fffffff) { + *pwc = wc; + conv->istate = state; + return count; + } else { + conv->istate = state; + return RET_SHIFT_ILSEQ(count); + } + } + conv->istate = state; + return RET_TOOFEW(count); +} + +/* But we output UCS-4 in big-endian order, without byte-order mark. */ +static int +ucs4_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc <= 0x7fffffff) { + if (n >= 4) { + r[0] = (unsigned char) (wc >> 24); + r[1] = (unsigned char) (wc >> 16); + r[2] = (unsigned char) (wc >> 8); + r[3] = (unsigned char) wc; + return 4; + } else + return RET_TOOSMALL; + } else + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/ucs4be.h b/libs/libiconv/lib/ucs4be.h new file mode 100644 index 00000000..241bc158 --- /dev/null +++ b/libs/libiconv/lib/ucs4be.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 1999-2000 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UCS-4BE = UCS-4 big endian + */ + +static int +ucs4be_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + if (n >= 4) { + *pwc = (s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]; + return 4; + } + return RET_TOOFEW(0); +} + +static int +ucs4be_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 4) { + r[0] = (unsigned char) (wc >> 24); + r[1] = (unsigned char) (wc >> 16); + r[2] = (unsigned char) (wc >> 8); + r[3] = (unsigned char) wc; + return 4; + } else + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/ucs4internal.h b/libs/libiconv/lib/ucs4internal.h new file mode 100644 index 00000000..bd793a3f --- /dev/null +++ b/libs/libiconv/lib/ucs4internal.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 1999-2000 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UCS-4-INTERNAL = UCS-4 with machine dependent endianness and alignment + */ + +static int +ucs4internal_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + if (n >= 4) { + *pwc = *(const unsigned int *)s; + return 4; + } + return RET_TOOFEW(0); +} + +static int +ucs4internal_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 4) { + *(unsigned int *)r = wc; + return 4; + } else + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/ucs4le.h b/libs/libiconv/lib/ucs4le.h new file mode 100644 index 00000000..0c762fec --- /dev/null +++ b/libs/libiconv/lib/ucs4le.h @@ -0,0 +1,46 @@ +/* + * Copyright (C) 1999-2000 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UCS-4LE = UCS-4 little endian + */ + +static int +ucs4le_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + if (n >= 4) { + *pwc = s[0] + (s[1] << 8) + (s[2] << 16) + (s[3] << 24); + return 4; + } + return RET_TOOFEW(0); +} + +static int +ucs4le_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 4) { + r[0] = (unsigned char) wc; + r[1] = (unsigned char) (wc >> 8); + r[2] = (unsigned char) (wc >> 16); + r[3] = (unsigned char) (wc >> 24); + return 4; + } else + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/ucs4swapped.h b/libs/libiconv/lib/ucs4swapped.h new file mode 100644 index 00000000..6a292ecd --- /dev/null +++ b/libs/libiconv/lib/ucs4swapped.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 1999-2000 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UCS-4-SWAPPED = UCS-4-INTERNAL with inverted endianness + */ + +static int +ucs4swapped_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + /* This function assumes that 'unsigned int' has exactly 32 bits. */ + if (sizeof(unsigned int) != 4) abort(); + + if (n >= 4) { + unsigned int x = *(const unsigned int *)s; + x = (x >> 24) | ((x >> 8) & 0xff00) | ((x & 0xff00) << 8) | (x << 24); + *pwc = x; + return 4; + } + return RET_TOOFEW(0); +} + +static int +ucs4swapped_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + /* This function assumes that 'unsigned int' has exactly 32 bits. */ + if (sizeof(unsigned int) != 4) abort(); + + if (n >= 4) { + unsigned int x = wc; + x = (x >> 24) | ((x >> 8) & 0xff00) | ((x & 0xff00) << 8) | (x << 24); + *(unsigned int *)r = x; + return 4; + } else + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/uhc_1.h b/libs/libiconv/lib/uhc_1.h new file mode 100644 index 00000000..7b0c7258 --- /dev/null +++ b/libs/libiconv/lib/uhc_1.h @@ -0,0 +1,1725 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * Unified Hangul Code part 1 + */ + +static const unsigned short uhc_1_2uni_main_page81[64] = { + 0xac02, 0xac8d, 0xad14, 0xad91, 0xadfa, 0xae7a, 0xaee6, 0xaf57, + 0xafbf, 0xb030, 0xb0a5, 0xb122, 0xb19e, 0xb207, 0xb26f, 0xb2f0, + 0xb366, 0xb3e1, 0xb445, 0xb4ad, 0xb51e, 0xb590, 0xb600, 0xb661, + 0xb6c3, 0xb723, 0xb79f, 0xb811, 0xb885, 0xb8f1, 0xb95a, 0xb9d4, + 0xba47, 0xbac2, 0xbb28, 0xbb9a, 0xbc03, 0xbc80, 0xbcfe, 0xbd67, + 0xbdd2, 0xbe3d, 0xbeb8, 0xbf23, 0xbf83, 0xbfe6, 0xc040, 0xc0a7, + 0xc132, 0xc1b1, 0xc224, 0xc297, 0xc310, 0xc37a, 0xc3db, 0xc446, + 0xc4aa, 0xc50f, 0xc596, 0xc626, 0xc6a8, 0xc726, 0xc7b8, 0xc832, +}; +static const unsigned char uhc_1_2uni_page81[5696] = { + /* 0x81 */ + 0x00, 0x01, 0x03, 0x04, 0x09, 0x0a, 0x0b, 0x0c, + 0x0d, 0x16, 0x1c, 0x1d, 0x1f, 0x20, 0x21, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2c, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x38, 0x39, 0x3b, + 0x3c, 0x3d, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, 0x4a, 0x4c, 0x4d, 0x4e, + 0x4f, 0x50, 0x51, 0x53, 0x54, 0x55, 0x57, 0x58, + 0x59, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x6b, 0x6c, 0x6d, 0x70, 0x71, 0x73, 0x74, + 0x77, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x80, 0x85, + 0x86, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x11, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1e, 0x20, 0x21, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2d, + 0x31, 0x32, 0x33, 0x35, 0x36, 0x38, 0x39, 0x3a, + 0x3c, 0x3d, 0x3e, 0x40, 0x41, 0x42, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x49, 0x4b, 0x4c, 0x4d, 0x4e, + 0x4f, 0x50, 0x51, 0x52, 0x55, 0x56, 0x58, 0x59, + 0x5c, 0x5e, 0x60, 0x61, 0x65, 0x67, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x71, 0x72, 0x74, 0x75, 0x76, + 0x78, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x81, 0x83, + 0x85, 0x86, + /* 0x82 */ + 0x00, 0x01, 0x02, 0x03, 0x05, 0x06, 0x07, 0x09, + 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x16, 0x17, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x22, 0x23, 0x25, 0x26, 0x27, 0x29, + 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x32, 0x34, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3e, + 0x3f, 0x41, 0x42, 0x43, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x4b, 0x4c, 0x4e, 0x50, 0x51, 0x52, + 0x53, 0x54, 0x55, 0x56, 0x57, 0x5a, 0x5b, 0x5d, + 0x5e, 0x63, 0x64, 0x65, 0x66, 0x6a, 0x6c, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x76, 0x77, 0x79, 0x7a, + 0x7b, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, 0x31, 0x32, 0x34, 0x35, + 0x36, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, + 0x41, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x4c, 0x4d, 0x4e, 0x50, 0x51, 0x52, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, + 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, + 0x65, 0x66, + /* 0x83 */ + 0x00, 0x01, 0x03, 0x04, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0d, 0x10, 0x12, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x38, 0x39, 0x3b, + 0x3c, 0x3f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x48, + 0x4a, 0x4d, 0x4e, 0x4f, 0x51, 0x55, 0x57, 0x58, + 0x59, 0x5b, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x64, + 0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x70, 0x71, 0x73, + 0x74, 0x75, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, + 0x7d, 0x00, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, + 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x45, 0x47, 0x48, + 0x49, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, + 0x54, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x60, + 0x61, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x6b, + /* 0x84 */ + 0x00, 0x01, 0x03, 0x04, 0x06, 0x08, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0f, 0x10, 0x11, 0x13, 0x14, + 0x15, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x23, 0x24, 0x25, 0x26, 0x28, + 0x29, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, + 0x42, 0x43, 0x44, 0x45, 0x48, 0x49, 0x4b, 0x4d, + 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x58, + 0x5a, 0x5e, 0x5f, 0x60, 0x61, 0x64, 0x65, 0x66, + 0x67, 0x68, 0x69, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x00, 0x01, 0x02, 0x03, 0x04, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, + 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x2a, 0x2b, 0x2c, + 0x2e, 0x2f, 0x30, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x3b, 0x3c, 0x3d, 0x3f, 0x40, 0x41, + 0x42, 0x43, 0x44, 0x46, 0x47, 0x48, 0x49, 0x4a, + 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, + 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, + 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x63, 0x64, + 0x66, 0x67, + /* 0x85 */ + 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x0b, + 0x0d, 0x10, 0x11, 0x12, 0x13, 0x14, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x33, 0x34, + 0x36, 0x37, 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, + 0x3f, 0x40, 0x43, 0x44, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x4b, 0x4c, 0x4e, 0x4f, 0x50, 0x52, 0x53, + 0x54, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, + 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x67, 0x68, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x16, 0x17, 0x19, + 0x1b, 0x1d, 0x1f, 0x20, 0x21, 0x22, 0x26, 0x28, + 0x2a, 0x2b, 0x2c, 0x2e, 0x2f, 0x30, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, + 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, + 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, + 0x4b, 0x4e, 0x4f, 0x51, 0x52, 0x53, 0x55, 0x56, + 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5e, 0x60, 0x62, + 0x63, 0x64, 0x65, 0x66, 0x67, 0x6b, 0x6d, 0x6e, + 0x73, 0x74, + /* 0x86 */ + 0x00, 0x01, 0x02, 0x05, 0x0b, 0x0d, 0x11, 0x12, + 0x14, 0x15, 0x16, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x21, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2d, 0x2e, 0x30, 0x31, 0x32, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3c, 0x3d, 0x3e, + 0x3f, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x65, 0x68, 0x69, 0x6a, 0x6c, + 0x6f, 0x70, 0x71, 0x72, 0x75, 0x79, 0x7a, 0x7b, + 0x7c, 0x00, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x14, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x20, 0x21, 0x23, + 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x30, 0x31, 0x34, 0x35, 0x37, 0x38, 0x39, + 0x3b, 0x3c, 0x3d, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x58, 0x59, 0x5b, 0x5c, 0x5d, 0x5f, + 0x61, 0x62, 0x63, 0x64, 0x65, 0x68, 0x6a, 0x6c, + 0x6d, 0x6e, 0x6f, 0x73, 0x74, 0x75, 0x77, 0x78, + 0x79, 0x7b, + /* 0x87 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2f, 0x30, 0x31, + 0x33, 0x34, 0x35, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x40, 0x42, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x48, 0x49, 0x4c, 0x4d, 0x4f, 0x50, 0x51, + 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, + 0x5c, 0x5e, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, + 0x68, 0x00, 0x02, 0x03, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0f, 0x11, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x52, 0x53, 0x54, 0x56, 0x57, 0x58, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x63, 0x64, 0x65, + 0x66, 0x67, + /* 0x88 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x23, 0x24, 0x26, 0x27, 0x28, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x33, 0x35, 0x38, + 0x39, 0x3a, 0x3c, 0x3e, 0x3f, 0x40, 0x42, 0x43, + 0x44, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x5b, 0x5c, 0x5e, 0x5f, + 0x60, 0x62, 0x64, 0x65, 0x66, 0x67, 0x68, 0x6b, + 0x6d, 0x6f, 0x70, 0x71, 0x72, 0x74, 0x78, 0x7a, + 0x7b, 0x00, 0x01, 0x02, 0x06, 0x0c, 0x0d, 0x0e, + 0x12, 0x13, 0x15, 0x16, 0x17, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x22, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2d, 0x2e, 0x2f, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, + 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, + 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, + 0x62, 0x63, 0x67, 0x69, 0x6a, 0x6d, 0x70, 0x71, + 0x72, 0x73, + /* 0x89 */ + 0x00, 0x02, 0x04, 0x06, 0x07, 0x09, 0x0c, 0x0d, + 0x0f, 0x10, 0x11, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1c, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x27, 0x28, 0x29, 0x2b, 0x2c, 0x2d, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, + 0x43, 0x44, 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x60, 0x61, 0x63, 0x64, 0x67, 0x69, + 0x6b, 0x6c, 0x6d, 0x70, 0x72, 0x74, 0x76, 0x78, + 0x79, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x30, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x38, 0x39, 0x3a, 0x3c, + 0x3d, 0x3e, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x49, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, + 0x62, 0x63, + /* 0x8a */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0d, 0x0e, 0x10, 0x11, 0x12, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1d, + 0x1f, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, + 0x42, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, + 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, + 0x53, 0x54, 0x55, 0x56, 0x57, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x60, 0x61, 0x62, 0x64, 0x65, + 0x66, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x09, 0x0b, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x14, 0x15, 0x16, 0x18, 0x19, 0x1a, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x24, 0x25, + 0x26, 0x27, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, + 0x31, 0x32, 0x34, 0x35, 0x38, 0x3a, 0x3b, 0x3c, + 0x3d, 0x3e, 0x41, 0x43, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, + 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x65, 0x66, 0x69, 0x6a, 0x6c, + 0x6d, 0x70, + /* 0x8b */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x14, 0x15, 0x17, 0x18, + 0x19, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, + 0x24, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x30, 0x31, + 0x33, 0x34, 0x35, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x40, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, + 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, + 0x71, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x12, 0x13, 0x15, 0x16, 0x17, 0x19, 0x1c, + 0x1d, 0x1e, 0x1f, 0x22, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2e, 0x2f, 0x31, 0x32, 0x33, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3e, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5d, + 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, + 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, + 0x6e, 0x6f, + /* 0x8c */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x12, 0x13, 0x15, 0x16, 0x17, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, + 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x3d, 0x3e, 0x40, 0x41, 0x42, 0x44, + 0x45, 0x46, 0x47, 0x48, 0x49, 0x4c, 0x4d, 0x4e, + 0x4f, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, + /* 0x8d */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2e, 0x2f, 0x30, 0x32, + 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3f, 0x40, 0x41, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, + 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, + 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, + 0x5f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x07, 0x08, + 0x0a, 0x0b, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x17, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x22, 0x23, 0x24, 0x26, 0x27, 0x28, + 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3e, 0x3f, 0x40, 0x42, 0x43, 0x44, 0x46, + 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4f, 0x51, + 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x5b, 0x5c, + 0x5e, 0x5f, 0x60, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x67, 0x68, 0x6b, 0x70, 0x71, 0x72, 0x77, 0x78, + 0x7a, 0x7b, + /* 0x8e */ + 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x0b, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x17, + 0x18, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x29, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, + 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, + 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, + 0x4b, 0x4c, 0x4f, 0x50, 0x52, 0x53, 0x54, 0x56, + 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5f, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x6b, 0x6c, 0x6e, 0x6f, + 0x70, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x09, 0x0b, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x15, 0x16, 0x18, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x21, 0x22, 0x25, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x30, 0x31, 0x32, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, 0x41, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4d, 0x4e, 0x50, 0x51, 0x52, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5d, + 0x5f, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x68, + 0x69, 0x6a, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, + 0x72, 0x73, + /* 0x8f */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2c, 0x2d, 0x2e, 0x30, 0x31, 0x32, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3d, 0x3f, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x48, 0x49, + 0x4a, 0x4c, 0x4d, 0x4e, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x59, 0x5b, 0x5d, 0x5e, + 0x5f, 0x60, 0x61, 0x62, 0x65, 0x66, 0x68, 0x69, + 0x6a, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x09, 0x0b, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2e, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4d, 0x4e, 0x50, + 0x51, 0x52, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x5c, 0x5d, 0x5f, 0x61, 0x62, 0x63, 0x64, + 0x65, 0x66, + /* 0x90 */ + 0x00, 0x01, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x10, 0x12, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1c, 0x1d, 0x1f, 0x20, + 0x21, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2c, 0x2e, 0x31, 0x32, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x54, 0x55, 0x57, 0x58, 0x59, 0x5b, 0x5c, + 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x64, 0x66, 0x68, + 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x70, 0x71, 0x73, + 0x79, 0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x0b, + 0x0c, 0x0e, 0x12, 0x13, 0x15, 0x16, 0x17, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x22, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2e, 0x2f, 0x30, 0x31, + 0x32, 0x33, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, + 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, + 0x66, 0x67, 0x69, 0x6a, 0x6b, 0x6d, 0x6f, 0x70, + 0x71, 0x72, + /* 0x91 */ + 0x00, 0x03, 0x05, 0x08, 0x09, 0x0a, 0x0b, 0x0f, + 0x10, 0x12, 0x13, 0x14, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1f, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x2b, 0x2c, 0x2e, 0x2f, 0x30, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, + 0x3b, 0x3f, 0x41, 0x42, 0x43, 0x44, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x63, 0x66, 0x67, 0x68, 0x6a, 0x6c, 0x6d, + 0x6e, 0x6f, 0x70, 0x73, 0x75, 0x77, 0x78, 0x79, + 0x7a, 0x00, 0x01, 0x03, 0x04, 0x05, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x18, 0x19, 0x1a, + 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3b, + 0x3c, 0x3d, 0x3f, 0x40, 0x41, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4c, 0x4e, 0x50, + 0x51, 0x52, 0x53, 0x54, 0x55, 0x57, 0x58, 0x59, + 0x5b, 0x5c, 0x5d, 0x5f, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, + /* 0x92 */ + 0x00, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0f, 0x11, 0x12, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1e, 0x20, 0x22, 0x23, 0x24, 0x26, + 0x29, 0x2a, 0x2b, 0x2d, 0x2e, 0x2f, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x3a, 0x3c, + 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, + 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, + 0x5e, 0x5f, 0x61, 0x62, 0x63, 0x65, 0x66, 0x67, + 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, + 0x71, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0b, 0x0c, 0x0d, 0x0f, 0x10, + 0x11, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1b, 0x1c, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x27, 0x28, 0x29, 0x2b, 0x2c, 0x2d, + 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x37, + 0x38, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, + 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x60, 0x61, 0x63, + 0x64, 0x67, + /* 0x93 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x07, 0x0b, 0x0d, + 0x0f, 0x10, 0x16, 0x17, 0x1d, 0x1e, 0x1f, 0x20, + 0x23, 0x25, 0x27, 0x28, 0x29, 0x2b, 0x2c, 0x2f, + 0x30, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x3b, 0x3c, 0x3f, 0x43, 0x44, 0x45, 0x47, + 0x48, 0x4b, 0x4c, 0x4e, 0x4f, 0x50, 0x51, 0x52, + 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x09, + 0x0a, 0x0d, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x16, + 0x18, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x22, 0x23, + 0x25, 0x26, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, + 0x2f, 0x32, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3e, 0x3f, 0x41, 0x42, 0x43, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4e, 0x52, 0x53, + 0x54, 0x56, 0x57, 0x59, 0x5a, 0x5b, 0x5d, 0x5e, + 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, + 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, + 0x6f, 0x70, 0x71, 0x72, 0x73, 0x77, 0x79, 0x7a, + 0x7b, 0x7d, + /* 0x94 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x0a, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x13, 0x14, + 0x15, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4c, 0x4d, 0x4f, 0x50, 0x51, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5c, 0x5d, 0x5e, + 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x67, + 0x68, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x1b, 0x1c, 0x1e, 0x1f, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x2b, 0x2d, 0x2f, 0x30, 0x31, 0x34, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3e, + 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x48, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, + 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x69, 0x6a, + /* 0x95 */ + 0x00, 0x01, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1f, 0x20, 0x21, 0x23, 0x24, 0x25, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2f, 0x30, + 0x32, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3c, + 0x3d, 0x3f, 0x40, 0x41, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x48, 0x49, 0x4c, 0x4e, 0x4f, 0x50, 0x51, + 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x09, 0x0a, 0x0c, 0x0d, 0x0e, 0x10, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x19, 0x1b, 0x1f, 0x20, 0x21, + 0x22, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2c, 0x2e, + 0x2f, 0x30, 0x31, 0x32, 0x35, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x41, 0x42, 0x44, 0x45, 0x46, 0x48, + 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x51, 0x55, + 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, + 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, + /* 0x96 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x1a, 0x1b, 0x1d, 0x1e, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x29, 0x2a, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, + 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x4a, + 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, + 0x5d, 0x5e, 0x5f, 0x62, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1f, 0x20, + 0x22, 0x23, 0x24, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2f, 0x30, 0x31, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, + 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, + 0x5e, 0x5f, + /* 0x97 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2e, 0x2f, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, + 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x4b, 0x4c, + 0x4e, 0x4f, 0x50, 0x52, 0x53, 0x54, 0x55, 0x56, + 0x57, 0x58, 0x5a, 0x5b, 0x5d, 0x5f, 0x60, 0x61, + 0x62, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, + 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, + 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, + 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x57, + 0x58, 0x59, + /* 0x98 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x19, + 0x1a, 0x1b, 0x1d, 0x1e, 0x1f, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, 0x52, 0x53, 0x55, 0x56, 0x57, 0x59, + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x62, 0x64, + 0x66, 0x00, 0x01, 0x02, 0x03, 0x04, 0x07, 0x0a, + 0x0b, 0x10, 0x11, 0x12, 0x13, 0x14, 0x17, 0x1b, + 0x1c, 0x1d, 0x1f, 0x20, 0x23, 0x24, 0x26, 0x27, + 0x28, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x33, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3f, + 0x40, 0x42, 0x43, 0x44, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x4b, 0x4c, 0x4f, 0x51, 0x53, 0x54, 0x55, + 0x56, 0x57, 0x58, 0x5a, 0x5b, 0x5c, 0x5e, 0x5f, + 0x60, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, + 0x6a, 0x6b, 0x6c, 0x6d, 0x6f, 0x70, 0x71, 0x72, + 0x73, 0x74, 0x7a, 0x7b, 0x7e, 0x81, 0x82, 0x83, + 0x84, 0x87, + /* 0x99 */ + 0x00, 0x01, 0x02, 0x03, 0x05, 0x08, 0x09, 0x0b, + 0x0c, 0x0d, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x18, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, + 0x24, 0x25, 0x27, 0x28, 0x29, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x34, 0x38, 0x39, 0x3a, + 0x3b, 0x3c, 0x3d, 0x3f, 0x40, 0x41, 0x43, 0x44, + 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x54, 0x55, 0x56, + 0x57, 0x58, 0x59, 0x5d, 0x5f, 0x60, 0x61, 0x63, + 0x65, 0x66, 0x67, 0x68, 0x69, 0x6c, 0x6e, 0x70, + 0x71, 0x72, 0x74, 0x75, 0x78, 0x79, 0x7b, 0x7c, + 0x7d, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x14, 0x15, 0x16, 0x18, 0x19, + 0x1a, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, + 0x24, 0x25, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x30, 0x31, 0x32, 0x34, 0x35, 0x36, 0x38, + 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x41, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4d, + 0x4e, 0x50, 0x51, 0x52, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5d, 0x5f, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x69, 0x6a, 0x6c, 0x6d, 0x70, + 0x71, 0x72, + /* 0x9a */ + 0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x0a, 0x0c, + 0x0f, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2e, 0x2f, 0x31, 0x32, 0x33, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3d, + 0x3e, 0x3f, 0x40, 0x42, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x51, 0x52, + 0x53, 0x54, 0x55, 0x56, 0x57, 0x5a, 0x5c, 0x5e, + 0x5f, 0x60, 0x61, 0x62, 0x63, 0x66, 0x67, 0x68, + 0x69, 0x6a, 0x6b, 0x6d, 0x6e, 0x6f, 0x70, 0x71, + 0x72, 0x00, 0x02, 0x03, 0x05, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0f, 0x10, 0x12, 0x13, 0x14, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1f, 0x21, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, + 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, + 0x43, 0x44, 0x47, 0x48, 0x4a, 0x4b, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x57, 0x59, 0x5b, 0x5c, + 0x5d, 0x5e, 0x60, 0x63, 0x66, 0x67, 0x68, 0x6a, + 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x73, 0x74, + 0x77, 0x78, + /* 0x9b */ + 0x00, 0x01, 0x02, 0x06, 0x07, 0x09, 0x0a, 0x0b, + 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x16, + 0x17, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, + 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, + 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x5a, 0x5b, + 0x5d, 0x5e, 0x5f, 0x61, 0x63, 0x64, 0x65, 0x66, + 0x67, 0x00, 0x01, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0b, 0x0c, 0x0d, 0x0f, 0x10, 0x11, 0x13, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, + 0x5d, 0x60, + /* 0x9c */ + 0x00, 0x02, 0x03, 0x06, 0x08, 0x09, 0x0a, 0x0b, + 0x0c, 0x0f, 0x10, 0x11, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x1b, 0x1c, 0x1e, 0x1f, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c, 0x2e, 0x2f, 0x30, 0x31, 0x32, + 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x4a, 0x4b, 0x4c, + 0x4d, 0x4e, 0x4f, 0x50, 0x52, 0x53, 0x54, 0x56, + 0x57, 0x58, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x00, 0x01, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x20, 0x21, + 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x30, 0x31, 0x32, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4f, 0x50, + 0x51, 0x52, 0x53, 0x54, 0x55, 0x57, 0x58, 0x59, + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, + 0x62, 0x63, + /* 0x9d */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0f, 0x10, + 0x11, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x40, 0x41, 0x42, + 0x43, 0x44, 0x45, 0x48, 0x49, 0x4b, 0x4c, 0x4d, + 0x4f, 0x51, 0x52, 0x53, 0x54, 0x58, 0x59, 0x5a, + 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x63, + 0x64, 0x00, 0x02, 0x03, 0x04, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x1b, + 0x1c, 0x1e, 0x1f, 0x20, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x2b, 0x2d, 0x2f, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x37, 0x38, 0x3c, 0x40, 0x41, + 0x42, 0x43, 0x47, 0x4b, 0x4c, 0x4d, 0x50, 0x53, + 0x54, 0x56, 0x57, 0x58, 0x5a, 0x5b, 0x5c, 0x5d, + 0x5e, 0x5f, 0x60, 0x63, 0x67, 0x68, 0x69, 0x6a, + 0x6b, 0x6c, 0x6f, 0x70, 0x72, 0x73, 0x74, 0x76, + 0x77, 0x79, 0x7a, 0x7b, 0x7c, 0x7f, 0x81, 0x83, + 0x84, 0x85, + /* 0x9e */ + 0x00, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x20, 0x21, 0x24, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x35, 0x37, 0x39, 0x3c, 0x3d, 0x3f, 0x40, + 0x41, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4c, 0x4e, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, + 0x59, 0x5b, 0x5c, 0x5d, 0x5f, 0x62, 0x63, 0x64, + 0x65, 0x6c, 0x6d, 0x6e, 0x73, 0x74, 0x75, 0x77, + 0x78, 0x79, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, + 0x81, 0x84, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, + 0x8d, 0x00, 0x01, 0x03, 0x04, 0x05, 0x09, 0x0b, + 0x0c, 0x10, 0x12, 0x14, 0x16, 0x17, 0x18, 0x19, + 0x1c, 0x1d, 0x1f, 0x20, 0x21, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2c, 0x30, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x38, 0x39, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x47, 0x48, 0x4a, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x54, 0x55, 0x57, 0x58, 0x59, 0x5b, 0x5c, + 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x64, 0x66, 0x68, + 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x70, 0x71, 0x73, + 0x74, 0x75, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, + 0x7d, 0x80, + /* 0x9f */ + 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x0a, + 0x0b, 0x0d, 0x0e, 0x0f, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x1a, 0x1c, 0x1e, 0x1f, 0x20, 0x21, 0x22, + 0x23, 0x26, 0x27, 0x29, 0x2a, 0x2b, 0x2d, 0x2e, + 0x2f, 0x30, 0x31, 0x32, 0x33, 0x36, 0x37, 0x3a, + 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, 0x42, 0x43, 0x45, + 0x46, 0x47, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, + 0x4f, 0x52, 0x53, 0x54, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x5b, 0x5e, 0x5f, 0x61, 0x62, 0x63, 0x65, + 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6e, 0x70, + 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x7a, 0x7b, + 0x7d, 0x00, 0x01, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0c, 0x0e, 0x10, 0x12, 0x13, 0x14, + 0x15, 0x18, 0x19, 0x1b, 0x1c, 0x1d, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x25, 0x28, 0x2a, 0x33, 0x34, + 0x35, 0x37, 0x38, 0x39, 0x3b, 0x3c, 0x3d, 0x3e, + 0x3f, 0x40, 0x41, 0x43, 0x44, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x50, 0x51, 0x53, + 0x54, 0x55, 0x59, 0x5a, 0x5b, 0x5c, 0x60, 0x65, + 0x66, 0x67, 0x69, 0x6c, 0x6d, 0x6f, 0x73, 0x75, + 0x76, 0x77, 0x78, 0x79, 0x7c, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x88, 0x89, 0x8b, 0x8c, 0x8d, 0x8f, + 0x90, 0x91, + /* 0xa0 */ + 0x00, 0x01, 0x02, 0x03, 0x06, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x12, 0x13, 0x15, 0x17, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x21, 0x22, + 0x23, 0x24, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2d, 0x2e, 0x2f, 0x31, 0x32, 0x33, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, + 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, + 0x47, 0x4a, 0x4b, 0x4d, 0x4e, 0x4f, 0x51, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x5a, 0x5c, 0x5f, 0x60, + 0x61, 0x62, 0x63, 0x66, 0x67, 0x69, 0x6a, 0x6b, + 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x76, + 0x78, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, + 0x08, 0x09, 0x0b, 0x0c, 0x0d, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x18, 0x19, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, + 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x40, + 0x41, 0x43, 0x44, 0x45, 0x47, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x50, 0x52, 0x56, 0x57, 0x58, 0x5c, + 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x63, 0x64, 0x65, + 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6c, 0x6e, 0x70, + 0x71, 0x72, +}; + +static int +uhc_1_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0x81 && c1 <= 0xa0)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x41 && c2 < 0x5b) || (c2 >= 0x61 && c2 < 0x7b) || (c2 >= 0x81 && c2 < 0xff)) { + unsigned int row = c1 - 0x81; + unsigned int col = c2 - (c2 >= 0x81 ? 0x4d : c2 >= 0x61 ? 0x47 : 0x41); + unsigned int i = 178 * row + col; + if (i < 5696) { + *pwc = (ucs4_t) (uhc_1_2uni_main_page81[2*row+(col>=89?1:0)] + uhc_1_2uni_page81[i]); + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short uhc_1_2charset_main[45] = { + 0x8141, 0x81cd, 0x829b, 0x8363, 0x83e9, 0x84b7, 0x8585, 0x8647, + 0x86d3, 0x87a1, 0x8869, 0x88ef, 0x89bd, 0x8a8b, 0x8b4d, 0x8bd9, + 0x8ca7, 0x8d6f, 0x8df5, 0x8ec3, 0x8f91, 0x9053, 0x90df, 0x91ad, + 0x9275, 0x92fb, 0x93c9, 0x9497, 0x9559, 0x95e5, 0x96b3, 0x9781, + 0x9843, 0x98cf, 0x999d, 0x9a65, 0x9aeb, 0x9bb9, 0x9c87, 0x9d49, + 0x9dd5, 0x9ea3, 0x9f6b, 0x9ff1, 0xa0bf, +}; +static const unsigned char uhc_1_2charset[5696] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, + 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x8b, 0x8c, 0x8d, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xb4, 0xb5, + 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0xa6, 0xa7, 0xa8, 0xa9, + 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, + 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, + 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc6, 0xc7, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, + 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, + 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, + 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, + 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, + 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, + 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x58, 0x59, + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, + 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, + 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, + 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, + 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, + 0xa2, 0xa3, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x6e, 0x6f, 0x70, 0x71, + 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, + 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, + 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0xa0, 0xa1, + 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, + 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, + 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, + 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, + 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, + 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, + 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, + 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, + 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x6b, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x92, 0x93, 0x94, 0x95, + 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, + 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, + 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, + 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, + 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9a, 0x9b, 0x9c, 0x9d, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0xb6, 0xb7, 0xb8, 0xb9, + 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x68, 0x69, + 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, + 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, + 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, + 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, + 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, + 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, + 0xb2, 0xb3, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, + 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, + 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, + 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, + 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, + 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, + 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, + 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x65, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x8c, 0x8d, + 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, + 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, + 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, + 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, + 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x7e, 0x7f, 0x80, 0x81, + 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, + 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0xb0, 0xb1, + 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, + 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, + 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x7b, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, + 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, + 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, + 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, + 0xaa, 0xab, 0xac, 0xad, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, + 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, + 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, + 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, + 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, + 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, + 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, + 0x00, 0x01, 0x02, 0x03, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, + 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, + 0x8e, 0x8f, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, + 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, + 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, + 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, + 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x78, 0x79, + 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, + 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, + 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, + 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, + 0x00, 0x01, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, + 0x72, 0x73, 0x74, 0x75, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x9c, 0x9d, + 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, + 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, + 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x8e, 0x8f, 0x90, 0x91, + 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, + 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0xc0, 0xc1, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, + 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, + 0x8a, 0x8b, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xb2, 0xb3, 0xb4, 0xb5, + 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, + 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, + 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, + 0xba, 0xbb, 0xbc, 0xbd, 0xc4, 0xc5, 0xc6, 0xc7, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, + 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, + 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, + 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, + 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, + 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, + 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, + 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, + 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, + 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, + 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x88, 0x89, + 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f, 0x90, 0x91, + 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, 0xa0, 0xa1, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, 0xc0, 0xc1, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x4c, 0x4d, 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, + 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, + 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, + 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, + 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, + 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, + 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x8b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, 0x71, + 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, 0x80, 0x81, + 0x82, 0x83, 0x84, 0x85, 0x8c, 0x8d, 0x8e, 0x8f, + 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f, + 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xac, 0xad, + 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, + 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, + 0x58, 0x59, 0x5a, 0x5b, 0x9e, 0x9f, 0xa0, 0xa1, + 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, + 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb0, 0xb1, + 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, + 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, + 0x4e, 0x4f, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, + 0x56, 0x57, 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, + 0x5e, 0x5f, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, + 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, + 0x6e, 0x6f, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, + 0x76, 0x77, 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, + 0x7e, 0x7f, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x50, 0x51, + 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, + 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x60, 0x61, + 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f, + 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, + 0x96, 0x97, 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, + 0x9e, 0x9f, 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, + 0xae, 0xaf, 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, + 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, + 0xbe, 0xbf, 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, +}; + +static const Summary16 uhc_1_uni2indx_pageac[459] = { + /* 0xac00 */ + { 0, 0xf86c }, { 9, 0xc100 }, { 12, 0x4fee }, { 23, 0xecfc }, + { 34, 0xd7fe }, { 47, 0xeeef }, { 60, 0xffff }, { 76, 0xfa6c }, + { 86, 0xe184 }, { 92, 0x4fee }, { 103, 0x68fc }, { 112, 0xc4fe }, + { 122, 0xeeed }, { 134, 0xff5f }, { 148, 0x6a6c }, { 156, 0xcf94 }, + /* 0xad00 */ + { 165, 0x4fae }, { 175, 0xeefd }, { 188, 0xcdfe }, { 200, 0xeecf }, + { 212, 0xfd4f }, { 224, 0xfeee }, { 237, 0xcff5 }, { 249, 0x4786 }, + { 256, 0xecf9 }, { 267, 0xcffe }, { 280, 0xffef }, { 295, 0xff7f }, + { 310, 0xfeec }, { 322, 0xeff4 }, { 334, 0xffee }, { 348, 0x6cff }, + /* 0xae00 */ + { 360, 0xd4fc }, { 370, 0xffef }, { 385, 0xffff }, { 401, 0xfa6c }, + { 411, 0x8b94 }, { 418, 0x4fae }, { 428, 0xecdc }, { 438, 0xc4fe }, + { 448, 0xefcf }, { 461, 0xffff }, { 477, 0xffff }, { 493, 0x8fff }, + { 506, 0x4fee }, { 517, 0xecfc }, { 528, 0xd6ff }, { 541, 0xeeef }, + /* 0xaf00 */ + { 554, 0xde7f }, { 567, 0xfffe }, { 582, 0xcfff }, { 596, 0x4fea }, + { 606, 0xfcf1 }, { 617, 0xcffe }, { 630, 0xffcf }, { 644, 0xfdff }, + { 659, 0xfeee }, { 672, 0xefdc }, { 684, 0xffff }, { 700, 0xecff }, + { 713, 0x947e }, { 722, 0xefef }, { 736, 0xfcff }, { 750, 0xfeec }, + /* 0xb000 */ + { 762, 0xefec }, { 774, 0xcfee }, { 786, 0xfeff }, { 801, 0xffff }, + { 817, 0xaacf }, { 827, 0xdd47 }, { 837, 0xffff }, { 853, 0xcfff }, + { 867, 0x4fee }, { 878, 0x68fd }, { 888, 0x04f8 }, { 894, 0xeec5 }, + { 904, 0xfc4f }, { 915, 0xfeec }, { 927, 0xffde }, { 941, 0xffff }, + /* 0xb100 */ + { 957, 0xe4ff }, { 969, 0xc4f2 }, { 977, 0xeec7 }, { 988, 0xfc4f }, + { 999, 0xfeec }, { 1011, 0xeecc }, { 1021, 0xfffe }, { 1036, 0xecff }, + { 1049, 0xd4fa }, { 1059, 0xeee3 }, { 1070, 0xfeff }, { 1085, 0xffff }, + { 1101, 0xefff }, { 1116, 0x4fee }, { 1127, 0xecff }, { 1140, 0xd5fe }, + /* 0xb200 */ + { 1152, 0xe6cf }, { 1163, 0xfd4f }, { 1175, 0xfffe }, { 1190, 0xefef }, + { 1204, 0xffff }, { 1220, 0xeeff }, { 1234, 0xfcfe }, { 1247, 0xefcf }, + { 1260, 0xfdcf }, { 1273, 0xf8ec }, { 1283, 0xeb94 }, { 1292, 0xffee }, + { 1306, 0xecff }, { 1319, 0xd4fa }, { 1329, 0x068b }, { 1335, 0x7047 }, + /* 0xb300 */ + { 1342, 0xfeec }, { 1354, 0xefc4 }, { 1364, 0xffff }, { 1380, 0xffff }, + { 1396, 0xffff }, { 1412, 0x268f }, { 1420, 0xb54f }, { 1430, 0xfeec }, + { 1442, 0xefc4 }, { 1452, 0xffee }, { 1466, 0xeefc }, { 1478, 0xffff }, + { 1494, 0xa6cf }, { 1504, 0xd54e }, { 1513, 0xfeee }, { 1526, 0xefff }, + /* 0xb400 */ + { 1541, 0xffff }, { 1557, 0xeefe }, { 1570, 0xf4fe }, { 1582, 0xffef }, + { 1597, 0xffff }, { 1613, 0xfeec }, { 1625, 0xefd4 }, { 1636, 0xffff }, + { 1652, 0xfefe }, { 1666, 0xdfff }, { 1681, 0xeeef }, { 1694, 0xfd5f }, + { 1707, 0xfeee }, { 1720, 0xcfde }, { 1732, 0x4fa6 }, { 1741, 0xfefd }, + /* 0xb500 */ + { 1755, 0xffff }, { 1771, 0xe6cf }, { 1782, 0xf84f }, { 1792, 0xfeec }, + { 1804, 0xc7c4 }, { 1812, 0x4fee }, { 1823, 0xfffc }, { 1837, 0xffff }, + { 1853, 0xffff }, { 1869, 0xffff }, { 1885, 0xf2ec }, { 1895, 0xc7c4 }, + { 1903, 0x4fee }, { 1914, 0xfefc }, { 1927, 0xefff }, { 1942, 0xffff }, + /* 0xb600 */ + { 1958, 0xffff }, { 1974, 0xfeec }, { 1986, 0xefdf }, { 2000, 0xffef }, + { 2015, 0xfeff }, { 2030, 0xffff }, { 2046, 0xfeef }, { 2060, 0xffff }, + { 2076, 0xffff }, { 2092, 0xcfff }, { 2106, 0xe7ee }, { 2118, 0xfffd }, + { 2133, 0xffff }, { 2149, 0xffef }, { 2164, 0xffff }, { 2180, 0xfeee }, + /* 0xb700 */ + { 2193, 0xffdc }, { 2206, 0xffff }, { 2222, 0x6cff }, { 2234, 0xf4fe }, + { 2246, 0xeeef }, { 2259, 0xffcf }, { 2273, 0xfeee }, { 2286, 0xcfd4 }, + { 2296, 0x4fee }, { 2307, 0xec38 }, { 2315, 0xc4fe }, { 2325, 0xfecf }, + { 2338, 0xfd7f }, { 2352, 0xffff }, { 2368, 0xcfff }, { 2382, 0x4fee }, + /* 0xb800 */ + { 2393, 0xec7c }, { 2403, 0xd4fe }, { 2414, 0xeecf }, { 2426, 0xfc4f }, + { 2437, 0xffee }, { 2451, 0xcff5 }, { 2463, 0x4fee }, { 2474, 0xeefd }, + { 2487, 0xdfff }, { 2502, 0xffff }, { 2518, 0xfeff }, { 2533, 0xfeee }, + { 2546, 0xefd4 }, { 2557, 0x5fee }, { 2569, 0xecfd }, { 2581, 0xd4fe }, + /* 0xb900 */ + { 2592, 0xffef }, { 2607, 0xfeff }, { 2622, 0xfffe }, { 2637, 0xcfff }, + { 2651, 0x6fee }, { 2663, 0xecfd }, { 2675, 0xd4fe }, { 2686, 0xeecf }, + { 2698, 0x994f }, { 2707, 0xffff }, { 2723, 0xcfff }, { 2737, 0x4fee }, + { 2748, 0x2cfd }, { 2758, 0x94f8 }, { 2766, 0xeec5 }, { 2776, 0xf84f }, + /* 0xba00 */ + { 2786, 0xfefc }, { 2799, 0xffdf }, { 2814, 0xffff }, { 2830, 0xecff }, + { 2843, 0x94fa }, { 2852, 0xeec7 }, { 2863, 0xfc4f }, { 2874, 0xfeec }, + { 2886, 0xef47 }, { 2897, 0xffff }, { 2913, 0xe4ff }, { 2925, 0xd4fa }, + { 2935, 0xfeef }, { 2949, 0xfcff }, { 2963, 0xffff }, { 2979, 0xefff }, + /* 0xbb00 */ + { 2994, 0x5fee }, { 3006, 0xeefd }, { 3019, 0xf5fe }, { 3032, 0x868f }, + { 3040, 0x5d4f }, { 3050, 0xfeee }, { 3063, 0xeff5 }, { 3076, 0xffff }, + { 3092, 0xeeff }, { 3106, 0xfffe }, { 3121, 0xeeef }, { 3134, 0xff6f }, + { 3148, 0xfeee }, { 3161, 0xfff6 }, { 3175, 0xffff }, { 3191, 0x6cff }, + /* 0xbc00 */ + { 3203, 0x44fa }, { 3211, 0x060d }, { 3216, 0xdd4f }, { 3227, 0xfeec }, + { 3239, 0xcdc4 }, { 3247, 0xdffe }, { 3261, 0xffff }, { 3277, 0xffff }, + { 3293, 0xa6cf }, { 3303, 0xf94f }, { 3314, 0xfe6c }, { 3325, 0xcfc4 }, + { 3334, 0x5fee }, { 3346, 0xeedc }, { 3357, 0xffff }, { 3373, 0xee8f }, + /* 0xbd00 */ + { 3384, 0xfd4f }, { 3396, 0xffee }, { 3410, 0xefef }, { 3424, 0xffff }, + { 3440, 0xecfe }, { 3452, 0xfcfe }, { 3465, 0xfeef }, { 3479, 0xffff }, + { 3495, 0xf86c }, { 3504, 0xe9d4 }, { 3513, 0xffef }, { 3528, 0xfefe }, + { 3542, 0xffff }, { 3558, 0xeecf }, { 3570, 0xfdff }, { 3585, 0xfeee }, + /* 0xbe00 */ + { 3598, 0xcfd6 }, { 3609, 0x4fee }, { 3620, 0xffff }, { 3636, 0xffff }, + { 3652, 0xaecf }, { 3663, 0xf14f }, { 3673, 0xfaec }, { 3684, 0xc7c4 }, + { 3692, 0x4fee }, { 3703, 0xfcfc }, { 3715, 0xfeff }, { 3730, 0xffff }, + { 3746, 0xffff }, { 3762, 0xfe6c }, { 3773, 0xefc6 }, { 3784, 0xffff }, + /* 0xbf00 */ + { 3800, 0xfcfd }, { 3813, 0xc4ff }, { 3824, 0xffff }, { 3840, 0xffff }, + { 3856, 0xfeec }, { 3868, 0xffdc }, { 3881, 0xffff }, { 3897, 0xffff }, + { 3913, 0xffff }, { 3929, 0xffef }, { 3944, 0xffff }, { 3960, 0xfffe }, + { 3975, 0xcfdf }, { 3988, 0x6fee }, { 4000, 0xfffd }, { 4015, 0xffff }, + /* 0xc000 */ + { 4031, 0xffff }, { 4047, 0xffff }, { 4063, 0xffff }, { 4079, 0xefff }, + { 4094, 0xffff }, { 4110, 0xeefd }, { 4123, 0xfcfe }, { 4136, 0xffff }, + { 4152, 0xffff }, { 4168, 0xfeec }, { 4180, 0x4fd4 }, { 4189, 0x4f86 }, + { 4197, 0xecdc }, { 4207, 0xc4fe }, { 4217, 0xeecf }, { 4229, 0xfd4f }, + /* 0xc100 */ + { 4241, 0xfeee }, { 4254, 0x0fde }, { 4264, 0x4f26 }, { 4272, 0xecbc }, + { 4282, 0xc4fe }, { 4292, 0xeecf }, { 4304, 0xfc4f }, { 4315, 0xfeee }, + { 4328, 0x8fdf }, { 4340, 0x4fae }, { 4350, 0xecdd }, { 4361, 0xdffe }, + { 4375, 0xeeef }, { 4388, 0xfe6f }, { 4401, 0xfeee }, { 4414, 0xcff4 }, + /* 0xc200 */ + { 4425, 0x4fee }, { 4436, 0x6cfd }, { 4447, 0x54fe }, { 4457, 0xffe9 }, + { 4470, 0xfeff }, { 4485, 0xfeec }, { 4497, 0xcfde }, { 4509, 0x4fee }, + { 4520, 0xfcfd }, { 4533, 0xd6fe }, { 4545, 0xcecf }, { 4556, 0xfd4f }, + { 4568, 0xffff }, { 4584, 0xcfff }, { 4598, 0x47e6 }, { 4607, 0xe4bd }, + /* 0xc300 */ + { 4617, 0xccfe }, { 4628, 0xeec7 }, { 4639, 0xfccf }, { 4651, 0xffff }, + { 4667, 0xffdf }, { 4682, 0xffff }, { 4698, 0xecff }, { 4711, 0xccfa }, + { 4721, 0xeeef }, { 4734, 0xffff }, { 4750, 0xffff }, { 4766, 0xffff }, + { 4782, 0xfffe }, { 4797, 0x6cff }, { 4809, 0xdcfa }, { 4820, 0xfecf }, + /* 0xc400 */ + { 4833, 0xfeff }, { 4848, 0xfffe }, { 4863, 0xefef }, { 4877, 0xcfee }, + { 4889, 0xfeff }, { 4904, 0xffff }, { 4920, 0xeecf }, { 4932, 0xfdcf }, + { 4945, 0xfffe }, { 4960, 0xefef }, { 4974, 0xffff }, { 4990, 0xeeff }, + { 5004, 0xffff }, { 5020, 0xffff }, { 5036, 0xfdff }, { 5051, 0x7aec }, + /* 0xc500 */ + { 5061, 0xeffc }, { 5074, 0xefee }, { 5087, 0xecff }, { 5100, 0xd4fe }, + { 5111, 0x88cf }, { 5119, 0x9c47 }, { 5127, 0xfeec }, { 5139, 0xcfc4 }, + { 5148, 0x4f6e }, { 5158, 0xee5d }, { 5169, 0xfdfe }, { 5183, 0x84cf }, + { 5191, 0xa80f }, { 5198, 0xfeec }, { 5210, 0x8fd4 }, { 5219, 0x0f2e }, + /* 0xc600 */ + { 5227, 0xee1c }, { 5236, 0xe4fe }, { 5247, 0x8ecf }, { 5257, 0xf546 }, + { 5266, 0xfeec }, { 5278, 0xcfc4 }, { 5287, 0x6ffe }, { 5300, 0xecfd }, + { 5312, 0xd4fe }, { 5323, 0xeecf }, { 5335, 0xfd4f }, { 5347, 0xf8ec }, + { 5357, 0xcfd4 }, { 5367, 0xcfee }, { 5379, 0xecfc }, { 5390, 0xdcfe }, + /* 0xc700 */ + { 5402, 0xeecf }, { 5414, 0xfd4f }, { 5426, 0xfeec }, { 5438, 0xcf54 }, + { 5447, 0x4bee }, { 5457, 0xee01 }, { 5464, 0xf6fe }, { 5477, 0x8ecf }, + { 5487, 0xb847 }, { 5495, 0xfa2c }, { 5504, 0xcf84 }, { 5512, 0x4fee }, + { 5523, 0xacfc }, { 5533, 0xdefe }, { 5546, 0xeeef }, { 5559, 0xffff }, + /* 0xc800 */ + { 5575, 0xfaec }, { 5586, 0xcf94 }, { 5595, 0x4fee }, { 5606, 0xeefd }, + { 5619, 0xccfe }, { 5630, 0xffef }, { 5645, 0xffff }, { 5661, 0xfaec }, + { 5672, 0xc714 }, { 5679, 0x5fef }, { 5692, 0x001d }, +}; + +static int +uhc_1_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + if (wc >= 0xac00 && wc < 0xc8b0) { + const Summary16 *summary = &uhc_1_uni2indx_pageac[(wc>>4)-0xac0]; + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + used += summary->indx; + c = uhc_1_2charset_main[used>>7] + uhc_1_2charset[used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/uhc_2.h b/libs/libiconv/lib/uhc_2.h new file mode 100644 index 00000000..4aa290a9 --- /dev/null +++ b/libs/libiconv/lib/uhc_2.h @@ -0,0 +1,1022 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * Unified Hangul Code part 2 + */ + +static const unsigned short uhc_2_2uni_main_pagea1[76] = { + 0xc8a5, 0xc8d8, 0xc910, 0xc93e, 0xc971, 0xc9a5, 0xc9de, 0xca1c, + 0xca47, 0xca7b, 0xcaa8, 0xcadd, 0xcb0b, 0xcb3a, 0xcb6d, 0xcb99, + 0xcbc5, 0xcbf3, 0xcc25, 0xcc67, 0xcc94, 0xcccf, 0xccfe, 0xcd34, + 0xcd61, 0xcd92, 0xcdc6, 0xcdf5, 0xce2c, 0xce5d, 0xce9a, 0xcecc, + 0xcf02, 0xcf3b, 0xcf6d, 0xcf9e, 0xcfcc, 0xcfff, 0xd02e, 0xd064, + 0xd095, 0xd0cc, 0xd105, 0xd132, 0xd16e, 0xd19b, 0xd1d0, 0xd1fd, + 0xd22a, 0xd25e, 0xd28d, 0xd2c5, 0xd2fb, 0xd33e, 0xd36a, 0xd3a1, + 0xd3d7, 0xd40d, 0xd438, 0xd467, 0xd49e, 0xd4c9, 0xd4fe, 0xd52e, + 0xd564, 0xd59d, 0xd5ca, 0xd606, 0xd63d, 0xd677, 0xd6ab, 0xd6e2, + 0xd715, 0xd74e, 0xd78d, 0xfffd, +}; +static const unsigned char uhc_2_2uni_pagea1[3126] = { + /* 0xa1 */ + 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x19, 0x1a, + 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x24, + 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x31, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1e, 0x1f, 0x20, 0x21, 0x22, + 0x23, 0x26, 0x27, 0x29, 0x2a, 0x2b, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0x36, + /* 0xa2 */ + 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, + 0x23, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x14, 0x15, 0x17, 0x18, + 0x19, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, + 0x24, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2f, 0x30, 0x31, + /* 0xa3 */ + 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x19, 0x1a, 0x1c, + 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x29, 0x2b, 0x2d, 0x2e, 0x2f, 0x30, 0x31, + 0x32, 0x33, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1d, 0x1e, 0x20, + 0x21, 0x24, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2d, + 0x2f, 0x32, 0x33, 0x36, + /* 0xa4 */ + 0x00, 0x01, 0x03, 0x05, 0x07, 0x08, 0x0a, 0x0b, + 0x0c, 0x0d, 0x10, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1c, 0x1d, 0x1f, 0x20, 0x21, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2c, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x37, 0x38, 0x39, 0x3b, + 0x3c, 0x3d, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2a, + /* 0xa5 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x07, 0x08, 0x0a, + 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x17, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, + 0x32, 0x33, 0x00, 0x01, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, + /* 0xa6 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x16, 0x17, 0x19, 0x1a, + 0x1b, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x26, 0x28, 0x2a, 0x2c, 0x2d, 0x2e, 0x2f, 0x32, + 0x33, 0x34, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2c, 0x2d, + /* 0xa7 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, 0x07, 0x08, + 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2e, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x10, + 0x11, 0x13, 0x14, 0x15, 0x17, 0x18, 0x19, 0x1a, + 0x1b, 0x1c, 0x1d, 0x20, 0x21, 0x22, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2b, 0x2c, 0x2d, 0x2e, + 0x2f, 0x30, 0x31, 0x32, + /* 0xa8 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, + /* 0xa9 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, + 0x23, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x1b, 0x1c, 0x1e, 0x1f, 0x20, + 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x2b, + 0x2c, 0x2d, 0x30, 0x31, + /* 0xaa */ + 0x00, 0x01, 0x05, 0x06, 0x08, 0x0a, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x15, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x21, 0x22, 0x24, 0x25, 0x26, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x31, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3c, 0x3d, + 0x3e, 0x40, 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0x0d, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, + /* 0xab */ + 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x09, 0x0a, + 0x0b, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x16, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x22, + 0x23, 0x25, 0x26, 0x27, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2e, 0x2f, 0x32, 0x34, 0x36, 0x37, 0x38, + 0x39, 0x3a, 0x00, 0x02, 0x03, 0x04, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1e, 0x1f, 0x20, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x2d, 0x2e, + /* 0xac */ + 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0c, 0x0d, 0x0f, 0x10, 0x11, 0x13, 0x14, + 0x15, 0x16, 0x17, 0x18, 0x19, 0x1c, 0x1e, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, + 0x2b, 0x2c, 0x2d, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x00, 0x01, 0x02, 0x03, 0x04, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x29, 0x2a, 0x2b, + /* 0xad */ + 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0d, 0x0f, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, + 0x2f, 0x30, 0x00, 0x01, 0x04, 0x05, 0x07, 0x08, + 0x09, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x14, 0x16, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, + 0x2f, 0x30, 0x31, 0x33, + /* 0xae */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, + 0x09, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, + 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, 0x2b, 0x2c, + 0x2d, 0x2e, 0x00, 0x01, 0x02, 0x05, 0x07, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12, + 0x14, 0x15, 0x16, 0x18, 0x19, 0x1a, 0x1b, 0x1c, + 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x23, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x2d, 0x2e, 0x30, 0x31, + 0x32, 0x34, 0x35, 0x36, + /* 0xaf */ + 0x00, 0x01, 0x02, 0x03, 0x06, 0x08, 0x0a, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2e, 0x2f, 0x00, 0x01, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0d, 0x0f, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x29, 0x2b, + 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x35, 0x36, + 0x38, 0x39, 0x3a, 0x3c, + /* 0xb0 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x1a, 0x1b, 0x1d, 0x1e, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x2a, 0x2e, 0x2f, + 0x30, 0x31, 0x32, 0x33, + /* 0xb1 */ + 0x00, 0x01, 0x03, 0x04, 0x05, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x10, 0x12, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1d, 0x1f, + 0x20, 0x21, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2c, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x37, 0x38, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x1b, 0x1c, 0x1e, 0x1f, 0x20, + 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x2b, + 0x2d, 0x2f, 0x30, 0x31, + /* 0xb2 */ + 0x00, 0x01, 0x02, 0x05, 0x06, 0x08, 0x09, 0x0a, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x14, + 0x15, 0x16, 0x17, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, + 0x2f, 0x30, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c, 0x2d, + /* 0xb3 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x16, 0x17, 0x19, 0x1a, + 0x1b, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x26, 0x28, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x31, 0x32, 0x00, 0x02, 0x03, 0x04, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, + 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c, 0x2d, + /* 0xb4 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x08, 0x09, + 0x0b, 0x0c, 0x0d, 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x18, 0x1a, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x23, 0x24, 0x25, 0x27, 0x28, 0x29, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x33, + 0x34, 0x35, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x1a, 0x1b, + 0x1c, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x2e, 0x2f, 0x30, + /* 0xb5 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x11, + 0x12, 0x14, 0x15, 0x16, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x21, 0x23, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2d, 0x2e, 0x30, 0x31, 0x32, + 0x35, 0x36, 0x00, 0x01, 0x02, 0x03, 0x06, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x12, 0x13, 0x15, + 0x16, 0x17, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x22, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, + 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, + /* 0xb6 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x00, 0x01, 0x03, 0x04, 0x05, 0x07, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x10, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1c, 0x1d, 0x1f, 0x20, + 0x21, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, + 0x2c, 0x2e, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x37, 0x38, 0x39, 0x3b, + /* 0xb7 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x17, 0x18, 0x19, + 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x2b, 0x2c, 0x00, 0x01, 0x02, 0x03, 0x04, 0x07, + 0x08, 0x0a, 0x0b, 0x0c, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x17, 0x19, 0x1b, 0x1c, 0x1d, + 0x1e, 0x20, 0x22, 0x23, 0x24, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0x34, + /* 0xb8 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x25, 0x26, 0x27, 0x29, 0x2a, + 0x2b, 0x2c, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0b, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, + /* 0xb9 */ + 0x00, 0x01, 0x04, 0x05, 0x07, 0x08, 0x09, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x14, 0x16, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x33, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x21, 0x24, 0x25, 0x27, 0x28, 0x29, + 0x2b, 0x2c, 0x2d, 0x2e, + /* 0xba */ + 0x00, 0x01, 0x02, 0x05, 0x06, 0x07, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x0e, 0x10, 0x11, 0x12, 0x14, + 0x15, 0x16, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x20, 0x21, 0x22, 0x23, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2d, 0x2e, 0x30, 0x31, 0x34, + 0x36, 0x37, 0x00, 0x01, 0x02, 0x05, 0x07, 0x08, + 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x10, 0x11, + 0x12, 0x14, 0x15, 0x16, 0x18, 0x19, 0x1a, 0x1b, + 0x1c, 0x1d, 0x1e, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2d, 0x2e, 0x30, + 0x31, 0x32, 0x34, 0x35, + /* 0xbb */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x07, 0x09, 0x0b, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x14, 0x16, 0x17, + 0x18, 0x1a, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x23, + 0x27, 0x28, 0x29, 0x2b, 0x2c, 0x2f, 0x30, 0x32, + 0x33, 0x34, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, + 0x28, 0x29, 0x2a, 0x2b, + /* 0xbc */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x14, 0x15, 0x17, 0x18, 0x19, 0x1b, + 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x24, 0x28, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x30, 0x31, 0x33, + 0x34, 0x35, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x09, 0x0b, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x14, 0x15, 0x16, 0x18, 0x19, 0x1a, 0x1c, + 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x25, 0x26, + 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x35, + /* 0xbd */ + 0x00, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0b, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x17, 0x18, 0x1a, 0x1b, 0x1c, 0x1e, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x27, 0x29, + 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x32, 0x33, + 0x34, 0x35, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2a, + /* 0xbe */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x09, 0x0a, 0x0b, 0x0d, 0x0e, 0x0f, 0x10, 0x11, + 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, + 0x22, 0x23, 0x25, 0x26, 0x27, 0x29, 0x2a, 0x2b, + 0x2d, 0x2e, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x07, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x13, 0x14, 0x16, 0x17, 0x1a, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x23, 0x25, 0x27, 0x28, 0x29, + 0x2a, 0x2b, 0x2c, 0x2e, 0x2f, 0x30, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, + /* 0xbf */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2a, 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, + 0x08, 0x09, 0x0a, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, + 0x11, 0x12, 0x14, 0x15, 0x17, 0x18, 0x19, 0x1a, + 0x1b, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, 0x24, + 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x30, 0x31, 0x33, + /* 0xc0 */ + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x07, 0x08, + 0x09, 0x0b, 0x0c, 0x0d, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x18, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x10, 0x11, 0x13, 0x14, 0x15, 0x17, 0x18, 0x19, + 0x1a, 0x1b, 0x1c, 0x1d, 0x20, 0x22, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2c, 0x2d, 0x2f, 0x30, + 0x31, 0x33, 0x34, 0x35, + /* 0xc1 */ + 0x00, 0x02, 0x03, 0x06, 0x08, 0x0a, 0x0b, 0x0c, + 0x0d, 0x0e, 0x0f, 0x12, 0x13, 0x15, 0x16, 0x17, + 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x22, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2d, 0x2e, + 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2a, + /* 0xc2 */ + 0x00, 0x01, 0x03, 0x04, 0x05, 0x07, 0x09, 0x0a, + 0x0b, 0x0c, 0x0d, 0x10, 0x12, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0x1c, 0x1d, 0x1f, 0x20, 0x21, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2c, + 0x2e, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x38, + 0x39, 0x3b, 0x00, 0x01, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0c, 0x10, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x17, 0x18, 0x19, 0x1b, 0x1c, 0x1d, + 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, + 0x30, 0x31, 0x34, 0x35, + /* 0xc3 */ + 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x09, + 0x0a, 0x0d, 0x0f, 0x11, 0x12, 0x13, 0x15, 0x16, + 0x19, 0x1a, 0x1c, 0x1d, 0x1e, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2b, + 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x35, 0x36, + 0x38, 0x39, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0d, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x17, 0x18, 0x1a, + 0x1b, 0x1c, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, + 0x24, 0x25, 0x27, 0x29, 0x2b, 0x2c, 0x2d, 0x2e, + 0x2f, 0x30, 0x32, 0x33, + /* 0xc4 */ + 0x00, 0x02, 0x03, 0x04, 0x06, 0x07, 0x08, 0x09, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0f, 0x11, 0x12, 0x13, + 0x14, 0x15, 0x16, 0x17, 0x18, 0x1b, 0x1c, 0x1e, + 0x1f, 0x20, 0x22, 0x23, 0x24, 0x25, 0x27, 0x28, + 0x2a, 0x2b, 0x2d, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x36, 0x00, 0x01, 0x03, 0x04, 0x05, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0f, 0x10, + 0x11, 0x12, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, + 0x1c, 0x1d, 0x1f, 0x20, 0x21, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x30, 0x31, 0x32, + /* 0xc5 */ + 0x00, 0x01, 0x02, 0x05, 0x06, 0x08, 0x09, 0x0a, + 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x15, + 0x17, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x21, + 0x22, 0x24, 0x25, 0x26, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x30, 0x31, 0x33, 0x35, 0x36, + 0x37, 0x38, 0x00, 0x01, 0x04, 0x05, 0x07, 0x0c, + 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x14, 0x16, 0x18, + 0x19, 0x1a, 0x1c, 0x1d, 0x1f, 0x20, 0x21, 0x23, + 0x24, 0x25, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, + 0x2d, 0x30, 0x31, 0x32, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0x3c, 0x3d, + /* 0xc6 */ + 0x00, 0x01, 0x02, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x09, 0x0a, 0x0d, 0x0f, 0x11, 0x12, 0x13, 0x14, + 0x15, 0x16, +}; + +static int +uhc_2_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c1 = s[0]; + if ((c1 >= 0xa1 && c1 <= 0xc6)) { + if (n >= 2) { + unsigned char c2 = s[1]; + if ((c2 >= 0x41 && c2 < 0x5b) || (c2 >= 0x61 && c2 < 0x7b) || (c2 >= 0x81 && c2 < 0xa1)) { + unsigned int row = c1 - 0xa1; + unsigned int col = c2 - (c2 >= 0x81 ? 0x4d : c2 >= 0x61 ? 0x47 : 0x41); + unsigned int i = 84 * row + col; + if (i < 3126) { + *pwc = (ucs4_t) (uhc_2_2uni_main_pagea1[2*row+(col>=42?1:0)] + uhc_2_2uni_pagea1[i]); + return 2; + } + } + return RET_ILSEQ; + } + return RET_TOOFEW(0); + } + return RET_ILSEQ; +} + +static const unsigned short uhc_2_2charset_main[49] = { + 0xa141, 0xa18d, 0xa273, 0xa359, 0xa445, 0xa491, 0xa577, 0xa663, + 0xa749, 0xa795, 0xa881, 0xa967, 0xaa4d, 0xaa99, 0xab85, 0xac6b, + 0xad51, 0xad9d, 0xae89, 0xaf6f, 0xb055, 0xb141, 0xb18d, 0xb273, + 0xb359, 0xb445, 0xb491, 0xb577, 0xb663, 0xb749, 0xb795, 0xb881, + 0xb967, 0xba4d, 0xba99, 0xbb85, 0xbc6b, 0xbd51, 0xbd9d, 0xbe89, + 0xbf6f, 0xc055, 0xc141, 0xc18d, 0xc273, 0xc359, 0xc445, 0xc491, + 0xc577, +}; +static const unsigned char uhc_2_2charset[3126] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0xe8, 0xe9, 0xea, 0xeb, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0xca, 0xcb, 0xcc, 0xcd, + 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xea, 0xeb, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xcc, 0xcd, + 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe8, 0xe9, 0xea, 0xeb, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x00, 0x01, 0x02, 0x03, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0xe8, 0xe9, 0xea, 0xeb, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0xca, 0xcb, 0xcc, 0xcd, + 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xea, 0xeb, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xcc, 0xcd, + 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe8, 0xe9, 0xea, 0xeb, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x00, 0x01, 0x02, 0x03, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xc4, 0xc5, + 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, + 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xeb, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf, + 0xd0, 0xd1, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x28, 0x29, 0x2a, 0x2b, + 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0xe8, 0xe9, 0xea, 0xeb, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, + 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x3c, 0x3d, 0x3e, 0x3f, 0x40, 0x41, 0x42, 0x43, + 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, + 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf, + 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, + 0xde, 0xdf, 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, + 0x00, 0x01, 0x02, 0x03, 0x0a, 0x0b, 0x0c, 0x0d, + 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, + 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, + 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, + 0x26, 0x27, 0x28, 0x29, 0xca, 0xcb, 0xcc, 0xcd, + 0xce, 0xcf, 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, + 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xdb, +}; + +static const Summary16 uhc_2_uni2indx_pagec8[251] = { + /* 0xc800 */ + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0x0000 }, + { 0, 0x0000 }, { 0, 0x0000 }, { 0, 0xfee0 }, { 10, 0xcfff }, + { 24, 0xeeef }, { 37, 0xfd4f }, { 49, 0xffec }, { 62, 0xcfdf }, + /* 0xc900 */ + { 75, 0x4f8e }, { 84, 0xfefd }, { 98, 0xefff }, { 113, 0xffef }, + { 128, 0xffff }, { 144, 0xfeec }, { 156, 0xeff4 }, { 168, 0xefee }, + { 181, 0xecff }, { 194, 0xd4fe }, { 205, 0xffff }, { 221, 0xffff }, + { 237, 0xfa6c }, { 247, 0xc994 }, { 254, 0x4f6a }, { 263, 0xecfc }, + /* 0xca00 */ + { 274, 0xc4fe }, { 284, 0xfeef }, { 298, 0xfdff }, { 313, 0xffff }, + { 329, 0xcfff }, { 343, 0x4fee }, { 354, 0xfefc }, { 367, 0xdfff }, + { 382, 0xffef }, { 397, 0xfeff }, { 412, 0xffff }, { 428, 0xcfff }, + { 442, 0x4fee }, { 453, 0xfcf5 }, { 465, 0xeffe }, { 479, 0xffef }, + /* 0xcb00 */ + { 494, 0xfeff }, { 509, 0xfeee }, { 522, 0xfffc }, { 536, 0xffff }, + { 552, 0xecfd }, { 564, 0xdcfe }, { 576, 0xffef }, { 591, 0xfcff }, + { 605, 0xffff }, { 621, 0xefff }, { 636, 0xffff }, { 652, 0xfeff }, + { 667, 0xffff }, { 683, 0xffef }, { 698, 0xfd6f }, { 711, 0xffff }, + /* 0xcc00 */ + { 727, 0xcfff }, { 741, 0xcfee }, { 753, 0xac79 }, { 762, 0x84fe }, + { 771, 0xeecf }, { 783, 0xfc4f }, { 794, 0xfeae }, { 806, 0xffde }, + { 820, 0xffff }, { 836, 0xecff }, { 849, 0xc4fe }, { 859, 0xeecf }, + { 871, 0xfd4f }, { 883, 0xffee }, { 897, 0xefef }, { 911, 0xfffe }, + /* 0xcd00 */ + { 926, 0xecfd }, { 938, 0xd4fe }, { 949, 0xeeef }, { 962, 0xfdff }, + { 977, 0xffff }, { 993, 0xefff }, { 1008, 0x4fee }, { 1019, 0xfefd }, + { 1033, 0xfeff }, { 1048, 0xeecf }, { 1060, 0xfd4f }, { 1072, 0xfffe }, + { 1087, 0xefef }, { 1101, 0xfffe }, { 1116, 0xeeff }, { 1130, 0xd4fe }, + /* 0xce00 */ + { 1141, 0xeeef }, { 1154, 0xfdef }, { 1168, 0xfeec }, { 1180, 0xffd4 }, + { 1192, 0xffff }, { 1208, 0x6cff }, { 1220, 0xd4fc }, { 1230, 0xeecf }, + { 1242, 0xfd4f }, { 1254, 0xfeec }, { 1266, 0xcfc4 }, { 1275, 0xffff }, + { 1291, 0xfffd }, { 1306, 0xffff }, { 1322, 0xe6cf }, { 1333, 0xfc4f }, + /* 0xcf00 */ + { 1344, 0xfeec }, { 1356, 0xefd4 }, { 1367, 0x4fee }, { 1378, 0xfefc }, + { 1391, 0xffff }, { 1407, 0xeecf }, { 1419, 0xfd4f }, { 1431, 0xfeec }, + { 1443, 0xefde }, { 1456, 0xffff }, { 1472, 0xfefd }, { 1486, 0xfffe }, + { 1501, 0xffef }, { 1516, 0xffff }, { 1532, 0xfeec }, { 1544, 0xefd4 }, + /* 0xd000 */ + { 1555, 0xffee }, { 1569, 0xfefd }, { 1583, 0xdfff }, { 1598, 0xeecf }, + { 1610, 0xfd4f }, { 1622, 0xfeee }, { 1635, 0xcffe }, { 1648, 0xcfee }, + { 1660, 0xfffd }, { 1675, 0xffff }, { 1691, 0xeecf }, { 1703, 0xfd4f }, + { 1715, 0xfcec }, { 1726, 0xcfc4 }, { 1735, 0x4fee }, { 1746, 0xfefc }, + /* 0xd100 */ + { 1759, 0xdfff }, { 1774, 0xffff }, { 1790, 0xffff }, { 1806, 0xfaec }, + { 1817, 0xcfc4 }, { 1826, 0x4fee }, { 1837, 0xeefd }, { 1850, 0xefff }, + { 1865, 0xfeef }, { 1879, 0xffff }, { 1895, 0xfeec }, { 1907, 0xebd4 }, + { 1917, 0xfffe }, { 1932, 0xfeff }, { 1947, 0xffff }, { 1963, 0xfeef }, + /* 0xd200 */ + { 1977, 0xfd7f }, { 1991, 0xfffe }, { 2006, 0xcfff }, { 2020, 0x4fee }, + { 2031, 0xfefd }, { 2045, 0xefff }, { 2060, 0xffef }, { 2075, 0xffff }, + { 2091, 0xfeec }, { 2103, 0xefdc }, { 2115, 0xefee }, { 2128, 0x6cfd }, + { 2139, 0xf4fa }, { 2150, 0xeeef }, { 2163, 0xffcf }, { 2177, 0xfeec }, + /* 0xd300 */ + { 2189, 0x8fd4 }, { 2198, 0x4fae }, { 2208, 0xecdc }, { 2218, 0xc4fe }, + { 2228, 0xffcf }, { 2242, 0xffff }, { 2258, 0xffff }, { 2274, 0xcfff }, + { 2288, 0x4fee }, { 2299, 0xecfc }, { 2310, 0xd4fe }, { 2321, 0xeeef }, + { 2334, 0xfccf }, { 2346, 0xfefe }, { 2360, 0xcff5 }, { 2372, 0x4fee }, + /* 0xd400 */ + { 2383, 0xfefd }, { 2397, 0xdfff }, { 2412, 0xffff }, { 2428, 0xffff }, + { 2444, 0xffee }, { 2458, 0xefff }, { 2473, 0x5fee }, { 2485, 0x6cff }, + { 2497, 0xd4fa }, { 2507, 0xffef }, { 2522, 0xfdff }, { 2537, 0xffff }, + { 2553, 0xefff }, { 2568, 0x6fee }, { 2580, 0xeeff }, { 2594, 0xd6fe }, + /* 0xd500 */ + { 2606, 0xeeef }, { 2619, 0xff4f }, { 2632, 0xffff }, { 2648, 0xcfff }, + { 2662, 0x4fee }, { 2673, 0xecfd }, { 2685, 0xd4de }, { 2695, 0xeecf }, + { 2707, 0xfc4f }, { 2718, 0xfffe }, { 2733, 0xffdf }, { 2748, 0xffff }, + { 2764, 0xecff }, { 2777, 0xd4fa }, { 2787, 0xeecf }, { 2799, 0xfd4f }, + /* 0xd600 */ + { 2811, 0xfeec }, { 2823, 0xefc4 }, { 2833, 0xdfee }, { 2846, 0xecff }, + { 2859, 0xd4de }, { 2869, 0xeecd }, { 2880, 0xfd7f }, { 2894, 0xffec }, + { 2907, 0xcfd7 }, { 2919, 0x5fee }, { 2931, 0xeefd }, { 2944, 0xf5fe }, + { 2957, 0xeecf }, { 2969, 0xfd6d }, { 2981, 0xfeee }, { 2994, 0xcfde }, + /* 0xd700 */ + { 3006, 0xffee }, { 3020, 0xecfd }, { 3032, 0xd4fe }, { 3043, 0xeecf }, + { 3055, 0xfd6f }, { 3068, 0xfc2c }, { 3077, 0xedd4 }, { 3087, 0xcfee }, + { 3099, 0xecfd }, { 3111, 0xd4fe }, { 3122, 0x000f }, +}; + +static int +uhc_2_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (n >= 2) { + if (wc >= 0xc800 && wc < 0xd7b0) { + const Summary16 *summary = &uhc_2_uni2indx_pagec8[(wc>>4)-0xc80]; + unsigned short used = summary->used; + unsigned int i = wc & 0x0f; + if (used & ((unsigned short) 1 << i)) { + unsigned short c; + /* Keep in `used' only the bits 0..i-1. */ + used &= ((unsigned short) 1 << i) - 1; + /* Add `summary->indx' and the number of bits set in `used'. */ + used = (used & 0x5555) + ((used & 0xaaaa) >> 1); + used = (used & 0x3333) + ((used & 0xcccc) >> 2); + used = (used & 0x0f0f) + ((used & 0xf0f0) >> 4); + used = (used & 0x00ff) + (used >> 8); + used += summary->indx; + c = uhc_2_2charset_main[used>>6] + uhc_2_2charset[used]; + r[0] = (c >> 8); r[1] = (c & 0xff); + return 2; + } + } + return RET_ILUNI; + } + return RET_TOOSMALL; +} diff --git a/libs/libiconv/lib/utf16.h b/libs/libiconv/lib/utf16.h new file mode 100644 index 00000000..99b5e2c2 --- /dev/null +++ b/libs/libiconv/lib/utf16.h @@ -0,0 +1,113 @@ +/* + * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UTF-16 + */ + +/* Specification: RFC 2781 */ + +/* Here we accept FFFE/FEFF marks as endianness indicators everywhere + in the stream, not just at the beginning. (This is contrary to what + RFC 2781 section 3.2 specifies, but it allows concatenation of byte + sequences to work flawlessly, while disagreeing with the RFC behaviour + only for strings containing U+FEFF characters, which is quite rare.) + The default is big-endian. */ +/* The state is 0 if big-endian, 1 if little-endian. */ +static int +utf16_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + state_t state = conv->istate; + int count = 0; + for (; n >= 2;) { + ucs4_t wc = (state ? s[0] + (s[1] << 8) : (s[0] << 8) + s[1]); + if (wc == 0xfeff) { + } else if (wc == 0xfffe) { + state ^= 1; + } else if (wc >= 0xd800 && wc < 0xdc00) { + if (n >= 4) { + ucs4_t wc2 = (state ? s[2] + (s[3] << 8) : (s[2] << 8) + s[3]); + if (!(wc2 >= 0xdc00 && wc2 < 0xe000)) + goto ilseq; + *pwc = 0x10000 + ((wc - 0xd800) << 10) + (wc2 - 0xdc00); + conv->istate = state; + return count+4; + } else + break; + } else if (wc >= 0xdc00 && wc < 0xe000) { + goto ilseq; + } else { + *pwc = wc; + conv->istate = state; + return count+2; + } + s += 2; n -= 2; count += 2; + } + conv->istate = state; + return RET_TOOFEW(count); + +ilseq: + conv->istate = state; + return RET_SHIFT_ILSEQ(count); +} + +/* We output UTF-16 in big-endian order, with byte-order mark. + See RFC 2781 section 3.3 for a rationale: Some document formats + mandate a BOM; the file concatenation issue is not so severe as + long as the above utf16_mbtowc function is used. */ +/* The state is 0 at the beginning, 1 after the BOM has been written. */ +static int +utf16_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc != 0xfffe && !(wc >= 0xd800 && wc < 0xe000)) { + int count = 0; + if (!conv->ostate) { + if (n >= 2) { + r[0] = 0xFE; + r[1] = 0xFF; + r += 2; n -= 2; count += 2; + } else + return RET_TOOSMALL; + } + if (wc < 0x10000) { + if (n >= 2) { + r[0] = (unsigned char) (wc >> 8); + r[1] = (unsigned char) wc; + conv->ostate = 1; + return count+2; + } else + return RET_TOOSMALL; + } + else if (wc < 0x110000) { + if (n >= 4) { + ucs4_t wc1 = 0xd800 + ((wc - 0x10000) >> 10); + ucs4_t wc2 = 0xdc00 + ((wc - 0x10000) & 0x3ff); + r[0] = (unsigned char) (wc1 >> 8); + r[1] = (unsigned char) wc1; + r[2] = (unsigned char) (wc2 >> 8); + r[3] = (unsigned char) wc2; + conv->ostate = 1; + return count+4; + } else + return RET_TOOSMALL; + } + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/utf16be.h b/libs/libiconv/lib/utf16be.h new file mode 100644 index 00000000..a6d90ffb --- /dev/null +++ b/libs/libiconv/lib/utf16be.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UTF-16BE + */ + +/* Specification: RFC 2781 */ + +static int +utf16be_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + int count = 0; + if (n >= 2) { + ucs4_t wc = (s[0] << 8) + s[1]; + if (wc >= 0xd800 && wc < 0xdc00) { + if (n >= 4) { + ucs4_t wc2 = (s[2] << 8) + s[3]; + if (!(wc2 >= 0xdc00 && wc2 < 0xe000)) + goto ilseq; + *pwc = 0x10000 + ((wc - 0xd800) << 10) + (wc2 - 0xdc00); + return count+4; + } + } else if (wc >= 0xdc00 && wc < 0xe000) { + goto ilseq; + } else { + *pwc = wc; + return count+2; + } + } + return RET_TOOFEW(count); + +ilseq: + return RET_SHIFT_ILSEQ(count); +} + +static int +utf16be_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (!(wc >= 0xd800 && wc < 0xe000)) { + if (wc < 0x10000) { + if (n >= 2) { + r[0] = (unsigned char) (wc >> 8); + r[1] = (unsigned char) wc; + return 2; + } else + return RET_TOOSMALL; + } + else if (wc < 0x110000) { + if (n >= 4) { + ucs4_t wc1 = 0xd800 + ((wc - 0x10000) >> 10); + ucs4_t wc2 = 0xdc00 + ((wc - 0x10000) & 0x3ff); + r[0] = (unsigned char) (wc1 >> 8); + r[1] = (unsigned char) wc1; + r[2] = (unsigned char) (wc2 >> 8); + r[3] = (unsigned char) wc2; + return 4; + } else + return RET_TOOSMALL; + } + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/utf16le.h b/libs/libiconv/lib/utf16le.h new file mode 100644 index 00000000..5bb2b026 --- /dev/null +++ b/libs/libiconv/lib/utf16le.h @@ -0,0 +1,80 @@ +/* + * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UTF-16LE + */ + +/* Specification: RFC 2781 */ + +static int +utf16le_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + int count = 0; + if (n >= 2) { + ucs4_t wc = s[0] + (s[1] << 8); + if (wc >= 0xd800 && wc < 0xdc00) { + if (n >= 4) { + ucs4_t wc2 = s[2] + (s[3] << 8); + if (!(wc2 >= 0xdc00 && wc2 < 0xe000)) + goto ilseq; + *pwc = 0x10000 + ((wc - 0xd800) << 10) + (wc2 - 0xdc00); + return count+4; + } + } else if (wc >= 0xdc00 && wc < 0xe000) { + goto ilseq; + } else { + *pwc = wc; + return count+2; + } + } + return RET_TOOFEW(count); + +ilseq: + return RET_SHIFT_ILSEQ(count); +} + +static int +utf16le_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (!(wc >= 0xd800 && wc < 0xe000)) { + if (wc < 0x10000) { + if (n >= 2) { + r[0] = (unsigned char) wc; + r[1] = (unsigned char) (wc >> 8); + return 2; + } else + return RET_TOOSMALL; + } + else if (wc < 0x110000) { + if (n >= 4) { + ucs4_t wc1 = 0xd800 + ((wc - 0x10000) >> 10); + ucs4_t wc2 = 0xdc00 + ((wc - 0x10000) & 0x3ff); + r[0] = (unsigned char) wc1; + r[1] = (unsigned char) (wc1 >> 8); + r[2] = (unsigned char) wc2; + r[3] = (unsigned char) (wc2 >> 8); + return 4; + } else + return RET_TOOSMALL; + } + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/utf32.h b/libs/libiconv/lib/utf32.h new file mode 100644 index 00000000..bc579ae0 --- /dev/null +++ b/libs/libiconv/lib/utf32.h @@ -0,0 +1,93 @@ +/* + * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UTF-32 + */ + +/* Specification: Unicode 3.1 Standard Annex #19 */ + +/* Here we accept FFFE0000/0000FEFF marks as endianness indicators + everywhere in the stream, not just at the beginning. (This is contrary + to what #19 D36c specifies, but it allows concatenation of byte + sequences to work flawlessly, while disagreeing with #19 behaviour + only for strings containing U+FEFF characters, which is quite rare.) + The default is big-endian. */ +/* The state is 0 if big-endian, 1 if little-endian. */ +static int +utf32_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + state_t state = conv->istate; + int count = 0; + for (; n >= 4;) { + ucs4_t wc = (state + ? s[0] + (s[1] << 8) + (s[2] << 16) + (s[3] << 24) + : (s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]); + count += 4; + if (wc == 0x0000feff) { + } else if (wc == 0xfffe0000u) { + state ^= 1; + } else { + if (wc < 0x110000 && !(wc >= 0xd800 && wc < 0xe000)) { + *pwc = wc; + conv->istate = state; + return count; + } else { + conv->istate = state; + return RET_SHIFT_ILSEQ(count); + } + } + s += 4; n -= 4; + } + conv->istate = state; + return RET_TOOFEW(count); +} + +/* We output UTF-32 in big-endian order, with byte-order mark. */ +/* The state is 0 at the beginning, 1 after the BOM has been written. */ +static int +utf32_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x110000 && !(wc >= 0xd800 && wc < 0xe000)) { + int count = 0; + if (!conv->ostate) { + if (n >= 4) { + r[0] = 0x00; + r[1] = 0x00; + r[2] = 0xFE; + r[3] = 0xFF; + r += 4; n -= 4; count += 4; + } else + return RET_TOOSMALL; + } + if (wc < 0x110000) { + if (n >= 4) { + r[0] = 0; + r[1] = (unsigned char) (wc >> 16); + r[2] = (unsigned char) (wc >> 8); + r[3] = (unsigned char) wc; + conv->ostate = 1; + return count+4; + } else + return RET_TOOSMALL; + } + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/utf32be.h b/libs/libiconv/lib/utf32be.h new file mode 100644 index 00000000..50811298 --- /dev/null +++ b/libs/libiconv/lib/utf32be.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UTF-32BE + */ + +/* Specification: Unicode 3.1 Standard Annex #19 */ + +static int +utf32be_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + if (n >= 4) { + ucs4_t wc = (s[0] << 24) + (s[1] << 16) + (s[2] << 8) + s[3]; + if (wc < 0x110000 && !(wc >= 0xd800 && wc < 0xe000)) { + *pwc = wc; + return 4; + } else + return RET_ILSEQ; + } + return RET_TOOFEW(0); +} + +static int +utf32be_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x110000 && !(wc >= 0xd800 && wc < 0xe000)) { + if (n >= 4) { + r[0] = 0; + r[1] = (unsigned char) (wc >> 16); + r[2] = (unsigned char) (wc >> 8); + r[3] = (unsigned char) wc; + return 4; + } else + return RET_TOOSMALL; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/utf32le.h b/libs/libiconv/lib/utf32le.h new file mode 100644 index 00000000..9d3699bc --- /dev/null +++ b/libs/libiconv/lib/utf32le.h @@ -0,0 +1,55 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UTF-32LE + */ + +/* Specification: Unicode 3.1 Standard Annex #19 */ + +static int +utf32le_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + if (n >= 4) { + ucs4_t wc = s[0] + (s[1] << 8) + (s[2] << 16) + (s[3] << 24); + if (wc < 0x110000 && !(wc >= 0xd800 && wc < 0xe000)) { + *pwc = wc; + return 4; + } else + return RET_ILSEQ; + } + return RET_TOOFEW(0); +} + +static int +utf32le_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + if (wc < 0x110000 && !(wc >= 0xd800 && wc < 0xe000)) { + if (n >= 4) { + r[0] = (unsigned char) wc; + r[1] = (unsigned char) (wc >> 8); + r[2] = (unsigned char) (wc >> 16); + r[3] = 0; + return 4; + } else + return RET_TOOSMALL; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/lib/utf7.h b/libs/libiconv/lib/utf7.h new file mode 100644 index 00000000..888bfb4d --- /dev/null +++ b/libs/libiconv/lib/utf7.h @@ -0,0 +1,355 @@ +/* + * Copyright (C) 1999-2001, 2008 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UTF-7 + */ + +/* Specification: RFC 2152 (and old RFC 1641, RFC 1642) */ +/* The original Base64 encoding is defined in RFC 2045. */ + +/* Set of direct characters: + * A-Z a-z 0-9 ' ( ) , - . / : ? space tab lf cr + */ +static const unsigned char direct_tab[128/8] = { + 0x00, 0x26, 0x00, 0x00, 0x81, 0xf3, 0xff, 0x87, + 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07, +}; +#define isdirect(ch) ((ch) < 128 && ((direct_tab[(ch)>>3] >> (ch & 7)) & 1)) + +/* Set of direct and optional direct characters: + * A-Z a-z 0-9 ' ( ) , - . / : ? space tab lf cr + * ! " # $ % & * ; < = > @ [ ] ^ _ ` { | } + */ +static const unsigned char xdirect_tab[128/8] = { + 0x00, 0x26, 0x00, 0x00, 0xff, 0xf7, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xef, 0xff, 0xff, 0xff, 0x3f, +}; +#define isxdirect(ch) ((ch) < 128 && ((xdirect_tab[(ch)>>3] >> (ch & 7)) & 1)) + +/* Set of base64 characters, extended: + * A-Z a-z 0-9 + / - + */ +static const unsigned char xbase64_tab[128/8] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0xff, 0x03, + 0xfe, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x07, +}; +#define isxbase64(ch) ((ch) < 128 && ((xbase64_tab[(ch)>>3] >> (ch & 7)) & 1)) + +/* + * The state is structured as follows: + * bit 1..0: shift + * bit 7..2: data + * Precise meaning: + * shift data + * 0 0 not inside base64 encoding + * 1 0 inside base64, no pending bits + * 2 XXXX00 inside base64, 4 bits remain from 2nd byte + * 3 XX0000 inside base64, 2 bits remain from 3rd byte + */ + +static int +utf7_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + state_t state = conv->istate; + int count = 0; /* number of input bytes already read */ + if (state & 3) + goto active; + else + goto inactive; + +inactive: + { + /* Here (state & 3) == 0 */ + if (n < count+1) + goto none; + { + unsigned char c = *s; + if (isxdirect(c)) { + *pwc = (ucs4_t) c; + conv->istate = state; + return count+1; + } + if (c == '+') { + if (n < count+2) + goto none; + if (s[1] == '-') { + *pwc = (ucs4_t) '+'; + conv->istate = state; + return count+2; + } + s++; count++; + state = 1; + goto active; + } + goto ilseq; + } + } + +active: + { + /* base64 encoding active */ + unsigned int wc = 0; + state_t base64state = state; + unsigned int kmax = 2; /* number of payload bytes to read */ + unsigned int k = 0; /* number of payload bytes already read */ + unsigned int base64count = 0; /* number of base64 bytes already read */ + for (;;) { + unsigned char c = *s; + unsigned int i; + if (c >= 'A' && c <= 'Z') + i = c-'A'; + else if (c >= 'a' && c <= 'z') + i = c-'a'+26; + else if (c >= '0' && c <= '9') + i = c-'0'+52; + else if (c == '+') + i = 62; + else if (c == '/') + i = 63; + else { + /* c terminates base64 encoding */ + if (base64state & -4) + goto ilseq; /* data must be 0, otherwise illegal */ + if (base64count) + goto ilseq; /* partial UTF-16 characters are invalid */ + if (c == '-') { + s++; count++; + } + state = 0; + goto inactive; + } + s++; base64count++; + /* read 6 bits: 0 <= i < 64 */ + switch (base64state & 3) { + case 1: /* inside base64, no pending bits */ + base64state = (i << 2) | 0; break; + case 0: /* inside base64, 6 bits remain from 1st byte */ + wc = (wc << 8) | (base64state & -4) | (i >> 4); k++; + base64state = ((i & 15) << 4) | 2; break; + case 2: /* inside base64, 4 bits remain from 2nd byte */ + wc = (wc << 8) | (base64state & -4) | (i >> 2); k++; + base64state = ((i & 3) << 6) | 3; break; + case 3: /* inside base64, 2 bits remain from 3rd byte */ + wc = (wc << 8) | (base64state & -4) | i; k++; + base64state = 1; break; + } + if (k == kmax) { + /* UTF-16: When we see a High Surrogate, we must also decode + the following Low Surrogate. */ + if (kmax == 2 && (wc >= 0xd800 && wc < 0xdc00)) + kmax = 4; + else + break; + } + if (n < count+base64count+1) + goto none; + } + /* Here k = kmax > 0, hence base64count > 0. */ + if ((base64state & 3) == 0) abort(); + if (kmax == 4) { + ucs4_t wc1 = wc >> 16; + ucs4_t wc2 = wc & 0xffff; + if (!(wc1 >= 0xd800 && wc1 < 0xdc00)) abort(); + if (!(wc2 >= 0xdc00 && wc2 < 0xe000)) goto ilseq; + *pwc = 0x10000 + ((wc1 - 0xd800) << 10) + (wc2 - 0xdc00); + } else { + *pwc = wc; + } + conv->istate = base64state; + return count+base64count; + } + +none: + conv->istate = state; + return RET_TOOFEW(count); + +ilseq: + conv->istate = state; + return RET_SHIFT_ILSEQ(count); +} + +/* + * The state is structured as follows: + * bit 1..0: shift + * bit 7..2: data + * Precise meaning: + * shift data + * 0 0 not inside base64 encoding + * 1 0 inside base64, no pending bits + * 2 XX00 inside base64, 2 bits known for 2nd byte + * 3 XXXX inside base64, 4 bits known for 3rd byte + */ + +/* Define this to 1 if you want the so-called "optional direct" characters + ! " # $ % & * ; < = > @ [ ] ^ _ ` { | } + to be encoded. Define to 0 if you want them to be passed straight through, + like the so-called "direct" characters. + We set this to 1 because it's safer. + */ +#define UTF7_ENCODE_OPTIONAL_CHARS 1 + +static int +utf7_wctomb (conv_t conv, unsigned char *r, ucs4_t iwc, int n) +{ + state_t state = conv->ostate; + unsigned int wc = iwc; + int count = 0; + if (state & 3) + goto active; + +/*inactive:*/ + { + if (UTF7_ENCODE_OPTIONAL_CHARS ? isdirect(wc) : isxdirect(wc)) { + r[0] = (unsigned char) wc; + /*conv->ostate = state;*/ + return 1; + } else { + *r++ = '+'; + if (wc == '+') { + if (n < 2) + return RET_TOOSMALL; + *r = '-'; + /*conv->ostate = state;*/ + return 2; + } + count = 1; + state = 1; + goto active; + } + } + +active: + { + /* base64 encoding active */ + if (UTF7_ENCODE_OPTIONAL_CHARS ? isdirect(wc) : isxdirect(wc)) { + /* deactivate base64 encoding */ + count += ((state & 3) >= 2 ? 1 : 0) + (isxbase64(wc) ? 1 : 0) + 1; + if (n < count) + return RET_TOOSMALL; + if ((state & 3) >= 2) { + unsigned int i = state & -4; + unsigned char c; + if (i < 26) + c = i+'A'; + else if (i < 52) + c = i-26+'a'; + else if (i < 62) + c = i-52+'0'; + else if (i == 62) + c = '+'; + else if (i == 63) + c = '/'; + else + abort(); + *r++ = c; + } + if (isxbase64(wc)) + *r++ = '-'; + state = 0; + *r++ = (unsigned char) wc; + conv->ostate = state; + return count; + } else { + unsigned int k; /* number of payload bytes to write */ + if (wc < 0x10000) { + k = 2; + count += ((state & 3) >= 2 ? 3 : 2); + } else if (wc < 0x110000) { + unsigned int wc1 = 0xd800 + ((wc - 0x10000) >> 10); + unsigned int wc2 = 0xdc00 + ((wc - 0x10000) & 0x3ff); + wc = (wc1 << 16) | wc2; + k = 4; + count += ((state & 3) >= 3 ? 6 : 5); + } else + return RET_ILUNI; + if (n < count) + return RET_TOOSMALL; + for (;;) { + unsigned int i; + unsigned char c; + switch (state & 3) { + case 0: /* inside base64, 6 bits known for 4th byte */ + c = (state & -4) >> 2; state = 1; break; + case 1: /* inside base64, no pending bits */ + i = (wc >> (8 * --k)) & 0xff; + c = i >> 2; state = ((i & 3) << 4) | 2; break; + case 2: /* inside base64, 2 bits known for 2nd byte */ + i = (wc >> (8 * --k)) & 0xff; + c = (state & -4) | (i >> 4); state = ((i & 15) << 2) | 3; break; + case 3: /* inside base64, 4 bits known for 3rd byte */ + i = (wc >> (8 * --k)) & 0xff; + c = (state & -4) | (i >> 6); state = ((i & 63) << 2) | 0; break; + default: abort(); /* stupid gcc */ + } + if (c < 26) + c = c+'A'; + else if (c < 52) + c = c-26+'a'; + else if (c < 62) + c = c-52+'0'; + else if (c == 62) + c = '+'; + else if (c == 63) + c = '/'; + else + abort(); + *r++ = c; + if ((state & 3) && (k == 0)) + break; + } + conv->ostate = state; + return count; + } + } +} + +static int +utf7_reset (conv_t conv, unsigned char *r, int n) +{ + state_t state = conv->ostate; + if (state & 3) { + /* deactivate base64 encoding */ + unsigned int count = ((state & 3) >= 2 ? 1 : 0) + 1; + if (n < count) + return RET_TOOSMALL; + if ((state & 3) >= 2) { + unsigned int i = state & -4; + unsigned char c; + if (i < 26) + c = i+'A'; + else if (i < 52) + c = i-26+'a'; + else if (i < 62) + c = i-52+'0'; + else if (i == 62) + c = '+'; + else if (i == 63) + c = '/'; + else + abort(); + *r++ = c; + } + *r++ = '-'; + /* conv->ostate = 0; will be done by the caller */ + return count; + } else + return 0; +} diff --git a/libs/libiconv/lib/utf8.h b/libs/libiconv/lib/utf8.h new file mode 100644 index 00000000..9d07219c --- /dev/null +++ b/libs/libiconv/lib/utf8.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 1999-2001, 2004 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * UTF-8 + */ + +/* Specification: RFC 3629 */ + +static int +utf8_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = s[0]; + + if (c < 0x80) { + *pwc = c; + return 1; + } else if (c < 0xc2) { + return RET_ILSEQ; + } else if (c < 0xe0) { + if (n < 2) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40)) + return RET_ILSEQ; + *pwc = ((ucs4_t) (c & 0x1f) << 6) + | (ucs4_t) (s[1] ^ 0x80); + return 2; + } else if (c < 0xf0) { + if (n < 3) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (c >= 0xe1 || s[1] >= 0xa0))) + return RET_ILSEQ; + *pwc = ((ucs4_t) (c & 0x0f) << 12) + | ((ucs4_t) (s[1] ^ 0x80) << 6) + | (ucs4_t) (s[2] ^ 0x80); + return 3; + } else if (c < 0xf8 && sizeof(ucs4_t)*8 >= 32) { + if (n < 4) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 + && (c >= 0xf1 || s[1] >= 0x90))) + return RET_ILSEQ; + *pwc = ((ucs4_t) (c & 0x07) << 18) + | ((ucs4_t) (s[1] ^ 0x80) << 12) + | ((ucs4_t) (s[2] ^ 0x80) << 6) + | (ucs4_t) (s[3] ^ 0x80); + return 4; + } else if (c < 0xfc && sizeof(ucs4_t)*8 >= 32) { + if (n < 5) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 + && (c >= 0xf9 || s[1] >= 0x88))) + return RET_ILSEQ; + *pwc = ((ucs4_t) (c & 0x03) << 24) + | ((ucs4_t) (s[1] ^ 0x80) << 18) + | ((ucs4_t) (s[2] ^ 0x80) << 12) + | ((ucs4_t) (s[3] ^ 0x80) << 6) + | (ucs4_t) (s[4] ^ 0x80); + return 5; + } else if (c < 0xfe && sizeof(ucs4_t)*8 >= 32) { + if (n < 6) + return RET_TOOFEW(0); + if (!((s[1] ^ 0x80) < 0x40 && (s[2] ^ 0x80) < 0x40 + && (s[3] ^ 0x80) < 0x40 && (s[4] ^ 0x80) < 0x40 + && (s[5] ^ 0x80) < 0x40 + && (c >= 0xfd || s[1] >= 0x84))) + return RET_ILSEQ; + *pwc = ((ucs4_t) (c & 0x01) << 30) + | ((ucs4_t) (s[1] ^ 0x80) << 24) + | ((ucs4_t) (s[2] ^ 0x80) << 18) + | ((ucs4_t) (s[3] ^ 0x80) << 12) + | ((ucs4_t) (s[4] ^ 0x80) << 6) + | (ucs4_t) (s[5] ^ 0x80); + return 6; + } else + return RET_ILSEQ; +} + +static int +utf8_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) /* n == 0 is acceptable */ +{ + int count; + if (wc < 0x80) + count = 1; + else if (wc < 0x800) + count = 2; + else if (wc < 0x10000) + count = 3; + else if (wc < 0x200000) + count = 4; + else if (wc < 0x4000000) + count = 5; + else if (wc <= 0x7fffffff) + count = 6; + else + return RET_ILUNI; + if (n < count) + return RET_TOOSMALL; + switch (count) { /* note: code falls through cases! */ + case 6: r[5] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x4000000; + case 5: r[4] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x200000; + case 4: r[3] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x10000; + case 3: r[2] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0x800; + case 2: r[1] = 0x80 | (wc & 0x3f); wc = wc >> 6; wc |= 0xc0; + case 1: r[0] = wc; + } + return count; +} diff --git a/libs/libiconv/lib/vietcomb.h b/libs/libiconv/lib/vietcomb.h new file mode 100644 index 00000000..023b5e32 --- /dev/null +++ b/libs/libiconv/lib/vietcomb.h @@ -0,0 +1,466 @@ +/* + * Copyright (C) 2001, 2004, 2011 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* Combining characters used in Vietnamese encodings CP1258, TCVN. */ + +#ifndef _VIETCOMB_H +#define _VIETCOMB_H + +/* Relevant combining characters: + 0x0300, 0x0301, 0x0303, 0x0309, 0x0323. */ + +/* Composition tables for each of the relevant combining characters. */ +static const struct { unsigned short base; unsigned short composed; } viet_comp_table_data[] = { +#define viet_comp_table0300_idx 0 +#define viet_comp_table0300_len 31 + { 0x0041, 0x00C0 }, + { 0x0045, 0x00C8 }, + { 0x0049, 0x00CC }, + { 0x004E, 0x01F8 }, + { 0x004F, 0x00D2 }, + { 0x0055, 0x00D9 }, + { 0x0057, 0x1E80 }, + { 0x0059, 0x1EF2 }, + { 0x0061, 0x00E0 }, + { 0x0065, 0x00E8 }, + { 0x0069, 0x00EC }, + { 0x006E, 0x01F9 }, + { 0x006F, 0x00F2 }, + { 0x0075, 0x00F9 }, + { 0x0077, 0x1E81 }, + { 0x0079, 0x1EF3 }, + { 0x00A8, 0x1FED }, + { 0x00C2, 0x1EA6 }, + { 0x00CA, 0x1EC0 }, + { 0x00D4, 0x1ED2 }, + { 0x00DC, 0x01DB }, + { 0x00E2, 0x1EA7 }, + { 0x00EA, 0x1EC1 }, + { 0x00F4, 0x1ED3 }, + { 0x00FC, 0x01DC }, + { 0x0102, 0x1EB0 }, + { 0x0103, 0x1EB1 }, +/*{ 0x0112, 0x1E14 },*/ +/*{ 0x0113, 0x1E15 },*/ +/*{ 0x014C, 0x1E50 },*/ +/*{ 0x014D, 0x1E51 },*/ + { 0x01A0, 0x1EDC }, + { 0x01A1, 0x1EDD }, + { 0x01AF, 0x1EEA }, + { 0x01B0, 0x1EEB }, +#define viet_comp_table0301_idx (viet_comp_table0300_idx+viet_comp_table0300_len) +#define viet_comp_table0301_len 63 + { 0x0041, 0x00C1 }, + { 0x0043, 0x0106 }, + { 0x0045, 0x00C9 }, + { 0x0047, 0x01F4 }, + { 0x0049, 0x00CD }, + { 0x004B, 0x1E30 }, + { 0x004C, 0x0139 }, + { 0x004D, 0x1E3E }, + { 0x004E, 0x0143 }, + { 0x004F, 0x00D3 }, + { 0x0050, 0x1E54 }, + { 0x0052, 0x0154 }, + { 0x0053, 0x015A }, + { 0x0055, 0x00DA }, + { 0x0057, 0x1E82 }, + { 0x0059, 0x00DD }, + { 0x005A, 0x0179 }, + { 0x0061, 0x00E1 }, + { 0x0063, 0x0107 }, + { 0x0065, 0x00E9 }, + { 0x0067, 0x01F5 }, + { 0x0069, 0x00ED }, + { 0x006B, 0x1E31 }, + { 0x006C, 0x013A }, + { 0x006D, 0x1E3F }, + { 0x006E, 0x0144 }, + { 0x006F, 0x00F3 }, + { 0x0070, 0x1E55 }, + { 0x0072, 0x0155 }, + { 0x0073, 0x015B }, + { 0x0075, 0x00FA }, + { 0x0077, 0x1E83 }, + { 0x0079, 0x00FD }, + { 0x007A, 0x017A }, + { 0x00A8, 0x0385 }, /* prefer U+0385 over U+1FEE */ + { 0x00C2, 0x1EA4 }, + { 0x00C5, 0x01FA }, + { 0x00C6, 0x01FC }, + { 0x00C7, 0x1E08 }, + { 0x00CA, 0x1EBE }, + { 0x00CF, 0x1E2E }, + { 0x00D4, 0x1ED0 }, + { 0x00D5, 0x1E4C }, + { 0x00D8, 0x01FE }, + { 0x00DC, 0x01D7 }, + { 0x00E2, 0x1EA5 }, + { 0x00E5, 0x01FB }, + { 0x00E6, 0x01FD }, + { 0x00E7, 0x1E09 }, + { 0x00EA, 0x1EBF }, + { 0x00EF, 0x1E2F }, + { 0x00F4, 0x1ED1 }, + { 0x00F5, 0x1E4D }, + { 0x00F8, 0x01FF }, + { 0x00FC, 0x01D8 }, + { 0x0102, 0x1EAE }, + { 0x0103, 0x1EAF }, +/*{ 0x0112, 0x1E16 },*/ +/*{ 0x0113, 0x1E17 },*/ +/*{ 0x014C, 0x1E52 },*/ +/*{ 0x014D, 0x1E53 },*/ + { 0x0168, 0x1E78 }, + { 0x0169, 0x1E79 }, + { 0x01A0, 0x1EDA }, + { 0x01A1, 0x1EDB }, + { 0x01AF, 0x1EE8 }, + { 0x01B0, 0x1EE9 }, +#define viet_comp_table0303_idx (viet_comp_table0301_idx+viet_comp_table0301_len) +#define viet_comp_table0303_len 34 + { 0x0041, 0x00C3 }, + { 0x0045, 0x1EBC }, + { 0x0049, 0x0128 }, + { 0x004E, 0x00D1 }, + { 0x004F, 0x00D5 }, + { 0x0055, 0x0168 }, + { 0x0056, 0x1E7C }, + { 0x0059, 0x1EF8 }, + { 0x0061, 0x00E3 }, + { 0x0065, 0x1EBD }, + { 0x0069, 0x0129 }, + { 0x006E, 0x00F1 }, + { 0x006F, 0x00F5 }, + { 0x0075, 0x0169 }, + { 0x0076, 0x1E7D }, + { 0x0079, 0x1EF9 }, + { 0x00C2, 0x1EAA }, + { 0x00CA, 0x1EC4 }, + { 0x00D3, 0x1E4C }, + { 0x00D4, 0x1ED6 }, + { 0x00D6, 0x1E4E }, + { 0x00DA, 0x1E78 }, + { 0x00E2, 0x1EAB }, + { 0x00EA, 0x1EC5 }, + { 0x00F3, 0x1E4D }, + { 0x00F4, 0x1ED7 }, + { 0x00F6, 0x1E4F }, + { 0x00FA, 0x1E79 }, + { 0x0102, 0x1EB4 }, + { 0x0103, 0x1EB5 }, + { 0x01A0, 0x1EE0 }, + { 0x01A1, 0x1EE1 }, + { 0x01AF, 0x1EEE }, + { 0x01B0, 0x1EEF }, +#define viet_comp_table0309_idx (viet_comp_table0303_idx+viet_comp_table0303_len) +#define viet_comp_table0309_len 24 + { 0x0041, 0x1EA2 }, + { 0x0045, 0x1EBA }, + { 0x0049, 0x1EC8 }, + { 0x004F, 0x1ECE }, + { 0x0055, 0x1EE6 }, + { 0x0059, 0x1EF6 }, + { 0x0061, 0x1EA3 }, + { 0x0065, 0x1EBB }, + { 0x0069, 0x1EC9 }, + { 0x006F, 0x1ECF }, + { 0x0075, 0x1EE7 }, + { 0x0079, 0x1EF7 }, + { 0x00C2, 0x1EA8 }, + { 0x00CA, 0x1EC2 }, + { 0x00D4, 0x1ED4 }, + { 0x00E2, 0x1EA9 }, + { 0x00EA, 0x1EC3 }, + { 0x00F4, 0x1ED5 }, + { 0x0102, 0x1EB2 }, + { 0x0103, 0x1EB3 }, + { 0x01A0, 0x1EDE }, + { 0x01A1, 0x1EDF }, + { 0x01AF, 0x1EEC }, + { 0x01B0, 0x1EED }, +#define viet_comp_table0323_idx (viet_comp_table0309_idx+viet_comp_table0309_len) +#define viet_comp_table0323_len 50 + { 0x0041, 0x1EA0 }, + { 0x0042, 0x1E04 }, + { 0x0044, 0x1E0C }, + { 0x0045, 0x1EB8 }, + { 0x0048, 0x1E24 }, + { 0x0049, 0x1ECA }, + { 0x004B, 0x1E32 }, + { 0x004C, 0x1E36 }, + { 0x004D, 0x1E42 }, + { 0x004E, 0x1E46 }, + { 0x004F, 0x1ECC }, + { 0x0052, 0x1E5A }, + { 0x0053, 0x1E62 }, + { 0x0054, 0x1E6C }, + { 0x0055, 0x1EE4 }, + { 0x0056, 0x1E7E }, + { 0x0057, 0x1E88 }, + { 0x0059, 0x1EF4 }, + { 0x005A, 0x1E92 }, + { 0x0061, 0x1EA1 }, + { 0x0062, 0x1E05 }, + { 0x0064, 0x1E0D }, + { 0x0065, 0x1EB9 }, + { 0x0068, 0x1E25 }, + { 0x0069, 0x1ECB }, + { 0x006B, 0x1E33 }, + { 0x006C, 0x1E37 }, + { 0x006D, 0x1E43 }, + { 0x006E, 0x1E47 }, + { 0x006F, 0x1ECD }, + { 0x0072, 0x1E5B }, + { 0x0073, 0x1E63 }, + { 0x0074, 0x1E6D }, + { 0x0075, 0x1EE5 }, + { 0x0076, 0x1E7F }, + { 0x0077, 0x1E89 }, + { 0x0079, 0x1EF5 }, + { 0x007A, 0x1E93 }, + { 0x00C2, 0x1EAC }, + { 0x00CA, 0x1EC6 }, + { 0x00D4, 0x1ED8 }, + { 0x00E2, 0x1EAD }, + { 0x00EA, 0x1EC7 }, + { 0x00F4, 0x1ED9 }, + { 0x0102, 0x1EB6 }, + { 0x0103, 0x1EB7 }, + { 0x01A0, 0x1EE2 }, + { 0x01A1, 0x1EE3 }, + { 0x01AF, 0x1EF0 }, + { 0x01B0, 0x1EF1 }, +}; +static const struct { unsigned int len; unsigned int idx; } viet_comp_table[] = { + { viet_comp_table0300_len, viet_comp_table0300_idx }, + { viet_comp_table0301_len, viet_comp_table0301_idx }, + { viet_comp_table0303_len, viet_comp_table0303_idx }, + { viet_comp_table0309_len, viet_comp_table0309_idx }, + { viet_comp_table0323_len, viet_comp_table0323_idx }, +}; + +/* Decomposition table for the relevant Unicode characters. */ +struct viet_decomp { unsigned short composed; unsigned int base : 12; int comb1 : 4; }; +static const struct viet_decomp viet_decomp_table[] = { + { 0x00B4, 0x0020, 1 }, /* compatibility decomposition - for TCVN only */ + { 0x00C0, 0x0041, 0 }, + { 0x00C1, 0x0041, 1 }, + { 0x00C3, 0x0041, 2 }, + { 0x00C8, 0x0045, 0 }, + { 0x00C9, 0x0045, 1 }, + { 0x00CC, 0x0049, 0 }, + { 0x00CD, 0x0049, 1 }, + { 0x00D1, 0x004E, 2 }, + { 0x00D2, 0x004F, 0 }, + { 0x00D3, 0x004F, 1 }, + { 0x00D5, 0x004F, 2 }, + { 0x00D9, 0x0055, 0 }, + { 0x00DA, 0x0055, 1 }, + { 0x00DD, 0x0059, 1 }, + { 0x00E0, 0x0061, 0 }, + { 0x00E1, 0x0061, 1 }, + { 0x00E3, 0x0061, 2 }, + { 0x00E8, 0x0065, 0 }, + { 0x00E9, 0x0065, 1 }, + { 0x00EC, 0x0069, 0 }, + { 0x00ED, 0x0069, 1 }, + { 0x00F1, 0x006E, 2 }, + { 0x00F2, 0x006F, 0 }, + { 0x00F3, 0x006F, 1 }, + { 0x00F5, 0x006F, 2 }, + { 0x00F9, 0x0075, 0 }, + { 0x00FA, 0x0075, 1 }, + { 0x00FD, 0x0079, 1 }, + { 0x0106, 0x0043, 1 }, + { 0x0107, 0x0063, 1 }, + { 0x0128, 0x0049, 2 }, + { 0x0129, 0x0069, 2 }, + { 0x0139, 0x004C, 1 }, + { 0x013A, 0x006C, 1 }, + { 0x0143, 0x004E, 1 }, + { 0x0144, 0x006E, 1 }, + { 0x0154, 0x0052, 1 }, + { 0x0155, 0x0072, 1 }, + { 0x015A, 0x0053, 1 }, + { 0x015B, 0x0073, 1 }, + { 0x0168, 0x0055, 2 }, + { 0x0169, 0x0075, 2 }, + { 0x0179, 0x005A, 1 }, + { 0x017A, 0x007A, 1 }, + { 0x01D7, 0x00DC, 1 }, + { 0x01D8, 0x00FC, 1 }, + { 0x01DB, 0x00DC, 0 }, + { 0x01DC, 0x00FC, 0 }, + { 0x01F4, 0x0047, 1 }, + { 0x01F5, 0x0067, 1 }, + { 0x01F8, 0x004E, 0 }, + { 0x01F9, 0x006E, 0 }, + { 0x01FA, 0x00C5, 1 }, + { 0x01FB, 0x00E5, 1 }, + { 0x01FC, 0x00C6, 1 }, + { 0x01FD, 0x00E6, 1 }, + { 0x01FE, 0x00D8, 1 }, + { 0x01FF, 0x00F8, 1 }, + { 0x02DC, 0x0020, 2 }, /* compatibility decomposition - for TCVN only */ + { 0x0385, 0x00A8, 1 }, + { 0x1E04, 0x0042, 4 }, + { 0x1E05, 0x0062, 4 }, + { 0x1E08, 0x00C7, 1 }, + { 0x1E09, 0x00E7, 1 }, + { 0x1E0C, 0x0044, 4 }, + { 0x1E0D, 0x0064, 4 }, + { 0x1E24, 0x0048, 4 }, + { 0x1E25, 0x0068, 4 }, + { 0x1E2E, 0x00CF, 1 }, + { 0x1E2F, 0x00EF, 1 }, + { 0x1E30, 0x004B, 1 }, + { 0x1E31, 0x006B, 1 }, + { 0x1E32, 0x004B, 4 }, + { 0x1E33, 0x006B, 4 }, + { 0x1E36, 0x004C, 4 }, + { 0x1E37, 0x006C, 4 }, + { 0x1E3E, 0x004D, 1 }, + { 0x1E3F, 0x006D, 1 }, + { 0x1E42, 0x004D, 4 }, + { 0x1E43, 0x006D, 4 }, + { 0x1E46, 0x004E, 4 }, + { 0x1E47, 0x006E, 4 }, + { 0x1E4C, 0x00D3, 2 }, /*{ 0x1E4C, 0x00D5, 1 },*/ /*{ 0x1E4C, 0x004F, 1, 2 },*/ + { 0x1E4D, 0x00F3, 2 }, /*{ 0x1E4D, 0x00F5, 1 },*/ /*{ 0x1E4D, 0x006F, 1, 2 },*/ + { 0x1E4E, 0x00D6, 2 }, + { 0x1E4F, 0x00F6, 2 }, + { 0x1E54, 0x0050, 1 }, + { 0x1E55, 0x0070, 1 }, + { 0x1E5A, 0x0052, 4 }, + { 0x1E5B, 0x0072, 4 }, + { 0x1E62, 0x0053, 4 }, + { 0x1E63, 0x0073, 4 }, + { 0x1E6C, 0x0054, 4 }, + { 0x1E6D, 0x0074, 4 }, + { 0x1E78, 0x00DA, 2 }, /*{ 0x1E78, 0x0168, 1 },*/ /*{ 0x1E78, 0x0055, 1, 2 },*/ + { 0x1E79, 0x00FA, 2 }, /*{ 0x1E79, 0x0169, 1 },*/ /*{ 0x1E79, 0x0075, 1, 2 },*/ + { 0x1E7C, 0x0056, 2 }, + { 0x1E7D, 0x0076, 2 }, + { 0x1E7E, 0x0056, 4 }, + { 0x1E7F, 0x0076, 4 }, + { 0x1E80, 0x0057, 0 }, + { 0x1E81, 0x0077, 0 }, + { 0x1E82, 0x0057, 1 }, + { 0x1E83, 0x0077, 1 }, + { 0x1E88, 0x0057, 4 }, + { 0x1E89, 0x0077, 4 }, + { 0x1E92, 0x005A, 4 }, + { 0x1E93, 0x007A, 4 }, + { 0x1EA0, 0x0041, 4 }, + { 0x1EA1, 0x0061, 4 }, + { 0x1EA2, 0x0041, 3 }, + { 0x1EA3, 0x0061, 3 }, + { 0x1EA4, 0x00C2, 1 }, + { 0x1EA5, 0x00E2, 1 }, + { 0x1EA6, 0x00C2, 0 }, + { 0x1EA7, 0x00E2, 0 }, + { 0x1EA8, 0x00C2, 3 }, + { 0x1EA9, 0x00E2, 3 }, + { 0x1EAA, 0x00C2, 2 }, + { 0x1EAB, 0x00E2, 2 }, + { 0x1EAC, 0x00C2, 4 }, + { 0x1EAD, 0x00E2, 4 }, + { 0x1EAE, 0x0102, 1 }, + { 0x1EAF, 0x0103, 1 }, + { 0x1EB0, 0x0102, 0 }, + { 0x1EB1, 0x0103, 0 }, + { 0x1EB2, 0x0102, 3 }, + { 0x1EB3, 0x0103, 3 }, + { 0x1EB4, 0x0102, 2 }, + { 0x1EB5, 0x0103, 2 }, + { 0x1EB6, 0x0102, 4 }, + { 0x1EB7, 0x0103, 4 }, + { 0x1EB8, 0x0045, 4 }, + { 0x1EB9, 0x0065, 4 }, + { 0x1EBA, 0x0045, 3 }, + { 0x1EBB, 0x0065, 3 }, + { 0x1EBC, 0x0045, 2 }, + { 0x1EBD, 0x0065, 2 }, + { 0x1EBE, 0x00CA, 1 }, + { 0x1EBF, 0x00EA, 1 }, + { 0x1EC0, 0x00CA, 0 }, + { 0x1EC1, 0x00EA, 0 }, + { 0x1EC2, 0x00CA, 3 }, + { 0x1EC3, 0x00EA, 3 }, + { 0x1EC4, 0x00CA, 2 }, + { 0x1EC5, 0x00EA, 2 }, + { 0x1EC6, 0x00CA, 4 }, + { 0x1EC7, 0x00EA, 4 }, + { 0x1EC8, 0x0049, 3 }, + { 0x1EC9, 0x0069, 3 }, + { 0x1ECA, 0x0049, 4 }, + { 0x1ECB, 0x0069, 4 }, + { 0x1ECC, 0x004F, 4 }, + { 0x1ECD, 0x006F, 4 }, + { 0x1ECE, 0x004F, 3 }, + { 0x1ECF, 0x006F, 3 }, + { 0x1ED0, 0x00D4, 1 }, + { 0x1ED1, 0x00F4, 1 }, + { 0x1ED2, 0x00D4, 0 }, + { 0x1ED3, 0x00F4, 0 }, + { 0x1ED4, 0x00D4, 3 }, + { 0x1ED5, 0x00F4, 3 }, + { 0x1ED6, 0x00D4, 2 }, + { 0x1ED7, 0x00F4, 2 }, + { 0x1ED8, 0x00D4, 4 }, + { 0x1ED9, 0x00F4, 4 }, + { 0x1EDA, 0x01A0, 1 }, + { 0x1EDB, 0x01A1, 1 }, + { 0x1EDC, 0x01A0, 0 }, + { 0x1EDD, 0x01A1, 0 }, + { 0x1EDE, 0x01A0, 3 }, + { 0x1EDF, 0x01A1, 3 }, + { 0x1EE0, 0x01A0, 2 }, + { 0x1EE1, 0x01A1, 2 }, + { 0x1EE2, 0x01A0, 4 }, + { 0x1EE3, 0x01A1, 4 }, + { 0x1EE4, 0x0055, 4 }, + { 0x1EE5, 0x0075, 4 }, + { 0x1EE6, 0x0055, 3 }, + { 0x1EE7, 0x0075, 3 }, + { 0x1EE8, 0x01AF, 1 }, + { 0x1EE9, 0x01B0, 1 }, + { 0x1EEA, 0x01AF, 0 }, + { 0x1EEB, 0x01B0, 0 }, + { 0x1EEC, 0x01AF, 3 }, + { 0x1EED, 0x01B0, 3 }, + { 0x1EEE, 0x01AF, 2 }, + { 0x1EEF, 0x01B0, 2 }, + { 0x1EF0, 0x01AF, 4 }, + { 0x1EF1, 0x01B0, 4 }, + { 0x1EF2, 0x0059, 0 }, + { 0x1EF3, 0x0079, 0 }, + { 0x1EF4, 0x0059, 4 }, + { 0x1EF5, 0x0079, 4 }, + { 0x1EF6, 0x0059, 3 }, + { 0x1EF7, 0x0079, 3 }, + { 0x1EF8, 0x0059, 2 }, + { 0x1EF9, 0x0079, 2 }, + { 0x1FED, 0x00A8, 0 }, + { 0x1FEE, 0x00A8, 1 }, /* U+1FEE => U+0385 => U+00A8 U+0301 */ +}; + +#endif /* _VIETCOMB_H */ diff --git a/libs/libiconv/lib/viscii.h b/libs/libiconv/lib/viscii.h new file mode 100644 index 00000000..04e68fa8 --- /dev/null +++ b/libs/libiconv/lib/viscii.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 1999-2001 Free Software Foundation, Inc. + * This file is part of the GNU LIBICONV Library. + * + * The GNU LIBICONV Library is free software; you can redistribute it + * and/or modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * The GNU LIBICONV Library is distributed in the hope that it will be + * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with the GNU LIBICONV Library; see the file COPYING.LIB. + * If not, write to the Free Software Foundation, Inc., 51 Franklin Street, + * Fifth Floor, Boston, MA 02110-1301, USA. + */ + +/* + * VISCII1.1-1 + */ + +/* Specification: RFC 1456 */ + +static const unsigned short viscii_2uni_1[32] = { + /* 0x00 */ + 0x0000, 0x0001, 0x1eb2, 0x0003, 0x0004, 0x1eb4, 0x1eaa, 0x0007, + 0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, + /* 0x10 */ + 0x0010, 0x0011, 0x0012, 0x0013, 0x1ef6, 0x0015, 0x0016, 0x0017, + 0x0018, 0x1ef8, 0x001a, 0x001b, 0x001c, 0x001d, 0x1ef4, 0x001f, +}; +static const unsigned short viscii_2uni_2[128] = { + /* 0x80 */ + 0x1ea0, 0x1eae, 0x1eb0, 0x1eb6, 0x1ea4, 0x1ea6, 0x1ea8, 0x1eac, + 0x1ebc, 0x1eb8, 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6, 0x1ed0, + /* 0x90 */ + 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8, 0x1ee2, 0x1eda, 0x1edc, 0x1ede, + 0x1eca, 0x1ece, 0x1ecc, 0x1ec8, 0x1ee6, 0x0168, 0x1ee4, 0x1ef2, + /* 0xa0 */ + 0x00d5, 0x1eaf, 0x1eb1, 0x1eb7, 0x1ea5, 0x1ea7, 0x1ea9, 0x1ead, + 0x1ebd, 0x1eb9, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5, 0x1ec7, 0x1ed1, + /* 0xb0 */ + 0x1ed3, 0x1ed5, 0x1ed7, 0x1ee0, 0x01a0, 0x1ed9, 0x1edd, 0x1edf, + 0x1ecb, 0x1ef0, 0x1ee8, 0x1eea, 0x1eec, 0x01a1, 0x1edb, 0x01af, + /* 0xc0 */ + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x1ea2, 0x0102, 0x1eb3, 0x1eb5, + 0x00c8, 0x00c9, 0x00ca, 0x1eba, 0x00cc, 0x00cd, 0x0128, 0x1ef3, + /* 0xd0 */ + 0x0110, 0x1ee9, 0x00d2, 0x00d3, 0x00d4, 0x1ea1, 0x1ef7, 0x1eeb, + 0x1eed, 0x00d9, 0x00da, 0x1ef9, 0x1ef5, 0x00dd, 0x1ee1, 0x01b0, + /* 0xe0 */ + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x1ea3, 0x0103, 0x1eef, 0x1eab, + 0x00e8, 0x00e9, 0x00ea, 0x1ebb, 0x00ec, 0x00ed, 0x0129, 0x1ec9, + /* 0xf0 */ + 0x0111, 0x1ef1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x1ecf, 0x1ecd, + 0x1ee5, 0x00f9, 0x00fa, 0x0169, 0x1ee7, 0x00fd, 0x1ee3, 0x1eee, +}; + +static int +viscii_mbtowc (conv_t conv, ucs4_t *pwc, const unsigned char *s, int n) +{ + unsigned char c = *s; + if (c < 0x20) + *pwc = (ucs4_t) viscii_2uni_1[c]; + else if (c < 0x80) + *pwc = (ucs4_t) c; + else + *pwc = (ucs4_t) viscii_2uni_2[c-0x80]; + return 1; +} + +static const unsigned char viscii_page00[64+184] = { + 0xc0, 0xc1, 0xc2, 0xc3, 0x00, 0x00, 0x00, 0x00, /* 0xc0-0xc7 */ + 0xc8, 0xc9, 0xca, 0x00, 0xcc, 0xcd, 0x00, 0x00, /* 0xc8-0xcf */ + 0x00, 0x00, 0xd2, 0xd3, 0xd4, 0xa0, 0x00, 0x00, /* 0xd0-0xd7 */ + 0x00, 0xd9, 0xda, 0x00, 0x00, 0xdd, 0x00, 0x00, /* 0xd8-0xdf */ + 0xe0, 0xe1, 0xe2, 0xe3, 0x00, 0x00, 0x00, 0x00, /* 0xe0-0xe7 */ + 0xe8, 0xe9, 0xea, 0x00, 0xec, 0xed, 0x00, 0x00, /* 0xe8-0xef */ + 0x00, 0x00, 0xf2, 0xf3, 0xf4, 0xf5, 0x00, 0x00, /* 0xf0-0xf7 */ + 0x00, 0xf9, 0xfa, 0x00, 0x00, 0xfd, 0x00, 0x00, /* 0xf8-0xff */ + /* 0x0100 */ + 0x00, 0x00, 0xc5, 0xe5, 0x00, 0x00, 0x00, 0x00, /* 0x00-0x07 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x08-0x0f */ + 0xd0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x17 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x18-0x1f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x27 */ + 0xce, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x30-0x37 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x38-0x3f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x47 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x48-0x4f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50-0x57 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x67 */ + 0x9d, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x77 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x87 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8f */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x97 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9f */ + 0xb4, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xa0-0xa7 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, /* 0xa8-0xaf */ + 0xdf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xb0-0xb7 */ +}; +static const unsigned char viscii_page1e[96] = { + 0x80, 0xd5, 0xc4, 0xe4, 0x84, 0xa4, 0x85, 0xa5, /* 0xa0-0xa7 */ + 0x86, 0xa6, 0x06, 0xe7, 0x87, 0xa7, 0x81, 0xa1, /* 0xa8-0xaf */ + 0x82, 0xa2, 0x02, 0xc6, 0x05, 0xc7, 0x83, 0xa3, /* 0xb0-0xb7 */ + 0x89, 0xa9, 0xcb, 0xeb, 0x88, 0xa8, 0x8a, 0xaa, /* 0xb8-0xbf */ + 0x8b, 0xab, 0x8c, 0xac, 0x8d, 0xad, 0x8e, 0xae, /* 0xc0-0xc7 */ + 0x9b, 0xef, 0x98, 0xb8, 0x9a, 0xf7, 0x99, 0xf6, /* 0xc8-0xcf */ + 0x8f, 0xaf, 0x90, 0xb0, 0x91, 0xb1, 0x92, 0xb2, /* 0xd0-0xd7 */ + 0x93, 0xb5, 0x95, 0xbe, 0x96, 0xb6, 0x97, 0xb7, /* 0xd8-0xdf */ + 0xb3, 0xde, 0x94, 0xfe, 0x9e, 0xf8, 0x9c, 0xfc, /* 0xe0-0xe7 */ + 0xba, 0xd1, 0xbb, 0xd7, 0xbc, 0xd8, 0xff, 0xe6, /* 0xe8-0xef */ + 0xb9, 0xf1, 0x9f, 0xcf, 0x1e, 0xdc, 0x14, 0xd6, /* 0xf0-0xf7 */ + 0x19, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xf8-0xff */ +}; + +static int +viscii_wctomb (conv_t conv, unsigned char *r, ucs4_t wc, int n) +{ + unsigned char c = 0; + if (wc < 0x0080 && (wc >= 0x0020 || (0x42100064 & (1 << wc)) == 0)) { + *r = wc; + return 1; + } + else if (wc >= 0x00c0 && wc < 0x01b8) + c = viscii_page00[wc-0x00c0]; + else if (wc >= 0x1ea0 && wc < 0x1f00) + c = viscii_page1e[wc-0x1ea0]; + if (c != 0) { + *r = c; + return 1; + } + return RET_ILUNI; +} diff --git a/libs/libiconv/libcharset/AUTHORS b/libs/libiconv/libcharset/AUTHORS new file mode 100644 index 00000000..8bedd794 --- /dev/null +++ b/libs/libiconv/libcharset/AUTHORS @@ -0,0 +1 @@ +Bruno Haible diff --git a/libs/libiconv/libcharset/COPYING.LIB b/libs/libiconv/libcharset/COPYING.LIB new file mode 100644 index 00000000..778d0bb5 --- /dev/null +++ b/libs/libiconv/libcharset/COPYING.LIB @@ -0,0 +1,482 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + MA 02110-1301, USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/libs/libiconv/libcharset/ChangeLog b/libs/libiconv/libcharset/ChangeLog new file mode 100644 index 00000000..0e07ec44 --- /dev/null +++ b/libs/libiconv/libcharset/ChangeLog @@ -0,0 +1,699 @@ +2010-09-23 Bruno Haible + + Switch to autoconf 2.68. + * autogen.sh: Update comment. + * Makefile.devel (AUTOCONF, AUTOHEADER): Switch to version 2.68. + +2010-09-23 Bruno Haible + + * m4/libtool.m4: Update from libtool-2.4, with modifications: + 2008-04-06 Bruno Haible + * m4/libtool.m4 (LT_INIT): When setting LIBTOOL, use + CONFIG_SHELL; don't assume that the Makefile.in will set SHELL + to ${CONFIG_SHELL}. + * m4/ltversion.m4: Update from libtool-2.4. + * build-aux/ltmain.sh: Likewise. + +2010-07-31 Bruno Haible + + * Makefile.devel (AUTOCONF, AUTOHEADER): Switch to version 2.67. + +2010-07-03 Bruno Haible + + * Makefile.devel (AUTOCONF, AUTOHEADER): Switch to version 2.66. + +2010-06-04 Bruno Haible + + Addendum to 2009-10-18 commit. + * m4/fcntl-o.m4: New file, from gnulib. + * m4/fcntl_h.m4: Remove file. + +2010-06-04 Bruno Haible + + * m4/libtool.m4: Update from libtool-2.2.8, with modifications: + 2008-04-06 Bruno Haible + * m4/libtool.m4 (LT_INIT): When setting LIBTOOL, use + CONFIG_SHELL; don't assume that the Makefile.in will set SHELL + to ${CONFIG_SHELL}. + * m4/ltoptions.m4: Update from libtool-2.2.8. + * m4/ltversion.m4: Likewise. + * m4/lt~obsolete.m4: Likewise. + * build-aux/ltmain.sh: Likewise. + +2010-05-08 Bruno Haible + + * tools/cygwin-1.7.2: New file. + * lib/config.charset: Update comments for Cygwin 1.7. + * lib/localcharset.c: Likewise. + +2010-03-30 Bruno Haible + + * README.woe32: Mention Cygwin. + +2009-12-11 Bruno Haible + + * include/libcharset.h.in: Untabify. + +2009-12-11 Bruno Haible + + * Makefile.devel (AUTOCONF, AUTOHEADER): Switch to version 2.65. + +2009-10-18 Bruno Haible + + * README: Update. + +2009-10-18 Bruno Haible + + * configure.ac: Invoke gl_FCNTL_O_FLAGS. + * INTEGRATE: Mention fcntl_h.m4 and the gl_FCNTL_O_FLAGS invocation. + +2009-08-15 Bruno Haible + + * Makefile.devel (AUTOCONF, AUTOHEADER): Switch to version 2.64. + +2009-05-19 Bruno Haible + + * Makefile.devel (AUTOMAKE, ACLOCAL): Switch to version 1.11. + * autogen.sh: Update comments. + +2009-01-25 Bruno Haible + + Don't install charset.alias on MacOS X >= 10.3. + * INTEGRATE: Don't install charset.alias on MacOS X >= 10.3, if the + file does not yet exist. + +2009-01-25 Bruno Haible + + Don't install charset.alias on mingw and Cygwin. + * INTEGRATE: Don't install charset.alias on mingw and Cygwin, if the + file does not yet exist. The result for these platforms is hardcoded in + localcharset.c. + +2009-01-24 Bruno Haible + + * tools/all-charsets: Add CP1131, ARMSCII-8, PT154 to the list of + allowed encodings. + * tools/darwin-7.5: Regenerated. + * tools/darwin-9.5: Regenerated. + +2009-01-18 Bruno Haible + + * tools/darwin-9.5: New file. + +2009-01-18 Bruno Haible + + * tools/locale_monthnames.c: New file. + +2009-01-16 Bruno Haible + + * Makefile.in (install-strip): New target. + Reported by Alon Bar-Lev . + +2009-01-14 Bruno Haible + + * configure.ac: More consistent m4 quoting. + +2008-09-28 Bruno Haible + + * build-aux/ltmain.sh (func_emit_cwrapperexe_src): On mingw, + preprocess the argument vector through prepare_spawn. + +2008-09-16 Bruno Haible + + * Makefile.devel (AUTOCONF, AUTOHEADER): Switch to version 2.63. + +2008-09-07 Bruno Haible + + * m4/libtool.m4: Update from libtool-2.2.6, with modifications: + 2008-04-06 Bruno Haible + * m4/libtool.m4 (LT_INIT): When setting LIBTOOL, use + CONFIG_SHELL; don't assume that the Makefile.in will set SHELL + to ${CONFIG_SHELL}. + * m4/ltoptions.m4: Update from libtool-2.2.6. + * m4/ltsugar.m4: Likewise. + * m4/ltversion.m4: Likewise. + * build-aux/ltmain.sh: Likewise. + +2008-05-18 Bruno Haible + + * m4/libtool.m4: Update from libtool-2.2.4, with modifications: + 2008-04-06 Bruno Haible + * m4/libtool.m4 (LT_INIT): When setting LIBTOOL, use + CONFIG_SHELL; don't assume that the Makefile.in will set SHELL + to ${CONFIG_SHELL}. + * m4/ltoptions.m4: Update from libtool-2.2.4. + * m4/ltversion.m4: Likewise. + * m4/lt~obsolete.m4: Likewise. + * build-aux/ltmain.sh: Likewise. + +2008-04-14 Bruno Haible + + * configure.ac: Invoke AC_USE_SYSTEM_EXTENSIONS instead of AC_AIX and + AC_MINIX. + * Makefile.devel (AUTOCONF, AUTOHEADER): Require autoconf-2.62. + +2008-04-06 Bruno Haible + + * m4/libtool.m4: Update from libtool-2.2.2, with modifications: + 2008-04-06 Bruno Haible + * m4/libtool.m4 (LT_INIT): When setting LIBTOOL, use + CONFIG_SHELL; don't assume that the Makefile.in will set SHELL + to ${CONFIG_SHELL}. + * m4/ltoptions.m4: New file, from libtool-2.2.2. + * m4/ltsugar.m4: New file, from libtool-2.2.2. + * m4/ltversion.m4: New file, from libtool-2.2.2. + * m4/lt~obsolete.m4: New file, from libtool-2.2.2. + * build-aux/ltmain.sh: New file, from libtool-2.2.2. + * configure.ac: Use LT_INIT instead of AC_PROG_LIBTOOL. + +2007-11-14 Bruno Haible + + * tools/all-locales: Add "C" for Darwin. Treat OpenBSD like Darwin. + +2007-11-11 Bruno Haible + + * Makefile.devel (AUTOCONF, AUTOHEADER): Require version 2.61. + (ACLOCAL): Require version 1.10. + +2007-10-26 Bruno Haible + + * m4/libtool.m4: Update, based on libtool-1.5.24. + * build-aux/ltmain.sh: Update, based on libtool-1.5.24. + +2007-06-30 Bruno Haible + + * autogen.sh: New file. + * DEPENDENCIES: New file. + * HACKING: New file. + +2007-03-04 Bruno Haible + + * configure.ac: Invoke gl_RELOCATABLE_LIBRARY instead of + AC_RELOCATABLE_LIBRARY. + * m4/relocatable-lib.m4: New file, from gnulib. + * m4/relocatable.m4: Remove file. + +2007-02-16 Juan Manuel Guerrero + + * djgpp/*: Update. + +2006-10-31 Bruno Haible + + Update from GNU gettext. + 2006-10-25 Bruno Haible + * m4/relocatable.m4 (AC_RELOCATABLE_BODY): Renamed from + AC_RELOCATABLE, without the AC_LIBOBJ invocation. + (AC_RELOCATABLE): New macro. Invoke AC_LIBOBJ here. + +2006-10-18 Bruno Haible + + * INTEGRATE: Remove recommendation to test for setlocale. + +2006-07-29 Bruno Haible + + * configure.ac: Assume , , exist. + +2006-07-29 Bruno Haible + + * configure.ac: Remove obsolete calls AC_PROG_GCC_TRADITIONAL, + AC_ISC_POSIX. + +2006-07-25 Bruno Haible + + * Makefile.msvc: Remove file. + * Makefile.devel (config.h.msvc): Remove rule. + (include/libcharset.h.msvc-shared, include/localcharset.h.msvc-shared): + Remove rules. + (all): Update. + +2006-07-25 Bruno Haible + + * Makefile.vms: Remove file. + * Makefile.devel (config.h_vms): Remove rule. + (all): Update. + +2006-06-27 Bruno Haible + + * Makefile.devel (AUTOCONF, AUTOHEADER): Use autoconf-2.60. + * Makefile.in (datarootdir): New variable. + * configure.ac (mandir): Remove customization. + +2006-03-28 Ralf Wildenhues + + * m4/libtool.m4 (_LT_SYS_DYNAMIC_LINKER) [ linux ]: Avoid warning when + "parsing" /etc/ld.so.conf and empty /etc/ld.so.conf.d. + +2006-05-15 Bruno Haible + + * m4/relocatable.m4: Update from GNU gettext. + +2006-05-14 Bruno Haible , + Ralf Wildenhues + + * m4/libtool.m4 [ linux ] (AC_LIBTOOL_LANG_CXX_CONFIG) + (AC_LIBTOOL_POSTDEP_PREDEP, AC_LIBTOOL_PROG_COMPILER_PIC) + (AC_LIBTOOL_PROG_LD_SHLIBS): Add support for Sun C 5.9, + Sun C++ 5.9, and Sun Fortran 8.3 on Linux. + +2006-05-06 Charles Wilson + + * m4/libtool.m4: On Cygwin, like on mingw, define DLL_EXPORT when + compiling a shared library object. + +2006-03-31 Juan Manuel Guerrero + + * djgpp/*: Update. + +2005-12-29 Bruno Haible + + * configure.ac: Renamed from configure.in. + * Makefile.devel (configure, config.h.in): Update. + * djgpp/Makefile.maint (fnchange.lst, README): Update. + +2005-12-29 Bruno Haible + + * build-aux/config.guess: Update to GNU version 2005-12-23. + * build-aux/config.sub: Likewise. + * build-aux/config.libpath: Update from GNU gettext. + +2005-12-29 Bruno Haible + + * m4/codeset.m4: Update from GNU gettext. + * m4/glibc21.m4: Update from GNU gettext. + * m4/relocatable.m4: Update from GNU gettext. + * configure: Invoke gl_GLIBC21 instead of jm_GLIBC21. + +2005-12-29 Bruno Haible + + * m4/libtool.m4: Update, based on libtool-1.5.22. + * build-aux/ltmain.sh: Update, based on libtool-1.5.22. + +2005-09-18 Bruno Haible + + * m4/libtool.m4: Update, based on libtool-1.5.20. + * build-aux/ltmain.sh: Update, based on libtool-1.5.20. + +2005-07-24 Bruno Haible + + Tidy up exported symbols. + * m4/visibility.m4: New file. + * include/export.h: New file. + * configure.in Invoke gl_VISIBILITY. Use AC_CONFIG_FILES. Arrange to + create also include/localcharset.h.inst. + (VERSION): Bump to 1.4. + * Makefile.devel (all): Depend on include/localcharset.h.build.in. + (include/localcharset.h.build.in): New rule. + * Makefile.in (all): Remove dependency on include/localcharset.h. + (include/localcharset.h): Remove rule. + (install-lib, install): Install include/localcharset.h.inst, + not the include/localcharset.h that was used for building. + (distclean, maintainer-clean): Remove also include/localcharset.h.inst. + +2005-07-08 Bruno Haible + + * m4/libtool.m4 (postinstall_cmds) [cygwin,mingw,pw32]: Make DLL + executable after installing it. + +2005-07-07 Bruno Haible + + * configure.in: Bump version number. + * windows/charset.rc: Likewise. + +2005-07-05 Bruno Haible + + * m4/relocatable.m4 (AC_RELOCATABLE): On mingw, simply set + SET_RELOCATABLE to a trivial value. + +2005-07-05 Bruno Haible + + * Makefile.devel (AUTOHEADER, ACLOCAL): New variables. + (autoconf/aclocal.m4, config.h.in): Use them. + +2005-03-22 Bruno Haible + + * build-aux: New directory, renamed from autoconf. + * configure.in (AC_CONFIG_AUX_DIR): Use build-aux. + * Makefile.in (mkinstalldirs): Update. + +2005-01-05 Bruno Haible + + * m4/libtool.m4: Update from GNU gettext, based on libtool-1.5.10. + * autoconf/ltmain.sh: Update from GNU gettext, based on libtool-1.5.10. + +2004-09-21 Juan Manuel Guerrero + + * djgpp/config.bat: Update. + * djgpp/config.sed: Update. + * djgpp/config.site: Update. + * djgpp/fnchange.in: Update. + * djgpp/README.in: Update. + +2004-08-25 Bruno Haible + + * m4/libtool.m4: Update from GNU gettext, based on libtool-1.5.6. + * autoconf/ltmain.sh: Update from GNU gettext, based on libtool-1.5.6. + +2004-01-20 Bruno Haible + + Upgrade from gettext-0.14. + + 2003-08-24 Bruno Haible + * m4/relocatable.m4 (AC_RELOCATABLE): Use $(host) instead of @host@, + since the substitution of @host@ may occur before the substitution of + @SET_RELOCATABLE@. + +2004-01-20 Bruno Haible + + Assume automake-1.8. + * Makefile.devel (AUTOCONF): Assume autoconf-2.59. + +2003-06-18 Bruno Haible + + * config/install-sh: Update from automake-1.7.5. + +2003-06-07 Bruno Haible + + * Makefile.devel (config.h_vms): Remove INSTALLPREFIX. + Reported by Jouk Jansen . + +2003-05-19 Bruno Haible + + * windows/charset.rc: Include . + Reported by Perry Rapp. + +2003-05-07 Bruno Haible + + * Makefile.vms: New file. + * Makefile.devel (config.h_vms): New rule. + (all): Depend on it. + +2003-05-06 Bruno Haible + + * m4/libtool.m4: Update from GNU gettext, based on libtool-1.5. + +2003-05-06 Bruno Haible + + * autoconf/config.guess: Update to GNU version 2003-02-22. + * autoconf/config.sub: Likewise. + +2003-05-06 Bruno Haible + + * autoconf/ltmain.sh: Update from GNU gettext, based on libtool-1.5. + +2003-04-12 Bruno Haible + + * configure.in (mandir): Change default value. + * Makefile.in (datadir): New variable. + +2003-04-05 Bruno Haible + + Support for relocatable installation. + * m4/relocatable.m4: New file, from GNU gettext. + * autoconf/config.libpath: New file, from GNU gettext. + * configure.in: Invoke AC_RELOCATABLE_LIBRARY. + * include/libcharset.h.in: New file. + * Makefile.devel (include/libcharset.h.msvc-shared): New rule. + (all): Depend on it. + (autoconf/aclocal.m4): Update aclocal invocation. + (config.h.msvc): Handle INSTALLPREFIX. + * Makefile.in (include/libcharset.h): New rule. + (all): Depend on it. + (install-lib, install): Also install libcharset.h. + (uninstall): Uninstall libcharset.h. + (distclean, maintainer-clean): Remove include/libcharset.h. + * Makefile.msvc (all): Create include/libcharset.h. + (install): Also install libcharset.h. + (uninstall): Uninstall libcharset.h. + (mostlyclean, clean, distclean, maintainer-clean): Remove + include/libcharset.h. + * INSTALL.generic: Document --enable-relocatable and + --with-libintl-prefix. Remove the recommendation to set CPPFLAGS and + LDFLAGS. The lib-link.m4 macros make this unnecessary. + +2003-04-05 Bruno Haible + + * Makefile.msvc (PREFIX): New variable. + (prefix): Use it. + (distclean, maintainer-clean): Drop Unix specific removals. + * man/Makefile.msvc (PREFIX): New variable. + (prefix): Use it. + (clean): Drop unnecessary removals. + (distclean): Drop Unix specific removal. + +2003-04-05 Bruno Haible + + * configure.in: Invoke AM_LANGINFO_CODESET, not jm_LANGINFO_CODESET. + * autoconf/ltmain.sh: Update from GNU gettext. + 2003-02-18 Bruno Haible + Fix the 2002-09-16 fix. + * ltmain.sh (install): If "ln -s -f" fails (this is the case + with /usr/bin/ln on Solaris 2.7), fall back to "rm && ln -s". + * m4/codeset.m4: Update from GNU gettext-0.10.40. + * m4/glibc21.m4: Update from GNU gettext-0.10.40. + +2003-03-17 Bruno Haible + + Improved MSVC support. + * windows/charset.rc: New file. + * Makefile.msvc (prefix): Use less Unixy value. + (local_prefix): Remove variable. + (libdir, includedir): Use backslashes. + (bindir): New variable. + (mandir): Remove variable. + (INSTALL, INSTALL_PROGRAM, INSTALL_DATA): New variables. + (mostlyclean, clean): Remove config.h and include/localcharset.h. + (install, installdirs, uninstall): Rewritten. + * README.woe32: Mention automatic installation command. + + Rename libcharset.h to localcharset.h. + * include/localcharset.h.in: Renamed from include/libcharset.h.in. + * tools/locale_charset.c: Include localcharset.h, not libcharset.h. + * Makefile.in (include/localcharset.h): Renamed from + include/libcharset.h. + (all): Update dependency. + (install-lib, install, uninstall, distclean, maintainer-clean): Update. + * Makefile.msvc (all): Create include/localcharset.h, not + include/libcharset.h. + * Makefile.devel (include/localcharset.h.msvc-shared): Renamed from + include/libcharset.h.msvc-shared. + (all): Update dependency. + (config.h.in): Touch the file when done; autoheader doesn't do it. + (config.h.msvc): Make rule more robust. + * INTEGRATE: Mention localcharset.h only once. + * djgpp/README.in, djgpp/README: Update. + * djgpp/config.bat: Update. + * djgpp/config.sed: Update. + * djgpp/fnchange.in, djgpp/fnchange.lst: Update. + * configure.in (VERSION): Bump to 1.2. + * NEWS: New file. + +2003-02-14 Bruno Haible + + * Makefile.devel (AUTOCONF): Switch to autoconf-2.57. + (configure, config.h.in): Update rules. + +2003-01-03 Albert Chin + + * autoconf/ltmain.sh: Don't pass -R flags found in a .la's + dependency_libs variable directly down to the linker. + Reported by Tim Mooney . + +2003-01-12 Bruno Haible + + * INTEGRATE: Mention localcharset.h. + +2003-01-01 Bruno Haible + + * Makefile.in (mkinstalldirs): Renamed from MKINSTALLDIRS. + (install-lib, install, installdirs): Use it. + +2002-09-27 Bruno Haible + + * autoconf/mkinstalldirs: Upgrade to automake-1.7.2 version. + +2002-11-07 Bruno Haible + + * m4/libtool.m4: Upgrade to libtool-1.4.3. + * autoconf/ltmain.sh: Upgrade to libtool-1.4.3. + +2002-07-14 Bruno Haible + + * m4/libtool.m4 (_LT_AC_LTCONFIG_HACK): Add support for GNU/FreeBSD. + +2002-06-12 Bruno Haible + + * configure.in: Use new AC_* names of libtool macros. Invoke + AC_LIBTOOL_WIN32_DLL. + +2002-11-07 Bruno Haible + + Make "make install" without prior "make" work. + * Makefile.in (install): Depend on include/libcharset.h. + Reported by Martin Mokrejš . + +2002-05-12 Bruno Haible + + * tools/all-charsets: Update for change of lib/config.charset. + +2002-05-12 Bruno Haible + + * Makefile.devel (AUTOCONF): New variable. + (configure): Use the AUTOCONF variable. + +2002-05-08 Bruno Haible + + * README.woe32: Renamed from README.win32. + +2002-02-06 Bruno Haible + + * m4/libtool.m4: Upgrade to libtool-1.4.2. + * autoconf/ltmain.sh: Likewise. + +2002-02-02 Bruno Haible + + * autoconf/ltmain.sh: Add DESTDIR support on ELF systems. + +2001-11-03 Bruno Haible + + * autoconf/ltmain.sh: chmod 777 the .libs directory, so that + "make install" succeeds. + +2001-12-04 Bruno Haible + + * INTEGRATE: Change the install rule to not create $(libdir) if + there is no file to install in it. + +2001-07-17 Bruno Haible + + * configure.in (VERSION): Bump to 1.1. + +2001-06-08 Bruno Haible + + * m4/libtool.m4: Upgrade to libtool-1.4. + * autoconf/ltmain.sh: Likewise. + * autoconf/ltconfig: Remove file. + +2001-06-08 Bruno Haible + + * autoconf/config.guess: Update to GNU version 2001-05-11. + * autoconf/config.sub: Likewise. + +2001-05-21 Bruno Haible + + * Makefile.in (include/libcharset.h): New target. + (all): Depend on it. + +2001-05-11 Bruno Haible + + * INTEGRATE (Makefile.in): Fix syntax error. + +2001-05-06 Bruno Haible + + * Makefile.msvc (config.h): Allow the 'del' command to fail. + +2001-03-21 Bruno Haible + + * INSTALL.generic (Particular Systems): Add recommendations for AIX 3. + +2001-03-10 Bruno Haible + + * INSTALL.generic: New section "Particular Systems". + +2001-03-05 Bruno Haible + + * tools/all-charsets: Update for change of lib/config.charset. + +2001-03-01 Bruno Haible + + * tools/all-charsets: Update for change of lib/config.charset. + +2001-02-25 Bruno Haible + + * autoconf/ltconfig: + sed -e 's/reload object files/produce relocatable object files/'. + +2001-02-25 Bruno Haible + + * include/libcharset.h.in (locale_charset): Return value is never + NULL any more. + +2001-02-22 Bruno Haible + + * INTEGRATE (Makefile.am): Change $@-t to t-$@. For DJGPP. + Patch by Juan Manuel Guerrero . + +2001-02-20 Bruno Haible + + Better support for DOS/Windows platforms. + * autoconf/ltconfig: Upgrade to libtool-1.3.5. + * autoconf/ltmain.sh: Likewise. + * m4/libtool.m4: Likewise. + * autoconf/aclocal.m4: Likewise. + * configure.in: Call AC_OBJEXT and AC_EXEEXT. + +2001-02-20 Bruno Haible + + * Makefile.in (libdir, includedir, mandir): Use the autoconf + determined value, in order to respect the configure arguments. + * lib/Makefile.in (libdir): Likewise. + +2000-12-13 Bruno Haible + + * autoconf/install-sh: Update to a newer version from fileutils. + +2000-12-12 Bruno Haible + + * Makefile.in: Use $(MAKE) instead of $(MAKE) -r. Needed with Solaris + "make", which doesn't set MAKE as expected by @SET_MAKE@ if -r is + given. Reported by Toshimitsu Fujiwara. + +2000-12-08 Bruno Haible + + * Makefile.in (exec_prefix): Use configure's --exec-prefix argument. + +2000-12-02 Bruno Haible + + * Makefile.msvc (check): Depend on target 'force' as well. + (mostlyclean, clean, distclean, maintainer-clean): Fix dependency. + + * Makefile.msvc: Replace STATIC with its opposite flag, DLL. + +2000-11-24 Bruno Haible + + * tools/all-charsets: Update for 2000-10-31 change of + lib/config.charset. + +2000-11-23 Bruno Haible + + * Makefile.in (install-lib): Fix for builddir != srcdir. + +2000-11-22 Bruno Haible + + * Makefile.in (all): Fix for builddir != srcdir. + +2000-11-21 Bruno Haible + + * include/libcharset.h.in: Renamed from include/libcharset.h. + * windows/dllexport.h: New file. + * Makefile.devel (all): Add config.h.msvc, + include/libcharset.h.msvc-shared. + (config.h.msvc, include/libcharset.h.msvc-shared): New targets. + * Makefile.msvc (MFLAGS): New variable. + (all): Create include\libcharset.h. + (distclean, maintainer-clean): Remove include\libcharset.h. + * Makefile.in (CP): New variable. + (all): Create include/libcharset.h. + (distclean, maintainer-clean): Remove include/libcharset.h. + +2000-11-18 Bruno Haible + + * Makefile.devel (config.h.in): Rename from config.h. + +2000-11-16 Bruno Haible + + * Makefile.in: After "cd", use "&&" not ";". + +2000-10-31 Bruno Haible + + * Makefile.msvc: New file. + * README.win32: New file. diff --git a/libs/libiconv/libcharset/DEPENDENCIES b/libs/libiconv/libcharset/DEPENDENCIES new file mode 100644 index 00000000..42dae65a --- /dev/null +++ b/libs/libiconv/libcharset/DEPENDENCIES @@ -0,0 +1 @@ +No packages need to be installed before GNU libcharset is installed. diff --git a/libs/libiconv/libcharset/HACKING b/libs/libiconv/libcharset/HACKING new file mode 100644 index 00000000..57c744c1 --- /dev/null +++ b/libs/libiconv/libcharset/HACKING @@ -0,0 +1,36 @@ +All you need to know when hacking (modifying) GNU libcharset or when building +it off the CVS. + + +Requirements +============ + +You will need reasonably recent versions of the build tools: + + * A C compiler. Such as GNU GCC. + + Homepage: + http://gcc.gnu.org/ + + * GNU autoconf + + Homepage: + http://www.gnu.org/software/autoconf/ + + * GNU m4 + + Homepage: + http://www.gnu.org/software/m4/ + + * Perl + + Homepage: + http://www.perl.org/ + +And, of course, the packages listed in the DEPENDENCIES file. + + +Building off the CVS +==================== + +Access to the CVS is described at http://sourceforge.net/cvs/?group_id=51585 . + +After fetching the sources from the CVS, peek at the comments in autogen.sh, +then run "./autogen.sh"; then you can proceed with "./configure" as usual. + diff --git a/libs/libiconv/libcharset/INSTALL.generic b/libs/libiconv/libcharset/INSTALL.generic new file mode 100644 index 00000000..13813e8b --- /dev/null +++ b/libs/libiconv/libcharset/INSTALL.generic @@ -0,0 +1,273 @@ +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.ac' is used to create `configure' by a program +called `autoconf'. You only need `configure.ac' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + + On MacOS X 10.5 and later systems, you can create libraries and +executables that work on multiple system types--known as "fat" or +"universal" binaries--by specifying multiple '-arch' options to the +compiler but only a single '-arch' option to the preprocessor. Like +this: + + ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \ + CPP="gcc -E" CXXCPP="g++ -E" + + This is not guaranteed to produce working output in all cases. You +may have to build one architecture at a time and combine the results +using the 'lipo' tool if you have problems. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Relocatable Installation +======================== + + By default, `make install' will install a package with hardwired +file names, and the package will not work correctly when copied or +moved to a different location in the filesystem. + + Some packages pay attention to the `--enable-relocatable' option to +`configure'. This option makes the entire installed package +relocatable. This means, it can be moved or copied to a different +location on the filesystem. It is possible to make symlinks to the +installed and moved programs, and invoke them through the symlink. It +is possible to do the same thing with a hard link _only_ if the hard +linked file is in the same directory as the real program. + + For reliability it is best to give together with --enable-relocatable +a `--prefix' option pointing to an otherwise unused (and never used +again) directory, for example, `--prefix=/tmp/inst$$'. This is +recommended because on some OSes the executables remember the location +of shared libraries (and prefer them over LD_LIBRARY_PATH !), therefore +such an executable will look for its shared libraries first in the +original installation directory and only then in the current +installation directory. + + Installation with `--enable-relocatable' will not work for setuid / +setgid executables. (This is because such an executable kills its +LD_LIBRARY_PATH variable when it is launched.) + + The runtime penalty and size penalty are nearly zero on Linux 2.2 or +newer (just one system call more when an executable is launched), and +small on other systems (the wrapper program just sets an environment +variable and execs the real program). + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + + For packages that use the GNU libiconv library, you can use the +`configure' option `--with-libiconv-prefix' to specify the prefix you +used while installing GNU libiconv. This option is not necessary if +that other prefix is the same as the one now specified through --prefix. + + For packages that use the GNU libintl library, you can use the +`configure' option `--with-libintl-prefix' to specify the prefix you +used while installing GNU gettext-runtime. This option is not necessary if +that other prefix is the same as the one now specified through --prefix. + +Particular Systems +================== + + On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC +is not installed, it is recommended to use the following options in order +to use an ANSI C compiler: + + ./configure CC="cc -Ae -D_XOPEN_SOURCE=500" + +and if that doesn't work, install pre-built binaries of GCC for HP-UX. + + On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot +parse its `' header file. The option `-nodtk' can be used as +a workaround. If GNU CC is not installed, it is therefore recommended +to try + + ./configure CC="cc" + +and if that doesn't work, try + + ./configure CC="cc -nodtk" + + On AIX 3, the C include files by default don't define some necessary +prototype declarations. If GNU CC is not installed, it is recommended to +use the following options: + + ./configure CC="xlc -D_ALL_SOURCE" + + On BeOS, user installed software goes in /boot/home/config, not +/usr/local. It is recommended to use the following options: + + ./configure --prefix=/boot/home/config + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. + diff --git a/libs/libiconv/libcharset/INTEGRATE b/libs/libiconv/libcharset/INTEGRATE new file mode 100644 index 00000000..2eb1b032 --- /dev/null +++ b/libs/libiconv/libcharset/INTEGRATE @@ -0,0 +1,154 @@ +Integration of this library into your package: + +* Copy the lib/ sourcefiles (localcharset.c, config.charset, ref-add.sin, + ref-del.sin) and the include file (include/localcharset.h) into your + package. + +* Add the m4/ files (codeset.m4, fcntl_h.m4, glibc21.m4) to your aclocal.m4 + file or, if you are using automake, to your m4/ directory. + +* Add the following lines to your configure.ac file: + + AC_CANONICAL_HOST + AM_LANGINFO_CODESET + gl_FCNTL_O_FLAGS + jm_GLIBC21 + AC_CHECK_HEADERS(stddef.h stdlib.h string.h) + + and make sure that it sets and AC_SUBSTs the PACKAGE variable. + +* If you are not using automake, add rules to your Makefile.in: + + - Augment target "all" by + localcharset.o charset.alias ref-add.sed ref-del.sed + with special rules for the last three: + + charset.alias: $(srcdir)/config.charset + $(SHELL) $(srcdir)/config.charset '@host@' > t-$@ + mv t-$@ $@ + + ref-add.sed : $(srcdir)/ref-add.sin + sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $(srcdir)/ref-add.sin > t-$@ + mv t-$@ $@ + + ref-del.sed : $(srcdir)/ref-del.sin + sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $(srcdir)/ref-del.sin > t-$@ + mv t-$@ $@ + + - Augment target "install" by + + if test @GLIBC21@ = no; then \ + case '@host_os@' in \ + darwin[56]*) \ + need_charset_alias=true ;; \ + darwin* | cygwin* | mingw* | pw32* | cegcc*) \ + need_charset_alias=false ;; \ + *) \ + need_charset_alias=true ;; \ + esac ; \ + else \ + need_charset_alias=false ; \ + fi ; \ + if $$need_charset_alias; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir) ; \ + fi ; \ + if test -f $(DESTDIR)$(libdir)/charset.alias; then \ + sed -f ref-add.sed $(DESTDIR)$(libdir)/charset.alias > $(DESTDIR)$(libdir)/t-charset.alias; \ + $(INSTALL_DATA) $(DESTDIR)$(libdir)/t-charset.alias $(DESTDIR)$(libdir)/charset.alias; \ + rm -f $(DESTDIR)$(libdir)/t-charset.alias; \ + else \ + if $$need_charset_alias; then \ + sed -f ref-add.sed charset.alias > $(DESTDIR)$(libdir)/t-charset.alias; \ + $(INSTALL_DATA) $(DESTDIR)$(libdir)/t-charset.alias $(DESTDIR)$(libdir)/charset.alias; \ + rm -f $(DESTDIR)$(libdir)/t-charset.alias; \ + fi; \ + fi + + - Augment target "installdirs" by + + if test @GLIBC21@ = no; then \ + case '@host_os@' in \ + darwin[56]*) \ + need_charset_alias=true ;; \ + darwin* | cygwin* | mingw* | pw32* | cegcc*) \ + need_charset_alias=false ;; \ + *) \ + need_charset_alias=true ;; \ + esac ; \ + else \ + need_charset_alias=false ; \ + fi ; \ + if $$need_charset_alias; then \ + $(mkinstalldirs) $(DESTDIR)$(libdir) ; \ + fi ; \ + + - Augment target "uninstall" by + + if test -f $(DESTDIR)$(libdir)/charset.alias; then \ + sed -f ref-del.sed $(DESTDIR)$(libdir)/charset.alias > $(DESTDIR)$(libdir)/t-charset.alias; \ + if grep '^# Packages using this file: $$' $(DESTDIR)$(libdir)/t-charset.alias > /dev/null; then \ + rm -f $(DESTDIR)$(libdir)/charset.alias; \ + else \ + $(INSTALL_DATA) $(DESTDIR)$(libdir)/t-charset.alias $(DESTDIR)$(libdir)/charset.alias; \ + fi; \ + rm -f $(DESTDIR)$(libdir)/t-charset.alias; \ + fi + + - Augment target "clean" by + + rm -f charset.alias ref-add.sed ref-del.sed + +* If you are using automake, add rules to your Makefile.am: + + - Augment the main *_SOURCES variable by + + localcharset.h localcharset.c + + - Augment EXTRA_DIST by + + config.charset ref-add.sin ref-del.sin + + - Augment target "all-local" by + + charset.alias ref-add.sed ref-del.sed + + - Add the lines: + +charset_alias = $(DESTDIR)$(libdir)/charset.alias +charset_tmp = $(DESTDIR)$(libdir)/charset.tmp +install-exec-local: all-local + test @GLIBC21@ != no || $(mkinstalldirs) $(DESTDIR)$(libdir) + if test -f $(charset_alias); then \ + sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ + rm -f $(charset_tmp) ; \ + else \ + if test @GLIBC21@ = no; then \ + sed -f ref-add.sed charset.alias > $(charset_tmp) ; \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \ + rm -f $(charset_tmp) ; \ + fi ; \ + fi + +uninstall-local: all-local + if test -f $(charset_alias); then \ + sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \ + if grep '^# Packages using this file: $$' $(charset_tmp) \ + > /dev/null; then \ + rm -f $(charset_alias); \ + else \ + $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \ + fi; \ + rm -f $(charset_tmp); \ + fi + +charset.alias: config.charset + $(SHELL) $(srcdir)/config.charset '@host@' > t-$@ + mv t-$@ $@ + +SUFFIXES = .sed .sin +.sin.sed: + sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $< > t-$@ + mv t-$@ $@ + +CLEANFILES = charset.alias ref-add.sed ref-del.sed diff --git a/libs/libiconv/libcharset/NEWS b/libs/libiconv/libcharset/NEWS new file mode 100644 index 00000000..85caf004 --- /dev/null +++ b/libs/libiconv/libcharset/NEWS @@ -0,0 +1,5 @@ +New in 1.4: +* Tidy up the list of symbols exported from libcharset (assumes gcc >= 4.0). + +New in 1.2: +* The include file is renamed from "libcharset.h" to "localcharset.h". diff --git a/libs/libiconv/libcharset/README b/libs/libiconv/libcharset/README new file mode 100644 index 00000000..581f637f --- /dev/null +++ b/libs/libiconv/libcharset/README @@ -0,0 +1,62 @@ + LIBCHARSET - portable character set determination library + +This library provides a function which determines the character set / encoding +of text in the currently selected locale (the LC_CTYPE locale facet). + +It is useful for portable programs which need to process text in other +encodings and locales than the currently selected one. Possible uses: + + * Use of Unicode in POSIX compliant applications. + * Conversion of text between the current locale's encoding and UTF-8 (or + any other given encoding). + * Mail agents. + +In theory, this would be very simple: POSIX provides the nl_langinfo function, +in such a way that + + nl_langinfo (CODESET) + +returns the encoding name. But the nl_langinfo function still does not exist +on some systems, and on those where it exists it returns unstandardized +variations of the encoding names, like (on Solaris) "PCK" for "Shift_JIS". + +This library fixes these flaws and provides a function + + const char * locale_charset (void); + +It determines the current locale's character encoding, and canonicalizes it +into one of the canonical names listed in config.charset. The result must +not be freed; it is statically allocated. If the canonical name cannot be +determined, the result is a non-canonical name. + + +Installation: + +As usual for GNU packages: + + $ ./configure --prefix=/usr/local + $ make + $ make install + + +This library is used in + GNU coreutils + GNU gettext + GNU clisp + + +To integrate this library into your package: +- Either from this package. See file INTEGRATE. +- Or from gnulib. See + + + +Distribution: + The libcharset directory of + ftp://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.8.tar.gz + +Homepage: + http://www.haible.de/bruno/packages-libcharset.html + + +Bruno Haible diff --git a/libs/libiconv/libcharset/README.djgpp b/libs/libiconv/libcharset/README.djgpp new file mode 100644 index 00000000..aa8c4209 --- /dev/null +++ b/libs/libiconv/libcharset/README.djgpp @@ -0,0 +1,3 @@ +Installation on DJGPP: + +See the file djgpp/README. diff --git a/libs/libiconv/libcharset/README.woe32 b/libs/libiconv/libcharset/README.woe32 new file mode 100644 index 00000000..4ac0c415 --- /dev/null +++ b/libs/libiconv/libcharset/README.woe32 @@ -0,0 +1,4 @@ +Installation on Woe32 (WinNT/2000/XP/Vista/7, Win95/98/ME): + +Building requires the mingw or cygwin development environment (includes gcc). +MS Visual C/C++ with "nmake" is no longer supported. diff --git a/libs/libiconv/libcharset/include/export.h b/libs/libiconv/libcharset/include/export.h new file mode 100644 index 00000000..84e74aa3 --- /dev/null +++ b/libs/libiconv/libcharset/include/export.h @@ -0,0 +1,6 @@ + +#if @HAVE_VISIBILITY@ && BUILDING_LIBCHARSET +#define LIBCHARSET_DLL_EXPORTED __attribute__((__visibility__("default"))) +#else +#define LIBCHARSET_DLL_EXPORTED +#endif diff --git a/libs/libiconv/libcharset/include/localcharset.h b/libs/libiconv/libcharset/include/localcharset.h new file mode 100644 index 00000000..bf2ce21c --- /dev/null +++ b/libs/libiconv/libcharset/include/localcharset.h @@ -0,0 +1,48 @@ +/* Determine a canonical name for the current locale's character encoding. + Copyright (C) 2000-2003 Free Software Foundation, Inc. + This file is part of the GNU CHARSET Library. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +#ifndef _LOCALCHARSET_H +#define _LOCALCHARSET_H + +#if 1 && BUILDING_LIBCHARSET +#define LIBCHARSET_DLL_EXPORTED __attribute__((__visibility__("default"))) +#else +#define LIBCHARSET_DLL_EXPORTED +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Determine the current locale's character encoding, and canonicalize it + into one of the canonical names listed in config.charset. + The result must not be freed; it is statically allocated. + If the canonical name cannot be determined, the result is a non-canonical + name. */ +extern LIBCHARSET_DLL_EXPORTED const char * locale_charset (void); + + +#ifdef __cplusplus +} +#endif + + +#endif /* _LOCALCHARSET_H */ diff --git a/libs/libiconv/libcharset/lib/localcharset.c b/libs/libiconv/libcharset/lib/localcharset.c new file mode 100644 index 00000000..1b29597d --- /dev/null +++ b/libs/libiconv/libcharset/lib/localcharset.c @@ -0,0 +1,548 @@ +/* Determine a canonical name for the current locale's character encoding. + + Copyright (C) 2000-2006, 2008-2010 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published + by the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +/* Written by Bruno Haible . */ + +#include + +/* Specification. */ +#include "localcharset.h" + +#include +#include +#include +#include +#include + +#if defined __APPLE__ && defined __MACH__ && HAVE_LANGINFO_CODESET +# define DARWIN7 /* Darwin 7 or newer, i.e. MacOS X 10.3 or newer */ +#endif + +#if defined _WIN32 || defined __WIN32__ +# define WIN32_NATIVE +#endif + +#if defined __EMX__ +/* Assume EMX program runs on OS/2, even if compiled under DOS. */ +# ifndef OS2 +# define OS2 +# endif +#endif + +#if !defined WIN32_NATIVE && !defined ANDROID && !defined __ANDROID__ /* EDIT BY MR */ +# include +# if HAVE_LANGINFO_CODESET +# include +# else +# if 0 /* see comment below */ +# include +# endif +# endif +# ifdef __CYGWIN__ +# define WIN32_LEAN_AND_MEAN +# include +# endif +#elif defined WIN32_NATIVE +# define WIN32_LEAN_AND_MEAN +# include +#endif +#if defined OS2 +# define INCL_DOS +# include +#endif + +#if ENABLE_RELOCATABLE +# include "relocatable.h" +#else +# define relocate(pathname) (pathname) +#endif + +/* Get LIBDIR. */ +#ifndef LIBDIR +# include "configmake.h" +#endif + +/* Define O_NOFOLLOW to 0 on platforms where it does not exist. */ +#ifndef O_NOFOLLOW +# define O_NOFOLLOW 0 +#endif + +#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ + /* Win32, Cygwin, OS/2, DOS */ +# define ISSLASH(C) ((C) == '/' || (C) == '\\') +#endif + +#ifndef DIRECTORY_SEPARATOR +# define DIRECTORY_SEPARATOR '/' +#endif + +#ifndef ISSLASH +# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR) +#endif + +#if HAVE_DECL_GETC_UNLOCKED +# undef getc +# define getc getc_unlocked +#endif + +/* The following static variable is declared 'volatile' to avoid a + possible multithread problem in the function get_charset_aliases. If we + are running in a threaded environment, and if two threads initialize + 'charset_aliases' simultaneously, both will produce the same value, + and everything will be ok if the two assignments to 'charset_aliases' + are atomic. But I don't know what will happen if the two assignments mix. */ +#if __STDC__ != 1 +# define volatile /* empty */ +#endif +/* Pointer to the contents of the charset.alias file, if it has already been + read, else NULL. Its format is: + ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0' */ +static const char * volatile charset_aliases; + +/* Return a pointer to the contents of the charset.alias file. */ +static const char * +get_charset_aliases (void) +{ + const char *cp; + + cp = charset_aliases; + if (cp == NULL) + { +#if !(defined DARWIN7 || defined VMS || defined WIN32_NATIVE || defined __CYGWIN__) + const char *dir; + const char *base = "charset.alias"; + char *file_name; + + /* Make it possible to override the charset.alias location. This is + necessary for running the testsuite before "make install". */ + dir = getenv ("CHARSETALIASDIR"); + if (dir == NULL || dir[0] == '\0') + dir = relocate (LIBDIR); + + /* Concatenate dir and base into freshly allocated file_name. */ + { + size_t dir_len = strlen (dir); + size_t base_len = strlen (base); + int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1])); + file_name = (char *) malloc (dir_len + add_slash + base_len + 1); + if (file_name != NULL) + { + memcpy (file_name, dir, dir_len); + if (add_slash) + file_name[dir_len] = DIRECTORY_SEPARATOR; + memcpy (file_name + dir_len + add_slash, base, base_len + 1); + } + } + + if (file_name == NULL) + /* Out of memory. Treat the file as empty. */ + cp = ""; + else + { + int fd; + + /* Open the file. Reject symbolic links on platforms that support + O_NOFOLLOW. This is a security feature. Without it, an attacker + could retrieve parts of the contents (namely, the tail of the + first line that starts with "* ") of an arbitrary file by placing + a symbolic link to that file under the name "charset.alias" in + some writable directory and defining the environment variable + CHARSETALIASDIR to point to that directory. */ + fd = open (file_name, + O_RDONLY | (HAVE_WORKING_O_NOFOLLOW ? O_NOFOLLOW : 0)); + if (fd < 0) + /* File not found. Treat it as empty. */ + cp = ""; + else + { + FILE *fp; + + fp = fdopen (fd, "r"); + if (fp == NULL) + { + /* Out of memory. Treat the file as empty. */ + close (fd); + cp = ""; + } + else + { + /* Parse the file's contents. */ + char *res_ptr = NULL; + size_t res_size = 0; + + for (;;) + { + int c; + char buf1[50+1]; + char buf2[50+1]; + size_t l1, l2; + char *old_res_ptr; + + c = getc (fp); + if (c == EOF) + break; + if (c == '\n' || c == ' ' || c == '\t') + continue; + if (c == '#') + { + /* Skip comment, to end of line. */ + do + c = getc (fp); + while (!(c == EOF || c == '\n')); + if (c == EOF) + break; + continue; + } + ungetc (c, fp); + if (fscanf (fp, "%50s %50s", buf1, buf2) < 2) + break; + l1 = strlen (buf1); + l2 = strlen (buf2); + old_res_ptr = res_ptr; + if (res_size == 0) + { + res_size = l1 + 1 + l2 + 1; + res_ptr = (char *) malloc (res_size + 1); + } + else + { + res_size += l1 + 1 + l2 + 1; + res_ptr = (char *) realloc (res_ptr, res_size + 1); + } + if (res_ptr == NULL) + { + /* Out of memory. */ + res_size = 0; + free (old_res_ptr); + break; + } + strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1); + strcpy (res_ptr + res_size - (l2 + 1), buf2); + } + fclose (fp); + if (res_size == 0) + cp = ""; + else + { + *(res_ptr + res_size) = '\0'; + cp = res_ptr; + } + } + } + + free (file_name); + } + +#else + +# if defined DARWIN7 + /* To avoid the trouble of installing a file that is shared by many + GNU packages -- many packaging systems have problems with this --, + simply inline the aliases here. */ + cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" + "ISO8859-2" "\0" "ISO-8859-2" "\0" + "ISO8859-4" "\0" "ISO-8859-4" "\0" + "ISO8859-5" "\0" "ISO-8859-5" "\0" + "ISO8859-7" "\0" "ISO-8859-7" "\0" + "ISO8859-9" "\0" "ISO-8859-9" "\0" + "ISO8859-13" "\0" "ISO-8859-13" "\0" + "ISO8859-15" "\0" "ISO-8859-15" "\0" + "KOI8-R" "\0" "KOI8-R" "\0" + "KOI8-U" "\0" "KOI8-U" "\0" + "CP866" "\0" "CP866" "\0" + "CP949" "\0" "CP949" "\0" + "CP1131" "\0" "CP1131" "\0" + "CP1251" "\0" "CP1251" "\0" + "eucCN" "\0" "GB2312" "\0" + "GB2312" "\0" "GB2312" "\0" + "eucJP" "\0" "EUC-JP" "\0" + "eucKR" "\0" "EUC-KR" "\0" + "Big5" "\0" "BIG5" "\0" + "Big5HKSCS" "\0" "BIG5-HKSCS" "\0" + "GBK" "\0" "GBK" "\0" + "GB18030" "\0" "GB18030" "\0" + "SJIS" "\0" "SHIFT_JIS" "\0" + "ARMSCII-8" "\0" "ARMSCII-8" "\0" + "PT154" "\0" "PT154" "\0" + /*"ISCII-DEV" "\0" "?" "\0"*/ + "*" "\0" "UTF-8" "\0"; +# endif + +# if defined VMS + /* To avoid the troubles of an extra file charset.alias_vms in the + sources of many GNU packages, simply inline the aliases here. */ + /* The list of encodings is taken from the OpenVMS 7.3-1 documentation + "Compaq C Run-Time Library Reference Manual for OpenVMS systems" + section 10.7 "Handling Different Character Sets". */ + cp = "ISO8859-1" "\0" "ISO-8859-1" "\0" + "ISO8859-2" "\0" "ISO-8859-2" "\0" + "ISO8859-5" "\0" "ISO-8859-5" "\0" + "ISO8859-7" "\0" "ISO-8859-7" "\0" + "ISO8859-8" "\0" "ISO-8859-8" "\0" + "ISO8859-9" "\0" "ISO-8859-9" "\0" + /* Japanese */ + "eucJP" "\0" "EUC-JP" "\0" + "SJIS" "\0" "SHIFT_JIS" "\0" + "DECKANJI" "\0" "DEC-KANJI" "\0" + "SDECKANJI" "\0" "EUC-JP" "\0" + /* Chinese */ + "eucTW" "\0" "EUC-TW" "\0" + "DECHANYU" "\0" "DEC-HANYU" "\0" + "DECHANZI" "\0" "GB2312" "\0" + /* Korean */ + "DECKOREAN" "\0" "EUC-KR" "\0"; +# endif + +# if defined WIN32_NATIVE || defined __CYGWIN__ + /* To avoid the troubles of installing a separate file in the same + directory as the DLL and of retrieving the DLL's directory at + runtime, simply inline the aliases here. */ + + cp = "CP936" "\0" "GBK" "\0" + "CP1361" "\0" "JOHAB" "\0" + "CP20127" "\0" "ASCII" "\0" + "CP20866" "\0" "KOI8-R" "\0" + "CP20936" "\0" "GB2312" "\0" + "CP21866" "\0" "KOI8-RU" "\0" + "CP28591" "\0" "ISO-8859-1" "\0" + "CP28592" "\0" "ISO-8859-2" "\0" + "CP28593" "\0" "ISO-8859-3" "\0" + "CP28594" "\0" "ISO-8859-4" "\0" + "CP28595" "\0" "ISO-8859-5" "\0" + "CP28596" "\0" "ISO-8859-6" "\0" + "CP28597" "\0" "ISO-8859-7" "\0" + "CP28598" "\0" "ISO-8859-8" "\0" + "CP28599" "\0" "ISO-8859-9" "\0" + "CP28605" "\0" "ISO-8859-15" "\0" + "CP38598" "\0" "ISO-8859-8" "\0" + "CP51932" "\0" "EUC-JP" "\0" + "CP51936" "\0" "GB2312" "\0" + "CP51949" "\0" "EUC-KR" "\0" + "CP51950" "\0" "EUC-TW" "\0" + "CP54936" "\0" "GB18030" "\0" + "CP65001" "\0" "UTF-8" "\0"; +# endif +#endif + + charset_aliases = cp; + } + + return cp; +} + +/* Determine the current locale's character encoding, and canonicalize it + into one of the canonical names listed in config.charset. + The result must not be freed; it is statically allocated. + If the canonical name cannot be determined, the result is a non-canonical + name. */ + +#ifdef STATIC +STATIC +#endif +const char * +locale_charset (void) +{ + const char *codeset; + const char *aliases; + +#if !(defined WIN32_NATIVE || defined OS2 || defined ANDROID || defined __ANDROID__) /* EDIT BY MR */ + +# if HAVE_LANGINFO_CODESET + + /* Most systems support nl_langinfo (CODESET) nowadays. */ + codeset = nl_langinfo (CODESET); + +# ifdef __CYGWIN__ + /* Cygwin < 1.7 does not have locales. nl_langinfo (CODESET) always + returns "US-ASCII". Return the suffix of the locale name from the + environment variables (if present) or the codepage as a number. */ + if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0) + { + const char *locale; + static char buf[2 + 10 + 1]; + + locale = getenv ("LC_ALL"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + } + if (locale != NULL && locale[0] != '\0') + { + /* If the locale name contains an encoding after the dot, return + it. */ + const char *dot = strchr (locale, '.'); + + if (dot != NULL) + { + const char *modifier; + + dot++; + /* Look for the possible @... trailer and remove it, if any. */ + modifier = strchr (dot, '@'); + if (modifier == NULL) + return dot; + if (modifier - dot < sizeof (buf)) + { + memcpy (buf, dot, modifier - dot); + buf [modifier - dot] = '\0'; + return buf; + } + } + } + + /* Woe32 has a function returning the locale's codepage as a number: + GetACP(). This encoding is used by Cygwin, unless the user has set + the environment variable CYGWIN=codepage:oem (which very few people + do). + Output directed to console windows needs to be converted (to + GetOEMCP() if the console is using a raster font, or to + GetConsoleOutputCP() if it is using a TrueType font). Cygwin does + this conversion transparently (see winsup/cygwin/fhandler_console.cc), + converting to GetConsoleOutputCP(). This leads to correct results, + except when SetConsoleOutputCP has been called and a raster font is + in use. */ + sprintf (buf, "CP%u", GetACP ()); + codeset = buf; + } +# endif + +# else + + /* On old systems which lack it, use setlocale or getenv. */ + const char *locale = NULL; + + /* But most old systems don't have a complete set of locales. Some + (like SunOS 4 or DJGPP) have only the C locale. Therefore we don't + use setlocale here; it would return "C" when it doesn't support the + locale name the user has set. */ +# if 0 + locale = setlocale (LC_CTYPE, NULL); +# endif + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_ALL"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + } + } + + /* On some old systems, one used to set locale = "iso8859_1". On others, + you set it to "language_COUNTRY.charset". In any case, we resolve it + through the charset.alias file. */ + codeset = locale; + +# endif + +#elif defined WIN32_NATIVE + + static char buf[2 + 10 + 1]; + + /* Woe32 has a function returning the locale's codepage as a number: + GetACP(). + When the output goes to a console window, it needs to be provided in + GetOEMCP() encoding if the console is using a raster font, or in + GetConsoleOutputCP() encoding if it is using a TrueType font. + But in GUI programs and for output sent to files and pipes, GetACP() + encoding is the best bet. */ + sprintf (buf, "CP%u", GetACP ()); + codeset = buf; + +#elif defined OS2 + + const char *locale; + static char buf[2 + 10 + 1]; + ULONG cp[3]; + ULONG cplen; + + /* Allow user to override the codeset, as set in the operating system, + with standard language environment variables. */ + locale = getenv ("LC_ALL"); + if (locale == NULL || locale[0] == '\0') + { + locale = getenv ("LC_CTYPE"); + if (locale == NULL || locale[0] == '\0') + locale = getenv ("LANG"); + } + if (locale != NULL && locale[0] != '\0') + { + /* If the locale name contains an encoding after the dot, return it. */ + const char *dot = strchr (locale, '.'); + + if (dot != NULL) + { + const char *modifier; + + dot++; + /* Look for the possible @... trailer and remove it, if any. */ + modifier = strchr (dot, '@'); + if (modifier == NULL) + return dot; + if (modifier - dot < sizeof (buf)) + { + memcpy (buf, dot, modifier - dot); + buf [modifier - dot] = '\0'; + return buf; + } + } + + /* Resolve through the charset.alias file. */ + codeset = locale; + } + else + { + /* OS/2 has a function returning the locale's codepage as a number. */ + if (DosQueryCp (sizeof (cp), cp, &cplen)) + codeset = ""; + else + { + sprintf (buf, "CP%u", cp[0]); + codeset = buf; + } + } + +#endif + + if (codeset == NULL) + /* The canonical name cannot be determined. */ + codeset = ""; + + /* Resolve alias. */ + for (aliases = get_charset_aliases (); + *aliases != '\0'; + aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1) + if (strcmp (codeset, aliases) == 0 + || (aliases[0] == '*' && aliases[1] == '\0')) + { + codeset = aliases + strlen (aliases) + 1; + break; + } + + /* Don't return an empty string. GNU libc and GNU libiconv interpret + the empty string as denoting "the locale's character encoding", + thus GNU libiconv would call this function a second time. */ + if (codeset[0] == '\0') + codeset = "ASCII"; + + return codeset; +} diff --git a/libs/openssl/Android.mk b/libs/openssl/Android.mk new file mode 100644 index 00000000..d2a5af57 --- /dev/null +++ b/libs/openssl/Android.mk @@ -0,0 +1,7 @@ +LOCAL_PATH := $(call my-dir) + +subdirs := $(addprefix $(LOCAL_PATH)/,$(addsuffix /Android.mk, \ + crypto \ + )) + +include $(subdirs) diff --git a/libs/openssl/Application.mk b/libs/openssl/Application.mk new file mode 100644 index 00000000..0460b334 --- /dev/null +++ b/libs/openssl/Application.mk @@ -0,0 +1,4 @@ +APP_PLATFORM := android-9 +APP_ABI := armeabi armeabi-v7a x86 +NDK_TOOLCHAIN_VERSION := 4.8 +APP_STL := gnustl_static \ No newline at end of file diff --git a/libs/openssl/CHANGES b/libs/openssl/CHANGES new file mode 100644 index 00000000..1c7a5edc --- /dev/null +++ b/libs/openssl/CHANGES @@ -0,0 +1,10737 @@ + + OpenSSL CHANGES + _______________ + + Changes between 1.0.1s and 1.0.1t [3 May 2016] + + *) Prevent padding oracle in AES-NI CBC MAC check + + A MITM attacker can use a padding oracle attack to decrypt traffic + when the connection uses an AES CBC cipher and the server support + AES-NI. + + This issue was introduced as part of the fix for Lucky 13 padding + attack (CVE-2013-0169). The padding check was rewritten to be in + constant time by making sure that always the same bytes are read and + compared against either the MAC or padding bytes. But it no longer + checked that there was enough data to have both the MAC and padding + bytes. + + This issue was reported by Juraj Somorovsky using TLS-Attacker. + (CVE-2016-2107) + [Kurt Roeckx] + + *) Fix EVP_EncodeUpdate overflow + + An overflow can occur in the EVP_EncodeUpdate() function which is used for + Base64 encoding of binary data. If an attacker is able to supply very large + amounts of input data then a length check can overflow resulting in a heap + corruption. + + Internally to OpenSSL the EVP_EncodeUpdate() function is primarly used by + the PEM_write_bio* family of functions. These are mainly used within the + OpenSSL command line applications, so any application which processes data + from an untrusted source and outputs it as a PEM file should be considered + vulnerable to this issue. User applications that call these APIs directly + with large amounts of untrusted data may also be vulnerable. + + This issue was reported by Guido Vranken. + (CVE-2016-2105) + [Matt Caswell] + + *) Fix EVP_EncryptUpdate overflow + + An overflow can occur in the EVP_EncryptUpdate() function. If an attacker + is able to supply very large amounts of input data after a previous call to + EVP_EncryptUpdate() with a partial block then a length check can overflow + resulting in a heap corruption. Following an analysis of all OpenSSL + internal usage of the EVP_EncryptUpdate() function all usage is one of two + forms. The first form is where the EVP_EncryptUpdate() call is known to be + the first called function after an EVP_EncryptInit(), and therefore that + specific call must be safe. The second form is where the length passed to + EVP_EncryptUpdate() can be seen from the code to be some small value and + therefore there is no possibility of an overflow. Since all instances are + one of these two forms, it is believed that there can be no overflows in + internal code due to this problem. It should be noted that + EVP_DecryptUpdate() can call EVP_EncryptUpdate() in certain code paths. + Also EVP_CipherUpdate() is a synonym for EVP_EncryptUpdate(). All instances + of these calls have also been analysed too and it is believed there are no + instances in internal usage where an overflow could occur. + + This issue was reported by Guido Vranken. + (CVE-2016-2106) + [Matt Caswell] + + *) Prevent ASN.1 BIO excessive memory allocation + + When ASN.1 data is read from a BIO using functions such as d2i_CMS_bio() + a short invalid encoding can casuse allocation of large amounts of memory + potentially consuming excessive resources or exhausting memory. + + Any application parsing untrusted data through d2i BIO functions is + affected. The memory based functions such as d2i_X509() are *not* affected. + Since the memory based functions are used by the TLS library, TLS + applications are not affected. + + This issue was reported by Brian Carpenter. + (CVE-2016-2109) + [Stephen Henson] + + *) EBCDIC overread + + ASN1 Strings that are over 1024 bytes can cause an overread in applications + using the X509_NAME_oneline() function on EBCDIC systems. This could result + in arbitrary stack data being returned in the buffer. + + This issue was reported by Guido Vranken. + (CVE-2016-2176) + [Matt Caswell] + + *) Modify behavior of ALPN to invoke callback after SNI/servername + callback, such that updates to the SSL_CTX affect ALPN. + [Todd Short] + + *) Remove LOW from the DEFAULT cipher list. This removes singles DES from the + default. + [Kurt Roeckx] + + *) Only remove the SSLv2 methods with the no-ssl2-method option. When the + methods are enabled and ssl2 is disabled the methods return NULL. + [Kurt Roeckx] + + Changes between 1.0.1r and 1.0.1s [1 Mar 2016] + + * Disable weak ciphers in SSLv3 and up in default builds of OpenSSL. + Builds that are not configured with "enable-weak-ssl-ciphers" will not + provide any "EXPORT" or "LOW" strength ciphers. + [Viktor Dukhovni] + + * Disable SSLv2 default build, default negotiation and weak ciphers. SSLv2 + is by default disabled at build-time. Builds that are not configured with + "enable-ssl2" will not support SSLv2. Even if "enable-ssl2" is used, + users who want to negotiate SSLv2 via the version-flexible SSLv23_method() + will need to explicitly call either of: + + SSL_CTX_clear_options(ctx, SSL_OP_NO_SSLv2); + or + SSL_clear_options(ssl, SSL_OP_NO_SSLv2); + + as appropriate. Even if either of those is used, or the application + explicitly uses the version-specific SSLv2_method() or its client and + server variants, SSLv2 ciphers vulnerable to exhaustive search key + recovery have been removed. Specifically, the SSLv2 40-bit EXPORT + ciphers, and SSLv2 56-bit DES are no longer available. + (CVE-2016-0800) + [Viktor Dukhovni] + + *) Fix a double-free in DSA code + + A double free bug was discovered when OpenSSL parses malformed DSA private + keys and could lead to a DoS attack or memory corruption for applications + that receive DSA private keys from untrusted sources. This scenario is + considered rare. + + This issue was reported to OpenSSL by Adam Langley(Google/BoringSSL) using + libFuzzer. + (CVE-2016-0705) + [Stephen Henson] + + *) Disable SRP fake user seed to address a server memory leak. + + Add a new method SRP_VBASE_get1_by_user that handles the seed properly. + + SRP_VBASE_get_by_user had inconsistent memory management behaviour. + In order to fix an unavoidable memory leak, SRP_VBASE_get_by_user + was changed to ignore the "fake user" SRP seed, even if the seed + is configured. + + Users should use SRP_VBASE_get1_by_user instead. Note that in + SRP_VBASE_get1_by_user, caller must free the returned value. Note + also that even though configuring the SRP seed attempts to hide + invalid usernames by continuing the handshake with fake + credentials, this behaviour is not constant time and no strong + guarantees are made that the handshake is indistinguishable from + that of a valid user. + (CVE-2016-0798) + [Emilia Käsper] + + *) Fix BN_hex2bn/BN_dec2bn NULL pointer deref/heap corruption + + In the BN_hex2bn function the number of hex digits is calculated using an + int value |i|. Later |bn_expand| is called with a value of |i * 4|. For + large values of |i| this can result in |bn_expand| not allocating any + memory because |i * 4| is negative. This can leave the internal BIGNUM data + field as NULL leading to a subsequent NULL ptr deref. For very large values + of |i|, the calculation |i * 4| could be a positive value smaller than |i|. + In this case memory is allocated to the internal BIGNUM data field, but it + is insufficiently sized leading to heap corruption. A similar issue exists + in BN_dec2bn. This could have security consequences if BN_hex2bn/BN_dec2bn + is ever called by user applications with very large untrusted hex/dec data. + This is anticipated to be a rare occurrence. + + All OpenSSL internal usage of these functions use data that is not expected + to be untrusted, e.g. config file data or application command line + arguments. If user developed applications generate config file data based + on untrusted data then it is possible that this could also lead to security + consequences. This is also anticipated to be rare. + + This issue was reported to OpenSSL by Guido Vranken. + (CVE-2016-0797) + [Matt Caswell] + + *) Fix memory issues in BIO_*printf functions + + The internal |fmtstr| function used in processing a "%s" format string in + the BIO_*printf functions could overflow while calculating the length of a + string and cause an OOB read when printing very long strings. + + Additionally the internal |doapr_outch| function can attempt to write to an + OOB memory location (at an offset from the NULL pointer) in the event of a + memory allocation failure. In 1.0.2 and below this could be caused where + the size of a buffer to be allocated is greater than INT_MAX. E.g. this + could be in processing a very long "%s" format string. Memory leaks can + also occur. + + The first issue may mask the second issue dependent on compiler behaviour. + These problems could enable attacks where large amounts of untrusted data + is passed to the BIO_*printf functions. If applications use these functions + in this way then they could be vulnerable. OpenSSL itself uses these + functions when printing out human-readable dumps of ASN.1 data. Therefore + applications that print this data could be vulnerable if the data is from + untrusted sources. OpenSSL command line applications could also be + vulnerable where they print out ASN.1 data, or if untrusted data is passed + as command line arguments. + + Libssl is not considered directly vulnerable. Additionally certificates etc + received via remote connections via libssl are also unlikely to be able to + trigger these issues because of message size limits enforced within libssl. + + This issue was reported to OpenSSL Guido Vranken. + (CVE-2016-0799) + [Matt Caswell] + + *) Side channel attack on modular exponentiation + + A side-channel attack was found which makes use of cache-bank conflicts on + the Intel Sandy-Bridge microarchitecture which could lead to the recovery + of RSA keys. The ability to exploit this issue is limited as it relies on + an attacker who has control of code in a thread running on the same + hyper-threaded core as the victim thread which is performing decryptions. + + This issue was reported to OpenSSL by Yuval Yarom, The University of + Adelaide and NICTA, Daniel Genkin, Technion and Tel Aviv University, and + Nadia Heninger, University of Pennsylvania with more information at + http://cachebleed.info. + (CVE-2016-0702) + [Andy Polyakov] + + *) Change the req app to generate a 2048-bit RSA/DSA key by default, + if no keysize is specified with default_bits. This fixes an + omission in an earlier change that changed all RSA/DSA key generation + apps to use 2048 bits by default. + [Emilia Käsper] + + Changes between 1.0.1q and 1.0.1r [28 Jan 2016] + + *) Protection for DH small subgroup attacks + + As a precautionary measure the SSL_OP_SINGLE_DH_USE option has been + switched on by default and cannot be disabled. This could have some + performance impact. + [Matt Caswell] + + *) SSLv2 doesn't block disabled ciphers + + A malicious client can negotiate SSLv2 ciphers that have been disabled on + the server and complete SSLv2 handshakes even if all SSLv2 ciphers have + been disabled, provided that the SSLv2 protocol was not also disabled via + SSL_OP_NO_SSLv2. + + This issue was reported to OpenSSL on 26th December 2015 by Nimrod Aviram + and Sebastian Schinzel. + (CVE-2015-3197) + [Viktor Dukhovni] + + *) Reject DH handshakes with parameters shorter than 1024 bits. + [Kurt Roeckx] + + Changes between 1.0.1p and 1.0.1q [3 Dec 2015] + + *) Certificate verify crash with missing PSS parameter + + The signature verification routines will crash with a NULL pointer + dereference if presented with an ASN.1 signature using the RSA PSS + algorithm and absent mask generation function parameter. Since these + routines are used to verify certificate signature algorithms this can be + used to crash any certificate verification operation and exploited in a + DoS attack. Any application which performs certificate verification is + vulnerable including OpenSSL clients and servers which enable client + authentication. + + This issue was reported to OpenSSL by Loïc Jonas Etienne (Qnective AG). + (CVE-2015-3194) + [Stephen Henson] + + *) X509_ATTRIBUTE memory leak + + When presented with a malformed X509_ATTRIBUTE structure OpenSSL will leak + memory. This structure is used by the PKCS#7 and CMS routines so any + application which reads PKCS#7 or CMS data from untrusted sources is + affected. SSL/TLS is not affected. + + This issue was reported to OpenSSL by Adam Langley (Google/BoringSSL) using + libFuzzer. + (CVE-2015-3195) + [Stephen Henson] + + *) Rewrite EVP_DecodeUpdate (base64 decoding) to fix several bugs. + This changes the decoding behaviour for some invalid messages, + though the change is mostly in the more lenient direction, and + legacy behaviour is preserved as much as possible. + [Emilia Käsper] + + *) In DSA_generate_parameters_ex, if the provided seed is too short, + use a random seed, as already documented. + [Rich Salz and Ismo Puustinen ] + + Changes between 1.0.1o and 1.0.1p [9 Jul 2015] + + *) Alternate chains certificate forgery + + During certificate verfification, OpenSSL will attempt to find an + alternative certificate chain if the first attempt to build such a chain + fails. An error in the implementation of this logic can mean that an + attacker could cause certain checks on untrusted certificates to be + bypassed, such as the CA flag, enabling them to use a valid leaf + certificate to act as a CA and "issue" an invalid certificate. + + This issue was reported to OpenSSL by Adam Langley/David Benjamin + (Google/BoringSSL). + (CVE-2015-1793) + [Matt Caswell] + + *) Race condition handling PSK identify hint + + If PSK identity hints are received by a multi-threaded client then + the values are wrongly updated in the parent SSL_CTX structure. This can + result in a race condition potentially leading to a double free of the + identify hint data. + (CVE-2015-3196) + [Stephen Henson] + + Changes between 1.0.1n and 1.0.1o [12 Jun 2015] + *) Fix HMAC ABI incompatibility. The previous version introduced an ABI + incompatibility in the handling of HMAC. The previous ABI has now been + restored. + + Changes between 1.0.1m and 1.0.1n [11 Jun 2015] + + *) Malformed ECParameters causes infinite loop + + When processing an ECParameters structure OpenSSL enters an infinite loop + if the curve specified is over a specially malformed binary polynomial + field. + + This can be used to perform denial of service against any + system which processes public keys, certificate requests or + certificates. This includes TLS clients and TLS servers with + client authentication enabled. + + This issue was reported to OpenSSL by Joseph Barr-Pixton. + (CVE-2015-1788) + [Andy Polyakov] + + *) Exploitable out-of-bounds read in X509_cmp_time + + X509_cmp_time does not properly check the length of the ASN1_TIME + string and can read a few bytes out of bounds. In addition, + X509_cmp_time accepts an arbitrary number of fractional seconds in the + time string. + + An attacker can use this to craft malformed certificates and CRLs of + various sizes and potentially cause a segmentation fault, resulting in + a DoS on applications that verify certificates or CRLs. TLS clients + that verify CRLs are affected. TLS clients and servers with client + authentication enabled may be affected if they use custom verification + callbacks. + + This issue was reported to OpenSSL by Robert Swiecki (Google), and + independently by Hanno Böck. + (CVE-2015-1789) + [Emilia Käsper] + + *) PKCS7 crash with missing EnvelopedContent + + The PKCS#7 parsing code does not handle missing inner EncryptedContent + correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs + with missing content and trigger a NULL pointer dereference on parsing. + + Applications that decrypt PKCS#7 data or otherwise parse PKCS#7 + structures from untrusted sources are affected. OpenSSL clients and + servers are not affected. + + This issue was reported to OpenSSL by Michal Zalewski (Google). + (CVE-2015-1790) + [Emilia Käsper] + + *) CMS verify infinite loop with unknown hash function + + When verifying a signedData message the CMS code can enter an infinite loop + if presented with an unknown hash function OID. This can be used to perform + denial of service against any system which verifies signedData messages using + the CMS code. + This issue was reported to OpenSSL by Johannes Bauer. + (CVE-2015-1792) + [Stephen Henson] + + *) Race condition handling NewSessionTicket + + If a NewSessionTicket is received by a multi-threaded client when attempting to + reuse a previous ticket then a race condition can occur potentially leading to + a double free of the ticket data. + (CVE-2015-1791) + [Matt Caswell] + + *) Reject DH handshakes with parameters shorter than 768 bits. + [Kurt Roeckx and Emilia Kasper] + + *) dhparam: generate 2048-bit parameters by default. + [Kurt Roeckx and Emilia Kasper] + + Changes between 1.0.1l and 1.0.1m [19 Mar 2015] + + *) Segmentation fault in ASN1_TYPE_cmp fix + + The function ASN1_TYPE_cmp will crash with an invalid read if an attempt is + made to compare ASN.1 boolean types. Since ASN1_TYPE_cmp is used to check + certificate signature algorithm consistency this can be used to crash any + certificate verification operation and exploited in a DoS attack. Any + application which performs certificate verification is vulnerable including + OpenSSL clients and servers which enable client authentication. + (CVE-2015-0286) + [Stephen Henson] + + *) ASN.1 structure reuse memory corruption fix + + Reusing a structure in ASN.1 parsing may allow an attacker to cause + memory corruption via an invalid write. Such reuse is and has been + strongly discouraged and is believed to be rare. + + Applications that parse structures containing CHOICE or ANY DEFINED BY + components may be affected. Certificate parsing (d2i_X509 and related + functions) are however not affected. OpenSSL clients and servers are + not affected. + (CVE-2015-0287) + [Stephen Henson] + + *) PKCS7 NULL pointer dereferences fix + + The PKCS#7 parsing code does not handle missing outer ContentInfo + correctly. An attacker can craft malformed ASN.1-encoded PKCS#7 blobs with + missing content and trigger a NULL pointer dereference on parsing. + + Applications that verify PKCS#7 signatures, decrypt PKCS#7 data or + otherwise parse PKCS#7 structures from untrusted sources are + affected. OpenSSL clients and servers are not affected. + + This issue was reported to OpenSSL by Michal Zalewski (Google). + (CVE-2015-0289) + [Emilia Käsper] + + *) DoS via reachable assert in SSLv2 servers fix + + A malicious client can trigger an OPENSSL_assert (i.e., an abort) in + servers that both support SSLv2 and enable export cipher suites by sending + a specially crafted SSLv2 CLIENT-MASTER-KEY message. + + This issue was discovered by Sean Burford (Google) and Emilia Käsper + (OpenSSL development team). + (CVE-2015-0293) + [Emilia Käsper] + + *) Use After Free following d2i_ECPrivatekey error fix + + A malformed EC private key file consumed via the d2i_ECPrivateKey function + could cause a use after free condition. This, in turn, could cause a double + free in several private key parsing functions (such as d2i_PrivateKey + or EVP_PKCS82PKEY) and could lead to a DoS attack or memory corruption + for applications that receive EC private keys from untrusted + sources. This scenario is considered rare. + + This issue was discovered by the BoringSSL project and fixed in their + commit 517073cd4b. + (CVE-2015-0209) + [Matt Caswell] + + *) X509_to_X509_REQ NULL pointer deref fix + + The function X509_to_X509_REQ will crash with a NULL pointer dereference if + the certificate key is invalid. This function is rarely used in practice. + + This issue was discovered by Brian Carpenter. + (CVE-2015-0288) + [Stephen Henson] + + *) Removed the export ciphers from the DEFAULT ciphers + [Kurt Roeckx] + + Changes between 1.0.1k and 1.0.1l [15 Jan 2015] + + *) Build fixes for the Windows and OpenVMS platforms + [Matt Caswell and Richard Levitte] + + Changes between 1.0.1j and 1.0.1k [8 Jan 2015] + + *) Fix DTLS segmentation fault in dtls1_get_record. A carefully crafted DTLS + message can cause a segmentation fault in OpenSSL due to a NULL pointer + dereference. This could lead to a Denial Of Service attack. Thanks to + Markus Stenberg of Cisco Systems, Inc. for reporting this issue. + (CVE-2014-3571) + [Steve Henson] + + *) Fix DTLS memory leak in dtls1_buffer_record. A memory leak can occur in the + dtls1_buffer_record function under certain conditions. In particular this + could occur if an attacker sent repeated DTLS records with the same + sequence number but for the next epoch. The memory leak could be exploited + by an attacker in a Denial of Service attack through memory exhaustion. + Thanks to Chris Mueller for reporting this issue. + (CVE-2015-0206) + [Matt Caswell] + + *) Fix issue where no-ssl3 configuration sets method to NULL. When openssl is + built with the no-ssl3 option and a SSL v3 ClientHello is received the ssl + method would be set to NULL which could later result in a NULL pointer + dereference. Thanks to Frank Schmirler for reporting this issue. + (CVE-2014-3569) + [Kurt Roeckx] + + *) Abort handshake if server key exchange message is omitted for ephemeral + ECDH ciphersuites. + + Thanks to Karthikeyan Bhargavan of the PROSECCO team at INRIA for + reporting this issue. + (CVE-2014-3572) + [Steve Henson] + + *) Remove non-export ephemeral RSA code on client and server. This code + violated the TLS standard by allowing the use of temporary RSA keys in + non-export ciphersuites and could be used by a server to effectively + downgrade the RSA key length used to a value smaller than the server + certificate. Thanks for Karthikeyan Bhargavan of the PROSECCO team at + INRIA or reporting this issue. + (CVE-2015-0204) + [Steve Henson] + + *) Fixed issue where DH client certificates are accepted without verification. + An OpenSSL server will accept a DH certificate for client authentication + without the certificate verify message. This effectively allows a client to + authenticate without the use of a private key. This only affects servers + which trust a client certificate authority which issues certificates + containing DH keys: these are extremely rare and hardly ever encountered. + Thanks for Karthikeyan Bhargavan of the PROSECCO team at INRIA or reporting + this issue. + (CVE-2015-0205) + [Steve Henson] + + *) Ensure that the session ID context of an SSL is updated when its + SSL_CTX is updated via SSL_set_SSL_CTX. + + The session ID context is typically set from the parent SSL_CTX, + and can vary with the CTX. + [Adam Langley] + + *) Fix various certificate fingerprint issues. + + By using non-DER or invalid encodings outside the signed portion of a + certificate the fingerprint can be changed without breaking the signature. + Although no details of the signed portion of the certificate can be changed + this can cause problems with some applications: e.g. those using the + certificate fingerprint for blacklists. + + 1. Reject signatures with non zero unused bits. + + If the BIT STRING containing the signature has non zero unused bits reject + the signature. All current signature algorithms require zero unused bits. + + 2. Check certificate algorithm consistency. + + Check the AlgorithmIdentifier inside TBS matches the one in the + certificate signature. NB: this will result in signature failure + errors for some broken certificates. + + Thanks to Konrad Kraszewski from Google for reporting this issue. + + 3. Check DSA/ECDSA signatures use DER. + + Reencode DSA/ECDSA signatures and compare with the original received + signature. Return an error if there is a mismatch. + + This will reject various cases including garbage after signature + (thanks to Antti Karjalainen and Tuomo Untinen from the Codenomicon CROSS + program for discovering this case) and use of BER or invalid ASN.1 INTEGERs + (negative or with leading zeroes). + + Further analysis was conducted and fixes were developed by Stephen Henson + of the OpenSSL core team. + + (CVE-2014-8275) + [Steve Henson] + + *) Correct Bignum squaring. Bignum squaring (BN_sqr) may produce incorrect + results on some platforms, including x86_64. This bug occurs at random + with a very low probability, and is not known to be exploitable in any + way, though its exact impact is difficult to determine. Thanks to Pieter + Wuille (Blockstream) who reported this issue and also suggested an initial + fix. Further analysis was conducted by the OpenSSL development team and + Adam Langley of Google. The final fix was developed by Andy Polyakov of + the OpenSSL core team. + (CVE-2014-3570) + [Andy Polyakov] + + *) Do not resume sessions on the server if the negotiated protocol + version does not match the session's version. Resuming with a different + version, while not strictly forbidden by the RFC, is of questionable + sanity and breaks all known clients. + [David Benjamin, Emilia Käsper] + + *) Tighten handling of the ChangeCipherSpec (CCS) message: reject + early CCS messages during renegotiation. (Note that because + renegotiation is encrypted, this early CCS was not exploitable.) + [Emilia Käsper] + + *) Tighten client-side session ticket handling during renegotiation: + ensure that the client only accepts a session ticket if the server sends + the extension anew in the ServerHello. Previously, a TLS client would + reuse the old extension state and thus accept a session ticket if one was + announced in the initial ServerHello. + + Similarly, ensure that the client requires a session ticket if one + was advertised in the ServerHello. Previously, a TLS client would + ignore a missing NewSessionTicket message. + [Emilia Käsper] + + Changes between 1.0.1i and 1.0.1j [15 Oct 2014] + + *) SRTP Memory Leak. + + A flaw in the DTLS SRTP extension parsing code allows an attacker, who + sends a carefully crafted handshake message, to cause OpenSSL to fail + to free up to 64k of memory causing a memory leak. This could be + exploited in a Denial Of Service attack. This issue affects OpenSSL + 1.0.1 server implementations for both SSL/TLS and DTLS regardless of + whether SRTP is used or configured. Implementations of OpenSSL that + have been compiled with OPENSSL_NO_SRTP defined are not affected. + + The fix was developed by the OpenSSL team. + (CVE-2014-3513) + [OpenSSL team] + + *) Session Ticket Memory Leak. + + When an OpenSSL SSL/TLS/DTLS server receives a session ticket the + integrity of that ticket is first verified. In the event of a session + ticket integrity check failing, OpenSSL will fail to free memory + causing a memory leak. By sending a large number of invalid session + tickets an attacker could exploit this issue in a Denial Of Service + attack. + (CVE-2014-3567) + [Steve Henson] + + *) Build option no-ssl3 is incomplete. + + When OpenSSL is configured with "no-ssl3" as a build option, servers + could accept and complete a SSL 3.0 handshake, and clients could be + configured to send them. + (CVE-2014-3568) + [Akamai and the OpenSSL team] + + *) Add support for TLS_FALLBACK_SCSV. + Client applications doing fallback retries should call + SSL_set_mode(s, SSL_MODE_SEND_FALLBACK_SCSV). + (CVE-2014-3566) + [Adam Langley, Bodo Moeller] + + *) Add additional DigestInfo checks. + + Reencode DigestInto in DER and check against the original when + verifying RSA signature: this will reject any improperly encoded + DigestInfo structures. + + Note: this is a precautionary measure and no attacks are currently known. + + [Steve Henson] + + Changes between 1.0.1h and 1.0.1i [6 Aug 2014] + + *) Fix SRP buffer overrun vulnerability. Invalid parameters passed to the + SRP code can be overrun an internal buffer. Add sanity check that + g, A, B < N to SRP code. + + Thanks to Sean Devlin and Watson Ladd of Cryptography Services, NCC + Group for discovering this issue. + (CVE-2014-3512) + [Steve Henson] + + *) A flaw in the OpenSSL SSL/TLS server code causes the server to negotiate + TLS 1.0 instead of higher protocol versions when the ClientHello message + is badly fragmented. This allows a man-in-the-middle attacker to force a + downgrade to TLS 1.0 even if both the server and the client support a + higher protocol version, by modifying the client's TLS records. + + Thanks to David Benjamin and Adam Langley (Google) for discovering and + researching this issue. + (CVE-2014-3511) + [David Benjamin] + + *) OpenSSL DTLS clients enabling anonymous (EC)DH ciphersuites are subject + to a denial of service attack. A malicious server can crash the client + with a null pointer dereference (read) by specifying an anonymous (EC)DH + ciphersuite and sending carefully crafted handshake messages. + + Thanks to Felix Gröbert (Google) for discovering and researching this + issue. + (CVE-2014-3510) + [Emilia Käsper] + + *) By sending carefully crafted DTLS packets an attacker could cause openssl + to leak memory. This can be exploited through a Denial of Service attack. + Thanks to Adam Langley for discovering and researching this issue. + (CVE-2014-3507) + [Adam Langley] + + *) An attacker can force openssl to consume large amounts of memory whilst + processing DTLS handshake messages. This can be exploited through a + Denial of Service attack. + Thanks to Adam Langley for discovering and researching this issue. + (CVE-2014-3506) + [Adam Langley] + + *) An attacker can force an error condition which causes openssl to crash + whilst processing DTLS packets due to memory being freed twice. This + can be exploited through a Denial of Service attack. + Thanks to Adam Langley and Wan-Teh Chang for discovering and researching + this issue. + (CVE-2014-3505) + [Adam Langley] + + *) If a multithreaded client connects to a malicious server using a resumed + session and the server sends an ec point format extension it could write + up to 255 bytes to freed memory. + + Thanks to Gabor Tyukasz (LogMeIn Inc) for discovering and researching this + issue. + (CVE-2014-3509) + [Gabor Tyukasz] + + *) A malicious server can crash an OpenSSL client with a null pointer + dereference (read) by specifying an SRP ciphersuite even though it was not + properly negotiated with the client. This can be exploited through a + Denial of Service attack. + + Thanks to Joonas Kuorilehto and Riku Hietamäki (Codenomicon) for + discovering and researching this issue. + (CVE-2014-5139) + [Steve Henson] + + *) A flaw in OBJ_obj2txt may cause pretty printing functions such as + X509_name_oneline, X509_name_print_ex et al. to leak some information + from the stack. Applications may be affected if they echo pretty printing + output to the attacker. + + Thanks to Ivan Fratric (Google) for discovering this issue. + (CVE-2014-3508) + [Emilia Käsper, and Steve Henson] + + *) Fix ec_GFp_simple_points_make_affine (thus, EC_POINTs_mul etc.) + for corner cases. (Certain input points at infinity could lead to + bogus results, with non-infinity inputs mapped to infinity too.) + [Bodo Moeller] + + Changes between 1.0.1g and 1.0.1h [5 Jun 2014] + + *) Fix for SSL/TLS MITM flaw. An attacker using a carefully crafted + handshake can force the use of weak keying material in OpenSSL + SSL/TLS clients and servers. + + Thanks to KIKUCHI Masashi (Lepidum Co. Ltd.) for discovering and + researching this issue. (CVE-2014-0224) + [KIKUCHI Masashi, Steve Henson] + + *) Fix DTLS recursion flaw. By sending an invalid DTLS handshake to an + OpenSSL DTLS client the code can be made to recurse eventually crashing + in a DoS attack. + + Thanks to Imre Rad (Search-Lab Ltd.) for discovering this issue. + (CVE-2014-0221) + [Imre Rad, Steve Henson] + + *) Fix DTLS invalid fragment vulnerability. A buffer overrun attack can + be triggered by sending invalid DTLS fragments to an OpenSSL DTLS + client or server. This is potentially exploitable to run arbitrary + code on a vulnerable client or server. + + Thanks to Jüri Aedla for reporting this issue. (CVE-2014-0195) + [Jüri Aedla, Steve Henson] + + *) Fix bug in TLS code where clients enable anonymous ECDH ciphersuites + are subject to a denial of service attack. + + Thanks to Felix Gröbert and Ivan Fratric at Google for discovering + this issue. (CVE-2014-3470) + [Felix Gröbert, Ivan Fratric, Steve Henson] + + *) Harmonize version and its documentation. -f flag is used to display + compilation flags. + [mancha ] + + *) Fix eckey_priv_encode so it immediately returns an error upon a failure + in i2d_ECPrivateKey. + [mancha ] + + *) Fix some double frees. These are not thought to be exploitable. + [mancha ] + + Changes between 1.0.1f and 1.0.1g [7 Apr 2014] + + *) A missing bounds check in the handling of the TLS heartbeat extension + can be used to reveal up to 64k of memory to a connected client or + server. + + Thanks for Neel Mehta of Google Security for discovering this bug and to + Adam Langley and Bodo Moeller for + preparing the fix (CVE-2014-0160) + [Adam Langley, Bodo Moeller] + + *) Fix for the attack described in the paper "Recovering OpenSSL + ECDSA Nonces Using the FLUSH+RELOAD Cache Side-channel Attack" + by Yuval Yarom and Naomi Benger. Details can be obtained from: + http://eprint.iacr.org/2014/140 + + Thanks to Yuval Yarom and Naomi Benger for discovering this + flaw and to Yuval Yarom for supplying a fix (CVE-2014-0076) + [Yuval Yarom and Naomi Benger] + + *) TLS pad extension: draft-agl-tls-padding-03 + + Workaround for the "TLS hang bug" (see FAQ and PR#2771): if the + TLS client Hello record length value would otherwise be > 255 and + less that 512 pad with a dummy extension containing zeroes so it + is at least 512 bytes long. + + [Adam Langley, Steve Henson] + + Changes between 1.0.1e and 1.0.1f [6 Jan 2014] + + *) Fix for TLS record tampering bug. A carefully crafted invalid + handshake could crash OpenSSL with a NULL pointer exception. + Thanks to Anton Johansson for reporting this issues. + (CVE-2013-4353) + + *) Keep original DTLS digest and encryption contexts in retransmission + structures so we can use the previous session parameters if they need + to be resent. (CVE-2013-6450) + [Steve Henson] + + *) Add option SSL_OP_SAFARI_ECDHE_ECDSA_BUG (part of SSL_OP_ALL) which + avoids preferring ECDHE-ECDSA ciphers when the client appears to be + Safari on OS X. Safari on OS X 10.8..10.8.3 advertises support for + several ECDHE-ECDSA ciphers, but fails to negotiate them. The bug + is fixed in OS X 10.8.4, but Apple have ruled out both hot fixing + 10.8..10.8.3 and forcing users to upgrade to 10.8.4 or newer. + [Rob Stradling, Adam Langley] + + Changes between 1.0.1d and 1.0.1e [11 Feb 2013] + + *) Correct fix for CVE-2013-0169. The original didn't work on AES-NI + supporting platforms or when small records were transferred. + [Andy Polyakov, Steve Henson] + + Changes between 1.0.1c and 1.0.1d [5 Feb 2013] + + *) Make the decoding of SSLv3, TLS and DTLS CBC records constant time. + + This addresses the flaw in CBC record processing discovered by + Nadhem Alfardan and Kenny Paterson. Details of this attack can be found + at: http://www.isg.rhul.ac.uk/tls/ + + Thanks go to Nadhem Alfardan and Kenny Paterson of the Information + Security Group at Royal Holloway, University of London + (www.isg.rhul.ac.uk) for discovering this flaw and Adam Langley and + Emilia Käsper for the initial patch. + (CVE-2013-0169) + [Emilia Käsper, Adam Langley, Ben Laurie, Andy Polyakov, Steve Henson] + + *) Fix flaw in AESNI handling of TLS 1.2 and 1.1 records for CBC mode + ciphersuites which can be exploited in a denial of service attack. + Thanks go to and to Adam Langley for discovering + and detecting this bug and to Wolfgang Ettlinger + for independently discovering this issue. + (CVE-2012-2686) + [Adam Langley] + + *) Return an error when checking OCSP signatures when key is NULL. + This fixes a DoS attack. (CVE-2013-0166) + [Steve Henson] + + *) Make openssl verify return errors. + [Chris Palmer and Ben Laurie] + + *) Call OCSP Stapling callback after ciphersuite has been chosen, so + the right response is stapled. Also change SSL_get_certificate() + so it returns the certificate actually sent. + See http://rt.openssl.org/Ticket/Display.html?id=2836. + [Rob Stradling ] + + *) Fix possible deadlock when decoding public keys. + [Steve Henson] + + *) Don't use TLS 1.0 record version number in initial client hello + if renegotiating. + [Steve Henson] + + Changes between 1.0.1b and 1.0.1c [10 May 2012] + + *) Sanity check record length before skipping explicit IV in TLS + 1.2, 1.1 and DTLS to fix DoS attack. + + Thanks to Codenomicon for discovering this issue using Fuzz-o-Matic + fuzzing as a service testing platform. + (CVE-2012-2333) + [Steve Henson] + + *) Initialise tkeylen properly when encrypting CMS messages. + Thanks to Solar Designer of Openwall for reporting this issue. + [Steve Henson] + + *) In FIPS mode don't try to use composite ciphers as they are not + approved. + [Steve Henson] + + Changes between 1.0.1a and 1.0.1b [26 Apr 2012] + + *) OpenSSL 1.0.0 sets SSL_OP_ALL to 0x80000FFFL and OpenSSL 1.0.1 and + 1.0.1a set SSL_OP_NO_TLSv1_1 to 0x00000400L which would unfortunately + mean any application compiled against OpenSSL 1.0.0 headers setting + SSL_OP_ALL would also set SSL_OP_NO_TLSv1_1, unintentionally disablng + TLS 1.1 also. Fix this by changing the value of SSL_OP_NO_TLSv1_1 to + 0x10000000L Any application which was previously compiled against + OpenSSL 1.0.1 or 1.0.1a headers and which cares about SSL_OP_NO_TLSv1_1 + will need to be recompiled as a result. Letting be results in + inability to disable specifically TLS 1.1 and in client context, + in unlike event, limit maximum offered version to TLS 1.0 [see below]. + [Steve Henson] + + *) In order to ensure interoperabilty SSL_OP_NO_protocolX does not + disable just protocol X, but all protocols above X *if* there are + protocols *below* X still enabled. In more practical terms it means + that if application wants to disable TLS1.0 in favor of TLS1.1 and + above, it's not sufficient to pass SSL_OP_NO_TLSv1, one has to pass + SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. This applies to + client side. + [Andy Polyakov] + + Changes between 1.0.1 and 1.0.1a [19 Apr 2012] + + *) Check for potentially exploitable overflows in asn1_d2i_read_bio + BUF_mem_grow and BUF_mem_grow_clean. Refuse attempts to shrink buffer + in CRYPTO_realloc_clean. + + Thanks to Tavis Ormandy, Google Security Team, for discovering this + issue and to Adam Langley for fixing it. + (CVE-2012-2110) + [Adam Langley (Google), Tavis Ormandy, Google Security Team] + + *) Don't allow TLS 1.2 SHA-256 ciphersuites in TLS 1.0, 1.1 connections. + [Adam Langley] + + *) Workarounds for some broken servers that "hang" if a client hello + record length exceeds 255 bytes. + + 1. Do not use record version number > TLS 1.0 in initial client + hello: some (but not all) hanging servers will now work. + 2. If we set OPENSSL_MAX_TLS1_2_CIPHER_LENGTH this will truncate + the number of ciphers sent in the client hello. This should be + set to an even number, such as 50, for example by passing: + -DOPENSSL_MAX_TLS1_2_CIPHER_LENGTH=50 to config or Configure. + Most broken servers should now work. + 3. If all else fails setting OPENSSL_NO_TLS1_2_CLIENT will disable + TLS 1.2 client support entirely. + [Steve Henson] + + *) Fix SEGV in Vector Permutation AES module observed in OpenSSH. + [Andy Polyakov] + + Changes between 1.0.0h and 1.0.1 [14 Mar 2012] + + *) Add compatibility with old MDC2 signatures which use an ASN1 OCTET + STRING form instead of a DigestInfo. + [Steve Henson] + + *) The format used for MDC2 RSA signatures is inconsistent between EVP + and the RSA_sign/RSA_verify functions. This was made more apparent when + OpenSSL used RSA_sign/RSA_verify for some RSA signatures in particular + those which went through EVP_PKEY_METHOD in 1.0.0 and later. Detect + the correct format in RSA_verify so both forms transparently work. + [Steve Henson] + + *) Some servers which support TLS 1.0 can choke if we initially indicate + support for TLS 1.2 and later renegotiate using TLS 1.0 in the RSA + encrypted premaster secret. As a workaround use the maximum pemitted + client version in client hello, this should keep such servers happy + and still work with previous versions of OpenSSL. + [Steve Henson] + + *) Add support for TLS/DTLS heartbeats. + [Robin Seggelmann ] + + *) Add support for SCTP. + [Robin Seggelmann ] + + *) Improved PRNG seeding for VOS. + [Paul Green ] + + *) Extensive assembler packs updates, most notably: + + - x86[_64]: AES-NI, PCLMULQDQ, RDRAND support; + - x86[_64]: SSSE3 support (SHA1, vector-permutation AES); + - x86_64: bit-sliced AES implementation; + - ARM: NEON support, contemporary platforms optimizations; + - s390x: z196 support; + - *: GHASH and GF(2^m) multiplication implementations; + + [Andy Polyakov] + + *) Make TLS-SRP code conformant with RFC 5054 API cleanup + (removal of unnecessary code) + [Peter Sylvester ] + + *) Add TLS key material exporter from RFC 5705. + [Eric Rescorla] + + *) Add DTLS-SRTP negotiation from RFC 5764. + [Eric Rescorla] + + *) Add Next Protocol Negotiation, + http://tools.ietf.org/html/draft-agl-tls-nextprotoneg-00. Can be + disabled with a no-npn flag to config or Configure. Code donated + by Google. + [Adam Langley and Ben Laurie] + + *) Add optional 64-bit optimized implementations of elliptic curves NIST-P224, + NIST-P256, NIST-P521, with constant-time single point multiplication on + typical inputs. Compiler support for the nonstandard type __uint128_t is + required to use this (present in gcc 4.4 and later, for 64-bit builds). + Code made available under Apache License version 2.0. + + Specify "enable-ec_nistp_64_gcc_128" on the Configure (or config) command + line to include this in your build of OpenSSL, and run "make depend" (or + "make update"). This enables the following EC_METHODs: + + EC_GFp_nistp224_method() + EC_GFp_nistp256_method() + EC_GFp_nistp521_method() + + EC_GROUP_new_by_curve_name() will automatically use these (while + EC_GROUP_new_curve_GFp() currently prefers the more flexible + implementations). + [Emilia Käsper, Adam Langley, Bodo Moeller (Google)] + + *) Use type ossl_ssize_t instad of ssize_t which isn't available on + all platforms. Move ssize_t definition from e_os.h to the public + header file e_os2.h as it now appears in public header file cms.h + [Steve Henson] + + *) New -sigopt option to the ca, req and x509 utilities. Additional + signature parameters can be passed using this option and in + particular PSS. + [Steve Henson] + + *) Add RSA PSS signing function. This will generate and set the + appropriate AlgorithmIdentifiers for PSS based on those in the + corresponding EVP_MD_CTX structure. No application support yet. + [Steve Henson] + + *) Support for companion algorithm specific ASN1 signing routines. + New function ASN1_item_sign_ctx() signs a pre-initialised + EVP_MD_CTX structure and sets AlgorithmIdentifiers based on + the appropriate parameters. + [Steve Henson] + + *) Add new algorithm specific ASN1 verification initialisation function + to EVP_PKEY_ASN1_METHOD: this is not in EVP_PKEY_METHOD since the ASN1 + handling will be the same no matter what EVP_PKEY_METHOD is used. + Add a PSS handler to support verification of PSS signatures: checked + against a number of sample certificates. + [Steve Henson] + + *) Add signature printing for PSS. Add PSS OIDs. + [Steve Henson, Martin Kaiser ] + + *) Add algorithm specific signature printing. An individual ASN1 method + can now print out signatures instead of the standard hex dump. + + More complex signatures (e.g. PSS) can print out more meaningful + information. Include DSA version that prints out the signature + parameters r, s. + [Steve Henson] + + *) Password based recipient info support for CMS library: implementing + RFC3211. + [Steve Henson] + + *) Split password based encryption into PBES2 and PBKDF2 functions. This + neatly separates the code into cipher and PBE sections and is required + for some algorithms that split PBES2 into separate pieces (such as + password based CMS). + [Steve Henson] + + *) Session-handling fixes: + - Fix handling of connections that are resuming with a session ID, + but also support Session Tickets. + - Fix a bug that suppressed issuing of a new ticket if the client + presented a ticket with an expired session. + - Try to set the ticket lifetime hint to something reasonable. + - Make tickets shorter by excluding irrelevant information. + - On the client side, don't ignore renewed tickets. + [Adam Langley, Bodo Moeller (Google)] + + *) Fix PSK session representation. + [Bodo Moeller] + + *) Add RC4-MD5 and AESNI-SHA1 "stitched" implementations. + + This work was sponsored by Intel. + [Andy Polyakov] + + *) Add GCM support to TLS library. Some custom code is needed to split + the IV between the fixed (from PRF) and explicit (from TLS record) + portions. This adds all GCM ciphersuites supported by RFC5288 and + RFC5289. Generalise some AES* cipherstrings to inlclude GCM and + add a special AESGCM string for GCM only. + [Steve Henson] + + *) Expand range of ctrls for AES GCM. Permit setting invocation + field on decrypt and retrieval of invocation field only on encrypt. + [Steve Henson] + + *) Add HMAC ECC ciphersuites from RFC5289. Include SHA384 PRF support. + As required by RFC5289 these ciphersuites cannot be used if for + versions of TLS earlier than 1.2. + [Steve Henson] + + *) For FIPS capable OpenSSL interpret a NULL default public key method + as unset and return the appopriate default but do *not* set the default. + This means we can return the appopriate method in applications that + swicth between FIPS and non-FIPS modes. + [Steve Henson] + + *) Redirect HMAC and CMAC operations to FIPS module in FIPS mode. If an + ENGINE is used then we cannot handle that in the FIPS module so we + keep original code iff non-FIPS operations are allowed. + [Steve Henson] + + *) Add -attime option to openssl utilities. + [Peter Eckersley , Ben Laurie and Steve Henson] + + *) Redirect DSA and DH operations to FIPS module in FIPS mode. + [Steve Henson] + + *) Redirect ECDSA and ECDH operations to FIPS module in FIPS mode. Also use + FIPS EC methods unconditionally for now. + [Steve Henson] + + *) New build option no-ec2m to disable characteristic 2 code. + [Steve Henson] + + *) Backport libcrypto audit of return value checking from 1.1.0-dev; not + all cases can be covered as some introduce binary incompatibilities. + [Steve Henson] + + *) Redirect RSA operations to FIPS module including keygen, + encrypt, decrypt, sign and verify. Block use of non FIPS RSA methods. + [Steve Henson] + + *) Add similar low level API blocking to ciphers. + [Steve Henson] + + *) Low level digest APIs are not approved in FIPS mode: any attempt + to use these will cause a fatal error. Applications that *really* want + to use them can use the private_* version instead. + [Steve Henson] + + *) Redirect cipher operations to FIPS module for FIPS builds. + [Steve Henson] + + *) Redirect digest operations to FIPS module for FIPS builds. + [Steve Henson] + + *) Update build system to add "fips" flag which will link in fipscanister.o + for static and shared library builds embedding a signature if needed. + [Steve Henson] + + *) Output TLS supported curves in preference order instead of numerical + order. This is currently hardcoded for the highest order curves first. + This should be configurable so applications can judge speed vs strength. + [Steve Henson] + + *) Add TLS v1.2 server support for client authentication. + [Steve Henson] + + *) Add support for FIPS mode in ssl library: disable SSLv3, non-FIPS ciphers + and enable MD5. + [Steve Henson] + + *) Functions FIPS_mode_set() and FIPS_mode() which call the underlying + FIPS modules versions. + [Steve Henson] + + *) Add TLS v1.2 client side support for client authentication. Keep cache + of handshake records longer as we don't know the hash algorithm to use + until after the certificate request message is received. + [Steve Henson] + + *) Initial TLS v1.2 client support. Add a default signature algorithms + extension including all the algorithms we support. Parse new signature + format in client key exchange. Relax some ECC signing restrictions for + TLS v1.2 as indicated in RFC5246. + [Steve Henson] + + *) Add server support for TLS v1.2 signature algorithms extension. Switch + to new signature format when needed using client digest preference. + All server ciphersuites should now work correctly in TLS v1.2. No client + support yet and no support for client certificates. + [Steve Henson] + + *) Initial TLS v1.2 support. Add new SHA256 digest to ssl code, switch + to SHA256 for PRF when using TLS v1.2 and later. Add new SHA256 based + ciphersuites. At present only RSA key exchange ciphersuites work with + TLS v1.2. Add new option for TLS v1.2 replacing the old and obsolete + SSL_OP_PKCS1_CHECK flags with SSL_OP_NO_TLSv1_2. New TLSv1.2 methods + and version checking. + [Steve Henson] + + *) New option OPENSSL_NO_SSL_INTERN. If an application can be compiled + with this defined it will not be affected by any changes to ssl internal + structures. Add several utility functions to allow openssl application + to work with OPENSSL_NO_SSL_INTERN defined. + [Steve Henson] + + *) Add SRP support. + [Tom Wu and Ben Laurie] + + *) Add functions to copy EVP_PKEY_METHOD and retrieve flags and id. + [Steve Henson] + + *) Permit abbreviated handshakes when renegotiating using the function + SSL_renegotiate_abbreviated(). + [Robin Seggelmann ] + + *) Add call to ENGINE_register_all_complete() to + ENGINE_load_builtin_engines(), so some implementations get used + automatically instead of needing explicit application support. + [Steve Henson] + + *) Add support for TLS key exporter as described in RFC5705. + [Robin Seggelmann , Steve Henson] + + *) Initial TLSv1.1 support. Since TLSv1.1 is very similar to TLS v1.0 only + a few changes are required: + + Add SSL_OP_NO_TLSv1_1 flag. + Add TLSv1_1 methods. + Update version checking logic to handle version 1.1. + Add explicit IV handling (ported from DTLS code). + Add command line options to s_client/s_server. + [Steve Henson] + + Changes between 1.0.0g and 1.0.0h [12 Mar 2012] + + *) Fix MMA (Bleichenbacher's attack on PKCS #1 v1.5 RSA padding) weakness + in CMS and PKCS7 code. When RSA decryption fails use a random key for + content decryption and always return the same error. Note: this attack + needs on average 2^20 messages so it only affects automated senders. The + old behaviour can be reenabled in the CMS code by setting the + CMS_DEBUG_DECRYPT flag: this is useful for debugging and testing where + an MMA defence is not necessary. + Thanks to Ivan Nestlerode for discovering + this issue. (CVE-2012-0884) + [Steve Henson] + + *) Fix CVE-2011-4619: make sure we really are receiving a + client hello before rejecting multiple SGC restarts. Thanks to + Ivan Nestlerode for discovering this bug. + [Steve Henson] + + Changes between 1.0.0f and 1.0.0g [18 Jan 2012] + + *) Fix for DTLS DoS issue introduced by fix for CVE-2011-4109. + Thanks to Antonio Martin, Enterprise Secure Access Research and + Development, Cisco Systems, Inc. for discovering this bug and + preparing a fix. (CVE-2012-0050) + [Antonio Martin] + + Changes between 1.0.0e and 1.0.0f [4 Jan 2012] + + *) Nadhem Alfardan and Kenny Paterson have discovered an extension + of the Vaudenay padding oracle attack on CBC mode encryption + which enables an efficient plaintext recovery attack against + the OpenSSL implementation of DTLS. Their attack exploits timing + differences arising during decryption processing. A research + paper describing this attack can be found at: + http://www.isg.rhul.ac.uk/~kp/dtls.pdf + Thanks go to Nadhem Alfardan and Kenny Paterson of the Information + Security Group at Royal Holloway, University of London + (www.isg.rhul.ac.uk) for discovering this flaw and to Robin Seggelmann + and Michael Tuexen + for preparing the fix. (CVE-2011-4108) + [Robin Seggelmann, Michael Tuexen] + + *) Clear bytes used for block padding of SSL 3.0 records. + (CVE-2011-4576) + [Adam Langley (Google)] + + *) Only allow one SGC handshake restart for SSL/TLS. Thanks to George + Kadianakis for discovering this issue and + Adam Langley for preparing the fix. (CVE-2011-4619) + [Adam Langley (Google)] + + *) Check parameters are not NULL in GOST ENGINE. (CVE-2012-0027) + [Andrey Kulikov ] + + *) Prevent malformed RFC3779 data triggering an assertion failure. + Thanks to Andrew Chi, BBN Technologies, for discovering the flaw + and Rob Austein for fixing it. (CVE-2011-4577) + [Rob Austein ] + + *) Improved PRNG seeding for VOS. + [Paul Green ] + + *) Fix ssl_ciph.c set-up race. + [Adam Langley (Google)] + + *) Fix spurious failures in ecdsatest.c. + [Emilia Käsper (Google)] + + *) Fix the BIO_f_buffer() implementation (which was mixing different + interpretations of the '..._len' fields). + [Adam Langley (Google)] + + *) Fix handling of BN_BLINDING: now BN_BLINDING_invert_ex (rather than + BN_BLINDING_invert_ex) calls BN_BLINDING_update, ensuring that concurrent + threads won't reuse the same blinding coefficients. + + This also avoids the need to obtain the CRYPTO_LOCK_RSA_BLINDING + lock to call BN_BLINDING_invert_ex, and avoids one use of + BN_BLINDING_update for each BN_BLINDING structure (previously, + the last update always remained unused). + [Emilia Käsper (Google)] + + *) In ssl3_clear, preserve s3->init_extra along with s3->rbuf. + [Bob Buckholz (Google)] + + Changes between 1.0.0d and 1.0.0e [6 Sep 2011] + + *) Fix bug where CRLs with nextUpdate in the past are sometimes accepted + by initialising X509_STORE_CTX properly. (CVE-2011-3207) + [Kaspar Brand ] + + *) Fix SSL memory handling for (EC)DH ciphersuites, in particular + for multi-threaded use of ECDH. (CVE-2011-3210) + [Adam Langley (Google)] + + *) Fix x509_name_ex_d2i memory leak on bad inputs. + [Bodo Moeller] + + *) Remove hard coded ecdsaWithSHA1 signature tests in ssl code and check + signature public key algorithm by using OID xref utilities instead. + Before this you could only use some ECC ciphersuites with SHA1 only. + [Steve Henson] + + *) Add protection against ECDSA timing attacks as mentioned in the paper + by Billy Bob Brumley and Nicola Tuveri, see: + + http://eprint.iacr.org/2011/232.pdf + + [Billy Bob Brumley and Nicola Tuveri] + + Changes between 1.0.0c and 1.0.0d [8 Feb 2011] + + *) Fix parsing of OCSP stapling ClientHello extension. CVE-2011-0014 + [Neel Mehta, Adam Langley, Bodo Moeller (Google)] + + *) Fix bug in string printing code: if *any* escaping is enabled we must + escape the escape character (backslash) or the resulting string is + ambiguous. + [Steve Henson] + + Changes between 1.0.0b and 1.0.0c [2 Dec 2010] + + *) Disable code workaround for ancient and obsolete Netscape browsers + and servers: an attacker can use it in a ciphersuite downgrade attack. + Thanks to Martin Rex for discovering this bug. CVE-2010-4180 + [Steve Henson] + + *) Fixed J-PAKE implementation error, originally discovered by + Sebastien Martini, further info and confirmation from Stefan + Arentz and Feng Hao. Note that this fix is a security fix. CVE-2010-4252 + [Ben Laurie] + + Changes between 1.0.0a and 1.0.0b [16 Nov 2010] + + *) Fix extension code to avoid race conditions which can result in a buffer + overrun vulnerability: resumed sessions must not be modified as they can + be shared by multiple threads. CVE-2010-3864 + [Steve Henson] + + *) Fix WIN32 build system to correctly link an ENGINE directory into + a DLL. + [Steve Henson] + + Changes between 1.0.0 and 1.0.0a [01 Jun 2010] + + *) Check return value of int_rsa_verify in pkey_rsa_verifyrecover + (CVE-2010-1633) + [Steve Henson, Peter-Michael Hager ] + + Changes between 0.9.8n and 1.0.0 [29 Mar 2010] + + *) Add "missing" function EVP_CIPHER_CTX_copy(). This copies a cipher + context. The operation can be customised via the ctrl mechanism in + case ENGINEs want to include additional functionality. + [Steve Henson] + + *) Tolerate yet another broken PKCS#8 key format: private key value negative. + [Steve Henson] + + *) Add new -subject_hash_old and -issuer_hash_old options to x509 utility to + output hashes compatible with older versions of OpenSSL. + [Willy Weisz ] + + *) Fix compression algorithm handling: if resuming a session use the + compression algorithm of the resumed session instead of determining + it from client hello again. Don't allow server to change algorithm. + [Steve Henson] + + *) Add load_crls() function to apps tidying load_certs() too. Add option + to verify utility to allow additional CRLs to be included. + [Steve Henson] + + *) Update OCSP request code to permit adding custom headers to the request: + some responders need this. + [Steve Henson] + + *) The function EVP_PKEY_sign() returns <=0 on error: check return code + correctly. + [Julia Lawall ] + + *) Update verify callback code in apps/s_cb.c and apps/verify.c, it + needlessly dereferenced structures, used obsolete functions and + didn't handle all updated verify codes correctly. + [Steve Henson] + + *) Disable MD2 in the default configuration. + [Steve Henson] + + *) In BIO_pop() and BIO_push() use the ctrl argument (which was NULL) to + indicate the initial BIO being pushed or popped. This makes it possible + to determine whether the BIO is the one explicitly called or as a result + of the ctrl being passed down the chain. Fix BIO_pop() and SSL BIOs so + it handles reference counts correctly and doesn't zero out the I/O bio + when it is not being explicitly popped. WARNING: applications which + included workarounds for the old buggy behaviour will need to be modified + or they could free up already freed BIOs. + [Steve Henson] + + *) Extend the uni2asc/asc2uni => OPENSSL_uni2asc/OPENSSL_asc2uni + renaming to all platforms (within the 0.9.8 branch, this was + done conditionally on Netware platforms to avoid a name clash). + [Guenter ] + + *) Add ECDHE and PSK support to DTLS. + [Michael Tuexen ] + + *) Add CHECKED_STACK_OF macro to safestack.h, otherwise safestack can't + be used on C++. + [Steve Henson] + + *) Add "missing" function EVP_MD_flags() (without this the only way to + retrieve a digest flags is by accessing the structure directly. Update + EVP_MD_do_all*() and EVP_CIPHER_do_all*() to include the name a digest + or cipher is registered as in the "from" argument. Print out all + registered digests in the dgst usage message instead of manually + attempting to work them out. + [Steve Henson] + + *) If no SSLv2 ciphers are used don't use an SSLv2 compatible client hello: + this allows the use of compression and extensions. Change default cipher + string to remove SSLv2 ciphersuites. This effectively avoids ancient SSLv2 + by default unless an application cipher string requests it. + [Steve Henson] + + *) Alter match criteria in PKCS12_parse(). It used to try to use local + key ids to find matching certificates and keys but some PKCS#12 files + don't follow the (somewhat unwritten) rules and this strategy fails. + Now just gather all certificates together and the first private key + then look for the first certificate that matches the key. + [Steve Henson] + + *) Support use of registered digest and cipher names for dgst and cipher + commands instead of having to add each one as a special case. So now + you can do: + + openssl sha256 foo + + as well as: + + openssl dgst -sha256 foo + + and this works for ENGINE based algorithms too. + + [Steve Henson] + + *) Update Gost ENGINE to support parameter files. + [Victor B. Wagner ] + + *) Support GeneralizedTime in ca utility. + [Oliver Martin , Steve Henson] + + *) Enhance the hash format used for certificate directory links. The new + form uses the canonical encoding (meaning equivalent names will work + even if they aren't identical) and uses SHA1 instead of MD5. This form + is incompatible with the older format and as a result c_rehash should + be used to rebuild symbolic links. + [Steve Henson] + + *) Make PKCS#8 the default write format for private keys, replacing the + traditional format. This form is standardised, more secure and doesn't + include an implicit MD5 dependency. + [Steve Henson] + + *) Add a $gcc_devteam_warn option to Configure. The idea is that any code + committed to OpenSSL should pass this lot as a minimum. + [Steve Henson] + + *) Add session ticket override functionality for use by EAP-FAST. + [Jouni Malinen ] + + *) Modify HMAC functions to return a value. Since these can be implemented + in an ENGINE errors can occur. + [Steve Henson] + + *) Type-checked OBJ_bsearch_ex. + [Ben Laurie] + + *) Type-checked OBJ_bsearch. Also some constification necessitated + by type-checking. Still to come: TXT_DB, bsearch(?), + OBJ_bsearch_ex, qsort, CRYPTO_EX_DATA, ASN1_VALUE, ASN1_STRING, + CONF_VALUE. + [Ben Laurie] + + *) New function OPENSSL_gmtime_adj() to add a specific number of days and + seconds to a tm structure directly, instead of going through OS + specific date routines. This avoids any issues with OS routines such + as the year 2038 bug. New *_adj() functions for ASN1 time structures + and X509_time_adj_ex() to cover the extended range. The existing + X509_time_adj() is still usable and will no longer have any date issues. + [Steve Henson] + + *) Delta CRL support. New use deltas option which will attempt to locate + and search any appropriate delta CRLs available. + + This work was sponsored by Google. + [Steve Henson] + + *) Support for CRLs partitioned by reason code. Reorganise CRL processing + code and add additional score elements. Validate alternate CRL paths + as part of the CRL checking and indicate a new error "CRL path validation + error" in this case. Applications wanting additional details can use + the verify callback and check the new "parent" field. If this is not + NULL CRL path validation is taking place. Existing applications wont + see this because it requires extended CRL support which is off by + default. + + This work was sponsored by Google. + [Steve Henson] + + *) Support for freshest CRL extension. + + This work was sponsored by Google. + [Steve Henson] + + *) Initial indirect CRL support. Currently only supported in the CRLs + passed directly and not via lookup. Process certificate issuer + CRL entry extension and lookup CRL entries by bother issuer name + and serial number. Check and process CRL issuer entry in IDP extension. + + This work was sponsored by Google. + [Steve Henson] + + *) Add support for distinct certificate and CRL paths. The CRL issuer + certificate is validated separately in this case. Only enabled if + an extended CRL support flag is set: this flag will enable additional + CRL functionality in future. + + This work was sponsored by Google. + [Steve Henson] + + *) Add support for policy mappings extension. + + This work was sponsored by Google. + [Steve Henson] + + *) Fixes to pathlength constraint, self issued certificate handling, + policy processing to align with RFC3280 and PKITS tests. + + This work was sponsored by Google. + [Steve Henson] + + *) Support for name constraints certificate extension. DN, email, DNS + and URI types are currently supported. + + This work was sponsored by Google. + [Steve Henson] + + *) To cater for systems that provide a pointer-based thread ID rather + than numeric, deprecate the current numeric thread ID mechanism and + replace it with a structure and associated callback type. This + mechanism allows a numeric "hash" to be extracted from a thread ID in + either case, and on platforms where pointers are larger than 'long', + mixing is done to help ensure the numeric 'hash' is usable even if it + can't be guaranteed unique. The default mechanism is to use "&errno" + as a pointer-based thread ID to distinguish between threads. + + Applications that want to provide their own thread IDs should now use + CRYPTO_THREADID_set_callback() to register a callback that will call + either CRYPTO_THREADID_set_numeric() or CRYPTO_THREADID_set_pointer(). + + Note that ERR_remove_state() is now deprecated, because it is tied + to the assumption that thread IDs are numeric. ERR_remove_state(0) + to free the current thread's error state should be replaced by + ERR_remove_thread_state(NULL). + + (This new approach replaces the functions CRYPTO_set_idptr_callback(), + CRYPTO_get_idptr_callback(), and CRYPTO_thread_idptr() that existed in + OpenSSL 0.9.9-dev between June 2006 and August 2008. Also, if an + application was previously providing a numeric thread callback that + was inappropriate for distinguishing threads, then uniqueness might + have been obtained with &errno that happened immediately in the + intermediate development versions of OpenSSL; this is no longer the + case, the numeric thread callback will now override the automatic use + of &errno.) + [Geoff Thorpe, with help from Bodo Moeller] + + *) Initial support for different CRL issuing certificates. This covers a + simple case where the self issued certificates in the chain exist and + the real CRL issuer is higher in the existing chain. + + This work was sponsored by Google. + [Steve Henson] + + *) Removed effectively defunct crypto/store from the build. + [Ben Laurie] + + *) Revamp of STACK to provide stronger type-checking. Still to come: + TXT_DB, bsearch(?), OBJ_bsearch, qsort, CRYPTO_EX_DATA, ASN1_VALUE, + ASN1_STRING, CONF_VALUE. + [Ben Laurie] + + *) Add a new SSL_MODE_RELEASE_BUFFERS mode flag to release unused buffer + RAM on SSL connections. This option can save about 34k per idle SSL. + [Nick Mathewson] + + *) Revamp of LHASH to provide stronger type-checking. Still to come: + STACK, TXT_DB, bsearch, qsort. + [Ben Laurie] + + *) Initial support for Cryptographic Message Syntax (aka CMS) based + on RFC3850, RFC3851 and RFC3852. New cms directory and cms utility, + support for data, signedData, compressedData, digestedData and + encryptedData, envelopedData types included. Scripts to check against + RFC4134 examples draft and interop and consistency checks of many + content types and variants. + [Steve Henson] + + *) Add options to enc utility to support use of zlib compression BIO. + [Steve Henson] + + *) Extend mk1mf to support importing of options and assembly language + files from Configure script, currently only included in VC-WIN32. + The assembly language rules can now optionally generate the source + files from the associated perl scripts. + [Steve Henson] + + *) Implement remaining functionality needed to support GOST ciphersuites. + Interop testing has been performed using CryptoPro implementations. + [Victor B. Wagner ] + + *) s390x assembler pack. + [Andy Polyakov] + + *) ARMv4 assembler pack. ARMv4 refers to v4 and later ISA, not CPU + "family." + [Andy Polyakov] + + *) Implement Opaque PRF Input TLS extension as specified in + draft-rescorla-tls-opaque-prf-input-00.txt. Since this is not an + official specification yet and no extension type assignment by + IANA exists, this extension (for now) will have to be explicitly + enabled when building OpenSSL by providing the extension number + to use. For example, specify an option + + -DTLSEXT_TYPE_opaque_prf_input=0x9527 + + to the "config" or "Configure" script to enable the extension, + assuming extension number 0x9527 (which is a completely arbitrary + and unofficial assignment based on the MD5 hash of the Internet + Draft). Note that by doing so, you potentially lose + interoperability with other TLS implementations since these might + be using the same extension number for other purposes. + + SSL_set_tlsext_opaque_prf_input(ssl, src, len) is used to set the + opaque PRF input value to use in the handshake. This will create + an interal copy of the length-'len' string at 'src', and will + return non-zero for success. + + To get more control and flexibility, provide a callback function + by using + + SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) + SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) + + where + + int (*cb)(SSL *, void *peerinput, size_t len, void *arg); + void *arg; + + Callback function 'cb' will be called in handshakes, and is + expected to use SSL_set_tlsext_opaque_prf_input() as appropriate. + Argument 'arg' is for application purposes (the value as given to + SSL_CTX_set_tlsext_opaque_prf_input_callback_arg() will directly + be provided to the callback function). The callback function + has to return non-zero to report success: usually 1 to use opaque + PRF input just if possible, or 2 to enforce use of the opaque PRF + input. In the latter case, the library will abort the handshake + if opaque PRF input is not successfully negotiated. + + Arguments 'peerinput' and 'len' given to the callback function + will always be NULL and 0 in the case of a client. A server will + see the client's opaque PRF input through these variables if + available (NULL and 0 otherwise). Note that if the server + provides an opaque PRF input, the length must be the same as the + length of the client's opaque PRF input. + + Note that the callback function will only be called when creating + a new session (session resumption can resume whatever was + previously negotiated), and will not be called in SSL 2.0 + handshakes; thus, SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) or + SSL_set_options(ssl, SSL_OP_NO_SSLv2) is especially recommended + for applications that need to enforce opaque PRF input. + + [Bodo Moeller] + + *) Update ssl code to support digests other than SHA1+MD5 for handshake + MAC. + + [Victor B. Wagner ] + + *) Add RFC4507 support to OpenSSL. This includes the corrections in + RFC4507bis. The encrypted ticket format is an encrypted encoded + SSL_SESSION structure, that way new session features are automatically + supported. + + If a client application caches session in an SSL_SESSION structure + support is transparent because tickets are now stored in the encoded + SSL_SESSION. + + The SSL_CTX structure automatically generates keys for ticket + protection in servers so again support should be possible + with no application modification. + + If a client or server wishes to disable RFC4507 support then the option + SSL_OP_NO_TICKET can be set. + + Add a TLS extension debugging callback to allow the contents of any client + or server extensions to be examined. + + This work was sponsored by Google. + [Steve Henson] + + *) Final changes to avoid use of pointer pointer casts in OpenSSL. + OpenSSL should now compile cleanly on gcc 4.2 + [Peter Hartley , Steve Henson] + + *) Update SSL library to use new EVP_PKEY MAC API. Include generic MAC + support including streaming MAC support: this is required for GOST + ciphersuite support. + [Victor B. Wagner , Steve Henson] + + *) Add option -stream to use PKCS#7 streaming in smime utility. New + function i2d_PKCS7_bio_stream() and PEM_write_PKCS7_bio_stream() + to output in BER and PEM format. + [Steve Henson] + + *) Experimental support for use of HMAC via EVP_PKEY interface. This + allows HMAC to be handled via the EVP_DigestSign*() interface. The + EVP_PKEY "key" in this case is the HMAC key, potentially allowing + ENGINE support for HMAC keys which are unextractable. New -mac and + -macopt options to dgst utility. + [Steve Henson] + + *) New option -sigopt to dgst utility. Update dgst to use + EVP_Digest{Sign,Verify}*. These two changes make it possible to use + alternative signing paramaters such as X9.31 or PSS in the dgst + utility. + [Steve Henson] + + *) Change ssl_cipher_apply_rule(), the internal function that does + the work each time a ciphersuite string requests enabling + ("foo+bar"), moving ("+foo+bar"), disabling ("-foo+bar", or + removing ("!foo+bar") a class of ciphersuites: Now it maintains + the order of disabled ciphersuites such that those ciphersuites + that most recently went from enabled to disabled not only stay + in order with respect to each other, but also have higher priority + than other disabled ciphersuites the next time ciphersuites are + enabled again. + + This means that you can now say, e.g., "PSK:-PSK:HIGH" to enable + the same ciphersuites as with "HIGH" alone, but in a specific + order where the PSK ciphersuites come first (since they are the + most recently disabled ciphersuites when "HIGH" is parsed). + + Also, change ssl_create_cipher_list() (using this new + funcionality) such that between otherwise identical + cihpersuites, ephemeral ECDH is preferred over ephemeral DH in + the default order. + [Bodo Moeller] + + *) Change ssl_create_cipher_list() so that it automatically + arranges the ciphersuites in reasonable order before starting + to process the rule string. Thus, the definition for "DEFAULT" + (SSL_DEFAULT_CIPHER_LIST) now is just "ALL:!aNULL:!eNULL", but + remains equivalent to "AES:ALL:!aNULL:!eNULL:+aECDH:+kRSA:+RC4:@STRENGTH". + This makes it much easier to arrive at a reasonable default order + in applications for which anonymous ciphers are OK (meaning + that you can't actually use DEFAULT). + [Bodo Moeller; suggested by Victor Duchovni] + + *) Split the SSL/TLS algorithm mask (as used for ciphersuite string + processing) into multiple integers instead of setting + "SSL_MKEY_MASK" bits, "SSL_AUTH_MASK" bits, "SSL_ENC_MASK", + "SSL_MAC_MASK", and "SSL_SSL_MASK" bits all in a single integer. + (These masks as well as the individual bit definitions are hidden + away into the non-exported interface ssl/ssl_locl.h, so this + change to the definition of the SSL_CIPHER structure shouldn't + affect applications.) This give us more bits for each of these + categories, so there is no longer a need to coagulate AES128 and + AES256 into a single algorithm bit, and to coagulate Camellia128 + and Camellia256 into a single algorithm bit, which has led to all + kinds of kludges. + + Thus, among other things, the kludge introduced in 0.9.7m and + 0.9.8e for masking out AES256 independently of AES128 or masking + out Camellia256 independently of AES256 is not needed here in 0.9.9. + + With the change, we also introduce new ciphersuite aliases that + so far were missing: "AES128", "AES256", "CAMELLIA128", and + "CAMELLIA256". + [Bodo Moeller] + + *) Add support for dsa-with-SHA224 and dsa-with-SHA256. + Use the leftmost N bytes of the signature input if the input is + larger than the prime q (with N being the size in bytes of q). + [Nils Larsch] + + *) Very *very* experimental PKCS#7 streaming encoder support. Nothing uses + it yet and it is largely untested. + [Steve Henson] + + *) Add support for the ecdsa-with-SHA224/256/384/512 signature types. + [Nils Larsch] + + *) Initial incomplete changes to avoid need for function casts in OpenSSL + some compilers (gcc 4.2 and later) reject their use. Safestack is + reimplemented. Update ASN1 to avoid use of legacy functions. + [Steve Henson] + + *) Win32/64 targets are linked with Winsock2. + [Andy Polyakov] + + *) Add an X509_CRL_METHOD structure to allow CRL processing to be redirected + to external functions. This can be used to increase CRL handling + efficiency especially when CRLs are very large by (for example) storing + the CRL revoked certificates in a database. + [Steve Henson] + + *) Overhaul of by_dir code. Add support for dynamic loading of CRLs so + new CRLs added to a directory can be used. New command line option + -verify_return_error to s_client and s_server. This causes real errors + to be returned by the verify callback instead of carrying on no matter + what. This reflects the way a "real world" verify callback would behave. + [Steve Henson] + + *) GOST engine, supporting several GOST algorithms and public key formats. + Kindly donated by Cryptocom. + [Cryptocom] + + *) Partial support for Issuing Distribution Point CRL extension. CRLs + partitioned by DP are handled but no indirect CRL or reason partitioning + (yet). Complete overhaul of CRL handling: now the most suitable CRL is + selected via a scoring technique which handles IDP and AKID in CRLs. + [Steve Henson] + + *) New X509_STORE_CTX callbacks lookup_crls() and lookup_certs() which + will ultimately be used for all verify operations: this will remove the + X509_STORE dependency on certificate verification and allow alternative + lookup methods. X509_STORE based implementations of these two callbacks. + [Steve Henson] + + *) Allow multiple CRLs to exist in an X509_STORE with matching issuer names. + Modify get_crl() to find a valid (unexpired) CRL if possible. + [Steve Henson] + + *) New function X509_CRL_match() to check if two CRLs are identical. Normally + this would be called X509_CRL_cmp() but that name is already used by + a function that just compares CRL issuer names. Cache several CRL + extensions in X509_CRL structure and cache CRLDP in X509. + [Steve Henson] + + *) Store a "canonical" representation of X509_NAME structure (ASN1 Name) + this maps equivalent X509_NAME structures into a consistent structure. + Name comparison can then be performed rapidly using memcmp(). + [Steve Henson] + + *) Non-blocking OCSP request processing. Add -timeout option to ocsp + utility. + [Steve Henson] + + *) Allow digests to supply their own micalg string for S/MIME type using + the ctrl EVP_MD_CTRL_MICALG. + [Steve Henson] + + *) During PKCS7 signing pass the PKCS7 SignerInfo structure to the + EVP_PKEY_METHOD before and after signing via the EVP_PKEY_CTRL_PKCS7_SIGN + ctrl. It can then customise the structure before and/or after signing + if necessary. + [Steve Henson] + + *) New function OBJ_add_sigid() to allow application defined signature OIDs + to be added to OpenSSLs internal tables. New function OBJ_sigid_free() + to free up any added signature OIDs. + [Steve Henson] + + *) New functions EVP_CIPHER_do_all(), EVP_CIPHER_do_all_sorted(), + EVP_MD_do_all() and EVP_MD_do_all_sorted() to enumerate internal + digest and cipher tables. New options added to openssl utility: + list-message-digest-algorithms and list-cipher-algorithms. + [Steve Henson] + + *) Change the array representation of binary polynomials: the list + of degrees of non-zero coefficients is now terminated with -1. + Previously it was terminated with 0, which was also part of the + value; thus, the array representation was not applicable to + polynomials where t^0 has coefficient zero. This change makes + the array representation useful in a more general context. + [Douglas Stebila] + + *) Various modifications and fixes to SSL/TLS cipher string + handling. For ECC, the code now distinguishes between fixed ECDH + with RSA certificates on the one hand and with ECDSA certificates + on the other hand, since these are separate ciphersuites. The + unused code for Fortezza ciphersuites has been removed. + + For consistency with EDH, ephemeral ECDH is now called "EECDH" + (not "ECDHE"). For consistency with the code for DH + certificates, use of ECDH certificates is now considered ECDH + authentication, not RSA or ECDSA authentication (the latter is + merely the CA's signing algorithm and not actively used in the + protocol). + + The temporary ciphersuite alias "ECCdraft" is no longer + available, and ECC ciphersuites are no longer excluded from "ALL" + and "DEFAULT". The following aliases now exist for RFC 4492 + ciphersuites, most of these by analogy with the DH case: + + kECDHr - ECDH cert, signed with RSA + kECDHe - ECDH cert, signed with ECDSA + kECDH - ECDH cert (signed with either RSA or ECDSA) + kEECDH - ephemeral ECDH + ECDH - ECDH cert or ephemeral ECDH + + aECDH - ECDH cert + aECDSA - ECDSA cert + ECDSA - ECDSA cert + + AECDH - anonymous ECDH + EECDH - non-anonymous ephemeral ECDH (equivalent to "kEECDH:-AECDH") + + [Bodo Moeller] + + *) Add additional S/MIME capabilities for AES and GOST ciphers if supported. + Use correct micalg parameters depending on digest(s) in signed message. + [Steve Henson] + + *) Add engine support for EVP_PKEY_ASN1_METHOD. Add functions to process + an ENGINE asn1 method. Support ENGINE lookups in the ASN1 code. + [Steve Henson] + + *) Initial engine support for EVP_PKEY_METHOD. New functions to permit + an engine to register a method. Add ENGINE lookups for methods and + functional reference processing. + [Steve Henson] + + *) New functions EVP_Digest{Sign,Verify)*. These are enchance versions of + EVP_{Sign,Verify}* which allow an application to customise the signature + process. + [Steve Henson] + + *) New -resign option to smime utility. This adds one or more signers + to an existing PKCS#7 signedData structure. Also -md option to use an + alternative message digest algorithm for signing. + [Steve Henson] + + *) Tidy up PKCS#7 routines and add new functions to make it easier to + create PKCS7 structures containing multiple signers. Update smime + application to support multiple signers. + [Steve Henson] + + *) New -macalg option to pkcs12 utility to allow setting of an alternative + digest MAC. + [Steve Henson] + + *) Initial support for PKCS#5 v2.0 PRFs other than default SHA1 HMAC. + Reorganize PBE internals to lookup from a static table using NIDs, + add support for HMAC PBE OID translation. Add a EVP_CIPHER ctrl: + EVP_CTRL_PBE_PRF_NID this allows a cipher to specify an alternative + PRF which will be automatically used with PBES2. + [Steve Henson] + + *) Replace the algorithm specific calls to generate keys in "req" with the + new API. + [Steve Henson] + + *) Update PKCS#7 enveloped data routines to use new API. This is now + supported by any public key method supporting the encrypt operation. A + ctrl is added to allow the public key algorithm to examine or modify + the PKCS#7 RecipientInfo structure if it needs to: for RSA this is + a no op. + [Steve Henson] + + *) Add a ctrl to asn1 method to allow a public key algorithm to express + a default digest type to use. In most cases this will be SHA1 but some + algorithms (such as GOST) need to specify an alternative digest. The + return value indicates how strong the prefernce is 1 means optional and + 2 is mandatory (that is it is the only supported type). Modify + ASN1_item_sign() to accept a NULL digest argument to indicate it should + use the default md. Update openssl utilities to use the default digest + type for signing if it is not explicitly indicated. + [Steve Henson] + + *) Use OID cross reference table in ASN1_sign() and ASN1_verify(). New + EVP_MD flag EVP_MD_FLAG_PKEY_METHOD_SIGNATURE. This uses the relevant + signing method from the key type. This effectively removes the link + between digests and public key types. + [Steve Henson] + + *) Add an OID cross reference table and utility functions. Its purpose is to + translate between signature OIDs such as SHA1WithrsaEncryption and SHA1, + rsaEncryption. This will allow some of the algorithm specific hackery + needed to use the correct OID to be removed. + [Steve Henson] + + *) Remove algorithm specific dependencies when setting PKCS7_SIGNER_INFO + structures for PKCS7_sign(). They are now set up by the relevant public + key ASN1 method. + [Steve Henson] + + *) Add provisional EC pkey method with support for ECDSA and ECDH. + [Steve Henson] + + *) Add support for key derivation (agreement) in the API, DH method and + pkeyutl. + [Steve Henson] + + *) Add DSA pkey method and DH pkey methods, extend DH ASN1 method to support + public and private key formats. As a side effect these add additional + command line functionality not previously available: DSA signatures can be + generated and verified using pkeyutl and DH key support and generation in + pkey, genpkey. + [Steve Henson] + + *) BeOS support. + [Oliver Tappe ] + + *) New make target "install_html_docs" installs HTML renditions of the + manual pages. + [Oliver Tappe ] + + *) New utility "genpkey" this is analagous to "genrsa" etc except it can + generate keys for any algorithm. Extend and update EVP_PKEY_METHOD to + support key and parameter generation and add initial key generation + functionality for RSA. + [Steve Henson] + + *) Add functions for main EVP_PKEY_method operations. The undocumented + functions EVP_PKEY_{encrypt,decrypt} have been renamed to + EVP_PKEY_{encrypt,decrypt}_old. + [Steve Henson] + + *) Initial definitions for EVP_PKEY_METHOD. This will be a high level public + key API, doesn't do much yet. + [Steve Henson] + + *) New function EVP_PKEY_asn1_get0_info() to retrieve information about + public key algorithms. New option to openssl utility: + "list-public-key-algorithms" to print out info. + [Steve Henson] + + *) Implement the Supported Elliptic Curves Extension for + ECC ciphersuites from draft-ietf-tls-ecc-12.txt. + [Douglas Stebila] + + *) Don't free up OIDs in OBJ_cleanup() if they are in use by EVP_MD or + EVP_CIPHER structures to avoid later problems in EVP_cleanup(). + [Steve Henson] + + *) New utilities pkey and pkeyparam. These are similar to algorithm specific + utilities such as rsa, dsa, dsaparam etc except they process any key + type. + [Steve Henson] + + *) Transfer public key printing routines to EVP_PKEY_ASN1_METHOD. New + functions EVP_PKEY_print_public(), EVP_PKEY_print_private(), + EVP_PKEY_print_param() to print public key data from an EVP_PKEY + structure. + [Steve Henson] + + *) Initial support for pluggable public key ASN1. + De-spaghettify the public key ASN1 handling. Move public and private + key ASN1 handling to a new EVP_PKEY_ASN1_METHOD structure. Relocate + algorithm specific handling to a single module within the relevant + algorithm directory. Add functions to allow (near) opaque processing + of public and private key structures. + [Steve Henson] + + *) Implement the Supported Point Formats Extension for + ECC ciphersuites from draft-ietf-tls-ecc-12.txt. + [Douglas Stebila] + + *) Add initial support for RFC 4279 PSK TLS ciphersuites. Add members + for the psk identity [hint] and the psk callback functions to the + SSL_SESSION, SSL and SSL_CTX structure. + + New ciphersuites: + PSK-RC4-SHA, PSK-3DES-EDE-CBC-SHA, PSK-AES128-CBC-SHA, + PSK-AES256-CBC-SHA + + New functions: + SSL_CTX_use_psk_identity_hint + SSL_get_psk_identity_hint + SSL_get_psk_identity + SSL_use_psk_identity_hint + + [Mika Kousa and Pasi Eronen of Nokia Corporation] + + *) Add RFC 3161 compliant time stamp request creation, response generation + and response verification functionality. + [Zoltán Glózik , The OpenTSA Project] + + *) Add initial support for TLS extensions, specifically for the server_name + extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now + have new members for a host name. The SSL data structure has an + additional member SSL_CTX *initial_ctx so that new sessions can be + stored in that context to allow for session resumption, even after the + SSL has been switched to a new SSL_CTX in reaction to a client's + server_name extension. + + New functions (subject to change): + + SSL_get_servername() + SSL_get_servername_type() + SSL_set_SSL_CTX() + + New CTRL codes and macros (subject to change): + + SSL_CTRL_SET_TLSEXT_SERVERNAME_CB + - SSL_CTX_set_tlsext_servername_callback() + SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG + - SSL_CTX_set_tlsext_servername_arg() + SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_host_name() + + openssl s_client has a new '-servername ...' option. + + openssl s_server has new options '-servername_host ...', '-cert2 ...', + '-key2 ...', '-servername_fatal' (subject to change). This allows + testing the HostName extension for a specific single host name ('-cert' + and '-key' remain fallbacks for handshakes without HostName + negotiation). If the unrecogninzed_name alert has to be sent, this by + default is a warning; it becomes fatal with the '-servername_fatal' + option. + + [Peter Sylvester, Remy Allais, Christophe Renou] + + *) Whirlpool hash implementation is added. + [Andy Polyakov] + + *) BIGNUM code on 64-bit SPARCv9 targets is switched from bn(64,64) to + bn(64,32). Because of instruction set limitations it doesn't have + any negative impact on performance. This was done mostly in order + to make it possible to share assembler modules, such as bn_mul_mont + implementations, between 32- and 64-bit builds without hassle. + [Andy Polyakov] + + *) Move code previously exiled into file crypto/ec/ec2_smpt.c + to ec2_smpl.c, and no longer require the OPENSSL_EC_BIN_PT_COMP + macro. + [Bodo Moeller] + + *) New candidate for BIGNUM assembler implementation, bn_mul_mont, + dedicated Montgomery multiplication procedure, is introduced. + BN_MONT_CTX is modified to allow bn_mul_mont to reach for higher + "64-bit" performance on certain 32-bit targets. + [Andy Polyakov] + + *) New option SSL_OP_NO_COMP to disable use of compression selectively + in SSL structures. New SSL ctrl to set maximum send fragment size. + Save memory by seeting the I/O buffer sizes dynamically instead of + using the maximum available value. + [Steve Henson] + + *) New option -V for 'openssl ciphers'. This prints the ciphersuite code + in addition to the text details. + [Bodo Moeller] + + *) Very, very preliminary EXPERIMENTAL support for printing of general + ASN1 structures. This currently produces rather ugly output and doesn't + handle several customised structures at all. + [Steve Henson] + + *) Integrated support for PVK file format and some related formats such + as MS PUBLICKEYBLOB and PRIVATEKEYBLOB. Command line switches to support + these in the 'rsa' and 'dsa' utilities. + [Steve Henson] + + *) Support for PKCS#1 RSAPublicKey format on rsa utility command line. + [Steve Henson] + + *) Remove the ancient ASN1_METHOD code. This was only ever used in one + place for the (very old) "NETSCAPE" format certificates which are now + handled using new ASN1 code equivalents. + [Steve Henson] + + *) Let the TLSv1_method() etc. functions return a 'const' SSL_METHOD + pointer and make the SSL_METHOD parameter in SSL_CTX_new, + SSL_CTX_set_ssl_version and SSL_set_ssl_method 'const'. + [Nils Larsch] + + *) Modify CRL distribution points extension code to print out previously + unsupported fields. Enhance extension setting code to allow setting of + all fields. + [Steve Henson] + + *) Add print and set support for Issuing Distribution Point CRL extension. + [Steve Henson] + + *) Change 'Configure' script to enable Camellia by default. + [NTT] + + Changes between 0.9.8m and 0.9.8n [24 Mar 2010] + + *) When rejecting SSL/TLS records due to an incorrect version number, never + update s->server with a new major version number. As of + - OpenSSL 0.9.8m if 'short' is a 16-bit type, + - OpenSSL 0.9.8f if 'short' is longer than 16 bits, + the previous behavior could result in a read attempt at NULL when + receiving specific incorrect SSL/TLS records once record payload + protection is active. (CVE-2010-0740) + [Bodo Moeller, Adam Langley ] + + *) Fix for CVE-2010-0433 where some kerberos enabled versions of OpenSSL + could be crashed if the relevant tables were not present (e.g. chrooted). + [Tomas Hoger ] + + Changes between 0.9.8l and 0.9.8m [25 Feb 2010] + + *) Always check bn_wexpend() return values for failure. (CVE-2009-3245) + [Martin Olsson, Neel Mehta] + + *) Fix X509_STORE locking: Every 'objs' access requires a lock (to + accommodate for stack sorting, always a write lock!). + [Bodo Moeller] + + *) On some versions of WIN32 Heap32Next is very slow. This can cause + excessive delays in the RAND_poll(): over a minute. As a workaround + include a time check in the inner Heap32Next loop too. + [Steve Henson] + + *) The code that handled flushing of data in SSL/TLS originally used the + BIO_CTRL_INFO ctrl to see if any data was pending first. This caused + the problem outlined in PR#1949. The fix suggested there however can + trigger problems with buggy BIO_CTRL_WPENDING (e.g. some versions + of Apache). So instead simplify the code to flush unconditionally. + This should be fine since flushing with no data to flush is a no op. + [Steve Henson] + + *) Handle TLS versions 2.0 and later properly and correctly use the + highest version of TLS/SSL supported. Although TLS >= 2.0 is some way + off ancient servers have a habit of sticking around for a while... + [Steve Henson] + + *) Modify compression code so it frees up structures without using the + ex_data callbacks. This works around a problem where some applications + call CRYPTO_cleanup_all_ex_data() before application exit (e.g. when + restarting) then use compression (e.g. SSL with compression) later. + This results in significant per-connection memory leaks and + has caused some security issues including CVE-2008-1678 and + CVE-2009-4355. + [Steve Henson] + + *) Constify crypto/cast (i.e., ): a CAST_KEY doesn't + change when encrypting or decrypting. + [Bodo Moeller] + + *) Add option SSL_OP_LEGACY_SERVER_CONNECT which will allow clients to + connect and renegotiate with servers which do not support RI. + Until RI is more widely deployed this option is enabled by default. + [Steve Henson] + + *) Add "missing" ssl ctrls to clear options and mode. + [Steve Henson] + + *) If client attempts to renegotiate and doesn't support RI respond with + a no_renegotiation alert as required by RFC5746. Some renegotiating + TLS clients will continue a connection gracefully when they receive + the alert. Unfortunately OpenSSL mishandled this alert and would hang + waiting for a server hello which it will never receive. Now we treat a + received no_renegotiation alert as a fatal error. This is because + applications requesting a renegotiation might well expect it to succeed + and would have no code in place to handle the server denying it so the + only safe thing to do is to terminate the connection. + [Steve Henson] + + *) Add ctrl macro SSL_get_secure_renegotiation_support() which returns 1 if + peer supports secure renegotiation and 0 otherwise. Print out peer + renegotiation support in s_client/s_server. + [Steve Henson] + + *) Replace the highly broken and deprecated SPKAC certification method with + the updated NID creation version. This should correctly handle UTF8. + [Steve Henson] + + *) Implement RFC5746. Re-enable renegotiation but require the extension + as needed. Unfortunately, SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION + turns out to be a bad idea. It has been replaced by + SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION which can be set with + SSL_CTX_set_options(). This is really not recommended unless you + know what you are doing. + [Eric Rescorla , Ben Laurie, Steve Henson] + + *) Fixes to stateless session resumption handling. Use initial_ctx when + issuing and attempting to decrypt tickets in case it has changed during + servername handling. Use a non-zero length session ID when attempting + stateless session resumption: this makes it possible to determine if + a resumption has occurred immediately after receiving server hello + (several places in OpenSSL subtly assume this) instead of later in + the handshake. + [Steve Henson] + + *) The functions ENGINE_ctrl(), OPENSSL_isservice(), + CMS_get1_RecipientRequest() and RAND_bytes() can return <=0 on error + fixes for a few places where the return code is not checked + correctly. + [Julia Lawall ] + + *) Add --strict-warnings option to Configure script to include devteam + warnings in other configurations. + [Steve Henson] + + *) Add support for --libdir option and LIBDIR variable in makefiles. This + makes it possible to install openssl libraries in locations which + have names other than "lib", for example "/usr/lib64" which some + systems need. + [Steve Henson, based on patch from Jeremy Utley] + + *) Don't allow the use of leading 0x80 in OIDs. This is a violation of + X690 8.9.12 and can produce some misleading textual output of OIDs. + [Steve Henson, reported by Dan Kaminsky] + + *) Delete MD2 from algorithm tables. This follows the recommendation in + several standards that it is not used in new applications due to + several cryptographic weaknesses. For binary compatibility reasons + the MD2 API is still compiled in by default. + [Steve Henson] + + *) Add compression id to {d2i,i2d}_SSL_SESSION so it is correctly saved + and restored. + [Steve Henson] + + *) Rename uni2asc and asc2uni functions to OPENSSL_uni2asc and + OPENSSL_asc2uni conditionally on Netware platforms to avoid a name + clash. + [Guenter ] + + *) Fix the server certificate chain building code to use X509_verify_cert(), + it used to have an ad-hoc builder which was unable to cope with anything + other than a simple chain. + [David Woodhouse , Steve Henson] + + *) Don't check self signed certificate signatures in X509_verify_cert() + by default (a flag can override this): it just wastes time without + adding any security. As a useful side effect self signed root CAs + with non-FIPS digests are now usable in FIPS mode. + [Steve Henson] + + *) In dtls1_process_out_of_seq_message() the check if the current message + is already buffered was missing. For every new message was memory + allocated, allowing an attacker to perform an denial of service attack + with sending out of seq handshake messages until there is no memory + left. Additionally every future messege was buffered, even if the + sequence number made no sense and would be part of another handshake. + So only messages with sequence numbers less than 10 in advance will be + buffered. (CVE-2009-1378) + [Robin Seggelmann, discovered by Daniel Mentz] + + *) Records are buffered if they arrive with a future epoch to be + processed after finishing the corresponding handshake. There is + currently no limitation to this buffer allowing an attacker to perform + a DOS attack with sending records with future epochs until there is no + memory left. This patch adds the pqueue_size() function to detemine + the size of a buffer and limits the record buffer to 100 entries. + (CVE-2009-1377) + [Robin Seggelmann, discovered by Daniel Mentz] + + *) Keep a copy of frag->msg_header.frag_len so it can be used after the + parent structure is freed. (CVE-2009-1379) + [Daniel Mentz] + + *) Handle non-blocking I/O properly in SSL_shutdown() call. + [Darryl Miles ] + + *) Add 2.5.4.* OIDs + [Ilya O. ] + + Changes between 0.9.8k and 0.9.8l [5 Nov 2009] + + *) Disable renegotiation completely - this fixes a severe security + problem (CVE-2009-3555) at the cost of breaking all + renegotiation. Renegotiation can be re-enabled by setting + SSL3_FLAGS_ALLOW_UNSAFE_LEGACY_RENEGOTIATION in s3->flags at + run-time. This is really not recommended unless you know what + you're doing. + [Ben Laurie] + + Changes between 0.9.8j and 0.9.8k [25 Mar 2009] + + *) Don't set val to NULL when freeing up structures, it is freed up by + underlying code. If sizeof(void *) > sizeof(long) this can result in + zeroing past the valid field. (CVE-2009-0789) + [Paolo Ganci ] + + *) Fix bug where return value of CMS_SignerInfo_verify_content() was not + checked correctly. This would allow some invalid signed attributes to + appear to verify correctly. (CVE-2009-0591) + [Ivan Nestlerode ] + + *) Reject UniversalString and BMPString types with invalid lengths. This + prevents a crash in ASN1_STRING_print_ex() which assumes the strings have + a legal length. (CVE-2009-0590) + [Steve Henson] + + *) Set S/MIME signing as the default purpose rather than setting it + unconditionally. This allows applications to override it at the store + level. + [Steve Henson] + + *) Permit restricted recursion of ASN1 strings. This is needed in practice + to handle some structures. + [Steve Henson] + + *) Improve efficiency of mem_gets: don't search whole buffer each time + for a '\n' + [Jeremy Shapiro ] + + *) New -hex option for openssl rand. + [Matthieu Herrb] + + *) Print out UTF8String and NumericString when parsing ASN1. + [Steve Henson] + + *) Support NumericString type for name components. + [Steve Henson] + + *) Allow CC in the environment to override the automatically chosen + compiler. Note that nothing is done to ensure flags work with the + chosen compiler. + [Ben Laurie] + + Changes between 0.9.8i and 0.9.8j [07 Jan 2009] + + *) Properly check EVP_VerifyFinal() and similar return values + (CVE-2008-5077). + [Ben Laurie, Bodo Moeller, Google Security Team] + + *) Enable TLS extensions by default. + [Ben Laurie] + + *) Allow the CHIL engine to be loaded, whether the application is + multithreaded or not. (This does not release the developer from the + obligation to set up the dynamic locking callbacks.) + [Sander Temme ] + + *) Use correct exit code if there is an error in dgst command. + [Steve Henson; problem pointed out by Roland Dirlewanger] + + *) Tweak Configure so that you need to say "experimental-jpake" to enable + JPAKE, and need to use -DOPENSSL_EXPERIMENTAL_JPAKE in applications. + [Bodo Moeller] + + *) Add experimental JPAKE support, including demo authentication in + s_client and s_server. + [Ben Laurie] + + *) Set the comparison function in v3_addr_canonize(). + [Rob Austein ] + + *) Add support for XMPP STARTTLS in s_client. + [Philip Paeps ] + + *) Change the server-side SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG behavior + to ensure that even with this option, only ciphersuites in the + server's preference list will be accepted. (Note that the option + applies only when resuming a session, so the earlier behavior was + just about the algorithm choice for symmetric cryptography.) + [Bodo Moeller] + + Changes between 0.9.8h and 0.9.8i [15 Sep 2008] + + *) Fix NULL pointer dereference if a DTLS server received + ChangeCipherSpec as first record (CVE-2009-1386). + [PR #1679] + + *) Fix a state transitition in s3_srvr.c and d1_srvr.c + (was using SSL3_ST_CW_CLNT_HELLO_B, should be ..._ST_SW_SRVR_...). + [Nagendra Modadugu] + + *) The fix in 0.9.8c that supposedly got rid of unsafe + double-checked locking was incomplete for RSA blinding, + addressing just one layer of what turns out to have been + doubly unsafe triple-checked locking. + + So now fix this for real by retiring the MONT_HELPER macro + in crypto/rsa/rsa_eay.c. + + [Bodo Moeller; problem pointed out by Marius Schilder] + + *) Various precautionary measures: + + - Avoid size_t integer overflow in HASH_UPDATE (md32_common.h). + + - Avoid a buffer overflow in d2i_SSL_SESSION() (ssl_asn1.c). + (NB: This would require knowledge of the secret session ticket key + to exploit, in which case you'd be SOL either way.) + + - Change bn_nist.c so that it will properly handle input BIGNUMs + outside the expected range. + + - Enforce the 'num' check in BN_div() (bn_div.c) for non-BN_DEBUG + builds. + + [Neel Mehta, Bodo Moeller] + + *) Allow engines to be "soft loaded" - i.e. optionally don't die if + the load fails. Useful for distros. + [Ben Laurie and the FreeBSD team] + + *) Add support for Local Machine Keyset attribute in PKCS#12 files. + [Steve Henson] + + *) Fix BN_GF2m_mod_arr() top-bit cleanup code. + [Huang Ying] + + *) Expand ENGINE to support engine supplied SSL client certificate functions. + + This work was sponsored by Logica. + [Steve Henson] + + *) Add CryptoAPI ENGINE to support use of RSA and DSA keys held in Windows + keystores. Support for SSL/TLS client authentication too. + Not compiled unless enable-capieng specified to Configure. + + This work was sponsored by Logica. + [Steve Henson] + + *) Fix bug in X509_ATTRIBUTE creation: dont set attribute using + ASN1_TYPE_set1 if MBSTRING flag set. This bug would crash certain + attribute creation routines such as certifcate requests and PKCS#12 + files. + [Steve Henson] + + Changes between 0.9.8g and 0.9.8h [28 May 2008] + + *) Fix flaw if 'Server Key exchange message' is omitted from a TLS + handshake which could lead to a cilent crash as found using the + Codenomicon TLS test suite (CVE-2008-1672) + [Steve Henson, Mark Cox] + + *) Fix double free in TLS server name extensions which could lead to + a remote crash found by Codenomicon TLS test suite (CVE-2008-0891) + [Joe Orton] + + *) Clear error queue in SSL_CTX_use_certificate_chain_file() + + Clear the error queue to ensure that error entries left from + older function calls do not interfere with the correct operation. + [Lutz Jaenicke, Erik de Castro Lopo] + + *) Remove root CA certificates of commercial CAs: + + The OpenSSL project does not recommend any specific CA and does not + have any policy with respect to including or excluding any CA. + Therefore it does not make any sense to ship an arbitrary selection + of root CA certificates with the OpenSSL software. + [Lutz Jaenicke] + + *) RSA OAEP patches to fix two separate invalid memory reads. + The first one involves inputs when 'lzero' is greater than + 'SHA_DIGEST_LENGTH' (it would read about SHA_DIGEST_LENGTH bytes + before the beginning of from). The second one involves inputs where + the 'db' section contains nothing but zeroes (there is a one-byte + invalid read after the end of 'db'). + [Ivan Nestlerode ] + + *) Partial backport from 0.9.9-dev: + + Introduce bn_mul_mont (dedicated Montgomery multiplication + procedure) as a candidate for BIGNUM assembler implementation. + While 0.9.9-dev uses assembler for various architectures, only + x86_64 is available by default here in the 0.9.8 branch, and + 32-bit x86 is available through a compile-time setting. + + To try the 32-bit x86 assembler implementation, use Configure + option "enable-montasm" (which exists only for this backport). + + As "enable-montasm" for 32-bit x86 disclaims code stability + anyway, in this constellation we activate additional code + backported from 0.9.9-dev for further performance improvements, + namely BN_from_montgomery_word. (To enable this otherwise, + e.g. x86_64, try "-DMONT_FROM_WORD___NON_DEFAULT_0_9_8_BUILD".) + + [Andy Polyakov (backport partially by Bodo Moeller)] + + *) Add TLS session ticket callback. This allows an application to set + TLS ticket cipher and HMAC keys rather than relying on hardcoded fixed + values. This is useful for key rollover for example where several key + sets may exist with different names. + [Steve Henson] + + *) Reverse ENGINE-internal logic for caching default ENGINE handles. + This was broken until now in 0.9.8 releases, such that the only way + a registered ENGINE could be used (assuming it initialises + successfully on the host) was to explicitly set it as the default + for the relevant algorithms. This is in contradiction with 0.9.7 + behaviour and the documentation. With this fix, when an ENGINE is + registered into a given algorithm's table of implementations, the + 'uptodate' flag is reset so that auto-discovery will be used next + time a new context for that algorithm attempts to select an + implementation. + [Ian Lister (tweaked by Geoff Thorpe)] + + *) Backport of CMS code to OpenSSL 0.9.8. This differs from the 0.9.9 + implemention in the following ways: + + Lack of EVP_PKEY_ASN1_METHOD means algorithm parameters have to be + hard coded. + + Lack of BER streaming support means one pass streaming processing is + only supported if data is detached: setting the streaming flag is + ignored for embedded content. + + CMS support is disabled by default and must be explicitly enabled + with the enable-cms configuration option. + [Steve Henson] + + *) Update the GMP engine glue to do direct copies between BIGNUM and + mpz_t when openssl and GMP use the same limb size. Otherwise the + existing "conversion via a text string export" trick is still used. + [Paul Sheer ] + + *) Zlib compression BIO. This is a filter BIO which compressed and + uncompresses any data passed through it. + [Steve Henson] + + *) Add AES_wrap_key() and AES_unwrap_key() functions to implement + RFC3394 compatible AES key wrapping. + [Steve Henson] + + *) Add utility functions to handle ASN1 structures. ASN1_STRING_set0(): + sets string data without copying. X509_ALGOR_set0() and + X509_ALGOR_get0(): set and retrieve X509_ALGOR (AlgorithmIdentifier) + data. Attribute function X509at_get0_data_by_OBJ(): retrieves data + from an X509_ATTRIBUTE structure optionally checking it occurs only + once. ASN1_TYPE_set1(): set and ASN1_TYPE structure copying supplied + data. + [Steve Henson] + + *) Fix BN flag handling in RSA_eay_mod_exp() and BN_MONT_CTX_set() + to get the expected BN_FLG_CONSTTIME behavior. + [Bodo Moeller (Google)] + + *) Netware support: + + - fixed wrong usage of ioctlsocket() when build for LIBC BSD sockets + - fixed do_tests.pl to run the test suite with CLIB builds too (CLIB_OPT) + - added some more tests to do_tests.pl + - fixed RunningProcess usage so that it works with newer LIBC NDKs too + - removed usage of BN_LLONG for CLIB builds to avoid runtime dependency + - added new Configure targets netware-clib-bsdsock, netware-clib-gcc, + netware-clib-bsdsock-gcc, netware-libc-bsdsock-gcc + - various changes to netware.pl to enable gcc-cross builds on Win32 + platform + - changed crypto/bio/b_sock.c to work with macro functions (CLIB BSD) + - various changes to fix missing prototype warnings + - fixed x86nasm.pl to create correct asm files for NASM COFF output + - added AES, WHIRLPOOL and CPUID assembler code to build files + - added missing AES assembler make rules to mk1mf.pl + - fixed order of includes in apps/ocsp.c so that e_os.h settings apply + [Guenter Knauf ] + + *) Implement certificate status request TLS extension defined in RFC3546. + A client can set the appropriate parameters and receive the encoded + OCSP response via a callback. A server can query the supplied parameters + and set the encoded OCSP response in the callback. Add simplified examples + to s_client and s_server. + [Steve Henson] + + Changes between 0.9.8f and 0.9.8g [19 Oct 2007] + + *) Fix various bugs: + + Binary incompatibility of ssl_ctx_st structure + + DTLS interoperation with non-compliant servers + + Don't call get_session_cb() without proposed session + + Fix ia64 assembler code + [Andy Polyakov, Steve Henson] + + Changes between 0.9.8e and 0.9.8f [11 Oct 2007] + + *) DTLS Handshake overhaul. There were longstanding issues with + OpenSSL DTLS implementation, which were making it impossible for + RFC 4347 compliant client to communicate with OpenSSL server. + Unfortunately just fixing these incompatibilities would "cut off" + pre-0.9.8f clients. To allow for hassle free upgrade post-0.9.8e + server keeps tolerating non RFC compliant syntax. The opposite is + not true, 0.9.8f client can not communicate with earlier server. + This update even addresses CVE-2007-4995. + [Andy Polyakov] + + *) Changes to avoid need for function casts in OpenSSL: some compilers + (gcc 4.2 and later) reject their use. + [Kurt Roeckx , Peter Hartley , + Steve Henson] + + *) Add RFC4507 support to OpenSSL. This includes the corrections in + RFC4507bis. The encrypted ticket format is an encrypted encoded + SSL_SESSION structure, that way new session features are automatically + supported. + + If a client application caches session in an SSL_SESSION structure + support is transparent because tickets are now stored in the encoded + SSL_SESSION. + + The SSL_CTX structure automatically generates keys for ticket + protection in servers so again support should be possible + with no application modification. + + If a client or server wishes to disable RFC4507 support then the option + SSL_OP_NO_TICKET can be set. + + Add a TLS extension debugging callback to allow the contents of any client + or server extensions to be examined. + + This work was sponsored by Google. + [Steve Henson] + + *) Add initial support for TLS extensions, specifically for the server_name + extension so far. The SSL_SESSION, SSL_CTX, and SSL data structures now + have new members for a host name. The SSL data structure has an + additional member SSL_CTX *initial_ctx so that new sessions can be + stored in that context to allow for session resumption, even after the + SSL has been switched to a new SSL_CTX in reaction to a client's + server_name extension. + + New functions (subject to change): + + SSL_get_servername() + SSL_get_servername_type() + SSL_set_SSL_CTX() + + New CTRL codes and macros (subject to change): + + SSL_CTRL_SET_TLSEXT_SERVERNAME_CB + - SSL_CTX_set_tlsext_servername_callback() + SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG + - SSL_CTX_set_tlsext_servername_arg() + SSL_CTRL_SET_TLSEXT_HOSTNAME - SSL_set_tlsext_host_name() + + openssl s_client has a new '-servername ...' option. + + openssl s_server has new options '-servername_host ...', '-cert2 ...', + '-key2 ...', '-servername_fatal' (subject to change). This allows + testing the HostName extension for a specific single host name ('-cert' + and '-key' remain fallbacks for handshakes without HostName + negotiation). If the unrecogninzed_name alert has to be sent, this by + default is a warning; it becomes fatal with the '-servername_fatal' + option. + + [Peter Sylvester, Remy Allais, Christophe Renou, Steve Henson] + + *) Add AES and SSE2 assembly language support to VC++ build. + [Steve Henson] + + *) Mitigate attack on final subtraction in Montgomery reduction. + [Andy Polyakov] + + *) Fix crypto/ec/ec_mult.c to work properly with scalars of value 0 + (which previously caused an internal error). + [Bodo Moeller] + + *) Squeeze another 10% out of IGE mode when in != out. + [Ben Laurie] + + *) AES IGE mode speedup. + [Dean Gaudet (Google)] + + *) Add the Korean symmetric 128-bit cipher SEED (see + http://www.kisa.or.kr/kisa/seed/jsp/seed_eng.jsp) and + add SEED ciphersuites from RFC 4162: + + TLS_RSA_WITH_SEED_CBC_SHA = "SEED-SHA" + TLS_DHE_DSS_WITH_SEED_CBC_SHA = "DHE-DSS-SEED-SHA" + TLS_DHE_RSA_WITH_SEED_CBC_SHA = "DHE-RSA-SEED-SHA" + TLS_DH_anon_WITH_SEED_CBC_SHA = "ADH-SEED-SHA" + + To minimize changes between patchlevels in the OpenSSL 0.9.8 + series, SEED remains excluded from compilation unless OpenSSL + is configured with 'enable-seed'. + [KISA, Bodo Moeller] + + *) Mitigate branch prediction attacks, which can be practical if a + single processor is shared, allowing a spy process to extract + information. For detailed background information, see + http://eprint.iacr.org/2007/039 (O. Aciicmez, S. Gueron, + J.-P. Seifert, "New Branch Prediction Vulnerabilities in OpenSSL + and Necessary Software Countermeasures"). The core of the change + are new versions BN_div_no_branch() and + BN_mod_inverse_no_branch() of BN_div() and BN_mod_inverse(), + respectively, which are slower, but avoid the security-relevant + conditional branches. These are automatically called by BN_div() + and BN_mod_inverse() if the flag BN_FLG_CONSTTIME is set for one + of the input BIGNUMs. Also, BN_is_bit_set() has been changed to + remove a conditional branch. + + BN_FLG_CONSTTIME is the new name for the previous + BN_FLG_EXP_CONSTTIME flag, since it now affects more than just + modular exponentiation. (Since OpenSSL 0.9.7h, setting this flag + in the exponent causes BN_mod_exp_mont() to use the alternative + implementation in BN_mod_exp_mont_consttime().) The old name + remains as a deprecated alias. + + Similary, RSA_FLAG_NO_EXP_CONSTTIME is replaced by a more general + RSA_FLAG_NO_CONSTTIME flag since the RSA implementation now uses + constant-time implementations for more than just exponentiation. + Here too the old name is kept as a deprecated alias. + + BN_BLINDING_new() will now use BN_dup() for the modulus so that + the BN_BLINDING structure gets an independent copy of the + modulus. This means that the previous "BIGNUM *m" argument to + BN_BLINDING_new() and to BN_BLINDING_create_param() now + essentially becomes "const BIGNUM *m", although we can't actually + change this in the header file before 0.9.9. It allows + RSA_setup_blinding() to use BN_with_flags() on the modulus to + enable BN_FLG_CONSTTIME. + + [Matthew D Wood (Intel Corp)] + + *) In the SSL/TLS server implementation, be strict about session ID + context matching (which matters if an application uses a single + external cache for different purposes). Previously, + out-of-context reuse was forbidden only if SSL_VERIFY_PEER was + set. This did ensure strict client verification, but meant that, + with applications using a single external cache for quite + different requirements, clients could circumvent ciphersuite + restrictions for a given session ID context by starting a session + in a different context. + [Bodo Moeller] + + *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that + a ciphersuite string such as "DEFAULT:RSA" cannot enable + authentication-only ciphersuites. + [Bodo Moeller] + + *) Update the SSL_get_shared_ciphers() fix CVE-2006-3738 which was + not complete and could lead to a possible single byte overflow + (CVE-2007-5135) [Ben Laurie] + + Changes between 0.9.8d and 0.9.8e [23 Feb 2007] + + *) Since AES128 and AES256 (and similarly Camellia128 and + Camellia256) share a single mask bit in the logic of + ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a + kludge to work properly if AES128 is available and AES256 isn't + (or if Camellia128 is available and Camellia256 isn't). + [Victor Duchovni] + + *) Fix the BIT STRING encoding generated by crypto/ec/ec_asn1.c + (within i2d_ECPrivateKey, i2d_ECPKParameters, i2d_ECParameters): + When a point or a seed is encoded in a BIT STRING, we need to + prevent the removal of trailing zero bits to get the proper DER + encoding. (By default, crypto/asn1/a_bitstr.c assumes the case + of a NamedBitList, for which trailing 0 bits need to be removed.) + [Bodo Moeller] + + *) Have SSL/TLS server implementation tolerate "mismatched" record + protocol version while receiving ClientHello even if the + ClientHello is fragmented. (The server can't insist on the + particular protocol version it has chosen before the ServerHello + message has informed the client about his choice.) + [Bodo Moeller] + + *) Add RFC 3779 support. + [Rob Austein for ARIN, Ben Laurie] + + *) Load error codes if they are not already present instead of using a + static variable. This allows them to be cleanly unloaded and reloaded. + Improve header file function name parsing. + [Steve Henson] + + *) extend SMTP and IMAP protocol emulation in s_client to use EHLO + or CAPABILITY handshake as required by RFCs. + [Goetz Babin-Ebell] + + Changes between 0.9.8c and 0.9.8d [28 Sep 2006] + + *) Introduce limits to prevent malicious keys being able to + cause a denial of service. (CVE-2006-2940) + [Steve Henson, Bodo Moeller] + + *) Fix ASN.1 parsing of certain invalid structures that can result + in a denial of service. (CVE-2006-2937) [Steve Henson] + + *) Fix buffer overflow in SSL_get_shared_ciphers() function. + (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team] + + *) Fix SSL client code which could crash if connecting to a + malicious SSLv2 server. (CVE-2006-4343) + [Tavis Ormandy and Will Drewry, Google Security Team] + + *) Since 0.9.8b, ciphersuite strings naming explicit ciphersuites + match only those. Before that, "AES256-SHA" would be interpreted + as a pattern and match "AES128-SHA" too (since AES128-SHA got + the same strength classification in 0.9.7h) as we currently only + have a single AES bit in the ciphersuite description bitmap. + That change, however, also applied to ciphersuite strings such as + "RC4-MD5" that intentionally matched multiple ciphersuites -- + namely, SSL 2.0 ciphersuites in addition to the more common ones + from SSL 3.0/TLS 1.0. + + So we change the selection algorithm again: Naming an explicit + ciphersuite selects this one ciphersuite, and any other similar + ciphersuite (same bitmap) from *other* protocol versions. + Thus, "RC4-MD5" again will properly select both the SSL 2.0 + ciphersuite and the SSL 3.0/TLS 1.0 ciphersuite. + + Since SSL 2.0 does not have any ciphersuites for which the + 128/256 bit distinction would be relevant, this works for now. + The proper fix will be to use different bits for AES128 and + AES256, which would have avoided the problems from the beginning; + however, bits are scarce, so we can only do this in a new release + (not just a patchlevel) when we can change the SSL_CIPHER + definition to split the single 'unsigned long mask' bitmap into + multiple values to extend the available space. + + [Bodo Moeller] + + Changes between 0.9.8b and 0.9.8c [05 Sep 2006] + + *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher + (CVE-2006-4339) [Ben Laurie and Google Security Team] + + *) Add AES IGE and biIGE modes. + [Ben Laurie] + + *) Change the Unix randomness entropy gathering to use poll() when + possible instead of select(), since the latter has some + undesirable limitations. + [Darryl Miles via Richard Levitte and Bodo Moeller] + + *) Disable "ECCdraft" ciphersuites more thoroughly. Now special + treatment in ssl/ssl_ciph.s makes sure that these ciphersuites + cannot be implicitly activated as part of, e.g., the "AES" alias. + However, please upgrade to OpenSSL 0.9.9[-dev] for + non-experimental use of the ECC ciphersuites to get TLS extension + support, which is required for curve and point format negotiation + to avoid potential handshake problems. + [Bodo Moeller] + + *) Disable rogue ciphersuites: + + - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5") + - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5") + - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5") + + The latter two were purportedly from + draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really + appear there. + + Also deactivate the remaining ciphersuites from + draft-ietf-tls-56-bit-ciphersuites-01.txt. These are just as + unofficial, and the ID has long expired. + [Bodo Moeller] + + *) Fix RSA blinding Heisenbug (problems sometimes occured on + dual-core machines) and other potential thread-safety issues. + [Bodo Moeller] + + *) Add the symmetric cipher Camellia (128-bit, 192-bit, 256-bit key + versions), which is now available for royalty-free use + (see http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html). + Also, add Camellia TLS ciphersuites from RFC 4132. + + To minimize changes between patchlevels in the OpenSSL 0.9.8 + series, Camellia remains excluded from compilation unless OpenSSL + is configured with 'enable-camellia'. + [NTT] + + *) Disable the padding bug check when compression is in use. The padding + bug check assumes the first packet is of even length, this is not + necessarily true if compresssion is enabled and can result in false + positives causing handshake failure. The actual bug test is ancient + code so it is hoped that implementations will either have fixed it by + now or any which still have the bug do not support compression. + [Steve Henson] + + Changes between 0.9.8a and 0.9.8b [04 May 2006] + + *) When applying a cipher rule check to see if string match is an explicit + cipher suite and only match that one cipher suite if it is. + [Steve Henson] + + *) Link in manifests for VC++ if needed. + [Austin Ziegler ] + + *) Update support for ECC-based TLS ciphersuites according to + draft-ietf-tls-ecc-12.txt with proposed changes (but without + TLS extensions, which are supported starting with the 0.9.9 + branch, not in the OpenSSL 0.9.8 branch). + [Douglas Stebila] + + *) New functions EVP_CIPHER_CTX_new() and EVP_CIPHER_CTX_free() to support + opaque EVP_CIPHER_CTX handling. + [Steve Henson] + + *) Fixes and enhancements to zlib compression code. We now only use + "zlib1.dll" and use the default __cdecl calling convention on Win32 + to conform with the standards mentioned here: + http://www.zlib.net/DLL_FAQ.txt + Static zlib linking now works on Windows and the new --with-zlib-include + --with-zlib-lib options to Configure can be used to supply the location + of the headers and library. Gracefully handle case where zlib library + can't be loaded. + [Steve Henson] + + *) Several fixes and enhancements to the OID generation code. The old code + sometimes allowed invalid OIDs (1.X for X >= 40 for example), couldn't + handle numbers larger than ULONG_MAX, truncated printing and had a + non standard OBJ_obj2txt() behaviour. + [Steve Henson] + + *) Add support for building of engines under engine/ as shared libraries + under VC++ build system. + [Steve Henson] + + *) Corrected the numerous bugs in the Win32 path splitter in DSO. + Hopefully, we will not see any false combination of paths any more. + [Richard Levitte] + + Changes between 0.9.8 and 0.9.8a [11 Oct 2005] + + *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING + (part of SSL_OP_ALL). This option used to disable the + countermeasure against man-in-the-middle protocol-version + rollback in the SSL 2.0 server implementation, which is a bad + idea. (CVE-2005-2969) + + [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center + for Information Security, National Institute of Advanced Industrial + Science and Technology [AIST], Japan)] + + *) Add two function to clear and return the verify parameter flags. + [Steve Henson] + + *) Keep cipherlists sorted in the source instead of sorting them at + runtime, thus removing the need for a lock. + [Nils Larsch] + + *) Avoid some small subgroup attacks in Diffie-Hellman. + [Nick Mathewson and Ben Laurie] + + *) Add functions for well-known primes. + [Nick Mathewson] + + *) Extended Windows CE support. + [Satoshi Nakamura and Andy Polyakov] + + *) Initialize SSL_METHOD structures at compile time instead of during + runtime, thus removing the need for a lock. + [Steve Henson] + + *) Make PKCS7_decrypt() work even if no certificate is supplied by + attempting to decrypt each encrypted key in turn. Add support to + smime utility. + [Steve Henson] + + Changes between 0.9.7h and 0.9.8 [05 Jul 2005] + + [NB: OpenSSL 0.9.7i and later 0.9.7 patch levels were released after + OpenSSL 0.9.8.] + + *) Add libcrypto.pc and libssl.pc for those who feel they need them. + [Richard Levitte] + + *) Change CA.sh and CA.pl so they don't bundle the CSR and the private + key into the same file any more. + [Richard Levitte] + + *) Add initial support for Win64, both IA64 and AMD64/x64 flavors. + [Andy Polyakov] + + *) Add -utf8 command line and config file option to 'ca'. + [Stefan and Geoff Thorpe] + + *) Add attribute functions to EVP_PKEY structure. Modify + PKCS12_create() to recognize a CSP name attribute and + use it. Make -CSP option work again in pkcs12 utility. + [Steve Henson] + + *) Add new functionality to the bn blinding code: + - automatic re-creation of the BN_BLINDING parameters after + a fixed number of uses (currently 32) + - add new function for parameter creation + - introduce flags to control the update behaviour of the + BN_BLINDING parameters + - hide BN_BLINDING structure + Add a second BN_BLINDING slot to the RSA structure to improve + performance when a single RSA object is shared among several + threads. + [Nils Larsch] + + *) Add support for DTLS. + [Nagendra Modadugu and Ben Laurie] + + *) Add support for DER encoded private keys (SSL_FILETYPE_ASN1) + to SSL_CTX_use_PrivateKey_file() and SSL_use_PrivateKey_file() + [Walter Goulet] + + *) Remove buggy and incompletet DH cert support from + ssl/ssl_rsa.c and ssl/s3_both.c + [Nils Larsch] + + *) Use SHA-1 instead of MD5 as the default digest algorithm for + the apps/openssl applications. + [Nils Larsch] + + *) Compile clean with "-Wall -Wmissing-prototypes + -Wstrict-prototypes -Wmissing-declarations -Werror". Currently + DEBUG_SAFESTACK must also be set. + [Ben Laurie] + + *) Change ./Configure so that certain algorithms can be disabled by default. + The new counterpiece to "no-xxx" is "enable-xxx". + + The patented RC5 and MDC2 algorithms will now be disabled unless + "enable-rc5" and "enable-mdc2", respectively, are specified. + + (IDEA remains enabled despite being patented. This is because IDEA + is frequently required for interoperability, and there is no license + fee for non-commercial use. As before, "no-idea" can be used to + avoid this algorithm.) + + [Bodo Moeller] + + *) Add processing of proxy certificates (see RFC 3820). This work was + sponsored by KTH (The Royal Institute of Technology in Stockholm) and + EGEE (Enabling Grids for E-science in Europe). + [Richard Levitte] + + *) RC4 performance overhaul on modern architectures/implementations, such + as Intel P4, IA-64 and AMD64. + [Andy Polyakov] + + *) New utility extract-section.pl. This can be used specify an alternative + section number in a pod file instead of having to treat each file as + a separate case in Makefile. This can be done by adding two lines to the + pod file: + + =for comment openssl_section:XXX + + The blank line is mandatory. + + [Steve Henson] + + *) New arguments -certform, -keyform and -pass for s_client and s_server + to allow alternative format key and certificate files and passphrase + sources. + [Steve Henson] + + *) New structure X509_VERIFY_PARAM which combines current verify parameters, + update associated structures and add various utility functions. + + Add new policy related verify parameters, include policy checking in + standard verify code. Enhance 'smime' application with extra parameters + to support policy checking and print out. + [Steve Henson] + + *) Add a new engine to support VIA PadLock ACE extensions in the VIA C3 + Nehemiah processors. These extensions support AES encryption in hardware + as well as RNG (though RNG support is currently disabled). + [Michal Ludvig , with help from Andy Polyakov] + + *) Deprecate BN_[get|set]_params() functions (they were ignored internally). + [Geoff Thorpe] + + *) New FIPS 180-2 algorithms, SHA-224/-256/-384/-512 are implemented. + [Andy Polyakov and a number of other people] + + *) Improved PowerPC platform support. Most notably BIGNUM assembler + implementation contributed by IBM. + [Suresh Chari, Peter Waltenberg, Andy Polyakov] + + *) The new 'RSA_generate_key_ex' function now takes a BIGNUM for the public + exponent rather than 'unsigned long'. There is a corresponding change to + the new 'rsa_keygen' element of the RSA_METHOD structure. + [Jelte Jansen, Geoff Thorpe] + + *) Functionality for creating the initial serial number file is now + moved from CA.pl to the 'ca' utility with a new option -create_serial. + + (Before OpenSSL 0.9.7e, CA.pl used to initialize the serial + number file to 1, which is bound to cause problems. To avoid + the problems while respecting compatibility between different 0.9.7 + patchlevels, 0.9.7e employed 'openssl x509 -next_serial' in + CA.pl for serial number initialization. With the new release 0.9.8, + we can fix the problem directly in the 'ca' utility.) + [Steve Henson] + + *) Reduced header interdepencies by declaring more opaque objects in + ossl_typ.h. As a consequence, including some headers (eg. engine.h) will + give fewer recursive includes, which could break lazy source code - so + this change is covered by the OPENSSL_NO_DEPRECATED symbol. As always, + developers should define this symbol when building and using openssl to + ensure they track the recommended behaviour, interfaces, [etc], but + backwards-compatible behaviour prevails when this isn't defined. + [Geoff Thorpe] + + *) New function X509_POLICY_NODE_print() which prints out policy nodes. + [Steve Henson] + + *) Add new EVP function EVP_CIPHER_CTX_rand_key and associated functionality. + This will generate a random key of the appropriate length based on the + cipher context. The EVP_CIPHER can provide its own random key generation + routine to support keys of a specific form. This is used in the des and + 3des routines to generate a key of the correct parity. Update S/MIME + code to use new functions and hence generate correct parity DES keys. + Add EVP_CHECK_DES_KEY #define to return an error if the key is not + valid (weak or incorrect parity). + [Steve Henson] + + *) Add a local set of CRLs that can be used by X509_verify_cert() as well + as looking them up. This is useful when the verified structure may contain + CRLs, for example PKCS#7 signedData. Modify PKCS7_verify() to use any CRLs + present unless the new PKCS7_NO_CRL flag is asserted. + [Steve Henson] + + *) Extend ASN1 oid configuration module. It now additionally accepts the + syntax: + + shortName = some long name, 1.2.3.4 + [Steve Henson] + + *) Reimplemented the BN_CTX implementation. There is now no more static + limitation on the number of variables it can handle nor the depth of the + "stack" handling for BN_CTX_start()/BN_CTX_end() pairs. The stack + information can now expand as required, and rather than having a single + static array of bignums, BN_CTX now uses a linked-list of such arrays + allowing it to expand on demand whilst maintaining the usefulness of + BN_CTX's "bundling". + [Geoff Thorpe] + + *) Add a missing BN_CTX parameter to the 'rsa_mod_exp' callback in RSA_METHOD + to allow all RSA operations to function using a single BN_CTX. + [Geoff Thorpe] + + *) Preliminary support for certificate policy evaluation and checking. This + is initially intended to pass the tests outlined in "Conformance Testing + of Relying Party Client Certificate Path Processing Logic" v1.07. + [Steve Henson] + + *) bn_dup_expand() has been deprecated, it was introduced in 0.9.7 and + remained unused and not that useful. A variety of other little bignum + tweaks and fixes have also been made continuing on from the audit (see + below). + [Geoff Thorpe] + + *) Constify all or almost all d2i, c2i, s2i and r2i functions, along with + associated ASN1, EVP and SSL functions and old ASN1 macros. + [Richard Levitte] + + *) BN_zero() only needs to set 'top' and 'neg' to zero for correct results, + and this should never fail. So the return value from the use of + BN_set_word() (which can fail due to needless expansion) is now deprecated; + if OPENSSL_NO_DEPRECATED is defined, BN_zero() is a void macro. + [Geoff Thorpe] + + *) BN_CTX_get() should return zero-valued bignums, providing the same + initialised value as BN_new(). + [Geoff Thorpe, suggested by Ulf Möller] + + *) Support for inhibitAnyPolicy certificate extension. + [Steve Henson] + + *) An audit of the BIGNUM code is underway, for which debugging code is + enabled when BN_DEBUG is defined. This makes stricter enforcements on what + is considered valid when processing BIGNUMs, and causes execution to + assert() when a problem is discovered. If BN_DEBUG_RAND is defined, + further steps are taken to deliberately pollute unused data in BIGNUM + structures to try and expose faulty code further on. For now, openssl will + (in its default mode of operation) continue to tolerate the inconsistent + forms that it has tolerated in the past, but authors and packagers should + consider trying openssl and their own applications when compiled with + these debugging symbols defined. It will help highlight potential bugs in + their own code, and will improve the test coverage for OpenSSL itself. At + some point, these tighter rules will become openssl's default to improve + maintainability, though the assert()s and other overheads will remain only + in debugging configurations. See bn.h for more details. + [Geoff Thorpe, Nils Larsch, Ulf Möller] + + *) BN_CTX_init() has been deprecated, as BN_CTX is an opaque structure + that can only be obtained through BN_CTX_new() (which implicitly + initialises it). The presence of this function only made it possible + to overwrite an existing structure (and cause memory leaks). + [Geoff Thorpe] + + *) Because of the callback-based approach for implementing LHASH as a + template type, lh_insert() adds opaque objects to hash-tables and + lh_doall() or lh_doall_arg() are typically used with a destructor callback + to clean up those corresponding objects before destroying the hash table + (and losing the object pointers). So some over-zealous constifications in + LHASH have been relaxed so that lh_insert() does not take (nor store) the + objects as "const" and the lh_doall[_arg] callback wrappers are not + prototyped to have "const" restrictions on the object pointers they are + given (and so aren't required to cast them away any more). + [Geoff Thorpe] + + *) The tmdiff.h API was so ugly and minimal that our own timing utility + (speed) prefers to use its own implementation. The two implementations + haven't been consolidated as yet (volunteers?) but the tmdiff API has had + its object type properly exposed (MS_TM) instead of casting to/from "char + *". This may still change yet if someone realises MS_TM and "ms_time_***" + aren't necessarily the greatest nomenclatures - but this is what was used + internally to the implementation so I've used that for now. + [Geoff Thorpe] + + *) Ensure that deprecated functions do not get compiled when + OPENSSL_NO_DEPRECATED is defined. Some "openssl" subcommands and a few of + the self-tests were still using deprecated key-generation functions so + these have been updated also. + [Geoff Thorpe] + + *) Reorganise PKCS#7 code to separate the digest location functionality + into PKCS7_find_digest(), digest addtion into PKCS7_bio_add_digest(). + New function PKCS7_set_digest() to set the digest type for PKCS#7 + digestedData type. Add additional code to correctly generate the + digestedData type and add support for this type in PKCS7 initialization + functions. + [Steve Henson] + + *) New function PKCS7_set0_type_other() this initializes a PKCS7 + structure of type "other". + [Steve Henson] + + *) Fix prime generation loop in crypto/bn/bn_prime.pl by making + sure the loop does correctly stop and breaking ("division by zero") + modulus operations are not performed. The (pre-generated) prime + table crypto/bn/bn_prime.h was already correct, but it could not be + re-generated on some platforms because of the "division by zero" + situation in the script. + [Ralf S. Engelschall] + + *) Update support for ECC-based TLS ciphersuites according to + draft-ietf-tls-ecc-03.txt: the KDF1 key derivation function with + SHA-1 now is only used for "small" curves (where the + representation of a field element takes up to 24 bytes); for + larger curves, the field element resulting from ECDH is directly + used as premaster secret. + [Douglas Stebila (Sun Microsystems Laboratories)] + + *) Add code for kP+lQ timings to crypto/ec/ectest.c, and add SEC2 + curve secp160r1 to the tests. + [Douglas Stebila (Sun Microsystems Laboratories)] + + *) Add the possibility to load symbols globally with DSO. + [Götz Babin-Ebell via Richard Levitte] + + *) Add the functions ERR_set_mark() and ERR_pop_to_mark() for better + control of the error stack. + [Richard Levitte] + + *) Add support for STORE in ENGINE. + [Richard Levitte] + + *) Add the STORE type. The intention is to provide a common interface + to certificate and key stores, be they simple file-based stores, or + HSM-type store, or LDAP stores, or... + NOTE: The code is currently UNTESTED and isn't really used anywhere. + [Richard Levitte] + + *) Add a generic structure called OPENSSL_ITEM. This can be used to + pass a list of arguments to any function as well as provide a way + for a function to pass data back to the caller. + [Richard Levitte] + + *) Add the functions BUF_strndup() and BUF_memdup(). BUF_strndup() + works like BUF_strdup() but can be used to duplicate a portion of + a string. The copy gets NUL-terminated. BUF_memdup() duplicates + a memory area. + [Richard Levitte] + + *) Add the function sk_find_ex() which works like sk_find(), but will + return an index to an element even if an exact match couldn't be + found. The index is guaranteed to point at the element where the + searched-for key would be inserted to preserve sorting order. + [Richard Levitte] + + *) Add the function OBJ_bsearch_ex() which works like OBJ_bsearch() but + takes an extra flags argument for optional functionality. Currently, + the following flags are defined: + + OBJ_BSEARCH_VALUE_ON_NOMATCH + This one gets OBJ_bsearch_ex() to return a pointer to the first + element where the comparing function returns a negative or zero + number. + + OBJ_BSEARCH_FIRST_VALUE_ON_MATCH + This one gets OBJ_bsearch_ex() to return a pointer to the first + element where the comparing function returns zero. This is useful + if there are more than one element where the comparing function + returns zero. + [Richard Levitte] + + *) Make it possible to create self-signed certificates with 'openssl ca' + in such a way that the self-signed certificate becomes part of the + CA database and uses the same mechanisms for serial number generation + as all other certificate signing. The new flag '-selfsign' enables + this functionality. Adapt CA.sh and CA.pl.in. + [Richard Levitte] + + *) Add functionality to check the public key of a certificate request + against a given private. This is useful to check that a certificate + request can be signed by that key (self-signing). + [Richard Levitte] + + *) Make it possible to have multiple active certificates with the same + subject in the CA index file. This is done only if the keyword + 'unique_subject' is set to 'no' in the main CA section (default + if 'CA_default') of the configuration file. The value is saved + with the database itself in a separate index attribute file, + named like the index file with '.attr' appended to the name. + [Richard Levitte] + + *) Generate muti valued AVAs using '+' notation in config files for + req and dirName. + [Steve Henson] + + *) Support for nameConstraints certificate extension. + [Steve Henson] + + *) Support for policyConstraints certificate extension. + [Steve Henson] + + *) Support for policyMappings certificate extension. + [Steve Henson] + + *) Make sure the default DSA_METHOD implementation only uses its + dsa_mod_exp() and/or bn_mod_exp() handlers if they are non-NULL, + and change its own handlers to be NULL so as to remove unnecessary + indirection. This lets alternative implementations fallback to the + default implementation more easily. + [Geoff Thorpe] + + *) Support for directoryName in GeneralName related extensions + in config files. + [Steve Henson] + + *) Make it possible to link applications using Makefile.shared. + Make that possible even when linking against static libraries! + [Richard Levitte] + + *) Support for single pass processing for S/MIME signing. This now + means that S/MIME signing can be done from a pipe, in addition + cleartext signing (multipart/signed type) is effectively streaming + and the signed data does not need to be all held in memory. + + This is done with a new flag PKCS7_STREAM. When this flag is set + PKCS7_sign() only initializes the PKCS7 structure and the actual signing + is done after the data is output (and digests calculated) in + SMIME_write_PKCS7(). + [Steve Henson] + + *) Add full support for -rpath/-R, both in shared libraries and + applications, at least on the platforms where it's known how + to do it. + [Richard Levitte] + + *) In crypto/ec/ec_mult.c, implement fast point multiplication with + precomputation, based on wNAF splitting: EC_GROUP_precompute_mult() + will now compute a table of multiples of the generator that + makes subsequent invocations of EC_POINTs_mul() or EC_POINT_mul() + faster (notably in the case of a single point multiplication, + scalar * generator). + [Nils Larsch, Bodo Moeller] + + *) IPv6 support for certificate extensions. The various extensions + which use the IP:a.b.c.d can now take IPv6 addresses using the + formats of RFC1884 2.2 . IPv6 addresses are now also displayed + correctly. + [Steve Henson] + + *) Added an ENGINE that implements RSA by performing private key + exponentiations with the GMP library. The conversions to and from + GMP's mpz_t format aren't optimised nor are any montgomery forms + cached, and on x86 it appears OpenSSL's own performance has caught up. + However there are likely to be other architectures where GMP could + provide a boost. This ENGINE is not built in by default, but it can be + specified at Configure time and should be accompanied by the necessary + linker additions, eg; + ./config -DOPENSSL_USE_GMP -lgmp + [Geoff Thorpe] + + *) "openssl engine" will not display ENGINE/DSO load failure errors when + testing availability of engines with "-t" - the old behaviour is + produced by increasing the feature's verbosity with "-tt". + [Geoff Thorpe] + + *) ECDSA routines: under certain error conditions uninitialized BN objects + could be freed. Solution: make sure initialization is performed early + enough. (Reported and fix supplied by Nils Larsch + via PR#459) + [Lutz Jaenicke] + + *) Key-generation can now be implemented in RSA_METHOD, DSA_METHOD + and DH_METHOD (eg. by ENGINE implementations) to override the normal + software implementations. For DSA and DH, parameter generation can + also be overriden by providing the appropriate method callbacks. + [Geoff Thorpe] + + *) Change the "progress" mechanism used in key-generation and + primality testing to functions that take a new BN_GENCB pointer in + place of callback/argument pairs. The new API functions have "_ex" + postfixes and the older functions are reimplemented as wrappers for + the new ones. The OPENSSL_NO_DEPRECATED symbol can be used to hide + declarations of the old functions to help (graceful) attempts to + migrate to the new functions. Also, the new key-generation API + functions operate on a caller-supplied key-structure and return + success/failure rather than returning a key or NULL - this is to + help make "keygen" another member function of RSA_METHOD etc. + + Example for using the new callback interface: + + int (*my_callback)(int a, int b, BN_GENCB *cb) = ...; + void *my_arg = ...; + BN_GENCB my_cb; + + BN_GENCB_set(&my_cb, my_callback, my_arg); + + return BN_is_prime_ex(some_bignum, BN_prime_checks, NULL, &cb); + /* For the meaning of a, b in calls to my_callback(), see the + * documentation of the function that calls the callback. + * cb will point to my_cb; my_arg can be retrieved as cb->arg. + * my_callback should return 1 if it wants BN_is_prime_ex() + * to continue, or 0 to stop. + */ + + [Geoff Thorpe] + + *) Change the ZLIB compression method to be stateful, and make it + available to TLS with the number defined in + draft-ietf-tls-compression-04.txt. + [Richard Levitte] + + *) Add the ASN.1 structures and functions for CertificatePair, which + is defined as follows (according to X.509_4thEditionDraftV6.pdf): + + CertificatePair ::= SEQUENCE { + forward [0] Certificate OPTIONAL, + reverse [1] Certificate OPTIONAL, + -- at least one of the pair shall be present -- } + + Also implement the PEM functions to read and write certificate + pairs, and defined the PEM tag as "CERTIFICATE PAIR". + + This needed to be defined, mostly for the sake of the LDAP + attribute crossCertificatePair, but may prove useful elsewhere as + well. + [Richard Levitte] + + *) Make it possible to inhibit symlinking of shared libraries in + Makefile.shared, for Cygwin's sake. + [Richard Levitte] + + *) Extend the BIGNUM API by creating a function + void BN_set_negative(BIGNUM *a, int neg); + and a macro that behave like + int BN_is_negative(const BIGNUM *a); + + to avoid the need to access 'a->neg' directly in applications. + [Nils Larsch] + + *) Implement fast modular reduction for pseudo-Mersenne primes + used in NIST curves (crypto/bn/bn_nist.c, crypto/ec/ecp_nist.c). + EC_GROUP_new_curve_GFp() will now automatically use this + if applicable. + [Nils Larsch ] + + *) Add new lock type (CRYPTO_LOCK_BN). + [Bodo Moeller] + + *) Change the ENGINE framework to automatically load engines + dynamically from specific directories unless they could be + found to already be built in or loaded. Move all the + current engines except for the cryptodev one to a new + directory engines/. + The engines in engines/ are built as shared libraries if + the "shared" options was given to ./Configure or ./config. + Otherwise, they are inserted in libcrypto.a. + /usr/local/ssl/engines is the default directory for dynamic + engines, but that can be overriden at configure time through + the usual use of --prefix and/or --openssldir, and at run + time with the environment variable OPENSSL_ENGINES. + [Geoff Thorpe and Richard Levitte] + + *) Add Makefile.shared, a helper makefile to build shared + libraries. Addapt Makefile.org. + [Richard Levitte] + + *) Add version info to Win32 DLLs. + [Peter 'Luna' Runestig" ] + + *) Add new 'medium level' PKCS#12 API. Certificates and keys + can be added using this API to created arbitrary PKCS#12 + files while avoiding the low level API. + + New options to PKCS12_create(), key or cert can be NULL and + will then be omitted from the output file. The encryption + algorithm NIDs can be set to -1 for no encryption, the mac + iteration count can be set to 0 to omit the mac. + + Enhance pkcs12 utility by making the -nokeys and -nocerts + options work when creating a PKCS#12 file. New option -nomac + to omit the mac, NONE can be set for an encryption algorithm. + New code is modified to use the enhanced PKCS12_create() + instead of the low level API. + [Steve Henson] + + *) Extend ASN1 encoder to support indefinite length constructed + encoding. This can output sequences tags and octet strings in + this form. Modify pk7_asn1.c to support indefinite length + encoding. This is experimental and needs additional code to + be useful, such as an ASN1 bio and some enhanced streaming + PKCS#7 code. + + Extend template encode functionality so that tagging is passed + down to the template encoder. + [Steve Henson] + + *) Let 'openssl req' fail if an argument to '-newkey' is not + recognized instead of using RSA as a default. + [Bodo Moeller] + + *) Add support for ECC-based ciphersuites from draft-ietf-tls-ecc-01.txt. + As these are not official, they are not included in "ALL"; + the "ECCdraft" ciphersuite group alias can be used to select them. + [Vipul Gupta and Sumit Gupta (Sun Microsystems Laboratories)] + + *) Add ECDH engine support. + [Nils Gura and Douglas Stebila (Sun Microsystems Laboratories)] + + *) Add ECDH in new directory crypto/ecdh/. + [Douglas Stebila (Sun Microsystems Laboratories)] + + *) Let BN_rand_range() abort with an error after 100 iterations + without success (which indicates a broken PRNG). + [Bodo Moeller] + + *) Change BN_mod_sqrt() so that it verifies that the input value + is really the square of the return value. (Previously, + BN_mod_sqrt would show GIGO behaviour.) + [Bodo Moeller] + + *) Add named elliptic curves over binary fields from X9.62, SECG, + and WAP/WTLS; add OIDs that were still missing. + + [Sheueling Chang Shantz and Douglas Stebila + (Sun Microsystems Laboratories)] + + *) Extend the EC library for elliptic curves over binary fields + (new files ec2_smpl.c, ec2_smpt.c, ec2_mult.c in crypto/ec/). + New EC_METHOD: + + EC_GF2m_simple_method + + New API functions: + + EC_GROUP_new_curve_GF2m + EC_GROUP_set_curve_GF2m + EC_GROUP_get_curve_GF2m + EC_POINT_set_affine_coordinates_GF2m + EC_POINT_get_affine_coordinates_GF2m + EC_POINT_set_compressed_coordinates_GF2m + + Point compression for binary fields is disabled by default for + patent reasons (compile with OPENSSL_EC_BIN_PT_COMP defined to + enable it). + + As binary polynomials are represented as BIGNUMs, various members + of the EC_GROUP and EC_POINT data structures can be shared + between the implementations for prime fields and binary fields; + the above ..._GF2m functions (except for EX_GROUP_new_curve_GF2m) + are essentially identical to their ..._GFp counterparts. + (For simplicity, the '..._GFp' prefix has been dropped from + various internal method names.) + + An internal 'field_div' method (similar to 'field_mul' and + 'field_sqr') has been added; this is used only for binary fields. + + [Sheueling Chang Shantz and Douglas Stebila + (Sun Microsystems Laboratories)] + + *) Optionally dispatch EC_POINT_mul(), EC_POINT_precompute_mult() + through methods ('mul', 'precompute_mult'). + + The generic implementations (now internally called 'ec_wNAF_mul' + and 'ec_wNAF_precomputed_mult') remain the default if these + methods are undefined. + + [Sheueling Chang Shantz and Douglas Stebila + (Sun Microsystems Laboratories)] + + *) New function EC_GROUP_get_degree, which is defined through + EC_METHOD. For curves over prime fields, this returns the bit + length of the modulus. + + [Sheueling Chang Shantz and Douglas Stebila + (Sun Microsystems Laboratories)] + + *) New functions EC_GROUP_dup, EC_POINT_dup. + (These simply call ..._new and ..._copy). + + [Sheueling Chang Shantz and Douglas Stebila + (Sun Microsystems Laboratories)] + + *) Add binary polynomial arithmetic software in crypto/bn/bn_gf2m.c. + Polynomials are represented as BIGNUMs (where the sign bit is not + used) in the following functions [macros]: + + BN_GF2m_add + BN_GF2m_sub [= BN_GF2m_add] + BN_GF2m_mod [wrapper for BN_GF2m_mod_arr] + BN_GF2m_mod_mul [wrapper for BN_GF2m_mod_mul_arr] + BN_GF2m_mod_sqr [wrapper for BN_GF2m_mod_sqr_arr] + BN_GF2m_mod_inv + BN_GF2m_mod_exp [wrapper for BN_GF2m_mod_exp_arr] + BN_GF2m_mod_sqrt [wrapper for BN_GF2m_mod_sqrt_arr] + BN_GF2m_mod_solve_quad [wrapper for BN_GF2m_mod_solve_quad_arr] + BN_GF2m_cmp [= BN_ucmp] + + (Note that only the 'mod' functions are actually for fields GF(2^m). + BN_GF2m_add() is misnomer, but this is for the sake of consistency.) + + For some functions, an the irreducible polynomial defining a + field can be given as an 'unsigned int[]' with strictly + decreasing elements giving the indices of those bits that are set; + i.e., p[] represents the polynomial + f(t) = t^p[0] + t^p[1] + ... + t^p[k] + where + p[0] > p[1] > ... > p[k] = 0. + This applies to the following functions: + + BN_GF2m_mod_arr + BN_GF2m_mod_mul_arr + BN_GF2m_mod_sqr_arr + BN_GF2m_mod_inv_arr [wrapper for BN_GF2m_mod_inv] + BN_GF2m_mod_div_arr [wrapper for BN_GF2m_mod_div] + BN_GF2m_mod_exp_arr + BN_GF2m_mod_sqrt_arr + BN_GF2m_mod_solve_quad_arr + BN_GF2m_poly2arr + BN_GF2m_arr2poly + + Conversion can be performed by the following functions: + + BN_GF2m_poly2arr + BN_GF2m_arr2poly + + bntest.c has additional tests for binary polynomial arithmetic. + + Two implementations for BN_GF2m_mod_div() are available. + The default algorithm simply uses BN_GF2m_mod_inv() and + BN_GF2m_mod_mul(). The alternative algorithm is compiled in only + if OPENSSL_SUN_GF2M_DIV is defined (patent pending; read the + copyright notice in crypto/bn/bn_gf2m.c before enabling it). + + [Sheueling Chang Shantz and Douglas Stebila + (Sun Microsystems Laboratories)] + + *) Add new error code 'ERR_R_DISABLED' that can be used when some + functionality is disabled at compile-time. + [Douglas Stebila ] + + *) Change default behaviour of 'openssl asn1parse' so that more + information is visible when viewing, e.g., a certificate: + + Modify asn1_parse2 (crypto/asn1/asn1_par.c) so that in non-'dump' + mode the content of non-printable OCTET STRINGs is output in a + style similar to INTEGERs, but with '[HEX DUMP]' prepended to + avoid the appearance of a printable string. + [Nils Larsch ] + + *) Add 'asn1_flag' and 'asn1_form' member to EC_GROUP with access + functions + EC_GROUP_set_asn1_flag() + EC_GROUP_get_asn1_flag() + EC_GROUP_set_point_conversion_form() + EC_GROUP_get_point_conversion_form() + These control ASN1 encoding details: + - Curves (i.e., groups) are encoded explicitly unless asn1_flag + has been set to OPENSSL_EC_NAMED_CURVE. + - Points are encoded in uncompressed form by default; options for + asn1_for are as for point2oct, namely + POINT_CONVERSION_COMPRESSED + POINT_CONVERSION_UNCOMPRESSED + POINT_CONVERSION_HYBRID + + Also add 'seed' and 'seed_len' members to EC_GROUP with access + functions + EC_GROUP_set_seed() + EC_GROUP_get0_seed() + EC_GROUP_get_seed_len() + This is used only for ASN1 purposes (so far). + [Nils Larsch ] + + *) Add 'field_type' member to EC_METHOD, which holds the NID + of the appropriate field type OID. The new function + EC_METHOD_get_field_type() returns this value. + [Nils Larsch ] + + *) Add functions + EC_POINT_point2bn() + EC_POINT_bn2point() + EC_POINT_point2hex() + EC_POINT_hex2point() + providing useful interfaces to EC_POINT_point2oct() and + EC_POINT_oct2point(). + [Nils Larsch ] + + *) Change internals of the EC library so that the functions + EC_GROUP_set_generator() + EC_GROUP_get_generator() + EC_GROUP_get_order() + EC_GROUP_get_cofactor() + are implemented directly in crypto/ec/ec_lib.c and not dispatched + to methods, which would lead to unnecessary code duplication when + adding different types of curves. + [Nils Larsch with input by Bodo Moeller] + + *) Implement compute_wNAF (crypto/ec/ec_mult.c) without BIGNUM + arithmetic, and such that modified wNAFs are generated + (which avoid length expansion in many cases). + [Bodo Moeller] + + *) Add a function EC_GROUP_check_discriminant() (defined via + EC_METHOD) that verifies that the curve discriminant is non-zero. + + Add a function EC_GROUP_check() that makes some sanity tests + on a EC_GROUP, its generator and order. This includes + EC_GROUP_check_discriminant(). + [Nils Larsch ] + + *) Add ECDSA in new directory crypto/ecdsa/. + + Add applications 'openssl ecparam' and 'openssl ecdsa' + (these are based on 'openssl dsaparam' and 'openssl dsa'). + + ECDSA support is also included in various other files across the + library. Most notably, + - 'openssl req' now has a '-newkey ecdsa:file' option; + - EVP_PKCS82PKEY (crypto/evp/evp_pkey.c) now can handle ECDSA; + - X509_PUBKEY_get (crypto/asn1/x_pubkey.c) and + d2i_PublicKey (crypto/asn1/d2i_pu.c) have been modified to make + them suitable for ECDSA where domain parameters must be + extracted before the specific public key; + - ECDSA engine support has been added. + [Nils Larsch ] + + *) Include some named elliptic curves, and add OIDs from X9.62, + SECG, and WAP/WTLS. Each curve can be obtained from the new + function + EC_GROUP_new_by_curve_name(), + and the list of available named curves can be obtained with + EC_get_builtin_curves(). + Also add a 'curve_name' member to EC_GROUP objects, which can be + accessed via + EC_GROUP_set_curve_name() + EC_GROUP_get_curve_name() + [Nils Larsch ] + + *) Include "!eNULL" in SSL_DEFAULT_CIPHER_LIST to make sure that + a ciphersuite string such as "DEFAULT:RSA" cannot enable + authentication-only ciphersuites. + [Bodo Moeller] + + *) Since AES128 and AES256 share a single mask bit in the logic of + ssl/ssl_ciph.c, the code for masking out disabled ciphers needs a + kludge to work properly if AES128 is available and AES256 isn't. + [Victor Duchovni] + + *) Expand security boundary to match 1.1.1 module. + [Steve Henson] + + *) Remove redundant features: hash file source, editing of test vectors + modify fipsld to use external fips_premain.c signature. + [Steve Henson] + + *) New perl script mkfipsscr.pl to create shell scripts or batch files to + run algorithm test programs. + [Steve Henson] + + *) Make algorithm test programs more tolerant of whitespace. + [Steve Henson] + + *) Have SSL/TLS server implementation tolerate "mismatched" record + protocol version while receiving ClientHello even if the + ClientHello is fragmented. (The server can't insist on the + particular protocol version it has chosen before the ServerHello + message has informed the client about his choice.) + [Bodo Moeller] + + *) Load error codes if they are not already present instead of using a + static variable. This allows them to be cleanly unloaded and reloaded. + [Steve Henson] + + Changes between 0.9.7k and 0.9.7l [28 Sep 2006] + + *) Introduce limits to prevent malicious keys being able to + cause a denial of service. (CVE-2006-2940) + [Steve Henson, Bodo Moeller] + + *) Fix ASN.1 parsing of certain invalid structures that can result + in a denial of service. (CVE-2006-2937) [Steve Henson] + + *) Fix buffer overflow in SSL_get_shared_ciphers() function. + (CVE-2006-3738) [Tavis Ormandy and Will Drewry, Google Security Team] + + *) Fix SSL client code which could crash if connecting to a + malicious SSLv2 server. (CVE-2006-4343) + [Tavis Ormandy and Will Drewry, Google Security Team] + + *) Change ciphersuite string processing so that an explicit + ciphersuite selects this one ciphersuite (so that "AES256-SHA" + will no longer include "AES128-SHA"), and any other similar + ciphersuite (same bitmap) from *other* protocol versions (so that + "RC4-MD5" will still include both the SSL 2.0 ciphersuite and the + SSL 3.0/TLS 1.0 ciphersuite). This is a backport combining + changes from 0.9.8b and 0.9.8d. + [Bodo Moeller] + + Changes between 0.9.7j and 0.9.7k [05 Sep 2006] + + *) Avoid PKCS #1 v1.5 signature attack discovered by Daniel Bleichenbacher + (CVE-2006-4339) [Ben Laurie and Google Security Team] + + *) Change the Unix randomness entropy gathering to use poll() when + possible instead of select(), since the latter has some + undesirable limitations. + [Darryl Miles via Richard Levitte and Bodo Moeller] + + *) Disable rogue ciphersuites: + + - SSLv2 0x08 0x00 0x80 ("RC4-64-MD5") + - SSLv3/TLSv1 0x00 0x61 ("EXP1024-RC2-CBC-MD5") + - SSLv3/TLSv1 0x00 0x60 ("EXP1024-RC4-MD5") + + The latter two were purportedly from + draft-ietf-tls-56-bit-ciphersuites-0[01].txt, but do not really + appear there. + + Also deactive the remaining ciphersuites from + draft-ietf-tls-56-bit-ciphersuites-01.txt. These are just as + unofficial, and the ID has long expired. + [Bodo Moeller] + + *) Fix RSA blinding Heisenbug (problems sometimes occured on + dual-core machines) and other potential thread-safety issues. + [Bodo Moeller] + + Changes between 0.9.7i and 0.9.7j [04 May 2006] + + *) Adapt fipsld and the build system to link against the validated FIPS + module in FIPS mode. + [Steve Henson] + + *) Fixes for VC++ 2005 build under Windows. + [Steve Henson] + + *) Add new Windows build target VC-32-GMAKE for VC++. This uses GNU make + from a Windows bash shell such as MSYS. It is autodetected from the + "config" script when run from a VC++ environment. Modify standard VC++ + build to use fipscanister.o from the GNU make build. + [Steve Henson] + + Changes between 0.9.7h and 0.9.7i [14 Oct 2005] + + *) Wrapped the definition of EVP_MAX_MD_SIZE in a #ifdef OPENSSL_FIPS. + The value now differs depending on if you build for FIPS or not. + BEWARE! A program linked with a shared FIPSed libcrypto can't be + safely run with a non-FIPSed libcrypto, as it may crash because of + the difference induced by this change. + [Andy Polyakov] + + Changes between 0.9.7g and 0.9.7h [11 Oct 2005] + + *) Remove the functionality of SSL_OP_MSIE_SSLV2_RSA_PADDING + (part of SSL_OP_ALL). This option used to disable the + countermeasure against man-in-the-middle protocol-version + rollback in the SSL 2.0 server implementation, which is a bad + idea. (CVE-2005-2969) + + [Bodo Moeller; problem pointed out by Yutaka Oiwa (Research Center + for Information Security, National Institute of Advanced Industrial + Science and Technology [AIST], Japan)] + + *) Minimal support for X9.31 signatures and PSS padding modes. This is + mainly for FIPS compliance and not fully integrated at this stage. + [Steve Henson] + + *) For DSA signing, unless DSA_FLAG_NO_EXP_CONSTTIME is set, perform + the exponentiation using a fixed-length exponent. (Otherwise, + the information leaked through timing could expose the secret key + after many signatures; cf. Bleichenbacher's attack on DSA with + biased k.) + [Bodo Moeller] + + *) Make a new fixed-window mod_exp implementation the default for + RSA, DSA, and DH private-key operations so that the sequence of + squares and multiplies and the memory access pattern are + independent of the particular secret key. This will mitigate + cache-timing and potential related attacks. + + BN_mod_exp_mont_consttime() is the new exponentiation implementation, + and this is automatically used by BN_mod_exp_mont() if the new flag + BN_FLG_EXP_CONSTTIME is set for the exponent. RSA, DSA, and DH + will use this BN flag for private exponents unless the flag + RSA_FLAG_NO_EXP_CONSTTIME, DSA_FLAG_NO_EXP_CONSTTIME, or + DH_FLAG_NO_EXP_CONSTTIME, respectively, is set. + + [Matthew D Wood (Intel Corp), with some changes by Bodo Moeller] + + *) Change the client implementation for SSLv23_method() and + SSLv23_client_method() so that is uses the SSL 3.0/TLS 1.0 + Client Hello message format if the SSL_OP_NO_SSLv2 option is set. + (Previously, the SSL 2.0 backwards compatible Client Hello + message format would be used even with SSL_OP_NO_SSLv2.) + [Bodo Moeller] + + *) Add support for smime-type MIME parameter in S/MIME messages which some + clients need. + [Steve Henson] + + *) New function BN_MONT_CTX_set_locked() to set montgomery parameters in + a threadsafe manner. Modify rsa code to use new function and add calls + to dsa and dh code (which had race conditions before). + [Steve Henson] + + *) Include the fixed error library code in the C error file definitions + instead of fixing them up at runtime. This keeps the error code + structures constant. + [Steve Henson] + + Changes between 0.9.7f and 0.9.7g [11 Apr 2005] + + [NB: OpenSSL 0.9.7h and later 0.9.7 patch levels were released after + OpenSSL 0.9.8.] + + *) Fixes for newer kerberos headers. NB: the casts are needed because + the 'length' field is signed on one version and unsigned on another + with no (?) obvious way to tell the difference, without these VC++ + complains. Also the "definition" of FAR (blank) is no longer included + nor is the error ENOMEM. KRB5_PRIVATE has to be set to 1 to pick up + some needed definitions. + [Steve Henson] + + *) Undo Cygwin change. + [Ulf Möller] + + *) Added support for proxy certificates according to RFC 3820. + Because they may be a security thread to unaware applications, + they must be explicitely allowed in run-time. See + docs/HOWTO/proxy_certificates.txt for further information. + [Richard Levitte] + + Changes between 0.9.7e and 0.9.7f [22 Mar 2005] + + *) Use (SSL_RANDOM_VALUE - 4) bytes of pseudo random data when generating + server and client random values. Previously + (SSL_RANDOM_VALUE - sizeof(time_t)) would be used which would result in + less random data when sizeof(time_t) > 4 (some 64 bit platforms). + + This change has negligible security impact because: + + 1. Server and client random values still have 24 bytes of pseudo random + data. + + 2. Server and client random values are sent in the clear in the initial + handshake. + + 3. The master secret is derived using the premaster secret (48 bytes in + size for static RSA ciphersuites) as well as client server and random + values. + + The OpenSSL team would like to thank the UK NISCC for bringing this issue + to our attention. + + [Stephen Henson, reported by UK NISCC] + + *) Use Windows randomness collection on Cygwin. + [Ulf Möller] + + *) Fix hang in EGD/PRNGD query when communication socket is closed + prematurely by EGD/PRNGD. + [Darren Tucker via Lutz Jänicke, resolves #1014] + + *) Prompt for pass phrases when appropriate for PKCS12 input format. + [Steve Henson] + + *) Back-port of selected performance improvements from development + branch, as well as improved support for PowerPC platforms. + [Andy Polyakov] + + *) Add lots of checks for memory allocation failure, error codes to indicate + failure and freeing up memory if a failure occurs. + [Nauticus Networks SSL Team , Steve Henson] + + *) Add new -passin argument to dgst. + [Steve Henson] + + *) Perform some character comparisons of different types in X509_NAME_cmp: + this is needed for some certificates that reencode DNs into UTF8Strings + (in violation of RFC3280) and can't or wont issue name rollover + certificates. + [Steve Henson] + + *) Make an explicit check during certificate validation to see that + the CA setting in each certificate on the chain is correct. As a + side effect always do the following basic checks on extensions, + not just when there's an associated purpose to the check: + + - if there is an unhandled critical extension (unless the user + has chosen to ignore this fault) + - if the path length has been exceeded (if one is set at all) + - that certain extensions fit the associated purpose (if one has + been given) + [Richard Levitte] + + Changes between 0.9.7d and 0.9.7e [25 Oct 2004] + + *) Avoid a race condition when CRLs are checked in a multi threaded + environment. This would happen due to the reordering of the revoked + entries during signature checking and serial number lookup. Now the + encoding is cached and the serial number sort performed under a lock. + Add new STACK function sk_is_sorted(). + [Steve Henson] + + *) Add Delta CRL to the extension code. + [Steve Henson] + + *) Various fixes to s3_pkt.c so alerts are sent properly. + [David Holmes ] + + *) Reduce the chances of duplicate issuer name and serial numbers (in + violation of RFC3280) using the OpenSSL certificate creation utilities. + This is done by creating a random 64 bit value for the initial serial + number when a serial number file is created or when a self signed + certificate is created using 'openssl req -x509'. The initial serial + number file is created using 'openssl x509 -next_serial' in CA.pl + rather than being initialized to 1. + [Steve Henson] + + Changes between 0.9.7c and 0.9.7d [17 Mar 2004] + + *) Fix null-pointer assignment in do_change_cipher_spec() revealed + by using the Codenomicon TLS Test Tool (CVE-2004-0079) + [Joe Orton, Steve Henson] + + *) Fix flaw in SSL/TLS handshaking when using Kerberos ciphersuites + (CVE-2004-0112) + [Joe Orton, Steve Henson] + + *) Make it possible to have multiple active certificates with the same + subject in the CA index file. This is done only if the keyword + 'unique_subject' is set to 'no' in the main CA section (default + if 'CA_default') of the configuration file. The value is saved + with the database itself in a separate index attribute file, + named like the index file with '.attr' appended to the name. + [Richard Levitte] + + *) X509 verify fixes. Disable broken certificate workarounds when + X509_V_FLAGS_X509_STRICT is set. Check CRL issuer has cRLSign set if + keyUsage extension present. Don't accept CRLs with unhandled critical + extensions: since verify currently doesn't process CRL extensions this + rejects a CRL with *any* critical extensions. Add new verify error codes + for these cases. + [Steve Henson] + + *) When creating an OCSP nonce use an OCTET STRING inside the extnValue. + A clarification of RFC2560 will require the use of OCTET STRINGs and + some implementations cannot handle the current raw format. Since OpenSSL + copies and compares OCSP nonces as opaque blobs without any attempt at + parsing them this should not create any compatibility issues. + [Steve Henson] + + *) New md flag EVP_MD_CTX_FLAG_REUSE this allows md_data to be reused when + calling EVP_MD_CTX_copy_ex() to avoid calling OPENSSL_malloc(). Without + this HMAC (and other) operations are several times slower than OpenSSL + < 0.9.7. + [Steve Henson] + + *) Print out GeneralizedTime and UTCTime in ASN1_STRING_print_ex(). + [Peter Sylvester ] + + *) Use the correct content when signing type "other". + [Steve Henson] + + Changes between 0.9.7b and 0.9.7c [30 Sep 2003] + + *) Fix various bugs revealed by running the NISCC test suite: + + Stop out of bounds reads in the ASN1 code when presented with + invalid tags (CVE-2003-0543 and CVE-2003-0544). + + Free up ASN1_TYPE correctly if ANY type is invalid (CVE-2003-0545). + + If verify callback ignores invalid public key errors don't try to check + certificate signature with the NULL public key. + + [Steve Henson] + + *) New -ignore_err option in ocsp application to stop the server + exiting on the first error in a request. + [Steve Henson] + + *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate + if the server requested one: as stated in TLS 1.0 and SSL 3.0 + specifications. + [Steve Henson] + + *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional + extra data after the compression methods not only for TLS 1.0 + but also for SSL 3.0 (as required by the specification). + [Bodo Moeller; problem pointed out by Matthias Loepfe] + + *) Change X509_certificate_type() to mark the key as exported/exportable + when it's 512 *bits* long, not 512 bytes. + [Richard Levitte] + + *) Change AES_cbc_encrypt() so it outputs exact multiple of + blocks during encryption. + [Richard Levitte] + + *) Various fixes to base64 BIO and non blocking I/O. On write + flushes were not handled properly if the BIO retried. On read + data was not being buffered properly and had various logic bugs. + This also affects blocking I/O when the data being decoded is a + certain size. + [Steve Henson] + + *) Various S/MIME bugfixes and compatibility changes: + output correct application/pkcs7 MIME type if + PKCS7_NOOLDMIMETYPE is set. Tolerate some broken signatures. + Output CR+LF for EOL if PKCS7_CRLFEOL is set (this makes opening + of files as .eml work). Correctly handle very long lines in MIME + parser. + [Steve Henson] + + Changes between 0.9.7a and 0.9.7b [10 Apr 2003] + + *) Countermeasure against the Klima-Pokorny-Rosa extension of + Bleichbacher's attack on PKCS #1 v1.5 padding: treat + a protocol version number mismatch like a decryption error + in ssl3_get_client_key_exchange (ssl/s3_srvr.c). + [Bodo Moeller] + + *) Turn on RSA blinding by default in the default implementation + to avoid a timing attack. Applications that don't want it can call + RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING. + They would be ill-advised to do so in most cases. + [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller] + + *) Change RSA blinding code so that it works when the PRNG is not + seeded (in this case, the secret RSA exponent is abused as + an unpredictable seed -- if it is not unpredictable, there + is no point in blinding anyway). Make RSA blinding thread-safe + by remembering the creator's thread ID in rsa->blinding and + having all other threads use local one-time blinding factors + (this requires more computation than sharing rsa->blinding, but + avoids excessive locking; and if an RSA object is not shared + between threads, blinding will still be very fast). + [Bodo Moeller] + + *) Fixed a typo bug that would cause ENGINE_set_default() to set an + ENGINE as defaults for all supported algorithms irrespective of + the 'flags' parameter. 'flags' is now honoured, so applications + should make sure they are passing it correctly. + [Geoff Thorpe] + + *) Target "mingw" now allows native Windows code to be generated in + the Cygwin environment as well as with the MinGW compiler. + [Ulf Moeller] + + Changes between 0.9.7 and 0.9.7a [19 Feb 2003] + + *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked + via timing by performing a MAC computation even if incorrrect + block cipher padding has been found. This is a countermeasure + against active attacks where the attacker has to distinguish + between bad padding and a MAC verification error. (CVE-2003-0078) + + [Bodo Moeller; problem pointed out by Brice Canvel (EPFL), + Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and + Martin Vuagnoux (EPFL, Ilion)] + + *) Make the no-err option work as intended. The intention with no-err + is not to have the whole error stack handling routines removed from + libcrypto, it's only intended to remove all the function name and + reason texts, thereby removing some of the footprint that may not + be interesting if those errors aren't displayed anyway. + + NOTE: it's still possible for any application or module to have it's + own set of error texts inserted. The routines are there, just not + used by default when no-err is given. + [Richard Levitte] + + *) Add support for FreeBSD on IA64. + [dirk.meyer@dinoex.sub.org via Richard Levitte, resolves #454] + + *) Adjust DES_cbc_cksum() so it returns the same value as the MIT + Kerberos function mit_des_cbc_cksum(). Before this change, + the value returned by DES_cbc_cksum() was like the one from + mit_des_cbc_cksum(), except the bytes were swapped. + [Kevin Greaney and Richard Levitte] + + *) Allow an application to disable the automatic SSL chain building. + Before this a rather primitive chain build was always performed in + ssl3_output_cert_chain(): an application had no way to send the + correct chain if the automatic operation produced an incorrect result. + + Now the chain builder is disabled if either: + + 1. Extra certificates are added via SSL_CTX_add_extra_chain_cert(). + + 2. The mode flag SSL_MODE_NO_AUTO_CHAIN is set. + + The reasoning behind this is that an application would not want the + auto chain building to take place if extra chain certificates are + present and it might also want a means of sending no additional + certificates (for example the chain has two certificates and the + root is omitted). + [Steve Henson] + + *) Add the possibility to build without the ENGINE framework. + [Steven Reddie via Richard Levitte] + + *) Under Win32 gmtime() can return NULL: check return value in + OPENSSL_gmtime(). Add error code for case where gmtime() fails. + [Steve Henson] + + *) DSA routines: under certain error conditions uninitialized BN objects + could be freed. Solution: make sure initialization is performed early + enough. (Reported and fix supplied by Ivan D Nestlerode , + Nils Larsch via PR#459) + [Lutz Jaenicke] + + *) Another fix for SSLv2 session ID handling: the session ID was incorrectly + checked on reconnect on the client side, therefore session resumption + could still fail with a "ssl session id is different" error. This + behaviour is masked when SSL_OP_ALL is used due to + SSL_OP_MICROSOFT_SESS_ID_BUG being set. + Behaviour observed by Crispin Flowerday as + followup to PR #377. + [Lutz Jaenicke] + + *) IA-32 assembler support enhancements: unified ELF targets, support + for SCO/Caldera platforms, fix for Cygwin shared build. + [Andy Polyakov] + + *) Add support for FreeBSD on sparc64. As a consequence, support for + FreeBSD on non-x86 processors is separate from x86 processors on + the config script, much like the NetBSD support. + [Richard Levitte & Kris Kennaway ] + + Changes between 0.9.6h and 0.9.7 [31 Dec 2002] + + [NB: OpenSSL 0.9.6i and later 0.9.6 patch levels were released after + OpenSSL 0.9.7.] + + *) Fix session ID handling in SSLv2 client code: the SERVER FINISHED + code (06) was taken as the first octet of the session ID and the last + octet was ignored consequently. As a result SSLv2 client side session + caching could not have worked due to the session ID mismatch between + client and server. + Behaviour observed by Crispin Flowerday as + PR #377. + [Lutz Jaenicke] + + *) Change the declaration of needed Kerberos libraries to use EX_LIBS + instead of the special (and badly supported) LIBKRB5. LIBKRB5 is + removed entirely. + [Richard Levitte] + + *) The hw_ncipher.c engine requires dynamic locks. Unfortunately, it + seems that in spite of existing for more than a year, many application + author have done nothing to provide the necessary callbacks, which + means that this particular engine will not work properly anywhere. + This is a very unfortunate situation which forces us, in the name + of usability, to give the hw_ncipher.c a static lock, which is part + of libcrypto. + NOTE: This is for the 0.9.7 series ONLY. This hack will never + appear in 0.9.8 or later. We EXPECT application authors to have + dealt properly with this when 0.9.8 is released (unless we actually + make such changes in the libcrypto locking code that changes will + have to be made anyway). + [Richard Levitte] + + *) In asn1_d2i_read_bio() repeatedly call BIO_read() until all content + octets have been read, EOF or an error occurs. Without this change + some truncated ASN1 structures will not produce an error. + [Steve Henson] + + *) Disable Heimdal support, since it hasn't been fully implemented. + Still give the possibility to force the use of Heimdal, but with + warnings and a request that patches get sent to openssl-dev. + [Richard Levitte] + + *) Add the VC-CE target, introduce the WINCE sysname, and add + INSTALL.WCE and appropriate conditionals to make it build. + [Steven Reddie via Richard Levitte] + + *) Change the DLL names for Cygwin to cygcrypto-x.y.z.dll and + cygssl-x.y.z.dll, where x, y and z are the major, minor and + edit numbers of the version. + [Corinna Vinschen and Richard Levitte] + + *) Introduce safe string copy and catenation functions + (BUF_strlcpy() and BUF_strlcat()). + [Ben Laurie (CHATS) and Richard Levitte] + + *) Avoid using fixed-size buffers for one-line DNs. + [Ben Laurie (CHATS)] + + *) Add BUF_MEM_grow_clean() to avoid information leakage when + resizing buffers containing secrets, and use where appropriate. + [Ben Laurie (CHATS)] + + *) Avoid using fixed size buffers for configuration file location. + [Ben Laurie (CHATS)] + + *) Avoid filename truncation for various CA files. + [Ben Laurie (CHATS)] + + *) Use sizeof in preference to magic numbers. + [Ben Laurie (CHATS)] + + *) Avoid filename truncation in cert requests. + [Ben Laurie (CHATS)] + + *) Add assertions to check for (supposedly impossible) buffer + overflows. + [Ben Laurie (CHATS)] + + *) Don't cache truncated DNS entries in the local cache (this could + potentially lead to a spoofing attack). + [Ben Laurie (CHATS)] + + *) Fix various buffers to be large enough for hex/decimal + representations in a platform independent manner. + [Ben Laurie (CHATS)] + + *) Add CRYPTO_realloc_clean() to avoid information leakage when + resizing buffers containing secrets, and use where appropriate. + [Ben Laurie (CHATS)] + + *) Add BIO_indent() to avoid much slightly worrying code to do + indents. + [Ben Laurie (CHATS)] + + *) Convert sprintf()/BIO_puts() to BIO_printf(). + [Ben Laurie (CHATS)] + + *) buffer_gets() could terminate with the buffer only half + full. Fixed. + [Ben Laurie (CHATS)] + + *) Add assertions to prevent user-supplied crypto functions from + overflowing internal buffers by having large block sizes, etc. + [Ben Laurie (CHATS)] + + *) New OPENSSL_assert() macro (similar to assert(), but enabled + unconditionally). + [Ben Laurie (CHATS)] + + *) Eliminate unused copy of key in RC4. + [Ben Laurie (CHATS)] + + *) Eliminate unused and incorrectly sized buffers for IV in pem.h. + [Ben Laurie (CHATS)] + + *) Fix off-by-one error in EGD path. + [Ben Laurie (CHATS)] + + *) If RANDFILE path is too long, ignore instead of truncating. + [Ben Laurie (CHATS)] + + *) Eliminate unused and incorrectly sized X.509 structure + CBCParameter. + [Ben Laurie (CHATS)] + + *) Eliminate unused and dangerous function knumber(). + [Ben Laurie (CHATS)] + + *) Eliminate unused and dangerous structure, KSSL_ERR. + [Ben Laurie (CHATS)] + + *) Protect against overlong session ID context length in an encoded + session object. Since these are local, this does not appear to be + exploitable. + [Ben Laurie (CHATS)] + + *) Change from security patch (see 0.9.6e below) that did not affect + the 0.9.6 release series: + + Remote buffer overflow in SSL3 protocol - an attacker could + supply an oversized master key in Kerberos-enabled versions. + (CVE-2002-0657) + [Ben Laurie (CHATS)] + + *) Change the SSL kerb5 codes to match RFC 2712. + [Richard Levitte] + + *) Make -nameopt work fully for req and add -reqopt switch. + [Michael Bell , Steve Henson] + + *) The "block size" for block ciphers in CFB and OFB mode should be 1. + [Steve Henson, reported by Yngve Nysaeter Pettersen ] + + *) Make sure tests can be performed even if the corresponding algorithms + have been removed entirely. This was also the last step to make + OpenSSL compilable with DJGPP under all reasonable conditions. + [Richard Levitte, Doug Kaufman ] + + *) Add cipher selection rules COMPLEMENTOFALL and COMPLEMENTOFDEFAULT + to allow version independent disabling of normally unselected ciphers, + which may be activated as a side-effect of selecting a single cipher. + + (E.g., cipher list string "RSA" enables ciphersuites that are left + out of "ALL" because they do not provide symmetric encryption. + "RSA:!COMPLEMEMENTOFALL" avoids these unsafe ciphersuites.) + [Lutz Jaenicke, Bodo Moeller] + + *) Add appropriate support for separate platform-dependent build + directories. The recommended way to make a platform-dependent + build directory is the following (tested on Linux), maybe with + some local tweaks: + + # Place yourself outside of the OpenSSL source tree. In + # this example, the environment variable OPENSSL_SOURCE + # is assumed to contain the absolute OpenSSL source directory. + mkdir -p objtree/"`uname -s`-`uname -r`-`uname -m`" + cd objtree/"`uname -s`-`uname -r`-`uname -m`" + (cd $OPENSSL_SOURCE; find . -type f) | while read F; do + mkdir -p `dirname $F` + ln -s $OPENSSL_SOURCE/$F $F + done + + To be absolutely sure not to disturb the source tree, a "make clean" + is a good thing. If it isn't successfull, don't worry about it, + it probably means the source directory is very clean. + [Richard Levitte] + + *) Make sure any ENGINE control commands make local copies of string + pointers passed to them whenever necessary. Otherwise it is possible + the caller may have overwritten (or deallocated) the original string + data when a later ENGINE operation tries to use the stored values. + [Götz Babin-Ebell ] + + *) Improve diagnostics in file reading and command-line digests. + [Ben Laurie aided and abetted by Solar Designer ] + + *) Add AES modes CFB and OFB to the object database. Correct an + error in AES-CFB decryption. + [Richard Levitte] + + *) Remove most calls to EVP_CIPHER_CTX_cleanup() in evp_enc.c, this + allows existing EVP_CIPHER_CTX structures to be reused after + calling EVP_*Final(). This behaviour is used by encryption + BIOs and some applications. This has the side effect that + applications must explicitly clean up cipher contexts with + EVP_CIPHER_CTX_cleanup() or they will leak memory. + [Steve Henson] + + *) Check the values of dna and dnb in bn_mul_recursive before calling + bn_mul_comba (a non zero value means the a or b arrays do not contain + n2 elements) and fallback to bn_mul_normal if either is not zero. + [Steve Henson] + + *) Fix escaping of non-ASCII characters when using the -subj option + of the "openssl req" command line tool. (Robert Joop ) + [Lutz Jaenicke] + + *) Make object definitions compliant to LDAP (RFC2256): SN is the short + form for "surname", serialNumber has no short form. + Use "mail" as the short name for "rfc822Mailbox" according to RFC2798; + therefore remove "mail" short name for "internet 7". + The OID for unique identifiers in X509 certificates is + x500UniqueIdentifier, not uniqueIdentifier. + Some more OID additions. (Michael Bell ) + [Lutz Jaenicke] + + *) Add an "init" command to the ENGINE config module and auto initialize + ENGINEs. Without any "init" command the ENGINE will be initialized + after all ctrl commands have been executed on it. If init=1 the + ENGINE is initailized at that point (ctrls before that point are run + on the uninitialized ENGINE and after on the initialized one). If + init=0 then the ENGINE will not be iniatialized at all. + [Steve Henson] + + *) Fix the 'app_verify_callback' interface so that the user-defined + argument is actually passed to the callback: In the + SSL_CTX_set_cert_verify_callback() prototype, the callback + declaration has been changed from + int (*cb)() + into + int (*cb)(X509_STORE_CTX *,void *); + in ssl_verify_cert_chain (ssl/ssl_cert.c), the call + i=s->ctx->app_verify_callback(&ctx) + has been changed into + i=s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg). + + To update applications using SSL_CTX_set_cert_verify_callback(), + a dummy argument can be added to their callback functions. + [D. K. Smetters ] + + *) Added the '4758cca' ENGINE to support IBM 4758 cards. + [Maurice Gittens , touchups by Geoff Thorpe] + + *) Add and OPENSSL_LOAD_CONF define which will cause + OpenSSL_add_all_algorithms() to load the openssl.cnf config file. + This allows older applications to transparently support certain + OpenSSL features: such as crypto acceleration and dynamic ENGINE loading. + Two new functions OPENSSL_add_all_algorithms_noconf() which will never + load the config file and OPENSSL_add_all_algorithms_conf() which will + always load it have also been added. + [Steve Henson] + + *) Add the OFB, CFB and CTR (all with 128 bit feedback) to AES. + Adjust NIDs and EVP layer. + [Stephen Sprunk and Richard Levitte] + + *) Config modules support in openssl utility. + + Most commands now load modules from the config file, + though in a few (such as version) this isn't done + because it couldn't be used for anything. + + In the case of ca and req the config file used is + the same as the utility itself: that is the -config + command line option can be used to specify an + alternative file. + [Steve Henson] + + *) Move default behaviour from OPENSSL_config(). If appname is NULL + use "openssl_conf" if filename is NULL use default openssl config file. + [Steve Henson] + + *) Add an argument to OPENSSL_config() to allow the use of an alternative + config section name. Add a new flag to tolerate a missing config file + and move code to CONF_modules_load_file(). + [Steve Henson] + + *) Support for crypto accelerator cards from Accelerated Encryption + Processing, www.aep.ie. (Use engine 'aep') + The support was copied from 0.9.6c [engine] and adapted/corrected + to work with the new engine framework. + [AEP Inc. and Richard Levitte] + + *) Support for SureWare crypto accelerator cards from Baltimore + Technologies. (Use engine 'sureware') + The support was copied from 0.9.6c [engine] and adapted + to work with the new engine framework. + [Richard Levitte] + + *) Have the CHIL engine fork-safe (as defined by nCipher) and actually + make the newer ENGINE framework commands for the CHIL engine work. + [Toomas Kiisk and Richard Levitte] + + *) Make it possible to produce shared libraries on ReliantUNIX. + [Robert Dahlem via Richard Levitte] + + *) Add the configuration target debug-linux-ppro. + Make 'openssl rsa' use the general key loading routines + implemented in apps.c, and make those routines able to + handle the key format FORMAT_NETSCAPE and the variant + FORMAT_IISSGC. + [Toomas Kiisk via Richard Levitte] + + *) Fix a crashbug and a logic bug in hwcrhk_load_pubkey(). + [Toomas Kiisk via Richard Levitte] + + *) Add -keyform to rsautl, and document -engine. + [Richard Levitte, inspired by Toomas Kiisk ] + + *) Change BIO_new_file (crypto/bio/bss_file.c) to use new + BIO_R_NO_SUCH_FILE error code rather than the generic + ERR_R_SYS_LIB error code if fopen() fails with ENOENT. + [Ben Laurie] + + *) Add new functions + ERR_peek_last_error + ERR_peek_last_error_line + ERR_peek_last_error_line_data. + These are similar to + ERR_peek_error + ERR_peek_error_line + ERR_peek_error_line_data, + but report on the latest error recorded rather than the first one + still in the error queue. + [Ben Laurie, Bodo Moeller] + + *) default_algorithms option in ENGINE config module. This allows things + like: + default_algorithms = ALL + default_algorithms = RSA, DSA, RAND, CIPHERS, DIGESTS + [Steve Henson] + + *) Prelminary ENGINE config module. + [Steve Henson] + + *) New experimental application configuration code. + [Steve Henson] + + *) Change the AES code to follow the same name structure as all other + symmetric ciphers, and behave the same way. Move everything to + the directory crypto/aes, thereby obsoleting crypto/rijndael. + [Stephen Sprunk and Richard Levitte] + + *) SECURITY: remove unsafe setjmp/signal interaction from ui_openssl.c. + [Ben Laurie and Theo de Raadt] + + *) Add option to output public keys in req command. + [Massimiliano Pala madwolf@openca.org] + + *) Use wNAFs in EC_POINTs_mul() for improved efficiency + (up to about 10% better than before for P-192 and P-224). + [Bodo Moeller] + + *) New functions/macros + + SSL_CTX_set_msg_callback(ctx, cb) + SSL_CTX_set_msg_callback_arg(ctx, arg) + SSL_set_msg_callback(ssl, cb) + SSL_set_msg_callback_arg(ssl, arg) + + to request calling a callback function + + void cb(int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg) + + whenever a protocol message has been completely received + (write_p == 0) or sent (write_p == 1). Here 'version' is the + protocol version according to which the SSL library interprets + the current protocol message (SSL2_VERSION, SSL3_VERSION, or + TLS1_VERSION). 'content_type' is 0 in the case of SSL 2.0, or + the content type as defined in the SSL 3.0/TLS 1.0 protocol + specification (change_cipher_spec(20), alert(21), handshake(22)). + 'buf' and 'len' point to the actual message, 'ssl' to the + SSL object, and 'arg' is the application-defined value set by + SSL[_CTX]_set_msg_callback_arg(). + + 'openssl s_client' and 'openssl s_server' have new '-msg' options + to enable a callback that displays all protocol messages. + [Bodo Moeller] + + *) Change the shared library support so shared libraries are built as + soon as the corresponding static library is finished, and thereby get + openssl and the test programs linked against the shared library. + This still only happens when the keyword "shard" has been given to + the configuration scripts. + + NOTE: shared library support is still an experimental thing, and + backward binary compatibility is still not guaranteed. + ["Maciej W. Rozycki" and Richard Levitte] + + *) Add support for Subject Information Access extension. + [Peter Sylvester ] + + *) Make BUF_MEM_grow() behaviour more consistent: Initialise to zero + additional bytes when new memory had to be allocated, not just + when reusing an existing buffer. + [Bodo Moeller] + + *) New command line and configuration option 'utf8' for the req command. + This allows field values to be specified as UTF8 strings. + [Steve Henson] + + *) Add -multi and -mr options to "openssl speed" - giving multiple parallel + runs for the former and machine-readable output for the latter. + [Ben Laurie] + + *) Add '-noemailDN' option to 'openssl ca'. This prevents inclusion + of the e-mail address in the DN (i.e., it will go into a certificate + extension only). The new configuration file option 'email_in_dn = no' + has the same effect. + [Massimiliano Pala madwolf@openca.org] + + *) Change all functions with names starting with des_ to be starting + with DES_ instead. Add wrappers that are compatible with libdes, + but are named _ossl_old_des_*. Finally, add macros that map the + des_* symbols to the corresponding _ossl_old_des_* if libdes + compatibility is desired. If OpenSSL 0.9.6c compatibility is + desired, the des_* symbols will be mapped to DES_*, with one + exception. + + Since we provide two compatibility mappings, the user needs to + define the macro OPENSSL_DES_LIBDES_COMPATIBILITY if libdes + compatibility is desired. The default (i.e., when that macro + isn't defined) is OpenSSL 0.9.6c compatibility. + + There are also macros that enable and disable the support of old + des functions altogether. Those are OPENSSL_ENABLE_OLD_DES_SUPPORT + and OPENSSL_DISABLE_OLD_DES_SUPPORT. If none or both of those + are defined, the default will apply: to support the old des routines. + + In either case, one must include openssl/des.h to get the correct + definitions. Do not try to just include openssl/des_old.h, that + won't work. + + NOTE: This is a major break of an old API into a new one. Software + authors are encouraged to switch to the DES_ style functions. Some + time in the future, des_old.h and the libdes compatibility functions + will be disable (i.e. OPENSSL_DISABLE_OLD_DES_SUPPORT will be the + default), and then completely removed. + [Richard Levitte] + + *) Test for certificates which contain unsupported critical extensions. + If such a certificate is found during a verify operation it is + rejected by default: this behaviour can be overridden by either + handling the new error X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION or + by setting the verify flag X509_V_FLAG_IGNORE_CRITICAL. A new function + X509_supported_extension() has also been added which returns 1 if a + particular extension is supported. + [Steve Henson] + + *) Modify the behaviour of EVP cipher functions in similar way to digests + to retain compatibility with existing code. + [Steve Henson] + + *) Modify the behaviour of EVP_DigestInit() and EVP_DigestFinal() to retain + compatibility with existing code. In particular the 'ctx' parameter does + not have to be to be initialized before the call to EVP_DigestInit() and + it is tidied up after a call to EVP_DigestFinal(). New function + EVP_DigestFinal_ex() which does not tidy up the ctx. Similarly function + EVP_MD_CTX_copy() changed to not require the destination to be + initialized valid and new function EVP_MD_CTX_copy_ex() added which + requires the destination to be valid. + + Modify all the OpenSSL digest calls to use EVP_DigestInit_ex(), + EVP_DigestFinal_ex() and EVP_MD_CTX_copy_ex(). + [Steve Henson] + + *) Change ssl3_get_message (ssl/s3_both.c) and the functions using it + so that complete 'Handshake' protocol structures are kept in memory + instead of overwriting 'msg_type' and 'length' with 'body' data. + [Bodo Moeller] + + *) Add an implementation of SSL_add_dir_cert_subjects_to_stack for Win32. + [Massimo Santin via Richard Levitte] + + *) Major restructuring to the underlying ENGINE code. This includes + reduction of linker bloat, separation of pure "ENGINE" manipulation + (initialisation, etc) from functionality dealing with implementations + of specific crypto iterfaces. This change also introduces integrated + support for symmetric ciphers and digest implementations - so ENGINEs + can now accelerate these by providing EVP_CIPHER and EVP_MD + implementations of their own. This is detailed in crypto/engine/README + as it couldn't be adequately described here. However, there are a few + API changes worth noting - some RSA, DSA, DH, and RAND functions that + were changed in the original introduction of ENGINE code have now + reverted back - the hooking from this code to ENGINE is now a good + deal more passive and at run-time, operations deal directly with + RSA_METHODs, DSA_METHODs (etc) as they did before, rather than + dereferencing through an ENGINE pointer any more. Also, the ENGINE + functions dealing with BN_MOD_EXP[_CRT] handlers have been removed - + they were not being used by the framework as there is no concept of a + BIGNUM_METHOD and they could not be generalised to the new + 'ENGINE_TABLE' mechanism that underlies the new code. Similarly, + ENGINE_cpy() has been removed as it cannot be consistently defined in + the new code. + [Geoff Thorpe] + + *) Change ASN1_GENERALIZEDTIME_check() to allow fractional seconds. + [Steve Henson] + + *) Change mkdef.pl to sort symbols that get the same entry number, + and make sure the automatically generated functions ERR_load_* + become part of libeay.num as well. + [Richard Levitte] + + *) New function SSL_renegotiate_pending(). This returns true once + renegotiation has been requested (either SSL_renegotiate() call + or HelloRequest/ClientHello receveived from the peer) and becomes + false once a handshake has been completed. + (For servers, SSL_renegotiate() followed by SSL_do_handshake() + sends a HelloRequest, but does not ensure that a handshake takes + place. SSL_renegotiate_pending() is useful for checking if the + client has followed the request.) + [Bodo Moeller] + + *) New SSL option SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION. + By default, clients may request session resumption even during + renegotiation (if session ID contexts permit); with this option, + session resumption is possible only in the first handshake. + + SSL_OP_ALL is now 0x00000FFFL instead of 0x000FFFFFL. This makes + more bits available for options that should not be part of + SSL_OP_ALL (such as SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION). + [Bodo Moeller] + + *) Add some demos for certificate and certificate request creation. + [Steve Henson] + + *) Make maximum certificate chain size accepted from the peer application + settable (SSL*_get/set_max_cert_list()), as proposed by + "Douglas E. Engert" . + [Lutz Jaenicke] + + *) Add support for shared libraries for Unixware-7 + (Boyd Lynn Gerber ). + [Lutz Jaenicke] + + *) Add a "destroy" handler to ENGINEs that allows structural cleanup to + be done prior to destruction. Use this to unload error strings from + ENGINEs that load their own error strings. NB: This adds two new API + functions to "get" and "set" this destroy handler in an ENGINE. + [Geoff Thorpe] + + *) Alter all existing ENGINE implementations (except "openssl" and + "openbsd") to dynamically instantiate their own error strings. This + makes them more flexible to be built both as statically-linked ENGINEs + and self-contained shared-libraries loadable via the "dynamic" ENGINE. + Also, add stub code to each that makes building them as self-contained + shared-libraries easier (see README.ENGINE). + [Geoff Thorpe] + + *) Add a "dynamic" ENGINE that provides a mechanism for binding ENGINE + implementations into applications that are completely implemented in + self-contained shared-libraries. The "dynamic" ENGINE exposes control + commands that can be used to configure what shared-library to load and + to control aspects of the way it is handled. Also, made an update to + the README.ENGINE file that brings its information up-to-date and + provides some information and instructions on the "dynamic" ENGINE + (ie. how to use it, how to build "dynamic"-loadable ENGINEs, etc). + [Geoff Thorpe] + + *) Make it possible to unload ranges of ERR strings with a new + "ERR_unload_strings" function. + [Geoff Thorpe] + + *) Add a copy() function to EVP_MD. + [Ben Laurie] + + *) Make EVP_MD routines take a context pointer instead of just the + md_data void pointer. + [Ben Laurie] + + *) Add flags to EVP_MD and EVP_MD_CTX. EVP_MD_FLAG_ONESHOT indicates + that the digest can only process a single chunk of data + (typically because it is provided by a piece of + hardware). EVP_MD_CTX_FLAG_ONESHOT indicates that the application + is only going to provide a single chunk of data, and hence the + framework needn't accumulate the data for oneshot drivers. + [Ben Laurie] + + *) As with "ERR", make it possible to replace the underlying "ex_data" + functions. This change also alters the storage and management of global + ex_data state - it's now all inside ex_data.c and all "class" code (eg. + RSA, BIO, SSL_CTX, etc) no longer stores its own STACKS and per-class + index counters. The API functions that use this state have been changed + to take a "class_index" rather than pointers to the class's local STACK + and counter, and there is now an API function to dynamically create new + classes. This centralisation allows us to (a) plug a lot of the + thread-safety problems that existed, and (b) makes it possible to clean + up all allocated state using "CRYPTO_cleanup_all_ex_data()". W.r.t. (b) + such data would previously have always leaked in application code and + workarounds were in place to make the memory debugging turn a blind eye + to it. Application code that doesn't use this new function will still + leak as before, but their memory debugging output will announce it now + rather than letting it slide. + + Besides the addition of CRYPTO_cleanup_all_ex_data(), another API change + induced by the "ex_data" overhaul is that X509_STORE_CTX_init() now + has a return value to indicate success or failure. + [Geoff Thorpe] + + *) Make it possible to replace the underlying "ERR" functions such that the + global state (2 LHASH tables and 2 locks) is only used by the "default" + implementation. This change also adds two functions to "get" and "set" + the implementation prior to it being automatically set the first time + any other ERR function takes place. Ie. an application can call "get", + pass the return value to a module it has just loaded, and that module + can call its own "set" function using that value. This means the + module's "ERR" operations will use (and modify) the error state in the + application and not in its own statically linked copy of OpenSSL code. + [Geoff Thorpe] + + *) Give DH, DSA, and RSA types their own "**_up_ref()" function to increment + reference counts. This performs normal REF_PRINT/REF_CHECK macros on + the operation, and provides a more encapsulated way for external code + (crypto/evp/ and ssl/) to do this. Also changed the evp and ssl code + to use these functions rather than manually incrementing the counts. + + Also rename "DSO_up()" function to more descriptive "DSO_up_ref()". + [Geoff Thorpe] + + *) Add EVP test program. + [Ben Laurie] + + *) Add symmetric cipher support to ENGINE. Expect the API to change! + [Ben Laurie] + + *) New CRL functions: X509_CRL_set_version(), X509_CRL_set_issuer_name() + X509_CRL_set_lastUpdate(), X509_CRL_set_nextUpdate(), X509_CRL_sort(), + X509_REVOKED_set_serialNumber(), and X509_REVOKED_set_revocationDate(). + These allow a CRL to be built without having to access X509_CRL fields + directly. Modify 'ca' application to use new functions. + [Steve Henson] + + *) Move SSL_OP_TLS_ROLLBACK_BUG out of the SSL_OP_ALL list of recommended + bug workarounds. Rollback attack detection is a security feature. + The problem will only arise on OpenSSL servers when TLSv1 is not + available (sslv3_server_method() or SSL_OP_NO_TLSv1). + Software authors not wanting to support TLSv1 will have special reasons + for their choice and can explicitly enable this option. + [Bodo Moeller, Lutz Jaenicke] + + *) Rationalise EVP so it can be extended: don't include a union of + cipher/digest structures, add init/cleanup functions for EVP_MD_CTX + (similar to those existing for EVP_CIPHER_CTX). + Usage example: + + EVP_MD_CTX md; + + EVP_MD_CTX_init(&md); /* new function call */ + EVP_DigestInit(&md, EVP_sha1()); + EVP_DigestUpdate(&md, in, len); + EVP_DigestFinal(&md, out, NULL); + EVP_MD_CTX_cleanup(&md); /* new function call */ + + [Ben Laurie] + + *) Make DES key schedule conform to the usual scheme, as well as + correcting its structure. This means that calls to DES functions + now have to pass a pointer to a des_key_schedule instead of a + plain des_key_schedule (which was actually always a pointer + anyway): E.g., + + des_key_schedule ks; + + des_set_key_checked(..., &ks); + des_ncbc_encrypt(..., &ks, ...); + + (Note that a later change renames 'des_...' into 'DES_...'.) + [Ben Laurie] + + *) Initial reduction of linker bloat: the use of some functions, such as + PEM causes large amounts of unused functions to be linked in due to + poor organisation. For example pem_all.c contains every PEM function + which has a knock on effect of linking in large amounts of (unused) + ASN1 code. Grouping together similar functions and splitting unrelated + functions prevents this. + [Steve Henson] + + *) Cleanup of EVP macros. + [Ben Laurie] + + *) Change historical references to {NID,SN,LN}_des_ede and ede3 to add the + correct _ecb suffix. + [Ben Laurie] + + *) Add initial OCSP responder support to ocsp application. The + revocation information is handled using the text based index + use by the ca application. The responder can either handle + requests generated internally, supplied in files (for example + via a CGI script) or using an internal minimal server. + [Steve Henson] + + *) Add configuration choices to get zlib compression for TLS. + [Richard Levitte] + + *) Changes to Kerberos SSL for RFC 2712 compliance: + 1. Implemented real KerberosWrapper, instead of just using + KRB5 AP_REQ message. [Thanks to Simon Wilkinson ] + 2. Implemented optional authenticator field of KerberosWrapper. + + Added openssl-style ASN.1 macros for Kerberos ticket, ap_req, + and authenticator structs; see crypto/krb5/. + + Generalized Kerberos calls to support multiple Kerberos libraries. + [Vern Staats , + Jeffrey Altman + via Richard Levitte] + + *) Cause 'openssl speed' to use fully hard-coded DSA keys as it + already does with RSA. testdsa.h now has 'priv_key/pub_key' + values for each of the key sizes rather than having just + parameters (and 'speed' generating keys each time). + [Geoff Thorpe] + + *) Speed up EVP routines. + Before: +encrypt +type 8 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes +des-cbc 4408.85k 5560.51k 5778.46k 5862.20k 5825.16k +des-cbc 4389.55k 5571.17k 5792.23k 5846.91k 5832.11k +des-cbc 4394.32k 5575.92k 5807.44k 5848.37k 5841.30k +decrypt +des-cbc 3482.66k 5069.49k 5496.39k 5614.16k 5639.28k +des-cbc 3480.74k 5068.76k 5510.34k 5609.87k 5635.52k +des-cbc 3483.72k 5067.62k 5504.60k 5708.01k 5724.80k + After: +encrypt +des-cbc 4660.16k 5650.19k 5807.19k 5827.13k 5783.32k +decrypt +des-cbc 3624.96k 5258.21k 5530.91k 5624.30k 5628.26k + [Ben Laurie] + + *) Added the OS2-EMX target. + ["Brian Havard" and Richard Levitte] + + *) Rewrite apps to use NCONF routines instead of the old CONF. New functions + to support NCONF routines in extension code. New function CONF_set_nconf() + to allow functions which take an NCONF to also handle the old LHASH + structure: this means that the old CONF compatible routines can be + retained (in particular wrt extensions) without having to duplicate the + code. New function X509V3_add_ext_nconf_sk to add extensions to a stack. + [Steve Henson] + + *) Enhance the general user interface with mechanisms for inner control + and with possibilities to have yes/no kind of prompts. + [Richard Levitte] + + *) Change all calls to low level digest routines in the library and + applications to use EVP. Add missing calls to HMAC_cleanup() and + don't assume HMAC_CTX can be copied using memcpy(). + [Verdon Walker , Steve Henson] + + *) Add the possibility to control engines through control names but with + arbitrary arguments instead of just a string. + Change the key loaders to take a UI_METHOD instead of a callback + function pointer. NOTE: this breaks binary compatibility with earlier + versions of OpenSSL [engine]. + Adapt the nCipher code for these new conditions and add a card insertion + callback. + [Richard Levitte] + + *) Enhance the general user interface with mechanisms to better support + dialog box interfaces, application-defined prompts, the possibility + to use defaults (for example default passwords from somewhere else) + and interrupts/cancellations. + [Richard Levitte] + + *) Tidy up PKCS#12 attribute handling. Add support for the CSP name + attribute in PKCS#12 files, add new -CSP option to pkcs12 utility. + [Steve Henson] + + *) Fix a memory leak in 'sk_dup()' in the case reallocation fails. (Also + tidy up some unnecessarily weird code in 'sk_new()'). + [Geoff, reported by Diego Tartara ] + + *) Change the key loading routines for ENGINEs to use the same kind + callback (pem_password_cb) as all other routines that need this + kind of callback. + [Richard Levitte] + + *) Increase ENTROPY_NEEDED to 32 bytes, as Rijndael can operate with + 256 bit (=32 byte) keys. Of course seeding with more entropy bytes + than this minimum value is recommended. + [Lutz Jaenicke] + + *) New random seeder for OpenVMS, using the system process statistics + that are easily reachable. + [Richard Levitte] + + *) Windows apparently can't transparently handle global + variables defined in DLLs. Initialisations such as: + + const ASN1_ITEM *it = &ASN1_INTEGER_it; + + wont compile. This is used by the any applications that need to + declare their own ASN1 modules. This was fixed by adding the option + EXPORT_VAR_AS_FN to all Win32 platforms, although this isn't strictly + needed for static libraries under Win32. + [Steve Henson] + + *) New functions X509_PURPOSE_set() and X509_TRUST_set() to handle + setting of purpose and trust fields. New X509_STORE trust and + purpose functions and tidy up setting in other SSL functions. + [Steve Henson] + + *) Add copies of X509_STORE_CTX fields and callbacks to X509_STORE + structure. These are inherited by X509_STORE_CTX when it is + initialised. This allows various defaults to be set in the + X509_STORE structure (such as flags for CRL checking and custom + purpose or trust settings) for functions which only use X509_STORE_CTX + internally such as S/MIME. + + Modify X509_STORE_CTX_purpose_inherit() so it only sets purposes and + trust settings if they are not set in X509_STORE. This allows X509_STORE + purposes and trust (in S/MIME for example) to override any set by default. + + Add command line options for CRL checking to smime, s_client and s_server + applications. + [Steve Henson] + + *) Initial CRL based revocation checking. If the CRL checking flag(s) + are set then the CRL is looked up in the X509_STORE structure and + its validity and signature checked, then if the certificate is found + in the CRL the verify fails with a revoked error. + + Various new CRL related callbacks added to X509_STORE_CTX structure. + + Command line options added to 'verify' application to support this. + + This needs some additional work, such as being able to handle multiple + CRLs with different times, extension based lookup (rather than just + by subject name) and ultimately more complete V2 CRL extension + handling. + [Steve Henson] + + *) Add a general user interface API (crypto/ui/). This is designed + to replace things like des_read_password and friends (backward + compatibility functions using this new API are provided). + The purpose is to remove prompting functions from the DES code + section as well as provide for prompting through dialog boxes in + a window system and the like. + [Richard Levitte] + + *) Add "ex_data" support to ENGINE so implementations can add state at a + per-structure level rather than having to store it globally. + [Geoff] + + *) Make it possible for ENGINE structures to be copied when retrieved by + ENGINE_by_id() if the ENGINE specifies a new flag: ENGINE_FLAGS_BY_ID_COPY. + This causes the "original" ENGINE structure to act like a template, + analogous to the RSA vs. RSA_METHOD type of separation. Because of this + operational state can be localised to each ENGINE structure, despite the + fact they all share the same "methods". New ENGINE structures returned in + this case have no functional references and the return value is the single + structural reference. This matches the single structural reference returned + by ENGINE_by_id() normally, when it is incremented on the pre-existing + ENGINE structure. + [Geoff] + + *) Fix ASN1 decoder when decoding type ANY and V_ASN1_OTHER: since this + needs to match any other type at all we need to manually clear the + tag cache. + [Steve Henson] + + *) Changes to the "openssl engine" utility to include; + - verbosity levels ('-v', '-vv', and '-vvv') that provide information + about an ENGINE's available control commands. + - executing control commands from command line arguments using the + '-pre' and '-post' switches. '-post' is only used if '-t' is + specified and the ENGINE is successfully initialised. The syntax for + the individual commands are colon-separated, for example; + openssl engine chil -pre FORK_CHECK:0 -pre SO_PATH:/lib/test.so + [Geoff] + + *) New dynamic control command support for ENGINEs. ENGINEs can now + declare their own commands (numbers), names (strings), descriptions, + and input types for run-time discovery by calling applications. A + subset of these commands are implicitly classed as "executable" + depending on their input type, and only these can be invoked through + the new string-based API function ENGINE_ctrl_cmd_string(). (Eg. this + can be based on user input, config files, etc). The distinction is + that "executable" commands cannot return anything other than a boolean + result and can only support numeric or string input, whereas some + discoverable commands may only be for direct use through + ENGINE_ctrl(), eg. supporting the exchange of binary data, function + pointers, or other custom uses. The "executable" commands are to + support parameterisations of ENGINE behaviour that can be + unambiguously defined by ENGINEs and used consistently across any + OpenSSL-based application. Commands have been added to all the + existing hardware-supporting ENGINEs, noticeably "SO_PATH" to allow + control over shared-library paths without source code alterations. + [Geoff] + + *) Changed all ENGINE implementations to dynamically allocate their + ENGINEs rather than declaring them statically. Apart from this being + necessary with the removal of the ENGINE_FLAGS_MALLOCED distinction, + this also allows the implementations to compile without using the + internal engine_int.h header. + [Geoff] + + *) Minor adjustment to "rand" code. RAND_get_rand_method() now returns a + 'const' value. Any code that should be able to modify a RAND_METHOD + should already have non-const pointers to it (ie. they should only + modify their own ones). + [Geoff] + + *) Made a variety of little tweaks to the ENGINE code. + - "atalla" and "ubsec" string definitions were moved from header files + to C code. "nuron" string definitions were placed in variables + rather than hard-coded - allowing parameterisation of these values + later on via ctrl() commands. + - Removed unused "#if 0"'d code. + - Fixed engine list iteration code so it uses ENGINE_free() to release + structural references. + - Constified the RAND_METHOD element of ENGINE structures. + - Constified various get/set functions as appropriate and added + missing functions (including a catch-all ENGINE_cpy that duplicates + all ENGINE values onto a new ENGINE except reference counts/state). + - Removed NULL parameter checks in get/set functions. Setting a method + or function to NULL is a way of cancelling out a previously set + value. Passing a NULL ENGINE parameter is just plain stupid anyway + and doesn't justify the extra error symbols and code. + - Deprecate the ENGINE_FLAGS_MALLOCED define and move the area for + flags from engine_int.h to engine.h. + - Changed prototypes for ENGINE handler functions (init(), finish(), + ctrl(), key-load functions, etc) to take an (ENGINE*) parameter. + [Geoff] + + *) Implement binary inversion algorithm for BN_mod_inverse in addition + to the algorithm using long division. The binary algorithm can be + used only if the modulus is odd. On 32-bit systems, it is faster + only for relatively small moduli (roughly 20-30% for 128-bit moduli, + roughly 5-15% for 256-bit moduli), so we use it only for moduli + up to 450 bits. In 64-bit environments, the binary algorithm + appears to be advantageous for much longer moduli; here we use it + for moduli up to 2048 bits. + [Bodo Moeller] + + *) Rewrite CHOICE field setting in ASN1_item_ex_d2i(). The old code + could not support the combine flag in choice fields. + [Steve Henson] + + *) Add a 'copy_extensions' option to the 'ca' utility. This copies + extensions from a certificate request to the certificate. + [Steve Henson] + + *) Allow multiple 'certopt' and 'nameopt' options to be separated + by commas. Add 'namopt' and 'certopt' options to the 'ca' config + file: this allows the display of the certificate about to be + signed to be customised, to allow certain fields to be included + or excluded and extension details. The old system didn't display + multicharacter strings properly, omitted fields not in the policy + and couldn't display additional details such as extensions. + [Steve Henson] + + *) Function EC_POINTs_mul for multiple scalar multiplication + of an arbitrary number of elliptic curve points + \sum scalars[i]*points[i], + optionally including the generator defined for the EC_GROUP: + scalar*generator + \sum scalars[i]*points[i]. + + EC_POINT_mul is a simple wrapper function for the typical case + that the point list has just one item (besides the optional + generator). + [Bodo Moeller] + + *) First EC_METHODs for curves over GF(p): + + EC_GFp_simple_method() uses the basic BN_mod_mul and BN_mod_sqr + operations and provides various method functions that can also + operate with faster implementations of modular arithmetic. + + EC_GFp_mont_method() reuses most functions that are part of + EC_GFp_simple_method, but uses Montgomery arithmetic. + + [Bodo Moeller; point addition and point doubling + implementation directly derived from source code provided by + Lenka Fibikova ] + + *) Framework for elliptic curves (crypto/ec/ec.h, crypto/ec/ec_lcl.h, + crypto/ec/ec_lib.c): + + Curves are EC_GROUP objects (with an optional group generator) + based on EC_METHODs that are built into the library. + + Points are EC_POINT objects based on EC_GROUP objects. + + Most of the framework would be able to handle curves over arbitrary + finite fields, but as there are no obvious types for fields other + than GF(p), some functions are limited to that for now. + [Bodo Moeller] + + *) Add the -HTTP option to s_server. It is similar to -WWW, but requires + that the file contains a complete HTTP response. + [Richard Levitte] + + *) Add the ec directory to mkdef.pl and mkfiles.pl. In mkdef.pl + change the def and num file printf format specifier from "%-40sXXX" + to "%-39s XXX". The latter will always guarantee a space after the + field while the former will cause them to run together if the field + is 40 of more characters long. + [Steve Henson] + + *) Constify the cipher and digest 'method' functions and structures + and modify related functions to take constant EVP_MD and EVP_CIPHER + pointers. + [Steve Henson] + + *) Hide BN_CTX structure details in bn_lcl.h instead of publishing them + in . Also further increase BN_CTX_NUM to 32. + [Bodo Moeller] + + *) Modify EVP_Digest*() routines so they now return values. Although the + internal software routines can never fail additional hardware versions + might. + [Steve Henson] + + *) Clean up crypto/err/err.h and change some error codes to avoid conflicts: + + Previously ERR_R_FATAL was too small and coincided with ERR_LIB_PKCS7 + (= ERR_R_PKCS7_LIB); it is now 64 instead of 32. + + ASN1 error codes + ERR_R_NESTED_ASN1_ERROR + ... + ERR_R_MISSING_ASN1_EOS + were 4 .. 9, conflicting with + ERR_LIB_RSA (= ERR_R_RSA_LIB) + ... + ERR_LIB_PEM (= ERR_R_PEM_LIB). + They are now 58 .. 63 (i.e., just below ERR_R_FATAL). + + Add new error code 'ERR_R_INTERNAL_ERROR'. + [Bodo Moeller] + + *) Don't overuse locks in crypto/err/err.c: For data retrieval, CRYPTO_r_lock + suffices. + [Bodo Moeller] + + *) New option '-subj arg' for 'openssl req' and 'openssl ca'. This + sets the subject name for a new request or supersedes the + subject name in a given request. Formats that can be parsed are + 'CN=Some Name, OU=myOU, C=IT' + and + 'CN=Some Name/OU=myOU/C=IT'. + + Add options '-batch' and '-verbose' to 'openssl req'. + [Massimiliano Pala ] + + *) Introduce the possibility to access global variables through + functions on platform were that's the best way to handle exporting + global variables in shared libraries. To enable this functionality, + one must configure with "EXPORT_VAR_AS_FN" or defined the C macro + "OPENSSL_EXPORT_VAR_AS_FUNCTION" in crypto/opensslconf.h (the latter + is normally done by Configure or something similar). + + To implement a global variable, use the macro OPENSSL_IMPLEMENT_GLOBAL + in the source file (foo.c) like this: + + OPENSSL_IMPLEMENT_GLOBAL(int,foo)=1; + OPENSSL_IMPLEMENT_GLOBAL(double,bar); + + To declare a global variable, use the macros OPENSSL_DECLARE_GLOBAL + and OPENSSL_GLOBAL_REF in the header file (foo.h) like this: + + OPENSSL_DECLARE_GLOBAL(int,foo); + #define foo OPENSSL_GLOBAL_REF(foo) + OPENSSL_DECLARE_GLOBAL(double,bar); + #define bar OPENSSL_GLOBAL_REF(bar) + + The #defines are very important, and therefore so is including the + header file everywhere where the defined globals are used. + + The macro OPENSSL_EXPORT_VAR_AS_FUNCTION also affects the definition + of ASN.1 items, but that structure is a bit different. + + The largest change is in util/mkdef.pl which has been enhanced with + better and easier to understand logic to choose which symbols should + go into the Windows .def files as well as a number of fixes and code + cleanup (among others, algorithm keywords are now sorted + lexicographically to avoid constant rewrites). + [Richard Levitte] + + *) In BN_div() keep a copy of the sign of 'num' before writing the + result to 'rm' because if rm==num the value will be overwritten + and produce the wrong result if 'num' is negative: this caused + problems with BN_mod() and BN_nnmod(). + [Steve Henson] + + *) Function OCSP_request_verify(). This checks the signature on an + OCSP request and verifies the signer certificate. The signer + certificate is just checked for a generic purpose and OCSP request + trust settings. + [Steve Henson] + + *) Add OCSP_check_validity() function to check the validity of OCSP + responses. OCSP responses are prepared in real time and may only + be a few seconds old. Simply checking that the current time lies + between thisUpdate and nextUpdate max reject otherwise valid responses + caused by either OCSP responder or client clock inaccuracy. Instead + we allow thisUpdate and nextUpdate to fall within a certain period of + the current time. The age of the response can also optionally be + checked. Two new options -validity_period and -status_age added to + ocsp utility. + [Steve Henson] + + *) If signature or public key algorithm is unrecognized print out its + OID rather that just UNKNOWN. + [Steve Henson] + + *) Change OCSP_cert_to_id() to tolerate a NULL subject certificate and + OCSP_cert_id_new() a NULL serialNumber. This allows a partial certificate + ID to be generated from the issuer certificate alone which can then be + passed to OCSP_id_issuer_cmp(). + [Steve Henson] + + *) New compilation option ASN1_ITEM_FUNCTIONS. This causes the new + ASN1 modules to export functions returning ASN1_ITEM pointers + instead of the ASN1_ITEM structures themselves. This adds several + new macros which allow the underlying ASN1 function/structure to + be accessed transparently. As a result code should not use ASN1_ITEM + references directly (such as &X509_it) but instead use the relevant + macros (such as ASN1_ITEM_rptr(X509)). This option is to allow + use of the new ASN1 code on platforms where exporting structures + is problematical (for example in shared libraries) but exporting + functions returning pointers to structures is not. + [Steve Henson] + + *) Add support for overriding the generation of SSL/TLS session IDs. + These callbacks can be registered either in an SSL_CTX or per SSL. + The purpose of this is to allow applications to control, if they wish, + the arbitrary values chosen for use as session IDs, particularly as it + can be useful for session caching in multiple-server environments. A + command-line switch for testing this (and any client code that wishes + to use such a feature) has been added to "s_server". + [Geoff Thorpe, Lutz Jaenicke] + + *) Modify mkdef.pl to recognise and parse preprocessor conditionals + of the form '#if defined(...) || defined(...) || ...' and + '#if !defined(...) && !defined(...) && ...'. This also avoids + the growing number of special cases it was previously handling. + [Richard Levitte] + + *) Make all configuration macros available for application by making + sure they are available in opensslconf.h, by giving them names starting + with "OPENSSL_" to avoid conflicts with other packages and by making + sure e_os2.h will cover all platform-specific cases together with + opensslconf.h. + Additionally, it is now possible to define configuration/platform- + specific names (called "system identities"). In the C code, these + are prefixed with "OPENSSL_SYSNAME_". e_os2.h will create another + macro with the name beginning with "OPENSSL_SYS_", which is determined + from "OPENSSL_SYSNAME_*" or compiler-specific macros depending on + what is available. + [Richard Levitte] + + *) New option -set_serial to 'req' and 'x509' this allows the serial + number to use to be specified on the command line. Previously self + signed certificates were hard coded with serial number 0 and the + CA options of 'x509' had to use a serial number in a file which was + auto incremented. + [Steve Henson] + + *) New options to 'ca' utility to support V2 CRL entry extensions. + Currently CRL reason, invalidity date and hold instruction are + supported. Add new CRL extensions to V3 code and some new objects. + [Steve Henson] + + *) New function EVP_CIPHER_CTX_set_padding() this is used to + disable standard block padding (aka PKCS#5 padding) in the EVP + API, which was previously mandatory. This means that the data is + not padded in any way and so the total length much be a multiple + of the block size, otherwise an error occurs. + [Steve Henson] + + *) Initial (incomplete) OCSP SSL support. + [Steve Henson] + + *) New function OCSP_parse_url(). This splits up a URL into its host, + port and path components: primarily to parse OCSP URLs. New -url + option to ocsp utility. + [Steve Henson] + + *) New nonce behavior. The return value of OCSP_check_nonce() now + reflects the various checks performed. Applications can decide + whether to tolerate certain situations such as an absent nonce + in a response when one was present in a request: the ocsp application + just prints out a warning. New function OCSP_add1_basic_nonce() + this is to allow responders to include a nonce in a response even if + the request is nonce-less. + [Steve Henson] + + *) Disable stdin buffering in load_cert (apps/apps.c) so that no certs are + skipped when using openssl x509 multiple times on a single input file, + e.g. "(openssl x509 -out cert1; openssl x509 -out cert2) ] + + *) New OCSP verify flag OCSP_TRUSTOTHER. When set the "other" certificates + passed by the function are trusted implicitly. If any of them signed the + response then it is assumed to be valid and is not verified. + [Steve Henson] + + *) In PKCS7_set_type() initialise content_type in PKCS7_ENC_CONTENT + to data. This was previously part of the PKCS7 ASN1 code. This + was causing problems with OpenSSL created PKCS#12 and PKCS#7 structures. + [Steve Henson, reported by Kenneth R. Robinette + ] + + *) Add CRYPTO_push_info() and CRYPTO_pop_info() calls to new ASN1 + routines: without these tracing memory leaks is very painful. + Fix leaks in PKCS12 and PKCS7 routines. + [Steve Henson] + + *) Make X509_time_adj() cope with the new behaviour of ASN1_TIME_new(). + Previously it initialised the 'type' argument to V_ASN1_UTCTIME which + effectively meant GeneralizedTime would never be used. Now it + is initialised to -1 but X509_time_adj() now has to check the value + and use ASN1_TIME_set() if the value is not V_ASN1_UTCTIME or + V_ASN1_GENERALIZEDTIME, without this it always uses GeneralizedTime. + [Steve Henson, reported by Kenneth R. Robinette + ] + + *) Fixes to BN_to_ASN1_INTEGER when bn is zero. This would previously + result in a zero length in the ASN1_INTEGER structure which was + not consistent with the structure when d2i_ASN1_INTEGER() was used + and would cause ASN1_INTEGER_cmp() to fail. Enhance s2i_ASN1_INTEGER() + to cope with hex and negative integers. Fix bug in i2a_ASN1_INTEGER() + where it did not print out a minus for negative ASN1_INTEGER. + [Steve Henson] + + *) Add summary printout to ocsp utility. The various functions which + convert status values to strings have been renamed to: + OCSP_response_status_str(), OCSP_cert_status_str() and + OCSP_crl_reason_str() and are no longer static. New options + to verify nonce values and to disable verification. OCSP response + printout format cleaned up. + [Steve Henson] + + *) Add additional OCSP certificate checks. These are those specified + in RFC2560. This consists of two separate checks: the CA of the + certificate being checked must either be the OCSP signer certificate + or the issuer of the OCSP signer certificate. In the latter case the + OCSP signer certificate must contain the OCSP signing extended key + usage. This check is performed by attempting to match the OCSP + signer or the OCSP signer CA to the issuerNameHash and issuerKeyHash + in the OCSP_CERTID structures of the response. + [Steve Henson] + + *) Initial OCSP certificate verification added to OCSP_basic_verify() + and related routines. This uses the standard OpenSSL certificate + verify routines to perform initial checks (just CA validity) and + to obtain the certificate chain. Then additional checks will be + performed on the chain. Currently the root CA is checked to see + if it is explicitly trusted for OCSP signing. This is used to set + a root CA as a global signing root: that is any certificate that + chains to that CA is an acceptable OCSP signing certificate. + [Steve Henson] + + *) New '-extfile ...' option to 'openssl ca' for reading X.509v3 + extensions from a separate configuration file. + As when reading extensions from the main configuration file, + the '-extensions ...' option may be used for specifying the + section to use. + [Massimiliano Pala ] + + *) New OCSP utility. Allows OCSP requests to be generated or + read. The request can be sent to a responder and the output + parsed, outputed or printed in text form. Not complete yet: + still needs to check the OCSP response validity. + [Steve Henson] + + *) New subcommands for 'openssl ca': + 'openssl ca -status ' prints the status of the cert with + the given serial number (according to the index file). + 'openssl ca -updatedb' updates the expiry status of certificates + in the index file. + [Massimiliano Pala ] + + *) New '-newreq-nodes' command option to CA.pl. This is like + '-newreq', but calls 'openssl req' with the '-nodes' option + so that the resulting key is not encrypted. + [Damien Miller ] + + *) New configuration for the GNU Hurd. + [Jonathan Bartlett via Richard Levitte] + + *) Initial code to implement OCSP basic response verify. This + is currently incomplete. Currently just finds the signer's + certificate and verifies the signature on the response. + [Steve Henson] + + *) New SSLeay_version code SSLEAY_DIR to determine the compiled-in + value of OPENSSLDIR. This is available via the new '-d' option + to 'openssl version', and is also included in 'openssl version -a'. + [Bodo Moeller] + + *) Allowing defining memory allocation callbacks that will be given + file name and line number information in additional arguments + (a const char* and an int). The basic functionality remains, as + well as the original possibility to just replace malloc(), + realloc() and free() by functions that do not know about these + additional arguments. To register and find out the current + settings for extended allocation functions, the following + functions are provided: + + CRYPTO_set_mem_ex_functions + CRYPTO_set_locked_mem_ex_functions + CRYPTO_get_mem_ex_functions + CRYPTO_get_locked_mem_ex_functions + + These work the same way as CRYPTO_set_mem_functions and friends. + CRYPTO_get_[locked_]mem_functions now writes 0 where such an + extended allocation function is enabled. + Similarly, CRYPTO_get_[locked_]mem_ex_functions writes 0 where + a conventional allocation function is enabled. + [Richard Levitte, Bodo Moeller] + + *) Finish off removing the remaining LHASH function pointer casts. + There should no longer be any prototype-casting required when using + the LHASH abstraction, and any casts that remain are "bugs". See + the callback types and macros at the head of lhash.h for details + (and "OBJ_cleanup" in crypto/objects/obj_dat.c as an example). + [Geoff Thorpe] + + *) Add automatic query of EGD sockets in RAND_poll() for the unix variant. + If /dev/[u]random devices are not available or do not return enough + entropy, EGD style sockets (served by EGD or PRNGD) will automatically + be queried. + The locations /var/run/egd-pool, /dev/egd-pool, /etc/egd-pool, and + /etc/entropy will be queried once each in this sequence, quering stops + when enough entropy was collected without querying more sockets. + [Lutz Jaenicke] + + *) Change the Unix RAND_poll() variant to be able to poll several + random devices, as specified by DEVRANDOM, until a sufficient amount + of data has been collected. We spend at most 10 ms on each file + (select timeout) and read in non-blocking mode. DEVRANDOM now + defaults to the list "/dev/urandom", "/dev/random", "/dev/srandom" + (previously it was just the string "/dev/urandom"), so on typical + platforms the 10 ms delay will never occur. + Also separate out the Unix variant to its own file, rand_unix.c. + For VMS, there's a currently-empty rand_vms.c. + [Richard Levitte] + + *) Move OCSP client related routines to ocsp_cl.c. These + provide utility functions which an application needing + to issue a request to an OCSP responder and analyse the + response will typically need: as opposed to those which an + OCSP responder itself would need which will be added later. + + OCSP_request_sign() signs an OCSP request with an API similar + to PKCS7_sign(). OCSP_response_status() returns status of OCSP + response. OCSP_response_get1_basic() extracts basic response + from response. OCSP_resp_find_status(): finds and extracts status + information from an OCSP_CERTID structure (which will be created + when the request structure is built). These are built from lower + level functions which work on OCSP_SINGLERESP structures but + wont normally be used unless the application wishes to examine + extensions in the OCSP response for example. + + Replace nonce routines with a pair of functions. + OCSP_request_add1_nonce() adds a nonce value and optionally + generates a random value. OCSP_check_nonce() checks the + validity of the nonce in an OCSP response. + [Steve Henson] + + *) Change function OCSP_request_add() to OCSP_request_add0_id(). + This doesn't copy the supplied OCSP_CERTID and avoids the + need to free up the newly created id. Change return type + to OCSP_ONEREQ to return the internal OCSP_ONEREQ structure. + This can then be used to add extensions to the request. + Deleted OCSP_request_new(), since most of its functionality + is now in OCSP_REQUEST_new() (and the case insensitive name + clash) apart from the ability to set the request name which + will be added elsewhere. + [Steve Henson] + + *) Update OCSP API. Remove obsolete extensions argument from + various functions. Extensions are now handled using the new + OCSP extension code. New simple OCSP HTTP function which + can be used to send requests and parse the response. + [Steve Henson] + + *) Fix the PKCS#7 (S/MIME) code to work with new ASN1. Two new + ASN1_ITEM structures help with sign and verify. PKCS7_ATTR_SIGN + uses the special reorder version of SET OF to sort the attributes + and reorder them to match the encoded order. This resolves a long + standing problem: a verify on a PKCS7 structure just after signing + it used to fail because the attribute order did not match the + encoded order. PKCS7_ATTR_VERIFY does not reorder the attributes: + it uses the received order. This is necessary to tolerate some broken + software that does not order SET OF. This is handled by encoding + as a SEQUENCE OF but using implicit tagging (with UNIVERSAL class) + to produce the required SET OF. + [Steve Henson] + + *) Have mk1mf.pl generate the macros OPENSSL_BUILD_SHLIBCRYPTO and + OPENSSL_BUILD_SHLIBSSL and use them appropriately in the header + files to get correct declarations of the ASN.1 item variables. + [Richard Levitte] + + *) Rewrite of PKCS#12 code to use new ASN1 functionality. Replace many + PKCS#12 macros with real functions. Fix two unrelated ASN1 bugs: + asn1_check_tlen() would sometimes attempt to use 'ctx' when it was + NULL and ASN1_TYPE was not dereferenced properly in asn1_ex_c2i(). + New ASN1 macro: DECLARE_ASN1_ITEM() which just declares the relevant + ASN1_ITEM and no wrapper functions. + [Steve Henson] + + *) New functions or ASN1_item_d2i_fp() and ASN1_item_d2i_bio(). These + replace the old function pointer based I/O routines. Change most of + the *_d2i_bio() and *_d2i_fp() functions to use these. + [Steve Henson] + + *) Enhance mkdef.pl to be more accepting about spacing in C preprocessor + lines, recognice more "algorithms" that can be deselected, and make + it complain about algorithm deselection that isn't recognised. + [Richard Levitte] + + *) New ASN1 functions to handle dup, sign, verify, digest, pack and + unpack operations in terms of ASN1_ITEM. Modify existing wrappers + to use new functions. Add NO_ASN1_OLD which can be set to remove + some old style ASN1 functions: this can be used to determine if old + code will still work when these eventually go away. + [Steve Henson] + + *) New extension functions for OCSP structures, these follow the + same conventions as certificates and CRLs. + [Steve Henson] + + *) New function X509V3_add1_i2d(). This automatically encodes and + adds an extension. Its behaviour can be customised with various + flags to append, replace or delete. Various wrappers added for + certifcates and CRLs. + [Steve Henson] + + *) Fix to avoid calling the underlying ASN1 print routine when + an extension cannot be parsed. Correct a typo in the + OCSP_SERVICELOC extension. Tidy up print OCSP format. + [Steve Henson] + + *) Make mkdef.pl parse some of the ASN1 macros and add apropriate + entries for variables. + [Steve Henson] + + *) Add functionality to apps/openssl.c for detecting locking + problems: As the program is single-threaded, all we have + to do is register a locking callback using an array for + storing which locks are currently held by the program. + [Bodo Moeller] + + *) Use a lock around the call to CRYPTO_get_ex_new_index() in + SSL_get_ex_data_X509_STORE_idx(), which is used in + ssl_verify_cert_chain() and thus can be called at any time + during TLS/SSL handshakes so that thread-safety is essential. + Unfortunately, the ex_data design is not at all suited + for multi-threaded use, so it probably should be abolished. + [Bodo Moeller] + + *) Added Broadcom "ubsec" ENGINE to OpenSSL. + [Broadcom, tweaked and integrated by Geoff Thorpe] + + *) Move common extension printing code to new function + X509V3_print_extensions(). Reorganise OCSP print routines and + implement some needed OCSP ASN1 functions. Add OCSP extensions. + [Steve Henson] + + *) New function X509_signature_print() to remove duplication in some + print routines. + [Steve Henson] + + *) Add a special meaning when SET OF and SEQUENCE OF flags are both + set (this was treated exactly the same as SET OF previously). This + is used to reorder the STACK representing the structure to match the + encoding. This will be used to get round a problem where a PKCS7 + structure which was signed could not be verified because the STACK + order did not reflect the encoded order. + [Steve Henson] + + *) Reimplement the OCSP ASN1 module using the new code. + [Steve Henson] + + *) Update the X509V3 code to permit the use of an ASN1_ITEM structure + for its ASN1 operations. The old style function pointers still exist + for now but they will eventually go away. + [Steve Henson] + + *) Merge in replacement ASN1 code from the ASN1 branch. This almost + completely replaces the old ASN1 functionality with a table driven + encoder and decoder which interprets an ASN1_ITEM structure describing + the ASN1 module. Compatibility with the existing ASN1 API (i2d,d2i) is + largely maintained. Almost all of the old asn1_mac.h macro based ASN1 + has also been converted to the new form. + [Steve Henson] + + *) Change BN_mod_exp_recp so that negative moduli are tolerated + (the sign is ignored). Similarly, ignore the sign in BN_MONT_CTX_set + so that BN_mod_exp_mont and BN_mod_exp_mont_word work + for negative moduli. + [Bodo Moeller] + + *) Fix BN_uadd and BN_usub: Always return non-negative results instead + of not touching the result's sign bit. + [Bodo Moeller] + + *) BN_div bugfix: If the result is 0, the sign (res->neg) must not be + set. + [Bodo Moeller] + + *) Changed the LHASH code to use prototypes for callbacks, and created + macros to declare and implement thin (optionally static) functions + that provide type-safety and avoid function pointer casting for the + type-specific callbacks. + [Geoff Thorpe] + + *) Added Kerberos Cipher Suites to be used with TLS, as written in + RFC 2712. + [Veers Staats , + Jeffrey Altman , via Richard Levitte] + + *) Reformat the FAQ so the different questions and answers can be divided + in sections depending on the subject. + [Richard Levitte] + + *) Have the zlib compression code load ZLIB.DLL dynamically under + Windows. + [Richard Levitte] + + *) New function BN_mod_sqrt for computing square roots modulo a prime + (using the probabilistic Tonelli-Shanks algorithm unless + p == 3 (mod 4) or p == 5 (mod 8), which are cases that can + be handled deterministically). + [Lenka Fibikova , Bodo Moeller] + + *) Make BN_mod_inverse faster by explicitly handling small quotients + in the Euclid loop. (Speed gain about 20% for small moduli [256 or + 512 bits], about 30% for larger ones [1024 or 2048 bits].) + [Bodo Moeller] + + *) New function BN_kronecker. + [Bodo Moeller] + + *) Fix BN_gcd so that it works on negative inputs; the result is + positive unless both parameters are zero. + Previously something reasonably close to an infinite loop was + possible because numbers could be growing instead of shrinking + in the implementation of Euclid's algorithm. + [Bodo Moeller] + + *) Fix BN_is_word() and BN_is_one() macros to take into account the + sign of the number in question. + + Fix BN_is_word(a,w) to work correctly for w == 0. + + The old BN_is_word(a,w) macro is now called BN_abs_is_word(a,w) + because its test if the absolute value of 'a' equals 'w'. + Note that BN_abs_is_word does *not* handle w == 0 reliably; + it exists mostly for use in the implementations of BN_is_zero(), + BN_is_one(), and BN_is_word(). + [Bodo Moeller] + + *) New function BN_swap. + [Bodo Moeller] + + *) Use BN_nnmod instead of BN_mod in crypto/bn/bn_exp.c so that + the exponentiation functions are more likely to produce reasonable + results on negative inputs. + [Bodo Moeller] + + *) Change BN_mod_mul so that the result is always non-negative. + Previously, it could be negative if one of the factors was negative; + I don't think anyone really wanted that behaviour. + [Bodo Moeller] + + *) Move BN_mod_... functions into new file crypto/bn/bn_mod.c + (except for exponentiation, which stays in crypto/bn/bn_exp.c, + and BN_mod_mul_reciprocal, which stays in crypto/bn/bn_recp.c) + and add new functions: + + BN_nnmod + BN_mod_sqr + BN_mod_add + BN_mod_add_quick + BN_mod_sub + BN_mod_sub_quick + BN_mod_lshift1 + BN_mod_lshift1_quick + BN_mod_lshift + BN_mod_lshift_quick + + These functions always generate non-negative results. + + BN_nnmod otherwise is like BN_mod (if BN_mod computes a remainder r + such that |m| < r < 0, BN_nnmod will output rem + |m| instead). + + BN_mod_XXX_quick(r, a, [b,] m) generates the same result as + BN_mod_XXX(r, a, [b,] m, ctx), but requires that a [and b] + be reduced modulo m. + [Lenka Fibikova , Bodo Moeller] + +#if 0 + The following entry accidentily appeared in the CHANGES file + distributed with OpenSSL 0.9.7. The modifications described in + it do *not* apply to OpenSSL 0.9.7. + + *) Remove a few calls to bn_wexpand() in BN_sqr() (the one in there + was actually never needed) and in BN_mul(). The removal in BN_mul() + required a small change in bn_mul_part_recursive() and the addition + of the functions bn_cmp_part_words(), bn_sub_part_words() and + bn_add_part_words(), which do the same thing as bn_cmp_words(), + bn_sub_words() and bn_add_words() except they take arrays with + differing sizes. + [Richard Levitte] +#endif + + *) In 'openssl passwd', verify passwords read from the terminal + unless the '-salt' option is used (which usually means that + verification would just waste user's time since the resulting + hash is going to be compared with some given password hash) + or the new '-noverify' option is used. + + This is an incompatible change, but it does not affect + non-interactive use of 'openssl passwd' (passwords on the command + line, '-stdin' option, '-in ...' option) and thus should not + cause any problems. + [Bodo Moeller] + + *) Remove all references to RSAref, since there's no more need for it. + [Richard Levitte] + + *) Make DSO load along a path given through an environment variable + (SHLIB_PATH) with shl_load(). + [Richard Levitte] + + *) Constify the ENGINE code as a result of BIGNUM constification. + Also constify the RSA code and most things related to it. In a + few places, most notable in the depth of the ASN.1 code, ugly + casts back to non-const were required (to be solved at a later + time) + [Richard Levitte] + + *) Make it so the openssl application has all engines loaded by default. + [Richard Levitte] + + *) Constify the BIGNUM routines a little more. + [Richard Levitte] + + *) Add the following functions: + + ENGINE_load_cswift() + ENGINE_load_chil() + ENGINE_load_atalla() + ENGINE_load_nuron() + ENGINE_load_builtin_engines() + + That way, an application can itself choose if external engines that + are built-in in OpenSSL shall ever be used or not. The benefit is + that applications won't have to be linked with libdl or other dso + libraries unless it's really needed. + + Changed 'openssl engine' to load all engines on demand. + Changed the engine header files to avoid the duplication of some + declarations (they differed!). + [Richard Levitte] + + *) 'openssl engine' can now list capabilities. + [Richard Levitte] + + *) Better error reporting in 'openssl engine'. + [Richard Levitte] + + *) Never call load_dh_param(NULL) in s_server. + [Bodo Moeller] + + *) Add engine application. It can currently list engines by name and + identity, and test if they are actually available. + [Richard Levitte] + + *) Improve RPM specification file by forcing symbolic linking and making + sure the installed documentation is also owned by root.root. + [Damien Miller ] + + *) Give the OpenSSL applications more possibilities to make use of + keys (public as well as private) handled by engines. + [Richard Levitte] + + *) Add OCSP code that comes from CertCo. + [Richard Levitte] + + *) Add VMS support for the Rijndael code. + [Richard Levitte] + + *) Added untested support for Nuron crypto accelerator. + [Ben Laurie] + + *) Add support for external cryptographic devices. This code was + previously distributed separately as the "engine" branch. + [Geoff Thorpe, Richard Levitte] + + *) Rework the filename-translation in the DSO code. It is now possible to + have far greater control over how a "name" is turned into a filename + depending on the operating environment and any oddities about the + different shared library filenames on each system. + [Geoff Thorpe] + + *) Support threads on FreeBSD-elf in Configure. + [Richard Levitte] + + *) Fix for SHA1 assembly problem with MASM: it produces + warnings about corrupt line number information when assembling + with debugging information. This is caused by the overlapping + of two sections. + [Bernd Matthes , Steve Henson] + + *) NCONF changes. + NCONF_get_number() has no error checking at all. As a replacement, + NCONF_get_number_e() is defined (_e for "error checking") and is + promoted strongly. The old NCONF_get_number is kept around for + binary backward compatibility. + Make it possible for methods to load from something other than a BIO, + by providing a function pointer that is given a name instead of a BIO. + For example, this could be used to load configuration data from an + LDAP server. + [Richard Levitte] + + *) Fix for non blocking accept BIOs. Added new I/O special reason + BIO_RR_ACCEPT to cover this case. Previously use of accept BIOs + with non blocking I/O was not possible because no retry code was + implemented. Also added new SSL code SSL_WANT_ACCEPT to cover + this case. + [Steve Henson] + + *) Added the beginnings of Rijndael support. + [Ben Laurie] + + *) Fix for bug in DirectoryString mask setting. Add support for + X509_NAME_print_ex() in 'req' and X509_print_ex() function + to allow certificate printing to more controllable, additional + 'certopt' option to 'x509' to allow new printing options to be + set. + [Steve Henson] + + *) Clean old EAY MD5 hack from e_os.h. + [Richard Levitte] + + Changes between 0.9.6l and 0.9.6m [17 Mar 2004] + + *) Fix null-pointer assignment in do_change_cipher_spec() revealed + by using the Codenomicon TLS Test Tool (CVE-2004-0079) + [Joe Orton, Steve Henson] + + Changes between 0.9.6k and 0.9.6l [04 Nov 2003] + + *) Fix additional bug revealed by the NISCC test suite: + + Stop bug triggering large recursion when presented with + certain ASN.1 tags (CVE-2003-0851) + [Steve Henson] + + Changes between 0.9.6j and 0.9.6k [30 Sep 2003] + + *) Fix various bugs revealed by running the NISCC test suite: + + Stop out of bounds reads in the ASN1 code when presented with + invalid tags (CVE-2003-0543 and CVE-2003-0544). + + If verify callback ignores invalid public key errors don't try to check + certificate signature with the NULL public key. + + [Steve Henson] + + *) In ssl3_accept() (ssl/s3_srvr.c) only accept a client certificate + if the server requested one: as stated in TLS 1.0 and SSL 3.0 + specifications. + [Steve Henson] + + *) In ssl3_get_client_hello() (ssl/s3_srvr.c), tolerate additional + extra data after the compression methods not only for TLS 1.0 + but also for SSL 3.0 (as required by the specification). + [Bodo Moeller; problem pointed out by Matthias Loepfe] + + *) Change X509_certificate_type() to mark the key as exported/exportable + when it's 512 *bits* long, not 512 bytes. + [Richard Levitte] + + Changes between 0.9.6i and 0.9.6j [10 Apr 2003] + + *) Countermeasure against the Klima-Pokorny-Rosa extension of + Bleichbacher's attack on PKCS #1 v1.5 padding: treat + a protocol version number mismatch like a decryption error + in ssl3_get_client_key_exchange (ssl/s3_srvr.c). + [Bodo Moeller] + + *) Turn on RSA blinding by default in the default implementation + to avoid a timing attack. Applications that don't want it can call + RSA_blinding_off() or use the new flag RSA_FLAG_NO_BLINDING. + They would be ill-advised to do so in most cases. + [Ben Laurie, Steve Henson, Geoff Thorpe, Bodo Moeller] + + *) Change RSA blinding code so that it works when the PRNG is not + seeded (in this case, the secret RSA exponent is abused as + an unpredictable seed -- if it is not unpredictable, there + is no point in blinding anyway). Make RSA blinding thread-safe + by remembering the creator's thread ID in rsa->blinding and + having all other threads use local one-time blinding factors + (this requires more computation than sharing rsa->blinding, but + avoids excessive locking; and if an RSA object is not shared + between threads, blinding will still be very fast). + [Bodo Moeller] + + Changes between 0.9.6h and 0.9.6i [19 Feb 2003] + + *) In ssl3_get_record (ssl/s3_pkt.c), minimize information leaked + via timing by performing a MAC computation even if incorrrect + block cipher padding has been found. This is a countermeasure + against active attacks where the attacker has to distinguish + between bad padding and a MAC verification error. (CVE-2003-0078) + + [Bodo Moeller; problem pointed out by Brice Canvel (EPFL), + Alain Hiltgen (UBS), Serge Vaudenay (EPFL), and + Martin Vuagnoux (EPFL, Ilion)] + + Changes between 0.9.6g and 0.9.6h [5 Dec 2002] + + *) New function OPENSSL_cleanse(), which is used to cleanse a section of + memory from it's contents. This is done with a counter that will + place alternating values in each byte. This can be used to solve + two issues: 1) the removal of calls to memset() by highly optimizing + compilers, and 2) cleansing with other values than 0, since those can + be read through on certain media, for example a swap space on disk. + [Geoff Thorpe] + + *) Bugfix: client side session caching did not work with external caching, + because the session->cipher setting was not restored when reloading + from the external cache. This problem was masked, when + SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG (part of SSL_OP_ALL) was set. + (Found by Steve Haslam .) + [Lutz Jaenicke] + + *) Fix client_certificate (ssl/s2_clnt.c): The permissible total + length of the REQUEST-CERTIFICATE message is 18 .. 34, not 17 .. 33. + [Zeev Lieber ] + + *) Undo an undocumented change introduced in 0.9.6e which caused + repeated calls to OpenSSL_add_all_ciphers() and + OpenSSL_add_all_digests() to be ignored, even after calling + EVP_cleanup(). + [Richard Levitte] + + *) Change the default configuration reader to deal with last line not + being properly terminated. + [Richard Levitte] + + *) Change X509_NAME_cmp() so it applies the special rules on handling + DN values that are of type PrintableString, as well as RDNs of type + emailAddress where the value has the type ia5String. + [stefank@valicert.com via Richard Levitte] + + *) Add a SSL_SESS_CACHE_NO_INTERNAL_STORE flag to take over half + the job SSL_SESS_CACHE_NO_INTERNAL_LOOKUP was inconsistently + doing, define a new flag (SSL_SESS_CACHE_NO_INTERNAL) to be + the bitwise-OR of the two for use by the majority of applications + wanting this behaviour, and update the docs. The documented + behaviour and actual behaviour were inconsistent and had been + changing anyway, so this is more a bug-fix than a behavioural + change. + [Geoff Thorpe, diagnosed by Nadav Har'El] + + *) Don't impose a 16-byte length minimum on session IDs in ssl/s3_clnt.c + (the SSL 3.0 and TLS 1.0 specifications allow any length up to 32 bytes). + [Bodo Moeller] + + *) Fix initialization code race conditions in + SSLv23_method(), SSLv23_client_method(), SSLv23_server_method(), + SSLv2_method(), SSLv2_client_method(), SSLv2_server_method(), + SSLv3_method(), SSLv3_client_method(), SSLv3_server_method(), + TLSv1_method(), TLSv1_client_method(), TLSv1_server_method(), + ssl2_get_cipher_by_char(), + ssl3_get_cipher_by_char(). + [Patrick McCormick , Bodo Moeller] + + *) Reorder cleanup sequence in SSL_CTX_free(): only remove the ex_data after + the cached sessions are flushed, as the remove_cb() might use ex_data + contents. Bug found by Sam Varshavchik + (see [openssl.org #212]). + [Geoff Thorpe, Lutz Jaenicke] + + *) Fix typo in OBJ_txt2obj which incorrectly passed the content + length, instead of the encoding length to d2i_ASN1_OBJECT. + [Steve Henson] + + Changes between 0.9.6f and 0.9.6g [9 Aug 2002] + + *) [In 0.9.6g-engine release:] + Fix crypto/engine/vendor_defns/cswift.h for WIN32 (use '_stdcall'). + [Lynn Gazis ] + + Changes between 0.9.6e and 0.9.6f [8 Aug 2002] + + *) Fix ASN1 checks. Check for overflow by comparing with LONG_MAX + and get fix the header length calculation. + [Florian Weimer , + Alon Kantor (and others), + Steve Henson] + + *) Use proper error handling instead of 'assertions' in buffer + overflow checks added in 0.9.6e. This prevents DoS (the + assertions could call abort()). + [Arne Ansper , Bodo Moeller] + + Changes between 0.9.6d and 0.9.6e [30 Jul 2002] + + *) Add various sanity checks to asn1_get_length() to reject + the ASN1 length bytes if they exceed sizeof(long), will appear + negative or the content length exceeds the length of the + supplied buffer. + [Steve Henson, Adi Stav , James Yonan ] + + *) Fix cipher selection routines: ciphers without encryption had no flags + for the cipher strength set and where therefore not handled correctly + by the selection routines (PR #130). + [Lutz Jaenicke] + + *) Fix EVP_dsa_sha macro. + [Nils Larsch] + + *) New option + SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS + for disabling the SSL 3.0/TLS 1.0 CBC vulnerability countermeasure + that was added in OpenSSL 0.9.6d. + + As the countermeasure turned out to be incompatible with some + broken SSL implementations, the new option is part of SSL_OP_ALL. + SSL_OP_ALL is usually employed when compatibility with weird SSL + implementations is desired (e.g. '-bugs' option to 's_client' and + 's_server'), so the new option is automatically set in many + applications. + [Bodo Moeller] + + *) Changes in security patch: + + Changes marked "(CHATS)" were sponsored by the Defense Advanced + Research Projects Agency (DARPA) and Air Force Research Laboratory, + Air Force Materiel Command, USAF, under agreement number + F30602-01-2-0537. + + *) Add various sanity checks to asn1_get_length() to reject + the ASN1 length bytes if they exceed sizeof(long), will appear + negative or the content length exceeds the length of the + supplied buffer. (CVE-2002-0659) + [Steve Henson, Adi Stav , James Yonan ] + + *) Assertions for various potential buffer overflows, not known to + happen in practice. + [Ben Laurie (CHATS)] + + *) Various temporary buffers to hold ASCII versions of integers were + too small for 64 bit platforms. (CVE-2002-0655) + [Matthew Byng-Maddick and Ben Laurie (CHATS)> + + *) Remote buffer overflow in SSL3 protocol - an attacker could + supply an oversized session ID to a client. (CVE-2002-0656) + [Ben Laurie (CHATS)] + + *) Remote buffer overflow in SSL2 protocol - an attacker could + supply an oversized client master key. (CVE-2002-0656) + [Ben Laurie (CHATS)] + + Changes between 0.9.6c and 0.9.6d [9 May 2002] + + *) Fix crypto/asn1/a_sign.c so that 'parameters' is omitted (not + encoded as NULL) with id-dsa-with-sha1. + [Nils Larsch ; problem pointed out by Bodo Moeller] + + *) Check various X509_...() return values in apps/req.c. + [Nils Larsch ] + + *) Fix BASE64 decode (EVP_DecodeUpdate) for data with CR/LF ended lines: + an end-of-file condition would erronously be flagged, when the CRLF + was just at the end of a processed block. The bug was discovered when + processing data through a buffering memory BIO handing the data to a + BASE64-decoding BIO. Bug fund and patch submitted by Pavel Tsekov + and Nedelcho Stanev. + [Lutz Jaenicke] + + *) Implement a countermeasure against a vulnerability recently found + in CBC ciphersuites in SSL 3.0/TLS 1.0: Send an empty fragment + before application data chunks to avoid the use of known IVs + with data potentially chosen by the attacker. + [Bodo Moeller] + + *) Fix length checks in ssl3_get_client_hello(). + [Bodo Moeller] + + *) TLS/SSL library bugfix: use s->s3->in_read_app_data differently + to prevent ssl3_read_internal() from incorrectly assuming that + ssl3_read_bytes() found application data while handshake + processing was enabled when in fact s->s3->in_read_app_data was + merely automatically cleared during the initial handshake. + [Bodo Moeller; problem pointed out by Arne Ansper ] + + *) Fix object definitions for Private and Enterprise: they were not + recognized in their shortname (=lowercase) representation. Extend + obj_dat.pl to issue an error when using undefined keywords instead + of silently ignoring the problem (Svenning Sorensen + ). + [Lutz Jaenicke] + + *) Fix DH_generate_parameters() so that it works for 'non-standard' + generators, i.e. generators other than 2 and 5. (Previously, the + code did not properly initialise the 'add' and 'rem' values to + BN_generate_prime().) + + In the new general case, we do not insist that 'generator' is + actually a primitive root: This requirement is rather pointless; + a generator of the order-q subgroup is just as good, if not + better. + [Bodo Moeller] + + *) Map new X509 verification errors to alerts. Discovered and submitted by + Tom Wu . + [Lutz Jaenicke] + + *) Fix ssl3_pending() (ssl/s3_lib.c) to prevent SSL_pending() from + returning non-zero before the data has been completely received + when using non-blocking I/O. + [Bodo Moeller; problem pointed out by John Hughes] + + *) Some of the ciphers missed the strength entry (SSL_LOW etc). + [Ben Laurie, Lutz Jaenicke] + + *) Fix bug in SSL_clear(): bad sessions were not removed (found by + Yoram Zahavi ). + [Lutz Jaenicke] + + *) Add information about CygWin 1.3 and on, and preserve proper + configuration for the versions before that. + [Corinna Vinschen and Richard Levitte] + + *) Make removal from session cache (SSL_CTX_remove_session()) more robust: + check whether we deal with a copy of a session and do not delete from + the cache in this case. Problem reported by "Izhar Shoshani Levi" + . + [Lutz Jaenicke] + + *) Do not store session data into the internal session cache, if it + is never intended to be looked up (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP + flag is set). Proposed by Aslam . + [Lutz Jaenicke] + + *) Have ASN1_BIT_STRING_set_bit() really clear a bit when the requested + value is 0. + [Richard Levitte] + + *) [In 0.9.6d-engine release:] + Fix a crashbug and a logic bug in hwcrhk_load_pubkey(). + [Toomas Kiisk via Richard Levitte] + + *) Add the configuration target linux-s390x. + [Neale Ferguson via Richard Levitte] + + *) The earlier bugfix for the SSL3_ST_SW_HELLO_REQ_C case of + ssl3_accept (ssl/s3_srvr.c) incorrectly used a local flag + variable as an indication that a ClientHello message has been + received. As the flag value will be lost between multiple + invocations of ssl3_accept when using non-blocking I/O, the + function may not be aware that a handshake has actually taken + place, thus preventing a new session from being added to the + session cache. + + To avoid this problem, we now set s->new_session to 2 instead of + using a local variable. + [Lutz Jaenicke, Bodo Moeller] + + *) Bugfix: Return -1 from ssl3_get_server_done (ssl3/s3_clnt.c) + if the SSL_R_LENGTH_MISMATCH error is detected. + [Geoff Thorpe, Bodo Moeller] + + *) New 'shared_ldflag' column in Configure platform table. + [Richard Levitte] + + *) Fix EVP_CIPHER_mode macro. + ["Dan S. Camper" ] + + *) Fix ssl3_read_bytes (ssl/s3_pkt.c): To ignore messages of unknown + type, we must throw them away by setting rr->length to 0. + [D P Chang ] + + Changes between 0.9.6b and 0.9.6c [21 dec 2001] + + *) Fix BN_rand_range bug pointed out by Dominikus Scherkl + . (The previous implementation + worked incorrectly for those cases where range = 10..._2 and + 3*range is two bits longer than range.) + [Bodo Moeller] + + *) Only add signing time to PKCS7 structures if it is not already + present. + [Steve Henson] + + *) Fix crypto/objects/objects.h: "ld-ce" should be "id-ce", + OBJ_ld_ce should be OBJ_id_ce. + Also some ip-pda OIDs in crypto/objects/objects.txt were + incorrect (cf. RFC 3039). + [Matt Cooper, Frederic Giudicelli, Bodo Moeller] + + *) Release CRYPTO_LOCK_DYNLOCK when CRYPTO_destroy_dynlockid() + returns early because it has nothing to do. + [Andy Schneider ] + + *) [In 0.9.6c-engine release:] + Fix mutex callback return values in crypto/engine/hw_ncipher.c. + [Andy Schneider ] + + *) [In 0.9.6c-engine release:] + Add support for Cryptographic Appliance's keyserver technology. + (Use engine 'keyclient') + [Cryptographic Appliances and Geoff Thorpe] + + *) Add a configuration entry for OS/390 Unix. The C compiler 'c89' + is called via tools/c89.sh because arguments have to be + rearranged (all '-L' options must appear before the first object + modules). + [Richard Shapiro ] + + *) [In 0.9.6c-engine release:] + Add support for Broadcom crypto accelerator cards, backported + from 0.9.7. + [Broadcom, Nalin Dahyabhai , Mark Cox] + + *) [In 0.9.6c-engine release:] + Add support for SureWare crypto accelerator cards from + Baltimore Technologies. (Use engine 'sureware') + [Baltimore Technologies and Mark Cox] + + *) [In 0.9.6c-engine release:] + Add support for crypto accelerator cards from Accelerated + Encryption Processing, www.aep.ie. (Use engine 'aep') + [AEP Inc. and Mark Cox] + + *) Add a configuration entry for gcc on UnixWare. + [Gary Benson ] + + *) Change ssl/s2_clnt.c and ssl/s2_srvr.c so that received handshake + messages are stored in a single piece (fixed-length part and + variable-length part combined) and fix various bugs found on the way. + [Bodo Moeller] + + *) Disable caching in BIO_gethostbyname(), directly use gethostbyname() + instead. BIO_gethostbyname() does not know what timeouts are + appropriate, so entries would stay in cache even when they have + become invalid. + [Bodo Moeller; problem pointed out by Rich Salz + + *) Change ssl23_get_client_hello (ssl/s23_srvr.c) behaviour when + faced with a pathologically small ClientHello fragment that does + not contain client_version: Instead of aborting with an error, + simply choose the highest available protocol version (i.e., + TLS 1.0 unless it is disabled). In practice, ClientHello + messages are never sent like this, but this change gives us + strictly correct behaviour at least for TLS. + [Bodo Moeller] + + *) Fix SSL handshake functions and SSL_clear() such that SSL_clear() + never resets s->method to s->ctx->method when called from within + one of the SSL handshake functions. + [Bodo Moeller; problem pointed out by Niko Baric] + + *) In ssl3_get_client_hello (ssl/s3_srvr.c), generate a fatal alert + (sent using the client's version number) if client_version is + smaller than the protocol version in use. Also change + ssl23_get_client_hello (ssl/s23_srvr.c) to select TLS 1.0 if + the client demanded SSL 3.0 but only TLS 1.0 is enabled; then + the client will at least see that alert. + [Bodo Moeller] + + *) Fix ssl3_get_message (ssl/s3_both.c) to handle message fragmentation + correctly. + [Bodo Moeller] + + *) Avoid infinite loop in ssl3_get_message (ssl/s3_both.c) if a + client receives HelloRequest while in a handshake. + [Bodo Moeller; bug noticed by Andy Schneider ] + + *) Bugfix in ssl3_accept (ssl/s3_srvr.c): Case SSL3_ST_SW_HELLO_REQ_C + should end in 'break', not 'goto end' which circuments various + cleanups done in state SSL_ST_OK. But session related stuff + must be disabled for SSL_ST_OK in the case that we just sent a + HelloRequest. + + Also avoid some overhead by not calling ssl_init_wbio_buffer() + before just sending a HelloRequest. + [Bodo Moeller, Eric Rescorla ] + + *) Fix ssl/s3_enc.c, ssl/t1_enc.c and ssl/s3_pkt.c so that we don't + reveal whether illegal block cipher padding was found or a MAC + verification error occured. (Neither SSLerr() codes nor alerts + are directly visible to potential attackers, but the information + may leak via logfiles.) + + Similar changes are not required for the SSL 2.0 implementation + because the number of padding bytes is sent in clear for SSL 2.0, + and the extra bytes are just ignored. However ssl/s2_pkt.c + failed to verify that the purported number of padding bytes is in + the legal range. + [Bodo Moeller] + + *) Add OpenUNIX-8 support including shared libraries + (Boyd Lynn Gerber ). + [Lutz Jaenicke] + + *) Improve RSA_padding_check_PKCS1_OAEP() check again to avoid + 'wristwatch attack' using huge encoding parameters (cf. + James H. Manger's CRYPTO 2001 paper). Note that the + RSA_PKCS1_OAEP_PADDING case of RSA_private_decrypt() does not use + encoding parameters and hence was not vulnerable. + [Bodo Moeller] + + *) BN_sqr() bug fix. + [Ulf Möller, reported by Jim Ellis ] + + *) Rabin-Miller test analyses assume uniformly distributed witnesses, + so use BN_pseudo_rand_range() instead of using BN_pseudo_rand() + followed by modular reduction. + [Bodo Moeller; pointed out by Adam Young ] + + *) Add BN_pseudo_rand_range() with obvious functionality: BN_rand_range() + equivalent based on BN_pseudo_rand() instead of BN_rand(). + [Bodo Moeller] + + *) s3_srvr.c: allow sending of large client certificate lists (> 16 kB). + This function was broken, as the check for a new client hello message + to handle SGC did not allow these large messages. + (Tracked down by "Douglas E. Engert" .) + [Lutz Jaenicke] + + *) Add alert descriptions for TLSv1 to SSL_alert_desc_string[_long](). + [Lutz Jaenicke] + + *) Fix buggy behaviour of BIO_get_num_renegotiates() and BIO_ctrl() + for BIO_C_GET_WRITE_BUF_SIZE ("Stephen Hinton" ). + [Lutz Jaenicke] + + *) Rework the configuration and shared library support for Tru64 Unix. + The configuration part makes use of modern compiler features and + still retains old compiler behavior for those that run older versions + of the OS. The shared library support part includes a variant that + uses the RPATH feature, and is available through the special + configuration target "alpha-cc-rpath", which will never be selected + automatically. + [Tim Mooney via Richard Levitte] + + *) In ssl3_get_key_exchange (ssl/s3_clnt.c), call ssl3_get_message() + with the same message size as in ssl3_get_certificate_request(). + Otherwise, if no ServerKeyExchange message occurs, CertificateRequest + messages might inadvertently be reject as too long. + [Petr Lampa ] + + *) Enhanced support for IA-64 Unix platforms (well, Linux and HP-UX). + [Andy Polyakov] + + *) Modified SSL library such that the verify_callback that has been set + specificly for an SSL object with SSL_set_verify() is actually being + used. Before the change, a verify_callback set with this function was + ignored and the verify_callback() set in the SSL_CTX at the time of + the call was used. New function X509_STORE_CTX_set_verify_cb() introduced + to allow the necessary settings. + [Lutz Jaenicke] + + *) Initialize static variable in crypto/dsa/dsa_lib.c and crypto/dh/dh_lib.c + explicitly to NULL, as at least on Solaris 8 this seems not always to be + done automatically (in contradiction to the requirements of the C + standard). This made problems when used from OpenSSH. + [Lutz Jaenicke] + + *) In OpenSSL 0.9.6a and 0.9.6b, crypto/dh/dh_key.c ignored + dh->length and always used + + BN_rand_range(priv_key, dh->p). + + BN_rand_range() is not necessary for Diffie-Hellman, and this + specific range makes Diffie-Hellman unnecessarily inefficient if + dh->length (recommended exponent length) is much smaller than the + length of dh->p. We could use BN_rand_range() if the order of + the subgroup was stored in the DH structure, but we only have + dh->length. + + So switch back to + + BN_rand(priv_key, l, ...) + + where 'l' is dh->length if this is defined, or BN_num_bits(dh->p)-1 + otherwise. + [Bodo Moeller] + + *) In + + RSA_eay_public_encrypt + RSA_eay_private_decrypt + RSA_eay_private_encrypt (signing) + RSA_eay_public_decrypt (signature verification) + + (default implementations for RSA_public_encrypt, + RSA_private_decrypt, RSA_private_encrypt, RSA_public_decrypt), + always reject numbers >= n. + [Bodo Moeller] + + *) In crypto/rand/md_rand.c, use a new short-time lock CRYPTO_LOCK_RAND2 + to synchronize access to 'locking_thread'. This is necessary on + systems where access to 'locking_thread' (an 'unsigned long' + variable) is not atomic. + [Bodo Moeller] + + *) In crypto/rand/md_rand.c, set 'locking_thread' to current thread's ID + *before* setting the 'crypto_lock_rand' flag. The previous code had + a race condition if 0 is a valid thread ID. + [Travis Vitek ] + + *) Add support for shared libraries under Irix. + [Albert Chin-A-Young ] + + *) Add configuration option to build on Linux on both big-endian and + little-endian MIPS. + [Ralf Baechle ] + + *) Add the possibility to create shared libraries on HP-UX. + [Richard Levitte] + + Changes between 0.9.6a and 0.9.6b [9 Jul 2001] + + *) Change ssleay_rand_bytes (crypto/rand/md_rand.c) + to avoid a SSLeay/OpenSSL PRNG weakness pointed out by + Markku-Juhani O. Saarinen : + PRNG state recovery was possible based on the output of + one PRNG request appropriately sized to gain knowledge on + 'md' followed by enough consecutive 1-byte PRNG requests + to traverse all of 'state'. + + 1. When updating 'md_local' (the current thread's copy of 'md') + during PRNG output generation, hash all of the previous + 'md_local' value, not just the half used for PRNG output. + + 2. Make the number of bytes from 'state' included into the hash + independent from the number of PRNG bytes requested. + + The first measure alone would be sufficient to avoid + Markku-Juhani's attack. (Actually it had never occurred + to me that the half of 'md_local' used for chaining was the + half from which PRNG output bytes were taken -- I had always + assumed that the secret half would be used.) The second + measure makes sure that additional data from 'state' is never + mixed into 'md_local' in small portions; this heuristically + further strengthens the PRNG. + [Bodo Moeller] + + *) Fix crypto/bn/asm/mips3.s. + [Andy Polyakov] + + *) When only the key is given to "enc", the IV is undefined. Print out + an error message in this case. + [Lutz Jaenicke] + + *) Handle special case when X509_NAME is empty in X509 printing routines. + [Steve Henson] + + *) In dsa_do_verify (crypto/dsa/dsa_ossl.c), verify that r and s are + positive and less than q. + [Bodo Moeller] + + *) Don't change *pointer in CRYPTO_add_lock() is add_lock_callback is + used: it isn't thread safe and the add_lock_callback should handle + that itself. + [Paul Rose ] + + *) Verify that incoming data obeys the block size in + ssl3_enc (ssl/s3_enc.c) and tls1_enc (ssl/t1_enc.c). + [Bodo Moeller] + + *) Fix OAEP check. + [Ulf Möller, Bodo Möller] + + *) The countermeasure against Bleichbacher's attack on PKCS #1 v1.5 + RSA encryption was accidentally removed in s3_srvr.c in OpenSSL 0.9.5 + when fixing the server behaviour for backwards-compatible 'client + hello' messages. (Note that the attack is impractical against + SSL 3.0 and TLS 1.0 anyway because length and version checking + means that the probability of guessing a valid ciphertext is + around 2^-40; see section 5 in Bleichenbacher's CRYPTO '98 + paper.) + + Before 0.9.5, the countermeasure (hide the error by generating a + random 'decryption result') did not work properly because + ERR_clear_error() was missing, meaning that SSL_get_error() would + detect the supposedly ignored error. + + Both problems are now fixed. + [Bodo Moeller] + + *) In crypto/bio/bf_buff.c, increase DEFAULT_BUFFER_SIZE to 4096 + (previously it was 1024). + [Bodo Moeller] + + *) Fix for compatibility mode trust settings: ignore trust settings + unless some valid trust or reject settings are present. + [Steve Henson] + + *) Fix for blowfish EVP: its a variable length cipher. + [Steve Henson] + + *) Fix various bugs related to DSA S/MIME verification. Handle missing + parameters in DSA public key structures and return an error in the + DSA routines if parameters are absent. + [Steve Henson] + + *) In versions up to 0.9.6, RAND_file_name() resorted to file ".rnd" + in the current directory if neither $RANDFILE nor $HOME was set. + RAND_file_name() in 0.9.6a returned NULL in this case. This has + caused some confusion to Windows users who haven't defined $HOME. + Thus RAND_file_name() is changed again: e_os.h can define a + DEFAULT_HOME, which will be used if $HOME is not set. + For Windows, we use "C:"; on other platforms, we still require + environment variables. + + *) Move 'if (!initialized) RAND_poll()' into regions protected by + CRYPTO_LOCK_RAND. This is not strictly necessary, but avoids + having multiple threads call RAND_poll() concurrently. + [Bodo Moeller] + + *) In crypto/rand/md_rand.c, replace 'add_do_not_lock' flag by a + combination of a flag and a thread ID variable. + Otherwise while one thread is in ssleay_rand_bytes (which sets the + flag), *other* threads can enter ssleay_add_bytes without obeying + the CRYPTO_LOCK_RAND lock (and may even illegally release the lock + that they do not hold after the first thread unsets add_do_not_lock). + [Bodo Moeller] + + *) Change bctest again: '-x' expressions are not available in all + versions of 'test'. + [Bodo Moeller] + + Changes between 0.9.6 and 0.9.6a [5 Apr 2001] + + *) Fix a couple of memory leaks in PKCS7_dataDecode() + [Steve Henson, reported by Heyun Zheng ] + + *) Change Configure and Makefiles to provide EXE_EXT, which will contain + the default extension for executables, if any. Also, make the perl + scripts that use symlink() to test if it really exists and use "cp" + if it doesn't. All this made OpenSSL compilable and installable in + CygWin. + [Richard Levitte] + + *) Fix for asn1_GetSequence() for indefinite length constructed data. + If SEQUENCE is length is indefinite just set c->slen to the total + amount of data available. + [Steve Henson, reported by shige@FreeBSD.org] + [This change does not apply to 0.9.7.] + + *) Change bctest to avoid here-documents inside command substitution + (workaround for FreeBSD /bin/sh bug). + For compatibility with Ultrix, avoid shell functions (introduced + in the bctest version that searches along $PATH). + [Bodo Moeller] + + *) Rename 'des_encrypt' to 'des_encrypt1'. This avoids the clashes + with des_encrypt() defined on some operating systems, like Solaris + and UnixWare. + [Richard Levitte] + + *) Check the result of RSA-CRT (see D. Boneh, R. DeMillo, R. Lipton: + On the Importance of Eliminating Errors in Cryptographic + Computations, J. Cryptology 14 (2001) 2, 101-119, + http://theory.stanford.edu/~dabo/papers/faults.ps.gz). + [Ulf Moeller] + + *) MIPS assembler BIGNUM division bug fix. + [Andy Polyakov] + + *) Disabled incorrect Alpha assembler code. + [Richard Levitte] + + *) Fix PKCS#7 decode routines so they correctly update the length + after reading an EOC for the EXPLICIT tag. + [Steve Henson] + [This change does not apply to 0.9.7.] + + *) Fix bug in PKCS#12 key generation routines. This was triggered + if a 3DES key was generated with a 0 initial byte. Include + PKCS12_BROKEN_KEYGEN compilation option to retain the old + (but broken) behaviour. + [Steve Henson] + + *) Enhance bctest to search for a working bc along $PATH and print + it when found. + [Tim Rice via Richard Levitte] + + *) Fix memory leaks in err.c: free err_data string if necessary; + don't write to the wrong index in ERR_set_error_data. + [Bodo Moeller] + + *) Implement ssl23_peek (analogous to ssl23_read), which previously + did not exist. + [Bodo Moeller] + + *) Replace rdtsc with _emit statements for VC++ version 5. + [Jeremy Cooper ] + + *) Make it possible to reuse SSLv2 sessions. + [Richard Levitte] + + *) In copy_email() check for >= 0 as a return value for + X509_NAME_get_index_by_NID() since 0 is a valid index. + [Steve Henson reported by Massimiliano Pala ] + + *) Avoid coredump with unsupported or invalid public keys by checking if + X509_get_pubkey() fails in PKCS7_verify(). Fix memory leak when + PKCS7_verify() fails with non detached data. + [Steve Henson] + + *) Don't use getenv in library functions when run as setuid/setgid. + New function OPENSSL_issetugid(). + [Ulf Moeller] + + *) Avoid false positives in memory leak detection code (crypto/mem_dbg.c) + due to incorrect handling of multi-threading: + + 1. Fix timing glitch in the MemCheck_off() portion of CRYPTO_mem_ctrl(). + + 2. Fix logical glitch in is_MemCheck_on() aka CRYPTO_is_mem_check_on(). + + 3. Count how many times MemCheck_off() has been called so that + nested use can be treated correctly. This also avoids + inband-signalling in the previous code (which relied on the + assumption that thread ID 0 is impossible). + [Bodo Moeller] + + *) Add "-rand" option also to s_client and s_server. + [Lutz Jaenicke] + + *) Fix CPU detection on Irix 6.x. + [Kurt Hockenbury and + "Bruce W. Forsberg" ] + + *) Fix X509_NAME bug which produced incorrect encoding if X509_NAME + was empty. + [Steve Henson] + [This change does not apply to 0.9.7.] + + *) Use the cached encoding of an X509_NAME structure rather than + copying it. This is apparently the reason for the libsafe "errors" + but the code is actually correct. + [Steve Henson] + + *) Add new function BN_rand_range(), and fix DSA_sign_setup() to prevent + Bleichenbacher's DSA attack. + Extend BN_[pseudo_]rand: As before, top=1 forces the highest two bits + to be set and top=0 forces the highest bit to be set; top=-1 is new + and leaves the highest bit random. + [Ulf Moeller, Bodo Moeller] + + *) In the NCONF_...-based implementations for CONF_... queries + (crypto/conf/conf_lib.c), if the input LHASH is NULL, avoid using + a temporary CONF structure with the data component set to NULL + (which gives segmentation faults in lh_retrieve). + Instead, use NULL for the CONF pointer in CONF_get_string and + CONF_get_number (which may use environment variables) and directly + return NULL from CONF_get_section. + [Bodo Moeller] + + *) Fix potential buffer overrun for EBCDIC. + [Ulf Moeller] + + *) Tolerate nonRepudiation as being valid for S/MIME signing and certSign + keyUsage if basicConstraints absent for a CA. + [Steve Henson] + + *) Make SMIME_write_PKCS7() write mail header values with a format that + is more generally accepted (no spaces before the semicolon), since + some programs can't parse those values properly otherwise. Also make + sure BIO's that break lines after each write do not create invalid + headers. + [Richard Levitte] + + *) Make the CRL encoding routines work with empty SEQUENCE OF. The + macros previously used would not encode an empty SEQUENCE OF + and break the signature. + [Steve Henson] + [This change does not apply to 0.9.7.] + + *) Zero the premaster secret after deriving the master secret in + DH ciphersuites. + [Steve Henson] + + *) Add some EVP_add_digest_alias registrations (as found in + OpenSSL_add_all_digests()) to SSL_library_init() + aka OpenSSL_add_ssl_algorithms(). This provides improved + compatibility with peers using X.509 certificates + with unconventional AlgorithmIdentifier OIDs. + [Bodo Moeller] + + *) Fix for Irix with NO_ASM. + ["Bruce W. Forsberg" ] + + *) ./config script fixes. + [Ulf Moeller, Richard Levitte] + + *) Fix 'openssl passwd -1'. + [Bodo Moeller] + + *) Change PKCS12_key_gen_asc() so it can cope with non null + terminated strings whose length is passed in the passlen + parameter, for example from PEM callbacks. This was done + by adding an extra length parameter to asc2uni(). + [Steve Henson, reported by ] + + *) Fix C code generated by 'openssl dsaparam -C': If a BN_bin2bn + call failed, free the DSA structure. + [Bodo Moeller] + + *) Fix to uni2asc() to cope with zero length Unicode strings. + These are present in some PKCS#12 files. + [Steve Henson] + + *) Increase s2->wbuf allocation by one byte in ssl2_new (ssl/s2_lib.c). + Otherwise do_ssl_write (ssl/s2_pkt.c) will write beyond buffer limits + when writing a 32767 byte record. + [Bodo Moeller; problem reported by Eric Day ] + + *) In RSA_eay_public_{en,ed}crypt and RSA_eay_mod_exp (rsa_eay.c), + obtain lock CRYPTO_LOCK_RSA before setting rsa->_method_mod_{n,p,q}. + + (RSA objects have a reference count access to which is protected + by CRYPTO_LOCK_RSA [see rsa_lib.c, s3_srvr.c, ssl_cert.c, ssl_rsa.c], + so they are meant to be shared between threads.) + [Bodo Moeller, Geoff Thorpe; original patch submitted by + "Reddie, Steven" ] + + *) Fix a deadlock in CRYPTO_mem_leaks(). + [Bodo Moeller] + + *) Use better test patterns in bntest. + [Ulf Möller] + + *) rand_win.c fix for Borland C. + [Ulf Möller] + + *) BN_rshift bugfix for n == 0. + [Bodo Moeller] + + *) Add a 'bctest' script that checks for some known 'bc' bugs + so that 'make test' does not abort just because 'bc' is broken. + [Bodo Moeller] + + *) Store verify_result within SSL_SESSION also for client side to + avoid potential security hole. (Re-used sessions on the client side + always resulted in verify_result==X509_V_OK, not using the original + result of the server certificate verification.) + [Lutz Jaenicke] + + *) Fix ssl3_pending: If the record in s->s3->rrec is not of type + SSL3_RT_APPLICATION_DATA, return 0. + Similarly, change ssl2_pending to return 0 if SSL_in_init(s) is true. + [Bodo Moeller] + + *) Fix SSL_peek: + Both ssl2_peek and ssl3_peek, which were totally broken in earlier + releases, have been re-implemented by renaming the previous + implementations of ssl2_read and ssl3_read to ssl2_read_internal + and ssl3_read_internal, respectively, and adding 'peek' parameters + to them. The new ssl[23]_{read,peek} functions are calls to + ssl[23]_read_internal with the 'peek' flag set appropriately. + A 'peek' parameter has also been added to ssl3_read_bytes, which + does the actual work for ssl3_read_internal. + [Bodo Moeller] + + *) Initialise "ex_data" member of RSA/DSA/DH structures prior to calling + the method-specific "init()" handler. Also clean up ex_data after + calling the method-specific "finish()" handler. Previously, this was + happening the other way round. + [Geoff Thorpe] + + *) Increase BN_CTX_NUM (the number of BIGNUMs in a BN_CTX) to 16. + The previous value, 12, was not always sufficient for BN_mod_exp(). + [Bodo Moeller] + + *) Make sure that shared libraries get the internal name engine with + the full version number and not just 0. This should mark the + shared libraries as not backward compatible. Of course, this should + be changed again when we can guarantee backward binary compatibility. + [Richard Levitte] + + *) Fix typo in get_cert_by_subject() in by_dir.c + [Jean-Marc Desperrier ] + + *) Rework the system to generate shared libraries: + + - Make note of the expected extension for the shared libraries and + if there is a need for symbolic links from for example libcrypto.so.0 + to libcrypto.so.0.9.7. There is extended info in Configure for + that. + + - Make as few rebuilds of the shared libraries as possible. + + - Still avoid linking the OpenSSL programs with the shared libraries. + + - When installing, install the shared libraries separately from the + static ones. + [Richard Levitte] + + *) Fix SSL_CTX_set_read_ahead macro to actually use its argument. + + Copy SSL_CTX's read_ahead flag to SSL object directly in SSL_new + and not in SSL_clear because the latter is also used by the + accept/connect functions; previously, the settings made by + SSL_set_read_ahead would be lost during the handshake. + [Bodo Moeller; problems reported by Anders Gertz ] + + *) Correct util/mkdef.pl to be selective about disabled algorithms. + Previously, it would create entries for disableed algorithms no + matter what. + [Richard Levitte] + + *) Added several new manual pages for SSL_* function. + [Lutz Jaenicke] + + Changes between 0.9.5a and 0.9.6 [24 Sep 2000] + + *) In ssl23_get_client_hello, generate an error message when faced + with an initial SSL 3.0/TLS record that is too small to contain the + first two bytes of the ClientHello message, i.e. client_version. + (Note that this is a pathologic case that probably has never happened + in real life.) The previous approach was to use the version number + from the record header as a substitute; but our protocol choice + should not depend on that one because it is not authenticated + by the Finished messages. + [Bodo Moeller] + + *) More robust randomness gathering functions for Windows. + [Jeffrey Altman ] + + *) For compatibility reasons if the flag X509_V_FLAG_ISSUER_CHECK is + not set then we don't setup the error code for issuer check errors + to avoid possibly overwriting other errors which the callback does + handle. If an application does set the flag then we assume it knows + what it is doing and can handle the new informational codes + appropriately. + [Steve Henson] + + *) Fix for a nasty bug in ASN1_TYPE handling. ASN1_TYPE is used for + a general "ANY" type, as such it should be able to decode anything + including tagged types. However it didn't check the class so it would + wrongly interpret tagged types in the same way as their universal + counterpart and unknown types were just rejected. Changed so that the + tagged and unknown types are handled in the same way as a SEQUENCE: + that is the encoding is stored intact. There is also a new type + "V_ASN1_OTHER" which is used when the class is not universal, in this + case we have no idea what the actual type is so we just lump them all + together. + [Steve Henson] + + *) On VMS, stdout may very well lead to a file that is written to + in a record-oriented fashion. That means that every write() will + write a separate record, which will be read separately by the + programs trying to read from it. This can be very confusing. + + The solution is to put a BIO filter in the way that will buffer + text until a linefeed is reached, and then write everything a + line at a time, so every record written will be an actual line, + not chunks of lines and not (usually doesn't happen, but I've + seen it once) several lines in one record. BIO_f_linebuffer() is + the answer. + + Currently, it's a VMS-only method, because that's where it has + been tested well enough. + [Richard Levitte] + + *) Remove 'optimized' squaring variant in BN_mod_mul_montgomery, + it can return incorrect results. + (Note: The buggy variant was not enabled in OpenSSL 0.9.5a, + but it was in 0.9.6-beta[12].) + [Bodo Moeller] + + *) Disable the check for content being present when verifying detached + signatures in pk7_smime.c. Some versions of Netscape (wrongly) + include zero length content when signing messages. + [Steve Henson] + + *) New BIO_shutdown_wr macro, which invokes the BIO_C_SHUTDOWN_WR + BIO_ctrl (for BIO pairs). + [Bodo Möller] + + *) Add DSO method for VMS. + [Richard Levitte] + + *) Bug fix: Montgomery multiplication could produce results with the + wrong sign. + [Ulf Möller] + + *) Add RPM specification openssl.spec and modify it to build three + packages. The default package contains applications, application + documentation and run-time libraries. The devel package contains + include files, static libraries and function documentation. The + doc package contains the contents of the doc directory. The original + openssl.spec was provided by Damien Miller . + [Richard Levitte] + + *) Add a large number of documentation files for many SSL routines. + [Lutz Jaenicke ] + + *) Add a configuration entry for Sony News 4. + [NAKAJI Hiroyuki ] + + *) Don't set the two most significant bits to one when generating a + random number < q in the DSA library. + [Ulf Möller] + + *) New SSL API mode 'SSL_MODE_AUTO_RETRY'. This disables the default + behaviour that SSL_read may result in SSL_ERROR_WANT_READ (even if + the underlying transport is blocking) if a handshake took place. + (The default behaviour is needed by applications such as s_client + and s_server that use select() to determine when to use SSL_read; + but for applications that know in advance when to expect data, it + just makes things more complicated.) + [Bodo Moeller] + + *) Add RAND_egd_bytes(), which gives control over the number of bytes read + from EGD. + [Ben Laurie] + + *) Add a few more EBCDIC conditionals that make `req' and `x509' + work better on such systems. + [Martin Kraemer ] + + *) Add two demo programs for PKCS12_parse() and PKCS12_create(). + Update PKCS12_parse() so it copies the friendlyName and the + keyid to the certificates aux info. + [Steve Henson] + + *) Fix bug in PKCS7_verify() which caused an infinite loop + if there was more than one signature. + [Sven Uszpelkat ] + + *) Major change in util/mkdef.pl to include extra information + about each symbol, as well as presentig variables as well + as functions. This change means that there's n more need + to rebuild the .num files when some algorithms are excluded. + [Richard Levitte] + + *) Allow the verify time to be set by an application, + rather than always using the current time. + [Steve Henson] + + *) Phase 2 verify code reorganisation. The certificate + verify code now looks up an issuer certificate by a + number of criteria: subject name, authority key id + and key usage. It also verifies self signed certificates + by the same criteria. The main comparison function is + X509_check_issued() which performs these checks. + + Lot of changes were necessary in order to support this + without completely rewriting the lookup code. + + Authority and subject key identifier are now cached. + + The LHASH 'certs' is X509_STORE has now been replaced + by a STACK_OF(X509_OBJECT). This is mainly because an + LHASH can't store or retrieve multiple objects with + the same hash value. + + As a result various functions (which were all internal + use only) have changed to handle the new X509_STORE + structure. This will break anything that messed round + with X509_STORE internally. + + The functions X509_STORE_add_cert() now checks for an + exact match, rather than just subject name. + + The X509_STORE API doesn't directly support the retrieval + of multiple certificates matching a given criteria, however + this can be worked round by performing a lookup first + (which will fill the cache with candidate certificates) + and then examining the cache for matches. This is probably + the best we can do without throwing out X509_LOOKUP + entirely (maybe later...). + + The X509_VERIFY_CTX structure has been enhanced considerably. + + All certificate lookup operations now go via a get_issuer() + callback. Although this currently uses an X509_STORE it + can be replaced by custom lookups. This is a simple way + to bypass the X509_STORE hackery necessary to make this + work and makes it possible to use more efficient techniques + in future. A very simple version which uses a simple + STACK for its trusted certificate store is also provided + using X509_STORE_CTX_trusted_stack(). + + The verify_cb() and verify() callbacks now have equivalents + in the X509_STORE_CTX structure. + + X509_STORE_CTX also has a 'flags' field which can be used + to customise the verify behaviour. + [Steve Henson] + + *) Add new PKCS#7 signing option PKCS7_NOSMIMECAP which + excludes S/MIME capabilities. + [Steve Henson] + + *) When a certificate request is read in keep a copy of the + original encoding of the signed data and use it when outputing + again. Signatures then use the original encoding rather than + a decoded, encoded version which may cause problems if the + request is improperly encoded. + [Steve Henson] + + *) For consistency with other BIO_puts implementations, call + buffer_write(b, ...) directly in buffer_puts instead of calling + BIO_write(b, ...). + + In BIO_puts, increment b->num_write as in BIO_write. + [Peter.Sylvester@EdelWeb.fr] + + *) Fix BN_mul_word for the case where the word is 0. (We have to use + BN_zero, we may not return a BIGNUM with an array consisting of + words set to zero.) + [Bodo Moeller] + + *) Avoid calling abort() from within the library when problems are + detected, except if preprocessor symbols have been defined + (such as REF_CHECK, BN_DEBUG etc.). + [Bodo Moeller] + + *) New openssl application 'rsautl'. This utility can be + used for low level RSA operations. DER public key + BIO/fp routines also added. + [Steve Henson] + + *) New Configure entry and patches for compiling on QNX 4. + [Andreas Schneider ] + + *) A demo state-machine implementation was sponsored by + Nuron (http://www.nuron.com/) and is now available in + demos/state_machine. + [Ben Laurie] + + *) New options added to the 'dgst' utility for signature + generation and verification. + [Steve Henson] + + *) Unrecognized PKCS#7 content types are now handled via a + catch all ASN1_TYPE structure. This allows unsupported + types to be stored as a "blob" and an application can + encode and decode it manually. + [Steve Henson] + + *) Fix various signed/unsigned issues to make a_strex.c + compile under VC++. + [Oscar Jacobsson ] + + *) ASN1 fixes. i2d_ASN1_OBJECT was not returning the correct + length if passed a buffer. ASN1_INTEGER_to_BN failed + if passed a NULL BN and its argument was negative. + [Steve Henson, pointed out by Sven Heiberg ] + + *) Modification to PKCS#7 encoding routines to output definite + length encoding. Since currently the whole structures are in + memory there's not real point in using indefinite length + constructed encoding. However if OpenSSL is compiled with + the flag PKCS7_INDEFINITE_ENCODING the old form is used. + [Steve Henson] + + *) Added BIO_vprintf() and BIO_vsnprintf(). + [Richard Levitte] + + *) Added more prefixes to parse for in the the strings written + through a logging bio, to cover all the levels that are available + through syslog. The prefixes are now: + + PANIC, EMERG, EMR => LOG_EMERG + ALERT, ALR => LOG_ALERT + CRIT, CRI => LOG_CRIT + ERROR, ERR => LOG_ERR + WARNING, WARN, WAR => LOG_WARNING + NOTICE, NOTE, NOT => LOG_NOTICE + INFO, INF => LOG_INFO + DEBUG, DBG => LOG_DEBUG + + and as before, if none of those prefixes are present at the + beginning of the string, LOG_ERR is chosen. + + On Win32, the LOG_* levels are mapped according to this: + + LOG_EMERG, LOG_ALERT, LOG_CRIT, LOG_ERR => EVENTLOG_ERROR_TYPE + LOG_WARNING => EVENTLOG_WARNING_TYPE + LOG_NOTICE, LOG_INFO, LOG_DEBUG => EVENTLOG_INFORMATION_TYPE + + [Richard Levitte] + + *) Made it possible to reconfigure with just the configuration + argument "reconf" or "reconfigure". The command line arguments + are stored in Makefile.ssl in the variable CONFIGURE_ARGS, + and are retrieved from there when reconfiguring. + [Richard Levitte] + + *) MD4 implemented. + [Assar Westerlund , Richard Levitte] + + *) Add the arguments -CAfile and -CApath to the pkcs12 utility. + [Richard Levitte] + + *) The obj_dat.pl script was messing up the sorting of object + names. The reason was that it compared the quoted version + of strings as a result "OCSP" > "OCSP Signing" because + " > SPACE. Changed script to store unquoted versions of + names and add quotes on output. It was also omitting some + names from the lookup table if they were given a default + value (that is if SN is missing it is given the same + value as LN and vice versa), these are now added on the + grounds that if an object has a name we should be able to + look it up. Finally added warning output when duplicate + short or long names are found. + [Steve Henson] + + *) Changes needed for Tandem NSK. + [Scott Uroff ] + + *) Fix SSL 2.0 rollback checking: Due to an off-by-one error in + RSA_padding_check_SSLv23(), special padding was never detected + and thus the SSL 3.0/TLS 1.0 countermeasure against protocol + version rollback attacks was not effective. + + In s23_clnt.c, don't use special rollback-attack detection padding + (RSA_SSLV23_PADDING) if SSL 2.0 is the only protocol enabled in the + client; similarly, in s23_srvr.c, don't do the rollback check if + SSL 2.0 is the only protocol enabled in the server. + [Bodo Moeller] + + *) Make it possible to get hexdumps of unprintable data with 'openssl + asn1parse'. By implication, the functions ASN1_parse_dump() and + BIO_dump_indent() are added. + [Richard Levitte] + + *) New functions ASN1_STRING_print_ex() and X509_NAME_print_ex() + these print out strings and name structures based on various + flags including RFC2253 support and proper handling of + multibyte characters. Added options to the 'x509' utility + to allow the various flags to be set. + [Steve Henson] + + *) Various fixes to use ASN1_TIME instead of ASN1_UTCTIME. + Also change the functions X509_cmp_current_time() and + X509_gmtime_adj() work with an ASN1_TIME structure, + this will enable certificates using GeneralizedTime in validity + dates to be checked. + [Steve Henson] + + *) Make the NEG_PUBKEY_BUG code (which tolerates invalid + negative public key encodings) on by default, + NO_NEG_PUBKEY_BUG can be set to disable it. + [Steve Henson] + + *) New function c2i_ASN1_OBJECT() which acts on ASN1_OBJECT + content octets. An i2c_ASN1_OBJECT is unnecessary because + the encoding can be trivially obtained from the structure. + [Steve Henson] + + *) crypto/err.c locking bugfix: Use write locks (CRYPTO_w_[un]lock), + not read locks (CRYPTO_r_[un]lock). + [Bodo Moeller] + + *) A first attempt at creating official support for shared + libraries through configuration. I've kept it so the + default is static libraries only, and the OpenSSL programs + are always statically linked for now, but there are + preparations for dynamic linking in place. + This has been tested on Linux and Tru64. + [Richard Levitte] + + *) Randomness polling function for Win9x, as described in: + Peter Gutmann, Software Generation of Practically Strong + Random Numbers. + [Ulf Möller] + + *) Fix so PRNG is seeded in req if using an already existing + DSA key. + [Steve Henson] + + *) New options to smime application. -inform and -outform + allow alternative formats for the S/MIME message including + PEM and DER. The -content option allows the content to be + specified separately. This should allow things like Netscape + form signing output easier to verify. + [Steve Henson] + + *) Fix the ASN1 encoding of tags using the 'long form'. + [Steve Henson] + + *) New ASN1 functions, i2c_* and c2i_* for INTEGER and BIT + STRING types. These convert content octets to and from the + underlying type. The actual tag and length octets are + already assumed to have been read in and checked. These + are needed because all other string types have virtually + identical handling apart from the tag. By having versions + of the ASN1 functions that just operate on content octets + IMPLICIT tagging can be handled properly. It also allows + the ASN1_ENUMERATED code to be cut down because ASN1_ENUMERATED + and ASN1_INTEGER are identical apart from the tag. + [Steve Henson] + + *) Change the handling of OID objects as follows: + + - New object identifiers are inserted in objects.txt, following + the syntax given in objects.README. + - objects.pl is used to process obj_mac.num and create a new + obj_mac.h. + - obj_dat.pl is used to create a new obj_dat.h, using the data in + obj_mac.h. + + This is currently kind of a hack, and the perl code in objects.pl + isn't very elegant, but it works as I intended. The simplest way + to check that it worked correctly is to look in obj_dat.h and + check the array nid_objs and make sure the objects haven't moved + around (this is important!). Additions are OK, as well as + consistent name changes. + [Richard Levitte] + + *) Add BSD-style MD5-based passwords to 'openssl passwd' (option '-1'). + [Bodo Moeller] + + *) Addition of the command line parameter '-rand file' to 'openssl req'. + The given file adds to whatever has already been seeded into the + random pool through the RANDFILE configuration file option or + environment variable, or the default random state file. + [Richard Levitte] + + *) mkstack.pl now sorts each macro group into lexical order. + Previously the output order depended on the order the files + appeared in the directory, resulting in needless rewriting + of safestack.h . + [Steve Henson] + + *) Patches to make OpenSSL compile under Win32 again. Mostly + work arounds for the VC++ problem that it treats func() as + func(void). Also stripped out the parts of mkdef.pl that + added extra typesafe functions: these no longer exist. + [Steve Henson] + + *) Reorganisation of the stack code. The macros are now all + collected in safestack.h . Each macro is defined in terms of + a "stack macro" of the form SKM_(type, a, b). The + DEBUG_SAFESTACK is now handled in terms of function casts, + this has the advantage of retaining type safety without the + use of additional functions. If DEBUG_SAFESTACK is not defined + then the non typesafe macros are used instead. Also modified the + mkstack.pl script to handle the new form. Needs testing to see + if which (if any) compilers it chokes and maybe make DEBUG_SAFESTACK + the default if no major problems. Similar behaviour for ASN1_SET_OF + and PKCS12_STACK_OF. + [Steve Henson] + + *) When some versions of IIS use the 'NET' form of private key the + key derivation algorithm is different. Normally MD5(password) is + used as a 128 bit RC4 key. In the modified case + MD5(MD5(password) + "SGCKEYSALT") is used insted. Added some + new functions i2d_RSA_NET(), d2i_RSA_NET() etc which are the same + as the old Netscape_RSA functions except they have an additional + 'sgckey' parameter which uses the modified algorithm. Also added + an -sgckey command line option to the rsa utility. Thanks to + Adrian Peck for posting details of the modified + algorithm to openssl-dev. + [Steve Henson] + + *) The evp_local.h macros were using 'c.##kname' which resulted in + invalid expansion on some systems (SCO 5.0.5 for example). + Corrected to 'c.kname'. + [Phillip Porch ] + + *) New X509_get1_email() and X509_REQ_get1_email() functions that return + a STACK of email addresses from a certificate or request, these look + in the subject name and the subject alternative name extensions and + omit any duplicate addresses. + [Steve Henson] + + *) Re-implement BN_mod_exp2_mont using independent (and larger) windows. + This makes DSA verification about 2 % faster. + [Bodo Moeller] + + *) Increase maximum window size in BN_mod_exp_... to 6 bits instead of 5 + (meaning that now 2^5 values will be precomputed, which is only 4 KB + plus overhead for 1024 bit moduli). + This makes exponentiations about 0.5 % faster for 1024 bit + exponents (as measured by "openssl speed rsa2048"). + [Bodo Moeller] + + *) Rename memory handling macros to avoid conflicts with other + software: + Malloc => OPENSSL_malloc + Malloc_locked => OPENSSL_malloc_locked + Realloc => OPENSSL_realloc + Free => OPENSSL_free + [Richard Levitte] + + *) New function BN_mod_exp_mont_word for small bases (roughly 15% + faster than BN_mod_exp_mont, i.e. 7% for a full DH exchange). + [Bodo Moeller] + + *) CygWin32 support. + [John Jarvie ] + + *) The type-safe stack code has been rejigged. It is now only compiled + in when OpenSSL is configured with the DEBUG_SAFESTACK option and + by default all type-specific stack functions are "#define"d back to + standard stack functions. This results in more streamlined output + but retains the type-safety checking possibilities of the original + approach. + [Geoff Thorpe] + + *) The STACK code has been cleaned up, and certain type declarations + that didn't make a lot of sense have been brought in line. This has + also involved a cleanup of sorts in safestack.h to more correctly + map type-safe stack functions onto their plain stack counterparts. + This work has also resulted in a variety of "const"ifications of + lots of the code, especially "_cmp" operations which should normally + be prototyped with "const" parameters anyway. + [Geoff Thorpe] + + *) When generating bytes for the first time in md_rand.c, 'stir the pool' + by seeding with STATE_SIZE dummy bytes (with zero entropy count). + (The PRNG state consists of two parts, the large pool 'state' and 'md', + where all of 'md' is used each time the PRNG is used, but 'state' + is used only indexed by a cyclic counter. As entropy may not be + well distributed from the beginning, 'md' is important as a + chaining variable. However, the output function chains only half + of 'md', i.e. 80 bits. ssleay_rand_add, on the other hand, chains + all of 'md', and seeding with STATE_SIZE dummy bytes will result + in all of 'state' being rewritten, with the new values depending + on virtually all of 'md'. This overcomes the 80 bit limitation.) + [Bodo Moeller] + + *) In ssl/s2_clnt.c and ssl/s3_clnt.c, call ERR_clear_error() when + the handshake is continued after ssl_verify_cert_chain(); + otherwise, if SSL_VERIFY_NONE is set, remaining error codes + can lead to 'unexplainable' connection aborts later. + [Bodo Moeller; problem tracked down by Lutz Jaenicke] + + *) Major EVP API cipher revision. + Add hooks for extra EVP features. This allows various cipher + parameters to be set in the EVP interface. Support added for variable + key length ciphers via the EVP_CIPHER_CTX_set_key_length() function and + setting of RC2 and RC5 parameters. + + Modify EVP_OpenInit() and EVP_SealInit() to cope with variable key length + ciphers. + + Remove lots of duplicated code from the EVP library. For example *every* + cipher init() function handles the 'iv' in the same way according to the + cipher mode. They also all do nothing if the 'key' parameter is NULL and + for CFB and OFB modes they zero ctx->num. + + New functionality allows removal of S/MIME code RC2 hack. + + Most of the routines have the same form and so can be declared in terms + of macros. + + By shifting this to the top level EVP_CipherInit() it can be removed from + all individual ciphers. If the cipher wants to handle IVs or keys + differently it can set the EVP_CIPH_CUSTOM_IV or EVP_CIPH_ALWAYS_CALL_INIT + flags. + + Change lots of functions like EVP_EncryptUpdate() to now return a + value: although software versions of the algorithms cannot fail + any installed hardware versions can. + [Steve Henson] + + *) Implement SSL_OP_TLS_ROLLBACK_BUG: In ssl3_get_client_key_exchange, if + this option is set, tolerate broken clients that send the negotiated + protocol version number instead of the requested protocol version + number. + [Bodo Moeller] + + *) Call dh_tmp_cb (set by ..._TMP_DH_CB) with correct 'is_export' flag; + i.e. non-zero for export ciphersuites, zero otherwise. + Previous versions had this flag inverted, inconsistent with + rsa_tmp_cb (..._TMP_RSA_CB). + [Bodo Moeller; problem reported by Amit Chopra] + + *) Add missing DSA library text string. Work around for some IIS + key files with invalid SEQUENCE encoding. + [Steve Henson] + + *) Add a document (doc/standards.txt) that list all kinds of standards + and so on that are implemented in OpenSSL. + [Richard Levitte] + + *) Enhance c_rehash script. Old version would mishandle certificates + with the same subject name hash and wouldn't handle CRLs at all. + Added -fingerprint option to crl utility, to support new c_rehash + features. + [Steve Henson] + + *) Eliminate non-ANSI declarations in crypto.h and stack.h. + [Ulf Möller] + + *) Fix for SSL server purpose checking. Server checking was + rejecting certificates which had extended key usage present + but no ssl client purpose. + [Steve Henson, reported by Rene Grosser ] + + *) Make PKCS#12 code work with no password. The PKCS#12 spec + is a little unclear about how a blank password is handled. + Since the password in encoded as a BMPString with terminating + double NULL a zero length password would end up as just the + double NULL. However no password at all is different and is + handled differently in the PKCS#12 key generation code. NS + treats a blank password as zero length. MSIE treats it as no + password on export: but it will try both on import. We now do + the same: PKCS12_parse() tries zero length and no password if + the password is set to "" or NULL (NULL is now a valid password: + it wasn't before) as does the pkcs12 application. + [Steve Henson] + + *) Bugfixes in apps/x509.c: Avoid a memory leak; and don't use + perror when PEM_read_bio_X509_REQ fails, the error message must + be obtained from the error queue. + [Bodo Moeller] + + *) Avoid 'thread_hash' memory leak in crypto/err/err.c by freeing + it in ERR_remove_state if appropriate, and change ERR_get_state + accordingly to avoid race conditions (this is necessary because + thread_hash is no longer constant once set). + [Bodo Moeller] + + *) Bugfix for linux-elf makefile.one. + [Ulf Möller] + + *) RSA_get_default_method() will now cause a default + RSA_METHOD to be chosen if one doesn't exist already. + Previously this was only set during a call to RSA_new() + or RSA_new_method(NULL) meaning it was possible for + RSA_get_default_method() to return NULL. + [Geoff Thorpe] + + *) Added native name translation to the existing DSO code + that will convert (if the flag to do so is set) filenames + that are sufficiently small and have no path information + into a canonical native form. Eg. "blah" converted to + "libblah.so" or "blah.dll" etc. + [Geoff Thorpe] + + *) New function ERR_error_string_n(e, buf, len) which is like + ERR_error_string(e, buf), but writes at most 'len' bytes + including the 0 terminator. For ERR_error_string_n, 'buf' + may not be NULL. + [Damien Miller , Bodo Moeller] + + *) CONF library reworked to become more general. A new CONF + configuration file reader "class" is implemented as well as a + new functions (NCONF_*, for "New CONF") to handle it. The now + old CONF_* functions are still there, but are reimplemented to + work in terms of the new functions. Also, a set of functions + to handle the internal storage of the configuration data is + provided to make it easier to write new configuration file + reader "classes" (I can definitely see something reading a + configuration file in XML format, for example), called _CONF_*, + or "the configuration storage API"... + + The new configuration file reading functions are: + + NCONF_new, NCONF_free, NCONF_load, NCONF_load_fp, NCONF_load_bio, + NCONF_get_section, NCONF_get_string, NCONF_get_numbre + + NCONF_default, NCONF_WIN32 + + NCONF_dump_fp, NCONF_dump_bio + + NCONF_default and NCONF_WIN32 are method (or "class") choosers, + NCONF_new creates a new CONF object. This works in the same way + as other interfaces in OpenSSL, like the BIO interface. + NCONF_dump_* dump the internal storage of the configuration file, + which is useful for debugging. All other functions take the same + arguments as the old CONF_* functions wth the exception of the + first that must be a `CONF *' instead of a `LHASH *'. + + To make it easer to use the new classes with the old CONF_* functions, + the function CONF_set_default_method is provided. + [Richard Levitte] + + *) Add '-tls1' option to 'openssl ciphers', which was already + mentioned in the documentation but had not been implemented. + (This option is not yet really useful because even the additional + experimental TLS 1.0 ciphers are currently treated as SSL 3.0 ciphers.) + [Bodo Moeller] + + *) Initial DSO code added into libcrypto for letting OpenSSL (and + OpenSSL-based applications) load shared libraries and bind to + them in a portable way. + [Geoff Thorpe, with contributions from Richard Levitte] + + Changes between 0.9.5 and 0.9.5a [1 Apr 2000] + + *) Make sure _lrotl and _lrotr are only used with MSVC. + + *) Use lock CRYPTO_LOCK_RAND correctly in ssleay_rand_status + (the default implementation of RAND_status). + + *) Rename openssl x509 option '-crlext', which was added in 0.9.5, + to '-clrext' (= clear extensions), as intended and documented. + [Bodo Moeller; inconsistency pointed out by Michael Attili + ] + + *) Fix for HMAC. It wasn't zeroing the rest of the block if the key length + was larger than the MD block size. + [Steve Henson, pointed out by Yost William ] + + *) Modernise PKCS12_parse() so it uses STACK_OF(X509) for its ca argument + fix a leak when the ca argument was passed as NULL. Stop X509_PUBKEY_set() + using the passed key: if the passed key was a private key the result + of X509_print(), for example, would be to print out all the private key + components. + [Steve Henson] + + *) des_quad_cksum() byte order bug fix. + [Ulf Möller, using the problem description in krb4-0.9.7, where + the solution is attributed to Derrick J Brashear ] + + *) Fix so V_ASN1_APP_CHOOSE works again: however its use is strongly + discouraged. + [Steve Henson, pointed out by Brian Korver ] + + *) For easily testing in shell scripts whether some command + 'openssl XXX' exists, the new pseudo-command 'openssl no-XXX' + returns with exit code 0 iff no command of the given name is available. + 'no-XXX' is printed in this case, 'XXX' otherwise. In both cases, + the output goes to stdout and nothing is printed to stderr. + Additional arguments are always ignored. + + Since for each cipher there is a command of the same name, + the 'no-cipher' compilation switches can be tested this way. + + ('openssl no-XXX' is not able to detect pseudo-commands such + as 'quit', 'list-XXX-commands', or 'no-XXX' itself.) + [Bodo Moeller] + + *) Update test suite so that 'make test' succeeds in 'no-rsa' configuration. + [Bodo Moeller] + + *) For SSL_[CTX_]set_tmp_dh, don't create a DH key if SSL_OP_SINGLE_DH_USE + is set; it will be thrown away anyway because each handshake creates + its own key. + ssl_cert_dup, which is used by SSL_new, now copies DH keys in addition + to parameters -- in previous versions (since OpenSSL 0.9.3) the + 'default key' from SSL_CTX_set_tmp_dh would always be lost, meanining + you effectivly got SSL_OP_SINGLE_DH_USE when using this macro. + [Bodo Moeller] + + *) New s_client option -ign_eof: EOF at stdin is ignored, and + 'Q' and 'R' lose their special meanings (quit/renegotiate). + This is part of what -quiet does; unlike -quiet, -ign_eof + does not suppress any output. + [Richard Levitte] + + *) Add compatibility options to the purpose and trust code. The + purpose X509_PURPOSE_ANY is "any purpose" which automatically + accepts a certificate or CA, this was the previous behaviour, + with all the associated security issues. + + X509_TRUST_COMPAT is the old trust behaviour: only and + automatically trust self signed roots in certificate store. A + new trust setting X509_TRUST_DEFAULT is used to specify that + a purpose has no associated trust setting and it should instead + use the value in the default purpose. + [Steve Henson] + + *) Fix the PKCS#8 DSA private key code so it decodes keys again + and fix a memory leak. + [Steve Henson] + + *) In util/mkerr.pl (which implements 'make errors'), preserve + reason strings from the previous version of the .c file, as + the default to have only downcase letters (and digits) in + automatically generated reasons codes is not always appropriate. + [Bodo Moeller] + + *) In ERR_load_ERR_strings(), build an ERR_LIB_SYS error reason table + using strerror. Previously, ERR_reason_error_string() returned + library names as reason strings for SYSerr; but SYSerr is a special + case where small numbers are errno values, not library numbers. + [Bodo Moeller] + + *) Add '-dsaparam' option to 'openssl dhparam' application. This + converts DSA parameters into DH parameters. (When creating parameters, + DSA_generate_parameters is used.) + [Bodo Moeller] + + *) Include 'length' (recommended exponent length) in C code generated + by 'openssl dhparam -C'. + [Bodo Moeller] + + *) The second argument to set_label in perlasm was already being used + so couldn't be used as a "file scope" flag. Moved to third argument + which was free. + [Steve Henson] + + *) In PEM_ASN1_write_bio and some other functions, use RAND_pseudo_bytes + instead of RAND_bytes for encryption IVs and salts. + [Bodo Moeller] + + *) Include RAND_status() into RAND_METHOD instead of implementing + it only for md_rand.c Otherwise replacing the PRNG by calling + RAND_set_rand_method would be impossible. + [Bodo Moeller] + + *) Don't let DSA_generate_key() enter an infinite loop if the random + number generation fails. + [Bodo Moeller] + + *) New 'rand' application for creating pseudo-random output. + [Bodo Moeller] + + *) Added configuration support for Linux/IA64 + [Rolf Haberrecker ] + + *) Assembler module support for Mingw32. + [Ulf Möller] + + *) Shared library support for HPUX (in shlib/). + [Lutz Jaenicke and Anonymous] + + *) Shared library support for Solaris gcc. + [Lutz Behnke ] + + Changes between 0.9.4 and 0.9.5 [28 Feb 2000] + + *) PKCS7_encrypt() was adding text MIME headers twice because they + were added manually and by SMIME_crlf_copy(). + [Steve Henson] + + *) In bntest.c don't call BN_rand with zero bits argument. + [Steve Henson, pointed out by Andrew W. Gray ] + + *) BN_mul bugfix: In bn_mul_part_recursion() only the a>a[n] && b>b[n] + case was implemented. This caused BN_div_recp() to fail occasionally. + [Ulf Möller] + + *) Add an optional second argument to the set_label() in the perl + assembly language builder. If this argument exists and is set + to 1 it signals that the assembler should use a symbol whose + scope is the entire file, not just the current function. This + is needed with MASM which uses the format label:: for this scope. + [Steve Henson, pointed out by Peter Runestig ] + + *) Change the ASN1 types so they are typedefs by default. Before + almost all types were #define'd to ASN1_STRING which was causing + STACK_OF() problems: you couldn't declare STACK_OF(ASN1_UTF8STRING) + for example. + [Steve Henson] + + *) Change names of new functions to the new get1/get0 naming + convention: After 'get1', the caller owns a reference count + and has to call ..._free; 'get0' returns a pointer to some + data structure without incrementing reference counters. + (Some of the existing 'get' functions increment a reference + counter, some don't.) + Similarly, 'set1' and 'add1' functions increase reference + counters or duplicate objects. + [Steve Henson] + + *) Allow for the possibility of temp RSA key generation failure: + the code used to assume it always worked and crashed on failure. + [Steve Henson] + + *) Fix potential buffer overrun problem in BIO_printf(). + [Ulf Möller, using public domain code by Patrick Powell; problem + pointed out by David Sacerdote ] + + *) Support EGD . New functions + RAND_egd() and RAND_status(). In the command line application, + the EGD socket can be specified like a seed file using RANDFILE + or -rand. + [Ulf Möller] + + *) Allow the string CERTIFICATE to be tolerated in PKCS#7 structures. + Some CAs (e.g. Verisign) distribute certificates in this form. + [Steve Henson] + + *) Remove the SSL_ALLOW_ADH compile option and set the default cipher + list to exclude them. This means that no special compilation option + is needed to use anonymous DH: it just needs to be included in the + cipher list. + [Steve Henson] + + *) Change the EVP_MD_CTX_type macro so its meaning consistent with + EVP_MD_type. The old functionality is available in a new macro called + EVP_MD_md(). Change code that uses it and update docs. + [Steve Henson] + + *) ..._ctrl functions now have corresponding ..._callback_ctrl functions + where the 'void *' argument is replaced by a function pointer argument. + Previously 'void *' was abused to point to functions, which works on + many platforms, but is not correct. As these functions are usually + called by macros defined in OpenSSL header files, most source code + should work without changes. + [Richard Levitte] + + *) (which is created by Configure) now contains + sections with information on -D... compiler switches used for + compiling the library so that applications can see them. To enable + one of these sections, a pre-processor symbol OPENSSL_..._DEFINES + must be defined. E.g., + #define OPENSSL_ALGORITHM_DEFINES + #include + defines all pertinent NO_ symbols, such as NO_IDEA, NO_RSA, etc. + [Richard Levitte, Ulf and Bodo Möller] + + *) Bugfix: Tolerate fragmentation and interleaving in the SSL 3/TLS + record layer. + [Bodo Moeller] + + *) Change the 'other' type in certificate aux info to a STACK_OF + X509_ALGOR. Although not an AlgorithmIdentifier as such it has + the required ASN1 format: arbitrary types determined by an OID. + [Steve Henson] + + *) Add some PEM_write_X509_REQ_NEW() functions and a command line + argument to 'req'. This is not because the function is newer or + better than others it just uses the work 'NEW' in the certificate + request header lines. Some software needs this. + [Steve Henson] + + *) Reorganise password command line arguments: now passwords can be + obtained from various sources. Delete the PEM_cb function and make + it the default behaviour: i.e. if the callback is NULL and the + usrdata argument is not NULL interpret it as a null terminated pass + phrase. If usrdata and the callback are NULL then the pass phrase + is prompted for as usual. + [Steve Henson] + + *) Add support for the Compaq Atalla crypto accelerator. If it is installed, + the support is automatically enabled. The resulting binaries will + autodetect the card and use it if present. + [Ben Laurie and Compaq Inc.] + + *) Work around for Netscape hang bug. This sends certificate request + and server done in one record. Since this is perfectly legal in the + SSL/TLS protocol it isn't a "bug" option and is on by default. See + the bugs/SSLv3 entry for more info. + [Steve Henson] + + *) HP-UX tune-up: new unified configs, HP C compiler bug workaround. + [Andy Polyakov] + + *) Add -rand argument to smime and pkcs12 applications and read/write + of seed file. + [Steve Henson] + + *) New 'passwd' tool for crypt(3) and apr1 password hashes. + [Bodo Moeller] + + *) Add command line password options to the remaining applications. + [Steve Henson] + + *) Bug fix for BN_div_recp() for numerators with an even number of + bits. + [Ulf Möller] + + *) More tests in bntest.c, and changed test_bn output. + [Ulf Möller] + + *) ./config recognizes MacOS X now. + [Andy Polyakov] + + *) Bug fix for BN_div() when the first words of num and divsor are + equal (it gave wrong results if (rem=(n1-q*d0)&BN_MASK2) < d0). + [Ulf Möller] + + *) Add support for various broken PKCS#8 formats, and command line + options to produce them. + [Steve Henson] + + *) New functions BN_CTX_start(), BN_CTX_get() and BT_CTX_end() to + get temporary BIGNUMs from a BN_CTX. + [Ulf Möller] + + *) Correct return values in BN_mod_exp_mont() and BN_mod_exp2_mont() + for p == 0. + [Ulf Möller] + + *) Change the SSLeay_add_all_*() functions to OpenSSL_add_all_*() and + include a #define from the old name to the new. The original intent + was that statically linked binaries could for example just call + SSLeay_add_all_ciphers() to just add ciphers to the table and not + link with digests. This never worked becayse SSLeay_add_all_digests() + and SSLeay_add_all_ciphers() were in the same source file so calling + one would link with the other. They are now in separate source files. + [Steve Henson] + + *) Add a new -notext option to 'ca' and a -pubkey option to 'spkac'. + [Steve Henson] + + *) Use a less unusual form of the Miller-Rabin primality test (it used + a binary algorithm for exponentiation integrated into the Miller-Rabin + loop, our standard modexp algorithms are faster). + [Bodo Moeller] + + *) Support for the EBCDIC character set completed. + [Martin Kraemer ] + + *) Source code cleanups: use const where appropriate, eliminate casts, + use void * instead of char * in lhash. + [Ulf Möller] + + *) Bugfix: ssl3_send_server_key_exchange was not restartable + (the state was not changed to SSL3_ST_SW_KEY_EXCH_B, and because of + this the server could overwrite ephemeral keys that the client + has already seen). + [Bodo Moeller] + + *) Turn DSA_is_prime into a macro that calls BN_is_prime, + using 50 iterations of the Rabin-Miller test. + + DSA_generate_parameters now uses BN_is_prime_fasttest (with 50 + iterations of the Rabin-Miller test as required by the appendix + to FIPS PUB 186[-1]) instead of DSA_is_prime. + As BN_is_prime_fasttest includes trial division, DSA parameter + generation becomes much faster. + + This implies a change for the callback functions in DSA_is_prime + and DSA_generate_parameters: The callback function is called once + for each positive witness in the Rabin-Miller test, not just + occasionally in the inner loop; and the parameters to the + callback function now provide an iteration count for the outer + loop rather than for the current invocation of the inner loop. + DSA_generate_parameters additionally can call the callback + function with an 'iteration count' of -1, meaning that a + candidate has passed the trial division test (when q is generated + from an application-provided seed, trial division is skipped). + [Bodo Moeller] + + *) New function BN_is_prime_fasttest that optionally does trial + division before starting the Rabin-Miller test and has + an additional BN_CTX * argument (whereas BN_is_prime always + has to allocate at least one BN_CTX). + 'callback(1, -1, cb_arg)' is called when a number has passed the + trial division stage. + [Bodo Moeller] + + *) Fix for bug in CRL encoding. The validity dates weren't being handled + as ASN1_TIME. + [Steve Henson] + + *) New -pkcs12 option to CA.pl script to write out a PKCS#12 file. + [Steve Henson] + + *) New function BN_pseudo_rand(). + [Ulf Möller] + + *) Clean up BN_mod_mul_montgomery(): replace the broken (and unreadable) + bignum version of BN_from_montgomery() with the working code from + SSLeay 0.9.0 (the word based version is faster anyway), and clean up + the comments. + [Ulf Möller] + + *) Avoid a race condition in s2_clnt.c (function get_server_hello) that + made it impossible to use the same SSL_SESSION data structure in + SSL2 clients in multiple threads. + [Bodo Moeller] + + *) The return value of RAND_load_file() no longer counts bytes obtained + by stat(). RAND_load_file(..., -1) is new and uses the complete file + to seed the PRNG (previously an explicit byte count was required). + [Ulf Möller, Bodo Möller] + + *) Clean up CRYPTO_EX_DATA functions, some of these didn't have prototypes + used (char *) instead of (void *) and had casts all over the place. + [Steve Henson] + + *) Make BN_generate_prime() return NULL on error if ret!=NULL. + [Ulf Möller] + + *) Retain source code compatibility for BN_prime_checks macro: + BN_is_prime(..., BN_prime_checks, ...) now uses + BN_prime_checks_for_size to determine the appropriate number of + Rabin-Miller iterations. + [Ulf Möller] + + *) Diffie-Hellman uses "safe" primes: DH_check() return code renamed to + DH_CHECK_P_NOT_SAFE_PRIME. + (Check if this is true? OpenPGP calls them "strong".) + [Ulf Möller] + + *) Merge the functionality of "dh" and "gendh" programs into a new program + "dhparam". The old programs are retained for now but will handle DH keys + (instead of parameters) in future. + [Steve Henson] + + *) Make the ciphers, s_server and s_client programs check the return values + when a new cipher list is set. + [Steve Henson] + + *) Enhance the SSL/TLS cipher mechanism to correctly handle the TLS 56bit + ciphers. Before when the 56bit ciphers were enabled the sorting was + wrong. + + The syntax for the cipher sorting has been extended to support sorting by + cipher-strength (using the strength_bits hard coded in the tables). + The new command is "@STRENGTH" (see also doc/apps/ciphers.pod). + + Fix a bug in the cipher-command parser: when supplying a cipher command + string with an "undefined" symbol (neither command nor alphanumeric + [A-Za-z0-9], ssl_set_cipher_list used to hang in an endless loop. Now + an error is flagged. + + Due to the strength-sorting extension, the code of the + ssl_create_cipher_list() function was completely rearranged. I hope that + the readability was also increased :-) + [Lutz Jaenicke ] + + *) Minor change to 'x509' utility. The -CAcreateserial option now uses 1 + for the first serial number and places 2 in the serial number file. This + avoids problems when the root CA is created with serial number zero and + the first user certificate has the same issuer name and serial number + as the root CA. + [Steve Henson] + + *) Fixes to X509_ATTRIBUTE utilities, change the 'req' program so it uses + the new code. Add documentation for this stuff. + [Steve Henson] + + *) Changes to X509_ATTRIBUTE utilities. These have been renamed from + X509_*() to X509at_*() on the grounds that they don't handle X509 + structures and behave in an analagous way to the X509v3 functions: + they shouldn't be called directly but wrapper functions should be used + instead. + + So we also now have some wrapper functions that call the X509at functions + when passed certificate requests. (TO DO: similar things can be done with + PKCS#7 signed and unsigned attributes, PKCS#12 attributes and a few other + things. Some of these need some d2i or i2d and print functionality + because they handle more complex structures.) + [Steve Henson] + + *) Add missing #ifndefs that caused missing symbols when building libssl + as a shared library without RSA. Use #ifndef NO_SSL2 instead of + NO_RSA in ssl/s2*.c. + [Kris Kennaway , modified by Ulf Möller] + + *) Precautions against using the PRNG uninitialized: RAND_bytes() now + has a return value which indicates the quality of the random data + (1 = ok, 0 = not seeded). Also an error is recorded on the thread's + error queue. New function RAND_pseudo_bytes() generates output that is + guaranteed to be unique but not unpredictable. RAND_add is like + RAND_seed, but takes an extra argument for an entropy estimate + (RAND_seed always assumes full entropy). + [Ulf Möller] + + *) Do more iterations of Rabin-Miller probable prime test (specifically, + 3 for 1024-bit primes, 6 for 512-bit primes, 12 for 256-bit primes + instead of only 2 for all lengths; see BN_prime_checks_for_size definition + in crypto/bn/bn_prime.c for the complete table). This guarantees a + false-positive rate of at most 2^-80 for random input. + [Bodo Moeller] + + *) Rewrite ssl3_read_n (ssl/s3_pkt.c) avoiding a couple of bugs. + [Bodo Moeller] + + *) New function X509_CTX_rget_chain() (renamed to X509_CTX_get1_chain + in the 0.9.5 release), this returns the chain + from an X509_CTX structure with a dup of the stack and all + the X509 reference counts upped: so the stack will exist + after X509_CTX_cleanup() has been called. Modify pkcs12.c + to use this. + + Also make SSL_SESSION_print() print out the verify return + code. + [Steve Henson] + + *) Add manpage for the pkcs12 command. Also change the default + behaviour so MAC iteration counts are used unless the new + -nomaciter option is used. This improves file security and + only older versions of MSIE (4.0 for example) need it. + [Steve Henson] + + *) Honor the no-xxx Configure options when creating .DEF files. + [Ulf Möller] + + *) Add PKCS#10 attributes to field table: challengePassword, + unstructuredName and unstructuredAddress. These are taken from + draft PKCS#9 v2.0 but are compatible with v1.2 provided no + international characters are used. + + More changes to X509_ATTRIBUTE code: allow the setting of types + based on strings. Remove the 'loc' parameter when adding + attributes because these will be a SET OF encoding which is sorted + in ASN1 order. + [Steve Henson] + + *) Initial changes to the 'req' utility to allow request generation + automation. This will allow an application to just generate a template + file containing all the field values and have req construct the + request. + + Initial support for X509_ATTRIBUTE handling. Stacks of these are + used all over the place including certificate requests and PKCS#7 + structures. They are currently handled manually where necessary with + some primitive wrappers for PKCS#7. The new functions behave in a + manner analogous to the X509 extension functions: they allow + attributes to be looked up by NID and added. + + Later something similar to the X509V3 code would be desirable to + automatically handle the encoding, decoding and printing of the + more complex types. The string types like challengePassword can + be handled by the string table functions. + + Also modified the multi byte string table handling. Now there is + a 'global mask' which masks out certain types. The table itself + can use the flag STABLE_NO_MASK to ignore the mask setting: this + is useful when for example there is only one permissible type + (as in countryName) and using the mask might result in no valid + types at all. + [Steve Henson] + + *) Clean up 'Finished' handling, and add functions SSL_get_finished and + SSL_get_peer_finished to allow applications to obtain the latest + Finished messages sent to the peer or expected from the peer, + respectively. (SSL_get_peer_finished is usually the Finished message + actually received from the peer, otherwise the protocol will be aborted.) + + As the Finished message are message digests of the complete handshake + (with a total of 192 bits for TLS 1.0 and more for SSL 3.0), they can + be used for external authentication procedures when the authentication + provided by SSL/TLS is not desired or is not enough. + [Bodo Moeller] + + *) Enhanced support for Alpha Linux is added. Now ./config checks if + the host supports BWX extension and if Compaq C is present on the + $PATH. Just exploiting of the BWX extension results in 20-30% + performance kick for some algorithms, e.g. DES and RC4 to mention + a couple. Compaq C in turn generates ~20% faster code for MD5 and + SHA1. + [Andy Polyakov] + + *) Add support for MS "fast SGC". This is arguably a violation of the + SSL3/TLS protocol. Netscape SGC does two handshakes: the first with + weak crypto and after checking the certificate is SGC a second one + with strong crypto. MS SGC stops the first handshake after receiving + the server certificate message and sends a second client hello. Since + a server will typically do all the time consuming operations before + expecting any further messages from the client (server key exchange + is the most expensive) there is little difference between the two. + + To get OpenSSL to support MS SGC we have to permit a second client + hello message after we have sent server done. In addition we have to + reset the MAC if we do get this second client hello. + [Steve Henson] + + *) Add a function 'd2i_AutoPrivateKey()' this will automatically decide + if a DER encoded private key is RSA or DSA traditional format. Changed + d2i_PrivateKey_bio() to use it. This is only needed for the "traditional" + format DER encoded private key. Newer code should use PKCS#8 format which + has the key type encoded in the ASN1 structure. Added DER private key + support to pkcs8 application. + [Steve Henson] + + *) SSL 3/TLS 1 servers now don't request certificates when an anonymous + ciphersuites has been selected (as required by the SSL 3/TLS 1 + specifications). Exception: When SSL_VERIFY_FAIL_IF_NO_PEER_CERT + is set, we interpret this as a request to violate the specification + (the worst that can happen is a handshake failure, and 'correct' + behaviour would result in a handshake failure anyway). + [Bodo Moeller] + + *) In SSL_CTX_add_session, take into account that there might be multiple + SSL_SESSION structures with the same session ID (e.g. when two threads + concurrently obtain them from an external cache). + The internal cache can handle only one SSL_SESSION with a given ID, + so if there's a conflict, we now throw out the old one to achieve + consistency. + [Bodo Moeller] + + *) Add OIDs for idea and blowfish in CBC mode. This will allow both + to be used in PKCS#5 v2.0 and S/MIME. Also add checking to + some routines that use cipher OIDs: some ciphers do not have OIDs + defined and so they cannot be used for S/MIME and PKCS#5 v2.0 for + example. + [Steve Henson] + + *) Simplify the trust setting structure and code. Now we just have + two sequences of OIDs for trusted and rejected settings. These will + typically have values the same as the extended key usage extension + and any application specific purposes. + + The trust checking code now has a default behaviour: it will just + check for an object with the same NID as the passed id. Functions can + be provided to override either the default behaviour or the behaviour + for a given id. SSL client, server and email already have functions + in place for compatibility: they check the NID and also return "trusted" + if the certificate is self signed. + [Steve Henson] + + *) Add d2i,i2d bio/fp functions for PrivateKey: these convert the + traditional format into an EVP_PKEY structure. + [Steve Henson] + + *) Add a password callback function PEM_cb() which either prompts for + a password if usr_data is NULL or otherwise assumes it is a null + terminated password. Allow passwords to be passed on command line + environment or config files in a few more utilities. + [Steve Henson] + + *) Add a bunch of DER and PEM functions to handle PKCS#8 format private + keys. Add some short names for PKCS#8 PBE algorithms and allow them + to be specified on the command line for the pkcs8 and pkcs12 utilities. + Update documentation. + [Steve Henson] + + *) Support for ASN1 "NULL" type. This could be handled before by using + ASN1_TYPE but there wasn't any function that would try to read a NULL + and produce an error if it couldn't. For compatibility we also have + ASN1_NULL_new() and ASN1_NULL_free() functions but these are faked and + don't allocate anything because they don't need to. + [Steve Henson] + + *) Initial support for MacOS is now provided. Examine INSTALL.MacOS + for details. + [Andy Polyakov, Roy Woods ] + + *) Rebuild of the memory allocation routines used by OpenSSL code and + possibly others as well. The purpose is to make an interface that + provide hooks so anyone can build a separate set of allocation and + deallocation routines to be used by OpenSSL, for example memory + pool implementations, or something else, which was previously hard + since Malloc(), Realloc() and Free() were defined as macros having + the values malloc, realloc and free, respectively (except for Win32 + compilations). The same is provided for memory debugging code. + OpenSSL already comes with functionality to find memory leaks, but + this gives people a chance to debug other memory problems. + + With these changes, a new set of functions and macros have appeared: + + CRYPTO_set_mem_debug_functions() [F] + CRYPTO_get_mem_debug_functions() [F] + CRYPTO_dbg_set_options() [F] + CRYPTO_dbg_get_options() [F] + CRYPTO_malloc_debug_init() [M] + + The memory debug functions are NULL by default, unless the library + is compiled with CRYPTO_MDEBUG or friends is defined. If someone + wants to debug memory anyway, CRYPTO_malloc_debug_init() (which + gives the standard debugging functions that come with OpenSSL) or + CRYPTO_set_mem_debug_functions() (tells OpenSSL to use functions + provided by the library user) must be used. When the standard + debugging functions are used, CRYPTO_dbg_set_options can be used to + request additional information: + CRYPTO_dbg_set_options(V_CYRPTO_MDEBUG_xxx) corresponds to setting + the CRYPTO_MDEBUG_xxx macro when compiling the library. + + Also, things like CRYPTO_set_mem_functions will always give the + expected result (the new set of functions is used for allocation + and deallocation) at all times, regardless of platform and compiler + options. + + To finish it up, some functions that were never use in any other + way than through macros have a new API and new semantic: + + CRYPTO_dbg_malloc() + CRYPTO_dbg_realloc() + CRYPTO_dbg_free() + + All macros of value have retained their old syntax. + [Richard Levitte and Bodo Moeller] + + *) Some S/MIME fixes. The OID for SMIMECapabilities was wrong, the + ordering of SMIMECapabilities wasn't in "strength order" and there + was a missing NULL in the AlgorithmIdentifier for the SHA1 signature + algorithm. + [Steve Henson] + + *) Some ASN1 types with illegal zero length encoding (INTEGER, + ENUMERATED and OBJECT IDENTIFIER) choked the ASN1 routines. + [Frans Heymans , modified by Steve Henson] + + *) Merge in my S/MIME library for OpenSSL. This provides a simple + S/MIME API on top of the PKCS#7 code, a MIME parser (with enough + functionality to handle multipart/signed properly) and a utility + called 'smime' to call all this stuff. This is based on code I + originally wrote for Celo who have kindly allowed it to be + included in OpenSSL. + [Steve Henson] + + *) Add variants des_set_key_checked and des_set_key_unchecked of + des_set_key (aka des_key_sched). Global variable des_check_key + decides which of these is called by des_set_key; this way + des_check_key behaves as it always did, but applications and + the library itself, which was buggy for des_check_key == 1, + have a cleaner way to pick the version they need. + [Bodo Moeller] + + *) New function PKCS12_newpass() which changes the password of a + PKCS12 structure. + [Steve Henson] + + *) Modify X509_TRUST and X509_PURPOSE so it also uses a static and + dynamic mix. In both cases the ids can be used as an index into the + table. Also modified the X509_TRUST_add() and X509_PURPOSE_add() + functions so they accept a list of the field values and the + application doesn't need to directly manipulate the X509_TRUST + structure. + [Steve Henson] + + *) Modify the ASN1_STRING_TABLE stuff so it also uses bsearch and doesn't + need initialising. + [Steve Henson] + + *) Modify the way the V3 extension code looks up extensions. This now + works in a similar way to the object code: we have some "standard" + extensions in a static table which is searched with OBJ_bsearch() + and the application can add dynamic ones if needed. The file + crypto/x509v3/ext_dat.h now has the info: this file needs to be + updated whenever a new extension is added to the core code and kept + in ext_nid order. There is a simple program 'tabtest.c' which checks + this. New extensions are not added too often so this file can readily + be maintained manually. + + There are two big advantages in doing things this way. The extensions + can be looked up immediately and no longer need to be "added" using + X509V3_add_standard_extensions(): this function now does nothing. + [Side note: I get *lots* of email saying the extension code doesn't + work because people forget to call this function] + Also no dynamic allocation is done unless new extensions are added: + so if we don't add custom extensions there is no need to call + X509V3_EXT_cleanup(). + [Steve Henson] + + *) Modify enc utility's salting as follows: make salting the default. Add a + magic header, so unsalted files fail gracefully instead of just decrypting + to garbage. This is because not salting is a big security hole, so people + should be discouraged from doing it. + [Ben Laurie] + + *) Fixes and enhancements to the 'x509' utility. It allowed a message + digest to be passed on the command line but it only used this + parameter when signing a certificate. Modified so all relevant + operations are affected by the digest parameter including the + -fingerprint and -x509toreq options. Also -x509toreq choked if a + DSA key was used because it didn't fix the digest. + [Steve Henson] + + *) Initial certificate chain verify code. Currently tests the untrusted + certificates for consistency with the verify purpose (which is set + when the X509_STORE_CTX structure is set up) and checks the pathlength. + + There is a NO_CHAIN_VERIFY compilation option to keep the old behaviour: + this is because it will reject chains with invalid extensions whereas + every previous version of OpenSSL and SSLeay made no checks at all. + + Trust code: checks the root CA for the relevant trust settings. Trust + settings have an initial value consistent with the verify purpose: e.g. + if the verify purpose is for SSL client use it expects the CA to be + trusted for SSL client use. However the default value can be changed to + permit custom trust settings: one example of this would be to only trust + certificates from a specific "secure" set of CAs. + + Also added X509_STORE_CTX_new() and X509_STORE_CTX_free() functions + which should be used for version portability: especially since the + verify structure is likely to change more often now. + + SSL integration. Add purpose and trust to SSL_CTX and SSL and functions + to set them. If not set then assume SSL clients will verify SSL servers + and vice versa. + + Two new options to the verify program: -untrusted allows a set of + untrusted certificates to be passed in and -purpose which sets the + intended purpose of the certificate. If a purpose is set then the + new chain verify code is used to check extension consistency. + [Steve Henson] + + *) Support for the authority information access extension. + [Steve Henson] + + *) Modify RSA and DSA PEM read routines to transparently handle + PKCS#8 format private keys. New *_PUBKEY_* functions that handle + public keys in a format compatible with certificate + SubjectPublicKeyInfo structures. Unfortunately there were already + functions called *_PublicKey_* which used various odd formats so + these are retained for compatibility: however the DSA variants were + never in a public release so they have been deleted. Changed dsa/rsa + utilities to handle the new format: note no releases ever handled public + keys so we should be OK. + + The primary motivation for this change is to avoid the same fiasco + that dogs private keys: there are several incompatible private key + formats some of which are standard and some OpenSSL specific and + require various evil hacks to allow partial transparent handling and + even then it doesn't work with DER formats. Given the option anything + other than PKCS#8 should be dumped: but the other formats have to + stay in the name of compatibility. + + With public keys and the benefit of hindsight one standard format + is used which works with EVP_PKEY, RSA or DSA structures: though + it clearly returns an error if you try to read the wrong kind of key. + + Added a -pubkey option to the 'x509' utility to output the public key. + Also rename the EVP_PKEY_get_*() to EVP_PKEY_rget_*() + (renamed to EVP_PKEY_get1_*() in the OpenSSL 0.9.5 release) and add + EVP_PKEY_rset_*() functions (renamed to EVP_PKEY_set1_*()) + that do the same as the EVP_PKEY_assign_*() except they up the + reference count of the added key (they don't "swallow" the + supplied key). + [Steve Henson] + + *) Fixes to crypto/x509/by_file.c the code to read in certificates and + CRLs would fail if the file contained no certificates or no CRLs: + added a new function to read in both types and return the number + read: this means that if none are read it will be an error. The + DER versions of the certificate and CRL reader would always fail + because it isn't possible to mix certificates and CRLs in DER format + without choking one or the other routine. Changed this to just read + a certificate: this is the best we can do. Also modified the code + in apps/verify.c to take notice of return codes: it was previously + attempting to read in certificates from NULL pointers and ignoring + any errors: this is one reason why the cert and CRL reader seemed + to work. It doesn't check return codes from the default certificate + routines: these may well fail if the certificates aren't installed. + [Steve Henson] + + *) Code to support otherName option in GeneralName. + [Steve Henson] + + *) First update to verify code. Change the verify utility + so it warns if it is passed a self signed certificate: + for consistency with the normal behaviour. X509_verify + has been modified to it will now verify a self signed + certificate if *exactly* the same certificate appears + in the store: it was previously impossible to trust a + single self signed certificate. This means that: + openssl verify ss.pem + now gives a warning about a self signed certificate but + openssl verify -CAfile ss.pem ss.pem + is OK. + [Steve Henson] + + *) For servers, store verify_result in SSL_SESSION data structure + (and add it to external session representation). + This is needed when client certificate verifications fails, + but an application-provided verification callback (set by + SSL_CTX_set_cert_verify_callback) allows accepting the session + anyway (i.e. leaves x509_store_ctx->error != X509_V_OK + but returns 1): When the session is reused, we have to set + ssl->verify_result to the appropriate error code to avoid + security holes. + [Bodo Moeller, problem pointed out by Lutz Jaenicke] + + *) Fix a bug in the new PKCS#7 code: it didn't consider the + case in PKCS7_dataInit() where the signed PKCS7 structure + didn't contain any existing data because it was being created. + [Po-Cheng Chen , slightly modified by Steve Henson] + + *) Add a salt to the key derivation routines in enc.c. This + forms the first 8 bytes of the encrypted file. Also add a + -S option to allow a salt to be input on the command line. + [Steve Henson] + + *) New function X509_cmp(). Oddly enough there wasn't a function + to compare two certificates. We do this by working out the SHA1 + hash and comparing that. X509_cmp() will be needed by the trust + code. + [Steve Henson] + + *) SSL_get1_session() is like SSL_get_session(), but increments + the reference count in the SSL_SESSION returned. + [Geoff Thorpe ] + + *) Fix for 'req': it was adding a null to request attributes. + Also change the X509_LOOKUP and X509_INFO code to handle + certificate auxiliary information. + [Steve Henson] + + *) Add support for 40 and 64 bit RC2 and RC4 algorithms: document + the 'enc' command. + [Steve Henson] + + *) Add the possibility to add extra information to the memory leak + detecting output, to form tracebacks, showing from where each + allocation was originated: CRYPTO_push_info("constant string") adds + the string plus current file name and line number to a per-thread + stack, CRYPTO_pop_info() does the obvious, CRYPTO_remove_all_info() + is like calling CYRPTO_pop_info() until the stack is empty. + Also updated memory leak detection code to be multi-thread-safe. + [Richard Levitte] + + *) Add options -text and -noout to pkcs7 utility and delete the + encryption options which never did anything. Update docs. + [Steve Henson] + + *) Add options to some of the utilities to allow the pass phrase + to be included on either the command line (not recommended on + OSes like Unix) or read from the environment. Update the + manpages and fix a few bugs. + [Steve Henson] + + *) Add a few manpages for some of the openssl commands. + [Steve Henson] + + *) Fix the -revoke option in ca. It was freeing up memory twice, + leaking and not finding already revoked certificates. + [Steve Henson] + + *) Extensive changes to support certificate auxiliary information. + This involves the use of X509_CERT_AUX structure and X509_AUX + functions. An X509_AUX function such as PEM_read_X509_AUX() + can still read in a certificate file in the usual way but it + will also read in any additional "auxiliary information". By + doing things this way a fair degree of compatibility can be + retained: existing certificates can have this information added + using the new 'x509' options. + + Current auxiliary information includes an "alias" and some trust + settings. The trust settings will ultimately be used in enhanced + certificate chain verification routines: currently a certificate + can only be trusted if it is self signed and then it is trusted + for all purposes. + [Steve Henson] + + *) Fix assembler for Alpha (tested only on DEC OSF not Linux or *BSD). + The problem was that one of the replacement routines had not been working + since SSLeay releases. For now the offending routine has been replaced + with non-optimised assembler. Even so, this now gives around 95% + performance improvement for 1024 bit RSA signs. + [Mark Cox] + + *) Hack to fix PKCS#7 decryption when used with some unorthodox RC2 + handling. Most clients have the effective key size in bits equal to + the key length in bits: so a 40 bit RC2 key uses a 40 bit (5 byte) key. + A few however don't do this and instead use the size of the decrypted key + to determine the RC2 key length and the AlgorithmIdentifier to determine + the effective key length. In this case the effective key length can still + be 40 bits but the key length can be 168 bits for example. This is fixed + by manually forcing an RC2 key into the EVP_PKEY structure because the + EVP code can't currently handle unusual RC2 key sizes: it always assumes + the key length and effective key length are equal. + [Steve Henson] + + *) Add a bunch of functions that should simplify the creation of + X509_NAME structures. Now you should be able to do: + X509_NAME_add_entry_by_txt(nm, "CN", MBSTRING_ASC, "Steve", -1, -1, 0); + and have it automatically work out the correct field type and fill in + the structures. The more adventurous can try: + X509_NAME_add_entry_by_txt(nm, field, MBSTRING_UTF8, str, -1, -1, 0); + and it will (hopefully) work out the correct multibyte encoding. + [Steve Henson] + + *) Change the 'req' utility to use the new field handling and multibyte + copy routines. Before the DN field creation was handled in an ad hoc + way in req, ca, and x509 which was rather broken and didn't support + BMPStrings or UTF8Strings. Since some software doesn't implement + BMPStrings or UTF8Strings yet, they can be enabled using the config file + using the dirstring_type option. See the new comment in the default + openssl.cnf for more info. + [Steve Henson] + + *) Make crypto/rand/md_rand.c more robust: + - Assure unique random numbers after fork(). + - Make sure that concurrent threads access the global counter and + md serializably so that we never lose entropy in them + or use exactly the same state in multiple threads. + Access to the large state is not always serializable because + the additional locking could be a performance killer, and + md should be large enough anyway. + [Bodo Moeller] + + *) New file apps/app_rand.c with commonly needed functionality + for handling the random seed file. + + Use the random seed file in some applications that previously did not: + ca, + dsaparam -genkey (which also ignored its '-rand' option), + s_client, + s_server, + x509 (when signing). + Except on systems with /dev/urandom, it is crucial to have a random + seed file at least for key creation, DSA signing, and for DH exchanges; + for RSA signatures we could do without one. + + gendh and gendsa (unlike genrsa) used to read only the first byte + of each file listed in the '-rand' option. The function as previously + found in genrsa is now in app_rand.c and is used by all programs + that support '-rand'. + [Bodo Moeller] + + *) In RAND_write_file, use mode 0600 for creating files; + don't just chmod when it may be too late. + [Bodo Moeller] + + *) Report an error from X509_STORE_load_locations + when X509_LOOKUP_load_file or X509_LOOKUP_add_dir failed. + [Bill Perry] + + *) New function ASN1_mbstring_copy() this copies a string in either + ASCII, Unicode, Universal (4 bytes per character) or UTF8 format + into an ASN1_STRING type. A mask of permissible types is passed + and it chooses the "minimal" type to use or an error if not type + is suitable. + [Steve Henson] + + *) Add function equivalents to the various macros in asn1.h. The old + macros are retained with an M_ prefix. Code inside the library can + use the M_ macros. External code (including the openssl utility) + should *NOT* in order to be "shared library friendly". + [Steve Henson] + + *) Add various functions that can check a certificate's extensions + to see if it usable for various purposes such as SSL client, + server or S/MIME and CAs of these types. This is currently + VERY EXPERIMENTAL but will ultimately be used for certificate chain + verification. Also added a -purpose flag to x509 utility to + print out all the purposes. + [Steve Henson] + + *) Add a CRYPTO_EX_DATA to X509 certificate structure and associated + functions. + [Steve Henson] + + *) New X509V3_{X509,CRL,REVOKED}_get_d2i() functions. These will search + for, obtain and decode and extension and obtain its critical flag. + This allows all the necessary extension code to be handled in a + single function call. + [Steve Henson] + + *) RC4 tune-up featuring 30-40% performance improvement on most RISC + platforms. See crypto/rc4/rc4_enc.c for further details. + [Andy Polyakov] + + *) New -noout option to asn1parse. This causes no output to be produced + its main use is when combined with -strparse and -out to extract data + from a file (which may not be in ASN.1 format). + [Steve Henson] + + *) Fix for pkcs12 program. It was hashing an invalid certificate pointer + when producing the local key id. + [Richard Levitte ] + + *) New option -dhparam in s_server. This allows a DH parameter file to be + stated explicitly. If it is not stated then it tries the first server + certificate file. The previous behaviour hard coded the filename + "server.pem". + [Steve Henson] + + *) Add -pubin and -pubout options to the rsa and dsa commands. These allow + a public key to be input or output. For example: + openssl rsa -in key.pem -pubout -out pubkey.pem + Also added necessary DSA public key functions to handle this. + [Steve Henson] + + *) Fix so PKCS7_dataVerify() doesn't crash if no certificates are contained + in the message. This was handled by allowing + X509_find_by_issuer_and_serial() to tolerate a NULL passed to it. + [Steve Henson, reported by Sampo Kellomaki ] + + *) Fix for bug in d2i_ASN1_bytes(): other ASN1 functions add an extra null + to the end of the strings whereas this didn't. This would cause problems + if strings read with d2i_ASN1_bytes() were later modified. + [Steve Henson, reported by Arne Ansper ] + + *) Fix for base64 decode bug. When a base64 bio reads only one line of + data and it contains EOF it will end up returning an error. This is + caused by input 46 bytes long. The cause is due to the way base64 + BIOs find the start of base64 encoded data. They do this by trying a + trial decode on each line until they find one that works. When they + do a flag is set and it starts again knowing it can pass all the + data directly through the decoder. Unfortunately it doesn't reset + the context it uses. This means that if EOF is reached an attempt + is made to pass two EOFs through the context and this causes the + resulting error. This can also cause other problems as well. As is + usual with these problems it takes *ages* to find and the fix is + trivial: move one line. + [Steve Henson, reported by ian@uns.ns.ac.yu (Ivan Nejgebauer) ] + + *) Ugly workaround to get s_client and s_server working under Windows. The + old code wouldn't work because it needed to select() on sockets and the + tty (for keypresses and to see if data could be written). Win32 only + supports select() on sockets so we select() with a 1s timeout on the + sockets and then see if any characters are waiting to be read, if none + are present then we retry, we also assume we can always write data to + the tty. This isn't nice because the code then blocks until we've + received a complete line of data and it is effectively polling the + keyboard at 1s intervals: however it's quite a bit better than not + working at all :-) A dedicated Windows application might handle this + with an event loop for example. + [Steve Henson] + + *) Enhance RSA_METHOD structure. Now there are two extra methods, rsa_sign + and rsa_verify. When the RSA_FLAGS_SIGN_VER option is set these functions + will be called when RSA_sign() and RSA_verify() are used. This is useful + if rsa_pub_dec() and rsa_priv_enc() equivalents are not available. + For this to work properly RSA_public_decrypt() and RSA_private_encrypt() + should *not* be used: RSA_sign() and RSA_verify() must be used instead. + This necessitated the support of an extra signature type NID_md5_sha1 + for SSL signatures and modifications to the SSL library to use it instead + of calling RSA_public_decrypt() and RSA_private_encrypt(). + [Steve Henson] + + *) Add new -verify -CAfile and -CApath options to the crl program, these + will lookup a CRL issuers certificate and verify the signature in a + similar way to the verify program. Tidy up the crl program so it + no longer accesses structures directly. Make the ASN1 CRL parsing a bit + less strict. It will now permit CRL extensions even if it is not + a V2 CRL: this will allow it to tolerate some broken CRLs. + [Steve Henson] + + *) Initialize all non-automatic variables each time one of the openssl + sub-programs is started (this is necessary as they may be started + multiple times from the "OpenSSL>" prompt). + [Lennart Bang, Bodo Moeller] + + *) Preliminary compilation option RSA_NULL which disables RSA crypto without + removing all other RSA functionality (this is what NO_RSA does). This + is so (for example) those in the US can disable those operations covered + by the RSA patent while allowing storage and parsing of RSA keys and RSA + key generation. + [Steve Henson] + + *) Non-copying interface to BIO pairs. + (still largely untested) + [Bodo Moeller] + + *) New function ANS1_tag2str() to convert an ASN1 tag to a descriptive + ASCII string. This was handled independently in various places before. + [Steve Henson] + + *) New functions UTF8_getc() and UTF8_putc() that parse and generate + UTF8 strings a character at a time. + [Steve Henson] + + *) Use client_version from client hello to select the protocol + (s23_srvr.c) and for RSA client key exchange verification + (s3_srvr.c), as required by the SSL 3.0/TLS 1.0 specifications. + [Bodo Moeller] + + *) Add various utility functions to handle SPKACs, these were previously + handled by poking round in the structure internals. Added new function + NETSCAPE_SPKI_print() to print out SPKAC and a new utility 'spkac' to + print, verify and generate SPKACs. Based on an original idea from + Massimiliano Pala but extensively modified. + [Steve Henson] + + *) RIPEMD160 is operational on all platforms and is back in 'make test'. + [Andy Polyakov] + + *) Allow the config file extension section to be overwritten on the + command line. Based on an original idea from Massimiliano Pala + . The new option is called -extensions + and can be applied to ca, req and x509. Also -reqexts to override + the request extensions in req and -crlexts to override the crl extensions + in ca. + [Steve Henson] + + *) Add new feature to the SPKAC handling in ca. Now you can include + the same field multiple times by preceding it by "XXXX." for example: + 1.OU="Unit name 1" + 2.OU="Unit name 2" + this is the same syntax as used in the req config file. + [Steve Henson] + + *) Allow certificate extensions to be added to certificate requests. These + are specified in a 'req_extensions' option of the req section of the + config file. They can be printed out with the -text option to req but + are otherwise ignored at present. + [Steve Henson] + + *) Fix a horrible bug in enc_read() in crypto/evp/bio_enc.c: if the first + data read consists of only the final block it would not decrypted because + EVP_CipherUpdate() would correctly report zero bytes had been decrypted. + A misplaced 'break' also meant the decrypted final block might not be + copied until the next read. + [Steve Henson] + + *) Initial support for DH_METHOD. Again based on RSA_METHOD. Also added + a few extra parameters to the DH structure: these will be useful if + for example we want the value of 'q' or implement X9.42 DH. + [Steve Henson] + + *) Initial support for DSA_METHOD. This is based on the RSA_METHOD and + provides hooks that allow the default DSA functions or functions on a + "per key" basis to be replaced. This allows hardware acceleration and + hardware key storage to be handled without major modification to the + library. Also added low level modexp hooks and CRYPTO_EX structure and + associated functions. + [Steve Henson] + + *) Add a new flag to memory BIOs, BIO_FLAG_MEM_RDONLY. This marks the BIO + as "read only": it can't be written to and the buffer it points to will + not be freed. Reading from a read only BIO is much more efficient than + a normal memory BIO. This was added because there are several times when + an area of memory needs to be read from a BIO. The previous method was + to create a memory BIO and write the data to it, this results in two + copies of the data and an O(n^2) reading algorithm. There is a new + function BIO_new_mem_buf() which creates a read only memory BIO from + an area of memory. Also modified the PKCS#7 routines to use read only + memory BIOs. + [Steve Henson] + + *) Bugfix: ssl23_get_client_hello did not work properly when called in + state SSL23_ST_SR_CLNT_HELLO_B, i.e. when the first 7 bytes of + a SSLv2-compatible client hello for SSLv3 or TLSv1 could be read, + but a retry condition occured while trying to read the rest. + [Bodo Moeller] + + *) The PKCS7_ENC_CONTENT_new() function was setting the content type as + NID_pkcs7_encrypted by default: this was wrong since this should almost + always be NID_pkcs7_data. Also modified the PKCS7_set_type() to handle + the encrypted data type: this is a more sensible place to put it and it + allows the PKCS#12 code to be tidied up that duplicated this + functionality. + [Steve Henson] + + *) Changed obj_dat.pl script so it takes its input and output files on + the command line. This should avoid shell escape redirection problems + under Win32. + [Steve Henson] + + *) Initial support for certificate extension requests, these are included + in things like Xenroll certificate requests. Included functions to allow + extensions to be obtained and added. + [Steve Henson] + + *) -crlf option to s_client and s_server for sending newlines as + CRLF (as required by many protocols). + [Bodo Moeller] + + Changes between 0.9.3a and 0.9.4 [09 Aug 1999] + + *) Install libRSAglue.a when OpenSSL is built with RSAref. + [Ralf S. Engelschall] + + *) A few more ``#ifndef NO_FP_API / #endif'' pairs for consistency. + [Andrija Antonijevic ] + + *) Fix -startdate and -enddate (which was missing) arguments to 'ca' + program. + [Steve Henson] + + *) New function DSA_dup_DH, which duplicates DSA parameters/keys as + DH parameters/keys (q is lost during that conversion, but the resulting + DH parameters contain its length). + + For 1024-bit p, DSA_generate_parameters followed by DSA_dup_DH is + much faster than DH_generate_parameters (which creates parameters + where p = 2*q + 1), and also the smaller q makes DH computations + much more efficient (160-bit exponentiation instead of 1024-bit + exponentiation); so this provides a convenient way to support DHE + ciphersuites in SSL/TLS servers (see ssl/ssltest.c). It is of + utter importance to use + SSL_CTX_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); + or + SSL_set_options(s_ctx, SSL_OP_SINGLE_DH_USE); + when such DH parameters are used, because otherwise small subgroup + attacks may become possible! + [Bodo Moeller] + + *) Avoid memory leak in i2d_DHparams. + [Bodo Moeller] + + *) Allow the -k option to be used more than once in the enc program: + this allows the same encrypted message to be read by multiple recipients. + [Steve Henson] + + *) New function OBJ_obj2txt(buf, buf_len, a, no_name), this converts + an ASN1_OBJECT to a text string. If the "no_name" parameter is set then + it will always use the numerical form of the OID, even if it has a short + or long name. + [Steve Henson] + + *) Added an extra RSA flag: RSA_FLAG_EXT_PKEY. Previously the rsa_mod_exp + method only got called if p,q,dmp1,dmq1,iqmp components were present, + otherwise bn_mod_exp was called. In the case of hardware keys for example + no private key components need be present and it might store extra data + in the RSA structure, which cannot be accessed from bn_mod_exp. + By setting RSA_FLAG_EXT_PKEY rsa_mod_exp will always be called for + private key operations. + [Steve Henson] + + *) Added support for SPARC Linux. + [Andy Polyakov] + + *) pem_password_cb function type incompatibly changed from + typedef int pem_password_cb(char *buf, int size, int rwflag); + to + ....(char *buf, int size, int rwflag, void *userdata); + so that applications can pass data to their callbacks: + The PEM[_ASN1]_{read,write}... functions and macros now take an + additional void * argument, which is just handed through whenever + the password callback is called. + [Damien Miller ; tiny changes by Bodo Moeller] + + New function SSL_CTX_set_default_passwd_cb_userdata. + + Compatibility note: As many C implementations push function arguments + onto the stack in reverse order, the new library version is likely to + interoperate with programs that have been compiled with the old + pem_password_cb definition (PEM_whatever takes some data that + happens to be on the stack as its last argument, and the callback + just ignores this garbage); but there is no guarantee whatsoever that + this will work. + + *) The -DPLATFORM="\"$(PLATFORM)\"" definition and the similar -DCFLAGS=... + (both in crypto/Makefile.ssl for use by crypto/cversion.c) caused + problems not only on Windows, but also on some Unix platforms. + To avoid problematic command lines, these definitions are now in an + auto-generated file crypto/buildinf.h (created by crypto/Makefile.ssl + for standard "make" builds, by util/mk1mf.pl for "mk1mf" builds). + [Bodo Moeller] + + *) MIPS III/IV assembler module is reimplemented. + [Andy Polyakov] + + *) More DES library cleanups: remove references to srand/rand and + delete an unused file. + [Ulf Möller] + + *) Add support for the the free Netwide assembler (NASM) under Win32, + since not many people have MASM (ml) and it can be hard to obtain. + This is currently experimental but it seems to work OK and pass all + the tests. Check out INSTALL.W32 for info. + [Steve Henson] + + *) Fix memory leaks in s3_clnt.c: All non-anonymous SSL3/TLS1 connections + without temporary keys kept an extra copy of the server key, + and connections with temporary keys did not free everything in case + of an error. + [Bodo Moeller] + + *) New function RSA_check_key and new openssl rsa option -check + for verifying the consistency of RSA keys. + [Ulf Moeller, Bodo Moeller] + + *) Various changes to make Win32 compile work: + 1. Casts to avoid "loss of data" warnings in p5_crpt2.c + 2. Change unsigned int to int in b_dump.c to avoid "signed/unsigned + comparison" warnings. + 3. Add sk__sort to DEF file generator and do make update. + [Steve Henson] + + *) Add a debugging option to PKCS#5 v2 key generation function: when + you #define DEBUG_PKCS5V2 passwords, salts, iteration counts and + derived keys are printed to stderr. + [Steve Henson] + + *) Copy the flags in ASN1_STRING_dup(). + [Roman E. Pavlov ] + + *) The x509 application mishandled signing requests containing DSA + keys when the signing key was also DSA and the parameters didn't match. + + It was supposed to omit the parameters when they matched the signing key: + the verifying software was then supposed to automatically use the CA's + parameters if they were absent from the end user certificate. + + Omitting parameters is no longer recommended. The test was also + the wrong way round! This was probably due to unusual behaviour in + EVP_cmp_parameters() which returns 1 if the parameters match. + This meant that parameters were omitted when they *didn't* match and + the certificate was useless. Certificates signed with 'ca' didn't have + this bug. + [Steve Henson, reported by Doug Erickson ] + + *) Memory leak checking (-DCRYPTO_MDEBUG) had some problems. + The interface is as follows: + Applications can use + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) aka MemCheck_start(), + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) aka MemCheck_stop(); + "off" is now the default. + The library internally uses + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) aka MemCheck_off(), + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) aka MemCheck_on() + to disable memory-checking temporarily. + + Some inconsistent states that previously were possible (and were + even the default) are now avoided. + + -DCRYPTO_MDEBUG_TIME is new and additionally stores the current time + with each memory chunk allocated; this is occasionally more helpful + than just having a counter. + + -DCRYPTO_MDEBUG_THREAD is also new and adds the thread ID. + + -DCRYPTO_MDEBUG_ALL enables all of the above, plus any future + extensions. + [Bodo Moeller] + + *) Introduce "mode" for SSL structures (with defaults in SSL_CTX), + which largely parallels "options", but is for changing API behaviour, + whereas "options" are about protocol behaviour. + Initial "mode" flags are: + + SSL_MODE_ENABLE_PARTIAL_WRITE Allow SSL_write to report success when + a single record has been written. + SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER Don't insist that SSL_write + retries use the same buffer location. + (But all of the contents must be + copied!) + [Bodo Moeller] + + *) Bugfix: SSL_set_options ignored its parameter, only SSL_CTX_set_options + worked. + + *) Fix problems with no-hmac etc. + [Ulf Möller, pointed out by Brian Wellington ] + + *) New functions RSA_get_default_method(), RSA_set_method() and + RSA_get_method(). These allows replacement of RSA_METHODs without having + to mess around with the internals of an RSA structure. + [Steve Henson] + + *) Fix memory leaks in DSA_do_sign and DSA_is_prime. + Also really enable memory leak checks in openssl.c and in some + test programs. + [Chad C. Mulligan, Bodo Moeller] + + *) Fix a bug in d2i_ASN1_INTEGER() and i2d_ASN1_INTEGER() which can mess + up the length of negative integers. This has now been simplified to just + store the length when it is first determined and use it later, rather + than trying to keep track of where data is copied and updating it to + point to the end. + [Steve Henson, reported by Brien Wheeler + ] + + *) Add a new function PKCS7_signatureVerify. This allows the verification + of a PKCS#7 signature but with the signing certificate passed to the + function itself. This contrasts with PKCS7_dataVerify which assumes the + certificate is present in the PKCS#7 structure. This isn't always the + case: certificates can be omitted from a PKCS#7 structure and be + distributed by "out of band" means (such as a certificate database). + [Steve Henson] + + *) Complete the PEM_* macros with DECLARE_PEM versions to replace the + function prototypes in pem.h, also change util/mkdef.pl to add the + necessary function names. + [Steve Henson] + + *) mk1mf.pl (used by Windows builds) did not properly read the + options set by Configure in the top level Makefile, and Configure + was not even able to write more than one option correctly. + Fixed, now "no-idea no-rc5 -DCRYPTO_MDEBUG" etc. works as intended. + [Bodo Moeller] + + *) New functions CONF_load_bio() and CONF_load_fp() to allow a config + file to be loaded from a BIO or FILE pointer. The BIO version will + for example allow memory BIOs to contain config info. + [Steve Henson] + + *) New function "CRYPTO_num_locks" that returns CRYPTO_NUM_LOCKS. + Whoever hopes to achieve shared-library compatibility across versions + must use this, not the compile-time macro. + (Exercise 0.9.4: Which is the minimum library version required by + such programs?) + Note: All this applies only to multi-threaded programs, others don't + need locks. + [Bodo Moeller] + + *) Add missing case to s3_clnt.c state machine -- one of the new SSL tests + through a BIO pair triggered the default case, i.e. + SSLerr(...,SSL_R_UNKNOWN_STATE). + [Bodo Moeller] + + *) New "BIO pair" concept (crypto/bio/bss_bio.c) so that applications + can use the SSL library even if none of the specific BIOs is + appropriate. + [Bodo Moeller] + + *) Fix a bug in i2d_DSAPublicKey() which meant it returned the wrong value + for the encoded length. + [Jeon KyoungHo ] + + *) Add initial documentation of the X509V3 functions. + [Steve Henson] + + *) Add a new pair of functions PEM_write_PKCS8PrivateKey() and + PEM_write_bio_PKCS8PrivateKey() that are equivalent to + PEM_write_PrivateKey() and PEM_write_bio_PrivateKey() but use the more + secure PKCS#8 private key format with a high iteration count. + [Steve Henson] + + *) Fix determination of Perl interpreter: A perl or perl5 + _directory_ in $PATH was also accepted as the interpreter. + [Ralf S. Engelschall] + + *) Fix demos/sign/sign.c: well there wasn't anything strictly speaking + wrong with it but it was very old and did things like calling + PEM_ASN1_read() directly and used MD5 for the hash not to mention some + unusual formatting. + [Steve Henson] + + *) Fix demos/selfsign.c: it used obsolete and deleted functions, changed + to use the new extension code. + [Steve Henson] + + *) Implement the PEM_read/PEM_write functions in crypto/pem/pem_all.c + with macros. This should make it easier to change their form, add extra + arguments etc. Fix a few PEM prototypes which didn't have cipher as a + constant. + [Steve Henson] + + *) Add to configuration table a new entry that can specify an alternative + name for unistd.h (for pre-POSIX systems); we need this for NeXTstep, + according to Mark Crispin . + [Bodo Moeller] + +#if 0 + *) DES CBC did not update the IV. Weird. + [Ben Laurie] +#else + des_cbc_encrypt does not update the IV, but des_ncbc_encrypt does. + Changing the behaviour of the former might break existing programs -- + where IV updating is needed, des_ncbc_encrypt can be used. +#endif + + *) When bntest is run from "make test" it drives bc to check its + calculations, as well as internally checking them. If an internal check + fails, it needs to cause bc to give a non-zero result or make test carries + on without noticing the failure. Fixed. + [Ben Laurie] + + *) DES library cleanups. + [Ulf Möller] + + *) Add support for PKCS#5 v2.0 PBE algorithms. This will permit PKCS#8 to be + used with any cipher unlike PKCS#5 v1.5 which can at most handle 64 bit + ciphers. NOTE: although the key derivation function has been verified + against some published test vectors it has not been extensively tested + yet. Added a -v2 "cipher" option to pkcs8 application to allow the use + of v2.0. + [Steve Henson] + + *) Instead of "mkdir -p", which is not fully portable, use new + Perl script "util/mkdir-p.pl". + [Bodo Moeller] + + *) Rewrite the way password based encryption (PBE) is handled. It used to + assume that the ASN1 AlgorithmIdentifier parameter was a PBEParameter + structure. This was true for the PKCS#5 v1.5 and PKCS#12 PBE algorithms + but doesn't apply to PKCS#5 v2.0 where it can be something else. Now + the 'parameter' field of the AlgorithmIdentifier is passed to the + underlying key generation function so it must do its own ASN1 parsing. + This has also changed the EVP_PBE_CipherInit() function which now has a + 'parameter' argument instead of literal salt and iteration count values + and the function EVP_PBE_ALGOR_CipherInit() has been deleted. + [Steve Henson] + + *) Support for PKCS#5 v1.5 compatible password based encryption algorithms + and PKCS#8 functionality. New 'pkcs8' application linked to openssl. + Needed to change the PEM_STRING_EVP_PKEY value which was just "PRIVATE + KEY" because this clashed with PKCS#8 unencrypted string. Since this + value was just used as a "magic string" and not used directly its + value doesn't matter. + [Steve Henson] + + *) Introduce some semblance of const correctness to BN. Shame C doesn't + support mutable. + [Ben Laurie] + + *) "linux-sparc64" configuration (ultrapenguin). + [Ray Miller ] + "linux-sparc" configuration. + [Christian Forster ] + + *) config now generates no-xxx options for missing ciphers. + [Ulf Möller] + + *) Support the EBCDIC character set (work in progress). + File ebcdic.c not yet included because it has a different license. + [Martin Kraemer ] + + *) Support BS2000/OSD-POSIX. + [Martin Kraemer ] + + *) Make callbacks for key generation use void * instead of char *. + [Ben Laurie] + + *) Make S/MIME samples compile (not yet tested). + [Ben Laurie] + + *) Additional typesafe stacks. + [Ben Laurie] + + *) New configuration variants "bsdi-elf-gcc" (BSD/OS 4.x). + [Bodo Moeller] + + + Changes between 0.9.3 and 0.9.3a [29 May 1999] + + *) New configuration variant "sco5-gcc". + + *) Updated some demos. + [Sean O Riordain, Wade Scholine] + + *) Add missing BIO_free at exit of pkcs12 application. + [Wu Zhigang] + + *) Fix memory leak in conf.c. + [Steve Henson] + + *) Updates for Win32 to assembler version of MD5. + [Steve Henson] + + *) Set #! path to perl in apps/der_chop to where we found it + instead of using a fixed path. + [Bodo Moeller] + + *) SHA library changes for irix64-mips4-cc. + [Andy Polyakov] + + *) Improvements for VMS support. + [Richard Levitte] + + + Changes between 0.9.2b and 0.9.3 [24 May 1999] + + *) Bignum library bug fix. IRIX 6 passes "make test" now! + This also avoids the problems with SC4.2 and unpatched SC5. + [Andy Polyakov ] + + *) New functions sk_num, sk_value and sk_set to replace the previous macros. + These are required because of the typesafe stack would otherwise break + existing code. If old code used a structure member which used to be STACK + and is now STACK_OF (for example cert in a PKCS7_SIGNED structure) with + sk_num or sk_value it would produce an error because the num, data members + are not present in STACK_OF. Now it just produces a warning. sk_set + replaces the old method of assigning a value to sk_value + (e.g. sk_value(x, i) = y) which the library used in a few cases. Any code + that does this will no longer work (and should use sk_set instead) but + this could be regarded as a "questionable" behaviour anyway. + [Steve Henson] + + *) Fix most of the other PKCS#7 bugs. The "experimental" code can now + correctly handle encrypted S/MIME data. + [Steve Henson] + + *) Change type of various DES function arguments from des_cblock + (which means, in function argument declarations, pointer to char) + to des_cblock * (meaning pointer to array with 8 char elements), + which allows the compiler to do more typechecking; it was like + that back in SSLeay, but with lots of ugly casts. + + Introduce new type const_des_cblock. + [Bodo Moeller] + + *) Reorganise the PKCS#7 library and get rid of some of the more obvious + problems: find RecipientInfo structure that matches recipient certificate + and initialise the ASN1 structures properly based on passed cipher. + [Steve Henson] + + *) Belatedly make the BN tests actually check the results. + [Ben Laurie] + + *) Fix the encoding and decoding of negative ASN1 INTEGERS and conversion + to and from BNs: it was completely broken. New compilation option + NEG_PUBKEY_BUG to allow for some broken certificates that encode public + key elements as negative integers. + [Steve Henson] + + *) Reorganize and speed up MD5. + [Andy Polyakov ] + + *) VMS support. + [Richard Levitte ] + + *) New option -out to asn1parse to allow the parsed structure to be + output to a file. This is most useful when combined with the -strparse + option to examine the output of things like OCTET STRINGS. + [Steve Henson] + + *) Make SSL library a little more fool-proof by not requiring any longer + that SSL_set_{accept,connect}_state be called before + SSL_{accept,connect} may be used (SSL_set_..._state is omitted + in many applications because usually everything *appeared* to work as + intended anyway -- now it really works as intended). + [Bodo Moeller] + + *) Move openssl.cnf out of lib/. + [Ulf Möller] + + *) Fix various things to let OpenSSL even pass ``egcc -pipe -O2 -Wall + -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes + -Wmissing-declarations -Wnested-externs -Winline'' with EGCS 1.1.2+ + [Ralf S. Engelschall] + + *) Various fixes to the EVP and PKCS#7 code. It may now be able to + handle PKCS#7 enveloped data properly. + [Sebastian Akerman , modified by Steve] + + *) Create a duplicate of the SSL_CTX's CERT in SSL_new instead of + copying pointers. The cert_st handling is changed by this in + various ways (and thus what used to be known as ctx->default_cert + is now called ctx->cert, since we don't resort to s->ctx->[default_]cert + any longer when s->cert does not give us what we need). + ssl_cert_instantiate becomes obsolete by this change. + As soon as we've got the new code right (possibly it already is?), + we have solved a couple of bugs of the earlier code where s->cert + was used as if it could not have been shared with other SSL structures. + + Note that using the SSL API in certain dirty ways now will result + in different behaviour than observed with earlier library versions: + Changing settings for an SSL_CTX *ctx after having done s = SSL_new(ctx) + does not influence s as it used to. + + In order to clean up things more thoroughly, inside SSL_SESSION + we don't use CERT any longer, but a new structure SESS_CERT + that holds per-session data (if available); currently, this is + the peer's certificate chain and, for clients, the server's certificate + and temporary key. CERT holds only those values that can have + meaningful defaults in an SSL_CTX. + [Bodo Moeller] + + *) New function X509V3_EXT_i2d() to create an X509_EXTENSION structure + from the internal representation. Various PKCS#7 fixes: remove some + evil casts and set the enc_dig_alg field properly based on the signing + key type. + [Steve Henson] + + *) Allow PKCS#12 password to be set from the command line or the + environment. Let 'ca' get its config file name from the environment + variables "OPENSSL_CONF" or "SSLEAY_CONF" (for consistency with 'req' + and 'x509'). + [Steve Henson] + + *) Allow certificate policies extension to use an IA5STRING for the + organization field. This is contrary to the PKIX definition but + VeriSign uses it and IE5 only recognises this form. Document 'x509' + extension option. + [Steve Henson] + + *) Add PEDANTIC compiler flag to allow compilation with gcc -pedantic, + without disallowing inline assembler and the like for non-pedantic builds. + [Ben Laurie] + + *) Support Borland C++ builder. + [Janez Jere , modified by Ulf Möller] + + *) Support Mingw32. + [Ulf Möller] + + *) SHA-1 cleanups and performance enhancements. + [Andy Polyakov ] + + *) Sparc v8plus assembler for the bignum library. + [Andy Polyakov ] + + *) Accept any -xxx and +xxx compiler options in Configure. + [Ulf Möller] + + *) Update HPUX configuration. + [Anonymous] + + *) Add missing sk__unshift() function to safestack.h + [Ralf S. Engelschall] + + *) New function SSL_CTX_use_certificate_chain_file that sets the + "extra_cert"s in addition to the certificate. (This makes sense + only for "PEM" format files, as chains as a whole are not + DER-encoded.) + [Bodo Moeller] + + *) Support verify_depth from the SSL API. + x509_vfy.c had what can be considered an off-by-one-error: + Its depth (which was not part of the external interface) + was actually counting the number of certificates in a chain; + now it really counts the depth. + [Bodo Moeller] + + *) Bugfix in crypto/x509/x509_cmp.c: The SSLerr macro was used + instead of X509err, which often resulted in confusing error + messages since the error codes are not globally unique + (e.g. an alleged error in ssl3_accept when a certificate + didn't match the private key). + + *) New function SSL_CTX_set_session_id_context that allows to set a default + value (so that you don't need SSL_set_session_id_context for each + connection using the SSL_CTX). + [Bodo Moeller] + + *) OAEP decoding bug fix. + [Ulf Möller] + + *) Support INSTALL_PREFIX for package builders, as proposed by + David Harris. + [Bodo Moeller] + + *) New Configure options "threads" and "no-threads". For systems + where the proper compiler options are known (currently Solaris + and Linux), "threads" is the default. + [Bodo Moeller] + + *) New script util/mklink.pl as a faster substitute for util/mklink.sh. + [Bodo Moeller] + + *) Install various scripts to $(OPENSSLDIR)/misc, not to + $(INSTALLTOP)/bin -- they shouldn't clutter directories + such as /usr/local/bin. + [Bodo Moeller] + + *) "make linux-shared" to build shared libraries. + [Niels Poppe ] + + *) New Configure option no- (rsa, idea, rc5, ...). + [Ulf Möller] + + *) Add the PKCS#12 API documentation to openssl.txt. Preliminary support for + extension adding in x509 utility. + [Steve Henson] + + *) Remove NOPROTO sections and error code comments. + [Ulf Möller] + + *) Partial rewrite of the DEF file generator to now parse the ANSI + prototypes. + [Steve Henson] + + *) New Configure options --prefix=DIR and --openssldir=DIR. + [Ulf Möller] + + *) Complete rewrite of the error code script(s). It is all now handled + by one script at the top level which handles error code gathering, + header rewriting and C source file generation. It should be much better + than the old method: it now uses a modified version of Ulf's parser to + read the ANSI prototypes in all header files (thus the old K&R definitions + aren't needed for error creation any more) and do a better job of + translating function codes into names. The old 'ASN1 error code imbedded + in a comment' is no longer necessary and it doesn't use .err files which + have now been deleted. Also the error code call doesn't have to appear all + on one line (which resulted in some large lines...). + [Steve Henson] + + *) Change #include filenames from to . + [Bodo Moeller] + + *) Change behaviour of ssl2_read when facing length-0 packets: Don't return + 0 (which usually indicates a closed connection), but continue reading. + [Bodo Moeller] + + *) Fix some race conditions. + [Bodo Moeller] + + *) Add support for CRL distribution points extension. Add Certificate + Policies and CRL distribution points documentation. + [Steve Henson] + + *) Move the autogenerated header file parts to crypto/opensslconf.h. + [Ulf Möller] + + *) Fix new 56-bit DES export ciphersuites: they were using 7 bytes instead of + 8 of keying material. Merlin has also confirmed interop with this fix + between OpenSSL and Baltimore C/SSL 2.0 and J/SSL 2.0. + [Merlin Hughes ] + + *) Fix lots of warnings. + [Richard Levitte ] + + *) In add_cert_dir() in crypto/x509/by_dir.c, break out of the loop if + the directory spec didn't end with a LIST_SEPARATOR_CHAR. + [Richard Levitte ] + + *) Fix problems with sizeof(long) == 8. + [Andy Polyakov ] + + *) Change functions to ANSI C. + [Ulf Möller] + + *) Fix typos in error codes. + [Martin Kraemer , Ulf Möller] + + *) Remove defunct assembler files from Configure. + [Ulf Möller] + + *) SPARC v8 assembler BIGNUM implementation. + [Andy Polyakov ] + + *) Support for Certificate Policies extension: both print and set. + Various additions to support the r2i method this uses. + [Steve Henson] + + *) A lot of constification, and fix a bug in X509_NAME_oneline() that could + return a const string when you are expecting an allocated buffer. + [Ben Laurie] + + *) Add support for ASN1 types UTF8String and VISIBLESTRING, also the CHOICE + types DirectoryString and DisplayText. + [Steve Henson] + + *) Add code to allow r2i extensions to access the configuration database, + add an LHASH database driver and add several ctx helper functions. + [Steve Henson] + + *) Fix an evil bug in bn_expand2() which caused various BN functions to + fail when they extended the size of a BIGNUM. + [Steve Henson] + + *) Various utility functions to handle SXNet extension. Modify mkdef.pl to + support typesafe stack. + [Steve Henson] + + *) Fix typo in SSL_[gs]et_options(). + [Nils Frostberg ] + + *) Delete various functions and files that belonged to the (now obsolete) + old X509V3 handling code. + [Steve Henson] + + *) New Configure option "rsaref". + [Ulf Möller] + + *) Don't auto-generate pem.h. + [Bodo Moeller] + + *) Introduce type-safe ASN.1 SETs. + [Ben Laurie] + + *) Convert various additional casted stacks to type-safe STACK_OF() variants. + [Ben Laurie, Ralf S. Engelschall, Steve Henson] + + *) Introduce type-safe STACKs. This will almost certainly break lots of code + that links with OpenSSL (well at least cause lots of warnings), but fear + not: the conversion is trivial, and it eliminates loads of evil casts. A + few STACKed things have been converted already. Feel free to convert more. + In the fullness of time, I'll do away with the STACK type altogether. + [Ben Laurie] + + *) Add `openssl ca -revoke ' facility which revokes a certificate + specified in by updating the entry in the index.txt file. + This way one no longer has to edit the index.txt file manually for + revoking a certificate. The -revoke option does the gory details now. + [Massimiliano Pala , Ralf S. Engelschall] + + *) Fix `openssl crl -noout -text' combination where `-noout' killed the + `-text' option at all and this way the `-noout -text' combination was + inconsistent in `openssl crl' with the friends in `openssl x509|rsa|dsa'. + [Ralf S. Engelschall] + + *) Make sure a corresponding plain text error message exists for the + X509_V_ERR_CERT_REVOKED/23 error number which can occur when a + verify callback function determined that a certificate was revoked. + [Ralf S. Engelschall] + + *) Bugfix: In test/testenc, don't test "openssl " for + ciphers that were excluded, e.g. by -DNO_IDEA. Also, test + all available cipers including rc5, which was forgotten until now. + In order to let the testing shell script know which algorithms + are available, a new (up to now undocumented) command + "openssl list-cipher-commands" is used. + [Bodo Moeller] + + *) Bugfix: s_client occasionally would sleep in select() when + it should have checked SSL_pending() first. + [Bodo Moeller] + + *) New functions DSA_do_sign and DSA_do_verify to provide access to + the raw DSA values prior to ASN.1 encoding. + [Ulf Möller] + + *) Tweaks to Configure + [Niels Poppe ] + + *) Add support for PKCS#5 v2.0 ASN1 PBES2 structures. No other support, + yet... + [Steve Henson] + + *) New variables $(RANLIB) and $(PERL) in the Makefiles. + [Ulf Möller] + + *) New config option to avoid instructions that are illegal on the 80386. + The default code is faster, but requires at least a 486. + [Ulf Möller] + + *) Got rid of old SSL2_CLIENT_VERSION (inconsistently used) and + SSL2_SERVER_VERSION (not used at all) macros, which are now the + same as SSL2_VERSION anyway. + [Bodo Moeller] + + *) New "-showcerts" option for s_client. + [Bodo Moeller] + + *) Still more PKCS#12 integration. Add pkcs12 application to openssl + application. Various cleanups and fixes. + [Steve Henson] + + *) More PKCS#12 integration. Add new pkcs12 directory with Makefile.ssl and + modify error routines to work internally. Add error codes and PBE init + to library startup routines. + [Steve Henson] + + *) Further PKCS#12 integration. Added password based encryption, PKCS#8 and + packing functions to asn1 and evp. Changed function names and error + codes along the way. + [Steve Henson] + + *) PKCS12 integration: and so it begins... First of several patches to + slowly integrate PKCS#12 functionality into OpenSSL. Add PKCS#12 + objects to objects.h + [Steve Henson] + + *) Add a new 'indent' option to some X509V3 extension code. Initial ASN1 + and display support for Thawte strong extranet extension. + [Steve Henson] + + *) Add LinuxPPC support. + [Jeff Dubrule ] + + *) Get rid of redundant BN file bn_mulw.c, and rename bn_div64 to + bn_div_words in alpha.s. + [Hannes Reinecke and Ben Laurie] + + *) Make sure the RSA OAEP test is skipped under -DRSAref because + OAEP isn't supported when OpenSSL is built with RSAref. + [Ulf Moeller ] + + *) Move definitions of IS_SET/IS_SEQUENCE inside crypto/asn1/asn1.h + so they no longer are missing under -DNOPROTO. + [Soren S. Jorvang ] + + + Changes between 0.9.1c and 0.9.2b [22 Mar 1999] + + *) Make SSL_get_peer_cert_chain() work in servers. Unfortunately, it still + doesn't work when the session is reused. Coming soon! + [Ben Laurie] + + *) Fix a security hole, that allows sessions to be reused in the wrong + context thus bypassing client cert protection! All software that uses + client certs and session caches in multiple contexts NEEDS PATCHING to + allow session reuse! A fuller solution is in the works. + [Ben Laurie, problem pointed out by Holger Reif, Bodo Moeller (and ???)] + + *) Some more source tree cleanups (removed obsolete files + crypto/bf/asm/bf586.pl, test/test.txt and crypto/sha/asm/f.s; changed + permission on "config" script to be executable) and a fix for the INSTALL + document. + [Ulf Moeller ] + + *) Remove some legacy and erroneous uses of malloc, free instead of + Malloc, Free. + [Lennart Bang , with minor changes by Steve] + + *) Make rsa_oaep_test return non-zero on error. + [Ulf Moeller ] + + *) Add support for native Solaris shared libraries. Configure + solaris-sparc-sc4-pic, make, then run shlib/solaris-sc4.sh. It'd be nice + if someone would make that last step automatic. + [Matthias Loepfe ] + + *) ctx_size was not built with the right compiler during "make links". Fixed. + [Ben Laurie] + + *) Change the meaning of 'ALL' in the cipher list. It now means "everything + except NULL ciphers". This means the default cipher list will no longer + enable NULL ciphers. They need to be specifically enabled e.g. with + the string "DEFAULT:eNULL". + [Steve Henson] + + *) Fix to RSA private encryption routines: if p < q then it would + occasionally produce an invalid result. This will only happen with + externally generated keys because OpenSSL (and SSLeay) ensure p > q. + [Steve Henson] + + *) Be less restrictive and allow also `perl util/perlpath.pl + /path/to/bin/perl' in addition to `perl util/perlpath.pl /path/to/bin', + because this way one can also use an interpreter named `perl5' (which is + usually the name of Perl 5.xxx on platforms where an Perl 4.x is still + installed as `perl'). + [Matthias Loepfe ] + + *) Let util/clean-depend.pl work also with older Perl 5.00x versions. + [Matthias Loepfe ] + + *) Fix Makefile.org so CC,CFLAG etc are passed to 'make links' add + advapi32.lib to Win32 build and change the pem test comparision + to fc.exe (thanks to Ulrich Kroener for the + suggestion). Fix misplaced ASNI prototypes and declarations in evp.h + and crypto/des/ede_cbcm_enc.c. + [Steve Henson] + + *) DES quad checksum was broken on big-endian architectures. Fixed. + [Ben Laurie] + + *) Comment out two functions in bio.h that aren't implemented. Fix up the + Win32 test batch file so it (might) work again. The Win32 test batch file + is horrible: I feel ill.... + [Steve Henson] + + *) Move various #ifdefs around so NO_SYSLOG, NO_DIRENT etc are now selected + in e_os.h. Audit of header files to check ANSI and non ANSI + sections: 10 functions were absent from non ANSI section and not exported + from Windows DLLs. Fixed up libeay.num for new functions. + [Steve Henson] + + *) Make `openssl version' output lines consistent. + [Ralf S. Engelschall] + + *) Fix Win32 symbol export lists for BIO functions: Added + BIO_get_ex_new_index, BIO_get_ex_num, BIO_get_ex_data and BIO_set_ex_data + to ms/libeay{16,32}.def. + [Ralf S. Engelschall] + + *) Second round of fixing the OpenSSL perl/ stuff. It now at least compiled + fine under Unix and passes some trivial tests I've now added. But the + whole stuff is horribly incomplete, so a README.1ST with a disclaimer was + added to make sure no one expects that this stuff really works in the + OpenSSL 0.9.2 release. Additionally I've started to clean the XS sources + up and fixed a few little bugs and inconsistencies in OpenSSL.{pm,xs} and + openssl_bio.xs. + [Ralf S. Engelschall] + + *) Fix the generation of two part addresses in perl. + [Kenji Miyake , integrated by Ben Laurie] + + *) Add config entry for Linux on MIPS. + [John Tobey ] + + *) Make links whenever Configure is run, unless we are on Windoze. + [Ben Laurie] + + *) Permit extensions to be added to CRLs using crl_section in openssl.cnf. + Currently only issuerAltName and AuthorityKeyIdentifier make any sense + in CRLs. + [Steve Henson] + + *) Add a useful kludge to allow package maintainers to specify compiler and + other platforms details on the command line without having to patch the + Configure script everytime: One now can use ``perl Configure + :
'', i.e. platform ids are allowed to have details appended + to them (seperated by colons). This is treated as there would be a static + pre-configured entry in Configure's %table under key with value +
and ``perl Configure '' is called. So, when you want to + perform a quick test-compile under FreeBSD 3.1 with pgcc and without + assembler stuff you can use ``perl Configure "FreeBSD-elf:pgcc:-O6:::"'' + now, which overrides the FreeBSD-elf entry on-the-fly. + [Ralf S. Engelschall] + + *) Disable new TLS1 ciphersuites by default: they aren't official yet. + [Ben Laurie] + + *) Allow DSO flags like -fpic, -fPIC, -KPIC etc. to be specified + on the `perl Configure ...' command line. This way one can compile + OpenSSL libraries with Position Independent Code (PIC) which is needed + for linking it into DSOs. + [Ralf S. Engelschall] + + *) Remarkably, export ciphers were totally broken and no-one had noticed! + Fixed. + [Ben Laurie] + + *) Cleaned up the LICENSE document: The official contact for any license + questions now is the OpenSSL core team under openssl-core@openssl.org. + And add a paragraph about the dual-license situation to make sure people + recognize that _BOTH_ the OpenSSL license _AND_ the SSLeay license apply + to the OpenSSL toolkit. + [Ralf S. Engelschall] + + *) General source tree makefile cleanups: Made `making xxx in yyy...' + display consistent in the source tree and replaced `/bin/rm' by `rm'. + Additonally cleaned up the `make links' target: Remove unnecessary + semicolons, subsequent redundant removes, inline point.sh into mklink.sh + to speed processing and no longer clutter the display with confusing + stuff. Instead only the actually done links are displayed. + [Ralf S. Engelschall] + + *) Permit null encryption ciphersuites, used for authentication only. It used + to be necessary to set the preprocessor define SSL_ALLOW_ENULL to do this. + It is now necessary to set SSL_FORBID_ENULL to prevent the use of null + encryption. + [Ben Laurie] + + *) Add a bunch of fixes to the PKCS#7 stuff. It used to sometimes reorder + signed attributes when verifying signatures (this would break them), + the detached data encoding was wrong and public keys obtained using + X509_get_pubkey() weren't freed. + [Steve Henson] + + *) Add text documentation for the BUFFER functions. Also added a work around + to a Win95 console bug. This was triggered by the password read stuff: the + last character typed gets carried over to the next fread(). If you were + generating a new cert request using 'req' for example then the last + character of the passphrase would be CR which would then enter the first + field as blank. + [Steve Henson] + + *) Added the new `Includes OpenSSL Cryptography Software' button as + doc/openssl_button.{gif,html} which is similar in style to the old SSLeay + button and can be used by applications based on OpenSSL to show the + relationship to the OpenSSL project. + [Ralf S. Engelschall] + + *) Remove confusing variables in function signatures in files + ssl/ssl_lib.c and ssl/ssl.h. + [Lennart Bong ] + + *) Don't install bss_file.c under PREFIX/include/ + [Lennart Bong ] + + *) Get the Win32 compile working again. Modify mkdef.pl so it can handle + functions that return function pointers and has support for NT specific + stuff. Fix mk1mf.pl and VC-32.pl to support NT differences also. Various + #ifdef WIN32 and WINNTs sprinkled about the place and some changes from + unsigned to signed types: this was killing the Win32 compile. + [Steve Henson] + + *) Add new certificate file to stack functions, + SSL_add_dir_cert_subjects_to_stack() and + SSL_add_file_cert_subjects_to_stack(). These largely supplant + SSL_load_client_CA_file(), and can be used to add multiple certs easily + to a stack (usually this is then handed to SSL_CTX_set_client_CA_list()). + This means that Apache-SSL and similar packages don't have to mess around + to add as many CAs as they want to the preferred list. + [Ben Laurie] + + *) Experiment with doxygen documentation. Currently only partially applied to + ssl/ssl_lib.c. + See http://www.stack.nl/~dimitri/doxygen/index.html, and run doxygen with + openssl.doxy as the configuration file. + [Ben Laurie] + + *) Get rid of remaining C++-style comments which strict C compilers hate. + [Ralf S. Engelschall, pointed out by Carlos Amengual] + + *) Changed BN_RECURSION in bn_mont.c to BN_RECURSION_MONT so it is not + compiled in by default: it has problems with large keys. + [Steve Henson] + + *) Add a bunch of SSL_xxx() functions for configuring the temporary RSA and + DH private keys and/or callback functions which directly correspond to + their SSL_CTX_xxx() counterparts but work on a per-connection basis. This + is needed for applications which have to configure certificates on a + per-connection basis (e.g. Apache+mod_ssl) instead of a per-context basis + (e.g. s_server). + For the RSA certificate situation is makes no difference, but + for the DSA certificate situation this fixes the "no shared cipher" + problem where the OpenSSL cipher selection procedure failed because the + temporary keys were not overtaken from the context and the API provided + no way to reconfigure them. + The new functions now let applications reconfigure the stuff and they + are in detail: SSL_need_tmp_RSA, SSL_set_tmp_rsa, SSL_set_tmp_dh, + SSL_set_tmp_rsa_callback and SSL_set_tmp_dh_callback. Additionally a new + non-public-API function ssl_cert_instantiate() is used as a helper + function and also to reduce code redundancy inside ssl_rsa.c. + [Ralf S. Engelschall] + + *) Move s_server -dcert and -dkey options out of the undocumented feature + area because they are useful for the DSA situation and should be + recognized by the users. + [Ralf S. Engelschall] + + *) Fix the cipher decision scheme for export ciphers: the export bits are + *not* within SSL_MKEY_MASK or SSL_AUTH_MASK, they are within + SSL_EXP_MASK. So, the original variable has to be used instead of the + already masked variable. + [Richard Levitte ] + + *) Fix 'port' variable from `int' to `unsigned int' in crypto/bio/b_sock.c + [Richard Levitte ] + + *) Change type of another md_len variable in pk7_doit.c:PKCS7_dataFinal() + from `int' to `unsigned int' because it's a length and initialized by + EVP_DigestFinal() which expects an `unsigned int *'. + [Richard Levitte ] + + *) Don't hard-code path to Perl interpreter on shebang line of Configure + script. Instead use the usual Shell->Perl transition trick. + [Ralf S. Engelschall] + + *) Make `openssl x509 -noout -modulus' functional also for DSA certificates + (in addition to RSA certificates) to match the behaviour of `openssl dsa + -noout -modulus' as it's already the case for `openssl rsa -noout + -modulus'. For RSA the -modulus is the real "modulus" while for DSA + currently the public key is printed (a decision which was already done by + `openssl dsa -modulus' in the past) which serves a similar purpose. + Additionally the NO_RSA no longer completely removes the whole -modulus + option; it now only avoids using the RSA stuff. Same applies to NO_DSA + now, too. + [Ralf S. Engelschall] + + *) Add Arne Ansper's reliable BIO - this is an encrypted, block-digested + BIO. See the source (crypto/evp/bio_ok.c) for more info. + [Arne Ansper ] + + *) Dump the old yucky req code that tried (and failed) to allow raw OIDs + to be added. Now both 'req' and 'ca' can use new objects defined in the + config file. + [Steve Henson] + + *) Add cool BIO that does syslog (or event log on NT). + [Arne Ansper , integrated by Ben Laurie] + + *) Add support for new TLS ciphersuites, TLS_RSA_EXPORT56_WITH_RC4_56_MD5, + TLS_RSA_EXPORT56_WITH_RC2_CBC_56_MD5 and + TLS_RSA_EXPORT56_WITH_DES_CBC_SHA, as specified in "56-bit Export Cipher + Suites For TLS", draft-ietf-tls-56-bit-ciphersuites-00.txt. + [Ben Laurie] + + *) Add preliminary config info for new extension code. + [Steve Henson] + + *) Make RSA_NO_PADDING really use no padding. + [Ulf Moeller ] + + *) Generate errors when private/public key check is done. + [Ben Laurie] + + *) Overhaul for 'crl' utility. New function X509_CRL_print. Partial support + for some CRL extensions and new objects added. + [Steve Henson] + + *) Really fix the ASN1 IMPLICIT bug this time... Partial support for private + key usage extension and fuller support for authority key id. + [Steve Henson] + + *) Add OAEP encryption for the OpenSSL crypto library. OAEP is the improved + padding method for RSA, which is recommended for new applications in PKCS + #1 v2.0 (RFC 2437, October 1998). + OAEP (Optimal Asymmetric Encryption Padding) has better theoretical + foundations than the ad-hoc padding used in PKCS #1 v1.5. It is secure + against Bleichbacher's attack on RSA. + [Ulf Moeller , reformatted, corrected and integrated by + Ben Laurie] + + *) Updates to the new SSL compression code + [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)] + + *) Fix so that the version number in the master secret, when passed + via RSA, checks that if TLS was proposed, but we roll back to SSLv3 + (because the server will not accept higher), that the version number + is 0x03,0x01, not 0x03,0x00 + [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)] + + *) Run extensive memory leak checks on SSL apps. Fixed *lots* of memory + leaks in ssl/ relating to new X509_get_pubkey() behaviour. Also fixes + in apps/ and an unrelated leak in crypto/dsa/dsa_vrf.c + [Steve Henson] + + *) Support for RAW extensions where an arbitrary extension can be + created by including its DER encoding. See apps/openssl.cnf for + an example. + [Steve Henson] + + *) Make sure latest Perl versions don't interpret some generated C array + code as Perl array code in the crypto/err/err_genc.pl script. + [Lars Weber <3weber@informatik.uni-hamburg.de>] + + *) Modify ms/do_ms.bat to not generate assembly language makefiles since + not many people have the assembler. Various Win32 compilation fixes and + update to the INSTALL.W32 file with (hopefully) more accurate Win32 + build instructions. + [Steve Henson] + + *) Modify configure script 'Configure' to automatically create crypto/date.h + file under Win32 and also build pem.h from pem.org. New script + util/mkfiles.pl to create the MINFO file on environments that can't do a + 'make files': perl util/mkfiles.pl >MINFO should work. + [Steve Henson] + + *) Major rework of DES function declarations, in the pursuit of correctness + and purity. As a result, many evil casts evaporated, and some weirdness, + too. You may find this causes warnings in your code. Zapping your evil + casts will probably fix them. Mostly. + [Ben Laurie] + + *) Fix for a typo in asn1.h. Bug fix to object creation script + obj_dat.pl. It considered a zero in an object definition to mean + "end of object": none of the objects in objects.h have any zeros + so it wasn't spotted. + [Steve Henson, reported by Erwann ABALEA ] + + *) Add support for Triple DES Cipher Block Chaining with Output Feedback + Masking (CBCM). In the absence of test vectors, the best I have been able + to do is check that the decrypt undoes the encrypt, so far. Send me test + vectors if you have them. + [Ben Laurie] + + *) Correct calculation of key length for export ciphers (too much space was + allocated for null ciphers). This has not been tested! + [Ben Laurie] + + *) Modifications to the mkdef.pl for Win32 DEF file creation. The usage + message is now correct (it understands "crypto" and "ssl" on its + command line). There is also now an "update" option. This will update + the util/ssleay.num and util/libeay.num files with any new functions. + If you do a: + perl util/mkdef.pl crypto ssl update + it will update them. + [Steve Henson] + + *) Overhauled the Perl interface (perl/*): + - ported BN stuff to OpenSSL's different BN library + - made the perl/ source tree CVS-aware + - renamed the package from SSLeay to OpenSSL (the files still contain + their history because I've copied them in the repository) + - removed obsolete files (the test scripts will be replaced + by better Test::Harness variants in the future) + [Ralf S. Engelschall] + + *) First cut for a very conservative source tree cleanup: + 1. merge various obsolete readme texts into doc/ssleay.txt + where we collect the old documents and readme texts. + 2. remove the first part of files where I'm already sure that we no + longer need them because of three reasons: either they are just temporary + files which were left by Eric or they are preserved original files where + I've verified that the diff is also available in the CVS via "cvs diff + -rSSLeay_0_8_1b" or they were renamed (as it was definitely the case for + the crypto/md/ stuff). + [Ralf S. Engelschall] + + *) More extension code. Incomplete support for subject and issuer alt + name, issuer and authority key id. Change the i2v function parameters + and add an extra 'crl' parameter in the X509V3_CTX structure: guess + what that's for :-) Fix to ASN1 macro which messed up + IMPLICIT tag and add f_enum.c which adds a2i, i2a for ENUMERATED. + [Steve Henson] + + *) Preliminary support for ENUMERATED type. This is largely copied from the + INTEGER code. + [Steve Henson] + + *) Add new function, EVP_MD_CTX_copy() to replace frequent use of memcpy. + [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)] + + *) Make sure `make rehash' target really finds the `openssl' program. + [Ralf S. Engelschall, Matthias Loepfe ] + + *) Squeeze another 7% of speed out of MD5 assembler, at least on a P2. I'd + like to hear about it if this slows down other processors. + [Ben Laurie] + + *) Add CygWin32 platform information to Configure script. + [Alan Batie ] + + *) Fixed ms/32all.bat script: `no_asm' -> `no-asm' + [Rainer W. Gerling ] + + *) New program nseq to manipulate netscape certificate sequences + [Steve Henson] + + *) Modify crl2pkcs7 so it supports multiple -certfile arguments. Fix a + few typos. + [Steve Henson] + + *) Fixes to BN code. Previously the default was to define BN_RECURSION + but the BN code had some problems that would cause failures when + doing certificate verification and some other functions. + [Eric A. Young, (from changes to C2Net SSLeay, integrated by Mark Cox)] + + *) Add ASN1 and PEM code to support netscape certificate sequences. + [Steve Henson] + + *) Add ASN1 and PEM code to support netscape certificate sequences. + [Steve Henson] + + *) Add several PKIX and private extended key usage OIDs. + [Steve Henson] + + *) Modify the 'ca' program to handle the new extension code. Modify + openssl.cnf for new extension format, add comments. + [Steve Henson] + + *) More X509 V3 changes. Fix typo in v3_bitstr.c. Add support to 'req' + and add a sample to openssl.cnf so req -x509 now adds appropriate + CA extensions. + [Steve Henson] + + *) Continued X509 V3 changes. Add to other makefiles, integrate with the + error code, add initial support to X509_print() and x509 application. + [Steve Henson] + + *) Takes a deep breath and start addding X509 V3 extension support code. Add + files in crypto/x509v3. Move original stuff to crypto/x509v3/old. All this + stuff is currently isolated and isn't even compiled yet. + [Steve Henson] + + *) Continuing patches for GeneralizedTime. Fix up certificate and CRL + ASN1 to use ASN1_TIME and modify print routines to use ASN1_TIME_print. + Removed the versions check from X509 routines when loading extensions: + this allows certain broken certificates that don't set the version + properly to be processed. + [Steve Henson] + + *) Deal with irritating shit to do with dependencies, in YAAHW (Yet Another + Ad Hoc Way) - Makefile.ssls now all contain local dependencies, which + can still be regenerated with "make depend". + [Ben Laurie] + + *) Spelling mistake in C version of CAST-128. + [Ben Laurie, reported by Jeremy Hylton ] + + *) Changes to the error generation code. The perl script err-code.pl + now reads in the old error codes and retains the old numbers, only + adding new ones if necessary. It also only changes the .err files if new + codes are added. The makefiles have been modified to only insert errors + when needed (to avoid needlessly modifying header files). This is done + by only inserting errors if the .err file is newer than the auto generated + C file. To rebuild all the error codes from scratch (the old behaviour) + either modify crypto/Makefile.ssl to pass the -regen flag to err_code.pl + or delete all the .err files. + [Steve Henson] + + *) CAST-128 was incorrectly implemented for short keys. The C version has + been fixed, but is untested. The assembler versions are also fixed, but + new assembler HAS NOT BEEN GENERATED FOR WIN32 - the Makefile needs fixing + to regenerate it if needed. + [Ben Laurie, reported (with fix for C version) by Jun-ichiro itojun + Hagino ] + + *) File was opened incorrectly in randfile.c. + [Ulf Möller ] + + *) Beginning of support for GeneralizedTime. d2i, i2d, check and print + functions. Also ASN1_TIME suite which is a CHOICE of UTCTime or + GeneralizedTime. ASN1_TIME is the proper type used in certificates et + al: it's just almost always a UTCTime. Note this patch adds new error + codes so do a "make errors" if there are problems. + [Steve Henson] + + *) Correct Linux 1 recognition in config. + [Ulf Möller ] + + *) Remove pointless MD5 hash when using DSA keys in ca. + [Anonymous ] + + *) Generate an error if given an empty string as a cert directory. Also + generate an error if handed NULL (previously returned 0 to indicate an + error, but didn't set one). + [Ben Laurie, reported by Anonymous ] + + *) Add prototypes to SSL methods. Make SSL_write's buffer const, at last. + [Ben Laurie] + + *) Fix the dummy function BN_ref_mod_exp() in rsaref.c to have the correct + parameters. This was causing a warning which killed off the Win32 compile. + [Steve Henson] + + *) Remove C++ style comments from crypto/bn/bn_local.h. + [Neil Costigan ] + + *) The function OBJ_txt2nid was broken. It was supposed to return a nid + based on a text string, looking up short and long names and finally + "dot" format. The "dot" format stuff didn't work. Added new function + OBJ_txt2obj to do the same but return an ASN1_OBJECT and rewrote + OBJ_txt2nid to use it. OBJ_txt2obj can also return objects even if the + OID is not part of the table. + [Steve Henson] + + *) Add prototypes to X509 lookup/verify methods, fixing a bug in + X509_LOOKUP_by_alias(). + [Ben Laurie] + + *) Sort openssl functions by name. + [Ben Laurie] + + *) Get the gendsa program working (hopefully) and add it to app list. Remove + encryption from sample DSA keys (in case anyone is interested the password + was "1234"). + [Steve Henson] + + *) Make _all_ *_free functions accept a NULL pointer. + [Frans Heymans ] + + *) If a DH key is generated in s3_srvr.c, don't blow it by trying to use + NULL pointers. + [Anonymous ] + + *) s_server should send the CAfile as acceptable CAs, not its own cert. + [Bodo Moeller <3moeller@informatik.uni-hamburg.de>] + + *) Don't blow it for numeric -newkey arguments to apps/req. + [Bodo Moeller <3moeller@informatik.uni-hamburg.de>] + + *) Temp key "for export" tests were wrong in s3_srvr.c. + [Anonymous ] + + *) Add prototype for temp key callback functions + SSL_CTX_set_tmp_{rsa,dh}_callback(). + [Ben Laurie] + + *) Make DH_free() tolerate being passed a NULL pointer (like RSA_free() and + DSA_free()). Make X509_PUBKEY_set() check for errors in d2i_PublicKey(). + [Steve Henson] + + *) X509_name_add_entry() freed the wrong thing after an error. + [Arne Ansper ] + + *) rsa_eay.c would attempt to free a NULL context. + [Arne Ansper ] + + *) BIO_s_socket() had a broken should_retry() on Windoze. + [Arne Ansper ] + + *) BIO_f_buffer() didn't pass on BIO_CTRL_FLUSH. + [Arne Ansper ] + + *) Make sure the already existing X509_STORE->depth variable is initialized + in X509_STORE_new(), but document the fact that this variable is still + unused in the certificate verification process. + [Ralf S. Engelschall] + + *) Fix the various library and apps files to free up pkeys obtained from + X509_PUBKEY_get() et al. Also allow x509.c to handle netscape extensions. + [Steve Henson] + + *) Fix reference counting in X509_PUBKEY_get(). This makes + demos/maurice/example2.c work, amongst others, probably. + [Steve Henson and Ben Laurie] + + *) First cut of a cleanup for apps/. First the `ssleay' program is now named + `openssl' and second, the shortcut symlinks for the `openssl ' + are no longer created. This way we have a single and consistent command + line interface `openssl ', similar to `cvs '. + [Ralf S. Engelschall, Paul Sutton and Ben Laurie] + + *) ca.c: move test for DSA keys inside #ifndef NO_DSA. Make pubkey + BIT STRING wrapper always have zero unused bits. + [Steve Henson] + + *) Add CA.pl, perl version of CA.sh, add extended key usage OID. + [Steve Henson] + + *) Make the top-level INSTALL documentation easier to understand. + [Paul Sutton] + + *) Makefiles updated to exit if an error occurs in a sub-directory + make (including if user presses ^C) [Paul Sutton] + + *) Make Montgomery context stuff explicit in RSA data structure. + [Ben Laurie] + + *) Fix build order of pem and err to allow for generated pem.h. + [Ben Laurie] + + *) Fix renumbering bug in X509_NAME_delete_entry(). + [Ben Laurie] + + *) Enhanced the err-ins.pl script so it makes the error library number + global and can add a library name. This is needed for external ASN1 and + other error libraries. + [Steve Henson] + + *) Fixed sk_insert which never worked properly. + [Steve Henson] + + *) Fix ASN1 macros so they can handle indefinite length construted + EXPLICIT tags. Some non standard certificates use these: they can now + be read in. + [Steve Henson] + + *) Merged the various old/obsolete SSLeay documentation files (doc/xxx.doc) + into a single doc/ssleay.txt bundle. This way the information is still + preserved but no longer messes up this directory. Now it's new room for + the new set of documenation files. + [Ralf S. Engelschall] + + *) SETs were incorrectly DER encoded. This was a major pain, because they + shared code with SEQUENCEs, which aren't coded the same. This means that + almost everything to do with SETs or SEQUENCEs has either changed name or + number of arguments. + [Ben Laurie, based on a partial fix by GP Jayan ] + + *) Fix test data to work with the above. + [Ben Laurie] + + *) Fix the RSA header declarations that hid a bug I fixed in 0.9.0b but + was already fixed by Eric for 0.9.1 it seems. + [Ben Laurie - pointed out by Ulf Möller ] + + *) Autodetect FreeBSD3. + [Ben Laurie] + + *) Fix various bugs in Configure. This affects the following platforms: + nextstep + ncr-scde + unixware-2.0 + unixware-2.0-pentium + sco5-cc. + [Ben Laurie] + + *) Eliminate generated files from CVS. Reorder tests to regenerate files + before they are needed. + [Ben Laurie] + + *) Generate Makefile.ssl from Makefile.org (to keep CVS happy). + [Ben Laurie] + + + Changes between 0.9.1b and 0.9.1c [23-Dec-1998] + + *) Added OPENSSL_VERSION_NUMBER to crypto/crypto.h and + changed SSLeay to OpenSSL in version strings. + [Ralf S. Engelschall] + + *) Some fixups to the top-level documents. + [Paul Sutton] + + *) Fixed the nasty bug where rsaref.h was not found under compile-time + because the symlink to include/ was missing. + [Ralf S. Engelschall] + + *) Incorporated the popular no-RSA/DSA-only patches + which allow to compile a RSA-free SSLeay. + [Andrew Cooke / Interrader Ldt., Ralf S. Engelschall] + + *) Fixed nasty rehash problem under `make -f Makefile.ssl links' + when "ssleay" is still not found. + [Ralf S. Engelschall] + + *) Added more platforms to Configure: Cray T3E, HPUX 11, + [Ralf S. Engelschall, Beckmann ] + + *) Updated the README file. + [Ralf S. Engelschall] + + *) Added various .cvsignore files in the CVS repository subdirs + to make a "cvs update" really silent. + [Ralf S. Engelschall] + + *) Recompiled the error-definition header files and added + missing symbols to the Win32 linker tables. + [Ralf S. Engelschall] + + *) Cleaned up the top-level documents; + o new files: CHANGES and LICENSE + o merged VERSION, HISTORY* and README* files a CHANGES.SSLeay + o merged COPYRIGHT into LICENSE + o removed obsolete TODO file + o renamed MICROSOFT to INSTALL.W32 + [Ralf S. Engelschall] + + *) Removed dummy files from the 0.9.1b source tree: + crypto/asn1/x crypto/bio/cd crypto/bio/fg crypto/bio/grep crypto/bio/vi + crypto/bn/asm/......add.c crypto/bn/asm/a.out crypto/dsa/f crypto/md5/f + crypto/pem/gmon.out crypto/perlasm/f crypto/pkcs7/build crypto/rsa/f + crypto/sha/asm/f crypto/threads/f ms/zzz ssl/f ssl/f.mak test/f + util/f.mak util/pl/f util/pl/f.mak crypto/bf/bf_locl.old apps/f + [Ralf S. Engelschall] + + *) Added various platform portability fixes. + [Mark J. Cox] + + *) The Genesis of the OpenSSL rpject: + We start with the latest (unreleased) SSLeay version 0.9.1b which Eric A. + Young and Tim J. Hudson created while they were working for C2Net until + summer 1998. + [The OpenSSL Project] + + + Changes between 0.9.0b and 0.9.1b [not released] + + *) Updated a few CA certificates under certs/ + [Eric A. Young] + + *) Changed some BIGNUM api stuff. + [Eric A. Young] + + *) Various platform ports: OpenBSD, Ultrix, IRIX 64bit, NetBSD, + DGUX x86, Linux Alpha, etc. + [Eric A. Young] + + *) New COMP library [crypto/comp/] for SSL Record Layer Compression: + RLE (dummy implemented) and ZLIB (really implemented when ZLIB is + available). + [Eric A. Young] + + *) Add -strparse option to asn1pars program which parses nested + binary structures + [Dr Stephen Henson ] + + *) Added "oid_file" to ssleay.cnf for "ca" and "req" programs. + [Eric A. Young] + + *) DSA fix for "ca" program. + [Eric A. Young] + + *) Added "-genkey" option to "dsaparam" program. + [Eric A. Young] + + *) Added RIPE MD160 (rmd160) message digest. + [Eric A. Young] + + *) Added -a (all) option to "ssleay version" command. + [Eric A. Young] + + *) Added PLATFORM define which is the id given to Configure. + [Eric A. Young] + + *) Added MemCheck_XXXX functions to crypto/mem.c for memory checking. + [Eric A. Young] + + *) Extended the ASN.1 parser routines. + [Eric A. Young] + + *) Extended BIO routines to support REUSEADDR, seek, tell, etc. + [Eric A. Young] + + *) Added a BN_CTX to the BN library. + [Eric A. Young] + + *) Fixed the weak key values in DES library + [Eric A. Young] + + *) Changed API in EVP library for cipher aliases. + [Eric A. Young] + + *) Added support for RC2/64bit cipher. + [Eric A. Young] + + *) Converted the lhash library to the crypto/mem.c functions. + [Eric A. Young] + + *) Added more recognized ASN.1 object ids. + [Eric A. Young] + + *) Added more RSA padding checks for SSL/TLS. + [Eric A. Young] + + *) Added BIO proxy/filter functionality. + [Eric A. Young] + + *) Added extra_certs to SSL_CTX which can be used + send extra CA certificates to the client in the CA cert chain sending + process. It can be configured with SSL_CTX_add_extra_chain_cert(). + [Eric A. Young] + + *) Now Fortezza is denied in the authentication phase because + this is key exchange mechanism is not supported by SSLeay at all. + [Eric A. Young] + + *) Additional PKCS1 checks. + [Eric A. Young] + + *) Support the string "TLSv1" for all TLS v1 ciphers. + [Eric A. Young] + + *) Added function SSL_get_ex_data_X509_STORE_CTX_idx() which gives the + ex_data index of the SSL context in the X509_STORE_CTX ex_data. + [Eric A. Young] + + *) Fixed a few memory leaks. + [Eric A. Young] + + *) Fixed various code and comment typos. + [Eric A. Young] + + *) A minor bug in ssl/s3_clnt.c where there would always be 4 0 + bytes sent in the client random. + [Edward Bishop ] + diff --git a/libs/openssl/LICENSE b/libs/openssl/LICENSE new file mode 100644 index 00000000..fb03713d --- /dev/null +++ b/libs/openssl/LICENSE @@ -0,0 +1,127 @@ + + LICENSE ISSUES + ============== + + The OpenSSL toolkit stays under a dual license, i.e. both the conditions of + the OpenSSL License and the original SSLeay license apply to the toolkit. + See below for the actual license texts. Actually both licenses are BSD-style + Open Source licenses. In case of any license issues related to OpenSSL + please contact openssl-core@openssl.org. + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-2016 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + + Original SSLeay License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + diff --git a/libs/openssl/README b/libs/openssl/README new file mode 100644 index 00000000..9395f2ba --- /dev/null +++ b/libs/openssl/README @@ -0,0 +1,119 @@ + + OpenSSL 1.0.1t 3 May 2016 + + Copyright (c) 1998-2015 The OpenSSL Project + Copyright (c) 1995-1998 Eric A. Young, Tim J. Hudson + All rights reserved. + + DESCRIPTION + ----------- + + The OpenSSL Project is a collaborative effort to develop a robust, + commercial-grade, fully featured, and Open Source toolkit implementing the + Secure Sockets Layer (SSLv3) and Transport Layer Security (TLS) protocols as + well as a full-strength general purpose cryptograpic library. The project is + managed by a worldwide community of volunteers that use the Internet to + communicate, plan, and develop the OpenSSL toolkit and its related + documentation. + + OpenSSL is descended from the SSLeay library developed by Eric A. Young + and Tim J. Hudson. The OpenSSL toolkit is licensed under a dual-license (the + OpenSSL license plus the SSLeay license), which means that you are free to + get and use it for commercial and non-commercial purposes as long as you + fulfill the conditions of both licenses. + + OVERVIEW + -------- + + The OpenSSL toolkit includes: + + libssl.a: + Provides the client and server-side implementations for SSLv3 and TLS. + + libcrypto.a: + Provides general cryptographic and X.509 support needed by SSL/TLS but + not logically part of it. + + openssl: + A command line tool that can be used for: + Creation of key parameters + Creation of X.509 certificates, CSRs and CRLs + Calculation of message digests + Encryption and decryption + SSL/TLS client and server tests + Handling of S/MIME signed or encrypted mail + And more... + + INSTALLATION + ------------ + + See the appropriate file: + INSTALL Linux, Unix, etc. + INSTALL.DJGPP DOS platform with DJGPP + INSTALL.NW Netware + INSTALL.OS2 OS/2 + INSTALL.VMS VMS + INSTALL.W32 Windows (32bit) + INSTALL.W64 Windows (64bit) + INSTALL.WCE Windows CE + + SUPPORT + ------- + + See the OpenSSL website www.openssl.org for details on how to obtain + commercial technical support. + + If you have any problems with OpenSSL then please take the following steps + first: + + - Download the current snapshot from ftp://ftp.openssl.org/snapshot/ + to see if the problem has already been addressed + - Remove ASM versions of libraries + - Remove compiler optimisation flags + + If you wish to report a bug then please include the following information in + any bug report: + + - On Unix systems: + Self-test report generated by 'make report' + - On other systems: + OpenSSL version: output of 'openssl version -a' + OS Name, Version, Hardware platform + Compiler Details (name, version) + - Application Details (name, version) + - Problem Description (steps that will reproduce the problem, if known) + - Stack Traceback (if the application dumps core) + + Email the report to: + + rt@openssl.org + + In order to avoid spam, this is a moderated mailing list, and it might + take a day for the ticket to show up. (We also scan posts to make sure + that security disclosures aren't publically posted by mistake.) Mail + to this address is recorded in the public RT (request tracker) database + (see https://www.openssl.org/community/index.html#bugs for details) and + also forwarded the public openssl-dev mailing list. Confidential mail + may be sent to openssl-security@openssl.org (PGP key available from the + key servers). + + Please do NOT use this for general assistance or support queries. + Just because something doesn't work the way you expect does not mean it + is necessarily a bug in OpenSSL. + + You can also make GitHub pull requests. If you do this, please also send + mail to rt@openssl.org with a link to the PR so that we can more easily + keep track of it. + + HOW TO CONTRIBUTE TO OpenSSL + ---------------------------- + + See CONTRIBUTING + + LEGALITIES + ---------- + + A number of nations, in particular the U.S., restrict the use or export + of cryptography. If you are potentially subject to such restrictions + you should seek competent professional legal advice before attempting to + develop or distribute cryptographic code. diff --git a/libs/openssl/android-config.mk b/libs/openssl/android-config.mk new file mode 100644 index 00000000..65b4dece --- /dev/null +++ b/libs/openssl/android-config.mk @@ -0,0 +1,17 @@ +# +# These flags represent the build-time configuration of openssl for android +# +# They were pruned from the "Makefile" generated by running ./Configure from import_openssl.sh +# + +# From CLFAG= +LOCAL_CFLAGS += -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DL_ENDIAN #-DTERMIO + +# From DEPFLAG= +LOCAL_CFLAGS += -DOPENSSL_NO_CAPIENG -DOPENSSL_NO_CMS -DOPENSSL_NO_GMP -DOPENSSL_NO_IDEA -DOPENSSL_NO_JPAKE -DOPENSSL_NO_MD2 -DOPENSSL_NO_MDC2 -DOPENSSL_NO_RC5 -DOPENSSL_NO_SHA0 -DOPENSSL_NO_RFC3779 -DOPENSSL_NO_SEED -DOPENSSL_NO_STORE -DOPENSSL_NO_WHIRLPOOL + +# Extra +LOCAL_CFLAGS += -DOPENSSL_NO_HW -DOPENSSL_NO_ENGINE -DZLIB + +# Debug +# LOCAL_CFLAGS += -DCIPHER_DEBUG diff --git a/libs/openssl/crypto/LPdir_nyi.c b/libs/openssl/crypto/LPdir_nyi.c new file mode 100644 index 00000000..283d5b06 --- /dev/null +++ b/libs/openssl/crypto/LPdir_nyi.c @@ -0,0 +1,47 @@ +/* + * $LP: LPlib/source/LPdir_win.c,v 1.1 2004/06/14 10:07:56 _cvs_levitte Exp $ + */ +/* + * Copyright (c) 2004, Richard Levitte + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef LPDIR_H +# include "LPdir.h" +#endif + +struct LP_dir_context_st { + void *dummy; +}; +const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory) +{ + errno = EINVAL; + return 0; +} + +int LP_find_file_end(LP_DIR_CTX **ctx) +{ + errno = EINVAL; + return 0; +} diff --git a/libs/openssl/crypto/LPdir_unix.c b/libs/openssl/crypto/LPdir_unix.c new file mode 100644 index 00000000..bead6abd --- /dev/null +++ b/libs/openssl/crypto/LPdir_unix.c @@ -0,0 +1,126 @@ +/* + * $LP: LPlib/source/LPdir_unix.c,v 1.11 2004/09/23 22:07:22 _cvs_levitte Exp + * $ + */ +/* + * Copyright (c) 2004, Richard Levitte + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#ifndef LPDIR_H +# include "LPdir.h" +#endif + +/* + * The POSIXly macro for the maximum number of characters in a file path is + * NAME_MAX. However, some operating systems use PATH_MAX instead. + * Therefore, it seems natural to first check for PATH_MAX and use that, and + * if it doesn't exist, use NAME_MAX. + */ +#if defined(PATH_MAX) +# define LP_ENTRY_SIZE PATH_MAX +#elif defined(NAME_MAX) +# define LP_ENTRY_SIZE NAME_MAX +#endif + +/* + * Of course, there's the possibility that neither PATH_MAX nor NAME_MAX + * exist. It's also possible that NAME_MAX exists but is define to a very + * small value (HP-UX offers 14), so we need to check if we got a result, and + * if it meets a minimum standard, and create or change it if not. + */ +#if !defined(LP_ENTRY_SIZE) || LP_ENTRY_SIZE<255 +# undef LP_ENTRY_SIZE +# define LP_ENTRY_SIZE 255 +#endif + +struct LP_dir_context_st { + DIR *dir; + char entry_name[LP_ENTRY_SIZE + 1]; +}; + +const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory) +{ + struct dirent *direntry = NULL; + + if (ctx == NULL || directory == NULL) { + errno = EINVAL; + return 0; + } + + errno = 0; + if (*ctx == NULL) { + *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX)); + if (*ctx == NULL) { + errno = ENOMEM; + return 0; + } + memset(*ctx, '\0', sizeof(LP_DIR_CTX)); + + (*ctx)->dir = opendir(directory); + if ((*ctx)->dir == NULL) { + int save_errno = errno; /* Probably not needed, but I'm paranoid */ + free(*ctx); + *ctx = NULL; + errno = save_errno; + return 0; + } + } + + direntry = readdir((*ctx)->dir); + if (direntry == NULL) { + return 0; + } + + strncpy((*ctx)->entry_name, direntry->d_name, + sizeof((*ctx)->entry_name) - 1); + (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0'; + return (*ctx)->entry_name; +} + +int LP_find_file_end(LP_DIR_CTX **ctx) +{ + if (ctx != NULL && *ctx != NULL) { + int ret = closedir((*ctx)->dir); + + free(*ctx); + switch (ret) { + case 0: + return 1; + case -1: + return 0; + default: + break; + } + } + errno = EINVAL; + return 0; +} diff --git a/libs/openssl/crypto/LPdir_vms.c b/libs/openssl/crypto/LPdir_vms.c new file mode 100644 index 00000000..88c7ddd8 --- /dev/null +++ b/libs/openssl/crypto/LPdir_vms.c @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2004, Richard Levitte + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef LPDIR_H +# include "LPdir.h" +#endif +#include "vms_rms.h" + +/* Some compiler options hide EVMSERR. */ +#ifndef EVMSERR +# define EVMSERR 65535 /* error for non-translatable VMS errors */ +#endif + +struct LP_dir_context_st { + unsigned long VMS_context; + char filespec[NAMX_MAXRSS + 1]; + char result[NAMX_MAXRSS + 1]; + struct dsc$descriptor_d filespec_dsc; + struct dsc$descriptor_d result_dsc; +}; + +const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory) +{ + int status; + char *p, *r; + size_t l; + unsigned long flags = 0; + +/* Arrange 32-bit pointer to (copied) string storage, if needed. */ +#if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size save +# pragma pointer_size 32 + char *ctx_filespec_32p; +# pragma pointer_size restore + char ctx_filespec_32[NAMX_MAXRSS + 1]; +#endif /* __INITIAL_POINTER_SIZE == 64 */ + +#ifdef NAML$C_MAXRSS + flags |= LIB$M_FIL_LONG_NAMES; +#endif + + if (ctx == NULL || directory == NULL) { + errno = EINVAL; + return 0; + } + + errno = 0; + if (*ctx == NULL) { + size_t filespeclen = strlen(directory); + char *filespec = NULL; + + if (filespeclen == 0) { + errno = ENOENT; + return 0; + } + + /* MUST be a VMS directory specification! Let's estimate if it is. */ + if (directory[filespeclen - 1] != ']' + && directory[filespeclen - 1] != '>' + && directory[filespeclen - 1] != ':') { + errno = EINVAL; + return 0; + } + + filespeclen += 4; /* "*.*;" */ + + if (filespeclen > NAMX_MAXRSS) { + errno = ENAMETOOLONG; + return 0; + } + + *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX)); + if (*ctx == NULL) { + errno = ENOMEM; + return 0; + } + memset(*ctx, '\0', sizeof(LP_DIR_CTX)); + + strcpy((*ctx)->filespec, directory); + strcat((*ctx)->filespec, "*.*;"); + +/* Arrange 32-bit pointer to (copied) string storage, if needed. */ +#if __INITIAL_POINTER_SIZE == 64 +# define CTX_FILESPEC ctx_filespec_32p + /* Copy the file name to storage with a 32-bit pointer. */ + ctx_filespec_32p = ctx_filespec_32; + strcpy(ctx_filespec_32p, (*ctx)->filespec); +#else /* __INITIAL_POINTER_SIZE == 64 */ +# define CTX_FILESPEC (*ctx)->filespec +#endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + (*ctx)->filespec_dsc.dsc$w_length = filespeclen; + (*ctx)->filespec_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + (*ctx)->filespec_dsc.dsc$b_class = DSC$K_CLASS_S; + (*ctx)->filespec_dsc.dsc$a_pointer = CTX_FILESPEC; + } + + (*ctx)->result_dsc.dsc$w_length = 0; + (*ctx)->result_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + (*ctx)->result_dsc.dsc$b_class = DSC$K_CLASS_D; + (*ctx)->result_dsc.dsc$a_pointer = 0; + + status = lib$find_file(&(*ctx)->filespec_dsc, &(*ctx)->result_dsc, + &(*ctx)->VMS_context, 0, 0, 0, &flags); + + if (status == RMS$_NMF) { + errno = 0; + vaxc$errno = status; + return NULL; + } + + if (!$VMS_STATUS_SUCCESS(status)) { + errno = EVMSERR; + vaxc$errno = status; + return NULL; + } + + /* + * Quick, cheap and dirty way to discard any device and directory, since + * we only want file names + */ + l = (*ctx)->result_dsc.dsc$w_length; + p = (*ctx)->result_dsc.dsc$a_pointer; + r = p; + for (; *p; p++) { + if (*p == '^' && p[1] != '\0') { /* Take care of ODS-5 escapes */ + p++; + } else if (*p == ':' || *p == '>' || *p == ']') { + l -= p + 1 - r; + r = p + 1; + } else if (*p == ';') { + l = p - r; + break; + } + } + + strncpy((*ctx)->result, r, l); + (*ctx)->result[l] = '\0'; + str$free1_dx(&(*ctx)->result_dsc); + + return (*ctx)->result; +} + +int LP_find_file_end(LP_DIR_CTX **ctx) +{ + if (ctx != NULL && *ctx != NULL) { + int status = lib$find_file_end(&(*ctx)->VMS_context); + + free(*ctx); + + if (!$VMS_STATUS_SUCCESS(status)) { + errno = EVMSERR; + vaxc$errno = status; + return 0; + } + return 1; + } + errno = EINVAL; + return 0; +} diff --git a/libs/openssl/crypto/LPdir_win.c b/libs/openssl/crypto/LPdir_win.c new file mode 100644 index 00000000..07e63fb4 --- /dev/null +++ b/libs/openssl/crypto/LPdir_win.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2004, Richard Levitte + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#ifndef LPDIR_H +# include "LPdir.h" +#endif + +/* + * We're most likely overcautious here, but let's reserve for broken WinCE + * headers and explicitly opt for UNICODE call. Keep in mind that our WinCE + * builds are compiled with -DUNICODE [as well as -D_UNICODE]. + */ +#if defined(LP_SYS_WINCE) && !defined(FindFirstFile) +# define FindFirstFile FindFirstFileW +#endif +#if defined(LP_SYS_WINCE) && !defined(FindNextFile) +# define FindNextFile FindNextFileW +#endif + +#ifndef NAME_MAX +# define NAME_MAX 255 +#endif + +struct LP_dir_context_st { + WIN32_FIND_DATA ctx; + HANDLE handle; + char entry_name[NAME_MAX + 1]; +}; + +const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory) +{ + if (ctx == NULL || directory == NULL) { + errno = EINVAL; + return 0; + } + + errno = 0; + if (*ctx == NULL) { + const char *extdir = directory; + char *extdirbuf = NULL; + size_t dirlen = strlen(directory); + + if (dirlen == 0) { + errno = ENOENT; + return 0; + } + + *ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX)); + if (*ctx == NULL) { + errno = ENOMEM; + return 0; + } + memset(*ctx, '\0', sizeof(LP_DIR_CTX)); + + if (directory[dirlen - 1] != '*') { + extdirbuf = (char *)malloc(dirlen + 3); + if (extdirbuf == NULL) { + free(*ctx); + *ctx = NULL; + errno = ENOMEM; + return 0; + } + if (directory[dirlen - 1] != '/' && directory[dirlen - 1] != '\\') + extdir = strcat(strcpy(extdirbuf, directory), "/*"); + else + extdir = strcat(strcpy(extdirbuf, directory), "*"); + } + + if (sizeof(TCHAR) != sizeof(char)) { + TCHAR *wdir = NULL; + /* len_0 denotes string length *with* trailing 0 */ + size_t index = 0, len_0 = strlen(extdir) + 1; + + wdir = (TCHAR *)calloc(len_0, sizeof(TCHAR)); + if (wdir == NULL) { + if (extdirbuf != NULL) { + free(extdirbuf); + } + free(*ctx); + *ctx = NULL; + errno = ENOMEM; + return 0; + } +#ifdef LP_MULTIBYTE_AVAILABLE + if (!MultiByteToWideChar + (CP_ACP, 0, extdir, len_0, (WCHAR *)wdir, len_0)) +#endif + for (index = 0; index < len_0; index++) + wdir[index] = (TCHAR)extdir[index]; + + (*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx); + + free(wdir); + } else { + (*ctx)->handle = FindFirstFile((TCHAR *)extdir, &(*ctx)->ctx); + } + if (extdirbuf != NULL) { + free(extdirbuf); + } + + if ((*ctx)->handle == INVALID_HANDLE_VALUE) { + free(*ctx); + *ctx = NULL; + errno = EINVAL; + return 0; + } + } else { + if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE) { + return 0; + } + } + if (sizeof(TCHAR) != sizeof(char)) { + TCHAR *wdir = (*ctx)->ctx.cFileName; + size_t index, len_0 = 0; + + while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1)) + len_0++; + len_0++; + +#ifdef LP_MULTIBYTE_AVAILABLE + if (!WideCharToMultiByte + (CP_ACP, 0, (WCHAR *)wdir, len_0, (*ctx)->entry_name, + sizeof((*ctx)->entry_name), NULL, 0)) +#endif + for (index = 0; index < len_0; index++) + (*ctx)->entry_name[index] = (char)wdir[index]; + } else + strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName, + sizeof((*ctx)->entry_name) - 1); + + (*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0'; + + return (*ctx)->entry_name; +} + +int LP_find_file_end(LP_DIR_CTX **ctx) +{ + if (ctx != NULL && *ctx != NULL) { + FindClose((*ctx)->handle); + free(*ctx); + *ctx = NULL; + return 1; + } + errno = EINVAL; + return 0; +} diff --git a/libs/openssl/crypto/LPdir_win32.c b/libs/openssl/crypto/LPdir_win32.c new file mode 100644 index 00000000..b1c983d8 --- /dev/null +++ b/libs/openssl/crypto/LPdir_win32.c @@ -0,0 +1,33 @@ +/* + * $LP: LPlib/source/LPdir_win32.c,v 1.3 2004/08/26 13:36:05 _cvs_levitte Exp + * $ + */ +/* + * Copyright (c) 2004, Richard Levitte + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define LP_SYS_WIN32 +#define LP_MULTIBYTE_AVAILABLE +#include "LPdir_win.c" diff --git a/libs/openssl/crypto/LPdir_wince.c b/libs/openssl/crypto/LPdir_wince.c new file mode 100644 index 00000000..ae8a56f4 --- /dev/null +++ b/libs/openssl/crypto/LPdir_wince.c @@ -0,0 +1,36 @@ +/* + * $LP: LPlib/source/LPdir_wince.c,v 1.3 2004/08/26 13:36:05 _cvs_levitte Exp + * $ + */ +/* + * Copyright (c) 2004, Richard Levitte + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define LP_SYS_WINCE +/* + * We might want to define LP_MULTIBYTE_AVAILABLE here. It's currently under + * investigation what the exact conditions would be + */ +#include "LPdir_win.c" diff --git a/libs/openssl/crypto/aes/README b/libs/openssl/crypto/aes/README new file mode 100644 index 00000000..0f9620a8 --- /dev/null +++ b/libs/openssl/crypto/aes/README @@ -0,0 +1,3 @@ +This is an OpenSSL-compatible version of AES (also called Rijndael). +aes_core.c is basically the same as rijndael-alg-fst.c but with an +API that looks like the rest of the OpenSSL symmetric cipher suite. diff --git a/libs/openssl/crypto/aes/aes.h b/libs/openssl/crypto/aes/aes.h new file mode 100644 index 00000000..faa66c49 --- /dev/null +++ b/libs/openssl/crypto/aes/aes.h @@ -0,0 +1,149 @@ +/* crypto/aes/aes.h */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef HEADER_AES_H +# define HEADER_AES_H + +# include + +# ifdef OPENSSL_NO_AES +# error AES is disabled. +# endif + +# include + +# define AES_ENCRYPT 1 +# define AES_DECRYPT 0 + +/* + * Because array size can't be a const in C, the following two are macros. + * Both sizes are in bytes. + */ +# define AES_MAXNR 14 +# define AES_BLOCK_SIZE 16 + +#ifdef __cplusplus +extern "C" { +#endif + +/* This should be a hidden type, but EVP requires that the size be known */ +struct aes_key_st { +# ifdef AES_LONG + unsigned long rd_key[4 * (AES_MAXNR + 1)]; +# else + unsigned int rd_key[4 * (AES_MAXNR + 1)]; +# endif + int rounds; +}; +typedef struct aes_key_st AES_KEY; + +const char *AES_options(void); + +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); + +int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); +int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key); + +void AES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void AES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key, const int enc); +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc); +void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc); +void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num); +void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char ivec[AES_BLOCK_SIZE], + unsigned char ecount_buf[AES_BLOCK_SIZE], + unsigned int *num); +/* NB: the IV is _two_ blocks long */ +void AES_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc); +/* NB: the IV is _four_ blocks long */ +void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + const AES_KEY *key2, const unsigned char *ivec, + const int enc); + +int AES_wrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen); +int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen); + + +#ifdef __cplusplus +} +#endif + +#endif /* !HEADER_AES_H */ diff --git a/libs/openssl/crypto/aes/aes_cbc.c b/libs/openssl/crypto/aes/aes_cbc.c new file mode 100644 index 00000000..805d0e26 --- /dev/null +++ b/libs/openssl/crypto/aes/aes_cbc.c @@ -0,0 +1,66 @@ +/* crypto/aes/aes_cbc.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include + +void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + unsigned char *ivec, const int enc) +{ + + if (enc) + CRYPTO_cbc128_encrypt(in, out, len, key, ivec, + (block128_f) AES_encrypt); + else + CRYPTO_cbc128_decrypt(in, out, len, key, ivec, + (block128_f) AES_decrypt); +} diff --git a/libs/openssl/crypto/aes/aes_cfb.c b/libs/openssl/crypto/aes/aes_cfb.c new file mode 100644 index 00000000..12250009 --- /dev/null +++ b/libs/openssl/crypto/aes/aes_cfb.c @@ -0,0 +1,85 @@ +/* crypto/aes/aes_cfb.c */ +/* ==================================================================== + * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include + +/* + * The input and output encrypted as though 128bit cfb mode is being used. + * The extra state information to record how much of the 128bit block we have + * used is contained in *num; + */ + +void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc) +{ + + CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, + (block128_f) AES_encrypt); +} + +/* N.B. This expects the input to be packed, MS bit first */ +void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc) +{ + CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc, + (block128_f) AES_encrypt); +} + +void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num, const int enc) +{ + CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc, + (block128_f) AES_encrypt); +} diff --git a/libs/openssl/crypto/aes/aes_core.c b/libs/openssl/crypto/aes/aes_core.c new file mode 100644 index 00000000..7019b5d7 --- /dev/null +++ b/libs/openssl/crypto/aes/aes_core.c @@ -0,0 +1,1363 @@ +/* crypto/aes/aes_core.c */ +/** + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* Note: rewritten a little bit to provide error control and an OpenSSL- + compatible API */ + +#ifndef AES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +#include +#include +#include "aes_locl.h" + +#ifndef AES_ASM +/*- +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; + +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01]; +*/ + +static const u32 Te0[256] = { + 0xc66363a5U, 0xf87c7c84U, 0xee777799U, 0xf67b7b8dU, + 0xfff2f20dU, 0xd66b6bbdU, 0xde6f6fb1U, 0x91c5c554U, + 0x60303050U, 0x02010103U, 0xce6767a9U, 0x562b2b7dU, + 0xe7fefe19U, 0xb5d7d762U, 0x4dababe6U, 0xec76769aU, + 0x8fcaca45U, 0x1f82829dU, 0x89c9c940U, 0xfa7d7d87U, + 0xeffafa15U, 0xb25959ebU, 0x8e4747c9U, 0xfbf0f00bU, + 0x41adadecU, 0xb3d4d467U, 0x5fa2a2fdU, 0x45afafeaU, + 0x239c9cbfU, 0x53a4a4f7U, 0xe4727296U, 0x9bc0c05bU, + 0x75b7b7c2U, 0xe1fdfd1cU, 0x3d9393aeU, 0x4c26266aU, + 0x6c36365aU, 0x7e3f3f41U, 0xf5f7f702U, 0x83cccc4fU, + 0x6834345cU, 0x51a5a5f4U, 0xd1e5e534U, 0xf9f1f108U, + 0xe2717193U, 0xabd8d873U, 0x62313153U, 0x2a15153fU, + 0x0804040cU, 0x95c7c752U, 0x46232365U, 0x9dc3c35eU, + 0x30181828U, 0x379696a1U, 0x0a05050fU, 0x2f9a9ab5U, + 0x0e070709U, 0x24121236U, 0x1b80809bU, 0xdfe2e23dU, + 0xcdebeb26U, 0x4e272769U, 0x7fb2b2cdU, 0xea75759fU, + 0x1209091bU, 0x1d83839eU, 0x582c2c74U, 0x341a1a2eU, + 0x361b1b2dU, 0xdc6e6eb2U, 0xb45a5aeeU, 0x5ba0a0fbU, + 0xa45252f6U, 0x763b3b4dU, 0xb7d6d661U, 0x7db3b3ceU, + 0x5229297bU, 0xdde3e33eU, 0x5e2f2f71U, 0x13848497U, + 0xa65353f5U, 0xb9d1d168U, 0x00000000U, 0xc1eded2cU, + 0x40202060U, 0xe3fcfc1fU, 0x79b1b1c8U, 0xb65b5bedU, + 0xd46a6abeU, 0x8dcbcb46U, 0x67bebed9U, 0x7239394bU, + 0x944a4adeU, 0x984c4cd4U, 0xb05858e8U, 0x85cfcf4aU, + 0xbbd0d06bU, 0xc5efef2aU, 0x4faaaae5U, 0xedfbfb16U, + 0x864343c5U, 0x9a4d4dd7U, 0x66333355U, 0x11858594U, + 0x8a4545cfU, 0xe9f9f910U, 0x04020206U, 0xfe7f7f81U, + 0xa05050f0U, 0x783c3c44U, 0x259f9fbaU, 0x4ba8a8e3U, + 0xa25151f3U, 0x5da3a3feU, 0x804040c0U, 0x058f8f8aU, + 0x3f9292adU, 0x219d9dbcU, 0x70383848U, 0xf1f5f504U, + 0x63bcbcdfU, 0x77b6b6c1U, 0xafdada75U, 0x42212163U, + 0x20101030U, 0xe5ffff1aU, 0xfdf3f30eU, 0xbfd2d26dU, + 0x81cdcd4cU, 0x180c0c14U, 0x26131335U, 0xc3ecec2fU, + 0xbe5f5fe1U, 0x359797a2U, 0x884444ccU, 0x2e171739U, + 0x93c4c457U, 0x55a7a7f2U, 0xfc7e7e82U, 0x7a3d3d47U, + 0xc86464acU, 0xba5d5de7U, 0x3219192bU, 0xe6737395U, + 0xc06060a0U, 0x19818198U, 0x9e4f4fd1U, 0xa3dcdc7fU, + 0x44222266U, 0x542a2a7eU, 0x3b9090abU, 0x0b888883U, + 0x8c4646caU, 0xc7eeee29U, 0x6bb8b8d3U, 0x2814143cU, + 0xa7dede79U, 0xbc5e5ee2U, 0x160b0b1dU, 0xaddbdb76U, + 0xdbe0e03bU, 0x64323256U, 0x743a3a4eU, 0x140a0a1eU, + 0x924949dbU, 0x0c06060aU, 0x4824246cU, 0xb85c5ce4U, + 0x9fc2c25dU, 0xbdd3d36eU, 0x43acacefU, 0xc46262a6U, + 0x399191a8U, 0x319595a4U, 0xd3e4e437U, 0xf279798bU, + 0xd5e7e732U, 0x8bc8c843U, 0x6e373759U, 0xda6d6db7U, + 0x018d8d8cU, 0xb1d5d564U, 0x9c4e4ed2U, 0x49a9a9e0U, + 0xd86c6cb4U, 0xac5656faU, 0xf3f4f407U, 0xcfeaea25U, + 0xca6565afU, 0xf47a7a8eU, 0x47aeaee9U, 0x10080818U, + 0x6fbabad5U, 0xf0787888U, 0x4a25256fU, 0x5c2e2e72U, + 0x381c1c24U, 0x57a6a6f1U, 0x73b4b4c7U, 0x97c6c651U, + 0xcbe8e823U, 0xa1dddd7cU, 0xe874749cU, 0x3e1f1f21U, + 0x964b4bddU, 0x61bdbddcU, 0x0d8b8b86U, 0x0f8a8a85U, + 0xe0707090U, 0x7c3e3e42U, 0x71b5b5c4U, 0xcc6666aaU, + 0x904848d8U, 0x06030305U, 0xf7f6f601U, 0x1c0e0e12U, + 0xc26161a3U, 0x6a35355fU, 0xae5757f9U, 0x69b9b9d0U, + 0x17868691U, 0x99c1c158U, 0x3a1d1d27U, 0x279e9eb9U, + 0xd9e1e138U, 0xebf8f813U, 0x2b9898b3U, 0x22111133U, + 0xd26969bbU, 0xa9d9d970U, 0x078e8e89U, 0x339494a7U, + 0x2d9b9bb6U, 0x3c1e1e22U, 0x15878792U, 0xc9e9e920U, + 0x87cece49U, 0xaa5555ffU, 0x50282878U, 0xa5dfdf7aU, + 0x038c8c8fU, 0x59a1a1f8U, 0x09898980U, 0x1a0d0d17U, + 0x65bfbfdaU, 0xd7e6e631U, 0x844242c6U, 0xd06868b8U, + 0x824141c3U, 0x299999b0U, 0x5a2d2d77U, 0x1e0f0f11U, + 0x7bb0b0cbU, 0xa85454fcU, 0x6dbbbbd6U, 0x2c16163aU, +}; +static const u32 Te1[256] = { + 0xa5c66363U, 0x84f87c7cU, 0x99ee7777U, 0x8df67b7bU, + 0x0dfff2f2U, 0xbdd66b6bU, 0xb1de6f6fU, 0x5491c5c5U, + 0x50603030U, 0x03020101U, 0xa9ce6767U, 0x7d562b2bU, + 0x19e7fefeU, 0x62b5d7d7U, 0xe64dababU, 0x9aec7676U, + 0x458fcacaU, 0x9d1f8282U, 0x4089c9c9U, 0x87fa7d7dU, + 0x15effafaU, 0xebb25959U, 0xc98e4747U, 0x0bfbf0f0U, + 0xec41adadU, 0x67b3d4d4U, 0xfd5fa2a2U, 0xea45afafU, + 0xbf239c9cU, 0xf753a4a4U, 0x96e47272U, 0x5b9bc0c0U, + 0xc275b7b7U, 0x1ce1fdfdU, 0xae3d9393U, 0x6a4c2626U, + 0x5a6c3636U, 0x417e3f3fU, 0x02f5f7f7U, 0x4f83ccccU, + 0x5c683434U, 0xf451a5a5U, 0x34d1e5e5U, 0x08f9f1f1U, + 0x93e27171U, 0x73abd8d8U, 0x53623131U, 0x3f2a1515U, + 0x0c080404U, 0x5295c7c7U, 0x65462323U, 0x5e9dc3c3U, + 0x28301818U, 0xa1379696U, 0x0f0a0505U, 0xb52f9a9aU, + 0x090e0707U, 0x36241212U, 0x9b1b8080U, 0x3ddfe2e2U, + 0x26cdebebU, 0x694e2727U, 0xcd7fb2b2U, 0x9fea7575U, + 0x1b120909U, 0x9e1d8383U, 0x74582c2cU, 0x2e341a1aU, + 0x2d361b1bU, 0xb2dc6e6eU, 0xeeb45a5aU, 0xfb5ba0a0U, + 0xf6a45252U, 0x4d763b3bU, 0x61b7d6d6U, 0xce7db3b3U, + 0x7b522929U, 0x3edde3e3U, 0x715e2f2fU, 0x97138484U, + 0xf5a65353U, 0x68b9d1d1U, 0x00000000U, 0x2cc1ededU, + 0x60402020U, 0x1fe3fcfcU, 0xc879b1b1U, 0xedb65b5bU, + 0xbed46a6aU, 0x468dcbcbU, 0xd967bebeU, 0x4b723939U, + 0xde944a4aU, 0xd4984c4cU, 0xe8b05858U, 0x4a85cfcfU, + 0x6bbbd0d0U, 0x2ac5efefU, 0xe54faaaaU, 0x16edfbfbU, + 0xc5864343U, 0xd79a4d4dU, 0x55663333U, 0x94118585U, + 0xcf8a4545U, 0x10e9f9f9U, 0x06040202U, 0x81fe7f7fU, + 0xf0a05050U, 0x44783c3cU, 0xba259f9fU, 0xe34ba8a8U, + 0xf3a25151U, 0xfe5da3a3U, 0xc0804040U, 0x8a058f8fU, + 0xad3f9292U, 0xbc219d9dU, 0x48703838U, 0x04f1f5f5U, + 0xdf63bcbcU, 0xc177b6b6U, 0x75afdadaU, 0x63422121U, + 0x30201010U, 0x1ae5ffffU, 0x0efdf3f3U, 0x6dbfd2d2U, + 0x4c81cdcdU, 0x14180c0cU, 0x35261313U, 0x2fc3ececU, + 0xe1be5f5fU, 0xa2359797U, 0xcc884444U, 0x392e1717U, + 0x5793c4c4U, 0xf255a7a7U, 0x82fc7e7eU, 0x477a3d3dU, + 0xacc86464U, 0xe7ba5d5dU, 0x2b321919U, 0x95e67373U, + 0xa0c06060U, 0x98198181U, 0xd19e4f4fU, 0x7fa3dcdcU, + 0x66442222U, 0x7e542a2aU, 0xab3b9090U, 0x830b8888U, + 0xca8c4646U, 0x29c7eeeeU, 0xd36bb8b8U, 0x3c281414U, + 0x79a7dedeU, 0xe2bc5e5eU, 0x1d160b0bU, 0x76addbdbU, + 0x3bdbe0e0U, 0x56643232U, 0x4e743a3aU, 0x1e140a0aU, + 0xdb924949U, 0x0a0c0606U, 0x6c482424U, 0xe4b85c5cU, + 0x5d9fc2c2U, 0x6ebdd3d3U, 0xef43acacU, 0xa6c46262U, + 0xa8399191U, 0xa4319595U, 0x37d3e4e4U, 0x8bf27979U, + 0x32d5e7e7U, 0x438bc8c8U, 0x596e3737U, 0xb7da6d6dU, + 0x8c018d8dU, 0x64b1d5d5U, 0xd29c4e4eU, 0xe049a9a9U, + 0xb4d86c6cU, 0xfaac5656U, 0x07f3f4f4U, 0x25cfeaeaU, + 0xafca6565U, 0x8ef47a7aU, 0xe947aeaeU, 0x18100808U, + 0xd56fbabaU, 0x88f07878U, 0x6f4a2525U, 0x725c2e2eU, + 0x24381c1cU, 0xf157a6a6U, 0xc773b4b4U, 0x5197c6c6U, + 0x23cbe8e8U, 0x7ca1ddddU, 0x9ce87474U, 0x213e1f1fU, + 0xdd964b4bU, 0xdc61bdbdU, 0x860d8b8bU, 0x850f8a8aU, + 0x90e07070U, 0x427c3e3eU, 0xc471b5b5U, 0xaacc6666U, + 0xd8904848U, 0x05060303U, 0x01f7f6f6U, 0x121c0e0eU, + 0xa3c26161U, 0x5f6a3535U, 0xf9ae5757U, 0xd069b9b9U, + 0x91178686U, 0x5899c1c1U, 0x273a1d1dU, 0xb9279e9eU, + 0x38d9e1e1U, 0x13ebf8f8U, 0xb32b9898U, 0x33221111U, + 0xbbd26969U, 0x70a9d9d9U, 0x89078e8eU, 0xa7339494U, + 0xb62d9b9bU, 0x223c1e1eU, 0x92158787U, 0x20c9e9e9U, + 0x4987ceceU, 0xffaa5555U, 0x78502828U, 0x7aa5dfdfU, + 0x8f038c8cU, 0xf859a1a1U, 0x80098989U, 0x171a0d0dU, + 0xda65bfbfU, 0x31d7e6e6U, 0xc6844242U, 0xb8d06868U, + 0xc3824141U, 0xb0299999U, 0x775a2d2dU, 0x111e0f0fU, + 0xcb7bb0b0U, 0xfca85454U, 0xd66dbbbbU, 0x3a2c1616U, +}; +static const u32 Te2[256] = { + 0x63a5c663U, 0x7c84f87cU, 0x7799ee77U, 0x7b8df67bU, + 0xf20dfff2U, 0x6bbdd66bU, 0x6fb1de6fU, 0xc55491c5U, + 0x30506030U, 0x01030201U, 0x67a9ce67U, 0x2b7d562bU, + 0xfe19e7feU, 0xd762b5d7U, 0xabe64dabU, 0x769aec76U, + 0xca458fcaU, 0x829d1f82U, 0xc94089c9U, 0x7d87fa7dU, + 0xfa15effaU, 0x59ebb259U, 0x47c98e47U, 0xf00bfbf0U, + 0xadec41adU, 0xd467b3d4U, 0xa2fd5fa2U, 0xafea45afU, + 0x9cbf239cU, 0xa4f753a4U, 0x7296e472U, 0xc05b9bc0U, + 0xb7c275b7U, 0xfd1ce1fdU, 0x93ae3d93U, 0x266a4c26U, + 0x365a6c36U, 0x3f417e3fU, 0xf702f5f7U, 0xcc4f83ccU, + 0x345c6834U, 0xa5f451a5U, 0xe534d1e5U, 0xf108f9f1U, + 0x7193e271U, 0xd873abd8U, 0x31536231U, 0x153f2a15U, + 0x040c0804U, 0xc75295c7U, 0x23654623U, 0xc35e9dc3U, + 0x18283018U, 0x96a13796U, 0x050f0a05U, 0x9ab52f9aU, + 0x07090e07U, 0x12362412U, 0x809b1b80U, 0xe23ddfe2U, + 0xeb26cdebU, 0x27694e27U, 0xb2cd7fb2U, 0x759fea75U, + 0x091b1209U, 0x839e1d83U, 0x2c74582cU, 0x1a2e341aU, + 0x1b2d361bU, 0x6eb2dc6eU, 0x5aeeb45aU, 0xa0fb5ba0U, + 0x52f6a452U, 0x3b4d763bU, 0xd661b7d6U, 0xb3ce7db3U, + 0x297b5229U, 0xe33edde3U, 0x2f715e2fU, 0x84971384U, + 0x53f5a653U, 0xd168b9d1U, 0x00000000U, 0xed2cc1edU, + 0x20604020U, 0xfc1fe3fcU, 0xb1c879b1U, 0x5bedb65bU, + 0x6abed46aU, 0xcb468dcbU, 0xbed967beU, 0x394b7239U, + 0x4ade944aU, 0x4cd4984cU, 0x58e8b058U, 0xcf4a85cfU, + 0xd06bbbd0U, 0xef2ac5efU, 0xaae54faaU, 0xfb16edfbU, + 0x43c58643U, 0x4dd79a4dU, 0x33556633U, 0x85941185U, + 0x45cf8a45U, 0xf910e9f9U, 0x02060402U, 0x7f81fe7fU, + 0x50f0a050U, 0x3c44783cU, 0x9fba259fU, 0xa8e34ba8U, + 0x51f3a251U, 0xa3fe5da3U, 0x40c08040U, 0x8f8a058fU, + 0x92ad3f92U, 0x9dbc219dU, 0x38487038U, 0xf504f1f5U, + 0xbcdf63bcU, 0xb6c177b6U, 0xda75afdaU, 0x21634221U, + 0x10302010U, 0xff1ae5ffU, 0xf30efdf3U, 0xd26dbfd2U, + 0xcd4c81cdU, 0x0c14180cU, 0x13352613U, 0xec2fc3ecU, + 0x5fe1be5fU, 0x97a23597U, 0x44cc8844U, 0x17392e17U, + 0xc45793c4U, 0xa7f255a7U, 0x7e82fc7eU, 0x3d477a3dU, + 0x64acc864U, 0x5de7ba5dU, 0x192b3219U, 0x7395e673U, + 0x60a0c060U, 0x81981981U, 0x4fd19e4fU, 0xdc7fa3dcU, + 0x22664422U, 0x2a7e542aU, 0x90ab3b90U, 0x88830b88U, + 0x46ca8c46U, 0xee29c7eeU, 0xb8d36bb8U, 0x143c2814U, + 0xde79a7deU, 0x5ee2bc5eU, 0x0b1d160bU, 0xdb76addbU, + 0xe03bdbe0U, 0x32566432U, 0x3a4e743aU, 0x0a1e140aU, + 0x49db9249U, 0x060a0c06U, 0x246c4824U, 0x5ce4b85cU, + 0xc25d9fc2U, 0xd36ebdd3U, 0xacef43acU, 0x62a6c462U, + 0x91a83991U, 0x95a43195U, 0xe437d3e4U, 0x798bf279U, + 0xe732d5e7U, 0xc8438bc8U, 0x37596e37U, 0x6db7da6dU, + 0x8d8c018dU, 0xd564b1d5U, 0x4ed29c4eU, 0xa9e049a9U, + 0x6cb4d86cU, 0x56faac56U, 0xf407f3f4U, 0xea25cfeaU, + 0x65afca65U, 0x7a8ef47aU, 0xaee947aeU, 0x08181008U, + 0xbad56fbaU, 0x7888f078U, 0x256f4a25U, 0x2e725c2eU, + 0x1c24381cU, 0xa6f157a6U, 0xb4c773b4U, 0xc65197c6U, + 0xe823cbe8U, 0xdd7ca1ddU, 0x749ce874U, 0x1f213e1fU, + 0x4bdd964bU, 0xbddc61bdU, 0x8b860d8bU, 0x8a850f8aU, + 0x7090e070U, 0x3e427c3eU, 0xb5c471b5U, 0x66aacc66U, + 0x48d89048U, 0x03050603U, 0xf601f7f6U, 0x0e121c0eU, + 0x61a3c261U, 0x355f6a35U, 0x57f9ae57U, 0xb9d069b9U, + 0x86911786U, 0xc15899c1U, 0x1d273a1dU, 0x9eb9279eU, + 0xe138d9e1U, 0xf813ebf8U, 0x98b32b98U, 0x11332211U, + 0x69bbd269U, 0xd970a9d9U, 0x8e89078eU, 0x94a73394U, + 0x9bb62d9bU, 0x1e223c1eU, 0x87921587U, 0xe920c9e9U, + 0xce4987ceU, 0x55ffaa55U, 0x28785028U, 0xdf7aa5dfU, + 0x8c8f038cU, 0xa1f859a1U, 0x89800989U, 0x0d171a0dU, + 0xbfda65bfU, 0xe631d7e6U, 0x42c68442U, 0x68b8d068U, + 0x41c38241U, 0x99b02999U, 0x2d775a2dU, 0x0f111e0fU, + 0xb0cb7bb0U, 0x54fca854U, 0xbbd66dbbU, 0x163a2c16U, +}; +static const u32 Te3[256] = { + 0x6363a5c6U, 0x7c7c84f8U, 0x777799eeU, 0x7b7b8df6U, + 0xf2f20dffU, 0x6b6bbdd6U, 0x6f6fb1deU, 0xc5c55491U, + 0x30305060U, 0x01010302U, 0x6767a9ceU, 0x2b2b7d56U, + 0xfefe19e7U, 0xd7d762b5U, 0xababe64dU, 0x76769aecU, + 0xcaca458fU, 0x82829d1fU, 0xc9c94089U, 0x7d7d87faU, + 0xfafa15efU, 0x5959ebb2U, 0x4747c98eU, 0xf0f00bfbU, + 0xadadec41U, 0xd4d467b3U, 0xa2a2fd5fU, 0xafafea45U, + 0x9c9cbf23U, 0xa4a4f753U, 0x727296e4U, 0xc0c05b9bU, + 0xb7b7c275U, 0xfdfd1ce1U, 0x9393ae3dU, 0x26266a4cU, + 0x36365a6cU, 0x3f3f417eU, 0xf7f702f5U, 0xcccc4f83U, + 0x34345c68U, 0xa5a5f451U, 0xe5e534d1U, 0xf1f108f9U, + 0x717193e2U, 0xd8d873abU, 0x31315362U, 0x15153f2aU, + 0x04040c08U, 0xc7c75295U, 0x23236546U, 0xc3c35e9dU, + 0x18182830U, 0x9696a137U, 0x05050f0aU, 0x9a9ab52fU, + 0x0707090eU, 0x12123624U, 0x80809b1bU, 0xe2e23ddfU, + 0xebeb26cdU, 0x2727694eU, 0xb2b2cd7fU, 0x75759feaU, + 0x09091b12U, 0x83839e1dU, 0x2c2c7458U, 0x1a1a2e34U, + 0x1b1b2d36U, 0x6e6eb2dcU, 0x5a5aeeb4U, 0xa0a0fb5bU, + 0x5252f6a4U, 0x3b3b4d76U, 0xd6d661b7U, 0xb3b3ce7dU, + 0x29297b52U, 0xe3e33eddU, 0x2f2f715eU, 0x84849713U, + 0x5353f5a6U, 0xd1d168b9U, 0x00000000U, 0xeded2cc1U, + 0x20206040U, 0xfcfc1fe3U, 0xb1b1c879U, 0x5b5bedb6U, + 0x6a6abed4U, 0xcbcb468dU, 0xbebed967U, 0x39394b72U, + 0x4a4ade94U, 0x4c4cd498U, 0x5858e8b0U, 0xcfcf4a85U, + 0xd0d06bbbU, 0xefef2ac5U, 0xaaaae54fU, 0xfbfb16edU, + 0x4343c586U, 0x4d4dd79aU, 0x33335566U, 0x85859411U, + 0x4545cf8aU, 0xf9f910e9U, 0x02020604U, 0x7f7f81feU, + 0x5050f0a0U, 0x3c3c4478U, 0x9f9fba25U, 0xa8a8e34bU, + 0x5151f3a2U, 0xa3a3fe5dU, 0x4040c080U, 0x8f8f8a05U, + 0x9292ad3fU, 0x9d9dbc21U, 0x38384870U, 0xf5f504f1U, + 0xbcbcdf63U, 0xb6b6c177U, 0xdada75afU, 0x21216342U, + 0x10103020U, 0xffff1ae5U, 0xf3f30efdU, 0xd2d26dbfU, + 0xcdcd4c81U, 0x0c0c1418U, 0x13133526U, 0xecec2fc3U, + 0x5f5fe1beU, 0x9797a235U, 0x4444cc88U, 0x1717392eU, + 0xc4c45793U, 0xa7a7f255U, 0x7e7e82fcU, 0x3d3d477aU, + 0x6464acc8U, 0x5d5de7baU, 0x19192b32U, 0x737395e6U, + 0x6060a0c0U, 0x81819819U, 0x4f4fd19eU, 0xdcdc7fa3U, + 0x22226644U, 0x2a2a7e54U, 0x9090ab3bU, 0x8888830bU, + 0x4646ca8cU, 0xeeee29c7U, 0xb8b8d36bU, 0x14143c28U, + 0xdede79a7U, 0x5e5ee2bcU, 0x0b0b1d16U, 0xdbdb76adU, + 0xe0e03bdbU, 0x32325664U, 0x3a3a4e74U, 0x0a0a1e14U, + 0x4949db92U, 0x06060a0cU, 0x24246c48U, 0x5c5ce4b8U, + 0xc2c25d9fU, 0xd3d36ebdU, 0xacacef43U, 0x6262a6c4U, + 0x9191a839U, 0x9595a431U, 0xe4e437d3U, 0x79798bf2U, + 0xe7e732d5U, 0xc8c8438bU, 0x3737596eU, 0x6d6db7daU, + 0x8d8d8c01U, 0xd5d564b1U, 0x4e4ed29cU, 0xa9a9e049U, + 0x6c6cb4d8U, 0x5656faacU, 0xf4f407f3U, 0xeaea25cfU, + 0x6565afcaU, 0x7a7a8ef4U, 0xaeaee947U, 0x08081810U, + 0xbabad56fU, 0x787888f0U, 0x25256f4aU, 0x2e2e725cU, + 0x1c1c2438U, 0xa6a6f157U, 0xb4b4c773U, 0xc6c65197U, + 0xe8e823cbU, 0xdddd7ca1U, 0x74749ce8U, 0x1f1f213eU, + 0x4b4bdd96U, 0xbdbddc61U, 0x8b8b860dU, 0x8a8a850fU, + 0x707090e0U, 0x3e3e427cU, 0xb5b5c471U, 0x6666aaccU, + 0x4848d890U, 0x03030506U, 0xf6f601f7U, 0x0e0e121cU, + 0x6161a3c2U, 0x35355f6aU, 0x5757f9aeU, 0xb9b9d069U, + 0x86869117U, 0xc1c15899U, 0x1d1d273aU, 0x9e9eb927U, + 0xe1e138d9U, 0xf8f813ebU, 0x9898b32bU, 0x11113322U, + 0x6969bbd2U, 0xd9d970a9U, 0x8e8e8907U, 0x9494a733U, + 0x9b9bb62dU, 0x1e1e223cU, 0x87879215U, 0xe9e920c9U, + 0xcece4987U, 0x5555ffaaU, 0x28287850U, 0xdfdf7aa5U, + 0x8c8c8f03U, 0xa1a1f859U, 0x89898009U, 0x0d0d171aU, + 0xbfbfda65U, 0xe6e631d7U, 0x4242c684U, 0x6868b8d0U, + 0x4141c382U, 0x9999b029U, 0x2d2d775aU, 0x0f0f111eU, + 0xb0b0cb7bU, 0x5454fca8U, 0xbbbbd66dU, 0x16163a2cU, +}; + +static const u32 Td0[256] = { + 0x51f4a750U, 0x7e416553U, 0x1a17a4c3U, 0x3a275e96U, + 0x3bab6bcbU, 0x1f9d45f1U, 0xacfa58abU, 0x4be30393U, + 0x2030fa55U, 0xad766df6U, 0x88cc7691U, 0xf5024c25U, + 0x4fe5d7fcU, 0xc52acbd7U, 0x26354480U, 0xb562a38fU, + 0xdeb15a49U, 0x25ba1b67U, 0x45ea0e98U, 0x5dfec0e1U, + 0xc32f7502U, 0x814cf012U, 0x8d4697a3U, 0x6bd3f9c6U, + 0x038f5fe7U, 0x15929c95U, 0xbf6d7aebU, 0x955259daU, + 0xd4be832dU, 0x587421d3U, 0x49e06929U, 0x8ec9c844U, + 0x75c2896aU, 0xf48e7978U, 0x99583e6bU, 0x27b971ddU, + 0xbee14fb6U, 0xf088ad17U, 0xc920ac66U, 0x7dce3ab4U, + 0x63df4a18U, 0xe51a3182U, 0x97513360U, 0x62537f45U, + 0xb16477e0U, 0xbb6bae84U, 0xfe81a01cU, 0xf9082b94U, + 0x70486858U, 0x8f45fd19U, 0x94de6c87U, 0x527bf8b7U, + 0xab73d323U, 0x724b02e2U, 0xe31f8f57U, 0x6655ab2aU, + 0xb2eb2807U, 0x2fb5c203U, 0x86c57b9aU, 0xd33708a5U, + 0x302887f2U, 0x23bfa5b2U, 0x02036abaU, 0xed16825cU, + 0x8acf1c2bU, 0xa779b492U, 0xf307f2f0U, 0x4e69e2a1U, + 0x65daf4cdU, 0x0605bed5U, 0xd134621fU, 0xc4a6fe8aU, + 0x342e539dU, 0xa2f355a0U, 0x058ae132U, 0xa4f6eb75U, + 0x0b83ec39U, 0x4060efaaU, 0x5e719f06U, 0xbd6e1051U, + 0x3e218af9U, 0x96dd063dU, 0xdd3e05aeU, 0x4de6bd46U, + 0x91548db5U, 0x71c45d05U, 0x0406d46fU, 0x605015ffU, + 0x1998fb24U, 0xd6bde997U, 0x894043ccU, 0x67d99e77U, + 0xb0e842bdU, 0x07898b88U, 0xe7195b38U, 0x79c8eedbU, + 0xa17c0a47U, 0x7c420fe9U, 0xf8841ec9U, 0x00000000U, + 0x09808683U, 0x322bed48U, 0x1e1170acU, 0x6c5a724eU, + 0xfd0efffbU, 0x0f853856U, 0x3daed51eU, 0x362d3927U, + 0x0a0fd964U, 0x685ca621U, 0x9b5b54d1U, 0x24362e3aU, + 0x0c0a67b1U, 0x9357e70fU, 0xb4ee96d2U, 0x1b9b919eU, + 0x80c0c54fU, 0x61dc20a2U, 0x5a774b69U, 0x1c121a16U, + 0xe293ba0aU, 0xc0a02ae5U, 0x3c22e043U, 0x121b171dU, + 0x0e090d0bU, 0xf28bc7adU, 0x2db6a8b9U, 0x141ea9c8U, + 0x57f11985U, 0xaf75074cU, 0xee99ddbbU, 0xa37f60fdU, + 0xf701269fU, 0x5c72f5bcU, 0x44663bc5U, 0x5bfb7e34U, + 0x8b432976U, 0xcb23c6dcU, 0xb6edfc68U, 0xb8e4f163U, + 0xd731dccaU, 0x42638510U, 0x13972240U, 0x84c61120U, + 0x854a247dU, 0xd2bb3df8U, 0xaef93211U, 0xc729a16dU, + 0x1d9e2f4bU, 0xdcb230f3U, 0x0d8652ecU, 0x77c1e3d0U, + 0x2bb3166cU, 0xa970b999U, 0x119448faU, 0x47e96422U, + 0xa8fc8cc4U, 0xa0f03f1aU, 0x567d2cd8U, 0x223390efU, + 0x87494ec7U, 0xd938d1c1U, 0x8ccaa2feU, 0x98d40b36U, + 0xa6f581cfU, 0xa57ade28U, 0xdab78e26U, 0x3fadbfa4U, + 0x2c3a9de4U, 0x5078920dU, 0x6a5fcc9bU, 0x547e4662U, + 0xf68d13c2U, 0x90d8b8e8U, 0x2e39f75eU, 0x82c3aff5U, + 0x9f5d80beU, 0x69d0937cU, 0x6fd52da9U, 0xcf2512b3U, + 0xc8ac993bU, 0x10187da7U, 0xe89c636eU, 0xdb3bbb7bU, + 0xcd267809U, 0x6e5918f4U, 0xec9ab701U, 0x834f9aa8U, + 0xe6956e65U, 0xaaffe67eU, 0x21bccf08U, 0xef15e8e6U, + 0xbae79bd9U, 0x4a6f36ceU, 0xea9f09d4U, 0x29b07cd6U, + 0x31a4b2afU, 0x2a3f2331U, 0xc6a59430U, 0x35a266c0U, + 0x744ebc37U, 0xfc82caa6U, 0xe090d0b0U, 0x33a7d815U, + 0xf104984aU, 0x41ecdaf7U, 0x7fcd500eU, 0x1791f62fU, + 0x764dd68dU, 0x43efb04dU, 0xccaa4d54U, 0xe49604dfU, + 0x9ed1b5e3U, 0x4c6a881bU, 0xc12c1fb8U, 0x4665517fU, + 0x9d5eea04U, 0x018c355dU, 0xfa877473U, 0xfb0b412eU, + 0xb3671d5aU, 0x92dbd252U, 0xe9105633U, 0x6dd64713U, + 0x9ad7618cU, 0x37a10c7aU, 0x59f8148eU, 0xeb133c89U, + 0xcea927eeU, 0xb761c935U, 0xe11ce5edU, 0x7a47b13cU, + 0x9cd2df59U, 0x55f2733fU, 0x1814ce79U, 0x73c737bfU, + 0x53f7cdeaU, 0x5ffdaa5bU, 0xdf3d6f14U, 0x7844db86U, + 0xcaaff381U, 0xb968c43eU, 0x3824342cU, 0xc2a3405fU, + 0x161dc372U, 0xbce2250cU, 0x283c498bU, 0xff0d9541U, + 0x39a80171U, 0x080cb3deU, 0xd8b4e49cU, 0x6456c190U, + 0x7bcb8461U, 0xd532b670U, 0x486c5c74U, 0xd0b85742U, +}; +static const u32 Td1[256] = { + 0x5051f4a7U, 0x537e4165U, 0xc31a17a4U, 0x963a275eU, + 0xcb3bab6bU, 0xf11f9d45U, 0xabacfa58U, 0x934be303U, + 0x552030faU, 0xf6ad766dU, 0x9188cc76U, 0x25f5024cU, + 0xfc4fe5d7U, 0xd7c52acbU, 0x80263544U, 0x8fb562a3U, + 0x49deb15aU, 0x6725ba1bU, 0x9845ea0eU, 0xe15dfec0U, + 0x02c32f75U, 0x12814cf0U, 0xa38d4697U, 0xc66bd3f9U, + 0xe7038f5fU, 0x9515929cU, 0xebbf6d7aU, 0xda955259U, + 0x2dd4be83U, 0xd3587421U, 0x2949e069U, 0x448ec9c8U, + 0x6a75c289U, 0x78f48e79U, 0x6b99583eU, 0xdd27b971U, + 0xb6bee14fU, 0x17f088adU, 0x66c920acU, 0xb47dce3aU, + 0x1863df4aU, 0x82e51a31U, 0x60975133U, 0x4562537fU, + 0xe0b16477U, 0x84bb6baeU, 0x1cfe81a0U, 0x94f9082bU, + 0x58704868U, 0x198f45fdU, 0x8794de6cU, 0xb7527bf8U, + 0x23ab73d3U, 0xe2724b02U, 0x57e31f8fU, 0x2a6655abU, + 0x07b2eb28U, 0x032fb5c2U, 0x9a86c57bU, 0xa5d33708U, + 0xf2302887U, 0xb223bfa5U, 0xba02036aU, 0x5ced1682U, + 0x2b8acf1cU, 0x92a779b4U, 0xf0f307f2U, 0xa14e69e2U, + 0xcd65daf4U, 0xd50605beU, 0x1fd13462U, 0x8ac4a6feU, + 0x9d342e53U, 0xa0a2f355U, 0x32058ae1U, 0x75a4f6ebU, + 0x390b83ecU, 0xaa4060efU, 0x065e719fU, 0x51bd6e10U, + 0xf93e218aU, 0x3d96dd06U, 0xaedd3e05U, 0x464de6bdU, + 0xb591548dU, 0x0571c45dU, 0x6f0406d4U, 0xff605015U, + 0x241998fbU, 0x97d6bde9U, 0xcc894043U, 0x7767d99eU, + 0xbdb0e842U, 0x8807898bU, 0x38e7195bU, 0xdb79c8eeU, + 0x47a17c0aU, 0xe97c420fU, 0xc9f8841eU, 0x00000000U, + 0x83098086U, 0x48322bedU, 0xac1e1170U, 0x4e6c5a72U, + 0xfbfd0effU, 0x560f8538U, 0x1e3daed5U, 0x27362d39U, + 0x640a0fd9U, 0x21685ca6U, 0xd19b5b54U, 0x3a24362eU, + 0xb10c0a67U, 0x0f9357e7U, 0xd2b4ee96U, 0x9e1b9b91U, + 0x4f80c0c5U, 0xa261dc20U, 0x695a774bU, 0x161c121aU, + 0x0ae293baU, 0xe5c0a02aU, 0x433c22e0U, 0x1d121b17U, + 0x0b0e090dU, 0xadf28bc7U, 0xb92db6a8U, 0xc8141ea9U, + 0x8557f119U, 0x4caf7507U, 0xbbee99ddU, 0xfda37f60U, + 0x9ff70126U, 0xbc5c72f5U, 0xc544663bU, 0x345bfb7eU, + 0x768b4329U, 0xdccb23c6U, 0x68b6edfcU, 0x63b8e4f1U, + 0xcad731dcU, 0x10426385U, 0x40139722U, 0x2084c611U, + 0x7d854a24U, 0xf8d2bb3dU, 0x11aef932U, 0x6dc729a1U, + 0x4b1d9e2fU, 0xf3dcb230U, 0xec0d8652U, 0xd077c1e3U, + 0x6c2bb316U, 0x99a970b9U, 0xfa119448U, 0x2247e964U, + 0xc4a8fc8cU, 0x1aa0f03fU, 0xd8567d2cU, 0xef223390U, + 0xc787494eU, 0xc1d938d1U, 0xfe8ccaa2U, 0x3698d40bU, + 0xcfa6f581U, 0x28a57adeU, 0x26dab78eU, 0xa43fadbfU, + 0xe42c3a9dU, 0x0d507892U, 0x9b6a5fccU, 0x62547e46U, + 0xc2f68d13U, 0xe890d8b8U, 0x5e2e39f7U, 0xf582c3afU, + 0xbe9f5d80U, 0x7c69d093U, 0xa96fd52dU, 0xb3cf2512U, + 0x3bc8ac99U, 0xa710187dU, 0x6ee89c63U, 0x7bdb3bbbU, + 0x09cd2678U, 0xf46e5918U, 0x01ec9ab7U, 0xa8834f9aU, + 0x65e6956eU, 0x7eaaffe6U, 0x0821bccfU, 0xe6ef15e8U, + 0xd9bae79bU, 0xce4a6f36U, 0xd4ea9f09U, 0xd629b07cU, + 0xaf31a4b2U, 0x312a3f23U, 0x30c6a594U, 0xc035a266U, + 0x37744ebcU, 0xa6fc82caU, 0xb0e090d0U, 0x1533a7d8U, + 0x4af10498U, 0xf741ecdaU, 0x0e7fcd50U, 0x2f1791f6U, + 0x8d764dd6U, 0x4d43efb0U, 0x54ccaa4dU, 0xdfe49604U, + 0xe39ed1b5U, 0x1b4c6a88U, 0xb8c12c1fU, 0x7f466551U, + 0x049d5eeaU, 0x5d018c35U, 0x73fa8774U, 0x2efb0b41U, + 0x5ab3671dU, 0x5292dbd2U, 0x33e91056U, 0x136dd647U, + 0x8c9ad761U, 0x7a37a10cU, 0x8e59f814U, 0x89eb133cU, + 0xeecea927U, 0x35b761c9U, 0xede11ce5U, 0x3c7a47b1U, + 0x599cd2dfU, 0x3f55f273U, 0x791814ceU, 0xbf73c737U, + 0xea53f7cdU, 0x5b5ffdaaU, 0x14df3d6fU, 0x867844dbU, + 0x81caaff3U, 0x3eb968c4U, 0x2c382434U, 0x5fc2a340U, + 0x72161dc3U, 0x0cbce225U, 0x8b283c49U, 0x41ff0d95U, + 0x7139a801U, 0xde080cb3U, 0x9cd8b4e4U, 0x906456c1U, + 0x617bcb84U, 0x70d532b6U, 0x74486c5cU, 0x42d0b857U, +}; +static const u32 Td2[256] = { + 0xa75051f4U, 0x65537e41U, 0xa4c31a17U, 0x5e963a27U, + 0x6bcb3babU, 0x45f11f9dU, 0x58abacfaU, 0x03934be3U, + 0xfa552030U, 0x6df6ad76U, 0x769188ccU, 0x4c25f502U, + 0xd7fc4fe5U, 0xcbd7c52aU, 0x44802635U, 0xa38fb562U, + 0x5a49deb1U, 0x1b6725baU, 0x0e9845eaU, 0xc0e15dfeU, + 0x7502c32fU, 0xf012814cU, 0x97a38d46U, 0xf9c66bd3U, + 0x5fe7038fU, 0x9c951592U, 0x7aebbf6dU, 0x59da9552U, + 0x832dd4beU, 0x21d35874U, 0x692949e0U, 0xc8448ec9U, + 0x896a75c2U, 0x7978f48eU, 0x3e6b9958U, 0x71dd27b9U, + 0x4fb6bee1U, 0xad17f088U, 0xac66c920U, 0x3ab47dceU, + 0x4a1863dfU, 0x3182e51aU, 0x33609751U, 0x7f456253U, + 0x77e0b164U, 0xae84bb6bU, 0xa01cfe81U, 0x2b94f908U, + 0x68587048U, 0xfd198f45U, 0x6c8794deU, 0xf8b7527bU, + 0xd323ab73U, 0x02e2724bU, 0x8f57e31fU, 0xab2a6655U, + 0x2807b2ebU, 0xc2032fb5U, 0x7b9a86c5U, 0x08a5d337U, + 0x87f23028U, 0xa5b223bfU, 0x6aba0203U, 0x825ced16U, + 0x1c2b8acfU, 0xb492a779U, 0xf2f0f307U, 0xe2a14e69U, + 0xf4cd65daU, 0xbed50605U, 0x621fd134U, 0xfe8ac4a6U, + 0x539d342eU, 0x55a0a2f3U, 0xe132058aU, 0xeb75a4f6U, + 0xec390b83U, 0xefaa4060U, 0x9f065e71U, 0x1051bd6eU, + 0x8af93e21U, 0x063d96ddU, 0x05aedd3eU, 0xbd464de6U, + 0x8db59154U, 0x5d0571c4U, 0xd46f0406U, 0x15ff6050U, + 0xfb241998U, 0xe997d6bdU, 0x43cc8940U, 0x9e7767d9U, + 0x42bdb0e8U, 0x8b880789U, 0x5b38e719U, 0xeedb79c8U, + 0x0a47a17cU, 0x0fe97c42U, 0x1ec9f884U, 0x00000000U, + 0x86830980U, 0xed48322bU, 0x70ac1e11U, 0x724e6c5aU, + 0xfffbfd0eU, 0x38560f85U, 0xd51e3daeU, 0x3927362dU, + 0xd9640a0fU, 0xa621685cU, 0x54d19b5bU, 0x2e3a2436U, + 0x67b10c0aU, 0xe70f9357U, 0x96d2b4eeU, 0x919e1b9bU, + 0xc54f80c0U, 0x20a261dcU, 0x4b695a77U, 0x1a161c12U, + 0xba0ae293U, 0x2ae5c0a0U, 0xe0433c22U, 0x171d121bU, + 0x0d0b0e09U, 0xc7adf28bU, 0xa8b92db6U, 0xa9c8141eU, + 0x198557f1U, 0x074caf75U, 0xddbbee99U, 0x60fda37fU, + 0x269ff701U, 0xf5bc5c72U, 0x3bc54466U, 0x7e345bfbU, + 0x29768b43U, 0xc6dccb23U, 0xfc68b6edU, 0xf163b8e4U, + 0xdccad731U, 0x85104263U, 0x22401397U, 0x112084c6U, + 0x247d854aU, 0x3df8d2bbU, 0x3211aef9U, 0xa16dc729U, + 0x2f4b1d9eU, 0x30f3dcb2U, 0x52ec0d86U, 0xe3d077c1U, + 0x166c2bb3U, 0xb999a970U, 0x48fa1194U, 0x642247e9U, + 0x8cc4a8fcU, 0x3f1aa0f0U, 0x2cd8567dU, 0x90ef2233U, + 0x4ec78749U, 0xd1c1d938U, 0xa2fe8ccaU, 0x0b3698d4U, + 0x81cfa6f5U, 0xde28a57aU, 0x8e26dab7U, 0xbfa43fadU, + 0x9de42c3aU, 0x920d5078U, 0xcc9b6a5fU, 0x4662547eU, + 0x13c2f68dU, 0xb8e890d8U, 0xf75e2e39U, 0xaff582c3U, + 0x80be9f5dU, 0x937c69d0U, 0x2da96fd5U, 0x12b3cf25U, + 0x993bc8acU, 0x7da71018U, 0x636ee89cU, 0xbb7bdb3bU, + 0x7809cd26U, 0x18f46e59U, 0xb701ec9aU, 0x9aa8834fU, + 0x6e65e695U, 0xe67eaaffU, 0xcf0821bcU, 0xe8e6ef15U, + 0x9bd9bae7U, 0x36ce4a6fU, 0x09d4ea9fU, 0x7cd629b0U, + 0xb2af31a4U, 0x23312a3fU, 0x9430c6a5U, 0x66c035a2U, + 0xbc37744eU, 0xcaa6fc82U, 0xd0b0e090U, 0xd81533a7U, + 0x984af104U, 0xdaf741ecU, 0x500e7fcdU, 0xf62f1791U, + 0xd68d764dU, 0xb04d43efU, 0x4d54ccaaU, 0x04dfe496U, + 0xb5e39ed1U, 0x881b4c6aU, 0x1fb8c12cU, 0x517f4665U, + 0xea049d5eU, 0x355d018cU, 0x7473fa87U, 0x412efb0bU, + 0x1d5ab367U, 0xd25292dbU, 0x5633e910U, 0x47136dd6U, + 0x618c9ad7U, 0x0c7a37a1U, 0x148e59f8U, 0x3c89eb13U, + 0x27eecea9U, 0xc935b761U, 0xe5ede11cU, 0xb13c7a47U, + 0xdf599cd2U, 0x733f55f2U, 0xce791814U, 0x37bf73c7U, + 0xcdea53f7U, 0xaa5b5ffdU, 0x6f14df3dU, 0xdb867844U, + 0xf381caafU, 0xc43eb968U, 0x342c3824U, 0x405fc2a3U, + 0xc372161dU, 0x250cbce2U, 0x498b283cU, 0x9541ff0dU, + 0x017139a8U, 0xb3de080cU, 0xe49cd8b4U, 0xc1906456U, + 0x84617bcbU, 0xb670d532U, 0x5c74486cU, 0x5742d0b8U, +}; +static const u32 Td3[256] = { + 0xf4a75051U, 0x4165537eU, 0x17a4c31aU, 0x275e963aU, + 0xab6bcb3bU, 0x9d45f11fU, 0xfa58abacU, 0xe303934bU, + 0x30fa5520U, 0x766df6adU, 0xcc769188U, 0x024c25f5U, + 0xe5d7fc4fU, 0x2acbd7c5U, 0x35448026U, 0x62a38fb5U, + 0xb15a49deU, 0xba1b6725U, 0xea0e9845U, 0xfec0e15dU, + 0x2f7502c3U, 0x4cf01281U, 0x4697a38dU, 0xd3f9c66bU, + 0x8f5fe703U, 0x929c9515U, 0x6d7aebbfU, 0x5259da95U, + 0xbe832dd4U, 0x7421d358U, 0xe0692949U, 0xc9c8448eU, + 0xc2896a75U, 0x8e7978f4U, 0x583e6b99U, 0xb971dd27U, + 0xe14fb6beU, 0x88ad17f0U, 0x20ac66c9U, 0xce3ab47dU, + 0xdf4a1863U, 0x1a3182e5U, 0x51336097U, 0x537f4562U, + 0x6477e0b1U, 0x6bae84bbU, 0x81a01cfeU, 0x082b94f9U, + 0x48685870U, 0x45fd198fU, 0xde6c8794U, 0x7bf8b752U, + 0x73d323abU, 0x4b02e272U, 0x1f8f57e3U, 0x55ab2a66U, + 0xeb2807b2U, 0xb5c2032fU, 0xc57b9a86U, 0x3708a5d3U, + 0x2887f230U, 0xbfa5b223U, 0x036aba02U, 0x16825cedU, + 0xcf1c2b8aU, 0x79b492a7U, 0x07f2f0f3U, 0x69e2a14eU, + 0xdaf4cd65U, 0x05bed506U, 0x34621fd1U, 0xa6fe8ac4U, + 0x2e539d34U, 0xf355a0a2U, 0x8ae13205U, 0xf6eb75a4U, + 0x83ec390bU, 0x60efaa40U, 0x719f065eU, 0x6e1051bdU, + 0x218af93eU, 0xdd063d96U, 0x3e05aeddU, 0xe6bd464dU, + 0x548db591U, 0xc45d0571U, 0x06d46f04U, 0x5015ff60U, + 0x98fb2419U, 0xbde997d6U, 0x4043cc89U, 0xd99e7767U, + 0xe842bdb0U, 0x898b8807U, 0x195b38e7U, 0xc8eedb79U, + 0x7c0a47a1U, 0x420fe97cU, 0x841ec9f8U, 0x00000000U, + 0x80868309U, 0x2bed4832U, 0x1170ac1eU, 0x5a724e6cU, + 0x0efffbfdU, 0x8538560fU, 0xaed51e3dU, 0x2d392736U, + 0x0fd9640aU, 0x5ca62168U, 0x5b54d19bU, 0x362e3a24U, + 0x0a67b10cU, 0x57e70f93U, 0xee96d2b4U, 0x9b919e1bU, + 0xc0c54f80U, 0xdc20a261U, 0x774b695aU, 0x121a161cU, + 0x93ba0ae2U, 0xa02ae5c0U, 0x22e0433cU, 0x1b171d12U, + 0x090d0b0eU, 0x8bc7adf2U, 0xb6a8b92dU, 0x1ea9c814U, + 0xf1198557U, 0x75074cafU, 0x99ddbbeeU, 0x7f60fda3U, + 0x01269ff7U, 0x72f5bc5cU, 0x663bc544U, 0xfb7e345bU, + 0x4329768bU, 0x23c6dccbU, 0xedfc68b6U, 0xe4f163b8U, + 0x31dccad7U, 0x63851042U, 0x97224013U, 0xc6112084U, + 0x4a247d85U, 0xbb3df8d2U, 0xf93211aeU, 0x29a16dc7U, + 0x9e2f4b1dU, 0xb230f3dcU, 0x8652ec0dU, 0xc1e3d077U, + 0xb3166c2bU, 0x70b999a9U, 0x9448fa11U, 0xe9642247U, + 0xfc8cc4a8U, 0xf03f1aa0U, 0x7d2cd856U, 0x3390ef22U, + 0x494ec787U, 0x38d1c1d9U, 0xcaa2fe8cU, 0xd40b3698U, + 0xf581cfa6U, 0x7ade28a5U, 0xb78e26daU, 0xadbfa43fU, + 0x3a9de42cU, 0x78920d50U, 0x5fcc9b6aU, 0x7e466254U, + 0x8d13c2f6U, 0xd8b8e890U, 0x39f75e2eU, 0xc3aff582U, + 0x5d80be9fU, 0xd0937c69U, 0xd52da96fU, 0x2512b3cfU, + 0xac993bc8U, 0x187da710U, 0x9c636ee8U, 0x3bbb7bdbU, + 0x267809cdU, 0x5918f46eU, 0x9ab701ecU, 0x4f9aa883U, + 0x956e65e6U, 0xffe67eaaU, 0xbccf0821U, 0x15e8e6efU, + 0xe79bd9baU, 0x6f36ce4aU, 0x9f09d4eaU, 0xb07cd629U, + 0xa4b2af31U, 0x3f23312aU, 0xa59430c6U, 0xa266c035U, + 0x4ebc3774U, 0x82caa6fcU, 0x90d0b0e0U, 0xa7d81533U, + 0x04984af1U, 0xecdaf741U, 0xcd500e7fU, 0x91f62f17U, + 0x4dd68d76U, 0xefb04d43U, 0xaa4d54ccU, 0x9604dfe4U, + 0xd1b5e39eU, 0x6a881b4cU, 0x2c1fb8c1U, 0x65517f46U, + 0x5eea049dU, 0x8c355d01U, 0x877473faU, 0x0b412efbU, + 0x671d5ab3U, 0xdbd25292U, 0x105633e9U, 0xd647136dU, + 0xd7618c9aU, 0xa10c7a37U, 0xf8148e59U, 0x133c89ebU, + 0xa927eeceU, 0x61c935b7U, 0x1ce5ede1U, 0x47b13c7aU, + 0xd2df599cU, 0xf2733f55U, 0x14ce7918U, 0xc737bf73U, + 0xf7cdea53U, 0xfdaa5b5fU, 0x3d6f14dfU, 0x44db8678U, + 0xaff381caU, 0x68c43eb9U, 0x24342c38U, 0xa3405fc2U, + 0x1dc37216U, 0xe2250cbcU, 0x3c498b28U, 0x0d9541ffU, + 0xa8017139U, 0x0cb3de08U, 0xb4e49cd8U, 0x56c19064U, + 0xcb84617bU, 0x32b670d5U, 0x6c5c7448U, 0xb85742d0U, +}; +static const u8 Td4[256] = { + 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, + 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, + 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, + 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, + 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, + 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, + 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, + 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, + 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, + 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, + 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, + 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, + 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, + 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, + 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, + 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, + 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, + 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, + 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, + 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, + 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, + 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, + 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, + 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, + 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, + 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, + 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, + 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, + 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, + 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, + 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, + 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU, +}; +static const u32 rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +/** + * Expand the cipher key into the encryption key schedule. + */ +int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ + + u32 *rk; + int i = 0; + u32 temp; + + if (!userKey || !key) + return -1; + if (bits != 128 && bits != 192 && bits != 256) + return -2; + + rk = key->rd_key; + + if (bits==128) + key->rounds = 10; + else if (bits==192) + key->rounds = 12; + else + key->rounds = 14; + + rk[0] = GETU32(userKey ); + rk[1] = GETU32(userKey + 4); + rk[2] = GETU32(userKey + 8); + rk[3] = GETU32(userKey + 12); + if (bits == 128) { + while (1) { + temp = rk[3]; + rk[4] = rk[0] ^ + (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te0[(temp ) & 0xff] & 0x0000ff00) ^ + (Te1[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + return 0; + } + rk += 4; + } + } + rk[4] = GETU32(userKey + 16); + rk[5] = GETU32(userKey + 20); + if (bits == 192) { + while (1) { + temp = rk[ 5]; + rk[ 6] = rk[ 0] ^ + (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te0[(temp ) & 0xff] & 0x0000ff00) ^ + (Te1[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + return 0; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } + rk[6] = GETU32(userKey + 24); + rk[7] = GETU32(userKey + 28); + if (bits == 256) { + while (1) { + temp = rk[ 7]; + rk[ 8] = rk[ 0] ^ + (Te2[(temp >> 16) & 0xff] & 0xff000000) ^ + (Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^ + (Te0[(temp ) & 0xff] & 0x0000ff00) ^ + (Te1[(temp >> 24) ] & 0x000000ff) ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + return 0; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ + (Te2[(temp >> 24) ] & 0xff000000) ^ + (Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(temp ) & 0xff] & 0x000000ff); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + + rk += 8; + } + } + return 0; +} + +/** + * Expand the cipher key into the decryption key schedule. + */ +int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ + + u32 *rk; + int i, j, status; + u32 temp; + + /* first, start with an encryption schedule */ + status = private_AES_set_encrypt_key(userKey, bits, key); + if (status < 0) + return status; + + rk = key->rd_key; + + /* invert the order of the round keys: */ + for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + for (i = 1; i < (key->rounds); i++) { + rk += 4; + rk[0] = + Td0[Te1[(rk[0] >> 24) ] & 0xff] ^ + Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^ + Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^ + Td3[Te1[(rk[0] ) & 0xff] & 0xff]; + rk[1] = + Td0[Te1[(rk[1] >> 24) ] & 0xff] ^ + Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^ + Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^ + Td3[Te1[(rk[1] ) & 0xff] & 0xff]; + rk[2] = + Td0[Te1[(rk[2] >> 24) ] & 0xff] ^ + Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^ + Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^ + Td3[Te1[(rk[2] ) & 0xff] & 0xff]; + rk[3] = + Td0[Te1[(rk[3] >> 24) ] & 0xff] ^ + Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^ + Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^ + Td3[Te1[(rk[3] ) & 0xff] & 0xff]; + } + return 0; +} + +/* + * Encrypt a single block + * in and out can overlap + */ +void AES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key) { + + const u32 *rk; + u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + assert(in && out && key); + rk = key->rd_key; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(in ) ^ rk[0]; + s1 = GETU32(in + 4) ^ rk[1]; + s2 = GETU32(in + 8) ^ rk[2]; + s3 = GETU32(in + 12) ^ rk[3]; +#ifdef FULL_UNROLL + /* round 1: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7]; + /* round 2: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11]; + /* round 3: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15]; + /* round 4: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19]; + /* round 5: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23]; + /* round 6: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27]; + /* round 7: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31]; + /* round 8: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35]; + /* round 9: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39]; + if (key->rounds > 10) { + /* round 10: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[41]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[42]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[43]; + /* round 11: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[44]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[45]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[46]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[47]; + if (key->rounds > 12) { + /* round 12: */ + s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[48]; + s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[49]; + s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[50]; + s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[51]; + /* round 13: */ + t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[52]; + t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[53]; + t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[54]; + t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[55]; + } + } + rk += key->rounds << 2; +#else /* !FULL_UNROLL */ + /* + * Nr - 1 full rounds: + */ + r = key->rounds >> 1; + for (;;) { + t0 = + Te0[(s0 >> 24) ] ^ + Te1[(s1 >> 16) & 0xff] ^ + Te2[(s2 >> 8) & 0xff] ^ + Te3[(s3 ) & 0xff] ^ + rk[4]; + t1 = + Te0[(s1 >> 24) ] ^ + Te1[(s2 >> 16) & 0xff] ^ + Te2[(s3 >> 8) & 0xff] ^ + Te3[(s0 ) & 0xff] ^ + rk[5]; + t2 = + Te0[(s2 >> 24) ] ^ + Te1[(s3 >> 16) & 0xff] ^ + Te2[(s0 >> 8) & 0xff] ^ + Te3[(s1 ) & 0xff] ^ + rk[6]; + t3 = + Te0[(s3 >> 24) ] ^ + Te1[(s0 >> 16) & 0xff] ^ + Te2[(s1 >> 8) & 0xff] ^ + Te3[(s2 ) & 0xff] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Te0[(t0 >> 24) ] ^ + Te1[(t1 >> 16) & 0xff] ^ + Te2[(t2 >> 8) & 0xff] ^ + Te3[(t3 ) & 0xff] ^ + rk[0]; + s1 = + Te0[(t1 >> 24) ] ^ + Te1[(t2 >> 16) & 0xff] ^ + Te2[(t3 >> 8) & 0xff] ^ + Te3[(t0 ) & 0xff] ^ + rk[1]; + s2 = + Te0[(t2 >> 24) ] ^ + Te1[(t3 >> 16) & 0xff] ^ + Te2[(t0 >> 8) & 0xff] ^ + Te3[(t1 ) & 0xff] ^ + rk[2]; + s3 = + Te0[(t3 >> 24) ] ^ + Te1[(t0 >> 16) & 0xff] ^ + Te2[(t1 >> 8) & 0xff] ^ + Te3[(t2 ) & 0xff] ^ + rk[3]; + } +#endif /* ?FULL_UNROLL */ + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + (Te2[(t0 >> 24) ] & 0xff000000) ^ + (Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t3 ) & 0xff] & 0x000000ff) ^ + rk[0]; + PUTU32(out , s0); + s1 = + (Te2[(t1 >> 24) ] & 0xff000000) ^ + (Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t0 ) & 0xff] & 0x000000ff) ^ + rk[1]; + PUTU32(out + 4, s1); + s2 = + (Te2[(t2 >> 24) ] & 0xff000000) ^ + (Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t1 ) & 0xff] & 0x000000ff) ^ + rk[2]; + PUTU32(out + 8, s2); + s3 = + (Te2[(t3 >> 24) ] & 0xff000000) ^ + (Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^ + (Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^ + (Te1[(t2 ) & 0xff] & 0x000000ff) ^ + rk[3]; + PUTU32(out + 12, s3); +} + +/* + * Decrypt a single block + * in and out can overlap + */ +void AES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key) +{ + + const u32 *rk; + u32 s0, s1, s2, s3, t0, t1, t2, t3; +#ifndef FULL_UNROLL + int r; +#endif /* ?FULL_UNROLL */ + + assert(in && out && key); + rk = key->rd_key; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(in ) ^ rk[0]; + s1 = GETU32(in + 4) ^ rk[1]; + s2 = GETU32(in + 8) ^ rk[2]; + s3 = GETU32(in + 12) ^ rk[3]; +#ifdef FULL_UNROLL + /* round 1: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[ 4]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[ 5]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[ 6]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[ 7]; + /* round 2: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[ 8]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[ 9]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[10]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[11]; + /* round 3: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[12]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[13]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[14]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[15]; + /* round 4: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[16]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[17]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[18]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[19]; + /* round 5: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[20]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[21]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[22]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[23]; + /* round 6: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[24]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[25]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[26]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[27]; + /* round 7: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[28]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[29]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[30]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[31]; + /* round 8: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[32]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[33]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[34]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[35]; + /* round 9: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[36]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[37]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[38]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[39]; + if (key->rounds > 10) { + /* round 10: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[40]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[41]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[42]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[43]; + /* round 11: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[44]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[45]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[46]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[47]; + if (key->rounds > 12) { + /* round 12: */ + s0 = Td0[t0 >> 24] ^ Td1[(t3 >> 16) & 0xff] ^ Td2[(t2 >> 8) & 0xff] ^ Td3[t1 & 0xff] ^ rk[48]; + s1 = Td0[t1 >> 24] ^ Td1[(t0 >> 16) & 0xff] ^ Td2[(t3 >> 8) & 0xff] ^ Td3[t2 & 0xff] ^ rk[49]; + s2 = Td0[t2 >> 24] ^ Td1[(t1 >> 16) & 0xff] ^ Td2[(t0 >> 8) & 0xff] ^ Td3[t3 & 0xff] ^ rk[50]; + s3 = Td0[t3 >> 24] ^ Td1[(t2 >> 16) & 0xff] ^ Td2[(t1 >> 8) & 0xff] ^ Td3[t0 & 0xff] ^ rk[51]; + /* round 13: */ + t0 = Td0[s0 >> 24] ^ Td1[(s3 >> 16) & 0xff] ^ Td2[(s2 >> 8) & 0xff] ^ Td3[s1 & 0xff] ^ rk[52]; + t1 = Td0[s1 >> 24] ^ Td1[(s0 >> 16) & 0xff] ^ Td2[(s3 >> 8) & 0xff] ^ Td3[s2 & 0xff] ^ rk[53]; + t2 = Td0[s2 >> 24] ^ Td1[(s1 >> 16) & 0xff] ^ Td2[(s0 >> 8) & 0xff] ^ Td3[s3 & 0xff] ^ rk[54]; + t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55]; + } + } + rk += key->rounds << 2; +#else /* !FULL_UNROLL */ + /* + * Nr - 1 full rounds: + */ + r = key->rounds >> 1; + for (;;) { + t0 = + Td0[(s0 >> 24) ] ^ + Td1[(s3 >> 16) & 0xff] ^ + Td2[(s2 >> 8) & 0xff] ^ + Td3[(s1 ) & 0xff] ^ + rk[4]; + t1 = + Td0[(s1 >> 24) ] ^ + Td1[(s0 >> 16) & 0xff] ^ + Td2[(s3 >> 8) & 0xff] ^ + Td3[(s2 ) & 0xff] ^ + rk[5]; + t2 = + Td0[(s2 >> 24) ] ^ + Td1[(s1 >> 16) & 0xff] ^ + Td2[(s0 >> 8) & 0xff] ^ + Td3[(s3 ) & 0xff] ^ + rk[6]; + t3 = + Td0[(s3 >> 24) ] ^ + Td1[(s2 >> 16) & 0xff] ^ + Td2[(s1 >> 8) & 0xff] ^ + Td3[(s0 ) & 0xff] ^ + rk[7]; + + rk += 8; + if (--r == 0) { + break; + } + + s0 = + Td0[(t0 >> 24) ] ^ + Td1[(t3 >> 16) & 0xff] ^ + Td2[(t2 >> 8) & 0xff] ^ + Td3[(t1 ) & 0xff] ^ + rk[0]; + s1 = + Td0[(t1 >> 24) ] ^ + Td1[(t0 >> 16) & 0xff] ^ + Td2[(t3 >> 8) & 0xff] ^ + Td3[(t2 ) & 0xff] ^ + rk[1]; + s2 = + Td0[(t2 >> 24) ] ^ + Td1[(t1 >> 16) & 0xff] ^ + Td2[(t0 >> 8) & 0xff] ^ + Td3[(t3 ) & 0xff] ^ + rk[2]; + s3 = + Td0[(t3 >> 24) ] ^ + Td1[(t2 >> 16) & 0xff] ^ + Td2[(t1 >> 8) & 0xff] ^ + Td3[(t0 ) & 0xff] ^ + rk[3]; + } +#endif /* ?FULL_UNROLL */ + /* + * apply last round and + * map cipher state to byte array block: + */ + s0 = + ((u32)Td4[(t0 >> 24) ] << 24) ^ + ((u32)Td4[(t3 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t2 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t1 ) & 0xff]) ^ + rk[0]; + PUTU32(out , s0); + s1 = + ((u32)Td4[(t1 >> 24) ] << 24) ^ + ((u32)Td4[(t0 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t3 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t2 ) & 0xff]) ^ + rk[1]; + PUTU32(out + 4, s1); + s2 = + ((u32)Td4[(t2 >> 24) ] << 24) ^ + ((u32)Td4[(t1 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t0 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t3 ) & 0xff]) ^ + rk[2]; + PUTU32(out + 8, s2); + s3 = + ((u32)Td4[(t3 >> 24) ] << 24) ^ + ((u32)Td4[(t2 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(t1 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(t0 ) & 0xff]) ^ + rk[3]; + PUTU32(out + 12, s3); +} + +#else /* AES_ASM */ + +static const u8 Te4[256] = { + 0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U, + 0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U, + 0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U, + 0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U, + 0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU, + 0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U, + 0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU, + 0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U, + 0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U, + 0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U, + 0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU, + 0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU, + 0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U, + 0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U, + 0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U, + 0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U, + 0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U, + 0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U, + 0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U, + 0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU, + 0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU, + 0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U, + 0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U, + 0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U, + 0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U, + 0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU, + 0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU, + 0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU, + 0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U, + 0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU, + 0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U, + 0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U +}; +static const u32 rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, + 0x10000000, 0x20000000, 0x40000000, 0x80000000, + 0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +/** + * Expand the cipher key into the encryption key schedule. + */ +int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ + u32 *rk; + int i = 0; + u32 temp; + + if (!userKey || !key) + return -1; + if (bits != 128 && bits != 192 && bits != 256) + return -2; + + rk = key->rd_key; + + if (bits==128) + key->rounds = 10; + else if (bits==192) + key->rounds = 12; + else + key->rounds = 14; + + rk[0] = GETU32(userKey ); + rk[1] = GETU32(userKey + 4); + rk[2] = GETU32(userKey + 8); + rk[3] = GETU32(userKey + 12); + if (bits == 128) { + while (1) { + temp = rk[3]; + rk[4] = rk[0] ^ + ((u32)Te4[(temp >> 16) & 0xff] << 24) ^ + ((u32)Te4[(temp >> 8) & 0xff] << 16) ^ + ((u32)Te4[(temp ) & 0xff] << 8) ^ + ((u32)Te4[(temp >> 24) ]) ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + return 0; + } + rk += 4; + } + } + rk[4] = GETU32(userKey + 16); + rk[5] = GETU32(userKey + 20); + if (bits == 192) { + while (1) { + temp = rk[ 5]; + rk[ 6] = rk[ 0] ^ + ((u32)Te4[(temp >> 16) & 0xff] << 24) ^ + ((u32)Te4[(temp >> 8) & 0xff] << 16) ^ + ((u32)Te4[(temp ) & 0xff] << 8) ^ + ((u32)Te4[(temp >> 24) ]) ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + return 0; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } + rk[6] = GETU32(userKey + 24); + rk[7] = GETU32(userKey + 28); + if (bits == 256) { + while (1) { + temp = rk[ 7]; + rk[ 8] = rk[ 0] ^ + ((u32)Te4[(temp >> 16) & 0xff] << 24) ^ + ((u32)Te4[(temp >> 8) & 0xff] << 16) ^ + ((u32)Te4[(temp ) & 0xff] << 8) ^ + ((u32)Te4[(temp >> 24) ]) ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + return 0; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ + ((u32)Te4[(temp >> 24) ] << 24) ^ + ((u32)Te4[(temp >> 16) & 0xff] << 16) ^ + ((u32)Te4[(temp >> 8) & 0xff] << 8) ^ + ((u32)Te4[(temp ) & 0xff]); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + + rk += 8; + } + } + return 0; +} + +/** + * Expand the cipher key into the decryption key schedule. + */ +int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ + + u32 *rk; + int i, j, status; + u32 temp; + + /* first, start with an encryption schedule */ + status = private_AES_set_encrypt_key(userKey, bits, key); + if (status < 0) + return status; + + rk = key->rd_key; + + /* invert the order of the round keys: */ + for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + for (i = 1; i < (key->rounds); i++) { + rk += 4; + for (j = 0; j < 4; j++) { + u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m; + + tp1 = rk[j]; + m = tp1 & 0x80808080; + tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + m = tp2 & 0x80808080; + tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + m = tp4 & 0x80808080; + tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + tp9 = tp8 ^ tp1; + tpb = tp9 ^ tp2; + tpd = tp9 ^ tp4; + tpe = tp8 ^ tp4 ^ tp2; +#if defined(ROTATE) + rk[j] = tpe ^ ROTATE(tpd,16) ^ + ROTATE(tp9,24) ^ ROTATE(tpb,8); +#else + rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ + (tp9 >> 8) ^ (tp9 << 24) ^ + (tpb >> 24) ^ (tpb << 8); +#endif + } + } + return 0; +} + +#endif /* AES_ASM */ diff --git a/libs/openssl/crypto/aes/aes_ctr.c b/libs/openssl/crypto/aes/aes_ctr.c new file mode 100644 index 00000000..9e760c4b --- /dev/null +++ b/libs/openssl/crypto/aes/aes_ctr.c @@ -0,0 +1,63 @@ +/* crypto/aes/aes_ctr.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include + +void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char ivec[AES_BLOCK_SIZE], + unsigned char ecount_buf[AES_BLOCK_SIZE], + unsigned int *num) +{ + CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num, + (block128_f) AES_encrypt); +} diff --git a/libs/openssl/crypto/aes/aes_ecb.c b/libs/openssl/crypto/aes/aes_ecb.c new file mode 100644 index 00000000..52151a5c --- /dev/null +++ b/libs/openssl/crypto/aes/aes_ecb.c @@ -0,0 +1,73 @@ +/* crypto/aes/aes_ecb.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef AES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +#include +#include "aes_locl.h" + +void AES_ecb_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key, const int enc) +{ + + assert(in && out && key); + assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); + + if (AES_ENCRYPT == enc) + AES_encrypt(in, out, key); + else + AES_decrypt(in, out, key); +} diff --git a/libs/openssl/crypto/aes/aes_ige.c b/libs/openssl/crypto/aes/aes_ige.c new file mode 100644 index 00000000..8f2b7706 --- /dev/null +++ b/libs/openssl/crypto/aes/aes_ige.c @@ -0,0 +1,323 @@ +/* crypto/aes/aes_ige.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "cryptlib.h" + +#include +#include "aes_locl.h" + +#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long)) +typedef struct { + unsigned long data[N_WORDS]; +} aes_block_t; + +/* XXX: probably some better way to do this */ +#if defined(__i386__) || defined(__x86_64__) +# define UNALIGNED_MEMOPS_ARE_FAST 1 +#else +# define UNALIGNED_MEMOPS_ARE_FAST 0 +#endif + +#if UNALIGNED_MEMOPS_ARE_FAST +# define load_block(d, s) (d) = *(const aes_block_t *)(s) +# define store_block(d, s) *(aes_block_t *)(d) = (s) +#else +# define load_block(d, s) memcpy((d).data, (s), AES_BLOCK_SIZE) +# define store_block(d, s) memcpy((d), (s).data, AES_BLOCK_SIZE) +#endif + +/* N.B. The IV for this mode is _twice_ the block size */ + +void AES_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, const int enc) +{ + size_t n; + size_t len = length; + + OPENSSL_assert(in && out && key && ivec); + OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); + OPENSSL_assert((length % AES_BLOCK_SIZE) == 0); + + len = length / AES_BLOCK_SIZE; + + if (AES_ENCRYPT == enc) { + if (in != out && + (UNALIGNED_MEMOPS_ARE_FAST + || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) == + 0)) { + aes_block_t *ivp = (aes_block_t *) ivec; + aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE); + + while (len) { + aes_block_t *inp = (aes_block_t *) in; + aes_block_t *outp = (aes_block_t *) out; + + for (n = 0; n < N_WORDS; ++n) + outp->data[n] = inp->data[n] ^ ivp->data[n]; + AES_encrypt((unsigned char *)outp->data, + (unsigned char *)outp->data, key); + for (n = 0; n < N_WORDS; ++n) + outp->data[n] ^= iv2p->data[n]; + ivp = outp; + iv2p = inp; + --len; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + memcpy(ivec, ivp->data, AES_BLOCK_SIZE); + memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); + } else { + aes_block_t tmp, tmp2; + aes_block_t iv; + aes_block_t iv2; + + load_block(iv, ivec); + load_block(iv2, ivec + AES_BLOCK_SIZE); + + while (len) { + load_block(tmp, in); + for (n = 0; n < N_WORDS; ++n) + tmp2.data[n] = tmp.data[n] ^ iv.data[n]; + AES_encrypt((unsigned char *)tmp2.data, + (unsigned char *)tmp2.data, key); + for (n = 0; n < N_WORDS; ++n) + tmp2.data[n] ^= iv2.data[n]; + store_block(out, tmp2); + iv = tmp2; + iv2 = tmp; + --len; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + memcpy(ivec, iv.data, AES_BLOCK_SIZE); + memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); + } + } else { + if (in != out && + (UNALIGNED_MEMOPS_ARE_FAST + || ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) == + 0)) { + aes_block_t *ivp = (aes_block_t *) ivec; + aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE); + + while (len) { + aes_block_t tmp; + aes_block_t *inp = (aes_block_t *) in; + aes_block_t *outp = (aes_block_t *) out; + + for (n = 0; n < N_WORDS; ++n) + tmp.data[n] = inp->data[n] ^ iv2p->data[n]; + AES_decrypt((unsigned char *)tmp.data, + (unsigned char *)outp->data, key); + for (n = 0; n < N_WORDS; ++n) + outp->data[n] ^= ivp->data[n]; + ivp = inp; + iv2p = outp; + --len; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + memcpy(ivec, ivp->data, AES_BLOCK_SIZE); + memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE); + } else { + aes_block_t tmp, tmp2; + aes_block_t iv; + aes_block_t iv2; + + load_block(iv, ivec); + load_block(iv2, ivec + AES_BLOCK_SIZE); + + while (len) { + load_block(tmp, in); + tmp2 = tmp; + for (n = 0; n < N_WORDS; ++n) + tmp.data[n] ^= iv2.data[n]; + AES_decrypt((unsigned char *)tmp.data, + (unsigned char *)tmp.data, key); + for (n = 0; n < N_WORDS; ++n) + tmp.data[n] ^= iv.data[n]; + store_block(out, tmp); + iv = tmp2; + iv2 = tmp; + --len; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + memcpy(ivec, iv.data, AES_BLOCK_SIZE); + memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE); + } + } +} + +/* + * Note that its effectively impossible to do biIGE in anything other + * than a single pass, so no provision is made for chaining. + */ + +/* N.B. The IV for this mode is _four times_ the block size */ + +void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + const AES_KEY *key2, const unsigned char *ivec, + const int enc) +{ + size_t n; + size_t len = length; + unsigned char tmp[AES_BLOCK_SIZE]; + unsigned char tmp2[AES_BLOCK_SIZE]; + unsigned char tmp3[AES_BLOCK_SIZE]; + unsigned char prev[AES_BLOCK_SIZE]; + const unsigned char *iv; + const unsigned char *iv2; + + OPENSSL_assert(in && out && key && ivec); + OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc)); + OPENSSL_assert((length % AES_BLOCK_SIZE) == 0); + + if (AES_ENCRYPT == enc) { + /* + * XXX: Do a separate case for when in != out (strictly should check + * for overlap, too) + */ + + /* First the forward pass */ + iv = ivec; + iv2 = ivec + AES_BLOCK_SIZE; + while (len >= AES_BLOCK_SIZE) { + for (n = 0; n < AES_BLOCK_SIZE; ++n) + out[n] = in[n] ^ iv[n]; + AES_encrypt(out, out, key); + for (n = 0; n < AES_BLOCK_SIZE; ++n) + out[n] ^= iv2[n]; + iv = out; + memcpy(prev, in, AES_BLOCK_SIZE); + iv2 = prev; + len -= AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + + /* And now backwards */ + iv = ivec + AES_BLOCK_SIZE * 2; + iv2 = ivec + AES_BLOCK_SIZE * 3; + len = length; + while (len >= AES_BLOCK_SIZE) { + out -= AES_BLOCK_SIZE; + /* + * XXX: reduce copies by alternating between buffers + */ + memcpy(tmp, out, AES_BLOCK_SIZE); + for (n = 0; n < AES_BLOCK_SIZE; ++n) + out[n] ^= iv[n]; + /* + * hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); + */ + AES_encrypt(out, out, key); + /* + * hexdump(stdout,"enc", out, AES_BLOCK_SIZE); + */ + /* + * hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); + */ + for (n = 0; n < AES_BLOCK_SIZE; ++n) + out[n] ^= iv2[n]; + /* + * hexdump(stdout,"out", out, AES_BLOCK_SIZE); + */ + iv = out; + memcpy(prev, tmp, AES_BLOCK_SIZE); + iv2 = prev; + len -= AES_BLOCK_SIZE; + } + } else { + /* First backwards */ + iv = ivec + AES_BLOCK_SIZE * 2; + iv2 = ivec + AES_BLOCK_SIZE * 3; + in += length; + out += length; + while (len >= AES_BLOCK_SIZE) { + in -= AES_BLOCK_SIZE; + out -= AES_BLOCK_SIZE; + memcpy(tmp, in, AES_BLOCK_SIZE); + memcpy(tmp2, in, AES_BLOCK_SIZE); + for (n = 0; n < AES_BLOCK_SIZE; ++n) + tmp[n] ^= iv2[n]; + AES_decrypt(tmp, out, key); + for (n = 0; n < AES_BLOCK_SIZE; ++n) + out[n] ^= iv[n]; + memcpy(tmp3, tmp2, AES_BLOCK_SIZE); + iv = tmp3; + iv2 = out; + len -= AES_BLOCK_SIZE; + } + + /* And now forwards */ + iv = ivec; + iv2 = ivec + AES_BLOCK_SIZE; + len = length; + while (len >= AES_BLOCK_SIZE) { + memcpy(tmp, out, AES_BLOCK_SIZE); + memcpy(tmp2, out, AES_BLOCK_SIZE); + for (n = 0; n < AES_BLOCK_SIZE; ++n) + tmp[n] ^= iv2[n]; + AES_decrypt(tmp, out, key); + for (n = 0; n < AES_BLOCK_SIZE; ++n) + out[n] ^= iv[n]; + memcpy(tmp3, tmp2, AES_BLOCK_SIZE); + iv = tmp3; + iv2 = out; + len -= AES_BLOCK_SIZE; + in += AES_BLOCK_SIZE; + out += AES_BLOCK_SIZE; + } + } +} diff --git a/libs/openssl/crypto/aes/aes_locl.h b/libs/openssl/crypto/aes/aes_locl.h new file mode 100644 index 00000000..7acd74ec --- /dev/null +++ b/libs/openssl/crypto/aes/aes_locl.h @@ -0,0 +1,89 @@ +/* crypto/aes/aes.h */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef HEADER_AES_LOCL_H +# define HEADER_AES_LOCL_H + +# include + +# ifdef OPENSSL_NO_AES +# error AES is disabled. +# endif + +# include +# include +# include + +# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) +# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) +# define GETU32(p) SWAP(*((u32 *)(p))) +# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); } +# else +# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3])) +# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); } +# endif + +# ifdef AES_LONG +typedef unsigned long u32; +# else +typedef unsigned int u32; +# endif +typedef unsigned short u16; +typedef unsigned char u8; + +# define MAXKC (256/32) +# define MAXKB (256/8) +# define MAXNR 14 + +/* This controls loop-unrolling in aes_core.c */ +# undef FULL_UNROLL + +#endif /* !HEADER_AES_LOCL_H */ diff --git a/libs/openssl/crypto/aes/aes_misc.c b/libs/openssl/crypto/aes/aes_misc.c new file mode 100644 index 00000000..fafad4d6 --- /dev/null +++ b/libs/openssl/crypto/aes/aes_misc.c @@ -0,0 +1,86 @@ +/* crypto/aes/aes_misc.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include +#include "aes_locl.h" + +const char AES_version[] = "AES" OPENSSL_VERSION_PTEXT; + +const char *AES_options(void) +{ +#ifdef FULL_UNROLL + return "aes(full)"; +#else + return "aes(partial)"; +#endif +} + +/* FIPS wrapper functions to block low level AES calls in FIPS mode */ + +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ +#ifdef OPENSSL_FIPS + fips_cipher_abort(AES); +#endif + return private_AES_set_encrypt_key(userKey, bits, key); +} + +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ +#ifdef OPENSSL_FIPS + fips_cipher_abort(AES); +#endif + return private_AES_set_decrypt_key(userKey, bits, key); +} diff --git a/libs/openssl/crypto/aes/aes_ofb.c b/libs/openssl/crypto/aes/aes_ofb.c new file mode 100644 index 00000000..64a08caa --- /dev/null +++ b/libs/openssl/crypto/aes/aes_ofb.c @@ -0,0 +1,61 @@ +/* crypto/aes/aes_ofb.c */ +/* ==================================================================== + * Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include + +void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char *ivec, int *num) +{ + CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, + (block128_f) AES_encrypt); +} diff --git a/libs/openssl/crypto/aes/aes_wrap.c b/libs/openssl/crypto/aes/aes_wrap.c new file mode 100644 index 00000000..b1ab8e25 --- /dev/null +++ b/libs/openssl/crypto/aes/aes_wrap.c @@ -0,0 +1,250 @@ +/* crypto/aes/aes_wrap.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "cryptlib.h" +#include +#include + +static const unsigned char default_iv[] = { + 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, +}; + +int AES_wrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen) +{ + unsigned char *A, B[16], *R; + unsigned int i, j, t; + if ((inlen & 0x7) || (inlen < 8)) + return -1; + A = B; + t = 1; + memcpy(out + 8, in, inlen); + if (!iv) + iv = default_iv; + + memcpy(A, iv, 8); + + for (j = 0; j < 6; j++) { + R = out + 8; + for (i = 0; i < inlen; i += 8, t++, R += 8) { + memcpy(B + 8, R, 8); + AES_encrypt(B, B, key); + A[7] ^= (unsigned char)(t & 0xff); + if (t > 0xff) { + A[6] ^= (unsigned char)((t >> 8) & 0xff); + A[5] ^= (unsigned char)((t >> 16) & 0xff); + A[4] ^= (unsigned char)((t >> 24) & 0xff); + } + memcpy(R, B + 8, 8); + } + } + memcpy(out, A, 8); + return inlen + 8; +} + +int AES_unwrap_key(AES_KEY *key, const unsigned char *iv, + unsigned char *out, + const unsigned char *in, unsigned int inlen) +{ + unsigned char *A, B[16], *R; + unsigned int i, j, t; + inlen -= 8; + if (inlen & 0x7) + return -1; + if (inlen < 8) + return -1; + A = B; + t = 6 * (inlen >> 3); + memcpy(A, in, 8); + memcpy(out, in + 8, inlen); + for (j = 0; j < 6; j++) { + R = out + inlen - 8; + for (i = 0; i < inlen; i += 8, t--, R -= 8) { + A[7] ^= (unsigned char)(t & 0xff); + if (t > 0xff) { + A[6] ^= (unsigned char)((t >> 8) & 0xff); + A[5] ^= (unsigned char)((t >> 16) & 0xff); + A[4] ^= (unsigned char)((t >> 24) & 0xff); + } + memcpy(B + 8, R, 8); + AES_decrypt(B, B, key); + memcpy(R, B + 8, 8); + } + } + if (!iv) + iv = default_iv; + if (memcmp(A, iv, 8)) { + OPENSSL_cleanse(out, inlen); + return 0; + } + return inlen; +} + +#ifdef AES_WRAP_TEST + +int AES_wrap_unwrap_test(const unsigned char *kek, int keybits, + const unsigned char *iv, + const unsigned char *eout, + const unsigned char *key, int keylen) +{ + unsigned char *otmp = NULL, *ptmp = NULL; + int r, ret = 0; + AES_KEY wctx; + otmp = OPENSSL_malloc(keylen + 8); + ptmp = OPENSSL_malloc(keylen); + if (!otmp || !ptmp) + return 0; + if (AES_set_encrypt_key(kek, keybits, &wctx)) + goto err; + r = AES_wrap_key(&wctx, iv, otmp, key, keylen); + if (r <= 0) + goto err; + + if (eout && memcmp(eout, otmp, keylen)) + goto err; + + if (AES_set_decrypt_key(kek, keybits, &wctx)) + goto err; + r = AES_unwrap_key(&wctx, iv, ptmp, otmp, r); + + if (memcmp(key, ptmp, keylen)) + goto err; + + ret = 1; + + err: + if (otmp) + OPENSSL_free(otmp); + if (ptmp) + OPENSSL_free(ptmp); + + return ret; + +} + +int main(int argc, char **argv) +{ + + static const unsigned char kek[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f + }; + + static const unsigned char key[] = { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f + }; + + static const unsigned char e1[] = { + 0x1f, 0xa6, 0x8b, 0x0a, 0x81, 0x12, 0xb4, 0x47, + 0xae, 0xf3, 0x4b, 0xd8, 0xfb, 0x5a, 0x7b, 0x82, + 0x9d, 0x3e, 0x86, 0x23, 0x71, 0xd2, 0xcf, 0xe5 + }; + + static const unsigned char e2[] = { + 0x96, 0x77, 0x8b, 0x25, 0xae, 0x6c, 0xa4, 0x35, + 0xf9, 0x2b, 0x5b, 0x97, 0xc0, 0x50, 0xae, 0xd2, + 0x46, 0x8a, 0xb8, 0xa1, 0x7a, 0xd8, 0x4e, 0x5d + }; + + static const unsigned char e3[] = { + 0x64, 0xe8, 0xc3, 0xf9, 0xce, 0x0f, 0x5b, 0xa2, + 0x63, 0xe9, 0x77, 0x79, 0x05, 0x81, 0x8a, 0x2a, + 0x93, 0xc8, 0x19, 0x1e, 0x7d, 0x6e, 0x8a, 0xe7 + }; + + static const unsigned char e4[] = { + 0x03, 0x1d, 0x33, 0x26, 0x4e, 0x15, 0xd3, 0x32, + 0x68, 0xf2, 0x4e, 0xc2, 0x60, 0x74, 0x3e, 0xdc, + 0xe1, 0xc6, 0xc7, 0xdd, 0xee, 0x72, 0x5a, 0x93, + 0x6b, 0xa8, 0x14, 0x91, 0x5c, 0x67, 0x62, 0xd2 + }; + + static const unsigned char e5[] = { + 0xa8, 0xf9, 0xbc, 0x16, 0x12, 0xc6, 0x8b, 0x3f, + 0xf6, 0xe6, 0xf4, 0xfb, 0xe3, 0x0e, 0x71, 0xe4, + 0x76, 0x9c, 0x8b, 0x80, 0xa3, 0x2c, 0xb8, 0x95, + 0x8c, 0xd5, 0xd1, 0x7d, 0x6b, 0x25, 0x4d, 0xa1 + }; + + static const unsigned char e6[] = { + 0x28, 0xc9, 0xf4, 0x04, 0xc4, 0xb8, 0x10, 0xf4, + 0xcb, 0xcc, 0xb3, 0x5c, 0xfb, 0x87, 0xf8, 0x26, + 0x3f, 0x57, 0x86, 0xe2, 0xd8, 0x0e, 0xd3, 0x26, + 0xcb, 0xc7, 0xf0, 0xe7, 0x1a, 0x99, 0xf4, 0x3b, + 0xfb, 0x98, 0x8b, 0x9b, 0x7a, 0x02, 0xdd, 0x21 + }; + + AES_KEY wctx, xctx; + int ret; + ret = AES_wrap_unwrap_test(kek, 128, NULL, e1, key, 16); + fprintf(stderr, "Key test result %d\n", ret); + ret = AES_wrap_unwrap_test(kek, 192, NULL, e2, key, 16); + fprintf(stderr, "Key test result %d\n", ret); + ret = AES_wrap_unwrap_test(kek, 256, NULL, e3, key, 16); + fprintf(stderr, "Key test result %d\n", ret); + ret = AES_wrap_unwrap_test(kek, 192, NULL, e4, key, 24); + fprintf(stderr, "Key test result %d\n", ret); + ret = AES_wrap_unwrap_test(kek, 256, NULL, e5, key, 24); + fprintf(stderr, "Key test result %d\n", ret); + ret = AES_wrap_unwrap_test(kek, 256, NULL, e6, key, 32); + fprintf(stderr, "Key test result %d\n", ret); +} + +#endif diff --git a/libs/openssl/crypto/aes/aes_x86core.c b/libs/openssl/crypto/aes/aes_x86core.c new file mode 100644 index 00000000..428bd58d --- /dev/null +++ b/libs/openssl/crypto/aes/aes_x86core.c @@ -0,0 +1,1070 @@ +/* crypto/aes/aes_core.c */ +/** + * rijndael-alg-fst.c + * + * @version 3.0 (December 2000) + * + * Optimised ANSI C code for the Rijndael cipher (now AES) + * + * @author Vincent Rijmen + * @author Antoon Bosselaers + * @author Paulo Barreto + * + * This code is hereby placed in the public domain. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This is experimental x86[_64] derivative. It assumes little-endian + * byte order and expects CPU to sustain unaligned memory references. + * It is used as playground for cache-time attack mitigations and + * serves as reference C implementation for x86[_64] assembler. + * + * + */ + + +#ifndef AES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +#include +#include +#include "aes_locl.h" + +/* + * These two parameters control which table, 256-byte or 2KB, is + * referenced in outer and respectively inner rounds. + */ +#define AES_COMPACT_IN_OUTER_ROUNDS +#ifdef AES_COMPACT_IN_OUTER_ROUNDS +/* AES_COMPACT_IN_OUTER_ROUNDS costs ~30% in performance, while + * adding AES_COMPACT_IN_INNER_ROUNDS reduces benchmark *further* + * by factor of ~2. */ +# undef AES_COMPACT_IN_INNER_ROUNDS +#endif + +#if 1 +static void prefetch256(const void *table) +{ + volatile unsigned long *t=(void *)table,ret; + unsigned long sum; + int i; + + /* 32 is common least cache-line size */ + for (sum=0,i=0;i<256/sizeof(t[0]);i+=32/sizeof(t[0])) sum ^= t[i]; + + ret = sum; +} +#else +# define prefetch256(t) +#endif + +#undef GETU32 +#define GETU32(p) (*((u32*)(p))) + +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +typedef unsigned __int64 u64; +#define U64(C) C##UI64 +#elif defined(__arch64__) +typedef unsigned long u64; +#define U64(C) C##UL +#else +typedef unsigned long long u64; +#define U64(C) C##ULL +#endif + +#undef ROTATE +#if defined(_MSC_VER) || defined(__ICC) +# define ROTATE(a,n) _lrotl(a,n) +#elif defined(__GNUC__) && __GNUC__>=2 +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ( \ + "roll %1,%0" \ + : "=r"(ret) \ + : "I"(n), "0"(a) \ + : "cc"); \ + ret; \ + }) +# endif +#endif +/*- +Te [x] = S [x].[02, 01, 01, 03, 02, 01, 01, 03]; +Te0[x] = S [x].[02, 01, 01, 03]; +Te1[x] = S [x].[03, 02, 01, 01]; +Te2[x] = S [x].[01, 03, 02, 01]; +Te3[x] = S [x].[01, 01, 03, 02]; +*/ +#define Te0 (u32)((u64*)((u8*)Te+0)) +#define Te1 (u32)((u64*)((u8*)Te+3)) +#define Te2 (u32)((u64*)((u8*)Te+2)) +#define Te3 (u32)((u64*)((u8*)Te+1)) +/*- +Td [x] = Si[x].[0e, 09, 0d, 0b, 0e, 09, 0d, 0b]; +Td0[x] = Si[x].[0e, 09, 0d, 0b]; +Td1[x] = Si[x].[0b, 0e, 09, 0d]; +Td2[x] = Si[x].[0d, 0b, 0e, 09]; +Td3[x] = Si[x].[09, 0d, 0b, 0e]; +Td4[x] = Si[x].[01]; +*/ +#define Td0 (u32)((u64*)((u8*)Td+0)) +#define Td1 (u32)((u64*)((u8*)Td+3)) +#define Td2 (u32)((u64*)((u8*)Td+2)) +#define Td3 (u32)((u64*)((u8*)Td+1)) + +static const u64 Te[256] = { + U64(0xa56363c6a56363c6), U64(0x847c7cf8847c7cf8), + U64(0x997777ee997777ee), U64(0x8d7b7bf68d7b7bf6), + U64(0x0df2f2ff0df2f2ff), U64(0xbd6b6bd6bd6b6bd6), + U64(0xb16f6fdeb16f6fde), U64(0x54c5c59154c5c591), + U64(0x5030306050303060), U64(0x0301010203010102), + U64(0xa96767cea96767ce), U64(0x7d2b2b567d2b2b56), + U64(0x19fefee719fefee7), U64(0x62d7d7b562d7d7b5), + U64(0xe6abab4de6abab4d), U64(0x9a7676ec9a7676ec), + U64(0x45caca8f45caca8f), U64(0x9d82821f9d82821f), + U64(0x40c9c98940c9c989), U64(0x877d7dfa877d7dfa), + U64(0x15fafaef15fafaef), U64(0xeb5959b2eb5959b2), + U64(0xc947478ec947478e), U64(0x0bf0f0fb0bf0f0fb), + U64(0xecadad41ecadad41), U64(0x67d4d4b367d4d4b3), + U64(0xfda2a25ffda2a25f), U64(0xeaafaf45eaafaf45), + U64(0xbf9c9c23bf9c9c23), U64(0xf7a4a453f7a4a453), + U64(0x967272e4967272e4), U64(0x5bc0c09b5bc0c09b), + U64(0xc2b7b775c2b7b775), U64(0x1cfdfde11cfdfde1), + U64(0xae93933dae93933d), U64(0x6a26264c6a26264c), + U64(0x5a36366c5a36366c), U64(0x413f3f7e413f3f7e), + U64(0x02f7f7f502f7f7f5), U64(0x4fcccc834fcccc83), + U64(0x5c3434685c343468), U64(0xf4a5a551f4a5a551), + U64(0x34e5e5d134e5e5d1), U64(0x08f1f1f908f1f1f9), + U64(0x937171e2937171e2), U64(0x73d8d8ab73d8d8ab), + U64(0x5331316253313162), U64(0x3f15152a3f15152a), + U64(0x0c0404080c040408), U64(0x52c7c79552c7c795), + U64(0x6523234665232346), U64(0x5ec3c39d5ec3c39d), + U64(0x2818183028181830), U64(0xa1969637a1969637), + U64(0x0f05050a0f05050a), U64(0xb59a9a2fb59a9a2f), + U64(0x0907070e0907070e), U64(0x3612122436121224), + U64(0x9b80801b9b80801b), U64(0x3de2e2df3de2e2df), + U64(0x26ebebcd26ebebcd), U64(0x6927274e6927274e), + U64(0xcdb2b27fcdb2b27f), U64(0x9f7575ea9f7575ea), + U64(0x1b0909121b090912), U64(0x9e83831d9e83831d), + U64(0x742c2c58742c2c58), U64(0x2e1a1a342e1a1a34), + U64(0x2d1b1b362d1b1b36), U64(0xb26e6edcb26e6edc), + U64(0xee5a5ab4ee5a5ab4), U64(0xfba0a05bfba0a05b), + U64(0xf65252a4f65252a4), U64(0x4d3b3b764d3b3b76), + U64(0x61d6d6b761d6d6b7), U64(0xceb3b37dceb3b37d), + U64(0x7b2929527b292952), U64(0x3ee3e3dd3ee3e3dd), + U64(0x712f2f5e712f2f5e), U64(0x9784841397848413), + U64(0xf55353a6f55353a6), U64(0x68d1d1b968d1d1b9), + U64(0x0000000000000000), U64(0x2cededc12cededc1), + U64(0x6020204060202040), U64(0x1ffcfce31ffcfce3), + U64(0xc8b1b179c8b1b179), U64(0xed5b5bb6ed5b5bb6), + U64(0xbe6a6ad4be6a6ad4), U64(0x46cbcb8d46cbcb8d), + U64(0xd9bebe67d9bebe67), U64(0x4b3939724b393972), + U64(0xde4a4a94de4a4a94), U64(0xd44c4c98d44c4c98), + U64(0xe85858b0e85858b0), U64(0x4acfcf854acfcf85), + U64(0x6bd0d0bb6bd0d0bb), U64(0x2aefefc52aefefc5), + U64(0xe5aaaa4fe5aaaa4f), U64(0x16fbfbed16fbfbed), + U64(0xc5434386c5434386), U64(0xd74d4d9ad74d4d9a), + U64(0x5533336655333366), U64(0x9485851194858511), + U64(0xcf45458acf45458a), U64(0x10f9f9e910f9f9e9), + U64(0x0602020406020204), U64(0x817f7ffe817f7ffe), + U64(0xf05050a0f05050a0), U64(0x443c3c78443c3c78), + U64(0xba9f9f25ba9f9f25), U64(0xe3a8a84be3a8a84b), + U64(0xf35151a2f35151a2), U64(0xfea3a35dfea3a35d), + U64(0xc0404080c0404080), U64(0x8a8f8f058a8f8f05), + U64(0xad92923fad92923f), U64(0xbc9d9d21bc9d9d21), + U64(0x4838387048383870), U64(0x04f5f5f104f5f5f1), + U64(0xdfbcbc63dfbcbc63), U64(0xc1b6b677c1b6b677), + U64(0x75dadaaf75dadaaf), U64(0x6321214263212142), + U64(0x3010102030101020), U64(0x1affffe51affffe5), + U64(0x0ef3f3fd0ef3f3fd), U64(0x6dd2d2bf6dd2d2bf), + U64(0x4ccdcd814ccdcd81), U64(0x140c0c18140c0c18), + U64(0x3513132635131326), U64(0x2fececc32fececc3), + U64(0xe15f5fbee15f5fbe), U64(0xa2979735a2979735), + U64(0xcc444488cc444488), U64(0x3917172e3917172e), + U64(0x57c4c49357c4c493), U64(0xf2a7a755f2a7a755), + U64(0x827e7efc827e7efc), U64(0x473d3d7a473d3d7a), + U64(0xac6464c8ac6464c8), U64(0xe75d5dbae75d5dba), + U64(0x2b1919322b191932), U64(0x957373e6957373e6), + U64(0xa06060c0a06060c0), U64(0x9881811998818119), + U64(0xd14f4f9ed14f4f9e), U64(0x7fdcdca37fdcdca3), + U64(0x6622224466222244), U64(0x7e2a2a547e2a2a54), + U64(0xab90903bab90903b), U64(0x8388880b8388880b), + U64(0xca46468cca46468c), U64(0x29eeeec729eeeec7), + U64(0xd3b8b86bd3b8b86b), U64(0x3c1414283c141428), + U64(0x79dedea779dedea7), U64(0xe25e5ebce25e5ebc), + U64(0x1d0b0b161d0b0b16), U64(0x76dbdbad76dbdbad), + U64(0x3be0e0db3be0e0db), U64(0x5632326456323264), + U64(0x4e3a3a744e3a3a74), U64(0x1e0a0a141e0a0a14), + U64(0xdb494992db494992), U64(0x0a06060c0a06060c), + U64(0x6c2424486c242448), U64(0xe45c5cb8e45c5cb8), + U64(0x5dc2c29f5dc2c29f), U64(0x6ed3d3bd6ed3d3bd), + U64(0xefacac43efacac43), U64(0xa66262c4a66262c4), + U64(0xa8919139a8919139), U64(0xa4959531a4959531), + U64(0x37e4e4d337e4e4d3), U64(0x8b7979f28b7979f2), + U64(0x32e7e7d532e7e7d5), U64(0x43c8c88b43c8c88b), + U64(0x5937376e5937376e), U64(0xb76d6ddab76d6dda), + U64(0x8c8d8d018c8d8d01), U64(0x64d5d5b164d5d5b1), + U64(0xd24e4e9cd24e4e9c), U64(0xe0a9a949e0a9a949), + U64(0xb46c6cd8b46c6cd8), U64(0xfa5656acfa5656ac), + U64(0x07f4f4f307f4f4f3), U64(0x25eaeacf25eaeacf), + U64(0xaf6565caaf6565ca), U64(0x8e7a7af48e7a7af4), + U64(0xe9aeae47e9aeae47), U64(0x1808081018080810), + U64(0xd5baba6fd5baba6f), U64(0x887878f0887878f0), + U64(0x6f25254a6f25254a), U64(0x722e2e5c722e2e5c), + U64(0x241c1c38241c1c38), U64(0xf1a6a657f1a6a657), + U64(0xc7b4b473c7b4b473), U64(0x51c6c69751c6c697), + U64(0x23e8e8cb23e8e8cb), U64(0x7cdddda17cdddda1), + U64(0x9c7474e89c7474e8), U64(0x211f1f3e211f1f3e), + U64(0xdd4b4b96dd4b4b96), U64(0xdcbdbd61dcbdbd61), + U64(0x868b8b0d868b8b0d), U64(0x858a8a0f858a8a0f), + U64(0x907070e0907070e0), U64(0x423e3e7c423e3e7c), + U64(0xc4b5b571c4b5b571), U64(0xaa6666ccaa6666cc), + U64(0xd8484890d8484890), U64(0x0503030605030306), + U64(0x01f6f6f701f6f6f7), U64(0x120e0e1c120e0e1c), + U64(0xa36161c2a36161c2), U64(0x5f35356a5f35356a), + U64(0xf95757aef95757ae), U64(0xd0b9b969d0b9b969), + U64(0x9186861791868617), U64(0x58c1c19958c1c199), + U64(0x271d1d3a271d1d3a), U64(0xb99e9e27b99e9e27), + U64(0x38e1e1d938e1e1d9), U64(0x13f8f8eb13f8f8eb), + U64(0xb398982bb398982b), U64(0x3311112233111122), + U64(0xbb6969d2bb6969d2), U64(0x70d9d9a970d9d9a9), + U64(0x898e8e07898e8e07), U64(0xa7949433a7949433), + U64(0xb69b9b2db69b9b2d), U64(0x221e1e3c221e1e3c), + U64(0x9287871592878715), U64(0x20e9e9c920e9e9c9), + U64(0x49cece8749cece87), U64(0xff5555aaff5555aa), + U64(0x7828285078282850), U64(0x7adfdfa57adfdfa5), + U64(0x8f8c8c038f8c8c03), U64(0xf8a1a159f8a1a159), + U64(0x8089890980898909), U64(0x170d0d1a170d0d1a), + U64(0xdabfbf65dabfbf65), U64(0x31e6e6d731e6e6d7), + U64(0xc6424284c6424284), U64(0xb86868d0b86868d0), + U64(0xc3414182c3414182), U64(0xb0999929b0999929), + U64(0x772d2d5a772d2d5a), U64(0x110f0f1e110f0f1e), + U64(0xcbb0b07bcbb0b07b), U64(0xfc5454a8fc5454a8), + U64(0xd6bbbb6dd6bbbb6d), U64(0x3a16162c3a16162c) +}; + +static const u8 Te4[256] = { + 0x63U, 0x7cU, 0x77U, 0x7bU, 0xf2U, 0x6bU, 0x6fU, 0xc5U, + 0x30U, 0x01U, 0x67U, 0x2bU, 0xfeU, 0xd7U, 0xabU, 0x76U, + 0xcaU, 0x82U, 0xc9U, 0x7dU, 0xfaU, 0x59U, 0x47U, 0xf0U, + 0xadU, 0xd4U, 0xa2U, 0xafU, 0x9cU, 0xa4U, 0x72U, 0xc0U, + 0xb7U, 0xfdU, 0x93U, 0x26U, 0x36U, 0x3fU, 0xf7U, 0xccU, + 0x34U, 0xa5U, 0xe5U, 0xf1U, 0x71U, 0xd8U, 0x31U, 0x15U, + 0x04U, 0xc7U, 0x23U, 0xc3U, 0x18U, 0x96U, 0x05U, 0x9aU, + 0x07U, 0x12U, 0x80U, 0xe2U, 0xebU, 0x27U, 0xb2U, 0x75U, + 0x09U, 0x83U, 0x2cU, 0x1aU, 0x1bU, 0x6eU, 0x5aU, 0xa0U, + 0x52U, 0x3bU, 0xd6U, 0xb3U, 0x29U, 0xe3U, 0x2fU, 0x84U, + 0x53U, 0xd1U, 0x00U, 0xedU, 0x20U, 0xfcU, 0xb1U, 0x5bU, + 0x6aU, 0xcbU, 0xbeU, 0x39U, 0x4aU, 0x4cU, 0x58U, 0xcfU, + 0xd0U, 0xefU, 0xaaU, 0xfbU, 0x43U, 0x4dU, 0x33U, 0x85U, + 0x45U, 0xf9U, 0x02U, 0x7fU, 0x50U, 0x3cU, 0x9fU, 0xa8U, + 0x51U, 0xa3U, 0x40U, 0x8fU, 0x92U, 0x9dU, 0x38U, 0xf5U, + 0xbcU, 0xb6U, 0xdaU, 0x21U, 0x10U, 0xffU, 0xf3U, 0xd2U, + 0xcdU, 0x0cU, 0x13U, 0xecU, 0x5fU, 0x97U, 0x44U, 0x17U, + 0xc4U, 0xa7U, 0x7eU, 0x3dU, 0x64U, 0x5dU, 0x19U, 0x73U, + 0x60U, 0x81U, 0x4fU, 0xdcU, 0x22U, 0x2aU, 0x90U, 0x88U, + 0x46U, 0xeeU, 0xb8U, 0x14U, 0xdeU, 0x5eU, 0x0bU, 0xdbU, + 0xe0U, 0x32U, 0x3aU, 0x0aU, 0x49U, 0x06U, 0x24U, 0x5cU, + 0xc2U, 0xd3U, 0xacU, 0x62U, 0x91U, 0x95U, 0xe4U, 0x79U, + 0xe7U, 0xc8U, 0x37U, 0x6dU, 0x8dU, 0xd5U, 0x4eU, 0xa9U, + 0x6cU, 0x56U, 0xf4U, 0xeaU, 0x65U, 0x7aU, 0xaeU, 0x08U, + 0xbaU, 0x78U, 0x25U, 0x2eU, 0x1cU, 0xa6U, 0xb4U, 0xc6U, + 0xe8U, 0xddU, 0x74U, 0x1fU, 0x4bU, 0xbdU, 0x8bU, 0x8aU, + 0x70U, 0x3eU, 0xb5U, 0x66U, 0x48U, 0x03U, 0xf6U, 0x0eU, + 0x61U, 0x35U, 0x57U, 0xb9U, 0x86U, 0xc1U, 0x1dU, 0x9eU, + 0xe1U, 0xf8U, 0x98U, 0x11U, 0x69U, 0xd9U, 0x8eU, 0x94U, + 0x9bU, 0x1eU, 0x87U, 0xe9U, 0xceU, 0x55U, 0x28U, 0xdfU, + 0x8cU, 0xa1U, 0x89U, 0x0dU, 0xbfU, 0xe6U, 0x42U, 0x68U, + 0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U +}; + +static const u64 Td[256] = { + U64(0x50a7f45150a7f451), U64(0x5365417e5365417e), + U64(0xc3a4171ac3a4171a), U64(0x965e273a965e273a), + U64(0xcb6bab3bcb6bab3b), U64(0xf1459d1ff1459d1f), + U64(0xab58faacab58faac), U64(0x9303e34b9303e34b), + U64(0x55fa302055fa3020), U64(0xf66d76adf66d76ad), + U64(0x9176cc889176cc88), U64(0x254c02f5254c02f5), + U64(0xfcd7e54ffcd7e54f), U64(0xd7cb2ac5d7cb2ac5), + U64(0x8044352680443526), U64(0x8fa362b58fa362b5), + U64(0x495ab1de495ab1de), U64(0x671bba25671bba25), + U64(0x980eea45980eea45), U64(0xe1c0fe5de1c0fe5d), + U64(0x02752fc302752fc3), U64(0x12f04c8112f04c81), + U64(0xa397468da397468d), U64(0xc6f9d36bc6f9d36b), + U64(0xe75f8f03e75f8f03), U64(0x959c9215959c9215), + U64(0xeb7a6dbfeb7a6dbf), U64(0xda595295da595295), + U64(0x2d83bed42d83bed4), U64(0xd3217458d3217458), + U64(0x2969e0492969e049), U64(0x44c8c98e44c8c98e), + U64(0x6a89c2756a89c275), U64(0x78798ef478798ef4), + U64(0x6b3e58996b3e5899), U64(0xdd71b927dd71b927), + U64(0xb64fe1beb64fe1be), U64(0x17ad88f017ad88f0), + U64(0x66ac20c966ac20c9), U64(0xb43ace7db43ace7d), + U64(0x184adf63184adf63), U64(0x82311ae582311ae5), + U64(0x6033519760335197), U64(0x457f5362457f5362), + U64(0xe07764b1e07764b1), U64(0x84ae6bbb84ae6bbb), + U64(0x1ca081fe1ca081fe), U64(0x942b08f9942b08f9), + U64(0x5868487058684870), U64(0x19fd458f19fd458f), + U64(0x876cde94876cde94), U64(0xb7f87b52b7f87b52), + U64(0x23d373ab23d373ab), U64(0xe2024b72e2024b72), + U64(0x578f1fe3578f1fe3), U64(0x2aab55662aab5566), + U64(0x0728ebb20728ebb2), U64(0x03c2b52f03c2b52f), + U64(0x9a7bc5869a7bc586), U64(0xa50837d3a50837d3), + U64(0xf2872830f2872830), U64(0xb2a5bf23b2a5bf23), + U64(0xba6a0302ba6a0302), U64(0x5c8216ed5c8216ed), + U64(0x2b1ccf8a2b1ccf8a), U64(0x92b479a792b479a7), + U64(0xf0f207f3f0f207f3), U64(0xa1e2694ea1e2694e), + U64(0xcdf4da65cdf4da65), U64(0xd5be0506d5be0506), + U64(0x1f6234d11f6234d1), U64(0x8afea6c48afea6c4), + U64(0x9d532e349d532e34), U64(0xa055f3a2a055f3a2), + U64(0x32e18a0532e18a05), U64(0x75ebf6a475ebf6a4), + U64(0x39ec830b39ec830b), U64(0xaaef6040aaef6040), + U64(0x069f715e069f715e), U64(0x51106ebd51106ebd), + U64(0xf98a213ef98a213e), U64(0x3d06dd963d06dd96), + U64(0xae053eddae053edd), U64(0x46bde64d46bde64d), + U64(0xb58d5491b58d5491), U64(0x055dc471055dc471), + U64(0x6fd406046fd40604), U64(0xff155060ff155060), + U64(0x24fb981924fb9819), U64(0x97e9bdd697e9bdd6), + U64(0xcc434089cc434089), U64(0x779ed967779ed967), + U64(0xbd42e8b0bd42e8b0), U64(0x888b8907888b8907), + U64(0x385b19e7385b19e7), U64(0xdbeec879dbeec879), + U64(0x470a7ca1470a7ca1), U64(0xe90f427ce90f427c), + U64(0xc91e84f8c91e84f8), U64(0x0000000000000000), + U64(0x8386800983868009), U64(0x48ed2b3248ed2b32), + U64(0xac70111eac70111e), U64(0x4e725a6c4e725a6c), + U64(0xfbff0efdfbff0efd), U64(0x5638850f5638850f), + U64(0x1ed5ae3d1ed5ae3d), U64(0x27392d3627392d36), + U64(0x64d90f0a64d90f0a), U64(0x21a65c6821a65c68), + U64(0xd1545b9bd1545b9b), U64(0x3a2e36243a2e3624), + U64(0xb1670a0cb1670a0c), U64(0x0fe757930fe75793), + U64(0xd296eeb4d296eeb4), U64(0x9e919b1b9e919b1b), + U64(0x4fc5c0804fc5c080), U64(0xa220dc61a220dc61), + U64(0x694b775a694b775a), U64(0x161a121c161a121c), + U64(0x0aba93e20aba93e2), U64(0xe52aa0c0e52aa0c0), + U64(0x43e0223c43e0223c), U64(0x1d171b121d171b12), + U64(0x0b0d090e0b0d090e), U64(0xadc78bf2adc78bf2), + U64(0xb9a8b62db9a8b62d), U64(0xc8a91e14c8a91e14), + U64(0x8519f1578519f157), U64(0x4c0775af4c0775af), + U64(0xbbdd99eebbdd99ee), U64(0xfd607fa3fd607fa3), + U64(0x9f2601f79f2601f7), U64(0xbcf5725cbcf5725c), + U64(0xc53b6644c53b6644), U64(0x347efb5b347efb5b), + U64(0x7629438b7629438b), U64(0xdcc623cbdcc623cb), + U64(0x68fcedb668fcedb6), U64(0x63f1e4b863f1e4b8), + U64(0xcadc31d7cadc31d7), U64(0x1085634210856342), + U64(0x4022971340229713), U64(0x2011c6842011c684), + U64(0x7d244a857d244a85), U64(0xf83dbbd2f83dbbd2), + U64(0x1132f9ae1132f9ae), U64(0x6da129c76da129c7), + U64(0x4b2f9e1d4b2f9e1d), U64(0xf330b2dcf330b2dc), + U64(0xec52860dec52860d), U64(0xd0e3c177d0e3c177), + U64(0x6c16b32b6c16b32b), U64(0x99b970a999b970a9), + U64(0xfa489411fa489411), U64(0x2264e9472264e947), + U64(0xc48cfca8c48cfca8), U64(0x1a3ff0a01a3ff0a0), + U64(0xd82c7d56d82c7d56), U64(0xef903322ef903322), + U64(0xc74e4987c74e4987), U64(0xc1d138d9c1d138d9), + U64(0xfea2ca8cfea2ca8c), U64(0x360bd498360bd498), + U64(0xcf81f5a6cf81f5a6), U64(0x28de7aa528de7aa5), + U64(0x268eb7da268eb7da), U64(0xa4bfad3fa4bfad3f), + U64(0xe49d3a2ce49d3a2c), U64(0x0d9278500d927850), + U64(0x9bcc5f6a9bcc5f6a), U64(0x62467e5462467e54), + U64(0xc2138df6c2138df6), U64(0xe8b8d890e8b8d890), + U64(0x5ef7392e5ef7392e), U64(0xf5afc382f5afc382), + U64(0xbe805d9fbe805d9f), U64(0x7c93d0697c93d069), + U64(0xa92dd56fa92dd56f), U64(0xb31225cfb31225cf), + U64(0x3b99acc83b99acc8), U64(0xa77d1810a77d1810), + U64(0x6e639ce86e639ce8), U64(0x7bbb3bdb7bbb3bdb), + U64(0x097826cd097826cd), U64(0xf418596ef418596e), + U64(0x01b79aec01b79aec), U64(0xa89a4f83a89a4f83), + U64(0x656e95e6656e95e6), U64(0x7ee6ffaa7ee6ffaa), + U64(0x08cfbc2108cfbc21), U64(0xe6e815efe6e815ef), + U64(0xd99be7bad99be7ba), U64(0xce366f4ace366f4a), + U64(0xd4099fead4099fea), U64(0xd67cb029d67cb029), + U64(0xafb2a431afb2a431), U64(0x31233f2a31233f2a), + U64(0x3094a5c63094a5c6), U64(0xc066a235c066a235), + U64(0x37bc4e7437bc4e74), U64(0xa6ca82fca6ca82fc), + U64(0xb0d090e0b0d090e0), U64(0x15d8a73315d8a733), + U64(0x4a9804f14a9804f1), U64(0xf7daec41f7daec41), + U64(0x0e50cd7f0e50cd7f), U64(0x2ff691172ff69117), + U64(0x8dd64d768dd64d76), U64(0x4db0ef434db0ef43), + U64(0x544daacc544daacc), U64(0xdf0496e4df0496e4), + U64(0xe3b5d19ee3b5d19e), U64(0x1b886a4c1b886a4c), + U64(0xb81f2cc1b81f2cc1), U64(0x7f5165467f516546), + U64(0x04ea5e9d04ea5e9d), U64(0x5d358c015d358c01), + U64(0x737487fa737487fa), U64(0x2e410bfb2e410bfb), + U64(0x5a1d67b35a1d67b3), U64(0x52d2db9252d2db92), + U64(0x335610e9335610e9), U64(0x1347d66d1347d66d), + U64(0x8c61d79a8c61d79a), U64(0x7a0ca1377a0ca137), + U64(0x8e14f8598e14f859), U64(0x893c13eb893c13eb), + U64(0xee27a9ceee27a9ce), U64(0x35c961b735c961b7), + U64(0xede51ce1ede51ce1), U64(0x3cb1477a3cb1477a), + U64(0x59dfd29c59dfd29c), U64(0x3f73f2553f73f255), + U64(0x79ce141879ce1418), U64(0xbf37c773bf37c773), + U64(0xeacdf753eacdf753), U64(0x5baafd5f5baafd5f), + U64(0x146f3ddf146f3ddf), U64(0x86db447886db4478), + U64(0x81f3afca81f3afca), U64(0x3ec468b93ec468b9), + U64(0x2c3424382c342438), U64(0x5f40a3c25f40a3c2), + U64(0x72c31d1672c31d16), U64(0x0c25e2bc0c25e2bc), + U64(0x8b493c288b493c28), U64(0x41950dff41950dff), + U64(0x7101a8397101a839), U64(0xdeb30c08deb30c08), + U64(0x9ce4b4d89ce4b4d8), U64(0x90c1566490c15664), + U64(0x6184cb7b6184cb7b), U64(0x70b632d570b632d5), + U64(0x745c6c48745c6c48), U64(0x4257b8d04257b8d0) +}; +static const u8 Td4[256] = { + 0x52U, 0x09U, 0x6aU, 0xd5U, 0x30U, 0x36U, 0xa5U, 0x38U, + 0xbfU, 0x40U, 0xa3U, 0x9eU, 0x81U, 0xf3U, 0xd7U, 0xfbU, + 0x7cU, 0xe3U, 0x39U, 0x82U, 0x9bU, 0x2fU, 0xffU, 0x87U, + 0x34U, 0x8eU, 0x43U, 0x44U, 0xc4U, 0xdeU, 0xe9U, 0xcbU, + 0x54U, 0x7bU, 0x94U, 0x32U, 0xa6U, 0xc2U, 0x23U, 0x3dU, + 0xeeU, 0x4cU, 0x95U, 0x0bU, 0x42U, 0xfaU, 0xc3U, 0x4eU, + 0x08U, 0x2eU, 0xa1U, 0x66U, 0x28U, 0xd9U, 0x24U, 0xb2U, + 0x76U, 0x5bU, 0xa2U, 0x49U, 0x6dU, 0x8bU, 0xd1U, 0x25U, + 0x72U, 0xf8U, 0xf6U, 0x64U, 0x86U, 0x68U, 0x98U, 0x16U, + 0xd4U, 0xa4U, 0x5cU, 0xccU, 0x5dU, 0x65U, 0xb6U, 0x92U, + 0x6cU, 0x70U, 0x48U, 0x50U, 0xfdU, 0xedU, 0xb9U, 0xdaU, + 0x5eU, 0x15U, 0x46U, 0x57U, 0xa7U, 0x8dU, 0x9dU, 0x84U, + 0x90U, 0xd8U, 0xabU, 0x00U, 0x8cU, 0xbcU, 0xd3U, 0x0aU, + 0xf7U, 0xe4U, 0x58U, 0x05U, 0xb8U, 0xb3U, 0x45U, 0x06U, + 0xd0U, 0x2cU, 0x1eU, 0x8fU, 0xcaU, 0x3fU, 0x0fU, 0x02U, + 0xc1U, 0xafU, 0xbdU, 0x03U, 0x01U, 0x13U, 0x8aU, 0x6bU, + 0x3aU, 0x91U, 0x11U, 0x41U, 0x4fU, 0x67U, 0xdcU, 0xeaU, + 0x97U, 0xf2U, 0xcfU, 0xceU, 0xf0U, 0xb4U, 0xe6U, 0x73U, + 0x96U, 0xacU, 0x74U, 0x22U, 0xe7U, 0xadU, 0x35U, 0x85U, + 0xe2U, 0xf9U, 0x37U, 0xe8U, 0x1cU, 0x75U, 0xdfU, 0x6eU, + 0x47U, 0xf1U, 0x1aU, 0x71U, 0x1dU, 0x29U, 0xc5U, 0x89U, + 0x6fU, 0xb7U, 0x62U, 0x0eU, 0xaaU, 0x18U, 0xbeU, 0x1bU, + 0xfcU, 0x56U, 0x3eU, 0x4bU, 0xc6U, 0xd2U, 0x79U, 0x20U, + 0x9aU, 0xdbU, 0xc0U, 0xfeU, 0x78U, 0xcdU, 0x5aU, 0xf4U, + 0x1fU, 0xddU, 0xa8U, 0x33U, 0x88U, 0x07U, 0xc7U, 0x31U, + 0xb1U, 0x12U, 0x10U, 0x59U, 0x27U, 0x80U, 0xecU, 0x5fU, + 0x60U, 0x51U, 0x7fU, 0xa9U, 0x19U, 0xb5U, 0x4aU, 0x0dU, + 0x2dU, 0xe5U, 0x7aU, 0x9fU, 0x93U, 0xc9U, 0x9cU, 0xefU, + 0xa0U, 0xe0U, 0x3bU, 0x4dU, 0xaeU, 0x2aU, 0xf5U, 0xb0U, + 0xc8U, 0xebU, 0xbbU, 0x3cU, 0x83U, 0x53U, 0x99U, 0x61U, + 0x17U, 0x2bU, 0x04U, 0x7eU, 0xbaU, 0x77U, 0xd6U, 0x26U, + 0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU +}; + +static const u32 rcon[] = { + 0x00000001U, 0x00000002U, 0x00000004U, 0x00000008U, + 0x00000010U, 0x00000020U, 0x00000040U, 0x00000080U, + 0x0000001bU, 0x00000036U, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */ +}; + +/** + * Expand the cipher key into the encryption key schedule. + */ +int AES_set_encrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ + + u32 *rk; + int i = 0; + u32 temp; + + if (!userKey || !key) + return -1; + if (bits != 128 && bits != 192 && bits != 256) + return -2; + + rk = key->rd_key; + + if (bits==128) + key->rounds = 10; + else if (bits==192) + key->rounds = 12; + else + key->rounds = 14; + + rk[0] = GETU32(userKey ); + rk[1] = GETU32(userKey + 4); + rk[2] = GETU32(userKey + 8); + rk[3] = GETU32(userKey + 12); + if (bits == 128) { + while (1) { + temp = rk[3]; + rk[4] = rk[0] ^ + ((u32)Te4[(temp >> 8) & 0xff] ) ^ + ((u32)Te4[(temp >> 16) & 0xff] << 8) ^ + ((u32)Te4[(temp >> 24) ] << 16) ^ + ((u32)Te4[(temp ) & 0xff] << 24) ^ + rcon[i]; + rk[5] = rk[1] ^ rk[4]; + rk[6] = rk[2] ^ rk[5]; + rk[7] = rk[3] ^ rk[6]; + if (++i == 10) { + return 0; + } + rk += 4; + } + } + rk[4] = GETU32(userKey + 16); + rk[5] = GETU32(userKey + 20); + if (bits == 192) { + while (1) { + temp = rk[ 5]; + rk[ 6] = rk[ 0] ^ + ((u32)Te4[(temp >> 8) & 0xff] ) ^ + ((u32)Te4[(temp >> 16) & 0xff] << 8) ^ + ((u32)Te4[(temp >> 24) ] << 16) ^ + ((u32)Te4[(temp ) & 0xff] << 24) ^ + rcon[i]; + rk[ 7] = rk[ 1] ^ rk[ 6]; + rk[ 8] = rk[ 2] ^ rk[ 7]; + rk[ 9] = rk[ 3] ^ rk[ 8]; + if (++i == 8) { + return 0; + } + rk[10] = rk[ 4] ^ rk[ 9]; + rk[11] = rk[ 5] ^ rk[10]; + rk += 6; + } + } + rk[6] = GETU32(userKey + 24); + rk[7] = GETU32(userKey + 28); + if (bits == 256) { + while (1) { + temp = rk[ 7]; + rk[ 8] = rk[ 0] ^ + ((u32)Te4[(temp >> 8) & 0xff] ) ^ + ((u32)Te4[(temp >> 16) & 0xff] << 8) ^ + ((u32)Te4[(temp >> 24) ] << 16) ^ + ((u32)Te4[(temp ) & 0xff] << 24) ^ + rcon[i]; + rk[ 9] = rk[ 1] ^ rk[ 8]; + rk[10] = rk[ 2] ^ rk[ 9]; + rk[11] = rk[ 3] ^ rk[10]; + if (++i == 7) { + return 0; + } + temp = rk[11]; + rk[12] = rk[ 4] ^ + ((u32)Te4[(temp ) & 0xff] ) ^ + ((u32)Te4[(temp >> 8) & 0xff] << 8) ^ + ((u32)Te4[(temp >> 16) & 0xff] << 16) ^ + ((u32)Te4[(temp >> 24) ] << 24); + rk[13] = rk[ 5] ^ rk[12]; + rk[14] = rk[ 6] ^ rk[13]; + rk[15] = rk[ 7] ^ rk[14]; + + rk += 8; + } + } + return 0; +} + +/** + * Expand the cipher key into the decryption key schedule. + */ +int AES_set_decrypt_key(const unsigned char *userKey, const int bits, + AES_KEY *key) +{ + + u32 *rk; + int i, j, status; + u32 temp; + + /* first, start with an encryption schedule */ + status = AES_set_encrypt_key(userKey, bits, key); + if (status < 0) + return status; + + rk = key->rd_key; + + /* invert the order of the round keys: */ + for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) { + temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp; + temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp; + temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp; + temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp; + } + /* apply the inverse MixColumn transform to all round keys but the first and the last: */ + for (i = 1; i < (key->rounds); i++) { + rk += 4; +#if 1 + for (j = 0; j < 4; j++) { + u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m; + + tp1 = rk[j]; + m = tp1 & 0x80808080; + tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + m = tp2 & 0x80808080; + tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + m = tp4 & 0x80808080; + tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + tp9 = tp8 ^ tp1; + tpb = tp9 ^ tp2; + tpd = tp9 ^ tp4; + tpe = tp8 ^ tp4 ^ tp2; +#if defined(ROTATE) + rk[j] = tpe ^ ROTATE(tpd,16) ^ + ROTATE(tp9,8) ^ ROTATE(tpb,24); +#else + rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ + (tp9 >> 24) ^ (tp9 << 8) ^ + (tpb >> 8) ^ (tpb << 24); +#endif + } +#else + rk[0] = + Td0[Te2[(rk[0] ) & 0xff] & 0xff] ^ + Td1[Te2[(rk[0] >> 8) & 0xff] & 0xff] ^ + Td2[Te2[(rk[0] >> 16) & 0xff] & 0xff] ^ + Td3[Te2[(rk[0] >> 24) ] & 0xff]; + rk[1] = + Td0[Te2[(rk[1] ) & 0xff] & 0xff] ^ + Td1[Te2[(rk[1] >> 8) & 0xff] & 0xff] ^ + Td2[Te2[(rk[1] >> 16) & 0xff] & 0xff] ^ + Td3[Te2[(rk[1] >> 24) ] & 0xff]; + rk[2] = + Td0[Te2[(rk[2] ) & 0xff] & 0xff] ^ + Td1[Te2[(rk[2] >> 8) & 0xff] & 0xff] ^ + Td2[Te2[(rk[2] >> 16) & 0xff] & 0xff] ^ + Td3[Te2[(rk[2] >> 24) ] & 0xff]; + rk[3] = + Td0[Te2[(rk[3] ) & 0xff] & 0xff] ^ + Td1[Te2[(rk[3] >> 8) & 0xff] & 0xff] ^ + Td2[Te2[(rk[3] >> 16) & 0xff] & 0xff] ^ + Td3[Te2[(rk[3] >> 24) ] & 0xff]; +#endif + } + return 0; +} + +/* + * Encrypt a single block + * in and out can overlap + */ +void AES_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key) +{ + + const u32 *rk; + u32 s0, s1, s2, s3, t[4]; + int r; + + assert(in && out && key); + rk = key->rd_key; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(in ) ^ rk[0]; + s1 = GETU32(in + 4) ^ rk[1]; + s2 = GETU32(in + 8) ^ rk[2]; + s3 = GETU32(in + 12) ^ rk[3]; + +#if defined(AES_COMPACT_IN_OUTER_ROUNDS) + prefetch256(Te4); + + t[0] = (u32)Te4[(s0 ) & 0xff] ^ + (u32)Te4[(s1 >> 8) & 0xff] << 8 ^ + (u32)Te4[(s2 >> 16) & 0xff] << 16 ^ + (u32)Te4[(s3 >> 24) ] << 24; + t[1] = (u32)Te4[(s1 ) & 0xff] ^ + (u32)Te4[(s2 >> 8) & 0xff] << 8 ^ + (u32)Te4[(s3 >> 16) & 0xff] << 16 ^ + (u32)Te4[(s0 >> 24) ] << 24; + t[2] = (u32)Te4[(s2 ) & 0xff] ^ + (u32)Te4[(s3 >> 8) & 0xff] << 8 ^ + (u32)Te4[(s0 >> 16) & 0xff] << 16 ^ + (u32)Te4[(s1 >> 24) ] << 24; + t[3] = (u32)Te4[(s3 ) & 0xff] ^ + (u32)Te4[(s0 >> 8) & 0xff] << 8 ^ + (u32)Te4[(s1 >> 16) & 0xff] << 16 ^ + (u32)Te4[(s2 >> 24) ] << 24; + + /* now do the linear transform using words */ + { int i; + u32 r0, r1, r2; + + for (i = 0; i < 4; i++) { + r0 = t[i]; + r1 = r0 & 0x80808080; + r2 = ((r0 & 0x7f7f7f7f) << 1) ^ + ((r1 - (r1 >> 7)) & 0x1b1b1b1b); +#if defined(ROTATE) + t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^ + ROTATE(r0,16) ^ ROTATE(r0,8); +#else + t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^ + (r0 << 16) ^ (r0 >> 16) ^ + (r0 << 8) ^ (r0 >> 24); +#endif + t[i] ^= rk[4+i]; + } + } +#else + t[0] = Te0[(s0 ) & 0xff] ^ + Te1[(s1 >> 8) & 0xff] ^ + Te2[(s2 >> 16) & 0xff] ^ + Te3[(s3 >> 24) ] ^ + rk[4]; + t[1] = Te0[(s1 ) & 0xff] ^ + Te1[(s2 >> 8) & 0xff] ^ + Te2[(s3 >> 16) & 0xff] ^ + Te3[(s0 >> 24) ] ^ + rk[5]; + t[2] = Te0[(s2 ) & 0xff] ^ + Te1[(s3 >> 8) & 0xff] ^ + Te2[(s0 >> 16) & 0xff] ^ + Te3[(s1 >> 24) ] ^ + rk[6]; + t[3] = Te0[(s3 ) & 0xff] ^ + Te1[(s0 >> 8) & 0xff] ^ + Te2[(s1 >> 16) & 0xff] ^ + Te3[(s2 >> 24) ] ^ + rk[7]; +#endif + s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3]; + + /* + * Nr - 2 full rounds: + */ + for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) { +#if defined(AES_COMPACT_IN_INNER_ROUNDS) + t[0] = (u32)Te4[(s0 ) & 0xff] ^ + (u32)Te4[(s1 >> 8) & 0xff] << 8 ^ + (u32)Te4[(s2 >> 16) & 0xff] << 16 ^ + (u32)Te4[(s3 >> 24) ] << 24; + t[1] = (u32)Te4[(s1 ) & 0xff] ^ + (u32)Te4[(s2 >> 8) & 0xff] << 8 ^ + (u32)Te4[(s3 >> 16) & 0xff] << 16 ^ + (u32)Te4[(s0 >> 24) ] << 24; + t[2] = (u32)Te4[(s2 ) & 0xff] ^ + (u32)Te4[(s3 >> 8) & 0xff] << 8 ^ + (u32)Te4[(s0 >> 16) & 0xff] << 16 ^ + (u32)Te4[(s1 >> 24) ] << 24; + t[3] = (u32)Te4[(s3 ) & 0xff] ^ + (u32)Te4[(s0 >> 8) & 0xff] << 8 ^ + (u32)Te4[(s1 >> 16) & 0xff] << 16 ^ + (u32)Te4[(s2 >> 24) ] << 24; + + /* now do the linear transform using words */ + { + int i; + u32 r0, r1, r2; + + for (i = 0; i < 4; i++) { + r0 = t[i]; + r1 = r0 & 0x80808080; + r2 = ((r0 & 0x7f7f7f7f) << 1) ^ + ((r1 - (r1 >> 7)) & 0x1b1b1b1b); +#if defined(ROTATE) + t[i] = r2 ^ ROTATE(r2,24) ^ ROTATE(r0,24) ^ + ROTATE(r0,16) ^ ROTATE(r0,8); +#else + t[i] = r2 ^ ((r2 ^ r0) << 24) ^ ((r2 ^ r0) >> 8) ^ + (r0 << 16) ^ (r0 >> 16) ^ + (r0 << 8) ^ (r0 >> 24); +#endif + t[i] ^= rk[i]; + } + } +#else + t[0] = Te0[(s0 ) & 0xff] ^ + Te1[(s1 >> 8) & 0xff] ^ + Te2[(s2 >> 16) & 0xff] ^ + Te3[(s3 >> 24) ] ^ + rk[0]; + t[1] = Te0[(s1 ) & 0xff] ^ + Te1[(s2 >> 8) & 0xff] ^ + Te2[(s3 >> 16) & 0xff] ^ + Te3[(s0 >> 24) ] ^ + rk[1]; + t[2] = Te0[(s2 ) & 0xff] ^ + Te1[(s3 >> 8) & 0xff] ^ + Te2[(s0 >> 16) & 0xff] ^ + Te3[(s1 >> 24) ] ^ + rk[2]; + t[3] = Te0[(s3 ) & 0xff] ^ + Te1[(s0 >> 8) & 0xff] ^ + Te2[(s1 >> 16) & 0xff] ^ + Te3[(s2 >> 24) ] ^ + rk[3]; +#endif + s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3]; + } + /* + * apply last round and + * map cipher state to byte array block: + */ +#if defined(AES_COMPACT_IN_OUTER_ROUNDS) + prefetch256(Te4); + + *(u32*)(out+0) = + (u32)Te4[(s0 ) & 0xff] ^ + (u32)Te4[(s1 >> 8) & 0xff] << 8 ^ + (u32)Te4[(s2 >> 16) & 0xff] << 16 ^ + (u32)Te4[(s3 >> 24) ] << 24 ^ + rk[0]; + *(u32*)(out+4) = + (u32)Te4[(s1 ) & 0xff] ^ + (u32)Te4[(s2 >> 8) & 0xff] << 8 ^ + (u32)Te4[(s3 >> 16) & 0xff] << 16 ^ + (u32)Te4[(s0 >> 24) ] << 24 ^ + rk[1]; + *(u32*)(out+8) = + (u32)Te4[(s2 ) & 0xff] ^ + (u32)Te4[(s3 >> 8) & 0xff] << 8 ^ + (u32)Te4[(s0 >> 16) & 0xff] << 16 ^ + (u32)Te4[(s1 >> 24) ] << 24 ^ + rk[2]; + *(u32*)(out+12) = + (u32)Te4[(s3 ) & 0xff] ^ + (u32)Te4[(s0 >> 8) & 0xff] << 8 ^ + (u32)Te4[(s1 >> 16) & 0xff] << 16 ^ + (u32)Te4[(s2 >> 24) ] << 24 ^ + rk[3]; +#else + *(u32*)(out+0) = + (Te2[(s0 ) & 0xff] & 0x000000ffU) ^ + (Te3[(s1 >> 8) & 0xff] & 0x0000ff00U) ^ + (Te0[(s2 >> 16) & 0xff] & 0x00ff0000U) ^ + (Te1[(s3 >> 24) ] & 0xff000000U) ^ + rk[0]; + *(u32*)(out+4) = + (Te2[(s1 ) & 0xff] & 0x000000ffU) ^ + (Te3[(s2 >> 8) & 0xff] & 0x0000ff00U) ^ + (Te0[(s3 >> 16) & 0xff] & 0x00ff0000U) ^ + (Te1[(s0 >> 24) ] & 0xff000000U) ^ + rk[1]; + *(u32*)(out+8) = + (Te2[(s2 ) & 0xff] & 0x000000ffU) ^ + (Te3[(s3 >> 8) & 0xff] & 0x0000ff00U) ^ + (Te0[(s0 >> 16) & 0xff] & 0x00ff0000U) ^ + (Te1[(s1 >> 24) ] & 0xff000000U) ^ + rk[2]; + *(u32*)(out+12) = + (Te2[(s3 ) & 0xff] & 0x000000ffU) ^ + (Te3[(s0 >> 8) & 0xff] & 0x0000ff00U) ^ + (Te0[(s1 >> 16) & 0xff] & 0x00ff0000U) ^ + (Te1[(s2 >> 24) ] & 0xff000000U) ^ + rk[3]; +#endif +} + +/* + * Decrypt a single block + * in and out can overlap + */ +void AES_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key) +{ + + const u32 *rk; + u32 s0, s1, s2, s3, t[4]; + int r; + + assert(in && out && key); + rk = key->rd_key; + + /* + * map byte array block to cipher state + * and add initial round key: + */ + s0 = GETU32(in ) ^ rk[0]; + s1 = GETU32(in + 4) ^ rk[1]; + s2 = GETU32(in + 8) ^ rk[2]; + s3 = GETU32(in + 12) ^ rk[3]; + +#if defined(AES_COMPACT_IN_OUTER_ROUNDS) + prefetch256(Td4); + + t[0] = (u32)Td4[(s0 ) & 0xff] ^ + (u32)Td4[(s3 >> 8) & 0xff] << 8 ^ + (u32)Td4[(s2 >> 16) & 0xff] << 16 ^ + (u32)Td4[(s1 >> 24) ] << 24; + t[1] = (u32)Td4[(s1 ) & 0xff] ^ + (u32)Td4[(s0 >> 8) & 0xff] << 8 ^ + (u32)Td4[(s3 >> 16) & 0xff] << 16 ^ + (u32)Td4[(s2 >> 24) ] << 24; + t[2] = (u32)Td4[(s2 ) & 0xff] ^ + (u32)Td4[(s1 >> 8) & 0xff] << 8 ^ + (u32)Td4[(s0 >> 16) & 0xff] << 16 ^ + (u32)Td4[(s3 >> 24) ] << 24; + t[3] = (u32)Td4[(s3 ) & 0xff] ^ + (u32)Td4[(s2 >> 8) & 0xff] << 8 ^ + (u32)Td4[(s1 >> 16) & 0xff] << 16 ^ + (u32)Td4[(s0 >> 24) ] << 24; + + /* now do the linear transform using words */ + { + int i; + u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m; + + for (i = 0; i < 4; i++) { + tp1 = t[i]; + m = tp1 & 0x80808080; + tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + m = tp2 & 0x80808080; + tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + m = tp4 & 0x80808080; + tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + tp9 = tp8 ^ tp1; + tpb = tp9 ^ tp2; + tpd = tp9 ^ tp4; + tpe = tp8 ^ tp4 ^ tp2; +#if defined(ROTATE) + t[i] = tpe ^ ROTATE(tpd,16) ^ + ROTATE(tp9,8) ^ ROTATE(tpb,24); +#else + t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ + (tp9 >> 24) ^ (tp9 << 8) ^ + (tpb >> 8) ^ (tpb << 24); +#endif + t[i] ^= rk[4+i]; + } + } +#else + t[0] = Td0[(s0 ) & 0xff] ^ + Td1[(s3 >> 8) & 0xff] ^ + Td2[(s2 >> 16) & 0xff] ^ + Td3[(s1 >> 24) ] ^ + rk[4]; + t[1] = Td0[(s1 ) & 0xff] ^ + Td1[(s0 >> 8) & 0xff] ^ + Td2[(s3 >> 16) & 0xff] ^ + Td3[(s2 >> 24) ] ^ + rk[5]; + t[2] = Td0[(s2 ) & 0xff] ^ + Td1[(s1 >> 8) & 0xff] ^ + Td2[(s0 >> 16) & 0xff] ^ + Td3[(s3 >> 24) ] ^ + rk[6]; + t[3] = Td0[(s3 ) & 0xff] ^ + Td1[(s2 >> 8) & 0xff] ^ + Td2[(s1 >> 16) & 0xff] ^ + Td3[(s0 >> 24) ] ^ + rk[7]; +#endif + s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3]; + + /* + * Nr - 2 full rounds: + */ + for (rk+=8,r=key->rounds-2; r>0; rk+=4,r--) { +#if defined(AES_COMPACT_IN_INNER_ROUNDS) + t[0] = (u32)Td4[(s0 ) & 0xff] ^ + (u32)Td4[(s3 >> 8) & 0xff] << 8 ^ + (u32)Td4[(s2 >> 16) & 0xff] << 16 ^ + (u32)Td4[(s1 >> 24) ] << 24; + t[1] = (u32)Td4[(s1 ) & 0xff] ^ + (u32)Td4[(s0 >> 8) & 0xff] << 8 ^ + (u32)Td4[(s3 >> 16) & 0xff] << 16 ^ + (u32)Td4[(s2 >> 24) ] << 24; + t[2] = (u32)Td4[(s2 ) & 0xff] ^ + (u32)Td4[(s1 >> 8) & 0xff] << 8 ^ + (u32)Td4[(s0 >> 16) & 0xff] << 16 ^ + (u32)Td4[(s3 >> 24) ] << 24; + t[3] = (u32)Td4[(s3 ) & 0xff] ^ + (u32)Td4[(s2 >> 8) & 0xff] << 8 ^ + (u32)Td4[(s1 >> 16) & 0xff] << 16 ^ + (u32)Td4[(s0 >> 24) ] << 24; + + /* now do the linear transform using words */ + { + int i; + u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m; + + for (i = 0; i < 4; i++) { + tp1 = t[i]; + m = tp1 & 0x80808080; + tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + m = tp2 & 0x80808080; + tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + m = tp4 & 0x80808080; + tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^ + ((m - (m >> 7)) & 0x1b1b1b1b); + tp9 = tp8 ^ tp1; + tpb = tp9 ^ tp2; + tpd = tp9 ^ tp4; + tpe = tp8 ^ tp4 ^ tp2; +#if defined(ROTATE) + t[i] = tpe ^ ROTATE(tpd,16) ^ + ROTATE(tp9,8) ^ ROTATE(tpb,24); +#else + t[i] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^ + (tp9 >> 24) ^ (tp9 << 8) ^ + (tpb >> 8) ^ (tpb << 24); +#endif + t[i] ^= rk[i]; + } + } +#else + t[0] = Td0[(s0 ) & 0xff] ^ + Td1[(s3 >> 8) & 0xff] ^ + Td2[(s2 >> 16) & 0xff] ^ + Td3[(s1 >> 24) ] ^ + rk[0]; + t[1] = Td0[(s1 ) & 0xff] ^ + Td1[(s0 >> 8) & 0xff] ^ + Td2[(s3 >> 16) & 0xff] ^ + Td3[(s2 >> 24) ] ^ + rk[1]; + t[2] = Td0[(s2 ) & 0xff] ^ + Td1[(s1 >> 8) & 0xff] ^ + Td2[(s0 >> 16) & 0xff] ^ + Td3[(s3 >> 24) ] ^ + rk[2]; + t[3] = Td0[(s3 ) & 0xff] ^ + Td1[(s2 >> 8) & 0xff] ^ + Td2[(s1 >> 16) & 0xff] ^ + Td3[(s0 >> 24) ] ^ + rk[3]; +#endif + s0 = t[0]; s1 = t[1]; s2 = t[2]; s3 = t[3]; + } + /* + * apply last round and + * map cipher state to byte array block: + */ + prefetch256(Td4); + + *(u32*)(out+0) = + ((u32)Td4[(s0 ) & 0xff]) ^ + ((u32)Td4[(s3 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(s2 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(s1 >> 24) ] << 24) ^ + rk[0]; + *(u32*)(out+4) = + ((u32)Td4[(s1 ) & 0xff]) ^ + ((u32)Td4[(s0 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(s3 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(s2 >> 24) ] << 24) ^ + rk[1]; + *(u32*)(out+8) = + ((u32)Td4[(s2 ) & 0xff]) ^ + ((u32)Td4[(s1 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(s0 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(s3 >> 24) ] << 24) ^ + rk[2]; + *(u32*)(out+12) = + ((u32)Td4[(s3 ) & 0xff]) ^ + ((u32)Td4[(s2 >> 8) & 0xff] << 8) ^ + ((u32)Td4[(s1 >> 16) & 0xff] << 16) ^ + ((u32)Td4[(s0 >> 24) ] << 24) ^ + rk[3]; +} diff --git a/libs/openssl/crypto/aes/asm/aes-586.pl b/libs/openssl/crypto/aes/asm/aes-586.pl new file mode 100755 index 00000000..51b500dd --- /dev/null +++ b/libs/openssl/crypto/aes/asm/aes-586.pl @@ -0,0 +1,2980 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# Version 4.3. +# +# You might fail to appreciate this module performance from the first +# try. If compared to "vanilla" linux-ia32-icc target, i.e. considered +# to be *the* best Intel C compiler without -KPIC, performance appears +# to be virtually identical... But try to re-configure with shared +# library support... Aha! Intel compiler "suddenly" lags behind by 30% +# [on P4, more on others]:-) And if compared to position-independent +# code generated by GNU C, this code performs *more* than *twice* as +# fast! Yes, all this buzz about PIC means that unlike other hand- +# coded implementations, this one was explicitly designed to be safe +# to use even in shared library context... This also means that this +# code isn't necessarily absolutely fastest "ever," because in order +# to achieve position independence an extra register has to be +# off-loaded to stack, which affects the benchmark result. +# +# Special note about instruction choice. Do you recall RC4_INT code +# performing poorly on P4? It might be the time to figure out why. +# RC4_INT code implies effective address calculations in base+offset*4 +# form. Trouble is that it seems that offset scaling turned to be +# critical path... At least eliminating scaling resulted in 2.8x RC4 +# performance improvement [as you might recall]. As AES code is hungry +# for scaling too, I [try to] avoid the latter by favoring off-by-2 +# shifts and masking the result with 0xFF<<2 instead of "boring" 0xFF. +# +# As was shown by Dean Gaudet , the above note turned +# void. Performance improvement with off-by-2 shifts was observed on +# intermediate implementation, which was spilling yet another register +# to stack... Final offset*4 code below runs just a tad faster on P4, +# but exhibits up to 10% improvement on other cores. +# +# Second version is "monolithic" replacement for aes_core.c, which in +# addition to AES_[de|en]crypt implements private_AES_set_[de|en]cryption_key. +# This made it possible to implement little-endian variant of the +# algorithm without modifying the base C code. Motivating factor for +# the undertaken effort was that it appeared that in tight IA-32 +# register window little-endian flavor could achieve slightly higher +# Instruction Level Parallelism, and it indeed resulted in up to 15% +# better performance on most recent µ-archs... +# +# Third version adds AES_cbc_encrypt implementation, which resulted in +# up to 40% performance imrovement of CBC benchmark results. 40% was +# observed on P4 core, where "overall" imrovement coefficient, i.e. if +# compared to PIC generated by GCC and in CBC mode, was observed to be +# as large as 4x:-) CBC performance is virtually identical to ECB now +# and on some platforms even better, e.g. 17.6 "small" cycles/byte on +# Opteron, because certain function prologues and epilogues are +# effectively taken out of the loop... +# +# Version 3.2 implements compressed tables and prefetch of these tables +# in CBC[!] mode. Former means that 3/4 of table references are now +# misaligned, which unfortunately has negative impact on elder IA-32 +# implementations, Pentium suffered 30% penalty, PIII - 10%. +# +# Version 3.3 avoids L1 cache aliasing between stack frame and +# S-boxes, and 3.4 - L1 cache aliasing even between key schedule. The +# latter is achieved by copying the key schedule to controlled place in +# stack. This unfortunately has rather strong impact on small block CBC +# performance, ~2x deterioration on 16-byte block if compared to 3.3. +# +# Version 3.5 checks if there is L1 cache aliasing between user-supplied +# key schedule and S-boxes and abstains from copying the former if +# there is no. This allows end-user to consciously retain small block +# performance by aligning key schedule in specific manner. +# +# Version 3.6 compresses Td4 to 256 bytes and prefetches it in ECB. +# +# Current ECB performance numbers for 128-bit key in CPU cycles per +# processed byte [measure commonly used by AES benchmarkers] are: +# +# small footprint fully unrolled +# P4 24 22 +# AMD K8 20 19 +# PIII 25 23 +# Pentium 81 78 +# +# Version 3.7 reimplements outer rounds as "compact." Meaning that +# first and last rounds reference compact 256 bytes S-box. This means +# that first round consumes a lot more CPU cycles and that encrypt +# and decrypt performance becomes asymmetric. Encrypt performance +# drops by 10-12%, while decrypt - by 20-25%:-( 256 bytes S-box is +# aggressively pre-fetched. +# +# Version 4.0 effectively rolls back to 3.6 and instead implements +# additional set of functions, _[x86|sse]_AES_[en|de]crypt_compact, +# which use exclusively 256 byte S-box. These functions are to be +# called in modes not concealing plain text, such as ECB, or when +# we're asked to process smaller amount of data [or unconditionally +# on hyper-threading CPU]. Currently it's called unconditionally from +# AES_[en|de]crypt, which affects all modes, but CBC. CBC routine +# still needs to be modified to switch between slower and faster +# mode when appropriate... But in either case benchmark landscape +# changes dramatically and below numbers are CPU cycles per processed +# byte for 128-bit key. +# +# ECB encrypt ECB decrypt CBC large chunk +# P4 56[60] 84[100] 23 +# AMD K8 48[44] 70[79] 18 +# PIII 41[50] 61[91] 24 +# Core 2 32[38] 45[70] 18.5 +# Pentium 120 160 77 +# +# Version 4.1 switches to compact S-box even in key schedule setup. +# +# Version 4.2 prefetches compact S-box in every SSE round or in other +# words every cache-line is *guaranteed* to be accessed within ~50 +# cycles window. Why just SSE? Because it's needed on hyper-threading +# CPU! Which is also why it's prefetched with 64 byte stride. Best +# part is that it has no negative effect on performance:-) +# +# Version 4.3 implements switch between compact and non-compact block +# functions in AES_cbc_encrypt depending on how much data was asked +# to be processed in one stroke. +# +###################################################################### +# Timing attacks are classified in two classes: synchronous when +# attacker consciously initiates cryptographic operation and collects +# timing data of various character afterwards, and asynchronous when +# malicious code is executed on same CPU simultaneously with AES, +# instruments itself and performs statistical analysis of this data. +# +# As far as synchronous attacks go the root to the AES timing +# vulnerability is twofold. Firstly, of 256 S-box elements at most 160 +# are referred to in single 128-bit block operation. Well, in C +# implementation with 4 distinct tables it's actually as little as 40 +# references per 256 elements table, but anyway... Secondly, even +# though S-box elements are clustered into smaller amount of cache- +# lines, smaller than 160 and even 40, it turned out that for certain +# plain-text pattern[s] or simply put chosen plain-text and given key +# few cache-lines remain unaccessed during block operation. Now, if +# attacker can figure out this access pattern, he can deduct the key +# [or at least part of it]. The natural way to mitigate this kind of +# attacks is to minimize the amount of cache-lines in S-box and/or +# prefetch them to ensure that every one is accessed for more uniform +# timing. But note that *if* plain-text was concealed in such way that +# input to block function is distributed *uniformly*, then attack +# wouldn't apply. Now note that some encryption modes, most notably +# CBC, do mask the plain-text in this exact way [secure cipher output +# is distributed uniformly]. Yes, one still might find input that +# would reveal the information about given key, but if amount of +# candidate inputs to be tried is larger than amount of possible key +# combinations then attack becomes infeasible. This is why revised +# AES_cbc_encrypt "dares" to switch to larger S-box when larger chunk +# of data is to be processed in one stroke. The current size limit of +# 512 bytes is chosen to provide same [diminishigly low] probability +# for cache-line to remain untouched in large chunk operation with +# large S-box as for single block operation with compact S-box and +# surely needs more careful consideration... +# +# As for asynchronous attacks. There are two flavours: attacker code +# being interleaved with AES on hyper-threading CPU at *instruction* +# level, and two processes time sharing single core. As for latter. +# Two vectors. 1. Given that attacker process has higher priority, +# yield execution to process performing AES just before timer fires +# off the scheduler, immediately regain control of CPU and analyze the +# cache state. For this attack to be efficient attacker would have to +# effectively slow down the operation by several *orders* of magnitute, +# by ratio of time slice to duration of handful of AES rounds, which +# unlikely to remain unnoticed. Not to mention that this also means +# that he would spend correspondigly more time to collect enough +# statistical data to mount the attack. It's probably appropriate to +# say that if adeversary reckons that this attack is beneficial and +# risks to be noticed, you probably have larger problems having him +# mere opportunity. In other words suggested code design expects you +# to preclude/mitigate this attack by overall system security design. +# 2. Attacker manages to make his code interrupt driven. In order for +# this kind of attack to be feasible, interrupt rate has to be high +# enough, again comparable to duration of handful of AES rounds. But +# is there interrupt source of such rate? Hardly, not even 1Gbps NIC +# generates interrupts at such raging rate... +# +# And now back to the former, hyper-threading CPU or more specifically +# Intel P4. Recall that asynchronous attack implies that malicious +# code instruments itself. And naturally instrumentation granularity +# has be noticeably lower than duration of codepath accessing S-box. +# Given that all cache-lines are accessed during that time that is. +# Current implementation accesses *all* cache-lines within ~50 cycles +# window, which is actually *less* than RDTSC latency on Intel P4! + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"aes-586.pl",$x86only = $ARGV[$#ARGV] eq "386"); +&static_label("AES_Te"); +&static_label("AES_Td"); + +$s0="eax"; +$s1="ebx"; +$s2="ecx"; +$s3="edx"; +$key="edi"; +$acc="esi"; +$tbl="ebp"; + +# stack frame layout in _[x86|sse]_AES_* routines, frame is allocated +# by caller +$__ra=&DWP(0,"esp"); # return address +$__s0=&DWP(4,"esp"); # s0 backing store +$__s1=&DWP(8,"esp"); # s1 backing store +$__s2=&DWP(12,"esp"); # s2 backing store +$__s3=&DWP(16,"esp"); # s3 backing store +$__key=&DWP(20,"esp"); # pointer to key schedule +$__end=&DWP(24,"esp"); # pointer to end of key schedule +$__tbl=&DWP(28,"esp"); # %ebp backing store + +# stack frame layout in AES_[en|crypt] routines, which differs from +# above by 4 and overlaps by %ebp backing store +$_tbl=&DWP(24,"esp"); +$_esp=&DWP(28,"esp"); + +sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } } + +$speed_limit=512; # chunks smaller than $speed_limit are + # processed with compact routine in CBC mode +$small_footprint=1; # $small_footprint=1 code is ~5% slower [on + # recent µ-archs], but ~5 times smaller! + # I favor compact code to minimize cache + # contention and in hope to "collect" 5% back + # in real-life applications... + +$vertical_spin=0; # shift "verticaly" defaults to 0, because of + # its proof-of-concept status... +# Note that there is no decvert(), as well as last encryption round is +# performed with "horizontal" shifts. This is because this "vertical" +# implementation [one which groups shifts on a given $s[i] to form a +# "column," unlike "horizontal" one, which groups shifts on different +# $s[i] to form a "row"] is work in progress. It was observed to run +# few percents faster on Intel cores, but not AMD. On AMD K8 core it's +# whole 12% slower:-( So we face a trade-off... Shall it be resolved +# some day? Till then the code is considered experimental and by +# default remains dormant... + +sub encvert() +{ my ($te,@s) = @_; + my $v0 = $acc, $v1 = $key; + + &mov ($v0,$s[3]); # copy s3 + &mov (&DWP(4,"esp"),$s[2]); # save s2 + &mov ($v1,$s[0]); # copy s0 + &mov (&DWP(8,"esp"),$s[1]); # save s1 + + &movz ($s[2],&HB($s[0])); + &and ($s[0],0xFF); + &mov ($s[0],&DWP(0,$te,$s[0],8)); # s0>>0 + &shr ($v1,16); + &mov ($s[3],&DWP(3,$te,$s[2],8)); # s0>>8 + &movz ($s[1],&HB($v1)); + &and ($v1,0xFF); + &mov ($s[2],&DWP(2,$te,$v1,8)); # s0>>16 + &mov ($v1,$v0); + &mov ($s[1],&DWP(1,$te,$s[1],8)); # s0>>24 + + &and ($v0,0xFF); + &xor ($s[3],&DWP(0,$te,$v0,8)); # s3>>0 + &movz ($v0,&HB($v1)); + &shr ($v1,16); + &xor ($s[2],&DWP(3,$te,$v0,8)); # s3>>8 + &movz ($v0,&HB($v1)); + &and ($v1,0xFF); + &xor ($s[1],&DWP(2,$te,$v1,8)); # s3>>16 + &mov ($v1,&DWP(4,"esp")); # restore s2 + &xor ($s[0],&DWP(1,$te,$v0,8)); # s3>>24 + + &mov ($v0,$v1); + &and ($v1,0xFF); + &xor ($s[2],&DWP(0,$te,$v1,8)); # s2>>0 + &movz ($v1,&HB($v0)); + &shr ($v0,16); + &xor ($s[1],&DWP(3,$te,$v1,8)); # s2>>8 + &movz ($v1,&HB($v0)); + &and ($v0,0xFF); + &xor ($s[0],&DWP(2,$te,$v0,8)); # s2>>16 + &mov ($v0,&DWP(8,"esp")); # restore s1 + &xor ($s[3],&DWP(1,$te,$v1,8)); # s2>>24 + + &mov ($v1,$v0); + &and ($v0,0xFF); + &xor ($s[1],&DWP(0,$te,$v0,8)); # s1>>0 + &movz ($v0,&HB($v1)); + &shr ($v1,16); + &xor ($s[0],&DWP(3,$te,$v0,8)); # s1>>8 + &movz ($v0,&HB($v1)); + &and ($v1,0xFF); + &xor ($s[3],&DWP(2,$te,$v1,8)); # s1>>16 + &mov ($key,$__key); # reincarnate v1 as key + &xor ($s[2],&DWP(1,$te,$v0,8)); # s1>>24 +} + +# Another experimental routine, which features "horizontal spin," but +# eliminates one reference to stack. Strangely enough runs slower... +sub enchoriz() +{ my $v0 = $key, $v1 = $acc; + + &movz ($v0,&LB($s0)); # 3, 2, 1, 0* + &rotr ($s2,8); # 8,11,10, 9 + &mov ($v1,&DWP(0,$te,$v0,8)); # 0 + &movz ($v0,&HB($s1)); # 7, 6, 5*, 4 + &rotr ($s3,16); # 13,12,15,14 + &xor ($v1,&DWP(3,$te,$v0,8)); # 5 + &movz ($v0,&HB($s2)); # 8,11,10*, 9 + &rotr ($s0,16); # 1, 0, 3, 2 + &xor ($v1,&DWP(2,$te,$v0,8)); # 10 + &movz ($v0,&HB($s3)); # 13,12,15*,14 + &xor ($v1,&DWP(1,$te,$v0,8)); # 15, t[0] collected + &mov ($__s0,$v1); # t[0] saved + + &movz ($v0,&LB($s1)); # 7, 6, 5, 4* + &shr ($s1,16); # -, -, 7, 6 + &mov ($v1,&DWP(0,$te,$v0,8)); # 4 + &movz ($v0,&LB($s3)); # 13,12,15,14* + &xor ($v1,&DWP(2,$te,$v0,8)); # 14 + &movz ($v0,&HB($s0)); # 1, 0, 3*, 2 + &and ($s3,0xffff0000); # 13,12, -, - + &xor ($v1,&DWP(1,$te,$v0,8)); # 3 + &movz ($v0,&LB($s2)); # 8,11,10, 9* + &or ($s3,$s1); # 13,12, 7, 6 + &xor ($v1,&DWP(3,$te,$v0,8)); # 9, t[1] collected + &mov ($s1,$v1); # s[1]=t[1] + + &movz ($v0,&LB($s0)); # 1, 0, 3, 2* + &shr ($s2,16); # -, -, 8,11 + &mov ($v1,&DWP(2,$te,$v0,8)); # 2 + &movz ($v0,&HB($s3)); # 13,12, 7*, 6 + &xor ($v1,&DWP(1,$te,$v0,8)); # 7 + &movz ($v0,&HB($s2)); # -, -, 8*,11 + &xor ($v1,&DWP(0,$te,$v0,8)); # 8 + &mov ($v0,$s3); + &shr ($v0,24); # 13 + &xor ($v1,&DWP(3,$te,$v0,8)); # 13, t[2] collected + + &movz ($v0,&LB($s2)); # -, -, 8,11* + &shr ($s0,24); # 1* + &mov ($s2,&DWP(1,$te,$v0,8)); # 11 + &xor ($s2,&DWP(3,$te,$s0,8)); # 1 + &mov ($s0,$__s0); # s[0]=t[0] + &movz ($v0,&LB($s3)); # 13,12, 7, 6* + &shr ($s3,16); # , ,13,12 + &xor ($s2,&DWP(2,$te,$v0,8)); # 6 + &mov ($key,$__key); # reincarnate v0 as key + &and ($s3,0xff); # , ,13,12* + &mov ($s3,&DWP(0,$te,$s3,8)); # 12 + &xor ($s3,$s2); # s[2]=t[3] collected + &mov ($s2,$v1); # s[2]=t[2] +} + +# More experimental code... SSE one... Even though this one eliminates +# *all* references to stack, it's not faster... +sub sse_encbody() +{ + &movz ($acc,&LB("eax")); # 0 + &mov ("ecx",&DWP(0,$tbl,$acc,8)); # 0 + &pshufw ("mm2","mm0",0x0d); # 7, 6, 3, 2 + &movz ("edx",&HB("eax")); # 1 + &mov ("edx",&DWP(3,$tbl,"edx",8)); # 1 + &shr ("eax",16); # 5, 4 + + &movz ($acc,&LB("ebx")); # 10 + &xor ("ecx",&DWP(2,$tbl,$acc,8)); # 10 + &pshufw ("mm6","mm4",0x08); # 13,12, 9, 8 + &movz ($acc,&HB("ebx")); # 11 + &xor ("edx",&DWP(1,$tbl,$acc,8)); # 11 + &shr ("ebx",16); # 15,14 + + &movz ($acc,&HB("eax")); # 5 + &xor ("ecx",&DWP(3,$tbl,$acc,8)); # 5 + &movq ("mm3",QWP(16,$key)); + &movz ($acc,&HB("ebx")); # 15 + &xor ("ecx",&DWP(1,$tbl,$acc,8)); # 15 + &movd ("mm0","ecx"); # t[0] collected + + &movz ($acc,&LB("eax")); # 4 + &mov ("ecx",&DWP(0,$tbl,$acc,8)); # 4 + &movd ("eax","mm2"); # 7, 6, 3, 2 + &movz ($acc,&LB("ebx")); # 14 + &xor ("ecx",&DWP(2,$tbl,$acc,8)); # 14 + &movd ("ebx","mm6"); # 13,12, 9, 8 + + &movz ($acc,&HB("eax")); # 3 + &xor ("ecx",&DWP(1,$tbl,$acc,8)); # 3 + &movz ($acc,&HB("ebx")); # 9 + &xor ("ecx",&DWP(3,$tbl,$acc,8)); # 9 + &movd ("mm1","ecx"); # t[1] collected + + &movz ($acc,&LB("eax")); # 2 + &mov ("ecx",&DWP(2,$tbl,$acc,8)); # 2 + &shr ("eax",16); # 7, 6 + &punpckldq ("mm0","mm1"); # t[0,1] collected + &movz ($acc,&LB("ebx")); # 8 + &xor ("ecx",&DWP(0,$tbl,$acc,8)); # 8 + &shr ("ebx",16); # 13,12 + + &movz ($acc,&HB("eax")); # 7 + &xor ("ecx",&DWP(1,$tbl,$acc,8)); # 7 + &pxor ("mm0","mm3"); + &movz ("eax",&LB("eax")); # 6 + &xor ("edx",&DWP(2,$tbl,"eax",8)); # 6 + &pshufw ("mm1","mm0",0x08); # 5, 4, 1, 0 + &movz ($acc,&HB("ebx")); # 13 + &xor ("ecx",&DWP(3,$tbl,$acc,8)); # 13 + &xor ("ecx",&DWP(24,$key)); # t[2] + &movd ("mm4","ecx"); # t[2] collected + &movz ("ebx",&LB("ebx")); # 12 + &xor ("edx",&DWP(0,$tbl,"ebx",8)); # 12 + &shr ("ecx",16); + &movd ("eax","mm1"); # 5, 4, 1, 0 + &mov ("ebx",&DWP(28,$key)); # t[3] + &xor ("ebx","edx"); + &movd ("mm5","ebx"); # t[3] collected + &and ("ebx",0xffff0000); + &or ("ebx","ecx"); + + &punpckldq ("mm4","mm5"); # t[2,3] collected +} + +###################################################################### +# "Compact" block function +###################################################################### + +sub enccompact() +{ my $Fn = mov; + while ($#_>5) { pop(@_); $Fn=sub{}; } + my ($i,$te,@s)=@_; + my $tmp = $key; + my $out = $i==3?$s[0]:$acc; + + # $Fn is used in first compact round and its purpose is to + # void restoration of some values from stack, so that after + # 4xenccompact with extra argument $key value is left there... + if ($i==3) { &$Fn ($key,$__key); }##%edx + else { &mov ($out,$s[0]); } + &and ($out,0xFF); + if ($i==1) { &shr ($s[0],16); }#%ebx[1] + if ($i==2) { &shr ($s[0],24); }#%ecx[2] + &movz ($out,&BP(-128,$te,$out,1)); + + if ($i==3) { $tmp=$s[1]; }##%eax + &movz ($tmp,&HB($s[1])); + &movz ($tmp,&BP(-128,$te,$tmp,1)); + &shl ($tmp,8); + &xor ($out,$tmp); + + if ($i==3) { $tmp=$s[2]; &mov ($s[1],$__s0); }##%ebx + else { &mov ($tmp,$s[2]); + &shr ($tmp,16); } + if ($i==2) { &and ($s[1],0xFF); }#%edx[2] + &and ($tmp,0xFF); + &movz ($tmp,&BP(-128,$te,$tmp,1)); + &shl ($tmp,16); + &xor ($out,$tmp); + + if ($i==3) { $tmp=$s[3]; &mov ($s[2],$__s1); }##%ecx + elsif($i==2){ &movz ($tmp,&HB($s[3])); }#%ebx[2] + else { &mov ($tmp,$s[3]); + &shr ($tmp,24); } + &movz ($tmp,&BP(-128,$te,$tmp,1)); + &shl ($tmp,24); + &xor ($out,$tmp); + if ($i<2) { &mov (&DWP(4+4*$i,"esp"),$out); } + if ($i==3) { &mov ($s[3],$acc); } + &comment(); +} + +sub enctransform() +{ my @s = ($s0,$s1,$s2,$s3); + my $i = shift; + my $tmp = $tbl; + my $r2 = $key ; + + &mov ($acc,$s[$i]); + &and ($acc,0x80808080); + &mov ($tmp,$acc); + &shr ($tmp,7); + &lea ($r2,&DWP(0,$s[$i],$s[$i])); + &sub ($acc,$tmp); + &and ($r2,0xfefefefe); + &and ($acc,0x1b1b1b1b); + &mov ($tmp,$s[$i]); + &xor ($acc,$r2); # r2 + + &xor ($s[$i],$acc); # r0 ^ r2 + &rotl ($s[$i],24); + &xor ($s[$i],$acc) # ROTATE(r2^r0,24) ^ r2 + &rotr ($tmp,16); + &xor ($s[$i],$tmp); + &rotr ($tmp,8); + &xor ($s[$i],$tmp); +} + +&function_begin_B("_x86_AES_encrypt_compact"); + # note that caller is expected to allocate stack frame for me! + &mov ($__key,$key); # save key + + &xor ($s0,&DWP(0,$key)); # xor with key + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + + &mov ($acc,&DWP(240,$key)); # load key->rounds + &lea ($acc,&DWP(-2,$acc,$acc)); + &lea ($acc,&DWP(0,$key,$acc,8)); + &mov ($__end,$acc); # end of key schedule + + # prefetch Te4 + &mov ($key,&DWP(0-128,$tbl)); + &mov ($acc,&DWP(32-128,$tbl)); + &mov ($key,&DWP(64-128,$tbl)); + &mov ($acc,&DWP(96-128,$tbl)); + &mov ($key,&DWP(128-128,$tbl)); + &mov ($acc,&DWP(160-128,$tbl)); + &mov ($key,&DWP(192-128,$tbl)); + &mov ($acc,&DWP(224-128,$tbl)); + + &set_label("loop",16); + + &enccompact(0,$tbl,$s0,$s1,$s2,$s3,1); + &enccompact(1,$tbl,$s1,$s2,$s3,$s0,1); + &enccompact(2,$tbl,$s2,$s3,$s0,$s1,1); + &enccompact(3,$tbl,$s3,$s0,$s1,$s2,1); + &enctransform(2); + &enctransform(3); + &enctransform(0); + &enctransform(1); + &mov ($key,$__key); + &mov ($tbl,$__tbl); + &add ($key,16); # advance rd_key + &xor ($s0,&DWP(0,$key)); + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + + &cmp ($key,$__end); + &mov ($__key,$key); + &jb (&label("loop")); + + &enccompact(0,$tbl,$s0,$s1,$s2,$s3); + &enccompact(1,$tbl,$s1,$s2,$s3,$s0); + &enccompact(2,$tbl,$s2,$s3,$s0,$s1); + &enccompact(3,$tbl,$s3,$s0,$s1,$s2); + + &xor ($s0,&DWP(16,$key)); + &xor ($s1,&DWP(20,$key)); + &xor ($s2,&DWP(24,$key)); + &xor ($s3,&DWP(28,$key)); + + &ret (); +&function_end_B("_x86_AES_encrypt_compact"); + +###################################################################### +# "Compact" SSE block function. +###################################################################### +# +# Performance is not actually extraordinary in comparison to pure +# x86 code. In particular encrypt performance is virtually the same. +# Decrypt performance on the other hand is 15-20% better on newer +# µ-archs [but we're thankful for *any* improvement here], and ~50% +# better on PIII:-) And additionally on the pros side this code +# eliminates redundant references to stack and thus relieves/ +# minimizes the pressure on the memory bus. +# +# MMX register layout lsb +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | mm4 | mm0 | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# | s3 | s2 | s1 | s0 | +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# |15|14|13|12|11|10| 9| 8| 7| 6| 5| 4| 3| 2| 1| 0| +# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ +# +# Indexes translate as s[N/4]>>(8*(N%4)), e.g. 5 means s1>>8. +# In this terms encryption and decryption "compact" permutation +# matrices can be depicted as following: +# +# encryption lsb # decryption lsb +# +----++----+----+----+----+ # +----++----+----+----+----+ +# | t0 || 15 | 10 | 5 | 0 | # | t0 || 7 | 10 | 13 | 0 | +# +----++----+----+----+----+ # +----++----+----+----+----+ +# | t1 || 3 | 14 | 9 | 4 | # | t1 || 11 | 14 | 1 | 4 | +# +----++----+----+----+----+ # +----++----+----+----+----+ +# | t2 || 7 | 2 | 13 | 8 | # | t2 || 15 | 2 | 5 | 8 | +# +----++----+----+----+----+ # +----++----+----+----+----+ +# | t3 || 11 | 6 | 1 | 12 | # | t3 || 3 | 6 | 9 | 12 | +# +----++----+----+----+----+ # +----++----+----+----+----+ +# +###################################################################### +# Why not xmm registers? Short answer. It was actually tested and +# was not any faster, but *contrary*, most notably on Intel CPUs. +# Longer answer. Main advantage of using mm registers is that movd +# latency is lower, especially on Intel P4. While arithmetic +# instructions are twice as many, they can be scheduled every cycle +# and not every second one when they are operating on xmm register, +# so that "arithmetic throughput" remains virtually the same. And +# finally the code can be executed even on elder SSE-only CPUs:-) + +sub sse_enccompact() +{ + &pshufw ("mm1","mm0",0x08); # 5, 4, 1, 0 + &pshufw ("mm5","mm4",0x0d); # 15,14,11,10 + &movd ("eax","mm1"); # 5, 4, 1, 0 + &movd ("ebx","mm5"); # 15,14,11,10 + + &movz ($acc,&LB("eax")); # 0 + &movz ("ecx",&BP(-128,$tbl,$acc,1)); # 0 + &pshufw ("mm2","mm0",0x0d); # 7, 6, 3, 2 + &movz ("edx",&HB("eax")); # 1 + &movz ("edx",&BP(-128,$tbl,"edx",1)); # 1 + &shl ("edx",8); # 1 + &shr ("eax",16); # 5, 4 + + &movz ($acc,&LB("ebx")); # 10 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 10 + &shl ($acc,16); # 10 + &or ("ecx",$acc); # 10 + &pshufw ("mm6","mm4",0x08); # 13,12, 9, 8 + &movz ($acc,&HB("ebx")); # 11 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 11 + &shl ($acc,24); # 11 + &or ("edx",$acc); # 11 + &shr ("ebx",16); # 15,14 + + &movz ($acc,&HB("eax")); # 5 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 5 + &shl ($acc,8); # 5 + &or ("ecx",$acc); # 5 + &movz ($acc,&HB("ebx")); # 15 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 15 + &shl ($acc,24); # 15 + &or ("ecx",$acc); # 15 + &movd ("mm0","ecx"); # t[0] collected + + &movz ($acc,&LB("eax")); # 4 + &movz ("ecx",&BP(-128,$tbl,$acc,1)); # 4 + &movd ("eax","mm2"); # 7, 6, 3, 2 + &movz ($acc,&LB("ebx")); # 14 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 14 + &shl ($acc,16); # 14 + &or ("ecx",$acc); # 14 + + &movd ("ebx","mm6"); # 13,12, 9, 8 + &movz ($acc,&HB("eax")); # 3 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 3 + &shl ($acc,24); # 3 + &or ("ecx",$acc); # 3 + &movz ($acc,&HB("ebx")); # 9 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 9 + &shl ($acc,8); # 9 + &or ("ecx",$acc); # 9 + &movd ("mm1","ecx"); # t[1] collected + + &movz ($acc,&LB("ebx")); # 8 + &movz ("ecx",&BP(-128,$tbl,$acc,1)); # 8 + &shr ("ebx",16); # 13,12 + &movz ($acc,&LB("eax")); # 2 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 2 + &shl ($acc,16); # 2 + &or ("ecx",$acc); # 2 + &shr ("eax",16); # 7, 6 + + &punpckldq ("mm0","mm1"); # t[0,1] collected + + &movz ($acc,&HB("eax")); # 7 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 7 + &shl ($acc,24); # 7 + &or ("ecx",$acc); # 7 + &and ("eax",0xff); # 6 + &movz ("eax",&BP(-128,$tbl,"eax",1)); # 6 + &shl ("eax",16); # 6 + &or ("edx","eax"); # 6 + &movz ($acc,&HB("ebx")); # 13 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 13 + &shl ($acc,8); # 13 + &or ("ecx",$acc); # 13 + &movd ("mm4","ecx"); # t[2] collected + &and ("ebx",0xff); # 12 + &movz ("ebx",&BP(-128,$tbl,"ebx",1)); # 12 + &or ("edx","ebx"); # 12 + &movd ("mm5","edx"); # t[3] collected + + &punpckldq ("mm4","mm5"); # t[2,3] collected +} + + if (!$x86only) { +&function_begin_B("_sse_AES_encrypt_compact"); + &pxor ("mm0",&QWP(0,$key)); # 7, 6, 5, 4, 3, 2, 1, 0 + &pxor ("mm4",&QWP(8,$key)); # 15,14,13,12,11,10, 9, 8 + + # note that caller is expected to allocate stack frame for me! + &mov ($acc,&DWP(240,$key)); # load key->rounds + &lea ($acc,&DWP(-2,$acc,$acc)); + &lea ($acc,&DWP(0,$key,$acc,8)); + &mov ($__end,$acc); # end of key schedule + + &mov ($s0,0x1b1b1b1b); # magic constant + &mov (&DWP(8,"esp"),$s0); + &mov (&DWP(12,"esp"),$s0); + + # prefetch Te4 + &mov ($s0,&DWP(0-128,$tbl)); + &mov ($s1,&DWP(32-128,$tbl)); + &mov ($s2,&DWP(64-128,$tbl)); + &mov ($s3,&DWP(96-128,$tbl)); + &mov ($s0,&DWP(128-128,$tbl)); + &mov ($s1,&DWP(160-128,$tbl)); + &mov ($s2,&DWP(192-128,$tbl)); + &mov ($s3,&DWP(224-128,$tbl)); + + &set_label("loop",16); + &sse_enccompact(); + &add ($key,16); + &cmp ($key,$__end); + &ja (&label("out")); + + &movq ("mm2",&QWP(8,"esp")); + &pxor ("mm3","mm3"); &pxor ("mm7","mm7"); + &movq ("mm1","mm0"); &movq ("mm5","mm4"); # r0 + &pcmpgtb("mm3","mm0"); &pcmpgtb("mm7","mm4"); + &pand ("mm3","mm2"); &pand ("mm7","mm2"); + &pshufw ("mm2","mm0",0xb1); &pshufw ("mm6","mm4",0xb1);# ROTATE(r0,16) + &paddb ("mm0","mm0"); &paddb ("mm4","mm4"); + &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # = r2 + &pshufw ("mm3","mm2",0xb1); &pshufw ("mm7","mm6",0xb1);# r0 + &pxor ("mm1","mm0"); &pxor ("mm5","mm4"); # r0^r2 + &pxor ("mm0","mm2"); &pxor ("mm4","mm6"); # ^= ROTATE(r0,16) + + &movq ("mm2","mm3"); &movq ("mm6","mm7"); + &pslld ("mm3",8); &pslld ("mm7",8); + &psrld ("mm2",24); &psrld ("mm6",24); + &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= r0<<8 + &pxor ("mm0","mm2"); &pxor ("mm4","mm6"); # ^= r0>>24 + + &movq ("mm3","mm1"); &movq ("mm7","mm5"); + &movq ("mm2",&QWP(0,$key)); &movq ("mm6",&QWP(8,$key)); + &psrld ("mm1",8); &psrld ("mm5",8); + &mov ($s0,&DWP(0-128,$tbl)); + &pslld ("mm3",24); &pslld ("mm7",24); + &mov ($s1,&DWP(64-128,$tbl)); + &pxor ("mm0","mm1"); &pxor ("mm4","mm5"); # ^= (r2^r0)<<8 + &mov ($s2,&DWP(128-128,$tbl)); + &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= (r2^r0)>>24 + &mov ($s3,&DWP(192-128,$tbl)); + + &pxor ("mm0","mm2"); &pxor ("mm4","mm6"); + &jmp (&label("loop")); + + &set_label("out",16); + &pxor ("mm0",&QWP(0,$key)); + &pxor ("mm4",&QWP(8,$key)); + + &ret (); +&function_end_B("_sse_AES_encrypt_compact"); + } + +###################################################################### +# Vanilla block function. +###################################################################### + +sub encstep() +{ my ($i,$te,@s) = @_; + my $tmp = $key; + my $out = $i==3?$s[0]:$acc; + + # lines marked with #%e?x[i] denote "reordered" instructions... + if ($i==3) { &mov ($key,$__key); }##%edx + else { &mov ($out,$s[0]); + &and ($out,0xFF); } + if ($i==1) { &shr ($s[0],16); }#%ebx[1] + if ($i==2) { &shr ($s[0],24); }#%ecx[2] + &mov ($out,&DWP(0,$te,$out,8)); + + if ($i==3) { $tmp=$s[1]; }##%eax + &movz ($tmp,&HB($s[1])); + &xor ($out,&DWP(3,$te,$tmp,8)); + + if ($i==3) { $tmp=$s[2]; &mov ($s[1],$__s0); }##%ebx + else { &mov ($tmp,$s[2]); + &shr ($tmp,16); } + if ($i==2) { &and ($s[1],0xFF); }#%edx[2] + &and ($tmp,0xFF); + &xor ($out,&DWP(2,$te,$tmp,8)); + + if ($i==3) { $tmp=$s[3]; &mov ($s[2],$__s1); }##%ecx + elsif($i==2){ &movz ($tmp,&HB($s[3])); }#%ebx[2] + else { &mov ($tmp,$s[3]); + &shr ($tmp,24) } + &xor ($out,&DWP(1,$te,$tmp,8)); + if ($i<2) { &mov (&DWP(4+4*$i,"esp"),$out); } + if ($i==3) { &mov ($s[3],$acc); } + &comment(); +} + +sub enclast() +{ my ($i,$te,@s)=@_; + my $tmp = $key; + my $out = $i==3?$s[0]:$acc; + + if ($i==3) { &mov ($key,$__key); }##%edx + else { &mov ($out,$s[0]); } + &and ($out,0xFF); + if ($i==1) { &shr ($s[0],16); }#%ebx[1] + if ($i==2) { &shr ($s[0],24); }#%ecx[2] + &mov ($out,&DWP(2,$te,$out,8)); + &and ($out,0x000000ff); + + if ($i==3) { $tmp=$s[1]; }##%eax + &movz ($tmp,&HB($s[1])); + &mov ($tmp,&DWP(0,$te,$tmp,8)); + &and ($tmp,0x0000ff00); + &xor ($out,$tmp); + + if ($i==3) { $tmp=$s[2]; &mov ($s[1],$__s0); }##%ebx + else { &mov ($tmp,$s[2]); + &shr ($tmp,16); } + if ($i==2) { &and ($s[1],0xFF); }#%edx[2] + &and ($tmp,0xFF); + &mov ($tmp,&DWP(0,$te,$tmp,8)); + &and ($tmp,0x00ff0000); + &xor ($out,$tmp); + + if ($i==3) { $tmp=$s[3]; &mov ($s[2],$__s1); }##%ecx + elsif($i==2){ &movz ($tmp,&HB($s[3])); }#%ebx[2] + else { &mov ($tmp,$s[3]); + &shr ($tmp,24); } + &mov ($tmp,&DWP(2,$te,$tmp,8)); + &and ($tmp,0xff000000); + &xor ($out,$tmp); + if ($i<2) { &mov (&DWP(4+4*$i,"esp"),$out); } + if ($i==3) { &mov ($s[3],$acc); } +} + +&function_begin_B("_x86_AES_encrypt"); + if ($vertical_spin) { + # I need high parts of volatile registers to be accessible... + &exch ($s1="edi",$key="ebx"); + &mov ($s2="esi",$acc="ecx"); + } + + # note that caller is expected to allocate stack frame for me! + &mov ($__key,$key); # save key + + &xor ($s0,&DWP(0,$key)); # xor with key + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + + &mov ($acc,&DWP(240,$key)); # load key->rounds + + if ($small_footprint) { + &lea ($acc,&DWP(-2,$acc,$acc)); + &lea ($acc,&DWP(0,$key,$acc,8)); + &mov ($__end,$acc); # end of key schedule + + &set_label("loop",16); + if ($vertical_spin) { + &encvert($tbl,$s0,$s1,$s2,$s3); + } else { + &encstep(0,$tbl,$s0,$s1,$s2,$s3); + &encstep(1,$tbl,$s1,$s2,$s3,$s0); + &encstep(2,$tbl,$s2,$s3,$s0,$s1); + &encstep(3,$tbl,$s3,$s0,$s1,$s2); + } + &add ($key,16); # advance rd_key + &xor ($s0,&DWP(0,$key)); + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + &cmp ($key,$__end); + &mov ($__key,$key); + &jb (&label("loop")); + } + else { + &cmp ($acc,10); + &jle (&label("10rounds")); + &cmp ($acc,12); + &jle (&label("12rounds")); + + &set_label("14rounds",4); + for ($i=1;$i<3;$i++) { + if ($vertical_spin) { + &encvert($tbl,$s0,$s1,$s2,$s3); + } else { + &encstep(0,$tbl,$s0,$s1,$s2,$s3); + &encstep(1,$tbl,$s1,$s2,$s3,$s0); + &encstep(2,$tbl,$s2,$s3,$s0,$s1); + &encstep(3,$tbl,$s3,$s0,$s1,$s2); + } + &xor ($s0,&DWP(16*$i+0,$key)); + &xor ($s1,&DWP(16*$i+4,$key)); + &xor ($s2,&DWP(16*$i+8,$key)); + &xor ($s3,&DWP(16*$i+12,$key)); + } + &add ($key,32); + &mov ($__key,$key); # advance rd_key + &set_label("12rounds",4); + for ($i=1;$i<3;$i++) { + if ($vertical_spin) { + &encvert($tbl,$s0,$s1,$s2,$s3); + } else { + &encstep(0,$tbl,$s0,$s1,$s2,$s3); + &encstep(1,$tbl,$s1,$s2,$s3,$s0); + &encstep(2,$tbl,$s2,$s3,$s0,$s1); + &encstep(3,$tbl,$s3,$s0,$s1,$s2); + } + &xor ($s0,&DWP(16*$i+0,$key)); + &xor ($s1,&DWP(16*$i+4,$key)); + &xor ($s2,&DWP(16*$i+8,$key)); + &xor ($s3,&DWP(16*$i+12,$key)); + } + &add ($key,32); + &mov ($__key,$key); # advance rd_key + &set_label("10rounds",4); + for ($i=1;$i<10;$i++) { + if ($vertical_spin) { + &encvert($tbl,$s0,$s1,$s2,$s3); + } else { + &encstep(0,$tbl,$s0,$s1,$s2,$s3); + &encstep(1,$tbl,$s1,$s2,$s3,$s0); + &encstep(2,$tbl,$s2,$s3,$s0,$s1); + &encstep(3,$tbl,$s3,$s0,$s1,$s2); + } + &xor ($s0,&DWP(16*$i+0,$key)); + &xor ($s1,&DWP(16*$i+4,$key)); + &xor ($s2,&DWP(16*$i+8,$key)); + &xor ($s3,&DWP(16*$i+12,$key)); + } + } + + if ($vertical_spin) { + # "reincarnate" some registers for "horizontal" spin... + &mov ($s1="ebx",$key="edi"); + &mov ($s2="ecx",$acc="esi"); + } + &enclast(0,$tbl,$s0,$s1,$s2,$s3); + &enclast(1,$tbl,$s1,$s2,$s3,$s0); + &enclast(2,$tbl,$s2,$s3,$s0,$s1); + &enclast(3,$tbl,$s3,$s0,$s1,$s2); + + &add ($key,$small_footprint?16:160); + &xor ($s0,&DWP(0,$key)); + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + + &ret (); + +&set_label("AES_Te",64); # Yes! I keep it in the code segment! + &_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6); + &_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591); + &_data_word(0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56); + &_data_word(0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec); + &_data_word(0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa); + &_data_word(0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb); + &_data_word(0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45); + &_data_word(0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b); + &_data_word(0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c); + &_data_word(0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83); + &_data_word(0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9); + &_data_word(0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a); + &_data_word(0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d); + &_data_word(0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f); + &_data_word(0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df); + &_data_word(0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea); + &_data_word(0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34); + &_data_word(0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b); + &_data_word(0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d); + &_data_word(0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413); + &_data_word(0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1); + &_data_word(0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6); + &_data_word(0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972); + &_data_word(0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85); + &_data_word(0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed); + &_data_word(0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511); + &_data_word(0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe); + &_data_word(0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b); + &_data_word(0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05); + &_data_word(0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1); + &_data_word(0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142); + &_data_word(0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf); + &_data_word(0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3); + &_data_word(0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e); + &_data_word(0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a); + &_data_word(0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6); + &_data_word(0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3); + &_data_word(0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b); + &_data_word(0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428); + &_data_word(0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad); + &_data_word(0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14); + &_data_word(0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8); + &_data_word(0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4); + &_data_word(0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2); + &_data_word(0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda); + &_data_word(0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949); + &_data_word(0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf); + &_data_word(0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810); + &_data_word(0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c); + &_data_word(0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697); + &_data_word(0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e); + &_data_word(0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f); + &_data_word(0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc); + &_data_word(0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c); + &_data_word(0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969); + &_data_word(0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27); + &_data_word(0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122); + &_data_word(0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433); + &_data_word(0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9); + &_data_word(0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5); + &_data_word(0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a); + &_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0); + &_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e); + &_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c); + +#Te4 # four copies of Te4 to choose from to avoid L1 aliasing + &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5); + &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76); + &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0); + &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0); + &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc); + &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15); + &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a); + &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75); + &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0); + &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84); + &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b); + &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf); + &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85); + &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8); + &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5); + &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2); + &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17); + &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73); + &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88); + &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb); + &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c); + &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79); + &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9); + &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08); + &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6); + &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a); + &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e); + &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e); + &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94); + &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf); + &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68); + &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16); + + &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5); + &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76); + &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0); + &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0); + &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc); + &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15); + &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a); + &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75); + &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0); + &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84); + &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b); + &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf); + &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85); + &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8); + &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5); + &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2); + &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17); + &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73); + &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88); + &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb); + &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c); + &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79); + &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9); + &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08); + &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6); + &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a); + &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e); + &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e); + &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94); + &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf); + &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68); + &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16); + + &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5); + &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76); + &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0); + &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0); + &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc); + &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15); + &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a); + &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75); + &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0); + &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84); + &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b); + &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf); + &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85); + &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8); + &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5); + &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2); + &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17); + &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73); + &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88); + &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb); + &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c); + &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79); + &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9); + &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08); + &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6); + &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a); + &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e); + &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e); + &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94); + &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf); + &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68); + &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16); + + &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5); + &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76); + &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0); + &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0); + &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc); + &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15); + &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a); + &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75); + &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0); + &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84); + &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b); + &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf); + &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85); + &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8); + &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5); + &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2); + &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17); + &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73); + &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88); + &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb); + &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c); + &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79); + &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9); + &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08); + &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6); + &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a); + &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e); + &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e); + &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94); + &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf); + &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68); + &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16); +#rcon: + &data_word(0x00000001, 0x00000002, 0x00000004, 0x00000008); + &data_word(0x00000010, 0x00000020, 0x00000040, 0x00000080); + &data_word(0x0000001b, 0x00000036, 0x00000000, 0x00000000); + &data_word(0x00000000, 0x00000000, 0x00000000, 0x00000000); +&function_end_B("_x86_AES_encrypt"); + +# void AES_encrypt (const void *inp,void *out,const AES_KEY *key); +&function_begin("AES_encrypt"); + &mov ($acc,&wparam(0)); # load inp + &mov ($key,&wparam(2)); # load key + + &mov ($s0,"esp"); + &sub ("esp",36); + &and ("esp",-64); # align to cache-line + + # place stack frame just "above" the key schedule + &lea ($s1,&DWP(-64-63,$key)); + &sub ($s1,"esp"); + &neg ($s1); + &and ($s1,0x3C0); # modulo 1024, but aligned to cache-line + &sub ("esp",$s1); + &add ("esp",4); # 4 is reserved for caller's return address + &mov ($_esp,$s0); # save stack pointer + + &call (&label("pic_point")); # make it PIC! + &set_label("pic_point"); + &blindpop($tbl); + &picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if (!$x86only); + &lea ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl)); + + # pick Te4 copy which can't "overlap" with stack frame or key schedule + &lea ($s1,&DWP(768-4,"esp")); + &sub ($s1,$tbl); + &and ($s1,0x300); + &lea ($tbl,&DWP(2048+128,$tbl,$s1)); + + if (!$x86only) { + &bt (&DWP(0,$s0),25); # check for SSE bit + &jnc (&label("x86")); + + &movq ("mm0",&QWP(0,$acc)); + &movq ("mm4",&QWP(8,$acc)); + &call ("_sse_AES_encrypt_compact"); + &mov ("esp",$_esp); # restore stack pointer + &mov ($acc,&wparam(1)); # load out + &movq (&QWP(0,$acc),"mm0"); # write output data + &movq (&QWP(8,$acc),"mm4"); + &emms (); + &function_end_A(); + } + &set_label("x86",16); + &mov ($_tbl,$tbl); + &mov ($s0,&DWP(0,$acc)); # load input data + &mov ($s1,&DWP(4,$acc)); + &mov ($s2,&DWP(8,$acc)); + &mov ($s3,&DWP(12,$acc)); + &call ("_x86_AES_encrypt_compact"); + &mov ("esp",$_esp); # restore stack pointer + &mov ($acc,&wparam(1)); # load out + &mov (&DWP(0,$acc),$s0); # write output data + &mov (&DWP(4,$acc),$s1); + &mov (&DWP(8,$acc),$s2); + &mov (&DWP(12,$acc),$s3); +&function_end("AES_encrypt"); + +#--------------------------------------------------------------------# + +###################################################################### +# "Compact" block function +###################################################################### + +sub deccompact() +{ my $Fn = mov; + while ($#_>5) { pop(@_); $Fn=sub{}; } + my ($i,$td,@s)=@_; + my $tmp = $key; + my $out = $i==3?$s[0]:$acc; + + # $Fn is used in first compact round and its purpose is to + # void restoration of some values from stack, so that after + # 4xdeccompact with extra argument $key, $s0 and $s1 values + # are left there... + if($i==3) { &$Fn ($key,$__key); } + else { &mov ($out,$s[0]); } + &and ($out,0xFF); + &movz ($out,&BP(-128,$td,$out,1)); + + if ($i==3) { $tmp=$s[1]; } + &movz ($tmp,&HB($s[1])); + &movz ($tmp,&BP(-128,$td,$tmp,1)); + &shl ($tmp,8); + &xor ($out,$tmp); + + if ($i==3) { $tmp=$s[2]; &mov ($s[1],$acc); } + else { mov ($tmp,$s[2]); } + &shr ($tmp,16); + &and ($tmp,0xFF); + &movz ($tmp,&BP(-128,$td,$tmp,1)); + &shl ($tmp,16); + &xor ($out,$tmp); + + if ($i==3) { $tmp=$s[3]; &$Fn ($s[2],$__s1); } + else { &mov ($tmp,$s[3]); } + &shr ($tmp,24); + &movz ($tmp,&BP(-128,$td,$tmp,1)); + &shl ($tmp,24); + &xor ($out,$tmp); + if ($i<2) { &mov (&DWP(4+4*$i,"esp"),$out); } + if ($i==3) { &$Fn ($s[3],$__s0); } +} + +# must be called with 2,3,0,1 as argument sequence!!! +sub dectransform() +{ my @s = ($s0,$s1,$s2,$s3); + my $i = shift; + my $tmp = $key; + my $tp2 = @s[($i+2)%4]; $tp2 = @s[2] if ($i==1); + my $tp4 = @s[($i+3)%4]; $tp4 = @s[3] if ($i==1); + my $tp8 = $tbl; + + &mov ($acc,$s[$i]); + &and ($acc,0x80808080); + &mov ($tmp,$acc); + &shr ($tmp,7); + &lea ($tp2,&DWP(0,$s[$i],$s[$i])); + &sub ($acc,$tmp); + &and ($tp2,0xfefefefe); + &and ($acc,0x1b1b1b1b); + &xor ($acc,$tp2); + &mov ($tp2,$acc); + + &and ($acc,0x80808080); + &mov ($tmp,$acc); + &shr ($tmp,7); + &lea ($tp4,&DWP(0,$tp2,$tp2)); + &sub ($acc,$tmp); + &and ($tp4,0xfefefefe); + &and ($acc,0x1b1b1b1b); + &xor ($tp2,$s[$i]); # tp2^tp1 + &xor ($acc,$tp4); + &mov ($tp4,$acc); + + &and ($acc,0x80808080); + &mov ($tmp,$acc); + &shr ($tmp,7); + &lea ($tp8,&DWP(0,$tp4,$tp4)); + &sub ($acc,$tmp); + &and ($tp8,0xfefefefe); + &and ($acc,0x1b1b1b1b); + &xor ($tp4,$s[$i]); # tp4^tp1 + &rotl ($s[$i],8); # = ROTATE(tp1,8) + &xor ($tp8,$acc); + + &xor ($s[$i],$tp2); + &xor ($tp2,$tp8); + &rotl ($tp2,24); + &xor ($s[$i],$tp4); + &xor ($tp4,$tp8); + &rotl ($tp4,16); + &xor ($s[$i],$tp8); # ^= tp8^(tp4^tp1)^(tp2^tp1) + &rotl ($tp8,8); + &xor ($s[$i],$tp2); # ^= ROTATE(tp8^tp2^tp1,24) + &xor ($s[$i],$tp4); # ^= ROTATE(tp8^tp4^tp1,16) + &mov ($s[0],$__s0) if($i==2); #prefetch $s0 + &mov ($s[1],$__s1) if($i==3); #prefetch $s1 + &mov ($s[2],$__s2) if($i==1); + &xor ($s[$i],$tp8); # ^= ROTATE(tp8,8) + + &mov ($s[3],$__s3) if($i==1); + &mov (&DWP(4+4*$i,"esp"),$s[$i]) if($i>=2); +} + +&function_begin_B("_x86_AES_decrypt_compact"); + # note that caller is expected to allocate stack frame for me! + &mov ($__key,$key); # save key + + &xor ($s0,&DWP(0,$key)); # xor with key + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + + &mov ($acc,&DWP(240,$key)); # load key->rounds + + &lea ($acc,&DWP(-2,$acc,$acc)); + &lea ($acc,&DWP(0,$key,$acc,8)); + &mov ($__end,$acc); # end of key schedule + + # prefetch Td4 + &mov ($key,&DWP(0-128,$tbl)); + &mov ($acc,&DWP(32-128,$tbl)); + &mov ($key,&DWP(64-128,$tbl)); + &mov ($acc,&DWP(96-128,$tbl)); + &mov ($key,&DWP(128-128,$tbl)); + &mov ($acc,&DWP(160-128,$tbl)); + &mov ($key,&DWP(192-128,$tbl)); + &mov ($acc,&DWP(224-128,$tbl)); + + &set_label("loop",16); + + &deccompact(0,$tbl,$s0,$s3,$s2,$s1,1); + &deccompact(1,$tbl,$s1,$s0,$s3,$s2,1); + &deccompact(2,$tbl,$s2,$s1,$s0,$s3,1); + &deccompact(3,$tbl,$s3,$s2,$s1,$s0,1); + &dectransform(2); + &dectransform(3); + &dectransform(0); + &dectransform(1); + &mov ($key,$__key); + &mov ($tbl,$__tbl); + &add ($key,16); # advance rd_key + &xor ($s0,&DWP(0,$key)); + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + + &cmp ($key,$__end); + &mov ($__key,$key); + &jb (&label("loop")); + + &deccompact(0,$tbl,$s0,$s3,$s2,$s1); + &deccompact(1,$tbl,$s1,$s0,$s3,$s2); + &deccompact(2,$tbl,$s2,$s1,$s0,$s3); + &deccompact(3,$tbl,$s3,$s2,$s1,$s0); + + &xor ($s0,&DWP(16,$key)); + &xor ($s1,&DWP(20,$key)); + &xor ($s2,&DWP(24,$key)); + &xor ($s3,&DWP(28,$key)); + + &ret (); +&function_end_B("_x86_AES_decrypt_compact"); + +###################################################################### +# "Compact" SSE block function. +###################################################################### + +sub sse_deccompact() +{ + &pshufw ("mm1","mm0",0x0c); # 7, 6, 1, 0 + &movd ("eax","mm1"); # 7, 6, 1, 0 + + &pshufw ("mm5","mm4",0x09); # 13,12,11,10 + &movz ($acc,&LB("eax")); # 0 + &movz ("ecx",&BP(-128,$tbl,$acc,1)); # 0 + &movd ("ebx","mm5"); # 13,12,11,10 + &movz ("edx",&HB("eax")); # 1 + &movz ("edx",&BP(-128,$tbl,"edx",1)); # 1 + &shl ("edx",8); # 1 + + &pshufw ("mm2","mm0",0x06); # 3, 2, 5, 4 + &movz ($acc,&LB("ebx")); # 10 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 10 + &shl ($acc,16); # 10 + &or ("ecx",$acc); # 10 + &shr ("eax",16); # 7, 6 + &movz ($acc,&HB("ebx")); # 11 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 11 + &shl ($acc,24); # 11 + &or ("edx",$acc); # 11 + &shr ("ebx",16); # 13,12 + + &pshufw ("mm6","mm4",0x03); # 9, 8,15,14 + &movz ($acc,&HB("eax")); # 7 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 7 + &shl ($acc,24); # 7 + &or ("ecx",$acc); # 7 + &movz ($acc,&HB("ebx")); # 13 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 13 + &shl ($acc,8); # 13 + &or ("ecx",$acc); # 13 + &movd ("mm0","ecx"); # t[0] collected + + &movz ($acc,&LB("eax")); # 6 + &movd ("eax","mm2"); # 3, 2, 5, 4 + &movz ("ecx",&BP(-128,$tbl,$acc,1)); # 6 + &shl ("ecx",16); # 6 + &movz ($acc,&LB("ebx")); # 12 + &movd ("ebx","mm6"); # 9, 8,15,14 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 12 + &or ("ecx",$acc); # 12 + + &movz ($acc,&LB("eax")); # 4 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 4 + &or ("edx",$acc); # 4 + &movz ($acc,&LB("ebx")); # 14 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 14 + &shl ($acc,16); # 14 + &or ("edx",$acc); # 14 + &movd ("mm1","edx"); # t[1] collected + + &movz ($acc,&HB("eax")); # 5 + &movz ("edx",&BP(-128,$tbl,$acc,1)); # 5 + &shl ("edx",8); # 5 + &movz ($acc,&HB("ebx")); # 15 + &shr ("eax",16); # 3, 2 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 15 + &shl ($acc,24); # 15 + &or ("edx",$acc); # 15 + &shr ("ebx",16); # 9, 8 + + &punpckldq ("mm0","mm1"); # t[0,1] collected + + &movz ($acc,&HB("ebx")); # 9 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 9 + &shl ($acc,8); # 9 + &or ("ecx",$acc); # 9 + &and ("ebx",0xff); # 8 + &movz ("ebx",&BP(-128,$tbl,"ebx",1)); # 8 + &or ("edx","ebx"); # 8 + &movz ($acc,&LB("eax")); # 2 + &movz ($acc,&BP(-128,$tbl,$acc,1)); # 2 + &shl ($acc,16); # 2 + &or ("edx",$acc); # 2 + &movd ("mm4","edx"); # t[2] collected + &movz ("eax",&HB("eax")); # 3 + &movz ("eax",&BP(-128,$tbl,"eax",1)); # 3 + &shl ("eax",24); # 3 + &or ("ecx","eax"); # 3 + &movd ("mm5","ecx"); # t[3] collected + + &punpckldq ("mm4","mm5"); # t[2,3] collected +} + + if (!$x86only) { +&function_begin_B("_sse_AES_decrypt_compact"); + &pxor ("mm0",&QWP(0,$key)); # 7, 6, 5, 4, 3, 2, 1, 0 + &pxor ("mm4",&QWP(8,$key)); # 15,14,13,12,11,10, 9, 8 + + # note that caller is expected to allocate stack frame for me! + &mov ($acc,&DWP(240,$key)); # load key->rounds + &lea ($acc,&DWP(-2,$acc,$acc)); + &lea ($acc,&DWP(0,$key,$acc,8)); + &mov ($__end,$acc); # end of key schedule + + &mov ($s0,0x1b1b1b1b); # magic constant + &mov (&DWP(8,"esp"),$s0); + &mov (&DWP(12,"esp"),$s0); + + # prefetch Td4 + &mov ($s0,&DWP(0-128,$tbl)); + &mov ($s1,&DWP(32-128,$tbl)); + &mov ($s2,&DWP(64-128,$tbl)); + &mov ($s3,&DWP(96-128,$tbl)); + &mov ($s0,&DWP(128-128,$tbl)); + &mov ($s1,&DWP(160-128,$tbl)); + &mov ($s2,&DWP(192-128,$tbl)); + &mov ($s3,&DWP(224-128,$tbl)); + + &set_label("loop",16); + &sse_deccompact(); + &add ($key,16); + &cmp ($key,$__end); + &ja (&label("out")); + + # ROTATE(x^y,N) == ROTATE(x,N)^ROTATE(y,N) + &movq ("mm3","mm0"); &movq ("mm7","mm4"); + &movq ("mm2","mm0",1); &movq ("mm6","mm4",1); + &movq ("mm1","mm0"); &movq ("mm5","mm4"); + &pshufw ("mm0","mm0",0xb1); &pshufw ("mm4","mm4",0xb1);# = ROTATE(tp0,16) + &pslld ("mm2",8); &pslld ("mm6",8); + &psrld ("mm3",8); &psrld ("mm7",8); + &pxor ("mm0","mm2"); &pxor ("mm4","mm6"); # ^= tp0<<8 + &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= tp0>>8 + &pslld ("mm2",16); &pslld ("mm6",16); + &psrld ("mm3",16); &psrld ("mm7",16); + &pxor ("mm0","mm2"); &pxor ("mm4","mm6"); # ^= tp0<<24 + &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= tp0>>24 + + &movq ("mm3",&QWP(8,"esp")); + &pxor ("mm2","mm2"); &pxor ("mm6","mm6"); + &pcmpgtb("mm2","mm1"); &pcmpgtb("mm6","mm5"); + &pand ("mm2","mm3"); &pand ("mm6","mm3"); + &paddb ("mm1","mm1"); &paddb ("mm5","mm5"); + &pxor ("mm1","mm2"); &pxor ("mm5","mm6"); # tp2 + &movq ("mm3","mm1"); &movq ("mm7","mm5"); + &movq ("mm2","mm1"); &movq ("mm6","mm5"); + &pxor ("mm0","mm1"); &pxor ("mm4","mm5"); # ^= tp2 + &pslld ("mm3",24); &pslld ("mm7",24); + &psrld ("mm2",8); &psrld ("mm6",8); + &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= tp2<<24 + &pxor ("mm0","mm2"); &pxor ("mm4","mm6"); # ^= tp2>>8 + + &movq ("mm2",&QWP(8,"esp")); + &pxor ("mm3","mm3"); &pxor ("mm7","mm7"); + &pcmpgtb("mm3","mm1"); &pcmpgtb("mm7","mm5"); + &pand ("mm3","mm2"); &pand ("mm7","mm2"); + &paddb ("mm1","mm1"); &paddb ("mm5","mm5"); + &pxor ("mm1","mm3"); &pxor ("mm5","mm7"); # tp4 + &pshufw ("mm3","mm1",0xb1); &pshufw ("mm7","mm5",0xb1); + &pxor ("mm0","mm1"); &pxor ("mm4","mm5"); # ^= tp4 + &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= ROTATE(tp4,16) + + &pxor ("mm3","mm3"); &pxor ("mm7","mm7"); + &pcmpgtb("mm3","mm1"); &pcmpgtb("mm7","mm5"); + &pand ("mm3","mm2"); &pand ("mm7","mm2"); + &paddb ("mm1","mm1"); &paddb ("mm5","mm5"); + &pxor ("mm1","mm3"); &pxor ("mm5","mm7"); # tp8 + &pxor ("mm0","mm1"); &pxor ("mm4","mm5"); # ^= tp8 + &movq ("mm3","mm1"); &movq ("mm7","mm5"); + &pshufw ("mm2","mm1",0xb1); &pshufw ("mm6","mm5",0xb1); + &pxor ("mm0","mm2"); &pxor ("mm4","mm6"); # ^= ROTATE(tp8,16) + &pslld ("mm1",8); &pslld ("mm5",8); + &psrld ("mm3",8); &psrld ("mm7",8); + &movq ("mm2",&QWP(0,$key)); &movq ("mm6",&QWP(8,$key)); + &pxor ("mm0","mm1"); &pxor ("mm4","mm5"); # ^= tp8<<8 + &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= tp8>>8 + &mov ($s0,&DWP(0-128,$tbl)); + &pslld ("mm1",16); &pslld ("mm5",16); + &mov ($s1,&DWP(64-128,$tbl)); + &psrld ("mm3",16); &psrld ("mm7",16); + &mov ($s2,&DWP(128-128,$tbl)); + &pxor ("mm0","mm1"); &pxor ("mm4","mm5"); # ^= tp8<<24 + &mov ($s3,&DWP(192-128,$tbl)); + &pxor ("mm0","mm3"); &pxor ("mm4","mm7"); # ^= tp8>>24 + + &pxor ("mm0","mm2"); &pxor ("mm4","mm6"); + &jmp (&label("loop")); + + &set_label("out",16); + &pxor ("mm0",&QWP(0,$key)); + &pxor ("mm4",&QWP(8,$key)); + + &ret (); +&function_end_B("_sse_AES_decrypt_compact"); + } + +###################################################################### +# Vanilla block function. +###################################################################### + +sub decstep() +{ my ($i,$td,@s) = @_; + my $tmp = $key; + my $out = $i==3?$s[0]:$acc; + + # no instructions are reordered, as performance appears + # optimal... or rather that all attempts to reorder didn't + # result in better performance [which by the way is not a + # bit lower than ecryption]. + if($i==3) { &mov ($key,$__key); } + else { &mov ($out,$s[0]); } + &and ($out,0xFF); + &mov ($out,&DWP(0,$td,$out,8)); + + if ($i==3) { $tmp=$s[1]; } + &movz ($tmp,&HB($s[1])); + &xor ($out,&DWP(3,$td,$tmp,8)); + + if ($i==3) { $tmp=$s[2]; &mov ($s[1],$acc); } + else { &mov ($tmp,$s[2]); } + &shr ($tmp,16); + &and ($tmp,0xFF); + &xor ($out,&DWP(2,$td,$tmp,8)); + + if ($i==3) { $tmp=$s[3]; &mov ($s[2],$__s1); } + else { &mov ($tmp,$s[3]); } + &shr ($tmp,24); + &xor ($out,&DWP(1,$td,$tmp,8)); + if ($i<2) { &mov (&DWP(4+4*$i,"esp"),$out); } + if ($i==3) { &mov ($s[3],$__s0); } + &comment(); +} + +sub declast() +{ my ($i,$td,@s)=@_; + my $tmp = $key; + my $out = $i==3?$s[0]:$acc; + + if($i==0) { &lea ($td,&DWP(2048+128,$td)); + &mov ($tmp,&DWP(0-128,$td)); + &mov ($acc,&DWP(32-128,$td)); + &mov ($tmp,&DWP(64-128,$td)); + &mov ($acc,&DWP(96-128,$td)); + &mov ($tmp,&DWP(128-128,$td)); + &mov ($acc,&DWP(160-128,$td)); + &mov ($tmp,&DWP(192-128,$td)); + &mov ($acc,&DWP(224-128,$td)); + &lea ($td,&DWP(-128,$td)); } + if($i==3) { &mov ($key,$__key); } + else { &mov ($out,$s[0]); } + &and ($out,0xFF); + &movz ($out,&BP(0,$td,$out,1)); + + if ($i==3) { $tmp=$s[1]; } + &movz ($tmp,&HB($s[1])); + &movz ($tmp,&BP(0,$td,$tmp,1)); + &shl ($tmp,8); + &xor ($out,$tmp); + + if ($i==3) { $tmp=$s[2]; &mov ($s[1],$acc); } + else { mov ($tmp,$s[2]); } + &shr ($tmp,16); + &and ($tmp,0xFF); + &movz ($tmp,&BP(0,$td,$tmp,1)); + &shl ($tmp,16); + &xor ($out,$tmp); + + if ($i==3) { $tmp=$s[3]; &mov ($s[2],$__s1); } + else { &mov ($tmp,$s[3]); } + &shr ($tmp,24); + &movz ($tmp,&BP(0,$td,$tmp,1)); + &shl ($tmp,24); + &xor ($out,$tmp); + if ($i<2) { &mov (&DWP(4+4*$i,"esp"),$out); } + if ($i==3) { &mov ($s[3],$__s0); + &lea ($td,&DWP(-2048,$td)); } +} + +&function_begin_B("_x86_AES_decrypt"); + # note that caller is expected to allocate stack frame for me! + &mov ($__key,$key); # save key + + &xor ($s0,&DWP(0,$key)); # xor with key + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + + &mov ($acc,&DWP(240,$key)); # load key->rounds + + if ($small_footprint) { + &lea ($acc,&DWP(-2,$acc,$acc)); + &lea ($acc,&DWP(0,$key,$acc,8)); + &mov ($__end,$acc); # end of key schedule + &set_label("loop",16); + &decstep(0,$tbl,$s0,$s3,$s2,$s1); + &decstep(1,$tbl,$s1,$s0,$s3,$s2); + &decstep(2,$tbl,$s2,$s1,$s0,$s3); + &decstep(3,$tbl,$s3,$s2,$s1,$s0); + &add ($key,16); # advance rd_key + &xor ($s0,&DWP(0,$key)); + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + &cmp ($key,$__end); + &mov ($__key,$key); + &jb (&label("loop")); + } + else { + &cmp ($acc,10); + &jle (&label("10rounds")); + &cmp ($acc,12); + &jle (&label("12rounds")); + + &set_label("14rounds",4); + for ($i=1;$i<3;$i++) { + &decstep(0,$tbl,$s0,$s3,$s2,$s1); + &decstep(1,$tbl,$s1,$s0,$s3,$s2); + &decstep(2,$tbl,$s2,$s1,$s0,$s3); + &decstep(3,$tbl,$s3,$s2,$s1,$s0); + &xor ($s0,&DWP(16*$i+0,$key)); + &xor ($s1,&DWP(16*$i+4,$key)); + &xor ($s2,&DWP(16*$i+8,$key)); + &xor ($s3,&DWP(16*$i+12,$key)); + } + &add ($key,32); + &mov ($__key,$key); # advance rd_key + &set_label("12rounds",4); + for ($i=1;$i<3;$i++) { + &decstep(0,$tbl,$s0,$s3,$s2,$s1); + &decstep(1,$tbl,$s1,$s0,$s3,$s2); + &decstep(2,$tbl,$s2,$s1,$s0,$s3); + &decstep(3,$tbl,$s3,$s2,$s1,$s0); + &xor ($s0,&DWP(16*$i+0,$key)); + &xor ($s1,&DWP(16*$i+4,$key)); + &xor ($s2,&DWP(16*$i+8,$key)); + &xor ($s3,&DWP(16*$i+12,$key)); + } + &add ($key,32); + &mov ($__key,$key); # advance rd_key + &set_label("10rounds",4); + for ($i=1;$i<10;$i++) { + &decstep(0,$tbl,$s0,$s3,$s2,$s1); + &decstep(1,$tbl,$s1,$s0,$s3,$s2); + &decstep(2,$tbl,$s2,$s1,$s0,$s3); + &decstep(3,$tbl,$s3,$s2,$s1,$s0); + &xor ($s0,&DWP(16*$i+0,$key)); + &xor ($s1,&DWP(16*$i+4,$key)); + &xor ($s2,&DWP(16*$i+8,$key)); + &xor ($s3,&DWP(16*$i+12,$key)); + } + } + + &declast(0,$tbl,$s0,$s3,$s2,$s1); + &declast(1,$tbl,$s1,$s0,$s3,$s2); + &declast(2,$tbl,$s2,$s1,$s0,$s3); + &declast(3,$tbl,$s3,$s2,$s1,$s0); + + &add ($key,$small_footprint?16:160); + &xor ($s0,&DWP(0,$key)); + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + + &ret (); + +&set_label("AES_Td",64); # Yes! I keep it in the code segment! + &_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a); + &_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b); + &_data_word(0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5); + &_data_word(0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5); + &_data_word(0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d); + &_data_word(0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b); + &_data_word(0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295); + &_data_word(0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e); + &_data_word(0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927); + &_data_word(0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d); + &_data_word(0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362); + &_data_word(0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9); + &_data_word(0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52); + &_data_word(0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566); + &_data_word(0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3); + &_data_word(0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed); + &_data_word(0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e); + &_data_word(0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4); + &_data_word(0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4); + &_data_word(0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd); + &_data_word(0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d); + &_data_word(0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060); + &_data_word(0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967); + &_data_word(0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879); + &_data_word(0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000); + &_data_word(0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c); + &_data_word(0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36); + &_data_word(0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624); + &_data_word(0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b); + &_data_word(0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c); + &_data_word(0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12); + &_data_word(0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14); + &_data_word(0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3); + &_data_word(0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b); + &_data_word(0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8); + &_data_word(0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684); + &_data_word(0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7); + &_data_word(0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177); + &_data_word(0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947); + &_data_word(0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322); + &_data_word(0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498); + &_data_word(0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f); + &_data_word(0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54); + &_data_word(0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382); + &_data_word(0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf); + &_data_word(0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb); + &_data_word(0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83); + &_data_word(0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef); + &_data_word(0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029); + &_data_word(0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235); + &_data_word(0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733); + &_data_word(0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117); + &_data_word(0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4); + &_data_word(0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546); + &_data_word(0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb); + &_data_word(0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d); + &_data_word(0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb); + &_data_word(0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a); + &_data_word(0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773); + &_data_word(0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478); + &_data_word(0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2); + &_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff); + &_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664); + &_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0); + +#Td4: # four copies of Td4 to choose from to avoid L1 aliasing + &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); + &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); + &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); + &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb); + &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d); + &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e); + &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2); + &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25); + &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16); + &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92); + &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda); + &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84); + &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a); + &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06); + &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02); + &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b); + &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea); + &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73); + &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85); + &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e); + &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89); + &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b); + &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20); + &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4); + &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31); + &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f); + &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d); + &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef); + &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0); + &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); + &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); + &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); + + &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); + &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); + &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); + &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb); + &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d); + &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e); + &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2); + &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25); + &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16); + &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92); + &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda); + &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84); + &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a); + &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06); + &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02); + &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b); + &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea); + &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73); + &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85); + &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e); + &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89); + &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b); + &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20); + &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4); + &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31); + &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f); + &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d); + &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef); + &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0); + &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); + &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); + &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); + + &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); + &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); + &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); + &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb); + &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d); + &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e); + &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2); + &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25); + &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16); + &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92); + &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda); + &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84); + &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a); + &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06); + &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02); + &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b); + &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea); + &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73); + &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85); + &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e); + &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89); + &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b); + &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20); + &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4); + &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31); + &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f); + &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d); + &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef); + &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0); + &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); + &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); + &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); + + &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); + &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); + &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); + &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb); + &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d); + &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e); + &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2); + &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25); + &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16); + &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92); + &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda); + &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84); + &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a); + &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06); + &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02); + &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b); + &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea); + &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73); + &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85); + &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e); + &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89); + &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b); + &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20); + &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4); + &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31); + &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f); + &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d); + &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef); + &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0); + &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); + &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); + &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); +&function_end_B("_x86_AES_decrypt"); + +# void AES_decrypt (const void *inp,void *out,const AES_KEY *key); +&function_begin("AES_decrypt"); + &mov ($acc,&wparam(0)); # load inp + &mov ($key,&wparam(2)); # load key + + &mov ($s0,"esp"); + &sub ("esp",36); + &and ("esp",-64); # align to cache-line + + # place stack frame just "above" the key schedule + &lea ($s1,&DWP(-64-63,$key)); + &sub ($s1,"esp"); + &neg ($s1); + &and ($s1,0x3C0); # modulo 1024, but aligned to cache-line + &sub ("esp",$s1); + &add ("esp",4); # 4 is reserved for caller's return address + &mov ($_esp,$s0); # save stack pointer + + &call (&label("pic_point")); # make it PIC! + &set_label("pic_point"); + &blindpop($tbl); + &picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if(!$x86only); + &lea ($tbl,&DWP(&label("AES_Td")."-".&label("pic_point"),$tbl)); + + # pick Td4 copy which can't "overlap" with stack frame or key schedule + &lea ($s1,&DWP(768-4,"esp")); + &sub ($s1,$tbl); + &and ($s1,0x300); + &lea ($tbl,&DWP(2048+128,$tbl,$s1)); + + if (!$x86only) { + &bt (&DWP(0,$s0),25); # check for SSE bit + &jnc (&label("x86")); + + &movq ("mm0",&QWP(0,$acc)); + &movq ("mm4",&QWP(8,$acc)); + &call ("_sse_AES_decrypt_compact"); + &mov ("esp",$_esp); # restore stack pointer + &mov ($acc,&wparam(1)); # load out + &movq (&QWP(0,$acc),"mm0"); # write output data + &movq (&QWP(8,$acc),"mm4"); + &emms (); + &function_end_A(); + } + &set_label("x86",16); + &mov ($_tbl,$tbl); + &mov ($s0,&DWP(0,$acc)); # load input data + &mov ($s1,&DWP(4,$acc)); + &mov ($s2,&DWP(8,$acc)); + &mov ($s3,&DWP(12,$acc)); + &call ("_x86_AES_decrypt_compact"); + &mov ("esp",$_esp); # restore stack pointer + &mov ($acc,&wparam(1)); # load out + &mov (&DWP(0,$acc),$s0); # write output data + &mov (&DWP(4,$acc),$s1); + &mov (&DWP(8,$acc),$s2); + &mov (&DWP(12,$acc),$s3); +&function_end("AES_decrypt"); + +# void AES_cbc_encrypt (const void char *inp, unsigned char *out, +# size_t length, const AES_KEY *key, +# unsigned char *ivp,const int enc); +{ +# stack frame layout +# -4(%esp) # return address 0(%esp) +# 0(%esp) # s0 backing store 4(%esp) +# 4(%esp) # s1 backing store 8(%esp) +# 8(%esp) # s2 backing store 12(%esp) +# 12(%esp) # s3 backing store 16(%esp) +# 16(%esp) # key backup 20(%esp) +# 20(%esp) # end of key schedule 24(%esp) +# 24(%esp) # %ebp backup 28(%esp) +# 28(%esp) # %esp backup +my $_inp=&DWP(32,"esp"); # copy of wparam(0) +my $_out=&DWP(36,"esp"); # copy of wparam(1) +my $_len=&DWP(40,"esp"); # copy of wparam(2) +my $_key=&DWP(44,"esp"); # copy of wparam(3) +my $_ivp=&DWP(48,"esp"); # copy of wparam(4) +my $_tmp=&DWP(52,"esp"); # volatile variable +# +my $ivec=&DWP(60,"esp"); # ivec[16] +my $aes_key=&DWP(76,"esp"); # copy of aes_key +my $mark=&DWP(76+240,"esp"); # copy of aes_key->rounds + +&function_begin("AES_cbc_encrypt"); + &mov ($s2 eq "ecx"? $s2 : "",&wparam(2)); # load len + &cmp ($s2,0); + &je (&label("drop_out")); + + &call (&label("pic_point")); # make it PIC! + &set_label("pic_point"); + &blindpop($tbl); + &picmeup($s0,"OPENSSL_ia32cap_P",$tbl,&label("pic_point")) if(!$x86only); + + &cmp (&wparam(5),0); + &lea ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl)); + &jne (&label("picked_te")); + &lea ($tbl,&DWP(&label("AES_Td")."-".&label("AES_Te"),$tbl)); + &set_label("picked_te"); + + # one can argue if this is required + &pushf (); + &cld (); + + &cmp ($s2,$speed_limit); + &jb (&label("slow_way")); + &test ($s2,15); + &jnz (&label("slow_way")); + if (!$x86only) { + &bt (&DWP(0,$s0),28); # check for hyper-threading bit + &jc (&label("slow_way")); + } + # pre-allocate aligned stack frame... + &lea ($acc,&DWP(-80-244,"esp")); + &and ($acc,-64); + + # ... and make sure it doesn't alias with $tbl modulo 4096 + &mov ($s0,$tbl); + &lea ($s1,&DWP(2048+256,$tbl)); + &mov ($s3,$acc); + &and ($s0,0xfff); # s = %ebp&0xfff + &and ($s1,0xfff); # e = (%ebp+2048+256)&0xfff + &and ($s3,0xfff); # p = %esp&0xfff + + &cmp ($s3,$s1); # if (p>=e) %esp =- (p-e); + &jb (&label("tbl_break_out")); + &sub ($s3,$s1); + &sub ($acc,$s3); + &jmp (&label("tbl_ok")); + &set_label("tbl_break_out",4); # else %esp -= (p-s)&0xfff + framesz; + &sub ($s3,$s0); + &and ($s3,0xfff); + &add ($s3,384); + &sub ($acc,$s3); + &set_label("tbl_ok",4); + + &lea ($s3,&wparam(0)); # obtain pointer to parameter block + &exch ("esp",$acc); # allocate stack frame + &add ("esp",4); # reserve for return address! + &mov ($_tbl,$tbl); # save %ebp + &mov ($_esp,$acc); # save %esp + + &mov ($s0,&DWP(0,$s3)); # load inp + &mov ($s1,&DWP(4,$s3)); # load out + #&mov ($s2,&DWP(8,$s3)); # load len + &mov ($key,&DWP(12,$s3)); # load key + &mov ($acc,&DWP(16,$s3)); # load ivp + &mov ($s3,&DWP(20,$s3)); # load enc flag + + &mov ($_inp,$s0); # save copy of inp + &mov ($_out,$s1); # save copy of out + &mov ($_len,$s2); # save copy of len + &mov ($_key,$key); # save copy of key + &mov ($_ivp,$acc); # save copy of ivp + + &mov ($mark,0); # copy of aes_key->rounds = 0; + # do we copy key schedule to stack? + &mov ($s1 eq "ebx" ? $s1 : "",$key); + &mov ($s2 eq "ecx" ? $s2 : "",244/4); + &sub ($s1,$tbl); + &mov ("esi",$key); + &and ($s1,0xfff); + &lea ("edi",$aes_key); + &cmp ($s1,2048+256); + &jb (&label("do_copy")); + &cmp ($s1,4096-244); + &jb (&label("skip_copy")); + &set_label("do_copy",4); + &mov ($_key,"edi"); + &data_word(0xA5F3F689); # rep movsd + &set_label("skip_copy"); + + &mov ($key,16); + &set_label("prefetch_tbl",4); + &mov ($s0,&DWP(0,$tbl)); + &mov ($s1,&DWP(32,$tbl)); + &mov ($s2,&DWP(64,$tbl)); + &mov ($acc,&DWP(96,$tbl)); + &lea ($tbl,&DWP(128,$tbl)); + &sub ($key,1); + &jnz (&label("prefetch_tbl")); + &sub ($tbl,2048); + + &mov ($acc,$_inp); + &mov ($key,$_ivp); + + &cmp ($s3,0); + &je (&label("fast_decrypt")); + +#----------------------------- ENCRYPT -----------------------------# + &mov ($s0,&DWP(0,$key)); # load iv + &mov ($s1,&DWP(4,$key)); + + &set_label("fast_enc_loop",16); + &mov ($s2,&DWP(8,$key)); + &mov ($s3,&DWP(12,$key)); + + &xor ($s0,&DWP(0,$acc)); # xor input data + &xor ($s1,&DWP(4,$acc)); + &xor ($s2,&DWP(8,$acc)); + &xor ($s3,&DWP(12,$acc)); + + &mov ($key,$_key); # load key + &call ("_x86_AES_encrypt"); + + &mov ($acc,$_inp); # load inp + &mov ($key,$_out); # load out + + &mov (&DWP(0,$key),$s0); # save output data + &mov (&DWP(4,$key),$s1); + &mov (&DWP(8,$key),$s2); + &mov (&DWP(12,$key),$s3); + + &lea ($acc,&DWP(16,$acc)); # advance inp + &mov ($s2,$_len); # load len + &mov ($_inp,$acc); # save inp + &lea ($s3,&DWP(16,$key)); # advance out + &mov ($_out,$s3); # save out + &sub ($s2,16); # decrease len + &mov ($_len,$s2); # save len + &jnz (&label("fast_enc_loop")); + &mov ($acc,$_ivp); # load ivp + &mov ($s2,&DWP(8,$key)); # restore last 2 dwords + &mov ($s3,&DWP(12,$key)); + &mov (&DWP(0,$acc),$s0); # save ivec + &mov (&DWP(4,$acc),$s1); + &mov (&DWP(8,$acc),$s2); + &mov (&DWP(12,$acc),$s3); + + &cmp ($mark,0); # was the key schedule copied? + &mov ("edi",$_key); + &je (&label("skip_ezero")); + # zero copy of key schedule + &mov ("ecx",240/4); + &xor ("eax","eax"); + &align (4); + &data_word(0xABF3F689); # rep stosd + &set_label("skip_ezero") + &mov ("esp",$_esp); + &popf (); + &set_label("drop_out"); + &function_end_A(); + &pushf (); # kludge, never executed + +#----------------------------- DECRYPT -----------------------------# +&set_label("fast_decrypt",16); + + &cmp ($acc,$_out); + &je (&label("fast_dec_in_place")); # in-place processing... + + &mov ($_tmp,$key); + + &align (4); + &set_label("fast_dec_loop",16); + &mov ($s0,&DWP(0,$acc)); # read input + &mov ($s1,&DWP(4,$acc)); + &mov ($s2,&DWP(8,$acc)); + &mov ($s3,&DWP(12,$acc)); + + &mov ($key,$_key); # load key + &call ("_x86_AES_decrypt"); + + &mov ($key,$_tmp); # load ivp + &mov ($acc,$_len); # load len + &xor ($s0,&DWP(0,$key)); # xor iv + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + + &mov ($key,$_out); # load out + &mov ($acc,$_inp); # load inp + + &mov (&DWP(0,$key),$s0); # write output + &mov (&DWP(4,$key),$s1); + &mov (&DWP(8,$key),$s2); + &mov (&DWP(12,$key),$s3); + + &mov ($s2,$_len); # load len + &mov ($_tmp,$acc); # save ivp + &lea ($acc,&DWP(16,$acc)); # advance inp + &mov ($_inp,$acc); # save inp + &lea ($key,&DWP(16,$key)); # advance out + &mov ($_out,$key); # save out + &sub ($s2,16); # decrease len + &mov ($_len,$s2); # save len + &jnz (&label("fast_dec_loop")); + &mov ($key,$_tmp); # load temp ivp + &mov ($acc,$_ivp); # load user ivp + &mov ($s0,&DWP(0,$key)); # load iv + &mov ($s1,&DWP(4,$key)); + &mov ($s2,&DWP(8,$key)); + &mov ($s3,&DWP(12,$key)); + &mov (&DWP(0,$acc),$s0); # copy back to user + &mov (&DWP(4,$acc),$s1); + &mov (&DWP(8,$acc),$s2); + &mov (&DWP(12,$acc),$s3); + &jmp (&label("fast_dec_out")); + + &set_label("fast_dec_in_place",16); + &set_label("fast_dec_in_place_loop"); + &mov ($s0,&DWP(0,$acc)); # read input + &mov ($s1,&DWP(4,$acc)); + &mov ($s2,&DWP(8,$acc)); + &mov ($s3,&DWP(12,$acc)); + + &lea ($key,$ivec); + &mov (&DWP(0,$key),$s0); # copy to temp + &mov (&DWP(4,$key),$s1); + &mov (&DWP(8,$key),$s2); + &mov (&DWP(12,$key),$s3); + + &mov ($key,$_key); # load key + &call ("_x86_AES_decrypt"); + + &mov ($key,$_ivp); # load ivp + &mov ($acc,$_out); # load out + &xor ($s0,&DWP(0,$key)); # xor iv + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + + &mov (&DWP(0,$acc),$s0); # write output + &mov (&DWP(4,$acc),$s1); + &mov (&DWP(8,$acc),$s2); + &mov (&DWP(12,$acc),$s3); + + &lea ($acc,&DWP(16,$acc)); # advance out + &mov ($_out,$acc); # save out + + &lea ($acc,$ivec); + &mov ($s0,&DWP(0,$acc)); # read temp + &mov ($s1,&DWP(4,$acc)); + &mov ($s2,&DWP(8,$acc)); + &mov ($s3,&DWP(12,$acc)); + + &mov (&DWP(0,$key),$s0); # copy iv + &mov (&DWP(4,$key),$s1); + &mov (&DWP(8,$key),$s2); + &mov (&DWP(12,$key),$s3); + + &mov ($acc,$_inp); # load inp + &mov ($s2,$_len); # load len + &lea ($acc,&DWP(16,$acc)); # advance inp + &mov ($_inp,$acc); # save inp + &sub ($s2,16); # decrease len + &mov ($_len,$s2); # save len + &jnz (&label("fast_dec_in_place_loop")); + + &set_label("fast_dec_out",4); + &cmp ($mark,0); # was the key schedule copied? + &mov ("edi",$_key); + &je (&label("skip_dzero")); + # zero copy of key schedule + &mov ("ecx",240/4); + &xor ("eax","eax"); + &align (4); + &data_word(0xABF3F689); # rep stosd + &set_label("skip_dzero") + &mov ("esp",$_esp); + &popf (); + &function_end_A(); + &pushf (); # kludge, never executed + +#--------------------------- SLOW ROUTINE ---------------------------# +&set_label("slow_way",16); + + &mov ($s0,&DWP(0,$s0)) if (!$x86only);# load OPENSSL_ia32cap + &mov ($key,&wparam(3)); # load key + + # pre-allocate aligned stack frame... + &lea ($acc,&DWP(-80,"esp")); + &and ($acc,-64); + + # ... and make sure it doesn't alias with $key modulo 1024 + &lea ($s1,&DWP(-80-63,$key)); + &sub ($s1,$acc); + &neg ($s1); + &and ($s1,0x3C0); # modulo 1024, but aligned to cache-line + &sub ($acc,$s1); + + # pick S-box copy which can't overlap with stack frame or $key + &lea ($s1,&DWP(768,$acc)); + &sub ($s1,$tbl); + &and ($s1,0x300); + &lea ($tbl,&DWP(2048+128,$tbl,$s1)); + + &lea ($s3,&wparam(0)); # pointer to parameter block + + &exch ("esp",$acc); + &add ("esp",4); # reserve for return address! + &mov ($_tbl,$tbl); # save %ebp + &mov ($_esp,$acc); # save %esp + &mov ($_tmp,$s0); # save OPENSSL_ia32cap + + &mov ($s0,&DWP(0,$s3)); # load inp + &mov ($s1,&DWP(4,$s3)); # load out + #&mov ($s2,&DWP(8,$s3)); # load len + #&mov ($key,&DWP(12,$s3)); # load key + &mov ($acc,&DWP(16,$s3)); # load ivp + &mov ($s3,&DWP(20,$s3)); # load enc flag + + &mov ($_inp,$s0); # save copy of inp + &mov ($_out,$s1); # save copy of out + &mov ($_len,$s2); # save copy of len + &mov ($_key,$key); # save copy of key + &mov ($_ivp,$acc); # save copy of ivp + + &mov ($key,$acc); + &mov ($acc,$s0); + + &cmp ($s3,0); + &je (&label("slow_decrypt")); + +#--------------------------- SLOW ENCRYPT ---------------------------# + &cmp ($s2,16); + &mov ($s3,$s1); + &jb (&label("slow_enc_tail")); + + if (!$x86only) { + &bt ($_tmp,25); # check for SSE bit + &jnc (&label("slow_enc_x86")); + + &movq ("mm0",&QWP(0,$key)); # load iv + &movq ("mm4",&QWP(8,$key)); + + &set_label("slow_enc_loop_sse",16); + &pxor ("mm0",&QWP(0,$acc)); # xor input data + &pxor ("mm4",&QWP(8,$acc)); + + &mov ($key,$_key); + &call ("_sse_AES_encrypt_compact"); + + &mov ($acc,$_inp); # load inp + &mov ($key,$_out); # load out + &mov ($s2,$_len); # load len + + &movq (&QWP(0,$key),"mm0"); # save output data + &movq (&QWP(8,$key),"mm4"); + + &lea ($acc,&DWP(16,$acc)); # advance inp + &mov ($_inp,$acc); # save inp + &lea ($s3,&DWP(16,$key)); # advance out + &mov ($_out,$s3); # save out + &sub ($s2,16); # decrease len + &cmp ($s2,16); + &mov ($_len,$s2); # save len + &jae (&label("slow_enc_loop_sse")); + &test ($s2,15); + &jnz (&label("slow_enc_tail")); + &mov ($acc,$_ivp); # load ivp + &movq (&QWP(0,$acc),"mm0"); # save ivec + &movq (&QWP(8,$acc),"mm4"); + &emms (); + &mov ("esp",$_esp); + &popf (); + &function_end_A(); + &pushf (); # kludge, never executed + } + &set_label("slow_enc_x86",16); + &mov ($s0,&DWP(0,$key)); # load iv + &mov ($s1,&DWP(4,$key)); + + &set_label("slow_enc_loop_x86",4); + &mov ($s2,&DWP(8,$key)); + &mov ($s3,&DWP(12,$key)); + + &xor ($s0,&DWP(0,$acc)); # xor input data + &xor ($s1,&DWP(4,$acc)); + &xor ($s2,&DWP(8,$acc)); + &xor ($s3,&DWP(12,$acc)); + + &mov ($key,$_key); # load key + &call ("_x86_AES_encrypt_compact"); + + &mov ($acc,$_inp); # load inp + &mov ($key,$_out); # load out + + &mov (&DWP(0,$key),$s0); # save output data + &mov (&DWP(4,$key),$s1); + &mov (&DWP(8,$key),$s2); + &mov (&DWP(12,$key),$s3); + + &mov ($s2,$_len); # load len + &lea ($acc,&DWP(16,$acc)); # advance inp + &mov ($_inp,$acc); # save inp + &lea ($s3,&DWP(16,$key)); # advance out + &mov ($_out,$s3); # save out + &sub ($s2,16); # decrease len + &cmp ($s2,16); + &mov ($_len,$s2); # save len + &jae (&label("slow_enc_loop_x86")); + &test ($s2,15); + &jnz (&label("slow_enc_tail")); + &mov ($acc,$_ivp); # load ivp + &mov ($s2,&DWP(8,$key)); # restore last dwords + &mov ($s3,&DWP(12,$key)); + &mov (&DWP(0,$acc),$s0); # save ivec + &mov (&DWP(4,$acc),$s1); + &mov (&DWP(8,$acc),$s2); + &mov (&DWP(12,$acc),$s3); + + &mov ("esp",$_esp); + &popf (); + &function_end_A(); + &pushf (); # kludge, never executed + + &set_label("slow_enc_tail",16); + &emms () if (!$x86only); + &mov ($key eq "edi"? $key:"",$s3); # load out to edi + &mov ($s1,16); + &sub ($s1,$s2); + &cmp ($key,$acc eq "esi"? $acc:""); # compare with inp + &je (&label("enc_in_place")); + &align (4); + &data_word(0xA4F3F689); # rep movsb # copy input + &jmp (&label("enc_skip_in_place")); + &set_label("enc_in_place"); + &lea ($key,&DWP(0,$key,$s2)); + &set_label("enc_skip_in_place"); + &mov ($s2,$s1); + &xor ($s0,$s0); + &align (4); + &data_word(0xAAF3F689); # rep stosb # zero tail + + &mov ($key,$_ivp); # restore ivp + &mov ($acc,$s3); # output as input + &mov ($s0,&DWP(0,$key)); + &mov ($s1,&DWP(4,$key)); + &mov ($_len,16); # len=16 + &jmp (&label("slow_enc_loop_x86")); # one more spin... + +#--------------------------- SLOW DECRYPT ---------------------------# +&set_label("slow_decrypt",16); + if (!$x86only) { + &bt ($_tmp,25); # check for SSE bit + &jnc (&label("slow_dec_loop_x86")); + + &set_label("slow_dec_loop_sse",4); + &movq ("mm0",&QWP(0,$acc)); # read input + &movq ("mm4",&QWP(8,$acc)); + + &mov ($key,$_key); + &call ("_sse_AES_decrypt_compact"); + + &mov ($acc,$_inp); # load inp + &lea ($s0,$ivec); + &mov ($s1,$_out); # load out + &mov ($s2,$_len); # load len + &mov ($key,$_ivp); # load ivp + + &movq ("mm1",&QWP(0,$acc)); # re-read input + &movq ("mm5",&QWP(8,$acc)); + + &pxor ("mm0",&QWP(0,$key)); # xor iv + &pxor ("mm4",&QWP(8,$key)); + + &movq (&QWP(0,$key),"mm1"); # copy input to iv + &movq (&QWP(8,$key),"mm5"); + + &sub ($s2,16); # decrease len + &jc (&label("slow_dec_partial_sse")); + + &movq (&QWP(0,$s1),"mm0"); # write output + &movq (&QWP(8,$s1),"mm4"); + + &lea ($s1,&DWP(16,$s1)); # advance out + &mov ($_out,$s1); # save out + &lea ($acc,&DWP(16,$acc)); # advance inp + &mov ($_inp,$acc); # save inp + &mov ($_len,$s2); # save len + &jnz (&label("slow_dec_loop_sse")); + &emms (); + &mov ("esp",$_esp); + &popf (); + &function_end_A(); + &pushf (); # kludge, never executed + + &set_label("slow_dec_partial_sse",16); + &movq (&QWP(0,$s0),"mm0"); # save output to temp + &movq (&QWP(8,$s0),"mm4"); + &emms (); + + &add ($s2 eq "ecx" ? "ecx":"",16); + &mov ("edi",$s1); # out + &mov ("esi",$s0); # temp + &align (4); + &data_word(0xA4F3F689); # rep movsb # copy partial output + + &mov ("esp",$_esp); + &popf (); + &function_end_A(); + &pushf (); # kludge, never executed + } + &set_label("slow_dec_loop_x86",16); + &mov ($s0,&DWP(0,$acc)); # read input + &mov ($s1,&DWP(4,$acc)); + &mov ($s2,&DWP(8,$acc)); + &mov ($s3,&DWP(12,$acc)); + + &lea ($key,$ivec); + &mov (&DWP(0,$key),$s0); # copy to temp + &mov (&DWP(4,$key),$s1); + &mov (&DWP(8,$key),$s2); + &mov (&DWP(12,$key),$s3); + + &mov ($key,$_key); # load key + &call ("_x86_AES_decrypt_compact"); + + &mov ($key,$_ivp); # load ivp + &mov ($acc,$_len); # load len + &xor ($s0,&DWP(0,$key)); # xor iv + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + + &sub ($acc,16); + &jc (&label("slow_dec_partial_x86")); + + &mov ($_len,$acc); # save len + &mov ($acc,$_out); # load out + + &mov (&DWP(0,$acc),$s0); # write output + &mov (&DWP(4,$acc),$s1); + &mov (&DWP(8,$acc),$s2); + &mov (&DWP(12,$acc),$s3); + + &lea ($acc,&DWP(16,$acc)); # advance out + &mov ($_out,$acc); # save out + + &lea ($acc,$ivec); + &mov ($s0,&DWP(0,$acc)); # read temp + &mov ($s1,&DWP(4,$acc)); + &mov ($s2,&DWP(8,$acc)); + &mov ($s3,&DWP(12,$acc)); + + &mov (&DWP(0,$key),$s0); # copy it to iv + &mov (&DWP(4,$key),$s1); + &mov (&DWP(8,$key),$s2); + &mov (&DWP(12,$key),$s3); + + &mov ($acc,$_inp); # load inp + &lea ($acc,&DWP(16,$acc)); # advance inp + &mov ($_inp,$acc); # save inp + &jnz (&label("slow_dec_loop_x86")); + &mov ("esp",$_esp); + &popf (); + &function_end_A(); + &pushf (); # kludge, never executed + + &set_label("slow_dec_partial_x86",16); + &lea ($acc,$ivec); + &mov (&DWP(0,$acc),$s0); # save output to temp + &mov (&DWP(4,$acc),$s1); + &mov (&DWP(8,$acc),$s2); + &mov (&DWP(12,$acc),$s3); + + &mov ($acc,$_inp); + &mov ($s0,&DWP(0,$acc)); # re-read input + &mov ($s1,&DWP(4,$acc)); + &mov ($s2,&DWP(8,$acc)); + &mov ($s3,&DWP(12,$acc)); + + &mov (&DWP(0,$key),$s0); # copy it to iv + &mov (&DWP(4,$key),$s1); + &mov (&DWP(8,$key),$s2); + &mov (&DWP(12,$key),$s3); + + &mov ("ecx",$_len); + &mov ("edi",$_out); + &lea ("esi",$ivec); + &align (4); + &data_word(0xA4F3F689); # rep movsb # copy partial output + + &mov ("esp",$_esp); + &popf (); +&function_end("AES_cbc_encrypt"); +} + +#------------------------------------------------------------------# + +sub enckey() +{ + &movz ("esi",&LB("edx")); # rk[i]>>0 + &movz ("ebx",&BP(-128,$tbl,"esi",1)); + &movz ("esi",&HB("edx")); # rk[i]>>8 + &shl ("ebx",24); + &xor ("eax","ebx"); + + &movz ("ebx",&BP(-128,$tbl,"esi",1)); + &shr ("edx",16); + &movz ("esi",&LB("edx")); # rk[i]>>16 + &xor ("eax","ebx"); + + &movz ("ebx",&BP(-128,$tbl,"esi",1)); + &movz ("esi",&HB("edx")); # rk[i]>>24 + &shl ("ebx",8); + &xor ("eax","ebx"); + + &movz ("ebx",&BP(-128,$tbl,"esi",1)); + &shl ("ebx",16); + &xor ("eax","ebx"); + + &xor ("eax",&DWP(1024-128,$tbl,"ecx",4)); # rcon +} + +&function_begin("_x86_AES_set_encrypt_key"); + &mov ("esi",&wparam(1)); # user supplied key + &mov ("edi",&wparam(3)); # private key schedule + + &test ("esi",-1); + &jz (&label("badpointer")); + &test ("edi",-1); + &jz (&label("badpointer")); + + &call (&label("pic_point")); + &set_label("pic_point"); + &blindpop($tbl); + &lea ($tbl,&DWP(&label("AES_Te")."-".&label("pic_point"),$tbl)); + &lea ($tbl,&DWP(2048+128,$tbl)); + + # prefetch Te4 + &mov ("eax",&DWP(0-128,$tbl)); + &mov ("ebx",&DWP(32-128,$tbl)); + &mov ("ecx",&DWP(64-128,$tbl)); + &mov ("edx",&DWP(96-128,$tbl)); + &mov ("eax",&DWP(128-128,$tbl)); + &mov ("ebx",&DWP(160-128,$tbl)); + &mov ("ecx",&DWP(192-128,$tbl)); + &mov ("edx",&DWP(224-128,$tbl)); + + &mov ("ecx",&wparam(2)); # number of bits in key + &cmp ("ecx",128); + &je (&label("10rounds")); + &cmp ("ecx",192); + &je (&label("12rounds")); + &cmp ("ecx",256); + &je (&label("14rounds")); + &mov ("eax",-2); # invalid number of bits + &jmp (&label("exit")); + + &set_label("10rounds"); + &mov ("eax",&DWP(0,"esi")); # copy first 4 dwords + &mov ("ebx",&DWP(4,"esi")); + &mov ("ecx",&DWP(8,"esi")); + &mov ("edx",&DWP(12,"esi")); + &mov (&DWP(0,"edi"),"eax"); + &mov (&DWP(4,"edi"),"ebx"); + &mov (&DWP(8,"edi"),"ecx"); + &mov (&DWP(12,"edi"),"edx"); + + &xor ("ecx","ecx"); + &jmp (&label("10shortcut")); + + &align (4); + &set_label("10loop"); + &mov ("eax",&DWP(0,"edi")); # rk[0] + &mov ("edx",&DWP(12,"edi")); # rk[3] + &set_label("10shortcut"); + &enckey (); + + &mov (&DWP(16,"edi"),"eax"); # rk[4] + &xor ("eax",&DWP(4,"edi")); + &mov (&DWP(20,"edi"),"eax"); # rk[5] + &xor ("eax",&DWP(8,"edi")); + &mov (&DWP(24,"edi"),"eax"); # rk[6] + &xor ("eax",&DWP(12,"edi")); + &mov (&DWP(28,"edi"),"eax"); # rk[7] + &inc ("ecx"); + &add ("edi",16); + &cmp ("ecx",10); + &jl (&label("10loop")); + + &mov (&DWP(80,"edi"),10); # setup number of rounds + &xor ("eax","eax"); + &jmp (&label("exit")); + + &set_label("12rounds"); + &mov ("eax",&DWP(0,"esi")); # copy first 6 dwords + &mov ("ebx",&DWP(4,"esi")); + &mov ("ecx",&DWP(8,"esi")); + &mov ("edx",&DWP(12,"esi")); + &mov (&DWP(0,"edi"),"eax"); + &mov (&DWP(4,"edi"),"ebx"); + &mov (&DWP(8,"edi"),"ecx"); + &mov (&DWP(12,"edi"),"edx"); + &mov ("ecx",&DWP(16,"esi")); + &mov ("edx",&DWP(20,"esi")); + &mov (&DWP(16,"edi"),"ecx"); + &mov (&DWP(20,"edi"),"edx"); + + &xor ("ecx","ecx"); + &jmp (&label("12shortcut")); + + &align (4); + &set_label("12loop"); + &mov ("eax",&DWP(0,"edi")); # rk[0] + &mov ("edx",&DWP(20,"edi")); # rk[5] + &set_label("12shortcut"); + &enckey (); + + &mov (&DWP(24,"edi"),"eax"); # rk[6] + &xor ("eax",&DWP(4,"edi")); + &mov (&DWP(28,"edi"),"eax"); # rk[7] + &xor ("eax",&DWP(8,"edi")); + &mov (&DWP(32,"edi"),"eax"); # rk[8] + &xor ("eax",&DWP(12,"edi")); + &mov (&DWP(36,"edi"),"eax"); # rk[9] + + &cmp ("ecx",7); + &je (&label("12break")); + &inc ("ecx"); + + &xor ("eax",&DWP(16,"edi")); + &mov (&DWP(40,"edi"),"eax"); # rk[10] + &xor ("eax",&DWP(20,"edi")); + &mov (&DWP(44,"edi"),"eax"); # rk[11] + + &add ("edi",24); + &jmp (&label("12loop")); + + &set_label("12break"); + &mov (&DWP(72,"edi"),12); # setup number of rounds + &xor ("eax","eax"); + &jmp (&label("exit")); + + &set_label("14rounds"); + &mov ("eax",&DWP(0,"esi")); # copy first 8 dwords + &mov ("ebx",&DWP(4,"esi")); + &mov ("ecx",&DWP(8,"esi")); + &mov ("edx",&DWP(12,"esi")); + &mov (&DWP(0,"edi"),"eax"); + &mov (&DWP(4,"edi"),"ebx"); + &mov (&DWP(8,"edi"),"ecx"); + &mov (&DWP(12,"edi"),"edx"); + &mov ("eax",&DWP(16,"esi")); + &mov ("ebx",&DWP(20,"esi")); + &mov ("ecx",&DWP(24,"esi")); + &mov ("edx",&DWP(28,"esi")); + &mov (&DWP(16,"edi"),"eax"); + &mov (&DWP(20,"edi"),"ebx"); + &mov (&DWP(24,"edi"),"ecx"); + &mov (&DWP(28,"edi"),"edx"); + + &xor ("ecx","ecx"); + &jmp (&label("14shortcut")); + + &align (4); + &set_label("14loop"); + &mov ("edx",&DWP(28,"edi")); # rk[7] + &set_label("14shortcut"); + &mov ("eax",&DWP(0,"edi")); # rk[0] + + &enckey (); + + &mov (&DWP(32,"edi"),"eax"); # rk[8] + &xor ("eax",&DWP(4,"edi")); + &mov (&DWP(36,"edi"),"eax"); # rk[9] + &xor ("eax",&DWP(8,"edi")); + &mov (&DWP(40,"edi"),"eax"); # rk[10] + &xor ("eax",&DWP(12,"edi")); + &mov (&DWP(44,"edi"),"eax"); # rk[11] + + &cmp ("ecx",6); + &je (&label("14break")); + &inc ("ecx"); + + &mov ("edx","eax"); + &mov ("eax",&DWP(16,"edi")); # rk[4] + &movz ("esi",&LB("edx")); # rk[11]>>0 + &movz ("ebx",&BP(-128,$tbl,"esi",1)); + &movz ("esi",&HB("edx")); # rk[11]>>8 + &xor ("eax","ebx"); + + &movz ("ebx",&BP(-128,$tbl,"esi",1)); + &shr ("edx",16); + &shl ("ebx",8); + &movz ("esi",&LB("edx")); # rk[11]>>16 + &xor ("eax","ebx"); + + &movz ("ebx",&BP(-128,$tbl,"esi",1)); + &movz ("esi",&HB("edx")); # rk[11]>>24 + &shl ("ebx",16); + &xor ("eax","ebx"); + + &movz ("ebx",&BP(-128,$tbl,"esi",1)); + &shl ("ebx",24); + &xor ("eax","ebx"); + + &mov (&DWP(48,"edi"),"eax"); # rk[12] + &xor ("eax",&DWP(20,"edi")); + &mov (&DWP(52,"edi"),"eax"); # rk[13] + &xor ("eax",&DWP(24,"edi")); + &mov (&DWP(56,"edi"),"eax"); # rk[14] + &xor ("eax",&DWP(28,"edi")); + &mov (&DWP(60,"edi"),"eax"); # rk[15] + + &add ("edi",32); + &jmp (&label("14loop")); + + &set_label("14break"); + &mov (&DWP(48,"edi"),14); # setup number of rounds + &xor ("eax","eax"); + &jmp (&label("exit")); + + &set_label("badpointer"); + &mov ("eax",-1); + &set_label("exit"); +&function_end("_x86_AES_set_encrypt_key"); + +# int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, +# AES_KEY *key) +&function_begin_B("private_AES_set_encrypt_key"); + &call ("_x86_AES_set_encrypt_key"); + &ret (); +&function_end_B("private_AES_set_encrypt_key"); + +sub deckey() +{ my ($i,$key,$tp1,$tp2,$tp4,$tp8) = @_; + my $tmp = $tbl; + + &mov ($acc,$tp1); + &and ($acc,0x80808080); + &mov ($tmp,$acc); + &shr ($tmp,7); + &lea ($tp2,&DWP(0,$tp1,$tp1)); + &sub ($acc,$tmp); + &and ($tp2,0xfefefefe); + &and ($acc,0x1b1b1b1b); + &xor ($acc,$tp2); + &mov ($tp2,$acc); + + &and ($acc,0x80808080); + &mov ($tmp,$acc); + &shr ($tmp,7); + &lea ($tp4,&DWP(0,$tp2,$tp2)); + &sub ($acc,$tmp); + &and ($tp4,0xfefefefe); + &and ($acc,0x1b1b1b1b); + &xor ($tp2,$tp1); # tp2^tp1 + &xor ($acc,$tp4); + &mov ($tp4,$acc); + + &and ($acc,0x80808080); + &mov ($tmp,$acc); + &shr ($tmp,7); + &lea ($tp8,&DWP(0,$tp4,$tp4)); + &xor ($tp4,$tp1); # tp4^tp1 + &sub ($acc,$tmp); + &and ($tp8,0xfefefefe); + &and ($acc,0x1b1b1b1b); + &rotl ($tp1,8); # = ROTATE(tp1,8) + &xor ($tp8,$acc); + + &mov ($tmp,&DWP(4*($i+1),$key)); # modulo-scheduled load + + &xor ($tp1,$tp2); + &xor ($tp2,$tp8); + &xor ($tp1,$tp4); + &rotl ($tp2,24); + &xor ($tp4,$tp8); + &xor ($tp1,$tp8); # ^= tp8^(tp4^tp1)^(tp2^tp1) + &rotl ($tp4,16); + &xor ($tp1,$tp2); # ^= ROTATE(tp8^tp2^tp1,24) + &rotl ($tp8,8); + &xor ($tp1,$tp4); # ^= ROTATE(tp8^tp4^tp1,16) + &mov ($tp2,$tmp); + &xor ($tp1,$tp8); # ^= ROTATE(tp8,8) + + &mov (&DWP(4*$i,$key),$tp1); +} + +# int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, +# AES_KEY *key) +&function_begin_B("private_AES_set_decrypt_key"); + &call ("_x86_AES_set_encrypt_key"); + &cmp ("eax",0); + &je (&label("proceed")); + &ret (); + + &set_label("proceed"); + &push ("ebp"); + &push ("ebx"); + &push ("esi"); + &push ("edi"); + + &mov ("esi",&wparam(2)); + &mov ("ecx",&DWP(240,"esi")); # pull number of rounds + &lea ("ecx",&DWP(0,"","ecx",4)); + &lea ("edi",&DWP(0,"esi","ecx",4)); # pointer to last chunk + + &set_label("invert",4); # invert order of chunks + &mov ("eax",&DWP(0,"esi")); + &mov ("ebx",&DWP(4,"esi")); + &mov ("ecx",&DWP(0,"edi")); + &mov ("edx",&DWP(4,"edi")); + &mov (&DWP(0,"edi"),"eax"); + &mov (&DWP(4,"edi"),"ebx"); + &mov (&DWP(0,"esi"),"ecx"); + &mov (&DWP(4,"esi"),"edx"); + &mov ("eax",&DWP(8,"esi")); + &mov ("ebx",&DWP(12,"esi")); + &mov ("ecx",&DWP(8,"edi")); + &mov ("edx",&DWP(12,"edi")); + &mov (&DWP(8,"edi"),"eax"); + &mov (&DWP(12,"edi"),"ebx"); + &mov (&DWP(8,"esi"),"ecx"); + &mov (&DWP(12,"esi"),"edx"); + &add ("esi",16); + &sub ("edi",16); + &cmp ("esi","edi"); + &jne (&label("invert")); + + &mov ($key,&wparam(2)); + &mov ($acc,&DWP(240,$key)); # pull number of rounds + &lea ($acc,&DWP(-2,$acc,$acc)); + &lea ($acc,&DWP(0,$key,$acc,8)); + &mov (&wparam(2),$acc); + + &mov ($s0,&DWP(16,$key)); # modulo-scheduled load + &set_label("permute",4); # permute the key schedule + &add ($key,16); + &deckey (0,$key,$s0,$s1,$s2,$s3); + &deckey (1,$key,$s1,$s2,$s3,$s0); + &deckey (2,$key,$s2,$s3,$s0,$s1); + &deckey (3,$key,$s3,$s0,$s1,$s2); + &cmp ($key,&wparam(2)); + &jb (&label("permute")); + + &xor ("eax","eax"); # return success +&function_end("private_AES_set_decrypt_key"); +&asciz("AES for x86, CRYPTOGAMS by "); + +&asm_finish(); diff --git a/libs/openssl/crypto/aes/asm/aes-armv4.pl b/libs/openssl/crypto/aes/asm/aes-armv4.pl new file mode 100644 index 00000000..86b86c4a --- /dev/null +++ b/libs/openssl/crypto/aes/asm/aes-armv4.pl @@ -0,0 +1,1134 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# AES for ARMv4 + +# January 2007. +# +# Code uses single 1K S-box and is >2 times faster than code generated +# by gcc-3.4.1. This is thanks to unique feature of ARMv4 ISA, which +# allows to merge logical or arithmetic operation with shift or rotate +# in one instruction and emit combined result every cycle. The module +# is endian-neutral. The performance is ~42 cycles/byte for 128-bit +# key [on single-issue Xscale PXA250 core]. + +# May 2007. +# +# AES_set_[en|de]crypt_key is added. + +# July 2010. +# +# Rescheduling for dual-issue pipeline resulted in 12% improvement on +# Cortex A8 core and ~25 cycles per byte processed with 128-bit key. + +# February 2011. +# +# Profiler-assisted and platform-specific optimization resulted in 16% +# improvement on Cortex A8 core and ~21.5 cycles per byte. + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +$s0="r0"; +$s1="r1"; +$s2="r2"; +$s3="r3"; +$t1="r4"; +$t2="r5"; +$t3="r6"; +$i1="r7"; +$i2="r8"; +$i3="r9"; + +$tbl="r10"; +$key="r11"; +$rounds="r12"; + +$code=<<___; +#include "arm_arch.h" +.text +.code 32 + +.type AES_Te,%object +.align 5 +AES_Te: +.word 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d +.word 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554 +.word 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d +.word 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a +.word 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87 +.word 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b +.word 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea +.word 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b +.word 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a +.word 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f +.word 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108 +.word 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f +.word 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e +.word 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5 +.word 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d +.word 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f +.word 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e +.word 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb +.word 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce +.word 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497 +.word 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c +.word 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed +.word 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b +.word 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a +.word 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16 +.word 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594 +.word 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81 +.word 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3 +.word 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a +.word 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504 +.word 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163 +.word 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d +.word 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f +.word 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739 +.word 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47 +.word 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395 +.word 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f +.word 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883 +.word 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c +.word 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76 +.word 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e +.word 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4 +.word 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6 +.word 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b +.word 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7 +.word 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0 +.word 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25 +.word 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818 +.word 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72 +.word 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651 +.word 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21 +.word 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85 +.word 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa +.word 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12 +.word 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0 +.word 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9 +.word 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133 +.word 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7 +.word 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920 +.word 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a +.word 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17 +.word 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8 +.word 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11 +.word 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a +@ Te4[256] +.byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5 +.byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 +.byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0 +.byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 +.byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc +.byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 +.byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a +.byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 +.byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0 +.byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 +.byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b +.byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf +.byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85 +.byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 +.byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5 +.byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 +.byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17 +.byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 +.byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88 +.byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb +.byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c +.byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 +.byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9 +.byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 +.byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6 +.byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a +.byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e +.byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e +.byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94 +.byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf +.byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68 +.byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +@ rcon[] +.word 0x01000000, 0x02000000, 0x04000000, 0x08000000 +.word 0x10000000, 0x20000000, 0x40000000, 0x80000000 +.word 0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0 +.size AES_Te,.-AES_Te + +@ void AES_encrypt(const unsigned char *in, unsigned char *out, +@ const AES_KEY *key) { +.global AES_encrypt +.type AES_encrypt,%function +.align 5 +AES_encrypt: + sub r3,pc,#8 @ AES_encrypt + stmdb sp!,{r1,r4-r12,lr} + mov $rounds,r0 @ inp + mov $key,r2 + sub $tbl,r3,#AES_encrypt-AES_Te @ Te +#if __ARM_ARCH__<7 + ldrb $s0,[$rounds,#3] @ load input data in endian-neutral + ldrb $t1,[$rounds,#2] @ manner... + ldrb $t2,[$rounds,#1] + ldrb $t3,[$rounds,#0] + orr $s0,$s0,$t1,lsl#8 + ldrb $s1,[$rounds,#7] + orr $s0,$s0,$t2,lsl#16 + ldrb $t1,[$rounds,#6] + orr $s0,$s0,$t3,lsl#24 + ldrb $t2,[$rounds,#5] + ldrb $t3,[$rounds,#4] + orr $s1,$s1,$t1,lsl#8 + ldrb $s2,[$rounds,#11] + orr $s1,$s1,$t2,lsl#16 + ldrb $t1,[$rounds,#10] + orr $s1,$s1,$t3,lsl#24 + ldrb $t2,[$rounds,#9] + ldrb $t3,[$rounds,#8] + orr $s2,$s2,$t1,lsl#8 + ldrb $s3,[$rounds,#15] + orr $s2,$s2,$t2,lsl#16 + ldrb $t1,[$rounds,#14] + orr $s2,$s2,$t3,lsl#24 + ldrb $t2,[$rounds,#13] + ldrb $t3,[$rounds,#12] + orr $s3,$s3,$t1,lsl#8 + orr $s3,$s3,$t2,lsl#16 + orr $s3,$s3,$t3,lsl#24 +#else + ldr $s0,[$rounds,#0] + ldr $s1,[$rounds,#4] + ldr $s2,[$rounds,#8] + ldr $s3,[$rounds,#12] +#ifdef __ARMEL__ + rev $s0,$s0 + rev $s1,$s1 + rev $s2,$s2 + rev $s3,$s3 +#endif +#endif + bl _armv4_AES_encrypt + + ldr $rounds,[sp],#4 @ pop out +#if __ARM_ARCH__>=7 +#ifdef __ARMEL__ + rev $s0,$s0 + rev $s1,$s1 + rev $s2,$s2 + rev $s3,$s3 +#endif + str $s0,[$rounds,#0] + str $s1,[$rounds,#4] + str $s2,[$rounds,#8] + str $s3,[$rounds,#12] +#else + mov $t1,$s0,lsr#24 @ write output in endian-neutral + mov $t2,$s0,lsr#16 @ manner... + mov $t3,$s0,lsr#8 + strb $t1,[$rounds,#0] + strb $t2,[$rounds,#1] + mov $t1,$s1,lsr#24 + strb $t3,[$rounds,#2] + mov $t2,$s1,lsr#16 + strb $s0,[$rounds,#3] + mov $t3,$s1,lsr#8 + strb $t1,[$rounds,#4] + strb $t2,[$rounds,#5] + mov $t1,$s2,lsr#24 + strb $t3,[$rounds,#6] + mov $t2,$s2,lsr#16 + strb $s1,[$rounds,#7] + mov $t3,$s2,lsr#8 + strb $t1,[$rounds,#8] + strb $t2,[$rounds,#9] + mov $t1,$s3,lsr#24 + strb $t3,[$rounds,#10] + mov $t2,$s3,lsr#16 + strb $s2,[$rounds,#11] + mov $t3,$s3,lsr#8 + strb $t1,[$rounds,#12] + strb $t2,[$rounds,#13] + strb $t3,[$rounds,#14] + strb $s3,[$rounds,#15] +#endif +#if __ARM_ARCH__>=5 + ldmia sp!,{r4-r12,pc} +#else + ldmia sp!,{r4-r12,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif +.size AES_encrypt,.-AES_encrypt + +.type _armv4_AES_encrypt,%function +.align 2 +_armv4_AES_encrypt: + str lr,[sp,#-4]! @ push lr + ldmia $key!,{$t1-$i1} + eor $s0,$s0,$t1 + ldr $rounds,[$key,#240-16] + eor $s1,$s1,$t2 + eor $s2,$s2,$t3 + eor $s3,$s3,$i1 + sub $rounds,$rounds,#1 + mov lr,#255 + + and $i1,lr,$s0 + and $i2,lr,$s0,lsr#8 + and $i3,lr,$s0,lsr#16 + mov $s0,$s0,lsr#24 +.Lenc_loop: + ldr $t1,[$tbl,$i1,lsl#2] @ Te3[s0>>0] + and $i1,lr,$s1,lsr#16 @ i0 + ldr $t2,[$tbl,$i2,lsl#2] @ Te2[s0>>8] + and $i2,lr,$s1 + ldr $t3,[$tbl,$i3,lsl#2] @ Te1[s0>>16] + and $i3,lr,$s1,lsr#8 + ldr $s0,[$tbl,$s0,lsl#2] @ Te0[s0>>24] + mov $s1,$s1,lsr#24 + + ldr $i1,[$tbl,$i1,lsl#2] @ Te1[s1>>16] + ldr $i2,[$tbl,$i2,lsl#2] @ Te3[s1>>0] + ldr $i3,[$tbl,$i3,lsl#2] @ Te2[s1>>8] + eor $s0,$s0,$i1,ror#8 + ldr $s1,[$tbl,$s1,lsl#2] @ Te0[s1>>24] + and $i1,lr,$s2,lsr#8 @ i0 + eor $t2,$t2,$i2,ror#8 + and $i2,lr,$s2,lsr#16 @ i1 + eor $t3,$t3,$i3,ror#8 + and $i3,lr,$s2 + ldr $i1,[$tbl,$i1,lsl#2] @ Te2[s2>>8] + eor $s1,$s1,$t1,ror#24 + ldr $i2,[$tbl,$i2,lsl#2] @ Te1[s2>>16] + mov $s2,$s2,lsr#24 + + ldr $i3,[$tbl,$i3,lsl#2] @ Te3[s2>>0] + eor $s0,$s0,$i1,ror#16 + ldr $s2,[$tbl,$s2,lsl#2] @ Te0[s2>>24] + and $i1,lr,$s3 @ i0 + eor $s1,$s1,$i2,ror#8 + and $i2,lr,$s3,lsr#8 @ i1 + eor $t3,$t3,$i3,ror#16 + and $i3,lr,$s3,lsr#16 @ i2 + ldr $i1,[$tbl,$i1,lsl#2] @ Te3[s3>>0] + eor $s2,$s2,$t2,ror#16 + ldr $i2,[$tbl,$i2,lsl#2] @ Te2[s3>>8] + mov $s3,$s3,lsr#24 + + ldr $i3,[$tbl,$i3,lsl#2] @ Te1[s3>>16] + eor $s0,$s0,$i1,ror#24 + ldr $i1,[$key],#16 + eor $s1,$s1,$i2,ror#16 + ldr $s3,[$tbl,$s3,lsl#2] @ Te0[s3>>24] + eor $s2,$s2,$i3,ror#8 + ldr $t1,[$key,#-12] + eor $s3,$s3,$t3,ror#8 + + ldr $t2,[$key,#-8] + eor $s0,$s0,$i1 + ldr $t3,[$key,#-4] + and $i1,lr,$s0 + eor $s1,$s1,$t1 + and $i2,lr,$s0,lsr#8 + eor $s2,$s2,$t2 + and $i3,lr,$s0,lsr#16 + eor $s3,$s3,$t3 + mov $s0,$s0,lsr#24 + + subs $rounds,$rounds,#1 + bne .Lenc_loop + + add $tbl,$tbl,#2 + + ldrb $t1,[$tbl,$i1,lsl#2] @ Te4[s0>>0] + and $i1,lr,$s1,lsr#16 @ i0 + ldrb $t2,[$tbl,$i2,lsl#2] @ Te4[s0>>8] + and $i2,lr,$s1 + ldrb $t3,[$tbl,$i3,lsl#2] @ Te4[s0>>16] + and $i3,lr,$s1,lsr#8 + ldrb $s0,[$tbl,$s0,lsl#2] @ Te4[s0>>24] + mov $s1,$s1,lsr#24 + + ldrb $i1,[$tbl,$i1,lsl#2] @ Te4[s1>>16] + ldrb $i2,[$tbl,$i2,lsl#2] @ Te4[s1>>0] + ldrb $i3,[$tbl,$i3,lsl#2] @ Te4[s1>>8] + eor $s0,$i1,$s0,lsl#8 + ldrb $s1,[$tbl,$s1,lsl#2] @ Te4[s1>>24] + and $i1,lr,$s2,lsr#8 @ i0 + eor $t2,$i2,$t2,lsl#8 + and $i2,lr,$s2,lsr#16 @ i1 + eor $t3,$i3,$t3,lsl#8 + and $i3,lr,$s2 + ldrb $i1,[$tbl,$i1,lsl#2] @ Te4[s2>>8] + eor $s1,$t1,$s1,lsl#24 + ldrb $i2,[$tbl,$i2,lsl#2] @ Te4[s2>>16] + mov $s2,$s2,lsr#24 + + ldrb $i3,[$tbl,$i3,lsl#2] @ Te4[s2>>0] + eor $s0,$i1,$s0,lsl#8 + ldrb $s2,[$tbl,$s2,lsl#2] @ Te4[s2>>24] + and $i1,lr,$s3 @ i0 + eor $s1,$s1,$i2,lsl#16 + and $i2,lr,$s3,lsr#8 @ i1 + eor $t3,$i3,$t3,lsl#8 + and $i3,lr,$s3,lsr#16 @ i2 + ldrb $i1,[$tbl,$i1,lsl#2] @ Te4[s3>>0] + eor $s2,$t2,$s2,lsl#24 + ldrb $i2,[$tbl,$i2,lsl#2] @ Te4[s3>>8] + mov $s3,$s3,lsr#24 + + ldrb $i3,[$tbl,$i3,lsl#2] @ Te4[s3>>16] + eor $s0,$i1,$s0,lsl#8 + ldr $i1,[$key,#0] + ldrb $s3,[$tbl,$s3,lsl#2] @ Te4[s3>>24] + eor $s1,$s1,$i2,lsl#8 + ldr $t1,[$key,#4] + eor $s2,$s2,$i3,lsl#16 + ldr $t2,[$key,#8] + eor $s3,$t3,$s3,lsl#24 + ldr $t3,[$key,#12] + + eor $s0,$s0,$i1 + eor $s1,$s1,$t1 + eor $s2,$s2,$t2 + eor $s3,$s3,$t3 + + sub $tbl,$tbl,#2 + ldr pc,[sp],#4 @ pop and return +.size _armv4_AES_encrypt,.-_armv4_AES_encrypt + +.global private_AES_set_encrypt_key +.type private_AES_set_encrypt_key,%function +.align 5 +private_AES_set_encrypt_key: +_armv4_AES_set_encrypt_key: + sub r3,pc,#8 @ AES_set_encrypt_key + teq r0,#0 + moveq r0,#-1 + beq .Labrt + teq r2,#0 + moveq r0,#-1 + beq .Labrt + + teq r1,#128 + beq .Lok + teq r1,#192 + beq .Lok + teq r1,#256 + movne r0,#-1 + bne .Labrt + +.Lok: stmdb sp!,{r4-r12,lr} + sub $tbl,r3,#_armv4_AES_set_encrypt_key-AES_Te-1024 @ Te4 + + mov $rounds,r0 @ inp + mov lr,r1 @ bits + mov $key,r2 @ key + +#if __ARM_ARCH__<7 + ldrb $s0,[$rounds,#3] @ load input data in endian-neutral + ldrb $t1,[$rounds,#2] @ manner... + ldrb $t2,[$rounds,#1] + ldrb $t3,[$rounds,#0] + orr $s0,$s0,$t1,lsl#8 + ldrb $s1,[$rounds,#7] + orr $s0,$s0,$t2,lsl#16 + ldrb $t1,[$rounds,#6] + orr $s0,$s0,$t3,lsl#24 + ldrb $t2,[$rounds,#5] + ldrb $t3,[$rounds,#4] + orr $s1,$s1,$t1,lsl#8 + ldrb $s2,[$rounds,#11] + orr $s1,$s1,$t2,lsl#16 + ldrb $t1,[$rounds,#10] + orr $s1,$s1,$t3,lsl#24 + ldrb $t2,[$rounds,#9] + ldrb $t3,[$rounds,#8] + orr $s2,$s2,$t1,lsl#8 + ldrb $s3,[$rounds,#15] + orr $s2,$s2,$t2,lsl#16 + ldrb $t1,[$rounds,#14] + orr $s2,$s2,$t3,lsl#24 + ldrb $t2,[$rounds,#13] + ldrb $t3,[$rounds,#12] + orr $s3,$s3,$t1,lsl#8 + str $s0,[$key],#16 + orr $s3,$s3,$t2,lsl#16 + str $s1,[$key,#-12] + orr $s3,$s3,$t3,lsl#24 + str $s2,[$key,#-8] + str $s3,[$key,#-4] +#else + ldr $s0,[$rounds,#0] + ldr $s1,[$rounds,#4] + ldr $s2,[$rounds,#8] + ldr $s3,[$rounds,#12] +#ifdef __ARMEL__ + rev $s0,$s0 + rev $s1,$s1 + rev $s2,$s2 + rev $s3,$s3 +#endif + str $s0,[$key],#16 + str $s1,[$key,#-12] + str $s2,[$key,#-8] + str $s3,[$key,#-4] +#endif + + teq lr,#128 + bne .Lnot128 + mov $rounds,#10 + str $rounds,[$key,#240-16] + add $t3,$tbl,#256 @ rcon + mov lr,#255 + +.L128_loop: + and $t2,lr,$s3,lsr#24 + and $i1,lr,$s3,lsr#16 + ldrb $t2,[$tbl,$t2] + and $i2,lr,$s3,lsr#8 + ldrb $i1,[$tbl,$i1] + and $i3,lr,$s3 + ldrb $i2,[$tbl,$i2] + orr $t2,$t2,$i1,lsl#24 + ldrb $i3,[$tbl,$i3] + orr $t2,$t2,$i2,lsl#16 + ldr $t1,[$t3],#4 @ rcon[i++] + orr $t2,$t2,$i3,lsl#8 + eor $t2,$t2,$t1 + eor $s0,$s0,$t2 @ rk[4]=rk[0]^... + eor $s1,$s1,$s0 @ rk[5]=rk[1]^rk[4] + str $s0,[$key],#16 + eor $s2,$s2,$s1 @ rk[6]=rk[2]^rk[5] + str $s1,[$key,#-12] + eor $s3,$s3,$s2 @ rk[7]=rk[3]^rk[6] + str $s2,[$key,#-8] + subs $rounds,$rounds,#1 + str $s3,[$key,#-4] + bne .L128_loop + sub r2,$key,#176 + b .Ldone + +.Lnot128: +#if __ARM_ARCH__<7 + ldrb $i2,[$rounds,#19] + ldrb $t1,[$rounds,#18] + ldrb $t2,[$rounds,#17] + ldrb $t3,[$rounds,#16] + orr $i2,$i2,$t1,lsl#8 + ldrb $i3,[$rounds,#23] + orr $i2,$i2,$t2,lsl#16 + ldrb $t1,[$rounds,#22] + orr $i2,$i2,$t3,lsl#24 + ldrb $t2,[$rounds,#21] + ldrb $t3,[$rounds,#20] + orr $i3,$i3,$t1,lsl#8 + orr $i3,$i3,$t2,lsl#16 + str $i2,[$key],#8 + orr $i3,$i3,$t3,lsl#24 + str $i3,[$key,#-4] +#else + ldr $i2,[$rounds,#16] + ldr $i3,[$rounds,#20] +#ifdef __ARMEL__ + rev $i2,$i2 + rev $i3,$i3 +#endif + str $i2,[$key],#8 + str $i3,[$key,#-4] +#endif + + teq lr,#192 + bne .Lnot192 + mov $rounds,#12 + str $rounds,[$key,#240-24] + add $t3,$tbl,#256 @ rcon + mov lr,#255 + mov $rounds,#8 + +.L192_loop: + and $t2,lr,$i3,lsr#24 + and $i1,lr,$i3,lsr#16 + ldrb $t2,[$tbl,$t2] + and $i2,lr,$i3,lsr#8 + ldrb $i1,[$tbl,$i1] + and $i3,lr,$i3 + ldrb $i2,[$tbl,$i2] + orr $t2,$t2,$i1,lsl#24 + ldrb $i3,[$tbl,$i3] + orr $t2,$t2,$i2,lsl#16 + ldr $t1,[$t3],#4 @ rcon[i++] + orr $t2,$t2,$i3,lsl#8 + eor $i3,$t2,$t1 + eor $s0,$s0,$i3 @ rk[6]=rk[0]^... + eor $s1,$s1,$s0 @ rk[7]=rk[1]^rk[6] + str $s0,[$key],#24 + eor $s2,$s2,$s1 @ rk[8]=rk[2]^rk[7] + str $s1,[$key,#-20] + eor $s3,$s3,$s2 @ rk[9]=rk[3]^rk[8] + str $s2,[$key,#-16] + subs $rounds,$rounds,#1 + str $s3,[$key,#-12] + subeq r2,$key,#216 + beq .Ldone + + ldr $i1,[$key,#-32] + ldr $i2,[$key,#-28] + eor $i1,$i1,$s3 @ rk[10]=rk[4]^rk[9] + eor $i3,$i2,$i1 @ rk[11]=rk[5]^rk[10] + str $i1,[$key,#-8] + str $i3,[$key,#-4] + b .L192_loop + +.Lnot192: +#if __ARM_ARCH__<7 + ldrb $i2,[$rounds,#27] + ldrb $t1,[$rounds,#26] + ldrb $t2,[$rounds,#25] + ldrb $t3,[$rounds,#24] + orr $i2,$i2,$t1,lsl#8 + ldrb $i3,[$rounds,#31] + orr $i2,$i2,$t2,lsl#16 + ldrb $t1,[$rounds,#30] + orr $i2,$i2,$t3,lsl#24 + ldrb $t2,[$rounds,#29] + ldrb $t3,[$rounds,#28] + orr $i3,$i3,$t1,lsl#8 + orr $i3,$i3,$t2,lsl#16 + str $i2,[$key],#8 + orr $i3,$i3,$t3,lsl#24 + str $i3,[$key,#-4] +#else + ldr $i2,[$rounds,#24] + ldr $i3,[$rounds,#28] +#ifdef __ARMEL__ + rev $i2,$i2 + rev $i3,$i3 +#endif + str $i2,[$key],#8 + str $i3,[$key,#-4] +#endif + + mov $rounds,#14 + str $rounds,[$key,#240-32] + add $t3,$tbl,#256 @ rcon + mov lr,#255 + mov $rounds,#7 + +.L256_loop: + and $t2,lr,$i3,lsr#24 + and $i1,lr,$i3,lsr#16 + ldrb $t2,[$tbl,$t2] + and $i2,lr,$i3,lsr#8 + ldrb $i1,[$tbl,$i1] + and $i3,lr,$i3 + ldrb $i2,[$tbl,$i2] + orr $t2,$t2,$i1,lsl#24 + ldrb $i3,[$tbl,$i3] + orr $t2,$t2,$i2,lsl#16 + ldr $t1,[$t3],#4 @ rcon[i++] + orr $t2,$t2,$i3,lsl#8 + eor $i3,$t2,$t1 + eor $s0,$s0,$i3 @ rk[8]=rk[0]^... + eor $s1,$s1,$s0 @ rk[9]=rk[1]^rk[8] + str $s0,[$key],#32 + eor $s2,$s2,$s1 @ rk[10]=rk[2]^rk[9] + str $s1,[$key,#-28] + eor $s3,$s3,$s2 @ rk[11]=rk[3]^rk[10] + str $s2,[$key,#-24] + subs $rounds,$rounds,#1 + str $s3,[$key,#-20] + subeq r2,$key,#256 + beq .Ldone + + and $t2,lr,$s3 + and $i1,lr,$s3,lsr#8 + ldrb $t2,[$tbl,$t2] + and $i2,lr,$s3,lsr#16 + ldrb $i1,[$tbl,$i1] + and $i3,lr,$s3,lsr#24 + ldrb $i2,[$tbl,$i2] + orr $t2,$t2,$i1,lsl#8 + ldrb $i3,[$tbl,$i3] + orr $t2,$t2,$i2,lsl#16 + ldr $t1,[$key,#-48] + orr $t2,$t2,$i3,lsl#24 + + ldr $i1,[$key,#-44] + ldr $i2,[$key,#-40] + eor $t1,$t1,$t2 @ rk[12]=rk[4]^... + ldr $i3,[$key,#-36] + eor $i1,$i1,$t1 @ rk[13]=rk[5]^rk[12] + str $t1,[$key,#-16] + eor $i2,$i2,$i1 @ rk[14]=rk[6]^rk[13] + str $i1,[$key,#-12] + eor $i3,$i3,$i2 @ rk[15]=rk[7]^rk[14] + str $i2,[$key,#-8] + str $i3,[$key,#-4] + b .L256_loop + +.Ldone: mov r0,#0 + ldmia sp!,{r4-r12,lr} +.Labrt: tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +.size private_AES_set_encrypt_key,.-private_AES_set_encrypt_key + +.global private_AES_set_decrypt_key +.type private_AES_set_decrypt_key,%function +.align 5 +private_AES_set_decrypt_key: + str lr,[sp,#-4]! @ push lr + bl _armv4_AES_set_encrypt_key + teq r0,#0 + ldrne lr,[sp],#4 @ pop lr + bne .Labrt + + stmdb sp!,{r4-r12} + + ldr $rounds,[r2,#240] @ AES_set_encrypt_key preserves r2, + mov $key,r2 @ which is AES_KEY *key + mov $i1,r2 + add $i2,r2,$rounds,lsl#4 + +.Linv: ldr $s0,[$i1] + ldr $s1,[$i1,#4] + ldr $s2,[$i1,#8] + ldr $s3,[$i1,#12] + ldr $t1,[$i2] + ldr $t2,[$i2,#4] + ldr $t3,[$i2,#8] + ldr $i3,[$i2,#12] + str $s0,[$i2],#-16 + str $s1,[$i2,#16+4] + str $s2,[$i2,#16+8] + str $s3,[$i2,#16+12] + str $t1,[$i1],#16 + str $t2,[$i1,#-12] + str $t3,[$i1,#-8] + str $i3,[$i1,#-4] + teq $i1,$i2 + bne .Linv +___ +$mask80=$i1; +$mask1b=$i2; +$mask7f=$i3; +$code.=<<___; + ldr $s0,[$key,#16]! @ prefetch tp1 + mov $mask80,#0x80 + mov $mask1b,#0x1b + orr $mask80,$mask80,#0x8000 + orr $mask1b,$mask1b,#0x1b00 + orr $mask80,$mask80,$mask80,lsl#16 + orr $mask1b,$mask1b,$mask1b,lsl#16 + sub $rounds,$rounds,#1 + mvn $mask7f,$mask80 + mov $rounds,$rounds,lsl#2 @ (rounds-1)*4 + +.Lmix: and $t1,$s0,$mask80 + and $s1,$s0,$mask7f + sub $t1,$t1,$t1,lsr#7 + and $t1,$t1,$mask1b + eor $s1,$t1,$s1,lsl#1 @ tp2 + + and $t1,$s1,$mask80 + and $s2,$s1,$mask7f + sub $t1,$t1,$t1,lsr#7 + and $t1,$t1,$mask1b + eor $s2,$t1,$s2,lsl#1 @ tp4 + + and $t1,$s2,$mask80 + and $s3,$s2,$mask7f + sub $t1,$t1,$t1,lsr#7 + and $t1,$t1,$mask1b + eor $s3,$t1,$s3,lsl#1 @ tp8 + + eor $t1,$s1,$s2 + eor $t2,$s0,$s3 @ tp9 + eor $t1,$t1,$s3 @ tpe + eor $t1,$t1,$s1,ror#24 + eor $t1,$t1,$t2,ror#24 @ ^= ROTATE(tpb=tp9^tp2,8) + eor $t1,$t1,$s2,ror#16 + eor $t1,$t1,$t2,ror#16 @ ^= ROTATE(tpd=tp9^tp4,16) + eor $t1,$t1,$t2,ror#8 @ ^= ROTATE(tp9,24) + + ldr $s0,[$key,#4] @ prefetch tp1 + str $t1,[$key],#4 + subs $rounds,$rounds,#1 + bne .Lmix + + mov r0,#0 +#if __ARM_ARCH__>=5 + ldmia sp!,{r4-r12,pc} +#else + ldmia sp!,{r4-r12,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif +.size private_AES_set_decrypt_key,.-private_AES_set_decrypt_key + +.type AES_Td,%object +.align 5 +AES_Td: +.word 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96 +.word 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393 +.word 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25 +.word 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f +.word 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1 +.word 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6 +.word 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da +.word 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844 +.word 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd +.word 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4 +.word 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45 +.word 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94 +.word 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7 +.word 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a +.word 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5 +.word 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c +.word 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1 +.word 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a +.word 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75 +.word 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051 +.word 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46 +.word 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff +.word 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77 +.word 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb +.word 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000 +.word 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e +.word 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927 +.word 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a +.word 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e +.word 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16 +.word 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d +.word 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8 +.word 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd +.word 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34 +.word 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163 +.word 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120 +.word 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d +.word 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0 +.word 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422 +.word 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef +.word 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36 +.word 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4 +.word 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662 +.word 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5 +.word 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3 +.word 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b +.word 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8 +.word 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6 +.word 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6 +.word 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0 +.word 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815 +.word 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f +.word 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df +.word 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f +.word 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e +.word 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713 +.word 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89 +.word 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c +.word 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf +.word 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86 +.word 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f +.word 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541 +.word 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190 +.word 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742 +@ Td4[256] +.byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38 +.byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb +.byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87 +.byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb +.byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d +.byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e +.byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2 +.byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 +.byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16 +.byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 +.byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda +.byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 +.byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a +.byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 +.byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02 +.byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b +.byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea +.byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 +.byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85 +.byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e +.byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89 +.byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b +.byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20 +.byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 +.byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31 +.byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f +.byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d +.byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef +.byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0 +.byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 +.byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26 +.byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +.size AES_Td,.-AES_Td + +@ void AES_decrypt(const unsigned char *in, unsigned char *out, +@ const AES_KEY *key) { +.global AES_decrypt +.type AES_decrypt,%function +.align 5 +AES_decrypt: + sub r3,pc,#8 @ AES_decrypt + stmdb sp!,{r1,r4-r12,lr} + mov $rounds,r0 @ inp + mov $key,r2 + sub $tbl,r3,#AES_decrypt-AES_Td @ Td +#if __ARM_ARCH__<7 + ldrb $s0,[$rounds,#3] @ load input data in endian-neutral + ldrb $t1,[$rounds,#2] @ manner... + ldrb $t2,[$rounds,#1] + ldrb $t3,[$rounds,#0] + orr $s0,$s0,$t1,lsl#8 + ldrb $s1,[$rounds,#7] + orr $s0,$s0,$t2,lsl#16 + ldrb $t1,[$rounds,#6] + orr $s0,$s0,$t3,lsl#24 + ldrb $t2,[$rounds,#5] + ldrb $t3,[$rounds,#4] + orr $s1,$s1,$t1,lsl#8 + ldrb $s2,[$rounds,#11] + orr $s1,$s1,$t2,lsl#16 + ldrb $t1,[$rounds,#10] + orr $s1,$s1,$t3,lsl#24 + ldrb $t2,[$rounds,#9] + ldrb $t3,[$rounds,#8] + orr $s2,$s2,$t1,lsl#8 + ldrb $s3,[$rounds,#15] + orr $s2,$s2,$t2,lsl#16 + ldrb $t1,[$rounds,#14] + orr $s2,$s2,$t3,lsl#24 + ldrb $t2,[$rounds,#13] + ldrb $t3,[$rounds,#12] + orr $s3,$s3,$t1,lsl#8 + orr $s3,$s3,$t2,lsl#16 + orr $s3,$s3,$t3,lsl#24 +#else + ldr $s0,[$rounds,#0] + ldr $s1,[$rounds,#4] + ldr $s2,[$rounds,#8] + ldr $s3,[$rounds,#12] +#ifdef __ARMEL__ + rev $s0,$s0 + rev $s1,$s1 + rev $s2,$s2 + rev $s3,$s3 +#endif +#endif + bl _armv4_AES_decrypt + + ldr $rounds,[sp],#4 @ pop out +#if __ARM_ARCH__>=7 +#ifdef __ARMEL__ + rev $s0,$s0 + rev $s1,$s1 + rev $s2,$s2 + rev $s3,$s3 +#endif + str $s0,[$rounds,#0] + str $s1,[$rounds,#4] + str $s2,[$rounds,#8] + str $s3,[$rounds,#12] +#else + mov $t1,$s0,lsr#24 @ write output in endian-neutral + mov $t2,$s0,lsr#16 @ manner... + mov $t3,$s0,lsr#8 + strb $t1,[$rounds,#0] + strb $t2,[$rounds,#1] + mov $t1,$s1,lsr#24 + strb $t3,[$rounds,#2] + mov $t2,$s1,lsr#16 + strb $s0,[$rounds,#3] + mov $t3,$s1,lsr#8 + strb $t1,[$rounds,#4] + strb $t2,[$rounds,#5] + mov $t1,$s2,lsr#24 + strb $t3,[$rounds,#6] + mov $t2,$s2,lsr#16 + strb $s1,[$rounds,#7] + mov $t3,$s2,lsr#8 + strb $t1,[$rounds,#8] + strb $t2,[$rounds,#9] + mov $t1,$s3,lsr#24 + strb $t3,[$rounds,#10] + mov $t2,$s3,lsr#16 + strb $s2,[$rounds,#11] + mov $t3,$s3,lsr#8 + strb $t1,[$rounds,#12] + strb $t2,[$rounds,#13] + strb $t3,[$rounds,#14] + strb $s3,[$rounds,#15] +#endif +#if __ARM_ARCH__>=5 + ldmia sp!,{r4-r12,pc} +#else + ldmia sp!,{r4-r12,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif +.size AES_decrypt,.-AES_decrypt + +.type _armv4_AES_decrypt,%function +.align 2 +_armv4_AES_decrypt: + str lr,[sp,#-4]! @ push lr + ldmia $key!,{$t1-$i1} + eor $s0,$s0,$t1 + ldr $rounds,[$key,#240-16] + eor $s1,$s1,$t2 + eor $s2,$s2,$t3 + eor $s3,$s3,$i1 + sub $rounds,$rounds,#1 + mov lr,#255 + + and $i1,lr,$s0,lsr#16 + and $i2,lr,$s0,lsr#8 + and $i3,lr,$s0 + mov $s0,$s0,lsr#24 +.Ldec_loop: + ldr $t1,[$tbl,$i1,lsl#2] @ Td1[s0>>16] + and $i1,lr,$s1 @ i0 + ldr $t2,[$tbl,$i2,lsl#2] @ Td2[s0>>8] + and $i2,lr,$s1,lsr#16 + ldr $t3,[$tbl,$i3,lsl#2] @ Td3[s0>>0] + and $i3,lr,$s1,lsr#8 + ldr $s0,[$tbl,$s0,lsl#2] @ Td0[s0>>24] + mov $s1,$s1,lsr#24 + + ldr $i1,[$tbl,$i1,lsl#2] @ Td3[s1>>0] + ldr $i2,[$tbl,$i2,lsl#2] @ Td1[s1>>16] + ldr $i3,[$tbl,$i3,lsl#2] @ Td2[s1>>8] + eor $s0,$s0,$i1,ror#24 + ldr $s1,[$tbl,$s1,lsl#2] @ Td0[s1>>24] + and $i1,lr,$s2,lsr#8 @ i0 + eor $t2,$i2,$t2,ror#8 + and $i2,lr,$s2 @ i1 + eor $t3,$i3,$t3,ror#8 + and $i3,lr,$s2,lsr#16 + ldr $i1,[$tbl,$i1,lsl#2] @ Td2[s2>>8] + eor $s1,$s1,$t1,ror#8 + ldr $i2,[$tbl,$i2,lsl#2] @ Td3[s2>>0] + mov $s2,$s2,lsr#24 + + ldr $i3,[$tbl,$i3,lsl#2] @ Td1[s2>>16] + eor $s0,$s0,$i1,ror#16 + ldr $s2,[$tbl,$s2,lsl#2] @ Td0[s2>>24] + and $i1,lr,$s3,lsr#16 @ i0 + eor $s1,$s1,$i2,ror#24 + and $i2,lr,$s3,lsr#8 @ i1 + eor $t3,$i3,$t3,ror#8 + and $i3,lr,$s3 @ i2 + ldr $i1,[$tbl,$i1,lsl#2] @ Td1[s3>>16] + eor $s2,$s2,$t2,ror#8 + ldr $i2,[$tbl,$i2,lsl#2] @ Td2[s3>>8] + mov $s3,$s3,lsr#24 + + ldr $i3,[$tbl,$i3,lsl#2] @ Td3[s3>>0] + eor $s0,$s0,$i1,ror#8 + ldr $i1,[$key],#16 + eor $s1,$s1,$i2,ror#16 + ldr $s3,[$tbl,$s3,lsl#2] @ Td0[s3>>24] + eor $s2,$s2,$i3,ror#24 + + ldr $t1,[$key,#-12] + eor $s0,$s0,$i1 + ldr $t2,[$key,#-8] + eor $s3,$s3,$t3,ror#8 + ldr $t3,[$key,#-4] + and $i1,lr,$s0,lsr#16 + eor $s1,$s1,$t1 + and $i2,lr,$s0,lsr#8 + eor $s2,$s2,$t2 + and $i3,lr,$s0 + eor $s3,$s3,$t3 + mov $s0,$s0,lsr#24 + + subs $rounds,$rounds,#1 + bne .Ldec_loop + + add $tbl,$tbl,#1024 + + ldr $t2,[$tbl,#0] @ prefetch Td4 + ldr $t3,[$tbl,#32] + ldr $t1,[$tbl,#64] + ldr $t2,[$tbl,#96] + ldr $t3,[$tbl,#128] + ldr $t1,[$tbl,#160] + ldr $t2,[$tbl,#192] + ldr $t3,[$tbl,#224] + + ldrb $s0,[$tbl,$s0] @ Td4[s0>>24] + ldrb $t1,[$tbl,$i1] @ Td4[s0>>16] + and $i1,lr,$s1 @ i0 + ldrb $t2,[$tbl,$i2] @ Td4[s0>>8] + and $i2,lr,$s1,lsr#16 + ldrb $t3,[$tbl,$i3] @ Td4[s0>>0] + and $i3,lr,$s1,lsr#8 + + ldrb $i1,[$tbl,$i1] @ Td4[s1>>0] + ldrb $s1,[$tbl,$s1,lsr#24] @ Td4[s1>>24] + ldrb $i2,[$tbl,$i2] @ Td4[s1>>16] + eor $s0,$i1,$s0,lsl#24 + ldrb $i3,[$tbl,$i3] @ Td4[s1>>8] + eor $s1,$t1,$s1,lsl#8 + and $i1,lr,$s2,lsr#8 @ i0 + eor $t2,$t2,$i2,lsl#8 + and $i2,lr,$s2 @ i1 + ldrb $i1,[$tbl,$i1] @ Td4[s2>>8] + eor $t3,$t3,$i3,lsl#8 + ldrb $i2,[$tbl,$i2] @ Td4[s2>>0] + and $i3,lr,$s2,lsr#16 + + ldrb $s2,[$tbl,$s2,lsr#24] @ Td4[s2>>24] + eor $s0,$s0,$i1,lsl#8 + ldrb $i3,[$tbl,$i3] @ Td4[s2>>16] + eor $s1,$i2,$s1,lsl#16 + and $i1,lr,$s3,lsr#16 @ i0 + eor $s2,$t2,$s2,lsl#16 + and $i2,lr,$s3,lsr#8 @ i1 + ldrb $i1,[$tbl,$i1] @ Td4[s3>>16] + eor $t3,$t3,$i3,lsl#16 + ldrb $i2,[$tbl,$i2] @ Td4[s3>>8] + and $i3,lr,$s3 @ i2 + + ldrb $i3,[$tbl,$i3] @ Td4[s3>>0] + ldrb $s3,[$tbl,$s3,lsr#24] @ Td4[s3>>24] + eor $s0,$s0,$i1,lsl#16 + ldr $i1,[$key,#0] + eor $s1,$s1,$i2,lsl#8 + ldr $t1,[$key,#4] + eor $s2,$i3,$s2,lsl#8 + ldr $t2,[$key,#8] + eor $s3,$t3,$s3,lsl#24 + ldr $t3,[$key,#12] + + eor $s0,$s0,$i1 + eor $s1,$s1,$t1 + eor $s2,$s2,$t2 + eor $s3,$s3,$t3 + + sub $tbl,$tbl,#1024 + ldr pc,[sp],#4 @ pop and return +.size _armv4_AES_decrypt,.-_armv4_AES_decrypt +.asciz "AES for ARMv4, CRYPTOGAMS by " +.align 2 +___ + +$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 +print $code; +close STDOUT; # enforce flush diff --git a/libs/openssl/crypto/aes/asm/aes-ia64.S b/libs/openssl/crypto/aes/asm/aes-ia64.S new file mode 100644 index 00000000..7f6c4c36 --- /dev/null +++ b/libs/openssl/crypto/aes/asm/aes-ia64.S @@ -0,0 +1,1123 @@ +// ==================================================================== +// Written by Andy Polyakov for the OpenSSL +// project. Rights for redistribution and usage in source and binary +// forms are granted according to the OpenSSL license. +// ==================================================================== +// +// What's wrong with compiler generated code? Compiler never uses +// variable 'shr' which is pairable with 'extr'/'dep' instructions. +// Then it uses 'zxt' which is an I-type, but can be replaced with +// 'and' which in turn can be assigned to M-port [there're double as +// much M-ports as there're I-ports on Itanium 2]. By sacrificing few +// registers for small constants (255, 24 and 16) to be used with +// 'shr' and 'and' instructions I can achieve better ILP, Intruction +// Level Parallelism, and performance. This code outperforms GCC 3.3 +// generated code by over factor of 2 (two), GCC 3.4 - by 70% and +// HP C - by 40%. Measured best-case scenario, i.e. aligned +// big-endian input, ECB timing on Itanium 2 is (18 + 13*rounds) +// ticks per block, or 9.25 CPU cycles per byte for 128 bit key. + +// Version 1.2 mitigates the hazard of cache-timing attacks by +// a) compressing S-boxes from 8KB to 2KB+256B, b) scheduling +// references to S-boxes for L2 cache latency, c) prefetching T[ed]4 +// prior last round. As result performance dropped to (26 + 15*rounds) +// ticks per block or 11 cycles per byte processed with 128-bit key. +// This is ~16% deterioration. For reference Itanium 2 L1 cache has +// 64 bytes line size and L2 - 128 bytes... + +.ident "aes-ia64.S, version 1.2" +.ident "IA-64 ISA artwork by Andy Polyakov " +.explicit +.text + +rk0=r8; rk1=r9; + +pfssave=r2; +lcsave=r10; +prsave=r3; +maskff=r11; +twenty4=r14; +sixteen=r15; + +te00=r16; te11=r17; te22=r18; te33=r19; +te01=r20; te12=r21; te23=r22; te30=r23; +te02=r24; te13=r25; te20=r26; te31=r27; +te03=r28; te10=r29; te21=r30; te32=r31; + +// these are rotating... +t0=r32; s0=r33; +t1=r34; s1=r35; +t2=r36; s2=r37; +t3=r38; s3=r39; + +te0=r40; te1=r41; te2=r42; te3=r43; + +#if defined(_HPUX_SOURCE) && !defined(_LP64) +# define ADDP addp4 +#else +# define ADDP add +#endif + +// Offsets from Te0 +#define TE0 0 +#define TE2 2 +#if defined(_HPUX_SOURCE) || defined(B_ENDIAN) +#define TE1 3 +#define TE3 1 +#else +#define TE1 1 +#define TE3 3 +#endif + +// This implies that AES_KEY comprises 32-bit key schedule elements +// even on LP64 platforms. +#ifndef KSZ +# define KSZ 4 +# define LDKEY ld4 +#endif + +.proc _ia64_AES_encrypt# +// Input: rk0-rk1 +// te0 +// te3 as AES_KEY->rounds!!! +// s0-s3 +// maskff,twenty4,sixteen +// Output: r16,r20,r24,r28 as s0-s3 +// Clobber: r16-r31,rk0-rk1,r32-r43 +.align 32 +_ia64_AES_encrypt: + .prologue + .altrp b6 + .body +{ .mmi; alloc r16=ar.pfs,12,0,0,8 + LDKEY t0=[rk0],2*KSZ + mov pr.rot=1<<16 } +{ .mmi; LDKEY t1=[rk1],2*KSZ + add te1=TE1,te0 + add te3=-3,te3 };; +{ .mib; LDKEY t2=[rk0],2*KSZ + mov ar.ec=2 } +{ .mib; LDKEY t3=[rk1],2*KSZ + add te2=TE2,te0 + brp.loop.imp .Le_top,.Le_end-16 };; + +{ .mmi; xor s0=s0,t0 + xor s1=s1,t1 + mov ar.lc=te3 } +{ .mmi; xor s2=s2,t2 + xor s3=s3,t3 + add te3=TE3,te0 };; + +.align 32 +.Le_top: +{ .mmi; (p0) LDKEY t0=[rk0],2*KSZ // 0/0:rk[0] + (p0) and te33=s3,maskff // 0/0:s3&0xff + (p0) extr.u te22=s2,8,8 } // 0/0:s2>>8&0xff +{ .mmi; (p0) LDKEY t1=[rk1],2*KSZ // 0/1:rk[1] + (p0) and te30=s0,maskff // 0/1:s0&0xff + (p0) shr.u te00=s0,twenty4 };; // 0/0:s0>>24 +{ .mmi; (p0) LDKEY t2=[rk0],2*KSZ // 1/2:rk[2] + (p0) shladd te33=te33,3,te3 // 1/0:te0+s0>>24 + (p0) extr.u te23=s3,8,8 } // 1/1:s3>>8&0xff +{ .mmi; (p0) LDKEY t3=[rk1],2*KSZ // 1/3:rk[3] + (p0) shladd te30=te30,3,te3 // 1/1:te3+s0 + (p0) shr.u te01=s1,twenty4 };; // 1/1:s1>>24 +{ .mmi; (p0) ld4 te33=[te33] // 2/0:te3[s3&0xff] + (p0) shladd te22=te22,3,te2 // 2/0:te2+s2>>8&0xff + (p0) extr.u te20=s0,8,8 } // 2/2:s0>>8&0xff +{ .mmi; (p0) ld4 te30=[te30] // 2/1:te3[s0] + (p0) shladd te23=te23,3,te2 // 2/1:te2+s3>>8 + (p0) shr.u te02=s2,twenty4 };; // 2/2:s2>>24 +{ .mmi; (p0) ld4 te22=[te22] // 3/0:te2[s2>>8] + (p0) shladd te20=te20,3,te2 // 3/2:te2+s0>>8 + (p0) extr.u te21=s1,8,8 } // 3/3:s1>>8&0xff +{ .mmi; (p0) ld4 te23=[te23] // 3/1:te2[s3>>8] + (p0) shladd te00=te00,3,te0 // 3/0:te0+s0>>24 + (p0) shr.u te03=s3,twenty4 };; // 3/3:s3>>24 +{ .mmi; (p0) ld4 te20=[te20] // 4/2:te2[s0>>8] + (p0) shladd te21=te21,3,te2 // 4/3:te3+s2 + (p0) extr.u te11=s1,16,8 } // 4/0:s1>>16&0xff +{ .mmi; (p0) ld4 te00=[te00] // 4/0:te0[s0>>24] + (p0) shladd te01=te01,3,te0 // 4/1:te0+s1>>24 + (p0) shr.u te13=s3,sixteen };; // 4/2:s3>>16 +{ .mmi; (p0) ld4 te21=[te21] // 5/3:te2[s1>>8] + (p0) shladd te11=te11,3,te1 // 5/0:te1+s1>>16 + (p0) extr.u te12=s2,16,8 } // 5/1:s2>>16&0xff +{ .mmi; (p0) ld4 te01=[te01] // 5/1:te0[s1>>24] + (p0) shladd te02=te02,3,te0 // 5/2:te0+s2>>24 + (p0) and te31=s1,maskff };; // 5/2:s1&0xff +{ .mmi; (p0) ld4 te11=[te11] // 6/0:te1[s1>>16] + (p0) shladd te12=te12,3,te1 // 6/1:te1+s2>>16 + (p0) extr.u te10=s0,16,8 } // 6/3:s0>>16&0xff +{ .mmi; (p0) ld4 te02=[te02] // 6/2:te0[s2>>24] + (p0) shladd te03=te03,3,te0 // 6/3:te1+s0>>16 + (p0) and te32=s2,maskff };; // 6/3:s2&0xff + +{ .mmi; (p0) ld4 te12=[te12] // 7/1:te1[s2>>16] + (p0) shladd te31=te31,3,te3 // 7/2:te3+s1&0xff + (p0) and te13=te13,maskff} // 7/2:s3>>16&0xff +{ .mmi; (p0) ld4 te03=[te03] // 7/3:te0[s3>>24] + (p0) shladd te32=te32,3,te3 // 7/3:te3+s2 + (p0) xor t0=t0,te33 };; // 7/0: +{ .mmi; (p0) ld4 te31=[te31] // 8/2:te3[s1] + (p0) shladd te13=te13,3,te1 // 8/2:te1+s3>>16 + (p0) xor t0=t0,te22 } // 8/0: +{ .mmi; (p0) ld4 te32=[te32] // 8/3:te3[s2] + (p0) shladd te10=te10,3,te1 // 8/3:te1+s0>>16 + (p0) xor t1=t1,te30 };; // 8/1: +{ .mmi; (p0) ld4 te13=[te13] // 9/2:te1[s3>>16] + (p0) ld4 te10=[te10] // 9/3:te1[s0>>16] + (p0) xor t0=t0,te00 };; // 9/0: !L2 scheduling +{ .mmi; (p0) xor t1=t1,te23 // 10[9]/1: + (p0) xor t2=t2,te20 // 10[9]/2: + (p0) xor t3=t3,te21 };; // 10[9]/3: +{ .mmi; (p0) xor t0=t0,te11 // 11[10]/0:done! + (p0) xor t1=t1,te01 // 11[10]/1: + (p0) xor t2=t2,te02 };; // 11[10]/2: !L2 scheduling +{ .mmi; (p0) xor t3=t3,te03 // 12[10]/3: + (p16) cmp.eq p0,p17=r0,r0 };; // 12[10]/clear (p17) +{ .mmi; (p0) xor t1=t1,te12 // 13[11]/1:done! + (p0) xor t2=t2,te31 // 13[11]/2: + (p0) xor t3=t3,te32 } // 13[11]/3: +{ .mmi; (p17) add te0=2048,te0 // 13[11]/ + (p17) add te1=2048+64-TE1,te1};; // 13[11]/ +{ .mib; (p0) xor t2=t2,te13 // 14[12]/2:done! + (p17) add te2=2048+128-TE2,te2} // 14[12]/ +{ .mib; (p0) xor t3=t3,te10 // 14[12]/3:done! + (p17) add te3=2048+192-TE3,te3 // 14[12]/ + br.ctop.sptk .Le_top };; +.Le_end: + + +{ .mmi; ld8 te12=[te0] // prefetch Te4 + ld8 te31=[te1] } +{ .mmi; ld8 te10=[te2] + ld8 te32=[te3] } + +{ .mmi; LDKEY t0=[rk0],2*KSZ // 0/0:rk[0] + and te33=s3,maskff // 0/0:s3&0xff + extr.u te22=s2,8,8 } // 0/0:s2>>8&0xff +{ .mmi; LDKEY t1=[rk1],2*KSZ // 0/1:rk[1] + and te30=s0,maskff // 0/1:s0&0xff + shr.u te00=s0,twenty4 };; // 0/0:s0>>24 +{ .mmi; LDKEY t2=[rk0],2*KSZ // 1/2:rk[2] + add te33=te33,te0 // 1/0:te0+s0>>24 + extr.u te23=s3,8,8 } // 1/1:s3>>8&0xff +{ .mmi; LDKEY t3=[rk1],2*KSZ // 1/3:rk[3] + add te30=te30,te0 // 1/1:te0+s0 + shr.u te01=s1,twenty4 };; // 1/1:s1>>24 +{ .mmi; ld1 te33=[te33] // 2/0:te0[s3&0xff] + add te22=te22,te0 // 2/0:te0+s2>>8&0xff + extr.u te20=s0,8,8 } // 2/2:s0>>8&0xff +{ .mmi; ld1 te30=[te30] // 2/1:te0[s0] + add te23=te23,te0 // 2/1:te0+s3>>8 + shr.u te02=s2,twenty4 };; // 2/2:s2>>24 +{ .mmi; ld1 te22=[te22] // 3/0:te0[s2>>8] + add te20=te20,te0 // 3/2:te0+s0>>8 + extr.u te21=s1,8,8 } // 3/3:s1>>8&0xff +{ .mmi; ld1 te23=[te23] // 3/1:te0[s3>>8] + add te00=te00,te0 // 3/0:te0+s0>>24 + shr.u te03=s3,twenty4 };; // 3/3:s3>>24 +{ .mmi; ld1 te20=[te20] // 4/2:te0[s0>>8] + add te21=te21,te0 // 4/3:te0+s2 + extr.u te11=s1,16,8 } // 4/0:s1>>16&0xff +{ .mmi; ld1 te00=[te00] // 4/0:te0[s0>>24] + add te01=te01,te0 // 4/1:te0+s1>>24 + shr.u te13=s3,sixteen };; // 4/2:s3>>16 +{ .mmi; ld1 te21=[te21] // 5/3:te0[s1>>8] + add te11=te11,te0 // 5/0:te0+s1>>16 + extr.u te12=s2,16,8 } // 5/1:s2>>16&0xff +{ .mmi; ld1 te01=[te01] // 5/1:te0[s1>>24] + add te02=te02,te0 // 5/2:te0+s2>>24 + and te31=s1,maskff };; // 5/2:s1&0xff +{ .mmi; ld1 te11=[te11] // 6/0:te0[s1>>16] + add te12=te12,te0 // 6/1:te0+s2>>16 + extr.u te10=s0,16,8 } // 6/3:s0>>16&0xff +{ .mmi; ld1 te02=[te02] // 6/2:te0[s2>>24] + add te03=te03,te0 // 6/3:te0+s0>>16 + and te32=s2,maskff };; // 6/3:s2&0xff + +{ .mmi; ld1 te12=[te12] // 7/1:te0[s2>>16] + add te31=te31,te0 // 7/2:te0+s1&0xff + dep te33=te22,te33,8,8} // 7/0: +{ .mmi; ld1 te03=[te03] // 7/3:te0[s3>>24] + add te32=te32,te0 // 7/3:te0+s2 + and te13=te13,maskff};; // 7/2:s3>>16&0xff +{ .mmi; ld1 te31=[te31] // 8/2:te0[s1] + add te13=te13,te0 // 8/2:te0+s3>>16 + dep te30=te23,te30,8,8} // 8/1: +{ .mmi; ld1 te32=[te32] // 8/3:te0[s2] + add te10=te10,te0 // 8/3:te0+s0>>16 + shl te00=te00,twenty4};; // 8/0: +{ .mii; ld1 te13=[te13] // 9/2:te0[s3>>16] + dep te33=te11,te33,16,8 // 9/0: + shl te01=te01,twenty4};; // 9/1: +{ .mii; ld1 te10=[te10] // 10/3:te0[s0>>16] + dep te31=te20,te31,8,8 // 10/2: + shl te02=te02,twenty4};; // 10/2: +{ .mii; xor t0=t0,te33 // 11/0: + dep te32=te21,te32,8,8 // 11/3: + shl te12=te12,sixteen};; // 11/1: +{ .mii; xor r16=t0,te00 // 12/0:done! + dep te31=te13,te31,16,8 // 12/2: + shl te03=te03,twenty4};; // 12/3: +{ .mmi; xor t1=t1,te01 // 13/1: + xor t2=t2,te02 // 13/2: + dep te32=te10,te32,16,8};; // 13/3: +{ .mmi; xor t1=t1,te30 // 14/1: + xor r24=t2,te31 // 14/2:done! + xor t3=t3,te32 };; // 14/3: +{ .mib; xor r20=t1,te12 // 15/1:done! + xor r28=t3,te03 // 15/3:done! + br.ret.sptk b6 };; +.endp _ia64_AES_encrypt# + +// void AES_encrypt (const void *in,void *out,const AES_KEY *key); +.global AES_encrypt# +.proc AES_encrypt# +.align 32 +AES_encrypt: + .prologue + .save ar.pfs,pfssave +{ .mmi; alloc pfssave=ar.pfs,3,1,12,0 + and out0=3,in0 + mov r3=ip } +{ .mmi; ADDP in0=0,in0 + mov loc0=psr.um + ADDP out11=KSZ*60,in2 };; // &AES_KEY->rounds + +{ .mmi; ld4 out11=[out11] // AES_KEY->rounds + add out8=(AES_Te#-AES_encrypt#),r3 // Te0 + .save pr,prsave + mov prsave=pr } +{ .mmi; rum 1<<3 // clear um.ac + .save ar.lc,lcsave + mov lcsave=ar.lc };; + + .body +#if defined(_HPUX_SOURCE) // HPUX is big-endian, cut 15+15 cycles... +{ .mib; cmp.ne p6,p0=out0,r0 + add out0=4,in0 +(p6) br.dpnt.many .Le_i_unaligned };; + +{ .mmi; ld4 out1=[in0],8 // s0 + and out9=3,in1 + mov twenty4=24 } +{ .mmi; ld4 out3=[out0],8 // s1 + ADDP rk0=0,in2 + mov sixteen=16 };; +{ .mmi; ld4 out5=[in0] // s2 + cmp.ne p6,p0=out9,r0 + mov maskff=0xff } +{ .mmb; ld4 out7=[out0] // s3 + ADDP rk1=KSZ,in2 + br.call.sptk.many b6=_ia64_AES_encrypt };; + +{ .mib; ADDP in0=4,in1 + ADDP in1=0,in1 +(p6) br.spnt .Le_o_unaligned };; + +{ .mii; mov psr.um=loc0 + mov ar.pfs=pfssave + mov ar.lc=lcsave };; +{ .mmi; st4 [in1]=r16,8 // s0 + st4 [in0]=r20,8 // s1 + mov pr=prsave,0x1ffff };; +{ .mmb; st4 [in1]=r24 // s2 + st4 [in0]=r28 // s3 + br.ret.sptk.many b0 };; +#endif + +.align 32 +.Le_i_unaligned: +{ .mmi; add out0=1,in0 + add out2=2,in0 + add out4=3,in0 };; +{ .mmi; ld1 r16=[in0],4 + ld1 r17=[out0],4 }//;; +{ .mmi; ld1 r18=[out2],4 + ld1 out1=[out4],4 };; // s0 +{ .mmi; ld1 r20=[in0],4 + ld1 r21=[out0],4 }//;; +{ .mmi; ld1 r22=[out2],4 + ld1 out3=[out4],4 };; // s1 +{ .mmi; ld1 r24=[in0],4 + ld1 r25=[out0],4 }//;; +{ .mmi; ld1 r26=[out2],4 + ld1 out5=[out4],4 };; // s2 +{ .mmi; ld1 r28=[in0] + ld1 r29=[out0] }//;; +{ .mmi; ld1 r30=[out2] + ld1 out7=[out4] };; // s3 + +{ .mii; + dep out1=r16,out1,24,8 //;; + dep out3=r20,out3,24,8 }//;; +{ .mii; ADDP rk0=0,in2 + dep out5=r24,out5,24,8 //;; + dep out7=r28,out7,24,8 };; +{ .mii; ADDP rk1=KSZ,in2 + dep out1=r17,out1,16,8 //;; + dep out3=r21,out3,16,8 }//;; +{ .mii; mov twenty4=24 + dep out5=r25,out5,16,8 //;; + dep out7=r29,out7,16,8 };; +{ .mii; mov sixteen=16 + dep out1=r18,out1,8,8 //;; + dep out3=r22,out3,8,8 }//;; +{ .mii; mov maskff=0xff + dep out5=r26,out5,8,8 //;; + dep out7=r30,out7,8,8 };; + +{ .mib; br.call.sptk.many b6=_ia64_AES_encrypt };; + +.Le_o_unaligned: +{ .mii; ADDP out0=0,in1 + extr.u r17=r16,8,8 // s0 + shr.u r19=r16,twenty4 }//;; +{ .mii; ADDP out1=1,in1 + extr.u r18=r16,16,8 + shr.u r23=r20,twenty4 }//;; // s1 +{ .mii; ADDP out2=2,in1 + extr.u r21=r20,8,8 + shr.u r22=r20,sixteen }//;; +{ .mii; ADDP out3=3,in1 + extr.u r25=r24,8,8 // s2 + shr.u r27=r24,twenty4 };; +{ .mii; st1 [out3]=r16,4 + extr.u r26=r24,16,8 + shr.u r31=r28,twenty4 }//;; // s3 +{ .mii; st1 [out2]=r17,4 + extr.u r29=r28,8,8 + shr.u r30=r28,sixteen }//;; + +{ .mmi; st1 [out1]=r18,4 + st1 [out0]=r19,4 };; +{ .mmi; st1 [out3]=r20,4 + st1 [out2]=r21,4 }//;; +{ .mmi; st1 [out1]=r22,4 + st1 [out0]=r23,4 };; +{ .mmi; st1 [out3]=r24,4 + st1 [out2]=r25,4 + mov pr=prsave,0x1ffff }//;; +{ .mmi; st1 [out1]=r26,4 + st1 [out0]=r27,4 + mov ar.pfs=pfssave };; +{ .mmi; st1 [out3]=r28 + st1 [out2]=r29 + mov ar.lc=lcsave }//;; +{ .mmi; st1 [out1]=r30 + st1 [out0]=r31 } +{ .mfb; mov psr.um=loc0 // restore user mask + br.ret.sptk.many b0 };; +.endp AES_encrypt# + +// *AES_decrypt are autogenerated by the following script: +#if 0 +#!/usr/bin/env perl +print "// *AES_decrypt are autogenerated by the following script:\n#if 0\n"; +open(PROG,'<'.$0); while() { print; } close(PROG); +print "#endif\n"; +while(<>) { + $process=1 if (/\.proc\s+_ia64_AES_encrypt/); + next if (!$process); + + #s/te00=s0/td00=s0/; s/te00/td00/g; + s/te11=s1/td13=s3/; s/te11/td13/g; + #s/te22=s2/td22=s2/; s/te22/td22/g; + s/te33=s3/td31=s1/; s/te33/td31/g; + + #s/te01=s1/td01=s1/; s/te01/td01/g; + s/te12=s2/td10=s0/; s/te12/td10/g; + #s/te23=s3/td23=s3/; s/te23/td23/g; + s/te30=s0/td32=s2/; s/te30/td32/g; + + #s/te02=s2/td02=s2/; s/te02/td02/g; + s/te13=s3/td11=s1/; s/te13/td11/g; + #s/te20=s0/td20=s0/; s/te20/td20/g; + s/te31=s1/td33=s3/; s/te31/td33/g; + + #s/te03=s3/td03=s3/; s/te03/td03/g; + s/te10=s0/td12=s2/; s/te10/td12/g; + #s/te21=s1/td21=s1/; s/te21/td21/g; + s/te32=s2/td30=s0/; s/te32/td30/g; + + s/td/te/g; + + s/AES_encrypt/AES_decrypt/g; + s/\.Le_/.Ld_/g; + s/AES_Te#/AES_Td#/g; + + print; + + exit if (/\.endp\s+AES_decrypt/); +} +#endif +.proc _ia64_AES_decrypt# +// Input: rk0-rk1 +// te0 +// te3 as AES_KEY->rounds!!! +// s0-s3 +// maskff,twenty4,sixteen +// Output: r16,r20,r24,r28 as s0-s3 +// Clobber: r16-r31,rk0-rk1,r32-r43 +.align 32 +_ia64_AES_decrypt: + .prologue + .altrp b6 + .body +{ .mmi; alloc r16=ar.pfs,12,0,0,8 + LDKEY t0=[rk0],2*KSZ + mov pr.rot=1<<16 } +{ .mmi; LDKEY t1=[rk1],2*KSZ + add te1=TE1,te0 + add te3=-3,te3 };; +{ .mib; LDKEY t2=[rk0],2*KSZ + mov ar.ec=2 } +{ .mib; LDKEY t3=[rk1],2*KSZ + add te2=TE2,te0 + brp.loop.imp .Ld_top,.Ld_end-16 };; + +{ .mmi; xor s0=s0,t0 + xor s1=s1,t1 + mov ar.lc=te3 } +{ .mmi; xor s2=s2,t2 + xor s3=s3,t3 + add te3=TE3,te0 };; + +.align 32 +.Ld_top: +{ .mmi; (p0) LDKEY t0=[rk0],2*KSZ // 0/0:rk[0] + (p0) and te31=s1,maskff // 0/0:s3&0xff + (p0) extr.u te22=s2,8,8 } // 0/0:s2>>8&0xff +{ .mmi; (p0) LDKEY t1=[rk1],2*KSZ // 0/1:rk[1] + (p0) and te32=s2,maskff // 0/1:s0&0xff + (p0) shr.u te00=s0,twenty4 };; // 0/0:s0>>24 +{ .mmi; (p0) LDKEY t2=[rk0],2*KSZ // 1/2:rk[2] + (p0) shladd te31=te31,3,te3 // 1/0:te0+s0>>24 + (p0) extr.u te23=s3,8,8 } // 1/1:s3>>8&0xff +{ .mmi; (p0) LDKEY t3=[rk1],2*KSZ // 1/3:rk[3] + (p0) shladd te32=te32,3,te3 // 1/1:te3+s0 + (p0) shr.u te01=s1,twenty4 };; // 1/1:s1>>24 +{ .mmi; (p0) ld4 te31=[te31] // 2/0:te3[s3&0xff] + (p0) shladd te22=te22,3,te2 // 2/0:te2+s2>>8&0xff + (p0) extr.u te20=s0,8,8 } // 2/2:s0>>8&0xff +{ .mmi; (p0) ld4 te32=[te32] // 2/1:te3[s0] + (p0) shladd te23=te23,3,te2 // 2/1:te2+s3>>8 + (p0) shr.u te02=s2,twenty4 };; // 2/2:s2>>24 +{ .mmi; (p0) ld4 te22=[te22] // 3/0:te2[s2>>8] + (p0) shladd te20=te20,3,te2 // 3/2:te2+s0>>8 + (p0) extr.u te21=s1,8,8 } // 3/3:s1>>8&0xff +{ .mmi; (p0) ld4 te23=[te23] // 3/1:te2[s3>>8] + (p0) shladd te00=te00,3,te0 // 3/0:te0+s0>>24 + (p0) shr.u te03=s3,twenty4 };; // 3/3:s3>>24 +{ .mmi; (p0) ld4 te20=[te20] // 4/2:te2[s0>>8] + (p0) shladd te21=te21,3,te2 // 4/3:te3+s2 + (p0) extr.u te13=s3,16,8 } // 4/0:s1>>16&0xff +{ .mmi; (p0) ld4 te00=[te00] // 4/0:te0[s0>>24] + (p0) shladd te01=te01,3,te0 // 4/1:te0+s1>>24 + (p0) shr.u te11=s1,sixteen };; // 4/2:s3>>16 +{ .mmi; (p0) ld4 te21=[te21] // 5/3:te2[s1>>8] + (p0) shladd te13=te13,3,te1 // 5/0:te1+s1>>16 + (p0) extr.u te10=s0,16,8 } // 5/1:s2>>16&0xff +{ .mmi; (p0) ld4 te01=[te01] // 5/1:te0[s1>>24] + (p0) shladd te02=te02,3,te0 // 5/2:te0+s2>>24 + (p0) and te33=s3,maskff };; // 5/2:s1&0xff +{ .mmi; (p0) ld4 te13=[te13] // 6/0:te1[s1>>16] + (p0) shladd te10=te10,3,te1 // 6/1:te1+s2>>16 + (p0) extr.u te12=s2,16,8 } // 6/3:s0>>16&0xff +{ .mmi; (p0) ld4 te02=[te02] // 6/2:te0[s2>>24] + (p0) shladd te03=te03,3,te0 // 6/3:te1+s0>>16 + (p0) and te30=s0,maskff };; // 6/3:s2&0xff + +{ .mmi; (p0) ld4 te10=[te10] // 7/1:te1[s2>>16] + (p0) shladd te33=te33,3,te3 // 7/2:te3+s1&0xff + (p0) and te11=te11,maskff} // 7/2:s3>>16&0xff +{ .mmi; (p0) ld4 te03=[te03] // 7/3:te0[s3>>24] + (p0) shladd te30=te30,3,te3 // 7/3:te3+s2 + (p0) xor t0=t0,te31 };; // 7/0: +{ .mmi; (p0) ld4 te33=[te33] // 8/2:te3[s1] + (p0) shladd te11=te11,3,te1 // 8/2:te1+s3>>16 + (p0) xor t0=t0,te22 } // 8/0: +{ .mmi; (p0) ld4 te30=[te30] // 8/3:te3[s2] + (p0) shladd te12=te12,3,te1 // 8/3:te1+s0>>16 + (p0) xor t1=t1,te32 };; // 8/1: +{ .mmi; (p0) ld4 te11=[te11] // 9/2:te1[s3>>16] + (p0) ld4 te12=[te12] // 9/3:te1[s0>>16] + (p0) xor t0=t0,te00 };; // 9/0: !L2 scheduling +{ .mmi; (p0) xor t1=t1,te23 // 10[9]/1: + (p0) xor t2=t2,te20 // 10[9]/2: + (p0) xor t3=t3,te21 };; // 10[9]/3: +{ .mmi; (p0) xor t0=t0,te13 // 11[10]/0:done! + (p0) xor t1=t1,te01 // 11[10]/1: + (p0) xor t2=t2,te02 };; // 11[10]/2: !L2 scheduling +{ .mmi; (p0) xor t3=t3,te03 // 12[10]/3: + (p16) cmp.eq p0,p17=r0,r0 };; // 12[10]/clear (p17) +{ .mmi; (p0) xor t1=t1,te10 // 13[11]/1:done! + (p0) xor t2=t2,te33 // 13[11]/2: + (p0) xor t3=t3,te30 } // 13[11]/3: +{ .mmi; (p17) add te0=2048,te0 // 13[11]/ + (p17) add te1=2048+64-TE1,te1};; // 13[11]/ +{ .mib; (p0) xor t2=t2,te11 // 14[12]/2:done! + (p17) add te2=2048+128-TE2,te2} // 14[12]/ +{ .mib; (p0) xor t3=t3,te12 // 14[12]/3:done! + (p17) add te3=2048+192-TE3,te3 // 14[12]/ + br.ctop.sptk .Ld_top };; +.Ld_end: + + +{ .mmi; ld8 te10=[te0] // prefetch Td4 + ld8 te33=[te1] } +{ .mmi; ld8 te12=[te2] + ld8 te30=[te3] } + +{ .mmi; LDKEY t0=[rk0],2*KSZ // 0/0:rk[0] + and te31=s1,maskff // 0/0:s3&0xff + extr.u te22=s2,8,8 } // 0/0:s2>>8&0xff +{ .mmi; LDKEY t1=[rk1],2*KSZ // 0/1:rk[1] + and te32=s2,maskff // 0/1:s0&0xff + shr.u te00=s0,twenty4 };; // 0/0:s0>>24 +{ .mmi; LDKEY t2=[rk0],2*KSZ // 1/2:rk[2] + add te31=te31,te0 // 1/0:te0+s0>>24 + extr.u te23=s3,8,8 } // 1/1:s3>>8&0xff +{ .mmi; LDKEY t3=[rk1],2*KSZ // 1/3:rk[3] + add te32=te32,te0 // 1/1:te0+s0 + shr.u te01=s1,twenty4 };; // 1/1:s1>>24 +{ .mmi; ld1 te31=[te31] // 2/0:te0[s3&0xff] + add te22=te22,te0 // 2/0:te0+s2>>8&0xff + extr.u te20=s0,8,8 } // 2/2:s0>>8&0xff +{ .mmi; ld1 te32=[te32] // 2/1:te0[s0] + add te23=te23,te0 // 2/1:te0+s3>>8 + shr.u te02=s2,twenty4 };; // 2/2:s2>>24 +{ .mmi; ld1 te22=[te22] // 3/0:te0[s2>>8] + add te20=te20,te0 // 3/2:te0+s0>>8 + extr.u te21=s1,8,8 } // 3/3:s1>>8&0xff +{ .mmi; ld1 te23=[te23] // 3/1:te0[s3>>8] + add te00=te00,te0 // 3/0:te0+s0>>24 + shr.u te03=s3,twenty4 };; // 3/3:s3>>24 +{ .mmi; ld1 te20=[te20] // 4/2:te0[s0>>8] + add te21=te21,te0 // 4/3:te0+s2 + extr.u te13=s3,16,8 } // 4/0:s1>>16&0xff +{ .mmi; ld1 te00=[te00] // 4/0:te0[s0>>24] + add te01=te01,te0 // 4/1:te0+s1>>24 + shr.u te11=s1,sixteen };; // 4/2:s3>>16 +{ .mmi; ld1 te21=[te21] // 5/3:te0[s1>>8] + add te13=te13,te0 // 5/0:te0+s1>>16 + extr.u te10=s0,16,8 } // 5/1:s2>>16&0xff +{ .mmi; ld1 te01=[te01] // 5/1:te0[s1>>24] + add te02=te02,te0 // 5/2:te0+s2>>24 + and te33=s3,maskff };; // 5/2:s1&0xff +{ .mmi; ld1 te13=[te13] // 6/0:te0[s1>>16] + add te10=te10,te0 // 6/1:te0+s2>>16 + extr.u te12=s2,16,8 } // 6/3:s0>>16&0xff +{ .mmi; ld1 te02=[te02] // 6/2:te0[s2>>24] + add te03=te03,te0 // 6/3:te0+s0>>16 + and te30=s0,maskff };; // 6/3:s2&0xff + +{ .mmi; ld1 te10=[te10] // 7/1:te0[s2>>16] + add te33=te33,te0 // 7/2:te0+s1&0xff + dep te31=te22,te31,8,8} // 7/0: +{ .mmi; ld1 te03=[te03] // 7/3:te0[s3>>24] + add te30=te30,te0 // 7/3:te0+s2 + and te11=te11,maskff};; // 7/2:s3>>16&0xff +{ .mmi; ld1 te33=[te33] // 8/2:te0[s1] + add te11=te11,te0 // 8/2:te0+s3>>16 + dep te32=te23,te32,8,8} // 8/1: +{ .mmi; ld1 te30=[te30] // 8/3:te0[s2] + add te12=te12,te0 // 8/3:te0+s0>>16 + shl te00=te00,twenty4};; // 8/0: +{ .mii; ld1 te11=[te11] // 9/2:te0[s3>>16] + dep te31=te13,te31,16,8 // 9/0: + shl te01=te01,twenty4};; // 9/1: +{ .mii; ld1 te12=[te12] // 10/3:te0[s0>>16] + dep te33=te20,te33,8,8 // 10/2: + shl te02=te02,twenty4};; // 10/2: +{ .mii; xor t0=t0,te31 // 11/0: + dep te30=te21,te30,8,8 // 11/3: + shl te10=te10,sixteen};; // 11/1: +{ .mii; xor r16=t0,te00 // 12/0:done! + dep te33=te11,te33,16,8 // 12/2: + shl te03=te03,twenty4};; // 12/3: +{ .mmi; xor t1=t1,te01 // 13/1: + xor t2=t2,te02 // 13/2: + dep te30=te12,te30,16,8};; // 13/3: +{ .mmi; xor t1=t1,te32 // 14/1: + xor r24=t2,te33 // 14/2:done! + xor t3=t3,te30 };; // 14/3: +{ .mib; xor r20=t1,te10 // 15/1:done! + xor r28=t3,te03 // 15/3:done! + br.ret.sptk b6 };; +.endp _ia64_AES_decrypt# + +// void AES_decrypt (const void *in,void *out,const AES_KEY *key); +.global AES_decrypt# +.proc AES_decrypt# +.align 32 +AES_decrypt: + .prologue + .save ar.pfs,pfssave +{ .mmi; alloc pfssave=ar.pfs,3,1,12,0 + and out0=3,in0 + mov r3=ip } +{ .mmi; ADDP in0=0,in0 + mov loc0=psr.um + ADDP out11=KSZ*60,in2 };; // &AES_KEY->rounds + +{ .mmi; ld4 out11=[out11] // AES_KEY->rounds + add out8=(AES_Td#-AES_decrypt#),r3 // Te0 + .save pr,prsave + mov prsave=pr } +{ .mmi; rum 1<<3 // clear um.ac + .save ar.lc,lcsave + mov lcsave=ar.lc };; + + .body +#if defined(_HPUX_SOURCE) // HPUX is big-endian, cut 15+15 cycles... +{ .mib; cmp.ne p6,p0=out0,r0 + add out0=4,in0 +(p6) br.dpnt.many .Ld_i_unaligned };; + +{ .mmi; ld4 out1=[in0],8 // s0 + and out9=3,in1 + mov twenty4=24 } +{ .mmi; ld4 out3=[out0],8 // s1 + ADDP rk0=0,in2 + mov sixteen=16 };; +{ .mmi; ld4 out5=[in0] // s2 + cmp.ne p6,p0=out9,r0 + mov maskff=0xff } +{ .mmb; ld4 out7=[out0] // s3 + ADDP rk1=KSZ,in2 + br.call.sptk.many b6=_ia64_AES_decrypt };; + +{ .mib; ADDP in0=4,in1 + ADDP in1=0,in1 +(p6) br.spnt .Ld_o_unaligned };; + +{ .mii; mov psr.um=loc0 + mov ar.pfs=pfssave + mov ar.lc=lcsave };; +{ .mmi; st4 [in1]=r16,8 // s0 + st4 [in0]=r20,8 // s1 + mov pr=prsave,0x1ffff };; +{ .mmb; st4 [in1]=r24 // s2 + st4 [in0]=r28 // s3 + br.ret.sptk.many b0 };; +#endif + +.align 32 +.Ld_i_unaligned: +{ .mmi; add out0=1,in0 + add out2=2,in0 + add out4=3,in0 };; +{ .mmi; ld1 r16=[in0],4 + ld1 r17=[out0],4 }//;; +{ .mmi; ld1 r18=[out2],4 + ld1 out1=[out4],4 };; // s0 +{ .mmi; ld1 r20=[in0],4 + ld1 r21=[out0],4 }//;; +{ .mmi; ld1 r22=[out2],4 + ld1 out3=[out4],4 };; // s1 +{ .mmi; ld1 r24=[in0],4 + ld1 r25=[out0],4 }//;; +{ .mmi; ld1 r26=[out2],4 + ld1 out5=[out4],4 };; // s2 +{ .mmi; ld1 r28=[in0] + ld1 r29=[out0] }//;; +{ .mmi; ld1 r30=[out2] + ld1 out7=[out4] };; // s3 + +{ .mii; + dep out1=r16,out1,24,8 //;; + dep out3=r20,out3,24,8 }//;; +{ .mii; ADDP rk0=0,in2 + dep out5=r24,out5,24,8 //;; + dep out7=r28,out7,24,8 };; +{ .mii; ADDP rk1=KSZ,in2 + dep out1=r17,out1,16,8 //;; + dep out3=r21,out3,16,8 }//;; +{ .mii; mov twenty4=24 + dep out5=r25,out5,16,8 //;; + dep out7=r29,out7,16,8 };; +{ .mii; mov sixteen=16 + dep out1=r18,out1,8,8 //;; + dep out3=r22,out3,8,8 }//;; +{ .mii; mov maskff=0xff + dep out5=r26,out5,8,8 //;; + dep out7=r30,out7,8,8 };; + +{ .mib; br.call.sptk.many b6=_ia64_AES_decrypt };; + +.Ld_o_unaligned: +{ .mii; ADDP out0=0,in1 + extr.u r17=r16,8,8 // s0 + shr.u r19=r16,twenty4 }//;; +{ .mii; ADDP out1=1,in1 + extr.u r18=r16,16,8 + shr.u r23=r20,twenty4 }//;; // s1 +{ .mii; ADDP out2=2,in1 + extr.u r21=r20,8,8 + shr.u r22=r20,sixteen }//;; +{ .mii; ADDP out3=3,in1 + extr.u r25=r24,8,8 // s2 + shr.u r27=r24,twenty4 };; +{ .mii; st1 [out3]=r16,4 + extr.u r26=r24,16,8 + shr.u r31=r28,twenty4 }//;; // s3 +{ .mii; st1 [out2]=r17,4 + extr.u r29=r28,8,8 + shr.u r30=r28,sixteen }//;; + +{ .mmi; st1 [out1]=r18,4 + st1 [out0]=r19,4 };; +{ .mmi; st1 [out3]=r20,4 + st1 [out2]=r21,4 }//;; +{ .mmi; st1 [out1]=r22,4 + st1 [out0]=r23,4 };; +{ .mmi; st1 [out3]=r24,4 + st1 [out2]=r25,4 + mov pr=prsave,0x1ffff }//;; +{ .mmi; st1 [out1]=r26,4 + st1 [out0]=r27,4 + mov ar.pfs=pfssave };; +{ .mmi; st1 [out3]=r28 + st1 [out2]=r29 + mov ar.lc=lcsave }//;; +{ .mmi; st1 [out1]=r30 + st1 [out0]=r31 } +{ .mfb; mov psr.um=loc0 // restore user mask + br.ret.sptk.many b0 };; +.endp AES_decrypt# + +// leave it in .text segment... +.align 64 +.global AES_Te# +.type AES_Te#,@object +AES_Te: data4 0xc66363a5,0xc66363a5, 0xf87c7c84,0xf87c7c84 + data4 0xee777799,0xee777799, 0xf67b7b8d,0xf67b7b8d + data4 0xfff2f20d,0xfff2f20d, 0xd66b6bbd,0xd66b6bbd + data4 0xde6f6fb1,0xde6f6fb1, 0x91c5c554,0x91c5c554 + data4 0x60303050,0x60303050, 0x02010103,0x02010103 + data4 0xce6767a9,0xce6767a9, 0x562b2b7d,0x562b2b7d + data4 0xe7fefe19,0xe7fefe19, 0xb5d7d762,0xb5d7d762 + data4 0x4dababe6,0x4dababe6, 0xec76769a,0xec76769a + data4 0x8fcaca45,0x8fcaca45, 0x1f82829d,0x1f82829d + data4 0x89c9c940,0x89c9c940, 0xfa7d7d87,0xfa7d7d87 + data4 0xeffafa15,0xeffafa15, 0xb25959eb,0xb25959eb + data4 0x8e4747c9,0x8e4747c9, 0xfbf0f00b,0xfbf0f00b + data4 0x41adadec,0x41adadec, 0xb3d4d467,0xb3d4d467 + data4 0x5fa2a2fd,0x5fa2a2fd, 0x45afafea,0x45afafea + data4 0x239c9cbf,0x239c9cbf, 0x53a4a4f7,0x53a4a4f7 + data4 0xe4727296,0xe4727296, 0x9bc0c05b,0x9bc0c05b + data4 0x75b7b7c2,0x75b7b7c2, 0xe1fdfd1c,0xe1fdfd1c + data4 0x3d9393ae,0x3d9393ae, 0x4c26266a,0x4c26266a + data4 0x6c36365a,0x6c36365a, 0x7e3f3f41,0x7e3f3f41 + data4 0xf5f7f702,0xf5f7f702, 0x83cccc4f,0x83cccc4f + data4 0x6834345c,0x6834345c, 0x51a5a5f4,0x51a5a5f4 + data4 0xd1e5e534,0xd1e5e534, 0xf9f1f108,0xf9f1f108 + data4 0xe2717193,0xe2717193, 0xabd8d873,0xabd8d873 + data4 0x62313153,0x62313153, 0x2a15153f,0x2a15153f + data4 0x0804040c,0x0804040c, 0x95c7c752,0x95c7c752 + data4 0x46232365,0x46232365, 0x9dc3c35e,0x9dc3c35e + data4 0x30181828,0x30181828, 0x379696a1,0x379696a1 + data4 0x0a05050f,0x0a05050f, 0x2f9a9ab5,0x2f9a9ab5 + data4 0x0e070709,0x0e070709, 0x24121236,0x24121236 + data4 0x1b80809b,0x1b80809b, 0xdfe2e23d,0xdfe2e23d + data4 0xcdebeb26,0xcdebeb26, 0x4e272769,0x4e272769 + data4 0x7fb2b2cd,0x7fb2b2cd, 0xea75759f,0xea75759f + data4 0x1209091b,0x1209091b, 0x1d83839e,0x1d83839e + data4 0x582c2c74,0x582c2c74, 0x341a1a2e,0x341a1a2e + data4 0x361b1b2d,0x361b1b2d, 0xdc6e6eb2,0xdc6e6eb2 + data4 0xb45a5aee,0xb45a5aee, 0x5ba0a0fb,0x5ba0a0fb + data4 0xa45252f6,0xa45252f6, 0x763b3b4d,0x763b3b4d + data4 0xb7d6d661,0xb7d6d661, 0x7db3b3ce,0x7db3b3ce + data4 0x5229297b,0x5229297b, 0xdde3e33e,0xdde3e33e + data4 0x5e2f2f71,0x5e2f2f71, 0x13848497,0x13848497 + data4 0xa65353f5,0xa65353f5, 0xb9d1d168,0xb9d1d168 + data4 0x00000000,0x00000000, 0xc1eded2c,0xc1eded2c + data4 0x40202060,0x40202060, 0xe3fcfc1f,0xe3fcfc1f + data4 0x79b1b1c8,0x79b1b1c8, 0xb65b5bed,0xb65b5bed + data4 0xd46a6abe,0xd46a6abe, 0x8dcbcb46,0x8dcbcb46 + data4 0x67bebed9,0x67bebed9, 0x7239394b,0x7239394b + data4 0x944a4ade,0x944a4ade, 0x984c4cd4,0x984c4cd4 + data4 0xb05858e8,0xb05858e8, 0x85cfcf4a,0x85cfcf4a + data4 0xbbd0d06b,0xbbd0d06b, 0xc5efef2a,0xc5efef2a + data4 0x4faaaae5,0x4faaaae5, 0xedfbfb16,0xedfbfb16 + data4 0x864343c5,0x864343c5, 0x9a4d4dd7,0x9a4d4dd7 + data4 0x66333355,0x66333355, 0x11858594,0x11858594 + data4 0x8a4545cf,0x8a4545cf, 0xe9f9f910,0xe9f9f910 + data4 0x04020206,0x04020206, 0xfe7f7f81,0xfe7f7f81 + data4 0xa05050f0,0xa05050f0, 0x783c3c44,0x783c3c44 + data4 0x259f9fba,0x259f9fba, 0x4ba8a8e3,0x4ba8a8e3 + data4 0xa25151f3,0xa25151f3, 0x5da3a3fe,0x5da3a3fe + data4 0x804040c0,0x804040c0, 0x058f8f8a,0x058f8f8a + data4 0x3f9292ad,0x3f9292ad, 0x219d9dbc,0x219d9dbc + data4 0x70383848,0x70383848, 0xf1f5f504,0xf1f5f504 + data4 0x63bcbcdf,0x63bcbcdf, 0x77b6b6c1,0x77b6b6c1 + data4 0xafdada75,0xafdada75, 0x42212163,0x42212163 + data4 0x20101030,0x20101030, 0xe5ffff1a,0xe5ffff1a + data4 0xfdf3f30e,0xfdf3f30e, 0xbfd2d26d,0xbfd2d26d + data4 0x81cdcd4c,0x81cdcd4c, 0x180c0c14,0x180c0c14 + data4 0x26131335,0x26131335, 0xc3ecec2f,0xc3ecec2f + data4 0xbe5f5fe1,0xbe5f5fe1, 0x359797a2,0x359797a2 + data4 0x884444cc,0x884444cc, 0x2e171739,0x2e171739 + data4 0x93c4c457,0x93c4c457, 0x55a7a7f2,0x55a7a7f2 + data4 0xfc7e7e82,0xfc7e7e82, 0x7a3d3d47,0x7a3d3d47 + data4 0xc86464ac,0xc86464ac, 0xba5d5de7,0xba5d5de7 + data4 0x3219192b,0x3219192b, 0xe6737395,0xe6737395 + data4 0xc06060a0,0xc06060a0, 0x19818198,0x19818198 + data4 0x9e4f4fd1,0x9e4f4fd1, 0xa3dcdc7f,0xa3dcdc7f + data4 0x44222266,0x44222266, 0x542a2a7e,0x542a2a7e + data4 0x3b9090ab,0x3b9090ab, 0x0b888883,0x0b888883 + data4 0x8c4646ca,0x8c4646ca, 0xc7eeee29,0xc7eeee29 + data4 0x6bb8b8d3,0x6bb8b8d3, 0x2814143c,0x2814143c + data4 0xa7dede79,0xa7dede79, 0xbc5e5ee2,0xbc5e5ee2 + data4 0x160b0b1d,0x160b0b1d, 0xaddbdb76,0xaddbdb76 + data4 0xdbe0e03b,0xdbe0e03b, 0x64323256,0x64323256 + data4 0x743a3a4e,0x743a3a4e, 0x140a0a1e,0x140a0a1e + data4 0x924949db,0x924949db, 0x0c06060a,0x0c06060a + data4 0x4824246c,0x4824246c, 0xb85c5ce4,0xb85c5ce4 + data4 0x9fc2c25d,0x9fc2c25d, 0xbdd3d36e,0xbdd3d36e + data4 0x43acacef,0x43acacef, 0xc46262a6,0xc46262a6 + data4 0x399191a8,0x399191a8, 0x319595a4,0x319595a4 + data4 0xd3e4e437,0xd3e4e437, 0xf279798b,0xf279798b + data4 0xd5e7e732,0xd5e7e732, 0x8bc8c843,0x8bc8c843 + data4 0x6e373759,0x6e373759, 0xda6d6db7,0xda6d6db7 + data4 0x018d8d8c,0x018d8d8c, 0xb1d5d564,0xb1d5d564 + data4 0x9c4e4ed2,0x9c4e4ed2, 0x49a9a9e0,0x49a9a9e0 + data4 0xd86c6cb4,0xd86c6cb4, 0xac5656fa,0xac5656fa + data4 0xf3f4f407,0xf3f4f407, 0xcfeaea25,0xcfeaea25 + data4 0xca6565af,0xca6565af, 0xf47a7a8e,0xf47a7a8e + data4 0x47aeaee9,0x47aeaee9, 0x10080818,0x10080818 + data4 0x6fbabad5,0x6fbabad5, 0xf0787888,0xf0787888 + data4 0x4a25256f,0x4a25256f, 0x5c2e2e72,0x5c2e2e72 + data4 0x381c1c24,0x381c1c24, 0x57a6a6f1,0x57a6a6f1 + data4 0x73b4b4c7,0x73b4b4c7, 0x97c6c651,0x97c6c651 + data4 0xcbe8e823,0xcbe8e823, 0xa1dddd7c,0xa1dddd7c + data4 0xe874749c,0xe874749c, 0x3e1f1f21,0x3e1f1f21 + data4 0x964b4bdd,0x964b4bdd, 0x61bdbddc,0x61bdbddc + data4 0x0d8b8b86,0x0d8b8b86, 0x0f8a8a85,0x0f8a8a85 + data4 0xe0707090,0xe0707090, 0x7c3e3e42,0x7c3e3e42 + data4 0x71b5b5c4,0x71b5b5c4, 0xcc6666aa,0xcc6666aa + data4 0x904848d8,0x904848d8, 0x06030305,0x06030305 + data4 0xf7f6f601,0xf7f6f601, 0x1c0e0e12,0x1c0e0e12 + data4 0xc26161a3,0xc26161a3, 0x6a35355f,0x6a35355f + data4 0xae5757f9,0xae5757f9, 0x69b9b9d0,0x69b9b9d0 + data4 0x17868691,0x17868691, 0x99c1c158,0x99c1c158 + data4 0x3a1d1d27,0x3a1d1d27, 0x279e9eb9,0x279e9eb9 + data4 0xd9e1e138,0xd9e1e138, 0xebf8f813,0xebf8f813 + data4 0x2b9898b3,0x2b9898b3, 0x22111133,0x22111133 + data4 0xd26969bb,0xd26969bb, 0xa9d9d970,0xa9d9d970 + data4 0x078e8e89,0x078e8e89, 0x339494a7,0x339494a7 + data4 0x2d9b9bb6,0x2d9b9bb6, 0x3c1e1e22,0x3c1e1e22 + data4 0x15878792,0x15878792, 0xc9e9e920,0xc9e9e920 + data4 0x87cece49,0x87cece49, 0xaa5555ff,0xaa5555ff + data4 0x50282878,0x50282878, 0xa5dfdf7a,0xa5dfdf7a + data4 0x038c8c8f,0x038c8c8f, 0x59a1a1f8,0x59a1a1f8 + data4 0x09898980,0x09898980, 0x1a0d0d17,0x1a0d0d17 + data4 0x65bfbfda,0x65bfbfda, 0xd7e6e631,0xd7e6e631 + data4 0x844242c6,0x844242c6, 0xd06868b8,0xd06868b8 + data4 0x824141c3,0x824141c3, 0x299999b0,0x299999b0 + data4 0x5a2d2d77,0x5a2d2d77, 0x1e0f0f11,0x1e0f0f11 + data4 0x7bb0b0cb,0x7bb0b0cb, 0xa85454fc,0xa85454fc + data4 0x6dbbbbd6,0x6dbbbbd6, 0x2c16163a,0x2c16163a +// Te4: + data1 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5 + data1 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 + data1 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0 + data1 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 + data1 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc + data1 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 + data1 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a + data1 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 + data1 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0 + data1 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 + data1 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b + data1 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf + data1 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85 + data1 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 + data1 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5 + data1 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 + data1 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17 + data1 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 + data1 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88 + data1 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb + data1 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c + data1 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 + data1 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9 + data1 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 + data1 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6 + data1 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a + data1 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e + data1 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e + data1 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94 + data1 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf + data1 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68 + data1 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +.size AES_Te#,2048+256 // HP-UX assembler fails to ".-AES_Te#" + +.align 64 +.global AES_Td# +.type AES_Td#,@object +AES_Td: data4 0x51f4a750,0x51f4a750, 0x7e416553,0x7e416553 + data4 0x1a17a4c3,0x1a17a4c3, 0x3a275e96,0x3a275e96 + data4 0x3bab6bcb,0x3bab6bcb, 0x1f9d45f1,0x1f9d45f1 + data4 0xacfa58ab,0xacfa58ab, 0x4be30393,0x4be30393 + data4 0x2030fa55,0x2030fa55, 0xad766df6,0xad766df6 + data4 0x88cc7691,0x88cc7691, 0xf5024c25,0xf5024c25 + data4 0x4fe5d7fc,0x4fe5d7fc, 0xc52acbd7,0xc52acbd7 + data4 0x26354480,0x26354480, 0xb562a38f,0xb562a38f + data4 0xdeb15a49,0xdeb15a49, 0x25ba1b67,0x25ba1b67 + data4 0x45ea0e98,0x45ea0e98, 0x5dfec0e1,0x5dfec0e1 + data4 0xc32f7502,0xc32f7502, 0x814cf012,0x814cf012 + data4 0x8d4697a3,0x8d4697a3, 0x6bd3f9c6,0x6bd3f9c6 + data4 0x038f5fe7,0x038f5fe7, 0x15929c95,0x15929c95 + data4 0xbf6d7aeb,0xbf6d7aeb, 0x955259da,0x955259da + data4 0xd4be832d,0xd4be832d, 0x587421d3,0x587421d3 + data4 0x49e06929,0x49e06929, 0x8ec9c844,0x8ec9c844 + data4 0x75c2896a,0x75c2896a, 0xf48e7978,0xf48e7978 + data4 0x99583e6b,0x99583e6b, 0x27b971dd,0x27b971dd + data4 0xbee14fb6,0xbee14fb6, 0xf088ad17,0xf088ad17 + data4 0xc920ac66,0xc920ac66, 0x7dce3ab4,0x7dce3ab4 + data4 0x63df4a18,0x63df4a18, 0xe51a3182,0xe51a3182 + data4 0x97513360,0x97513360, 0x62537f45,0x62537f45 + data4 0xb16477e0,0xb16477e0, 0xbb6bae84,0xbb6bae84 + data4 0xfe81a01c,0xfe81a01c, 0xf9082b94,0xf9082b94 + data4 0x70486858,0x70486858, 0x8f45fd19,0x8f45fd19 + data4 0x94de6c87,0x94de6c87, 0x527bf8b7,0x527bf8b7 + data4 0xab73d323,0xab73d323, 0x724b02e2,0x724b02e2 + data4 0xe31f8f57,0xe31f8f57, 0x6655ab2a,0x6655ab2a + data4 0xb2eb2807,0xb2eb2807, 0x2fb5c203,0x2fb5c203 + data4 0x86c57b9a,0x86c57b9a, 0xd33708a5,0xd33708a5 + data4 0x302887f2,0x302887f2, 0x23bfa5b2,0x23bfa5b2 + data4 0x02036aba,0x02036aba, 0xed16825c,0xed16825c + data4 0x8acf1c2b,0x8acf1c2b, 0xa779b492,0xa779b492 + data4 0xf307f2f0,0xf307f2f0, 0x4e69e2a1,0x4e69e2a1 + data4 0x65daf4cd,0x65daf4cd, 0x0605bed5,0x0605bed5 + data4 0xd134621f,0xd134621f, 0xc4a6fe8a,0xc4a6fe8a + data4 0x342e539d,0x342e539d, 0xa2f355a0,0xa2f355a0 + data4 0x058ae132,0x058ae132, 0xa4f6eb75,0xa4f6eb75 + data4 0x0b83ec39,0x0b83ec39, 0x4060efaa,0x4060efaa + data4 0x5e719f06,0x5e719f06, 0xbd6e1051,0xbd6e1051 + data4 0x3e218af9,0x3e218af9, 0x96dd063d,0x96dd063d + data4 0xdd3e05ae,0xdd3e05ae, 0x4de6bd46,0x4de6bd46 + data4 0x91548db5,0x91548db5, 0x71c45d05,0x71c45d05 + data4 0x0406d46f,0x0406d46f, 0x605015ff,0x605015ff + data4 0x1998fb24,0x1998fb24, 0xd6bde997,0xd6bde997 + data4 0x894043cc,0x894043cc, 0x67d99e77,0x67d99e77 + data4 0xb0e842bd,0xb0e842bd, 0x07898b88,0x07898b88 + data4 0xe7195b38,0xe7195b38, 0x79c8eedb,0x79c8eedb + data4 0xa17c0a47,0xa17c0a47, 0x7c420fe9,0x7c420fe9 + data4 0xf8841ec9,0xf8841ec9, 0x00000000,0x00000000 + data4 0x09808683,0x09808683, 0x322bed48,0x322bed48 + data4 0x1e1170ac,0x1e1170ac, 0x6c5a724e,0x6c5a724e + data4 0xfd0efffb,0xfd0efffb, 0x0f853856,0x0f853856 + data4 0x3daed51e,0x3daed51e, 0x362d3927,0x362d3927 + data4 0x0a0fd964,0x0a0fd964, 0x685ca621,0x685ca621 + data4 0x9b5b54d1,0x9b5b54d1, 0x24362e3a,0x24362e3a + data4 0x0c0a67b1,0x0c0a67b1, 0x9357e70f,0x9357e70f + data4 0xb4ee96d2,0xb4ee96d2, 0x1b9b919e,0x1b9b919e + data4 0x80c0c54f,0x80c0c54f, 0x61dc20a2,0x61dc20a2 + data4 0x5a774b69,0x5a774b69, 0x1c121a16,0x1c121a16 + data4 0xe293ba0a,0xe293ba0a, 0xc0a02ae5,0xc0a02ae5 + data4 0x3c22e043,0x3c22e043, 0x121b171d,0x121b171d + data4 0x0e090d0b,0x0e090d0b, 0xf28bc7ad,0xf28bc7ad + data4 0x2db6a8b9,0x2db6a8b9, 0x141ea9c8,0x141ea9c8 + data4 0x57f11985,0x57f11985, 0xaf75074c,0xaf75074c + data4 0xee99ddbb,0xee99ddbb, 0xa37f60fd,0xa37f60fd + data4 0xf701269f,0xf701269f, 0x5c72f5bc,0x5c72f5bc + data4 0x44663bc5,0x44663bc5, 0x5bfb7e34,0x5bfb7e34 + data4 0x8b432976,0x8b432976, 0xcb23c6dc,0xcb23c6dc + data4 0xb6edfc68,0xb6edfc68, 0xb8e4f163,0xb8e4f163 + data4 0xd731dcca,0xd731dcca, 0x42638510,0x42638510 + data4 0x13972240,0x13972240, 0x84c61120,0x84c61120 + data4 0x854a247d,0x854a247d, 0xd2bb3df8,0xd2bb3df8 + data4 0xaef93211,0xaef93211, 0xc729a16d,0xc729a16d + data4 0x1d9e2f4b,0x1d9e2f4b, 0xdcb230f3,0xdcb230f3 + data4 0x0d8652ec,0x0d8652ec, 0x77c1e3d0,0x77c1e3d0 + data4 0x2bb3166c,0x2bb3166c, 0xa970b999,0xa970b999 + data4 0x119448fa,0x119448fa, 0x47e96422,0x47e96422 + data4 0xa8fc8cc4,0xa8fc8cc4, 0xa0f03f1a,0xa0f03f1a + data4 0x567d2cd8,0x567d2cd8, 0x223390ef,0x223390ef + data4 0x87494ec7,0x87494ec7, 0xd938d1c1,0xd938d1c1 + data4 0x8ccaa2fe,0x8ccaa2fe, 0x98d40b36,0x98d40b36 + data4 0xa6f581cf,0xa6f581cf, 0xa57ade28,0xa57ade28 + data4 0xdab78e26,0xdab78e26, 0x3fadbfa4,0x3fadbfa4 + data4 0x2c3a9de4,0x2c3a9de4, 0x5078920d,0x5078920d + data4 0x6a5fcc9b,0x6a5fcc9b, 0x547e4662,0x547e4662 + data4 0xf68d13c2,0xf68d13c2, 0x90d8b8e8,0x90d8b8e8 + data4 0x2e39f75e,0x2e39f75e, 0x82c3aff5,0x82c3aff5 + data4 0x9f5d80be,0x9f5d80be, 0x69d0937c,0x69d0937c + data4 0x6fd52da9,0x6fd52da9, 0xcf2512b3,0xcf2512b3 + data4 0xc8ac993b,0xc8ac993b, 0x10187da7,0x10187da7 + data4 0xe89c636e,0xe89c636e, 0xdb3bbb7b,0xdb3bbb7b + data4 0xcd267809,0xcd267809, 0x6e5918f4,0x6e5918f4 + data4 0xec9ab701,0xec9ab701, 0x834f9aa8,0x834f9aa8 + data4 0xe6956e65,0xe6956e65, 0xaaffe67e,0xaaffe67e + data4 0x21bccf08,0x21bccf08, 0xef15e8e6,0xef15e8e6 + data4 0xbae79bd9,0xbae79bd9, 0x4a6f36ce,0x4a6f36ce + data4 0xea9f09d4,0xea9f09d4, 0x29b07cd6,0x29b07cd6 + data4 0x31a4b2af,0x31a4b2af, 0x2a3f2331,0x2a3f2331 + data4 0xc6a59430,0xc6a59430, 0x35a266c0,0x35a266c0 + data4 0x744ebc37,0x744ebc37, 0xfc82caa6,0xfc82caa6 + data4 0xe090d0b0,0xe090d0b0, 0x33a7d815,0x33a7d815 + data4 0xf104984a,0xf104984a, 0x41ecdaf7,0x41ecdaf7 + data4 0x7fcd500e,0x7fcd500e, 0x1791f62f,0x1791f62f + data4 0x764dd68d,0x764dd68d, 0x43efb04d,0x43efb04d + data4 0xccaa4d54,0xccaa4d54, 0xe49604df,0xe49604df + data4 0x9ed1b5e3,0x9ed1b5e3, 0x4c6a881b,0x4c6a881b + data4 0xc12c1fb8,0xc12c1fb8, 0x4665517f,0x4665517f + data4 0x9d5eea04,0x9d5eea04, 0x018c355d,0x018c355d + data4 0xfa877473,0xfa877473, 0xfb0b412e,0xfb0b412e + data4 0xb3671d5a,0xb3671d5a, 0x92dbd252,0x92dbd252 + data4 0xe9105633,0xe9105633, 0x6dd64713,0x6dd64713 + data4 0x9ad7618c,0x9ad7618c, 0x37a10c7a,0x37a10c7a + data4 0x59f8148e,0x59f8148e, 0xeb133c89,0xeb133c89 + data4 0xcea927ee,0xcea927ee, 0xb761c935,0xb761c935 + data4 0xe11ce5ed,0xe11ce5ed, 0x7a47b13c,0x7a47b13c + data4 0x9cd2df59,0x9cd2df59, 0x55f2733f,0x55f2733f + data4 0x1814ce79,0x1814ce79, 0x73c737bf,0x73c737bf + data4 0x53f7cdea,0x53f7cdea, 0x5ffdaa5b,0x5ffdaa5b + data4 0xdf3d6f14,0xdf3d6f14, 0x7844db86,0x7844db86 + data4 0xcaaff381,0xcaaff381, 0xb968c43e,0xb968c43e + data4 0x3824342c,0x3824342c, 0xc2a3405f,0xc2a3405f + data4 0x161dc372,0x161dc372, 0xbce2250c,0xbce2250c + data4 0x283c498b,0x283c498b, 0xff0d9541,0xff0d9541 + data4 0x39a80171,0x39a80171, 0x080cb3de,0x080cb3de + data4 0xd8b4e49c,0xd8b4e49c, 0x6456c190,0x6456c190 + data4 0x7bcb8461,0x7bcb8461, 0xd532b670,0xd532b670 + data4 0x486c5c74,0x486c5c74, 0xd0b85742,0xd0b85742 +// Td4: + data1 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38 + data1 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb + data1 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87 + data1 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb + data1 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d + data1 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e + data1 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2 + data1 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 + data1 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16 + data1 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 + data1 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda + data1 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 + data1 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a + data1 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 + data1 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02 + data1 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b + data1 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea + data1 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 + data1 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85 + data1 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e + data1 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89 + data1 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b + data1 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20 + data1 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 + data1 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31 + data1 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f + data1 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d + data1 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef + data1 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0 + data1 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 + data1 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26 + data1 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +.size AES_Td#,2048+256 // HP-UX assembler fails to ".-AES_Td#" diff --git a/libs/openssl/crypto/aes/asm/aes-mips.pl b/libs/openssl/crypto/aes/asm/aes-mips.pl new file mode 100644 index 00000000..537c8d31 --- /dev/null +++ b/libs/openssl/crypto/aes/asm/aes-mips.pl @@ -0,0 +1,1611 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# AES for MIPS + +# October 2010 +# +# Code uses 1K[+256B] S-box and on single-issue core [such as R5000] +# spends ~68 cycles per byte processed with 128-bit key. This is ~16% +# faster than gcc-generated code, which is not very impressive. But +# recall that compressed S-box requires extra processing, namely +# additional rotations. Rotations are implemented with lwl/lwr pairs, +# which is normally used for loading unaligned data. Another cool +# thing about this module is its endian neutrality, which means that +# it processes data without ever changing byte order... + +###################################################################### +# There is a number of MIPS ABI in use, O32 and N32/64 are most +# widely used. Then there is a new contender: NUBI. It appears that if +# one picks the latter, it's possible to arrange code in ABI neutral +# manner. Therefore let's stick to NUBI register layout: +# +($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25)); +($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11)); +($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23)); +($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31)); +# +# The return value is placed in $a0. Following coding rules facilitate +# interoperability: +# +# - never ever touch $tp, "thread pointer", former $gp; +# - copy return value to $t0, former $v0 [or to $a0 if you're adapting +# old code]; +# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary; +# +# For reference here is register layout for N32/64 MIPS ABIs: +# +# ($zero,$at,$v0,$v1)=map("\$$_",(0..3)); +# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11)); +# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25)); +# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23)); +# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31)); +# +$flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64 + +if ($flavour =~ /64|n32/i) { + $PTR_ADD="dadd"; # incidentally works even on n32 + $PTR_SUB="dsub"; # incidentally works even on n32 + $REG_S="sd"; + $REG_L="ld"; + $PTR_SLL="dsll"; # incidentally works even on n32 + $SZREG=8; +} else { + $PTR_ADD="add"; + $PTR_SUB="sub"; + $REG_S="sw"; + $REG_L="lw"; + $PTR_SLL="sll"; + $SZREG=4; +} +$pf = ($flavour =~ /nubi/i) ? $t0 : $t2; +# +# +# +###################################################################### + +$big_endian=(`echo MIPSEL | $ENV{CC} -E -`=~/MIPSEL/)?1:0 if ($ENV{CC}); + +for (@ARGV) { $output=$_ if (/^\w[\w\-]*\.\w+$/); } +open STDOUT,">$output"; + +if (!defined($big_endian)) +{ $big_endian=(unpack('L',pack('N',1))==1); } + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +my ($MSB,$LSB)=(0,3); # automatically converted to little-endian + +$code.=<<___; +.text +#ifdef OPENSSL_FIPSCANISTER +# include +#endif + +#if !defined(__vxworks) || defined(__pic__) +.option pic2 +#endif +.set noat +___ + +{{{ +my $FRAMESIZE=16*$SZREG; +my $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc0fff008 : 0xc0ff0000; + +my ($inp,$out,$key,$Tbl,$s0,$s1,$s2,$s3)=($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7); +my ($i0,$i1,$i2,$i3)=($at,$t0,$t1,$t2); +my ($t0,$t1,$t2,$t3,$t4,$t5,$t6,$t7,$t8,$t9,$t10,$t11) = map("\$$_",(12..23)); +my ($key0,$cnt)=($gp,$fp); + +# instuction ordering is "stolen" from output from MIPSpro assembler +# invoked with -mips3 -O3 arguments... +$code.=<<___; +.align 5 +.ent _mips_AES_encrypt +_mips_AES_encrypt: + .frame $sp,0,$ra + .set reorder + lw $t0,0($key) + lw $t1,4($key) + lw $t2,8($key) + lw $t3,12($key) + lw $cnt,240($key) + $PTR_ADD $key0,$key,16 + + xor $s0,$t0 + xor $s1,$t1 + xor $s2,$t2 + xor $s3,$t3 + + sub $cnt,1 + _xtr $i0,$s1,16-2 +.Loop_enc: + _xtr $i1,$s2,16-2 + _xtr $i2,$s3,16-2 + _xtr $i3,$s0,16-2 + and $i0,0x3fc + and $i1,0x3fc + and $i2,0x3fc + and $i3,0x3fc + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lwl $t0,3($i0) # Te1[s1>>16] + lwl $t1,3($i1) # Te1[s2>>16] + lwl $t2,3($i2) # Te1[s3>>16] + lwl $t3,3($i3) # Te1[s0>>16] + lwr $t0,2($i0) # Te1[s1>>16] + lwr $t1,2($i1) # Te1[s2>>16] + lwr $t2,2($i2) # Te1[s3>>16] + lwr $t3,2($i3) # Te1[s0>>16] + + _xtr $i0,$s2,8-2 + _xtr $i1,$s3,8-2 + _xtr $i2,$s0,8-2 + _xtr $i3,$s1,8-2 + and $i0,0x3fc + and $i1,0x3fc + and $i2,0x3fc + and $i3,0x3fc + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lwl $t4,2($i0) # Te2[s2>>8] + lwl $t5,2($i1) # Te2[s3>>8] + lwl $t6,2($i2) # Te2[s0>>8] + lwl $t7,2($i3) # Te2[s1>>8] + lwr $t4,1($i0) # Te2[s2>>8] + lwr $t5,1($i1) # Te2[s3>>8] + lwr $t6,1($i2) # Te2[s0>>8] + lwr $t7,1($i3) # Te2[s1>>8] + + _xtr $i0,$s3,0-2 + _xtr $i1,$s0,0-2 + _xtr $i2,$s1,0-2 + _xtr $i3,$s2,0-2 + and $i0,0x3fc + and $i1,0x3fc + and $i2,0x3fc + and $i3,0x3fc + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lwl $t8,1($i0) # Te3[s3] + lwl $t9,1($i1) # Te3[s0] + lwl $t10,1($i2) # Te3[s1] + lwl $t11,1($i3) # Te3[s2] + lwr $t8,0($i0) # Te3[s3] + lwr $t9,0($i1) # Te3[s0] + lwr $t10,0($i2) # Te3[s1] + lwr $t11,0($i3) # Te3[s2] + + _xtr $i0,$s0,24-2 + _xtr $i1,$s1,24-2 + _xtr $i2,$s2,24-2 + _xtr $i3,$s3,24-2 + and $i0,0x3fc + and $i1,0x3fc + and $i2,0x3fc + and $i3,0x3fc + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + xor $t0,$t4 + xor $t1,$t5 + xor $t2,$t6 + xor $t3,$t7 + lw $t4,0($i0) # Te0[s0>>24] + lw $t5,0($i1) # Te0[s1>>24] + lw $t6,0($i2) # Te0[s2>>24] + lw $t7,0($i3) # Te0[s3>>24] + + lw $s0,0($key0) + lw $s1,4($key0) + lw $s2,8($key0) + lw $s3,12($key0) + + xor $t0,$t8 + xor $t1,$t9 + xor $t2,$t10 + xor $t3,$t11 + + xor $t0,$t4 + xor $t1,$t5 + xor $t2,$t6 + xor $t3,$t7 + + sub $cnt,1 + $PTR_ADD $key0,16 + xor $s0,$t0 + xor $s1,$t1 + xor $s2,$t2 + xor $s3,$t3 + .set noreorder + bnez $cnt,.Loop_enc + _xtr $i0,$s1,16-2 + + .set reorder + _xtr $i1,$s2,16-2 + _xtr $i2,$s3,16-2 + _xtr $i3,$s0,16-2 + and $i0,0x3fc + and $i1,0x3fc + and $i2,0x3fc + and $i3,0x3fc + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lbu $t0,2($i0) # Te4[s1>>16] + lbu $t1,2($i1) # Te4[s2>>16] + lbu $t2,2($i2) # Te4[s3>>16] + lbu $t3,2($i3) # Te4[s0>>16] + + _xtr $i0,$s2,8-2 + _xtr $i1,$s3,8-2 + _xtr $i2,$s0,8-2 + _xtr $i3,$s1,8-2 + and $i0,0x3fc + and $i1,0x3fc + and $i2,0x3fc + and $i3,0x3fc + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lbu $t4,2($i0) # Te4[s2>>8] + lbu $t5,2($i1) # Te4[s3>>8] + lbu $t6,2($i2) # Te4[s0>>8] + lbu $t7,2($i3) # Te4[s1>>8] + + _xtr $i0,$s0,24-2 + _xtr $i1,$s1,24-2 + _xtr $i2,$s2,24-2 + _xtr $i3,$s3,24-2 + and $i0,0x3fc + and $i1,0x3fc + and $i2,0x3fc + and $i3,0x3fc + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lbu $t8,2($i0) # Te4[s0>>24] + lbu $t9,2($i1) # Te4[s1>>24] + lbu $t10,2($i2) # Te4[s2>>24] + lbu $t11,2($i3) # Te4[s3>>24] + + _xtr $i0,$s3,0-2 + _xtr $i1,$s0,0-2 + _xtr $i2,$s1,0-2 + _xtr $i3,$s2,0-2 + and $i0,0x3fc + and $i1,0x3fc + and $i2,0x3fc + and $i3,0x3fc + + _ins $t0,16 + _ins $t1,16 + _ins $t2,16 + _ins $t3,16 + + _ins $t4,8 + _ins $t5,8 + _ins $t6,8 + _ins $t7,8 + + xor $t0,$t4 + xor $t1,$t5 + xor $t2,$t6 + xor $t3,$t7 + + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lbu $t4,2($i0) # Te4[s3] + lbu $t5,2($i1) # Te4[s0] + lbu $t6,2($i2) # Te4[s1] + lbu $t7,2($i3) # Te4[s2] + + _ins $t8,24 + _ins $t9,24 + _ins $t10,24 + _ins $t11,24 + + lw $s0,0($key0) + lw $s1,4($key0) + lw $s2,8($key0) + lw $s3,12($key0) + + xor $t0,$t8 + xor $t1,$t9 + xor $t2,$t10 + xor $t3,$t11 + + _ins $t4,0 + _ins $t5,0 + _ins $t6,0 + _ins $t7,0 + + xor $t0,$t4 + xor $t1,$t5 + xor $t2,$t6 + xor $t3,$t7 + + xor $s0,$t0 + xor $s1,$t1 + xor $s2,$t2 + xor $s3,$t3 + + jr $ra +.end _mips_AES_encrypt + +.align 5 +.globl AES_encrypt +.ent AES_encrypt +AES_encrypt: + .frame $sp,$FRAMESIZE,$ra + .mask $SAVED_REGS_MASK,-$SZREG + .set noreorder +___ +$code.=<<___ if ($flavour =~ /o32/i); # o32 PIC-ification + .cpload $pf +___ +$code.=<<___; + $PTR_SUB $sp,$FRAMESIZE + $REG_S $ra,$FRAMESIZE-1*$SZREG($sp) + $REG_S $fp,$FRAMESIZE-2*$SZREG($sp) + $REG_S $s11,$FRAMESIZE-3*$SZREG($sp) + $REG_S $s10,$FRAMESIZE-4*$SZREG($sp) + $REG_S $s9,$FRAMESIZE-5*$SZREG($sp) + $REG_S $s8,$FRAMESIZE-6*$SZREG($sp) + $REG_S $s7,$FRAMESIZE-7*$SZREG($sp) + $REG_S $s6,$FRAMESIZE-8*$SZREG($sp) + $REG_S $s5,$FRAMESIZE-9*$SZREG($sp) + $REG_S $s4,$FRAMESIZE-10*$SZREG($sp) +___ +$code.=<<___ if ($flavour =~ /nubi/i); # optimize non-nubi prologue + $REG_S \$15,$FRAMESIZE-11*$SZREG($sp) + $REG_S \$14,$FRAMESIZE-12*$SZREG($sp) + $REG_S \$13,$FRAMESIZE-13*$SZREG($sp) + $REG_S \$12,$FRAMESIZE-14*$SZREG($sp) + $REG_S $gp,$FRAMESIZE-15*$SZREG($sp) +___ +$code.=<<___ if ($flavour !~ /o32/i); # non-o32 PIC-ification + .cplocal $Tbl + .cpsetup $pf,$zero,AES_encrypt +___ +$code.=<<___; + .set reorder + la $Tbl,AES_Te # PIC-ified 'load address' + + lwl $s0,0+$MSB($inp) + lwl $s1,4+$MSB($inp) + lwl $s2,8+$MSB($inp) + lwl $s3,12+$MSB($inp) + lwr $s0,0+$LSB($inp) + lwr $s1,4+$LSB($inp) + lwr $s2,8+$LSB($inp) + lwr $s3,12+$LSB($inp) + + bal _mips_AES_encrypt + + swr $s0,0+$LSB($out) + swr $s1,4+$LSB($out) + swr $s2,8+$LSB($out) + swr $s3,12+$LSB($out) + swl $s0,0+$MSB($out) + swl $s1,4+$MSB($out) + swl $s2,8+$MSB($out) + swl $s3,12+$MSB($out) + + .set noreorder + $REG_L $ra,$FRAMESIZE-1*$SZREG($sp) + $REG_L $fp,$FRAMESIZE-2*$SZREG($sp) + $REG_L $s11,$FRAMESIZE-3*$SZREG($sp) + $REG_L $s10,$FRAMESIZE-4*$SZREG($sp) + $REG_L $s9,$FRAMESIZE-5*$SZREG($sp) + $REG_L $s8,$FRAMESIZE-6*$SZREG($sp) + $REG_L $s7,$FRAMESIZE-7*$SZREG($sp) + $REG_L $s6,$FRAMESIZE-8*$SZREG($sp) + $REG_L $s5,$FRAMESIZE-9*$SZREG($sp) + $REG_L $s4,$FRAMESIZE-10*$SZREG($sp) +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L \$15,$FRAMESIZE-11*$SZREG($sp) + $REG_L \$14,$FRAMESIZE-12*$SZREG($sp) + $REG_L \$13,$FRAMESIZE-13*$SZREG($sp) + $REG_L \$12,$FRAMESIZE-14*$SZREG($sp) + $REG_L $gp,$FRAMESIZE-15*$SZREG($sp) +___ +$code.=<<___; + jr $ra + $PTR_ADD $sp,$FRAMESIZE +.end AES_encrypt +___ + +$code.=<<___; +.align 5 +.ent _mips_AES_decrypt +_mips_AES_decrypt: + .frame $sp,0,$ra + .set reorder + lw $t0,0($key) + lw $t1,4($key) + lw $t2,8($key) + lw $t3,12($key) + lw $cnt,240($key) + $PTR_ADD $key0,$key,16 + + xor $s0,$t0 + xor $s1,$t1 + xor $s2,$t2 + xor $s3,$t3 + + sub $cnt,1 + _xtr $i0,$s3,16-2 +.Loop_dec: + _xtr $i1,$s0,16-2 + _xtr $i2,$s1,16-2 + _xtr $i3,$s2,16-2 + and $i0,0x3fc + and $i1,0x3fc + and $i2,0x3fc + and $i3,0x3fc + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lwl $t0,3($i0) # Td1[s3>>16] + lwl $t1,3($i1) # Td1[s0>>16] + lwl $t2,3($i2) # Td1[s1>>16] + lwl $t3,3($i3) # Td1[s2>>16] + lwr $t0,2($i0) # Td1[s3>>16] + lwr $t1,2($i1) # Td1[s0>>16] + lwr $t2,2($i2) # Td1[s1>>16] + lwr $t3,2($i3) # Td1[s2>>16] + + _xtr $i0,$s2,8-2 + _xtr $i1,$s3,8-2 + _xtr $i2,$s0,8-2 + _xtr $i3,$s1,8-2 + and $i0,0x3fc + and $i1,0x3fc + and $i2,0x3fc + and $i3,0x3fc + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lwl $t4,2($i0) # Td2[s2>>8] + lwl $t5,2($i1) # Td2[s3>>8] + lwl $t6,2($i2) # Td2[s0>>8] + lwl $t7,2($i3) # Td2[s1>>8] + lwr $t4,1($i0) # Td2[s2>>8] + lwr $t5,1($i1) # Td2[s3>>8] + lwr $t6,1($i2) # Td2[s0>>8] + lwr $t7,1($i3) # Td2[s1>>8] + + _xtr $i0,$s1,0-2 + _xtr $i1,$s2,0-2 + _xtr $i2,$s3,0-2 + _xtr $i3,$s0,0-2 + and $i0,0x3fc + and $i1,0x3fc + and $i2,0x3fc + and $i3,0x3fc + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lwl $t8,1($i0) # Td3[s1] + lwl $t9,1($i1) # Td3[s2] + lwl $t10,1($i2) # Td3[s3] + lwl $t11,1($i3) # Td3[s0] + lwr $t8,0($i0) # Td3[s1] + lwr $t9,0($i1) # Td3[s2] + lwr $t10,0($i2) # Td3[s3] + lwr $t11,0($i3) # Td3[s0] + + _xtr $i0,$s0,24-2 + _xtr $i1,$s1,24-2 + _xtr $i2,$s2,24-2 + _xtr $i3,$s3,24-2 + and $i0,0x3fc + and $i1,0x3fc + and $i2,0x3fc + and $i3,0x3fc + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + + xor $t0,$t4 + xor $t1,$t5 + xor $t2,$t6 + xor $t3,$t7 + + + lw $t4,0($i0) # Td0[s0>>24] + lw $t5,0($i1) # Td0[s1>>24] + lw $t6,0($i2) # Td0[s2>>24] + lw $t7,0($i3) # Td0[s3>>24] + + lw $s0,0($key0) + lw $s1,4($key0) + lw $s2,8($key0) + lw $s3,12($key0) + + xor $t0,$t8 + xor $t1,$t9 + xor $t2,$t10 + xor $t3,$t11 + + xor $t0,$t4 + xor $t1,$t5 + xor $t2,$t6 + xor $t3,$t7 + + sub $cnt,1 + $PTR_ADD $key0,16 + xor $s0,$t0 + xor $s1,$t1 + xor $s2,$t2 + xor $s3,$t3 + .set noreorder + bnez $cnt,.Loop_dec + _xtr $i0,$s3,16-2 + + .set reorder + lw $t4,1024($Tbl) # prefetch Td4 + lw $t5,1024+32($Tbl) + lw $t6,1024+64($Tbl) + lw $t7,1024+96($Tbl) + lw $t8,1024+128($Tbl) + lw $t9,1024+160($Tbl) + lw $t10,1024+192($Tbl) + lw $t11,1024+224($Tbl) + + _xtr $i0,$s3,16 + _xtr $i1,$s0,16 + _xtr $i2,$s1,16 + _xtr $i3,$s2,16 + and $i0,0xff + and $i1,0xff + and $i2,0xff + and $i3,0xff + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lbu $t0,1024($i0) # Td4[s3>>16] + lbu $t1,1024($i1) # Td4[s0>>16] + lbu $t2,1024($i2) # Td4[s1>>16] + lbu $t3,1024($i3) # Td4[s2>>16] + + _xtr $i0,$s2,8 + _xtr $i1,$s3,8 + _xtr $i2,$s0,8 + _xtr $i3,$s1,8 + and $i0,0xff + and $i1,0xff + and $i2,0xff + and $i3,0xff + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lbu $t4,1024($i0) # Td4[s2>>8] + lbu $t5,1024($i1) # Td4[s3>>8] + lbu $t6,1024($i2) # Td4[s0>>8] + lbu $t7,1024($i3) # Td4[s1>>8] + + _xtr $i0,$s0,24 + _xtr $i1,$s1,24 + _xtr $i2,$s2,24 + _xtr $i3,$s3,24 + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lbu $t8,1024($i0) # Td4[s0>>24] + lbu $t9,1024($i1) # Td4[s1>>24] + lbu $t10,1024($i2) # Td4[s2>>24] + lbu $t11,1024($i3) # Td4[s3>>24] + + _xtr $i0,$s1,0 + _xtr $i1,$s2,0 + _xtr $i2,$s3,0 + _xtr $i3,$s0,0 + + _ins $t0,16 + _ins $t1,16 + _ins $t2,16 + _ins $t3,16 + + _ins $t4,8 + _ins $t5,8 + _ins $t6,8 + _ins $t7,8 + + xor $t0,$t4 + xor $t1,$t5 + xor $t2,$t6 + xor $t3,$t7 + + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lbu $t4,1024($i0) # Td4[s1] + lbu $t5,1024($i1) # Td4[s2] + lbu $t6,1024($i2) # Td4[s3] + lbu $t7,1024($i3) # Td4[s0] + + _ins $t8,24 + _ins $t9,24 + _ins $t10,24 + _ins $t11,24 + + lw $s0,0($key0) + lw $s1,4($key0) + lw $s2,8($key0) + lw $s3,12($key0) + + _ins $t4,0 + _ins $t5,0 + _ins $t6,0 + _ins $t7,0 + + + xor $t0,$t8 + xor $t1,$t9 + xor $t2,$t10 + xor $t3,$t11 + + xor $t0,$t4 + xor $t1,$t5 + xor $t2,$t6 + xor $t3,$t7 + + xor $s0,$t0 + xor $s1,$t1 + xor $s2,$t2 + xor $s3,$t3 + + jr $ra +.end _mips_AES_decrypt + +.align 5 +.globl AES_decrypt +.ent AES_decrypt +AES_decrypt: + .frame $sp,$FRAMESIZE,$ra + .mask $SAVED_REGS_MASK,-$SZREG + .set noreorder +___ +$code.=<<___ if ($flavour =~ /o32/i); # o32 PIC-ification + .cpload $pf +___ +$code.=<<___; + $PTR_SUB $sp,$FRAMESIZE + $REG_S $ra,$FRAMESIZE-1*$SZREG($sp) + $REG_S $fp,$FRAMESIZE-2*$SZREG($sp) + $REG_S $s11,$FRAMESIZE-3*$SZREG($sp) + $REG_S $s10,$FRAMESIZE-4*$SZREG($sp) + $REG_S $s9,$FRAMESIZE-5*$SZREG($sp) + $REG_S $s8,$FRAMESIZE-6*$SZREG($sp) + $REG_S $s7,$FRAMESIZE-7*$SZREG($sp) + $REG_S $s6,$FRAMESIZE-8*$SZREG($sp) + $REG_S $s5,$FRAMESIZE-9*$SZREG($sp) + $REG_S $s4,$FRAMESIZE-10*$SZREG($sp) +___ +$code.=<<___ if ($flavour =~ /nubi/i); # optimize non-nubi prologue + $REG_S \$15,$FRAMESIZE-11*$SZREG($sp) + $REG_S \$14,$FRAMESIZE-12*$SZREG($sp) + $REG_S \$13,$FRAMESIZE-13*$SZREG($sp) + $REG_S \$12,$FRAMESIZE-14*$SZREG($sp) + $REG_S $gp,$FRAMESIZE-15*$SZREG($sp) +___ +$code.=<<___ if ($flavour !~ /o32/i); # non-o32 PIC-ification + .cplocal $Tbl + .cpsetup $pf,$zero,AES_decrypt +___ +$code.=<<___; + .set reorder + la $Tbl,AES_Td # PIC-ified 'load address' + + lwl $s0,0+$MSB($inp) + lwl $s1,4+$MSB($inp) + lwl $s2,8+$MSB($inp) + lwl $s3,12+$MSB($inp) + lwr $s0,0+$LSB($inp) + lwr $s1,4+$LSB($inp) + lwr $s2,8+$LSB($inp) + lwr $s3,12+$LSB($inp) + + bal _mips_AES_decrypt + + swr $s0,0+$LSB($out) + swr $s1,4+$LSB($out) + swr $s2,8+$LSB($out) + swr $s3,12+$LSB($out) + swl $s0,0+$MSB($out) + swl $s1,4+$MSB($out) + swl $s2,8+$MSB($out) + swl $s3,12+$MSB($out) + + .set noreorder + $REG_L $ra,$FRAMESIZE-1*$SZREG($sp) + $REG_L $fp,$FRAMESIZE-2*$SZREG($sp) + $REG_L $s11,$FRAMESIZE-3*$SZREG($sp) + $REG_L $s10,$FRAMESIZE-4*$SZREG($sp) + $REG_L $s9,$FRAMESIZE-5*$SZREG($sp) + $REG_L $s8,$FRAMESIZE-6*$SZREG($sp) + $REG_L $s7,$FRAMESIZE-7*$SZREG($sp) + $REG_L $s6,$FRAMESIZE-8*$SZREG($sp) + $REG_L $s5,$FRAMESIZE-9*$SZREG($sp) + $REG_L $s4,$FRAMESIZE-10*$SZREG($sp) +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L \$15,$FRAMESIZE-11*$SZREG($sp) + $REG_L \$14,$FRAMESIZE-12*$SZREG($sp) + $REG_L \$13,$FRAMESIZE-13*$SZREG($sp) + $REG_L \$12,$FRAMESIZE-14*$SZREG($sp) + $REG_L $gp,$FRAMESIZE-15*$SZREG($sp) +___ +$code.=<<___; + jr $ra + $PTR_ADD $sp,$FRAMESIZE +.end AES_decrypt +___ +}}} + +{{{ +my $FRAMESIZE=8*$SZREG; +my $SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc000f008 : 0xc0000000; + +my ($inp,$bits,$key,$Tbl)=($a0,$a1,$a2,$a3); +my ($rk0,$rk1,$rk2,$rk3,$rk4,$rk5,$rk6,$rk7)=($a4,$a5,$a6,$a7,$s0,$s1,$s2,$s3); +my ($i0,$i1,$i2,$i3)=($at,$t0,$t1,$t2); +my ($rcon,$cnt)=($gp,$fp); + +$code.=<<___; +.align 5 +.ent _mips_AES_set_encrypt_key +_mips_AES_set_encrypt_key: + .frame $sp,0,$ra + .set noreorder + beqz $inp,.Lekey_done + li $t0,-1 + beqz $key,.Lekey_done + $PTR_ADD $rcon,$Tbl,1024+256 + + .set reorder + lwl $rk0,0+$MSB($inp) # load 128 bits + lwl $rk1,4+$MSB($inp) + lwl $rk2,8+$MSB($inp) + lwl $rk3,12+$MSB($inp) + li $at,128 + lwr $rk0,0+$LSB($inp) + lwr $rk1,4+$LSB($inp) + lwr $rk2,8+$LSB($inp) + lwr $rk3,12+$LSB($inp) + .set noreorder + beq $bits,$at,.L128bits + li $cnt,10 + + .set reorder + lwl $rk4,16+$MSB($inp) # load 192 bits + lwl $rk5,20+$MSB($inp) + li $at,192 + lwr $rk4,16+$LSB($inp) + lwr $rk5,20+$LSB($inp) + .set noreorder + beq $bits,$at,.L192bits + li $cnt,8 + + .set reorder + lwl $rk6,24+$MSB($inp) # load 256 bits + lwl $rk7,28+$MSB($inp) + li $at,256 + lwr $rk6,24+$LSB($inp) + lwr $rk7,28+$LSB($inp) + .set noreorder + beq $bits,$at,.L256bits + li $cnt,7 + + b .Lekey_done + li $t0,-2 + +.align 4 +.L128bits: + .set reorder + srl $i0,$rk3,16 + srl $i1,$rk3,8 + and $i0,0xff + and $i1,0xff + and $i2,$rk3,0xff + srl $i3,$rk3,24 + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lbu $i0,1024($i0) + lbu $i1,1024($i1) + lbu $i2,1024($i2) + lbu $i3,1024($i3) + + sw $rk0,0($key) + sw $rk1,4($key) + sw $rk2,8($key) + sw $rk3,12($key) + sub $cnt,1 + $PTR_ADD $key,16 + + _bias $i0,24 + _bias $i1,16 + _bias $i2,8 + _bias $i3,0 + + xor $rk0,$i0 + lw $i0,0($rcon) + xor $rk0,$i1 + xor $rk0,$i2 + xor $rk0,$i3 + xor $rk0,$i0 + + xor $rk1,$rk0 + xor $rk2,$rk1 + xor $rk3,$rk2 + + .set noreorder + bnez $cnt,.L128bits + $PTR_ADD $rcon,4 + + sw $rk0,0($key) + sw $rk1,4($key) + sw $rk2,8($key) + li $cnt,10 + sw $rk3,12($key) + li $t0,0 + sw $cnt,80($key) + b .Lekey_done + $PTR_SUB $key,10*16 + +.align 4 +.L192bits: + .set reorder + srl $i0,$rk5,16 + srl $i1,$rk5,8 + and $i0,0xff + and $i1,0xff + and $i2,$rk5,0xff + srl $i3,$rk5,24 + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lbu $i0,1024($i0) + lbu $i1,1024($i1) + lbu $i2,1024($i2) + lbu $i3,1024($i3) + + sw $rk0,0($key) + sw $rk1,4($key) + sw $rk2,8($key) + sw $rk3,12($key) + sw $rk4,16($key) + sw $rk5,20($key) + sub $cnt,1 + $PTR_ADD $key,24 + + _bias $i0,24 + _bias $i1,16 + _bias $i2,8 + _bias $i3,0 + + xor $rk0,$i0 + lw $i0,0($rcon) + xor $rk0,$i1 + xor $rk0,$i2 + xor $rk0,$i3 + xor $rk0,$i0 + + xor $rk1,$rk0 + xor $rk2,$rk1 + xor $rk3,$rk2 + xor $rk4,$rk3 + xor $rk5,$rk4 + + .set noreorder + bnez $cnt,.L192bits + $PTR_ADD $rcon,4 + + sw $rk0,0($key) + sw $rk1,4($key) + sw $rk2,8($key) + li $cnt,12 + sw $rk3,12($key) + li $t0,0 + sw $cnt,48($key) + b .Lekey_done + $PTR_SUB $key,12*16 + +.align 4 +.L256bits: + .set reorder + srl $i0,$rk7,16 + srl $i1,$rk7,8 + and $i0,0xff + and $i1,0xff + and $i2,$rk7,0xff + srl $i3,$rk7,24 + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lbu $i0,1024($i0) + lbu $i1,1024($i1) + lbu $i2,1024($i2) + lbu $i3,1024($i3) + + sw $rk0,0($key) + sw $rk1,4($key) + sw $rk2,8($key) + sw $rk3,12($key) + sw $rk4,16($key) + sw $rk5,20($key) + sw $rk6,24($key) + sw $rk7,28($key) + sub $cnt,1 + + _bias $i0,24 + _bias $i1,16 + _bias $i2,8 + _bias $i3,0 + + xor $rk0,$i0 + lw $i0,0($rcon) + xor $rk0,$i1 + xor $rk0,$i2 + xor $rk0,$i3 + xor $rk0,$i0 + + xor $rk1,$rk0 + xor $rk2,$rk1 + xor $rk3,$rk2 + beqz $cnt,.L256bits_done + + srl $i0,$rk3,24 + srl $i1,$rk3,16 + srl $i2,$rk3,8 + and $i3,$rk3,0xff + and $i1,0xff + and $i2,0xff + $PTR_ADD $i0,$Tbl + $PTR_ADD $i1,$Tbl + $PTR_ADD $i2,$Tbl + $PTR_ADD $i3,$Tbl + lbu $i0,1024($i0) + lbu $i1,1024($i1) + lbu $i2,1024($i2) + lbu $i3,1024($i3) + sll $i0,24 + sll $i1,16 + sll $i2,8 + + xor $rk4,$i0 + xor $rk4,$i1 + xor $rk4,$i2 + xor $rk4,$i3 + + xor $rk5,$rk4 + xor $rk6,$rk5 + xor $rk7,$rk6 + + $PTR_ADD $key,32 + .set noreorder + b .L256bits + $PTR_ADD $rcon,4 + +.L256bits_done: + sw $rk0,32($key) + sw $rk1,36($key) + sw $rk2,40($key) + li $cnt,14 + sw $rk3,44($key) + li $t0,0 + sw $cnt,48($key) + $PTR_SUB $key,12*16 + +.Lekey_done: + jr $ra + nop +.end _mips_AES_set_encrypt_key + +.globl private_AES_set_encrypt_key +.ent private_AES_set_encrypt_key +private_AES_set_encrypt_key: + .frame $sp,$FRAMESIZE,$ra + .mask $SAVED_REGS_MASK,-$SZREG + .set noreorder +___ +$code.=<<___ if ($flavour =~ /o32/i); # o32 PIC-ification + .cpload $pf +___ +$code.=<<___; + $PTR_SUB $sp,$FRAMESIZE + $REG_S $ra,$FRAMESIZE-1*$SZREG($sp) + $REG_S $fp,$FRAMESIZE-2*$SZREG($sp) +___ +$code.=<<___ if ($flavour =~ /nubi/i); # optimize non-nubi prologue + $REG_S $s3,$FRAMESIZE-3*$SZREG($sp) + $REG_S $s2,$FRAMESIZE-4*$SZREG($sp) + $REG_S $s1,$FRAMESIZE-5*$SZREG($sp) + $REG_S $s0,$FRAMESIZE-6*$SZREG($sp) + $REG_S $gp,$FRAMESIZE-7*$SZREG($sp) +___ +$code.=<<___ if ($flavour !~ /o32/i); # non-o32 PIC-ification + .cplocal $Tbl + .cpsetup $pf,$zero,private_AES_set_encrypt_key +___ +$code.=<<___; + .set reorder + la $Tbl,AES_Te # PIC-ified 'load address' + + bal _mips_AES_set_encrypt_key + + .set noreorder + move $a0,$t0 + $REG_L $ra,$FRAMESIZE-1*$SZREG($sp) + $REG_L $fp,$FRAMESIZE-2*$SZREG($sp) +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $s3,$FRAMESIZE-11*$SZREG($sp) + $REG_L $s2,$FRAMESIZE-12*$SZREG($sp) + $REG_L $s1,$FRAMESIZE-13*$SZREG($sp) + $REG_L $s0,$FRAMESIZE-14*$SZREG($sp) + $REG_L $gp,$FRAMESIZE-15*$SZREG($sp) +___ +$code.=<<___; + jr $ra + $PTR_ADD $sp,$FRAMESIZE +.end private_AES_set_encrypt_key +___ + +my ($head,$tail)=($inp,$bits); +my ($tp1,$tp2,$tp4,$tp8,$tp9,$tpb,$tpd,$tpe)=($a4,$a5,$a6,$a7,$s0,$s1,$s2,$s3); +my ($m,$x80808080,$x7f7f7f7f,$x1b1b1b1b)=($at,$t0,$t1,$t2); +$code.=<<___; +.align 5 +.globl private_AES_set_decrypt_key +.ent private_AES_set_decrypt_key +private_AES_set_decrypt_key: + .frame $sp,$FRAMESIZE,$ra + .mask $SAVED_REGS_MASK,-$SZREG + .set noreorder +___ +$code.=<<___ if ($flavour =~ /o32/i); # o32 PIC-ification + .cpload $pf +___ +$code.=<<___; + $PTR_SUB $sp,$FRAMESIZE + $REG_S $ra,$FRAMESIZE-1*$SZREG($sp) + $REG_S $fp,$FRAMESIZE-2*$SZREG($sp) +___ +$code.=<<___ if ($flavour =~ /nubi/i); # optimize non-nubi prologue + $REG_S $s3,$FRAMESIZE-3*$SZREG($sp) + $REG_S $s2,$FRAMESIZE-4*$SZREG($sp) + $REG_S $s1,$FRAMESIZE-5*$SZREG($sp) + $REG_S $s0,$FRAMESIZE-6*$SZREG($sp) + $REG_S $gp,$FRAMESIZE-7*$SZREG($sp) +___ +$code.=<<___ if ($flavour !~ /o32/i); # non-o32 PIC-ification + .cplocal $Tbl + .cpsetup $pf,$zero,private_AES_set_decrypt_key +___ +$code.=<<___; + .set reorder + la $Tbl,AES_Te # PIC-ified 'load address' + + bal _mips_AES_set_encrypt_key + + bltz $t0,.Ldkey_done + + sll $at,$cnt,4 + $PTR_ADD $head,$key,0 + $PTR_ADD $tail,$key,$at +.align 4 +.Lswap: + lw $rk0,0($head) + lw $rk1,4($head) + lw $rk2,8($head) + lw $rk3,12($head) + lw $rk4,0($tail) + lw $rk5,4($tail) + lw $rk6,8($tail) + lw $rk7,12($tail) + sw $rk0,0($tail) + sw $rk1,4($tail) + sw $rk2,8($tail) + sw $rk3,12($tail) + $PTR_ADD $head,16 + $PTR_SUB $tail,16 + sw $rk4,-16($head) + sw $rk5,-12($head) + sw $rk6,-8($head) + sw $rk7,-4($head) + bne $head,$tail,.Lswap + + lw $tp1,16($key) # modulo-scheduled + lui $x80808080,0x8080 + sub $cnt,1 + or $x80808080,0x8080 + sll $cnt,2 + $PTR_ADD $key,16 + lui $x1b1b1b1b,0x1b1b + nor $x7f7f7f7f,$zero,$x80808080 + or $x1b1b1b1b,0x1b1b +.align 4 +.Lmix: + and $m,$tp1,$x80808080 + and $tp2,$tp1,$x7f7f7f7f + srl $tp4,$m,7 + addu $tp2,$tp2 # tp2<<1 + subu $m,$tp4 + and $m,$x1b1b1b1b + xor $tp2,$m + + and $m,$tp2,$x80808080 + and $tp4,$tp2,$x7f7f7f7f + srl $tp8,$m,7 + addu $tp4,$tp4 # tp4<<1 + subu $m,$tp8 + and $m,$x1b1b1b1b + xor $tp4,$m + + and $m,$tp4,$x80808080 + and $tp8,$tp4,$x7f7f7f7f + srl $tp9,$m,7 + addu $tp8,$tp8 # tp8<<1 + subu $m,$tp9 + and $m,$x1b1b1b1b + xor $tp8,$m + + xor $tp9,$tp8,$tp1 + xor $tpe,$tp8,$tp4 + xor $tpb,$tp9,$tp2 + xor $tpd,$tp9,$tp4 + + _ror $tp1,$tpd,16 + xor $tpe,$tp2 + _ror $tp2,$tpd,-16 + xor $tpe,$tp1 + _ror $tp1,$tp9,8 + xor $tpe,$tp2 + _ror $tp2,$tp9,-24 + xor $tpe,$tp1 + _ror $tp1,$tpb,24 + xor $tpe,$tp2 + _ror $tp2,$tpb,-8 + xor $tpe,$tp1 + lw $tp1,4($key) # modulo-scheduled + xor $tpe,$tp2 + sub $cnt,1 + sw $tpe,0($key) + $PTR_ADD $key,4 + bnez $cnt,.Lmix + + li $t0,0 +.Ldkey_done: + .set noreorder + move $a0,$t0 + $REG_L $ra,$FRAMESIZE-1*$SZREG($sp) + $REG_L $fp,$FRAMESIZE-2*$SZREG($sp) +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $s3,$FRAMESIZE-11*$SZREG($sp) + $REG_L $s2,$FRAMESIZE-12*$SZREG($sp) + $REG_L $s1,$FRAMESIZE-13*$SZREG($sp) + $REG_L $s0,$FRAMESIZE-14*$SZREG($sp) + $REG_L $gp,$FRAMESIZE-15*$SZREG($sp) +___ +$code.=<<___; + jr $ra + $PTR_ADD $sp,$FRAMESIZE +.end private_AES_set_decrypt_key +___ +}}} + +###################################################################### +# Tables are kept in endian-neutral manner +$code.=<<___; +.rdata +.align 6 +AES_Te: +.byte 0xc6,0x63,0x63,0xa5, 0xf8,0x7c,0x7c,0x84 # Te0 +.byte 0xee,0x77,0x77,0x99, 0xf6,0x7b,0x7b,0x8d +.byte 0xff,0xf2,0xf2,0x0d, 0xd6,0x6b,0x6b,0xbd +.byte 0xde,0x6f,0x6f,0xb1, 0x91,0xc5,0xc5,0x54 +.byte 0x60,0x30,0x30,0x50, 0x02,0x01,0x01,0x03 +.byte 0xce,0x67,0x67,0xa9, 0x56,0x2b,0x2b,0x7d +.byte 0xe7,0xfe,0xfe,0x19, 0xb5,0xd7,0xd7,0x62 +.byte 0x4d,0xab,0xab,0xe6, 0xec,0x76,0x76,0x9a +.byte 0x8f,0xca,0xca,0x45, 0x1f,0x82,0x82,0x9d +.byte 0x89,0xc9,0xc9,0x40, 0xfa,0x7d,0x7d,0x87 +.byte 0xef,0xfa,0xfa,0x15, 0xb2,0x59,0x59,0xeb +.byte 0x8e,0x47,0x47,0xc9, 0xfb,0xf0,0xf0,0x0b +.byte 0x41,0xad,0xad,0xec, 0xb3,0xd4,0xd4,0x67 +.byte 0x5f,0xa2,0xa2,0xfd, 0x45,0xaf,0xaf,0xea +.byte 0x23,0x9c,0x9c,0xbf, 0x53,0xa4,0xa4,0xf7 +.byte 0xe4,0x72,0x72,0x96, 0x9b,0xc0,0xc0,0x5b +.byte 0x75,0xb7,0xb7,0xc2, 0xe1,0xfd,0xfd,0x1c +.byte 0x3d,0x93,0x93,0xae, 0x4c,0x26,0x26,0x6a +.byte 0x6c,0x36,0x36,0x5a, 0x7e,0x3f,0x3f,0x41 +.byte 0xf5,0xf7,0xf7,0x02, 0x83,0xcc,0xcc,0x4f +.byte 0x68,0x34,0x34,0x5c, 0x51,0xa5,0xa5,0xf4 +.byte 0xd1,0xe5,0xe5,0x34, 0xf9,0xf1,0xf1,0x08 +.byte 0xe2,0x71,0x71,0x93, 0xab,0xd8,0xd8,0x73 +.byte 0x62,0x31,0x31,0x53, 0x2a,0x15,0x15,0x3f +.byte 0x08,0x04,0x04,0x0c, 0x95,0xc7,0xc7,0x52 +.byte 0x46,0x23,0x23,0x65, 0x9d,0xc3,0xc3,0x5e +.byte 0x30,0x18,0x18,0x28, 0x37,0x96,0x96,0xa1 +.byte 0x0a,0x05,0x05,0x0f, 0x2f,0x9a,0x9a,0xb5 +.byte 0x0e,0x07,0x07,0x09, 0x24,0x12,0x12,0x36 +.byte 0x1b,0x80,0x80,0x9b, 0xdf,0xe2,0xe2,0x3d +.byte 0xcd,0xeb,0xeb,0x26, 0x4e,0x27,0x27,0x69 +.byte 0x7f,0xb2,0xb2,0xcd, 0xea,0x75,0x75,0x9f +.byte 0x12,0x09,0x09,0x1b, 0x1d,0x83,0x83,0x9e +.byte 0x58,0x2c,0x2c,0x74, 0x34,0x1a,0x1a,0x2e +.byte 0x36,0x1b,0x1b,0x2d, 0xdc,0x6e,0x6e,0xb2 +.byte 0xb4,0x5a,0x5a,0xee, 0x5b,0xa0,0xa0,0xfb +.byte 0xa4,0x52,0x52,0xf6, 0x76,0x3b,0x3b,0x4d +.byte 0xb7,0xd6,0xd6,0x61, 0x7d,0xb3,0xb3,0xce +.byte 0x52,0x29,0x29,0x7b, 0xdd,0xe3,0xe3,0x3e +.byte 0x5e,0x2f,0x2f,0x71, 0x13,0x84,0x84,0x97 +.byte 0xa6,0x53,0x53,0xf5, 0xb9,0xd1,0xd1,0x68 +.byte 0x00,0x00,0x00,0x00, 0xc1,0xed,0xed,0x2c +.byte 0x40,0x20,0x20,0x60, 0xe3,0xfc,0xfc,0x1f +.byte 0x79,0xb1,0xb1,0xc8, 0xb6,0x5b,0x5b,0xed +.byte 0xd4,0x6a,0x6a,0xbe, 0x8d,0xcb,0xcb,0x46 +.byte 0x67,0xbe,0xbe,0xd9, 0x72,0x39,0x39,0x4b +.byte 0x94,0x4a,0x4a,0xde, 0x98,0x4c,0x4c,0xd4 +.byte 0xb0,0x58,0x58,0xe8, 0x85,0xcf,0xcf,0x4a +.byte 0xbb,0xd0,0xd0,0x6b, 0xc5,0xef,0xef,0x2a +.byte 0x4f,0xaa,0xaa,0xe5, 0xed,0xfb,0xfb,0x16 +.byte 0x86,0x43,0x43,0xc5, 0x9a,0x4d,0x4d,0xd7 +.byte 0x66,0x33,0x33,0x55, 0x11,0x85,0x85,0x94 +.byte 0x8a,0x45,0x45,0xcf, 0xe9,0xf9,0xf9,0x10 +.byte 0x04,0x02,0x02,0x06, 0xfe,0x7f,0x7f,0x81 +.byte 0xa0,0x50,0x50,0xf0, 0x78,0x3c,0x3c,0x44 +.byte 0x25,0x9f,0x9f,0xba, 0x4b,0xa8,0xa8,0xe3 +.byte 0xa2,0x51,0x51,0xf3, 0x5d,0xa3,0xa3,0xfe +.byte 0x80,0x40,0x40,0xc0, 0x05,0x8f,0x8f,0x8a +.byte 0x3f,0x92,0x92,0xad, 0x21,0x9d,0x9d,0xbc +.byte 0x70,0x38,0x38,0x48, 0xf1,0xf5,0xf5,0x04 +.byte 0x63,0xbc,0xbc,0xdf, 0x77,0xb6,0xb6,0xc1 +.byte 0xaf,0xda,0xda,0x75, 0x42,0x21,0x21,0x63 +.byte 0x20,0x10,0x10,0x30, 0xe5,0xff,0xff,0x1a +.byte 0xfd,0xf3,0xf3,0x0e, 0xbf,0xd2,0xd2,0x6d +.byte 0x81,0xcd,0xcd,0x4c, 0x18,0x0c,0x0c,0x14 +.byte 0x26,0x13,0x13,0x35, 0xc3,0xec,0xec,0x2f +.byte 0xbe,0x5f,0x5f,0xe1, 0x35,0x97,0x97,0xa2 +.byte 0x88,0x44,0x44,0xcc, 0x2e,0x17,0x17,0x39 +.byte 0x93,0xc4,0xc4,0x57, 0x55,0xa7,0xa7,0xf2 +.byte 0xfc,0x7e,0x7e,0x82, 0x7a,0x3d,0x3d,0x47 +.byte 0xc8,0x64,0x64,0xac, 0xba,0x5d,0x5d,0xe7 +.byte 0x32,0x19,0x19,0x2b, 0xe6,0x73,0x73,0x95 +.byte 0xc0,0x60,0x60,0xa0, 0x19,0x81,0x81,0x98 +.byte 0x9e,0x4f,0x4f,0xd1, 0xa3,0xdc,0xdc,0x7f +.byte 0x44,0x22,0x22,0x66, 0x54,0x2a,0x2a,0x7e +.byte 0x3b,0x90,0x90,0xab, 0x0b,0x88,0x88,0x83 +.byte 0x8c,0x46,0x46,0xca, 0xc7,0xee,0xee,0x29 +.byte 0x6b,0xb8,0xb8,0xd3, 0x28,0x14,0x14,0x3c +.byte 0xa7,0xde,0xde,0x79, 0xbc,0x5e,0x5e,0xe2 +.byte 0x16,0x0b,0x0b,0x1d, 0xad,0xdb,0xdb,0x76 +.byte 0xdb,0xe0,0xe0,0x3b, 0x64,0x32,0x32,0x56 +.byte 0x74,0x3a,0x3a,0x4e, 0x14,0x0a,0x0a,0x1e +.byte 0x92,0x49,0x49,0xdb, 0x0c,0x06,0x06,0x0a +.byte 0x48,0x24,0x24,0x6c, 0xb8,0x5c,0x5c,0xe4 +.byte 0x9f,0xc2,0xc2,0x5d, 0xbd,0xd3,0xd3,0x6e +.byte 0x43,0xac,0xac,0xef, 0xc4,0x62,0x62,0xa6 +.byte 0x39,0x91,0x91,0xa8, 0x31,0x95,0x95,0xa4 +.byte 0xd3,0xe4,0xe4,0x37, 0xf2,0x79,0x79,0x8b +.byte 0xd5,0xe7,0xe7,0x32, 0x8b,0xc8,0xc8,0x43 +.byte 0x6e,0x37,0x37,0x59, 0xda,0x6d,0x6d,0xb7 +.byte 0x01,0x8d,0x8d,0x8c, 0xb1,0xd5,0xd5,0x64 +.byte 0x9c,0x4e,0x4e,0xd2, 0x49,0xa9,0xa9,0xe0 +.byte 0xd8,0x6c,0x6c,0xb4, 0xac,0x56,0x56,0xfa +.byte 0xf3,0xf4,0xf4,0x07, 0xcf,0xea,0xea,0x25 +.byte 0xca,0x65,0x65,0xaf, 0xf4,0x7a,0x7a,0x8e +.byte 0x47,0xae,0xae,0xe9, 0x10,0x08,0x08,0x18 +.byte 0x6f,0xba,0xba,0xd5, 0xf0,0x78,0x78,0x88 +.byte 0x4a,0x25,0x25,0x6f, 0x5c,0x2e,0x2e,0x72 +.byte 0x38,0x1c,0x1c,0x24, 0x57,0xa6,0xa6,0xf1 +.byte 0x73,0xb4,0xb4,0xc7, 0x97,0xc6,0xc6,0x51 +.byte 0xcb,0xe8,0xe8,0x23, 0xa1,0xdd,0xdd,0x7c +.byte 0xe8,0x74,0x74,0x9c, 0x3e,0x1f,0x1f,0x21 +.byte 0x96,0x4b,0x4b,0xdd, 0x61,0xbd,0xbd,0xdc +.byte 0x0d,0x8b,0x8b,0x86, 0x0f,0x8a,0x8a,0x85 +.byte 0xe0,0x70,0x70,0x90, 0x7c,0x3e,0x3e,0x42 +.byte 0x71,0xb5,0xb5,0xc4, 0xcc,0x66,0x66,0xaa +.byte 0x90,0x48,0x48,0xd8, 0x06,0x03,0x03,0x05 +.byte 0xf7,0xf6,0xf6,0x01, 0x1c,0x0e,0x0e,0x12 +.byte 0xc2,0x61,0x61,0xa3, 0x6a,0x35,0x35,0x5f +.byte 0xae,0x57,0x57,0xf9, 0x69,0xb9,0xb9,0xd0 +.byte 0x17,0x86,0x86,0x91, 0x99,0xc1,0xc1,0x58 +.byte 0x3a,0x1d,0x1d,0x27, 0x27,0x9e,0x9e,0xb9 +.byte 0xd9,0xe1,0xe1,0x38, 0xeb,0xf8,0xf8,0x13 +.byte 0x2b,0x98,0x98,0xb3, 0x22,0x11,0x11,0x33 +.byte 0xd2,0x69,0x69,0xbb, 0xa9,0xd9,0xd9,0x70 +.byte 0x07,0x8e,0x8e,0x89, 0x33,0x94,0x94,0xa7 +.byte 0x2d,0x9b,0x9b,0xb6, 0x3c,0x1e,0x1e,0x22 +.byte 0x15,0x87,0x87,0x92, 0xc9,0xe9,0xe9,0x20 +.byte 0x87,0xce,0xce,0x49, 0xaa,0x55,0x55,0xff +.byte 0x50,0x28,0x28,0x78, 0xa5,0xdf,0xdf,0x7a +.byte 0x03,0x8c,0x8c,0x8f, 0x59,0xa1,0xa1,0xf8 +.byte 0x09,0x89,0x89,0x80, 0x1a,0x0d,0x0d,0x17 +.byte 0x65,0xbf,0xbf,0xda, 0xd7,0xe6,0xe6,0x31 +.byte 0x84,0x42,0x42,0xc6, 0xd0,0x68,0x68,0xb8 +.byte 0x82,0x41,0x41,0xc3, 0x29,0x99,0x99,0xb0 +.byte 0x5a,0x2d,0x2d,0x77, 0x1e,0x0f,0x0f,0x11 +.byte 0x7b,0xb0,0xb0,0xcb, 0xa8,0x54,0x54,0xfc +.byte 0x6d,0xbb,0xbb,0xd6, 0x2c,0x16,0x16,0x3a + +.byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5 # Te4 +.byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 +.byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0 +.byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 +.byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc +.byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 +.byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a +.byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 +.byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0 +.byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 +.byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b +.byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf +.byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85 +.byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 +.byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5 +.byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 +.byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17 +.byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 +.byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88 +.byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb +.byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c +.byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 +.byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9 +.byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 +.byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6 +.byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a +.byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e +.byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e +.byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94 +.byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf +.byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68 +.byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 + +.byte 0x01,0x00,0x00,0x00, 0x02,0x00,0x00,0x00 # rcon +.byte 0x04,0x00,0x00,0x00, 0x08,0x00,0x00,0x00 +.byte 0x10,0x00,0x00,0x00, 0x20,0x00,0x00,0x00 +.byte 0x40,0x00,0x00,0x00, 0x80,0x00,0x00,0x00 +.byte 0x1B,0x00,0x00,0x00, 0x36,0x00,0x00,0x00 + +.align 6 +AES_Td: +.byte 0x51,0xf4,0xa7,0x50, 0x7e,0x41,0x65,0x53 # Td0 +.byte 0x1a,0x17,0xa4,0xc3, 0x3a,0x27,0x5e,0x96 +.byte 0x3b,0xab,0x6b,0xcb, 0x1f,0x9d,0x45,0xf1 +.byte 0xac,0xfa,0x58,0xab, 0x4b,0xe3,0x03,0x93 +.byte 0x20,0x30,0xfa,0x55, 0xad,0x76,0x6d,0xf6 +.byte 0x88,0xcc,0x76,0x91, 0xf5,0x02,0x4c,0x25 +.byte 0x4f,0xe5,0xd7,0xfc, 0xc5,0x2a,0xcb,0xd7 +.byte 0x26,0x35,0x44,0x80, 0xb5,0x62,0xa3,0x8f +.byte 0xde,0xb1,0x5a,0x49, 0x25,0xba,0x1b,0x67 +.byte 0x45,0xea,0x0e,0x98, 0x5d,0xfe,0xc0,0xe1 +.byte 0xc3,0x2f,0x75,0x02, 0x81,0x4c,0xf0,0x12 +.byte 0x8d,0x46,0x97,0xa3, 0x6b,0xd3,0xf9,0xc6 +.byte 0x03,0x8f,0x5f,0xe7, 0x15,0x92,0x9c,0x95 +.byte 0xbf,0x6d,0x7a,0xeb, 0x95,0x52,0x59,0xda +.byte 0xd4,0xbe,0x83,0x2d, 0x58,0x74,0x21,0xd3 +.byte 0x49,0xe0,0x69,0x29, 0x8e,0xc9,0xc8,0x44 +.byte 0x75,0xc2,0x89,0x6a, 0xf4,0x8e,0x79,0x78 +.byte 0x99,0x58,0x3e,0x6b, 0x27,0xb9,0x71,0xdd +.byte 0xbe,0xe1,0x4f,0xb6, 0xf0,0x88,0xad,0x17 +.byte 0xc9,0x20,0xac,0x66, 0x7d,0xce,0x3a,0xb4 +.byte 0x63,0xdf,0x4a,0x18, 0xe5,0x1a,0x31,0x82 +.byte 0x97,0x51,0x33,0x60, 0x62,0x53,0x7f,0x45 +.byte 0xb1,0x64,0x77,0xe0, 0xbb,0x6b,0xae,0x84 +.byte 0xfe,0x81,0xa0,0x1c, 0xf9,0x08,0x2b,0x94 +.byte 0x70,0x48,0x68,0x58, 0x8f,0x45,0xfd,0x19 +.byte 0x94,0xde,0x6c,0x87, 0x52,0x7b,0xf8,0xb7 +.byte 0xab,0x73,0xd3,0x23, 0x72,0x4b,0x02,0xe2 +.byte 0xe3,0x1f,0x8f,0x57, 0x66,0x55,0xab,0x2a +.byte 0xb2,0xeb,0x28,0x07, 0x2f,0xb5,0xc2,0x03 +.byte 0x86,0xc5,0x7b,0x9a, 0xd3,0x37,0x08,0xa5 +.byte 0x30,0x28,0x87,0xf2, 0x23,0xbf,0xa5,0xb2 +.byte 0x02,0x03,0x6a,0xba, 0xed,0x16,0x82,0x5c +.byte 0x8a,0xcf,0x1c,0x2b, 0xa7,0x79,0xb4,0x92 +.byte 0xf3,0x07,0xf2,0xf0, 0x4e,0x69,0xe2,0xa1 +.byte 0x65,0xda,0xf4,0xcd, 0x06,0x05,0xbe,0xd5 +.byte 0xd1,0x34,0x62,0x1f, 0xc4,0xa6,0xfe,0x8a +.byte 0x34,0x2e,0x53,0x9d, 0xa2,0xf3,0x55,0xa0 +.byte 0x05,0x8a,0xe1,0x32, 0xa4,0xf6,0xeb,0x75 +.byte 0x0b,0x83,0xec,0x39, 0x40,0x60,0xef,0xaa +.byte 0x5e,0x71,0x9f,0x06, 0xbd,0x6e,0x10,0x51 +.byte 0x3e,0x21,0x8a,0xf9, 0x96,0xdd,0x06,0x3d +.byte 0xdd,0x3e,0x05,0xae, 0x4d,0xe6,0xbd,0x46 +.byte 0x91,0x54,0x8d,0xb5, 0x71,0xc4,0x5d,0x05 +.byte 0x04,0x06,0xd4,0x6f, 0x60,0x50,0x15,0xff +.byte 0x19,0x98,0xfb,0x24, 0xd6,0xbd,0xe9,0x97 +.byte 0x89,0x40,0x43,0xcc, 0x67,0xd9,0x9e,0x77 +.byte 0xb0,0xe8,0x42,0xbd, 0x07,0x89,0x8b,0x88 +.byte 0xe7,0x19,0x5b,0x38, 0x79,0xc8,0xee,0xdb +.byte 0xa1,0x7c,0x0a,0x47, 0x7c,0x42,0x0f,0xe9 +.byte 0xf8,0x84,0x1e,0xc9, 0x00,0x00,0x00,0x00 +.byte 0x09,0x80,0x86,0x83, 0x32,0x2b,0xed,0x48 +.byte 0x1e,0x11,0x70,0xac, 0x6c,0x5a,0x72,0x4e +.byte 0xfd,0x0e,0xff,0xfb, 0x0f,0x85,0x38,0x56 +.byte 0x3d,0xae,0xd5,0x1e, 0x36,0x2d,0x39,0x27 +.byte 0x0a,0x0f,0xd9,0x64, 0x68,0x5c,0xa6,0x21 +.byte 0x9b,0x5b,0x54,0xd1, 0x24,0x36,0x2e,0x3a +.byte 0x0c,0x0a,0x67,0xb1, 0x93,0x57,0xe7,0x0f +.byte 0xb4,0xee,0x96,0xd2, 0x1b,0x9b,0x91,0x9e +.byte 0x80,0xc0,0xc5,0x4f, 0x61,0xdc,0x20,0xa2 +.byte 0x5a,0x77,0x4b,0x69, 0x1c,0x12,0x1a,0x16 +.byte 0xe2,0x93,0xba,0x0a, 0xc0,0xa0,0x2a,0xe5 +.byte 0x3c,0x22,0xe0,0x43, 0x12,0x1b,0x17,0x1d +.byte 0x0e,0x09,0x0d,0x0b, 0xf2,0x8b,0xc7,0xad +.byte 0x2d,0xb6,0xa8,0xb9, 0x14,0x1e,0xa9,0xc8 +.byte 0x57,0xf1,0x19,0x85, 0xaf,0x75,0x07,0x4c +.byte 0xee,0x99,0xdd,0xbb, 0xa3,0x7f,0x60,0xfd +.byte 0xf7,0x01,0x26,0x9f, 0x5c,0x72,0xf5,0xbc +.byte 0x44,0x66,0x3b,0xc5, 0x5b,0xfb,0x7e,0x34 +.byte 0x8b,0x43,0x29,0x76, 0xcb,0x23,0xc6,0xdc +.byte 0xb6,0xed,0xfc,0x68, 0xb8,0xe4,0xf1,0x63 +.byte 0xd7,0x31,0xdc,0xca, 0x42,0x63,0x85,0x10 +.byte 0x13,0x97,0x22,0x40, 0x84,0xc6,0x11,0x20 +.byte 0x85,0x4a,0x24,0x7d, 0xd2,0xbb,0x3d,0xf8 +.byte 0xae,0xf9,0x32,0x11, 0xc7,0x29,0xa1,0x6d +.byte 0x1d,0x9e,0x2f,0x4b, 0xdc,0xb2,0x30,0xf3 +.byte 0x0d,0x86,0x52,0xec, 0x77,0xc1,0xe3,0xd0 +.byte 0x2b,0xb3,0x16,0x6c, 0xa9,0x70,0xb9,0x99 +.byte 0x11,0x94,0x48,0xfa, 0x47,0xe9,0x64,0x22 +.byte 0xa8,0xfc,0x8c,0xc4, 0xa0,0xf0,0x3f,0x1a +.byte 0x56,0x7d,0x2c,0xd8, 0x22,0x33,0x90,0xef +.byte 0x87,0x49,0x4e,0xc7, 0xd9,0x38,0xd1,0xc1 +.byte 0x8c,0xca,0xa2,0xfe, 0x98,0xd4,0x0b,0x36 +.byte 0xa6,0xf5,0x81,0xcf, 0xa5,0x7a,0xde,0x28 +.byte 0xda,0xb7,0x8e,0x26, 0x3f,0xad,0xbf,0xa4 +.byte 0x2c,0x3a,0x9d,0xe4, 0x50,0x78,0x92,0x0d +.byte 0x6a,0x5f,0xcc,0x9b, 0x54,0x7e,0x46,0x62 +.byte 0xf6,0x8d,0x13,0xc2, 0x90,0xd8,0xb8,0xe8 +.byte 0x2e,0x39,0xf7,0x5e, 0x82,0xc3,0xaf,0xf5 +.byte 0x9f,0x5d,0x80,0xbe, 0x69,0xd0,0x93,0x7c +.byte 0x6f,0xd5,0x2d,0xa9, 0xcf,0x25,0x12,0xb3 +.byte 0xc8,0xac,0x99,0x3b, 0x10,0x18,0x7d,0xa7 +.byte 0xe8,0x9c,0x63,0x6e, 0xdb,0x3b,0xbb,0x7b +.byte 0xcd,0x26,0x78,0x09, 0x6e,0x59,0x18,0xf4 +.byte 0xec,0x9a,0xb7,0x01, 0x83,0x4f,0x9a,0xa8 +.byte 0xe6,0x95,0x6e,0x65, 0xaa,0xff,0xe6,0x7e +.byte 0x21,0xbc,0xcf,0x08, 0xef,0x15,0xe8,0xe6 +.byte 0xba,0xe7,0x9b,0xd9, 0x4a,0x6f,0x36,0xce +.byte 0xea,0x9f,0x09,0xd4, 0x29,0xb0,0x7c,0xd6 +.byte 0x31,0xa4,0xb2,0xaf, 0x2a,0x3f,0x23,0x31 +.byte 0xc6,0xa5,0x94,0x30, 0x35,0xa2,0x66,0xc0 +.byte 0x74,0x4e,0xbc,0x37, 0xfc,0x82,0xca,0xa6 +.byte 0xe0,0x90,0xd0,0xb0, 0x33,0xa7,0xd8,0x15 +.byte 0xf1,0x04,0x98,0x4a, 0x41,0xec,0xda,0xf7 +.byte 0x7f,0xcd,0x50,0x0e, 0x17,0x91,0xf6,0x2f +.byte 0x76,0x4d,0xd6,0x8d, 0x43,0xef,0xb0,0x4d +.byte 0xcc,0xaa,0x4d,0x54, 0xe4,0x96,0x04,0xdf +.byte 0x9e,0xd1,0xb5,0xe3, 0x4c,0x6a,0x88,0x1b +.byte 0xc1,0x2c,0x1f,0xb8, 0x46,0x65,0x51,0x7f +.byte 0x9d,0x5e,0xea,0x04, 0x01,0x8c,0x35,0x5d +.byte 0xfa,0x87,0x74,0x73, 0xfb,0x0b,0x41,0x2e +.byte 0xb3,0x67,0x1d,0x5a, 0x92,0xdb,0xd2,0x52 +.byte 0xe9,0x10,0x56,0x33, 0x6d,0xd6,0x47,0x13 +.byte 0x9a,0xd7,0x61,0x8c, 0x37,0xa1,0x0c,0x7a +.byte 0x59,0xf8,0x14,0x8e, 0xeb,0x13,0x3c,0x89 +.byte 0xce,0xa9,0x27,0xee, 0xb7,0x61,0xc9,0x35 +.byte 0xe1,0x1c,0xe5,0xed, 0x7a,0x47,0xb1,0x3c +.byte 0x9c,0xd2,0xdf,0x59, 0x55,0xf2,0x73,0x3f +.byte 0x18,0x14,0xce,0x79, 0x73,0xc7,0x37,0xbf +.byte 0x53,0xf7,0xcd,0xea, 0x5f,0xfd,0xaa,0x5b +.byte 0xdf,0x3d,0x6f,0x14, 0x78,0x44,0xdb,0x86 +.byte 0xca,0xaf,0xf3,0x81, 0xb9,0x68,0xc4,0x3e +.byte 0x38,0x24,0x34,0x2c, 0xc2,0xa3,0x40,0x5f +.byte 0x16,0x1d,0xc3,0x72, 0xbc,0xe2,0x25,0x0c +.byte 0x28,0x3c,0x49,0x8b, 0xff,0x0d,0x95,0x41 +.byte 0x39,0xa8,0x01,0x71, 0x08,0x0c,0xb3,0xde +.byte 0xd8,0xb4,0xe4,0x9c, 0x64,0x56,0xc1,0x90 +.byte 0x7b,0xcb,0x84,0x61, 0xd5,0x32,0xb6,0x70 +.byte 0x48,0x6c,0x5c,0x74, 0xd0,0xb8,0x57,0x42 + +.byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38 # Td4 +.byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb +.byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87 +.byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb +.byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d +.byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e +.byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2 +.byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 +.byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16 +.byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 +.byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda +.byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 +.byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a +.byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 +.byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02 +.byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b +.byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea +.byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 +.byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85 +.byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e +.byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89 +.byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b +.byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20 +.byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 +.byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31 +.byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f +.byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d +.byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef +.byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0 +.byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 +.byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26 +.byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +___ + +foreach (split("\n",$code)) { + s/\`([^\`]*)\`/eval $1/ge; + + # made-up _instructions, _xtr, _ins, _ror and _bias, cope + # with byte order dependencies... + if (/^\s+_/) { + s/(_[a-z]+\s+)(\$[0-9]+),([^,]+)(#.*)*$/$1$2,$2,$3/; + + s/_xtr\s+(\$[0-9]+),(\$[0-9]+),([0-9]+(\-2)*)/ + sprintf("srl\t$1,$2,%d",$big_endian ? eval($3) + : eval("24-$3"))/e or + s/_ins\s+(\$[0-9]+),(\$[0-9]+),([0-9]+)/ + sprintf("sll\t$1,$2,%d",$big_endian ? eval($3) + : eval("24-$3"))/e or + s/_ror\s+(\$[0-9]+),(\$[0-9]+),(\-?[0-9]+)/ + sprintf("srl\t$1,$2,%d",$big_endian ? eval($3) + : eval("$3*-1"))/e or + s/_bias\s+(\$[0-9]+),(\$[0-9]+),([0-9]+)/ + sprintf("sll\t$1,$2,%d",$big_endian ? eval($3) + : eval("($3-16)&31"))/e; + + s/srl\s+(\$[0-9]+),(\$[0-9]+),\-([0-9]+)/ + sprintf("sll\t$1,$2,$3")/e or + s/srl\s+(\$[0-9]+),(\$[0-9]+),0/ + sprintf("and\t$1,$2,0xff")/e or + s/(sll\s+\$[0-9]+,\$[0-9]+,0)/#$1/; + } + + # convert lwl/lwr and swr/swl to little-endian order + if (!$big_endian && /^\s+[sl]w[lr]\s+/) { + s/([sl]wl.*)([0-9]+)\((\$[0-9]+)\)/ + sprintf("$1%d($3)",eval("$2-$2%4+($2%4-1)&3"))/e or + s/([sl]wr.*)([0-9]+)\((\$[0-9]+)\)/ + sprintf("$1%d($3)",eval("$2-$2%4+($2%4+1)&3"))/e; + } + + print $_,"\n"; +} + +close STDOUT; diff --git a/libs/openssl/crypto/aes/asm/aes-parisc.pl b/libs/openssl/crypto/aes/asm/aes-parisc.pl new file mode 100644 index 00000000..714dcfbb --- /dev/null +++ b/libs/openssl/crypto/aes/asm/aes-parisc.pl @@ -0,0 +1,1022 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# AES for PA-RISC. +# +# June 2009. +# +# The module is mechanical transliteration of aes-sparcv9.pl, but with +# a twist: S-boxes are compressed even further down to 1K+256B. On +# PA-7100LC performance is ~40% better than gcc 3.2 generated code and +# is about 33 cycles per byte processed with 128-bit key. Newer CPUs +# perform at 16 cycles per byte. It's not faster than code generated +# by vendor compiler, but recall that it has compressed S-boxes, which +# requires extra processing. +# +# Special thanks to polarhome.com for providing HP-UX account. + +$flavour = shift; +$output = shift; +open STDOUT,">$output"; + +if ($flavour =~ /64/) { + $LEVEL ="2.0W"; + $SIZE_T =8; + $FRAME_MARKER =80; + $SAVED_RP =16; + $PUSH ="std"; + $PUSHMA ="std,ma"; + $POP ="ldd"; + $POPMB ="ldd,mb"; +} else { + $LEVEL ="1.0"; + $SIZE_T =4; + $FRAME_MARKER =48; + $SAVED_RP =20; + $PUSH ="stw"; + $PUSHMA ="stwm"; + $POP ="ldw"; + $POPMB ="ldwm"; +} + +$FRAME=16*$SIZE_T+$FRAME_MARKER;# 16 saved regs + frame marker + # [+ argument transfer] +$inp="%r26"; # arg0 +$out="%r25"; # arg1 +$key="%r24"; # arg2 + +($s0,$s1,$s2,$s3) = ("%r1","%r2","%r3","%r4"); +($t0,$t1,$t2,$t3) = ("%r5","%r6","%r7","%r8"); + +($acc0, $acc1, $acc2, $acc3, $acc4, $acc5, $acc6, $acc7, + $acc8, $acc9,$acc10,$acc11,$acc12,$acc13,$acc14,$acc15) = +("%r9","%r10","%r11","%r12","%r13","%r14","%r15","%r16", +"%r17","%r18","%r19","%r20","%r21","%r22","%r23","%r26"); + +$tbl="%r28"; +$rounds="%r29"; + +$code=<<___; + .LEVEL $LEVEL + .SPACE \$TEXT\$ + .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY + + .EXPORT AES_encrypt,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR + .ALIGN 64 +AES_encrypt + .PROC + .CALLINFO FRAME=`$FRAME-16*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=18 + .ENTRY + $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue + $PUSHMA %r3,$FRAME(%sp) + $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp) + $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp) + $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp) + $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp) + $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp) + $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp) + $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp) + $PUSH %r11,`-$FRAME+8*$SIZE_T`(%sp) + $PUSH %r12,`-$FRAME+9*$SIZE_T`(%sp) + $PUSH %r13,`-$FRAME+10*$SIZE_T`(%sp) + $PUSH %r14,`-$FRAME+11*$SIZE_T`(%sp) + $PUSH %r15,`-$FRAME+12*$SIZE_T`(%sp) + $PUSH %r16,`-$FRAME+13*$SIZE_T`(%sp) + $PUSH %r17,`-$FRAME+14*$SIZE_T`(%sp) + $PUSH %r18,`-$FRAME+15*$SIZE_T`(%sp) + + blr %r0,$tbl + ldi 3,$t0 +L\$enc_pic + andcm $tbl,$t0,$tbl + ldo L\$AES_Te-L\$enc_pic($tbl),$tbl + + and $inp,$t0,$t0 + sub $inp,$t0,$inp + ldw 0($inp),$s0 + ldw 4($inp),$s1 + ldw 8($inp),$s2 + comib,= 0,$t0,L\$enc_inp_aligned + ldw 12($inp),$s3 + + sh3addl $t0,%r0,$t0 + subi 32,$t0,$t0 + mtctl $t0,%cr11 + ldw 16($inp),$t1 + vshd $s0,$s1,$s0 + vshd $s1,$s2,$s1 + vshd $s2,$s3,$s2 + vshd $s3,$t1,$s3 + +L\$enc_inp_aligned + bl _parisc_AES_encrypt,%r31 + nop + + extru,<> $out,31,2,%r0 + b L\$enc_out_aligned + nop + + _srm $s0,24,$acc0 + _srm $s0,16,$acc1 + stb $acc0,0($out) + _srm $s0,8,$acc2 + stb $acc1,1($out) + _srm $s1,24,$acc4 + stb $acc2,2($out) + _srm $s1,16,$acc5 + stb $s0,3($out) + _srm $s1,8,$acc6 + stb $acc4,4($out) + _srm $s2,24,$acc0 + stb $acc5,5($out) + _srm $s2,16,$acc1 + stb $acc6,6($out) + _srm $s2,8,$acc2 + stb $s1,7($out) + _srm $s3,24,$acc4 + stb $acc0,8($out) + _srm $s3,16,$acc5 + stb $acc1,9($out) + _srm $s3,8,$acc6 + stb $acc2,10($out) + stb $s2,11($out) + stb $acc4,12($out) + stb $acc5,13($out) + stb $acc6,14($out) + b L\$enc_done + stb $s3,15($out) + +L\$enc_out_aligned + stw $s0,0($out) + stw $s1,4($out) + stw $s2,8($out) + stw $s3,12($out) + +L\$enc_done + $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue + $POP `-$FRAME+1*$SIZE_T`(%sp),%r4 + $POP `-$FRAME+2*$SIZE_T`(%sp),%r5 + $POP `-$FRAME+3*$SIZE_T`(%sp),%r6 + $POP `-$FRAME+4*$SIZE_T`(%sp),%r7 + $POP `-$FRAME+5*$SIZE_T`(%sp),%r8 + $POP `-$FRAME+6*$SIZE_T`(%sp),%r9 + $POP `-$FRAME+7*$SIZE_T`(%sp),%r10 + $POP `-$FRAME+8*$SIZE_T`(%sp),%r11 + $POP `-$FRAME+9*$SIZE_T`(%sp),%r12 + $POP `-$FRAME+10*$SIZE_T`(%sp),%r13 + $POP `-$FRAME+11*$SIZE_T`(%sp),%r14 + $POP `-$FRAME+12*$SIZE_T`(%sp),%r15 + $POP `-$FRAME+13*$SIZE_T`(%sp),%r16 + $POP `-$FRAME+14*$SIZE_T`(%sp),%r17 + $POP `-$FRAME+15*$SIZE_T`(%sp),%r18 + bv (%r2) + .EXIT + $POPMB -$FRAME(%sp),%r3 + .PROCEND + + .ALIGN 16 +_parisc_AES_encrypt + .PROC + .CALLINFO MILLICODE + .ENTRY + ldw 240($key),$rounds + ldw 0($key),$t0 + ldw 4($key),$t1 + ldw 8($key),$t2 + _srm $rounds,1,$rounds + xor $t0,$s0,$s0 + ldw 12($key),$t3 + _srm $s0,24,$acc0 + xor $t1,$s1,$s1 + ldw 16($key),$t0 + _srm $s1,16,$acc1 + xor $t2,$s2,$s2 + ldw 20($key),$t1 + xor $t3,$s3,$s3 + ldw 24($key),$t2 + ldw 28($key),$t3 +L\$enc_loop + _srm $s2,8,$acc2 + ldwx,s $acc0($tbl),$acc0 + _srm $s3,0,$acc3 + ldwx,s $acc1($tbl),$acc1 + _srm $s1,24,$acc4 + ldwx,s $acc2($tbl),$acc2 + _srm $s2,16,$acc5 + ldwx,s $acc3($tbl),$acc3 + _srm $s3,8,$acc6 + ldwx,s $acc4($tbl),$acc4 + _srm $s0,0,$acc7 + ldwx,s $acc5($tbl),$acc5 + _srm $s2,24,$acc8 + ldwx,s $acc6($tbl),$acc6 + _srm $s3,16,$acc9 + ldwx,s $acc7($tbl),$acc7 + _srm $s0,8,$acc10 + ldwx,s $acc8($tbl),$acc8 + _srm $s1,0,$acc11 + ldwx,s $acc9($tbl),$acc9 + _srm $s3,24,$acc12 + ldwx,s $acc10($tbl),$acc10 + _srm $s0,16,$acc13 + ldwx,s $acc11($tbl),$acc11 + _srm $s1,8,$acc14 + ldwx,s $acc12($tbl),$acc12 + _srm $s2,0,$acc15 + ldwx,s $acc13($tbl),$acc13 + ldwx,s $acc14($tbl),$acc14 + ldwx,s $acc15($tbl),$acc15 + addib,= -1,$rounds,L\$enc_last + ldo 32($key),$key + + _ror $acc1,8,$acc1 + xor $acc0,$t0,$t0 + ldw 0($key),$s0 + _ror $acc2,16,$acc2 + xor $acc1,$t0,$t0 + ldw 4($key),$s1 + _ror $acc3,24,$acc3 + xor $acc2,$t0,$t0 + ldw 8($key),$s2 + _ror $acc5,8,$acc5 + xor $acc3,$t0,$t0 + ldw 12($key),$s3 + _ror $acc6,16,$acc6 + xor $acc4,$t1,$t1 + _ror $acc7,24,$acc7 + xor $acc5,$t1,$t1 + _ror $acc9,8,$acc9 + xor $acc6,$t1,$t1 + _ror $acc10,16,$acc10 + xor $acc7,$t1,$t1 + _ror $acc11,24,$acc11 + xor $acc8,$t2,$t2 + _ror $acc13,8,$acc13 + xor $acc9,$t2,$t2 + _ror $acc14,16,$acc14 + xor $acc10,$t2,$t2 + _ror $acc15,24,$acc15 + xor $acc11,$t2,$t2 + xor $acc12,$acc14,$acc14 + xor $acc13,$t3,$t3 + _srm $t0,24,$acc0 + xor $acc14,$t3,$t3 + _srm $t1,16,$acc1 + xor $acc15,$t3,$t3 + + _srm $t2,8,$acc2 + ldwx,s $acc0($tbl),$acc0 + _srm $t3,0,$acc3 + ldwx,s $acc1($tbl),$acc1 + _srm $t1,24,$acc4 + ldwx,s $acc2($tbl),$acc2 + _srm $t2,16,$acc5 + ldwx,s $acc3($tbl),$acc3 + _srm $t3,8,$acc6 + ldwx,s $acc4($tbl),$acc4 + _srm $t0,0,$acc7 + ldwx,s $acc5($tbl),$acc5 + _srm $t2,24,$acc8 + ldwx,s $acc6($tbl),$acc6 + _srm $t3,16,$acc9 + ldwx,s $acc7($tbl),$acc7 + _srm $t0,8,$acc10 + ldwx,s $acc8($tbl),$acc8 + _srm $t1,0,$acc11 + ldwx,s $acc9($tbl),$acc9 + _srm $t3,24,$acc12 + ldwx,s $acc10($tbl),$acc10 + _srm $t0,16,$acc13 + ldwx,s $acc11($tbl),$acc11 + _srm $t1,8,$acc14 + ldwx,s $acc12($tbl),$acc12 + _srm $t2,0,$acc15 + ldwx,s $acc13($tbl),$acc13 + _ror $acc1,8,$acc1 + ldwx,s $acc14($tbl),$acc14 + + _ror $acc2,16,$acc2 + xor $acc0,$s0,$s0 + ldwx,s $acc15($tbl),$acc15 + _ror $acc3,24,$acc3 + xor $acc1,$s0,$s0 + ldw 16($key),$t0 + _ror $acc5,8,$acc5 + xor $acc2,$s0,$s0 + ldw 20($key),$t1 + _ror $acc6,16,$acc6 + xor $acc3,$s0,$s0 + ldw 24($key),$t2 + _ror $acc7,24,$acc7 + xor $acc4,$s1,$s1 + ldw 28($key),$t3 + _ror $acc9,8,$acc9 + xor $acc5,$s1,$s1 + ldw 1024+0($tbl),%r0 ; prefetch te4 + _ror $acc10,16,$acc10 + xor $acc6,$s1,$s1 + ldw 1024+32($tbl),%r0 ; prefetch te4 + _ror $acc11,24,$acc11 + xor $acc7,$s1,$s1 + ldw 1024+64($tbl),%r0 ; prefetch te4 + _ror $acc13,8,$acc13 + xor $acc8,$s2,$s2 + ldw 1024+96($tbl),%r0 ; prefetch te4 + _ror $acc14,16,$acc14 + xor $acc9,$s2,$s2 + ldw 1024+128($tbl),%r0 ; prefetch te4 + _ror $acc15,24,$acc15 + xor $acc10,$s2,$s2 + ldw 1024+160($tbl),%r0 ; prefetch te4 + _srm $s0,24,$acc0 + xor $acc11,$s2,$s2 + ldw 1024+192($tbl),%r0 ; prefetch te4 + xor $acc12,$acc14,$acc14 + xor $acc13,$s3,$s3 + ldw 1024+224($tbl),%r0 ; prefetch te4 + _srm $s1,16,$acc1 + xor $acc14,$s3,$s3 + b L\$enc_loop + xor $acc15,$s3,$s3 + + .ALIGN 16 +L\$enc_last + ldo 1024($tbl),$rounds + _ror $acc1,8,$acc1 + xor $acc0,$t0,$t0 + ldw 0($key),$s0 + _ror $acc2,16,$acc2 + xor $acc1,$t0,$t0 + ldw 4($key),$s1 + _ror $acc3,24,$acc3 + xor $acc2,$t0,$t0 + ldw 8($key),$s2 + _ror $acc5,8,$acc5 + xor $acc3,$t0,$t0 + ldw 12($key),$s3 + _ror $acc6,16,$acc6 + xor $acc4,$t1,$t1 + _ror $acc7,24,$acc7 + xor $acc5,$t1,$t1 + _ror $acc9,8,$acc9 + xor $acc6,$t1,$t1 + _ror $acc10,16,$acc10 + xor $acc7,$t1,$t1 + _ror $acc11,24,$acc11 + xor $acc8,$t2,$t2 + _ror $acc13,8,$acc13 + xor $acc9,$t2,$t2 + _ror $acc14,16,$acc14 + xor $acc10,$t2,$t2 + _ror $acc15,24,$acc15 + xor $acc11,$t2,$t2 + xor $acc12,$acc14,$acc14 + xor $acc13,$t3,$t3 + _srm $t0,24,$acc0 + xor $acc14,$t3,$t3 + _srm $t1,16,$acc1 + xor $acc15,$t3,$t3 + + _srm $t2,8,$acc2 + ldbx $acc0($rounds),$acc0 + _srm $t1,24,$acc4 + ldbx $acc1($rounds),$acc1 + _srm $t2,16,$acc5 + _srm $t3,0,$acc3 + ldbx $acc2($rounds),$acc2 + ldbx $acc3($rounds),$acc3 + _srm $t3,8,$acc6 + ldbx $acc4($rounds),$acc4 + _srm $t2,24,$acc8 + ldbx $acc5($rounds),$acc5 + _srm $t3,16,$acc9 + _srm $t0,0,$acc7 + ldbx $acc6($rounds),$acc6 + ldbx $acc7($rounds),$acc7 + _srm $t0,8,$acc10 + ldbx $acc8($rounds),$acc8 + _srm $t3,24,$acc12 + ldbx $acc9($rounds),$acc9 + _srm $t0,16,$acc13 + _srm $t1,0,$acc11 + ldbx $acc10($rounds),$acc10 + _srm $t1,8,$acc14 + ldbx $acc11($rounds),$acc11 + ldbx $acc12($rounds),$acc12 + ldbx $acc13($rounds),$acc13 + _srm $t2,0,$acc15 + ldbx $acc14($rounds),$acc14 + + dep $acc0,7,8,$acc3 + ldbx $acc15($rounds),$acc15 + dep $acc4,7,8,$acc7 + dep $acc1,15,8,$acc3 + dep $acc5,15,8,$acc7 + dep $acc2,23,8,$acc3 + dep $acc6,23,8,$acc7 + xor $acc3,$s0,$s0 + xor $acc7,$s1,$s1 + dep $acc8,7,8,$acc11 + dep $acc12,7,8,$acc15 + dep $acc9,15,8,$acc11 + dep $acc13,15,8,$acc15 + dep $acc10,23,8,$acc11 + dep $acc14,23,8,$acc15 + xor $acc11,$s2,$s2 + + bv (%r31) + .EXIT + xor $acc15,$s3,$s3 + .PROCEND + + .ALIGN 64 +L\$AES_Te + .WORD 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d + .WORD 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554 + .WORD 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d + .WORD 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a + .WORD 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87 + .WORD 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b + .WORD 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea + .WORD 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b + .WORD 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a + .WORD 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f + .WORD 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108 + .WORD 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f + .WORD 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e + .WORD 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5 + .WORD 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d + .WORD 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f + .WORD 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e + .WORD 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb + .WORD 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce + .WORD 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497 + .WORD 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c + .WORD 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed + .WORD 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b + .WORD 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a + .WORD 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16 + .WORD 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594 + .WORD 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81 + .WORD 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3 + .WORD 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a + .WORD 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504 + .WORD 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163 + .WORD 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d + .WORD 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f + .WORD 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739 + .WORD 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47 + .WORD 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395 + .WORD 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f + .WORD 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883 + .WORD 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c + .WORD 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76 + .WORD 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e + .WORD 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4 + .WORD 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6 + .WORD 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b + .WORD 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7 + .WORD 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0 + .WORD 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25 + .WORD 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818 + .WORD 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72 + .WORD 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651 + .WORD 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21 + .WORD 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85 + .WORD 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa + .WORD 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12 + .WORD 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0 + .WORD 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9 + .WORD 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133 + .WORD 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7 + .WORD 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920 + .WORD 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a + .WORD 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17 + .WORD 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8 + .WORD 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11 + .WORD 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a + .BYTE 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5 + .BYTE 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 + .BYTE 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0 + .BYTE 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 + .BYTE 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc + .BYTE 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 + .BYTE 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a + .BYTE 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 + .BYTE 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0 + .BYTE 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 + .BYTE 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b + .BYTE 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf + .BYTE 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85 + .BYTE 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 + .BYTE 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5 + .BYTE 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 + .BYTE 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17 + .BYTE 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 + .BYTE 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88 + .BYTE 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb + .BYTE 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c + .BYTE 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 + .BYTE 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9 + .BYTE 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 + .BYTE 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6 + .BYTE 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a + .BYTE 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e + .BYTE 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e + .BYTE 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94 + .BYTE 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf + .BYTE 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68 + .BYTE 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +___ + +$code.=<<___; + .EXPORT AES_decrypt,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR + .ALIGN 16 +AES_decrypt + .PROC + .CALLINFO FRAME=`$FRAME-16*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=18 + .ENTRY + $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue + $PUSHMA %r3,$FRAME(%sp) + $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp) + $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp) + $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp) + $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp) + $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp) + $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp) + $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp) + $PUSH %r11,`-$FRAME+8*$SIZE_T`(%sp) + $PUSH %r12,`-$FRAME+9*$SIZE_T`(%sp) + $PUSH %r13,`-$FRAME+10*$SIZE_T`(%sp) + $PUSH %r14,`-$FRAME+11*$SIZE_T`(%sp) + $PUSH %r15,`-$FRAME+12*$SIZE_T`(%sp) + $PUSH %r16,`-$FRAME+13*$SIZE_T`(%sp) + $PUSH %r17,`-$FRAME+14*$SIZE_T`(%sp) + $PUSH %r18,`-$FRAME+15*$SIZE_T`(%sp) + + blr %r0,$tbl + ldi 3,$t0 +L\$dec_pic + andcm $tbl,$t0,$tbl + ldo L\$AES_Td-L\$dec_pic($tbl),$tbl + + and $inp,$t0,$t0 + sub $inp,$t0,$inp + ldw 0($inp),$s0 + ldw 4($inp),$s1 + ldw 8($inp),$s2 + comib,= 0,$t0,L\$dec_inp_aligned + ldw 12($inp),$s3 + + sh3addl $t0,%r0,$t0 + subi 32,$t0,$t0 + mtctl $t0,%cr11 + ldw 16($inp),$t1 + vshd $s0,$s1,$s0 + vshd $s1,$s2,$s1 + vshd $s2,$s3,$s2 + vshd $s3,$t1,$s3 + +L\$dec_inp_aligned + bl _parisc_AES_decrypt,%r31 + nop + + extru,<> $out,31,2,%r0 + b L\$dec_out_aligned + nop + + _srm $s0,24,$acc0 + _srm $s0,16,$acc1 + stb $acc0,0($out) + _srm $s0,8,$acc2 + stb $acc1,1($out) + _srm $s1,24,$acc4 + stb $acc2,2($out) + _srm $s1,16,$acc5 + stb $s0,3($out) + _srm $s1,8,$acc6 + stb $acc4,4($out) + _srm $s2,24,$acc0 + stb $acc5,5($out) + _srm $s2,16,$acc1 + stb $acc6,6($out) + _srm $s2,8,$acc2 + stb $s1,7($out) + _srm $s3,24,$acc4 + stb $acc0,8($out) + _srm $s3,16,$acc5 + stb $acc1,9($out) + _srm $s3,8,$acc6 + stb $acc2,10($out) + stb $s2,11($out) + stb $acc4,12($out) + stb $acc5,13($out) + stb $acc6,14($out) + b L\$dec_done + stb $s3,15($out) + +L\$dec_out_aligned + stw $s0,0($out) + stw $s1,4($out) + stw $s2,8($out) + stw $s3,12($out) + +L\$dec_done + $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue + $POP `-$FRAME+1*$SIZE_T`(%sp),%r4 + $POP `-$FRAME+2*$SIZE_T`(%sp),%r5 + $POP `-$FRAME+3*$SIZE_T`(%sp),%r6 + $POP `-$FRAME+4*$SIZE_T`(%sp),%r7 + $POP `-$FRAME+5*$SIZE_T`(%sp),%r8 + $POP `-$FRAME+6*$SIZE_T`(%sp),%r9 + $POP `-$FRAME+7*$SIZE_T`(%sp),%r10 + $POP `-$FRAME+8*$SIZE_T`(%sp),%r11 + $POP `-$FRAME+9*$SIZE_T`(%sp),%r12 + $POP `-$FRAME+10*$SIZE_T`(%sp),%r13 + $POP `-$FRAME+11*$SIZE_T`(%sp),%r14 + $POP `-$FRAME+12*$SIZE_T`(%sp),%r15 + $POP `-$FRAME+13*$SIZE_T`(%sp),%r16 + $POP `-$FRAME+14*$SIZE_T`(%sp),%r17 + $POP `-$FRAME+15*$SIZE_T`(%sp),%r18 + bv (%r2) + .EXIT + $POPMB -$FRAME(%sp),%r3 + .PROCEND + + .ALIGN 16 +_parisc_AES_decrypt + .PROC + .CALLINFO MILLICODE + .ENTRY + ldw 240($key),$rounds + ldw 0($key),$t0 + ldw 4($key),$t1 + ldw 8($key),$t2 + ldw 12($key),$t3 + _srm $rounds,1,$rounds + xor $t0,$s0,$s0 + ldw 16($key),$t0 + xor $t1,$s1,$s1 + ldw 20($key),$t1 + _srm $s0,24,$acc0 + xor $t2,$s2,$s2 + ldw 24($key),$t2 + xor $t3,$s3,$s3 + ldw 28($key),$t3 + _srm $s3,16,$acc1 +L\$dec_loop + _srm $s2,8,$acc2 + ldwx,s $acc0($tbl),$acc0 + _srm $s1,0,$acc3 + ldwx,s $acc1($tbl),$acc1 + _srm $s1,24,$acc4 + ldwx,s $acc2($tbl),$acc2 + _srm $s0,16,$acc5 + ldwx,s $acc3($tbl),$acc3 + _srm $s3,8,$acc6 + ldwx,s $acc4($tbl),$acc4 + _srm $s2,0,$acc7 + ldwx,s $acc5($tbl),$acc5 + _srm $s2,24,$acc8 + ldwx,s $acc6($tbl),$acc6 + _srm $s1,16,$acc9 + ldwx,s $acc7($tbl),$acc7 + _srm $s0,8,$acc10 + ldwx,s $acc8($tbl),$acc8 + _srm $s3,0,$acc11 + ldwx,s $acc9($tbl),$acc9 + _srm $s3,24,$acc12 + ldwx,s $acc10($tbl),$acc10 + _srm $s2,16,$acc13 + ldwx,s $acc11($tbl),$acc11 + _srm $s1,8,$acc14 + ldwx,s $acc12($tbl),$acc12 + _srm $s0,0,$acc15 + ldwx,s $acc13($tbl),$acc13 + ldwx,s $acc14($tbl),$acc14 + ldwx,s $acc15($tbl),$acc15 + addib,= -1,$rounds,L\$dec_last + ldo 32($key),$key + + _ror $acc1,8,$acc1 + xor $acc0,$t0,$t0 + ldw 0($key),$s0 + _ror $acc2,16,$acc2 + xor $acc1,$t0,$t0 + ldw 4($key),$s1 + _ror $acc3,24,$acc3 + xor $acc2,$t0,$t0 + ldw 8($key),$s2 + _ror $acc5,8,$acc5 + xor $acc3,$t0,$t0 + ldw 12($key),$s3 + _ror $acc6,16,$acc6 + xor $acc4,$t1,$t1 + _ror $acc7,24,$acc7 + xor $acc5,$t1,$t1 + _ror $acc9,8,$acc9 + xor $acc6,$t1,$t1 + _ror $acc10,16,$acc10 + xor $acc7,$t1,$t1 + _ror $acc11,24,$acc11 + xor $acc8,$t2,$t2 + _ror $acc13,8,$acc13 + xor $acc9,$t2,$t2 + _ror $acc14,16,$acc14 + xor $acc10,$t2,$t2 + _ror $acc15,24,$acc15 + xor $acc11,$t2,$t2 + xor $acc12,$acc14,$acc14 + xor $acc13,$t3,$t3 + _srm $t0,24,$acc0 + xor $acc14,$t3,$t3 + xor $acc15,$t3,$t3 + _srm $t3,16,$acc1 + + _srm $t2,8,$acc2 + ldwx,s $acc0($tbl),$acc0 + _srm $t1,0,$acc3 + ldwx,s $acc1($tbl),$acc1 + _srm $t1,24,$acc4 + ldwx,s $acc2($tbl),$acc2 + _srm $t0,16,$acc5 + ldwx,s $acc3($tbl),$acc3 + _srm $t3,8,$acc6 + ldwx,s $acc4($tbl),$acc4 + _srm $t2,0,$acc7 + ldwx,s $acc5($tbl),$acc5 + _srm $t2,24,$acc8 + ldwx,s $acc6($tbl),$acc6 + _srm $t1,16,$acc9 + ldwx,s $acc7($tbl),$acc7 + _srm $t0,8,$acc10 + ldwx,s $acc8($tbl),$acc8 + _srm $t3,0,$acc11 + ldwx,s $acc9($tbl),$acc9 + _srm $t3,24,$acc12 + ldwx,s $acc10($tbl),$acc10 + _srm $t2,16,$acc13 + ldwx,s $acc11($tbl),$acc11 + _srm $t1,8,$acc14 + ldwx,s $acc12($tbl),$acc12 + _srm $t0,0,$acc15 + ldwx,s $acc13($tbl),$acc13 + _ror $acc1,8,$acc1 + ldwx,s $acc14($tbl),$acc14 + + _ror $acc2,16,$acc2 + xor $acc0,$s0,$s0 + ldwx,s $acc15($tbl),$acc15 + _ror $acc3,24,$acc3 + xor $acc1,$s0,$s0 + ldw 16($key),$t0 + _ror $acc5,8,$acc5 + xor $acc2,$s0,$s0 + ldw 20($key),$t1 + _ror $acc6,16,$acc6 + xor $acc3,$s0,$s0 + ldw 24($key),$t2 + _ror $acc7,24,$acc7 + xor $acc4,$s1,$s1 + ldw 28($key),$t3 + _ror $acc9,8,$acc9 + xor $acc5,$s1,$s1 + ldw 1024+0($tbl),%r0 ; prefetch td4 + _ror $acc10,16,$acc10 + xor $acc6,$s1,$s1 + ldw 1024+32($tbl),%r0 ; prefetch td4 + _ror $acc11,24,$acc11 + xor $acc7,$s1,$s1 + ldw 1024+64($tbl),%r0 ; prefetch td4 + _ror $acc13,8,$acc13 + xor $acc8,$s2,$s2 + ldw 1024+96($tbl),%r0 ; prefetch td4 + _ror $acc14,16,$acc14 + xor $acc9,$s2,$s2 + ldw 1024+128($tbl),%r0 ; prefetch td4 + _ror $acc15,24,$acc15 + xor $acc10,$s2,$s2 + ldw 1024+160($tbl),%r0 ; prefetch td4 + _srm $s0,24,$acc0 + xor $acc11,$s2,$s2 + ldw 1024+192($tbl),%r0 ; prefetch td4 + xor $acc12,$acc14,$acc14 + xor $acc13,$s3,$s3 + ldw 1024+224($tbl),%r0 ; prefetch td4 + xor $acc14,$s3,$s3 + xor $acc15,$s3,$s3 + b L\$dec_loop + _srm $s3,16,$acc1 + + .ALIGN 16 +L\$dec_last + ldo 1024($tbl),$rounds + _ror $acc1,8,$acc1 + xor $acc0,$t0,$t0 + ldw 0($key),$s0 + _ror $acc2,16,$acc2 + xor $acc1,$t0,$t0 + ldw 4($key),$s1 + _ror $acc3,24,$acc3 + xor $acc2,$t0,$t0 + ldw 8($key),$s2 + _ror $acc5,8,$acc5 + xor $acc3,$t0,$t0 + ldw 12($key),$s3 + _ror $acc6,16,$acc6 + xor $acc4,$t1,$t1 + _ror $acc7,24,$acc7 + xor $acc5,$t1,$t1 + _ror $acc9,8,$acc9 + xor $acc6,$t1,$t1 + _ror $acc10,16,$acc10 + xor $acc7,$t1,$t1 + _ror $acc11,24,$acc11 + xor $acc8,$t2,$t2 + _ror $acc13,8,$acc13 + xor $acc9,$t2,$t2 + _ror $acc14,16,$acc14 + xor $acc10,$t2,$t2 + _ror $acc15,24,$acc15 + xor $acc11,$t2,$t2 + xor $acc12,$acc14,$acc14 + xor $acc13,$t3,$t3 + _srm $t0,24,$acc0 + xor $acc14,$t3,$t3 + xor $acc15,$t3,$t3 + _srm $t3,16,$acc1 + + _srm $t2,8,$acc2 + ldbx $acc0($rounds),$acc0 + _srm $t1,24,$acc4 + ldbx $acc1($rounds),$acc1 + _srm $t0,16,$acc5 + _srm $t1,0,$acc3 + ldbx $acc2($rounds),$acc2 + ldbx $acc3($rounds),$acc3 + _srm $t3,8,$acc6 + ldbx $acc4($rounds),$acc4 + _srm $t2,24,$acc8 + ldbx $acc5($rounds),$acc5 + _srm $t1,16,$acc9 + _srm $t2,0,$acc7 + ldbx $acc6($rounds),$acc6 + ldbx $acc7($rounds),$acc7 + _srm $t0,8,$acc10 + ldbx $acc8($rounds),$acc8 + _srm $t3,24,$acc12 + ldbx $acc9($rounds),$acc9 + _srm $t2,16,$acc13 + _srm $t3,0,$acc11 + ldbx $acc10($rounds),$acc10 + _srm $t1,8,$acc14 + ldbx $acc11($rounds),$acc11 + ldbx $acc12($rounds),$acc12 + ldbx $acc13($rounds),$acc13 + _srm $t0,0,$acc15 + ldbx $acc14($rounds),$acc14 + + dep $acc0,7,8,$acc3 + ldbx $acc15($rounds),$acc15 + dep $acc4,7,8,$acc7 + dep $acc1,15,8,$acc3 + dep $acc5,15,8,$acc7 + dep $acc2,23,8,$acc3 + dep $acc6,23,8,$acc7 + xor $acc3,$s0,$s0 + xor $acc7,$s1,$s1 + dep $acc8,7,8,$acc11 + dep $acc12,7,8,$acc15 + dep $acc9,15,8,$acc11 + dep $acc13,15,8,$acc15 + dep $acc10,23,8,$acc11 + dep $acc14,23,8,$acc15 + xor $acc11,$s2,$s2 + + bv (%r31) + .EXIT + xor $acc15,$s3,$s3 + .PROCEND + + .ALIGN 64 +L\$AES_Td + .WORD 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96 + .WORD 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393 + .WORD 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25 + .WORD 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f + .WORD 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1 + .WORD 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6 + .WORD 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da + .WORD 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844 + .WORD 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd + .WORD 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4 + .WORD 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45 + .WORD 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94 + .WORD 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7 + .WORD 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a + .WORD 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5 + .WORD 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c + .WORD 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1 + .WORD 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a + .WORD 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75 + .WORD 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051 + .WORD 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46 + .WORD 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff + .WORD 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77 + .WORD 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb + .WORD 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000 + .WORD 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e + .WORD 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927 + .WORD 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a + .WORD 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e + .WORD 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16 + .WORD 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d + .WORD 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8 + .WORD 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd + .WORD 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34 + .WORD 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163 + .WORD 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120 + .WORD 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d + .WORD 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0 + .WORD 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422 + .WORD 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef + .WORD 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36 + .WORD 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4 + .WORD 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662 + .WORD 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5 + .WORD 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3 + .WORD 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b + .WORD 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8 + .WORD 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6 + .WORD 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6 + .WORD 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0 + .WORD 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815 + .WORD 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f + .WORD 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df + .WORD 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f + .WORD 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e + .WORD 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713 + .WORD 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89 + .WORD 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c + .WORD 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf + .WORD 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86 + .WORD 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f + .WORD 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541 + .WORD 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190 + .WORD 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742 + .BYTE 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38 + .BYTE 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb + .BYTE 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87 + .BYTE 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb + .BYTE 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d + .BYTE 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e + .BYTE 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2 + .BYTE 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 + .BYTE 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16 + .BYTE 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 + .BYTE 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda + .BYTE 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 + .BYTE 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a + .BYTE 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 + .BYTE 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02 + .BYTE 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b + .BYTE 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea + .BYTE 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 + .BYTE 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85 + .BYTE 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e + .BYTE 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89 + .BYTE 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b + .BYTE 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20 + .BYTE 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 + .BYTE 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31 + .BYTE 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f + .BYTE 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d + .BYTE 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef + .BYTE 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0 + .BYTE 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 + .BYTE 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26 + .BYTE 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d + .STRINGZ "AES for PA-RISC, CRYPTOGAMS by " +___ + +foreach (split("\n",$code)) { + s/\`([^\`]*)\`/eval $1/ge; + + # translate made up instructons: _ror, _srm + s/_ror(\s+)(%r[0-9]+),/shd$1$2,$2,/ or + + s/_srm(\s+%r[0-9]+),([0-9]+),/ + $SIZE_T==4 ? sprintf("extru%s,%d,8,",$1,31-$2) + : sprintf("extrd,u%s,%d,8,",$1,63-$2)/e; + + s/,\*/,/ if ($SIZE_T==4); + s/\bbv\b(.*\(%r2\))/bve$1/ if ($SIZE_T==8); + print $_,"\n"; +} +close STDOUT; diff --git a/libs/openssl/crypto/aes/asm/aes-ppc.pl b/libs/openssl/crypto/aes/asm/aes-ppc.pl new file mode 100644 index 00000000..7c52cbe5 --- /dev/null +++ b/libs/openssl/crypto/aes/asm/aes-ppc.pl @@ -0,0 +1,1365 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# Needs more work: key setup, CBC routine... +# +# ppc_AES_[en|de]crypt perform at 18 cycles per byte processed with +# 128-bit key, which is ~40% better than 64-bit code generated by gcc +# 4.0. But these are not the ones currently used! Their "compact" +# counterparts are, for security reason. ppc_AES_encrypt_compact runs +# at 1/2 of ppc_AES_encrypt speed, while ppc_AES_decrypt_compact - +# at 1/3 of ppc_AES_decrypt. + +# February 2010 +# +# Rescheduling instructions to favour Power6 pipeline gave 10% +# performance improvement on the platfrom in question (and marginal +# improvement even on others). It should be noted that Power6 fails +# to process byte in 18 cycles, only in 23, because it fails to issue +# 4 load instructions in two cycles, only in 3. As result non-compact +# block subroutines are 25% slower than one would expect. Compact +# functions scale better, because they have pure computational part, +# which scales perfectly with clock frequency. To be specific +# ppc_AES_encrypt_compact operates at 42 cycles per byte, while +# ppc_AES_decrypt_compact - at 55 (in 64-bit build). + +$flavour = shift; + +if ($flavour =~ /64/) { + $SIZE_T =8; + $LRSAVE =2*$SIZE_T; + $STU ="stdu"; + $POP ="ld"; + $PUSH ="std"; +} elsif ($flavour =~ /32/) { + $SIZE_T =4; + $LRSAVE =$SIZE_T; + $STU ="stwu"; + $POP ="lwz"; + $PUSH ="stw"; +} else { die "nonsense $flavour"; } + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or +die "can't locate ppc-xlate.pl"; + +open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; + +$FRAME=32*$SIZE_T; + +sub _data_word() +{ my $i; + while(defined($i=shift)) { $code.=sprintf"\t.long\t0x%08x,0x%08x\n",$i,$i; } +} + +$sp="r1"; +$toc="r2"; +$inp="r3"; +$out="r4"; +$key="r5"; + +$Tbl0="r3"; +$Tbl1="r6"; +$Tbl2="r7"; +$Tbl3="r2"; + +$s0="r8"; +$s1="r9"; +$s2="r10"; +$s3="r11"; + +$t0="r12"; +$t1="r13"; +$t2="r14"; +$t3="r15"; + +$acc00="r16"; +$acc01="r17"; +$acc02="r18"; +$acc03="r19"; + +$acc04="r20"; +$acc05="r21"; +$acc06="r22"; +$acc07="r23"; + +$acc08="r24"; +$acc09="r25"; +$acc10="r26"; +$acc11="r27"; + +$acc12="r28"; +$acc13="r29"; +$acc14="r30"; +$acc15="r31"; + +# stay away from TLS pointer +if ($SIZE_T==8) { die if ($t1 ne "r13"); $t1="r0"; } +else { die if ($Tbl3 ne "r2"); $Tbl3=$t0; $t0="r0"; } +$mask80=$Tbl2; +$mask1b=$Tbl3; + +$code.=<<___; +.machine "any" +.text + +.align 7 +LAES_Te: + mflr r0 + bcl 20,31,\$+4 + mflr $Tbl0 ; vvvvv "distance" between . and 1st data entry + addi $Tbl0,$Tbl0,`128-8` + mtlr r0 + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 + .space `64-9*4` +LAES_Td: + mflr r0 + bcl 20,31,\$+4 + mflr $Tbl0 ; vvvvvvvv "distance" between . and 1st data entry + addi $Tbl0,$Tbl0,`128-64-8+2048+256` + mtlr r0 + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 + .space `128-64-9*4` +___ +&_data_word( + 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, + 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, + 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, + 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, + 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, + 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, + 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, + 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, + 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, + 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, + 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, + 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, + 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, + 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, + 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, + 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, + 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, + 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, + 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, + 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, + 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, + 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, + 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, + 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, + 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, + 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, + 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, + 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, + 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, + 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, + 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, + 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, + 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, + 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, + 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, + 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, + 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, + 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, + 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, + 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, + 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, + 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, + 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, + 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, + 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, + 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, + 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, + 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, + 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, + 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, + 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, + 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, + 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, + 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, + 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, + 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, + 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, + 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, + 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, + 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, + 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, + 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, + 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, + 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a); +$code.=<<___; +.byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5 +.byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 +.byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0 +.byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 +.byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc +.byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 +.byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a +.byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 +.byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0 +.byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 +.byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b +.byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf +.byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85 +.byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 +.byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5 +.byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 +.byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17 +.byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 +.byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88 +.byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb +.byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c +.byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 +.byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9 +.byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 +.byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6 +.byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a +.byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e +.byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e +.byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94 +.byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf +.byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68 +.byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +___ +&_data_word( + 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, + 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, + 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, + 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, + 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, + 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, + 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, + 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, + 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, + 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, + 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, + 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, + 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, + 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, + 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, + 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, + 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, + 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, + 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, + 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, + 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, + 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, + 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, + 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, + 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, + 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, + 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, + 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, + 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, + 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, + 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, + 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, + 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, + 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, + 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, + 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, + 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, + 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, + 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, + 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, + 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, + 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, + 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, + 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, + 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, + 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, + 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, + 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, + 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, + 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, + 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, + 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, + 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, + 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, + 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, + 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, + 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, + 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, + 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, + 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, + 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, + 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, + 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, + 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742); +$code.=<<___; +.byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38 +.byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb +.byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87 +.byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb +.byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d +.byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e +.byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2 +.byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 +.byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16 +.byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 +.byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda +.byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 +.byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a +.byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 +.byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02 +.byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b +.byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea +.byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 +.byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85 +.byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e +.byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89 +.byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b +.byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20 +.byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 +.byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31 +.byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f +.byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d +.byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef +.byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0 +.byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 +.byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26 +.byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d + + +.globl .AES_encrypt +.align 7 +.AES_encrypt: + $STU $sp,-$FRAME($sp) + mflr r0 + + $PUSH $toc,`$FRAME-$SIZE_T*20`($sp) + $PUSH r13,`$FRAME-$SIZE_T*19`($sp) + $PUSH r14,`$FRAME-$SIZE_T*18`($sp) + $PUSH r15,`$FRAME-$SIZE_T*17`($sp) + $PUSH r16,`$FRAME-$SIZE_T*16`($sp) + $PUSH r17,`$FRAME-$SIZE_T*15`($sp) + $PUSH r18,`$FRAME-$SIZE_T*14`($sp) + $PUSH r19,`$FRAME-$SIZE_T*13`($sp) + $PUSH r20,`$FRAME-$SIZE_T*12`($sp) + $PUSH r21,`$FRAME-$SIZE_T*11`($sp) + $PUSH r22,`$FRAME-$SIZE_T*10`($sp) + $PUSH r23,`$FRAME-$SIZE_T*9`($sp) + $PUSH r24,`$FRAME-$SIZE_T*8`($sp) + $PUSH r25,`$FRAME-$SIZE_T*7`($sp) + $PUSH r26,`$FRAME-$SIZE_T*6`($sp) + $PUSH r27,`$FRAME-$SIZE_T*5`($sp) + $PUSH r28,`$FRAME-$SIZE_T*4`($sp) + $PUSH r29,`$FRAME-$SIZE_T*3`($sp) + $PUSH r30,`$FRAME-$SIZE_T*2`($sp) + $PUSH r31,`$FRAME-$SIZE_T*1`($sp) + $PUSH r0,`$FRAME+$LRSAVE`($sp) + + andi. $t0,$inp,3 + andi. $t1,$out,3 + or. $t0,$t0,$t1 + bne Lenc_unaligned + +Lenc_unaligned_ok: + lwz $s0,0($inp) + lwz $s1,4($inp) + lwz $s2,8($inp) + lwz $s3,12($inp) + bl LAES_Te + bl Lppc_AES_encrypt_compact + stw $s0,0($out) + stw $s1,4($out) + stw $s2,8($out) + stw $s3,12($out) + b Lenc_done + +Lenc_unaligned: + subfic $t0,$inp,4096 + subfic $t1,$out,4096 + andi. $t0,$t0,4096-16 + beq Lenc_xpage + andi. $t1,$t1,4096-16 + bne Lenc_unaligned_ok + +Lenc_xpage: + lbz $acc00,0($inp) + lbz $acc01,1($inp) + lbz $acc02,2($inp) + lbz $s0,3($inp) + lbz $acc04,4($inp) + lbz $acc05,5($inp) + lbz $acc06,6($inp) + lbz $s1,7($inp) + lbz $acc08,8($inp) + lbz $acc09,9($inp) + lbz $acc10,10($inp) + insrwi $s0,$acc00,8,0 + lbz $s2,11($inp) + insrwi $s1,$acc04,8,0 + lbz $acc12,12($inp) + insrwi $s0,$acc01,8,8 + lbz $acc13,13($inp) + insrwi $s1,$acc05,8,8 + lbz $acc14,14($inp) + insrwi $s0,$acc02,8,16 + lbz $s3,15($inp) + insrwi $s1,$acc06,8,16 + insrwi $s2,$acc08,8,0 + insrwi $s3,$acc12,8,0 + insrwi $s2,$acc09,8,8 + insrwi $s3,$acc13,8,8 + insrwi $s2,$acc10,8,16 + insrwi $s3,$acc14,8,16 + + bl LAES_Te + bl Lppc_AES_encrypt_compact + + extrwi $acc00,$s0,8,0 + extrwi $acc01,$s0,8,8 + stb $acc00,0($out) + extrwi $acc02,$s0,8,16 + stb $acc01,1($out) + stb $acc02,2($out) + extrwi $acc04,$s1,8,0 + stb $s0,3($out) + extrwi $acc05,$s1,8,8 + stb $acc04,4($out) + extrwi $acc06,$s1,8,16 + stb $acc05,5($out) + stb $acc06,6($out) + extrwi $acc08,$s2,8,0 + stb $s1,7($out) + extrwi $acc09,$s2,8,8 + stb $acc08,8($out) + extrwi $acc10,$s2,8,16 + stb $acc09,9($out) + stb $acc10,10($out) + extrwi $acc12,$s3,8,0 + stb $s2,11($out) + extrwi $acc13,$s3,8,8 + stb $acc12,12($out) + extrwi $acc14,$s3,8,16 + stb $acc13,13($out) + stb $acc14,14($out) + stb $s3,15($out) + +Lenc_done: + $POP r0,`$FRAME+$LRSAVE`($sp) + $POP $toc,`$FRAME-$SIZE_T*20`($sp) + $POP r13,`$FRAME-$SIZE_T*19`($sp) + $POP r14,`$FRAME-$SIZE_T*18`($sp) + $POP r15,`$FRAME-$SIZE_T*17`($sp) + $POP r16,`$FRAME-$SIZE_T*16`($sp) + $POP r17,`$FRAME-$SIZE_T*15`($sp) + $POP r18,`$FRAME-$SIZE_T*14`($sp) + $POP r19,`$FRAME-$SIZE_T*13`($sp) + $POP r20,`$FRAME-$SIZE_T*12`($sp) + $POP r21,`$FRAME-$SIZE_T*11`($sp) + $POP r22,`$FRAME-$SIZE_T*10`($sp) + $POP r23,`$FRAME-$SIZE_T*9`($sp) + $POP r24,`$FRAME-$SIZE_T*8`($sp) + $POP r25,`$FRAME-$SIZE_T*7`($sp) + $POP r26,`$FRAME-$SIZE_T*6`($sp) + $POP r27,`$FRAME-$SIZE_T*5`($sp) + $POP r28,`$FRAME-$SIZE_T*4`($sp) + $POP r29,`$FRAME-$SIZE_T*3`($sp) + $POP r30,`$FRAME-$SIZE_T*2`($sp) + $POP r31,`$FRAME-$SIZE_T*1`($sp) + mtlr r0 + addi $sp,$sp,$FRAME + blr + .long 0 + .byte 0,12,4,1,0x80,18,3,0 + .long 0 + +.align 5 +Lppc_AES_encrypt: + lwz $acc00,240($key) + addi $Tbl1,$Tbl0,3 + lwz $t0,0($key) + addi $Tbl2,$Tbl0,2 + lwz $t1,4($key) + addi $Tbl3,$Tbl0,1 + lwz $t2,8($key) + addi $acc00,$acc00,-1 + lwz $t3,12($key) + addi $key,$key,16 + xor $s0,$s0,$t0 + xor $s1,$s1,$t1 + xor $s2,$s2,$t2 + xor $s3,$s3,$t3 + mtctr $acc00 +.align 4 +Lenc_loop: + rlwinm $acc00,$s0,`32-24+3`,21,28 + rlwinm $acc01,$s1,`32-24+3`,21,28 + rlwinm $acc02,$s2,`32-24+3`,21,28 + rlwinm $acc03,$s3,`32-24+3`,21,28 + lwz $t0,0($key) + rlwinm $acc04,$s1,`32-16+3`,21,28 + lwz $t1,4($key) + rlwinm $acc05,$s2,`32-16+3`,21,28 + lwz $t2,8($key) + rlwinm $acc06,$s3,`32-16+3`,21,28 + lwz $t3,12($key) + rlwinm $acc07,$s0,`32-16+3`,21,28 + lwzx $acc00,$Tbl0,$acc00 + rlwinm $acc08,$s2,`32-8+3`,21,28 + lwzx $acc01,$Tbl0,$acc01 + rlwinm $acc09,$s3,`32-8+3`,21,28 + lwzx $acc02,$Tbl0,$acc02 + rlwinm $acc10,$s0,`32-8+3`,21,28 + lwzx $acc03,$Tbl0,$acc03 + rlwinm $acc11,$s1,`32-8+3`,21,28 + lwzx $acc04,$Tbl1,$acc04 + rlwinm $acc12,$s3,`0+3`,21,28 + lwzx $acc05,$Tbl1,$acc05 + rlwinm $acc13,$s0,`0+3`,21,28 + lwzx $acc06,$Tbl1,$acc06 + rlwinm $acc14,$s1,`0+3`,21,28 + lwzx $acc07,$Tbl1,$acc07 + rlwinm $acc15,$s2,`0+3`,21,28 + lwzx $acc08,$Tbl2,$acc08 + xor $t0,$t0,$acc00 + lwzx $acc09,$Tbl2,$acc09 + xor $t1,$t1,$acc01 + lwzx $acc10,$Tbl2,$acc10 + xor $t2,$t2,$acc02 + lwzx $acc11,$Tbl2,$acc11 + xor $t3,$t3,$acc03 + lwzx $acc12,$Tbl3,$acc12 + xor $t0,$t0,$acc04 + lwzx $acc13,$Tbl3,$acc13 + xor $t1,$t1,$acc05 + lwzx $acc14,$Tbl3,$acc14 + xor $t2,$t2,$acc06 + lwzx $acc15,$Tbl3,$acc15 + xor $t3,$t3,$acc07 + xor $t0,$t0,$acc08 + xor $t1,$t1,$acc09 + xor $t2,$t2,$acc10 + xor $t3,$t3,$acc11 + xor $s0,$t0,$acc12 + xor $s1,$t1,$acc13 + xor $s2,$t2,$acc14 + xor $s3,$t3,$acc15 + addi $key,$key,16 + bdnz- Lenc_loop + + addi $Tbl2,$Tbl0,2048 + nop + lwz $t0,0($key) + rlwinm $acc00,$s0,`32-24`,24,31 + lwz $t1,4($key) + rlwinm $acc01,$s1,`32-24`,24,31 + lwz $t2,8($key) + rlwinm $acc02,$s2,`32-24`,24,31 + lwz $t3,12($key) + rlwinm $acc03,$s3,`32-24`,24,31 + lwz $acc08,`2048+0`($Tbl0) ! prefetch Te4 + rlwinm $acc04,$s1,`32-16`,24,31 + lwz $acc09,`2048+32`($Tbl0) + rlwinm $acc05,$s2,`32-16`,24,31 + lwz $acc10,`2048+64`($Tbl0) + rlwinm $acc06,$s3,`32-16`,24,31 + lwz $acc11,`2048+96`($Tbl0) + rlwinm $acc07,$s0,`32-16`,24,31 + lwz $acc12,`2048+128`($Tbl0) + rlwinm $acc08,$s2,`32-8`,24,31 + lwz $acc13,`2048+160`($Tbl0) + rlwinm $acc09,$s3,`32-8`,24,31 + lwz $acc14,`2048+192`($Tbl0) + rlwinm $acc10,$s0,`32-8`,24,31 + lwz $acc15,`2048+224`($Tbl0) + rlwinm $acc11,$s1,`32-8`,24,31 + lbzx $acc00,$Tbl2,$acc00 + rlwinm $acc12,$s3,`0`,24,31 + lbzx $acc01,$Tbl2,$acc01 + rlwinm $acc13,$s0,`0`,24,31 + lbzx $acc02,$Tbl2,$acc02 + rlwinm $acc14,$s1,`0`,24,31 + lbzx $acc03,$Tbl2,$acc03 + rlwinm $acc15,$s2,`0`,24,31 + lbzx $acc04,$Tbl2,$acc04 + rlwinm $s0,$acc00,24,0,7 + lbzx $acc05,$Tbl2,$acc05 + rlwinm $s1,$acc01,24,0,7 + lbzx $acc06,$Tbl2,$acc06 + rlwinm $s2,$acc02,24,0,7 + lbzx $acc07,$Tbl2,$acc07 + rlwinm $s3,$acc03,24,0,7 + lbzx $acc08,$Tbl2,$acc08 + rlwimi $s0,$acc04,16,8,15 + lbzx $acc09,$Tbl2,$acc09 + rlwimi $s1,$acc05,16,8,15 + lbzx $acc10,$Tbl2,$acc10 + rlwimi $s2,$acc06,16,8,15 + lbzx $acc11,$Tbl2,$acc11 + rlwimi $s3,$acc07,16,8,15 + lbzx $acc12,$Tbl2,$acc12 + rlwimi $s0,$acc08,8,16,23 + lbzx $acc13,$Tbl2,$acc13 + rlwimi $s1,$acc09,8,16,23 + lbzx $acc14,$Tbl2,$acc14 + rlwimi $s2,$acc10,8,16,23 + lbzx $acc15,$Tbl2,$acc15 + rlwimi $s3,$acc11,8,16,23 + or $s0,$s0,$acc12 + or $s1,$s1,$acc13 + or $s2,$s2,$acc14 + or $s3,$s3,$acc15 + xor $s0,$s0,$t0 + xor $s1,$s1,$t1 + xor $s2,$s2,$t2 + xor $s3,$s3,$t3 + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 + +.align 4 +Lppc_AES_encrypt_compact: + lwz $acc00,240($key) + addi $Tbl1,$Tbl0,2048 + lwz $t0,0($key) + lis $mask80,0x8080 + lwz $t1,4($key) + lis $mask1b,0x1b1b + lwz $t2,8($key) + ori $mask80,$mask80,0x8080 + lwz $t3,12($key) + ori $mask1b,$mask1b,0x1b1b + addi $key,$key,16 + mtctr $acc00 +.align 4 +Lenc_compact_loop: + xor $s0,$s0,$t0 + xor $s1,$s1,$t1 + rlwinm $acc00,$s0,`32-24`,24,31 + xor $s2,$s2,$t2 + rlwinm $acc01,$s1,`32-24`,24,31 + xor $s3,$s3,$t3 + rlwinm $acc02,$s2,`32-24`,24,31 + rlwinm $acc03,$s3,`32-24`,24,31 + rlwinm $acc04,$s1,`32-16`,24,31 + rlwinm $acc05,$s2,`32-16`,24,31 + rlwinm $acc06,$s3,`32-16`,24,31 + rlwinm $acc07,$s0,`32-16`,24,31 + lbzx $acc00,$Tbl1,$acc00 + rlwinm $acc08,$s2,`32-8`,24,31 + lbzx $acc01,$Tbl1,$acc01 + rlwinm $acc09,$s3,`32-8`,24,31 + lbzx $acc02,$Tbl1,$acc02 + rlwinm $acc10,$s0,`32-8`,24,31 + lbzx $acc03,$Tbl1,$acc03 + rlwinm $acc11,$s1,`32-8`,24,31 + lbzx $acc04,$Tbl1,$acc04 + rlwinm $acc12,$s3,`0`,24,31 + lbzx $acc05,$Tbl1,$acc05 + rlwinm $acc13,$s0,`0`,24,31 + lbzx $acc06,$Tbl1,$acc06 + rlwinm $acc14,$s1,`0`,24,31 + lbzx $acc07,$Tbl1,$acc07 + rlwinm $acc15,$s2,`0`,24,31 + lbzx $acc08,$Tbl1,$acc08 + rlwinm $s0,$acc00,24,0,7 + lbzx $acc09,$Tbl1,$acc09 + rlwinm $s1,$acc01,24,0,7 + lbzx $acc10,$Tbl1,$acc10 + rlwinm $s2,$acc02,24,0,7 + lbzx $acc11,$Tbl1,$acc11 + rlwinm $s3,$acc03,24,0,7 + lbzx $acc12,$Tbl1,$acc12 + rlwimi $s0,$acc04,16,8,15 + lbzx $acc13,$Tbl1,$acc13 + rlwimi $s1,$acc05,16,8,15 + lbzx $acc14,$Tbl1,$acc14 + rlwimi $s2,$acc06,16,8,15 + lbzx $acc15,$Tbl1,$acc15 + rlwimi $s3,$acc07,16,8,15 + rlwimi $s0,$acc08,8,16,23 + rlwimi $s1,$acc09,8,16,23 + rlwimi $s2,$acc10,8,16,23 + rlwimi $s3,$acc11,8,16,23 + lwz $t0,0($key) + or $s0,$s0,$acc12 + lwz $t1,4($key) + or $s1,$s1,$acc13 + lwz $t2,8($key) + or $s2,$s2,$acc14 + lwz $t3,12($key) + or $s3,$s3,$acc15 + + addi $key,$key,16 + bdz Lenc_compact_done + + and $acc00,$s0,$mask80 # r1=r0&0x80808080 + and $acc01,$s1,$mask80 + and $acc02,$s2,$mask80 + and $acc03,$s3,$mask80 + srwi $acc04,$acc00,7 # r1>>7 + andc $acc08,$s0,$mask80 # r0&0x7f7f7f7f + srwi $acc05,$acc01,7 + andc $acc09,$s1,$mask80 + srwi $acc06,$acc02,7 + andc $acc10,$s2,$mask80 + srwi $acc07,$acc03,7 + andc $acc11,$s3,$mask80 + sub $acc00,$acc00,$acc04 # r1-(r1>>7) + sub $acc01,$acc01,$acc05 + sub $acc02,$acc02,$acc06 + sub $acc03,$acc03,$acc07 + add $acc08,$acc08,$acc08 # (r0&0x7f7f7f7f)<<1 + add $acc09,$acc09,$acc09 + add $acc10,$acc10,$acc10 + add $acc11,$acc11,$acc11 + and $acc00,$acc00,$mask1b # (r1-(r1>>7))&0x1b1b1b1b + and $acc01,$acc01,$mask1b + and $acc02,$acc02,$mask1b + and $acc03,$acc03,$mask1b + xor $acc00,$acc00,$acc08 # r2 + xor $acc01,$acc01,$acc09 + rotlwi $acc12,$s0,16 # ROTATE(r0,16) + xor $acc02,$acc02,$acc10 + rotlwi $acc13,$s1,16 + xor $acc03,$acc03,$acc11 + rotlwi $acc14,$s2,16 + + xor $s0,$s0,$acc00 # r0^r2 + rotlwi $acc15,$s3,16 + xor $s1,$s1,$acc01 + rotrwi $s0,$s0,24 # ROTATE(r2^r0,24) + xor $s2,$s2,$acc02 + rotrwi $s1,$s1,24 + xor $s3,$s3,$acc03 + rotrwi $s2,$s2,24 + xor $s0,$s0,$acc00 # ROTATE(r2^r0,24)^r2 + rotrwi $s3,$s3,24 + xor $s1,$s1,$acc01 + xor $s2,$s2,$acc02 + xor $s3,$s3,$acc03 + rotlwi $acc08,$acc12,8 # ROTATE(r0,24) + xor $s0,$s0,$acc12 # + rotlwi $acc09,$acc13,8 + xor $s1,$s1,$acc13 + rotlwi $acc10,$acc14,8 + xor $s2,$s2,$acc14 + rotlwi $acc11,$acc15,8 + xor $s3,$s3,$acc15 + xor $s0,$s0,$acc08 # + xor $s1,$s1,$acc09 + xor $s2,$s2,$acc10 + xor $s3,$s3,$acc11 + + b Lenc_compact_loop +.align 4 +Lenc_compact_done: + xor $s0,$s0,$t0 + xor $s1,$s1,$t1 + xor $s2,$s2,$t2 + xor $s3,$s3,$t3 + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 + +.globl .AES_decrypt +.align 7 +.AES_decrypt: + $STU $sp,-$FRAME($sp) + mflr r0 + + $PUSH $toc,`$FRAME-$SIZE_T*20`($sp) + $PUSH r13,`$FRAME-$SIZE_T*19`($sp) + $PUSH r14,`$FRAME-$SIZE_T*18`($sp) + $PUSH r15,`$FRAME-$SIZE_T*17`($sp) + $PUSH r16,`$FRAME-$SIZE_T*16`($sp) + $PUSH r17,`$FRAME-$SIZE_T*15`($sp) + $PUSH r18,`$FRAME-$SIZE_T*14`($sp) + $PUSH r19,`$FRAME-$SIZE_T*13`($sp) + $PUSH r20,`$FRAME-$SIZE_T*12`($sp) + $PUSH r21,`$FRAME-$SIZE_T*11`($sp) + $PUSH r22,`$FRAME-$SIZE_T*10`($sp) + $PUSH r23,`$FRAME-$SIZE_T*9`($sp) + $PUSH r24,`$FRAME-$SIZE_T*8`($sp) + $PUSH r25,`$FRAME-$SIZE_T*7`($sp) + $PUSH r26,`$FRAME-$SIZE_T*6`($sp) + $PUSH r27,`$FRAME-$SIZE_T*5`($sp) + $PUSH r28,`$FRAME-$SIZE_T*4`($sp) + $PUSH r29,`$FRAME-$SIZE_T*3`($sp) + $PUSH r30,`$FRAME-$SIZE_T*2`($sp) + $PUSH r31,`$FRAME-$SIZE_T*1`($sp) + $PUSH r0,`$FRAME+$LRSAVE`($sp) + + andi. $t0,$inp,3 + andi. $t1,$out,3 + or. $t0,$t0,$t1 + bne Ldec_unaligned + +Ldec_unaligned_ok: + lwz $s0,0($inp) + lwz $s1,4($inp) + lwz $s2,8($inp) + lwz $s3,12($inp) + bl LAES_Td + bl Lppc_AES_decrypt_compact + stw $s0,0($out) + stw $s1,4($out) + stw $s2,8($out) + stw $s3,12($out) + b Ldec_done + +Ldec_unaligned: + subfic $t0,$inp,4096 + subfic $t1,$out,4096 + andi. $t0,$t0,4096-16 + beq Ldec_xpage + andi. $t1,$t1,4096-16 + bne Ldec_unaligned_ok + +Ldec_xpage: + lbz $acc00,0($inp) + lbz $acc01,1($inp) + lbz $acc02,2($inp) + lbz $s0,3($inp) + lbz $acc04,4($inp) + lbz $acc05,5($inp) + lbz $acc06,6($inp) + lbz $s1,7($inp) + lbz $acc08,8($inp) + lbz $acc09,9($inp) + lbz $acc10,10($inp) + insrwi $s0,$acc00,8,0 + lbz $s2,11($inp) + insrwi $s1,$acc04,8,0 + lbz $acc12,12($inp) + insrwi $s0,$acc01,8,8 + lbz $acc13,13($inp) + insrwi $s1,$acc05,8,8 + lbz $acc14,14($inp) + insrwi $s0,$acc02,8,16 + lbz $s3,15($inp) + insrwi $s1,$acc06,8,16 + insrwi $s2,$acc08,8,0 + insrwi $s3,$acc12,8,0 + insrwi $s2,$acc09,8,8 + insrwi $s3,$acc13,8,8 + insrwi $s2,$acc10,8,16 + insrwi $s3,$acc14,8,16 + + bl LAES_Td + bl Lppc_AES_decrypt_compact + + extrwi $acc00,$s0,8,0 + extrwi $acc01,$s0,8,8 + stb $acc00,0($out) + extrwi $acc02,$s0,8,16 + stb $acc01,1($out) + stb $acc02,2($out) + extrwi $acc04,$s1,8,0 + stb $s0,3($out) + extrwi $acc05,$s1,8,8 + stb $acc04,4($out) + extrwi $acc06,$s1,8,16 + stb $acc05,5($out) + stb $acc06,6($out) + extrwi $acc08,$s2,8,0 + stb $s1,7($out) + extrwi $acc09,$s2,8,8 + stb $acc08,8($out) + extrwi $acc10,$s2,8,16 + stb $acc09,9($out) + stb $acc10,10($out) + extrwi $acc12,$s3,8,0 + stb $s2,11($out) + extrwi $acc13,$s3,8,8 + stb $acc12,12($out) + extrwi $acc14,$s3,8,16 + stb $acc13,13($out) + stb $acc14,14($out) + stb $s3,15($out) + +Ldec_done: + $POP r0,`$FRAME+$LRSAVE`($sp) + $POP $toc,`$FRAME-$SIZE_T*20`($sp) + $POP r13,`$FRAME-$SIZE_T*19`($sp) + $POP r14,`$FRAME-$SIZE_T*18`($sp) + $POP r15,`$FRAME-$SIZE_T*17`($sp) + $POP r16,`$FRAME-$SIZE_T*16`($sp) + $POP r17,`$FRAME-$SIZE_T*15`($sp) + $POP r18,`$FRAME-$SIZE_T*14`($sp) + $POP r19,`$FRAME-$SIZE_T*13`($sp) + $POP r20,`$FRAME-$SIZE_T*12`($sp) + $POP r21,`$FRAME-$SIZE_T*11`($sp) + $POP r22,`$FRAME-$SIZE_T*10`($sp) + $POP r23,`$FRAME-$SIZE_T*9`($sp) + $POP r24,`$FRAME-$SIZE_T*8`($sp) + $POP r25,`$FRAME-$SIZE_T*7`($sp) + $POP r26,`$FRAME-$SIZE_T*6`($sp) + $POP r27,`$FRAME-$SIZE_T*5`($sp) + $POP r28,`$FRAME-$SIZE_T*4`($sp) + $POP r29,`$FRAME-$SIZE_T*3`($sp) + $POP r30,`$FRAME-$SIZE_T*2`($sp) + $POP r31,`$FRAME-$SIZE_T*1`($sp) + mtlr r0 + addi $sp,$sp,$FRAME + blr + .long 0 + .byte 0,12,4,1,0x80,18,3,0 + .long 0 + +.align 5 +Lppc_AES_decrypt: + lwz $acc00,240($key) + addi $Tbl1,$Tbl0,3 + lwz $t0,0($key) + addi $Tbl2,$Tbl0,2 + lwz $t1,4($key) + addi $Tbl3,$Tbl0,1 + lwz $t2,8($key) + addi $acc00,$acc00,-1 + lwz $t3,12($key) + addi $key,$key,16 + xor $s0,$s0,$t0 + xor $s1,$s1,$t1 + xor $s2,$s2,$t2 + xor $s3,$s3,$t3 + mtctr $acc00 +.align 4 +Ldec_loop: + rlwinm $acc00,$s0,`32-24+3`,21,28 + rlwinm $acc01,$s1,`32-24+3`,21,28 + rlwinm $acc02,$s2,`32-24+3`,21,28 + rlwinm $acc03,$s3,`32-24+3`,21,28 + lwz $t0,0($key) + rlwinm $acc04,$s3,`32-16+3`,21,28 + lwz $t1,4($key) + rlwinm $acc05,$s0,`32-16+3`,21,28 + lwz $t2,8($key) + rlwinm $acc06,$s1,`32-16+3`,21,28 + lwz $t3,12($key) + rlwinm $acc07,$s2,`32-16+3`,21,28 + lwzx $acc00,$Tbl0,$acc00 + rlwinm $acc08,$s2,`32-8+3`,21,28 + lwzx $acc01,$Tbl0,$acc01 + rlwinm $acc09,$s3,`32-8+3`,21,28 + lwzx $acc02,$Tbl0,$acc02 + rlwinm $acc10,$s0,`32-8+3`,21,28 + lwzx $acc03,$Tbl0,$acc03 + rlwinm $acc11,$s1,`32-8+3`,21,28 + lwzx $acc04,$Tbl1,$acc04 + rlwinm $acc12,$s1,`0+3`,21,28 + lwzx $acc05,$Tbl1,$acc05 + rlwinm $acc13,$s2,`0+3`,21,28 + lwzx $acc06,$Tbl1,$acc06 + rlwinm $acc14,$s3,`0+3`,21,28 + lwzx $acc07,$Tbl1,$acc07 + rlwinm $acc15,$s0,`0+3`,21,28 + lwzx $acc08,$Tbl2,$acc08 + xor $t0,$t0,$acc00 + lwzx $acc09,$Tbl2,$acc09 + xor $t1,$t1,$acc01 + lwzx $acc10,$Tbl2,$acc10 + xor $t2,$t2,$acc02 + lwzx $acc11,$Tbl2,$acc11 + xor $t3,$t3,$acc03 + lwzx $acc12,$Tbl3,$acc12 + xor $t0,$t0,$acc04 + lwzx $acc13,$Tbl3,$acc13 + xor $t1,$t1,$acc05 + lwzx $acc14,$Tbl3,$acc14 + xor $t2,$t2,$acc06 + lwzx $acc15,$Tbl3,$acc15 + xor $t3,$t3,$acc07 + xor $t0,$t0,$acc08 + xor $t1,$t1,$acc09 + xor $t2,$t2,$acc10 + xor $t3,$t3,$acc11 + xor $s0,$t0,$acc12 + xor $s1,$t1,$acc13 + xor $s2,$t2,$acc14 + xor $s3,$t3,$acc15 + addi $key,$key,16 + bdnz- Ldec_loop + + addi $Tbl2,$Tbl0,2048 + nop + lwz $t0,0($key) + rlwinm $acc00,$s0,`32-24`,24,31 + lwz $t1,4($key) + rlwinm $acc01,$s1,`32-24`,24,31 + lwz $t2,8($key) + rlwinm $acc02,$s2,`32-24`,24,31 + lwz $t3,12($key) + rlwinm $acc03,$s3,`32-24`,24,31 + lwz $acc08,`2048+0`($Tbl0) ! prefetch Td4 + rlwinm $acc04,$s3,`32-16`,24,31 + lwz $acc09,`2048+32`($Tbl0) + rlwinm $acc05,$s0,`32-16`,24,31 + lwz $acc10,`2048+64`($Tbl0) + lbzx $acc00,$Tbl2,$acc00 + lwz $acc11,`2048+96`($Tbl0) + lbzx $acc01,$Tbl2,$acc01 + lwz $acc12,`2048+128`($Tbl0) + rlwinm $acc06,$s1,`32-16`,24,31 + lwz $acc13,`2048+160`($Tbl0) + rlwinm $acc07,$s2,`32-16`,24,31 + lwz $acc14,`2048+192`($Tbl0) + rlwinm $acc08,$s2,`32-8`,24,31 + lwz $acc15,`2048+224`($Tbl0) + rlwinm $acc09,$s3,`32-8`,24,31 + lbzx $acc02,$Tbl2,$acc02 + rlwinm $acc10,$s0,`32-8`,24,31 + lbzx $acc03,$Tbl2,$acc03 + rlwinm $acc11,$s1,`32-8`,24,31 + lbzx $acc04,$Tbl2,$acc04 + rlwinm $acc12,$s1,`0`,24,31 + lbzx $acc05,$Tbl2,$acc05 + rlwinm $acc13,$s2,`0`,24,31 + lbzx $acc06,$Tbl2,$acc06 + rlwinm $acc14,$s3,`0`,24,31 + lbzx $acc07,$Tbl2,$acc07 + rlwinm $acc15,$s0,`0`,24,31 + lbzx $acc08,$Tbl2,$acc08 + rlwinm $s0,$acc00,24,0,7 + lbzx $acc09,$Tbl2,$acc09 + rlwinm $s1,$acc01,24,0,7 + lbzx $acc10,$Tbl2,$acc10 + rlwinm $s2,$acc02,24,0,7 + lbzx $acc11,$Tbl2,$acc11 + rlwinm $s3,$acc03,24,0,7 + lbzx $acc12,$Tbl2,$acc12 + rlwimi $s0,$acc04,16,8,15 + lbzx $acc13,$Tbl2,$acc13 + rlwimi $s1,$acc05,16,8,15 + lbzx $acc14,$Tbl2,$acc14 + rlwimi $s2,$acc06,16,8,15 + lbzx $acc15,$Tbl2,$acc15 + rlwimi $s3,$acc07,16,8,15 + rlwimi $s0,$acc08,8,16,23 + rlwimi $s1,$acc09,8,16,23 + rlwimi $s2,$acc10,8,16,23 + rlwimi $s3,$acc11,8,16,23 + or $s0,$s0,$acc12 + or $s1,$s1,$acc13 + or $s2,$s2,$acc14 + or $s3,$s3,$acc15 + xor $s0,$s0,$t0 + xor $s1,$s1,$t1 + xor $s2,$s2,$t2 + xor $s3,$s3,$t3 + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 + +.align 4 +Lppc_AES_decrypt_compact: + lwz $acc00,240($key) + addi $Tbl1,$Tbl0,2048 + lwz $t0,0($key) + lis $mask80,0x8080 + lwz $t1,4($key) + lis $mask1b,0x1b1b + lwz $t2,8($key) + ori $mask80,$mask80,0x8080 + lwz $t3,12($key) + ori $mask1b,$mask1b,0x1b1b + addi $key,$key,16 +___ +$code.=<<___ if ($SIZE_T==8); + insrdi $mask80,$mask80,32,0 + insrdi $mask1b,$mask1b,32,0 +___ +$code.=<<___; + mtctr $acc00 +.align 4 +Ldec_compact_loop: + xor $s0,$s0,$t0 + xor $s1,$s1,$t1 + rlwinm $acc00,$s0,`32-24`,24,31 + xor $s2,$s2,$t2 + rlwinm $acc01,$s1,`32-24`,24,31 + xor $s3,$s3,$t3 + rlwinm $acc02,$s2,`32-24`,24,31 + rlwinm $acc03,$s3,`32-24`,24,31 + rlwinm $acc04,$s3,`32-16`,24,31 + rlwinm $acc05,$s0,`32-16`,24,31 + rlwinm $acc06,$s1,`32-16`,24,31 + rlwinm $acc07,$s2,`32-16`,24,31 + lbzx $acc00,$Tbl1,$acc00 + rlwinm $acc08,$s2,`32-8`,24,31 + lbzx $acc01,$Tbl1,$acc01 + rlwinm $acc09,$s3,`32-8`,24,31 + lbzx $acc02,$Tbl1,$acc02 + rlwinm $acc10,$s0,`32-8`,24,31 + lbzx $acc03,$Tbl1,$acc03 + rlwinm $acc11,$s1,`32-8`,24,31 + lbzx $acc04,$Tbl1,$acc04 + rlwinm $acc12,$s1,`0`,24,31 + lbzx $acc05,$Tbl1,$acc05 + rlwinm $acc13,$s2,`0`,24,31 + lbzx $acc06,$Tbl1,$acc06 + rlwinm $acc14,$s3,`0`,24,31 + lbzx $acc07,$Tbl1,$acc07 + rlwinm $acc15,$s0,`0`,24,31 + lbzx $acc08,$Tbl1,$acc08 + rlwinm $s0,$acc00,24,0,7 + lbzx $acc09,$Tbl1,$acc09 + rlwinm $s1,$acc01,24,0,7 + lbzx $acc10,$Tbl1,$acc10 + rlwinm $s2,$acc02,24,0,7 + lbzx $acc11,$Tbl1,$acc11 + rlwinm $s3,$acc03,24,0,7 + lbzx $acc12,$Tbl1,$acc12 + rlwimi $s0,$acc04,16,8,15 + lbzx $acc13,$Tbl1,$acc13 + rlwimi $s1,$acc05,16,8,15 + lbzx $acc14,$Tbl1,$acc14 + rlwimi $s2,$acc06,16,8,15 + lbzx $acc15,$Tbl1,$acc15 + rlwimi $s3,$acc07,16,8,15 + rlwimi $s0,$acc08,8,16,23 + rlwimi $s1,$acc09,8,16,23 + rlwimi $s2,$acc10,8,16,23 + rlwimi $s3,$acc11,8,16,23 + lwz $t0,0($key) + or $s0,$s0,$acc12 + lwz $t1,4($key) + or $s1,$s1,$acc13 + lwz $t2,8($key) + or $s2,$s2,$acc14 + lwz $t3,12($key) + or $s3,$s3,$acc15 + + addi $key,$key,16 + bdz Ldec_compact_done +___ +$code.=<<___ if ($SIZE_T==8); + # vectorized permutation improves decrypt performance by 10% + insrdi $s0,$s1,32,0 + insrdi $s2,$s3,32,0 + + and $acc00,$s0,$mask80 # r1=r0&0x80808080 + and $acc02,$s2,$mask80 + srdi $acc04,$acc00,7 # r1>>7 + srdi $acc06,$acc02,7 + andc $acc08,$s0,$mask80 # r0&0x7f7f7f7f + andc $acc10,$s2,$mask80 + sub $acc00,$acc00,$acc04 # r1-(r1>>7) + sub $acc02,$acc02,$acc06 + add $acc08,$acc08,$acc08 # (r0&0x7f7f7f7f)<<1 + add $acc10,$acc10,$acc10 + and $acc00,$acc00,$mask1b # (r1-(r1>>7))&0x1b1b1b1b + and $acc02,$acc02,$mask1b + xor $acc00,$acc00,$acc08 # r2 + xor $acc02,$acc02,$acc10 + + and $acc04,$acc00,$mask80 # r1=r2&0x80808080 + and $acc06,$acc02,$mask80 + srdi $acc08,$acc04,7 # r1>>7 + srdi $acc10,$acc06,7 + andc $acc12,$acc00,$mask80 # r2&0x7f7f7f7f + andc $acc14,$acc02,$mask80 + sub $acc04,$acc04,$acc08 # r1-(r1>>7) + sub $acc06,$acc06,$acc10 + add $acc12,$acc12,$acc12 # (r2&0x7f7f7f7f)<<1 + add $acc14,$acc14,$acc14 + and $acc04,$acc04,$mask1b # (r1-(r1>>7))&0x1b1b1b1b + and $acc06,$acc06,$mask1b + xor $acc04,$acc04,$acc12 # r4 + xor $acc06,$acc06,$acc14 + + and $acc08,$acc04,$mask80 # r1=r4&0x80808080 + and $acc10,$acc06,$mask80 + srdi $acc12,$acc08,7 # r1>>7 + srdi $acc14,$acc10,7 + sub $acc08,$acc08,$acc12 # r1-(r1>>7) + sub $acc10,$acc10,$acc14 + andc $acc12,$acc04,$mask80 # r4&0x7f7f7f7f + andc $acc14,$acc06,$mask80 + add $acc12,$acc12,$acc12 # (r4&0x7f7f7f7f)<<1 + add $acc14,$acc14,$acc14 + and $acc08,$acc08,$mask1b # (r1-(r1>>7))&0x1b1b1b1b + and $acc10,$acc10,$mask1b + xor $acc08,$acc08,$acc12 # r8 + xor $acc10,$acc10,$acc14 + + xor $acc00,$acc00,$s0 # r2^r0 + xor $acc02,$acc02,$s2 + xor $acc04,$acc04,$s0 # r4^r0 + xor $acc06,$acc06,$s2 + + extrdi $acc01,$acc00,32,0 + extrdi $acc03,$acc02,32,0 + extrdi $acc05,$acc04,32,0 + extrdi $acc07,$acc06,32,0 + extrdi $acc09,$acc08,32,0 + extrdi $acc11,$acc10,32,0 +___ +$code.=<<___ if ($SIZE_T==4); + and $acc00,$s0,$mask80 # r1=r0&0x80808080 + and $acc01,$s1,$mask80 + and $acc02,$s2,$mask80 + and $acc03,$s3,$mask80 + srwi $acc04,$acc00,7 # r1>>7 + andc $acc08,$s0,$mask80 # r0&0x7f7f7f7f + srwi $acc05,$acc01,7 + andc $acc09,$s1,$mask80 + srwi $acc06,$acc02,7 + andc $acc10,$s2,$mask80 + srwi $acc07,$acc03,7 + andc $acc11,$s3,$mask80 + sub $acc00,$acc00,$acc04 # r1-(r1>>7) + sub $acc01,$acc01,$acc05 + sub $acc02,$acc02,$acc06 + sub $acc03,$acc03,$acc07 + add $acc08,$acc08,$acc08 # (r0&0x7f7f7f7f)<<1 + add $acc09,$acc09,$acc09 + add $acc10,$acc10,$acc10 + add $acc11,$acc11,$acc11 + and $acc00,$acc00,$mask1b # (r1-(r1>>7))&0x1b1b1b1b + and $acc01,$acc01,$mask1b + and $acc02,$acc02,$mask1b + and $acc03,$acc03,$mask1b + xor $acc00,$acc00,$acc08 # r2 + xor $acc01,$acc01,$acc09 + xor $acc02,$acc02,$acc10 + xor $acc03,$acc03,$acc11 + + and $acc04,$acc00,$mask80 # r1=r2&0x80808080 + and $acc05,$acc01,$mask80 + and $acc06,$acc02,$mask80 + and $acc07,$acc03,$mask80 + srwi $acc08,$acc04,7 # r1>>7 + andc $acc12,$acc00,$mask80 # r2&0x7f7f7f7f + srwi $acc09,$acc05,7 + andc $acc13,$acc01,$mask80 + srwi $acc10,$acc06,7 + andc $acc14,$acc02,$mask80 + srwi $acc11,$acc07,7 + andc $acc15,$acc03,$mask80 + sub $acc04,$acc04,$acc08 # r1-(r1>>7) + sub $acc05,$acc05,$acc09 + sub $acc06,$acc06,$acc10 + sub $acc07,$acc07,$acc11 + add $acc12,$acc12,$acc12 # (r2&0x7f7f7f7f)<<1 + add $acc13,$acc13,$acc13 + add $acc14,$acc14,$acc14 + add $acc15,$acc15,$acc15 + and $acc04,$acc04,$mask1b # (r1-(r1>>7))&0x1b1b1b1b + and $acc05,$acc05,$mask1b + and $acc06,$acc06,$mask1b + and $acc07,$acc07,$mask1b + xor $acc04,$acc04,$acc12 # r4 + xor $acc05,$acc05,$acc13 + xor $acc06,$acc06,$acc14 + xor $acc07,$acc07,$acc15 + + and $acc08,$acc04,$mask80 # r1=r4&0x80808080 + and $acc09,$acc05,$mask80 + srwi $acc12,$acc08,7 # r1>>7 + and $acc10,$acc06,$mask80 + srwi $acc13,$acc09,7 + and $acc11,$acc07,$mask80 + srwi $acc14,$acc10,7 + sub $acc08,$acc08,$acc12 # r1-(r1>>7) + srwi $acc15,$acc11,7 + sub $acc09,$acc09,$acc13 + sub $acc10,$acc10,$acc14 + sub $acc11,$acc11,$acc15 + andc $acc12,$acc04,$mask80 # r4&0x7f7f7f7f + andc $acc13,$acc05,$mask80 + andc $acc14,$acc06,$mask80 + andc $acc15,$acc07,$mask80 + add $acc12,$acc12,$acc12 # (r4&0x7f7f7f7f)<<1 + add $acc13,$acc13,$acc13 + add $acc14,$acc14,$acc14 + add $acc15,$acc15,$acc15 + and $acc08,$acc08,$mask1b # (r1-(r1>>7))&0x1b1b1b1b + and $acc09,$acc09,$mask1b + and $acc10,$acc10,$mask1b + and $acc11,$acc11,$mask1b + xor $acc08,$acc08,$acc12 # r8 + xor $acc09,$acc09,$acc13 + xor $acc10,$acc10,$acc14 + xor $acc11,$acc11,$acc15 + + xor $acc00,$acc00,$s0 # r2^r0 + xor $acc01,$acc01,$s1 + xor $acc02,$acc02,$s2 + xor $acc03,$acc03,$s3 + xor $acc04,$acc04,$s0 # r4^r0 + xor $acc05,$acc05,$s1 + xor $acc06,$acc06,$s2 + xor $acc07,$acc07,$s3 +___ +$code.=<<___; + rotrwi $s0,$s0,8 # = ROTATE(r0,8) + rotrwi $s1,$s1,8 + xor $s0,$s0,$acc00 # ^= r2^r0 + rotrwi $s2,$s2,8 + xor $s1,$s1,$acc01 + rotrwi $s3,$s3,8 + xor $s2,$s2,$acc02 + xor $s3,$s3,$acc03 + xor $acc00,$acc00,$acc08 + xor $acc01,$acc01,$acc09 + xor $acc02,$acc02,$acc10 + xor $acc03,$acc03,$acc11 + xor $s0,$s0,$acc04 # ^= r4^r0 + rotrwi $acc00,$acc00,24 + xor $s1,$s1,$acc05 + rotrwi $acc01,$acc01,24 + xor $s2,$s2,$acc06 + rotrwi $acc02,$acc02,24 + xor $s3,$s3,$acc07 + rotrwi $acc03,$acc03,24 + xor $acc04,$acc04,$acc08 + xor $acc05,$acc05,$acc09 + xor $acc06,$acc06,$acc10 + xor $acc07,$acc07,$acc11 + xor $s0,$s0,$acc08 # ^= r8 [^((r4^r0)^(r2^r0)=r4^r2)] + rotrwi $acc04,$acc04,16 + xor $s1,$s1,$acc09 + rotrwi $acc05,$acc05,16 + xor $s2,$s2,$acc10 + rotrwi $acc06,$acc06,16 + xor $s3,$s3,$acc11 + rotrwi $acc07,$acc07,16 + xor $s0,$s0,$acc00 # ^= ROTATE(r8^r2^r0,24) + rotrwi $acc08,$acc08,8 + xor $s1,$s1,$acc01 + rotrwi $acc09,$acc09,8 + xor $s2,$s2,$acc02 + rotrwi $acc10,$acc10,8 + xor $s3,$s3,$acc03 + rotrwi $acc11,$acc11,8 + xor $s0,$s0,$acc04 # ^= ROTATE(r8^r4^r0,16) + xor $s1,$s1,$acc05 + xor $s2,$s2,$acc06 + xor $s3,$s3,$acc07 + xor $s0,$s0,$acc08 # ^= ROTATE(r8,8) + xor $s1,$s1,$acc09 + xor $s2,$s2,$acc10 + xor $s3,$s3,$acc11 + + b Ldec_compact_loop +.align 4 +Ldec_compact_done: + xor $s0,$s0,$t0 + xor $s1,$s1,$t1 + xor $s2,$s2,$t2 + xor $s3,$s3,$t3 + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 + +.asciz "AES for PPC, CRYPTOGAMS by " +.align 7 +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/aes/asm/aes-s390x.pl b/libs/openssl/crypto/aes/asm/aes-s390x.pl new file mode 100644 index 00000000..e75dcd03 --- /dev/null +++ b/libs/openssl/crypto/aes/asm/aes-s390x.pl @@ -0,0 +1,2237 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# AES for s390x. + +# April 2007. +# +# Software performance improvement over gcc-generated code is ~70% and +# in absolute terms is ~73 cycles per byte processed with 128-bit key. +# You're likely to exclaim "why so slow?" Keep in mind that z-CPUs are +# *strictly* in-order execution and issued instruction [in this case +# load value from memory is critical] has to complete before execution +# flow proceeds. S-boxes are compressed to 2KB[+256B]. +# +# As for hardware acceleration support. It's basically a "teaser," as +# it can and should be improved in several ways. Most notably support +# for CBC is not utilized, nor multiple blocks are ever processed. +# Then software key schedule can be postponed till hardware support +# detection... Performance improvement over assembler is reportedly +# ~2.5x, but can reach >8x [naturally on larger chunks] if proper +# support is implemented. + +# May 2007. +# +# Implement AES_set_[en|de]crypt_key. Key schedule setup is avoided +# for 128-bit keys, if hardware support is detected. + +# Januray 2009. +# +# Add support for hardware AES192/256 and reschedule instructions to +# minimize/avoid Address Generation Interlock hazard and to favour +# dual-issue z10 pipeline. This gave ~25% improvement on z10 and +# almost 50% on z9. The gain is smaller on z10, because being dual- +# issue z10 makes it improssible to eliminate the interlock condition: +# critial path is not long enough. Yet it spends ~24 cycles per byte +# processed with 128-bit key. +# +# Unlike previous version hardware support detection takes place only +# at the moment of key schedule setup, which is denoted in key->rounds. +# This is done, because deferred key setup can't be made MT-safe, not +# for keys longer than 128 bits. +# +# Add AES_cbc_encrypt, which gives incredible performance improvement, +# it was measured to be ~6.6x. It's less than previously mentioned 8x, +# because software implementation was optimized. + +# May 2010. +# +# Add AES_ctr32_encrypt. If hardware-assisted, it provides up to 4.3x +# performance improvement over "generic" counter mode routine relying +# on single-block, also hardware-assisted, AES_encrypt. "Up to" refers +# to the fact that exact throughput value depends on current stack +# frame alignment within 4KB page. In worst case you get ~75% of the +# maximum, but *on average* it would be as much as ~98%. Meaning that +# worst case is unlike, it's like hitting ravine on plateau. + +# November 2010. +# +# Adapt for -m31 build. If kernel supports what's called "highgprs" +# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit +# instructions and achieve "64-bit" performance even in 31-bit legacy +# application context. The feature is not specific to any particular +# processor, as long as it's "z-CPU". Latter implies that the code +# remains z/Architecture specific. On z990 it was measured to perform +# 2x better than code generated by gcc 4.3. + +# December 2010. +# +# Add support for z196 "cipher message with counter" instruction. +# Note however that it's disengaged, because it was measured to +# perform ~12% worse than vanilla km-based code... + +# February 2011. +# +# Add AES_xts_[en|de]crypt. This includes support for z196 km-xts-aes +# instructions, which deliver ~70% improvement at 8KB block size over +# vanilla km-based code, 37% - at most like 512-bytes block size. + +$flavour = shift; + +if ($flavour =~ /3[12]/) { + $SIZE_T=4; + $g=""; +} else { + $SIZE_T=8; + $g="g"; +} + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +$softonly=0; # allow hardware support + +$t0="%r0"; $mask="%r0"; +$t1="%r1"; +$t2="%r2"; $inp="%r2"; +$t3="%r3"; $out="%r3"; $bits="%r3"; +$key="%r4"; +$i1="%r5"; +$i2="%r6"; +$i3="%r7"; +$s0="%r8"; +$s1="%r9"; +$s2="%r10"; +$s3="%r11"; +$tbl="%r12"; +$rounds="%r13"; +$ra="%r14"; +$sp="%r15"; + +$stdframe=16*$SIZE_T+4*8; + +sub _data_word() +{ my $i; + while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; } +} + +$code=<<___; +.text + +.type AES_Te,\@object +.align 256 +AES_Te: +___ +&_data_word( + 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, + 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, + 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, + 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, + 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, + 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, + 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, + 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, + 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, + 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, + 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, + 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, + 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, + 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, + 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, + 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, + 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, + 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, + 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, + 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, + 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, + 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, + 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, + 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, + 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, + 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, + 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, + 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, + 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, + 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, + 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, + 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, + 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, + 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, + 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, + 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, + 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, + 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, + 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, + 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, + 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, + 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, + 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, + 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, + 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, + 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, + 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, + 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, + 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, + 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, + 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, + 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, + 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, + 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, + 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, + 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, + 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, + 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, + 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, + 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, + 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, + 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, + 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, + 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a); +$code.=<<___; +# Te4[256] +.byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5 +.byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 +.byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0 +.byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 +.byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc +.byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 +.byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a +.byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 +.byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0 +.byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 +.byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b +.byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf +.byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85 +.byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 +.byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5 +.byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 +.byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17 +.byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 +.byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88 +.byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb +.byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c +.byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 +.byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9 +.byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 +.byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6 +.byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a +.byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e +.byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e +.byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94 +.byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf +.byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68 +.byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +# rcon[] +.long 0x01000000, 0x02000000, 0x04000000, 0x08000000 +.long 0x10000000, 0x20000000, 0x40000000, 0x80000000 +.long 0x1B000000, 0x36000000, 0, 0, 0, 0, 0, 0 +.align 256 +.size AES_Te,.-AES_Te + +# void AES_encrypt(const unsigned char *inp, unsigned char *out, +# const AES_KEY *key) { +.globl AES_encrypt +.type AES_encrypt,\@function +AES_encrypt: +___ +$code.=<<___ if (!$softonly); + l %r0,240($key) + lhi %r1,16 + clr %r0,%r1 + jl .Lesoft + + la %r1,0($key) + #la %r2,0($inp) + la %r4,0($out) + lghi %r3,16 # single block length + .long 0xb92e0042 # km %r4,%r2 + brc 1,.-4 # can this happen? + br %r14 +.align 64 +.Lesoft: +___ +$code.=<<___; + stm${g} %r3,$ra,3*$SIZE_T($sp) + + llgf $s0,0($inp) + llgf $s1,4($inp) + llgf $s2,8($inp) + llgf $s3,12($inp) + + larl $tbl,AES_Te + bras $ra,_s390x_AES_encrypt + + l${g} $out,3*$SIZE_T($sp) + st $s0,0($out) + st $s1,4($out) + st $s2,8($out) + st $s3,12($out) + + lm${g} %r6,$ra,6*$SIZE_T($sp) + br $ra +.size AES_encrypt,.-AES_encrypt + +.type _s390x_AES_encrypt,\@function +.align 16 +_s390x_AES_encrypt: + st${g} $ra,15*$SIZE_T($sp) + x $s0,0($key) + x $s1,4($key) + x $s2,8($key) + x $s3,12($key) + l $rounds,240($key) + llill $mask,`0xff<<3` + aghi $rounds,-1 + j .Lenc_loop +.align 16 +.Lenc_loop: + sllg $t1,$s0,`0+3` + srlg $t2,$s0,`8-3` + srlg $t3,$s0,`16-3` + srl $s0,`24-3` + nr $s0,$mask + ngr $t1,$mask + nr $t2,$mask + nr $t3,$mask + + srlg $i1,$s1,`16-3` # i0 + sllg $i2,$s1,`0+3` + srlg $i3,$s1,`8-3` + srl $s1,`24-3` + nr $i1,$mask + nr $s1,$mask + ngr $i2,$mask + nr $i3,$mask + + l $s0,0($s0,$tbl) # Te0[s0>>24] + l $t1,1($t1,$tbl) # Te3[s0>>0] + l $t2,2($t2,$tbl) # Te2[s0>>8] + l $t3,3($t3,$tbl) # Te1[s0>>16] + + x $s0,3($i1,$tbl) # Te1[s1>>16] + l $s1,0($s1,$tbl) # Te0[s1>>24] + x $t2,1($i2,$tbl) # Te3[s1>>0] + x $t3,2($i3,$tbl) # Te2[s1>>8] + + srlg $i1,$s2,`8-3` # i0 + srlg $i2,$s2,`16-3` # i1 + nr $i1,$mask + nr $i2,$mask + sllg $i3,$s2,`0+3` + srl $s2,`24-3` + nr $s2,$mask + ngr $i3,$mask + + xr $s1,$t1 + srlg $ra,$s3,`8-3` # i1 + sllg $t1,$s3,`0+3` # i0 + nr $ra,$mask + la $key,16($key) + ngr $t1,$mask + + x $s0,2($i1,$tbl) # Te2[s2>>8] + x $s1,3($i2,$tbl) # Te1[s2>>16] + l $s2,0($s2,$tbl) # Te0[s2>>24] + x $t3,1($i3,$tbl) # Te3[s2>>0] + + srlg $i3,$s3,`16-3` # i2 + xr $s2,$t2 + srl $s3,`24-3` + nr $i3,$mask + nr $s3,$mask + + x $s0,0($key) + x $s1,4($key) + x $s2,8($key) + x $t3,12($key) + + x $s0,1($t1,$tbl) # Te3[s3>>0] + x $s1,2($ra,$tbl) # Te2[s3>>8] + x $s2,3($i3,$tbl) # Te1[s3>>16] + l $s3,0($s3,$tbl) # Te0[s3>>24] + xr $s3,$t3 + + brct $rounds,.Lenc_loop + .align 16 + + sllg $t1,$s0,`0+3` + srlg $t2,$s0,`8-3` + ngr $t1,$mask + srlg $t3,$s0,`16-3` + srl $s0,`24-3` + nr $s0,$mask + nr $t2,$mask + nr $t3,$mask + + srlg $i1,$s1,`16-3` # i0 + sllg $i2,$s1,`0+3` + ngr $i2,$mask + srlg $i3,$s1,`8-3` + srl $s1,`24-3` + nr $i1,$mask + nr $s1,$mask + nr $i3,$mask + + llgc $s0,2($s0,$tbl) # Te4[s0>>24] + llgc $t1,2($t1,$tbl) # Te4[s0>>0] + sll $s0,24 + llgc $t2,2($t2,$tbl) # Te4[s0>>8] + llgc $t3,2($t3,$tbl) # Te4[s0>>16] + sll $t2,8 + sll $t3,16 + + llgc $i1,2($i1,$tbl) # Te4[s1>>16] + llgc $s1,2($s1,$tbl) # Te4[s1>>24] + llgc $i2,2($i2,$tbl) # Te4[s1>>0] + llgc $i3,2($i3,$tbl) # Te4[s1>>8] + sll $i1,16 + sll $s1,24 + sll $i3,8 + or $s0,$i1 + or $s1,$t1 + or $t2,$i2 + or $t3,$i3 + + srlg $i1,$s2,`8-3` # i0 + srlg $i2,$s2,`16-3` # i1 + nr $i1,$mask + nr $i2,$mask + sllg $i3,$s2,`0+3` + srl $s2,`24-3` + ngr $i3,$mask + nr $s2,$mask + + sllg $t1,$s3,`0+3` # i0 + srlg $ra,$s3,`8-3` # i1 + ngr $t1,$mask + + llgc $i1,2($i1,$tbl) # Te4[s2>>8] + llgc $i2,2($i2,$tbl) # Te4[s2>>16] + sll $i1,8 + llgc $s2,2($s2,$tbl) # Te4[s2>>24] + llgc $i3,2($i3,$tbl) # Te4[s2>>0] + sll $i2,16 + nr $ra,$mask + sll $s2,24 + or $s0,$i1 + or $s1,$i2 + or $s2,$t2 + or $t3,$i3 + + srlg $i3,$s3,`16-3` # i2 + srl $s3,`24-3` + nr $i3,$mask + nr $s3,$mask + + l $t0,16($key) + l $t2,20($key) + + llgc $i1,2($t1,$tbl) # Te4[s3>>0] + llgc $i2,2($ra,$tbl) # Te4[s3>>8] + llgc $i3,2($i3,$tbl) # Te4[s3>>16] + llgc $s3,2($s3,$tbl) # Te4[s3>>24] + sll $i2,8 + sll $i3,16 + sll $s3,24 + or $s0,$i1 + or $s1,$i2 + or $s2,$i3 + or $s3,$t3 + + l${g} $ra,15*$SIZE_T($sp) + xr $s0,$t0 + xr $s1,$t2 + x $s2,24($key) + x $s3,28($key) + + br $ra +.size _s390x_AES_encrypt,.-_s390x_AES_encrypt +___ + +$code.=<<___; +.type AES_Td,\@object +.align 256 +AES_Td: +___ +&_data_word( + 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, + 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, + 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, + 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, + 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, + 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, + 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, + 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, + 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, + 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, + 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, + 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, + 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, + 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, + 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, + 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, + 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, + 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, + 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, + 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, + 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, + 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, + 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, + 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, + 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, + 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, + 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, + 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, + 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, + 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, + 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, + 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, + 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, + 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, + 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, + 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, + 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, + 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, + 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, + 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, + 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, + 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, + 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, + 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, + 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, + 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, + 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, + 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, + 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, + 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, + 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, + 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, + 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, + 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, + 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, + 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, + 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, + 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, + 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, + 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, + 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, + 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, + 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, + 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742); +$code.=<<___; +# Td4[256] +.byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38 +.byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb +.byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87 +.byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb +.byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d +.byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e +.byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2 +.byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 +.byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16 +.byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 +.byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda +.byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 +.byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a +.byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 +.byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02 +.byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b +.byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea +.byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 +.byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85 +.byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e +.byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89 +.byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b +.byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20 +.byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 +.byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31 +.byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f +.byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d +.byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef +.byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0 +.byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 +.byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26 +.byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +.size AES_Td,.-AES_Td + +# void AES_decrypt(const unsigned char *inp, unsigned char *out, +# const AES_KEY *key) { +.globl AES_decrypt +.type AES_decrypt,\@function +AES_decrypt: +___ +$code.=<<___ if (!$softonly); + l %r0,240($key) + lhi %r1,16 + clr %r0,%r1 + jl .Ldsoft + + la %r1,0($key) + #la %r2,0($inp) + la %r4,0($out) + lghi %r3,16 # single block length + .long 0xb92e0042 # km %r4,%r2 + brc 1,.-4 # can this happen? + br %r14 +.align 64 +.Ldsoft: +___ +$code.=<<___; + stm${g} %r3,$ra,3*$SIZE_T($sp) + + llgf $s0,0($inp) + llgf $s1,4($inp) + llgf $s2,8($inp) + llgf $s3,12($inp) + + larl $tbl,AES_Td + bras $ra,_s390x_AES_decrypt + + l${g} $out,3*$SIZE_T($sp) + st $s0,0($out) + st $s1,4($out) + st $s2,8($out) + st $s3,12($out) + + lm${g} %r6,$ra,6*$SIZE_T($sp) + br $ra +.size AES_decrypt,.-AES_decrypt + +.type _s390x_AES_decrypt,\@function +.align 16 +_s390x_AES_decrypt: + st${g} $ra,15*$SIZE_T($sp) + x $s0,0($key) + x $s1,4($key) + x $s2,8($key) + x $s3,12($key) + l $rounds,240($key) + llill $mask,`0xff<<3` + aghi $rounds,-1 + j .Ldec_loop +.align 16 +.Ldec_loop: + srlg $t1,$s0,`16-3` + srlg $t2,$s0,`8-3` + sllg $t3,$s0,`0+3` + srl $s0,`24-3` + nr $s0,$mask + nr $t1,$mask + nr $t2,$mask + ngr $t3,$mask + + sllg $i1,$s1,`0+3` # i0 + srlg $i2,$s1,`16-3` + srlg $i3,$s1,`8-3` + srl $s1,`24-3` + ngr $i1,$mask + nr $s1,$mask + nr $i2,$mask + nr $i3,$mask + + l $s0,0($s0,$tbl) # Td0[s0>>24] + l $t1,3($t1,$tbl) # Td1[s0>>16] + l $t2,2($t2,$tbl) # Td2[s0>>8] + l $t3,1($t3,$tbl) # Td3[s0>>0] + + x $s0,1($i1,$tbl) # Td3[s1>>0] + l $s1,0($s1,$tbl) # Td0[s1>>24] + x $t2,3($i2,$tbl) # Td1[s1>>16] + x $t3,2($i3,$tbl) # Td2[s1>>8] + + srlg $i1,$s2,`8-3` # i0 + sllg $i2,$s2,`0+3` # i1 + srlg $i3,$s2,`16-3` + srl $s2,`24-3` + nr $i1,$mask + ngr $i2,$mask + nr $s2,$mask + nr $i3,$mask + + xr $s1,$t1 + srlg $ra,$s3,`8-3` # i1 + srlg $t1,$s3,`16-3` # i0 + nr $ra,$mask + la $key,16($key) + nr $t1,$mask + + x $s0,2($i1,$tbl) # Td2[s2>>8] + x $s1,1($i2,$tbl) # Td3[s2>>0] + l $s2,0($s2,$tbl) # Td0[s2>>24] + x $t3,3($i3,$tbl) # Td1[s2>>16] + + sllg $i3,$s3,`0+3` # i2 + srl $s3,`24-3` + ngr $i3,$mask + nr $s3,$mask + + xr $s2,$t2 + x $s0,0($key) + x $s1,4($key) + x $s2,8($key) + x $t3,12($key) + + x $s0,3($t1,$tbl) # Td1[s3>>16] + x $s1,2($ra,$tbl) # Td2[s3>>8] + x $s2,1($i3,$tbl) # Td3[s3>>0] + l $s3,0($s3,$tbl) # Td0[s3>>24] + xr $s3,$t3 + + brct $rounds,.Ldec_loop + .align 16 + + l $t1,`2048+0`($tbl) # prefetch Td4 + l $t2,`2048+64`($tbl) + l $t3,`2048+128`($tbl) + l $i1,`2048+192`($tbl) + llill $mask,0xff + + srlg $i3,$s0,24 # i0 + srlg $t1,$s0,16 + srlg $t2,$s0,8 + nr $s0,$mask # i3 + nr $t1,$mask + + srlg $i1,$s1,24 + nr $t2,$mask + srlg $i2,$s1,16 + srlg $ra,$s1,8 + nr $s1,$mask # i0 + nr $i2,$mask + nr $ra,$mask + + llgc $i3,2048($i3,$tbl) # Td4[s0>>24] + llgc $t1,2048($t1,$tbl) # Td4[s0>>16] + llgc $t2,2048($t2,$tbl) # Td4[s0>>8] + sll $t1,16 + llgc $t3,2048($s0,$tbl) # Td4[s0>>0] + sllg $s0,$i3,24 + sll $t2,8 + + llgc $s1,2048($s1,$tbl) # Td4[s1>>0] + llgc $i1,2048($i1,$tbl) # Td4[s1>>24] + llgc $i2,2048($i2,$tbl) # Td4[s1>>16] + sll $i1,24 + llgc $i3,2048($ra,$tbl) # Td4[s1>>8] + sll $i2,16 + sll $i3,8 + or $s0,$s1 + or $t1,$i1 + or $t2,$i2 + or $t3,$i3 + + srlg $i1,$s2,8 # i0 + srlg $i2,$s2,24 + srlg $i3,$s2,16 + nr $s2,$mask # i1 + nr $i1,$mask + nr $i3,$mask + llgc $i1,2048($i1,$tbl) # Td4[s2>>8] + llgc $s1,2048($s2,$tbl) # Td4[s2>>0] + llgc $i2,2048($i2,$tbl) # Td4[s2>>24] + llgc $i3,2048($i3,$tbl) # Td4[s2>>16] + sll $i1,8 + sll $i2,24 + or $s0,$i1 + sll $i3,16 + or $t2,$i2 + or $t3,$i3 + + srlg $i1,$s3,16 # i0 + srlg $i2,$s3,8 # i1 + srlg $i3,$s3,24 + nr $s3,$mask # i2 + nr $i1,$mask + nr $i2,$mask + + l${g} $ra,15*$SIZE_T($sp) + or $s1,$t1 + l $t0,16($key) + l $t1,20($key) + + llgc $i1,2048($i1,$tbl) # Td4[s3>>16] + llgc $i2,2048($i2,$tbl) # Td4[s3>>8] + sll $i1,16 + llgc $s2,2048($s3,$tbl) # Td4[s3>>0] + llgc $s3,2048($i3,$tbl) # Td4[s3>>24] + sll $i2,8 + sll $s3,24 + or $s0,$i1 + or $s1,$i2 + or $s2,$t2 + or $s3,$t3 + + xr $s0,$t0 + xr $s1,$t1 + x $s2,24($key) + x $s3,28($key) + + br $ra +.size _s390x_AES_decrypt,.-_s390x_AES_decrypt +___ + +$code.=<<___; +# void AES_set_encrypt_key(const unsigned char *in, int bits, +# AES_KEY *key) { +.globl private_AES_set_encrypt_key +.type private_AES_set_encrypt_key,\@function +.align 16 +private_AES_set_encrypt_key: +_s390x_AES_set_encrypt_key: + lghi $t0,0 + cl${g}r $inp,$t0 + je .Lminus1 + cl${g}r $key,$t0 + je .Lminus1 + + lghi $t0,128 + clr $bits,$t0 + je .Lproceed + lghi $t0,192 + clr $bits,$t0 + je .Lproceed + lghi $t0,256 + clr $bits,$t0 + je .Lproceed + lghi %r2,-2 + br %r14 + +.align 16 +.Lproceed: +___ +$code.=<<___ if (!$softonly); + # convert bits to km code, [128,192,256]->[18,19,20] + lhi %r5,-128 + lhi %r0,18 + ar %r5,$bits + srl %r5,6 + ar %r5,%r0 + + larl %r1,OPENSSL_s390xcap_P + lg %r0,0(%r1) + tmhl %r0,0x4000 # check for message-security assist + jz .Lekey_internal + + lghi %r0,0 # query capability vector + la %r1,16($sp) + .long 0xb92f0042 # kmc %r4,%r2 + + llihh %r1,0x8000 + srlg %r1,%r1,0(%r5) + ng %r1,16($sp) + jz .Lekey_internal + + lmg %r0,%r1,0($inp) # just copy 128 bits... + stmg %r0,%r1,0($key) + lhi %r0,192 + cr $bits,%r0 + jl 1f + lg %r1,16($inp) + stg %r1,16($key) + je 1f + lg %r1,24($inp) + stg %r1,24($key) +1: st $bits,236($key) # save bits [for debugging purposes] + lgr $t0,%r5 + st %r5,240($key) # save km code + lghi %r2,0 + br %r14 +___ +$code.=<<___; +.align 16 +.Lekey_internal: + stm${g} %r4,%r13,4*$SIZE_T($sp) # all non-volatile regs and $key + + larl $tbl,AES_Te+2048 + + llgf $s0,0($inp) + llgf $s1,4($inp) + llgf $s2,8($inp) + llgf $s3,12($inp) + st $s0,0($key) + st $s1,4($key) + st $s2,8($key) + st $s3,12($key) + lghi $t0,128 + cr $bits,$t0 + jne .Lnot128 + + llill $mask,0xff + lghi $t3,0 # i=0 + lghi $rounds,10 + st $rounds,240($key) + + llgfr $t2,$s3 # temp=rk[3] + srlg $i1,$s3,8 + srlg $i2,$s3,16 + srlg $i3,$s3,24 + nr $t2,$mask + nr $i1,$mask + nr $i2,$mask + +.align 16 +.L128_loop: + la $t2,0($t2,$tbl) + la $i1,0($i1,$tbl) + la $i2,0($i2,$tbl) + la $i3,0($i3,$tbl) + icm $t2,2,0($t2) # Te4[rk[3]>>0]<<8 + icm $t2,4,0($i1) # Te4[rk[3]>>8]<<16 + icm $t2,8,0($i2) # Te4[rk[3]>>16]<<24 + icm $t2,1,0($i3) # Te4[rk[3]>>24] + x $t2,256($t3,$tbl) # rcon[i] + xr $s0,$t2 # rk[4]=rk[0]^... + xr $s1,$s0 # rk[5]=rk[1]^rk[4] + xr $s2,$s1 # rk[6]=rk[2]^rk[5] + xr $s3,$s2 # rk[7]=rk[3]^rk[6] + + llgfr $t2,$s3 # temp=rk[3] + srlg $i1,$s3,8 + srlg $i2,$s3,16 + nr $t2,$mask + nr $i1,$mask + srlg $i3,$s3,24 + nr $i2,$mask + + st $s0,16($key) + st $s1,20($key) + st $s2,24($key) + st $s3,28($key) + la $key,16($key) # key+=4 + la $t3,4($t3) # i++ + brct $rounds,.L128_loop + lghi $t0,10 + lghi %r2,0 + lm${g} %r4,%r13,4*$SIZE_T($sp) + br $ra + +.align 16 +.Lnot128: + llgf $t0,16($inp) + llgf $t1,20($inp) + st $t0,16($key) + st $t1,20($key) + lghi $t0,192 + cr $bits,$t0 + jne .Lnot192 + + llill $mask,0xff + lghi $t3,0 # i=0 + lghi $rounds,12 + st $rounds,240($key) + lghi $rounds,8 + + srlg $i1,$t1,8 + srlg $i2,$t1,16 + srlg $i3,$t1,24 + nr $t1,$mask + nr $i1,$mask + nr $i2,$mask + +.align 16 +.L192_loop: + la $t1,0($t1,$tbl) + la $i1,0($i1,$tbl) + la $i2,0($i2,$tbl) + la $i3,0($i3,$tbl) + icm $t1,2,0($t1) # Te4[rk[5]>>0]<<8 + icm $t1,4,0($i1) # Te4[rk[5]>>8]<<16 + icm $t1,8,0($i2) # Te4[rk[5]>>16]<<24 + icm $t1,1,0($i3) # Te4[rk[5]>>24] + x $t1,256($t3,$tbl) # rcon[i] + xr $s0,$t1 # rk[6]=rk[0]^... + xr $s1,$s0 # rk[7]=rk[1]^rk[6] + xr $s2,$s1 # rk[8]=rk[2]^rk[7] + xr $s3,$s2 # rk[9]=rk[3]^rk[8] + + st $s0,24($key) + st $s1,28($key) + st $s2,32($key) + st $s3,36($key) + brct $rounds,.L192_continue + lghi $t0,12 + lghi %r2,0 + lm${g} %r4,%r13,4*$SIZE_T($sp) + br $ra + +.align 16 +.L192_continue: + lgr $t1,$s3 + x $t1,16($key) # rk[10]=rk[4]^rk[9] + st $t1,40($key) + x $t1,20($key) # rk[11]=rk[5]^rk[10] + st $t1,44($key) + + srlg $i1,$t1,8 + srlg $i2,$t1,16 + srlg $i3,$t1,24 + nr $t1,$mask + nr $i1,$mask + nr $i2,$mask + + la $key,24($key) # key+=6 + la $t3,4($t3) # i++ + j .L192_loop + +.align 16 +.Lnot192: + llgf $t0,24($inp) + llgf $t1,28($inp) + st $t0,24($key) + st $t1,28($key) + llill $mask,0xff + lghi $t3,0 # i=0 + lghi $rounds,14 + st $rounds,240($key) + lghi $rounds,7 + + srlg $i1,$t1,8 + srlg $i2,$t1,16 + srlg $i3,$t1,24 + nr $t1,$mask + nr $i1,$mask + nr $i2,$mask + +.align 16 +.L256_loop: + la $t1,0($t1,$tbl) + la $i1,0($i1,$tbl) + la $i2,0($i2,$tbl) + la $i3,0($i3,$tbl) + icm $t1,2,0($t1) # Te4[rk[7]>>0]<<8 + icm $t1,4,0($i1) # Te4[rk[7]>>8]<<16 + icm $t1,8,0($i2) # Te4[rk[7]>>16]<<24 + icm $t1,1,0($i3) # Te4[rk[7]>>24] + x $t1,256($t3,$tbl) # rcon[i] + xr $s0,$t1 # rk[8]=rk[0]^... + xr $s1,$s0 # rk[9]=rk[1]^rk[8] + xr $s2,$s1 # rk[10]=rk[2]^rk[9] + xr $s3,$s2 # rk[11]=rk[3]^rk[10] + st $s0,32($key) + st $s1,36($key) + st $s2,40($key) + st $s3,44($key) + brct $rounds,.L256_continue + lghi $t0,14 + lghi %r2,0 + lm${g} %r4,%r13,4*$SIZE_T($sp) + br $ra + +.align 16 +.L256_continue: + lgr $t1,$s3 # temp=rk[11] + srlg $i1,$s3,8 + srlg $i2,$s3,16 + srlg $i3,$s3,24 + nr $t1,$mask + nr $i1,$mask + nr $i2,$mask + la $t1,0($t1,$tbl) + la $i1,0($i1,$tbl) + la $i2,0($i2,$tbl) + la $i3,0($i3,$tbl) + llgc $t1,0($t1) # Te4[rk[11]>>0] + icm $t1,2,0($i1) # Te4[rk[11]>>8]<<8 + icm $t1,4,0($i2) # Te4[rk[11]>>16]<<16 + icm $t1,8,0($i3) # Te4[rk[11]>>24]<<24 + x $t1,16($key) # rk[12]=rk[4]^... + st $t1,48($key) + x $t1,20($key) # rk[13]=rk[5]^rk[12] + st $t1,52($key) + x $t1,24($key) # rk[14]=rk[6]^rk[13] + st $t1,56($key) + x $t1,28($key) # rk[15]=rk[7]^rk[14] + st $t1,60($key) + + srlg $i1,$t1,8 + srlg $i2,$t1,16 + srlg $i3,$t1,24 + nr $t1,$mask + nr $i1,$mask + nr $i2,$mask + + la $key,32($key) # key+=8 + la $t3,4($t3) # i++ + j .L256_loop + +.Lminus1: + lghi %r2,-1 + br $ra +.size private_AES_set_encrypt_key,.-private_AES_set_encrypt_key + +# void AES_set_decrypt_key(const unsigned char *in, int bits, +# AES_KEY *key) { +.globl private_AES_set_decrypt_key +.type private_AES_set_decrypt_key,\@function +.align 16 +private_AES_set_decrypt_key: + #st${g} $key,4*$SIZE_T($sp) # I rely on AES_set_encrypt_key to + st${g} $ra,14*$SIZE_T($sp) # save non-volatile registers and $key! + bras $ra,_s390x_AES_set_encrypt_key + #l${g} $key,4*$SIZE_T($sp) + l${g} $ra,14*$SIZE_T($sp) + ltgr %r2,%r2 + bnzr $ra +___ +$code.=<<___ if (!$softonly); + #l $t0,240($key) + lhi $t1,16 + cr $t0,$t1 + jl .Lgo + oill $t0,0x80 # set "decrypt" bit + st $t0,240($key) + br $ra +___ +$code.=<<___; +.align 16 +.Lgo: lgr $rounds,$t0 #llgf $rounds,240($key) + la $i1,0($key) + sllg $i2,$rounds,4 + la $i2,0($i2,$key) + srl $rounds,1 + lghi $t1,-16 + +.align 16 +.Linv: lmg $s0,$s1,0($i1) + lmg $s2,$s3,0($i2) + stmg $s0,$s1,0($i2) + stmg $s2,$s3,0($i1) + la $i1,16($i1) + la $i2,0($t1,$i2) + brct $rounds,.Linv +___ +$mask80=$i1; +$mask1b=$i2; +$maskfe=$i3; +$code.=<<___; + llgf $rounds,240($key) + aghi $rounds,-1 + sll $rounds,2 # (rounds-1)*4 + llilh $mask80,0x8080 + llilh $mask1b,0x1b1b + llilh $maskfe,0xfefe + oill $mask80,0x8080 + oill $mask1b,0x1b1b + oill $maskfe,0xfefe + +.align 16 +.Lmix: l $s0,16($key) # tp1 + lr $s1,$s0 + ngr $s1,$mask80 + srlg $t1,$s1,7 + slr $s1,$t1 + nr $s1,$mask1b + sllg $t1,$s0,1 + nr $t1,$maskfe + xr $s1,$t1 # tp2 + + lr $s2,$s1 + ngr $s2,$mask80 + srlg $t1,$s2,7 + slr $s2,$t1 + nr $s2,$mask1b + sllg $t1,$s1,1 + nr $t1,$maskfe + xr $s2,$t1 # tp4 + + lr $s3,$s2 + ngr $s3,$mask80 + srlg $t1,$s3,7 + slr $s3,$t1 + nr $s3,$mask1b + sllg $t1,$s2,1 + nr $t1,$maskfe + xr $s3,$t1 # tp8 + + xr $s1,$s0 # tp2^tp1 + xr $s2,$s0 # tp4^tp1 + rll $s0,$s0,24 # = ROTATE(tp1,8) + xr $s2,$s3 # ^=tp8 + xr $s0,$s1 # ^=tp2^tp1 + xr $s1,$s3 # tp2^tp1^tp8 + xr $s0,$s2 # ^=tp4^tp1^tp8 + rll $s1,$s1,8 + rll $s2,$s2,16 + xr $s0,$s1 # ^= ROTATE(tp8^tp2^tp1,24) + rll $s3,$s3,24 + xr $s0,$s2 # ^= ROTATE(tp8^tp4^tp1,16) + xr $s0,$s3 # ^= ROTATE(tp8,8) + + st $s0,16($key) + la $key,4($key) + brct $rounds,.Lmix + + lm${g} %r6,%r13,6*$SIZE_T($sp)# as was saved by AES_set_encrypt_key! + lghi %r2,0 + br $ra +.size private_AES_set_decrypt_key,.-private_AES_set_decrypt_key +___ + +######################################################################## +# void AES_cbc_encrypt(const unsigned char *in, unsigned char *out, +# size_t length, const AES_KEY *key, +# unsigned char *ivec, const int enc) +{ +my $inp="%r2"; +my $out="%r4"; # length and out are swapped +my $len="%r3"; +my $key="%r5"; +my $ivp="%r6"; + +$code.=<<___; +.globl AES_cbc_encrypt +.type AES_cbc_encrypt,\@function +.align 16 +AES_cbc_encrypt: + xgr %r3,%r4 # flip %r3 and %r4, out and len + xgr %r4,%r3 + xgr %r3,%r4 +___ +$code.=<<___ if (!$softonly); + lhi %r0,16 + cl %r0,240($key) + jh .Lcbc_software + + lg %r0,0($ivp) # copy ivec + lg %r1,8($ivp) + stmg %r0,%r1,16($sp) + lmg %r0,%r1,0($key) # copy key, cover 256 bit + stmg %r0,%r1,32($sp) + lmg %r0,%r1,16($key) + stmg %r0,%r1,48($sp) + l %r0,240($key) # load kmc code + lghi $key,15 # res=len%16, len-=res; + ngr $key,$len + sl${g}r $len,$key + la %r1,16($sp) # parameter block - ivec || key + jz .Lkmc_truncated + .long 0xb92f0042 # kmc %r4,%r2 + brc 1,.-4 # pay attention to "partial completion" + ltr $key,$key + jnz .Lkmc_truncated +.Lkmc_done: + lmg %r0,%r1,16($sp) # copy ivec to caller + stg %r0,0($ivp) + stg %r1,8($ivp) + br $ra +.align 16 +.Lkmc_truncated: + ahi $key,-1 # it's the way it's encoded in mvc + tmll %r0,0x80 + jnz .Lkmc_truncated_dec + lghi %r1,0 + stg %r1,16*$SIZE_T($sp) + stg %r1,16*$SIZE_T+8($sp) + bras %r1,1f + mvc 16*$SIZE_T(1,$sp),0($inp) +1: ex $key,0(%r1) + la %r1,16($sp) # restore parameter block + la $inp,16*$SIZE_T($sp) + lghi $len,16 + .long 0xb92f0042 # kmc %r4,%r2 + j .Lkmc_done +.align 16 +.Lkmc_truncated_dec: + st${g} $out,4*$SIZE_T($sp) + la $out,16*$SIZE_T($sp) + lghi $len,16 + .long 0xb92f0042 # kmc %r4,%r2 + l${g} $out,4*$SIZE_T($sp) + bras %r1,2f + mvc 0(1,$out),16*$SIZE_T($sp) +2: ex $key,0(%r1) + j .Lkmc_done +.align 16 +.Lcbc_software: +___ +$code.=<<___; + stm${g} $key,$ra,5*$SIZE_T($sp) + lhi %r0,0 + cl %r0,`$stdframe+$SIZE_T-4`($sp) + je .Lcbc_decrypt + + larl $tbl,AES_Te + + llgf $s0,0($ivp) + llgf $s1,4($ivp) + llgf $s2,8($ivp) + llgf $s3,12($ivp) + + lghi $t0,16 + sl${g}r $len,$t0 + brc 4,.Lcbc_enc_tail # if borrow +.Lcbc_enc_loop: + stm${g} $inp,$out,2*$SIZE_T($sp) + x $s0,0($inp) + x $s1,4($inp) + x $s2,8($inp) + x $s3,12($inp) + lgr %r4,$key + + bras $ra,_s390x_AES_encrypt + + lm${g} $inp,$key,2*$SIZE_T($sp) + st $s0,0($out) + st $s1,4($out) + st $s2,8($out) + st $s3,12($out) + + la $inp,16($inp) + la $out,16($out) + lghi $t0,16 + lt${g}r $len,$len + jz .Lcbc_enc_done + sl${g}r $len,$t0 + brc 4,.Lcbc_enc_tail # if borrow + j .Lcbc_enc_loop +.align 16 +.Lcbc_enc_done: + l${g} $ivp,6*$SIZE_T($sp) + st $s0,0($ivp) + st $s1,4($ivp) + st $s2,8($ivp) + st $s3,12($ivp) + + lm${g} %r7,$ra,7*$SIZE_T($sp) + br $ra + +.align 16 +.Lcbc_enc_tail: + aghi $len,15 + lghi $t0,0 + stg $t0,16*$SIZE_T($sp) + stg $t0,16*$SIZE_T+8($sp) + bras $t1,3f + mvc 16*$SIZE_T(1,$sp),0($inp) +3: ex $len,0($t1) + lghi $len,0 + la $inp,16*$SIZE_T($sp) + j .Lcbc_enc_loop + +.align 16 +.Lcbc_decrypt: + larl $tbl,AES_Td + + lg $t0,0($ivp) + lg $t1,8($ivp) + stmg $t0,$t1,16*$SIZE_T($sp) + +.Lcbc_dec_loop: + stm${g} $inp,$out,2*$SIZE_T($sp) + llgf $s0,0($inp) + llgf $s1,4($inp) + llgf $s2,8($inp) + llgf $s3,12($inp) + lgr %r4,$key + + bras $ra,_s390x_AES_decrypt + + lm${g} $inp,$key,2*$SIZE_T($sp) + sllg $s0,$s0,32 + sllg $s2,$s2,32 + lr $s0,$s1 + lr $s2,$s3 + + lg $t0,0($inp) + lg $t1,8($inp) + xg $s0,16*$SIZE_T($sp) + xg $s2,16*$SIZE_T+8($sp) + lghi $s1,16 + sl${g}r $len,$s1 + brc 4,.Lcbc_dec_tail # if borrow + brc 2,.Lcbc_dec_done # if zero + stg $s0,0($out) + stg $s2,8($out) + stmg $t0,$t1,16*$SIZE_T($sp) + + la $inp,16($inp) + la $out,16($out) + j .Lcbc_dec_loop + +.Lcbc_dec_done: + stg $s0,0($out) + stg $s2,8($out) +.Lcbc_dec_exit: + lm${g} %r6,$ra,6*$SIZE_T($sp) + stmg $t0,$t1,0($ivp) + + br $ra + +.align 16 +.Lcbc_dec_tail: + aghi $len,15 + stg $s0,16*$SIZE_T($sp) + stg $s2,16*$SIZE_T+8($sp) + bras $s1,4f + mvc 0(1,$out),16*$SIZE_T($sp) +4: ex $len,0($s1) + j .Lcbc_dec_exit +.size AES_cbc_encrypt,.-AES_cbc_encrypt +___ +} +######################################################################## +# void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, +# size_t blocks, const AES_KEY *key, +# const unsigned char *ivec) +{ +my $inp="%r2"; +my $out="%r4"; # blocks and out are swapped +my $len="%r3"; +my $key="%r5"; my $iv0="%r5"; +my $ivp="%r6"; +my $fp ="%r7"; + +$code.=<<___; +.globl AES_ctr32_encrypt +.type AES_ctr32_encrypt,\@function +.align 16 +AES_ctr32_encrypt: + xgr %r3,%r4 # flip %r3 and %r4, $out and $len + xgr %r4,%r3 + xgr %r3,%r4 + llgfr $len,$len # safe in ctr32 subroutine even in 64-bit case +___ +$code.=<<___ if (!$softonly); + l %r0,240($key) + lhi %r1,16 + clr %r0,%r1 + jl .Lctr32_software + + stm${g} %r6,$s3,6*$SIZE_T($sp) + + slgr $out,$inp + la %r1,0($key) # %r1 is permanent copy of $key + lg $iv0,0($ivp) # load ivec + lg $ivp,8($ivp) + + # prepare and allocate stack frame at the top of 4K page + # with 1K reserved for eventual signal handling + lghi $s0,-1024-256-16# guarantee at least 256-bytes buffer + lghi $s1,-4096 + algr $s0,$sp + lgr $fp,$sp + ngr $s0,$s1 # align at page boundary + slgr $fp,$s0 # total buffer size + lgr $s2,$sp + lghi $s1,1024+16 # sl[g]fi is extended-immediate facility + slgr $fp,$s1 # deduct reservation to get usable buffer size + # buffer size is at lest 256 and at most 3072+256-16 + + la $sp,1024($s0) # alloca + srlg $fp,$fp,4 # convert bytes to blocks, minimum 16 + st${g} $s2,0($sp) # back-chain + st${g} $fp,$SIZE_T($sp) + + slgr $len,$fp + brc 1,.Lctr32_hw_switch # not zero, no borrow + algr $fp,$len # input is shorter than allocated buffer + lghi $len,0 + st${g} $fp,$SIZE_T($sp) + +.Lctr32_hw_switch: +___ +$code.=<<___ if (0); ######### kmctr code was measured to be ~12% slower + larl $s0,OPENSSL_s390xcap_P + lg $s0,8($s0) + tmhh $s0,0x0004 # check for message_security-assist-4 + jz .Lctr32_km_loop + + llgfr $s0,%r0 + lgr $s1,%r1 + lghi %r0,0 + la %r1,16($sp) + .long 0xb92d2042 # kmctr %r4,%r2,%r2 + + llihh %r0,0x8000 # check if kmctr supports the function code + srlg %r0,%r0,0($s0) + ng %r0,16($sp) + lgr %r0,$s0 + lgr %r1,$s1 + jz .Lctr32_km_loop + +####### kmctr code + algr $out,$inp # restore $out + lgr $s1,$len # $s1 undertakes $len + j .Lctr32_kmctr_loop +.align 16 +.Lctr32_kmctr_loop: + la $s2,16($sp) + lgr $s3,$fp +.Lctr32_kmctr_prepare: + stg $iv0,0($s2) + stg $ivp,8($s2) + la $s2,16($s2) + ahi $ivp,1 # 32-bit increment, preserves upper half + brct $s3,.Lctr32_kmctr_prepare + + #la $inp,0($inp) # inp + sllg $len,$fp,4 # len + #la $out,0($out) # out + la $s2,16($sp) # iv + .long 0xb92da042 # kmctr $out,$s2,$inp + brc 1,.-4 # pay attention to "partial completion" + + slgr $s1,$fp + brc 1,.Lctr32_kmctr_loop # not zero, no borrow + algr $fp,$s1 + lghi $s1,0 + brc 4+1,.Lctr32_kmctr_loop # not zero + + l${g} $sp,0($sp) + lm${g} %r6,$s3,6*$SIZE_T($sp) + br $ra +.align 16 +___ +$code.=<<___; +.Lctr32_km_loop: + la $s2,16($sp) + lgr $s3,$fp +.Lctr32_km_prepare: + stg $iv0,0($s2) + stg $ivp,8($s2) + la $s2,16($s2) + ahi $ivp,1 # 32-bit increment, preserves upper half + brct $s3,.Lctr32_km_prepare + + la $s0,16($sp) # inp + sllg $s1,$fp,4 # len + la $s2,16($sp) # out + .long 0xb92e00a8 # km %r10,%r8 + brc 1,.-4 # pay attention to "partial completion" + + la $s2,16($sp) + lgr $s3,$fp + slgr $s2,$inp +.Lctr32_km_xor: + lg $s0,0($inp) + lg $s1,8($inp) + xg $s0,0($s2,$inp) + xg $s1,8($s2,$inp) + stg $s0,0($out,$inp) + stg $s1,8($out,$inp) + la $inp,16($inp) + brct $s3,.Lctr32_km_xor + + slgr $len,$fp + brc 1,.Lctr32_km_loop # not zero, no borrow + algr $fp,$len + lghi $len,0 + brc 4+1,.Lctr32_km_loop # not zero + + l${g} $s0,0($sp) + l${g} $s1,$SIZE_T($sp) + la $s2,16($sp) +.Lctr32_km_zap: + stg $s0,0($s2) + stg $s0,8($s2) + la $s2,16($s2) + brct $s1,.Lctr32_km_zap + + la $sp,0($s0) + lm${g} %r6,$s3,6*$SIZE_T($sp) + br $ra +.align 16 +.Lctr32_software: +___ +$code.=<<___; + stm${g} $key,$ra,5*$SIZE_T($sp) + sl${g}r $inp,$out + larl $tbl,AES_Te + llgf $t1,12($ivp) + +.Lctr32_loop: + stm${g} $inp,$out,2*$SIZE_T($sp) + llgf $s0,0($ivp) + llgf $s1,4($ivp) + llgf $s2,8($ivp) + lgr $s3,$t1 + st $t1,16*$SIZE_T($sp) + lgr %r4,$key + + bras $ra,_s390x_AES_encrypt + + lm${g} $inp,$ivp,2*$SIZE_T($sp) + llgf $t1,16*$SIZE_T($sp) + x $s0,0($inp,$out) + x $s1,4($inp,$out) + x $s2,8($inp,$out) + x $s3,12($inp,$out) + stm $s0,$s3,0($out) + + la $out,16($out) + ahi $t1,1 # 32-bit increment + brct $len,.Lctr32_loop + + lm${g} %r6,$ra,6*$SIZE_T($sp) + br $ra +.size AES_ctr32_encrypt,.-AES_ctr32_encrypt +___ +} + +######################################################################## +# void AES_xts_encrypt(const char *inp,char *out,size_t len, +# const AES_KEY *key1, const AES_KEY *key2, +# const unsigned char iv[16]); +# +{ +my $inp="%r2"; +my $out="%r4"; # len and out are swapped +my $len="%r3"; +my $key1="%r5"; # $i1 +my $key2="%r6"; # $i2 +my $fp="%r7"; # $i3 +my $tweak=16*$SIZE_T+16; # or $stdframe-16, bottom of the frame... + +$code.=<<___; +.type _s390x_xts_km,\@function +.align 16 +_s390x_xts_km: +___ +$code.=<<___ if(1); + llgfr $s0,%r0 # put aside the function code + lghi $s1,0x7f + nr $s1,%r0 + lghi %r0,0 # query capability vector + la %r1,$tweak-16($sp) + .long 0xb92e0042 # km %r4,%r2 + llihh %r1,0x8000 + srlg %r1,%r1,32($s1) # check for 32+function code + ng %r1,$tweak-16($sp) + lgr %r0,$s0 # restore the function code + la %r1,0($key1) # restore $key1 + jz .Lxts_km_vanilla + + lmg $i2,$i3,$tweak($sp) # put aside the tweak value + algr $out,$inp + + oill %r0,32 # switch to xts function code + aghi $s1,-18 # + sllg $s1,$s1,3 # (function code - 18)*8, 0 or 16 + la %r1,$tweak-16($sp) + slgr %r1,$s1 # parameter block position + lmg $s0,$s3,0($key1) # load 256 bits of key material, + stmg $s0,$s3,0(%r1) # and copy it to parameter block. + # yes, it contains junk and overlaps + # with the tweak in 128-bit case. + # it's done to avoid conditional + # branch. + stmg $i2,$i3,$tweak($sp) # "re-seat" the tweak value + + .long 0xb92e0042 # km %r4,%r2 + brc 1,.-4 # pay attention to "partial completion" + + lrvg $s0,$tweak+0($sp) # load the last tweak + lrvg $s1,$tweak+8($sp) + stmg %r0,%r3,$tweak-32($sp) # wipe copy of the key + + nill %r0,0xffdf # switch back to original function code + la %r1,0($key1) # restore pointer to $key1 + slgr $out,$inp + + llgc $len,2*$SIZE_T-1($sp) + nill $len,0x0f # $len%=16 + br $ra + +.align 16 +.Lxts_km_vanilla: +___ +$code.=<<___; + # prepare and allocate stack frame at the top of 4K page + # with 1K reserved for eventual signal handling + lghi $s0,-1024-256-16# guarantee at least 256-bytes buffer + lghi $s1,-4096 + algr $s0,$sp + lgr $fp,$sp + ngr $s0,$s1 # align at page boundary + slgr $fp,$s0 # total buffer size + lgr $s2,$sp + lghi $s1,1024+16 # sl[g]fi is extended-immediate facility + slgr $fp,$s1 # deduct reservation to get usable buffer size + # buffer size is at lest 256 and at most 3072+256-16 + + la $sp,1024($s0) # alloca + nill $fp,0xfff0 # round to 16*n + st${g} $s2,0($sp) # back-chain + nill $len,0xfff0 # redundant + st${g} $fp,$SIZE_T($sp) + + slgr $len,$fp + brc 1,.Lxts_km_go # not zero, no borrow + algr $fp,$len # input is shorter than allocated buffer + lghi $len,0 + st${g} $fp,$SIZE_T($sp) + +.Lxts_km_go: + lrvg $s0,$tweak+0($s2) # load the tweak value in little-endian + lrvg $s1,$tweak+8($s2) + + la $s2,16($sp) # vector of ascending tweak values + slgr $s2,$inp + srlg $s3,$fp,4 + j .Lxts_km_start + +.Lxts_km_loop: + la $s2,16($sp) + slgr $s2,$inp + srlg $s3,$fp,4 +.Lxts_km_prepare: + lghi $i1,0x87 + srag $i2,$s1,63 # broadcast upper bit + ngr $i1,$i2 # rem + algr $s0,$s0 + alcgr $s1,$s1 + xgr $s0,$i1 +.Lxts_km_start: + lrvgr $i1,$s0 # flip byte order + lrvgr $i2,$s1 + stg $i1,0($s2,$inp) + stg $i2,8($s2,$inp) + xg $i1,0($inp) + xg $i2,8($inp) + stg $i1,0($out,$inp) + stg $i2,8($out,$inp) + la $inp,16($inp) + brct $s3,.Lxts_km_prepare + + slgr $inp,$fp # rewind $inp + la $s2,0($out,$inp) + lgr $s3,$fp + .long 0xb92e00aa # km $s2,$s2 + brc 1,.-4 # pay attention to "partial completion" + + la $s2,16($sp) + slgr $s2,$inp + srlg $s3,$fp,4 +.Lxts_km_xor: + lg $i1,0($out,$inp) + lg $i2,8($out,$inp) + xg $i1,0($s2,$inp) + xg $i2,8($s2,$inp) + stg $i1,0($out,$inp) + stg $i2,8($out,$inp) + la $inp,16($inp) + brct $s3,.Lxts_km_xor + + slgr $len,$fp + brc 1,.Lxts_km_loop # not zero, no borrow + algr $fp,$len + lghi $len,0 + brc 4+1,.Lxts_km_loop # not zero + + l${g} $i1,0($sp) # back-chain + llgf $fp,`2*$SIZE_T-4`($sp) # bytes used + la $i2,16($sp) + srlg $fp,$fp,4 +.Lxts_km_zap: + stg $i1,0($i2) + stg $i1,8($i2) + la $i2,16($i2) + brct $fp,.Lxts_km_zap + + la $sp,0($i1) + llgc $len,2*$SIZE_T-1($i1) + nill $len,0x0f # $len%=16 + bzr $ra + + # generate one more tweak... + lghi $i1,0x87 + srag $i2,$s1,63 # broadcast upper bit + ngr $i1,$i2 # rem + algr $s0,$s0 + alcgr $s1,$s1 + xgr $s0,$i1 + + ltr $len,$len # clear zero flag + br $ra +.size _s390x_xts_km,.-_s390x_xts_km + +.globl AES_xts_encrypt +.type AES_xts_encrypt,\@function +.align 16 +AES_xts_encrypt: + xgr %r3,%r4 # flip %r3 and %r4, $out and $len + xgr %r4,%r3 + xgr %r3,%r4 +___ +$code.=<<___ if ($SIZE_T==4); + llgfr $len,$len +___ +$code.=<<___; + st${g} $len,1*$SIZE_T($sp) # save copy of $len + srag $len,$len,4 # formally wrong, because it expands + # sign byte, but who can afford asking + # to process more than 2^63-1 bytes? + # I use it, because it sets condition + # code... + bcr 8,$ra # abort if zero (i.e. less than 16) +___ +$code.=<<___ if (!$softonly); + llgf %r0,240($key2) + lhi %r1,16 + clr %r0,%r1 + jl .Lxts_enc_software + + st${g} $ra,5*$SIZE_T($sp) + stm${g} %r6,$s3,6*$SIZE_T($sp) + + sllg $len,$len,4 # $len&=~15 + slgr $out,$inp + + # generate the tweak value + l${g} $s3,$stdframe($sp) # pointer to iv + la $s2,$tweak($sp) + lmg $s0,$s1,0($s3) + lghi $s3,16 + stmg $s0,$s1,0($s2) + la %r1,0($key2) # $key2 is not needed anymore + .long 0xb92e00aa # km $s2,$s2, generate the tweak + brc 1,.-4 # can this happen? + + l %r0,240($key1) + la %r1,0($key1) # $key1 is not needed anymore + bras $ra,_s390x_xts_km + jz .Lxts_enc_km_done + + aghi $inp,-16 # take one step back + la $i3,0($out,$inp) # put aside real $out +.Lxts_enc_km_steal: + llgc $i1,16($inp) + llgc $i2,0($out,$inp) + stc $i1,0($out,$inp) + stc $i2,16($out,$inp) + la $inp,1($inp) + brct $len,.Lxts_enc_km_steal + + la $s2,0($i3) + lghi $s3,16 + lrvgr $i1,$s0 # flip byte order + lrvgr $i2,$s1 + xg $i1,0($s2) + xg $i2,8($s2) + stg $i1,0($s2) + stg $i2,8($s2) + .long 0xb92e00aa # km $s2,$s2 + brc 1,.-4 # can this happen? + lrvgr $i1,$s0 # flip byte order + lrvgr $i2,$s1 + xg $i1,0($i3) + xg $i2,8($i3) + stg $i1,0($i3) + stg $i2,8($i3) + +.Lxts_enc_km_done: + stg $sp,$tweak+0($sp) # wipe tweak + stg $sp,$tweak+8($sp) + l${g} $ra,5*$SIZE_T($sp) + lm${g} %r6,$s3,6*$SIZE_T($sp) + br $ra +.align 16 +.Lxts_enc_software: +___ +$code.=<<___; + stm${g} %r6,$ra,6*$SIZE_T($sp) + + slgr $out,$inp + + l${g} $s3,$stdframe($sp) # ivp + llgf $s0,0($s3) # load iv + llgf $s1,4($s3) + llgf $s2,8($s3) + llgf $s3,12($s3) + stm${g} %r2,%r5,2*$SIZE_T($sp) + la $key,0($key2) + larl $tbl,AES_Te + bras $ra,_s390x_AES_encrypt # generate the tweak + lm${g} %r2,%r5,2*$SIZE_T($sp) + stm $s0,$s3,$tweak($sp) # save the tweak + j .Lxts_enc_enter + +.align 16 +.Lxts_enc_loop: + lrvg $s1,$tweak+0($sp) # load the tweak in little-endian + lrvg $s3,$tweak+8($sp) + lghi %r1,0x87 + srag %r0,$s3,63 # broadcast upper bit + ngr %r1,%r0 # rem + algr $s1,$s1 + alcgr $s3,$s3 + xgr $s1,%r1 + lrvgr $s1,$s1 # flip byte order + lrvgr $s3,$s3 + srlg $s0,$s1,32 # smash the tweak to 4x32-bits + stg $s1,$tweak+0($sp) # save the tweak + llgfr $s1,$s1 + srlg $s2,$s3,32 + stg $s3,$tweak+8($sp) + llgfr $s3,$s3 + la $inp,16($inp) # $inp+=16 +.Lxts_enc_enter: + x $s0,0($inp) # ^=*($inp) + x $s1,4($inp) + x $s2,8($inp) + x $s3,12($inp) + stm${g} %r2,%r3,2*$SIZE_T($sp) # only two registers are changing + la $key,0($key1) + bras $ra,_s390x_AES_encrypt + lm${g} %r2,%r5,2*$SIZE_T($sp) + x $s0,$tweak+0($sp) # ^=tweak + x $s1,$tweak+4($sp) + x $s2,$tweak+8($sp) + x $s3,$tweak+12($sp) + st $s0,0($out,$inp) + st $s1,4($out,$inp) + st $s2,8($out,$inp) + st $s3,12($out,$inp) + brct${g} $len,.Lxts_enc_loop + + llgc $len,`2*$SIZE_T-1`($sp) + nill $len,0x0f # $len%16 + jz .Lxts_enc_done + + la $i3,0($inp,$out) # put aside real $out +.Lxts_enc_steal: + llgc %r0,16($inp) + llgc %r1,0($out,$inp) + stc %r0,0($out,$inp) + stc %r1,16($out,$inp) + la $inp,1($inp) + brct $len,.Lxts_enc_steal + la $out,0($i3) # restore real $out + + # generate last tweak... + lrvg $s1,$tweak+0($sp) # load the tweak in little-endian + lrvg $s3,$tweak+8($sp) + lghi %r1,0x87 + srag %r0,$s3,63 # broadcast upper bit + ngr %r1,%r0 # rem + algr $s1,$s1 + alcgr $s3,$s3 + xgr $s1,%r1 + lrvgr $s1,$s1 # flip byte order + lrvgr $s3,$s3 + srlg $s0,$s1,32 # smash the tweak to 4x32-bits + stg $s1,$tweak+0($sp) # save the tweak + llgfr $s1,$s1 + srlg $s2,$s3,32 + stg $s3,$tweak+8($sp) + llgfr $s3,$s3 + + x $s0,0($out) # ^=*(inp)|stolen cipther-text + x $s1,4($out) + x $s2,8($out) + x $s3,12($out) + st${g} $out,4*$SIZE_T($sp) + la $key,0($key1) + bras $ra,_s390x_AES_encrypt + l${g} $out,4*$SIZE_T($sp) + x $s0,`$tweak+0`($sp) # ^=tweak + x $s1,`$tweak+4`($sp) + x $s2,`$tweak+8`($sp) + x $s3,`$tweak+12`($sp) + st $s0,0($out) + st $s1,4($out) + st $s2,8($out) + st $s3,12($out) + +.Lxts_enc_done: + stg $sp,$tweak+0($sp) # wipe tweak + stg $sp,$twesk+8($sp) + lm${g} %r6,$ra,6*$SIZE_T($sp) + br $ra +.size AES_xts_encrypt,.-AES_xts_encrypt +___ +# void AES_xts_decrypt(const char *inp,char *out,size_t len, +# const AES_KEY *key1, const AES_KEY *key2, +# const unsigned char iv[16]); +# +$code.=<<___; +.globl AES_xts_decrypt +.type AES_xts_decrypt,\@function +.align 16 +AES_xts_decrypt: + xgr %r3,%r4 # flip %r3 and %r4, $out and $len + xgr %r4,%r3 + xgr %r3,%r4 +___ +$code.=<<___ if ($SIZE_T==4); + llgfr $len,$len +___ +$code.=<<___; + st${g} $len,1*$SIZE_T($sp) # save copy of $len + aghi $len,-16 + bcr 4,$ra # abort if less than zero. formally + # wrong, because $len is unsigned, + # but who can afford asking to + # process more than 2^63-1 bytes? + tmll $len,0x0f + jnz .Lxts_dec_proceed + aghi $len,16 +.Lxts_dec_proceed: +___ +$code.=<<___ if (!$softonly); + llgf %r0,240($key2) + lhi %r1,16 + clr %r0,%r1 + jl .Lxts_dec_software + + st${g} $ra,5*$SIZE_T($sp) + stm${g} %r6,$s3,6*$SIZE_T($sp) + + nill $len,0xfff0 # $len&=~15 + slgr $out,$inp + + # generate the tweak value + l${g} $s3,$stdframe($sp) # pointer to iv + la $s2,$tweak($sp) + lmg $s0,$s1,0($s3) + lghi $s3,16 + stmg $s0,$s1,0($s2) + la %r1,0($key2) # $key2 is not needed past this point + .long 0xb92e00aa # km $s2,$s2, generate the tweak + brc 1,.-4 # can this happen? + + l %r0,240($key1) + la %r1,0($key1) # $key1 is not needed anymore + + ltgr $len,$len + jz .Lxts_dec_km_short + bras $ra,_s390x_xts_km + jz .Lxts_dec_km_done + + lrvgr $s2,$s0 # make copy in reverse byte order + lrvgr $s3,$s1 + j .Lxts_dec_km_2ndtweak + +.Lxts_dec_km_short: + llgc $len,`2*$SIZE_T-1`($sp) + nill $len,0x0f # $len%=16 + lrvg $s0,$tweak+0($sp) # load the tweak + lrvg $s1,$tweak+8($sp) + lrvgr $s2,$s0 # make copy in reverse byte order + lrvgr $s3,$s1 + +.Lxts_dec_km_2ndtweak: + lghi $i1,0x87 + srag $i2,$s1,63 # broadcast upper bit + ngr $i1,$i2 # rem + algr $s0,$s0 + alcgr $s1,$s1 + xgr $s0,$i1 + lrvgr $i1,$s0 # flip byte order + lrvgr $i2,$s1 + + xg $i1,0($inp) + xg $i2,8($inp) + stg $i1,0($out,$inp) + stg $i2,8($out,$inp) + la $i2,0($out,$inp) + lghi $i3,16 + .long 0xb92e0066 # km $i2,$i2 + brc 1,.-4 # can this happen? + lrvgr $i1,$s0 + lrvgr $i2,$s1 + xg $i1,0($out,$inp) + xg $i2,8($out,$inp) + stg $i1,0($out,$inp) + stg $i2,8($out,$inp) + + la $i3,0($out,$inp) # put aside real $out +.Lxts_dec_km_steal: + llgc $i1,16($inp) + llgc $i2,0($out,$inp) + stc $i1,0($out,$inp) + stc $i2,16($out,$inp) + la $inp,1($inp) + brct $len,.Lxts_dec_km_steal + + lgr $s0,$s2 + lgr $s1,$s3 + xg $s0,0($i3) + xg $s1,8($i3) + stg $s0,0($i3) + stg $s1,8($i3) + la $s0,0($i3) + lghi $s1,16 + .long 0xb92e0088 # km $s0,$s0 + brc 1,.-4 # can this happen? + xg $s2,0($i3) + xg $s3,8($i3) + stg $s2,0($i3) + stg $s3,8($i3) +.Lxts_dec_km_done: + stg $sp,$tweak+0($sp) # wipe tweak + stg $sp,$tweak+8($sp) + l${g} $ra,5*$SIZE_T($sp) + lm${g} %r6,$s3,6*$SIZE_T($sp) + br $ra +.align 16 +.Lxts_dec_software: +___ +$code.=<<___; + stm${g} %r6,$ra,6*$SIZE_T($sp) + + srlg $len,$len,4 + slgr $out,$inp + + l${g} $s3,$stdframe($sp) # ivp + llgf $s0,0($s3) # load iv + llgf $s1,4($s3) + llgf $s2,8($s3) + llgf $s3,12($s3) + stm${g} %r2,%r5,2*$SIZE_T($sp) + la $key,0($key2) + larl $tbl,AES_Te + bras $ra,_s390x_AES_encrypt # generate the tweak + lm${g} %r2,%r5,2*$SIZE_T($sp) + larl $tbl,AES_Td + lt${g}r $len,$len + stm $s0,$s3,$tweak($sp) # save the tweak + jz .Lxts_dec_short + j .Lxts_dec_enter + +.align 16 +.Lxts_dec_loop: + lrvg $s1,$tweak+0($sp) # load the tweak in little-endian + lrvg $s3,$tweak+8($sp) + lghi %r1,0x87 + srag %r0,$s3,63 # broadcast upper bit + ngr %r1,%r0 # rem + algr $s1,$s1 + alcgr $s3,$s3 + xgr $s1,%r1 + lrvgr $s1,$s1 # flip byte order + lrvgr $s3,$s3 + srlg $s0,$s1,32 # smash the tweak to 4x32-bits + stg $s1,$tweak+0($sp) # save the tweak + llgfr $s1,$s1 + srlg $s2,$s3,32 + stg $s3,$tweak+8($sp) + llgfr $s3,$s3 +.Lxts_dec_enter: + x $s0,0($inp) # tweak^=*(inp) + x $s1,4($inp) + x $s2,8($inp) + x $s3,12($inp) + stm${g} %r2,%r3,2*$SIZE_T($sp) # only two registers are changing + la $key,0($key1) + bras $ra,_s390x_AES_decrypt + lm${g} %r2,%r5,2*$SIZE_T($sp) + x $s0,$tweak+0($sp) # ^=tweak + x $s1,$tweak+4($sp) + x $s2,$tweak+8($sp) + x $s3,$tweak+12($sp) + st $s0,0($out,$inp) + st $s1,4($out,$inp) + st $s2,8($out,$inp) + st $s3,12($out,$inp) + la $inp,16($inp) + brct${g} $len,.Lxts_dec_loop + + llgc $len,`2*$SIZE_T-1`($sp) + nill $len,0x0f # $len%16 + jz .Lxts_dec_done + + # generate pair of tweaks... + lrvg $s1,$tweak+0($sp) # load the tweak in little-endian + lrvg $s3,$tweak+8($sp) + lghi %r1,0x87 + srag %r0,$s3,63 # broadcast upper bit + ngr %r1,%r0 # rem + algr $s1,$s1 + alcgr $s3,$s3 + xgr $s1,%r1 + lrvgr $i2,$s1 # flip byte order + lrvgr $i3,$s3 + stmg $i2,$i3,$tweak($sp) # save the 1st tweak + j .Lxts_dec_2ndtweak + +.align 16 +.Lxts_dec_short: + llgc $len,`2*$SIZE_T-1`($sp) + nill $len,0x0f # $len%16 + lrvg $s1,$tweak+0($sp) # load the tweak in little-endian + lrvg $s3,$tweak+8($sp) +.Lxts_dec_2ndtweak: + lghi %r1,0x87 + srag %r0,$s3,63 # broadcast upper bit + ngr %r1,%r0 # rem + algr $s1,$s1 + alcgr $s3,$s3 + xgr $s1,%r1 + lrvgr $s1,$s1 # flip byte order + lrvgr $s3,$s3 + srlg $s0,$s1,32 # smash the tweak to 4x32-bits + stg $s1,$tweak-16+0($sp) # save the 2nd tweak + llgfr $s1,$s1 + srlg $s2,$s3,32 + stg $s3,$tweak-16+8($sp) + llgfr $s3,$s3 + + x $s0,0($inp) # tweak_the_2nd^=*(inp) + x $s1,4($inp) + x $s2,8($inp) + x $s3,12($inp) + stm${g} %r2,%r3,2*$SIZE_T($sp) + la $key,0($key1) + bras $ra,_s390x_AES_decrypt + lm${g} %r2,%r5,2*$SIZE_T($sp) + x $s0,$tweak-16+0($sp) # ^=tweak_the_2nd + x $s1,$tweak-16+4($sp) + x $s2,$tweak-16+8($sp) + x $s3,$tweak-16+12($sp) + st $s0,0($out,$inp) + st $s1,4($out,$inp) + st $s2,8($out,$inp) + st $s3,12($out,$inp) + + la $i3,0($out,$inp) # put aside real $out +.Lxts_dec_steal: + llgc %r0,16($inp) + llgc %r1,0($out,$inp) + stc %r0,0($out,$inp) + stc %r1,16($out,$inp) + la $inp,1($inp) + brct $len,.Lxts_dec_steal + la $out,0($i3) # restore real $out + + lm $s0,$s3,$tweak($sp) # load the 1st tweak + x $s0,0($out) # tweak^=*(inp)|stolen cipher-text + x $s1,4($out) + x $s2,8($out) + x $s3,12($out) + st${g} $out,4*$SIZE_T($sp) + la $key,0($key1) + bras $ra,_s390x_AES_decrypt + l${g} $out,4*$SIZE_T($sp) + x $s0,$tweak+0($sp) # ^=tweak + x $s1,$tweak+4($sp) + x $s2,$tweak+8($sp) + x $s3,$tweak+12($sp) + st $s0,0($out) + st $s1,4($out) + st $s2,8($out) + st $s3,12($out) + stg $sp,$tweak-16+0($sp) # wipe 2nd tweak + stg $sp,$tweak-16+8($sp) +.Lxts_dec_done: + stg $sp,$tweak+0($sp) # wipe tweak + stg $sp,$twesk+8($sp) + lm${g} %r6,$ra,6*$SIZE_T($sp) + br $ra +.size AES_xts_decrypt,.-AES_xts_decrypt +___ +} +$code.=<<___; +.string "AES for s390x, CRYPTOGAMS by " +.comm OPENSSL_s390xcap_P,16,8 +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; # force flush diff --git a/libs/openssl/crypto/aes/asm/aes-sparcv9.pl b/libs/openssl/crypto/aes/asm/aes-sparcv9.pl new file mode 100755 index 00000000..403c4d12 --- /dev/null +++ b/libs/openssl/crypto/aes/asm/aes-sparcv9.pl @@ -0,0 +1,1182 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. Rights for redistribution and usage in source and binary +# forms are granted according to the OpenSSL license. +# ==================================================================== +# +# Version 1.1 +# +# The major reason for undertaken effort was to mitigate the hazard of +# cache-timing attack. This is [currently and initially!] addressed in +# two ways. 1. S-boxes are compressed from 5KB to 2KB+256B size each. +# 2. References to them are scheduled for L2 cache latency, meaning +# that the tables don't have to reside in L1 cache. Once again, this +# is an initial draft and one should expect more countermeasures to +# be implemented... +# +# Version 1.1 prefetches T[ed]4 in order to mitigate attack on last +# round. +# +# Even though performance was not the primary goal [on the contrary, +# extra shifts "induced" by compressed S-box and longer loop epilogue +# "induced" by scheduling for L2 have negative effect on performance], +# the code turned out to run in ~23 cycles per processed byte en-/ +# decrypted with 128-bit key. This is pretty good result for code +# with mentioned qualities and UltraSPARC core. Compared to Sun C +# generated code my encrypt procedure runs just few percents faster, +# while decrypt one - whole 50% faster [yes, Sun C failed to generate +# optimal decrypt procedure]. Compared to GNU C generated code both +# procedures are more than 60% faster:-) + +$bits=32; +for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); } +if ($bits==64) { $bias=2047; $frame=192; } +else { $bias=0; $frame=112; } +$locals=16; + +$acc0="%l0"; +$acc1="%o0"; +$acc2="%o1"; +$acc3="%o2"; + +$acc4="%l1"; +$acc5="%o3"; +$acc6="%o4"; +$acc7="%o5"; + +$acc8="%l2"; +$acc9="%o7"; +$acc10="%g1"; +$acc11="%g2"; + +$acc12="%l3"; +$acc13="%g3"; +$acc14="%g4"; +$acc15="%g5"; + +$t0="%l4"; +$t1="%l5"; +$t2="%l6"; +$t3="%l7"; + +$s0="%i0"; +$s1="%i1"; +$s2="%i2"; +$s3="%i3"; +$tbl="%i4"; +$key="%i5"; +$rounds="%i7"; # aliases with return address, which is off-loaded to stack + +sub _data_word() +{ my $i; + while(defined($i=shift)) { $code.=sprintf"\t.long\t0x%08x,0x%08x\n",$i,$i; } +} + +$code.=<<___ if ($bits==64); +.register %g2,#scratch +.register %g3,#scratch +___ +$code.=<<___; +.section ".text",#alloc,#execinstr + +.align 256 +AES_Te: +___ +&_data_word( + 0xc66363a5, 0xf87c7c84, 0xee777799, 0xf67b7b8d, + 0xfff2f20d, 0xd66b6bbd, 0xde6f6fb1, 0x91c5c554, + 0x60303050, 0x02010103, 0xce6767a9, 0x562b2b7d, + 0xe7fefe19, 0xb5d7d762, 0x4dababe6, 0xec76769a, + 0x8fcaca45, 0x1f82829d, 0x89c9c940, 0xfa7d7d87, + 0xeffafa15, 0xb25959eb, 0x8e4747c9, 0xfbf0f00b, + 0x41adadec, 0xb3d4d467, 0x5fa2a2fd, 0x45afafea, + 0x239c9cbf, 0x53a4a4f7, 0xe4727296, 0x9bc0c05b, + 0x75b7b7c2, 0xe1fdfd1c, 0x3d9393ae, 0x4c26266a, + 0x6c36365a, 0x7e3f3f41, 0xf5f7f702, 0x83cccc4f, + 0x6834345c, 0x51a5a5f4, 0xd1e5e534, 0xf9f1f108, + 0xe2717193, 0xabd8d873, 0x62313153, 0x2a15153f, + 0x0804040c, 0x95c7c752, 0x46232365, 0x9dc3c35e, + 0x30181828, 0x379696a1, 0x0a05050f, 0x2f9a9ab5, + 0x0e070709, 0x24121236, 0x1b80809b, 0xdfe2e23d, + 0xcdebeb26, 0x4e272769, 0x7fb2b2cd, 0xea75759f, + 0x1209091b, 0x1d83839e, 0x582c2c74, 0x341a1a2e, + 0x361b1b2d, 0xdc6e6eb2, 0xb45a5aee, 0x5ba0a0fb, + 0xa45252f6, 0x763b3b4d, 0xb7d6d661, 0x7db3b3ce, + 0x5229297b, 0xdde3e33e, 0x5e2f2f71, 0x13848497, + 0xa65353f5, 0xb9d1d168, 0x00000000, 0xc1eded2c, + 0x40202060, 0xe3fcfc1f, 0x79b1b1c8, 0xb65b5bed, + 0xd46a6abe, 0x8dcbcb46, 0x67bebed9, 0x7239394b, + 0x944a4ade, 0x984c4cd4, 0xb05858e8, 0x85cfcf4a, + 0xbbd0d06b, 0xc5efef2a, 0x4faaaae5, 0xedfbfb16, + 0x864343c5, 0x9a4d4dd7, 0x66333355, 0x11858594, + 0x8a4545cf, 0xe9f9f910, 0x04020206, 0xfe7f7f81, + 0xa05050f0, 0x783c3c44, 0x259f9fba, 0x4ba8a8e3, + 0xa25151f3, 0x5da3a3fe, 0x804040c0, 0x058f8f8a, + 0x3f9292ad, 0x219d9dbc, 0x70383848, 0xf1f5f504, + 0x63bcbcdf, 0x77b6b6c1, 0xafdada75, 0x42212163, + 0x20101030, 0xe5ffff1a, 0xfdf3f30e, 0xbfd2d26d, + 0x81cdcd4c, 0x180c0c14, 0x26131335, 0xc3ecec2f, + 0xbe5f5fe1, 0x359797a2, 0x884444cc, 0x2e171739, + 0x93c4c457, 0x55a7a7f2, 0xfc7e7e82, 0x7a3d3d47, + 0xc86464ac, 0xba5d5de7, 0x3219192b, 0xe6737395, + 0xc06060a0, 0x19818198, 0x9e4f4fd1, 0xa3dcdc7f, + 0x44222266, 0x542a2a7e, 0x3b9090ab, 0x0b888883, + 0x8c4646ca, 0xc7eeee29, 0x6bb8b8d3, 0x2814143c, + 0xa7dede79, 0xbc5e5ee2, 0x160b0b1d, 0xaddbdb76, + 0xdbe0e03b, 0x64323256, 0x743a3a4e, 0x140a0a1e, + 0x924949db, 0x0c06060a, 0x4824246c, 0xb85c5ce4, + 0x9fc2c25d, 0xbdd3d36e, 0x43acacef, 0xc46262a6, + 0x399191a8, 0x319595a4, 0xd3e4e437, 0xf279798b, + 0xd5e7e732, 0x8bc8c843, 0x6e373759, 0xda6d6db7, + 0x018d8d8c, 0xb1d5d564, 0x9c4e4ed2, 0x49a9a9e0, + 0xd86c6cb4, 0xac5656fa, 0xf3f4f407, 0xcfeaea25, + 0xca6565af, 0xf47a7a8e, 0x47aeaee9, 0x10080818, + 0x6fbabad5, 0xf0787888, 0x4a25256f, 0x5c2e2e72, + 0x381c1c24, 0x57a6a6f1, 0x73b4b4c7, 0x97c6c651, + 0xcbe8e823, 0xa1dddd7c, 0xe874749c, 0x3e1f1f21, + 0x964b4bdd, 0x61bdbddc, 0x0d8b8b86, 0x0f8a8a85, + 0xe0707090, 0x7c3e3e42, 0x71b5b5c4, 0xcc6666aa, + 0x904848d8, 0x06030305, 0xf7f6f601, 0x1c0e0e12, + 0xc26161a3, 0x6a35355f, 0xae5757f9, 0x69b9b9d0, + 0x17868691, 0x99c1c158, 0x3a1d1d27, 0x279e9eb9, + 0xd9e1e138, 0xebf8f813, 0x2b9898b3, 0x22111133, + 0xd26969bb, 0xa9d9d970, 0x078e8e89, 0x339494a7, + 0x2d9b9bb6, 0x3c1e1e22, 0x15878792, 0xc9e9e920, + 0x87cece49, 0xaa5555ff, 0x50282878, 0xa5dfdf7a, + 0x038c8c8f, 0x59a1a1f8, 0x09898980, 0x1a0d0d17, + 0x65bfbfda, 0xd7e6e631, 0x844242c6, 0xd06868b8, + 0x824141c3, 0x299999b0, 0x5a2d2d77, 0x1e0f0f11, + 0x7bb0b0cb, 0xa85454fc, 0x6dbbbbd6, 0x2c16163a); +$code.=<<___; + .byte 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5 + .byte 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76 + .byte 0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0 + .byte 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0 + .byte 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc + .byte 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15 + .byte 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a + .byte 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75 + .byte 0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0 + .byte 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84 + .byte 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b + .byte 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf + .byte 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85 + .byte 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8 + .byte 0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5 + .byte 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2 + .byte 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17 + .byte 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73 + .byte 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88 + .byte 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb + .byte 0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c + .byte 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79 + .byte 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9 + .byte 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08 + .byte 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6 + .byte 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a + .byte 0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e + .byte 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e + .byte 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94 + .byte 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf + .byte 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68 + .byte 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 +.type AES_Te,#object +.size AES_Te,(.-AES_Te) + +.align 64 +.skip 16 +_sparcv9_AES_encrypt: + save %sp,-$frame-$locals,%sp + stx %i7,[%sp+$bias+$frame+0] ! off-load return address + ld [$key+240],$rounds + ld [$key+0],$t0 + ld [$key+4],$t1 ! + ld [$key+8],$t2 + srl $rounds,1,$rounds + xor $t0,$s0,$s0 + ld [$key+12],$t3 + srl $s0,21,$acc0 + xor $t1,$s1,$s1 + ld [$key+16],$t0 + srl $s1,13,$acc1 ! + xor $t2,$s2,$s2 + ld [$key+20],$t1 + xor $t3,$s3,$s3 + ld [$key+24],$t2 + and $acc0,2040,$acc0 + ld [$key+28],$t3 + nop +.Lenc_loop: + srl $s2,5,$acc2 ! + and $acc1,2040,$acc1 + ldx [$tbl+$acc0],$acc0 + sll $s3,3,$acc3 + and $acc2,2040,$acc2 + ldx [$tbl+$acc1],$acc1 + srl $s1,21,$acc4 + and $acc3,2040,$acc3 + ldx [$tbl+$acc2],$acc2 ! + srl $s2,13,$acc5 + and $acc4,2040,$acc4 + ldx [$tbl+$acc3],$acc3 + srl $s3,5,$acc6 + and $acc5,2040,$acc5 + ldx [$tbl+$acc4],$acc4 + fmovs %f0,%f0 + sll $s0,3,$acc7 ! + and $acc6,2040,$acc6 + ldx [$tbl+$acc5],$acc5 + srl $s2,21,$acc8 + and $acc7,2040,$acc7 + ldx [$tbl+$acc6],$acc6 + srl $s3,13,$acc9 + and $acc8,2040,$acc8 + ldx [$tbl+$acc7],$acc7 ! + srl $s0,5,$acc10 + and $acc9,2040,$acc9 + ldx [$tbl+$acc8],$acc8 + sll $s1,3,$acc11 + and $acc10,2040,$acc10 + ldx [$tbl+$acc9],$acc9 + fmovs %f0,%f0 + srl $s3,21,$acc12 ! + and $acc11,2040,$acc11 + ldx [$tbl+$acc10],$acc10 + srl $s0,13,$acc13 + and $acc12,2040,$acc12 + ldx [$tbl+$acc11],$acc11 + srl $s1,5,$acc14 + and $acc13,2040,$acc13 + ldx [$tbl+$acc12],$acc12 ! + sll $s2,3,$acc15 + and $acc14,2040,$acc14 + ldx [$tbl+$acc13],$acc13 + and $acc15,2040,$acc15 + add $key,32,$key + ldx [$tbl+$acc14],$acc14 + fmovs %f0,%f0 + subcc $rounds,1,$rounds ! + ldx [$tbl+$acc15],$acc15 + bz,a,pn %icc,.Lenc_last + add $tbl,2048,$rounds + + srlx $acc1,8,$acc1 + xor $acc0,$t0,$t0 + ld [$key+0],$s0 + fmovs %f0,%f0 + srlx $acc2,16,$acc2 ! + xor $acc1,$t0,$t0 + ld [$key+4],$s1 + srlx $acc3,24,$acc3 + xor $acc2,$t0,$t0 + ld [$key+8],$s2 + srlx $acc5,8,$acc5 + xor $acc3,$t0,$t0 + ld [$key+12],$s3 ! + srlx $acc6,16,$acc6 + xor $acc4,$t1,$t1 + fmovs %f0,%f0 + srlx $acc7,24,$acc7 + xor $acc5,$t1,$t1 + srlx $acc9,8,$acc9 + xor $acc6,$t1,$t1 + srlx $acc10,16,$acc10 ! + xor $acc7,$t1,$t1 + srlx $acc11,24,$acc11 + xor $acc8,$t2,$t2 + srlx $acc13,8,$acc13 + xor $acc9,$t2,$t2 + srlx $acc14,16,$acc14 + xor $acc10,$t2,$t2 + srlx $acc15,24,$acc15 ! + xor $acc11,$t2,$t2 + xor $acc12,$acc14,$acc14 + xor $acc13,$t3,$t3 + srl $t0,21,$acc0 + xor $acc14,$t3,$t3 + srl $t1,13,$acc1 + xor $acc15,$t3,$t3 + + and $acc0,2040,$acc0 ! + srl $t2,5,$acc2 + and $acc1,2040,$acc1 + ldx [$tbl+$acc0],$acc0 + sll $t3,3,$acc3 + and $acc2,2040,$acc2 + ldx [$tbl+$acc1],$acc1 + fmovs %f0,%f0 + srl $t1,21,$acc4 ! + and $acc3,2040,$acc3 + ldx [$tbl+$acc2],$acc2 + srl $t2,13,$acc5 + and $acc4,2040,$acc4 + ldx [$tbl+$acc3],$acc3 + srl $t3,5,$acc6 + and $acc5,2040,$acc5 + ldx [$tbl+$acc4],$acc4 ! + sll $t0,3,$acc7 + and $acc6,2040,$acc6 + ldx [$tbl+$acc5],$acc5 + srl $t2,21,$acc8 + and $acc7,2040,$acc7 + ldx [$tbl+$acc6],$acc6 + fmovs %f0,%f0 + srl $t3,13,$acc9 ! + and $acc8,2040,$acc8 + ldx [$tbl+$acc7],$acc7 + srl $t0,5,$acc10 + and $acc9,2040,$acc9 + ldx [$tbl+$acc8],$acc8 + sll $t1,3,$acc11 + and $acc10,2040,$acc10 + ldx [$tbl+$acc9],$acc9 ! + srl $t3,21,$acc12 + and $acc11,2040,$acc11 + ldx [$tbl+$acc10],$acc10 + srl $t0,13,$acc13 + and $acc12,2040,$acc12 + ldx [$tbl+$acc11],$acc11 + fmovs %f0,%f0 + srl $t1,5,$acc14 ! + and $acc13,2040,$acc13 + ldx [$tbl+$acc12],$acc12 + sll $t2,3,$acc15 + and $acc14,2040,$acc14 + ldx [$tbl+$acc13],$acc13 + srlx $acc1,8,$acc1 + and $acc15,2040,$acc15 + ldx [$tbl+$acc14],$acc14 ! + + srlx $acc2,16,$acc2 + xor $acc0,$s0,$s0 + ldx [$tbl+$acc15],$acc15 + srlx $acc3,24,$acc3 + xor $acc1,$s0,$s0 + ld [$key+16],$t0 + fmovs %f0,%f0 + srlx $acc5,8,$acc5 ! + xor $acc2,$s0,$s0 + ld [$key+20],$t1 + srlx $acc6,16,$acc6 + xor $acc3,$s0,$s0 + ld [$key+24],$t2 + srlx $acc7,24,$acc7 + xor $acc4,$s1,$s1 + ld [$key+28],$t3 ! + srlx $acc9,8,$acc9 + xor $acc5,$s1,$s1 + ldx [$tbl+2048+0],%g0 ! prefetch te4 + srlx $acc10,16,$acc10 + xor $acc6,$s1,$s1 + ldx [$tbl+2048+32],%g0 ! prefetch te4 + srlx $acc11,24,$acc11 + xor $acc7,$s1,$s1 + ldx [$tbl+2048+64],%g0 ! prefetch te4 + srlx $acc13,8,$acc13 + xor $acc8,$s2,$s2 + ldx [$tbl+2048+96],%g0 ! prefetch te4 + srlx $acc14,16,$acc14 ! + xor $acc9,$s2,$s2 + ldx [$tbl+2048+128],%g0 ! prefetch te4 + srlx $acc15,24,$acc15 + xor $acc10,$s2,$s2 + ldx [$tbl+2048+160],%g0 ! prefetch te4 + srl $s0,21,$acc0 + xor $acc11,$s2,$s2 + ldx [$tbl+2048+192],%g0 ! prefetch te4 + xor $acc12,$acc14,$acc14 + xor $acc13,$s3,$s3 + ldx [$tbl+2048+224],%g0 ! prefetch te4 + srl $s1,13,$acc1 ! + xor $acc14,$s3,$s3 + xor $acc15,$s3,$s3 + ba .Lenc_loop + and $acc0,2040,$acc0 + +.align 32 +.Lenc_last: + srlx $acc1,8,$acc1 ! + xor $acc0,$t0,$t0 + ld [$key+0],$s0 + srlx $acc2,16,$acc2 + xor $acc1,$t0,$t0 + ld [$key+4],$s1 + srlx $acc3,24,$acc3 + xor $acc2,$t0,$t0 + ld [$key+8],$s2 ! + srlx $acc5,8,$acc5 + xor $acc3,$t0,$t0 + ld [$key+12],$s3 + srlx $acc6,16,$acc6 + xor $acc4,$t1,$t1 + srlx $acc7,24,$acc7 + xor $acc5,$t1,$t1 + srlx $acc9,8,$acc9 ! + xor $acc6,$t1,$t1 + srlx $acc10,16,$acc10 + xor $acc7,$t1,$t1 + srlx $acc11,24,$acc11 + xor $acc8,$t2,$t2 + srlx $acc13,8,$acc13 + xor $acc9,$t2,$t2 + srlx $acc14,16,$acc14 ! + xor $acc10,$t2,$t2 + srlx $acc15,24,$acc15 + xor $acc11,$t2,$t2 + xor $acc12,$acc14,$acc14 + xor $acc13,$t3,$t3 + srl $t0,24,$acc0 + xor $acc14,$t3,$t3 + srl $t1,16,$acc1 ! + xor $acc15,$t3,$t3 + + srl $t2,8,$acc2 + and $acc1,255,$acc1 + ldub [$rounds+$acc0],$acc0 + srl $t1,24,$acc4 + and $acc2,255,$acc2 + ldub [$rounds+$acc1],$acc1 + srl $t2,16,$acc5 ! + and $t3,255,$acc3 + ldub [$rounds+$acc2],$acc2 + ldub [$rounds+$acc3],$acc3 + srl $t3,8,$acc6 + and $acc5,255,$acc5 + ldub [$rounds+$acc4],$acc4 + fmovs %f0,%f0 + srl $t2,24,$acc8 ! + and $acc6,255,$acc6 + ldub [$rounds+$acc5],$acc5 + srl $t3,16,$acc9 + and $t0,255,$acc7 + ldub [$rounds+$acc6],$acc6 + ldub [$rounds+$acc7],$acc7 + fmovs %f0,%f0 + srl $t0,8,$acc10 ! + and $acc9,255,$acc9 + ldub [$rounds+$acc8],$acc8 + srl $t3,24,$acc12 + and $acc10,255,$acc10 + ldub [$rounds+$acc9],$acc9 + srl $t0,16,$acc13 + and $t1,255,$acc11 + ldub [$rounds+$acc10],$acc10 ! + srl $t1,8,$acc14 + and $acc13,255,$acc13 + ldub [$rounds+$acc11],$acc11 + ldub [$rounds+$acc12],$acc12 + and $acc14,255,$acc14 + ldub [$rounds+$acc13],$acc13 + and $t2,255,$acc15 + ldub [$rounds+$acc14],$acc14 ! + + sll $acc0,24,$acc0 + xor $acc3,$s0,$s0 + ldub [$rounds+$acc15],$acc15 + sll $acc1,16,$acc1 + xor $acc0,$s0,$s0 + ldx [%sp+$bias+$frame+0],%i7 ! restore return address + fmovs %f0,%f0 + sll $acc2,8,$acc2 ! + xor $acc1,$s0,$s0 + sll $acc4,24,$acc4 + xor $acc2,$s0,$s0 + sll $acc5,16,$acc5 + xor $acc7,$s1,$s1 + sll $acc6,8,$acc6 + xor $acc4,$s1,$s1 + sll $acc8,24,$acc8 ! + xor $acc5,$s1,$s1 + sll $acc9,16,$acc9 + xor $acc11,$s2,$s2 + sll $acc10,8,$acc10 + xor $acc6,$s1,$s1 + sll $acc12,24,$acc12 + xor $acc8,$s2,$s2 + sll $acc13,16,$acc13 ! + xor $acc9,$s2,$s2 + sll $acc14,8,$acc14 + xor $acc10,$s2,$s2 + xor $acc12,$acc14,$acc14 + xor $acc13,$s3,$s3 + xor $acc14,$s3,$s3 + xor $acc15,$s3,$s3 + + ret + restore +.type _sparcv9_AES_encrypt,#function +.size _sparcv9_AES_encrypt,(.-_sparcv9_AES_encrypt) + +.align 32 +.globl AES_encrypt +AES_encrypt: + or %o0,%o1,%g1 + andcc %g1,3,%g0 + bnz,pn %xcc,.Lunaligned_enc + save %sp,-$frame,%sp + + ld [%i0+0],%o0 + ld [%i0+4],%o1 + ld [%i0+8],%o2 + ld [%i0+12],%o3 + +1: call .+8 + add %o7,AES_Te-1b,%o4 + call _sparcv9_AES_encrypt + mov %i2,%o5 + + st %o0,[%i1+0] + st %o1,[%i1+4] + st %o2,[%i1+8] + st %o3,[%i1+12] + + ret + restore + +.align 32 +.Lunaligned_enc: + ldub [%i0+0],%l0 + ldub [%i0+1],%l1 + ldub [%i0+2],%l2 + + sll %l0,24,%l0 + ldub [%i0+3],%l3 + sll %l1,16,%l1 + ldub [%i0+4],%l4 + sll %l2,8,%l2 + or %l1,%l0,%l0 + ldub [%i0+5],%l5 + sll %l4,24,%l4 + or %l3,%l2,%l2 + ldub [%i0+6],%l6 + sll %l5,16,%l5 + or %l0,%l2,%o0 + ldub [%i0+7],%l7 + + sll %l6,8,%l6 + or %l5,%l4,%l4 + ldub [%i0+8],%l0 + or %l7,%l6,%l6 + ldub [%i0+9],%l1 + or %l4,%l6,%o1 + ldub [%i0+10],%l2 + + sll %l0,24,%l0 + ldub [%i0+11],%l3 + sll %l1,16,%l1 + ldub [%i0+12],%l4 + sll %l2,8,%l2 + or %l1,%l0,%l0 + ldub [%i0+13],%l5 + sll %l4,24,%l4 + or %l3,%l2,%l2 + ldub [%i0+14],%l6 + sll %l5,16,%l5 + or %l0,%l2,%o2 + ldub [%i0+15],%l7 + + sll %l6,8,%l6 + or %l5,%l4,%l4 + or %l7,%l6,%l6 + or %l4,%l6,%o3 + +1: call .+8 + add %o7,AES_Te-1b,%o4 + call _sparcv9_AES_encrypt + mov %i2,%o5 + + srl %o0,24,%l0 + srl %o0,16,%l1 + stb %l0,[%i1+0] + srl %o0,8,%l2 + stb %l1,[%i1+1] + stb %l2,[%i1+2] + srl %o1,24,%l4 + stb %o0,[%i1+3] + + srl %o1,16,%l5 + stb %l4,[%i1+4] + srl %o1,8,%l6 + stb %l5,[%i1+5] + stb %l6,[%i1+6] + srl %o2,24,%l0 + stb %o1,[%i1+7] + + srl %o2,16,%l1 + stb %l0,[%i1+8] + srl %o2,8,%l2 + stb %l1,[%i1+9] + stb %l2,[%i1+10] + srl %o3,24,%l4 + stb %o2,[%i1+11] + + srl %o3,16,%l5 + stb %l4,[%i1+12] + srl %o3,8,%l6 + stb %l5,[%i1+13] + stb %l6,[%i1+14] + stb %o3,[%i1+15] + + ret + restore +.type AES_encrypt,#function +.size AES_encrypt,(.-AES_encrypt) + +___ + +$code.=<<___; +.align 256 +AES_Td: +___ +&_data_word( + 0x51f4a750, 0x7e416553, 0x1a17a4c3, 0x3a275e96, + 0x3bab6bcb, 0x1f9d45f1, 0xacfa58ab, 0x4be30393, + 0x2030fa55, 0xad766df6, 0x88cc7691, 0xf5024c25, + 0x4fe5d7fc, 0xc52acbd7, 0x26354480, 0xb562a38f, + 0xdeb15a49, 0x25ba1b67, 0x45ea0e98, 0x5dfec0e1, + 0xc32f7502, 0x814cf012, 0x8d4697a3, 0x6bd3f9c6, + 0x038f5fe7, 0x15929c95, 0xbf6d7aeb, 0x955259da, + 0xd4be832d, 0x587421d3, 0x49e06929, 0x8ec9c844, + 0x75c2896a, 0xf48e7978, 0x99583e6b, 0x27b971dd, + 0xbee14fb6, 0xf088ad17, 0xc920ac66, 0x7dce3ab4, + 0x63df4a18, 0xe51a3182, 0x97513360, 0x62537f45, + 0xb16477e0, 0xbb6bae84, 0xfe81a01c, 0xf9082b94, + 0x70486858, 0x8f45fd19, 0x94de6c87, 0x527bf8b7, + 0xab73d323, 0x724b02e2, 0xe31f8f57, 0x6655ab2a, + 0xb2eb2807, 0x2fb5c203, 0x86c57b9a, 0xd33708a5, + 0x302887f2, 0x23bfa5b2, 0x02036aba, 0xed16825c, + 0x8acf1c2b, 0xa779b492, 0xf307f2f0, 0x4e69e2a1, + 0x65daf4cd, 0x0605bed5, 0xd134621f, 0xc4a6fe8a, + 0x342e539d, 0xa2f355a0, 0x058ae132, 0xa4f6eb75, + 0x0b83ec39, 0x4060efaa, 0x5e719f06, 0xbd6e1051, + 0x3e218af9, 0x96dd063d, 0xdd3e05ae, 0x4de6bd46, + 0x91548db5, 0x71c45d05, 0x0406d46f, 0x605015ff, + 0x1998fb24, 0xd6bde997, 0x894043cc, 0x67d99e77, + 0xb0e842bd, 0x07898b88, 0xe7195b38, 0x79c8eedb, + 0xa17c0a47, 0x7c420fe9, 0xf8841ec9, 0x00000000, + 0x09808683, 0x322bed48, 0x1e1170ac, 0x6c5a724e, + 0xfd0efffb, 0x0f853856, 0x3daed51e, 0x362d3927, + 0x0a0fd964, 0x685ca621, 0x9b5b54d1, 0x24362e3a, + 0x0c0a67b1, 0x9357e70f, 0xb4ee96d2, 0x1b9b919e, + 0x80c0c54f, 0x61dc20a2, 0x5a774b69, 0x1c121a16, + 0xe293ba0a, 0xc0a02ae5, 0x3c22e043, 0x121b171d, + 0x0e090d0b, 0xf28bc7ad, 0x2db6a8b9, 0x141ea9c8, + 0x57f11985, 0xaf75074c, 0xee99ddbb, 0xa37f60fd, + 0xf701269f, 0x5c72f5bc, 0x44663bc5, 0x5bfb7e34, + 0x8b432976, 0xcb23c6dc, 0xb6edfc68, 0xb8e4f163, + 0xd731dcca, 0x42638510, 0x13972240, 0x84c61120, + 0x854a247d, 0xd2bb3df8, 0xaef93211, 0xc729a16d, + 0x1d9e2f4b, 0xdcb230f3, 0x0d8652ec, 0x77c1e3d0, + 0x2bb3166c, 0xa970b999, 0x119448fa, 0x47e96422, + 0xa8fc8cc4, 0xa0f03f1a, 0x567d2cd8, 0x223390ef, + 0x87494ec7, 0xd938d1c1, 0x8ccaa2fe, 0x98d40b36, + 0xa6f581cf, 0xa57ade28, 0xdab78e26, 0x3fadbfa4, + 0x2c3a9de4, 0x5078920d, 0x6a5fcc9b, 0x547e4662, + 0xf68d13c2, 0x90d8b8e8, 0x2e39f75e, 0x82c3aff5, + 0x9f5d80be, 0x69d0937c, 0x6fd52da9, 0xcf2512b3, + 0xc8ac993b, 0x10187da7, 0xe89c636e, 0xdb3bbb7b, + 0xcd267809, 0x6e5918f4, 0xec9ab701, 0x834f9aa8, + 0xe6956e65, 0xaaffe67e, 0x21bccf08, 0xef15e8e6, + 0xbae79bd9, 0x4a6f36ce, 0xea9f09d4, 0x29b07cd6, + 0x31a4b2af, 0x2a3f2331, 0xc6a59430, 0x35a266c0, + 0x744ebc37, 0xfc82caa6, 0xe090d0b0, 0x33a7d815, + 0xf104984a, 0x41ecdaf7, 0x7fcd500e, 0x1791f62f, + 0x764dd68d, 0x43efb04d, 0xccaa4d54, 0xe49604df, + 0x9ed1b5e3, 0x4c6a881b, 0xc12c1fb8, 0x4665517f, + 0x9d5eea04, 0x018c355d, 0xfa877473, 0xfb0b412e, + 0xb3671d5a, 0x92dbd252, 0xe9105633, 0x6dd64713, + 0x9ad7618c, 0x37a10c7a, 0x59f8148e, 0xeb133c89, + 0xcea927ee, 0xb761c935, 0xe11ce5ed, 0x7a47b13c, + 0x9cd2df59, 0x55f2733f, 0x1814ce79, 0x73c737bf, + 0x53f7cdea, 0x5ffdaa5b, 0xdf3d6f14, 0x7844db86, + 0xcaaff381, 0xb968c43e, 0x3824342c, 0xc2a3405f, + 0x161dc372, 0xbce2250c, 0x283c498b, 0xff0d9541, + 0x39a80171, 0x080cb3de, 0xd8b4e49c, 0x6456c190, + 0x7bcb8461, 0xd532b670, 0x486c5c74, 0xd0b85742); +$code.=<<___; + .byte 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38 + .byte 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb + .byte 0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87 + .byte 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb + .byte 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d + .byte 0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e + .byte 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2 + .byte 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25 + .byte 0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16 + .byte 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92 + .byte 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda + .byte 0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84 + .byte 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a + .byte 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06 + .byte 0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02 + .byte 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b + .byte 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea + .byte 0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73 + .byte 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85 + .byte 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e + .byte 0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89 + .byte 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b + .byte 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20 + .byte 0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4 + .byte 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31 + .byte 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f + .byte 0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d + .byte 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef + .byte 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0 + .byte 0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61 + .byte 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26 + .byte 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d +.type AES_Td,#object +.size AES_Td,(.-AES_Td) + +.align 64 +.skip 16 +_sparcv9_AES_decrypt: + save %sp,-$frame-$locals,%sp + stx %i7,[%sp+$bias+$frame+0] ! off-load return address + ld [$key+240],$rounds + ld [$key+0],$t0 + ld [$key+4],$t1 ! + ld [$key+8],$t2 + ld [$key+12],$t3 + srl $rounds,1,$rounds + xor $t0,$s0,$s0 + ld [$key+16],$t0 + xor $t1,$s1,$s1 + ld [$key+20],$t1 + srl $s0,21,$acc0 ! + xor $t2,$s2,$s2 + ld [$key+24],$t2 + xor $t3,$s3,$s3 + and $acc0,2040,$acc0 + ld [$key+28],$t3 + srl $s3,13,$acc1 + nop +.Ldec_loop: + srl $s2,5,$acc2 ! + and $acc1,2040,$acc1 + ldx [$tbl+$acc0],$acc0 + sll $s1,3,$acc3 + and $acc2,2040,$acc2 + ldx [$tbl+$acc1],$acc1 + srl $s1,21,$acc4 + and $acc3,2040,$acc3 + ldx [$tbl+$acc2],$acc2 ! + srl $s0,13,$acc5 + and $acc4,2040,$acc4 + ldx [$tbl+$acc3],$acc3 + srl $s3,5,$acc6 + and $acc5,2040,$acc5 + ldx [$tbl+$acc4],$acc4 + fmovs %f0,%f0 + sll $s2,3,$acc7 ! + and $acc6,2040,$acc6 + ldx [$tbl+$acc5],$acc5 + srl $s2,21,$acc8 + and $acc7,2040,$acc7 + ldx [$tbl+$acc6],$acc6 + srl $s1,13,$acc9 + and $acc8,2040,$acc8 + ldx [$tbl+$acc7],$acc7 ! + srl $s0,5,$acc10 + and $acc9,2040,$acc9 + ldx [$tbl+$acc8],$acc8 + sll $s3,3,$acc11 + and $acc10,2040,$acc10 + ldx [$tbl+$acc9],$acc9 + fmovs %f0,%f0 + srl $s3,21,$acc12 ! + and $acc11,2040,$acc11 + ldx [$tbl+$acc10],$acc10 + srl $s2,13,$acc13 + and $acc12,2040,$acc12 + ldx [$tbl+$acc11],$acc11 + srl $s1,5,$acc14 + and $acc13,2040,$acc13 + ldx [$tbl+$acc12],$acc12 ! + sll $s0,3,$acc15 + and $acc14,2040,$acc14 + ldx [$tbl+$acc13],$acc13 + and $acc15,2040,$acc15 + add $key,32,$key + ldx [$tbl+$acc14],$acc14 + fmovs %f0,%f0 + subcc $rounds,1,$rounds ! + ldx [$tbl+$acc15],$acc15 + bz,a,pn %icc,.Ldec_last + add $tbl,2048,$rounds + + srlx $acc1,8,$acc1 + xor $acc0,$t0,$t0 + ld [$key+0],$s0 + fmovs %f0,%f0 + srlx $acc2,16,$acc2 ! + xor $acc1,$t0,$t0 + ld [$key+4],$s1 + srlx $acc3,24,$acc3 + xor $acc2,$t0,$t0 + ld [$key+8],$s2 + srlx $acc5,8,$acc5 + xor $acc3,$t0,$t0 + ld [$key+12],$s3 ! + srlx $acc6,16,$acc6 + xor $acc4,$t1,$t1 + fmovs %f0,%f0 + srlx $acc7,24,$acc7 + xor $acc5,$t1,$t1 + srlx $acc9,8,$acc9 + xor $acc6,$t1,$t1 + srlx $acc10,16,$acc10 ! + xor $acc7,$t1,$t1 + srlx $acc11,24,$acc11 + xor $acc8,$t2,$t2 + srlx $acc13,8,$acc13 + xor $acc9,$t2,$t2 + srlx $acc14,16,$acc14 + xor $acc10,$t2,$t2 + srlx $acc15,24,$acc15 ! + xor $acc11,$t2,$t2 + xor $acc12,$acc14,$acc14 + xor $acc13,$t3,$t3 + srl $t0,21,$acc0 + xor $acc14,$t3,$t3 + xor $acc15,$t3,$t3 + srl $t3,13,$acc1 + + and $acc0,2040,$acc0 ! + srl $t2,5,$acc2 + and $acc1,2040,$acc1 + ldx [$tbl+$acc0],$acc0 + sll $t1,3,$acc3 + and $acc2,2040,$acc2 + ldx [$tbl+$acc1],$acc1 + fmovs %f0,%f0 + srl $t1,21,$acc4 ! + and $acc3,2040,$acc3 + ldx [$tbl+$acc2],$acc2 + srl $t0,13,$acc5 + and $acc4,2040,$acc4 + ldx [$tbl+$acc3],$acc3 + srl $t3,5,$acc6 + and $acc5,2040,$acc5 + ldx [$tbl+$acc4],$acc4 ! + sll $t2,3,$acc7 + and $acc6,2040,$acc6 + ldx [$tbl+$acc5],$acc5 + srl $t2,21,$acc8 + and $acc7,2040,$acc7 + ldx [$tbl+$acc6],$acc6 + fmovs %f0,%f0 + srl $t1,13,$acc9 ! + and $acc8,2040,$acc8 + ldx [$tbl+$acc7],$acc7 + srl $t0,5,$acc10 + and $acc9,2040,$acc9 + ldx [$tbl+$acc8],$acc8 + sll $t3,3,$acc11 + and $acc10,2040,$acc10 + ldx [$tbl+$acc9],$acc9 ! + srl $t3,21,$acc12 + and $acc11,2040,$acc11 + ldx [$tbl+$acc10],$acc10 + srl $t2,13,$acc13 + and $acc12,2040,$acc12 + ldx [$tbl+$acc11],$acc11 + fmovs %f0,%f0 + srl $t1,5,$acc14 ! + and $acc13,2040,$acc13 + ldx [$tbl+$acc12],$acc12 + sll $t0,3,$acc15 + and $acc14,2040,$acc14 + ldx [$tbl+$acc13],$acc13 + srlx $acc1,8,$acc1 + and $acc15,2040,$acc15 + ldx [$tbl+$acc14],$acc14 ! + + srlx $acc2,16,$acc2 + xor $acc0,$s0,$s0 + ldx [$tbl+$acc15],$acc15 + srlx $acc3,24,$acc3 + xor $acc1,$s0,$s0 + ld [$key+16],$t0 + fmovs %f0,%f0 + srlx $acc5,8,$acc5 ! + xor $acc2,$s0,$s0 + ld [$key+20],$t1 + srlx $acc6,16,$acc6 + xor $acc3,$s0,$s0 + ld [$key+24],$t2 + srlx $acc7,24,$acc7 + xor $acc4,$s1,$s1 + ld [$key+28],$t3 ! + srlx $acc9,8,$acc9 + xor $acc5,$s1,$s1 + ldx [$tbl+2048+0],%g0 ! prefetch td4 + srlx $acc10,16,$acc10 + xor $acc6,$s1,$s1 + ldx [$tbl+2048+32],%g0 ! prefetch td4 + srlx $acc11,24,$acc11 + xor $acc7,$s1,$s1 + ldx [$tbl+2048+64],%g0 ! prefetch td4 + srlx $acc13,8,$acc13 + xor $acc8,$s2,$s2 + ldx [$tbl+2048+96],%g0 ! prefetch td4 + srlx $acc14,16,$acc14 ! + xor $acc9,$s2,$s2 + ldx [$tbl+2048+128],%g0 ! prefetch td4 + srlx $acc15,24,$acc15 + xor $acc10,$s2,$s2 + ldx [$tbl+2048+160],%g0 ! prefetch td4 + srl $s0,21,$acc0 + xor $acc11,$s2,$s2 + ldx [$tbl+2048+192],%g0 ! prefetch td4 + xor $acc12,$acc14,$acc14 + xor $acc13,$s3,$s3 + ldx [$tbl+2048+224],%g0 ! prefetch td4 + and $acc0,2040,$acc0 ! + xor $acc14,$s3,$s3 + xor $acc15,$s3,$s3 + ba .Ldec_loop + srl $s3,13,$acc1 + +.align 32 +.Ldec_last: + srlx $acc1,8,$acc1 ! + xor $acc0,$t0,$t0 + ld [$key+0],$s0 + srlx $acc2,16,$acc2 + xor $acc1,$t0,$t0 + ld [$key+4],$s1 + srlx $acc3,24,$acc3 + xor $acc2,$t0,$t0 + ld [$key+8],$s2 ! + srlx $acc5,8,$acc5 + xor $acc3,$t0,$t0 + ld [$key+12],$s3 + srlx $acc6,16,$acc6 + xor $acc4,$t1,$t1 + srlx $acc7,24,$acc7 + xor $acc5,$t1,$t1 + srlx $acc9,8,$acc9 ! + xor $acc6,$t1,$t1 + srlx $acc10,16,$acc10 + xor $acc7,$t1,$t1 + srlx $acc11,24,$acc11 + xor $acc8,$t2,$t2 + srlx $acc13,8,$acc13 + xor $acc9,$t2,$t2 + srlx $acc14,16,$acc14 ! + xor $acc10,$t2,$t2 + srlx $acc15,24,$acc15 + xor $acc11,$t2,$t2 + xor $acc12,$acc14,$acc14 + xor $acc13,$t3,$t3 + srl $t0,24,$acc0 + xor $acc14,$t3,$t3 + xor $acc15,$t3,$t3 ! + srl $t3,16,$acc1 + + srl $t2,8,$acc2 + and $acc1,255,$acc1 + ldub [$rounds+$acc0],$acc0 + srl $t1,24,$acc4 + and $acc2,255,$acc2 + ldub [$rounds+$acc1],$acc1 + srl $t0,16,$acc5 ! + and $t1,255,$acc3 + ldub [$rounds+$acc2],$acc2 + ldub [$rounds+$acc3],$acc3 + srl $t3,8,$acc6 + and $acc5,255,$acc5 + ldub [$rounds+$acc4],$acc4 + fmovs %f0,%f0 + srl $t2,24,$acc8 ! + and $acc6,255,$acc6 + ldub [$rounds+$acc5],$acc5 + srl $t1,16,$acc9 + and $t2,255,$acc7 + ldub [$rounds+$acc6],$acc6 + ldub [$rounds+$acc7],$acc7 + fmovs %f0,%f0 + srl $t0,8,$acc10 ! + and $acc9,255,$acc9 + ldub [$rounds+$acc8],$acc8 + srl $t3,24,$acc12 + and $acc10,255,$acc10 + ldub [$rounds+$acc9],$acc9 + srl $t2,16,$acc13 + and $t3,255,$acc11 + ldub [$rounds+$acc10],$acc10 ! + srl $t1,8,$acc14 + and $acc13,255,$acc13 + ldub [$rounds+$acc11],$acc11 + ldub [$rounds+$acc12],$acc12 + and $acc14,255,$acc14 + ldub [$rounds+$acc13],$acc13 + and $t0,255,$acc15 + ldub [$rounds+$acc14],$acc14 ! + + sll $acc0,24,$acc0 + xor $acc3,$s0,$s0 + ldub [$rounds+$acc15],$acc15 + sll $acc1,16,$acc1 + xor $acc0,$s0,$s0 + ldx [%sp+$bias+$frame+0],%i7 ! restore return address + fmovs %f0,%f0 + sll $acc2,8,$acc2 ! + xor $acc1,$s0,$s0 + sll $acc4,24,$acc4 + xor $acc2,$s0,$s0 + sll $acc5,16,$acc5 + xor $acc7,$s1,$s1 + sll $acc6,8,$acc6 + xor $acc4,$s1,$s1 + sll $acc8,24,$acc8 ! + xor $acc5,$s1,$s1 + sll $acc9,16,$acc9 + xor $acc11,$s2,$s2 + sll $acc10,8,$acc10 + xor $acc6,$s1,$s1 + sll $acc12,24,$acc12 + xor $acc8,$s2,$s2 + sll $acc13,16,$acc13 ! + xor $acc9,$s2,$s2 + sll $acc14,8,$acc14 + xor $acc10,$s2,$s2 + xor $acc12,$acc14,$acc14 + xor $acc13,$s3,$s3 + xor $acc14,$s3,$s3 + xor $acc15,$s3,$s3 + + ret + restore +.type _sparcv9_AES_decrypt,#function +.size _sparcv9_AES_decrypt,(.-_sparcv9_AES_decrypt) + +.align 32 +.globl AES_decrypt +AES_decrypt: + or %o0,%o1,%g1 + andcc %g1,3,%g0 + bnz,pn %xcc,.Lunaligned_dec + save %sp,-$frame,%sp + + ld [%i0+0],%o0 + ld [%i0+4],%o1 + ld [%i0+8],%o2 + ld [%i0+12],%o3 + +1: call .+8 + add %o7,AES_Td-1b,%o4 + call _sparcv9_AES_decrypt + mov %i2,%o5 + + st %o0,[%i1+0] + st %o1,[%i1+4] + st %o2,[%i1+8] + st %o3,[%i1+12] + + ret + restore + +.align 32 +.Lunaligned_dec: + ldub [%i0+0],%l0 + ldub [%i0+1],%l1 + ldub [%i0+2],%l2 + + sll %l0,24,%l0 + ldub [%i0+3],%l3 + sll %l1,16,%l1 + ldub [%i0+4],%l4 + sll %l2,8,%l2 + or %l1,%l0,%l0 + ldub [%i0+5],%l5 + sll %l4,24,%l4 + or %l3,%l2,%l2 + ldub [%i0+6],%l6 + sll %l5,16,%l5 + or %l0,%l2,%o0 + ldub [%i0+7],%l7 + + sll %l6,8,%l6 + or %l5,%l4,%l4 + ldub [%i0+8],%l0 + or %l7,%l6,%l6 + ldub [%i0+9],%l1 + or %l4,%l6,%o1 + ldub [%i0+10],%l2 + + sll %l0,24,%l0 + ldub [%i0+11],%l3 + sll %l1,16,%l1 + ldub [%i0+12],%l4 + sll %l2,8,%l2 + or %l1,%l0,%l0 + ldub [%i0+13],%l5 + sll %l4,24,%l4 + or %l3,%l2,%l2 + ldub [%i0+14],%l6 + sll %l5,16,%l5 + or %l0,%l2,%o2 + ldub [%i0+15],%l7 + + sll %l6,8,%l6 + or %l5,%l4,%l4 + or %l7,%l6,%l6 + or %l4,%l6,%o3 + +1: call .+8 + add %o7,AES_Td-1b,%o4 + call _sparcv9_AES_decrypt + mov %i2,%o5 + + srl %o0,24,%l0 + srl %o0,16,%l1 + stb %l0,[%i1+0] + srl %o0,8,%l2 + stb %l1,[%i1+1] + stb %l2,[%i1+2] + srl %o1,24,%l4 + stb %o0,[%i1+3] + + srl %o1,16,%l5 + stb %l4,[%i1+4] + srl %o1,8,%l6 + stb %l5,[%i1+5] + stb %l6,[%i1+6] + srl %o2,24,%l0 + stb %o1,[%i1+7] + + srl %o2,16,%l1 + stb %l0,[%i1+8] + srl %o2,8,%l2 + stb %l1,[%i1+9] + stb %l2,[%i1+10] + srl %o3,24,%l4 + stb %o2,[%i1+11] + + srl %o3,16,%l5 + stb %l4,[%i1+12] + srl %o3,8,%l6 + stb %l5,[%i1+13] + stb %l6,[%i1+14] + stb %o3,[%i1+15] + + ret + restore +.type AES_decrypt,#function +.size AES_decrypt,(.-AES_decrypt) +___ + +# fmovs instructions substituting for FP nops were originally added +# to meet specific instruction alignment requirements to maximize ILP. +# As UltraSPARC T1, a.k.a. Niagara, has shared FPU, FP nops can have +# undesired effect, so just omit them and sacrifice some portion of +# percent in performance... +$code =~ s/fmovs.*$//gm; + +print $code; +close STDOUT; # ensure flush diff --git a/libs/openssl/crypto/aes/asm/aes-x86_64.pl b/libs/openssl/crypto/aes/asm/aes-x86_64.pl new file mode 100755 index 00000000..34cbb5d8 --- /dev/null +++ b/libs/openssl/crypto/aes/asm/aes-x86_64.pl @@ -0,0 +1,2819 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# Version 2.1. +# +# aes-*-cbc benchmarks are improved by >70% [compared to gcc 3.3.2 on +# Opteron 240 CPU] plus all the bells-n-whistles from 32-bit version +# [you'll notice a lot of resemblance], such as compressed S-boxes +# in little-endian byte order, prefetch of these tables in CBC mode, +# as well as avoiding L1 cache aliasing between stack frame and key +# schedule and already mentioned tables, compressed Td4... +# +# Performance in number of cycles per processed byte for 128-bit key: +# +# ECB encrypt ECB decrypt CBC large chunk +# AMD64 33 41 13.0 +# EM64T 38 59 18.6(*) +# Core 2 30 43 14.5(*) +# +# (*) with hyper-threading off + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +$verticalspin=1; # unlike 32-bit version $verticalspin performs + # ~15% better on both AMD and Intel cores +$speed_limit=512; # see aes-586.pl for details + +$code=".text\n"; + +$s0="%eax"; +$s1="%ebx"; +$s2="%ecx"; +$s3="%edx"; +$acc0="%esi"; $mask80="%rsi"; +$acc1="%edi"; $maskfe="%rdi"; +$acc2="%ebp"; $mask1b="%rbp"; +$inp="%r8"; +$out="%r9"; +$t0="%r10d"; +$t1="%r11d"; +$t2="%r12d"; +$rnds="%r13d"; +$sbox="%r14"; +$key="%r15"; + +sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/; $r; } +sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/; + $r =~ s/%[er]([sd]i)/%\1l/; + $r =~ s/%(r[0-9]+)[d]?/%\1b/; $r; } +sub LO() { my $r=shift; $r =~ s/%r([a-z]+)/%e\1/; + $r =~ s/%r([0-9]+)/%r\1d/; $r; } +sub _data_word() +{ my $i; + while(defined($i=shift)) { $code.=sprintf".long\t0x%08x,0x%08x\n",$i,$i; } +} +sub data_word() +{ my $i; + my $last=pop(@_); + $code.=".long\t"; + while(defined($i=shift)) { $code.=sprintf"0x%08x,",$i; } + $code.=sprintf"0x%08x\n",$last; +} + +sub data_byte() +{ my $i; + my $last=pop(@_); + $code.=".byte\t"; + while(defined($i=shift)) { $code.=sprintf"0x%02x,",$i&0xff; } + $code.=sprintf"0x%02x\n",$last&0xff; +} + +sub encvert() +{ my $t3="%r8d"; # zaps $inp! + +$code.=<<___; + # favor 3-way issue Opteron pipeline... + movzb `&lo("$s0")`,$acc0 + movzb `&lo("$s1")`,$acc1 + movzb `&lo("$s2")`,$acc2 + mov 0($sbox,$acc0,8),$t0 + mov 0($sbox,$acc1,8),$t1 + mov 0($sbox,$acc2,8),$t2 + + movzb `&hi("$s1")`,$acc0 + movzb `&hi("$s2")`,$acc1 + movzb `&lo("$s3")`,$acc2 + xor 3($sbox,$acc0,8),$t0 + xor 3($sbox,$acc1,8),$t1 + mov 0($sbox,$acc2,8),$t3 + + movzb `&hi("$s3")`,$acc0 + shr \$16,$s2 + movzb `&hi("$s0")`,$acc2 + xor 3($sbox,$acc0,8),$t2 + shr \$16,$s3 + xor 3($sbox,$acc2,8),$t3 + + shr \$16,$s1 + lea 16($key),$key + shr \$16,$s0 + + movzb `&lo("$s2")`,$acc0 + movzb `&lo("$s3")`,$acc1 + movzb `&lo("$s0")`,$acc2 + xor 2($sbox,$acc0,8),$t0 + xor 2($sbox,$acc1,8),$t1 + xor 2($sbox,$acc2,8),$t2 + + movzb `&hi("$s3")`,$acc0 + movzb `&hi("$s0")`,$acc1 + movzb `&lo("$s1")`,$acc2 + xor 1($sbox,$acc0,8),$t0 + xor 1($sbox,$acc1,8),$t1 + xor 2($sbox,$acc2,8),$t3 + + mov 12($key),$s3 + movzb `&hi("$s1")`,$acc1 + movzb `&hi("$s2")`,$acc2 + mov 0($key),$s0 + xor 1($sbox,$acc1,8),$t2 + xor 1($sbox,$acc2,8),$t3 + + mov 4($key),$s1 + mov 8($key),$s2 + xor $t0,$s0 + xor $t1,$s1 + xor $t2,$s2 + xor $t3,$s3 +___ +} + +sub enclastvert() +{ my $t3="%r8d"; # zaps $inp! + +$code.=<<___; + movzb `&lo("$s0")`,$acc0 + movzb `&lo("$s1")`,$acc1 + movzb `&lo("$s2")`,$acc2 + movzb 2($sbox,$acc0,8),$t0 + movzb 2($sbox,$acc1,8),$t1 + movzb 2($sbox,$acc2,8),$t2 + + movzb `&lo("$s3")`,$acc0 + movzb `&hi("$s1")`,$acc1 + movzb `&hi("$s2")`,$acc2 + movzb 2($sbox,$acc0,8),$t3 + mov 0($sbox,$acc1,8),$acc1 #$t0 + mov 0($sbox,$acc2,8),$acc2 #$t1 + + and \$0x0000ff00,$acc1 + and \$0x0000ff00,$acc2 + + xor $acc1,$t0 + xor $acc2,$t1 + shr \$16,$s2 + + movzb `&hi("$s3")`,$acc0 + movzb `&hi("$s0")`,$acc1 + shr \$16,$s3 + mov 0($sbox,$acc0,8),$acc0 #$t2 + mov 0($sbox,$acc1,8),$acc1 #$t3 + + and \$0x0000ff00,$acc0 + and \$0x0000ff00,$acc1 + shr \$16,$s1 + xor $acc0,$t2 + xor $acc1,$t3 + shr \$16,$s0 + + movzb `&lo("$s2")`,$acc0 + movzb `&lo("$s3")`,$acc1 + movzb `&lo("$s0")`,$acc2 + mov 0($sbox,$acc0,8),$acc0 #$t0 + mov 0($sbox,$acc1,8),$acc1 #$t1 + mov 0($sbox,$acc2,8),$acc2 #$t2 + + and \$0x00ff0000,$acc0 + and \$0x00ff0000,$acc1 + and \$0x00ff0000,$acc2 + + xor $acc0,$t0 + xor $acc1,$t1 + xor $acc2,$t2 + + movzb `&lo("$s1")`,$acc0 + movzb `&hi("$s3")`,$acc1 + movzb `&hi("$s0")`,$acc2 + mov 0($sbox,$acc0,8),$acc0 #$t3 + mov 2($sbox,$acc1,8),$acc1 #$t0 + mov 2($sbox,$acc2,8),$acc2 #$t1 + + and \$0x00ff0000,$acc0 + and \$0xff000000,$acc1 + and \$0xff000000,$acc2 + + xor $acc0,$t3 + xor $acc1,$t0 + xor $acc2,$t1 + + movzb `&hi("$s1")`,$acc0 + movzb `&hi("$s2")`,$acc1 + mov 16+12($key),$s3 + mov 2($sbox,$acc0,8),$acc0 #$t2 + mov 2($sbox,$acc1,8),$acc1 #$t3 + mov 16+0($key),$s0 + + and \$0xff000000,$acc0 + and \$0xff000000,$acc1 + + xor $acc0,$t2 + xor $acc1,$t3 + + mov 16+4($key),$s1 + mov 16+8($key),$s2 + xor $t0,$s0 + xor $t1,$s1 + xor $t2,$s2 + xor $t3,$s3 +___ +} + +sub encstep() +{ my ($i,@s) = @_; + my $tmp0=$acc0; + my $tmp1=$acc1; + my $tmp2=$acc2; + my $out=($t0,$t1,$t2,$s[0])[$i]; + + if ($i==3) { + $tmp0=$s[1]; + $tmp1=$s[2]; + $tmp2=$s[3]; + } + $code.=" movzb ".&lo($s[0]).",$out\n"; + $code.=" mov $s[2],$tmp1\n" if ($i!=3); + $code.=" lea 16($key),$key\n" if ($i==0); + + $code.=" movzb ".&hi($s[1]).",$tmp0\n"; + $code.=" mov 0($sbox,$out,8),$out\n"; + + $code.=" shr \$16,$tmp1\n"; + $code.=" mov $s[3],$tmp2\n" if ($i!=3); + $code.=" xor 3($sbox,$tmp0,8),$out\n"; + + $code.=" movzb ".&lo($tmp1).",$tmp1\n"; + $code.=" shr \$24,$tmp2\n"; + $code.=" xor 4*$i($key),$out\n"; + + $code.=" xor 2($sbox,$tmp1,8),$out\n"; + $code.=" xor 1($sbox,$tmp2,8),$out\n"; + + $code.=" mov $t0,$s[1]\n" if ($i==3); + $code.=" mov $t1,$s[2]\n" if ($i==3); + $code.=" mov $t2,$s[3]\n" if ($i==3); + $code.="\n"; +} + +sub enclast() +{ my ($i,@s)=@_; + my $tmp0=$acc0; + my $tmp1=$acc1; + my $tmp2=$acc2; + my $out=($t0,$t1,$t2,$s[0])[$i]; + + if ($i==3) { + $tmp0=$s[1]; + $tmp1=$s[2]; + $tmp2=$s[3]; + } + $code.=" movzb ".&lo($s[0]).",$out\n"; + $code.=" mov $s[2],$tmp1\n" if ($i!=3); + + $code.=" mov 2($sbox,$out,8),$out\n"; + $code.=" shr \$16,$tmp1\n"; + $code.=" mov $s[3],$tmp2\n" if ($i!=3); + + $code.=" and \$0x000000ff,$out\n"; + $code.=" movzb ".&hi($s[1]).",$tmp0\n"; + $code.=" movzb ".&lo($tmp1).",$tmp1\n"; + $code.=" shr \$24,$tmp2\n"; + + $code.=" mov 0($sbox,$tmp0,8),$tmp0\n"; + $code.=" mov 0($sbox,$tmp1,8),$tmp1\n"; + $code.=" mov 2($sbox,$tmp2,8),$tmp2\n"; + + $code.=" and \$0x0000ff00,$tmp0\n"; + $code.=" and \$0x00ff0000,$tmp1\n"; + $code.=" and \$0xff000000,$tmp2\n"; + + $code.=" xor $tmp0,$out\n"; + $code.=" mov $t0,$s[1]\n" if ($i==3); + $code.=" xor $tmp1,$out\n"; + $code.=" mov $t1,$s[2]\n" if ($i==3); + $code.=" xor $tmp2,$out\n"; + $code.=" mov $t2,$s[3]\n" if ($i==3); + $code.="\n"; +} + +$code.=<<___; +.type _x86_64_AES_encrypt,\@abi-omnipotent +.align 16 +_x86_64_AES_encrypt: + xor 0($key),$s0 # xor with key + xor 4($key),$s1 + xor 8($key),$s2 + xor 12($key),$s3 + + mov 240($key),$rnds # load key->rounds + sub \$1,$rnds + jmp .Lenc_loop +.align 16 +.Lenc_loop: +___ + if ($verticalspin) { &encvert(); } + else { &encstep(0,$s0,$s1,$s2,$s3); + &encstep(1,$s1,$s2,$s3,$s0); + &encstep(2,$s2,$s3,$s0,$s1); + &encstep(3,$s3,$s0,$s1,$s2); + } +$code.=<<___; + sub \$1,$rnds + jnz .Lenc_loop +___ + if ($verticalspin) { &enclastvert(); } + else { &enclast(0,$s0,$s1,$s2,$s3); + &enclast(1,$s1,$s2,$s3,$s0); + &enclast(2,$s2,$s3,$s0,$s1); + &enclast(3,$s3,$s0,$s1,$s2); + $code.=<<___; + xor 16+0($key),$s0 # xor with key + xor 16+4($key),$s1 + xor 16+8($key),$s2 + xor 16+12($key),$s3 +___ + } +$code.=<<___; + .byte 0xf3,0xc3 # rep ret +.size _x86_64_AES_encrypt,.-_x86_64_AES_encrypt +___ + +# it's possible to implement this by shifting tN by 8, filling least +# significant byte with byte load and finally bswap-ing at the end, +# but such partial register load kills Core 2... +sub enccompactvert() +{ my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d"); + +$code.=<<___; + movzb `&lo("$s0")`,$t0 + movzb `&lo("$s1")`,$t1 + movzb `&lo("$s2")`,$t2 + movzb ($sbox,$t0,1),$t0 + movzb ($sbox,$t1,1),$t1 + movzb ($sbox,$t2,1),$t2 + + movzb `&lo("$s3")`,$t3 + movzb `&hi("$s1")`,$acc0 + movzb `&hi("$s2")`,$acc1 + movzb ($sbox,$t3,1),$t3 + movzb ($sbox,$acc0,1),$t4 #$t0 + movzb ($sbox,$acc1,1),$t5 #$t1 + + movzb `&hi("$s3")`,$acc2 + movzb `&hi("$s0")`,$acc0 + shr \$16,$s2 + movzb ($sbox,$acc2,1),$acc2 #$t2 + movzb ($sbox,$acc0,1),$acc0 #$t3 + shr \$16,$s3 + + movzb `&lo("$s2")`,$acc1 + shl \$8,$t4 + shl \$8,$t5 + movzb ($sbox,$acc1,1),$acc1 #$t0 + xor $t4,$t0 + xor $t5,$t1 + + movzb `&lo("$s3")`,$t4 + shr \$16,$s0 + shr \$16,$s1 + movzb `&lo("$s0")`,$t5 + shl \$8,$acc2 + shl \$8,$acc0 + movzb ($sbox,$t4,1),$t4 #$t1 + movzb ($sbox,$t5,1),$t5 #$t2 + xor $acc2,$t2 + xor $acc0,$t3 + + movzb `&lo("$s1")`,$acc2 + movzb `&hi("$s3")`,$acc0 + shl \$16,$acc1 + movzb ($sbox,$acc2,1),$acc2 #$t3 + movzb ($sbox,$acc0,1),$acc0 #$t0 + xor $acc1,$t0 + + movzb `&hi("$s0")`,$acc1 + shr \$8,$s2 + shr \$8,$s1 + movzb ($sbox,$acc1,1),$acc1 #$t1 + movzb ($sbox,$s2,1),$s3 #$t3 + movzb ($sbox,$s1,1),$s2 #$t2 + shl \$16,$t4 + shl \$16,$t5 + shl \$16,$acc2 + xor $t4,$t1 + xor $t5,$t2 + xor $acc2,$t3 + + shl \$24,$acc0 + shl \$24,$acc1 + shl \$24,$s3 + xor $acc0,$t0 + shl \$24,$s2 + xor $acc1,$t1 + mov $t0,$s0 + mov $t1,$s1 + xor $t2,$s2 + xor $t3,$s3 +___ +} + +sub enctransform_ref() +{ my $sn = shift; + my ($acc,$r2,$tmp)=("%r8d","%r9d","%r13d"); + +$code.=<<___; + mov $sn,$acc + and \$0x80808080,$acc + mov $acc,$tmp + shr \$7,$tmp + lea ($sn,$sn),$r2 + sub $tmp,$acc + and \$0xfefefefe,$r2 + and \$0x1b1b1b1b,$acc + mov $sn,$tmp + xor $acc,$r2 + + xor $r2,$sn + rol \$24,$sn + xor $r2,$sn + ror \$16,$tmp + xor $tmp,$sn + ror \$8,$tmp + xor $tmp,$sn +___ +} + +# unlike decrypt case it does not pay off to parallelize enctransform +sub enctransform() +{ my ($t3,$r20,$r21)=($acc2,"%r8d","%r9d"); + +$code.=<<___; + mov $s0,$acc0 + mov $s1,$acc1 + and \$0x80808080,$acc0 + and \$0x80808080,$acc1 + mov $acc0,$t0 + mov $acc1,$t1 + shr \$7,$t0 + lea ($s0,$s0),$r20 + shr \$7,$t1 + lea ($s1,$s1),$r21 + sub $t0,$acc0 + sub $t1,$acc1 + and \$0xfefefefe,$r20 + and \$0xfefefefe,$r21 + and \$0x1b1b1b1b,$acc0 + and \$0x1b1b1b1b,$acc1 + mov $s0,$t0 + mov $s1,$t1 + xor $acc0,$r20 + xor $acc1,$r21 + + xor $r20,$s0 + xor $r21,$s1 + mov $s2,$acc0 + mov $s3,$acc1 + rol \$24,$s0 + rol \$24,$s1 + and \$0x80808080,$acc0 + and \$0x80808080,$acc1 + xor $r20,$s0 + xor $r21,$s1 + mov $acc0,$t2 + mov $acc1,$t3 + ror \$16,$t0 + ror \$16,$t1 + shr \$7,$t2 + lea ($s2,$s2),$r20 + xor $t0,$s0 + xor $t1,$s1 + shr \$7,$t3 + lea ($s3,$s3),$r21 + ror \$8,$t0 + ror \$8,$t1 + sub $t2,$acc0 + sub $t3,$acc1 + xor $t0,$s0 + xor $t1,$s1 + + and \$0xfefefefe,$r20 + and \$0xfefefefe,$r21 + and \$0x1b1b1b1b,$acc0 + and \$0x1b1b1b1b,$acc1 + mov $s2,$t2 + mov $s3,$t3 + xor $acc0,$r20 + xor $acc1,$r21 + + xor $r20,$s2 + xor $r21,$s3 + rol \$24,$s2 + rol \$24,$s3 + xor $r20,$s2 + xor $r21,$s3 + mov 0($sbox),$acc0 # prefetch Te4 + ror \$16,$t2 + ror \$16,$t3 + mov 64($sbox),$acc1 + xor $t2,$s2 + xor $t3,$s3 + mov 128($sbox),$r20 + ror \$8,$t2 + ror \$8,$t3 + mov 192($sbox),$r21 + xor $t2,$s2 + xor $t3,$s3 +___ +} + +$code.=<<___; +.type _x86_64_AES_encrypt_compact,\@abi-omnipotent +.align 16 +_x86_64_AES_encrypt_compact: + lea 128($sbox),$inp # size optimization + mov 0-128($inp),$acc1 # prefetch Te4 + mov 32-128($inp),$acc2 + mov 64-128($inp),$t0 + mov 96-128($inp),$t1 + mov 128-128($inp),$acc1 + mov 160-128($inp),$acc2 + mov 192-128($inp),$t0 + mov 224-128($inp),$t1 + jmp .Lenc_loop_compact +.align 16 +.Lenc_loop_compact: + xor 0($key),$s0 # xor with key + xor 4($key),$s1 + xor 8($key),$s2 + xor 12($key),$s3 + lea 16($key),$key +___ + &enccompactvert(); +$code.=<<___; + cmp 16(%rsp),$key + je .Lenc_compact_done +___ + &enctransform(); +$code.=<<___; + jmp .Lenc_loop_compact +.align 16 +.Lenc_compact_done: + xor 0($key),$s0 + xor 4($key),$s1 + xor 8($key),$s2 + xor 12($key),$s3 + .byte 0xf3,0xc3 # rep ret +.size _x86_64_AES_encrypt_compact,.-_x86_64_AES_encrypt_compact +___ + +# void AES_encrypt (const void *inp,void *out,const AES_KEY *key); +$code.=<<___; +.globl AES_encrypt +.type AES_encrypt,\@function,3 +.align 16 +.globl asm_AES_encrypt +.hidden asm_AES_encrypt +asm_AES_encrypt: +AES_encrypt: + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + + # allocate frame "above" key schedule + mov %rsp,%r10 + lea -63(%rdx),%rcx # %rdx is key argument + and \$-64,%rsp + sub %rsp,%rcx + neg %rcx + and \$0x3c0,%rcx + sub %rcx,%rsp + sub \$32,%rsp + + mov %rsi,16(%rsp) # save out + mov %r10,24(%rsp) # save real stack pointer +.Lenc_prologue: + + mov %rdx,$key + mov 240($key),$rnds # load rounds + + mov 0(%rdi),$s0 # load input vector + mov 4(%rdi),$s1 + mov 8(%rdi),$s2 + mov 12(%rdi),$s3 + + shl \$4,$rnds + lea ($key,$rnds),%rbp + mov $key,(%rsp) # key schedule + mov %rbp,8(%rsp) # end of key schedule + + # pick Te4 copy which can't "overlap" with stack frame or key schedule + lea .LAES_Te+2048(%rip),$sbox + lea 768(%rsp),%rbp + sub $sbox,%rbp + and \$0x300,%rbp + lea ($sbox,%rbp),$sbox + + call _x86_64_AES_encrypt_compact + + mov 16(%rsp),$out # restore out + mov 24(%rsp),%rsi # restore saved stack pointer + mov $s0,0($out) # write output vector + mov $s1,4($out) + mov $s2,8($out) + mov $s3,12($out) + + mov (%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 + mov 24(%rsi),%r12 + mov 32(%rsi),%rbp + mov 40(%rsi),%rbx + lea 48(%rsi),%rsp +.Lenc_epilogue: + ret +.size AES_encrypt,.-AES_encrypt +___ + +#------------------------------------------------------------------# + +sub decvert() +{ my $t3="%r8d"; # zaps $inp! + +$code.=<<___; + # favor 3-way issue Opteron pipeline... + movzb `&lo("$s0")`,$acc0 + movzb `&lo("$s1")`,$acc1 + movzb `&lo("$s2")`,$acc2 + mov 0($sbox,$acc0,8),$t0 + mov 0($sbox,$acc1,8),$t1 + mov 0($sbox,$acc2,8),$t2 + + movzb `&hi("$s3")`,$acc0 + movzb `&hi("$s0")`,$acc1 + movzb `&lo("$s3")`,$acc2 + xor 3($sbox,$acc0,8),$t0 + xor 3($sbox,$acc1,8),$t1 + mov 0($sbox,$acc2,8),$t3 + + movzb `&hi("$s1")`,$acc0 + shr \$16,$s0 + movzb `&hi("$s2")`,$acc2 + xor 3($sbox,$acc0,8),$t2 + shr \$16,$s3 + xor 3($sbox,$acc2,8),$t3 + + shr \$16,$s1 + lea 16($key),$key + shr \$16,$s2 + + movzb `&lo("$s2")`,$acc0 + movzb `&lo("$s3")`,$acc1 + movzb `&lo("$s0")`,$acc2 + xor 2($sbox,$acc0,8),$t0 + xor 2($sbox,$acc1,8),$t1 + xor 2($sbox,$acc2,8),$t2 + + movzb `&hi("$s1")`,$acc0 + movzb `&hi("$s2")`,$acc1 + movzb `&lo("$s1")`,$acc2 + xor 1($sbox,$acc0,8),$t0 + xor 1($sbox,$acc1,8),$t1 + xor 2($sbox,$acc2,8),$t3 + + movzb `&hi("$s3")`,$acc0 + mov 12($key),$s3 + movzb `&hi("$s0")`,$acc2 + xor 1($sbox,$acc0,8),$t2 + mov 0($key),$s0 + xor 1($sbox,$acc2,8),$t3 + + xor $t0,$s0 + mov 4($key),$s1 + mov 8($key),$s2 + xor $t2,$s2 + xor $t1,$s1 + xor $t3,$s3 +___ +} + +sub declastvert() +{ my $t3="%r8d"; # zaps $inp! + +$code.=<<___; + lea 2048($sbox),$sbox # size optimization + movzb `&lo("$s0")`,$acc0 + movzb `&lo("$s1")`,$acc1 + movzb `&lo("$s2")`,$acc2 + movzb ($sbox,$acc0,1),$t0 + movzb ($sbox,$acc1,1),$t1 + movzb ($sbox,$acc2,1),$t2 + + movzb `&lo("$s3")`,$acc0 + movzb `&hi("$s3")`,$acc1 + movzb `&hi("$s0")`,$acc2 + movzb ($sbox,$acc0,1),$t3 + movzb ($sbox,$acc1,1),$acc1 #$t0 + movzb ($sbox,$acc2,1),$acc2 #$t1 + + shl \$8,$acc1 + shl \$8,$acc2 + + xor $acc1,$t0 + xor $acc2,$t1 + shr \$16,$s3 + + movzb `&hi("$s1")`,$acc0 + movzb `&hi("$s2")`,$acc1 + shr \$16,$s0 + movzb ($sbox,$acc0,1),$acc0 #$t2 + movzb ($sbox,$acc1,1),$acc1 #$t3 + + shl \$8,$acc0 + shl \$8,$acc1 + shr \$16,$s1 + xor $acc0,$t2 + xor $acc1,$t3 + shr \$16,$s2 + + movzb `&lo("$s2")`,$acc0 + movzb `&lo("$s3")`,$acc1 + movzb `&lo("$s0")`,$acc2 + movzb ($sbox,$acc0,1),$acc0 #$t0 + movzb ($sbox,$acc1,1),$acc1 #$t1 + movzb ($sbox,$acc2,1),$acc2 #$t2 + + shl \$16,$acc0 + shl \$16,$acc1 + shl \$16,$acc2 + + xor $acc0,$t0 + xor $acc1,$t1 + xor $acc2,$t2 + + movzb `&lo("$s1")`,$acc0 + movzb `&hi("$s1")`,$acc1 + movzb `&hi("$s2")`,$acc2 + movzb ($sbox,$acc0,1),$acc0 #$t3 + movzb ($sbox,$acc1,1),$acc1 #$t0 + movzb ($sbox,$acc2,1),$acc2 #$t1 + + shl \$16,$acc0 + shl \$24,$acc1 + shl \$24,$acc2 + + xor $acc0,$t3 + xor $acc1,$t0 + xor $acc2,$t1 + + movzb `&hi("$s3")`,$acc0 + movzb `&hi("$s0")`,$acc1 + mov 16+12($key),$s3 + movzb ($sbox,$acc0,1),$acc0 #$t2 + movzb ($sbox,$acc1,1),$acc1 #$t3 + mov 16+0($key),$s0 + + shl \$24,$acc0 + shl \$24,$acc1 + + xor $acc0,$t2 + xor $acc1,$t3 + + mov 16+4($key),$s1 + mov 16+8($key),$s2 + lea -2048($sbox),$sbox + xor $t0,$s0 + xor $t1,$s1 + xor $t2,$s2 + xor $t3,$s3 +___ +} + +sub decstep() +{ my ($i,@s) = @_; + my $tmp0=$acc0; + my $tmp1=$acc1; + my $tmp2=$acc2; + my $out=($t0,$t1,$t2,$s[0])[$i]; + + $code.=" mov $s[0],$out\n" if ($i!=3); + $tmp1=$s[2] if ($i==3); + $code.=" mov $s[2],$tmp1\n" if ($i!=3); + $code.=" and \$0xFF,$out\n"; + + $code.=" mov 0($sbox,$out,8),$out\n"; + $code.=" shr \$16,$tmp1\n"; + $tmp2=$s[3] if ($i==3); + $code.=" mov $s[3],$tmp2\n" if ($i!=3); + + $tmp0=$s[1] if ($i==3); + $code.=" movzb ".&hi($s[1]).",$tmp0\n"; + $code.=" and \$0xFF,$tmp1\n"; + $code.=" shr \$24,$tmp2\n"; + + $code.=" xor 3($sbox,$tmp0,8),$out\n"; + $code.=" xor 2($sbox,$tmp1,8),$out\n"; + $code.=" xor 1($sbox,$tmp2,8),$out\n"; + + $code.=" mov $t2,$s[1]\n" if ($i==3); + $code.=" mov $t1,$s[2]\n" if ($i==3); + $code.=" mov $t0,$s[3]\n" if ($i==3); + $code.="\n"; +} + +sub declast() +{ my ($i,@s)=@_; + my $tmp0=$acc0; + my $tmp1=$acc1; + my $tmp2=$acc2; + my $out=($t0,$t1,$t2,$s[0])[$i]; + + $code.=" mov $s[0],$out\n" if ($i!=3); + $tmp1=$s[2] if ($i==3); + $code.=" mov $s[2],$tmp1\n" if ($i!=3); + $code.=" and \$0xFF,$out\n"; + + $code.=" movzb 2048($sbox,$out,1),$out\n"; + $code.=" shr \$16,$tmp1\n"; + $tmp2=$s[3] if ($i==3); + $code.=" mov $s[3],$tmp2\n" if ($i!=3); + + $tmp0=$s[1] if ($i==3); + $code.=" movzb ".&hi($s[1]).",$tmp0\n"; + $code.=" and \$0xFF,$tmp1\n"; + $code.=" shr \$24,$tmp2\n"; + + $code.=" movzb 2048($sbox,$tmp0,1),$tmp0\n"; + $code.=" movzb 2048($sbox,$tmp1,1),$tmp1\n"; + $code.=" movzb 2048($sbox,$tmp2,1),$tmp2\n"; + + $code.=" shl \$8,$tmp0\n"; + $code.=" shl \$16,$tmp1\n"; + $code.=" shl \$24,$tmp2\n"; + + $code.=" xor $tmp0,$out\n"; + $code.=" mov $t2,$s[1]\n" if ($i==3); + $code.=" xor $tmp1,$out\n"; + $code.=" mov $t1,$s[2]\n" if ($i==3); + $code.=" xor $tmp2,$out\n"; + $code.=" mov $t0,$s[3]\n" if ($i==3); + $code.="\n"; +} + +$code.=<<___; +.type _x86_64_AES_decrypt,\@abi-omnipotent +.align 16 +_x86_64_AES_decrypt: + xor 0($key),$s0 # xor with key + xor 4($key),$s1 + xor 8($key),$s2 + xor 12($key),$s3 + + mov 240($key),$rnds # load key->rounds + sub \$1,$rnds + jmp .Ldec_loop +.align 16 +.Ldec_loop: +___ + if ($verticalspin) { &decvert(); } + else { &decstep(0,$s0,$s3,$s2,$s1); + &decstep(1,$s1,$s0,$s3,$s2); + &decstep(2,$s2,$s1,$s0,$s3); + &decstep(3,$s3,$s2,$s1,$s0); + $code.=<<___; + lea 16($key),$key + xor 0($key),$s0 # xor with key + xor 4($key),$s1 + xor 8($key),$s2 + xor 12($key),$s3 +___ + } +$code.=<<___; + sub \$1,$rnds + jnz .Ldec_loop +___ + if ($verticalspin) { &declastvert(); } + else { &declast(0,$s0,$s3,$s2,$s1); + &declast(1,$s1,$s0,$s3,$s2); + &declast(2,$s2,$s1,$s0,$s3); + &declast(3,$s3,$s2,$s1,$s0); + $code.=<<___; + xor 16+0($key),$s0 # xor with key + xor 16+4($key),$s1 + xor 16+8($key),$s2 + xor 16+12($key),$s3 +___ + } +$code.=<<___; + .byte 0xf3,0xc3 # rep ret +.size _x86_64_AES_decrypt,.-_x86_64_AES_decrypt +___ + +sub deccompactvert() +{ my ($t3,$t4,$t5)=("%r8d","%r9d","%r13d"); + +$code.=<<___; + movzb `&lo("$s0")`,$t0 + movzb `&lo("$s1")`,$t1 + movzb `&lo("$s2")`,$t2 + movzb ($sbox,$t0,1),$t0 + movzb ($sbox,$t1,1),$t1 + movzb ($sbox,$t2,1),$t2 + + movzb `&lo("$s3")`,$t3 + movzb `&hi("$s3")`,$acc0 + movzb `&hi("$s0")`,$acc1 + movzb ($sbox,$t3,1),$t3 + movzb ($sbox,$acc0,1),$t4 #$t0 + movzb ($sbox,$acc1,1),$t5 #$t1 + + movzb `&hi("$s1")`,$acc2 + movzb `&hi("$s2")`,$acc0 + shr \$16,$s2 + movzb ($sbox,$acc2,1),$acc2 #$t2 + movzb ($sbox,$acc0,1),$acc0 #$t3 + shr \$16,$s3 + + movzb `&lo("$s2")`,$acc1 + shl \$8,$t4 + shl \$8,$t5 + movzb ($sbox,$acc1,1),$acc1 #$t0 + xor $t4,$t0 + xor $t5,$t1 + + movzb `&lo("$s3")`,$t4 + shr \$16,$s0 + shr \$16,$s1 + movzb `&lo("$s0")`,$t5 + shl \$8,$acc2 + shl \$8,$acc0 + movzb ($sbox,$t4,1),$t4 #$t1 + movzb ($sbox,$t5,1),$t5 #$t2 + xor $acc2,$t2 + xor $acc0,$t3 + + movzb `&lo("$s1")`,$acc2 + movzb `&hi("$s1")`,$acc0 + shl \$16,$acc1 + movzb ($sbox,$acc2,1),$acc2 #$t3 + movzb ($sbox,$acc0,1),$acc0 #$t0 + xor $acc1,$t0 + + movzb `&hi("$s2")`,$acc1 + shl \$16,$t4 + shl \$16,$t5 + movzb ($sbox,$acc1,1),$s1 #$t1 + xor $t4,$t1 + xor $t5,$t2 + + movzb `&hi("$s3")`,$acc1 + shr \$8,$s0 + shl \$16,$acc2 + movzb ($sbox,$acc1,1),$s2 #$t2 + movzb ($sbox,$s0,1),$s3 #$t3 + xor $acc2,$t3 + + shl \$24,$acc0 + shl \$24,$s1 + shl \$24,$s2 + xor $acc0,$t0 + shl \$24,$s3 + xor $t1,$s1 + mov $t0,$s0 + xor $t2,$s2 + xor $t3,$s3 +___ +} + +# parallelized version! input is pair of 64-bit values: %rax=s1.s0 +# and %rcx=s3.s2, output is four 32-bit values in %eax=s0, %ebx=s1, +# %ecx=s2 and %edx=s3. +sub dectransform() +{ my ($tp10,$tp20,$tp40,$tp80,$acc0)=("%rax","%r8", "%r9", "%r10","%rbx"); + my ($tp18,$tp28,$tp48,$tp88,$acc8)=("%rcx","%r11","%r12","%r13","%rdx"); + my $prefetch = shift; + +$code.=<<___; + mov $tp10,$acc0 + mov $tp18,$acc8 + and $mask80,$acc0 + and $mask80,$acc8 + mov $acc0,$tp40 + mov $acc8,$tp48 + shr \$7,$tp40 + lea ($tp10,$tp10),$tp20 + shr \$7,$tp48 + lea ($tp18,$tp18),$tp28 + sub $tp40,$acc0 + sub $tp48,$acc8 + and $maskfe,$tp20 + and $maskfe,$tp28 + and $mask1b,$acc0 + and $mask1b,$acc8 + xor $tp20,$acc0 + xor $tp28,$acc8 + mov $acc0,$tp20 + mov $acc8,$tp28 + + and $mask80,$acc0 + and $mask80,$acc8 + mov $acc0,$tp80 + mov $acc8,$tp88 + shr \$7,$tp80 + lea ($tp20,$tp20),$tp40 + shr \$7,$tp88 + lea ($tp28,$tp28),$tp48 + sub $tp80,$acc0 + sub $tp88,$acc8 + and $maskfe,$tp40 + and $maskfe,$tp48 + and $mask1b,$acc0 + and $mask1b,$acc8 + xor $tp40,$acc0 + xor $tp48,$acc8 + mov $acc0,$tp40 + mov $acc8,$tp48 + + and $mask80,$acc0 + and $mask80,$acc8 + mov $acc0,$tp80 + mov $acc8,$tp88 + shr \$7,$tp80 + xor $tp10,$tp20 # tp2^=tp1 + shr \$7,$tp88 + xor $tp18,$tp28 # tp2^=tp1 + sub $tp80,$acc0 + sub $tp88,$acc8 + lea ($tp40,$tp40),$tp80 + lea ($tp48,$tp48),$tp88 + xor $tp10,$tp40 # tp4^=tp1 + xor $tp18,$tp48 # tp4^=tp1 + and $maskfe,$tp80 + and $maskfe,$tp88 + and $mask1b,$acc0 + and $mask1b,$acc8 + xor $acc0,$tp80 + xor $acc8,$tp88 + + xor $tp80,$tp10 # tp1^=tp8 + xor $tp88,$tp18 # tp1^=tp8 + xor $tp80,$tp20 # tp2^tp1^=tp8 + xor $tp88,$tp28 # tp2^tp1^=tp8 + mov $tp10,$acc0 + mov $tp18,$acc8 + xor $tp80,$tp40 # tp4^tp1^=tp8 + xor $tp88,$tp48 # tp4^tp1^=tp8 + shr \$32,$acc0 + shr \$32,$acc8 + xor $tp20,$tp80 # tp8^=tp8^tp2^tp1=tp2^tp1 + xor $tp28,$tp88 # tp8^=tp8^tp2^tp1=tp2^tp1 + rol \$8,`&LO("$tp10")` # ROTATE(tp1^tp8,8) + rol \$8,`&LO("$tp18")` # ROTATE(tp1^tp8,8) + xor $tp40,$tp80 # tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2 + xor $tp48,$tp88 # tp2^tp1^=tp8^tp4^tp1=tp8^tp4^tp2 + + rol \$8,`&LO("$acc0")` # ROTATE(tp1^tp8,8) + rol \$8,`&LO("$acc8")` # ROTATE(tp1^tp8,8) + xor `&LO("$tp80")`,`&LO("$tp10")` + xor `&LO("$tp88")`,`&LO("$tp18")` + shr \$32,$tp80 + shr \$32,$tp88 + xor `&LO("$tp80")`,`&LO("$acc0")` + xor `&LO("$tp88")`,`&LO("$acc8")` + + mov $tp20,$tp80 + mov $tp28,$tp88 + shr \$32,$tp80 + shr \$32,$tp88 + rol \$24,`&LO("$tp20")` # ROTATE(tp2^tp1^tp8,24) + rol \$24,`&LO("$tp28")` # ROTATE(tp2^tp1^tp8,24) + rol \$24,`&LO("$tp80")` # ROTATE(tp2^tp1^tp8,24) + rol \$24,`&LO("$tp88")` # ROTATE(tp2^tp1^tp8,24) + xor `&LO("$tp20")`,`&LO("$tp10")` + xor `&LO("$tp28")`,`&LO("$tp18")` + mov $tp40,$tp20 + mov $tp48,$tp28 + xor `&LO("$tp80")`,`&LO("$acc0")` + xor `&LO("$tp88")`,`&LO("$acc8")` + + `"mov 0($sbox),$mask80" if ($prefetch)` + shr \$32,$tp20 + shr \$32,$tp28 + `"mov 64($sbox),$maskfe" if ($prefetch)` + rol \$16,`&LO("$tp40")` # ROTATE(tp4^tp1^tp8,16) + rol \$16,`&LO("$tp48")` # ROTATE(tp4^tp1^tp8,16) + `"mov 128($sbox),$mask1b" if ($prefetch)` + rol \$16,`&LO("$tp20")` # ROTATE(tp4^tp1^tp8,16) + rol \$16,`&LO("$tp28")` # ROTATE(tp4^tp1^tp8,16) + `"mov 192($sbox),$tp80" if ($prefetch)` + xor `&LO("$tp40")`,`&LO("$tp10")` + xor `&LO("$tp48")`,`&LO("$tp18")` + `"mov 256($sbox),$tp88" if ($prefetch)` + xor `&LO("$tp20")`,`&LO("$acc0")` + xor `&LO("$tp28")`,`&LO("$acc8")` +___ +} + +$code.=<<___; +.type _x86_64_AES_decrypt_compact,\@abi-omnipotent +.align 16 +_x86_64_AES_decrypt_compact: + lea 128($sbox),$inp # size optimization + mov 0-128($inp),$acc1 # prefetch Td4 + mov 32-128($inp),$acc2 + mov 64-128($inp),$t0 + mov 96-128($inp),$t1 + mov 128-128($inp),$acc1 + mov 160-128($inp),$acc2 + mov 192-128($inp),$t0 + mov 224-128($inp),$t1 + jmp .Ldec_loop_compact + +.align 16 +.Ldec_loop_compact: + xor 0($key),$s0 # xor with key + xor 4($key),$s1 + xor 8($key),$s2 + xor 12($key),$s3 + lea 16($key),$key +___ + &deccompactvert(); +$code.=<<___; + cmp 16(%rsp),$key + je .Ldec_compact_done + + mov 256+0($sbox),$mask80 + shl \$32,%rbx + shl \$32,%rdx + mov 256+8($sbox),$maskfe + or %rbx,%rax + or %rdx,%rcx + mov 256+16($sbox),$mask1b +___ + &dectransform(1); +$code.=<<___; + jmp .Ldec_loop_compact +.align 16 +.Ldec_compact_done: + xor 0($key),$s0 + xor 4($key),$s1 + xor 8($key),$s2 + xor 12($key),$s3 + .byte 0xf3,0xc3 # rep ret +.size _x86_64_AES_decrypt_compact,.-_x86_64_AES_decrypt_compact +___ + +# void AES_decrypt (const void *inp,void *out,const AES_KEY *key); +$code.=<<___; +.globl AES_decrypt +.type AES_decrypt,\@function,3 +.align 16 +.globl asm_AES_decrypt +.hidden asm_AES_decrypt +asm_AES_decrypt: +AES_decrypt: + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + + # allocate frame "above" key schedule + mov %rsp,%r10 + lea -63(%rdx),%rcx # %rdx is key argument + and \$-64,%rsp + sub %rsp,%rcx + neg %rcx + and \$0x3c0,%rcx + sub %rcx,%rsp + sub \$32,%rsp + + mov %rsi,16(%rsp) # save out + mov %r10,24(%rsp) # save real stack pointer +.Ldec_prologue: + + mov %rdx,$key + mov 240($key),$rnds # load rounds + + mov 0(%rdi),$s0 # load input vector + mov 4(%rdi),$s1 + mov 8(%rdi),$s2 + mov 12(%rdi),$s3 + + shl \$4,$rnds + lea ($key,$rnds),%rbp + mov $key,(%rsp) # key schedule + mov %rbp,8(%rsp) # end of key schedule + + # pick Td4 copy which can't "overlap" with stack frame or key schedule + lea .LAES_Td+2048(%rip),$sbox + lea 768(%rsp),%rbp + sub $sbox,%rbp + and \$0x300,%rbp + lea ($sbox,%rbp),$sbox + shr \$3,%rbp # recall "magic" constants! + add %rbp,$sbox + + call _x86_64_AES_decrypt_compact + + mov 16(%rsp),$out # restore out + mov 24(%rsp),%rsi # restore saved stack pointer + mov $s0,0($out) # write output vector + mov $s1,4($out) + mov $s2,8($out) + mov $s3,12($out) + + mov (%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 + mov 24(%rsi),%r12 + mov 32(%rsi),%rbp + mov 40(%rsi),%rbx + lea 48(%rsi),%rsp +.Ldec_epilogue: + ret +.size AES_decrypt,.-AES_decrypt +___ +#------------------------------------------------------------------# + +sub enckey() +{ +$code.=<<___; + movz %dl,%esi # rk[i]>>0 + movzb -128(%rbp,%rsi),%ebx + movz %dh,%esi # rk[i]>>8 + shl \$24,%ebx + xor %ebx,%eax + + movzb -128(%rbp,%rsi),%ebx + shr \$16,%edx + movz %dl,%esi # rk[i]>>16 + xor %ebx,%eax + + movzb -128(%rbp,%rsi),%ebx + movz %dh,%esi # rk[i]>>24 + shl \$8,%ebx + xor %ebx,%eax + + movzb -128(%rbp,%rsi),%ebx + shl \$16,%ebx + xor %ebx,%eax + + xor 1024-128(%rbp,%rcx,4),%eax # rcon +___ +} + +# int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits, +# AES_KEY *key) +$code.=<<___; +.globl private_AES_set_encrypt_key +.type private_AES_set_encrypt_key,\@function,3 +.align 16 +private_AES_set_encrypt_key: + push %rbx + push %rbp + push %r12 # redundant, but allows to share + push %r13 # exception handler... + push %r14 + push %r15 + sub \$8,%rsp +.Lenc_key_prologue: + + call _x86_64_AES_set_encrypt_key + + mov 8(%rsp),%r15 + mov 16(%rsp),%r14 + mov 24(%rsp),%r13 + mov 32(%rsp),%r12 + mov 40(%rsp),%rbp + mov 48(%rsp),%rbx + add \$56,%rsp +.Lenc_key_epilogue: + ret +.size private_AES_set_encrypt_key,.-private_AES_set_encrypt_key + +.type _x86_64_AES_set_encrypt_key,\@abi-omnipotent +.align 16 +_x86_64_AES_set_encrypt_key: + mov %esi,%ecx # %ecx=bits + mov %rdi,%rsi # %rsi=userKey + mov %rdx,%rdi # %rdi=key + + test \$-1,%rsi + jz .Lbadpointer + test \$-1,%rdi + jz .Lbadpointer + + lea .LAES_Te(%rip),%rbp + lea 2048+128(%rbp),%rbp + + # prefetch Te4 + mov 0-128(%rbp),%eax + mov 32-128(%rbp),%ebx + mov 64-128(%rbp),%r8d + mov 96-128(%rbp),%edx + mov 128-128(%rbp),%eax + mov 160-128(%rbp),%ebx + mov 192-128(%rbp),%r8d + mov 224-128(%rbp),%edx + + cmp \$128,%ecx + je .L10rounds + cmp \$192,%ecx + je .L12rounds + cmp \$256,%ecx + je .L14rounds + mov \$-2,%rax # invalid number of bits + jmp .Lexit + +.L10rounds: + mov 0(%rsi),%rax # copy first 4 dwords + mov 8(%rsi),%rdx + mov %rax,0(%rdi) + mov %rdx,8(%rdi) + + shr \$32,%rdx + xor %ecx,%ecx + jmp .L10shortcut +.align 4 +.L10loop: + mov 0(%rdi),%eax # rk[0] + mov 12(%rdi),%edx # rk[3] +.L10shortcut: +___ + &enckey (); +$code.=<<___; + mov %eax,16(%rdi) # rk[4] + xor 4(%rdi),%eax + mov %eax,20(%rdi) # rk[5] + xor 8(%rdi),%eax + mov %eax,24(%rdi) # rk[6] + xor 12(%rdi),%eax + mov %eax,28(%rdi) # rk[7] + add \$1,%ecx + lea 16(%rdi),%rdi + cmp \$10,%ecx + jl .L10loop + + movl \$10,80(%rdi) # setup number of rounds + xor %rax,%rax + jmp .Lexit + +.L12rounds: + mov 0(%rsi),%rax # copy first 6 dwords + mov 8(%rsi),%rbx + mov 16(%rsi),%rdx + mov %rax,0(%rdi) + mov %rbx,8(%rdi) + mov %rdx,16(%rdi) + + shr \$32,%rdx + xor %ecx,%ecx + jmp .L12shortcut +.align 4 +.L12loop: + mov 0(%rdi),%eax # rk[0] + mov 20(%rdi),%edx # rk[5] +.L12shortcut: +___ + &enckey (); +$code.=<<___; + mov %eax,24(%rdi) # rk[6] + xor 4(%rdi),%eax + mov %eax,28(%rdi) # rk[7] + xor 8(%rdi),%eax + mov %eax,32(%rdi) # rk[8] + xor 12(%rdi),%eax + mov %eax,36(%rdi) # rk[9] + + cmp \$7,%ecx + je .L12break + add \$1,%ecx + + xor 16(%rdi),%eax + mov %eax,40(%rdi) # rk[10] + xor 20(%rdi),%eax + mov %eax,44(%rdi) # rk[11] + + lea 24(%rdi),%rdi + jmp .L12loop +.L12break: + movl \$12,72(%rdi) # setup number of rounds + xor %rax,%rax + jmp .Lexit + +.L14rounds: + mov 0(%rsi),%rax # copy first 8 dwords + mov 8(%rsi),%rbx + mov 16(%rsi),%rcx + mov 24(%rsi),%rdx + mov %rax,0(%rdi) + mov %rbx,8(%rdi) + mov %rcx,16(%rdi) + mov %rdx,24(%rdi) + + shr \$32,%rdx + xor %ecx,%ecx + jmp .L14shortcut +.align 4 +.L14loop: + mov 0(%rdi),%eax # rk[0] + mov 28(%rdi),%edx # rk[4] +.L14shortcut: +___ + &enckey (); +$code.=<<___; + mov %eax,32(%rdi) # rk[8] + xor 4(%rdi),%eax + mov %eax,36(%rdi) # rk[9] + xor 8(%rdi),%eax + mov %eax,40(%rdi) # rk[10] + xor 12(%rdi),%eax + mov %eax,44(%rdi) # rk[11] + + cmp \$6,%ecx + je .L14break + add \$1,%ecx + + mov %eax,%edx + mov 16(%rdi),%eax # rk[4] + movz %dl,%esi # rk[11]>>0 + movzb -128(%rbp,%rsi),%ebx + movz %dh,%esi # rk[11]>>8 + xor %ebx,%eax + + movzb -128(%rbp,%rsi),%ebx + shr \$16,%edx + shl \$8,%ebx + movz %dl,%esi # rk[11]>>16 + xor %ebx,%eax + + movzb -128(%rbp,%rsi),%ebx + movz %dh,%esi # rk[11]>>24 + shl \$16,%ebx + xor %ebx,%eax + + movzb -128(%rbp,%rsi),%ebx + shl \$24,%ebx + xor %ebx,%eax + + mov %eax,48(%rdi) # rk[12] + xor 20(%rdi),%eax + mov %eax,52(%rdi) # rk[13] + xor 24(%rdi),%eax + mov %eax,56(%rdi) # rk[14] + xor 28(%rdi),%eax + mov %eax,60(%rdi) # rk[15] + + lea 32(%rdi),%rdi + jmp .L14loop +.L14break: + movl \$14,48(%rdi) # setup number of rounds + xor %rax,%rax + jmp .Lexit + +.Lbadpointer: + mov \$-1,%rax +.Lexit: + .byte 0xf3,0xc3 # rep ret +.size _x86_64_AES_set_encrypt_key,.-_x86_64_AES_set_encrypt_key +___ + +sub deckey_ref() +{ my ($i,$ptr,$te,$td) = @_; + my ($tp1,$tp2,$tp4,$tp8,$acc)=("%eax","%ebx","%edi","%edx","%r8d"); +$code.=<<___; + mov $i($ptr),$tp1 + mov $tp1,$acc + and \$0x80808080,$acc + mov $acc,$tp4 + shr \$7,$tp4 + lea 0($tp1,$tp1),$tp2 + sub $tp4,$acc + and \$0xfefefefe,$tp2 + and \$0x1b1b1b1b,$acc + xor $tp2,$acc + mov $acc,$tp2 + + and \$0x80808080,$acc + mov $acc,$tp8 + shr \$7,$tp8 + lea 0($tp2,$tp2),$tp4 + sub $tp8,$acc + and \$0xfefefefe,$tp4 + and \$0x1b1b1b1b,$acc + xor $tp1,$tp2 # tp2^tp1 + xor $tp4,$acc + mov $acc,$tp4 + + and \$0x80808080,$acc + mov $acc,$tp8 + shr \$7,$tp8 + sub $tp8,$acc + lea 0($tp4,$tp4),$tp8 + xor $tp1,$tp4 # tp4^tp1 + and \$0xfefefefe,$tp8 + and \$0x1b1b1b1b,$acc + xor $acc,$tp8 + + xor $tp8,$tp1 # tp1^tp8 + rol \$8,$tp1 # ROTATE(tp1^tp8,8) + xor $tp8,$tp2 # tp2^tp1^tp8 + xor $tp8,$tp4 # tp4^tp1^tp8 + xor $tp2,$tp8 + xor $tp4,$tp8 # tp8^(tp8^tp4^tp1)^(tp8^tp2^tp1)=tp8^tp4^tp2 + + xor $tp8,$tp1 + rol \$24,$tp2 # ROTATE(tp2^tp1^tp8,24) + xor $tp2,$tp1 + rol \$16,$tp4 # ROTATE(tp4^tp1^tp8,16) + xor $tp4,$tp1 + + mov $tp1,$i($ptr) +___ +} + +# int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits, +# AES_KEY *key) +$code.=<<___; +.globl private_AES_set_decrypt_key +.type private_AES_set_decrypt_key,\@function,3 +.align 16 +private_AES_set_decrypt_key: + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + push %rdx # save key schedule +.Ldec_key_prologue: + + call _x86_64_AES_set_encrypt_key + mov (%rsp),%r8 # restore key schedule + cmp \$0,%eax + jne .Labort + + mov 240(%r8),%r14d # pull number of rounds + xor %rdi,%rdi + lea (%rdi,%r14d,4),%rcx + mov %r8,%rsi + lea (%r8,%rcx,4),%rdi # pointer to last chunk +.align 4 +.Linvert: + mov 0(%rsi),%rax + mov 8(%rsi),%rbx + mov 0(%rdi),%rcx + mov 8(%rdi),%rdx + mov %rax,0(%rdi) + mov %rbx,8(%rdi) + mov %rcx,0(%rsi) + mov %rdx,8(%rsi) + lea 16(%rsi),%rsi + lea -16(%rdi),%rdi + cmp %rsi,%rdi + jne .Linvert + + lea .LAES_Te+2048+1024(%rip),%rax # rcon + + mov 40(%rax),$mask80 + mov 48(%rax),$maskfe + mov 56(%rax),$mask1b + + mov %r8,$key + sub \$1,%r14d +.align 4 +.Lpermute: + lea 16($key),$key + mov 0($key),%rax + mov 8($key),%rcx +___ + &dectransform (); +$code.=<<___; + mov %eax,0($key) + mov %ebx,4($key) + mov %ecx,8($key) + mov %edx,12($key) + sub \$1,%r14d + jnz .Lpermute + + xor %rax,%rax +.Labort: + mov 8(%rsp),%r15 + mov 16(%rsp),%r14 + mov 24(%rsp),%r13 + mov 32(%rsp),%r12 + mov 40(%rsp),%rbp + mov 48(%rsp),%rbx + add \$56,%rsp +.Ldec_key_epilogue: + ret +.size private_AES_set_decrypt_key,.-private_AES_set_decrypt_key +___ + +# void AES_cbc_encrypt (const void char *inp, unsigned char *out, +# size_t length, const AES_KEY *key, +# unsigned char *ivp,const int enc); +{ +# stack frame layout +# -8(%rsp) return address +my $keyp="0(%rsp)"; # one to pass as $key +my $keyend="8(%rsp)"; # &(keyp->rd_key[4*keyp->rounds]) +my $_rsp="16(%rsp)"; # saved %rsp +my $_inp="24(%rsp)"; # copy of 1st parameter, inp +my $_out="32(%rsp)"; # copy of 2nd parameter, out +my $_len="40(%rsp)"; # copy of 3rd parameter, length +my $_key="48(%rsp)"; # copy of 4th parameter, key +my $_ivp="56(%rsp)"; # copy of 5th parameter, ivp +my $ivec="64(%rsp)"; # ivec[16] +my $aes_key="80(%rsp)"; # copy of aes_key +my $mark="80+240(%rsp)"; # copy of aes_key->rounds + +$code.=<<___; +.globl AES_cbc_encrypt +.type AES_cbc_encrypt,\@function,6 +.align 16 +.extern OPENSSL_ia32cap_P +.globl asm_AES_cbc_encrypt +.hidden asm_AES_cbc_encrypt +asm_AES_cbc_encrypt: +AES_cbc_encrypt: + cmp \$0,%rdx # check length + je .Lcbc_epilogue + pushfq + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 +.Lcbc_prologue: + + cld + mov %r9d,%r9d # clear upper half of enc + + lea .LAES_Te(%rip),$sbox + cmp \$0,%r9 + jne .Lcbc_picked_te + lea .LAES_Td(%rip),$sbox +.Lcbc_picked_te: + + mov OPENSSL_ia32cap_P(%rip),%r10d + cmp \$$speed_limit,%rdx + jb .Lcbc_slow_prologue + test \$15,%rdx + jnz .Lcbc_slow_prologue + bt \$28,%r10d + jc .Lcbc_slow_prologue + + # allocate aligned stack frame... + lea -88-248(%rsp),$key + and \$-64,$key + + # ... and make sure it doesn't alias with AES_T[ed] modulo 4096 + mov $sbox,%r10 + lea 2304($sbox),%r11 + mov $key,%r12 + and \$0xFFF,%r10 # s = $sbox&0xfff + and \$0xFFF,%r11 # e = ($sbox+2048)&0xfff + and \$0xFFF,%r12 # p = %rsp&0xfff + + cmp %r11,%r12 # if (p=>e) %rsp =- (p-e); + jb .Lcbc_te_break_out + sub %r11,%r12 + sub %r12,$key + jmp .Lcbc_te_ok +.Lcbc_te_break_out: # else %rsp -= (p-s)&0xfff + framesz + sub %r10,%r12 + and \$0xFFF,%r12 + add \$320,%r12 + sub %r12,$key +.align 4 +.Lcbc_te_ok: + + xchg %rsp,$key + #add \$8,%rsp # reserve for return address! + mov $key,$_rsp # save %rsp +.Lcbc_fast_body: + mov %rdi,$_inp # save copy of inp + mov %rsi,$_out # save copy of out + mov %rdx,$_len # save copy of len + mov %rcx,$_key # save copy of key + mov %r8,$_ivp # save copy of ivp + movl \$0,$mark # copy of aes_key->rounds = 0; + mov %r8,%rbp # rearrange input arguments + mov %r9,%rbx + mov %rsi,$out + mov %rdi,$inp + mov %rcx,$key + + mov 240($key),%eax # key->rounds + # do we copy key schedule to stack? + mov $key,%r10 + sub $sbox,%r10 + and \$0xfff,%r10 + cmp \$2304,%r10 + jb .Lcbc_do_ecopy + cmp \$4096-248,%r10 + jb .Lcbc_skip_ecopy +.align 4 +.Lcbc_do_ecopy: + mov $key,%rsi + lea $aes_key,%rdi + lea $aes_key,$key + mov \$240/8,%ecx + .long 0x90A548F3 # rep movsq + mov %eax,(%rdi) # copy aes_key->rounds +.Lcbc_skip_ecopy: + mov $key,$keyp # save key pointer + + mov \$18,%ecx +.align 4 +.Lcbc_prefetch_te: + mov 0($sbox),%r10 + mov 32($sbox),%r11 + mov 64($sbox),%r12 + mov 96($sbox),%r13 + lea 128($sbox),$sbox + sub \$1,%ecx + jnz .Lcbc_prefetch_te + lea -2304($sbox),$sbox + + cmp \$0,%rbx + je .LFAST_DECRYPT + +#----------------------------- ENCRYPT -----------------------------# + mov 0(%rbp),$s0 # load iv + mov 4(%rbp),$s1 + mov 8(%rbp),$s2 + mov 12(%rbp),$s3 + +.align 4 +.Lcbc_fast_enc_loop: + xor 0($inp),$s0 + xor 4($inp),$s1 + xor 8($inp),$s2 + xor 12($inp),$s3 + mov $keyp,$key # restore key + mov $inp,$_inp # if ($verticalspin) save inp + + call _x86_64_AES_encrypt + + mov $_inp,$inp # if ($verticalspin) restore inp + mov $_len,%r10 + mov $s0,0($out) + mov $s1,4($out) + mov $s2,8($out) + mov $s3,12($out) + + lea 16($inp),$inp + lea 16($out),$out + sub \$16,%r10 + test \$-16,%r10 + mov %r10,$_len + jnz .Lcbc_fast_enc_loop + mov $_ivp,%rbp # restore ivp + mov $s0,0(%rbp) # save ivec + mov $s1,4(%rbp) + mov $s2,8(%rbp) + mov $s3,12(%rbp) + + jmp .Lcbc_fast_cleanup + +#----------------------------- DECRYPT -----------------------------# +.align 16 +.LFAST_DECRYPT: + cmp $inp,$out + je .Lcbc_fast_dec_in_place + + mov %rbp,$ivec +.align 4 +.Lcbc_fast_dec_loop: + mov 0($inp),$s0 # read input + mov 4($inp),$s1 + mov 8($inp),$s2 + mov 12($inp),$s3 + mov $keyp,$key # restore key + mov $inp,$_inp # if ($verticalspin) save inp + + call _x86_64_AES_decrypt + + mov $ivec,%rbp # load ivp + mov $_inp,$inp # if ($verticalspin) restore inp + mov $_len,%r10 # load len + xor 0(%rbp),$s0 # xor iv + xor 4(%rbp),$s1 + xor 8(%rbp),$s2 + xor 12(%rbp),$s3 + mov $inp,%rbp # current input, next iv + + sub \$16,%r10 + mov %r10,$_len # update len + mov %rbp,$ivec # update ivp + + mov $s0,0($out) # write output + mov $s1,4($out) + mov $s2,8($out) + mov $s3,12($out) + + lea 16($inp),$inp + lea 16($out),$out + jnz .Lcbc_fast_dec_loop + mov $_ivp,%r12 # load user ivp + mov 0(%rbp),%r10 # load iv + mov 8(%rbp),%r11 + mov %r10,0(%r12) # copy back to user + mov %r11,8(%r12) + jmp .Lcbc_fast_cleanup + +.align 16 +.Lcbc_fast_dec_in_place: + mov 0(%rbp),%r10 # copy iv to stack + mov 8(%rbp),%r11 + mov %r10,0+$ivec + mov %r11,8+$ivec +.align 4 +.Lcbc_fast_dec_in_place_loop: + mov 0($inp),$s0 # load input + mov 4($inp),$s1 + mov 8($inp),$s2 + mov 12($inp),$s3 + mov $keyp,$key # restore key + mov $inp,$_inp # if ($verticalspin) save inp + + call _x86_64_AES_decrypt + + mov $_inp,$inp # if ($verticalspin) restore inp + mov $_len,%r10 + xor 0+$ivec,$s0 + xor 4+$ivec,$s1 + xor 8+$ivec,$s2 + xor 12+$ivec,$s3 + + mov 0($inp),%r11 # load input + mov 8($inp),%r12 + sub \$16,%r10 + jz .Lcbc_fast_dec_in_place_done + + mov %r11,0+$ivec # copy input to iv + mov %r12,8+$ivec + + mov $s0,0($out) # save output [zaps input] + mov $s1,4($out) + mov $s2,8($out) + mov $s3,12($out) + + lea 16($inp),$inp + lea 16($out),$out + mov %r10,$_len + jmp .Lcbc_fast_dec_in_place_loop +.Lcbc_fast_dec_in_place_done: + mov $_ivp,%rdi + mov %r11,0(%rdi) # copy iv back to user + mov %r12,8(%rdi) + + mov $s0,0($out) # save output [zaps input] + mov $s1,4($out) + mov $s2,8($out) + mov $s3,12($out) + +.align 4 +.Lcbc_fast_cleanup: + cmpl \$0,$mark # was the key schedule copied? + lea $aes_key,%rdi + je .Lcbc_exit + mov \$240/8,%ecx + xor %rax,%rax + .long 0x90AB48F3 # rep stosq + + jmp .Lcbc_exit + +#--------------------------- SLOW ROUTINE ---------------------------# +.align 16 +.Lcbc_slow_prologue: + # allocate aligned stack frame... + lea -88(%rsp),%rbp + and \$-64,%rbp + # ... just "above" key schedule + lea -88-63(%rcx),%r10 + sub %rbp,%r10 + neg %r10 + and \$0x3c0,%r10 + sub %r10,%rbp + + xchg %rsp,%rbp + #add \$8,%rsp # reserve for return address! + mov %rbp,$_rsp # save %rsp +.Lcbc_slow_body: + #mov %rdi,$_inp # save copy of inp + #mov %rsi,$_out # save copy of out + #mov %rdx,$_len # save copy of len + #mov %rcx,$_key # save copy of key + mov %r8,$_ivp # save copy of ivp + mov %r8,%rbp # rearrange input arguments + mov %r9,%rbx + mov %rsi,$out + mov %rdi,$inp + mov %rcx,$key + mov %rdx,%r10 + + mov 240($key),%eax + mov $key,$keyp # save key pointer + shl \$4,%eax + lea ($key,%rax),%rax + mov %rax,$keyend + + # pick Te4 copy which can't "overlap" with stack frame or key scdedule + lea 2048($sbox),$sbox + lea 768-8(%rsp),%rax + sub $sbox,%rax + and \$0x300,%rax + lea ($sbox,%rax),$sbox + + cmp \$0,%rbx + je .LSLOW_DECRYPT + +#--------------------------- SLOW ENCRYPT ---------------------------# + test \$-16,%r10 # check upon length + mov 0(%rbp),$s0 # load iv + mov 4(%rbp),$s1 + mov 8(%rbp),$s2 + mov 12(%rbp),$s3 + jz .Lcbc_slow_enc_tail # short input... + +.align 4 +.Lcbc_slow_enc_loop: + xor 0($inp),$s0 + xor 4($inp),$s1 + xor 8($inp),$s2 + xor 12($inp),$s3 + mov $keyp,$key # restore key + mov $inp,$_inp # save inp + mov $out,$_out # save out + mov %r10,$_len # save len + + call _x86_64_AES_encrypt_compact + + mov $_inp,$inp # restore inp + mov $_out,$out # restore out + mov $_len,%r10 # restore len + mov $s0,0($out) + mov $s1,4($out) + mov $s2,8($out) + mov $s3,12($out) + + lea 16($inp),$inp + lea 16($out),$out + sub \$16,%r10 + test \$-16,%r10 + jnz .Lcbc_slow_enc_loop + test \$15,%r10 + jnz .Lcbc_slow_enc_tail + mov $_ivp,%rbp # restore ivp + mov $s0,0(%rbp) # save ivec + mov $s1,4(%rbp) + mov $s2,8(%rbp) + mov $s3,12(%rbp) + + jmp .Lcbc_exit + +.align 4 +.Lcbc_slow_enc_tail: + mov %rax,%r11 + mov %rcx,%r12 + mov %r10,%rcx + mov $inp,%rsi + mov $out,%rdi + .long 0x9066A4F3 # rep movsb + mov \$16,%rcx # zero tail + sub %r10,%rcx + xor %rax,%rax + .long 0x9066AAF3 # rep stosb + mov $out,$inp # this is not a mistake! + mov \$16,%r10 # len=16 + mov %r11,%rax + mov %r12,%rcx + jmp .Lcbc_slow_enc_loop # one more spin... +#--------------------------- SLOW DECRYPT ---------------------------# +.align 16 +.LSLOW_DECRYPT: + shr \$3,%rax + add %rax,$sbox # recall "magic" constants! + + mov 0(%rbp),%r11 # copy iv to stack + mov 8(%rbp),%r12 + mov %r11,0+$ivec + mov %r12,8+$ivec + +.align 4 +.Lcbc_slow_dec_loop: + mov 0($inp),$s0 # load input + mov 4($inp),$s1 + mov 8($inp),$s2 + mov 12($inp),$s3 + mov $keyp,$key # restore key + mov $inp,$_inp # save inp + mov $out,$_out # save out + mov %r10,$_len # save len + + call _x86_64_AES_decrypt_compact + + mov $_inp,$inp # restore inp + mov $_out,$out # restore out + mov $_len,%r10 + xor 0+$ivec,$s0 + xor 4+$ivec,$s1 + xor 8+$ivec,$s2 + xor 12+$ivec,$s3 + + mov 0($inp),%r11 # load input + mov 8($inp),%r12 + sub \$16,%r10 + jc .Lcbc_slow_dec_partial + jz .Lcbc_slow_dec_done + + mov %r11,0+$ivec # copy input to iv + mov %r12,8+$ivec + + mov $s0,0($out) # save output [can zap input] + mov $s1,4($out) + mov $s2,8($out) + mov $s3,12($out) + + lea 16($inp),$inp + lea 16($out),$out + jmp .Lcbc_slow_dec_loop +.Lcbc_slow_dec_done: + mov $_ivp,%rdi + mov %r11,0(%rdi) # copy iv back to user + mov %r12,8(%rdi) + + mov $s0,0($out) # save output [can zap input] + mov $s1,4($out) + mov $s2,8($out) + mov $s3,12($out) + + jmp .Lcbc_exit + +.align 4 +.Lcbc_slow_dec_partial: + mov $_ivp,%rdi + mov %r11,0(%rdi) # copy iv back to user + mov %r12,8(%rdi) + + mov $s0,0+$ivec # save output to stack + mov $s1,4+$ivec + mov $s2,8+$ivec + mov $s3,12+$ivec + + mov $out,%rdi + lea $ivec,%rsi + lea 16(%r10),%rcx + .long 0x9066A4F3 # rep movsb + jmp .Lcbc_exit + +.align 16 +.Lcbc_exit: + mov $_rsp,%rsi + mov (%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 + mov 24(%rsi),%r12 + mov 32(%rsi),%rbp + mov 40(%rsi),%rbx + lea 48(%rsi),%rsp +.Lcbc_popfq: + popfq +.Lcbc_epilogue: + ret +.size AES_cbc_encrypt,.-AES_cbc_encrypt +___ +} + +$code.=<<___; +.align 64 +.LAES_Te: +___ + &_data_word(0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6); + &_data_word(0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591); + &_data_word(0x50303060, 0x03010102, 0xa96767ce, 0x7d2b2b56); + &_data_word(0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec); + &_data_word(0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa); + &_data_word(0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb); + &_data_word(0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45); + &_data_word(0xbf9c9c23, 0xf7a4a453, 0x967272e4, 0x5bc0c09b); + &_data_word(0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c); + &_data_word(0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83); + &_data_word(0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9); + &_data_word(0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a); + &_data_word(0x0c040408, 0x52c7c795, 0x65232346, 0x5ec3c39d); + &_data_word(0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f); + &_data_word(0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df); + &_data_word(0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea); + &_data_word(0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34); + &_data_word(0x2d1b1b36, 0xb26e6edc, 0xee5a5ab4, 0xfba0a05b); + &_data_word(0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d); + &_data_word(0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413); + &_data_word(0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1); + &_data_word(0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6); + &_data_word(0xbe6a6ad4, 0x46cbcb8d, 0xd9bebe67, 0x4b393972); + &_data_word(0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85); + &_data_word(0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed); + &_data_word(0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511); + &_data_word(0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe); + &_data_word(0xf05050a0, 0x443c3c78, 0xba9f9f25, 0xe3a8a84b); + &_data_word(0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05); + &_data_word(0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1); + &_data_word(0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142); + &_data_word(0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf); + &_data_word(0x4ccdcd81, 0x140c0c18, 0x35131326, 0x2fececc3); + &_data_word(0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e); + &_data_word(0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a); + &_data_word(0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6); + &_data_word(0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3); + &_data_word(0x66222244, 0x7e2a2a54, 0xab90903b, 0x8388880b); + &_data_word(0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428); + &_data_word(0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad); + &_data_word(0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14); + &_data_word(0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8); + &_data_word(0x5dc2c29f, 0x6ed3d3bd, 0xefacac43, 0xa66262c4); + &_data_word(0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2); + &_data_word(0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda); + &_data_word(0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949); + &_data_word(0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf); + &_data_word(0xaf6565ca, 0x8e7a7af4, 0xe9aeae47, 0x18080810); + &_data_word(0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c); + &_data_word(0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697); + &_data_word(0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e); + &_data_word(0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f); + &_data_word(0x907070e0, 0x423e3e7c, 0xc4b5b571, 0xaa6666cc); + &_data_word(0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c); + &_data_word(0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969); + &_data_word(0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27); + &_data_word(0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122); + &_data_word(0xbb6969d2, 0x70d9d9a9, 0x898e8e07, 0xa7949433); + &_data_word(0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9); + &_data_word(0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5); + &_data_word(0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a); + &_data_word(0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0); + &_data_word(0xc3414182, 0xb0999929, 0x772d2d5a, 0x110f0f1e); + &_data_word(0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c); + +#Te4 # four copies of Te4 to choose from to avoid L1 aliasing + &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5); + &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76); + &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0); + &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0); + &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc); + &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15); + &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a); + &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75); + &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0); + &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84); + &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b); + &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf); + &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85); + &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8); + &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5); + &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2); + &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17); + &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73); + &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88); + &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb); + &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c); + &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79); + &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9); + &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08); + &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6); + &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a); + &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e); + &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e); + &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94); + &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf); + &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68); + &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16); + + &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5); + &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76); + &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0); + &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0); + &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc); + &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15); + &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a); + &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75); + &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0); + &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84); + &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b); + &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf); + &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85); + &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8); + &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5); + &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2); + &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17); + &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73); + &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88); + &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb); + &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c); + &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79); + &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9); + &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08); + &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6); + &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a); + &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e); + &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e); + &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94); + &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf); + &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68); + &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16); + + &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5); + &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76); + &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0); + &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0); + &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc); + &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15); + &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a); + &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75); + &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0); + &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84); + &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b); + &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf); + &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85); + &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8); + &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5); + &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2); + &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17); + &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73); + &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88); + &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb); + &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c); + &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79); + &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9); + &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08); + &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6); + &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a); + &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e); + &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e); + &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94); + &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf); + &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68); + &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16); + + &data_byte(0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5); + &data_byte(0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76); + &data_byte(0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0); + &data_byte(0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0); + &data_byte(0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc); + &data_byte(0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15); + &data_byte(0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a); + &data_byte(0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75); + &data_byte(0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0); + &data_byte(0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84); + &data_byte(0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b); + &data_byte(0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf); + &data_byte(0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85); + &data_byte(0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8); + &data_byte(0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5); + &data_byte(0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2); + &data_byte(0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17); + &data_byte(0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73); + &data_byte(0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88); + &data_byte(0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb); + &data_byte(0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c); + &data_byte(0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79); + &data_byte(0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9); + &data_byte(0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08); + &data_byte(0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6); + &data_byte(0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a); + &data_byte(0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e); + &data_byte(0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e); + &data_byte(0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94); + &data_byte(0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf); + &data_byte(0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68); + &data_byte(0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16); +#rcon: +$code.=<<___; + .long 0x00000001, 0x00000002, 0x00000004, 0x00000008 + .long 0x00000010, 0x00000020, 0x00000040, 0x00000080 + .long 0x0000001b, 0x00000036, 0x80808080, 0x80808080 + .long 0xfefefefe, 0xfefefefe, 0x1b1b1b1b, 0x1b1b1b1b +___ +$code.=<<___; +.align 64 +.LAES_Td: +___ + &_data_word(0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a); + &_data_word(0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b); + &_data_word(0x55fa3020, 0xf66d76ad, 0x9176cc88, 0x254c02f5); + &_data_word(0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5); + &_data_word(0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d); + &_data_word(0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b); + &_data_word(0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295); + &_data_word(0x2d83bed4, 0xd3217458, 0x2969e049, 0x44c8c98e); + &_data_word(0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927); + &_data_word(0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d); + &_data_word(0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362); + &_data_word(0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9); + &_data_word(0x58684870, 0x19fd458f, 0x876cde94, 0xb7f87b52); + &_data_word(0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566); + &_data_word(0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3); + &_data_word(0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed); + &_data_word(0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e); + &_data_word(0xcdf4da65, 0xd5be0506, 0x1f6234d1, 0x8afea6c4); + &_data_word(0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4); + &_data_word(0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd); + &_data_word(0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d); + &_data_word(0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060); + &_data_word(0x24fb9819, 0x97e9bdd6, 0xcc434089, 0x779ed967); + &_data_word(0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879); + &_data_word(0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000); + &_data_word(0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c); + &_data_word(0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36); + &_data_word(0x64d90f0a, 0x21a65c68, 0xd1545b9b, 0x3a2e3624); + &_data_word(0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b); + &_data_word(0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c); + &_data_word(0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12); + &_data_word(0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14); + &_data_word(0x8519f157, 0x4c0775af, 0xbbdd99ee, 0xfd607fa3); + &_data_word(0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b); + &_data_word(0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8); + &_data_word(0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684); + &_data_word(0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7); + &_data_word(0x4b2f9e1d, 0xf330b2dc, 0xec52860d, 0xd0e3c177); + &_data_word(0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947); + &_data_word(0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322); + &_data_word(0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498); + &_data_word(0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f); + &_data_word(0xe49d3a2c, 0x0d927850, 0x9bcc5f6a, 0x62467e54); + &_data_word(0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382); + &_data_word(0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf); + &_data_word(0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb); + &_data_word(0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83); + &_data_word(0x656e95e6, 0x7ee6ffaa, 0x08cfbc21, 0xe6e815ef); + &_data_word(0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029); + &_data_word(0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235); + &_data_word(0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733); + &_data_word(0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117); + &_data_word(0x8dd64d76, 0x4db0ef43, 0x544daacc, 0xdf0496e4); + &_data_word(0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546); + &_data_word(0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb); + &_data_word(0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d); + &_data_word(0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb); + &_data_word(0xee27a9ce, 0x35c961b7, 0xede51ce1, 0x3cb1477a); + &_data_word(0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773); + &_data_word(0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478); + &_data_word(0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2); + &_data_word(0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff); + &_data_word(0x7101a839, 0xdeb30c08, 0x9ce4b4d8, 0x90c15664); + &_data_word(0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0); + +#Td4: # four copies of Td4 to choose from to avoid L1 aliasing + &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); + &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); + &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); + &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb); + &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d); + &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e); + &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2); + &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25); + &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16); + &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92); + &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda); + &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84); + &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a); + &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06); + &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02); + &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b); + &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea); + &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73); + &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85); + &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e); + &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89); + &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b); + &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20); + &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4); + &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31); + &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f); + &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d); + &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef); + &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0); + &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); + &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); + &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); +$code.=<<___; + .long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe + .long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0 +___ + &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); + &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); + &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); + &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb); + &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d); + &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e); + &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2); + &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25); + &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16); + &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92); + &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda); + &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84); + &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a); + &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06); + &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02); + &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b); + &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea); + &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73); + &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85); + &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e); + &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89); + &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b); + &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20); + &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4); + &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31); + &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f); + &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d); + &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef); + &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0); + &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); + &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); + &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); +$code.=<<___; + .long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe + .long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0 +___ + &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); + &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); + &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); + &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb); + &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d); + &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e); + &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2); + &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25); + &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16); + &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92); + &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda); + &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84); + &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a); + &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06); + &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02); + &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b); + &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea); + &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73); + &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85); + &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e); + &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89); + &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b); + &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20); + &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4); + &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31); + &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f); + &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d); + &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef); + &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0); + &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); + &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); + &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); +$code.=<<___; + .long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe + .long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0 +___ + &data_byte(0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38); + &data_byte(0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb); + &data_byte(0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87); + &data_byte(0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb); + &data_byte(0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d); + &data_byte(0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e); + &data_byte(0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2); + &data_byte(0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25); + &data_byte(0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16); + &data_byte(0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92); + &data_byte(0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda); + &data_byte(0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84); + &data_byte(0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a); + &data_byte(0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06); + &data_byte(0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02); + &data_byte(0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b); + &data_byte(0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea); + &data_byte(0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73); + &data_byte(0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85); + &data_byte(0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e); + &data_byte(0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89); + &data_byte(0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b); + &data_byte(0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20); + &data_byte(0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4); + &data_byte(0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31); + &data_byte(0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f); + &data_byte(0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d); + &data_byte(0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef); + &data_byte(0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0); + &data_byte(0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61); + &data_byte(0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26); + &data_byte(0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d); +$code.=<<___; + .long 0x80808080, 0x80808080, 0xfefefefe, 0xfefefefe + .long 0x1b1b1b1b, 0x1b1b1b1b, 0, 0 +.asciz "AES for x86_64, CRYPTOGAMS by " +.align 64 +___ + +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type block_se_handler,\@abi-omnipotent +.align 16 +block_se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + mov 8($disp),%rsi # disp->ImageBase + mov 56($disp),%r11 # disp->HandlerData + + mov 0(%r11),%r10d # HandlerData[0] + lea (%rsi,%r10),%r10 # prologue label + cmp %r10,%rbx # context->RipRsp + + mov 4(%r11),%r10d # HandlerData[1] + lea (%rsi,%r10),%r10 # epilogue label + cmp %r10,%rbx # context->Rip>=epilogue label + jae .Lin_block_prologue + + mov 24(%rax),%rax # pull saved real stack pointer + lea 48(%rax),%rax # adjust... + + mov -8(%rax),%rbx + mov -16(%rax),%rbp + mov -24(%rax),%r12 + mov -32(%rax),%r13 + mov -40(%rax),%r14 + mov -48(%rax),%r15 + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + +.Lin_block_prologue: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + jmp .Lcommon_seh_exit +.size block_se_handler,.-block_se_handler + +.type key_se_handler,\@abi-omnipotent +.align 16 +key_se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + mov 8($disp),%rsi # disp->ImageBase + mov 56($disp),%r11 # disp->HandlerData + + mov 0(%r11),%r10d # HandlerData[0] + lea (%rsi,%r10),%r10 # prologue label + cmp %r10,%rbx # context->RipRsp + + mov 4(%r11),%r10d # HandlerData[1] + lea (%rsi,%r10),%r10 # epilogue label + cmp %r10,%rbx # context->Rip>=epilogue label + jae .Lin_key_prologue + + lea 56(%rax),%rax + + mov -8(%rax),%rbx + mov -16(%rax),%rbp + mov -24(%rax),%r12 + mov -32(%rax),%r13 + mov -40(%rax),%r14 + mov -48(%rax),%r15 + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + +.Lin_key_prologue: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + jmp .Lcommon_seh_exit +.size key_se_handler,.-key_se_handler + +.type cbc_se_handler,\@abi-omnipotent +.align 16 +cbc_se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + lea .Lcbc_prologue(%rip),%r10 + cmp %r10,%rbx # context->Rip<.Lcbc_prologue + jb .Lin_cbc_prologue + + lea .Lcbc_fast_body(%rip),%r10 + cmp %r10,%rbx # context->Rip<.Lcbc_fast_body + jb .Lin_cbc_frame_setup + + lea .Lcbc_slow_prologue(%rip),%r10 + cmp %r10,%rbx # context->Rip<.Lcbc_slow_prologue + jb .Lin_cbc_body + + lea .Lcbc_slow_body(%rip),%r10 + cmp %r10,%rbx # context->Rip<.Lcbc_slow_body + jb .Lin_cbc_frame_setup + +.Lin_cbc_body: + mov 152($context),%rax # pull context->Rsp + + lea .Lcbc_epilogue(%rip),%r10 + cmp %r10,%rbx # context->Rip>=.Lcbc_epilogue + jae .Lin_cbc_prologue + + lea 8(%rax),%rax + + lea .Lcbc_popfq(%rip),%r10 + cmp %r10,%rbx # context->Rip>=.Lcbc_popfq + jae .Lin_cbc_prologue + + mov `16-8`(%rax),%rax # biased $_rsp + lea 56(%rax),%rax + +.Lin_cbc_frame_setup: + mov -16(%rax),%rbx + mov -24(%rax),%rbp + mov -32(%rax),%r12 + mov -40(%rax),%r13 + mov -48(%rax),%r14 + mov -56(%rax),%r15 + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + +.Lin_cbc_prologue: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + +.Lcommon_seh_exit: + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$`1232/8`,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size cbc_se_handler,.-cbc_se_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_AES_encrypt + .rva .LSEH_end_AES_encrypt + .rva .LSEH_info_AES_encrypt + + .rva .LSEH_begin_AES_decrypt + .rva .LSEH_end_AES_decrypt + .rva .LSEH_info_AES_decrypt + + .rva .LSEH_begin_private_AES_set_encrypt_key + .rva .LSEH_end_private_AES_set_encrypt_key + .rva .LSEH_info_private_AES_set_encrypt_key + + .rva .LSEH_begin_private_AES_set_decrypt_key + .rva .LSEH_end_private_AES_set_decrypt_key + .rva .LSEH_info_private_AES_set_decrypt_key + + .rva .LSEH_begin_AES_cbc_encrypt + .rva .LSEH_end_AES_cbc_encrypt + .rva .LSEH_info_AES_cbc_encrypt + +.section .xdata +.align 8 +.LSEH_info_AES_encrypt: + .byte 9,0,0,0 + .rva block_se_handler + .rva .Lenc_prologue,.Lenc_epilogue # HandlerData[] +.LSEH_info_AES_decrypt: + .byte 9,0,0,0 + .rva block_se_handler + .rva .Ldec_prologue,.Ldec_epilogue # HandlerData[] +.LSEH_info_private_AES_set_encrypt_key: + .byte 9,0,0,0 + .rva key_se_handler + .rva .Lenc_key_prologue,.Lenc_key_epilogue # HandlerData[] +.LSEH_info_private_AES_set_decrypt_key: + .byte 9,0,0,0 + .rva key_se_handler + .rva .Ldec_key_prologue,.Ldec_key_epilogue # HandlerData[] +.LSEH_info_AES_cbc_encrypt: + .byte 9,0,0,0 + .rva cbc_se_handler +___ +} + +$code =~ s/\`([^\`]*)\`/eval($1)/gem; + +print $code; + +close STDOUT; diff --git a/libs/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl b/libs/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl new file mode 100644 index 00000000..3c8f6c19 --- /dev/null +++ b/libs/openssl/crypto/aes/asm/aesni-sha1-x86_64.pl @@ -0,0 +1,1250 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# June 2011 +# +# This is AESNI-CBC+SHA1 "stitch" implementation. The idea, as spelled +# in http://download.intel.com/design/intarch/papers/323686.pdf, is +# that since AESNI-CBC encrypt exhibit *very* low instruction-level +# parallelism, interleaving it with another algorithm would allow to +# utilize processor resources better and achieve better performance. +# SHA1 instruction sequences(*) are taken from sha1-x86_64.pl and +# AESNI code is weaved into it. Below are performance numbers in +# cycles per processed byte, less is better, for standalone AESNI-CBC +# encrypt, sum of the latter and standalone SHA1, and "stitched" +# subroutine: +# +# AES-128-CBC +SHA1 stitch gain +# Westmere 3.77[+5.6] 9.37 6.65 +41% +# Sandy Bridge 5.05[+5.2(6.3)] 10.25(11.35) 6.16(7.08) +67%(+60%) +# +# AES-192-CBC +# Westmere 4.51 10.11 6.97 +45% +# Sandy Bridge 6.05 11.25(12.35) 6.34(7.27) +77%(+70%) +# +# AES-256-CBC +# Westmere 5.25 10.85 7.25 +50% +# Sandy Bridge 7.05 12.25(13.35) 7.06(7.70) +74%(+73%) +# +# (*) There are two code paths: SSSE3 and AVX. See sha1-568.pl for +# background information. Above numbers in parentheses are SSSE3 +# results collected on AVX-capable CPU, i.e. apply on OSes that +# don't support AVX. +# +# Needless to mention that it makes no sense to implement "stitched" +# *decrypt* subroutine. Because *both* AESNI-CBC decrypt and SHA1 +# fully utilize parallelism, so stitching would not give any gain +# anyway. Well, there might be some, e.g. because of better cache +# locality... For reference, here are performance results for +# standalone AESNI-CBC decrypt: +# +# AES-128-CBC AES-192-CBC AES-256-CBC +# Westmere 1.31 1.55 1.80 +# Sandy Bridge 0.93 1.06 1.22 + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +$avx=1 if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` + =~ /GNU assembler version ([2-9]\.[0-9]+)/ && + $1>=2.19); +$avx=1 if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) && + `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ && + $1>=2.09); +$avx=1 if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && + `ml64 2>&1` =~ /Version ([0-9]+)\./ && + $1>=10); + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +# void aesni_cbc_sha1_enc(const void *inp, +# void *out, +# size_t length, +# const AES_KEY *key, +# unsigned char *iv, +# SHA_CTX *ctx, +# const void *in0); + +$code.=<<___; +.text +.extern OPENSSL_ia32cap_P + +.globl aesni_cbc_sha1_enc +.type aesni_cbc_sha1_enc,\@abi-omnipotent +.align 16 +aesni_cbc_sha1_enc: + # caller should check for SSSE3 and AES-NI bits + mov OPENSSL_ia32cap_P+0(%rip),%r10d + mov OPENSSL_ia32cap_P+4(%rip),%r11d +___ +$code.=<<___ if ($avx); + and \$`1<<28`,%r11d # mask AVX bit + and \$`1<<30`,%r10d # mask "Intel CPU" bit + or %r11d,%r10d + cmp \$`1<<28|1<<30`,%r10d + je aesni_cbc_sha1_enc_avx +___ +$code.=<<___; + jmp aesni_cbc_sha1_enc_ssse3 + ret +.size aesni_cbc_sha1_enc,.-aesni_cbc_sha1_enc +___ + +my ($in0,$out,$len,$key,$ivp,$ctx,$inp)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9","%r10"); + +my $Xi=4; +my @X=map("%xmm$_",(4..7,0..3)); +my @Tx=map("%xmm$_",(8..10)); +my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp"); # size optimization +my @T=("%esi","%edi"); +my $j=0; my $jj=0; my $r=0; my $sn=0; +my $K_XX_XX="%r11"; +my ($iv,$in,$rndkey0)=map("%xmm$_",(11..13)); +my @rndkey=("%xmm14","%xmm15"); + +sub AUTOLOAD() # thunk [simplified] 32-bit style perlasm +{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; + my $arg = pop; + $arg = "\$$arg" if ($arg*1 eq $arg); + $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n"; +} + +my $_rol=sub { &rol(@_) }; +my $_ror=sub { &ror(@_) }; + +$code.=<<___; +.type aesni_cbc_sha1_enc_ssse3,\@function,6 +.align 16 +aesni_cbc_sha1_enc_ssse3: + mov `($win64?56:8)`(%rsp),$inp # load 7th argument + #shr \$6,$len # debugging artefact + #jz .Lepilogue_ssse3 # debugging artefact + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + lea `-104-($win64?10*16:0)`(%rsp),%rsp + #mov $in0,$inp # debugging artefact + #lea 64(%rsp),$ctx # debugging artefact +___ +$code.=<<___ if ($win64); + movaps %xmm6,96+0(%rsp) + movaps %xmm7,96+16(%rsp) + movaps %xmm8,96+32(%rsp) + movaps %xmm9,96+48(%rsp) + movaps %xmm10,96+64(%rsp) + movaps %xmm11,96+80(%rsp) + movaps %xmm12,96+96(%rsp) + movaps %xmm13,96+112(%rsp) + movaps %xmm14,96+128(%rsp) + movaps %xmm15,96+144(%rsp) +.Lprologue_ssse3: +___ +$code.=<<___; + mov $in0,%r12 # reassign arguments + mov $out,%r13 + mov $len,%r14 + mov $key,%r15 + movdqu ($ivp),$iv # load IV + mov $ivp,88(%rsp) # save $ivp +___ +my ($in0,$out,$len,$key)=map("%r$_",(12..15)); # reassign arguments +my $rounds="${ivp}d"; +$code.=<<___; + shl \$6,$len + sub $in0,$out + mov 240($key),$rounds + add $inp,$len # end of input + + lea K_XX_XX(%rip),$K_XX_XX + mov 0($ctx),$A # load context + mov 4($ctx),$B + mov 8($ctx),$C + mov 12($ctx),$D + mov $B,@T[0] # magic seed + mov 16($ctx),$E + + movdqa 64($K_XX_XX),@X[2] # pbswap mask + movdqa 0($K_XX_XX),@Tx[1] # K_00_19 + movdqu 0($inp),@X[-4&7] # load input to %xmm[0-3] + movdqu 16($inp),@X[-3&7] + movdqu 32($inp),@X[-2&7] + movdqu 48($inp),@X[-1&7] + pshufb @X[2],@X[-4&7] # byte swap + add \$64,$inp + pshufb @X[2],@X[-3&7] + pshufb @X[2],@X[-2&7] + pshufb @X[2],@X[-1&7] + paddd @Tx[1],@X[-4&7] # add K_00_19 + paddd @Tx[1],@X[-3&7] + paddd @Tx[1],@X[-2&7] + movdqa @X[-4&7],0(%rsp) # X[]+K xfer to IALU + psubd @Tx[1],@X[-4&7] # restore X[] + movdqa @X[-3&7],16(%rsp) + psubd @Tx[1],@X[-3&7] + movdqa @X[-2&7],32(%rsp) + psubd @Tx[1],@X[-2&7] + movups ($key),$rndkey0 # $key[0] + movups 16($key),$rndkey[0] # forward reference + jmp .Loop_ssse3 +___ + +my $aesenc=sub { + use integer; + my ($n,$k)=($r/10,$r%10); + if ($k==0) { + $code.=<<___; + movups `16*$n`($in0),$in # load input + xorps $rndkey0,$in +___ + $code.=<<___ if ($n); + movups $iv,`16*($n-1)`($out,$in0) # write output +___ + $code.=<<___; + xorps $in,$iv + aesenc $rndkey[0],$iv + movups `32+16*$k`($key),$rndkey[1] +___ + } elsif ($k==9) { + $sn++; + $code.=<<___; + cmp \$11,$rounds + jb .Laesenclast$sn + movups `32+16*($k+0)`($key),$rndkey[1] + aesenc $rndkey[0],$iv + movups `32+16*($k+1)`($key),$rndkey[0] + aesenc $rndkey[1],$iv + je .Laesenclast$sn + movups `32+16*($k+2)`($key),$rndkey[1] + aesenc $rndkey[0],$iv + movups `32+16*($k+3)`($key),$rndkey[0] + aesenc $rndkey[1],$iv +.Laesenclast$sn: + aesenclast $rndkey[0],$iv + movups 16($key),$rndkey[1] # forward reference +___ + } else { + $code.=<<___; + aesenc $rndkey[0],$iv + movups `32+16*$k`($key),$rndkey[1] +___ + } + $r++; unshift(@rndkey,pop(@rndkey)); +}; + +sub Xupdate_ssse3_16_31() # recall that $Xi starts wtih 4 +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 40 instructions + my ($a,$b,$c,$d,$e); + + &movdqa (@X[0],@X[-3&7]); + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (@Tx[0],@X[-1&7]); + &palignr(@X[0],@X[-4&7],8); # compose "X[-14]" in "X[0]" + eval(shift(@insns)); + eval(shift(@insns)); + + &paddd (@Tx[1],@X[-1&7]); + eval(shift(@insns)); + eval(shift(@insns)); + &psrldq (@Tx[0],4); # "X[-3]", 3 dwords + eval(shift(@insns)); + eval(shift(@insns)); + &pxor (@X[0],@X[-4&7]); # "X[0]"^="X[-16]" + eval(shift(@insns)); + eval(shift(@insns)); + + &pxor (@Tx[0],@X[-2&7]); # "X[-3]"^"X[-8]" + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &pxor (@X[0],@Tx[0]); # "X[0]"^="X[-3]"^"X[-8]" + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + + &movdqa (@Tx[2],@X[0]); + &movdqa (@Tx[0],@X[0]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &pslldq (@Tx[2],12); # "X[0]"<<96, extract one dword + &paddd (@X[0],@X[0]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &psrld (@Tx[0],31); + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (@Tx[1],@Tx[2]); + eval(shift(@insns)); + eval(shift(@insns)); + + &psrld (@Tx[2],30); + &por (@X[0],@Tx[0]); # "X[0]"<<<=1 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &pslld (@Tx[1],2); + &pxor (@X[0],@Tx[2]); + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (@Tx[2],eval(16*(($Xi)/5))."($K_XX_XX)"); # K_XX_XX + eval(shift(@insns)); + eval(shift(@insns)); + + &pxor (@X[0],@Tx[1]); # "X[0]"^=("X[0]">>96)<<<2 + + foreach (@insns) { eval; } # remaining instructions [if any] + + $Xi++; push(@X,shift(@X)); # "rotate" X[] + push(@Tx,shift(@Tx)); +} + +sub Xupdate_ssse3_32_79() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 to 48 instructions + my ($a,$b,$c,$d,$e); + + &movdqa (@Tx[0],@X[-1&7]) if ($Xi==8); + eval(shift(@insns)); # body_20_39 + &pxor (@X[0],@X[-4&7]); # "X[0]"="X[-32]"^"X[-16]" + &palignr(@Tx[0],@X[-2&7],8); # compose "X[-6]" + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + + &pxor (@X[0],@X[-7&7]); # "X[0]"^="X[-28]" + eval(shift(@insns)); + eval(shift(@insns)) if (@insns[0] !~ /&ro[rl]/); + if ($Xi%5) { + &movdqa (@Tx[2],@Tx[1]);# "perpetuate" K_XX_XX... + } else { # ... or load next one + &movdqa (@Tx[2],eval(16*($Xi/5))."($K_XX_XX)"); + } + &paddd (@Tx[1],@X[-1&7]); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &pxor (@X[0],@Tx[0]); # "X[0]"^="X[-6]" + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + + &movdqa (@Tx[0],@X[0]); + &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &pslld (@X[0],2); + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + &psrld (@Tx[0],30); + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &por (@X[0],@Tx[0]); # "X[0]"<<<=2 + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + &movdqa (@Tx[1],@X[0]) if ($Xi<19); + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + + foreach (@insns) { eval; } # remaining instructions + + $Xi++; push(@X,shift(@X)); # "rotate" X[] + push(@Tx,shift(@Tx)); +} + +sub Xuplast_ssse3_80() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + &paddd (@Tx[1],@X[-1&7]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer IALU + + foreach (@insns) { eval; } # remaining instructions + + &cmp ($inp,$len); + &je (".Ldone_ssse3"); + + unshift(@Tx,pop(@Tx)); + + &movdqa (@X[2],"64($K_XX_XX)"); # pbswap mask + &movdqa (@Tx[1],"0($K_XX_XX)"); # K_00_19 + &movdqu (@X[-4&7],"0($inp)"); # load input + &movdqu (@X[-3&7],"16($inp)"); + &movdqu (@X[-2&7],"32($inp)"); + &movdqu (@X[-1&7],"48($inp)"); + &pshufb (@X[-4&7],@X[2]); # byte swap + &add ($inp,64); + + $Xi=0; +} + +sub Xloop_ssse3() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + eval(shift(@insns)); + &pshufb (@X[($Xi-3)&7],@X[2]); + eval(shift(@insns)); + eval(shift(@insns)); + &paddd (@X[($Xi-4)&7],@Tx[1]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (eval(16*$Xi)."(%rsp)",@X[($Xi-4)&7]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + &psubd (@X[($Xi-4)&7],@Tx[1]); + + foreach (@insns) { eval; } + $Xi++; +} + +sub Xtail_ssse3() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + foreach (@insns) { eval; } +} + +sub body_00_19 () { + use integer; + my ($k,$n); + my @r=( + '($a,$b,$c,$d,$e)=@V;'. + '&add ($e,eval(4*($j&15))."(%rsp)");', # X[]+K xfer + '&xor ($c,$d);', + '&mov (@T[1],$a);', # $b in next round + '&$_rol ($a,5);', + '&and (@T[0],$c);', # ($b&($c^$d)) + '&xor ($c,$d);', # restore $c + '&xor (@T[0],$d);', + '&add ($e,$a);', + '&$_ror ($b,$j?7:2);', # $b>>>2 + '&add ($e,@T[0]);' .'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));' + ); + $n = scalar(@r); + $k = (($jj+1)*12/20)*20*$n/12; # 12 aesencs per these 20 rounds + @r[$k%$n].='&$aesenc();' if ($jj==$k/$n); + $jj++; + return @r; +} + +sub body_20_39 () { + use integer; + my ($k,$n); + my @r=( + '($a,$b,$c,$d,$e)=@V;'. + '&add ($e,eval(4*($j++&15))."(%rsp)");', # X[]+K xfer + '&xor (@T[0],$d);', # ($b^$d) + '&mov (@T[1],$a);', # $b in next round + '&$_rol ($a,5);', + '&xor (@T[0],$c);', # ($b^$d^$c) + '&add ($e,$a);', + '&$_ror ($b,7);', # $b>>>2 + '&add ($e,@T[0]);' .'unshift(@V,pop(@V)); unshift(@T,pop(@T));' + ); + $n = scalar(@r); + $k = (($jj+1)*8/20)*20*$n/8; # 8 aesencs per these 20 rounds + @r[$k%$n].='&$aesenc();' if ($jj==$k/$n); + $jj++; + return @r; +} + +sub body_40_59 () { + use integer; + my ($k,$n); + my @r=( + '($a,$b,$c,$d,$e)=@V;'. + '&mov (@T[1],$c);', + '&xor ($c,$d);', + '&add ($e,eval(4*($j++&15))."(%rsp)");', # X[]+K xfer + '&and (@T[1],$d);', + '&and (@T[0],$c);', # ($b&($c^$d)) + '&$_ror ($b,7);', # $b>>>2 + '&add ($e,@T[1]);', + '&mov (@T[1],$a);', # $b in next round + '&$_rol ($a,5);', + '&add ($e,@T[0]);', + '&xor ($c,$d);', # restore $c + '&add ($e,$a);' .'unshift(@V,pop(@V)); unshift(@T,pop(@T));' + ); + $n = scalar(@r); + $k=(($jj+1)*12/20)*20*$n/12; # 12 aesencs per these 20 rounds + @r[$k%$n].='&$aesenc();' if ($jj==$k/$n); + $jj++; + return @r; +} +$code.=<<___; +.align 16 +.Loop_ssse3: +___ + &Xupdate_ssse3_16_31(\&body_00_19); + &Xupdate_ssse3_16_31(\&body_00_19); + &Xupdate_ssse3_16_31(\&body_00_19); + &Xupdate_ssse3_16_31(\&body_00_19); + &Xupdate_ssse3_32_79(\&body_00_19); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xuplast_ssse3_80(\&body_20_39); # can jump to "done" + + $saved_j=$j; @saved_V=@V; + $saved_r=$r; @saved_rndkey=@rndkey; + + &Xloop_ssse3(\&body_20_39); + &Xloop_ssse3(\&body_20_39); + &Xloop_ssse3(\&body_20_39); + +$code.=<<___; + movups $iv,48($out,$in0) # write output + lea 64($in0),$in0 + + add 0($ctx),$A # update context + add 4($ctx),@T[0] + add 8($ctx),$C + add 12($ctx),$D + mov $A,0($ctx) + add 16($ctx),$E + mov @T[0],4($ctx) + mov @T[0],$B # magic seed + mov $C,8($ctx) + mov $D,12($ctx) + mov $E,16($ctx) + jmp .Loop_ssse3 + +.align 16 +.Ldone_ssse3: +___ + $jj=$j=$saved_j; @V=@saved_V; + $r=$saved_r; @rndkey=@saved_rndkey; + + &Xtail_ssse3(\&body_20_39); + &Xtail_ssse3(\&body_20_39); + &Xtail_ssse3(\&body_20_39); + +$code.=<<___; + movups $iv,48($out,$in0) # write output + mov 88(%rsp),$ivp # restore $ivp + + add 0($ctx),$A # update context + add 4($ctx),@T[0] + add 8($ctx),$C + mov $A,0($ctx) + add 12($ctx),$D + mov @T[0],4($ctx) + add 16($ctx),$E + mov $C,8($ctx) + mov $D,12($ctx) + mov $E,16($ctx) + movups $iv,($ivp) # write IV +___ +$code.=<<___ if ($win64); + movaps 96+0(%rsp),%xmm6 + movaps 96+16(%rsp),%xmm7 + movaps 96+32(%rsp),%xmm8 + movaps 96+48(%rsp),%xmm9 + movaps 96+64(%rsp),%xmm10 + movaps 96+80(%rsp),%xmm11 + movaps 96+96(%rsp),%xmm12 + movaps 96+112(%rsp),%xmm13 + movaps 96+128(%rsp),%xmm14 + movaps 96+144(%rsp),%xmm15 +___ +$code.=<<___; + lea `104+($win64?10*16:0)`(%rsp),%rsi + mov 0(%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 + mov 24(%rsi),%r12 + mov 32(%rsi),%rbp + mov 40(%rsi),%rbx + lea 48(%rsi),%rsp +.Lepilogue_ssse3: + ret +.size aesni_cbc_sha1_enc_ssse3,.-aesni_cbc_sha1_enc_ssse3 +___ + +$j=$jj=$r=$sn=0; + +if ($avx) { +my ($in0,$out,$len,$key,$ivp,$ctx,$inp)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9","%r10"); + +my $Xi=4; +my @X=map("%xmm$_",(4..7,0..3)); +my @Tx=map("%xmm$_",(8..10)); +my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp"); # size optimization +my @T=("%esi","%edi"); + +my $_rol=sub { &shld(@_[0],@_) }; +my $_ror=sub { &shrd(@_[0],@_) }; + +$code.=<<___; +.type aesni_cbc_sha1_enc_avx,\@function,6 +.align 16 +aesni_cbc_sha1_enc_avx: + mov `($win64?56:8)`(%rsp),$inp # load 7th argument + #shr \$6,$len # debugging artefact + #jz .Lepilogue_avx # debugging artefact + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + lea `-104-($win64?10*16:0)`(%rsp),%rsp + #mov $in0,$inp # debugging artefact + #lea 64(%rsp),$ctx # debugging artefact +___ +$code.=<<___ if ($win64); + movaps %xmm6,96+0(%rsp) + movaps %xmm7,96+16(%rsp) + movaps %xmm8,96+32(%rsp) + movaps %xmm9,96+48(%rsp) + movaps %xmm10,96+64(%rsp) + movaps %xmm11,96+80(%rsp) + movaps %xmm12,96+96(%rsp) + movaps %xmm13,96+112(%rsp) + movaps %xmm14,96+128(%rsp) + movaps %xmm15,96+144(%rsp) +.Lprologue_avx: +___ +$code.=<<___; + vzeroall + mov $in0,%r12 # reassign arguments + mov $out,%r13 + mov $len,%r14 + mov $key,%r15 + vmovdqu ($ivp),$iv # load IV + mov $ivp,88(%rsp) # save $ivp +___ +my ($in0,$out,$len,$key)=map("%r$_",(12..15)); # reassign arguments +my $rounds="${ivp}d"; +$code.=<<___; + shl \$6,$len + sub $in0,$out + mov 240($key),$rounds + add \$112,$key # size optimization + add $inp,$len # end of input + + lea K_XX_XX(%rip),$K_XX_XX + mov 0($ctx),$A # load context + mov 4($ctx),$B + mov 8($ctx),$C + mov 12($ctx),$D + mov $B,@T[0] # magic seed + mov 16($ctx),$E + + vmovdqa 64($K_XX_XX),@X[2] # pbswap mask + vmovdqa 0($K_XX_XX),@Tx[1] # K_00_19 + vmovdqu 0($inp),@X[-4&7] # load input to %xmm[0-3] + vmovdqu 16($inp),@X[-3&7] + vmovdqu 32($inp),@X[-2&7] + vmovdqu 48($inp),@X[-1&7] + vpshufb @X[2],@X[-4&7],@X[-4&7] # byte swap + add \$64,$inp + vpshufb @X[2],@X[-3&7],@X[-3&7] + vpshufb @X[2],@X[-2&7],@X[-2&7] + vpshufb @X[2],@X[-1&7],@X[-1&7] + vpaddd @Tx[1],@X[-4&7],@X[0] # add K_00_19 + vpaddd @Tx[1],@X[-3&7],@X[1] + vpaddd @Tx[1],@X[-2&7],@X[2] + vmovdqa @X[0],0(%rsp) # X[]+K xfer to IALU + vmovdqa @X[1],16(%rsp) + vmovdqa @X[2],32(%rsp) + vmovups -112($key),$rndkey0 # $key[0] + vmovups 16-112($key),$rndkey[0] # forward reference + jmp .Loop_avx +___ + +my $aesenc=sub { + use integer; + my ($n,$k)=($r/10,$r%10); + if ($k==0) { + $code.=<<___; + vmovups `16*$n`($in0),$in # load input + vxorps $rndkey0,$in,$in +___ + $code.=<<___ if ($n); + vmovups $iv,`16*($n-1)`($out,$in0) # write output +___ + $code.=<<___; + vxorps $in,$iv,$iv + vaesenc $rndkey[0],$iv,$iv + vmovups `32+16*$k-112`($key),$rndkey[1] +___ + } elsif ($k==9) { + $sn++; + $code.=<<___; + cmp \$11,$rounds + jb .Lvaesenclast$sn + vaesenc $rndkey[0],$iv,$iv + vmovups `32+16*($k+0)-112`($key),$rndkey[1] + vaesenc $rndkey[1],$iv,$iv + vmovups `32+16*($k+1)-112`($key),$rndkey[0] + je .Lvaesenclast$sn + vaesenc $rndkey[0],$iv,$iv + vmovups `32+16*($k+2)-112`($key),$rndkey[1] + vaesenc $rndkey[1],$iv,$iv + vmovups `32+16*($k+3)-112`($key),$rndkey[0] +.Lvaesenclast$sn: + vaesenclast $rndkey[0],$iv,$iv + vmovups 16-112($key),$rndkey[1] # forward reference +___ + } else { + $code.=<<___; + vaesenc $rndkey[0],$iv,$iv + vmovups `32+16*$k-112`($key),$rndkey[1] +___ + } + $r++; unshift(@rndkey,pop(@rndkey)); +}; + +sub Xupdate_avx_16_31() # recall that $Xi starts wtih 4 +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 40 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + eval(shift(@insns)); + &vpalignr(@X[0],@X[-3&7],@X[-4&7],8); # compose "X[-14]" in "X[0]" + eval(shift(@insns)); + eval(shift(@insns)); + + &vpaddd (@Tx[1],@Tx[1],@X[-1&7]); + eval(shift(@insns)); + eval(shift(@insns)); + &vpsrldq(@Tx[0],@X[-1&7],4); # "X[-3]", 3 dwords + eval(shift(@insns)); + eval(shift(@insns)); + &vpxor (@X[0],@X[0],@X[-4&7]); # "X[0]"^="X[-16]" + eval(shift(@insns)); + eval(shift(@insns)); + + &vpxor (@Tx[0],@Tx[0],@X[-2&7]); # "X[-3]"^"X[-8]" + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpxor (@X[0],@X[0],@Tx[0]); # "X[0]"^="X[-3]"^"X[-8]" + eval(shift(@insns)); + eval(shift(@insns)); + &vmovdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + + &vpsrld (@Tx[0],@X[0],31); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpslldq(@Tx[2],@X[0],12); # "X[0]"<<96, extract one dword + &vpaddd (@X[0],@X[0],@X[0]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpsrld (@Tx[1],@Tx[2],30); + &vpor (@X[0],@X[0],@Tx[0]); # "X[0]"<<<=1 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpslld (@Tx[2],@Tx[2],2); + &vpxor (@X[0],@X[0],@Tx[1]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpxor (@X[0],@X[0],@Tx[2]); # "X[0]"^=("X[0]">>96)<<<2 + eval(shift(@insns)); + eval(shift(@insns)); + &vmovdqa (@Tx[2],eval(16*(($Xi)/5))."($K_XX_XX)"); # K_XX_XX + eval(shift(@insns)); + eval(shift(@insns)); + + + foreach (@insns) { eval; } # remaining instructions [if any] + + $Xi++; push(@X,shift(@X)); # "rotate" X[] + push(@Tx,shift(@Tx)); +} + +sub Xupdate_avx_32_79() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 to 48 instructions + my ($a,$b,$c,$d,$e); + + &vpalignr(@Tx[0],@X[-1&7],@X[-2&7],8); # compose "X[-6]" + &vpxor (@X[0],@X[0],@X[-4&7]); # "X[0]"="X[-32]"^"X[-16]" + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + + &vpxor (@X[0],@X[0],@X[-7&7]); # "X[0]"^="X[-28]" + eval(shift(@insns)); + eval(shift(@insns)) if (@insns[0] !~ /&ro[rl]/); + if ($Xi%5) { + &vmovdqa (@Tx[2],@Tx[1]);# "perpetuate" K_XX_XX... + } else { # ... or load next one + &vmovdqa (@Tx[2],eval(16*($Xi/5))."($K_XX_XX)"); + } + &vpaddd (@Tx[1],@Tx[1],@X[-1&7]); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &vpxor (@X[0],@X[0],@Tx[0]); # "X[0]"^="X[-6]" + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + + &vpsrld (@Tx[0],@X[0],30); + &vmovdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &vpslld (@X[0],@X[0],2); + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &vpor (@X[0],@X[0],@Tx[0]); # "X[0]"<<<=2 + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + &vmovdqa (@Tx[1],@X[0]) if ($Xi<19); + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + + foreach (@insns) { eval; } # remaining instructions + + $Xi++; push(@X,shift(@X)); # "rotate" X[] + push(@Tx,shift(@Tx)); +} + +sub Xuplast_avx_80() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + &vpaddd (@Tx[1],@Tx[1],@X[-1&7]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer IALU + + foreach (@insns) { eval; } # remaining instructions + + &cmp ($inp,$len); + &je (".Ldone_avx"); + + unshift(@Tx,pop(@Tx)); + + &vmovdqa(@X[2],"64($K_XX_XX)"); # pbswap mask + &vmovdqa(@Tx[1],"0($K_XX_XX)"); # K_00_19 + &vmovdqu(@X[-4&7],"0($inp)"); # load input + &vmovdqu(@X[-3&7],"16($inp)"); + &vmovdqu(@X[-2&7],"32($inp)"); + &vmovdqu(@X[-1&7],"48($inp)"); + &vpshufb(@X[-4&7],@X[-4&7],@X[2]); # byte swap + &add ($inp,64); + + $Xi=0; +} + +sub Xloop_avx() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + eval(shift(@insns)); + &vpshufb(@X[($Xi-3)&7],@X[($Xi-3)&7],@X[2]); + eval(shift(@insns)); + eval(shift(@insns)); + &vpaddd (@X[$Xi&7],@X[($Xi-4)&7],@Tx[1]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + &vmovdqa(eval(16*$Xi)."(%rsp)",@X[$Xi&7]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + + foreach (@insns) { eval; } + $Xi++; +} + +sub Xtail_avx() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + foreach (@insns) { eval; } +} + +$code.=<<___; +.align 16 +.Loop_avx: +___ + &Xupdate_avx_16_31(\&body_00_19); + &Xupdate_avx_16_31(\&body_00_19); + &Xupdate_avx_16_31(\&body_00_19); + &Xupdate_avx_16_31(\&body_00_19); + &Xupdate_avx_32_79(\&body_00_19); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_20_39); + &Xuplast_avx_80(\&body_20_39); # can jump to "done" + + $saved_j=$j; @saved_V=@V; + $saved_r=$r; @saved_rndkey=@rndkey; + + &Xloop_avx(\&body_20_39); + &Xloop_avx(\&body_20_39); + &Xloop_avx(\&body_20_39); + +$code.=<<___; + vmovups $iv,48($out,$in0) # write output + lea 64($in0),$in0 + + add 0($ctx),$A # update context + add 4($ctx),@T[0] + add 8($ctx),$C + add 12($ctx),$D + mov $A,0($ctx) + add 16($ctx),$E + mov @T[0],4($ctx) + mov @T[0],$B # magic seed + mov $C,8($ctx) + mov $D,12($ctx) + mov $E,16($ctx) + jmp .Loop_avx + +.align 16 +.Ldone_avx: +___ + $jj=$j=$saved_j; @V=@saved_V; + $r=$saved_r; @rndkey=@saved_rndkey; + + &Xtail_avx(\&body_20_39); + &Xtail_avx(\&body_20_39); + &Xtail_avx(\&body_20_39); + +$code.=<<___; + vmovups $iv,48($out,$in0) # write output + mov 88(%rsp),$ivp # restore $ivp + + add 0($ctx),$A # update context + add 4($ctx),@T[0] + add 8($ctx),$C + mov $A,0($ctx) + add 12($ctx),$D + mov @T[0],4($ctx) + add 16($ctx),$E + mov $C,8($ctx) + mov $D,12($ctx) + mov $E,16($ctx) + vmovups $iv,($ivp) # write IV + vzeroall +___ +$code.=<<___ if ($win64); + movaps 96+0(%rsp),%xmm6 + movaps 96+16(%rsp),%xmm7 + movaps 96+32(%rsp),%xmm8 + movaps 96+48(%rsp),%xmm9 + movaps 96+64(%rsp),%xmm10 + movaps 96+80(%rsp),%xmm11 + movaps 96+96(%rsp),%xmm12 + movaps 96+112(%rsp),%xmm13 + movaps 96+128(%rsp),%xmm14 + movaps 96+144(%rsp),%xmm15 +___ +$code.=<<___; + lea `104+($win64?10*16:0)`(%rsp),%rsi + mov 0(%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 + mov 24(%rsi),%r12 + mov 32(%rsi),%rbp + mov 40(%rsi),%rbx + lea 48(%rsi),%rsp +.Lepilogue_avx: + ret +.size aesni_cbc_sha1_enc_avx,.-aesni_cbc_sha1_enc_avx +___ +} +$code.=<<___; +.align 64 +K_XX_XX: +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 # K_00_19 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 # K_20_39 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc # K_40_59 +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 # K_60_79 +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f # pbswap mask + +.asciz "AESNI-CBC+SHA1 stitch for x86_64, CRYPTOGAMS by " +.align 64 +___ + +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type ssse3_handler,\@abi-omnipotent +.align 16 +ssse3_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + mov 8($disp),%rsi # disp->ImageBase + mov 56($disp),%r11 # disp->HandlerData + + mov 0(%r11),%r10d # HandlerData[0] + lea (%rsi,%r10),%r10 # prologue label + cmp %r10,%rbx # context->RipRsp + + mov 4(%r11),%r10d # HandlerData[1] + lea (%rsi,%r10),%r10 # epilogue label + cmp %r10,%rbx # context->Rip>=epilogue label + jae .Lcommon_seh_tail + + lea 96(%rax),%rsi + lea 512($context),%rdi # &context.Xmm6 + mov \$20,%ecx + .long 0xa548f3fc # cld; rep movsq + lea `104+10*16`(%rax),%rax # adjust stack pointer + + mov 0(%rax),%r15 + mov 8(%rax),%r14 + mov 16(%rax),%r13 + mov 24(%rax),%r12 + mov 32(%rax),%rbp + mov 40(%rax),%rbx + lea 48(%rax),%rax + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + +.Lcommon_seh_tail: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$154,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size ssse3_handler,.-ssse3_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_aesni_cbc_sha1_enc_ssse3 + .rva .LSEH_end_aesni_cbc_sha1_enc_ssse3 + .rva .LSEH_info_aesni_cbc_sha1_enc_ssse3 +___ +$code.=<<___ if ($avx); + .rva .LSEH_begin_aesni_cbc_sha1_enc_avx + .rva .LSEH_end_aesni_cbc_sha1_enc_avx + .rva .LSEH_info_aesni_cbc_sha1_enc_avx +___ +$code.=<<___; +.section .xdata +.align 8 +.LSEH_info_aesni_cbc_sha1_enc_ssse3: + .byte 9,0,0,0 + .rva ssse3_handler + .rva .Lprologue_ssse3,.Lepilogue_ssse3 # HandlerData[] +___ +$code.=<<___ if ($avx); +.LSEH_info_aesni_cbc_sha1_enc_avx: + .byte 9,0,0,0 + .rva ssse3_handler + .rva .Lprologue_avx,.Lepilogue_avx # HandlerData[] +___ +} + +#################################################################### +sub rex { + local *opcode=shift; + my ($dst,$src)=@_; + my $rex=0; + + $rex|=0x04 if($dst>=8); + $rex|=0x01 if($src>=8); + push @opcode,$rex|0x40 if($rex); +} + +sub aesni { + my $line=shift; + my @opcode=(0x66); + + if ($line=~/(aes[a-z]+)\s+%xmm([0-9]+),\s*%xmm([0-9]+)/) { + my %opcodelet = ( + "aesenc" => 0xdc, "aesenclast" => 0xdd + ); + return undef if (!defined($opcodelet{$1})); + rex(\@opcode,$3,$2); + push @opcode,0x0f,0x38,$opcodelet{$1}; + push @opcode,0xc0|($2&7)|(($3&7)<<3); # ModR/M + return ".byte\t".join(',',@opcode); + } + return $line; +} + +$code =~ s/\`([^\`]*)\`/eval($1)/gem; +$code =~ s/\b(aes.*%xmm[0-9]+).*$/aesni($1)/gem; + +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/aes/asm/aesni-x86.pl b/libs/openssl/crypto/aes/asm/aesni-x86.pl new file mode 100644 index 00000000..8c1d0b5b --- /dev/null +++ b/libs/openssl/crypto/aes/asm/aesni-x86.pl @@ -0,0 +1,2189 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# This module implements support for Intel AES-NI extension. In +# OpenSSL context it's used with Intel engine, but can also be used as +# drop-in replacement for crypto/aes/asm/aes-586.pl [see below for +# details]. +# +# Performance. +# +# To start with see corresponding paragraph in aesni-x86_64.pl... +# Instead of filling table similar to one found there I've chosen to +# summarize *comparison* results for raw ECB, CTR and CBC benchmarks. +# The simplified table below represents 32-bit performance relative +# to 64-bit one in every given point. Ratios vary for different +# encryption modes, therefore interval values. +# +# 16-byte 64-byte 256-byte 1-KB 8-KB +# 53-67% 67-84% 91-94% 95-98% 97-99.5% +# +# Lower ratios for smaller block sizes are perfectly understandable, +# because function call overhead is higher in 32-bit mode. Largest +# 8-KB block performance is virtually same: 32-bit code is less than +# 1% slower for ECB, CBC and CCM, and ~3% slower otherwise. + +# January 2011 +# +# See aesni-x86_64.pl for details. Unlike x86_64 version this module +# interleaves at most 6 aes[enc|dec] instructions, because there are +# not enough registers for 8x interleave [which should be optimal for +# Sandy Bridge]. Actually, performance results for 6x interleave +# factor presented in aesni-x86_64.pl (except for CTR) are for this +# module. + +# April 2011 +# +# Add aesni_xts_[en|de]crypt. Westmere spends 1.50 cycles processing +# one byte out of 8KB with 128-bit key, Sandy Bridge - 1.09. + +$PREFIX="aesni"; # if $PREFIX is set to "AES", the script + # generates drop-in replacement for + # crypto/aes/asm/aes-586.pl:-) +$inline=1; # inline _aesni_[en|de]crypt + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],$0); + +if ($PREFIX eq "aesni") { $movekey=*movups; } +else { $movekey=*movups; } + +$len="eax"; +$rounds="ecx"; +$key="edx"; +$inp="esi"; +$out="edi"; +$rounds_="ebx"; # backup copy for $rounds +$key_="ebp"; # backup copy for $key + +$rndkey0="xmm0"; +$rndkey1="xmm1"; +$inout0="xmm2"; +$inout1="xmm3"; +$inout2="xmm4"; +$inout3="xmm5"; $in1="xmm5"; +$inout4="xmm6"; $in0="xmm6"; +$inout5="xmm7"; $ivec="xmm7"; + +# AESNI extension +sub aeskeygenassist +{ my($dst,$src,$imm)=@_; + if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/) + { &data_byte(0x66,0x0f,0x3a,0xdf,0xc0|($1<<3)|$2,$imm); } +} +sub aescommon +{ my($opcodelet,$dst,$src)=@_; + if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/) + { &data_byte(0x66,0x0f,0x38,$opcodelet,0xc0|($1<<3)|$2);} +} +sub aesimc { aescommon(0xdb,@_); } +sub aesenc { aescommon(0xdc,@_); } +sub aesenclast { aescommon(0xdd,@_); } +sub aesdec { aescommon(0xde,@_); } +sub aesdeclast { aescommon(0xdf,@_); } + +# Inline version of internal aesni_[en|de]crypt1 +{ my $sn; +sub aesni_inline_generate1 +{ my ($p,$inout,$ivec)=@_; $inout=$inout0 if (!defined($inout)); + $sn++; + + &$movekey ($rndkey0,&QWP(0,$key)); + &$movekey ($rndkey1,&QWP(16,$key)); + &xorps ($ivec,$rndkey0) if (defined($ivec)); + &lea ($key,&DWP(32,$key)); + &xorps ($inout,$ivec) if (defined($ivec)); + &xorps ($inout,$rndkey0) if (!defined($ivec)); + &set_label("${p}1_loop_$sn"); + eval"&aes${p} ($inout,$rndkey1)"; + &dec ($rounds); + &$movekey ($rndkey1,&QWP(0,$key)); + &lea ($key,&DWP(16,$key)); + &jnz (&label("${p}1_loop_$sn")); + eval"&aes${p}last ($inout,$rndkey1)"; +}} + +sub aesni_generate1 # fully unrolled loop +{ my ($p,$inout)=@_; $inout=$inout0 if (!defined($inout)); + + &function_begin_B("_aesni_${p}rypt1"); + &movups ($rndkey0,&QWP(0,$key)); + &$movekey ($rndkey1,&QWP(0x10,$key)); + &xorps ($inout,$rndkey0); + &$movekey ($rndkey0,&QWP(0x20,$key)); + &lea ($key,&DWP(0x30,$key)); + &cmp ($rounds,11); + &jb (&label("${p}128")); + &lea ($key,&DWP(0x20,$key)); + &je (&label("${p}192")); + &lea ($key,&DWP(0x20,$key)); + eval"&aes${p} ($inout,$rndkey1)"; + &$movekey ($rndkey1,&QWP(-0x40,$key)); + eval"&aes${p} ($inout,$rndkey0)"; + &$movekey ($rndkey0,&QWP(-0x30,$key)); + &set_label("${p}192"); + eval"&aes${p} ($inout,$rndkey1)"; + &$movekey ($rndkey1,&QWP(-0x20,$key)); + eval"&aes${p} ($inout,$rndkey0)"; + &$movekey ($rndkey0,&QWP(-0x10,$key)); + &set_label("${p}128"); + eval"&aes${p} ($inout,$rndkey1)"; + &$movekey ($rndkey1,&QWP(0,$key)); + eval"&aes${p} ($inout,$rndkey0)"; + &$movekey ($rndkey0,&QWP(0x10,$key)); + eval"&aes${p} ($inout,$rndkey1)"; + &$movekey ($rndkey1,&QWP(0x20,$key)); + eval"&aes${p} ($inout,$rndkey0)"; + &$movekey ($rndkey0,&QWP(0x30,$key)); + eval"&aes${p} ($inout,$rndkey1)"; + &$movekey ($rndkey1,&QWP(0x40,$key)); + eval"&aes${p} ($inout,$rndkey0)"; + &$movekey ($rndkey0,&QWP(0x50,$key)); + eval"&aes${p} ($inout,$rndkey1)"; + &$movekey ($rndkey1,&QWP(0x60,$key)); + eval"&aes${p} ($inout,$rndkey0)"; + &$movekey ($rndkey0,&QWP(0x70,$key)); + eval"&aes${p} ($inout,$rndkey1)"; + eval"&aes${p}last ($inout,$rndkey0)"; + &ret(); + &function_end_B("_aesni_${p}rypt1"); +} + +# void $PREFIX_encrypt (const void *inp,void *out,const AES_KEY *key); +&aesni_generate1("enc") if (!$inline); +&function_begin_B("${PREFIX}_encrypt"); + &mov ("eax",&wparam(0)); + &mov ($key,&wparam(2)); + &movups ($inout0,&QWP(0,"eax")); + &mov ($rounds,&DWP(240,$key)); + &mov ("eax",&wparam(1)); + if ($inline) + { &aesni_inline_generate1("enc"); } + else + { &call ("_aesni_encrypt1"); } + &movups (&QWP(0,"eax"),$inout0); + &ret (); +&function_end_B("${PREFIX}_encrypt"); + +# void $PREFIX_decrypt (const void *inp,void *out,const AES_KEY *key); +&aesni_generate1("dec") if(!$inline); +&function_begin_B("${PREFIX}_decrypt"); + &mov ("eax",&wparam(0)); + &mov ($key,&wparam(2)); + &movups ($inout0,&QWP(0,"eax")); + &mov ($rounds,&DWP(240,$key)); + &mov ("eax",&wparam(1)); + if ($inline) + { &aesni_inline_generate1("dec"); } + else + { &call ("_aesni_decrypt1"); } + &movups (&QWP(0,"eax"),$inout0); + &ret (); +&function_end_B("${PREFIX}_decrypt"); + +# _aesni_[en|de]cryptN are private interfaces, N denotes interleave +# factor. Why 3x subroutine were originally used in loops? Even though +# aes[enc|dec] latency was originally 6, it could be scheduled only +# every *2nd* cycle. Thus 3x interleave was the one providing optimal +# utilization, i.e. when subroutine's throughput is virtually same as +# of non-interleaved subroutine [for number of input blocks up to 3]. +# This is why it makes no sense to implement 2x subroutine. +# aes[enc|dec] latency in next processor generation is 8, but the +# instructions can be scheduled every cycle. Optimal interleave for +# new processor is therefore 8x, but it's unfeasible to accommodate it +# in XMM registers addreassable in 32-bit mode and therefore 6x is +# used instead... + +sub aesni_generate3 +{ my $p=shift; + + &function_begin_B("_aesni_${p}rypt3"); + &$movekey ($rndkey0,&QWP(0,$key)); + &shr ($rounds,1); + &$movekey ($rndkey1,&QWP(16,$key)); + &lea ($key,&DWP(32,$key)); + &xorps ($inout0,$rndkey0); + &pxor ($inout1,$rndkey0); + &pxor ($inout2,$rndkey0); + &$movekey ($rndkey0,&QWP(0,$key)); + + &set_label("${p}3_loop"); + eval"&aes${p} ($inout0,$rndkey1)"; + eval"&aes${p} ($inout1,$rndkey1)"; + &dec ($rounds); + eval"&aes${p} ($inout2,$rndkey1)"; + &$movekey ($rndkey1,&QWP(16,$key)); + eval"&aes${p} ($inout0,$rndkey0)"; + eval"&aes${p} ($inout1,$rndkey0)"; + &lea ($key,&DWP(32,$key)); + eval"&aes${p} ($inout2,$rndkey0)"; + &$movekey ($rndkey0,&QWP(0,$key)); + &jnz (&label("${p}3_loop")); + eval"&aes${p} ($inout0,$rndkey1)"; + eval"&aes${p} ($inout1,$rndkey1)"; + eval"&aes${p} ($inout2,$rndkey1)"; + eval"&aes${p}last ($inout0,$rndkey0)"; + eval"&aes${p}last ($inout1,$rndkey0)"; + eval"&aes${p}last ($inout2,$rndkey0)"; + &ret(); + &function_end_B("_aesni_${p}rypt3"); +} + +# 4x interleave is implemented to improve small block performance, +# most notably [and naturally] 4 block by ~30%. One can argue that one +# should have implemented 5x as well, but improvement would be <20%, +# so it's not worth it... +sub aesni_generate4 +{ my $p=shift; + + &function_begin_B("_aesni_${p}rypt4"); + &$movekey ($rndkey0,&QWP(0,$key)); + &$movekey ($rndkey1,&QWP(16,$key)); + &shr ($rounds,1); + &lea ($key,&DWP(32,$key)); + &xorps ($inout0,$rndkey0); + &pxor ($inout1,$rndkey0); + &pxor ($inout2,$rndkey0); + &pxor ($inout3,$rndkey0); + &$movekey ($rndkey0,&QWP(0,$key)); + + &set_label("${p}4_loop"); + eval"&aes${p} ($inout0,$rndkey1)"; + eval"&aes${p} ($inout1,$rndkey1)"; + &dec ($rounds); + eval"&aes${p} ($inout2,$rndkey1)"; + eval"&aes${p} ($inout3,$rndkey1)"; + &$movekey ($rndkey1,&QWP(16,$key)); + eval"&aes${p} ($inout0,$rndkey0)"; + eval"&aes${p} ($inout1,$rndkey0)"; + &lea ($key,&DWP(32,$key)); + eval"&aes${p} ($inout2,$rndkey0)"; + eval"&aes${p} ($inout3,$rndkey0)"; + &$movekey ($rndkey0,&QWP(0,$key)); + &jnz (&label("${p}4_loop")); + + eval"&aes${p} ($inout0,$rndkey1)"; + eval"&aes${p} ($inout1,$rndkey1)"; + eval"&aes${p} ($inout2,$rndkey1)"; + eval"&aes${p} ($inout3,$rndkey1)"; + eval"&aes${p}last ($inout0,$rndkey0)"; + eval"&aes${p}last ($inout1,$rndkey0)"; + eval"&aes${p}last ($inout2,$rndkey0)"; + eval"&aes${p}last ($inout3,$rndkey0)"; + &ret(); + &function_end_B("_aesni_${p}rypt4"); +} + +sub aesni_generate6 +{ my $p=shift; + + &function_begin_B("_aesni_${p}rypt6"); + &static_label("_aesni_${p}rypt6_enter"); + &$movekey ($rndkey0,&QWP(0,$key)); + &shr ($rounds,1); + &$movekey ($rndkey1,&QWP(16,$key)); + &lea ($key,&DWP(32,$key)); + &xorps ($inout0,$rndkey0); + &pxor ($inout1,$rndkey0); # pxor does better here + eval"&aes${p} ($inout0,$rndkey1)"; + &pxor ($inout2,$rndkey0); + eval"&aes${p} ($inout1,$rndkey1)"; + &pxor ($inout3,$rndkey0); + &dec ($rounds); + eval"&aes${p} ($inout2,$rndkey1)"; + &pxor ($inout4,$rndkey0); + eval"&aes${p} ($inout3,$rndkey1)"; + &pxor ($inout5,$rndkey0); + eval"&aes${p} ($inout4,$rndkey1)"; + &$movekey ($rndkey0,&QWP(0,$key)); + eval"&aes${p} ($inout5,$rndkey1)"; + &jmp (&label("_aesni_${p}rypt6_enter")); + + &set_label("${p}6_loop",16); + eval"&aes${p} ($inout0,$rndkey1)"; + eval"&aes${p} ($inout1,$rndkey1)"; + &dec ($rounds); + eval"&aes${p} ($inout2,$rndkey1)"; + eval"&aes${p} ($inout3,$rndkey1)"; + eval"&aes${p} ($inout4,$rndkey1)"; + eval"&aes${p} ($inout5,$rndkey1)"; + &set_label("_aesni_${p}rypt6_enter",16); + &$movekey ($rndkey1,&QWP(16,$key)); + eval"&aes${p} ($inout0,$rndkey0)"; + eval"&aes${p} ($inout1,$rndkey0)"; + &lea ($key,&DWP(32,$key)); + eval"&aes${p} ($inout2,$rndkey0)"; + eval"&aes${p} ($inout3,$rndkey0)"; + eval"&aes${p} ($inout4,$rndkey0)"; + eval"&aes${p} ($inout5,$rndkey0)"; + &$movekey ($rndkey0,&QWP(0,$key)); + &jnz (&label("${p}6_loop")); + + eval"&aes${p} ($inout0,$rndkey1)"; + eval"&aes${p} ($inout1,$rndkey1)"; + eval"&aes${p} ($inout2,$rndkey1)"; + eval"&aes${p} ($inout3,$rndkey1)"; + eval"&aes${p} ($inout4,$rndkey1)"; + eval"&aes${p} ($inout5,$rndkey1)"; + eval"&aes${p}last ($inout0,$rndkey0)"; + eval"&aes${p}last ($inout1,$rndkey0)"; + eval"&aes${p}last ($inout2,$rndkey0)"; + eval"&aes${p}last ($inout3,$rndkey0)"; + eval"&aes${p}last ($inout4,$rndkey0)"; + eval"&aes${p}last ($inout5,$rndkey0)"; + &ret(); + &function_end_B("_aesni_${p}rypt6"); +} +&aesni_generate3("enc") if ($PREFIX eq "aesni"); +&aesni_generate3("dec"); +&aesni_generate4("enc") if ($PREFIX eq "aesni"); +&aesni_generate4("dec"); +&aesni_generate6("enc") if ($PREFIX eq "aesni"); +&aesni_generate6("dec"); + +if ($PREFIX eq "aesni") { +###################################################################### +# void aesni_ecb_encrypt (const void *in, void *out, +# size_t length, const AES_KEY *key, +# int enc); +&function_begin("aesni_ecb_encrypt"); + &mov ($inp,&wparam(0)); + &mov ($out,&wparam(1)); + &mov ($len,&wparam(2)); + &mov ($key,&wparam(3)); + &mov ($rounds_,&wparam(4)); + &and ($len,-16); + &jz (&label("ecb_ret")); + &mov ($rounds,&DWP(240,$key)); + &test ($rounds_,$rounds_); + &jz (&label("ecb_decrypt")); + + &mov ($key_,$key); # backup $key + &mov ($rounds_,$rounds); # backup $rounds + &cmp ($len,0x60); + &jb (&label("ecb_enc_tail")); + + &movdqu ($inout0,&QWP(0,$inp)); + &movdqu ($inout1,&QWP(0x10,$inp)); + &movdqu ($inout2,&QWP(0x20,$inp)); + &movdqu ($inout3,&QWP(0x30,$inp)); + &movdqu ($inout4,&QWP(0x40,$inp)); + &movdqu ($inout5,&QWP(0x50,$inp)); + &lea ($inp,&DWP(0x60,$inp)); + &sub ($len,0x60); + &jmp (&label("ecb_enc_loop6_enter")); + +&set_label("ecb_enc_loop6",16); + &movups (&QWP(0,$out),$inout0); + &movdqu ($inout0,&QWP(0,$inp)); + &movups (&QWP(0x10,$out),$inout1); + &movdqu ($inout1,&QWP(0x10,$inp)); + &movups (&QWP(0x20,$out),$inout2); + &movdqu ($inout2,&QWP(0x20,$inp)); + &movups (&QWP(0x30,$out),$inout3); + &movdqu ($inout3,&QWP(0x30,$inp)); + &movups (&QWP(0x40,$out),$inout4); + &movdqu ($inout4,&QWP(0x40,$inp)); + &movups (&QWP(0x50,$out),$inout5); + &lea ($out,&DWP(0x60,$out)); + &movdqu ($inout5,&QWP(0x50,$inp)); + &lea ($inp,&DWP(0x60,$inp)); +&set_label("ecb_enc_loop6_enter"); + + &call ("_aesni_encrypt6"); + + &mov ($key,$key_); # restore $key + &mov ($rounds,$rounds_); # restore $rounds + &sub ($len,0x60); + &jnc (&label("ecb_enc_loop6")); + + &movups (&QWP(0,$out),$inout0); + &movups (&QWP(0x10,$out),$inout1); + &movups (&QWP(0x20,$out),$inout2); + &movups (&QWP(0x30,$out),$inout3); + &movups (&QWP(0x40,$out),$inout4); + &movups (&QWP(0x50,$out),$inout5); + &lea ($out,&DWP(0x60,$out)); + &add ($len,0x60); + &jz (&label("ecb_ret")); + +&set_label("ecb_enc_tail"); + &movups ($inout0,&QWP(0,$inp)); + &cmp ($len,0x20); + &jb (&label("ecb_enc_one")); + &movups ($inout1,&QWP(0x10,$inp)); + &je (&label("ecb_enc_two")); + &movups ($inout2,&QWP(0x20,$inp)); + &cmp ($len,0x40); + &jb (&label("ecb_enc_three")); + &movups ($inout3,&QWP(0x30,$inp)); + &je (&label("ecb_enc_four")); + &movups ($inout4,&QWP(0x40,$inp)); + &xorps ($inout5,$inout5); + &call ("_aesni_encrypt6"); + &movups (&QWP(0,$out),$inout0); + &movups (&QWP(0x10,$out),$inout1); + &movups (&QWP(0x20,$out),$inout2); + &movups (&QWP(0x30,$out),$inout3); + &movups (&QWP(0x40,$out),$inout4); + jmp (&label("ecb_ret")); + +&set_label("ecb_enc_one",16); + if ($inline) + { &aesni_inline_generate1("enc"); } + else + { &call ("_aesni_encrypt1"); } + &movups (&QWP(0,$out),$inout0); + &jmp (&label("ecb_ret")); + +&set_label("ecb_enc_two",16); + &xorps ($inout2,$inout2); + &call ("_aesni_encrypt3"); + &movups (&QWP(0,$out),$inout0); + &movups (&QWP(0x10,$out),$inout1); + &jmp (&label("ecb_ret")); + +&set_label("ecb_enc_three",16); + &call ("_aesni_encrypt3"); + &movups (&QWP(0,$out),$inout0); + &movups (&QWP(0x10,$out),$inout1); + &movups (&QWP(0x20,$out),$inout2); + &jmp (&label("ecb_ret")); + +&set_label("ecb_enc_four",16); + &call ("_aesni_encrypt4"); + &movups (&QWP(0,$out),$inout0); + &movups (&QWP(0x10,$out),$inout1); + &movups (&QWP(0x20,$out),$inout2); + &movups (&QWP(0x30,$out),$inout3); + &jmp (&label("ecb_ret")); +###################################################################### +&set_label("ecb_decrypt",16); + &mov ($key_,$key); # backup $key + &mov ($rounds_,$rounds); # backup $rounds + &cmp ($len,0x60); + &jb (&label("ecb_dec_tail")); + + &movdqu ($inout0,&QWP(0,$inp)); + &movdqu ($inout1,&QWP(0x10,$inp)); + &movdqu ($inout2,&QWP(0x20,$inp)); + &movdqu ($inout3,&QWP(0x30,$inp)); + &movdqu ($inout4,&QWP(0x40,$inp)); + &movdqu ($inout5,&QWP(0x50,$inp)); + &lea ($inp,&DWP(0x60,$inp)); + &sub ($len,0x60); + &jmp (&label("ecb_dec_loop6_enter")); + +&set_label("ecb_dec_loop6",16); + &movups (&QWP(0,$out),$inout0); + &movdqu ($inout0,&QWP(0,$inp)); + &movups (&QWP(0x10,$out),$inout1); + &movdqu ($inout1,&QWP(0x10,$inp)); + &movups (&QWP(0x20,$out),$inout2); + &movdqu ($inout2,&QWP(0x20,$inp)); + &movups (&QWP(0x30,$out),$inout3); + &movdqu ($inout3,&QWP(0x30,$inp)); + &movups (&QWP(0x40,$out),$inout4); + &movdqu ($inout4,&QWP(0x40,$inp)); + &movups (&QWP(0x50,$out),$inout5); + &lea ($out,&DWP(0x60,$out)); + &movdqu ($inout5,&QWP(0x50,$inp)); + &lea ($inp,&DWP(0x60,$inp)); +&set_label("ecb_dec_loop6_enter"); + + &call ("_aesni_decrypt6"); + + &mov ($key,$key_); # restore $key + &mov ($rounds,$rounds_); # restore $rounds + &sub ($len,0x60); + &jnc (&label("ecb_dec_loop6")); + + &movups (&QWP(0,$out),$inout0); + &movups (&QWP(0x10,$out),$inout1); + &movups (&QWP(0x20,$out),$inout2); + &movups (&QWP(0x30,$out),$inout3); + &movups (&QWP(0x40,$out),$inout4); + &movups (&QWP(0x50,$out),$inout5); + &lea ($out,&DWP(0x60,$out)); + &add ($len,0x60); + &jz (&label("ecb_ret")); + +&set_label("ecb_dec_tail"); + &movups ($inout0,&QWP(0,$inp)); + &cmp ($len,0x20); + &jb (&label("ecb_dec_one")); + &movups ($inout1,&QWP(0x10,$inp)); + &je (&label("ecb_dec_two")); + &movups ($inout2,&QWP(0x20,$inp)); + &cmp ($len,0x40); + &jb (&label("ecb_dec_three")); + &movups ($inout3,&QWP(0x30,$inp)); + &je (&label("ecb_dec_four")); + &movups ($inout4,&QWP(0x40,$inp)); + &xorps ($inout5,$inout5); + &call ("_aesni_decrypt6"); + &movups (&QWP(0,$out),$inout0); + &movups (&QWP(0x10,$out),$inout1); + &movups (&QWP(0x20,$out),$inout2); + &movups (&QWP(0x30,$out),$inout3); + &movups (&QWP(0x40,$out),$inout4); + &jmp (&label("ecb_ret")); + +&set_label("ecb_dec_one",16); + if ($inline) + { &aesni_inline_generate1("dec"); } + else + { &call ("_aesni_decrypt1"); } + &movups (&QWP(0,$out),$inout0); + &jmp (&label("ecb_ret")); + +&set_label("ecb_dec_two",16); + &xorps ($inout2,$inout2); + &call ("_aesni_decrypt3"); + &movups (&QWP(0,$out),$inout0); + &movups (&QWP(0x10,$out),$inout1); + &jmp (&label("ecb_ret")); + +&set_label("ecb_dec_three",16); + &call ("_aesni_decrypt3"); + &movups (&QWP(0,$out),$inout0); + &movups (&QWP(0x10,$out),$inout1); + &movups (&QWP(0x20,$out),$inout2); + &jmp (&label("ecb_ret")); + +&set_label("ecb_dec_four",16); + &call ("_aesni_decrypt4"); + &movups (&QWP(0,$out),$inout0); + &movups (&QWP(0x10,$out),$inout1); + &movups (&QWP(0x20,$out),$inout2); + &movups (&QWP(0x30,$out),$inout3); + +&set_label("ecb_ret"); +&function_end("aesni_ecb_encrypt"); + +###################################################################### +# void aesni_ccm64_[en|de]crypt_blocks (const void *in, void *out, +# size_t blocks, const AES_KEY *key, +# const char *ivec,char *cmac); +# +# Handles only complete blocks, operates on 64-bit counter and +# does not update *ivec! Nor does it finalize CMAC value +# (see engine/eng_aesni.c for details) +# +{ my $cmac=$inout1; +&function_begin("aesni_ccm64_encrypt_blocks"); + &mov ($inp,&wparam(0)); + &mov ($out,&wparam(1)); + &mov ($len,&wparam(2)); + &mov ($key,&wparam(3)); + &mov ($rounds_,&wparam(4)); + &mov ($rounds,&wparam(5)); + &mov ($key_,"esp"); + &sub ("esp",60); + &and ("esp",-16); # align stack + &mov (&DWP(48,"esp"),$key_); + + &movdqu ($ivec,&QWP(0,$rounds_)); # load ivec + &movdqu ($cmac,&QWP(0,$rounds)); # load cmac + &mov ($rounds,&DWP(240,$key)); + + # compose byte-swap control mask for pshufb on stack + &mov (&DWP(0,"esp"),0x0c0d0e0f); + &mov (&DWP(4,"esp"),0x08090a0b); + &mov (&DWP(8,"esp"),0x04050607); + &mov (&DWP(12,"esp"),0x00010203); + + # compose counter increment vector on stack + &mov ($rounds_,1); + &xor ($key_,$key_); + &mov (&DWP(16,"esp"),$rounds_); + &mov (&DWP(20,"esp"),$key_); + &mov (&DWP(24,"esp"),$key_); + &mov (&DWP(28,"esp"),$key_); + + &shr ($rounds,1); + &lea ($key_,&DWP(0,$key)); + &movdqa ($inout3,&QWP(0,"esp")); + &movdqa ($inout0,$ivec); + &mov ($rounds_,$rounds); + &pshufb ($ivec,$inout3); + +&set_label("ccm64_enc_outer"); + &$movekey ($rndkey0,&QWP(0,$key_)); + &mov ($rounds,$rounds_); + &movups ($in0,&QWP(0,$inp)); + + &xorps ($inout0,$rndkey0); + &$movekey ($rndkey1,&QWP(16,$key_)); + &xorps ($rndkey0,$in0); + &lea ($key,&DWP(32,$key_)); + &xorps ($cmac,$rndkey0); # cmac^=inp + &$movekey ($rndkey0,&QWP(0,$key)); + +&set_label("ccm64_enc2_loop"); + &aesenc ($inout0,$rndkey1); + &dec ($rounds); + &aesenc ($cmac,$rndkey1); + &$movekey ($rndkey1,&QWP(16,$key)); + &aesenc ($inout0,$rndkey0); + &lea ($key,&DWP(32,$key)); + &aesenc ($cmac,$rndkey0); + &$movekey ($rndkey0,&QWP(0,$key)); + &jnz (&label("ccm64_enc2_loop")); + &aesenc ($inout0,$rndkey1); + &aesenc ($cmac,$rndkey1); + &paddq ($ivec,&QWP(16,"esp")); + &aesenclast ($inout0,$rndkey0); + &aesenclast ($cmac,$rndkey0); + + &dec ($len); + &lea ($inp,&DWP(16,$inp)); + &xorps ($in0,$inout0); # inp^=E(ivec) + &movdqa ($inout0,$ivec); + &movups (&QWP(0,$out),$in0); # save output + &lea ($out,&DWP(16,$out)); + &pshufb ($inout0,$inout3); + &jnz (&label("ccm64_enc_outer")); + + &mov ("esp",&DWP(48,"esp")); + &mov ($out,&wparam(5)); + &movups (&QWP(0,$out),$cmac); +&function_end("aesni_ccm64_encrypt_blocks"); + +&function_begin("aesni_ccm64_decrypt_blocks"); + &mov ($inp,&wparam(0)); + &mov ($out,&wparam(1)); + &mov ($len,&wparam(2)); + &mov ($key,&wparam(3)); + &mov ($rounds_,&wparam(4)); + &mov ($rounds,&wparam(5)); + &mov ($key_,"esp"); + &sub ("esp",60); + &and ("esp",-16); # align stack + &mov (&DWP(48,"esp"),$key_); + + &movdqu ($ivec,&QWP(0,$rounds_)); # load ivec + &movdqu ($cmac,&QWP(0,$rounds)); # load cmac + &mov ($rounds,&DWP(240,$key)); + + # compose byte-swap control mask for pshufb on stack + &mov (&DWP(0,"esp"),0x0c0d0e0f); + &mov (&DWP(4,"esp"),0x08090a0b); + &mov (&DWP(8,"esp"),0x04050607); + &mov (&DWP(12,"esp"),0x00010203); + + # compose counter increment vector on stack + &mov ($rounds_,1); + &xor ($key_,$key_); + &mov (&DWP(16,"esp"),$rounds_); + &mov (&DWP(20,"esp"),$key_); + &mov (&DWP(24,"esp"),$key_); + &mov (&DWP(28,"esp"),$key_); + + &movdqa ($inout3,&QWP(0,"esp")); # bswap mask + &movdqa ($inout0,$ivec); + + &mov ($key_,$key); + &mov ($rounds_,$rounds); + + &pshufb ($ivec,$inout3); + if ($inline) + { &aesni_inline_generate1("enc"); } + else + { &call ("_aesni_encrypt1"); } + &movups ($in0,&QWP(0,$inp)); # load inp + &paddq ($ivec,&QWP(16,"esp")); + &lea ($inp,&QWP(16,$inp)); + &jmp (&label("ccm64_dec_outer")); + +&set_label("ccm64_dec_outer",16); + &xorps ($in0,$inout0); # inp ^= E(ivec) + &movdqa ($inout0,$ivec); + &mov ($rounds,$rounds_); + &movups (&QWP(0,$out),$in0); # save output + &lea ($out,&DWP(16,$out)); + &pshufb ($inout0,$inout3); + + &sub ($len,1); + &jz (&label("ccm64_dec_break")); + + &$movekey ($rndkey0,&QWP(0,$key_)); + &shr ($rounds,1); + &$movekey ($rndkey1,&QWP(16,$key_)); + &xorps ($in0,$rndkey0); + &lea ($key,&DWP(32,$key_)); + &xorps ($inout0,$rndkey0); + &xorps ($cmac,$in0); # cmac^=out + &$movekey ($rndkey0,&QWP(0,$key)); + +&set_label("ccm64_dec2_loop"); + &aesenc ($inout0,$rndkey1); + &dec ($rounds); + &aesenc ($cmac,$rndkey1); + &$movekey ($rndkey1,&QWP(16,$key)); + &aesenc ($inout0,$rndkey0); + &lea ($key,&DWP(32,$key)); + &aesenc ($cmac,$rndkey0); + &$movekey ($rndkey0,&QWP(0,$key)); + &jnz (&label("ccm64_dec2_loop")); + &movups ($in0,&QWP(0,$inp)); # load inp + &paddq ($ivec,&QWP(16,"esp")); + &aesenc ($inout0,$rndkey1); + &aesenc ($cmac,$rndkey1); + &lea ($inp,&QWP(16,$inp)); + &aesenclast ($inout0,$rndkey0); + &aesenclast ($cmac,$rndkey0); + &jmp (&label("ccm64_dec_outer")); + +&set_label("ccm64_dec_break",16); + &mov ($key,$key_); + if ($inline) + { &aesni_inline_generate1("enc",$cmac,$in0); } + else + { &call ("_aesni_encrypt1",$cmac); } + + &mov ("esp",&DWP(48,"esp")); + &mov ($out,&wparam(5)); + &movups (&QWP(0,$out),$cmac); +&function_end("aesni_ccm64_decrypt_blocks"); +} + +###################################################################### +# void aesni_ctr32_encrypt_blocks (const void *in, void *out, +# size_t blocks, const AES_KEY *key, +# const char *ivec); +# +# Handles only complete blocks, operates on 32-bit counter and +# does not update *ivec! (see engine/eng_aesni.c for details) +# +# stack layout: +# 0 pshufb mask +# 16 vector addend: 0,6,6,6 +# 32 counter-less ivec +# 48 1st triplet of counter vector +# 64 2nd triplet of counter vector +# 80 saved %esp + +&function_begin("aesni_ctr32_encrypt_blocks"); + &mov ($inp,&wparam(0)); + &mov ($out,&wparam(1)); + &mov ($len,&wparam(2)); + &mov ($key,&wparam(3)); + &mov ($rounds_,&wparam(4)); + &mov ($key_,"esp"); + &sub ("esp",88); + &and ("esp",-16); # align stack + &mov (&DWP(80,"esp"),$key_); + + &cmp ($len,1); + &je (&label("ctr32_one_shortcut")); + + &movdqu ($inout5,&QWP(0,$rounds_)); # load ivec + + # compose byte-swap control mask for pshufb on stack + &mov (&DWP(0,"esp"),0x0c0d0e0f); + &mov (&DWP(4,"esp"),0x08090a0b); + &mov (&DWP(8,"esp"),0x04050607); + &mov (&DWP(12,"esp"),0x00010203); + + # compose counter increment vector on stack + &mov ($rounds,6); + &xor ($key_,$key_); + &mov (&DWP(16,"esp"),$rounds); + &mov (&DWP(20,"esp"),$rounds); + &mov (&DWP(24,"esp"),$rounds); + &mov (&DWP(28,"esp"),$key_); + + &pextrd ($rounds_,$inout5,3); # pull 32-bit counter + &pinsrd ($inout5,$key_,3); # wipe 32-bit counter + + &mov ($rounds,&DWP(240,$key)); # key->rounds + + # compose 2 vectors of 3x32-bit counters + &bswap ($rounds_); + &pxor ($rndkey1,$rndkey1); + &pxor ($rndkey0,$rndkey0); + &movdqa ($inout0,&QWP(0,"esp")); # load byte-swap mask + &pinsrd ($rndkey1,$rounds_,0); + &lea ($key_,&DWP(3,$rounds_)); + &pinsrd ($rndkey0,$key_,0); + &inc ($rounds_); + &pinsrd ($rndkey1,$rounds_,1); + &inc ($key_); + &pinsrd ($rndkey0,$key_,1); + &inc ($rounds_); + &pinsrd ($rndkey1,$rounds_,2); + &inc ($key_); + &pinsrd ($rndkey0,$key_,2); + &movdqa (&QWP(48,"esp"),$rndkey1); # save 1st triplet + &pshufb ($rndkey1,$inout0); # byte swap + &movdqa (&QWP(64,"esp"),$rndkey0); # save 2nd triplet + &pshufb ($rndkey0,$inout0); # byte swap + + &pshufd ($inout0,$rndkey1,3<<6); # place counter to upper dword + &pshufd ($inout1,$rndkey1,2<<6); + &cmp ($len,6); + &jb (&label("ctr32_tail")); + &movdqa (&QWP(32,"esp"),$inout5); # save counter-less ivec + &shr ($rounds,1); + &mov ($key_,$key); # backup $key + &mov ($rounds_,$rounds); # backup $rounds + &sub ($len,6); + &jmp (&label("ctr32_loop6")); + +&set_label("ctr32_loop6",16); + &pshufd ($inout2,$rndkey1,1<<6); + &movdqa ($rndkey1,&QWP(32,"esp")); # pull counter-less ivec + &pshufd ($inout3,$rndkey0,3<<6); + &por ($inout0,$rndkey1); # merge counter-less ivec + &pshufd ($inout4,$rndkey0,2<<6); + &por ($inout1,$rndkey1); + &pshufd ($inout5,$rndkey0,1<<6); + &por ($inout2,$rndkey1); + &por ($inout3,$rndkey1); + &por ($inout4,$rndkey1); + &por ($inout5,$rndkey1); + + # inlining _aesni_encrypt6's prologue gives ~4% improvement... + &$movekey ($rndkey0,&QWP(0,$key_)); + &$movekey ($rndkey1,&QWP(16,$key_)); + &lea ($key,&DWP(32,$key_)); + &dec ($rounds); + &pxor ($inout0,$rndkey0); + &pxor ($inout1,$rndkey0); + &aesenc ($inout0,$rndkey1); + &pxor ($inout2,$rndkey0); + &aesenc ($inout1,$rndkey1); + &pxor ($inout3,$rndkey0); + &aesenc ($inout2,$rndkey1); + &pxor ($inout4,$rndkey0); + &aesenc ($inout3,$rndkey1); + &pxor ($inout5,$rndkey0); + &aesenc ($inout4,$rndkey1); + &$movekey ($rndkey0,&QWP(0,$key)); + &aesenc ($inout5,$rndkey1); + + &call (&label("_aesni_encrypt6_enter")); + + &movups ($rndkey1,&QWP(0,$inp)); + &movups ($rndkey0,&QWP(0x10,$inp)); + &xorps ($inout0,$rndkey1); + &movups ($rndkey1,&QWP(0x20,$inp)); + &xorps ($inout1,$rndkey0); + &movups (&QWP(0,$out),$inout0); + &movdqa ($rndkey0,&QWP(16,"esp")); # load increment + &xorps ($inout2,$rndkey1); + &movdqa ($rndkey1,&QWP(48,"esp")); # load 1st triplet + &movups (&QWP(0x10,$out),$inout1); + &movups (&QWP(0x20,$out),$inout2); + + &paddd ($rndkey1,$rndkey0); # 1st triplet increment + &paddd ($rndkey0,&QWP(64,"esp")); # 2nd triplet increment + &movdqa ($inout0,&QWP(0,"esp")); # load byte swap mask + + &movups ($inout1,&QWP(0x30,$inp)); + &movups ($inout2,&QWP(0x40,$inp)); + &xorps ($inout3,$inout1); + &movups ($inout1,&QWP(0x50,$inp)); + &lea ($inp,&DWP(0x60,$inp)); + &movdqa (&QWP(48,"esp"),$rndkey1); # save 1st triplet + &pshufb ($rndkey1,$inout0); # byte swap + &xorps ($inout4,$inout2); + &movups (&QWP(0x30,$out),$inout3); + &xorps ($inout5,$inout1); + &movdqa (&QWP(64,"esp"),$rndkey0); # save 2nd triplet + &pshufb ($rndkey0,$inout0); # byte swap + &movups (&QWP(0x40,$out),$inout4); + &pshufd ($inout0,$rndkey1,3<<6); + &movups (&QWP(0x50,$out),$inout5); + &lea ($out,&DWP(0x60,$out)); + + &mov ($rounds,$rounds_); + &pshufd ($inout1,$rndkey1,2<<6); + &sub ($len,6); + &jnc (&label("ctr32_loop6")); + + &add ($len,6); + &jz (&label("ctr32_ret")); + &mov ($key,$key_); + &lea ($rounds,&DWP(1,"",$rounds,2)); # restore $rounds + &movdqa ($inout5,&QWP(32,"esp")); # pull count-less ivec + +&set_label("ctr32_tail"); + &por ($inout0,$inout5); + &cmp ($len,2); + &jb (&label("ctr32_one")); + + &pshufd ($inout2,$rndkey1,1<<6); + &por ($inout1,$inout5); + &je (&label("ctr32_two")); + + &pshufd ($inout3,$rndkey0,3<<6); + &por ($inout2,$inout5); + &cmp ($len,4); + &jb (&label("ctr32_three")); + + &pshufd ($inout4,$rndkey0,2<<6); + &por ($inout3,$inout5); + &je (&label("ctr32_four")); + + &por ($inout4,$inout5); + &call ("_aesni_encrypt6"); + &movups ($rndkey1,&QWP(0,$inp)); + &movups ($rndkey0,&QWP(0x10,$inp)); + &xorps ($inout0,$rndkey1); + &movups ($rndkey1,&QWP(0x20,$inp)); + &xorps ($inout1,$rndkey0); + &movups ($rndkey0,&QWP(0x30,$inp)); + &xorps ($inout2,$rndkey1); + &movups ($rndkey1,&QWP(0x40,$inp)); + &xorps ($inout3,$rndkey0); + &movups (&QWP(0,$out),$inout0); + &xorps ($inout4,$rndkey1); + &movups (&QWP(0x10,$out),$inout1); + &movups (&QWP(0x20,$out),$inout2); + &movups (&QWP(0x30,$out),$inout3); + &movups (&QWP(0x40,$out),$inout4); + &jmp (&label("ctr32_ret")); + +&set_label("ctr32_one_shortcut",16); + &movups ($inout0,&QWP(0,$rounds_)); # load ivec + &mov ($rounds,&DWP(240,$key)); + +&set_label("ctr32_one"); + if ($inline) + { &aesni_inline_generate1("enc"); } + else + { &call ("_aesni_encrypt1"); } + &movups ($in0,&QWP(0,$inp)); + &xorps ($in0,$inout0); + &movups (&QWP(0,$out),$in0); + &jmp (&label("ctr32_ret")); + +&set_label("ctr32_two",16); + &call ("_aesni_encrypt3"); + &movups ($inout3,&QWP(0,$inp)); + &movups ($inout4,&QWP(0x10,$inp)); + &xorps ($inout0,$inout3); + &xorps ($inout1,$inout4); + &movups (&QWP(0,$out),$inout0); + &movups (&QWP(0x10,$out),$inout1); + &jmp (&label("ctr32_ret")); + +&set_label("ctr32_three",16); + &call ("_aesni_encrypt3"); + &movups ($inout3,&QWP(0,$inp)); + &movups ($inout4,&QWP(0x10,$inp)); + &xorps ($inout0,$inout3); + &movups ($inout5,&QWP(0x20,$inp)); + &xorps ($inout1,$inout4); + &movups (&QWP(0,$out),$inout0); + &xorps ($inout2,$inout5); + &movups (&QWP(0x10,$out),$inout1); + &movups (&QWP(0x20,$out),$inout2); + &jmp (&label("ctr32_ret")); + +&set_label("ctr32_four",16); + &call ("_aesni_encrypt4"); + &movups ($inout4,&QWP(0,$inp)); + &movups ($inout5,&QWP(0x10,$inp)); + &movups ($rndkey1,&QWP(0x20,$inp)); + &xorps ($inout0,$inout4); + &movups ($rndkey0,&QWP(0x30,$inp)); + &xorps ($inout1,$inout5); + &movups (&QWP(0,$out),$inout0); + &xorps ($inout2,$rndkey1); + &movups (&QWP(0x10,$out),$inout1); + &xorps ($inout3,$rndkey0); + &movups (&QWP(0x20,$out),$inout2); + &movups (&QWP(0x30,$out),$inout3); + +&set_label("ctr32_ret"); + &mov ("esp",&DWP(80,"esp")); +&function_end("aesni_ctr32_encrypt_blocks"); + +###################################################################### +# void aesni_xts_[en|de]crypt(const char *inp,char *out,size_t len, +# const AES_KEY *key1, const AES_KEY *key2 +# const unsigned char iv[16]); +# +{ my ($tweak,$twtmp,$twres,$twmask)=($rndkey1,$rndkey0,$inout0,$inout1); + +&function_begin("aesni_xts_encrypt"); + &mov ($key,&wparam(4)); # key2 + &mov ($inp,&wparam(5)); # clear-text tweak + + &mov ($rounds,&DWP(240,$key)); # key2->rounds + &movups ($inout0,&QWP(0,$inp)); + if ($inline) + { &aesni_inline_generate1("enc"); } + else + { &call ("_aesni_encrypt1"); } + + &mov ($inp,&wparam(0)); + &mov ($out,&wparam(1)); + &mov ($len,&wparam(2)); + &mov ($key,&wparam(3)); # key1 + + &mov ($key_,"esp"); + &sub ("esp",16*7+8); + &mov ($rounds,&DWP(240,$key)); # key1->rounds + &and ("esp",-16); # align stack + + &mov (&DWP(16*6+0,"esp"),0x87); # compose the magic constant + &mov (&DWP(16*6+4,"esp"),0); + &mov (&DWP(16*6+8,"esp"),1); + &mov (&DWP(16*6+12,"esp"),0); + &mov (&DWP(16*7+0,"esp"),$len); # save original $len + &mov (&DWP(16*7+4,"esp"),$key_); # save original %esp + + &movdqa ($tweak,$inout0); + &pxor ($twtmp,$twtmp); + &movdqa ($twmask,&QWP(6*16,"esp")); # 0x0...010...87 + &pcmpgtd($twtmp,$tweak); # broadcast upper bits + + &and ($len,-16); + &mov ($key_,$key); # backup $key + &mov ($rounds_,$rounds); # backup $rounds + &sub ($len,16*6); + &jc (&label("xts_enc_short")); + + &shr ($rounds,1); + &mov ($rounds_,$rounds); + &jmp (&label("xts_enc_loop6")); + +&set_label("xts_enc_loop6",16); + for ($i=0;$i<4;$i++) { + &pshufd ($twres,$twtmp,0x13); + &pxor ($twtmp,$twtmp); + &movdqa (&QWP(16*$i,"esp"),$tweak); + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &pand ($twres,$twmask); # isolate carry and residue + &pcmpgtd ($twtmp,$tweak); # broadcast upper bits + &pxor ($tweak,$twres); + } + &pshufd ($inout5,$twtmp,0x13); + &movdqa (&QWP(16*$i++,"esp"),$tweak); + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &$movekey ($rndkey0,&QWP(0,$key_)); + &pand ($inout5,$twmask); # isolate carry and residue + &movups ($inout0,&QWP(0,$inp)); # load input + &pxor ($inout5,$tweak); + + # inline _aesni_encrypt6 prologue and flip xor with tweak and key[0] + &movdqu ($inout1,&QWP(16*1,$inp)); + &xorps ($inout0,$rndkey0); # input^=rndkey[0] + &movdqu ($inout2,&QWP(16*2,$inp)); + &pxor ($inout1,$rndkey0); + &movdqu ($inout3,&QWP(16*3,$inp)); + &pxor ($inout2,$rndkey0); + &movdqu ($inout4,&QWP(16*4,$inp)); + &pxor ($inout3,$rndkey0); + &movdqu ($rndkey1,&QWP(16*5,$inp)); + &pxor ($inout4,$rndkey0); + &lea ($inp,&DWP(16*6,$inp)); + &pxor ($inout0,&QWP(16*0,"esp")); # input^=tweak + &movdqa (&QWP(16*$i,"esp"),$inout5); # save last tweak + &pxor ($inout5,$rndkey1); + + &$movekey ($rndkey1,&QWP(16,$key_)); + &lea ($key,&DWP(32,$key_)); + &pxor ($inout1,&QWP(16*1,"esp")); + &aesenc ($inout0,$rndkey1); + &pxor ($inout2,&QWP(16*2,"esp")); + &aesenc ($inout1,$rndkey1); + &pxor ($inout3,&QWP(16*3,"esp")); + &dec ($rounds); + &aesenc ($inout2,$rndkey1); + &pxor ($inout4,&QWP(16*4,"esp")); + &aesenc ($inout3,$rndkey1); + &pxor ($inout5,$rndkey0); + &aesenc ($inout4,$rndkey1); + &$movekey ($rndkey0,&QWP(0,$key)); + &aesenc ($inout5,$rndkey1); + &call (&label("_aesni_encrypt6_enter")); + + &movdqa ($tweak,&QWP(16*5,"esp")); # last tweak + &pxor ($twtmp,$twtmp); + &xorps ($inout0,&QWP(16*0,"esp")); # output^=tweak + &pcmpgtd ($twtmp,$tweak); # broadcast upper bits + &xorps ($inout1,&QWP(16*1,"esp")); + &movups (&QWP(16*0,$out),$inout0); # write output + &xorps ($inout2,&QWP(16*2,"esp")); + &movups (&QWP(16*1,$out),$inout1); + &xorps ($inout3,&QWP(16*3,"esp")); + &movups (&QWP(16*2,$out),$inout2); + &xorps ($inout4,&QWP(16*4,"esp")); + &movups (&QWP(16*3,$out),$inout3); + &xorps ($inout5,$tweak); + &movups (&QWP(16*4,$out),$inout4); + &pshufd ($twres,$twtmp,0x13); + &movups (&QWP(16*5,$out),$inout5); + &lea ($out,&DWP(16*6,$out)); + &movdqa ($twmask,&QWP(16*6,"esp")); # 0x0...010...87 + + &pxor ($twtmp,$twtmp); + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &pand ($twres,$twmask); # isolate carry and residue + &pcmpgtd($twtmp,$tweak); # broadcast upper bits + &mov ($rounds,$rounds_); # restore $rounds + &pxor ($tweak,$twres); + + &sub ($len,16*6); + &jnc (&label("xts_enc_loop6")); + + &lea ($rounds,&DWP(1,"",$rounds,2)); # restore $rounds + &mov ($key,$key_); # restore $key + &mov ($rounds_,$rounds); + +&set_label("xts_enc_short"); + &add ($len,16*6); + &jz (&label("xts_enc_done6x")); + + &movdqa ($inout3,$tweak); # put aside previous tweak + &cmp ($len,0x20); + &jb (&label("xts_enc_one")); + + &pshufd ($twres,$twtmp,0x13); + &pxor ($twtmp,$twtmp); + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &pand ($twres,$twmask); # isolate carry and residue + &pcmpgtd($twtmp,$tweak); # broadcast upper bits + &pxor ($tweak,$twres); + &je (&label("xts_enc_two")); + + &pshufd ($twres,$twtmp,0x13); + &pxor ($twtmp,$twtmp); + &movdqa ($inout4,$tweak); # put aside previous tweak + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &pand ($twres,$twmask); # isolate carry and residue + &pcmpgtd($twtmp,$tweak); # broadcast upper bits + &pxor ($tweak,$twres); + &cmp ($len,0x40); + &jb (&label("xts_enc_three")); + + &pshufd ($twres,$twtmp,0x13); + &pxor ($twtmp,$twtmp); + &movdqa ($inout5,$tweak); # put aside previous tweak + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &pand ($twres,$twmask); # isolate carry and residue + &pcmpgtd($twtmp,$tweak); # broadcast upper bits + &pxor ($tweak,$twres); + &movdqa (&QWP(16*0,"esp"),$inout3); + &movdqa (&QWP(16*1,"esp"),$inout4); + &je (&label("xts_enc_four")); + + &movdqa (&QWP(16*2,"esp"),$inout5); + &pshufd ($inout5,$twtmp,0x13); + &movdqa (&QWP(16*3,"esp"),$tweak); + &paddq ($tweak,$tweak); # &psllq($inout0,1); + &pand ($inout5,$twmask); # isolate carry and residue + &pxor ($inout5,$tweak); + + &movdqu ($inout0,&QWP(16*0,$inp)); # load input + &movdqu ($inout1,&QWP(16*1,$inp)); + &movdqu ($inout2,&QWP(16*2,$inp)); + &pxor ($inout0,&QWP(16*0,"esp")); # input^=tweak + &movdqu ($inout3,&QWP(16*3,$inp)); + &pxor ($inout1,&QWP(16*1,"esp")); + &movdqu ($inout4,&QWP(16*4,$inp)); + &pxor ($inout2,&QWP(16*2,"esp")); + &lea ($inp,&DWP(16*5,$inp)); + &pxor ($inout3,&QWP(16*3,"esp")); + &movdqa (&QWP(16*4,"esp"),$inout5); # save last tweak + &pxor ($inout4,$inout5); + + &call ("_aesni_encrypt6"); + + &movaps ($tweak,&QWP(16*4,"esp")); # last tweak + &xorps ($inout0,&QWP(16*0,"esp")); # output^=tweak + &xorps ($inout1,&QWP(16*1,"esp")); + &xorps ($inout2,&QWP(16*2,"esp")); + &movups (&QWP(16*0,$out),$inout0); # write output + &xorps ($inout3,&QWP(16*3,"esp")); + &movups (&QWP(16*1,$out),$inout1); + &xorps ($inout4,$tweak); + &movups (&QWP(16*2,$out),$inout2); + &movups (&QWP(16*3,$out),$inout3); + &movups (&QWP(16*4,$out),$inout4); + &lea ($out,&DWP(16*5,$out)); + &jmp (&label("xts_enc_done")); + +&set_label("xts_enc_one",16); + &movups ($inout0,&QWP(16*0,$inp)); # load input + &lea ($inp,&DWP(16*1,$inp)); + &xorps ($inout0,$inout3); # input^=tweak + if ($inline) + { &aesni_inline_generate1("enc"); } + else + { &call ("_aesni_encrypt1"); } + &xorps ($inout0,$inout3); # output^=tweak + &movups (&QWP(16*0,$out),$inout0); # write output + &lea ($out,&DWP(16*1,$out)); + + &movdqa ($tweak,$inout3); # last tweak + &jmp (&label("xts_enc_done")); + +&set_label("xts_enc_two",16); + &movaps ($inout4,$tweak); # put aside last tweak + + &movups ($inout0,&QWP(16*0,$inp)); # load input + &movups ($inout1,&QWP(16*1,$inp)); + &lea ($inp,&DWP(16*2,$inp)); + &xorps ($inout0,$inout3); # input^=tweak + &xorps ($inout1,$inout4); + &xorps ($inout2,$inout2); + + &call ("_aesni_encrypt3"); + + &xorps ($inout0,$inout3); # output^=tweak + &xorps ($inout1,$inout4); + &movups (&QWP(16*0,$out),$inout0); # write output + &movups (&QWP(16*1,$out),$inout1); + &lea ($out,&DWP(16*2,$out)); + + &movdqa ($tweak,$inout4); # last tweak + &jmp (&label("xts_enc_done")); + +&set_label("xts_enc_three",16); + &movaps ($inout5,$tweak); # put aside last tweak + &movups ($inout0,&QWP(16*0,$inp)); # load input + &movups ($inout1,&QWP(16*1,$inp)); + &movups ($inout2,&QWP(16*2,$inp)); + &lea ($inp,&DWP(16*3,$inp)); + &xorps ($inout0,$inout3); # input^=tweak + &xorps ($inout1,$inout4); + &xorps ($inout2,$inout5); + + &call ("_aesni_encrypt3"); + + &xorps ($inout0,$inout3); # output^=tweak + &xorps ($inout1,$inout4); + &xorps ($inout2,$inout5); + &movups (&QWP(16*0,$out),$inout0); # write output + &movups (&QWP(16*1,$out),$inout1); + &movups (&QWP(16*2,$out),$inout2); + &lea ($out,&DWP(16*3,$out)); + + &movdqa ($tweak,$inout5); # last tweak + &jmp (&label("xts_enc_done")); + +&set_label("xts_enc_four",16); + &movaps ($inout4,$tweak); # put aside last tweak + + &movups ($inout0,&QWP(16*0,$inp)); # load input + &movups ($inout1,&QWP(16*1,$inp)); + &movups ($inout2,&QWP(16*2,$inp)); + &xorps ($inout0,&QWP(16*0,"esp")); # input^=tweak + &movups ($inout3,&QWP(16*3,$inp)); + &lea ($inp,&DWP(16*4,$inp)); + &xorps ($inout1,&QWP(16*1,"esp")); + &xorps ($inout2,$inout5); + &xorps ($inout3,$inout4); + + &call ("_aesni_encrypt4"); + + &xorps ($inout0,&QWP(16*0,"esp")); # output^=tweak + &xorps ($inout1,&QWP(16*1,"esp")); + &xorps ($inout2,$inout5); + &movups (&QWP(16*0,$out),$inout0); # write output + &xorps ($inout3,$inout4); + &movups (&QWP(16*1,$out),$inout1); + &movups (&QWP(16*2,$out),$inout2); + &movups (&QWP(16*3,$out),$inout3); + &lea ($out,&DWP(16*4,$out)); + + &movdqa ($tweak,$inout4); # last tweak + &jmp (&label("xts_enc_done")); + +&set_label("xts_enc_done6x",16); # $tweak is pre-calculated + &mov ($len,&DWP(16*7+0,"esp")); # restore original $len + &and ($len,15); + &jz (&label("xts_enc_ret")); + &movdqa ($inout3,$tweak); + &mov (&DWP(16*7+0,"esp"),$len); # save $len%16 + &jmp (&label("xts_enc_steal")); + +&set_label("xts_enc_done",16); + &mov ($len,&DWP(16*7+0,"esp")); # restore original $len + &pxor ($twtmp,$twtmp); + &and ($len,15); + &jz (&label("xts_enc_ret")); + + &pcmpgtd($twtmp,$tweak); # broadcast upper bits + &mov (&DWP(16*7+0,"esp"),$len); # save $len%16 + &pshufd ($inout3,$twtmp,0x13); + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &pand ($inout3,&QWP(16*6,"esp")); # isolate carry and residue + &pxor ($inout3,$tweak); + +&set_label("xts_enc_steal"); + &movz ($rounds,&BP(0,$inp)); + &movz ($key,&BP(-16,$out)); + &lea ($inp,&DWP(1,$inp)); + &mov (&BP(-16,$out),&LB($rounds)); + &mov (&BP(0,$out),&LB($key)); + &lea ($out,&DWP(1,$out)); + &sub ($len,1); + &jnz (&label("xts_enc_steal")); + + &sub ($out,&DWP(16*7+0,"esp")); # rewind $out + &mov ($key,$key_); # restore $key + &mov ($rounds,$rounds_); # restore $rounds + + &movups ($inout0,&QWP(-16,$out)); # load input + &xorps ($inout0,$inout3); # input^=tweak + if ($inline) + { &aesni_inline_generate1("enc"); } + else + { &call ("_aesni_encrypt1"); } + &xorps ($inout0,$inout3); # output^=tweak + &movups (&QWP(-16,$out),$inout0); # write output + +&set_label("xts_enc_ret"); + &mov ("esp",&DWP(16*7+4,"esp")); # restore %esp +&function_end("aesni_xts_encrypt"); + +&function_begin("aesni_xts_decrypt"); + &mov ($key,&wparam(4)); # key2 + &mov ($inp,&wparam(5)); # clear-text tweak + + &mov ($rounds,&DWP(240,$key)); # key2->rounds + &movups ($inout0,&QWP(0,$inp)); + if ($inline) + { &aesni_inline_generate1("enc"); } + else + { &call ("_aesni_encrypt1"); } + + &mov ($inp,&wparam(0)); + &mov ($out,&wparam(1)); + &mov ($len,&wparam(2)); + &mov ($key,&wparam(3)); # key1 + + &mov ($key_,"esp"); + &sub ("esp",16*7+8); + &and ("esp",-16); # align stack + + &xor ($rounds_,$rounds_); # if(len%16) len-=16; + &test ($len,15); + &setnz (&LB($rounds_)); + &shl ($rounds_,4); + &sub ($len,$rounds_); + + &mov (&DWP(16*6+0,"esp"),0x87); # compose the magic constant + &mov (&DWP(16*6+4,"esp"),0); + &mov (&DWP(16*6+8,"esp"),1); + &mov (&DWP(16*6+12,"esp"),0); + &mov (&DWP(16*7+0,"esp"),$len); # save original $len + &mov (&DWP(16*7+4,"esp"),$key_); # save original %esp + + &mov ($rounds,&DWP(240,$key)); # key1->rounds + &mov ($key_,$key); # backup $key + &mov ($rounds_,$rounds); # backup $rounds + + &movdqa ($tweak,$inout0); + &pxor ($twtmp,$twtmp); + &movdqa ($twmask,&QWP(6*16,"esp")); # 0x0...010...87 + &pcmpgtd($twtmp,$tweak); # broadcast upper bits + + &and ($len,-16); + &sub ($len,16*6); + &jc (&label("xts_dec_short")); + + &shr ($rounds,1); + &mov ($rounds_,$rounds); + &jmp (&label("xts_dec_loop6")); + +&set_label("xts_dec_loop6",16); + for ($i=0;$i<4;$i++) { + &pshufd ($twres,$twtmp,0x13); + &pxor ($twtmp,$twtmp); + &movdqa (&QWP(16*$i,"esp"),$tweak); + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &pand ($twres,$twmask); # isolate carry and residue + &pcmpgtd ($twtmp,$tweak); # broadcast upper bits + &pxor ($tweak,$twres); + } + &pshufd ($inout5,$twtmp,0x13); + &movdqa (&QWP(16*$i++,"esp"),$tweak); + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &$movekey ($rndkey0,&QWP(0,$key_)); + &pand ($inout5,$twmask); # isolate carry and residue + &movups ($inout0,&QWP(0,$inp)); # load input + &pxor ($inout5,$tweak); + + # inline _aesni_encrypt6 prologue and flip xor with tweak and key[0] + &movdqu ($inout1,&QWP(16*1,$inp)); + &xorps ($inout0,$rndkey0); # input^=rndkey[0] + &movdqu ($inout2,&QWP(16*2,$inp)); + &pxor ($inout1,$rndkey0); + &movdqu ($inout3,&QWP(16*3,$inp)); + &pxor ($inout2,$rndkey0); + &movdqu ($inout4,&QWP(16*4,$inp)); + &pxor ($inout3,$rndkey0); + &movdqu ($rndkey1,&QWP(16*5,$inp)); + &pxor ($inout4,$rndkey0); + &lea ($inp,&DWP(16*6,$inp)); + &pxor ($inout0,&QWP(16*0,"esp")); # input^=tweak + &movdqa (&QWP(16*$i,"esp"),$inout5); # save last tweak + &pxor ($inout5,$rndkey1); + + &$movekey ($rndkey1,&QWP(16,$key_)); + &lea ($key,&DWP(32,$key_)); + &pxor ($inout1,&QWP(16*1,"esp")); + &aesdec ($inout0,$rndkey1); + &pxor ($inout2,&QWP(16*2,"esp")); + &aesdec ($inout1,$rndkey1); + &pxor ($inout3,&QWP(16*3,"esp")); + &dec ($rounds); + &aesdec ($inout2,$rndkey1); + &pxor ($inout4,&QWP(16*4,"esp")); + &aesdec ($inout3,$rndkey1); + &pxor ($inout5,$rndkey0); + &aesdec ($inout4,$rndkey1); + &$movekey ($rndkey0,&QWP(0,$key)); + &aesdec ($inout5,$rndkey1); + &call (&label("_aesni_decrypt6_enter")); + + &movdqa ($tweak,&QWP(16*5,"esp")); # last tweak + &pxor ($twtmp,$twtmp); + &xorps ($inout0,&QWP(16*0,"esp")); # output^=tweak + &pcmpgtd ($twtmp,$tweak); # broadcast upper bits + &xorps ($inout1,&QWP(16*1,"esp")); + &movups (&QWP(16*0,$out),$inout0); # write output + &xorps ($inout2,&QWP(16*2,"esp")); + &movups (&QWP(16*1,$out),$inout1); + &xorps ($inout3,&QWP(16*3,"esp")); + &movups (&QWP(16*2,$out),$inout2); + &xorps ($inout4,&QWP(16*4,"esp")); + &movups (&QWP(16*3,$out),$inout3); + &xorps ($inout5,$tweak); + &movups (&QWP(16*4,$out),$inout4); + &pshufd ($twres,$twtmp,0x13); + &movups (&QWP(16*5,$out),$inout5); + &lea ($out,&DWP(16*6,$out)); + &movdqa ($twmask,&QWP(16*6,"esp")); # 0x0...010...87 + + &pxor ($twtmp,$twtmp); + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &pand ($twres,$twmask); # isolate carry and residue + &pcmpgtd($twtmp,$tweak); # broadcast upper bits + &mov ($rounds,$rounds_); # restore $rounds + &pxor ($tweak,$twres); + + &sub ($len,16*6); + &jnc (&label("xts_dec_loop6")); + + &lea ($rounds,&DWP(1,"",$rounds,2)); # restore $rounds + &mov ($key,$key_); # restore $key + &mov ($rounds_,$rounds); + +&set_label("xts_dec_short"); + &add ($len,16*6); + &jz (&label("xts_dec_done6x")); + + &movdqa ($inout3,$tweak); # put aside previous tweak + &cmp ($len,0x20); + &jb (&label("xts_dec_one")); + + &pshufd ($twres,$twtmp,0x13); + &pxor ($twtmp,$twtmp); + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &pand ($twres,$twmask); # isolate carry and residue + &pcmpgtd($twtmp,$tweak); # broadcast upper bits + &pxor ($tweak,$twres); + &je (&label("xts_dec_two")); + + &pshufd ($twres,$twtmp,0x13); + &pxor ($twtmp,$twtmp); + &movdqa ($inout4,$tweak); # put aside previous tweak + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &pand ($twres,$twmask); # isolate carry and residue + &pcmpgtd($twtmp,$tweak); # broadcast upper bits + &pxor ($tweak,$twres); + &cmp ($len,0x40); + &jb (&label("xts_dec_three")); + + &pshufd ($twres,$twtmp,0x13); + &pxor ($twtmp,$twtmp); + &movdqa ($inout5,$tweak); # put aside previous tweak + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &pand ($twres,$twmask); # isolate carry and residue + &pcmpgtd($twtmp,$tweak); # broadcast upper bits + &pxor ($tweak,$twres); + &movdqa (&QWP(16*0,"esp"),$inout3); + &movdqa (&QWP(16*1,"esp"),$inout4); + &je (&label("xts_dec_four")); + + &movdqa (&QWP(16*2,"esp"),$inout5); + &pshufd ($inout5,$twtmp,0x13); + &movdqa (&QWP(16*3,"esp"),$tweak); + &paddq ($tweak,$tweak); # &psllq($inout0,1); + &pand ($inout5,$twmask); # isolate carry and residue + &pxor ($inout5,$tweak); + + &movdqu ($inout0,&QWP(16*0,$inp)); # load input + &movdqu ($inout1,&QWP(16*1,$inp)); + &movdqu ($inout2,&QWP(16*2,$inp)); + &pxor ($inout0,&QWP(16*0,"esp")); # input^=tweak + &movdqu ($inout3,&QWP(16*3,$inp)); + &pxor ($inout1,&QWP(16*1,"esp")); + &movdqu ($inout4,&QWP(16*4,$inp)); + &pxor ($inout2,&QWP(16*2,"esp")); + &lea ($inp,&DWP(16*5,$inp)); + &pxor ($inout3,&QWP(16*3,"esp")); + &movdqa (&QWP(16*4,"esp"),$inout5); # save last tweak + &pxor ($inout4,$inout5); + + &call ("_aesni_decrypt6"); + + &movaps ($tweak,&QWP(16*4,"esp")); # last tweak + &xorps ($inout0,&QWP(16*0,"esp")); # output^=tweak + &xorps ($inout1,&QWP(16*1,"esp")); + &xorps ($inout2,&QWP(16*2,"esp")); + &movups (&QWP(16*0,$out),$inout0); # write output + &xorps ($inout3,&QWP(16*3,"esp")); + &movups (&QWP(16*1,$out),$inout1); + &xorps ($inout4,$tweak); + &movups (&QWP(16*2,$out),$inout2); + &movups (&QWP(16*3,$out),$inout3); + &movups (&QWP(16*4,$out),$inout4); + &lea ($out,&DWP(16*5,$out)); + &jmp (&label("xts_dec_done")); + +&set_label("xts_dec_one",16); + &movups ($inout0,&QWP(16*0,$inp)); # load input + &lea ($inp,&DWP(16*1,$inp)); + &xorps ($inout0,$inout3); # input^=tweak + if ($inline) + { &aesni_inline_generate1("dec"); } + else + { &call ("_aesni_decrypt1"); } + &xorps ($inout0,$inout3); # output^=tweak + &movups (&QWP(16*0,$out),$inout0); # write output + &lea ($out,&DWP(16*1,$out)); + + &movdqa ($tweak,$inout3); # last tweak + &jmp (&label("xts_dec_done")); + +&set_label("xts_dec_two",16); + &movaps ($inout4,$tweak); # put aside last tweak + + &movups ($inout0,&QWP(16*0,$inp)); # load input + &movups ($inout1,&QWP(16*1,$inp)); + &lea ($inp,&DWP(16*2,$inp)); + &xorps ($inout0,$inout3); # input^=tweak + &xorps ($inout1,$inout4); + + &call ("_aesni_decrypt3"); + + &xorps ($inout0,$inout3); # output^=tweak + &xorps ($inout1,$inout4); + &movups (&QWP(16*0,$out),$inout0); # write output + &movups (&QWP(16*1,$out),$inout1); + &lea ($out,&DWP(16*2,$out)); + + &movdqa ($tweak,$inout4); # last tweak + &jmp (&label("xts_dec_done")); + +&set_label("xts_dec_three",16); + &movaps ($inout5,$tweak); # put aside last tweak + &movups ($inout0,&QWP(16*0,$inp)); # load input + &movups ($inout1,&QWP(16*1,$inp)); + &movups ($inout2,&QWP(16*2,$inp)); + &lea ($inp,&DWP(16*3,$inp)); + &xorps ($inout0,$inout3); # input^=tweak + &xorps ($inout1,$inout4); + &xorps ($inout2,$inout5); + + &call ("_aesni_decrypt3"); + + &xorps ($inout0,$inout3); # output^=tweak + &xorps ($inout1,$inout4); + &xorps ($inout2,$inout5); + &movups (&QWP(16*0,$out),$inout0); # write output + &movups (&QWP(16*1,$out),$inout1); + &movups (&QWP(16*2,$out),$inout2); + &lea ($out,&DWP(16*3,$out)); + + &movdqa ($tweak,$inout5); # last tweak + &jmp (&label("xts_dec_done")); + +&set_label("xts_dec_four",16); + &movaps ($inout4,$tweak); # put aside last tweak + + &movups ($inout0,&QWP(16*0,$inp)); # load input + &movups ($inout1,&QWP(16*1,$inp)); + &movups ($inout2,&QWP(16*2,$inp)); + &xorps ($inout0,&QWP(16*0,"esp")); # input^=tweak + &movups ($inout3,&QWP(16*3,$inp)); + &lea ($inp,&DWP(16*4,$inp)); + &xorps ($inout1,&QWP(16*1,"esp")); + &xorps ($inout2,$inout5); + &xorps ($inout3,$inout4); + + &call ("_aesni_decrypt4"); + + &xorps ($inout0,&QWP(16*0,"esp")); # output^=tweak + &xorps ($inout1,&QWP(16*1,"esp")); + &xorps ($inout2,$inout5); + &movups (&QWP(16*0,$out),$inout0); # write output + &xorps ($inout3,$inout4); + &movups (&QWP(16*1,$out),$inout1); + &movups (&QWP(16*2,$out),$inout2); + &movups (&QWP(16*3,$out),$inout3); + &lea ($out,&DWP(16*4,$out)); + + &movdqa ($tweak,$inout4); # last tweak + &jmp (&label("xts_dec_done")); + +&set_label("xts_dec_done6x",16); # $tweak is pre-calculated + &mov ($len,&DWP(16*7+0,"esp")); # restore original $len + &and ($len,15); + &jz (&label("xts_dec_ret")); + &mov (&DWP(16*7+0,"esp"),$len); # save $len%16 + &jmp (&label("xts_dec_only_one_more")); + +&set_label("xts_dec_done",16); + &mov ($len,&DWP(16*7+0,"esp")); # restore original $len + &pxor ($twtmp,$twtmp); + &and ($len,15); + &jz (&label("xts_dec_ret")); + + &pcmpgtd($twtmp,$tweak); # broadcast upper bits + &mov (&DWP(16*7+0,"esp"),$len); # save $len%16 + &pshufd ($twres,$twtmp,0x13); + &pxor ($twtmp,$twtmp); + &movdqa ($twmask,&QWP(16*6,"esp")); + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &pand ($twres,$twmask); # isolate carry and residue + &pcmpgtd($twtmp,$tweak); # broadcast upper bits + &pxor ($tweak,$twres); + +&set_label("xts_dec_only_one_more"); + &pshufd ($inout3,$twtmp,0x13); + &movdqa ($inout4,$tweak); # put aside previous tweak + &paddq ($tweak,$tweak); # &psllq($tweak,1); + &pand ($inout3,$twmask); # isolate carry and residue + &pxor ($inout3,$tweak); + + &mov ($key,$key_); # restore $key + &mov ($rounds,$rounds_); # restore $rounds + + &movups ($inout0,&QWP(0,$inp)); # load input + &xorps ($inout0,$inout3); # input^=tweak + if ($inline) + { &aesni_inline_generate1("dec"); } + else + { &call ("_aesni_decrypt1"); } + &xorps ($inout0,$inout3); # output^=tweak + &movups (&QWP(0,$out),$inout0); # write output + +&set_label("xts_dec_steal"); + &movz ($rounds,&BP(16,$inp)); + &movz ($key,&BP(0,$out)); + &lea ($inp,&DWP(1,$inp)); + &mov (&BP(0,$out),&LB($rounds)); + &mov (&BP(16,$out),&LB($key)); + &lea ($out,&DWP(1,$out)); + &sub ($len,1); + &jnz (&label("xts_dec_steal")); + + &sub ($out,&DWP(16*7+0,"esp")); # rewind $out + &mov ($key,$key_); # restore $key + &mov ($rounds,$rounds_); # restore $rounds + + &movups ($inout0,&QWP(0,$out)); # load input + &xorps ($inout0,$inout4); # input^=tweak + if ($inline) + { &aesni_inline_generate1("dec"); } + else + { &call ("_aesni_decrypt1"); } + &xorps ($inout0,$inout4); # output^=tweak + &movups (&QWP(0,$out),$inout0); # write output + +&set_label("xts_dec_ret"); + &mov ("esp",&DWP(16*7+4,"esp")); # restore %esp +&function_end("aesni_xts_decrypt"); +} +} + +###################################################################### +# void $PREFIX_cbc_encrypt (const void *inp, void *out, +# size_t length, const AES_KEY *key, +# unsigned char *ivp,const int enc); +&function_begin("${PREFIX}_cbc_encrypt"); + &mov ($inp,&wparam(0)); + &mov ($rounds_,"esp"); + &mov ($out,&wparam(1)); + &sub ($rounds_,24); + &mov ($len,&wparam(2)); + &and ($rounds_,-16); + &mov ($key,&wparam(3)); + &mov ($key_,&wparam(4)); + &test ($len,$len); + &jz (&label("cbc_abort")); + + &cmp (&wparam(5),0); + &xchg ($rounds_,"esp"); # alloca + &movups ($ivec,&QWP(0,$key_)); # load IV + &mov ($rounds,&DWP(240,$key)); + &mov ($key_,$key); # backup $key + &mov (&DWP(16,"esp"),$rounds_); # save original %esp + &mov ($rounds_,$rounds); # backup $rounds + &je (&label("cbc_decrypt")); + + &movaps ($inout0,$ivec); + &cmp ($len,16); + &jb (&label("cbc_enc_tail")); + &sub ($len,16); + &jmp (&label("cbc_enc_loop")); + +&set_label("cbc_enc_loop",16); + &movups ($ivec,&QWP(0,$inp)); # input actually + &lea ($inp,&DWP(16,$inp)); + if ($inline) + { &aesni_inline_generate1("enc",$inout0,$ivec); } + else + { &xorps($inout0,$ivec); &call("_aesni_encrypt1"); } + &mov ($rounds,$rounds_); # restore $rounds + &mov ($key,$key_); # restore $key + &movups (&QWP(0,$out),$inout0); # store output + &lea ($out,&DWP(16,$out)); + &sub ($len,16); + &jnc (&label("cbc_enc_loop")); + &add ($len,16); + &jnz (&label("cbc_enc_tail")); + &movaps ($ivec,$inout0); + &jmp (&label("cbc_ret")); + +&set_label("cbc_enc_tail"); + &mov ("ecx",$len); # zaps $rounds + &data_word(0xA4F3F689); # rep movsb + &mov ("ecx",16); # zero tail + &sub ("ecx",$len); + &xor ("eax","eax"); # zaps $len + &data_word(0xAAF3F689); # rep stosb + &lea ($out,&DWP(-16,$out)); # rewind $out by 1 block + &mov ($rounds,$rounds_); # restore $rounds + &mov ($inp,$out); # $inp and $out are the same + &mov ($key,$key_); # restore $key + &jmp (&label("cbc_enc_loop")); +###################################################################### +&set_label("cbc_decrypt",16); + &cmp ($len,0x50); + &jbe (&label("cbc_dec_tail")); + &movaps (&QWP(0,"esp"),$ivec); # save IV + &sub ($len,0x50); + &jmp (&label("cbc_dec_loop6_enter")); + +&set_label("cbc_dec_loop6",16); + &movaps (&QWP(0,"esp"),$rndkey0); # save IV + &movups (&QWP(0,$out),$inout5); + &lea ($out,&DWP(0x10,$out)); +&set_label("cbc_dec_loop6_enter"); + &movdqu ($inout0,&QWP(0,$inp)); + &movdqu ($inout1,&QWP(0x10,$inp)); + &movdqu ($inout2,&QWP(0x20,$inp)); + &movdqu ($inout3,&QWP(0x30,$inp)); + &movdqu ($inout4,&QWP(0x40,$inp)); + &movdqu ($inout5,&QWP(0x50,$inp)); + + &call ("_aesni_decrypt6"); + + &movups ($rndkey1,&QWP(0,$inp)); + &movups ($rndkey0,&QWP(0x10,$inp)); + &xorps ($inout0,&QWP(0,"esp")); # ^=IV + &xorps ($inout1,$rndkey1); + &movups ($rndkey1,&QWP(0x20,$inp)); + &xorps ($inout2,$rndkey0); + &movups ($rndkey0,&QWP(0x30,$inp)); + &xorps ($inout3,$rndkey1); + &movups ($rndkey1,&QWP(0x40,$inp)); + &xorps ($inout4,$rndkey0); + &movups ($rndkey0,&QWP(0x50,$inp)); # IV + &xorps ($inout5,$rndkey1); + &movups (&QWP(0,$out),$inout0); + &movups (&QWP(0x10,$out),$inout1); + &lea ($inp,&DWP(0x60,$inp)); + &movups (&QWP(0x20,$out),$inout2); + &mov ($rounds,$rounds_) # restore $rounds + &movups (&QWP(0x30,$out),$inout3); + &mov ($key,$key_); # restore $key + &movups (&QWP(0x40,$out),$inout4); + &lea ($out,&DWP(0x50,$out)); + &sub ($len,0x60); + &ja (&label("cbc_dec_loop6")); + + &movaps ($inout0,$inout5); + &movaps ($ivec,$rndkey0); + &add ($len,0x50); + &jle (&label("cbc_dec_tail_collected")); + &movups (&QWP(0,$out),$inout0); + &lea ($out,&DWP(0x10,$out)); +&set_label("cbc_dec_tail"); + &movups ($inout0,&QWP(0,$inp)); + &movaps ($in0,$inout0); + &cmp ($len,0x10); + &jbe (&label("cbc_dec_one")); + + &movups ($inout1,&QWP(0x10,$inp)); + &movaps ($in1,$inout1); + &cmp ($len,0x20); + &jbe (&label("cbc_dec_two")); + + &movups ($inout2,&QWP(0x20,$inp)); + &cmp ($len,0x30); + &jbe (&label("cbc_dec_three")); + + &movups ($inout3,&QWP(0x30,$inp)); + &cmp ($len,0x40); + &jbe (&label("cbc_dec_four")); + + &movups ($inout4,&QWP(0x40,$inp)); + &movaps (&QWP(0,"esp"),$ivec); # save IV + &movups ($inout0,&QWP(0,$inp)); + &xorps ($inout5,$inout5); + &call ("_aesni_decrypt6"); + &movups ($rndkey1,&QWP(0,$inp)); + &movups ($rndkey0,&QWP(0x10,$inp)); + &xorps ($inout0,&QWP(0,"esp")); # ^= IV + &xorps ($inout1,$rndkey1); + &movups ($rndkey1,&QWP(0x20,$inp)); + &xorps ($inout2,$rndkey0); + &movups ($rndkey0,&QWP(0x30,$inp)); + &xorps ($inout3,$rndkey1); + &movups ($ivec,&QWP(0x40,$inp)); # IV + &xorps ($inout4,$rndkey0); + &movups (&QWP(0,$out),$inout0); + &movups (&QWP(0x10,$out),$inout1); + &movups (&QWP(0x20,$out),$inout2); + &movups (&QWP(0x30,$out),$inout3); + &lea ($out,&DWP(0x40,$out)); + &movaps ($inout0,$inout4); + &sub ($len,0x50); + &jmp (&label("cbc_dec_tail_collected")); + +&set_label("cbc_dec_one",16); + if ($inline) + { &aesni_inline_generate1("dec"); } + else + { &call ("_aesni_decrypt1"); } + &xorps ($inout0,$ivec); + &movaps ($ivec,$in0); + &sub ($len,0x10); + &jmp (&label("cbc_dec_tail_collected")); + +&set_label("cbc_dec_two",16); + &xorps ($inout2,$inout2); + &call ("_aesni_decrypt3"); + &xorps ($inout0,$ivec); + &xorps ($inout1,$in0); + &movups (&QWP(0,$out),$inout0); + &movaps ($inout0,$inout1); + &lea ($out,&DWP(0x10,$out)); + &movaps ($ivec,$in1); + &sub ($len,0x20); + &jmp (&label("cbc_dec_tail_collected")); + +&set_label("cbc_dec_three",16); + &call ("_aesni_decrypt3"); + &xorps ($inout0,$ivec); + &xorps ($inout1,$in0); + &xorps ($inout2,$in1); + &movups (&QWP(0,$out),$inout0); + &movaps ($inout0,$inout2); + &movups (&QWP(0x10,$out),$inout1); + &lea ($out,&DWP(0x20,$out)); + &movups ($ivec,&QWP(0x20,$inp)); + &sub ($len,0x30); + &jmp (&label("cbc_dec_tail_collected")); + +&set_label("cbc_dec_four",16); + &call ("_aesni_decrypt4"); + &movups ($rndkey1,&QWP(0x10,$inp)); + &movups ($rndkey0,&QWP(0x20,$inp)); + &xorps ($inout0,$ivec); + &movups ($ivec,&QWP(0x30,$inp)); + &xorps ($inout1,$in0); + &movups (&QWP(0,$out),$inout0); + &xorps ($inout2,$rndkey1); + &movups (&QWP(0x10,$out),$inout1); + &xorps ($inout3,$rndkey0); + &movups (&QWP(0x20,$out),$inout2); + &lea ($out,&DWP(0x30,$out)); + &movaps ($inout0,$inout3); + &sub ($len,0x40); + +&set_label("cbc_dec_tail_collected"); + &and ($len,15); + &jnz (&label("cbc_dec_tail_partial")); + &movups (&QWP(0,$out),$inout0); + &jmp (&label("cbc_ret")); + +&set_label("cbc_dec_tail_partial",16); + &movaps (&QWP(0,"esp"),$inout0); + &mov ("ecx",16); + &mov ($inp,"esp"); + &sub ("ecx",$len); + &data_word(0xA4F3F689); # rep movsb + +&set_label("cbc_ret"); + &mov ("esp",&DWP(16,"esp")); # pull original %esp + &mov ($key_,&wparam(4)); + &movups (&QWP(0,$key_),$ivec); # output IV +&set_label("cbc_abort"); +&function_end("${PREFIX}_cbc_encrypt"); + +###################################################################### +# Mechanical port from aesni-x86_64.pl. +# +# _aesni_set_encrypt_key is private interface, +# input: +# "eax" const unsigned char *userKey +# $rounds int bits +# $key AES_KEY *key +# output: +# "eax" return code +# $round rounds + +&function_begin_B("_aesni_set_encrypt_key"); + &test ("eax","eax"); + &jz (&label("bad_pointer")); + &test ($key,$key); + &jz (&label("bad_pointer")); + + &movups ("xmm0",&QWP(0,"eax")); # pull first 128 bits of *userKey + &xorps ("xmm4","xmm4"); # low dword of xmm4 is assumed 0 + &lea ($key,&DWP(16,$key)); + &cmp ($rounds,256); + &je (&label("14rounds")); + &cmp ($rounds,192); + &je (&label("12rounds")); + &cmp ($rounds,128); + &jne (&label("bad_keybits")); + +&set_label("10rounds",16); + &mov ($rounds,9); + &$movekey (&QWP(-16,$key),"xmm0"); # round 0 + &aeskeygenassist("xmm1","xmm0",0x01); # round 1 + &call (&label("key_128_cold")); + &aeskeygenassist("xmm1","xmm0",0x2); # round 2 + &call (&label("key_128")); + &aeskeygenassist("xmm1","xmm0",0x04); # round 3 + &call (&label("key_128")); + &aeskeygenassist("xmm1","xmm0",0x08); # round 4 + &call (&label("key_128")); + &aeskeygenassist("xmm1","xmm0",0x10); # round 5 + &call (&label("key_128")); + &aeskeygenassist("xmm1","xmm0",0x20); # round 6 + &call (&label("key_128")); + &aeskeygenassist("xmm1","xmm0",0x40); # round 7 + &call (&label("key_128")); + &aeskeygenassist("xmm1","xmm0",0x80); # round 8 + &call (&label("key_128")); + &aeskeygenassist("xmm1","xmm0",0x1b); # round 9 + &call (&label("key_128")); + &aeskeygenassist("xmm1","xmm0",0x36); # round 10 + &call (&label("key_128")); + &$movekey (&QWP(0,$key),"xmm0"); + &mov (&DWP(80,$key),$rounds); + &xor ("eax","eax"); + &ret(); + +&set_label("key_128",16); + &$movekey (&QWP(0,$key),"xmm0"); + &lea ($key,&DWP(16,$key)); +&set_label("key_128_cold"); + &shufps ("xmm4","xmm0",0b00010000); + &xorps ("xmm0","xmm4"); + &shufps ("xmm4","xmm0",0b10001100); + &xorps ("xmm0","xmm4"); + &shufps ("xmm1","xmm1",0b11111111); # critical path + &xorps ("xmm0","xmm1"); + &ret(); + +&set_label("12rounds",16); + &movq ("xmm2",&QWP(16,"eax")); # remaining 1/3 of *userKey + &mov ($rounds,11); + &$movekey (&QWP(-16,$key),"xmm0") # round 0 + &aeskeygenassist("xmm1","xmm2",0x01); # round 1,2 + &call (&label("key_192a_cold")); + &aeskeygenassist("xmm1","xmm2",0x02); # round 2,3 + &call (&label("key_192b")); + &aeskeygenassist("xmm1","xmm2",0x04); # round 4,5 + &call (&label("key_192a")); + &aeskeygenassist("xmm1","xmm2",0x08); # round 5,6 + &call (&label("key_192b")); + &aeskeygenassist("xmm1","xmm2",0x10); # round 7,8 + &call (&label("key_192a")); + &aeskeygenassist("xmm1","xmm2",0x20); # round 8,9 + &call (&label("key_192b")); + &aeskeygenassist("xmm1","xmm2",0x40); # round 10,11 + &call (&label("key_192a")); + &aeskeygenassist("xmm1","xmm2",0x80); # round 11,12 + &call (&label("key_192b")); + &$movekey (&QWP(0,$key),"xmm0"); + &mov (&DWP(48,$key),$rounds); + &xor ("eax","eax"); + &ret(); + +&set_label("key_192a",16); + &$movekey (&QWP(0,$key),"xmm0"); + &lea ($key,&DWP(16,$key)); +&set_label("key_192a_cold",16); + &movaps ("xmm5","xmm2"); +&set_label("key_192b_warm"); + &shufps ("xmm4","xmm0",0b00010000); + &movdqa ("xmm3","xmm2"); + &xorps ("xmm0","xmm4"); + &shufps ("xmm4","xmm0",0b10001100); + &pslldq ("xmm3",4); + &xorps ("xmm0","xmm4"); + &pshufd ("xmm1","xmm1",0b01010101); # critical path + &pxor ("xmm2","xmm3"); + &pxor ("xmm0","xmm1"); + &pshufd ("xmm3","xmm0",0b11111111); + &pxor ("xmm2","xmm3"); + &ret(); + +&set_label("key_192b",16); + &movaps ("xmm3","xmm0"); + &shufps ("xmm5","xmm0",0b01000100); + &$movekey (&QWP(0,$key),"xmm5"); + &shufps ("xmm3","xmm2",0b01001110); + &$movekey (&QWP(16,$key),"xmm3"); + &lea ($key,&DWP(32,$key)); + &jmp (&label("key_192b_warm")); + +&set_label("14rounds",16); + &movups ("xmm2",&QWP(16,"eax")); # remaining half of *userKey + &mov ($rounds,13); + &lea ($key,&DWP(16,$key)); + &$movekey (&QWP(-32,$key),"xmm0"); # round 0 + &$movekey (&QWP(-16,$key),"xmm2"); # round 1 + &aeskeygenassist("xmm1","xmm2",0x01); # round 2 + &call (&label("key_256a_cold")); + &aeskeygenassist("xmm1","xmm0",0x01); # round 3 + &call (&label("key_256b")); + &aeskeygenassist("xmm1","xmm2",0x02); # round 4 + &call (&label("key_256a")); + &aeskeygenassist("xmm1","xmm0",0x02); # round 5 + &call (&label("key_256b")); + &aeskeygenassist("xmm1","xmm2",0x04); # round 6 + &call (&label("key_256a")); + &aeskeygenassist("xmm1","xmm0",0x04); # round 7 + &call (&label("key_256b")); + &aeskeygenassist("xmm1","xmm2",0x08); # round 8 + &call (&label("key_256a")); + &aeskeygenassist("xmm1","xmm0",0x08); # round 9 + &call (&label("key_256b")); + &aeskeygenassist("xmm1","xmm2",0x10); # round 10 + &call (&label("key_256a")); + &aeskeygenassist("xmm1","xmm0",0x10); # round 11 + &call (&label("key_256b")); + &aeskeygenassist("xmm1","xmm2",0x20); # round 12 + &call (&label("key_256a")); + &aeskeygenassist("xmm1","xmm0",0x20); # round 13 + &call (&label("key_256b")); + &aeskeygenassist("xmm1","xmm2",0x40); # round 14 + &call (&label("key_256a")); + &$movekey (&QWP(0,$key),"xmm0"); + &mov (&DWP(16,$key),$rounds); + &xor ("eax","eax"); + &ret(); + +&set_label("key_256a",16); + &$movekey (&QWP(0,$key),"xmm2"); + &lea ($key,&DWP(16,$key)); +&set_label("key_256a_cold"); + &shufps ("xmm4","xmm0",0b00010000); + &xorps ("xmm0","xmm4"); + &shufps ("xmm4","xmm0",0b10001100); + &xorps ("xmm0","xmm4"); + &shufps ("xmm1","xmm1",0b11111111); # critical path + &xorps ("xmm0","xmm1"); + &ret(); + +&set_label("key_256b",16); + &$movekey (&QWP(0,$key),"xmm0"); + &lea ($key,&DWP(16,$key)); + + &shufps ("xmm4","xmm2",0b00010000); + &xorps ("xmm2","xmm4"); + &shufps ("xmm4","xmm2",0b10001100); + &xorps ("xmm2","xmm4"); + &shufps ("xmm1","xmm1",0b10101010); # critical path + &xorps ("xmm2","xmm1"); + &ret(); + +&set_label("bad_pointer",4); + &mov ("eax",-1); + &ret (); +&set_label("bad_keybits",4); + &mov ("eax",-2); + &ret (); +&function_end_B("_aesni_set_encrypt_key"); + +# int $PREFIX_set_encrypt_key (const unsigned char *userKey, int bits, +# AES_KEY *key) +&function_begin_B("${PREFIX}_set_encrypt_key"); + &mov ("eax",&wparam(0)); + &mov ($rounds,&wparam(1)); + &mov ($key,&wparam(2)); + &call ("_aesni_set_encrypt_key"); + &ret (); +&function_end_B("${PREFIX}_set_encrypt_key"); + +# int $PREFIX_set_decrypt_key (const unsigned char *userKey, int bits, +# AES_KEY *key) +&function_begin_B("${PREFIX}_set_decrypt_key"); + &mov ("eax",&wparam(0)); + &mov ($rounds,&wparam(1)); + &mov ($key,&wparam(2)); + &call ("_aesni_set_encrypt_key"); + &mov ($key,&wparam(2)); + &shl ($rounds,4) # rounds-1 after _aesni_set_encrypt_key + &test ("eax","eax"); + &jnz (&label("dec_key_ret")); + &lea ("eax",&DWP(16,$key,$rounds)); # end of key schedule + + &$movekey ("xmm0",&QWP(0,$key)); # just swap + &$movekey ("xmm1",&QWP(0,"eax")); + &$movekey (&QWP(0,"eax"),"xmm0"); + &$movekey (&QWP(0,$key),"xmm1"); + &lea ($key,&DWP(16,$key)); + &lea ("eax",&DWP(-16,"eax")); + +&set_label("dec_key_inverse"); + &$movekey ("xmm0",&QWP(0,$key)); # swap and inverse + &$movekey ("xmm1",&QWP(0,"eax")); + &aesimc ("xmm0","xmm0"); + &aesimc ("xmm1","xmm1"); + &lea ($key,&DWP(16,$key)); + &lea ("eax",&DWP(-16,"eax")); + &$movekey (&QWP(16,"eax"),"xmm0"); + &$movekey (&QWP(-16,$key),"xmm1"); + &cmp ("eax",$key); + &ja (&label("dec_key_inverse")); + + &$movekey ("xmm0",&QWP(0,$key)); # inverse middle + &aesimc ("xmm0","xmm0"); + &$movekey (&QWP(0,$key),"xmm0"); + + &xor ("eax","eax"); # return success +&set_label("dec_key_ret"); + &ret (); +&function_end_B("${PREFIX}_set_decrypt_key"); +&asciz("AES for Intel AES-NI, CRYPTOGAMS by "); + +&asm_finish(); diff --git a/libs/openssl/crypto/aes/asm/aesni-x86_64.pl b/libs/openssl/crypto/aes/asm/aesni-x86_64.pl new file mode 100644 index 00000000..c9270dfd --- /dev/null +++ b/libs/openssl/crypto/aes/asm/aesni-x86_64.pl @@ -0,0 +1,3071 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# This module implements support for Intel AES-NI extension. In +# OpenSSL context it's used with Intel engine, but can also be used as +# drop-in replacement for crypto/aes/asm/aes-x86_64.pl [see below for +# details]. +# +# Performance. +# +# Given aes(enc|dec) instructions' latency asymptotic performance for +# non-parallelizable modes such as CBC encrypt is 3.75 cycles per byte +# processed with 128-bit key. And given their throughput asymptotic +# performance for parallelizable modes is 1.25 cycles per byte. Being +# asymptotic limit it's not something you commonly achieve in reality, +# but how close does one get? Below are results collected for +# different modes and block sized. Pairs of numbers are for en-/ +# decryption. +# +# 16-byte 64-byte 256-byte 1-KB 8-KB +# ECB 4.25/4.25 1.38/1.38 1.28/1.28 1.26/1.26 1.26/1.26 +# CTR 5.42/5.42 1.92/1.92 1.44/1.44 1.28/1.28 1.26/1.26 +# CBC 4.38/4.43 4.15/1.43 4.07/1.32 4.07/1.29 4.06/1.28 +# CCM 5.66/9.42 4.42/5.41 4.16/4.40 4.09/4.15 4.06/4.07 +# OFB 5.42/5.42 4.64/4.64 4.44/4.44 4.39/4.39 4.38/4.38 +# CFB 5.73/5.85 5.56/5.62 5.48/5.56 5.47/5.55 5.47/5.55 +# +# ECB, CTR, CBC and CCM results are free from EVP overhead. This means +# that otherwise used 'openssl speed -evp aes-128-??? -engine aesni +# [-decrypt]' will exhibit 10-15% worse results for smaller blocks. +# The results were collected with specially crafted speed.c benchmark +# in order to compare them with results reported in "Intel Advanced +# Encryption Standard (AES) New Instruction Set" White Paper Revision +# 3.0 dated May 2010. All above results are consistently better. This +# module also provides better performance for block sizes smaller than +# 128 bytes in points *not* represented in the above table. +# +# Looking at the results for 8-KB buffer. +# +# CFB and OFB results are far from the limit, because implementation +# uses "generic" CRYPTO_[c|o]fb128_encrypt interfaces relying on +# single-block aesni_encrypt, which is not the most optimal way to go. +# CBC encrypt result is unexpectedly high and there is no documented +# explanation for it. Seemingly there is a small penalty for feeding +# the result back to AES unit the way it's done in CBC mode. There is +# nothing one can do and the result appears optimal. CCM result is +# identical to CBC, because CBC-MAC is essentially CBC encrypt without +# saving output. CCM CTR "stays invisible," because it's neatly +# interleaved wih CBC-MAC. This provides ~30% improvement over +# "straghtforward" CCM implementation with CTR and CBC-MAC performed +# disjointly. Parallelizable modes practically achieve the theoretical +# limit. +# +# Looking at how results vary with buffer size. +# +# Curves are practically saturated at 1-KB buffer size. In most cases +# "256-byte" performance is >95%, and "64-byte" is ~90% of "8-KB" one. +# CTR curve doesn't follow this pattern and is "slowest" changing one +# with "256-byte" result being 87% of "8-KB." This is because overhead +# in CTR mode is most computationally intensive. Small-block CCM +# decrypt is slower than encrypt, because first CTR and last CBC-MAC +# iterations can't be interleaved. +# +# Results for 192- and 256-bit keys. +# +# EVP-free results were observed to scale perfectly with number of +# rounds for larger block sizes, i.e. 192-bit result being 10/12 times +# lower and 256-bit one - 10/14. Well, in CBC encrypt case differences +# are a tad smaller, because the above mentioned penalty biases all +# results by same constant value. In similar way function call +# overhead affects small-block performance, as well as OFB and CFB +# results. Differences are not large, most common coefficients are +# 10/11.7 and 10/13.4 (as opposite to 10/12.0 and 10/14.0), but one +# observe even 10/11.2 and 10/12.4 (CTR, OFB, CFB)... + +# January 2011 +# +# While Westmere processor features 6 cycles latency for aes[enc|dec] +# instructions, which can be scheduled every second cycle, Sandy +# Bridge spends 8 cycles per instruction, but it can schedule them +# every cycle. This means that code targeting Westmere would perform +# suboptimally on Sandy Bridge. Therefore this update. +# +# In addition, non-parallelizable CBC encrypt (as well as CCM) is +# optimized. Relative improvement might appear modest, 8% on Westmere, +# but in absolute terms it's 3.77 cycles per byte encrypted with +# 128-bit key on Westmere, and 5.07 - on Sandy Bridge. These numbers +# should be compared to asymptotic limits of 3.75 for Westmere and +# 5.00 for Sandy Bridge. Actually, the fact that they get this close +# to asymptotic limits is quite amazing. Indeed, the limit is +# calculated as latency times number of rounds, 10 for 128-bit key, +# and divided by 16, the number of bytes in block, or in other words +# it accounts *solely* for aesenc instructions. But there are extra +# instructions, and numbers so close to the asymptotic limits mean +# that it's as if it takes as little as *one* additional cycle to +# execute all of them. How is it possible? It is possible thanks to +# out-of-order execution logic, which manages to overlap post- +# processing of previous block, things like saving the output, with +# actual encryption of current block, as well as pre-processing of +# current block, things like fetching input and xor-ing it with +# 0-round element of the key schedule, with actual encryption of +# previous block. Keep this in mind... +# +# For parallelizable modes, such as ECB, CBC decrypt, CTR, higher +# performance is achieved by interleaving instructions working on +# independent blocks. In which case asymptotic limit for such modes +# can be obtained by dividing above mentioned numbers by AES +# instructions' interleave factor. Westmere can execute at most 3 +# instructions at a time, meaning that optimal interleave factor is 3, +# and that's where the "magic" number of 1.25 come from. "Optimal +# interleave factor" means that increase of interleave factor does +# not improve performance. The formula has proven to reflect reality +# pretty well on Westmere... Sandy Bridge on the other hand can +# execute up to 8 AES instructions at a time, so how does varying +# interleave factor affect the performance? Here is table for ECB +# (numbers are cycles per byte processed with 128-bit key): +# +# instruction interleave factor 3x 6x 8x +# theoretical asymptotic limit 1.67 0.83 0.625 +# measured performance for 8KB block 1.05 0.86 0.84 +# +# "as if" interleave factor 4.7x 5.8x 6.0x +# +# Further data for other parallelizable modes: +# +# CBC decrypt 1.16 0.93 0.93 +# CTR 1.14 0.91 n/a +# +# Well, given 3x column it's probably inappropriate to call the limit +# asymptotic, if it can be surpassed, isn't it? What happens there? +# Rewind to CBC paragraph for the answer. Yes, out-of-order execution +# magic is responsible for this. Processor overlaps not only the +# additional instructions with AES ones, but even AES instuctions +# processing adjacent triplets of independent blocks. In the 6x case +# additional instructions still claim disproportionally small amount +# of additional cycles, but in 8x case number of instructions must be +# a tad too high for out-of-order logic to cope with, and AES unit +# remains underutilized... As you can see 8x interleave is hardly +# justifiable, so there no need to feel bad that 32-bit aesni-x86.pl +# utilizies 6x interleave because of limited register bank capacity. +# +# Higher interleave factors do have negative impact on Westmere +# performance. While for ECB mode it's negligible ~1.5%, other +# parallelizables perform ~5% worse, which is outweighed by ~25% +# improvement on Sandy Bridge. To balance regression on Westmere +# CTR mode was implemented with 6x aesenc interleave factor. + +# April 2011 +# +# Add aesni_xts_[en|de]crypt. Westmere spends 1.33 cycles processing +# one byte out of 8KB with 128-bit key, Sandy Bridge - 0.97. Just like +# in CTR mode AES instruction interleave factor was chosen to be 6x. + +$PREFIX="aesni"; # if $PREFIX is set to "AES", the script + # generates drop-in replacement for + # crypto/aes/asm/aes-x86_64.pl:-) + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +$movkey = $PREFIX eq "aesni" ? "movups" : "movups"; +@_4args=$win64? ("%rcx","%rdx","%r8", "%r9") : # Win64 order + ("%rdi","%rsi","%rdx","%rcx"); # Unix order + +$code=".text\n"; + +$rounds="%eax"; # input to and changed by aesni_[en|de]cryptN !!! +# this is natural Unix argument order for public $PREFIX_[ecb|cbc]_encrypt ... +$inp="%rdi"; +$out="%rsi"; +$len="%rdx"; +$key="%rcx"; # input to and changed by aesni_[en|de]cryptN !!! +$ivp="%r8"; # cbc, ctr, ... + +$rnds_="%r10d"; # backup copy for $rounds +$key_="%r11"; # backup copy for $key + +# %xmm register layout +$rndkey0="%xmm0"; $rndkey1="%xmm1"; +$inout0="%xmm2"; $inout1="%xmm3"; +$inout2="%xmm4"; $inout3="%xmm5"; +$inout4="%xmm6"; $inout5="%xmm7"; +$inout6="%xmm8"; $inout7="%xmm9"; + +$in2="%xmm6"; $in1="%xmm7"; # used in CBC decrypt, CTR, ... +$in0="%xmm8"; $iv="%xmm9"; + +# Inline version of internal aesni_[en|de]crypt1. +# +# Why folded loop? Because aes[enc|dec] is slow enough to accommodate +# cycles which take care of loop variables... +{ my $sn; +sub aesni_generate1 { +my ($p,$key,$rounds,$inout,$ivec)=@_; $inout=$inout0 if (!defined($inout)); +++$sn; +$code.=<<___; + $movkey ($key),$rndkey0 + $movkey 16($key),$rndkey1 +___ +$code.=<<___ if (defined($ivec)); + xorps $rndkey0,$ivec + lea 32($key),$key + xorps $ivec,$inout +___ +$code.=<<___ if (!defined($ivec)); + lea 32($key),$key + xorps $rndkey0,$inout +___ +$code.=<<___; +.Loop_${p}1_$sn: + aes${p} $rndkey1,$inout + dec $rounds + $movkey ($key),$rndkey1 + lea 16($key),$key + jnz .Loop_${p}1_$sn # loop body is 16 bytes + aes${p}last $rndkey1,$inout +___ +}} +# void $PREFIX_[en|de]crypt (const void *inp,void *out,const AES_KEY *key); +# +{ my ($inp,$out,$key) = @_4args; + +$code.=<<___; +.globl ${PREFIX}_encrypt +.type ${PREFIX}_encrypt,\@abi-omnipotent +.align 16 +${PREFIX}_encrypt: + movups ($inp),$inout0 # load input + mov 240($key),$rounds # key->rounds +___ + &aesni_generate1("enc",$key,$rounds); +$code.=<<___; + movups $inout0,($out) # output + ret +.size ${PREFIX}_encrypt,.-${PREFIX}_encrypt + +.globl ${PREFIX}_decrypt +.type ${PREFIX}_decrypt,\@abi-omnipotent +.align 16 +${PREFIX}_decrypt: + movups ($inp),$inout0 # load input + mov 240($key),$rounds # key->rounds +___ + &aesni_generate1("dec",$key,$rounds); +$code.=<<___; + movups $inout0,($out) # output + ret +.size ${PREFIX}_decrypt, .-${PREFIX}_decrypt +___ +} + +# _aesni_[en|de]cryptN are private interfaces, N denotes interleave +# factor. Why 3x subroutine were originally used in loops? Even though +# aes[enc|dec] latency was originally 6, it could be scheduled only +# every *2nd* cycle. Thus 3x interleave was the one providing optimal +# utilization, i.e. when subroutine's throughput is virtually same as +# of non-interleaved subroutine [for number of input blocks up to 3]. +# This is why it makes no sense to implement 2x subroutine. +# aes[enc|dec] latency in next processor generation is 8, but the +# instructions can be scheduled every cycle. Optimal interleave for +# new processor is therefore 8x... +sub aesni_generate3 { +my $dir=shift; +# As already mentioned it takes in $key and $rounds, which are *not* +# preserved. $inout[0-2] is cipher/clear text... +$code.=<<___; +.type _aesni_${dir}rypt3,\@abi-omnipotent +.align 16 +_aesni_${dir}rypt3: + $movkey ($key),$rndkey0 + shr \$1,$rounds + $movkey 16($key),$rndkey1 + lea 32($key),$key + xorps $rndkey0,$inout0 + xorps $rndkey0,$inout1 + xorps $rndkey0,$inout2 + $movkey ($key),$rndkey0 + +.L${dir}_loop3: + aes${dir} $rndkey1,$inout0 + aes${dir} $rndkey1,$inout1 + dec $rounds + aes${dir} $rndkey1,$inout2 + $movkey 16($key),$rndkey1 + aes${dir} $rndkey0,$inout0 + aes${dir} $rndkey0,$inout1 + lea 32($key),$key + aes${dir} $rndkey0,$inout2 + $movkey ($key),$rndkey0 + jnz .L${dir}_loop3 + + aes${dir} $rndkey1,$inout0 + aes${dir} $rndkey1,$inout1 + aes${dir} $rndkey1,$inout2 + aes${dir}last $rndkey0,$inout0 + aes${dir}last $rndkey0,$inout1 + aes${dir}last $rndkey0,$inout2 + ret +.size _aesni_${dir}rypt3,.-_aesni_${dir}rypt3 +___ +} +# 4x interleave is implemented to improve small block performance, +# most notably [and naturally] 4 block by ~30%. One can argue that one +# should have implemented 5x as well, but improvement would be <20%, +# so it's not worth it... +sub aesni_generate4 { +my $dir=shift; +# As already mentioned it takes in $key and $rounds, which are *not* +# preserved. $inout[0-3] is cipher/clear text... +$code.=<<___; +.type _aesni_${dir}rypt4,\@abi-omnipotent +.align 16 +_aesni_${dir}rypt4: + $movkey ($key),$rndkey0 + shr \$1,$rounds + $movkey 16($key),$rndkey1 + lea 32($key),$key + xorps $rndkey0,$inout0 + xorps $rndkey0,$inout1 + xorps $rndkey0,$inout2 + xorps $rndkey0,$inout3 + $movkey ($key),$rndkey0 + +.L${dir}_loop4: + aes${dir} $rndkey1,$inout0 + aes${dir} $rndkey1,$inout1 + dec $rounds + aes${dir} $rndkey1,$inout2 + aes${dir} $rndkey1,$inout3 + $movkey 16($key),$rndkey1 + aes${dir} $rndkey0,$inout0 + aes${dir} $rndkey0,$inout1 + lea 32($key),$key + aes${dir} $rndkey0,$inout2 + aes${dir} $rndkey0,$inout3 + $movkey ($key),$rndkey0 + jnz .L${dir}_loop4 + + aes${dir} $rndkey1,$inout0 + aes${dir} $rndkey1,$inout1 + aes${dir} $rndkey1,$inout2 + aes${dir} $rndkey1,$inout3 + aes${dir}last $rndkey0,$inout0 + aes${dir}last $rndkey0,$inout1 + aes${dir}last $rndkey0,$inout2 + aes${dir}last $rndkey0,$inout3 + ret +.size _aesni_${dir}rypt4,.-_aesni_${dir}rypt4 +___ +} +sub aesni_generate6 { +my $dir=shift; +# As already mentioned it takes in $key and $rounds, which are *not* +# preserved. $inout[0-5] is cipher/clear text... +$code.=<<___; +.type _aesni_${dir}rypt6,\@abi-omnipotent +.align 16 +_aesni_${dir}rypt6: + $movkey ($key),$rndkey0 + shr \$1,$rounds + $movkey 16($key),$rndkey1 + lea 32($key),$key + xorps $rndkey0,$inout0 + pxor $rndkey0,$inout1 + aes${dir} $rndkey1,$inout0 + pxor $rndkey0,$inout2 + aes${dir} $rndkey1,$inout1 + pxor $rndkey0,$inout3 + aes${dir} $rndkey1,$inout2 + pxor $rndkey0,$inout4 + aes${dir} $rndkey1,$inout3 + pxor $rndkey0,$inout5 + dec $rounds + aes${dir} $rndkey1,$inout4 + $movkey ($key),$rndkey0 + aes${dir} $rndkey1,$inout5 + jmp .L${dir}_loop6_enter +.align 16 +.L${dir}_loop6: + aes${dir} $rndkey1,$inout0 + aes${dir} $rndkey1,$inout1 + dec $rounds + aes${dir} $rndkey1,$inout2 + aes${dir} $rndkey1,$inout3 + aes${dir} $rndkey1,$inout4 + aes${dir} $rndkey1,$inout5 +.L${dir}_loop6_enter: # happens to be 16-byte aligned + $movkey 16($key),$rndkey1 + aes${dir} $rndkey0,$inout0 + aes${dir} $rndkey0,$inout1 + lea 32($key),$key + aes${dir} $rndkey0,$inout2 + aes${dir} $rndkey0,$inout3 + aes${dir} $rndkey0,$inout4 + aes${dir} $rndkey0,$inout5 + $movkey ($key),$rndkey0 + jnz .L${dir}_loop6 + + aes${dir} $rndkey1,$inout0 + aes${dir} $rndkey1,$inout1 + aes${dir} $rndkey1,$inout2 + aes${dir} $rndkey1,$inout3 + aes${dir} $rndkey1,$inout4 + aes${dir} $rndkey1,$inout5 + aes${dir}last $rndkey0,$inout0 + aes${dir}last $rndkey0,$inout1 + aes${dir}last $rndkey0,$inout2 + aes${dir}last $rndkey0,$inout3 + aes${dir}last $rndkey0,$inout4 + aes${dir}last $rndkey0,$inout5 + ret +.size _aesni_${dir}rypt6,.-_aesni_${dir}rypt6 +___ +} +sub aesni_generate8 { +my $dir=shift; +# As already mentioned it takes in $key and $rounds, which are *not* +# preserved. $inout[0-7] is cipher/clear text... +$code.=<<___; +.type _aesni_${dir}rypt8,\@abi-omnipotent +.align 16 +_aesni_${dir}rypt8: + $movkey ($key),$rndkey0 + shr \$1,$rounds + $movkey 16($key),$rndkey1 + lea 32($key),$key + xorps $rndkey0,$inout0 + xorps $rndkey0,$inout1 + aes${dir} $rndkey1,$inout0 + pxor $rndkey0,$inout2 + aes${dir} $rndkey1,$inout1 + pxor $rndkey0,$inout3 + aes${dir} $rndkey1,$inout2 + pxor $rndkey0,$inout4 + aes${dir} $rndkey1,$inout3 + pxor $rndkey0,$inout5 + dec $rounds + aes${dir} $rndkey1,$inout4 + pxor $rndkey0,$inout6 + aes${dir} $rndkey1,$inout5 + pxor $rndkey0,$inout7 + $movkey ($key),$rndkey0 + aes${dir} $rndkey1,$inout6 + aes${dir} $rndkey1,$inout7 + $movkey 16($key),$rndkey1 + jmp .L${dir}_loop8_enter +.align 16 +.L${dir}_loop8: + aes${dir} $rndkey1,$inout0 + aes${dir} $rndkey1,$inout1 + dec $rounds + aes${dir} $rndkey1,$inout2 + aes${dir} $rndkey1,$inout3 + aes${dir} $rndkey1,$inout4 + aes${dir} $rndkey1,$inout5 + aes${dir} $rndkey1,$inout6 + aes${dir} $rndkey1,$inout7 + $movkey 16($key),$rndkey1 +.L${dir}_loop8_enter: # happens to be 16-byte aligned + aes${dir} $rndkey0,$inout0 + aes${dir} $rndkey0,$inout1 + lea 32($key),$key + aes${dir} $rndkey0,$inout2 + aes${dir} $rndkey0,$inout3 + aes${dir} $rndkey0,$inout4 + aes${dir} $rndkey0,$inout5 + aes${dir} $rndkey0,$inout6 + aes${dir} $rndkey0,$inout7 + $movkey ($key),$rndkey0 + jnz .L${dir}_loop8 + + aes${dir} $rndkey1,$inout0 + aes${dir} $rndkey1,$inout1 + aes${dir} $rndkey1,$inout2 + aes${dir} $rndkey1,$inout3 + aes${dir} $rndkey1,$inout4 + aes${dir} $rndkey1,$inout5 + aes${dir} $rndkey1,$inout6 + aes${dir} $rndkey1,$inout7 + aes${dir}last $rndkey0,$inout0 + aes${dir}last $rndkey0,$inout1 + aes${dir}last $rndkey0,$inout2 + aes${dir}last $rndkey0,$inout3 + aes${dir}last $rndkey0,$inout4 + aes${dir}last $rndkey0,$inout5 + aes${dir}last $rndkey0,$inout6 + aes${dir}last $rndkey0,$inout7 + ret +.size _aesni_${dir}rypt8,.-_aesni_${dir}rypt8 +___ +} +&aesni_generate3("enc") if ($PREFIX eq "aesni"); +&aesni_generate3("dec"); +&aesni_generate4("enc") if ($PREFIX eq "aesni"); +&aesni_generate4("dec"); +&aesni_generate6("enc") if ($PREFIX eq "aesni"); +&aesni_generate6("dec"); +&aesni_generate8("enc") if ($PREFIX eq "aesni"); +&aesni_generate8("dec"); + +if ($PREFIX eq "aesni") { +######################################################################## +# void aesni_ecb_encrypt (const void *in, void *out, +# size_t length, const AES_KEY *key, +# int enc); +$code.=<<___; +.globl aesni_ecb_encrypt +.type aesni_ecb_encrypt,\@function,5 +.align 16 +aesni_ecb_encrypt: +___ +$code.=<<___ if ($win64); + lea -0x58(%rsp),%rsp + movaps %xmm6,(%rsp) + movaps %xmm7,0x10(%rsp) + movaps %xmm8,0x20(%rsp) + movaps %xmm9,0x30(%rsp) +.Lecb_enc_body: +___ +$code.=<<___; + and \$-16,$len + jz .Lecb_ret + + mov 240($key),$rounds # key->rounds + $movkey ($key),$rndkey0 + mov $key,$key_ # backup $key + mov $rounds,$rnds_ # backup $rounds + test %r8d,%r8d # 5th argument + jz .Lecb_decrypt +#--------------------------- ECB ENCRYPT ------------------------------# + cmp \$0x80,$len + jb .Lecb_enc_tail + + movdqu ($inp),$inout0 + movdqu 0x10($inp),$inout1 + movdqu 0x20($inp),$inout2 + movdqu 0x30($inp),$inout3 + movdqu 0x40($inp),$inout4 + movdqu 0x50($inp),$inout5 + movdqu 0x60($inp),$inout6 + movdqu 0x70($inp),$inout7 + lea 0x80($inp),$inp + sub \$0x80,$len + jmp .Lecb_enc_loop8_enter +.align 16 +.Lecb_enc_loop8: + movups $inout0,($out) + mov $key_,$key # restore $key + movdqu ($inp),$inout0 + mov $rnds_,$rounds # restore $rounds + movups $inout1,0x10($out) + movdqu 0x10($inp),$inout1 + movups $inout2,0x20($out) + movdqu 0x20($inp),$inout2 + movups $inout3,0x30($out) + movdqu 0x30($inp),$inout3 + movups $inout4,0x40($out) + movdqu 0x40($inp),$inout4 + movups $inout5,0x50($out) + movdqu 0x50($inp),$inout5 + movups $inout6,0x60($out) + movdqu 0x60($inp),$inout6 + movups $inout7,0x70($out) + lea 0x80($out),$out + movdqu 0x70($inp),$inout7 + lea 0x80($inp),$inp +.Lecb_enc_loop8_enter: + + call _aesni_encrypt8 + + sub \$0x80,$len + jnc .Lecb_enc_loop8 + + movups $inout0,($out) + mov $key_,$key # restore $key + movups $inout1,0x10($out) + mov $rnds_,$rounds # restore $rounds + movups $inout2,0x20($out) + movups $inout3,0x30($out) + movups $inout4,0x40($out) + movups $inout5,0x50($out) + movups $inout6,0x60($out) + movups $inout7,0x70($out) + lea 0x80($out),$out + add \$0x80,$len + jz .Lecb_ret + +.Lecb_enc_tail: + movups ($inp),$inout0 + cmp \$0x20,$len + jb .Lecb_enc_one + movups 0x10($inp),$inout1 + je .Lecb_enc_two + movups 0x20($inp),$inout2 + cmp \$0x40,$len + jb .Lecb_enc_three + movups 0x30($inp),$inout3 + je .Lecb_enc_four + movups 0x40($inp),$inout4 + cmp \$0x60,$len + jb .Lecb_enc_five + movups 0x50($inp),$inout5 + je .Lecb_enc_six + movdqu 0x60($inp),$inout6 + call _aesni_encrypt8 + movups $inout0,($out) + movups $inout1,0x10($out) + movups $inout2,0x20($out) + movups $inout3,0x30($out) + movups $inout4,0x40($out) + movups $inout5,0x50($out) + movups $inout6,0x60($out) + jmp .Lecb_ret +.align 16 +.Lecb_enc_one: +___ + &aesni_generate1("enc",$key,$rounds); +$code.=<<___; + movups $inout0,($out) + jmp .Lecb_ret +.align 16 +.Lecb_enc_two: + xorps $inout2,$inout2 + call _aesni_encrypt3 + movups $inout0,($out) + movups $inout1,0x10($out) + jmp .Lecb_ret +.align 16 +.Lecb_enc_three: + call _aesni_encrypt3 + movups $inout0,($out) + movups $inout1,0x10($out) + movups $inout2,0x20($out) + jmp .Lecb_ret +.align 16 +.Lecb_enc_four: + call _aesni_encrypt4 + movups $inout0,($out) + movups $inout1,0x10($out) + movups $inout2,0x20($out) + movups $inout3,0x30($out) + jmp .Lecb_ret +.align 16 +.Lecb_enc_five: + xorps $inout5,$inout5 + call _aesni_encrypt6 + movups $inout0,($out) + movups $inout1,0x10($out) + movups $inout2,0x20($out) + movups $inout3,0x30($out) + movups $inout4,0x40($out) + jmp .Lecb_ret +.align 16 +.Lecb_enc_six: + call _aesni_encrypt6 + movups $inout0,($out) + movups $inout1,0x10($out) + movups $inout2,0x20($out) + movups $inout3,0x30($out) + movups $inout4,0x40($out) + movups $inout5,0x50($out) + jmp .Lecb_ret + #--------------------------- ECB DECRYPT ------------------------------# +.align 16 +.Lecb_decrypt: + cmp \$0x80,$len + jb .Lecb_dec_tail + + movdqu ($inp),$inout0 + movdqu 0x10($inp),$inout1 + movdqu 0x20($inp),$inout2 + movdqu 0x30($inp),$inout3 + movdqu 0x40($inp),$inout4 + movdqu 0x50($inp),$inout5 + movdqu 0x60($inp),$inout6 + movdqu 0x70($inp),$inout7 + lea 0x80($inp),$inp + sub \$0x80,$len + jmp .Lecb_dec_loop8_enter +.align 16 +.Lecb_dec_loop8: + movups $inout0,($out) + mov $key_,$key # restore $key + movdqu ($inp),$inout0 + mov $rnds_,$rounds # restore $rounds + movups $inout1,0x10($out) + movdqu 0x10($inp),$inout1 + movups $inout2,0x20($out) + movdqu 0x20($inp),$inout2 + movups $inout3,0x30($out) + movdqu 0x30($inp),$inout3 + movups $inout4,0x40($out) + movdqu 0x40($inp),$inout4 + movups $inout5,0x50($out) + movdqu 0x50($inp),$inout5 + movups $inout6,0x60($out) + movdqu 0x60($inp),$inout6 + movups $inout7,0x70($out) + lea 0x80($out),$out + movdqu 0x70($inp),$inout7 + lea 0x80($inp),$inp +.Lecb_dec_loop8_enter: + + call _aesni_decrypt8 + + $movkey ($key_),$rndkey0 + sub \$0x80,$len + jnc .Lecb_dec_loop8 + + movups $inout0,($out) + mov $key_,$key # restore $key + movups $inout1,0x10($out) + mov $rnds_,$rounds # restore $rounds + movups $inout2,0x20($out) + movups $inout3,0x30($out) + movups $inout4,0x40($out) + movups $inout5,0x50($out) + movups $inout6,0x60($out) + movups $inout7,0x70($out) + lea 0x80($out),$out + add \$0x80,$len + jz .Lecb_ret + +.Lecb_dec_tail: + movups ($inp),$inout0 + cmp \$0x20,$len + jb .Lecb_dec_one + movups 0x10($inp),$inout1 + je .Lecb_dec_two + movups 0x20($inp),$inout2 + cmp \$0x40,$len + jb .Lecb_dec_three + movups 0x30($inp),$inout3 + je .Lecb_dec_four + movups 0x40($inp),$inout4 + cmp \$0x60,$len + jb .Lecb_dec_five + movups 0x50($inp),$inout5 + je .Lecb_dec_six + movups 0x60($inp),$inout6 + $movkey ($key),$rndkey0 + call _aesni_decrypt8 + movups $inout0,($out) + movups $inout1,0x10($out) + movups $inout2,0x20($out) + movups $inout3,0x30($out) + movups $inout4,0x40($out) + movups $inout5,0x50($out) + movups $inout6,0x60($out) + jmp .Lecb_ret +.align 16 +.Lecb_dec_one: +___ + &aesni_generate1("dec",$key,$rounds); +$code.=<<___; + movups $inout0,($out) + jmp .Lecb_ret +.align 16 +.Lecb_dec_two: + xorps $inout2,$inout2 + call _aesni_decrypt3 + movups $inout0,($out) + movups $inout1,0x10($out) + jmp .Lecb_ret +.align 16 +.Lecb_dec_three: + call _aesni_decrypt3 + movups $inout0,($out) + movups $inout1,0x10($out) + movups $inout2,0x20($out) + jmp .Lecb_ret +.align 16 +.Lecb_dec_four: + call _aesni_decrypt4 + movups $inout0,($out) + movups $inout1,0x10($out) + movups $inout2,0x20($out) + movups $inout3,0x30($out) + jmp .Lecb_ret +.align 16 +.Lecb_dec_five: + xorps $inout5,$inout5 + call _aesni_decrypt6 + movups $inout0,($out) + movups $inout1,0x10($out) + movups $inout2,0x20($out) + movups $inout3,0x30($out) + movups $inout4,0x40($out) + jmp .Lecb_ret +.align 16 +.Lecb_dec_six: + call _aesni_decrypt6 + movups $inout0,($out) + movups $inout1,0x10($out) + movups $inout2,0x20($out) + movups $inout3,0x30($out) + movups $inout4,0x40($out) + movups $inout5,0x50($out) + +.Lecb_ret: +___ +$code.=<<___ if ($win64); + movaps (%rsp),%xmm6 + movaps 0x10(%rsp),%xmm7 + movaps 0x20(%rsp),%xmm8 + movaps 0x30(%rsp),%xmm9 + lea 0x58(%rsp),%rsp +.Lecb_enc_ret: +___ +$code.=<<___; + ret +.size aesni_ecb_encrypt,.-aesni_ecb_encrypt +___ + +{ +###################################################################### +# void aesni_ccm64_[en|de]crypt_blocks (const void *in, void *out, +# size_t blocks, const AES_KEY *key, +# const char *ivec,char *cmac); +# +# Handles only complete blocks, operates on 64-bit counter and +# does not update *ivec! Nor does it finalize CMAC value +# (see engine/eng_aesni.c for details) +# +{ +my $cmac="%r9"; # 6th argument + +my $increment="%xmm6"; +my $bswap_mask="%xmm7"; + +$code.=<<___; +.globl aesni_ccm64_encrypt_blocks +.type aesni_ccm64_encrypt_blocks,\@function,6 +.align 16 +aesni_ccm64_encrypt_blocks: +___ +$code.=<<___ if ($win64); + lea -0x58(%rsp),%rsp + movaps %xmm6,(%rsp) + movaps %xmm7,0x10(%rsp) + movaps %xmm8,0x20(%rsp) + movaps %xmm9,0x30(%rsp) +.Lccm64_enc_body: +___ +$code.=<<___; + mov 240($key),$rounds # key->rounds + movdqu ($ivp),$iv + movdqa .Lincrement64(%rip),$increment + movdqa .Lbswap_mask(%rip),$bswap_mask + + shr \$1,$rounds + lea 0($key),$key_ + movdqu ($cmac),$inout1 + movdqa $iv,$inout0 + mov $rounds,$rnds_ + pshufb $bswap_mask,$iv + jmp .Lccm64_enc_outer +.align 16 +.Lccm64_enc_outer: + $movkey ($key_),$rndkey0 + mov $rnds_,$rounds + movups ($inp),$in0 # load inp + + xorps $rndkey0,$inout0 # counter + $movkey 16($key_),$rndkey1 + xorps $in0,$rndkey0 + lea 32($key_),$key + xorps $rndkey0,$inout1 # cmac^=inp + $movkey ($key),$rndkey0 + +.Lccm64_enc2_loop: + aesenc $rndkey1,$inout0 + dec $rounds + aesenc $rndkey1,$inout1 + $movkey 16($key),$rndkey1 + aesenc $rndkey0,$inout0 + lea 32($key),$key + aesenc $rndkey0,$inout1 + $movkey 0($key),$rndkey0 + jnz .Lccm64_enc2_loop + aesenc $rndkey1,$inout0 + aesenc $rndkey1,$inout1 + paddq $increment,$iv + aesenclast $rndkey0,$inout0 + aesenclast $rndkey0,$inout1 + + dec $len + lea 16($inp),$inp + xorps $inout0,$in0 # inp ^= E(iv) + movdqa $iv,$inout0 + movups $in0,($out) # save output + lea 16($out),$out + pshufb $bswap_mask,$inout0 + jnz .Lccm64_enc_outer + + movups $inout1,($cmac) +___ +$code.=<<___ if ($win64); + movaps (%rsp),%xmm6 + movaps 0x10(%rsp),%xmm7 + movaps 0x20(%rsp),%xmm8 + movaps 0x30(%rsp),%xmm9 + lea 0x58(%rsp),%rsp +.Lccm64_enc_ret: +___ +$code.=<<___; + ret +.size aesni_ccm64_encrypt_blocks,.-aesni_ccm64_encrypt_blocks +___ +###################################################################### +$code.=<<___; +.globl aesni_ccm64_decrypt_blocks +.type aesni_ccm64_decrypt_blocks,\@function,6 +.align 16 +aesni_ccm64_decrypt_blocks: +___ +$code.=<<___ if ($win64); + lea -0x58(%rsp),%rsp + movaps %xmm6,(%rsp) + movaps %xmm7,0x10(%rsp) + movaps %xmm8,0x20(%rsp) + movaps %xmm9,0x30(%rsp) +.Lccm64_dec_body: +___ +$code.=<<___; + mov 240($key),$rounds # key->rounds + movups ($ivp),$iv + movdqu ($cmac),$inout1 + movdqa .Lincrement64(%rip),$increment + movdqa .Lbswap_mask(%rip),$bswap_mask + + movaps $iv,$inout0 + mov $rounds,$rnds_ + mov $key,$key_ + pshufb $bswap_mask,$iv +___ + &aesni_generate1("enc",$key,$rounds); +$code.=<<___; + movups ($inp),$in0 # load inp + paddq $increment,$iv + lea 16($inp),$inp + jmp .Lccm64_dec_outer +.align 16 +.Lccm64_dec_outer: + xorps $inout0,$in0 # inp ^= E(iv) + movdqa $iv,$inout0 + mov $rnds_,$rounds + movups $in0,($out) # save output + lea 16($out),$out + pshufb $bswap_mask,$inout0 + + sub \$1,$len + jz .Lccm64_dec_break + + $movkey ($key_),$rndkey0 + shr \$1,$rounds + $movkey 16($key_),$rndkey1 + xorps $rndkey0,$in0 + lea 32($key_),$key + xorps $rndkey0,$inout0 + xorps $in0,$inout1 # cmac^=out + $movkey ($key),$rndkey0 + +.Lccm64_dec2_loop: + aesenc $rndkey1,$inout0 + dec $rounds + aesenc $rndkey1,$inout1 + $movkey 16($key),$rndkey1 + aesenc $rndkey0,$inout0 + lea 32($key),$key + aesenc $rndkey0,$inout1 + $movkey 0($key),$rndkey0 + jnz .Lccm64_dec2_loop + movups ($inp),$in0 # load inp + paddq $increment,$iv + aesenc $rndkey1,$inout0 + aesenc $rndkey1,$inout1 + lea 16($inp),$inp + aesenclast $rndkey0,$inout0 + aesenclast $rndkey0,$inout1 + jmp .Lccm64_dec_outer + +.align 16 +.Lccm64_dec_break: + #xorps $in0,$inout1 # cmac^=out +___ + &aesni_generate1("enc",$key_,$rounds,$inout1,$in0); +$code.=<<___; + movups $inout1,($cmac) +___ +$code.=<<___ if ($win64); + movaps (%rsp),%xmm6 + movaps 0x10(%rsp),%xmm7 + movaps 0x20(%rsp),%xmm8 + movaps 0x30(%rsp),%xmm9 + lea 0x58(%rsp),%rsp +.Lccm64_dec_ret: +___ +$code.=<<___; + ret +.size aesni_ccm64_decrypt_blocks,.-aesni_ccm64_decrypt_blocks +___ +} +###################################################################### +# void aesni_ctr32_encrypt_blocks (const void *in, void *out, +# size_t blocks, const AES_KEY *key, +# const char *ivec); +# +# Handles only complete blocks, operates on 32-bit counter and +# does not update *ivec! (see engine/eng_aesni.c for details) +# +{ +my $reserved = $win64?0:-0x28; +my ($in0,$in1,$in2,$in3)=map("%xmm$_",(8..11)); +my ($iv0,$iv1,$ivec)=("%xmm12","%xmm13","%xmm14"); +my $bswap_mask="%xmm15"; + +$code.=<<___; +.globl aesni_ctr32_encrypt_blocks +.type aesni_ctr32_encrypt_blocks,\@function,5 +.align 16 +aesni_ctr32_encrypt_blocks: +___ +$code.=<<___ if ($win64); + lea -0xc8(%rsp),%rsp + movaps %xmm6,0x20(%rsp) + movaps %xmm7,0x30(%rsp) + movaps %xmm8,0x40(%rsp) + movaps %xmm9,0x50(%rsp) + movaps %xmm10,0x60(%rsp) + movaps %xmm11,0x70(%rsp) + movaps %xmm12,0x80(%rsp) + movaps %xmm13,0x90(%rsp) + movaps %xmm14,0xa0(%rsp) + movaps %xmm15,0xb0(%rsp) +.Lctr32_body: +___ +$code.=<<___; + cmp \$1,$len + je .Lctr32_one_shortcut + + movdqu ($ivp),$ivec + movdqa .Lbswap_mask(%rip),$bswap_mask + xor $rounds,$rounds + pextrd \$3,$ivec,$rnds_ # pull 32-bit counter + pinsrd \$3,$rounds,$ivec # wipe 32-bit counter + + mov 240($key),$rounds # key->rounds + bswap $rnds_ + pxor $iv0,$iv0 # vector of 3 32-bit counters + pxor $iv1,$iv1 # vector of 3 32-bit counters + pinsrd \$0,$rnds_,$iv0 + lea 3($rnds_),$key_ + pinsrd \$0,$key_,$iv1 + inc $rnds_ + pinsrd \$1,$rnds_,$iv0 + inc $key_ + pinsrd \$1,$key_,$iv1 + inc $rnds_ + pinsrd \$2,$rnds_,$iv0 + inc $key_ + pinsrd \$2,$key_,$iv1 + movdqa $iv0,$reserved(%rsp) + pshufb $bswap_mask,$iv0 + movdqa $iv1,`$reserved+0x10`(%rsp) + pshufb $bswap_mask,$iv1 + + pshufd \$`3<<6`,$iv0,$inout0 # place counter to upper dword + pshufd \$`2<<6`,$iv0,$inout1 + pshufd \$`1<<6`,$iv0,$inout2 + cmp \$6,$len + jb .Lctr32_tail + shr \$1,$rounds + mov $key,$key_ # backup $key + mov $rounds,$rnds_ # backup $rounds + sub \$6,$len + jmp .Lctr32_loop6 + +.align 16 +.Lctr32_loop6: + pshufd \$`3<<6`,$iv1,$inout3 + por $ivec,$inout0 # merge counter-less ivec + $movkey ($key_),$rndkey0 + pshufd \$`2<<6`,$iv1,$inout4 + por $ivec,$inout1 + $movkey 16($key_),$rndkey1 + pshufd \$`1<<6`,$iv1,$inout5 + por $ivec,$inout2 + por $ivec,$inout3 + xorps $rndkey0,$inout0 + por $ivec,$inout4 + por $ivec,$inout5 + + # inline _aesni_encrypt6 and interleave last rounds + # with own code... + + pxor $rndkey0,$inout1 + aesenc $rndkey1,$inout0 + lea 32($key_),$key + pxor $rndkey0,$inout2 + aesenc $rndkey1,$inout1 + movdqa .Lincrement32(%rip),$iv1 + pxor $rndkey0,$inout3 + aesenc $rndkey1,$inout2 + movdqa $reserved(%rsp),$iv0 + pxor $rndkey0,$inout4 + aesenc $rndkey1,$inout3 + pxor $rndkey0,$inout5 + $movkey ($key),$rndkey0 + dec $rounds + aesenc $rndkey1,$inout4 + aesenc $rndkey1,$inout5 + jmp .Lctr32_enc_loop6_enter +.align 16 +.Lctr32_enc_loop6: + aesenc $rndkey1,$inout0 + aesenc $rndkey1,$inout1 + dec $rounds + aesenc $rndkey1,$inout2 + aesenc $rndkey1,$inout3 + aesenc $rndkey1,$inout4 + aesenc $rndkey1,$inout5 +.Lctr32_enc_loop6_enter: + $movkey 16($key),$rndkey1 + aesenc $rndkey0,$inout0 + aesenc $rndkey0,$inout1 + lea 32($key),$key + aesenc $rndkey0,$inout2 + aesenc $rndkey0,$inout3 + aesenc $rndkey0,$inout4 + aesenc $rndkey0,$inout5 + $movkey ($key),$rndkey0 + jnz .Lctr32_enc_loop6 + + aesenc $rndkey1,$inout0 + paddd $iv1,$iv0 # increment counter vector + aesenc $rndkey1,$inout1 + paddd `$reserved+0x10`(%rsp),$iv1 + aesenc $rndkey1,$inout2 + movdqa $iv0,$reserved(%rsp) # save counter vector + aesenc $rndkey1,$inout3 + movdqa $iv1,`$reserved+0x10`(%rsp) + aesenc $rndkey1,$inout4 + pshufb $bswap_mask,$iv0 # byte swap + aesenc $rndkey1,$inout5 + pshufb $bswap_mask,$iv1 + + aesenclast $rndkey0,$inout0 + movups ($inp),$in0 # load input + aesenclast $rndkey0,$inout1 + movups 0x10($inp),$in1 + aesenclast $rndkey0,$inout2 + movups 0x20($inp),$in2 + aesenclast $rndkey0,$inout3 + movups 0x30($inp),$in3 + aesenclast $rndkey0,$inout4 + movups 0x40($inp),$rndkey1 + aesenclast $rndkey0,$inout5 + movups 0x50($inp),$rndkey0 + lea 0x60($inp),$inp + + xorps $inout0,$in0 # xor + pshufd \$`3<<6`,$iv0,$inout0 + xorps $inout1,$in1 + pshufd \$`2<<6`,$iv0,$inout1 + movups $in0,($out) # store output + xorps $inout2,$in2 + pshufd \$`1<<6`,$iv0,$inout2 + movups $in1,0x10($out) + xorps $inout3,$in3 + movups $in2,0x20($out) + xorps $inout4,$rndkey1 + movups $in3,0x30($out) + xorps $inout5,$rndkey0 + movups $rndkey1,0x40($out) + movups $rndkey0,0x50($out) + lea 0x60($out),$out + mov $rnds_,$rounds + sub \$6,$len + jnc .Lctr32_loop6 + + add \$6,$len + jz .Lctr32_done + mov $key_,$key # restore $key + lea 1($rounds,$rounds),$rounds # restore original value + +.Lctr32_tail: + por $ivec,$inout0 + movups ($inp),$in0 + cmp \$2,$len + jb .Lctr32_one + + por $ivec,$inout1 + movups 0x10($inp),$in1 + je .Lctr32_two + + pshufd \$`3<<6`,$iv1,$inout3 + por $ivec,$inout2 + movups 0x20($inp),$in2 + cmp \$4,$len + jb .Lctr32_three + + pshufd \$`2<<6`,$iv1,$inout4 + por $ivec,$inout3 + movups 0x30($inp),$in3 + je .Lctr32_four + + por $ivec,$inout4 + xorps $inout5,$inout5 + + call _aesni_encrypt6 + + movups 0x40($inp),$rndkey1 + xorps $inout0,$in0 + xorps $inout1,$in1 + movups $in0,($out) + xorps $inout2,$in2 + movups $in1,0x10($out) + xorps $inout3,$in3 + movups $in2,0x20($out) + xorps $inout4,$rndkey1 + movups $in3,0x30($out) + movups $rndkey1,0x40($out) + jmp .Lctr32_done + +.align 16 +.Lctr32_one_shortcut: + movups ($ivp),$inout0 + movups ($inp),$in0 + mov 240($key),$rounds # key->rounds +.Lctr32_one: +___ + &aesni_generate1("enc",$key,$rounds); +$code.=<<___; + xorps $inout0,$in0 + movups $in0,($out) + jmp .Lctr32_done + +.align 16 +.Lctr32_two: + xorps $inout2,$inout2 + call _aesni_encrypt3 + xorps $inout0,$in0 + xorps $inout1,$in1 + movups $in0,($out) + movups $in1,0x10($out) + jmp .Lctr32_done + +.align 16 +.Lctr32_three: + call _aesni_encrypt3 + xorps $inout0,$in0 + xorps $inout1,$in1 + movups $in0,($out) + xorps $inout2,$in2 + movups $in1,0x10($out) + movups $in2,0x20($out) + jmp .Lctr32_done + +.align 16 +.Lctr32_four: + call _aesni_encrypt4 + xorps $inout0,$in0 + xorps $inout1,$in1 + movups $in0,($out) + xorps $inout2,$in2 + movups $in1,0x10($out) + xorps $inout3,$in3 + movups $in2,0x20($out) + movups $in3,0x30($out) + +.Lctr32_done: +___ +$code.=<<___ if ($win64); + movaps 0x20(%rsp),%xmm6 + movaps 0x30(%rsp),%xmm7 + movaps 0x40(%rsp),%xmm8 + movaps 0x50(%rsp),%xmm9 + movaps 0x60(%rsp),%xmm10 + movaps 0x70(%rsp),%xmm11 + movaps 0x80(%rsp),%xmm12 + movaps 0x90(%rsp),%xmm13 + movaps 0xa0(%rsp),%xmm14 + movaps 0xb0(%rsp),%xmm15 + lea 0xc8(%rsp),%rsp +.Lctr32_ret: +___ +$code.=<<___; + ret +.size aesni_ctr32_encrypt_blocks,.-aesni_ctr32_encrypt_blocks +___ +} + +###################################################################### +# void aesni_xts_[en|de]crypt(const char *inp,char *out,size_t len, +# const AES_KEY *key1, const AES_KEY *key2 +# const unsigned char iv[16]); +# +{ +my @tweak=map("%xmm$_",(10..15)); +my ($twmask,$twres,$twtmp)=("%xmm8","%xmm9",@tweak[4]); +my ($key2,$ivp,$len_)=("%r8","%r9","%r9"); +my $frame_size = 0x68 + ($win64?160:0); + +$code.=<<___; +.globl aesni_xts_encrypt +.type aesni_xts_encrypt,\@function,6 +.align 16 +aesni_xts_encrypt: + lea -$frame_size(%rsp),%rsp +___ +$code.=<<___ if ($win64); + movaps %xmm6,0x60(%rsp) + movaps %xmm7,0x70(%rsp) + movaps %xmm8,0x80(%rsp) + movaps %xmm9,0x90(%rsp) + movaps %xmm10,0xa0(%rsp) + movaps %xmm11,0xb0(%rsp) + movaps %xmm12,0xc0(%rsp) + movaps %xmm13,0xd0(%rsp) + movaps %xmm14,0xe0(%rsp) + movaps %xmm15,0xf0(%rsp) +.Lxts_enc_body: +___ +$code.=<<___; + movups ($ivp),@tweak[5] # load clear-text tweak + mov 240(%r8),$rounds # key2->rounds + mov 240($key),$rnds_ # key1->rounds +___ + # generate the tweak + &aesni_generate1("enc",$key2,$rounds,@tweak[5]); +$code.=<<___; + mov $key,$key_ # backup $key + mov $rnds_,$rounds # backup $rounds + mov $len,$len_ # backup $len + and \$-16,$len + + movdqa .Lxts_magic(%rip),$twmask + pxor $twtmp,$twtmp + pcmpgtd @tweak[5],$twtmp # broadcast upper bits +___ + for ($i=0;$i<4;$i++) { + $code.=<<___; + pshufd \$0x13,$twtmp,$twres + pxor $twtmp,$twtmp + movdqa @tweak[5],@tweak[$i] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + pand $twmask,$twres # isolate carry and residue + pcmpgtd @tweak[5],$twtmp # broadcat upper bits + pxor $twres,@tweak[5] +___ + } +$code.=<<___; + sub \$16*6,$len + jc .Lxts_enc_short + + shr \$1,$rounds + sub \$1,$rounds + mov $rounds,$rnds_ + jmp .Lxts_enc_grandloop + +.align 16 +.Lxts_enc_grandloop: + pshufd \$0x13,$twtmp,$twres + movdqa @tweak[5],@tweak[4] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + movdqu `16*0`($inp),$inout0 # load input + pand $twmask,$twres # isolate carry and residue + movdqu `16*1`($inp),$inout1 + pxor $twres,@tweak[5] + + movdqu `16*2`($inp),$inout2 + pxor @tweak[0],$inout0 # input^=tweak + movdqu `16*3`($inp),$inout3 + pxor @tweak[1],$inout1 + movdqu `16*4`($inp),$inout4 + pxor @tweak[2],$inout2 + movdqu `16*5`($inp),$inout5 + lea `16*6`($inp),$inp + pxor @tweak[3],$inout3 + $movkey ($key_),$rndkey0 + pxor @tweak[4],$inout4 + pxor @tweak[5],$inout5 + + # inline _aesni_encrypt6 and interleave first and last rounds + # with own code... + $movkey 16($key_),$rndkey1 + pxor $rndkey0,$inout0 + pxor $rndkey0,$inout1 + movdqa @tweak[0],`16*0`(%rsp) # put aside tweaks + aesenc $rndkey1,$inout0 + lea 32($key_),$key + pxor $rndkey0,$inout2 + movdqa @tweak[1],`16*1`(%rsp) + aesenc $rndkey1,$inout1 + pxor $rndkey0,$inout3 + movdqa @tweak[2],`16*2`(%rsp) + aesenc $rndkey1,$inout2 + pxor $rndkey0,$inout4 + movdqa @tweak[3],`16*3`(%rsp) + aesenc $rndkey1,$inout3 + pxor $rndkey0,$inout5 + $movkey ($key),$rndkey0 + dec $rounds + movdqa @tweak[4],`16*4`(%rsp) + aesenc $rndkey1,$inout4 + movdqa @tweak[5],`16*5`(%rsp) + aesenc $rndkey1,$inout5 + pxor $twtmp,$twtmp + pcmpgtd @tweak[5],$twtmp + jmp .Lxts_enc_loop6_enter + +.align 16 +.Lxts_enc_loop6: + aesenc $rndkey1,$inout0 + aesenc $rndkey1,$inout1 + dec $rounds + aesenc $rndkey1,$inout2 + aesenc $rndkey1,$inout3 + aesenc $rndkey1,$inout4 + aesenc $rndkey1,$inout5 +.Lxts_enc_loop6_enter: + $movkey 16($key),$rndkey1 + aesenc $rndkey0,$inout0 + aesenc $rndkey0,$inout1 + lea 32($key),$key + aesenc $rndkey0,$inout2 + aesenc $rndkey0,$inout3 + aesenc $rndkey0,$inout4 + aesenc $rndkey0,$inout5 + $movkey ($key),$rndkey0 + jnz .Lxts_enc_loop6 + + pshufd \$0x13,$twtmp,$twres + pxor $twtmp,$twtmp + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + aesenc $rndkey1,$inout0 + pand $twmask,$twres # isolate carry and residue + aesenc $rndkey1,$inout1 + pcmpgtd @tweak[5],$twtmp # broadcast upper bits + aesenc $rndkey1,$inout2 + pxor $twres,@tweak[5] + aesenc $rndkey1,$inout3 + aesenc $rndkey1,$inout4 + aesenc $rndkey1,$inout5 + $movkey 16($key),$rndkey1 + + pshufd \$0x13,$twtmp,$twres + pxor $twtmp,$twtmp + movdqa @tweak[5],@tweak[0] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + aesenc $rndkey0,$inout0 + pand $twmask,$twres # isolate carry and residue + aesenc $rndkey0,$inout1 + pcmpgtd @tweak[5],$twtmp # broadcat upper bits + aesenc $rndkey0,$inout2 + pxor $twres,@tweak[5] + aesenc $rndkey0,$inout3 + aesenc $rndkey0,$inout4 + aesenc $rndkey0,$inout5 + $movkey 32($key),$rndkey0 + + pshufd \$0x13,$twtmp,$twres + pxor $twtmp,$twtmp + movdqa @tweak[5],@tweak[1] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + aesenc $rndkey1,$inout0 + pand $twmask,$twres # isolate carry and residue + aesenc $rndkey1,$inout1 + pcmpgtd @tweak[5],$twtmp # broadcat upper bits + aesenc $rndkey1,$inout2 + pxor $twres,@tweak[5] + aesenc $rndkey1,$inout3 + aesenc $rndkey1,$inout4 + aesenc $rndkey1,$inout5 + + pshufd \$0x13,$twtmp,$twres + pxor $twtmp,$twtmp + movdqa @tweak[5],@tweak[2] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + aesenclast $rndkey0,$inout0 + pand $twmask,$twres # isolate carry and residue + aesenclast $rndkey0,$inout1 + pcmpgtd @tweak[5],$twtmp # broadcat upper bits + aesenclast $rndkey0,$inout2 + pxor $twres,@tweak[5] + aesenclast $rndkey0,$inout3 + aesenclast $rndkey0,$inout4 + aesenclast $rndkey0,$inout5 + + pshufd \$0x13,$twtmp,$twres + pxor $twtmp,$twtmp + movdqa @tweak[5],@tweak[3] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + xorps `16*0`(%rsp),$inout0 # output^=tweak + pand $twmask,$twres # isolate carry and residue + xorps `16*1`(%rsp),$inout1 + pcmpgtd @tweak[5],$twtmp # broadcat upper bits + pxor $twres,@tweak[5] + + xorps `16*2`(%rsp),$inout2 + movups $inout0,`16*0`($out) # write output + xorps `16*3`(%rsp),$inout3 + movups $inout1,`16*1`($out) + xorps `16*4`(%rsp),$inout4 + movups $inout2,`16*2`($out) + xorps `16*5`(%rsp),$inout5 + movups $inout3,`16*3`($out) + mov $rnds_,$rounds # restore $rounds + movups $inout4,`16*4`($out) + movups $inout5,`16*5`($out) + lea `16*6`($out),$out + sub \$16*6,$len + jnc .Lxts_enc_grandloop + + lea 3($rounds,$rounds),$rounds # restore original value + mov $key_,$key # restore $key + mov $rounds,$rnds_ # backup $rounds + +.Lxts_enc_short: + add \$16*6,$len + jz .Lxts_enc_done + + cmp \$0x20,$len + jb .Lxts_enc_one + je .Lxts_enc_two + + cmp \$0x40,$len + jb .Lxts_enc_three + je .Lxts_enc_four + + pshufd \$0x13,$twtmp,$twres + movdqa @tweak[5],@tweak[4] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + movdqu ($inp),$inout0 + pand $twmask,$twres # isolate carry and residue + movdqu 16*1($inp),$inout1 + pxor $twres,@tweak[5] + + movdqu 16*2($inp),$inout2 + pxor @tweak[0],$inout0 + movdqu 16*3($inp),$inout3 + pxor @tweak[1],$inout1 + movdqu 16*4($inp),$inout4 + lea 16*5($inp),$inp + pxor @tweak[2],$inout2 + pxor @tweak[3],$inout3 + pxor @tweak[4],$inout4 + + call _aesni_encrypt6 + + xorps @tweak[0],$inout0 + movdqa @tweak[5],@tweak[0] + xorps @tweak[1],$inout1 + xorps @tweak[2],$inout2 + movdqu $inout0,($out) + xorps @tweak[3],$inout3 + movdqu $inout1,16*1($out) + xorps @tweak[4],$inout4 + movdqu $inout2,16*2($out) + movdqu $inout3,16*3($out) + movdqu $inout4,16*4($out) + lea 16*5($out),$out + jmp .Lxts_enc_done + +.align 16 +.Lxts_enc_one: + movups ($inp),$inout0 + lea 16*1($inp),$inp + xorps @tweak[0],$inout0 +___ + &aesni_generate1("enc",$key,$rounds); +$code.=<<___; + xorps @tweak[0],$inout0 + movdqa @tweak[1],@tweak[0] + movups $inout0,($out) + lea 16*1($out),$out + jmp .Lxts_enc_done + +.align 16 +.Lxts_enc_two: + movups ($inp),$inout0 + movups 16($inp),$inout1 + lea 32($inp),$inp + xorps @tweak[0],$inout0 + xorps @tweak[1],$inout1 + + call _aesni_encrypt3 + + xorps @tweak[0],$inout0 + movdqa @tweak[2],@tweak[0] + xorps @tweak[1],$inout1 + movups $inout0,($out) + movups $inout1,16*1($out) + lea 16*2($out),$out + jmp .Lxts_enc_done + +.align 16 +.Lxts_enc_three: + movups ($inp),$inout0 + movups 16*1($inp),$inout1 + movups 16*2($inp),$inout2 + lea 16*3($inp),$inp + xorps @tweak[0],$inout0 + xorps @tweak[1],$inout1 + xorps @tweak[2],$inout2 + + call _aesni_encrypt3 + + xorps @tweak[0],$inout0 + movdqa @tweak[3],@tweak[0] + xorps @tweak[1],$inout1 + xorps @tweak[2],$inout2 + movups $inout0,($out) + movups $inout1,16*1($out) + movups $inout2,16*2($out) + lea 16*3($out),$out + jmp .Lxts_enc_done + +.align 16 +.Lxts_enc_four: + movups ($inp),$inout0 + movups 16*1($inp),$inout1 + movups 16*2($inp),$inout2 + xorps @tweak[0],$inout0 + movups 16*3($inp),$inout3 + lea 16*4($inp),$inp + xorps @tweak[1],$inout1 + xorps @tweak[2],$inout2 + xorps @tweak[3],$inout3 + + call _aesni_encrypt4 + + xorps @tweak[0],$inout0 + movdqa @tweak[5],@tweak[0] + xorps @tweak[1],$inout1 + xorps @tweak[2],$inout2 + movups $inout0,($out) + xorps @tweak[3],$inout3 + movups $inout1,16*1($out) + movups $inout2,16*2($out) + movups $inout3,16*3($out) + lea 16*4($out),$out + jmp .Lxts_enc_done + +.align 16 +.Lxts_enc_done: + and \$15,$len_ + jz .Lxts_enc_ret + mov $len_,$len + +.Lxts_enc_steal: + movzb ($inp),%eax # borrow $rounds ... + movzb -16($out),%ecx # ... and $key + lea 1($inp),$inp + mov %al,-16($out) + mov %cl,0($out) + lea 1($out),$out + sub \$1,$len + jnz .Lxts_enc_steal + + sub $len_,$out # rewind $out + mov $key_,$key # restore $key + mov $rnds_,$rounds # restore $rounds + + movups -16($out),$inout0 + xorps @tweak[0],$inout0 +___ + &aesni_generate1("enc",$key,$rounds); +$code.=<<___; + xorps @tweak[0],$inout0 + movups $inout0,-16($out) + +.Lxts_enc_ret: +___ +$code.=<<___ if ($win64); + movaps 0x60(%rsp),%xmm6 + movaps 0x70(%rsp),%xmm7 + movaps 0x80(%rsp),%xmm8 + movaps 0x90(%rsp),%xmm9 + movaps 0xa0(%rsp),%xmm10 + movaps 0xb0(%rsp),%xmm11 + movaps 0xc0(%rsp),%xmm12 + movaps 0xd0(%rsp),%xmm13 + movaps 0xe0(%rsp),%xmm14 + movaps 0xf0(%rsp),%xmm15 +___ +$code.=<<___; + lea $frame_size(%rsp),%rsp +.Lxts_enc_epilogue: + ret +.size aesni_xts_encrypt,.-aesni_xts_encrypt +___ + +$code.=<<___; +.globl aesni_xts_decrypt +.type aesni_xts_decrypt,\@function,6 +.align 16 +aesni_xts_decrypt: + lea -$frame_size(%rsp),%rsp +___ +$code.=<<___ if ($win64); + movaps %xmm6,0x60(%rsp) + movaps %xmm7,0x70(%rsp) + movaps %xmm8,0x80(%rsp) + movaps %xmm9,0x90(%rsp) + movaps %xmm10,0xa0(%rsp) + movaps %xmm11,0xb0(%rsp) + movaps %xmm12,0xc0(%rsp) + movaps %xmm13,0xd0(%rsp) + movaps %xmm14,0xe0(%rsp) + movaps %xmm15,0xf0(%rsp) +.Lxts_dec_body: +___ +$code.=<<___; + movups ($ivp),@tweak[5] # load clear-text tweak + mov 240($key2),$rounds # key2->rounds + mov 240($key),$rnds_ # key1->rounds +___ + # generate the tweak + &aesni_generate1("enc",$key2,$rounds,@tweak[5]); +$code.=<<___; + xor %eax,%eax # if ($len%16) len-=16; + test \$15,$len + setnz %al + shl \$4,%rax + sub %rax,$len + + mov $key,$key_ # backup $key + mov $rnds_,$rounds # backup $rounds + mov $len,$len_ # backup $len + and \$-16,$len + + movdqa .Lxts_magic(%rip),$twmask + pxor $twtmp,$twtmp + pcmpgtd @tweak[5],$twtmp # broadcast upper bits +___ + for ($i=0;$i<4;$i++) { + $code.=<<___; + pshufd \$0x13,$twtmp,$twres + pxor $twtmp,$twtmp + movdqa @tweak[5],@tweak[$i] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + pand $twmask,$twres # isolate carry and residue + pcmpgtd @tweak[5],$twtmp # broadcat upper bits + pxor $twres,@tweak[5] +___ + } +$code.=<<___; + sub \$16*6,$len + jc .Lxts_dec_short + + shr \$1,$rounds + sub \$1,$rounds + mov $rounds,$rnds_ + jmp .Lxts_dec_grandloop + +.align 16 +.Lxts_dec_grandloop: + pshufd \$0x13,$twtmp,$twres + movdqa @tweak[5],@tweak[4] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + movdqu `16*0`($inp),$inout0 # load input + pand $twmask,$twres # isolate carry and residue + movdqu `16*1`($inp),$inout1 + pxor $twres,@tweak[5] + + movdqu `16*2`($inp),$inout2 + pxor @tweak[0],$inout0 # input^=tweak + movdqu `16*3`($inp),$inout3 + pxor @tweak[1],$inout1 + movdqu `16*4`($inp),$inout4 + pxor @tweak[2],$inout2 + movdqu `16*5`($inp),$inout5 + lea `16*6`($inp),$inp + pxor @tweak[3],$inout3 + $movkey ($key_),$rndkey0 + pxor @tweak[4],$inout4 + pxor @tweak[5],$inout5 + + # inline _aesni_decrypt6 and interleave first and last rounds + # with own code... + $movkey 16($key_),$rndkey1 + pxor $rndkey0,$inout0 + pxor $rndkey0,$inout1 + movdqa @tweak[0],`16*0`(%rsp) # put aside tweaks + aesdec $rndkey1,$inout0 + lea 32($key_),$key + pxor $rndkey0,$inout2 + movdqa @tweak[1],`16*1`(%rsp) + aesdec $rndkey1,$inout1 + pxor $rndkey0,$inout3 + movdqa @tweak[2],`16*2`(%rsp) + aesdec $rndkey1,$inout2 + pxor $rndkey0,$inout4 + movdqa @tweak[3],`16*3`(%rsp) + aesdec $rndkey1,$inout3 + pxor $rndkey0,$inout5 + $movkey ($key),$rndkey0 + dec $rounds + movdqa @tweak[4],`16*4`(%rsp) + aesdec $rndkey1,$inout4 + movdqa @tweak[5],`16*5`(%rsp) + aesdec $rndkey1,$inout5 + pxor $twtmp,$twtmp + pcmpgtd @tweak[5],$twtmp + jmp .Lxts_dec_loop6_enter + +.align 16 +.Lxts_dec_loop6: + aesdec $rndkey1,$inout0 + aesdec $rndkey1,$inout1 + dec $rounds + aesdec $rndkey1,$inout2 + aesdec $rndkey1,$inout3 + aesdec $rndkey1,$inout4 + aesdec $rndkey1,$inout5 +.Lxts_dec_loop6_enter: + $movkey 16($key),$rndkey1 + aesdec $rndkey0,$inout0 + aesdec $rndkey0,$inout1 + lea 32($key),$key + aesdec $rndkey0,$inout2 + aesdec $rndkey0,$inout3 + aesdec $rndkey0,$inout4 + aesdec $rndkey0,$inout5 + $movkey ($key),$rndkey0 + jnz .Lxts_dec_loop6 + + pshufd \$0x13,$twtmp,$twres + pxor $twtmp,$twtmp + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + aesdec $rndkey1,$inout0 + pand $twmask,$twres # isolate carry and residue + aesdec $rndkey1,$inout1 + pcmpgtd @tweak[5],$twtmp # broadcast upper bits + aesdec $rndkey1,$inout2 + pxor $twres,@tweak[5] + aesdec $rndkey1,$inout3 + aesdec $rndkey1,$inout4 + aesdec $rndkey1,$inout5 + $movkey 16($key),$rndkey1 + + pshufd \$0x13,$twtmp,$twres + pxor $twtmp,$twtmp + movdqa @tweak[5],@tweak[0] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + aesdec $rndkey0,$inout0 + pand $twmask,$twres # isolate carry and residue + aesdec $rndkey0,$inout1 + pcmpgtd @tweak[5],$twtmp # broadcat upper bits + aesdec $rndkey0,$inout2 + pxor $twres,@tweak[5] + aesdec $rndkey0,$inout3 + aesdec $rndkey0,$inout4 + aesdec $rndkey0,$inout5 + $movkey 32($key),$rndkey0 + + pshufd \$0x13,$twtmp,$twres + pxor $twtmp,$twtmp + movdqa @tweak[5],@tweak[1] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + aesdec $rndkey1,$inout0 + pand $twmask,$twres # isolate carry and residue + aesdec $rndkey1,$inout1 + pcmpgtd @tweak[5],$twtmp # broadcat upper bits + aesdec $rndkey1,$inout2 + pxor $twres,@tweak[5] + aesdec $rndkey1,$inout3 + aesdec $rndkey1,$inout4 + aesdec $rndkey1,$inout5 + + pshufd \$0x13,$twtmp,$twres + pxor $twtmp,$twtmp + movdqa @tweak[5],@tweak[2] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + aesdeclast $rndkey0,$inout0 + pand $twmask,$twres # isolate carry and residue + aesdeclast $rndkey0,$inout1 + pcmpgtd @tweak[5],$twtmp # broadcat upper bits + aesdeclast $rndkey0,$inout2 + pxor $twres,@tweak[5] + aesdeclast $rndkey0,$inout3 + aesdeclast $rndkey0,$inout4 + aesdeclast $rndkey0,$inout5 + + pshufd \$0x13,$twtmp,$twres + pxor $twtmp,$twtmp + movdqa @tweak[5],@tweak[3] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + xorps `16*0`(%rsp),$inout0 # output^=tweak + pand $twmask,$twres # isolate carry and residue + xorps `16*1`(%rsp),$inout1 + pcmpgtd @tweak[5],$twtmp # broadcat upper bits + pxor $twres,@tweak[5] + + xorps `16*2`(%rsp),$inout2 + movups $inout0,`16*0`($out) # write output + xorps `16*3`(%rsp),$inout3 + movups $inout1,`16*1`($out) + xorps `16*4`(%rsp),$inout4 + movups $inout2,`16*2`($out) + xorps `16*5`(%rsp),$inout5 + movups $inout3,`16*3`($out) + mov $rnds_,$rounds # restore $rounds + movups $inout4,`16*4`($out) + movups $inout5,`16*5`($out) + lea `16*6`($out),$out + sub \$16*6,$len + jnc .Lxts_dec_grandloop + + lea 3($rounds,$rounds),$rounds # restore original value + mov $key_,$key # restore $key + mov $rounds,$rnds_ # backup $rounds + +.Lxts_dec_short: + add \$16*6,$len + jz .Lxts_dec_done + + cmp \$0x20,$len + jb .Lxts_dec_one + je .Lxts_dec_two + + cmp \$0x40,$len + jb .Lxts_dec_three + je .Lxts_dec_four + + pshufd \$0x13,$twtmp,$twres + movdqa @tweak[5],@tweak[4] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + movdqu ($inp),$inout0 + pand $twmask,$twres # isolate carry and residue + movdqu 16*1($inp),$inout1 + pxor $twres,@tweak[5] + + movdqu 16*2($inp),$inout2 + pxor @tweak[0],$inout0 + movdqu 16*3($inp),$inout3 + pxor @tweak[1],$inout1 + movdqu 16*4($inp),$inout4 + lea 16*5($inp),$inp + pxor @tweak[2],$inout2 + pxor @tweak[3],$inout3 + pxor @tweak[4],$inout4 + + call _aesni_decrypt6 + + xorps @tweak[0],$inout0 + xorps @tweak[1],$inout1 + xorps @tweak[2],$inout2 + movdqu $inout0,($out) + xorps @tweak[3],$inout3 + movdqu $inout1,16*1($out) + xorps @tweak[4],$inout4 + movdqu $inout2,16*2($out) + pxor $twtmp,$twtmp + movdqu $inout3,16*3($out) + pcmpgtd @tweak[5],$twtmp + movdqu $inout4,16*4($out) + lea 16*5($out),$out + pshufd \$0x13,$twtmp,@tweak[1] # $twres + and \$15,$len_ + jz .Lxts_dec_ret + + movdqa @tweak[5],@tweak[0] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + pand $twmask,@tweak[1] # isolate carry and residue + pxor @tweak[5],@tweak[1] + jmp .Lxts_dec_done2 + +.align 16 +.Lxts_dec_one: + movups ($inp),$inout0 + lea 16*1($inp),$inp + xorps @tweak[0],$inout0 +___ + &aesni_generate1("dec",$key,$rounds); +$code.=<<___; + xorps @tweak[0],$inout0 + movdqa @tweak[1],@tweak[0] + movups $inout0,($out) + movdqa @tweak[2],@tweak[1] + lea 16*1($out),$out + jmp .Lxts_dec_done + +.align 16 +.Lxts_dec_two: + movups ($inp),$inout0 + movups 16($inp),$inout1 + lea 32($inp),$inp + xorps @tweak[0],$inout0 + xorps @tweak[1],$inout1 + + call _aesni_decrypt3 + + xorps @tweak[0],$inout0 + movdqa @tweak[2],@tweak[0] + xorps @tweak[1],$inout1 + movdqa @tweak[3],@tweak[1] + movups $inout0,($out) + movups $inout1,16*1($out) + lea 16*2($out),$out + jmp .Lxts_dec_done + +.align 16 +.Lxts_dec_three: + movups ($inp),$inout0 + movups 16*1($inp),$inout1 + movups 16*2($inp),$inout2 + lea 16*3($inp),$inp + xorps @tweak[0],$inout0 + xorps @tweak[1],$inout1 + xorps @tweak[2],$inout2 + + call _aesni_decrypt3 + + xorps @tweak[0],$inout0 + movdqa @tweak[3],@tweak[0] + xorps @tweak[1],$inout1 + movdqa @tweak[5],@tweak[1] + xorps @tweak[2],$inout2 + movups $inout0,($out) + movups $inout1,16*1($out) + movups $inout2,16*2($out) + lea 16*3($out),$out + jmp .Lxts_dec_done + +.align 16 +.Lxts_dec_four: + pshufd \$0x13,$twtmp,$twres + movdqa @tweak[5],@tweak[4] + paddq @tweak[5],@tweak[5] # psllq 1,$tweak + movups ($inp),$inout0 + pand $twmask,$twres # isolate carry and residue + movups 16*1($inp),$inout1 + pxor $twres,@tweak[5] + + movups 16*2($inp),$inout2 + xorps @tweak[0],$inout0 + movups 16*3($inp),$inout3 + lea 16*4($inp),$inp + xorps @tweak[1],$inout1 + xorps @tweak[2],$inout2 + xorps @tweak[3],$inout3 + + call _aesni_decrypt4 + + xorps @tweak[0],$inout0 + movdqa @tweak[4],@tweak[0] + xorps @tweak[1],$inout1 + movdqa @tweak[5],@tweak[1] + xorps @tweak[2],$inout2 + movups $inout0,($out) + xorps @tweak[3],$inout3 + movups $inout1,16*1($out) + movups $inout2,16*2($out) + movups $inout3,16*3($out) + lea 16*4($out),$out + jmp .Lxts_dec_done + +.align 16 +.Lxts_dec_done: + and \$15,$len_ + jz .Lxts_dec_ret +.Lxts_dec_done2: + mov $len_,$len + mov $key_,$key # restore $key + mov $rnds_,$rounds # restore $rounds + + movups ($inp),$inout0 + xorps @tweak[1],$inout0 +___ + &aesni_generate1("dec",$key,$rounds); +$code.=<<___; + xorps @tweak[1],$inout0 + movups $inout0,($out) + +.Lxts_dec_steal: + movzb 16($inp),%eax # borrow $rounds ... + movzb ($out),%ecx # ... and $key + lea 1($inp),$inp + mov %al,($out) + mov %cl,16($out) + lea 1($out),$out + sub \$1,$len + jnz .Lxts_dec_steal + + sub $len_,$out # rewind $out + mov $key_,$key # restore $key + mov $rnds_,$rounds # restore $rounds + + movups ($out),$inout0 + xorps @tweak[0],$inout0 +___ + &aesni_generate1("dec",$key,$rounds); +$code.=<<___; + xorps @tweak[0],$inout0 + movups $inout0,($out) + +.Lxts_dec_ret: +___ +$code.=<<___ if ($win64); + movaps 0x60(%rsp),%xmm6 + movaps 0x70(%rsp),%xmm7 + movaps 0x80(%rsp),%xmm8 + movaps 0x90(%rsp),%xmm9 + movaps 0xa0(%rsp),%xmm10 + movaps 0xb0(%rsp),%xmm11 + movaps 0xc0(%rsp),%xmm12 + movaps 0xd0(%rsp),%xmm13 + movaps 0xe0(%rsp),%xmm14 + movaps 0xf0(%rsp),%xmm15 +___ +$code.=<<___; + lea $frame_size(%rsp),%rsp +.Lxts_dec_epilogue: + ret +.size aesni_xts_decrypt,.-aesni_xts_decrypt +___ +} }} + +######################################################################## +# void $PREFIX_cbc_encrypt (const void *inp, void *out, +# size_t length, const AES_KEY *key, +# unsigned char *ivp,const int enc); +{ +my $reserved = $win64?0x40:-0x18; # used in decrypt +$code.=<<___; +.globl ${PREFIX}_cbc_encrypt +.type ${PREFIX}_cbc_encrypt,\@function,6 +.align 16 +${PREFIX}_cbc_encrypt: + test $len,$len # check length + jz .Lcbc_ret + + mov 240($key),$rnds_ # key->rounds + mov $key,$key_ # backup $key + test %r9d,%r9d # 6th argument + jz .Lcbc_decrypt +#--------------------------- CBC ENCRYPT ------------------------------# + movups ($ivp),$inout0 # load iv as initial state + mov $rnds_,$rounds + cmp \$16,$len + jb .Lcbc_enc_tail + sub \$16,$len + jmp .Lcbc_enc_loop +.align 16 +.Lcbc_enc_loop: + movups ($inp),$inout1 # load input + lea 16($inp),$inp + #xorps $inout1,$inout0 +___ + &aesni_generate1("enc",$key,$rounds,$inout0,$inout1); +$code.=<<___; + mov $rnds_,$rounds # restore $rounds + mov $key_,$key # restore $key + movups $inout0,0($out) # store output + lea 16($out),$out + sub \$16,$len + jnc .Lcbc_enc_loop + add \$16,$len + jnz .Lcbc_enc_tail + movups $inout0,($ivp) + jmp .Lcbc_ret + +.Lcbc_enc_tail: + mov $len,%rcx # zaps $key + xchg $inp,$out # $inp is %rsi and $out is %rdi now + .long 0x9066A4F3 # rep movsb + mov \$16,%ecx # zero tail + sub $len,%rcx + xor %eax,%eax + .long 0x9066AAF3 # rep stosb + lea -16(%rdi),%rdi # rewind $out by 1 block + mov $rnds_,$rounds # restore $rounds + mov %rdi,%rsi # $inp and $out are the same + mov $key_,$key # restore $key + xor $len,$len # len=16 + jmp .Lcbc_enc_loop # one more spin + #--------------------------- CBC DECRYPT ------------------------------# +.align 16 +.Lcbc_decrypt: +___ +$code.=<<___ if ($win64); + lea -0x58(%rsp),%rsp + movaps %xmm6,(%rsp) + movaps %xmm7,0x10(%rsp) + movaps %xmm8,0x20(%rsp) + movaps %xmm9,0x30(%rsp) +.Lcbc_decrypt_body: +___ +$code.=<<___; + movups ($ivp),$iv + mov $rnds_,$rounds + cmp \$0x70,$len + jbe .Lcbc_dec_tail + shr \$1,$rnds_ + sub \$0x70,$len + mov $rnds_,$rounds + movaps $iv,$reserved(%rsp) + jmp .Lcbc_dec_loop8_enter +.align 16 +.Lcbc_dec_loop8: + movaps $rndkey0,$reserved(%rsp) # save IV + movups $inout7,($out) + lea 0x10($out),$out +.Lcbc_dec_loop8_enter: + $movkey ($key),$rndkey0 + movups ($inp),$inout0 # load input + movups 0x10($inp),$inout1 + $movkey 16($key),$rndkey1 + + lea 32($key),$key + movdqu 0x20($inp),$inout2 + xorps $rndkey0,$inout0 + movdqu 0x30($inp),$inout3 + xorps $rndkey0,$inout1 + movdqu 0x40($inp),$inout4 + aesdec $rndkey1,$inout0 + pxor $rndkey0,$inout2 + movdqu 0x50($inp),$inout5 + aesdec $rndkey1,$inout1 + pxor $rndkey0,$inout3 + movdqu 0x60($inp),$inout6 + aesdec $rndkey1,$inout2 + pxor $rndkey0,$inout4 + movdqu 0x70($inp),$inout7 + aesdec $rndkey1,$inout3 + pxor $rndkey0,$inout5 + dec $rounds + aesdec $rndkey1,$inout4 + pxor $rndkey0,$inout6 + aesdec $rndkey1,$inout5 + pxor $rndkey0,$inout7 + $movkey ($key),$rndkey0 + aesdec $rndkey1,$inout6 + aesdec $rndkey1,$inout7 + $movkey 16($key),$rndkey1 + + call .Ldec_loop8_enter + + movups ($inp),$rndkey1 # re-load input + movups 0x10($inp),$rndkey0 + xorps $reserved(%rsp),$inout0 # ^= IV + xorps $rndkey1,$inout1 + movups 0x20($inp),$rndkey1 + xorps $rndkey0,$inout2 + movups 0x30($inp),$rndkey0 + xorps $rndkey1,$inout3 + movups 0x40($inp),$rndkey1 + xorps $rndkey0,$inout4 + movups 0x50($inp),$rndkey0 + xorps $rndkey1,$inout5 + movups 0x60($inp),$rndkey1 + xorps $rndkey0,$inout6 + movups 0x70($inp),$rndkey0 # IV + xorps $rndkey1,$inout7 + movups $inout0,($out) + movups $inout1,0x10($out) + movups $inout2,0x20($out) + movups $inout3,0x30($out) + mov $rnds_,$rounds # restore $rounds + movups $inout4,0x40($out) + mov $key_,$key # restore $key + movups $inout5,0x50($out) + lea 0x80($inp),$inp + movups $inout6,0x60($out) + lea 0x70($out),$out + sub \$0x80,$len + ja .Lcbc_dec_loop8 + + movaps $inout7,$inout0 + movaps $rndkey0,$iv + add \$0x70,$len + jle .Lcbc_dec_tail_collected + movups $inout0,($out) + lea 1($rnds_,$rnds_),$rounds + lea 0x10($out),$out +.Lcbc_dec_tail: + movups ($inp),$inout0 + movaps $inout0,$in0 + cmp \$0x10,$len + jbe .Lcbc_dec_one + + movups 0x10($inp),$inout1 + movaps $inout1,$in1 + cmp \$0x20,$len + jbe .Lcbc_dec_two + + movups 0x20($inp),$inout2 + movaps $inout2,$in2 + cmp \$0x30,$len + jbe .Lcbc_dec_three + + movups 0x30($inp),$inout3 + cmp \$0x40,$len + jbe .Lcbc_dec_four + + movups 0x40($inp),$inout4 + cmp \$0x50,$len + jbe .Lcbc_dec_five + + movups 0x50($inp),$inout5 + cmp \$0x60,$len + jbe .Lcbc_dec_six + + movups 0x60($inp),$inout6 + movaps $iv,$reserved(%rsp) # save IV + call _aesni_decrypt8 + movups ($inp),$rndkey1 + movups 0x10($inp),$rndkey0 + xorps $reserved(%rsp),$inout0 # ^= IV + xorps $rndkey1,$inout1 + movups 0x20($inp),$rndkey1 + xorps $rndkey0,$inout2 + movups 0x30($inp),$rndkey0 + xorps $rndkey1,$inout3 + movups 0x40($inp),$rndkey1 + xorps $rndkey0,$inout4 + movups 0x50($inp),$rndkey0 + xorps $rndkey1,$inout5 + movups 0x60($inp),$iv # IV + xorps $rndkey0,$inout6 + movups $inout0,($out) + movups $inout1,0x10($out) + movups $inout2,0x20($out) + movups $inout3,0x30($out) + movups $inout4,0x40($out) + movups $inout5,0x50($out) + lea 0x60($out),$out + movaps $inout6,$inout0 + sub \$0x70,$len + jmp .Lcbc_dec_tail_collected +.align 16 +.Lcbc_dec_one: +___ + &aesni_generate1("dec",$key,$rounds); +$code.=<<___; + xorps $iv,$inout0 + movaps $in0,$iv + sub \$0x10,$len + jmp .Lcbc_dec_tail_collected +.align 16 +.Lcbc_dec_two: + xorps $inout2,$inout2 + call _aesni_decrypt3 + xorps $iv,$inout0 + xorps $in0,$inout1 + movups $inout0,($out) + movaps $in1,$iv + movaps $inout1,$inout0 + lea 0x10($out),$out + sub \$0x20,$len + jmp .Lcbc_dec_tail_collected +.align 16 +.Lcbc_dec_three: + call _aesni_decrypt3 + xorps $iv,$inout0 + xorps $in0,$inout1 + movups $inout0,($out) + xorps $in1,$inout2 + movups $inout1,0x10($out) + movaps $in2,$iv + movaps $inout2,$inout0 + lea 0x20($out),$out + sub \$0x30,$len + jmp .Lcbc_dec_tail_collected +.align 16 +.Lcbc_dec_four: + call _aesni_decrypt4 + xorps $iv,$inout0 + movups 0x30($inp),$iv + xorps $in0,$inout1 + movups $inout0,($out) + xorps $in1,$inout2 + movups $inout1,0x10($out) + xorps $in2,$inout3 + movups $inout2,0x20($out) + movaps $inout3,$inout0 + lea 0x30($out),$out + sub \$0x40,$len + jmp .Lcbc_dec_tail_collected +.align 16 +.Lcbc_dec_five: + xorps $inout5,$inout5 + call _aesni_decrypt6 + movups 0x10($inp),$rndkey1 + movups 0x20($inp),$rndkey0 + xorps $iv,$inout0 + xorps $in0,$inout1 + xorps $rndkey1,$inout2 + movups 0x30($inp),$rndkey1 + xorps $rndkey0,$inout3 + movups 0x40($inp),$iv + xorps $rndkey1,$inout4 + movups $inout0,($out) + movups $inout1,0x10($out) + movups $inout2,0x20($out) + movups $inout3,0x30($out) + lea 0x40($out),$out + movaps $inout4,$inout0 + sub \$0x50,$len + jmp .Lcbc_dec_tail_collected +.align 16 +.Lcbc_dec_six: + call _aesni_decrypt6 + movups 0x10($inp),$rndkey1 + movups 0x20($inp),$rndkey0 + xorps $iv,$inout0 + xorps $in0,$inout1 + xorps $rndkey1,$inout2 + movups 0x30($inp),$rndkey1 + xorps $rndkey0,$inout3 + movups 0x40($inp),$rndkey0 + xorps $rndkey1,$inout4 + movups 0x50($inp),$iv + xorps $rndkey0,$inout5 + movups $inout0,($out) + movups $inout1,0x10($out) + movups $inout2,0x20($out) + movups $inout3,0x30($out) + movups $inout4,0x40($out) + lea 0x50($out),$out + movaps $inout5,$inout0 + sub \$0x60,$len + jmp .Lcbc_dec_tail_collected +.align 16 +.Lcbc_dec_tail_collected: + and \$15,$len + movups $iv,($ivp) + jnz .Lcbc_dec_tail_partial + movups $inout0,($out) + jmp .Lcbc_dec_ret +.align 16 +.Lcbc_dec_tail_partial: + movaps $inout0,$reserved(%rsp) + mov \$16,%rcx + mov $out,%rdi + sub $len,%rcx + lea $reserved(%rsp),%rsi + .long 0x9066A4F3 # rep movsb + +.Lcbc_dec_ret: +___ +$code.=<<___ if ($win64); + movaps (%rsp),%xmm6 + movaps 0x10(%rsp),%xmm7 + movaps 0x20(%rsp),%xmm8 + movaps 0x30(%rsp),%xmm9 + lea 0x58(%rsp),%rsp +___ +$code.=<<___; +.Lcbc_ret: + ret +.size ${PREFIX}_cbc_encrypt,.-${PREFIX}_cbc_encrypt +___ +} +# int $PREFIX_set_[en|de]crypt_key (const unsigned char *userKey, +# int bits, AES_KEY *key) +{ my ($inp,$bits,$key) = @_4args; + $bits =~ s/%r/%e/; + +$code.=<<___; +.globl ${PREFIX}_set_decrypt_key +.type ${PREFIX}_set_decrypt_key,\@abi-omnipotent +.align 16 +${PREFIX}_set_decrypt_key: + .byte 0x48,0x83,0xEC,0x08 # sub rsp,8 + call __aesni_set_encrypt_key + shl \$4,$bits # rounds-1 after _aesni_set_encrypt_key + test %eax,%eax + jnz .Ldec_key_ret + lea 16($key,$bits),$inp # points at the end of key schedule + + $movkey ($key),%xmm0 # just swap + $movkey ($inp),%xmm1 + $movkey %xmm0,($inp) + $movkey %xmm1,($key) + lea 16($key),$key + lea -16($inp),$inp + +.Ldec_key_inverse: + $movkey ($key),%xmm0 # swap and inverse + $movkey ($inp),%xmm1 + aesimc %xmm0,%xmm0 + aesimc %xmm1,%xmm1 + lea 16($key),$key + lea -16($inp),$inp + $movkey %xmm0,16($inp) + $movkey %xmm1,-16($key) + cmp $key,$inp + ja .Ldec_key_inverse + + $movkey ($key),%xmm0 # inverse middle + aesimc %xmm0,%xmm0 + $movkey %xmm0,($inp) +.Ldec_key_ret: + add \$8,%rsp + ret +.LSEH_end_set_decrypt_key: +.size ${PREFIX}_set_decrypt_key,.-${PREFIX}_set_decrypt_key +___ + +# This is based on submission by +# +# Huang Ying +# Vinodh Gopal +# Kahraman Akdemir +# +# Agressively optimized in respect to aeskeygenassist's critical path +# and is contained in %xmm0-5 to meet Win64 ABI requirement. +# +$code.=<<___; +.globl ${PREFIX}_set_encrypt_key +.type ${PREFIX}_set_encrypt_key,\@abi-omnipotent +.align 16 +${PREFIX}_set_encrypt_key: +__aesni_set_encrypt_key: + .byte 0x48,0x83,0xEC,0x08 # sub rsp,8 + mov \$-1,%rax + test $inp,$inp + jz .Lenc_key_ret + test $key,$key + jz .Lenc_key_ret + + movups ($inp),%xmm0 # pull first 128 bits of *userKey + xorps %xmm4,%xmm4 # low dword of xmm4 is assumed 0 + lea 16($key),%rax + cmp \$256,$bits + je .L14rounds + cmp \$192,$bits + je .L12rounds + cmp \$128,$bits + jne .Lbad_keybits + +.L10rounds: + mov \$9,$bits # 10 rounds for 128-bit key + $movkey %xmm0,($key) # round 0 + aeskeygenassist \$0x1,%xmm0,%xmm1 # round 1 + call .Lkey_expansion_128_cold + aeskeygenassist \$0x2,%xmm0,%xmm1 # round 2 + call .Lkey_expansion_128 + aeskeygenassist \$0x4,%xmm0,%xmm1 # round 3 + call .Lkey_expansion_128 + aeskeygenassist \$0x8,%xmm0,%xmm1 # round 4 + call .Lkey_expansion_128 + aeskeygenassist \$0x10,%xmm0,%xmm1 # round 5 + call .Lkey_expansion_128 + aeskeygenassist \$0x20,%xmm0,%xmm1 # round 6 + call .Lkey_expansion_128 + aeskeygenassist \$0x40,%xmm0,%xmm1 # round 7 + call .Lkey_expansion_128 + aeskeygenassist \$0x80,%xmm0,%xmm1 # round 8 + call .Lkey_expansion_128 + aeskeygenassist \$0x1b,%xmm0,%xmm1 # round 9 + call .Lkey_expansion_128 + aeskeygenassist \$0x36,%xmm0,%xmm1 # round 10 + call .Lkey_expansion_128 + $movkey %xmm0,(%rax) + mov $bits,80(%rax) # 240(%rdx) + xor %eax,%eax + jmp .Lenc_key_ret + +.align 16 +.L12rounds: + movq 16($inp),%xmm2 # remaining 1/3 of *userKey + mov \$11,$bits # 12 rounds for 192 + $movkey %xmm0,($key) # round 0 + aeskeygenassist \$0x1,%xmm2,%xmm1 # round 1,2 + call .Lkey_expansion_192a_cold + aeskeygenassist \$0x2,%xmm2,%xmm1 # round 2,3 + call .Lkey_expansion_192b + aeskeygenassist \$0x4,%xmm2,%xmm1 # round 4,5 + call .Lkey_expansion_192a + aeskeygenassist \$0x8,%xmm2,%xmm1 # round 5,6 + call .Lkey_expansion_192b + aeskeygenassist \$0x10,%xmm2,%xmm1 # round 7,8 + call .Lkey_expansion_192a + aeskeygenassist \$0x20,%xmm2,%xmm1 # round 8,9 + call .Lkey_expansion_192b + aeskeygenassist \$0x40,%xmm2,%xmm1 # round 10,11 + call .Lkey_expansion_192a + aeskeygenassist \$0x80,%xmm2,%xmm1 # round 11,12 + call .Lkey_expansion_192b + $movkey %xmm0,(%rax) + mov $bits,48(%rax) # 240(%rdx) + xor %rax, %rax + jmp .Lenc_key_ret + +.align 16 +.L14rounds: + movups 16($inp),%xmm2 # remaning half of *userKey + mov \$13,$bits # 14 rounds for 256 + lea 16(%rax),%rax + $movkey %xmm0,($key) # round 0 + $movkey %xmm2,16($key) # round 1 + aeskeygenassist \$0x1,%xmm2,%xmm1 # round 2 + call .Lkey_expansion_256a_cold + aeskeygenassist \$0x1,%xmm0,%xmm1 # round 3 + call .Lkey_expansion_256b + aeskeygenassist \$0x2,%xmm2,%xmm1 # round 4 + call .Lkey_expansion_256a + aeskeygenassist \$0x2,%xmm0,%xmm1 # round 5 + call .Lkey_expansion_256b + aeskeygenassist \$0x4,%xmm2,%xmm1 # round 6 + call .Lkey_expansion_256a + aeskeygenassist \$0x4,%xmm0,%xmm1 # round 7 + call .Lkey_expansion_256b + aeskeygenassist \$0x8,%xmm2,%xmm1 # round 8 + call .Lkey_expansion_256a + aeskeygenassist \$0x8,%xmm0,%xmm1 # round 9 + call .Lkey_expansion_256b + aeskeygenassist \$0x10,%xmm2,%xmm1 # round 10 + call .Lkey_expansion_256a + aeskeygenassist \$0x10,%xmm0,%xmm1 # round 11 + call .Lkey_expansion_256b + aeskeygenassist \$0x20,%xmm2,%xmm1 # round 12 + call .Lkey_expansion_256a + aeskeygenassist \$0x20,%xmm0,%xmm1 # round 13 + call .Lkey_expansion_256b + aeskeygenassist \$0x40,%xmm2,%xmm1 # round 14 + call .Lkey_expansion_256a + $movkey %xmm0,(%rax) + mov $bits,16(%rax) # 240(%rdx) + xor %rax,%rax + jmp .Lenc_key_ret + +.align 16 +.Lbad_keybits: + mov \$-2,%rax +.Lenc_key_ret: + add \$8,%rsp + ret +.LSEH_end_set_encrypt_key: + +.align 16 +.Lkey_expansion_128: + $movkey %xmm0,(%rax) + lea 16(%rax),%rax +.Lkey_expansion_128_cold: + shufps \$0b00010000,%xmm0,%xmm4 + xorps %xmm4, %xmm0 + shufps \$0b10001100,%xmm0,%xmm4 + xorps %xmm4, %xmm0 + shufps \$0b11111111,%xmm1,%xmm1 # critical path + xorps %xmm1,%xmm0 + ret + +.align 16 +.Lkey_expansion_192a: + $movkey %xmm0,(%rax) + lea 16(%rax),%rax +.Lkey_expansion_192a_cold: + movaps %xmm2, %xmm5 +.Lkey_expansion_192b_warm: + shufps \$0b00010000,%xmm0,%xmm4 + movdqa %xmm2,%xmm3 + xorps %xmm4,%xmm0 + shufps \$0b10001100,%xmm0,%xmm4 + pslldq \$4,%xmm3 + xorps %xmm4,%xmm0 + pshufd \$0b01010101,%xmm1,%xmm1 # critical path + pxor %xmm3,%xmm2 + pxor %xmm1,%xmm0 + pshufd \$0b11111111,%xmm0,%xmm3 + pxor %xmm3,%xmm2 + ret + +.align 16 +.Lkey_expansion_192b: + movaps %xmm0,%xmm3 + shufps \$0b01000100,%xmm0,%xmm5 + $movkey %xmm5,(%rax) + shufps \$0b01001110,%xmm2,%xmm3 + $movkey %xmm3,16(%rax) + lea 32(%rax),%rax + jmp .Lkey_expansion_192b_warm + +.align 16 +.Lkey_expansion_256a: + $movkey %xmm2,(%rax) + lea 16(%rax),%rax +.Lkey_expansion_256a_cold: + shufps \$0b00010000,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps \$0b10001100,%xmm0,%xmm4 + xorps %xmm4,%xmm0 + shufps \$0b11111111,%xmm1,%xmm1 # critical path + xorps %xmm1,%xmm0 + ret + +.align 16 +.Lkey_expansion_256b: + $movkey %xmm0,(%rax) + lea 16(%rax),%rax + + shufps \$0b00010000,%xmm2,%xmm4 + xorps %xmm4,%xmm2 + shufps \$0b10001100,%xmm2,%xmm4 + xorps %xmm4,%xmm2 + shufps \$0b10101010,%xmm1,%xmm1 # critical path + xorps %xmm1,%xmm2 + ret +.size ${PREFIX}_set_encrypt_key,.-${PREFIX}_set_encrypt_key +.size __aesni_set_encrypt_key,.-__aesni_set_encrypt_key +___ +} + +$code.=<<___; +.align 64 +.Lbswap_mask: + .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.Lincrement32: + .long 6,6,6,0 +.Lincrement64: + .long 1,0,0,0 +.Lxts_magic: + .long 0x87,0,1,0 + +.asciz "AES for Intel AES-NI, CRYPTOGAMS by " +.align 64 +___ + +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +___ +$code.=<<___ if ($PREFIX eq "aesni"); +.type ecb_ccm64_se_handler,\@abi-omnipotent +.align 16 +ecb_ccm64_se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + mov 8($disp),%rsi # disp->ImageBase + mov 56($disp),%r11 # disp->HandlerData + + mov 0(%r11),%r10d # HandlerData[0] + lea (%rsi,%r10),%r10 # prologue label + cmp %r10,%rbx # context->RipRsp + + mov 4(%r11),%r10d # HandlerData[1] + lea (%rsi,%r10),%r10 # epilogue label + cmp %r10,%rbx # context->Rip>=epilogue label + jae .Lcommon_seh_tail + + lea 0(%rax),%rsi # %xmm save area + lea 512($context),%rdi # &context.Xmm6 + mov \$8,%ecx # 4*sizeof(%xmm0)/sizeof(%rax) + .long 0xa548f3fc # cld; rep movsq + lea 0x58(%rax),%rax # adjust stack pointer + + jmp .Lcommon_seh_tail +.size ecb_ccm64_se_handler,.-ecb_ccm64_se_handler + +.type ctr32_se_handler,\@abi-omnipotent +.align 16 +ctr32_se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + lea .Lctr32_body(%rip),%r10 + cmp %r10,%rbx # context->Rip<"prologue" label + jb .Lcommon_seh_tail + + mov 152($context),%rax # pull context->Rsp + + lea .Lctr32_ret(%rip),%r10 + cmp %r10,%rbx + jae .Lcommon_seh_tail + + lea 0x20(%rax),%rsi # %xmm save area + lea 512($context),%rdi # &context.Xmm6 + mov \$20,%ecx # 10*sizeof(%xmm0)/sizeof(%rax) + .long 0xa548f3fc # cld; rep movsq + lea 0xc8(%rax),%rax # adjust stack pointer + + jmp .Lcommon_seh_tail +.size ctr32_se_handler,.-ctr32_se_handler + +.type xts_se_handler,\@abi-omnipotent +.align 16 +xts_se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + mov 8($disp),%rsi # disp->ImageBase + mov 56($disp),%r11 # disp->HandlerData + + mov 0(%r11),%r10d # HandlerData[0] + lea (%rsi,%r10),%r10 # prologue lable + cmp %r10,%rbx # context->RipRsp + + mov 4(%r11),%r10d # HandlerData[1] + lea (%rsi,%r10),%r10 # epilogue label + cmp %r10,%rbx # context->Rip>=epilogue label + jae .Lcommon_seh_tail + + lea 0x60(%rax),%rsi # %xmm save area + lea 512($context),%rdi # & context.Xmm6 + mov \$20,%ecx # 10*sizeof(%xmm0)/sizeof(%rax) + .long 0xa548f3fc # cld; rep movsq + lea 0x68+160(%rax),%rax # adjust stack pointer + + jmp .Lcommon_seh_tail +.size xts_se_handler,.-xts_se_handler +___ +$code.=<<___; +.type cbc_se_handler,\@abi-omnipotent +.align 16 +cbc_se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 152($context),%rax # pull context->Rsp + mov 248($context),%rbx # pull context->Rip + + lea .Lcbc_decrypt(%rip),%r10 + cmp %r10,%rbx # context->Rip<"prologue" label + jb .Lcommon_seh_tail + + lea .Lcbc_decrypt_body(%rip),%r10 + cmp %r10,%rbx # context->RipRip>="epilogue" label + jae .Lcommon_seh_tail + + lea 0(%rax),%rsi # top of stack + lea 512($context),%rdi # &context.Xmm6 + mov \$8,%ecx # 4*sizeof(%xmm0)/sizeof(%rax) + .long 0xa548f3fc # cld; rep movsq + lea 0x58(%rax),%rax # adjust stack pointer + jmp .Lcommon_seh_tail + +.Lrestore_cbc_rax: + mov 120($context),%rax + +.Lcommon_seh_tail: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$154,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size cbc_se_handler,.-cbc_se_handler + +.section .pdata +.align 4 +___ +$code.=<<___ if ($PREFIX eq "aesni"); + .rva .LSEH_begin_aesni_ecb_encrypt + .rva .LSEH_end_aesni_ecb_encrypt + .rva .LSEH_info_ecb + + .rva .LSEH_begin_aesni_ccm64_encrypt_blocks + .rva .LSEH_end_aesni_ccm64_encrypt_blocks + .rva .LSEH_info_ccm64_enc + + .rva .LSEH_begin_aesni_ccm64_decrypt_blocks + .rva .LSEH_end_aesni_ccm64_decrypt_blocks + .rva .LSEH_info_ccm64_dec + + .rva .LSEH_begin_aesni_ctr32_encrypt_blocks + .rva .LSEH_end_aesni_ctr32_encrypt_blocks + .rva .LSEH_info_ctr32 + + .rva .LSEH_begin_aesni_xts_encrypt + .rva .LSEH_end_aesni_xts_encrypt + .rva .LSEH_info_xts_enc + + .rva .LSEH_begin_aesni_xts_decrypt + .rva .LSEH_end_aesni_xts_decrypt + .rva .LSEH_info_xts_dec +___ +$code.=<<___; + .rva .LSEH_begin_${PREFIX}_cbc_encrypt + .rva .LSEH_end_${PREFIX}_cbc_encrypt + .rva .LSEH_info_cbc + + .rva ${PREFIX}_set_decrypt_key + .rva .LSEH_end_set_decrypt_key + .rva .LSEH_info_key + + .rva ${PREFIX}_set_encrypt_key + .rva .LSEH_end_set_encrypt_key + .rva .LSEH_info_key +.section .xdata +.align 8 +___ +$code.=<<___ if ($PREFIX eq "aesni"); +.LSEH_info_ecb: + .byte 9,0,0,0 + .rva ecb_ccm64_se_handler + .rva .Lecb_enc_body,.Lecb_enc_ret # HandlerData[] +.LSEH_info_ccm64_enc: + .byte 9,0,0,0 + .rva ecb_ccm64_se_handler + .rva .Lccm64_enc_body,.Lccm64_enc_ret # HandlerData[] +.LSEH_info_ccm64_dec: + .byte 9,0,0,0 + .rva ecb_ccm64_se_handler + .rva .Lccm64_dec_body,.Lccm64_dec_ret # HandlerData[] +.LSEH_info_ctr32: + .byte 9,0,0,0 + .rva ctr32_se_handler +.LSEH_info_xts_enc: + .byte 9,0,0,0 + .rva xts_se_handler + .rva .Lxts_enc_body,.Lxts_enc_epilogue # HandlerData[] +.LSEH_info_xts_dec: + .byte 9,0,0,0 + .rva xts_se_handler + .rva .Lxts_dec_body,.Lxts_dec_epilogue # HandlerData[] +___ +$code.=<<___; +.LSEH_info_cbc: + .byte 9,0,0,0 + .rva cbc_se_handler +.LSEH_info_key: + .byte 0x01,0x04,0x01,0x00 + .byte 0x04,0x02,0x00,0x00 # sub rsp,8 +___ +} + +sub rex { + local *opcode=shift; + my ($dst,$src)=@_; + my $rex=0; + + $rex|=0x04 if($dst>=8); + $rex|=0x01 if($src>=8); + push @opcode,$rex|0x40 if($rex); +} + +sub aesni { + my $line=shift; + my @opcode=(0x66); + + if ($line=~/(aeskeygenassist)\s+\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) { + rex(\@opcode,$4,$3); + push @opcode,0x0f,0x3a,0xdf; + push @opcode,0xc0|($3&7)|(($4&7)<<3); # ModR/M + my $c=$2; + push @opcode,$c=~/^0/?oct($c):$c; + return ".byte\t".join(',',@opcode); + } + elsif ($line=~/(aes[a-z]+)\s+%xmm([0-9]+),\s*%xmm([0-9]+)/) { + my %opcodelet = ( + "aesimc" => 0xdb, + "aesenc" => 0xdc, "aesenclast" => 0xdd, + "aesdec" => 0xde, "aesdeclast" => 0xdf + ); + return undef if (!defined($opcodelet{$1})); + rex(\@opcode,$3,$2); + push @opcode,0x0f,0x38,$opcodelet{$1}; + push @opcode,0xc0|($2&7)|(($3&7)<<3); # ModR/M + return ".byte\t".join(',',@opcode); + } + return $line; +} + +$code =~ s/\`([^\`]*)\`/eval($1)/gem; +$code =~ s/\b(aes.*%xmm[0-9]+).*$/aesni($1)/gem; + +print $code; + +close STDOUT; diff --git a/libs/openssl/crypto/aes/asm/bsaes-x86_64.pl b/libs/openssl/crypto/aes/asm/bsaes-x86_64.pl new file mode 100644 index 00000000..41b90f08 --- /dev/null +++ b/libs/openssl/crypto/aes/asm/bsaes-x86_64.pl @@ -0,0 +1,3108 @@ +#!/usr/bin/env perl + +################################################################### +### AES-128 [originally in CTR mode] ### +### bitsliced implementation for Intel Core 2 processors ### +### requires support of SSE extensions up to SSSE3 ### +### Author: Emilia Käsper and Peter Schwabe ### +### Date: 2009-03-19 ### +### Public domain ### +### ### +### See http://homes.esat.kuleuven.be/~ekasper/#software for ### +### further information. ### +################################################################### +# +# September 2011. +# +# Started as transliteration to "perlasm" the original code has +# undergone following changes: +# +# - code was made position-independent; +# - rounds were folded into a loop resulting in >5x size reduction +# from 12.5KB to 2.2KB; +# - above was possibile thanks to mixcolumns() modification that +# allowed to feed its output back to aesenc[last], this was +# achieved at cost of two additional inter-registers moves; +# - some instruction reordering and interleaving; +# - this module doesn't implement key setup subroutine, instead it +# relies on conversion of "conventional" key schedule as returned +# by AES_set_encrypt_key (see discussion below); +# - first and last round keys are treated differently, which allowed +# to skip one shiftrows(), reduce bit-sliced key schedule and +# speed-up conversion by 22%; +# - support for 192- and 256-bit keys was added; +# +# Resulting performance in CPU cycles spent to encrypt one byte out +# of 4096-byte buffer with 128-bit key is: +# +# Emilia's this(*) difference +# +# Core 2 9.30 8.69 +7% +# Nehalem(**) 7.63 6.98 +9% +# Atom 17.1 17.4 -2%(***) +# +# (*) Comparison is not completely fair, because "this" is ECB, +# i.e. no extra processing such as counter values calculation +# and xor-ing input as in Emilia's CTR implementation is +# performed. However, the CTR calculations stand for not more +# than 1% of total time, so comparison is *rather* fair. +# +# (**) Results were collected on Westmere, which is considered to +# be equivalent to Nehalem for this code. +# +# (***) Slowdown on Atom is rather strange per se, because original +# implementation has a number of 9+-bytes instructions, which +# are bad for Atom front-end, and which I eliminated completely. +# In attempt to address deterioration sbox() was tested in FP +# SIMD "domain" (movaps instead of movdqa, xorps instead of +# pxor, etc.). While it resulted in nominal 4% improvement on +# Atom, it hurted Westmere by more than 2x factor. +# +# As for key schedule conversion subroutine. Interface to OpenSSL +# relies on per-invocation on-the-fly conversion. This naturally +# has impact on performance, especially for short inputs. Conversion +# time in CPU cycles and its ratio to CPU cycles spent in 8x block +# function is: +# +# conversion conversion/8x block +# Core 2 240 0.22 +# Nehalem 180 0.20 +# Atom 430 0.19 +# +# The ratio values mean that 128-byte blocks will be processed +# 16-18% slower, 256-byte blocks - 9-10%, 384-byte blocks - 6-7%, +# etc. Then keep in mind that input sizes not divisible by 128 are +# *effectively* slower, especially shortest ones, e.g. consecutive +# 144-byte blocks are processed 44% slower than one would expect, +# 272 - 29%, 400 - 22%, etc. Yet, despite all these "shortcomings" +# it's still faster than ["hyper-threading-safe" code path in] +# aes-x86_64.pl on all lengths above 64 bytes... +# +# October 2011. +# +# Add decryption procedure. Performance in CPU cycles spent to decrypt +# one byte out of 4096-byte buffer with 128-bit key is: +# +# Core 2 9.83 +# Nehalem 7.74 +# Atom 19.0 +# +# November 2011. +# +# Add bsaes_xts_[en|de]crypt. Less-than-80-bytes-block performance is +# suboptimal, but XTS is meant to be used with larger blocks... +# +# + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +my ($inp,$out,$len,$key,$ivp)=("%rdi","%rsi","%rdx","%rcx"); +my @XMM=map("%xmm$_",(15,0..14)); # best on Atom, +10% over (0..15) +my $ecb=0; # suppress unreferenced ECB subroutines, spare some space... + +{ +my ($key,$rounds,$const)=("%rax","%r10d","%r11"); + +sub Sbox { +# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb +# output in lsb > [b0, b1, b4, b6, b3, b7, b2, b5] < msb +my @b=@_[0..7]; +my @t=@_[8..11]; +my @s=@_[12..15]; + &InBasisChange (@b); + &Inv_GF256 (@b[6,5,0,3,7,1,4,2],@t,@s); + &OutBasisChange (@b[7,1,4,2,6,5,0,3]); +} + +sub InBasisChange { +# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb +# output in lsb > [b6, b5, b0, b3, b7, b1, b4, b2] < msb +my @b=@_[0..7]; +$code.=<<___; + pxor @b[6], @b[5] + pxor @b[1], @b[2] + pxor @b[0], @b[3] + pxor @b[2], @b[6] + pxor @b[0], @b[5] + + pxor @b[3], @b[6] + pxor @b[7], @b[3] + pxor @b[5], @b[7] + pxor @b[4], @b[3] + pxor @b[5], @b[4] + pxor @b[1], @b[3] + + pxor @b[7], @b[2] + pxor @b[5], @b[1] +___ +} + +sub OutBasisChange { +# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb +# output in lsb > [b6, b1, b2, b4, b7, b0, b3, b5] < msb +my @b=@_[0..7]; +$code.=<<___; + pxor @b[6], @b[0] + pxor @b[4], @b[1] + pxor @b[0], @b[2] + pxor @b[6], @b[4] + pxor @b[1], @b[6] + + pxor @b[5], @b[1] + pxor @b[3], @b[5] + pxor @b[7], @b[3] + pxor @b[5], @b[7] + pxor @b[5], @b[2] + + pxor @b[7], @b[4] +___ +} + +sub InvSbox { +# input in lsb > [b0, b1, b2, b3, b4, b5, b6, b7] < msb +# output in lsb > [b0, b1, b6, b4, b2, b7, b3, b5] < msb +my @b=@_[0..7]; +my @t=@_[8..11]; +my @s=@_[12..15]; + &InvInBasisChange (@b); + &Inv_GF256 (@b[5,1,2,6,3,7,0,4],@t,@s); + &InvOutBasisChange (@b[3,7,0,4,5,1,2,6]); +} + +sub InvInBasisChange { # OutBasisChange in reverse +my @b=@_[5,1,2,6,3,7,0,4]; +$code.=<<___ + pxor @b[7], @b[4] + + pxor @b[5], @b[7] + pxor @b[5], @b[2] + pxor @b[7], @b[3] + pxor @b[3], @b[5] + pxor @b[5], @b[1] + + pxor @b[1], @b[6] + pxor @b[0], @b[2] + pxor @b[6], @b[4] + pxor @b[6], @b[0] + pxor @b[4], @b[1] +___ +} + +sub InvOutBasisChange { # InBasisChange in reverse +my @b=@_[2,5,7,3,6,1,0,4]; +$code.=<<___; + pxor @b[5], @b[1] + pxor @b[7], @b[2] + + pxor @b[1], @b[3] + pxor @b[5], @b[4] + pxor @b[5], @b[7] + pxor @b[4], @b[3] + pxor @b[0], @b[5] + pxor @b[7], @b[3] + pxor @b[2], @b[6] + pxor @b[1], @b[2] + pxor @b[3], @b[6] + + pxor @b[0], @b[3] + pxor @b[6], @b[5] +___ +} + +sub Mul_GF4 { +#;************************************************************* +#;* Mul_GF4: Input x0-x1,y0-y1 Output x0-x1 Temp t0 (8) * +#;************************************************************* +my ($x0,$x1,$y0,$y1,$t0)=@_; +$code.=<<___; + movdqa $y0, $t0 + pxor $y1, $t0 + pand $x0, $t0 + pxor $x1, $x0 + pand $y0, $x1 + pand $y1, $x0 + pxor $x1, $x0 + pxor $t0, $x1 +___ +} + +sub Mul_GF4_N { # not used, see next subroutine +# multiply and scale by N +my ($x0,$x1,$y0,$y1,$t0)=@_; +$code.=<<___; + movdqa $y0, $t0 + pxor $y1, $t0 + pand $x0, $t0 + pxor $x1, $x0 + pand $y0, $x1 + pand $y1, $x0 + pxor $x0, $x1 + pxor $t0, $x0 +___ +} + +sub Mul_GF4_N_GF4 { +# interleaved Mul_GF4_N and Mul_GF4 +my ($x0,$x1,$y0,$y1,$t0, + $x2,$x3,$y2,$y3,$t1)=@_; +$code.=<<___; + movdqa $y0, $t0 + movdqa $y2, $t1 + pxor $y1, $t0 + pxor $y3, $t1 + pand $x0, $t0 + pand $x2, $t1 + pxor $x1, $x0 + pxor $x3, $x2 + pand $y0, $x1 + pand $y2, $x3 + pand $y1, $x0 + pand $y3, $x2 + pxor $x0, $x1 + pxor $x3, $x2 + pxor $t0, $x0 + pxor $t1, $x3 +___ +} +sub Mul_GF16_2 { +my @x=@_[0..7]; +my @y=@_[8..11]; +my @t=@_[12..15]; +$code.=<<___; + movdqa @x[0], @t[0] + movdqa @x[1], @t[1] +___ + &Mul_GF4 (@x[0], @x[1], @y[0], @y[1], @t[2]); +$code.=<<___; + pxor @x[2], @t[0] + pxor @x[3], @t[1] + pxor @y[2], @y[0] + pxor @y[3], @y[1] +___ + Mul_GF4_N_GF4 (@t[0], @t[1], @y[0], @y[1], @t[3], + @x[2], @x[3], @y[2], @y[3], @t[2]); +$code.=<<___; + pxor @t[0], @x[0] + pxor @t[0], @x[2] + pxor @t[1], @x[1] + pxor @t[1], @x[3] + + movdqa @x[4], @t[0] + movdqa @x[5], @t[1] + pxor @x[6], @t[0] + pxor @x[7], @t[1] +___ + &Mul_GF4_N_GF4 (@t[0], @t[1], @y[0], @y[1], @t[3], + @x[6], @x[7], @y[2], @y[3], @t[2]); +$code.=<<___; + pxor @y[2], @y[0] + pxor @y[3], @y[1] +___ + &Mul_GF4 (@x[4], @x[5], @y[0], @y[1], @t[3]); +$code.=<<___; + pxor @t[0], @x[4] + pxor @t[0], @x[6] + pxor @t[1], @x[5] + pxor @t[1], @x[7] +___ +} +sub Inv_GF256 { +#;******************************************************************** +#;* Inv_GF256: Input x0-x7 Output x0-x7 Temp t0-t3,s0-s3 (144) * +#;******************************************************************** +my @x=@_[0..7]; +my @t=@_[8..11]; +my @s=@_[12..15]; +# direct optimizations from hardware +$code.=<<___; + movdqa @x[4], @t[3] + movdqa @x[5], @t[2] + movdqa @x[1], @t[1] + movdqa @x[7], @s[1] + movdqa @x[0], @s[0] + + pxor @x[6], @t[3] + pxor @x[7], @t[2] + pxor @x[3], @t[1] + movdqa @t[3], @s[2] + pxor @x[6], @s[1] + movdqa @t[2], @t[0] + pxor @x[2], @s[0] + movdqa @t[3], @s[3] + + por @t[1], @t[2] + por @s[0], @t[3] + pxor @t[0], @s[3] + pand @s[0], @s[2] + pxor @t[1], @s[0] + pand @t[1], @t[0] + pand @s[0], @s[3] + movdqa @x[3], @s[0] + pxor @x[2], @s[0] + pand @s[0], @s[1] + pxor @s[1], @t[3] + pxor @s[1], @t[2] + movdqa @x[4], @s[1] + movdqa @x[1], @s[0] + pxor @x[5], @s[1] + pxor @x[0], @s[0] + movdqa @s[1], @t[1] + pand @s[0], @s[1] + por @s[0], @t[1] + pxor @s[1], @t[0] + pxor @s[3], @t[3] + pxor @s[2], @t[2] + pxor @s[3], @t[1] + movdqa @x[7], @s[0] + pxor @s[2], @t[0] + movdqa @x[6], @s[1] + pxor @s[2], @t[1] + movdqa @x[5], @s[2] + pand @x[3], @s[0] + movdqa @x[4], @s[3] + pand @x[2], @s[1] + pand @x[1], @s[2] + por @x[0], @s[3] + pxor @s[0], @t[3] + pxor @s[1], @t[2] + pxor @s[2], @t[1] + pxor @s[3], @t[0] + + #Inv_GF16 \t0, \t1, \t2, \t3, \s0, \s1, \s2, \s3 + + # new smaller inversion + + movdqa @t[3], @s[0] + pand @t[1], @t[3] + pxor @t[2], @s[0] + + movdqa @t[0], @s[2] + movdqa @s[0], @s[3] + pxor @t[3], @s[2] + pand @s[2], @s[3] + + movdqa @t[1], @s[1] + pxor @t[2], @s[3] + pxor @t[0], @s[1] + + pxor @t[2], @t[3] + + pand @t[3], @s[1] + + movdqa @s[2], @t[2] + pxor @t[0], @s[1] + + pxor @s[1], @t[2] + pxor @s[1], @t[1] + + pand @t[0], @t[2] + + pxor @t[2], @s[2] + pxor @t[2], @t[1] + + pand @s[3], @s[2] + + pxor @s[0], @s[2] +___ +# output in s3, s2, s1, t1 + +# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \t2, \t3, \t0, \t1, \s0, \s1, \s2, \s3 + +# Mul_GF16_2 \x0, \x1, \x2, \x3, \x4, \x5, \x6, \x7, \s3, \s2, \s1, \t1, \s0, \t0, \t2, \t3 + &Mul_GF16_2(@x,@s[3,2,1],@t[1],@s[0],@t[0,2,3]); + +### output msb > [x3,x2,x1,x0,x7,x6,x5,x4] < lsb +} + +# AES linear components + +sub ShiftRows { +my @x=@_[0..7]; +my $mask=pop; +$code.=<<___; + pxor 0x00($key),@x[0] + pxor 0x10($key),@x[1] + pshufb $mask,@x[0] + pxor 0x20($key),@x[2] + pshufb $mask,@x[1] + pxor 0x30($key),@x[3] + pshufb $mask,@x[2] + pxor 0x40($key),@x[4] + pshufb $mask,@x[3] + pxor 0x50($key),@x[5] + pshufb $mask,@x[4] + pxor 0x60($key),@x[6] + pshufb $mask,@x[5] + pxor 0x70($key),@x[7] + pshufb $mask,@x[6] + lea 0x80($key),$key + pshufb $mask,@x[7] +___ +} + +sub MixColumns { +# modified to emit output in order suitable for feeding back to aesenc[last] +my @x=@_[0..7]; +my @t=@_[8..15]; +my $inv=@_[16]; # optional +$code.=<<___; + pshufd \$0x93, @x[0], @t[0] # x0 <<< 32 + pshufd \$0x93, @x[1], @t[1] + pxor @t[0], @x[0] # x0 ^ (x0 <<< 32) + pshufd \$0x93, @x[2], @t[2] + pxor @t[1], @x[1] + pshufd \$0x93, @x[3], @t[3] + pxor @t[2], @x[2] + pshufd \$0x93, @x[4], @t[4] + pxor @t[3], @x[3] + pshufd \$0x93, @x[5], @t[5] + pxor @t[4], @x[4] + pshufd \$0x93, @x[6], @t[6] + pxor @t[5], @x[5] + pshufd \$0x93, @x[7], @t[7] + pxor @t[6], @x[6] + pxor @t[7], @x[7] + + pxor @x[0], @t[1] + pxor @x[7], @t[0] + pxor @x[7], @t[1] + pshufd \$0x4E, @x[0], @x[0] # (x0 ^ (x0 <<< 32)) <<< 64) + pxor @x[1], @t[2] + pshufd \$0x4E, @x[1], @x[1] + pxor @x[4], @t[5] + pxor @t[0], @x[0] + pxor @x[5], @t[6] + pxor @t[1], @x[1] + pxor @x[3], @t[4] + pshufd \$0x4E, @x[4], @t[0] + pxor @x[6], @t[7] + pshufd \$0x4E, @x[5], @t[1] + pxor @x[2], @t[3] + pshufd \$0x4E, @x[3], @x[4] + pxor @x[7], @t[3] + pshufd \$0x4E, @x[7], @x[5] + pxor @x[7], @t[4] + pshufd \$0x4E, @x[6], @x[3] + pxor @t[4], @t[0] + pshufd \$0x4E, @x[2], @x[6] + pxor @t[5], @t[1] +___ +$code.=<<___ if (!$inv); + pxor @t[3], @x[4] + pxor @t[7], @x[5] + pxor @t[6], @x[3] + movdqa @t[0], @x[2] + pxor @t[2], @x[6] + movdqa @t[1], @x[7] +___ +$code.=<<___ if ($inv); + pxor @x[4], @t[3] + pxor @t[7], @x[5] + pxor @x[3], @t[6] + movdqa @t[0], @x[3] + pxor @t[2], @x[6] + movdqa @t[6], @x[2] + movdqa @t[1], @x[7] + movdqa @x[6], @x[4] + movdqa @t[3], @x[6] +___ +} + +sub InvMixColumns_orig { +my @x=@_[0..7]; +my @t=@_[8..15]; + +$code.=<<___; + # multiplication by 0x0e + pshufd \$0x93, @x[7], @t[7] + movdqa @x[2], @t[2] + pxor @x[5], @x[7] # 7 5 + pxor @x[5], @x[2] # 2 5 + pshufd \$0x93, @x[0], @t[0] + movdqa @x[5], @t[5] + pxor @x[0], @x[5] # 5 0 [1] + pxor @x[1], @x[0] # 0 1 + pshufd \$0x93, @x[1], @t[1] + pxor @x[2], @x[1] # 1 25 + pxor @x[6], @x[0] # 01 6 [2] + pxor @x[3], @x[1] # 125 3 [4] + pshufd \$0x93, @x[3], @t[3] + pxor @x[0], @x[2] # 25 016 [3] + pxor @x[7], @x[3] # 3 75 + pxor @x[6], @x[7] # 75 6 [0] + pshufd \$0x93, @x[6], @t[6] + movdqa @x[4], @t[4] + pxor @x[4], @x[6] # 6 4 + pxor @x[3], @x[4] # 4 375 [6] + pxor @x[7], @x[3] # 375 756=36 + pxor @t[5], @x[6] # 64 5 [7] + pxor @t[2], @x[3] # 36 2 + pxor @t[4], @x[3] # 362 4 [5] + pshufd \$0x93, @t[5], @t[5] +___ + my @y = @x[7,5,0,2,1,3,4,6]; +$code.=<<___; + # multiplication by 0x0b + pxor @y[0], @y[1] + pxor @t[0], @y[0] + pxor @t[1], @y[1] + pshufd \$0x93, @t[2], @t[2] + pxor @t[5], @y[0] + pxor @t[6], @y[1] + pxor @t[7], @y[0] + pshufd \$0x93, @t[4], @t[4] + pxor @t[6], @t[7] # clobber t[7] + pxor @y[0], @y[1] + + pxor @t[0], @y[3] + pshufd \$0x93, @t[0], @t[0] + pxor @t[1], @y[2] + pxor @t[1], @y[4] + pxor @t[2], @y[2] + pshufd \$0x93, @t[1], @t[1] + pxor @t[2], @y[3] + pxor @t[2], @y[5] + pxor @t[7], @y[2] + pshufd \$0x93, @t[2], @t[2] + pxor @t[3], @y[3] + pxor @t[3], @y[6] + pxor @t[3], @y[4] + pshufd \$0x93, @t[3], @t[3] + pxor @t[4], @y[7] + pxor @t[4], @y[5] + pxor @t[7], @y[7] + pxor @t[5], @y[3] + pxor @t[4], @y[4] + pxor @t[5], @t[7] # clobber t[7] even more + + pxor @t[7], @y[5] + pshufd \$0x93, @t[4], @t[4] + pxor @t[7], @y[6] + pxor @t[7], @y[4] + + pxor @t[5], @t[7] + pshufd \$0x93, @t[5], @t[5] + pxor @t[6], @t[7] # restore t[7] + + # multiplication by 0x0d + pxor @y[7], @y[4] + pxor @t[4], @y[7] + pshufd \$0x93, @t[6], @t[6] + pxor @t[0], @y[2] + pxor @t[5], @y[7] + pxor @t[2], @y[2] + pshufd \$0x93, @t[7], @t[7] + + pxor @y[1], @y[3] + pxor @t[1], @y[1] + pxor @t[0], @y[0] + pxor @t[0], @y[3] + pxor @t[5], @y[1] + pxor @t[5], @y[0] + pxor @t[7], @y[1] + pshufd \$0x93, @t[0], @t[0] + pxor @t[6], @y[0] + pxor @y[1], @y[3] + pxor @t[1], @y[4] + pshufd \$0x93, @t[1], @t[1] + + pxor @t[7], @y[7] + pxor @t[2], @y[4] + pxor @t[2], @y[5] + pshufd \$0x93, @t[2], @t[2] + pxor @t[6], @y[2] + pxor @t[3], @t[6] # clobber t[6] + pxor @y[7], @y[4] + pxor @t[6], @y[3] + + pxor @t[6], @y[6] + pxor @t[5], @y[5] + pxor @t[4], @y[6] + pshufd \$0x93, @t[4], @t[4] + pxor @t[6], @y[5] + pxor @t[7], @y[6] + pxor @t[3], @t[6] # restore t[6] + + pshufd \$0x93, @t[5], @t[5] + pshufd \$0x93, @t[6], @t[6] + pshufd \$0x93, @t[7], @t[7] + pshufd \$0x93, @t[3], @t[3] + + # multiplication by 0x09 + pxor @y[1], @y[4] + pxor @y[1], @t[1] # t[1]=y[1] + pxor @t[5], @t[0] # clobber t[0] + pxor @t[5], @t[1] + pxor @t[0], @y[3] + pxor @y[0], @t[0] # t[0]=y[0] + pxor @t[6], @t[1] + pxor @t[7], @t[6] # clobber t[6] + pxor @t[1], @y[4] + pxor @t[4], @y[7] + pxor @y[4], @t[4] # t[4]=y[4] + pxor @t[3], @y[6] + pxor @y[3], @t[3] # t[3]=y[3] + pxor @t[2], @y[5] + pxor @y[2], @t[2] # t[2]=y[2] + pxor @t[7], @t[3] + pxor @y[5], @t[5] # t[5]=y[5] + pxor @t[6], @t[2] + pxor @t[6], @t[5] + pxor @y[6], @t[6] # t[6]=y[6] + pxor @y[7], @t[7] # t[7]=y[7] + + movdqa @t[0],@XMM[0] + movdqa @t[1],@XMM[1] + movdqa @t[2],@XMM[2] + movdqa @t[3],@XMM[3] + movdqa @t[4],@XMM[4] + movdqa @t[5],@XMM[5] + movdqa @t[6],@XMM[6] + movdqa @t[7],@XMM[7] +___ +} + +sub InvMixColumns { +my @x=@_[0..7]; +my @t=@_[8..15]; + +# Thanks to Jussi Kivilinna for providing pointer to +# +# | 0e 0b 0d 09 | | 02 03 01 01 | | 05 00 04 00 | +# | 09 0e 0b 0d | = | 01 02 03 01 | x | 00 05 00 04 | +# | 0d 09 0e 0b | | 01 01 02 03 | | 04 00 05 00 | +# | 0b 0d 09 0e | | 03 01 01 02 | | 00 04 00 05 | + +$code.=<<___; + # multiplication by 0x05-0x00-0x04-0x00 + pshufd \$0x4E, @x[0], @t[0] + pshufd \$0x4E, @x[6], @t[6] + pxor @x[0], @t[0] + pshufd \$0x4E, @x[7], @t[7] + pxor @x[6], @t[6] + pshufd \$0x4E, @x[1], @t[1] + pxor @x[7], @t[7] + pshufd \$0x4E, @x[2], @t[2] + pxor @x[1], @t[1] + pshufd \$0x4E, @x[3], @t[3] + pxor @x[2], @t[2] + pxor @t[6], @x[0] + pxor @t[6], @x[1] + pshufd \$0x4E, @x[4], @t[4] + pxor @x[3], @t[3] + pxor @t[0], @x[2] + pxor @t[1], @x[3] + pshufd \$0x4E, @x[5], @t[5] + pxor @x[4], @t[4] + pxor @t[7], @x[1] + pxor @t[2], @x[4] + pxor @x[5], @t[5] + + pxor @t[7], @x[2] + pxor @t[6], @x[3] + pxor @t[6], @x[4] + pxor @t[3], @x[5] + pxor @t[4], @x[6] + pxor @t[7], @x[4] + pxor @t[7], @x[5] + pxor @t[5], @x[7] +___ + &MixColumns (@x,@t,1); # flipped 2<->3 and 4<->6 +} + +sub aesenc { # not used +my @b=@_[0..7]; +my @t=@_[8..15]; +$code.=<<___; + movdqa 0x30($const),@t[0] # .LSR +___ + &ShiftRows (@b,@t[0]); + &Sbox (@b,@t); + &MixColumns (@b[0,1,4,6,3,7,2,5],@t); +} + +sub aesenclast { # not used +my @b=@_[0..7]; +my @t=@_[8..15]; +$code.=<<___; + movdqa 0x40($const),@t[0] # .LSRM0 +___ + &ShiftRows (@b,@t[0]); + &Sbox (@b,@t); +$code.=<<___ + pxor 0x00($key),@b[0] + pxor 0x10($key),@b[1] + pxor 0x20($key),@b[4] + pxor 0x30($key),@b[6] + pxor 0x40($key),@b[3] + pxor 0x50($key),@b[7] + pxor 0x60($key),@b[2] + pxor 0x70($key),@b[5] +___ +} + +sub swapmove { +my ($a,$b,$n,$mask,$t)=@_; +$code.=<<___; + movdqa $b,$t + psrlq \$$n,$b + pxor $a,$b + pand $mask,$b + pxor $b,$a + psllq \$$n,$b + pxor $t,$b +___ +} +sub swapmove2x { +my ($a0,$b0,$a1,$b1,$n,$mask,$t0,$t1)=@_; +$code.=<<___; + movdqa $b0,$t0 + psrlq \$$n,$b0 + movdqa $b1,$t1 + psrlq \$$n,$b1 + pxor $a0,$b0 + pxor $a1,$b1 + pand $mask,$b0 + pand $mask,$b1 + pxor $b0,$a0 + psllq \$$n,$b0 + pxor $b1,$a1 + psllq \$$n,$b1 + pxor $t0,$b0 + pxor $t1,$b1 +___ +} + +sub bitslice { +my @x=reverse(@_[0..7]); +my ($t0,$t1,$t2,$t3)=@_[8..11]; +$code.=<<___; + movdqa 0x00($const),$t0 # .LBS0 + movdqa 0x10($const),$t1 # .LBS1 +___ + &swapmove2x(@x[0,1,2,3],1,$t0,$t2,$t3); + &swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3); +$code.=<<___; + movdqa 0x20($const),$t0 # .LBS2 +___ + &swapmove2x(@x[0,2,1,3],2,$t1,$t2,$t3); + &swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3); + + &swapmove2x(@x[0,4,1,5],4,$t0,$t2,$t3); + &swapmove2x(@x[2,6,3,7],4,$t0,$t2,$t3); +} + +$code.=<<___; +.text + +.extern asm_AES_encrypt +.extern asm_AES_decrypt + +.type _bsaes_encrypt8,\@abi-omnipotent +.align 64 +_bsaes_encrypt8: + lea .LBS0(%rip), $const # constants table + + movdqa ($key), @XMM[9] # round 0 key + lea 0x10($key), $key + movdqa 0x50($const), @XMM[8] # .LM0SR + pxor @XMM[9], @XMM[0] # xor with round0 key + pxor @XMM[9], @XMM[1] + pshufb @XMM[8], @XMM[0] + pxor @XMM[9], @XMM[2] + pshufb @XMM[8], @XMM[1] + pxor @XMM[9], @XMM[3] + pshufb @XMM[8], @XMM[2] + pxor @XMM[9], @XMM[4] + pshufb @XMM[8], @XMM[3] + pxor @XMM[9], @XMM[5] + pshufb @XMM[8], @XMM[4] + pxor @XMM[9], @XMM[6] + pshufb @XMM[8], @XMM[5] + pxor @XMM[9], @XMM[7] + pshufb @XMM[8], @XMM[6] + pshufb @XMM[8], @XMM[7] +_bsaes_encrypt8_bitslice: +___ + &bitslice (@XMM[0..7, 8..11]); +$code.=<<___; + dec $rounds + jmp .Lenc_sbox +.align 16 +.Lenc_loop: +___ + &ShiftRows (@XMM[0..7, 8]); +$code.=".Lenc_sbox:\n"; + &Sbox (@XMM[0..7, 8..15]); +$code.=<<___; + dec $rounds + jl .Lenc_done +___ + &MixColumns (@XMM[0,1,4,6,3,7,2,5, 8..15]); +$code.=<<___; + movdqa 0x30($const), @XMM[8] # .LSR + jnz .Lenc_loop + movdqa 0x40($const), @XMM[8] # .LSRM0 + jmp .Lenc_loop +.align 16 +.Lenc_done: +___ + # output in lsb > [t0, t1, t4, t6, t3, t7, t2, t5] < msb + &bitslice (@XMM[0,1,4,6,3,7,2,5, 8..11]); +$code.=<<___; + movdqa ($key), @XMM[8] # last round key + pxor @XMM[8], @XMM[4] + pxor @XMM[8], @XMM[6] + pxor @XMM[8], @XMM[3] + pxor @XMM[8], @XMM[7] + pxor @XMM[8], @XMM[2] + pxor @XMM[8], @XMM[5] + pxor @XMM[8], @XMM[0] + pxor @XMM[8], @XMM[1] + ret +.size _bsaes_encrypt8,.-_bsaes_encrypt8 + +.type _bsaes_decrypt8,\@abi-omnipotent +.align 64 +_bsaes_decrypt8: + lea .LBS0(%rip), $const # constants table + + movdqa ($key), @XMM[9] # round 0 key + lea 0x10($key), $key + movdqa -0x30($const), @XMM[8] # .LM0ISR + pxor @XMM[9], @XMM[0] # xor with round0 key + pxor @XMM[9], @XMM[1] + pshufb @XMM[8], @XMM[0] + pxor @XMM[9], @XMM[2] + pshufb @XMM[8], @XMM[1] + pxor @XMM[9], @XMM[3] + pshufb @XMM[8], @XMM[2] + pxor @XMM[9], @XMM[4] + pshufb @XMM[8], @XMM[3] + pxor @XMM[9], @XMM[5] + pshufb @XMM[8], @XMM[4] + pxor @XMM[9], @XMM[6] + pshufb @XMM[8], @XMM[5] + pxor @XMM[9], @XMM[7] + pshufb @XMM[8], @XMM[6] + pshufb @XMM[8], @XMM[7] +___ + &bitslice (@XMM[0..7, 8..11]); +$code.=<<___; + dec $rounds + jmp .Ldec_sbox +.align 16 +.Ldec_loop: +___ + &ShiftRows (@XMM[0..7, 8]); +$code.=".Ldec_sbox:\n"; + &InvSbox (@XMM[0..7, 8..15]); +$code.=<<___; + dec $rounds + jl .Ldec_done +___ + &InvMixColumns (@XMM[0,1,6,4,2,7,3,5, 8..15]); +$code.=<<___; + movdqa -0x10($const), @XMM[8] # .LISR + jnz .Ldec_loop + movdqa -0x20($const), @XMM[8] # .LISRM0 + jmp .Ldec_loop +.align 16 +.Ldec_done: +___ + &bitslice (@XMM[0,1,6,4,2,7,3,5, 8..11]); +$code.=<<___; + movdqa ($key), @XMM[8] # last round key + pxor @XMM[8], @XMM[6] + pxor @XMM[8], @XMM[4] + pxor @XMM[8], @XMM[2] + pxor @XMM[8], @XMM[7] + pxor @XMM[8], @XMM[3] + pxor @XMM[8], @XMM[5] + pxor @XMM[8], @XMM[0] + pxor @XMM[8], @XMM[1] + ret +.size _bsaes_decrypt8,.-_bsaes_decrypt8 +___ +} +{ +my ($out,$inp,$rounds,$const)=("%rax","%rcx","%r10d","%r11"); + +sub bitslice_key { +my @x=reverse(@_[0..7]); +my ($bs0,$bs1,$bs2,$t2,$t3)=@_[8..12]; + + &swapmove (@x[0,1],1,$bs0,$t2,$t3); +$code.=<<___; + #&swapmove(@x[2,3],1,$t0,$t2,$t3); + movdqa @x[0], @x[2] + movdqa @x[1], @x[3] +___ + #&swapmove2x(@x[4,5,6,7],1,$t0,$t2,$t3); + + &swapmove2x (@x[0,2,1,3],2,$bs1,$t2,$t3); +$code.=<<___; + #&swapmove2x(@x[4,6,5,7],2,$t1,$t2,$t3); + movdqa @x[0], @x[4] + movdqa @x[2], @x[6] + movdqa @x[1], @x[5] + movdqa @x[3], @x[7] +___ + &swapmove2x (@x[0,4,1,5],4,$bs2,$t2,$t3); + &swapmove2x (@x[2,6,3,7],4,$bs2,$t2,$t3); +} + +$code.=<<___; +.type _bsaes_key_convert,\@abi-omnipotent +.align 16 +_bsaes_key_convert: + lea .Lmasks(%rip), $const + movdqu ($inp), %xmm7 # load round 0 key + lea 0x10($inp), $inp + movdqa 0x00($const), %xmm0 # 0x01... + movdqa 0x10($const), %xmm1 # 0x02... + movdqa 0x20($const), %xmm2 # 0x04... + movdqa 0x30($const), %xmm3 # 0x08... + movdqa 0x40($const), %xmm4 # .LM0 + pcmpeqd %xmm5, %xmm5 # .LNOT + + movdqu ($inp), %xmm6 # load round 1 key + movdqa %xmm7, ($out) # save round 0 key + lea 0x10($out), $out + dec $rounds + jmp .Lkey_loop +.align 16 +.Lkey_loop: + pshufb %xmm4, %xmm6 # .LM0 + + movdqa %xmm0, %xmm8 + movdqa %xmm1, %xmm9 + + pand %xmm6, %xmm8 + pand %xmm6, %xmm9 + movdqa %xmm2, %xmm10 + pcmpeqb %xmm0, %xmm8 + psllq \$4, %xmm0 # 0x10... + movdqa %xmm3, %xmm11 + pcmpeqb %xmm1, %xmm9 + psllq \$4, %xmm1 # 0x20... + + pand %xmm6, %xmm10 + pand %xmm6, %xmm11 + movdqa %xmm0, %xmm12 + pcmpeqb %xmm2, %xmm10 + psllq \$4, %xmm2 # 0x40... + movdqa %xmm1, %xmm13 + pcmpeqb %xmm3, %xmm11 + psllq \$4, %xmm3 # 0x80... + + movdqa %xmm2, %xmm14 + movdqa %xmm3, %xmm15 + pxor %xmm5, %xmm8 # "pnot" + pxor %xmm5, %xmm9 + + pand %xmm6, %xmm12 + pand %xmm6, %xmm13 + movdqa %xmm8, 0x00($out) # write bit-sliced round key + pcmpeqb %xmm0, %xmm12 + psrlq \$4, %xmm0 # 0x01... + movdqa %xmm9, 0x10($out) + pcmpeqb %xmm1, %xmm13 + psrlq \$4, %xmm1 # 0x02... + lea 0x10($inp), $inp + + pand %xmm6, %xmm14 + pand %xmm6, %xmm15 + movdqa %xmm10, 0x20($out) + pcmpeqb %xmm2, %xmm14 + psrlq \$4, %xmm2 # 0x04... + movdqa %xmm11, 0x30($out) + pcmpeqb %xmm3, %xmm15 + psrlq \$4, %xmm3 # 0x08... + movdqu ($inp), %xmm6 # load next round key + + pxor %xmm5, %xmm13 # "pnot" + pxor %xmm5, %xmm14 + movdqa %xmm12, 0x40($out) + movdqa %xmm13, 0x50($out) + movdqa %xmm14, 0x60($out) + movdqa %xmm15, 0x70($out) + lea 0x80($out),$out + dec $rounds + jnz .Lkey_loop + + movdqa 0x50($const), %xmm7 # .L63 + #movdqa %xmm6, ($out) # don't save last round key + ret +.size _bsaes_key_convert,.-_bsaes_key_convert +___ +} + +if (0 && !$win64) { # following four functions are unsupported interface + # used for benchmarking... +$code.=<<___; +.globl bsaes_enc_key_convert +.type bsaes_enc_key_convert,\@function,2 +.align 16 +bsaes_enc_key_convert: + mov 240($inp),%r10d # pass rounds + mov $inp,%rcx # pass key + mov $out,%rax # pass key schedule + call _bsaes_key_convert + pxor %xmm6,%xmm7 # fix up last round key + movdqa %xmm7,(%rax) # save last round key + ret +.size bsaes_enc_key_convert,.-bsaes_enc_key_convert + +.globl bsaes_encrypt_128 +.type bsaes_encrypt_128,\@function,4 +.align 16 +bsaes_encrypt_128: +.Lenc128_loop: + movdqu 0x00($inp), @XMM[0] # load input + movdqu 0x10($inp), @XMM[1] + movdqu 0x20($inp), @XMM[2] + movdqu 0x30($inp), @XMM[3] + movdqu 0x40($inp), @XMM[4] + movdqu 0x50($inp), @XMM[5] + movdqu 0x60($inp), @XMM[6] + movdqu 0x70($inp), @XMM[7] + mov $key, %rax # pass the $key + lea 0x80($inp), $inp + mov \$10,%r10d + + call _bsaes_encrypt8 + + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[4], 0x20($out) + movdqu @XMM[6], 0x30($out) + movdqu @XMM[3], 0x40($out) + movdqu @XMM[7], 0x50($out) + movdqu @XMM[2], 0x60($out) + movdqu @XMM[5], 0x70($out) + lea 0x80($out), $out + sub \$0x80,$len + ja .Lenc128_loop + ret +.size bsaes_encrypt_128,.-bsaes_encrypt_128 + +.globl bsaes_dec_key_convert +.type bsaes_dec_key_convert,\@function,2 +.align 16 +bsaes_dec_key_convert: + mov 240($inp),%r10d # pass rounds + mov $inp,%rcx # pass key + mov $out,%rax # pass key schedule + call _bsaes_key_convert + pxor ($out),%xmm7 # fix up round 0 key + movdqa %xmm6,(%rax) # save last round key + movdqa %xmm7,($out) + ret +.size bsaes_dec_key_convert,.-bsaes_dec_key_convert + +.globl bsaes_decrypt_128 +.type bsaes_decrypt_128,\@function,4 +.align 16 +bsaes_decrypt_128: +.Ldec128_loop: + movdqu 0x00($inp), @XMM[0] # load input + movdqu 0x10($inp), @XMM[1] + movdqu 0x20($inp), @XMM[2] + movdqu 0x30($inp), @XMM[3] + movdqu 0x40($inp), @XMM[4] + movdqu 0x50($inp), @XMM[5] + movdqu 0x60($inp), @XMM[6] + movdqu 0x70($inp), @XMM[7] + mov $key, %rax # pass the $key + lea 0x80($inp), $inp + mov \$10,%r10d + + call _bsaes_decrypt8 + + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[6], 0x20($out) + movdqu @XMM[4], 0x30($out) + movdqu @XMM[2], 0x40($out) + movdqu @XMM[7], 0x50($out) + movdqu @XMM[3], 0x60($out) + movdqu @XMM[5], 0x70($out) + lea 0x80($out), $out + sub \$0x80,$len + ja .Ldec128_loop + ret +.size bsaes_decrypt_128,.-bsaes_decrypt_128 +___ +} +{ +###################################################################### +# +# OpenSSL interface +# +my ($arg1,$arg2,$arg3,$arg4,$arg5,$arg6)=$win64 ? ("%rcx","%rdx","%r8","%r9","%r10","%r11d") + : ("%rdi","%rsi","%rdx","%rcx","%r8","%r9d"); +my ($inp,$out,$len,$key)=("%r12","%r13","%r14","%r15"); + +if ($ecb) { +$code.=<<___; +.globl bsaes_ecb_encrypt_blocks +.type bsaes_ecb_encrypt_blocks,\@abi-omnipotent +.align 16 +bsaes_ecb_encrypt_blocks: + mov %rsp, %rax +.Lecb_enc_prologue: + push %rbp + push %rbx + push %r12 + push %r13 + push %r14 + push %r15 + lea -0x48(%rsp),%rsp +___ +$code.=<<___ if ($win64); + lea -0xa0(%rsp), %rsp + movaps %xmm6, 0x40(%rsp) + movaps %xmm7, 0x50(%rsp) + movaps %xmm8, 0x60(%rsp) + movaps %xmm9, 0x70(%rsp) + movaps %xmm10, 0x80(%rsp) + movaps %xmm11, 0x90(%rsp) + movaps %xmm12, 0xa0(%rsp) + movaps %xmm13, 0xb0(%rsp) + movaps %xmm14, 0xc0(%rsp) + movaps %xmm15, 0xd0(%rsp) +.Lecb_enc_body: +___ +$code.=<<___; + mov %rsp,%rbp # backup %rsp + mov 240($arg4),%eax # rounds + mov $arg1,$inp # backup arguments + mov $arg2,$out + mov $arg3,$len + mov $arg4,$key + cmp \$8,$arg3 + jb .Lecb_enc_short + + mov %eax,%ebx # backup rounds + shl \$7,%rax # 128 bytes per inner round key + sub \$`128-32`,%rax # size of bit-sliced key schedule + sub %rax,%rsp + mov %rsp,%rax # pass key schedule + mov $key,%rcx # pass key + mov %ebx,%r10d # pass rounds + call _bsaes_key_convert + pxor %xmm6,%xmm7 # fix up last round key + movdqa %xmm7,(%rax) # save last round key + + sub \$8,$len +.Lecb_enc_loop: + movdqu 0x00($inp), @XMM[0] # load input + movdqu 0x10($inp), @XMM[1] + movdqu 0x20($inp), @XMM[2] + movdqu 0x30($inp), @XMM[3] + movdqu 0x40($inp), @XMM[4] + movdqu 0x50($inp), @XMM[5] + mov %rsp, %rax # pass key schedule + movdqu 0x60($inp), @XMM[6] + mov %ebx,%r10d # pass rounds + movdqu 0x70($inp), @XMM[7] + lea 0x80($inp), $inp + + call _bsaes_encrypt8 + + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[4], 0x20($out) + movdqu @XMM[6], 0x30($out) + movdqu @XMM[3], 0x40($out) + movdqu @XMM[7], 0x50($out) + movdqu @XMM[2], 0x60($out) + movdqu @XMM[5], 0x70($out) + lea 0x80($out), $out + sub \$8,$len + jnc .Lecb_enc_loop + + add \$8,$len + jz .Lecb_enc_done + + movdqu 0x00($inp), @XMM[0] # load input + mov %rsp, %rax # pass key schedule + mov %ebx,%r10d # pass rounds + cmp \$2,$len + jb .Lecb_enc_one + movdqu 0x10($inp), @XMM[1] + je .Lecb_enc_two + movdqu 0x20($inp), @XMM[2] + cmp \$4,$len + jb .Lecb_enc_three + movdqu 0x30($inp), @XMM[3] + je .Lecb_enc_four + movdqu 0x40($inp), @XMM[4] + cmp \$6,$len + jb .Lecb_enc_five + movdqu 0x50($inp), @XMM[5] + je .Lecb_enc_six + movdqu 0x60($inp), @XMM[6] + call _bsaes_encrypt8 + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[4], 0x20($out) + movdqu @XMM[6], 0x30($out) + movdqu @XMM[3], 0x40($out) + movdqu @XMM[7], 0x50($out) + movdqu @XMM[2], 0x60($out) + jmp .Lecb_enc_done +.align 16 +.Lecb_enc_six: + call _bsaes_encrypt8 + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[4], 0x20($out) + movdqu @XMM[6], 0x30($out) + movdqu @XMM[3], 0x40($out) + movdqu @XMM[7], 0x50($out) + jmp .Lecb_enc_done +.align 16 +.Lecb_enc_five: + call _bsaes_encrypt8 + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[4], 0x20($out) + movdqu @XMM[6], 0x30($out) + movdqu @XMM[3], 0x40($out) + jmp .Lecb_enc_done +.align 16 +.Lecb_enc_four: + call _bsaes_encrypt8 + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[4], 0x20($out) + movdqu @XMM[6], 0x30($out) + jmp .Lecb_enc_done +.align 16 +.Lecb_enc_three: + call _bsaes_encrypt8 + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[4], 0x20($out) + jmp .Lecb_enc_done +.align 16 +.Lecb_enc_two: + call _bsaes_encrypt8 + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + jmp .Lecb_enc_done +.align 16 +.Lecb_enc_one: + call _bsaes_encrypt8 + movdqu @XMM[0], 0x00($out) # write output + jmp .Lecb_enc_done +.align 16 +.Lecb_enc_short: + lea ($inp), $arg1 + lea ($out), $arg2 + lea ($key), $arg3 + call asm_AES_encrypt + lea 16($inp), $inp + lea 16($out), $out + dec $len + jnz .Lecb_enc_short + +.Lecb_enc_done: + lea (%rsp),%rax + pxor %xmm0, %xmm0 +.Lecb_enc_bzero: # wipe key schedule [if any] + movdqa %xmm0, 0x00(%rax) + movdqa %xmm0, 0x10(%rax) + lea 0x20(%rax), %rax + cmp %rax, %rbp + jb .Lecb_enc_bzero + + lea (%rbp),%rsp # restore %rsp +___ +$code.=<<___ if ($win64); + movaps 0x40(%rbp), %xmm6 + movaps 0x50(%rbp), %xmm7 + movaps 0x60(%rbp), %xmm8 + movaps 0x70(%rbp), %xmm9 + movaps 0x80(%rbp), %xmm10 + movaps 0x90(%rbp), %xmm11 + movaps 0xa0(%rbp), %xmm12 + movaps 0xb0(%rbp), %xmm13 + movaps 0xc0(%rbp), %xmm14 + movaps 0xd0(%rbp), %xmm15 + lea 0xa0(%rbp), %rsp +___ +$code.=<<___; + mov 0x48(%rsp), %r15 + mov 0x50(%rsp), %r14 + mov 0x58(%rsp), %r13 + mov 0x60(%rsp), %r12 + mov 0x68(%rsp), %rbx + mov 0x70(%rsp), %rax + lea 0x78(%rsp), %rsp + mov %rax, %rbp +.Lecb_enc_epilogue: + ret +.size bsaes_ecb_encrypt_blocks,.-bsaes_ecb_encrypt_blocks + +.globl bsaes_ecb_decrypt_blocks +.type bsaes_ecb_decrypt_blocks,\@abi-omnipotent +.align 16 +bsaes_ecb_decrypt_blocks: + mov %rsp, %rax +.Lecb_dec_prologue: + push %rbp + push %rbx + push %r12 + push %r13 + push %r14 + push %r15 + lea -0x48(%rsp),%rsp +___ +$code.=<<___ if ($win64); + lea -0xa0(%rsp), %rsp + movaps %xmm6, 0x40(%rsp) + movaps %xmm7, 0x50(%rsp) + movaps %xmm8, 0x60(%rsp) + movaps %xmm9, 0x70(%rsp) + movaps %xmm10, 0x80(%rsp) + movaps %xmm11, 0x90(%rsp) + movaps %xmm12, 0xa0(%rsp) + movaps %xmm13, 0xb0(%rsp) + movaps %xmm14, 0xc0(%rsp) + movaps %xmm15, 0xd0(%rsp) +.Lecb_dec_body: +___ +$code.=<<___; + mov %rsp,%rbp # backup %rsp + mov 240($arg4),%eax # rounds + mov $arg1,$inp # backup arguments + mov $arg2,$out + mov $arg3,$len + mov $arg4,$key + cmp \$8,$arg3 + jb .Lecb_dec_short + + mov %eax,%ebx # backup rounds + shl \$7,%rax # 128 bytes per inner round key + sub \$`128-32`,%rax # size of bit-sliced key schedule + sub %rax,%rsp + mov %rsp,%rax # pass key schedule + mov $key,%rcx # pass key + mov %ebx,%r10d # pass rounds + call _bsaes_key_convert + pxor (%rsp),%xmm7 # fix up 0 round key + movdqa %xmm6,(%rax) # save last round key + movdqa %xmm7,(%rsp) + + sub \$8,$len +.Lecb_dec_loop: + movdqu 0x00($inp), @XMM[0] # load input + movdqu 0x10($inp), @XMM[1] + movdqu 0x20($inp), @XMM[2] + movdqu 0x30($inp), @XMM[3] + movdqu 0x40($inp), @XMM[4] + movdqu 0x50($inp), @XMM[5] + mov %rsp, %rax # pass key schedule + movdqu 0x60($inp), @XMM[6] + mov %ebx,%r10d # pass rounds + movdqu 0x70($inp), @XMM[7] + lea 0x80($inp), $inp + + call _bsaes_decrypt8 + + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[6], 0x20($out) + movdqu @XMM[4], 0x30($out) + movdqu @XMM[2], 0x40($out) + movdqu @XMM[7], 0x50($out) + movdqu @XMM[3], 0x60($out) + movdqu @XMM[5], 0x70($out) + lea 0x80($out), $out + sub \$8,$len + jnc .Lecb_dec_loop + + add \$8,$len + jz .Lecb_dec_done + + movdqu 0x00($inp), @XMM[0] # load input + mov %rsp, %rax # pass key schedule + mov %ebx,%r10d # pass rounds + cmp \$2,$len + jb .Lecb_dec_one + movdqu 0x10($inp), @XMM[1] + je .Lecb_dec_two + movdqu 0x20($inp), @XMM[2] + cmp \$4,$len + jb .Lecb_dec_three + movdqu 0x30($inp), @XMM[3] + je .Lecb_dec_four + movdqu 0x40($inp), @XMM[4] + cmp \$6,$len + jb .Lecb_dec_five + movdqu 0x50($inp), @XMM[5] + je .Lecb_dec_six + movdqu 0x60($inp), @XMM[6] + call _bsaes_decrypt8 + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[6], 0x20($out) + movdqu @XMM[4], 0x30($out) + movdqu @XMM[2], 0x40($out) + movdqu @XMM[7], 0x50($out) + movdqu @XMM[3], 0x60($out) + jmp .Lecb_dec_done +.align 16 +.Lecb_dec_six: + call _bsaes_decrypt8 + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[6], 0x20($out) + movdqu @XMM[4], 0x30($out) + movdqu @XMM[2], 0x40($out) + movdqu @XMM[7], 0x50($out) + jmp .Lecb_dec_done +.align 16 +.Lecb_dec_five: + call _bsaes_decrypt8 + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[6], 0x20($out) + movdqu @XMM[4], 0x30($out) + movdqu @XMM[2], 0x40($out) + jmp .Lecb_dec_done +.align 16 +.Lecb_dec_four: + call _bsaes_decrypt8 + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[6], 0x20($out) + movdqu @XMM[4], 0x30($out) + jmp .Lecb_dec_done +.align 16 +.Lecb_dec_three: + call _bsaes_decrypt8 + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[6], 0x20($out) + jmp .Lecb_dec_done +.align 16 +.Lecb_dec_two: + call _bsaes_decrypt8 + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + jmp .Lecb_dec_done +.align 16 +.Lecb_dec_one: + call _bsaes_decrypt8 + movdqu @XMM[0], 0x00($out) # write output + jmp .Lecb_dec_done +.align 16 +.Lecb_dec_short: + lea ($inp), $arg1 + lea ($out), $arg2 + lea ($key), $arg3 + call asm_AES_decrypt + lea 16($inp), $inp + lea 16($out), $out + dec $len + jnz .Lecb_dec_short + +.Lecb_dec_done: + lea (%rsp),%rax + pxor %xmm0, %xmm0 +.Lecb_dec_bzero: # wipe key schedule [if any] + movdqa %xmm0, 0x00(%rax) + movdqa %xmm0, 0x10(%rax) + lea 0x20(%rax), %rax + cmp %rax, %rbp + jb .Lecb_dec_bzero + + lea (%rbp),%rsp # restore %rsp +___ +$code.=<<___ if ($win64); + movaps 0x40(%rbp), %xmm6 + movaps 0x50(%rbp), %xmm7 + movaps 0x60(%rbp), %xmm8 + movaps 0x70(%rbp), %xmm9 + movaps 0x80(%rbp), %xmm10 + movaps 0x90(%rbp), %xmm11 + movaps 0xa0(%rbp), %xmm12 + movaps 0xb0(%rbp), %xmm13 + movaps 0xc0(%rbp), %xmm14 + movaps 0xd0(%rbp), %xmm15 + lea 0xa0(%rbp), %rsp +___ +$code.=<<___; + mov 0x48(%rsp), %r15 + mov 0x50(%rsp), %r14 + mov 0x58(%rsp), %r13 + mov 0x60(%rsp), %r12 + mov 0x68(%rsp), %rbx + mov 0x70(%rsp), %rax + lea 0x78(%rsp), %rsp + mov %rax, %rbp +.Lecb_dec_epilogue: + ret +.size bsaes_ecb_decrypt_blocks,.-bsaes_ecb_decrypt_blocks +___ +} +$code.=<<___; +.extern asm_AES_cbc_encrypt +.globl bsaes_cbc_encrypt +.type bsaes_cbc_encrypt,\@abi-omnipotent +.align 16 +bsaes_cbc_encrypt: +___ +$code.=<<___ if ($win64); + mov 48(%rsp),$arg6 # pull direction flag +___ +$code.=<<___; + cmp \$0,$arg6 + jne asm_AES_cbc_encrypt + cmp \$128,$arg3 + jb asm_AES_cbc_encrypt + + mov %rsp, %rax +.Lcbc_dec_prologue: + push %rbp + push %rbx + push %r12 + push %r13 + push %r14 + push %r15 + lea -0x48(%rsp), %rsp +___ +$code.=<<___ if ($win64); + mov 0xa0(%rsp),$arg5 # pull ivp + lea -0xa0(%rsp), %rsp + movaps %xmm6, 0x40(%rsp) + movaps %xmm7, 0x50(%rsp) + movaps %xmm8, 0x60(%rsp) + movaps %xmm9, 0x70(%rsp) + movaps %xmm10, 0x80(%rsp) + movaps %xmm11, 0x90(%rsp) + movaps %xmm12, 0xa0(%rsp) + movaps %xmm13, 0xb0(%rsp) + movaps %xmm14, 0xc0(%rsp) + movaps %xmm15, 0xd0(%rsp) +.Lcbc_dec_body: +___ +$code.=<<___; + mov %rsp, %rbp # backup %rsp + mov 240($arg4), %eax # rounds + mov $arg1, $inp # backup arguments + mov $arg2, $out + mov $arg3, $len + mov $arg4, $key + mov $arg5, %rbx + shr \$4, $len # bytes to blocks + + mov %eax, %edx # rounds + shl \$7, %rax # 128 bytes per inner round key + sub \$`128-32`, %rax # size of bit-sliced key schedule + sub %rax, %rsp + + mov %rsp, %rax # pass key schedule + mov $key, %rcx # pass key + mov %edx, %r10d # pass rounds + call _bsaes_key_convert + pxor (%rsp),%xmm7 # fix up 0 round key + movdqa %xmm6,(%rax) # save last round key + movdqa %xmm7,(%rsp) + + movdqu (%rbx), @XMM[15] # load IV + sub \$8,$len +.Lcbc_dec_loop: + movdqu 0x00($inp), @XMM[0] # load input + movdqu 0x10($inp), @XMM[1] + movdqu 0x20($inp), @XMM[2] + movdqu 0x30($inp), @XMM[3] + movdqu 0x40($inp), @XMM[4] + movdqu 0x50($inp), @XMM[5] + mov %rsp, %rax # pass key schedule + movdqu 0x60($inp), @XMM[6] + mov %edx,%r10d # pass rounds + movdqu 0x70($inp), @XMM[7] + movdqa @XMM[15], 0x20(%rbp) # put aside IV + + call _bsaes_decrypt8 + + pxor 0x20(%rbp), @XMM[0] # ^= IV + movdqu 0x00($inp), @XMM[8] # re-load input + movdqu 0x10($inp), @XMM[9] + pxor @XMM[8], @XMM[1] + movdqu 0x20($inp), @XMM[10] + pxor @XMM[9], @XMM[6] + movdqu 0x30($inp), @XMM[11] + pxor @XMM[10], @XMM[4] + movdqu 0x40($inp), @XMM[12] + pxor @XMM[11], @XMM[2] + movdqu 0x50($inp), @XMM[13] + pxor @XMM[12], @XMM[7] + movdqu 0x60($inp), @XMM[14] + pxor @XMM[13], @XMM[3] + movdqu 0x70($inp), @XMM[15] # IV + pxor @XMM[14], @XMM[5] + movdqu @XMM[0], 0x00($out) # write output + lea 0x80($inp), $inp + movdqu @XMM[1], 0x10($out) + movdqu @XMM[6], 0x20($out) + movdqu @XMM[4], 0x30($out) + movdqu @XMM[2], 0x40($out) + movdqu @XMM[7], 0x50($out) + movdqu @XMM[3], 0x60($out) + movdqu @XMM[5], 0x70($out) + lea 0x80($out), $out + sub \$8,$len + jnc .Lcbc_dec_loop + + add \$8,$len + jz .Lcbc_dec_done + + movdqu 0x00($inp), @XMM[0] # load input + mov %rsp, %rax # pass key schedule + mov %edx, %r10d # pass rounds + cmp \$2,$len + jb .Lcbc_dec_one + movdqu 0x10($inp), @XMM[1] + je .Lcbc_dec_two + movdqu 0x20($inp), @XMM[2] + cmp \$4,$len + jb .Lcbc_dec_three + movdqu 0x30($inp), @XMM[3] + je .Lcbc_dec_four + movdqu 0x40($inp), @XMM[4] + cmp \$6,$len + jb .Lcbc_dec_five + movdqu 0x50($inp), @XMM[5] + je .Lcbc_dec_six + movdqu 0x60($inp), @XMM[6] + movdqa @XMM[15], 0x20(%rbp) # put aside IV + call _bsaes_decrypt8 + pxor 0x20(%rbp), @XMM[0] # ^= IV + movdqu 0x00($inp), @XMM[8] # re-load input + movdqu 0x10($inp), @XMM[9] + pxor @XMM[8], @XMM[1] + movdqu 0x20($inp), @XMM[10] + pxor @XMM[9], @XMM[6] + movdqu 0x30($inp), @XMM[11] + pxor @XMM[10], @XMM[4] + movdqu 0x40($inp), @XMM[12] + pxor @XMM[11], @XMM[2] + movdqu 0x50($inp), @XMM[13] + pxor @XMM[12], @XMM[7] + movdqu 0x60($inp), @XMM[15] # IV + pxor @XMM[13], @XMM[3] + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[6], 0x20($out) + movdqu @XMM[4], 0x30($out) + movdqu @XMM[2], 0x40($out) + movdqu @XMM[7], 0x50($out) + movdqu @XMM[3], 0x60($out) + jmp .Lcbc_dec_done +.align 16 +.Lcbc_dec_six: + movdqa @XMM[15], 0x20(%rbp) # put aside IV + call _bsaes_decrypt8 + pxor 0x20(%rbp), @XMM[0] # ^= IV + movdqu 0x00($inp), @XMM[8] # re-load input + movdqu 0x10($inp), @XMM[9] + pxor @XMM[8], @XMM[1] + movdqu 0x20($inp), @XMM[10] + pxor @XMM[9], @XMM[6] + movdqu 0x30($inp), @XMM[11] + pxor @XMM[10], @XMM[4] + movdqu 0x40($inp), @XMM[12] + pxor @XMM[11], @XMM[2] + movdqu 0x50($inp), @XMM[15] # IV + pxor @XMM[12], @XMM[7] + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[6], 0x20($out) + movdqu @XMM[4], 0x30($out) + movdqu @XMM[2], 0x40($out) + movdqu @XMM[7], 0x50($out) + jmp .Lcbc_dec_done +.align 16 +.Lcbc_dec_five: + movdqa @XMM[15], 0x20(%rbp) # put aside IV + call _bsaes_decrypt8 + pxor 0x20(%rbp), @XMM[0] # ^= IV + movdqu 0x00($inp), @XMM[8] # re-load input + movdqu 0x10($inp), @XMM[9] + pxor @XMM[8], @XMM[1] + movdqu 0x20($inp), @XMM[10] + pxor @XMM[9], @XMM[6] + movdqu 0x30($inp), @XMM[11] + pxor @XMM[10], @XMM[4] + movdqu 0x40($inp), @XMM[15] # IV + pxor @XMM[11], @XMM[2] + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[6], 0x20($out) + movdqu @XMM[4], 0x30($out) + movdqu @XMM[2], 0x40($out) + jmp .Lcbc_dec_done +.align 16 +.Lcbc_dec_four: + movdqa @XMM[15], 0x20(%rbp) # put aside IV + call _bsaes_decrypt8 + pxor 0x20(%rbp), @XMM[0] # ^= IV + movdqu 0x00($inp), @XMM[8] # re-load input + movdqu 0x10($inp), @XMM[9] + pxor @XMM[8], @XMM[1] + movdqu 0x20($inp), @XMM[10] + pxor @XMM[9], @XMM[6] + movdqu 0x30($inp), @XMM[15] # IV + pxor @XMM[10], @XMM[4] + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[6], 0x20($out) + movdqu @XMM[4], 0x30($out) + jmp .Lcbc_dec_done +.align 16 +.Lcbc_dec_three: + movdqa @XMM[15], 0x20(%rbp) # put aside IV + call _bsaes_decrypt8 + pxor 0x20(%rbp), @XMM[0] # ^= IV + movdqu 0x00($inp), @XMM[8] # re-load input + movdqu 0x10($inp), @XMM[9] + pxor @XMM[8], @XMM[1] + movdqu 0x20($inp), @XMM[15] # IV + pxor @XMM[9], @XMM[6] + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + movdqu @XMM[6], 0x20($out) + jmp .Lcbc_dec_done +.align 16 +.Lcbc_dec_two: + movdqa @XMM[15], 0x20(%rbp) # put aside IV + call _bsaes_decrypt8 + pxor 0x20(%rbp), @XMM[0] # ^= IV + movdqu 0x00($inp), @XMM[8] # re-load input + movdqu 0x10($inp), @XMM[15] # IV + pxor @XMM[8], @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + jmp .Lcbc_dec_done +.align 16 +.Lcbc_dec_one: + lea ($inp), $arg1 + lea 0x20(%rbp), $arg2 # buffer output + lea ($key), $arg3 + call asm_AES_decrypt # doesn't touch %xmm + pxor 0x20(%rbp), @XMM[15] # ^= IV + movdqu @XMM[15], ($out) # write output + movdqa @XMM[0], @XMM[15] # IV + +.Lcbc_dec_done: + movdqu @XMM[15], (%rbx) # return IV + lea (%rsp), %rax + pxor %xmm0, %xmm0 +.Lcbc_dec_bzero: # wipe key schedule [if any] + movdqa %xmm0, 0x00(%rax) + movdqa %xmm0, 0x10(%rax) + lea 0x20(%rax), %rax + cmp %rax, %rbp + ja .Lcbc_dec_bzero + + lea (%rbp),%rsp # restore %rsp +___ +$code.=<<___ if ($win64); + movaps 0x40(%rbp), %xmm6 + movaps 0x50(%rbp), %xmm7 + movaps 0x60(%rbp), %xmm8 + movaps 0x70(%rbp), %xmm9 + movaps 0x80(%rbp), %xmm10 + movaps 0x90(%rbp), %xmm11 + movaps 0xa0(%rbp), %xmm12 + movaps 0xb0(%rbp), %xmm13 + movaps 0xc0(%rbp), %xmm14 + movaps 0xd0(%rbp), %xmm15 + lea 0xa0(%rbp), %rsp +___ +$code.=<<___; + mov 0x48(%rsp), %r15 + mov 0x50(%rsp), %r14 + mov 0x58(%rsp), %r13 + mov 0x60(%rsp), %r12 + mov 0x68(%rsp), %rbx + mov 0x70(%rsp), %rax + lea 0x78(%rsp), %rsp + mov %rax, %rbp +.Lcbc_dec_epilogue: + ret +.size bsaes_cbc_encrypt,.-bsaes_cbc_encrypt + +.globl bsaes_ctr32_encrypt_blocks +.type bsaes_ctr32_encrypt_blocks,\@abi-omnipotent +.align 16 +bsaes_ctr32_encrypt_blocks: + mov %rsp, %rax +.Lctr_enc_prologue: + push %rbp + push %rbx + push %r12 + push %r13 + push %r14 + push %r15 + lea -0x48(%rsp), %rsp +___ +$code.=<<___ if ($win64); + mov 0xa0(%rsp),$arg5 # pull ivp + lea -0xa0(%rsp), %rsp + movaps %xmm6, 0x40(%rsp) + movaps %xmm7, 0x50(%rsp) + movaps %xmm8, 0x60(%rsp) + movaps %xmm9, 0x70(%rsp) + movaps %xmm10, 0x80(%rsp) + movaps %xmm11, 0x90(%rsp) + movaps %xmm12, 0xa0(%rsp) + movaps %xmm13, 0xb0(%rsp) + movaps %xmm14, 0xc0(%rsp) + movaps %xmm15, 0xd0(%rsp) +.Lctr_enc_body: +___ +$code.=<<___; + mov %rsp, %rbp # backup %rsp + movdqu ($arg5), %xmm0 # load counter + mov 240($arg4), %eax # rounds + mov $arg1, $inp # backup arguments + mov $arg2, $out + mov $arg3, $len + mov $arg4, $key + movdqa %xmm0, 0x20(%rbp) # copy counter + cmp \$8, $arg3 + jb .Lctr_enc_short + + mov %eax, %ebx # rounds + shl \$7, %rax # 128 bytes per inner round key + sub \$`128-32`, %rax # size of bit-sliced key schedule + sub %rax, %rsp + + mov %rsp, %rax # pass key schedule + mov $key, %rcx # pass key + mov %ebx, %r10d # pass rounds + call _bsaes_key_convert + pxor %xmm6,%xmm7 # fix up last round key + movdqa %xmm7,(%rax) # save last round key + + movdqa (%rsp), @XMM[9] # load round0 key + lea .LADD1(%rip), %r11 + movdqa 0x20(%rbp), @XMM[0] # counter copy + movdqa -0x20(%r11), @XMM[8] # .LSWPUP + pshufb @XMM[8], @XMM[9] # byte swap upper part + pshufb @XMM[8], @XMM[0] + movdqa @XMM[9], (%rsp) # save adjusted round0 key + jmp .Lctr_enc_loop +.align 16 +.Lctr_enc_loop: + movdqa @XMM[0], 0x20(%rbp) # save counter + movdqa @XMM[0], @XMM[1] # prepare 8 counter values + movdqa @XMM[0], @XMM[2] + paddd 0x00(%r11), @XMM[1] # .LADD1 + movdqa @XMM[0], @XMM[3] + paddd 0x10(%r11), @XMM[2] # .LADD2 + movdqa @XMM[0], @XMM[4] + paddd 0x20(%r11), @XMM[3] # .LADD3 + movdqa @XMM[0], @XMM[5] + paddd 0x30(%r11), @XMM[4] # .LADD4 + movdqa @XMM[0], @XMM[6] + paddd 0x40(%r11), @XMM[5] # .LADD5 + movdqa @XMM[0], @XMM[7] + paddd 0x50(%r11), @XMM[6] # .LADD6 + paddd 0x60(%r11), @XMM[7] # .LADD7 + + # Borrow prologue from _bsaes_encrypt8 to use the opportunity + # to flip byte order in 32-bit counter + movdqa (%rsp), @XMM[9] # round 0 key + lea 0x10(%rsp), %rax # pass key schedule + movdqa -0x10(%r11), @XMM[8] # .LSWPUPM0SR + pxor @XMM[9], @XMM[0] # xor with round0 key + pxor @XMM[9], @XMM[1] + pshufb @XMM[8], @XMM[0] + pxor @XMM[9], @XMM[2] + pshufb @XMM[8], @XMM[1] + pxor @XMM[9], @XMM[3] + pshufb @XMM[8], @XMM[2] + pxor @XMM[9], @XMM[4] + pshufb @XMM[8], @XMM[3] + pxor @XMM[9], @XMM[5] + pshufb @XMM[8], @XMM[4] + pxor @XMM[9], @XMM[6] + pshufb @XMM[8], @XMM[5] + pxor @XMM[9], @XMM[7] + pshufb @XMM[8], @XMM[6] + lea .LBS0(%rip), %r11 # constants table + pshufb @XMM[8], @XMM[7] + mov %ebx,%r10d # pass rounds + + call _bsaes_encrypt8_bitslice + + sub \$8,$len + jc .Lctr_enc_loop_done + + movdqu 0x00($inp), @XMM[8] # load input + movdqu 0x10($inp), @XMM[9] + movdqu 0x20($inp), @XMM[10] + movdqu 0x30($inp), @XMM[11] + movdqu 0x40($inp), @XMM[12] + movdqu 0x50($inp), @XMM[13] + movdqu 0x60($inp), @XMM[14] + movdqu 0x70($inp), @XMM[15] + lea 0x80($inp),$inp + pxor @XMM[0], @XMM[8] + movdqa 0x20(%rbp), @XMM[0] # load counter + pxor @XMM[9], @XMM[1] + movdqu @XMM[8], 0x00($out) # write output + pxor @XMM[10], @XMM[4] + movdqu @XMM[1], 0x10($out) + pxor @XMM[11], @XMM[6] + movdqu @XMM[4], 0x20($out) + pxor @XMM[12], @XMM[3] + movdqu @XMM[6], 0x30($out) + pxor @XMM[13], @XMM[7] + movdqu @XMM[3], 0x40($out) + pxor @XMM[14], @XMM[2] + movdqu @XMM[7], 0x50($out) + pxor @XMM[15], @XMM[5] + movdqu @XMM[2], 0x60($out) + lea .LADD1(%rip), %r11 + movdqu @XMM[5], 0x70($out) + lea 0x80($out), $out + paddd 0x70(%r11), @XMM[0] # .LADD8 + jnz .Lctr_enc_loop + + jmp .Lctr_enc_done +.align 16 +.Lctr_enc_loop_done: + add \$8, $len + movdqu 0x00($inp), @XMM[8] # load input + pxor @XMM[8], @XMM[0] + movdqu @XMM[0], 0x00($out) # write output + cmp \$2,$len + jb .Lctr_enc_done + movdqu 0x10($inp), @XMM[9] + pxor @XMM[9], @XMM[1] + movdqu @XMM[1], 0x10($out) + je .Lctr_enc_done + movdqu 0x20($inp), @XMM[10] + pxor @XMM[10], @XMM[4] + movdqu @XMM[4], 0x20($out) + cmp \$4,$len + jb .Lctr_enc_done + movdqu 0x30($inp), @XMM[11] + pxor @XMM[11], @XMM[6] + movdqu @XMM[6], 0x30($out) + je .Lctr_enc_done + movdqu 0x40($inp), @XMM[12] + pxor @XMM[12], @XMM[3] + movdqu @XMM[3], 0x40($out) + cmp \$6,$len + jb .Lctr_enc_done + movdqu 0x50($inp), @XMM[13] + pxor @XMM[13], @XMM[7] + movdqu @XMM[7], 0x50($out) + je .Lctr_enc_done + movdqu 0x60($inp), @XMM[14] + pxor @XMM[14], @XMM[2] + movdqu @XMM[2], 0x60($out) + jmp .Lctr_enc_done + +.align 16 +.Lctr_enc_short: + lea 0x20(%rbp), $arg1 + lea 0x30(%rbp), $arg2 + lea ($key), $arg3 + call asm_AES_encrypt + movdqu ($inp), @XMM[1] + lea 16($inp), $inp + mov 0x2c(%rbp), %eax # load 32-bit counter + bswap %eax + pxor 0x30(%rbp), @XMM[1] + inc %eax # increment + movdqu @XMM[1], ($out) + bswap %eax + lea 16($out), $out + mov %eax, 0x2c(%rsp) # save 32-bit counter + dec $len + jnz .Lctr_enc_short + +.Lctr_enc_done: + lea (%rsp), %rax + pxor %xmm0, %xmm0 +.Lctr_enc_bzero: # wipe key schedule [if any] + movdqa %xmm0, 0x00(%rax) + movdqa %xmm0, 0x10(%rax) + lea 0x20(%rax), %rax + cmp %rax, %rbp + ja .Lctr_enc_bzero + + lea (%rbp),%rsp # restore %rsp +___ +$code.=<<___ if ($win64); + movaps 0x40(%rbp), %xmm6 + movaps 0x50(%rbp), %xmm7 + movaps 0x60(%rbp), %xmm8 + movaps 0x70(%rbp), %xmm9 + movaps 0x80(%rbp), %xmm10 + movaps 0x90(%rbp), %xmm11 + movaps 0xa0(%rbp), %xmm12 + movaps 0xb0(%rbp), %xmm13 + movaps 0xc0(%rbp), %xmm14 + movaps 0xd0(%rbp), %xmm15 + lea 0xa0(%rbp), %rsp +___ +$code.=<<___; + mov 0x48(%rsp), %r15 + mov 0x50(%rsp), %r14 + mov 0x58(%rsp), %r13 + mov 0x60(%rsp), %r12 + mov 0x68(%rsp), %rbx + mov 0x70(%rsp), %rax + lea 0x78(%rsp), %rsp + mov %rax, %rbp +.Lctr_enc_epilogue: + ret +.size bsaes_ctr32_encrypt_blocks,.-bsaes_ctr32_encrypt_blocks +___ +###################################################################### +# void bsaes_xts_[en|de]crypt(const char *inp,char *out,size_t len, +# const AES_KEY *key1, const AES_KEY *key2, +# const unsigned char iv[16]); +# +my ($twmask,$twres,$twtmp)=@XMM[13..15]; +$arg6=~s/d$//; + +$code.=<<___; +.globl bsaes_xts_encrypt +.type bsaes_xts_encrypt,\@abi-omnipotent +.align 16 +bsaes_xts_encrypt: + mov %rsp, %rax +.Lxts_enc_prologue: + push %rbp + push %rbx + push %r12 + push %r13 + push %r14 + push %r15 + lea -0x48(%rsp), %rsp +___ +$code.=<<___ if ($win64); + mov 0xa0(%rsp),$arg5 # pull key2 + mov 0xa8(%rsp),$arg6 # pull ivp + lea -0xa0(%rsp), %rsp + movaps %xmm6, 0x40(%rsp) + movaps %xmm7, 0x50(%rsp) + movaps %xmm8, 0x60(%rsp) + movaps %xmm9, 0x70(%rsp) + movaps %xmm10, 0x80(%rsp) + movaps %xmm11, 0x90(%rsp) + movaps %xmm12, 0xa0(%rsp) + movaps %xmm13, 0xb0(%rsp) + movaps %xmm14, 0xc0(%rsp) + movaps %xmm15, 0xd0(%rsp) +.Lxts_enc_body: +___ +$code.=<<___; + mov %rsp, %rbp # backup %rsp + mov $arg1, $inp # backup arguments + mov $arg2, $out + mov $arg3, $len + mov $arg4, $key + + lea ($arg6), $arg1 + lea 0x20(%rbp), $arg2 + lea ($arg5), $arg3 + call asm_AES_encrypt # generate initial tweak + + mov 240($key), %eax # rounds + mov $len, %rbx # backup $len + + mov %eax, %edx # rounds + shl \$7, %rax # 128 bytes per inner round key + sub \$`128-32`, %rax # size of bit-sliced key schedule + sub %rax, %rsp + + mov %rsp, %rax # pass key schedule + mov $key, %rcx # pass key + mov %edx, %r10d # pass rounds + call _bsaes_key_convert + pxor %xmm6, %xmm7 # fix up last round key + movdqa %xmm7, (%rax) # save last round key + + and \$-16, $len + sub \$0x80, %rsp # place for tweak[8] + movdqa 0x20(%rbp), @XMM[7] # initial tweak + + pxor $twtmp, $twtmp + movdqa .Lxts_magic(%rip), $twmask + pcmpgtd @XMM[7], $twtmp # broadcast upper bits + + sub \$0x80, $len + jc .Lxts_enc_short + jmp .Lxts_enc_loop + +.align 16 +.Lxts_enc_loop: +___ + for ($i=0;$i<7;$i++) { + $code.=<<___; + pshufd \$0x13, $twtmp, $twres + pxor $twtmp, $twtmp + movdqa @XMM[7], @XMM[$i] + movdqa @XMM[7], `0x10*$i`(%rsp)# save tweak[$i] + paddq @XMM[7], @XMM[7] # psllq 1,$tweak + pand $twmask, $twres # isolate carry and residue + pcmpgtd @XMM[7], $twtmp # broadcast upper bits + pxor $twres, @XMM[7] +___ + $code.=<<___ if ($i>=1); + movdqu `0x10*($i-1)`($inp), @XMM[8+$i-1] +___ + $code.=<<___ if ($i>=2); + pxor @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[] +___ + } +$code.=<<___; + movdqu 0x60($inp), @XMM[8+6] + pxor @XMM[8+5], @XMM[5] + movdqu 0x70($inp), @XMM[8+7] + lea 0x80($inp), $inp + movdqa @XMM[7], 0x70(%rsp) + pxor @XMM[8+6], @XMM[6] + lea 0x80(%rsp), %rax # pass key schedule + pxor @XMM[8+7], @XMM[7] + mov %edx, %r10d # pass rounds + + call _bsaes_encrypt8 + + pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + pxor 0x10(%rsp), @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + pxor 0x20(%rsp), @XMM[4] + movdqu @XMM[1], 0x10($out) + pxor 0x30(%rsp), @XMM[6] + movdqu @XMM[4], 0x20($out) + pxor 0x40(%rsp), @XMM[3] + movdqu @XMM[6], 0x30($out) + pxor 0x50(%rsp), @XMM[7] + movdqu @XMM[3], 0x40($out) + pxor 0x60(%rsp), @XMM[2] + movdqu @XMM[7], 0x50($out) + pxor 0x70(%rsp), @XMM[5] + movdqu @XMM[2], 0x60($out) + movdqu @XMM[5], 0x70($out) + lea 0x80($out), $out + + movdqa 0x70(%rsp), @XMM[7] # prepare next iteration tweak + pxor $twtmp, $twtmp + movdqa .Lxts_magic(%rip), $twmask + pcmpgtd @XMM[7], $twtmp + pshufd \$0x13, $twtmp, $twres + pxor $twtmp, $twtmp + paddq @XMM[7], @XMM[7] # psllq 1,$tweak + pand $twmask, $twres # isolate carry and residue + pcmpgtd @XMM[7], $twtmp # broadcast upper bits + pxor $twres, @XMM[7] + + sub \$0x80,$len + jnc .Lxts_enc_loop + +.Lxts_enc_short: + add \$0x80, $len + jz .Lxts_enc_done +___ + for ($i=0;$i<7;$i++) { + $code.=<<___; + pshufd \$0x13, $twtmp, $twres + pxor $twtmp, $twtmp + movdqa @XMM[7], @XMM[$i] + movdqa @XMM[7], `0x10*$i`(%rsp)# save tweak[$i] + paddq @XMM[7], @XMM[7] # psllq 1,$tweak + pand $twmask, $twres # isolate carry and residue + pcmpgtd @XMM[7], $twtmp # broadcast upper bits + pxor $twres, @XMM[7] +___ + $code.=<<___ if ($i>=1); + movdqu `0x10*($i-1)`($inp), @XMM[8+$i-1] + cmp \$`0x10*$i`,$len + je .Lxts_enc_$i +___ + $code.=<<___ if ($i>=2); + pxor @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[] +___ + } +$code.=<<___; + movdqu 0x60($inp), @XMM[8+6] + pxor @XMM[8+5], @XMM[5] + movdqa @XMM[7], 0x70(%rsp) + lea 0x70($inp), $inp + pxor @XMM[8+6], @XMM[6] + lea 0x80(%rsp), %rax # pass key schedule + mov %edx, %r10d # pass rounds + + call _bsaes_encrypt8 + + pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + pxor 0x10(%rsp), @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + pxor 0x20(%rsp), @XMM[4] + movdqu @XMM[1], 0x10($out) + pxor 0x30(%rsp), @XMM[6] + movdqu @XMM[4], 0x20($out) + pxor 0x40(%rsp), @XMM[3] + movdqu @XMM[6], 0x30($out) + pxor 0x50(%rsp), @XMM[7] + movdqu @XMM[3], 0x40($out) + pxor 0x60(%rsp), @XMM[2] + movdqu @XMM[7], 0x50($out) + movdqu @XMM[2], 0x60($out) + lea 0x70($out), $out + + movdqa 0x70(%rsp), @XMM[7] # next iteration tweak + jmp .Lxts_enc_done +.align 16 +.Lxts_enc_6: + pxor @XMM[8+4], @XMM[4] + lea 0x60($inp), $inp + pxor @XMM[8+5], @XMM[5] + lea 0x80(%rsp), %rax # pass key schedule + mov %edx, %r10d # pass rounds + + call _bsaes_encrypt8 + + pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + pxor 0x10(%rsp), @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + pxor 0x20(%rsp), @XMM[4] + movdqu @XMM[1], 0x10($out) + pxor 0x30(%rsp), @XMM[6] + movdqu @XMM[4], 0x20($out) + pxor 0x40(%rsp), @XMM[3] + movdqu @XMM[6], 0x30($out) + pxor 0x50(%rsp), @XMM[7] + movdqu @XMM[3], 0x40($out) + movdqu @XMM[7], 0x50($out) + lea 0x60($out), $out + + movdqa 0x60(%rsp), @XMM[7] # next iteration tweak + jmp .Lxts_enc_done +.align 16 +.Lxts_enc_5: + pxor @XMM[8+3], @XMM[3] + lea 0x50($inp), $inp + pxor @XMM[8+4], @XMM[4] + lea 0x80(%rsp), %rax # pass key schedule + mov %edx, %r10d # pass rounds + + call _bsaes_encrypt8 + + pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + pxor 0x10(%rsp), @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + pxor 0x20(%rsp), @XMM[4] + movdqu @XMM[1], 0x10($out) + pxor 0x30(%rsp), @XMM[6] + movdqu @XMM[4], 0x20($out) + pxor 0x40(%rsp), @XMM[3] + movdqu @XMM[6], 0x30($out) + movdqu @XMM[3], 0x40($out) + lea 0x50($out), $out + + movdqa 0x50(%rsp), @XMM[7] # next iteration tweak + jmp .Lxts_enc_done +.align 16 +.Lxts_enc_4: + pxor @XMM[8+2], @XMM[2] + lea 0x40($inp), $inp + pxor @XMM[8+3], @XMM[3] + lea 0x80(%rsp), %rax # pass key schedule + mov %edx, %r10d # pass rounds + + call _bsaes_encrypt8 + + pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + pxor 0x10(%rsp), @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + pxor 0x20(%rsp), @XMM[4] + movdqu @XMM[1], 0x10($out) + pxor 0x30(%rsp), @XMM[6] + movdqu @XMM[4], 0x20($out) + movdqu @XMM[6], 0x30($out) + lea 0x40($out), $out + + movdqa 0x40(%rsp), @XMM[7] # next iteration tweak + jmp .Lxts_enc_done +.align 16 +.Lxts_enc_3: + pxor @XMM[8+1], @XMM[1] + lea 0x30($inp), $inp + pxor @XMM[8+2], @XMM[2] + lea 0x80(%rsp), %rax # pass key schedule + mov %edx, %r10d # pass rounds + + call _bsaes_encrypt8 + + pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + pxor 0x10(%rsp), @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + pxor 0x20(%rsp), @XMM[4] + movdqu @XMM[1], 0x10($out) + movdqu @XMM[4], 0x20($out) + lea 0x30($out), $out + + movdqa 0x30(%rsp), @XMM[7] # next iteration tweak + jmp .Lxts_enc_done +.align 16 +.Lxts_enc_2: + pxor @XMM[8+0], @XMM[0] + lea 0x20($inp), $inp + pxor @XMM[8+1], @XMM[1] + lea 0x80(%rsp), %rax # pass key schedule + mov %edx, %r10d # pass rounds + + call _bsaes_encrypt8 + + pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + pxor 0x10(%rsp), @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + lea 0x20($out), $out + + movdqa 0x20(%rsp), @XMM[7] # next iteration tweak + jmp .Lxts_enc_done +.align 16 +.Lxts_enc_1: + pxor @XMM[0], @XMM[8] + lea 0x10($inp), $inp + movdqa @XMM[8], 0x20(%rbp) + lea 0x20(%rbp), $arg1 + lea 0x20(%rbp), $arg2 + lea ($key), $arg3 + call asm_AES_encrypt # doesn't touch %xmm + pxor 0x20(%rbp), @XMM[0] # ^= tweak[] + #pxor @XMM[8], @XMM[0] + #lea 0x80(%rsp), %rax # pass key schedule + #mov %edx, %r10d # pass rounds + #call _bsaes_encrypt8 + #pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + movdqu @XMM[0], 0x00($out) # write output + lea 0x10($out), $out + + movdqa 0x10(%rsp), @XMM[7] # next iteration tweak + +.Lxts_enc_done: + and \$15, %ebx + jz .Lxts_enc_ret + mov $out, %rdx + +.Lxts_enc_steal: + movzb ($inp), %eax + movzb -16(%rdx), %ecx + lea 1($inp), $inp + mov %al, -16(%rdx) + mov %cl, 0(%rdx) + lea 1(%rdx), %rdx + sub \$1,%ebx + jnz .Lxts_enc_steal + + movdqu -16($out), @XMM[0] + lea 0x20(%rbp), $arg1 + pxor @XMM[7], @XMM[0] + lea 0x20(%rbp), $arg2 + movdqa @XMM[0], 0x20(%rbp) + lea ($key), $arg3 + call asm_AES_encrypt # doesn't touch %xmm + pxor 0x20(%rbp), @XMM[7] + movdqu @XMM[7], -16($out) + +.Lxts_enc_ret: + lea (%rsp), %rax + pxor %xmm0, %xmm0 +.Lxts_enc_bzero: # wipe key schedule [if any] + movdqa %xmm0, 0x00(%rax) + movdqa %xmm0, 0x10(%rax) + lea 0x20(%rax), %rax + cmp %rax, %rbp + ja .Lxts_enc_bzero + + lea (%rbp),%rsp # restore %rsp +___ +$code.=<<___ if ($win64); + movaps 0x40(%rbp), %xmm6 + movaps 0x50(%rbp), %xmm7 + movaps 0x60(%rbp), %xmm8 + movaps 0x70(%rbp), %xmm9 + movaps 0x80(%rbp), %xmm10 + movaps 0x90(%rbp), %xmm11 + movaps 0xa0(%rbp), %xmm12 + movaps 0xb0(%rbp), %xmm13 + movaps 0xc0(%rbp), %xmm14 + movaps 0xd0(%rbp), %xmm15 + lea 0xa0(%rbp), %rsp +___ +$code.=<<___; + mov 0x48(%rsp), %r15 + mov 0x50(%rsp), %r14 + mov 0x58(%rsp), %r13 + mov 0x60(%rsp), %r12 + mov 0x68(%rsp), %rbx + mov 0x70(%rsp), %rax + lea 0x78(%rsp), %rsp + mov %rax, %rbp +.Lxts_enc_epilogue: + ret +.size bsaes_xts_encrypt,.-bsaes_xts_encrypt + +.globl bsaes_xts_decrypt +.type bsaes_xts_decrypt,\@abi-omnipotent +.align 16 +bsaes_xts_decrypt: + mov %rsp, %rax +.Lxts_dec_prologue: + push %rbp + push %rbx + push %r12 + push %r13 + push %r14 + push %r15 + lea -0x48(%rsp), %rsp +___ +$code.=<<___ if ($win64); + mov 0xa0(%rsp),$arg5 # pull key2 + mov 0xa8(%rsp),$arg6 # pull ivp + lea -0xa0(%rsp), %rsp + movaps %xmm6, 0x40(%rsp) + movaps %xmm7, 0x50(%rsp) + movaps %xmm8, 0x60(%rsp) + movaps %xmm9, 0x70(%rsp) + movaps %xmm10, 0x80(%rsp) + movaps %xmm11, 0x90(%rsp) + movaps %xmm12, 0xa0(%rsp) + movaps %xmm13, 0xb0(%rsp) + movaps %xmm14, 0xc0(%rsp) + movaps %xmm15, 0xd0(%rsp) +.Lxts_dec_body: +___ +$code.=<<___; + mov %rsp, %rbp # backup %rsp + mov $arg1, $inp # backup arguments + mov $arg2, $out + mov $arg3, $len + mov $arg4, $key + + lea ($arg6), $arg1 + lea 0x20(%rbp), $arg2 + lea ($arg5), $arg3 + call asm_AES_encrypt # generate initial tweak + + mov 240($key), %eax # rounds + mov $len, %rbx # backup $len + + mov %eax, %edx # rounds + shl \$7, %rax # 128 bytes per inner round key + sub \$`128-32`, %rax # size of bit-sliced key schedule + sub %rax, %rsp + + mov %rsp, %rax # pass key schedule + mov $key, %rcx # pass key + mov %edx, %r10d # pass rounds + call _bsaes_key_convert + pxor (%rsp), %xmm7 # fix up round 0 key + movdqa %xmm6, (%rax) # save last round key + movdqa %xmm7, (%rsp) + + xor %eax, %eax # if ($len%16) len-=16; + and \$-16, $len + test \$15, %ebx + setnz %al + shl \$4, %rax + sub %rax, $len + + sub \$0x80, %rsp # place for tweak[8] + movdqa 0x20(%rbp), @XMM[7] # initial tweak + + pxor $twtmp, $twtmp + movdqa .Lxts_magic(%rip), $twmask + pcmpgtd @XMM[7], $twtmp # broadcast upper bits + + sub \$0x80, $len + jc .Lxts_dec_short + jmp .Lxts_dec_loop + +.align 16 +.Lxts_dec_loop: +___ + for ($i=0;$i<7;$i++) { + $code.=<<___; + pshufd \$0x13, $twtmp, $twres + pxor $twtmp, $twtmp + movdqa @XMM[7], @XMM[$i] + movdqa @XMM[7], `0x10*$i`(%rsp)# save tweak[$i] + paddq @XMM[7], @XMM[7] # psllq 1,$tweak + pand $twmask, $twres # isolate carry and residue + pcmpgtd @XMM[7], $twtmp # broadcast upper bits + pxor $twres, @XMM[7] +___ + $code.=<<___ if ($i>=1); + movdqu `0x10*($i-1)`($inp), @XMM[8+$i-1] +___ + $code.=<<___ if ($i>=2); + pxor @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[] +___ + } +$code.=<<___; + movdqu 0x60($inp), @XMM[8+6] + pxor @XMM[8+5], @XMM[5] + movdqu 0x70($inp), @XMM[8+7] + lea 0x80($inp), $inp + movdqa @XMM[7], 0x70(%rsp) + pxor @XMM[8+6], @XMM[6] + lea 0x80(%rsp), %rax # pass key schedule + pxor @XMM[8+7], @XMM[7] + mov %edx, %r10d # pass rounds + + call _bsaes_decrypt8 + + pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + pxor 0x10(%rsp), @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + pxor 0x20(%rsp), @XMM[6] + movdqu @XMM[1], 0x10($out) + pxor 0x30(%rsp), @XMM[4] + movdqu @XMM[6], 0x20($out) + pxor 0x40(%rsp), @XMM[2] + movdqu @XMM[4], 0x30($out) + pxor 0x50(%rsp), @XMM[7] + movdqu @XMM[2], 0x40($out) + pxor 0x60(%rsp), @XMM[3] + movdqu @XMM[7], 0x50($out) + pxor 0x70(%rsp), @XMM[5] + movdqu @XMM[3], 0x60($out) + movdqu @XMM[5], 0x70($out) + lea 0x80($out), $out + + movdqa 0x70(%rsp), @XMM[7] # prepare next iteration tweak + pxor $twtmp, $twtmp + movdqa .Lxts_magic(%rip), $twmask + pcmpgtd @XMM[7], $twtmp + pshufd \$0x13, $twtmp, $twres + pxor $twtmp, $twtmp + paddq @XMM[7], @XMM[7] # psllq 1,$tweak + pand $twmask, $twres # isolate carry and residue + pcmpgtd @XMM[7], $twtmp # broadcast upper bits + pxor $twres, @XMM[7] + + sub \$0x80,$len + jnc .Lxts_dec_loop + +.Lxts_dec_short: + add \$0x80, $len + jz .Lxts_dec_done +___ + for ($i=0;$i<7;$i++) { + $code.=<<___; + pshufd \$0x13, $twtmp, $twres + pxor $twtmp, $twtmp + movdqa @XMM[7], @XMM[$i] + movdqa @XMM[7], `0x10*$i`(%rsp)# save tweak[$i] + paddq @XMM[7], @XMM[7] # psllq 1,$tweak + pand $twmask, $twres # isolate carry and residue + pcmpgtd @XMM[7], $twtmp # broadcast upper bits + pxor $twres, @XMM[7] +___ + $code.=<<___ if ($i>=1); + movdqu `0x10*($i-1)`($inp), @XMM[8+$i-1] + cmp \$`0x10*$i`,$len + je .Lxts_dec_$i +___ + $code.=<<___ if ($i>=2); + pxor @XMM[8+$i-2], @XMM[$i-2]# input[] ^ tweak[] +___ + } +$code.=<<___; + movdqu 0x60($inp), @XMM[8+6] + pxor @XMM[8+5], @XMM[5] + movdqa @XMM[7], 0x70(%rsp) + lea 0x70($inp), $inp + pxor @XMM[8+6], @XMM[6] + lea 0x80(%rsp), %rax # pass key schedule + mov %edx, %r10d # pass rounds + + call _bsaes_decrypt8 + + pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + pxor 0x10(%rsp), @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + pxor 0x20(%rsp), @XMM[6] + movdqu @XMM[1], 0x10($out) + pxor 0x30(%rsp), @XMM[4] + movdqu @XMM[6], 0x20($out) + pxor 0x40(%rsp), @XMM[2] + movdqu @XMM[4], 0x30($out) + pxor 0x50(%rsp), @XMM[7] + movdqu @XMM[2], 0x40($out) + pxor 0x60(%rsp), @XMM[3] + movdqu @XMM[7], 0x50($out) + movdqu @XMM[3], 0x60($out) + lea 0x70($out), $out + + movdqa 0x70(%rsp), @XMM[7] # next iteration tweak + jmp .Lxts_dec_done +.align 16 +.Lxts_dec_6: + pxor @XMM[8+4], @XMM[4] + lea 0x60($inp), $inp + pxor @XMM[8+5], @XMM[5] + lea 0x80(%rsp), %rax # pass key schedule + mov %edx, %r10d # pass rounds + + call _bsaes_decrypt8 + + pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + pxor 0x10(%rsp), @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + pxor 0x20(%rsp), @XMM[6] + movdqu @XMM[1], 0x10($out) + pxor 0x30(%rsp), @XMM[4] + movdqu @XMM[6], 0x20($out) + pxor 0x40(%rsp), @XMM[2] + movdqu @XMM[4], 0x30($out) + pxor 0x50(%rsp), @XMM[7] + movdqu @XMM[2], 0x40($out) + movdqu @XMM[7], 0x50($out) + lea 0x60($out), $out + + movdqa 0x60(%rsp), @XMM[7] # next iteration tweak + jmp .Lxts_dec_done +.align 16 +.Lxts_dec_5: + pxor @XMM[8+3], @XMM[3] + lea 0x50($inp), $inp + pxor @XMM[8+4], @XMM[4] + lea 0x80(%rsp), %rax # pass key schedule + mov %edx, %r10d # pass rounds + + call _bsaes_decrypt8 + + pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + pxor 0x10(%rsp), @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + pxor 0x20(%rsp), @XMM[6] + movdqu @XMM[1], 0x10($out) + pxor 0x30(%rsp), @XMM[4] + movdqu @XMM[6], 0x20($out) + pxor 0x40(%rsp), @XMM[2] + movdqu @XMM[4], 0x30($out) + movdqu @XMM[2], 0x40($out) + lea 0x50($out), $out + + movdqa 0x50(%rsp), @XMM[7] # next iteration tweak + jmp .Lxts_dec_done +.align 16 +.Lxts_dec_4: + pxor @XMM[8+2], @XMM[2] + lea 0x40($inp), $inp + pxor @XMM[8+3], @XMM[3] + lea 0x80(%rsp), %rax # pass key schedule + mov %edx, %r10d # pass rounds + + call _bsaes_decrypt8 + + pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + pxor 0x10(%rsp), @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + pxor 0x20(%rsp), @XMM[6] + movdqu @XMM[1], 0x10($out) + pxor 0x30(%rsp), @XMM[4] + movdqu @XMM[6], 0x20($out) + movdqu @XMM[4], 0x30($out) + lea 0x40($out), $out + + movdqa 0x40(%rsp), @XMM[7] # next iteration tweak + jmp .Lxts_dec_done +.align 16 +.Lxts_dec_3: + pxor @XMM[8+1], @XMM[1] + lea 0x30($inp), $inp + pxor @XMM[8+2], @XMM[2] + lea 0x80(%rsp), %rax # pass key schedule + mov %edx, %r10d # pass rounds + + call _bsaes_decrypt8 + + pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + pxor 0x10(%rsp), @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + pxor 0x20(%rsp), @XMM[6] + movdqu @XMM[1], 0x10($out) + movdqu @XMM[6], 0x20($out) + lea 0x30($out), $out + + movdqa 0x30(%rsp), @XMM[7] # next iteration tweak + jmp .Lxts_dec_done +.align 16 +.Lxts_dec_2: + pxor @XMM[8+0], @XMM[0] + lea 0x20($inp), $inp + pxor @XMM[8+1], @XMM[1] + lea 0x80(%rsp), %rax # pass key schedule + mov %edx, %r10d # pass rounds + + call _bsaes_decrypt8 + + pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + pxor 0x10(%rsp), @XMM[1] + movdqu @XMM[0], 0x00($out) # write output + movdqu @XMM[1], 0x10($out) + lea 0x20($out), $out + + movdqa 0x20(%rsp), @XMM[7] # next iteration tweak + jmp .Lxts_dec_done +.align 16 +.Lxts_dec_1: + pxor @XMM[0], @XMM[8] + lea 0x10($inp), $inp + movdqa @XMM[8], 0x20(%rbp) + lea 0x20(%rbp), $arg1 + lea 0x20(%rbp), $arg2 + lea ($key), $arg3 + call asm_AES_decrypt # doesn't touch %xmm + pxor 0x20(%rbp), @XMM[0] # ^= tweak[] + #pxor @XMM[8], @XMM[0] + #lea 0x80(%rsp), %rax # pass key schedule + #mov %edx, %r10d # pass rounds + #call _bsaes_decrypt8 + #pxor 0x00(%rsp), @XMM[0] # ^= tweak[] + movdqu @XMM[0], 0x00($out) # write output + lea 0x10($out), $out + + movdqa 0x10(%rsp), @XMM[7] # next iteration tweak + +.Lxts_dec_done: + and \$15, %ebx + jz .Lxts_dec_ret + + pxor $twtmp, $twtmp + movdqa .Lxts_magic(%rip), $twmask + pcmpgtd @XMM[7], $twtmp + pshufd \$0x13, $twtmp, $twres + movdqa @XMM[7], @XMM[6] + paddq @XMM[7], @XMM[7] # psllq 1,$tweak + pand $twmask, $twres # isolate carry and residue + movdqu ($inp), @XMM[0] + pxor $twres, @XMM[7] + + lea 0x20(%rbp), $arg1 + pxor @XMM[7], @XMM[0] + lea 0x20(%rbp), $arg2 + movdqa @XMM[0], 0x20(%rbp) + lea ($key), $arg3 + call asm_AES_decrypt # doesn't touch %xmm + pxor 0x20(%rbp), @XMM[7] + mov $out, %rdx + movdqu @XMM[7], ($out) + +.Lxts_dec_steal: + movzb 16($inp), %eax + movzb (%rdx), %ecx + lea 1($inp), $inp + mov %al, (%rdx) + mov %cl, 16(%rdx) + lea 1(%rdx), %rdx + sub \$1,%ebx + jnz .Lxts_dec_steal + + movdqu ($out), @XMM[0] + lea 0x20(%rbp), $arg1 + pxor @XMM[6], @XMM[0] + lea 0x20(%rbp), $arg2 + movdqa @XMM[0], 0x20(%rbp) + lea ($key), $arg3 + call asm_AES_decrypt # doesn't touch %xmm + pxor 0x20(%rbp), @XMM[6] + movdqu @XMM[6], ($out) + +.Lxts_dec_ret: + lea (%rsp), %rax + pxor %xmm0, %xmm0 +.Lxts_dec_bzero: # wipe key schedule [if any] + movdqa %xmm0, 0x00(%rax) + movdqa %xmm0, 0x10(%rax) + lea 0x20(%rax), %rax + cmp %rax, %rbp + ja .Lxts_dec_bzero + + lea (%rbp),%rsp # restore %rsp +___ +$code.=<<___ if ($win64); + movaps 0x40(%rbp), %xmm6 + movaps 0x50(%rbp), %xmm7 + movaps 0x60(%rbp), %xmm8 + movaps 0x70(%rbp), %xmm9 + movaps 0x80(%rbp), %xmm10 + movaps 0x90(%rbp), %xmm11 + movaps 0xa0(%rbp), %xmm12 + movaps 0xb0(%rbp), %xmm13 + movaps 0xc0(%rbp), %xmm14 + movaps 0xd0(%rbp), %xmm15 + lea 0xa0(%rbp), %rsp +___ +$code.=<<___; + mov 0x48(%rsp), %r15 + mov 0x50(%rsp), %r14 + mov 0x58(%rsp), %r13 + mov 0x60(%rsp), %r12 + mov 0x68(%rsp), %rbx + mov 0x70(%rsp), %rax + lea 0x78(%rsp), %rsp + mov %rax, %rbp +.Lxts_dec_epilogue: + ret +.size bsaes_xts_decrypt,.-bsaes_xts_decrypt +___ +} +$code.=<<___; +.type _bsaes_const,\@object +.align 64 +_bsaes_const: +.LM0ISR: # InvShiftRows constants + .quad 0x0a0e0206070b0f03, 0x0004080c0d010509 +.LISRM0: + .quad 0x01040b0e0205080f, 0x0306090c00070a0d +.LISR: + .quad 0x0504070602010003, 0x0f0e0d0c080b0a09 +.LBS0: # bit-slice constants + .quad 0x5555555555555555, 0x5555555555555555 +.LBS1: + .quad 0x3333333333333333, 0x3333333333333333 +.LBS2: + .quad 0x0f0f0f0f0f0f0f0f, 0x0f0f0f0f0f0f0f0f +.LSR: # shiftrows constants + .quad 0x0504070600030201, 0x0f0e0d0c0a09080b +.LSRM0: + .quad 0x0304090e00050a0f, 0x01060b0c0207080d +.LM0SR: + .quad 0x0a0e02060f03070b, 0x0004080c05090d01 +.LSWPUP: # byte-swap upper dword + .quad 0x0706050403020100, 0x0c0d0e0f0b0a0908 +.LSWPUPM0SR: + .quad 0x0a0d02060c03070b, 0x0004080f05090e01 +.LADD1: # counter increment constants + .quad 0x0000000000000000, 0x0000000100000000 +.LADD2: + .quad 0x0000000000000000, 0x0000000200000000 +.LADD3: + .quad 0x0000000000000000, 0x0000000300000000 +.LADD4: + .quad 0x0000000000000000, 0x0000000400000000 +.LADD5: + .quad 0x0000000000000000, 0x0000000500000000 +.LADD6: + .quad 0x0000000000000000, 0x0000000600000000 +.LADD7: + .quad 0x0000000000000000, 0x0000000700000000 +.LADD8: + .quad 0x0000000000000000, 0x0000000800000000 +.Lxts_magic: + .long 0x87,0,1,0 +.Lmasks: + .quad 0x0101010101010101, 0x0101010101010101 + .quad 0x0202020202020202, 0x0202020202020202 + .quad 0x0404040404040404, 0x0404040404040404 + .quad 0x0808080808080808, 0x0808080808080808 +.LM0: + .quad 0x02060a0e03070b0f, 0x0004080c0105090d +.L63: + .quad 0x6363636363636363, 0x6363636363636363 +.asciz "Bit-sliced AES for x86_64/SSSE3, Emilia Käsper, Peter Schwabe, Andy Polyakov" +.align 64 +.size _bsaes_const,.-_bsaes_const +___ + +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type se_handler,\@abi-omnipotent +.align 16 +se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + mov 8($disp),%rsi # disp->ImageBase + mov 56($disp),%r11 # disp->HandlerData + + mov 0(%r11),%r10d # HandlerData[0] + lea (%rsi,%r10),%r10 # prologue label + cmp %r10,%rbx # context->RipRsp + + mov 4(%r11),%r10d # HandlerData[1] + lea (%rsi,%r10),%r10 # epilogue label + cmp %r10,%rbx # context->Rip>=epilogue label + jae .Lin_prologue + + mov 160($context),%rax # pull context->Rbp + + lea 0x40(%rax),%rsi # %xmm save area + lea 512($context),%rdi # &context.Xmm6 + mov \$20,%ecx # 10*sizeof(%xmm0)/sizeof(%rax) + .long 0xa548f3fc # cld; rep movsq + lea 0xa0(%rax),%rax # adjust stack pointer + + mov 0x70(%rax),%rbp + mov 0x68(%rax),%rbx + mov 0x60(%rax),%r12 + mov 0x58(%rax),%r13 + mov 0x50(%rax),%r14 + mov 0x48(%rax),%r15 + lea 0x78(%rax),%rax # adjust stack pointer + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + +.Lin_prologue: + mov %rax,152($context) # restore context->Rsp + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$`1232/8`,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size se_handler,.-se_handler + +.section .pdata +.align 4 +___ +$code.=<<___ if ($ecb); + .rva .Lecb_enc_prologue + .rva .Lecb_enc_epilogue + .rva .Lecb_enc_info + + .rva .Lecb_dec_prologue + .rva .Lecb_dec_epilogue + .rva .Lecb_dec_info +___ +$code.=<<___; + .rva .Lcbc_dec_prologue + .rva .Lcbc_dec_epilogue + .rva .Lcbc_dec_info + + .rva .Lctr_enc_prologue + .rva .Lctr_enc_epilogue + .rva .Lctr_enc_info + + .rva .Lxts_enc_prologue + .rva .Lxts_enc_epilogue + .rva .Lxts_enc_info + + .rva .Lxts_dec_prologue + .rva .Lxts_dec_epilogue + .rva .Lxts_dec_info + +.section .xdata +.align 8 +___ +$code.=<<___ if ($ecb); +.Lecb_enc_info: + .byte 9,0,0,0 + .rva se_handler + .rva .Lecb_enc_body,.Lecb_enc_epilogue # HandlerData[] +.Lecb_dec_info: + .byte 9,0,0,0 + .rva se_handler + .rva .Lecb_dec_body,.Lecb_dec_epilogue # HandlerData[] +___ +$code.=<<___; +.Lcbc_dec_info: + .byte 9,0,0,0 + .rva se_handler + .rva .Lcbc_dec_body,.Lcbc_dec_epilogue # HandlerData[] +.Lctr_enc_info: + .byte 9,0,0,0 + .rva se_handler + .rva .Lctr_enc_body,.Lctr_enc_epilogue # HandlerData[] +.Lxts_enc_info: + .byte 9,0,0,0 + .rva se_handler + .rva .Lxts_enc_body,.Lxts_enc_epilogue # HandlerData[] +.Lxts_dec_info: + .byte 9,0,0,0 + .rva se_handler + .rva .Lxts_dec_body,.Lxts_dec_epilogue # HandlerData[] +___ +} + +$code =~ s/\`([^\`]*)\`/eval($1)/gem; + +print $code; + +close STDOUT; diff --git a/libs/openssl/crypto/aes/asm/vpaes-x86.pl b/libs/openssl/crypto/aes/asm/vpaes-x86.pl new file mode 100644 index 00000000..1533e2c3 --- /dev/null +++ b/libs/openssl/crypto/aes/asm/vpaes-x86.pl @@ -0,0 +1,903 @@ +#!/usr/bin/env perl + +###################################################################### +## Constant-time SSSE3 AES core implementation. +## version 0.1 +## +## By Mike Hamburg (Stanford University), 2009 +## Public domain. +## +## For details see http://shiftleft.org/papers/vector_aes/ and +## http://crypto.stanford.edu/vpaes/. + +###################################################################### +# September 2011. +# +# Port vpaes-x86_64.pl as 32-bit "almost" drop-in replacement for +# aes-586.pl. "Almost" refers to the fact that AES_cbc_encrypt +# doesn't handle partial vectors (doesn't have to if called from +# EVP only). "Drop-in" implies that this module doesn't share key +# schedule structure with the original nor does it make assumption +# about its alignment... +# +# Performance summary. aes-586.pl column lists large-block CBC +# encrypt/decrypt/with-hyper-threading-off(*) results in cycles per +# byte processed with 128-bit key, and vpaes-x86.pl column - [also +# large-block CBC] encrypt/decrypt. +# +# aes-586.pl vpaes-x86.pl +# +# Core 2(**) 29.1/42.3/18.3 22.0/25.6(***) +# Nehalem 27.9/40.4/18.1 10.3/12.0 +# Atom 102./119./60.1 64.5/85.3(***) +# +# (*) "Hyper-threading" in the context refers rather to cache shared +# among multiple cores, than to specifically Intel HTT. As vast +# majority of contemporary cores share cache, slower code path +# is common place. In other words "with-hyper-threading-off" +# results are presented mostly for reference purposes. +# +# (**) "Core 2" refers to initial 65nm design, a.k.a. Conroe. +# +# (***) Less impressive improvement on Core 2 and Atom is due to slow +# pshufb, yet it's respectable +32%/65% improvement on Core 2 +# and +58%/40% on Atom (as implied, over "hyper-threading-safe" +# code path). +# +# + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"vpaes-x86.pl",$x86only = $ARGV[$#ARGV] eq "386"); + +$PREFIX="vpaes"; + +my ($round, $base, $magic, $key, $const, $inp, $out)= + ("eax", "ebx", "ecx", "edx","ebp", "esi","edi"); + +&static_label("_vpaes_consts"); +&static_label("_vpaes_schedule_low_round"); + +&set_label("_vpaes_consts",64); +$k_inv=-0x30; # inv, inva + &data_word(0x0D080180,0x0E05060F,0x0A0B0C02,0x04070309); + &data_word(0x0F0B0780,0x01040A06,0x02050809,0x030D0E0C); + +$k_s0F=-0x10; # s0F + &data_word(0x0F0F0F0F,0x0F0F0F0F,0x0F0F0F0F,0x0F0F0F0F); + +$k_ipt=0x00; # input transform (lo, hi) + &data_word(0x5A2A7000,0xC2B2E898,0x52227808,0xCABAE090); + &data_word(0x317C4D00,0x4C01307D,0xB0FDCC81,0xCD80B1FC); + +$k_sb1=0x20; # sb1u, sb1t + &data_word(0xCB503E00,0xB19BE18F,0x142AF544,0xA5DF7A6E); + &data_word(0xFAE22300,0x3618D415,0x0D2ED9EF,0x3BF7CCC1); +$k_sb2=0x40; # sb2u, sb2t + &data_word(0x0B712400,0xE27A93C6,0xBC982FCD,0x5EB7E955); + &data_word(0x0AE12900,0x69EB8840,0xAB82234A,0xC2A163C8); +$k_sbo=0x60; # sbou, sbot + &data_word(0x6FBDC700,0xD0D26D17,0xC502A878,0x15AABF7A); + &data_word(0x5FBB6A00,0xCFE474A5,0x412B35FA,0x8E1E90D1); + +$k_mc_forward=0x80; # mc_forward + &data_word(0x00030201,0x04070605,0x080B0A09,0x0C0F0E0D); + &data_word(0x04070605,0x080B0A09,0x0C0F0E0D,0x00030201); + &data_word(0x080B0A09,0x0C0F0E0D,0x00030201,0x04070605); + &data_word(0x0C0F0E0D,0x00030201,0x04070605,0x080B0A09); + +$k_mc_backward=0xc0; # mc_backward + &data_word(0x02010003,0x06050407,0x0A09080B,0x0E0D0C0F); + &data_word(0x0E0D0C0F,0x02010003,0x06050407,0x0A09080B); + &data_word(0x0A09080B,0x0E0D0C0F,0x02010003,0x06050407); + &data_word(0x06050407,0x0A09080B,0x0E0D0C0F,0x02010003); + +$k_sr=0x100; # sr + &data_word(0x03020100,0x07060504,0x0B0A0908,0x0F0E0D0C); + &data_word(0x0F0A0500,0x030E0904,0x07020D08,0x0B06010C); + &data_word(0x0B020900,0x0F060D04,0x030A0108,0x070E050C); + &data_word(0x070A0D00,0x0B0E0104,0x0F020508,0x0306090C); + +$k_rcon=0x140; # rcon + &data_word(0xAF9DEEB6,0x1F8391B9,0x4D7C7D81,0x702A9808); + +$k_s63=0x150; # s63: all equal to 0x63 transformed + &data_word(0x5B5B5B5B,0x5B5B5B5B,0x5B5B5B5B,0x5B5B5B5B); + +$k_opt=0x160; # output transform + &data_word(0xD6B66000,0xFF9F4929,0xDEBE6808,0xF7974121); + &data_word(0x50BCEC00,0x01EDBD51,0xB05C0CE0,0xE10D5DB1); + +$k_deskew=0x180; # deskew tables: inverts the sbox's "skew" + &data_word(0x47A4E300,0x07E4A340,0x5DBEF91A,0x1DFEB95A); + &data_word(0x83EA6900,0x5F36B5DC,0xF49D1E77,0x2841C2AB); +## +## Decryption stuff +## Key schedule constants +## +$k_dksd=0x1a0; # decryption key schedule: invskew x*D + &data_word(0xA3E44700,0xFEB91A5D,0x5A1DBEF9,0x0740E3A4); + &data_word(0xB5368300,0x41C277F4,0xAB289D1E,0x5FDC69EA); +$k_dksb=0x1c0; # decryption key schedule: invskew x*B + &data_word(0x8550D500,0x9A4FCA1F,0x1CC94C99,0x03D65386); + &data_word(0xB6FC4A00,0x115BEDA7,0x7E3482C8,0xD993256F); +$k_dkse=0x1e0; # decryption key schedule: invskew x*E + 0x63 + &data_word(0x1FC9D600,0xD5031CCA,0x994F5086,0x53859A4C); + &data_word(0x4FDC7BE8,0xA2319605,0x20B31487,0xCD5EF96A); +$k_dks9=0x200; # decryption key schedule: invskew x*9 + &data_word(0x7ED9A700,0xB6116FC8,0x82255BFC,0x4AED9334); + &data_word(0x27143300,0x45765162,0xE9DAFDCE,0x8BB89FAC); + +## +## Decryption stuff +## Round function constants +## +$k_dipt=0x220; # decryption input transform + &data_word(0x0B545F00,0x0F505B04,0x114E451A,0x154A411E); + &data_word(0x60056500,0x86E383E6,0xF491F194,0x12771772); + +$k_dsb9=0x240; # decryption sbox output *9*u, *9*t + &data_word(0x9A86D600,0x851C0353,0x4F994CC9,0xCAD51F50); + &data_word(0xECD74900,0xC03B1789,0xB2FBA565,0x725E2C9E); +$k_dsbd=0x260; # decryption sbox output *D*u, *D*t + &data_word(0xE6B1A200,0x7D57CCDF,0x882A4439,0xF56E9B13); + &data_word(0x24C6CB00,0x3CE2FAF7,0x15DEEFD3,0x2931180D); +$k_dsbb=0x280; # decryption sbox output *B*u, *B*t + &data_word(0x96B44200,0xD0226492,0xB0F2D404,0x602646F6); + &data_word(0xCD596700,0xC19498A6,0x3255AA6B,0xF3FF0C3E); +$k_dsbe=0x2a0; # decryption sbox output *E*u, *E*t + &data_word(0x26D4D000,0x46F29296,0x64B4F6B0,0x22426004); + &data_word(0xFFAAC100,0x0C55A6CD,0x98593E32,0x9467F36B); +$k_dsbo=0x2c0; # decryption sbox final output + &data_word(0x7EF94000,0x1387EA53,0xD4943E2D,0xC7AA6DB9); + &data_word(0x93441D00,0x12D7560F,0xD8C58E9C,0xCA4B8159); +&asciz ("Vector Permutation AES for x86/SSSE3, Mike Hamburg (Stanford University)"); +&align (64); + +&function_begin_B("_vpaes_preheat"); + &add ($const,&DWP(0,"esp")); + &movdqa ("xmm7",&QWP($k_inv,$const)); + &movdqa ("xmm6",&QWP($k_s0F,$const)); + &ret (); +&function_end_B("_vpaes_preheat"); + +## +## _aes_encrypt_core +## +## AES-encrypt %xmm0. +## +## Inputs: +## %xmm0 = input +## %xmm6-%xmm7 as in _vpaes_preheat +## (%edx) = scheduled keys +## +## Output in %xmm0 +## Clobbers %xmm1-%xmm5, %eax, %ebx, %ecx, %edx +## +## +&function_begin_B("_vpaes_encrypt_core"); + &mov ($magic,16); + &mov ($round,&DWP(240,$key)); + &movdqa ("xmm1","xmm6") + &movdqa ("xmm2",&QWP($k_ipt,$const)); + &pandn ("xmm1","xmm0"); + &movdqu ("xmm5",&QWP(0,$key)); + &psrld ("xmm1",4); + &pand ("xmm0","xmm6"); + &pshufb ("xmm2","xmm0"); + &movdqa ("xmm0",&QWP($k_ipt+16,$const)); + &pshufb ("xmm0","xmm1"); + &pxor ("xmm2","xmm5"); + &pxor ("xmm0","xmm2"); + &add ($key,16); + &lea ($base,&DWP($k_mc_backward,$const)); + &jmp (&label("enc_entry")); + + +&set_label("enc_loop",16); + # middle of middle round + &movdqa ("xmm4",&QWP($k_sb1,$const)); # 4 : sb1u + &pshufb ("xmm4","xmm2"); # 4 = sb1u + &pxor ("xmm4","xmm5"); # 4 = sb1u + k + &movdqa ("xmm0",&QWP($k_sb1+16,$const));# 0 : sb1t + &pshufb ("xmm0","xmm3"); # 0 = sb1t + &pxor ("xmm0","xmm4"); # 0 = A + &movdqa ("xmm5",&QWP($k_sb2,$const)); # 4 : sb2u + &pshufb ("xmm5","xmm2"); # 4 = sb2u + &movdqa ("xmm1",&QWP(-0x40,$base,$magic));# .Lk_mc_forward[] + &movdqa ("xmm2",&QWP($k_sb2+16,$const));# 2 : sb2t + &pshufb ("xmm2","xmm3"); # 2 = sb2t + &pxor ("xmm2","xmm5"); # 2 = 2A + &movdqa ("xmm4",&QWP(0,$base,$magic)); # .Lk_mc_backward[] + &movdqa ("xmm3","xmm0"); # 3 = A + &pshufb ("xmm0","xmm1"); # 0 = B + &add ($key,16); # next key + &pxor ("xmm0","xmm2"); # 0 = 2A+B + &pshufb ("xmm3","xmm4"); # 3 = D + &add ($magic,16); # next mc + &pxor ("xmm3","xmm0"); # 3 = 2A+B+D + &pshufb ("xmm0","xmm1"); # 0 = 2B+C + &and ($magic,0x30); # ... mod 4 + &pxor ("xmm0","xmm3"); # 0 = 2A+3B+C+D + &sub ($round,1); # nr-- + +&set_label("enc_entry"); + # top of round + &movdqa ("xmm1","xmm6"); # 1 : i + &pandn ("xmm1","xmm0"); # 1 = i<<4 + &psrld ("xmm1",4); # 1 = i + &pand ("xmm0","xmm6"); # 0 = k + &movdqa ("xmm5",&QWP($k_inv+16,$const));# 2 : a/k + &pshufb ("xmm5","xmm0"); # 2 = a/k + &pxor ("xmm0","xmm1"); # 0 = j + &movdqa ("xmm3","xmm7"); # 3 : 1/i + &pshufb ("xmm3","xmm1"); # 3 = 1/i + &pxor ("xmm3","xmm5"); # 3 = iak = 1/i + a/k + &movdqa ("xmm4","xmm7"); # 4 : 1/j + &pshufb ("xmm4","xmm0"); # 4 = 1/j + &pxor ("xmm4","xmm5"); # 4 = jak = 1/j + a/k + &movdqa ("xmm2","xmm7"); # 2 : 1/iak + &pshufb ("xmm2","xmm3"); # 2 = 1/iak + &pxor ("xmm2","xmm0"); # 2 = io + &movdqa ("xmm3","xmm7"); # 3 : 1/jak + &movdqu ("xmm5",&QWP(0,$key)); + &pshufb ("xmm3","xmm4"); # 3 = 1/jak + &pxor ("xmm3","xmm1"); # 3 = jo + &jnz (&label("enc_loop")); + + # middle of last round + &movdqa ("xmm4",&QWP($k_sbo,$const)); # 3 : sbou .Lk_sbo + &movdqa ("xmm0",&QWP($k_sbo+16,$const));# 3 : sbot .Lk_sbo+16 + &pshufb ("xmm4","xmm2"); # 4 = sbou + &pxor ("xmm4","xmm5"); # 4 = sb1u + k + &pshufb ("xmm0","xmm3"); # 0 = sb1t + &movdqa ("xmm1",&QWP(0x40,$base,$magic));# .Lk_sr[] + &pxor ("xmm0","xmm4"); # 0 = A + &pshufb ("xmm0","xmm1"); + &ret (); +&function_end_B("_vpaes_encrypt_core"); + +## +## Decryption core +## +## Same API as encryption core. +## +&function_begin_B("_vpaes_decrypt_core"); + &mov ($round,&DWP(240,$key)); + &lea ($base,&DWP($k_dsbd,$const)); + &movdqa ("xmm1","xmm6"); + &movdqa ("xmm2",&QWP($k_dipt-$k_dsbd,$base)); + &pandn ("xmm1","xmm0"); + &mov ($magic,$round); + &psrld ("xmm1",4) + &movdqu ("xmm5",&QWP(0,$key)); + &shl ($magic,4); + &pand ("xmm0","xmm6"); + &pshufb ("xmm2","xmm0"); + &movdqa ("xmm0",&QWP($k_dipt-$k_dsbd+16,$base)); + &xor ($magic,0x30); + &pshufb ("xmm0","xmm1"); + &and ($magic,0x30); + &pxor ("xmm2","xmm5"); + &movdqa ("xmm5",&QWP($k_mc_forward+48,$const)); + &pxor ("xmm0","xmm2"); + &add ($key,16); + &lea ($magic,&DWP($k_sr-$k_dsbd,$base,$magic)); + &jmp (&label("dec_entry")); + +&set_label("dec_loop",16); +## +## Inverse mix columns +## + &movdqa ("xmm4",&QWP(-0x20,$base)); # 4 : sb9u + &pshufb ("xmm4","xmm2"); # 4 = sb9u + &pxor ("xmm4","xmm0"); + &movdqa ("xmm0",&QWP(-0x10,$base)); # 0 : sb9t + &pshufb ("xmm0","xmm3"); # 0 = sb9t + &pxor ("xmm0","xmm4"); # 0 = ch + &add ($key,16); # next round key + + &pshufb ("xmm0","xmm5"); # MC ch + &movdqa ("xmm4",&QWP(0,$base)); # 4 : sbdu + &pshufb ("xmm4","xmm2"); # 4 = sbdu + &pxor ("xmm4","xmm0"); # 4 = ch + &movdqa ("xmm0",&QWP(0x10,$base)); # 0 : sbdt + &pshufb ("xmm0","xmm3"); # 0 = sbdt + &pxor ("xmm0","xmm4"); # 0 = ch + &sub ($round,1); # nr-- + + &pshufb ("xmm0","xmm5"); # MC ch + &movdqa ("xmm4",&QWP(0x20,$base)); # 4 : sbbu + &pshufb ("xmm4","xmm2"); # 4 = sbbu + &pxor ("xmm4","xmm0"); # 4 = ch + &movdqa ("xmm0",&QWP(0x30,$base)); # 0 : sbbt + &pshufb ("xmm0","xmm3"); # 0 = sbbt + &pxor ("xmm0","xmm4"); # 0 = ch + + &pshufb ("xmm0","xmm5"); # MC ch + &movdqa ("xmm4",&QWP(0x40,$base)); # 4 : sbeu + &pshufb ("xmm4","xmm2"); # 4 = sbeu + &pxor ("xmm4","xmm0"); # 4 = ch + &movdqa ("xmm0",&QWP(0x50,$base)); # 0 : sbet + &pshufb ("xmm0","xmm3"); # 0 = sbet + &pxor ("xmm0","xmm4"); # 0 = ch + + &palignr("xmm5","xmm5",12); + +&set_label("dec_entry"); + # top of round + &movdqa ("xmm1","xmm6"); # 1 : i + &pandn ("xmm1","xmm0"); # 1 = i<<4 + &psrld ("xmm1",4); # 1 = i + &pand ("xmm0","xmm6"); # 0 = k + &movdqa ("xmm2",&QWP($k_inv+16,$const));# 2 : a/k + &pshufb ("xmm2","xmm0"); # 2 = a/k + &pxor ("xmm0","xmm1"); # 0 = j + &movdqa ("xmm3","xmm7"); # 3 : 1/i + &pshufb ("xmm3","xmm1"); # 3 = 1/i + &pxor ("xmm3","xmm2"); # 3 = iak = 1/i + a/k + &movdqa ("xmm4","xmm7"); # 4 : 1/j + &pshufb ("xmm4","xmm0"); # 4 = 1/j + &pxor ("xmm4","xmm2"); # 4 = jak = 1/j + a/k + &movdqa ("xmm2","xmm7"); # 2 : 1/iak + &pshufb ("xmm2","xmm3"); # 2 = 1/iak + &pxor ("xmm2","xmm0"); # 2 = io + &movdqa ("xmm3","xmm7"); # 3 : 1/jak + &pshufb ("xmm3","xmm4"); # 3 = 1/jak + &pxor ("xmm3","xmm1"); # 3 = jo + &movdqu ("xmm0",&QWP(0,$key)); + &jnz (&label("dec_loop")); + + # middle of last round + &movdqa ("xmm4",&QWP(0x60,$base)); # 3 : sbou + &pshufb ("xmm4","xmm2"); # 4 = sbou + &pxor ("xmm4","xmm0"); # 4 = sb1u + k + &movdqa ("xmm0",&QWP(0x70,$base)); # 0 : sbot + &movdqa ("xmm2",&QWP(0,$magic)); + &pshufb ("xmm0","xmm3"); # 0 = sb1t + &pxor ("xmm0","xmm4"); # 0 = A + &pshufb ("xmm0","xmm2"); + &ret (); +&function_end_B("_vpaes_decrypt_core"); + +######################################################## +## ## +## AES key schedule ## +## ## +######################################################## +&function_begin_B("_vpaes_schedule_core"); + &add ($const,&DWP(0,"esp")); + &movdqu ("xmm0",&QWP(0,$inp)); # load key (unaligned) + &movdqa ("xmm2",&QWP($k_rcon,$const)); # load rcon + + # input transform + &movdqa ("xmm3","xmm0"); + &lea ($base,&DWP($k_ipt,$const)); + &movdqa (&QWP(4,"esp"),"xmm2"); # xmm8 + &call ("_vpaes_schedule_transform"); + &movdqa ("xmm7","xmm0"); + + &test ($out,$out); + &jnz (&label("schedule_am_decrypting")); + + # encrypting, output zeroth round key after transform + &movdqu (&QWP(0,$key),"xmm0"); + &jmp (&label("schedule_go")); + +&set_label("schedule_am_decrypting"); + # decrypting, output zeroth round key after shiftrows + &movdqa ("xmm1",&QWP($k_sr,$const,$magic)); + &pshufb ("xmm3","xmm1"); + &movdqu (&QWP(0,$key),"xmm3"); + &xor ($magic,0x30); + +&set_label("schedule_go"); + &cmp ($round,192); + &ja (&label("schedule_256")); + &je (&label("schedule_192")); + # 128: fall though + +## +## .schedule_128 +## +## 128-bit specific part of key schedule. +## +## This schedule is really simple, because all its parts +## are accomplished by the subroutines. +## +&set_label("schedule_128"); + &mov ($round,10); + +&set_label("loop_schedule_128"); + &call ("_vpaes_schedule_round"); + &dec ($round); + &jz (&label("schedule_mangle_last")); + &call ("_vpaes_schedule_mangle"); # write output + &jmp (&label("loop_schedule_128")); + +## +## .aes_schedule_192 +## +## 192-bit specific part of key schedule. +## +## The main body of this schedule is the same as the 128-bit +## schedule, but with more smearing. The long, high side is +## stored in %xmm7 as before, and the short, low side is in +## the high bits of %xmm6. +## +## This schedule is somewhat nastier, however, because each +## round produces 192 bits of key material, or 1.5 round keys. +## Therefore, on each cycle we do 2 rounds and produce 3 round +## keys. +## +&set_label("schedule_192",16); + &movdqu ("xmm0",&QWP(8,$inp)); # load key part 2 (very unaligned) + &call ("_vpaes_schedule_transform"); # input transform + &movdqa ("xmm6","xmm0"); # save short part + &pxor ("xmm4","xmm4"); # clear 4 + &movhlps("xmm6","xmm4"); # clobber low side with zeros + &mov ($round,4); + +&set_label("loop_schedule_192"); + &call ("_vpaes_schedule_round"); + &palignr("xmm0","xmm6",8); + &call ("_vpaes_schedule_mangle"); # save key n + &call ("_vpaes_schedule_192_smear"); + &call ("_vpaes_schedule_mangle"); # save key n+1 + &call ("_vpaes_schedule_round"); + &dec ($round); + &jz (&label("schedule_mangle_last")); + &call ("_vpaes_schedule_mangle"); # save key n+2 + &call ("_vpaes_schedule_192_smear"); + &jmp (&label("loop_schedule_192")); + +## +## .aes_schedule_256 +## +## 256-bit specific part of key schedule. +## +## The structure here is very similar to the 128-bit +## schedule, but with an additional "low side" in +## %xmm6. The low side's rounds are the same as the +## high side's, except no rcon and no rotation. +## +&set_label("schedule_256",16); + &movdqu ("xmm0",&QWP(16,$inp)); # load key part 2 (unaligned) + &call ("_vpaes_schedule_transform"); # input transform + &mov ($round,7); + +&set_label("loop_schedule_256"); + &call ("_vpaes_schedule_mangle"); # output low result + &movdqa ("xmm6","xmm0"); # save cur_lo in xmm6 + + # high round + &call ("_vpaes_schedule_round"); + &dec ($round); + &jz (&label("schedule_mangle_last")); + &call ("_vpaes_schedule_mangle"); + + # low round. swap xmm7 and xmm6 + &pshufd ("xmm0","xmm0",0xFF); + &movdqa (&QWP(20,"esp"),"xmm7"); + &movdqa ("xmm7","xmm6"); + &call ("_vpaes_schedule_low_round"); + &movdqa ("xmm7",&QWP(20,"esp")); + + &jmp (&label("loop_schedule_256")); + +## +## .aes_schedule_mangle_last +## +## Mangler for last round of key schedule +## Mangles %xmm0 +## when encrypting, outputs out(%xmm0) ^ 63 +## when decrypting, outputs unskew(%xmm0) +## +## Always called right before return... jumps to cleanup and exits +## +&set_label("schedule_mangle_last",16); + # schedule last round key from xmm0 + &lea ($base,&DWP($k_deskew,$const)); + &test ($out,$out); + &jnz (&label("schedule_mangle_last_dec")); + + # encrypting + &movdqa ("xmm1",&QWP($k_sr,$const,$magic)); + &pshufb ("xmm0","xmm1"); # output permute + &lea ($base,&DWP($k_opt,$const)); # prepare to output transform + &add ($key,32); + +&set_label("schedule_mangle_last_dec"); + &add ($key,-16); + &pxor ("xmm0",&QWP($k_s63,$const)); + &call ("_vpaes_schedule_transform"); # output transform + &movdqu (&QWP(0,$key),"xmm0"); # save last key + + # cleanup + &pxor ("xmm0","xmm0"); + &pxor ("xmm1","xmm1"); + &pxor ("xmm2","xmm2"); + &pxor ("xmm3","xmm3"); + &pxor ("xmm4","xmm4"); + &pxor ("xmm5","xmm5"); + &pxor ("xmm6","xmm6"); + &pxor ("xmm7","xmm7"); + &ret (); +&function_end_B("_vpaes_schedule_core"); + +## +## .aes_schedule_192_smear +## +## Smear the short, low side in the 192-bit key schedule. +## +## Inputs: +## %xmm7: high side, b a x y +## %xmm6: low side, d c 0 0 +## %xmm13: 0 +## +## Outputs: +## %xmm6: b+c+d b+c 0 0 +## %xmm0: b+c+d b+c b a +## +&function_begin_B("_vpaes_schedule_192_smear"); + &pshufd ("xmm0","xmm6",0x80); # d c 0 0 -> c 0 0 0 + &pxor ("xmm6","xmm0"); # -> c+d c 0 0 + &pshufd ("xmm0","xmm7",0xFE); # b a _ _ -> b b b a + &pxor ("xmm6","xmm0"); # -> b+c+d b+c b a + &movdqa ("xmm0","xmm6"); + &pxor ("xmm1","xmm1"); + &movhlps("xmm6","xmm1"); # clobber low side with zeros + &ret (); +&function_end_B("_vpaes_schedule_192_smear"); + +## +## .aes_schedule_round +## +## Runs one main round of the key schedule on %xmm0, %xmm7 +## +## Specifically, runs subbytes on the high dword of %xmm0 +## then rotates it by one byte and xors into the low dword of +## %xmm7. +## +## Adds rcon from low byte of %xmm8, then rotates %xmm8 for +## next rcon. +## +## Smears the dwords of %xmm7 by xoring the low into the +## second low, result into third, result into highest. +## +## Returns results in %xmm7 = %xmm0. +## Clobbers %xmm1-%xmm5. +## +&function_begin_B("_vpaes_schedule_round"); + # extract rcon from xmm8 + &movdqa ("xmm2",&QWP(8,"esp")); # xmm8 + &pxor ("xmm1","xmm1"); + &palignr("xmm1","xmm2",15); + &palignr("xmm2","xmm2",15); + &pxor ("xmm7","xmm1"); + + # rotate + &pshufd ("xmm0","xmm0",0xFF); + &palignr("xmm0","xmm0",1); + + # fall through... + &movdqa (&QWP(8,"esp"),"xmm2"); # xmm8 + + # low round: same as high round, but no rotation and no rcon. +&set_label("_vpaes_schedule_low_round"); + # smear xmm7 + &movdqa ("xmm1","xmm7"); + &pslldq ("xmm7",4); + &pxor ("xmm7","xmm1"); + &movdqa ("xmm1","xmm7"); + &pslldq ("xmm7",8); + &pxor ("xmm7","xmm1"); + &pxor ("xmm7",&QWP($k_s63,$const)); + + # subbyte + &movdqa ("xmm4",&QWP($k_s0F,$const)); + &movdqa ("xmm5",&QWP($k_inv,$const)); # 4 : 1/j + &movdqa ("xmm1","xmm4"); + &pandn ("xmm1","xmm0"); + &psrld ("xmm1",4); # 1 = i + &pand ("xmm0","xmm4"); # 0 = k + &movdqa ("xmm2",&QWP($k_inv+16,$const));# 2 : a/k + &pshufb ("xmm2","xmm0"); # 2 = a/k + &pxor ("xmm0","xmm1"); # 0 = j + &movdqa ("xmm3","xmm5"); # 3 : 1/i + &pshufb ("xmm3","xmm1"); # 3 = 1/i + &pxor ("xmm3","xmm2"); # 3 = iak = 1/i + a/k + &movdqa ("xmm4","xmm5"); # 4 : 1/j + &pshufb ("xmm4","xmm0"); # 4 = 1/j + &pxor ("xmm4","xmm2"); # 4 = jak = 1/j + a/k + &movdqa ("xmm2","xmm5"); # 2 : 1/iak + &pshufb ("xmm2","xmm3"); # 2 = 1/iak + &pxor ("xmm2","xmm0"); # 2 = io + &movdqa ("xmm3","xmm5"); # 3 : 1/jak + &pshufb ("xmm3","xmm4"); # 3 = 1/jak + &pxor ("xmm3","xmm1"); # 3 = jo + &movdqa ("xmm4",&QWP($k_sb1,$const)); # 4 : sbou + &pshufb ("xmm4","xmm2"); # 4 = sbou + &movdqa ("xmm0",&QWP($k_sb1+16,$const));# 0 : sbot + &pshufb ("xmm0","xmm3"); # 0 = sb1t + &pxor ("xmm0","xmm4"); # 0 = sbox output + + # add in smeared stuff + &pxor ("xmm0","xmm7"); + &movdqa ("xmm7","xmm0"); + &ret (); +&function_end_B("_vpaes_schedule_round"); + +## +## .aes_schedule_transform +## +## Linear-transform %xmm0 according to tables at (%ebx) +## +## Output in %xmm0 +## Clobbers %xmm1, %xmm2 +## +&function_begin_B("_vpaes_schedule_transform"); + &movdqa ("xmm2",&QWP($k_s0F,$const)); + &movdqa ("xmm1","xmm2"); + &pandn ("xmm1","xmm0"); + &psrld ("xmm1",4); + &pand ("xmm0","xmm2"); + &movdqa ("xmm2",&QWP(0,$base)); + &pshufb ("xmm2","xmm0"); + &movdqa ("xmm0",&QWP(16,$base)); + &pshufb ("xmm0","xmm1"); + &pxor ("xmm0","xmm2"); + &ret (); +&function_end_B("_vpaes_schedule_transform"); + +## +## .aes_schedule_mangle +## +## Mangle xmm0 from (basis-transformed) standard version +## to our version. +## +## On encrypt, +## xor with 0x63 +## multiply by circulant 0,1,1,1 +## apply shiftrows transform +## +## On decrypt, +## xor with 0x63 +## multiply by "inverse mixcolumns" circulant E,B,D,9 +## deskew +## apply shiftrows transform +## +## +## Writes out to (%edx), and increments or decrements it +## Keeps track of round number mod 4 in %ecx +## Preserves xmm0 +## Clobbers xmm1-xmm5 +## +&function_begin_B("_vpaes_schedule_mangle"); + &movdqa ("xmm4","xmm0"); # save xmm0 for later + &movdqa ("xmm5",&QWP($k_mc_forward,$const)); + &test ($out,$out); + &jnz (&label("schedule_mangle_dec")); + + # encrypting + &add ($key,16); + &pxor ("xmm4",&QWP($k_s63,$const)); + &pshufb ("xmm4","xmm5"); + &movdqa ("xmm3","xmm4"); + &pshufb ("xmm4","xmm5"); + &pxor ("xmm3","xmm4"); + &pshufb ("xmm4","xmm5"); + &pxor ("xmm3","xmm4"); + + &jmp (&label("schedule_mangle_both")); + +&set_label("schedule_mangle_dec",16); + # inverse mix columns + &movdqa ("xmm2",&QWP($k_s0F,$const)); + &lea ($inp,&DWP($k_dksd,$const)); + &movdqa ("xmm1","xmm2"); + &pandn ("xmm1","xmm4"); + &psrld ("xmm1",4); # 1 = hi + &pand ("xmm4","xmm2"); # 4 = lo + + &movdqa ("xmm2",&QWP(0,$inp)); + &pshufb ("xmm2","xmm4"); + &movdqa ("xmm3",&QWP(0x10,$inp)); + &pshufb ("xmm3","xmm1"); + &pxor ("xmm3","xmm2"); + &pshufb ("xmm3","xmm5"); + + &movdqa ("xmm2",&QWP(0x20,$inp)); + &pshufb ("xmm2","xmm4"); + &pxor ("xmm2","xmm3"); + &movdqa ("xmm3",&QWP(0x30,$inp)); + &pshufb ("xmm3","xmm1"); + &pxor ("xmm3","xmm2"); + &pshufb ("xmm3","xmm5"); + + &movdqa ("xmm2",&QWP(0x40,$inp)); + &pshufb ("xmm2","xmm4"); + &pxor ("xmm2","xmm3"); + &movdqa ("xmm3",&QWP(0x50,$inp)); + &pshufb ("xmm3","xmm1"); + &pxor ("xmm3","xmm2"); + &pshufb ("xmm3","xmm5"); + + &movdqa ("xmm2",&QWP(0x60,$inp)); + &pshufb ("xmm2","xmm4"); + &pxor ("xmm2","xmm3"); + &movdqa ("xmm3",&QWP(0x70,$inp)); + &pshufb ("xmm3","xmm1"); + &pxor ("xmm3","xmm2"); + + &add ($key,-16); + +&set_label("schedule_mangle_both"); + &movdqa ("xmm1",&QWP($k_sr,$const,$magic)); + &pshufb ("xmm3","xmm1"); + &add ($magic,-16); + &and ($magic,0x30); + &movdqu (&QWP(0,$key),"xmm3"); + &ret (); +&function_end_B("_vpaes_schedule_mangle"); + +# +# Interface to OpenSSL +# +&function_begin("${PREFIX}_set_encrypt_key"); + &mov ($inp,&wparam(0)); # inp + &lea ($base,&DWP(-56,"esp")); + &mov ($round,&wparam(1)); # bits + &and ($base,-16); + &mov ($key,&wparam(2)); # key + &xchg ($base,"esp"); # alloca + &mov (&DWP(48,"esp"),$base); + + &mov ($base,$round); + &shr ($base,5); + &add ($base,5); + &mov (&DWP(240,$key),$base); # AES_KEY->rounds = nbits/32+5; + &mov ($magic,0x30); + &mov ($out,0); + + &lea ($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point"))); + &call ("_vpaes_schedule_core"); +&set_label("pic_point"); + + &mov ("esp",&DWP(48,"esp")); + &xor ("eax","eax"); +&function_end("${PREFIX}_set_encrypt_key"); + +&function_begin("${PREFIX}_set_decrypt_key"); + &mov ($inp,&wparam(0)); # inp + &lea ($base,&DWP(-56,"esp")); + &mov ($round,&wparam(1)); # bits + &and ($base,-16); + &mov ($key,&wparam(2)); # key + &xchg ($base,"esp"); # alloca + &mov (&DWP(48,"esp"),$base); + + &mov ($base,$round); + &shr ($base,5); + &add ($base,5); + &mov (&DWP(240,$key),$base); # AES_KEY->rounds = nbits/32+5; + &shl ($base,4); + &lea ($key,&DWP(16,$key,$base)); + + &mov ($out,1); + &mov ($magic,$round); + &shr ($magic,1); + &and ($magic,32); + &xor ($magic,32); # nbist==192?0:32; + + &lea ($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point"))); + &call ("_vpaes_schedule_core"); +&set_label("pic_point"); + + &mov ("esp",&DWP(48,"esp")); + &xor ("eax","eax"); +&function_end("${PREFIX}_set_decrypt_key"); + +&function_begin("${PREFIX}_encrypt"); + &lea ($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point"))); + &call ("_vpaes_preheat"); +&set_label("pic_point"); + &mov ($inp,&wparam(0)); # inp + &lea ($base,&DWP(-56,"esp")); + &mov ($out,&wparam(1)); # out + &and ($base,-16); + &mov ($key,&wparam(2)); # key + &xchg ($base,"esp"); # alloca + &mov (&DWP(48,"esp"),$base); + + &movdqu ("xmm0",&QWP(0,$inp)); + &call ("_vpaes_encrypt_core"); + &movdqu (&QWP(0,$out),"xmm0"); + + &mov ("esp",&DWP(48,"esp")); +&function_end("${PREFIX}_encrypt"); + +&function_begin("${PREFIX}_decrypt"); + &lea ($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point"))); + &call ("_vpaes_preheat"); +&set_label("pic_point"); + &mov ($inp,&wparam(0)); # inp + &lea ($base,&DWP(-56,"esp")); + &mov ($out,&wparam(1)); # out + &and ($base,-16); + &mov ($key,&wparam(2)); # key + &xchg ($base,"esp"); # alloca + &mov (&DWP(48,"esp"),$base); + + &movdqu ("xmm0",&QWP(0,$inp)); + &call ("_vpaes_decrypt_core"); + &movdqu (&QWP(0,$out),"xmm0"); + + &mov ("esp",&DWP(48,"esp")); +&function_end("${PREFIX}_decrypt"); + +&function_begin("${PREFIX}_cbc_encrypt"); + &mov ($inp,&wparam(0)); # inp + &mov ($out,&wparam(1)); # out + &mov ($round,&wparam(2)); # len + &mov ($key,&wparam(3)); # key + &sub ($round,16); + &jc (&label("cbc_abort")); + &lea ($base,&DWP(-56,"esp")); + &mov ($const,&wparam(4)); # ivp + &and ($base,-16); + &mov ($magic,&wparam(5)); # enc + &xchg ($base,"esp"); # alloca + &movdqu ("xmm1",&QWP(0,$const)); # load IV + &sub ($out,$inp); + &mov (&DWP(48,"esp"),$base); + + &mov (&DWP(0,"esp"),$out); # save out + &mov (&DWP(4,"esp"),$key) # save key + &mov (&DWP(8,"esp"),$const); # save ivp + &mov ($out,$round); # $out works as $len + + &lea ($const,&DWP(&label("_vpaes_consts")."+0x30-".&label("pic_point"))); + &call ("_vpaes_preheat"); +&set_label("pic_point"); + &cmp ($magic,0); + &je (&label("cbc_dec_loop")); + &jmp (&label("cbc_enc_loop")); + +&set_label("cbc_enc_loop",16); + &movdqu ("xmm0",&QWP(0,$inp)); # load input + &pxor ("xmm0","xmm1"); # inp^=iv + &call ("_vpaes_encrypt_core"); + &mov ($base,&DWP(0,"esp")); # restore out + &mov ($key,&DWP(4,"esp")); # restore key + &movdqa ("xmm1","xmm0"); + &movdqu (&QWP(0,$base,$inp),"xmm0"); # write output + &lea ($inp,&DWP(16,$inp)); + &sub ($out,16); + &jnc (&label("cbc_enc_loop")); + &jmp (&label("cbc_done")); + +&set_label("cbc_dec_loop",16); + &movdqu ("xmm0",&QWP(0,$inp)); # load input + &movdqa (&QWP(16,"esp"),"xmm1"); # save IV + &movdqa (&QWP(32,"esp"),"xmm0"); # save future IV + &call ("_vpaes_decrypt_core"); + &mov ($base,&DWP(0,"esp")); # restore out + &mov ($key,&DWP(4,"esp")); # restore key + &pxor ("xmm0",&QWP(16,"esp")); # out^=iv + &movdqa ("xmm1",&QWP(32,"esp")); # load next IV + &movdqu (&QWP(0,$base,$inp),"xmm0"); # write output + &lea ($inp,&DWP(16,$inp)); + &sub ($out,16); + &jnc (&label("cbc_dec_loop")); + +&set_label("cbc_done"); + &mov ($base,&DWP(8,"esp")); # restore ivp + &mov ("esp",&DWP(48,"esp")); + &movdqu (&QWP(0,$base),"xmm1"); # write IV +&set_label("cbc_abort"); +&function_end("${PREFIX}_cbc_encrypt"); + +&asm_finish(); diff --git a/libs/openssl/crypto/aes/asm/vpaes-x86_64.pl b/libs/openssl/crypto/aes/asm/vpaes-x86_64.pl new file mode 100644 index 00000000..bd7f45b8 --- /dev/null +++ b/libs/openssl/crypto/aes/asm/vpaes-x86_64.pl @@ -0,0 +1,1207 @@ +#!/usr/bin/env perl + +###################################################################### +## Constant-time SSSE3 AES core implementation. +## version 0.1 +## +## By Mike Hamburg (Stanford University), 2009 +## Public domain. +## +## For details see http://shiftleft.org/papers/vector_aes/ and +## http://crypto.stanford.edu/vpaes/. + +###################################################################### +# September 2011. +# +# Interface to OpenSSL as "almost" drop-in replacement for +# aes-x86_64.pl. "Almost" refers to the fact that AES_cbc_encrypt +# doesn't handle partial vectors (doesn't have to if called from +# EVP only). "Drop-in" implies that this module doesn't share key +# schedule structure with the original nor does it make assumption +# about its alignment... +# +# Performance summary. aes-x86_64.pl column lists large-block CBC +# encrypt/decrypt/with-hyper-threading-off(*) results in cycles per +# byte processed with 128-bit key, and vpaes-x86_64.pl column - +# [also large-block CBC] encrypt/decrypt. +# +# aes-x86_64.pl vpaes-x86_64.pl +# +# Core 2(**) 30.5/43.7/14.3 21.8/25.7(***) +# Nehalem 30.5/42.2/14.6 9.8/11.8 +# Atom 63.9/79.0/32.1 64.0/84.8(***) +# +# (*) "Hyper-threading" in the context refers rather to cache shared +# among multiple cores, than to specifically Intel HTT. As vast +# majority of contemporary cores share cache, slower code path +# is common place. In other words "with-hyper-threading-off" +# results are presented mostly for reference purposes. +# +# (**) "Core 2" refers to initial 65nm design, a.k.a. Conroe. +# +# (***) Less impressive improvement on Core 2 and Atom is due to slow +# pshufb, yet it's respectable +40%/78% improvement on Core 2 +# (as implied, over "hyper-threading-safe" code path). +# +# + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +$PREFIX="vpaes"; + +$code.=<<___; +.text + +## +## _aes_encrypt_core +## +## AES-encrypt %xmm0. +## +## Inputs: +## %xmm0 = input +## %xmm9-%xmm15 as in _vpaes_preheat +## (%rdx) = scheduled keys +## +## Output in %xmm0 +## Clobbers %xmm1-%xmm5, %r9, %r10, %r11, %rax +## Preserves %xmm6 - %xmm8 so you get some local vectors +## +## +.type _vpaes_encrypt_core,\@abi-omnipotent +.align 16 +_vpaes_encrypt_core: + mov %rdx, %r9 + mov \$16, %r11 + mov 240(%rdx),%eax + movdqa %xmm9, %xmm1 + movdqa .Lk_ipt(%rip), %xmm2 # iptlo + pandn %xmm0, %xmm1 + movdqu (%r9), %xmm5 # round0 key + psrld \$4, %xmm1 + pand %xmm9, %xmm0 + pshufb %xmm0, %xmm2 + movdqa .Lk_ipt+16(%rip), %xmm0 # ipthi + pshufb %xmm1, %xmm0 + pxor %xmm5, %xmm2 + pxor %xmm2, %xmm0 + add \$16, %r9 + lea .Lk_mc_backward(%rip),%r10 + jmp .Lenc_entry + +.align 16 +.Lenc_loop: + # middle of middle round + movdqa %xmm13, %xmm4 # 4 : sb1u + pshufb %xmm2, %xmm4 # 4 = sb1u + pxor %xmm5, %xmm4 # 4 = sb1u + k + movdqa %xmm12, %xmm0 # 0 : sb1t + pshufb %xmm3, %xmm0 # 0 = sb1t + pxor %xmm4, %xmm0 # 0 = A + movdqa %xmm15, %xmm5 # 4 : sb2u + pshufb %xmm2, %xmm5 # 4 = sb2u + movdqa -0x40(%r11,%r10), %xmm1 # .Lk_mc_forward[] + movdqa %xmm14, %xmm2 # 2 : sb2t + pshufb %xmm3, %xmm2 # 2 = sb2t + pxor %xmm5, %xmm2 # 2 = 2A + movdqa (%r11,%r10), %xmm4 # .Lk_mc_backward[] + movdqa %xmm0, %xmm3 # 3 = A + pshufb %xmm1, %xmm0 # 0 = B + add \$16, %r9 # next key + pxor %xmm2, %xmm0 # 0 = 2A+B + pshufb %xmm4, %xmm3 # 3 = D + add \$16, %r11 # next mc + pxor %xmm0, %xmm3 # 3 = 2A+B+D + pshufb %xmm1, %xmm0 # 0 = 2B+C + and \$0x30, %r11 # ... mod 4 + pxor %xmm3, %xmm0 # 0 = 2A+3B+C+D + sub \$1,%rax # nr-- + +.Lenc_entry: + # top of round + movdqa %xmm9, %xmm1 # 1 : i + pandn %xmm0, %xmm1 # 1 = i<<4 + psrld \$4, %xmm1 # 1 = i + pand %xmm9, %xmm0 # 0 = k + movdqa %xmm11, %xmm5 # 2 : a/k + pshufb %xmm0, %xmm5 # 2 = a/k + pxor %xmm1, %xmm0 # 0 = j + movdqa %xmm10, %xmm3 # 3 : 1/i + pshufb %xmm1, %xmm3 # 3 = 1/i + pxor %xmm5, %xmm3 # 3 = iak = 1/i + a/k + movdqa %xmm10, %xmm4 # 4 : 1/j + pshufb %xmm0, %xmm4 # 4 = 1/j + pxor %xmm5, %xmm4 # 4 = jak = 1/j + a/k + movdqa %xmm10, %xmm2 # 2 : 1/iak + pshufb %xmm3, %xmm2 # 2 = 1/iak + pxor %xmm0, %xmm2 # 2 = io + movdqa %xmm10, %xmm3 # 3 : 1/jak + movdqu (%r9), %xmm5 + pshufb %xmm4, %xmm3 # 3 = 1/jak + pxor %xmm1, %xmm3 # 3 = jo + jnz .Lenc_loop + + # middle of last round + movdqa -0x60(%r10), %xmm4 # 3 : sbou .Lk_sbo + movdqa -0x50(%r10), %xmm0 # 0 : sbot .Lk_sbo+16 + pshufb %xmm2, %xmm4 # 4 = sbou + pxor %xmm5, %xmm4 # 4 = sb1u + k + pshufb %xmm3, %xmm0 # 0 = sb1t + movdqa 0x40(%r11,%r10), %xmm1 # .Lk_sr[] + pxor %xmm4, %xmm0 # 0 = A + pshufb %xmm1, %xmm0 + ret +.size _vpaes_encrypt_core,.-_vpaes_encrypt_core + +## +## Decryption core +## +## Same API as encryption core. +## +.type _vpaes_decrypt_core,\@abi-omnipotent +.align 16 +_vpaes_decrypt_core: + mov %rdx, %r9 # load key + mov 240(%rdx),%eax + movdqa %xmm9, %xmm1 + movdqa .Lk_dipt(%rip), %xmm2 # iptlo + pandn %xmm0, %xmm1 + mov %rax, %r11 + psrld \$4, %xmm1 + movdqu (%r9), %xmm5 # round0 key + shl \$4, %r11 + pand %xmm9, %xmm0 + pshufb %xmm0, %xmm2 + movdqa .Lk_dipt+16(%rip), %xmm0 # ipthi + xor \$0x30, %r11 + lea .Lk_dsbd(%rip),%r10 + pshufb %xmm1, %xmm0 + and \$0x30, %r11 + pxor %xmm5, %xmm2 + movdqa .Lk_mc_forward+48(%rip), %xmm5 + pxor %xmm2, %xmm0 + add \$16, %r9 + add %r10, %r11 + jmp .Ldec_entry + +.align 16 +.Ldec_loop: +## +## Inverse mix columns +## + movdqa -0x20(%r10),%xmm4 # 4 : sb9u + pshufb %xmm2, %xmm4 # 4 = sb9u + pxor %xmm0, %xmm4 + movdqa -0x10(%r10),%xmm0 # 0 : sb9t + pshufb %xmm3, %xmm0 # 0 = sb9t + pxor %xmm4, %xmm0 # 0 = ch + add \$16, %r9 # next round key + + pshufb %xmm5, %xmm0 # MC ch + movdqa 0x00(%r10),%xmm4 # 4 : sbdu + pshufb %xmm2, %xmm4 # 4 = sbdu + pxor %xmm0, %xmm4 # 4 = ch + movdqa 0x10(%r10),%xmm0 # 0 : sbdt + pshufb %xmm3, %xmm0 # 0 = sbdt + pxor %xmm4, %xmm0 # 0 = ch + sub \$1,%rax # nr-- + + pshufb %xmm5, %xmm0 # MC ch + movdqa 0x20(%r10),%xmm4 # 4 : sbbu + pshufb %xmm2, %xmm4 # 4 = sbbu + pxor %xmm0, %xmm4 # 4 = ch + movdqa 0x30(%r10),%xmm0 # 0 : sbbt + pshufb %xmm3, %xmm0 # 0 = sbbt + pxor %xmm4, %xmm0 # 0 = ch + + pshufb %xmm5, %xmm0 # MC ch + movdqa 0x40(%r10),%xmm4 # 4 : sbeu + pshufb %xmm2, %xmm4 # 4 = sbeu + pxor %xmm0, %xmm4 # 4 = ch + movdqa 0x50(%r10),%xmm0 # 0 : sbet + pshufb %xmm3, %xmm0 # 0 = sbet + pxor %xmm4, %xmm0 # 0 = ch + + palignr \$12, %xmm5, %xmm5 + +.Ldec_entry: + # top of round + movdqa %xmm9, %xmm1 # 1 : i + pandn %xmm0, %xmm1 # 1 = i<<4 + psrld \$4, %xmm1 # 1 = i + pand %xmm9, %xmm0 # 0 = k + movdqa %xmm11, %xmm2 # 2 : a/k + pshufb %xmm0, %xmm2 # 2 = a/k + pxor %xmm1, %xmm0 # 0 = j + movdqa %xmm10, %xmm3 # 3 : 1/i + pshufb %xmm1, %xmm3 # 3 = 1/i + pxor %xmm2, %xmm3 # 3 = iak = 1/i + a/k + movdqa %xmm10, %xmm4 # 4 : 1/j + pshufb %xmm0, %xmm4 # 4 = 1/j + pxor %xmm2, %xmm4 # 4 = jak = 1/j + a/k + movdqa %xmm10, %xmm2 # 2 : 1/iak + pshufb %xmm3, %xmm2 # 2 = 1/iak + pxor %xmm0, %xmm2 # 2 = io + movdqa %xmm10, %xmm3 # 3 : 1/jak + pshufb %xmm4, %xmm3 # 3 = 1/jak + pxor %xmm1, %xmm3 # 3 = jo + movdqu (%r9), %xmm0 + jnz .Ldec_loop + + # middle of last round + movdqa 0x60(%r10), %xmm4 # 3 : sbou + pshufb %xmm2, %xmm4 # 4 = sbou + pxor %xmm0, %xmm4 # 4 = sb1u + k + movdqa 0x70(%r10), %xmm0 # 0 : sbot + movdqa -0x160(%r11), %xmm2 # .Lk_sr-.Lk_dsbd=-0x160 + pshufb %xmm3, %xmm0 # 0 = sb1t + pxor %xmm4, %xmm0 # 0 = A + pshufb %xmm2, %xmm0 + ret +.size _vpaes_decrypt_core,.-_vpaes_decrypt_core + +######################################################## +## ## +## AES key schedule ## +## ## +######################################################## +.type _vpaes_schedule_core,\@abi-omnipotent +.align 16 +_vpaes_schedule_core: + # rdi = key + # rsi = size in bits + # rdx = buffer + # rcx = direction. 0=encrypt, 1=decrypt + + call _vpaes_preheat # load the tables + movdqa .Lk_rcon(%rip), %xmm8 # load rcon + movdqu (%rdi), %xmm0 # load key (unaligned) + + # input transform + movdqa %xmm0, %xmm3 + lea .Lk_ipt(%rip), %r11 + call _vpaes_schedule_transform + movdqa %xmm0, %xmm7 + + lea .Lk_sr(%rip),%r10 + test %rcx, %rcx + jnz .Lschedule_am_decrypting + + # encrypting, output zeroth round key after transform + movdqu %xmm0, (%rdx) + jmp .Lschedule_go + +.Lschedule_am_decrypting: + # decrypting, output zeroth round key after shiftrows + movdqa (%r8,%r10),%xmm1 + pshufb %xmm1, %xmm3 + movdqu %xmm3, (%rdx) + xor \$0x30, %r8 + +.Lschedule_go: + cmp \$192, %esi + ja .Lschedule_256 + je .Lschedule_192 + # 128: fall though + +## +## .schedule_128 +## +## 128-bit specific part of key schedule. +## +## This schedule is really simple, because all its parts +## are accomplished by the subroutines. +## +.Lschedule_128: + mov \$10, %esi + +.Loop_schedule_128: + call _vpaes_schedule_round + dec %rsi + jz .Lschedule_mangle_last + call _vpaes_schedule_mangle # write output + jmp .Loop_schedule_128 + +## +## .aes_schedule_192 +## +## 192-bit specific part of key schedule. +## +## The main body of this schedule is the same as the 128-bit +## schedule, but with more smearing. The long, high side is +## stored in %xmm7 as before, and the short, low side is in +## the high bits of %xmm6. +## +## This schedule is somewhat nastier, however, because each +## round produces 192 bits of key material, or 1.5 round keys. +## Therefore, on each cycle we do 2 rounds and produce 3 round +## keys. +## +.align 16 +.Lschedule_192: + movdqu 8(%rdi),%xmm0 # load key part 2 (very unaligned) + call _vpaes_schedule_transform # input transform + movdqa %xmm0, %xmm6 # save short part + pxor %xmm4, %xmm4 # clear 4 + movhlps %xmm4, %xmm6 # clobber low side with zeros + mov \$4, %esi + +.Loop_schedule_192: + call _vpaes_schedule_round + palignr \$8,%xmm6,%xmm0 + call _vpaes_schedule_mangle # save key n + call _vpaes_schedule_192_smear + call _vpaes_schedule_mangle # save key n+1 + call _vpaes_schedule_round + dec %rsi + jz .Lschedule_mangle_last + call _vpaes_schedule_mangle # save key n+2 + call _vpaes_schedule_192_smear + jmp .Loop_schedule_192 + +## +## .aes_schedule_256 +## +## 256-bit specific part of key schedule. +## +## The structure here is very similar to the 128-bit +## schedule, but with an additional "low side" in +## %xmm6. The low side's rounds are the same as the +## high side's, except no rcon and no rotation. +## +.align 16 +.Lschedule_256: + movdqu 16(%rdi),%xmm0 # load key part 2 (unaligned) + call _vpaes_schedule_transform # input transform + mov \$7, %esi + +.Loop_schedule_256: + call _vpaes_schedule_mangle # output low result + movdqa %xmm0, %xmm6 # save cur_lo in xmm6 + + # high round + call _vpaes_schedule_round + dec %rsi + jz .Lschedule_mangle_last + call _vpaes_schedule_mangle + + # low round. swap xmm7 and xmm6 + pshufd \$0xFF, %xmm0, %xmm0 + movdqa %xmm7, %xmm5 + movdqa %xmm6, %xmm7 + call _vpaes_schedule_low_round + movdqa %xmm5, %xmm7 + + jmp .Loop_schedule_256 + + +## +## .aes_schedule_mangle_last +## +## Mangler for last round of key schedule +## Mangles %xmm0 +## when encrypting, outputs out(%xmm0) ^ 63 +## when decrypting, outputs unskew(%xmm0) +## +## Always called right before return... jumps to cleanup and exits +## +.align 16 +.Lschedule_mangle_last: + # schedule last round key from xmm0 + lea .Lk_deskew(%rip),%r11 # prepare to deskew + test %rcx, %rcx + jnz .Lschedule_mangle_last_dec + + # encrypting + movdqa (%r8,%r10),%xmm1 + pshufb %xmm1, %xmm0 # output permute + lea .Lk_opt(%rip), %r11 # prepare to output transform + add \$32, %rdx + +.Lschedule_mangle_last_dec: + add \$-16, %rdx + pxor .Lk_s63(%rip), %xmm0 + call _vpaes_schedule_transform # output transform + movdqu %xmm0, (%rdx) # save last key + + # cleanup + pxor %xmm0, %xmm0 + pxor %xmm1, %xmm1 + pxor %xmm2, %xmm2 + pxor %xmm3, %xmm3 + pxor %xmm4, %xmm4 + pxor %xmm5, %xmm5 + pxor %xmm6, %xmm6 + pxor %xmm7, %xmm7 + ret +.size _vpaes_schedule_core,.-_vpaes_schedule_core + +## +## .aes_schedule_192_smear +## +## Smear the short, low side in the 192-bit key schedule. +## +## Inputs: +## %xmm7: high side, b a x y +## %xmm6: low side, d c 0 0 +## %xmm13: 0 +## +## Outputs: +## %xmm6: b+c+d b+c 0 0 +## %xmm0: b+c+d b+c b a +## +.type _vpaes_schedule_192_smear,\@abi-omnipotent +.align 16 +_vpaes_schedule_192_smear: + pshufd \$0x80, %xmm6, %xmm0 # d c 0 0 -> c 0 0 0 + pxor %xmm0, %xmm6 # -> c+d c 0 0 + pshufd \$0xFE, %xmm7, %xmm0 # b a _ _ -> b b b a + pxor %xmm0, %xmm6 # -> b+c+d b+c b a + movdqa %xmm6, %xmm0 + pxor %xmm1, %xmm1 + movhlps %xmm1, %xmm6 # clobber low side with zeros + ret +.size _vpaes_schedule_192_smear,.-_vpaes_schedule_192_smear + +## +## .aes_schedule_round +## +## Runs one main round of the key schedule on %xmm0, %xmm7 +## +## Specifically, runs subbytes on the high dword of %xmm0 +## then rotates it by one byte and xors into the low dword of +## %xmm7. +## +## Adds rcon from low byte of %xmm8, then rotates %xmm8 for +## next rcon. +## +## Smears the dwords of %xmm7 by xoring the low into the +## second low, result into third, result into highest. +## +## Returns results in %xmm7 = %xmm0. +## Clobbers %xmm1-%xmm4, %r11. +## +.type _vpaes_schedule_round,\@abi-omnipotent +.align 16 +_vpaes_schedule_round: + # extract rcon from xmm8 + pxor %xmm1, %xmm1 + palignr \$15, %xmm8, %xmm1 + palignr \$15, %xmm8, %xmm8 + pxor %xmm1, %xmm7 + + # rotate + pshufd \$0xFF, %xmm0, %xmm0 + palignr \$1, %xmm0, %xmm0 + + # fall through... + + # low round: same as high round, but no rotation and no rcon. +_vpaes_schedule_low_round: + # smear xmm7 + movdqa %xmm7, %xmm1 + pslldq \$4, %xmm7 + pxor %xmm1, %xmm7 + movdqa %xmm7, %xmm1 + pslldq \$8, %xmm7 + pxor %xmm1, %xmm7 + pxor .Lk_s63(%rip), %xmm7 + + # subbytes + movdqa %xmm9, %xmm1 + pandn %xmm0, %xmm1 + psrld \$4, %xmm1 # 1 = i + pand %xmm9, %xmm0 # 0 = k + movdqa %xmm11, %xmm2 # 2 : a/k + pshufb %xmm0, %xmm2 # 2 = a/k + pxor %xmm1, %xmm0 # 0 = j + movdqa %xmm10, %xmm3 # 3 : 1/i + pshufb %xmm1, %xmm3 # 3 = 1/i + pxor %xmm2, %xmm3 # 3 = iak = 1/i + a/k + movdqa %xmm10, %xmm4 # 4 : 1/j + pshufb %xmm0, %xmm4 # 4 = 1/j + pxor %xmm2, %xmm4 # 4 = jak = 1/j + a/k + movdqa %xmm10, %xmm2 # 2 : 1/iak + pshufb %xmm3, %xmm2 # 2 = 1/iak + pxor %xmm0, %xmm2 # 2 = io + movdqa %xmm10, %xmm3 # 3 : 1/jak + pshufb %xmm4, %xmm3 # 3 = 1/jak + pxor %xmm1, %xmm3 # 3 = jo + movdqa %xmm13, %xmm4 # 4 : sbou + pshufb %xmm2, %xmm4 # 4 = sbou + movdqa %xmm12, %xmm0 # 0 : sbot + pshufb %xmm3, %xmm0 # 0 = sb1t + pxor %xmm4, %xmm0 # 0 = sbox output + + # add in smeared stuff + pxor %xmm7, %xmm0 + movdqa %xmm0, %xmm7 + ret +.size _vpaes_schedule_round,.-_vpaes_schedule_round + +## +## .aes_schedule_transform +## +## Linear-transform %xmm0 according to tables at (%r11) +## +## Requires that %xmm9 = 0x0F0F... as in preheat +## Output in %xmm0 +## Clobbers %xmm1, %xmm2 +## +.type _vpaes_schedule_transform,\@abi-omnipotent +.align 16 +_vpaes_schedule_transform: + movdqa %xmm9, %xmm1 + pandn %xmm0, %xmm1 + psrld \$4, %xmm1 + pand %xmm9, %xmm0 + movdqa (%r11), %xmm2 # lo + pshufb %xmm0, %xmm2 + movdqa 16(%r11), %xmm0 # hi + pshufb %xmm1, %xmm0 + pxor %xmm2, %xmm0 + ret +.size _vpaes_schedule_transform,.-_vpaes_schedule_transform + +## +## .aes_schedule_mangle +## +## Mangle xmm0 from (basis-transformed) standard version +## to our version. +## +## On encrypt, +## xor with 0x63 +## multiply by circulant 0,1,1,1 +## apply shiftrows transform +## +## On decrypt, +## xor with 0x63 +## multiply by "inverse mixcolumns" circulant E,B,D,9 +## deskew +## apply shiftrows transform +## +## +## Writes out to (%rdx), and increments or decrements it +## Keeps track of round number mod 4 in %r8 +## Preserves xmm0 +## Clobbers xmm1-xmm5 +## +.type _vpaes_schedule_mangle,\@abi-omnipotent +.align 16 +_vpaes_schedule_mangle: + movdqa %xmm0, %xmm4 # save xmm0 for later + movdqa .Lk_mc_forward(%rip),%xmm5 + test %rcx, %rcx + jnz .Lschedule_mangle_dec + + # encrypting + add \$16, %rdx + pxor .Lk_s63(%rip),%xmm4 + pshufb %xmm5, %xmm4 + movdqa %xmm4, %xmm3 + pshufb %xmm5, %xmm4 + pxor %xmm4, %xmm3 + pshufb %xmm5, %xmm4 + pxor %xmm4, %xmm3 + + jmp .Lschedule_mangle_both +.align 16 +.Lschedule_mangle_dec: + # inverse mix columns + lea .Lk_dksd(%rip),%r11 + movdqa %xmm9, %xmm1 + pandn %xmm4, %xmm1 + psrld \$4, %xmm1 # 1 = hi + pand %xmm9, %xmm4 # 4 = lo + + movdqa 0x00(%r11), %xmm2 + pshufb %xmm4, %xmm2 + movdqa 0x10(%r11), %xmm3 + pshufb %xmm1, %xmm3 + pxor %xmm2, %xmm3 + pshufb %xmm5, %xmm3 + + movdqa 0x20(%r11), %xmm2 + pshufb %xmm4, %xmm2 + pxor %xmm3, %xmm2 + movdqa 0x30(%r11), %xmm3 + pshufb %xmm1, %xmm3 + pxor %xmm2, %xmm3 + pshufb %xmm5, %xmm3 + + movdqa 0x40(%r11), %xmm2 + pshufb %xmm4, %xmm2 + pxor %xmm3, %xmm2 + movdqa 0x50(%r11), %xmm3 + pshufb %xmm1, %xmm3 + pxor %xmm2, %xmm3 + pshufb %xmm5, %xmm3 + + movdqa 0x60(%r11), %xmm2 + pshufb %xmm4, %xmm2 + pxor %xmm3, %xmm2 + movdqa 0x70(%r11), %xmm3 + pshufb %xmm1, %xmm3 + pxor %xmm2, %xmm3 + + add \$-16, %rdx + +.Lschedule_mangle_both: + movdqa (%r8,%r10),%xmm1 + pshufb %xmm1,%xmm3 + add \$-16, %r8 + and \$0x30, %r8 + movdqu %xmm3, (%rdx) + ret +.size _vpaes_schedule_mangle,.-_vpaes_schedule_mangle + +# +# Interface to OpenSSL +# +.globl ${PREFIX}_set_encrypt_key +.type ${PREFIX}_set_encrypt_key,\@function,3 +.align 16 +${PREFIX}_set_encrypt_key: +___ +$code.=<<___ if ($win64); + lea -0xb8(%rsp),%rsp + movaps %xmm6,0x10(%rsp) + movaps %xmm7,0x20(%rsp) + movaps %xmm8,0x30(%rsp) + movaps %xmm9,0x40(%rsp) + movaps %xmm10,0x50(%rsp) + movaps %xmm11,0x60(%rsp) + movaps %xmm12,0x70(%rsp) + movaps %xmm13,0x80(%rsp) + movaps %xmm14,0x90(%rsp) + movaps %xmm15,0xa0(%rsp) +.Lenc_key_body: +___ +$code.=<<___; + mov %esi,%eax + shr \$5,%eax + add \$5,%eax + mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; + + mov \$0,%ecx + mov \$0x30,%r8d + call _vpaes_schedule_core +___ +$code.=<<___ if ($win64); + movaps 0x10(%rsp),%xmm6 + movaps 0x20(%rsp),%xmm7 + movaps 0x30(%rsp),%xmm8 + movaps 0x40(%rsp),%xmm9 + movaps 0x50(%rsp),%xmm10 + movaps 0x60(%rsp),%xmm11 + movaps 0x70(%rsp),%xmm12 + movaps 0x80(%rsp),%xmm13 + movaps 0x90(%rsp),%xmm14 + movaps 0xa0(%rsp),%xmm15 + lea 0xb8(%rsp),%rsp +.Lenc_key_epilogue: +___ +$code.=<<___; + xor %eax,%eax + ret +.size ${PREFIX}_set_encrypt_key,.-${PREFIX}_set_encrypt_key + +.globl ${PREFIX}_set_decrypt_key +.type ${PREFIX}_set_decrypt_key,\@function,3 +.align 16 +${PREFIX}_set_decrypt_key: +___ +$code.=<<___ if ($win64); + lea -0xb8(%rsp),%rsp + movaps %xmm6,0x10(%rsp) + movaps %xmm7,0x20(%rsp) + movaps %xmm8,0x30(%rsp) + movaps %xmm9,0x40(%rsp) + movaps %xmm10,0x50(%rsp) + movaps %xmm11,0x60(%rsp) + movaps %xmm12,0x70(%rsp) + movaps %xmm13,0x80(%rsp) + movaps %xmm14,0x90(%rsp) + movaps %xmm15,0xa0(%rsp) +.Ldec_key_body: +___ +$code.=<<___; + mov %esi,%eax + shr \$5,%eax + add \$5,%eax + mov %eax,240(%rdx) # AES_KEY->rounds = nbits/32+5; + shl \$4,%eax + lea 16(%rdx,%rax),%rdx + + mov \$1,%ecx + mov %esi,%r8d + shr \$1,%r8d + and \$32,%r8d + xor \$32,%r8d # nbits==192?0:32 + call _vpaes_schedule_core +___ +$code.=<<___ if ($win64); + movaps 0x10(%rsp),%xmm6 + movaps 0x20(%rsp),%xmm7 + movaps 0x30(%rsp),%xmm8 + movaps 0x40(%rsp),%xmm9 + movaps 0x50(%rsp),%xmm10 + movaps 0x60(%rsp),%xmm11 + movaps 0x70(%rsp),%xmm12 + movaps 0x80(%rsp),%xmm13 + movaps 0x90(%rsp),%xmm14 + movaps 0xa0(%rsp),%xmm15 + lea 0xb8(%rsp),%rsp +.Ldec_key_epilogue: +___ +$code.=<<___; + xor %eax,%eax + ret +.size ${PREFIX}_set_decrypt_key,.-${PREFIX}_set_decrypt_key + +.globl ${PREFIX}_encrypt +.type ${PREFIX}_encrypt,\@function,3 +.align 16 +${PREFIX}_encrypt: +___ +$code.=<<___ if ($win64); + lea -0xb8(%rsp),%rsp + movaps %xmm6,0x10(%rsp) + movaps %xmm7,0x20(%rsp) + movaps %xmm8,0x30(%rsp) + movaps %xmm9,0x40(%rsp) + movaps %xmm10,0x50(%rsp) + movaps %xmm11,0x60(%rsp) + movaps %xmm12,0x70(%rsp) + movaps %xmm13,0x80(%rsp) + movaps %xmm14,0x90(%rsp) + movaps %xmm15,0xa0(%rsp) +.Lenc_body: +___ +$code.=<<___; + movdqu (%rdi),%xmm0 + call _vpaes_preheat + call _vpaes_encrypt_core + movdqu %xmm0,(%rsi) +___ +$code.=<<___ if ($win64); + movaps 0x10(%rsp),%xmm6 + movaps 0x20(%rsp),%xmm7 + movaps 0x30(%rsp),%xmm8 + movaps 0x40(%rsp),%xmm9 + movaps 0x50(%rsp),%xmm10 + movaps 0x60(%rsp),%xmm11 + movaps 0x70(%rsp),%xmm12 + movaps 0x80(%rsp),%xmm13 + movaps 0x90(%rsp),%xmm14 + movaps 0xa0(%rsp),%xmm15 + lea 0xb8(%rsp),%rsp +.Lenc_epilogue: +___ +$code.=<<___; + ret +.size ${PREFIX}_encrypt,.-${PREFIX}_encrypt + +.globl ${PREFIX}_decrypt +.type ${PREFIX}_decrypt,\@function,3 +.align 16 +${PREFIX}_decrypt: +___ +$code.=<<___ if ($win64); + lea -0xb8(%rsp),%rsp + movaps %xmm6,0x10(%rsp) + movaps %xmm7,0x20(%rsp) + movaps %xmm8,0x30(%rsp) + movaps %xmm9,0x40(%rsp) + movaps %xmm10,0x50(%rsp) + movaps %xmm11,0x60(%rsp) + movaps %xmm12,0x70(%rsp) + movaps %xmm13,0x80(%rsp) + movaps %xmm14,0x90(%rsp) + movaps %xmm15,0xa0(%rsp) +.Ldec_body: +___ +$code.=<<___; + movdqu (%rdi),%xmm0 + call _vpaes_preheat + call _vpaes_decrypt_core + movdqu %xmm0,(%rsi) +___ +$code.=<<___ if ($win64); + movaps 0x10(%rsp),%xmm6 + movaps 0x20(%rsp),%xmm7 + movaps 0x30(%rsp),%xmm8 + movaps 0x40(%rsp),%xmm9 + movaps 0x50(%rsp),%xmm10 + movaps 0x60(%rsp),%xmm11 + movaps 0x70(%rsp),%xmm12 + movaps 0x80(%rsp),%xmm13 + movaps 0x90(%rsp),%xmm14 + movaps 0xa0(%rsp),%xmm15 + lea 0xb8(%rsp),%rsp +.Ldec_epilogue: +___ +$code.=<<___; + ret +.size ${PREFIX}_decrypt,.-${PREFIX}_decrypt +___ +{ +my ($inp,$out,$len,$key,$ivp,$enc)=("%rdi","%rsi","%rdx","%rcx","%r8","%r9"); +# void AES_cbc_encrypt (const void char *inp, unsigned char *out, +# size_t length, const AES_KEY *key, +# unsigned char *ivp,const int enc); +$code.=<<___; +.globl ${PREFIX}_cbc_encrypt +.type ${PREFIX}_cbc_encrypt,\@function,6 +.align 16 +${PREFIX}_cbc_encrypt: + xchg $key,$len +___ +($len,$key)=($key,$len); +$code.=<<___; + sub \$16,$len + jc .Lcbc_abort +___ +$code.=<<___ if ($win64); + lea -0xb8(%rsp),%rsp + movaps %xmm6,0x10(%rsp) + movaps %xmm7,0x20(%rsp) + movaps %xmm8,0x30(%rsp) + movaps %xmm9,0x40(%rsp) + movaps %xmm10,0x50(%rsp) + movaps %xmm11,0x60(%rsp) + movaps %xmm12,0x70(%rsp) + movaps %xmm13,0x80(%rsp) + movaps %xmm14,0x90(%rsp) + movaps %xmm15,0xa0(%rsp) +.Lcbc_body: +___ +$code.=<<___; + movdqu ($ivp),%xmm6 # load IV + sub $inp,$out + call _vpaes_preheat + cmp \$0,${enc}d + je .Lcbc_dec_loop + jmp .Lcbc_enc_loop +.align 16 +.Lcbc_enc_loop: + movdqu ($inp),%xmm0 + pxor %xmm6,%xmm0 + call _vpaes_encrypt_core + movdqa %xmm0,%xmm6 + movdqu %xmm0,($out,$inp) + lea 16($inp),$inp + sub \$16,$len + jnc .Lcbc_enc_loop + jmp .Lcbc_done +.align 16 +.Lcbc_dec_loop: + movdqu ($inp),%xmm0 + movdqa %xmm0,%xmm7 + call _vpaes_decrypt_core + pxor %xmm6,%xmm0 + movdqa %xmm7,%xmm6 + movdqu %xmm0,($out,$inp) + lea 16($inp),$inp + sub \$16,$len + jnc .Lcbc_dec_loop +.Lcbc_done: + movdqu %xmm6,($ivp) # save IV +___ +$code.=<<___ if ($win64); + movaps 0x10(%rsp),%xmm6 + movaps 0x20(%rsp),%xmm7 + movaps 0x30(%rsp),%xmm8 + movaps 0x40(%rsp),%xmm9 + movaps 0x50(%rsp),%xmm10 + movaps 0x60(%rsp),%xmm11 + movaps 0x70(%rsp),%xmm12 + movaps 0x80(%rsp),%xmm13 + movaps 0x90(%rsp),%xmm14 + movaps 0xa0(%rsp),%xmm15 + lea 0xb8(%rsp),%rsp +.Lcbc_epilogue: +___ +$code.=<<___; +.Lcbc_abort: + ret +.size ${PREFIX}_cbc_encrypt,.-${PREFIX}_cbc_encrypt +___ +} +$code.=<<___; +## +## _aes_preheat +## +## Fills register %r10 -> .aes_consts (so you can -fPIC) +## and %xmm9-%xmm15 as specified below. +## +.type _vpaes_preheat,\@abi-omnipotent +.align 16 +_vpaes_preheat: + lea .Lk_s0F(%rip), %r10 + movdqa -0x20(%r10), %xmm10 # .Lk_inv + movdqa -0x10(%r10), %xmm11 # .Lk_inv+16 + movdqa 0x00(%r10), %xmm9 # .Lk_s0F + movdqa 0x30(%r10), %xmm13 # .Lk_sb1 + movdqa 0x40(%r10), %xmm12 # .Lk_sb1+16 + movdqa 0x50(%r10), %xmm15 # .Lk_sb2 + movdqa 0x60(%r10), %xmm14 # .Lk_sb2+16 + ret +.size _vpaes_preheat,.-_vpaes_preheat +######################################################## +## ## +## Constants ## +## ## +######################################################## +.type _vpaes_consts,\@object +.align 64 +_vpaes_consts: +.Lk_inv: # inv, inva + .quad 0x0E05060F0D080180, 0x040703090A0B0C02 + .quad 0x01040A060F0B0780, 0x030D0E0C02050809 + +.Lk_s0F: # s0F + .quad 0x0F0F0F0F0F0F0F0F, 0x0F0F0F0F0F0F0F0F + +.Lk_ipt: # input transform (lo, hi) + .quad 0xC2B2E8985A2A7000, 0xCABAE09052227808 + .quad 0x4C01307D317C4D00, 0xCD80B1FCB0FDCC81 + +.Lk_sb1: # sb1u, sb1t + .quad 0xB19BE18FCB503E00, 0xA5DF7A6E142AF544 + .quad 0x3618D415FAE22300, 0x3BF7CCC10D2ED9EF +.Lk_sb2: # sb2u, sb2t + .quad 0xE27A93C60B712400, 0x5EB7E955BC982FCD + .quad 0x69EB88400AE12900, 0xC2A163C8AB82234A +.Lk_sbo: # sbou, sbot + .quad 0xD0D26D176FBDC700, 0x15AABF7AC502A878 + .quad 0xCFE474A55FBB6A00, 0x8E1E90D1412B35FA + +.Lk_mc_forward: # mc_forward + .quad 0x0407060500030201, 0x0C0F0E0D080B0A09 + .quad 0x080B0A0904070605, 0x000302010C0F0E0D + .quad 0x0C0F0E0D080B0A09, 0x0407060500030201 + .quad 0x000302010C0F0E0D, 0x080B0A0904070605 + +.Lk_mc_backward:# mc_backward + .quad 0x0605040702010003, 0x0E0D0C0F0A09080B + .quad 0x020100030E0D0C0F, 0x0A09080B06050407 + .quad 0x0E0D0C0F0A09080B, 0x0605040702010003 + .quad 0x0A09080B06050407, 0x020100030E0D0C0F + +.Lk_sr: # sr + .quad 0x0706050403020100, 0x0F0E0D0C0B0A0908 + .quad 0x030E09040F0A0500, 0x0B06010C07020D08 + .quad 0x0F060D040B020900, 0x070E050C030A0108 + .quad 0x0B0E0104070A0D00, 0x0306090C0F020508 + +.Lk_rcon: # rcon + .quad 0x1F8391B9AF9DEEB6, 0x702A98084D7C7D81 + +.Lk_s63: # s63: all equal to 0x63 transformed + .quad 0x5B5B5B5B5B5B5B5B, 0x5B5B5B5B5B5B5B5B + +.Lk_opt: # output transform + .quad 0xFF9F4929D6B66000, 0xF7974121DEBE6808 + .quad 0x01EDBD5150BCEC00, 0xE10D5DB1B05C0CE0 + +.Lk_deskew: # deskew tables: inverts the sbox's "skew" + .quad 0x07E4A34047A4E300, 0x1DFEB95A5DBEF91A + .quad 0x5F36B5DC83EA6900, 0x2841C2ABF49D1E77 + +## +## Decryption stuff +## Key schedule constants +## +.Lk_dksd: # decryption key schedule: invskew x*D + .quad 0xFEB91A5DA3E44700, 0x0740E3A45A1DBEF9 + .quad 0x41C277F4B5368300, 0x5FDC69EAAB289D1E +.Lk_dksb: # decryption key schedule: invskew x*B + .quad 0x9A4FCA1F8550D500, 0x03D653861CC94C99 + .quad 0x115BEDA7B6FC4A00, 0xD993256F7E3482C8 +.Lk_dkse: # decryption key schedule: invskew x*E + 0x63 + .quad 0xD5031CCA1FC9D600, 0x53859A4C994F5086 + .quad 0xA23196054FDC7BE8, 0xCD5EF96A20B31487 +.Lk_dks9: # decryption key schedule: invskew x*9 + .quad 0xB6116FC87ED9A700, 0x4AED933482255BFC + .quad 0x4576516227143300, 0x8BB89FACE9DAFDCE + +## +## Decryption stuff +## Round function constants +## +.Lk_dipt: # decryption input transform + .quad 0x0F505B040B545F00, 0x154A411E114E451A + .quad 0x86E383E660056500, 0x12771772F491F194 + +.Lk_dsb9: # decryption sbox output *9*u, *9*t + .quad 0x851C03539A86D600, 0xCAD51F504F994CC9 + .quad 0xC03B1789ECD74900, 0x725E2C9EB2FBA565 +.Lk_dsbd: # decryption sbox output *D*u, *D*t + .quad 0x7D57CCDFE6B1A200, 0xF56E9B13882A4439 + .quad 0x3CE2FAF724C6CB00, 0x2931180D15DEEFD3 +.Lk_dsbb: # decryption sbox output *B*u, *B*t + .quad 0xD022649296B44200, 0x602646F6B0F2D404 + .quad 0xC19498A6CD596700, 0xF3FF0C3E3255AA6B +.Lk_dsbe: # decryption sbox output *E*u, *E*t + .quad 0x46F2929626D4D000, 0x2242600464B4F6B0 + .quad 0x0C55A6CDFFAAC100, 0x9467F36B98593E32 +.Lk_dsbo: # decryption sbox final output + .quad 0x1387EA537EF94000, 0xC7AA6DB9D4943E2D + .quad 0x12D7560F93441D00, 0xCA4B8159D8C58E9C +.asciz "Vector Permutation AES for x86_64/SSSE3, Mike Hamburg (Stanford University)" +.align 64 +.size _vpaes_consts,.-_vpaes_consts +___ + +if ($win64) { +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type se_handler,\@abi-omnipotent +.align 16 +se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + mov 8($disp),%rsi # disp->ImageBase + mov 56($disp),%r11 # disp->HandlerData + + mov 0(%r11),%r10d # HandlerData[0] + lea (%rsi,%r10),%r10 # prologue label + cmp %r10,%rbx # context->RipRsp + + mov 4(%r11),%r10d # HandlerData[1] + lea (%rsi,%r10),%r10 # epilogue label + cmp %r10,%rbx # context->Rip>=epilogue label + jae .Lin_prologue + + lea 16(%rax),%rsi # %xmm save area + lea 512($context),%rdi # &context.Xmm6 + mov \$20,%ecx # 10*sizeof(%xmm0)/sizeof(%rax) + .long 0xa548f3fc # cld; rep movsq + lea 0xb8(%rax),%rax # adjust stack pointer + +.Lin_prologue: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$`1232/8`,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size se_handler,.-se_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_${PREFIX}_set_encrypt_key + .rva .LSEH_end_${PREFIX}_set_encrypt_key + .rva .LSEH_info_${PREFIX}_set_encrypt_key + + .rva .LSEH_begin_${PREFIX}_set_decrypt_key + .rva .LSEH_end_${PREFIX}_set_decrypt_key + .rva .LSEH_info_${PREFIX}_set_decrypt_key + + .rva .LSEH_begin_${PREFIX}_encrypt + .rva .LSEH_end_${PREFIX}_encrypt + .rva .LSEH_info_${PREFIX}_encrypt + + .rva .LSEH_begin_${PREFIX}_decrypt + .rva .LSEH_end_${PREFIX}_decrypt + .rva .LSEH_info_${PREFIX}_decrypt + + .rva .LSEH_begin_${PREFIX}_cbc_encrypt + .rva .LSEH_end_${PREFIX}_cbc_encrypt + .rva .LSEH_info_${PREFIX}_cbc_encrypt + +.section .xdata +.align 8 +.LSEH_info_${PREFIX}_set_encrypt_key: + .byte 9,0,0,0 + .rva se_handler + .rva .Lenc_key_body,.Lenc_key_epilogue # HandlerData[] +.LSEH_info_${PREFIX}_set_decrypt_key: + .byte 9,0,0,0 + .rva se_handler + .rva .Ldec_key_body,.Ldec_key_epilogue # HandlerData[] +.LSEH_info_${PREFIX}_encrypt: + .byte 9,0,0,0 + .rva se_handler + .rva .Lenc_body,.Lenc_epilogue # HandlerData[] +.LSEH_info_${PREFIX}_decrypt: + .byte 9,0,0,0 + .rva se_handler + .rva .Ldec_body,.Ldec_epilogue # HandlerData[] +.LSEH_info_${PREFIX}_cbc_encrypt: + .byte 9,0,0,0 + .rva se_handler + .rva .Lcbc_body,.Lcbc_epilogue # HandlerData[] +___ +} + +$code =~ s/\`([^\`]*)\`/eval($1)/gem; + +print $code; + +close STDOUT; diff --git a/libs/openssl/crypto/alphacpuid.pl b/libs/openssl/crypto/alphacpuid.pl new file mode 100644 index 00000000..4b3cbb98 --- /dev/null +++ b/libs/openssl/crypto/alphacpuid.pl @@ -0,0 +1,126 @@ +#!/usr/bin/env perl +print <<'___'; +.text + +.set noat + +.globl OPENSSL_cpuid_setup +.ent OPENSSL_cpuid_setup +OPENSSL_cpuid_setup: + .frame $30,0,$26 + .prologue 0 + ret ($26) +.end OPENSSL_cpuid_setup + +.globl OPENSSL_wipe_cpu +.ent OPENSSL_wipe_cpu +OPENSSL_wipe_cpu: + .frame $30,0,$26 + .prologue 0 + clr $1 + clr $2 + clr $3 + clr $4 + clr $5 + clr $6 + clr $7 + clr $8 + clr $16 + clr $17 + clr $18 + clr $19 + clr $20 + clr $21 + clr $22 + clr $23 + clr $24 + clr $25 + clr $27 + clr $at + clr $29 + fclr $f0 + fclr $f1 + fclr $f10 + fclr $f11 + fclr $f12 + fclr $f13 + fclr $f14 + fclr $f15 + fclr $f16 + fclr $f17 + fclr $f18 + fclr $f19 + fclr $f20 + fclr $f21 + fclr $f22 + fclr $f23 + fclr $f24 + fclr $f25 + fclr $f26 + fclr $f27 + fclr $f28 + fclr $f29 + fclr $f30 + mov $sp,$0 + ret ($26) +.end OPENSSL_wipe_cpu + +.globl OPENSSL_atomic_add +.ent OPENSSL_atomic_add +OPENSSL_atomic_add: + .frame $30,0,$26 + .prologue 0 +1: ldl_l $0,0($16) + addl $0,$17,$1 + stl_c $1,0($16) + beq $1,1b + addl $0,$17,$0 + ret ($26) +.end OPENSSL_atomic_add + +.globl OPENSSL_rdtsc +.ent OPENSSL_rdtsc +OPENSSL_rdtsc: + .frame $30,0,$26 + .prologue 0 + rpcc $0 + ret ($26) +.end OPENSSL_rdtsc + +.globl OPENSSL_cleanse +.ent OPENSSL_cleanse +OPENSSL_cleanse: + .frame $30,0,$26 + .prologue 0 + beq $17,.Ldone + and $16,7,$0 + bic $17,7,$at + beq $at,.Little + beq $0,.Laligned + +.Little: + subq $0,8,$0 + ldq_u $1,0($16) + mov $16,$2 +.Lalign: + mskbl $1,$16,$1 + lda $16,1($16) + subq $17,1,$17 + addq $0,1,$0 + beq $17,.Lout + bne $0,.Lalign +.Lout: stq_u $1,0($2) + beq $17,.Ldone + bic $17,7,$at + beq $at,.Little + +.Laligned: + stq $31,0($16) + subq $17,8,$17 + lda $16,8($16) + bic $17,7,$at + bne $at,.Laligned + bne $17,.Little +.Ldone: ret ($26) +.end OPENSSL_cleanse +___ diff --git a/libs/openssl/crypto/arm_arch.h b/libs/openssl/crypto/arm_arch.h new file mode 100644 index 00000000..b6543716 --- /dev/null +++ b/libs/openssl/crypto/arm_arch.h @@ -0,0 +1,51 @@ +#ifndef __ARM_ARCH_H__ +# define __ARM_ARCH_H__ + +# if !defined(__ARM_ARCH__) +# if defined(__CC_ARM) +# define __ARM_ARCH__ __TARGET_ARCH_ARM +# if defined(__BIG_ENDIAN) +# define __ARMEB__ +# else +# define __ARMEL__ +# endif +# elif defined(__GNUC__) + /* + * Why doesn't gcc define __ARM_ARCH__? Instead it defines + * bunch of below macros. See all_architectires[] table in + * gcc/config/arm/arm.c. On a side note it defines + * __ARMEL__/__ARMEB__ for little-/big-endian. + */ +# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \ + defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \ + defined(__ARM_ARCH_7EM__) +# define __ARM_ARCH__ 7 +# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \ + defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__) || \ + defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__) || \ + defined(__ARM_ARCH_6T2__) +# define __ARM_ARCH__ 6 +# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || \ + defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__) || \ + defined(__ARM_ARCH_5TEJ__) +# define __ARM_ARCH__ 5 +# elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) +# define __ARM_ARCH__ 4 +# else +# error "unsupported ARM architecture" +# endif +# endif +# endif + +# ifdef OPENSSL_FIPSCANISTER +# include +# endif + +# if !__ASSEMBLER__ +extern unsigned int OPENSSL_armcap_P; + +# define ARMV7_NEON (1<<0) +# define ARMV7_TICK (1<<1) +# endif + +#endif diff --git a/libs/openssl/crypto/armcap.c b/libs/openssl/crypto/armcap.c new file mode 100644 index 00000000..28522ea8 --- /dev/null +++ b/libs/openssl/crypto/armcap.c @@ -0,0 +1,81 @@ +#include +#include +#include +#include +#include +#include + +#include "arm_arch.h" + +unsigned int OPENSSL_armcap_P; + +static sigset_t all_masked; + +static sigjmp_buf ill_jmp; +static void ill_handler(int sig) +{ + siglongjmp(ill_jmp, sig); +} + +/* + * Following subroutines could have been inlined, but it's not all + * ARM compilers support inline assembler... + */ +void _armv7_neon_probe(void); +unsigned int _armv7_tick(void); + +unsigned int OPENSSL_rdtsc(void) +{ + if (OPENSSL_armcap_P & ARMV7_TICK) + return _armv7_tick(); + else + return 0; +} + +#if defined(__GNUC__) && __GNUC__>=2 +void OPENSSL_cpuid_setup(void) __attribute__ ((constructor)); +#endif +void OPENSSL_cpuid_setup(void) +{ + char *e; + struct sigaction ill_oact, ill_act; + sigset_t oset; + static int trigger = 0; + + if (trigger) + return; + trigger = 1; + + if ((e = getenv("OPENSSL_armcap"))) { + OPENSSL_armcap_P = strtoul(e, NULL, 0); + return; + } + + sigfillset(&all_masked); + sigdelset(&all_masked, SIGILL); + sigdelset(&all_masked, SIGTRAP); + sigdelset(&all_masked, SIGFPE); + sigdelset(&all_masked, SIGBUS); + sigdelset(&all_masked, SIGSEGV); + + OPENSSL_armcap_P = 0; + + memset(&ill_act, 0, sizeof(ill_act)); + ill_act.sa_handler = ill_handler; + ill_act.sa_mask = all_masked; + + sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); + sigaction(SIGILL, &ill_act, &ill_oact); + + if (sigsetjmp(ill_jmp, 1) == 0) { + _armv7_neon_probe(); + OPENSSL_armcap_P |= ARMV7_NEON; + } + if (sigsetjmp(ill_jmp, 1) == 0) { + _armv7_tick(); + OPENSSL_armcap_P |= ARMV7_TICK; + } + + sigaction(SIGILL, &ill_oact, NULL); + sigprocmask(SIG_SETMASK, &oset, NULL); +} diff --git a/libs/openssl/crypto/armv4cpuid.S b/libs/openssl/crypto/armv4cpuid.S new file mode 100644 index 00000000..2d618dea --- /dev/null +++ b/libs/openssl/crypto/armv4cpuid.S @@ -0,0 +1,154 @@ +#include "arm_arch.h" + +.text +.code 32 + +.align 5 +.global _armv7_neon_probe +.type _armv7_neon_probe,%function +_armv7_neon_probe: + .word 0xf26ee1fe @ vorr q15,q15,q15 + .word 0xe12fff1e @ bx lr +.size _armv7_neon_probe,.-_armv7_neon_probe + +.global _armv7_tick +.type _armv7_tick,%function +_armv7_tick: + mrc p15,0,r0,c9,c13,0 + .word 0xe12fff1e @ bx lr +.size _armv7_tick,.-_armv7_tick + +.global OPENSSL_atomic_add +.type OPENSSL_atomic_add,%function +OPENSSL_atomic_add: +#if __ARM_ARCH__>=6 +.Ladd: ldrex r2,[r0] + add r3,r2,r1 + strex r2,r3,[r0] + cmp r2,#0 + bne .Ladd + mov r0,r3 + .word 0xe12fff1e @ bx lr +#else + stmdb sp!,{r4-r6,lr} + ldr r2,.Lspinlock + adr r3,.Lspinlock + mov r4,r0 + mov r5,r1 + add r6,r3,r2 @ &spinlock + b .+8 +.Lspin: bl sched_yield + mov r0,#-1 + swp r0,r0,[r6] + cmp r0,#0 + bne .Lspin + + ldr r2,[r4] + add r2,r2,r5 + str r2,[r4] + str r0,[r6] @ release spinlock + ldmia sp!,{r4-r6,lr} + tst lr,#1 + moveq pc,lr + .word 0xe12fff1e @ bx lr +#endif +.size OPENSSL_atomic_add,.-OPENSSL_atomic_add + +.global OPENSSL_cleanse +.type OPENSSL_cleanse,%function +OPENSSL_cleanse: + eor ip,ip,ip + cmp r1,#7 + subhs r1,r1,#4 + bhs .Lot + cmp r1,#0 + beq .Lcleanse_done +.Little: + strb ip,[r0],#1 + subs r1,r1,#1 + bhi .Little + b .Lcleanse_done + +.Lot: tst r0,#3 + beq .Laligned + strb ip,[r0],#1 + sub r1,r1,#1 + b .Lot +.Laligned: + str ip,[r0],#4 + subs r1,r1,#4 + bhs .Laligned + adds r1,r1,#4 + bne .Little +.Lcleanse_done: + tst lr,#1 + moveq pc,lr + .word 0xe12fff1e @ bx lr +.size OPENSSL_cleanse,.-OPENSSL_cleanse + +.global OPENSSL_wipe_cpu +.type OPENSSL_wipe_cpu,%function +OPENSSL_wipe_cpu: + ldr r0,.LOPENSSL_armcap + adr r1,.LOPENSSL_armcap + ldr r0,[r1,r0] + eor r2,r2,r2 + eor r3,r3,r3 + eor ip,ip,ip + tst r0,#1 + beq .Lwipe_done + .word 0xf3000150 @ veor q0, q0, q0 + .word 0xf3022152 @ veor q1, q1, q1 + .word 0xf3044154 @ veor q2, q2, q2 + .word 0xf3066156 @ veor q3, q3, q3 + .word 0xf34001f0 @ veor q8, q8, q8 + .word 0xf34221f2 @ veor q9, q9, q9 + .word 0xf34441f4 @ veor q10, q10, q10 + .word 0xf34661f6 @ veor q11, q11, q11 + .word 0xf34881f8 @ veor q12, q12, q12 + .word 0xf34aa1fa @ veor q13, q13, q13 + .word 0xf34cc1fc @ veor q14, q14, q14 + .word 0xf34ee1fe @ veor q15, q15, q15 +.Lwipe_done: + mov r0,sp + tst lr,#1 + moveq pc,lr + .word 0xe12fff1e @ bx lr +.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu + +.global OPENSSL_instrument_bus +.type OPENSSL_instrument_bus,%function +OPENSSL_instrument_bus: + eor r0,r0,r0 + tst lr,#1 + moveq pc,lr + .word 0xe12fff1e @ bx lr +.size OPENSSL_instrument_bus,.-OPENSSL_instrument_bus + +.global OPENSSL_instrument_bus2 +.type OPENSSL_instrument_bus2,%function +OPENSSL_instrument_bus2: + eor r0,r0,r0 + tst lr,#1 + moveq pc,lr + .word 0xe12fff1e @ bx lr +.size OPENSSL_instrument_bus2,.-OPENSSL_instrument_bus2 + +.align 5 +.LOPENSSL_armcap: +.word OPENSSL_armcap_P-.LOPENSSL_armcap +#if __ARM_ARCH__>=6 +.align 5 +#else +.Lspinlock: +.word atomic_add_spinlock-.Lspinlock +.align 5 + +.data +.align 2 +atomic_add_spinlock: +.word 0 +#endif + +.comm OPENSSL_armcap_P,4,4 +.hidden OPENSSL_armcap_P diff --git a/libs/openssl/crypto/asn1/a_bitstr.c b/libs/openssl/crypto/asn1/a_bitstr.c new file mode 100644 index 00000000..f906188b --- /dev/null +++ b/libs/openssl/crypto/asn1/a_bitstr.c @@ -0,0 +1,262 @@ +/* crypto/asn1/a_bitstr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include + +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len) +{ + return M_ASN1_BIT_STRING_set(x, d, len); +} + +int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp) +{ + int ret, j, bits, len; + unsigned char *p, *d; + + if (a == NULL) + return (0); + + len = a->length; + + if (len > 0) { + if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) { + bits = (int)a->flags & 0x07; + } else { + for (; len > 0; len--) { + if (a->data[len - 1]) + break; + } + j = a->data[len - 1]; + if (j & 0x01) + bits = 0; + else if (j & 0x02) + bits = 1; + else if (j & 0x04) + bits = 2; + else if (j & 0x08) + bits = 3; + else if (j & 0x10) + bits = 4; + else if (j & 0x20) + bits = 5; + else if (j & 0x40) + bits = 6; + else if (j & 0x80) + bits = 7; + else + bits = 0; /* should not happen */ + } + } else + bits = 0; + + ret = 1 + len; + if (pp == NULL) + return (ret); + + p = *pp; + + *(p++) = (unsigned char)bits; + d = a->data; + memcpy(p, d, len); + p += len; + if (len > 0) + p[-1] &= (0xff << bits); + *pp = p; + return (ret); +} + +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, + const unsigned char **pp, long len) +{ + ASN1_BIT_STRING *ret = NULL; + const unsigned char *p; + unsigned char *s; + int i; + + if (len < 1) { + i = ASN1_R_STRING_TOO_SHORT; + goto err; + } + + if ((a == NULL) || ((*a) == NULL)) { + if ((ret = M_ASN1_BIT_STRING_new()) == NULL) + return (NULL); + } else + ret = (*a); + + p = *pp; + i = *(p++); + if (i > 7) { + i = ASN1_R_INVALID_BIT_STRING_BITS_LEFT; + goto err; + } + /* + * We do this to preserve the settings. If we modify the settings, via + * the _set_bit function, we will recalculate on output + */ + ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */ + ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */ + + if (len-- > 1) { /* using one because of the bits left byte */ + s = (unsigned char *)OPENSSL_malloc((int)len); + if (s == NULL) { + i = ERR_R_MALLOC_FAILURE; + goto err; + } + memcpy(s, p, (int)len); + s[len - 1] &= (0xff << i); + p += len; + } else + s = NULL; + + ret->length = (int)len; + if (ret->data != NULL) + OPENSSL_free(ret->data); + ret->data = s; + ret->type = V_ASN1_BIT_STRING; + if (a != NULL) + (*a) = ret; + *pp = p; + return (ret); + err: + ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + M_ASN1_BIT_STRING_free(ret); + return (NULL); +} + +/* + * These next 2 functions from Goetz Babin-Ebell + */ +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value) +{ + int w, v, iv; + unsigned char *c; + + w = n / 8; + v = 1 << (7 - (n & 0x07)); + iv = ~v; + if (!value) + v = 0; + + if (a == NULL) + return 0; + + a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */ + + if ((a->length < (w + 1)) || (a->data == NULL)) { + if (!value) + return (1); /* Don't need to set */ + if (a->data == NULL) + c = (unsigned char *)OPENSSL_malloc(w + 1); + else + c = (unsigned char *)OPENSSL_realloc_clean(a->data, + a->length, w + 1); + if (c == NULL) { + ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT, ERR_R_MALLOC_FAILURE); + return 0; + } + if (w + 1 - a->length > 0) + memset(c + a->length, 0, w + 1 - a->length); + a->data = c; + a->length = w + 1; + } + a->data[w] = ((a->data[w]) & iv) | v; + while ((a->length > 0) && (a->data[a->length - 1] == 0)) + a->length--; + return (1); +} + +int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n) +{ + int w, v; + + w = n / 8; + v = 1 << (7 - (n & 0x07)); + if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL)) + return (0); + return ((a->data[w] & v) != 0); +} + +/* + * Checks if the given bit string contains only bits specified by + * the flags vector. Returns 0 if there is at least one bit set in 'a' + * which is not specified in 'flags', 1 otherwise. + * 'len' is the length of 'flags'. + */ +int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, + unsigned char *flags, int flags_len) +{ + int i, ok; + /* Check if there is one bit set at all. */ + if (!a || !a->data) + return 1; + + /* + * Check each byte of the internal representation of the bit string. + */ + ok = 1; + for (i = 0; i < a->length && ok; ++i) { + unsigned char mask = i < flags_len ? ~flags[i] : 0xff; + /* We are done if there is an unneeded bit set. */ + ok = (a->data[i] & mask) == 0; + } + return ok; +} diff --git a/libs/openssl/crypto/asn1/a_bool.c b/libs/openssl/crypto/asn1/a_bool.c new file mode 100644 index 00000000..1b85bc9e --- /dev/null +++ b/libs/openssl/crypto/asn1/a_bool.c @@ -0,0 +1,111 @@ +/* crypto/asn1/a_bool.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include + +int i2d_ASN1_BOOLEAN(int a, unsigned char **pp) +{ + int r; + unsigned char *p; + + r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN); + if (pp == NULL) + return (r); + p = *pp; + + ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL); + *(p++) = (unsigned char)a; + *pp = p; + return (r); +} + +int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length) +{ + int ret = -1; + const unsigned char *p; + long len; + int inf, tag, xclass; + int i = 0; + + p = *pp; + inf = ASN1_get_object(&p, &len, &tag, &xclass, length); + if (inf & 0x80) { + i = ASN1_R_BAD_OBJECT_HEADER; + goto err; + } + + if (tag != V_ASN1_BOOLEAN) { + i = ASN1_R_EXPECTING_A_BOOLEAN; + goto err; + } + + if (len != 1) { + i = ASN1_R_BOOLEAN_IS_WRONG_LENGTH; + goto err; + } + ret = (int)*(p++); + if (a != NULL) + (*a) = ret; + *pp = p; + return (ret); + err: + ASN1err(ASN1_F_D2I_ASN1_BOOLEAN, i); + return (ret); +} diff --git a/libs/openssl/crypto/asn1/a_bytes.c b/libs/openssl/crypto/asn1/a_bytes.c new file mode 100644 index 00000000..385b5398 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_bytes.c @@ -0,0 +1,306 @@ +/* crypto/asn1/a_bytes.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include + +static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c); +/* + * type is a 'bitmap' of acceptable string types. + */ +ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp, + long length, int type) +{ + ASN1_STRING *ret = NULL; + const unsigned char *p; + unsigned char *s; + long len; + int inf, tag, xclass; + int i = 0; + + p = *pp; + inf = ASN1_get_object(&p, &len, &tag, &xclass, length); + if (inf & 0x80) + goto err; + + if (tag >= 32) { + i = ASN1_R_TAG_VALUE_TOO_HIGH; + goto err; + } + if (!(ASN1_tag2bit(tag) & type)) { + i = ASN1_R_WRONG_TYPE; + goto err; + } + + /* If a bit-string, exit early */ + if (tag == V_ASN1_BIT_STRING) + return (d2i_ASN1_BIT_STRING(a, pp, length)); + + if ((a == NULL) || ((*a) == NULL)) { + if ((ret = ASN1_STRING_new()) == NULL) + return (NULL); + } else + ret = (*a); + + if (len != 0) { + s = (unsigned char *)OPENSSL_malloc((int)len + 1); + if (s == NULL) { + i = ERR_R_MALLOC_FAILURE; + goto err; + } + memcpy(s, p, (int)len); + s[len] = '\0'; + p += len; + } else + s = NULL; + + if (ret->data != NULL) + OPENSSL_free(ret->data); + ret->length = (int)len; + ret->data = s; + ret->type = tag; + if (a != NULL) + (*a) = ret; + *pp = p; + return (ret); + err: + ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES, i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + ASN1_STRING_free(ret); + return (NULL); +} + +int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass) +{ + int ret, r, constructed; + unsigned char *p; + + if (a == NULL) + return (0); + + if (tag == V_ASN1_BIT_STRING) + return (i2d_ASN1_BIT_STRING(a, pp)); + + ret = a->length; + r = ASN1_object_size(0, ret, tag); + if (pp == NULL) + return (r); + p = *pp; + + if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET)) + constructed = 1; + else + constructed = 0; + ASN1_put_object(&p, constructed, ret, tag, xclass); + memcpy(p, a->data, a->length); + p += a->length; + *pp = p; + return (r); +} + +ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, + long length, int Ptag, int Pclass) +{ + ASN1_STRING *ret = NULL; + const unsigned char *p; + unsigned char *s; + long len; + int inf, tag, xclass; + int i = 0; + + if ((a == NULL) || ((*a) == NULL)) { + if ((ret = ASN1_STRING_new()) == NULL) + return (NULL); + } else + ret = (*a); + + p = *pp; + inf = ASN1_get_object(&p, &len, &tag, &xclass, length); + if (inf & 0x80) { + i = ASN1_R_BAD_OBJECT_HEADER; + goto err; + } + + if (tag != Ptag) { + i = ASN1_R_WRONG_TAG; + goto err; + } + + if (inf & V_ASN1_CONSTRUCTED) { + ASN1_const_CTX c; + + c.pp = pp; + c.p = p; + c.inf = inf; + c.slen = len; + c.tag = Ptag; + c.xclass = Pclass; + c.max = (length == 0) ? 0 : (p + length); + if (!asn1_collate_primitive(ret, &c)) + goto err; + else { + p = c.p; + } + } else { + if (len != 0) { + if ((ret->length < len) || (ret->data == NULL)) { + s = (unsigned char *)OPENSSL_malloc((int)len + 1); + if (s == NULL) { + i = ERR_R_MALLOC_FAILURE; + goto err; + } + if (ret->data != NULL) + OPENSSL_free(ret->data); + } else + s = ret->data; + memcpy(s, p, (int)len); + s[len] = '\0'; + p += len; + } else { + s = NULL; + if (ret->data != NULL) + OPENSSL_free(ret->data); + } + + ret->length = (int)len; + ret->data = s; + ret->type = Ptag; + } + + if (a != NULL) + (*a) = ret; + *pp = p; + return (ret); + err: + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + ASN1_STRING_free(ret); + ASN1err(ASN1_F_D2I_ASN1_BYTES, i); + return (NULL); +} + +/* + * We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse them + * into the one structure that is then returned + */ +/* + * There have been a few bug fixes for this function from Paul Keogh + * , many thanks to him + */ +static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c) +{ + ASN1_STRING *os = NULL; + BUF_MEM b; + int num; + + b.length = 0; + b.max = 0; + b.data = NULL; + + if (a == NULL) { + c->error = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + num = 0; + for (;;) { + if (c->inf & 1) { + c->eos = ASN1_const_check_infinite_end(&c->p, + (long)(c->max - c->p)); + if (c->eos) + break; + } else { + if (c->slen <= 0) + break; + } + + c->q = c->p; + if (d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass) + == NULL) { + c->error = ERR_R_ASN1_LIB; + goto err; + } + + if (!BUF_MEM_grow_clean(&b, num + os->length)) { + c->error = ERR_R_BUF_LIB; + goto err; + } + memcpy(&(b.data[num]), os->data, os->length); + if (!(c->inf & 1)) + c->slen -= (c->p - c->q); + num += os->length; + } + + if (!asn1_const_Finish(c)) + goto err; + + a->length = num; + if (a->data != NULL) + OPENSSL_free(a->data); + a->data = (unsigned char *)b.data; + if (os != NULL) + ASN1_STRING_free(os); + return (1); + err: + ASN1err(ASN1_F_ASN1_COLLATE_PRIMITIVE, c->error); + if (os != NULL) + ASN1_STRING_free(os); + if (b.data != NULL) + OPENSSL_free(b.data); + return (0); +} diff --git a/libs/openssl/crypto/asn1/a_d2i_fp.c b/libs/openssl/crypto/asn1/a_d2i_fp.c new file mode 100644 index 00000000..51b6f245 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_d2i_fp.c @@ -0,0 +1,284 @@ +/* crypto/asn1/a_d2i_fp.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include + +static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb); + +#ifndef NO_OLD_ASN1 +# ifndef OPENSSL_NO_FP_API + +void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x) +{ + BIO *b; + void *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ASN1err(ASN1_F_ASN1_D2I_FP, ERR_R_BUF_LIB); + return (NULL); + } + BIO_set_fp(b, in, BIO_NOCLOSE); + ret = ASN1_d2i_bio(xnew, d2i, b, x); + BIO_free(b); + return (ret); +} +# endif + +void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x) +{ + BUF_MEM *b = NULL; + const unsigned char *p; + void *ret = NULL; + int len; + + len = asn1_d2i_read_bio(in, &b); + if (len < 0) + goto err; + + p = (unsigned char *)b->data; + ret = d2i(x, &p, len); + err: + if (b != NULL) + BUF_MEM_free(b); + return (ret); +} + +#endif + +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x) +{ + BUF_MEM *b = NULL; + const unsigned char *p; + void *ret = NULL; + int len; + + len = asn1_d2i_read_bio(in, &b); + if (len < 0) + goto err; + + p = (const unsigned char *)b->data; + ret = ASN1_item_d2i(x, &p, len, it); + err: + if (b != NULL) + BUF_MEM_free(b); + return (ret); +} + +#ifndef OPENSSL_NO_FP_API +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x) +{ + BIO *b; + char *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_D2I_FP, ERR_R_BUF_LIB); + return (NULL); + } + BIO_set_fp(b, in, BIO_NOCLOSE); + ret = ASN1_item_d2i_bio(it, b, x); + BIO_free(b); + return (ret); +} +#endif + +#define HEADER_SIZE 8 +#define ASN1_CHUNK_INITIAL_SIZE (16 * 1024) +static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb) +{ + BUF_MEM *b; + unsigned char *p; + int i; + ASN1_const_CTX c; + size_t want = HEADER_SIZE; + int eos = 0; + size_t off = 0; + size_t len = 0; + + b = BUF_MEM_new(); + if (b == NULL) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); + return -1; + } + + ERR_clear_error(); + for (;;) { + if (want >= (len - off)) { + want -= (len - off); + + if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + i = BIO_read(in, &(b->data[len]), want); + if ((i < 0) && ((len - off) == 0)) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA); + goto err; + } + if (i > 0) { + if (len + i < len) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); + goto err; + } + len += i; + } + } + /* else data already loaded */ + + p = (unsigned char *)&(b->data[off]); + c.p = p; + c.inf = ASN1_get_object(&(c.p), &(c.slen), &(c.tag), &(c.xclass), + len - off); + if (c.inf & 0x80) { + unsigned long e; + + e = ERR_GET_REASON(ERR_peek_error()); + if (e != ASN1_R_TOO_LONG) + goto err; + else + ERR_clear_error(); /* clear error */ + } + i = c.p - p; /* header length */ + off += i; /* end of data */ + + if (c.inf & 1) { + /* no data body so go round again */ + eos++; + if (eos < 0) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_HEADER_TOO_LONG); + goto err; + } + want = HEADER_SIZE; + } else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) { + /* eos value, so go back and read another header */ + eos--; + if (eos <= 0) + break; + else + want = HEADER_SIZE; + } else { + /* suck in c.slen bytes of data */ + want = c.slen; + if (want > (len - off)) { + size_t chunk_max = ASN1_CHUNK_INITIAL_SIZE; + + want -= (len - off); + if (want > INT_MAX /* BIO_read takes an int length */ || + len + want < len) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); + goto err; + } + while (want > 0) { + /* + * Read content in chunks of increasing size + * so we can return an error for EOF without + * having to allocate the entire content length + * in one go. + */ + size_t chunk = want > chunk_max ? chunk_max : want; + + if (!BUF_MEM_grow_clean(b, len + chunk)) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + want -= chunk; + while (chunk > 0) { + i = BIO_read(in, &(b->data[len]), chunk); + if (i <= 0) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, + ASN1_R_NOT_ENOUGH_DATA); + goto err; + } + /* + * This can't overflow because |len+want| didn't + * overflow. + */ + len += i; + chunk -= i; + } + if (chunk_max < INT_MAX/2) + chunk_max *= 2; + } + } + if (off + c.slen < off) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); + goto err; + } + off += c.slen; + if (eos <= 0) { + break; + } else + want = HEADER_SIZE; + } + } + + if (off > INT_MAX) { + ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG); + goto err; + } + + *pb = b; + return off; + err: + if (b != NULL) + BUF_MEM_free(b); + return -1; +} diff --git a/libs/openssl/crypto/asn1/a_digest.c b/libs/openssl/crypto/asn1/a_digest.c new file mode 100644 index 00000000..7cbc4751 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_digest.c @@ -0,0 +1,111 @@ +/* crypto/asn1/a_digest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include "cryptlib.h" + +#ifndef NO_SYS_TYPES_H +# include +#endif + +#include +#include +#include +#include + +#ifndef NO_ASN1_OLD + +int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, + unsigned char *md, unsigned int *len) +{ + int i; + unsigned char *str, *p; + + i = i2d(data, NULL); + if ((str = (unsigned char *)OPENSSL_malloc(i)) == NULL) { + ASN1err(ASN1_F_ASN1_DIGEST, ERR_R_MALLOC_FAILURE); + return (0); + } + p = str; + i2d(data, &p); + + if (!EVP_Digest(str, i, md, len, type, NULL)) + return 0; + OPENSSL_free(str); + return (1); +} + +#endif + +int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn, + unsigned char *md, unsigned int *len) +{ + int i; + unsigned char *str = NULL; + + i = ASN1_item_i2d(asn, &str, it); + if (!str) + return (0); + + if (!EVP_Digest(str, i, md, len, type, NULL)) + return 0; + OPENSSL_free(str); + return (1); +} diff --git a/libs/openssl/crypto/asn1/a_dup.c b/libs/openssl/crypto/asn1/a_dup.c new file mode 100644 index 00000000..349ab562 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_dup.c @@ -0,0 +1,117 @@ +/* crypto/asn1/a_dup.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include + +#ifndef NO_OLD_ASN1 + +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x) +{ + unsigned char *b, *p; + const unsigned char *p2; + int i; + char *ret; + + if (x == NULL) + return (NULL); + + i = i2d(x, NULL); + b = OPENSSL_malloc(i + 10); + if (b == NULL) { + ASN1err(ASN1_F_ASN1_DUP, ERR_R_MALLOC_FAILURE); + return (NULL); + } + p = b; + i = i2d(x, &p); + p2 = b; + ret = d2i(NULL, &p2, i); + OPENSSL_free(b); + return (ret); +} + +#endif + +/* + * ASN1_ITEM version of dup: this follows the model above except we don't + * need to allocate the buffer. At some point this could be rewritten to + * directly dup the underlying structure instead of doing and encode and + * decode. + */ + +void *ASN1_item_dup(const ASN1_ITEM *it, void *x) +{ + unsigned char *b = NULL; + const unsigned char *p; + long i; + void *ret; + + if (x == NULL) + return (NULL); + + i = ASN1_item_i2d(x, &b, it); + if (b == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_DUP, ERR_R_MALLOC_FAILURE); + return (NULL); + } + p = b; + ret = ASN1_item_d2i(NULL, &p, i, it); + OPENSSL_free(b); + return (ret); +} diff --git a/libs/openssl/crypto/asn1/a_enum.c b/libs/openssl/crypto/asn1/a_enum.c new file mode 100644 index 00000000..c3498ac9 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_enum.c @@ -0,0 +1,181 @@ +/* crypto/asn1/a_enum.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +/* + * Code for ENUMERATED type: identical to INTEGER apart from a different tag. + * for comments on encoding see a_int.c + */ + +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v) +{ + int j, k; + unsigned int i; + unsigned char buf[sizeof(long) + 1]; + long d; + + a->type = V_ASN1_ENUMERATED; + if (a->length < (int)(sizeof(long) + 1)) { + if (a->data != NULL) + OPENSSL_free(a->data); + if ((a->data = + (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL) + memset((char *)a->data, 0, sizeof(long) + 1); + } + if (a->data == NULL) { + ASN1err(ASN1_F_ASN1_ENUMERATED_SET, ERR_R_MALLOC_FAILURE); + return (0); + } + d = v; + if (d < 0) { + d = -d; + a->type = V_ASN1_NEG_ENUMERATED; + } + + for (i = 0; i < sizeof(long); i++) { + if (d == 0) + break; + buf[i] = (int)d & 0xff; + d >>= 8; + } + j = 0; + for (k = i - 1; k >= 0; k--) + a->data[j++] = buf[k]; + a->length = j; + return (1); +} + +long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a) +{ + int neg = 0, i; + long r = 0; + + if (a == NULL) + return (0L); + i = a->type; + if (i == V_ASN1_NEG_ENUMERATED) + neg = 1; + else if (i != V_ASN1_ENUMERATED) + return -1; + + if (a->length > (int)sizeof(long)) { + /* hmm... a bit ugly */ + return (0xffffffffL); + } + if (a->data == NULL) + return 0; + + for (i = 0; i < a->length; i++) { + r <<= 8; + r |= (unsigned char)a->data[i]; + } + if (neg) + r = -r; + return (r); +} + +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai) +{ + ASN1_ENUMERATED *ret; + int len, j; + + if (ai == NULL) + ret = M_ASN1_ENUMERATED_new(); + else + ret = ai; + if (ret == NULL) { + ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + if (BN_is_negative(bn)) + ret->type = V_ASN1_NEG_ENUMERATED; + else + ret->type = V_ASN1_ENUMERATED; + j = BN_num_bits(bn); + len = ((j == 0) ? 0 : ((j / 8) + 1)); + if (ret->length < len + 4) { + unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4); + if (!new_data) { + ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); + goto err; + } + ret->data = new_data; + } + + ret->length = BN_bn2bin(bn, ret->data); + return (ret); + err: + if (ret != ai) + M_ASN1_ENUMERATED_free(ret); + return (NULL); +} + +BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn) +{ + BIGNUM *ret; + + if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) + ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN, ASN1_R_BN_LIB); + else if (ai->type == V_ASN1_NEG_ENUMERATED) + BN_set_negative(ret, 1); + return (ret); +} diff --git a/libs/openssl/crypto/asn1/a_gentm.c b/libs/openssl/crypto/asn1/a_gentm.c new file mode 100644 index 00000000..8b3ef716 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_gentm.c @@ -0,0 +1,270 @@ +/* crypto/asn1/a_gentm.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * GENERALIZEDTIME implementation, written by Steve Henson. Based on UTCTIME + */ + +#include +#include +#include "cryptlib.h" +#include "o_time.h" +#include + +#if 0 + +int i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **pp) +{ +# ifdef CHARSET_EBCDIC + /* KLUDGE! We convert to ascii before writing DER */ + int len; + char tmp[24]; + ASN1_STRING tmpstr = *(ASN1_STRING *)a; + + len = tmpstr.length; + ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof tmp) ? sizeof tmp : len); + tmpstr.data = tmp; + + a = (ASN1_GENERALIZEDTIME *)&tmpstr; +# endif + return (i2d_ASN1_bytes((ASN1_STRING *)a, pp, + V_ASN1_GENERALIZEDTIME, V_ASN1_UNIVERSAL)); +} + +ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a, + unsigned char **pp, + long length) +{ + ASN1_GENERALIZEDTIME *ret = NULL; + + ret = + (ASN1_GENERALIZEDTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length, + V_ASN1_GENERALIZEDTIME, + V_ASN1_UNIVERSAL); + if (ret == NULL) { + ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME, ERR_R_NESTED_ASN1_ERROR); + return (NULL); + } +# ifdef CHARSET_EBCDIC + ascii2ebcdic(ret->data, ret->data, ret->length); +# endif + if (!ASN1_GENERALIZEDTIME_check(ret)) { + ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME, ASN1_R_INVALID_TIME_FORMAT); + goto err; + } + + return (ret); + err: + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + M_ASN1_GENERALIZEDTIME_free(ret); + return (NULL); +} + +#endif + +int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d) +{ + static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 }; + static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 }; + char *a; + int n, i, l, o; + + if (d->type != V_ASN1_GENERALIZEDTIME) + return (0); + l = d->length; + a = (char *)d->data; + o = 0; + /* + * GENERALIZEDTIME is similar to UTCTIME except the year is represented + * as YYYY. This stuff treats everything as a two digit field so make + * first two fields 00 to 99 + */ + if (l < 13) + goto err; + for (i = 0; i < 7; i++) { + if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { + i++; + break; + } + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = a[o] - '0'; + if (++o > l) + goto err; + + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = (n * 10) + a[o] - '0'; + if (++o > l) + goto err; + + if ((n < min[i]) || (n > max[i])) + goto err; + } + /* + * Optional fractional seconds: decimal point followed by one or more + * digits. + */ + if (a[o] == '.') { + if (++o > l) + goto err; + i = o; + while ((a[o] >= '0') && (a[o] <= '9') && (o <= l)) + o++; + /* Must have at least one digit after decimal point */ + if (i == o) + goto err; + } + + if (a[o] == 'Z') + o++; + else if ((a[o] == '+') || (a[o] == '-')) { + o++; + if (o + 4 > l) + goto err; + for (i = 7; i < 9; i++) { + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = a[o] - '0'; + o++; + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = (n * 10) + a[o] - '0'; + if ((n < min[i]) || (n > max[i])) + goto err; + o++; + } + } else { + /* Missing time zone information. */ + goto err; + } + return (o == l); + err: + return (0); +} + +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str) +{ + ASN1_GENERALIZEDTIME t; + + t.type = V_ASN1_GENERALIZEDTIME; + t.length = strlen(str); + t.data = (unsigned char *)str; + if (ASN1_GENERALIZEDTIME_check(&t)) { + if (s != NULL) { + if (!ASN1_STRING_set((ASN1_STRING *)s, + (unsigned char *)str, t.length)) + return 0; + s->type = V_ASN1_GENERALIZEDTIME; + } + return (1); + } else + return (0); +} + +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, + time_t t) +{ + return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0); +} + +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, + long offset_sec) +{ + char *p; + struct tm *ts; + struct tm data; + size_t len = 20; + + if (s == NULL) + s = M_ASN1_GENERALIZEDTIME_new(); + if (s == NULL) + return (NULL); + + ts = OPENSSL_gmtime(&t, &data); + if (ts == NULL) + return (NULL); + + if (offset_day || offset_sec) { + if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) + return NULL; + } + + p = (char *)s->data; + if ((p == NULL) || ((size_t)s->length < len)) { + p = OPENSSL_malloc(len); + if (p == NULL) { + ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, ERR_R_MALLOC_FAILURE); + return (NULL); + } + if (s->data != NULL) + OPENSSL_free(s->data); + s->data = (unsigned char *)p; + } + + BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900, + ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, + ts->tm_sec); + s->length = strlen(p); + s->type = V_ASN1_GENERALIZEDTIME; +#ifdef CHARSET_EBCDIC_not + ebcdic2ascii(s->data, s->data, s->length); +#endif + return (s); +} diff --git a/libs/openssl/crypto/asn1/a_i2d_fp.c b/libs/openssl/crypto/asn1/a_i2d_fp.c new file mode 100644 index 00000000..0f56cd4e --- /dev/null +++ b/libs/openssl/crypto/asn1/a_i2d_fp.c @@ -0,0 +1,157 @@ +/* crypto/asn1/a_i2d_fp.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +#ifndef NO_OLD_ASN1 + +# ifndef OPENSSL_NO_FP_API +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ASN1err(ASN1_F_ASN1_I2D_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, out, BIO_NOCLOSE); + ret = ASN1_i2d_bio(i2d, b, x); + BIO_free(b); + return (ret); +} +# endif + +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x) +{ + char *b; + unsigned char *p; + int i, j = 0, n, ret = 1; + + n = i2d(x, NULL); + b = (char *)OPENSSL_malloc(n); + if (b == NULL) { + ASN1err(ASN1_F_ASN1_I2D_BIO, ERR_R_MALLOC_FAILURE); + return (0); + } + + p = (unsigned char *)b; + i2d(x, &p); + + for (;;) { + i = BIO_write(out, &(b[j]), n); + if (i == n) + break; + if (i <= 0) { + ret = 0; + break; + } + j += i; + n -= i; + } + OPENSSL_free(b); + return (ret); +} + +#endif + +#ifndef OPENSSL_NO_FP_API +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_I2D_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, out, BIO_NOCLOSE); + ret = ASN1_item_i2d_bio(it, b, x); + BIO_free(b); + return (ret); +} +#endif + +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x) +{ + unsigned char *b = NULL; + int i, j = 0, n, ret = 1; + + n = ASN1_item_i2d(x, &b, it); + if (b == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO, ERR_R_MALLOC_FAILURE); + return (0); + } + + for (;;) { + i = BIO_write(out, &(b[j]), n); + if (i == n) + break; + if (i <= 0) { + ret = 0; + break; + } + j += i; + n -= i; + } + OPENSSL_free(b); + return (ret); +} diff --git a/libs/openssl/crypto/asn1/a_int.c b/libs/openssl/crypto/asn1/a_int.c new file mode 100644 index 00000000..7e26704a --- /dev/null +++ b/libs/openssl/crypto/asn1/a_int.c @@ -0,0 +1,464 @@ +/* crypto/asn1/a_int.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x) +{ + return M_ASN1_INTEGER_dup(x); +} + +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y) +{ + int neg, ret; + /* Compare signs */ + neg = x->type & V_ASN1_NEG; + if (neg != (y->type & V_ASN1_NEG)) { + if (neg) + return -1; + else + return 1; + } + + ret = ASN1_STRING_cmp(x, y); + + if (neg) + return -ret; + else + return ret; +} + +/*- + * This converts an ASN1 INTEGER into its content encoding. + * The internal representation is an ASN1_STRING whose data is a big endian + * representation of the value, ignoring the sign. The sign is determined by + * the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative. + * + * Positive integers are no problem: they are almost the same as the DER + * encoding, except if the first byte is >= 0x80 we need to add a zero pad. + * + * Negative integers are a bit trickier... + * The DER representation of negative integers is in 2s complement form. + * The internal form is converted by complementing each octet and finally + * adding one to the result. This can be done less messily with a little trick. + * If the internal form has trailing zeroes then they will become FF by the + * complement and 0 by the add one (due to carry) so just copy as many trailing + * zeros to the destination as there are in the source. The carry will add one + * to the last none zero octet: so complement this octet and add one and finally + * complement any left over until you get to the start of the string. + * + * Padding is a little trickier too. If the first bytes is > 0x80 then we pad + * with 0xff. However if the first byte is 0x80 and one of the following bytes + * is non-zero we pad with 0xff. The reason for this distinction is that 0x80 + * followed by optional zeros isn't padded. + */ + +int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp) +{ + int pad = 0, ret, i, neg; + unsigned char *p, *n, pb = 0; + + if (a == NULL) + return (0); + neg = a->type & V_ASN1_NEG; + if (a->length == 0) + ret = 1; + else { + ret = a->length; + i = a->data[0]; + if (ret == 1 && i == 0) + neg = 0; + if (!neg && (i > 127)) { + pad = 1; + pb = 0; + } else if (neg) { + if (i > 128) { + pad = 1; + pb = 0xFF; + } else if (i == 128) { + /* + * Special case: if any other bytes non zero we pad: + * otherwise we don't. + */ + for (i = 1; i < a->length; i++) + if (a->data[i]) { + pad = 1; + pb = 0xFF; + break; + } + } + } + ret += pad; + } + if (pp == NULL) + return (ret); + p = *pp; + + if (pad) + *(p++) = pb; + if (a->length == 0) + *(p++) = 0; + else if (!neg) + memcpy(p, a->data, (unsigned int)a->length); + else { + /* Begin at the end of the encoding */ + n = a->data + a->length - 1; + p += a->length - 1; + i = a->length; + /* Copy zeros to destination as long as source is zero */ + while (!*n && i > 1) { + *(p--) = 0; + n--; + i--; + } + /* Complement and increment next octet */ + *(p--) = ((*(n--)) ^ 0xff) + 1; + i--; + /* Complement any octets left */ + for (; i > 0; i--) + *(p--) = *(n--) ^ 0xff; + } + + *pp += ret; + return (ret); +} + +/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */ + +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long len) +{ + ASN1_INTEGER *ret = NULL; + const unsigned char *p, *pend; + unsigned char *to, *s; + int i; + + if ((a == NULL) || ((*a) == NULL)) { + if ((ret = M_ASN1_INTEGER_new()) == NULL) + return (NULL); + ret->type = V_ASN1_INTEGER; + } else + ret = (*a); + + p = *pp; + pend = p + len; + + /* + * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies + * a missing NULL parameter. + */ + s = (unsigned char *)OPENSSL_malloc((int)len + 1); + if (s == NULL) { + i = ERR_R_MALLOC_FAILURE; + goto err; + } + to = s; + if (!len) { + /* + * Strictly speaking this is an illegal INTEGER but we tolerate it. + */ + ret->type = V_ASN1_INTEGER; + } else if (*p & 0x80) { /* a negative number */ + ret->type = V_ASN1_NEG_INTEGER; + if ((*p == 0xff) && (len != 1)) { + p++; + len--; + } + i = len; + p += i - 1; + to += i - 1; + while ((!*p) && i) { + *(to--) = 0; + i--; + p--; + } + /* + * Special case: if all zeros then the number will be of the form FF + * followed by n zero bytes: this corresponds to 1 followed by n zero + * bytes. We've already written n zeros so we just append an extra + * one and set the first byte to a 1. This is treated separately + * because it is the only case where the number of bytes is larger + * than len. + */ + if (!i) { + *s = 1; + s[len] = 0; + len++; + } else { + *(to--) = (*(p--) ^ 0xff) + 1; + i--; + for (; i > 0; i--) + *(to--) = *(p--) ^ 0xff; + } + } else { + ret->type = V_ASN1_INTEGER; + if ((*p == 0) && (len != 1)) { + p++; + len--; + } + memcpy(s, p, (int)len); + } + + if (ret->data != NULL) + OPENSSL_free(ret->data); + ret->data = s; + ret->length = (int)len; + if (a != NULL) + (*a) = ret; + *pp = pend; + return (ret); + err: + ASN1err(ASN1_F_C2I_ASN1_INTEGER, i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + M_ASN1_INTEGER_free(ret); + return (NULL); +} + +/* + * This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1 + * integers: some broken software can encode a positive INTEGER with its MSB + * set as negative (it doesn't add a padding zero). + */ + +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length) +{ + ASN1_INTEGER *ret = NULL; + const unsigned char *p; + unsigned char *s; + long len; + int inf, tag, xclass; + int i; + + if ((a == NULL) || ((*a) == NULL)) { + if ((ret = M_ASN1_INTEGER_new()) == NULL) + return (NULL); + ret->type = V_ASN1_INTEGER; + } else + ret = (*a); + + p = *pp; + inf = ASN1_get_object(&p, &len, &tag, &xclass, length); + if (inf & 0x80) { + i = ASN1_R_BAD_OBJECT_HEADER; + goto err; + } + + if (tag != V_ASN1_INTEGER) { + i = ASN1_R_EXPECTING_AN_INTEGER; + goto err; + } + + /* + * We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies + * a missing NULL parameter. + */ + s = (unsigned char *)OPENSSL_malloc((int)len + 1); + if (s == NULL) { + i = ERR_R_MALLOC_FAILURE; + goto err; + } + ret->type = V_ASN1_INTEGER; + if (len) { + if ((*p == 0) && (len != 1)) { + p++; + len--; + } + memcpy(s, p, (int)len); + p += len; + } + + if (ret->data != NULL) + OPENSSL_free(ret->data); + ret->data = s; + ret->length = (int)len; + if (a != NULL) + (*a) = ret; + *pp = p; + return (ret); + err: + ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + M_ASN1_INTEGER_free(ret); + return (NULL); +} + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) +{ + int j, k; + unsigned int i; + unsigned char buf[sizeof(long) + 1]; + long d; + + a->type = V_ASN1_INTEGER; + if (a->length < (int)(sizeof(long) + 1)) { + if (a->data != NULL) + OPENSSL_free(a->data); + if ((a->data = + (unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL) + memset((char *)a->data, 0, sizeof(long) + 1); + } + if (a->data == NULL) { + ASN1err(ASN1_F_ASN1_INTEGER_SET, ERR_R_MALLOC_FAILURE); + return (0); + } + d = v; + if (d < 0) { + d = -d; + a->type = V_ASN1_NEG_INTEGER; + } + + for (i = 0; i < sizeof(long); i++) { + if (d == 0) + break; + buf[i] = (int)d & 0xff; + d >>= 8; + } + j = 0; + for (k = i - 1; k >= 0; k--) + a->data[j++] = buf[k]; + a->length = j; + return (1); +} + +long ASN1_INTEGER_get(const ASN1_INTEGER *a) +{ + int neg = 0, i; + long r = 0; + + if (a == NULL) + return (0L); + i = a->type; + if (i == V_ASN1_NEG_INTEGER) + neg = 1; + else if (i != V_ASN1_INTEGER) + return -1; + + if (a->length > (int)sizeof(long)) { + /* hmm... a bit ugly, return all ones */ + return -1; + } + if (a->data == NULL) + return 0; + + for (i = 0; i < a->length; i++) { + r <<= 8; + r |= (unsigned char)a->data[i]; + } + if (neg) + r = -r; + return (r); +} + +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai) +{ + ASN1_INTEGER *ret; + int len, j; + + if (ai == NULL) + ret = M_ASN1_INTEGER_new(); + else + ret = ai; + if (ret == NULL) { + ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + if (BN_is_negative(bn) && !BN_is_zero(bn)) + ret->type = V_ASN1_NEG_INTEGER; + else + ret->type = V_ASN1_INTEGER; + j = BN_num_bits(bn); + len = ((j == 0) ? 0 : ((j / 8) + 1)); + if (ret->length < len + 4) { + unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4); + if (!new_data) { + ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); + goto err; + } + ret->data = new_data; + } + ret->length = BN_bn2bin(bn, ret->data); + /* Correct zero case */ + if (!ret->length) { + ret->data[0] = 0; + ret->length = 1; + } + return (ret); + err: + if (ret != ai) + M_ASN1_INTEGER_free(ret); + return (NULL); +} + +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn) +{ + BIGNUM *ret; + + if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL) + ASN1err(ASN1_F_ASN1_INTEGER_TO_BN, ASN1_R_BN_LIB); + else if (ai->type == V_ASN1_NEG_INTEGER) + BN_set_negative(ret, 1); + return (ret); +} + +IMPLEMENT_STACK_OF(ASN1_INTEGER) + +IMPLEMENT_ASN1_SET_OF(ASN1_INTEGER) diff --git a/libs/openssl/crypto/asn1/a_mbstr.c b/libs/openssl/crypto/asn1/a_mbstr.c new file mode 100644 index 00000000..6935efe0 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_mbstr.c @@ -0,0 +1,423 @@ +/* a_mbstr.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include + +static int traverse_string(const unsigned char *p, int len, int inform, + int (*rfunc) (unsigned long value, void *in), + void *arg); +static int in_utf8(unsigned long value, void *arg); +static int out_utf8(unsigned long value, void *arg); +static int type_str(unsigned long value, void *arg); +static int cpy_asc(unsigned long value, void *arg); +static int cpy_bmp(unsigned long value, void *arg); +static int cpy_univ(unsigned long value, void *arg); +static int cpy_utf8(unsigned long value, void *arg); +static int is_printable(unsigned long value); + +/* + * These functions take a string in UTF8, ASCII or multibyte form and a mask + * of permissible ASN1 string types. It then works out the minimal type + * (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) and + * creates a string of the correct type with the supplied data. Yes this is + * horrible: it has to be :-( The 'ncopy' form checks minimum and maximum + * size limits too. + */ + +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask) +{ + return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0); +} + +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask, + long minsize, long maxsize) +{ + int str_type; + int ret; + char free_out; + int outform, outlen = 0; + ASN1_STRING *dest; + unsigned char *p; + int nchar; + char strbuf[32]; + int (*cpyfunc) (unsigned long, void *) = NULL; + if (len == -1) + len = strlen((const char *)in); + if (!mask) + mask = DIRSTRING_TYPE; + + /* First do a string check and work out the number of characters */ + switch (inform) { + + case MBSTRING_BMP: + if (len & 1) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, + ASN1_R_INVALID_BMPSTRING_LENGTH); + return -1; + } + nchar = len >> 1; + break; + + case MBSTRING_UNIV: + if (len & 3) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, + ASN1_R_INVALID_UNIVERSALSTRING_LENGTH); + return -1; + } + nchar = len >> 2; + break; + + case MBSTRING_UTF8: + nchar = 0; + /* This counts the characters and does utf8 syntax checking */ + ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar); + if (ret < 0) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_UTF8STRING); + return -1; + } + break; + + case MBSTRING_ASC: + nchar = len; + break; + + default: + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT); + return -1; + } + + if ((minsize > 0) && (nchar < minsize)) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT); + BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize); + ERR_add_error_data(2, "minsize=", strbuf); + return -1; + } + + if ((maxsize > 0) && (nchar > maxsize)) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG); + BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize); + ERR_add_error_data(2, "maxsize=", strbuf); + return -1; + } + + /* Now work out minimal type (if any) */ + if (traverse_string(in, len, inform, type_str, &mask) < 0) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS); + return -1; + } + + /* Now work out output format and string type */ + outform = MBSTRING_ASC; + if (mask & B_ASN1_PRINTABLESTRING) + str_type = V_ASN1_PRINTABLESTRING; + else if (mask & B_ASN1_IA5STRING) + str_type = V_ASN1_IA5STRING; + else if (mask & B_ASN1_T61STRING) + str_type = V_ASN1_T61STRING; + else if (mask & B_ASN1_BMPSTRING) { + str_type = V_ASN1_BMPSTRING; + outform = MBSTRING_BMP; + } else if (mask & B_ASN1_UNIVERSALSTRING) { + str_type = V_ASN1_UNIVERSALSTRING; + outform = MBSTRING_UNIV; + } else { + str_type = V_ASN1_UTF8STRING; + outform = MBSTRING_UTF8; + } + if (!out) + return str_type; + if (*out) { + free_out = 0; + dest = *out; + if (dest->data) { + dest->length = 0; + OPENSSL_free(dest->data); + dest->data = NULL; + } + dest->type = str_type; + } else { + free_out = 1; + dest = ASN1_STRING_type_new(str_type); + if (!dest) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); + return -1; + } + *out = dest; + } + /* If both the same type just copy across */ + if (inform == outform) { + if (!ASN1_STRING_set(dest, in, len)) { + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); + return -1; + } + return str_type; + } + + /* Work out how much space the destination will need */ + switch (outform) { + case MBSTRING_ASC: + outlen = nchar; + cpyfunc = cpy_asc; + break; + + case MBSTRING_BMP: + outlen = nchar << 1; + cpyfunc = cpy_bmp; + break; + + case MBSTRING_UNIV: + outlen = nchar << 2; + cpyfunc = cpy_univ; + break; + + case MBSTRING_UTF8: + outlen = 0; + traverse_string(in, len, inform, out_utf8, &outlen); + cpyfunc = cpy_utf8; + break; + } + if (!(p = OPENSSL_malloc(outlen + 1))) { + if (free_out) + ASN1_STRING_free(dest); + ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE); + return -1; + } + dest->length = outlen; + dest->data = p; + p[outlen] = 0; + traverse_string(in, len, inform, cpyfunc, &p); + return str_type; +} + +/* + * This function traverses a string and passes the value of each character to + * an optional function along with a void * argument. + */ + +static int traverse_string(const unsigned char *p, int len, int inform, + int (*rfunc) (unsigned long value, void *in), + void *arg) +{ + unsigned long value; + int ret; + while (len) { + if (inform == MBSTRING_ASC) { + value = *p++; + len--; + } else if (inform == MBSTRING_BMP) { + value = *p++ << 8; + value |= *p++; + len -= 2; + } else if (inform == MBSTRING_UNIV) { + value = ((unsigned long)*p++) << 24; + value |= ((unsigned long)*p++) << 16; + value |= *p++ << 8; + value |= *p++; + len -= 4; + } else { + ret = UTF8_getc(p, len, &value); + if (ret < 0) + return -1; + len -= ret; + p += ret; + } + if (rfunc) { + ret = rfunc(value, arg); + if (ret <= 0) + return ret; + } + } + return 1; +} + +/* Various utility functions for traverse_string */ + +/* Just count number of characters */ + +static int in_utf8(unsigned long value, void *arg) +{ + int *nchar; + nchar = arg; + (*nchar)++; + return 1; +} + +/* Determine size of output as a UTF8 String */ + +static int out_utf8(unsigned long value, void *arg) +{ + int *outlen; + outlen = arg; + *outlen += UTF8_putc(NULL, -1, value); + return 1; +} + +/* + * Determine the "type" of a string: check each character against a supplied + * "mask". + */ + +static int type_str(unsigned long value, void *arg) +{ + unsigned long types; + types = *((unsigned long *)arg); + if ((types & B_ASN1_PRINTABLESTRING) && !is_printable(value)) + types &= ~B_ASN1_PRINTABLESTRING; + if ((types & B_ASN1_IA5STRING) && (value > 127)) + types &= ~B_ASN1_IA5STRING; + if ((types & B_ASN1_T61STRING) && (value > 0xff)) + types &= ~B_ASN1_T61STRING; + if ((types & B_ASN1_BMPSTRING) && (value > 0xffff)) + types &= ~B_ASN1_BMPSTRING; + if (!types) + return -1; + *((unsigned long *)arg) = types; + return 1; +} + +/* Copy one byte per character ASCII like strings */ + +static int cpy_asc(unsigned long value, void *arg) +{ + unsigned char **p, *q; + p = arg; + q = *p; + *q = (unsigned char)value; + (*p)++; + return 1; +} + +/* Copy two byte per character BMPStrings */ + +static int cpy_bmp(unsigned long value, void *arg) +{ + unsigned char **p, *q; + p = arg; + q = *p; + *q++ = (unsigned char)((value >> 8) & 0xff); + *q = (unsigned char)(value & 0xff); + *p += 2; + return 1; +} + +/* Copy four byte per character UniversalStrings */ + +static int cpy_univ(unsigned long value, void *arg) +{ + unsigned char **p, *q; + p = arg; + q = *p; + *q++ = (unsigned char)((value >> 24) & 0xff); + *q++ = (unsigned char)((value >> 16) & 0xff); + *q++ = (unsigned char)((value >> 8) & 0xff); + *q = (unsigned char)(value & 0xff); + *p += 4; + return 1; +} + +/* Copy to a UTF8String */ + +static int cpy_utf8(unsigned long value, void *arg) +{ + unsigned char **p; + int ret; + p = arg; + /* We already know there is enough room so pass 0xff as the length */ + ret = UTF8_putc(*p, 0xff, value); + *p += ret; + return 1; +} + +/* Return 1 if the character is permitted in a PrintableString */ +static int is_printable(unsigned long value) +{ + int ch; + if (value > 0x7f) + return 0; + ch = (int)value; + /* + * Note: we can't use 'isalnum' because certain accented characters may + * count as alphanumeric in some environments. + */ +#ifndef CHARSET_EBCDIC + if ((ch >= 'a') && (ch <= 'z')) + return 1; + if ((ch >= 'A') && (ch <= 'Z')) + return 1; + if ((ch >= '0') && (ch <= '9')) + return 1; + if ((ch == ' ') || strchr("'()+,-./:=?", ch)) + return 1; +#else /* CHARSET_EBCDIC */ + if ((ch >= os_toascii['a']) && (ch <= os_toascii['z'])) + return 1; + if ((ch >= os_toascii['A']) && (ch <= os_toascii['Z'])) + return 1; + if ((ch >= os_toascii['0']) && (ch <= os_toascii['9'])) + return 1; + if ((ch == os_toascii[' ']) || strchr("'()+,-./:=?", os_toebcdic[ch])) + return 1; +#endif /* CHARSET_EBCDIC */ + return 0; +} diff --git a/libs/openssl/crypto/asn1/a_object.c b/libs/openssl/crypto/asn1/a_object.c new file mode 100644 index 00000000..27f9c169 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_object.c @@ -0,0 +1,402 @@ +/* crypto/asn1/a_object.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include + +int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp) +{ + unsigned char *p; + int objsize; + + if ((a == NULL) || (a->data == NULL)) + return (0); + + objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT); + if (pp == NULL) + return objsize; + + p = *pp; + ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); + memcpy(p, a->data, a->length); + p += a->length; + + *pp = p; + return (objsize); +} + +int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num) +{ + int i, first, len = 0, c, use_bn; + char ftmp[24], *tmp = ftmp; + int tmpsize = sizeof ftmp; + const char *p; + unsigned long l; + BIGNUM *bl = NULL; + + if (num == 0) + return (0); + else if (num == -1) + num = strlen(buf); + + p = buf; + c = *(p++); + num--; + if ((c >= '0') && (c <= '2')) { + first = c - '0'; + } else { + ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE); + goto err; + } + + if (num <= 0) { + ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER); + goto err; + } + c = *(p++); + num--; + for (;;) { + if (num <= 0) + break; + if ((c != '.') && (c != ' ')) { + ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR); + goto err; + } + l = 0; + use_bn = 0; + for (;;) { + if (num <= 0) + break; + num--; + c = *(p++); + if ((c == ' ') || (c == '.')) + break; + if ((c < '0') || (c > '9')) { + ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_DIGIT); + goto err; + } + if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) { + use_bn = 1; + if (!bl) + bl = BN_new(); + if (!bl || !BN_set_word(bl, l)) + goto err; + } + if (use_bn) { + if (!BN_mul_word(bl, 10L) + || !BN_add_word(bl, c - '0')) + goto err; + } else + l = l * 10L + (long)(c - '0'); + } + if (len == 0) { + if ((first < 2) && (l >= 40)) { + ASN1err(ASN1_F_A2D_ASN1_OBJECT, + ASN1_R_SECOND_NUMBER_TOO_LARGE); + goto err; + } + if (use_bn) { + if (!BN_add_word(bl, first * 40)) + goto err; + } else + l += (long)first *40; + } + i = 0; + if (use_bn) { + int blsize; + blsize = BN_num_bits(bl); + blsize = (blsize + 6) / 7; + if (blsize > tmpsize) { + if (tmp != ftmp) + OPENSSL_free(tmp); + tmpsize = blsize + 32; + tmp = OPENSSL_malloc(tmpsize); + if (!tmp) + goto err; + } + while (blsize--) + tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L); + } else { + + for (;;) { + tmp[i++] = (unsigned char)l & 0x7f; + l >>= 7L; + if (l == 0L) + break; + } + + } + if (out != NULL) { + if (len + i > olen) { + ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL); + goto err; + } + while (--i > 0) + out[len++] = tmp[i] | 0x80; + out[len++] = tmp[0]; + } else + len += i; + } + if (tmp != ftmp) + OPENSSL_free(tmp); + if (bl) + BN_free(bl); + return (len); + err: + if (tmp != ftmp) + OPENSSL_free(tmp); + if (bl) + BN_free(bl); + return (0); +} + +int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a) +{ + return OBJ_obj2txt(buf, buf_len, a, 0); +} + +int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a) +{ + char buf[80], *p = buf; + int i; + + if ((a == NULL) || (a->data == NULL)) + return (BIO_write(bp, "NULL", 4)); + i = i2t_ASN1_OBJECT(buf, sizeof buf, a); + if (i > (int)(sizeof(buf) - 1)) { + p = OPENSSL_malloc(i + 1); + if (!p) + return -1; + i2t_ASN1_OBJECT(p, i + 1, a); + } + if (i <= 0) + return BIO_write(bp, "", 9); + BIO_write(bp, p, i); + if (p != buf) + OPENSSL_free(p); + return (i); +} + +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length) +{ + const unsigned char *p; + long len; + int tag, xclass; + int inf, i; + ASN1_OBJECT *ret = NULL; + p = *pp; + inf = ASN1_get_object(&p, &len, &tag, &xclass, length); + if (inf & 0x80) { + i = ASN1_R_BAD_OBJECT_HEADER; + goto err; + } + + if (tag != V_ASN1_OBJECT) { + i = ASN1_R_EXPECTING_AN_OBJECT; + goto err; + } + ret = c2i_ASN1_OBJECT(a, &p, len); + if (ret) + *pp = p; + return ret; + err: + ASN1err(ASN1_F_D2I_ASN1_OBJECT, i); + return (NULL); +} + +ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long len) +{ + ASN1_OBJECT *ret = NULL; + const unsigned char *p; + unsigned char *data; + int i, length; + + /* + * Sanity check OID encoding. Need at least one content octet. MSB must + * be clear in the last octet. can't have leading 0x80 in subidentifiers, + * see: X.690 8.19.2 + */ + if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL || + p[len - 1] & 0x80) { + ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING); + return NULL; + } + /* Now 0 < len <= INT_MAX, so the cast is safe. */ + length = (int)len; + for (i = 0; i < length; i++, p++) { + if (*p == 0x80 && (!i || !(p[-1] & 0x80))) { + ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING); + return NULL; + } + } + + /* + * only the ASN1_OBJECTs from the 'table' will have values for ->sn or + * ->ln + */ + if ((a == NULL) || ((*a) == NULL) || + !((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { + if ((ret = ASN1_OBJECT_new()) == NULL) + return (NULL); + } else + ret = (*a); + + p = *pp; + /* detach data from object */ + data = (unsigned char *)ret->data; + ret->data = NULL; + /* once detached we can change it */ + if ((data == NULL) || (ret->length < length)) { + ret->length = 0; + if (data != NULL) + OPENSSL_free(data); + data = (unsigned char *)OPENSSL_malloc(length); + if (data == NULL) { + i = ERR_R_MALLOC_FAILURE; + goto err; + } + ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA; + } + memcpy(data, p, length); + /* reattach data to object, after which it remains const */ + ret->data = data; + ret->length = length; + ret->sn = NULL; + ret->ln = NULL; + /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */ + p += length; + + if (a != NULL) + (*a) = ret; + *pp = p; + return (ret); + err: + ASN1err(ASN1_F_C2I_ASN1_OBJECT, i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + ASN1_OBJECT_free(ret); + return (NULL); +} + +ASN1_OBJECT *ASN1_OBJECT_new(void) +{ + ASN1_OBJECT *ret; + + ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT)); + if (ret == NULL) { + ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->length = 0; + ret->data = NULL; + ret->nid = 0; + ret->sn = NULL; + ret->ln = NULL; + ret->flags = ASN1_OBJECT_FLAG_DYNAMIC; + return (ret); +} + +void ASN1_OBJECT_free(ASN1_OBJECT *a) +{ + if (a == NULL) + return; + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) { +#ifndef CONST_STRICT /* disable purely for compile-time strict + * const checking. Doing this on a "real" + * compile will cause memory leaks */ + if (a->sn != NULL) + OPENSSL_free((void *)a->sn); + if (a->ln != NULL) + OPENSSL_free((void *)a->ln); +#endif + a->sn = a->ln = NULL; + } + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) { + if (a->data != NULL) + OPENSSL_free((void *)a->data); + a->data = NULL; + a->length = 0; + } + if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC) + OPENSSL_free(a); +} + +ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, + const char *sn, const char *ln) +{ + ASN1_OBJECT o; + + o.sn = sn; + o.ln = ln; + o.data = data; + o.nid = nid; + o.length = len; + o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA; + return (OBJ_dup(&o)); +} + +IMPLEMENT_STACK_OF(ASN1_OBJECT) + +IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT) diff --git a/libs/openssl/crypto/asn1/a_octet.c b/libs/openssl/crypto/asn1/a_octet.c new file mode 100644 index 00000000..1a6e9ca9 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_octet.c @@ -0,0 +1,78 @@ +/* crypto/asn1/a_octet.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include + +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x) +{ + return M_ASN1_OCTET_STRING_dup(x); +} + +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, + const ASN1_OCTET_STRING *b) +{ + return M_ASN1_OCTET_STRING_cmp(a, b); +} + +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, + int len) +{ + return M_ASN1_OCTET_STRING_set(x, d, len); +} diff --git a/libs/openssl/crypto/asn1/a_print.c b/libs/openssl/crypto/asn1/a_print.c new file mode 100644 index 00000000..d83e4ad8 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_print.c @@ -0,0 +1,129 @@ +/* crypto/asn1/a_print.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include + +int ASN1_PRINTABLE_type(const unsigned char *s, int len) +{ + int c; + int ia5 = 0; + int t61 = 0; + + if (len <= 0) + len = -1; + if (s == NULL) + return (V_ASN1_PRINTABLESTRING); + + while ((*s) && (len-- != 0)) { + c = *(s++); +#ifndef CHARSET_EBCDIC + if (!(((c >= 'a') && (c <= 'z')) || + ((c >= 'A') && (c <= 'Z')) || + (c == ' ') || + ((c >= '0') && (c <= '9')) || + (c == ' ') || (c == '\'') || + (c == '(') || (c == ')') || + (c == '+') || (c == ',') || + (c == '-') || (c == '.') || + (c == '/') || (c == ':') || (c == '=') || (c == '?'))) + ia5 = 1; + if (c & 0x80) + t61 = 1; +#else + if (!isalnum(c) && (c != ' ') && strchr("'()+,-./:=?", c) == NULL) + ia5 = 1; + if (os_toascii[c] & 0x80) + t61 = 1; +#endif + } + if (t61) + return (V_ASN1_T61STRING); + if (ia5) + return (V_ASN1_IA5STRING); + return (V_ASN1_PRINTABLESTRING); +} + +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s) +{ + int i; + unsigned char *p; + + if (s->type != V_ASN1_UNIVERSALSTRING) + return (0); + if ((s->length % 4) != 0) + return (0); + p = s->data; + for (i = 0; i < s->length; i += 4) { + if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0')) + break; + else + p += 4; + } + if (i < s->length) + return (0); + p = s->data; + for (i = 3; i < s->length; i += 4) { + *(p++) = s->data[i]; + } + *(p) = '\0'; + s->length /= 4; + s->type = ASN1_PRINTABLE_type(s->data, s->length); + return (1); +} diff --git a/libs/openssl/crypto/asn1/a_set.c b/libs/openssl/crypto/asn1/a_set.c new file mode 100644 index 00000000..bf3f9718 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_set.c @@ -0,0 +1,238 @@ +/* crypto/asn1/a_set.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include + +#ifndef NO_ASN1_OLD + +typedef struct { + unsigned char *pbData; + int cbData; +} MYBLOB; + +/* + * SetBlobCmp This function compares two elements of SET_OF block + */ +static int SetBlobCmp(const void *elem1, const void *elem2) +{ + const MYBLOB *b1 = (const MYBLOB *)elem1; + const MYBLOB *b2 = (const MYBLOB *)elem2; + int r; + + r = memcmp(b1->pbData, b2->pbData, + b1->cbData < b2->cbData ? b1->cbData : b2->cbData); + if (r != 0) + return r; + return b1->cbData - b2->cbData; +} + +/* + * int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) + */ +int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, + i2d_of_void *i2d, int ex_tag, int ex_class, int is_set) +{ + int ret = 0, r; + int i; + unsigned char *p; + unsigned char *pStart, *pTempMem; + MYBLOB *rgSetBlob; + int totSize; + + if (a == NULL) + return (0); + for (i = sk_OPENSSL_BLOCK_num(a) - 1; i >= 0; i--) + ret += i2d(sk_OPENSSL_BLOCK_value(a, i), NULL); + r = ASN1_object_size(1, ret, ex_tag); + if (pp == NULL) + return (r); + + p = *pp; + ASN1_put_object(&p, 1, ret, ex_tag, ex_class); + +/* Modified by gp@nsj.co.jp */ + /* And then again by Ben */ + /* And again by Steve */ + + if (!is_set || (sk_OPENSSL_BLOCK_num(a) < 2)) { + for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++) + i2d(sk_OPENSSL_BLOCK_value(a, i), &p); + + *pp = p; + return (r); + } + + pStart = p; /* Catch the beg of Setblobs */ + /* In this array we will store the SET blobs */ + rgSetBlob = OPENSSL_malloc(sk_OPENSSL_BLOCK_num(a) * sizeof(MYBLOB)); + if (rgSetBlob == NULL) { + ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE); + return (0); + } + + for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++) { + rgSetBlob[i].pbData = p; /* catch each set encode blob */ + i2d(sk_OPENSSL_BLOCK_value(a, i), &p); + rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this + * SetBlob */ + } + *pp = p; + totSize = p - pStart; /* This is the total size of all set blobs */ + + /* + * Now we have to sort the blobs. I am using a simple algo. *Sort ptrs + * *Copy to temp-mem *Copy from temp-mem to user-mem + */ + qsort(rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp); + if (!(pTempMem = OPENSSL_malloc(totSize))) { + ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE); + return (0); + } + +/* Copy to temp mem */ + p = pTempMem; + for (i = 0; i < sk_OPENSSL_BLOCK_num(a); ++i) { + memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData); + p += rgSetBlob[i].cbData; + } + +/* Copy back to user mem*/ + memcpy(pStart, pTempMem, totSize); + OPENSSL_free(pTempMem); + OPENSSL_free(rgSetBlob); + + return (r); +} + +STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a, + const unsigned char **pp, + long length, d2i_of_void *d2i, + void (*free_func) (OPENSSL_BLOCK), + int ex_tag, int ex_class) +{ + ASN1_const_CTX c; + STACK_OF(OPENSSL_BLOCK) *ret = NULL; + + if ((a == NULL) || ((*a) == NULL)) { + if ((ret = sk_OPENSSL_BLOCK_new_null()) == NULL) { + ASN1err(ASN1_F_D2I_ASN1_SET, ERR_R_MALLOC_FAILURE); + goto err; + } + } else + ret = (*a); + + c.p = *pp; + c.max = (length == 0) ? 0 : (c.p + length); + + c.inf = ASN1_get_object(&c.p, &c.slen, &c.tag, &c.xclass, c.max - c.p); + if (c.inf & 0x80) + goto err; + if (ex_class != c.xclass) { + ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_BAD_CLASS); + goto err; + } + if (ex_tag != c.tag) { + ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_BAD_TAG); + goto err; + } + if ((c.slen + c.p) > c.max) { + ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_LENGTH_ERROR); + goto err; + } + /* + * check for infinite constructed - it can be as long as the amount of + * data passed to us + */ + if (c.inf == (V_ASN1_CONSTRUCTED + 1)) + c.slen = length + *pp - c.p; + c.max = c.p + c.slen; + + while (c.p < c.max) { + char *s; + + if (M_ASN1_D2I_end_sequence()) + break; + /* + * XXX: This was called with 4 arguments, incorrectly, it seems if + * ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) + */ + if ((s = d2i(NULL, &c.p, c.slen)) == NULL) { + ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_ERROR_PARSING_SET_ELEMENT); + asn1_add_error(*pp, (int)(c.p - *pp)); + goto err; + } + if (!sk_OPENSSL_BLOCK_push(ret, s)) + goto err; + } + if (a != NULL) + (*a) = ret; + *pp = c.p; + return (ret); + err: + if ((ret != NULL) && ((a == NULL) || (*a != ret))) { + if (free_func != NULL) + sk_OPENSSL_BLOCK_pop_free(ret, free_func); + else + sk_OPENSSL_BLOCK_free(ret); + } + return (NULL); +} + +#endif diff --git a/libs/openssl/crypto/asn1/a_sign.c b/libs/openssl/crypto/asn1/a_sign.c new file mode 100644 index 00000000..51c6a0c3 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_sign.c @@ -0,0 +1,331 @@ +/* crypto/asn1/a_sign.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "cryptlib.h" + +#ifndef NO_SYS_TYPES_H +# include +#endif + +#include +#include +#include +#include +#include +#include "asn1_locl.h" + +#ifndef NO_ASN1_OLD + +int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey, + const EVP_MD *type) +{ + EVP_MD_CTX ctx; + unsigned char *p, *buf_in = NULL, *buf_out = NULL; + int i, inl = 0, outl = 0, outll = 0; + X509_ALGOR *a; + + EVP_MD_CTX_init(&ctx); + for (i = 0; i < 2; i++) { + if (i == 0) + a = algor1; + else + a = algor2; + if (a == NULL) + continue; + if (type->pkey_type == NID_dsaWithSHA1) { + /* + * special case: RFC 2459 tells us to omit 'parameters' with + * id-dsa-with-sha1 + */ + ASN1_TYPE_free(a->parameter); + a->parameter = NULL; + } else if ((a->parameter == NULL) || + (a->parameter->type != V_ASN1_NULL)) { + ASN1_TYPE_free(a->parameter); + if ((a->parameter = ASN1_TYPE_new()) == NULL) + goto err; + a->parameter->type = V_ASN1_NULL; + } + ASN1_OBJECT_free(a->algorithm); + a->algorithm = OBJ_nid2obj(type->pkey_type); + if (a->algorithm == NULL) { + ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE); + goto err; + } + if (a->algorithm->length == 0) { + ASN1err(ASN1_F_ASN1_SIGN, + ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); + goto err; + } + } + inl = i2d(data, NULL); + buf_in = (unsigned char *)OPENSSL_malloc((unsigned int)inl); + outll = outl = EVP_PKEY_size(pkey); + buf_out = (unsigned char *)OPENSSL_malloc((unsigned int)outl); + if ((buf_in == NULL) || (buf_out == NULL)) { + outl = 0; + ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + p = buf_in; + + i2d(data, &p); + if (!EVP_SignInit_ex(&ctx, type, NULL) + || !EVP_SignUpdate(&ctx, (unsigned char *)buf_in, inl) + || !EVP_SignFinal(&ctx, (unsigned char *)buf_out, + (unsigned int *)&outl, pkey)) { + outl = 0; + ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB); + goto err; + } + if (signature->data != NULL) + OPENSSL_free(signature->data); + signature->data = buf_out; + buf_out = NULL; + signature->length = outl; + /* + * In the interests of compatibility, I'll make sure that the bit string + * has a 'not-used bits' value of 0 + */ + signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + err: + EVP_MD_CTX_cleanup(&ctx); + if (buf_in != NULL) { + OPENSSL_cleanse((char *)buf_in, (unsigned int)inl); + OPENSSL_free(buf_in); + } + if (buf_out != NULL) { + OPENSSL_cleanse((char *)buf_out, outll); + OPENSSL_free(buf_out); + } + return (outl); +} + +#endif + +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn, + EVP_PKEY *pkey, const EVP_MD *type) +{ + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) { + EVP_MD_CTX_cleanup(&ctx); + return 0; + } + return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx); +} + +int ASN1_item_sign_ctx(const ASN1_ITEM *it, + X509_ALGOR *algor1, X509_ALGOR *algor2, + ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx) +{ + const EVP_MD *type; + EVP_PKEY *pkey; + unsigned char *buf_in = NULL, *buf_out = NULL; + size_t inl = 0, outl = 0, outll = 0; + int signid, paramtype; + int rv; + + type = EVP_MD_CTX_md(ctx); + pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + + if (!type || !pkey) { + ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED); + return 0; + } + + if (pkey->ameth->item_sign) { + rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature); + if (rv == 1) + outl = signature->length; + /*- + * Return value meanings: + * <=0: error. + * 1: method does everything. + * 2: carry on as normal. + * 3: ASN1 method sets algorithm identifiers: just sign. + */ + if (rv <= 0) + ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); + if (rv <= 1) + goto err; + } else + rv = 2; + + if (rv == 2) { + if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { + if (!pkey->ameth || + !OBJ_find_sigid_by_algs(&signid, + EVP_MD_nid(type), + pkey->ameth->pkey_id)) { + ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, + ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); + return 0; + } + } else + signid = type->pkey_type; + + if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL) + paramtype = V_ASN1_NULL; + else + paramtype = V_ASN1_UNDEF; + + if (algor1) + X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL); + if (algor2) + X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL); + + } + + inl = ASN1_item_i2d(asn, &buf_in, it); + outll = outl = EVP_PKEY_size(pkey); + buf_out = OPENSSL_malloc((unsigned int)outl); + if ((buf_in == NULL) || (buf_out == NULL)) { + outl = 0; + ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestSignUpdate(ctx, buf_in, inl) + || !EVP_DigestSignFinal(ctx, buf_out, &outl)) { + outl = 0; + ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB); + goto err; + } + if (signature->data != NULL) + OPENSSL_free(signature->data); + signature->data = buf_out; + buf_out = NULL; + signature->length = outl; + /* + * In the interests of compatibility, I'll make sure that the bit string + * has a 'not-used bits' value of 0 + */ + signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + signature->flags |= ASN1_STRING_FLAG_BITS_LEFT; + err: + EVP_MD_CTX_cleanup(ctx); + if (buf_in != NULL) { + OPENSSL_cleanse((char *)buf_in, (unsigned int)inl); + OPENSSL_free(buf_in); + } + if (buf_out != NULL) { + OPENSSL_cleanse((char *)buf_out, outll); + OPENSSL_free(buf_out); + } + return (outl); +} diff --git a/libs/openssl/crypto/asn1/a_strex.c b/libs/openssl/crypto/asn1/a_strex.c new file mode 100644 index 00000000..35fd44cd --- /dev/null +++ b/libs/openssl/crypto/asn1/a_strex.c @@ -0,0 +1,649 @@ +/* a_strex.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include + +#include "charmap.h" + +/* + * ASN1_STRING_print_ex() and X509_NAME_print_ex(). Enhanced string and name + * printing routines handling multibyte characters, RFC2253 and a host of + * other options. + */ + +#define CHARTYPE_BS_ESC (ASN1_STRFLGS_ESC_2253 | CHARTYPE_FIRST_ESC_2253 | CHARTYPE_LAST_ESC_2253) + +#define ESC_FLAGS (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB) + +/* + * Three IO functions for sending data to memory, a BIO and and a FILE + * pointer. + */ +#if 0 /* never used */ +static int send_mem_chars(void *arg, const void *buf, int len) +{ + unsigned char **out = arg; + if (!out) + return 1; + memcpy(*out, buf, len); + *out += len; + return 1; +} +#endif + +static int send_bio_chars(void *arg, const void *buf, int len) +{ + if (!arg) + return 1; + if (BIO_write(arg, buf, len) != len) + return 0; + return 1; +} + +static int send_fp_chars(void *arg, const void *buf, int len) +{ + if (!arg) + return 1; + if (fwrite(buf, 1, len, arg) != (unsigned int)len) + return 0; + return 1; +} + +typedef int char_io (void *arg, const void *buf, int len); + +/* + * This function handles display of strings, one character at a time. It is + * passed an unsigned long for each character because it could come from 2 or + * even 4 byte forms. + */ + +static int do_esc_char(unsigned long c, unsigned char flags, char *do_quotes, + char_io *io_ch, void *arg) +{ + unsigned char chflgs, chtmp; + char tmphex[HEX_SIZE(long) + 3]; + + if (c > 0xffffffffL) + return -1; + if (c > 0xffff) { + BIO_snprintf(tmphex, sizeof tmphex, "\\W%08lX", c); + if (!io_ch(arg, tmphex, 10)) + return -1; + return 10; + } + if (c > 0xff) { + BIO_snprintf(tmphex, sizeof tmphex, "\\U%04lX", c); + if (!io_ch(arg, tmphex, 6)) + return -1; + return 6; + } + chtmp = (unsigned char)c; + if (chtmp > 0x7f) + chflgs = flags & ASN1_STRFLGS_ESC_MSB; + else + chflgs = char_type[chtmp] & flags; + if (chflgs & CHARTYPE_BS_ESC) { + /* If we don't escape with quotes, signal we need quotes */ + if (chflgs & ASN1_STRFLGS_ESC_QUOTE) { + if (do_quotes) + *do_quotes = 1; + if (!io_ch(arg, &chtmp, 1)) + return -1; + return 1; + } + if (!io_ch(arg, "\\", 1)) + return -1; + if (!io_ch(arg, &chtmp, 1)) + return -1; + return 2; + } + if (chflgs & (ASN1_STRFLGS_ESC_CTRL | ASN1_STRFLGS_ESC_MSB)) { + BIO_snprintf(tmphex, 11, "\\%02X", chtmp); + if (!io_ch(arg, tmphex, 3)) + return -1; + return 3; + } + /* + * If we get this far and do any escaping at all must escape the escape + * character itself: backslash. + */ + if (chtmp == '\\' && flags & ESC_FLAGS) { + if (!io_ch(arg, "\\\\", 2)) + return -1; + return 2; + } + if (!io_ch(arg, &chtmp, 1)) + return -1; + return 1; +} + +#define BUF_TYPE_WIDTH_MASK 0x7 +#define BUF_TYPE_CONVUTF8 0x8 + +/* + * This function sends each character in a buffer to do_esc_char(). It + * interprets the content formats and converts to or from UTF8 as + * appropriate. + */ + +static int do_buf(unsigned char *buf, int buflen, + int type, unsigned char flags, char *quotes, char_io *io_ch, + void *arg) +{ + int i, outlen, len; + unsigned char orflags, *p, *q; + unsigned long c; + p = buf; + q = buf + buflen; + outlen = 0; + while (p != q) { + if (p == buf && flags & ASN1_STRFLGS_ESC_2253) + orflags = CHARTYPE_FIRST_ESC_2253; + else + orflags = 0; + switch (type & BUF_TYPE_WIDTH_MASK) { + case 4: + c = ((unsigned long)*p++) << 24; + c |= ((unsigned long)*p++) << 16; + c |= ((unsigned long)*p++) << 8; + c |= *p++; + break; + + case 2: + c = ((unsigned long)*p++) << 8; + c |= *p++; + break; + + case 1: + c = *p++; + break; + + case 0: + i = UTF8_getc(p, buflen, &c); + if (i < 0) + return -1; /* Invalid UTF8String */ + p += i; + break; + default: + return -1; /* invalid width */ + } + if (p == q && flags & ASN1_STRFLGS_ESC_2253) + orflags = CHARTYPE_LAST_ESC_2253; + if (type & BUF_TYPE_CONVUTF8) { + unsigned char utfbuf[6]; + int utflen; + utflen = UTF8_putc(utfbuf, sizeof utfbuf, c); + for (i = 0; i < utflen; i++) { + /* + * We don't need to worry about setting orflags correctly + * because if utflen==1 its value will be correct anyway + * otherwise each character will be > 0x7f and so the + * character will never be escaped on first and last. + */ + len = + do_esc_char(utfbuf[i], (unsigned char)(flags | orflags), + quotes, io_ch, arg); + if (len < 0) + return -1; + outlen += len; + } + } else { + len = + do_esc_char(c, (unsigned char)(flags | orflags), quotes, + io_ch, arg); + if (len < 0) + return -1; + outlen += len; + } + } + return outlen; +} + +/* This function hex dumps a buffer of characters */ + +static int do_hex_dump(char_io *io_ch, void *arg, unsigned char *buf, + int buflen) +{ + static const char hexdig[] = "0123456789ABCDEF"; + unsigned char *p, *q; + char hextmp[2]; + if (arg) { + p = buf; + q = buf + buflen; + while (p != q) { + hextmp[0] = hexdig[*p >> 4]; + hextmp[1] = hexdig[*p & 0xf]; + if (!io_ch(arg, hextmp, 2)) + return -1; + p++; + } + } + return buflen << 1; +} + +/* + * "dump" a string. This is done when the type is unknown, or the flags + * request it. We can either dump the content octets or the entire DER + * encoding. This uses the RFC2253 #01234 format. + */ + +static int do_dump(unsigned long lflags, char_io *io_ch, void *arg, + ASN1_STRING *str) +{ + /* + * Placing the ASN1_STRING in a temp ASN1_TYPE allows the DER encoding to + * readily obtained + */ + ASN1_TYPE t; + unsigned char *der_buf, *p; + int outlen, der_len; + + if (!io_ch(arg, "#", 1)) + return -1; + /* If we don't dump DER encoding just dump content octets */ + if (!(lflags & ASN1_STRFLGS_DUMP_DER)) { + outlen = do_hex_dump(io_ch, arg, str->data, str->length); + if (outlen < 0) + return -1; + return outlen + 1; + } + t.type = str->type; + t.value.ptr = (char *)str; + der_len = i2d_ASN1_TYPE(&t, NULL); + der_buf = OPENSSL_malloc(der_len); + if (!der_buf) + return -1; + p = der_buf; + i2d_ASN1_TYPE(&t, &p); + outlen = do_hex_dump(io_ch, arg, der_buf, der_len); + OPENSSL_free(der_buf); + if (outlen < 0) + return -1; + return outlen + 1; +} + +/* + * Lookup table to convert tags to character widths, 0 = UTF8 encoded, -1 is + * used for non string types otherwise it is the number of bytes per + * character + */ + +static const signed char tag2nbyte[] = { + -1, -1, -1, -1, -1, /* 0-4 */ + -1, -1, -1, -1, -1, /* 5-9 */ + -1, -1, 0, -1, /* 10-13 */ + -1, -1, -1, -1, /* 15-17 */ + -1, 1, 1, /* 18-20 */ + -1, 1, 1, 1, /* 21-24 */ + -1, 1, -1, /* 25-27 */ + 4, -1, 2 /* 28-30 */ +}; + +/* + * This is the main function, print out an ASN1_STRING taking note of various + * escape and display options. Returns number of characters written or -1 if + * an error occurred. + */ + +static int do_print_ex(char_io *io_ch, void *arg, unsigned long lflags, + ASN1_STRING *str) +{ + int outlen, len; + int type; + char quotes; + unsigned char flags; + quotes = 0; + /* Keep a copy of escape flags */ + flags = (unsigned char)(lflags & ESC_FLAGS); + + type = str->type; + + outlen = 0; + + if (lflags & ASN1_STRFLGS_SHOW_TYPE) { + const char *tagname; + tagname = ASN1_tag2str(type); + outlen += strlen(tagname); + if (!io_ch(arg, tagname, outlen) || !io_ch(arg, ":", 1)) + return -1; + outlen++; + } + + /* Decide what to do with type, either dump content or display it */ + + /* Dump everything */ + if (lflags & ASN1_STRFLGS_DUMP_ALL) + type = -1; + /* Ignore the string type */ + else if (lflags & ASN1_STRFLGS_IGNORE_TYPE) + type = 1; + else { + /* Else determine width based on type */ + if ((type > 0) && (type < 31)) + type = tag2nbyte[type]; + else + type = -1; + if ((type == -1) && !(lflags & ASN1_STRFLGS_DUMP_UNKNOWN)) + type = 1; + } + + if (type == -1) { + len = do_dump(lflags, io_ch, arg, str); + if (len < 0) + return -1; + outlen += len; + return outlen; + } + + if (lflags & ASN1_STRFLGS_UTF8_CONVERT) { + /* + * Note: if string is UTF8 and we want to convert to UTF8 then we + * just interpret it as 1 byte per character to avoid converting + * twice. + */ + if (!type) + type = 1; + else + type |= BUF_TYPE_CONVUTF8; + } + + len = do_buf(str->data, str->length, type, flags, "es, io_ch, NULL); + if (len < 0) + return -1; + outlen += len; + if (quotes) + outlen += 2; + if (!arg) + return outlen; + if (quotes && !io_ch(arg, "\"", 1)) + return -1; + if (do_buf(str->data, str->length, type, flags, NULL, io_ch, arg) < 0) + return -1; + if (quotes && !io_ch(arg, "\"", 1)) + return -1; + return outlen; +} + +/* Used for line indenting: print 'indent' spaces */ + +static int do_indent(char_io *io_ch, void *arg, int indent) +{ + int i; + for (i = 0; i < indent; i++) + if (!io_ch(arg, " ", 1)) + return 0; + return 1; +} + +#define FN_WIDTH_LN 25 +#define FN_WIDTH_SN 10 + +static int do_name_ex(char_io *io_ch, void *arg, X509_NAME *n, + int indent, unsigned long flags) +{ + int i, prev = -1, orflags, cnt; + int fn_opt, fn_nid; + ASN1_OBJECT *fn; + ASN1_STRING *val; + X509_NAME_ENTRY *ent; + char objtmp[80]; + const char *objbuf; + int outlen, len; + char *sep_dn, *sep_mv, *sep_eq; + int sep_dn_len, sep_mv_len, sep_eq_len; + if (indent < 0) + indent = 0; + outlen = indent; + if (!do_indent(io_ch, arg, indent)) + return -1; + switch (flags & XN_FLAG_SEP_MASK) { + case XN_FLAG_SEP_MULTILINE: + sep_dn = "\n"; + sep_dn_len = 1; + sep_mv = " + "; + sep_mv_len = 3; + break; + + case XN_FLAG_SEP_COMMA_PLUS: + sep_dn = ","; + sep_dn_len = 1; + sep_mv = "+"; + sep_mv_len = 1; + indent = 0; + break; + + case XN_FLAG_SEP_CPLUS_SPC: + sep_dn = ", "; + sep_dn_len = 2; + sep_mv = " + "; + sep_mv_len = 3; + indent = 0; + break; + + case XN_FLAG_SEP_SPLUS_SPC: + sep_dn = "; "; + sep_dn_len = 2; + sep_mv = " + "; + sep_mv_len = 3; + indent = 0; + break; + + default: + return -1; + } + + if (flags & XN_FLAG_SPC_EQ) { + sep_eq = " = "; + sep_eq_len = 3; + } else { + sep_eq = "="; + sep_eq_len = 1; + } + + fn_opt = flags & XN_FLAG_FN_MASK; + + cnt = X509_NAME_entry_count(n); + for (i = 0; i < cnt; i++) { + if (flags & XN_FLAG_DN_REV) + ent = X509_NAME_get_entry(n, cnt - i - 1); + else + ent = X509_NAME_get_entry(n, i); + if (prev != -1) { + if (prev == ent->set) { + if (!io_ch(arg, sep_mv, sep_mv_len)) + return -1; + outlen += sep_mv_len; + } else { + if (!io_ch(arg, sep_dn, sep_dn_len)) + return -1; + outlen += sep_dn_len; + if (!do_indent(io_ch, arg, indent)) + return -1; + outlen += indent; + } + } + prev = ent->set; + fn = X509_NAME_ENTRY_get_object(ent); + val = X509_NAME_ENTRY_get_data(ent); + fn_nid = OBJ_obj2nid(fn); + if (fn_opt != XN_FLAG_FN_NONE) { + int objlen, fld_len; + if ((fn_opt == XN_FLAG_FN_OID) || (fn_nid == NID_undef)) { + OBJ_obj2txt(objtmp, sizeof objtmp, fn, 1); + fld_len = 0; /* XXX: what should this be? */ + objbuf = objtmp; + } else { + if (fn_opt == XN_FLAG_FN_SN) { + fld_len = FN_WIDTH_SN; + objbuf = OBJ_nid2sn(fn_nid); + } else if (fn_opt == XN_FLAG_FN_LN) { + fld_len = FN_WIDTH_LN; + objbuf = OBJ_nid2ln(fn_nid); + } else { + fld_len = 0; /* XXX: what should this be? */ + objbuf = ""; + } + } + objlen = strlen(objbuf); + if (!io_ch(arg, objbuf, objlen)) + return -1; + if ((objlen < fld_len) && (flags & XN_FLAG_FN_ALIGN)) { + if (!do_indent(io_ch, arg, fld_len - objlen)) + return -1; + outlen += fld_len - objlen; + } + if (!io_ch(arg, sep_eq, sep_eq_len)) + return -1; + outlen += objlen + sep_eq_len; + } + /* + * If the field name is unknown then fix up the DER dump flag. We + * might want to limit this further so it will DER dump on anything + * other than a few 'standard' fields. + */ + if ((fn_nid == NID_undef) && (flags & XN_FLAG_DUMP_UNKNOWN_FIELDS)) + orflags = ASN1_STRFLGS_DUMP_ALL; + else + orflags = 0; + + len = do_print_ex(io_ch, arg, flags | orflags, val); + if (len < 0) + return -1; + outlen += len; + } + return outlen; +} + +/* Wrappers round the main functions */ + +int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, + unsigned long flags) +{ + if (flags == XN_FLAG_COMPAT) + return X509_NAME_print(out, nm, indent); + return do_name_ex(send_bio_chars, out, nm, indent, flags); +} + +#ifndef OPENSSL_NO_FP_API +int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, + unsigned long flags) +{ + if (flags == XN_FLAG_COMPAT) { + BIO *btmp; + int ret; + btmp = BIO_new_fp(fp, BIO_NOCLOSE); + if (!btmp) + return -1; + ret = X509_NAME_print(btmp, nm, indent); + BIO_free(btmp); + return ret; + } + return do_name_ex(send_fp_chars, fp, nm, indent, flags); +} +#endif + +int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags) +{ + return do_print_ex(send_bio_chars, out, flags, str); +} + +#ifndef OPENSSL_NO_FP_API +int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags) +{ + return do_print_ex(send_fp_chars, fp, flags, str); +} +#endif + +/* + * Utility function: convert any string type to UTF8, returns number of bytes + * in output string or a negative error code + */ + +int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in) +{ + ASN1_STRING stmp, *str = &stmp; + int mbflag, type, ret; + if (!in) + return -1; + type = in->type; + if ((type < 0) || (type > 30)) + return -1; + mbflag = tag2nbyte[type]; + if (mbflag == -1) + return -1; + mbflag |= MBSTRING_FLAG; + stmp.data = NULL; + stmp.length = 0; + stmp.flags = 0; + ret = + ASN1_mbstring_copy(&str, in->data, in->length, mbflag, + B_ASN1_UTF8STRING); + if (ret < 0) + return ret; + *out = stmp.data; + return stmp.length; +} diff --git a/libs/openssl/crypto/asn1/a_strnid.c b/libs/openssl/crypto/asn1/a_strnid.c new file mode 100644 index 00000000..52243453 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_strnid.c @@ -0,0 +1,313 @@ +/* a_strnid.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include +#include + +static STACK_OF(ASN1_STRING_TABLE) *stable = NULL; +static void st_free(ASN1_STRING_TABLE *tbl); +static int sk_table_cmp(const ASN1_STRING_TABLE *const *a, + const ASN1_STRING_TABLE *const *b); + +/* + * This is the global mask for the mbstring functions: this is use to mask + * out certain types (such as BMPString and UTF8String) because certain + * software (e.g. Netscape) has problems with them. + */ + +static unsigned long global_mask = B_ASN1_UTF8STRING; + +void ASN1_STRING_set_default_mask(unsigned long mask) +{ + global_mask = mask; +} + +unsigned long ASN1_STRING_get_default_mask(void) +{ + return global_mask; +} + +/*- + * This function sets the default to various "flavours" of configuration. + * based on an ASCII string. Currently this is: + * MASK:XXXX : a numerical mask value. + * nobmp : Don't use BMPStrings (just Printable, T61). + * pkix : PKIX recommendation in RFC2459. + * utf8only : only use UTF8Strings (RFC2459 recommendation for 2004). + * default: the default value, Printable, T61, BMP. + */ + +int ASN1_STRING_set_default_mask_asc(const char *p) +{ + unsigned long mask; + char *end; + if (!strncmp(p, "MASK:", 5)) { + if (!p[5]) + return 0; + mask = strtoul(p + 5, &end, 0); + if (*end) + return 0; + } else if (!strcmp(p, "nombstr")) + mask = ~((unsigned long)(B_ASN1_BMPSTRING | B_ASN1_UTF8STRING)); + else if (!strcmp(p, "pkix")) + mask = ~((unsigned long)B_ASN1_T61STRING); + else if (!strcmp(p, "utf8only")) + mask = B_ASN1_UTF8STRING; + else if (!strcmp(p, "default")) + mask = 0xFFFFFFFFL; + else + return 0; + ASN1_STRING_set_default_mask(mask); + return 1; +} + +/* + * The following function generates an ASN1_STRING based on limits in a + * table. Frequently the types and length of an ASN1_STRING are restricted by + * a corresponding OID. For example certificates and certificate requests. + */ + +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, + const unsigned char *in, int inlen, + int inform, int nid) +{ + ASN1_STRING_TABLE *tbl; + ASN1_STRING *str = NULL; + unsigned long mask; + int ret; + if (!out) + out = &str; + tbl = ASN1_STRING_TABLE_get(nid); + if (tbl) { + mask = tbl->mask; + if (!(tbl->flags & STABLE_NO_MASK)) + mask &= global_mask; + ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask, + tbl->minsize, tbl->maxsize); + } else + ret = + ASN1_mbstring_copy(out, in, inlen, inform, + DIRSTRING_TYPE & global_mask); + if (ret <= 0) + return NULL; + return *out; +} + +/* + * Now the tables and helper functions for the string table: + */ + +/* size limits: this stuff is taken straight from RFC3280 */ + +#define ub_name 32768 +#define ub_common_name 64 +#define ub_locality_name 128 +#define ub_state_name 128 +#define ub_organization_name 64 +#define ub_organization_unit_name 64 +#define ub_title 64 +#define ub_email_address 128 +#define ub_serial_number 64 + +/* This table must be kept in NID order */ + +static const ASN1_STRING_TABLE tbl_standard[] = { + {NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0}, + {NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, + {NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0}, + {NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0}, + {NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0}, + {NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE, + 0}, + {NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, + STABLE_NO_MASK}, + {NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0}, + {NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0}, + {NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0}, + {NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0}, + {NID_surname, 1, ub_name, DIRSTRING_TYPE, 0}, + {NID_initials, 1, ub_name, DIRSTRING_TYPE, 0}, + {NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING, + STABLE_NO_MASK}, + {NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}, + {NID_name, 1, ub_name, DIRSTRING_TYPE, 0}, + {NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK}, + {NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK}, + {NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK} +}; + +static int sk_table_cmp(const ASN1_STRING_TABLE *const *a, + const ASN1_STRING_TABLE *const *b) +{ + return (*a)->nid - (*b)->nid; +} + +DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table); + +static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b) +{ + return a->nid - b->nid; +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table); + +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid) +{ + int idx; + ASN1_STRING_TABLE *ttmp; + ASN1_STRING_TABLE fnd; + fnd.nid = nid; + ttmp = OBJ_bsearch_table(&fnd, tbl_standard, + sizeof(tbl_standard) / + sizeof(ASN1_STRING_TABLE)); + if (ttmp) + return ttmp; + if (!stable) + return NULL; + idx = sk_ASN1_STRING_TABLE_find(stable, &fnd); + if (idx < 0) + return NULL; + return sk_ASN1_STRING_TABLE_value(stable, idx); +} + +int ASN1_STRING_TABLE_add(int nid, + long minsize, long maxsize, unsigned long mask, + unsigned long flags) +{ + ASN1_STRING_TABLE *tmp; + char new_nid = 0; + flags &= ~STABLE_FLAGS_MALLOC; + if (!stable) + stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp); + if (!stable) { + ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!(tmp = ASN1_STRING_TABLE_get(nid))) { + tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE)); + if (!tmp) { + ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + tmp->flags = flags | STABLE_FLAGS_MALLOC; + tmp->nid = nid; + new_nid = 1; + } else + tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags; + if (minsize != -1) + tmp->minsize = minsize; + if (maxsize != -1) + tmp->maxsize = maxsize; + tmp->mask = mask; + if (new_nid) + sk_ASN1_STRING_TABLE_push(stable, tmp); + return 1; +} + +void ASN1_STRING_TABLE_cleanup(void) +{ + STACK_OF(ASN1_STRING_TABLE) *tmp; + tmp = stable; + if (!tmp) + return; + stable = NULL; + sk_ASN1_STRING_TABLE_pop_free(tmp, st_free); +} + +static void st_free(ASN1_STRING_TABLE *tbl) +{ + if (tbl->flags & STABLE_FLAGS_MALLOC) + OPENSSL_free(tbl); +} + + +IMPLEMENT_STACK_OF(ASN1_STRING_TABLE) + +#ifdef STRING_TABLE_TEST + +main() +{ + ASN1_STRING_TABLE *tmp; + int i, last_nid = -1; + + for (tmp = tbl_standard, i = 0; + i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++) { + if (tmp->nid < last_nid) { + last_nid = 0; + break; + } + last_nid = tmp->nid; + } + + if (last_nid != 0) { + printf("Table order OK\n"); + exit(0); + } + + for (tmp = tbl_standard, i = 0; + i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++) + printf("Index %d, NID %d, Name=%s\n", i, tmp->nid, + OBJ_nid2ln(tmp->nid)); + +} + +#endif diff --git a/libs/openssl/crypto/asn1/a_time.c b/libs/openssl/crypto/asn1/a_time.c new file mode 100644 index 00000000..c81f0de5 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_time.c @@ -0,0 +1,198 @@ +/* crypto/asn1/a_time.c */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/*- + * This is an implementation of the ASN1 Time structure which is: + * Time ::= CHOICE { + * utcTime UTCTime, + * generalTime GeneralizedTime } + * written by Steve Henson. + */ + +#include +#include +#include "cryptlib.h" +#include "o_time.h" +#include + +IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME) + +IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME) + +#if 0 +int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp) +{ +# ifdef CHARSET_EBCDIC + /* KLUDGE! We convert to ascii before writing DER */ + char tmp[24]; + ASN1_STRING tmpstr; + + if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) { + int len; + + tmpstr = *(ASN1_STRING *)a; + len = tmpstr.length; + ebcdic2ascii(tmp, tmpstr.data, + (len >= sizeof tmp) ? sizeof tmp : len); + tmpstr.data = tmp; + a = (ASN1_GENERALIZEDTIME *)&tmpstr; + } +# endif + if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) + return (i2d_ASN1_bytes((ASN1_STRING *)a, pp, + a->type, V_ASN1_UNIVERSAL)); + ASN1err(ASN1_F_I2D_ASN1_TIME, ASN1_R_EXPECTING_A_TIME); + return -1; +} +#endif + +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t) +{ + return ASN1_TIME_adj(s, t, 0, 0); +} + +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, + int offset_day, long offset_sec) +{ + struct tm *ts; + struct tm data; + + ts = OPENSSL_gmtime(&t, &data); + if (ts == NULL) { + ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME); + return NULL; + } + if (offset_day || offset_sec) { + if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) + return NULL; + } + if ((ts->tm_year >= 50) && (ts->tm_year < 150)) + return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); + return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec); +} + +int ASN1_TIME_check(ASN1_TIME *t) +{ + if (t->type == V_ASN1_GENERALIZEDTIME) + return ASN1_GENERALIZEDTIME_check(t); + else if (t->type == V_ASN1_UTCTIME) + return ASN1_UTCTIME_check(t); + return 0; +} + +/* Convert an ASN1_TIME structure to GeneralizedTime */ +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, + ASN1_GENERALIZEDTIME **out) +{ + ASN1_GENERALIZEDTIME *ret; + char *str; + int newlen; + + if (!ASN1_TIME_check(t)) + return NULL; + + if (!out || !*out) { + if (!(ret = ASN1_GENERALIZEDTIME_new())) + return NULL; + if (out) + *out = ret; + } else + ret = *out; + + /* If already GeneralizedTime just copy across */ + if (t->type == V_ASN1_GENERALIZEDTIME) { + if (!ASN1_STRING_set(ret, t->data, t->length)) + return NULL; + return ret; + } + + /* grow the string */ + if (!ASN1_STRING_set(ret, NULL, t->length + 2)) + return NULL; + /* ASN1_STRING_set() allocated 'len + 1' bytes. */ + newlen = t->length + 2 + 1; + str = (char *)ret->data; + /* Work out the century and prepend */ + if (t->data[0] >= '5') + BUF_strlcpy(str, "19", newlen); + else + BUF_strlcpy(str, "20", newlen); + + BUF_strlcat(str, (char *)t->data, newlen); + + return ret; +} + +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str) +{ + ASN1_TIME t; + + t.length = strlen(str); + t.data = (unsigned char *)str; + t.flags = 0; + + t.type = V_ASN1_UTCTIME; + + if (!ASN1_TIME_check(&t)) { + t.type = V_ASN1_GENERALIZEDTIME; + if (!ASN1_TIME_check(&t)) + return 0; + } + + if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t)) + return 0; + + return 1; +} diff --git a/libs/openssl/crypto/asn1/a_type.c b/libs/openssl/crypto/asn1/a_type.c new file mode 100644 index 00000000..bb166e85 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_type.c @@ -0,0 +1,155 @@ +/* crypto/asn1/a_type.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +int ASN1_TYPE_get(ASN1_TYPE *a) +{ + if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL)) + return (a->type); + else + return (0); +} + +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value) +{ + if (a->value.ptr != NULL) { + ASN1_TYPE **tmp_a = &a; + ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL); + } + a->type = type; + if (type == V_ASN1_BOOLEAN) + a->value.boolean = value ? 0xff : 0; + else + a->value.ptr = value; +} + +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value) +{ + if (!value || (type == V_ASN1_BOOLEAN)) { + void *p = (void *)value; + ASN1_TYPE_set(a, type, p); + } else if (type == V_ASN1_OBJECT) { + ASN1_OBJECT *odup; + odup = OBJ_dup(value); + if (!odup) + return 0; + ASN1_TYPE_set(a, type, odup); + } else { + ASN1_STRING *sdup; + sdup = ASN1_STRING_dup(value); + if (!sdup) + return 0; + ASN1_TYPE_set(a, type, sdup); + } + return 1; +} + +IMPLEMENT_STACK_OF(ASN1_TYPE) + +IMPLEMENT_ASN1_SET_OF(ASN1_TYPE) + +/* Returns 0 if they are equal, != 0 otherwise. */ +int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b) +{ + int result = -1; + + if (!a || !b || a->type != b->type) + return -1; + + switch (a->type) { + case V_ASN1_OBJECT: + result = OBJ_cmp(a->value.object, b->value.object); + break; + case V_ASN1_BOOLEAN: + result = a->value.boolean - b->value.boolean; + break; + case V_ASN1_NULL: + result = 0; /* They do not have content. */ + break; + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + case V_ASN1_BIT_STRING: + case V_ASN1_OCTET_STRING: + case V_ASN1_SEQUENCE: + case V_ASN1_SET: + case V_ASN1_NUMERICSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_VIDEOTEXSTRING: + case V_ASN1_IA5STRING: + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + case V_ASN1_GRAPHICSTRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_BMPSTRING: + case V_ASN1_UTF8STRING: + case V_ASN1_OTHER: + default: + result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr, + (ASN1_STRING *)b->value.ptr); + break; + } + + return result; +} diff --git a/libs/openssl/crypto/asn1/a_utctm.c b/libs/openssl/crypto/asn1/a_utctm.c new file mode 100644 index 00000000..179de6d3 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_utctm.c @@ -0,0 +1,330 @@ +/* crypto/asn1/a_utctm.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include "o_time.h" +#include + +#if 0 +int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp) +{ +# ifndef CHARSET_EBCDIC + return (i2d_ASN1_bytes((ASN1_STRING *)a, pp, + V_ASN1_UTCTIME, V_ASN1_UNIVERSAL)); +# else + /* KLUDGE! We convert to ascii before writing DER */ + int len; + char tmp[24]; + ASN1_STRING x = *(ASN1_STRING *)a; + + len = x.length; + ebcdic2ascii(tmp, x.data, (len >= sizeof tmp) ? sizeof tmp : len); + x.data = tmp; + return i2d_ASN1_bytes(&x, pp, V_ASN1_UTCTIME, V_ASN1_UNIVERSAL); +# endif +} + +ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp, + long length) +{ + ASN1_UTCTIME *ret = NULL; + + ret = (ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length, + V_ASN1_UTCTIME, V_ASN1_UNIVERSAL); + if (ret == NULL) { + ASN1err(ASN1_F_D2I_ASN1_UTCTIME, ERR_R_NESTED_ASN1_ERROR); + return (NULL); + } +# ifdef CHARSET_EBCDIC + ascii2ebcdic(ret->data, ret->data, ret->length); +# endif + if (!ASN1_UTCTIME_check(ret)) { + ASN1err(ASN1_F_D2I_ASN1_UTCTIME, ASN1_R_INVALID_TIME_FORMAT); + goto err; + } + + return (ret); + err: + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + M_ASN1_UTCTIME_free(ret); + return (NULL); +} + +#endif + +int ASN1_UTCTIME_check(ASN1_UTCTIME *d) +{ + static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 }; + static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 }; + char *a; + int n, i, l, o; + + if (d->type != V_ASN1_UTCTIME) + return (0); + l = d->length; + a = (char *)d->data; + o = 0; + + if (l < 11) + goto err; + for (i = 0; i < 6; i++) { + if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) { + i++; + break; + } + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = a[o] - '0'; + if (++o > l) + goto err; + + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = (n * 10) + a[o] - '0'; + if (++o > l) + goto err; + + if ((n < min[i]) || (n > max[i])) + goto err; + } + if (a[o] == 'Z') + o++; + else if ((a[o] == '+') || (a[o] == '-')) { + o++; + if (o + 4 > l) + goto err; + for (i = 6; i < 8; i++) { + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = a[o] - '0'; + o++; + if ((a[o] < '0') || (a[o] > '9')) + goto err; + n = (n * 10) + a[o] - '0'; + if ((n < min[i]) || (n > max[i])) + goto err; + o++; + } + } + return (o == l); + err: + return (0); +} + +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str) +{ + ASN1_UTCTIME t; + + t.type = V_ASN1_UTCTIME; + t.length = strlen(str); + t.data = (unsigned char *)str; + if (ASN1_UTCTIME_check(&t)) { + if (s != NULL) { + if (!ASN1_STRING_set((ASN1_STRING *)s, + (unsigned char *)str, t.length)) + return 0; + s->type = V_ASN1_UTCTIME; + } + return (1); + } else + return (0); +} + +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t) +{ + return ASN1_UTCTIME_adj(s, t, 0, 0); +} + +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec) +{ + char *p; + struct tm *ts; + struct tm data; + size_t len = 20; + int free_s = 0; + + if (s == NULL) { + free_s = 1; + s = M_ASN1_UTCTIME_new(); + } + if (s == NULL) + goto err; + + ts = OPENSSL_gmtime(&t, &data); + if (ts == NULL) + goto err; + + if (offset_day || offset_sec) { + if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec)) + goto err; + } + + if ((ts->tm_year < 50) || (ts->tm_year >= 150)) + goto err; + + p = (char *)s->data; + if ((p == NULL) || ((size_t)s->length < len)) { + p = OPENSSL_malloc(len); + if (p == NULL) { + ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE); + goto err; + } + if (s->data != NULL) + OPENSSL_free(s->data); + s->data = (unsigned char *)p; + } + + BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100, + ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min, + ts->tm_sec); + s->length = strlen(p); + s->type = V_ASN1_UTCTIME; +#ifdef CHARSET_EBCDIC_not + ebcdic2ascii(s->data, s->data, s->length); +#endif + return (s); + err: + if (free_s && s) + M_ASN1_UTCTIME_free(s); + return NULL; +} + +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t) +{ + struct tm *tm; + struct tm data; + int offset; + int year; + +#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0') + + if (s->data[12] == 'Z') + offset = 0; + else { + offset = g2(s->data + 13) * 60 + g2(s->data + 15); + if (s->data[12] == '-') + offset = -offset; + } + + t -= offset * 60; /* FIXME: may overflow in extreme cases */ + + tm = OPENSSL_gmtime(&t, &data); + /* + * NB: -1, 0, 1 already valid return values so use -2 to indicate error. + */ + if (tm == NULL) + return -2; + +#define return_cmp(a,b) if ((a)<(b)) return -1; else if ((a)>(b)) return 1 + year = g2(s->data); + if (year < 50) + year += 100; + return_cmp(year, tm->tm_year); + return_cmp(g2(s->data + 2) - 1, tm->tm_mon); + return_cmp(g2(s->data + 4), tm->tm_mday); + return_cmp(g2(s->data + 6), tm->tm_hour); + return_cmp(g2(s->data + 8), tm->tm_min); + return_cmp(g2(s->data + 10), tm->tm_sec); +#undef g2 +#undef return_cmp + + return 0; +} + +#if 0 +time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s) +{ + struct tm tm; + int offset; + + memset(&tm, '\0', sizeof tm); + +# define g2(p) (((p)[0]-'0')*10+(p)[1]-'0') + tm.tm_year = g2(s->data); + if (tm.tm_year < 50) + tm.tm_year += 100; + tm.tm_mon = g2(s->data + 2) - 1; + tm.tm_mday = g2(s->data + 4); + tm.tm_hour = g2(s->data + 6); + tm.tm_min = g2(s->data + 8); + tm.tm_sec = g2(s->data + 10); + if (s->data[12] == 'Z') + offset = 0; + else { + offset = g2(s->data + 13) * 60 + g2(s->data + 15); + if (s->data[12] == '-') + offset = -offset; + } +# undef g2 + + /* + * FIXME: mktime assumes the current timezone + * instead of UTC, and unless we rewrite OpenSSL + * in Lisp we cannot locally change the timezone + * without possibly interfering with other parts + * of the program. timegm, which uses UTC, is + * non-standard. + * Also time_t is inappropriate for general + * UTC times because it may a 32 bit type. + */ + return mktime(&tm) - offset * 60; +} +#endif diff --git a/libs/openssl/crypto/asn1/a_utf8.c b/libs/openssl/crypto/asn1/a_utf8.c new file mode 100644 index 00000000..23dc2e82 --- /dev/null +++ b/libs/openssl/crypto/asn1/a_utf8.c @@ -0,0 +1,237 @@ +/* crypto/asn1/a_utf8.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include + +/* UTF8 utilities */ + +/*- + * This parses a UTF8 string one character at a time. It is passed a pointer + * to the string and the length of the string. It sets 'value' to the value of + * the current character. It returns the number of characters read or a + * negative error code: + * -1 = string too short + * -2 = illegal character + * -3 = subsequent characters not of the form 10xxxxxx + * -4 = character encoded incorrectly (not minimal length). + */ + +int UTF8_getc(const unsigned char *str, int len, unsigned long *val) +{ + const unsigned char *p; + unsigned long value; + int ret; + if (len <= 0) + return 0; + p = str; + + /* Check syntax and work out the encoded value (if correct) */ + if ((*p & 0x80) == 0) { + value = *p++ & 0x7f; + ret = 1; + } else if ((*p & 0xe0) == 0xc0) { + if (len < 2) + return -1; + if ((p[1] & 0xc0) != 0x80) + return -3; + value = (*p++ & 0x1f) << 6; + value |= *p++ & 0x3f; + if (value < 0x80) + return -4; + ret = 2; + } else if ((*p & 0xf0) == 0xe0) { + if (len < 3) + return -1; + if (((p[1] & 0xc0) != 0x80) + || ((p[2] & 0xc0) != 0x80)) + return -3; + value = (*p++ & 0xf) << 12; + value |= (*p++ & 0x3f) << 6; + value |= *p++ & 0x3f; + if (value < 0x800) + return -4; + ret = 3; + } else if ((*p & 0xf8) == 0xf0) { + if (len < 4) + return -1; + if (((p[1] & 0xc0) != 0x80) + || ((p[2] & 0xc0) != 0x80) + || ((p[3] & 0xc0) != 0x80)) + return -3; + value = ((unsigned long)(*p++ & 0x7)) << 18; + value |= (*p++ & 0x3f) << 12; + value |= (*p++ & 0x3f) << 6; + value |= *p++ & 0x3f; + if (value < 0x10000) + return -4; + ret = 4; + } else if ((*p & 0xfc) == 0xf8) { + if (len < 5) + return -1; + if (((p[1] & 0xc0) != 0x80) + || ((p[2] & 0xc0) != 0x80) + || ((p[3] & 0xc0) != 0x80) + || ((p[4] & 0xc0) != 0x80)) + return -3; + value = ((unsigned long)(*p++ & 0x3)) << 24; + value |= ((unsigned long)(*p++ & 0x3f)) << 18; + value |= ((unsigned long)(*p++ & 0x3f)) << 12; + value |= (*p++ & 0x3f) << 6; + value |= *p++ & 0x3f; + if (value < 0x200000) + return -4; + ret = 5; + } else if ((*p & 0xfe) == 0xfc) { + if (len < 6) + return -1; + if (((p[1] & 0xc0) != 0x80) + || ((p[2] & 0xc0) != 0x80) + || ((p[3] & 0xc0) != 0x80) + || ((p[4] & 0xc0) != 0x80) + || ((p[5] & 0xc0) != 0x80)) + return -3; + value = ((unsigned long)(*p++ & 0x1)) << 30; + value |= ((unsigned long)(*p++ & 0x3f)) << 24; + value |= ((unsigned long)(*p++ & 0x3f)) << 18; + value |= ((unsigned long)(*p++ & 0x3f)) << 12; + value |= (*p++ & 0x3f) << 6; + value |= *p++ & 0x3f; + if (value < 0x4000000) + return -4; + ret = 6; + } else + return -2; + *val = value; + return ret; +} + +/* + * This takes a character 'value' and writes the UTF8 encoded value in 'str' + * where 'str' is a buffer containing 'len' characters. Returns the number of + * characters written or -1 if 'len' is too small. 'str' can be set to NULL + * in which case it just returns the number of characters. It will need at + * most 6 characters. + */ + +int UTF8_putc(unsigned char *str, int len, unsigned long value) +{ + if (!str) + len = 6; /* Maximum we will need */ + else if (len <= 0) + return -1; + if (value < 0x80) { + if (str) + *str = (unsigned char)value; + return 1; + } + if (value < 0x800) { + if (len < 2) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 2; + } + if (value < 0x10000) { + if (len < 3) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0); + *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 3; + } + if (value < 0x200000) { + if (len < 4) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0); + *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 4; + } + if (value < 0x4000000) { + if (len < 5) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8); + *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 5; + } + if (len < 6) + return -1; + if (str) { + *str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc); + *str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80); + *str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80); + *str = (unsigned char)((value & 0x3f) | 0x80); + } + return 6; +} diff --git a/libs/openssl/crypto/asn1/a_verify.c b/libs/openssl/crypto/asn1/a_verify.c new file mode 100644 index 00000000..3ffd934c --- /dev/null +++ b/libs/openssl/crypto/asn1/a_verify.c @@ -0,0 +1,231 @@ +/* crypto/asn1/a_verify.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include "cryptlib.h" +#include "asn1_locl.h" + +#ifndef NO_SYS_TYPES_H +# include +#endif + +#include +#include +#include +#include +#include + +#ifndef NO_ASN1_OLD + +int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature, + char *data, EVP_PKEY *pkey) +{ + EVP_MD_CTX ctx; + const EVP_MD *type; + unsigned char *p, *buf_in = NULL; + int ret = -1, i, inl; + + EVP_MD_CTX_init(&ctx); + i = OBJ_obj2nid(a->algorithm); + type = EVP_get_digestbyname(OBJ_nid2sn(i)); + if (type == NULL) { + ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + goto err; + } + + if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { + ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); + goto err; + } + + inl = i2d(data, NULL); + buf_in = OPENSSL_malloc((unsigned int)inl); + if (buf_in == NULL) { + ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + p = buf_in; + + i2d(data, &p); + if (!EVP_VerifyInit_ex(&ctx, type, NULL) + || !EVP_VerifyUpdate(&ctx, (unsigned char *)buf_in, inl)) { + ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB); + ret = 0; + goto err; + } + + OPENSSL_cleanse(buf_in, (unsigned int)inl); + OPENSSL_free(buf_in); + + if (EVP_VerifyFinal(&ctx, (unsigned char *)signature->data, + (unsigned int)signature->length, pkey) <= 0) { + ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB); + ret = 0; + goto err; + } + /* + * we don't need to zero the 'ctx' because we just checked public + * information + */ + /* memset(&ctx,0,sizeof(ctx)); */ + ret = 1; + err: + EVP_MD_CTX_cleanup(&ctx); + return (ret); +} + +#endif + +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, + ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) +{ + EVP_MD_CTX ctx; + unsigned char *buf_in = NULL; + int ret = -1, inl; + + int mdnid, pknid; + + if (!pkey) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT); + return -1; + } + + EVP_MD_CTX_init(&ctx); + + /* Convert signature OID into digest and public key OIDs */ + if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + goto err; + } + if (mdnid == NID_undef) { + if (!pkey->ameth || !pkey->ameth->item_verify) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, + ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + goto err; + } + ret = pkey->ameth->item_verify(&ctx, it, asn, a, signature, pkey); + /* + * Return value of 2 means carry on, anything else means we exit + * straight away: either a fatal error of the underlying verification + * routine handles all verification. + */ + if (ret != 2) + goto err; + ret = -1; + } else { + const EVP_MD *type; + type = EVP_get_digestbynid(mdnid); + if (type == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, + ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + goto err; + } + + /* Check public key OID matches public key type */ + if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE); + goto err; + } + + if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); + ret = 0; + goto err; + } + + } + + inl = ASN1_item_i2d(asn, &buf_in, it); + + if (buf_in == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); + ret = 0; + goto err; + } + + OPENSSL_cleanse(buf_in, (unsigned int)inl); + OPENSSL_free(buf_in); + + if (EVP_DigestVerifyFinal(&ctx, signature->data, + (size_t)signature->length) <= 0) { + ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB); + ret = 0; + goto err; + } + /* + * we don't need to zero the 'ctx' because we just checked public + * information + */ + /* memset(&ctx,0,sizeof(ctx)); */ + ret = 1; + err: + EVP_MD_CTX_cleanup(&ctx); + return (ret); +} diff --git a/libs/openssl/crypto/asn1/ameth_lib.c b/libs/openssl/crypto/asn1/ameth_lib.c new file mode 100644 index 00000000..45f3f405 --- /dev/null +++ b/libs/openssl/crypto/asn1/ameth_lib.c @@ -0,0 +1,462 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include "asn1_locl.h" + +extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[]; +extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[]; +extern const EVP_PKEY_ASN1_METHOD dh_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD eckey_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth; + +/* Keep this sorted in type order !! */ +static const EVP_PKEY_ASN1_METHOD *standard_methods[] = { +#ifndef OPENSSL_NO_RSA + &rsa_asn1_meths[0], + &rsa_asn1_meths[1], +#endif +#ifndef OPENSSL_NO_DH + &dh_asn1_meth, +#endif +#ifndef OPENSSL_NO_DSA + &dsa_asn1_meths[0], + &dsa_asn1_meths[1], + &dsa_asn1_meths[2], + &dsa_asn1_meths[3], + &dsa_asn1_meths[4], +#endif +#ifndef OPENSSL_NO_EC + &eckey_asn1_meth, +#endif + &hmac_asn1_meth, + &cmac_asn1_meth +}; + +typedef int sk_cmp_fn_type(const char *const *a, const char *const *b); +DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD) +static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL; + +#ifdef TEST +void main() +{ + int i; + for (i = 0; + i < sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); i++) + fprintf(stderr, "Number %d id=%d (%s)\n", i, + standard_methods[i]->pkey_id, + OBJ_nid2sn(standard_methods[i]->pkey_id)); +} +#endif + +DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *, + const EVP_PKEY_ASN1_METHOD *, ameth); + +static int ameth_cmp(const EVP_PKEY_ASN1_METHOD *const *a, + const EVP_PKEY_ASN1_METHOD *const *b) +{ + return ((*a)->pkey_id - (*b)->pkey_id); +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *, + const EVP_PKEY_ASN1_METHOD *, ameth); + +int EVP_PKEY_asn1_get_count(void) +{ + int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); + if (app_methods) + num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods); + return num; +} + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx) +{ + int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); + if (idx < 0) + return NULL; + if (idx < num) + return standard_methods[idx]; + idx -= num; + return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); +} + +static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type) +{ + EVP_PKEY_ASN1_METHOD tmp; + const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret; + tmp.pkey_id = type; + if (app_methods) { + int idx; + idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp); + if (idx >= 0) + return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx); + } + ret = OBJ_bsearch_ameth(&t, standard_methods, sizeof(standard_methods) + / sizeof(EVP_PKEY_ASN1_METHOD *)); + if (!ret || !*ret) + return NULL; + return *ret; +} + +/* + * Find an implementation of an ASN1 algorithm. If 'pe' is not NULL also + * search through engines and set *pe to a functional reference to the engine + * implementing 'type' or NULL if no engine implements it. + */ + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type) +{ + const EVP_PKEY_ASN1_METHOD *t; + + for (;;) { + t = pkey_asn1_find(type); + if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS)) + break; + type = t->pkey_base_id; + } + if (pe) { +#ifndef OPENSSL_NO_ENGINE + ENGINE *e; + /* type will contain the final unaliased type */ + e = ENGINE_get_pkey_asn1_meth_engine(type); + if (e) { + *pe = e; + return ENGINE_get_pkey_asn1_meth(e, type); + } +#endif + *pe = NULL; + } + return t; +} + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len) +{ + int i; + const EVP_PKEY_ASN1_METHOD *ameth; + if (len == -1) + len = strlen(str); + if (pe) { +#ifndef OPENSSL_NO_ENGINE + ENGINE *e; + ameth = ENGINE_pkey_asn1_find_str(&e, str, len); + if (ameth) { + /* + * Convert structural into functional reference + */ + if (!ENGINE_init(e)) + ameth = NULL; + ENGINE_free(e); + *pe = e; + return ameth; + } +#endif + *pe = NULL; + } + for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) { + ameth = EVP_PKEY_asn1_get0(i); + if (ameth->pkey_flags & ASN1_PKEY_ALIAS) + continue; + if (((int)strlen(ameth->pem_str) == len) && + !strncasecmp(ameth->pem_str, str, len)) + return ameth; + } + return NULL; +} + +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth) +{ + if (app_methods == NULL) { + app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp); + if (!app_methods) + return 0; + } + if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth)) + return 0; + sk_EVP_PKEY_ASN1_METHOD_sort(app_methods); + return 1; +} + +int EVP_PKEY_asn1_add_alias(int to, int from) +{ + EVP_PKEY_ASN1_METHOD *ameth; + ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL); + if (!ameth) + return 0; + ameth->pkey_base_id = to; + if (!EVP_PKEY_asn1_add0(ameth)) { + EVP_PKEY_asn1_free(ameth); + return 0; + } + return 1; +} + +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, + int *ppkey_flags, const char **pinfo, + const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth) +{ + if (!ameth) + return 0; + if (ppkey_id) + *ppkey_id = ameth->pkey_id; + if (ppkey_base_id) + *ppkey_base_id = ameth->pkey_base_id; + if (ppkey_flags) + *ppkey_flags = ameth->pkey_flags; + if (pinfo) + *pinfo = ameth->info; + if (ppem_str) + *ppem_str = ameth->pem_str; + return 1; +} + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey) +{ + return pkey->ameth; +} + +EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, + const char *pem_str, const char *info) +{ + EVP_PKEY_ASN1_METHOD *ameth; + ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD)); + if (!ameth) + return NULL; + + memset(ameth, 0, sizeof(EVP_PKEY_ASN1_METHOD)); + + ameth->pkey_id = id; + ameth->pkey_base_id = id; + ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC; + + if (info) { + ameth->info = BUF_strdup(info); + if (!ameth->info) + goto err; + } else + ameth->info = NULL; + + if (pem_str) { + ameth->pem_str = BUF_strdup(pem_str); + if (!ameth->pem_str) + goto err; + } else + ameth->pem_str = NULL; + + ameth->pub_decode = 0; + ameth->pub_encode = 0; + ameth->pub_cmp = 0; + ameth->pub_print = 0; + + ameth->priv_decode = 0; + ameth->priv_encode = 0; + ameth->priv_print = 0; + + ameth->old_priv_encode = 0; + ameth->old_priv_decode = 0; + + ameth->item_verify = 0; + ameth->item_sign = 0; + + ameth->pkey_size = 0; + ameth->pkey_bits = 0; + + ameth->param_decode = 0; + ameth->param_encode = 0; + ameth->param_missing = 0; + ameth->param_copy = 0; + ameth->param_cmp = 0; + ameth->param_print = 0; + + ameth->pkey_free = 0; + ameth->pkey_ctrl = 0; + + return ameth; + + err: + + EVP_PKEY_asn1_free(ameth); + return NULL; + +} + +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, + const EVP_PKEY_ASN1_METHOD *src) +{ + + dst->pub_decode = src->pub_decode; + dst->pub_encode = src->pub_encode; + dst->pub_cmp = src->pub_cmp; + dst->pub_print = src->pub_print; + + dst->priv_decode = src->priv_decode; + dst->priv_encode = src->priv_encode; + dst->priv_print = src->priv_print; + + dst->old_priv_encode = src->old_priv_encode; + dst->old_priv_decode = src->old_priv_decode; + + dst->pkey_size = src->pkey_size; + dst->pkey_bits = src->pkey_bits; + + dst->param_decode = src->param_decode; + dst->param_encode = src->param_encode; + dst->param_missing = src->param_missing; + dst->param_copy = src->param_copy; + dst->param_cmp = src->param_cmp; + dst->param_print = src->param_print; + + dst->pkey_free = src->pkey_free; + dst->pkey_ctrl = src->pkey_ctrl; + + dst->item_sign = src->item_sign; + dst->item_verify = src->item_verify; + +} + +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth) +{ + if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) { + if (ameth->pem_str) + OPENSSL_free(ameth->pem_str); + if (ameth->info) + OPENSSL_free(ameth->info); + OPENSSL_free(ameth); + } +} + +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, + int (*pub_decode) (EVP_PKEY *pk, + X509_PUBKEY *pub), + int (*pub_encode) (X509_PUBKEY *pub, + const EVP_PKEY *pk), + int (*pub_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*pub_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx), + int (*pkey_size) (const EVP_PKEY *pk), + int (*pkey_bits) (const EVP_PKEY *pk)) +{ + ameth->pub_decode = pub_decode; + ameth->pub_encode = pub_encode; + ameth->pub_cmp = pub_cmp; + ameth->pub_print = pub_print; + ameth->pkey_size = pkey_size; + ameth->pkey_bits = pkey_bits; +} + +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, + int (*priv_decode) (EVP_PKEY *pk, + PKCS8_PRIV_KEY_INFO + *p8inf), + int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, + const EVP_PKEY *pk), + int (*priv_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)) +{ + ameth->priv_decode = priv_decode; + ameth->priv_encode = priv_encode; + ameth->priv_print = priv_print; +} + +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, + int (*param_decode) (EVP_PKEY *pkey, + const unsigned char **pder, + int derlen), + int (*param_encode) (const EVP_PKEY *pkey, + unsigned char **pder), + int (*param_missing) (const EVP_PKEY *pk), + int (*param_copy) (EVP_PKEY *to, + const EVP_PKEY *from), + int (*param_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*param_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx)) +{ + ameth->param_decode = param_decode; + ameth->param_encode = param_encode; + ameth->param_missing = param_missing; + ameth->param_copy = param_copy; + ameth->param_cmp = param_cmp; + ameth->param_print = param_print; +} + +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, + void (*pkey_free) (EVP_PKEY *pkey)) +{ + ameth->pkey_free = pkey_free; +} + +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_ctrl) (EVP_PKEY *pkey, int op, + long arg1, void *arg2)) +{ + ameth->pkey_ctrl = pkey_ctrl; +} diff --git a/libs/openssl/crypto/asn1/asn1.h b/libs/openssl/crypto/asn1/asn1.h new file mode 100644 index 00000000..39b7833f --- /dev/null +++ b/libs/openssl/crypto/asn1/asn1.h @@ -0,0 +1,1417 @@ +/* crypto/asn1/asn1.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ASN1_H +# define HEADER_ASN1_H + +# include +# include +# ifndef OPENSSL_NO_BIO +# include +# endif +# include +# include + +# include + +# include +# ifndef OPENSSL_NO_DEPRECATED +# include +# endif + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define V_ASN1_UNIVERSAL 0x00 +# define V_ASN1_APPLICATION 0x40 +# define V_ASN1_CONTEXT_SPECIFIC 0x80 +# define V_ASN1_PRIVATE 0xc0 + +# define V_ASN1_CONSTRUCTED 0x20 +# define V_ASN1_PRIMITIVE_TAG 0x1f +# define V_ASN1_PRIMATIVE_TAG 0x1f + +# define V_ASN1_APP_CHOOSE -2/* let the recipient choose */ +# define V_ASN1_OTHER -3/* used in ASN1_TYPE */ +# define V_ASN1_ANY -4/* used in ASN1 template code */ + +# define V_ASN1_NEG 0x100/* negative flag */ + +# define V_ASN1_UNDEF -1 +# define V_ASN1_EOC 0 +# define V_ASN1_BOOLEAN 1 /**/ +# define V_ASN1_INTEGER 2 +# define V_ASN1_NEG_INTEGER (2 | V_ASN1_NEG) +# define V_ASN1_BIT_STRING 3 +# define V_ASN1_OCTET_STRING 4 +# define V_ASN1_NULL 5 +# define V_ASN1_OBJECT 6 +# define V_ASN1_OBJECT_DESCRIPTOR 7 +# define V_ASN1_EXTERNAL 8 +# define V_ASN1_REAL 9 +# define V_ASN1_ENUMERATED 10 +# define V_ASN1_NEG_ENUMERATED (10 | V_ASN1_NEG) +# define V_ASN1_UTF8STRING 12 +# define V_ASN1_SEQUENCE 16 +# define V_ASN1_SET 17 +# define V_ASN1_NUMERICSTRING 18 /**/ +# define V_ASN1_PRINTABLESTRING 19 +# define V_ASN1_T61STRING 20 +# define V_ASN1_TELETEXSTRING 20/* alias */ +# define V_ASN1_VIDEOTEXSTRING 21 /**/ +# define V_ASN1_IA5STRING 22 +# define V_ASN1_UTCTIME 23 +# define V_ASN1_GENERALIZEDTIME 24 /**/ +# define V_ASN1_GRAPHICSTRING 25 /**/ +# define V_ASN1_ISO64STRING 26 /**/ +# define V_ASN1_VISIBLESTRING 26/* alias */ +# define V_ASN1_GENERALSTRING 27 /**/ +# define V_ASN1_UNIVERSALSTRING 28 /**/ +# define V_ASN1_BMPSTRING 30 +/* For use with d2i_ASN1_type_bytes() */ +# define B_ASN1_NUMERICSTRING 0x0001 +# define B_ASN1_PRINTABLESTRING 0x0002 +# define B_ASN1_T61STRING 0x0004 +# define B_ASN1_TELETEXSTRING 0x0004 +# define B_ASN1_VIDEOTEXSTRING 0x0008 +# define B_ASN1_IA5STRING 0x0010 +# define B_ASN1_GRAPHICSTRING 0x0020 +# define B_ASN1_ISO64STRING 0x0040 +# define B_ASN1_VISIBLESTRING 0x0040 +# define B_ASN1_GENERALSTRING 0x0080 +# define B_ASN1_UNIVERSALSTRING 0x0100 +# define B_ASN1_OCTET_STRING 0x0200 +# define B_ASN1_BIT_STRING 0x0400 +# define B_ASN1_BMPSTRING 0x0800 +# define B_ASN1_UNKNOWN 0x1000 +# define B_ASN1_UTF8STRING 0x2000 +# define B_ASN1_UTCTIME 0x4000 +# define B_ASN1_GENERALIZEDTIME 0x8000 +# define B_ASN1_SEQUENCE 0x10000 +/* For use with ASN1_mbstring_copy() */ +# define MBSTRING_FLAG 0x1000 +# define MBSTRING_UTF8 (MBSTRING_FLAG) +# define MBSTRING_ASC (MBSTRING_FLAG|1) +# define MBSTRING_BMP (MBSTRING_FLAG|2) +# define MBSTRING_UNIV (MBSTRING_FLAG|4) +# define SMIME_OLDMIME 0x400 +# define SMIME_CRLFEOL 0x800 +# define SMIME_STREAM 0x1000 + struct X509_algor_st; +DECLARE_STACK_OF(X509_ALGOR) + +# define DECLARE_ASN1_SET_OF(type)/* filled in by mkstack.pl */ +# define IMPLEMENT_ASN1_SET_OF(type)/* nothing, no longer needed */ + +/* + * We MUST make sure that, except for constness, asn1_ctx_st and + * asn1_const_ctx are exactly the same. Fortunately, as soon as the old ASN1 + * parsing macros are gone, we can throw this away as well... + */ +typedef struct asn1_ctx_st { + unsigned char *p; /* work char pointer */ + int eos; /* end of sequence read for indefinite + * encoding */ + int error; /* error code to use when returning an error */ + int inf; /* constructed if 0x20, indefinite is 0x21 */ + int tag; /* tag from last 'get object' */ + int xclass; /* class from last 'get object' */ + long slen; /* length of last 'get object' */ + unsigned char *max; /* largest value of p allowed */ + unsigned char *q; /* temporary variable */ + unsigned char **pp; /* variable */ + int line; /* used in error processing */ +} ASN1_CTX; + +typedef struct asn1_const_ctx_st { + const unsigned char *p; /* work char pointer */ + int eos; /* end of sequence read for indefinite + * encoding */ + int error; /* error code to use when returning an error */ + int inf; /* constructed if 0x20, indefinite is 0x21 */ + int tag; /* tag from last 'get object' */ + int xclass; /* class from last 'get object' */ + long slen; /* length of last 'get object' */ + const unsigned char *max; /* largest value of p allowed */ + const unsigned char *q; /* temporary variable */ + const unsigned char **pp; /* variable */ + int line; /* used in error processing */ +} ASN1_const_CTX; + +/* + * These are used internally in the ASN1_OBJECT to keep track of whether the + * names and data need to be free()ed + */ +# define ASN1_OBJECT_FLAG_DYNAMIC 0x01/* internal use */ +# define ASN1_OBJECT_FLAG_CRITICAL 0x02/* critical x509v3 object id */ +# define ASN1_OBJECT_FLAG_DYNAMIC_STRINGS 0x04/* internal use */ +# define ASN1_OBJECT_FLAG_DYNAMIC_DATA 0x08/* internal use */ +typedef struct asn1_object_st { + const char *sn, *ln; + int nid; + int length; + const unsigned char *data; /* data remains const after init */ + int flags; /* Should we free this one */ +} ASN1_OBJECT; + +# define ASN1_STRING_FLAG_BITS_LEFT 0x08/* Set if 0x07 has bits left value */ +/* + * This indicates that the ASN1_STRING is not a real value but just a place + * holder for the location where indefinite length constructed data should be + * inserted in the memory buffer + */ +# define ASN1_STRING_FLAG_NDEF 0x010 + +/* + * This flag is used by the CMS code to indicate that a string is not + * complete and is a place holder for content when it had all been accessed. + * The flag will be reset when content has been written to it. + */ + +# define ASN1_STRING_FLAG_CONT 0x020 +/* + * This flag is used by ASN1 code to indicate an ASN1_STRING is an MSTRING + * type. + */ +# define ASN1_STRING_FLAG_MSTRING 0x040 +/* This is the base type that holds just about everything :-) */ +struct asn1_string_st { + int length; + int type; + unsigned char *data; + /* + * The value of the following field depends on the type being held. It + * is mostly being used for BIT_STRING so if the input data has a + * non-zero 'unused bits' value, it will be handled correctly + */ + long flags; +}; + +/* + * ASN1_ENCODING structure: this is used to save the received encoding of an + * ASN1 type. This is useful to get round problems with invalid encodings + * which can break signatures. + */ + +typedef struct ASN1_ENCODING_st { + unsigned char *enc; /* DER encoding */ + long len; /* Length of encoding */ + int modified; /* set to 1 if 'enc' is invalid */ +} ASN1_ENCODING; + +/* Used with ASN1 LONG type: if a long is set to this it is omitted */ +# define ASN1_LONG_UNDEF 0x7fffffffL + +# define STABLE_FLAGS_MALLOC 0x01 +# define STABLE_NO_MASK 0x02 +# define DIRSTRING_TYPE \ + (B_ASN1_PRINTABLESTRING|B_ASN1_T61STRING|B_ASN1_BMPSTRING|B_ASN1_UTF8STRING) +# define PKCS9STRING_TYPE (DIRSTRING_TYPE|B_ASN1_IA5STRING) + +typedef struct asn1_string_table_st { + int nid; + long minsize; + long maxsize; + unsigned long mask; + unsigned long flags; +} ASN1_STRING_TABLE; + +DECLARE_STACK_OF(ASN1_STRING_TABLE) + +/* size limits: this stuff is taken straight from RFC2459 */ + +# define ub_name 32768 +# define ub_common_name 64 +# define ub_locality_name 128 +# define ub_state_name 128 +# define ub_organization_name 64 +# define ub_organization_unit_name 64 +# define ub_title 64 +# define ub_email_address 128 + +/* + * Declarations for template structures: for full definitions see asn1t.h + */ +typedef struct ASN1_TEMPLATE_st ASN1_TEMPLATE; +typedef struct ASN1_TLC_st ASN1_TLC; +/* This is just an opaque pointer */ +typedef struct ASN1_VALUE_st ASN1_VALUE; + +/* Declare ASN1 functions: the implement macro in in asn1t.h */ + +# define DECLARE_ASN1_FUNCTIONS(type) DECLARE_ASN1_FUNCTIONS_name(type, type) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS(type) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, type) + +# define DECLARE_ASN1_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) + +# define DECLARE_ASN1_FUNCTIONS_fname(type, itname, name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(itname) + +# define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ + type *d2i_##name(type **a, const unsigned char **in, long len); \ + int i2d_##name(const type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(name) + +# define DECLARE_ASN1_NDEF_FUNCTION(name) \ + int i2d_##name##_NDEF(name *a, unsigned char **out); + +# define DECLARE_ASN1_FUNCTIONS_const(name) \ + DECLARE_ASN1_ALLOC_FUNCTIONS(name) \ + DECLARE_ASN1_ENCODE_FUNCTIONS_const(name, name) + +# define DECLARE_ASN1_ALLOC_FUNCTIONS_name(type, name) \ + type *name##_new(void); \ + void name##_free(type *a); + +# define DECLARE_ASN1_PRINT_FUNCTION(stname) \ + DECLARE_ASN1_PRINT_FUNCTION_fname(stname, stname) + +# define DECLARE_ASN1_PRINT_FUNCTION_fname(stname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx); + +# define D2I_OF(type) type *(*)(type **,const unsigned char **,long) +# define I2D_OF(type) int (*)(type *,unsigned char **) +# define I2D_OF_const(type) int (*)(const type *,unsigned char **) + +# define CHECKED_D2I_OF(type, d2i) \ + ((d2i_of_void*) (1 ? d2i : ((D2I_OF(type))0))) +# define CHECKED_I2D_OF(type, i2d) \ + ((i2d_of_void*) (1 ? i2d : ((I2D_OF(type))0))) +# define CHECKED_NEW_OF(type, xnew) \ + ((void *(*)(void)) (1 ? xnew : ((type *(*)(void))0))) +# define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +# define CHECKED_PPTR_OF(type, p) \ + ((void**) (1 ? p : (type**)0)) + +# define TYPEDEF_D2I_OF(type) typedef type *d2i_of_##type(type **,const unsigned char **,long) +# define TYPEDEF_I2D_OF(type) typedef int i2d_of_##type(type *,unsigned char **) +# define TYPEDEF_D2I2D_OF(type) TYPEDEF_D2I_OF(type); TYPEDEF_I2D_OF(type) + +TYPEDEF_D2I2D_OF(void); + +/*- + * The following macros and typedefs allow an ASN1_ITEM + * to be embedded in a structure and referenced. Since + * the ASN1_ITEM pointers need to be globally accessible + * (possibly from shared libraries) they may exist in + * different forms. On platforms that support it the + * ASN1_ITEM structure itself will be globally exported. + * Other platforms will export a function that returns + * an ASN1_ITEM pointer. + * + * To handle both cases transparently the macros below + * should be used instead of hard coding an ASN1_ITEM + * pointer in a structure. + * + * The structure will look like this: + * + * typedef struct SOMETHING_st { + * ... + * ASN1_ITEM_EXP *iptr; + * ... + * } SOMETHING; + * + * It would be initialised as e.g.: + * + * SOMETHING somevar = {...,ASN1_ITEM_ref(X509),...}; + * + * and the actual pointer extracted with: + * + * const ASN1_ITEM *it = ASN1_ITEM_ptr(somevar.iptr); + * + * Finally an ASN1_ITEM pointer can be extracted from an + * appropriate reference with: ASN1_ITEM_rptr(X509). This + * would be used when a function takes an ASN1_ITEM * argument. + * + */ + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM ASN1_ITEM_EXP; + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +# define ASN1_ITEM_ptr(iptr) (iptr) + +/* Macro to include ASN1_ITEM pointer from base type */ +# define ASN1_ITEM_ref(iptr) (&(iptr##_it)) + +# define ASN1_ITEM_rptr(ref) (&(ref##_it)) + +# define DECLARE_ASN1_ITEM(name) \ + OPENSSL_EXTERN const ASN1_ITEM name##_it; + +# else + +/* + * Platforms that can't easily handle shared global variables are declared as + * functions returning ASN1_ITEM pointers. + */ + +/* ASN1_ITEM pointer exported type */ +typedef const ASN1_ITEM *ASN1_ITEM_EXP (void); + +/* Macro to obtain ASN1_ITEM pointer from exported type */ +# define ASN1_ITEM_ptr(iptr) (iptr()) + +/* Macro to include ASN1_ITEM pointer from base type */ +# define ASN1_ITEM_ref(iptr) (iptr##_it) + +# define ASN1_ITEM_rptr(ref) (ref##_it()) + +# define DECLARE_ASN1_ITEM(name) \ + const ASN1_ITEM * name##_it(void); + +# endif + +/* Parameters used by ASN1_STRING_print_ex() */ + +/* + * These determine which characters to escape: RFC2253 special characters, + * control characters and MSB set characters + */ + +# define ASN1_STRFLGS_ESC_2253 1 +# define ASN1_STRFLGS_ESC_CTRL 2 +# define ASN1_STRFLGS_ESC_MSB 4 + +/* + * This flag determines how we do escaping: normally RC2253 backslash only, + * set this to use backslash and quote. + */ + +# define ASN1_STRFLGS_ESC_QUOTE 8 + +/* These three flags are internal use only. */ + +/* Character is a valid PrintableString character */ +# define CHARTYPE_PRINTABLESTRING 0x10 +/* Character needs escaping if it is the first character */ +# define CHARTYPE_FIRST_ESC_2253 0x20 +/* Character needs escaping if it is the last character */ +# define CHARTYPE_LAST_ESC_2253 0x40 + +/* + * NB the internal flags are safely reused below by flags handled at the top + * level. + */ + +/* + * If this is set we convert all character strings to UTF8 first + */ + +# define ASN1_STRFLGS_UTF8_CONVERT 0x10 + +/* + * If this is set we don't attempt to interpret content: just assume all + * strings are 1 byte per character. This will produce some pretty odd + * looking output! + */ + +# define ASN1_STRFLGS_IGNORE_TYPE 0x20 + +/* If this is set we include the string type in the output */ +# define ASN1_STRFLGS_SHOW_TYPE 0x40 + +/* + * This determines which strings to display and which to 'dump' (hex dump of + * content octets or DER encoding). We can only dump non character strings or + * everything. If we don't dump 'unknown' they are interpreted as character + * strings with 1 octet per character and are subject to the usual escaping + * options. + */ + +# define ASN1_STRFLGS_DUMP_ALL 0x80 +# define ASN1_STRFLGS_DUMP_UNKNOWN 0x100 + +/* + * These determine what 'dumping' does, we can dump the content octets or the + * DER encoding: both use the RFC2253 #XXXXX notation. + */ + +# define ASN1_STRFLGS_DUMP_DER 0x200 + +/* + * All the string flags consistent with RFC2253, escaping control characters + * isn't essential in RFC2253 but it is advisable anyway. + */ + +# define ASN1_STRFLGS_RFC2253 (ASN1_STRFLGS_ESC_2253 | \ + ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + ASN1_STRFLGS_UTF8_CONVERT | \ + ASN1_STRFLGS_DUMP_UNKNOWN | \ + ASN1_STRFLGS_DUMP_DER) + +DECLARE_STACK_OF(ASN1_INTEGER) +DECLARE_ASN1_SET_OF(ASN1_INTEGER) + +DECLARE_STACK_OF(ASN1_GENERALSTRING) + +typedef struct asn1_type_st { + int type; + union { + char *ptr; + ASN1_BOOLEAN boolean; + ASN1_STRING *asn1_string; + ASN1_OBJECT *object; + ASN1_INTEGER *integer; + ASN1_ENUMERATED *enumerated; + ASN1_BIT_STRING *bit_string; + ASN1_OCTET_STRING *octet_string; + ASN1_PRINTABLESTRING *printablestring; + ASN1_T61STRING *t61string; + ASN1_IA5STRING *ia5string; + ASN1_GENERALSTRING *generalstring; + ASN1_BMPSTRING *bmpstring; + ASN1_UNIVERSALSTRING *universalstring; + ASN1_UTCTIME *utctime; + ASN1_GENERALIZEDTIME *generalizedtime; + ASN1_VISIBLESTRING *visiblestring; + ASN1_UTF8STRING *utf8string; + /* + * set and sequence are left complete and still contain the set or + * sequence bytes + */ + ASN1_STRING *set; + ASN1_STRING *sequence; + ASN1_VALUE *asn1_value; + } value; +} ASN1_TYPE; + +DECLARE_STACK_OF(ASN1_TYPE) +DECLARE_ASN1_SET_OF(ASN1_TYPE) + +typedef STACK_OF(ASN1_TYPE) ASN1_SEQUENCE_ANY; + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ASN1_SEQUENCE_ANY, ASN1_SET_ANY) + +typedef struct NETSCAPE_X509_st { + ASN1_OCTET_STRING *header; + X509 *cert; +} NETSCAPE_X509; + +/* This is used to contain a list of bit names */ +typedef struct BIT_STRING_BITNAME_st { + int bitnum; + const char *lname; + const char *sname; +} BIT_STRING_BITNAME; + +# define M_ASN1_STRING_length(x) ((x)->length) +# define M_ASN1_STRING_length_set(x, n) ((x)->length = (n)) +# define M_ASN1_STRING_type(x) ((x)->type) +# define M_ASN1_STRING_data(x) ((x)->data) + +/* Macros for string operations */ +# define M_ASN1_BIT_STRING_new() (ASN1_BIT_STRING *)\ + ASN1_STRING_type_new(V_ASN1_BIT_STRING) +# define M_ASN1_BIT_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_BIT_STRING_dup(a) (ASN1_BIT_STRING *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_ASN1_BIT_STRING_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) +# define M_ASN1_BIT_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) + +# define M_ASN1_INTEGER_new() (ASN1_INTEGER *)\ + ASN1_STRING_type_new(V_ASN1_INTEGER) +# define M_ASN1_INTEGER_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_INTEGER_dup(a) (ASN1_INTEGER *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_ASN1_INTEGER_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) + +# define M_ASN1_ENUMERATED_new() (ASN1_ENUMERATED *)\ + ASN1_STRING_type_new(V_ASN1_ENUMERATED) +# define M_ASN1_ENUMERATED_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_ENUMERATED_dup(a) (ASN1_ENUMERATED *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_ASN1_ENUMERATED_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) + +# define M_ASN1_OCTET_STRING_new() (ASN1_OCTET_STRING *)\ + ASN1_STRING_type_new(V_ASN1_OCTET_STRING) +# define M_ASN1_OCTET_STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_OCTET_STRING_dup(a) (ASN1_OCTET_STRING *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_ASN1_OCTET_STRING_cmp(a,b) ASN1_STRING_cmp(\ + (const ASN1_STRING *)a,(const ASN1_STRING *)b) +# define M_ASN1_OCTET_STRING_set(a,b,c) ASN1_STRING_set((ASN1_STRING *)a,b,c) +# define M_ASN1_OCTET_STRING_print(a,b) ASN1_STRING_print(a,(ASN1_STRING *)b) +# define M_i2d_ASN1_OCTET_STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_OCTET_STRING,\ + V_ASN1_UNIVERSAL) + +# define B_ASN1_TIME \ + B_ASN1_UTCTIME | \ + B_ASN1_GENERALIZEDTIME + +# define B_ASN1_PRINTABLE \ + B_ASN1_NUMERICSTRING| \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_T61STRING| \ + B_ASN1_IA5STRING| \ + B_ASN1_BIT_STRING| \ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING|\ + B_ASN1_SEQUENCE|\ + B_ASN1_UNKNOWN + +# define B_ASN1_DIRECTORYSTRING \ + B_ASN1_PRINTABLESTRING| \ + B_ASN1_TELETEXSTRING|\ + B_ASN1_BMPSTRING|\ + B_ASN1_UNIVERSALSTRING|\ + B_ASN1_UTF8STRING + +# define B_ASN1_DISPLAYTEXT \ + B_ASN1_IA5STRING| \ + B_ASN1_VISIBLESTRING| \ + B_ASN1_BMPSTRING|\ + B_ASN1_UTF8STRING + +# define M_ASN1_PRINTABLE_new() ASN1_STRING_type_new(V_ASN1_T61STRING) +# define M_ASN1_PRINTABLE_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_PRINTABLE(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_PRINTABLE(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_PRINTABLE) + +# define M_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING) +# define M_DIRECTORYSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_DIRECTORYSTRING(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +# define M_d2i_DIRECTORYSTRING(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_DIRECTORYSTRING) + +# define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING) +# define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_DISPLAYTEXT(a,pp) i2d_ASN1_bytes((ASN1_STRING *)a,\ + pp,a->type,V_ASN1_UNIVERSAL) +# define M_d2i_DISPLAYTEXT(a,pp,l) \ + d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l, \ + B_ASN1_DISPLAYTEXT) + +# define M_ASN1_PRINTABLESTRING_new() (ASN1_PRINTABLESTRING *)\ + ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING) +# define M_ASN1_PRINTABLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_PRINTABLESTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_PRINTABLESTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_PRINTABLESTRING(a,pp,l) \ + (ASN1_PRINTABLESTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_PRINTABLESTRING) + +# define M_ASN1_T61STRING_new() (ASN1_T61STRING *)\ + ASN1_STRING_type_new(V_ASN1_T61STRING) +# define M_ASN1_T61STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_T61STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_T61STRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_T61STRING(a,pp,l) \ + (ASN1_T61STRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_T61STRING) + +# define M_ASN1_IA5STRING_new() (ASN1_IA5STRING *)\ + ASN1_STRING_type_new(V_ASN1_IA5STRING) +# define M_ASN1_IA5STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_IA5STRING_dup(a) \ + (ASN1_IA5STRING *)ASN1_STRING_dup((const ASN1_STRING *)a) +# define M_i2d_ASN1_IA5STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_IA5STRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_IA5STRING(a,pp,l) \ + (ASN1_IA5STRING *)d2i_ASN1_type_bytes((ASN1_STRING **)a,pp,l,\ + B_ASN1_IA5STRING) + +# define M_ASN1_UTCTIME_new() (ASN1_UTCTIME *)\ + ASN1_STRING_type_new(V_ASN1_UTCTIME) +# define M_ASN1_UTCTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_UTCTIME_dup(a) (ASN1_UTCTIME *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) + +# define M_ASN1_GENERALIZEDTIME_new() (ASN1_GENERALIZEDTIME *)\ + ASN1_STRING_type_new(V_ASN1_GENERALIZEDTIME) +# define M_ASN1_GENERALIZEDTIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_GENERALIZEDTIME_dup(a) (ASN1_GENERALIZEDTIME *)ASN1_STRING_dup(\ + (const ASN1_STRING *)a) + +# define M_ASN1_TIME_new() (ASN1_TIME *)\ + ASN1_STRING_type_new(V_ASN1_UTCTIME) +# define M_ASN1_TIME_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_ASN1_TIME_dup(a) (ASN1_TIME *)\ + ASN1_STRING_dup((const ASN1_STRING *)a) + +# define M_ASN1_GENERALSTRING_new() (ASN1_GENERALSTRING *)\ + ASN1_STRING_type_new(V_ASN1_GENERALSTRING) +# define M_ASN1_GENERALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_GENERALSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_GENERALSTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_GENERALSTRING(a,pp,l) \ + (ASN1_GENERALSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_GENERALSTRING) + +# define M_ASN1_UNIVERSALSTRING_new() (ASN1_UNIVERSALSTRING *)\ + ASN1_STRING_type_new(V_ASN1_UNIVERSALSTRING) +# define M_ASN1_UNIVERSALSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_UNIVERSALSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UNIVERSALSTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_UNIVERSALSTRING(a,pp,l) \ + (ASN1_UNIVERSALSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_UNIVERSALSTRING) + +# define M_ASN1_BMPSTRING_new() (ASN1_BMPSTRING *)\ + ASN1_STRING_type_new(V_ASN1_BMPSTRING) +# define M_ASN1_BMPSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_BMPSTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_BMPSTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_BMPSTRING(a,pp,l) \ + (ASN1_BMPSTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_BMPSTRING) + +# define M_ASN1_VISIBLESTRING_new() (ASN1_VISIBLESTRING *)\ + ASN1_STRING_type_new(V_ASN1_VISIBLESTRING) +# define M_ASN1_VISIBLESTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_VISIBLESTRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_VISIBLESTRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_VISIBLESTRING(a,pp,l) \ + (ASN1_VISIBLESTRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_VISIBLESTRING) + +# define M_ASN1_UTF8STRING_new() (ASN1_UTF8STRING *)\ + ASN1_STRING_type_new(V_ASN1_UTF8STRING) +# define M_ASN1_UTF8STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) +# define M_i2d_ASN1_UTF8STRING(a,pp) \ + i2d_ASN1_bytes((ASN1_STRING *)a,pp,V_ASN1_UTF8STRING,\ + V_ASN1_UNIVERSAL) +# define M_d2i_ASN1_UTF8STRING(a,pp,l) \ + (ASN1_UTF8STRING *)d2i_ASN1_type_bytes\ + ((ASN1_STRING **)a,pp,l,B_ASN1_UTF8STRING) + + /* for the is_set parameter to i2d_ASN1_SET */ +# define IS_SEQUENCE 0 +# define IS_SET 1 + +DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) + +int ASN1_TYPE_get(ASN1_TYPE *a); +void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); +int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); +int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); + +ASN1_OBJECT *ASN1_OBJECT_new(void); +void ASN1_OBJECT_free(ASN1_OBJECT *a); +int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp); +ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length); +ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, + long length); + +DECLARE_ASN1_ITEM(ASN1_OBJECT) + +DECLARE_STACK_OF(ASN1_OBJECT) +DECLARE_ASN1_SET_OF(ASN1_OBJECT) + +ASN1_STRING *ASN1_STRING_new(void); +void ASN1_STRING_free(ASN1_STRING *a); +void ASN1_STRING_clear_free(ASN1_STRING *a); +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); +ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *a); +ASN1_STRING *ASN1_STRING_type_new(int type); +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b); + /* + * Since this is used to store all sorts of things, via macros, for now, + * make its data void * + */ +int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); +int ASN1_STRING_length(const ASN1_STRING *x); +void ASN1_STRING_length_set(ASN1_STRING *x, int n); +int ASN1_STRING_type(ASN1_STRING *x); +unsigned char *ASN1_STRING_data(ASN1_STRING *x); + +DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING) +int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp); +ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a, + const unsigned char **pp, long length); +int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length); +int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); +int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n); +int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, + unsigned char *flags, int flags_len); + +# ifndef OPENSSL_NO_BIO +int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, + BIT_STRING_BITNAME *tbl, int indent); +# endif +int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl); +int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value, + BIT_STRING_BITNAME *tbl); + +int i2d_ASN1_BOOLEAN(int a, unsigned char **pp); +int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length); + +DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER) +int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp); +ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length); +ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp, + long length); +ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x); +int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); + +DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) + +int ASN1_UTCTIME_check(ASN1_UTCTIME *a); +ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t); +ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); +int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t); +# if 0 +time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s); +# endif + +int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *a); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s, + time_t t); +ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, + time_t t, int offset_day, + long offset_sec); +int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); + +DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) +ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a); +int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, + const ASN1_OCTET_STRING *b); +int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *str, const unsigned char *data, + int len); + +DECLARE_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTF8STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_NULL) +DECLARE_ASN1_FUNCTIONS(ASN1_BMPSTRING) + +int UTF8_getc(const unsigned char *str, int len, unsigned long *val); +int UTF8_putc(unsigned char *str, int len, unsigned long value); + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) + +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) +DECLARE_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT) +DECLARE_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_T61STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_IA5STRING) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALSTRING) +DECLARE_ASN1_FUNCTIONS(ASN1_UTCTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) +DECLARE_ASN1_FUNCTIONS(ASN1_TIME) + +DECLARE_ASN1_ITEM(ASN1_OCTET_STRING_NDEF) + +ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t); +ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t, + int offset_day, long offset_sec); +int ASN1_TIME_check(ASN1_TIME *t); +ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME + **out); +int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); + +int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp, + i2d_of_void *i2d, int ex_tag, int ex_class, int is_set); +STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a, + const unsigned char **pp, + long length, d2i_of_void *d2i, + void (*free_func) (OPENSSL_BLOCK), + int ex_tag, int ex_class); + +# ifndef OPENSSL_NO_BIO +int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a); +int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size); +int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a); +int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size); +int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a); +int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size); +int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type); +# endif +int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a); + +int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num); +ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len, + const char *sn, const char *ln); + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); +long ASN1_INTEGER_get(const ASN1_INTEGER *a); +ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); +BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn); + +int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); +long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a); +ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai); +BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn); + +/* General */ +/* given a string, return the correct type, max is the maximum length */ +int ASN1_PRINTABLE_type(const unsigned char *s, int max); + +int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass); +ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp, + long length, int Ptag, int Pclass); +unsigned long ASN1_tag2bit(int tag); +/* type is one or more of the B_ASN1_ values. */ +ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp, + long length, int type); + +/* PARSING */ +int asn1_Finish(ASN1_CTX *c); +int asn1_const_Finish(ASN1_const_CTX *c); + +/* SPECIALS */ +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, + int *pclass, long omax); +int ASN1_check_infinite_end(unsigned char **p, long len); +int ASN1_const_check_infinite_end(const unsigned char **p, long len); +void ASN1_put_object(unsigned char **pp, int constructed, int length, + int tag, int xclass); +int ASN1_put_eoc(unsigned char **pp); +int ASN1_object_size(int constructed, int length, int tag); + +/* Used to implement other functions */ +void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x); + +# define ASN1_dup_of(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_dup_of_const(type,i2d,d2i,x) \ + ((type*)ASN1_dup(CHECKED_I2D_OF(const type, i2d), \ + CHECKED_D2I_OF(type, d2i), \ + CHECKED_PTR_OF(const type, x))) + +void *ASN1_item_dup(const ASN1_ITEM *it, void *x); + +/* ASN1 alloc/free macros for when a type is only used internally */ + +# define M_ASN1_new_of(type) (type *)ASN1_item_new(ASN1_ITEM_rptr(type)) +# define M_ASN1_free_of(x, type) \ + ASN1_item_free(CHECKED_PTR_OF(type, x), ASN1_ITEM_rptr(type)) + +# ifndef OPENSSL_NO_FP_API +void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x); + +# define ASN1_d2i_fp_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_fp(CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x); + +# define ASN1_i2d_fp_of(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_i2d_fp_of_const(type,i2d,out,x) \ + (ASN1_i2d_fp(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); +int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags); +# endif + +int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in); + +# ifndef OPENSSL_NO_BIO +void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x); + +# define ASN1_d2i_bio_of(type,xnew,d2i,in,x) \ + ((type*)ASN1_d2i_bio( CHECKED_NEW_OF(type, xnew), \ + CHECKED_D2I_OF(type, d2i), \ + in, \ + CHECKED_PPTR_OF(type, x))) + +void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x); + +# define ASN1_i2d_bio_of(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(type, i2d), \ + out, \ + CHECKED_PTR_OF(type, x))) + +# define ASN1_i2d_bio_of_const(type,i2d,out,x) \ + (ASN1_i2d_bio(CHECKED_I2D_OF(const type, i2d), \ + out, \ + CHECKED_PTR_OF(const type, x))) + +int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); +int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); +int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); +int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a); +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); +int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags); +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, + unsigned char *buf, int off); +int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent); +int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, + int dump); +# endif +const char *ASN1_tag2str(int tag); + +/* Used to load and write netscape format cert */ + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_X509) + +int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s); + +int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len); +int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len); +int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, + unsigned char *data, int len); +int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, + unsigned char *data, int max_len); + +STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len, + d2i_of_void *d2i, + void (*free_func) (OPENSSL_BLOCK)); +unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d, + unsigned char **buf, int *len); +void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i); +void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it); +ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, + ASN1_OCTET_STRING **oct); + +# define ASN1_pack_string_of(type,obj,i2d,oct) \ + (ASN1_pack_string(CHECKED_PTR_OF(type, obj), \ + CHECKED_I2D_OF(type, i2d), \ + oct)) + +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, + ASN1_OCTET_STRING **oct); + +void ASN1_STRING_set_default_mask(unsigned long mask); +int ASN1_STRING_set_default_mask_asc(const char *p); +unsigned long ASN1_STRING_get_default_mask(void); +int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask); +int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, + int inform, unsigned long mask, + long minsize, long maxsize); + +ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, + const unsigned char *in, int inlen, + int inform, int nid); +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid); +int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long); +void ASN1_STRING_TABLE_cleanup(void); + +/* ASN1 template functions */ + +/* Old API compatible functions */ +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, + long len, const ASN1_ITEM *it); +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); +int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it); + +void ASN1_add_oid_module(void); + +ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf); +ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf); + +/* ASN1 Print flags */ + +/* Indicate missing OPTIONAL fields */ +# define ASN1_PCTX_FLAGS_SHOW_ABSENT 0x001 +/* Mark start and end of SEQUENCE */ +# define ASN1_PCTX_FLAGS_SHOW_SEQUENCE 0x002 +/* Mark start and end of SEQUENCE/SET OF */ +# define ASN1_PCTX_FLAGS_SHOW_SSOF 0x004 +/* Show the ASN1 type of primitives */ +# define ASN1_PCTX_FLAGS_SHOW_TYPE 0x008 +/* Don't show ASN1 type of ANY */ +# define ASN1_PCTX_FLAGS_NO_ANY_TYPE 0x010 +/* Don't show ASN1 type of MSTRINGs */ +# define ASN1_PCTX_FLAGS_NO_MSTRING_TYPE 0x020 +/* Don't show field names in SEQUENCE */ +# define ASN1_PCTX_FLAGS_NO_FIELD_NAME 0x040 +/* Show structure names of each SEQUENCE field */ +# define ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME 0x080 +/* Don't show structure name even at top level */ +# define ASN1_PCTX_FLAGS_NO_STRUCT_NAME 0x100 + +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, + const ASN1_ITEM *it, const ASN1_PCTX *pctx); +ASN1_PCTX *ASN1_PCTX_new(void); +void ASN1_PCTX_free(ASN1_PCTX *p); +unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags); +unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p); +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags); + +BIO_METHOD *BIO_f_asn1(void); + +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it); + +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it); +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const char *hdr, const ASN1_ITEM *it); +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it); +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it); +int SMIME_crlf_copy(BIO *in, BIO *out, int flags); +int SMIME_text(BIO *in, BIO *out); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ASN1_strings(void); + +/* Error codes for the ASN1 functions. */ + +/* Function codes. */ +# define ASN1_F_A2D_ASN1_OBJECT 100 +# define ASN1_F_A2I_ASN1_ENUMERATED 101 +# define ASN1_F_A2I_ASN1_INTEGER 102 +# define ASN1_F_A2I_ASN1_STRING 103 +# define ASN1_F_APPEND_EXP 176 +# define ASN1_F_ASN1_BIT_STRING_SET_BIT 183 +# define ASN1_F_ASN1_CB 177 +# define ASN1_F_ASN1_CHECK_TLEN 104 +# define ASN1_F_ASN1_COLLATE_PRIMITIVE 105 +# define ASN1_F_ASN1_COLLECT 106 +# define ASN1_F_ASN1_D2I_EX_PRIMITIVE 108 +# define ASN1_F_ASN1_D2I_FP 109 +# define ASN1_F_ASN1_D2I_READ_BIO 107 +# define ASN1_F_ASN1_DIGEST 184 +# define ASN1_F_ASN1_DO_ADB 110 +# define ASN1_F_ASN1_DUP 111 +# define ASN1_F_ASN1_ENUMERATED_SET 112 +# define ASN1_F_ASN1_ENUMERATED_TO_BN 113 +# define ASN1_F_ASN1_EX_C2I 204 +# define ASN1_F_ASN1_FIND_END 190 +# define ASN1_F_ASN1_GENERALIZEDTIME_ADJ 216 +# define ASN1_F_ASN1_GENERALIZEDTIME_SET 185 +# define ASN1_F_ASN1_GENERATE_V3 178 +# define ASN1_F_ASN1_GET_OBJECT 114 +# define ASN1_F_ASN1_HEADER_NEW 115 +# define ASN1_F_ASN1_I2D_BIO 116 +# define ASN1_F_ASN1_I2D_FP 117 +# define ASN1_F_ASN1_INTEGER_SET 118 +# define ASN1_F_ASN1_INTEGER_TO_BN 119 +# define ASN1_F_ASN1_ITEM_D2I_FP 206 +# define ASN1_F_ASN1_ITEM_DUP 191 +# define ASN1_F_ASN1_ITEM_EX_COMBINE_NEW 121 +# define ASN1_F_ASN1_ITEM_EX_D2I 120 +# define ASN1_F_ASN1_ITEM_I2D_BIO 192 +# define ASN1_F_ASN1_ITEM_I2D_FP 193 +# define ASN1_F_ASN1_ITEM_PACK 198 +# define ASN1_F_ASN1_ITEM_SIGN 195 +# define ASN1_F_ASN1_ITEM_SIGN_CTX 220 +# define ASN1_F_ASN1_ITEM_UNPACK 199 +# define ASN1_F_ASN1_ITEM_VERIFY 197 +# define ASN1_F_ASN1_MBSTRING_NCOPY 122 +# define ASN1_F_ASN1_OBJECT_NEW 123 +# define ASN1_F_ASN1_OUTPUT_DATA 214 +# define ASN1_F_ASN1_PACK_STRING 124 +# define ASN1_F_ASN1_PCTX_NEW 205 +# define ASN1_F_ASN1_PKCS5_PBE_SET 125 +# define ASN1_F_ASN1_SEQ_PACK 126 +# define ASN1_F_ASN1_SEQ_UNPACK 127 +# define ASN1_F_ASN1_SIGN 128 +# define ASN1_F_ASN1_STR2TYPE 179 +# define ASN1_F_ASN1_STRING_SET 186 +# define ASN1_F_ASN1_STRING_TABLE_ADD 129 +# define ASN1_F_ASN1_STRING_TYPE_NEW 130 +# define ASN1_F_ASN1_TEMPLATE_EX_D2I 132 +# define ASN1_F_ASN1_TEMPLATE_NEW 133 +# define ASN1_F_ASN1_TEMPLATE_NOEXP_D2I 131 +# define ASN1_F_ASN1_TIME_ADJ 217 +# define ASN1_F_ASN1_TIME_SET 175 +# define ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING 134 +# define ASN1_F_ASN1_TYPE_GET_OCTETSTRING 135 +# define ASN1_F_ASN1_UNPACK_STRING 136 +# define ASN1_F_ASN1_UTCTIME_ADJ 218 +# define ASN1_F_ASN1_UTCTIME_SET 187 +# define ASN1_F_ASN1_VERIFY 137 +# define ASN1_F_B64_READ_ASN1 209 +# define ASN1_F_B64_WRITE_ASN1 210 +# define ASN1_F_BIO_NEW_NDEF 208 +# define ASN1_F_BITSTR_CB 180 +# define ASN1_F_BN_TO_ASN1_ENUMERATED 138 +# define ASN1_F_BN_TO_ASN1_INTEGER 139 +# define ASN1_F_C2I_ASN1_BIT_STRING 189 +# define ASN1_F_C2I_ASN1_INTEGER 194 +# define ASN1_F_C2I_ASN1_OBJECT 196 +# define ASN1_F_COLLECT_DATA 140 +# define ASN1_F_D2I_ASN1_BIT_STRING 141 +# define ASN1_F_D2I_ASN1_BOOLEAN 142 +# define ASN1_F_D2I_ASN1_BYTES 143 +# define ASN1_F_D2I_ASN1_GENERALIZEDTIME 144 +# define ASN1_F_D2I_ASN1_HEADER 145 +# define ASN1_F_D2I_ASN1_INTEGER 146 +# define ASN1_F_D2I_ASN1_OBJECT 147 +# define ASN1_F_D2I_ASN1_SET 148 +# define ASN1_F_D2I_ASN1_TYPE_BYTES 149 +# define ASN1_F_D2I_ASN1_UINTEGER 150 +# define ASN1_F_D2I_ASN1_UTCTIME 151 +# define ASN1_F_D2I_AUTOPRIVATEKEY 207 +# define ASN1_F_D2I_NETSCAPE_RSA 152 +# define ASN1_F_D2I_NETSCAPE_RSA_2 153 +# define ASN1_F_D2I_PRIVATEKEY 154 +# define ASN1_F_D2I_PUBLICKEY 155 +# define ASN1_F_D2I_RSA_NET 200 +# define ASN1_F_D2I_RSA_NET_2 201 +# define ASN1_F_D2I_X509 156 +# define ASN1_F_D2I_X509_CINF 157 +# define ASN1_F_D2I_X509_PKEY 159 +# define ASN1_F_I2D_ASN1_BIO_STREAM 211 +# define ASN1_F_I2D_ASN1_SET 188 +# define ASN1_F_I2D_ASN1_TIME 160 +# define ASN1_F_I2D_DSA_PUBKEY 161 +# define ASN1_F_I2D_EC_PUBKEY 181 +# define ASN1_F_I2D_PRIVATEKEY 163 +# define ASN1_F_I2D_PUBLICKEY 164 +# define ASN1_F_I2D_RSA_NET 162 +# define ASN1_F_I2D_RSA_PUBKEY 165 +# define ASN1_F_LONG_C2I 166 +# define ASN1_F_OID_MODULE_INIT 174 +# define ASN1_F_PARSE_TAGGING 182 +# define ASN1_F_PKCS5_PBE2_SET_IV 167 +# define ASN1_F_PKCS5_PBE_SET 202 +# define ASN1_F_PKCS5_PBE_SET0_ALGOR 215 +# define ASN1_F_PKCS5_PBKDF2_SET 219 +# define ASN1_F_SMIME_READ_ASN1 212 +# define ASN1_F_SMIME_TEXT 213 +# define ASN1_F_X509_CINF_NEW 168 +# define ASN1_F_X509_CRL_ADD0_REVOKED 169 +# define ASN1_F_X509_INFO_NEW 170 +# define ASN1_F_X509_NAME_ENCODE 203 +# define ASN1_F_X509_NAME_EX_D2I 158 +# define ASN1_F_X509_NAME_EX_NEW 171 +# define ASN1_F_X509_NEW 172 +# define ASN1_F_X509_PKEY_NEW 173 + +/* Reason codes. */ +# define ASN1_R_ADDING_OBJECT 171 +# define ASN1_R_ASN1_PARSE_ERROR 203 +# define ASN1_R_ASN1_SIG_PARSE_ERROR 204 +# define ASN1_R_AUX_ERROR 100 +# define ASN1_R_BAD_CLASS 101 +# define ASN1_R_BAD_OBJECT_HEADER 102 +# define ASN1_R_BAD_PASSWORD_READ 103 +# define ASN1_R_BAD_TAG 104 +# define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 214 +# define ASN1_R_BN_LIB 105 +# define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 +# define ASN1_R_BUFFER_TOO_SMALL 107 +# define ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 108 +# define ASN1_R_CONTEXT_NOT_INITIALISED 217 +# define ASN1_R_DATA_IS_WRONG 109 +# define ASN1_R_DECODE_ERROR 110 +# define ASN1_R_DECODING_ERROR 111 +# define ASN1_R_DEPTH_EXCEEDED 174 +# define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 198 +# define ASN1_R_ENCODE_ERROR 112 +# define ASN1_R_ERROR_GETTING_TIME 173 +# define ASN1_R_ERROR_LOADING_SECTION 172 +# define ASN1_R_ERROR_PARSING_SET_ELEMENT 113 +# define ASN1_R_ERROR_SETTING_CIPHER_PARAMS 114 +# define ASN1_R_EXPECTING_AN_INTEGER 115 +# define ASN1_R_EXPECTING_AN_OBJECT 116 +# define ASN1_R_EXPECTING_A_BOOLEAN 117 +# define ASN1_R_EXPECTING_A_TIME 118 +# define ASN1_R_EXPLICIT_LENGTH_MISMATCH 119 +# define ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED 120 +# define ASN1_R_FIELD_MISSING 121 +# define ASN1_R_FIRST_NUM_TOO_LARGE 122 +# define ASN1_R_HEADER_TOO_LONG 123 +# define ASN1_R_ILLEGAL_BITSTRING_FORMAT 175 +# define ASN1_R_ILLEGAL_BOOLEAN 176 +# define ASN1_R_ILLEGAL_CHARACTERS 124 +# define ASN1_R_ILLEGAL_FORMAT 177 +# define ASN1_R_ILLEGAL_HEX 178 +# define ASN1_R_ILLEGAL_IMPLICIT_TAG 179 +# define ASN1_R_ILLEGAL_INTEGER 180 +# define ASN1_R_ILLEGAL_NESTED_TAGGING 181 +# define ASN1_R_ILLEGAL_NULL 125 +# define ASN1_R_ILLEGAL_NULL_VALUE 182 +# define ASN1_R_ILLEGAL_OBJECT 183 +# define ASN1_R_ILLEGAL_OPTIONAL_ANY 126 +# define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 170 +# define ASN1_R_ILLEGAL_TAGGED_ANY 127 +# define ASN1_R_ILLEGAL_TIME_VALUE 184 +# define ASN1_R_INTEGER_NOT_ASCII_FORMAT 185 +# define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 128 +# define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 220 +# define ASN1_R_INVALID_BMPSTRING_LENGTH 129 +# define ASN1_R_INVALID_DIGIT 130 +# define ASN1_R_INVALID_MIME_TYPE 205 +# define ASN1_R_INVALID_MODIFIER 186 +# define ASN1_R_INVALID_NUMBER 187 +# define ASN1_R_INVALID_OBJECT_ENCODING 216 +# define ASN1_R_INVALID_SEPARATOR 131 +# define ASN1_R_INVALID_TIME_FORMAT 132 +# define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 133 +# define ASN1_R_INVALID_UTF8STRING 134 +# define ASN1_R_IV_TOO_LARGE 135 +# define ASN1_R_LENGTH_ERROR 136 +# define ASN1_R_LIST_ERROR 188 +# define ASN1_R_MIME_NO_CONTENT_TYPE 206 +# define ASN1_R_MIME_PARSE_ERROR 207 +# define ASN1_R_MIME_SIG_PARSE_ERROR 208 +# define ASN1_R_MISSING_EOC 137 +# define ASN1_R_MISSING_SECOND_NUMBER 138 +# define ASN1_R_MISSING_VALUE 189 +# define ASN1_R_MSTRING_NOT_UNIVERSAL 139 +# define ASN1_R_MSTRING_WRONG_TAG 140 +# define ASN1_R_NESTED_ASN1_STRING 197 +# define ASN1_R_NON_HEX_CHARACTERS 141 +# define ASN1_R_NOT_ASCII_FORMAT 190 +# define ASN1_R_NOT_ENOUGH_DATA 142 +# define ASN1_R_NO_CONTENT_TYPE 209 +# define ASN1_R_NO_DEFAULT_DIGEST 201 +# define ASN1_R_NO_MATCHING_CHOICE_TYPE 143 +# define ASN1_R_NO_MULTIPART_BODY_FAILURE 210 +# define ASN1_R_NO_MULTIPART_BOUNDARY 211 +# define ASN1_R_NO_SIG_CONTENT_TYPE 212 +# define ASN1_R_NULL_IS_WRONG_LENGTH 144 +# define ASN1_R_OBJECT_NOT_ASCII_FORMAT 191 +# define ASN1_R_ODD_NUMBER_OF_CHARS 145 +# define ASN1_R_PRIVATE_KEY_HEADER_MISSING 146 +# define ASN1_R_SECOND_NUMBER_TOO_LARGE 147 +# define ASN1_R_SEQUENCE_LENGTH_MISMATCH 148 +# define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 149 +# define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 192 +# define ASN1_R_SHORT_LINE 150 +# define ASN1_R_SIG_INVALID_MIME_TYPE 213 +# define ASN1_R_STREAMING_NOT_SUPPORTED 202 +# define ASN1_R_STRING_TOO_LONG 151 +# define ASN1_R_STRING_TOO_SHORT 152 +# define ASN1_R_TAG_VALUE_TOO_HIGH 153 +# define ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 154 +# define ASN1_R_TIME_NOT_ASCII_FORMAT 193 +# define ASN1_R_TOO_LONG 155 +# define ASN1_R_TYPE_NOT_CONSTRUCTED 156 +# define ASN1_R_TYPE_NOT_PRIMITIVE 218 +# define ASN1_R_UNABLE_TO_DECODE_RSA_KEY 157 +# define ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY 158 +# define ASN1_R_UNEXPECTED_EOC 159 +# define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 215 +# define ASN1_R_UNKNOWN_FORMAT 160 +# define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 161 +# define ASN1_R_UNKNOWN_OBJECT_TYPE 162 +# define ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE 163 +# define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 199 +# define ASN1_R_UNKNOWN_TAG 194 +# define ASN1_R_UNKOWN_FORMAT 195 +# define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 164 +# define ASN1_R_UNSUPPORTED_CIPHER 165 +# define ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM 166 +# define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 167 +# define ASN1_R_UNSUPPORTED_TYPE 196 +# define ASN1_R_WRONG_PUBLIC_KEY_TYPE 200 +# define ASN1_R_WRONG_TAG 168 +# define ASN1_R_WRONG_TYPE 169 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/asn1/asn1_err.c b/libs/openssl/crypto/asn1/asn1_err.c new file mode 100644 index 00000000..fd4ac8d9 --- /dev/null +++ b/libs/openssl/crypto/asn1/asn1_err.c @@ -0,0 +1,354 @@ +/* crypto/asn1/asn1_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASN1,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASN1,0,reason) + +static ERR_STRING_DATA ASN1_str_functs[] = { + {ERR_FUNC(ASN1_F_A2D_ASN1_OBJECT), "a2d_ASN1_OBJECT"}, + {ERR_FUNC(ASN1_F_A2I_ASN1_ENUMERATED), "a2i_ASN1_ENUMERATED"}, + {ERR_FUNC(ASN1_F_A2I_ASN1_INTEGER), "a2i_ASN1_INTEGER"}, + {ERR_FUNC(ASN1_F_A2I_ASN1_STRING), "a2i_ASN1_STRING"}, + {ERR_FUNC(ASN1_F_APPEND_EXP), "APPEND_EXP"}, + {ERR_FUNC(ASN1_F_ASN1_BIT_STRING_SET_BIT), "ASN1_BIT_STRING_set_bit"}, + {ERR_FUNC(ASN1_F_ASN1_CB), "ASN1_CB"}, + {ERR_FUNC(ASN1_F_ASN1_CHECK_TLEN), "ASN1_CHECK_TLEN"}, + {ERR_FUNC(ASN1_F_ASN1_COLLATE_PRIMITIVE), "ASN1_COLLATE_PRIMITIVE"}, + {ERR_FUNC(ASN1_F_ASN1_COLLECT), "ASN1_COLLECT"}, + {ERR_FUNC(ASN1_F_ASN1_D2I_EX_PRIMITIVE), "ASN1_D2I_EX_PRIMITIVE"}, + {ERR_FUNC(ASN1_F_ASN1_D2I_FP), "ASN1_d2i_fp"}, + {ERR_FUNC(ASN1_F_ASN1_D2I_READ_BIO), "ASN1_D2I_READ_BIO"}, + {ERR_FUNC(ASN1_F_ASN1_DIGEST), "ASN1_digest"}, + {ERR_FUNC(ASN1_F_ASN1_DO_ADB), "ASN1_DO_ADB"}, + {ERR_FUNC(ASN1_F_ASN1_DUP), "ASN1_dup"}, + {ERR_FUNC(ASN1_F_ASN1_ENUMERATED_SET), "ASN1_ENUMERATED_set"}, + {ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN), "ASN1_ENUMERATED_to_BN"}, + {ERR_FUNC(ASN1_F_ASN1_EX_C2I), "ASN1_EX_C2I"}, + {ERR_FUNC(ASN1_F_ASN1_FIND_END), "ASN1_FIND_END"}, + {ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ), "ASN1_GENERALIZEDTIME_adj"}, + {ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET), "ASN1_GENERALIZEDTIME_set"}, + {ERR_FUNC(ASN1_F_ASN1_GENERATE_V3), "ASN1_generate_v3"}, + {ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"}, + {ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_NEW"}, + {ERR_FUNC(ASN1_F_ASN1_I2D_BIO), "ASN1_i2d_bio"}, + {ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"}, + {ERR_FUNC(ASN1_F_ASN1_INTEGER_SET), "ASN1_INTEGER_set"}, + {ERR_FUNC(ASN1_F_ASN1_INTEGER_TO_BN), "ASN1_INTEGER_to_BN"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_D2I_FP), "ASN1_item_d2i_fp"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_DUP), "ASN1_item_dup"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW), "ASN1_ITEM_EX_COMBINE_NEW"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_EX_D2I), "ASN1_ITEM_EX_D2I"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO), "ASN1_item_i2d_bio"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX), "ASN1_item_sign_ctx"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"}, + {ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"}, + {ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"}, + {ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"}, + {ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "ASN1_OUTPUT_DATA"}, + {ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"}, + {ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_new"}, + {ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"}, + {ERR_FUNC(ASN1_F_ASN1_SEQ_PACK), "ASN1_seq_pack"}, + {ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK), "ASN1_seq_unpack"}, + {ERR_FUNC(ASN1_F_ASN1_SIGN), "ASN1_sign"}, + {ERR_FUNC(ASN1_F_ASN1_STR2TYPE), "ASN1_STR2TYPE"}, + {ERR_FUNC(ASN1_F_ASN1_STRING_SET), "ASN1_STRING_set"}, + {ERR_FUNC(ASN1_F_ASN1_STRING_TABLE_ADD), "ASN1_STRING_TABLE_add"}, + {ERR_FUNC(ASN1_F_ASN1_STRING_TYPE_NEW), "ASN1_STRING_type_new"}, + {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I), "ASN1_TEMPLATE_EX_D2I"}, + {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW), "ASN1_TEMPLATE_NEW"}, + {ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I), "ASN1_TEMPLATE_NOEXP_D2I"}, + {ERR_FUNC(ASN1_F_ASN1_TIME_ADJ), "ASN1_TIME_adj"}, + {ERR_FUNC(ASN1_F_ASN1_TIME_SET), "ASN1_TIME_set"}, + {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING), + "ASN1_TYPE_get_int_octetstring"}, + {ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING), "ASN1_TYPE_get_octetstring"}, + {ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING), "ASN1_unpack_string"}, + {ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ), "ASN1_UTCTIME_adj"}, + {ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET), "ASN1_UTCTIME_set"}, + {ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"}, + {ERR_FUNC(ASN1_F_B64_READ_ASN1), "B64_READ_ASN1"}, + {ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_WRITE_ASN1"}, + {ERR_FUNC(ASN1_F_BIO_NEW_NDEF), "BIO_new_NDEF"}, + {ERR_FUNC(ASN1_F_BITSTR_CB), "BITSTR_CB"}, + {ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED), "BN_to_ASN1_ENUMERATED"}, + {ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER), "BN_to_ASN1_INTEGER"}, + {ERR_FUNC(ASN1_F_C2I_ASN1_BIT_STRING), "c2i_ASN1_BIT_STRING"}, + {ERR_FUNC(ASN1_F_C2I_ASN1_INTEGER), "c2i_ASN1_INTEGER"}, + {ERR_FUNC(ASN1_F_C2I_ASN1_OBJECT), "c2i_ASN1_OBJECT"}, + {ERR_FUNC(ASN1_F_COLLECT_DATA), "COLLECT_DATA"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_BIT_STRING), "D2I_ASN1_BIT_STRING"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN), "d2i_ASN1_BOOLEAN"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_BYTES), "d2i_ASN1_bytes"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME), "D2I_ASN1_GENERALIZEDTIME"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_HEADER), "D2I_ASN1_HEADER"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER), "D2I_ASN1_INTEGER"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT), "d2i_ASN1_OBJECT"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_SET), "d2i_ASN1_SET"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES), "d2i_ASN1_type_bytes"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER), "d2i_ASN1_UINTEGER"}, + {ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME), "D2I_ASN1_UTCTIME"}, + {ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY), "d2i_AutoPrivateKey"}, + {ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA), "d2i_Netscape_RSA"}, + {ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2), "D2I_NETSCAPE_RSA_2"}, + {ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"}, + {ERR_FUNC(ASN1_F_D2I_PUBLICKEY), "d2i_PublicKey"}, + {ERR_FUNC(ASN1_F_D2I_RSA_NET), "d2i_RSA_NET"}, + {ERR_FUNC(ASN1_F_D2I_RSA_NET_2), "D2I_RSA_NET_2"}, + {ERR_FUNC(ASN1_F_D2I_X509), "D2I_X509"}, + {ERR_FUNC(ASN1_F_D2I_X509_CINF), "D2I_X509_CINF"}, + {ERR_FUNC(ASN1_F_D2I_X509_PKEY), "d2i_X509_PKEY"}, + {ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM), "i2d_ASN1_bio_stream"}, + {ERR_FUNC(ASN1_F_I2D_ASN1_SET), "i2d_ASN1_SET"}, + {ERR_FUNC(ASN1_F_I2D_ASN1_TIME), "I2D_ASN1_TIME"}, + {ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"}, + {ERR_FUNC(ASN1_F_I2D_EC_PUBKEY), "i2d_EC_PUBKEY"}, + {ERR_FUNC(ASN1_F_I2D_PRIVATEKEY), "i2d_PrivateKey"}, + {ERR_FUNC(ASN1_F_I2D_PUBLICKEY), "i2d_PublicKey"}, + {ERR_FUNC(ASN1_F_I2D_RSA_NET), "i2d_RSA_NET"}, + {ERR_FUNC(ASN1_F_I2D_RSA_PUBKEY), "i2d_RSA_PUBKEY"}, + {ERR_FUNC(ASN1_F_LONG_C2I), "LONG_C2I"}, + {ERR_FUNC(ASN1_F_OID_MODULE_INIT), "OID_MODULE_INIT"}, + {ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"}, + {ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV), "PKCS5_pbe2_set_iv"}, + {ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"}, + {ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR), "PKCS5_pbe_set0_algor"}, + {ERR_FUNC(ASN1_F_PKCS5_PBKDF2_SET), "PKCS5_pbkdf2_set"}, + {ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"}, + {ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"}, + {ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"}, + {ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED), "X509_CRL_add0_revoked"}, + {ERR_FUNC(ASN1_F_X509_INFO_NEW), "X509_INFO_new"}, + {ERR_FUNC(ASN1_F_X509_NAME_ENCODE), "X509_NAME_ENCODE"}, + {ERR_FUNC(ASN1_F_X509_NAME_EX_D2I), "X509_NAME_EX_D2I"}, + {ERR_FUNC(ASN1_F_X509_NAME_EX_NEW), "X509_NAME_EX_NEW"}, + {ERR_FUNC(ASN1_F_X509_NEW), "X509_NEW"}, + {ERR_FUNC(ASN1_F_X509_PKEY_NEW), "X509_PKEY_new"}, + {0, NULL} +}; + +static ERR_STRING_DATA ASN1_str_reasons[] = { + {ERR_REASON(ASN1_R_ADDING_OBJECT), "adding object"}, + {ERR_REASON(ASN1_R_ASN1_PARSE_ERROR), "asn1 parse error"}, + {ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR), "asn1 sig parse error"}, + {ERR_REASON(ASN1_R_AUX_ERROR), "aux error"}, + {ERR_REASON(ASN1_R_BAD_CLASS), "bad class"}, + {ERR_REASON(ASN1_R_BAD_OBJECT_HEADER), "bad object header"}, + {ERR_REASON(ASN1_R_BAD_PASSWORD_READ), "bad password read"}, + {ERR_REASON(ASN1_R_BAD_TAG), "bad tag"}, + {ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH), + "bmpstring is wrong length"}, + {ERR_REASON(ASN1_R_BN_LIB), "bn lib"}, + {ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH), "boolean is wrong length"}, + {ERR_REASON(ASN1_R_BUFFER_TOO_SMALL), "buffer too small"}, + {ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER), + "cipher has no object identifier"}, + {ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED), "context not initialised"}, + {ERR_REASON(ASN1_R_DATA_IS_WRONG), "data is wrong"}, + {ERR_REASON(ASN1_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(ASN1_R_DECODING_ERROR), "decoding error"}, + {ERR_REASON(ASN1_R_DEPTH_EXCEEDED), "depth exceeded"}, + {ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED), + "digest and key type not supported"}, + {ERR_REASON(ASN1_R_ENCODE_ERROR), "encode error"}, + {ERR_REASON(ASN1_R_ERROR_GETTING_TIME), "error getting time"}, + {ERR_REASON(ASN1_R_ERROR_LOADING_SECTION), "error loading section"}, + {ERR_REASON(ASN1_R_ERROR_PARSING_SET_ELEMENT), + "error parsing set element"}, + {ERR_REASON(ASN1_R_ERROR_SETTING_CIPHER_PARAMS), + "error setting cipher params"}, + {ERR_REASON(ASN1_R_EXPECTING_AN_INTEGER), "expecting an integer"}, + {ERR_REASON(ASN1_R_EXPECTING_AN_OBJECT), "expecting an object"}, + {ERR_REASON(ASN1_R_EXPECTING_A_BOOLEAN), "expecting a boolean"}, + {ERR_REASON(ASN1_R_EXPECTING_A_TIME), "expecting a time"}, + {ERR_REASON(ASN1_R_EXPLICIT_LENGTH_MISMATCH), "explicit length mismatch"}, + {ERR_REASON(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED), + "explicit tag not constructed"}, + {ERR_REASON(ASN1_R_FIELD_MISSING), "field missing"}, + {ERR_REASON(ASN1_R_FIRST_NUM_TOO_LARGE), "first num too large"}, + {ERR_REASON(ASN1_R_HEADER_TOO_LONG), "header too long"}, + {ERR_REASON(ASN1_R_ILLEGAL_BITSTRING_FORMAT), "illegal bitstring format"}, + {ERR_REASON(ASN1_R_ILLEGAL_BOOLEAN), "illegal boolean"}, + {ERR_REASON(ASN1_R_ILLEGAL_CHARACTERS), "illegal characters"}, + {ERR_REASON(ASN1_R_ILLEGAL_FORMAT), "illegal format"}, + {ERR_REASON(ASN1_R_ILLEGAL_HEX), "illegal hex"}, + {ERR_REASON(ASN1_R_ILLEGAL_IMPLICIT_TAG), "illegal implicit tag"}, + {ERR_REASON(ASN1_R_ILLEGAL_INTEGER), "illegal integer"}, + {ERR_REASON(ASN1_R_ILLEGAL_NESTED_TAGGING), "illegal nested tagging"}, + {ERR_REASON(ASN1_R_ILLEGAL_NULL), "illegal null"}, + {ERR_REASON(ASN1_R_ILLEGAL_NULL_VALUE), "illegal null value"}, + {ERR_REASON(ASN1_R_ILLEGAL_OBJECT), "illegal object"}, + {ERR_REASON(ASN1_R_ILLEGAL_OPTIONAL_ANY), "illegal optional any"}, + {ERR_REASON(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE), + "illegal options on item template"}, + {ERR_REASON(ASN1_R_ILLEGAL_TAGGED_ANY), "illegal tagged any"}, + {ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE), "illegal time value"}, + {ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT), "integer not ascii format"}, + {ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG), + "integer too large for long"}, + {ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT), + "invalid bit string bits left"}, + {ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH), "invalid bmpstring length"}, + {ERR_REASON(ASN1_R_INVALID_DIGIT), "invalid digit"}, + {ERR_REASON(ASN1_R_INVALID_MIME_TYPE), "invalid mime type"}, + {ERR_REASON(ASN1_R_INVALID_MODIFIER), "invalid modifier"}, + {ERR_REASON(ASN1_R_INVALID_NUMBER), "invalid number"}, + {ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING), "invalid object encoding"}, + {ERR_REASON(ASN1_R_INVALID_SEPARATOR), "invalid separator"}, + {ERR_REASON(ASN1_R_INVALID_TIME_FORMAT), "invalid time format"}, + {ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH), + "invalid universalstring length"}, + {ERR_REASON(ASN1_R_INVALID_UTF8STRING), "invalid utf8string"}, + {ERR_REASON(ASN1_R_IV_TOO_LARGE), "iv too large"}, + {ERR_REASON(ASN1_R_LENGTH_ERROR), "length error"}, + {ERR_REASON(ASN1_R_LIST_ERROR), "list error"}, + {ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE), "mime no content type"}, + {ERR_REASON(ASN1_R_MIME_PARSE_ERROR), "mime parse error"}, + {ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR), "mime sig parse error"}, + {ERR_REASON(ASN1_R_MISSING_EOC), "missing eoc"}, + {ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER), "missing second number"}, + {ERR_REASON(ASN1_R_MISSING_VALUE), "missing value"}, + {ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL), "mstring not universal"}, + {ERR_REASON(ASN1_R_MSTRING_WRONG_TAG), "mstring wrong tag"}, + {ERR_REASON(ASN1_R_NESTED_ASN1_STRING), "nested asn1 string"}, + {ERR_REASON(ASN1_R_NON_HEX_CHARACTERS), "non hex characters"}, + {ERR_REASON(ASN1_R_NOT_ASCII_FORMAT), "not ascii format"}, + {ERR_REASON(ASN1_R_NOT_ENOUGH_DATA), "not enough data"}, + {ERR_REASON(ASN1_R_NO_CONTENT_TYPE), "no content type"}, + {ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST), "no default digest"}, + {ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE), "no matching choice type"}, + {ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE), + "no multipart body failure"}, + {ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY), "no multipart boundary"}, + {ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE), "no sig content type"}, + {ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH), "null is wrong length"}, + {ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT), "object not ascii format"}, + {ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS), "odd number of chars"}, + {ERR_REASON(ASN1_R_PRIVATE_KEY_HEADER_MISSING), + "private key header missing"}, + {ERR_REASON(ASN1_R_SECOND_NUMBER_TOO_LARGE), "second number too large"}, + {ERR_REASON(ASN1_R_SEQUENCE_LENGTH_MISMATCH), "sequence length mismatch"}, + {ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED), "sequence not constructed"}, + {ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG), + "sequence or set needs config"}, + {ERR_REASON(ASN1_R_SHORT_LINE), "short line"}, + {ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"}, + {ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED), "streaming not supported"}, + {ERR_REASON(ASN1_R_STRING_TOO_LONG), "string too long"}, + {ERR_REASON(ASN1_R_STRING_TOO_SHORT), "string too short"}, + {ERR_REASON(ASN1_R_TAG_VALUE_TOO_HIGH), "tag value too high"}, + {ERR_REASON(ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), + "the asn1 object identifier is not known for this md"}, + {ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT), "time not ascii format"}, + {ERR_REASON(ASN1_R_TOO_LONG), "too long"}, + {ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED), "type not constructed"}, + {ERR_REASON(ASN1_R_TYPE_NOT_PRIMITIVE), "type not primitive"}, + {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY), "unable to decode rsa key"}, + {ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY), + "unable to decode rsa private key"}, + {ERR_REASON(ASN1_R_UNEXPECTED_EOC), "unexpected eoc"}, + {ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH), + "universalstring is wrong length"}, + {ERR_REASON(ASN1_R_UNKNOWN_FORMAT), "unknown format"}, + {ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM), + "unknown message digest algorithm"}, + {ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE), "unknown object type"}, + {ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE), "unknown public key type"}, + {ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM), + "unknown signature algorithm"}, + {ERR_REASON(ASN1_R_UNKNOWN_TAG), "unknown tag"}, + {ERR_REASON(ASN1_R_UNKOWN_FORMAT), "unknown format"}, + {ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE), + "unsupported any defined by type"}, + {ERR_REASON(ASN1_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, + {ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM), + "unsupported encryption algorithm"}, + {ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE), + "unsupported public key type"}, + {ERR_REASON(ASN1_R_UNSUPPORTED_TYPE), "unsupported type"}, + {ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE), "wrong public key type"}, + {ERR_REASON(ASN1_R_WRONG_TAG), "wrong tag"}, + {ERR_REASON(ASN1_R_WRONG_TYPE), "wrong type"}, + {0, NULL} +}; + +#endif + +void ERR_load_ASN1_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL) { + ERR_load_strings(0, ASN1_str_functs); + ERR_load_strings(0, ASN1_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/asn1/asn1_gen.c b/libs/openssl/crypto/asn1/asn1_gen.c new file mode 100644 index 00000000..65749239 --- /dev/null +++ b/libs/openssl/crypto/asn1/asn1_gen.c @@ -0,0 +1,831 @@ +/* asn1_gen.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include +#include + +#define ASN1_GEN_FLAG 0x10000 +#define ASN1_GEN_FLAG_IMP (ASN1_GEN_FLAG|1) +#define ASN1_GEN_FLAG_EXP (ASN1_GEN_FLAG|2) +#define ASN1_GEN_FLAG_TAG (ASN1_GEN_FLAG|3) +#define ASN1_GEN_FLAG_BITWRAP (ASN1_GEN_FLAG|4) +#define ASN1_GEN_FLAG_OCTWRAP (ASN1_GEN_FLAG|5) +#define ASN1_GEN_FLAG_SEQWRAP (ASN1_GEN_FLAG|6) +#define ASN1_GEN_FLAG_SETWRAP (ASN1_GEN_FLAG|7) +#define ASN1_GEN_FLAG_FORMAT (ASN1_GEN_FLAG|8) + +#define ASN1_GEN_STR(str,val) {str, sizeof(str) - 1, val} + +#define ASN1_FLAG_EXP_MAX 20 +/* Maximum number of nested sequences */ +#define ASN1_GEN_SEQ_MAX_DEPTH 50 + +/* Input formats */ + +/* ASCII: default */ +#define ASN1_GEN_FORMAT_ASCII 1 +/* UTF8 */ +#define ASN1_GEN_FORMAT_UTF8 2 +/* Hex */ +#define ASN1_GEN_FORMAT_HEX 3 +/* List of bits */ +#define ASN1_GEN_FORMAT_BITLIST 4 + +struct tag_name_st { + const char *strnam; + int len; + int tag; +}; + +typedef struct { + int exp_tag; + int exp_class; + int exp_constructed; + int exp_pad; + long exp_len; +} tag_exp_type; + +typedef struct { + int imp_tag; + int imp_class; + int utype; + int format; + const char *str; + tag_exp_type exp_list[ASN1_FLAG_EXP_MAX]; + int exp_count; +} tag_exp_arg; + +static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth, + int *perr); +static int bitstr_cb(const char *elem, int len, void *bitstr); +static int asn1_cb(const char *elem, int len, void *bitstr); +static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, + int exp_constructed, int exp_pad, int imp_ok); +static int parse_tagging(const char *vstart, int vlen, int *ptag, + int *pclass); +static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, + int depth, int *perr); +static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype); +static int asn1_str2tag(const char *tagstr, int len); + +ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf) +{ + X509V3_CTX cnf; + + if (!nconf) + return ASN1_generate_v3(str, NULL); + + X509V3_set_nconf(&cnf, nconf); + return ASN1_generate_v3(str, &cnf); +} + +ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf) +{ + int err = 0; + ASN1_TYPE *ret = generate_v3(str, cnf, 0, &err); + if (err) + ASN1err(ASN1_F_ASN1_GENERATE_V3, err); + return ret; +} + +static ASN1_TYPE *generate_v3(char *str, X509V3_CTX *cnf, int depth, + int *perr) +{ + ASN1_TYPE *ret; + tag_exp_arg asn1_tags; + tag_exp_type *etmp; + + int i, len; + + unsigned char *orig_der = NULL, *new_der = NULL; + const unsigned char *cpy_start; + unsigned char *p; + const unsigned char *cp; + int cpy_len; + long hdr_len; + int hdr_constructed = 0, hdr_tag, hdr_class; + int r; + + asn1_tags.imp_tag = -1; + asn1_tags.imp_class = -1; + asn1_tags.format = ASN1_GEN_FORMAT_ASCII; + asn1_tags.exp_count = 0; + if (CONF_parse_list(str, ',', 1, asn1_cb, &asn1_tags) != 0) { + *perr = ASN1_R_UNKNOWN_TAG; + return NULL; + } + + if ((asn1_tags.utype == V_ASN1_SEQUENCE) + || (asn1_tags.utype == V_ASN1_SET)) { + if (!cnf) { + *perr = ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG; + return NULL; + } + if (depth >= ASN1_GEN_SEQ_MAX_DEPTH) { + *perr = ASN1_R_ILLEGAL_NESTED_TAGGING; + return NULL; + } + ret = asn1_multi(asn1_tags.utype, asn1_tags.str, cnf, depth, perr); + } else + ret = asn1_str2type(asn1_tags.str, asn1_tags.format, asn1_tags.utype); + + if (!ret) + return NULL; + + /* If no tagging return base type */ + if ((asn1_tags.imp_tag == -1) && (asn1_tags.exp_count == 0)) + return ret; + + /* Generate the encoding */ + cpy_len = i2d_ASN1_TYPE(ret, &orig_der); + ASN1_TYPE_free(ret); + ret = NULL; + /* Set point to start copying for modified encoding */ + cpy_start = orig_der; + + /* Do we need IMPLICIT tagging? */ + if (asn1_tags.imp_tag != -1) { + /* If IMPLICIT we will replace the underlying tag */ + /* Skip existing tag+len */ + r = ASN1_get_object(&cpy_start, &hdr_len, &hdr_tag, &hdr_class, + cpy_len); + if (r & 0x80) + goto err; + /* Update copy length */ + cpy_len -= cpy_start - orig_der; + /* + * For IMPLICIT tagging the length should match the original length + * and constructed flag should be consistent. + */ + if (r & 0x1) { + /* Indefinite length constructed */ + hdr_constructed = 2; + hdr_len = 0; + } else + /* Just retain constructed flag */ + hdr_constructed = r & V_ASN1_CONSTRUCTED; + /* + * Work out new length with IMPLICIT tag: ignore constructed because + * it will mess up if indefinite length + */ + len = ASN1_object_size(0, hdr_len, asn1_tags.imp_tag); + } else + len = cpy_len; + + /* Work out length in any EXPLICIT, starting from end */ + + for (i = 0, etmp = asn1_tags.exp_list + asn1_tags.exp_count - 1; + i < asn1_tags.exp_count; i++, etmp--) { + /* Content length: number of content octets + any padding */ + len += etmp->exp_pad; + etmp->exp_len = len; + /* Total object length: length including new header */ + len = ASN1_object_size(0, len, etmp->exp_tag); + } + + /* Allocate buffer for new encoding */ + + new_der = OPENSSL_malloc(len); + if (!new_der) + goto err; + + /* Generate tagged encoding */ + + p = new_der; + + /* Output explicit tags first */ + + for (i = 0, etmp = asn1_tags.exp_list; i < asn1_tags.exp_count; + i++, etmp++) { + ASN1_put_object(&p, etmp->exp_constructed, etmp->exp_len, + etmp->exp_tag, etmp->exp_class); + if (etmp->exp_pad) + *p++ = 0; + } + + /* If IMPLICIT, output tag */ + + if (asn1_tags.imp_tag != -1) { + if (asn1_tags.imp_class == V_ASN1_UNIVERSAL + && (asn1_tags.imp_tag == V_ASN1_SEQUENCE + || asn1_tags.imp_tag == V_ASN1_SET)) + hdr_constructed = V_ASN1_CONSTRUCTED; + ASN1_put_object(&p, hdr_constructed, hdr_len, + asn1_tags.imp_tag, asn1_tags.imp_class); + } + + /* Copy across original encoding */ + memcpy(p, cpy_start, cpy_len); + + cp = new_der; + + /* Obtain new ASN1_TYPE structure */ + ret = d2i_ASN1_TYPE(NULL, &cp, len); + + err: + if (orig_der) + OPENSSL_free(orig_der); + if (new_der) + OPENSSL_free(new_der); + + return ret; + +} + +static int asn1_cb(const char *elem, int len, void *bitstr) +{ + tag_exp_arg *arg = bitstr; + int i; + int utype; + int vlen = 0; + const char *p, *vstart = NULL; + + int tmp_tag, tmp_class; + + if (elem == NULL) + return -1; + + for (i = 0, p = elem; i < len; p++, i++) { + /* Look for the ':' in name value pairs */ + if (*p == ':') { + vstart = p + 1; + vlen = len - (vstart - elem); + len = p - elem; + break; + } + } + + utype = asn1_str2tag(elem, len); + + if (utype == -1) { + ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_TAG); + ERR_add_error_data(2, "tag=", elem); + return -1; + } + + /* If this is not a modifier mark end of string and exit */ + if (!(utype & ASN1_GEN_FLAG)) { + arg->utype = utype; + arg->str = vstart; + /* If no value and not end of string, error */ + if (!vstart && elem[len]) { + ASN1err(ASN1_F_ASN1_CB, ASN1_R_MISSING_VALUE); + return -1; + } + return 0; + } + + switch (utype) { + + case ASN1_GEN_FLAG_IMP: + /* Check for illegal multiple IMPLICIT tagging */ + if (arg->imp_tag != -1) { + ASN1err(ASN1_F_ASN1_CB, ASN1_R_ILLEGAL_NESTED_TAGGING); + return -1; + } + if (!parse_tagging(vstart, vlen, &arg->imp_tag, &arg->imp_class)) + return -1; + break; + + case ASN1_GEN_FLAG_EXP: + + if (!parse_tagging(vstart, vlen, &tmp_tag, &tmp_class)) + return -1; + if (!append_exp(arg, tmp_tag, tmp_class, 1, 0, 0)) + return -1; + break; + + case ASN1_GEN_FLAG_SEQWRAP: + if (!append_exp(arg, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, 1, 0, 1)) + return -1; + break; + + case ASN1_GEN_FLAG_SETWRAP: + if (!append_exp(arg, V_ASN1_SET, V_ASN1_UNIVERSAL, 1, 0, 1)) + return -1; + break; + + case ASN1_GEN_FLAG_BITWRAP: + if (!append_exp(arg, V_ASN1_BIT_STRING, V_ASN1_UNIVERSAL, 0, 1, 1)) + return -1; + break; + + case ASN1_GEN_FLAG_OCTWRAP: + if (!append_exp(arg, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL, 0, 0, 1)) + return -1; + break; + + case ASN1_GEN_FLAG_FORMAT: + if (!vstart) { + ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKNOWN_FORMAT); + return -1; + } + if (!strncmp(vstart, "ASCII", 5)) + arg->format = ASN1_GEN_FORMAT_ASCII; + else if (!strncmp(vstart, "UTF8", 4)) + arg->format = ASN1_GEN_FORMAT_UTF8; + else if (!strncmp(vstart, "HEX", 3)) + arg->format = ASN1_GEN_FORMAT_HEX; + else if (!strncmp(vstart, "BITLIST", 7)) + arg->format = ASN1_GEN_FORMAT_BITLIST; + else { + ASN1err(ASN1_F_ASN1_CB, ASN1_R_UNKOWN_FORMAT); + return -1; + } + break; + + } + + return 1; + +} + +static int parse_tagging(const char *vstart, int vlen, int *ptag, int *pclass) +{ + char erch[2]; + long tag_num; + char *eptr; + if (!vstart) + return 0; + tag_num = strtoul(vstart, &eptr, 10); + /* Check we haven't gone past max length: should be impossible */ + if (eptr && *eptr && (eptr > vstart + vlen)) + return 0; + if (tag_num < 0) { + ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_NUMBER); + return 0; + } + *ptag = tag_num; + /* If we have non numeric characters, parse them */ + if (eptr) + vlen -= eptr - vstart; + else + vlen = 0; + if (vlen) { + switch (*eptr) { + + case 'U': + *pclass = V_ASN1_UNIVERSAL; + break; + + case 'A': + *pclass = V_ASN1_APPLICATION; + break; + + case 'P': + *pclass = V_ASN1_PRIVATE; + break; + + case 'C': + *pclass = V_ASN1_CONTEXT_SPECIFIC; + break; + + default: + erch[0] = *eptr; + erch[1] = 0; + ASN1err(ASN1_F_PARSE_TAGGING, ASN1_R_INVALID_MODIFIER); + ERR_add_error_data(2, "Char=", erch); + return 0; + break; + + } + } else + *pclass = V_ASN1_CONTEXT_SPECIFIC; + + return 1; + +} + +/* Handle multiple types: SET and SEQUENCE */ + +static ASN1_TYPE *asn1_multi(int utype, const char *section, X509V3_CTX *cnf, + int depth, int *perr) +{ + ASN1_TYPE *ret = NULL; + STACK_OF(ASN1_TYPE) *sk = NULL; + STACK_OF(CONF_VALUE) *sect = NULL; + unsigned char *der = NULL; + int derlen; + int i; + sk = sk_ASN1_TYPE_new_null(); + if (!sk) + goto bad; + if (section) { + if (!cnf) + goto bad; + sect = X509V3_get_section(cnf, (char *)section); + if (!sect) + goto bad; + for (i = 0; i < sk_CONF_VALUE_num(sect); i++) { + ASN1_TYPE *typ = + generate_v3(sk_CONF_VALUE_value(sect, i)->value, cnf, + depth + 1, perr); + if (!typ) + goto bad; + if (!sk_ASN1_TYPE_push(sk, typ)) + goto bad; + } + } + + /* + * Now we has a STACK of the components, convert to the correct form + */ + + if (utype == V_ASN1_SET) + derlen = i2d_ASN1_SET_ANY(sk, &der); + else + derlen = i2d_ASN1_SEQUENCE_ANY(sk, &der); + + if (derlen < 0) + goto bad; + + if (!(ret = ASN1_TYPE_new())) + goto bad; + + if (!(ret->value.asn1_string = ASN1_STRING_type_new(utype))) + goto bad; + + ret->type = utype; + + ret->value.asn1_string->data = der; + ret->value.asn1_string->length = derlen; + + der = NULL; + + bad: + + if (der) + OPENSSL_free(der); + + if (sk) + sk_ASN1_TYPE_pop_free(sk, ASN1_TYPE_free); + if (sect) + X509V3_section_free(cnf, sect); + + return ret; +} + +static int append_exp(tag_exp_arg *arg, int exp_tag, int exp_class, + int exp_constructed, int exp_pad, int imp_ok) +{ + tag_exp_type *exp_tmp; + /* Can only have IMPLICIT if permitted */ + if ((arg->imp_tag != -1) && !imp_ok) { + ASN1err(ASN1_F_APPEND_EXP, ASN1_R_ILLEGAL_IMPLICIT_TAG); + return 0; + } + + if (arg->exp_count == ASN1_FLAG_EXP_MAX) { + ASN1err(ASN1_F_APPEND_EXP, ASN1_R_DEPTH_EXCEEDED); + return 0; + } + + exp_tmp = &arg->exp_list[arg->exp_count++]; + + /* + * If IMPLICIT set tag to implicit value then reset implicit tag since it + * has been used. + */ + if (arg->imp_tag != -1) { + exp_tmp->exp_tag = arg->imp_tag; + exp_tmp->exp_class = arg->imp_class; + arg->imp_tag = -1; + arg->imp_class = -1; + } else { + exp_tmp->exp_tag = exp_tag; + exp_tmp->exp_class = exp_class; + } + exp_tmp->exp_constructed = exp_constructed; + exp_tmp->exp_pad = exp_pad; + + return 1; +} + +static int asn1_str2tag(const char *tagstr, int len) +{ + unsigned int i; + static const struct tag_name_st *tntmp, tnst[] = { + ASN1_GEN_STR("BOOL", V_ASN1_BOOLEAN), + ASN1_GEN_STR("BOOLEAN", V_ASN1_BOOLEAN), + ASN1_GEN_STR("NULL", V_ASN1_NULL), + ASN1_GEN_STR("INT", V_ASN1_INTEGER), + ASN1_GEN_STR("INTEGER", V_ASN1_INTEGER), + ASN1_GEN_STR("ENUM", V_ASN1_ENUMERATED), + ASN1_GEN_STR("ENUMERATED", V_ASN1_ENUMERATED), + ASN1_GEN_STR("OID", V_ASN1_OBJECT), + ASN1_GEN_STR("OBJECT", V_ASN1_OBJECT), + ASN1_GEN_STR("UTCTIME", V_ASN1_UTCTIME), + ASN1_GEN_STR("UTC", V_ASN1_UTCTIME), + ASN1_GEN_STR("GENERALIZEDTIME", V_ASN1_GENERALIZEDTIME), + ASN1_GEN_STR("GENTIME", V_ASN1_GENERALIZEDTIME), + ASN1_GEN_STR("OCT", V_ASN1_OCTET_STRING), + ASN1_GEN_STR("OCTETSTRING", V_ASN1_OCTET_STRING), + ASN1_GEN_STR("BITSTR", V_ASN1_BIT_STRING), + ASN1_GEN_STR("BITSTRING", V_ASN1_BIT_STRING), + ASN1_GEN_STR("UNIVERSALSTRING", V_ASN1_UNIVERSALSTRING), + ASN1_GEN_STR("UNIV", V_ASN1_UNIVERSALSTRING), + ASN1_GEN_STR("IA5", V_ASN1_IA5STRING), + ASN1_GEN_STR("IA5STRING", V_ASN1_IA5STRING), + ASN1_GEN_STR("UTF8", V_ASN1_UTF8STRING), + ASN1_GEN_STR("UTF8String", V_ASN1_UTF8STRING), + ASN1_GEN_STR("BMP", V_ASN1_BMPSTRING), + ASN1_GEN_STR("BMPSTRING", V_ASN1_BMPSTRING), + ASN1_GEN_STR("VISIBLESTRING", V_ASN1_VISIBLESTRING), + ASN1_GEN_STR("VISIBLE", V_ASN1_VISIBLESTRING), + ASN1_GEN_STR("PRINTABLESTRING", V_ASN1_PRINTABLESTRING), + ASN1_GEN_STR("PRINTABLE", V_ASN1_PRINTABLESTRING), + ASN1_GEN_STR("T61", V_ASN1_T61STRING), + ASN1_GEN_STR("T61STRING", V_ASN1_T61STRING), + ASN1_GEN_STR("TELETEXSTRING", V_ASN1_T61STRING), + ASN1_GEN_STR("GeneralString", V_ASN1_GENERALSTRING), + ASN1_GEN_STR("GENSTR", V_ASN1_GENERALSTRING), + ASN1_GEN_STR("NUMERIC", V_ASN1_NUMERICSTRING), + ASN1_GEN_STR("NUMERICSTRING", V_ASN1_NUMERICSTRING), + + /* Special cases */ + ASN1_GEN_STR("SEQUENCE", V_ASN1_SEQUENCE), + ASN1_GEN_STR("SEQ", V_ASN1_SEQUENCE), + ASN1_GEN_STR("SET", V_ASN1_SET), + /* type modifiers */ + /* Explicit tag */ + ASN1_GEN_STR("EXP", ASN1_GEN_FLAG_EXP), + ASN1_GEN_STR("EXPLICIT", ASN1_GEN_FLAG_EXP), + /* Implicit tag */ + ASN1_GEN_STR("IMP", ASN1_GEN_FLAG_IMP), + ASN1_GEN_STR("IMPLICIT", ASN1_GEN_FLAG_IMP), + /* OCTET STRING wrapper */ + ASN1_GEN_STR("OCTWRAP", ASN1_GEN_FLAG_OCTWRAP), + /* SEQUENCE wrapper */ + ASN1_GEN_STR("SEQWRAP", ASN1_GEN_FLAG_SEQWRAP), + /* SET wrapper */ + ASN1_GEN_STR("SETWRAP", ASN1_GEN_FLAG_SETWRAP), + /* BIT STRING wrapper */ + ASN1_GEN_STR("BITWRAP", ASN1_GEN_FLAG_BITWRAP), + ASN1_GEN_STR("FORM", ASN1_GEN_FLAG_FORMAT), + ASN1_GEN_STR("FORMAT", ASN1_GEN_FLAG_FORMAT), + }; + + if (len == -1) + len = strlen(tagstr); + + tntmp = tnst; + for (i = 0; i < sizeof(tnst) / sizeof(struct tag_name_st); i++, tntmp++) { + if ((len == tntmp->len) && !strncmp(tntmp->strnam, tagstr, len)) + return tntmp->tag; + } + + return -1; +} + +static ASN1_TYPE *asn1_str2type(const char *str, int format, int utype) +{ + ASN1_TYPE *atmp = NULL; + + CONF_VALUE vtmp; + + unsigned char *rdata; + long rdlen; + + int no_unused = 1; + + if (!(atmp = ASN1_TYPE_new())) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!str) + str = ""; + + switch (utype) { + + case V_ASN1_NULL: + if (str && *str) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_NULL_VALUE); + goto bad_form; + } + break; + + case V_ASN1_BOOLEAN: + if (format != ASN1_GEN_FORMAT_ASCII) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_NOT_ASCII_FORMAT); + goto bad_form; + } + vtmp.name = NULL; + vtmp.section = NULL; + vtmp.value = (char *)str; + if (!X509V3_get_value_bool(&vtmp, &atmp->value.boolean)) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BOOLEAN); + goto bad_str; + } + break; + + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + if (format != ASN1_GEN_FORMAT_ASCII) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_INTEGER_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_INTEGER); + goto bad_str; + } + break; + + case V_ASN1_OBJECT: + if (format != ASN1_GEN_FORMAT_ASCII) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_OBJECT_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_OBJECT); + goto bad_str; + } + break; + + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + if (format != ASN1_GEN_FORMAT_ASCII) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_TIME_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.asn1_string = ASN1_STRING_new())) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + goto bad_str; + } + if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + goto bad_str; + } + atmp->value.asn1_string->type = utype; + if (!ASN1_TIME_check(atmp->value.asn1_string)) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_TIME_VALUE); + goto bad_str; + } + + break; + + case V_ASN1_BMPSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_IA5STRING: + case V_ASN1_T61STRING: + case V_ASN1_UTF8STRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_NUMERICSTRING: + + if (format == ASN1_GEN_FORMAT_ASCII) + format = MBSTRING_ASC; + else if (format == ASN1_GEN_FORMAT_UTF8) + format = MBSTRING_UTF8; + else { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_FORMAT); + goto bad_form; + } + + if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, + -1, format, ASN1_tag2bit(utype)) <= 0) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + goto bad_str; + } + + break; + + case V_ASN1_BIT_STRING: + + case V_ASN1_OCTET_STRING: + + if (!(atmp->value.asn1_string = ASN1_STRING_new())) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ERR_R_MALLOC_FAILURE); + goto bad_form; + } + + if (format == ASN1_GEN_FORMAT_HEX) { + + if (!(rdata = string_to_hex((char *)str, &rdlen))) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_HEX); + goto bad_str; + } + + atmp->value.asn1_string->data = rdata; + atmp->value.asn1_string->length = rdlen; + atmp->value.asn1_string->type = utype; + + } else if (format == ASN1_GEN_FORMAT_ASCII) + ASN1_STRING_set(atmp->value.asn1_string, str, -1); + else if ((format == ASN1_GEN_FORMAT_BITLIST) + && (utype == V_ASN1_BIT_STRING)) { + if (!CONF_parse_list + (str, ',', 1, bitstr_cb, atmp->value.bit_string)) { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_LIST_ERROR); + goto bad_str; + } + no_unused = 0; + + } else { + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_ILLEGAL_BITSTRING_FORMAT); + goto bad_form; + } + + if ((utype == V_ASN1_BIT_STRING) && no_unused) { + atmp->value.asn1_string->flags + &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + atmp->value.asn1_string->flags |= ASN1_STRING_FLAG_BITS_LEFT; + } + + break; + + default: + ASN1err(ASN1_F_ASN1_STR2TYPE, ASN1_R_UNSUPPORTED_TYPE); + goto bad_str; + break; + } + + atmp->type = utype; + return atmp; + + bad_str: + ERR_add_error_data(2, "string=", str); + bad_form: + + ASN1_TYPE_free(atmp); + return NULL; + +} + +static int bitstr_cb(const char *elem, int len, void *bitstr) +{ + long bitnum; + char *eptr; + if (!elem) + return 0; + bitnum = strtoul(elem, &eptr, 10); + if (eptr && *eptr && (eptr != elem + len)) + return 0; + if (bitnum < 0) { + ASN1err(ASN1_F_BITSTR_CB, ASN1_R_INVALID_NUMBER); + return 0; + } + if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { + ASN1err(ASN1_F_BITSTR_CB, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} diff --git a/libs/openssl/crypto/asn1/asn1_lib.c b/libs/openssl/crypto/asn1/asn1_lib.c new file mode 100644 index 00000000..874b1af8 --- /dev/null +++ b/libs/openssl/crypto/asn1/asn1_lib.c @@ -0,0 +1,479 @@ +/* crypto/asn1/asn1_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include + +static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, + long max); +static void asn1_put_length(unsigned char **pp, int length); +const char ASN1_version[] = "ASN.1" OPENSSL_VERSION_PTEXT; + +static int _asn1_check_infinite_end(const unsigned char **p, long len) +{ + /* + * If there is 0 or 1 byte left, the length check should pick things up + */ + if (len <= 0) + return (1); + else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) { + (*p) += 2; + return (1); + } + return (0); +} + +int ASN1_check_infinite_end(unsigned char **p, long len) +{ + return _asn1_check_infinite_end((const unsigned char **)p, len); +} + +int ASN1_const_check_infinite_end(const unsigned char **p, long len) +{ + return _asn1_check_infinite_end(p, len); +} + +int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, + int *pclass, long omax) +{ + int i, ret; + long l; + const unsigned char *p = *pp; + int tag, xclass, inf; + long max = omax; + + if (!max) + goto err; + ret = (*p & V_ASN1_CONSTRUCTED); + xclass = (*p & V_ASN1_PRIVATE); + i = *p & V_ASN1_PRIMITIVE_TAG; + if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */ + p++; + if (--max == 0) + goto err; + l = 0; + while (*p & 0x80) { + l <<= 7L; + l |= *(p++) & 0x7f; + if (--max == 0) + goto err; + if (l > (INT_MAX >> 7L)) + goto err; + } + l <<= 7L; + l |= *(p++) & 0x7f; + tag = (int)l; + if (--max == 0) + goto err; + } else { + tag = i; + p++; + if (--max == 0) + goto err; + } + *ptag = tag; + *pclass = xclass; + if (!asn1_get_length(&p, &inf, plength, max)) + goto err; + + if (inf && !(ret & V_ASN1_CONSTRUCTED)) + goto err; + +#if 0 + fprintf(stderr, "p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n", + (int)p, *plength, omax, (int)*pp, (int)(p + *plength), + (int)(omax + *pp)); + +#endif + if (*plength > (omax - (p - *pp))) { + ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG); + /* + * Set this so that even if things are not long enough the values are + * set correctly + */ + ret |= 0x80; + } + *pp = p; + return (ret | inf); + err: + ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG); + return (0x80); +} + +static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, + long max) +{ + const unsigned char *p = *pp; + unsigned long ret = 0; + unsigned long i; + + if (max-- < 1) + return 0; + if (*p == 0x80) { + *inf = 1; + ret = 0; + p++; + } else { + *inf = 0; + i = *p & 0x7f; + if (*(p++) & 0x80) { + if (i > sizeof(ret) || max < (long)i) + return 0; + while (i-- > 0) { + ret <<= 8L; + ret |= *(p++); + } + } else + ret = i; + } + if (ret > LONG_MAX) + return 0; + *pp = p; + *rl = (long)ret; + return 1; +} + +/* + * class 0 is constructed constructed == 2 for indefinite length constructed + */ +void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, + int xclass) +{ + unsigned char *p = *pp; + int i, ttag; + + i = (constructed) ? V_ASN1_CONSTRUCTED : 0; + i |= (xclass & V_ASN1_PRIVATE); + if (tag < 31) + *(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG); + else { + *(p++) = i | V_ASN1_PRIMITIVE_TAG; + for (i = 0, ttag = tag; ttag > 0; i++) + ttag >>= 7; + ttag = i; + while (i-- > 0) { + p[i] = tag & 0x7f; + if (i != (ttag - 1)) + p[i] |= 0x80; + tag >>= 7; + } + p += ttag; + } + if (constructed == 2) + *(p++) = 0x80; + else + asn1_put_length(&p, length); + *pp = p; +} + +int ASN1_put_eoc(unsigned char **pp) +{ + unsigned char *p = *pp; + *p++ = 0; + *p++ = 0; + *pp = p; + return 2; +} + +static void asn1_put_length(unsigned char **pp, int length) +{ + unsigned char *p = *pp; + int i, l; + if (length <= 127) + *(p++) = (unsigned char)length; + else { + l = length; + for (i = 0; l > 0; i++) + l >>= 8; + *(p++) = i | 0x80; + l = i; + while (i-- > 0) { + p[i] = length & 0xff; + length >>= 8; + } + p += l; + } + *pp = p; +} + +int ASN1_object_size(int constructed, int length, int tag) +{ + int ret; + + ret = length; + ret++; + if (tag >= 31) { + while (tag > 0) { + tag >>= 7; + ret++; + } + } + if (constructed == 2) + return ret + 3; + ret++; + if (length > 127) { + while (length > 0) { + length >>= 8; + ret++; + } + } + return (ret); +} + +static int _asn1_Finish(ASN1_const_CTX *c) +{ + if ((c->inf == (1 | V_ASN1_CONSTRUCTED)) && (!c->eos)) { + if (!ASN1_const_check_infinite_end(&c->p, c->slen)) { + c->error = ERR_R_MISSING_ASN1_EOS; + return (0); + } + } + if (((c->slen != 0) && !(c->inf & 1)) || ((c->slen < 0) && (c->inf & 1))) { + c->error = ERR_R_ASN1_LENGTH_MISMATCH; + return (0); + } + return (1); +} + +int asn1_Finish(ASN1_CTX *c) +{ + return _asn1_Finish((ASN1_const_CTX *)c); +} + +int asn1_const_Finish(ASN1_const_CTX *c) +{ + return _asn1_Finish(c); +} + +int asn1_GetSequence(ASN1_const_CTX *c, long *length) +{ + const unsigned char *q; + + q = c->p; + c->inf = ASN1_get_object(&(c->p), &(c->slen), &(c->tag), &(c->xclass), + *length); + if (c->inf & 0x80) { + c->error = ERR_R_BAD_GET_ASN1_OBJECT_CALL; + return (0); + } + if (c->tag != V_ASN1_SEQUENCE) { + c->error = ERR_R_EXPECTING_AN_ASN1_SEQUENCE; + return (0); + } + (*length) -= (c->p - q); + if (c->max && (*length < 0)) { + c->error = ERR_R_ASN1_LENGTH_MISMATCH; + return (0); + } + if (c->inf == (1 | V_ASN1_CONSTRUCTED)) + c->slen = *length + *(c->pp) - c->p; + c->eos = 0; + return (1); +} + +int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str) +{ + if (str == NULL) + return 0; + dst->type = str->type; + if (!ASN1_STRING_set(dst, str->data, str->length)) + return 0; + dst->flags = str->flags; + return 1; +} + +ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str) +{ + ASN1_STRING *ret; + if (!str) + return NULL; + ret = ASN1_STRING_new(); + if (!ret) + return NULL; + if (!ASN1_STRING_copy(ret, str)) { + ASN1_STRING_free(ret); + return NULL; + } + return ret; +} + +int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len) +{ + unsigned char *c; + const char *data = _data; + + if (len < 0) { + if (data == NULL) + return (0); + else + len = strlen(data); + } + if ((str->length < len) || (str->data == NULL)) { + c = str->data; + if (c == NULL) + str->data = OPENSSL_malloc(len + 1); + else + str->data = OPENSSL_realloc(c, len + 1); + + if (str->data == NULL) { + ASN1err(ASN1_F_ASN1_STRING_SET, ERR_R_MALLOC_FAILURE); + str->data = c; + return (0); + } + } + str->length = len; + if (data != NULL) { + memcpy(str->data, data, len); + /* an allowance for strings :-) */ + str->data[len] = '\0'; + } + return (1); +} + +void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len) +{ + if (str->data) + OPENSSL_free(str->data); + str->data = data; + str->length = len; +} + +ASN1_STRING *ASN1_STRING_new(void) +{ + return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING)); +} + +ASN1_STRING *ASN1_STRING_type_new(int type) +{ + ASN1_STRING *ret; + + ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING)); + if (ret == NULL) { + ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->length = 0; + ret->type = type; + ret->data = NULL; + ret->flags = 0; + return (ret); +} + +void ASN1_STRING_free(ASN1_STRING *a) +{ + if (a == NULL) + return; + if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF)) + OPENSSL_free(a->data); + OPENSSL_free(a); +} + +void ASN1_STRING_clear_free(ASN1_STRING *a) +{ + if (a && a->data && !(a->flags & ASN1_STRING_FLAG_NDEF)) + OPENSSL_cleanse(a->data, a->length); + ASN1_STRING_free(a); +} + +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) +{ + int i; + + i = (a->length - b->length); + if (i == 0) { + i = memcmp(a->data, b->data, a->length); + if (i == 0) + return (a->type - b->type); + else + return (i); + } else + return (i); +} + +void asn1_add_error(const unsigned char *address, int offset) +{ + char buf1[DECIMAL_SIZE(address) + 1], buf2[DECIMAL_SIZE(offset) + 1]; + + BIO_snprintf(buf1, sizeof buf1, "%lu", (unsigned long)address); + BIO_snprintf(buf2, sizeof buf2, "%d", offset); + ERR_add_error_data(4, "address=", buf1, " offset=", buf2); +} + +int ASN1_STRING_length(const ASN1_STRING *x) +{ + return M_ASN1_STRING_length(x); +} + +void ASN1_STRING_length_set(ASN1_STRING *x, int len) +{ + M_ASN1_STRING_length_set(x, len); + return; +} + +int ASN1_STRING_type(ASN1_STRING *x) +{ + return M_ASN1_STRING_type(x); +} + +unsigned char *ASN1_STRING_data(ASN1_STRING *x) +{ + return M_ASN1_STRING_data(x); +} diff --git a/libs/openssl/crypto/asn1/asn1_locl.h b/libs/openssl/crypto/asn1/asn1_locl.h new file mode 100644 index 00000000..9f5ed847 --- /dev/null +++ b/libs/openssl/crypto/asn1/asn1_locl.h @@ -0,0 +1,132 @@ +/* asn1t.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Internal ASN1 structures and functions: not for application use */ + +/* ASN1 print context structure */ + +struct asn1_pctx_st { + unsigned long flags; + unsigned long nm_flags; + unsigned long cert_flags; + unsigned long oid_flags; + unsigned long str_flags; +} /* ASN1_PCTX */ ; + +/* ASN1 public key method structure */ + +struct evp_pkey_asn1_method_st { + int pkey_id; + int pkey_base_id; + unsigned long pkey_flags; + char *pem_str; + char *info; + int (*pub_decode) (EVP_PKEY *pk, X509_PUBKEY *pub); + int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk); + int (*pub_cmp) (const EVP_PKEY *a, const EVP_PKEY *b); + int (*pub_print) (BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*priv_decode) (EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf); + int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk); + int (*priv_print) (BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*pkey_size) (const EVP_PKEY *pk); + int (*pkey_bits) (const EVP_PKEY *pk); + int (*param_decode) (EVP_PKEY *pkey, + const unsigned char **pder, int derlen); + int (*param_encode) (const EVP_PKEY *pkey, unsigned char **pder); + int (*param_missing) (const EVP_PKEY *pk); + int (*param_copy) (EVP_PKEY *to, const EVP_PKEY *from); + int (*param_cmp) (const EVP_PKEY *a, const EVP_PKEY *b); + int (*param_print) (BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*sig_print) (BIO *out, + const X509_ALGOR *sigalg, const ASN1_STRING *sig, + int indent, ASN1_PCTX *pctx); + void (*pkey_free) (EVP_PKEY *pkey); + int (*pkey_ctrl) (EVP_PKEY *pkey, int op, long arg1, void *arg2); + /* Legacy functions for old PEM */ + int (*old_priv_decode) (EVP_PKEY *pkey, + const unsigned char **pder, int derlen); + int (*old_priv_encode) (const EVP_PKEY *pkey, unsigned char **pder); + /* Custom ASN1 signature verification */ + int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey); + int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *alg1, X509_ALGOR *alg2, + ASN1_BIT_STRING *sig); +} /* EVP_PKEY_ASN1_METHOD */ ; + +/* + * Method to handle CRL access. In general a CRL could be very large (several + * Mb) and can consume large amounts of resources if stored in memory by + * multiple processes. This method allows general CRL operations to be + * redirected to more efficient callbacks: for example a CRL entry database. + */ + +#define X509_CRL_METHOD_DYNAMIC 1 + +struct x509_crl_method_st { + int flags; + int (*crl_init) (X509_CRL *crl); + int (*crl_free) (X509_CRL *crl); + int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret, + ASN1_INTEGER *ser, X509_NAME *issuer); + int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk); +}; diff --git a/libs/openssl/crypto/asn1/asn1_mac.h b/libs/openssl/crypto/asn1/asn1_mac.h new file mode 100644 index 00000000..abc6dc35 --- /dev/null +++ b/libs/openssl/crypto/asn1/asn1_mac.h @@ -0,0 +1,579 @@ +/* crypto/asn1/asn1_mac.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ASN1_MAC_H +# define HEADER_ASN1_MAC_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef ASN1_MAC_ERR_LIB +# define ASN1_MAC_ERR_LIB ERR_LIB_ASN1 +# endif + +# define ASN1_MAC_H_err(f,r,line) \ + ERR_PUT_error(ASN1_MAC_ERR_LIB,(f),(r),__FILE__,(line)) + +# define M_ASN1_D2I_vars(a,type,func) \ + ASN1_const_CTX c; \ + type ret=NULL; \ + \ + c.pp=(const unsigned char **)pp; \ + c.q= *(const unsigned char **)pp; \ + c.error=ERR_R_NESTED_ASN1_ERROR; \ + if ((a == NULL) || ((*a) == NULL)) \ + { if ((ret=(type)func()) == NULL) \ + { c.line=__LINE__; goto err; } } \ + else ret=(*a); + +# define M_ASN1_D2I_Init() \ + c.p= *(const unsigned char **)pp; \ + c.max=(length == 0)?0:(c.p+length); + +# define M_ASN1_D2I_Finish_2(a) \ + if (!asn1_const_Finish(&c)) \ + { c.line=__LINE__; goto err; } \ + *(const unsigned char **)pp=c.p; \ + if (a != NULL) (*a)=ret; \ + return(ret); + +# define M_ASN1_D2I_Finish(a,func,e) \ + M_ASN1_D2I_Finish_2(a); \ +err:\ + ASN1_MAC_H_err((e),c.error,c.line); \ + asn1_add_error(*(const unsigned char **)pp,(int)(c.q- *pp)); \ + if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \ + return(NULL) + +# define M_ASN1_D2I_start_sequence() \ + if (!asn1_GetSequence(&c,&length)) \ + { c.line=__LINE__; goto err; } +/* Begin reading ASN1 without a surrounding sequence */ +# define M_ASN1_D2I_begin() \ + c.slen = length; + +/* End reading ASN1 with no check on length */ +# define M_ASN1_D2I_Finish_nolen(a, func, e) \ + *pp=c.p; \ + if (a != NULL) (*a)=ret; \ + return(ret); \ +err:\ + ASN1_MAC_H_err((e),c.error,c.line); \ + asn1_add_error(*pp,(int)(c.q- *pp)); \ + if ((ret != NULL) && ((a == NULL) || (*a != ret))) func(ret); \ + return(NULL) + +# define M_ASN1_D2I_end_sequence() \ + (((c.inf&1) == 0)?(c.slen <= 0): \ + (c.eos=ASN1_const_check_infinite_end(&c.p,c.slen))) + +/* Don't use this with d2i_ASN1_BOOLEAN() */ +# define M_ASN1_D2I_get(b, func) \ + c.q=c.p; \ + if (func(&(b),&c.p,c.slen) == NULL) \ + {c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +/* Don't use this with d2i_ASN1_BOOLEAN() */ +# define M_ASN1_D2I_get_x(type,b,func) \ + c.q=c.p; \ + if (((D2I_OF(type))func)(&(b),&c.p,c.slen) == NULL) \ + {c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +/* use this instead () */ +# define M_ASN1_D2I_get_int(b,func) \ + c.q=c.p; \ + if (func(&(b),&c.p,c.slen) < 0) \ + {c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +# define M_ASN1_D2I_get_opt(b,func,type) \ + if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \ + == (V_ASN1_UNIVERSAL|(type)))) \ + { \ + M_ASN1_D2I_get(b,func); \ + } + +# define M_ASN1_D2I_get_int_opt(b,func,type) \ + if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) \ + == (V_ASN1_UNIVERSAL|(type)))) \ + { \ + M_ASN1_D2I_get_int(b,func); \ + } + +# define M_ASN1_D2I_get_imp(b,func, type) \ + M_ASN1_next=(_tmp& V_ASN1_CONSTRUCTED)|type; \ + c.q=c.p; \ + if (func(&(b),&c.p,c.slen) == NULL) \ + {c.line=__LINE__; M_ASN1_next_prev = _tmp; goto err; } \ + c.slen-=(c.p-c.q);\ + M_ASN1_next_prev=_tmp; + +# define M_ASN1_D2I_get_IMP_opt(b,func,tag,type) \ + if ((c.slen != 0) && ((M_ASN1_next & (~V_ASN1_CONSTRUCTED)) == \ + (V_ASN1_CONTEXT_SPECIFIC|(tag)))) \ + { \ + unsigned char _tmp = M_ASN1_next; \ + M_ASN1_D2I_get_imp(b,func, type);\ + } + +# define M_ASN1_D2I_get_set(r,func,free_func) \ + M_ASN1_D2I_get_imp_set(r,func,free_func, \ + V_ASN1_SET,V_ASN1_UNIVERSAL); + +# define M_ASN1_D2I_get_set_type(type,r,func,free_func) \ + M_ASN1_D2I_get_imp_set_type(type,r,func,free_func, \ + V_ASN1_SET,V_ASN1_UNIVERSAL); + +# define M_ASN1_D2I_get_set_opt(r,func,free_func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SET)))\ + { M_ASN1_D2I_get_set(r,func,free_func); } + +# define M_ASN1_D2I_get_set_opt_type(type,r,func,free_func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SET)))\ + { M_ASN1_D2I_get_set_type(type,r,func,free_func); } + +# define M_ASN1_I2D_len_SET_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_len_SET(a,f); + +# define M_ASN1_I2D_put_SET_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_put_SET(a,f); + +# define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_put_SEQUENCE(a,f); + +# define M_ASN1_I2D_put_SEQUENCE_opt_type(type,a,f) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + M_ASN1_I2D_put_SEQUENCE_type(type,a,f); + +# define M_ASN1_D2I_get_IMP_set_opt(b,func,free_func,tag) \ + if ((c.slen != 0) && \ + (M_ASN1_next == \ + (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\ + { \ + M_ASN1_D2I_get_imp_set(b,func,free_func,\ + tag,V_ASN1_CONTEXT_SPECIFIC); \ + } + +# define M_ASN1_D2I_get_IMP_set_opt_type(type,b,func,free_func,tag) \ + if ((c.slen != 0) && \ + (M_ASN1_next == \ + (V_ASN1_CONTEXT_SPECIFIC|V_ASN1_CONSTRUCTED|(tag))))\ + { \ + M_ASN1_D2I_get_imp_set_type(type,b,func,free_func,\ + tag,V_ASN1_CONTEXT_SPECIFIC); \ + } + +# define M_ASN1_D2I_get_seq(r,func,free_func) \ + M_ASN1_D2I_get_imp_set(r,func,free_func,\ + V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL); + +# define M_ASN1_D2I_get_seq_type(type,r,func,free_func) \ + M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\ + V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL) + +# define M_ASN1_D2I_get_seq_opt(r,func,free_func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\ + { M_ASN1_D2I_get_seq(r,func,free_func); } + +# define M_ASN1_D2I_get_seq_opt_type(type,r,func,free_func) \ + if ((c.slen != 0) && (M_ASN1_next == (V_ASN1_UNIVERSAL| \ + V_ASN1_CONSTRUCTED|V_ASN1_SEQUENCE)))\ + { M_ASN1_D2I_get_seq_type(type,r,func,free_func); } + +# define M_ASN1_D2I_get_IMP_set(r,func,free_func,x) \ + M_ASN1_D2I_get_imp_set(r,func,free_func,\ + x,V_ASN1_CONTEXT_SPECIFIC); + +# define M_ASN1_D2I_get_IMP_set_type(type,r,func,free_func,x) \ + M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,\ + x,V_ASN1_CONTEXT_SPECIFIC); + +# define M_ASN1_D2I_get_imp_set(r,func,free_func,a,b) \ + c.q=c.p; \ + if (d2i_ASN1_SET(&(r),&c.p,c.slen,(char *(*)())func,\ + (void (*)())free_func,a,b) == NULL) \ + { c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +# define M_ASN1_D2I_get_imp_set_type(type,r,func,free_func,a,b) \ + c.q=c.p; \ + if (d2i_ASN1_SET_OF_##type(&(r),&c.p,c.slen,func,\ + free_func,a,b) == NULL) \ + { c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +# define M_ASN1_D2I_get_set_strings(r,func,a,b) \ + c.q=c.p; \ + if (d2i_ASN1_STRING_SET(&(r),&c.p,c.slen,a,b) == NULL) \ + { c.line=__LINE__; goto err; } \ + c.slen-=(c.p-c.q); + +# define M_ASN1_D2I_get_EXP_opt(r,func,tag) \ + if ((c.slen != 0L) && (M_ASN1_next == \ + (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ + { \ + int Tinf,Ttag,Tclass; \ + long Tlen; \ + \ + c.q=c.p; \ + Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ + if (Tinf & 0x80) \ + { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ + c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ + Tlen = c.slen - (c.p - c.q) - 2; \ + if (func(&(r),&c.p,Tlen) == NULL) \ + { c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ + Tlen = c.slen - (c.p - c.q); \ + if(!ASN1_const_check_infinite_end(&c.p, Tlen)) \ + { c.error=ERR_R_MISSING_ASN1_EOS; \ + c.line=__LINE__; goto err; } \ + }\ + c.slen-=(c.p-c.q); \ + } + +# define M_ASN1_D2I_get_EXP_set_opt(r,func,free_func,tag,b) \ + if ((c.slen != 0) && (M_ASN1_next == \ + (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ + { \ + int Tinf,Ttag,Tclass; \ + long Tlen; \ + \ + c.q=c.p; \ + Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ + if (Tinf & 0x80) \ + { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ + c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ + Tlen = c.slen - (c.p - c.q) - 2; \ + if (d2i_ASN1_SET(&(r),&c.p,Tlen,(char *(*)())func, \ + (void (*)())free_func, \ + b,V_ASN1_UNIVERSAL) == NULL) \ + { c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ + Tlen = c.slen - (c.p - c.q); \ + if(!ASN1_check_infinite_end(&c.p, Tlen)) \ + { c.error=ERR_R_MISSING_ASN1_EOS; \ + c.line=__LINE__; goto err; } \ + }\ + c.slen-=(c.p-c.q); \ + } + +# define M_ASN1_D2I_get_EXP_set_opt_type(type,r,func,free_func,tag,b) \ + if ((c.slen != 0) && (M_ASN1_next == \ + (V_ASN1_CONSTRUCTED|V_ASN1_CONTEXT_SPECIFIC|tag))) \ + { \ + int Tinf,Ttag,Tclass; \ + long Tlen; \ + \ + c.q=c.p; \ + Tinf=ASN1_get_object(&c.p,&Tlen,&Ttag,&Tclass,c.slen); \ + if (Tinf & 0x80) \ + { c.error=ERR_R_BAD_ASN1_OBJECT_HEADER; \ + c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) \ + Tlen = c.slen - (c.p - c.q) - 2; \ + if (d2i_ASN1_SET_OF_##type(&(r),&c.p,Tlen,func, \ + free_func,b,V_ASN1_UNIVERSAL) == NULL) \ + { c.line=__LINE__; goto err; } \ + if (Tinf == (V_ASN1_CONSTRUCTED+1)) { \ + Tlen = c.slen - (c.p - c.q); \ + if(!ASN1_check_infinite_end(&c.p, Tlen)) \ + { c.error=ERR_R_MISSING_ASN1_EOS; \ + c.line=__LINE__; goto err; } \ + }\ + c.slen-=(c.p-c.q); \ + } + +/* New macros */ +# define M_ASN1_New_Malloc(ret,type) \ + if ((ret=(type *)OPENSSL_malloc(sizeof(type))) == NULL) \ + { c.line=__LINE__; goto err2; } + +# define M_ASN1_New(arg,func) \ + if (((arg)=func()) == NULL) return(NULL) + +# define M_ASN1_New_Error(a) \ +/*- err: ASN1_MAC_H_err((a),ERR_R_NESTED_ASN1_ERROR,c.line); \ + return(NULL);*/ \ + err2: ASN1_MAC_H_err((a),ERR_R_MALLOC_FAILURE,c.line); \ + return(NULL) + +/* + * BIG UGLY WARNING! This is so damn ugly I wanna puke. Unfortunately, some + * macros that use ASN1_const_CTX still insist on writing in the input + * stream. ARGH! ARGH! ARGH! Let's get rid of this macro package. Please? -- + * Richard Levitte + */ +# define M_ASN1_next (*((unsigned char *)(c.p))) +# define M_ASN1_next_prev (*((unsigned char *)(c.q))) + +/*************************************************/ + +# define M_ASN1_I2D_vars(a) int r=0,ret=0; \ + unsigned char *p; \ + if (a == NULL) return(0) + +/* Length Macros */ +# define M_ASN1_I2D_len(a,f) ret+=f(a,NULL) +# define M_ASN1_I2D_len_IMP_opt(a,f) if (a != NULL) M_ASN1_I2D_len(a,f) + +# define M_ASN1_I2D_len_SET(a,f) \ + ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET); + +# define M_ASN1_I2D_len_SET_type(type,a,f) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SET, \ + V_ASN1_UNIVERSAL,IS_SET); + +# define M_ASN1_I2D_len_SEQUENCE(a,f) \ + ret+=i2d_ASN1_SET(a,NULL,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \ + IS_SEQUENCE); + +# define M_ASN1_I2D_len_SEQUENCE_type(type,a,f) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,V_ASN1_SEQUENCE, \ + V_ASN1_UNIVERSAL,IS_SEQUENCE) + +# define M_ASN1_I2D_len_SEQUENCE_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_len_SEQUENCE(a,f); + +# define M_ASN1_I2D_len_SEQUENCE_opt_type(type,a,f) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + M_ASN1_I2D_len_SEQUENCE_type(type,a,f); + +# define M_ASN1_I2D_len_IMP_SET(a,f,x) \ + ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET); + +# define M_ASN1_I2D_len_IMP_SET_type(type,a,f,x) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ + V_ASN1_CONTEXT_SPECIFIC,IS_SET); + +# define M_ASN1_I2D_len_IMP_SET_opt(a,f,x) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SET); + +# define M_ASN1_I2D_len_IMP_SET_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ + V_ASN1_CONTEXT_SPECIFIC,IS_SET); + +# define M_ASN1_I2D_len_IMP_SEQUENCE(a,f,x) \ + ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); + +# define M_ASN1_I2D_len_IMP_SEQUENCE_opt(a,f,x) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + ret+=i2d_ASN1_SET(a,NULL,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); + +# define M_ASN1_I2D_len_IMP_SEQUENCE_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + ret+=i2d_ASN1_SET_OF_##type(a,NULL,f,x, \ + V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); + +# define M_ASN1_I2D_len_EXP_opt(a,f,mtag,v) \ + if (a != NULL)\ + { \ + v=f(a,NULL); \ + ret+=ASN1_object_size(1,v,mtag); \ + } + +# define M_ASN1_I2D_len_EXP_SET_opt(a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_num(a) != 0))\ + { \ + v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL,IS_SET); \ + ret+=ASN1_object_size(1,v,mtag); \ + } + +# define M_ASN1_I2D_len_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_num(a) != 0))\ + { \ + v=i2d_ASN1_SET(a,NULL,f,tag,V_ASN1_UNIVERSAL, \ + IS_SEQUENCE); \ + ret+=ASN1_object_size(1,v,mtag); \ + } + +# define M_ASN1_I2D_len_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_##type##_num(a) != 0))\ + { \ + v=i2d_ASN1_SET_OF_##type(a,NULL,f,tag, \ + V_ASN1_UNIVERSAL, \ + IS_SEQUENCE); \ + ret+=ASN1_object_size(1,v,mtag); \ + } + +/* Put Macros */ +# define M_ASN1_I2D_put(a,f) f(a,&p) + +# define M_ASN1_I2D_put_IMP_opt(a,f,t) \ + if (a != NULL) \ + { \ + unsigned char *q=p; \ + f(a,&p); \ + *q=(V_ASN1_CONTEXT_SPECIFIC|t|(*q&V_ASN1_CONSTRUCTED));\ + } + +# define M_ASN1_I2D_put_SET(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SET,\ + V_ASN1_UNIVERSAL,IS_SET) +# define M_ASN1_I2D_put_SET_type(type,a,f) \ + i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SET,V_ASN1_UNIVERSAL,IS_SET) +# define M_ASN1_I2D_put_IMP_SET(a,f,x) i2d_ASN1_SET(a,&p,f,x,\ + V_ASN1_CONTEXT_SPECIFIC,IS_SET) +# define M_ASN1_I2D_put_IMP_SET_type(type,a,f,x) \ + i2d_ASN1_SET_OF_##type(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC,IS_SET) +# define M_ASN1_I2D_put_IMP_SEQUENCE(a,f,x) i2d_ASN1_SET(a,&p,f,x,\ + V_ASN1_CONTEXT_SPECIFIC,IS_SEQUENCE) + +# define M_ASN1_I2D_put_SEQUENCE(a,f) i2d_ASN1_SET(a,&p,f,V_ASN1_SEQUENCE,\ + V_ASN1_UNIVERSAL,IS_SEQUENCE) + +# define M_ASN1_I2D_put_SEQUENCE_type(type,a,f) \ + i2d_ASN1_SET_OF_##type(a,&p,f,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL, \ + IS_SEQUENCE) + +# define M_ASN1_I2D_put_SEQUENCE_opt(a,f) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + M_ASN1_I2D_put_SEQUENCE(a,f); + +# define M_ASN1_I2D_put_IMP_SET_opt(a,f,x) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SET); } + +# define M_ASN1_I2D_put_IMP_SET_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + { i2d_ASN1_SET_OF_##type(a,&p,f,x, \ + V_ASN1_CONTEXT_SPECIFIC, \ + IS_SET); } + +# define M_ASN1_I2D_put_IMP_SEQUENCE_opt(a,f,x) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + { i2d_ASN1_SET(a,&p,f,x,V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); } + +# define M_ASN1_I2D_put_IMP_SEQUENCE_opt_type(type,a,f,x) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + { i2d_ASN1_SET_OF_##type(a,&p,f,x, \ + V_ASN1_CONTEXT_SPECIFIC, \ + IS_SEQUENCE); } + +# define M_ASN1_I2D_put_EXP_opt(a,f,tag,v) \ + if (a != NULL) \ + { \ + ASN1_put_object(&p,1,v,tag,V_ASN1_CONTEXT_SPECIFIC); \ + f(a,&p); \ + } + +# define M_ASN1_I2D_put_EXP_SET_opt(a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + { \ + ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ + i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SET); \ + } + +# define M_ASN1_I2D_put_EXP_SEQUENCE_opt(a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_num(a) != 0)) \ + { \ + ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ + i2d_ASN1_SET(a,&p,f,tag,V_ASN1_UNIVERSAL,IS_SEQUENCE); \ + } + +# define M_ASN1_I2D_put_EXP_SEQUENCE_opt_type(type,a,f,mtag,tag,v) \ + if ((a != NULL) && (sk_##type##_num(a) != 0)) \ + { \ + ASN1_put_object(&p,1,v,mtag,V_ASN1_CONTEXT_SPECIFIC); \ + i2d_ASN1_SET_OF_##type(a,&p,f,tag,V_ASN1_UNIVERSAL, \ + IS_SEQUENCE); \ + } + +# define M_ASN1_I2D_seq_total() \ + r=ASN1_object_size(1,ret,V_ASN1_SEQUENCE); \ + if (pp == NULL) return(r); \ + p= *pp; \ + ASN1_put_object(&p,1,ret,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL) + +# define M_ASN1_I2D_INF_seq_start(tag,ctx) \ + *(p++)=(V_ASN1_CONSTRUCTED|(tag)|(ctx)); \ + *(p++)=0x80 + +# define M_ASN1_I2D_INF_seq_end() *(p++)=0x00; *(p++)=0x00 + +# define M_ASN1_I2D_finish() *pp=p; \ + return(r); + +int asn1_GetSequence(ASN1_const_CTX *c, long *length); +void asn1_add_error(const unsigned char *address, int offset); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/asn1/asn1_par.c b/libs/openssl/crypto/asn1/asn1_par.c new file mode 100644 index 00000000..e85e3398 --- /dev/null +++ b/libs/openssl/crypto/asn1/asn1_par.c @@ -0,0 +1,424 @@ +/* crypto/asn1/asn1_par.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +#ifndef ASN1_PARSE_MAXDEPTH +#define ASN1_PARSE_MAXDEPTH 128 +#endif + +static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, + int indent); +static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, + int offset, int depth, int indent, int dump); +static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed, + int indent) +{ + static const char fmt[] = "%-18s"; + char str[128]; + const char *p; + + if (constructed & V_ASN1_CONSTRUCTED) + p = "cons: "; + else + p = "prim: "; + if (BIO_write(bp, p, 6) < 6) + goto err; + BIO_indent(bp, indent, 128); + + p = str; + if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE) + BIO_snprintf(str, sizeof str, "priv [ %d ] ", tag); + else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC) + BIO_snprintf(str, sizeof str, "cont [ %d ]", tag); + else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION) + BIO_snprintf(str, sizeof str, "appl [ %d ]", tag); + else if (tag > 30) + BIO_snprintf(str, sizeof str, "", tag); + else + p = ASN1_tag2str(tag); + + if (BIO_printf(bp, fmt, p) <= 0) + goto err; + return (1); + err: + return (0); +} + +int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent) +{ + return (asn1_parse2(bp, &pp, len, 0, 0, indent, 0)); +} + +int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, + int dump) +{ + return (asn1_parse2(bp, &pp, len, 0, 0, indent, dump)); +} + +static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, + int offset, int depth, int indent, int dump) +{ + const unsigned char *p, *ep, *tot, *op, *opp; + long len; + int tag, xclass, ret = 0; + int nl, hl, j, r; + ASN1_OBJECT *o = NULL; + ASN1_OCTET_STRING *os = NULL; + /* ASN1_BMPSTRING *bmp=NULL; */ + int dump_indent; + +#if 0 + dump_indent = indent; +#else + dump_indent = 6; /* Because we know BIO_dump_indent() */ +#endif + + if (depth > ASN1_PARSE_MAXDEPTH) { + BIO_puts(bp, "BAD RECURSION DEPTH\n"); + return 0; + } + + p = *pp; + tot = p + length; + op = p - 1; + while ((p < tot) && (op < p)) { + op = p; + j = ASN1_get_object(&p, &len, &tag, &xclass, length); +#ifdef LINT + j = j; +#endif + if (j & 0x80) { + if (BIO_write(bp, "Error in encoding\n", 18) <= 0) + goto end; + ret = 0; + goto end; + } + hl = (p - op); + length -= hl; + /* + * if j == 0x21 it is a constructed indefinite length object + */ + if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp)) + <= 0) + goto end; + + if (j != (V_ASN1_CONSTRUCTED | 1)) { + if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ", + depth, (long)hl, len) <= 0) + goto end; + } else { + if (BIO_printf(bp, "d=%-2d hl=%ld l=inf ", depth, (long)hl) <= 0) + goto end; + } + if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0)) + goto end; + if (j & V_ASN1_CONSTRUCTED) { + const unsigned char *sp; + + ep = p + len; + if (BIO_write(bp, "\n", 1) <= 0) + goto end; + if (len > length) { + BIO_printf(bp, "length is greater than %ld\n", length); + ret = 0; + goto end; + } + if ((j == 0x21) && (len == 0)) { + sp = p; + for (;;) { + r = asn1_parse2(bp, &p, (long)(tot - p), + offset + (p - *pp), depth + 1, + indent, dump); + if (r == 0) { + ret = 0; + goto end; + } + if ((r == 2) || (p >= tot)) { + len = p - sp; + break; + } + } + } else { + long tmp = len; + + while (p < ep) { + sp = p; + r = asn1_parse2(bp, &p, tmp, offset + (p - *pp), depth + 1, + indent, dump); + if (r == 0) { + ret = 0; + goto end; + } + tmp -= p - sp; + } + } + } else if (xclass != 0) { + p += len; + if (BIO_write(bp, "\n", 1) <= 0) + goto end; + } else { + nl = 0; + if ((tag == V_ASN1_PRINTABLESTRING) || + (tag == V_ASN1_T61STRING) || + (tag == V_ASN1_IA5STRING) || + (tag == V_ASN1_VISIBLESTRING) || + (tag == V_ASN1_NUMERICSTRING) || + (tag == V_ASN1_UTF8STRING) || + (tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) { + if (BIO_write(bp, ":", 1) <= 0) + goto end; + if ((len > 0) && BIO_write(bp, (const char *)p, (int)len) + != (int)len) + goto end; + } else if (tag == V_ASN1_OBJECT) { + opp = op; + if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) { + if (BIO_write(bp, ":", 1) <= 0) + goto end; + i2a_ASN1_OBJECT(bp, o); + } else { + if (BIO_write(bp, ":BAD OBJECT", 11) <= 0) + goto end; + } + } else if (tag == V_ASN1_BOOLEAN) { + int ii; + + opp = op; + ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl); + if (ii < 0) { + if (BIO_write(bp, "Bad boolean\n", 12) <= 0) + goto end; + } + BIO_printf(bp, ":%d", ii); + } else if (tag == V_ASN1_BMPSTRING) { + /* do the BMP thang */ + } else if (tag == V_ASN1_OCTET_STRING) { + int i, printable = 1; + + opp = op; + os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl); + if (os != NULL && os->length > 0) { + opp = os->data; + /* + * testing whether the octet string is printable + */ + for (i = 0; i < os->length; i++) { + if (((opp[i] < ' ') && + (opp[i] != '\n') && + (opp[i] != '\r') && + (opp[i] != '\t')) || (opp[i] > '~')) { + printable = 0; + break; + } + } + if (printable) + /* printable string */ + { + if (BIO_write(bp, ":", 1) <= 0) + goto end; + if (BIO_write(bp, (const char *)opp, os->length) <= 0) + goto end; + } else if (!dump) + /* + * not printable => print octet string as hex dump + */ + { + if (BIO_write(bp, "[HEX DUMP]:", 11) <= 0) + goto end; + for (i = 0; i < os->length; i++) { + if (BIO_printf(bp, "%02X", opp[i]) <= 0) + goto end; + } + } else + /* print the normal dump */ + { + if (!nl) { + if (BIO_write(bp, "\n", 1) <= 0) + goto end; + } + if (BIO_dump_indent(bp, + (const char *)opp, + ((dump == -1 || dump > + os-> + length) ? os->length : dump), + dump_indent) <= 0) + goto end; + nl = 1; + } + } + if (os != NULL) { + M_ASN1_OCTET_STRING_free(os); + os = NULL; + } + } else if (tag == V_ASN1_INTEGER) { + ASN1_INTEGER *bs; + int i; + + opp = op; + bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl); + if (bs != NULL) { + if (BIO_write(bp, ":", 1) <= 0) + goto end; + if (bs->type == V_ASN1_NEG_INTEGER) + if (BIO_write(bp, "-", 1) <= 0) + goto end; + for (i = 0; i < bs->length; i++) { + if (BIO_printf(bp, "%02X", bs->data[i]) <= 0) + goto end; + } + if (bs->length == 0) { + if (BIO_write(bp, "00", 2) <= 0) + goto end; + } + } else { + if (BIO_write(bp, "BAD INTEGER", 11) <= 0) + goto end; + } + M_ASN1_INTEGER_free(bs); + } else if (tag == V_ASN1_ENUMERATED) { + ASN1_ENUMERATED *bs; + int i; + + opp = op; + bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl); + if (bs != NULL) { + if (BIO_write(bp, ":", 1) <= 0) + goto end; + if (bs->type == V_ASN1_NEG_ENUMERATED) + if (BIO_write(bp, "-", 1) <= 0) + goto end; + for (i = 0; i < bs->length; i++) { + if (BIO_printf(bp, "%02X", bs->data[i]) <= 0) + goto end; + } + if (bs->length == 0) { + if (BIO_write(bp, "00", 2) <= 0) + goto end; + } + } else { + if (BIO_write(bp, "BAD ENUMERATED", 14) <= 0) + goto end; + } + M_ASN1_ENUMERATED_free(bs); + } else if (len > 0 && dump) { + if (!nl) { + if (BIO_write(bp, "\n", 1) <= 0) + goto end; + } + if (BIO_dump_indent(bp, (const char *)p, + ((dump == -1 || dump > len) ? len : dump), + dump_indent) <= 0) + goto end; + nl = 1; + } + + if (!nl) { + if (BIO_write(bp, "\n", 1) <= 0) + goto end; + } + p += len; + if ((tag == V_ASN1_EOC) && (xclass == 0)) { + ret = 2; /* End of sequence */ + goto end; + } + } + length -= len; + } + ret = 1; + end: + if (o != NULL) + ASN1_OBJECT_free(o); + if (os != NULL) + M_ASN1_OCTET_STRING_free(os); + *pp = p; + return (ret); +} + +const char *ASN1_tag2str(int tag) +{ + static const char *const tag2str[] = { + /* 0-4 */ + "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", + /* 5-9 */ + "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", + /* 10-13 */ + "ENUMERATED", "", "UTF8STRING", "", + /* 15-17 */ + "", "", "SEQUENCE", "SET", + /* 18-20 */ + "NUMERICSTRING", "PRINTABLESTRING", "T61STRING", + /* 21-24 */ + "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", + /* 25-27 */ + "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", + /* 28-30 */ + "UNIVERSALSTRING", "", "BMPSTRING" + }; + + if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED)) + tag &= ~0x100; + + if (tag < 0 || tag > 30) + return "(unknown)"; + return tag2str[tag]; +} diff --git a/libs/openssl/crypto/asn1/asn1t.h b/libs/openssl/crypto/asn1/asn1t.h new file mode 100644 index 00000000..99bc0eec --- /dev/null +++ b/libs/openssl/crypto/asn1/asn1t.h @@ -0,0 +1,973 @@ +/* asn1t.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ASN1T_H +# define HEADER_ASN1T_H + +# include +# include +# include + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +/* ASN1 template defines, structures and functions */ + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr)) + +/* Macros for start and end of ASN1_ITEM definition */ + +# define ASN1_ITEM_start(itname) \ + OPENSSL_GLOBAL const ASN1_ITEM itname##_it = { + +# define ASN1_ITEM_end(itname) \ + }; + +# else + +/* Macro to obtain ASN1_ADB pointer from a type (only used internally) */ +# define ASN1_ADB_ptr(iptr) ((const ASN1_ADB *)(iptr())) + +/* Macros for start and end of ASN1_ITEM definition */ + +# define ASN1_ITEM_start(itname) \ + const ASN1_ITEM * itname##_it(void) \ + { \ + static const ASN1_ITEM local_it = { + +# define ASN1_ITEM_end(itname) \ + }; \ + return &local_it; \ + } + +# endif + +/* Macros to aid ASN1 template writing */ + +# define ASN1_ITEM_TEMPLATE(tname) \ + static const ASN1_TEMPLATE tname##_item_tt + +# define ASN1_ITEM_TEMPLATE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_PRIMITIVE,\ + -1,\ + &tname##_item_tt,\ + 0,\ + NULL,\ + 0,\ + #tname \ + ASN1_ITEM_end(tname) + +/* This is a ASN1 type which just embeds a template */ + +/*- + * This pair helps declare a SEQUENCE. We can do: + * + * ASN1_SEQUENCE(stname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END(stname) + * + * This will produce an ASN1_ITEM called stname_it + * for a structure called stname. + * + * If you want the same structure but a different + * name then use: + * + * ASN1_SEQUENCE(itname) = { + * ... SEQUENCE components ... + * } ASN1_SEQUENCE_END_name(stname, itname) + * + * This will create an item called itname_it using + * a structure called stname. + */ + +# define ASN1_SEQUENCE(tname) \ + static const ASN1_TEMPLATE tname##_seq_tt[] + +# define ASN1_SEQUENCE_END(stname) ASN1_SEQUENCE_END_name(stname, stname) + +# define ASN1_SEQUENCE_END_name(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_NDEF_SEQUENCE(tname) \ + ASN1_SEQUENCE(tname) + +# define ASN1_NDEF_SEQUENCE_cb(tname, cb) \ + ASN1_SEQUENCE_cb(tname, cb) + +# define ASN1_SEQUENCE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_BROKEN_SEQUENCE(tname) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_ref(tname, cb, lck) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), lck, cb, 0}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_SEQUENCE_enc(tname, enc, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 0, 0, cb, offsetof(tname, enc)}; \ + ASN1_SEQUENCE(tname) + +# define ASN1_NDEF_SEQUENCE_END(tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(tname),\ + #tname \ + ASN1_ITEM_end(tname) + +# define ASN1_BROKEN_SEQUENCE_END(stname) ASN1_SEQUENCE_END_ref(stname, stname) + +# define ASN1_SEQUENCE_END_enc(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +# define ASN1_SEQUENCE_END_cb(stname, tname) ASN1_SEQUENCE_END_ref(stname, tname) + +# define ASN1_SEQUENCE_END_ref(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_NDEF_SEQUENCE_END_cb(stname, tname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_NDEF_SEQUENCE,\ + V_ASN1_SEQUENCE,\ + tname##_seq_tt,\ + sizeof(tname##_seq_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/*- + * This pair helps declare a CHOICE type. We can do: + * + * ASN1_CHOICE(chname) = { + * ... CHOICE options ... + * ASN1_CHOICE_END(chname) + * + * This will produce an ASN1_ITEM called chname_it + * for a structure called chname. The structure + * definition must look like this: + * typedef struct { + * int type; + * union { + * ASN1_SOMETHING *opt1; + * ASN1_SOMEOTHER *opt2; + * } value; + * } chname; + * + * the name of the selector must be 'type'. + * to use an alternative selector name use the + * ASN1_CHOICE_END_selector() version. + */ + +# define ASN1_CHOICE(tname) \ + static const ASN1_TEMPLATE tname##_ch_tt[] + +# define ASN1_CHOICE_cb(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, 0, 0, 0, cb, 0}; \ + ASN1_CHOICE(tname) + +# define ASN1_CHOICE_END(stname) ASN1_CHOICE_END_name(stname, stname) + +# define ASN1_CHOICE_END_name(stname, tname) ASN1_CHOICE_END_selector(stname, tname, type) + +# define ASN1_CHOICE_END_selector(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + NULL,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +# define ASN1_CHOICE_END_cb(stname, tname, selname) \ + ;\ + ASN1_ITEM_start(tname) \ + ASN1_ITYPE_CHOICE,\ + offsetof(stname,selname) ,\ + tname##_ch_tt,\ + sizeof(tname##_ch_tt) / sizeof(ASN1_TEMPLATE),\ + &tname##_aux,\ + sizeof(stname),\ + #stname \ + ASN1_ITEM_end(tname) + +/* This helps with the template wrapper form of ASN1_ITEM */ + +# define ASN1_EX_TEMPLATE_TYPE(flags, tag, name, type) { \ + (flags), (tag), 0,\ + #name, ASN1_ITEM_ref(type) } + +/* These help with SEQUENCE or CHOICE components */ + +/* used to declare other types */ + +# define ASN1_EX_TYPE(flags, tag, stname, field, type) { \ + (flags), (tag), offsetof(stname, field),\ + #field, ASN1_ITEM_ref(type) } + +/* used when the structure is combined with the parent */ + +# define ASN1_EX_COMBINE(flags, tag, type) { \ + (flags)|ASN1_TFLG_COMBINE, (tag), 0, NULL, ASN1_ITEM_ref(type) } + +/* implicit and explicit helper macros */ + +# define ASN1_IMP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_IMPLICIT | ex, tag, stname, field, type) + +# define ASN1_EXP_EX(stname, field, type, tag, ex) \ + ASN1_EX_TYPE(ASN1_TFLG_EXPLICIT | ex, tag, stname, field, type) + +/* Any defined by macros: the field used is in the table itself */ + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION +# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, (const ASN1_ITEM *)&(tblname##_adb) } +# else +# define ASN1_ADB_OBJECT(tblname) { ASN1_TFLG_ADB_OID, -1, 0, #tblname, tblname##_adb } +# define ASN1_ADB_INTEGER(tblname) { ASN1_TFLG_ADB_INT, -1, 0, #tblname, tblname##_adb } +# endif +/* Plain simple type */ +# define ASN1_SIMPLE(stname, field, type) ASN1_EX_TYPE(0,0, stname, field, type) + +/* OPTIONAL simple type */ +# define ASN1_OPT(stname, field, type) ASN1_EX_TYPE(ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* IMPLICIT tagged simple type */ +# define ASN1_IMP(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, 0) + +/* IMPLICIT tagged OPTIONAL simple type */ +# define ASN1_IMP_OPT(stname, field, type, tag) ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) + +/* Same as above but EXPLICIT */ + +# define ASN1_EXP(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, 0) +# define ASN1_EXP_OPT(stname, field, type, tag) ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL) + +/* SEQUENCE OF type */ +# define ASN1_SEQUENCE_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, stname, field, type) + +/* OPTIONAL SEQUENCE OF */ +# define ASN1_SEQUENCE_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Same as above but for SET OF */ + +# define ASN1_SET_OF(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF, 0, stname, field, type) + +# define ASN1_SET_OF_OPT(stname, field, type) \ + ASN1_EX_TYPE(ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL, 0, stname, field, type) + +/* Finally compound types of SEQUENCE, SET, IMPLICIT, EXPLICIT and OPTIONAL */ + +# define ASN1_IMP_SET_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +# define ASN1_EXP_SET_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF) + +# define ASN1_IMP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_EXP_SET_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SET_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_IMP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +# define ASN1_IMP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_IMP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +# define ASN1_EXP_SEQUENCE_OF(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF) + +# define ASN1_EXP_SEQUENCE_OF_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_SEQUENCE_OF|ASN1_TFLG_OPTIONAL) + +/* EXPLICIT using indefinite length constructed form */ +# define ASN1_NDEF_EXP(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_NDEF) + +/* EXPLICIT OPTIONAL using indefinite length constructed form */ +# define ASN1_NDEF_EXP_OPT(stname, field, type, tag) \ + ASN1_EXP_EX(stname, field, type, tag, ASN1_TFLG_OPTIONAL|ASN1_TFLG_NDEF) + +/* Macros for the ASN1_ADB structure */ + +# define ASN1_ADB(name) \ + static const ASN1_ADB_TABLE name##_adbtbl[] + +# ifndef OPENSSL_EXPORT_VAR_AS_FUNCTION + +# define ASN1_ADB_END(name, flags, field, app_table, def, none) \ + ;\ + static const ASN1_ADB name##_adb = {\ + flags,\ + offsetof(name, field),\ + app_table,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + } + +# else + +# define ASN1_ADB_END(name, flags, field, app_table, def, none) \ + ;\ + static const ASN1_ITEM *name##_adb(void) \ + { \ + static const ASN1_ADB internal_adb = \ + {\ + flags,\ + offsetof(name, field),\ + app_table,\ + name##_adbtbl,\ + sizeof(name##_adbtbl) / sizeof(ASN1_ADB_TABLE),\ + def,\ + none\ + }; \ + return (const ASN1_ITEM *) &internal_adb; \ + } \ + void dummy_function(void) + +# endif + +# define ADB_ENTRY(val, template) {val, template} + +# define ASN1_ADB_TEMPLATE(name) \ + static const ASN1_TEMPLATE name##_tt + +/* + * This is the ASN1 template structure that defines a wrapper round the + * actual type. It determines the actual position of the field in the value + * structure, various flags such as OPTIONAL and the field name. + */ + +struct ASN1_TEMPLATE_st { + unsigned long flags; /* Various flags */ + long tag; /* tag, not used if no tagging */ + unsigned long offset; /* Offset of this field in structure */ +# ifndef NO_ASN1_FIELD_NAMES + const char *field_name; /* Field name */ +# endif + ASN1_ITEM_EXP *item; /* Relevant ASN1_ITEM or ASN1_ADB */ +}; + +/* Macro to extract ASN1_ITEM and ASN1_ADB pointer from ASN1_TEMPLATE */ + +# define ASN1_TEMPLATE_item(t) (t->item_ptr) +# define ASN1_TEMPLATE_adb(t) (t->item_ptr) + +typedef struct ASN1_ADB_TABLE_st ASN1_ADB_TABLE; +typedef struct ASN1_ADB_st ASN1_ADB; + +struct ASN1_ADB_st { + unsigned long flags; /* Various flags */ + unsigned long offset; /* Offset of selector field */ + STACK_OF(ASN1_ADB_TABLE) **app_items; /* Application defined items */ + const ASN1_ADB_TABLE *tbl; /* Table of possible types */ + long tblcount; /* Number of entries in tbl */ + const ASN1_TEMPLATE *default_tt; /* Type to use if no match */ + const ASN1_TEMPLATE *null_tt; /* Type to use if selector is NULL */ +}; + +struct ASN1_ADB_TABLE_st { + long value; /* NID for an object or value for an int */ + const ASN1_TEMPLATE tt; /* item for this value */ +}; + +/* template flags */ + +/* Field is optional */ +# define ASN1_TFLG_OPTIONAL (0x1) + +/* Field is a SET OF */ +# define ASN1_TFLG_SET_OF (0x1 << 1) + +/* Field is a SEQUENCE OF */ +# define ASN1_TFLG_SEQUENCE_OF (0x2 << 1) + +/* + * Special case: this refers to a SET OF that will be sorted into DER order + * when encoded *and* the corresponding STACK will be modified to match the + * new order. + */ +# define ASN1_TFLG_SET_ORDER (0x3 << 1) + +/* Mask for SET OF or SEQUENCE OF */ +# define ASN1_TFLG_SK_MASK (0x3 << 1) + +/* + * These flags mean the tag should be taken from the tag field. If EXPLICIT + * then the underlying type is used for the inner tag. + */ + +/* IMPLICIT tagging */ +# define ASN1_TFLG_IMPTAG (0x1 << 3) + +/* EXPLICIT tagging, inner tag from underlying type */ +# define ASN1_TFLG_EXPTAG (0x2 << 3) + +# define ASN1_TFLG_TAG_MASK (0x3 << 3) + +/* context specific IMPLICIT */ +# define ASN1_TFLG_IMPLICIT ASN1_TFLG_IMPTAG|ASN1_TFLG_CONTEXT + +/* context specific EXPLICIT */ +# define ASN1_TFLG_EXPLICIT ASN1_TFLG_EXPTAG|ASN1_TFLG_CONTEXT + +/* + * If tagging is in force these determine the type of tag to use. Otherwise + * the tag is determined by the underlying type. These values reflect the + * actual octet format. + */ + +/* Universal tag */ +# define ASN1_TFLG_UNIVERSAL (0x0<<6) +/* Application tag */ +# define ASN1_TFLG_APPLICATION (0x1<<6) +/* Context specific tag */ +# define ASN1_TFLG_CONTEXT (0x2<<6) +/* Private tag */ +# define ASN1_TFLG_PRIVATE (0x3<<6) + +# define ASN1_TFLG_TAG_CLASS (0x3<<6) + +/* + * These are for ANY DEFINED BY type. In this case the 'item' field points to + * an ASN1_ADB structure which contains a table of values to decode the + * relevant type + */ + +# define ASN1_TFLG_ADB_MASK (0x3<<8) + +# define ASN1_TFLG_ADB_OID (0x1<<8) + +# define ASN1_TFLG_ADB_INT (0x1<<9) + +/* + * This flag means a parent structure is passed instead of the field: this is + * useful is a SEQUENCE is being combined with a CHOICE for example. Since + * this means the structure and item name will differ we need to use the + * ASN1_CHOICE_END_name() macro for example. + */ + +# define ASN1_TFLG_COMBINE (0x1<<10) + +/* + * This flag when present in a SEQUENCE OF, SET OF or EXPLICIT causes + * indefinite length constructed encoding to be used if required. + */ + +# define ASN1_TFLG_NDEF (0x1<<11) + +/* This is the actual ASN1 item itself */ + +struct ASN1_ITEM_st { + char itype; /* The item type, primitive, SEQUENCE, CHOICE + * or extern */ + long utype; /* underlying type */ + const ASN1_TEMPLATE *templates; /* If SEQUENCE or CHOICE this contains + * the contents */ + long tcount; /* Number of templates if SEQUENCE or CHOICE */ + const void *funcs; /* functions that handle this type */ + long size; /* Structure size (usually) */ +# ifndef NO_ASN1_FIELD_NAMES + const char *sname; /* Structure name */ +# endif +}; + +/*- + * These are values for the itype field and + * determine how the type is interpreted. + * + * For PRIMITIVE types the underlying type + * determines the behaviour if items is NULL. + * + * Otherwise templates must contain a single + * template and the type is treated in the + * same way as the type specified in the template. + * + * For SEQUENCE types the templates field points + * to the members, the size field is the + * structure size. + * + * For CHOICE types the templates field points + * to each possible member (typically a union) + * and the 'size' field is the offset of the + * selector. + * + * The 'funcs' field is used for application + * specific functions. + * + * For COMPAT types the funcs field gives a + * set of functions that handle this type, this + * supports the old d2i, i2d convention. + * + * The EXTERN type uses a new style d2i/i2d. + * The new style should be used where possible + * because it avoids things like the d2i IMPLICIT + * hack. + * + * MSTRING is a multiple string type, it is used + * for a CHOICE of character strings where the + * actual strings all occupy an ASN1_STRING + * structure. In this case the 'utype' field + * has a special meaning, it is used as a mask + * of acceptable types using the B_ASN1 constants. + * + * NDEF_SEQUENCE is the same as SEQUENCE except + * that it will use indefinite length constructed + * encoding if requested. + * + */ + +# define ASN1_ITYPE_PRIMITIVE 0x0 + +# define ASN1_ITYPE_SEQUENCE 0x1 + +# define ASN1_ITYPE_CHOICE 0x2 + +# define ASN1_ITYPE_COMPAT 0x3 + +# define ASN1_ITYPE_EXTERN 0x4 + +# define ASN1_ITYPE_MSTRING 0x5 + +# define ASN1_ITYPE_NDEF_SEQUENCE 0x6 + +/* + * Cache for ASN1 tag and length, so we don't keep re-reading it for things + * like CHOICE + */ + +struct ASN1_TLC_st { + char valid; /* Values below are valid */ + int ret; /* return value */ + long plen; /* length */ + int ptag; /* class value */ + int pclass; /* class value */ + int hdrlen; /* header length */ +}; + +/* Typedefs for ASN1 function pointers */ + +typedef ASN1_VALUE *ASN1_new_func(void); +typedef void ASN1_free_func(ASN1_VALUE *a); +typedef ASN1_VALUE *ASN1_d2i_func(ASN1_VALUE **a, const unsigned char **in, + long length); +typedef int ASN1_i2d_func(ASN1_VALUE *a, unsigned char **in); + +typedef int ASN1_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +typedef int ASN1_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +typedef int ASN1_ex_new_func(ASN1_VALUE **pval, const ASN1_ITEM *it); +typedef void ASN1_ex_free_func(ASN1_VALUE **pval, const ASN1_ITEM *it); + +typedef int ASN1_ex_print_func(BIO *out, ASN1_VALUE **pval, + int indent, const char *fname, + const ASN1_PCTX *pctx); + +typedef int ASN1_primitive_i2c(ASN1_VALUE **pval, unsigned char *cont, + int *putype, const ASN1_ITEM *it); +typedef int ASN1_primitive_c2i(ASN1_VALUE **pval, const unsigned char *cont, + int len, int utype, char *free_cont, + const ASN1_ITEM *it); +typedef int ASN1_primitive_print(BIO *out, ASN1_VALUE **pval, + const ASN1_ITEM *it, int indent, + const ASN1_PCTX *pctx); + +typedef struct ASN1_COMPAT_FUNCS_st { + ASN1_new_func *asn1_new; + ASN1_free_func *asn1_free; + ASN1_d2i_func *asn1_d2i; + ASN1_i2d_func *asn1_i2d; +} ASN1_COMPAT_FUNCS; + +typedef struct ASN1_EXTERN_FUNCS_st { + void *app_data; + ASN1_ex_new_func *asn1_ex_new; + ASN1_ex_free_func *asn1_ex_free; + ASN1_ex_free_func *asn1_ex_clear; + ASN1_ex_d2i *asn1_ex_d2i; + ASN1_ex_i2d *asn1_ex_i2d; + ASN1_ex_print_func *asn1_ex_print; +} ASN1_EXTERN_FUNCS; + +typedef struct ASN1_PRIMITIVE_FUNCS_st { + void *app_data; + unsigned long flags; + ASN1_ex_new_func *prim_new; + ASN1_ex_free_func *prim_free; + ASN1_ex_free_func *prim_clear; + ASN1_primitive_c2i *prim_c2i; + ASN1_primitive_i2c *prim_i2c; + ASN1_primitive_print *prim_print; +} ASN1_PRIMITIVE_FUNCS; + +/* + * This is the ASN1_AUX structure: it handles various miscellaneous + * requirements. For example the use of reference counts and an informational + * callback. The "informational callback" is called at various points during + * the ASN1 encoding and decoding. It can be used to provide minor + * customisation of the structures used. This is most useful where the + * supplied routines *almost* do the right thing but need some extra help at + * a few points. If the callback returns zero then it is assumed a fatal + * error has occurred and the main operation should be abandoned. If major + * changes in the default behaviour are required then an external type is + * more appropriate. + */ + +typedef int ASN1_aux_cb(int operation, ASN1_VALUE **in, const ASN1_ITEM *it, + void *exarg); + +typedef struct ASN1_AUX_st { + void *app_data; + int flags; + int ref_offset; /* Offset of reference value */ + int ref_lock; /* Lock type to use */ + ASN1_aux_cb *asn1_cb; + int enc_offset; /* Offset of ASN1_ENCODING structure */ +} ASN1_AUX; + +/* For print related callbacks exarg points to this structure */ +typedef struct ASN1_PRINT_ARG_st { + BIO *out; + int indent; + const ASN1_PCTX *pctx; +} ASN1_PRINT_ARG; + +/* For streaming related callbacks exarg points to this structure */ +typedef struct ASN1_STREAM_ARG_st { + /* BIO to stream through */ + BIO *out; + /* BIO with filters appended */ + BIO *ndef_bio; + /* Streaming I/O boundary */ + unsigned char **boundary; +} ASN1_STREAM_ARG; + +/* Flags in ASN1_AUX */ + +/* Use a reference count */ +# define ASN1_AFLG_REFCOUNT 1 +/* Save the encoding of structure (useful for signatures) */ +# define ASN1_AFLG_ENCODING 2 +/* The Sequence length is invalid */ +# define ASN1_AFLG_BROKEN 4 + +/* operation values for asn1_cb */ + +# define ASN1_OP_NEW_PRE 0 +# define ASN1_OP_NEW_POST 1 +# define ASN1_OP_FREE_PRE 2 +# define ASN1_OP_FREE_POST 3 +# define ASN1_OP_D2I_PRE 4 +# define ASN1_OP_D2I_POST 5 +# define ASN1_OP_I2D_PRE 6 +# define ASN1_OP_I2D_POST 7 +# define ASN1_OP_PRINT_PRE 8 +# define ASN1_OP_PRINT_POST 9 +# define ASN1_OP_STREAM_PRE 10 +# define ASN1_OP_STREAM_POST 11 +# define ASN1_OP_DETACHED_PRE 12 +# define ASN1_OP_DETACHED_POST 13 + +/* Macro to implement a primitive type */ +# define IMPLEMENT_ASN1_TYPE(stname) IMPLEMENT_ASN1_TYPE_ex(stname, stname, 0) +# define IMPLEMENT_ASN1_TYPE_ex(itname, vname, ex) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_PRIMITIVE, V_##vname, NULL, 0, NULL, ex, #itname \ + ASN1_ITEM_end(itname) + +/* Macro to implement a multi string type */ +# define IMPLEMENT_ASN1_MSTRING(itname, mask) \ + ASN1_ITEM_start(itname) \ + ASN1_ITYPE_MSTRING, mask, NULL, 0, NULL, sizeof(ASN1_STRING), #itname \ + ASN1_ITEM_end(itname) + +/* Macro to implement an ASN1_ITEM in terms of old style funcs */ + +# define IMPLEMENT_COMPAT_ASN1(sname) IMPLEMENT_COMPAT_ASN1_type(sname, V_ASN1_SEQUENCE) + +# define IMPLEMENT_COMPAT_ASN1_type(sname, tag) \ + static const ASN1_COMPAT_FUNCS sname##_ff = { \ + (ASN1_new_func *)sname##_new, \ + (ASN1_free_func *)sname##_free, \ + (ASN1_d2i_func *)d2i_##sname, \ + (ASN1_i2d_func *)i2d_##sname, \ + }; \ + ASN1_ITEM_start(sname) \ + ASN1_ITYPE_COMPAT, \ + tag, \ + NULL, \ + 0, \ + &sname##_ff, \ + 0, \ + #sname \ + ASN1_ITEM_end(sname) + +# define IMPLEMENT_EXTERN_ASN1(sname, tag, fptrs) \ + ASN1_ITEM_start(sname) \ + ASN1_ITYPE_EXTERN, \ + tag, \ + NULL, \ + 0, \ + &fptrs, \ + 0, \ + #sname \ + ASN1_ITEM_end(sname) + +/* Macro to implement standard functions in terms of ASN1_ITEM structures */ + +# define IMPLEMENT_ASN1_FUNCTIONS(stname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_FUNCTIONS_name(stname, itname) IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, itname) + +# define IMPLEMENT_ASN1_FUNCTIONS_ENCODE_name(stname, itname) \ + IMPLEMENT_ASN1_FUNCTIONS_ENCODE_fname(stname, itname, itname) + +# define IMPLEMENT_STATIC_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(static, stname, stname, stname) + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS(stname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_pfname(pre, stname, itname, fname) \ + pre stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + pre void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +# define IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) \ + stname *fname##_new(void) \ + { \ + return (stname *)ASN1_item_new(ASN1_ITEM_rptr(itname)); \ + } \ + void fname##_free(stname *a) \ + { \ + ASN1_item_free((ASN1_VALUE *)a, ASN1_ITEM_rptr(itname)); \ + } + +# define IMPLEMENT_ASN1_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +# define IMPLEMENT_ASN1_NDEF_FUNCTION(stname) \ + int i2d_##stname##_NDEF(stname *a, unsigned char **out) \ + { \ + return ASN1_item_ndef_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(stname));\ + } + +/* + * This includes evil casts to remove const: they will go away when full ASN1 + * constification is done. + */ +# define IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + stname *d2i_##fname(stname **a, const unsigned char **in, long len) \ + { \ + return (stname *)ASN1_item_d2i((ASN1_VALUE **)a, in, len, ASN1_ITEM_rptr(itname));\ + } \ + int i2d_##fname(const stname *a, unsigned char **out) \ + { \ + return ASN1_item_i2d((ASN1_VALUE *)a, out, ASN1_ITEM_rptr(itname));\ + } + +# define IMPLEMENT_ASN1_DUP_FUNCTION(stname) \ + stname * stname##_dup(stname *x) \ + { \ + return ASN1_item_dup(ASN1_ITEM_rptr(stname), x); \ + } + +# define IMPLEMENT_ASN1_PRINT_FUNCTION(stname) \ + IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, stname, stname) + +# define IMPLEMENT_ASN1_PRINT_FUNCTION_fname(stname, itname, fname) \ + int fname##_print_ctx(BIO *out, stname *x, int indent, \ + const ASN1_PCTX *pctx) \ + { \ + return ASN1_item_print(out, (ASN1_VALUE *)x, indent, \ + ASN1_ITEM_rptr(itname), pctx); \ + } + +# define IMPLEMENT_ASN1_FUNCTIONS_const(name) \ + IMPLEMENT_ASN1_FUNCTIONS_const_fname(name, name, name) + +# define IMPLEMENT_ASN1_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(stname, itname, fname) \ + IMPLEMENT_ASN1_ALLOC_FUNCTIONS_fname(stname, itname, fname) + +/* external definitions for primitive types */ + +DECLARE_ASN1_ITEM(ASN1_BOOLEAN) +DECLARE_ASN1_ITEM(ASN1_TBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_FBOOLEAN) +DECLARE_ASN1_ITEM(ASN1_SEQUENCE) +DECLARE_ASN1_ITEM(CBIGNUM) +DECLARE_ASN1_ITEM(BIGNUM) +DECLARE_ASN1_ITEM(LONG) +DECLARE_ASN1_ITEM(ZLONG) + +DECLARE_STACK_OF(ASN1_VALUE) + +/* Functions used internally by the ASN1 code */ + +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it); +int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it); + +void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +int ASN1_template_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_TEMPLATE *tt); +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, char opt, + ASN1_TLC *ctx); + +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_TEMPLATE *tt); +void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, + const ASN1_ITEM *it); +int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it); + +int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); +int asn1_set_choice_selector(ASN1_VALUE **pval, int value, + const ASN1_ITEM *it); + +ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); + +const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, + int nullerr); + +int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it); + +void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it); +void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it); +int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, + const ASN1_ITEM *it); +int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, + const ASN1_ITEM *it); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/asn1/asn_mime.c b/libs/openssl/crypto/asn1/asn_mime.c new file mode 100644 index 00000000..96110c54 --- /dev/null +++ b/libs/openssl/crypto/asn1/asn_mime.c @@ -0,0 +1,974 @@ +/* asn_mime.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include "asn1_locl.h" + +/* + * Generalised MIME like utilities for streaming ASN1. Although many have a + * PKCS7/CMS like flavour others are more general purpose. + */ + +/* + * MIME format structures Note that all are translated to lower case apart + * from parameter values. Quotes are stripped off + */ + +typedef struct { + char *param_name; /* Param name e.g. "micalg" */ + char *param_value; /* Param value e.g. "sha1" */ +} MIME_PARAM; + +DECLARE_STACK_OF(MIME_PARAM) +IMPLEMENT_STACK_OF(MIME_PARAM) + +typedef struct { + char *name; /* Name of line e.g. "content-type" */ + char *value; /* Value of line e.g. "text/plain" */ + STACK_OF(MIME_PARAM) *params; /* Zero or more parameters */ +} MIME_HEADER; + +DECLARE_STACK_OF(MIME_HEADER) +IMPLEMENT_STACK_OF(MIME_HEADER) + +static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, + const ASN1_ITEM *it); +static char *strip_ends(char *name); +static char *strip_start(char *name); +static char *strip_end(char *name); +static MIME_HEADER *mime_hdr_new(char *name, char *value); +static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value); +static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio); +static int mime_hdr_cmp(const MIME_HEADER *const *a, + const MIME_HEADER *const *b); +static int mime_param_cmp(const MIME_PARAM *const *a, + const MIME_PARAM *const *b); +static void mime_param_free(MIME_PARAM *param); +static int mime_bound_check(char *line, int linelen, char *bound, int blen); +static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret); +static int strip_eol(char *linebuf, int *plen); +static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name); +static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name); +static void mime_hdr_free(MIME_HEADER *hdr); + +#define MAX_SMLEN 1024 +#define mime_debug(x) /* x */ + +/* Output an ASN1 structure in BER format streaming if necessary */ + +int i2d_ASN1_bio_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it) +{ + /* If streaming create stream BIO and copy all content through it */ + if (flags & SMIME_STREAM) { + BIO *bio, *tbio; + bio = BIO_new_NDEF(out, val, it); + if (!bio) { + ASN1err(ASN1_F_I2D_ASN1_BIO_STREAM, ERR_R_MALLOC_FAILURE); + return 0; + } + SMIME_crlf_copy(in, bio, flags); + (void)BIO_flush(bio); + /* Free up successive BIOs until we hit the old output BIO */ + do { + tbio = BIO_pop(bio); + BIO_free(bio); + bio = tbio; + } while (bio != out); + } + /* + * else just write out ASN1 structure which will have all content stored + * internally + */ + else + ASN1_item_i2d_bio(it, out, val); + return 1; +} + +/* Base 64 read and write of ASN1 structure */ + +static int B64_write_ASN1(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const ASN1_ITEM *it) +{ + BIO *b64; + int r; + b64 = BIO_new(BIO_f_base64()); + if (!b64) { + ASN1err(ASN1_F_B64_WRITE_ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + /* + * prepend the b64 BIO so all data is base64 encoded. + */ + out = BIO_push(b64, out); + r = i2d_ASN1_bio_stream(out, val, in, flags, it); + (void)BIO_flush(out); + BIO_pop(out); + BIO_free(b64); + return r; +} + +/* Streaming ASN1 PEM write */ + +int PEM_write_bio_ASN1_stream(BIO *out, ASN1_VALUE *val, BIO *in, int flags, + const char *hdr, const ASN1_ITEM *it) +{ + int r; + BIO_printf(out, "-----BEGIN %s-----\n", hdr); + r = B64_write_ASN1(out, val, in, flags, it); + BIO_printf(out, "-----END %s-----\n", hdr); + return r; +} + +static ASN1_VALUE *b64_read_asn1(BIO *bio, const ASN1_ITEM *it) +{ + BIO *b64; + ASN1_VALUE *val; + if (!(b64 = BIO_new(BIO_f_base64()))) { + ASN1err(ASN1_F_B64_READ_ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + bio = BIO_push(b64, bio); + val = ASN1_item_d2i_bio(it, bio, NULL); + if (!val) + ASN1err(ASN1_F_B64_READ_ASN1, ASN1_R_DECODE_ERROR); + (void)BIO_flush(bio); + bio = BIO_pop(bio); + BIO_free(b64); + return val; +} + +/* Generate the MIME "micalg" parameter from RFC3851, RFC4490 */ + +static int asn1_write_micalg(BIO *out, STACK_OF(X509_ALGOR) *mdalgs) +{ + const EVP_MD *md; + int i, have_unknown = 0, write_comma, ret = 0, md_nid; + have_unknown = 0; + write_comma = 0; + for (i = 0; i < sk_X509_ALGOR_num(mdalgs); i++) { + if (write_comma) + BIO_write(out, ",", 1); + write_comma = 1; + md_nid = OBJ_obj2nid(sk_X509_ALGOR_value(mdalgs, i)->algorithm); + md = EVP_get_digestbynid(md_nid); + if (md && md->md_ctrl) { + int rv; + char *micstr; + rv = md->md_ctrl(NULL, EVP_MD_CTRL_MICALG, 0, &micstr); + if (rv > 0) { + BIO_puts(out, micstr); + OPENSSL_free(micstr); + continue; + } + if (rv != -2) + goto err; + } + switch (md_nid) { + case NID_sha1: + BIO_puts(out, "sha1"); + break; + + case NID_md5: + BIO_puts(out, "md5"); + break; + + case NID_sha256: + BIO_puts(out, "sha-256"); + break; + + case NID_sha384: + BIO_puts(out, "sha-384"); + break; + + case NID_sha512: + BIO_puts(out, "sha-512"); + break; + + case NID_id_GostR3411_94: + BIO_puts(out, "gostr3411-94"); + goto err; + break; + + default: + if (have_unknown) + write_comma = 0; + else { + BIO_puts(out, "unknown"); + have_unknown = 1; + } + break; + + } + } + + ret = 1; + err: + + return ret; + +} + +/* SMIME sender */ + +int SMIME_write_ASN1(BIO *bio, ASN1_VALUE *val, BIO *data, int flags, + int ctype_nid, int econt_nid, + STACK_OF(X509_ALGOR) *mdalgs, const ASN1_ITEM *it) +{ + char bound[33], c; + int i; + const char *mime_prefix, *mime_eol, *cname = "smime.p7m"; + const char *msg_type = NULL; + if (flags & SMIME_OLDMIME) + mime_prefix = "application/x-pkcs7-"; + else + mime_prefix = "application/pkcs7-"; + + if (flags & SMIME_CRLFEOL) + mime_eol = "\r\n"; + else + mime_eol = "\n"; + if ((flags & SMIME_DETACHED) && data) { + /* We want multipart/signed */ + /* Generate a random boundary */ + if (RAND_pseudo_bytes((unsigned char *)bound, 32) < 0) + return 0; + for (i = 0; i < 32; i++) { + c = bound[i] & 0xf; + if (c < 10) + c += '0'; + else + c += 'A' - 10; + bound[i] = c; + } + bound[32] = 0; + BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol); + BIO_printf(bio, "Content-Type: multipart/signed;"); + BIO_printf(bio, " protocol=\"%ssignature\";", mime_prefix); + BIO_puts(bio, " micalg=\""); + asn1_write_micalg(bio, mdalgs); + BIO_printf(bio, "\"; boundary=\"----%s\"%s%s", + bound, mime_eol, mime_eol); + BIO_printf(bio, "This is an S/MIME signed message%s%s", + mime_eol, mime_eol); + /* Now write out the first part */ + BIO_printf(bio, "------%s%s", bound, mime_eol); + if (!asn1_output_data(bio, data, val, flags, it)) + return 0; + BIO_printf(bio, "%s------%s%s", mime_eol, bound, mime_eol); + + /* Headers for signature */ + + BIO_printf(bio, "Content-Type: %ssignature;", mime_prefix); + BIO_printf(bio, " name=\"smime.p7s\"%s", mime_eol); + BIO_printf(bio, "Content-Transfer-Encoding: base64%s", mime_eol); + BIO_printf(bio, "Content-Disposition: attachment;"); + BIO_printf(bio, " filename=\"smime.p7s\"%s%s", mime_eol, mime_eol); + B64_write_ASN1(bio, val, NULL, 0, it); + BIO_printf(bio, "%s------%s--%s%s", mime_eol, bound, + mime_eol, mime_eol); + return 1; + } + + /* Determine smime-type header */ + + if (ctype_nid == NID_pkcs7_enveloped) + msg_type = "enveloped-data"; + else if (ctype_nid == NID_pkcs7_signed) { + if (econt_nid == NID_id_smime_ct_receipt) + msg_type = "signed-receipt"; + else if (sk_X509_ALGOR_num(mdalgs) >= 0) + msg_type = "signed-data"; + else + msg_type = "certs-only"; + } else if (ctype_nid == NID_id_smime_ct_compressedData) { + msg_type = "compressed-data"; + cname = "smime.p7z"; + } + /* MIME headers */ + BIO_printf(bio, "MIME-Version: 1.0%s", mime_eol); + BIO_printf(bio, "Content-Disposition: attachment;"); + BIO_printf(bio, " filename=\"%s\"%s", cname, mime_eol); + BIO_printf(bio, "Content-Type: %smime;", mime_prefix); + if (msg_type) + BIO_printf(bio, " smime-type=%s;", msg_type); + BIO_printf(bio, " name=\"%s\"%s", cname, mime_eol); + BIO_printf(bio, "Content-Transfer-Encoding: base64%s%s", + mime_eol, mime_eol); + if (!B64_write_ASN1(bio, val, data, flags, it)) + return 0; + BIO_printf(bio, "%s", mime_eol); + return 1; +} + +/* Handle output of ASN1 data */ + +static int asn1_output_data(BIO *out, BIO *data, ASN1_VALUE *val, int flags, + const ASN1_ITEM *it) +{ + BIO *tmpbio; + const ASN1_AUX *aux = it->funcs; + ASN1_STREAM_ARG sarg; + int rv = 1; + + /* + * If data is not deteched or resigning then the output BIO is already + * set up to finalise when it is written through. + */ + if (!(flags & SMIME_DETACHED) || (flags & PKCS7_REUSE_DIGEST)) { + SMIME_crlf_copy(data, out, flags); + return 1; + } + + if (!aux || !aux->asn1_cb) { + ASN1err(ASN1_F_ASN1_OUTPUT_DATA, ASN1_R_STREAMING_NOT_SUPPORTED); + return 0; + } + + sarg.out = out; + sarg.ndef_bio = NULL; + sarg.boundary = NULL; + + /* Let ASN1 code prepend any needed BIOs */ + + if (aux->asn1_cb(ASN1_OP_DETACHED_PRE, &val, it, &sarg) <= 0) + return 0; + + /* Copy data across, passing through filter BIOs for processing */ + SMIME_crlf_copy(data, sarg.ndef_bio, flags); + + /* Finalize structure */ + if (aux->asn1_cb(ASN1_OP_DETACHED_POST, &val, it, &sarg) <= 0) + rv = 0; + + /* Now remove any digests prepended to the BIO */ + + while (sarg.ndef_bio != out) { + tmpbio = BIO_pop(sarg.ndef_bio); + BIO_free(sarg.ndef_bio); + sarg.ndef_bio = tmpbio; + } + + return rv; + +} + +/* + * SMIME reader: handle multipart/signed and opaque signing. in multipart + * case the content is placed in a memory BIO pointed to by "bcont". In + * opaque this is set to NULL + */ + +ASN1_VALUE *SMIME_read_ASN1(BIO *bio, BIO **bcont, const ASN1_ITEM *it) +{ + BIO *asnin; + STACK_OF(MIME_HEADER) *headers = NULL; + STACK_OF(BIO) *parts = NULL; + MIME_HEADER *hdr; + MIME_PARAM *prm; + ASN1_VALUE *val; + int ret; + + if (bcont) + *bcont = NULL; + + if (!(headers = mime_parse_hdr(bio))) { + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_PARSE_ERROR); + return NULL; + } + + if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_CONTENT_TYPE); + return NULL; + } + + /* Handle multipart/signed */ + + if (!strcmp(hdr->value, "multipart/signed")) { + /* Split into two parts */ + prm = mime_param_find(hdr, "boundary"); + if (!prm || !prm->param_value) { + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BOUNDARY); + return NULL; + } + ret = multi_split(bio, prm->param_value, &parts); + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + if (!ret || (sk_BIO_num(parts) != 2)) { + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_MULTIPART_BODY_FAILURE); + sk_BIO_pop_free(parts, BIO_vfree); + return NULL; + } + + /* Parse the signature piece */ + asnin = sk_BIO_value(parts, 1); + + if (!(headers = mime_parse_hdr(asnin))) { + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_MIME_SIG_PARSE_ERROR); + sk_BIO_pop_free(parts, BIO_vfree); + return NULL; + } + + /* Get content type */ + + if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_NO_SIG_CONTENT_TYPE); + return NULL; + } + + if (strcmp(hdr->value, "application/x-pkcs7-signature") && + strcmp(hdr->value, "application/pkcs7-signature")) { + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_SIG_INVALID_MIME_TYPE); + ERR_add_error_data(2, "type: ", hdr->value); + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + sk_BIO_pop_free(parts, BIO_vfree); + return NULL; + } + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + /* Read in ASN1 */ + if (!(val = b64_read_asn1(asnin, it))) { + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_SIG_PARSE_ERROR); + sk_BIO_pop_free(parts, BIO_vfree); + return NULL; + } + + if (bcont) { + *bcont = sk_BIO_value(parts, 0); + BIO_free(asnin); + sk_BIO_free(parts); + } else + sk_BIO_pop_free(parts, BIO_vfree); + return val; + } + + /* OK, if not multipart/signed try opaque signature */ + + if (strcmp(hdr->value, "application/x-pkcs7-mime") && + strcmp(hdr->value, "application/pkcs7-mime")) { + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_INVALID_MIME_TYPE); + ERR_add_error_data(2, "type: ", hdr->value); + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + return NULL; + } + + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + + if (!(val = b64_read_asn1(bio, it))) { + ASN1err(ASN1_F_SMIME_READ_ASN1, ASN1_R_ASN1_PARSE_ERROR); + return NULL; + } + return val; + +} + +/* Copy text from one BIO to another making the output CRLF at EOL */ +int SMIME_crlf_copy(BIO *in, BIO *out, int flags) +{ + BIO *bf; + char eol; + int len; + char linebuf[MAX_SMLEN]; + /* + * Buffer output so we don't write one line at a time. This is useful + * when streaming as we don't end up with one OCTET STRING per line. + */ + bf = BIO_new(BIO_f_buffer()); + if (!bf) + return 0; + out = BIO_push(bf, out); + if (flags & SMIME_BINARY) { + while ((len = BIO_read(in, linebuf, MAX_SMLEN)) > 0) + BIO_write(out, linebuf, len); + } else { + if (flags & SMIME_TEXT) + BIO_printf(out, "Content-Type: text/plain\r\n\r\n"); + while ((len = BIO_gets(in, linebuf, MAX_SMLEN)) > 0) { + eol = strip_eol(linebuf, &len); + if (len) + BIO_write(out, linebuf, len); + if (eol) + BIO_write(out, "\r\n", 2); + } + } + (void)BIO_flush(out); + BIO_pop(out); + BIO_free(bf); + return 1; +} + +/* Strip off headers if they are text/plain */ +int SMIME_text(BIO *in, BIO *out) +{ + char iobuf[4096]; + int len; + STACK_OF(MIME_HEADER) *headers; + MIME_HEADER *hdr; + + if (!(headers = mime_parse_hdr(in))) { + ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_PARSE_ERROR); + return 0; + } + if (!(hdr = mime_hdr_find(headers, "content-type")) || !hdr->value) { + ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_MIME_NO_CONTENT_TYPE); + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + return 0; + } + if (strcmp(hdr->value, "text/plain")) { + ASN1err(ASN1_F_SMIME_TEXT, ASN1_R_INVALID_MIME_TYPE); + ERR_add_error_data(2, "type: ", hdr->value); + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + return 0; + } + sk_MIME_HEADER_pop_free(headers, mime_hdr_free); + while ((len = BIO_read(in, iobuf, sizeof(iobuf))) > 0) + BIO_write(out, iobuf, len); + if (len < 0) + return 0; + return 1; +} + +/* + * Split a multipart/XXX message body into component parts: result is + * canonical parts in a STACK of bios + */ + +static int multi_split(BIO *bio, char *bound, STACK_OF(BIO) **ret) +{ + char linebuf[MAX_SMLEN]; + int len, blen; + int eol = 0, next_eol = 0; + BIO *bpart = NULL; + STACK_OF(BIO) *parts; + char state, part, first; + + blen = strlen(bound); + part = 0; + state = 0; + first = 1; + parts = sk_BIO_new_null(); + *ret = parts; + while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) { + state = mime_bound_check(linebuf, len, bound, blen); + if (state == 1) { + first = 1; + part++; + } else if (state == 2) { + sk_BIO_push(parts, bpart); + return 1; + } else if (part) { + /* Strip CR+LF from linebuf */ + next_eol = strip_eol(linebuf, &len); + if (first) { + first = 0; + if (bpart) + sk_BIO_push(parts, bpart); + bpart = BIO_new(BIO_s_mem()); + BIO_set_mem_eof_return(bpart, 0); + } else if (eol) + BIO_write(bpart, "\r\n", 2); + eol = next_eol; + if (len) + BIO_write(bpart, linebuf, len); + } + } + return 0; +} + +/* This is the big one: parse MIME header lines up to message body */ + +#define MIME_INVALID 0 +#define MIME_START 1 +#define MIME_TYPE 2 +#define MIME_NAME 3 +#define MIME_VALUE 4 +#define MIME_QUOTE 5 +#define MIME_COMMENT 6 + +static STACK_OF(MIME_HEADER) *mime_parse_hdr(BIO *bio) +{ + char *p, *q, c; + char *ntmp; + char linebuf[MAX_SMLEN]; + MIME_HEADER *mhdr = NULL; + STACK_OF(MIME_HEADER) *headers; + int len, state, save_state = 0; + + headers = sk_MIME_HEADER_new(mime_hdr_cmp); + if (!headers) + return NULL; + while ((len = BIO_gets(bio, linebuf, MAX_SMLEN)) > 0) { + /* If whitespace at line start then continuation line */ + if (mhdr && isspace((unsigned char)linebuf[0])) + state = MIME_NAME; + else + state = MIME_START; + ntmp = NULL; + /* Go through all characters */ + for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n'); + p++) { + + /* + * State machine to handle MIME headers if this looks horrible + * that's because it *is* + */ + + switch (state) { + case MIME_START: + if (c == ':') { + state = MIME_TYPE; + *p = 0; + ntmp = strip_ends(q); + q = p + 1; + } + break; + + case MIME_TYPE: + if (c == ';') { + mime_debug("Found End Value\n"); + *p = 0; + mhdr = mime_hdr_new(ntmp, strip_ends(q)); + sk_MIME_HEADER_push(headers, mhdr); + ntmp = NULL; + q = p + 1; + state = MIME_NAME; + } else if (c == '(') { + save_state = state; + state = MIME_COMMENT; + } + break; + + case MIME_COMMENT: + if (c == ')') { + state = save_state; + } + break; + + case MIME_NAME: + if (c == '=') { + state = MIME_VALUE; + *p = 0; + ntmp = strip_ends(q); + q = p + 1; + } + break; + + case MIME_VALUE: + if (c == ';') { + state = MIME_NAME; + *p = 0; + mime_hdr_addparam(mhdr, ntmp, strip_ends(q)); + ntmp = NULL; + q = p + 1; + } else if (c == '"') { + mime_debug("Found Quote\n"); + state = MIME_QUOTE; + } else if (c == '(') { + save_state = state; + state = MIME_COMMENT; + } + break; + + case MIME_QUOTE: + if (c == '"') { + mime_debug("Found Match Quote\n"); + state = MIME_VALUE; + } + break; + } + } + + if (state == MIME_TYPE) { + mhdr = mime_hdr_new(ntmp, strip_ends(q)); + sk_MIME_HEADER_push(headers, mhdr); + } else if (state == MIME_VALUE) + mime_hdr_addparam(mhdr, ntmp, strip_ends(q)); + if (p == linebuf) + break; /* Blank line means end of headers */ + } + + return headers; + +} + +static char *strip_ends(char *name) +{ + return strip_end(strip_start(name)); +} + +/* Strip a parameter of whitespace from start of param */ +static char *strip_start(char *name) +{ + char *p, c; + /* Look for first non white space or quote */ + for (p = name; (c = *p); p++) { + if (c == '"') { + /* Next char is start of string if non null */ + if (p[1]) + return p + 1; + /* Else null string */ + return NULL; + } + if (!isspace((unsigned char)c)) + return p; + } + return NULL; +} + +/* As above but strip from end of string : maybe should handle brackets? */ +static char *strip_end(char *name) +{ + char *p, c; + if (!name) + return NULL; + /* Look for first non white space or quote */ + for (p = name + strlen(name) - 1; p >= name; p--) { + c = *p; + if (c == '"') { + if (p - 1 == name) + return NULL; + *p = 0; + return name; + } + if (isspace((unsigned char)c)) + *p = 0; + else + return name; + } + return NULL; +} + +static MIME_HEADER *mime_hdr_new(char *name, char *value) +{ + MIME_HEADER *mhdr; + char *tmpname, *tmpval, *p; + int c; + if (name) { + if (!(tmpname = BUF_strdup(name))) + return NULL; + for (p = tmpname; *p; p++) { + c = (unsigned char)*p; + if (isupper(c)) { + c = tolower(c); + *p = c; + } + } + } else + tmpname = NULL; + if (value) { + if (!(tmpval = BUF_strdup(value))) + return NULL; + for (p = tmpval; *p; p++) { + c = (unsigned char)*p; + if (isupper(c)) { + c = tolower(c); + *p = c; + } + } + } else + tmpval = NULL; + mhdr = (MIME_HEADER *)OPENSSL_malloc(sizeof(MIME_HEADER)); + if (!mhdr) + return NULL; + mhdr->name = tmpname; + mhdr->value = tmpval; + if (!(mhdr->params = sk_MIME_PARAM_new(mime_param_cmp))) + return NULL; + return mhdr; +} + +static int mime_hdr_addparam(MIME_HEADER *mhdr, char *name, char *value) +{ + char *tmpname, *tmpval, *p; + int c; + MIME_PARAM *mparam; + if (name) { + tmpname = BUF_strdup(name); + if (!tmpname) + return 0; + for (p = tmpname; *p; p++) { + c = (unsigned char)*p; + if (isupper(c)) { + c = tolower(c); + *p = c; + } + } + } else + tmpname = NULL; + if (value) { + tmpval = BUF_strdup(value); + if (!tmpval) + return 0; + } else + tmpval = NULL; + /* Parameter values are case sensitive so leave as is */ + mparam = (MIME_PARAM *)OPENSSL_malloc(sizeof(MIME_PARAM)); + if (!mparam) + return 0; + mparam->param_name = tmpname; + mparam->param_value = tmpval; + sk_MIME_PARAM_push(mhdr->params, mparam); + return 1; +} + +static int mime_hdr_cmp(const MIME_HEADER *const *a, + const MIME_HEADER *const *b) +{ + if (!(*a)->name || !(*b)->name) + return ! !(*a)->name - ! !(*b)->name; + + return (strcmp((*a)->name, (*b)->name)); +} + +static int mime_param_cmp(const MIME_PARAM *const *a, + const MIME_PARAM *const *b) +{ + if (!(*a)->param_name || !(*b)->param_name) + return ! !(*a)->param_name - ! !(*b)->param_name; + return (strcmp((*a)->param_name, (*b)->param_name)); +} + +/* Find a header with a given name (if possible) */ + +static MIME_HEADER *mime_hdr_find(STACK_OF(MIME_HEADER) *hdrs, char *name) +{ + MIME_HEADER htmp; + int idx; + htmp.name = name; + idx = sk_MIME_HEADER_find(hdrs, &htmp); + if (idx < 0) + return NULL; + return sk_MIME_HEADER_value(hdrs, idx); +} + +static MIME_PARAM *mime_param_find(MIME_HEADER *hdr, char *name) +{ + MIME_PARAM param; + int idx; + param.param_name = name; + idx = sk_MIME_PARAM_find(hdr->params, ¶m); + if (idx < 0) + return NULL; + return sk_MIME_PARAM_value(hdr->params, idx); +} + +static void mime_hdr_free(MIME_HEADER *hdr) +{ + if (hdr->name) + OPENSSL_free(hdr->name); + if (hdr->value) + OPENSSL_free(hdr->value); + if (hdr->params) + sk_MIME_PARAM_pop_free(hdr->params, mime_param_free); + OPENSSL_free(hdr); +} + +static void mime_param_free(MIME_PARAM *param) +{ + if (param->param_name) + OPENSSL_free(param->param_name); + if (param->param_value) + OPENSSL_free(param->param_value); + OPENSSL_free(param); +} + +/*- + * Check for a multipart boundary. Returns: + * 0 : no boundary + * 1 : part boundary + * 2 : final boundary + */ +static int mime_bound_check(char *line, int linelen, char *bound, int blen) +{ + if (linelen == -1) + linelen = strlen(line); + if (blen == -1) + blen = strlen(bound); + /* Quickly eliminate if line length too short */ + if (blen + 2 > linelen) + return 0; + /* Check for part boundary */ + if (!strncmp(line, "--", 2) && !strncmp(line + 2, bound, blen)) { + if (!strncmp(line + blen + 2, "--", 2)) + return 2; + else + return 1; + } + return 0; +} + +static int strip_eol(char *linebuf, int *plen) +{ + int len = *plen; + char *p, c; + int is_eol = 0; + p = linebuf + len - 1; + for (p = linebuf + len - 1; len > 0; len--, p--) { + c = *p; + if (c == '\n') + is_eol = 1; + else if (c != '\r') + break; + } + *plen = len; + return is_eol; +} diff --git a/libs/openssl/crypto/asn1/asn_moid.c b/libs/openssl/crypto/asn1/asn_moid.c new file mode 100644 index 00000000..fab2dd92 --- /dev/null +++ b/libs/openssl/crypto/asn1/asn_moid.c @@ -0,0 +1,153 @@ +/* asn_moid.c */ +/* + * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include "cryptlib.h" +#include +#include +#include + +/* Simple ASN1 OID module: add all objects in a given section */ + +static int do_create(char *value, char *name); + +static int oid_module_init(CONF_IMODULE *md, const CONF *cnf) +{ + int i; + const char *oid_section; + STACK_OF(CONF_VALUE) *sktmp; + CONF_VALUE *oval; + oid_section = CONF_imodule_get_value(md); + if (!(sktmp = NCONF_get_section(cnf, oid_section))) { + ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION); + return 0; + } + for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { + oval = sk_CONF_VALUE_value(sktmp, i); + if (!do_create(oval->value, oval->name)) { + ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT); + return 0; + } + } + return 1; +} + +static void oid_module_finish(CONF_IMODULE *md) +{ + OBJ_cleanup(); +} + +void ASN1_add_oid_module(void) +{ + CONF_module_add("oid_section", oid_module_init, oid_module_finish); +} + +/*- + * Create an OID based on a name value pair. Accept two formats. + * shortname = 1.2.3.4 + * shortname = some long name, 1.2.3.4 + */ + +static int do_create(char *value, char *name) +{ + int nid; + ASN1_OBJECT *oid; + char *ln, *ostr, *p, *lntmp; + p = strrchr(value, ','); + if (!p) { + ln = name; + ostr = value; + } else { + ln = NULL; + ostr = p + 1; + if (!*ostr) + return 0; + while (isspace((unsigned char)*ostr)) + ostr++; + } + + nid = OBJ_create(ostr, name, ln); + + if (nid == NID_undef) + return 0; + + if (p) { + ln = value; + while (isspace((unsigned char)*ln)) + ln++; + p--; + while (isspace((unsigned char)*p)) { + if (p == ln) + return 0; + p--; + } + p++; + lntmp = OPENSSL_malloc((p - ln) + 1); + if (lntmp == NULL) + return 0; + memcpy(lntmp, ln, p - ln); + lntmp[p - ln] = 0; + oid = OBJ_nid2obj(nid); + oid->ln = lntmp; + } + + return 1; +} diff --git a/libs/openssl/crypto/asn1/asn_pack.c b/libs/openssl/crypto/asn1/asn_pack.c new file mode 100644 index 00000000..366caf01 --- /dev/null +++ b/libs/openssl/crypto/asn1/asn_pack.c @@ -0,0 +1,207 @@ +/* asn_pack.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +#ifndef NO_ASN1_OLD + +/* ASN1 packing and unpacking functions */ + +/* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */ + +STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len, + d2i_of_void *d2i, + void (*free_func) (OPENSSL_BLOCK)) +{ + STACK_OF(OPENSSL_BLOCK) *sk; + const unsigned char *pbuf; + pbuf = buf; + if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func, + V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL))) + ASN1err(ASN1_F_ASN1_SEQ_UNPACK, ASN1_R_DECODE_ERROR); + return sk; +} + +/* + * Turn a STACK structures into an ASN1 encoded SEQUENCE OF structure in a + * OPENSSL_malloc'ed buffer + */ + +unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d, + unsigned char **buf, int *len) +{ + int safelen; + unsigned char *safe, *p; + if (!(safelen = i2d_ASN1_SET(safes, NULL, i2d, V_ASN1_SEQUENCE, + V_ASN1_UNIVERSAL, IS_SEQUENCE))) { + ASN1err(ASN1_F_ASN1_SEQ_PACK, ASN1_R_ENCODE_ERROR); + return NULL; + } + if (!(safe = OPENSSL_malloc(safelen))) { + ASN1err(ASN1_F_ASN1_SEQ_PACK, ERR_R_MALLOC_FAILURE); + return NULL; + } + p = safe; + i2d_ASN1_SET(safes, &p, i2d, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL, + IS_SEQUENCE); + if (len) + *len = safelen; + if (buf) + *buf = safe; + return safe; +} + +/* Extract an ASN1 object from an ASN1_STRING */ + +void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i) +{ + const unsigned char *p; + char *ret; + + p = oct->data; + if (!(ret = d2i(NULL, &p, oct->length))) + ASN1err(ASN1_F_ASN1_UNPACK_STRING, ASN1_R_DECODE_ERROR); + return ret; +} + +/* Pack an ASN1 object into an ASN1_STRING */ + +ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_STRING **oct) +{ + unsigned char *p; + ASN1_STRING *octmp; + + if (!oct || !*oct) { + if (!(octmp = ASN1_STRING_new())) { + ASN1err(ASN1_F_ASN1_PACK_STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (oct) + *oct = octmp; + } else + octmp = *oct; + + if (!(octmp->length = i2d(obj, NULL))) { + ASN1err(ASN1_F_ASN1_PACK_STRING, ASN1_R_ENCODE_ERROR); + goto err; + } + if (!(p = OPENSSL_malloc(octmp->length))) { + ASN1err(ASN1_F_ASN1_PACK_STRING, ERR_R_MALLOC_FAILURE); + goto err; + } + octmp->data = p; + i2d(obj, &p); + return octmp; + err: + if (!oct || !*oct) { + ASN1_STRING_free(octmp); + if (oct) + *oct = NULL; + } + return NULL; +} + +#endif + +/* ASN1_ITEM versions of the above */ + +ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct) +{ + ASN1_STRING *octmp; + + if (!oct || !*oct) { + if (!(octmp = ASN1_STRING_new())) { + ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (oct) + *oct = octmp; + } else + octmp = *oct; + + if (octmp->data) { + OPENSSL_free(octmp->data); + octmp->data = NULL; + } + + if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) { + ASN1err(ASN1_F_ASN1_ITEM_PACK, ASN1_R_ENCODE_ERROR); + return NULL; + } + if (!octmp->data) { + ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE); + return NULL; + } + return octmp; +} + +/* Extract an ASN1 object from an ASN1_STRING */ + +void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it) +{ + const unsigned char *p; + void *ret; + + p = oct->data; + if (!(ret = ASN1_item_d2i(NULL, &p, oct->length, it))) + ASN1err(ASN1_F_ASN1_ITEM_UNPACK, ASN1_R_DECODE_ERROR); + return ret; +} diff --git a/libs/openssl/crypto/asn1/bio_asn1.c b/libs/openssl/crypto/asn1/bio_asn1.c new file mode 100644 index 00000000..60189b3b --- /dev/null +++ b/libs/openssl/crypto/asn1/bio_asn1.c @@ -0,0 +1,482 @@ +/* bio_asn1.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Experimental ASN1 BIO. When written through the data is converted to an + * ASN1 string type: default is OCTET STRING. Additional functions can be + * provided to add prefix and suffix data. + */ + +#include +#include +#include + +/* Must be large enough for biggest tag+length */ +#define DEFAULT_ASN1_BUF_SIZE 20 + +typedef enum { + ASN1_STATE_START, + ASN1_STATE_PRE_COPY, + ASN1_STATE_HEADER, + ASN1_STATE_HEADER_COPY, + ASN1_STATE_DATA_COPY, + ASN1_STATE_POST_COPY, + ASN1_STATE_DONE +} asn1_bio_state_t; + +typedef struct BIO_ASN1_EX_FUNCS_st { + asn1_ps_func *ex_func; + asn1_ps_func *ex_free_func; +} BIO_ASN1_EX_FUNCS; + +typedef struct BIO_ASN1_BUF_CTX_t { + /* Internal state */ + asn1_bio_state_t state; + /* Internal buffer */ + unsigned char *buf; + /* Size of buffer */ + int bufsize; + /* Current position in buffer */ + int bufpos; + /* Current buffer length */ + int buflen; + /* Amount of data to copy */ + int copylen; + /* Class and tag to use */ + int asn1_class, asn1_tag; + asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free; + /* Extra buffer for prefix and suffix data */ + unsigned char *ex_buf; + int ex_len; + int ex_pos; + void *ex_arg; +} BIO_ASN1_BUF_CTX; + +static int asn1_bio_write(BIO *h, const char *buf, int num); +static int asn1_bio_read(BIO *h, char *buf, int size); +static int asn1_bio_puts(BIO *h, const char *str); +static int asn1_bio_gets(BIO *h, char *str, int size); +static long asn1_bio_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int asn1_bio_new(BIO *h); +static int asn1_bio_free(BIO *data); +static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); + +static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size); +static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, + asn1_ps_func *cleanup, asn1_bio_state_t next); +static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, + asn1_ps_func *setup, + asn1_bio_state_t ex_state, + asn1_bio_state_t other_state); + +static BIO_METHOD methods_asn1 = { + BIO_TYPE_ASN1, + "asn1", + asn1_bio_write, + asn1_bio_read, + asn1_bio_puts, + asn1_bio_gets, + asn1_bio_ctrl, + asn1_bio_new, + asn1_bio_free, + asn1_bio_callback_ctrl, +}; + +BIO_METHOD *BIO_f_asn1(void) +{ + return (&methods_asn1); +} + +static int asn1_bio_new(BIO *b) +{ + BIO_ASN1_BUF_CTX *ctx; + ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX)); + if (!ctx) + return 0; + if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) { + OPENSSL_free(ctx); + return 0; + } + b->init = 1; + b->ptr = (char *)ctx; + b->flags = 0; + return 1; +} + +static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size) +{ + ctx->buf = OPENSSL_malloc(size); + if (!ctx->buf) + return 0; + ctx->bufsize = size; + ctx->bufpos = 0; + ctx->buflen = 0; + ctx->copylen = 0; + ctx->asn1_class = V_ASN1_UNIVERSAL; + ctx->asn1_tag = V_ASN1_OCTET_STRING; + ctx->ex_buf = 0; + ctx->ex_pos = 0; + ctx->ex_len = 0; + ctx->state = ASN1_STATE_START; + return 1; +} + +static int asn1_bio_free(BIO *b) +{ + BIO_ASN1_BUF_CTX *ctx; + ctx = (BIO_ASN1_BUF_CTX *)b->ptr; + if (ctx == NULL) + return 0; + if (ctx->buf) + OPENSSL_free(ctx->buf); + OPENSSL_free(ctx); + b->init = 0; + b->ptr = NULL; + b->flags = 0; + return 1; +} + +static int asn1_bio_write(BIO *b, const char *in, int inl) +{ + BIO_ASN1_BUF_CTX *ctx; + int wrmax, wrlen, ret; + unsigned char *p; + if (!in || (inl < 0) || (b->next_bio == NULL)) + return 0; + ctx = (BIO_ASN1_BUF_CTX *)b->ptr; + if (ctx == NULL) + return 0; + + wrlen = 0; + ret = -1; + + for (;;) { + switch (ctx->state) { + + /* Setup prefix data, call it */ + case ASN1_STATE_START: + if (!asn1_bio_setup_ex(b, ctx, ctx->prefix, + ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER)) + return 0; + break; + + /* Copy any pre data first */ + case ASN1_STATE_PRE_COPY: + + ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free, + ASN1_STATE_HEADER); + + if (ret <= 0) + goto done; + + break; + + case ASN1_STATE_HEADER: + ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl; + OPENSSL_assert(ctx->buflen <= ctx->bufsize); + p = ctx->buf; + ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class); + ctx->copylen = inl; + ctx->state = ASN1_STATE_HEADER_COPY; + + break; + + case ASN1_STATE_HEADER_COPY: + ret = BIO_write(b->next_bio, ctx->buf + ctx->bufpos, ctx->buflen); + if (ret <= 0) + goto done; + + ctx->buflen -= ret; + if (ctx->buflen) + ctx->bufpos += ret; + else { + ctx->bufpos = 0; + ctx->state = ASN1_STATE_DATA_COPY; + } + + break; + + case ASN1_STATE_DATA_COPY: + + if (inl > ctx->copylen) + wrmax = ctx->copylen; + else + wrmax = inl; + ret = BIO_write(b->next_bio, in, wrmax); + if (ret <= 0) + break; + wrlen += ret; + ctx->copylen -= ret; + in += ret; + inl -= ret; + + if (ctx->copylen == 0) + ctx->state = ASN1_STATE_HEADER; + + if (inl == 0) + goto done; + + break; + + default: + BIO_clear_retry_flags(b); + return 0; + + } + + } + + done: + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + + return (wrlen > 0) ? wrlen : ret; + +} + +static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, + asn1_ps_func *cleanup, asn1_bio_state_t next) +{ + int ret; + if (ctx->ex_len <= 0) + return 1; + for (;;) { + ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos, ctx->ex_len); + if (ret <= 0) + break; + ctx->ex_len -= ret; + if (ctx->ex_len > 0) + ctx->ex_pos += ret; + else { + if (cleanup) + cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg); + ctx->state = next; + ctx->ex_pos = 0; + break; + } + } + return ret; +} + +static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx, + asn1_ps_func *setup, + asn1_bio_state_t ex_state, + asn1_bio_state_t other_state) +{ + if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) { + BIO_clear_retry_flags(b); + return 0; + } + if (ctx->ex_len > 0) + ctx->state = ex_state; + else + ctx->state = other_state; + return 1; +} + +static int asn1_bio_read(BIO *b, char *in, int inl) +{ + if (!b->next_bio) + return 0; + return BIO_read(b->next_bio, in, inl); +} + +static int asn1_bio_puts(BIO *b, const char *str) +{ + return asn1_bio_write(b, str, strlen(str)); +} + +static int asn1_bio_gets(BIO *b, char *str, int size) +{ + if (!b->next_bio) + return 0; + return BIO_gets(b->next_bio, str, size); +} + +static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + if (b->next_bio == NULL) + return (0); + return BIO_callback_ctrl(b->next_bio, cmd, fp); +} + +static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2) +{ + BIO_ASN1_BUF_CTX *ctx; + BIO_ASN1_EX_FUNCS *ex_func; + long ret = 1; + ctx = (BIO_ASN1_BUF_CTX *)b->ptr; + if (ctx == NULL) + return 0; + switch (cmd) { + + case BIO_C_SET_PREFIX: + ex_func = arg2; + ctx->prefix = ex_func->ex_func; + ctx->prefix_free = ex_func->ex_free_func; + break; + + case BIO_C_GET_PREFIX: + ex_func = arg2; + ex_func->ex_func = ctx->prefix; + ex_func->ex_free_func = ctx->prefix_free; + break; + + case BIO_C_SET_SUFFIX: + ex_func = arg2; + ctx->suffix = ex_func->ex_func; + ctx->suffix_free = ex_func->ex_free_func; + break; + + case BIO_C_GET_SUFFIX: + ex_func = arg2; + ex_func->ex_func = ctx->suffix; + ex_func->ex_free_func = ctx->suffix_free; + break; + + case BIO_C_SET_EX_ARG: + ctx->ex_arg = arg2; + break; + + case BIO_C_GET_EX_ARG: + *(void **)arg2 = ctx->ex_arg; + break; + + case BIO_CTRL_FLUSH: + if (!b->next_bio) + return 0; + + /* Call post function if possible */ + if (ctx->state == ASN1_STATE_HEADER) { + if (!asn1_bio_setup_ex(b, ctx, ctx->suffix, + ASN1_STATE_POST_COPY, ASN1_STATE_DONE)) + return 0; + } + + if (ctx->state == ASN1_STATE_POST_COPY) { + ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free, + ASN1_STATE_DONE); + if (ret <= 0) + return ret; + } + + if (ctx->state == ASN1_STATE_DONE) + return BIO_ctrl(b->next_bio, cmd, arg1, arg2); + else { + BIO_clear_retry_flags(b); + return 0; + } + break; + + default: + if (!b->next_bio) + return 0; + return BIO_ctrl(b->next_bio, cmd, arg1, arg2); + + } + + return ret; +} + +static int asn1_bio_set_ex(BIO *b, int cmd, + asn1_ps_func *ex_func, asn1_ps_func *ex_free_func) +{ + BIO_ASN1_EX_FUNCS extmp; + extmp.ex_func = ex_func; + extmp.ex_free_func = ex_free_func; + return BIO_ctrl(b, cmd, 0, &extmp); +} + +static int asn1_bio_get_ex(BIO *b, int cmd, + asn1_ps_func **ex_func, + asn1_ps_func **ex_free_func) +{ + BIO_ASN1_EX_FUNCS extmp; + int ret; + ret = BIO_ctrl(b, cmd, 0, &extmp); + if (ret > 0) { + *ex_func = extmp.ex_func; + *ex_free_func = extmp.ex_free_func; + } + return ret; +} + +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, + asn1_ps_func *prefix_free) +{ + return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free); +} + +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, + asn1_ps_func **pprefix_free) +{ + return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free); +} + +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, + asn1_ps_func *suffix_free) +{ + return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free); +} + +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, + asn1_ps_func **psuffix_free) +{ + return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free); +} diff --git a/libs/openssl/crypto/asn1/bio_ndef.c b/libs/openssl/crypto/asn1/bio_ndef.c new file mode 100644 index 00000000..31949b87 --- /dev/null +++ b/libs/openssl/crypto/asn1/bio_ndef.c @@ -0,0 +1,248 @@ +/* bio_ndef.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include +#include + +#include + +/* Experimental NDEF ASN1 BIO support routines */ + +/* + * The usage is quite simple, initialize an ASN1 structure, get a BIO from it + * then any data written through the BIO will end up translated to + * approptiate format on the fly. The data is streamed out and does *not* + * need to be all held in memory at once. When the BIO is flushed the output + * is finalized and any signatures etc written out. The BIO is a 'proper' + * BIO and can handle non blocking I/O correctly. The usage is simple. The + * implementation is *not*... + */ + +/* BIO support data stored in the ASN1 BIO ex_arg */ + +typedef struct ndef_aux_st { + /* ASN1 structure this BIO refers to */ + ASN1_VALUE *val; + const ASN1_ITEM *it; + /* Top of the BIO chain */ + BIO *ndef_bio; + /* Output BIO */ + BIO *out; + /* Boundary where content is inserted */ + unsigned char **boundary; + /* DER buffer start */ + unsigned char *derbuf; +} NDEF_SUPPORT; + +static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg); +static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, + void *parg); +static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg); +static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, + void *parg); + +BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it) +{ + NDEF_SUPPORT *ndef_aux = NULL; + BIO *asn_bio = NULL; + const ASN1_AUX *aux = it->funcs; + ASN1_STREAM_ARG sarg; + + if (!aux || !aux->asn1_cb) { + ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED); + return NULL; + } + ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT)); + asn_bio = BIO_new(BIO_f_asn1()); + + /* ASN1 bio needs to be next to output BIO */ + + out = BIO_push(asn_bio, out); + + if (!ndef_aux || !asn_bio || !out) + goto err; + + BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free); + BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free); + + /* + * Now let callback prepend any digest, cipher etc BIOs ASN1 structure + * needs. + */ + + sarg.out = out; + sarg.ndef_bio = NULL; + sarg.boundary = NULL; + + if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0) + goto err; + + ndef_aux->val = val; + ndef_aux->it = it; + ndef_aux->ndef_bio = sarg.ndef_bio; + ndef_aux->boundary = sarg.boundary; + ndef_aux->out = out; + + BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux); + + return sarg.ndef_bio; + + err: + if (asn_bio) + BIO_free(asn_bio); + if (ndef_aux) + OPENSSL_free(ndef_aux); + return NULL; +} + +static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg) +{ + NDEF_SUPPORT *ndef_aux; + unsigned char *p; + int derlen; + + if (!parg) + return 0; + + ndef_aux = *(NDEF_SUPPORT **)parg; + + derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it); + p = OPENSSL_malloc(derlen); + if (!p) + return 0; + + ndef_aux->derbuf = p; + *pbuf = p; + derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); + + if (!*ndef_aux->boundary) + return 0; + + *plen = *ndef_aux->boundary - *pbuf; + + return 1; +} + +static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, + void *parg) +{ + NDEF_SUPPORT *ndef_aux; + + if (!parg) + return 0; + + ndef_aux = *(NDEF_SUPPORT **)parg; + + if (ndef_aux->derbuf) + OPENSSL_free(ndef_aux->derbuf); + + ndef_aux->derbuf = NULL; + *pbuf = NULL; + *plen = 0; + return 1; +} + +static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, + void *parg) +{ + NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg; + if (!ndef_prefix_free(b, pbuf, plen, parg)) + return 0; + OPENSSL_free(*pndef_aux); + *pndef_aux = NULL; + return 1; +} + +static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg) +{ + NDEF_SUPPORT *ndef_aux; + unsigned char *p; + int derlen; + const ASN1_AUX *aux; + ASN1_STREAM_ARG sarg; + + if (!parg) + return 0; + + ndef_aux = *(NDEF_SUPPORT **)parg; + + aux = ndef_aux->it->funcs; + + /* Finalize structures */ + sarg.ndef_bio = ndef_aux->ndef_bio; + sarg.out = ndef_aux->out; + sarg.boundary = ndef_aux->boundary; + if (aux->asn1_cb(ASN1_OP_STREAM_POST, + &ndef_aux->val, ndef_aux->it, &sarg) <= 0) + return 0; + + derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it); + p = OPENSSL_malloc(derlen); + if (!p) + return 0; + + ndef_aux->derbuf = p; + *pbuf = p; + derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it); + + if (!*ndef_aux->boundary) + return 0; + *pbuf = *ndef_aux->boundary; + *plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf); + + return 1; +} diff --git a/libs/openssl/crypto/asn1/charmap.h b/libs/openssl/crypto/asn1/charmap.h new file mode 100644 index 00000000..3305ad14 --- /dev/null +++ b/libs/openssl/crypto/asn1/charmap.h @@ -0,0 +1,15 @@ +/* + * Auto generated with chartype.pl script. Mask of various character + * properties + */ + +static const unsigned char char_type[] = { + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 120, 0, 1, 40, 0, 0, 0, 16, 16, 16, 0, 25, 25, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 9, 16, 9, 16, + 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 0, 0, 0, + 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, + 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 2 +}; diff --git a/libs/openssl/crypto/asn1/charmap.pl b/libs/openssl/crypto/asn1/charmap.pl new file mode 100644 index 00000000..25ebf2c2 --- /dev/null +++ b/libs/openssl/crypto/asn1/charmap.pl @@ -0,0 +1,83 @@ +#!/usr/local/bin/perl -w + +# Written by Dr Stephen N Henson (steve@openssl.org). +# Licensed under the terms of the OpenSSL license. + +use strict; + +my ($i, @arr); + +# Set up an array with the type of ASCII characters +# Each set bit represents a character property. + +# RFC2253 character properties +my $RFC2253_ESC = 1; # Character escaped with \ +my $ESC_CTRL = 2; # Escaped control character +# These are used with RFC1779 quoting using " +my $NOESC_QUOTE = 8; # Not escaped if quoted +my $PSTRING_CHAR = 0x10; # Valid PrintableString character +my $RFC2253_FIRST_ESC = 0x20; # Escaped with \ if first character +my $RFC2253_LAST_ESC = 0x40; # Escaped with \ if last character + +for($i = 0; $i < 128; $i++) { + # Set the RFC2253 escape characters (control) + $arr[$i] = 0; + if(($i < 32) || ($i > 126)) { + $arr[$i] |= $ESC_CTRL; + } + + # Some PrintableString characters + if( ( ( $i >= ord("a")) && ( $i <= ord("z")) ) + || ( ( $i >= ord("A")) && ( $i <= ord("Z")) ) + || ( ( $i >= ord("0")) && ( $i <= ord("9")) ) ) { + $arr[$i] |= $PSTRING_CHAR; + } +} + +# Now setup the rest + +# Remaining RFC2253 escaped characters + +$arr[ord(" ")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC | $RFC2253_LAST_ESC; +$arr[ord("#")] |= $NOESC_QUOTE | $RFC2253_FIRST_ESC; + +$arr[ord(",")] |= $NOESC_QUOTE | $RFC2253_ESC; +$arr[ord("+")] |= $NOESC_QUOTE | $RFC2253_ESC; +$arr[ord("\"")] |= $RFC2253_ESC; +$arr[ord("\\")] |= $RFC2253_ESC; +$arr[ord("<")] |= $NOESC_QUOTE | $RFC2253_ESC; +$arr[ord(">")] |= $NOESC_QUOTE | $RFC2253_ESC; +$arr[ord(";")] |= $NOESC_QUOTE | $RFC2253_ESC; + +# Remaining PrintableString characters + +$arr[ord(" ")] |= $PSTRING_CHAR; +$arr[ord("'")] |= $PSTRING_CHAR; +$arr[ord("(")] |= $PSTRING_CHAR; +$arr[ord(")")] |= $PSTRING_CHAR; +$arr[ord("+")] |= $PSTRING_CHAR; +$arr[ord(",")] |= $PSTRING_CHAR; +$arr[ord("-")] |= $PSTRING_CHAR; +$arr[ord(".")] |= $PSTRING_CHAR; +$arr[ord("/")] |= $PSTRING_CHAR; +$arr[ord(":")] |= $PSTRING_CHAR; +$arr[ord("=")] |= $PSTRING_CHAR; +$arr[ord("?")] |= $PSTRING_CHAR; + +# Now generate the C code + +print < +#include "cryptlib.h" +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include +#include +#include "asn1_locl.h" + +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length) +{ + EVP_PKEY *ret; + const unsigned char *p = *pp; + + if ((a == NULL) || (*a == NULL)) { + if ((ret = EVP_PKEY_new()) == NULL) { + ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB); + return (NULL); + } + } else { + ret = *a; +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) { + ENGINE_finish(ret->engine); + ret->engine = NULL; + } +#endif + } + + if (!EVP_PKEY_set_type(ret, type)) { + ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); + goto err; + } + + if (!ret->ameth->old_priv_decode || + !ret->ameth->old_priv_decode(ret, &p, length)) { + if (ret->ameth->priv_decode) { + PKCS8_PRIV_KEY_INFO *p8 = NULL; + p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); + if (!p8) + goto err; + EVP_PKEY_free(ret); + ret = EVP_PKCS82PKEY(p8); + PKCS8_PRIV_KEY_INFO_free(p8); + if (ret == NULL) + goto err; + } else { + ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB); + goto err; + } + } + *pp = p; + if (a != NULL) + (*a) = ret; + return (ret); + err: + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + EVP_PKEY_free(ret); + return (NULL); +} + +/* + * This works like d2i_PrivateKey() except it automatically works out the + * type + */ + +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length) +{ + STACK_OF(ASN1_TYPE) *inkey; + const unsigned char *p; + int keytype; + p = *pp; + /* + * Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by + * analyzing it we can determine the passed structure: this assumes the + * input is surrounded by an ASN1 SEQUENCE. + */ + inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length); + p = *pp; + /* + * Since we only need to discern "traditional format" RSA and DSA keys we + * can just count the elements. + */ + if (sk_ASN1_TYPE_num(inkey) == 6) + keytype = EVP_PKEY_DSA; + else if (sk_ASN1_TYPE_num(inkey) == 4) + keytype = EVP_PKEY_EC; + else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not + * traditional format */ + PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length); + EVP_PKEY *ret; + + sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); + if (!p8) { + ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY, + ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return NULL; + } + ret = EVP_PKCS82PKEY(p8); + PKCS8_PRIV_KEY_INFO_free(p8); + if (ret == NULL) + return NULL; + *pp = p; + if (a) { + *a = ret; + } + return ret; + } else + keytype = EVP_PKEY_RSA; + sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free); + return d2i_PrivateKey(keytype, a, pp, length); +} diff --git a/libs/openssl/crypto/asn1/d2i_pu.c b/libs/openssl/crypto/asn1/d2i_pu.c new file mode 100644 index 00000000..33542dd1 --- /dev/null +++ b/libs/openssl/crypto/asn1/d2i_pu.c @@ -0,0 +1,136 @@ +/* crypto/asn1/d2i_pu.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#ifndef OPENSSL_NO_DSA +# include +#endif +#ifndef OPENSSL_NO_EC +# include +#endif + +EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length) +{ + EVP_PKEY *ret; + + if ((a == NULL) || (*a == NULL)) { + if ((ret = EVP_PKEY_new()) == NULL) { + ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB); + return (NULL); + } + } else + ret = *a; + + if (!EVP_PKEY_set_type(ret, type)) { + ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB); + goto err; + } + + switch (EVP_PKEY_id(ret)) { +#ifndef OPENSSL_NO_RSA + case EVP_PKEY_RSA: + /* TMP UGLY CAST */ + if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL, + (const unsigned char **)pp, + length)) == NULL) { + ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); + goto err; + } + break; +#endif +#ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: + /* TMP UGLY CAST */ + if (!d2i_DSAPublicKey(&(ret->pkey.dsa), + (const unsigned char **)pp, length)) { + ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); + goto err; + } + break; +#endif +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + if (!o2i_ECPublicKey(&(ret->pkey.ec), + (const unsigned char **)pp, length)) { + ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB); + goto err; + } + break; +#endif + default: + ASN1err(ASN1_F_D2I_PUBLICKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE); + goto err; + /* break; */ + } + if (a != NULL) + (*a) = ret; + return (ret); + err: + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + EVP_PKEY_free(ret); + return (NULL); +} diff --git a/libs/openssl/crypto/asn1/evp_asn1.c b/libs/openssl/crypto/asn1/evp_asn1.c new file mode 100644 index 00000000..5876afa5 --- /dev/null +++ b/libs/openssl/crypto/asn1/evp_asn1.c @@ -0,0 +1,195 @@ +/* crypto/asn1/evp_asn1.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len) +{ + ASN1_STRING *os; + + if ((os = M_ASN1_OCTET_STRING_new()) == NULL) + return (0); + if (!M_ASN1_OCTET_STRING_set(os, data, len)) { + M_ASN1_OCTET_STRING_free(os); + return 0; + } + ASN1_TYPE_set(a, V_ASN1_OCTET_STRING, os); + return (1); +} + +/* int max_len: for returned value */ +int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len) +{ + int ret, num; + unsigned char *p; + + if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL)) { + ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING, ASN1_R_DATA_IS_WRONG); + return (-1); + } + p = M_ASN1_STRING_data(a->value.octet_string); + ret = M_ASN1_STRING_length(a->value.octet_string); + if (ret < max_len) + num = ret; + else + num = max_len; + memcpy(data, p, num); + return (ret); +} + +int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data, + int len) +{ + int n, size; + ASN1_OCTET_STRING os, *osp; + ASN1_INTEGER in; + unsigned char *p; + unsigned char buf[32]; /* when they have 256bit longs, I'll be in + * trouble */ + in.data = buf; + in.length = 32; + os.data = data; + os.type = V_ASN1_OCTET_STRING; + os.length = len; + ASN1_INTEGER_set(&in, num); + n = i2d_ASN1_INTEGER(&in, NULL); + n += M_i2d_ASN1_OCTET_STRING(&os, NULL); + + size = ASN1_object_size(1, n, V_ASN1_SEQUENCE); + + if ((osp = ASN1_STRING_new()) == NULL) + return (0); + /* Grow the 'string' */ + if (!ASN1_STRING_set(osp, NULL, size)) { + ASN1_STRING_free(osp); + return (0); + } + + M_ASN1_STRING_length_set(osp, size); + p = M_ASN1_STRING_data(osp); + + ASN1_put_object(&p, 1, n, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL); + i2d_ASN1_INTEGER(&in, &p); + M_i2d_ASN1_OCTET_STRING(&os, &p); + + ASN1_TYPE_set(a, V_ASN1_SEQUENCE, osp); + return (1); +} + +/* + * we return the actual length..., num may be missing, in which case, set it + * to zero + */ +/* int max_len: for returned value */ +int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, + unsigned char *data, int max_len) +{ + int ret = -1, n; + ASN1_INTEGER *ai = NULL; + ASN1_OCTET_STRING *os = NULL; + const unsigned char *p; + long length; + ASN1_const_CTX c; + + if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) { + goto err; + } + p = M_ASN1_STRING_data(a->value.sequence); + length = M_ASN1_STRING_length(a->value.sequence); + + c.pp = &p; + c.p = p; + c.max = p + length; + c.error = ASN1_R_DATA_IS_WRONG; + + M_ASN1_D2I_start_sequence(); + c.q = c.p; + if ((ai = d2i_ASN1_INTEGER(NULL, &c.p, c.slen)) == NULL) + goto err; + c.slen -= (c.p - c.q); + c.q = c.p; + if ((os = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL) + goto err; + c.slen -= (c.p - c.q); + if (!M_ASN1_D2I_end_sequence()) + goto err; + + if (num != NULL) + *num = ASN1_INTEGER_get(ai); + + ret = M_ASN1_STRING_length(os); + if (max_len > ret) + n = ret; + else + n = max_len; + + if (data != NULL) + memcpy(data, M_ASN1_STRING_data(os), n); + if (0) { + err: + ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, ASN1_R_DATA_IS_WRONG); + } + if (os != NULL) + M_ASN1_OCTET_STRING_free(os); + if (ai != NULL) + M_ASN1_INTEGER_free(ai); + return (ret); +} diff --git a/libs/openssl/crypto/asn1/f_enum.c b/libs/openssl/crypto/asn1/f_enum.c new file mode 100644 index 00000000..591c3b57 --- /dev/null +++ b/libs/openssl/crypto/asn1/f_enum.c @@ -0,0 +1,203 @@ +/* crypto/asn1/f_enum.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +/* Based on a_int.c: equivalent ENUMERATED functions */ + +int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a) +{ + int i, n = 0; + static const char *h = "0123456789ABCDEF"; + char buf[2]; + + if (a == NULL) + return (0); + + if (a->length == 0) { + if (BIO_write(bp, "00", 2) != 2) + goto err; + n = 2; + } else { + for (i = 0; i < a->length; i++) { + if ((i != 0) && (i % 35 == 0)) { + if (BIO_write(bp, "\\\n", 2) != 2) + goto err; + n += 2; + } + buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; + buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; + if (BIO_write(bp, buf, 2) != 2) + goto err; + n += 2; + } + } + return (n); + err: + return (-1); +} + +int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size) +{ + int ret = 0; + int i, j, k, m, n, again, bufsize; + unsigned char *s = NULL, *sp; + unsigned char *bufp; + int num = 0, slen = 0, first = 1; + + bs->type = V_ASN1_ENUMERATED; + + bufsize = BIO_gets(bp, buf, size); + for (;;) { + if (bufsize < 1) + goto err_sl; + i = bufsize; + if (buf[i - 1] == '\n') + buf[--i] = '\0'; + if (i == 0) + goto err_sl; + if (buf[i - 1] == '\r') + buf[--i] = '\0'; + if (i == 0) + goto err_sl; + again = (buf[i - 1] == '\\'); + + for (j = 0; j < i; j++) { + if (!(((buf[j] >= '0') && (buf[j] <= '9')) || + ((buf[j] >= 'a') && (buf[j] <= 'f')) || + ((buf[j] >= 'A') && (buf[j] <= 'F')))) { + i = j; + break; + } + } + buf[i] = '\0'; + /* + * We have now cleared all the crap off the end of the line + */ + if (i < 2) + goto err_sl; + + bufp = (unsigned char *)buf; + if (first) { + first = 0; + if ((bufp[0] == '0') && (buf[1] == '0')) { + bufp += 2; + i -= 2; + } + } + k = 0; + i -= again; + if (i % 2 != 0) { + ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_ODD_NUMBER_OF_CHARS); + goto err; + } + i /= 2; + if (num + i > slen) { + if (s == NULL) + sp = (unsigned char *)OPENSSL_malloc((unsigned int)num + + i * 2); + else + sp = (unsigned char *)OPENSSL_realloc(s, + (unsigned int)num + + i * 2); + if (sp == NULL) { + ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); + if (s != NULL) + OPENSSL_free(s); + goto err; + } + s = sp; + slen = num + i * 2; + } + for (j = 0; j < i; j++, k += 2) { + for (n = 0; n < 2; n++) { + m = bufp[k + n]; + if ((m >= '0') && (m <= '9')) + m -= '0'; + else if ((m >= 'a') && (m <= 'f')) + m = m - 'a' + 10; + else if ((m >= 'A') && (m <= 'F')) + m = m - 'A' + 10; + else { + ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, + ASN1_R_NON_HEX_CHARACTERS); + goto err; + } + s[num + j] <<= 4; + s[num + j] |= m; + } + } + num += i; + if (again) + bufsize = BIO_gets(bp, buf, size); + else + break; + } + bs->length = num; + bs->data = s; + ret = 1; + err: + if (0) { + err_sl: + ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_SHORT_LINE); + } + return (ret); +} diff --git a/libs/openssl/crypto/asn1/f_int.c b/libs/openssl/crypto/asn1/f_int.c new file mode 100644 index 00000000..4a81f81c --- /dev/null +++ b/libs/openssl/crypto/asn1/f_int.c @@ -0,0 +1,215 @@ +/* crypto/asn1/f_int.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a) +{ + int i, n = 0; + static const char *h = "0123456789ABCDEF"; + char buf[2]; + + if (a == NULL) + return (0); + + if (a->type & V_ASN1_NEG) { + if (BIO_write(bp, "-", 1) != 1) + goto err; + n = 1; + } + + if (a->length == 0) { + if (BIO_write(bp, "00", 2) != 2) + goto err; + n += 2; + } else { + for (i = 0; i < a->length; i++) { + if ((i != 0) && (i % 35 == 0)) { + if (BIO_write(bp, "\\\n", 2) != 2) + goto err; + n += 2; + } + buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; + buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; + if (BIO_write(bp, buf, 2) != 2) + goto err; + n += 2; + } + } + return (n); + err: + return (-1); +} + +int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size) +{ + int ret = 0; + int i, j, k, m, n, again, bufsize; + unsigned char *s = NULL, *sp; + unsigned char *bufp; + int num = 0, slen = 0, first = 1; + + bs->type = V_ASN1_INTEGER; + + bufsize = BIO_gets(bp, buf, size); + for (;;) { + if (bufsize < 1) + goto err_sl; + i = bufsize; + if (buf[i - 1] == '\n') + buf[--i] = '\0'; + if (i == 0) + goto err_sl; + if (buf[i - 1] == '\r') + buf[--i] = '\0'; + if (i == 0) + goto err_sl; + again = (buf[i - 1] == '\\'); + + for (j = 0; j < i; j++) { +#ifndef CHARSET_EBCDIC + if (!(((buf[j] >= '0') && (buf[j] <= '9')) || + ((buf[j] >= 'a') && (buf[j] <= 'f')) || + ((buf[j] >= 'A') && (buf[j] <= 'F')))) +#else + /* + * This #ifdef is not strictly necessary, since the characters + * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but + * not the whole alphabet). Nevertheless, isxdigit() is faster. + */ + if (!isxdigit(buf[j])) +#endif + { + i = j; + break; + } + } + buf[i] = '\0'; + /* + * We have now cleared all the crap off the end of the line + */ + if (i < 2) + goto err_sl; + + bufp = (unsigned char *)buf; + if (first) { + first = 0; + if ((bufp[0] == '0') && (buf[1] == '0')) { + bufp += 2; + i -= 2; + } + } + k = 0; + i -= again; + if (i % 2 != 0) { + ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS); + goto err; + } + i /= 2; + if (num + i > slen) { + if (s == NULL) + sp = (unsigned char *)OPENSSL_malloc((unsigned int)num + + i * 2); + else + sp = OPENSSL_realloc_clean(s, slen, num + i * 2); + if (sp == NULL) { + ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); + if (s != NULL) + OPENSSL_free(s); + goto err; + } + s = sp; + slen = num + i * 2; + } + for (j = 0; j < i; j++, k += 2) { + for (n = 0; n < 2; n++) { + m = bufp[k + n]; + if ((m >= '0') && (m <= '9')) + m -= '0'; + else if ((m >= 'a') && (m <= 'f')) + m = m - 'a' + 10; + else if ((m >= 'A') && (m <= 'F')) + m = m - 'A' + 10; + else { + ASN1err(ASN1_F_A2I_ASN1_INTEGER, + ASN1_R_NON_HEX_CHARACTERS); + goto err; + } + s[num + j] <<= 4; + s[num + j] |= m; + } + } + num += i; + if (again) + bufsize = BIO_gets(bp, buf, size); + else + break; + } + bs->length = num; + bs->data = s; + ret = 1; + err: + if (0) { + err_sl: + ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE); + } + return (ret); +} diff --git a/libs/openssl/crypto/asn1/f_string.c b/libs/openssl/crypto/asn1/f_string.c new file mode 100644 index 00000000..6a6cf347 --- /dev/null +++ b/libs/openssl/crypto/asn1/f_string.c @@ -0,0 +1,209 @@ +/* crypto/asn1/f_string.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type) +{ + int i, n = 0; + static const char *h = "0123456789ABCDEF"; + char buf[2]; + + if (a == NULL) + return (0); + + if (a->length == 0) { + if (BIO_write(bp, "0", 1) != 1) + goto err; + n = 1; + } else { + for (i = 0; i < a->length; i++) { + if ((i != 0) && (i % 35 == 0)) { + if (BIO_write(bp, "\\\n", 2) != 2) + goto err; + n += 2; + } + buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f]; + buf[1] = h[((unsigned char)a->data[i]) & 0x0f]; + if (BIO_write(bp, buf, 2) != 2) + goto err; + n += 2; + } + } + return (n); + err: + return (-1); +} + +int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size) +{ + int ret = 0; + int i, j, k, m, n, again, bufsize; + unsigned char *s = NULL, *sp; + unsigned char *bufp; + int num = 0, slen = 0, first = 1; + + bufsize = BIO_gets(bp, buf, size); + for (;;) { + if (bufsize < 1) { + if (first) + break; + else + goto err_sl; + } + first = 0; + + i = bufsize; + if (buf[i - 1] == '\n') + buf[--i] = '\0'; + if (i == 0) + goto err_sl; + if (buf[i - 1] == '\r') + buf[--i] = '\0'; + if (i == 0) + goto err_sl; + again = (buf[i - 1] == '\\'); + + for (j = i - 1; j > 0; j--) { +#ifndef CHARSET_EBCDIC + if (!(((buf[j] >= '0') && (buf[j] <= '9')) || + ((buf[j] >= 'a') && (buf[j] <= 'f')) || + ((buf[j] >= 'A') && (buf[j] <= 'F')))) +#else + /* + * This #ifdef is not strictly necessary, since the characters + * A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but + * not the whole alphabet). Nevertheless, isxdigit() is faster. + */ + if (!isxdigit(buf[j])) +#endif + { + i = j; + break; + } + } + buf[i] = '\0'; + /* + * We have now cleared all the crap off the end of the line + */ + if (i < 2) + goto err_sl; + + bufp = (unsigned char *)buf; + + k = 0; + i -= again; + if (i % 2 != 0) { + ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS); + goto err; + } + i /= 2; + if (num + i > slen) { + if (s == NULL) + sp = (unsigned char *)OPENSSL_malloc((unsigned int)num + + i * 2); + else + sp = (unsigned char *)OPENSSL_realloc(s, + (unsigned int)num + + i * 2); + if (sp == NULL) { + ASN1err(ASN1_F_A2I_ASN1_STRING, ERR_R_MALLOC_FAILURE); + if (s != NULL) + OPENSSL_free(s); + goto err; + } + s = sp; + slen = num + i * 2; + } + for (j = 0; j < i; j++, k += 2) { + for (n = 0; n < 2; n++) { + m = bufp[k + n]; + if ((m >= '0') && (m <= '9')) + m -= '0'; + else if ((m >= 'a') && (m <= 'f')) + m = m - 'a' + 10; + else if ((m >= 'A') && (m <= 'F')) + m = m - 'A' + 10; + else { + ASN1err(ASN1_F_A2I_ASN1_STRING, + ASN1_R_NON_HEX_CHARACTERS); + goto err; + } + s[num + j] <<= 4; + s[num + j] |= m; + } + } + num += i; + if (again) + bufsize = BIO_gets(bp, buf, size); + else + break; + } + bs->length = num; + bs->data = s; + ret = 1; + err: + if (0) { + err_sl: + ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE); + } + return (ret); +} diff --git a/libs/openssl/crypto/asn1/i2d_pr.c b/libs/openssl/crypto/asn1/i2d_pr.c new file mode 100644 index 00000000..4d338ac5 --- /dev/null +++ b/libs/openssl/crypto/asn1/i2d_pr.c @@ -0,0 +1,78 @@ +/* crypto/asn1/i2d_pr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include "asn1_locl.h" + +int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp) +{ + if (a->ameth && a->ameth->old_priv_encode) { + return a->ameth->old_priv_encode(a, pp); + } + if (a->ameth && a->ameth->priv_encode) { + PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a); + int ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp); + PKCS8_PRIV_KEY_INFO_free(p8); + return ret; + } + ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return (-1); +} diff --git a/libs/openssl/crypto/asn1/i2d_pu.c b/libs/openssl/crypto/asn1/i2d_pu.c new file mode 100644 index 00000000..b8ed3554 --- /dev/null +++ b/libs/openssl/crypto/asn1/i2d_pu.c @@ -0,0 +1,93 @@ +/* crypto/asn1/i2d_pu.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#ifndef OPENSSL_NO_DSA +# include +#endif +#ifndef OPENSSL_NO_EC +# include +#endif + +int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp) +{ + switch (a->type) { +#ifndef OPENSSL_NO_RSA + case EVP_PKEY_RSA: + return (i2d_RSAPublicKey(a->pkey.rsa, pp)); +#endif +#ifndef OPENSSL_NO_DSA + case EVP_PKEY_DSA: + return (i2d_DSAPublicKey(a->pkey.dsa, pp)); +#endif +#ifndef OPENSSL_NO_EC + case EVP_PKEY_EC: + return (i2o_ECPublicKey(a->pkey.ec, pp)); +#endif + default: + ASN1err(ASN1_F_I2D_PUBLICKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return (-1); + } +} diff --git a/libs/openssl/crypto/asn1/n_pkey.c b/libs/openssl/crypto/asn1/n_pkey.c new file mode 100644 index 00000000..d5a55146 --- /dev/null +++ b/libs/openssl/crypto/asn1/n_pkey.c @@ -0,0 +1,345 @@ +/* crypto/asn1/n_pkey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#ifndef OPENSSL_NO_RSA +# include +# include +# include +# include +# include +# include + +# ifndef OPENSSL_NO_RC4 + +typedef struct netscape_pkey_st { + long version; + X509_ALGOR *algor; + ASN1_OCTET_STRING *private_key; +} NETSCAPE_PKEY; + +typedef struct netscape_encrypted_pkey_st { + ASN1_OCTET_STRING *os; + /* + * This is the same structure as DigestInfo so use it: although this + * isn't really anything to do with digests. + */ + X509_SIG *enckey; +} NETSCAPE_ENCRYPTED_PKEY; + + +ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = { + ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, os, ASN1_OCTET_STRING), + ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG) +} ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY) + +DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_PKEY) +IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY) + +ASN1_SEQUENCE(NETSCAPE_PKEY) = { + ASN1_SIMPLE(NETSCAPE_PKEY, version, LONG), + ASN1_SIMPLE(NETSCAPE_PKEY, algor, X509_ALGOR), + ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(NETSCAPE_PKEY) + +DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY) +IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY) + +static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os, + int (*cb) (char *buf, int len, const char *prompt, + int verify), int sgckey); + +int i2d_Netscape_RSA(const RSA *a, unsigned char **pp, + int (*cb) (char *buf, int len, const char *prompt, + int verify)) +{ + return i2d_RSA_NET(a, pp, cb, 0); +} + +int i2d_RSA_NET(const RSA *a, unsigned char **pp, + int (*cb) (char *buf, int len, const char *prompt, + int verify), int sgckey) +{ + int i, j, ret = 0; + int rsalen, pkeylen, olen; + NETSCAPE_PKEY *pkey = NULL; + NETSCAPE_ENCRYPTED_PKEY *enckey = NULL; + unsigned char buf[256], *zz; + unsigned char key[EVP_MAX_KEY_LENGTH]; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + if (a == NULL) + return (0); + + if ((pkey = NETSCAPE_PKEY_new()) == NULL) + goto err; + if ((enckey = NETSCAPE_ENCRYPTED_PKEY_new()) == NULL) + goto err; + pkey->version = 0; + + pkey->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption); + if ((pkey->algor->parameter = ASN1_TYPE_new()) == NULL) + goto err; + pkey->algor->parameter->type = V_ASN1_NULL; + + rsalen = i2d_RSAPrivateKey(a, NULL); + + /* + * Fake some octet strings just for the initial length calculation. + */ + + pkey->private_key->length = rsalen; + + pkeylen = i2d_NETSCAPE_PKEY(pkey, NULL); + + enckey->enckey->digest->length = pkeylen; + + enckey->os->length = 11; /* "private-key" */ + + enckey->enckey->algor->algorithm = OBJ_nid2obj(NID_rc4); + if ((enckey->enckey->algor->parameter = ASN1_TYPE_new()) == NULL) + goto err; + enckey->enckey->algor->parameter->type = V_ASN1_NULL; + + if (pp == NULL) { + olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL); + NETSCAPE_PKEY_free(pkey); + NETSCAPE_ENCRYPTED_PKEY_free(enckey); + return olen; + } + + /* Since its RC4 encrypted length is actual length */ + if ((zz = (unsigned char *)OPENSSL_malloc(rsalen)) == NULL) { + ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE); + goto err; + } + + pkey->private_key->data = zz; + /* Write out private key encoding */ + i2d_RSAPrivateKey(a, &zz); + + if ((zz = OPENSSL_malloc(pkeylen)) == NULL) { + ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!ASN1_STRING_set(enckey->os, "private-key", -1)) { + ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE); + goto err; + } + enckey->enckey->digest->data = zz; + i2d_NETSCAPE_PKEY(pkey, &zz); + + /* Wipe the private key encoding */ + OPENSSL_cleanse(pkey->private_key->data, rsalen); + + if (cb == NULL) + cb = EVP_read_pw_string; + i = cb((char *)buf, 256, "Enter Private Key password:", 1); + if (i != 0) { + ASN1err(ASN1_F_I2D_RSA_NET, ASN1_R_BAD_PASSWORD_READ); + goto err; + } + i = strlen((char *)buf); + /* If the key is used for SGC the algorithm is modified a little. */ + if (sgckey) { + if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL)) + goto err; + memcpy(buf + 16, "SGCKEYSALT", 10); + i = 26; + } + + if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL)) + goto err; + OPENSSL_cleanse(buf, 256); + + /* Encrypt private key in place */ + zz = enckey->enckey->digest->data; + if (!EVP_EncryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL)) + goto err; + if (!EVP_EncryptUpdate(&ctx, zz, &i, zz, pkeylen)) + goto err; + if (!EVP_EncryptFinal_ex(&ctx, zz + i, &j)) + goto err; + + ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp); + err: + EVP_CIPHER_CTX_cleanup(&ctx); + NETSCAPE_ENCRYPTED_PKEY_free(enckey); + NETSCAPE_PKEY_free(pkey); + return (ret); +} + +RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, + int (*cb) (char *buf, int len, const char *prompt, + int verify)) +{ + return d2i_RSA_NET(a, pp, length, cb, 0); +} + +RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, + int (*cb) (char *buf, int len, const char *prompt, + int verify), int sgckey) +{ + RSA *ret = NULL; + const unsigned char *p; + NETSCAPE_ENCRYPTED_PKEY *enckey = NULL; + + p = *pp; + + enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length); + if (!enckey) { + ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_DECODING_ERROR); + return NULL; + } + + if ((enckey->os->length != 11) || (strncmp("private-key", + (char *)enckey->os->data, + 11) != 0)) { + ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_PRIVATE_KEY_HEADER_MISSING); + NETSCAPE_ENCRYPTED_PKEY_free(enckey); + return NULL; + } + if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4) { + ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM); + goto err; + } + if (cb == NULL) + cb = EVP_read_pw_string; + if ((ret = d2i_RSA_NET_2(a, enckey->enckey->digest, cb, sgckey)) == NULL) + goto err; + + *pp = p; + + err: + NETSCAPE_ENCRYPTED_PKEY_free(enckey); + return ret; + +} + +static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os, + int (*cb) (char *buf, int len, const char *prompt, + int verify), int sgckey) +{ + NETSCAPE_PKEY *pkey = NULL; + RSA *ret = NULL; + int i, j; + unsigned char buf[256]; + const unsigned char *zz; + unsigned char key[EVP_MAX_KEY_LENGTH]; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + i = cb((char *)buf, 256, "Enter Private Key password:", 0); + if (i != 0) { + ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_BAD_PASSWORD_READ); + goto err; + } + + i = strlen((char *)buf); + if (sgckey) { + if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL)) + goto err; + memcpy(buf + 16, "SGCKEYSALT", 10); + i = 26; + } + + if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL)) + goto err; + OPENSSL_cleanse(buf, 256); + + if (!EVP_DecryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL)) + goto err; + if (!EVP_DecryptUpdate(&ctx, os->data, &i, os->data, os->length)) + goto err; + if (!EVP_DecryptFinal_ex(&ctx, &(os->data[i]), &j)) + goto err; + os->length = i + j; + + zz = os->data; + + if ((pkey = d2i_NETSCAPE_PKEY(NULL, &zz, os->length)) == NULL) { + ASN1err(ASN1_F_D2I_RSA_NET_2, + ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY); + goto err; + } + + zz = pkey->private_key->data; + if ((ret = d2i_RSAPrivateKey(a, &zz, pkey->private_key->length)) == NULL) { + ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_UNABLE_TO_DECODE_RSA_KEY); + goto err; + } + err: + EVP_CIPHER_CTX_cleanup(&ctx); + NETSCAPE_PKEY_free(pkey); + return (ret); +} + +# endif /* OPENSSL_NO_RC4 */ + +#else /* !OPENSSL_NO_RSA */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif diff --git a/libs/openssl/crypto/asn1/nsseq.c b/libs/openssl/crypto/asn1/nsseq.c new file mode 100644 index 00000000..f2f7cba4 --- /dev/null +++ b/libs/openssl/crypto/asn1/nsseq.c @@ -0,0 +1,84 @@ +/* nsseq.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include + +static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_NEW_POST) { + NETSCAPE_CERT_SEQUENCE *nsseq; + nsseq = (NETSCAPE_CERT_SEQUENCE *)*pval; + nsseq->type = OBJ_nid2obj(NID_netscape_cert_sequence); + } + return 1; +} + +/* Netscape certificate sequence structure */ + +ASN1_SEQUENCE_cb(NETSCAPE_CERT_SEQUENCE, nsseq_cb) = { + ASN1_SIMPLE(NETSCAPE_CERT_SEQUENCE, type, ASN1_OBJECT), + ASN1_EXP_SEQUENCE_OF_OPT(NETSCAPE_CERT_SEQUENCE, certs, X509, 0) +} ASN1_SEQUENCE_END_cb(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE) + +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE) diff --git a/libs/openssl/crypto/asn1/p5_pbe.c b/libs/openssl/crypto/asn1/p5_pbe.c new file mode 100644 index 00000000..bdbfdcd6 --- /dev/null +++ b/libs/openssl/crypto/asn1/p5_pbe.c @@ -0,0 +1,143 @@ +/* p5_pbe.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +/* PKCS#5 password based encryption structure */ + +ASN1_SEQUENCE(PBEPARAM) = { + ASN1_SIMPLE(PBEPARAM, salt, ASN1_OCTET_STRING), + ASN1_SIMPLE(PBEPARAM, iter, ASN1_INTEGER) +} ASN1_SEQUENCE_END(PBEPARAM) + +IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM) + +/* Set an algorithm identifier for a PKCS#5 PBE algorithm */ + +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen) +{ + PBEPARAM *pbe = NULL; + ASN1_STRING *pbe_str = NULL; + unsigned char *sstr; + + pbe = PBEPARAM_new(); + if (!pbe) { + ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); + goto err; + } + if (iter <= 0) + iter = PKCS5_DEFAULT_ITER; + if (!ASN1_INTEGER_set(pbe->iter, iter)) { + ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!saltlen) + saltlen = PKCS5_SALT_LEN; + if (!ASN1_STRING_set(pbe->salt, NULL, saltlen)) { + ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); + goto err; + } + sstr = ASN1_STRING_data(pbe->salt); + if (salt) + memcpy(sstr, salt, saltlen); + else if (RAND_pseudo_bytes(sstr, saltlen) < 0) + goto err; + + if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) { + ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE); + goto err; + } + + PBEPARAM_free(pbe); + pbe = NULL; + + if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str)) + return 1; + + err: + if (pbe != NULL) + PBEPARAM_free(pbe); + if (pbe_str != NULL) + ASN1_STRING_free(pbe_str); + return 0; +} + +/* Return an algorithm identifier for a PKCS#5 PBE algorithm */ + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen) +{ + X509_ALGOR *ret; + ret = X509_ALGOR_new(); + if (!ret) { + ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen)) + return ret; + + X509_ALGOR_free(ret); + return NULL; +} diff --git a/libs/openssl/crypto/asn1/p5_pbev2.c b/libs/openssl/crypto/asn1/p5_pbev2.c new file mode 100644 index 00000000..73ba4a3d --- /dev/null +++ b/libs/openssl/crypto/asn1/p5_pbev2.c @@ -0,0 +1,280 @@ +/* p5_pbev2.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999-2004. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +/* PKCS#5 v2.0 password based encryption structures */ + +ASN1_SEQUENCE(PBE2PARAM) = { + ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR), + ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR) +} ASN1_SEQUENCE_END(PBE2PARAM) + +IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM) + +ASN1_SEQUENCE(PBKDF2PARAM) = { + ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY), + ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER), + ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER), + ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR) +} ASN1_SEQUENCE_END(PBKDF2PARAM) + +IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM) + +/* + * Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know + * this is horrible! Extended version to allow application supplied PRF NID + * and IV. + */ + +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid) +{ + X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL; + int alg_nid, keylen; + EVP_CIPHER_CTX ctx; + unsigned char iv[EVP_MAX_IV_LENGTH]; + PBE2PARAM *pbe2 = NULL; + ASN1_OBJECT *obj; + + alg_nid = EVP_CIPHER_type(cipher); + if (alg_nid == NID_undef) { + ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, + ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); + goto err; + } + obj = OBJ_nid2obj(alg_nid); + + if (!(pbe2 = PBE2PARAM_new())) + goto merr; + + /* Setup the AlgorithmIdentifier for the encryption scheme */ + scheme = pbe2->encryption; + + scheme->algorithm = obj; + if (!(scheme->parameter = ASN1_TYPE_new())) + goto merr; + + /* Create random IV */ + if (EVP_CIPHER_iv_length(cipher)) { + if (aiv) + memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher)); + else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0) + goto err; + } + + EVP_CIPHER_CTX_init(&ctx); + + /* Dummy cipherinit to just setup the IV, and PRF */ + if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0)) + goto err; + if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) { + ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS); + EVP_CIPHER_CTX_cleanup(&ctx); + goto err; + } + /* + * If prf NID unspecified see if cipher has a preference. An error is OK + * here: just means use default PRF. + */ + if ((prf_nid == -1) && + EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) { + ERR_clear_error(); + prf_nid = NID_hmacWithSHA1; + } + EVP_CIPHER_CTX_cleanup(&ctx); + + /* If its RC2 then we'd better setup the key length */ + + if (alg_nid == NID_rc2_cbc) + keylen = EVP_CIPHER_key_length(cipher); + else + keylen = -1; + + /* Setup keyfunc */ + + X509_ALGOR_free(pbe2->keyfunc); + + pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen); + + if (!pbe2->keyfunc) + goto merr; + + /* Now set up top level AlgorithmIdentifier */ + + if (!(ret = X509_ALGOR_new())) + goto merr; + if (!(ret->parameter = ASN1_TYPE_new())) + goto merr; + + ret->algorithm = OBJ_nid2obj(NID_pbes2); + + /* Encode PBE2PARAM into parameter */ + + if (!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM), + &ret->parameter->value.sequence)) + goto merr; + ret->parameter->type = V_ASN1_SEQUENCE; + + PBE2PARAM_free(pbe2); + pbe2 = NULL; + + return ret; + + merr: + ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE); + + err: + PBE2PARAM_free(pbe2); + /* Note 'scheme' is freed as part of pbe2 */ + X509_ALGOR_free(kalg); + X509_ALGOR_free(ret); + + return NULL; + +} + +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen) +{ + return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1); +} + +X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, + int prf_nid, int keylen) +{ + X509_ALGOR *keyfunc = NULL; + PBKDF2PARAM *kdf = NULL; + ASN1_OCTET_STRING *osalt = NULL; + + if (!(kdf = PBKDF2PARAM_new())) + goto merr; + if (!(osalt = M_ASN1_OCTET_STRING_new())) + goto merr; + + kdf->salt->value.octet_string = osalt; + kdf->salt->type = V_ASN1_OCTET_STRING; + + if (!saltlen) + saltlen = PKCS5_SALT_LEN; + if (!(osalt->data = OPENSSL_malloc(saltlen))) + goto merr; + + osalt->length = saltlen; + + if (salt) + memcpy(osalt->data, salt, saltlen); + else if (RAND_pseudo_bytes(osalt->data, saltlen) < 0) + goto merr; + + if (iter <= 0) + iter = PKCS5_DEFAULT_ITER; + + if (!ASN1_INTEGER_set(kdf->iter, iter)) + goto merr; + + /* If have a key len set it up */ + + if (keylen > 0) { + if (!(kdf->keylength = M_ASN1_INTEGER_new())) + goto merr; + if (!ASN1_INTEGER_set(kdf->keylength, keylen)) + goto merr; + } + + /* prf can stay NULL if we are using hmacWithSHA1 */ + if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) { + kdf->prf = X509_ALGOR_new(); + if (!kdf->prf) + goto merr; + X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL); + } + + /* Finally setup the keyfunc structure */ + + keyfunc = X509_ALGOR_new(); + if (!keyfunc) + goto merr; + + keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2); + + /* Encode PBKDF2PARAM into parameter of pbe2 */ + + if (!(keyfunc->parameter = ASN1_TYPE_new())) + goto merr; + + if (!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM), + &keyfunc->parameter->value.sequence)) + goto merr; + keyfunc->parameter->type = V_ASN1_SEQUENCE; + + PBKDF2PARAM_free(kdf); + return keyfunc; + + merr: + ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE); + PBKDF2PARAM_free(kdf); + X509_ALGOR_free(keyfunc); + return NULL; +} diff --git a/libs/openssl/crypto/asn1/p8_pkey.c b/libs/openssl/crypto/asn1/p8_pkey.c new file mode 100644 index 00000000..0a425cd2 --- /dev/null +++ b/libs/openssl/crypto/asn1/p8_pkey.c @@ -0,0 +1,145 @@ +/* p8_pkey.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include + +/* Minor tweak to operation: zero private key data */ +static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + /* Since the structure must still be valid use ASN1_OP_FREE_PRE */ + if (operation == ASN1_OP_FREE_PRE) { + PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval; + if (key->pkey && key->pkey->type == V_ASN1_OCTET_STRING + && key->pkey->value.octet_string != NULL) + OPENSSL_cleanse(key->pkey->value.octet_string->data, + key->pkey->value.octet_string->length); + } + return 1; +} + +ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = { + ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR), + ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_ANY), + ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0) +} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, + int ptype, void *pval, unsigned char *penc, int penclen) +{ + unsigned char **ppenc = NULL; + if (version >= 0) { + if (!ASN1_INTEGER_set(priv->version, version)) + return 0; + } + if (penc) { + int pmtype; + ASN1_OCTET_STRING *oct; + oct = ASN1_OCTET_STRING_new(); + if (!oct) + return 0; + oct->data = penc; + ppenc = &oct->data; + oct->length = penclen; + if (priv->broken == PKCS8_NO_OCTET) + pmtype = V_ASN1_SEQUENCE; + else + pmtype = V_ASN1_OCTET_STRING; + ASN1_TYPE_set(priv->pkey, pmtype, oct); + } + if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) { + /* If call fails do not swallow 'enc' */ + if (ppenc) + *ppenc = NULL; + return 0; + } + return 1; +} + +int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8) +{ + if (ppkalg) + *ppkalg = p8->pkeyalg->algorithm; + if (p8->pkey->type == V_ASN1_OCTET_STRING) { + p8->broken = PKCS8_OK; + if (pk) { + *pk = p8->pkey->value.octet_string->data; + *ppklen = p8->pkey->value.octet_string->length; + } + } else if (p8->pkey->type == V_ASN1_SEQUENCE) { + p8->broken = PKCS8_NO_OCTET; + if (pk) { + *pk = p8->pkey->value.sequence->data; + *ppklen = p8->pkey->value.sequence->length; + } + } else + return 0; + if (pa) + *pa = p8->pkeyalg; + return 1; +} diff --git a/libs/openssl/crypto/asn1/t_bitst.c b/libs/openssl/crypto/asn1/t_bitst.c new file mode 100644 index 00000000..d5cf3c77 --- /dev/null +++ b/libs/openssl/crypto/asn1/t_bitst.c @@ -0,0 +1,105 @@ +/* t_bitst.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include + +int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs, + BIT_STRING_BITNAME *tbl, int indent) +{ + BIT_STRING_BITNAME *bnam; + char first = 1; + BIO_printf(out, "%*s", indent, ""); + for (bnam = tbl; bnam->lname; bnam++) { + if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) { + if (!first) + BIO_puts(out, ", "); + BIO_puts(out, bnam->lname); + first = 0; + } + } + BIO_puts(out, "\n"); + return 1; +} + +int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value, + BIT_STRING_BITNAME *tbl) +{ + int bitnum; + bitnum = ASN1_BIT_STRING_num_asc(name, tbl); + if (bitnum < 0) + return 0; + if (bs) { + if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value)) + return 0; + } + return 1; +} + +int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl) +{ + BIT_STRING_BITNAME *bnam; + for (bnam = tbl; bnam->lname; bnam++) { + if (!strcmp(bnam->sname, name) || !strcmp(bnam->lname, name)) + return bnam->bitnum; + } + return -1; +} diff --git a/libs/openssl/crypto/asn1/t_crl.c b/libs/openssl/crypto/asn1/t_crl.c new file mode 100644 index 00000000..0dfaf0ba --- /dev/null +++ b/libs/openssl/crypto/asn1/t_crl.c @@ -0,0 +1,133 @@ +/* t_crl.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_FP_API +int X509_CRL_print_fp(FILE *fp, X509_CRL *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + X509err(X509_F_X509_CRL_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = X509_CRL_print(b, x); + BIO_free(b); + return (ret); +} +#endif + +int X509_CRL_print(BIO *out, X509_CRL *x) +{ + STACK_OF(X509_REVOKED) *rev; + X509_REVOKED *r; + long l; + int i; + char *p; + + BIO_printf(out, "Certificate Revocation List (CRL):\n"); + l = X509_CRL_get_version(x); + BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l + 1, l); + i = OBJ_obj2nid(x->sig_alg->algorithm); + X509_signature_print(out, x->sig_alg, NULL); + p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0); + BIO_printf(out, "%8sIssuer: %s\n", "", p); + OPENSSL_free(p); + BIO_printf(out, "%8sLast Update: ", ""); + ASN1_TIME_print(out, X509_CRL_get_lastUpdate(x)); + BIO_printf(out, "\n%8sNext Update: ", ""); + if (X509_CRL_get_nextUpdate(x)) + ASN1_TIME_print(out, X509_CRL_get_nextUpdate(x)); + else + BIO_printf(out, "NONE"); + BIO_printf(out, "\n"); + + X509V3_extensions_print(out, "CRL extensions", x->crl->extensions, 0, 8); + + rev = X509_CRL_get_REVOKED(x); + + if (sk_X509_REVOKED_num(rev) > 0) + BIO_printf(out, "Revoked Certificates:\n"); + else + BIO_printf(out, "No Revoked Certificates.\n"); + + for (i = 0; i < sk_X509_REVOKED_num(rev); i++) { + r = sk_X509_REVOKED_value(rev, i); + BIO_printf(out, " Serial Number: "); + i2a_ASN1_INTEGER(out, r->serialNumber); + BIO_printf(out, "\n Revocation Date: "); + ASN1_TIME_print(out, r->revocationDate); + BIO_printf(out, "\n"); + X509V3_extensions_print(out, "CRL entry extensions", + r->extensions, 0, 8); + } + X509_signature_print(out, x->sig_alg, x->signature); + + return 1; + +} diff --git a/libs/openssl/crypto/asn1/t_pkey.c b/libs/openssl/crypto/asn1/t_pkey.c new file mode 100644 index 00000000..735c3426 --- /dev/null +++ b/libs/openssl/crypto/asn1/t_pkey.c @@ -0,0 +1,113 @@ +/* crypto/asn1/t_pkey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num, + unsigned char *buf, int off) +{ + int n, i; + const char *neg; + + if (num == NULL) + return (1); + neg = (BN_is_negative(num)) ? "-" : ""; + if (!BIO_indent(bp, off, 128)) + return 0; + if (BN_is_zero(num)) { + if (BIO_printf(bp, "%s 0\n", number) <= 0) + return 0; + return 1; + } + + if (BN_num_bytes(num) <= BN_BYTES) { + if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg, + (unsigned long)num->d[0], neg, + (unsigned long)num->d[0]) + <= 0) + return (0); + } else { + buf[0] = 0; + if (BIO_printf(bp, "%s%s", number, + (neg[0] == '-') ? " (Negative)" : "") <= 0) + return (0); + n = BN_bn2bin(num, &buf[1]); + + if (buf[1] & 0x80) + n++; + else + buf++; + + for (i = 0; i < n; i++) { + if ((i % 15) == 0) { + if (BIO_puts(bp, "\n") <= 0 || !BIO_indent(bp, off + 4, 128)) + return 0; + } + if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":") + <= 0) + return (0); + } + if (BIO_write(bp, "\n", 1) <= 0) + return (0); + } + return (1); +} diff --git a/libs/openssl/crypto/asn1/t_req.c b/libs/openssl/crypto/asn1/t_req.c new file mode 100644 index 00000000..024553ab --- /dev/null +++ b/libs/openssl/crypto/asn1/t_req.c @@ -0,0 +1,254 @@ +/* crypto/asn1/t_req.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#ifndef OPENSSL_NO_DSA +# include +#endif + +#ifndef OPENSSL_NO_FP_API +int X509_REQ_print_fp(FILE *fp, X509_REQ *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + X509err(X509_F_X509_REQ_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = X509_REQ_print(b, x); + BIO_free(b); + return (ret); +} +#endif + +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, + unsigned long cflag) +{ + unsigned long l; + int i; + const char *neg; + X509_REQ_INFO *ri; + EVP_PKEY *pkey; + STACK_OF(X509_ATTRIBUTE) *sk; + STACK_OF(X509_EXTENSION) *exts; + char mlch = ' '; + int nmindent = 0; + + if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { + mlch = '\n'; + nmindent = 12; + } + + if (nmflags == X509_FLAG_COMPAT) + nmindent = 16; + + ri = x->req_info; + if (!(cflag & X509_FLAG_NO_HEADER)) { + if (BIO_write(bp, "Certificate Request:\n", 21) <= 0) + goto err; + if (BIO_write(bp, " Data:\n", 10) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_VERSION)) { + neg = (ri->version->type == V_ASN1_NEG_INTEGER) ? "-" : ""; + l = 0; + for (i = 0; i < ri->version->length; i++) { + l <<= 8; + l += ri->version->data[i]; + } + if (BIO_printf(bp, "%8sVersion: %s%lu (%s0x%lx)\n", "", neg, l, neg, + l) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_SUBJECT)) { + if (BIO_printf(bp, " Subject:%c", mlch) <= 0) + goto err; + if (X509_NAME_print_ex(bp, ri->subject, nmindent, nmflags) < 0) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_PUBKEY)) { + if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0) + goto err; + if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0) + goto err; + if (BIO_puts(bp, "\n") <= 0) + goto err; + + pkey = X509_REQ_get_pubkey(x); + if (pkey == NULL) { + BIO_printf(bp, "%12sUnable to load Public Key\n", ""); + ERR_print_errors(bp); + } else { + EVP_PKEY_print_public(bp, pkey, 16, NULL); + EVP_PKEY_free(pkey); + } + } + + if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) { + /* may not be */ + if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0) + goto err; + + sk = x->req_info->attributes; + if (sk_X509_ATTRIBUTE_num(sk) == 0) { + if (BIO_printf(bp, "%12sa0:00\n", "") <= 0) + goto err; + } else { + for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { + ASN1_TYPE *at; + X509_ATTRIBUTE *a; + ASN1_BIT_STRING *bs = NULL; + ASN1_TYPE *t; + int j, type = 0, count = 1, ii = 0; + + a = sk_X509_ATTRIBUTE_value(sk, i); + if (X509_REQ_extension_nid(OBJ_obj2nid(a->object))) + continue; + if (BIO_printf(bp, "%12s", "") <= 0) + goto err; + if ((j = i2a_ASN1_OBJECT(bp, a->object)) > 0) { + if (a->single) { + t = a->value.single; + type = t->type; + bs = t->value.bit_string; + } else { + ii = 0; + count = sk_ASN1_TYPE_num(a->value.set); + get_next: + at = sk_ASN1_TYPE_value(a->value.set, ii); + type = at->type; + bs = at->value.asn1_string; + } + } + for (j = 25 - j; j > 0; j--) + if (BIO_write(bp, " ", 1) != 1) + goto err; + if (BIO_puts(bp, ":") <= 0) + goto err; + if ((type == V_ASN1_PRINTABLESTRING) || + (type == V_ASN1_T61STRING) || + (type == V_ASN1_IA5STRING)) { + if (BIO_write(bp, (char *)bs->data, bs->length) + != bs->length) + goto err; + BIO_puts(bp, "\n"); + } else { + BIO_puts(bp, "unable to print attribute\n"); + } + if (++ii < count) + goto get_next; + } + } + } + if (!(cflag & X509_FLAG_NO_EXTENSIONS)) { + exts = X509_REQ_get_extensions(x); + if (exts) { + BIO_printf(bp, "%8sRequested Extensions:\n", ""); + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + ASN1_OBJECT *obj; + X509_EXTENSION *ex; + int j; + ex = sk_X509_EXTENSION_value(exts, i); + if (BIO_printf(bp, "%12s", "") <= 0) + goto err; + obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bp, obj); + j = X509_EXTENSION_get_critical(ex); + if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0) + goto err; + if (!X509V3_EXT_print(bp, ex, cflag, 16)) { + BIO_printf(bp, "%16s", ""); + M_ASN1_OCTET_STRING_print(bp, ex->value); + } + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + } + } + + if (!(cflag & X509_FLAG_NO_SIGDUMP)) { + if (!X509_signature_print(bp, x->sig_alg, x->signature)) + goto err; + } + + return (1); + err: + X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB); + return (0); +} + +int X509_REQ_print(BIO *bp, X509_REQ *x) +{ + return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} diff --git a/libs/openssl/crypto/asn1/t_spki.c b/libs/openssl/crypto/asn1/t_spki.c new file mode 100644 index 00000000..3bf48db5 --- /dev/null +++ b/libs/openssl/crypto/asn1/t_spki.c @@ -0,0 +1,108 @@ +/* t_spki.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#ifndef OPENSSL_NO_DSA +# include +#endif +#include + +/* Print out an SPKI */ + +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki) +{ + EVP_PKEY *pkey; + ASN1_IA5STRING *chal; + int i, n; + char *s; + BIO_printf(out, "Netscape SPKI:\n"); + i = OBJ_obj2nid(spki->spkac->pubkey->algor->algorithm); + BIO_printf(out, " Public Key Algorithm: %s\n", + (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); + pkey = X509_PUBKEY_get(spki->spkac->pubkey); + if (!pkey) + BIO_printf(out, " Unable to load public key\n"); + else { + EVP_PKEY_print_public(out, pkey, 4, NULL); + EVP_PKEY_free(pkey); + } + chal = spki->spkac->challenge; + if (chal->length) + BIO_printf(out, " Challenge String: %s\n", chal->data); + i = OBJ_obj2nid(spki->sig_algor->algorithm); + BIO_printf(out, " Signature Algorithm: %s", + (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); + + n = spki->signature->length; + s = (char *)spki->signature->data; + for (i = 0; i < n; i++) { + if ((i % 18) == 0) + BIO_write(out, "\n ", 7); + BIO_printf(out, "%02x%s", (unsigned char)s[i], + ((i + 1) == n) ? "" : ":"); + } + BIO_write(out, "\n", 1); + return 1; +} diff --git a/libs/openssl/crypto/asn1/t_x509.c b/libs/openssl/crypto/asn1/t_x509.c new file mode 100644 index 00000000..4f69b511 --- /dev/null +++ b/libs/openssl/crypto/asn1/t_x509.c @@ -0,0 +1,541 @@ +/* crypto/asn1/t_x509.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#ifndef OPENSSL_NO_DSA +# include +#endif +#ifndef OPENSSL_NO_EC +# include +#endif +#include +#include +#include +#include "asn1_locl.h" + +#ifndef OPENSSL_NO_FP_API +int X509_print_fp(FILE *fp, X509 *x) +{ + return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} + +int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, + unsigned long cflag) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = X509_print_ex(b, x, nmflag, cflag); + BIO_free(b); + return (ret); +} +#endif + +int X509_print(BIO *bp, X509 *x) +{ + return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} + +int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, + unsigned long cflag) +{ + long l; + int ret = 0, i; + char *m = NULL, mlch = ' '; + int nmindent = 0; + X509_CINF *ci; + ASN1_INTEGER *bs; + EVP_PKEY *pkey = NULL; + const char *neg; + + if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) { + mlch = '\n'; + nmindent = 12; + } + + if (nmflags == X509_FLAG_COMPAT) + nmindent = 16; + + ci = x->cert_info; + if (!(cflag & X509_FLAG_NO_HEADER)) { + if (BIO_write(bp, "Certificate:\n", 13) <= 0) + goto err; + if (BIO_write(bp, " Data:\n", 10) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_VERSION)) { + l = X509_get_version(x); + if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n", "", l + 1, l) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_SERIAL)) { + + if (BIO_write(bp, " Serial Number:", 22) <= 0) + goto err; + + bs = X509_get_serialNumber(x); + if (bs->length < (int)sizeof(long) + || (bs->length == sizeof(long) && (bs->data[0] & 0x80) == 0)) { + l = ASN1_INTEGER_get(bs); + if (bs->type == V_ASN1_NEG_INTEGER) { + l = -l; + neg = "-"; + } else + neg = ""; + if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, l, neg, l) <= 0) + goto err; + } else { + neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : ""; + if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0) + goto err; + + for (i = 0; i < bs->length; i++) { + if (BIO_printf(bp, "%02x%c", bs->data[i], + ((i + 1 == bs->length) ? '\n' : ':')) <= 0) + goto err; + } + } + + } + + if (!(cflag & X509_FLAG_NO_SIGNAME)) { + if (X509_signature_print(bp, ci->signature, NULL) <= 0) + goto err; +#if 0 + if (BIO_printf(bp, "%8sSignature Algorithm: ", "") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0) + goto err; + if (BIO_puts(bp, "\n") <= 0) + goto err; +#endif + } + + if (!(cflag & X509_FLAG_NO_ISSUER)) { + if (BIO_printf(bp, " Issuer:%c", mlch) <= 0) + goto err; + if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags) + < 0) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_VALIDITY)) { + if (BIO_write(bp, " Validity\n", 17) <= 0) + goto err; + if (BIO_write(bp, " Not Before: ", 24) <= 0) + goto err; + if (!ASN1_TIME_print(bp, X509_get_notBefore(x))) + goto err; + if (BIO_write(bp, "\n Not After : ", 25) <= 0) + goto err; + if (!ASN1_TIME_print(bp, X509_get_notAfter(x))) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_SUBJECT)) { + if (BIO_printf(bp, " Subject:%c", mlch) <= 0) + goto err; + if (X509_NAME_print_ex + (bp, X509_get_subject_name(x), nmindent, nmflags) < 0) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_PUBKEY)) { + if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0) + goto err; + if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0) + goto err; + if (BIO_puts(bp, "\n") <= 0) + goto err; + + pkey = X509_get_pubkey(x); + if (pkey == NULL) { + BIO_printf(bp, "%12sUnable to load Public Key\n", ""); + ERR_print_errors(bp); + } else { + EVP_PKEY_print_public(bp, pkey, 16, NULL); + EVP_PKEY_free(pkey); + } + } + + if (!(cflag & X509_FLAG_NO_EXTENSIONS)) + X509V3_extensions_print(bp, "X509v3 extensions", + ci->extensions, cflag, 8); + + if (!(cflag & X509_FLAG_NO_SIGDUMP)) { + if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0) + goto err; + } + if (!(cflag & X509_FLAG_NO_AUX)) { + if (!X509_CERT_AUX_print(bp, x->aux, 0)) + goto err; + } + ret = 1; + err: + if (m != NULL) + OPENSSL_free(m); + return (ret); +} + +int X509_ocspid_print(BIO *bp, X509 *x) +{ + unsigned char *der = NULL; + unsigned char *dertmp; + int derlen; + int i; + unsigned char SHA1md[SHA_DIGEST_LENGTH]; + + /* + * display the hash of the subject as it would appear in OCSP requests + */ + if (BIO_printf(bp, " Subject OCSP hash: ") <= 0) + goto err; + derlen = i2d_X509_NAME(x->cert_info->subject, NULL); + if ((der = dertmp = (unsigned char *)OPENSSL_malloc(derlen)) == NULL) + goto err; + i2d_X509_NAME(x->cert_info->subject, &dertmp); + + if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL)) + goto err; + for (i = 0; i < SHA_DIGEST_LENGTH; i++) { + if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) + goto err; + } + OPENSSL_free(der); + der = NULL; + + /* + * display the hash of the public key as it would appear in OCSP requests + */ + if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0) + goto err; + + if (!EVP_Digest(x->cert_info->key->public_key->data, + x->cert_info->key->public_key->length, + SHA1md, NULL, EVP_sha1(), NULL)) + goto err; + for (i = 0; i < SHA_DIGEST_LENGTH; i++) { + if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0) + goto err; + } + BIO_printf(bp, "\n"); + + return (1); + err: + if (der != NULL) + OPENSSL_free(der); + return (0); +} + +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent) +{ + const unsigned char *s; + int i, n; + + n = sig->length; + s = sig->data; + for (i = 0; i < n; i++) { + if ((i % 18) == 0) { + if (BIO_write(bp, "\n", 1) <= 0) + return 0; + if (BIO_indent(bp, indent, indent) <= 0) + return 0; + } + if (BIO_printf(bp, "%02x%s", s[i], ((i + 1) == n) ? "" : ":") <= 0) + return 0; + } + if (BIO_write(bp, "\n", 1) != 1) + return 0; + + return 1; +} + +int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig) +{ + int sig_nid; + if (BIO_puts(bp, " Signature Algorithm: ") <= 0) + return 0; + if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) + return 0; + + sig_nid = OBJ_obj2nid(sigalg->algorithm); + if (sig_nid != NID_undef) { + int pkey_nid, dig_nid; + const EVP_PKEY_ASN1_METHOD *ameth; + if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) { + ameth = EVP_PKEY_asn1_find(NULL, pkey_nid); + if (ameth && ameth->sig_print) + return ameth->sig_print(bp, sigalg, sig, 9, 0); + } + } + if (sig) + return X509_signature_dump(bp, sig, 9); + else if (BIO_puts(bp, "\n") <= 0) + return 0; + return 1; +} + +int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v) +{ + int i, n; + char buf[80]; + const char *p; + + if (v == NULL) + return (0); + n = 0; + p = (const char *)v->data; + for (i = 0; i < v->length; i++) { + if ((p[i] > '~') || ((p[i] < ' ') && + (p[i] != '\n') && (p[i] != '\r'))) + buf[n] = '.'; + else + buf[n] = p[i]; + n++; + if (n >= 80) { + if (BIO_write(bp, buf, n) <= 0) + return (0); + n = 0; + } + } + if (n > 0) + if (BIO_write(bp, buf, n) <= 0) + return (0); + return (1); +} + +int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm) +{ + if (tm->type == V_ASN1_UTCTIME) + return ASN1_UTCTIME_print(bp, tm); + if (tm->type == V_ASN1_GENERALIZEDTIME) + return ASN1_GENERALIZEDTIME_print(bp, tm); + BIO_write(bp, "Bad time value", 14); + return (0); +} + +static const char *mon[12] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" +}; + +int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm) +{ + char *v; + int gmt = 0; + int i; + int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0; + char *f = NULL; + int f_len = 0; + + i = tm->length; + v = (char *)tm->data; + + if (i < 12) + goto err; + if (v[i - 1] == 'Z') + gmt = 1; + for (i = 0; i < 12; i++) + if ((v[i] > '9') || (v[i] < '0')) + goto err; + y = (v[0] - '0') * 1000 + (v[1] - '0') * 100 + + (v[2] - '0') * 10 + (v[3] - '0'); + M = (v[4] - '0') * 10 + (v[5] - '0'); + if ((M > 12) || (M < 1)) + goto err; + d = (v[6] - '0') * 10 + (v[7] - '0'); + h = (v[8] - '0') * 10 + (v[9] - '0'); + m = (v[10] - '0') * 10 + (v[11] - '0'); + if (tm->length >= 14 && + (v[12] >= '0') && (v[12] <= '9') && + (v[13] >= '0') && (v[13] <= '9')) { + s = (v[12] - '0') * 10 + (v[13] - '0'); + /* Check for fractions of seconds. */ + if (tm->length >= 15 && v[14] == '.') { + int l = tm->length; + f = &v[14]; /* The decimal point. */ + f_len = 1; + while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9') + ++f_len; + } + } + + if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s", + mon[M - 1], d, h, m, s, f_len, f, y, + (gmt) ? " GMT" : "") <= 0) + return (0); + else + return (1); + err: + BIO_write(bp, "Bad time value", 14); + return (0); +} + +int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm) +{ + const char *v; + int gmt = 0; + int i; + int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0; + + i = tm->length; + v = (const char *)tm->data; + + if (i < 10) + goto err; + if (v[i - 1] == 'Z') + gmt = 1; + for (i = 0; i < 10; i++) + if ((v[i] > '9') || (v[i] < '0')) + goto err; + y = (v[0] - '0') * 10 + (v[1] - '0'); + if (y < 50) + y += 100; + M = (v[2] - '0') * 10 + (v[3] - '0'); + if ((M > 12) || (M < 1)) + goto err; + d = (v[4] - '0') * 10 + (v[5] - '0'); + h = (v[6] - '0') * 10 + (v[7] - '0'); + m = (v[8] - '0') * 10 + (v[9] - '0'); + if (tm->length >= 12 && + (v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9')) + s = (v[10] - '0') * 10 + (v[11] - '0'); + + if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s", + mon[M - 1], d, h, m, s, y + 1900, + (gmt) ? " GMT" : "") <= 0) + return (0); + else + return (1); + err: + BIO_write(bp, "Bad time value", 14); + return (0); +} + +int X509_NAME_print(BIO *bp, X509_NAME *name, int obase) +{ + char *s, *c, *b; + int ret = 0, l, i; + + l = 80 - 2 - obase; + + b = X509_NAME_oneline(name, NULL, 0); + if (!b) + return 0; + if (!*b) { + OPENSSL_free(b); + return 1; + } + s = b + 1; /* skip the first slash */ + + c = s; + for (;;) { +#ifndef CHARSET_EBCDIC + if (((*s == '/') && + ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') || + ((s[2] >= 'A') + && (s[2] <= 'Z') + && (s[3] == '=')) + ))) || (*s == '\0')) +#else + if (((*s == '/') && + (isupper(s[1]) && ((s[2] == '=') || + (isupper(s[2]) && (s[3] == '=')) + ))) || (*s == '\0')) +#endif + { + i = s - c; + if (BIO_write(bp, c, i) != i) + goto err; + c = s + 1; /* skip following slash */ + if (*s != '\0') { + if (BIO_write(bp, ", ", 2) != 2) + goto err; + } + l--; + } + if (*s == '\0') + break; + s++; + l--; + } + + ret = 1; + if (0) { + err: + X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB); + } + OPENSSL_free(b); + return (ret); +} diff --git a/libs/openssl/crypto/asn1/t_x509a.c b/libs/openssl/crypto/asn1/t_x509a.c new file mode 100644 index 00000000..f4b8f94c --- /dev/null +++ b/libs/openssl/crypto/asn1/t_x509a.c @@ -0,0 +1,115 @@ +/* t_x509a.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +/* + * X509_CERT_AUX and string set routines + */ + +int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent) +{ + char oidstr[80], first; + int i; + if (!aux) + return 1; + if (aux->trust) { + first = 1; + BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, ""); + for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) { + if (!first) + BIO_puts(out, ", "); + else + first = 0; + OBJ_obj2txt(oidstr, sizeof oidstr, + sk_ASN1_OBJECT_value(aux->trust, i), 0); + BIO_puts(out, oidstr); + } + BIO_puts(out, "\n"); + } else + BIO_printf(out, "%*sNo Trusted Uses.\n", indent, ""); + if (aux->reject) { + first = 1; + BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, ""); + for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) { + if (!first) + BIO_puts(out, ", "); + else + first = 0; + OBJ_obj2txt(oidstr, sizeof oidstr, + sk_ASN1_OBJECT_value(aux->reject, i), 0); + BIO_puts(out, oidstr); + } + BIO_puts(out, "\n"); + } else + BIO_printf(out, "%*sNo Rejected Uses.\n", indent, ""); + if (aux->alias) + BIO_printf(out, "%*sAlias: %s\n", indent, "", aux->alias->data); + if (aux->keyid) { + BIO_printf(out, "%*sKey Id: ", indent, ""); + for (i = 0; i < aux->keyid->length; i++) + BIO_printf(out, "%s%02X", i ? ":" : "", aux->keyid->data[i]); + BIO_write(out, "\n", 1); + } + return 1; +} diff --git a/libs/openssl/crypto/asn1/tasn_dec.c b/libs/openssl/crypto/asn1/tasn_dec.c new file mode 100644 index 00000000..2a13388b --- /dev/null +++ b/libs/openssl/crypto/asn1/tasn_dec.c @@ -0,0 +1,1229 @@ +/* tasn_dec.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include + +static int asn1_check_eoc(const unsigned char **in, long len); +static int asn1_find_end(const unsigned char **in, long len, char inf); + +static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, + char inf, int tag, int aclass, int depth); + +static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen); + +static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, + char *inf, char *cst, + const unsigned char **in, long len, + int exptag, int expclass, char opt, ASN1_TLC *ctx); + +static int asn1_template_ex_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx); +static int asn1_template_noexp_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx); +static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, + ASN1_TLC *ctx); + +/* Table to convert tags to bit values, used for MSTRING type */ +static const unsigned long tag2bit[32] = { + /* tags 0 - 3 */ + 0, 0, 0, B_ASN1_BIT_STRING, + /* tags 4- 7 */ + B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN, + /* tags 8-11 */ + B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, + /* tags 12-15 */ + B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, + /* tags 16-19 */ + B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING, + /* tags 20-22 */ + B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING, + /* tags 23-24 */ + B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, + /* tags 25-27 */ + B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING, + /* tags 28-31 */ + B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN, +}; + +unsigned long ASN1_tag2bit(int tag) +{ + if ((tag < 0) || (tag > 30)) + return 0; + return tag2bit[tag]; +} + +/* Macro to initialize and invalidate the cache */ + +#define asn1_tlc_clear(c) if (c) (c)->valid = 0 +/* Version to avoid compiler warning about 'c' always non-NULL */ +#define asn1_tlc_clear_nc(c) (c)->valid = 0 + +/* + * Decode an ASN1 item, this currently behaves just like a standard 'd2i' + * function. 'in' points to a buffer to read the data from, in future we + * will have more advanced versions that can input data a piece at a time and + * this will simply be a special case. + */ + +ASN1_VALUE *ASN1_item_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_ITEM *it) +{ + ASN1_TLC c; + ASN1_VALUE *ptmpval = NULL; + if (!pval) + pval = &ptmpval; + asn1_tlc_clear_nc(&c); + if (ASN1_item_ex_d2i(pval, in, len, it, -1, 0, 0, &c) > 0) + return *pval; + return NULL; +} + +int ASN1_template_d2i(ASN1_VALUE **pval, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt) +{ + ASN1_TLC c; + asn1_tlc_clear_nc(&c); + return asn1_template_ex_d2i(pval, in, len, tt, 0, &c); +} + +/* + * Decode an item, taking care of IMPLICIT tagging, if any. If 'opt' set and + * tag mismatch return -1 to handle OPTIONAL + */ + +int ASN1_item_ex_d2i(ASN1_VALUE **pval, const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx) +{ + const ASN1_TEMPLATE *tt, *errtt = NULL; + const ASN1_COMPAT_FUNCS *cf; + const ASN1_EXTERN_FUNCS *ef; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb; + const unsigned char *p = NULL, *q; + unsigned char *wp = NULL; /* BIG FAT WARNING! BREAKS CONST WHERE USED */ + unsigned char imphack = 0, oclass; + char seq_eoc, seq_nolen, cst, isopt; + long tmplen; + int i; + int otag; + int ret = 0; + ASN1_VALUE **pchptr, *ptmpval; + int combine = aclass & ASN1_TFLG_COMBINE; + aclass &= ~ASN1_TFLG_COMBINE; + if (!pval) + return 0; + if (aux && aux->asn1_cb) + asn1_cb = aux->asn1_cb; + else + asn1_cb = 0; + + switch (it->itype) { + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) { + /* + * tagging or OPTIONAL is currently illegal on an item template + * because the flags can't get passed down. In practice this + * isn't a problem: we include the relevant flags from the item + * template in the template itself. + */ + if ((tag != -1) || opt) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, + ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE); + goto err; + } + return asn1_template_ex_d2i(pval, in, len, + it->templates, opt, ctx); + } + return asn1_d2i_ex_primitive(pval, in, len, it, + tag, aclass, opt, ctx); + break; + + case ASN1_ITYPE_MSTRING: + p = *in; + /* Just read in tag and class */ + ret = asn1_check_tlen(NULL, &otag, &oclass, NULL, NULL, + &p, len, -1, 0, 1, ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + + /* Must be UNIVERSAL class */ + if (oclass != V_ASN1_UNIVERSAL) { + /* If OPTIONAL, assume this is OK */ + if (opt) + return -1; + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_NOT_UNIVERSAL); + goto err; + } + /* Check tag matches bit map */ + if (!(ASN1_tag2bit(otag) & it->utype)) { + /* If OPTIONAL, assume this is OK */ + if (opt) + return -1; + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MSTRING_WRONG_TAG); + goto err; + } + return asn1_d2i_ex_primitive(pval, in, len, it, otag, 0, 0, ctx); + + case ASN1_ITYPE_EXTERN: + /* Use new style d2i */ + ef = it->funcs; + return ef->asn1_ex_d2i(pval, in, len, it, tag, aclass, opt, ctx); + + case ASN1_ITYPE_COMPAT: + /* we must resort to old style evil hackery */ + cf = it->funcs; + + /* If OPTIONAL see if it is there */ + if (opt) { + int exptag; + p = *in; + if (tag == -1) + exptag = it->utype; + else + exptag = tag; + /* + * Don't care about anything other than presence of expected tag + */ + + ret = asn1_check_tlen(NULL, NULL, NULL, NULL, NULL, + &p, len, exptag, aclass, 1, ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + if (ret == -1) + return -1; + } + + /* + * This is the old style evil hack IMPLICIT handling: since the + * underlying code is expecting a tag and class other than the one + * present we change the buffer temporarily then change it back + * afterwards. This doesn't and never did work for tags > 30. Yes + * this is *horrible* but it is only needed for old style d2i which + * will hopefully not be around for much longer. FIXME: should copy + * the buffer then modify it so the input buffer can be const: we + * should *always* copy because the old style d2i might modify the + * buffer. + */ + + if (tag != -1) { + wp = *(unsigned char **)in; + imphack = *wp; + if (p == NULL) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + *wp = (unsigned char)((*p & V_ASN1_CONSTRUCTED) + | it->utype); + } + + ptmpval = cf->asn1_d2i(pval, in, len); + + if (tag != -1) + *wp = imphack; + + if (ptmpval) + return 1; + + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + + case ASN1_ITYPE_CHOICE: + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) + goto auxerr; + if (*pval) { + /* Free up and zero CHOICE value if initialised */ + i = asn1_get_choice_selector(pval, it); + if ((i >= 0) && (i < it->tcount)) { + tt = it->templates + i; + pchptr = asn1_get_field_ptr(pval, tt); + ASN1_template_free(pchptr, tt); + asn1_set_choice_selector(pval, -1, it); + } + } else if (!ASN1_item_ex_new(pval, it)) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + /* CHOICE type, try each possibility in turn */ + p = *in; + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + pchptr = asn1_get_field_ptr(pval, tt); + /* + * We mark field as OPTIONAL so its absence can be recognised. + */ + ret = asn1_template_ex_d2i(pchptr, &p, len, tt, 1, ctx); + /* If field not present, try the next one */ + if (ret == -1) + continue; + /* If positive return, read OK, break loop */ + if (ret > 0) + break; + /* Otherwise must be an ASN1 parsing error */ + errtt = tt; + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + + /* Did we fall off the end without reading anything? */ + if (i == it->tcount) { + /* If OPTIONAL, this is OK */ + if (opt) { + /* Free and zero it */ + ASN1_item_ex_free(pval, it); + return -1; + } + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_NO_MATCHING_CHOICE_TYPE); + goto err; + } + + asn1_set_choice_selector(pval, i, it); + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) + goto auxerr; + *in = p; + return 1; + + case ASN1_ITYPE_NDEF_SEQUENCE: + case ASN1_ITYPE_SEQUENCE: + p = *in; + tmplen = len; + + /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ + if (tag == -1) { + tag = V_ASN1_SEQUENCE; + aclass = V_ASN1_UNIVERSAL; + } + /* Get SEQUENCE length and update len, p */ + ret = asn1_check_tlen(&len, NULL, NULL, &seq_eoc, &cst, + &p, len, tag, aclass, opt, ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } else if (ret == -1) + return -1; + if (aux && (aux->flags & ASN1_AFLG_BROKEN)) { + len = tmplen - (p - *in); + seq_nolen = 1; + } + /* If indefinite we don't do a length check */ + else + seq_nolen = seq_eoc; + if (!cst) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); + goto err; + } + + if (!*pval && !ASN1_item_ex_new(pval, it)) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } + + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_PRE, pval, it, NULL)) + goto auxerr; + + /* Free up and zero any ADB found */ + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + if (tt->flags & ASN1_TFLG_ADB_MASK) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 1); + pseqval = asn1_get_field_ptr(pval, seqtt); + ASN1_template_free(pseqval, seqtt); + } + } + + /* Get each field entry */ + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 1); + if (!seqtt) + goto err; + pseqval = asn1_get_field_ptr(pval, seqtt); + /* Have we ran out of data? */ + if (!len) + break; + q = p; + if (asn1_check_eoc(&p, len)) { + if (!seq_eoc) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_UNEXPECTED_EOC); + goto err; + } + len -= p - q; + seq_eoc = 0; + q = p; + break; + } + /* + * This determines the OPTIONAL flag value. The field cannot be + * omitted if it is the last of a SEQUENCE and there is still + * data to be read. This isn't strictly necessary but it + * increases efficiency in some cases. + */ + if (i == (it->tcount - 1)) + isopt = 0; + else + isopt = (char)(seqtt->flags & ASN1_TFLG_OPTIONAL); + /* + * attempt to read in field, allowing each to be OPTIONAL + */ + + ret = asn1_template_ex_d2i(pseqval, &p, len, seqtt, isopt, ctx); + if (!ret) { + errtt = seqtt; + goto err; + } else if (ret == -1) { + /* + * OPTIONAL component absent. Free and zero the field. + */ + ASN1_template_free(pseqval, seqtt); + continue; + } + /* Update length */ + len -= p - q; + } + + /* Check for EOC if expecting one */ + if (seq_eoc && !asn1_check_eoc(&p, len)) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_MISSING_EOC); + goto err; + } + /* Check all data read */ + if (!seq_nolen && len) { + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_SEQUENCE_LENGTH_MISMATCH); + goto err; + } + + /* + * If we get here we've got no more data in the SEQUENCE, however we + * may not have read all fields so check all remaining are OPTIONAL + * and clear any that are. + */ + for (; i < it->tcount; tt++, i++) { + const ASN1_TEMPLATE *seqtt; + seqtt = asn1_do_adb(pval, tt, 1); + if (!seqtt) + goto err; + if (seqtt->flags & ASN1_TFLG_OPTIONAL) { + ASN1_VALUE **pseqval; + pseqval = asn1_get_field_ptr(pval, seqtt); + ASN1_template_free(pseqval, seqtt); + } else { + errtt = seqtt; + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_FIELD_MISSING); + goto err; + } + } + /* Save encoding */ + if (!asn1_enc_save(pval, *in, p - *in, it)) + goto auxerr; + if (asn1_cb && !asn1_cb(ASN1_OP_D2I_POST, pval, it, NULL)) + goto auxerr; + *in = p; + return 1; + + default: + return 0; + } + auxerr: + ASN1err(ASN1_F_ASN1_ITEM_EX_D2I, ASN1_R_AUX_ERROR); + err: + if (combine == 0) + ASN1_item_ex_free(pval, it); + if (errtt) + ERR_add_error_data(4, "Field=", errtt->field_name, + ", Type=", it->sname); + else + ERR_add_error_data(2, "Type=", it->sname); + return 0; +} + +/* + * Templates are handled with two separate functions. One handles any + * EXPLICIT tag and the other handles the rest. + */ + +static int asn1_template_ex_d2i(ASN1_VALUE **val, + const unsigned char **in, long inlen, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx) +{ + int flags, aclass; + int ret; + long len; + const unsigned char *p, *q; + char exp_eoc; + if (!val) + return 0; + flags = tt->flags; + aclass = flags & ASN1_TFLG_TAG_CLASS; + + p = *in; + + /* Check if EXPLICIT tag expected */ + if (flags & ASN1_TFLG_EXPTAG) { + char cst; + /* + * Need to work out amount of data available to the inner content and + * where it starts: so read in EXPLICIT header to get the info. + */ + ret = asn1_check_tlen(&len, NULL, NULL, &exp_eoc, &cst, + &p, inlen, tt->tag, aclass, opt, ctx); + q = p; + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + return 0; + } else if (ret == -1) + return -1; + if (!cst) { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, + ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED); + return 0; + } + /* We've found the field so it can't be OPTIONAL now */ + ret = asn1_template_noexp_d2i(val, &p, len, tt, 0, ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + return 0; + } + /* We read the field in OK so update length */ + len -= p - q; + if (exp_eoc) { + /* If NDEF we must have an EOC here */ + if (!asn1_check_eoc(&p, len)) { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, ASN1_R_MISSING_EOC); + goto err; + } + } else { + /* + * Otherwise we must hit the EXPLICIT tag end or its an error + */ + if (len) { + ASN1err(ASN1_F_ASN1_TEMPLATE_EX_D2I, + ASN1_R_EXPLICIT_LENGTH_MISMATCH); + goto err; + } + } + } else + return asn1_template_noexp_d2i(val, in, inlen, tt, opt, ctx); + + *in = p; + return 1; + + err: + ASN1_template_free(val, tt); + return 0; +} + +static int asn1_template_noexp_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_TEMPLATE *tt, char opt, + ASN1_TLC *ctx) +{ + int flags, aclass; + int ret; + const unsigned char *p, *q; + if (!val) + return 0; + flags = tt->flags; + aclass = flags & ASN1_TFLG_TAG_CLASS; + + p = *in; + q = p; + + if (flags & ASN1_TFLG_SK_MASK) { + /* SET OF, SEQUENCE OF */ + int sktag, skaclass; + char sk_eoc; + /* First work out expected inner tag value */ + if (flags & ASN1_TFLG_IMPTAG) { + sktag = tt->tag; + skaclass = aclass; + } else { + skaclass = V_ASN1_UNIVERSAL; + if (flags & ASN1_TFLG_SET_OF) + sktag = V_ASN1_SET; + else + sktag = V_ASN1_SEQUENCE; + } + /* Get the tag */ + ret = asn1_check_tlen(&len, NULL, NULL, &sk_eoc, NULL, + &p, len, sktag, skaclass, opt, ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); + return 0; + } else if (ret == -1) + return -1; + if (!*val) + *val = (ASN1_VALUE *)sk_new_null(); + else { + /* + * We've got a valid STACK: free up any items present + */ + STACK_OF(ASN1_VALUE) *sktmp = (STACK_OF(ASN1_VALUE) *)*val; + ASN1_VALUE *vtmp; + while (sk_ASN1_VALUE_num(sktmp) > 0) { + vtmp = sk_ASN1_VALUE_pop(sktmp); + ASN1_item_ex_free(&vtmp, ASN1_ITEM_ptr(tt->item)); + } + } + + if (!*val) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Read as many items as we can */ + while (len > 0) { + ASN1_VALUE *skfield; + q = p; + /* See if EOC found */ + if (asn1_check_eoc(&p, len)) { + if (!sk_eoc) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, + ASN1_R_UNEXPECTED_EOC); + goto err; + } + len -= p - q; + sk_eoc = 0; + break; + } + skfield = NULL; + if (!ASN1_item_ex_d2i(&skfield, &p, len, + ASN1_ITEM_ptr(tt->item), -1, 0, 0, ctx)) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, + ERR_R_NESTED_ASN1_ERROR); + goto err; + } + len -= p - q; + if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE); + goto err; + } + } + if (sk_eoc) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ASN1_R_MISSING_EOC); + goto err; + } + } else if (flags & ASN1_TFLG_IMPTAG) { + /* IMPLICIT tagging */ + ret = ASN1_item_ex_d2i(val, &p, len, + ASN1_ITEM_ptr(tt->item), tt->tag, aclass, opt, + ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } else if (ret == -1) + return -1; + } else { + /* Nothing special */ + ret = ASN1_item_ex_d2i(val, &p, len, ASN1_ITEM_ptr(tt->item), + -1, tt->flags & ASN1_TFLG_COMBINE, opt, ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_NESTED_ASN1_ERROR); + goto err; + } else if (ret == -1) + return -1; + } + + *in = p; + return 1; + + err: + ASN1_template_free(val, tt); + return 0; +} + +static int asn1_d2i_ex_primitive(ASN1_VALUE **pval, + const unsigned char **in, long inlen, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx) +{ + int ret = 0, utype; + long plen; + char cst, inf, free_cont = 0; + const unsigned char *p; + BUF_MEM buf; + const unsigned char *cont = NULL; + long len; + if (!pval) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_NULL); + return 0; /* Should never happen */ + } + + if (it->itype == ASN1_ITYPE_MSTRING) { + utype = tag; + tag = -1; + } else + utype = it->utype; + + if (utype == V_ASN1_ANY) { + /* If type is ANY need to figure out type from tag */ + unsigned char oclass; + if (tag >= 0) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_ILLEGAL_TAGGED_ANY); + return 0; + } + if (opt) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, + ASN1_R_ILLEGAL_OPTIONAL_ANY); + return 0; + } + p = *in; + ret = asn1_check_tlen(NULL, &utype, &oclass, NULL, NULL, + &p, inlen, -1, 0, 0, ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); + return 0; + } + if (oclass != V_ASN1_UNIVERSAL) + utype = V_ASN1_OTHER; + } + if (tag == -1) { + tag = utype; + aclass = V_ASN1_UNIVERSAL; + } + p = *in; + /* Check header */ + ret = asn1_check_tlen(&plen, NULL, NULL, &inf, &cst, + &p, inlen, tag, aclass, opt, ctx); + if (!ret) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_NESTED_ASN1_ERROR); + return 0; + } else if (ret == -1) + return -1; + ret = 0; + /* SEQUENCE, SET and "OTHER" are left in encoded form */ + if ((utype == V_ASN1_SEQUENCE) + || (utype == V_ASN1_SET) || (utype == V_ASN1_OTHER)) { + /* + * Clear context cache for type OTHER because the auto clear when we + * have a exact match wont work + */ + if (utype == V_ASN1_OTHER) { + asn1_tlc_clear(ctx); + } + /* SEQUENCE and SET must be constructed */ + else if (!cst) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, + ASN1_R_TYPE_NOT_CONSTRUCTED); + return 0; + } + + cont = *in; + /* If indefinite length constructed find the real end */ + if (inf) { + if (!asn1_find_end(&p, plen, inf)) + goto err; + len = p - cont; + } else { + len = p - cont + plen; + p += plen; + buf.data = NULL; + } + } else if (cst) { + if (utype == V_ASN1_NULL || utype == V_ASN1_BOOLEAN + || utype == V_ASN1_OBJECT || utype == V_ASN1_INTEGER + || utype == V_ASN1_ENUMERATED) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ASN1_R_TYPE_NOT_PRIMITIVE); + return 0; + } + buf.length = 0; + buf.max = 0; + buf.data = NULL; + /* + * Should really check the internal tags are correct but some things + * may get this wrong. The relevant specs say that constructed string + * types should be OCTET STRINGs internally irrespective of the type. + * So instead just check for UNIVERSAL class and ignore the tag. + */ + if (!asn1_collect(&buf, &p, plen, inf, -1, V_ASN1_UNIVERSAL, 0)) { + free_cont = 1; + goto err; + } + len = buf.length; + /* Append a final null to string */ + if (!BUF_MEM_grow_clean(&buf, len + 1)) { + ASN1err(ASN1_F_ASN1_D2I_EX_PRIMITIVE, ERR_R_MALLOC_FAILURE); + return 0; + } + buf.data[len] = 0; + cont = (const unsigned char *)buf.data; + free_cont = 1; + } else { + cont = p; + len = plen; + p += plen; + } + + /* We now have content length and type: translate into a structure */ + if (!asn1_ex_c2i(pval, cont, len, utype, &free_cont, it)) + goto err; + + *in = p; + ret = 1; + err: + if (free_cont && buf.data) + OPENSSL_free(buf.data); + return ret; +} + +/* Translate ASN1 content octets into a structure */ + +int asn1_ex_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it) +{ + ASN1_VALUE **opval = NULL; + ASN1_STRING *stmp; + ASN1_TYPE *typ = NULL; + int ret = 0; + const ASN1_PRIMITIVE_FUNCS *pf; + ASN1_INTEGER **tint; + pf = it->funcs; + + if (pf && pf->prim_c2i) + return pf->prim_c2i(pval, cont, len, utype, free_cont, it); + /* If ANY type clear type and set pointer to internal value */ + if (it->utype == V_ASN1_ANY) { + if (!*pval) { + typ = ASN1_TYPE_new(); + if (typ == NULL) + goto err; + *pval = (ASN1_VALUE *)typ; + } else + typ = (ASN1_TYPE *)*pval; + + if (utype != typ->type) + ASN1_TYPE_set(typ, utype, NULL); + opval = pval; + pval = &typ->value.asn1_value; + } + switch (utype) { + case V_ASN1_OBJECT: + if (!c2i_ASN1_OBJECT((ASN1_OBJECT **)pval, &cont, len)) + goto err; + break; + + case V_ASN1_NULL: + if (len) { + ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_NULL_IS_WRONG_LENGTH); + goto err; + } + *pval = (ASN1_VALUE *)1; + break; + + case V_ASN1_BOOLEAN: + if (len != 1) { + ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BOOLEAN_IS_WRONG_LENGTH); + goto err; + } else { + ASN1_BOOLEAN *tbool; + tbool = (ASN1_BOOLEAN *)pval; + *tbool = *cont; + } + break; + + case V_ASN1_BIT_STRING: + if (!c2i_ASN1_BIT_STRING((ASN1_BIT_STRING **)pval, &cont, len)) + goto err; + break; + + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + tint = (ASN1_INTEGER **)pval; + if (!c2i_ASN1_INTEGER(tint, &cont, len)) + goto err; + /* Fixup type to match the expected form */ + (*tint)->type = utype | ((*tint)->type & V_ASN1_NEG); + break; + + case V_ASN1_OCTET_STRING: + case V_ASN1_NUMERICSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_VIDEOTEXSTRING: + case V_ASN1_IA5STRING: + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + case V_ASN1_GRAPHICSTRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_BMPSTRING: + case V_ASN1_UTF8STRING: + case V_ASN1_OTHER: + case V_ASN1_SET: + case V_ASN1_SEQUENCE: + default: + if (utype == V_ASN1_BMPSTRING && (len & 1)) { + ASN1err(ASN1_F_ASN1_EX_C2I, ASN1_R_BMPSTRING_IS_WRONG_LENGTH); + goto err; + } + if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) { + ASN1err(ASN1_F_ASN1_EX_C2I, + ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH); + goto err; + } + /* All based on ASN1_STRING and handled the same */ + if (!*pval) { + stmp = ASN1_STRING_type_new(utype); + if (!stmp) { + ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE); + goto err; + } + *pval = (ASN1_VALUE *)stmp; + } else { + stmp = (ASN1_STRING *)*pval; + stmp->type = utype; + } + /* If we've already allocated a buffer use it */ + if (*free_cont) { + if (stmp->data) + OPENSSL_free(stmp->data); + stmp->data = (unsigned char *)cont; /* UGLY CAST! RL */ + stmp->length = len; + *free_cont = 0; + } else { + if (!ASN1_STRING_set(stmp, cont, len)) { + ASN1err(ASN1_F_ASN1_EX_C2I, ERR_R_MALLOC_FAILURE); + ASN1_STRING_free(stmp); + *pval = NULL; + goto err; + } + } + break; + } + /* If ASN1_ANY and NULL type fix up value */ + if (typ && (utype == V_ASN1_NULL)) + typ->value.ptr = NULL; + + ret = 1; + err: + if (!ret) { + ASN1_TYPE_free(typ); + if (opval) + *opval = NULL; + } + return ret; +} + +/* + * This function finds the end of an ASN1 structure when passed its maximum + * length, whether it is indefinite length and a pointer to the content. This + * is more efficient than calling asn1_collect because it does not recurse on + * each indefinite length header. + */ + +static int asn1_find_end(const unsigned char **in, long len, char inf) +{ + int expected_eoc; + long plen; + const unsigned char *p = *in, *q; + /* If not indefinite length constructed just add length */ + if (inf == 0) { + *in += len; + return 1; + } + expected_eoc = 1; + /* + * Indefinite length constructed form. Find the end when enough EOCs are + * found. If more indefinite length constructed headers are encountered + * increment the expected eoc count otherwise just skip to the end of the + * data. + */ + while (len > 0) { + if (asn1_check_eoc(&p, len)) { + expected_eoc--; + if (expected_eoc == 0) + break; + len -= 2; + continue; + } + q = p; + /* Just read in a header: only care about the length */ + if (!asn1_check_tlen(&plen, NULL, NULL, &inf, NULL, &p, len, + -1, 0, 0, NULL)) { + ASN1err(ASN1_F_ASN1_FIND_END, ERR_R_NESTED_ASN1_ERROR); + return 0; + } + if (inf) + expected_eoc++; + else + p += plen; + len -= p - q; + } + if (expected_eoc) { + ASN1err(ASN1_F_ASN1_FIND_END, ASN1_R_MISSING_EOC); + return 0; + } + *in = p; + return 1; +} + +/* + * This function collects the asn1 data from a constructred string type into + * a buffer. The values of 'in' and 'len' should refer to the contents of the + * constructed type and 'inf' should be set if it is indefinite length. + */ + +#ifndef ASN1_MAX_STRING_NEST +/* + * This determines how many levels of recursion are permitted in ASN1 string + * types. If it is not limited stack overflows can occur. If set to zero no + * recursion is allowed at all. Although zero should be adequate examples + * exist that require a value of 1. So 5 should be more than enough. + */ +# define ASN1_MAX_STRING_NEST 5 +#endif + +static int asn1_collect(BUF_MEM *buf, const unsigned char **in, long len, + char inf, int tag, int aclass, int depth) +{ + const unsigned char *p, *q; + long plen; + char cst, ininf; + p = *in; + inf &= 1; + /* + * If no buffer and not indefinite length constructed just pass over the + * encoded data + */ + if (!buf && !inf) { + *in += len; + return 1; + } + while (len > 0) { + q = p; + /* Check for EOC */ + if (asn1_check_eoc(&p, len)) { + /* + * EOC is illegal outside indefinite length constructed form + */ + if (!inf) { + ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_UNEXPECTED_EOC); + return 0; + } + inf = 0; + break; + } + + if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, + len, tag, aclass, 0, NULL)) { + ASN1err(ASN1_F_ASN1_COLLECT, ERR_R_NESTED_ASN1_ERROR); + return 0; + } + + /* If indefinite length constructed update max length */ + if (cst) { + if (depth >= ASN1_MAX_STRING_NEST) { + ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_NESTED_ASN1_STRING); + return 0; + } + if (!asn1_collect(buf, &p, plen, ininf, tag, aclass, depth + 1)) + return 0; + } else if (plen && !collect_data(buf, &p, plen)) + return 0; + len -= p - q; + } + if (inf) { + ASN1err(ASN1_F_ASN1_COLLECT, ASN1_R_MISSING_EOC); + return 0; + } + *in = p; + return 1; +} + +static int collect_data(BUF_MEM *buf, const unsigned char **p, long plen) +{ + int len; + if (buf) { + len = buf->length; + if (!BUF_MEM_grow_clean(buf, len + plen)) { + ASN1err(ASN1_F_COLLECT_DATA, ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(buf->data + len, *p, plen); + } + *p += plen; + return 1; +} + +/* Check for ASN1 EOC and swallow it if found */ + +static int asn1_check_eoc(const unsigned char **in, long len) +{ + const unsigned char *p; + if (len < 2) + return 0; + p = *in; + if (!p[0] && !p[1]) { + *in += 2; + return 1; + } + return 0; +} + +/* + * Check an ASN1 tag and length: a bit like ASN1_get_object but it sets the + * length for indefinite length constructed form, we don't know the exact + * length but we can set an upper bound to the amount of data available minus + * the header length just read. + */ + +static int asn1_check_tlen(long *olen, int *otag, unsigned char *oclass, + char *inf, char *cst, + const unsigned char **in, long len, + int exptag, int expclass, char opt, ASN1_TLC *ctx) +{ + int i; + int ptag, pclass; + long plen; + const unsigned char *p, *q; + p = *in; + q = p; + + if (ctx && ctx->valid) { + i = ctx->ret; + plen = ctx->plen; + pclass = ctx->pclass; + ptag = ctx->ptag; + p += ctx->hdrlen; + } else { + i = ASN1_get_object(&p, &plen, &ptag, &pclass, len); + if (ctx) { + ctx->ret = i; + ctx->plen = plen; + ctx->pclass = pclass; + ctx->ptag = ptag; + ctx->hdrlen = p - q; + ctx->valid = 1; + /* + * If definite length, and no error, length + header can't exceed + * total amount of data available. + */ + if (!(i & 0x81) && ((plen + ctx->hdrlen) > len)) { + ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_TOO_LONG); + asn1_tlc_clear(ctx); + return 0; + } + } + } + + if (i & 0x80) { + ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_BAD_OBJECT_HEADER); + asn1_tlc_clear(ctx); + return 0; + } + if (exptag >= 0) { + if ((exptag != ptag) || (expclass != pclass)) { + /* + * If type is OPTIONAL, not an error: indicate missing type. + */ + if (opt) + return -1; + asn1_tlc_clear(ctx); + ASN1err(ASN1_F_ASN1_CHECK_TLEN, ASN1_R_WRONG_TAG); + return 0; + } + /* + * We have a tag and class match: assume we are going to do something + * with it + */ + asn1_tlc_clear(ctx); + } + + if (i & 1) + plen = len - (p - q); + + if (inf) + *inf = i & 1; + + if (cst) + *cst = i & V_ASN1_CONSTRUCTED; + + if (olen) + *olen = plen; + + if (oclass) + *oclass = pclass; + + if (otag) + *otag = ptag; + + *in = p; + return 1; +} diff --git a/libs/openssl/crypto/asn1/tasn_enc.c b/libs/openssl/crypto/asn1/tasn_enc.c new file mode 100644 index 00000000..f7f83e56 --- /dev/null +++ b/libs/openssl/crypto/asn1/tasn_enc.c @@ -0,0 +1,659 @@ +/* tasn_enc.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include + +static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, + int skcontlen, const ASN1_ITEM *item, + int do_sort, int iclass); +static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_TEMPLATE *tt, int tag, int aclass); +static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it, int flags); + +/* + * Top level i2d equivalents: the 'ndef' variant instructs the encoder to use + * indefinite length constructed encoding, where appropriate + */ + +int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it) +{ + return asn1_item_flags_i2d(val, out, it, ASN1_TFLG_NDEF); +} + +int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it) +{ + return asn1_item_flags_i2d(val, out, it, 0); +} + +/* + * Encode an ASN1 item, this is use by the standard 'i2d' function. 'out' + * points to a buffer to output the data to. The new i2d has one additional + * feature. If the output buffer is NULL (i.e. *out == NULL) then a buffer is + * allocated and populated with the encoding. + */ + +static int asn1_item_flags_i2d(ASN1_VALUE *val, unsigned char **out, + const ASN1_ITEM *it, int flags) +{ + if (out && !*out) { + unsigned char *p, *buf; + int len; + len = ASN1_item_ex_i2d(&val, NULL, it, -1, flags); + if (len <= 0) + return len; + buf = OPENSSL_malloc(len); + if (!buf) + return -1; + p = buf; + ASN1_item_ex_i2d(&val, &p, it, -1, flags); + *out = buf; + return len; + } + + return ASN1_item_ex_i2d(&val, out, it, -1, flags); +} + +/* + * Encode an item, taking care of IMPLICIT tagging (if any). This function + * performs the normal item handling: it can be used in external types. + */ + +int ASN1_item_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass) +{ + const ASN1_TEMPLATE *tt = NULL; + unsigned char *p = NULL; + int i, seqcontlen, seqlen, ndef = 1; + const ASN1_COMPAT_FUNCS *cf; + const ASN1_EXTERN_FUNCS *ef; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb = 0; + + if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) + return 0; + + if (aux && aux->asn1_cb) + asn1_cb = aux->asn1_cb; + + switch (it->itype) { + + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) + return asn1_template_ex_i2d(pval, out, it->templates, + tag, aclass); + return asn1_i2d_ex_primitive(pval, out, it, tag, aclass); + break; + + case ASN1_ITYPE_MSTRING: + return asn1_i2d_ex_primitive(pval, out, it, -1, aclass); + + case ASN1_ITYPE_CHOICE: + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) + return 0; + i = asn1_get_choice_selector(pval, it); + if ((i >= 0) && (i < it->tcount)) { + ASN1_VALUE **pchval; + const ASN1_TEMPLATE *chtt; + chtt = it->templates + i; + pchval = asn1_get_field_ptr(pval, chtt); + return asn1_template_ex_i2d(pchval, out, chtt, -1, aclass); + } + /* Fixme: error condition if selector out of range */ + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) + return 0; + break; + + case ASN1_ITYPE_EXTERN: + /* If new style i2d it does all the work */ + ef = it->funcs; + return ef->asn1_ex_i2d(pval, out, it, tag, aclass); + + case ASN1_ITYPE_COMPAT: + /* old style hackery... */ + cf = it->funcs; + if (out) + p = *out; + i = cf->asn1_i2d(*pval, out); + /* + * Fixup for IMPLICIT tag: note this messes up for tags > 30, but so + * did the old code. Tags > 30 are very rare anyway. + */ + if (out && (tag != -1)) + *p = aclass | tag | (*p & V_ASN1_CONSTRUCTED); + return i; + + case ASN1_ITYPE_NDEF_SEQUENCE: + /* Use indefinite length constructed if requested */ + if (aclass & ASN1_TFLG_NDEF) + ndef = 2; + /* fall through */ + + case ASN1_ITYPE_SEQUENCE: + i = asn1_enc_restore(&seqcontlen, out, pval, it); + /* An error occurred */ + if (i < 0) + return 0; + /* We have a valid cached encoding... */ + if (i > 0) + return seqcontlen; + /* Otherwise carry on */ + seqcontlen = 0; + /* If no IMPLICIT tagging set to SEQUENCE, UNIVERSAL */ + if (tag == -1) { + tag = V_ASN1_SEQUENCE; + /* Retain any other flags in aclass */ + aclass = (aclass & ~ASN1_TFLG_TAG_CLASS) + | V_ASN1_UNIVERSAL; + } + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_PRE, pval, it, NULL)) + return 0; + /* First work out sequence content length */ + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 1); + if (!seqtt) + return 0; + pseqval = asn1_get_field_ptr(pval, seqtt); + /* FIXME: check for errors in enhanced version */ + seqcontlen += asn1_template_ex_i2d(pseqval, NULL, seqtt, + -1, aclass); + } + + seqlen = ASN1_object_size(ndef, seqcontlen, tag); + if (!out) + return seqlen; + /* Output SEQUENCE header */ + ASN1_put_object(out, ndef, seqcontlen, tag, aclass); + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + const ASN1_TEMPLATE *seqtt; + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 1); + if (!seqtt) + return 0; + pseqval = asn1_get_field_ptr(pval, seqtt); + /* FIXME: check for errors in enhanced version */ + asn1_template_ex_i2d(pseqval, out, seqtt, -1, aclass); + } + if (ndef == 2) + ASN1_put_eoc(out); + if (asn1_cb && !asn1_cb(ASN1_OP_I2D_POST, pval, it, NULL)) + return 0; + return seqlen; + + default: + return 0; + + } + return 0; +} + +int ASN1_template_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_TEMPLATE *tt) +{ + return asn1_template_ex_i2d(pval, out, tt, -1, 0); +} + +static int asn1_template_ex_i2d(ASN1_VALUE **pval, unsigned char **out, + const ASN1_TEMPLATE *tt, int tag, int iclass) +{ + int i, ret, flags, ttag, tclass, ndef; + flags = tt->flags; + /* + * Work out tag and class to use: tagging may come either from the + * template or the arguments, not both because this would create + * ambiguity. Additionally the iclass argument may contain some + * additional flags which should be noted and passed down to other + * levels. + */ + if (flags & ASN1_TFLG_TAG_MASK) { + /* Error if argument and template tagging */ + if (tag != -1) + /* FIXME: error code here */ + return -1; + /* Get tagging from template */ + ttag = tt->tag; + tclass = flags & ASN1_TFLG_TAG_CLASS; + } else if (tag != -1) { + /* No template tagging, get from arguments */ + ttag = tag; + tclass = iclass & ASN1_TFLG_TAG_CLASS; + } else { + ttag = -1; + tclass = 0; + } + /* + * Remove any class mask from iflag. + */ + iclass &= ~ASN1_TFLG_TAG_CLASS; + + /* + * At this point 'ttag' contains the outer tag to use, 'tclass' is the + * class and iclass is any flags passed to this function. + */ + + /* if template and arguments require ndef, use it */ + if ((flags & ASN1_TFLG_NDEF) && (iclass & ASN1_TFLG_NDEF)) + ndef = 2; + else + ndef = 1; + + if (flags & ASN1_TFLG_SK_MASK) { + /* SET OF, SEQUENCE OF */ + STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; + int isset, sktag, skaclass; + int skcontlen, sklen; + ASN1_VALUE *skitem; + + if (!*pval) + return 0; + + if (flags & ASN1_TFLG_SET_OF) { + isset = 1; + /* 2 means we reorder */ + if (flags & ASN1_TFLG_SEQUENCE_OF) + isset = 2; + } else + isset = 0; + + /* + * Work out inner tag value: if EXPLICIT or no tagging use underlying + * type. + */ + if ((ttag != -1) && !(flags & ASN1_TFLG_EXPTAG)) { + sktag = ttag; + skaclass = tclass; + } else { + skaclass = V_ASN1_UNIVERSAL; + if (isset) + sktag = V_ASN1_SET; + else + sktag = V_ASN1_SEQUENCE; + } + + /* Determine total length of items */ + skcontlen = 0; + for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + skitem = sk_ASN1_VALUE_value(sk, i); + skcontlen += ASN1_item_ex_i2d(&skitem, NULL, + ASN1_ITEM_ptr(tt->item), + -1, iclass); + } + sklen = ASN1_object_size(ndef, skcontlen, sktag); + /* If EXPLICIT need length of surrounding tag */ + if (flags & ASN1_TFLG_EXPTAG) + ret = ASN1_object_size(ndef, sklen, ttag); + else + ret = sklen; + + if (!out) + return ret; + + /* Now encode this lot... */ + /* EXPLICIT tag */ + if (flags & ASN1_TFLG_EXPTAG) + ASN1_put_object(out, ndef, sklen, ttag, tclass); + /* SET or SEQUENCE and IMPLICIT tag */ + ASN1_put_object(out, ndef, skcontlen, sktag, skaclass); + /* And the stuff itself */ + asn1_set_seq_out(sk, out, skcontlen, ASN1_ITEM_ptr(tt->item), + isset, iclass); + if (ndef == 2) { + ASN1_put_eoc(out); + if (flags & ASN1_TFLG_EXPTAG) + ASN1_put_eoc(out); + } + + return ret; + } + + if (flags & ASN1_TFLG_EXPTAG) { + /* EXPLICIT tagging */ + /* Find length of tagged item */ + i = ASN1_item_ex_i2d(pval, NULL, ASN1_ITEM_ptr(tt->item), -1, iclass); + if (!i) + return 0; + /* Find length of EXPLICIT tag */ + ret = ASN1_object_size(ndef, i, ttag); + if (out) { + /* Output tag and item */ + ASN1_put_object(out, ndef, i, ttag, tclass); + ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), -1, iclass); + if (ndef == 2) + ASN1_put_eoc(out); + } + return ret; + } + + /* Either normal or IMPLICIT tagging: combine class and flags */ + return ASN1_item_ex_i2d(pval, out, ASN1_ITEM_ptr(tt->item), + ttag, tclass | iclass); + +} + +/* Temporary structure used to hold DER encoding of items for SET OF */ + +typedef struct { + unsigned char *data; + int length; + ASN1_VALUE *field; +} DER_ENC; + +static int der_cmp(const void *a, const void *b) +{ + const DER_ENC *d1 = a, *d2 = b; + int cmplen, i; + cmplen = (d1->length < d2->length) ? d1->length : d2->length; + i = memcmp(d1->data, d2->data, cmplen); + if (i) + return i; + return d1->length - d2->length; +} + +/* Output the content octets of SET OF or SEQUENCE OF */ + +static int asn1_set_seq_out(STACK_OF(ASN1_VALUE) *sk, unsigned char **out, + int skcontlen, const ASN1_ITEM *item, + int do_sort, int iclass) +{ + int i; + ASN1_VALUE *skitem; + unsigned char *tmpdat = NULL, *p = NULL; + DER_ENC *derlst = NULL, *tder; + if (do_sort) { + /* Don't need to sort less than 2 items */ + if (sk_ASN1_VALUE_num(sk) < 2) + do_sort = 0; + else { + derlst = OPENSSL_malloc(sk_ASN1_VALUE_num(sk) + * sizeof(*derlst)); + if (!derlst) + return 0; + tmpdat = OPENSSL_malloc(skcontlen); + if (!tmpdat) { + OPENSSL_free(derlst); + return 0; + } + } + } + /* If not sorting just output each item */ + if (!do_sort) { + for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + skitem = sk_ASN1_VALUE_value(sk, i); + ASN1_item_ex_i2d(&skitem, out, item, -1, iclass); + } + return 1; + } + p = tmpdat; + + /* Doing sort: build up a list of each member's DER encoding */ + for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { + skitem = sk_ASN1_VALUE_value(sk, i); + tder->data = p; + tder->length = ASN1_item_ex_i2d(&skitem, &p, item, -1, iclass); + tder->field = skitem; + } + + /* Now sort them */ + qsort(derlst, sk_ASN1_VALUE_num(sk), sizeof(*derlst), der_cmp); + /* Output sorted DER encoding */ + p = *out; + for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) { + memcpy(p, tder->data, tder->length); + p += tder->length; + } + *out = p; + /* If do_sort is 2 then reorder the STACK */ + if (do_sort == 2) { + for (i = 0, tder = derlst; i < sk_ASN1_VALUE_num(sk); i++, tder++) + (void)sk_ASN1_VALUE_set(sk, i, tder->field); + } + OPENSSL_free(derlst); + OPENSSL_free(tmpdat); + return 1; +} + +static int asn1_i2d_ex_primitive(ASN1_VALUE **pval, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass) +{ + int len; + int utype; + int usetag; + int ndef = 0; + + utype = it->utype; + + /* + * Get length of content octets and maybe find out the underlying type. + */ + + len = asn1_ex_i2c(pval, NULL, &utype, it); + + /* + * If SEQUENCE, SET or OTHER then header is included in pseudo content + * octets so don't include tag+length. We need to check here because the + * call to asn1_ex_i2c() could change utype. + */ + if ((utype == V_ASN1_SEQUENCE) || (utype == V_ASN1_SET) || + (utype == V_ASN1_OTHER)) + usetag = 0; + else + usetag = 1; + + /* -1 means omit type */ + + if (len == -1) + return 0; + + /* -2 return is special meaning use ndef */ + if (len == -2) { + ndef = 2; + len = 0; + } + + /* If not implicitly tagged get tag from underlying type */ + if (tag == -1) + tag = utype; + + /* Output tag+length followed by content octets */ + if (out) { + if (usetag) + ASN1_put_object(out, ndef, len, tag, aclass); + asn1_ex_i2c(pval, *out, &utype, it); + if (ndef) + ASN1_put_eoc(out); + else + *out += len; + } + + if (usetag) + return ASN1_object_size(ndef, len, tag); + return len; +} + +/* Produce content octets from a structure */ + +int asn1_ex_i2c(ASN1_VALUE **pval, unsigned char *cout, int *putype, + const ASN1_ITEM *it) +{ + ASN1_BOOLEAN *tbool = NULL; + ASN1_STRING *strtmp; + ASN1_OBJECT *otmp; + int utype; + const unsigned char *cont; + unsigned char c; + int len; + const ASN1_PRIMITIVE_FUNCS *pf; + pf = it->funcs; + if (pf && pf->prim_i2c) + return pf->prim_i2c(pval, cout, putype, it); + + /* Should type be omitted? */ + if ((it->itype != ASN1_ITYPE_PRIMITIVE) + || (it->utype != V_ASN1_BOOLEAN)) { + if (!*pval) + return -1; + } + + if (it->itype == ASN1_ITYPE_MSTRING) { + /* If MSTRING type set the underlying type */ + strtmp = (ASN1_STRING *)*pval; + utype = strtmp->type; + *putype = utype; + } else if (it->utype == V_ASN1_ANY) { + /* If ANY set type and pointer to value */ + ASN1_TYPE *typ; + typ = (ASN1_TYPE *)*pval; + utype = typ->type; + *putype = utype; + pval = &typ->value.asn1_value; + } else + utype = *putype; + + switch (utype) { + case V_ASN1_OBJECT: + otmp = (ASN1_OBJECT *)*pval; + cont = otmp->data; + len = otmp->length; + break; + + case V_ASN1_NULL: + cont = NULL; + len = 0; + break; + + case V_ASN1_BOOLEAN: + tbool = (ASN1_BOOLEAN *)pval; + if (*tbool == -1) + return -1; + if (it->utype != V_ASN1_ANY) { + /* + * Default handling if value == size field then omit + */ + if (*tbool && (it->size > 0)) + return -1; + if (!*tbool && !it->size) + return -1; + } + c = (unsigned char)*tbool; + cont = &c; + len = 1; + break; + + case V_ASN1_BIT_STRING: + return i2c_ASN1_BIT_STRING((ASN1_BIT_STRING *)*pval, + cout ? &cout : NULL); + break; + + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + /* + * These are all have the same content format as ASN1_INTEGER + */ + return i2c_ASN1_INTEGER((ASN1_INTEGER *)*pval, cout ? &cout : NULL); + break; + + case V_ASN1_OCTET_STRING: + case V_ASN1_NUMERICSTRING: + case V_ASN1_PRINTABLESTRING: + case V_ASN1_T61STRING: + case V_ASN1_VIDEOTEXSTRING: + case V_ASN1_IA5STRING: + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + case V_ASN1_GRAPHICSTRING: + case V_ASN1_VISIBLESTRING: + case V_ASN1_GENERALSTRING: + case V_ASN1_UNIVERSALSTRING: + case V_ASN1_BMPSTRING: + case V_ASN1_UTF8STRING: + case V_ASN1_SEQUENCE: + case V_ASN1_SET: + default: + /* All based on ASN1_STRING and handled the same */ + strtmp = (ASN1_STRING *)*pval; + /* Special handling for NDEF */ + if ((it->size == ASN1_TFLG_NDEF) + && (strtmp->flags & ASN1_STRING_FLAG_NDEF)) { + if (cout) { + strtmp->data = cout; + strtmp->length = 0; + } + /* Special return code */ + return -2; + } + cont = strtmp->data; + len = strtmp->length; + + break; + + } + if (cout && len) + memcpy(cout, cont, len); + return len; +} diff --git a/libs/openssl/crypto/asn1/tasn_fre.c b/libs/openssl/crypto/asn1/tasn_fre.c new file mode 100644 index 00000000..aeea4eff --- /dev/null +++ b/libs/openssl/crypto/asn1/tasn_fre.c @@ -0,0 +1,249 @@ +/* tasn_fre.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include + +static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine); + +/* Free up an ASN1 structure */ + +void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it) +{ + asn1_item_combine_free(&val, it, 0); +} + +void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + asn1_item_combine_free(pval, it, 0); +} + +static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine) +{ + const ASN1_TEMPLATE *tt = NULL, *seqtt; + const ASN1_EXTERN_FUNCS *ef; + const ASN1_COMPAT_FUNCS *cf; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb; + int i; + if (!pval) + return; + if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval) + return; + if (aux && aux->asn1_cb) + asn1_cb = aux->asn1_cb; + else + asn1_cb = 0; + + switch (it->itype) { + + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) + ASN1_template_free(pval, it->templates); + else + ASN1_primitive_free(pval, it); + break; + + case ASN1_ITYPE_MSTRING: + ASN1_primitive_free(pval, it); + break; + + case ASN1_ITYPE_CHOICE: + if (asn1_cb) { + i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); + if (i == 2) + return; + } + i = asn1_get_choice_selector(pval, it); + if ((i >= 0) && (i < it->tcount)) { + ASN1_VALUE **pchval; + tt = it->templates + i; + pchval = asn1_get_field_ptr(pval, tt); + ASN1_template_free(pchval, tt); + } + if (asn1_cb) + asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); + if (!combine) { + OPENSSL_free(*pval); + *pval = NULL; + } + break; + + case ASN1_ITYPE_COMPAT: + cf = it->funcs; + if (cf && cf->asn1_free) + cf->asn1_free(*pval); + break; + + case ASN1_ITYPE_EXTERN: + ef = it->funcs; + if (ef && ef->asn1_ex_free) + ef->asn1_ex_free(pval, it); + break; + + case ASN1_ITYPE_NDEF_SEQUENCE: + case ASN1_ITYPE_SEQUENCE: + if (asn1_do_lock(pval, -1, it) > 0) + return; + if (asn1_cb) { + i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL); + if (i == 2) + return; + } + asn1_enc_free(pval, it); + /* + * If we free up as normal we will invalidate any ANY DEFINED BY + * field and we wont be able to determine the type of the field it + * defines. So free up in reverse order. + */ + tt = it->templates + it->tcount - 1; + for (i = 0; i < it->tcount; tt--, i++) { + ASN1_VALUE **pseqval; + seqtt = asn1_do_adb(pval, tt, 0); + if (!seqtt) + continue; + pseqval = asn1_get_field_ptr(pval, seqtt); + ASN1_template_free(pseqval, seqtt); + } + if (asn1_cb) + asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL); + if (!combine) { + OPENSSL_free(*pval); + *pval = NULL; + } + break; + } +} + +void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) +{ + int i; + if (tt->flags & ASN1_TFLG_SK_MASK) { + STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval; + for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) { + ASN1_VALUE *vtmp; + vtmp = sk_ASN1_VALUE_value(sk, i); + asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 0); + } + sk_ASN1_VALUE_free(sk); + *pval = NULL; + } else + asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item), + tt->flags & ASN1_TFLG_COMBINE); +} + +void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + int utype; + if (it) { + const ASN1_PRIMITIVE_FUNCS *pf; + pf = it->funcs; + if (pf && pf->prim_free) { + pf->prim_free(pval, it); + return; + } + } + /* Special case: if 'it' is NULL free contents of ASN1_TYPE */ + if (!it) { + ASN1_TYPE *typ = (ASN1_TYPE *)*pval; + utype = typ->type; + pval = &typ->value.asn1_value; + if (!*pval) + return; + } else if (it->itype == ASN1_ITYPE_MSTRING) { + utype = -1; + if (!*pval) + return; + } else { + utype = it->utype; + if ((utype != V_ASN1_BOOLEAN) && !*pval) + return; + } + + switch (utype) { + case V_ASN1_OBJECT: + ASN1_OBJECT_free((ASN1_OBJECT *)*pval); + break; + + case V_ASN1_BOOLEAN: + if (it) + *(ASN1_BOOLEAN *)pval = it->size; + else + *(ASN1_BOOLEAN *)pval = -1; + return; + + case V_ASN1_NULL: + break; + + case V_ASN1_ANY: + ASN1_primitive_free(pval, NULL); + OPENSSL_free(*pval); + break; + + default: + ASN1_STRING_free((ASN1_STRING *)*pval); + *pval = NULL; + break; + } + *pval = NULL; +} diff --git a/libs/openssl/crypto/asn1/tasn_new.c b/libs/openssl/crypto/asn1/tasn_new.c new file mode 100644 index 00000000..b0c73bee --- /dev/null +++ b/libs/openssl/crypto/asn1/tasn_new.c @@ -0,0 +1,381 @@ +/* tasn_new.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include + +static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine); +static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); +static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); +static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it); + +ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it) +{ + ASN1_VALUE *ret = NULL; + if (ASN1_item_ex_new(&ret, it) > 0) + return ret; + return NULL; +} + +/* Allocate an ASN1 structure */ + +int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + return asn1_item_ex_combine_new(pval, it, 0); +} + +static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine) +{ + const ASN1_TEMPLATE *tt = NULL; + const ASN1_COMPAT_FUNCS *cf; + const ASN1_EXTERN_FUNCS *ef; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb; + ASN1_VALUE **pseqval; + int i; + if (aux && aux->asn1_cb) + asn1_cb = aux->asn1_cb; + else + asn1_cb = 0; + +#ifdef CRYPTO_MDEBUG + if (it->sname) + CRYPTO_push_info(it->sname); +#endif + + switch (it->itype) { + + case ASN1_ITYPE_EXTERN: + ef = it->funcs; + if (ef && ef->asn1_ex_new) { + if (!ef->asn1_ex_new(pval, it)) + goto memerr; + } + break; + + case ASN1_ITYPE_COMPAT: + cf = it->funcs; + if (cf && cf->asn1_new) { + *pval = cf->asn1_new(); + if (!*pval) + goto memerr; + } + break; + + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) { + if (!ASN1_template_new(pval, it->templates)) + goto memerr; + } else if (!ASN1_primitive_new(pval, it)) + goto memerr; + break; + + case ASN1_ITYPE_MSTRING: + if (!ASN1_primitive_new(pval, it)) + goto memerr; + break; + + case ASN1_ITYPE_CHOICE: + if (asn1_cb) { + i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); + if (!i) + goto auxerr; + if (i == 2) { +#ifdef CRYPTO_MDEBUG + if (it->sname) + CRYPTO_pop_info(); +#endif + return 1; + } + } + if (!combine) { + *pval = OPENSSL_malloc(it->size); + if (!*pval) + goto memerr; + memset(*pval, 0, it->size); + } + asn1_set_choice_selector(pval, -1, it); + if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) + goto auxerr; + break; + + case ASN1_ITYPE_NDEF_SEQUENCE: + case ASN1_ITYPE_SEQUENCE: + if (asn1_cb) { + i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL); + if (!i) + goto auxerr; + if (i == 2) { +#ifdef CRYPTO_MDEBUG + if (it->sname) + CRYPTO_pop_info(); +#endif + return 1; + } + } + if (!combine) { + *pval = OPENSSL_malloc(it->size); + if (!*pval) + goto memerr; + memset(*pval, 0, it->size); + asn1_do_lock(pval, 0, it); + asn1_enc_init(pval, it); + } + for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) { + pseqval = asn1_get_field_ptr(pval, tt); + if (!ASN1_template_new(pseqval, tt)) + goto memerr; + } + if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL)) + goto auxerr; + break; + } +#ifdef CRYPTO_MDEBUG + if (it->sname) + CRYPTO_pop_info(); +#endif + return 1; + + memerr: + ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE); +#ifdef CRYPTO_MDEBUG + if (it->sname) + CRYPTO_pop_info(); +#endif + return 0; + + auxerr: + ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR); + ASN1_item_ex_free(pval, it); +#ifdef CRYPTO_MDEBUG + if (it->sname) + CRYPTO_pop_info(); +#endif + return 0; + +} + +static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + const ASN1_EXTERN_FUNCS *ef; + + switch (it->itype) { + + case ASN1_ITYPE_EXTERN: + ef = it->funcs; + if (ef && ef->asn1_ex_clear) + ef->asn1_ex_clear(pval, it); + else + *pval = NULL; + break; + + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) + asn1_template_clear(pval, it->templates); + else + asn1_primitive_clear(pval, it); + break; + + case ASN1_ITYPE_MSTRING: + asn1_primitive_clear(pval, it); + break; + + case ASN1_ITYPE_COMPAT: + case ASN1_ITYPE_CHOICE: + case ASN1_ITYPE_SEQUENCE: + case ASN1_ITYPE_NDEF_SEQUENCE: + *pval = NULL; + break; + } +} + +int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) +{ + const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item); + int ret; + if (tt->flags & ASN1_TFLG_OPTIONAL) { + asn1_template_clear(pval, tt); + return 1; + } + /* If ANY DEFINED BY nothing to do */ + + if (tt->flags & ASN1_TFLG_ADB_MASK) { + *pval = NULL; + return 1; + } +#ifdef CRYPTO_MDEBUG + if (tt->field_name) + CRYPTO_push_info(tt->field_name); +#endif + /* If SET OF or SEQUENCE OF, its a STACK */ + if (tt->flags & ASN1_TFLG_SK_MASK) { + STACK_OF(ASN1_VALUE) *skval; + skval = sk_ASN1_VALUE_new_null(); + if (!skval) { + ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE); + ret = 0; + goto done; + } + *pval = (ASN1_VALUE *)skval; + ret = 1; + goto done; + } + /* Otherwise pass it back to the item routine */ + ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE); + done: +#ifdef CRYPTO_MDEBUG + if (it->sname) + CRYPTO_pop_info(); +#endif + return ret; +} + +static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) +{ + /* If ADB or STACK just NULL the field */ + if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK)) + *pval = NULL; + else + asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item)); +} + +/* + * NB: could probably combine most of the real XXX_new() behaviour and junk + * all the old functions. + */ + +int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + ASN1_TYPE *typ; + ASN1_STRING *str; + int utype; + + if (!it) + return 0; + + if (it->funcs) { + const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; + if (pf->prim_new) + return pf->prim_new(pval, it); + } + + if (it->itype == ASN1_ITYPE_MSTRING) + utype = -1; + else + utype = it->utype; + switch (utype) { + case V_ASN1_OBJECT: + *pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef); + return 1; + + case V_ASN1_BOOLEAN: + *(ASN1_BOOLEAN *)pval = it->size; + return 1; + + case V_ASN1_NULL: + *pval = (ASN1_VALUE *)1; + return 1; + + case V_ASN1_ANY: + typ = OPENSSL_malloc(sizeof(ASN1_TYPE)); + if (!typ) + return 0; + typ->value.ptr = NULL; + typ->type = -1; + *pval = (ASN1_VALUE *)typ; + break; + + default: + str = ASN1_STRING_type_new(utype); + if (it->itype == ASN1_ITYPE_MSTRING && str) + str->flags |= ASN1_STRING_FLAG_MSTRING; + *pval = (ASN1_VALUE *)str; + break; + } + if (*pval) + return 1; + return 0; +} + +static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + int utype; + if (it && it->funcs) { + const ASN1_PRIMITIVE_FUNCS *pf = it->funcs; + if (pf->prim_clear) + pf->prim_clear(pval, it); + else + *pval = NULL; + return; + } + if (!it || (it->itype == ASN1_ITYPE_MSTRING)) + utype = -1; + else + utype = it->utype; + if (utype == V_ASN1_BOOLEAN) + *(ASN1_BOOLEAN *)pval = it->size; + else + *pval = NULL; +} diff --git a/libs/openssl/crypto/asn1/tasn_prn.c b/libs/openssl/crypto/asn1/tasn_prn.c new file mode 100644 index 00000000..5e7d53e9 --- /dev/null +++ b/libs/openssl/crypto/asn1/tasn_prn.c @@ -0,0 +1,585 @@ +/* tasn_prn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000,2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include "asn1_locl.h" + +/* + * Print routines. + */ + +/* ASN1_PCTX routines */ + +ASN1_PCTX default_pctx = { + ASN1_PCTX_FLAGS_SHOW_ABSENT, /* flags */ + 0, /* nm_flags */ + 0, /* cert_flags */ + 0, /* oid_flags */ + 0 /* str_flags */ +}; + +ASN1_PCTX *ASN1_PCTX_new(void) +{ + ASN1_PCTX *ret; + ret = OPENSSL_malloc(sizeof(ASN1_PCTX)); + if (ret == NULL) { + ASN1err(ASN1_F_ASN1_PCTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + ret->flags = 0; + ret->nm_flags = 0; + ret->cert_flags = 0; + ret->oid_flags = 0; + ret->str_flags = 0; + return ret; +} + +void ASN1_PCTX_free(ASN1_PCTX *p) +{ + OPENSSL_free(p); +} + +unsigned long ASN1_PCTX_get_flags(ASN1_PCTX *p) +{ + return p->flags; +} + +void ASN1_PCTX_set_flags(ASN1_PCTX *p, unsigned long flags) +{ + p->flags = flags; +} + +unsigned long ASN1_PCTX_get_nm_flags(ASN1_PCTX *p) +{ + return p->nm_flags; +} + +void ASN1_PCTX_set_nm_flags(ASN1_PCTX *p, unsigned long flags) +{ + p->nm_flags = flags; +} + +unsigned long ASN1_PCTX_get_cert_flags(ASN1_PCTX *p) +{ + return p->cert_flags; +} + +void ASN1_PCTX_set_cert_flags(ASN1_PCTX *p, unsigned long flags) +{ + p->cert_flags = flags; +} + +unsigned long ASN1_PCTX_get_oid_flags(ASN1_PCTX *p) +{ + return p->oid_flags; +} + +void ASN1_PCTX_set_oid_flags(ASN1_PCTX *p, unsigned long flags) +{ + p->oid_flags = flags; +} + +unsigned long ASN1_PCTX_get_str_flags(ASN1_PCTX *p) +{ + return p->str_flags; +} + +void ASN1_PCTX_set_str_flags(ASN1_PCTX *p, unsigned long flags) +{ + p->str_flags = flags; +} + +/* Main print routines */ + +static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, + const ASN1_ITEM *it, + const char *fname, const char *sname, + int nohdr, const ASN1_PCTX *pctx); + +int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, + const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx); + +static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, + const ASN1_ITEM *it, int indent, + const char *fname, const char *sname, + const ASN1_PCTX *pctx); + +static int asn1_print_fsname(BIO *out, int indent, + const char *fname, const char *sname, + const ASN1_PCTX *pctx); + +int ASN1_item_print(BIO *out, ASN1_VALUE *ifld, int indent, + const ASN1_ITEM *it, const ASN1_PCTX *pctx) +{ + const char *sname; + if (pctx == NULL) + pctx = &default_pctx; + if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME) + sname = NULL; + else + sname = it->sname; + return asn1_item_print_ctx(out, &ifld, indent, it, NULL, sname, 0, pctx); +} + +static int asn1_item_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, + const ASN1_ITEM *it, + const char *fname, const char *sname, + int nohdr, const ASN1_PCTX *pctx) +{ + const ASN1_TEMPLATE *tt; + const ASN1_EXTERN_FUNCS *ef; + ASN1_VALUE **tmpfld; + const ASN1_AUX *aux = it->funcs; + ASN1_aux_cb *asn1_cb; + ASN1_PRINT_ARG parg; + int i; + if (aux && aux->asn1_cb) { + parg.out = out; + parg.indent = indent; + parg.pctx = pctx; + asn1_cb = aux->asn1_cb; + } else + asn1_cb = 0; + + if (*fld == NULL) { + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_ABSENT) { + if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) + return 0; + if (BIO_puts(out, "\n") <= 0) + return 0; + } + return 1; + } + + switch (it->itype) { + case ASN1_ITYPE_PRIMITIVE: + if (it->templates) { + if (!asn1_template_print_ctx(out, fld, indent, + it->templates, pctx)) + return 0; + break; + } + /* fall thru */ + case ASN1_ITYPE_MSTRING: + if (!asn1_primitive_print(out, fld, it, indent, fname, sname, pctx)) + return 0; + break; + + case ASN1_ITYPE_EXTERN: + if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) + return 0; + /* Use new style print routine if possible */ + ef = it->funcs; + if (ef && ef->asn1_ex_print) { + i = ef->asn1_ex_print(out, fld, indent, "", pctx); + if (!i) + return 0; + if ((i == 2) && (BIO_puts(out, "\n") <= 0)) + return 0; + return 1; + } else if (sname && + BIO_printf(out, ":EXTERNAL TYPE %s\n", sname) <= 0) + return 0; + break; + + case ASN1_ITYPE_CHOICE: +#if 0 + if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) + return 0; +#endif + /* CHOICE type, get selector */ + i = asn1_get_choice_selector(fld, it); + /* This should never happen... */ + if ((i < 0) || (i >= it->tcount)) { + if (BIO_printf(out, "ERROR: selector [%d] invalid\n", i) <= 0) + return 0; + return 1; + } + tt = it->templates + i; + tmpfld = asn1_get_field_ptr(fld, tt); + if (!asn1_template_print_ctx(out, tmpfld, indent, tt, pctx)) + return 0; + break; + + case ASN1_ITYPE_SEQUENCE: + case ASN1_ITYPE_NDEF_SEQUENCE: + if (!nohdr && !asn1_print_fsname(out, indent, fname, sname, pctx)) + return 0; + if (fname || sname) { + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { + if (BIO_puts(out, " {\n") <= 0) + return 0; + } else { + if (BIO_puts(out, "\n") <= 0) + return 0; + } + } + + if (asn1_cb) { + i = asn1_cb(ASN1_OP_PRINT_PRE, fld, it, &parg); + if (i == 0) + return 0; + if (i == 2) + return 1; + } + + /* Print each field entry */ + for (i = 0, tt = it->templates; i < it->tcount; i++, tt++) { + const ASN1_TEMPLATE *seqtt; + seqtt = asn1_do_adb(fld, tt, 1); + if (!seqtt) + return 0; + tmpfld = asn1_get_field_ptr(fld, seqtt); + if (!asn1_template_print_ctx(out, tmpfld, + indent + 2, seqtt, pctx)) + return 0; + } + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { + if (BIO_printf(out, "%*s}\n", indent, "") < 0) + return 0; + } + + if (asn1_cb) { + i = asn1_cb(ASN1_OP_PRINT_POST, fld, it, &parg); + if (i == 0) + return 0; + } + break; + + default: + BIO_printf(out, "Unprocessed type %d\n", it->itype); + return 0; + } + + return 1; +} + +int asn1_template_print_ctx(BIO *out, ASN1_VALUE **fld, int indent, + const ASN1_TEMPLATE *tt, const ASN1_PCTX *pctx) +{ + int i, flags; + const char *sname, *fname; + flags = tt->flags; + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_FIELD_STRUCT_NAME) + sname = ASN1_ITEM_ptr(tt->item)->sname; + else + sname = NULL; + if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) + fname = NULL; + else + fname = tt->field_name; + if (flags & ASN1_TFLG_SK_MASK) { + char *tname; + ASN1_VALUE *skitem; + STACK_OF(ASN1_VALUE) *stack; + + /* SET OF, SEQUENCE OF */ + if (fname) { + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SSOF) { + if (flags & ASN1_TFLG_SET_OF) + tname = "SET"; + else + tname = "SEQUENCE"; + if (BIO_printf(out, "%*s%s OF %s {\n", + indent, "", tname, tt->field_name) <= 0) + return 0; + } else if (BIO_printf(out, "%*s%s:\n", indent, "", fname) <= 0) + return 0; + } + stack = (STACK_OF(ASN1_VALUE) *)*fld; + for (i = 0; i < sk_ASN1_VALUE_num(stack); i++) { + if ((i > 0) && (BIO_puts(out, "\n") <= 0)) + return 0; + + skitem = sk_ASN1_VALUE_value(stack, i); + if (!asn1_item_print_ctx(out, &skitem, indent + 2, + ASN1_ITEM_ptr(tt->item), NULL, NULL, 1, + pctx)) + return 0; + } + if (!i && BIO_printf(out, "%*s\n", indent + 2, "") <= 0) + return 0; + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_SEQUENCE) { + if (BIO_printf(out, "%*s}\n", indent, "") <= 0) + return 0; + } + return 1; + } + return asn1_item_print_ctx(out, fld, indent, ASN1_ITEM_ptr(tt->item), + fname, sname, 0, pctx); +} + +static int asn1_print_fsname(BIO *out, int indent, + const char *fname, const char *sname, + const ASN1_PCTX *pctx) +{ + static char spaces[] = " "; + const int nspaces = sizeof(spaces) - 1; + +#if 0 + if (!sname && !fname) + return 1; +#endif + + while (indent > nspaces) { + if (BIO_write(out, spaces, nspaces) != nspaces) + return 0; + indent -= nspaces; + } + if (BIO_write(out, spaces, indent) != indent) + return 0; + if (pctx->flags & ASN1_PCTX_FLAGS_NO_STRUCT_NAME) + sname = NULL; + if (pctx->flags & ASN1_PCTX_FLAGS_NO_FIELD_NAME) + fname = NULL; + if (!sname && !fname) + return 1; + if (fname) { + if (BIO_puts(out, fname) <= 0) + return 0; + } + if (sname) { + if (fname) { + if (BIO_printf(out, " (%s)", sname) <= 0) + return 0; + } else { + if (BIO_puts(out, sname) <= 0) + return 0; + } + } + if (BIO_write(out, ": ", 2) != 2) + return 0; + return 1; +} + +static int asn1_print_boolean_ctx(BIO *out, int boolval, + const ASN1_PCTX *pctx) +{ + const char *str; + switch (boolval) { + case -1: + str = "BOOL ABSENT"; + break; + + case 0: + str = "FALSE"; + break; + + default: + str = "TRUE"; + break; + + } + + if (BIO_puts(out, str) <= 0) + return 0; + return 1; + +} + +static int asn1_print_integer_ctx(BIO *out, ASN1_INTEGER *str, + const ASN1_PCTX *pctx) +{ + char *s; + int ret = 1; + s = i2s_ASN1_INTEGER(NULL, str); + if (BIO_puts(out, s) <= 0) + ret = 0; + OPENSSL_free(s); + return ret; +} + +static int asn1_print_oid_ctx(BIO *out, const ASN1_OBJECT *oid, + const ASN1_PCTX *pctx) +{ + char objbuf[80]; + const char *ln; + ln = OBJ_nid2ln(OBJ_obj2nid(oid)); + if (!ln) + ln = ""; + OBJ_obj2txt(objbuf, sizeof objbuf, oid, 1); + if (BIO_printf(out, "%s (%s)", ln, objbuf) <= 0) + return 0; + return 1; +} + +static int asn1_print_obstring_ctx(BIO *out, ASN1_STRING *str, int indent, + const ASN1_PCTX *pctx) +{ + if (str->type == V_ASN1_BIT_STRING) { + if (BIO_printf(out, " (%ld unused bits)\n", str->flags & 0x7) <= 0) + return 0; + } else if (BIO_puts(out, "\n") <= 0) + return 0; + if ((str->length > 0) + && BIO_dump_indent(out, (char *)str->data, str->length, + indent + 2) <= 0) + return 0; + return 1; +} + +static int asn1_primitive_print(BIO *out, ASN1_VALUE **fld, + const ASN1_ITEM *it, int indent, + const char *fname, const char *sname, + const ASN1_PCTX *pctx) +{ + long utype; + ASN1_STRING *str; + int ret = 1, needlf = 1; + const char *pname; + const ASN1_PRIMITIVE_FUNCS *pf; + pf = it->funcs; + if (!asn1_print_fsname(out, indent, fname, sname, pctx)) + return 0; + if (pf && pf->prim_print) + return pf->prim_print(out, fld, it, indent, pctx); + str = (ASN1_STRING *)*fld; + if (it->itype == ASN1_ITYPE_MSTRING) + utype = str->type & ~V_ASN1_NEG; + else + utype = it->utype; + if (utype == V_ASN1_ANY) { + ASN1_TYPE *atype = (ASN1_TYPE *)*fld; + utype = atype->type; + fld = &atype->value.asn1_value; + str = (ASN1_STRING *)*fld; + if (pctx->flags & ASN1_PCTX_FLAGS_NO_ANY_TYPE) + pname = NULL; + else + pname = ASN1_tag2str(utype); + } else { + if (pctx->flags & ASN1_PCTX_FLAGS_SHOW_TYPE) + pname = ASN1_tag2str(utype); + else + pname = NULL; + } + + if (utype == V_ASN1_NULL) { + if (BIO_puts(out, "NULL\n") <= 0) + return 0; + return 1; + } + + if (pname) { + if (BIO_puts(out, pname) <= 0) + return 0; + if (BIO_puts(out, ":") <= 0) + return 0; + } + + switch (utype) { + case V_ASN1_BOOLEAN: + { + int boolval = *(int *)fld; + if (boolval == -1) + boolval = it->size; + ret = asn1_print_boolean_ctx(out, boolval, pctx); + } + break; + + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + ret = asn1_print_integer_ctx(out, str, pctx); + break; + + case V_ASN1_UTCTIME: + ret = ASN1_UTCTIME_print(out, str); + break; + + case V_ASN1_GENERALIZEDTIME: + ret = ASN1_GENERALIZEDTIME_print(out, str); + break; + + case V_ASN1_OBJECT: + ret = asn1_print_oid_ctx(out, (const ASN1_OBJECT *)*fld, pctx); + break; + + case V_ASN1_OCTET_STRING: + case V_ASN1_BIT_STRING: + ret = asn1_print_obstring_ctx(out, str, indent, pctx); + needlf = 0; + break; + + case V_ASN1_SEQUENCE: + case V_ASN1_SET: + case V_ASN1_OTHER: + if (BIO_puts(out, "\n") <= 0) + return 0; + if (ASN1_parse_dump(out, str->data, str->length, indent, 0) <= 0) + ret = 0; + needlf = 0; + break; + + default: + ret = ASN1_STRING_print_ex(out, str, pctx->str_flags); + + } + if (!ret) + return 0; + if (needlf && BIO_puts(out, "\n") <= 0) + return 0; + return 1; +} diff --git a/libs/openssl/crypto/asn1/tasn_typ.c b/libs/openssl/crypto/asn1/tasn_typ.c new file mode 100644 index 00000000..740e86d5 --- /dev/null +++ b/libs/openssl/crypto/asn1/tasn_typ.c @@ -0,0 +1,149 @@ +/* tasn_typ.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include +#include +#include + +/* Declarations for string types */ + + +IMPLEMENT_ASN1_TYPE(ASN1_INTEGER) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_INTEGER) + +IMPLEMENT_ASN1_TYPE(ASN1_ENUMERATED) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_ENUMERATED) + +IMPLEMENT_ASN1_TYPE(ASN1_BIT_STRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_BIT_STRING) + +IMPLEMENT_ASN1_TYPE(ASN1_OCTET_STRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_OCTET_STRING) + +IMPLEMENT_ASN1_TYPE(ASN1_NULL) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL) + +IMPLEMENT_ASN1_TYPE(ASN1_OBJECT) + +IMPLEMENT_ASN1_TYPE(ASN1_UTF8STRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTF8STRING) + +IMPLEMENT_ASN1_TYPE(ASN1_PRINTABLESTRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_PRINTABLESTRING) + +IMPLEMENT_ASN1_TYPE(ASN1_T61STRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_T61STRING) + +IMPLEMENT_ASN1_TYPE(ASN1_IA5STRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_IA5STRING) + +IMPLEMENT_ASN1_TYPE(ASN1_GENERALSTRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALSTRING) + +IMPLEMENT_ASN1_TYPE(ASN1_UTCTIME) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_UTCTIME) + +IMPLEMENT_ASN1_TYPE(ASN1_GENERALIZEDTIME) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_GENERALIZEDTIME) + +IMPLEMENT_ASN1_TYPE(ASN1_VISIBLESTRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_VISIBLESTRING) + +IMPLEMENT_ASN1_TYPE(ASN1_UNIVERSALSTRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_UNIVERSALSTRING) + +IMPLEMENT_ASN1_TYPE(ASN1_BMPSTRING) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_BMPSTRING) + +IMPLEMENT_ASN1_TYPE(ASN1_ANY) + +/* Just swallow an ASN1_SEQUENCE in an ASN1_STRING */ +IMPLEMENT_ASN1_TYPE(ASN1_SEQUENCE) + +IMPLEMENT_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) + +/* Multistring types */ + +IMPLEMENT_ASN1_MSTRING(ASN1_PRINTABLE, B_ASN1_PRINTABLE) +IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, ASN1_PRINTABLE) + +IMPLEMENT_ASN1_MSTRING(DISPLAYTEXT, B_ASN1_DISPLAYTEXT) +IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DISPLAYTEXT) + +IMPLEMENT_ASN1_MSTRING(DIRECTORYSTRING, B_ASN1_DIRECTORYSTRING) +IMPLEMENT_ASN1_FUNCTIONS_name(ASN1_STRING, DIRECTORYSTRING) + +/* Three separate BOOLEAN type: normal, DEFAULT TRUE and DEFAULT FALSE */ +IMPLEMENT_ASN1_TYPE_ex(ASN1_BOOLEAN, ASN1_BOOLEAN, -1) +IMPLEMENT_ASN1_TYPE_ex(ASN1_TBOOLEAN, ASN1_BOOLEAN, 1) +IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0) + +/* Special, OCTET STRING with indefinite length constructed support */ + +IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF) + +ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY) +ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY) + +ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY) +ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SET_ANY, ASN1_SET_ANY) diff --git a/libs/openssl/crypto/asn1/tasn_utl.c b/libs/openssl/crypto/asn1/tasn_utl.c new file mode 100644 index 00000000..41726d8f --- /dev/null +++ b/libs/openssl/crypto/asn1/tasn_utl.c @@ -0,0 +1,275 @@ +/* tasn_utl.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include + +/* Utility functions for manipulating fields and offsets */ + +/* Add 'offset' to 'addr' */ +#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset) + +/* + * Given an ASN1_ITEM CHOICE type return the selector value + */ + +int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + int *sel = offset2ptr(*pval, it->utype); + return *sel; +} + +/* + * Given an ASN1_ITEM CHOICE type set the selector value, return old value. + */ + +int asn1_set_choice_selector(ASN1_VALUE **pval, int value, + const ASN1_ITEM *it) +{ + int *sel, ret; + sel = offset2ptr(*pval, it->utype); + ret = *sel; + *sel = value; + return ret; +} + +/* + * Do reference counting. The value 'op' decides what to do. if it is +1 + * then the count is incremented. If op is 0 count is set to 1. If op is -1 + * count is decremented and the return value is the current refrence count or + * 0 if no reference count exists. + */ + +int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) +{ + const ASN1_AUX *aux; + int *lck, ret; + if ((it->itype != ASN1_ITYPE_SEQUENCE) + && (it->itype != ASN1_ITYPE_NDEF_SEQUENCE)) + return 0; + aux = it->funcs; + if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) + return 0; + lck = offset2ptr(*pval, aux->ref_offset); + if (op == 0) { + *lck = 1; + return 1; + } + ret = CRYPTO_add(lck, op, aux->ref_lock); +#ifdef REF_PRINT + fprintf(stderr, "%s: Reference Count: %d\n", it->sname, *lck); +#endif +#ifdef REF_CHECK + if (ret < 0) + fprintf(stderr, "%s, bad reference count\n", it->sname); +#endif + return ret; +} + +static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + const ASN1_AUX *aux; + if (!pval || !*pval) + return NULL; + aux = it->funcs; + if (!aux || !(aux->flags & ASN1_AFLG_ENCODING)) + return NULL; + return offset2ptr(*pval, aux->enc_offset); +} + +void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + ASN1_ENCODING *enc; + enc = asn1_get_enc_ptr(pval, it); + if (enc) { + enc->enc = NULL; + enc->len = 0; + enc->modified = 1; + } +} + +void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + ASN1_ENCODING *enc; + enc = asn1_get_enc_ptr(pval, it); + if (enc) { + if (enc->enc) + OPENSSL_free(enc->enc); + enc->enc = NULL; + enc->len = 0; + enc->modified = 1; + } +} + +int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, + const ASN1_ITEM *it) +{ + ASN1_ENCODING *enc; + enc = asn1_get_enc_ptr(pval, it); + if (!enc) + return 1; + + if (enc->enc) + OPENSSL_free(enc->enc); + enc->enc = OPENSSL_malloc(inlen); + if (!enc->enc) + return 0; + memcpy(enc->enc, in, inlen); + enc->len = inlen; + enc->modified = 0; + + return 1; +} + +int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, + const ASN1_ITEM *it) +{ + ASN1_ENCODING *enc; + enc = asn1_get_enc_ptr(pval, it); + if (!enc || enc->modified) + return 0; + if (out) { + memcpy(*out, enc->enc, enc->len); + *out += enc->len; + } + if (len) + *len = enc->len; + return 1; +} + +/* Given an ASN1_TEMPLATE get a pointer to a field */ +ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) +{ + ASN1_VALUE **pvaltmp; + if (tt->flags & ASN1_TFLG_COMBINE) + return pval; + pvaltmp = offset2ptr(*pval, tt->offset); + /* + * NOTE for BOOLEAN types the field is just a plain int so we can't + * return int **, so settle for (int *). + */ + return pvaltmp; +} + +/* + * Handle ANY DEFINED BY template, find the selector, look up the relevant + * ASN1_TEMPLATE in the table and return it. + */ + +const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, + int nullerr) +{ + const ASN1_ADB *adb; + const ASN1_ADB_TABLE *atbl; + long selector; + ASN1_VALUE **sfld; + int i; + if (!(tt->flags & ASN1_TFLG_ADB_MASK)) + return tt; + + /* Else ANY DEFINED BY ... get the table */ + adb = ASN1_ADB_ptr(tt->item); + + /* Get the selector field */ + sfld = offset2ptr(*pval, adb->offset); + + /* Check if NULL */ + if (!sfld) { + if (!adb->null_tt) + goto err; + return adb->null_tt; + } + + /* + * Convert type to a long: NB: don't check for NID_undef here because it + * might be a legitimate value in the table + */ + if (tt->flags & ASN1_TFLG_ADB_OID) + selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld); + else + selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld); + + /* + * Try to find matching entry in table Maybe should check application + * types first to allow application override? Might also be useful to + * have a flag which indicates table is sorted and we can do a binary + * search. For now stick to a linear search. + */ + + for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++) + if (atbl->value == selector) + return &atbl->tt; + + /* FIXME: need to search application table too */ + + /* No match, return default type */ + if (!adb->default_tt) + goto err; + return adb->default_tt; + + err: + /* FIXME: should log the value or OID of unsupported type */ + if (nullerr) + ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); + return NULL; +} diff --git a/libs/openssl/crypto/asn1/x_algor.c b/libs/openssl/crypto/asn1/x_algor.c new file mode 100644 index 00000000..fd7d16d4 --- /dev/null +++ b/libs/openssl/crypto/asn1/x_algor.c @@ -0,0 +1,148 @@ +/* x_algor.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include + +ASN1_SEQUENCE(X509_ALGOR) = { + ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT), + ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY) +} ASN1_SEQUENCE_END(X509_ALGOR) + +ASN1_ITEM_TEMPLATE(X509_ALGORS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR) +ASN1_ITEM_TEMPLATE_END(X509_ALGORS) + +IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_ALGORS, X509_ALGORS, X509_ALGORS) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_ALGOR) + +IMPLEMENT_STACK_OF(X509_ALGOR) +IMPLEMENT_ASN1_SET_OF(X509_ALGOR) + +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval) +{ + if (!alg) + return 0; + if (ptype != V_ASN1_UNDEF) { + if (alg->parameter == NULL) + alg->parameter = ASN1_TYPE_new(); + if (alg->parameter == NULL) + return 0; + } + if (alg) { + if (alg->algorithm) + ASN1_OBJECT_free(alg->algorithm); + alg->algorithm = aobj; + } + if (ptype == 0) + return 1; + if (ptype == V_ASN1_UNDEF) { + if (alg->parameter) { + ASN1_TYPE_free(alg->parameter); + alg->parameter = NULL; + } + } else + ASN1_TYPE_set(alg->parameter, ptype, pval); + return 1; +} + +void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval, + X509_ALGOR *algor) +{ + if (paobj) + *paobj = algor->algorithm; + if (pptype) { + if (algor->parameter == NULL) { + *pptype = V_ASN1_UNDEF; + return; + } else + *pptype = algor->parameter->type; + if (ppval) + *ppval = algor->parameter->value.ptr; + } +} + +/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ + +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md) +{ + int param_type; + + if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT) + param_type = V_ASN1_UNDEF; + else + param_type = V_ASN1_NULL; + + X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); + +} + +int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b) +{ + int rv; + rv = OBJ_cmp(a->algorithm, b->algorithm); + if (rv) + return rv; + if (!a->parameter && !b->parameter) + return 0; + return ASN1_TYPE_cmp(a->parameter, b->parameter); +} diff --git a/libs/openssl/crypto/asn1/x_attrib.c b/libs/openssl/crypto/asn1/x_attrib.c new file mode 100644 index 00000000..93ef53bd --- /dev/null +++ b/libs/openssl/crypto/asn1/x_attrib.c @@ -0,0 +1,124 @@ +/* crypto/asn1/x_attrib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +/*- + * X509_ATTRIBUTE: this has the following form: + * + * typedef struct x509_attributes_st + * { + * ASN1_OBJECT *object; + * int single; + * union { + * char *ptr; + * STACK_OF(ASN1_TYPE) *set; + * ASN1_TYPE *single; + * } value; + * } X509_ATTRIBUTE; + * + * this needs some extra thought because the CHOICE type is + * merged with the main structure and because the value can + * be anything at all we *must* try the SET OF first because + * the ASN1_ANY type will swallow anything including the whole + * SET OF structure. + */ + +ASN1_CHOICE(X509_ATTRIBUTE_SET) = { + ASN1_SET_OF(X509_ATTRIBUTE, value.set, ASN1_ANY), + ASN1_SIMPLE(X509_ATTRIBUTE, value.single, ASN1_ANY) +} ASN1_CHOICE_END_selector(X509_ATTRIBUTE, X509_ATTRIBUTE_SET, single) + +ASN1_SEQUENCE(X509_ATTRIBUTE) = { + ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT), + /* CHOICE type merged with parent */ + ASN1_EX_COMBINE(0, 0, X509_ATTRIBUTE_SET) +} ASN1_SEQUENCE_END(X509_ATTRIBUTE) + +IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE) + +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value) +{ + X509_ATTRIBUTE *ret = NULL; + ASN1_TYPE *val = NULL; + + if ((ret = X509_ATTRIBUTE_new()) == NULL) + return (NULL); + ret->object = OBJ_nid2obj(nid); + ret->single = 0; + if ((ret->value.set = sk_ASN1_TYPE_new_null()) == NULL) + goto err; + if ((val = ASN1_TYPE_new()) == NULL) + goto err; + if (!sk_ASN1_TYPE_push(ret->value.set, val)) + goto err; + + ASN1_TYPE_set(val, atrtype, value); + return (ret); + err: + if (ret != NULL) + X509_ATTRIBUTE_free(ret); + if (val != NULL) + ASN1_TYPE_free(val); + return (NULL); +} diff --git a/libs/openssl/crypto/asn1/x_bignum.c b/libs/openssl/crypto/asn1/x_bignum.c new file mode 100644 index 00000000..eaf04663 --- /dev/null +++ b/libs/openssl/crypto/asn1/x_bignum.c @@ -0,0 +1,153 @@ +/* x_bignum.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include + +/* + * Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER + * as a BIGNUM directly. Currently it ignores the sign which isn't a problem + * since all BIGNUMs used are non negative and anything that looks negative + * is normally due to an encoding error. + */ + +#define BN_SENSITIVE 1 + +static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, + const ASN1_ITEM *it); +static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it); + +static ASN1_PRIMITIVE_FUNCS bignum_pf = { + NULL, 0, + bn_new, + bn_free, + 0, + bn_c2i, + bn_i2c +}; + +ASN1_ITEM_start(BIGNUM) + ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM" +ASN1_ITEM_end(BIGNUM) + +ASN1_ITEM_start(CBIGNUM) + ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM" +ASN1_ITEM_end(CBIGNUM) + +static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + *pval = (ASN1_VALUE *)BN_new(); + if (*pval) + return 1; + else + return 0; +} + +static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + if (!*pval) + return; + if (it->size & BN_SENSITIVE) + BN_clear_free((BIGNUM *)*pval); + else + BN_free((BIGNUM *)*pval); + *pval = NULL; +} + +static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, + const ASN1_ITEM *it) +{ + BIGNUM *bn; + int pad; + if (!*pval) + return -1; + bn = (BIGNUM *)*pval; + /* If MSB set in an octet we need a padding byte */ + if (BN_num_bits(bn) & 0x7) + pad = 0; + else + pad = 1; + if (cont) { + if (pad) + *cont++ = 0; + BN_bn2bin(bn, cont); + } + return pad + BN_num_bytes(bn); +} + +static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it) +{ + BIGNUM *bn; + + if (*pval == NULL && !bn_new(pval, it)) + return 0; + bn = (BIGNUM *)*pval; + if (!BN_bin2bn(cont, len, bn)) { + bn_free(pval, it); + return 0; + } + return 1; +} diff --git a/libs/openssl/crypto/asn1/x_crl.c b/libs/openssl/crypto/asn1/x_crl.c new file mode 100644 index 00000000..e258c714 --- /dev/null +++ b/libs/openssl/crypto/asn1/x_crl.c @@ -0,0 +1,515 @@ +/* crypto/asn1/x_crl.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "asn1_locl.h" +#include +#include +#include + +static int X509_REVOKED_cmp(const X509_REVOKED *const *a, + const X509_REVOKED *const *b); +static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp); + +ASN1_SEQUENCE(X509_REVOKED) = { + ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER), + ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME), + ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION) +} ASN1_SEQUENCE_END(X509_REVOKED) + +static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r); +static int def_crl_lookup(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial, + X509_NAME *issuer); + +static X509_CRL_METHOD int_crl_meth = { + 0, + 0, 0, + def_crl_lookup, + def_crl_verify +}; + +static const X509_CRL_METHOD *default_crl_method = &int_crl_meth; + +/* + * The X509_CRL_INFO structure needs a bit of customisation. Since we cache + * the original encoding the signature wont be affected by reordering of the + * revoked field. + */ +static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + X509_CRL_INFO *a = (X509_CRL_INFO *)*pval; + + if (!a || !a->revoked) + return 1; + switch (operation) { + /* + * Just set cmp function here. We don't sort because that would + * affect the output of X509_CRL_print(). + */ + case ASN1_OP_D2I_POST: + (void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp); + break; + } + return 1; +} + + +ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = { + ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME), + ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME), + ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME), + ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED), + ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0) +} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO) + +/* + * Set CRL entry issuer according to CRL certificate issuer extension. Check + * for unhandled critical CRL entry extensions. + */ + +static int crl_set_issuers(X509_CRL *crl) +{ + + int i, j; + GENERAL_NAMES *gens, *gtmp; + STACK_OF(X509_REVOKED) *revoked; + + revoked = X509_CRL_get_REVOKED(crl); + + gens = NULL; + for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) { + X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i); + STACK_OF(X509_EXTENSION) *exts; + ASN1_ENUMERATED *reason; + X509_EXTENSION *ext; + gtmp = X509_REVOKED_get_ext_d2i(rev, + NID_certificate_issuer, &j, NULL); + if (!gtmp && (j != -1)) { + crl->flags |= EXFLAG_INVALID; + return 1; + } + + if (gtmp) { + gens = gtmp; + if (!crl->issuers) { + crl->issuers = sk_GENERAL_NAMES_new_null(); + if (!crl->issuers) + return 0; + } + if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp)) + return 0; + } + rev->issuer = gens; + + reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL); + if (!reason && (j != -1)) { + crl->flags |= EXFLAG_INVALID; + return 1; + } + + if (reason) { + rev->reason = ASN1_ENUMERATED_get(reason); + ASN1_ENUMERATED_free(reason); + } else + rev->reason = CRL_REASON_NONE; + + /* Check for critical CRL entry extensions */ + + exts = rev->extensions; + + for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) { + ext = sk_X509_EXTENSION_value(exts, j); + if (ext->critical > 0) { + if (OBJ_obj2nid(ext->object) == NID_certificate_issuer) + continue; + crl->flags |= EXFLAG_CRITICAL; + break; + } + } + + } + + return 1; + +} + +/* + * The X509_CRL structure needs a bit of customisation. Cache some extensions + * and hash of the whole CRL. + */ +static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + X509_CRL *crl = (X509_CRL *)*pval; + STACK_OF(X509_EXTENSION) *exts; + X509_EXTENSION *ext; + int idx; + + switch (operation) { + case ASN1_OP_NEW_POST: + crl->idp = NULL; + crl->akid = NULL; + crl->flags = 0; + crl->idp_flags = 0; + crl->idp_reasons = CRLDP_ALL_REASONS; + crl->meth = default_crl_method; + crl->meth_data = NULL; + crl->issuers = NULL; + crl->crl_number = NULL; + crl->base_crl_number = NULL; + break; + + case ASN1_OP_D2I_POST: +#ifndef OPENSSL_NO_SHA + X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL); +#endif + crl->idp = X509_CRL_get_ext_d2i(crl, + NID_issuing_distribution_point, NULL, + NULL); + if (crl->idp) + setup_idp(crl, crl->idp); + + crl->akid = X509_CRL_get_ext_d2i(crl, + NID_authority_key_identifier, NULL, + NULL); + + crl->crl_number = X509_CRL_get_ext_d2i(crl, + NID_crl_number, NULL, NULL); + + crl->base_crl_number = X509_CRL_get_ext_d2i(crl, + NID_delta_crl, NULL, + NULL); + /* Delta CRLs must have CRL number */ + if (crl->base_crl_number && !crl->crl_number) + crl->flags |= EXFLAG_INVALID; + + /* + * See if we have any unhandled critical CRL extensions and indicate + * this in a flag. We only currently handle IDP so anything else + * critical sets the flag. This code accesses the X509_CRL structure + * directly: applications shouldn't do this. + */ + + exts = crl->crl->extensions; + + for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) { + int nid; + ext = sk_X509_EXTENSION_value(exts, idx); + nid = OBJ_obj2nid(ext->object); + if (nid == NID_freshest_crl) + crl->flags |= EXFLAG_FRESHEST; + if (ext->critical > 0) { + /* We handle IDP and deltas */ + if ((nid == NID_issuing_distribution_point) + || (nid == NID_authority_key_identifier) + || (nid == NID_delta_crl)) + break;; + crl->flags |= EXFLAG_CRITICAL; + break; + } + } + + if (!crl_set_issuers(crl)) + return 0; + + if (crl->meth->crl_init) { + if (crl->meth->crl_init(crl) == 0) + return 0; + } + break; + + case ASN1_OP_FREE_POST: + if (crl->meth->crl_free) { + if (!crl->meth->crl_free(crl)) + return 0; + } + if (crl->akid) + AUTHORITY_KEYID_free(crl->akid); + if (crl->idp) + ISSUING_DIST_POINT_free(crl->idp); + ASN1_INTEGER_free(crl->crl_number); + ASN1_INTEGER_free(crl->base_crl_number); + sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free); + break; + } + return 1; +} + +/* Convert IDP into a more convenient form */ + +static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp) +{ + int idp_only = 0; + /* Set various flags according to IDP */ + crl->idp_flags |= IDP_PRESENT; + if (idp->onlyuser > 0) { + idp_only++; + crl->idp_flags |= IDP_ONLYUSER; + } + if (idp->onlyCA > 0) { + idp_only++; + crl->idp_flags |= IDP_ONLYCA; + } + if (idp->onlyattr > 0) { + idp_only++; + crl->idp_flags |= IDP_ONLYATTR; + } + + if (idp_only > 1) + crl->idp_flags |= IDP_INVALID; + + if (idp->indirectCRL > 0) + crl->idp_flags |= IDP_INDIRECT; + + if (idp->onlysomereasons) { + crl->idp_flags |= IDP_REASONS; + if (idp->onlysomereasons->length > 0) + crl->idp_reasons = idp->onlysomereasons->data[0]; + if (idp->onlysomereasons->length > 1) + crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8); + crl->idp_reasons &= CRLDP_ALL_REASONS; + } + + DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl)); +} + +ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = { + ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO), + ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL) + +IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED) + +IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(X509_CRL) + +IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL) + +static int X509_REVOKED_cmp(const X509_REVOKED *const *a, + const X509_REVOKED *const *b) +{ + return (ASN1_STRING_cmp((ASN1_STRING *)(*a)->serialNumber, + (ASN1_STRING *)(*b)->serialNumber)); +} + +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev) +{ + X509_CRL_INFO *inf; + inf = crl->crl; + if (!inf->revoked) + inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp); + if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) { + ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE); + return 0; + } + inf->enc.modified = 1; + return 1; +} + +int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r) +{ + if (crl->meth->crl_verify) + return crl->meth->crl_verify(crl, r); + return 0; +} + +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial) +{ + if (crl->meth->crl_lookup) + return crl->meth->crl_lookup(crl, ret, serial, NULL); + return 0; +} + +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x) +{ + if (crl->meth->crl_lookup) + return crl->meth->crl_lookup(crl, ret, + X509_get_serialNumber(x), + X509_get_issuer_name(x)); + return 0; +} + +static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r) +{ + return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO), + crl->sig_alg, crl->signature, crl->crl, r)); +} + +static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm, + X509_REVOKED *rev) +{ + int i; + + if (!rev->issuer) { + if (!nm) + return 1; + if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl))) + return 1; + return 0; + } + + if (!nm) + nm = X509_CRL_get_issuer(crl); + + for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i); + if (gen->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(nm, gen->d.directoryName)) + return 1; + } + return 0; + +} + +static int def_crl_lookup(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial, + X509_NAME *issuer) +{ + X509_REVOKED rtmp, *rev; + int idx; + rtmp.serialNumber = serial; + /* + * Sort revoked into serial number order if not already sorted. Do this + * under a lock to avoid race condition. + */ + if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) { + CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL); + sk_X509_REVOKED_sort(crl->crl->revoked); + CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL); + } + idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp); + if (idx < 0) + return 0; + /* Need to look for matching name */ + for (; idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) { + rev = sk_X509_REVOKED_value(crl->crl->revoked, idx); + if (ASN1_INTEGER_cmp(rev->serialNumber, serial)) + return 0; + if (crl_revoked_issuer_match(crl, issuer, rev)) { + if (ret) + *ret = rev; + if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) + return 2; + return 1; + } + } + return 0; +} + +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth) +{ + if (meth == NULL) + default_crl_method = &int_crl_meth; + else + default_crl_method = meth; +} + +X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), + int (*crl_free) (X509_CRL *crl), + int (*crl_lookup) (X509_CRL *crl, + X509_REVOKED **ret, + ASN1_INTEGER *ser, + X509_NAME *issuer), + int (*crl_verify) (X509_CRL *crl, + EVP_PKEY *pk)) +{ + X509_CRL_METHOD *m; + m = OPENSSL_malloc(sizeof(X509_CRL_METHOD)); + if (!m) + return NULL; + m->crl_init = crl_init; + m->crl_free = crl_free; + m->crl_lookup = crl_lookup; + m->crl_verify = crl_verify; + m->flags = X509_CRL_METHOD_DYNAMIC; + return m; +} + +void X509_CRL_METHOD_free(X509_CRL_METHOD *m) +{ + if (!(m->flags & X509_CRL_METHOD_DYNAMIC)) + return; + OPENSSL_free(m); +} + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat) +{ + crl->meth_data = dat; +} + +void *X509_CRL_get_meth_data(X509_CRL *crl) +{ + return crl->meth_data; +} + +IMPLEMENT_STACK_OF(X509_REVOKED) + +IMPLEMENT_ASN1_SET_OF(X509_REVOKED) + +IMPLEMENT_STACK_OF(X509_CRL) + +IMPLEMENT_ASN1_SET_OF(X509_CRL) diff --git a/libs/openssl/crypto/asn1/x_exten.c b/libs/openssl/crypto/asn1/x_exten.c new file mode 100644 index 00000000..00a9580a --- /dev/null +++ b/libs/openssl/crypto/asn1/x_exten.c @@ -0,0 +1,77 @@ +/* x_exten.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include + +ASN1_SEQUENCE(X509_EXTENSION) = { + ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT), + ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN), + ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(X509_EXTENSION) + +ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION) +ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS) + +IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION) +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_EXTENSION) diff --git a/libs/openssl/crypto/asn1/x_info.c b/libs/openssl/crypto/asn1/x_info.c new file mode 100644 index 00000000..067fd72a --- /dev/null +++ b/libs/openssl/crypto/asn1/x_info.c @@ -0,0 +1,117 @@ +/* crypto/asn1/x_info.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +X509_INFO *X509_INFO_new(void) +{ + X509_INFO *ret = NULL; + + ret = (X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO)); + if (ret == NULL) { + ASN1err(ASN1_F_X509_INFO_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + ret->enc_cipher.cipher = NULL; + ret->enc_len = 0; + ret->enc_data = NULL; + + ret->references = 1; + ret->x509 = NULL; + ret->crl = NULL; + ret->x_pkey = NULL; + return (ret); +} + +void X509_INFO_free(X509_INFO *x) +{ + int i; + + if (x == NULL) + return; + + i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_X509_INFO); +#ifdef REF_PRINT + REF_PRINT("X509_INFO", x); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "X509_INFO_free, bad reference count\n"); + abort(); + } +#endif + + if (x->x509 != NULL) + X509_free(x->x509); + if (x->crl != NULL) + X509_CRL_free(x->crl); + if (x->x_pkey != NULL) + X509_PKEY_free(x->x_pkey); + if (x->enc_data != NULL) + OPENSSL_free(x->enc_data); + OPENSSL_free(x); +} + +IMPLEMENT_STACK_OF(X509_INFO) diff --git a/libs/openssl/crypto/asn1/x_long.c b/libs/openssl/crypto/asn1/x_long.c new file mode 100644 index 00000000..3aed44a3 --- /dev/null +++ b/libs/openssl/crypto/asn1/x_long.c @@ -0,0 +1,196 @@ +/* x_long.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include + +/* + * Custom primitive type for long handling. This converts between an + * ASN1_INTEGER and a long directly. + */ + +static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it); +static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it); + +static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, + const ASN1_ITEM *it); +static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it); +static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, + int indent, const ASN1_PCTX *pctx); + +static ASN1_PRIMITIVE_FUNCS long_pf = { + NULL, 0, + long_new, + long_free, + long_free, /* Clear should set to initial value */ + long_c2i, + long_i2c, + long_print +}; + +ASN1_ITEM_start(LONG) + ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG" +ASN1_ITEM_end(LONG) + +ASN1_ITEM_start(ZLONG) + ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG" +ASN1_ITEM_end(ZLONG) + +static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + *(long *)pval = it->size; + return 1; +} + +static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + *(long *)pval = it->size; +} + +static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, + const ASN1_ITEM *it) +{ + long ltmp; + unsigned long utmp; + int clen, pad, i; + /* this exists to bypass broken gcc optimization */ + char *cp = (char *)pval; + + /* use memcpy, because we may not be long aligned */ + memcpy(<mp, cp, sizeof(long)); + + if (ltmp == it->size) + return -1; + /* + * Convert the long to positive: we subtract one if negative so we can + * cleanly handle the padding if only the MSB of the leading octet is + * set. + */ + if (ltmp < 0) + utmp = -ltmp - 1; + else + utmp = ltmp; + clen = BN_num_bits_word(utmp); + /* If MSB of leading octet set we need to pad */ + if (!(clen & 0x7)) + pad = 1; + else + pad = 0; + + /* Convert number of bits to number of octets */ + clen = (clen + 7) >> 3; + + if (cont) { + if (pad) + *cont++ = (ltmp < 0) ? 0xff : 0; + for (i = clen - 1; i >= 0; i--) { + cont[i] = (unsigned char)(utmp & 0xff); + if (ltmp < 0) + cont[i] ^= 0xff; + utmp >>= 8; + } + } + return clen + pad; +} + +static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, + int utype, char *free_cont, const ASN1_ITEM *it) +{ + int neg, i; + long ltmp; + unsigned long utmp = 0; + char *cp = (char *)pval; + if (len > (int)sizeof(long)) { + ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); + return 0; + } + /* Is it negative? */ + if (len && (cont[0] & 0x80)) + neg = 1; + else + neg = 0; + utmp = 0; + for (i = 0; i < len; i++) { + utmp <<= 8; + if (neg) + utmp |= cont[i] ^ 0xff; + else + utmp |= cont[i]; + } + ltmp = (long)utmp; + if (neg) { + ltmp++; + ltmp = -ltmp; + } + if (ltmp == it->size) { + ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG); + return 0; + } + memcpy(cp, <mp, sizeof(long)); + return 1; +} + +static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, + int indent, const ASN1_PCTX *pctx) +{ + return BIO_printf(out, "%ld\n", *(long *)pval); +} diff --git a/libs/openssl/crypto/asn1/x_name.c b/libs/openssl/crypto/asn1/x_name.c new file mode 100644 index 00000000..a858c299 --- /dev/null +++ b/libs/openssl/crypto/asn1/x_name.c @@ -0,0 +1,538 @@ +/* crypto/asn1/x_name.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include "asn1_locl.h" + +typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY; +DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY) + +/* + * Maximum length of X509_NAME: much larger than anything we should + * ever see in practice. + */ + +#define X509_NAME_MAX (1024 * 1024) + +static int x509_name_ex_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_ITEM *it, + int tag, int aclass, char opt, ASN1_TLC *ctx); + +static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass); +static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it); +static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it); + +static int x509_name_encode(X509_NAME *a); +static int x509_name_canon(X509_NAME *a); +static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in); +static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname, + unsigned char **in); + +static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, + int indent, + const char *fname, const ASN1_PCTX *pctx); + +ASN1_SEQUENCE(X509_NAME_ENTRY) = { + ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT), + ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE) +} ASN1_SEQUENCE_END(X509_NAME_ENTRY) + +IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY) +IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY) + +/* + * For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so + * declare two template wrappers for this + */ + +ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY) +ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES) + +ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES) +ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL) + +/* + * Normally that's where it would end: we'd have two nested STACK structures + * representing the ASN1. Unfortunately X509_NAME uses a completely different + * form and caches encodings so we have to process the internal form and + * convert to the external form. + */ + +const ASN1_EXTERN_FUNCS x509_name_ff = { + NULL, + x509_name_ex_new, + x509_name_ex_free, + 0, /* Default clear behaviour is OK */ + x509_name_ex_d2i, + x509_name_ex_i2d, + x509_name_ex_print +}; + +IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff) + +IMPLEMENT_ASN1_FUNCTIONS(X509_NAME) + +IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME) + +static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it) +{ + X509_NAME *ret = NULL; + ret = OPENSSL_malloc(sizeof(X509_NAME)); + if (!ret) + goto memerr; + if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL) + goto memerr; + if ((ret->bytes = BUF_MEM_new()) == NULL) + goto memerr; + ret->canon_enc = NULL; + ret->canon_enclen = 0; + ret->modified = 1; + *val = (ASN1_VALUE *)ret; + return 1; + + memerr: + ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE); + if (ret) { + if (ret->entries) + sk_X509_NAME_ENTRY_free(ret->entries); + OPENSSL_free(ret); + } + return 0; +} + +static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +{ + X509_NAME *a; + if (!pval || !*pval) + return; + a = (X509_NAME *)*pval; + + BUF_MEM_free(a->bytes); + sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free); + if (a->canon_enc) + OPENSSL_free(a->canon_enc); + OPENSSL_free(a); + *pval = NULL; +} + +static int x509_name_ex_d2i(ASN1_VALUE **val, + const unsigned char **in, long len, + const ASN1_ITEM *it, int tag, int aclass, + char opt, ASN1_TLC *ctx) +{ + const unsigned char *p = *in, *q; + union { + STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; + ASN1_VALUE *a; + } intname = { + NULL + }; + union { + X509_NAME *x; + ASN1_VALUE *a; + } nm = { + NULL + }; + int i, j, ret; + STACK_OF(X509_NAME_ENTRY) *entries; + X509_NAME_ENTRY *entry; + if (len > X509_NAME_MAX) { + ASN1err(ASN1_F_X509_NAME_EX_D2I, ASN1_R_TOO_LONG); + return 0; + } + q = p; + + /* Get internal representation of Name */ + ret = ASN1_item_ex_d2i(&intname.a, + &p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL), + tag, aclass, opt, ctx); + + if (ret <= 0) + return ret; + + if (*val) + x509_name_ex_free(val, NULL); + if (!x509_name_ex_new(&nm.a, NULL)) + goto err; + /* We've decoded it: now cache encoding */ + if (!BUF_MEM_grow(nm.x->bytes, p - q)) + goto err; + memcpy(nm.x->bytes->data, q, p - q); + + /* Convert internal representation to X509_NAME structure */ + for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) { + entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i); + for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) { + entry = sk_X509_NAME_ENTRY_value(entries, j); + entry->set = i; + if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry)) + goto err; + } + sk_X509_NAME_ENTRY_free(entries); + } + sk_STACK_OF_X509_NAME_ENTRY_free(intname.s); + ret = x509_name_canon(nm.x); + if (!ret) + goto err; + nm.x->modified = 0; + *val = nm.a; + *in = p; + return ret; + err: + if (nm.x != NULL) + X509_NAME_free(nm.x); + ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR); + return 0; +} + +static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, + const ASN1_ITEM *it, int tag, int aclass) +{ + int ret; + X509_NAME *a = (X509_NAME *)*val; + if (a->modified) { + ret = x509_name_encode(a); + if (ret < 0) + return ret; + ret = x509_name_canon(a); + if (ret < 0) + return ret; + } + ret = a->bytes->length; + if (out != NULL) { + memcpy(*out, a->bytes->data, ret); + *out += ret; + } + return ret; +} + +static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne) +{ + sk_X509_NAME_ENTRY_free(ne); +} + +static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne) +{ + sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free); +} + +static int x509_name_encode(X509_NAME *a) +{ + union { + STACK_OF(STACK_OF_X509_NAME_ENTRY) *s; + ASN1_VALUE *a; + } intname = { + NULL + }; + int len; + unsigned char *p; + STACK_OF(X509_NAME_ENTRY) *entries = NULL; + X509_NAME_ENTRY *entry; + int i, set = -1; + intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null(); + if (!intname.s) + goto memerr; + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + entry = sk_X509_NAME_ENTRY_value(a->entries, i); + if (entry->set != set) { + entries = sk_X509_NAME_ENTRY_new_null(); + if (!entries) + goto memerr; + if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) + goto memerr; + set = entry->set; + } + if (!sk_X509_NAME_ENTRY_push(entries, entry)) + goto memerr; + } + len = ASN1_item_ex_i2d(&intname.a, NULL, + ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); + if (!BUF_MEM_grow(a->bytes, len)) + goto memerr; + p = (unsigned char *)a->bytes->data; + ASN1_item_ex_i2d(&intname.a, + &p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1); + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, + local_sk_X509_NAME_ENTRY_free); + a->modified = 0; + return len; + memerr: + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, + local_sk_X509_NAME_ENTRY_free); + ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE); + return -1; +} + +static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval, + int indent, + const char *fname, const ASN1_PCTX *pctx) +{ + if (X509_NAME_print_ex(out, (X509_NAME *)*pval, + indent, pctx->nm_flags) <= 0) + return 0; + return 2; +} + +/* + * This function generates the canonical encoding of the Name structure. In + * it all strings are converted to UTF8, leading, trailing and multiple + * spaces collapsed, converted to lower case and the leading SEQUENCE header + * removed. In future we could also normalize the UTF8 too. By doing this + * comparison of Name structures can be rapidly perfomed by just using + * memcmp() of the canonical encoding. By omitting the leading SEQUENCE name + * constraints of type dirName can also be checked with a simple memcmp(). + */ + +static int x509_name_canon(X509_NAME *a) +{ + unsigned char *p; + STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL; + STACK_OF(X509_NAME_ENTRY) *entries = NULL; + X509_NAME_ENTRY *entry, *tmpentry = NULL; + int i, set = -1, ret = 0; + + if (a->canon_enc) { + OPENSSL_free(a->canon_enc); + a->canon_enc = NULL; + } + /* Special case: empty X509_NAME => null encoding */ + if (sk_X509_NAME_ENTRY_num(a->entries) == 0) { + a->canon_enclen = 0; + return 1; + } + intname = sk_STACK_OF_X509_NAME_ENTRY_new_null(); + if (!intname) + goto err; + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + entry = sk_X509_NAME_ENTRY_value(a->entries, i); + if (entry->set != set) { + entries = sk_X509_NAME_ENTRY_new_null(); + if (!entries) + goto err; + if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) + goto err; + set = entry->set; + } + tmpentry = X509_NAME_ENTRY_new(); + if (!tmpentry) + goto err; + tmpentry->object = OBJ_dup(entry->object); + if (!asn1_string_canon(tmpentry->value, entry->value)) + goto err; + if (!sk_X509_NAME_ENTRY_push(entries, tmpentry)) + goto err; + tmpentry = NULL; + } + + /* Finally generate encoding */ + + a->canon_enclen = i2d_name_canon(intname, NULL); + + p = OPENSSL_malloc(a->canon_enclen); + + if (!p) + goto err; + + a->canon_enc = p; + + i2d_name_canon(intname, &p); + + ret = 1; + + err: + + if (tmpentry) + X509_NAME_ENTRY_free(tmpentry); + if (intname) + sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname, + local_sk_X509_NAME_ENTRY_pop_free); + return ret; +} + +/* Bitmap of all the types of string that will be canonicalized. */ + +#define ASN1_MASK_CANON \ + (B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \ + | B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \ + | B_ASN1_VISIBLESTRING) + +static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in) +{ + unsigned char *to, *from; + int len, i; + + /* If type not in bitmask just copy string across */ + if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) { + if (!ASN1_STRING_copy(out, in)) + return 0; + return 1; + } + + out->type = V_ASN1_UTF8STRING; + out->length = ASN1_STRING_to_UTF8(&out->data, in); + if (out->length == -1) + return 0; + + to = out->data; + from = to; + + len = out->length; + + /* + * Convert string in place to canonical form. Ultimately we may need to + * handle a wider range of characters but for now ignore anything with + * MSB set and rely on the isspace() and tolower() functions. + */ + + /* Ignore leading spaces */ + while ((len > 0) && !(*from & 0x80) && isspace(*from)) { + from++; + len--; + } + + to = from + len - 1; + + /* Ignore trailing spaces */ + while ((len > 0) && !(*to & 0x80) && isspace(*to)) { + to--; + len--; + } + + to = out->data; + + i = 0; + while (i < len) { + /* If MSB set just copy across */ + if (*from & 0x80) { + *to++ = *from++; + i++; + } + /* Collapse multiple spaces */ + else if (isspace(*from)) { + /* Copy one space across */ + *to++ = ' '; + /* + * Ignore subsequent spaces. Note: don't need to check len here + * because we know the last character is a non-space so we can't + * overflow. + */ + do { + from++; + i++; + } + while (!(*from & 0x80) && isspace(*from)); + } else { + *to++ = tolower(*from); + from++; + i++; + } + } + + out->length = to - out->data; + + return 1; + +} + +static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname, + unsigned char **in) +{ + int i, len, ltmp; + ASN1_VALUE *v; + STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname; + + len = 0; + for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) { + v = sk_ASN1_VALUE_value(intname, i); + ltmp = ASN1_item_ex_i2d(&v, in, + ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1); + if (ltmp < 0) + return ltmp; + len += ltmp; + } + return len; +} + +int X509_NAME_set(X509_NAME **xn, X509_NAME *name) +{ + X509_NAME *in; + + if (!xn || !name) + return (0); + + if (*xn != name) { + in = X509_NAME_dup(name); + if (in != NULL) { + X509_NAME_free(*xn); + *xn = in; + } + } + return (*xn != NULL); +} + +IMPLEMENT_STACK_OF(X509_NAME_ENTRY) + +IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY) diff --git a/libs/openssl/crypto/asn1/x_nx509.c b/libs/openssl/crypto/asn1/x_nx509.c new file mode 100644 index 00000000..5aa0ed58 --- /dev/null +++ b/libs/openssl/crypto/asn1/x_nx509.c @@ -0,0 +1,72 @@ +/* x_nx509.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include + +/* Old netscape certificate wrapper format */ + +ASN1_SEQUENCE(NETSCAPE_X509) = { + ASN1_SIMPLE(NETSCAPE_X509, header, ASN1_OCTET_STRING), + ASN1_OPT(NETSCAPE_X509, cert, X509) +} ASN1_SEQUENCE_END(NETSCAPE_X509) + +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_X509) diff --git a/libs/openssl/crypto/asn1/x_pkey.c b/libs/openssl/crypto/asn1/x_pkey.c new file mode 100644 index 00000000..2da23e47 --- /dev/null +++ b/libs/openssl/crypto/asn1/x_pkey.c @@ -0,0 +1,153 @@ +/* crypto/asn1/x_pkey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +/* need to implement */ +int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp) +{ + return (0); +} + +X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp, long length) +{ + int i; + M_ASN1_D2I_vars(a, X509_PKEY *, X509_PKEY_new); + + M_ASN1_D2I_Init(); + M_ASN1_D2I_start_sequence(); + M_ASN1_D2I_get_x(X509_ALGOR, ret->enc_algor, d2i_X509_ALGOR); + M_ASN1_D2I_get_x(ASN1_OCTET_STRING, ret->enc_pkey, d2i_ASN1_OCTET_STRING); + + ret->cipher.cipher = + EVP_get_cipherbyname(OBJ_nid2ln + (OBJ_obj2nid(ret->enc_algor->algorithm))); + if (ret->cipher.cipher == NULL) { + c.error = ASN1_R_UNSUPPORTED_CIPHER; + c.line = __LINE__; + goto err; + } + if (ret->enc_algor->parameter->type == V_ASN1_OCTET_STRING) { + i = ret->enc_algor->parameter->value.octet_string->length; + if (i > EVP_MAX_IV_LENGTH) { + c.error = ASN1_R_IV_TOO_LARGE; + c.line = __LINE__; + goto err; + } + memcpy(ret->cipher.iv, + ret->enc_algor->parameter->value.octet_string->data, i); + } else + memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH); + M_ASN1_D2I_Finish(a, X509_PKEY_free, ASN1_F_D2I_X509_PKEY); +} + +X509_PKEY *X509_PKEY_new(void) +{ + X509_PKEY *ret = NULL; + ASN1_CTX c; + + M_ASN1_New_Malloc(ret, X509_PKEY); + ret->version = 0; + M_ASN1_New(ret->enc_algor, X509_ALGOR_new); + M_ASN1_New(ret->enc_pkey, M_ASN1_OCTET_STRING_new); + ret->dec_pkey = NULL; + ret->key_length = 0; + ret->key_data = NULL; + ret->key_free = 0; + ret->cipher.cipher = NULL; + memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH); + ret->references = 1; + return (ret); + M_ASN1_New_Error(ASN1_F_X509_PKEY_NEW); +} + +void X509_PKEY_free(X509_PKEY *x) +{ + int i; + + if (x == NULL) + return; + + i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_X509_PKEY); +#ifdef REF_PRINT + REF_PRINT("X509_PKEY", x); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "X509_PKEY_free, bad reference count\n"); + abort(); + } +#endif + + if (x->enc_algor != NULL) + X509_ALGOR_free(x->enc_algor); + if (x->enc_pkey != NULL) + M_ASN1_OCTET_STRING_free(x->enc_pkey); + if (x->dec_pkey != NULL) + EVP_PKEY_free(x->dec_pkey); + if ((x->key_data != NULL) && (x->key_free)) + OPENSSL_free(x->key_data); + OPENSSL_free(x); +} diff --git a/libs/openssl/crypto/asn1/x_pubkey.c b/libs/openssl/crypto/asn1/x_pubkey.c new file mode 100644 index 00000000..6c57a797 --- /dev/null +++ b/libs/openssl/crypto/asn1/x_pubkey.c @@ -0,0 +1,374 @@ +/* crypto/asn1/x_pubkey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include "asn1_locl.h" +#ifndef OPENSSL_NO_RSA +# include +#endif +#ifndef OPENSSL_NO_DSA +# include +#endif + +/* Minor tweak to operation: free up EVP_PKEY */ +static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_FREE_POST) { + X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; + EVP_PKEY_free(pubkey->pkey); + } + return 1; +} + +ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = { + ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), + ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY) + +IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY) + +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) +{ + X509_PUBKEY *pk = NULL; + + if (x == NULL) + return (0); + + if ((pk = X509_PUBKEY_new()) == NULL) + goto error; + + if (pkey->ameth) { + if (pkey->ameth->pub_encode) { + if (!pkey->ameth->pub_encode(pk, pkey)) { + X509err(X509_F_X509_PUBKEY_SET, + X509_R_PUBLIC_KEY_ENCODE_ERROR); + goto error; + } + } else { + X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED); + goto error; + } + } else { + X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM); + goto error; + } + + if (*x != NULL) + X509_PUBKEY_free(*x); + + *x = pk; + + return 1; + error: + if (pk != NULL) + X509_PUBKEY_free(pk); + return 0; +} + +EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) +{ + EVP_PKEY *ret = NULL; + + if (key == NULL) + goto error; + + if (key->pkey != NULL) { + CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + return key->pkey; + } + + if (key->public_key == NULL) + goto error; + + if ((ret = EVP_PKEY_new()) == NULL) { + X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE); + goto error; + } + + if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm))) { + X509err(X509_F_X509_PUBKEY_GET, X509_R_UNSUPPORTED_ALGORITHM); + goto error; + } + + if (ret->ameth->pub_decode) { + if (!ret->ameth->pub_decode(ret, key)) { + X509err(X509_F_X509_PUBKEY_GET, X509_R_PUBLIC_KEY_DECODE_ERROR); + goto error; + } + } else { + X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED); + goto error; + } + + /* Check to see if another thread set key->pkey first */ + CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY); + if (key->pkey) { + CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); + EVP_PKEY_free(ret); + ret = key->pkey; + } else { + key->pkey = ret; + CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY); + } + CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY); + + return ret; + + error: + if (ret != NULL) + EVP_PKEY_free(ret); + return (NULL); +} + +/* + * Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or + * decode as X509_PUBKEY + */ + +EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length) +{ + X509_PUBKEY *xpk; + EVP_PKEY *pktmp; + const unsigned char *q; + q = *pp; + xpk = d2i_X509_PUBKEY(NULL, &q, length); + if (!xpk) + return NULL; + pktmp = X509_PUBKEY_get(xpk); + X509_PUBKEY_free(xpk); + if (!pktmp) + return NULL; + *pp = q; + if (a) { + EVP_PKEY_free(*a); + *a = pktmp; + } + return pktmp; +} + +int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp) +{ + X509_PUBKEY *xpk = NULL; + int ret; + if (!a) + return 0; + if (!X509_PUBKEY_set(&xpk, a)) + return 0; + ret = i2d_X509_PUBKEY(xpk, pp); + X509_PUBKEY_free(xpk); + return ret; +} + +/* + * The following are equivalents but which return RSA and DSA keys + */ +#ifndef OPENSSL_NO_RSA +RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + RSA *key; + const unsigned char *q; + q = *pp; + pkey = d2i_PUBKEY(NULL, &q, length); + if (!pkey) + return NULL; + key = EVP_PKEY_get1_RSA(pkey); + EVP_PKEY_free(pkey); + if (!key) + return NULL; + *pp = q; + if (a) { + RSA_free(*a); + *a = key; + } + return key; +} + +int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return 0; + pktmp = EVP_PKEY_new(); + if (!pktmp) { + ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE); + return 0; + } + EVP_PKEY_set1_RSA(pktmp, a); + ret = i2d_PUBKEY(pktmp, pp); + EVP_PKEY_free(pktmp); + return ret; +} +#endif + +#ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + DSA *key; + const unsigned char *q; + q = *pp; + pkey = d2i_PUBKEY(NULL, &q, length); + if (!pkey) + return NULL; + key = EVP_PKEY_get1_DSA(pkey); + EVP_PKEY_free(pkey); + if (!key) + return NULL; + *pp = q; + if (a) { + DSA_free(*a); + *a = key; + } + return key; +} + +int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return 0; + pktmp = EVP_PKEY_new(); + if (!pktmp) { + ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE); + return 0; + } + EVP_PKEY_set1_DSA(pktmp, a); + ret = i2d_PUBKEY(pktmp, pp); + EVP_PKEY_free(pktmp); + return ret; +} +#endif + +#ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length) +{ + EVP_PKEY *pkey; + EC_KEY *key; + const unsigned char *q; + q = *pp; + pkey = d2i_PUBKEY(NULL, &q, length); + if (!pkey) + return (NULL); + key = EVP_PKEY_get1_EC_KEY(pkey); + EVP_PKEY_free(pkey); + if (!key) + return (NULL); + *pp = q; + if (a) { + EC_KEY_free(*a); + *a = key; + } + return (key); +} + +int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return (0); + if ((pktmp = EVP_PKEY_new()) == NULL) { + ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE); + return (0); + } + EVP_PKEY_set1_EC_KEY(pktmp, a); + ret = i2d_PUBKEY(pktmp, pp); + EVP_PKEY_free(pktmp); + return (ret); +} +#endif + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen) +{ + if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval)) + return 0; + if (penc) { + if (pub->public_key->data) + OPENSSL_free(pub->public_key->data); + pub->public_key->data = penc; + pub->public_key->length = penclen; + /* Set number of unused bits to zero */ + pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT; + } + return 1; +} + +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, X509_PUBKEY *pub) +{ + if (ppkalg) + *ppkalg = pub->algor->algorithm; + if (pk) { + *pk = pub->public_key->data; + *ppklen = pub->public_key->length; + } + if (pa) + *pa = pub->algor; + return 1; +} diff --git a/libs/openssl/crypto/asn1/x_req.c b/libs/openssl/crypto/asn1/x_req.c new file mode 100644 index 00000000..ae293aa0 --- /dev/null +++ b/libs/openssl/crypto/asn1/x_req.c @@ -0,0 +1,116 @@ +/* crypto/asn1/x_req.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +/*- + * X509_REQ_INFO is handled in an unusual way to get round + * invalid encodings. Some broken certificate requests don't + * encode the attributes field if it is empty. This is in + * violation of PKCS#10 but we need to tolerate it. We do + * this by making the attributes field OPTIONAL then using + * the callback to initialise it to an empty STACK. + * + * This means that the field will be correctly encoded unless + * we NULL out the field. + * + * As a result we no longer need the req_kludge field because + * the information is now contained in the attributes field: + * 1. If it is NULL then it's the invalid omission. + * 2. If it is empty it is the correct encoding. + * 3. If it is not empty then some attributes are present. + * + */ + +static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval; + + if (operation == ASN1_OP_NEW_POST) { + rinf->attributes = sk_X509_ATTRIBUTE_new_null(); + if (!rinf->attributes) + return 0; + } + return 1; +} + +ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = { + ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME), + ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY), + /* This isn't really OPTIONAL but it gets round invalid + * encodings + */ + ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0) +} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO) + +ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_REQ) = { + ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO), + ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ) + +IMPLEMENT_ASN1_FUNCTIONS(X509_REQ) + +IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ) diff --git a/libs/openssl/crypto/asn1/x_sig.c b/libs/openssl/crypto/asn1/x_sig.c new file mode 100644 index 00000000..dd33720c --- /dev/null +++ b/libs/openssl/crypto/asn1/x_sig.c @@ -0,0 +1,69 @@ +/* crypto/asn1/x_sig.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +ASN1_SEQUENCE(X509_SIG) = { + ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR), + ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(X509_SIG) + +IMPLEMENT_ASN1_FUNCTIONS(X509_SIG) diff --git a/libs/openssl/crypto/asn1/x_spki.c b/libs/openssl/crypto/asn1/x_spki.c new file mode 100644 index 00000000..1df6b87d --- /dev/null +++ b/libs/openssl/crypto/asn1/x_spki.c @@ -0,0 +1,82 @@ +/* crypto/asn1/x_spki.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + + /* + * This module was send to me my Pat Richards who wrote it. + * It is under my Copyright with his permission + */ + +#include +#include "cryptlib.h" +#include +#include + +ASN1_SEQUENCE(NETSCAPE_SPKAC) = { + ASN1_SIMPLE(NETSCAPE_SPKAC, pubkey, X509_PUBKEY), + ASN1_SIMPLE(NETSCAPE_SPKAC, challenge, ASN1_IA5STRING) +} ASN1_SEQUENCE_END(NETSCAPE_SPKAC) + +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKAC) + +ASN1_SEQUENCE(NETSCAPE_SPKI) = { + ASN1_SIMPLE(NETSCAPE_SPKI, spkac, NETSCAPE_SPKAC), + ASN1_SIMPLE(NETSCAPE_SPKI, sig_algor, X509_ALGOR), + ASN1_SIMPLE(NETSCAPE_SPKI, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(NETSCAPE_SPKI) + +IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_SPKI) diff --git a/libs/openssl/crypto/asn1/x_val.c b/libs/openssl/crypto/asn1/x_val.c new file mode 100644 index 00000000..ee75a1e2 --- /dev/null +++ b/libs/openssl/crypto/asn1/x_val.c @@ -0,0 +1,69 @@ +/* crypto/asn1/x_val.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +ASN1_SEQUENCE(X509_VAL) = { + ASN1_SIMPLE(X509_VAL, notBefore, ASN1_TIME), + ASN1_SIMPLE(X509_VAL, notAfter, ASN1_TIME) +} ASN1_SEQUENCE_END(X509_VAL) + +IMPLEMENT_ASN1_FUNCTIONS(X509_VAL) diff --git a/libs/openssl/crypto/asn1/x_x509.c b/libs/openssl/crypto/asn1/x_x509.c new file mode 100644 index 00000000..15008715 --- /dev/null +++ b/libs/openssl/crypto/asn1/x_x509.c @@ -0,0 +1,219 @@ +/* crypto/asn1/x_x509.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +ASN1_SEQUENCE_enc(X509_CINF, enc, 0) = { + ASN1_EXP_OPT(X509_CINF, version, ASN1_INTEGER, 0), + ASN1_SIMPLE(X509_CINF, serialNumber, ASN1_INTEGER), + ASN1_SIMPLE(X509_CINF, signature, X509_ALGOR), + ASN1_SIMPLE(X509_CINF, issuer, X509_NAME), + ASN1_SIMPLE(X509_CINF, validity, X509_VAL), + ASN1_SIMPLE(X509_CINF, subject, X509_NAME), + ASN1_SIMPLE(X509_CINF, key, X509_PUBKEY), + ASN1_IMP_OPT(X509_CINF, issuerUID, ASN1_BIT_STRING, 1), + ASN1_IMP_OPT(X509_CINF, subjectUID, ASN1_BIT_STRING, 2), + ASN1_EXP_SEQUENCE_OF_OPT(X509_CINF, extensions, X509_EXTENSION, 3) +} ASN1_SEQUENCE_END_enc(X509_CINF, X509_CINF) + +IMPLEMENT_ASN1_FUNCTIONS(X509_CINF) +/* X509 top level structure needs a bit of customisation */ + +extern void policy_cache_free(X509_POLICY_CACHE *cache); + +static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + X509 *ret = (X509 *)*pval; + + switch (operation) { + + case ASN1_OP_NEW_POST: + ret->valid = 0; + ret->name = NULL; + ret->ex_flags = 0; + ret->ex_pathlen = -1; + ret->skid = NULL; + ret->akid = NULL; +#ifndef OPENSSL_NO_RFC3779 + ret->rfc3779_addr = NULL; + ret->rfc3779_asid = NULL; +#endif + ret->aux = NULL; + ret->crldp = NULL; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data); + break; + + case ASN1_OP_D2I_POST: + if (ret->name != NULL) + OPENSSL_free(ret->name); + ret->name = X509_NAME_oneline(ret->cert_info->subject, NULL, 0); + break; + + case ASN1_OP_FREE_POST: + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509, ret, &ret->ex_data); + X509_CERT_AUX_free(ret->aux); + ASN1_OCTET_STRING_free(ret->skid); + AUTHORITY_KEYID_free(ret->akid); + CRL_DIST_POINTS_free(ret->crldp); + policy_cache_free(ret->policy_cache); + GENERAL_NAMES_free(ret->altname); + NAME_CONSTRAINTS_free(ret->nc); +#ifndef OPENSSL_NO_RFC3779 + sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free); + ASIdentifiers_free(ret->rfc3779_asid); +#endif + + if (ret->name != NULL) + OPENSSL_free(ret->name); + break; + + } + + return 1; + +} + +ASN1_SEQUENCE_ref(X509, x509_cb, CRYPTO_LOCK_X509) = { + ASN1_SIMPLE(X509, cert_info, X509_CINF), + ASN1_SIMPLE(X509, sig_alg, X509_ALGOR), + ASN1_SIMPLE(X509, signature, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END_ref(X509, X509) + +IMPLEMENT_ASN1_FUNCTIONS(X509) + +IMPLEMENT_ASN1_DUP_FUNCTION(X509) + +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509, argl, argp, + new_func, dup_func, free_func); +} + +int X509_set_ex_data(X509 *r, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); +} + +void *X509_get_ex_data(X509 *r, int idx) +{ + return (CRYPTO_get_ex_data(&r->ex_data, idx)); +} + +/* + * X509_AUX ASN1 routines. X509_AUX is the name given to a certificate with + * extra info tagged on the end. Since these functions set how a certificate + * is trusted they should only be used when the certificate comes from a + * reliable source such as local storage. + */ + +X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length) +{ + const unsigned char *q; + X509 *ret; + int freeret = 0; + + /* Save start position */ + q = *pp; + + if (!a || *a == NULL) { + freeret = 1; + } + ret = d2i_X509(a, &q, length); + /* If certificate unreadable then forget it */ + if (!ret) + return NULL; + /* update length */ + length -= q - *pp; + if (length > 0 && !d2i_X509_CERT_AUX(&ret->aux, &q, length)) + goto err; + *pp = q; + return ret; + err: + if (freeret) { + X509_free(ret); + if (a) + *a = NULL; + } + return NULL; +} + +int i2d_X509_AUX(X509 *a, unsigned char **pp) +{ + int length, tmplen; + unsigned char *start = pp != NULL ? *pp : NULL; + length = i2d_X509(a, pp); + if (length < 0 || a == NULL) + return length; + + tmplen = i2d_X509_CERT_AUX(a->aux, pp); + if (tmplen < 0) { + if (start != NULL) + *pp = start; + return tmplen; + } + length += tmplen; + + return length; +} diff --git a/libs/openssl/crypto/asn1/x_x509a.c b/libs/openssl/crypto/asn1/x_x509a.c new file mode 100644 index 00000000..76bbc137 --- /dev/null +++ b/libs/openssl/crypto/asn1/x_x509a.c @@ -0,0 +1,193 @@ +/* a_x509a.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +/* + * X509_CERT_AUX routines. These are used to encode additional user + * modifiable data about a certificate. This data is appended to the X509 + * encoding when the *_X509_AUX routines are used. This means that the + * "traditional" X509 routines will simply ignore the extra data. + */ + +static X509_CERT_AUX *aux_get(X509 *x); + +ASN1_SEQUENCE(X509_CERT_AUX) = { + ASN1_SEQUENCE_OF_OPT(X509_CERT_AUX, trust, ASN1_OBJECT), + ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, reject, ASN1_OBJECT, 0), + ASN1_OPT(X509_CERT_AUX, alias, ASN1_UTF8STRING), + ASN1_OPT(X509_CERT_AUX, keyid, ASN1_OCTET_STRING), + ASN1_IMP_SEQUENCE_OF_OPT(X509_CERT_AUX, other, X509_ALGOR, 1) +} ASN1_SEQUENCE_END(X509_CERT_AUX) + +IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_AUX) + +static X509_CERT_AUX *aux_get(X509 *x) +{ + if (!x) + return NULL; + if (!x->aux && !(x->aux = X509_CERT_AUX_new())) + return NULL; + return x->aux; +} + +int X509_alias_set1(X509 *x, unsigned char *name, int len) +{ + X509_CERT_AUX *aux; + if (!name) { + if (!x || !x->aux || !x->aux->alias) + return 1; + ASN1_UTF8STRING_free(x->aux->alias); + x->aux->alias = NULL; + return 1; + } + if (!(aux = aux_get(x))) + return 0; + if (!aux->alias && !(aux->alias = ASN1_UTF8STRING_new())) + return 0; + return ASN1_STRING_set(aux->alias, name, len); +} + +int X509_keyid_set1(X509 *x, unsigned char *id, int len) +{ + X509_CERT_AUX *aux; + if (!id) { + if (!x || !x->aux || !x->aux->keyid) + return 1; + ASN1_OCTET_STRING_free(x->aux->keyid); + x->aux->keyid = NULL; + return 1; + } + if (!(aux = aux_get(x))) + return 0; + if (!aux->keyid && !(aux->keyid = ASN1_OCTET_STRING_new())) + return 0; + return ASN1_STRING_set(aux->keyid, id, len); +} + +unsigned char *X509_alias_get0(X509 *x, int *len) +{ + if (!x->aux || !x->aux->alias) + return NULL; + if (len) + *len = x->aux->alias->length; + return x->aux->alias->data; +} + +unsigned char *X509_keyid_get0(X509 *x, int *len) +{ + if (!x->aux || !x->aux->keyid) + return NULL; + if (len) + *len = x->aux->keyid->length; + return x->aux->keyid->data; +} + +int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj) +{ + X509_CERT_AUX *aux; + ASN1_OBJECT *objtmp; + if (!(objtmp = OBJ_dup(obj))) + return 0; + if (!(aux = aux_get(x))) + return 0; + if (!aux->trust && !(aux->trust = sk_ASN1_OBJECT_new_null())) + return 0; + return sk_ASN1_OBJECT_push(aux->trust, objtmp); +} + +int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj) +{ + X509_CERT_AUX *aux; + ASN1_OBJECT *objtmp; + if (!(objtmp = OBJ_dup(obj))) + return 0; + if (!(aux = aux_get(x))) + return 0; + if (!aux->reject && !(aux->reject = sk_ASN1_OBJECT_new_null())) + return 0; + return sk_ASN1_OBJECT_push(aux->reject, objtmp); +} + +void X509_trust_clear(X509 *x) +{ + if (x->aux && x->aux->trust) { + sk_ASN1_OBJECT_pop_free(x->aux->trust, ASN1_OBJECT_free); + x->aux->trust = NULL; + } +} + +void X509_reject_clear(X509 *x) +{ + if (x->aux && x->aux->reject) { + sk_ASN1_OBJECT_pop_free(x->aux->reject, ASN1_OBJECT_free); + x->aux->reject = NULL; + } +} + +ASN1_SEQUENCE(X509_CERT_PAIR) = { + ASN1_EXP_OPT(X509_CERT_PAIR, forward, X509, 0), + ASN1_EXP_OPT(X509_CERT_PAIR, reverse, X509, 1) +} ASN1_SEQUENCE_END(X509_CERT_PAIR) + +IMPLEMENT_ASN1_FUNCTIONS(X509_CERT_PAIR) diff --git a/libs/openssl/crypto/bf/COPYRIGHT b/libs/openssl/crypto/bf/COPYRIGHT new file mode 100644 index 00000000..68572235 --- /dev/null +++ b/libs/openssl/crypto/bf/COPYRIGHT @@ -0,0 +1,46 @@ +Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +All rights reserved. + +This package is an Blowfish implementation written +by Eric Young (eay@cryptsoft.com). + +This library is free for commercial and non-commercial use as long as +the following conditions are aheared to. The following conditions +apply to all code found in this distribution. + +Copyright remains Eric Young's, and as such any Copyright notices in +the code are not to be removed. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + This product includes software developed by Eric Young (eay@cryptsoft.com) + +THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +The license and distribution terms for any publically available version or +derivative of this code cannot be changed. i.e. this code cannot simply be +copied and put under another distrubution license +[including the GNU Public License.] + +The reason behind this being stated in this direct manner is past +experience in code simply being copied and the attribution removed +from it and then being distributed as part of other packages. This +implementation was a non-trivial and unpaid effort. diff --git a/libs/openssl/crypto/bf/INSTALL b/libs/openssl/crypto/bf/INSTALL new file mode 100644 index 00000000..3b259235 --- /dev/null +++ b/libs/openssl/crypto/bf/INSTALL @@ -0,0 +1,14 @@ +This Eric Young's blowfish implementation, taken from his SSLeay library +and made available as a separate library. + +The version number (0.7.2m) is the SSLeay version that this library was +taken from. + +To build, just unpack and type make. +If you are not using gcc, edit the Makefile. +If you are compiling for an x86 box, try the assembler (it needs improving). +There are also some compile time options that can improve performance, +these are documented in the Makefile. + +eric 15-Apr-1997 + diff --git a/libs/openssl/crypto/bf/README b/libs/openssl/crypto/bf/README new file mode 100644 index 00000000..f2712fd0 --- /dev/null +++ b/libs/openssl/crypto/bf/README @@ -0,0 +1,8 @@ +This is a quick packaging up of my blowfish code into a library. +It has been lifted from SSLeay. +The copyright notices seem a little harsh because I have not spent the +time to rewrite the conditions from the normal SSLeay ones. + +Basically if you just want to play with the library, not a problem. + +eric 15-Apr-1997 diff --git a/libs/openssl/crypto/bf/VERSION b/libs/openssl/crypto/bf/VERSION new file mode 100644 index 00000000..be995855 --- /dev/null +++ b/libs/openssl/crypto/bf/VERSION @@ -0,0 +1,6 @@ +The version numbers will follow my SSL implementation + +0.7.2r - Some reasonable default compiler options from + Peter Gutman + +0.7.2m - the first release diff --git a/libs/openssl/crypto/bf/asm/bf-586.pl b/libs/openssl/crypto/bf/asm/bf-586.pl new file mode 100644 index 00000000..b74cfbaf --- /dev/null +++ b/libs/openssl/crypto/bf/asm/bf-586.pl @@ -0,0 +1,137 @@ +#!/usr/local/bin/perl + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; +require "cbc.pl"; + +&asm_init($ARGV[0],"bf-586.pl",$ARGV[$#ARGV] eq "386"); + +$BF_ROUNDS=16; +$BF_OFF=($BF_ROUNDS+2)*4; +$L="edi"; +$R="esi"; +$P="ebp"; +$tmp1="eax"; +$tmp2="ebx"; +$tmp3="ecx"; +$tmp4="edx"; + +&BF_encrypt("BF_encrypt",1); +&BF_encrypt("BF_decrypt",0); +&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1); +&asm_finish(); + +sub BF_encrypt + { + local($name,$enc)=@_; + + &function_begin_B($name,""); + + &comment(""); + + &push("ebp"); + &push("ebx"); + &mov($tmp2,&wparam(0)); + &mov($P,&wparam(1)); + &push("esi"); + &push("edi"); + + &comment("Load the 2 words"); + &mov($L,&DWP(0,$tmp2,"",0)); + &mov($R,&DWP(4,$tmp2,"",0)); + + &xor( $tmp1, $tmp1); + + # encrypting part + + if ($enc) + { + &mov($tmp2,&DWP(0,$P,"",0)); + &xor( $tmp3, $tmp3); + + &xor($L,$tmp2); + for ($i=0; $i<$BF_ROUNDS; $i+=2) + { + &comment(""); + &comment("Round $i"); + &BF_ENCRYPT($i+1,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,1); + + &comment(""); + &comment("Round ".sprintf("%d",$i+1)); + &BF_ENCRYPT($i+2,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,1); + } + # &mov($tmp1,&wparam(0)); In last loop + &mov($tmp4,&DWP(($BF_ROUNDS+1)*4,$P,"",0)); + } + else + { + &mov($tmp2,&DWP(($BF_ROUNDS+1)*4,$P,"",0)); + &xor( $tmp3, $tmp3); + + &xor($L,$tmp2); + for ($i=$BF_ROUNDS; $i>0; $i-=2) + { + &comment(""); + &comment("Round $i"); + &BF_ENCRYPT($i,$R,$L,$P,$tmp1,$tmp2,$tmp3,$tmp4,0); + &comment(""); + &comment("Round ".sprintf("%d",$i-1)); + &BF_ENCRYPT($i-1,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,0); + } + # &mov($tmp1,&wparam(0)); In last loop + &mov($tmp4,&DWP(0,$P,"",0)); + } + + &xor($R,$tmp4); + &mov(&DWP(4,$tmp1,"",0),$L); + + &mov(&DWP(0,$tmp1,"",0),$R); + &function_end($name); + } + +sub BF_ENCRYPT + { + local($i,$L,$R,$P,$tmp1,$tmp2,$tmp3,$tmp4,$enc)=@_; + + &mov( $tmp4, &DWP(&n2a($i*4),$P,"",0)); # for next round + + &mov( $tmp2, $R); + &xor( $L, $tmp4); + + &shr( $tmp2, 16); + &mov( $tmp4, $R); + + &movb( &LB($tmp1), &HB($tmp2)); # A + &and( $tmp2, 0xff); # B + + &movb( &LB($tmp3), &HB($tmp4)); # C + &and( $tmp4, 0xff); # D + + &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4)); + &mov( $tmp2, &DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4)); + + &add( $tmp2, $tmp1); + &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0800),$P,$tmp3,4)); + + &xor( $tmp2, $tmp1); + &mov( $tmp4, &DWP(&n2a($BF_OFF+0x0C00),$P,$tmp4,4)); + + &add( $tmp2, $tmp4); + if (($enc && ($i != 16)) || ((!$enc) && ($i != 1))) + { &xor( $tmp1, $tmp1); } + else + { + &comment("Load parameter 0 ($i) enc=$enc"); + &mov($tmp1,&wparam(0)); + } # In last loop + + &xor( $L, $tmp2); + # delay + } + +sub n2a + { + sprintf("%d",$_[0]); + } + diff --git a/libs/openssl/crypto/bf/asm/bf-686.pl b/libs/openssl/crypto/bf/asm/bf-686.pl new file mode 100644 index 00000000..8e4c25f5 --- /dev/null +++ b/libs/openssl/crypto/bf/asm/bf-686.pl @@ -0,0 +1,127 @@ +#!/usr/local/bin/perl + +push(@INC,"perlasm","../../perlasm"); +require "x86asm.pl"; +require "cbc.pl"; + +&asm_init($ARGV[0],"bf-686.pl"); + +$BF_ROUNDS=16; +$BF_OFF=($BF_ROUNDS+2)*4; +$L="ecx"; +$R="edx"; +$P="edi"; +$tot="esi"; +$tmp1="eax"; +$tmp2="ebx"; +$tmp3="ebp"; + +&des_encrypt("BF_encrypt",1); +&des_encrypt("BF_decrypt",0); +&cbc("BF_cbc_encrypt","BF_encrypt","BF_decrypt",1,4,5,3,-1,-1); + +&asm_finish(); + +&file_end(); + +sub des_encrypt + { + local($name,$enc)=@_; + + &function_begin($name,""); + + &comment(""); + &comment("Load the 2 words"); + &mov("eax",&wparam(0)); + &mov($L,&DWP(0,"eax","",0)); + &mov($R,&DWP(4,"eax","",0)); + + &comment(""); + &comment("P pointer, s and enc flag"); + &mov($P,&wparam(1)); + + &xor( $tmp1, $tmp1); + &xor( $tmp2, $tmp2); + + # encrypting part + + if ($enc) + { + &xor($L,&DWP(0,$P,"",0)); + for ($i=0; $i<$BF_ROUNDS; $i+=2) + { + &comment(""); + &comment("Round $i"); + &BF_ENCRYPT($i+1,$R,$L,$P,$tot,$tmp1,$tmp2,$tmp3); + + &comment(""); + &comment("Round ".sprintf("%d",$i+1)); + &BF_ENCRYPT($i+2,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3); + } + &xor($R,&DWP(($BF_ROUNDS+1)*4,$P,"",0)); + + &mov("eax",&wparam(0)); + &mov(&DWP(0,"eax","",0),$R); + &mov(&DWP(4,"eax","",0),$L); + &function_end_A($name); + } + else + { + &xor($L,&DWP(($BF_ROUNDS+1)*4,$P,"",0)); + for ($i=$BF_ROUNDS; $i>0; $i-=2) + { + &comment(""); + &comment("Round $i"); + &BF_ENCRYPT($i,$R,$L,$P,$tot,$tmp1,$tmp2,$tmp3); + &comment(""); + &comment("Round ".sprintf("%d",$i-1)); + &BF_ENCRYPT($i-1,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3); + } + &xor($R,&DWP(0,$P,"",0)); + + &mov("eax",&wparam(0)); + &mov(&DWP(0,"eax","",0),$R); + &mov(&DWP(4,"eax","",0),$L); + &function_end_A($name); + } + + &function_end_B($name); + } + +sub BF_ENCRYPT + { + local($i,$L,$R,$P,$tot,$tmp1,$tmp2,$tmp3)=@_; + + &rotr( $R, 16); + &mov( $tot, &DWP(&n2a($i*4),$P,"",0)); + + &movb( &LB($tmp1), &HB($R)); + &movb( &LB($tmp2), &LB($R)); + + &rotr( $R, 16); + &xor( $L, $tot); + + &mov( $tot, &DWP(&n2a($BF_OFF+0x0000),$P,$tmp1,4)); + &mov( $tmp3, &DWP(&n2a($BF_OFF+0x0400),$P,$tmp2,4)); + + &movb( &LB($tmp1), &HB($R)); + &movb( &LB($tmp2), &LB($R)); + + &add( $tot, $tmp3); + &mov( $tmp1, &DWP(&n2a($BF_OFF+0x0800),$P,$tmp1,4)); # delay + + &xor( $tot, $tmp1); + &mov( $tmp3, &DWP(&n2a($BF_OFF+0x0C00),$P,$tmp2,4)); + + &add( $tot, $tmp3); + &xor( $tmp1, $tmp1); + + &xor( $L, $tot); + # delay + } + +sub n2a + { + sprintf("%d",$_[0]); + } + diff --git a/libs/openssl/crypto/bf/asm/readme b/libs/openssl/crypto/bf/asm/readme new file mode 100644 index 00000000..2385fa38 --- /dev/null +++ b/libs/openssl/crypto/bf/asm/readme @@ -0,0 +1,10 @@ +There are blowfish assembler generation scripts. +bf-586.pl version is for the pentium and +bf-686.pl is my original version, which is faster on the pentium pro. + +When using a bf-586.pl, the pentium pro/II is %8 slower than using +bf-686.pl. When using a bf-686.pl, the pentium is %16 slower +than bf-586.pl + +So the default is bf-586.pl + diff --git a/libs/openssl/crypto/bf/bf_cbc.c b/libs/openssl/crypto/bf/bf_cbc.c new file mode 100644 index 00000000..de827a1a --- /dev/null +++ b/libs/openssl/crypto/bf/bf_cbc.c @@ -0,0 +1,135 @@ +/* crypto/bf/bf_cbc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "bf_locl.h" + +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int encrypt) +{ + register BF_LONG tin0, tin1; + register BF_LONG tout0, tout1, xor0, xor1; + register long l = length; + BF_LONG tin[2]; + + if (encrypt) { + n2l(ivec, tout0); + n2l(ivec, tout1); + ivec -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + BF_encrypt(tin, schedule); + tout0 = tin[0]; + tout1 = tin[1]; + l2n(tout0, out); + l2n(tout1, out); + } + if (l != -8) { + n2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + BF_encrypt(tin, schedule); + tout0 = tin[0]; + tout1 = tin[1]; + l2n(tout0, out); + l2n(tout1, out); + } + l2n(tout0, ivec); + l2n(tout1, ivec); + } else { + n2l(ivec, xor0); + n2l(ivec, xor1); + ivec -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin[0] = tin0; + tin[1] = tin1; + BF_decrypt(tin, schedule); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2n(tout0, out); + l2n(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + n2l(in, tin0); + n2l(in, tin1); + tin[0] = tin0; + tin[1] = tin1; + BF_decrypt(tin, schedule); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2nn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2n(xor0, ivec); + l2n(xor1, ivec); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} diff --git a/libs/openssl/crypto/bf/bf_cfb64.c b/libs/openssl/crypto/bf/bf_cfb64.c new file mode 100644 index 00000000..ddeab6eb --- /dev/null +++ b/libs/openssl/crypto/bf/bf_cfb64.c @@ -0,0 +1,123 @@ +/* crypto/bf/bf_cfb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "bf_locl.h" + +/* + * The input and output encrypted as though 64bit cfb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ + +void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num, int encrypt) +{ + register BF_LONG v0, v1, t; + register int n = *num; + register long l = length; + BF_LONG ti[2]; + unsigned char *iv, c, cc; + + iv = (unsigned char *)ivec; + if (encrypt) { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + BF_encrypt((BF_LONG *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = (unsigned char *)ivec; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + BF_encrypt((BF_LONG *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = (unsigned char *)ivec; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; + *num = n; +} diff --git a/libs/openssl/crypto/bf/bf_ecb.c b/libs/openssl/crypto/bf/bf_ecb.c new file mode 100644 index 00000000..967a7f55 --- /dev/null +++ b/libs/openssl/crypto/bf/bf_ecb.c @@ -0,0 +1,100 @@ +/* crypto/bf/bf_ecb.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "bf_locl.h" +#include + +/* + * Blowfish as implemented from 'Blowfish: Springer-Verlag paper' (From + * LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, CAMBRIDGE + * SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993) + */ + +const char BF_version[] = "Blowfish" OPENSSL_VERSION_PTEXT; + +const char *BF_options(void) +{ +#ifdef BF_PTR + return ("blowfish(ptr)"); +#elif defined(BF_PTR2) + return ("blowfish(ptr2)"); +#else + return ("blowfish(idx)"); +#endif +} + +void BF_ecb_encrypt(const unsigned char *in, unsigned char *out, + const BF_KEY *key, int encrypt) +{ + BF_LONG l, d[2]; + + n2l(in, l); + d[0] = l; + n2l(in, l); + d[1] = l; + if (encrypt) + BF_encrypt(d, key); + else + BF_decrypt(d, key); + l = d[0]; + l2n(l, out); + l = d[1]; + l2n(l, out); + l = d[0] = d[1] = 0; +} diff --git a/libs/openssl/crypto/bf/bf_enc.c b/libs/openssl/crypto/bf/bf_enc.c new file mode 100644 index 00000000..b268795f --- /dev/null +++ b/libs/openssl/crypto/bf/bf_enc.c @@ -0,0 +1,300 @@ +/* crypto/bf/bf_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "bf_locl.h" + +/* + * Blowfish as implemented from 'Blowfish: Springer-Verlag paper' (From + * LECTURE NOTES IN COMPUTER SCIENCE 809, FAST SOFTWARE ENCRYPTION, CAMBRIDGE + * SECURITY WORKSHOP, CAMBRIDGE, U.K., DECEMBER 9-11, 1993) + */ + +#if (BF_ROUNDS != 16) && (BF_ROUNDS != 20) +# error If you set BF_ROUNDS to some value other than 16 or 20, you will have \ +to modify the code. +#endif + +void BF_encrypt(BF_LONG *data, const BF_KEY *key) +{ +#ifndef BF_PTR2 + register BF_LONG l, r; + register const BF_LONG *p, *s; + + p = key->P; + s = &(key->S[0]); + l = data[0]; + r = data[1]; + + l ^= p[0]; + BF_ENC(r, l, s, p[1]); + BF_ENC(l, r, s, p[2]); + BF_ENC(r, l, s, p[3]); + BF_ENC(l, r, s, p[4]); + BF_ENC(r, l, s, p[5]); + BF_ENC(l, r, s, p[6]); + BF_ENC(r, l, s, p[7]); + BF_ENC(l, r, s, p[8]); + BF_ENC(r, l, s, p[9]); + BF_ENC(l, r, s, p[10]); + BF_ENC(r, l, s, p[11]); + BF_ENC(l, r, s, p[12]); + BF_ENC(r, l, s, p[13]); + BF_ENC(l, r, s, p[14]); + BF_ENC(r, l, s, p[15]); + BF_ENC(l, r, s, p[16]); +# if BF_ROUNDS == 20 + BF_ENC(r, l, s, p[17]); + BF_ENC(l, r, s, p[18]); + BF_ENC(r, l, s, p[19]); + BF_ENC(l, r, s, p[20]); +# endif + r ^= p[BF_ROUNDS + 1]; + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +#else + register BF_LONG l, r, t, *k; + + l = data[0]; + r = data[1]; + k = (BF_LONG *)key; + + l ^= k[0]; + BF_ENC(r, l, k, 1); + BF_ENC(l, r, k, 2); + BF_ENC(r, l, k, 3); + BF_ENC(l, r, k, 4); + BF_ENC(r, l, k, 5); + BF_ENC(l, r, k, 6); + BF_ENC(r, l, k, 7); + BF_ENC(l, r, k, 8); + BF_ENC(r, l, k, 9); + BF_ENC(l, r, k, 10); + BF_ENC(r, l, k, 11); + BF_ENC(l, r, k, 12); + BF_ENC(r, l, k, 13); + BF_ENC(l, r, k, 14); + BF_ENC(r, l, k, 15); + BF_ENC(l, r, k, 16); +# if BF_ROUNDS == 20 + BF_ENC(r, l, k, 17); + BF_ENC(l, r, k, 18); + BF_ENC(r, l, k, 19); + BF_ENC(l, r, k, 20); +# endif + r ^= k[BF_ROUNDS + 1]; + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +#endif +} + +#ifndef BF_DEFAULT_OPTIONS + +void BF_decrypt(BF_LONG *data, const BF_KEY *key) +{ +# ifndef BF_PTR2 + register BF_LONG l, r; + register const BF_LONG *p, *s; + + p = key->P; + s = &(key->S[0]); + l = data[0]; + r = data[1]; + + l ^= p[BF_ROUNDS + 1]; +# if BF_ROUNDS == 20 + BF_ENC(r, l, s, p[20]); + BF_ENC(l, r, s, p[19]); + BF_ENC(r, l, s, p[18]); + BF_ENC(l, r, s, p[17]); +# endif + BF_ENC(r, l, s, p[16]); + BF_ENC(l, r, s, p[15]); + BF_ENC(r, l, s, p[14]); + BF_ENC(l, r, s, p[13]); + BF_ENC(r, l, s, p[12]); + BF_ENC(l, r, s, p[11]); + BF_ENC(r, l, s, p[10]); + BF_ENC(l, r, s, p[9]); + BF_ENC(r, l, s, p[8]); + BF_ENC(l, r, s, p[7]); + BF_ENC(r, l, s, p[6]); + BF_ENC(l, r, s, p[5]); + BF_ENC(r, l, s, p[4]); + BF_ENC(l, r, s, p[3]); + BF_ENC(r, l, s, p[2]); + BF_ENC(l, r, s, p[1]); + r ^= p[0]; + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +# else + register BF_LONG l, r, t, *k; + + l = data[0]; + r = data[1]; + k = (BF_LONG *)key; + + l ^= k[BF_ROUNDS + 1]; +# if BF_ROUNDS == 20 + BF_ENC(r, l, k, 20); + BF_ENC(l, r, k, 19); + BF_ENC(r, l, k, 18); + BF_ENC(l, r, k, 17); +# endif + BF_ENC(r, l, k, 16); + BF_ENC(l, r, k, 15); + BF_ENC(r, l, k, 14); + BF_ENC(l, r, k, 13); + BF_ENC(r, l, k, 12); + BF_ENC(l, r, k, 11); + BF_ENC(r, l, k, 10); + BF_ENC(l, r, k, 9); + BF_ENC(r, l, k, 8); + BF_ENC(l, r, k, 7); + BF_ENC(r, l, k, 6); + BF_ENC(l, r, k, 5); + BF_ENC(r, l, k, 4); + BF_ENC(l, r, k, 3); + BF_ENC(r, l, k, 2); + BF_ENC(l, r, k, 1); + r ^= k[0]; + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +# endif +} + +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int encrypt) +{ + register BF_LONG tin0, tin1; + register BF_LONG tout0, tout1, xor0, xor1; + register long l = length; + BF_LONG tin[2]; + + if (encrypt) { + n2l(ivec, tout0); + n2l(ivec, tout1); + ivec -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + BF_encrypt(tin, schedule); + tout0 = tin[0]; + tout1 = tin[1]; + l2n(tout0, out); + l2n(tout1, out); + } + if (l != -8) { + n2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + BF_encrypt(tin, schedule); + tout0 = tin[0]; + tout1 = tin[1]; + l2n(tout0, out); + l2n(tout1, out); + } + l2n(tout0, ivec); + l2n(tout1, ivec); + } else { + n2l(ivec, xor0); + n2l(ivec, xor1); + ivec -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin[0] = tin0; + tin[1] = tin1; + BF_decrypt(tin, schedule); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2n(tout0, out); + l2n(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + n2l(in, tin0); + n2l(in, tin1); + tin[0] = tin0; + tin[1] = tin1; + BF_decrypt(tin, schedule); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2nn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2n(xor0, ivec); + l2n(xor1, ivec); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} + +#endif diff --git a/libs/openssl/crypto/bf/bf_locl.h b/libs/openssl/crypto/bf/bf_locl.h new file mode 100644 index 00000000..9448aed4 --- /dev/null +++ b/libs/openssl/crypto/bf/bf_locl.h @@ -0,0 +1,221 @@ +/* crypto/bf/bf_locl.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BF_LOCL_H +# define HEADER_BF_LOCL_H +# include /* BF_PTR, BF_PTR2 */ + +# undef c2l +# define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +# undef c2ln +# define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +# undef l2c +# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* NOTE - c is not incremented as per l2c */ +# undef l2cn +# define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +/* NOTE - c is not incremented as per n2l */ +# define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +# define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + } \ + } + +# undef n2l +# define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +# undef l2n +# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +/* + * This is actually a big endian algorithm, the most significant byte is used + * to lookup array 0 + */ + +# if defined(BF_PTR2) + +/* + * This is basically a special Intel version. Point is that Intel + * doesn't have many registers, but offers a reach choice of addressing + * modes. So we spare some registers by directly traversing BF_KEY + * structure and hiring the most decorated addressing mode. The code + * generated by EGCS is *perfectly* competitive with assembler + * implementation! + */ +# define BF_ENC(LL,R,KEY,Pi) (\ + LL^=KEY[Pi], \ + t= KEY[BF_ROUNDS+2 + 0 + ((R>>24)&0xFF)], \ + t+= KEY[BF_ROUNDS+2 + 256 + ((R>>16)&0xFF)], \ + t^= KEY[BF_ROUNDS+2 + 512 + ((R>>8 )&0xFF)], \ + t+= KEY[BF_ROUNDS+2 + 768 + ((R )&0xFF)], \ + LL^=t \ + ) + +# elif defined(BF_PTR) + +# ifndef BF_LONG_LOG2 +# define BF_LONG_LOG2 2 /* default to BF_LONG being 32 bits */ +# endif +# define BF_M (0xFF<>BF_i)&BF_M gets folded into a single instruction, namely + * rlwinm. So let'em double-check if their compiler does it. + */ + +# define BF_ENC(LL,R,S,P) ( \ + LL^=P, \ + LL^= (((*(BF_LONG *)((unsigned char *)&(S[ 0])+((R>>BF_0)&BF_M))+ \ + *(BF_LONG *)((unsigned char *)&(S[256])+((R>>BF_1)&BF_M)))^ \ + *(BF_LONG *)((unsigned char *)&(S[512])+((R>>BF_2)&BF_M)))+ \ + *(BF_LONG *)((unsigned char *)&(S[768])+((R<>24)&0xff)] + \ + S[0x0100+((int)(R>>16)&0xff)])^ \ + S[0x0200+((int)(R>> 8)&0xff)])+ \ + S[0x0300+((int)(R )&0xff)])&0xffffffffL \ + ) +# endif + +#endif diff --git a/libs/openssl/crypto/bf/bf_ofb64.c b/libs/openssl/crypto/bf/bf_ofb64.c new file mode 100644 index 00000000..a8d190b5 --- /dev/null +++ b/libs/openssl/crypto/bf/bf_ofb64.c @@ -0,0 +1,110 @@ +/* crypto/bf/bf_ofb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "bf_locl.h" + +/* + * The input and output encrypted as though 64bit ofb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ +void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num) +{ + register BF_LONG v0, v1, t; + register int n = *num; + register long l = length; + unsigned char d[8]; + register char *dp; + BF_LONG ti[2]; + unsigned char *iv; + int save = 0; + + iv = (unsigned char *)ivec; + n2l(iv, v0); + n2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2n(v0, dp); + l2n(v1, dp); + while (l--) { + if (n == 0) { + BF_encrypt((BF_LONG *)ti, schedule); + dp = (char *)d; + t = ti[0]; + l2n(t, dp); + t = ti[1]; + l2n(t, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = (unsigned char *)ivec; + l2n(v0, iv); + l2n(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} diff --git a/libs/openssl/crypto/bf/bf_opts.c b/libs/openssl/crypto/bf/bf_opts.c new file mode 100644 index 00000000..f85495cf --- /dev/null +++ b/libs/openssl/crypto/bf/bf_opts.c @@ -0,0 +1,324 @@ +/* crypto/bf/bf_opts.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * define PART1, PART2, PART3 or PART4 to build only with a few of the + * options. This is for machines with 64k code segment size restrictions. + */ + +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX) +# define TIMES +#endif + +#include + +#include +#include OPENSSL_UNISTD_IO +OPENSSL_DECLARE_EXIT +#ifndef OPENSSL_SYS_NETWARE +# include +#endif +#ifndef _IRIX +# include +#endif +#ifdef TIMES +# include +# include +#endif + /* + * Depending on the VMS version, the tms structure is perhaps defined. + * The __TMS macro will show if it was. If it wasn't defined, we should + * undefine TIMES, since that tells the rest of the program how things + * should be handled. -- Richard Levitte + */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) +# undef TIMES +#endif +#ifndef TIMES +# include +#endif +#if defined(sun) || defined(__ultrix) +# define _POSIX_SOURCE +# include +# include +#endif +#include +#define BF_DEFAULT_OPTIONS +#undef BF_ENC +#define BF_encrypt BF_encrypt_normal +#undef HEADER_BF_LOCL_H +#include "bf_enc.c" +#define BF_PTR +#undef BF_PTR2 +#undef BF_ENC +#undef BF_encrypt +#define BF_encrypt BF_encrypt_ptr +#undef HEADER_BF_LOCL_H +#include "bf_enc.c" +#undef BF_PTR +#define BF_PTR2 +#undef BF_ENC +#undef BF_encrypt +#define BF_encrypt BF_encrypt_ptr2 +#undef HEADER_BF_LOCL_H +#include "bf_enc.c" +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */ +# define HZ 100.0 +# else /* _BSD_CLK_TCK_ */ +# define HZ ((double)_BSD_CLK_TCK_) +# endif +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +#endif +#define BUFSIZE ((long)1024) +long run = 0; + +double Time_F(int s); +#ifdef SIGALRM +# if defined(__STDC__) || defined(sgi) +# define SIGRETTYPE void +# else +# define SIGRETTYPE int +# endif + +SIGRETTYPE sig_done(int sig); +SIGRETTYPE sig_done(int sig) +{ + signal(SIGALRM, sig_done); + run = 0; +# ifdef LINT + sig = sig; +# endif +} +#endif + +#define START 0 +#define STOP 1 + +double Time_F(int s) +{ + double ret; +#ifdef TIMES + static struct tms tstart, tend; + + if (s == START) { + times(&tstart); + return (0); + } else { + times(&tend); + ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ; + return ((ret == 0.0) ? 1e-6 : ret); + } +#else /* !times() */ + static struct timeb tstart, tend; + long i; + + if (s == START) { + ftime(&tstart); + return (0); + } else { + ftime(&tend); + i = (long)tend.millitm - (long)tstart.millitm; + ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1000.0; + return ((ret == 0.0) ? 1e-6 : ret); + } +#endif +} + +#ifdef SIGALRM +# define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10); +#else +# define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb); +#endif + +#define time_it(func,name,index) \ + print_name(name); \ + Time_F(START); \ + for (count=0,run=1; COND(cb); count+=4) \ + { \ + unsigned long d[2]; \ + func(d,&sch); \ + func(d,&sch); \ + func(d,&sch); \ + func(d,&sch); \ + } \ + tm[index]=Time_F(STOP); \ + fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \ + tm[index]=((double)COUNT(cb))/tm[index]; + +#define print_it(name,index) \ + fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \ + tm[index]*8,1.0e6/tm[index]); + +int main(int argc, char **argv) +{ + long count; + static unsigned char buf[BUFSIZE]; + static char key[16] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 + }; + BF_KEY sch; + double d, tm[16], max = 0; + int rank[16]; + char *str[16]; + int max_idx = 0, i, num = 0, j; +#ifndef SIGALARM + long ca, cb, cc, cd, ce; +#endif + + for (i = 0; i < 12; i++) { + tm[i] = 0.0; + rank[i] = 0; + } + +#ifndef TIMES + fprintf(stderr, "To get the most accurate results, try to run this\n"); + fprintf(stderr, "program when this computer is idle.\n"); +#endif + + BF_set_key(&sch, 16, key); + +#ifndef SIGALRM + fprintf(stderr, "First we calculate the approximate speed ...\n"); + count = 10; + do { + long i; + unsigned long data[2]; + + count *= 2; + Time_F(START); + for (i = count; i; i--) + BF_encrypt(data, &sch); + d = Time_F(STOP); + } while (d < 3.0); + ca = count; + cb = count * 3; + cc = count * 3 * 8 / BUFSIZE + 1; + cd = count * 8 / BUFSIZE + 1; + + ce = count / 20 + 1; +# define COND(d) (count != (d)) +# define COUNT(d) (d) +#else +# define COND(c) (run) +# define COUNT(d) (count) + signal(SIGALRM, sig_done); + alarm(10); +#endif + + time_it(BF_encrypt_normal, "BF_encrypt_normal ", 0); + time_it(BF_encrypt_ptr, "BF_encrypt_ptr ", 1); + time_it(BF_encrypt_ptr2, "BF_encrypt_ptr2 ", 2); + num += 3; + + str[0] = ""; + print_it("BF_encrypt_normal ", 0); + max = tm[0]; + max_idx = 0; + str[1] = "ptr "; + print_it("BF_encrypt_ptr ", 1); + if (max < tm[1]) { + max = tm[1]; + max_idx = 1; + } + str[2] = "ptr2 "; + print_it("BF_encrypt_ptr2 ", 2); + if (max < tm[2]) { + max = tm[2]; + max_idx = 2; + } + + printf("options BF ecb/s\n"); + printf("%s %12.2f 100.0%%\n", str[max_idx], tm[max_idx]); + d = tm[max_idx]; + tm[max_idx] = -2.0; + max = -1.0; + for (;;) { + for (i = 0; i < 3; i++) { + if (max < tm[i]) { + max = tm[i]; + j = i; + } + } + if (max < 0.0) + break; + printf("%s %12.2f %4.1f%%\n", str[j], tm[j], tm[j] / d * 100.0); + tm[j] = -2.0; + max = -1.0; + } + + switch (max_idx) { + case 0: + printf("-DBF_DEFAULT_OPTIONS\n"); + break; + case 1: + printf("-DBF_PTR\n"); + break; + case 2: + printf("-DBF_PTR2\n"); + break; + } + exit(0); +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS) + return (0); +#endif +} diff --git a/libs/openssl/crypto/bf/bf_pi.h b/libs/openssl/crypto/bf/bf_pi.h new file mode 100644 index 00000000..46a26739 --- /dev/null +++ b/libs/openssl/crypto/bf/bf_pi.h @@ -0,0 +1,579 @@ +/* crypto/bf/bf_pi.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +static const BF_KEY bf_init = { + { + 0x243f6a88L, 0x85a308d3L, 0x13198a2eL, 0x03707344L, + 0xa4093822L, 0x299f31d0L, 0x082efa98L, 0xec4e6c89L, + 0x452821e6L, 0x38d01377L, 0xbe5466cfL, 0x34e90c6cL, + 0xc0ac29b7L, 0xc97c50ddL, 0x3f84d5b5L, 0xb5470917L, + 0x9216d5d9L, 0x8979fb1b}, { + 0xd1310ba6L, 0x98dfb5acL, 0x2ffd72dbL, + 0xd01adfb7L, + 0xb8e1afedL, 0x6a267e96L, 0xba7c9045L, + 0xf12c7f99L, + 0x24a19947L, 0xb3916cf7L, 0x0801f2e2L, + 0x858efc16L, + 0x636920d8L, 0x71574e69L, 0xa458fea3L, + 0xf4933d7eL, + 0x0d95748fL, 0x728eb658L, 0x718bcd58L, + 0x82154aeeL, + 0x7b54a41dL, 0xc25a59b5L, 0x9c30d539L, + 0x2af26013L, + 0xc5d1b023L, 0x286085f0L, 0xca417918L, + 0xb8db38efL, + 0x8e79dcb0L, 0x603a180eL, 0x6c9e0e8bL, + 0xb01e8a3eL, + 0xd71577c1L, 0xbd314b27L, 0x78af2fdaL, + 0x55605c60L, + 0xe65525f3L, 0xaa55ab94L, 0x57489862L, + 0x63e81440L, + 0x55ca396aL, 0x2aab10b6L, 0xb4cc5c34L, + 0x1141e8ceL, + 0xa15486afL, 0x7c72e993L, 0xb3ee1411L, + 0x636fbc2aL, + 0x2ba9c55dL, 0x741831f6L, 0xce5c3e16L, + 0x9b87931eL, + 0xafd6ba33L, 0x6c24cf5cL, 0x7a325381L, + 0x28958677L, + 0x3b8f4898L, 0x6b4bb9afL, 0xc4bfe81bL, + 0x66282193L, + 0x61d809ccL, 0xfb21a991L, 0x487cac60L, + 0x5dec8032L, + 0xef845d5dL, 0xe98575b1L, 0xdc262302L, + 0xeb651b88L, + 0x23893e81L, 0xd396acc5L, 0x0f6d6ff3L, + 0x83f44239L, + 0x2e0b4482L, 0xa4842004L, 0x69c8f04aL, + 0x9e1f9b5eL, + 0x21c66842L, 0xf6e96c9aL, 0x670c9c61L, + 0xabd388f0L, + 0x6a51a0d2L, 0xd8542f68L, 0x960fa728L, + 0xab5133a3L, + 0x6eef0b6cL, 0x137a3be4L, 0xba3bf050L, + 0x7efb2a98L, + 0xa1f1651dL, 0x39af0176L, 0x66ca593eL, + 0x82430e88L, + 0x8cee8619L, 0x456f9fb4L, 0x7d84a5c3L, + 0x3b8b5ebeL, + 0xe06f75d8L, 0x85c12073L, 0x401a449fL, + 0x56c16aa6L, + 0x4ed3aa62L, 0x363f7706L, 0x1bfedf72L, + 0x429b023dL, + 0x37d0d724L, 0xd00a1248L, 0xdb0fead3L, + 0x49f1c09bL, + 0x075372c9L, 0x80991b7bL, 0x25d479d8L, + 0xf6e8def7L, + 0xe3fe501aL, 0xb6794c3bL, 0x976ce0bdL, + 0x04c006baL, + 0xc1a94fb6L, 0x409f60c4L, 0x5e5c9ec2L, + 0x196a2463L, + 0x68fb6fafL, 0x3e6c53b5L, 0x1339b2ebL, + 0x3b52ec6fL, + 0x6dfc511fL, 0x9b30952cL, 0xcc814544L, + 0xaf5ebd09L, + 0xbee3d004L, 0xde334afdL, 0x660f2807L, + 0x192e4bb3L, + 0xc0cba857L, 0x45c8740fL, 0xd20b5f39L, + 0xb9d3fbdbL, + 0x5579c0bdL, 0x1a60320aL, 0xd6a100c6L, + 0x402c7279L, + 0x679f25feL, 0xfb1fa3ccL, 0x8ea5e9f8L, + 0xdb3222f8L, + 0x3c7516dfL, 0xfd616b15L, 0x2f501ec8L, + 0xad0552abL, + 0x323db5faL, 0xfd238760L, 0x53317b48L, + 0x3e00df82L, + 0x9e5c57bbL, 0xca6f8ca0L, 0x1a87562eL, + 0xdf1769dbL, + 0xd542a8f6L, 0x287effc3L, 0xac6732c6L, + 0x8c4f5573L, + 0x695b27b0L, 0xbbca58c8L, 0xe1ffa35dL, + 0xb8f011a0L, + 0x10fa3d98L, 0xfd2183b8L, 0x4afcb56cL, + 0x2dd1d35bL, + 0x9a53e479L, 0xb6f84565L, 0xd28e49bcL, + 0x4bfb9790L, + 0xe1ddf2daL, 0xa4cb7e33L, 0x62fb1341L, + 0xcee4c6e8L, + 0xef20cadaL, 0x36774c01L, 0xd07e9efeL, + 0x2bf11fb4L, + 0x95dbda4dL, 0xae909198L, 0xeaad8e71L, + 0x6b93d5a0L, + 0xd08ed1d0L, 0xafc725e0L, 0x8e3c5b2fL, + 0x8e7594b7L, + 0x8ff6e2fbL, 0xf2122b64L, 0x8888b812L, + 0x900df01cL, + 0x4fad5ea0L, 0x688fc31cL, 0xd1cff191L, + 0xb3a8c1adL, + 0x2f2f2218L, 0xbe0e1777L, 0xea752dfeL, + 0x8b021fa1L, + 0xe5a0cc0fL, 0xb56f74e8L, 0x18acf3d6L, + 0xce89e299L, + 0xb4a84fe0L, 0xfd13e0b7L, 0x7cc43b81L, + 0xd2ada8d9L, + 0x165fa266L, 0x80957705L, 0x93cc7314L, + 0x211a1477L, + 0xe6ad2065L, 0x77b5fa86L, 0xc75442f5L, + 0xfb9d35cfL, + 0xebcdaf0cL, 0x7b3e89a0L, 0xd6411bd3L, + 0xae1e7e49L, + 0x00250e2dL, 0x2071b35eL, 0x226800bbL, + 0x57b8e0afL, + 0x2464369bL, 0xf009b91eL, 0x5563911dL, + 0x59dfa6aaL, + 0x78c14389L, 0xd95a537fL, 0x207d5ba2L, + 0x02e5b9c5L, + 0x83260376L, 0x6295cfa9L, 0x11c81968L, + 0x4e734a41L, + 0xb3472dcaL, 0x7b14a94aL, 0x1b510052L, + 0x9a532915L, + 0xd60f573fL, 0xbc9bc6e4L, 0x2b60a476L, + 0x81e67400L, + 0x08ba6fb5L, 0x571be91fL, 0xf296ec6bL, + 0x2a0dd915L, + 0xb6636521L, 0xe7b9f9b6L, 0xff34052eL, + 0xc5855664L, + 0x53b02d5dL, 0xa99f8fa1L, 0x08ba4799L, + 0x6e85076aL, + 0x4b7a70e9L, 0xb5b32944L, 0xdb75092eL, + 0xc4192623L, + 0xad6ea6b0L, 0x49a7df7dL, 0x9cee60b8L, + 0x8fedb266L, + 0xecaa8c71L, 0x699a17ffL, 0x5664526cL, + 0xc2b19ee1L, + 0x193602a5L, 0x75094c29L, 0xa0591340L, + 0xe4183a3eL, + 0x3f54989aL, 0x5b429d65L, 0x6b8fe4d6L, + 0x99f73fd6L, + 0xa1d29c07L, 0xefe830f5L, 0x4d2d38e6L, + 0xf0255dc1L, + 0x4cdd2086L, 0x8470eb26L, 0x6382e9c6L, + 0x021ecc5eL, + 0x09686b3fL, 0x3ebaefc9L, 0x3c971814L, + 0x6b6a70a1L, + 0x687f3584L, 0x52a0e286L, 0xb79c5305L, + 0xaa500737L, + 0x3e07841cL, 0x7fdeae5cL, 0x8e7d44ecL, + 0x5716f2b8L, + 0xb03ada37L, 0xf0500c0dL, 0xf01c1f04L, + 0x0200b3ffL, + 0xae0cf51aL, 0x3cb574b2L, 0x25837a58L, + 0xdc0921bdL, + 0xd19113f9L, 0x7ca92ff6L, 0x94324773L, + 0x22f54701L, + 0x3ae5e581L, 0x37c2dadcL, 0xc8b57634L, + 0x9af3dda7L, + 0xa9446146L, 0x0fd0030eL, 0xecc8c73eL, + 0xa4751e41L, + 0xe238cd99L, 0x3bea0e2fL, 0x3280bba1L, + 0x183eb331L, + 0x4e548b38L, 0x4f6db908L, 0x6f420d03L, + 0xf60a04bfL, + 0x2cb81290L, 0x24977c79L, 0x5679b072L, + 0xbcaf89afL, + 0xde9a771fL, 0xd9930810L, 0xb38bae12L, + 0xdccf3f2eL, + 0x5512721fL, 0x2e6b7124L, 0x501adde6L, + 0x9f84cd87L, + 0x7a584718L, 0x7408da17L, 0xbc9f9abcL, + 0xe94b7d8cL, + 0xec7aec3aL, 0xdb851dfaL, 0x63094366L, + 0xc464c3d2L, + 0xef1c1847L, 0x3215d908L, 0xdd433b37L, + 0x24c2ba16L, + 0x12a14d43L, 0x2a65c451L, 0x50940002L, + 0x133ae4ddL, + 0x71dff89eL, 0x10314e55L, 0x81ac77d6L, + 0x5f11199bL, + 0x043556f1L, 0xd7a3c76bL, 0x3c11183bL, + 0x5924a509L, + 0xf28fe6edL, 0x97f1fbfaL, 0x9ebabf2cL, + 0x1e153c6eL, + 0x86e34570L, 0xeae96fb1L, 0x860e5e0aL, + 0x5a3e2ab3L, + 0x771fe71cL, 0x4e3d06faL, 0x2965dcb9L, + 0x99e71d0fL, + 0x803e89d6L, 0x5266c825L, 0x2e4cc978L, + 0x9c10b36aL, + 0xc6150ebaL, 0x94e2ea78L, 0xa5fc3c53L, + 0x1e0a2df4L, + 0xf2f74ea7L, 0x361d2b3dL, 0x1939260fL, + 0x19c27960L, + 0x5223a708L, 0xf71312b6L, 0xebadfe6eL, + 0xeac31f66L, + 0xe3bc4595L, 0xa67bc883L, 0xb17f37d1L, + 0x018cff28L, + 0xc332ddefL, 0xbe6c5aa5L, 0x65582185L, + 0x68ab9802L, + 0xeecea50fL, 0xdb2f953bL, 0x2aef7dadL, + 0x5b6e2f84L, + 0x1521b628L, 0x29076170L, 0xecdd4775L, + 0x619f1510L, + 0x13cca830L, 0xeb61bd96L, 0x0334fe1eL, + 0xaa0363cfL, + 0xb5735c90L, 0x4c70a239L, 0xd59e9e0bL, + 0xcbaade14L, + 0xeecc86bcL, 0x60622ca7L, 0x9cab5cabL, + 0xb2f3846eL, + 0x648b1eafL, 0x19bdf0caL, 0xa02369b9L, + 0x655abb50L, + 0x40685a32L, 0x3c2ab4b3L, 0x319ee9d5L, + 0xc021b8f7L, + 0x9b540b19L, 0x875fa099L, 0x95f7997eL, + 0x623d7da8L, + 0xf837889aL, 0x97e32d77L, 0x11ed935fL, + 0x16681281L, + 0x0e358829L, 0xc7e61fd6L, 0x96dedfa1L, + 0x7858ba99L, + 0x57f584a5L, 0x1b227263L, 0x9b83c3ffL, + 0x1ac24696L, + 0xcdb30aebL, 0x532e3054L, 0x8fd948e4L, + 0x6dbc3128L, + 0x58ebf2efL, 0x34c6ffeaL, 0xfe28ed61L, + 0xee7c3c73L, + 0x5d4a14d9L, 0xe864b7e3L, 0x42105d14L, + 0x203e13e0L, + 0x45eee2b6L, 0xa3aaabeaL, 0xdb6c4f15L, + 0xfacb4fd0L, + 0xc742f442L, 0xef6abbb5L, 0x654f3b1dL, + 0x41cd2105L, + 0xd81e799eL, 0x86854dc7L, 0xe44b476aL, + 0x3d816250L, + 0xcf62a1f2L, 0x5b8d2646L, 0xfc8883a0L, + 0xc1c7b6a3L, + 0x7f1524c3L, 0x69cb7492L, 0x47848a0bL, + 0x5692b285L, + 0x095bbf00L, 0xad19489dL, 0x1462b174L, + 0x23820e00L, + 0x58428d2aL, 0x0c55f5eaL, 0x1dadf43eL, + 0x233f7061L, + 0x3372f092L, 0x8d937e41L, 0xd65fecf1L, + 0x6c223bdbL, + 0x7cde3759L, 0xcbee7460L, 0x4085f2a7L, + 0xce77326eL, + 0xa6078084L, 0x19f8509eL, 0xe8efd855L, + 0x61d99735L, + 0xa969a7aaL, 0xc50c06c2L, 0x5a04abfcL, + 0x800bcadcL, + 0x9e447a2eL, 0xc3453484L, 0xfdd56705L, + 0x0e1e9ec9L, + 0xdb73dbd3L, 0x105588cdL, 0x675fda79L, + 0xe3674340L, + 0xc5c43465L, 0x713e38d8L, 0x3d28f89eL, + 0xf16dff20L, + 0x153e21e7L, 0x8fb03d4aL, 0xe6e39f2bL, + 0xdb83adf7L, + 0xe93d5a68L, 0x948140f7L, 0xf64c261cL, + 0x94692934L, + 0x411520f7L, 0x7602d4f7L, 0xbcf46b2eL, + 0xd4a20068L, + 0xd4082471L, 0x3320f46aL, 0x43b7d4b7L, + 0x500061afL, + 0x1e39f62eL, 0x97244546L, 0x14214f74L, + 0xbf8b8840L, + 0x4d95fc1dL, 0x96b591afL, 0x70f4ddd3L, + 0x66a02f45L, + 0xbfbc09ecL, 0x03bd9785L, 0x7fac6dd0L, + 0x31cb8504L, + 0x96eb27b3L, 0x55fd3941L, 0xda2547e6L, + 0xabca0a9aL, + 0x28507825L, 0x530429f4L, 0x0a2c86daL, + 0xe9b66dfbL, + 0x68dc1462L, 0xd7486900L, 0x680ec0a4L, + 0x27a18deeL, + 0x4f3ffea2L, 0xe887ad8cL, 0xb58ce006L, + 0x7af4d6b6L, + 0xaace1e7cL, 0xd3375fecL, 0xce78a399L, + 0x406b2a42L, + 0x20fe9e35L, 0xd9f385b9L, 0xee39d7abL, + 0x3b124e8bL, + 0x1dc9faf7L, 0x4b6d1856L, 0x26a36631L, + 0xeae397b2L, + 0x3a6efa74L, 0xdd5b4332L, 0x6841e7f7L, + 0xca7820fbL, + 0xfb0af54eL, 0xd8feb397L, 0x454056acL, + 0xba489527L, + 0x55533a3aL, 0x20838d87L, 0xfe6ba9b7L, + 0xd096954bL, + 0x55a867bcL, 0xa1159a58L, 0xcca92963L, + 0x99e1db33L, + 0xa62a4a56L, 0x3f3125f9L, 0x5ef47e1cL, + 0x9029317cL, + 0xfdf8e802L, 0x04272f70L, 0x80bb155cL, + 0x05282ce3L, + 0x95c11548L, 0xe4c66d22L, 0x48c1133fL, + 0xc70f86dcL, + 0x07f9c9eeL, 0x41041f0fL, 0x404779a4L, + 0x5d886e17L, + 0x325f51ebL, 0xd59bc0d1L, 0xf2bcc18fL, + 0x41113564L, + 0x257b7834L, 0x602a9c60L, 0xdff8e8a3L, + 0x1f636c1bL, + 0x0e12b4c2L, 0x02e1329eL, 0xaf664fd1L, + 0xcad18115L, + 0x6b2395e0L, 0x333e92e1L, 0x3b240b62L, + 0xeebeb922L, + 0x85b2a20eL, 0xe6ba0d99L, 0xde720c8cL, + 0x2da2f728L, + 0xd0127845L, 0x95b794fdL, 0x647d0862L, + 0xe7ccf5f0L, + 0x5449a36fL, 0x877d48faL, 0xc39dfd27L, + 0xf33e8d1eL, + 0x0a476341L, 0x992eff74L, 0x3a6f6eabL, + 0xf4f8fd37L, + 0xa812dc60L, 0xa1ebddf8L, 0x991be14cL, + 0xdb6e6b0dL, + 0xc67b5510L, 0x6d672c37L, 0x2765d43bL, + 0xdcd0e804L, + 0xf1290dc7L, 0xcc00ffa3L, 0xb5390f92L, + 0x690fed0bL, + 0x667b9ffbL, 0xcedb7d9cL, 0xa091cf0bL, + 0xd9155ea3L, + 0xbb132f88L, 0x515bad24L, 0x7b9479bfL, + 0x763bd6ebL, + 0x37392eb3L, 0xcc115979L, 0x8026e297L, + 0xf42e312dL, + 0x6842ada7L, 0xc66a2b3bL, 0x12754cccL, + 0x782ef11cL, + 0x6a124237L, 0xb79251e7L, 0x06a1bbe6L, + 0x4bfb6350L, + 0x1a6b1018L, 0x11caedfaL, 0x3d25bdd8L, + 0xe2e1c3c9L, + 0x44421659L, 0x0a121386L, 0xd90cec6eL, + 0xd5abea2aL, + 0x64af674eL, 0xda86a85fL, 0xbebfe988L, + 0x64e4c3feL, + 0x9dbc8057L, 0xf0f7c086L, 0x60787bf8L, + 0x6003604dL, + 0xd1fd8346L, 0xf6381fb0L, 0x7745ae04L, + 0xd736fcccL, + 0x83426b33L, 0xf01eab71L, 0xb0804187L, + 0x3c005e5fL, + 0x77a057beL, 0xbde8ae24L, 0x55464299L, + 0xbf582e61L, + 0x4e58f48fL, 0xf2ddfda2L, 0xf474ef38L, + 0x8789bdc2L, + 0x5366f9c3L, 0xc8b38e74L, 0xb475f255L, + 0x46fcd9b9L, + 0x7aeb2661L, 0x8b1ddf84L, 0x846a0e79L, + 0x915f95e2L, + 0x466e598eL, 0x20b45770L, 0x8cd55591L, + 0xc902de4cL, + 0xb90bace1L, 0xbb8205d0L, 0x11a86248L, + 0x7574a99eL, + 0xb77f19b6L, 0xe0a9dc09L, 0x662d09a1L, + 0xc4324633L, + 0xe85a1f02L, 0x09f0be8cL, 0x4a99a025L, + 0x1d6efe10L, + 0x1ab93d1dL, 0x0ba5a4dfL, 0xa186f20fL, + 0x2868f169L, + 0xdcb7da83L, 0x573906feL, 0xa1e2ce9bL, + 0x4fcd7f52L, + 0x50115e01L, 0xa70683faL, 0xa002b5c4L, + 0x0de6d027L, + 0x9af88c27L, 0x773f8641L, 0xc3604c06L, + 0x61a806b5L, + 0xf0177a28L, 0xc0f586e0L, 0x006058aaL, + 0x30dc7d62L, + 0x11e69ed7L, 0x2338ea63L, 0x53c2dd94L, + 0xc2c21634L, + 0xbbcbee56L, 0x90bcb6deL, 0xebfc7da1L, + 0xce591d76L, + 0x6f05e409L, 0x4b7c0188L, 0x39720a3dL, + 0x7c927c24L, + 0x86e3725fL, 0x724d9db9L, 0x1ac15bb4L, + 0xd39eb8fcL, + 0xed545578L, 0x08fca5b5L, 0xd83d7cd3L, + 0x4dad0fc4L, + 0x1e50ef5eL, 0xb161e6f8L, 0xa28514d9L, + 0x6c51133cL, + 0x6fd5c7e7L, 0x56e14ec4L, 0x362abfceL, + 0xddc6c837L, + 0xd79a3234L, 0x92638212L, 0x670efa8eL, + 0x406000e0L, + 0x3a39ce37L, 0xd3faf5cfL, 0xabc27737L, + 0x5ac52d1bL, + 0x5cb0679eL, 0x4fa33742L, 0xd3822740L, + 0x99bc9bbeL, + 0xd5118e9dL, 0xbf0f7315L, 0xd62d1c7eL, + 0xc700c47bL, + 0xb78c1b6bL, 0x21a19045L, 0xb26eb1beL, + 0x6a366eb4L, + 0x5748ab2fL, 0xbc946e79L, 0xc6a376d2L, + 0x6549c2c8L, + 0x530ff8eeL, 0x468dde7dL, 0xd5730a1dL, + 0x4cd04dc6L, + 0x2939bbdbL, 0xa9ba4650L, 0xac9526e8L, + 0xbe5ee304L, + 0xa1fad5f0L, 0x6a2d519aL, 0x63ef8ce2L, + 0x9a86ee22L, + 0xc089c2b8L, 0x43242ef6L, 0xa51e03aaL, + 0x9cf2d0a4L, + 0x83c061baL, 0x9be96a4dL, 0x8fe51550L, + 0xba645bd6L, + 0x2826a2f9L, 0xa73a3ae1L, 0x4ba99586L, + 0xef5562e9L, + 0xc72fefd3L, 0xf752f7daL, 0x3f046f69L, + 0x77fa0a59L, + 0x80e4a915L, 0x87b08601L, 0x9b09e6adL, + 0x3b3ee593L, + 0xe990fd5aL, 0x9e34d797L, 0x2cf0b7d9L, + 0x022b8b51L, + 0x96d5ac3aL, 0x017da67dL, 0xd1cf3ed6L, + 0x7c7d2d28L, + 0x1f9f25cfL, 0xadf2b89bL, 0x5ad6b472L, + 0x5a88f54cL, + 0xe029ac71L, 0xe019a5e6L, 0x47b0acfdL, + 0xed93fa9bL, + 0xe8d3c48dL, 0x283b57ccL, 0xf8d56629L, + 0x79132e28L, + 0x785f0191L, 0xed756055L, 0xf7960e44L, + 0xe3d35e8cL, + 0x15056dd4L, 0x88f46dbaL, 0x03a16125L, + 0x0564f0bdL, + 0xc3eb9e15L, 0x3c9057a2L, 0x97271aecL, + 0xa93a072aL, + 0x1b3f6d9bL, 0x1e6321f5L, 0xf59c66fbL, + 0x26dcf319L, + 0x7533d928L, 0xb155fdf5L, 0x03563482L, + 0x8aba3cbbL, + 0x28517711L, 0xc20ad9f8L, 0xabcc5167L, + 0xccad925fL, + 0x4de81751L, 0x3830dc8eL, 0x379d5862L, + 0x9320f991L, + 0xea7a90c2L, 0xfb3e7bceL, 0x5121ce64L, + 0x774fbe32L, + 0xa8b6e37eL, 0xc3293d46L, 0x48de5369L, + 0x6413e680L, + 0xa2ae0810L, 0xdd6db224L, 0x69852dfdL, + 0x09072166L, + 0xb39a460aL, 0x6445c0ddL, 0x586cdecfL, + 0x1c20c8aeL, + 0x5bbef7ddL, 0x1b588d40L, 0xccd2017fL, + 0x6bb4e3bbL, + 0xdda26a7eL, 0x3a59ff45L, 0x3e350a44L, + 0xbcb4cdd5L, + 0x72eacea8L, 0xfa6484bbL, 0x8d6612aeL, + 0xbf3c6f47L, + 0xd29be463L, 0x542f5d9eL, 0xaec2771bL, + 0xf64e6370L, + 0x740e0d8dL, 0xe75b1357L, 0xf8721671L, + 0xaf537d5dL, + 0x4040cb08L, 0x4eb4e2ccL, 0x34d2466aL, + 0x0115af84L, + 0xe1b00428L, 0x95983a1dL, 0x06b89fb4L, + 0xce6ea048L, + 0x6f3f3b82L, 0x3520ab82L, 0x011a1d4bL, + 0x277227f8L, + 0x611560b1L, 0xe7933fdcL, 0xbb3a792bL, + 0x344525bdL, + 0xa08839e1L, 0x51ce794bL, 0x2f32c9b7L, + 0xa01fbac9L, + 0xe01cc87eL, 0xbcc7d1f6L, 0xcf0111c3L, + 0xa1e8aac7L, + 0x1a908749L, 0xd44fbd9aL, 0xd0dadecbL, + 0xd50ada38L, + 0x0339c32aL, 0xc6913667L, 0x8df9317cL, + 0xe0b12b4fL, + 0xf79e59b7L, 0x43f5bb3aL, 0xf2d519ffL, + 0x27d9459cL, + 0xbf97222cL, 0x15e6fc2aL, 0x0f91fc71L, + 0x9b941525L, + 0xfae59361L, 0xceb69cebL, 0xc2a86459L, + 0x12baa8d1L, + 0xb6c1075eL, 0xe3056a0cL, 0x10d25065L, + 0xcb03a442L, + 0xe0ec6e0eL, 0x1698db3bL, 0x4c98a0beL, + 0x3278e964L, + 0x9f1f9532L, 0xe0d392dfL, 0xd3a0342bL, + 0x8971f21eL, + 0x1b0a7441L, 0x4ba3348cL, 0xc5be7120L, + 0xc37632d8L, + 0xdf359f8dL, 0x9b992f2eL, 0xe60b6f47L, + 0x0fe3f11dL, + 0xe54cda54L, 0x1edad891L, 0xce6279cfL, + 0xcd3e7e6fL, + 0x1618b166L, 0xfd2c1d05L, 0x848fd2c5L, + 0xf6fb2299L, + 0xf523f357L, 0xa6327623L, 0x93a83531L, + 0x56cccd02L, + 0xacf08162L, 0x5a75ebb5L, 0x6e163697L, + 0x88d273ccL, + 0xde966292L, 0x81b949d0L, 0x4c50901bL, + 0x71c65614L, + 0xe6c6c7bdL, 0x327a140aL, 0x45e1d006L, + 0xc3f27b9aL, + 0xc9aa53fdL, 0x62a80f00L, 0xbb25bfe2L, + 0x35bdd2f6L, + 0x71126905L, 0xb2040222L, 0xb6cbcf7cL, + 0xcd769c2bL, + 0x53113ec0L, 0x1640e3d3L, 0x38abbd60L, + 0x2547adf0L, + 0xba38209cL, 0xf746ce76L, 0x77afa1c5L, + 0x20756060L, + 0x85cbfe4eL, 0x8ae88dd8L, 0x7aaaf9b0L, + 0x4cf9aa7eL, + 0x1948c25cL, 0x02fb8a8cL, 0x01c36ae4L, + 0xd6ebe1f9L, + 0x90d4f869L, 0xa65cdea0L, 0x3f09252dL, + 0xc208e69fL, + 0xb74e6132L, 0xce77e25bL, 0x578fdfe3L, + 0x3ac372e6L, + } +}; diff --git a/libs/openssl/crypto/bf/bf_skey.c b/libs/openssl/crypto/bf/bf_skey.c new file mode 100644 index 00000000..2cb3c66c --- /dev/null +++ b/libs/openssl/crypto/bf/bf_skey.c @@ -0,0 +1,125 @@ +/* crypto/bf/bf_skey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include "bf_locl.h" +#include "bf_pi.h" + +void BF_set_key(BF_KEY *key, int len, const unsigned char *data) +#ifdef OPENSSL_FIPS +{ + fips_cipher_abort(BLOWFISH); + private_BF_set_key(key, len, data); +} + +void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data) +#endif +{ + int i; + BF_LONG *p, ri, in[2]; + const unsigned char *d, *end; + + memcpy(key, &bf_init, sizeof(BF_KEY)); + p = key->P; + + if (len > ((BF_ROUNDS + 2) * 4)) + len = (BF_ROUNDS + 2) * 4; + + d = data; + end = &(data[len]); + for (i = 0; i < (BF_ROUNDS + 2); i++) { + ri = *(d++); + if (d >= end) + d = data; + + ri <<= 8; + ri |= *(d++); + if (d >= end) + d = data; + + ri <<= 8; + ri |= *(d++); + if (d >= end) + d = data; + + ri <<= 8; + ri |= *(d++); + if (d >= end) + d = data; + + p[i] ^= ri; + } + + in[0] = 0L; + in[1] = 0L; + for (i = 0; i < (BF_ROUNDS + 2); i += 2) { + BF_encrypt(in, key); + p[i] = in[0]; + p[i + 1] = in[1]; + } + + p = key->S; + for (i = 0; i < 4 * 256; i += 2) { + BF_encrypt(in, key); + p[i] = in[0]; + p[i + 1] = in[1]; + } +} diff --git a/libs/openssl/crypto/bf/bfs.cpp b/libs/openssl/crypto/bf/bfs.cpp new file mode 100644 index 00000000..d74c4577 --- /dev/null +++ b/libs/openssl/crypto/bf/bfs.cpp @@ -0,0 +1,67 @@ +// +// gettsc.inl +// +// gives access to the Pentium's (secret) cycle counter +// +// This software was written by Leonard Janke (janke@unixg.ubc.ca) +// in 1996-7 and is entered, by him, into the public domain. + +#if defined(__WATCOMC__) +void GetTSC(unsigned long&); +#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax]; +#elif defined(__GNUC__) +inline +void GetTSC(unsigned long& tsc) +{ + asm volatile(".byte 15, 49\n\t" + : "=eax" (tsc) + : + : "%edx", "%eax"); +} +#elif defined(_MSC_VER) +inline +void GetTSC(unsigned long& tsc) +{ + unsigned long a; + __asm _emit 0fh + __asm _emit 31h + __asm mov a, eax; + tsc=a; +} +#endif + +#include +#include +#include + +void main(int argc,char *argv[]) + { + BF_KEY key; + unsigned long s1,s2,e1,e2; + unsigned long data[2]; + int i,j; + + for (j=0; j<6; j++) + { + for (i=0; i<1000; i++) /**/ + { + BF_encrypt(&data[0],&key); + GetTSC(s1); + BF_encrypt(&data[0],&key); + BF_encrypt(&data[0],&key); + BF_encrypt(&data[0],&key); + GetTSC(e1); + GetTSC(s2); + BF_encrypt(&data[0],&key); + BF_encrypt(&data[0],&key); + BF_encrypt(&data[0],&key); + BF_encrypt(&data[0],&key); + GetTSC(e2); + BF_encrypt(&data[0],&key); + } + + printf("blowfish %d %d (%d)\n", + e1-s1,e2-s2,((e2-s2)-(e1-s1))); + } + } + diff --git a/libs/openssl/crypto/bf/bfspeed.c b/libs/openssl/crypto/bf/bfspeed.c new file mode 100644 index 00000000..305ad8bc --- /dev/null +++ b/libs/openssl/crypto/bf/bfspeed.c @@ -0,0 +1,265 @@ +/* crypto/bf/bfspeed.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */ +/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */ + +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX) +# define TIMES +#endif + +#include + +#include +#include OPENSSL_UNISTD_IO +OPENSSL_DECLARE_EXIT +#ifndef OPENSSL_SYS_NETWARE +# include +#endif +#ifndef _IRIX +# include +#endif +#ifdef TIMES +# include +# include +#endif + /* + * Depending on the VMS version, the tms structure is perhaps defined. + * The __TMS macro will show if it was. If it wasn't defined, we should + * undefine TIMES, since that tells the rest of the program how things + * should be handled. -- Richard Levitte + */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) +# undef TIMES +#endif +#ifndef TIMES +# include +#endif +#if defined(sun) || defined(__ultrix) +# define _POSIX_SOURCE +# include +# include +#endif +#include +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# define HZ 100.0 +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +#endif +#define BUFSIZE ((long)1024) +long run = 0; + +double Time_F(int s); +#ifdef SIGALRM +# if defined(__STDC__) || defined(sgi) || defined(_AIX) +# define SIGRETTYPE void +# else +# define SIGRETTYPE int +# endif + +SIGRETTYPE sig_done(int sig); +SIGRETTYPE sig_done(int sig) +{ + signal(SIGALRM, sig_done); + run = 0; +# ifdef LINT + sig = sig; +# endif +} +#endif + +#define START 0 +#define STOP 1 + +double Time_F(int s) +{ + double ret; +#ifdef TIMES + static struct tms tstart, tend; + + if (s == START) { + times(&tstart); + return (0); + } else { + times(&tend); + ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ; + return ((ret == 0.0) ? 1e-6 : ret); + } +#else /* !times() */ + static struct timeb tstart, tend; + long i; + + if (s == START) { + ftime(&tstart); + return (0); + } else { + ftime(&tend); + i = (long)tend.millitm - (long)tstart.millitm; + ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1e3; + return ((ret == 0.0) ? 1e-6 : ret); + } +#endif +} + +int main(int argc, char **argv) +{ + long count; + static unsigned char buf[BUFSIZE]; + static unsigned char key[] = { + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + BF_KEY sch; + double a, b, c, d; +#ifndef SIGALRM + long ca, cb, cc; +#endif + +#ifndef TIMES + printf("To get the most accurate results, try to run this\n"); + printf("program when this computer is idle.\n"); +#endif + +#ifndef SIGALRM + printf("First we calculate the approximate speed ...\n"); + BF_set_key(&sch, 16, key); + count = 10; + do { + long i; + BF_LONG data[2]; + + count *= 2; + Time_F(START); + for (i = count; i; i--) + BF_encrypt(data, &sch); + d = Time_F(STOP); + } while (d < 3.0); + ca = count / 512; + cb = count; + cc = count * 8 / BUFSIZE + 1; + printf("Doing BF_set_key %ld times\n", ca); +# define COND(d) (count != (d)) +# define COUNT(d) (d) +#else +# define COND(c) (run) +# define COUNT(d) (count) + signal(SIGALRM, sig_done); + printf("Doing BF_set_key for 10 seconds\n"); + alarm(10); +#endif + + Time_F(START); + for (count = 0, run = 1; COND(ca); count += 4) { + BF_set_key(&sch, 16, key); + BF_set_key(&sch, 16, key); + BF_set_key(&sch, 16, key); + BF_set_key(&sch, 16, key); + } + d = Time_F(STOP); + printf("%ld BF_set_key's in %.2f seconds\n", count, d); + a = ((double)COUNT(ca)) / d; + +#ifdef SIGALRM + printf("Doing BF_encrypt's for 10 seconds\n"); + alarm(10); +#else + printf("Doing BF_encrypt %ld times\n", cb); +#endif + Time_F(START); + for (count = 0, run = 1; COND(cb); count += 4) { + BF_LONG data[2]; + + BF_encrypt(data, &sch); + BF_encrypt(data, &sch); + BF_encrypt(data, &sch); + BF_encrypt(data, &sch); + } + d = Time_F(STOP); + printf("%ld BF_encrypt's in %.2f second\n", count, d); + b = ((double)COUNT(cb) * 8) / d; + +#ifdef SIGALRM + printf("Doing BF_cbc_encrypt on %ld byte blocks for 10 seconds\n", + BUFSIZE); + alarm(10); +#else + printf("Doing BF_cbc_encrypt %ld times on %ld byte blocks\n", cc, + BUFSIZE); +#endif + Time_F(START); + for (count = 0, run = 1; COND(cc); count++) + BF_cbc_encrypt(buf, buf, BUFSIZE, &sch, &(key[0]), BF_ENCRYPT); + d = Time_F(STOP); + printf("%ld BF_cbc_encrypt's of %ld byte blocks in %.2f second\n", + count, BUFSIZE, d); + c = ((double)COUNT(cc) * BUFSIZE) / d; + + printf("Blowfish set_key per sec = %12.3f (%9.3fuS)\n", a, + 1.0e6 / a); + printf("Blowfish raw ecb bytes per sec = %12.3f (%9.3fuS)\n", b, + 8.0e6 / b); + printf("Blowfish cbc bytes per sec = %12.3f (%9.3fuS)\n", c, + 8.0e6 / c); + exit(0); +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS) + return (0); +#endif +} diff --git a/libs/openssl/crypto/bf/bftest.c b/libs/openssl/crypto/bf/bftest.c new file mode 100644 index 00000000..0b008f09 --- /dev/null +++ b/libs/openssl/crypto/bf/bftest.c @@ -0,0 +1,538 @@ +/* crypto/bf/bftest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * This has been a quickly hacked 'ideatest.c'. When I add tests for other + * RC2 modes, more of the code will be uncommented. + */ + +#include +#include +#include +#include /* To see if OPENSSL_NO_BF is defined */ + +#include "../e_os.h" + +#ifdef OPENSSL_NO_BF +int main(int argc, char *argv[]) +{ + printf("No BF support\n"); + return (0); +} +#else +# include + +# ifdef CHARSET_EBCDIC +# include +# endif + +static char *bf_key[2] = { + "abcdefghijklmnopqrstuvwxyz", + "Who is John Galt?" +}; + +/* big endian */ +static BF_LONG bf_plain[2][2] = { + {0x424c4f57L, 0x46495348L}, + {0xfedcba98L, 0x76543210L} +}; + +static BF_LONG bf_cipher[2][2] = { + {0x324ed0feL, 0xf413a203L}, + {0xcc91732bL, 0x8022f684L} +}; + +/************/ + +/* Lets use the DES test vectors :-) */ +# define NUM_TESTS 34 +static unsigned char ecb_data[NUM_TESTS][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}, + {0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57}, + {0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E}, + {0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86}, + {0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E}, + {0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6}, + {0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE}, + {0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6}, + {0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE}, + {0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16}, + {0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F}, + {0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46}, + {0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E}, + {0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76}, + {0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07}, + {0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F}, + {0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7}, + {0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF}, + {0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6}, + {0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF}, + {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E}, + {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10} +}; + +static unsigned char plain_data[NUM_TESTS][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42}, + {0x5C, 0xD5, 0x4C, 0xA8, 0x3D, 0xEF, 0x57, 0xDA}, + {0x02, 0x48, 0xD4, 0x38, 0x06, 0xF6, 0x71, 0x72}, + {0x51, 0x45, 0x4B, 0x58, 0x2D, 0xDF, 0x44, 0x0A}, + {0x42, 0xFD, 0x44, 0x30, 0x59, 0x57, 0x7F, 0xA2}, + {0x05, 0x9B, 0x5E, 0x08, 0x51, 0xCF, 0x14, 0x3A}, + {0x07, 0x56, 0xD8, 0xE0, 0x77, 0x47, 0x61, 0xD2}, + {0x76, 0x25, 0x14, 0xB8, 0x29, 0xBF, 0x48, 0x6A}, + {0x3B, 0xDD, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02}, + {0x26, 0x95, 0x5F, 0x68, 0x35, 0xAF, 0x60, 0x9A}, + {0x16, 0x4D, 0x5E, 0x40, 0x4F, 0x27, 0x52, 0x32}, + {0x6B, 0x05, 0x6E, 0x18, 0x75, 0x9F, 0x5C, 0xCA}, + {0x00, 0x4B, 0xD6, 0xEF, 0x09, 0x17, 0x60, 0x62}, + {0x48, 0x0D, 0x39, 0x00, 0x6E, 0xE7, 0x62, 0xF2}, + {0x43, 0x75, 0x40, 0xC8, 0x69, 0x8F, 0x3C, 0xFA}, + {0x07, 0x2D, 0x43, 0xA0, 0x77, 0x07, 0x52, 0x92}, + {0x02, 0xFE, 0x55, 0x77, 0x81, 0x17, 0xF1, 0x2A}, + {0x1D, 0x9D, 0x5C, 0x50, 0x18, 0xF7, 0x28, 0xC2}, + {0x30, 0x55, 0x32, 0x28, 0x6D, 0x6F, 0x29, 0x5A}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} +}; + +static unsigned char cipher_data[NUM_TESTS][8] = { + {0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}, + {0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A}, + {0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2}, + {0x24, 0x66, 0xDD, 0x87, 0x8B, 0x96, 0x3C, 0x9D}, + {0x61, 0xF9, 0xC3, 0x80, 0x22, 0x81, 0xB0, 0x96}, + {0x7D, 0x0C, 0xC6, 0x30, 0xAF, 0xDA, 0x1E, 0xC7}, + {0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}, + {0x0A, 0xCE, 0xAB, 0x0F, 0xC6, 0xA0, 0xA2, 0x8D}, + {0x59, 0xC6, 0x82, 0x45, 0xEB, 0x05, 0x28, 0x2B}, + {0xB1, 0xB8, 0xCC, 0x0B, 0x25, 0x0F, 0x09, 0xA0}, + {0x17, 0x30, 0xE5, 0x77, 0x8B, 0xEA, 0x1D, 0xA4}, + {0xA2, 0x5E, 0x78, 0x56, 0xCF, 0x26, 0x51, 0xEB}, + {0x35, 0x38, 0x82, 0xB1, 0x09, 0xCE, 0x8F, 0x1A}, + {0x48, 0xF4, 0xD0, 0x88, 0x4C, 0x37, 0x99, 0x18}, + {0x43, 0x21, 0x93, 0xB7, 0x89, 0x51, 0xFC, 0x98}, + {0x13, 0xF0, 0x41, 0x54, 0xD6, 0x9D, 0x1A, 0xE5}, + {0x2E, 0xED, 0xDA, 0x93, 0xFF, 0xD3, 0x9C, 0x79}, + {0xD8, 0x87, 0xE0, 0x39, 0x3C, 0x2D, 0xA6, 0xE3}, + {0x5F, 0x99, 0xD0, 0x4F, 0x5B, 0x16, 0x39, 0x69}, + {0x4A, 0x05, 0x7A, 0x3B, 0x24, 0xD3, 0x97, 0x7B}, + {0x45, 0x20, 0x31, 0xC1, 0xE4, 0xFA, 0xDA, 0x8E}, + {0x75, 0x55, 0xAE, 0x39, 0xF5, 0x9B, 0x87, 0xBD}, + {0x53, 0xC5, 0x5F, 0x9C, 0xB4, 0x9F, 0xC0, 0x19}, + {0x7A, 0x8E, 0x7B, 0xFA, 0x93, 0x7E, 0x89, 0xA3}, + {0xCF, 0x9C, 0x5D, 0x7A, 0x49, 0x86, 0xAD, 0xB5}, + {0xD1, 0xAB, 0xB2, 0x90, 0x65, 0x8B, 0xC7, 0x78}, + {0x55, 0xCB, 0x37, 0x74, 0xD1, 0x3E, 0xF2, 0x01}, + {0xFA, 0x34, 0xEC, 0x48, 0x47, 0xB2, 0x68, 0xB2}, + {0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE}, + {0xC3, 0x9E, 0x07, 0x2D, 0x9F, 0xAC, 0x63, 0x1D}, + {0x01, 0x49, 0x33, 0xE0, 0xCD, 0xAF, 0xF6, 0xE4}, + {0xF2, 0x1E, 0x9A, 0x77, 0xB7, 0x1C, 0x49, 0xBC}, + {0x24, 0x59, 0x46, 0x88, 0x57, 0x54, 0x36, 0x9A}, + {0x6B, 0x5C, 0x5A, 0x9C, 0x5D, 0x9E, 0x0A, 0x5A}, +}; + +static unsigned char cbc_key[16] = { + 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, + 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 +}; +static unsigned char cbc_iv[8] = + { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }; +static char cbc_data[40] = "7654321 Now is the time for "; +static unsigned char cbc_ok[32] = { + 0x6B, 0x77, 0xB4, 0xD6, 0x30, 0x06, 0xDE, 0xE6, + 0x05, 0xB1, 0x56, 0xE2, 0x74, 0x03, 0x97, 0x93, + 0x58, 0xDE, 0xB9, 0xE7, 0x15, 0x46, 0x16, 0xD9, + 0x59, 0xF1, 0x65, 0x2B, 0xD5, 0xFF, 0x92, 0xCC +}; + +static unsigned char cfb64_ok[] = { + 0xE7, 0x32, 0x14, 0xA2, 0x82, 0x21, 0x39, 0xCA, + 0xF2, 0x6E, 0xCF, 0x6D, 0x2E, 0xB9, 0xE7, 0x6E, + 0x3D, 0xA3, 0xDE, 0x04, 0xD1, 0x51, 0x72, 0x00, + 0x51, 0x9D, 0x57, 0xA6, 0xC3 +}; + +static unsigned char ofb64_ok[] = { + 0xE7, 0x32, 0x14, 0xA2, 0x82, 0x21, 0x39, 0xCA, + 0x62, 0xB3, 0x43, 0xCC, 0x5B, 0x65, 0x58, 0x73, + 0x10, 0xDD, 0x90, 0x8D, 0x0C, 0x24, 0x1B, 0x22, + 0x63, 0xC2, 0xCF, 0x80, 0xDA +}; + +# define KEY_TEST_NUM 25 +static unsigned char key_test[KEY_TEST_NUM] = { + 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87, + 0x78, 0x69, 0x5a, 0x4b, 0x3c, 0x2d, 0x1e, 0x0f, + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88 +}; + +static unsigned char key_data[8] = + { 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10 }; + +static unsigned char key_out[KEY_TEST_NUM][8] = { + {0xF9, 0xAD, 0x59, 0x7C, 0x49, 0xDB, 0x00, 0x5E}, + {0xE9, 0x1D, 0x21, 0xC1, 0xD9, 0x61, 0xA6, 0xD6}, + {0xE9, 0xC2, 0xB7, 0x0A, 0x1B, 0xC6, 0x5C, 0xF3}, + {0xBE, 0x1E, 0x63, 0x94, 0x08, 0x64, 0x0F, 0x05}, + {0xB3, 0x9E, 0x44, 0x48, 0x1B, 0xDB, 0x1E, 0x6E}, + {0x94, 0x57, 0xAA, 0x83, 0xB1, 0x92, 0x8C, 0x0D}, + {0x8B, 0xB7, 0x70, 0x32, 0xF9, 0x60, 0x62, 0x9D}, + {0xE8, 0x7A, 0x24, 0x4E, 0x2C, 0xC8, 0x5E, 0x82}, + {0x15, 0x75, 0x0E, 0x7A, 0x4F, 0x4E, 0xC5, 0x77}, + {0x12, 0x2B, 0xA7, 0x0B, 0x3A, 0xB6, 0x4A, 0xE0}, + {0x3A, 0x83, 0x3C, 0x9A, 0xFF, 0xC5, 0x37, 0xF6}, + {0x94, 0x09, 0xDA, 0x87, 0xA9, 0x0F, 0x6B, 0xF2}, + {0x88, 0x4F, 0x80, 0x62, 0x50, 0x60, 0xB8, 0xB4}, + {0x1F, 0x85, 0x03, 0x1C, 0x19, 0xE1, 0x19, 0x68}, + {0x79, 0xD9, 0x37, 0x3A, 0x71, 0x4C, 0xA3, 0x4F}, + {0x93, 0x14, 0x28, 0x87, 0xEE, 0x3B, 0xE1, 0x5C}, + {0x03, 0x42, 0x9E, 0x83, 0x8C, 0xE2, 0xD1, 0x4B}, + {0xA4, 0x29, 0x9E, 0x27, 0x46, 0x9F, 0xF6, 0x7B}, + {0xAF, 0xD5, 0xAE, 0xD1, 0xC1, 0xBC, 0x96, 0xA8}, + {0x10, 0x85, 0x1C, 0x0E, 0x38, 0x58, 0xDA, 0x9F}, + {0xE6, 0xF5, 0x1E, 0xD7, 0x9B, 0x9D, 0xB2, 0x1F}, + {0x64, 0xA6, 0xE1, 0x4A, 0xFD, 0x36, 0xB4, 0x6F}, + {0x80, 0xC7, 0xD7, 0xD4, 0x5A, 0x54, 0x79, 0xAD}, + {0x05, 0x04, 0x4B, 0x62, 0xFA, 0x52, 0xD0, 0x80}, +}; + +static int test(void); +static int print_test_data(void); +int main(int argc, char *argv[]) +{ + int ret; + + if (argc > 1) + ret = print_test_data(); + else + ret = test(); + +# ifdef OPENSSL_SYS_NETWARE + if (ret) + printf("ERROR: %d\n", ret); +# endif + EXIT(ret); + return (0); +} + +static int print_test_data(void) +{ + unsigned int i, j; + + printf("ecb test data\n"); + printf("key bytes\t\tclear bytes\t\tcipher bytes\n"); + for (i = 0; i < NUM_TESTS; i++) { + for (j = 0; j < 8; j++) + printf("%02X", ecb_data[i][j]); + printf("\t"); + for (j = 0; j < 8; j++) + printf("%02X", plain_data[i][j]); + printf("\t"); + for (j = 0; j < 8; j++) + printf("%02X", cipher_data[i][j]); + printf("\n"); + } + + printf("set_key test data\n"); + printf("data[8]= "); + for (j = 0; j < 8; j++) + printf("%02X", key_data[j]); + printf("\n"); + for (i = 0; i < KEY_TEST_NUM - 1; i++) { + printf("c="); + for (j = 0; j < 8; j++) + printf("%02X", key_out[i][j]); + printf(" k[%2u]=", i + 1); + for (j = 0; j < i + 1; j++) + printf("%02X", key_test[j]); + printf("\n"); + } + + printf("\nchaining mode test data\n"); + printf("key[16] = "); + for (j = 0; j < 16; j++) + printf("%02X", cbc_key[j]); + printf("\niv[8] = "); + for (j = 0; j < 8; j++) + printf("%02X", cbc_iv[j]); + printf("\ndata[%d] = '%s'", (int)strlen(cbc_data) + 1, cbc_data); + printf("\ndata[%d] = ", (int)strlen(cbc_data) + 1); + for (j = 0; j < strlen(cbc_data) + 1; j++) + printf("%02X", cbc_data[j]); + printf("\n"); + printf("cbc cipher text\n"); + printf("cipher[%d]= ", 32); + for (j = 0; j < 32; j++) + printf("%02X", cbc_ok[j]); + printf("\n"); + + printf("cfb64 cipher text\n"); + printf("cipher[%d]= ", (int)strlen(cbc_data) + 1); + for (j = 0; j < strlen(cbc_data) + 1; j++) + printf("%02X", cfb64_ok[j]); + printf("\n"); + + printf("ofb64 cipher text\n"); + printf("cipher[%d]= ", (int)strlen(cbc_data) + 1); + for (j = 0; j < strlen(cbc_data) + 1; j++) + printf("%02X", ofb64_ok[j]); + printf("\n"); + return (0); +} + +static int test(void) +{ + unsigned char cbc_in[40], cbc_out[40], iv[8]; + int i, n, err = 0; + BF_KEY key; + BF_LONG data[2]; + unsigned char out[8]; + BF_LONG len; + +# ifdef CHARSET_EBCDIC + ebcdic2ascii(cbc_data, cbc_data, strlen(cbc_data)); +# endif + + printf("testing blowfish in raw ecb mode\n"); + for (n = 0; n < 2; n++) { +# ifdef CHARSET_EBCDIC + ebcdic2ascii(bf_key[n], bf_key[n], strlen(bf_key[n])); +# endif + BF_set_key(&key, strlen(bf_key[n]), (unsigned char *)bf_key[n]); + + data[0] = bf_plain[n][0]; + data[1] = bf_plain[n][1]; + BF_encrypt(data, &key); + if (memcmp(&(bf_cipher[n][0]), &(data[0]), 8) != 0) { + printf("BF_encrypt error encrypting\n"); + printf("got :"); + for (i = 0; i < 2; i++) + printf("%08lX ", (unsigned long)data[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 2; i++) + printf("%08lX ", (unsigned long)bf_cipher[n][i]); + err = 1; + printf("\n"); + } + + BF_decrypt(&(data[0]), &key); + if (memcmp(&(bf_plain[n][0]), &(data[0]), 8) != 0) { + printf("BF_encrypt error decrypting\n"); + printf("got :"); + for (i = 0; i < 2; i++) + printf("%08lX ", (unsigned long)data[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 2; i++) + printf("%08lX ", (unsigned long)bf_plain[n][i]); + printf("\n"); + err = 1; + } + } + + printf("testing blowfish in ecb mode\n"); + + for (n = 0; n < NUM_TESTS; n++) { + BF_set_key(&key, 8, ecb_data[n]); + + BF_ecb_encrypt(&(plain_data[n][0]), out, &key, BF_ENCRYPT); + if (memcmp(&(cipher_data[n][0]), out, 8) != 0) { + printf("BF_ecb_encrypt blowfish error encrypting\n"); + printf("got :"); + for (i = 0; i < 8; i++) + printf("%02X ", out[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 8; i++) + printf("%02X ", cipher_data[n][i]); + err = 1; + printf("\n"); + } + + BF_ecb_encrypt(out, out, &key, BF_DECRYPT); + if (memcmp(&(plain_data[n][0]), out, 8) != 0) { + printf("BF_ecb_encrypt error decrypting\n"); + printf("got :"); + for (i = 0; i < 8; i++) + printf("%02X ", out[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 8; i++) + printf("%02X ", plain_data[n][i]); + printf("\n"); + err = 1; + } + } + + printf("testing blowfish set_key\n"); + for (n = 1; n < KEY_TEST_NUM; n++) { + BF_set_key(&key, n, key_test); + BF_ecb_encrypt(key_data, out, &key, BF_ENCRYPT); + /* mips-sgi-irix6.5-gcc vv -mabi=64 bug workaround */ + if (memcmp(out, &(key_out[i = n - 1][0]), 8) != 0) { + printf("blowfish setkey error\n"); + err = 1; + } + } + + printf("testing blowfish in cbc mode\n"); + len = strlen(cbc_data) + 1; + + BF_set_key(&key, 16, cbc_key); + memset(cbc_in, 0, sizeof cbc_in); + memset(cbc_out, 0, sizeof cbc_out); + memcpy(iv, cbc_iv, sizeof iv); + BF_cbc_encrypt((unsigned char *)cbc_data, cbc_out, len, + &key, iv, BF_ENCRYPT); + if (memcmp(cbc_out, cbc_ok, 32) != 0) { + err = 1; + printf("BF_cbc_encrypt encrypt error\n"); + for (i = 0; i < 32; i++) + printf("0x%02X,", cbc_out[i]); + } + memcpy(iv, cbc_iv, 8); + BF_cbc_encrypt(cbc_out, cbc_in, len, &key, iv, BF_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen(cbc_data) + 1) != 0) { + printf("BF_cbc_encrypt decrypt error\n"); + err = 1; + } + + printf("testing blowfish in cfb64 mode\n"); + + BF_set_key(&key, 16, cbc_key); + memset(cbc_in, 0, 40); + memset(cbc_out, 0, 40); + memcpy(iv, cbc_iv, 8); + n = 0; + BF_cfb64_encrypt((unsigned char *)cbc_data, cbc_out, (long)13, + &key, iv, &n, BF_ENCRYPT); + BF_cfb64_encrypt((unsigned char *)&(cbc_data[13]), &(cbc_out[13]), + len - 13, &key, iv, &n, BF_ENCRYPT); + if (memcmp(cbc_out, cfb64_ok, (int)len) != 0) { + err = 1; + printf("BF_cfb64_encrypt encrypt error\n"); + for (i = 0; i < (int)len; i++) + printf("0x%02X,", cbc_out[i]); + } + n = 0; + memcpy(iv, cbc_iv, 8); + BF_cfb64_encrypt(cbc_out, cbc_in, 17, &key, iv, &n, BF_DECRYPT); + BF_cfb64_encrypt(&(cbc_out[17]), &(cbc_in[17]), len - 17, + &key, iv, &n, BF_DECRYPT); + if (memcmp(cbc_in, cbc_data, (int)len) != 0) { + printf("BF_cfb64_encrypt decrypt error\n"); + err = 1; + } + + printf("testing blowfish in ofb64\n"); + + BF_set_key(&key, 16, cbc_key); + memset(cbc_in, 0, 40); + memset(cbc_out, 0, 40); + memcpy(iv, cbc_iv, 8); + n = 0; + BF_ofb64_encrypt((unsigned char *)cbc_data, cbc_out, (long)13, &key, iv, + &n); + BF_ofb64_encrypt((unsigned char *)&(cbc_data[13]), &(cbc_out[13]), + len - 13, &key, iv, &n); + if (memcmp(cbc_out, ofb64_ok, (int)len) != 0) { + err = 1; + printf("BF_ofb64_encrypt encrypt error\n"); + for (i = 0; i < (int)len; i++) + printf("0x%02X,", cbc_out[i]); + } + n = 0; + memcpy(iv, cbc_iv, 8); + BF_ofb64_encrypt(cbc_out, cbc_in, 17, &key, iv, &n); + BF_ofb64_encrypt(&(cbc_out[17]), &(cbc_in[17]), len - 17, &key, iv, &n); + if (memcmp(cbc_in, cbc_data, (int)len) != 0) { + printf("BF_ofb64_encrypt decrypt error\n"); + err = 1; + } + + return (err); +} +#endif diff --git a/libs/openssl/crypto/bf/blowfish.h b/libs/openssl/crypto/bf/blowfish.h new file mode 100644 index 00000000..83293027 --- /dev/null +++ b/libs/openssl/crypto/bf/blowfish.h @@ -0,0 +1,130 @@ +/* crypto/bf/blowfish.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BLOWFISH_H +# define HEADER_BLOWFISH_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_BF +# error BF is disabled. +# endif + +# define BF_ENCRYPT 1 +# define BF_DECRYPT 0 + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! BF_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! BF_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +# if defined(__LP32__) +# define BF_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define BF_LONG unsigned long +# define BF_LONG_LOG2 3 +/* + * _CRAY note. I could declare short, but I have no idea what impact + * does it have on performance on none-T3E machines. I could declare + * int, but at least on C90 sizeof(int) can be chosen at compile time. + * So I've chosen long... + * + */ +# else +# define BF_LONG unsigned int +# endif + +# define BF_ROUNDS 16 +# define BF_BLOCK 8 + +typedef struct bf_key_st { + BF_LONG P[BF_ROUNDS + 2]; + BF_LONG S[4 * 256]; +} BF_KEY; + +# ifdef OPENSSL_FIPS +void private_BF_set_key(BF_KEY *key, int len, const unsigned char *data); +# endif +void BF_set_key(BF_KEY *key, int len, const unsigned char *data); + +void BF_encrypt(BF_LONG *data, const BF_KEY *key); +void BF_decrypt(BF_LONG *data, const BF_KEY *key); + +void BF_ecb_encrypt(const unsigned char *in, unsigned char *out, + const BF_KEY *key, int enc); +void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + const BF_KEY *schedule, unsigned char *ivec, int enc); +void BF_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void BF_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const BF_KEY *schedule, + unsigned char *ivec, int *num); +const char *BF_options(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/bio/b_dump.c b/libs/openssl/crypto/bio/b_dump.c new file mode 100644 index 00000000..87c8162c --- /dev/null +++ b/libs/openssl/crypto/bio/b_dump.c @@ -0,0 +1,183 @@ +/* crypto/bio/b_dump.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * Stolen from tjh's ssl/ssl_trc.c stuff. + */ + +#include +#include "cryptlib.h" +#include "bio_lcl.h" + +#define TRUNCATE +#define DUMP_WIDTH 16 +#define DUMP_WIDTH_LESS_INDENT(i) (DUMP_WIDTH-((i-(i>6?6:i)+3)/4)) + +int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len) +{ + return BIO_dump_indent_cb(cb, u, s, len, 0); +} + +int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len, int indent) +{ + int ret = 0; + char buf[288 + 1], tmp[20], str[128 + 1]; + int i, j, rows, trc; + unsigned char ch; + int dump_width; + + trc = 0; + +#ifdef TRUNCATE + for (; (len > 0) && ((s[len - 1] == ' ') || (s[len - 1] == '\0')); len--) + trc++; +#endif + + if (indent < 0) + indent = 0; + if (indent) { + if (indent > 128) + indent = 128; + memset(str, ' ', indent); + } + str[indent] = '\0'; + + dump_width = DUMP_WIDTH_LESS_INDENT(indent); + rows = (len / dump_width); + if ((rows * dump_width) < len) + rows++; + for (i = 0; i < rows; i++) { + BUF_strlcpy(buf, str, sizeof buf); + BIO_snprintf(tmp, sizeof tmp, "%04x - ", i * dump_width); + BUF_strlcat(buf, tmp, sizeof buf); + for (j = 0; j < dump_width; j++) { + if (((i * dump_width) + j) >= len) { + BUF_strlcat(buf, " ", sizeof buf); + } else { + ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff; + BIO_snprintf(tmp, sizeof tmp, "%02x%c", ch, + j == 7 ? '-' : ' '); + BUF_strlcat(buf, tmp, sizeof buf); + } + } + BUF_strlcat(buf, " ", sizeof buf); + for (j = 0; j < dump_width; j++) { + if (((i * dump_width) + j) >= len) + break; + ch = ((unsigned char)*(s + i * dump_width + j)) & 0xff; +#ifndef CHARSET_EBCDIC + BIO_snprintf(tmp, sizeof tmp, "%c", + ((ch >= ' ') && (ch <= '~')) ? ch : '.'); +#else + BIO_snprintf(tmp, sizeof tmp, "%c", + ((ch >= os_toascii[' ']) && (ch <= os_toascii['~'])) + ? os_toebcdic[ch] + : '.'); +#endif + BUF_strlcat(buf, tmp, sizeof buf); + } + BUF_strlcat(buf, "\n", sizeof buf); + /* + * if this is the last call then update the ddt_dump thing so that we + * will move the selection point in the debug window + */ + ret += cb((void *)buf, strlen(buf), u); + } +#ifdef TRUNCATE + if (trc > 0) { + BIO_snprintf(buf, sizeof buf, "%s%04x - \n", str, + len + trc); + ret += cb((void *)buf, strlen(buf), u); + } +#endif + return (ret); +} + +#ifndef OPENSSL_NO_FP_API +static int write_fp(const void *data, size_t len, void *fp) +{ + return UP_fwrite(data, len, 1, fp); +} + +int BIO_dump_fp(FILE *fp, const char *s, int len) +{ + return BIO_dump_cb(write_fp, fp, s, len); +} + +int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent) +{ + return BIO_dump_indent_cb(write_fp, fp, s, len, indent); +} +#endif + +static int write_bio(const void *data, size_t len, void *bp) +{ + return BIO_write((BIO *)bp, (const char *)data, len); +} + +int BIO_dump(BIO *bp, const char *s, int len) +{ + return BIO_dump_cb(write_bio, bp, s, len); +} + +int BIO_dump_indent(BIO *bp, const char *s, int len, int indent) +{ + return BIO_dump_indent_cb(write_bio, bp, s, len, indent); +} diff --git a/libs/openssl/crypto/bio/b_print.c b/libs/openssl/crypto/bio/b_print.c new file mode 100644 index 00000000..90248fa2 --- /dev/null +++ b/libs/openssl/crypto/bio/b_print.c @@ -0,0 +1,863 @@ +/* crypto/bio/b_print.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* disable assert() unless BIO_DEBUG has been defined */ +#ifndef BIO_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +/* + * Stolen from tjh's ssl/ssl_trc.c stuff. + */ + +#include +#include +#include +#include +#include +#include "cryptlib.h" +#ifndef NO_SYS_TYPES_H +# include +#endif +#include /* To get BN_LLONG properly defined */ +#include + +#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT) +# ifndef HAVE_LONG_LONG +# define HAVE_LONG_LONG 1 +# endif +#endif + +/***************************************************************************/ + +/* + * Copyright Patrick Powell 1995 + * This code is based on code written by Patrick Powell + * It may be used for any purpose as long as this notice remains intact + * on all source code distributions. + */ + +/*- + * This code contains numerious changes and enhancements which were + * made by lots of contributors over the last years to Patrick Powell's + * original code: + * + * o Patrick Powell (1995) + * o Brandon Long (1996, for Mutt) + * o Thomas Roessler (1998, for Mutt) + * o Michael Elkins (1998, for Mutt) + * o Andrew Tridgell (1998, for Samba) + * o Luke Mewburn (1999, for LukemFTP) + * o Ralf S. Engelschall (1999, for Pth) + * o ... (for OpenSSL) + */ + +#ifdef HAVE_LONG_DOUBLE +# define LDOUBLE long double +#else +# define LDOUBLE double +#endif + +#ifdef HAVE_LONG_LONG +# if defined(_WIN32) && !defined(__GNUC__) +# define LLONG __int64 +# else +# define LLONG long long +# endif +#else +# define LLONG long +#endif + +static int fmtstr(char **, char **, size_t *, size_t *, + const char *, int, int, int); +static int fmtint(char **, char **, size_t *, size_t *, + LLONG, int, int, int, int); +static int fmtfp(char **, char **, size_t *, size_t *, + LDOUBLE, int, int, int); +static int doapr_outch(char **, char **, size_t *, size_t *, int); +static int _dopr(char **sbuffer, char **buffer, + size_t *maxlen, size_t *retlen, int *truncated, + const char *format, va_list args); + +/* format read states */ +#define DP_S_DEFAULT 0 +#define DP_S_FLAGS 1 +#define DP_S_MIN 2 +#define DP_S_DOT 3 +#define DP_S_MAX 4 +#define DP_S_MOD 5 +#define DP_S_CONV 6 +#define DP_S_DONE 7 + +/* format flags - Bits */ +#define DP_F_MINUS (1 << 0) +#define DP_F_PLUS (1 << 1) +#define DP_F_SPACE (1 << 2) +#define DP_F_NUM (1 << 3) +#define DP_F_ZERO (1 << 4) +#define DP_F_UP (1 << 5) +#define DP_F_UNSIGNED (1 << 6) + +/* conversion flags */ +#define DP_C_SHORT 1 +#define DP_C_LONG 2 +#define DP_C_LDOUBLE 3 +#define DP_C_LLONG 4 + +/* some handy macros */ +#define char_to_int(p) (p - '0') +#define OSSL_MAX(p,q) ((p >= q) ? p : q) + +static int +_dopr(char **sbuffer, + char **buffer, + size_t *maxlen, + size_t *retlen, int *truncated, const char *format, va_list args) +{ + char ch; + LLONG value; + LDOUBLE fvalue; + char *strvalue; + int min; + int max; + int state; + int flags; + int cflags; + size_t currlen; + + state = DP_S_DEFAULT; + flags = currlen = cflags = min = 0; + max = -1; + ch = *format++; + + while (state != DP_S_DONE) { + if (ch == '\0' || (buffer == NULL && currlen >= *maxlen)) + state = DP_S_DONE; + + switch (state) { + case DP_S_DEFAULT: + if (ch == '%') + state = DP_S_FLAGS; + else + if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch)) + return 0; + ch = *format++; + break; + case DP_S_FLAGS: + switch (ch) { + case '-': + flags |= DP_F_MINUS; + ch = *format++; + break; + case '+': + flags |= DP_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= DP_F_SPACE; + ch = *format++; + break; + case '#': + flags |= DP_F_NUM; + ch = *format++; + break; + case '0': + flags |= DP_F_ZERO; + ch = *format++; + break; + default: + state = DP_S_MIN; + break; + } + break; + case DP_S_MIN: + if (isdigit((unsigned char)ch)) { + min = 10 * min + char_to_int(ch); + ch = *format++; + } else if (ch == '*') { + min = va_arg(args, int); + ch = *format++; + state = DP_S_DOT; + } else + state = DP_S_DOT; + break; + case DP_S_DOT: + if (ch == '.') { + state = DP_S_MAX; + ch = *format++; + } else + state = DP_S_MOD; + break; + case DP_S_MAX: + if (isdigit((unsigned char)ch)) { + if (max < 0) + max = 0; + max = 10 * max + char_to_int(ch); + ch = *format++; + } else if (ch == '*') { + max = va_arg(args, int); + ch = *format++; + state = DP_S_MOD; + } else + state = DP_S_MOD; + break; + case DP_S_MOD: + switch (ch) { + case 'h': + cflags = DP_C_SHORT; + ch = *format++; + break; + case 'l': + if (*format == 'l') { + cflags = DP_C_LLONG; + format++; + } else + cflags = DP_C_LONG; + ch = *format++; + break; + case 'q': + cflags = DP_C_LLONG; + ch = *format++; + break; + case 'L': + cflags = DP_C_LDOUBLE; + ch = *format++; + break; + default: + break; + } + state = DP_S_CONV; + break; + case DP_S_CONV: + switch (ch) { + case 'd': + case 'i': + switch (cflags) { + case DP_C_SHORT: + value = (short int)va_arg(args, int); + break; + case DP_C_LONG: + value = va_arg(args, long int); + break; + case DP_C_LLONG: + value = va_arg(args, LLONG); + break; + default: + value = va_arg(args, int); + break; + } + if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, 10, min, + max, flags)) + return 0; + break; + case 'X': + flags |= DP_F_UP; + /* FALLTHROUGH */ + case 'x': + case 'o': + case 'u': + flags |= DP_F_UNSIGNED; + switch (cflags) { + case DP_C_SHORT: + value = (unsigned short int)va_arg(args, unsigned int); + break; + case DP_C_LONG: + value = (LLONG) va_arg(args, unsigned long int); + break; + case DP_C_LLONG: + value = va_arg(args, unsigned LLONG); + break; + default: + value = (LLONG) va_arg(args, unsigned int); + break; + } + if (!fmtint(sbuffer, buffer, &currlen, maxlen, value, + ch == 'o' ? 8 : (ch == 'u' ? 10 : 16), + min, max, flags)) + return 0; + break; + case 'f': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + if (!fmtfp(sbuffer, buffer, &currlen, maxlen, fvalue, min, max, + flags)) + return 0; + break; + case 'E': + flags |= DP_F_UP; + case 'e': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + break; + case 'G': + flags |= DP_F_UP; + case 'g': + if (cflags == DP_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + break; + case 'c': + if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, + va_arg(args, int))) + return 0; + break; + case 's': + strvalue = va_arg(args, char *); + if (max < 0) { + if (buffer) + max = INT_MAX; + else + max = *maxlen; + } + if (!fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue, + flags, min, max)) + return 0; + break; + case 'p': + value = (long)va_arg(args, void *); + if (!fmtint(sbuffer, buffer, &currlen, maxlen, + value, 16, min, max, flags | DP_F_NUM)) + return 0; + break; + case 'n': /* XXX */ + if (cflags == DP_C_SHORT) { + short int *num; + num = va_arg(args, short int *); + *num = currlen; + } else if (cflags == DP_C_LONG) { /* XXX */ + long int *num; + num = va_arg(args, long int *); + *num = (long int)currlen; + } else if (cflags == DP_C_LLONG) { /* XXX */ + LLONG *num; + num = va_arg(args, LLONG *); + *num = (LLONG) currlen; + } else { + int *num; + num = va_arg(args, int *); + *num = currlen; + } + break; + case '%': + if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, ch)) + return 0; + break; + case 'w': + /* not supported yet, treat as next char */ + ch = *format++; + break; + default: + /* unknown, skip */ + break; + } + ch = *format++; + state = DP_S_DEFAULT; + flags = cflags = min = 0; + max = -1; + break; + case DP_S_DONE: + break; + default: + break; + } + } + *truncated = (currlen > *maxlen - 1); + if (*truncated) + currlen = *maxlen - 1; + if(!doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0')) + return 0; + *retlen = currlen - 1; + return 1; +} + +static int +fmtstr(char **sbuffer, + char **buffer, + size_t *currlen, + size_t *maxlen, const char *value, int flags, int min, int max) +{ + int padlen; + size_t strln; + int cnt = 0; + + if (value == 0) + value = ""; + + strln = strlen(value); + if (strln > INT_MAX) + strln = INT_MAX; + + padlen = min - strln; + if (min < 0 || padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; + + while ((padlen > 0) && (cnt < max)) { + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) + return 0; + --padlen; + ++cnt; + } + while (*value && (cnt < max)) { + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *value++)) + return 0; + ++cnt; + } + while ((padlen < 0) && (cnt < max)) { + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) + return 0; + ++padlen; + ++cnt; + } + return 1; +} + +static int +fmtint(char **sbuffer, + char **buffer, + size_t *currlen, + size_t *maxlen, LLONG value, int base, int min, int max, int flags) +{ + int signvalue = 0; + const char *prefix = ""; + unsigned LLONG uvalue; + char convert[DECIMAL_SIZE(value) + 3]; + int place = 0; + int spadlen = 0; + int zpadlen = 0; + int caps = 0; + + if (max < 0) + max = 0; + uvalue = value; + if (!(flags & DP_F_UNSIGNED)) { + if (value < 0) { + signvalue = '-'; + uvalue = -value; + } else if (flags & DP_F_PLUS) + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + } + if (flags & DP_F_NUM) { + if (base == 8) + prefix = "0"; + if (base == 16) + prefix = "0x"; + } + if (flags & DP_F_UP) + caps = 1; + do { + convert[place++] = (caps ? "0123456789ABCDEF" : "0123456789abcdef") + [uvalue % (unsigned)base]; + uvalue = (uvalue / (unsigned)base); + } while (uvalue && (place < (int)sizeof(convert))); + if (place == sizeof(convert)) + place--; + convert[place] = 0; + + zpadlen = max - place; + spadlen = + min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix); + if (zpadlen < 0) + zpadlen = 0; + if (spadlen < 0) + spadlen = 0; + if (flags & DP_F_ZERO) { + zpadlen = OSSL_MAX(zpadlen, spadlen); + spadlen = 0; + } + if (flags & DP_F_MINUS) + spadlen = -spadlen; + + /* spaces */ + while (spadlen > 0) { + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) + return 0; + --spadlen; + } + + /* sign */ + if (signvalue) + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) + return 0; + + /* prefix */ + while (*prefix) { + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix)) + return 0; + prefix++; + } + + /* zeros */ + if (zpadlen > 0) { + while (zpadlen > 0) { + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) + return 0; + --zpadlen; + } + } + /* digits */ + while (place > 0) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place])) + return 0; + } + + /* left justified spaces */ + while (spadlen < 0) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) + return 0; + ++spadlen; + } + return 1; +} + +static LDOUBLE abs_val(LDOUBLE value) +{ + LDOUBLE result = value; + if (value < 0) + result = -value; + return result; +} + +static LDOUBLE pow_10(int in_exp) +{ + LDOUBLE result = 1; + while (in_exp) { + result *= 10; + in_exp--; + } + return result; +} + +static long roundv(LDOUBLE value) +{ + long intpart; + intpart = (long)value; + value = value - intpart; + if (value >= 0.5) + intpart++; + return intpart; +} + +static int +fmtfp(char **sbuffer, + char **buffer, + size_t *currlen, + size_t *maxlen, LDOUBLE fvalue, int min, int max, int flags) +{ + int signvalue = 0; + LDOUBLE ufvalue; + char iconvert[20]; + char fconvert[20]; + int iplace = 0; + int fplace = 0; + int padlen = 0; + int zpadlen = 0; + long intpart; + long fracpart; + long max10; + + if (max < 0) + max = 6; + ufvalue = abs_val(fvalue); + if (fvalue < 0) + signvalue = '-'; + else if (flags & DP_F_PLUS) + signvalue = '+'; + else if (flags & DP_F_SPACE) + signvalue = ' '; + + intpart = (long)ufvalue; + + /* + * sorry, we only support 9 digits past the decimal because of our + * conversion method + */ + if (max > 9) + max = 9; + + /* + * we "cheat" by converting the fractional part to integer by multiplying + * by a factor of 10 + */ + max10 = roundv(pow_10(max)); + fracpart = roundv(pow_10(max) * (ufvalue - intpart)); + + if (fracpart >= max10) { + intpart++; + fracpart -= max10; + } + + /* convert integer part */ + do { + iconvert[iplace++] = "0123456789"[intpart % 10]; + intpart = (intpart / 10); + } while (intpart && (iplace < (int)sizeof(iconvert))); + if (iplace == sizeof iconvert) + iplace--; + iconvert[iplace] = 0; + + /* convert fractional part */ + do { + fconvert[fplace++] = "0123456789"[fracpart % 10]; + fracpart = (fracpart / 10); + } while (fplace < max); + if (fplace == sizeof fconvert) + fplace--; + fconvert[fplace] = 0; + + /* -1 for decimal point, another -1 if we are printing a sign */ + padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); + zpadlen = max - fplace; + if (zpadlen < 0) + zpadlen = 0; + if (padlen < 0) + padlen = 0; + if (flags & DP_F_MINUS) + padlen = -padlen; + + if ((flags & DP_F_ZERO) && (padlen > 0)) { + if (signvalue) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) + return 0; + --padlen; + signvalue = 0; + } + while (padlen > 0) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) + return 0; + --padlen; + } + } + while (padlen > 0) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) + return 0; + --padlen; + } + if (signvalue && !doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue)) + return 0; + + while (iplace > 0) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace])) + return 0; + } + + /* + * Decimal point. This should probably use locale to find the correct + * char to print out. + */ + if (max > 0 || (flags & DP_F_NUM)) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '.')) + return 0; + + while (fplace > 0) { + if(!doapr_outch(sbuffer, buffer, currlen, maxlen, + fconvert[--fplace])) + return 0; + } + } + while (zpadlen > 0) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, '0')) + return 0; + --zpadlen; + } + + while (padlen < 0) { + if (!doapr_outch(sbuffer, buffer, currlen, maxlen, ' ')) + return 0; + ++padlen; + } + return 1; +} + +#define BUFFER_INC 1024 + +static int +doapr_outch(char **sbuffer, + char **buffer, size_t *currlen, size_t *maxlen, int c) +{ + /* If we haven't at least one buffer, someone has doe a big booboo */ + assert(*sbuffer != NULL || buffer != NULL); + + /* |currlen| must always be <= |*maxlen| */ + assert(*currlen <= *maxlen); + + if (buffer && *currlen == *maxlen) { + if (*maxlen > INT_MAX - BUFFER_INC) + return 0; + + *maxlen += BUFFER_INC; + if (*buffer == NULL) { + *buffer = OPENSSL_malloc(*maxlen); + if (*buffer == NULL) + return 0; + if (*currlen > 0) { + assert(*sbuffer != NULL); + memcpy(*buffer, *sbuffer, *currlen); + } + *sbuffer = NULL; + } else { + char *tmpbuf; + tmpbuf = OPENSSL_realloc(*buffer, *maxlen); + if (tmpbuf == NULL) + return 0; + *buffer = tmpbuf; + } + } + + if (*currlen < *maxlen) { + if (*sbuffer) + (*sbuffer)[(*currlen)++] = (char)c; + else + (*buffer)[(*currlen)++] = (char)c; + } + + return 1; +} + +/***************************************************************************/ + +int BIO_printf(BIO *bio, const char *format, ...) +{ + va_list args; + int ret; + + va_start(args, format); + + ret = BIO_vprintf(bio, format, args); + + va_end(args); + return (ret); +} + +int BIO_vprintf(BIO *bio, const char *format, va_list args) +{ + int ret; + size_t retlen; + char hugebuf[1024 * 2]; /* Was previously 10k, which is unreasonable + * in small-stack environments, like threads + * or DOS programs. */ + char *hugebufp = hugebuf; + size_t hugebufsize = sizeof(hugebuf); + char *dynbuf = NULL; + int ignored; + + dynbuf = NULL; + CRYPTO_push_info("doapr()"); + if (!_dopr(&hugebufp, &dynbuf, &hugebufsize, &retlen, &ignored, format, + args)) { + OPENSSL_free(dynbuf); + return -1; + } + if (dynbuf) { + ret = BIO_write(bio, dynbuf, (int)retlen); + OPENSSL_free(dynbuf); + } else { + ret = BIO_write(bio, hugebuf, (int)retlen); + } + CRYPTO_pop_info(); + return (ret); +} + +/* + * As snprintf is not available everywhere, we provide our own + * implementation. This function has nothing to do with BIOs, but it's + * closely related to BIO_printf, and we need *some* name prefix ... (XXX the + * function should be renamed, but to what?) + */ +int BIO_snprintf(char *buf, size_t n, const char *format, ...) +{ + va_list args; + int ret; + + va_start(args, format); + + ret = BIO_vsnprintf(buf, n, format, args); + + va_end(args); + return (ret); +} + +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) +{ + size_t retlen; + int truncated; + + if(!_dopr(&buf, NULL, &n, &retlen, &truncated, format, args)) + return -1; + + if (truncated) + /* + * In case of truncation, return -1 like traditional snprintf. + * (Current drafts for ISO/IEC 9899 say snprintf should return the + * number of characters that would have been written, had the buffer + * been large enough.) + */ + return -1; + else + return (retlen <= INT_MAX) ? (int)retlen : -1; +} diff --git a/libs/openssl/crypto/bio/b_sock.c b/libs/openssl/crypto/bio/b_sock.c new file mode 100644 index 00000000..bda882c4 --- /dev/null +++ b/libs/openssl/crypto/bio/b_sock.c @@ -0,0 +1,958 @@ +/* crypto/bio/b_sock.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#define USE_SOCKETS +#include "cryptlib.h" +#include +#if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_BSDSOCK) +# include +# if defined(NETWARE_CLIB) +# include +NETDB_DEFINE_CONTEXT +# endif +#endif +#ifndef OPENSSL_NO_SOCK +# include +# define SOCKET_PROTOCOL IPPROTO_TCP +# ifdef SO_MAXCONN +# define MAX_LISTEN SO_MAXCONN +# elif defined(SOMAXCONN) +# define MAX_LISTEN SOMAXCONN +# else +# define MAX_LISTEN 32 +# endif +# if defined(OPENSSL_SYS_WINDOWS) || (defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK)) +static int wsa_init_done = 0; +# endif + +/* + * WSAAPI specifier is required to make indirect calls to run-time + * linked WinSock 2 functions used in this module, to be specific + * [get|free]addrinfo and getnameinfo. This is because WinSock uses + * uses non-C calling convention, __stdcall vs. __cdecl, on x86 + * Windows. On non-WinSock platforms WSAAPI needs to be void. + */ +# ifndef WSAAPI +# define WSAAPI +# endif + +# if 0 +static unsigned long BIO_ghbn_hits = 0L; +static unsigned long BIO_ghbn_miss = 0L; + +# define GHBN_NUM 4 +static struct ghbn_cache_st { + char name[129]; + struct hostent *ent; + unsigned long order; +} ghbn_cache[GHBN_NUM]; +# endif + +static int get_ip(const char *str, unsigned char *ip); +# if 0 +static void ghbn_free(struct hostent *a); +static struct hostent *ghbn_dup(struct hostent *a); +# endif +int BIO_get_host_ip(const char *str, unsigned char *ip) +{ + int i; + int err = 1; + int locked = 0; + struct hostent *he; + + i = get_ip(str, ip); + if (i < 0) { + BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_INVALID_IP_ADDRESS); + goto err; + } + + /* + * At this point, we have something that is most probably correct in some + * way, so let's init the socket. + */ + if (BIO_sock_init() != 1) + return 0; /* don't generate another error code here */ + + /* + * If the string actually contained an IP address, we need not do + * anything more + */ + if (i > 0) + return (1); + + /* do a gethostbyname */ + CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME); + locked = 1; + he = BIO_gethostbyname(str); + if (he == NULL) { + BIOerr(BIO_F_BIO_GET_HOST_IP, BIO_R_BAD_HOSTNAME_LOOKUP); + goto err; + } + + /* cast to short because of win16 winsock definition */ + if ((short)he->h_addrtype != AF_INET) { + BIOerr(BIO_F_BIO_GET_HOST_IP, + BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET); + goto err; + } + for (i = 0; i < 4; i++) + ip[i] = he->h_addr_list[0][i]; + err = 0; + + err: + if (locked) + CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME); + if (err) { + ERR_add_error_data(2, "host=", str); + return 0; + } else + return 1; +} + +int BIO_get_port(const char *str, unsigned short *port_ptr) +{ + int i; + struct servent *s; + + if (str == NULL) { + BIOerr(BIO_F_BIO_GET_PORT, BIO_R_NO_PORT_DEFINED); + return (0); + } + i = atoi(str); + if (i != 0) + *port_ptr = (unsigned short)i; + else { + CRYPTO_w_lock(CRYPTO_LOCK_GETSERVBYNAME); + /* + * Note: under VMS with SOCKETSHR, it seems like the first parameter + * is 'char *', instead of 'const char *' + */ +# ifndef CONST_STRICT + s = getservbyname((char *)str, "tcp"); +# else + s = getservbyname(str, "tcp"); +# endif + if (s != NULL) + *port_ptr = ntohs((unsigned short)s->s_port); + CRYPTO_w_unlock(CRYPTO_LOCK_GETSERVBYNAME); + if (s == NULL) { + if (strcmp(str, "http") == 0) + *port_ptr = 80; + else if (strcmp(str, "telnet") == 0) + *port_ptr = 23; + else if (strcmp(str, "socks") == 0) + *port_ptr = 1080; + else if (strcmp(str, "https") == 0) + *port_ptr = 443; + else if (strcmp(str, "ssl") == 0) + *port_ptr = 443; + else if (strcmp(str, "ftp") == 0) + *port_ptr = 21; + else if (strcmp(str, "gopher") == 0) + *port_ptr = 70; +# if 0 + else if (strcmp(str, "wais") == 0) + *port_ptr = 21; +# endif + else { + SYSerr(SYS_F_GETSERVBYNAME, get_last_socket_error()); + ERR_add_error_data(3, "service='", str, "'"); + return (0); + } + } + } + return (1); +} + +int BIO_sock_error(int sock) +{ + int j, i; + int size; + +# if defined(OPENSSL_SYS_BEOS_R5) + return 0; +# endif + + size = sizeof(int); + /* + * Note: under Windows the third parameter is of type (char *) whereas + * under other systems it is (void *) if you don't have a cast it will + * choke the compiler: if you do have a cast then you can either go for + * (char *) or (void *). + */ + i = getsockopt(sock, SOL_SOCKET, SO_ERROR, (void *)&j, (void *)&size); + if (i < 0) + return (1); + else + return (j); +} + +# if 0 +long BIO_ghbn_ctrl(int cmd, int iarg, char *parg) +{ + int i; + char **p; + + switch (cmd) { + case BIO_GHBN_CTRL_HITS: + return (BIO_ghbn_hits); + /* break; */ + case BIO_GHBN_CTRL_MISSES: + return (BIO_ghbn_miss); + /* break; */ + case BIO_GHBN_CTRL_CACHE_SIZE: + return (GHBN_NUM); + /* break; */ + case BIO_GHBN_CTRL_GET_ENTRY: + if ((iarg >= 0) && (iarg < GHBN_NUM) && (ghbn_cache[iarg].order > 0)) { + p = (char **)parg; + if (p == NULL) + return (0); + *p = ghbn_cache[iarg].name; + ghbn_cache[iarg].name[128] = '\0'; + return (1); + } + return (0); + /* break; */ + case BIO_GHBN_CTRL_FLUSH: + for (i = 0; i < GHBN_NUM; i++) + ghbn_cache[i].order = 0; + break; + default: + return (0); + } + return (1); +} +# endif + +# if 0 +static struct hostent *ghbn_dup(struct hostent *a) +{ + struct hostent *ret; + int i, j; + + MemCheck_off(); + ret = (struct hostent *)OPENSSL_malloc(sizeof(struct hostent)); + if (ret == NULL) + return (NULL); + memset(ret, 0, sizeof(struct hostent)); + + for (i = 0; a->h_aliases[i] != NULL; i++) ; + i++; + ret->h_aliases = (char **)OPENSSL_malloc(i * sizeof(char *)); + if (ret->h_aliases == NULL) + goto err; + memset(ret->h_aliases, 0, i * sizeof(char *)); + + for (i = 0; a->h_addr_list[i] != NULL; i++) ; + i++; + ret->h_addr_list = (char **)OPENSSL_malloc(i * sizeof(char *)); + if (ret->h_addr_list == NULL) + goto err; + memset(ret->h_addr_list, 0, i * sizeof(char *)); + + j = strlen(a->h_name) + 1; + if ((ret->h_name = OPENSSL_malloc(j)) == NULL) + goto err; + memcpy((char *)ret->h_name, a->h_name, j); + for (i = 0; a->h_aliases[i] != NULL; i++) { + j = strlen(a->h_aliases[i]) + 1; + if ((ret->h_aliases[i] = OPENSSL_malloc(j)) == NULL) + goto err; + memcpy(ret->h_aliases[i], a->h_aliases[i], j); + } + ret->h_length = a->h_length; + ret->h_addrtype = a->h_addrtype; + for (i = 0; a->h_addr_list[i] != NULL; i++) { + if ((ret->h_addr_list[i] = OPENSSL_malloc(a->h_length)) == NULL) + goto err; + memcpy(ret->h_addr_list[i], a->h_addr_list[i], a->h_length); + } + if (0) { + err: + if (ret != NULL) + ghbn_free(ret); + ret = NULL; + } + MemCheck_on(); + return (ret); +} + +static void ghbn_free(struct hostent *a) +{ + int i; + + if (a == NULL) + return; + + if (a->h_aliases != NULL) { + for (i = 0; a->h_aliases[i] != NULL; i++) + OPENSSL_free(a->h_aliases[i]); + OPENSSL_free(a->h_aliases); + } + if (a->h_addr_list != NULL) { + for (i = 0; a->h_addr_list[i] != NULL; i++) + OPENSSL_free(a->h_addr_list[i]); + OPENSSL_free(a->h_addr_list); + } + if (a->h_name != NULL) + OPENSSL_free(a->h_name); + OPENSSL_free(a); +} + +# endif + +struct hostent *BIO_gethostbyname(const char *name) +{ +# if 1 + /* + * Caching gethostbyname() results forever is wrong, so we have to let + * the true gethostbyname() worry about this + */ +# if (defined(NETWARE_BSDSOCK) && !defined(__NOVELL_LIBC__)) + return gethostbyname((char *)name); +# else + return gethostbyname(name); +# endif +# else + struct hostent *ret; + int i, lowi = 0, j; + unsigned long low = (unsigned long)-1; + +# if 0 + /* + * It doesn't make sense to use locking here: The function interface is + * not thread-safe, because threads can never be sure when some other + * thread destroys the data they were given a pointer to. + */ + CRYPTO_w_lock(CRYPTO_LOCK_GETHOSTBYNAME); +# endif + j = strlen(name); + if (j < 128) { + for (i = 0; i < GHBN_NUM; i++) { + if (low > ghbn_cache[i].order) { + low = ghbn_cache[i].order; + lowi = i; + } + if (ghbn_cache[i].order > 0) { + if (strncmp(name, ghbn_cache[i].name, 128) == 0) + break; + } + } + } else + i = GHBN_NUM; + + if (i == GHBN_NUM) { /* no hit */ + BIO_ghbn_miss++; + /* + * Note: under VMS with SOCKETSHR, it seems like the first parameter + * is 'char *', instead of 'const char *' + */ +# ifndef CONST_STRICT + ret = gethostbyname((char *)name); +# else + ret = gethostbyname(name); +# endif + + if (ret == NULL) + goto end; + if (j > 128) { /* too big to cache */ +# if 0 + /* + * If we were trying to make this function thread-safe (which is + * bound to fail), we'd have to give up in this case (or allocate + * more memory). + */ + ret = NULL; +# endif + goto end; + } + + /* else add to cache */ + if (ghbn_cache[lowi].ent != NULL) + ghbn_free(ghbn_cache[lowi].ent); /* XXX not thread-safe */ + ghbn_cache[lowi].name[0] = '\0'; + + if ((ret = ghbn_cache[lowi].ent = ghbn_dup(ret)) == NULL) { + BIOerr(BIO_F_BIO_GETHOSTBYNAME, ERR_R_MALLOC_FAILURE); + goto end; + } + strncpy(ghbn_cache[lowi].name, name, 128); + ghbn_cache[lowi].order = BIO_ghbn_miss + BIO_ghbn_hits; + } else { + BIO_ghbn_hits++; + ret = ghbn_cache[i].ent; + ghbn_cache[i].order = BIO_ghbn_miss + BIO_ghbn_hits; + } + end: +# if 0 + CRYPTO_w_unlock(CRYPTO_LOCK_GETHOSTBYNAME); +# endif + return (ret); +# endif +} + +int BIO_sock_init(void) +{ +# ifdef OPENSSL_SYS_WINDOWS + static struct WSAData wsa_state; + + if (!wsa_init_done) { + int err; + + wsa_init_done = 1; + memset(&wsa_state, 0, sizeof(wsa_state)); + /* + * Not making wsa_state available to the rest of the code is formally + * wrong. But the structures we use are [beleived to be] invariable + * among Winsock DLLs, while API availability is [expected to be] + * probed at run-time with DSO_global_lookup. + */ + if (WSAStartup(0x0202, &wsa_state) != 0) { + err = WSAGetLastError(); + SYSerr(SYS_F_WSASTARTUP, err); + BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP); + return (-1); + } + } +# endif /* OPENSSL_SYS_WINDOWS */ +# ifdef WATT32 + extern int _watt_do_exit; + _watt_do_exit = 0; /* don't make sock_init() call exit() */ + if (sock_init()) + return (-1); +# endif + +# if defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) + WORD wVerReq; + WSADATA wsaData; + int err; + + if (!wsa_init_done) { + wsa_init_done = 1; + wVerReq = MAKEWORD(2, 0); + err = WSAStartup(wVerReq, &wsaData); + if (err != 0) { + SYSerr(SYS_F_WSASTARTUP, err); + BIOerr(BIO_F_BIO_SOCK_INIT, BIO_R_WSASTARTUP); + return (-1); + } + } +# endif + + return (1); +} + +void BIO_sock_cleanup(void) +{ +# ifdef OPENSSL_SYS_WINDOWS + if (wsa_init_done) { + wsa_init_done = 0; +# if 0 /* this call is claimed to be non-present in + * Winsock2 */ + WSACancelBlockingCall(); +# endif + WSACleanup(); + } +# elif defined(OPENSSL_SYS_NETWARE) && !defined(NETWARE_BSDSOCK) + if (wsa_init_done) { + wsa_init_done = 0; + WSACleanup(); + } +# endif +} + +# if !defined(OPENSSL_SYS_VMS) || __VMS_VER >= 70000000 + +int BIO_socket_ioctl(int fd, long type, void *arg) +{ + int i; + +# ifdef __DJGPP__ + i = ioctlsocket(fd, type, (char *)arg); +# else +# if defined(OPENSSL_SYS_VMS) + /*- + * 2011-02-18 SMS. + * VMS ioctl() can't tolerate a 64-bit "void *arg", but we + * observe that all the consumers pass in an "unsigned long *", + * so we arrange a local copy with a short pointer, and use + * that, instead. + */ +# if __INITIAL_POINTER_SIZE == 64 +# define ARG arg_32p +# pragma pointer_size save +# pragma pointer_size 32 + unsigned long arg_32; + unsigned long *arg_32p; +# pragma pointer_size restore + arg_32p = &arg_32; + arg_32 = *((unsigned long *)arg); +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define ARG arg +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ +# else /* defined(OPENSSL_SYS_VMS) */ +# define ARG arg +# endif /* defined(OPENSSL_SYS_VMS) [else] */ + + i = ioctlsocket(fd, type, ARG); +# endif /* __DJGPP__ */ + if (i < 0) + SYSerr(SYS_F_IOCTLSOCKET, get_last_socket_error()); + return (i); +} +# endif /* __VMS_VER */ + +/* + * The reason I have implemented this instead of using sscanf is because + * Visual C 1.52c gives an unresolved external when linking a DLL :-( + */ +static int get_ip(const char *str, unsigned char ip[4]) +{ + unsigned int tmp[4]; + int num = 0, c, ok = 0; + + tmp[0] = tmp[1] = tmp[2] = tmp[3] = 0; + + for (;;) { + c = *(str++); + if ((c >= '0') && (c <= '9')) { + ok = 1; + tmp[num] = tmp[num] * 10 + c - '0'; + if (tmp[num] > 255) + return (0); + } else if (c == '.') { + if (!ok) + return (-1); + if (num == 3) + return (0); + num++; + ok = 0; + } else if (c == '\0' && (num == 3) && ok) + break; + else + return (0); + } + ip[0] = tmp[0]; + ip[1] = tmp[1]; + ip[2] = tmp[2]; + ip[3] = tmp[3]; + return (1); +} + +int BIO_get_accept_socket(char *host, int bind_mode) +{ + int ret = 0; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +# if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +# endif + } server, client; + int s = INVALID_SOCKET, cs, addrlen; + unsigned char ip[4]; + unsigned short port; + char *str = NULL, *e; + char *h, *p; + unsigned long l; + int err_num; + + if (BIO_sock_init() != 1) + return (INVALID_SOCKET); + + if ((str = BUF_strdup(host)) == NULL) + return (INVALID_SOCKET); + + h = p = NULL; + h = str; + for (e = str; *e; e++) { + if (*e == ':') { + p = e; + } else if (*e == '/') { + *e = '\0'; + break; + } + } + if (p) + *p++ = '\0'; /* points at last ':', '::port' is special + * [see below] */ + else + p = h, h = NULL; + +# ifdef EAI_FAMILY + do { + static union { + void *p; + int (WSAAPI *f) (const char *, const char *, + const struct addrinfo *, struct addrinfo **); + } p_getaddrinfo = { + NULL + }; + static union { + void *p; + void (WSAAPI *f) (struct addrinfo *); + } p_freeaddrinfo = { + NULL + }; + struct addrinfo *res, hint; + + if (p_getaddrinfo.p == NULL) { + if ((p_getaddrinfo.p = DSO_global_lookup("getaddrinfo")) == NULL + || (p_freeaddrinfo.p = + DSO_global_lookup("freeaddrinfo")) == NULL) + p_getaddrinfo.p = (void *)-1; + } + if (p_getaddrinfo.p == (void *)-1) + break; + + /* + * '::port' enforces IPv6 wildcard listener. Some OSes, e.g. Solaris, + * default to IPv6 without any hint. Also note that commonly IPv6 + * wildchard socket can service IPv4 connections just as well... + */ + memset(&hint, 0, sizeof(hint)); + hint.ai_flags = AI_PASSIVE; + if (h) { + if (strchr(h, ':')) { + if (h[1] == '\0') + h = NULL; +# if OPENSSL_USE_IPV6 + hint.ai_family = AF_INET6; +# else + h = NULL; +# endif + } else if (h[0] == '*' && h[1] == '\0') { + hint.ai_family = AF_INET; + h = NULL; + } + } + + if ((*p_getaddrinfo.f) (h, p, &hint, &res)) + break; + + addrlen = res->ai_addrlen <= sizeof(server) ? + res->ai_addrlen : sizeof(server); + memcpy(&server, res->ai_addr, addrlen); + + (*p_freeaddrinfo.f) (res); + goto again; + } while (0); +# endif + + if (!BIO_get_port(p, &port)) + goto err; + + memset((char *)&server, 0, sizeof(server)); + server.sa_in.sin_family = AF_INET; + server.sa_in.sin_port = htons(port); + addrlen = sizeof(server.sa_in); + + if (h == NULL || strcmp(h, "*") == 0) + server.sa_in.sin_addr.s_addr = INADDR_ANY; + else { + if (!BIO_get_host_ip(h, &(ip[0]))) + goto err; + l = (unsigned long) + ((unsigned long)ip[0] << 24L) | + ((unsigned long)ip[1] << 16L) | + ((unsigned long)ip[2] << 8L) | ((unsigned long)ip[3]); + server.sa_in.sin_addr.s_addr = htonl(l); + } + + again: + s = socket(server.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL); + if (s == INVALID_SOCKET) { + SYSerr(SYS_F_SOCKET, get_last_socket_error()); + ERR_add_error_data(3, "port='", host, "'"); + BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET); + goto err; + } +# ifdef SO_REUSEADDR + if (bind_mode == BIO_BIND_REUSEADDR) { + int i = 1; + + ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i)); + bind_mode = BIO_BIND_NORMAL; + } +# endif + if (bind(s, &server.sa, addrlen) == -1) { +# ifdef SO_REUSEADDR + err_num = get_last_socket_error(); + if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) && +# ifdef OPENSSL_SYS_WINDOWS + /* + * Some versions of Windows define EADDRINUSE to a dummy value. + */ + (err_num == WSAEADDRINUSE)) +# else + (err_num == EADDRINUSE)) +# endif + { + client = server; + if (h == NULL || strcmp(h, "*") == 0) { +# if OPENSSL_USE_IPV6 + if (client.sa.sa_family == AF_INET6) { + memset(&client.sa_in6.sin6_addr, 0, + sizeof(client.sa_in6.sin6_addr)); + client.sa_in6.sin6_addr.s6_addr[15] = 1; + } else +# endif + if (client.sa.sa_family == AF_INET) { + client.sa_in.sin_addr.s_addr = htonl(0x7F000001); + } else + goto err; + } + cs = socket(client.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL); + if (cs != INVALID_SOCKET) { + int ii; + ii = connect(cs, &client.sa, addrlen); + closesocket(cs); + if (ii == INVALID_SOCKET) { + bind_mode = BIO_BIND_REUSEADDR; + closesocket(s); + goto again; + } + /* else error */ + } + /* else error */ + } +# endif + SYSerr(SYS_F_BIND, err_num); + ERR_add_error_data(3, "port='", host, "'"); + BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_BIND_SOCKET); + goto err; + } + if (listen(s, MAX_LISTEN) == -1) { + SYSerr(SYS_F_BIND, get_last_socket_error()); + ERR_add_error_data(3, "port='", host, "'"); + BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_LISTEN_SOCKET); + goto err; + } + ret = 1; + err: + if (str != NULL) + OPENSSL_free(str); + if ((ret == 0) && (s != INVALID_SOCKET)) { + closesocket(s); + s = INVALID_SOCKET; + } + return (s); +} + +int BIO_accept(int sock, char **addr) +{ + int ret = INVALID_SOCKET; + unsigned long l; + unsigned short port; + char *p; + + struct { + /* + * As for following union. Trouble is that there are platforms + * that have socklen_t and there are platforms that don't, on + * some platforms socklen_t is int and on some size_t. So what + * one can do? One can cook #ifdef spaghetti, which is nothing + * but masochistic. Or one can do union between int and size_t. + * One naturally does it primarily for 64-bit platforms where + * sizeof(int) != sizeof(size_t). But would it work? Note that + * if size_t member is initialized to 0, then later int member + * assignment naturally does the job on little-endian platforms + * regardless accept's expectations! What about big-endians? + * If accept expects int*, then it works, and if size_t*, then + * length value would appear as unreasonably large. But this + * won't prevent it from filling in the address structure. The + * trouble of course would be if accept returns more data than + * actual buffer can accomodate and overwrite stack... That's + * where early OPENSSL_assert comes into picture. Besides, the + * only 64-bit big-endian platform found so far that expects + * size_t* is HP-UX, where stack grows towards higher address. + * + */ + union { + size_t s; + int i; + } len; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +# if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +# endif + } from; + } sa; + + sa.len.s = 0; + sa.len.i = sizeof(sa.from); + memset(&sa.from, 0, sizeof(sa.from)); + ret = accept(sock, &sa.from.sa, (void *)&sa.len); + if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { + OPENSSL_assert(sa.len.s <= sizeof(sa.from)); + sa.len.i = (int)sa.len.s; + /* use sa.len.i from this point */ + } + if (ret == INVALID_SOCKET) { + if (BIO_sock_should_retry(ret)) + return -2; + SYSerr(SYS_F_ACCEPT, get_last_socket_error()); + BIOerr(BIO_F_BIO_ACCEPT, BIO_R_ACCEPT_ERROR); + goto end; + } + + if (addr == NULL) + goto end; + +# ifdef EAI_FAMILY + do { + char h[NI_MAXHOST], s[NI_MAXSERV]; + size_t nl; + static union { + void *p; + int (WSAAPI *f) (const struct sockaddr *, size_t /* socklen_t */ , + char *, size_t, char *, size_t, int); + } p_getnameinfo = { + NULL + }; + /* + * 2nd argument to getnameinfo is specified to be socklen_t. + * Unfortunately there is a number of environments where socklen_t is + * not defined. As it's passed by value, it's safe to pass it as + * size_t... + */ + + if (p_getnameinfo.p == NULL) { + if ((p_getnameinfo.p = DSO_global_lookup("getnameinfo")) == NULL) + p_getnameinfo.p = (void *)-1; + } + if (p_getnameinfo.p == (void *)-1) + break; + + if ((*p_getnameinfo.f) (&sa.from.sa, sa.len.i, h, sizeof(h), s, + sizeof(s), NI_NUMERICHOST | NI_NUMERICSERV)) + break; + nl = strlen(h) + strlen(s) + 2; + p = *addr; + if (p) { + *p = '\0'; + p = OPENSSL_realloc(p, nl); + } else { + p = OPENSSL_malloc(nl); + } + if (p == NULL) { + BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE); + goto end; + } + *addr = p; + BIO_snprintf(*addr, nl, "%s:%s", h, s); + goto end; + } while (0); +# endif + if (sa.from.sa.sa_family != AF_INET) + goto end; + l = ntohl(sa.from.sa_in.sin_addr.s_addr); + port = ntohs(sa.from.sa_in.sin_port); + if (*addr == NULL) { + if ((p = OPENSSL_malloc(24)) == NULL) { + BIOerr(BIO_F_BIO_ACCEPT, ERR_R_MALLOC_FAILURE); + goto end; + } + *addr = p; + } + BIO_snprintf(*addr, 24, "%d.%d.%d.%d:%d", + (unsigned char)(l >> 24L) & 0xff, + (unsigned char)(l >> 16L) & 0xff, + (unsigned char)(l >> 8L) & 0xff, + (unsigned char)(l) & 0xff, port); + end: + return (ret); +} + +int BIO_set_tcp_ndelay(int s, int on) +{ + int ret = 0; +# if defined(TCP_NODELAY) && (defined(IPPROTO_TCP) || defined(SOL_TCP)) + int opt; + +# ifdef SOL_TCP + opt = SOL_TCP; +# else +# ifdef IPPROTO_TCP + opt = IPPROTO_TCP; +# endif +# endif + + ret = setsockopt(s, opt, TCP_NODELAY, (char *)&on, sizeof(on)); +# endif + return (ret == 0); +} + +int BIO_socket_nbio(int s, int mode) +{ + int ret = -1; + int l; + + l = mode; +# ifdef FIONBIO + ret = BIO_socket_ioctl(s, FIONBIO, &l); +# endif + return (ret == 0); +} +#endif diff --git a/libs/openssl/crypto/bio/bf_buff.c b/libs/openssl/crypto/bio/bf_buff.c new file mode 100644 index 00000000..478fa16a --- /dev/null +++ b/libs/openssl/crypto/bio/bf_buff.c @@ -0,0 +1,517 @@ +/* crypto/bio/bf_buff.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include + +static int buffer_write(BIO *h, const char *buf, int num); +static int buffer_read(BIO *h, char *buf, int size); +static int buffer_puts(BIO *h, const char *str); +static int buffer_gets(BIO *h, char *str, int size); +static long buffer_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int buffer_new(BIO *h); +static int buffer_free(BIO *data); +static long buffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); +#define DEFAULT_BUFFER_SIZE 4096 + +static BIO_METHOD methods_buffer = { + BIO_TYPE_BUFFER, + "buffer", + buffer_write, + buffer_read, + buffer_puts, + buffer_gets, + buffer_ctrl, + buffer_new, + buffer_free, + buffer_callback_ctrl, +}; + +BIO_METHOD *BIO_f_buffer(void) +{ + return (&methods_buffer); +} + +static int buffer_new(BIO *bi) +{ + BIO_F_BUFFER_CTX *ctx; + + ctx = (BIO_F_BUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_F_BUFFER_CTX)); + if (ctx == NULL) + return (0); + ctx->ibuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE); + if (ctx->ibuf == NULL) { + OPENSSL_free(ctx); + return (0); + } + ctx->obuf = (char *)OPENSSL_malloc(DEFAULT_BUFFER_SIZE); + if (ctx->obuf == NULL) { + OPENSSL_free(ctx->ibuf); + OPENSSL_free(ctx); + return (0); + } + ctx->ibuf_size = DEFAULT_BUFFER_SIZE; + ctx->obuf_size = DEFAULT_BUFFER_SIZE; + ctx->ibuf_len = 0; + ctx->ibuf_off = 0; + ctx->obuf_len = 0; + ctx->obuf_off = 0; + + bi->init = 1; + bi->ptr = (char *)ctx; + bi->flags = 0; + return (1); +} + +static int buffer_free(BIO *a) +{ + BIO_F_BUFFER_CTX *b; + + if (a == NULL) + return (0); + b = (BIO_F_BUFFER_CTX *)a->ptr; + if (b->ibuf != NULL) + OPENSSL_free(b->ibuf); + if (b->obuf != NULL) + OPENSSL_free(b->obuf); + OPENSSL_free(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int buffer_read(BIO *b, char *out, int outl) +{ + int i, num = 0; + BIO_F_BUFFER_CTX *ctx; + + if (out == NULL) + return (0); + ctx = (BIO_F_BUFFER_CTX *)b->ptr; + + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + num = 0; + BIO_clear_retry_flags(b); + + start: + i = ctx->ibuf_len; + /* If there is stuff left over, grab it */ + if (i != 0) { + if (i > outl) + i = outl; + memcpy(out, &(ctx->ibuf[ctx->ibuf_off]), i); + ctx->ibuf_off += i; + ctx->ibuf_len -= i; + num += i; + if (outl == i) + return (num); + outl -= i; + out += i; + } + + /* + * We may have done a partial read. try to do more. We have nothing in + * the buffer. If we get an error and have read some data, just return it + * and let them retry to get the error again. copy direct to parent + * address space + */ + if (outl > ctx->ibuf_size) { + for (;;) { + i = BIO_read(b->next_bio, out, outl); + if (i <= 0) { + BIO_copy_next_retry(b); + if (i < 0) + return ((num > 0) ? num : i); + if (i == 0) + return (num); + } + num += i; + if (outl == i) + return (num); + out += i; + outl -= i; + } + } + /* else */ + + /* we are going to be doing some buffering */ + i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size); + if (i <= 0) { + BIO_copy_next_retry(b); + if (i < 0) + return ((num > 0) ? num : i); + if (i == 0) + return (num); + } + ctx->ibuf_off = 0; + ctx->ibuf_len = i; + + /* Lets re-read using ourselves :-) */ + goto start; +} + +static int buffer_write(BIO *b, const char *in, int inl) +{ + int i, num = 0; + BIO_F_BUFFER_CTX *ctx; + + if ((in == NULL) || (inl <= 0)) + return (0); + ctx = (BIO_F_BUFFER_CTX *)b->ptr; + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + + BIO_clear_retry_flags(b); + start: + i = ctx->obuf_size - (ctx->obuf_len + ctx->obuf_off); + /* add to buffer and return */ + if (i >= inl) { + memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, inl); + ctx->obuf_len += inl; + return (num + inl); + } + /* else */ + /* stuff already in buffer, so add to it first, then flush */ + if (ctx->obuf_len != 0) { + if (i > 0) { /* lets fill it up if we can */ + memcpy(&(ctx->obuf[ctx->obuf_off + ctx->obuf_len]), in, i); + in += i; + inl -= i; + num += i; + ctx->obuf_len += i; + } + /* we now have a full buffer needing flushing */ + for (;;) { + i = BIO_write(b->next_bio, &(ctx->obuf[ctx->obuf_off]), + ctx->obuf_len); + if (i <= 0) { + BIO_copy_next_retry(b); + + if (i < 0) + return ((num > 0) ? num : i); + if (i == 0) + return (num); + } + ctx->obuf_off += i; + ctx->obuf_len -= i; + if (ctx->obuf_len == 0) + break; + } + } + /* + * we only get here if the buffer has been flushed and we still have + * stuff to write + */ + ctx->obuf_off = 0; + + /* we now have inl bytes to write */ + while (inl >= ctx->obuf_size) { + i = BIO_write(b->next_bio, in, inl); + if (i <= 0) { + BIO_copy_next_retry(b); + if (i < 0) + return ((num > 0) ? num : i); + if (i == 0) + return (num); + } + num += i; + in += i; + inl -= i; + if (inl == 0) + return (num); + } + + /* + * copy the rest into the buffer since we have only a small amount left + */ + goto start; +} + +static long buffer_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO *dbio; + BIO_F_BUFFER_CTX *ctx; + long ret = 1; + char *p1, *p2; + int r, i, *ip; + int ibs, obs; + + ctx = (BIO_F_BUFFER_CTX *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->ibuf_off = 0; + ctx->ibuf_len = 0; + ctx->obuf_off = 0; + ctx->obuf_len = 0; + if (b->next_bio == NULL) + return (0); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_INFO: + ret = (long)ctx->obuf_len; + break; + case BIO_C_GET_BUFF_NUM_LINES: + ret = 0; + p1 = ctx->ibuf; + for (i = 0; i < ctx->ibuf_len; i++) { + if (p1[ctx->ibuf_off + i] == '\n') + ret++; + } + break; + case BIO_CTRL_WPENDING: + ret = (long)ctx->obuf_len; + if (ret == 0) { + if (b->next_bio == NULL) + return (0); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + } + break; + case BIO_CTRL_PENDING: + ret = (long)ctx->ibuf_len; + if (ret == 0) { + if (b->next_bio == NULL) + return (0); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + } + break; + case BIO_C_SET_BUFF_READ_DATA: + if (num > ctx->ibuf_size) { + p1 = OPENSSL_malloc((int)num); + if (p1 == NULL) + goto malloc_error; + if (ctx->ibuf != NULL) + OPENSSL_free(ctx->ibuf); + ctx->ibuf = p1; + } + ctx->ibuf_off = 0; + ctx->ibuf_len = (int)num; + memcpy(ctx->ibuf, ptr, (int)num); + ret = 1; + break; + case BIO_C_SET_BUFF_SIZE: + if (ptr != NULL) { + ip = (int *)ptr; + if (*ip == 0) { + ibs = (int)num; + obs = ctx->obuf_size; + } else { /* if (*ip == 1) */ + + ibs = ctx->ibuf_size; + obs = (int)num; + } + } else { + ibs = (int)num; + obs = (int)num; + } + p1 = ctx->ibuf; + p2 = ctx->obuf; + if ((ibs > DEFAULT_BUFFER_SIZE) && (ibs != ctx->ibuf_size)) { + p1 = (char *)OPENSSL_malloc((int)num); + if (p1 == NULL) + goto malloc_error; + } + if ((obs > DEFAULT_BUFFER_SIZE) && (obs != ctx->obuf_size)) { + p2 = (char *)OPENSSL_malloc((int)num); + if (p2 == NULL) { + if (p1 != ctx->ibuf) + OPENSSL_free(p1); + goto malloc_error; + } + } + if (ctx->ibuf != p1) { + OPENSSL_free(ctx->ibuf); + ctx->ibuf = p1; + ctx->ibuf_off = 0; + ctx->ibuf_len = 0; + ctx->ibuf_size = ibs; + } + if (ctx->obuf != p2) { + OPENSSL_free(ctx->obuf); + ctx->obuf = p2; + ctx->obuf_off = 0; + ctx->obuf_len = 0; + ctx->obuf_size = obs; + } + break; + case BIO_C_DO_STATE_MACHINE: + if (b->next_bio == NULL) + return (0); + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + + case BIO_CTRL_FLUSH: + if (b->next_bio == NULL) + return (0); + if (ctx->obuf_len <= 0) { + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + + for (;;) { + BIO_clear_retry_flags(b); + if (ctx->obuf_len > 0) { + r = BIO_write(b->next_bio, + &(ctx->obuf[ctx->obuf_off]), ctx->obuf_len); +#if 0 + fprintf(stderr, "FLUSH [%3d] %3d -> %3d\n", ctx->obuf_off, + ctx->obuf_len, r); +#endif + BIO_copy_next_retry(b); + if (r <= 0) + return ((long)r); + ctx->obuf_off += r; + ctx->obuf_len -= r; + } else { + ctx->obuf_len = 0; + ctx->obuf_off = 0; + ret = 1; + break; + } + } + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_DUP: + dbio = (BIO *)ptr; + if (!BIO_set_read_buffer_size(dbio, ctx->ibuf_size) || + !BIO_set_write_buffer_size(dbio, ctx->obuf_size)) + ret = 0; + break; + default: + if (b->next_bio == NULL) + return (0); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); + malloc_error: + BIOerr(BIO_F_BUFFER_CTRL, ERR_R_MALLOC_FAILURE); + return (0); +} + +static long buffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static int buffer_gets(BIO *b, char *buf, int size) +{ + BIO_F_BUFFER_CTX *ctx; + int num = 0, i, flag; + char *p; + + ctx = (BIO_F_BUFFER_CTX *)b->ptr; + size--; /* reserve space for a '\0' */ + BIO_clear_retry_flags(b); + + for (;;) { + if (ctx->ibuf_len > 0) { + p = &(ctx->ibuf[ctx->ibuf_off]); + flag = 0; + for (i = 0; (i < ctx->ibuf_len) && (i < size); i++) { + *(buf++) = p[i]; + if (p[i] == '\n') { + flag = 1; + i++; + break; + } + } + num += i; + size -= i; + ctx->ibuf_len -= i; + ctx->ibuf_off += i; + if (flag || size == 0) { + *buf = '\0'; + return (num); + } + } else { /* read another chunk */ + + i = BIO_read(b->next_bio, ctx->ibuf, ctx->ibuf_size); + if (i <= 0) { + BIO_copy_next_retry(b); + *buf = '\0'; + if (i < 0) + return ((num > 0) ? num : i); + if (i == 0) + return (num); + } + ctx->ibuf_len = i; + ctx->ibuf_off = 0; + } + } +} + +static int buffer_puts(BIO *b, const char *str) +{ + return (buffer_write(b, str, strlen(str))); +} diff --git a/libs/openssl/crypto/bio/bf_lbuf.c b/libs/openssl/crypto/bio/bf_lbuf.c new file mode 100644 index 00000000..46d0d5a1 --- /dev/null +++ b/libs/openssl/crypto/bio/bf_lbuf.c @@ -0,0 +1,391 @@ +/* crypto/bio/bf_buff.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include + +static int linebuffer_write(BIO *h, const char *buf, int num); +static int linebuffer_read(BIO *h, char *buf, int size); +static int linebuffer_puts(BIO *h, const char *str); +static int linebuffer_gets(BIO *h, char *str, int size); +static long linebuffer_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int linebuffer_new(BIO *h); +static int linebuffer_free(BIO *data); +static long linebuffer_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); + +/* A 10k maximum should be enough for most purposes */ +#define DEFAULT_LINEBUFFER_SIZE 1024*10 + +/* #define DEBUG */ + +static BIO_METHOD methods_linebuffer = { + BIO_TYPE_LINEBUFFER, + "linebuffer", + linebuffer_write, + linebuffer_read, + linebuffer_puts, + linebuffer_gets, + linebuffer_ctrl, + linebuffer_new, + linebuffer_free, + linebuffer_callback_ctrl, +}; + +BIO_METHOD *BIO_f_linebuffer(void) +{ + return (&methods_linebuffer); +} + +typedef struct bio_linebuffer_ctx_struct { + char *obuf; /* the output char array */ + int obuf_size; /* how big is the output buffer */ + int obuf_len; /* how many bytes are in it */ +} BIO_LINEBUFFER_CTX; + +static int linebuffer_new(BIO *bi) +{ + BIO_LINEBUFFER_CTX *ctx; + + ctx = (BIO_LINEBUFFER_CTX *)OPENSSL_malloc(sizeof(BIO_LINEBUFFER_CTX)); + if (ctx == NULL) + return (0); + ctx->obuf = (char *)OPENSSL_malloc(DEFAULT_LINEBUFFER_SIZE); + if (ctx->obuf == NULL) { + OPENSSL_free(ctx); + return (0); + } + ctx->obuf_size = DEFAULT_LINEBUFFER_SIZE; + ctx->obuf_len = 0; + + bi->init = 1; + bi->ptr = (char *)ctx; + bi->flags = 0; + return (1); +} + +static int linebuffer_free(BIO *a) +{ + BIO_LINEBUFFER_CTX *b; + + if (a == NULL) + return (0); + b = (BIO_LINEBUFFER_CTX *)a->ptr; + if (b->obuf != NULL) + OPENSSL_free(b->obuf); + OPENSSL_free(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int linebuffer_read(BIO *b, char *out, int outl) +{ + int ret = 0; + + if (out == NULL) + return (0); + if (b->next_bio == NULL) + return (0); + ret = BIO_read(b->next_bio, out, outl); + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return (ret); +} + +static int linebuffer_write(BIO *b, const char *in, int inl) +{ + int i, num = 0, foundnl; + BIO_LINEBUFFER_CTX *ctx; + + if ((in == NULL) || (inl <= 0)) + return (0); + ctx = (BIO_LINEBUFFER_CTX *)b->ptr; + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + + BIO_clear_retry_flags(b); + + do { + const char *p; + + for (p = in; p < in + inl && *p != '\n'; p++) ; + if (*p == '\n') { + p++; + foundnl = 1; + } else + foundnl = 0; + + /* + * If a NL was found and we already have text in the save buffer, + * concatenate them and write + */ + while ((foundnl || p - in > ctx->obuf_size - ctx->obuf_len) + && ctx->obuf_len > 0) { + int orig_olen = ctx->obuf_len; + + i = ctx->obuf_size - ctx->obuf_len; + if (p - in > 0) { + if (i >= p - in) { + memcpy(&(ctx->obuf[ctx->obuf_len]), in, p - in); + ctx->obuf_len += p - in; + inl -= p - in; + num += p - in; + in = p; + } else { + memcpy(&(ctx->obuf[ctx->obuf_len]), in, i); + ctx->obuf_len += i; + inl -= i; + in += i; + num += i; + } + } +#if 0 + BIO_write(b->next_bio, "<*<", 3); +#endif + i = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len); + if (i <= 0) { + ctx->obuf_len = orig_olen; + BIO_copy_next_retry(b); + +#if 0 + BIO_write(b->next_bio, ">*>", 3); +#endif + if (i < 0) + return ((num > 0) ? num : i); + if (i == 0) + return (num); + } +#if 0 + BIO_write(b->next_bio, ">*>", 3); +#endif + if (i < ctx->obuf_len) + memmove(ctx->obuf, ctx->obuf + i, ctx->obuf_len - i); + ctx->obuf_len -= i; + } + + /* + * Now that the save buffer is emptied, let's write the input buffer + * if a NL was found and there is anything to write. + */ + if ((foundnl || p - in > ctx->obuf_size) && p - in > 0) { +#if 0 + BIO_write(b->next_bio, "<*<", 3); +#endif + i = BIO_write(b->next_bio, in, p - in); + if (i <= 0) { + BIO_copy_next_retry(b); +#if 0 + BIO_write(b->next_bio, ">*>", 3); +#endif + if (i < 0) + return ((num > 0) ? num : i); + if (i == 0) + return (num); + } +#if 0 + BIO_write(b->next_bio, ">*>", 3); +#endif + num += i; + in += i; + inl -= i; + } + } + while (foundnl && inl > 0); + /* + * We've written as much as we can. The rest of the input buffer, if + * any, is text that doesn't and with a NL and therefore needs to be + * saved for the next trip. + */ + if (inl > 0) { + memcpy(&(ctx->obuf[ctx->obuf_len]), in, inl); + ctx->obuf_len += inl; + num += inl; + } + return num; +} + +static long linebuffer_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO *dbio; + BIO_LINEBUFFER_CTX *ctx; + long ret = 1; + char *p; + int r; + int obs; + + ctx = (BIO_LINEBUFFER_CTX *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->obuf_len = 0; + if (b->next_bio == NULL) + return (0); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_INFO: + ret = (long)ctx->obuf_len; + break; + case BIO_CTRL_WPENDING: + ret = (long)ctx->obuf_len; + if (ret == 0) { + if (b->next_bio == NULL) + return (0); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + } + break; + case BIO_C_SET_BUFF_SIZE: + obs = (int)num; + p = ctx->obuf; + if ((obs > DEFAULT_LINEBUFFER_SIZE) && (obs != ctx->obuf_size)) { + p = (char *)OPENSSL_malloc((int)num); + if (p == NULL) + goto malloc_error; + } + if (ctx->obuf != p) { + if (ctx->obuf_len > obs) { + ctx->obuf_len = obs; + } + memcpy(p, ctx->obuf, ctx->obuf_len); + OPENSSL_free(ctx->obuf); + ctx->obuf = p; + ctx->obuf_size = obs; + } + break; + case BIO_C_DO_STATE_MACHINE: + if (b->next_bio == NULL) + return (0); + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + + case BIO_CTRL_FLUSH: + if (b->next_bio == NULL) + return (0); + if (ctx->obuf_len <= 0) { + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + + for (;;) { + BIO_clear_retry_flags(b); + if (ctx->obuf_len > 0) { + r = BIO_write(b->next_bio, ctx->obuf, ctx->obuf_len); +#if 0 + fprintf(stderr, "FLUSH %3d -> %3d\n", ctx->obuf_len, r); +#endif + BIO_copy_next_retry(b); + if (r <= 0) + return ((long)r); + if (r < ctx->obuf_len) + memmove(ctx->obuf, ctx->obuf + r, ctx->obuf_len - r); + ctx->obuf_len -= r; + } else { + ctx->obuf_len = 0; + ret = 1; + break; + } + } + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_DUP: + dbio = (BIO *)ptr; + if (!BIO_set_write_buffer_size(dbio, ctx->obuf_size)) + ret = 0; + break; + default: + if (b->next_bio == NULL) + return (0); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); + malloc_error: + BIOerr(BIO_F_LINEBUFFER_CTRL, ERR_R_MALLOC_FAILURE); + return (0); +} + +static long linebuffer_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static int linebuffer_gets(BIO *b, char *buf, int size) +{ + if (b->next_bio == NULL) + return (0); + return (BIO_gets(b->next_bio, buf, size)); +} + +static int linebuffer_puts(BIO *b, const char *str) +{ + return (linebuffer_write(b, str, strlen(str))); +} diff --git a/libs/openssl/crypto/bio/bf_nbio.c b/libs/openssl/crypto/bio/bf_nbio.c new file mode 100644 index 00000000..a04f32a0 --- /dev/null +++ b/libs/openssl/crypto/bio/bf_nbio.c @@ -0,0 +1,253 @@ +/* crypto/bio/bf_nbio.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include + +/* + * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest + */ + +static int nbiof_write(BIO *h, const char *buf, int num); +static int nbiof_read(BIO *h, char *buf, int size); +static int nbiof_puts(BIO *h, const char *str); +static int nbiof_gets(BIO *h, char *str, int size); +static long nbiof_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int nbiof_new(BIO *h); +static int nbiof_free(BIO *data); +static long nbiof_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); +typedef struct nbio_test_st { + /* only set if we sent a 'should retry' error */ + int lrn; + int lwn; +} NBIO_TEST; + +static BIO_METHOD methods_nbiof = { + BIO_TYPE_NBIO_TEST, + "non-blocking IO test filter", + nbiof_write, + nbiof_read, + nbiof_puts, + nbiof_gets, + nbiof_ctrl, + nbiof_new, + nbiof_free, + nbiof_callback_ctrl, +}; + +BIO_METHOD *BIO_f_nbio_test(void) +{ + return (&methods_nbiof); +} + +static int nbiof_new(BIO *bi) +{ + NBIO_TEST *nt; + + if (!(nt = (NBIO_TEST *)OPENSSL_malloc(sizeof(NBIO_TEST)))) + return (0); + nt->lrn = -1; + nt->lwn = -1; + bi->ptr = (char *)nt; + bi->init = 1; + bi->flags = 0; + return (1); +} + +static int nbiof_free(BIO *a) +{ + if (a == NULL) + return (0); + if (a->ptr != NULL) + OPENSSL_free(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int nbiof_read(BIO *b, char *out, int outl) +{ + int ret = 0; +#if 1 + int num; + unsigned char n; +#endif + + if (out == NULL) + return (0); + if (b->next_bio == NULL) + return (0); + + BIO_clear_retry_flags(b); +#if 1 + if (RAND_pseudo_bytes(&n, 1) < 0) + return -1; + num = (n & 0x07); + + if (outl > num) + outl = num; + + if (num == 0) { + ret = -1; + BIO_set_retry_read(b); + } else +#endif + { + ret = BIO_read(b->next_bio, out, outl); + if (ret < 0) + BIO_copy_next_retry(b); + } + return (ret); +} + +static int nbiof_write(BIO *b, const char *in, int inl) +{ + NBIO_TEST *nt; + int ret = 0; + int num; + unsigned char n; + + if ((in == NULL) || (inl <= 0)) + return (0); + if (b->next_bio == NULL) + return (0); + nt = (NBIO_TEST *)b->ptr; + + BIO_clear_retry_flags(b); + +#if 1 + if (nt->lwn > 0) { + num = nt->lwn; + nt->lwn = 0; + } else { + if (RAND_pseudo_bytes(&n, 1) < 0) + return -1; + num = (n & 7); + } + + if (inl > num) + inl = num; + + if (num == 0) { + ret = -1; + BIO_set_retry_write(b); + } else +#endif + { + ret = BIO_write(b->next_bio, in, inl); + if (ret < 0) { + BIO_copy_next_retry(b); + nt->lwn = inl; + } + } + return (ret); +} + +static long nbiof_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + case BIO_CTRL_DUP: + ret = 0L; + break; + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); +} + +static long nbiof_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static int nbiof_gets(BIO *bp, char *buf, int size) +{ + if (bp->next_bio == NULL) + return (0); + return (BIO_gets(bp->next_bio, buf, size)); +} + +static int nbiof_puts(BIO *bp, const char *str) +{ + if (bp->next_bio == NULL) + return (0); + return (BIO_puts(bp->next_bio, str)); +} diff --git a/libs/openssl/crypto/bio/bf_null.c b/libs/openssl/crypto/bio/bf_null.c new file mode 100644 index 00000000..e0c79e82 --- /dev/null +++ b/libs/openssl/crypto/bio/bf_null.c @@ -0,0 +1,189 @@ +/* crypto/bio/bf_null.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include + +/* + * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest + */ + +static int nullf_write(BIO *h, const char *buf, int num); +static int nullf_read(BIO *h, char *buf, int size); +static int nullf_puts(BIO *h, const char *str); +static int nullf_gets(BIO *h, char *str, int size); +static long nullf_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int nullf_new(BIO *h); +static int nullf_free(BIO *data); +static long nullf_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); +static BIO_METHOD methods_nullf = { + BIO_TYPE_NULL_FILTER, + "NULL filter", + nullf_write, + nullf_read, + nullf_puts, + nullf_gets, + nullf_ctrl, + nullf_new, + nullf_free, + nullf_callback_ctrl, +}; + +BIO_METHOD *BIO_f_null(void) +{ + return (&methods_nullf); +} + +static int nullf_new(BIO *bi) +{ + bi->init = 1; + bi->ptr = NULL; + bi->flags = 0; + return (1); +} + +static int nullf_free(BIO *a) +{ + if (a == NULL) + return (0); + /*- + a->ptr=NULL; + a->init=0; + a->flags=0; + */ + return (1); +} + +static int nullf_read(BIO *b, char *out, int outl) +{ + int ret = 0; + + if (out == NULL) + return (0); + if (b->next_bio == NULL) + return (0); + ret = BIO_read(b->next_bio, out, outl); + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return (ret); +} + +static int nullf_write(BIO *b, const char *in, int inl) +{ + int ret = 0; + + if ((in == NULL) || (inl <= 0)) + return (0); + if (b->next_bio == NULL) + return (0); + ret = BIO_write(b->next_bio, in, inl); + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return (ret); +} + +static long nullf_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + case BIO_CTRL_DUP: + ret = 0L; + break; + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + } + return (ret); +} + +static long nullf_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static int nullf_gets(BIO *bp, char *buf, int size) +{ + if (bp->next_bio == NULL) + return (0); + return (BIO_gets(bp->next_bio, buf, size)); +} + +static int nullf_puts(BIO *bp, const char *str) +{ + if (bp->next_bio == NULL) + return (0); + return (BIO_puts(bp->next_bio, str)); +} diff --git a/libs/openssl/crypto/bio/bio.h b/libs/openssl/crypto/bio/bio.h new file mode 100644 index 00000000..05f629ae --- /dev/null +++ b/libs/openssl/crypto/bio/bio.h @@ -0,0 +1,879 @@ +/* crypto/bio/bio.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BIO_H +# define HEADER_BIO_H + +# include + +# ifndef OPENSSL_NO_FP_API +# include +# endif +# include + +# include + +# ifndef OPENSSL_NO_SCTP +# ifndef OPENSSL_SYS_VMS +# include +# else +# include +# endif +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* These are the 'types' of BIOs */ +# define BIO_TYPE_NONE 0 +# define BIO_TYPE_MEM (1|0x0400) +# define BIO_TYPE_FILE (2|0x0400) + +# define BIO_TYPE_FD (4|0x0400|0x0100) +# define BIO_TYPE_SOCKET (5|0x0400|0x0100) +# define BIO_TYPE_NULL (6|0x0400) +# define BIO_TYPE_SSL (7|0x0200) +# define BIO_TYPE_MD (8|0x0200)/* passive filter */ +# define BIO_TYPE_BUFFER (9|0x0200)/* filter */ +# define BIO_TYPE_CIPHER (10|0x0200)/* filter */ +# define BIO_TYPE_BASE64 (11|0x0200)/* filter */ +# define BIO_TYPE_CONNECT (12|0x0400|0x0100)/* socket - connect */ +# define BIO_TYPE_ACCEPT (13|0x0400|0x0100)/* socket for accept */ +# define BIO_TYPE_PROXY_CLIENT (14|0x0200)/* client proxy BIO */ +# define BIO_TYPE_PROXY_SERVER (15|0x0200)/* server proxy BIO */ +# define BIO_TYPE_NBIO_TEST (16|0x0200)/* server proxy BIO */ +# define BIO_TYPE_NULL_FILTER (17|0x0200) +# define BIO_TYPE_BER (18|0x0200)/* BER -> bin filter */ +# define BIO_TYPE_BIO (19|0x0400)/* (half a) BIO pair */ +# define BIO_TYPE_LINEBUFFER (20|0x0200)/* filter */ +# define BIO_TYPE_DGRAM (21|0x0400|0x0100) +# ifndef OPENSSL_NO_SCTP +# define BIO_TYPE_DGRAM_SCTP (24|0x0400|0x0100) +# endif +# define BIO_TYPE_ASN1 (22|0x0200)/* filter */ +# define BIO_TYPE_COMP (23|0x0200)/* filter */ + +# define BIO_TYPE_DESCRIPTOR 0x0100/* socket, fd, connect or accept */ +# define BIO_TYPE_FILTER 0x0200 +# define BIO_TYPE_SOURCE_SINK 0x0400 + +/* + * BIO_FILENAME_READ|BIO_CLOSE to open or close on free. + * BIO_set_fp(in,stdin,BIO_NOCLOSE); + */ +# define BIO_NOCLOSE 0x00 +# define BIO_CLOSE 0x01 + +/* + * These are used in the following macros and are passed to BIO_ctrl() + */ +# define BIO_CTRL_RESET 1/* opt - rewind/zero etc */ +# define BIO_CTRL_EOF 2/* opt - are we at the eof */ +# define BIO_CTRL_INFO 3/* opt - extra tit-bits */ +# define BIO_CTRL_SET 4/* man - set the 'IO' type */ +# define BIO_CTRL_GET 5/* man - get the 'IO' type */ +# define BIO_CTRL_PUSH 6/* opt - internal, used to signify change */ +# define BIO_CTRL_POP 7/* opt - internal, used to signify change */ +# define BIO_CTRL_GET_CLOSE 8/* man - set the 'close' on free */ +# define BIO_CTRL_SET_CLOSE 9/* man - set the 'close' on free */ +# define BIO_CTRL_PENDING 10/* opt - is their more data buffered */ +# define BIO_CTRL_FLUSH 11/* opt - 'flush' buffered output */ +# define BIO_CTRL_DUP 12/* man - extra stuff for 'duped' BIO */ +# define BIO_CTRL_WPENDING 13/* opt - number of bytes still to write */ +/* callback is int cb(BIO *bio,state,ret); */ +# define BIO_CTRL_SET_CALLBACK 14/* opt - set callback function */ +# define BIO_CTRL_GET_CALLBACK 15/* opt - set callback function */ + +# define BIO_CTRL_SET_FILENAME 30/* BIO_s_file special */ + +/* dgram BIO stuff */ +# define BIO_CTRL_DGRAM_CONNECT 31/* BIO dgram special */ +# define BIO_CTRL_DGRAM_SET_CONNECTED 32/* allow for an externally connected + * socket to be passed in */ +# define BIO_CTRL_DGRAM_SET_RECV_TIMEOUT 33/* setsockopt, essentially */ +# define BIO_CTRL_DGRAM_GET_RECV_TIMEOUT 34/* getsockopt, essentially */ +# define BIO_CTRL_DGRAM_SET_SEND_TIMEOUT 35/* setsockopt, essentially */ +# define BIO_CTRL_DGRAM_GET_SEND_TIMEOUT 36/* getsockopt, essentially */ + +# define BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP 37/* flag whether the last */ +# define BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP 38/* I/O operation tiemd out */ + +/* #ifdef IP_MTU_DISCOVER */ +# define BIO_CTRL_DGRAM_MTU_DISCOVER 39/* set DF bit on egress packets */ +/* #endif */ + +# define BIO_CTRL_DGRAM_QUERY_MTU 40/* as kernel for current MTU */ +# define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47 +# define BIO_CTRL_DGRAM_GET_MTU 41/* get cached value for MTU */ +# define BIO_CTRL_DGRAM_SET_MTU 42/* set cached value for MTU. + * want to use this if asking + * the kernel fails */ + +# define BIO_CTRL_DGRAM_MTU_EXCEEDED 43/* check whether the MTU was + * exceed in the previous write + * operation */ + +# define BIO_CTRL_DGRAM_GET_PEER 46 +# define BIO_CTRL_DGRAM_SET_PEER 44/* Destination for the data */ + +# define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45/* Next DTLS handshake timeout + * to adjust socket timeouts */ + +# define BIO_CTRL_DGRAM_GET_MTU_OVERHEAD 49 + +# ifndef OPENSSL_NO_SCTP +/* SCTP stuff */ +# define BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE 50 +# define BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY 51 +# define BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY 52 +# define BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD 53 +# define BIO_CTRL_DGRAM_SCTP_GET_SNDINFO 60 +# define BIO_CTRL_DGRAM_SCTP_SET_SNDINFO 61 +# define BIO_CTRL_DGRAM_SCTP_GET_RCVINFO 62 +# define BIO_CTRL_DGRAM_SCTP_SET_RCVINFO 63 +# define BIO_CTRL_DGRAM_SCTP_GET_PRINFO 64 +# define BIO_CTRL_DGRAM_SCTP_SET_PRINFO 65 +# define BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN 70 +# endif + +/* modifiers */ +# define BIO_FP_READ 0x02 +# define BIO_FP_WRITE 0x04 +# define BIO_FP_APPEND 0x08 +# define BIO_FP_TEXT 0x10 + +# define BIO_FLAGS_READ 0x01 +# define BIO_FLAGS_WRITE 0x02 +# define BIO_FLAGS_IO_SPECIAL 0x04 +# define BIO_FLAGS_RWS (BIO_FLAGS_READ|BIO_FLAGS_WRITE|BIO_FLAGS_IO_SPECIAL) +# define BIO_FLAGS_SHOULD_RETRY 0x08 +# ifndef BIO_FLAGS_UPLINK +/* + * "UPLINK" flag denotes file descriptors provided by application. It + * defaults to 0, as most platforms don't require UPLINK interface. + */ +# define BIO_FLAGS_UPLINK 0 +# endif + +/* Used in BIO_gethostbyname() */ +# define BIO_GHBN_CTRL_HITS 1 +# define BIO_GHBN_CTRL_MISSES 2 +# define BIO_GHBN_CTRL_CACHE_SIZE 3 +# define BIO_GHBN_CTRL_GET_ENTRY 4 +# define BIO_GHBN_CTRL_FLUSH 5 + +/* Mostly used in the SSL BIO */ +/*- + * Not used anymore + * #define BIO_FLAGS_PROTOCOL_DELAYED_READ 0x10 + * #define BIO_FLAGS_PROTOCOL_DELAYED_WRITE 0x20 + * #define BIO_FLAGS_PROTOCOL_STARTUP 0x40 + */ + +# define BIO_FLAGS_BASE64_NO_NL 0x100 + +/* + * This is used with memory BIOs: it means we shouldn't free up or change the + * data in any way. + */ +# define BIO_FLAGS_MEM_RDONLY 0x200 + +typedef struct bio_st BIO; + +void BIO_set_flags(BIO *b, int flags); +int BIO_test_flags(const BIO *b, int flags); +void BIO_clear_flags(BIO *b, int flags); + +# define BIO_get_flags(b) BIO_test_flags(b, ~(0x0)) +# define BIO_set_retry_special(b) \ + BIO_set_flags(b, (BIO_FLAGS_IO_SPECIAL|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_set_retry_read(b) \ + BIO_set_flags(b, (BIO_FLAGS_READ|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_set_retry_write(b) \ + BIO_set_flags(b, (BIO_FLAGS_WRITE|BIO_FLAGS_SHOULD_RETRY)) + +/* These are normally used internally in BIOs */ +# define BIO_clear_retry_flags(b) \ + BIO_clear_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) +# define BIO_get_retry_flags(b) \ + BIO_test_flags(b, (BIO_FLAGS_RWS|BIO_FLAGS_SHOULD_RETRY)) + +/* These should be used by the application to tell why we should retry */ +# define BIO_should_read(a) BIO_test_flags(a, BIO_FLAGS_READ) +# define BIO_should_write(a) BIO_test_flags(a, BIO_FLAGS_WRITE) +# define BIO_should_io_special(a) BIO_test_flags(a, BIO_FLAGS_IO_SPECIAL) +# define BIO_retry_type(a) BIO_test_flags(a, BIO_FLAGS_RWS) +# define BIO_should_retry(a) BIO_test_flags(a, BIO_FLAGS_SHOULD_RETRY) + +/* + * The next three are used in conjunction with the BIO_should_io_special() + * condition. After this returns true, BIO *BIO_get_retry_BIO(BIO *bio, int + * *reason); will walk the BIO stack and return the 'reason' for the special + * and the offending BIO. Given a BIO, BIO_get_retry_reason(bio) will return + * the code. + */ +/* + * Returned from the SSL bio when the certificate retrieval code had an error + */ +# define BIO_RR_SSL_X509_LOOKUP 0x01 +/* Returned from the connect BIO when a connect would have blocked */ +# define BIO_RR_CONNECT 0x02 +/* Returned from the accept BIO when an accept would have blocked */ +# define BIO_RR_ACCEPT 0x03 + +/* These are passed by the BIO callback */ +# define BIO_CB_FREE 0x01 +# define BIO_CB_READ 0x02 +# define BIO_CB_WRITE 0x03 +# define BIO_CB_PUTS 0x04 +# define BIO_CB_GETS 0x05 +# define BIO_CB_CTRL 0x06 + +/* + * The callback is called before and after the underling operation, The + * BIO_CB_RETURN flag indicates if it is after the call + */ +# define BIO_CB_RETURN 0x80 +# define BIO_CB_return(a) ((a)|BIO_CB_RETURN) +# define BIO_cb_pre(a) (!((a)&BIO_CB_RETURN)) +# define BIO_cb_post(a) ((a)&BIO_CB_RETURN) + +long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *, + int, long, long); +void BIO_set_callback(BIO *b, + long (*callback) (struct bio_st *, int, const char *, + int, long, long)); +char *BIO_get_callback_arg(const BIO *b); +void BIO_set_callback_arg(BIO *b, char *arg); + +const char *BIO_method_name(const BIO *b); +int BIO_method_type(const BIO *b); + +typedef void bio_info_cb (struct bio_st *, int, const char *, int, long, + long); + +typedef struct bio_method_st { + int type; + const char *name; + int (*bwrite) (BIO *, const char *, int); + int (*bread) (BIO *, char *, int); + int (*bputs) (BIO *, const char *); + int (*bgets) (BIO *, char *, int); + long (*ctrl) (BIO *, int, long, void *); + int (*create) (BIO *); + int (*destroy) (BIO *); + long (*callback_ctrl) (BIO *, int, bio_info_cb *); +} BIO_METHOD; + +struct bio_st { + BIO_METHOD *method; + /* bio, mode, argp, argi, argl, ret */ + long (*callback) (struct bio_st *, int, const char *, int, long, long); + char *cb_arg; /* first argument for the callback */ + int init; + int shutdown; + int flags; /* extra storage */ + int retry_reason; + int num; + void *ptr; + struct bio_st *next_bio; /* used by filter BIOs */ + struct bio_st *prev_bio; /* used by filter BIOs */ + int references; + unsigned long num_read; + unsigned long num_write; + CRYPTO_EX_DATA ex_data; +}; + +DECLARE_STACK_OF(BIO) + +typedef struct bio_f_buffer_ctx_struct { + /*- + * Buffers are setup like this: + * + * <---------------------- size -----------------------> + * +---------------------------------------------------+ + * | consumed | remaining | free space | + * +---------------------------------------------------+ + * <-- off --><------- len -------> + */ + /*- BIO *bio; *//* + * this is now in the BIO struct + */ + int ibuf_size; /* how big is the input buffer */ + int obuf_size; /* how big is the output buffer */ + char *ibuf; /* the char array */ + int ibuf_len; /* how many bytes are in it */ + int ibuf_off; /* write/read offset */ + char *obuf; /* the char array */ + int obuf_len; /* how many bytes are in it */ + int obuf_off; /* write/read offset */ +} BIO_F_BUFFER_CTX; + +/* Prefix and suffix callback in ASN1 BIO */ +typedef int asn1_ps_func (BIO *b, unsigned char **pbuf, int *plen, + void *parg); + +# ifndef OPENSSL_NO_SCTP +/* SCTP parameter structs */ +struct bio_dgram_sctp_sndinfo { + uint16_t snd_sid; + uint16_t snd_flags; + uint32_t snd_ppid; + uint32_t snd_context; +}; + +struct bio_dgram_sctp_rcvinfo { + uint16_t rcv_sid; + uint16_t rcv_ssn; + uint16_t rcv_flags; + uint32_t rcv_ppid; + uint32_t rcv_tsn; + uint32_t rcv_cumtsn; + uint32_t rcv_context; +}; + +struct bio_dgram_sctp_prinfo { + uint16_t pr_policy; + uint32_t pr_value; +}; +# endif + +/* connect BIO stuff */ +# define BIO_CONN_S_BEFORE 1 +# define BIO_CONN_S_GET_IP 2 +# define BIO_CONN_S_GET_PORT 3 +# define BIO_CONN_S_CREATE_SOCKET 4 +# define BIO_CONN_S_CONNECT 5 +# define BIO_CONN_S_OK 6 +# define BIO_CONN_S_BLOCKED_CONNECT 7 +# define BIO_CONN_S_NBIO 8 +/* + * #define BIO_CONN_get_param_hostname BIO_ctrl + */ + +# define BIO_C_SET_CONNECT 100 +# define BIO_C_DO_STATE_MACHINE 101 +# define BIO_C_SET_NBIO 102 +# define BIO_C_SET_PROXY_PARAM 103 +# define BIO_C_SET_FD 104 +# define BIO_C_GET_FD 105 +# define BIO_C_SET_FILE_PTR 106 +# define BIO_C_GET_FILE_PTR 107 +# define BIO_C_SET_FILENAME 108 +# define BIO_C_SET_SSL 109 +# define BIO_C_GET_SSL 110 +# define BIO_C_SET_MD 111 +# define BIO_C_GET_MD 112 +# define BIO_C_GET_CIPHER_STATUS 113 +# define BIO_C_SET_BUF_MEM 114 +# define BIO_C_GET_BUF_MEM_PTR 115 +# define BIO_C_GET_BUFF_NUM_LINES 116 +# define BIO_C_SET_BUFF_SIZE 117 +# define BIO_C_SET_ACCEPT 118 +# define BIO_C_SSL_MODE 119 +# define BIO_C_GET_MD_CTX 120 +# define BIO_C_GET_PROXY_PARAM 121 +# define BIO_C_SET_BUFF_READ_DATA 122/* data to read first */ +# define BIO_C_GET_CONNECT 123 +# define BIO_C_GET_ACCEPT 124 +# define BIO_C_SET_SSL_RENEGOTIATE_BYTES 125 +# define BIO_C_GET_SSL_NUM_RENEGOTIATES 126 +# define BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT 127 +# define BIO_C_FILE_SEEK 128 +# define BIO_C_GET_CIPHER_CTX 129 +# define BIO_C_SET_BUF_MEM_EOF_RETURN 130/* return end of input + * value */ +# define BIO_C_SET_BIND_MODE 131 +# define BIO_C_GET_BIND_MODE 132 +# define BIO_C_FILE_TELL 133 +# define BIO_C_GET_SOCKS 134 +# define BIO_C_SET_SOCKS 135 + +# define BIO_C_SET_WRITE_BUF_SIZE 136/* for BIO_s_bio */ +# define BIO_C_GET_WRITE_BUF_SIZE 137 +# define BIO_C_MAKE_BIO_PAIR 138 +# define BIO_C_DESTROY_BIO_PAIR 139 +# define BIO_C_GET_WRITE_GUARANTEE 140 +# define BIO_C_GET_READ_REQUEST 141 +# define BIO_C_SHUTDOWN_WR 142 +# define BIO_C_NREAD0 143 +# define BIO_C_NREAD 144 +# define BIO_C_NWRITE0 145 +# define BIO_C_NWRITE 146 +# define BIO_C_RESET_READ_REQUEST 147 +# define BIO_C_SET_MD_CTX 148 + +# define BIO_C_SET_PREFIX 149 +# define BIO_C_GET_PREFIX 150 +# define BIO_C_SET_SUFFIX 151 +# define BIO_C_GET_SUFFIX 152 + +# define BIO_C_SET_EX_ARG 153 +# define BIO_C_GET_EX_ARG 154 + +# define BIO_set_app_data(s,arg) BIO_set_ex_data(s,0,arg) +# define BIO_get_app_data(s) BIO_get_ex_data(s,0) + +/* BIO_s_connect() and BIO_s_socks4a_connect() */ +# define BIO_set_conn_hostname(b,name) BIO_ctrl(b,BIO_C_SET_CONNECT,0,(char *)name) +# define BIO_set_conn_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,1,(char *)port) +# define BIO_set_conn_ip(b,ip) BIO_ctrl(b,BIO_C_SET_CONNECT,2,(char *)ip) +# define BIO_set_conn_int_port(b,port) BIO_ctrl(b,BIO_C_SET_CONNECT,3,(char *)port) +# define BIO_get_conn_hostname(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,0) +# define BIO_get_conn_port(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,1) +# define BIO_get_conn_ip(b) BIO_ptr_ctrl(b,BIO_C_GET_CONNECT,2) +# define BIO_get_conn_int_port(b) BIO_ctrl(b,BIO_C_GET_CONNECT,3,NULL) + +# define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) + +/* BIO_s_accept() */ +# define BIO_set_accept_port(b,name) BIO_ctrl(b,BIO_C_SET_ACCEPT,0,(char *)name) +# define BIO_get_accept_port(b) BIO_ptr_ctrl(b,BIO_C_GET_ACCEPT,0) +/* #define BIO_set_nbio(b,n) BIO_ctrl(b,BIO_C_SET_NBIO,(n),NULL) */ +# define BIO_set_nbio_accept(b,n) BIO_ctrl(b,BIO_C_SET_ACCEPT,1,(n)?(void *)"a":NULL) +# define BIO_set_accept_bios(b,bio) BIO_ctrl(b,BIO_C_SET_ACCEPT,2,(char *)bio) + +# define BIO_BIND_NORMAL 0 +# define BIO_BIND_REUSEADDR_IF_UNUSED 1 +# define BIO_BIND_REUSEADDR 2 +# define BIO_set_bind_mode(b,mode) BIO_ctrl(b,BIO_C_SET_BIND_MODE,mode,NULL) +# define BIO_get_bind_mode(b,mode) BIO_ctrl(b,BIO_C_GET_BIND_MODE,0,NULL) + +/* BIO_s_accept() and BIO_s_connect() */ +# define BIO_do_connect(b) BIO_do_handshake(b) +# define BIO_do_accept(b) BIO_do_handshake(b) +# define BIO_do_handshake(b) BIO_ctrl(b,BIO_C_DO_STATE_MACHINE,0,NULL) + +/* BIO_s_proxy_client() */ +# define BIO_set_url(b,url) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,0,(char *)(url)) +# define BIO_set_proxies(b,p) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,1,(char *)(p)) +/* BIO_set_nbio(b,n) */ +# define BIO_set_filter_bio(b,s) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,2,(char *)(s)) +/* BIO *BIO_get_filter_bio(BIO *bio); */ +# define BIO_set_proxy_cb(b,cb) BIO_callback_ctrl(b,BIO_C_SET_PROXY_PARAM,3,(void *(*cb)())) +# define BIO_set_proxy_header(b,sk) BIO_ctrl(b,BIO_C_SET_PROXY_PARAM,4,(char *)sk) +# define BIO_set_no_connect_return(b,bool) BIO_int_ctrl(b,BIO_C_SET_PROXY_PARAM,5,bool) + +# define BIO_get_proxy_header(b,skp) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,0,(char *)skp) +# define BIO_get_proxies(b,pxy_p) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,1,(char *)(pxy_p)) +# define BIO_get_url(b,url) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,2,(char *)(url)) +# define BIO_get_no_connect_return(b) BIO_ctrl(b,BIO_C_GET_PROXY_PARAM,5,NULL) + +/* BIO_s_datagram(), BIO_s_fd(), BIO_s_socket(), BIO_s_accept() and BIO_s_connect() */ +# define BIO_set_fd(b,fd,c) BIO_int_ctrl(b,BIO_C_SET_FD,c,fd) +# define BIO_get_fd(b,c) BIO_ctrl(b,BIO_C_GET_FD,0,(char *)c) + +/* BIO_s_file() */ +# define BIO_set_fp(b,fp,c) BIO_ctrl(b,BIO_C_SET_FILE_PTR,c,(char *)fp) +# define BIO_get_fp(b,fpp) BIO_ctrl(b,BIO_C_GET_FILE_PTR,0,(char *)fpp) + +/* BIO_s_fd() and BIO_s_file() */ +# define BIO_seek(b,ofs) (int)BIO_ctrl(b,BIO_C_FILE_SEEK,ofs,NULL) +# define BIO_tell(b) (int)BIO_ctrl(b,BIO_C_FILE_TELL,0,NULL) + +/* + * name is cast to lose const, but might be better to route through a + * function so we can do it safely + */ +# ifdef CONST_STRICT +/* + * If you are wondering why this isn't defined, its because CONST_STRICT is + * purely a compile-time kludge to allow const to be checked. + */ +int BIO_read_filename(BIO *b, const char *name); +# else +# define BIO_read_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ,(char *)name) +# endif +# define BIO_write_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_WRITE,name) +# define BIO_append_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_APPEND,name) +# define BIO_rw_filename(b,name) BIO_ctrl(b,BIO_C_SET_FILENAME, \ + BIO_CLOSE|BIO_FP_READ|BIO_FP_WRITE,name) + +/* + * WARNING WARNING, this ups the reference count on the read bio of the SSL + * structure. This is because the ssl read BIO is now pointed to by the + * next_bio field in the bio. So when you free the BIO, make sure you are + * doing a BIO_free_all() to catch the underlying BIO. + */ +# define BIO_set_ssl(b,ssl,c) BIO_ctrl(b,BIO_C_SET_SSL,c,(char *)ssl) +# define BIO_get_ssl(b,sslp) BIO_ctrl(b,BIO_C_GET_SSL,0,(char *)sslp) +# define BIO_set_ssl_mode(b,client) BIO_ctrl(b,BIO_C_SSL_MODE,client,NULL) +# define BIO_set_ssl_renegotiate_bytes(b,num) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_BYTES,num,NULL); +# define BIO_get_num_renegotiates(b) \ + BIO_ctrl(b,BIO_C_GET_SSL_NUM_RENEGOTIATES,0,NULL); +# define BIO_set_ssl_renegotiate_timeout(b,seconds) \ + BIO_ctrl(b,BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT,seconds,NULL); + +/* defined in evp.h */ +/* #define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,1,(char *)md) */ + +# define BIO_get_mem_data(b,pp) BIO_ctrl(b,BIO_CTRL_INFO,0,(char *)pp) +# define BIO_set_mem_buf(b,bm,c) BIO_ctrl(b,BIO_C_SET_BUF_MEM,c,(char *)bm) +# define BIO_get_mem_ptr(b,pp) BIO_ctrl(b,BIO_C_GET_BUF_MEM_PTR,0,(char *)pp) +# define BIO_set_mem_eof_return(b,v) \ + BIO_ctrl(b,BIO_C_SET_BUF_MEM_EOF_RETURN,v,NULL) + +/* For the BIO_f_buffer() type */ +# define BIO_get_buffer_num_lines(b) BIO_ctrl(b,BIO_C_GET_BUFF_NUM_LINES,0,NULL) +# define BIO_set_buffer_size(b,size) BIO_ctrl(b,BIO_C_SET_BUFF_SIZE,size,NULL) +# define BIO_set_read_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,0) +# define BIO_set_write_buffer_size(b,size) BIO_int_ctrl(b,BIO_C_SET_BUFF_SIZE,size,1) +# define BIO_set_buffer_read_data(b,buf,num) BIO_ctrl(b,BIO_C_SET_BUFF_READ_DATA,num,buf) + +/* Don't use the next one unless you know what you are doing :-) */ +# define BIO_dup_state(b,ret) BIO_ctrl(b,BIO_CTRL_DUP,0,(char *)(ret)) + +# define BIO_reset(b) (int)BIO_ctrl(b,BIO_CTRL_RESET,0,NULL) +# define BIO_eof(b) (int)BIO_ctrl(b,BIO_CTRL_EOF,0,NULL) +# define BIO_set_close(b,c) (int)BIO_ctrl(b,BIO_CTRL_SET_CLOSE,(c),NULL) +# define BIO_get_close(b) (int)BIO_ctrl(b,BIO_CTRL_GET_CLOSE,0,NULL) +# define BIO_pending(b) (int)BIO_ctrl(b,BIO_CTRL_PENDING,0,NULL) +# define BIO_wpending(b) (int)BIO_ctrl(b,BIO_CTRL_WPENDING,0,NULL) +/* ...pending macros have inappropriate return type */ +size_t BIO_ctrl_pending(BIO *b); +size_t BIO_ctrl_wpending(BIO *b); +# define BIO_flush(b) (int)BIO_ctrl(b,BIO_CTRL_FLUSH,0,NULL) +# define BIO_get_info_callback(b,cbp) (int)BIO_ctrl(b,BIO_CTRL_GET_CALLBACK,0, \ + cbp) +# define BIO_set_info_callback(b,cb) (int)BIO_callback_ctrl(b,BIO_CTRL_SET_CALLBACK,cb) + +/* For the BIO_f_buffer() type */ +# define BIO_buffer_get_num_lines(b) BIO_ctrl(b,BIO_CTRL_GET,0,NULL) + +/* For BIO_s_bio() */ +# define BIO_set_write_buf_size(b,size) (int)BIO_ctrl(b,BIO_C_SET_WRITE_BUF_SIZE,size,NULL) +# define BIO_get_write_buf_size(b,size) (size_t)BIO_ctrl(b,BIO_C_GET_WRITE_BUF_SIZE,size,NULL) +# define BIO_make_bio_pair(b1,b2) (int)BIO_ctrl(b1,BIO_C_MAKE_BIO_PAIR,0,b2) +# define BIO_destroy_bio_pair(b) (int)BIO_ctrl(b,BIO_C_DESTROY_BIO_PAIR,0,NULL) +# define BIO_shutdown_wr(b) (int)BIO_ctrl(b, BIO_C_SHUTDOWN_WR, 0, NULL) +/* macros with inappropriate type -- but ...pending macros use int too: */ +# define BIO_get_write_guarantee(b) (int)BIO_ctrl(b,BIO_C_GET_WRITE_GUARANTEE,0,NULL) +# define BIO_get_read_request(b) (int)BIO_ctrl(b,BIO_C_GET_READ_REQUEST,0,NULL) +size_t BIO_ctrl_get_write_guarantee(BIO *b); +size_t BIO_ctrl_get_read_request(BIO *b); +int BIO_ctrl_reset_read_request(BIO *b); + +/* ctrl macros for dgram */ +# define BIO_ctrl_dgram_connect(b,peer) \ + (int)BIO_ctrl(b,BIO_CTRL_DGRAM_CONNECT,0, (char *)peer) +# define BIO_ctrl_set_connected(b, state, peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_CONNECTED, state, (char *)peer) +# define BIO_dgram_recv_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP, 0, NULL) +# define BIO_dgram_send_timedout(b) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP, 0, NULL) +# define BIO_dgram_get_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_GET_PEER, 0, (char *)peer) +# define BIO_dgram_set_peer(b,peer) \ + (int)BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, (char *)peer) +# define BIO_dgram_get_mtu_overhead(b) \ + (unsigned int)BIO_ctrl((b), BIO_CTRL_DGRAM_GET_MTU_OVERHEAD, 0, NULL) + +/* These two aren't currently implemented */ +/* int BIO_get_ex_num(BIO *bio); */ +/* void BIO_set_ex_free_func(BIO *bio,int idx,void (*cb)()); */ +int BIO_set_ex_data(BIO *bio, int idx, void *data); +void *BIO_get_ex_data(BIO *bio, int idx); +int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +unsigned long BIO_number_read(BIO *bio); +unsigned long BIO_number_written(BIO *bio); + +/* For BIO_f_asn1() */ +int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, + asn1_ps_func *prefix_free); +int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, + asn1_ps_func **pprefix_free); +int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, + asn1_ps_func *suffix_free); +int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, + asn1_ps_func **psuffix_free); + +# ifndef OPENSSL_NO_FP_API +BIO_METHOD *BIO_s_file(void); +BIO *BIO_new_file(const char *filename, const char *mode); +BIO *BIO_new_fp(FILE *stream, int close_flag); +# define BIO_s_file_internal BIO_s_file +# endif +BIO *BIO_new(BIO_METHOD *type); +int BIO_set(BIO *a, BIO_METHOD *type); +int BIO_free(BIO *a); +void BIO_vfree(BIO *a); +int BIO_read(BIO *b, void *data, int len); +int BIO_gets(BIO *bp, char *buf, int size); +int BIO_write(BIO *b, const void *data, int len); +int BIO_puts(BIO *bp, const char *buf); +int BIO_indent(BIO *b, int indent, int max); +long BIO_ctrl(BIO *bp, int cmd, long larg, void *parg); +long BIO_callback_ctrl(BIO *b, int cmd, + void (*fp) (struct bio_st *, int, const char *, int, + long, long)); +char *BIO_ptr_ctrl(BIO *bp, int cmd, long larg); +long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg); +BIO *BIO_push(BIO *b, BIO *append); +BIO *BIO_pop(BIO *b); +void BIO_free_all(BIO *a); +BIO *BIO_find_type(BIO *b, int bio_type); +BIO *BIO_next(BIO *b); +BIO *BIO_get_retry_BIO(BIO *bio, int *reason); +int BIO_get_retry_reason(BIO *bio); +BIO *BIO_dup_chain(BIO *in); + +int BIO_nread0(BIO *bio, char **buf); +int BIO_nread(BIO *bio, char **buf, int num); +int BIO_nwrite0(BIO *bio, char **buf); +int BIO_nwrite(BIO *bio, char **buf, int num); + +long BIO_debug_callback(BIO *bio, int cmd, const char *argp, int argi, + long argl, long ret); + +BIO_METHOD *BIO_s_mem(void); +BIO *BIO_new_mem_buf(void *buf, int len); +BIO_METHOD *BIO_s_socket(void); +BIO_METHOD *BIO_s_connect(void); +BIO_METHOD *BIO_s_accept(void); +BIO_METHOD *BIO_s_fd(void); +# ifndef OPENSSL_SYS_OS2 +BIO_METHOD *BIO_s_log(void); +# endif +BIO_METHOD *BIO_s_bio(void); +BIO_METHOD *BIO_s_null(void); +BIO_METHOD *BIO_f_null(void); +BIO_METHOD *BIO_f_buffer(void); +# ifdef OPENSSL_SYS_VMS +BIO_METHOD *BIO_f_linebuffer(void); +# endif +BIO_METHOD *BIO_f_nbio_test(void); +# ifndef OPENSSL_NO_DGRAM +BIO_METHOD *BIO_s_datagram(void); +# ifndef OPENSSL_NO_SCTP +BIO_METHOD *BIO_s_datagram_sctp(void); +# endif +# endif + +/* BIO_METHOD *BIO_f_ber(void); */ + +int BIO_sock_should_retry(int i); +int BIO_sock_non_fatal_error(int error); +int BIO_dgram_non_fatal_error(int error); + +int BIO_fd_should_retry(int i); +int BIO_fd_non_fatal_error(int error); +int BIO_dump_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len); +int BIO_dump_indent_cb(int (*cb) (const void *data, size_t len, void *u), + void *u, const char *s, int len, int indent); +int BIO_dump(BIO *b, const char *bytes, int len); +int BIO_dump_indent(BIO *b, const char *bytes, int len, int indent); +# ifndef OPENSSL_NO_FP_API +int BIO_dump_fp(FILE *fp, const char *s, int len); +int BIO_dump_indent_fp(FILE *fp, const char *s, int len, int indent); +# endif +struct hostent *BIO_gethostbyname(const char *name); +/*- + * We might want a thread-safe interface too: + * struct hostent *BIO_gethostbyname_r(const char *name, + * struct hostent *result, void *buffer, size_t buflen); + * or something similar (caller allocates a struct hostent, + * pointed to by "result", and additional buffer space for the various + * substructures; if the buffer does not suffice, NULL is returned + * and an appropriate error code is set). + */ +int BIO_sock_error(int sock); +int BIO_socket_ioctl(int fd, long type, void *arg); +int BIO_socket_nbio(int fd, int mode); +int BIO_get_port(const char *str, unsigned short *port_ptr); +int BIO_get_host_ip(const char *str, unsigned char *ip); +int BIO_get_accept_socket(char *host_port, int mode); +int BIO_accept(int sock, char **ip_port); +int BIO_sock_init(void); +void BIO_sock_cleanup(void); +int BIO_set_tcp_ndelay(int sock, int turn_on); + +BIO *BIO_new_socket(int sock, int close_flag); +BIO *BIO_new_dgram(int fd, int close_flag); +# ifndef OPENSSL_NO_SCTP +BIO *BIO_new_dgram_sctp(int fd, int close_flag); +int BIO_dgram_is_sctp(BIO *bio); +int BIO_dgram_sctp_notification_cb(BIO *b, + void (*handle_notifications) (BIO *bio, + void + *context, + void *buf), + void *context); +int BIO_dgram_sctp_wait_for_dry(BIO *b); +int BIO_dgram_sctp_msg_waiting(BIO *b); +# endif +BIO *BIO_new_fd(int fd, int close_flag); +BIO *BIO_new_connect(char *host_port); +BIO *BIO_new_accept(char *host_port); + +int BIO_new_bio_pair(BIO **bio1, size_t writebuf1, + BIO **bio2, size_t writebuf2); +/* + * If successful, returns 1 and in *bio1, *bio2 two BIO pair endpoints. + * Otherwise returns 0 and sets *bio1 and *bio2 to NULL. Size 0 uses default + * value. + */ + +void BIO_copy_next_retry(BIO *b); + +/* + * long BIO_ghbn_ctrl(int cmd,int iarg,char *parg); + */ + +# ifdef __GNUC__ +# define __bio_h__attr__ __attribute__ +# else +# define __bio_h__attr__(x) +# endif +int BIO_printf(BIO *bio, const char *format, ...) +__bio_h__attr__((__format__(__printf__, 2, 3))); +int BIO_vprintf(BIO *bio, const char *format, va_list args) +__bio_h__attr__((__format__(__printf__, 2, 0))); +int BIO_snprintf(char *buf, size_t n, const char *format, ...) +__bio_h__attr__((__format__(__printf__, 3, 4))); +int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) +__bio_h__attr__((__format__(__printf__, 3, 0))); +# undef __bio_h__attr__ + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BIO_strings(void); + +/* Error codes for the BIO functions. */ + +/* Function codes. */ +# define BIO_F_ACPT_STATE 100 +# define BIO_F_BIO_ACCEPT 101 +# define BIO_F_BIO_BER_GET_HEADER 102 +# define BIO_F_BIO_CALLBACK_CTRL 131 +# define BIO_F_BIO_CTRL 103 +# define BIO_F_BIO_GETHOSTBYNAME 120 +# define BIO_F_BIO_GETS 104 +# define BIO_F_BIO_GET_ACCEPT_SOCKET 105 +# define BIO_F_BIO_GET_HOST_IP 106 +# define BIO_F_BIO_GET_PORT 107 +# define BIO_F_BIO_MAKE_PAIR 121 +# define BIO_F_BIO_NEW 108 +# define BIO_F_BIO_NEW_FILE 109 +# define BIO_F_BIO_NEW_MEM_BUF 126 +# define BIO_F_BIO_NREAD 123 +# define BIO_F_BIO_NREAD0 124 +# define BIO_F_BIO_NWRITE 125 +# define BIO_F_BIO_NWRITE0 122 +# define BIO_F_BIO_PUTS 110 +# define BIO_F_BIO_READ 111 +# define BIO_F_BIO_SOCK_INIT 112 +# define BIO_F_BIO_WRITE 113 +# define BIO_F_BUFFER_CTRL 114 +# define BIO_F_CONN_CTRL 127 +# define BIO_F_CONN_STATE 115 +# define BIO_F_DGRAM_SCTP_READ 132 +# define BIO_F_DGRAM_SCTP_WRITE 133 +# define BIO_F_FILE_CTRL 116 +# define BIO_F_FILE_READ 130 +# define BIO_F_LINEBUFFER_CTRL 129 +# define BIO_F_MEM_READ 128 +# define BIO_F_MEM_WRITE 117 +# define BIO_F_SSL_NEW 118 +# define BIO_F_WSASTARTUP 119 + +/* Reason codes. */ +# define BIO_R_ACCEPT_ERROR 100 +# define BIO_R_BAD_FOPEN_MODE 101 +# define BIO_R_BAD_HOSTNAME_LOOKUP 102 +# define BIO_R_BROKEN_PIPE 124 +# define BIO_R_CONNECT_ERROR 103 +# define BIO_R_EOF_ON_MEMORY_BIO 127 +# define BIO_R_ERROR_SETTING_NBIO 104 +# define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET 105 +# define BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET 106 +# define BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET 107 +# define BIO_R_INVALID_ARGUMENT 125 +# define BIO_R_INVALID_IP_ADDRESS 108 +# define BIO_R_IN_USE 123 +# define BIO_R_KEEPALIVE 109 +# define BIO_R_NBIO_CONNECT_ERROR 110 +# define BIO_R_NO_ACCEPT_PORT_SPECIFIED 111 +# define BIO_R_NO_HOSTNAME_SPECIFIED 112 +# define BIO_R_NO_PORT_DEFINED 113 +# define BIO_R_NO_PORT_SPECIFIED 114 +# define BIO_R_NO_SUCH_FILE 128 +# define BIO_R_NULL_PARAMETER 115 +# define BIO_R_TAG_MISMATCH 116 +# define BIO_R_UNABLE_TO_BIND_SOCKET 117 +# define BIO_R_UNABLE_TO_CREATE_SOCKET 118 +# define BIO_R_UNABLE_TO_LISTEN_SOCKET 119 +# define BIO_R_UNINITIALIZED 120 +# define BIO_R_UNSUPPORTED_METHOD 121 +# define BIO_R_WRITE_TO_READ_ONLY_BIO 126 +# define BIO_R_WSASTARTUP 122 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/bio/bio_cb.c b/libs/openssl/crypto/bio/bio_cb.c new file mode 100644 index 00000000..d3e86068 --- /dev/null +++ b/libs/openssl/crypto/bio/bio_cb.c @@ -0,0 +1,145 @@ +/* crypto/bio/bio_cb.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include "cryptlib.h" +#include +#include + +long MS_CALLBACK BIO_debug_callback(BIO *bio, int cmd, const char *argp, + int argi, long argl, long ret) +{ + BIO *b; + MS_STATIC char buf[256]; + char *p; + long r = 1; + int len; + size_t p_maxlen; + + if (BIO_CB_RETURN & cmd) + r = ret; + + len = BIO_snprintf(buf,sizeof buf,"BIO[%p]: ",(void *)bio); + + p = buf + len; + p_maxlen = sizeof(buf) - len; + + switch (cmd) { + case BIO_CB_FREE: + BIO_snprintf(p, p_maxlen, "Free - %s\n", bio->method->name); + break; + case BIO_CB_READ: + if (bio->method->type & BIO_TYPE_DESCRIPTOR) + BIO_snprintf(p, p_maxlen, "read(%d,%lu) - %s fd=%d\n", + bio->num, (unsigned long)argi, + bio->method->name, bio->num); + else + BIO_snprintf(p, p_maxlen, "read(%d,%lu) - %s\n", + bio->num, (unsigned long)argi, bio->method->name); + break; + case BIO_CB_WRITE: + if (bio->method->type & BIO_TYPE_DESCRIPTOR) + BIO_snprintf(p, p_maxlen, "write(%d,%lu) - %s fd=%d\n", + bio->num, (unsigned long)argi, + bio->method->name, bio->num); + else + BIO_snprintf(p, p_maxlen, "write(%d,%lu) - %s\n", + bio->num, (unsigned long)argi, bio->method->name); + break; + case BIO_CB_PUTS: + BIO_snprintf(p, p_maxlen, "puts() - %s\n", bio->method->name); + break; + case BIO_CB_GETS: + BIO_snprintf(p, p_maxlen, "gets(%lu) - %s\n", (unsigned long)argi, + bio->method->name); + break; + case BIO_CB_CTRL: + BIO_snprintf(p, p_maxlen, "ctrl(%lu) - %s\n", (unsigned long)argi, + bio->method->name); + break; + case BIO_CB_RETURN | BIO_CB_READ: + BIO_snprintf(p, p_maxlen, "read return %ld\n", ret); + break; + case BIO_CB_RETURN | BIO_CB_WRITE: + BIO_snprintf(p, p_maxlen, "write return %ld\n", ret); + break; + case BIO_CB_RETURN | BIO_CB_GETS: + BIO_snprintf(p, p_maxlen, "gets return %ld\n", ret); + break; + case BIO_CB_RETURN | BIO_CB_PUTS: + BIO_snprintf(p, p_maxlen, "puts return %ld\n", ret); + break; + case BIO_CB_RETURN | BIO_CB_CTRL: + BIO_snprintf(p, p_maxlen, "ctrl return %ld\n", ret); + break; + default: + BIO_snprintf(p, p_maxlen, "bio callback - unknown type (%d)\n", cmd); + break; + } + + b = (BIO *)bio->cb_arg; + if (b != NULL) + BIO_write(b, buf, strlen(buf)); +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) + else + fputs(buf, stderr); +#endif + return (r); +} diff --git a/libs/openssl/crypto/bio/bio_err.c b/libs/openssl/crypto/bio/bio_err.c new file mode 100644 index 00000000..6dd6162f --- /dev/null +++ b/libs/openssl/crypto/bio/bio_err.c @@ -0,0 +1,157 @@ +/* crypto/bio/bio_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BIO,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BIO,0,reason) + +static ERR_STRING_DATA BIO_str_functs[] = { + {ERR_FUNC(BIO_F_ACPT_STATE), "ACPT_STATE"}, + {ERR_FUNC(BIO_F_BIO_ACCEPT), "BIO_accept"}, + {ERR_FUNC(BIO_F_BIO_BER_GET_HEADER), "BIO_BER_GET_HEADER"}, + {ERR_FUNC(BIO_F_BIO_CALLBACK_CTRL), "BIO_callback_ctrl"}, + {ERR_FUNC(BIO_F_BIO_CTRL), "BIO_ctrl"}, + {ERR_FUNC(BIO_F_BIO_GETHOSTBYNAME), "BIO_gethostbyname"}, + {ERR_FUNC(BIO_F_BIO_GETS), "BIO_gets"}, + {ERR_FUNC(BIO_F_BIO_GET_ACCEPT_SOCKET), "BIO_get_accept_socket"}, + {ERR_FUNC(BIO_F_BIO_GET_HOST_IP), "BIO_get_host_ip"}, + {ERR_FUNC(BIO_F_BIO_GET_PORT), "BIO_get_port"}, + {ERR_FUNC(BIO_F_BIO_MAKE_PAIR), "BIO_MAKE_PAIR"}, + {ERR_FUNC(BIO_F_BIO_NEW), "BIO_new"}, + {ERR_FUNC(BIO_F_BIO_NEW_FILE), "BIO_new_file"}, + {ERR_FUNC(BIO_F_BIO_NEW_MEM_BUF), "BIO_new_mem_buf"}, + {ERR_FUNC(BIO_F_BIO_NREAD), "BIO_nread"}, + {ERR_FUNC(BIO_F_BIO_NREAD0), "BIO_nread0"}, + {ERR_FUNC(BIO_F_BIO_NWRITE), "BIO_nwrite"}, + {ERR_FUNC(BIO_F_BIO_NWRITE0), "BIO_nwrite0"}, + {ERR_FUNC(BIO_F_BIO_PUTS), "BIO_puts"}, + {ERR_FUNC(BIO_F_BIO_READ), "BIO_read"}, + {ERR_FUNC(BIO_F_BIO_SOCK_INIT), "BIO_sock_init"}, + {ERR_FUNC(BIO_F_BIO_WRITE), "BIO_write"}, + {ERR_FUNC(BIO_F_BUFFER_CTRL), "BUFFER_CTRL"}, + {ERR_FUNC(BIO_F_CONN_CTRL), "CONN_CTRL"}, + {ERR_FUNC(BIO_F_CONN_STATE), "CONN_STATE"}, + {ERR_FUNC(BIO_F_DGRAM_SCTP_READ), "DGRAM_SCTP_READ"}, + {ERR_FUNC(BIO_F_DGRAM_SCTP_WRITE), "DGRAM_SCTP_WRITE"}, + {ERR_FUNC(BIO_F_FILE_CTRL), "FILE_CTRL"}, + {ERR_FUNC(BIO_F_FILE_READ), "FILE_READ"}, + {ERR_FUNC(BIO_F_LINEBUFFER_CTRL), "LINEBUFFER_CTRL"}, + {ERR_FUNC(BIO_F_MEM_READ), "MEM_READ"}, + {ERR_FUNC(BIO_F_MEM_WRITE), "MEM_WRITE"}, + {ERR_FUNC(BIO_F_SSL_NEW), "SSL_new"}, + {ERR_FUNC(BIO_F_WSASTARTUP), "WSASTARTUP"}, + {0, NULL} +}; + +static ERR_STRING_DATA BIO_str_reasons[] = { + {ERR_REASON(BIO_R_ACCEPT_ERROR), "accept error"}, + {ERR_REASON(BIO_R_BAD_FOPEN_MODE), "bad fopen mode"}, + {ERR_REASON(BIO_R_BAD_HOSTNAME_LOOKUP), "bad hostname lookup"}, + {ERR_REASON(BIO_R_BROKEN_PIPE), "broken pipe"}, + {ERR_REASON(BIO_R_CONNECT_ERROR), "connect error"}, + {ERR_REASON(BIO_R_EOF_ON_MEMORY_BIO), "EOF on memory BIO"}, + {ERR_REASON(BIO_R_ERROR_SETTING_NBIO), "error setting nbio"}, + {ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET), + "error setting nbio on accepted socket"}, + {ERR_REASON(BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET), + "error setting nbio on accept socket"}, + {ERR_REASON(BIO_R_GETHOSTBYNAME_ADDR_IS_NOT_AF_INET), + "gethostbyname addr is not af inet"}, + {ERR_REASON(BIO_R_INVALID_ARGUMENT), "invalid argument"}, + {ERR_REASON(BIO_R_INVALID_IP_ADDRESS), "invalid ip address"}, + {ERR_REASON(BIO_R_IN_USE), "in use"}, + {ERR_REASON(BIO_R_KEEPALIVE), "keepalive"}, + {ERR_REASON(BIO_R_NBIO_CONNECT_ERROR), "nbio connect error"}, + {ERR_REASON(BIO_R_NO_ACCEPT_PORT_SPECIFIED), "no accept port specified"}, + {ERR_REASON(BIO_R_NO_HOSTNAME_SPECIFIED), "no hostname specified"}, + {ERR_REASON(BIO_R_NO_PORT_DEFINED), "no port defined"}, + {ERR_REASON(BIO_R_NO_PORT_SPECIFIED), "no port specified"}, + {ERR_REASON(BIO_R_NO_SUCH_FILE), "no such file"}, + {ERR_REASON(BIO_R_NULL_PARAMETER), "null parameter"}, + {ERR_REASON(BIO_R_TAG_MISMATCH), "tag mismatch"}, + {ERR_REASON(BIO_R_UNABLE_TO_BIND_SOCKET), "unable to bind socket"}, + {ERR_REASON(BIO_R_UNABLE_TO_CREATE_SOCKET), "unable to create socket"}, + {ERR_REASON(BIO_R_UNABLE_TO_LISTEN_SOCKET), "unable to listen socket"}, + {ERR_REASON(BIO_R_UNINITIALIZED), "uninitialized"}, + {ERR_REASON(BIO_R_UNSUPPORTED_METHOD), "unsupported method"}, + {ERR_REASON(BIO_R_WRITE_TO_READ_ONLY_BIO), "write to read only BIO"}, + {ERR_REASON(BIO_R_WSASTARTUP), "WSAStartup"}, + {0, NULL} +}; + +#endif + +void ERR_load_BIO_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(BIO_str_functs[0].error) == NULL) { + ERR_load_strings(0, BIO_str_functs); + ERR_load_strings(0, BIO_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/bio/bio_lcl.h b/libs/openssl/crypto/bio/bio_lcl.h new file mode 100644 index 00000000..741884da --- /dev/null +++ b/libs/openssl/crypto/bio/bio_lcl.h @@ -0,0 +1,36 @@ +#include + +#if BIO_FLAGS_UPLINK==0 +/* Shortcut UPLINK calls on most platforms... */ +# define UP_stdin stdin +# define UP_stdout stdout +# define UP_stderr stderr +# define UP_fprintf fprintf +# define UP_fgets fgets +# define UP_fread fread +# define UP_fwrite fwrite +# undef UP_fsetmod +# define UP_feof feof +# define UP_fclose fclose + +# define UP_fopen fopen +# define UP_fseek fseek +# define UP_ftell ftell +# define UP_fflush fflush +# define UP_ferror ferror +# ifdef _WIN32 +# define UP_fileno _fileno +# define UP_open _open +# define UP_read _read +# define UP_write _write +# define UP_lseek _lseek +# define UP_close _close +# else +# define UP_fileno fileno +# define UP_open open +# define UP_read read +# define UP_write write +# define UP_lseek lseek +# define UP_close close +# endif +#endif diff --git a/libs/openssl/crypto/bio/bio_lib.c b/libs/openssl/crypto/bio/bio_lib.c new file mode 100644 index 00000000..07934f8a --- /dev/null +++ b/libs/openssl/crypto/bio/bio_lib.c @@ -0,0 +1,596 @@ +/* crypto/bio/bio_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include "cryptlib.h" +#include +#include + +BIO *BIO_new(BIO_METHOD *method) +{ + BIO *ret = NULL; + + ret = (BIO *)OPENSSL_malloc(sizeof(BIO)); + if (ret == NULL) { + BIOerr(BIO_F_BIO_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + if (!BIO_set(ret, method)) { + OPENSSL_free(ret); + ret = NULL; + } + return (ret); +} + +int BIO_set(BIO *bio, BIO_METHOD *method) +{ + bio->method = method; + bio->callback = NULL; + bio->cb_arg = NULL; + bio->init = 0; + bio->shutdown = 1; + bio->flags = 0; + bio->retry_reason = 0; + bio->num = 0; + bio->ptr = NULL; + bio->prev_bio = NULL; + bio->next_bio = NULL; + bio->references = 1; + bio->num_read = 0L; + bio->num_write = 0L; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); + if (method->create != NULL) + if (!method->create(bio)) { + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, bio, &bio->ex_data); + return (0); + } + return (1); +} + +int BIO_free(BIO *a) +{ + int i; + + if (a == NULL) + return (0); + + i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_BIO); +#ifdef REF_PRINT + REF_PRINT("BIO", a); +#endif + if (i > 0) + return (1); +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "BIO_free, bad reference count\n"); + abort(); + } +#endif + if ((a->callback != NULL) && + ((i = (int)a->callback(a, BIO_CB_FREE, NULL, 0, 0L, 1L)) <= 0)) + return (i); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_BIO, a, &a->ex_data); + + if ((a->method != NULL) && (a->method->destroy != NULL)) + a->method->destroy(a); + OPENSSL_free(a); + return (1); +} + +void BIO_vfree(BIO *a) +{ + BIO_free(a); +} + +void BIO_clear_flags(BIO *b, int flags) +{ + b->flags &= ~flags; +} + +int BIO_test_flags(const BIO *b, int flags) +{ + return (b->flags & flags); +} + +void BIO_set_flags(BIO *b, int flags) +{ + b->flags |= flags; +} + +long (*BIO_get_callback(const BIO *b)) (struct bio_st *, int, const char *, + int, long, long) { + return b->callback; +} + +void BIO_set_callback(BIO *b, + long (*cb) (struct bio_st *, int, const char *, int, + long, long)) +{ + b->callback = cb; +} + +void BIO_set_callback_arg(BIO *b, char *arg) +{ + b->cb_arg = arg; +} + +char *BIO_get_callback_arg(const BIO *b) +{ + return b->cb_arg; +} + +const char *BIO_method_name(const BIO *b) +{ + return b->method->name; +} + +int BIO_method_type(const BIO *b) +{ + return b->method->type; +} + +int BIO_read(BIO *b, void *out, int outl) +{ + int i; + long (*cb) (BIO *, int, const char *, int, long, long); + + if ((b == NULL) || (b->method == NULL) || (b->method->bread == NULL)) { + BIOerr(BIO_F_BIO_READ, BIO_R_UNSUPPORTED_METHOD); + return (-2); + } + + cb = b->callback; + if ((cb != NULL) && + ((i = (int)cb(b, BIO_CB_READ, out, outl, 0L, 1L)) <= 0)) + return (i); + + if (!b->init) { + BIOerr(BIO_F_BIO_READ, BIO_R_UNINITIALIZED); + return (-2); + } + + i = b->method->bread(b, out, outl); + + if (i > 0) + b->num_read += (unsigned long)i; + + if (cb != NULL) + i = (int)cb(b, BIO_CB_READ | BIO_CB_RETURN, out, outl, 0L, (long)i); + return (i); +} + +int BIO_write(BIO *b, const void *in, int inl) +{ + int i; + long (*cb) (BIO *, int, const char *, int, long, long); + + if (b == NULL) + return (0); + + cb = b->callback; + if ((b->method == NULL) || (b->method->bwrite == NULL)) { + BIOerr(BIO_F_BIO_WRITE, BIO_R_UNSUPPORTED_METHOD); + return (-2); + } + + if ((cb != NULL) && + ((i = (int)cb(b, BIO_CB_WRITE, in, inl, 0L, 1L)) <= 0)) + return (i); + + if (!b->init) { + BIOerr(BIO_F_BIO_WRITE, BIO_R_UNINITIALIZED); + return (-2); + } + + i = b->method->bwrite(b, in, inl); + + if (i > 0) + b->num_write += (unsigned long)i; + + if (cb != NULL) + i = (int)cb(b, BIO_CB_WRITE | BIO_CB_RETURN, in, inl, 0L, (long)i); + return (i); +} + +int BIO_puts(BIO *b, const char *in) +{ + int i; + long (*cb) (BIO *, int, const char *, int, long, long); + + if ((b == NULL) || (b->method == NULL) || (b->method->bputs == NULL)) { + BIOerr(BIO_F_BIO_PUTS, BIO_R_UNSUPPORTED_METHOD); + return (-2); + } + + cb = b->callback; + + if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_PUTS, in, 0, 0L, 1L)) <= 0)) + return (i); + + if (!b->init) { + BIOerr(BIO_F_BIO_PUTS, BIO_R_UNINITIALIZED); + return (-2); + } + + i = b->method->bputs(b, in); + + if (i > 0) + b->num_write += (unsigned long)i; + + if (cb != NULL) + i = (int)cb(b, BIO_CB_PUTS | BIO_CB_RETURN, in, 0, 0L, (long)i); + return (i); +} + +int BIO_gets(BIO *b, char *in, int inl) +{ + int i; + long (*cb) (BIO *, int, const char *, int, long, long); + + if ((b == NULL) || (b->method == NULL) || (b->method->bgets == NULL)) { + BIOerr(BIO_F_BIO_GETS, BIO_R_UNSUPPORTED_METHOD); + return (-2); + } + + cb = b->callback; + + if ((cb != NULL) && ((i = (int)cb(b, BIO_CB_GETS, in, inl, 0L, 1L)) <= 0)) + return (i); + + if (!b->init) { + BIOerr(BIO_F_BIO_GETS, BIO_R_UNINITIALIZED); + return (-2); + } + + i = b->method->bgets(b, in, inl); + + if (cb != NULL) + i = (int)cb(b, BIO_CB_GETS | BIO_CB_RETURN, in, inl, 0L, (long)i); + return (i); +} + +int BIO_indent(BIO *b, int indent, int max) +{ + if (indent < 0) + indent = 0; + if (indent > max) + indent = max; + while (indent--) + if (BIO_puts(b, " ") != 1) + return 0; + return 1; +} + +long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) +{ + int i; + + i = iarg; + return (BIO_ctrl(b, cmd, larg, (char *)&i)); +} + +char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) +{ + char *p = NULL; + + if (BIO_ctrl(b, cmd, larg, (char *)&p) <= 0) + return (NULL); + else + return (p); +} + +long BIO_ctrl(BIO *b, int cmd, long larg, void *parg) +{ + long ret; + long (*cb) (BIO *, int, const char *, int, long, long); + + if (b == NULL) + return (0); + + if ((b->method == NULL) || (b->method->ctrl == NULL)) { + BIOerr(BIO_F_BIO_CTRL, BIO_R_UNSUPPORTED_METHOD); + return (-2); + } + + cb = b->callback; + + if ((cb != NULL) && + ((ret = cb(b, BIO_CB_CTRL, parg, cmd, larg, 1L)) <= 0)) + return (ret); + + ret = b->method->ctrl(b, cmd, larg, parg); + + if (cb != NULL) + ret = cb(b, BIO_CB_CTRL | BIO_CB_RETURN, parg, cmd, larg, ret); + return (ret); +} + +long BIO_callback_ctrl(BIO *b, int cmd, + void (*fp) (struct bio_st *, int, const char *, int, + long, long)) +{ + long ret; + long (*cb) (BIO *, int, const char *, int, long, long); + + if (b == NULL) + return (0); + + if ((b->method == NULL) || (b->method->callback_ctrl == NULL)) { + BIOerr(BIO_F_BIO_CALLBACK_CTRL, BIO_R_UNSUPPORTED_METHOD); + return (-2); + } + + cb = b->callback; + + if ((cb != NULL) && + ((ret = cb(b, BIO_CB_CTRL, (void *)&fp, cmd, 0, 1L)) <= 0)) + return (ret); + + ret = b->method->callback_ctrl(b, cmd, fp); + + if (cb != NULL) + ret = cb(b, BIO_CB_CTRL | BIO_CB_RETURN, (void *)&fp, cmd, 0, ret); + return (ret); +} + +/* + * It is unfortunate to duplicate in functions what the BIO_(w)pending macros + * do; but those macros have inappropriate return type, and for interfacing + * from other programming languages, C macros aren't much of a help anyway. + */ +size_t BIO_ctrl_pending(BIO *bio) +{ + return BIO_ctrl(bio, BIO_CTRL_PENDING, 0, NULL); +} + +size_t BIO_ctrl_wpending(BIO *bio) +{ + return BIO_ctrl(bio, BIO_CTRL_WPENDING, 0, NULL); +} + +/* put the 'bio' on the end of b's list of operators */ +BIO *BIO_push(BIO *b, BIO *bio) +{ + BIO *lb; + + if (b == NULL) + return (bio); + lb = b; + while (lb->next_bio != NULL) + lb = lb->next_bio; + lb->next_bio = bio; + if (bio != NULL) + bio->prev_bio = lb; + /* called to do internal processing */ + BIO_ctrl(b, BIO_CTRL_PUSH, 0, lb); + return (b); +} + +/* Remove the first and return the rest */ +BIO *BIO_pop(BIO *b) +{ + BIO *ret; + + if (b == NULL) + return (NULL); + ret = b->next_bio; + + BIO_ctrl(b, BIO_CTRL_POP, 0, b); + + if (b->prev_bio != NULL) + b->prev_bio->next_bio = b->next_bio; + if (b->next_bio != NULL) + b->next_bio->prev_bio = b->prev_bio; + + b->next_bio = NULL; + b->prev_bio = NULL; + return (ret); +} + +BIO *BIO_get_retry_BIO(BIO *bio, int *reason) +{ + BIO *b, *last; + + b = last = bio; + for (;;) { + if (!BIO_should_retry(b)) + break; + last = b; + b = b->next_bio; + if (b == NULL) + break; + } + if (reason != NULL) + *reason = last->retry_reason; + return (last); +} + +int BIO_get_retry_reason(BIO *bio) +{ + return (bio->retry_reason); +} + +BIO *BIO_find_type(BIO *bio, int type) +{ + int mt, mask; + + if (!bio) + return NULL; + mask = type & 0xff; + do { + if (bio->method != NULL) { + mt = bio->method->type; + + if (!mask) { + if (mt & type) + return (bio); + } else if (mt == type) + return (bio); + } + bio = bio->next_bio; + } while (bio != NULL); + return (NULL); +} + +BIO *BIO_next(BIO *b) +{ + if (!b) + return NULL; + return b->next_bio; +} + +void BIO_free_all(BIO *bio) +{ + BIO *b; + int ref; + + while (bio != NULL) { + b = bio; + ref = b->references; + bio = bio->next_bio; + BIO_free(b); + /* Since ref count > 1, don't free anyone else. */ + if (ref > 1) + break; + } +} + +BIO *BIO_dup_chain(BIO *in) +{ + BIO *ret = NULL, *eoc = NULL, *bio, *new_bio; + + for (bio = in; bio != NULL; bio = bio->next_bio) { + if ((new_bio = BIO_new(bio->method)) == NULL) + goto err; + new_bio->callback = bio->callback; + new_bio->cb_arg = bio->cb_arg; + new_bio->init = bio->init; + new_bio->shutdown = bio->shutdown; + new_bio->flags = bio->flags; + + /* This will let SSL_s_sock() work with stdin/stdout */ + new_bio->num = bio->num; + + if (!BIO_dup_state(bio, (char *)new_bio)) { + BIO_free(new_bio); + goto err; + } + + /* copy app data */ + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data, + &bio->ex_data)) { + BIO_free(new_bio); + goto err; + } + + if (ret == NULL) { + eoc = new_bio; + ret = eoc; + } else { + BIO_push(eoc, new_bio); + eoc = new_bio; + } + } + return (ret); + err: + BIO_free_all(ret); + + return (NULL); +} + +void BIO_copy_next_retry(BIO *b) +{ + BIO_set_flags(b, BIO_get_retry_flags(b->next_bio)); + b->retry_reason = b->next_bio->retry_reason; +} + +int BIO_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_BIO, argl, argp, + new_func, dup_func, free_func); +} + +int BIO_set_ex_data(BIO *bio, int idx, void *data) +{ + return (CRYPTO_set_ex_data(&(bio->ex_data), idx, data)); +} + +void *BIO_get_ex_data(BIO *bio, int idx) +{ + return (CRYPTO_get_ex_data(&(bio->ex_data), idx)); +} + +unsigned long BIO_number_read(BIO *bio) +{ + if (bio) + return bio->num_read; + return 0; +} + +unsigned long BIO_number_written(BIO *bio) +{ + if (bio) + return bio->num_write; + return 0; +} + +IMPLEMENT_STACK_OF(BIO) diff --git a/libs/openssl/crypto/bio/bss_acpt.c b/libs/openssl/crypto/bio/bss_acpt.c new file mode 100644 index 00000000..d08292c3 --- /dev/null +++ b/libs/openssl/crypto/bio/bss_acpt.c @@ -0,0 +1,463 @@ +/* crypto/bio/bss_acpt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#define USE_SOCKETS +#include "cryptlib.h" +#include + +#ifndef OPENSSL_NO_SOCK + +# ifdef OPENSSL_SYS_WIN16 +# define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ +# else +# define SOCKET_PROTOCOL IPPROTO_TCP +# endif + +# if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) +/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ +# undef FIONBIO +# endif + +typedef struct bio_accept_st { + int state; + char *param_addr; + int accept_sock; + int accept_nbio; + char *addr; + int nbio; + /* + * If 0, it means normal, if 1, do a connect on bind failure, and if + * there is no-one listening, bind with SO_REUSEADDR. If 2, always use + * SO_REUSEADDR. + */ + int bind_mode; + BIO *bio_chain; +} BIO_ACCEPT; + +static int acpt_write(BIO *h, const char *buf, int num); +static int acpt_read(BIO *h, char *buf, int size); +static int acpt_puts(BIO *h, const char *str); +static long acpt_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int acpt_new(BIO *h); +static int acpt_free(BIO *data); +static int acpt_state(BIO *b, BIO_ACCEPT *c); +static void acpt_close_socket(BIO *data); +static BIO_ACCEPT *BIO_ACCEPT_new(void); +static void BIO_ACCEPT_free(BIO_ACCEPT *a); + +# define ACPT_S_BEFORE 1 +# define ACPT_S_GET_ACCEPT_SOCKET 2 +# define ACPT_S_OK 3 + +static BIO_METHOD methods_acceptp = { + BIO_TYPE_ACCEPT, + "socket accept", + acpt_write, + acpt_read, + acpt_puts, + NULL, /* connect_gets, */ + acpt_ctrl, + acpt_new, + acpt_free, + NULL, +}; + +BIO_METHOD *BIO_s_accept(void) +{ + return (&methods_acceptp); +} + +static int acpt_new(BIO *bi) +{ + BIO_ACCEPT *ba; + + bi->init = 0; + bi->num = INVALID_SOCKET; + bi->flags = 0; + if ((ba = BIO_ACCEPT_new()) == NULL) + return (0); + bi->ptr = (char *)ba; + ba->state = ACPT_S_BEFORE; + bi->shutdown = 1; + return (1); +} + +static BIO_ACCEPT *BIO_ACCEPT_new(void) +{ + BIO_ACCEPT *ret; + + if ((ret = (BIO_ACCEPT *)OPENSSL_malloc(sizeof(BIO_ACCEPT))) == NULL) + return (NULL); + + memset(ret, 0, sizeof(BIO_ACCEPT)); + ret->accept_sock = INVALID_SOCKET; + ret->bind_mode = BIO_BIND_NORMAL; + return (ret); +} + +static void BIO_ACCEPT_free(BIO_ACCEPT *a) +{ + if (a == NULL) + return; + + if (a->param_addr != NULL) + OPENSSL_free(a->param_addr); + if (a->addr != NULL) + OPENSSL_free(a->addr); + if (a->bio_chain != NULL) + BIO_free(a->bio_chain); + OPENSSL_free(a); +} + +static void acpt_close_socket(BIO *bio) +{ + BIO_ACCEPT *c; + + c = (BIO_ACCEPT *)bio->ptr; + if (c->accept_sock != INVALID_SOCKET) { + shutdown(c->accept_sock, 2); + closesocket(c->accept_sock); + c->accept_sock = INVALID_SOCKET; + bio->num = INVALID_SOCKET; + } +} + +static int acpt_free(BIO *a) +{ + BIO_ACCEPT *data; + + if (a == NULL) + return (0); + data = (BIO_ACCEPT *)a->ptr; + + if (a->shutdown) { + acpt_close_socket(a); + BIO_ACCEPT_free(data); + a->ptr = NULL; + a->flags = 0; + a->init = 0; + } + return (1); +} + +static int acpt_state(BIO *b, BIO_ACCEPT *c) +{ + BIO *bio = NULL, *dbio; + int s = -1; + int i; + + again: + switch (c->state) { + case ACPT_S_BEFORE: + if (c->param_addr == NULL) { + BIOerr(BIO_F_ACPT_STATE, BIO_R_NO_ACCEPT_PORT_SPECIFIED); + return (-1); + } + s = BIO_get_accept_socket(c->param_addr, c->bind_mode); + if (s == INVALID_SOCKET) + return (-1); + + if (c->accept_nbio) { + if (!BIO_socket_nbio(s, 1)) { + closesocket(s); + BIOerr(BIO_F_ACPT_STATE, + BIO_R_ERROR_SETTING_NBIO_ON_ACCEPT_SOCKET); + return (-1); + } + } + c->accept_sock = s; + b->num = s; + c->state = ACPT_S_GET_ACCEPT_SOCKET; + return (1); + /* break; */ + case ACPT_S_GET_ACCEPT_SOCKET: + if (b->next_bio != NULL) { + c->state = ACPT_S_OK; + goto again; + } + BIO_clear_retry_flags(b); + b->retry_reason = 0; + i = BIO_accept(c->accept_sock, &(c->addr)); + + /* -2 return means we should retry */ + if (i == -2) { + BIO_set_retry_special(b); + b->retry_reason = BIO_RR_ACCEPT; + return -1; + } + + if (i < 0) + return (i); + + bio = BIO_new_socket(i, BIO_CLOSE); + if (bio == NULL) + goto err; + + BIO_set_callback(bio, BIO_get_callback(b)); + BIO_set_callback_arg(bio, BIO_get_callback_arg(b)); + + if (c->nbio) { + if (!BIO_socket_nbio(i, 1)) { + BIOerr(BIO_F_ACPT_STATE, + BIO_R_ERROR_SETTING_NBIO_ON_ACCEPTED_SOCKET); + goto err; + } + } + + /* + * If the accept BIO has an bio_chain, we dup it and put the new + * socket at the end. + */ + if (c->bio_chain != NULL) { + if ((dbio = BIO_dup_chain(c->bio_chain)) == NULL) + goto err; + if (!BIO_push(dbio, bio)) + goto err; + bio = dbio; + } + if (BIO_push(b, bio) == NULL) + goto err; + + c->state = ACPT_S_OK; + return (1); + err: + if (bio != NULL) + BIO_free(bio); + else if (s >= 0) + closesocket(s); + return (0); + /* break; */ + case ACPT_S_OK: + if (b->next_bio == NULL) { + c->state = ACPT_S_GET_ACCEPT_SOCKET; + goto again; + } + return (1); + /* break; */ + default: + return (0); + /* break; */ + } + +} + +static int acpt_read(BIO *b, char *out, int outl) +{ + int ret = 0; + BIO_ACCEPT *data; + + BIO_clear_retry_flags(b); + data = (BIO_ACCEPT *)b->ptr; + + while (b->next_bio == NULL) { + ret = acpt_state(b, data); + if (ret <= 0) + return (ret); + } + + ret = BIO_read(b->next_bio, out, outl); + BIO_copy_next_retry(b); + return (ret); +} + +static int acpt_write(BIO *b, const char *in, int inl) +{ + int ret; + BIO_ACCEPT *data; + + BIO_clear_retry_flags(b); + data = (BIO_ACCEPT *)b->ptr; + + while (b->next_bio == NULL) { + ret = acpt_state(b, data); + if (ret <= 0) + return (ret); + } + + ret = BIO_write(b->next_bio, in, inl); + BIO_copy_next_retry(b); + return (ret); +} + +static long acpt_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + int *ip; + long ret = 1; + BIO_ACCEPT *data; + char **pp; + + data = (BIO_ACCEPT *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ret = 0; + data->state = ACPT_S_BEFORE; + acpt_close_socket(b); + b->flags = 0; + break; + case BIO_C_DO_STATE_MACHINE: + /* use this one to start the connection */ + ret = (long)acpt_state(b, data); + break; + case BIO_C_SET_ACCEPT: + if (ptr != NULL) { + if (num == 0) { + b->init = 1; + if (data->param_addr != NULL) + OPENSSL_free(data->param_addr); + data->param_addr = BUF_strdup(ptr); + } else if (num == 1) { + data->accept_nbio = (ptr != NULL); + } else if (num == 2) { + if (data->bio_chain != NULL) + BIO_free(data->bio_chain); + data->bio_chain = (BIO *)ptr; + } + } + break; + case BIO_C_SET_NBIO: + data->nbio = (int)num; + break; + case BIO_C_SET_FD: + b->init = 1; + b->num = *((int *)ptr); + data->accept_sock = b->num; + data->state = ACPT_S_GET_ACCEPT_SOCKET; + b->shutdown = (int)num; + b->init = 1; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = data->accept_sock; + ret = data->accept_sock; + } else + ret = -1; + break; + case BIO_C_GET_ACCEPT: + if (b->init) { + if (ptr != NULL) { + pp = (char **)ptr; + *pp = data->param_addr; + } else + ret = -1; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_FLUSH: + break; + case BIO_C_SET_BIND_MODE: + data->bind_mode = (int)num; + break; + case BIO_C_GET_BIND_MODE: + ret = (long)data->bind_mode; + break; + case BIO_CTRL_DUP: +/*- dbio=(BIO *)ptr; + if (data->param_port) EAY EAY + BIO_set_port(dbio,data->param_port); + if (data->param_hostname) + BIO_set_hostname(dbio,data->param_hostname); + BIO_set_nbio(dbio,data->nbio); */ + break; + + default: + ret = 0; + break; + } + return (ret); +} + +static int acpt_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = acpt_write(bp, str, n); + return (ret); +} + +BIO *BIO_new_accept(char *str) +{ + BIO *ret; + + ret = BIO_new(BIO_s_accept()); + if (ret == NULL) + return (NULL); + if (BIO_set_accept_port(ret, str)) + return (ret); + else { + BIO_free(ret); + return (NULL); + } +} + +#endif diff --git a/libs/openssl/crypto/bio/bss_bio.c b/libs/openssl/crypto/bio/bss_bio.c new file mode 100644 index 00000000..4d8727f8 --- /dev/null +++ b/libs/openssl/crypto/bio/bss_bio.c @@ -0,0 +1,886 @@ +/* crypto/bio/bss_bio.c */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Special method for a BIO where the other endpoint is also a BIO of this + * kind, handled by the same thread (i.e. the "peer" is actually ourselves, + * wearing a different hat). Such "BIO pairs" are mainly for using the SSL + * library with I/O interfaces for which no specific BIO method is available. + * See ssl/ssltest.c for some hints on how this can be used. + */ + +/* BIO_DEBUG implies BIO_PAIR_DEBUG */ +#ifdef BIO_DEBUG +# ifndef BIO_PAIR_DEBUG +# define BIO_PAIR_DEBUG +# endif +#endif + +/* disable assert() unless BIO_PAIR_DEBUG has been defined */ +#ifndef BIO_PAIR_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#include "e_os.h" + +/* VxWorks defines SSIZE_MAX with an empty value causing compile errors */ +#if defined(OPENSSL_SYS_VXWORKS) +# undef SSIZE_MAX +#endif +#ifndef SSIZE_MAX +# define SSIZE_MAX INT_MAX +#endif + +static int bio_new(BIO *bio); +static int bio_free(BIO *bio); +static int bio_read(BIO *bio, char *buf, int size); +static int bio_write(BIO *bio, const char *buf, int num); +static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr); +static int bio_puts(BIO *bio, const char *str); + +static int bio_make_pair(BIO *bio1, BIO *bio2); +static void bio_destroy_pair(BIO *bio); + +static BIO_METHOD methods_biop = { + BIO_TYPE_BIO, + "BIO pair", + bio_write, + bio_read, + bio_puts, + NULL /* no bio_gets */ , + bio_ctrl, + bio_new, + bio_free, + NULL /* no bio_callback_ctrl */ +}; + +BIO_METHOD *BIO_s_bio(void) +{ + return &methods_biop; +} + +struct bio_bio_st { + BIO *peer; /* NULL if buf == NULL. If peer != NULL, then + * peer->ptr is also a bio_bio_st, and its + * "peer" member points back to us. peer != + * NULL iff init != 0 in the BIO. */ + /* This is for what we write (i.e. reading uses peer's struct): */ + int closed; /* valid iff peer != NULL */ + size_t len; /* valid iff buf != NULL; 0 if peer == NULL */ + size_t offset; /* valid iff buf != NULL; 0 if len == 0 */ + size_t size; + char *buf; /* "size" elements (if != NULL) */ + size_t request; /* valid iff peer != NULL; 0 if len != 0, + * otherwise set by peer to number of bytes + * it (unsuccessfully) tried to read, never + * more than buffer space (size-len) + * warrants. */ +}; + +static int bio_new(BIO *bio) +{ + struct bio_bio_st *b; + + b = OPENSSL_malloc(sizeof *b); + if (b == NULL) + return 0; + + b->peer = NULL; + /* enough for one TLS record (just a default) */ + b->size = 17 * 1024; + b->buf = NULL; + + bio->ptr = b; + return 1; +} + +static int bio_free(BIO *bio) +{ + struct bio_bio_st *b; + + if (bio == NULL) + return 0; + b = bio->ptr; + + assert(b != NULL); + + if (b->peer) + bio_destroy_pair(bio); + + if (b->buf != NULL) { + OPENSSL_free(b->buf); + } + + OPENSSL_free(b); + + return 1; +} + +static int bio_read(BIO *bio, char *buf, int size_) +{ + size_t size = size_; + size_t rest; + struct bio_bio_st *b, *peer_b; + + BIO_clear_retry_flags(bio); + + if (!bio->init) + return 0; + + b = bio->ptr; + assert(b != NULL); + assert(b->peer != NULL); + peer_b = b->peer->ptr; + assert(peer_b != NULL); + assert(peer_b->buf != NULL); + + peer_b->request = 0; /* will be set in "retry_read" situation */ + + if (buf == NULL || size == 0) + return 0; + + if (peer_b->len == 0) { + if (peer_b->closed) + return 0; /* writer has closed, and no data is left */ + else { + BIO_set_retry_read(bio); /* buffer is empty */ + if (size <= peer_b->size) + peer_b->request = size; + else + /* + * don't ask for more than the peer can deliver in one write + */ + peer_b->request = peer_b->size; + return -1; + } + } + + /* we can read */ + if (peer_b->len < size) + size = peer_b->len; + + /* now read "size" bytes */ + + rest = size; + + assert(rest > 0); + do { /* one or two iterations */ + size_t chunk; + + assert(rest <= peer_b->len); + if (peer_b->offset + rest <= peer_b->size) + chunk = rest; + else + /* wrap around ring buffer */ + chunk = peer_b->size - peer_b->offset; + assert(peer_b->offset + chunk <= peer_b->size); + + memcpy(buf, peer_b->buf + peer_b->offset, chunk); + + peer_b->len -= chunk; + if (peer_b->len) { + peer_b->offset += chunk; + assert(peer_b->offset <= peer_b->size); + if (peer_b->offset == peer_b->size) + peer_b->offset = 0; + buf += chunk; + } else { + /* buffer now empty, no need to advance "buf" */ + assert(chunk == rest); + peer_b->offset = 0; + } + rest -= chunk; + } + while (rest); + + return size; +} + +/*- + * non-copying interface: provide pointer to available data in buffer + * bio_nread0: return number of available bytes + * bio_nread: also advance index + * (example usage: bio_nread0(), read from buffer, bio_nread() + * or just bio_nread(), read from buffer) + */ +/* + * WARNING: The non-copying interface is largely untested as of yet and may + * contain bugs. + */ +static ossl_ssize_t bio_nread0(BIO *bio, char **buf) +{ + struct bio_bio_st *b, *peer_b; + ossl_ssize_t num; + + BIO_clear_retry_flags(bio); + + if (!bio->init) + return 0; + + b = bio->ptr; + assert(b != NULL); + assert(b->peer != NULL); + peer_b = b->peer->ptr; + assert(peer_b != NULL); + assert(peer_b->buf != NULL); + + peer_b->request = 0; + + if (peer_b->len == 0) { + char dummy; + + /* avoid code duplication -- nothing available for reading */ + return bio_read(bio, &dummy, 1); /* returns 0 or -1 */ + } + + num = peer_b->len; + if (peer_b->size < peer_b->offset + num) + /* no ring buffer wrap-around for non-copying interface */ + num = peer_b->size - peer_b->offset; + assert(num > 0); + + if (buf != NULL) + *buf = peer_b->buf + peer_b->offset; + return num; +} + +static ossl_ssize_t bio_nread(BIO *bio, char **buf, size_t num_) +{ + struct bio_bio_st *b, *peer_b; + ossl_ssize_t num, available; + + if (num_ > SSIZE_MAX) + num = SSIZE_MAX; + else + num = (ossl_ssize_t) num_; + + available = bio_nread0(bio, buf); + if (num > available) + num = available; + if (num <= 0) + return num; + + b = bio->ptr; + peer_b = b->peer->ptr; + + peer_b->len -= num; + if (peer_b->len) { + peer_b->offset += num; + assert(peer_b->offset <= peer_b->size); + if (peer_b->offset == peer_b->size) + peer_b->offset = 0; + } else + peer_b->offset = 0; + + return num; +} + +static int bio_write(BIO *bio, const char *buf, int num_) +{ + size_t num = num_; + size_t rest; + struct bio_bio_st *b; + + BIO_clear_retry_flags(bio); + + if (!bio->init || buf == NULL || num == 0) + return 0; + + b = bio->ptr; + assert(b != NULL); + assert(b->peer != NULL); + assert(b->buf != NULL); + + b->request = 0; + if (b->closed) { + /* we already closed */ + BIOerr(BIO_F_BIO_WRITE, BIO_R_BROKEN_PIPE); + return -1; + } + + assert(b->len <= b->size); + + if (b->len == b->size) { + BIO_set_retry_write(bio); /* buffer is full */ + return -1; + } + + /* we can write */ + if (num > b->size - b->len) + num = b->size - b->len; + + /* now write "num" bytes */ + + rest = num; + + assert(rest > 0); + do { /* one or two iterations */ + size_t write_offset; + size_t chunk; + + assert(b->len + rest <= b->size); + + write_offset = b->offset + b->len; + if (write_offset >= b->size) + write_offset -= b->size; + /* b->buf[write_offset] is the first byte we can write to. */ + + if (write_offset + rest <= b->size) + chunk = rest; + else + /* wrap around ring buffer */ + chunk = b->size - write_offset; + + memcpy(b->buf + write_offset, buf, chunk); + + b->len += chunk; + + assert(b->len <= b->size); + + rest -= chunk; + buf += chunk; + } + while (rest); + + return num; +} + +/*- + * non-copying interface: provide pointer to region to write to + * bio_nwrite0: check how much space is available + * bio_nwrite: also increase length + * (example usage: bio_nwrite0(), write to buffer, bio_nwrite() + * or just bio_nwrite(), write to buffer) + */ +static ossl_ssize_t bio_nwrite0(BIO *bio, char **buf) +{ + struct bio_bio_st *b; + size_t num; + size_t write_offset; + + BIO_clear_retry_flags(bio); + + if (!bio->init) + return 0; + + b = bio->ptr; + assert(b != NULL); + assert(b->peer != NULL); + assert(b->buf != NULL); + + b->request = 0; + if (b->closed) { + BIOerr(BIO_F_BIO_NWRITE0, BIO_R_BROKEN_PIPE); + return -1; + } + + assert(b->len <= b->size); + + if (b->len == b->size) { + BIO_set_retry_write(bio); + return -1; + } + + num = b->size - b->len; + write_offset = b->offset + b->len; + if (write_offset >= b->size) + write_offset -= b->size; + if (write_offset + num > b->size) + /* + * no ring buffer wrap-around for non-copying interface (to fulfil + * the promise by BIO_ctrl_get_write_guarantee, BIO_nwrite may have + * to be called twice) + */ + num = b->size - write_offset; + + if (buf != NULL) + *buf = b->buf + write_offset; + assert(write_offset + num <= b->size); + + return num; +} + +static ossl_ssize_t bio_nwrite(BIO *bio, char **buf, size_t num_) +{ + struct bio_bio_st *b; + ossl_ssize_t num, space; + + if (num_ > SSIZE_MAX) + num = SSIZE_MAX; + else + num = (ossl_ssize_t) num_; + + space = bio_nwrite0(bio, buf); + if (num > space) + num = space; + if (num <= 0) + return num; + b = bio->ptr; + assert(b != NULL); + b->len += num; + assert(b->len <= b->size); + + return num; +} + +static long bio_ctrl(BIO *bio, int cmd, long num, void *ptr) +{ + long ret; + struct bio_bio_st *b = bio->ptr; + + assert(b != NULL); + + switch (cmd) { + /* specific CTRL codes */ + + case BIO_C_SET_WRITE_BUF_SIZE: + if (b->peer) { + BIOerr(BIO_F_BIO_CTRL, BIO_R_IN_USE); + ret = 0; + } else if (num == 0) { + BIOerr(BIO_F_BIO_CTRL, BIO_R_INVALID_ARGUMENT); + ret = 0; + } else { + size_t new_size = num; + + if (b->size != new_size) { + if (b->buf) { + OPENSSL_free(b->buf); + b->buf = NULL; + } + b->size = new_size; + } + ret = 1; + } + break; + + case BIO_C_GET_WRITE_BUF_SIZE: + ret = (long)b->size; + break; + + case BIO_C_MAKE_BIO_PAIR: + { + BIO *other_bio = ptr; + + if (bio_make_pair(bio, other_bio)) + ret = 1; + else + ret = 0; + } + break; + + case BIO_C_DESTROY_BIO_PAIR: + /* + * Affects both BIOs in the pair -- call just once! Or let + * BIO_free(bio1); BIO_free(bio2); do the job. + */ + bio_destroy_pair(bio); + ret = 1; + break; + + case BIO_C_GET_WRITE_GUARANTEE: + /* + * How many bytes can the caller feed to the next write without + * having to keep any? + */ + if (b->peer == NULL || b->closed) + ret = 0; + else + ret = (long)b->size - b->len; + break; + + case BIO_C_GET_READ_REQUEST: + /* + * If the peer unsuccessfully tried to read, how many bytes were + * requested? (As with BIO_CTRL_PENDING, that number can usually be + * treated as boolean.) + */ + ret = (long)b->request; + break; + + case BIO_C_RESET_READ_REQUEST: + /* + * Reset request. (Can be useful after read attempts at the other + * side that are meant to be non-blocking, e.g. when probing SSL_read + * to see if any data is available.) + */ + b->request = 0; + ret = 1; + break; + + case BIO_C_SHUTDOWN_WR: + /* similar to shutdown(..., SHUT_WR) */ + b->closed = 1; + ret = 1; + break; + + case BIO_C_NREAD0: + /* prepare for non-copying read */ + ret = (long)bio_nread0(bio, ptr); + break; + + case BIO_C_NREAD: + /* non-copying read */ + ret = (long)bio_nread(bio, ptr, (size_t)num); + break; + + case BIO_C_NWRITE0: + /* prepare for non-copying write */ + ret = (long)bio_nwrite0(bio, ptr); + break; + + case BIO_C_NWRITE: + /* non-copying write */ + ret = (long)bio_nwrite(bio, ptr, (size_t)num); + break; + + /* standard CTRL codes follow */ + + case BIO_CTRL_RESET: + if (b->buf != NULL) { + b->len = 0; + b->offset = 0; + } + ret = 0; + break; + + case BIO_CTRL_GET_CLOSE: + ret = bio->shutdown; + break; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + ret = 1; + break; + + case BIO_CTRL_PENDING: + if (b->peer != NULL) { + struct bio_bio_st *peer_b = b->peer->ptr; + + ret = (long)peer_b->len; + } else + ret = 0; + break; + + case BIO_CTRL_WPENDING: + if (b->buf != NULL) + ret = (long)b->len; + else + ret = 0; + break; + + case BIO_CTRL_DUP: + /* See BIO_dup_chain for circumstances we have to expect. */ + { + BIO *other_bio = ptr; + struct bio_bio_st *other_b; + + assert(other_bio != NULL); + other_b = other_bio->ptr; + assert(other_b != NULL); + + assert(other_b->buf == NULL); /* other_bio is always fresh */ + + other_b->size = b->size; + } + + ret = 1; + break; + + case BIO_CTRL_FLUSH: + ret = 1; + break; + + case BIO_CTRL_EOF: + { + BIO *other_bio = ptr; + + if (other_bio) { + struct bio_bio_st *other_b = other_bio->ptr; + + assert(other_b != NULL); + ret = other_b->len == 0 && other_b->closed; + } else + ret = 1; + } + break; + + default: + ret = 0; + } + return ret; +} + +static int bio_puts(BIO *bio, const char *str) +{ + return bio_write(bio, str, strlen(str)); +} + +static int bio_make_pair(BIO *bio1, BIO *bio2) +{ + struct bio_bio_st *b1, *b2; + + assert(bio1 != NULL); + assert(bio2 != NULL); + + b1 = bio1->ptr; + b2 = bio2->ptr; + + if (b1->peer != NULL || b2->peer != NULL) { + BIOerr(BIO_F_BIO_MAKE_PAIR, BIO_R_IN_USE); + return 0; + } + + if (b1->buf == NULL) { + b1->buf = OPENSSL_malloc(b1->size); + if (b1->buf == NULL) { + BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); + return 0; + } + b1->len = 0; + b1->offset = 0; + } + + if (b2->buf == NULL) { + b2->buf = OPENSSL_malloc(b2->size); + if (b2->buf == NULL) { + BIOerr(BIO_F_BIO_MAKE_PAIR, ERR_R_MALLOC_FAILURE); + return 0; + } + b2->len = 0; + b2->offset = 0; + } + + b1->peer = bio2; + b1->closed = 0; + b1->request = 0; + b2->peer = bio1; + b2->closed = 0; + b2->request = 0; + + bio1->init = 1; + bio2->init = 1; + + return 1; +} + +static void bio_destroy_pair(BIO *bio) +{ + struct bio_bio_st *b = bio->ptr; + + if (b != NULL) { + BIO *peer_bio = b->peer; + + if (peer_bio != NULL) { + struct bio_bio_st *peer_b = peer_bio->ptr; + + assert(peer_b != NULL); + assert(peer_b->peer == bio); + + peer_b->peer = NULL; + peer_bio->init = 0; + assert(peer_b->buf != NULL); + peer_b->len = 0; + peer_b->offset = 0; + + b->peer = NULL; + bio->init = 0; + assert(b->buf != NULL); + b->len = 0; + b->offset = 0; + } + } +} + +/* Exported convenience functions */ +int BIO_new_bio_pair(BIO **bio1_p, size_t writebuf1, + BIO **bio2_p, size_t writebuf2) +{ + BIO *bio1 = NULL, *bio2 = NULL; + long r; + int ret = 0; + + bio1 = BIO_new(BIO_s_bio()); + if (bio1 == NULL) + goto err; + bio2 = BIO_new(BIO_s_bio()); + if (bio2 == NULL) + goto err; + + if (writebuf1) { + r = BIO_set_write_buf_size(bio1, writebuf1); + if (!r) + goto err; + } + if (writebuf2) { + r = BIO_set_write_buf_size(bio2, writebuf2); + if (!r) + goto err; + } + + r = BIO_make_bio_pair(bio1, bio2); + if (!r) + goto err; + ret = 1; + + err: + if (ret == 0) { + if (bio1) { + BIO_free(bio1); + bio1 = NULL; + } + if (bio2) { + BIO_free(bio2); + bio2 = NULL; + } + } + + *bio1_p = bio1; + *bio2_p = bio2; + return ret; +} + +size_t BIO_ctrl_get_write_guarantee(BIO *bio) +{ + return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); +} + +size_t BIO_ctrl_get_read_request(BIO *bio) +{ + return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); +} + +int BIO_ctrl_reset_read_request(BIO *bio) +{ + return (BIO_ctrl(bio, BIO_C_RESET_READ_REQUEST, 0, NULL) != 0); +} + +/* + * BIO_nread0/nread/nwrite0/nwrite are available only for BIO pairs for now + * (conceivably some other BIOs could allow non-copying reads and writes + * too.) + */ +int BIO_nread0(BIO *bio, char **buf) +{ + long ret; + + if (!bio->init) { + BIOerr(BIO_F_BIO_NREAD0, BIO_R_UNINITIALIZED); + return -2; + } + + ret = BIO_ctrl(bio, BIO_C_NREAD0, 0, buf); + if (ret > INT_MAX) + return INT_MAX; + else + return (int)ret; +} + +int BIO_nread(BIO *bio, char **buf, int num) +{ + int ret; + + if (!bio->init) { + BIOerr(BIO_F_BIO_NREAD, BIO_R_UNINITIALIZED); + return -2; + } + + ret = (int)BIO_ctrl(bio, BIO_C_NREAD, num, buf); + if (ret > 0) + bio->num_read += ret; + return ret; +} + +int BIO_nwrite0(BIO *bio, char **buf) +{ + long ret; + + if (!bio->init) { + BIOerr(BIO_F_BIO_NWRITE0, BIO_R_UNINITIALIZED); + return -2; + } + + ret = BIO_ctrl(bio, BIO_C_NWRITE0, 0, buf); + if (ret > INT_MAX) + return INT_MAX; + else + return (int)ret; +} + +int BIO_nwrite(BIO *bio, char **buf, int num) +{ + int ret; + + if (!bio->init) { + BIOerr(BIO_F_BIO_NWRITE, BIO_R_UNINITIALIZED); + return -2; + } + + ret = BIO_ctrl(bio, BIO_C_NWRITE, num, buf); + if (ret > 0) + bio->num_write += ret; + return ret; +} diff --git a/libs/openssl/crypto/bio/bss_conn.c b/libs/openssl/crypto/bio/bss_conn.c new file mode 100644 index 00000000..ed214ca6 --- /dev/null +++ b/libs/openssl/crypto/bio/bss_conn.c @@ -0,0 +1,612 @@ +/* crypto/bio/bss_conn.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#define USE_SOCKETS +#include "cryptlib.h" +#include + +#ifndef OPENSSL_NO_SOCK + +# ifdef OPENSSL_SYS_WIN16 +# define SOCKET_PROTOCOL 0 /* more microsoft stupidity */ +# else +# define SOCKET_PROTOCOL IPPROTO_TCP +# endif + +# if (defined(OPENSSL_SYS_VMS) && __VMS_VER < 70000000) +/* FIONBIO used as a switch to enable ioctl, and that isn't in VMS < 7.0 */ +# undef FIONBIO +# endif + +typedef struct bio_connect_st { + int state; + char *param_hostname; + char *param_port; + int nbio; + unsigned char ip[4]; + unsigned short port; + struct sockaddr_in them; + /* + * int socket; this will be kept in bio->num so that it is compatible + * with the bss_sock bio + */ + /* + * called when the connection is initially made callback(BIO,state,ret); + * The callback should return 'ret'. state is for compatibility with the + * ssl info_callback + */ + int (*info_callback) (const BIO *bio, int state, int ret); +} BIO_CONNECT; + +static int conn_write(BIO *h, const char *buf, int num); +static int conn_read(BIO *h, char *buf, int size); +static int conn_puts(BIO *h, const char *str); +static long conn_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int conn_new(BIO *h); +static int conn_free(BIO *data); +static long conn_callback_ctrl(BIO *h, int cmd, bio_info_cb *); + +static int conn_state(BIO *b, BIO_CONNECT *c); +static void conn_close_socket(BIO *data); +BIO_CONNECT *BIO_CONNECT_new(void); +void BIO_CONNECT_free(BIO_CONNECT *a); + +static BIO_METHOD methods_connectp = { + BIO_TYPE_CONNECT, + "socket connect", + conn_write, + conn_read, + conn_puts, + NULL, /* connect_gets, */ + conn_ctrl, + conn_new, + conn_free, + conn_callback_ctrl, +}; + +static int conn_state(BIO *b, BIO_CONNECT *c) +{ + int ret = -1, i; + unsigned long l; + char *p, *q; + int (*cb) (const BIO *, int, int) = NULL; + + if (c->info_callback != NULL) + cb = c->info_callback; + + for (;;) { + switch (c->state) { + case BIO_CONN_S_BEFORE: + p = c->param_hostname; + if (p == NULL) { + BIOerr(BIO_F_CONN_STATE, BIO_R_NO_HOSTNAME_SPECIFIED); + goto exit_loop; + } + for (; *p != '\0'; p++) { + if ((*p == ':') || (*p == '/')) + break; + } + + i = *p; + if ((i == ':') || (i == '/')) { + + *(p++) = '\0'; + if (i == ':') { + for (q = p; *q; q++) + if (*q == '/') { + *q = '\0'; + break; + } + if (c->param_port != NULL) + OPENSSL_free(c->param_port); + c->param_port = BUF_strdup(p); + } + } + + if (c->param_port == NULL) { + BIOerr(BIO_F_CONN_STATE, BIO_R_NO_PORT_SPECIFIED); + ERR_add_error_data(2, "host=", c->param_hostname); + goto exit_loop; + } + c->state = BIO_CONN_S_GET_IP; + break; + + case BIO_CONN_S_GET_IP: + if (BIO_get_host_ip(c->param_hostname, &(c->ip[0])) <= 0) + goto exit_loop; + c->state = BIO_CONN_S_GET_PORT; + break; + + case BIO_CONN_S_GET_PORT: + if (c->param_port == NULL) { + /* abort(); */ + goto exit_loop; + } else if (BIO_get_port(c->param_port, &c->port) <= 0) + goto exit_loop; + c->state = BIO_CONN_S_CREATE_SOCKET; + break; + + case BIO_CONN_S_CREATE_SOCKET: + /* now setup address */ + memset((char *)&c->them, 0, sizeof(c->them)); + c->them.sin_family = AF_INET; + c->them.sin_port = htons((unsigned short)c->port); + l = (unsigned long) + ((unsigned long)c->ip[0] << 24L) | + ((unsigned long)c->ip[1] << 16L) | + ((unsigned long)c->ip[2] << 8L) | ((unsigned long)c->ip[3]); + c->them.sin_addr.s_addr = htonl(l); + c->state = BIO_CONN_S_CREATE_SOCKET; + + ret = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL); + if (ret == INVALID_SOCKET) { + SYSerr(SYS_F_SOCKET, get_last_socket_error()); + ERR_add_error_data(4, "host=", c->param_hostname, + ":", c->param_port); + BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET); + goto exit_loop; + } + b->num = ret; + c->state = BIO_CONN_S_NBIO; + break; + + case BIO_CONN_S_NBIO: + if (c->nbio) { + if (!BIO_socket_nbio(b->num, 1)) { + BIOerr(BIO_F_CONN_STATE, BIO_R_ERROR_SETTING_NBIO); + ERR_add_error_data(4, "host=", + c->param_hostname, ":", c->param_port); + goto exit_loop; + } + } + c->state = BIO_CONN_S_CONNECT; + +# if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE) + i = 1; + i = setsockopt(b->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, + sizeof(i)); + if (i < 0) { + SYSerr(SYS_F_SOCKET, get_last_socket_error()); + ERR_add_error_data(4, "host=", c->param_hostname, + ":", c->param_port); + BIOerr(BIO_F_CONN_STATE, BIO_R_KEEPALIVE); + goto exit_loop; + } +# endif + break; + + case BIO_CONN_S_CONNECT: + BIO_clear_retry_flags(b); + ret = connect(b->num, + (struct sockaddr *)&c->them, sizeof(c->them)); + b->retry_reason = 0; + if (ret < 0) { + if (BIO_sock_should_retry(ret)) { + BIO_set_retry_special(b); + c->state = BIO_CONN_S_BLOCKED_CONNECT; + b->retry_reason = BIO_RR_CONNECT; + } else { + SYSerr(SYS_F_CONNECT, get_last_socket_error()); + ERR_add_error_data(4, "host=", + c->param_hostname, ":", c->param_port); + BIOerr(BIO_F_CONN_STATE, BIO_R_CONNECT_ERROR); + } + goto exit_loop; + } else + c->state = BIO_CONN_S_OK; + break; + + case BIO_CONN_S_BLOCKED_CONNECT: + i = BIO_sock_error(b->num); + if (i) { + BIO_clear_retry_flags(b); + SYSerr(SYS_F_CONNECT, i); + ERR_add_error_data(4, "host=", + c->param_hostname, ":", c->param_port); + BIOerr(BIO_F_CONN_STATE, BIO_R_NBIO_CONNECT_ERROR); + ret = 0; + goto exit_loop; + } else + c->state = BIO_CONN_S_OK; + break; + + case BIO_CONN_S_OK: + ret = 1; + goto exit_loop; + default: + /* abort(); */ + goto exit_loop; + } + + if (cb != NULL) { + if (!(ret = cb((BIO *)b, c->state, ret))) + goto end; + } + } + + /* Loop does not exit */ + exit_loop: + if (cb != NULL) + ret = cb((BIO *)b, c->state, ret); + end: + return (ret); +} + +BIO_CONNECT *BIO_CONNECT_new(void) +{ + BIO_CONNECT *ret; + + if ((ret = (BIO_CONNECT *)OPENSSL_malloc(sizeof(BIO_CONNECT))) == NULL) + return (NULL); + ret->state = BIO_CONN_S_BEFORE; + ret->param_hostname = NULL; + ret->param_port = NULL; + ret->info_callback = NULL; + ret->nbio = 0; + ret->ip[0] = 0; + ret->ip[1] = 0; + ret->ip[2] = 0; + ret->ip[3] = 0; + ret->port = 0; + memset((char *)&ret->them, 0, sizeof(ret->them)); + return (ret); +} + +void BIO_CONNECT_free(BIO_CONNECT *a) +{ + if (a == NULL) + return; + + if (a->param_hostname != NULL) + OPENSSL_free(a->param_hostname); + if (a->param_port != NULL) + OPENSSL_free(a->param_port); + OPENSSL_free(a); +} + +BIO_METHOD *BIO_s_connect(void) +{ + return (&methods_connectp); +} + +static int conn_new(BIO *bi) +{ + bi->init = 0; + bi->num = INVALID_SOCKET; + bi->flags = 0; + if ((bi->ptr = (char *)BIO_CONNECT_new()) == NULL) + return (0); + else + return (1); +} + +static void conn_close_socket(BIO *bio) +{ + BIO_CONNECT *c; + + c = (BIO_CONNECT *)bio->ptr; + if (bio->num != INVALID_SOCKET) { + /* Only do a shutdown if things were established */ + if (c->state == BIO_CONN_S_OK) + shutdown(bio->num, 2); + closesocket(bio->num); + bio->num = INVALID_SOCKET; + } +} + +static int conn_free(BIO *a) +{ + BIO_CONNECT *data; + + if (a == NULL) + return (0); + data = (BIO_CONNECT *)a->ptr; + + if (a->shutdown) { + conn_close_socket(a); + BIO_CONNECT_free(data); + a->ptr = NULL; + a->flags = 0; + a->init = 0; + } + return (1); +} + +static int conn_read(BIO *b, char *out, int outl) +{ + int ret = 0; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)b->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(b, data); + if (ret <= 0) + return (ret); + } + + if (out != NULL) { + clear_socket_error(); + ret = readsocket(b->num, out, outl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_sock_should_retry(ret)) + BIO_set_retry_read(b); + } + } + return (ret); +} + +static int conn_write(BIO *b, const char *in, int inl) +{ + int ret; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)b->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(b, data); + if (ret <= 0) + return (ret); + } + + clear_socket_error(); + ret = writesocket(b->num, in, inl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_sock_should_retry(ret)) + BIO_set_retry_write(b); + } + return (ret); +} + +static long conn_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO *dbio; + int *ip; + const char **pptr = NULL; + long ret = 1; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ret = 0; + data->state = BIO_CONN_S_BEFORE; + conn_close_socket(b); + b->flags = 0; + break; + case BIO_C_DO_STATE_MACHINE: + /* use this one to start the connection */ + if (data->state != BIO_CONN_S_OK) + ret = (long)conn_state(b, data); + else + ret = 1; + break; + case BIO_C_GET_CONNECT: + if (ptr != NULL) { + pptr = (const char **)ptr; + } + + if (b->init) { + if (pptr != NULL) { + ret = 1; + if (num == 0) { + *pptr = data->param_hostname; + } else if (num == 1) { + *pptr = data->param_port; + } else if (num == 2) { + *pptr = (char *)&(data->ip[0]); + } else { + ret = 0; + } + } + if (num == 3) { + ret = data->port; + } + } else { + if (pptr != NULL) + *pptr = "not initialized"; + ret = 0; + } + break; + case BIO_C_SET_CONNECT: + if (ptr != NULL) { + b->init = 1; + if (num == 0) { + if (data->param_hostname != NULL) + OPENSSL_free(data->param_hostname); + data->param_hostname = BUF_strdup(ptr); + } else if (num == 1) { + if (data->param_port != NULL) + OPENSSL_free(data->param_port); + data->param_port = BUF_strdup(ptr); + } else if (num == 2) { + char buf[16]; + unsigned char *p = ptr; + + BIO_snprintf(buf, sizeof buf, "%d.%d.%d.%d", + p[0], p[1], p[2], p[3]); + if (data->param_hostname != NULL) + OPENSSL_free(data->param_hostname); + data->param_hostname = BUF_strdup(buf); + memcpy(&(data->ip[0]), ptr, 4); + } else if (num == 3) { + char buf[DECIMAL_SIZE(int) + 1]; + + BIO_snprintf(buf, sizeof buf, "%d", *(int *)ptr); + if (data->param_port != NULL) + OPENSSL_free(data->param_port); + data->param_port = BUF_strdup(buf); + data->port = *(int *)ptr; + } + } + break; + case BIO_C_SET_NBIO: + data->nbio = (int)num; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = b->num; + ret = b->num; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_FLUSH: + break; + case BIO_CTRL_DUP: + { + dbio = (BIO *)ptr; + if (data->param_port) + BIO_set_conn_port(dbio, data->param_port); + if (data->param_hostname) + BIO_set_conn_hostname(dbio, data->param_hostname); + BIO_set_nbio(dbio, data->nbio); + /* + * FIXME: the cast of the function seems unlikely to be a good + * idea + */ + (void)BIO_set_info_callback(dbio, + (bio_info_cb *)data->info_callback); + } + break; + case BIO_CTRL_SET_CALLBACK: + { +# if 0 /* FIXME: Should this be used? -- Richard + * Levitte */ + BIOerr(BIO_F_CONN_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ret = -1; +# else + ret = 0; +# endif + } + break; + case BIO_CTRL_GET_CALLBACK: + { + int (**fptr) (const BIO *bio, int state, int xret); + + fptr = (int (**)(const BIO *bio, int state, int xret))ptr; + *fptr = data->info_callback; + } + break; + default: + ret = 0; + break; + } + return (ret); +} + +static long conn_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)b->ptr; + + switch (cmd) { + case BIO_CTRL_SET_CALLBACK: + { + data->info_callback = + (int (*)(const struct bio_st *, int, int))fp; + } + break; + default: + ret = 0; + break; + } + return (ret); +} + +static int conn_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = conn_write(bp, str, n); + return (ret); +} + +BIO *BIO_new_connect(char *str) +{ + BIO *ret; + + ret = BIO_new(BIO_s_connect()); + if (ret == NULL) + return (NULL); + if (BIO_set_conn_hostname(ret, str)) + return (ret); + else { + BIO_free(ret); + return (NULL); + } +} + +#endif diff --git a/libs/openssl/crypto/bio/bss_dgram.c b/libs/openssl/crypto/bio/bss_dgram.c new file mode 100644 index 00000000..d12b83a8 --- /dev/null +++ b/libs/openssl/crypto/bio/bss_dgram.c @@ -0,0 +1,2011 @@ +/* crypto/bio/bio_dgram.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#define USE_SOCKETS +#include "cryptlib.h" + +#include +#ifndef OPENSSL_NO_DGRAM + +# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) +# include +# endif + +# ifndef OPENSSL_NO_SCTP +# include +# include +# define OPENSSL_SCTP_DATA_CHUNK_TYPE 0x00 +# define OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE 0xc0 +# endif + +# if defined(OPENSSL_SYS_LINUX) && !defined(IP_MTU) +# define IP_MTU 14 /* linux is lame */ +# endif + +# if defined(__FreeBSD__) && defined(IN6_IS_ADDR_V4MAPPED) +/* Standard definition causes type-punning problems. */ +# undef IN6_IS_ADDR_V4MAPPED +# define s6_addr32 __u6_addr.__u6_addr32 +# define IN6_IS_ADDR_V4MAPPED(a) \ + (((a)->s6_addr32[0] == 0) && \ + ((a)->s6_addr32[1] == 0) && \ + ((a)->s6_addr32[2] == htonl(0x0000ffff))) +# endif + +# ifdef WATT32 +# define sock_write SockWrite /* Watt-32 uses same names */ +# define sock_read SockRead +# define sock_puts SockPuts +# endif + +static int dgram_write(BIO *h, const char *buf, int num); +static int dgram_read(BIO *h, char *buf, int size); +static int dgram_puts(BIO *h, const char *str); +static long dgram_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int dgram_new(BIO *h); +static int dgram_free(BIO *data); +static int dgram_clear(BIO *bio); + +# ifndef OPENSSL_NO_SCTP +static int dgram_sctp_write(BIO *h, const char *buf, int num); +static int dgram_sctp_read(BIO *h, char *buf, int size); +static int dgram_sctp_puts(BIO *h, const char *str); +static long dgram_sctp_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int dgram_sctp_new(BIO *h); +static int dgram_sctp_free(BIO *data); +# ifdef SCTP_AUTHENTICATION_EVENT +static void dgram_sctp_handle_auth_free_key_event(BIO *b, union sctp_notification + *snp); +# endif +# endif + +static int BIO_dgram_should_retry(int s); + +static void get_current_time(struct timeval *t); + +static BIO_METHOD methods_dgramp = { + BIO_TYPE_DGRAM, + "datagram socket", + dgram_write, + dgram_read, + dgram_puts, + NULL, /* dgram_gets, */ + dgram_ctrl, + dgram_new, + dgram_free, + NULL, +}; + +# ifndef OPENSSL_NO_SCTP +static BIO_METHOD methods_dgramp_sctp = { + BIO_TYPE_DGRAM_SCTP, + "datagram sctp socket", + dgram_sctp_write, + dgram_sctp_read, + dgram_sctp_puts, + NULL, /* dgram_gets, */ + dgram_sctp_ctrl, + dgram_sctp_new, + dgram_sctp_free, + NULL, +}; +# endif + +typedef struct bio_dgram_data_st { + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +# if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +# endif + } peer; + unsigned int connected; + unsigned int _errno; + unsigned int mtu; + struct timeval next_timeout; + struct timeval socket_timeout; +} bio_dgram_data; + +# ifndef OPENSSL_NO_SCTP +typedef struct bio_dgram_sctp_save_message_st { + BIO *bio; + char *data; + int length; +} bio_dgram_sctp_save_message; + +typedef struct bio_dgram_sctp_data_st { + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +# if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +# endif + } peer; + unsigned int connected; + unsigned int _errno; + unsigned int mtu; + struct bio_dgram_sctp_sndinfo sndinfo; + struct bio_dgram_sctp_rcvinfo rcvinfo; + struct bio_dgram_sctp_prinfo prinfo; + void (*handle_notifications) (BIO *bio, void *context, void *buf); + void *notification_context; + int in_handshake; + int ccs_rcvd; + int ccs_sent; + int save_shutdown; + int peer_auth_tested; + bio_dgram_sctp_save_message saved_message; +} bio_dgram_sctp_data; +# endif + +BIO_METHOD *BIO_s_datagram(void) +{ + return (&methods_dgramp); +} + +BIO *BIO_new_dgram(int fd, int close_flag) +{ + BIO *ret; + + ret = BIO_new(BIO_s_datagram()); + if (ret == NULL) + return (NULL); + BIO_set_fd(ret, fd, close_flag); + return (ret); +} + +static int dgram_new(BIO *bi) +{ + bio_dgram_data *data = NULL; + + bi->init = 0; + bi->num = 0; + data = OPENSSL_malloc(sizeof(bio_dgram_data)); + if (data == NULL) + return 0; + memset(data, 0x00, sizeof(bio_dgram_data)); + bi->ptr = data; + + bi->flags = 0; + return (1); +} + +static int dgram_free(BIO *a) +{ + bio_dgram_data *data; + + if (a == NULL) + return (0); + if (!dgram_clear(a)) + return 0; + + data = (bio_dgram_data *)a->ptr; + if (data != NULL) + OPENSSL_free(data); + + return (1); +} + +static int dgram_clear(BIO *a) +{ + if (a == NULL) + return (0); + if (a->shutdown) { + if (a->init) { + SHUTDOWN2(a->num); + } + a->init = 0; + a->flags = 0; + } + return (1); +} + +static void dgram_adjust_rcv_timeout(BIO *b) +{ +# if defined(SO_RCVTIMEO) + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + union { + size_t s; + int i; + } sz = { + 0 + }; + + /* Is a timer active? */ + if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { + struct timeval timenow, timeleft; + + /* Read current socket timeout */ +# ifdef OPENSSL_SYS_WINDOWS + int timeout; + + sz.i = sizeof(timeout); + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, &sz.i) < 0) { + perror("getsockopt"); + } else { + data->socket_timeout.tv_sec = timeout / 1000; + data->socket_timeout.tv_usec = (timeout % 1000) * 1000; + } +# else + sz.i = sizeof(data->socket_timeout); + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + &(data->socket_timeout), (void *)&sz) < 0) { + perror("getsockopt"); + } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) + OPENSSL_assert(sz.s <= sizeof(data->socket_timeout)); +# endif + + /* Get current time */ + get_current_time(&timenow); + + /* Calculate time left until timer expires */ + memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval)); + if (timeleft.tv_usec < timenow.tv_usec) { + timeleft.tv_usec = 1000000 - timenow.tv_usec + timeleft.tv_usec; + timeleft.tv_sec--; + } else { + timeleft.tv_usec -= timenow.tv_usec; + } + if (timeleft.tv_sec < timenow.tv_sec) { + timeleft.tv_sec = 0; + timeleft.tv_usec = 1; + } else { + timeleft.tv_sec -= timenow.tv_sec; + } + + /* + * Adjust socket timeout if next handhake message timer will expire + * earlier. + */ + if ((data->socket_timeout.tv_sec == 0 + && data->socket_timeout.tv_usec == 0) + || (data->socket_timeout.tv_sec > timeleft.tv_sec) + || (data->socket_timeout.tv_sec == timeleft.tv_sec + && data->socket_timeout.tv_usec >= timeleft.tv_usec)) { +# ifdef OPENSSL_SYS_WINDOWS + timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, sizeof(timeout)) < 0) { + perror("setsockopt"); + } +# else + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft, + sizeof(struct timeval)) < 0) { + perror("setsockopt"); + } +# endif + } + } +# endif +} + +static void dgram_reset_rcv_timeout(BIO *b) +{ +# if defined(SO_RCVTIMEO) + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + + /* Is a timer active? */ + if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { +# ifdef OPENSSL_SYS_WINDOWS + int timeout = data->socket_timeout.tv_sec * 1000 + + data->socket_timeout.tv_usec / 1000; + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, sizeof(timeout)) < 0) { + perror("setsockopt"); + } +# else + if (setsockopt + (b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout), + sizeof(struct timeval)) < 0) { + perror("setsockopt"); + } +# endif + } +# endif +} + +static int dgram_read(BIO *b, char *out, int outl) +{ + int ret = 0; + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + + struct { + /* + * See commentary in b_sock.c. + */ + union { + size_t s; + int i; + } len; + union { + struct sockaddr sa; + struct sockaddr_in sa_in; +# if OPENSSL_USE_IPV6 + struct sockaddr_in6 sa_in6; +# endif + } peer; + } sa; + + sa.len.s = 0; + sa.len.i = sizeof(sa.peer); + + if (out != NULL) { + clear_socket_error(); + memset(&sa.peer, 0x00, sizeof(sa.peer)); + dgram_adjust_rcv_timeout(b); + ret = recvfrom(b->num, out, outl, 0, &sa.peer.sa, (void *)&sa.len); + if (sizeof(sa.len.i) != sizeof(sa.len.s) && sa.len.i == 0) { + OPENSSL_assert(sa.len.s <= sizeof(sa.peer)); + sa.len.i = (int)sa.len.s; + } + + if (!data->connected && ret >= 0) + BIO_ctrl(b, BIO_CTRL_DGRAM_SET_PEER, 0, &sa.peer); + + BIO_clear_retry_flags(b); + if (ret < 0) { + if (BIO_dgram_should_retry(ret)) { + BIO_set_retry_read(b); + data->_errno = get_last_socket_error(); + } + } + + dgram_reset_rcv_timeout(b); + } + return (ret); +} + +static int dgram_write(BIO *b, const char *in, int inl) +{ + int ret; + bio_dgram_data *data = (bio_dgram_data *)b->ptr; + clear_socket_error(); + + if (data->connected) + ret = writesocket(b->num, in, inl); + else { + int peerlen = sizeof(data->peer); + + if (data->peer.sa.sa_family == AF_INET) + peerlen = sizeof(data->peer.sa_in); +# if OPENSSL_USE_IPV6 + else if (data->peer.sa.sa_family == AF_INET6) + peerlen = sizeof(data->peer.sa_in6); +# endif +# if defined(NETWARE_CLIB) && defined(NETWARE_BSDSOCK) + ret = sendto(b->num, (char *)in, inl, 0, &data->peer.sa, peerlen); +# else + ret = sendto(b->num, in, inl, 0, &data->peer.sa, peerlen); +# endif + } + + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_dgram_should_retry(ret)) { + BIO_set_retry_write(b); + data->_errno = get_last_socket_error(); + +# if 0 /* higher layers are responsible for querying + * MTU, if necessary */ + if (data->_errno == EMSGSIZE) + /* retrieve the new MTU */ + BIO_ctrl(b, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); +# endif + } + } + return (ret); +} + +static long dgram_get_mtu_overhead(bio_dgram_data *data) +{ + long ret; + + switch (data->peer.sa.sa_family) { + case AF_INET: + /* + * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP + */ + ret = 28; + break; +# if OPENSSL_USE_IPV6 + case AF_INET6: +# ifdef IN6_IS_ADDR_V4MAPPED + if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr)) + /* + * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP + */ + ret = 28; + else +# endif + /* + * Assume this is UDP - 40 bytes for IP, 8 bytes for UDP + */ + ret = 48; + break; +# endif + default: + /* We don't know. Go with the historical default */ + ret = 28; + break; + } + return ret; +} + +static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + int *ip; + struct sockaddr *to = NULL; + bio_dgram_data *data = NULL; +# if defined(OPENSSL_SYS_LINUX) && (defined(IP_MTU_DISCOVER) || defined(IP_MTU)) + int sockopt_val = 0; + socklen_t sockopt_len; /* assume that system supporting IP_MTU is + * modern enough to define socklen_t */ + socklen_t addr_len; + union { + struct sockaddr sa; + struct sockaddr_in s4; +# if OPENSSL_USE_IPV6 + struct sockaddr_in6 s6; +# endif + } addr; +# endif + + data = (bio_dgram_data *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + num = 0; + ret = 0; + break; + case BIO_CTRL_INFO: + ret = 0; + break; + case BIO_C_SET_FD: + dgram_clear(b); + b->num = *((int *)ptr); + b->shutdown = (int)num; + b->init = 1; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = b->num; + ret = b->num; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + case BIO_CTRL_DGRAM_CONNECT: + to = (struct sockaddr *)ptr; +# if 0 + if (connect(b->num, to, sizeof(struct sockaddr)) < 0) { + perror("connect"); + ret = 0; + } else { +# endif + switch (to->sa_family) { + case AF_INET: + memcpy(&data->peer, to, sizeof(data->peer.sa_in)); + break; +# if OPENSSL_USE_IPV6 + case AF_INET6: + memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); + break; +# endif + default: + memcpy(&data->peer, to, sizeof(data->peer.sa)); + break; + } +# if 0 + } +# endif + break; + /* (Linux)kernel sets DF bit on outgoing IP packets */ + case BIO_CTRL_DGRAM_MTU_DISCOVER: +# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DO) + addr_len = (socklen_t) sizeof(addr); + memset((void *)&addr, 0, sizeof(addr)); + if (getsockname(b->num, &addr.sa, &addr_len) < 0) { + ret = 0; + break; + } + switch (addr.sa.sa_family) { + case AF_INET: + sockopt_val = IP_PMTUDISC_DO; + if ((ret = setsockopt(b->num, IPPROTO_IP, IP_MTU_DISCOVER, + &sockopt_val, sizeof(sockopt_val))) < 0) + perror("setsockopt"); + break; +# if OPENSSL_USE_IPV6 && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) + case AF_INET6: + sockopt_val = IPV6_PMTUDISC_DO; + if ((ret = setsockopt(b->num, IPPROTO_IPV6, IPV6_MTU_DISCOVER, + &sockopt_val, sizeof(sockopt_val))) < 0) + perror("setsockopt"); + break; +# endif + default: + ret = -1; + break; + } + ret = -1; +# else + break; +# endif + case BIO_CTRL_DGRAM_QUERY_MTU: +# if defined(OPENSSL_SYS_LINUX) && defined(IP_MTU) + addr_len = (socklen_t) sizeof(addr); + memset((void *)&addr, 0, sizeof(addr)); + if (getsockname(b->num, &addr.sa, &addr_len) < 0) { + ret = 0; + break; + } + sockopt_len = sizeof(sockopt_val); + switch (addr.sa.sa_family) { + case AF_INET: + if ((ret = + getsockopt(b->num, IPPROTO_IP, IP_MTU, (void *)&sockopt_val, + &sockopt_len)) < 0 || sockopt_val < 0) { + ret = 0; + } else { + /* + * we assume that the transport protocol is UDP and no IP + * options are used. + */ + data->mtu = sockopt_val - 8 - 20; + ret = data->mtu; + } + break; +# if OPENSSL_USE_IPV6 && defined(IPV6_MTU) + case AF_INET6: + if ((ret = + getsockopt(b->num, IPPROTO_IPV6, IPV6_MTU, + (void *)&sockopt_val, &sockopt_len)) < 0 + || sockopt_val < 0) { + ret = 0; + } else { + /* + * we assume that the transport protocol is UDP and no IPV6 + * options are used. + */ + data->mtu = sockopt_val - 8 - 40; + ret = data->mtu; + } + break; +# endif + default: + ret = 0; + break; + } +# else + ret = 0; +# endif + break; + case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: + ret = -dgram_get_mtu_overhead(data); + switch (data->peer.sa.sa_family) { + case AF_INET: + ret += 576; + break; +# if OPENSSL_USE_IPV6 + case AF_INET6: +# ifdef IN6_IS_ADDR_V4MAPPED + if (IN6_IS_ADDR_V4MAPPED(&data->peer.sa_in6.sin6_addr)) + ret += 576; + else +# endif + ret += 1280; + break; +# endif + default: + ret += 576; + break; + } + break; + case BIO_CTRL_DGRAM_GET_MTU: + return data->mtu; + break; + case BIO_CTRL_DGRAM_SET_MTU: + data->mtu = num; + ret = num; + break; + case BIO_CTRL_DGRAM_SET_CONNECTED: + to = (struct sockaddr *)ptr; + + if (to != NULL) { + data->connected = 1; + switch (to->sa_family) { + case AF_INET: + memcpy(&data->peer, to, sizeof(data->peer.sa_in)); + break; +# if OPENSSL_USE_IPV6 + case AF_INET6: + memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); + break; +# endif + default: + memcpy(&data->peer, to, sizeof(data->peer.sa)); + break; + } + } else { + data->connected = 0; + memset(&(data->peer), 0x00, sizeof(data->peer)); + } + break; + case BIO_CTRL_DGRAM_GET_PEER: + switch (data->peer.sa.sa_family) { + case AF_INET: + ret = sizeof(data->peer.sa_in); + break; +# if OPENSSL_USE_IPV6 + case AF_INET6: + ret = sizeof(data->peer.sa_in6); + break; +# endif + default: + ret = sizeof(data->peer.sa); + break; + } + if (num == 0 || num > ret) + num = ret; + memcpy(ptr, &data->peer, (ret = num)); + break; + case BIO_CTRL_DGRAM_SET_PEER: + to = (struct sockaddr *)ptr; + switch (to->sa_family) { + case AF_INET: + memcpy(&data->peer, to, sizeof(data->peer.sa_in)); + break; +# if OPENSSL_USE_IPV6 + case AF_INET6: + memcpy(&data->peer, to, sizeof(data->peer.sa_in6)); + break; +# endif + default: + memcpy(&data->peer, to, sizeof(data->peer.sa)); + break; + } + break; + case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: + memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); + break; +# if defined(SO_RCVTIMEO) + case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: +# ifdef OPENSSL_SYS_WINDOWS + { + struct timeval *tv = (struct timeval *)ptr; + int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, sizeof(timeout)) < 0) { + perror("setsockopt"); + ret = -1; + } + } +# else + if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, ptr, + sizeof(struct timeval)) < 0) { + perror("setsockopt"); + ret = -1; + } +# endif + break; + case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: + { + union { + size_t s; + int i; + } sz = { + 0 + }; +# ifdef OPENSSL_SYS_WINDOWS + int timeout; + struct timeval *tv = (struct timeval *)ptr; + + sz.i = sizeof(timeout); + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + (void *)&timeout, &sz.i) < 0) { + perror("getsockopt"); + ret = -1; + } else { + tv->tv_sec = timeout / 1000; + tv->tv_usec = (timeout % 1000) * 1000; + ret = sizeof(*tv); + } +# else + sz.i = sizeof(struct timeval); + if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, + ptr, (void *)&sz) < 0) { + perror("getsockopt"); + ret = -1; + } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) { + OPENSSL_assert(sz.s <= sizeof(struct timeval)); + ret = (int)sz.s; + } else + ret = sz.i; +# endif + } + break; +# endif +# if defined(SO_SNDTIMEO) + case BIO_CTRL_DGRAM_SET_SEND_TIMEOUT: +# ifdef OPENSSL_SYS_WINDOWS + { + struct timeval *tv = (struct timeval *)ptr; + int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000; + if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + (void *)&timeout, sizeof(timeout)) < 0) { + perror("setsockopt"); + ret = -1; + } + } +# else + if (setsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, ptr, + sizeof(struct timeval)) < 0) { + perror("setsockopt"); + ret = -1; + } +# endif + break; + case BIO_CTRL_DGRAM_GET_SEND_TIMEOUT: + { + union { + size_t s; + int i; + } sz = { + 0 + }; +# ifdef OPENSSL_SYS_WINDOWS + int timeout; + struct timeval *tv = (struct timeval *)ptr; + + sz.i = sizeof(timeout); + if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + (void *)&timeout, &sz.i) < 0) { + perror("getsockopt"); + ret = -1; + } else { + tv->tv_sec = timeout / 1000; + tv->tv_usec = (timeout % 1000) * 1000; + ret = sizeof(*tv); + } +# else + sz.i = sizeof(struct timeval); + if (getsockopt(b->num, SOL_SOCKET, SO_SNDTIMEO, + ptr, (void *)&sz) < 0) { + perror("getsockopt"); + ret = -1; + } else if (sizeof(sz.s) != sizeof(sz.i) && sz.i == 0) { + OPENSSL_assert(sz.s <= sizeof(struct timeval)); + ret = (int)sz.s; + } else + ret = sz.i; +# endif + } + break; +# endif + case BIO_CTRL_DGRAM_GET_SEND_TIMER_EXP: + /* fall-through */ + case BIO_CTRL_DGRAM_GET_RECV_TIMER_EXP: +# ifdef OPENSSL_SYS_WINDOWS + if (data->_errno == WSAETIMEDOUT) +# else + if (data->_errno == EAGAIN) +# endif + { + ret = 1; + data->_errno = 0; + } else + ret = 0; + break; +# ifdef EMSGSIZE + case BIO_CTRL_DGRAM_MTU_EXCEEDED: + if (data->_errno == EMSGSIZE) { + ret = 1; + data->_errno = 0; + } else + ret = 0; + break; +# endif + case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: + ret = dgram_get_mtu_overhead(data); + break; + default: + ret = 0; + break; + } + return (ret); +} + +static int dgram_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = dgram_write(bp, str, n); + return (ret); +} + +# ifndef OPENSSL_NO_SCTP +BIO_METHOD *BIO_s_datagram_sctp(void) +{ + return (&methods_dgramp_sctp); +} + +BIO *BIO_new_dgram_sctp(int fd, int close_flag) +{ + BIO *bio; + int ret, optval = 20000; + int auth_data = 0, auth_forward = 0; + unsigned char *p; + struct sctp_authchunk auth; + struct sctp_authchunks *authchunks; + socklen_t sockopt_len; +# ifdef SCTP_AUTHENTICATION_EVENT +# ifdef SCTP_EVENT + struct sctp_event event; +# else + struct sctp_event_subscribe event; +# endif +# endif + + bio = BIO_new(BIO_s_datagram_sctp()); + if (bio == NULL) + return (NULL); + BIO_set_fd(bio, fd, close_flag); + + /* Activate SCTP-AUTH for DATA and FORWARD-TSN chunks */ + auth.sauth_chunk = OPENSSL_SCTP_DATA_CHUNK_TYPE; + ret = + setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, + sizeof(struct sctp_authchunk)); + if (ret < 0) { + BIO_vfree(bio); + return (NULL); + } + auth.sauth_chunk = OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE; + ret = + setsockopt(fd, IPPROTO_SCTP, SCTP_AUTH_CHUNK, &auth, + sizeof(struct sctp_authchunk)); + if (ret < 0) { + BIO_vfree(bio); + return (NULL); + } + + /* + * Test if activation was successful. When using accept(), SCTP-AUTH has + * to be activated for the listening socket already, otherwise the + * connected socket won't use it. + */ + sockopt_len = (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t)); + authchunks = OPENSSL_malloc(sockopt_len); + if (!authchunks) { + BIO_vfree(bio); + return (NULL); + } + memset(authchunks, 0, sizeof(sockopt_len)); + ret = + getsockopt(fd, IPPROTO_SCTP, SCTP_LOCAL_AUTH_CHUNKS, authchunks, + &sockopt_len); + + if (ret < 0) { + OPENSSL_free(authchunks); + BIO_vfree(bio); + return (NULL); + } + + for (p = (unsigned char *)authchunks->gauth_chunks; + p < (unsigned char *)authchunks + sockopt_len; + p += sizeof(uint8_t)) { + if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) + auth_data = 1; + if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) + auth_forward = 1; + } + + OPENSSL_free(authchunks); + + OPENSSL_assert(auth_data); + OPENSSL_assert(auth_forward); + +# ifdef SCTP_AUTHENTICATION_EVENT +# ifdef SCTP_EVENT + memset(&event, 0, sizeof(struct sctp_event)); + event.se_assoc_id = 0; + event.se_type = SCTP_AUTHENTICATION_EVENT; + event.se_on = 1; + ret = + setsockopt(fd, IPPROTO_SCTP, SCTP_EVENT, &event, + sizeof(struct sctp_event)); + if (ret < 0) { + BIO_vfree(bio); + return (NULL); + } +# else + sockopt_len = (socklen_t) sizeof(struct sctp_event_subscribe); + ret = getsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, &sockopt_len); + if (ret < 0) { + BIO_vfree(bio); + return (NULL); + } + + event.sctp_authentication_event = 1; + + ret = + setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &event, + sizeof(struct sctp_event_subscribe)); + if (ret < 0) { + BIO_vfree(bio); + return (NULL); + } +# endif +# endif + + /* + * Disable partial delivery by setting the min size larger than the max + * record size of 2^14 + 2048 + 13 + */ + ret = + setsockopt(fd, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, &optval, + sizeof(optval)); + if (ret < 0) { + BIO_vfree(bio); + return (NULL); + } + + return (bio); +} + +int BIO_dgram_is_sctp(BIO *bio) +{ + return (BIO_method_type(bio) == BIO_TYPE_DGRAM_SCTP); +} + +static int dgram_sctp_new(BIO *bi) +{ + bio_dgram_sctp_data *data = NULL; + + bi->init = 0; + bi->num = 0; + data = OPENSSL_malloc(sizeof(bio_dgram_sctp_data)); + if (data == NULL) + return 0; + memset(data, 0x00, sizeof(bio_dgram_sctp_data)); +# ifdef SCTP_PR_SCTP_NONE + data->prinfo.pr_policy = SCTP_PR_SCTP_NONE; +# endif + bi->ptr = data; + + bi->flags = 0; + return (1); +} + +static int dgram_sctp_free(BIO *a) +{ + bio_dgram_sctp_data *data; + + if (a == NULL) + return (0); + if (!dgram_clear(a)) + return 0; + + data = (bio_dgram_sctp_data *) a->ptr; + if (data != NULL) { + if (data->saved_message.data != NULL) + OPENSSL_free(data->saved_message.data); + OPENSSL_free(data); + } + + return (1); +} + +# ifdef SCTP_AUTHENTICATION_EVENT +void dgram_sctp_handle_auth_free_key_event(BIO *b, + union sctp_notification *snp) +{ + int ret; + struct sctp_authkey_event *authkeyevent = &snp->sn_auth_event; + + if (authkeyevent->auth_indication == SCTP_AUTH_FREE_KEY) { + struct sctp_authkeyid authkeyid; + + /* delete key */ + authkeyid.scact_keynumber = authkeyevent->auth_keynumber; + ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, + &authkeyid, sizeof(struct sctp_authkeyid)); + } +} +# endif + +static int dgram_sctp_read(BIO *b, char *out, int outl) +{ + int ret = 0, n = 0, i, optval; + socklen_t optlen; + bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; + union sctp_notification *snp; + struct msghdr msg; + struct iovec iov; + struct cmsghdr *cmsg; + char cmsgbuf[512]; + + if (out != NULL) { + clear_socket_error(); + + do { + memset(&data->rcvinfo, 0x00, + sizeof(struct bio_dgram_sctp_rcvinfo)); + iov.iov_base = out; + iov.iov_len = outl; + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = cmsgbuf; + msg.msg_controllen = 512; + msg.msg_flags = 0; + n = recvmsg(b->num, &msg, 0); + + if (n <= 0) { + if (n < 0) + ret = n; + break; + } + + if (msg.msg_controllen > 0) { + for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; + cmsg = CMSG_NXTHDR(&msg, cmsg)) { + if (cmsg->cmsg_level != IPPROTO_SCTP) + continue; +# ifdef SCTP_RCVINFO + if (cmsg->cmsg_type == SCTP_RCVINFO) { + struct sctp_rcvinfo *rcvinfo; + + rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg); + data->rcvinfo.rcv_sid = rcvinfo->rcv_sid; + data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn; + data->rcvinfo.rcv_flags = rcvinfo->rcv_flags; + data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid; + data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn; + data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn; + data->rcvinfo.rcv_context = rcvinfo->rcv_context; + } +# endif +# ifdef SCTP_SNDRCV + if (cmsg->cmsg_type == SCTP_SNDRCV) { + struct sctp_sndrcvinfo *sndrcvinfo; + + sndrcvinfo = + (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + data->rcvinfo.rcv_sid = sndrcvinfo->sinfo_stream; + data->rcvinfo.rcv_ssn = sndrcvinfo->sinfo_ssn; + data->rcvinfo.rcv_flags = sndrcvinfo->sinfo_flags; + data->rcvinfo.rcv_ppid = sndrcvinfo->sinfo_ppid; + data->rcvinfo.rcv_tsn = sndrcvinfo->sinfo_tsn; + data->rcvinfo.rcv_cumtsn = sndrcvinfo->sinfo_cumtsn; + data->rcvinfo.rcv_context = sndrcvinfo->sinfo_context; + } +# endif + } + } + + if (msg.msg_flags & MSG_NOTIFICATION) { + snp = (union sctp_notification *)out; + if (snp->sn_header.sn_type == SCTP_SENDER_DRY_EVENT) { +# ifdef SCTP_EVENT + struct sctp_event event; +# else + struct sctp_event_subscribe event; + socklen_t eventsize; +# endif + /* + * If a message has been delayed until the socket is dry, + * it can be sent now. + */ + if (data->saved_message.length > 0) { + dgram_sctp_write(data->saved_message.bio, + data->saved_message.data, + data->saved_message.length); + OPENSSL_free(data->saved_message.data); + data->saved_message.data = NULL; + data->saved_message.length = 0; + } + + /* disable sender dry event */ +# ifdef SCTP_EVENT + memset(&event, 0, sizeof(struct sctp_event)); + event.se_assoc_id = 0; + event.se_type = SCTP_SENDER_DRY_EVENT; + event.se_on = 0; + i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, + sizeof(struct sctp_event)); + if (i < 0) { + ret = i; + break; + } +# else + eventsize = sizeof(struct sctp_event_subscribe); + i = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, + &eventsize); + if (i < 0) { + ret = i; + break; + } + + event.sctp_sender_dry_event = 0; + + i = setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, + sizeof(struct sctp_event_subscribe)); + if (i < 0) { + ret = i; + break; + } +# endif + } +# ifdef SCTP_AUTHENTICATION_EVENT + if (snp->sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) + dgram_sctp_handle_auth_free_key_event(b, snp); +# endif + + if (data->handle_notifications != NULL) + data->handle_notifications(b, data->notification_context, + (void *)out); + + memset(out, 0, outl); + } else + ret += n; + } + while ((msg.msg_flags & MSG_NOTIFICATION) && (msg.msg_flags & MSG_EOR) + && (ret < outl)); + + if (ret > 0 && !(msg.msg_flags & MSG_EOR)) { + /* Partial message read, this should never happen! */ + + /* + * The buffer was too small, this means the peer sent a message + * that was larger than allowed. + */ + if (ret == outl) + return -1; + + /* + * Test if socket buffer can handle max record size (2^14 + 2048 + * + 13) + */ + optlen = (socklen_t) sizeof(int); + ret = getsockopt(b->num, SOL_SOCKET, SO_RCVBUF, &optval, &optlen); + if (ret >= 0) + OPENSSL_assert(optval >= 18445); + + /* + * Test if SCTP doesn't partially deliver below max record size + * (2^14 + 2048 + 13) + */ + optlen = (socklen_t) sizeof(int); + ret = + getsockopt(b->num, IPPROTO_SCTP, SCTP_PARTIAL_DELIVERY_POINT, + &optval, &optlen); + if (ret >= 0) + OPENSSL_assert(optval >= 18445); + + /* + * Partially delivered notification??? Probably a bug.... + */ + OPENSSL_assert(!(msg.msg_flags & MSG_NOTIFICATION)); + + /* + * Everything seems ok till now, so it's most likely a message + * dropped by PR-SCTP. + */ + memset(out, 0, outl); + BIO_set_retry_read(b); + return -1; + } + + BIO_clear_retry_flags(b); + if (ret < 0) { + if (BIO_dgram_should_retry(ret)) { + BIO_set_retry_read(b); + data->_errno = get_last_socket_error(); + } + } + + /* Test if peer uses SCTP-AUTH before continuing */ + if (!data->peer_auth_tested) { + int ii, auth_data = 0, auth_forward = 0; + unsigned char *p; + struct sctp_authchunks *authchunks; + + optlen = + (socklen_t) (sizeof(sctp_assoc_t) + 256 * sizeof(uint8_t)); + authchunks = OPENSSL_malloc(optlen); + if (!authchunks) { + BIOerr(BIO_F_DGRAM_SCTP_READ, ERR_R_MALLOC_FAILURE); + return -1; + } + memset(authchunks, 0, sizeof(optlen)); + ii = getsockopt(b->num, IPPROTO_SCTP, SCTP_PEER_AUTH_CHUNKS, + authchunks, &optlen); + + if (ii >= 0) + for (p = (unsigned char *)authchunks->gauth_chunks; + p < (unsigned char *)authchunks + optlen; + p += sizeof(uint8_t)) { + if (*p == OPENSSL_SCTP_DATA_CHUNK_TYPE) + auth_data = 1; + if (*p == OPENSSL_SCTP_FORWARD_CUM_TSN_CHUNK_TYPE) + auth_forward = 1; + } + + OPENSSL_free(authchunks); + + if (!auth_data || !auth_forward) { + BIOerr(BIO_F_DGRAM_SCTP_READ, BIO_R_CONNECT_ERROR); + return -1; + } + + data->peer_auth_tested = 1; + } + } + return (ret); +} + +static int dgram_sctp_write(BIO *b, const char *in, int inl) +{ + int ret; + bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; + struct bio_dgram_sctp_sndinfo *sinfo = &(data->sndinfo); + struct bio_dgram_sctp_prinfo *pinfo = &(data->prinfo); + struct bio_dgram_sctp_sndinfo handshake_sinfo; + struct iovec iov[1]; + struct msghdr msg; + struct cmsghdr *cmsg; +# if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO) + char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo)) + + CMSG_SPACE(sizeof(struct sctp_prinfo))]; + struct sctp_sndinfo *sndinfo; + struct sctp_prinfo *prinfo; +# else + char cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))]; + struct sctp_sndrcvinfo *sndrcvinfo; +# endif + + clear_socket_error(); + + /* + * If we're send anything else than application data, disable all user + * parameters and flags. + */ + if (in[0] != 23) { + memset(&handshake_sinfo, 0x00, sizeof(struct bio_dgram_sctp_sndinfo)); +# ifdef SCTP_SACK_IMMEDIATELY + handshake_sinfo.snd_flags = SCTP_SACK_IMMEDIATELY; +# endif + sinfo = &handshake_sinfo; + } + + /* + * If we have to send a shutdown alert message and the socket is not dry + * yet, we have to save it and send it as soon as the socket gets dry. + */ + if (data->save_shutdown && !BIO_dgram_sctp_wait_for_dry(b)) { + char *tmp; + data->saved_message.bio = b; + if (!(tmp = OPENSSL_malloc(inl))) { + BIOerr(BIO_F_DGRAM_SCTP_WRITE, ERR_R_MALLOC_FAILURE); + return -1; + } + if (data->saved_message.data) + OPENSSL_free(data->saved_message.data); + data->saved_message.data = tmp; + memcpy(data->saved_message.data, in, inl); + data->saved_message.length = inl; + return inl; + } + + iov[0].iov_base = (char *)in; + iov[0].iov_len = inl; + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = iov; + msg.msg_iovlen = 1; + msg.msg_control = (caddr_t) cmsgbuf; + msg.msg_controllen = 0; + msg.msg_flags = 0; +# if defined(SCTP_SNDINFO) && defined(SCTP_PRINFO) + cmsg = (struct cmsghdr *)cmsgbuf; + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndinfo)); + sndinfo = (struct sctp_sndinfo *)CMSG_DATA(cmsg); + memset(sndinfo, 0, sizeof(struct sctp_sndinfo)); + sndinfo->snd_sid = sinfo->snd_sid; + sndinfo->snd_flags = sinfo->snd_flags; + sndinfo->snd_ppid = sinfo->snd_ppid; + sndinfo->snd_context = sinfo->snd_context; + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndinfo)); + + cmsg = + (struct cmsghdr *)&cmsgbuf[CMSG_SPACE(sizeof(struct sctp_sndinfo))]; + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_PRINFO; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_prinfo)); + prinfo = (struct sctp_prinfo *)CMSG_DATA(cmsg); + memset(prinfo, 0, sizeof(struct sctp_prinfo)); + prinfo->pr_policy = pinfo->pr_policy; + prinfo->pr_value = pinfo->pr_value; + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_prinfo)); +# else + cmsg = (struct cmsghdr *)cmsgbuf; + cmsg->cmsg_level = IPPROTO_SCTP; + cmsg->cmsg_type = SCTP_SNDRCV; + cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo)); + sndrcvinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); + memset(sndrcvinfo, 0, sizeof(struct sctp_sndrcvinfo)); + sndrcvinfo->sinfo_stream = sinfo->snd_sid; + sndrcvinfo->sinfo_flags = sinfo->snd_flags; +# ifdef __FreeBSD__ + sndrcvinfo->sinfo_flags |= pinfo->pr_policy; +# endif + sndrcvinfo->sinfo_ppid = sinfo->snd_ppid; + sndrcvinfo->sinfo_context = sinfo->snd_context; + sndrcvinfo->sinfo_timetolive = pinfo->pr_value; + msg.msg_controllen += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)); +# endif + + ret = sendmsg(b->num, &msg, 0); + + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_dgram_should_retry(ret)) { + BIO_set_retry_write(b); + data->_errno = get_last_socket_error(); + } + } + return (ret); +} + +static long dgram_sctp_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + bio_dgram_sctp_data *data = NULL; + socklen_t sockopt_len = 0; + struct sctp_authkeyid authkeyid; + struct sctp_authkey *authkey = NULL; + + data = (bio_dgram_sctp_data *) b->ptr; + + switch (cmd) { + case BIO_CTRL_DGRAM_QUERY_MTU: + /* + * Set to maximum (2^14) and ignore user input to enable transport + * protocol fragmentation. Returns always 2^14. + */ + data->mtu = 16384; + ret = data->mtu; + break; + case BIO_CTRL_DGRAM_SET_MTU: + /* + * Set to maximum (2^14) and ignore input to enable transport + * protocol fragmentation. Returns always 2^14. + */ + data->mtu = 16384; + ret = data->mtu; + break; + case BIO_CTRL_DGRAM_SET_CONNECTED: + case BIO_CTRL_DGRAM_CONNECT: + /* Returns always -1. */ + ret = -1; + break; + case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: + /* + * SCTP doesn't need the DTLS timer Returns always 1. + */ + break; + case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: + /* + * We allow transport protocol fragmentation so this is irrelevant + */ + ret = 0; + break; + case BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE: + if (num > 0) + data->in_handshake = 1; + else + data->in_handshake = 0; + + ret = + setsockopt(b->num, IPPROTO_SCTP, SCTP_NODELAY, + &data->in_handshake, sizeof(int)); + break; + case BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY: + /* + * New shared key for SCTP AUTH. Returns 0 on success, -1 otherwise. + */ + + /* Get active key */ + sockopt_len = sizeof(struct sctp_authkeyid); + ret = + getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, + &sockopt_len); + if (ret < 0) + break; + + /* Add new key */ + sockopt_len = sizeof(struct sctp_authkey) + 64 * sizeof(uint8_t); + authkey = OPENSSL_malloc(sockopt_len); + if (authkey == NULL) { + ret = -1; + break; + } + memset(authkey, 0x00, sockopt_len); + authkey->sca_keynumber = authkeyid.scact_keynumber + 1; +# ifndef __FreeBSD__ + /* + * This field is missing in FreeBSD 8.2 and earlier, and FreeBSD 8.3 + * and higher work without it. + */ + authkey->sca_keylength = 64; +# endif + memcpy(&authkey->sca_key[0], ptr, 64 * sizeof(uint8_t)); + + ret = + setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_KEY, authkey, + sockopt_len); + OPENSSL_free(authkey); + authkey = NULL; + if (ret < 0) + break; + + /* Reset active key */ + ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, + &authkeyid, sizeof(struct sctp_authkeyid)); + if (ret < 0) + break; + + break; + case BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY: + /* Returns 0 on success, -1 otherwise. */ + + /* Get active key */ + sockopt_len = sizeof(struct sctp_authkeyid); + ret = + getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, &authkeyid, + &sockopt_len); + if (ret < 0) + break; + + /* Set active key */ + authkeyid.scact_keynumber = authkeyid.scact_keynumber + 1; + ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, + &authkeyid, sizeof(struct sctp_authkeyid)); + if (ret < 0) + break; + + /* + * CCS has been sent, so remember that and fall through to check if + * we need to deactivate an old key + */ + data->ccs_sent = 1; + + case BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD: + /* Returns 0 on success, -1 otherwise. */ + + /* + * Has this command really been called or is this just a + * fall-through? + */ + if (cmd == BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD) + data->ccs_rcvd = 1; + + /* + * CSS has been both, received and sent, so deactivate an old key + */ + if (data->ccs_rcvd == 1 && data->ccs_sent == 1) { + /* Get active key */ + sockopt_len = sizeof(struct sctp_authkeyid); + ret = + getsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_ACTIVE_KEY, + &authkeyid, &sockopt_len); + if (ret < 0) + break; + + /* + * Deactivate key or delete second last key if + * SCTP_AUTHENTICATION_EVENT is not available. + */ + authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1; +# ifdef SCTP_AUTH_DEACTIVATE_KEY + sockopt_len = sizeof(struct sctp_authkeyid); + ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DEACTIVATE_KEY, + &authkeyid, sockopt_len); + if (ret < 0) + break; +# endif +# ifndef SCTP_AUTHENTICATION_EVENT + if (authkeyid.scact_keynumber > 0) { + authkeyid.scact_keynumber = authkeyid.scact_keynumber - 1; + ret = setsockopt(b->num, IPPROTO_SCTP, SCTP_AUTH_DELETE_KEY, + &authkeyid, sizeof(struct sctp_authkeyid)); + if (ret < 0) + break; + } +# endif + + data->ccs_rcvd = 0; + data->ccs_sent = 0; + } + break; + case BIO_CTRL_DGRAM_SCTP_GET_SNDINFO: + /* Returns the size of the copied struct. */ + if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo)) + num = sizeof(struct bio_dgram_sctp_sndinfo); + + memcpy(ptr, &(data->sndinfo), num); + ret = num; + break; + case BIO_CTRL_DGRAM_SCTP_SET_SNDINFO: + /* Returns the size of the copied struct. */ + if (num > (long)sizeof(struct bio_dgram_sctp_sndinfo)) + num = sizeof(struct bio_dgram_sctp_sndinfo); + + memcpy(&(data->sndinfo), ptr, num); + break; + case BIO_CTRL_DGRAM_SCTP_GET_RCVINFO: + /* Returns the size of the copied struct. */ + if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo)) + num = sizeof(struct bio_dgram_sctp_rcvinfo); + + memcpy(ptr, &data->rcvinfo, num); + + ret = num; + break; + case BIO_CTRL_DGRAM_SCTP_SET_RCVINFO: + /* Returns the size of the copied struct. */ + if (num > (long)sizeof(struct bio_dgram_sctp_rcvinfo)) + num = sizeof(struct bio_dgram_sctp_rcvinfo); + + memcpy(&(data->rcvinfo), ptr, num); + break; + case BIO_CTRL_DGRAM_SCTP_GET_PRINFO: + /* Returns the size of the copied struct. */ + if (num > (long)sizeof(struct bio_dgram_sctp_prinfo)) + num = sizeof(struct bio_dgram_sctp_prinfo); + + memcpy(ptr, &(data->prinfo), num); + ret = num; + break; + case BIO_CTRL_DGRAM_SCTP_SET_PRINFO: + /* Returns the size of the copied struct. */ + if (num > (long)sizeof(struct bio_dgram_sctp_prinfo)) + num = sizeof(struct bio_dgram_sctp_prinfo); + + memcpy(&(data->prinfo), ptr, num); + break; + case BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN: + /* Returns always 1. */ + if (num > 0) + data->save_shutdown = 1; + else + data->save_shutdown = 0; + break; + + default: + /* + * Pass to default ctrl function to process SCTP unspecific commands + */ + ret = dgram_ctrl(b, cmd, num, ptr); + break; + } + return (ret); +} + +int BIO_dgram_sctp_notification_cb(BIO *b, + void (*handle_notifications) (BIO *bio, + void + *context, + void *buf), + void *context) +{ + bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; + + if (handle_notifications != NULL) { + data->handle_notifications = handle_notifications; + data->notification_context = context; + } else + return -1; + + return 0; +} + +int BIO_dgram_sctp_wait_for_dry(BIO *b) +{ + int is_dry = 0; + int n, sockflags, ret; + union sctp_notification snp; + struct msghdr msg; + struct iovec iov; +# ifdef SCTP_EVENT + struct sctp_event event; +# else + struct sctp_event_subscribe event; + socklen_t eventsize; +# endif + bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; + + /* set sender dry event */ +# ifdef SCTP_EVENT + memset(&event, 0, sizeof(struct sctp_event)); + event.se_assoc_id = 0; + event.se_type = SCTP_SENDER_DRY_EVENT; + event.se_on = 1; + ret = + setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, + sizeof(struct sctp_event)); +# else + eventsize = sizeof(struct sctp_event_subscribe); + ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize); + if (ret < 0) + return -1; + + event.sctp_sender_dry_event = 1; + + ret = + setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, + sizeof(struct sctp_event_subscribe)); +# endif + if (ret < 0) + return -1; + + /* peek for notification */ + memset(&snp, 0x00, sizeof(union sctp_notification)); + iov.iov_base = (char *)&snp; + iov.iov_len = sizeof(union sctp_notification); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + + n = recvmsg(b->num, &msg, MSG_PEEK); + if (n <= 0) { + if ((n < 0) && (get_last_socket_error() != EAGAIN) + && (get_last_socket_error() != EWOULDBLOCK)) + return -1; + else + return 0; + } + + /* if we find a notification, process it and try again if necessary */ + while (msg.msg_flags & MSG_NOTIFICATION) { + memset(&snp, 0x00, sizeof(union sctp_notification)); + iov.iov_base = (char *)&snp; + iov.iov_len = sizeof(union sctp_notification); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + + n = recvmsg(b->num, &msg, 0); + if (n <= 0) { + if ((n < 0) && (get_last_socket_error() != EAGAIN) + && (get_last_socket_error() != EWOULDBLOCK)) + return -1; + else + return is_dry; + } + + if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) { + is_dry = 1; + + /* disable sender dry event */ +# ifdef SCTP_EVENT + memset(&event, 0, sizeof(struct sctp_event)); + event.se_assoc_id = 0; + event.se_type = SCTP_SENDER_DRY_EVENT; + event.se_on = 0; + ret = + setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event, + sizeof(struct sctp_event)); +# else + eventsize = (socklen_t) sizeof(struct sctp_event_subscribe); + ret = + getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, + &eventsize); + if (ret < 0) + return -1; + + event.sctp_sender_dry_event = 0; + + ret = + setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, + sizeof(struct sctp_event_subscribe)); +# endif + if (ret < 0) + return -1; + } +# ifdef SCTP_AUTHENTICATION_EVENT + if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) + dgram_sctp_handle_auth_free_key_event(b, &snp); +# endif + + if (data->handle_notifications != NULL) + data->handle_notifications(b, data->notification_context, + (void *)&snp); + + /* found notification, peek again */ + memset(&snp, 0x00, sizeof(union sctp_notification)); + iov.iov_base = (char *)&snp; + iov.iov_len = sizeof(union sctp_notification); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + + /* if we have seen the dry already, don't wait */ + if (is_dry) { + sockflags = fcntl(b->num, F_GETFL, 0); + fcntl(b->num, F_SETFL, O_NONBLOCK); + } + + n = recvmsg(b->num, &msg, MSG_PEEK); + + if (is_dry) { + fcntl(b->num, F_SETFL, sockflags); + } + + if (n <= 0) { + if ((n < 0) && (get_last_socket_error() != EAGAIN) + && (get_last_socket_error() != EWOULDBLOCK)) + return -1; + else + return is_dry; + } + } + + /* read anything else */ + return is_dry; +} + +int BIO_dgram_sctp_msg_waiting(BIO *b) +{ + int n, sockflags; + union sctp_notification snp; + struct msghdr msg; + struct iovec iov; + bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr; + + /* Check if there are any messages waiting to be read */ + do { + memset(&snp, 0x00, sizeof(union sctp_notification)); + iov.iov_base = (char *)&snp; + iov.iov_len = sizeof(union sctp_notification); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + + sockflags = fcntl(b->num, F_GETFL, 0); + fcntl(b->num, F_SETFL, O_NONBLOCK); + n = recvmsg(b->num, &msg, MSG_PEEK); + fcntl(b->num, F_SETFL, sockflags); + + /* if notification, process and try again */ + if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) { +# ifdef SCTP_AUTHENTICATION_EVENT + if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT) + dgram_sctp_handle_auth_free_key_event(b, &snp); +# endif + + memset(&snp, 0x00, sizeof(union sctp_notification)); + iov.iov_base = (char *)&snp; + iov.iov_len = sizeof(union sctp_notification); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + n = recvmsg(b->num, &msg, 0); + + if (data->handle_notifications != NULL) + data->handle_notifications(b, data->notification_context, + (void *)&snp); + } + + } while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)); + + /* Return 1 if there is a message to be read, return 0 otherwise. */ + if (n > 0) + return 1; + else + return 0; +} + +static int dgram_sctp_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = dgram_sctp_write(bp, str, n); + return (ret); +} +# endif + +static int BIO_dgram_should_retry(int i) +{ + int err; + + if ((i == 0) || (i == -1)) { + err = get_last_socket_error(); + +# if defined(OPENSSL_SYS_WINDOWS) + /* + * If the socket return value (i) is -1 and err is unexpectedly 0 at + * this point, the error code was overwritten by another system call + * before this error handling is called. + */ +# endif + + return (BIO_dgram_non_fatal_error(err)); + } + return (0); +} + +int BIO_dgram_non_fatal_error(int err) +{ + switch (err) { +# if defined(OPENSSL_SYS_WINDOWS) +# if defined(WSAEWOULDBLOCK) + case WSAEWOULDBLOCK: +# endif + +# if 0 /* This appears to always be an error */ +# if defined(WSAENOTCONN) + case WSAENOTCONN: +# endif +# endif +# endif + +# ifdef EWOULDBLOCK +# ifdef WSAEWOULDBLOCK +# if WSAEWOULDBLOCK != EWOULDBLOCK + case EWOULDBLOCK: +# endif +# else + case EWOULDBLOCK: +# endif +# endif + +# ifdef EINTR + case EINTR: +# endif + +# ifdef EAGAIN +# if EWOULDBLOCK != EAGAIN + case EAGAIN: +# endif +# endif + +# ifdef EPROTO + case EPROTO: +# endif + +# ifdef EINPROGRESS + case EINPROGRESS: +# endif + +# ifdef EALREADY + case EALREADY: +# endif + + return (1); + /* break; */ + default: + break; + } + return (0); +} + +static void get_current_time(struct timeval *t) +{ +# ifdef OPENSSL_SYS_WIN32 + struct _timeb tb; + _ftime(&tb); + t->tv_sec = (long)tb.time; + t->tv_usec = (long)tb.millitm * 1000; +# elif defined(OPENSSL_SYS_VMS) + struct timeb tb; + ftime(&tb); + t->tv_sec = (long)tb.time; + t->tv_usec = (long)tb.millitm * 1000; +# else + gettimeofday(t, NULL); +# endif +} + +#endif diff --git a/libs/openssl/crypto/bio/bss_fd.c b/libs/openssl/crypto/bio/bss_fd.c new file mode 100644 index 00000000..ccef5781 --- /dev/null +++ b/libs/openssl/crypto/bio/bss_fd.c @@ -0,0 +1,312 @@ +/* crypto/bio/bss_fd.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#define USE_SOCKETS +#include "cryptlib.h" + +#if defined(OPENSSL_NO_POSIX_IO) +/* + * One can argue that one should implement dummy placeholder for + * BIO_s_fd here... + */ +#else +/* + * As for unconditional usage of "UPLINK" interface in this module. + * Trouble is that unlike Unix file descriptors [which are indexes + * in kernel-side per-process table], corresponding descriptors on + * platforms which require "UPLINK" interface seem to be indexes + * in a user-land, non-global table. Well, in fact they are indexes + * in stdio _iob[], and recall that _iob[] was the very reason why + * "UPLINK" interface was introduced in first place. But one way on + * another. Neither libcrypto or libssl use this BIO meaning that + * file descriptors can only be provided by application. Therefore + * "UPLINK" calls are due... + */ +# include "bio_lcl.h" + +static int fd_write(BIO *h, const char *buf, int num); +static int fd_read(BIO *h, char *buf, int size); +static int fd_puts(BIO *h, const char *str); +static int fd_gets(BIO *h, char *buf, int size); +static long fd_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int fd_new(BIO *h); +static int fd_free(BIO *data); +int BIO_fd_should_retry(int s); + +static BIO_METHOD methods_fdp = { + BIO_TYPE_FD, "file descriptor", + fd_write, + fd_read, + fd_puts, + fd_gets, + fd_ctrl, + fd_new, + fd_free, + NULL, +}; + +BIO_METHOD *BIO_s_fd(void) +{ + return (&methods_fdp); +} + +BIO *BIO_new_fd(int fd, int close_flag) +{ + BIO *ret; + ret = BIO_new(BIO_s_fd()); + if (ret == NULL) + return (NULL); + BIO_set_fd(ret, fd, close_flag); + return (ret); +} + +static int fd_new(BIO *bi) +{ + bi->init = 0; + bi->num = -1; + bi->ptr = NULL; + bi->flags = BIO_FLAGS_UPLINK; /* essentially redundant */ + return (1); +} + +static int fd_free(BIO *a) +{ + if (a == NULL) + return (0); + if (a->shutdown) { + if (a->init) { + UP_close(a->num); + } + a->init = 0; + a->flags = BIO_FLAGS_UPLINK; + } + return (1); +} + +static int fd_read(BIO *b, char *out, int outl) +{ + int ret = 0; + + if (out != NULL) { + clear_sys_error(); + ret = UP_read(b->num, out, outl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_fd_should_retry(ret)) + BIO_set_retry_read(b); + } + } + return (ret); +} + +static int fd_write(BIO *b, const char *in, int inl) +{ + int ret; + clear_sys_error(); + ret = UP_write(b->num, in, inl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_fd_should_retry(ret)) + BIO_set_retry_write(b); + } + return (ret); +} + +static long fd_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + int *ip; + + switch (cmd) { + case BIO_CTRL_RESET: + num = 0; + case BIO_C_FILE_SEEK: + ret = (long)UP_lseek(b->num, num, 0); + break; + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + ret = (long)UP_lseek(b->num, 0, 1); + break; + case BIO_C_SET_FD: + fd_free(b); + b->num = *((int *)ptr); + b->shutdown = (int)num; + b->init = 1; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = b->num; + ret = b->num; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + default: + ret = 0; + break; + } + return (ret); +} + +static int fd_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = fd_write(bp, str, n); + return (ret); +} + +static int fd_gets(BIO *bp, char *buf, int size) +{ + int ret = 0; + char *ptr = buf; + char *end = buf + size - 1; + + while ((ptr < end) && (fd_read(bp, ptr, 1) > 0) && (ptr[0] != '\n')) + ptr++; + + ptr[0] = '\0'; + + if (buf[0] != '\0') + ret = strlen(buf); + return (ret); +} + +int BIO_fd_should_retry(int i) +{ + int err; + + if ((i == 0) || (i == -1)) { + err = get_last_sys_error(); + +# if defined(OPENSSL_SYS_WINDOWS) && 0/* more microsoft stupidity? perhaps + * not? Ben 4/1/99 */ + if ((i == -1) && (err == 0)) + return (1); +# endif + + return (BIO_fd_non_fatal_error(err)); + } + return (0); +} + +int BIO_fd_non_fatal_error(int err) +{ + switch (err) { + +# ifdef EWOULDBLOCK +# ifdef WSAEWOULDBLOCK +# if WSAEWOULDBLOCK != EWOULDBLOCK + case EWOULDBLOCK: +# endif +# else + case EWOULDBLOCK: +# endif +# endif + +# if defined(ENOTCONN) + case ENOTCONN: +# endif + +# ifdef EINTR + case EINTR: +# endif + +# ifdef EAGAIN +# if EWOULDBLOCK != EAGAIN + case EAGAIN: +# endif +# endif + +# ifdef EPROTO + case EPROTO: +# endif + +# ifdef EINPROGRESS + case EINPROGRESS: +# endif + +# ifdef EALREADY + case EALREADY: +# endif + return (1); + /* break; */ + default: + break; + } + return (0); +} +#endif diff --git a/libs/openssl/crypto/bio/bss_file.c b/libs/openssl/crypto/bio/bss_file.c new file mode 100644 index 00000000..bfba93e6 --- /dev/null +++ b/libs/openssl/crypto/bio/bss_file.c @@ -0,0 +1,472 @@ +/* crypto/bio/bss_file.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/*- + * 03-Dec-1997 rdenny@dc3.com Fix bug preventing use of stdin/stdout + * with binary data (e.g. asn1parse -inform DER < xxx) under + * Windows + */ + +#ifndef HEADER_BSS_FILE_C +# define HEADER_BSS_FILE_C + +# if defined(__linux) || defined(__sun) || defined(__hpux) +/* + * Following definition aliases fopen to fopen64 on above mentioned + * platforms. This makes it possible to open and sequentially access files + * larger than 2GB from 32-bit application. It does not allow to traverse + * them beyond 2GB with fseek/ftell, but on the other hand *no* 32-bit + * platform permits that, not with fseek/ftell. Not to mention that breaking + * 2GB limit for seeking would require surgery to *our* API. But sequential + * access suffices for practical cases when you can run into large files, + * such as fingerprinting, so we can let API alone. For reference, the list + * of 32-bit platforms which allow for sequential access of large files + * without extra "magic" comprise *BSD, Darwin, IRIX... + */ +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +# endif +# endif + +# include +# include +# include "cryptlib.h" +# include "bio_lcl.h" +# include + +# if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) +# include +# endif + +# if !defined(OPENSSL_NO_STDIO) + +static int MS_CALLBACK file_write(BIO *h, const char *buf, int num); +static int MS_CALLBACK file_read(BIO *h, char *buf, int size); +static int MS_CALLBACK file_puts(BIO *h, const char *str); +static int MS_CALLBACK file_gets(BIO *h, char *str, int size); +static long MS_CALLBACK file_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int MS_CALLBACK file_new(BIO *h); +static int MS_CALLBACK file_free(BIO *data); +static BIO_METHOD methods_filep = { + BIO_TYPE_FILE, + "FILE pointer", + file_write, + file_read, + file_puts, + file_gets, + file_ctrl, + file_new, + file_free, + NULL, +}; + +static FILE *file_fopen(const char *filename, const char *mode) +{ + FILE *file = NULL; + +# if defined(_WIN32) && defined(CP_UTF8) + int sz, len_0 = (int)strlen(filename) + 1; + DWORD flags; + + /* + * Basically there are three cases to cover: a) filename is + * pure ASCII string; b) actual UTF-8 encoded string and + * c) locale-ized string, i.e. one containing 8-bit + * characters that are meaningful in current system locale. + * If filename is pure ASCII or real UTF-8 encoded string, + * MultiByteToWideChar succeeds and _wfopen works. If + * filename is locale-ized string, chances are that + * MultiByteToWideChar fails reporting + * ERROR_NO_UNICODE_TRANSLATION, in which case we fall + * back to fopen... + */ + if ((sz = MultiByteToWideChar(CP_UTF8, (flags = MB_ERR_INVALID_CHARS), + filename, len_0, NULL, 0)) > 0 || + (GetLastError() == ERROR_INVALID_FLAGS && + (sz = MultiByteToWideChar(CP_UTF8, (flags = 0), + filename, len_0, NULL, 0)) > 0) + ) { + WCHAR wmode[8]; + WCHAR *wfilename = _alloca(sz * sizeof(WCHAR)); + + if (MultiByteToWideChar(CP_UTF8, flags, + filename, len_0, wfilename, sz) && + MultiByteToWideChar(CP_UTF8, 0, mode, strlen(mode) + 1, + wmode, sizeof(wmode) / sizeof(wmode[0])) && + (file = _wfopen(wfilename, wmode)) == NULL && + (errno == ENOENT || errno == EBADF) + ) { + /* + * UTF-8 decode succeeded, but no file, filename + * could still have been locale-ized... + */ + file = fopen(filename, mode); + } + } else if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) { + file = fopen(filename, mode); + } +# else + file = fopen(filename, mode); +# endif + return (file); +} + +BIO *BIO_new_file(const char *filename, const char *mode) +{ + BIO *ret; + FILE *file = file_fopen(filename, mode); + + if (file == NULL) { + SYSerr(SYS_F_FOPEN, get_last_sys_error()); + ERR_add_error_data(5, "fopen('", filename, "','", mode, "')"); + if (errno == ENOENT) + BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE); + else + BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB); + return (NULL); + } + if ((ret = BIO_new(BIO_s_file())) == NULL) { + fclose(file); + return (NULL); + } + + BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage + * UPLINK */ + BIO_set_fp(ret, file, BIO_CLOSE); + return (ret); +} + +BIO *BIO_new_fp(FILE *stream, int close_flag) +{ + BIO *ret; + + if ((ret = BIO_new(BIO_s_file())) == NULL) + return (NULL); + + BIO_set_flags(ret, BIO_FLAGS_UPLINK); /* redundant, left for + * documentation puposes */ + BIO_set_fp(ret, stream, close_flag); + return (ret); +} + +BIO_METHOD *BIO_s_file(void) +{ + return (&methods_filep); +} + +static int MS_CALLBACK file_new(BIO *bi) +{ + bi->init = 0; + bi->num = 0; + bi->ptr = NULL; + bi->flags = BIO_FLAGS_UPLINK; /* default to UPLINK */ + return (1); +} + +static int MS_CALLBACK file_free(BIO *a) +{ + if (a == NULL) + return (0); + if (a->shutdown) { + if ((a->init) && (a->ptr != NULL)) { + if (a->flags & BIO_FLAGS_UPLINK) + UP_fclose(a->ptr); + else + fclose(a->ptr); + a->ptr = NULL; + a->flags = BIO_FLAGS_UPLINK; + } + a->init = 0; + } + return (1); +} + +static int MS_CALLBACK file_read(BIO *b, char *out, int outl) +{ + int ret = 0; + + if (b->init && (out != NULL)) { + if (b->flags & BIO_FLAGS_UPLINK) + ret = UP_fread(out, 1, (int)outl, b->ptr); + else + ret = fread(out, 1, (int)outl, (FILE *)b->ptr); + if (ret == 0 + && (b->flags & BIO_FLAGS_UPLINK) ? UP_ferror((FILE *)b->ptr) : + ferror((FILE *)b->ptr)) { + SYSerr(SYS_F_FREAD, get_last_sys_error()); + BIOerr(BIO_F_FILE_READ, ERR_R_SYS_LIB); + ret = -1; + } + } + return (ret); +} + +static int MS_CALLBACK file_write(BIO *b, const char *in, int inl) +{ + int ret = 0; + + if (b->init && (in != NULL)) { + if (b->flags & BIO_FLAGS_UPLINK) + ret = UP_fwrite(in, (int)inl, 1, b->ptr); + else + ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr); + if (ret) + ret = inl; + /* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */ + /* + * according to Tim Hudson , the commented out + * version above can cause 'inl' write calls under some stupid stdio + * implementations (VMS) + */ + } + return (ret); +} + +static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + FILE *fp = (FILE *)b->ptr; + FILE **fpp; + char p[4]; + + switch (cmd) { + case BIO_C_FILE_SEEK: + case BIO_CTRL_RESET: + if (b->flags & BIO_FLAGS_UPLINK) + ret = (long)UP_fseek(b->ptr, num, 0); + else + ret = (long)fseek(fp, num, 0); + break; + case BIO_CTRL_EOF: + if (b->flags & BIO_FLAGS_UPLINK) + ret = (long)UP_feof(fp); + else + ret = (long)feof(fp); + break; + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + if (b->flags & BIO_FLAGS_UPLINK) + ret = UP_ftell(b->ptr); + else + ret = ftell(fp); + break; + case BIO_C_SET_FILE_PTR: + file_free(b); + b->shutdown = (int)num & BIO_CLOSE; + b->ptr = ptr; + b->init = 1; +# if BIO_FLAGS_UPLINK!=0 +# if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES) +# define _IOB_ENTRIES 20 +# endif +# if defined(_IOB_ENTRIES) + /* Safety net to catch purely internal BIO_set_fp calls */ + if ((size_t)ptr >= (size_t)stdin && + (size_t)ptr < (size_t)(stdin + _IOB_ENTRIES)) + BIO_clear_flags(b, BIO_FLAGS_UPLINK); +# endif +# endif +# ifdef UP_fsetmod + if (b->flags & BIO_FLAGS_UPLINK) + UP_fsetmod(b->ptr, (char)((num & BIO_FP_TEXT) ? 't' : 'b')); + else +# endif + { +# if defined(OPENSSL_SYS_WINDOWS) + int fd = _fileno((FILE *)ptr); + if (num & BIO_FP_TEXT) + _setmode(fd, _O_TEXT); + else + _setmode(fd, _O_BINARY); +# elif defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB) + int fd = fileno((FILE *)ptr); + /* Under CLib there are differences in file modes */ + if (num & BIO_FP_TEXT) + setmode(fd, O_TEXT); + else + setmode(fd, O_BINARY); +# elif defined(OPENSSL_SYS_MSDOS) + int fd = fileno((FILE *)ptr); + /* Set correct text/binary mode */ + if (num & BIO_FP_TEXT) + _setmode(fd, _O_TEXT); + /* Dangerous to set stdin/stdout to raw (unless redirected) */ + else { + if (fd == STDIN_FILENO || fd == STDOUT_FILENO) { + if (isatty(fd) <= 0) + _setmode(fd, _O_BINARY); + } else + _setmode(fd, _O_BINARY); + } +# elif defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN) + int fd = fileno((FILE *)ptr); + if (num & BIO_FP_TEXT) + setmode(fd, O_TEXT); + else + setmode(fd, O_BINARY); +# endif + } + break; + case BIO_C_SET_FILENAME: + file_free(b); + b->shutdown = (int)num & BIO_CLOSE; + if (num & BIO_FP_APPEND) { + if (num & BIO_FP_READ) + BUF_strlcpy(p, "a+", sizeof p); + else + BUF_strlcpy(p, "a", sizeof p); + } else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE)) + BUF_strlcpy(p, "r+", sizeof p); + else if (num & BIO_FP_WRITE) + BUF_strlcpy(p, "w", sizeof p); + else if (num & BIO_FP_READ) + BUF_strlcpy(p, "r", sizeof p); + else { + BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE); + ret = 0; + break; + } +# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN) + if (!(num & BIO_FP_TEXT)) + strcat(p, "b"); + else + strcat(p, "t"); +# endif +# if defined(OPENSSL_SYS_NETWARE) + if (!(num & BIO_FP_TEXT)) + strcat(p, "b"); + else + strcat(p, "t"); +# endif + fp = file_fopen(ptr, p); + if (fp == NULL) { + SYSerr(SYS_F_FOPEN, get_last_sys_error()); + ERR_add_error_data(5, "fopen('", ptr, "','", p, "')"); + BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB); + ret = 0; + break; + } + b->ptr = fp; + b->init = 1; + BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage + * UPLINK */ + break; + case BIO_C_GET_FILE_PTR: + /* the ptr parameter is actually a FILE ** in this case. */ + if (ptr != NULL) { + fpp = (FILE **)ptr; + *fpp = (FILE *)b->ptr; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = (long)b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_FLUSH: + if (b->flags & BIO_FLAGS_UPLINK) + UP_fflush(b->ptr); + else + fflush((FILE *)b->ptr); + break; + case BIO_CTRL_DUP: + ret = 1; + break; + + case BIO_CTRL_WPENDING: + case BIO_CTRL_PENDING: + case BIO_CTRL_PUSH: + case BIO_CTRL_POP: + default: + ret = 0; + break; + } + return (ret); +} + +static int MS_CALLBACK file_gets(BIO *bp, char *buf, int size) +{ + int ret = 0; + + buf[0] = '\0'; + if (bp->flags & BIO_FLAGS_UPLINK) { + if (!UP_fgets(buf, size, bp->ptr)) + goto err; + } else { + if (!fgets(buf, size, (FILE *)bp->ptr)) + goto err; + } + if (buf[0] != '\0') + ret = strlen(buf); + err: + return (ret); +} + +static int MS_CALLBACK file_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = file_write(bp, str, n); + return (ret); +} + +# endif /* OPENSSL_NO_STDIO */ + +#endif /* HEADER_BSS_FILE_C */ diff --git a/libs/openssl/crypto/bio/bss_log.c b/libs/openssl/crypto/bio/bss_log.c new file mode 100644 index 00000000..1283a525 --- /dev/null +++ b/libs/openssl/crypto/bio/bss_log.c @@ -0,0 +1,453 @@ +/* crypto/bio/bss_log.c */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Why BIO_s_log? + * + * BIO_s_log is useful for system daemons (or services under NT). It is + * one-way BIO, it sends all stuff to syslogd (on system that commonly use + * that), or event log (on NT), or OPCOM (on OpenVMS). + * + */ + +#include +#include + +#include "cryptlib.h" + +#if defined(OPENSSL_SYS_WINCE) +#elif defined(OPENSSL_SYS_WIN32) +#elif defined(OPENSSL_SYS_VMS) +# include +# include +# include +# include +/* Some compiler options may mask the declaration of "_malloc32". */ +# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE +# if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size save +# pragma pointer_size 32 +void *_malloc32(__size_t); +# pragma pointer_size restore +# endif /* __INITIAL_POINTER_SIZE == 64 */ +# endif /* __INITIAL_POINTER_SIZE && defined + * _ANSI_C_SOURCE */ +#elif defined(__ultrix) +# include +#elif defined(OPENSSL_SYS_NETWARE) +# define NO_SYSLOG +#elif (!defined(MSDOS) || defined(WATT32)) && !defined(OPENSSL_SYS_VXWORKS) && !defined(NO_SYSLOG) +# include +#endif + +#include +#include + +#ifndef NO_SYSLOG + +# if defined(OPENSSL_SYS_WIN32) +# define LOG_EMERG 0 +# define LOG_ALERT 1 +# define LOG_CRIT 2 +# define LOG_ERR 3 +# define LOG_WARNING 4 +# define LOG_NOTICE 5 +# define LOG_INFO 6 +# define LOG_DEBUG 7 + +# define LOG_DAEMON (3<<3) +# elif defined(OPENSSL_SYS_VMS) +/* On VMS, we don't really care about these, but we need them to compile */ +# define LOG_EMERG 0 +# define LOG_ALERT 1 +# define LOG_CRIT 2 +# define LOG_ERR 3 +# define LOG_WARNING 4 +# define LOG_NOTICE 5 +# define LOG_INFO 6 +# define LOG_DEBUG 7 + +# define LOG_DAEMON OPC$M_NM_NTWORK +# endif + +static int MS_CALLBACK slg_write(BIO *h, const char *buf, int num); +static int MS_CALLBACK slg_puts(BIO *h, const char *str); +static long MS_CALLBACK slg_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int MS_CALLBACK slg_new(BIO *h); +static int MS_CALLBACK slg_free(BIO *data); +static void xopenlog(BIO *bp, char *name, int level); +static void xsyslog(BIO *bp, int priority, const char *string); +static void xcloselog(BIO *bp); + +static BIO_METHOD methods_slg = { + BIO_TYPE_MEM, "syslog", + slg_write, + NULL, + slg_puts, + NULL, + slg_ctrl, + slg_new, + slg_free, + NULL, +}; + +BIO_METHOD *BIO_s_log(void) +{ + return (&methods_slg); +} + +static int MS_CALLBACK slg_new(BIO *bi) +{ + bi->init = 1; + bi->num = 0; + bi->ptr = NULL; + xopenlog(bi, "application", LOG_DAEMON); + return (1); +} + +static int MS_CALLBACK slg_free(BIO *a) +{ + if (a == NULL) + return (0); + xcloselog(a); + return (1); +} + +static int MS_CALLBACK slg_write(BIO *b, const char *in, int inl) +{ + int ret = inl; + char *buf; + char *pp; + int priority, i; + static const struct { + int strl; + char str[10]; + int log_level; + } mapping[] = { + { + 6, "PANIC ", LOG_EMERG + }, + { + 6, "EMERG ", LOG_EMERG + }, + { + 4, "EMR ", LOG_EMERG + }, + { + 6, "ALERT ", LOG_ALERT + }, + { + 4, "ALR ", LOG_ALERT + }, + { + 5, "CRIT ", LOG_CRIT + }, + { + 4, "CRI ", LOG_CRIT + }, + { + 6, "ERROR ", LOG_ERR + }, + { + 4, "ERR ", LOG_ERR + }, + { + 8, "WARNING ", LOG_WARNING + }, + { + 5, "WARN ", LOG_WARNING + }, + { + 4, "WAR ", LOG_WARNING + }, + { + 7, "NOTICE ", LOG_NOTICE + }, + { + 5, "NOTE ", LOG_NOTICE + }, + { + 4, "NOT ", LOG_NOTICE + }, + { + 5, "INFO ", LOG_INFO + }, + { + 4, "INF ", LOG_INFO + }, + { + 6, "DEBUG ", LOG_DEBUG + }, + { + 4, "DBG ", LOG_DEBUG + }, + { + 0, "", LOG_ERR + } + /* The default */ + }; + + if ((buf = (char *)OPENSSL_malloc(inl + 1)) == NULL) { + return (0); + } + strncpy(buf, in, inl); + buf[inl] = '\0'; + + i = 0; + while (strncmp(buf, mapping[i].str, mapping[i].strl) != 0) + i++; + priority = mapping[i].log_level; + pp = buf + mapping[i].strl; + + xsyslog(b, priority, pp); + + OPENSSL_free(buf); + return (ret); +} + +static long MS_CALLBACK slg_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + switch (cmd) { + case BIO_CTRL_SET: + xcloselog(b); + xopenlog(b, ptr, num); + break; + default: + break; + } + return (0); +} + +static int MS_CALLBACK slg_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = slg_write(bp, str, n); + return (ret); +} + +# if defined(OPENSSL_SYS_WIN32) + +static void xopenlog(BIO *bp, char *name, int level) +{ + if (check_winnt()) + bp->ptr = RegisterEventSourceA(NULL, name); + else + bp->ptr = NULL; +} + +static void xsyslog(BIO *bp, int priority, const char *string) +{ + LPCSTR lpszStrings[2]; + WORD evtype = EVENTLOG_ERROR_TYPE; + char pidbuf[DECIMAL_SIZE(DWORD) + 4]; + + if (bp->ptr == NULL) + return; + + switch (priority) { + case LOG_EMERG: + case LOG_ALERT: + case LOG_CRIT: + case LOG_ERR: + evtype = EVENTLOG_ERROR_TYPE; + break; + case LOG_WARNING: + evtype = EVENTLOG_WARNING_TYPE; + break; + case LOG_NOTICE: + case LOG_INFO: + case LOG_DEBUG: + evtype = EVENTLOG_INFORMATION_TYPE; + break; + default: + /* + * Should never happen, but set it + * as error anyway. + */ + evtype = EVENTLOG_ERROR_TYPE; + break; + } + + sprintf(pidbuf, "[%u] ", GetCurrentProcessId()); + lpszStrings[0] = pidbuf; + lpszStrings[1] = string; + + ReportEventA(bp->ptr, evtype, 0, 1024, NULL, 2, 0, lpszStrings, NULL); +} + +static void xcloselog(BIO *bp) +{ + if (bp->ptr) + DeregisterEventSource((HANDLE) (bp->ptr)); + bp->ptr = NULL; +} + +# elif defined(OPENSSL_SYS_VMS) + +static int VMS_OPC_target = LOG_DAEMON; + +static void xopenlog(BIO *bp, char *name, int level) +{ + VMS_OPC_target = level; +} + +static void xsyslog(BIO *bp, int priority, const char *string) +{ + struct dsc$descriptor_s opc_dsc; + +/* Arrange 32-bit pointer to opcdef buffer and malloc(), if needed. */ +# if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size save +# pragma pointer_size 32 +# define OPCDEF_TYPE __char_ptr32 +# define OPCDEF_MALLOC _malloc32 +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define OPCDEF_TYPE char * +# define OPCDEF_MALLOC OPENSSL_malloc +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + struct opcdef *opcdef_p; + +# if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size restore +# endif /* __INITIAL_POINTER_SIZE == 64 */ + + char buf[10240]; + unsigned int len; + struct dsc$descriptor_s buf_dsc; + $DESCRIPTOR(fao_cmd, "!AZ: !AZ"); + char *priority_tag; + + switch (priority) { + case LOG_EMERG: + priority_tag = "Emergency"; + break; + case LOG_ALERT: + priority_tag = "Alert"; + break; + case LOG_CRIT: + priority_tag = "Critical"; + break; + case LOG_ERR: + priority_tag = "Error"; + break; + case LOG_WARNING: + priority_tag = "Warning"; + break; + case LOG_NOTICE: + priority_tag = "Notice"; + break; + case LOG_INFO: + priority_tag = "Info"; + break; + case LOG_DEBUG: + priority_tag = "DEBUG"; + break; + } + + buf_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + buf_dsc.dsc$b_class = DSC$K_CLASS_S; + buf_dsc.dsc$a_pointer = buf; + buf_dsc.dsc$w_length = sizeof(buf) - 1; + + lib$sys_fao(&fao_cmd, &len, &buf_dsc, priority_tag, string); + + /* We know there's an 8-byte header. That's documented. */ + opcdef_p = OPCDEF_MALLOC(8 + len); + opcdef_p->opc$b_ms_type = OPC$_RQ_RQST; + memcpy(opcdef_p->opc$z_ms_target_classes, &VMS_OPC_target, 3); + opcdef_p->opc$l_ms_rqstid = 0; + memcpy(&opcdef_p->opc$l_ms_text, buf, len); + + opc_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + opc_dsc.dsc$b_class = DSC$K_CLASS_S; + opc_dsc.dsc$a_pointer = (OPCDEF_TYPE) opcdef_p; + opc_dsc.dsc$w_length = len + 8; + + sys$sndopr(opc_dsc, 0); + + OPENSSL_free(opcdef_p); +} + +static void xcloselog(BIO *bp) +{ +} + +# else /* Unix/Watt32 */ + +static void xopenlog(BIO *bp, char *name, int level) +{ +# ifdef WATT32 /* djgpp/DOS */ + openlog(name, LOG_PID | LOG_CONS | LOG_NDELAY, level); +# else + openlog(name, LOG_PID | LOG_CONS, level); +# endif +} + +static void xsyslog(BIO *bp, int priority, const char *string) +{ + syslog(priority, "%s", string); +} + +static void xcloselog(BIO *bp) +{ + closelog(); +} + +# endif /* Unix */ + +#endif /* NO_SYSLOG */ diff --git a/libs/openssl/crypto/bio/bss_mem.c b/libs/openssl/crypto/bio/bss_mem.c new file mode 100644 index 00000000..d190765d --- /dev/null +++ b/libs/openssl/crypto/bio/bss_mem.c @@ -0,0 +1,311 @@ +/* crypto/bio/bss_mem.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include + +static int mem_write(BIO *h, const char *buf, int num); +static int mem_read(BIO *h, char *buf, int size); +static int mem_puts(BIO *h, const char *str); +static int mem_gets(BIO *h, char *str, int size); +static long mem_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int mem_new(BIO *h); +static int mem_free(BIO *data); +static BIO_METHOD mem_method = { + BIO_TYPE_MEM, + "memory buffer", + mem_write, + mem_read, + mem_puts, + mem_gets, + mem_ctrl, + mem_new, + mem_free, + NULL, +}; + +/* + * bio->num is used to hold the value to return on 'empty', if it is 0, + * should_retry is not set + */ + +BIO_METHOD *BIO_s_mem(void) +{ + return (&mem_method); +} + +BIO *BIO_new_mem_buf(void *buf, int len) +{ + BIO *ret; + BUF_MEM *b; + size_t sz; + + if (!buf) { + BIOerr(BIO_F_BIO_NEW_MEM_BUF, BIO_R_NULL_PARAMETER); + return NULL; + } + sz = (len < 0) ? strlen(buf) : (size_t)len; + if (!(ret = BIO_new(BIO_s_mem()))) + return NULL; + b = (BUF_MEM *)ret->ptr; + b->data = buf; + b->length = sz; + b->max = sz; + ret->flags |= BIO_FLAGS_MEM_RDONLY; + /* Since this is static data retrying wont help */ + ret->num = 0; + return ret; +} + +static int mem_new(BIO *bi) +{ + BUF_MEM *b; + + if ((b = BUF_MEM_new()) == NULL) + return (0); + bi->shutdown = 1; + bi->init = 1; + bi->num = -1; + bi->ptr = (char *)b; + return (1); +} + +static int mem_free(BIO *a) +{ + if (a == NULL) + return (0); + if (a->shutdown) { + if ((a->init) && (a->ptr != NULL)) { + BUF_MEM *b; + b = (BUF_MEM *)a->ptr; + if (a->flags & BIO_FLAGS_MEM_RDONLY) + b->data = NULL; + BUF_MEM_free(b); + a->ptr = NULL; + } + } + return (1); +} + +static int mem_read(BIO *b, char *out, int outl) +{ + int ret = -1; + BUF_MEM *bm; + + bm = (BUF_MEM *)b->ptr; + BIO_clear_retry_flags(b); + ret = (outl >= 0 && (size_t)outl > bm->length) ? (int)bm->length : outl; + if ((out != NULL) && (ret > 0)) { + memcpy(out, bm->data, ret); + bm->length -= ret; + if (b->flags & BIO_FLAGS_MEM_RDONLY) + bm->data += ret; + else { + memmove(&(bm->data[0]), &(bm->data[ret]), bm->length); + } + } else if (bm->length == 0) { + ret = b->num; + if (ret != 0) + BIO_set_retry_read(b); + } + return (ret); +} + +static int mem_write(BIO *b, const char *in, int inl) +{ + int ret = -1; + int blen; + BUF_MEM *bm; + + bm = (BUF_MEM *)b->ptr; + if (in == NULL) { + BIOerr(BIO_F_MEM_WRITE, BIO_R_NULL_PARAMETER); + goto end; + } + + if (b->flags & BIO_FLAGS_MEM_RDONLY) { + BIOerr(BIO_F_MEM_WRITE, BIO_R_WRITE_TO_READ_ONLY_BIO); + goto end; + } + + BIO_clear_retry_flags(b); + blen = bm->length; + if (BUF_MEM_grow_clean(bm, blen + inl) != (blen + inl)) + goto end; + memcpy(&(bm->data[blen]), in, inl); + ret = inl; + end: + return (ret); +} + +static long mem_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + char **pptr; + + BUF_MEM *bm = (BUF_MEM *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + if (bm->data != NULL) { + /* For read only case reset to the start again */ + if (b->flags & BIO_FLAGS_MEM_RDONLY) { + bm->data -= bm->max - bm->length; + bm->length = bm->max; + } else { + memset(bm->data, 0, bm->max); + bm->length = 0; + } + } + break; + case BIO_CTRL_EOF: + ret = (long)(bm->length == 0); + break; + case BIO_C_SET_BUF_MEM_EOF_RETURN: + b->num = (int)num; + break; + case BIO_CTRL_INFO: + ret = (long)bm->length; + if (ptr != NULL) { + pptr = (char **)ptr; + *pptr = (char *)&(bm->data[0]); + } + break; + case BIO_C_SET_BUF_MEM: + mem_free(b); + b->shutdown = (int)num; + b->ptr = ptr; + break; + case BIO_C_GET_BUF_MEM_PTR: + if (ptr != NULL) { + pptr = (char **)ptr; + *pptr = (char *)bm; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = (long)b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + + case BIO_CTRL_WPENDING: + ret = 0L; + break; + case BIO_CTRL_PENDING: + ret = (long)bm->length; + break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + case BIO_CTRL_PUSH: + case BIO_CTRL_POP: + default: + ret = 0; + break; + } + return (ret); +} + +static int mem_gets(BIO *bp, char *buf, int size) +{ + int i, j; + int ret = -1; + char *p; + BUF_MEM *bm = (BUF_MEM *)bp->ptr; + + BIO_clear_retry_flags(bp); + j = bm->length; + if ((size - 1) < j) + j = size - 1; + if (j <= 0) { + *buf = '\0'; + return 0; + } + p = bm->data; + for (i = 0; i < j; i++) { + if (p[i] == '\n') { + i++; + break; + } + } + + /* + * i is now the max num of bytes to copy, either j or up to + * and including the first newline + */ + + i = mem_read(bp, buf, i); + if (i > 0) + buf[i] = '\0'; + ret = i; + return (ret); +} + +static int mem_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = mem_write(bp, str, n); + /* memory semantics is that it will always work */ + return (ret); +} diff --git a/libs/openssl/crypto/bio/bss_null.c b/libs/openssl/crypto/bio/bss_null.c new file mode 100644 index 00000000..6a03fa24 --- /dev/null +++ b/libs/openssl/crypto/bio/bss_null.c @@ -0,0 +1,149 @@ +/* crypto/bio/bss_null.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include + +static int null_write(BIO *h, const char *buf, int num); +static int null_read(BIO *h, char *buf, int size); +static int null_puts(BIO *h, const char *str); +static int null_gets(BIO *h, char *str, int size); +static long null_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int null_new(BIO *h); +static int null_free(BIO *data); +static BIO_METHOD null_method = { + BIO_TYPE_NULL, + "NULL", + null_write, + null_read, + null_puts, + null_gets, + null_ctrl, + null_new, + null_free, + NULL, +}; + +BIO_METHOD *BIO_s_null(void) +{ + return (&null_method); +} + +static int null_new(BIO *bi) +{ + bi->init = 1; + bi->num = 0; + bi->ptr = (NULL); + return (1); +} + +static int null_free(BIO *a) +{ + if (a == NULL) + return (0); + return (1); +} + +static int null_read(BIO *b, char *out, int outl) +{ + return (0); +} + +static int null_write(BIO *b, const char *in, int inl) +{ + return (inl); +} + +static long null_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + + switch (cmd) { + case BIO_CTRL_RESET: + case BIO_CTRL_EOF: + case BIO_CTRL_SET: + case BIO_CTRL_SET_CLOSE: + case BIO_CTRL_FLUSH: + case BIO_CTRL_DUP: + ret = 1; + break; + case BIO_CTRL_GET_CLOSE: + case BIO_CTRL_INFO: + case BIO_CTRL_GET: + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + default: + ret = 0; + break; + } + return (ret); +} + +static int null_gets(BIO *bp, char *buf, int size) +{ + return (0); +} + +static int null_puts(BIO *bp, const char *str) +{ + if (str == NULL) + return (0); + return (strlen(str)); +} diff --git a/libs/openssl/crypto/bio/bss_rtcp.c b/libs/openssl/crypto/bio/bss_rtcp.c new file mode 100644 index 00000000..09f14f48 --- /dev/null +++ b/libs/openssl/crypto/bio/bss_rtcp.c @@ -0,0 +1,319 @@ +/* crypto/bio/bss_rtcp.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/*- + * Written by David L. Jones + * Date: 22-JUL-1996 + * Revised: 25-SEP-1997 Update for 0.8.1, BIO_CTRL_SET -> BIO_C_SET_FD + */ +/* VMS */ +#include +#include +#include +#include +#include "cryptlib.h" +#include + +#include /* VMS IO$_ definitions */ +#include + +typedef unsigned short io_channel; +/*************************************************************************/ +struct io_status { + short status, count; + long flags; +}; + +/* Should have member alignment inhibited */ +struct rpc_msg { + /* 'A'-app data. 'R'-remote client 'G'-global */ + char channel; + /* 'G'-get, 'P'-put, 'C'-confirm, 'X'-close */ + char function; + /* Amount of data returned or max to return */ + unsigned short int length; + /* variable data */ + char data[4092]; +}; +#define RPC_HDR_SIZE (sizeof(struct rpc_msg) - 4092) + +struct rpc_ctx { + int filled, pos; + struct rpc_msg msg; +}; + +static int rtcp_write(BIO *h, const char *buf, int num); +static int rtcp_read(BIO *h, char *buf, int size); +static int rtcp_puts(BIO *h, const char *str); +static int rtcp_gets(BIO *h, char *str, int size); +static long rtcp_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int rtcp_new(BIO *h); +static int rtcp_free(BIO *data); + +static BIO_METHOD rtcp_method = { + BIO_TYPE_FD, + "RTCP", + rtcp_write, + rtcp_read, + rtcp_puts, + rtcp_gets, + rtcp_ctrl, + rtcp_new, + rtcp_free, + NULL, +}; + +BIO_METHOD *BIO_s_rtcp(void) +{ + return (&rtcp_method); +} + +/*****************************************************************************/ +/* + * Decnet I/O routines. + */ + +#ifdef __DECC +# pragma message save +# pragma message disable DOLLARID +#endif + +static int get(io_channel chan, char *buffer, int maxlen, int *length) +{ + int status; + struct io_status iosb; + status = sys$qiow(0, chan, IO$_READVBLK, &iosb, 0, 0, + buffer, maxlen, 0, 0, 0, 0); + if ((status & 1) == 1) + status = iosb.status; + if ((status & 1) == 1) + *length = iosb.count; + return status; +} + +static int put(io_channel chan, char *buffer, int length) +{ + int status; + struct io_status iosb; + status = sys$qiow(0, chan, IO$_WRITEVBLK, &iosb, 0, 0, + buffer, length, 0, 0, 0, 0); + if ((status & 1) == 1) + status = iosb.status; + return status; +} + +#ifdef __DECC +# pragma message restore +#endif + +/***************************************************************************/ + +static int rtcp_new(BIO *bi) +{ + struct rpc_ctx *ctx; + bi->init = 1; + bi->num = 0; + bi->flags = 0; + bi->ptr = OPENSSL_malloc(sizeof(struct rpc_ctx)); + ctx = (struct rpc_ctx *)bi->ptr; + ctx->filled = 0; + ctx->pos = 0; + return (1); +} + +static int rtcp_free(BIO *a) +{ + if (a == NULL) + return (0); + if (a->ptr) + OPENSSL_free(a->ptr); + a->ptr = NULL; + return (1); +} + +static int rtcp_read(BIO *b, char *out, int outl) +{ + int status, length; + struct rpc_ctx *ctx; + /* + * read data, return existing. + */ + ctx = (struct rpc_ctx *)b->ptr; + if (ctx->pos < ctx->filled) { + length = ctx->filled - ctx->pos; + if (length > outl) + length = outl; + memmove(out, &ctx->msg.data[ctx->pos], length); + ctx->pos += length; + return length; + } + /* + * Requst more data from R channel. + */ + ctx->msg.channel = 'R'; + ctx->msg.function = 'G'; + ctx->msg.length = sizeof(ctx->msg.data); + status = put(b->num, (char *)&ctx->msg, RPC_HDR_SIZE); + if ((status & 1) == 0) { + return -1; + } + /* + * Read. + */ + ctx->pos = ctx->filled = 0; + status = get(b->num, (char *)&ctx->msg, sizeof(ctx->msg), &length); + if ((status & 1) == 0) + length = -1; + if (ctx->msg.channel != 'R' || ctx->msg.function != 'C') { + length = -1; + } + ctx->filled = length - RPC_HDR_SIZE; + + if (ctx->pos < ctx->filled) { + length = ctx->filled - ctx->pos; + if (length > outl) + length = outl; + memmove(out, ctx->msg.data, length); + ctx->pos += length; + return length; + } + + return length; +} + +static int rtcp_write(BIO *b, const char *in, int inl) +{ + int status, i, segment, length; + struct rpc_ctx *ctx; + /* + * Output data, send in chunks no larger that sizeof(ctx->msg.data). + */ + ctx = (struct rpc_ctx *)b->ptr; + for (i = 0; i < inl; i += segment) { + segment = inl - i; + if (segment > sizeof(ctx->msg.data)) + segment = sizeof(ctx->msg.data); + ctx->msg.channel = 'R'; + ctx->msg.function = 'P'; + ctx->msg.length = segment; + memmove(ctx->msg.data, &in[i], segment); + status = put(b->num, (char *)&ctx->msg, segment + RPC_HDR_SIZE); + if ((status & 1) == 0) { + i = -1; + break; + } + + status = get(b->num, (char *)&ctx->msg, sizeof(ctx->msg), &length); + if (((status & 1) == 0) || (length < RPC_HDR_SIZE)) { + i = -1; + break; + } + if ((ctx->msg.channel != 'R') || (ctx->msg.function != 'C')) { + printf("unexpected response when confirming put %c %c\n", + ctx->msg.channel, ctx->msg.function); + + } + } + return (i); +} + +static long rtcp_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + + switch (cmd) { + case BIO_CTRL_RESET: + case BIO_CTRL_EOF: + ret = 1; + break; + case BIO_C_SET_FD: + b->num = num; + ret = 1; + break; + case BIO_CTRL_SET_CLOSE: + case BIO_CTRL_FLUSH: + case BIO_CTRL_DUP: + ret = 1; + break; + case BIO_CTRL_GET_CLOSE: + case BIO_CTRL_INFO: + case BIO_CTRL_GET: + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + default: + ret = 0; + break; + } + return (ret); +} + +static int rtcp_gets(BIO *bp, char *buf, int size) +{ + return (0); +} + +static int rtcp_puts(BIO *bp, const char *str) +{ + int length; + if (str == NULL) + return (0); + length = strlen(str); + if (length == 0) + return (0); + return rtcp_write(bp, str, length); +} diff --git a/libs/openssl/crypto/bio/bss_sock.c b/libs/openssl/crypto/bio/bss_sock.c new file mode 100644 index 00000000..6194d2c0 --- /dev/null +++ b/libs/openssl/crypto/bio/bss_sock.c @@ -0,0 +1,287 @@ +/* crypto/bio/bss_sock.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#define USE_SOCKETS +#include "cryptlib.h" + +#ifndef OPENSSL_NO_SOCK + +# include + +# ifdef WATT32 +# define sock_write SockWrite /* Watt-32 uses same names */ +# define sock_read SockRead +# define sock_puts SockPuts +# endif + +static int sock_write(BIO *h, const char *buf, int num); +static int sock_read(BIO *h, char *buf, int size); +static int sock_puts(BIO *h, const char *str); +static long sock_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int sock_new(BIO *h); +static int sock_free(BIO *data); +int BIO_sock_should_retry(int s); + +static BIO_METHOD methods_sockp = { + BIO_TYPE_SOCKET, + "socket", + sock_write, + sock_read, + sock_puts, + NULL, /* sock_gets, */ + sock_ctrl, + sock_new, + sock_free, + NULL, +}; + +BIO_METHOD *BIO_s_socket(void) +{ + return (&methods_sockp); +} + +BIO *BIO_new_socket(int fd, int close_flag) +{ + BIO *ret; + + ret = BIO_new(BIO_s_socket()); + if (ret == NULL) + return (NULL); + BIO_set_fd(ret, fd, close_flag); + return (ret); +} + +static int sock_new(BIO *bi) +{ + bi->init = 0; + bi->num = 0; + bi->ptr = NULL; + bi->flags = 0; + return (1); +} + +static int sock_free(BIO *a) +{ + if (a == NULL) + return (0); + if (a->shutdown) { + if (a->init) { + SHUTDOWN2(a->num); + } + a->init = 0; + a->flags = 0; + } + return (1); +} + +static int sock_read(BIO *b, char *out, int outl) +{ + int ret = 0; + + if (out != NULL) { + clear_socket_error(); + ret = readsocket(b->num, out, outl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_sock_should_retry(ret)) + BIO_set_retry_read(b); + } + } + return (ret); +} + +static int sock_write(BIO *b, const char *in, int inl) +{ + int ret; + + clear_socket_error(); + ret = writesocket(b->num, in, inl); + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (BIO_sock_should_retry(ret)) + BIO_set_retry_write(b); + } + return (ret); +} + +static long sock_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + long ret = 1; + int *ip; + + switch (cmd) { + case BIO_C_SET_FD: + sock_free(b); + b->num = *((int *)ptr); + b->shutdown = (int)num; + b->init = 1; + break; + case BIO_C_GET_FD: + if (b->init) { + ip = (int *)ptr; + if (ip != NULL) + *ip = b->num; + ret = b->num; + } else + ret = -1; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_DUP: + case BIO_CTRL_FLUSH: + ret = 1; + break; + default: + ret = 0; + break; + } + return (ret); +} + +static int sock_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = sock_write(bp, str, n); + return (ret); +} + +int BIO_sock_should_retry(int i) +{ + int err; + + if ((i == 0) || (i == -1)) { + err = get_last_socket_error(); + +# if defined(OPENSSL_SYS_WINDOWS) && 0/* more microsoft stupidity? perhaps + * not? Ben 4/1/99 */ + if ((i == -1) && (err == 0)) + return (1); +# endif + + return (BIO_sock_non_fatal_error(err)); + } + return (0); +} + +int BIO_sock_non_fatal_error(int err) +{ + switch (err) { +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_NETWARE) +# if defined(WSAEWOULDBLOCK) + case WSAEWOULDBLOCK: +# endif + +# if 0 /* This appears to always be an error */ +# if defined(WSAENOTCONN) + case WSAENOTCONN: +# endif +# endif +# endif + +# ifdef EWOULDBLOCK +# ifdef WSAEWOULDBLOCK +# if WSAEWOULDBLOCK != EWOULDBLOCK + case EWOULDBLOCK: +# endif +# else + case EWOULDBLOCK: +# endif +# endif + +# if defined(ENOTCONN) + case ENOTCONN: +# endif + +# ifdef EINTR + case EINTR: +# endif + +# ifdef EAGAIN +# if EWOULDBLOCK != EAGAIN + case EAGAIN: +# endif +# endif + +# ifdef EPROTO + case EPROTO: +# endif + +# ifdef EINPROGRESS + case EINPROGRESS: +# endif + +# ifdef EALREADY + case EALREADY: +# endif + return (1); + /* break; */ + default: + break; + } + return (0); +} + +#endif /* #ifndef OPENSSL_NO_SOCK */ diff --git a/libs/openssl/crypto/bn/asm/README b/libs/openssl/crypto/bn/asm/README new file mode 100644 index 00000000..b0f3a68a --- /dev/null +++ b/libs/openssl/crypto/bn/asm/README @@ -0,0 +1,27 @@ + + +All assember in this directory are just version of the file +crypto/bn/bn_asm.c. + +Quite a few of these files are just the assember output from gcc since on +quite a few machines they are 2 times faster than the system compiler. + +For the x86, I have hand written assember because of the bad job all +compilers seem to do on it. This normally gives a 2 time speed up in the RSA +routines. + +For the DEC alpha, I also hand wrote the assember (except the division which +is just the output from the C compiler pasted on the end of the file). +On the 2 alpha C compilers I had access to, it was not possible to do +64b x 64b -> 128b calculations (both long and the long long data types +were 64 bits). So the hand assember gives access to the 128 bit result and +a 2 times speedup :-). + +There are 3 versions of assember for the HP PA-RISC. + +pa-risc.s is the origional one which works fine and generated using gcc :-) + +pa-risc2W.s and pa-risc2.s are 64 and 32-bit PA-RISC 2.0 implementations +by Chris Ruemmler from HP (with some help from the HP C compiler). + + diff --git a/libs/openssl/crypto/bn/asm/alpha-mont.pl b/libs/openssl/crypto/bn/asm/alpha-mont.pl new file mode 100644 index 00000000..03596e20 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/alpha-mont.pl @@ -0,0 +1,321 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# On 21264 RSA sign performance improves by 70/35/20/15 percent for +# 512/1024/2048/4096 bit key lengths. This is against vendor compiler +# instructed to '-tune host' code with in-line assembler. Other +# benchmarks improve by 15-20%. To anchor it to something else, the +# code provides approximately the same performance per GHz as AMD64. +# I.e. if you compare 1GHz 21264 and 2GHz Opteron, you'll observe ~2x +# difference. + +# int bn_mul_mont( +$rp="a0"; # BN_ULONG *rp, +$ap="a1"; # const BN_ULONG *ap, +$bp="a2"; # const BN_ULONG *bp, +$np="a3"; # const BN_ULONG *np, +$n0="a4"; # const BN_ULONG *n0, +$num="a5"; # int num); + +$lo0="t0"; +$hi0="t1"; +$lo1="t2"; +$hi1="t3"; +$aj="t4"; +$bi="t5"; +$nj="t6"; +$tp="t7"; +$alo="t8"; +$ahi="t9"; +$nlo="t10"; +$nhi="t11"; +$tj="t12"; +$i="s3"; +$j="s4"; +$m1="s5"; + +$code=<<___; +#ifdef __linux__ +#include +#else +#include +#include +#endif + +.text + +.set noat +.set noreorder + +.globl bn_mul_mont +.align 5 +.ent bn_mul_mont +bn_mul_mont: + lda sp,-48(sp) + stq ra,0(sp) + stq s3,8(sp) + stq s4,16(sp) + stq s5,24(sp) + stq fp,32(sp) + mov sp,fp + .mask 0x0400f000,-48 + .frame fp,48,ra + .prologue 0 + + .align 4 + .set reorder + sextl $num,$num + mov 0,v0 + cmplt $num,4,AT + bne AT,.Lexit + + ldq $hi0,0($ap) # ap[0] + s8addq $num,16,AT + ldq $aj,8($ap) + subq sp,AT,sp + ldq $bi,0($bp) # bp[0] + lda AT,-4096(zero) # mov -4096,AT + ldq $n0,0($n0) + and sp,AT,sp + + mulq $hi0,$bi,$lo0 + ldq $hi1,0($np) # np[0] + umulh $hi0,$bi,$hi0 + ldq $nj,8($np) + + mulq $lo0,$n0,$m1 + + mulq $hi1,$m1,$lo1 + umulh $hi1,$m1,$hi1 + + addq $lo1,$lo0,$lo1 + cmpult $lo1,$lo0,AT + addq $hi1,AT,$hi1 + + mulq $aj,$bi,$alo + mov 2,$j + umulh $aj,$bi,$ahi + mov sp,$tp + + mulq $nj,$m1,$nlo + s8addq $j,$ap,$aj + umulh $nj,$m1,$nhi + s8addq $j,$np,$nj +.align 4 +.L1st: + .set noreorder + ldq $aj,0($aj) + addl $j,1,$j + ldq $nj,0($nj) + lda $tp,8($tp) + + addq $alo,$hi0,$lo0 + mulq $aj,$bi,$alo + cmpult $lo0,$hi0,AT + addq $nlo,$hi1,$lo1 + + mulq $nj,$m1,$nlo + addq $ahi,AT,$hi0 + cmpult $lo1,$hi1,v0 + cmplt $j,$num,$tj + + umulh $aj,$bi,$ahi + addq $nhi,v0,$hi1 + addq $lo1,$lo0,$lo1 + s8addq $j,$ap,$aj + + umulh $nj,$m1,$nhi + cmpult $lo1,$lo0,v0 + addq $hi1,v0,$hi1 + s8addq $j,$np,$nj + + stq $lo1,-8($tp) + nop + unop + bne $tj,.L1st + .set reorder + + addq $alo,$hi0,$lo0 + addq $nlo,$hi1,$lo1 + cmpult $lo0,$hi0,AT + cmpult $lo1,$hi1,v0 + addq $ahi,AT,$hi0 + addq $nhi,v0,$hi1 + + addq $lo1,$lo0,$lo1 + cmpult $lo1,$lo0,v0 + addq $hi1,v0,$hi1 + + stq $lo1,0($tp) + + addq $hi1,$hi0,$hi1 + cmpult $hi1,$hi0,AT + stq $hi1,8($tp) + stq AT,16($tp) + + mov 1,$i +.align 4 +.Louter: + s8addq $i,$bp,$bi + ldq $hi0,0($ap) + ldq $aj,8($ap) + ldq $bi,0($bi) + ldq $hi1,0($np) + ldq $nj,8($np) + ldq $tj,0(sp) + + mulq $hi0,$bi,$lo0 + umulh $hi0,$bi,$hi0 + + addq $lo0,$tj,$lo0 + cmpult $lo0,$tj,AT + addq $hi0,AT,$hi0 + + mulq $lo0,$n0,$m1 + + mulq $hi1,$m1,$lo1 + umulh $hi1,$m1,$hi1 + + addq $lo1,$lo0,$lo1 + cmpult $lo1,$lo0,AT + mov 2,$j + addq $hi1,AT,$hi1 + + mulq $aj,$bi,$alo + mov sp,$tp + umulh $aj,$bi,$ahi + + mulq $nj,$m1,$nlo + s8addq $j,$ap,$aj + umulh $nj,$m1,$nhi +.align 4 +.Linner: + .set noreorder + ldq $tj,8($tp) #L0 + nop #U1 + ldq $aj,0($aj) #L1 + s8addq $j,$np,$nj #U0 + + ldq $nj,0($nj) #L0 + nop #U1 + addq $alo,$hi0,$lo0 #L1 + lda $tp,8($tp) + + mulq $aj,$bi,$alo #U1 + cmpult $lo0,$hi0,AT #L0 + addq $nlo,$hi1,$lo1 #L1 + addl $j,1,$j + + mulq $nj,$m1,$nlo #U1 + addq $ahi,AT,$hi0 #L0 + addq $lo0,$tj,$lo0 #L1 + cmpult $lo1,$hi1,v0 #U0 + + umulh $aj,$bi,$ahi #U1 + cmpult $lo0,$tj,AT #L0 + addq $lo1,$lo0,$lo1 #L1 + addq $nhi,v0,$hi1 #U0 + + umulh $nj,$m1,$nhi #U1 + s8addq $j,$ap,$aj #L0 + cmpult $lo1,$lo0,v0 #L1 + cmplt $j,$num,$tj #U0 # borrow $tj + + addq $hi0,AT,$hi0 #L0 + addq $hi1,v0,$hi1 #U1 + stq $lo1,-8($tp) #L1 + bne $tj,.Linner #U0 + .set reorder + + ldq $tj,8($tp) + addq $alo,$hi0,$lo0 + addq $nlo,$hi1,$lo1 + cmpult $lo0,$hi0,AT + cmpult $lo1,$hi1,v0 + addq $ahi,AT,$hi0 + addq $nhi,v0,$hi1 + + addq $lo0,$tj,$lo0 + cmpult $lo0,$tj,AT + addq $hi0,AT,$hi0 + + ldq $tj,16($tp) + addq $lo1,$lo0,$j + cmpult $j,$lo0,v0 + addq $hi1,v0,$hi1 + + addq $hi1,$hi0,$lo1 + stq $j,0($tp) + cmpult $lo1,$hi0,$hi1 + addq $lo1,$tj,$lo1 + cmpult $lo1,$tj,AT + addl $i,1,$i + addq $hi1,AT,$hi1 + stq $lo1,8($tp) + cmplt $i,$num,$tj # borrow $tj + stq $hi1,16($tp) + bne $tj,.Louter + + s8addq $num,sp,$tj # &tp[num] + mov $rp,$bp # put rp aside + mov sp,$tp + mov sp,$ap + mov 0,$hi0 # clear borrow bit + +.align 4 +.Lsub: ldq $lo0,0($tp) + ldq $lo1,0($np) + lda $tp,8($tp) + lda $np,8($np) + subq $lo0,$lo1,$lo1 # tp[i]-np[i] + cmpult $lo0,$lo1,AT + subq $lo1,$hi0,$lo0 + cmpult $lo1,$lo0,$hi0 + or $hi0,AT,$hi0 + stq $lo0,0($rp) + cmpult $tp,$tj,v0 + lda $rp,8($rp) + bne v0,.Lsub + + subq $hi1,$hi0,$hi0 # handle upmost overflow bit + mov sp,$tp + mov $bp,$rp # restore rp + + and sp,$hi0,$ap + bic $bp,$hi0,$bp + bis $bp,$ap,$ap # ap=borrow?tp:rp + +.align 4 +.Lcopy: ldq $aj,0($ap) # copy or in-place refresh + lda $tp,8($tp) + lda $rp,8($rp) + lda $ap,8($ap) + stq zero,-8($tp) # zap tp + cmpult $tp,$tj,AT + stq $aj,-8($rp) + bne AT,.Lcopy + mov 1,v0 + +.Lexit: + .set noreorder + mov fp,sp + /*ldq ra,0(sp)*/ + ldq s3,8(sp) + ldq s4,16(sp) + ldq s5,24(sp) + ldq fp,32(sp) + lda sp,48(sp) + ret (ra) +.end bn_mul_mont +.ascii "Montgomery Multiplication for Alpha, CRYPTOGAMS by " +.align 2 +___ + +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/armv4-gf2m.pl b/libs/openssl/crypto/bn/asm/armv4-gf2m.pl new file mode 100644 index 00000000..22ad1f85 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/armv4-gf2m.pl @@ -0,0 +1,278 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# May 2011 +# +# The module implements bn_GF2m_mul_2x2 polynomial multiplication +# used in bn_gf2m.c. It's kind of low-hanging mechanical port from +# C for the time being... Except that it has two code paths: pure +# integer code suitable for any ARMv4 and later CPU and NEON code +# suitable for ARMv7. Pure integer 1x1 multiplication subroutine runs +# in ~45 cycles on dual-issue core such as Cortex A8, which is ~50% +# faster than compiler-generated code. For ECDH and ECDSA verify (but +# not for ECDSA sign) it means 25%-45% improvement depending on key +# length, more for longer keys. Even though NEON 1x1 multiplication +# runs in even less cycles, ~30, improvement is measurable only on +# longer keys. One has to optimize code elsewhere to get NEON glow... + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +sub Dlo() { shift=~m|q([1]?[0-9])|?"d".($1*2):""; } +sub Dhi() { shift=~m|q([1]?[0-9])|?"d".($1*2+1):""; } +sub Q() { shift=~m|d([1-3]?[02468])|?"q".($1/2):""; } + +$code=<<___; +#include "arm_arch.h" + +.text +.code 32 + +#if __ARM_ARCH__>=7 +.fpu neon + +.type mul_1x1_neon,%function +.align 5 +mul_1x1_neon: + vshl.u64 `&Dlo("q1")`,d16,#8 @ q1-q3 are slided $a + vmull.p8 `&Q("d0")`,d16,d17 @ a·bb + vshl.u64 `&Dlo("q2")`,d16,#16 + vmull.p8 q1,`&Dlo("q1")`,d17 @ a<<8·bb + vshl.u64 `&Dlo("q3")`,d16,#24 + vmull.p8 q2,`&Dlo("q2")`,d17 @ a<<16·bb + vshr.u64 `&Dlo("q1")`,#8 + vmull.p8 q3,`&Dlo("q3")`,d17 @ a<<24·bb + vshl.u64 `&Dhi("q1")`,#24 + veor d0,`&Dlo("q1")` + vshr.u64 `&Dlo("q2")`,#16 + veor d0,`&Dhi("q1")` + vshl.u64 `&Dhi("q2")`,#16 + veor d0,`&Dlo("q2")` + vshr.u64 `&Dlo("q3")`,#24 + veor d0,`&Dhi("q2")` + vshl.u64 `&Dhi("q3")`,#8 + veor d0,`&Dlo("q3")` + veor d0,`&Dhi("q3")` + bx lr +.size mul_1x1_neon,.-mul_1x1_neon +#endif +___ +################ +# private interface to mul_1x1_ialu +# +$a="r1"; +$b="r0"; + +($a0,$a1,$a2,$a12,$a4,$a14)= +($hi,$lo,$t0,$t1, $i0,$i1 )=map("r$_",(4..9),12); + +$mask="r12"; + +$code.=<<___; +.type mul_1x1_ialu,%function +.align 5 +mul_1x1_ialu: + mov $a0,#0 + bic $a1,$a,#3<<30 @ a1=a&0x3fffffff + str $a0,[sp,#0] @ tab[0]=0 + add $a2,$a1,$a1 @ a2=a1<<1 + str $a1,[sp,#4] @ tab[1]=a1 + eor $a12,$a1,$a2 @ a1^a2 + str $a2,[sp,#8] @ tab[2]=a2 + mov $a4,$a1,lsl#2 @ a4=a1<<2 + str $a12,[sp,#12] @ tab[3]=a1^a2 + eor $a14,$a1,$a4 @ a1^a4 + str $a4,[sp,#16] @ tab[4]=a4 + eor $a0,$a2,$a4 @ a2^a4 + str $a14,[sp,#20] @ tab[5]=a1^a4 + eor $a12,$a12,$a4 @ a1^a2^a4 + str $a0,[sp,#24] @ tab[6]=a2^a4 + and $i0,$mask,$b,lsl#2 + str $a12,[sp,#28] @ tab[7]=a1^a2^a4 + + and $i1,$mask,$b,lsr#1 + ldr $lo,[sp,$i0] @ tab[b & 0x7] + and $i0,$mask,$b,lsr#4 + ldr $t1,[sp,$i1] @ tab[b >> 3 & 0x7] + and $i1,$mask,$b,lsr#7 + ldr $t0,[sp,$i0] @ tab[b >> 6 & 0x7] + eor $lo,$lo,$t1,lsl#3 @ stall + mov $hi,$t1,lsr#29 + ldr $t1,[sp,$i1] @ tab[b >> 9 & 0x7] + + and $i0,$mask,$b,lsr#10 + eor $lo,$lo,$t0,lsl#6 + eor $hi,$hi,$t0,lsr#26 + ldr $t0,[sp,$i0] @ tab[b >> 12 & 0x7] + + and $i1,$mask,$b,lsr#13 + eor $lo,$lo,$t1,lsl#9 + eor $hi,$hi,$t1,lsr#23 + ldr $t1,[sp,$i1] @ tab[b >> 15 & 0x7] + + and $i0,$mask,$b,lsr#16 + eor $lo,$lo,$t0,lsl#12 + eor $hi,$hi,$t0,lsr#20 + ldr $t0,[sp,$i0] @ tab[b >> 18 & 0x7] + + and $i1,$mask,$b,lsr#19 + eor $lo,$lo,$t1,lsl#15 + eor $hi,$hi,$t1,lsr#17 + ldr $t1,[sp,$i1] @ tab[b >> 21 & 0x7] + + and $i0,$mask,$b,lsr#22 + eor $lo,$lo,$t0,lsl#18 + eor $hi,$hi,$t0,lsr#14 + ldr $t0,[sp,$i0] @ tab[b >> 24 & 0x7] + + and $i1,$mask,$b,lsr#25 + eor $lo,$lo,$t1,lsl#21 + eor $hi,$hi,$t1,lsr#11 + ldr $t1,[sp,$i1] @ tab[b >> 27 & 0x7] + + tst $a,#1<<30 + and $i0,$mask,$b,lsr#28 + eor $lo,$lo,$t0,lsl#24 + eor $hi,$hi,$t0,lsr#8 + ldr $t0,[sp,$i0] @ tab[b >> 30 ] + + eorne $lo,$lo,$b,lsl#30 + eorne $hi,$hi,$b,lsr#2 + tst $a,#1<<31 + eor $lo,$lo,$t1,lsl#27 + eor $hi,$hi,$t1,lsr#5 + eorne $lo,$lo,$b,lsl#31 + eorne $hi,$hi,$b,lsr#1 + eor $lo,$lo,$t0,lsl#30 + eor $hi,$hi,$t0,lsr#2 + + mov pc,lr +.size mul_1x1_ialu,.-mul_1x1_ialu +___ +################ +# void bn_GF2m_mul_2x2(BN_ULONG *r, +# BN_ULONG a1,BN_ULONG a0, +# BN_ULONG b1,BN_ULONG b0); # r[3..0]=a1a0·b1b0 + +($A1,$B1,$A0,$B0,$A1B1,$A0B0)=map("d$_",(18..23)); + +$code.=<<___; +.global bn_GF2m_mul_2x2 +.type bn_GF2m_mul_2x2,%function +.align 5 +bn_GF2m_mul_2x2: +#if __ARM_ARCH__>=7 + ldr r12,.LOPENSSL_armcap +.Lpic: ldr r12,[pc,r12] + tst r12,#1 + beq .Lialu + + veor $A1,$A1 + vmov.32 $B1,r3,r3 @ two copies of b1 + vmov.32 ${A1}[0],r1 @ a1 + + veor $A0,$A0 + vld1.32 ${B0}[],[sp,:32] @ two copies of b0 + vmov.32 ${A0}[0],r2 @ a0 + mov r12,lr + + vmov d16,$A1 + vmov d17,$B1 + bl mul_1x1_neon @ a1·b1 + vmov $A1B1,d0 + + vmov d16,$A0 + vmov d17,$B0 + bl mul_1x1_neon @ a0·b0 + vmov $A0B0,d0 + + veor d16,$A0,$A1 + veor d17,$B0,$B1 + veor $A0,$A0B0,$A1B1 + bl mul_1x1_neon @ (a0+a1)·(b0+b1) + + veor d0,$A0 @ (a0+a1)·(b0+b1)-a0·b0-a1·b1 + vshl.u64 d1,d0,#32 + vshr.u64 d0,d0,#32 + veor $A0B0,d1 + veor $A1B1,d0 + vst1.32 {${A0B0}[0]},[r0,:32]! + vst1.32 {${A0B0}[1]},[r0,:32]! + vst1.32 {${A1B1}[0]},[r0,:32]! + vst1.32 {${A1B1}[1]},[r0,:32] + bx r12 +.align 4 +.Lialu: +#endif +___ +$ret="r10"; # reassigned 1st argument +$code.=<<___; + stmdb sp!,{r4-r10,lr} + mov $ret,r0 @ reassign 1st argument + mov $b,r3 @ $b=b1 + ldr r3,[sp,#32] @ load b0 + mov $mask,#7<<2 + sub sp,sp,#32 @ allocate tab[8] + + bl mul_1x1_ialu @ a1·b1 + str $lo,[$ret,#8] + str $hi,[$ret,#12] + + eor $b,$b,r3 @ flip b0 and b1 + eor $a,$a,r2 @ flip a0 and a1 + eor r3,r3,$b + eor r2,r2,$a + eor $b,$b,r3 + eor $a,$a,r2 + bl mul_1x1_ialu @ a0·b0 + str $lo,[$ret] + str $hi,[$ret,#4] + + eor $a,$a,r2 + eor $b,$b,r3 + bl mul_1x1_ialu @ (a1+a0)·(b1+b0) +___ +@r=map("r$_",(6..9)); +$code.=<<___; + ldmia $ret,{@r[0]-@r[3]} + eor $lo,$lo,$hi + eor $hi,$hi,@r[1] + eor $lo,$lo,@r[0] + eor $hi,$hi,@r[2] + eor $lo,$lo,@r[3] + eor $hi,$hi,@r[3] + str $hi,[$ret,#8] + eor $lo,$lo,$hi + add sp,sp,#32 @ destroy tab[8] + str $lo,[$ret,#4] + +#if __ARM_ARCH__>=5 + ldmia sp!,{r4-r10,pc} +#else + ldmia sp!,{r4-r10,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif +.size bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2 +#if __ARM_ARCH__>=7 +.align 5 +.LOPENSSL_armcap: +.word OPENSSL_armcap_P-(.Lpic+8) +#endif +.asciz "GF(2^m) Multiplication for ARMv4/NEON, CRYPTOGAMS by " +.align 5 + +.comm OPENSSL_armcap_P,4,4 +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 +print $code; +close STDOUT; # enforce flush diff --git a/libs/openssl/crypto/bn/asm/armv4-mont.pl b/libs/openssl/crypto/bn/asm/armv4-mont.pl new file mode 100644 index 00000000..f78a8b5f --- /dev/null +++ b/libs/openssl/crypto/bn/asm/armv4-mont.pl @@ -0,0 +1,204 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# January 2007. + +# Montgomery multiplication for ARMv4. +# +# Performance improvement naturally varies among CPU implementations +# and compilers. The code was observed to provide +65-35% improvement +# [depending on key length, less for longer keys] on ARM920T, and +# +115-80% on Intel IXP425. This is compared to pre-bn_mul_mont code +# base and compiler generated code with in-lined umull and even umlal +# instructions. The latter means that this code didn't really have an +# "advantage" of utilizing some "secret" instruction. +# +# The code is interoperable with Thumb ISA and is rather compact, less +# than 1/2KB. Windows CE port would be trivial, as it's exclusively +# about decorations, ABI and instruction syntax are identical. + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +$num="r0"; # starts as num argument, but holds &tp[num-1] +$ap="r1"; +$bp="r2"; $bi="r2"; $rp="r2"; +$np="r3"; +$tp="r4"; +$aj="r5"; +$nj="r6"; +$tj="r7"; +$n0="r8"; +########### # r9 is reserved by ELF as platform specific, e.g. TLS pointer +$alo="r10"; # sl, gcc uses it to keep @GOT +$ahi="r11"; # fp +$nlo="r12"; # ip +########### # r13 is stack pointer +$nhi="r14"; # lr +########### # r15 is program counter + +#### argument block layout relative to &tp[num-1], a.k.a. $num +$_rp="$num,#12*4"; +# ap permanently resides in r1 +$_bp="$num,#13*4"; +# np permanently resides in r3 +$_n0="$num,#14*4"; +$_num="$num,#15*4"; $_bpend=$_num; + +$code=<<___; +.text + +.global bn_mul_mont +.type bn_mul_mont,%function + +.align 2 +bn_mul_mont: + stmdb sp!,{r0,r2} @ sp points at argument block + ldr $num,[sp,#3*4] @ load num + cmp $num,#2 + movlt r0,#0 + addlt sp,sp,#2*4 + blt .Labrt + + stmdb sp!,{r4-r12,lr} @ save 10 registers + + mov $num,$num,lsl#2 @ rescale $num for byte count + sub sp,sp,$num @ alloca(4*num) + sub sp,sp,#4 @ +extra dword + sub $num,$num,#4 @ "num=num-1" + add $tp,$bp,$num @ &bp[num-1] + + add $num,sp,$num @ $num to point at &tp[num-1] + ldr $n0,[$_n0] @ &n0 + ldr $bi,[$bp] @ bp[0] + ldr $aj,[$ap],#4 @ ap[0],ap++ + ldr $nj,[$np],#4 @ np[0],np++ + ldr $n0,[$n0] @ *n0 + str $tp,[$_bpend] @ save &bp[num] + + umull $alo,$ahi,$aj,$bi @ ap[0]*bp[0] + str $n0,[$_n0] @ save n0 value + mul $n0,$alo,$n0 @ "tp[0]"*n0 + mov $nlo,#0 + umlal $alo,$nlo,$nj,$n0 @ np[0]*n0+"t[0]" + mov $tp,sp + +.L1st: + ldr $aj,[$ap],#4 @ ap[j],ap++ + mov $alo,$ahi + ldr $nj,[$np],#4 @ np[j],np++ + mov $ahi,#0 + umlal $alo,$ahi,$aj,$bi @ ap[j]*bp[0] + mov $nhi,#0 + umlal $nlo,$nhi,$nj,$n0 @ np[j]*n0 + adds $nlo,$nlo,$alo + str $nlo,[$tp],#4 @ tp[j-1]=,tp++ + adc $nlo,$nhi,#0 + cmp $tp,$num + bne .L1st + + adds $nlo,$nlo,$ahi + ldr $tp,[$_bp] @ restore bp + mov $nhi,#0 + ldr $n0,[$_n0] @ restore n0 + adc $nhi,$nhi,#0 + str $nlo,[$num] @ tp[num-1]= + str $nhi,[$num,#4] @ tp[num]= + +.Louter: + sub $tj,$num,sp @ "original" $num-1 value + sub $ap,$ap,$tj @ "rewind" ap to &ap[1] + ldr $bi,[$tp,#4]! @ *(++bp) + sub $np,$np,$tj @ "rewind" np to &np[1] + ldr $aj,[$ap,#-4] @ ap[0] + ldr $alo,[sp] @ tp[0] + ldr $nj,[$np,#-4] @ np[0] + ldr $tj,[sp,#4] @ tp[1] + + mov $ahi,#0 + umlal $alo,$ahi,$aj,$bi @ ap[0]*bp[i]+tp[0] + str $tp,[$_bp] @ save bp + mul $n0,$alo,$n0 + mov $nlo,#0 + umlal $alo,$nlo,$nj,$n0 @ np[0]*n0+"tp[0]" + mov $tp,sp + +.Linner: + ldr $aj,[$ap],#4 @ ap[j],ap++ + adds $alo,$ahi,$tj @ +=tp[j] + ldr $nj,[$np],#4 @ np[j],np++ + mov $ahi,#0 + umlal $alo,$ahi,$aj,$bi @ ap[j]*bp[i] + mov $nhi,#0 + umlal $nlo,$nhi,$nj,$n0 @ np[j]*n0 + adc $ahi,$ahi,#0 + ldr $tj,[$tp,#8] @ tp[j+1] + adds $nlo,$nlo,$alo + str $nlo,[$tp],#4 @ tp[j-1]=,tp++ + adc $nlo,$nhi,#0 + cmp $tp,$num + bne .Linner + + adds $nlo,$nlo,$ahi + mov $nhi,#0 + ldr $tp,[$_bp] @ restore bp + adc $nhi,$nhi,#0 + ldr $n0,[$_n0] @ restore n0 + adds $nlo,$nlo,$tj + ldr $tj,[$_bpend] @ restore &bp[num] + adc $nhi,$nhi,#0 + str $nlo,[$num] @ tp[num-1]= + str $nhi,[$num,#4] @ tp[num]= + + cmp $tp,$tj + bne .Louter + + ldr $rp,[$_rp] @ pull rp + add $num,$num,#4 @ $num to point at &tp[num] + sub $aj,$num,sp @ "original" num value + mov $tp,sp @ "rewind" $tp + mov $ap,$tp @ "borrow" $ap + sub $np,$np,$aj @ "rewind" $np to &np[0] + + subs $tj,$tj,$tj @ "clear" carry flag +.Lsub: ldr $tj,[$tp],#4 + ldr $nj,[$np],#4 + sbcs $tj,$tj,$nj @ tp[j]-np[j] + str $tj,[$rp],#4 @ rp[j]= + teq $tp,$num @ preserve carry + bne .Lsub + sbcs $nhi,$nhi,#0 @ upmost carry + mov $tp,sp @ "rewind" $tp + sub $rp,$rp,$aj @ "rewind" $rp + + and $ap,$tp,$nhi + bic $np,$rp,$nhi + orr $ap,$ap,$np @ ap=borrow?tp:rp + +.Lcopy: ldr $tj,[$ap],#4 @ copy or in-place refresh + str sp,[$tp],#4 @ zap tp + str $tj,[$rp],#4 + cmp $tp,$num + bne .Lcopy + + add sp,$num,#4 @ skip over tp[num+1] + ldmia sp!,{r4-r12,lr} @ restore registers + add sp,sp,#2*4 @ skip over {r0,r2} + mov r0,#1 +.Labrt: tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +.size bn_mul_mont,.-bn_mul_mont +.asciz "Montgomery multiplication for ARMv4, CRYPTOGAMS by " +.align 2 +___ + +$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/bn-586.pl b/libs/openssl/crypto/bn/asm/bn-586.pl new file mode 100644 index 00000000..332ef3e9 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/bn-586.pl @@ -0,0 +1,774 @@ +#!/usr/local/bin/perl + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],$0); + +$sse2=0; +for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } + +&external_label("OPENSSL_ia32cap_P") if ($sse2); + +&bn_mul_add_words("bn_mul_add_words"); +&bn_mul_words("bn_mul_words"); +&bn_sqr_words("bn_sqr_words"); +&bn_div_words("bn_div_words"); +&bn_add_words("bn_add_words"); +&bn_sub_words("bn_sub_words"); +&bn_sub_part_words("bn_sub_part_words"); + +&asm_finish(); + +sub bn_mul_add_words + { + local($name)=@_; + + &function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":""); + + $r="eax"; + $a="edx"; + $c="ecx"; + + if ($sse2) { + &picmeup("eax","OPENSSL_ia32cap_P"); + &bt(&DWP(0,"eax"),26); + &jnc(&label("maw_non_sse2")); + + &mov($r,&wparam(0)); + &mov($a,&wparam(1)); + &mov($c,&wparam(2)); + &movd("mm0",&wparam(3)); # mm0 = w + &pxor("mm1","mm1"); # mm1 = carry_in + &jmp(&label("maw_sse2_entry")); + + &set_label("maw_sse2_unrolled",16); + &movd("mm3",&DWP(0,$r,"",0)); # mm3 = r[0] + &paddq("mm1","mm3"); # mm1 = carry_in + r[0] + &movd("mm2",&DWP(0,$a,"",0)); # mm2 = a[0] + &pmuludq("mm2","mm0"); # mm2 = w*a[0] + &movd("mm4",&DWP(4,$a,"",0)); # mm4 = a[1] + &pmuludq("mm4","mm0"); # mm4 = w*a[1] + &movd("mm6",&DWP(8,$a,"",0)); # mm6 = a[2] + &pmuludq("mm6","mm0"); # mm6 = w*a[2] + &movd("mm7",&DWP(12,$a,"",0)); # mm7 = a[3] + &pmuludq("mm7","mm0"); # mm7 = w*a[3] + &paddq("mm1","mm2"); # mm1 = carry_in + r[0] + w*a[0] + &movd("mm3",&DWP(4,$r,"",0)); # mm3 = r[1] + &paddq("mm3","mm4"); # mm3 = r[1] + w*a[1] + &movd("mm5",&DWP(8,$r,"",0)); # mm5 = r[2] + &paddq("mm5","mm6"); # mm5 = r[2] + w*a[2] + &movd("mm4",&DWP(12,$r,"",0)); # mm4 = r[3] + &paddq("mm7","mm4"); # mm7 = r[3] + w*a[3] + &movd(&DWP(0,$r,"",0),"mm1"); + &movd("mm2",&DWP(16,$a,"",0)); # mm2 = a[4] + &pmuludq("mm2","mm0"); # mm2 = w*a[4] + &psrlq("mm1",32); # mm1 = carry0 + &movd("mm4",&DWP(20,$a,"",0)); # mm4 = a[5] + &pmuludq("mm4","mm0"); # mm4 = w*a[5] + &paddq("mm1","mm3"); # mm1 = carry0 + r[1] + w*a[1] + &movd("mm6",&DWP(24,$a,"",0)); # mm6 = a[6] + &pmuludq("mm6","mm0"); # mm6 = w*a[6] + &movd(&DWP(4,$r,"",0),"mm1"); + &psrlq("mm1",32); # mm1 = carry1 + &movd("mm3",&DWP(28,$a,"",0)); # mm3 = a[7] + &add($a,32); + &pmuludq("mm3","mm0"); # mm3 = w*a[7] + &paddq("mm1","mm5"); # mm1 = carry1 + r[2] + w*a[2] + &movd("mm5",&DWP(16,$r,"",0)); # mm5 = r[4] + &paddq("mm2","mm5"); # mm2 = r[4] + w*a[4] + &movd(&DWP(8,$r,"",0),"mm1"); + &psrlq("mm1",32); # mm1 = carry2 + &paddq("mm1","mm7"); # mm1 = carry2 + r[3] + w*a[3] + &movd("mm5",&DWP(20,$r,"",0)); # mm5 = r[5] + &paddq("mm4","mm5"); # mm4 = r[5] + w*a[5] + &movd(&DWP(12,$r,"",0),"mm1"); + &psrlq("mm1",32); # mm1 = carry3 + &paddq("mm1","mm2"); # mm1 = carry3 + r[4] + w*a[4] + &movd("mm5",&DWP(24,$r,"",0)); # mm5 = r[6] + &paddq("mm6","mm5"); # mm6 = r[6] + w*a[6] + &movd(&DWP(16,$r,"",0),"mm1"); + &psrlq("mm1",32); # mm1 = carry4 + &paddq("mm1","mm4"); # mm1 = carry4 + r[5] + w*a[5] + &movd("mm5",&DWP(28,$r,"",0)); # mm5 = r[7] + &paddq("mm3","mm5"); # mm3 = r[7] + w*a[7] + &movd(&DWP(20,$r,"",0),"mm1"); + &psrlq("mm1",32); # mm1 = carry5 + &paddq("mm1","mm6"); # mm1 = carry5 + r[6] + w*a[6] + &movd(&DWP(24,$r,"",0),"mm1"); + &psrlq("mm1",32); # mm1 = carry6 + &paddq("mm1","mm3"); # mm1 = carry6 + r[7] + w*a[7] + &movd(&DWP(28,$r,"",0),"mm1"); + &lea($r,&DWP(32,$r)); + &psrlq("mm1",32); # mm1 = carry_out + + &sub($c,8); + &jz(&label("maw_sse2_exit")); + &set_label("maw_sse2_entry"); + &test($c,0xfffffff8); + &jnz(&label("maw_sse2_unrolled")); + + &set_label("maw_sse2_loop",4); + &movd("mm2",&DWP(0,$a)); # mm2 = a[i] + &movd("mm3",&DWP(0,$r)); # mm3 = r[i] + &pmuludq("mm2","mm0"); # a[i] *= w + &lea($a,&DWP(4,$a)); + &paddq("mm1","mm3"); # carry += r[i] + &paddq("mm1","mm2"); # carry += a[i]*w + &movd(&DWP(0,$r),"mm1"); # r[i] = carry_low + &sub($c,1); + &psrlq("mm1",32); # carry = carry_high + &lea($r,&DWP(4,$r)); + &jnz(&label("maw_sse2_loop")); + &set_label("maw_sse2_exit"); + &movd("eax","mm1"); # c = carry_out + &emms(); + &ret(); + + &set_label("maw_non_sse2",16); + } + + # function_begin prologue + &push("ebp"); + &push("ebx"); + &push("esi"); + &push("edi"); + + &comment(""); + $Low="eax"; + $High="edx"; + $a="ebx"; + $w="ebp"; + $r="edi"; + $c="esi"; + + &xor($c,$c); # clear carry + &mov($r,&wparam(0)); # + + &mov("ecx",&wparam(2)); # + &mov($a,&wparam(1)); # + + &and("ecx",0xfffffff8); # num / 8 + &mov($w,&wparam(3)); # + + &push("ecx"); # Up the stack for a tmp variable + + &jz(&label("maw_finish")); + + &set_label("maw_loop",16); + + for ($i=0; $i<32; $i+=4) + { + &comment("Round $i"); + + &mov("eax",&DWP($i,$a)); # *a + &mul($w); # *a * w + &add("eax",$c); # L(t)+= c + &adc("edx",0); # H(t)+=carry + &add("eax",&DWP($i,$r)); # L(t)+= *r + &adc("edx",0); # H(t)+=carry + &mov(&DWP($i,$r),"eax"); # *r= L(t); + &mov($c,"edx"); # c= H(t); + } + + &comment(""); + &sub("ecx",8); + &lea($a,&DWP(32,$a)); + &lea($r,&DWP(32,$r)); + &jnz(&label("maw_loop")); + + &set_label("maw_finish",0); + &mov("ecx",&wparam(2)); # get num + &and("ecx",7); + &jnz(&label("maw_finish2")); # helps branch prediction + &jmp(&label("maw_end")); + + &set_label("maw_finish2",1); + for ($i=0; $i<7; $i++) + { + &comment("Tail Round $i"); + &mov("eax",&DWP($i*4,$a)); # *a + &mul($w); # *a * w + &add("eax",$c); # L(t)+=c + &adc("edx",0); # H(t)+=carry + &add("eax",&DWP($i*4,$r)); # L(t)+= *r + &adc("edx",0); # H(t)+=carry + &dec("ecx") if ($i != 7-1); + &mov(&DWP($i*4,$r),"eax"); # *r= L(t); + &mov($c,"edx"); # c= H(t); + &jz(&label("maw_end")) if ($i != 7-1); + } + &set_label("maw_end",0); + &mov("eax",$c); + + &pop("ecx"); # clear variable from + + &function_end($name); + } + +sub bn_mul_words + { + local($name)=@_; + + &function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":""); + + $r="eax"; + $a="edx"; + $c="ecx"; + + if ($sse2) { + &picmeup("eax","OPENSSL_ia32cap_P"); + &bt(&DWP(0,"eax"),26); + &jnc(&label("mw_non_sse2")); + + &mov($r,&wparam(0)); + &mov($a,&wparam(1)); + &mov($c,&wparam(2)); + &movd("mm0",&wparam(3)); # mm0 = w + &pxor("mm1","mm1"); # mm1 = carry = 0 + + &set_label("mw_sse2_loop",16); + &movd("mm2",&DWP(0,$a)); # mm2 = a[i] + &pmuludq("mm2","mm0"); # a[i] *= w + &lea($a,&DWP(4,$a)); + &paddq("mm1","mm2"); # carry += a[i]*w + &movd(&DWP(0,$r),"mm1"); # r[i] = carry_low + &sub($c,1); + &psrlq("mm1",32); # carry = carry_high + &lea($r,&DWP(4,$r)); + &jnz(&label("mw_sse2_loop")); + + &movd("eax","mm1"); # return carry + &emms(); + &ret(); + &set_label("mw_non_sse2",16); + } + + # function_begin prologue + &push("ebp"); + &push("ebx"); + &push("esi"); + &push("edi"); + + &comment(""); + $Low="eax"; + $High="edx"; + $a="ebx"; + $w="ecx"; + $r="edi"; + $c="esi"; + $num="ebp"; + + &xor($c,$c); # clear carry + &mov($r,&wparam(0)); # + &mov($a,&wparam(1)); # + &mov($num,&wparam(2)); # + &mov($w,&wparam(3)); # + + &and($num,0xfffffff8); # num / 8 + &jz(&label("mw_finish")); + + &set_label("mw_loop",0); + for ($i=0; $i<32; $i+=4) + { + &comment("Round $i"); + + &mov("eax",&DWP($i,$a,"",0)); # *a + &mul($w); # *a * w + &add("eax",$c); # L(t)+=c + # XXX + + &adc("edx",0); # H(t)+=carry + &mov(&DWP($i,$r,"",0),"eax"); # *r= L(t); + + &mov($c,"edx"); # c= H(t); + } + + &comment(""); + &add($a,32); + &add($r,32); + &sub($num,8); + &jz(&label("mw_finish")); + &jmp(&label("mw_loop")); + + &set_label("mw_finish",0); + &mov($num,&wparam(2)); # get num + &and($num,7); + &jnz(&label("mw_finish2")); + &jmp(&label("mw_end")); + + &set_label("mw_finish2",1); + for ($i=0; $i<7; $i++) + { + &comment("Tail Round $i"); + &mov("eax",&DWP($i*4,$a,"",0));# *a + &mul($w); # *a * w + &add("eax",$c); # L(t)+=c + # XXX + &adc("edx",0); # H(t)+=carry + &mov(&DWP($i*4,$r,"",0),"eax");# *r= L(t); + &mov($c,"edx"); # c= H(t); + &dec($num) if ($i != 7-1); + &jz(&label("mw_end")) if ($i != 7-1); + } + &set_label("mw_end",0); + &mov("eax",$c); + + &function_end($name); + } + +sub bn_sqr_words + { + local($name)=@_; + + &function_begin_B($name,$sse2?"EXTRN\t_OPENSSL_ia32cap_P:DWORD":""); + + $r="eax"; + $a="edx"; + $c="ecx"; + + if ($sse2) { + &picmeup("eax","OPENSSL_ia32cap_P"); + &bt(&DWP(0,"eax"),26); + &jnc(&label("sqr_non_sse2")); + + &mov($r,&wparam(0)); + &mov($a,&wparam(1)); + &mov($c,&wparam(2)); + + &set_label("sqr_sse2_loop",16); + &movd("mm0",&DWP(0,$a)); # mm0 = a[i] + &pmuludq("mm0","mm0"); # a[i] *= a[i] + &lea($a,&DWP(4,$a)); # a++ + &movq(&QWP(0,$r),"mm0"); # r[i] = a[i]*a[i] + &sub($c,1); + &lea($r,&DWP(8,$r)); # r += 2 + &jnz(&label("sqr_sse2_loop")); + + &emms(); + &ret(); + &set_label("sqr_non_sse2",16); + } + + # function_begin prologue + &push("ebp"); + &push("ebx"); + &push("esi"); + &push("edi"); + + &comment(""); + $r="esi"; + $a="edi"; + $num="ebx"; + + &mov($r,&wparam(0)); # + &mov($a,&wparam(1)); # + &mov($num,&wparam(2)); # + + &and($num,0xfffffff8); # num / 8 + &jz(&label("sw_finish")); + + &set_label("sw_loop",0); + for ($i=0; $i<32; $i+=4) + { + &comment("Round $i"); + &mov("eax",&DWP($i,$a,"",0)); # *a + # XXX + &mul("eax"); # *a * *a + &mov(&DWP($i*2,$r,"",0),"eax"); # + &mov(&DWP($i*2+4,$r,"",0),"edx");# + } + + &comment(""); + &add($a,32); + &add($r,64); + &sub($num,8); + &jnz(&label("sw_loop")); + + &set_label("sw_finish",0); + &mov($num,&wparam(2)); # get num + &and($num,7); + &jz(&label("sw_end")); + + for ($i=0; $i<7; $i++) + { + &comment("Tail Round $i"); + &mov("eax",&DWP($i*4,$a,"",0)); # *a + # XXX + &mul("eax"); # *a * *a + &mov(&DWP($i*8,$r,"",0),"eax"); # + &dec($num) if ($i != 7-1); + &mov(&DWP($i*8+4,$r,"",0),"edx"); + &jz(&label("sw_end")) if ($i != 7-1); + } + &set_label("sw_end",0); + + &function_end($name); + } + +sub bn_div_words + { + local($name)=@_; + + &function_begin_B($name,""); + &mov("edx",&wparam(0)); # + &mov("eax",&wparam(1)); # + &mov("ecx",&wparam(2)); # + &div("ecx"); + &ret(); + &function_end_B($name); + } + +sub bn_add_words + { + local($name)=@_; + + &function_begin($name,""); + + &comment(""); + $a="esi"; + $b="edi"; + $c="eax"; + $r="ebx"; + $tmp1="ecx"; + $tmp2="edx"; + $num="ebp"; + + &mov($r,&wparam(0)); # get r + &mov($a,&wparam(1)); # get a + &mov($b,&wparam(2)); # get b + &mov($num,&wparam(3)); # get num + &xor($c,$c); # clear carry + &and($num,0xfffffff8); # num / 8 + + &jz(&label("aw_finish")); + + &set_label("aw_loop",0); + for ($i=0; $i<8; $i++) + { + &comment("Round $i"); + + &mov($tmp1,&DWP($i*4,$a,"",0)); # *a + &mov($tmp2,&DWP($i*4,$b,"",0)); # *b + &add($tmp1,$c); + &mov($c,0); + &adc($c,$c); + &add($tmp1,$tmp2); + &adc($c,0); + &mov(&DWP($i*4,$r,"",0),$tmp1); # *r + } + + &comment(""); + &add($a,32); + &add($b,32); + &add($r,32); + &sub($num,8); + &jnz(&label("aw_loop")); + + &set_label("aw_finish",0); + &mov($num,&wparam(3)); # get num + &and($num,7); + &jz(&label("aw_end")); + + for ($i=0; $i<7; $i++) + { + &comment("Tail Round $i"); + &mov($tmp1,&DWP($i*4,$a,"",0)); # *a + &mov($tmp2,&DWP($i*4,$b,"",0));# *b + &add($tmp1,$c); + &mov($c,0); + &adc($c,$c); + &add($tmp1,$tmp2); + &adc($c,0); + &dec($num) if ($i != 6); + &mov(&DWP($i*4,$r,"",0),$tmp1); # *r + &jz(&label("aw_end")) if ($i != 6); + } + &set_label("aw_end",0); + +# &mov("eax",$c); # $c is "eax" + + &function_end($name); + } + +sub bn_sub_words + { + local($name)=@_; + + &function_begin($name,""); + + &comment(""); + $a="esi"; + $b="edi"; + $c="eax"; + $r="ebx"; + $tmp1="ecx"; + $tmp2="edx"; + $num="ebp"; + + &mov($r,&wparam(0)); # get r + &mov($a,&wparam(1)); # get a + &mov($b,&wparam(2)); # get b + &mov($num,&wparam(3)); # get num + &xor($c,$c); # clear carry + &and($num,0xfffffff8); # num / 8 + + &jz(&label("aw_finish")); + + &set_label("aw_loop",0); + for ($i=0; $i<8; $i++) + { + &comment("Round $i"); + + &mov($tmp1,&DWP($i*4,$a,"",0)); # *a + &mov($tmp2,&DWP($i*4,$b,"",0)); # *b + &sub($tmp1,$c); + &mov($c,0); + &adc($c,$c); + &sub($tmp1,$tmp2); + &adc($c,0); + &mov(&DWP($i*4,$r,"",0),$tmp1); # *r + } + + &comment(""); + &add($a,32); + &add($b,32); + &add($r,32); + &sub($num,8); + &jnz(&label("aw_loop")); + + &set_label("aw_finish",0); + &mov($num,&wparam(3)); # get num + &and($num,7); + &jz(&label("aw_end")); + + for ($i=0; $i<7; $i++) + { + &comment("Tail Round $i"); + &mov($tmp1,&DWP($i*4,$a,"",0)); # *a + &mov($tmp2,&DWP($i*4,$b,"",0));# *b + &sub($tmp1,$c); + &mov($c,0); + &adc($c,$c); + &sub($tmp1,$tmp2); + &adc($c,0); + &dec($num) if ($i != 6); + &mov(&DWP($i*4,$r,"",0),$tmp1); # *r + &jz(&label("aw_end")) if ($i != 6); + } + &set_label("aw_end",0); + +# &mov("eax",$c); # $c is "eax" + + &function_end($name); + } + +sub bn_sub_part_words + { + local($name)=@_; + + &function_begin($name,""); + + &comment(""); + $a="esi"; + $b="edi"; + $c="eax"; + $r="ebx"; + $tmp1="ecx"; + $tmp2="edx"; + $num="ebp"; + + &mov($r,&wparam(0)); # get r + &mov($a,&wparam(1)); # get a + &mov($b,&wparam(2)); # get b + &mov($num,&wparam(3)); # get num + &xor($c,$c); # clear carry + &and($num,0xfffffff8); # num / 8 + + &jz(&label("aw_finish")); + + &set_label("aw_loop",0); + for ($i=0; $i<8; $i++) + { + &comment("Round $i"); + + &mov($tmp1,&DWP($i*4,$a,"",0)); # *a + &mov($tmp2,&DWP($i*4,$b,"",0)); # *b + &sub($tmp1,$c); + &mov($c,0); + &adc($c,$c); + &sub($tmp1,$tmp2); + &adc($c,0); + &mov(&DWP($i*4,$r,"",0),$tmp1); # *r + } + + &comment(""); + &add($a,32); + &add($b,32); + &add($r,32); + &sub($num,8); + &jnz(&label("aw_loop")); + + &set_label("aw_finish",0); + &mov($num,&wparam(3)); # get num + &and($num,7); + &jz(&label("aw_end")); + + for ($i=0; $i<7; $i++) + { + &comment("Tail Round $i"); + &mov($tmp1,&DWP(0,$a,"",0)); # *a + &mov($tmp2,&DWP(0,$b,"",0));# *b + &sub($tmp1,$c); + &mov($c,0); + &adc($c,$c); + &sub($tmp1,$tmp2); + &adc($c,0); + &mov(&DWP(0,$r,"",0),$tmp1); # *r + &add($a, 4); + &add($b, 4); + &add($r, 4); + &dec($num) if ($i != 6); + &jz(&label("aw_end")) if ($i != 6); + } + &set_label("aw_end",0); + + &cmp(&wparam(4),0); + &je(&label("pw_end")); + + &mov($num,&wparam(4)); # get dl + &cmp($num,0); + &je(&label("pw_end")); + &jge(&label("pw_pos")); + + &comment("pw_neg"); + &mov($tmp2,0); + &sub($tmp2,$num); + &mov($num,$tmp2); + &and($num,0xfffffff8); # num / 8 + &jz(&label("pw_neg_finish")); + + &set_label("pw_neg_loop",0); + for ($i=0; $i<8; $i++) + { + &comment("dl<0 Round $i"); + + &mov($tmp1,0); + &mov($tmp2,&DWP($i*4,$b,"",0)); # *b + &sub($tmp1,$c); + &mov($c,0); + &adc($c,$c); + &sub($tmp1,$tmp2); + &adc($c,0); + &mov(&DWP($i*4,$r,"",0),$tmp1); # *r + } + + &comment(""); + &add($b,32); + &add($r,32); + &sub($num,8); + &jnz(&label("pw_neg_loop")); + + &set_label("pw_neg_finish",0); + &mov($tmp2,&wparam(4)); # get dl + &mov($num,0); + &sub($num,$tmp2); + &and($num,7); + &jz(&label("pw_end")); + + for ($i=0; $i<7; $i++) + { + &comment("dl<0 Tail Round $i"); + &mov($tmp1,0); + &mov($tmp2,&DWP($i*4,$b,"",0));# *b + &sub($tmp1,$c); + &mov($c,0); + &adc($c,$c); + &sub($tmp1,$tmp2); + &adc($c,0); + &dec($num) if ($i != 6); + &mov(&DWP($i*4,$r,"",0),$tmp1); # *r + &jz(&label("pw_end")) if ($i != 6); + } + + &jmp(&label("pw_end")); + + &set_label("pw_pos",0); + + &and($num,0xfffffff8); # num / 8 + &jz(&label("pw_pos_finish")); + + &set_label("pw_pos_loop",0); + + for ($i=0; $i<8; $i++) + { + &comment("dl>0 Round $i"); + + &mov($tmp1,&DWP($i*4,$a,"",0)); # *a + &sub($tmp1,$c); + &mov(&DWP($i*4,$r,"",0),$tmp1); # *r + &jnc(&label("pw_nc".$i)); + } + + &comment(""); + &add($a,32); + &add($r,32); + &sub($num,8); + &jnz(&label("pw_pos_loop")); + + &set_label("pw_pos_finish",0); + &mov($num,&wparam(4)); # get dl + &and($num,7); + &jz(&label("pw_end")); + + for ($i=0; $i<7; $i++) + { + &comment("dl>0 Tail Round $i"); + &mov($tmp1,&DWP($i*4,$a,"",0)); # *a + &sub($tmp1,$c); + &mov(&DWP($i*4,$r,"",0),$tmp1); # *r + &jnc(&label("pw_tail_nc".$i)); + &dec($num) if ($i != 6); + &jz(&label("pw_end")) if ($i != 6); + } + &mov($c,1); + &jmp(&label("pw_end")); + + &set_label("pw_nc_loop",0); + for ($i=0; $i<8; $i++) + { + &mov($tmp1,&DWP($i*4,$a,"",0)); # *a + &mov(&DWP($i*4,$r,"",0),$tmp1); # *r + &set_label("pw_nc".$i,0); + } + + &comment(""); + &add($a,32); + &add($r,32); + &sub($num,8); + &jnz(&label("pw_nc_loop")); + + &mov($num,&wparam(4)); # get dl + &and($num,7); + &jz(&label("pw_nc_end")); + + for ($i=0; $i<7; $i++) + { + &mov($tmp1,&DWP($i*4,$a,"",0)); # *a + &mov(&DWP($i*4,$r,"",0),$tmp1); # *r + &set_label("pw_tail_nc".$i,0); + &dec($num) if ($i != 6); + &jz(&label("pw_nc_end")) if ($i != 6); + } + + &set_label("pw_nc_end",0); + &mov($c,0); + + &set_label("pw_end",0); + +# &mov("eax",$c); # $c is "eax" + + &function_end($name); + } + diff --git a/libs/openssl/crypto/bn/asm/co-586.pl b/libs/openssl/crypto/bn/asm/co-586.pl new file mode 100644 index 00000000..57101a6b --- /dev/null +++ b/libs/openssl/crypto/bn/asm/co-586.pl @@ -0,0 +1,287 @@ +#!/usr/local/bin/perl + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],$0); + +&bn_mul_comba("bn_mul_comba8",8); +&bn_mul_comba("bn_mul_comba4",4); +&bn_sqr_comba("bn_sqr_comba8",8); +&bn_sqr_comba("bn_sqr_comba4",4); + +&asm_finish(); + +sub mul_add_c + { + local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; + + # pos == -1 if eax and edx are pre-loaded, 0 to load from next + # words, and 1 if load return value + + &comment("mul a[$ai]*b[$bi]"); + + # "eax" and "edx" will always be pre-loaded. + # &mov("eax",&DWP($ai*4,$a,"",0)) ; + # &mov("edx",&DWP($bi*4,$b,"",0)); + + &mul("edx"); + &add($c0,"eax"); + &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # laod next a + &mov("eax",&wparam(0)) if $pos > 0; # load r[] + ### + &adc($c1,"edx"); + &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0; # laod next b + &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1; # laod next b + ### + &adc($c2,0); + # is pos > 1, it means it is the last loop + &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0; # save r[]; + &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # laod next a + } + +sub sqr_add_c + { + local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; + + # pos == -1 if eax and edx are pre-loaded, 0 to load from next + # words, and 1 if load return value + + &comment("sqr a[$ai]*a[$bi]"); + + # "eax" and "edx" will always be pre-loaded. + # &mov("eax",&DWP($ai*4,$a,"",0)) ; + # &mov("edx",&DWP($bi*4,$b,"",0)); + + if ($ai == $bi) + { &mul("eax");} + else + { &mul("edx");} + &add($c0,"eax"); + &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a + ### + &adc($c1,"edx"); + &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb); + ### + &adc($c2,0); + # is pos > 1, it means it is the last loop + &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[]; + &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b + } + +sub sqr_add_c2 + { + local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; + + # pos == -1 if eax and edx are pre-loaded, 0 to load from next + # words, and 1 if load return value + + &comment("sqr a[$ai]*a[$bi]"); + + # "eax" and "edx" will always be pre-loaded. + # &mov("eax",&DWP($ai*4,$a,"",0)) ; + # &mov("edx",&DWP($bi*4,$a,"",0)); + + if ($ai == $bi) + { &mul("eax");} + else + { &mul("edx");} + &add("eax","eax"); + ### + &adc("edx","edx"); + ### + &adc($c2,0); + &add($c0,"eax"); + &adc($c1,"edx"); + &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a + &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b + &adc($c2,0); + &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[]; + &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb); + ### + } + +sub bn_mul_comba + { + local($name,$num)=@_; + local($a,$b,$c0,$c1,$c2); + local($i,$as,$ae,$bs,$be,$ai,$bi); + local($tot,$end); + + &function_begin_B($name,""); + + $c0="ebx"; + $c1="ecx"; + $c2="ebp"; + $a="esi"; + $b="edi"; + + $as=0; + $ae=0; + $bs=0; + $be=0; + $tot=$num+$num-1; + + &push("esi"); + &mov($a,&wparam(1)); + &push("edi"); + &mov($b,&wparam(2)); + &push("ebp"); + &push("ebx"); + + &xor($c0,$c0); + &mov("eax",&DWP(0,$a,"",0)); # load the first word + &xor($c1,$c1); + &mov("edx",&DWP(0,$b,"",0)); # load the first second + + for ($i=0; $i<$tot; $i++) + { + $ai=$as; + $bi=$bs; + $end=$be+1; + + &comment("################## Calculate word $i"); + + for ($j=$bs; $j<$end; $j++) + { + &xor($c2,$c2) if ($j == $bs); + if (($j+1) == $end) + { + $v=1; + $v=2 if (($i+1) == $tot); + } + else + { $v=0; } + if (($j+1) != $end) + { + $na=($ai-1); + $nb=($bi+1); + } + else + { + $na=$as+($i < ($num-1)); + $nb=$bs+($i >= ($num-1)); + } +#printf STDERR "[$ai,$bi] -> [$na,$nb]\n"; + &mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb); + if ($v) + { + &comment("saved r[$i]"); + # &mov("eax",&wparam(0)); + # &mov(&DWP($i*4,"eax","",0),$c0); + ($c0,$c1,$c2)=($c1,$c2,$c0); + } + $ai--; + $bi++; + } + $as++ if ($i < ($num-1)); + $ae++ if ($i >= ($num-1)); + + $bs++ if ($i >= ($num-1)); + $be++ if ($i < ($num-1)); + } + &comment("save r[$i]"); + # &mov("eax",&wparam(0)); + &mov(&DWP($i*4,"eax","",0),$c0); + + &pop("ebx"); + &pop("ebp"); + &pop("edi"); + &pop("esi"); + &ret(); + &function_end_B($name); + } + +sub bn_sqr_comba + { + local($name,$num)=@_; + local($r,$a,$c0,$c1,$c2)=@_; + local($i,$as,$ae,$bs,$be,$ai,$bi); + local($b,$tot,$end,$half); + + &function_begin_B($name,""); + + $c0="ebx"; + $c1="ecx"; + $c2="ebp"; + $a="esi"; + $r="edi"; + + &push("esi"); + &push("edi"); + &push("ebp"); + &push("ebx"); + &mov($r,&wparam(0)); + &mov($a,&wparam(1)); + &xor($c0,$c0); + &xor($c1,$c1); + &mov("eax",&DWP(0,$a,"",0)); # load the first word + + $as=0; + $ae=0; + $bs=0; + $be=0; + $tot=$num+$num-1; + + for ($i=0; $i<$tot; $i++) + { + $ai=$as; + $bi=$bs; + $end=$be+1; + + &comment("############### Calculate word $i"); + for ($j=$bs; $j<$end; $j++) + { + &xor($c2,$c2) if ($j == $bs); + if (($ai-1) < ($bi+1)) + { + $v=1; + $v=2 if ($i+1) == $tot; + } + else + { $v=0; } + if (!$v) + { + $na=$ai-1; + $nb=$bi+1; + } + else + { + $na=$as+($i < ($num-1)); + $nb=$bs+($i >= ($num-1)); + } + if ($ai == $bi) + { + &sqr_add_c($r,$a,$ai,$bi, + $c0,$c1,$c2,$v,$i,$na,$nb); + } + else + { + &sqr_add_c2($r,$a,$ai,$bi, + $c0,$c1,$c2,$v,$i,$na,$nb); + } + if ($v) + { + &comment("saved r[$i]"); + #&mov(&DWP($i*4,$r,"",0),$c0); + ($c0,$c1,$c2)=($c1,$c2,$c0); + last; + } + $ai--; + $bi++; + } + $as++ if ($i < ($num-1)); + $ae++ if ($i >= ($num-1)); + + $bs++ if ($i >= ($num-1)); + $be++ if ($i < ($num-1)); + } + &mov(&DWP($i*4,$r,"",0),$c0); + &pop("ebx"); + &pop("ebp"); + &pop("edi"); + &pop("esi"); + &ret(); + &function_end_B($name); + } diff --git a/libs/openssl/crypto/bn/asm/ia64-mont.pl b/libs/openssl/crypto/bn/asm/ia64-mont.pl new file mode 100644 index 00000000..e2586584 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/ia64-mont.pl @@ -0,0 +1,851 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# January 2010 +# +# "Teaser" Montgomery multiplication module for IA-64. There are +# several possibilities for improvement: +# +# - modulo-scheduling outer loop would eliminate quite a number of +# stalls after ldf8, xma and getf.sig outside inner loop and +# improve shorter key performance; +# - shorter vector support [with input vectors being fetched only +# once] should be added; +# - 2x unroll with help of n0[1] would make the code scalable on +# "wider" IA-64, "wider" than Itanium 2 that is, which is not of +# acute interest, because upcoming Tukwila's individual cores are +# reportedly based on Itanium 2 design; +# - dedicated squaring procedure(?); +# +# January 2010 +# +# Shorter vector support is implemented by zero-padding ap and np +# vectors up to 8 elements, or 512 bits. This means that 256-bit +# inputs will be processed only 2 times faster than 512-bit inputs, +# not 4 [as one would expect, because algorithm complexity is n^2]. +# The reason for padding is that inputs shorter than 512 bits won't +# be processed faster anyway, because minimal critical path of the +# core loop happens to match 512-bit timing. Either way, it resulted +# in >100% improvement of 512-bit RSA sign benchmark and 50% - of +# 1024-bit one [in comparison to original version of *this* module]. +# +# So far 'openssl speed rsa dsa' output on 900MHz Itanium 2 *with* +# this module is: +# sign verify sign/s verify/s +# rsa 512 bits 0.000290s 0.000024s 3452.8 42031.4 +# rsa 1024 bits 0.000793s 0.000058s 1261.7 17172.0 +# rsa 2048 bits 0.005908s 0.000148s 169.3 6754.0 +# rsa 4096 bits 0.033456s 0.000469s 29.9 2133.6 +# dsa 512 bits 0.000253s 0.000198s 3949.9 5057.0 +# dsa 1024 bits 0.000585s 0.000607s 1708.4 1647.4 +# dsa 2048 bits 0.001453s 0.001703s 688.1 587.4 +# +# ... and *without* (but still with ia64.S): +# +# rsa 512 bits 0.000670s 0.000041s 1491.8 24145.5 +# rsa 1024 bits 0.001988s 0.000080s 502.9 12499.3 +# rsa 2048 bits 0.008702s 0.000189s 114.9 5293.9 +# rsa 4096 bits 0.043860s 0.000533s 22.8 1875.9 +# dsa 512 bits 0.000441s 0.000427s 2265.3 2340.6 +# dsa 1024 bits 0.000823s 0.000867s 1215.6 1153.2 +# dsa 2048 bits 0.001894s 0.002179s 528.1 458.9 +# +# As it can be seen, RSA sign performance improves by 130-30%, +# hereafter less for longer keys, while verify - by 74-13%. +# DSA performance improves by 115-30%. + +if ($^O eq "hpux") { + $ADDP="addp4"; + for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); } +} else { $ADDP="add"; } + +$code=<<___; +.explicit +.text + +// int bn_mul_mont (BN_ULONG *rp,const BN_ULONG *ap, +// const BN_ULONG *bp,const BN_ULONG *np, +// const BN_ULONG *n0p,int num); +.align 64 +.global bn_mul_mont# +.proc bn_mul_mont# +bn_mul_mont: + .prologue + .body +{ .mmi; cmp4.le p6,p7=2,r37;; +(p6) cmp4.lt.unc p8,p9=8,r37 + mov ret0=r0 };; +{ .bbb; +(p9) br.cond.dptk.many bn_mul_mont_8 +(p8) br.cond.dpnt.many bn_mul_mont_general +(p7) br.ret.spnt.many b0 };; +.endp bn_mul_mont# + +prevfs=r2; prevpr=r3; prevlc=r10; prevsp=r11; + +rptr=r8; aptr=r9; bptr=r14; nptr=r15; +tptr=r16; // &tp[0] +tp_1=r17; // &tp[-1] +num=r18; len=r19; lc=r20; +topbit=r21; // carry bit from tmp[num] + +n0=f6; +m0=f7; +bi=f8; + +.align 64 +.local bn_mul_mont_general# +.proc bn_mul_mont_general# +bn_mul_mont_general: + .prologue +{ .mmi; .save ar.pfs,prevfs + alloc prevfs=ar.pfs,6,2,0,8 + $ADDP aptr=0,in1 + .save ar.lc,prevlc + mov prevlc=ar.lc } +{ .mmi; .vframe prevsp + mov prevsp=sp + $ADDP bptr=0,in2 + .save pr,prevpr + mov prevpr=pr };; + + .body + .rotf alo[6],nlo[4],ahi[8],nhi[6] + .rotr a[3],n[3],t[2] + +{ .mmi; ldf8 bi=[bptr],8 // (*bp++) + ldf8 alo[4]=[aptr],16 // ap[0] + $ADDP r30=8,in1 };; +{ .mmi; ldf8 alo[3]=[r30],16 // ap[1] + ldf8 alo[2]=[aptr],16 // ap[2] + $ADDP in4=0,in4 };; +{ .mmi; ldf8 alo[1]=[r30] // ap[3] + ldf8 n0=[in4] // n0 + $ADDP rptr=0,in0 } +{ .mmi; $ADDP nptr=0,in3 + mov r31=16 + zxt4 num=in5 };; +{ .mmi; ldf8 nlo[2]=[nptr],8 // np[0] + shladd len=num,3,r0 + shladd r31=num,3,r31 };; +{ .mmi; ldf8 nlo[1]=[nptr],8 // np[1] + add lc=-5,num + sub r31=sp,r31 };; +{ .mfb; and sp=-16,r31 // alloca + xmpy.hu ahi[2]=alo[4],bi // ap[0]*bp[0] + nop.b 0 } +{ .mfb; nop.m 0 + xmpy.lu alo[4]=alo[4],bi + brp.loop.imp .L1st_ctop,.L1st_cend-16 + };; +{ .mfi; nop.m 0 + xma.hu ahi[1]=alo[3],bi,ahi[2] // ap[1]*bp[0] + add tp_1=8,sp } +{ .mfi; nop.m 0 + xma.lu alo[3]=alo[3],bi,ahi[2] + mov pr.rot=0x20001f<<16 + // ------^----- (p40) at first (p23) + // ----------^^ p[16:20]=1 + };; +{ .mfi; nop.m 0 + xmpy.lu m0=alo[4],n0 // (ap[0]*bp[0])*n0 + mov ar.lc=lc } +{ .mfi; nop.m 0 + fcvt.fxu.s1 nhi[1]=f0 + mov ar.ec=8 };; + +.align 32 +.L1st_ctop: +.pred.rel "mutex",p40,p42 +{ .mfi; (p16) ldf8 alo[0]=[aptr],8 // *(aptr++) + (p18) xma.hu ahi[0]=alo[2],bi,ahi[1] + (p40) add n[2]=n[2],a[2] } // (p23) } +{ .mfi; (p18) ldf8 nlo[0]=[nptr],8 // *(nptr++)(p16) + (p18) xma.lu alo[2]=alo[2],bi,ahi[1] + (p42) add n[2]=n[2],a[2],1 };; // (p23) +{ .mfi; (p21) getf.sig a[0]=alo[5] + (p20) xma.hu nhi[0]=nlo[2],m0,nhi[1] + (p42) cmp.leu p41,p39=n[2],a[2] } // (p23) +{ .mfi; (p23) st8 [tp_1]=n[2],8 + (p20) xma.lu nlo[2]=nlo[2],m0,nhi[1] + (p40) cmp.ltu p41,p39=n[2],a[2] } // (p23) +{ .mmb; (p21) getf.sig n[0]=nlo[3] + (p16) nop.m 0 + br.ctop.sptk .L1st_ctop };; +.L1st_cend: + +{ .mmi; getf.sig a[0]=ahi[6] // (p24) + getf.sig n[0]=nhi[4] + add num=-1,num };; // num-- +{ .mmi; .pred.rel "mutex",p40,p42 +(p40) add n[0]=n[0],a[0] +(p42) add n[0]=n[0],a[0],1 + sub aptr=aptr,len };; // rewind +{ .mmi; .pred.rel "mutex",p40,p42 +(p40) cmp.ltu p41,p39=n[0],a[0] +(p42) cmp.leu p41,p39=n[0],a[0] + sub nptr=nptr,len };; +{ .mmi; .pred.rel "mutex",p39,p41 +(p39) add topbit=r0,r0 +(p41) add topbit=r0,r0,1 + nop.i 0 } +{ .mmi; st8 [tp_1]=n[0] + add tptr=16,sp + add tp_1=8,sp };; + +.Louter: +{ .mmi; ldf8 bi=[bptr],8 // (*bp++) + ldf8 ahi[3]=[tptr] // tp[0] + add r30=8,aptr };; +{ .mmi; ldf8 alo[4]=[aptr],16 // ap[0] + ldf8 alo[3]=[r30],16 // ap[1] + add r31=8,nptr };; +{ .mfb; ldf8 alo[2]=[aptr],16 // ap[2] + xma.hu ahi[2]=alo[4],bi,ahi[3] // ap[0]*bp[i]+tp[0] + brp.loop.imp .Linner_ctop,.Linner_cend-16 + } +{ .mfb; ldf8 alo[1]=[r30] // ap[3] + xma.lu alo[4]=alo[4],bi,ahi[3] + clrrrb.pr };; +{ .mfi; ldf8 nlo[2]=[nptr],16 // np[0] + xma.hu ahi[1]=alo[3],bi,ahi[2] // ap[1]*bp[i] + nop.i 0 } +{ .mfi; ldf8 nlo[1]=[r31] // np[1] + xma.lu alo[3]=alo[3],bi,ahi[2] + mov pr.rot=0x20101f<<16 + // ------^----- (p40) at first (p23) + // --------^--- (p30) at first (p22) + // ----------^^ p[16:20]=1 + };; +{ .mfi; st8 [tptr]=r0 // tp[0] is already accounted + xmpy.lu m0=alo[4],n0 // (ap[0]*bp[i]+tp[0])*n0 + mov ar.lc=lc } +{ .mfi; + fcvt.fxu.s1 nhi[1]=f0 + mov ar.ec=8 };; + +// This loop spins in 4*(n+7) ticks on Itanium 2 and should spin in +// 7*(n+7) ticks on Itanium (the one codenamed Merced). Factor of 7 +// in latter case accounts for two-tick pipeline stall, which means +// that its performance would be ~20% lower than optimal one. No +// attempt was made to address this, because original Itanium is +// hardly represented out in the wild... +.align 32 +.Linner_ctop: +.pred.rel "mutex",p40,p42 +.pred.rel "mutex",p30,p32 +{ .mfi; (p16) ldf8 alo[0]=[aptr],8 // *(aptr++) + (p18) xma.hu ahi[0]=alo[2],bi,ahi[1] + (p40) add n[2]=n[2],a[2] } // (p23) +{ .mfi; (p16) nop.m 0 + (p18) xma.lu alo[2]=alo[2],bi,ahi[1] + (p42) add n[2]=n[2],a[2],1 };; // (p23) +{ .mfi; (p21) getf.sig a[0]=alo[5] + (p16) nop.f 0 + (p40) cmp.ltu p41,p39=n[2],a[2] } // (p23) +{ .mfi; (p21) ld8 t[0]=[tptr],8 + (p16) nop.f 0 + (p42) cmp.leu p41,p39=n[2],a[2] };; // (p23) +{ .mfi; (p18) ldf8 nlo[0]=[nptr],8 // *(nptr++) + (p20) xma.hu nhi[0]=nlo[2],m0,nhi[1] + (p30) add a[1]=a[1],t[1] } // (p22) +{ .mfi; (p16) nop.m 0 + (p20) xma.lu nlo[2]=nlo[2],m0,nhi[1] + (p32) add a[1]=a[1],t[1],1 };; // (p22) +{ .mmi; (p21) getf.sig n[0]=nlo[3] + (p16) nop.m 0 + (p30) cmp.ltu p31,p29=a[1],t[1] } // (p22) +{ .mmb; (p23) st8 [tp_1]=n[2],8 + (p32) cmp.leu p31,p29=a[1],t[1] // (p22) + br.ctop.sptk .Linner_ctop };; +.Linner_cend: + +{ .mmi; getf.sig a[0]=ahi[6] // (p24) + getf.sig n[0]=nhi[4] + nop.i 0 };; + +{ .mmi; .pred.rel "mutex",p31,p33 +(p31) add a[0]=a[0],topbit +(p33) add a[0]=a[0],topbit,1 + mov topbit=r0 };; +{ .mfi; .pred.rel "mutex",p31,p33 +(p31) cmp.ltu p32,p30=a[0],topbit +(p33) cmp.leu p32,p30=a[0],topbit + } +{ .mfi; .pred.rel "mutex",p40,p42 +(p40) add n[0]=n[0],a[0] +(p42) add n[0]=n[0],a[0],1 + };; +{ .mmi; .pred.rel "mutex",p44,p46 +(p40) cmp.ltu p41,p39=n[0],a[0] +(p42) cmp.leu p41,p39=n[0],a[0] +(p32) add topbit=r0,r0,1 } + +{ .mmi; st8 [tp_1]=n[0],8 + cmp4.ne p6,p0=1,num + sub aptr=aptr,len };; // rewind +{ .mmi; sub nptr=nptr,len +(p41) add topbit=r0,r0,1 + add tptr=16,sp } +{ .mmb; add tp_1=8,sp + add num=-1,num // num-- +(p6) br.cond.sptk.many .Louter };; + +{ .mbb; add lc=4,lc + brp.loop.imp .Lsub_ctop,.Lsub_cend-16 + clrrrb.pr };; +{ .mii; nop.m 0 + mov pr.rot=0x10001<<16 + // ------^---- (p33) at first (p17) + mov ar.lc=lc } +{ .mii; nop.m 0 + mov ar.ec=3 + nop.i 0 };; + +.Lsub_ctop: +.pred.rel "mutex",p33,p35 +{ .mfi; (p16) ld8 t[0]=[tptr],8 // t=*(tp++) + (p16) nop.f 0 + (p33) sub n[1]=t[1],n[1] } // (p17) +{ .mfi; (p16) ld8 n[0]=[nptr],8 // n=*(np++) + (p16) nop.f 0 + (p35) sub n[1]=t[1],n[1],1 };; // (p17) +{ .mib; (p18) st8 [rptr]=n[2],8 // *(rp++)=r + (p33) cmp.gtu p34,p32=n[1],t[1] // (p17) + (p18) nop.b 0 } +{ .mib; (p18) nop.m 0 + (p35) cmp.geu p34,p32=n[1],t[1] // (p17) + br.ctop.sptk .Lsub_ctop };; +.Lsub_cend: + +{ .mmb; .pred.rel "mutex",p34,p36 +(p34) sub topbit=topbit,r0 // (p19) +(p36) sub topbit=topbit,r0,1 + brp.loop.imp .Lcopy_ctop,.Lcopy_cend-16 + } +{ .mmb; sub rptr=rptr,len // rewind + sub tptr=tptr,len + clrrrb.pr };; +{ .mmi; and aptr=tptr,topbit + andcm bptr=rptr,topbit + mov pr.rot=1<<16 };; +{ .mii; or nptr=aptr,bptr + mov ar.lc=lc + mov ar.ec=3 };; + +.Lcopy_ctop: +{ .mmb; (p16) ld8 n[0]=[nptr],8 + (p18) st8 [tptr]=r0,8 + (p16) nop.b 0 } +{ .mmb; (p16) nop.m 0 + (p18) st8 [rptr]=n[2],8 + br.ctop.sptk .Lcopy_ctop };; +.Lcopy_cend: + +{ .mmi; mov ret0=1 // signal "handled" + rum 1<<5 // clear um.mfh + mov ar.lc=prevlc } +{ .mib; .restore sp + mov sp=prevsp + mov pr=prevpr,0x1ffff + br.ret.sptk.many b0 };; +.endp bn_mul_mont_general# + +a1=r16; a2=r17; a3=r18; a4=r19; a5=r20; a6=r21; a7=r22; a8=r23; +n1=r24; n2=r25; n3=r26; n4=r27; n5=r28; n6=r29; n7=r30; n8=r31; +t0=r15; + +ai0=f8; ai1=f9; ai2=f10; ai3=f11; ai4=f12; ai5=f13; ai6=f14; ai7=f15; +ni0=f16; ni1=f17; ni2=f18; ni3=f19; ni4=f20; ni5=f21; ni6=f22; ni7=f23; + +.align 64 +.skip 48 // aligns loop body +.local bn_mul_mont_8# +.proc bn_mul_mont_8# +bn_mul_mont_8: + .prologue +{ .mmi; .save ar.pfs,prevfs + alloc prevfs=ar.pfs,6,2,0,8 + .vframe prevsp + mov prevsp=sp + .save ar.lc,prevlc + mov prevlc=ar.lc } +{ .mmi; add r17=-6*16,sp + add sp=-7*16,sp + .save pr,prevpr + mov prevpr=pr };; + +{ .mmi; .save.gf 0,0x10 + stf.spill [sp]=f16,-16 + .save.gf 0,0x20 + stf.spill [r17]=f17,32 + add r16=-5*16,prevsp};; +{ .mmi; .save.gf 0,0x40 + stf.spill [r16]=f18,32 + .save.gf 0,0x80 + stf.spill [r17]=f19,32 + $ADDP aptr=0,in1 };; +{ .mmi; .save.gf 0,0x100 + stf.spill [r16]=f20,32 + .save.gf 0,0x200 + stf.spill [r17]=f21,32 + $ADDP r29=8,in1 };; +{ .mmi; .save.gf 0,0x400 + stf.spill [r16]=f22 + .save.gf 0,0x800 + stf.spill [r17]=f23 + $ADDP rptr=0,in0 };; + + .body + .rotf bj[8],mj[2],tf[2],alo[10],ahi[10],nlo[10],nhi[10] + .rotr t[8] + +// load input vectors padding them to 8 elements +{ .mmi; ldf8 ai0=[aptr],16 // ap[0] + ldf8 ai1=[r29],16 // ap[1] + $ADDP bptr=0,in2 } +{ .mmi; $ADDP r30=8,in2 + $ADDP nptr=0,in3 + $ADDP r31=8,in3 };; +{ .mmi; ldf8 bj[7]=[bptr],16 // bp[0] + ldf8 bj[6]=[r30],16 // bp[1] + cmp4.le p4,p5=3,in5 } +{ .mmi; ldf8 ni0=[nptr],16 // np[0] + ldf8 ni1=[r31],16 // np[1] + cmp4.le p6,p7=4,in5 };; + +{ .mfi; (p4)ldf8 ai2=[aptr],16 // ap[2] + (p5)fcvt.fxu ai2=f0 + cmp4.le p8,p9=5,in5 } +{ .mfi; (p6)ldf8 ai3=[r29],16 // ap[3] + (p7)fcvt.fxu ai3=f0 + cmp4.le p10,p11=6,in5 } +{ .mfi; (p4)ldf8 bj[5]=[bptr],16 // bp[2] + (p5)fcvt.fxu bj[5]=f0 + cmp4.le p12,p13=7,in5 } +{ .mfi; (p6)ldf8 bj[4]=[r30],16 // bp[3] + (p7)fcvt.fxu bj[4]=f0 + cmp4.le p14,p15=8,in5 } +{ .mfi; (p4)ldf8 ni2=[nptr],16 // np[2] + (p5)fcvt.fxu ni2=f0 + addp4 r28=-1,in5 } +{ .mfi; (p6)ldf8 ni3=[r31],16 // np[3] + (p7)fcvt.fxu ni3=f0 + $ADDP in4=0,in4 };; + +{ .mfi; ldf8 n0=[in4] + fcvt.fxu tf[1]=f0 + nop.i 0 } + +{ .mfi; (p8)ldf8 ai4=[aptr],16 // ap[4] + (p9)fcvt.fxu ai4=f0 + mov t[0]=r0 } +{ .mfi; (p10)ldf8 ai5=[r29],16 // ap[5] + (p11)fcvt.fxu ai5=f0 + mov t[1]=r0 } +{ .mfi; (p8)ldf8 bj[3]=[bptr],16 // bp[4] + (p9)fcvt.fxu bj[3]=f0 + mov t[2]=r0 } +{ .mfi; (p10)ldf8 bj[2]=[r30],16 // bp[5] + (p11)fcvt.fxu bj[2]=f0 + mov t[3]=r0 } +{ .mfi; (p8)ldf8 ni4=[nptr],16 // np[4] + (p9)fcvt.fxu ni4=f0 + mov t[4]=r0 } +{ .mfi; (p10)ldf8 ni5=[r31],16 // np[5] + (p11)fcvt.fxu ni5=f0 + mov t[5]=r0 };; + +{ .mfi; (p12)ldf8 ai6=[aptr],16 // ap[6] + (p13)fcvt.fxu ai6=f0 + mov t[6]=r0 } +{ .mfi; (p14)ldf8 ai7=[r29],16 // ap[7] + (p15)fcvt.fxu ai7=f0 + mov t[7]=r0 } +{ .mfi; (p12)ldf8 bj[1]=[bptr],16 // bp[6] + (p13)fcvt.fxu bj[1]=f0 + mov ar.lc=r28 } +{ .mfi; (p14)ldf8 bj[0]=[r30],16 // bp[7] + (p15)fcvt.fxu bj[0]=f0 + mov ar.ec=1 } +{ .mfi; (p12)ldf8 ni6=[nptr],16 // np[6] + (p13)fcvt.fxu ni6=f0 + mov pr.rot=1<<16 } +{ .mfb; (p14)ldf8 ni7=[r31],16 // np[7] + (p15)fcvt.fxu ni7=f0 + brp.loop.imp .Louter_8_ctop,.Louter_8_cend-16 + };; + +// The loop is scheduled for 32*n ticks on Itanium 2. Actual attempt +// to measure with help of Interval Time Counter indicated that the +// factor is a tad higher: 33 or 34, if not 35. Exact measurement and +// addressing the issue is problematic, because I don't have access +// to platform-specific instruction-level profiler. On Itanium it +// should run in 56*n ticks, because of higher xma latency... +.Louter_8_ctop: + .pred.rel "mutex",p40,p42 + .pred.rel "mutex",p48,p50 +{ .mfi; (p16) nop.m 0 // 0: + (p16) xma.hu ahi[0]=ai0,bj[7],tf[1] // ap[0]*b[i]+t[0] + (p40) add a3=a3,n3 } // (p17) a3+=n3 +{ .mfi; (p42) add a3=a3,n3,1 + (p16) xma.lu alo[0]=ai0,bj[7],tf[1] + (p16) nop.i 0 };; +{ .mii; (p17) getf.sig a7=alo[8] // 1: + (p48) add t[6]=t[6],a3 // (p17) t[6]+=a3 + (p50) add t[6]=t[6],a3,1 };; +{ .mfi; (p17) getf.sig a8=ahi[8] // 2: + (p17) xma.hu nhi[7]=ni6,mj[1],nhi[6] // np[6]*m0 + (p40) cmp.ltu p43,p41=a3,n3 } +{ .mfi; (p42) cmp.leu p43,p41=a3,n3 + (p17) xma.lu nlo[7]=ni6,mj[1],nhi[6] + (p16) nop.i 0 };; +{ .mii; (p17) getf.sig n5=nlo[6] // 3: + (p48) cmp.ltu p51,p49=t[6],a3 + (p50) cmp.leu p51,p49=t[6],a3 };; + .pred.rel "mutex",p41,p43 + .pred.rel "mutex",p49,p51 +{ .mfi; (p16) nop.m 0 // 4: + (p16) xma.hu ahi[1]=ai1,bj[7],ahi[0] // ap[1]*b[i] + (p41) add a4=a4,n4 } // (p17) a4+=n4 +{ .mfi; (p43) add a4=a4,n4,1 + (p16) xma.lu alo[1]=ai1,bj[7],ahi[0] + (p16) nop.i 0 };; +{ .mfi; (p49) add t[5]=t[5],a4 // 5: (p17) t[5]+=a4 + (p16) xmpy.lu mj[0]=alo[0],n0 // (ap[0]*b[i]+t[0])*n0 + (p51) add t[5]=t[5],a4,1 };; +{ .mfi; (p16) nop.m 0 // 6: + (p17) xma.hu nhi[8]=ni7,mj[1],nhi[7] // np[7]*m0 + (p41) cmp.ltu p42,p40=a4,n4 } +{ .mfi; (p43) cmp.leu p42,p40=a4,n4 + (p17) xma.lu nlo[8]=ni7,mj[1],nhi[7] + (p16) nop.i 0 };; +{ .mii; (p17) getf.sig n6=nlo[7] // 7: + (p49) cmp.ltu p50,p48=t[5],a4 + (p51) cmp.leu p50,p48=t[5],a4 };; + .pred.rel "mutex",p40,p42 + .pred.rel "mutex",p48,p50 +{ .mfi; (p16) nop.m 0 // 8: + (p16) xma.hu ahi[2]=ai2,bj[7],ahi[1] // ap[2]*b[i] + (p40) add a5=a5,n5 } // (p17) a5+=n5 +{ .mfi; (p42) add a5=a5,n5,1 + (p16) xma.lu alo[2]=ai2,bj[7],ahi[1] + (p16) nop.i 0 };; +{ .mii; (p16) getf.sig a1=alo[1] // 9: + (p48) add t[4]=t[4],a5 // p(17) t[4]+=a5 + (p50) add t[4]=t[4],a5,1 };; +{ .mfi; (p16) nop.m 0 // 10: + (p16) xma.hu nhi[0]=ni0,mj[0],alo[0] // np[0]*m0 + (p40) cmp.ltu p43,p41=a5,n5 } +{ .mfi; (p42) cmp.leu p43,p41=a5,n5 + (p16) xma.lu nlo[0]=ni0,mj[0],alo[0] + (p16) nop.i 0 };; +{ .mii; (p17) getf.sig n7=nlo[8] // 11: + (p48) cmp.ltu p51,p49=t[4],a5 + (p50) cmp.leu p51,p49=t[4],a5 };; + .pred.rel "mutex",p41,p43 + .pred.rel "mutex",p49,p51 +{ .mfi; (p17) getf.sig n8=nhi[8] // 12: + (p16) xma.hu ahi[3]=ai3,bj[7],ahi[2] // ap[3]*b[i] + (p41) add a6=a6,n6 } // (p17) a6+=n6 +{ .mfi; (p43) add a6=a6,n6,1 + (p16) xma.lu alo[3]=ai3,bj[7],ahi[2] + (p16) nop.i 0 };; +{ .mii; (p16) getf.sig a2=alo[2] // 13: + (p49) add t[3]=t[3],a6 // (p17) t[3]+=a6 + (p51) add t[3]=t[3],a6,1 };; +{ .mfi; (p16) nop.m 0 // 14: + (p16) xma.hu nhi[1]=ni1,mj[0],nhi[0] // np[1]*m0 + (p41) cmp.ltu p42,p40=a6,n6 } +{ .mfi; (p43) cmp.leu p42,p40=a6,n6 + (p16) xma.lu nlo[1]=ni1,mj[0],nhi[0] + (p16) nop.i 0 };; +{ .mii; (p16) nop.m 0 // 15: + (p49) cmp.ltu p50,p48=t[3],a6 + (p51) cmp.leu p50,p48=t[3],a6 };; + .pred.rel "mutex",p40,p42 + .pred.rel "mutex",p48,p50 +{ .mfi; (p16) nop.m 0 // 16: + (p16) xma.hu ahi[4]=ai4,bj[7],ahi[3] // ap[4]*b[i] + (p40) add a7=a7,n7 } // (p17) a7+=n7 +{ .mfi; (p42) add a7=a7,n7,1 + (p16) xma.lu alo[4]=ai4,bj[7],ahi[3] + (p16) nop.i 0 };; +{ .mii; (p16) getf.sig a3=alo[3] // 17: + (p48) add t[2]=t[2],a7 // (p17) t[2]+=a7 + (p50) add t[2]=t[2],a7,1 };; +{ .mfi; (p16) nop.m 0 // 18: + (p16) xma.hu nhi[2]=ni2,mj[0],nhi[1] // np[2]*m0 + (p40) cmp.ltu p43,p41=a7,n7 } +{ .mfi; (p42) cmp.leu p43,p41=a7,n7 + (p16) xma.lu nlo[2]=ni2,mj[0],nhi[1] + (p16) nop.i 0 };; +{ .mii; (p16) getf.sig n1=nlo[1] // 19: + (p48) cmp.ltu p51,p49=t[2],a7 + (p50) cmp.leu p51,p49=t[2],a7 };; + .pred.rel "mutex",p41,p43 + .pred.rel "mutex",p49,p51 +{ .mfi; (p16) nop.m 0 // 20: + (p16) xma.hu ahi[5]=ai5,bj[7],ahi[4] // ap[5]*b[i] + (p41) add a8=a8,n8 } // (p17) a8+=n8 +{ .mfi; (p43) add a8=a8,n8,1 + (p16) xma.lu alo[5]=ai5,bj[7],ahi[4] + (p16) nop.i 0 };; +{ .mii; (p16) getf.sig a4=alo[4] // 21: + (p49) add t[1]=t[1],a8 // (p17) t[1]+=a8 + (p51) add t[1]=t[1],a8,1 };; +{ .mfi; (p16) nop.m 0 // 22: + (p16) xma.hu nhi[3]=ni3,mj[0],nhi[2] // np[3]*m0 + (p41) cmp.ltu p42,p40=a8,n8 } +{ .mfi; (p43) cmp.leu p42,p40=a8,n8 + (p16) xma.lu nlo[3]=ni3,mj[0],nhi[2] + (p16) nop.i 0 };; +{ .mii; (p16) getf.sig n2=nlo[2] // 23: + (p49) cmp.ltu p50,p48=t[1],a8 + (p51) cmp.leu p50,p48=t[1],a8 };; +{ .mfi; (p16) nop.m 0 // 24: + (p16) xma.hu ahi[6]=ai6,bj[7],ahi[5] // ap[6]*b[i] + (p16) add a1=a1,n1 } // (p16) a1+=n1 +{ .mfi; (p16) nop.m 0 + (p16) xma.lu alo[6]=ai6,bj[7],ahi[5] + (p17) mov t[0]=r0 };; +{ .mii; (p16) getf.sig a5=alo[5] // 25: + (p16) add t0=t[7],a1 // (p16) t[7]+=a1 + (p42) add t[0]=t[0],r0,1 };; +{ .mfi; (p16) setf.sig tf[0]=t0 // 26: + (p16) xma.hu nhi[4]=ni4,mj[0],nhi[3] // np[4]*m0 + (p50) add t[0]=t[0],r0,1 } +{ .mfi; (p16) cmp.ltu.unc p42,p40=a1,n1 + (p16) xma.lu nlo[4]=ni4,mj[0],nhi[3] + (p16) nop.i 0 };; +{ .mii; (p16) getf.sig n3=nlo[3] // 27: + (p16) cmp.ltu.unc p50,p48=t0,a1 + (p16) nop.i 0 };; + .pred.rel "mutex",p40,p42 + .pred.rel "mutex",p48,p50 +{ .mfi; (p16) nop.m 0 // 28: + (p16) xma.hu ahi[7]=ai7,bj[7],ahi[6] // ap[7]*b[i] + (p40) add a2=a2,n2 } // (p16) a2+=n2 +{ .mfi; (p42) add a2=a2,n2,1 + (p16) xma.lu alo[7]=ai7,bj[7],ahi[6] + (p16) nop.i 0 };; +{ .mii; (p16) getf.sig a6=alo[6] // 29: + (p48) add t[6]=t[6],a2 // (p16) t[6]+=a2 + (p50) add t[6]=t[6],a2,1 };; +{ .mfi; (p16) nop.m 0 // 30: + (p16) xma.hu nhi[5]=ni5,mj[0],nhi[4] // np[5]*m0 + (p40) cmp.ltu p41,p39=a2,n2 } +{ .mfi; (p42) cmp.leu p41,p39=a2,n2 + (p16) xma.lu nlo[5]=ni5,mj[0],nhi[4] + (p16) nop.i 0 };; +{ .mfi; (p16) getf.sig n4=nlo[4] // 31: + (p16) nop.f 0 + (p48) cmp.ltu p49,p47=t[6],a2 } +{ .mfb; (p50) cmp.leu p49,p47=t[6],a2 + (p16) nop.f 0 + br.ctop.sptk.many .Louter_8_ctop };; +.Louter_8_cend: + +// above loop has to execute one more time, without (p16), which is +// replaced with merged move of np[8] to GPR bank + .pred.rel "mutex",p40,p42 + .pred.rel "mutex",p48,p50 +{ .mmi; (p0) getf.sig n1=ni0 // 0: + (p40) add a3=a3,n3 // (p17) a3+=n3 + (p42) add a3=a3,n3,1 };; +{ .mii; (p17) getf.sig a7=alo[8] // 1: + (p48) add t[6]=t[6],a3 // (p17) t[6]+=a3 + (p50) add t[6]=t[6],a3,1 };; +{ .mfi; (p17) getf.sig a8=ahi[8] // 2: + (p17) xma.hu nhi[7]=ni6,mj[1],nhi[6] // np[6]*m0 + (p40) cmp.ltu p43,p41=a3,n3 } +{ .mfi; (p42) cmp.leu p43,p41=a3,n3 + (p17) xma.lu nlo[7]=ni6,mj[1],nhi[6] + (p0) nop.i 0 };; +{ .mii; (p17) getf.sig n5=nlo[6] // 3: + (p48) cmp.ltu p51,p49=t[6],a3 + (p50) cmp.leu p51,p49=t[6],a3 };; + .pred.rel "mutex",p41,p43 + .pred.rel "mutex",p49,p51 +{ .mmi; (p0) getf.sig n2=ni1 // 4: + (p41) add a4=a4,n4 // (p17) a4+=n4 + (p43) add a4=a4,n4,1 };; +{ .mfi; (p49) add t[5]=t[5],a4 // 5: (p17) t[5]+=a4 + (p0) nop.f 0 + (p51) add t[5]=t[5],a4,1 };; +{ .mfi; (p0) getf.sig n3=ni2 // 6: + (p17) xma.hu nhi[8]=ni7,mj[1],nhi[7] // np[7]*m0 + (p41) cmp.ltu p42,p40=a4,n4 } +{ .mfi; (p43) cmp.leu p42,p40=a4,n4 + (p17) xma.lu nlo[8]=ni7,mj[1],nhi[7] + (p0) nop.i 0 };; +{ .mii; (p17) getf.sig n6=nlo[7] // 7: + (p49) cmp.ltu p50,p48=t[5],a4 + (p51) cmp.leu p50,p48=t[5],a4 };; + .pred.rel "mutex",p40,p42 + .pred.rel "mutex",p48,p50 +{ .mii; (p0) getf.sig n4=ni3 // 8: + (p40) add a5=a5,n5 // (p17) a5+=n5 + (p42) add a5=a5,n5,1 };; +{ .mii; (p0) nop.m 0 // 9: + (p48) add t[4]=t[4],a5 // p(17) t[4]+=a5 + (p50) add t[4]=t[4],a5,1 };; +{ .mii; (p0) nop.m 0 // 10: + (p40) cmp.ltu p43,p41=a5,n5 + (p42) cmp.leu p43,p41=a5,n5 };; +{ .mii; (p17) getf.sig n7=nlo[8] // 11: + (p48) cmp.ltu p51,p49=t[4],a5 + (p50) cmp.leu p51,p49=t[4],a5 };; + .pred.rel "mutex",p41,p43 + .pred.rel "mutex",p49,p51 +{ .mii; (p17) getf.sig n8=nhi[8] // 12: + (p41) add a6=a6,n6 // (p17) a6+=n6 + (p43) add a6=a6,n6,1 };; +{ .mii; (p0) getf.sig n5=ni4 // 13: + (p49) add t[3]=t[3],a6 // (p17) t[3]+=a6 + (p51) add t[3]=t[3],a6,1 };; +{ .mii; (p0) nop.m 0 // 14: + (p41) cmp.ltu p42,p40=a6,n6 + (p43) cmp.leu p42,p40=a6,n6 };; +{ .mii; (p0) getf.sig n6=ni5 // 15: + (p49) cmp.ltu p50,p48=t[3],a6 + (p51) cmp.leu p50,p48=t[3],a6 };; + .pred.rel "mutex",p40,p42 + .pred.rel "mutex",p48,p50 +{ .mii; (p0) nop.m 0 // 16: + (p40) add a7=a7,n7 // (p17) a7+=n7 + (p42) add a7=a7,n7,1 };; +{ .mii; (p0) nop.m 0 // 17: + (p48) add t[2]=t[2],a7 // (p17) t[2]+=a7 + (p50) add t[2]=t[2],a7,1 };; +{ .mii; (p0) nop.m 0 // 18: + (p40) cmp.ltu p43,p41=a7,n7 + (p42) cmp.leu p43,p41=a7,n7 };; +{ .mii; (p0) getf.sig n7=ni6 // 19: + (p48) cmp.ltu p51,p49=t[2],a7 + (p50) cmp.leu p51,p49=t[2],a7 };; + .pred.rel "mutex",p41,p43 + .pred.rel "mutex",p49,p51 +{ .mii; (p0) nop.m 0 // 20: + (p41) add a8=a8,n8 // (p17) a8+=n8 + (p43) add a8=a8,n8,1 };; +{ .mmi; (p0) nop.m 0 // 21: + (p49) add t[1]=t[1],a8 // (p17) t[1]+=a8 + (p51) add t[1]=t[1],a8,1 } +{ .mmi; (p17) mov t[0]=r0 + (p41) cmp.ltu p42,p40=a8,n8 + (p43) cmp.leu p42,p40=a8,n8 };; +{ .mmi; (p0) getf.sig n8=ni7 // 22: + (p49) cmp.ltu p50,p48=t[1],a8 + (p51) cmp.leu p50,p48=t[1],a8 } +{ .mmi; (p42) add t[0]=t[0],r0,1 + (p0) add r16=-7*16,prevsp + (p0) add r17=-6*16,prevsp };; + +// subtract np[8] from carrybit|tmp[8] +// carrybit|tmp[8] layout upon exit from above loop is: +// t[0]|t[1]|t[2]|t[3]|t[4]|t[5]|t[6]|t[7]|t0 (least significant) +{ .mmi; (p50)add t[0]=t[0],r0,1 + add r18=-5*16,prevsp + sub n1=t0,n1 };; +{ .mmi; cmp.gtu p34,p32=n1,t0;; + .pred.rel "mutex",p32,p34 + (p32)sub n2=t[7],n2 + (p34)sub n2=t[7],n2,1 };; +{ .mii; (p32)cmp.gtu p35,p33=n2,t[7] + (p34)cmp.geu p35,p33=n2,t[7];; + .pred.rel "mutex",p33,p35 + (p33)sub n3=t[6],n3 } +{ .mmi; (p35)sub n3=t[6],n3,1;; + (p33)cmp.gtu p34,p32=n3,t[6] + (p35)cmp.geu p34,p32=n3,t[6] };; + .pred.rel "mutex",p32,p34 +{ .mii; (p32)sub n4=t[5],n4 + (p34)sub n4=t[5],n4,1;; + (p32)cmp.gtu p35,p33=n4,t[5] } +{ .mmi; (p34)cmp.geu p35,p33=n4,t[5];; + .pred.rel "mutex",p33,p35 + (p33)sub n5=t[4],n5 + (p35)sub n5=t[4],n5,1 };; +{ .mii; (p33)cmp.gtu p34,p32=n5,t[4] + (p35)cmp.geu p34,p32=n5,t[4];; + .pred.rel "mutex",p32,p34 + (p32)sub n6=t[3],n6 } +{ .mmi; (p34)sub n6=t[3],n6,1;; + (p32)cmp.gtu p35,p33=n6,t[3] + (p34)cmp.geu p35,p33=n6,t[3] };; + .pred.rel "mutex",p33,p35 +{ .mii; (p33)sub n7=t[2],n7 + (p35)sub n7=t[2],n7,1;; + (p33)cmp.gtu p34,p32=n7,t[2] } +{ .mmi; (p35)cmp.geu p34,p32=n7,t[2];; + .pred.rel "mutex",p32,p34 + (p32)sub n8=t[1],n8 + (p34)sub n8=t[1],n8,1 };; +{ .mii; (p32)cmp.gtu p35,p33=n8,t[1] + (p34)cmp.geu p35,p33=n8,t[1];; + .pred.rel "mutex",p33,p35 + (p33)sub a8=t[0],r0 } +{ .mmi; (p35)sub a8=t[0],r0,1;; + (p33)cmp.gtu p34,p32=a8,t[0] + (p35)cmp.geu p34,p32=a8,t[0] };; + +// save the result, either tmp[num] or tmp[num]-np[num] + .pred.rel "mutex",p32,p34 +{ .mmi; (p32)st8 [rptr]=n1,8 + (p34)st8 [rptr]=t0,8 + add r19=-4*16,prevsp};; +{ .mmb; (p32)st8 [rptr]=n2,8 + (p34)st8 [rptr]=t[7],8 + (p5)br.cond.dpnt.few .Ldone };; +{ .mmb; (p32)st8 [rptr]=n3,8 + (p34)st8 [rptr]=t[6],8 + (p7)br.cond.dpnt.few .Ldone };; +{ .mmb; (p32)st8 [rptr]=n4,8 + (p34)st8 [rptr]=t[5],8 + (p9)br.cond.dpnt.few .Ldone };; +{ .mmb; (p32)st8 [rptr]=n5,8 + (p34)st8 [rptr]=t[4],8 + (p11)br.cond.dpnt.few .Ldone };; +{ .mmb; (p32)st8 [rptr]=n6,8 + (p34)st8 [rptr]=t[3],8 + (p13)br.cond.dpnt.few .Ldone };; +{ .mmb; (p32)st8 [rptr]=n7,8 + (p34)st8 [rptr]=t[2],8 + (p15)br.cond.dpnt.few .Ldone };; +{ .mmb; (p32)st8 [rptr]=n8,8 + (p34)st8 [rptr]=t[1],8 + nop.b 0 };; +.Ldone: // epilogue +{ .mmi; ldf.fill f16=[r16],64 + ldf.fill f17=[r17],64 + nop.i 0 } +{ .mmi; ldf.fill f18=[r18],64 + ldf.fill f19=[r19],64 + mov pr=prevpr,0x1ffff };; +{ .mmi; ldf.fill f20=[r16] + ldf.fill f21=[r17] + mov ar.lc=prevlc } +{ .mmi; ldf.fill f22=[r18] + ldf.fill f23=[r19] + mov ret0=1 } // signal "handled" +{ .mib; rum 1<<5 + .restore sp + mov sp=prevsp + br.ret.sptk.many b0 };; +.endp bn_mul_mont_8# + +.type copyright#,\@object +copyright: +stringz "Montgomery multiplication for IA-64, CRYPTOGAMS by " +___ + +$output=shift and open STDOUT,">$output"; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/ia64.S b/libs/openssl/crypto/bn/asm/ia64.S new file mode 100644 index 00000000..a9a42abf --- /dev/null +++ b/libs/openssl/crypto/bn/asm/ia64.S @@ -0,0 +1,1555 @@ +.explicit +.text +.ident "ia64.S, Version 2.1" +.ident "IA-64 ISA artwork by Andy Polyakov " + +// +// ==================================================================== +// Written by Andy Polyakov for the OpenSSL +// project. +// +// Rights for redistribution and usage in source and binary forms are +// granted according to the OpenSSL license. Warranty of any kind is +// disclaimed. +// ==================================================================== +// +// Version 2.x is Itanium2 re-tune. Few words about how Itanum2 is +// different from Itanium to this module viewpoint. Most notably, is it +// "wider" than Itanium? Can you experience loop scalability as +// discussed in commentary sections? Not really:-( Itanium2 has 6 +// integer ALU ports, i.e. it's 2 ports wider, but it's not enough to +// spin twice as fast, as I need 8 IALU ports. Amount of floating point +// ports is the same, i.e. 2, while I need 4. In other words, to this +// module Itanium2 remains effectively as "wide" as Itanium. Yet it's +// essentially different in respect to this module, and a re-tune was +// required. Well, because some intruction latencies has changed. Most +// noticeably those intensively used: +// +// Itanium Itanium2 +// ldf8 9 6 L2 hit +// ld8 2 1 L1 hit +// getf 2 5 +// xma[->getf] 7[+1] 4[+0] +// add[->st8] 1[+1] 1[+0] +// +// What does it mean? You might ratiocinate that the original code +// should run just faster... Because sum of latencies is smaller... +// Wrong! Note that getf latency increased. This means that if a loop is +// scheduled for lower latency (as they were), then it will suffer from +// stall condition and the code will therefore turn anti-scalable, e.g. +// original bn_mul_words spun at 5*n or 2.5 times slower than expected +// on Itanium2! What to do? Reschedule loops for Itanium2? But then +// Itanium would exhibit anti-scalability. So I've chosen to reschedule +// for worst latency for every instruction aiming for best *all-round* +// performance. + +// Q. How much faster does it get? +// A. Here is the output from 'openssl speed rsa dsa' for vanilla +// 0.9.6a compiled with gcc version 2.96 20000731 (Red Hat +// Linux 7.1 2.96-81): +// +// sign verify sign/s verify/s +// rsa 512 bits 0.0036s 0.0003s 275.3 2999.2 +// rsa 1024 bits 0.0203s 0.0011s 49.3 894.1 +// rsa 2048 bits 0.1331s 0.0040s 7.5 250.9 +// rsa 4096 bits 0.9270s 0.0147s 1.1 68.1 +// sign verify sign/s verify/s +// dsa 512 bits 0.0035s 0.0043s 288.3 234.8 +// dsa 1024 bits 0.0111s 0.0135s 90.0 74.2 +// +// And here is similar output but for this assembler +// implementation:-) +// +// sign verify sign/s verify/s +// rsa 512 bits 0.0021s 0.0001s 549.4 9638.5 +// rsa 1024 bits 0.0055s 0.0002s 183.8 4481.1 +// rsa 2048 bits 0.0244s 0.0006s 41.4 1726.3 +// rsa 4096 bits 0.1295s 0.0018s 7.7 561.5 +// sign verify sign/s verify/s +// dsa 512 bits 0.0012s 0.0013s 891.9 756.6 +// dsa 1024 bits 0.0023s 0.0028s 440.4 376.2 +// +// Yes, you may argue that it's not fair comparison as it's +// possible to craft the C implementation with BN_UMULT_HIGH +// inline assembler macro. But of course! Here is the output +// with the macro: +// +// sign verify sign/s verify/s +// rsa 512 bits 0.0020s 0.0002s 495.0 6561.0 +// rsa 1024 bits 0.0086s 0.0004s 116.2 2235.7 +// rsa 2048 bits 0.0519s 0.0015s 19.3 667.3 +// rsa 4096 bits 0.3464s 0.0053s 2.9 187.7 +// sign verify sign/s verify/s +// dsa 512 bits 0.0016s 0.0020s 613.1 510.5 +// dsa 1024 bits 0.0045s 0.0054s 221.0 183.9 +// +// My code is still way faster, huh:-) And I believe that even +// higher performance can be achieved. Note that as keys get +// longer, performance gain is larger. Why? According to the +// profiler there is another player in the field, namely +// BN_from_montgomery consuming larger and larger portion of CPU +// time as keysize decreases. I therefore consider putting effort +// to assembler implementation of the following routine: +// +// void bn_mul_add_mont (BN_ULONG *rp,BN_ULONG *np,int nl,BN_ULONG n0) +// { +// int i,j; +// BN_ULONG v; +// +// for (i=0; i for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# This module doesn't present direct interest for OpenSSL, because it +# doesn't provide better performance for longer keys, at least not on +# in-order-execution cores. While 512-bit RSA sign operations can be +# 65% faster in 64-bit mode, 1024-bit ones are only 15% faster, and +# 4096-bit ones are up to 15% slower. In 32-bit mode it varies from +# 16% improvement for 512-bit RSA sign to -33% for 4096-bit RSA +# verify:-( All comparisons are against bn_mul_mont-free assembler. +# The module might be of interest to embedded system developers, as +# the code is smaller than 1KB, yet offers >3x improvement on MIPS64 +# and 75-30% [less for longer keys] on MIPS32 over compiler-generated +# code. + +###################################################################### +# There is a number of MIPS ABI in use, O32 and N32/64 are most +# widely used. Then there is a new contender: NUBI. It appears that if +# one picks the latter, it's possible to arrange code in ABI neutral +# manner. Therefore let's stick to NUBI register layout: +# +($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25)); +($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11)); +($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23)); +($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31)); +# +# The return value is placed in $a0. Following coding rules facilitate +# interoperability: +# +# - never ever touch $tp, "thread pointer", former $gp; +# - copy return value to $t0, former $v0 [or to $a0 if you're adapting +# old code]; +# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary; +# +# For reference here is register layout for N32/64 MIPS ABIs: +# +# ($zero,$at,$v0,$v1)=map("\$$_",(0..3)); +# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11)); +# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25)); +# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23)); +# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31)); +# +$flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64 + +if ($flavour =~ /64|n32/i) { + $PTR_ADD="dadd"; # incidentally works even on n32 + $PTR_SUB="dsub"; # incidentally works even on n32 + $REG_S="sd"; + $REG_L="ld"; + $SZREG=8; +} else { + $PTR_ADD="add"; + $PTR_SUB="sub"; + $REG_S="sw"; + $REG_L="lw"; + $SZREG=4; +} +$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0x00fff000 : 0x00ff0000; +# +# +# +###################################################################### + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +if ($flavour =~ /64|n32/i) { + $LD="ld"; + $ST="sd"; + $MULTU="dmultu"; + $ADDU="daddu"; + $SUBU="dsubu"; + $BNSZ=8; +} else { + $LD="lw"; + $ST="sw"; + $MULTU="multu"; + $ADDU="addu"; + $SUBU="subu"; + $BNSZ=4; +} + +# int bn_mul_mont( +$rp=$a0; # BN_ULONG *rp, +$ap=$a1; # const BN_ULONG *ap, +$bp=$a2; # const BN_ULONG *bp, +$np=$a3; # const BN_ULONG *np, +$n0=$a4; # const BN_ULONG *n0, +$num=$a5; # int num); + +$lo0=$a6; +$hi0=$a7; +$lo1=$t1; +$hi1=$t2; +$aj=$s0; +$bi=$s1; +$nj=$s2; +$tp=$s3; +$alo=$s4; +$ahi=$s5; +$nlo=$s6; +$nhi=$s7; +$tj=$s8; +$i=$s9; +$j=$s10; +$m1=$s11; + +$FRAMESIZE=14; + +$code=<<___; +.text + +.set noat +.set noreorder + +.align 5 +.globl bn_mul_mont +.ent bn_mul_mont +bn_mul_mont: +___ +$code.=<<___ if ($flavour =~ /o32/i); + lw $n0,16($sp) + lw $num,20($sp) +___ +$code.=<<___; + slt $at,$num,4 + bnez $at,1f + li $t0,0 + slt $at,$num,17 # on in-order CPU + bnez $at,bn_mul_mont_internal + nop +1: jr $ra + li $a0,0 +.end bn_mul_mont + +.align 5 +.ent bn_mul_mont_internal +bn_mul_mont_internal: + .frame $fp,$FRAMESIZE*$SZREG,$ra + .mask 0x40000000|$SAVED_REGS_MASK,-$SZREG + $PTR_SUB $sp,$FRAMESIZE*$SZREG + $REG_S $fp,($FRAMESIZE-1)*$SZREG($sp) + $REG_S $s11,($FRAMESIZE-2)*$SZREG($sp) + $REG_S $s10,($FRAMESIZE-3)*$SZREG($sp) + $REG_S $s9,($FRAMESIZE-4)*$SZREG($sp) + $REG_S $s8,($FRAMESIZE-5)*$SZREG($sp) + $REG_S $s7,($FRAMESIZE-6)*$SZREG($sp) + $REG_S $s6,($FRAMESIZE-7)*$SZREG($sp) + $REG_S $s5,($FRAMESIZE-8)*$SZREG($sp) + $REG_S $s4,($FRAMESIZE-9)*$SZREG($sp) +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_S $s3,($FRAMESIZE-10)*$SZREG($sp) + $REG_S $s2,($FRAMESIZE-11)*$SZREG($sp) + $REG_S $s1,($FRAMESIZE-12)*$SZREG($sp) + $REG_S $s0,($FRAMESIZE-13)*$SZREG($sp) +___ +$code.=<<___; + move $fp,$sp + + .set reorder + $LD $n0,0($n0) + $LD $bi,0($bp) # bp[0] + $LD $aj,0($ap) # ap[0] + $LD $nj,0($np) # np[0] + + $PTR_SUB $sp,2*$BNSZ # place for two extra words + sll $num,`log($BNSZ)/log(2)` + li $at,-4096 + $PTR_SUB $sp,$num + and $sp,$at + + $MULTU $aj,$bi + $LD $alo,$BNSZ($ap) + $LD $nlo,$BNSZ($np) + mflo $lo0 + mfhi $hi0 + $MULTU $lo0,$n0 + mflo $m1 + + $MULTU $alo,$bi + mflo $alo + mfhi $ahi + + $MULTU $nj,$m1 + mflo $lo1 + mfhi $hi1 + $MULTU $nlo,$m1 + $ADDU $lo1,$lo0 + sltu $at,$lo1,$lo0 + $ADDU $hi1,$at + mflo $nlo + mfhi $nhi + + move $tp,$sp + li $j,2*$BNSZ +.align 4 +.L1st: + .set noreorder + $PTR_ADD $aj,$ap,$j + $PTR_ADD $nj,$np,$j + $LD $aj,($aj) + $LD $nj,($nj) + + $MULTU $aj,$bi + $ADDU $lo0,$alo,$hi0 + $ADDU $lo1,$nlo,$hi1 + sltu $at,$lo0,$hi0 + sltu $t0,$lo1,$hi1 + $ADDU $hi0,$ahi,$at + $ADDU $hi1,$nhi,$t0 + mflo $alo + mfhi $ahi + + $ADDU $lo1,$lo0 + sltu $at,$lo1,$lo0 + $MULTU $nj,$m1 + $ADDU $hi1,$at + addu $j,$BNSZ + $ST $lo1,($tp) + sltu $t0,$j,$num + mflo $nlo + mfhi $nhi + + bnez $t0,.L1st + $PTR_ADD $tp,$BNSZ + .set reorder + + $ADDU $lo0,$alo,$hi0 + sltu $at,$lo0,$hi0 + $ADDU $hi0,$ahi,$at + + $ADDU $lo1,$nlo,$hi1 + sltu $t0,$lo1,$hi1 + $ADDU $hi1,$nhi,$t0 + $ADDU $lo1,$lo0 + sltu $at,$lo1,$lo0 + $ADDU $hi1,$at + + $ST $lo1,($tp) + + $ADDU $hi1,$hi0 + sltu $at,$hi1,$hi0 + $ST $hi1,$BNSZ($tp) + $ST $at,2*$BNSZ($tp) + + li $i,$BNSZ +.align 4 +.Louter: + $PTR_ADD $bi,$bp,$i + $LD $bi,($bi) + $LD $aj,($ap) + $LD $alo,$BNSZ($ap) + $LD $tj,($sp) + + $MULTU $aj,$bi + $LD $nj,($np) + $LD $nlo,$BNSZ($np) + mflo $lo0 + mfhi $hi0 + $ADDU $lo0,$tj + $MULTU $lo0,$n0 + sltu $at,$lo0,$tj + $ADDU $hi0,$at + mflo $m1 + + $MULTU $alo,$bi + mflo $alo + mfhi $ahi + + $MULTU $nj,$m1 + mflo $lo1 + mfhi $hi1 + + $MULTU $nlo,$m1 + $ADDU $lo1,$lo0 + sltu $at,$lo1,$lo0 + $ADDU $hi1,$at + mflo $nlo + mfhi $nhi + + move $tp,$sp + li $j,2*$BNSZ + $LD $tj,$BNSZ($tp) +.align 4 +.Linner: + .set noreorder + $PTR_ADD $aj,$ap,$j + $PTR_ADD $nj,$np,$j + $LD $aj,($aj) + $LD $nj,($nj) + + $MULTU $aj,$bi + $ADDU $lo0,$alo,$hi0 + $ADDU $lo1,$nlo,$hi1 + sltu $at,$lo0,$hi0 + sltu $t0,$lo1,$hi1 + $ADDU $hi0,$ahi,$at + $ADDU $hi1,$nhi,$t0 + mflo $alo + mfhi $ahi + + $ADDU $lo0,$tj + addu $j,$BNSZ + $MULTU $nj,$m1 + sltu $at,$lo0,$tj + $ADDU $lo1,$lo0 + $ADDU $hi0,$at + sltu $t0,$lo1,$lo0 + $LD $tj,2*$BNSZ($tp) + $ADDU $hi1,$t0 + sltu $at,$j,$num + mflo $nlo + mfhi $nhi + $ST $lo1,($tp) + bnez $at,.Linner + $PTR_ADD $tp,$BNSZ + .set reorder + + $ADDU $lo0,$alo,$hi0 + sltu $at,$lo0,$hi0 + $ADDU $hi0,$ahi,$at + $ADDU $lo0,$tj + sltu $t0,$lo0,$tj + $ADDU $hi0,$t0 + + $LD $tj,2*$BNSZ($tp) + $ADDU $lo1,$nlo,$hi1 + sltu $at,$lo1,$hi1 + $ADDU $hi1,$nhi,$at + $ADDU $lo1,$lo0 + sltu $t0,$lo1,$lo0 + $ADDU $hi1,$t0 + $ST $lo1,($tp) + + $ADDU $lo1,$hi1,$hi0 + sltu $hi1,$lo1,$hi0 + $ADDU $lo1,$tj + sltu $at,$lo1,$tj + $ADDU $hi1,$at + $ST $lo1,$BNSZ($tp) + $ST $hi1,2*$BNSZ($tp) + + addu $i,$BNSZ + sltu $t0,$i,$num + bnez $t0,.Louter + + .set noreorder + $PTR_ADD $tj,$sp,$num # &tp[num] + move $tp,$sp + move $ap,$sp + li $hi0,0 # clear borrow bit + +.align 4 +.Lsub: $LD $lo0,($tp) + $LD $lo1,($np) + $PTR_ADD $tp,$BNSZ + $PTR_ADD $np,$BNSZ + $SUBU $lo1,$lo0,$lo1 # tp[i]-np[i] + sgtu $at,$lo1,$lo0 + $SUBU $lo0,$lo1,$hi0 + sgtu $hi0,$lo0,$lo1 + $ST $lo0,($rp) + or $hi0,$at + sltu $at,$tp,$tj + bnez $at,.Lsub + $PTR_ADD $rp,$BNSZ + + $SUBU $hi0,$hi1,$hi0 # handle upmost overflow bit + move $tp,$sp + $PTR_SUB $rp,$num # restore rp + not $hi1,$hi0 + + and $ap,$hi0,$sp + and $bp,$hi1,$rp + or $ap,$ap,$bp # ap=borrow?tp:rp + +.align 4 +.Lcopy: $LD $aj,($ap) + $PTR_ADD $ap,$BNSZ + $ST $zero,($tp) + $PTR_ADD $tp,$BNSZ + sltu $at,$tp,$tj + $ST $aj,($rp) + bnez $at,.Lcopy + $PTR_ADD $rp,$BNSZ + + li $a0,1 + li $t0,1 + + .set noreorder + move $sp,$fp + $REG_L $fp,($FRAMESIZE-1)*$SZREG($sp) + $REG_L $s11,($FRAMESIZE-2)*$SZREG($sp) + $REG_L $s10,($FRAMESIZE-3)*$SZREG($sp) + $REG_L $s9,($FRAMESIZE-4)*$SZREG($sp) + $REG_L $s8,($FRAMESIZE-5)*$SZREG($sp) + $REG_L $s7,($FRAMESIZE-6)*$SZREG($sp) + $REG_L $s6,($FRAMESIZE-7)*$SZREG($sp) + $REG_L $s5,($FRAMESIZE-8)*$SZREG($sp) + $REG_L $s4,($FRAMESIZE-9)*$SZREG($sp) +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $s3,($FRAMESIZE-10)*$SZREG($sp) + $REG_L $s2,($FRAMESIZE-11)*$SZREG($sp) + $REG_L $s1,($FRAMESIZE-12)*$SZREG($sp) + $REG_L $s0,($FRAMESIZE-13)*$SZREG($sp) +___ +$code.=<<___; + jr $ra + $PTR_ADD $sp,$FRAMESIZE*$SZREG +.end bn_mul_mont_internal +.rdata +.asciiz "Montgomery Multiplication for MIPS, CRYPTOGAMS by " +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; + +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/mips.pl b/libs/openssl/crypto/bn/asm/mips.pl new file mode 100644 index 00000000..215c9a74 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/mips.pl @@ -0,0 +1,2234 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. +# +# Rights for redistribution and usage in source and binary forms are +# granted according to the OpenSSL license. Warranty of any kind is +# disclaimed. +# ==================================================================== + + +# July 1999 +# +# This is drop-in MIPS III/IV ISA replacement for crypto/bn/bn_asm.c. +# +# The module is designed to work with either of the "new" MIPS ABI(5), +# namely N32 or N64, offered by IRIX 6.x. It's not ment to work under +# IRIX 5.x not only because it doesn't support new ABIs but also +# because 5.x kernels put R4x00 CPU into 32-bit mode and all those +# 64-bit instructions (daddu, dmultu, etc.) found below gonna only +# cause illegal instruction exception:-( +# +# In addition the code depends on preprocessor flags set up by MIPSpro +# compiler driver (either as or cc) and therefore (probably?) can't be +# compiled by the GNU assembler. GNU C driver manages fine though... +# I mean as long as -mmips-as is specified or is the default option, +# because then it simply invokes /usr/bin/as which in turn takes +# perfect care of the preprocessor definitions. Another neat feature +# offered by the MIPSpro assembler is an optimization pass. This gave +# me the opportunity to have the code looking more regular as all those +# architecture dependent instruction rescheduling details were left to +# the assembler. Cool, huh? +# +# Performance improvement is astonishing! 'apps/openssl speed rsa dsa' +# goes way over 3 times faster! +# +# + +# October 2010 +# +# Adapt the module even for 32-bit ABIs and other OSes. The former was +# achieved by mechanical replacement of 64-bit arithmetic instructions +# such as dmultu, daddu, etc. with their 32-bit counterparts and +# adjusting offsets denoting multiples of BN_ULONG. Above mentioned +# >3x performance improvement naturally does not apply to 32-bit code +# [because there is no instruction 32-bit compiler can't use], one +# has to content with 40-85% improvement depending on benchmark and +# key length, more for longer keys. + +$flavour = shift; +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +if ($flavour =~ /64|n32/i) { + $LD="ld"; + $ST="sd"; + $MULTU="dmultu"; + $DIVU="ddivu"; + $ADDU="daddu"; + $SUBU="dsubu"; + $SRL="dsrl"; + $SLL="dsll"; + $BNSZ=8; + $PTR_ADD="daddu"; + $PTR_SUB="dsubu"; + $SZREG=8; + $REG_S="sd"; + $REG_L="ld"; +} else { + $LD="lw"; + $ST="sw"; + $MULTU="multu"; + $DIVU="divu"; + $ADDU="addu"; + $SUBU="subu"; + $SRL="srl"; + $SLL="sll"; + $BNSZ=4; + $PTR_ADD="addu"; + $PTR_SUB="subu"; + $SZREG=4; + $REG_S="sw"; + $REG_L="lw"; + $code=".set mips2\n"; +} + +# Below is N32/64 register layout used in the original module. +# +($zero,$at,$v0,$v1)=map("\$$_",(0..3)); +($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11)); +($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25)); +($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23)); +($gp,$sp,$fp,$ra)=map("\$$_",(28..31)); +($ta0,$ta1,$ta2,$ta3)=($a4,$a5,$a6,$a7); +# +# No special adaptation is required for O32. NUBI on the other hand +# is treated by saving/restoring ($v1,$t0..$t3). + +$gp=$v1 if ($flavour =~ /nubi/i); + +$minus4=$v1; + +$code.=<<___; +.rdata +.asciiz "mips3.s, Version 1.2" +.asciiz "MIPS II/III/IV ISA artwork by Andy Polyakov " + +.text +.set noat + +.align 5 +.globl bn_mul_add_words +.ent bn_mul_add_words +bn_mul_add_words: + .set noreorder + bgtz $a2,bn_mul_add_words_internal + move $v0,$zero + jr $ra + move $a0,$v0 +.end bn_mul_add_words + +.align 5 +.ent bn_mul_add_words_internal +bn_mul_add_words_internal: +___ +$code.=<<___ if ($flavour =~ /nubi/i); + .frame $sp,6*$SZREG,$ra + .mask 0x8000f008,-$SZREG + .set noreorder + $PTR_SUB $sp,6*$SZREG + $REG_S $ra,5*$SZREG($sp) + $REG_S $t3,4*$SZREG($sp) + $REG_S $t2,3*$SZREG($sp) + $REG_S $t1,2*$SZREG($sp) + $REG_S $t0,1*$SZREG($sp) + $REG_S $gp,0*$SZREG($sp) +___ +$code.=<<___; + .set reorder + li $minus4,-4 + and $ta0,$a2,$minus4 + beqz $ta0,.L_bn_mul_add_words_tail + +.L_bn_mul_add_words_loop: + $LD $t0,0($a1) + $MULTU $t0,$a3 + $LD $t1,0($a0) + $LD $t2,$BNSZ($a1) + $LD $t3,$BNSZ($a0) + $LD $ta0,2*$BNSZ($a1) + $LD $ta1,2*$BNSZ($a0) + $ADDU $t1,$v0 + sltu $v0,$t1,$v0 # All manuals say it "compares 32-bit + # values", but it seems to work fine + # even on 64-bit registers. + mflo $at + mfhi $t0 + $ADDU $t1,$at + $ADDU $v0,$t0 + $MULTU $t2,$a3 + sltu $at,$t1,$at + $ST $t1,0($a0) + $ADDU $v0,$at + + $LD $ta2,3*$BNSZ($a1) + $LD $ta3,3*$BNSZ($a0) + $ADDU $t3,$v0 + sltu $v0,$t3,$v0 + mflo $at + mfhi $t2 + $ADDU $t3,$at + $ADDU $v0,$t2 + $MULTU $ta0,$a3 + sltu $at,$t3,$at + $ST $t3,$BNSZ($a0) + $ADDU $v0,$at + + subu $a2,4 + $PTR_ADD $a0,4*$BNSZ + $PTR_ADD $a1,4*$BNSZ + $ADDU $ta1,$v0 + sltu $v0,$ta1,$v0 + mflo $at + mfhi $ta0 + $ADDU $ta1,$at + $ADDU $v0,$ta0 + $MULTU $ta2,$a3 + sltu $at,$ta1,$at + $ST $ta1,-2*$BNSZ($a0) + $ADDU $v0,$at + + + and $ta0,$a2,$minus4 + $ADDU $ta3,$v0 + sltu $v0,$ta3,$v0 + mflo $at + mfhi $ta2 + $ADDU $ta3,$at + $ADDU $v0,$ta2 + sltu $at,$ta3,$at + $ST $ta3,-$BNSZ($a0) + .set noreorder + bgtz $ta0,.L_bn_mul_add_words_loop + $ADDU $v0,$at + + beqz $a2,.L_bn_mul_add_words_return + nop + +.L_bn_mul_add_words_tail: + .set reorder + $LD $t0,0($a1) + $MULTU $t0,$a3 + $LD $t1,0($a0) + subu $a2,1 + $ADDU $t1,$v0 + sltu $v0,$t1,$v0 + mflo $at + mfhi $t0 + $ADDU $t1,$at + $ADDU $v0,$t0 + sltu $at,$t1,$at + $ST $t1,0($a0) + $ADDU $v0,$at + beqz $a2,.L_bn_mul_add_words_return + + $LD $t0,$BNSZ($a1) + $MULTU $t0,$a3 + $LD $t1,$BNSZ($a0) + subu $a2,1 + $ADDU $t1,$v0 + sltu $v0,$t1,$v0 + mflo $at + mfhi $t0 + $ADDU $t1,$at + $ADDU $v0,$t0 + sltu $at,$t1,$at + $ST $t1,$BNSZ($a0) + $ADDU $v0,$at + beqz $a2,.L_bn_mul_add_words_return + + $LD $t0,2*$BNSZ($a1) + $MULTU $t0,$a3 + $LD $t1,2*$BNSZ($a0) + $ADDU $t1,$v0 + sltu $v0,$t1,$v0 + mflo $at + mfhi $t0 + $ADDU $t1,$at + $ADDU $v0,$t0 + sltu $at,$t1,$at + $ST $t1,2*$BNSZ($a0) + $ADDU $v0,$at + +.L_bn_mul_add_words_return: + .set noreorder +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $t3,4*$SZREG($sp) + $REG_L $t2,3*$SZREG($sp) + $REG_L $t1,2*$SZREG($sp) + $REG_L $t0,1*$SZREG($sp) + $REG_L $gp,0*$SZREG($sp) + $PTR_ADD $sp,6*$SZREG +___ +$code.=<<___; + jr $ra + move $a0,$v0 +.end bn_mul_add_words_internal + +.align 5 +.globl bn_mul_words +.ent bn_mul_words +bn_mul_words: + .set noreorder + bgtz $a2,bn_mul_words_internal + move $v0,$zero + jr $ra + move $a0,$v0 +.end bn_mul_words + +.align 5 +.ent bn_mul_words_internal +bn_mul_words_internal: +___ +$code.=<<___ if ($flavour =~ /nubi/i); + .frame $sp,6*$SZREG,$ra + .mask 0x8000f008,-$SZREG + .set noreorder + $PTR_SUB $sp,6*$SZREG + $REG_S $ra,5*$SZREG($sp) + $REG_S $t3,4*$SZREG($sp) + $REG_S $t2,3*$SZREG($sp) + $REG_S $t1,2*$SZREG($sp) + $REG_S $t0,1*$SZREG($sp) + $REG_S $gp,0*$SZREG($sp) +___ +$code.=<<___; + .set reorder + li $minus4,-4 + and $ta0,$a2,$minus4 + beqz $ta0,.L_bn_mul_words_tail + +.L_bn_mul_words_loop: + $LD $t0,0($a1) + $MULTU $t0,$a3 + $LD $t2,$BNSZ($a1) + $LD $ta0,2*$BNSZ($a1) + $LD $ta2,3*$BNSZ($a1) + mflo $at + mfhi $t0 + $ADDU $v0,$at + sltu $t1,$v0,$at + $MULTU $t2,$a3 + $ST $v0,0($a0) + $ADDU $v0,$t1,$t0 + + subu $a2,4 + $PTR_ADD $a0,4*$BNSZ + $PTR_ADD $a1,4*$BNSZ + mflo $at + mfhi $t2 + $ADDU $v0,$at + sltu $t3,$v0,$at + $MULTU $ta0,$a3 + $ST $v0,-3*$BNSZ($a0) + $ADDU $v0,$t3,$t2 + + mflo $at + mfhi $ta0 + $ADDU $v0,$at + sltu $ta1,$v0,$at + $MULTU $ta2,$a3 + $ST $v0,-2*$BNSZ($a0) + $ADDU $v0,$ta1,$ta0 + + and $ta0,$a2,$minus4 + mflo $at + mfhi $ta2 + $ADDU $v0,$at + sltu $ta3,$v0,$at + $ST $v0,-$BNSZ($a0) + .set noreorder + bgtz $ta0,.L_bn_mul_words_loop + $ADDU $v0,$ta3,$ta2 + + beqz $a2,.L_bn_mul_words_return + nop + +.L_bn_mul_words_tail: + .set reorder + $LD $t0,0($a1) + $MULTU $t0,$a3 + subu $a2,1 + mflo $at + mfhi $t0 + $ADDU $v0,$at + sltu $t1,$v0,$at + $ST $v0,0($a0) + $ADDU $v0,$t1,$t0 + beqz $a2,.L_bn_mul_words_return + + $LD $t0,$BNSZ($a1) + $MULTU $t0,$a3 + subu $a2,1 + mflo $at + mfhi $t0 + $ADDU $v0,$at + sltu $t1,$v0,$at + $ST $v0,$BNSZ($a0) + $ADDU $v0,$t1,$t0 + beqz $a2,.L_bn_mul_words_return + + $LD $t0,2*$BNSZ($a1) + $MULTU $t0,$a3 + mflo $at + mfhi $t0 + $ADDU $v0,$at + sltu $t1,$v0,$at + $ST $v0,2*$BNSZ($a0) + $ADDU $v0,$t1,$t0 + +.L_bn_mul_words_return: + .set noreorder +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $t3,4*$SZREG($sp) + $REG_L $t2,3*$SZREG($sp) + $REG_L $t1,2*$SZREG($sp) + $REG_L $t0,1*$SZREG($sp) + $REG_L $gp,0*$SZREG($sp) + $PTR_ADD $sp,6*$SZREG +___ +$code.=<<___; + jr $ra + move $a0,$v0 +.end bn_mul_words_internal + +.align 5 +.globl bn_sqr_words +.ent bn_sqr_words +bn_sqr_words: + .set noreorder + bgtz $a2,bn_sqr_words_internal + move $v0,$zero + jr $ra + move $a0,$v0 +.end bn_sqr_words + +.align 5 +.ent bn_sqr_words_internal +bn_sqr_words_internal: +___ +$code.=<<___ if ($flavour =~ /nubi/i); + .frame $sp,6*$SZREG,$ra + .mask 0x8000f008,-$SZREG + .set noreorder + $PTR_SUB $sp,6*$SZREG + $REG_S $ra,5*$SZREG($sp) + $REG_S $t3,4*$SZREG($sp) + $REG_S $t2,3*$SZREG($sp) + $REG_S $t1,2*$SZREG($sp) + $REG_S $t0,1*$SZREG($sp) + $REG_S $gp,0*$SZREG($sp) +___ +$code.=<<___; + .set reorder + li $minus4,-4 + and $ta0,$a2,$minus4 + beqz $ta0,.L_bn_sqr_words_tail + +.L_bn_sqr_words_loop: + $LD $t0,0($a1) + $MULTU $t0,$t0 + $LD $t2,$BNSZ($a1) + $LD $ta0,2*$BNSZ($a1) + $LD $ta2,3*$BNSZ($a1) + mflo $t1 + mfhi $t0 + $ST $t1,0($a0) + $ST $t0,$BNSZ($a0) + + $MULTU $t2,$t2 + subu $a2,4 + $PTR_ADD $a0,8*$BNSZ + $PTR_ADD $a1,4*$BNSZ + mflo $t3 + mfhi $t2 + $ST $t3,-6*$BNSZ($a0) + $ST $t2,-5*$BNSZ($a0) + + $MULTU $ta0,$ta0 + mflo $ta1 + mfhi $ta0 + $ST $ta1,-4*$BNSZ($a0) + $ST $ta0,-3*$BNSZ($a0) + + + $MULTU $ta2,$ta2 + and $ta0,$a2,$minus4 + mflo $ta3 + mfhi $ta2 + $ST $ta3,-2*$BNSZ($a0) + + .set noreorder + bgtz $ta0,.L_bn_sqr_words_loop + $ST $ta2,-$BNSZ($a0) + + beqz $a2,.L_bn_sqr_words_return + nop + +.L_bn_sqr_words_tail: + .set reorder + $LD $t0,0($a1) + $MULTU $t0,$t0 + subu $a2,1 + mflo $t1 + mfhi $t0 + $ST $t1,0($a0) + $ST $t0,$BNSZ($a0) + beqz $a2,.L_bn_sqr_words_return + + $LD $t0,$BNSZ($a1) + $MULTU $t0,$t0 + subu $a2,1 + mflo $t1 + mfhi $t0 + $ST $t1,2*$BNSZ($a0) + $ST $t0,3*$BNSZ($a0) + beqz $a2,.L_bn_sqr_words_return + + $LD $t0,2*$BNSZ($a1) + $MULTU $t0,$t0 + mflo $t1 + mfhi $t0 + $ST $t1,4*$BNSZ($a0) + $ST $t0,5*$BNSZ($a0) + +.L_bn_sqr_words_return: + .set noreorder +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $t3,4*$SZREG($sp) + $REG_L $t2,3*$SZREG($sp) + $REG_L $t1,2*$SZREG($sp) + $REG_L $t0,1*$SZREG($sp) + $REG_L $gp,0*$SZREG($sp) + $PTR_ADD $sp,6*$SZREG +___ +$code.=<<___; + jr $ra + move $a0,$v0 + +.end bn_sqr_words_internal + +.align 5 +.globl bn_add_words +.ent bn_add_words +bn_add_words: + .set noreorder + bgtz $a3,bn_add_words_internal + move $v0,$zero + jr $ra + move $a0,$v0 +.end bn_add_words + +.align 5 +.ent bn_add_words_internal +bn_add_words_internal: +___ +$code.=<<___ if ($flavour =~ /nubi/i); + .frame $sp,6*$SZREG,$ra + .mask 0x8000f008,-$SZREG + .set noreorder + $PTR_SUB $sp,6*$SZREG + $REG_S $ra,5*$SZREG($sp) + $REG_S $t3,4*$SZREG($sp) + $REG_S $t2,3*$SZREG($sp) + $REG_S $t1,2*$SZREG($sp) + $REG_S $t0,1*$SZREG($sp) + $REG_S $gp,0*$SZREG($sp) +___ +$code.=<<___; + .set reorder + li $minus4,-4 + and $at,$a3,$minus4 + beqz $at,.L_bn_add_words_tail + +.L_bn_add_words_loop: + $LD $t0,0($a1) + $LD $ta0,0($a2) + subu $a3,4 + $LD $t1,$BNSZ($a1) + and $at,$a3,$minus4 + $LD $t2,2*$BNSZ($a1) + $PTR_ADD $a2,4*$BNSZ + $LD $t3,3*$BNSZ($a1) + $PTR_ADD $a0,4*$BNSZ + $LD $ta1,-3*$BNSZ($a2) + $PTR_ADD $a1,4*$BNSZ + $LD $ta2,-2*$BNSZ($a2) + $LD $ta3,-$BNSZ($a2) + $ADDU $ta0,$t0 + sltu $t8,$ta0,$t0 + $ADDU $t0,$ta0,$v0 + sltu $v0,$t0,$ta0 + $ST $t0,-4*$BNSZ($a0) + $ADDU $v0,$t8 + + $ADDU $ta1,$t1 + sltu $t9,$ta1,$t1 + $ADDU $t1,$ta1,$v0 + sltu $v0,$t1,$ta1 + $ST $t1,-3*$BNSZ($a0) + $ADDU $v0,$t9 + + $ADDU $ta2,$t2 + sltu $t8,$ta2,$t2 + $ADDU $t2,$ta2,$v0 + sltu $v0,$t2,$ta2 + $ST $t2,-2*$BNSZ($a0) + $ADDU $v0,$t8 + + $ADDU $ta3,$t3 + sltu $t9,$ta3,$t3 + $ADDU $t3,$ta3,$v0 + sltu $v0,$t3,$ta3 + $ST $t3,-$BNSZ($a0) + + .set noreorder + bgtz $at,.L_bn_add_words_loop + $ADDU $v0,$t9 + + beqz $a3,.L_bn_add_words_return + nop + +.L_bn_add_words_tail: + .set reorder + $LD $t0,0($a1) + $LD $ta0,0($a2) + $ADDU $ta0,$t0 + subu $a3,1 + sltu $t8,$ta0,$t0 + $ADDU $t0,$ta0,$v0 + sltu $v0,$t0,$ta0 + $ST $t0,0($a0) + $ADDU $v0,$t8 + beqz $a3,.L_bn_add_words_return + + $LD $t1,$BNSZ($a1) + $LD $ta1,$BNSZ($a2) + $ADDU $ta1,$t1 + subu $a3,1 + sltu $t9,$ta1,$t1 + $ADDU $t1,$ta1,$v0 + sltu $v0,$t1,$ta1 + $ST $t1,$BNSZ($a0) + $ADDU $v0,$t9 + beqz $a3,.L_bn_add_words_return + + $LD $t2,2*$BNSZ($a1) + $LD $ta2,2*$BNSZ($a2) + $ADDU $ta2,$t2 + sltu $t8,$ta2,$t2 + $ADDU $t2,$ta2,$v0 + sltu $v0,$t2,$ta2 + $ST $t2,2*$BNSZ($a0) + $ADDU $v0,$t8 + +.L_bn_add_words_return: + .set noreorder +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $t3,4*$SZREG($sp) + $REG_L $t2,3*$SZREG($sp) + $REG_L $t1,2*$SZREG($sp) + $REG_L $t0,1*$SZREG($sp) + $REG_L $gp,0*$SZREG($sp) + $PTR_ADD $sp,6*$SZREG +___ +$code.=<<___; + jr $ra + move $a0,$v0 + +.end bn_add_words_internal + +.align 5 +.globl bn_sub_words +.ent bn_sub_words +bn_sub_words: + .set noreorder + bgtz $a3,bn_sub_words_internal + move $v0,$zero + jr $ra + move $a0,$zero +.end bn_sub_words + +.align 5 +.ent bn_sub_words_internal +bn_sub_words_internal: +___ +$code.=<<___ if ($flavour =~ /nubi/i); + .frame $sp,6*$SZREG,$ra + .mask 0x8000f008,-$SZREG + .set noreorder + $PTR_SUB $sp,6*$SZREG + $REG_S $ra,5*$SZREG($sp) + $REG_S $t3,4*$SZREG($sp) + $REG_S $t2,3*$SZREG($sp) + $REG_S $t1,2*$SZREG($sp) + $REG_S $t0,1*$SZREG($sp) + $REG_S $gp,0*$SZREG($sp) +___ +$code.=<<___; + .set reorder + li $minus4,-4 + and $at,$a3,$minus4 + beqz $at,.L_bn_sub_words_tail + +.L_bn_sub_words_loop: + $LD $t0,0($a1) + $LD $ta0,0($a2) + subu $a3,4 + $LD $t1,$BNSZ($a1) + and $at,$a3,$minus4 + $LD $t2,2*$BNSZ($a1) + $PTR_ADD $a2,4*$BNSZ + $LD $t3,3*$BNSZ($a1) + $PTR_ADD $a0,4*$BNSZ + $LD $ta1,-3*$BNSZ($a2) + $PTR_ADD $a1,4*$BNSZ + $LD $ta2,-2*$BNSZ($a2) + $LD $ta3,-$BNSZ($a2) + sltu $t8,$t0,$ta0 + $SUBU $ta0,$t0,$ta0 + $SUBU $t0,$ta0,$v0 + sgtu $v0,$t0,$ta0 + $ST $t0,-4*$BNSZ($a0) + $ADDU $v0,$t8 + + sltu $t9,$t1,$ta1 + $SUBU $ta1,$t1,$ta1 + $SUBU $t1,$ta1,$v0 + sgtu $v0,$t1,$ta1 + $ST $t1,-3*$BNSZ($a0) + $ADDU $v0,$t9 + + + sltu $t8,$t2,$ta2 + $SUBU $ta2,$t2,$ta2 + $SUBU $t2,$ta2,$v0 + sgtu $v0,$t2,$ta2 + $ST $t2,-2*$BNSZ($a0) + $ADDU $v0,$t8 + + sltu $t9,$t3,$ta3 + $SUBU $ta3,$t3,$ta3 + $SUBU $t3,$ta3,$v0 + sgtu $v0,$t3,$ta3 + $ST $t3,-$BNSZ($a0) + + .set noreorder + bgtz $at,.L_bn_sub_words_loop + $ADDU $v0,$t9 + + beqz $a3,.L_bn_sub_words_return + nop + +.L_bn_sub_words_tail: + .set reorder + $LD $t0,0($a1) + $LD $ta0,0($a2) + subu $a3,1 + sltu $t8,$t0,$ta0 + $SUBU $ta0,$t0,$ta0 + $SUBU $t0,$ta0,$v0 + sgtu $v0,$t0,$ta0 + $ST $t0,0($a0) + $ADDU $v0,$t8 + beqz $a3,.L_bn_sub_words_return + + $LD $t1,$BNSZ($a1) + subu $a3,1 + $LD $ta1,$BNSZ($a2) + sltu $t9,$t1,$ta1 + $SUBU $ta1,$t1,$ta1 + $SUBU $t1,$ta1,$v0 + sgtu $v0,$t1,$ta1 + $ST $t1,$BNSZ($a0) + $ADDU $v0,$t9 + beqz $a3,.L_bn_sub_words_return + + $LD $t2,2*$BNSZ($a1) + $LD $ta2,2*$BNSZ($a2) + sltu $t8,$t2,$ta2 + $SUBU $ta2,$t2,$ta2 + $SUBU $t2,$ta2,$v0 + sgtu $v0,$t2,$ta2 + $ST $t2,2*$BNSZ($a0) + $ADDU $v0,$t8 + +.L_bn_sub_words_return: + .set noreorder +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $t3,4*$SZREG($sp) + $REG_L $t2,3*$SZREG($sp) + $REG_L $t1,2*$SZREG($sp) + $REG_L $t0,1*$SZREG($sp) + $REG_L $gp,0*$SZREG($sp) + $PTR_ADD $sp,6*$SZREG +___ +$code.=<<___; + jr $ra + move $a0,$v0 +.end bn_sub_words_internal + +.align 5 +.globl bn_div_3_words +.ent bn_div_3_words +bn_div_3_words: + .set noreorder + move $a3,$a0 # we know that bn_div_words does not + # touch $a3, $ta2, $ta3 and preserves $a2 + # so that we can save two arguments + # and return address in registers + # instead of stack:-) + + $LD $a0,($a3) + move $ta2,$a1 + bne $a0,$a2,bn_div_3_words_internal + $LD $a1,-$BNSZ($a3) + li $v0,-1 + jr $ra + move $a0,$v0 +.end bn_div_3_words + +.align 5 +.ent bn_div_3_words_internal +bn_div_3_words_internal: +___ +$code.=<<___ if ($flavour =~ /nubi/i); + .frame $sp,6*$SZREG,$ra + .mask 0x8000f008,-$SZREG + .set noreorder + $PTR_SUB $sp,6*$SZREG + $REG_S $ra,5*$SZREG($sp) + $REG_S $t3,4*$SZREG($sp) + $REG_S $t2,3*$SZREG($sp) + $REG_S $t1,2*$SZREG($sp) + $REG_S $t0,1*$SZREG($sp) + $REG_S $gp,0*$SZREG($sp) +___ +$code.=<<___; + .set reorder + move $ta3,$ra + bal bn_div_words_internal + move $ra,$ta3 + $MULTU $ta2,$v0 + $LD $t2,-2*$BNSZ($a3) + move $ta0,$zero + mfhi $t1 + mflo $t0 + sltu $t8,$t1,$a1 +.L_bn_div_3_words_inner_loop: + bnez $t8,.L_bn_div_3_words_inner_loop_done + sgeu $at,$t2,$t0 + seq $t9,$t1,$a1 + and $at,$t9 + sltu $t3,$t0,$ta2 + $ADDU $a1,$a2 + $SUBU $t1,$t3 + $SUBU $t0,$ta2 + sltu $t8,$t1,$a1 + sltu $ta0,$a1,$a2 + or $t8,$ta0 + .set noreorder + beqz $at,.L_bn_div_3_words_inner_loop + $SUBU $v0,1 + $ADDU $v0,1 + .set reorder +.L_bn_div_3_words_inner_loop_done: + .set noreorder +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $t3,4*$SZREG($sp) + $REG_L $t2,3*$SZREG($sp) + $REG_L $t1,2*$SZREG($sp) + $REG_L $t0,1*$SZREG($sp) + $REG_L $gp,0*$SZREG($sp) + $PTR_ADD $sp,6*$SZREG +___ +$code.=<<___; + jr $ra + move $a0,$v0 +.end bn_div_3_words_internal + +.align 5 +.globl bn_div_words +.ent bn_div_words +bn_div_words: + .set noreorder + bnez $a2,bn_div_words_internal + li $v0,-1 # I would rather signal div-by-zero + # which can be done with 'break 7' + jr $ra + move $a0,$v0 +.end bn_div_words + +.align 5 +.ent bn_div_words_internal +bn_div_words_internal: +___ +$code.=<<___ if ($flavour =~ /nubi/i); + .frame $sp,6*$SZREG,$ra + .mask 0x8000f008,-$SZREG + .set noreorder + $PTR_SUB $sp,6*$SZREG + $REG_S $ra,5*$SZREG($sp) + $REG_S $t3,4*$SZREG($sp) + $REG_S $t2,3*$SZREG($sp) + $REG_S $t1,2*$SZREG($sp) + $REG_S $t0,1*$SZREG($sp) + $REG_S $gp,0*$SZREG($sp) +___ +$code.=<<___; + move $v1,$zero + bltz $a2,.L_bn_div_words_body + move $t9,$v1 + $SLL $a2,1 + bgtz $a2,.-4 + addu $t9,1 + + .set reorder + negu $t1,$t9 + li $t2,-1 + $SLL $t2,$t1 + and $t2,$a0 + $SRL $at,$a1,$t1 + .set noreorder + beqz $t2,.+12 + nop + break 6 # signal overflow + .set reorder + $SLL $a0,$t9 + $SLL $a1,$t9 + or $a0,$at +___ +$QT=$ta0; +$HH=$ta1; +$DH=$v1; +$code.=<<___; +.L_bn_div_words_body: + $SRL $DH,$a2,4*$BNSZ # bits + sgeu $at,$a0,$a2 + .set noreorder + beqz $at,.+12 + nop + $SUBU $a0,$a2 + .set reorder + + li $QT,-1 + $SRL $HH,$a0,4*$BNSZ # bits + $SRL $QT,4*$BNSZ # q=0xffffffff + beq $DH,$HH,.L_bn_div_words_skip_div1 + $DIVU $zero,$a0,$DH + mflo $QT +.L_bn_div_words_skip_div1: + $MULTU $a2,$QT + $SLL $t3,$a0,4*$BNSZ # bits + $SRL $at,$a1,4*$BNSZ # bits + or $t3,$at + mflo $t0 + mfhi $t1 +.L_bn_div_words_inner_loop1: + sltu $t2,$t3,$t0 + seq $t8,$HH,$t1 + sltu $at,$HH,$t1 + and $t2,$t8 + sltu $v0,$t0,$a2 + or $at,$t2 + .set noreorder + beqz $at,.L_bn_div_words_inner_loop1_done + $SUBU $t1,$v0 + $SUBU $t0,$a2 + b .L_bn_div_words_inner_loop1 + $SUBU $QT,1 + .set reorder +.L_bn_div_words_inner_loop1_done: + + $SLL $a1,4*$BNSZ # bits + $SUBU $a0,$t3,$t0 + $SLL $v0,$QT,4*$BNSZ # bits + + li $QT,-1 + $SRL $HH,$a0,4*$BNSZ # bits + $SRL $QT,4*$BNSZ # q=0xffffffff + beq $DH,$HH,.L_bn_div_words_skip_div2 + $DIVU $zero,$a0,$DH + mflo $QT +.L_bn_div_words_skip_div2: + $MULTU $a2,$QT + $SLL $t3,$a0,4*$BNSZ # bits + $SRL $at,$a1,4*$BNSZ # bits + or $t3,$at + mflo $t0 + mfhi $t1 +.L_bn_div_words_inner_loop2: + sltu $t2,$t3,$t0 + seq $t8,$HH,$t1 + sltu $at,$HH,$t1 + and $t2,$t8 + sltu $v1,$t0,$a2 + or $at,$t2 + .set noreorder + beqz $at,.L_bn_div_words_inner_loop2_done + $SUBU $t1,$v1 + $SUBU $t0,$a2 + b .L_bn_div_words_inner_loop2 + $SUBU $QT,1 + .set reorder +.L_bn_div_words_inner_loop2_done: + + $SUBU $a0,$t3,$t0 + or $v0,$QT + $SRL $v1,$a0,$t9 # $v1 contains remainder if anybody wants it + $SRL $a2,$t9 # restore $a2 + + .set noreorder + move $a1,$v1 +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $t3,4*$SZREG($sp) + $REG_L $t2,3*$SZREG($sp) + $REG_L $t1,2*$SZREG($sp) + $REG_L $t0,1*$SZREG($sp) + $REG_L $gp,0*$SZREG($sp) + $PTR_ADD $sp,6*$SZREG +___ +$code.=<<___; + jr $ra + move $a0,$v0 +.end bn_div_words_internal +___ +undef $HH; undef $QT; undef $DH; + +($a_0,$a_1,$a_2,$a_3)=($t0,$t1,$t2,$t3); +($b_0,$b_1,$b_2,$b_3)=($ta0,$ta1,$ta2,$ta3); + +($a_4,$a_5,$a_6,$a_7)=($s0,$s2,$s4,$a1); # once we load a[7], no use for $a1 +($b_4,$b_5,$b_6,$b_7)=($s1,$s3,$s5,$a2); # once we load b[7], no use for $a2 + +($t_1,$t_2,$c_1,$c_2,$c_3)=($t8,$t9,$v0,$v1,$a3); + +$code.=<<___; + +.align 5 +.globl bn_mul_comba8 +.ent bn_mul_comba8 +bn_mul_comba8: + .set noreorder +___ +$code.=<<___ if ($flavour =~ /nubi/i); + .frame $sp,12*$SZREG,$ra + .mask 0x803ff008,-$SZREG + $PTR_SUB $sp,12*$SZREG + $REG_S $ra,11*$SZREG($sp) + $REG_S $s5,10*$SZREG($sp) + $REG_S $s4,9*$SZREG($sp) + $REG_S $s3,8*$SZREG($sp) + $REG_S $s2,7*$SZREG($sp) + $REG_S $s1,6*$SZREG($sp) + $REG_S $s0,5*$SZREG($sp) + $REG_S $t3,4*$SZREG($sp) + $REG_S $t2,3*$SZREG($sp) + $REG_S $t1,2*$SZREG($sp) + $REG_S $t0,1*$SZREG($sp) + $REG_S $gp,0*$SZREG($sp) +___ +$code.=<<___ if ($flavour !~ /nubi/i); + .frame $sp,6*$SZREG,$ra + .mask 0x003f0000,-$SZREG + $PTR_SUB $sp,6*$SZREG + $REG_S $s5,5*$SZREG($sp) + $REG_S $s4,4*$SZREG($sp) + $REG_S $s3,3*$SZREG($sp) + $REG_S $s2,2*$SZREG($sp) + $REG_S $s1,1*$SZREG($sp) + $REG_S $s0,0*$SZREG($sp) +___ +$code.=<<___; + + .set reorder + $LD $a_0,0($a1) # If compiled with -mips3 option on + # R5000 box assembler barks on this + # 1ine with "should not have mult/div + # as last instruction in bb (R10K + # bug)" warning. If anybody out there + # has a clue about how to circumvent + # this do send me a note. + # + + $LD $b_0,0($a2) + $LD $a_1,$BNSZ($a1) + $LD $a_2,2*$BNSZ($a1) + $MULTU $a_0,$b_0 # mul_add_c(a[0],b[0],c1,c2,c3); + $LD $a_3,3*$BNSZ($a1) + $LD $b_1,$BNSZ($a2) + $LD $b_2,2*$BNSZ($a2) + $LD $b_3,3*$BNSZ($a2) + mflo $c_1 + mfhi $c_2 + + $LD $a_4,4*$BNSZ($a1) + $LD $a_5,5*$BNSZ($a1) + $MULTU $a_0,$b_1 # mul_add_c(a[0],b[1],c2,c3,c1); + $LD $a_6,6*$BNSZ($a1) + $LD $a_7,7*$BNSZ($a1) + $LD $b_4,4*$BNSZ($a2) + $LD $b_5,5*$BNSZ($a2) + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_1,$b_0 # mul_add_c(a[1],b[0],c2,c3,c1); + $ADDU $c_3,$t_2,$at + $LD $b_6,6*$BNSZ($a2) + $LD $b_7,7*$BNSZ($a2) + $ST $c_1,0($a0) # r[0]=c1; + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_2,$b_0 # mul_add_c(a[2],b[0],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $c_1,$c_3,$t_2 + $ST $c_2,$BNSZ($a0) # r[1]=c2; + + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_1,$b_1 # mul_add_c(a[1],b[1],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_0,$b_2 # mul_add_c(a[0],b[2],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $c_2,$c_1,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_0,$b_3 # mul_add_c(a[0],b[3],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + $ST $c_3,2*$BNSZ($a0) # r[2]=c3; + + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_1,$b_2 # mul_add_c(a[1],b[2],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $c_3,$c_2,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_2,$b_1 # mul_add_c(a[2],b[1],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_3,$b_0 # mul_add_c(a[3],b[0],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_4,$b_0 # mul_add_c(a[4],b[0],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + $ST $c_1,3*$BNSZ($a0) # r[3]=c1; + + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_3,$b_1 # mul_add_c(a[3],b[1],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $c_1,$c_3,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_2,$b_2 # mul_add_c(a[2],b[2],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_1,$b_3 # mul_add_c(a[1],b[3],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_0,$b_4 # mul_add_c(a[0],b[4],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_0,$b_5 # mul_add_c(a[0],b[5],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + $ST $c_2,4*$BNSZ($a0) # r[4]=c2; + + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_1,$b_4 # mul_add_c(a[1],b[4],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $c_2,$c_1,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_2,$b_3 # mul_add_c(a[2],b[3],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_3,$b_2 # mul_add_c(a[3],b[2],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_4,$b_1 # mul_add_c(a[4],b[1],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_5,$b_0 # mul_add_c(a[5],b[0],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_6,$b_0 # mul_add_c(a[6],b[0],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + $ST $c_3,5*$BNSZ($a0) # r[5]=c3; + + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_5,$b_1 # mul_add_c(a[5],b[1],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $c_3,$c_2,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_4,$b_2 # mul_add_c(a[4],b[2],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_3,$b_3 # mul_add_c(a[3],b[3],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_2,$b_4 # mul_add_c(a[2],b[4],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_1,$b_5 # mul_add_c(a[1],b[5],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_0,$b_6 # mul_add_c(a[0],b[6],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_0,$b_7 # mul_add_c(a[0],b[7],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + $ST $c_1,6*$BNSZ($a0) # r[6]=c1; + + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_1,$b_6 # mul_add_c(a[1],b[6],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $c_1,$c_3,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_2,$b_5 # mul_add_c(a[2],b[5],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_3,$b_4 # mul_add_c(a[3],b[4],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_4,$b_3 # mul_add_c(a[4],b[3],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_5,$b_2 # mul_add_c(a[5],b[2],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_6,$b_1 # mul_add_c(a[6],b[1],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_7,$b_0 # mul_add_c(a[7],b[0],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_7,$b_1 # mul_add_c(a[7],b[1],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + $ST $c_2,7*$BNSZ($a0) # r[7]=c2; + + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_6,$b_2 # mul_add_c(a[6],b[2],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $c_2,$c_1,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_5,$b_3 # mul_add_c(a[5],b[3],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_4,$b_4 # mul_add_c(a[4],b[4],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_3,$b_5 # mul_add_c(a[3],b[5],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_2,$b_6 # mul_add_c(a[2],b[6],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_1,$b_7 # mul_add_c(a[1],b[7],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_2,$b_7 # mul_add_c(a[2],b[7],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + $ST $c_3,8*$BNSZ($a0) # r[8]=c3; + + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_3,$b_6 # mul_add_c(a[3],b[6],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $c_3,$c_2,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_4,$b_5 # mul_add_c(a[4],b[5],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_5,$b_4 # mul_add_c(a[5],b[4],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_6,$b_3 # mul_add_c(a[6],b[3],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_7,$b_2 # mul_add_c(a[7],b[2],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_7,$b_3 # mul_add_c(a[7],b[3],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + $ST $c_1,9*$BNSZ($a0) # r[9]=c1; + + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_6,$b_4 # mul_add_c(a[6],b[4],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $c_1,$c_3,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_5,$b_5 # mul_add_c(a[5],b[5],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_4,$b_6 # mul_add_c(a[4],b[6],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_3,$b_7 # mul_add_c(a[3],b[7],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_4,$b_7 # mul_add_c(a[4],b[7],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + $ST $c_2,10*$BNSZ($a0) # r[10]=c2; + + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_5,$b_6 # mul_add_c(a[5],b[6],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $c_2,$c_1,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_6,$b_5 # mul_add_c(a[6],b[5],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_7,$b_4 # mul_add_c(a[7],b[4],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_7,$b_5 # mul_add_c(a[7],b[5],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + $ST $c_3,11*$BNSZ($a0) # r[11]=c3; + + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_6,$b_6 # mul_add_c(a[6],b[6],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $c_3,$c_2,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_5,$b_7 # mul_add_c(a[5],b[7],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_6,$b_7 # mul_add_c(a[6],b[7],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + $ST $c_1,12*$BNSZ($a0) # r[12]=c1; + + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_7,$b_6 # mul_add_c(a[7],b[6],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $c_1,$c_3,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_7,$b_7 # mul_add_c(a[7],b[7],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + $ST $c_2,13*$BNSZ($a0) # r[13]=c2; + + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + $ST $c_3,14*$BNSZ($a0) # r[14]=c3; + $ST $c_1,15*$BNSZ($a0) # r[15]=c1; + + .set noreorder +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $s5,10*$SZREG($sp) + $REG_L $s4,9*$SZREG($sp) + $REG_L $s3,8*$SZREG($sp) + $REG_L $s2,7*$SZREG($sp) + $REG_L $s1,6*$SZREG($sp) + $REG_L $s0,5*$SZREG($sp) + $REG_L $t3,4*$SZREG($sp) + $REG_L $t2,3*$SZREG($sp) + $REG_L $t1,2*$SZREG($sp) + $REG_L $t0,1*$SZREG($sp) + $REG_L $gp,0*$SZREG($sp) + jr $ra + $PTR_ADD $sp,12*$SZREG +___ +$code.=<<___ if ($flavour !~ /nubi/i); + $REG_L $s5,5*$SZREG($sp) + $REG_L $s4,4*$SZREG($sp) + $REG_L $s3,3*$SZREG($sp) + $REG_L $s2,2*$SZREG($sp) + $REG_L $s1,1*$SZREG($sp) + $REG_L $s0,0*$SZREG($sp) + jr $ra + $PTR_ADD $sp,6*$SZREG +___ +$code.=<<___; +.end bn_mul_comba8 + +.align 5 +.globl bn_mul_comba4 +.ent bn_mul_comba4 +bn_mul_comba4: +___ +$code.=<<___ if ($flavour =~ /nubi/i); + .frame $sp,6*$SZREG,$ra + .mask 0x8000f008,-$SZREG + .set noreorder + $PTR_SUB $sp,6*$SZREG + $REG_S $ra,5*$SZREG($sp) + $REG_S $t3,4*$SZREG($sp) + $REG_S $t2,3*$SZREG($sp) + $REG_S $t1,2*$SZREG($sp) + $REG_S $t0,1*$SZREG($sp) + $REG_S $gp,0*$SZREG($sp) +___ +$code.=<<___; + .set reorder + $LD $a_0,0($a1) + $LD $b_0,0($a2) + $LD $a_1,$BNSZ($a1) + $LD $a_2,2*$BNSZ($a1) + $MULTU $a_0,$b_0 # mul_add_c(a[0],b[0],c1,c2,c3); + $LD $a_3,3*$BNSZ($a1) + $LD $b_1,$BNSZ($a2) + $LD $b_2,2*$BNSZ($a2) + $LD $b_3,3*$BNSZ($a2) + mflo $c_1 + mfhi $c_2 + $ST $c_1,0($a0) + + $MULTU $a_0,$b_1 # mul_add_c(a[0],b[1],c2,c3,c1); + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_1,$b_0 # mul_add_c(a[1],b[0],c2,c3,c1); + $ADDU $c_3,$t_2,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_2,$b_0 # mul_add_c(a[2],b[0],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $c_1,$c_3,$t_2 + $ST $c_2,$BNSZ($a0) + + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_1,$b_1 # mul_add_c(a[1],b[1],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_0,$b_2 # mul_add_c(a[0],b[2],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $c_2,$c_1,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_0,$b_3 # mul_add_c(a[0],b[3],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + $ST $c_3,2*$BNSZ($a0) + + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_1,$b_2 # mul_add_c(a[1],b[2],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $c_3,$c_2,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_2,$b_1 # mul_add_c(a[2],b[1],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_3,$b_0 # mul_add_c(a[3],b[0],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_3,$b_1 # mul_add_c(a[3],b[1],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + $ST $c_1,3*$BNSZ($a0) + + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_2,$b_2 # mul_add_c(a[2],b[2],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $c_1,$c_3,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_1,$b_3 # mul_add_c(a[1],b[3],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_2,$b_3 # mul_add_c(a[2],b[3],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + $ST $c_2,4*$BNSZ($a0) + + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_3,$b_2 # mul_add_c(a[3],b[2],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $c_2,$c_1,$t_2 + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_3,$b_3 # mul_add_c(a[3],b[3],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + $ST $c_3,5*$BNSZ($a0) + + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + $ST $c_1,6*$BNSZ($a0) + $ST $c_2,7*$BNSZ($a0) + + .set noreorder +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $t3,4*$SZREG($sp) + $REG_L $t2,3*$SZREG($sp) + $REG_L $t1,2*$SZREG($sp) + $REG_L $t0,1*$SZREG($sp) + $REG_L $gp,0*$SZREG($sp) + $PTR_ADD $sp,6*$SZREG +___ +$code.=<<___; + jr $ra + nop +.end bn_mul_comba4 +___ + +($a_4,$a_5,$a_6,$a_7)=($b_0,$b_1,$b_2,$b_3); + +sub add_c2 () { +my ($hi,$lo,$c0,$c1,$c2, + $warm, # !$warm denotes first call with specific sequence of + # $c_[XYZ] when there is no Z-carry to accumulate yet; + $an,$bn # these two are arguments for multiplication which + # result is used in *next* step [which is why it's + # commented as "forward multiplication" below]; + )=@_; +$code.=<<___; + mflo $lo + mfhi $hi + $ADDU $c0,$lo + sltu $at,$c0,$lo + $MULTU $an,$bn # forward multiplication + $ADDU $c0,$lo + $ADDU $at,$hi + sltu $lo,$c0,$lo + $ADDU $c1,$at + $ADDU $hi,$lo +___ +$code.=<<___ if (!$warm); + sltu $c2,$c1,$at + $ADDU $c1,$hi + sltu $hi,$c1,$hi + $ADDU $c2,$hi +___ +$code.=<<___ if ($warm); + sltu $at,$c1,$at + $ADDU $c1,$hi + $ADDU $c2,$at + sltu $hi,$c1,$hi + $ADDU $c2,$hi +___ +} + +$code.=<<___; + +.align 5 +.globl bn_sqr_comba8 +.ent bn_sqr_comba8 +bn_sqr_comba8: +___ +$code.=<<___ if ($flavour =~ /nubi/i); + .frame $sp,6*$SZREG,$ra + .mask 0x8000f008,-$SZREG + .set noreorder + $PTR_SUB $sp,6*$SZREG + $REG_S $ra,5*$SZREG($sp) + $REG_S $t3,4*$SZREG($sp) + $REG_S $t2,3*$SZREG($sp) + $REG_S $t1,2*$SZREG($sp) + $REG_S $t0,1*$SZREG($sp) + $REG_S $gp,0*$SZREG($sp) +___ +$code.=<<___; + .set reorder + $LD $a_0,0($a1) + $LD $a_1,$BNSZ($a1) + $LD $a_2,2*$BNSZ($a1) + $LD $a_3,3*$BNSZ($a1) + + $MULTU $a_0,$a_0 # mul_add_c(a[0],b[0],c1,c2,c3); + $LD $a_4,4*$BNSZ($a1) + $LD $a_5,5*$BNSZ($a1) + $LD $a_6,6*$BNSZ($a1) + $LD $a_7,7*$BNSZ($a1) + mflo $c_1 + mfhi $c_2 + $ST $c_1,0($a0) + + $MULTU $a_0,$a_1 # mul_add_c2(a[0],b[1],c2,c3,c1); + mflo $t_1 + mfhi $t_2 + slt $c_1,$t_2,$zero + $SLL $t_2,1 + $MULTU $a_2,$a_0 # mul_add_c2(a[2],b[0],c3,c1,c2); + slt $a2,$t_1,$zero + $ADDU $t_2,$a2 + $SLL $t_1,1 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $ADDU $c_3,$t_2,$at + $ST $c_2,$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0, + $a_1,$a_1); # mul_add_c(a[1],b[1],c3,c1,c2); +$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_0,$a_3 # mul_add_c2(a[0],b[3],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + $ST $c_3,2*$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0, + $a_1,$a_2); # mul_add_c2(a[1],b[2],c1,c2,c3); + &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1, + $a_4,$a_0); # mul_add_c2(a[4],b[0],c2,c3,c1); +$code.=<<___; + $ST $c_1,3*$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0, + $a_3,$a_1); # mul_add_c2(a[3],b[1],c2,c3,c1); + &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1, + $a_2,$a_2); # mul_add_c(a[2],b[2],c2,c3,c1); +$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_0,$a_5 # mul_add_c2(a[0],b[5],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + $ST $c_2,4*$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0, + $a_1,$a_4); # mul_add_c2(a[1],b[4],c3,c1,c2); + &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1, + $a_2,$a_3); # mul_add_c2(a[2],b[3],c3,c1,c2); + &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1, + $a_6,$a_0); # mul_add_c2(a[6],b[0],c1,c2,c3); +$code.=<<___; + $ST $c_3,5*$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0, + $a_5,$a_1); # mul_add_c2(a[5],b[1],c1,c2,c3); + &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1, + $a_4,$a_2); # mul_add_c2(a[4],b[2],c1,c2,c3); + &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1, + $a_3,$a_3); # mul_add_c(a[3],b[3],c1,c2,c3); +$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_0,$a_7 # mul_add_c2(a[0],b[7],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + $ST $c_1,6*$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0, + $a_1,$a_6); # mul_add_c2(a[1],b[6],c2,c3,c1); + &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1, + $a_2,$a_5); # mul_add_c2(a[2],b[5],c2,c3,c1); + &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1, + $a_3,$a_4); # mul_add_c2(a[3],b[4],c2,c3,c1); + &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1, + $a_7,$a_1); # mul_add_c2(a[7],b[1],c3,c1,c2); +$code.=<<___; + $ST $c_2,7*$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0, + $a_6,$a_2); # mul_add_c2(a[6],b[2],c3,c1,c2); + &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1, + $a_5,$a_3); # mul_add_c2(a[5],b[3],c3,c1,c2); + &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1, + $a_4,$a_4); # mul_add_c(a[4],b[4],c3,c1,c2); +$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_2,$a_7 # mul_add_c2(a[2],b[7],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + $ST $c_3,8*$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0, + $a_3,$a_6); # mul_add_c2(a[3],b[6],c1,c2,c3); + &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1, + $a_4,$a_5); # mul_add_c2(a[4],b[5],c1,c2,c3); + &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1, + $a_7,$a_3); # mul_add_c2(a[7],b[3],c2,c3,c1); +$code.=<<___; + $ST $c_1,9*$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0, + $a_6,$a_4); # mul_add_c2(a[6],b[4],c2,c3,c1); + &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,1, + $a_5,$a_5); # mul_add_c(a[5],b[5],c2,c3,c1); +$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_4,$a_7 # mul_add_c2(a[4],b[7],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + $ST $c_2,10*$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0, + $a_5,$a_6); # mul_add_c2(a[5],b[6],c3,c1,c2); + &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,1, + $a_7,$a_5); # mul_add_c2(a[7],b[5],c1,c2,c3); +$code.=<<___; + $ST $c_3,11*$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0, + $a_6,$a_6); # mul_add_c(a[6],b[6],c1,c2,c3); +$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $MULTU $a_6,$a_7 # mul_add_c2(a[6],b[7],c2,c3,c1); + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + sltu $at,$c_2,$t_2 + $ADDU $c_3,$at + $ST $c_1,12*$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0, + $a_7,$a_7); # mul_add_c(a[7],b[7],c3,c1,c2); +$code.=<<___; + $ST $c_2,13*$BNSZ($a0) + + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + $ST $c_3,14*$BNSZ($a0) + $ST $c_1,15*$BNSZ($a0) + + .set noreorder +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $t3,4*$SZREG($sp) + $REG_L $t2,3*$SZREG($sp) + $REG_L $t1,2*$SZREG($sp) + $REG_L $t0,1*$SZREG($sp) + $REG_L $gp,0*$SZREG($sp) + $PTR_ADD $sp,6*$SZREG +___ +$code.=<<___; + jr $ra + nop +.end bn_sqr_comba8 + +.align 5 +.globl bn_sqr_comba4 +.ent bn_sqr_comba4 +bn_sqr_comba4: +___ +$code.=<<___ if ($flavour =~ /nubi/i); + .frame $sp,6*$SZREG,$ra + .mask 0x8000f008,-$SZREG + .set noreorder + $PTR_SUB $sp,6*$SZREG + $REG_S $ra,5*$SZREG($sp) + $REG_S $t3,4*$SZREG($sp) + $REG_S $t2,3*$SZREG($sp) + $REG_S $t1,2*$SZREG($sp) + $REG_S $t0,1*$SZREG($sp) + $REG_S $gp,0*$SZREG($sp) +___ +$code.=<<___; + .set reorder + $LD $a_0,0($a1) + $LD $a_1,$BNSZ($a1) + $MULTU $a_0,$a_0 # mul_add_c(a[0],b[0],c1,c2,c3); + $LD $a_2,2*$BNSZ($a1) + $LD $a_3,3*$BNSZ($a1) + mflo $c_1 + mfhi $c_2 + $ST $c_1,0($a0) + + $MULTU $a_0,$a_1 # mul_add_c2(a[0],b[1],c2,c3,c1); + mflo $t_1 + mfhi $t_2 + slt $c_1,$t_2,$zero + $SLL $t_2,1 + $MULTU $a_2,$a_0 # mul_add_c2(a[2],b[0],c3,c1,c2); + slt $a2,$t_1,$zero + $ADDU $t_2,$a2 + $SLL $t_1,1 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $ADDU $c_3,$t_2,$at + $ST $c_2,$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0, + $a_1,$a_1); # mul_add_c(a[1],b[1],c3,c1,c2); +$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_3,$t_1 + sltu $at,$c_3,$t_1 + $MULTU $a_0,$a_3 # mul_add_c2(a[0],b[3],c1,c2,c3); + $ADDU $t_2,$at + $ADDU $c_1,$t_2 + sltu $at,$c_1,$t_2 + $ADDU $c_2,$at + $ST $c_3,2*$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,0, + $a_1,$a_2); # mul_add_c2(a2[1],b[2],c1,c2,c3); + &add_c2($t_2,$t_1,$c_1,$c_2,$c_3,1, + $a_3,$a_1); # mul_add_c2(a[3],b[1],c2,c3,c1); +$code.=<<___; + $ST $c_1,3*$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_2,$c_3,$c_1,0, + $a_2,$a_2); # mul_add_c(a[2],b[2],c2,c3,c1); +$code.=<<___; + mflo $t_1 + mfhi $t_2 + $ADDU $c_2,$t_1 + sltu $at,$c_2,$t_1 + $MULTU $a_2,$a_3 # mul_add_c2(a[2],b[3],c3,c1,c2); + $ADDU $t_2,$at + $ADDU $c_3,$t_2 + sltu $at,$c_3,$t_2 + $ADDU $c_1,$at + $ST $c_2,4*$BNSZ($a0) +___ + &add_c2($t_2,$t_1,$c_3,$c_1,$c_2,0, + $a_3,$a_3); # mul_add_c(a[3],b[3],c1,c2,c3); +$code.=<<___; + $ST $c_3,5*$BNSZ($a0) + + mflo $t_1 + mfhi $t_2 + $ADDU $c_1,$t_1 + sltu $at,$c_1,$t_1 + $ADDU $t_2,$at + $ADDU $c_2,$t_2 + $ST $c_1,6*$BNSZ($a0) + $ST $c_2,7*$BNSZ($a0) + + .set noreorder +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $t3,4*$SZREG($sp) + $REG_L $t2,3*$SZREG($sp) + $REG_L $t1,2*$SZREG($sp) + $REG_L $t0,1*$SZREG($sp) + $REG_L $gp,0*$SZREG($sp) + $PTR_ADD $sp,6*$SZREG +___ +$code.=<<___; + jr $ra + nop +.end bn_sqr_comba4 +___ +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/mips3-mont.pl b/libs/openssl/crypto/bn/asm/mips3-mont.pl new file mode 100644 index 00000000..8f9156e0 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/mips3-mont.pl @@ -0,0 +1,327 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# This module doesn't present direct interest for OpenSSL, because it +# doesn't provide better performance for longer keys. While 512-bit +# RSA private key operations are 40% faster, 1024-bit ones are hardly +# faster at all, while longer key operations are slower by up to 20%. +# It might be of interest to embedded system developers though, as +# it's smaller than 1KB, yet offers ~3x improvement over compiler +# generated code. +# +# The module targets N32 and N64 MIPS ABIs and currently is a bit +# IRIX-centric, i.e. is likely to require adaptation for other OSes. + +# int bn_mul_mont( +$rp="a0"; # BN_ULONG *rp, +$ap="a1"; # const BN_ULONG *ap, +$bp="a2"; # const BN_ULONG *bp, +$np="a3"; # const BN_ULONG *np, +$n0="a4"; # const BN_ULONG *n0, +$num="a5"; # int num); + +$lo0="a6"; +$hi0="a7"; +$lo1="v0"; +$hi1="v1"; +$aj="t0"; +$bi="t1"; +$nj="t2"; +$tp="t3"; +$alo="s0"; +$ahi="s1"; +$nlo="s2"; +$nhi="s3"; +$tj="s4"; +$i="s5"; +$j="s6"; +$fp="t8"; +$m1="t9"; + +$FRAME=8*(2+8); + +$code=<<___; +#include +#include + +.text + +.set noat +.set reorder + +.align 5 +.globl bn_mul_mont +.ent bn_mul_mont +bn_mul_mont: + .set noreorder + PTR_SUB sp,64 + move $fp,sp + .frame $fp,64,ra + slt AT,$num,4 + li v0,0 + beqzl AT,.Lproceed + nop + jr ra + PTR_ADD sp,$fp,64 + .set reorder +.align 5 +.Lproceed: + ld $n0,0($n0) + ld $bi,0($bp) # bp[0] + ld $aj,0($ap) # ap[0] + ld $nj,0($np) # np[0] + PTR_SUB sp,16 # place for two extra words + sll $num,3 + li AT,-4096 + PTR_SUB sp,$num + and sp,AT + + sd s0,0($fp) + sd s1,8($fp) + sd s2,16($fp) + sd s3,24($fp) + sd s4,32($fp) + sd s5,40($fp) + sd s6,48($fp) + sd s7,56($fp) + + dmultu $aj,$bi + ld $alo,8($ap) + ld $nlo,8($np) + mflo $lo0 + mfhi $hi0 + dmultu $lo0,$n0 + mflo $m1 + + dmultu $alo,$bi + mflo $alo + mfhi $ahi + + dmultu $nj,$m1 + mflo $lo1 + mfhi $hi1 + dmultu $nlo,$m1 + daddu $lo1,$lo0 + sltu AT,$lo1,$lo0 + daddu $hi1,AT + mflo $nlo + mfhi $nhi + + move $tp,sp + li $j,16 +.align 4 +.L1st: + .set noreorder + PTR_ADD $aj,$ap,$j + ld $aj,($aj) + PTR_ADD $nj,$np,$j + ld $nj,($nj) + + dmultu $aj,$bi + daddu $lo0,$alo,$hi0 + daddu $lo1,$nlo,$hi1 + sltu AT,$lo0,$hi0 + sltu s7,$lo1,$hi1 + daddu $hi0,$ahi,AT + daddu $hi1,$nhi,s7 + mflo $alo + mfhi $ahi + + daddu $lo1,$lo0 + sltu AT,$lo1,$lo0 + dmultu $nj,$m1 + daddu $hi1,AT + addu $j,8 + sd $lo1,($tp) + sltu s7,$j,$num + mflo $nlo + mfhi $nhi + + bnez s7,.L1st + PTR_ADD $tp,8 + .set reorder + + daddu $lo0,$alo,$hi0 + sltu AT,$lo0,$hi0 + daddu $hi0,$ahi,AT + + daddu $lo1,$nlo,$hi1 + sltu s7,$lo1,$hi1 + daddu $hi1,$nhi,s7 + daddu $lo1,$lo0 + sltu AT,$lo1,$lo0 + daddu $hi1,AT + + sd $lo1,($tp) + + daddu $hi1,$hi0 + sltu AT,$hi1,$hi0 + sd $hi1,8($tp) + sd AT,16($tp) + + li $i,8 +.align 4 +.Louter: + PTR_ADD $bi,$bp,$i + ld $bi,($bi) + ld $aj,($ap) + ld $alo,8($ap) + ld $tj,(sp) + + dmultu $aj,$bi + ld $nj,($np) + ld $nlo,8($np) + mflo $lo0 + mfhi $hi0 + daddu $lo0,$tj + dmultu $lo0,$n0 + sltu AT,$lo0,$tj + daddu $hi0,AT + mflo $m1 + + dmultu $alo,$bi + mflo $alo + mfhi $ahi + + dmultu $nj,$m1 + mflo $lo1 + mfhi $hi1 + + dmultu $nlo,$m1 + daddu $lo1,$lo0 + sltu AT,$lo1,$lo0 + daddu $hi1,AT + mflo $nlo + mfhi $nhi + + move $tp,sp + li $j,16 + ld $tj,8($tp) +.align 4 +.Linner: + .set noreorder + PTR_ADD $aj,$ap,$j + ld $aj,($aj) + PTR_ADD $nj,$np,$j + ld $nj,($nj) + + dmultu $aj,$bi + daddu $lo0,$alo,$hi0 + daddu $lo1,$nlo,$hi1 + sltu AT,$lo0,$hi0 + sltu s7,$lo1,$hi1 + daddu $hi0,$ahi,AT + daddu $hi1,$nhi,s7 + mflo $alo + mfhi $ahi + + daddu $lo0,$tj + addu $j,8 + dmultu $nj,$m1 + sltu AT,$lo0,$tj + daddu $lo1,$lo0 + daddu $hi0,AT + sltu s7,$lo1,$lo0 + ld $tj,16($tp) + daddu $hi1,s7 + sltu AT,$j,$num + mflo $nlo + mfhi $nhi + sd $lo1,($tp) + bnez AT,.Linner + PTR_ADD $tp,8 + .set reorder + + daddu $lo0,$alo,$hi0 + sltu AT,$lo0,$hi0 + daddu $hi0,$ahi,AT + daddu $lo0,$tj + sltu s7,$lo0,$tj + daddu $hi0,s7 + + ld $tj,16($tp) + daddu $lo1,$nlo,$hi1 + sltu AT,$lo1,$hi1 + daddu $hi1,$nhi,AT + daddu $lo1,$lo0 + sltu s7,$lo1,$lo0 + daddu $hi1,s7 + sd $lo1,($tp) + + daddu $lo1,$hi1,$hi0 + sltu $hi1,$lo1,$hi0 + daddu $lo1,$tj + sltu AT,$lo1,$tj + daddu $hi1,AT + sd $lo1,8($tp) + sd $hi1,16($tp) + + addu $i,8 + sltu s7,$i,$num + bnez s7,.Louter + + .set noreorder + PTR_ADD $tj,sp,$num # &tp[num] + move $tp,sp + move $ap,sp + li $hi0,0 # clear borrow bit + +.align 4 +.Lsub: ld $lo0,($tp) + ld $lo1,($np) + PTR_ADD $tp,8 + PTR_ADD $np,8 + dsubu $lo1,$lo0,$lo1 # tp[i]-np[i] + sgtu AT,$lo1,$lo0 + dsubu $lo0,$lo1,$hi0 + sgtu $hi0,$lo0,$lo1 + sd $lo0,($rp) + or $hi0,AT + sltu AT,$tp,$tj + bnez AT,.Lsub + PTR_ADD $rp,8 + + dsubu $hi0,$hi1,$hi0 # handle upmost overflow bit + move $tp,sp + PTR_SUB $rp,$num # restore rp + not $hi1,$hi0 + + and $ap,$hi0,sp + and $bp,$hi1,$rp + or $ap,$ap,$bp # ap=borrow?tp:rp + +.align 4 +.Lcopy: ld $aj,($ap) + PTR_ADD $ap,8 + PTR_ADD $tp,8 + sd zero,-8($tp) + sltu AT,$tp,$tj + sd $aj,($rp) + bnez AT,.Lcopy + PTR_ADD $rp,8 + + ld s0,0($fp) + ld s1,8($fp) + ld s2,16($fp) + ld s3,24($fp) + ld s4,32($fp) + ld s5,40($fp) + ld s6,48($fp) + ld s7,56($fp) + li v0,1 + jr ra + PTR_ADD sp,$fp,64 + .set reorder +END(bn_mul_mont) +.rdata +.asciiz "Montgomery Multiplication for MIPS III/IV, CRYPTOGAMS by " +___ + +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/modexp512-x86_64.pl b/libs/openssl/crypto/bn/asm/modexp512-x86_64.pl new file mode 100644 index 00000000..bfd6e975 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/modexp512-x86_64.pl @@ -0,0 +1,1497 @@ +#!/usr/bin/env perl +# +# Copyright (c) 2010-2011 Intel Corp. +# Author: Vinodh.Gopal@intel.com +# Jim Guilford +# Erdinc.Ozturk@intel.com +# Maxim.Perminov@intel.com +# +# More information about algorithm used can be found at: +# http://www.cse.buffalo.edu/srds2009/escs2009_submission_Gopal.pdf +# +# ==================================================================== +# Copyright (c) 2011 The OpenSSL Project. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# +# 3. All advertising materials mentioning features or use of this +# software must display the following acknowledgment: +# "This product includes software developed by the OpenSSL Project +# for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" +# +# 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to +# endorse or promote products derived from this software without +# prior written permission. For written permission, please contact +# licensing@OpenSSL.org. +# +# 5. Products derived from this software may not be called "OpenSSL" +# nor may "OpenSSL" appear in their names without prior written +# permission of the OpenSSL Project. +# +# 6. Redistributions of any form whatsoever must retain the following +# acknowledgment: +# "This product includes software developed by the OpenSSL Project +# for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" +# +# THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY +# EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR +# ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED +# OF THE POSSIBILITY OF SUCH DAMAGE. +# ==================================================================== + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +use strict; +my $code=".text\n\n"; +my $m=0; + +# +# Define x512 macros +# + +#MULSTEP_512_ADD MACRO x7, x6, x5, x4, x3, x2, x1, x0, dst, src1, src2, add_src, tmp1, tmp2 +# +# uses rax, rdx, and args +sub MULSTEP_512_ADD +{ + my ($x, $DST, $SRC2, $ASRC, $OP, $TMP)=@_; + my @X=@$x; # make a copy +$code.=<<___; + mov (+8*0)($SRC2), %rax + mul $OP # rdx:rax = %OP * [0] + mov ($ASRC), $X[0] + add %rax, $X[0] + adc \$0, %rdx + mov $X[0], $DST +___ +for(my $i=1;$i<8;$i++) { +$code.=<<___; + mov %rdx, $TMP + + mov (+8*$i)($SRC2), %rax + mul $OP # rdx:rax = %OP * [$i] + mov (+8*$i)($ASRC), $X[$i] + add %rax, $X[$i] + adc \$0, %rdx + add $TMP, $X[$i] + adc \$0, %rdx +___ +} +$code.=<<___; + mov %rdx, $X[0] +___ +} + +#MULSTEP_512 MACRO x7, x6, x5, x4, x3, x2, x1, x0, dst, src2, src1_val, tmp +# +# uses rax, rdx, and args +sub MULSTEP_512 +{ + my ($x, $DST, $SRC2, $OP, $TMP)=@_; + my @X=@$x; # make a copy +$code.=<<___; + mov (+8*0)($SRC2), %rax + mul $OP # rdx:rax = %OP * [0] + add %rax, $X[0] + adc \$0, %rdx + mov $X[0], $DST +___ +for(my $i=1;$i<8;$i++) { +$code.=<<___; + mov %rdx, $TMP + + mov (+8*$i)($SRC2), %rax + mul $OP # rdx:rax = %OP * [$i] + add %rax, $X[$i] + adc \$0, %rdx + add $TMP, $X[$i] + adc \$0, %rdx +___ +} +$code.=<<___; + mov %rdx, $X[0] +___ +} + +# +# Swizzle Macros +# + +# macro to copy data from flat space to swizzled table +#MACRO swizzle pDst, pSrc, tmp1, tmp2 +# pDst and pSrc are modified +sub swizzle +{ + my ($pDst, $pSrc, $cnt, $d0)=@_; +$code.=<<___; + mov \$8, $cnt +loop_$m: + mov ($pSrc), $d0 + mov $d0#w, ($pDst) + shr \$16, $d0 + mov $d0#w, (+64*1)($pDst) + shr \$16, $d0 + mov $d0#w, (+64*2)($pDst) + shr \$16, $d0 + mov $d0#w, (+64*3)($pDst) + lea 8($pSrc), $pSrc + lea 64*4($pDst), $pDst + dec $cnt + jnz loop_$m +___ + + $m++; +} + +# macro to copy data from swizzled table to flat space +#MACRO unswizzle pDst, pSrc, tmp*3 +sub unswizzle +{ + my ($pDst, $pSrc, $cnt, $d0, $d1)=@_; +$code.=<<___; + mov \$4, $cnt +loop_$m: + movzxw (+64*3+256*0)($pSrc), $d0 + movzxw (+64*3+256*1)($pSrc), $d1 + shl \$16, $d0 + shl \$16, $d1 + mov (+64*2+256*0)($pSrc), $d0#w + mov (+64*2+256*1)($pSrc), $d1#w + shl \$16, $d0 + shl \$16, $d1 + mov (+64*1+256*0)($pSrc), $d0#w + mov (+64*1+256*1)($pSrc), $d1#w + shl \$16, $d0 + shl \$16, $d1 + mov (+64*0+256*0)($pSrc), $d0#w + mov (+64*0+256*1)($pSrc), $d1#w + mov $d0, (+8*0)($pDst) + mov $d1, (+8*1)($pDst) + lea 256*2($pSrc), $pSrc + lea 8*2($pDst), $pDst + sub \$1, $cnt + jnz loop_$m +___ + + $m++; +} + +# +# Data Structures +# + +# Reduce Data +# +# +# Offset Value +# 0C0 Carries +# 0B8 X2[10] +# 0B0 X2[9] +# 0A8 X2[8] +# 0A0 X2[7] +# 098 X2[6] +# 090 X2[5] +# 088 X2[4] +# 080 X2[3] +# 078 X2[2] +# 070 X2[1] +# 068 X2[0] +# 060 X1[12] P[10] +# 058 X1[11] P[9] Z[8] +# 050 X1[10] P[8] Z[7] +# 048 X1[9] P[7] Z[6] +# 040 X1[8] P[6] Z[5] +# 038 X1[7] P[5] Z[4] +# 030 X1[6] P[4] Z[3] +# 028 X1[5] P[3] Z[2] +# 020 X1[4] P[2] Z[1] +# 018 X1[3] P[1] Z[0] +# 010 X1[2] P[0] Y[2] +# 008 X1[1] Q[1] Y[1] +# 000 X1[0] Q[0] Y[0] + +my $X1_offset = 0; # 13 qwords +my $X2_offset = $X1_offset + 13*8; # 11 qwords +my $Carries_offset = $X2_offset + 11*8; # 1 qword +my $Q_offset = 0; # 2 qwords +my $P_offset = $Q_offset + 2*8; # 11 qwords +my $Y_offset = 0; # 3 qwords +my $Z_offset = $Y_offset + 3*8; # 9 qwords + +my $Red_Data_Size = $Carries_offset + 1*8; # (25 qwords) + +# +# Stack Frame +# +# +# offset value +# ... +# ... +# 280 Garray + +# 278 tmp16[15] +# ... ... +# 200 tmp16[0] + +# 1F8 tmp[7] +# ... ... +# 1C0 tmp[0] + +# 1B8 GT[7] +# ... ... +# 180 GT[0] + +# 178 Reduce Data +# ... ... +# 0B8 Reduce Data +# 0B0 reserved +# 0A8 reserved +# 0A0 reserved +# 098 reserved +# 090 reserved +# 088 reduce result addr +# 080 exp[8] + +# ... +# 048 exp[1] +# 040 exp[0] + +# 038 reserved +# 030 loop_idx +# 028 pg +# 020 i +# 018 pData ; arg 4 +# 010 pG ; arg 2 +# 008 pResult ; arg 1 +# 000 rsp ; stack pointer before subtract + +my $rsp_offset = 0; +my $pResult_offset = 8*1 + $rsp_offset; +my $pG_offset = 8*1 + $pResult_offset; +my $pData_offset = 8*1 + $pG_offset; +my $i_offset = 8*1 + $pData_offset; +my $pg_offset = 8*1 + $i_offset; +my $loop_idx_offset = 8*1 + $pg_offset; +my $reserved1_offset = 8*1 + $loop_idx_offset; +my $exp_offset = 8*1 + $reserved1_offset; +my $red_result_addr_offset= 8*9 + $exp_offset; +my $reserved2_offset = 8*1 + $red_result_addr_offset; +my $Reduce_Data_offset = 8*5 + $reserved2_offset; +my $GT_offset = $Red_Data_Size + $Reduce_Data_offset; +my $tmp_offset = 8*8 + $GT_offset; +my $tmp16_offset = 8*8 + $tmp_offset; +my $garray_offset = 8*16 + $tmp16_offset; +my $mem_size = 8*8*32 + $garray_offset; + +# +# Offsets within Reduce Data +# +# +# struct MODF_2FOLD_MONT_512_C1_DATA { +# UINT64 t[8][8]; +# UINT64 m[8]; +# UINT64 m1[8]; /* 2^768 % m */ +# UINT64 m2[8]; /* 2^640 % m */ +# UINT64 k1[2]; /* (- 1/m) % 2^128 */ +# }; + +my $T = 0; +my $M = 512; # = 8 * 8 * 8 +my $M1 = 576; # = 8 * 8 * 9 /* += 8 * 8 */ +my $M2 = 640; # = 8 * 8 * 10 /* += 8 * 8 */ +my $K1 = 704; # = 8 * 8 * 11 /* += 8 * 8 */ + +# +# FUNCTIONS +# + +{{{ +# +# MULADD_128x512 : Function to multiply 128-bits (2 qwords) by 512-bits (8 qwords) +# and add 512-bits (8 qwords) +# to get 640 bits (10 qwords) +# Input: 128-bit mul source: [rdi+8*1], rbp +# 512-bit mul source: [rsi+8*n] +# 512-bit add source: r15, r14, ..., r9, r8 +# Output: r9, r8, r15, r14, r13, r12, r11, r10, [rcx+8*1], [rcx+8*0] +# Clobbers all regs except: rcx, rsi, rdi +$code.=<<___; +.type MULADD_128x512,\@abi-omnipotent +.align 16 +MULADD_128x512: +___ + &MULSTEP_512([map("%r$_",(8..15))], "(+8*0)(%rcx)", "%rsi", "%rbp", "%rbx"); +$code.=<<___; + mov (+8*1)(%rdi), %rbp +___ + &MULSTEP_512([map("%r$_",(9..15,8))], "(+8*1)(%rcx)", "%rsi", "%rbp", "%rbx"); +$code.=<<___; + ret +.size MULADD_128x512,.-MULADD_128x512 +___ +}}} + +{{{ +#MULADD_256x512 MACRO pDst, pA, pB, OP, TMP, X7, X6, X5, X4, X3, X2, X1, X0 +# +# Inputs: pDst: Destination (768 bits, 12 qwords) +# pA: Multiplicand (1024 bits, 16 qwords) +# pB: Multiplicand (512 bits, 8 qwords) +# Dst = Ah * B + Al +# where Ah is (in qwords) A[15:12] (256 bits) and Al is A[7:0] (512 bits) +# Results in X3 X2 X1 X0 X7 X6 X5 X4 Dst[3:0] +# Uses registers: arguments, RAX, RDX +sub MULADD_256x512 +{ + my ($pDst, $pA, $pB, $OP, $TMP, $X)=@_; +$code.=<<___; + mov (+8*12)($pA), $OP +___ + &MULSTEP_512_ADD($X, "(+8*0)($pDst)", $pB, $pA, $OP, $TMP); + push(@$X,shift(@$X)); + +$code.=<<___; + mov (+8*13)($pA), $OP +___ + &MULSTEP_512($X, "(+8*1)($pDst)", $pB, $OP, $TMP); + push(@$X,shift(@$X)); + +$code.=<<___; + mov (+8*14)($pA), $OP +___ + &MULSTEP_512($X, "(+8*2)($pDst)", $pB, $OP, $TMP); + push(@$X,shift(@$X)); + +$code.=<<___; + mov (+8*15)($pA), $OP +___ + &MULSTEP_512($X, "(+8*3)($pDst)", $pB, $OP, $TMP); + push(@$X,shift(@$X)); +} + +# +# mont_reduce(UINT64 *x, /* 1024 bits, 16 qwords */ +# UINT64 *m, /* 512 bits, 8 qwords */ +# MODF_2FOLD_MONT_512_C1_DATA *data, +# UINT64 *r) /* 512 bits, 8 qwords */ +# Input: x (number to be reduced): tmp16 (Implicit) +# m (modulus): [pM] (Implicit) +# data (reduce data): [pData] (Implicit) +# Output: r (result): Address in [red_res_addr] +# result also in: r9, r8, r15, r14, r13, r12, r11, r10 + +my @X=map("%r$_",(8..15)); + +$code.=<<___; +.type mont_reduce,\@abi-omnipotent +.align 16 +mont_reduce: +___ + +my $STACK_DEPTH = 8; + # + # X1 = Xh * M1 + Xl +$code.=<<___; + lea (+$Reduce_Data_offset+$X1_offset+$STACK_DEPTH)(%rsp), %rdi # pX1 (Dst) 769 bits, 13 qwords + mov (+$pData_offset+$STACK_DEPTH)(%rsp), %rsi # pM1 (Bsrc) 512 bits, 8 qwords + add \$$M1, %rsi + lea (+$tmp16_offset+$STACK_DEPTH)(%rsp), %rcx # X (Asrc) 1024 bits, 16 qwords + +___ + + &MULADD_256x512("%rdi", "%rcx", "%rsi", "%rbp", "%rbx", \@X); # rotates @X 4 times + # results in r11, r10, r9, r8, r15, r14, r13, r12, X1[3:0] + +$code.=<<___; + xor %rax, %rax + # X1 += xl + add (+8*8)(%rcx), $X[4] + adc (+8*9)(%rcx), $X[5] + adc (+8*10)(%rcx), $X[6] + adc (+8*11)(%rcx), $X[7] + adc \$0, %rax + # X1 is now rax, r11-r8, r15-r12, tmp16[3:0] + + # + # check for carry ;; carry stored in rax + mov $X[4], (+8*8)(%rdi) # rdi points to X1 + mov $X[5], (+8*9)(%rdi) + mov $X[6], %rbp + mov $X[7], (+8*11)(%rdi) + + mov %rax, (+$Reduce_Data_offset+$Carries_offset+$STACK_DEPTH)(%rsp) + + mov (+8*0)(%rdi), $X[4] + mov (+8*1)(%rdi), $X[5] + mov (+8*2)(%rdi), $X[6] + mov (+8*3)(%rdi), $X[7] + + # X1 is now stored in: X1[11], rbp, X1[9:8], r15-r8 + # rdi -> X1 + # rsi -> M1 + + # + # X2 = Xh * M2 + Xl + # do first part (X2 = Xh * M2) + add \$8*10, %rdi # rdi -> pXh ; 128 bits, 2 qwords + # Xh is actually { [rdi+8*1], rbp } + add \$`$M2-$M1`, %rsi # rsi -> M2 + lea (+$Reduce_Data_offset+$X2_offset+$STACK_DEPTH)(%rsp), %rcx # rcx -> pX2 ; 641 bits, 11 qwords +___ + unshift(@X,pop(@X)); unshift(@X,pop(@X)); +$code.=<<___; + + call MULADD_128x512 # args in rcx, rdi / rbp, rsi, r15-r8 + # result in r9, r8, r15, r14, r13, r12, r11, r10, X2[1:0] + mov (+$Reduce_Data_offset+$Carries_offset+$STACK_DEPTH)(%rsp), %rax + + # X2 += Xl + add (+8*8-8*10)(%rdi), $X[6] # (-8*10) is to adjust rdi -> Xh to Xl + adc (+8*9-8*10)(%rdi), $X[7] + mov $X[6], (+8*8)(%rcx) + mov $X[7], (+8*9)(%rcx) + + adc %rax, %rax + mov %rax, (+$Reduce_Data_offset+$Carries_offset+$STACK_DEPTH)(%rsp) + + lea (+$Reduce_Data_offset+$Q_offset+$STACK_DEPTH)(%rsp), %rdi # rdi -> pQ ; 128 bits, 2 qwords + add \$`$K1-$M2`, %rsi # rsi -> pK1 ; 128 bits, 2 qwords + + # MUL_128x128t128 rdi, rcx, rsi ; Q = X2 * K1 (bottom half) + # B1:B0 = rsi[1:0] = K1[1:0] + # A1:A0 = rcx[1:0] = X2[1:0] + # Result = rdi[1],rbp = Q[1],rbp + mov (%rsi), %r8 # B0 + mov (+8*1)(%rsi), %rbx # B1 + + mov (%rcx), %rax # A0 + mul %r8 # B0 + mov %rax, %rbp + mov %rdx, %r9 + + mov (+8*1)(%rcx), %rax # A1 + mul %r8 # B0 + add %rax, %r9 + + mov (%rcx), %rax # A0 + mul %rbx # B1 + add %rax, %r9 + + mov %r9, (+8*1)(%rdi) + # end MUL_128x128t128 + + sub \$`$K1-$M`, %rsi + + mov (%rcx), $X[6] + mov (+8*1)(%rcx), $X[7] # r9:r8 = X2[1:0] + + call MULADD_128x512 # args in rcx, rdi / rbp, rsi, r15-r8 + # result in r9, r8, r15, r14, r13, r12, r11, r10, X2[1:0] + + # load first half of m to rdx, rdi, rbx, rax + # moved this here for efficiency + mov (+8*0)(%rsi), %rax + mov (+8*1)(%rsi), %rbx + mov (+8*2)(%rsi), %rdi + mov (+8*3)(%rsi), %rdx + + # continue with reduction + mov (+$Reduce_Data_offset+$Carries_offset+$STACK_DEPTH)(%rsp), %rbp + + add (+8*8)(%rcx), $X[6] + adc (+8*9)(%rcx), $X[7] + + #accumulate the final carry to rbp + adc %rbp, %rbp + + # Add in overflow corrections: R = (X2>>128) += T[overflow] + # R = {r9, r8, r15, r14, ..., r10} + shl \$3, %rbp + mov (+$pData_offset+$STACK_DEPTH)(%rsp), %rcx # rsi -> Data (and points to T) + add %rcx, %rbp # pT ; 512 bits, 8 qwords, spread out + + # rsi will be used to generate a mask after the addition + xor %rsi, %rsi + + add (+8*8*0)(%rbp), $X[0] + adc (+8*8*1)(%rbp), $X[1] + adc (+8*8*2)(%rbp), $X[2] + adc (+8*8*3)(%rbp), $X[3] + adc (+8*8*4)(%rbp), $X[4] + adc (+8*8*5)(%rbp), $X[5] + adc (+8*8*6)(%rbp), $X[6] + adc (+8*8*7)(%rbp), $X[7] + + # if there is a carry: rsi = 0xFFFFFFFFFFFFFFFF + # if carry is clear: rsi = 0x0000000000000000 + sbb \$0, %rsi + + # if carry is clear, subtract 0. Otherwise, subtract 256 bits of m + and %rsi, %rax + and %rsi, %rbx + and %rsi, %rdi + and %rsi, %rdx + + mov \$1, %rbp + sub %rax, $X[0] + sbb %rbx, $X[1] + sbb %rdi, $X[2] + sbb %rdx, $X[3] + + # if there is a borrow: rbp = 0 + # if there is no borrow: rbp = 1 + # this is used to save the borrows in between the first half and the 2nd half of the subtraction of m + sbb \$0, %rbp + + #load second half of m to rdx, rdi, rbx, rax + + add \$$M, %rcx + mov (+8*4)(%rcx), %rax + mov (+8*5)(%rcx), %rbx + mov (+8*6)(%rcx), %rdi + mov (+8*7)(%rcx), %rdx + + # use the rsi mask as before + # if carry is clear, subtract 0. Otherwise, subtract 256 bits of m + and %rsi, %rax + and %rsi, %rbx + and %rsi, %rdi + and %rsi, %rdx + + # if rbp = 0, there was a borrow before, it is moved to the carry flag + # if rbp = 1, there was not a borrow before, carry flag is cleared + sub \$1, %rbp + + sbb %rax, $X[4] + sbb %rbx, $X[5] + sbb %rdi, $X[6] + sbb %rdx, $X[7] + + # write R back to memory + + mov (+$red_result_addr_offset+$STACK_DEPTH)(%rsp), %rsi + mov $X[0], (+8*0)(%rsi) + mov $X[1], (+8*1)(%rsi) + mov $X[2], (+8*2)(%rsi) + mov $X[3], (+8*3)(%rsi) + mov $X[4], (+8*4)(%rsi) + mov $X[5], (+8*5)(%rsi) + mov $X[6], (+8*6)(%rsi) + mov $X[7], (+8*7)(%rsi) + + ret +.size mont_reduce,.-mont_reduce +___ +}}} + +{{{ +#MUL_512x512 MACRO pDst, pA, pB, x7, x6, x5, x4, x3, x2, x1, x0, tmp*2 +# +# Inputs: pDst: Destination (1024 bits, 16 qwords) +# pA: Multiplicand (512 bits, 8 qwords) +# pB: Multiplicand (512 bits, 8 qwords) +# Uses registers rax, rdx, args +# B operand in [pB] and also in x7...x0 +sub MUL_512x512 +{ + my ($pDst, $pA, $pB, $x, $OP, $TMP, $pDst_o)=@_; + my ($pDst, $pDst_o) = ($pDst =~ m/([^+]*)\+?(.*)?/); + my @X=@$x; # make a copy + +$code.=<<___; + mov (+8*0)($pA), $OP + + mov $X[0], %rax + mul $OP # rdx:rax = %OP * [0] + mov %rax, (+$pDst_o+8*0)($pDst) + mov %rdx, $X[0] +___ +for(my $i=1;$i<8;$i++) { +$code.=<<___; + mov $X[$i], %rax + mul $OP # rdx:rax = %OP * [$i] + add %rax, $X[$i-1] + adc \$0, %rdx + mov %rdx, $X[$i] +___ +} + +for(my $i=1;$i<8;$i++) { +$code.=<<___; + mov (+8*$i)($pA), $OP +___ + + &MULSTEP_512(\@X, "(+$pDst_o+8*$i)($pDst)", $pB, $OP, $TMP); + push(@X,shift(@X)); +} + +$code.=<<___; + mov $X[0], (+$pDst_o+8*8)($pDst) + mov $X[1], (+$pDst_o+8*9)($pDst) + mov $X[2], (+$pDst_o+8*10)($pDst) + mov $X[3], (+$pDst_o+8*11)($pDst) + mov $X[4], (+$pDst_o+8*12)($pDst) + mov $X[5], (+$pDst_o+8*13)($pDst) + mov $X[6], (+$pDst_o+8*14)($pDst) + mov $X[7], (+$pDst_o+8*15)($pDst) +___ +} + +# +# mont_mul_a3b : subroutine to compute (Src1 * Src2) % M (all 512-bits) +# Input: src1: Address of source 1: rdi +# src2: Address of source 2: rsi +# Output: dst: Address of destination: [red_res_addr] +# src2 and result also in: r9, r8, r15, r14, r13, r12, r11, r10 +# Temp: Clobbers [tmp16], all registers +$code.=<<___; +.type mont_mul_a3b,\@abi-omnipotent +.align 16 +mont_mul_a3b: + # + # multiply tmp = src1 * src2 + # For multiply: dst = rcx, src1 = rdi, src2 = rsi + # stack depth is extra 8 from call +___ + &MUL_512x512("%rsp+$tmp16_offset+8", "%rdi", "%rsi", [map("%r$_",(10..15,8..9))], "%rbp", "%rbx"); +$code.=<<___; + # + # Dst = tmp % m + # Call reduce(tmp, m, data, dst) + + # tail recursion optimization: jmp to mont_reduce and return from there + jmp mont_reduce + # call mont_reduce + # ret +.size mont_mul_a3b,.-mont_mul_a3b +___ +}}} + +{{{ +#SQR_512 MACRO pDest, pA, x7, x6, x5, x4, x3, x2, x1, x0, tmp*4 +# +# Input in memory [pA] and also in x7...x0 +# Uses all argument registers plus rax and rdx +# +# This version computes all of the off-diagonal terms into memory, +# and then it adds in the diagonal terms + +sub SQR_512 +{ + my ($pDst, $pA, $x, $A, $tmp, $x7, $x6, $pDst_o)=@_; + my ($pDst, $pDst_o) = ($pDst =~ m/([^+]*)\+?(.*)?/); + my @X=@$x; # make a copy +$code.=<<___; + # ------------------ + # first pass 01...07 + # ------------------ + mov $X[0], $A + + mov $X[1],%rax + mul $A + mov %rax, (+$pDst_o+8*1)($pDst) +___ +for(my $i=2;$i<8;$i++) { +$code.=<<___; + mov %rdx, $X[$i-2] + mov $X[$i],%rax + mul $A + add %rax, $X[$i-2] + adc \$0, %rdx +___ +} +$code.=<<___; + mov %rdx, $x7 + + mov $X[0], (+$pDst_o+8*2)($pDst) + + # ------------------ + # second pass 12...17 + # ------------------ + + mov (+8*1)($pA), $A + + mov (+8*2)($pA),%rax + mul $A + add %rax, $X[1] + adc \$0, %rdx + mov $X[1], (+$pDst_o+8*3)($pDst) + + mov %rdx, $X[0] + mov (+8*3)($pA),%rax + mul $A + add %rax, $X[2] + adc \$0, %rdx + add $X[0], $X[2] + adc \$0, %rdx + mov $X[2], (+$pDst_o+8*4)($pDst) + + mov %rdx, $X[0] + mov (+8*4)($pA),%rax + mul $A + add %rax, $X[3] + adc \$0, %rdx + add $X[0], $X[3] + adc \$0, %rdx + + mov %rdx, $X[0] + mov (+8*5)($pA),%rax + mul $A + add %rax, $X[4] + adc \$0, %rdx + add $X[0], $X[4] + adc \$0, %rdx + + mov %rdx, $X[0] + mov $X[6],%rax + mul $A + add %rax, $X[5] + adc \$0, %rdx + add $X[0], $X[5] + adc \$0, %rdx + + mov %rdx, $X[0] + mov $X[7],%rax + mul $A + add %rax, $x7 + adc \$0, %rdx + add $X[0], $x7 + adc \$0, %rdx + + mov %rdx, $X[1] + + # ------------------ + # third pass 23...27 + # ------------------ + mov (+8*2)($pA), $A + + mov (+8*3)($pA),%rax + mul $A + add %rax, $X[3] + adc \$0, %rdx + mov $X[3], (+$pDst_o+8*5)($pDst) + + mov %rdx, $X[0] + mov (+8*4)($pA),%rax + mul $A + add %rax, $X[4] + adc \$0, %rdx + add $X[0], $X[4] + adc \$0, %rdx + mov $X[4], (+$pDst_o+8*6)($pDst) + + mov %rdx, $X[0] + mov (+8*5)($pA),%rax + mul $A + add %rax, $X[5] + adc \$0, %rdx + add $X[0], $X[5] + adc \$0, %rdx + + mov %rdx, $X[0] + mov $X[6],%rax + mul $A + add %rax, $x7 + adc \$0, %rdx + add $X[0], $x7 + adc \$0, %rdx + + mov %rdx, $X[0] + mov $X[7],%rax + mul $A + add %rax, $X[1] + adc \$0, %rdx + add $X[0], $X[1] + adc \$0, %rdx + + mov %rdx, $X[2] + + # ------------------ + # fourth pass 34...37 + # ------------------ + + mov (+8*3)($pA), $A + + mov (+8*4)($pA),%rax + mul $A + add %rax, $X[5] + adc \$0, %rdx + mov $X[5], (+$pDst_o+8*7)($pDst) + + mov %rdx, $X[0] + mov (+8*5)($pA),%rax + mul $A + add %rax, $x7 + adc \$0, %rdx + add $X[0], $x7 + adc \$0, %rdx + mov $x7, (+$pDst_o+8*8)($pDst) + + mov %rdx, $X[0] + mov $X[6],%rax + mul $A + add %rax, $X[1] + adc \$0, %rdx + add $X[0], $X[1] + adc \$0, %rdx + + mov %rdx, $X[0] + mov $X[7],%rax + mul $A + add %rax, $X[2] + adc \$0, %rdx + add $X[0], $X[2] + adc \$0, %rdx + + mov %rdx, $X[5] + + # ------------------ + # fifth pass 45...47 + # ------------------ + mov (+8*4)($pA), $A + + mov (+8*5)($pA),%rax + mul $A + add %rax, $X[1] + adc \$0, %rdx + mov $X[1], (+$pDst_o+8*9)($pDst) + + mov %rdx, $X[0] + mov $X[6],%rax + mul $A + add %rax, $X[2] + adc \$0, %rdx + add $X[0], $X[2] + adc \$0, %rdx + mov $X[2], (+$pDst_o+8*10)($pDst) + + mov %rdx, $X[0] + mov $X[7],%rax + mul $A + add %rax, $X[5] + adc \$0, %rdx + add $X[0], $X[5] + adc \$0, %rdx + + mov %rdx, $X[1] + + # ------------------ + # sixth pass 56...57 + # ------------------ + mov (+8*5)($pA), $A + + mov $X[6],%rax + mul $A + add %rax, $X[5] + adc \$0, %rdx + mov $X[5], (+$pDst_o+8*11)($pDst) + + mov %rdx, $X[0] + mov $X[7],%rax + mul $A + add %rax, $X[1] + adc \$0, %rdx + add $X[0], $X[1] + adc \$0, %rdx + mov $X[1], (+$pDst_o+8*12)($pDst) + + mov %rdx, $X[2] + + # ------------------ + # seventh pass 67 + # ------------------ + mov $X[6], $A + + mov $X[7],%rax + mul $A + add %rax, $X[2] + adc \$0, %rdx + mov $X[2], (+$pDst_o+8*13)($pDst) + + mov %rdx, (+$pDst_o+8*14)($pDst) + + # start finalize (add in squares, and double off-terms) + mov (+$pDst_o+8*1)($pDst), $X[0] + mov (+$pDst_o+8*2)($pDst), $X[1] + mov (+$pDst_o+8*3)($pDst), $X[2] + mov (+$pDst_o+8*4)($pDst), $X[3] + mov (+$pDst_o+8*5)($pDst), $X[4] + mov (+$pDst_o+8*6)($pDst), $X[5] + + mov (+8*3)($pA), %rax + mul %rax + mov %rax, $x6 + mov %rdx, $X[6] + + add $X[0], $X[0] + adc $X[1], $X[1] + adc $X[2], $X[2] + adc $X[3], $X[3] + adc $X[4], $X[4] + adc $X[5], $X[5] + adc \$0, $X[6] + + mov (+8*0)($pA), %rax + mul %rax + mov %rax, (+$pDst_o+8*0)($pDst) + mov %rdx, $A + + mov (+8*1)($pA), %rax + mul %rax + + add $A, $X[0] + adc %rax, $X[1] + adc \$0, %rdx + + mov %rdx, $A + mov $X[0], (+$pDst_o+8*1)($pDst) + mov $X[1], (+$pDst_o+8*2)($pDst) + + mov (+8*2)($pA), %rax + mul %rax + + add $A, $X[2] + adc %rax, $X[3] + adc \$0, %rdx + + mov %rdx, $A + + mov $X[2], (+$pDst_o+8*3)($pDst) + mov $X[3], (+$pDst_o+8*4)($pDst) + + xor $tmp, $tmp + add $A, $X[4] + adc $x6, $X[5] + adc \$0, $tmp + + mov $X[4], (+$pDst_o+8*5)($pDst) + mov $X[5], (+$pDst_o+8*6)($pDst) + + # %%tmp has 0/1 in column 7 + # %%A6 has a full value in column 7 + + mov (+$pDst_o+8*7)($pDst), $X[0] + mov (+$pDst_o+8*8)($pDst), $X[1] + mov (+$pDst_o+8*9)($pDst), $X[2] + mov (+$pDst_o+8*10)($pDst), $X[3] + mov (+$pDst_o+8*11)($pDst), $X[4] + mov (+$pDst_o+8*12)($pDst), $X[5] + mov (+$pDst_o+8*13)($pDst), $x6 + mov (+$pDst_o+8*14)($pDst), $x7 + + mov $X[7], %rax + mul %rax + mov %rax, $X[7] + mov %rdx, $A + + add $X[0], $X[0] + adc $X[1], $X[1] + adc $X[2], $X[2] + adc $X[3], $X[3] + adc $X[4], $X[4] + adc $X[5], $X[5] + adc $x6, $x6 + adc $x7, $x7 + adc \$0, $A + + add $tmp, $X[0] + + mov (+8*4)($pA), %rax + mul %rax + + add $X[6], $X[0] + adc %rax, $X[1] + adc \$0, %rdx + + mov %rdx, $tmp + + mov $X[0], (+$pDst_o+8*7)($pDst) + mov $X[1], (+$pDst_o+8*8)($pDst) + + mov (+8*5)($pA), %rax + mul %rax + + add $tmp, $X[2] + adc %rax, $X[3] + adc \$0, %rdx + + mov %rdx, $tmp + + mov $X[2], (+$pDst_o+8*9)($pDst) + mov $X[3], (+$pDst_o+8*10)($pDst) + + mov (+8*6)($pA), %rax + mul %rax + + add $tmp, $X[4] + adc %rax, $X[5] + adc \$0, %rdx + + mov $X[4], (+$pDst_o+8*11)($pDst) + mov $X[5], (+$pDst_o+8*12)($pDst) + + add %rdx, $x6 + adc $X[7], $x7 + adc \$0, $A + + mov $x6, (+$pDst_o+8*13)($pDst) + mov $x7, (+$pDst_o+8*14)($pDst) + mov $A, (+$pDst_o+8*15)($pDst) +___ +} + +# +# sqr_reduce: subroutine to compute Result = reduce(Result * Result) +# +# input and result also in: r9, r8, r15, r14, r13, r12, r11, r10 +# +$code.=<<___; +.type sqr_reduce,\@abi-omnipotent +.align 16 +sqr_reduce: + mov (+$pResult_offset+8)(%rsp), %rcx +___ + &SQR_512("%rsp+$tmp16_offset+8", "%rcx", [map("%r$_",(10..15,8..9))], "%rbx", "%rbp", "%rsi", "%rdi"); +$code.=<<___; + # tail recursion optimization: jmp to mont_reduce and return from there + jmp mont_reduce + # call mont_reduce + # ret +.size sqr_reduce,.-sqr_reduce +___ +}}} + +# +# MAIN FUNCTION +# + +#mod_exp_512(UINT64 *result, /* 512 bits, 8 qwords */ +# UINT64 *g, /* 512 bits, 8 qwords */ +# UINT64 *exp, /* 512 bits, 8 qwords */ +# struct mod_ctx_512 *data) + +# window size = 5 +# table size = 2^5 = 32 +#table_entries equ 32 +#table_size equ table_entries * 8 +$code.=<<___; +.globl mod_exp_512 +.type mod_exp_512,\@function,4 +mod_exp_512: + push %rbp + push %rbx + push %r12 + push %r13 + push %r14 + push %r15 + + # adjust stack down and then align it with cache boundary + mov %rsp, %r8 + sub \$$mem_size, %rsp + and \$-64, %rsp + + # store previous stack pointer and arguments + mov %r8, (+$rsp_offset)(%rsp) + mov %rdi, (+$pResult_offset)(%rsp) + mov %rsi, (+$pG_offset)(%rsp) + mov %rcx, (+$pData_offset)(%rsp) +.Lbody: + # transform g into montgomery space + # GT = reduce(g * C2) = reduce(g * (2^256)) + # reduce expects to have the input in [tmp16] + pxor %xmm4, %xmm4 + movdqu (+16*0)(%rsi), %xmm0 + movdqu (+16*1)(%rsi), %xmm1 + movdqu (+16*2)(%rsi), %xmm2 + movdqu (+16*3)(%rsi), %xmm3 + movdqa %xmm4, (+$tmp16_offset+16*0)(%rsp) + movdqa %xmm4, (+$tmp16_offset+16*1)(%rsp) + movdqa %xmm4, (+$tmp16_offset+16*6)(%rsp) + movdqa %xmm4, (+$tmp16_offset+16*7)(%rsp) + movdqa %xmm0, (+$tmp16_offset+16*2)(%rsp) + movdqa %xmm1, (+$tmp16_offset+16*3)(%rsp) + movdqa %xmm2, (+$tmp16_offset+16*4)(%rsp) + movdqa %xmm3, (+$tmp16_offset+16*5)(%rsp) + + # load pExp before rdx gets blown away + movdqu (+16*0)(%rdx), %xmm0 + movdqu (+16*1)(%rdx), %xmm1 + movdqu (+16*2)(%rdx), %xmm2 + movdqu (+16*3)(%rdx), %xmm3 + + lea (+$GT_offset)(%rsp), %rbx + mov %rbx, (+$red_result_addr_offset)(%rsp) + call mont_reduce + + # Initialize tmp = C + lea (+$tmp_offset)(%rsp), %rcx + xor %rax, %rax + mov %rax, (+8*0)(%rcx) + mov %rax, (+8*1)(%rcx) + mov %rax, (+8*3)(%rcx) + mov %rax, (+8*4)(%rcx) + mov %rax, (+8*5)(%rcx) + mov %rax, (+8*6)(%rcx) + mov %rax, (+8*7)(%rcx) + mov %rax, (+$exp_offset+8*8)(%rsp) + movq \$1, (+8*2)(%rcx) + + lea (+$garray_offset)(%rsp), %rbp + mov %rcx, %rsi # pTmp + mov %rbp, %rdi # Garray[][0] +___ + + &swizzle("%rdi", "%rcx", "%rax", "%rbx"); + + # for (rax = 31; rax != 0; rax--) { + # tmp = reduce(tmp * G) + # swizzle(pg, tmp); + # pg += 2; } +$code.=<<___; + mov \$31, %rax + mov %rax, (+$i_offset)(%rsp) + mov %rbp, (+$pg_offset)(%rsp) + # rsi -> pTmp + mov %rsi, (+$red_result_addr_offset)(%rsp) + mov (+8*0)(%rsi), %r10 + mov (+8*1)(%rsi), %r11 + mov (+8*2)(%rsi), %r12 + mov (+8*3)(%rsi), %r13 + mov (+8*4)(%rsi), %r14 + mov (+8*5)(%rsi), %r15 + mov (+8*6)(%rsi), %r8 + mov (+8*7)(%rsi), %r9 +init_loop: + lea (+$GT_offset)(%rsp), %rdi + call mont_mul_a3b + lea (+$tmp_offset)(%rsp), %rsi + mov (+$pg_offset)(%rsp), %rbp + add \$2, %rbp + mov %rbp, (+$pg_offset)(%rsp) + mov %rsi, %rcx # rcx = rsi = addr of tmp +___ + + &swizzle("%rbp", "%rcx", "%rax", "%rbx"); +$code.=<<___; + mov (+$i_offset)(%rsp), %rax + sub \$1, %rax + mov %rax, (+$i_offset)(%rsp) + jne init_loop + + # + # Copy exponent onto stack + movdqa %xmm0, (+$exp_offset+16*0)(%rsp) + movdqa %xmm1, (+$exp_offset+16*1)(%rsp) + movdqa %xmm2, (+$exp_offset+16*2)(%rsp) + movdqa %xmm3, (+$exp_offset+16*3)(%rsp) + + + # + # Do exponentiation + # Initialize result to G[exp{511:507}] + mov (+$exp_offset+62)(%rsp), %eax + mov %rax, %rdx + shr \$11, %rax + and \$0x07FF, %edx + mov %edx, (+$exp_offset+62)(%rsp) + lea (+$garray_offset)(%rsp,%rax,2), %rsi + mov (+$pResult_offset)(%rsp), %rdx +___ + + &unswizzle("%rdx", "%rsi", "%rbp", "%rbx", "%rax"); + + # + # Loop variables + # rcx = [loop_idx] = index: 510-5 to 0 by 5 +$code.=<<___; + movq \$505, (+$loop_idx_offset)(%rsp) + + mov (+$pResult_offset)(%rsp), %rcx + mov %rcx, (+$red_result_addr_offset)(%rsp) + mov (+8*0)(%rcx), %r10 + mov (+8*1)(%rcx), %r11 + mov (+8*2)(%rcx), %r12 + mov (+8*3)(%rcx), %r13 + mov (+8*4)(%rcx), %r14 + mov (+8*5)(%rcx), %r15 + mov (+8*6)(%rcx), %r8 + mov (+8*7)(%rcx), %r9 + jmp sqr_2 + +main_loop_a3b: + call sqr_reduce + call sqr_reduce + call sqr_reduce +sqr_2: + call sqr_reduce + call sqr_reduce + + # + # Do multiply, first look up proper value in Garray + mov (+$loop_idx_offset)(%rsp), %rcx # bit index + mov %rcx, %rax + shr \$4, %rax # rax is word pointer + mov (+$exp_offset)(%rsp,%rax,2), %edx + and \$15, %rcx + shrq %cl, %rdx + and \$0x1F, %rdx + + lea (+$garray_offset)(%rsp,%rdx,2), %rsi + lea (+$tmp_offset)(%rsp), %rdx + mov %rdx, %rdi +___ + + &unswizzle("%rdx", "%rsi", "%rbp", "%rbx", "%rax"); + # rdi = tmp = pG + + # + # Call mod_mul_a1(pDst, pSrc1, pSrc2, pM, pData) + # result result pG M Data +$code.=<<___; + mov (+$pResult_offset)(%rsp), %rsi + call mont_mul_a3b + + # + # finish loop + mov (+$loop_idx_offset)(%rsp), %rcx + sub \$5, %rcx + mov %rcx, (+$loop_idx_offset)(%rsp) + jge main_loop_a3b + + # + +end_main_loop_a3b: + # transform result out of Montgomery space + # result = reduce(result) + mov (+$pResult_offset)(%rsp), %rdx + pxor %xmm4, %xmm4 + movdqu (+16*0)(%rdx), %xmm0 + movdqu (+16*1)(%rdx), %xmm1 + movdqu (+16*2)(%rdx), %xmm2 + movdqu (+16*3)(%rdx), %xmm3 + movdqa %xmm4, (+$tmp16_offset+16*4)(%rsp) + movdqa %xmm4, (+$tmp16_offset+16*5)(%rsp) + movdqa %xmm4, (+$tmp16_offset+16*6)(%rsp) + movdqa %xmm4, (+$tmp16_offset+16*7)(%rsp) + movdqa %xmm0, (+$tmp16_offset+16*0)(%rsp) + movdqa %xmm1, (+$tmp16_offset+16*1)(%rsp) + movdqa %xmm2, (+$tmp16_offset+16*2)(%rsp) + movdqa %xmm3, (+$tmp16_offset+16*3)(%rsp) + call mont_reduce + + # If result > m, subract m + # load result into r15:r8 + mov (+$pResult_offset)(%rsp), %rax + mov (+8*0)(%rax), %r8 + mov (+8*1)(%rax), %r9 + mov (+8*2)(%rax), %r10 + mov (+8*3)(%rax), %r11 + mov (+8*4)(%rax), %r12 + mov (+8*5)(%rax), %r13 + mov (+8*6)(%rax), %r14 + mov (+8*7)(%rax), %r15 + + # subtract m + mov (+$pData_offset)(%rsp), %rbx + add \$$M, %rbx + + sub (+8*0)(%rbx), %r8 + sbb (+8*1)(%rbx), %r9 + sbb (+8*2)(%rbx), %r10 + sbb (+8*3)(%rbx), %r11 + sbb (+8*4)(%rbx), %r12 + sbb (+8*5)(%rbx), %r13 + sbb (+8*6)(%rbx), %r14 + sbb (+8*7)(%rbx), %r15 + + # if Carry is clear, replace result with difference + mov (+8*0)(%rax), %rsi + mov (+8*1)(%rax), %rdi + mov (+8*2)(%rax), %rcx + mov (+8*3)(%rax), %rdx + cmovnc %r8, %rsi + cmovnc %r9, %rdi + cmovnc %r10, %rcx + cmovnc %r11, %rdx + mov %rsi, (+8*0)(%rax) + mov %rdi, (+8*1)(%rax) + mov %rcx, (+8*2)(%rax) + mov %rdx, (+8*3)(%rax) + + mov (+8*4)(%rax), %rsi + mov (+8*5)(%rax), %rdi + mov (+8*6)(%rax), %rcx + mov (+8*7)(%rax), %rdx + cmovnc %r12, %rsi + cmovnc %r13, %rdi + cmovnc %r14, %rcx + cmovnc %r15, %rdx + mov %rsi, (+8*4)(%rax) + mov %rdi, (+8*5)(%rax) + mov %rcx, (+8*6)(%rax) + mov %rdx, (+8*7)(%rax) + + mov (+$rsp_offset)(%rsp), %rsi + mov 0(%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 + mov 24(%rsi),%r12 + mov 32(%rsi),%rbx + mov 40(%rsi),%rbp + lea 48(%rsi),%rsp +.Lepilogue: + ret +.size mod_exp_512, . - mod_exp_512 +___ + +if ($win64) { +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +my $rec="%rcx"; +my $frame="%rdx"; +my $context="%r8"; +my $disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type mod_exp_512_se_handler,\@abi-omnipotent +.align 16 +mod_exp_512_se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + lea .Lbody(%rip),%r10 + cmp %r10,%rbx # context->RipRsp + + lea .Lepilogue(%rip),%r10 + cmp %r10,%rbx # context->Rip>=epilogue label + jae .Lin_prologue + + mov $rsp_offset(%rax),%rax # pull saved Rsp + + mov 32(%rax),%rbx + mov 40(%rax),%rbp + mov 24(%rax),%r12 + mov 16(%rax),%r13 + mov 8(%rax),%r14 + mov 0(%rax),%r15 + lea 48(%rax),%rax + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + +.Lin_prologue: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$154,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size mod_exp_512_se_handler,.-mod_exp_512_se_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_mod_exp_512 + .rva .LSEH_end_mod_exp_512 + .rva .LSEH_info_mod_exp_512 + +.section .xdata +.align 8 +.LSEH_info_mod_exp_512: + .byte 9,0,0,0 + .rva mod_exp_512_se_handler +___ +} + +sub reg_part { +my ($reg,$conv)=@_; + if ($reg =~ /%r[0-9]+/) { $reg .= $conv; } + elsif ($conv eq "b") { $reg =~ s/%[er]([^x]+)x?/%$1l/; } + elsif ($conv eq "w") { $reg =~ s/%[er](.+)/%$1/; } + elsif ($conv eq "d") { $reg =~ s/%[er](.+)/%e$1/; } + return $reg; +} + +$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem; +$code =~ s/\`([^\`]*)\`/eval $1/gem; +$code =~ s/(\(\+[^)]+\))/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/pa-risc2.s b/libs/openssl/crypto/bn/asm/pa-risc2.s new file mode 100644 index 00000000..f3b16290 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/pa-risc2.s @@ -0,0 +1,1618 @@ +; +; PA-RISC 2.0 implementation of bn_asm code, based on the +; 64-bit version of the code. This code is effectively the +; same as the 64-bit version except the register model is +; slightly different given all values must be 32-bit between +; function calls. Thus the 64-bit return values are returned +; in %ret0 and %ret1 vs just %ret0 as is done in 64-bit +; +; +; This code is approximately 2x faster than the C version +; for RSA/DSA. +; +; See http://devresource.hp.com/ for more details on the PA-RISC +; architecture. Also see the book "PA-RISC 2.0 Architecture" +; by Gerry Kane for information on the instruction set architecture. +; +; Code written by Chris Ruemmler (with some help from the HP C +; compiler). +; +; The code compiles with HP's assembler +; + + .level 2.0N + .space $TEXT$ + .subspa $CODE$,QUAD=0,ALIGN=8,ACCESS=0x2c,CODE_ONLY + +; +; Global Register definitions used for the routines. +; +; Some information about HP's runtime architecture for 32-bits. +; +; "Caller save" means the calling function must save the register +; if it wants the register to be preserved. +; "Callee save" means if a function uses the register, it must save +; the value before using it. +; +; For the floating point registers +; +; "caller save" registers: fr4-fr11, fr22-fr31 +; "callee save" registers: fr12-fr21 +; "special" registers: fr0-fr3 (status and exception registers) +; +; For the integer registers +; value zero : r0 +; "caller save" registers: r1,r19-r26 +; "callee save" registers: r3-r18 +; return register : r2 (rp) +; return values ; r28,r29 (ret0,ret1) +; Stack pointer ; r30 (sp) +; millicode return ptr ; r31 (also a caller save register) + + +; +; Arguments to the routines +; +r_ptr .reg %r26 +a_ptr .reg %r25 +b_ptr .reg %r24 +num .reg %r24 +n .reg %r23 + +; +; Note that the "w" argument for bn_mul_add_words and bn_mul_words +; is passed on the stack at a delta of -56 from the top of stack +; as the routine is entered. +; + +; +; Globals used in some routines +; + +top_overflow .reg %r23 +high_mask .reg %r22 ; value 0xffffffff80000000L + + +;------------------------------------------------------------------------------ +; +; bn_mul_add_words +; +;BN_ULONG bn_mul_add_words(BN_ULONG *r_ptr, BN_ULONG *a_ptr, +; int num, BN_ULONG w) +; +; arg0 = r_ptr +; arg1 = a_ptr +; arg3 = num +; -56(sp) = w +; +; Local register definitions +; + +fm1 .reg %fr22 +fm .reg %fr23 +ht_temp .reg %fr24 +ht_temp_1 .reg %fr25 +lt_temp .reg %fr26 +lt_temp_1 .reg %fr27 +fm1_1 .reg %fr28 +fm_1 .reg %fr29 + +fw_h .reg %fr7L +fw_l .reg %fr7R +fw .reg %fr7 + +fht_0 .reg %fr8L +flt_0 .reg %fr8R +t_float_0 .reg %fr8 + +fht_1 .reg %fr9L +flt_1 .reg %fr9R +t_float_1 .reg %fr9 + +tmp_0 .reg %r31 +tmp_1 .reg %r21 +m_0 .reg %r20 +m_1 .reg %r19 +ht_0 .reg %r1 +ht_1 .reg %r3 +lt_0 .reg %r4 +lt_1 .reg %r5 +m1_0 .reg %r6 +m1_1 .reg %r7 +rp_val .reg %r8 +rp_val_1 .reg %r9 + +bn_mul_add_words + .export bn_mul_add_words,entry,NO_RELOCATION,LONG_RETURN + .proc + .callinfo frame=128 + .entry + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + NOP ; Needed to make the loop 16-byte aligned + NOP ; needed to make the loop 16-byte aligned + + STD %r5,16(%sp) ; save r5 + NOP + STD %r6,24(%sp) ; save r6 + STD %r7,32(%sp) ; save r7 + + STD %r8,40(%sp) ; save r8 + STD %r9,48(%sp) ; save r9 + COPY %r0,%ret1 ; return 0 by default + DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32 + + CMPIB,>= 0,num,bn_mul_add_words_exit ; if (num <= 0) then exit + LDO 128(%sp),%sp ; bump stack + + ; + ; The loop is unrolled twice, so if there is only 1 number + ; then go straight to the cleanup code. + ; + CMPIB,= 1,num,bn_mul_add_words_single_top + FLDD -184(%sp),fw ; (-56-128) load up w into fw (fw_h/fw_l) + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; + ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus + ; two 32-bit mutiplies can be issued per cycle. + ; +bn_mul_add_words_unroll2 + + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + FLDD 8(a_ptr),t_float_1 ; load up 64-bit value (fr8L) ht(L)/lt(R) + LDD 0(r_ptr),rp_val ; rp[0] + LDD 8(r_ptr),rp_val_1 ; rp[1] + + XMPYU fht_0,fw_l,fm1 ; m1[0] = fht_0*fw_l + XMPYU fht_1,fw_l,fm1_1 ; m1[1] = fht_1*fw_l + FSTD fm1,-16(%sp) ; -16(sp) = m1[0] + FSTD fm1_1,-48(%sp) ; -48(sp) = m1[1] + + XMPYU flt_0,fw_h,fm ; m[0] = flt_0*fw_h + XMPYU flt_1,fw_h,fm_1 ; m[1] = flt_1*fw_h + FSTD fm,-8(%sp) ; -8(sp) = m[0] + FSTD fm_1,-40(%sp) ; -40(sp) = m[1] + + XMPYU fht_0,fw_h,ht_temp ; ht_temp = fht_0*fw_h + XMPYU fht_1,fw_h,ht_temp_1 ; ht_temp_1 = fht_1*fw_h + FSTD ht_temp,-24(%sp) ; -24(sp) = ht_temp + FSTD ht_temp_1,-56(%sp) ; -56(sp) = ht_temp_1 + + XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l + XMPYU flt_1,fw_l,lt_temp_1 ; lt_temp = lt*fw_l + FSTD lt_temp,-32(%sp) ; -32(sp) = lt_temp + FSTD lt_temp_1,-64(%sp) ; -64(sp) = lt_temp_1 + + LDD -8(%sp),m_0 ; m[0] + LDD -40(%sp),m_1 ; m[1] + LDD -16(%sp),m1_0 ; m1[0] + LDD -48(%sp),m1_1 ; m1[1] + + LDD -24(%sp),ht_0 ; ht[0] + LDD -56(%sp),ht_1 ; ht[1] + ADD,L m1_0,m_0,tmp_0 ; tmp_0 = m[0] + m1[0]; + ADD,L m1_1,m_1,tmp_1 ; tmp_1 = m[1] + m1[1]; + + LDD -32(%sp),lt_0 + LDD -64(%sp),lt_1 + CMPCLR,*>>= tmp_0,m1_0, %r0 ; if (m[0] < m1[0]) + ADD,L ht_0,top_overflow,ht_0 ; ht[0] += (1<<32) + + CMPCLR,*>>= tmp_1,m1_1,%r0 ; if (m[1] < m1[1]) + ADD,L ht_1,top_overflow,ht_1 ; ht[1] += (1<<32) + EXTRD,U tmp_0,31,32,m_0 ; m[0]>>32 + DEPD,Z tmp_0,31,32,m1_0 ; m1[0] = m[0]<<32 + + EXTRD,U tmp_1,31,32,m_1 ; m[1]>>32 + DEPD,Z tmp_1,31,32,m1_1 ; m1[1] = m[1]<<32 + ADD,L ht_0,m_0,ht_0 ; ht[0]+= (m[0]>>32) + ADD,L ht_1,m_1,ht_1 ; ht[1]+= (m[1]>>32) + + ADD lt_0,m1_0,lt_0 ; lt[0] = lt[0]+m1[0]; + ADD,DC ht_0,%r0,ht_0 ; ht[0]++ + ADD lt_1,m1_1,lt_1 ; lt[1] = lt[1]+m1[1]; + ADD,DC ht_1,%r0,ht_1 ; ht[1]++ + + ADD %ret1,lt_0,lt_0 ; lt[0] = lt[0] + c; + ADD,DC ht_0,%r0,ht_0 ; ht[0]++ + ADD lt_0,rp_val,lt_0 ; lt[0] = lt[0]+rp[0] + ADD,DC ht_0,%r0,ht_0 ; ht[0]++ + + LDO -2(num),num ; num = num - 2; + ADD ht_0,lt_1,lt_1 ; lt[1] = lt[1] + ht_0 (c); + ADD,DC ht_1,%r0,ht_1 ; ht[1]++ + STD lt_0,0(r_ptr) ; rp[0] = lt[0] + + ADD lt_1,rp_val_1,lt_1 ; lt[1] = lt[1]+rp[1] + ADD,DC ht_1,%r0,%ret1 ; ht[1]++ + LDO 16(a_ptr),a_ptr ; a_ptr += 2 + + STD lt_1,8(r_ptr) ; rp[1] = lt[1] + CMPIB,<= 2,num,bn_mul_add_words_unroll2 ; go again if more to do + LDO 16(r_ptr),r_ptr ; r_ptr += 2 + + CMPIB,=,N 0,num,bn_mul_add_words_exit ; are we done, or cleanup last one + + ; + ; Top of loop aligned on 64-byte boundary + ; +bn_mul_add_words_single_top + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + LDD 0(r_ptr),rp_val ; rp[0] + LDO 8(a_ptr),a_ptr ; a_ptr++ + XMPYU fht_0,fw_l,fm1 ; m1 = ht*fw_l + FSTD fm1,-16(%sp) ; -16(sp) = m1 + XMPYU flt_0,fw_h,fm ; m = lt*fw_h + FSTD fm,-8(%sp) ; -8(sp) = m + XMPYU fht_0,fw_h,ht_temp ; ht_temp = ht*fw_h + FSTD ht_temp,-24(%sp) ; -24(sp) = ht + XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l + FSTD lt_temp,-32(%sp) ; -32(sp) = lt + + LDD -8(%sp),m_0 + LDD -16(%sp),m1_0 ; m1 = temp1 + ADD,L m_0,m1_0,tmp_0 ; tmp_0 = m + m1; + LDD -24(%sp),ht_0 + LDD -32(%sp),lt_0 + + CMPCLR,*>>= tmp_0,m1_0,%r0 ; if (m < m1) + ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32) + + EXTRD,U tmp_0,31,32,m_0 ; m>>32 + DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32 + + ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32) + ADD lt_0,m1_0,tmp_0 ; tmp_0 = lt+m1; + ADD,DC ht_0,%r0,ht_0 ; ht++ + ADD %ret1,tmp_0,lt_0 ; lt = lt + c; + ADD,DC ht_0,%r0,ht_0 ; ht++ + ADD lt_0,rp_val,lt_0 ; lt = lt+rp[0] + ADD,DC ht_0,%r0,%ret1 ; ht++ + STD lt_0,0(r_ptr) ; rp[0] = lt + +bn_mul_add_words_exit + .EXIT + + EXTRD,U %ret1,31,32,%ret0 ; for 32-bit, return in ret0/ret1 + LDD -80(%sp),%r9 ; restore r9 + LDD -88(%sp),%r8 ; restore r8 + LDD -96(%sp),%r7 ; restore r7 + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 ; restore r3 + .PROCEND ;in=23,24,25,26,29;out=28; + +;---------------------------------------------------------------------------- +; +;BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) +; +; arg0 = rp +; arg1 = ap +; arg3 = num +; w on stack at -56(sp) + +bn_mul_words + .proc + .callinfo frame=128 + .entry + .EXPORT bn_mul_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + NOP + STD %r5,16(%sp) ; save r5 + + STD %r6,24(%sp) ; save r6 + STD %r7,32(%sp) ; save r7 + COPY %r0,%ret1 ; return 0 by default + DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32 + + CMPIB,>= 0,num,bn_mul_words_exit + LDO 128(%sp),%sp ; bump stack + + ; + ; See if only 1 word to do, thus just do cleanup + ; + CMPIB,= 1,num,bn_mul_words_single_top + FLDD -184(%sp),fw ; (-56-128) load up w into fw (fw_h/fw_l) + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; + ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus + ; two 32-bit mutiplies can be issued per cycle. + ; +bn_mul_words_unroll2 + + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + FLDD 8(a_ptr),t_float_1 ; load up 64-bit value (fr8L) ht(L)/lt(R) + XMPYU fht_0,fw_l,fm1 ; m1[0] = fht_0*fw_l + XMPYU fht_1,fw_l,fm1_1 ; m1[1] = ht*fw_l + + FSTD fm1,-16(%sp) ; -16(sp) = m1 + FSTD fm1_1,-48(%sp) ; -48(sp) = m1 + XMPYU flt_0,fw_h,fm ; m = lt*fw_h + XMPYU flt_1,fw_h,fm_1 ; m = lt*fw_h + + FSTD fm,-8(%sp) ; -8(sp) = m + FSTD fm_1,-40(%sp) ; -40(sp) = m + XMPYU fht_0,fw_h,ht_temp ; ht_temp = fht_0*fw_h + XMPYU fht_1,fw_h,ht_temp_1 ; ht_temp = ht*fw_h + + FSTD ht_temp,-24(%sp) ; -24(sp) = ht + FSTD ht_temp_1,-56(%sp) ; -56(sp) = ht + XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l + XMPYU flt_1,fw_l,lt_temp_1 ; lt_temp = lt*fw_l + + FSTD lt_temp,-32(%sp) ; -32(sp) = lt + FSTD lt_temp_1,-64(%sp) ; -64(sp) = lt + LDD -8(%sp),m_0 + LDD -40(%sp),m_1 + + LDD -16(%sp),m1_0 + LDD -48(%sp),m1_1 + LDD -24(%sp),ht_0 + LDD -56(%sp),ht_1 + + ADD,L m1_0,m_0,tmp_0 ; tmp_0 = m + m1; + ADD,L m1_1,m_1,tmp_1 ; tmp_1 = m + m1; + LDD -32(%sp),lt_0 + LDD -64(%sp),lt_1 + + CMPCLR,*>>= tmp_0,m1_0, %r0 ; if (m < m1) + ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32) + CMPCLR,*>>= tmp_1,m1_1,%r0 ; if (m < m1) + ADD,L ht_1,top_overflow,ht_1 ; ht += (1<<32) + + EXTRD,U tmp_0,31,32,m_0 ; m>>32 + DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32 + EXTRD,U tmp_1,31,32,m_1 ; m>>32 + DEPD,Z tmp_1,31,32,m1_1 ; m1 = m<<32 + + ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32) + ADD,L ht_1,m_1,ht_1 ; ht+= (m>>32) + ADD lt_0,m1_0,lt_0 ; lt = lt+m1; + ADD,DC ht_0,%r0,ht_0 ; ht++ + + ADD lt_1,m1_1,lt_1 ; lt = lt+m1; + ADD,DC ht_1,%r0,ht_1 ; ht++ + ADD %ret1,lt_0,lt_0 ; lt = lt + c (ret1); + ADD,DC ht_0,%r0,ht_0 ; ht++ + + ADD ht_0,lt_1,lt_1 ; lt = lt + c (ht_0) + ADD,DC ht_1,%r0,ht_1 ; ht++ + STD lt_0,0(r_ptr) ; rp[0] = lt + STD lt_1,8(r_ptr) ; rp[1] = lt + + COPY ht_1,%ret1 ; carry = ht + LDO -2(num),num ; num = num - 2; + LDO 16(a_ptr),a_ptr ; ap += 2 + CMPIB,<= 2,num,bn_mul_words_unroll2 + LDO 16(r_ptr),r_ptr ; rp++ + + CMPIB,=,N 0,num,bn_mul_words_exit ; are we done? + + ; + ; Top of loop aligned on 64-byte boundary + ; +bn_mul_words_single_top + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + + XMPYU fht_0,fw_l,fm1 ; m1 = ht*fw_l + FSTD fm1,-16(%sp) ; -16(sp) = m1 + XMPYU flt_0,fw_h,fm ; m = lt*fw_h + FSTD fm,-8(%sp) ; -8(sp) = m + XMPYU fht_0,fw_h,ht_temp ; ht_temp = ht*fw_h + FSTD ht_temp,-24(%sp) ; -24(sp) = ht + XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l + FSTD lt_temp,-32(%sp) ; -32(sp) = lt + + LDD -8(%sp),m_0 + LDD -16(%sp),m1_0 + ADD,L m_0,m1_0,tmp_0 ; tmp_0 = m + m1; + LDD -24(%sp),ht_0 + LDD -32(%sp),lt_0 + + CMPCLR,*>>= tmp_0,m1_0,%r0 ; if (m < m1) + ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32) + + EXTRD,U tmp_0,31,32,m_0 ; m>>32 + DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32 + + ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32) + ADD lt_0,m1_0,lt_0 ; lt= lt+m1; + ADD,DC ht_0,%r0,ht_0 ; ht++ + + ADD %ret1,lt_0,lt_0 ; lt = lt + c; + ADD,DC ht_0,%r0,ht_0 ; ht++ + + COPY ht_0,%ret1 ; copy carry + STD lt_0,0(r_ptr) ; rp[0] = lt + +bn_mul_words_exit + .EXIT + EXTRD,U %ret1,31,32,%ret0 ; for 32-bit, return in ret0/ret1 + LDD -96(%sp),%r7 ; restore r7 + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 ; restore r3 + .PROCEND + +;---------------------------------------------------------------------------- +; +;void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num) +; +; arg0 = rp +; arg1 = ap +; arg2 = num +; + +bn_sqr_words + .proc + .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_sqr_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + NOP + STD %r5,16(%sp) ; save r5 + + CMPIB,>= 0,num,bn_sqr_words_exit + LDO 128(%sp),%sp ; bump stack + + ; + ; If only 1, the goto straight to cleanup + ; + CMPIB,= 1,num,bn_sqr_words_single_top + DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; + +bn_sqr_words_unroll2 + FLDD 0(a_ptr),t_float_0 ; a[0] + FLDD 8(a_ptr),t_float_1 ; a[1] + XMPYU fht_0,flt_0,fm ; m[0] + XMPYU fht_1,flt_1,fm_1 ; m[1] + + FSTD fm,-24(%sp) ; store m[0] + FSTD fm_1,-56(%sp) ; store m[1] + XMPYU flt_0,flt_0,lt_temp ; lt[0] + XMPYU flt_1,flt_1,lt_temp_1 ; lt[1] + + FSTD lt_temp,-16(%sp) ; store lt[0] + FSTD lt_temp_1,-48(%sp) ; store lt[1] + XMPYU fht_0,fht_0,ht_temp ; ht[0] + XMPYU fht_1,fht_1,ht_temp_1 ; ht[1] + + FSTD ht_temp,-8(%sp) ; store ht[0] + FSTD ht_temp_1,-40(%sp) ; store ht[1] + LDD -24(%sp),m_0 + LDD -56(%sp),m_1 + + AND m_0,high_mask,tmp_0 ; m[0] & Mask + AND m_1,high_mask,tmp_1 ; m[1] & Mask + DEPD,Z m_0,30,31,m_0 ; m[0] << 32+1 + DEPD,Z m_1,30,31,m_1 ; m[1] << 32+1 + + LDD -16(%sp),lt_0 + LDD -48(%sp),lt_1 + EXTRD,U tmp_0,32,33,tmp_0 ; tmp_0 = m[0]&Mask >> 32-1 + EXTRD,U tmp_1,32,33,tmp_1 ; tmp_1 = m[1]&Mask >> 32-1 + + LDD -8(%sp),ht_0 + LDD -40(%sp),ht_1 + ADD,L ht_0,tmp_0,ht_0 ; ht[0] += tmp_0 + ADD,L ht_1,tmp_1,ht_1 ; ht[1] += tmp_1 + + ADD lt_0,m_0,lt_0 ; lt = lt+m + ADD,DC ht_0,%r0,ht_0 ; ht[0]++ + STD lt_0,0(r_ptr) ; rp[0] = lt[0] + STD ht_0,8(r_ptr) ; rp[1] = ht[1] + + ADD lt_1,m_1,lt_1 ; lt = lt+m + ADD,DC ht_1,%r0,ht_1 ; ht[1]++ + STD lt_1,16(r_ptr) ; rp[2] = lt[1] + STD ht_1,24(r_ptr) ; rp[3] = ht[1] + + LDO -2(num),num ; num = num - 2; + LDO 16(a_ptr),a_ptr ; ap += 2 + CMPIB,<= 2,num,bn_sqr_words_unroll2 + LDO 32(r_ptr),r_ptr ; rp += 4 + + CMPIB,=,N 0,num,bn_sqr_words_exit ; are we done? + + ; + ; Top of loop aligned on 64-byte boundary + ; +bn_sqr_words_single_top + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + + XMPYU fht_0,flt_0,fm ; m + FSTD fm,-24(%sp) ; store m + + XMPYU flt_0,flt_0,lt_temp ; lt + FSTD lt_temp,-16(%sp) ; store lt + + XMPYU fht_0,fht_0,ht_temp ; ht + FSTD ht_temp,-8(%sp) ; store ht + + LDD -24(%sp),m_0 ; load m + AND m_0,high_mask,tmp_0 ; m & Mask + DEPD,Z m_0,30,31,m_0 ; m << 32+1 + LDD -16(%sp),lt_0 ; lt + + LDD -8(%sp),ht_0 ; ht + EXTRD,U tmp_0,32,33,tmp_0 ; tmp_0 = m&Mask >> 32-1 + ADD m_0,lt_0,lt_0 ; lt = lt+m + ADD,L ht_0,tmp_0,ht_0 ; ht += tmp_0 + ADD,DC ht_0,%r0,ht_0 ; ht++ + + STD lt_0,0(r_ptr) ; rp[0] = lt + STD ht_0,8(r_ptr) ; rp[1] = ht + +bn_sqr_words_exit + .EXIT + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + .PROCEND ;in=23,24,25,26,29;out=28; + + +;---------------------------------------------------------------------------- +; +;BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) +; +; arg0 = rp +; arg1 = ap +; arg2 = bp +; arg3 = n + +t .reg %r22 +b .reg %r21 +l .reg %r20 + +bn_add_words + .proc + .entry + .callinfo + .EXPORT bn_add_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .align 64 + + CMPIB,>= 0,n,bn_add_words_exit + COPY %r0,%ret1 ; return 0 by default + + ; + ; If 2 or more numbers do the loop + ; + CMPIB,= 1,n,bn_add_words_single_top + NOP + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; +bn_add_words_unroll2 + LDD 0(a_ptr),t + LDD 0(b_ptr),b + ADD t,%ret1,t ; t = t+c; + ADD,DC %r0,%r0,%ret1 ; set c to carry + ADD t,b,l ; l = t + b[0] + ADD,DC %ret1,%r0,%ret1 ; c+= carry + STD l,0(r_ptr) + + LDD 8(a_ptr),t + LDD 8(b_ptr),b + ADD t,%ret1,t ; t = t+c; + ADD,DC %r0,%r0,%ret1 ; set c to carry + ADD t,b,l ; l = t + b[0] + ADD,DC %ret1,%r0,%ret1 ; c+= carry + STD l,8(r_ptr) + + LDO -2(n),n + LDO 16(a_ptr),a_ptr + LDO 16(b_ptr),b_ptr + + CMPIB,<= 2,n,bn_add_words_unroll2 + LDO 16(r_ptr),r_ptr + + CMPIB,=,N 0,n,bn_add_words_exit ; are we done? + +bn_add_words_single_top + LDD 0(a_ptr),t + LDD 0(b_ptr),b + + ADD t,%ret1,t ; t = t+c; + ADD,DC %r0,%r0,%ret1 ; set c to carry (could use CMPCLR??) + ADD t,b,l ; l = t + b[0] + ADD,DC %ret1,%r0,%ret1 ; c+= carry + STD l,0(r_ptr) + +bn_add_words_exit + .EXIT + BVE (%rp) + EXTRD,U %ret1,31,32,%ret0 ; for 32-bit, return in ret0/ret1 + .PROCEND ;in=23,24,25,26,29;out=28; + +;---------------------------------------------------------------------------- +; +;BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) +; +; arg0 = rp +; arg1 = ap +; arg2 = bp +; arg3 = n + +t1 .reg %r22 +t2 .reg %r21 +sub_tmp1 .reg %r20 +sub_tmp2 .reg %r19 + + +bn_sub_words + .proc + .callinfo + .EXPORT bn_sub_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + + CMPIB,>= 0,n,bn_sub_words_exit + COPY %r0,%ret1 ; return 0 by default + + ; + ; If 2 or more numbers do the loop + ; + CMPIB,= 1,n,bn_sub_words_single_top + NOP + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; +bn_sub_words_unroll2 + LDD 0(a_ptr),t1 + LDD 0(b_ptr),t2 + SUB t1,t2,sub_tmp1 ; t3 = t1-t2; + SUB sub_tmp1,%ret1,sub_tmp1 ; t3 = t3- c; + + CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2 + LDO 1(%r0),sub_tmp2 + + CMPCLR,*= t1,t2,%r0 + COPY sub_tmp2,%ret1 + STD sub_tmp1,0(r_ptr) + + LDD 8(a_ptr),t1 + LDD 8(b_ptr),t2 + SUB t1,t2,sub_tmp1 ; t3 = t1-t2; + SUB sub_tmp1,%ret1,sub_tmp1 ; t3 = t3- c; + CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2 + LDO 1(%r0),sub_tmp2 + + CMPCLR,*= t1,t2,%r0 + COPY sub_tmp2,%ret1 + STD sub_tmp1,8(r_ptr) + + LDO -2(n),n + LDO 16(a_ptr),a_ptr + LDO 16(b_ptr),b_ptr + + CMPIB,<= 2,n,bn_sub_words_unroll2 + LDO 16(r_ptr),r_ptr + + CMPIB,=,N 0,n,bn_sub_words_exit ; are we done? + +bn_sub_words_single_top + LDD 0(a_ptr),t1 + LDD 0(b_ptr),t2 + SUB t1,t2,sub_tmp1 ; t3 = t1-t2; + SUB sub_tmp1,%ret1,sub_tmp1 ; t3 = t3- c; + CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2 + LDO 1(%r0),sub_tmp2 + + CMPCLR,*= t1,t2,%r0 + COPY sub_tmp2,%ret1 + + STD sub_tmp1,0(r_ptr) + +bn_sub_words_exit + .EXIT + BVE (%rp) + EXTRD,U %ret1,31,32,%ret0 ; for 32-bit, return in ret0/ret1 + .PROCEND ;in=23,24,25,26,29;out=28; + +;------------------------------------------------------------------------------ +; +; unsigned long bn_div_words(unsigned long h, unsigned long l, unsigned long d) +; +; arg0 = h +; arg1 = l +; arg2 = d +; +; This is mainly just output from the HP C compiler. +; +;------------------------------------------------------------------------------ +bn_div_words + .PROC + .EXPORT bn_div_words,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR,RTNVAL=GR,LONG_RETURN + .IMPORT BN_num_bits_word,CODE + ;--- not PIC .IMPORT __iob,DATA + ;--- not PIC .IMPORT fprintf,CODE + .IMPORT abort,CODE + .IMPORT $$div2U,MILLICODE + .CALLINFO CALLER,FRAME=144,ENTRY_GR=%r9,SAVE_RP,ARGS_SAVED,ORDERING_AWARE + .ENTRY + STW %r2,-20(%r30) ;offset 0x8ec + STW,MA %r3,192(%r30) ;offset 0x8f0 + STW %r4,-188(%r30) ;offset 0x8f4 + DEPD %r5,31,32,%r6 ;offset 0x8f8 + STD %r6,-184(%r30) ;offset 0x8fc + DEPD %r7,31,32,%r8 ;offset 0x900 + STD %r8,-176(%r30) ;offset 0x904 + STW %r9,-168(%r30) ;offset 0x908 + LDD -248(%r30),%r3 ;offset 0x90c + COPY %r26,%r4 ;offset 0x910 + COPY %r24,%r5 ;offset 0x914 + DEPD %r25,31,32,%r4 ;offset 0x918 + CMPB,*<> %r3,%r0,$0006000C ;offset 0x91c + DEPD %r23,31,32,%r5 ;offset 0x920 + MOVIB,TR -1,%r29,$00060002 ;offset 0x924 + EXTRD,U %r29,31,32,%r28 ;offset 0x928 +$0006002A + LDO -1(%r29),%r29 ;offset 0x92c + SUB %r23,%r7,%r23 ;offset 0x930 +$00060024 + SUB %r4,%r31,%r25 ;offset 0x934 + AND %r25,%r19,%r26 ;offset 0x938 + CMPB,*<>,N %r0,%r26,$00060046 ;offset 0x93c + DEPD,Z %r25,31,32,%r20 ;offset 0x940 + OR %r20,%r24,%r21 ;offset 0x944 + CMPB,*<<,N %r21,%r23,$0006002A ;offset 0x948 + SUB %r31,%r2,%r31 ;offset 0x94c +$00060046 +$0006002E + DEPD,Z %r23,31,32,%r25 ;offset 0x950 + EXTRD,U %r23,31,32,%r26 ;offset 0x954 + AND %r25,%r19,%r24 ;offset 0x958 + ADD,L %r31,%r26,%r31 ;offset 0x95c + CMPCLR,*>>= %r5,%r24,%r0 ;offset 0x960 + LDO 1(%r31),%r31 ;offset 0x964 +$00060032 + CMPB,*<<=,N %r31,%r4,$00060036 ;offset 0x968 + LDO -1(%r29),%r29 ;offset 0x96c + ADD,L %r4,%r3,%r4 ;offset 0x970 +$00060036 + ADDIB,=,N -1,%r8,$D0 ;offset 0x974 + SUB %r5,%r24,%r28 ;offset 0x978 +$0006003A + SUB %r4,%r31,%r24 ;offset 0x97c + SHRPD %r24,%r28,32,%r4 ;offset 0x980 + DEPD,Z %r29,31,32,%r9 ;offset 0x984 + DEPD,Z %r28,31,32,%r5 ;offset 0x988 +$0006001C + EXTRD,U %r4,31,32,%r31 ;offset 0x98c + CMPB,*<>,N %r31,%r2,$00060020 ;offset 0x990 + MOVB,TR %r6,%r29,$D1 ;offset 0x994 + STD %r29,-152(%r30) ;offset 0x998 +$0006000C + EXTRD,U %r3,31,32,%r25 ;offset 0x99c + COPY %r3,%r26 ;offset 0x9a0 + EXTRD,U %r3,31,32,%r9 ;offset 0x9a4 + EXTRD,U %r4,31,32,%r8 ;offset 0x9a8 + .CALL ARGW0=GR,ARGW1=GR,RTNVAL=GR ;in=25,26;out=28; + B,L BN_num_bits_word,%r2 ;offset 0x9ac + EXTRD,U %r5,31,32,%r7 ;offset 0x9b0 + LDI 64,%r20 ;offset 0x9b4 + DEPD %r7,31,32,%r5 ;offset 0x9b8 + DEPD %r8,31,32,%r4 ;offset 0x9bc + DEPD %r9,31,32,%r3 ;offset 0x9c0 + CMPB,= %r28,%r20,$00060012 ;offset 0x9c4 + COPY %r28,%r24 ;offset 0x9c8 + MTSARCM %r24 ;offset 0x9cc + DEPDI,Z -1,%sar,1,%r19 ;offset 0x9d0 + CMPB,*>>,N %r4,%r19,$D2 ;offset 0x9d4 +$00060012 + SUBI 64,%r24,%r31 ;offset 0x9d8 + CMPCLR,*<< %r4,%r3,%r0 ;offset 0x9dc + SUB %r4,%r3,%r4 ;offset 0x9e0 +$00060016 + CMPB,= %r31,%r0,$0006001A ;offset 0x9e4 + COPY %r0,%r9 ;offset 0x9e8 + MTSARCM %r31 ;offset 0x9ec + DEPD,Z %r3,%sar,64,%r3 ;offset 0x9f0 + SUBI 64,%r31,%r26 ;offset 0x9f4 + MTSAR %r26 ;offset 0x9f8 + SHRPD %r4,%r5,%sar,%r4 ;offset 0x9fc + MTSARCM %r31 ;offset 0xa00 + DEPD,Z %r5,%sar,64,%r5 ;offset 0xa04 +$0006001A + DEPDI,Z -1,31,32,%r19 ;offset 0xa08 + AND %r3,%r19,%r29 ;offset 0xa0c + EXTRD,U %r29,31,32,%r2 ;offset 0xa10 + DEPDI,Z -1,63,32,%r6 ;offset 0xa14 + MOVIB,TR 2,%r8,$0006001C ;offset 0xa18 + EXTRD,U %r3,63,32,%r7 ;offset 0xa1c +$D2 + ;--- not PIC ADDIL LR'__iob-$global$,%r27,%r1 ;offset 0xa20 + ;--- not PIC LDIL LR'C$7,%r21 ;offset 0xa24 + ;--- not PIC LDO RR'__iob-$global$+32(%r1),%r26 ;offset 0xa28 + ;--- not PIC .CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,RTNVAL=GR ;in=24,25,26;out=28; + ;--- not PIC B,L fprintf,%r2 ;offset 0xa2c + ;--- not PIC LDO RR'C$7(%r21),%r25 ;offset 0xa30 + .CALL ; + B,L abort,%r2 ;offset 0xa34 + NOP ;offset 0xa38 + B $D3 ;offset 0xa3c + LDW -212(%r30),%r2 ;offset 0xa40 +$00060020 + COPY %r4,%r26 ;offset 0xa44 + EXTRD,U %r4,31,32,%r25 ;offset 0xa48 + COPY %r2,%r24 ;offset 0xa4c + .CALL ;in=23,24,25,26;out=20,21,22,28,29; (MILLICALL) + B,L $$div2U,%r31 ;offset 0xa50 + EXTRD,U %r2,31,32,%r23 ;offset 0xa54 + DEPD %r28,31,32,%r29 ;offset 0xa58 +$00060022 + STD %r29,-152(%r30) ;offset 0xa5c +$D1 + AND %r5,%r19,%r24 ;offset 0xa60 + EXTRD,U %r24,31,32,%r24 ;offset 0xa64 + STW %r2,-160(%r30) ;offset 0xa68 + STW %r7,-128(%r30) ;offset 0xa6c + FLDD -152(%r30),%fr4 ;offset 0xa70 + FLDD -152(%r30),%fr7 ;offset 0xa74 + FLDW -160(%r30),%fr8L ;offset 0xa78 + FLDW -128(%r30),%fr5L ;offset 0xa7c + XMPYU %fr8L,%fr7L,%fr10 ;offset 0xa80 + FSTD %fr10,-136(%r30) ;offset 0xa84 + XMPYU %fr8L,%fr7R,%fr22 ;offset 0xa88 + FSTD %fr22,-144(%r30) ;offset 0xa8c + XMPYU %fr5L,%fr4L,%fr11 ;offset 0xa90 + XMPYU %fr5L,%fr4R,%fr23 ;offset 0xa94 + FSTD %fr11,-112(%r30) ;offset 0xa98 + FSTD %fr23,-120(%r30) ;offset 0xa9c + LDD -136(%r30),%r28 ;offset 0xaa0 + DEPD,Z %r28,31,32,%r31 ;offset 0xaa4 + LDD -144(%r30),%r20 ;offset 0xaa8 + ADD,L %r20,%r31,%r31 ;offset 0xaac + LDD -112(%r30),%r22 ;offset 0xab0 + DEPD,Z %r22,31,32,%r22 ;offset 0xab4 + LDD -120(%r30),%r21 ;offset 0xab8 + B $00060024 ;offset 0xabc + ADD,L %r21,%r22,%r23 ;offset 0xac0 +$D0 + OR %r9,%r29,%r29 ;offset 0xac4 +$00060040 + EXTRD,U %r29,31,32,%r28 ;offset 0xac8 +$00060002 +$L2 + LDW -212(%r30),%r2 ;offset 0xacc +$D3 + LDW -168(%r30),%r9 ;offset 0xad0 + LDD -176(%r30),%r8 ;offset 0xad4 + EXTRD,U %r8,31,32,%r7 ;offset 0xad8 + LDD -184(%r30),%r6 ;offset 0xadc + EXTRD,U %r6,31,32,%r5 ;offset 0xae0 + LDW -188(%r30),%r4 ;offset 0xae4 + BVE (%r2) ;offset 0xae8 + .EXIT + LDW,MB -192(%r30),%r3 ;offset 0xaec + .PROCEND ;in=23,25;out=28,29;fpin=105,107; + + + + +;---------------------------------------------------------------------------- +; +; Registers to hold 64-bit values to manipulate. The "L" part +; of the register corresponds to the upper 32-bits, while the "R" +; part corresponds to the lower 32-bits +; +; Note, that when using b6 and b7, the code must save these before +; using them because they are callee save registers +; +; +; Floating point registers to use to save values that +; are manipulated. These don't collide with ftemp1-6 and +; are all caller save registers +; +a0 .reg %fr22 +a0L .reg %fr22L +a0R .reg %fr22R + +a1 .reg %fr23 +a1L .reg %fr23L +a1R .reg %fr23R + +a2 .reg %fr24 +a2L .reg %fr24L +a2R .reg %fr24R + +a3 .reg %fr25 +a3L .reg %fr25L +a3R .reg %fr25R + +a4 .reg %fr26 +a4L .reg %fr26L +a4R .reg %fr26R + +a5 .reg %fr27 +a5L .reg %fr27L +a5R .reg %fr27R + +a6 .reg %fr28 +a6L .reg %fr28L +a6R .reg %fr28R + +a7 .reg %fr29 +a7L .reg %fr29L +a7R .reg %fr29R + +b0 .reg %fr30 +b0L .reg %fr30L +b0R .reg %fr30R + +b1 .reg %fr31 +b1L .reg %fr31L +b1R .reg %fr31R + +; +; Temporary floating point variables, these are all caller save +; registers +; +ftemp1 .reg %fr4 +ftemp2 .reg %fr5 +ftemp3 .reg %fr6 +ftemp4 .reg %fr7 + +; +; The B set of registers when used. +; + +b2 .reg %fr8 +b2L .reg %fr8L +b2R .reg %fr8R + +b3 .reg %fr9 +b3L .reg %fr9L +b3R .reg %fr9R + +b4 .reg %fr10 +b4L .reg %fr10L +b4R .reg %fr10R + +b5 .reg %fr11 +b5L .reg %fr11L +b5R .reg %fr11R + +b6 .reg %fr12 +b6L .reg %fr12L +b6R .reg %fr12R + +b7 .reg %fr13 +b7L .reg %fr13L +b7R .reg %fr13R + +c1 .reg %r21 ; only reg +temp1 .reg %r20 ; only reg +temp2 .reg %r19 ; only reg +temp3 .reg %r31 ; only reg + +m1 .reg %r28 +c2 .reg %r23 +high_one .reg %r1 +ht .reg %r6 +lt .reg %r5 +m .reg %r4 +c3 .reg %r3 + +SQR_ADD_C .macro A0L,A0R,C1,C2,C3 + XMPYU A0L,A0R,ftemp1 ; m + FSTD ftemp1,-24(%sp) ; store m + + XMPYU A0R,A0R,ftemp2 ; lt + FSTD ftemp2,-16(%sp) ; store lt + + XMPYU A0L,A0L,ftemp3 ; ht + FSTD ftemp3,-8(%sp) ; store ht + + LDD -24(%sp),m ; load m + AND m,high_mask,temp2 ; m & Mask + DEPD,Z m,30,31,temp3 ; m << 32+1 + LDD -16(%sp),lt ; lt + + LDD -8(%sp),ht ; ht + EXTRD,U temp2,32,33,temp1 ; temp1 = m&Mask >> 32-1 + ADD temp3,lt,lt ; lt = lt+m + ADD,L ht,temp1,ht ; ht += temp1 + ADD,DC ht,%r0,ht ; ht++ + + ADD C1,lt,C1 ; c1=c1+lt + ADD,DC ht,%r0,ht ; ht++ + + ADD C2,ht,C2 ; c2=c2+ht + ADD,DC C3,%r0,C3 ; c3++ +.endm + +SQR_ADD_C2 .macro A0L,A0R,A1L,A1R,C1,C2,C3 + XMPYU A0L,A1R,ftemp1 ; m1 = bl*ht + FSTD ftemp1,-16(%sp) ; + XMPYU A0R,A1L,ftemp2 ; m = bh*lt + FSTD ftemp2,-8(%sp) ; + XMPYU A0R,A1R,ftemp3 ; lt = bl*lt + FSTD ftemp3,-32(%sp) + XMPYU A0L,A1L,ftemp4 ; ht = bh*ht + FSTD ftemp4,-24(%sp) ; + + LDD -8(%sp),m ; r21 = m + LDD -16(%sp),m1 ; r19 = m1 + ADD,L m,m1,m ; m+m1 + + DEPD,Z m,31,32,temp3 ; (m+m1<<32) + LDD -24(%sp),ht ; r24 = ht + + CMPCLR,*>>= m,m1,%r0 ; if (m < m1) + ADD,L ht,high_one,ht ; ht+=high_one + + EXTRD,U m,31,32,temp1 ; m >> 32 + LDD -32(%sp),lt ; lt + ADD,L ht,temp1,ht ; ht+= m>>32 + ADD lt,temp3,lt ; lt = lt+m1 + ADD,DC ht,%r0,ht ; ht++ + + ADD ht,ht,ht ; ht=ht+ht; + ADD,DC C3,%r0,C3 ; add in carry (c3++) + + ADD lt,lt,lt ; lt=lt+lt; + ADD,DC ht,%r0,ht ; add in carry (ht++) + + ADD C1,lt,C1 ; c1=c1+lt + ADD,DC,*NUV ht,%r0,ht ; add in carry (ht++) + LDO 1(C3),C3 ; bump c3 if overflow,nullify otherwise + + ADD C2,ht,C2 ; c2 = c2 + ht + ADD,DC C3,%r0,C3 ; add in carry (c3++) +.endm + +; +;void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a) +; arg0 = r_ptr +; arg1 = a_ptr +; + +bn_sqr_comba8 + .PROC + .CALLINFO FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_sqr_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .ENTRY + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + + ; + ; Zero out carries + ; + COPY %r0,c1 + COPY %r0,c2 + COPY %r0,c3 + + LDO 128(%sp),%sp ; bump stack + DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L + DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 + + ; + ; Load up all of the values we are going to use + ; + FLDD 0(a_ptr),a0 + FLDD 8(a_ptr),a1 + FLDD 16(a_ptr),a2 + FLDD 24(a_ptr),a3 + FLDD 32(a_ptr),a4 + FLDD 40(a_ptr),a5 + FLDD 48(a_ptr),a6 + FLDD 56(a_ptr),a7 + + SQR_ADD_C a0L,a0R,c1,c2,c3 + STD c1,0(r_ptr) ; r[0] = c1; + COPY %r0,c1 + + SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1 + STD c2,8(r_ptr) ; r[1] = c2; + COPY %r0,c2 + + SQR_ADD_C a1L,a1R,c3,c1,c2 + SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2 + STD c3,16(r_ptr) ; r[2] = c3; + COPY %r0,c3 + + SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3 + SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3 + STD c1,24(r_ptr) ; r[3] = c1; + COPY %r0,c1 + + SQR_ADD_C a2L,a2R,c2,c3,c1 + SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1 + SQR_ADD_C2 a4L,a4R,a0L,a0R,c2,c3,c1 + STD c2,32(r_ptr) ; r[4] = c2; + COPY %r0,c2 + + SQR_ADD_C2 a5L,a5R,a0L,a0R,c3,c1,c2 + SQR_ADD_C2 a4L,a4R,a1L,a1R,c3,c1,c2 + SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2 + STD c3,40(r_ptr) ; r[5] = c3; + COPY %r0,c3 + + SQR_ADD_C a3L,a3R,c1,c2,c3 + SQR_ADD_C2 a4L,a4R,a2L,a2R,c1,c2,c3 + SQR_ADD_C2 a5L,a5R,a1L,a1R,c1,c2,c3 + SQR_ADD_C2 a6L,a6R,a0L,a0R,c1,c2,c3 + STD c1,48(r_ptr) ; r[6] = c1; + COPY %r0,c1 + + SQR_ADD_C2 a7L,a7R,a0L,a0R,c2,c3,c1 + SQR_ADD_C2 a6L,a6R,a1L,a1R,c2,c3,c1 + SQR_ADD_C2 a5L,a5R,a2L,a2R,c2,c3,c1 + SQR_ADD_C2 a4L,a4R,a3L,a3R,c2,c3,c1 + STD c2,56(r_ptr) ; r[7] = c2; + COPY %r0,c2 + + SQR_ADD_C a4L,a4R,c3,c1,c2 + SQR_ADD_C2 a5L,a5R,a3L,a3R,c3,c1,c2 + SQR_ADD_C2 a6L,a6R,a2L,a2R,c3,c1,c2 + SQR_ADD_C2 a7L,a7R,a1L,a1R,c3,c1,c2 + STD c3,64(r_ptr) ; r[8] = c3; + COPY %r0,c3 + + SQR_ADD_C2 a7L,a7R,a2L,a2R,c1,c2,c3 + SQR_ADD_C2 a6L,a6R,a3L,a3R,c1,c2,c3 + SQR_ADD_C2 a5L,a5R,a4L,a4R,c1,c2,c3 + STD c1,72(r_ptr) ; r[9] = c1; + COPY %r0,c1 + + SQR_ADD_C a5L,a5R,c2,c3,c1 + SQR_ADD_C2 a6L,a6R,a4L,a4R,c2,c3,c1 + SQR_ADD_C2 a7L,a7R,a3L,a3R,c2,c3,c1 + STD c2,80(r_ptr) ; r[10] = c2; + COPY %r0,c2 + + SQR_ADD_C2 a7L,a7R,a4L,a4R,c3,c1,c2 + SQR_ADD_C2 a6L,a6R,a5L,a5R,c3,c1,c2 + STD c3,88(r_ptr) ; r[11] = c3; + COPY %r0,c3 + + SQR_ADD_C a6L,a6R,c1,c2,c3 + SQR_ADD_C2 a7L,a7R,a5L,a5R,c1,c2,c3 + STD c1,96(r_ptr) ; r[12] = c1; + COPY %r0,c1 + + SQR_ADD_C2 a7L,a7R,a6L,a6R,c2,c3,c1 + STD c2,104(r_ptr) ; r[13] = c2; + COPY %r0,c2 + + SQR_ADD_C a7L,a7R,c3,c1,c2 + STD c3, 112(r_ptr) ; r[14] = c3 + STD c1, 120(r_ptr) ; r[15] = c1 + + .EXIT + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + + .PROCEND + +;----------------------------------------------------------------------------- +; +;void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a) +; arg0 = r_ptr +; arg1 = a_ptr +; + +bn_sqr_comba4 + .proc + .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_sqr_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + + ; + ; Zero out carries + ; + COPY %r0,c1 + COPY %r0,c2 + COPY %r0,c3 + + LDO 128(%sp),%sp ; bump stack + DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L + DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 + + ; + ; Load up all of the values we are going to use + ; + FLDD 0(a_ptr),a0 + FLDD 8(a_ptr),a1 + FLDD 16(a_ptr),a2 + FLDD 24(a_ptr),a3 + FLDD 32(a_ptr),a4 + FLDD 40(a_ptr),a5 + FLDD 48(a_ptr),a6 + FLDD 56(a_ptr),a7 + + SQR_ADD_C a0L,a0R,c1,c2,c3 + + STD c1,0(r_ptr) ; r[0] = c1; + COPY %r0,c1 + + SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1 + + STD c2,8(r_ptr) ; r[1] = c2; + COPY %r0,c2 + + SQR_ADD_C a1L,a1R,c3,c1,c2 + SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2 + + STD c3,16(r_ptr) ; r[2] = c3; + COPY %r0,c3 + + SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3 + SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3 + + STD c1,24(r_ptr) ; r[3] = c1; + COPY %r0,c1 + + SQR_ADD_C a2L,a2R,c2,c3,c1 + SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1 + + STD c2,32(r_ptr) ; r[4] = c2; + COPY %r0,c2 + + SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2 + STD c3,40(r_ptr) ; r[5] = c3; + COPY %r0,c3 + + SQR_ADD_C a3L,a3R,c1,c2,c3 + STD c1,48(r_ptr) ; r[6] = c1; + STD c2,56(r_ptr) ; r[7] = c2; + + .EXIT + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + + .PROCEND + + +;--------------------------------------------------------------------------- + +MUL_ADD_C .macro A0L,A0R,B0L,B0R,C1,C2,C3 + XMPYU A0L,B0R,ftemp1 ; m1 = bl*ht + FSTD ftemp1,-16(%sp) ; + XMPYU A0R,B0L,ftemp2 ; m = bh*lt + FSTD ftemp2,-8(%sp) ; + XMPYU A0R,B0R,ftemp3 ; lt = bl*lt + FSTD ftemp3,-32(%sp) + XMPYU A0L,B0L,ftemp4 ; ht = bh*ht + FSTD ftemp4,-24(%sp) ; + + LDD -8(%sp),m ; r21 = m + LDD -16(%sp),m1 ; r19 = m1 + ADD,L m,m1,m ; m+m1 + + DEPD,Z m,31,32,temp3 ; (m+m1<<32) + LDD -24(%sp),ht ; r24 = ht + + CMPCLR,*>>= m,m1,%r0 ; if (m < m1) + ADD,L ht,high_one,ht ; ht+=high_one + + EXTRD,U m,31,32,temp1 ; m >> 32 + LDD -32(%sp),lt ; lt + ADD,L ht,temp1,ht ; ht+= m>>32 + ADD lt,temp3,lt ; lt = lt+m1 + ADD,DC ht,%r0,ht ; ht++ + + ADD C1,lt,C1 ; c1=c1+lt + ADD,DC ht,%r0,ht ; bump c3 if overflow,nullify otherwise + + ADD C2,ht,C2 ; c2 = c2 + ht + ADD,DC C3,%r0,C3 ; add in carry (c3++) +.endm + + +; +;void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) +; arg0 = r_ptr +; arg1 = a_ptr +; arg2 = b_ptr +; + +bn_mul_comba8 + .proc + .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_mul_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + FSTD %fr12,32(%sp) ; save r6 + FSTD %fr13,40(%sp) ; save r7 + + ; + ; Zero out carries + ; + COPY %r0,c1 + COPY %r0,c2 + COPY %r0,c3 + + LDO 128(%sp),%sp ; bump stack + DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 + + ; + ; Load up all of the values we are going to use + ; + FLDD 0(a_ptr),a0 + FLDD 8(a_ptr),a1 + FLDD 16(a_ptr),a2 + FLDD 24(a_ptr),a3 + FLDD 32(a_ptr),a4 + FLDD 40(a_ptr),a5 + FLDD 48(a_ptr),a6 + FLDD 56(a_ptr),a7 + + FLDD 0(b_ptr),b0 + FLDD 8(b_ptr),b1 + FLDD 16(b_ptr),b2 + FLDD 24(b_ptr),b3 + FLDD 32(b_ptr),b4 + FLDD 40(b_ptr),b5 + FLDD 48(b_ptr),b6 + FLDD 56(b_ptr),b7 + + MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3 + STD c1,0(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1 + STD c2,8(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2 + MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2 + MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2 + STD c3,16(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3 + MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3 + MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3 + MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3 + STD c1,24(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a4L,a4R,b0L,b0R,c2,c3,c1 + MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1 + MUL_ADD_C a0L,a0R,b4L,b4R,c2,c3,c1 + STD c2,32(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a0L,a0R,b5L,b5R,c3,c1,c2 + MUL_ADD_C a1L,a1R,b4L,b4R,c3,c1,c2 + MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2 + MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2 + MUL_ADD_C a4L,a4R,b1L,b1R,c3,c1,c2 + MUL_ADD_C a5L,a5R,b0L,b0R,c3,c1,c2 + STD c3,40(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a6L,a6R,b0L,b0R,c1,c2,c3 + MUL_ADD_C a5L,a5R,b1L,b1R,c1,c2,c3 + MUL_ADD_C a4L,a4R,b2L,b2R,c1,c2,c3 + MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3 + MUL_ADD_C a2L,a2R,b4L,b4R,c1,c2,c3 + MUL_ADD_C a1L,a1R,b5L,b5R,c1,c2,c3 + MUL_ADD_C a0L,a0R,b6L,b6R,c1,c2,c3 + STD c1,48(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a0L,a0R,b7L,b7R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b6L,b6R,c2,c3,c1 + MUL_ADD_C a2L,a2R,b5L,b5R,c2,c3,c1 + MUL_ADD_C a3L,a3R,b4L,b4R,c2,c3,c1 + MUL_ADD_C a4L,a4R,b3L,b3R,c2,c3,c1 + MUL_ADD_C a5L,a5R,b2L,b2R,c2,c3,c1 + MUL_ADD_C a6L,a6R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a7L,a7R,b0L,b0R,c2,c3,c1 + STD c2,56(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a7L,a7R,b1L,b1R,c3,c1,c2 + MUL_ADD_C a6L,a6R,b2L,b2R,c3,c1,c2 + MUL_ADD_C a5L,a5R,b3L,b3R,c3,c1,c2 + MUL_ADD_C a4L,a4R,b4L,b4R,c3,c1,c2 + MUL_ADD_C a3L,a3R,b5L,b5R,c3,c1,c2 + MUL_ADD_C a2L,a2R,b6L,b6R,c3,c1,c2 + MUL_ADD_C a1L,a1R,b7L,b7R,c3,c1,c2 + STD c3,64(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a2L,a2R,b7L,b7R,c1,c2,c3 + MUL_ADD_C a3L,a3R,b6L,b6R,c1,c2,c3 + MUL_ADD_C a4L,a4R,b5L,b5R,c1,c2,c3 + MUL_ADD_C a5L,a5R,b4L,b4R,c1,c2,c3 + MUL_ADD_C a6L,a6R,b3L,b3R,c1,c2,c3 + MUL_ADD_C a7L,a7R,b2L,b2R,c1,c2,c3 + STD c1,72(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a7L,a7R,b3L,b3R,c2,c3,c1 + MUL_ADD_C a6L,a6R,b4L,b4R,c2,c3,c1 + MUL_ADD_C a5L,a5R,b5L,b5R,c2,c3,c1 + MUL_ADD_C a4L,a4R,b6L,b6R,c2,c3,c1 + MUL_ADD_C a3L,a3R,b7L,b7R,c2,c3,c1 + STD c2,80(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a4L,a4R,b7L,b7R,c3,c1,c2 + MUL_ADD_C a5L,a5R,b6L,b6R,c3,c1,c2 + MUL_ADD_C a6L,a6R,b5L,b5R,c3,c1,c2 + MUL_ADD_C a7L,a7R,b4L,b4R,c3,c1,c2 + STD c3,88(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a7L,a7R,b5L,b5R,c1,c2,c3 + MUL_ADD_C a6L,a6R,b6L,b6R,c1,c2,c3 + MUL_ADD_C a5L,a5R,b7L,b7R,c1,c2,c3 + STD c1,96(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a6L,a6R,b7L,b7R,c2,c3,c1 + MUL_ADD_C a7L,a7R,b6L,b6R,c2,c3,c1 + STD c2,104(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a7L,a7R,b7L,b7R,c3,c1,c2 + STD c3,112(r_ptr) + STD c1,120(r_ptr) + + .EXIT + FLDD -88(%sp),%fr13 + FLDD -96(%sp),%fr12 + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + + .PROCEND + +;----------------------------------------------------------------------------- +; +;void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) +; arg0 = r_ptr +; arg1 = a_ptr +; arg2 = b_ptr +; + +bn_mul_comba4 + .proc + .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_mul_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + FSTD %fr12,32(%sp) ; save r6 + FSTD %fr13,40(%sp) ; save r7 + + ; + ; Zero out carries + ; + COPY %r0,c1 + COPY %r0,c2 + COPY %r0,c3 + + LDO 128(%sp),%sp ; bump stack + DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 + + ; + ; Load up all of the values we are going to use + ; + FLDD 0(a_ptr),a0 + FLDD 8(a_ptr),a1 + FLDD 16(a_ptr),a2 + FLDD 24(a_ptr),a3 + + FLDD 0(b_ptr),b0 + FLDD 8(b_ptr),b1 + FLDD 16(b_ptr),b2 + FLDD 24(b_ptr),b3 + + MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3 + STD c1,0(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1 + STD c2,8(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2 + MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2 + MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2 + STD c3,16(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3 + MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3 + MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3 + MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3 + STD c1,24(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1 + STD c2,32(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2 + MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2 + STD c3,40(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3 + STD c1,48(r_ptr) + STD c2,56(r_ptr) + + .EXIT + FLDD -88(%sp),%fr13 + FLDD -96(%sp),%fr12 + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + + .PROCEND + + +;--- not PIC .SPACE $TEXT$ +;--- not PIC .SUBSPA $CODE$ +;--- not PIC .SPACE $PRIVATE$,SORT=16 +;--- not PIC .IMPORT $global$,DATA +;--- not PIC .SPACE $TEXT$ +;--- not PIC .SUBSPA $CODE$ +;--- not PIC .SUBSPA $LIT$,ACCESS=0x2c +;--- not PIC C$7 +;--- not PIC .ALIGN 8 +;--- not PIC .STRINGZ "Division would overflow (%d)\n" + .END diff --git a/libs/openssl/crypto/bn/asm/pa-risc2W.s b/libs/openssl/crypto/bn/asm/pa-risc2W.s new file mode 100644 index 00000000..a9954575 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/pa-risc2W.s @@ -0,0 +1,1605 @@ +; +; PA-RISC 64-bit implementation of bn_asm code +; +; This code is approximately 2x faster than the C version +; for RSA/DSA. +; +; See http://devresource.hp.com/ for more details on the PA-RISC +; architecture. Also see the book "PA-RISC 2.0 Architecture" +; by Gerry Kane for information on the instruction set architecture. +; +; Code written by Chris Ruemmler (with some help from the HP C +; compiler). +; +; The code compiles with HP's assembler +; + + .level 2.0W + .space $TEXT$ + .subspa $CODE$,QUAD=0,ALIGN=8,ACCESS=0x2c,CODE_ONLY + +; +; Global Register definitions used for the routines. +; +; Some information about HP's runtime architecture for 64-bits. +; +; "Caller save" means the calling function must save the register +; if it wants the register to be preserved. +; "Callee save" means if a function uses the register, it must save +; the value before using it. +; +; For the floating point registers +; +; "caller save" registers: fr4-fr11, fr22-fr31 +; "callee save" registers: fr12-fr21 +; "special" registers: fr0-fr3 (status and exception registers) +; +; For the integer registers +; value zero : r0 +; "caller save" registers: r1,r19-r26 +; "callee save" registers: r3-r18 +; return register : r2 (rp) +; return values ; r28 (ret0,ret1) +; Stack pointer ; r30 (sp) +; global data pointer ; r27 (dp) +; argument pointer ; r29 (ap) +; millicode return ptr ; r31 (also a caller save register) + + +; +; Arguments to the routines +; +r_ptr .reg %r26 +a_ptr .reg %r25 +b_ptr .reg %r24 +num .reg %r24 +w .reg %r23 +n .reg %r23 + + +; +; Globals used in some routines +; + +top_overflow .reg %r29 +high_mask .reg %r22 ; value 0xffffffff80000000L + + +;------------------------------------------------------------------------------ +; +; bn_mul_add_words +; +;BN_ULONG bn_mul_add_words(BN_ULONG *r_ptr, BN_ULONG *a_ptr, +; int num, BN_ULONG w) +; +; arg0 = r_ptr +; arg1 = a_ptr +; arg2 = num +; arg3 = w +; +; Local register definitions +; + +fm1 .reg %fr22 +fm .reg %fr23 +ht_temp .reg %fr24 +ht_temp_1 .reg %fr25 +lt_temp .reg %fr26 +lt_temp_1 .reg %fr27 +fm1_1 .reg %fr28 +fm_1 .reg %fr29 + +fw_h .reg %fr7L +fw_l .reg %fr7R +fw .reg %fr7 + +fht_0 .reg %fr8L +flt_0 .reg %fr8R +t_float_0 .reg %fr8 + +fht_1 .reg %fr9L +flt_1 .reg %fr9R +t_float_1 .reg %fr9 + +tmp_0 .reg %r31 +tmp_1 .reg %r21 +m_0 .reg %r20 +m_1 .reg %r19 +ht_0 .reg %r1 +ht_1 .reg %r3 +lt_0 .reg %r4 +lt_1 .reg %r5 +m1_0 .reg %r6 +m1_1 .reg %r7 +rp_val .reg %r8 +rp_val_1 .reg %r9 + +bn_mul_add_words + .export bn_mul_add_words,entry,NO_RELOCATION,LONG_RETURN + .proc + .callinfo frame=128 + .entry + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + NOP ; Needed to make the loop 16-byte aligned + NOP ; Needed to make the loop 16-byte aligned + + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + STD %r7,32(%sp) ; save r7 + STD %r8,40(%sp) ; save r8 + + STD %r9,48(%sp) ; save r9 + COPY %r0,%ret0 ; return 0 by default + DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32 + STD w,56(%sp) ; store w on stack + + CMPIB,>= 0,num,bn_mul_add_words_exit ; if (num <= 0) then exit + LDO 128(%sp),%sp ; bump stack + + ; + ; The loop is unrolled twice, so if there is only 1 number + ; then go straight to the cleanup code. + ; + CMPIB,= 1,num,bn_mul_add_words_single_top + FLDD -72(%sp),fw ; load up w into fp register fw (fw_h/fw_l) + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; + ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus + ; two 32-bit mutiplies can be issued per cycle. + ; +bn_mul_add_words_unroll2 + + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + FLDD 8(a_ptr),t_float_1 ; load up 64-bit value (fr8L) ht(L)/lt(R) + LDD 0(r_ptr),rp_val ; rp[0] + LDD 8(r_ptr),rp_val_1 ; rp[1] + + XMPYU fht_0,fw_l,fm1 ; m1[0] = fht_0*fw_l + XMPYU fht_1,fw_l,fm1_1 ; m1[1] = fht_1*fw_l + FSTD fm1,-16(%sp) ; -16(sp) = m1[0] + FSTD fm1_1,-48(%sp) ; -48(sp) = m1[1] + + XMPYU flt_0,fw_h,fm ; m[0] = flt_0*fw_h + XMPYU flt_1,fw_h,fm_1 ; m[1] = flt_1*fw_h + FSTD fm,-8(%sp) ; -8(sp) = m[0] + FSTD fm_1,-40(%sp) ; -40(sp) = m[1] + + XMPYU fht_0,fw_h,ht_temp ; ht_temp = fht_0*fw_h + XMPYU fht_1,fw_h,ht_temp_1 ; ht_temp_1 = fht_1*fw_h + FSTD ht_temp,-24(%sp) ; -24(sp) = ht_temp + FSTD ht_temp_1,-56(%sp) ; -56(sp) = ht_temp_1 + + XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l + XMPYU flt_1,fw_l,lt_temp_1 ; lt_temp = lt*fw_l + FSTD lt_temp,-32(%sp) ; -32(sp) = lt_temp + FSTD lt_temp_1,-64(%sp) ; -64(sp) = lt_temp_1 + + LDD -8(%sp),m_0 ; m[0] + LDD -40(%sp),m_1 ; m[1] + LDD -16(%sp),m1_0 ; m1[0] + LDD -48(%sp),m1_1 ; m1[1] + + LDD -24(%sp),ht_0 ; ht[0] + LDD -56(%sp),ht_1 ; ht[1] + ADD,L m1_0,m_0,tmp_0 ; tmp_0 = m[0] + m1[0]; + ADD,L m1_1,m_1,tmp_1 ; tmp_1 = m[1] + m1[1]; + + LDD -32(%sp),lt_0 + LDD -64(%sp),lt_1 + CMPCLR,*>>= tmp_0,m1_0, %r0 ; if (m[0] < m1[0]) + ADD,L ht_0,top_overflow,ht_0 ; ht[0] += (1<<32) + + CMPCLR,*>>= tmp_1,m1_1,%r0 ; if (m[1] < m1[1]) + ADD,L ht_1,top_overflow,ht_1 ; ht[1] += (1<<32) + EXTRD,U tmp_0,31,32,m_0 ; m[0]>>32 + DEPD,Z tmp_0,31,32,m1_0 ; m1[0] = m[0]<<32 + + EXTRD,U tmp_1,31,32,m_1 ; m[1]>>32 + DEPD,Z tmp_1,31,32,m1_1 ; m1[1] = m[1]<<32 + ADD,L ht_0,m_0,ht_0 ; ht[0]+= (m[0]>>32) + ADD,L ht_1,m_1,ht_1 ; ht[1]+= (m[1]>>32) + + ADD lt_0,m1_0,lt_0 ; lt[0] = lt[0]+m1[0]; + ADD,DC ht_0,%r0,ht_0 ; ht[0]++ + ADD lt_1,m1_1,lt_1 ; lt[1] = lt[1]+m1[1]; + ADD,DC ht_1,%r0,ht_1 ; ht[1]++ + + ADD %ret0,lt_0,lt_0 ; lt[0] = lt[0] + c; + ADD,DC ht_0,%r0,ht_0 ; ht[0]++ + ADD lt_0,rp_val,lt_0 ; lt[0] = lt[0]+rp[0] + ADD,DC ht_0,%r0,ht_0 ; ht[0]++ + + LDO -2(num),num ; num = num - 2; + ADD ht_0,lt_1,lt_1 ; lt[1] = lt[1] + ht_0 (c); + ADD,DC ht_1,%r0,ht_1 ; ht[1]++ + STD lt_0,0(r_ptr) ; rp[0] = lt[0] + + ADD lt_1,rp_val_1,lt_1 ; lt[1] = lt[1]+rp[1] + ADD,DC ht_1,%r0,%ret0 ; ht[1]++ + LDO 16(a_ptr),a_ptr ; a_ptr += 2 + + STD lt_1,8(r_ptr) ; rp[1] = lt[1] + CMPIB,<= 2,num,bn_mul_add_words_unroll2 ; go again if more to do + LDO 16(r_ptr),r_ptr ; r_ptr += 2 + + CMPIB,=,N 0,num,bn_mul_add_words_exit ; are we done, or cleanup last one + + ; + ; Top of loop aligned on 64-byte boundary + ; +bn_mul_add_words_single_top + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + LDD 0(r_ptr),rp_val ; rp[0] + LDO 8(a_ptr),a_ptr ; a_ptr++ + XMPYU fht_0,fw_l,fm1 ; m1 = ht*fw_l + FSTD fm1,-16(%sp) ; -16(sp) = m1 + XMPYU flt_0,fw_h,fm ; m = lt*fw_h + FSTD fm,-8(%sp) ; -8(sp) = m + XMPYU fht_0,fw_h,ht_temp ; ht_temp = ht*fw_h + FSTD ht_temp,-24(%sp) ; -24(sp) = ht + XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l + FSTD lt_temp,-32(%sp) ; -32(sp) = lt + + LDD -8(%sp),m_0 + LDD -16(%sp),m1_0 ; m1 = temp1 + ADD,L m_0,m1_0,tmp_0 ; tmp_0 = m + m1; + LDD -24(%sp),ht_0 + LDD -32(%sp),lt_0 + + CMPCLR,*>>= tmp_0,m1_0,%r0 ; if (m < m1) + ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32) + + EXTRD,U tmp_0,31,32,m_0 ; m>>32 + DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32 + + ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32) + ADD lt_0,m1_0,tmp_0 ; tmp_0 = lt+m1; + ADD,DC ht_0,%r0,ht_0 ; ht++ + ADD %ret0,tmp_0,lt_0 ; lt = lt + c; + ADD,DC ht_0,%r0,ht_0 ; ht++ + ADD lt_0,rp_val,lt_0 ; lt = lt+rp[0] + ADD,DC ht_0,%r0,%ret0 ; ht++ + STD lt_0,0(r_ptr) ; rp[0] = lt + +bn_mul_add_words_exit + .EXIT + LDD -80(%sp),%r9 ; restore r9 + LDD -88(%sp),%r8 ; restore r8 + LDD -96(%sp),%r7 ; restore r7 + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 ; restore r3 + .PROCEND ;in=23,24,25,26,29;out=28; + +;---------------------------------------------------------------------------- +; +;BN_ULONG bn_mul_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) +; +; arg0 = rp +; arg1 = ap +; arg2 = num +; arg3 = w + +bn_mul_words + .proc + .callinfo frame=128 + .entry + .EXPORT bn_mul_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + + STD %r7,32(%sp) ; save r7 + COPY %r0,%ret0 ; return 0 by default + DEPDI,Z 1,31,1,top_overflow ; top_overflow = 1 << 32 + STD w,56(%sp) ; w on stack + + CMPIB,>= 0,num,bn_mul_words_exit + LDO 128(%sp),%sp ; bump stack + + ; + ; See if only 1 word to do, thus just do cleanup + ; + CMPIB,= 1,num,bn_mul_words_single_top + FLDD -72(%sp),fw ; load up w into fp register fw (fw_h/fw_l) + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; + ; PA-RISC 2.0 chips have two fully pipelined multipliers, thus + ; two 32-bit mutiplies can be issued per cycle. + ; +bn_mul_words_unroll2 + + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + FLDD 8(a_ptr),t_float_1 ; load up 64-bit value (fr8L) ht(L)/lt(R) + XMPYU fht_0,fw_l,fm1 ; m1[0] = fht_0*fw_l + XMPYU fht_1,fw_l,fm1_1 ; m1[1] = ht*fw_l + + FSTD fm1,-16(%sp) ; -16(sp) = m1 + FSTD fm1_1,-48(%sp) ; -48(sp) = m1 + XMPYU flt_0,fw_h,fm ; m = lt*fw_h + XMPYU flt_1,fw_h,fm_1 ; m = lt*fw_h + + FSTD fm,-8(%sp) ; -8(sp) = m + FSTD fm_1,-40(%sp) ; -40(sp) = m + XMPYU fht_0,fw_h,ht_temp ; ht_temp = fht_0*fw_h + XMPYU fht_1,fw_h,ht_temp_1 ; ht_temp = ht*fw_h + + FSTD ht_temp,-24(%sp) ; -24(sp) = ht + FSTD ht_temp_1,-56(%sp) ; -56(sp) = ht + XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l + XMPYU flt_1,fw_l,lt_temp_1 ; lt_temp = lt*fw_l + + FSTD lt_temp,-32(%sp) ; -32(sp) = lt + FSTD lt_temp_1,-64(%sp) ; -64(sp) = lt + LDD -8(%sp),m_0 + LDD -40(%sp),m_1 + + LDD -16(%sp),m1_0 + LDD -48(%sp),m1_1 + LDD -24(%sp),ht_0 + LDD -56(%sp),ht_1 + + ADD,L m1_0,m_0,tmp_0 ; tmp_0 = m + m1; + ADD,L m1_1,m_1,tmp_1 ; tmp_1 = m + m1; + LDD -32(%sp),lt_0 + LDD -64(%sp),lt_1 + + CMPCLR,*>>= tmp_0,m1_0, %r0 ; if (m < m1) + ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32) + CMPCLR,*>>= tmp_1,m1_1,%r0 ; if (m < m1) + ADD,L ht_1,top_overflow,ht_1 ; ht += (1<<32) + + EXTRD,U tmp_0,31,32,m_0 ; m>>32 + DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32 + EXTRD,U tmp_1,31,32,m_1 ; m>>32 + DEPD,Z tmp_1,31,32,m1_1 ; m1 = m<<32 + + ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32) + ADD,L ht_1,m_1,ht_1 ; ht+= (m>>32) + ADD lt_0,m1_0,lt_0 ; lt = lt+m1; + ADD,DC ht_0,%r0,ht_0 ; ht++ + + ADD lt_1,m1_1,lt_1 ; lt = lt+m1; + ADD,DC ht_1,%r0,ht_1 ; ht++ + ADD %ret0,lt_0,lt_0 ; lt = lt + c (ret0); + ADD,DC ht_0,%r0,ht_0 ; ht++ + + ADD ht_0,lt_1,lt_1 ; lt = lt + c (ht_0) + ADD,DC ht_1,%r0,ht_1 ; ht++ + STD lt_0,0(r_ptr) ; rp[0] = lt + STD lt_1,8(r_ptr) ; rp[1] = lt + + COPY ht_1,%ret0 ; carry = ht + LDO -2(num),num ; num = num - 2; + LDO 16(a_ptr),a_ptr ; ap += 2 + CMPIB,<= 2,num,bn_mul_words_unroll2 + LDO 16(r_ptr),r_ptr ; rp++ + + CMPIB,=,N 0,num,bn_mul_words_exit ; are we done? + + ; + ; Top of loop aligned on 64-byte boundary + ; +bn_mul_words_single_top + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + + XMPYU fht_0,fw_l,fm1 ; m1 = ht*fw_l + FSTD fm1,-16(%sp) ; -16(sp) = m1 + XMPYU flt_0,fw_h,fm ; m = lt*fw_h + FSTD fm,-8(%sp) ; -8(sp) = m + XMPYU fht_0,fw_h,ht_temp ; ht_temp = ht*fw_h + FSTD ht_temp,-24(%sp) ; -24(sp) = ht + XMPYU flt_0,fw_l,lt_temp ; lt_temp = lt*fw_l + FSTD lt_temp,-32(%sp) ; -32(sp) = lt + + LDD -8(%sp),m_0 + LDD -16(%sp),m1_0 + ADD,L m_0,m1_0,tmp_0 ; tmp_0 = m + m1; + LDD -24(%sp),ht_0 + LDD -32(%sp),lt_0 + + CMPCLR,*>>= tmp_0,m1_0,%r0 ; if (m < m1) + ADD,L ht_0,top_overflow,ht_0 ; ht += (1<<32) + + EXTRD,U tmp_0,31,32,m_0 ; m>>32 + DEPD,Z tmp_0,31,32,m1_0 ; m1 = m<<32 + + ADD,L ht_0,m_0,ht_0 ; ht+= (m>>32) + ADD lt_0,m1_0,lt_0 ; lt= lt+m1; + ADD,DC ht_0,%r0,ht_0 ; ht++ + + ADD %ret0,lt_0,lt_0 ; lt = lt + c; + ADD,DC ht_0,%r0,ht_0 ; ht++ + + COPY ht_0,%ret0 ; copy carry + STD lt_0,0(r_ptr) ; rp[0] = lt + +bn_mul_words_exit + .EXIT + LDD -96(%sp),%r7 ; restore r7 + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 ; restore r3 + .PROCEND ;in=23,24,25,26,29;out=28; + +;---------------------------------------------------------------------------- +; +;void bn_sqr_words(BN_ULONG *rp, BN_ULONG *ap, int num) +; +; arg0 = rp +; arg1 = ap +; arg2 = num +; + +bn_sqr_words + .proc + .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_sqr_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + NOP + STD %r5,16(%sp) ; save r5 + + CMPIB,>= 0,num,bn_sqr_words_exit + LDO 128(%sp),%sp ; bump stack + + ; + ; If only 1, the goto straight to cleanup + ; + CMPIB,= 1,num,bn_sqr_words_single_top + DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; + +bn_sqr_words_unroll2 + FLDD 0(a_ptr),t_float_0 ; a[0] + FLDD 8(a_ptr),t_float_1 ; a[1] + XMPYU fht_0,flt_0,fm ; m[0] + XMPYU fht_1,flt_1,fm_1 ; m[1] + + FSTD fm,-24(%sp) ; store m[0] + FSTD fm_1,-56(%sp) ; store m[1] + XMPYU flt_0,flt_0,lt_temp ; lt[0] + XMPYU flt_1,flt_1,lt_temp_1 ; lt[1] + + FSTD lt_temp,-16(%sp) ; store lt[0] + FSTD lt_temp_1,-48(%sp) ; store lt[1] + XMPYU fht_0,fht_0,ht_temp ; ht[0] + XMPYU fht_1,fht_1,ht_temp_1 ; ht[1] + + FSTD ht_temp,-8(%sp) ; store ht[0] + FSTD ht_temp_1,-40(%sp) ; store ht[1] + LDD -24(%sp),m_0 + LDD -56(%sp),m_1 + + AND m_0,high_mask,tmp_0 ; m[0] & Mask + AND m_1,high_mask,tmp_1 ; m[1] & Mask + DEPD,Z m_0,30,31,m_0 ; m[0] << 32+1 + DEPD,Z m_1,30,31,m_1 ; m[1] << 32+1 + + LDD -16(%sp),lt_0 + LDD -48(%sp),lt_1 + EXTRD,U tmp_0,32,33,tmp_0 ; tmp_0 = m[0]&Mask >> 32-1 + EXTRD,U tmp_1,32,33,tmp_1 ; tmp_1 = m[1]&Mask >> 32-1 + + LDD -8(%sp),ht_0 + LDD -40(%sp),ht_1 + ADD,L ht_0,tmp_0,ht_0 ; ht[0] += tmp_0 + ADD,L ht_1,tmp_1,ht_1 ; ht[1] += tmp_1 + + ADD lt_0,m_0,lt_0 ; lt = lt+m + ADD,DC ht_0,%r0,ht_0 ; ht[0]++ + STD lt_0,0(r_ptr) ; rp[0] = lt[0] + STD ht_0,8(r_ptr) ; rp[1] = ht[1] + + ADD lt_1,m_1,lt_1 ; lt = lt+m + ADD,DC ht_1,%r0,ht_1 ; ht[1]++ + STD lt_1,16(r_ptr) ; rp[2] = lt[1] + STD ht_1,24(r_ptr) ; rp[3] = ht[1] + + LDO -2(num),num ; num = num - 2; + LDO 16(a_ptr),a_ptr ; ap += 2 + CMPIB,<= 2,num,bn_sqr_words_unroll2 + LDO 32(r_ptr),r_ptr ; rp += 4 + + CMPIB,=,N 0,num,bn_sqr_words_exit ; are we done? + + ; + ; Top of loop aligned on 64-byte boundary + ; +bn_sqr_words_single_top + FLDD 0(a_ptr),t_float_0 ; load up 64-bit value (fr8L) ht(L)/lt(R) + + XMPYU fht_0,flt_0,fm ; m + FSTD fm,-24(%sp) ; store m + + XMPYU flt_0,flt_0,lt_temp ; lt + FSTD lt_temp,-16(%sp) ; store lt + + XMPYU fht_0,fht_0,ht_temp ; ht + FSTD ht_temp,-8(%sp) ; store ht + + LDD -24(%sp),m_0 ; load m + AND m_0,high_mask,tmp_0 ; m & Mask + DEPD,Z m_0,30,31,m_0 ; m << 32+1 + LDD -16(%sp),lt_0 ; lt + + LDD -8(%sp),ht_0 ; ht + EXTRD,U tmp_0,32,33,tmp_0 ; tmp_0 = m&Mask >> 32-1 + ADD m_0,lt_0,lt_0 ; lt = lt+m + ADD,L ht_0,tmp_0,ht_0 ; ht += tmp_0 + ADD,DC ht_0,%r0,ht_0 ; ht++ + + STD lt_0,0(r_ptr) ; rp[0] = lt + STD ht_0,8(r_ptr) ; rp[1] = ht + +bn_sqr_words_exit + .EXIT + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + .PROCEND ;in=23,24,25,26,29;out=28; + + +;---------------------------------------------------------------------------- +; +;BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) +; +; arg0 = rp +; arg1 = ap +; arg2 = bp +; arg3 = n + +t .reg %r22 +b .reg %r21 +l .reg %r20 + +bn_add_words + .proc + .entry + .callinfo + .EXPORT bn_add_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .align 64 + + CMPIB,>= 0,n,bn_add_words_exit + COPY %r0,%ret0 ; return 0 by default + + ; + ; If 2 or more numbers do the loop + ; + CMPIB,= 1,n,bn_add_words_single_top + NOP + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; +bn_add_words_unroll2 + LDD 0(a_ptr),t + LDD 0(b_ptr),b + ADD t,%ret0,t ; t = t+c; + ADD,DC %r0,%r0,%ret0 ; set c to carry + ADD t,b,l ; l = t + b[0] + ADD,DC %ret0,%r0,%ret0 ; c+= carry + STD l,0(r_ptr) + + LDD 8(a_ptr),t + LDD 8(b_ptr),b + ADD t,%ret0,t ; t = t+c; + ADD,DC %r0,%r0,%ret0 ; set c to carry + ADD t,b,l ; l = t + b[0] + ADD,DC %ret0,%r0,%ret0 ; c+= carry + STD l,8(r_ptr) + + LDO -2(n),n + LDO 16(a_ptr),a_ptr + LDO 16(b_ptr),b_ptr + + CMPIB,<= 2,n,bn_add_words_unroll2 + LDO 16(r_ptr),r_ptr + + CMPIB,=,N 0,n,bn_add_words_exit ; are we done? + +bn_add_words_single_top + LDD 0(a_ptr),t + LDD 0(b_ptr),b + + ADD t,%ret0,t ; t = t+c; + ADD,DC %r0,%r0,%ret0 ; set c to carry (could use CMPCLR??) + ADD t,b,l ; l = t + b[0] + ADD,DC %ret0,%r0,%ret0 ; c+= carry + STD l,0(r_ptr) + +bn_add_words_exit + .EXIT + BVE (%rp) + NOP + .PROCEND ;in=23,24,25,26,29;out=28; + +;---------------------------------------------------------------------------- +; +;BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) +; +; arg0 = rp +; arg1 = ap +; arg2 = bp +; arg3 = n + +t1 .reg %r22 +t2 .reg %r21 +sub_tmp1 .reg %r20 +sub_tmp2 .reg %r19 + + +bn_sub_words + .proc + .callinfo + .EXPORT bn_sub_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + + CMPIB,>= 0,n,bn_sub_words_exit + COPY %r0,%ret0 ; return 0 by default + + ; + ; If 2 or more numbers do the loop + ; + CMPIB,= 1,n,bn_sub_words_single_top + NOP + + ; + ; This loop is unrolled 2 times (64-byte aligned as well) + ; +bn_sub_words_unroll2 + LDD 0(a_ptr),t1 + LDD 0(b_ptr),t2 + SUB t1,t2,sub_tmp1 ; t3 = t1-t2; + SUB sub_tmp1,%ret0,sub_tmp1 ; t3 = t3- c; + + CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2 + LDO 1(%r0),sub_tmp2 + + CMPCLR,*= t1,t2,%r0 + COPY sub_tmp2,%ret0 + STD sub_tmp1,0(r_ptr) + + LDD 8(a_ptr),t1 + LDD 8(b_ptr),t2 + SUB t1,t2,sub_tmp1 ; t3 = t1-t2; + SUB sub_tmp1,%ret0,sub_tmp1 ; t3 = t3- c; + CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2 + LDO 1(%r0),sub_tmp2 + + CMPCLR,*= t1,t2,%r0 + COPY sub_tmp2,%ret0 + STD sub_tmp1,8(r_ptr) + + LDO -2(n),n + LDO 16(a_ptr),a_ptr + LDO 16(b_ptr),b_ptr + + CMPIB,<= 2,n,bn_sub_words_unroll2 + LDO 16(r_ptr),r_ptr + + CMPIB,=,N 0,n,bn_sub_words_exit ; are we done? + +bn_sub_words_single_top + LDD 0(a_ptr),t1 + LDD 0(b_ptr),t2 + SUB t1,t2,sub_tmp1 ; t3 = t1-t2; + SUB sub_tmp1,%ret0,sub_tmp1 ; t3 = t3- c; + CMPCLR,*>> t1,t2,sub_tmp2 ; clear if t1 > t2 + LDO 1(%r0),sub_tmp2 + + CMPCLR,*= t1,t2,%r0 + COPY sub_tmp2,%ret0 + + STD sub_tmp1,0(r_ptr) + +bn_sub_words_exit + .EXIT + BVE (%rp) + NOP + .PROCEND ;in=23,24,25,26,29;out=28; + +;------------------------------------------------------------------------------ +; +; unsigned long bn_div_words(unsigned long h, unsigned long l, unsigned long d) +; +; arg0 = h +; arg1 = l +; arg2 = d +; +; This is mainly just modified assembly from the compiler, thus the +; lack of variable names. +; +;------------------------------------------------------------------------------ +bn_div_words + .proc + .callinfo CALLER,FRAME=272,ENTRY_GR=%r10,SAVE_RP,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_div_words,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .IMPORT BN_num_bits_word,CODE,NO_RELOCATION + .IMPORT __iob,DATA + .IMPORT fprintf,CODE,NO_RELOCATION + .IMPORT abort,CODE,NO_RELOCATION + .IMPORT $$div2U,MILLICODE + .entry + STD %r2,-16(%r30) + STD,MA %r3,352(%r30) + STD %r4,-344(%r30) + STD %r5,-336(%r30) + STD %r6,-328(%r30) + STD %r7,-320(%r30) + STD %r8,-312(%r30) + STD %r9,-304(%r30) + STD %r10,-296(%r30) + + STD %r27,-288(%r30) ; save gp + + COPY %r24,%r3 ; save d + COPY %r26,%r4 ; save h (high 64-bits) + LDO -1(%r0),%ret0 ; return -1 by default + + CMPB,*= %r0,%arg2,$D3 ; if (d == 0) + COPY %r25,%r5 ; save l (low 64-bits) + + LDO -48(%r30),%r29 ; create ap + .CALL ;in=26,29;out=28; + B,L BN_num_bits_word,%r2 + COPY %r3,%r26 + LDD -288(%r30),%r27 ; restore gp + LDI 64,%r21 + + CMPB,= %r21,%ret0,$00000012 ;if (i == 64) (forward) + COPY %ret0,%r24 ; i + MTSARCM %r24 + DEPDI,Z -1,%sar,1,%r29 + CMPB,*<<,N %r29,%r4,bn_div_err_case ; if (h > 1<= d) + SUB %r4,%r3,%r4 ; h -= d + CMPB,= %r31,%r0,$0000001A ; if (i) + COPY %r0,%r10 ; ret = 0 + MTSARCM %r31 ; i to shift + DEPD,Z %r3,%sar,64,%r3 ; d <<= i; + SUBI 64,%r31,%r19 ; 64 - i; redundent + MTSAR %r19 ; (64 -i) to shift + SHRPD %r4,%r5,%sar,%r4 ; l>> (64-i) + MTSARCM %r31 ; i to shift + DEPD,Z %r5,%sar,64,%r5 ; l <<= i; + +$0000001A + DEPDI,Z -1,31,32,%r19 + EXTRD,U %r3,31,32,%r6 ; dh=(d&0xfff)>>32 + EXTRD,U %r3,63,32,%r8 ; dl = d&0xffffff + LDO 2(%r0),%r9 + STD %r3,-280(%r30) ; "d" to stack + +$0000001C + DEPDI,Z -1,63,32,%r29 ; + EXTRD,U %r4,31,32,%r31 ; h >> 32 + CMPB,*=,N %r31,%r6,$D2 ; if ((h>>32) != dh)(forward) div + COPY %r4,%r26 + EXTRD,U %r4,31,32,%r25 + COPY %r6,%r24 + .CALL ;in=23,24,25,26;out=20,21,22,28,29; (MILLICALL) + B,L $$div2U,%r2 + EXTRD,U %r6,31,32,%r23 + DEPD %r28,31,32,%r29 +$D2 + STD %r29,-272(%r30) ; q + AND %r5,%r19,%r24 ; t & 0xffffffff00000000; + EXTRD,U %r24,31,32,%r24 ; ??? + FLDD -272(%r30),%fr7 ; q + FLDD -280(%r30),%fr8 ; d + XMPYU %fr8L,%fr7L,%fr10 + FSTD %fr10,-256(%r30) + XMPYU %fr8L,%fr7R,%fr22 + FSTD %fr22,-264(%r30) + XMPYU %fr8R,%fr7L,%fr11 + XMPYU %fr8R,%fr7R,%fr23 + FSTD %fr11,-232(%r30) + FSTD %fr23,-240(%r30) + LDD -256(%r30),%r28 + DEPD,Z %r28,31,32,%r2 + LDD -264(%r30),%r20 + ADD,L %r20,%r2,%r31 + LDD -232(%r30),%r22 + DEPD,Z %r22,31,32,%r22 + LDD -240(%r30),%r21 + B $00000024 ; enter loop + ADD,L %r21,%r22,%r23 + +$0000002A + LDO -1(%r29),%r29 + SUB %r23,%r8,%r23 +$00000024 + SUB %r4,%r31,%r25 + AND %r25,%r19,%r26 + CMPB,*<>,N %r0,%r26,$00000046 ; (forward) + DEPD,Z %r25,31,32,%r20 + OR %r20,%r24,%r21 + CMPB,*<<,N %r21,%r23,$0000002A ;(backward) + SUB %r31,%r6,%r31 +;-------------Break path--------------------- + +$00000046 + DEPD,Z %r23,31,32,%r25 ;tl + EXTRD,U %r23,31,32,%r26 ;t + AND %r25,%r19,%r24 ;tl = (tl<<32)&0xfffffff0000000L + ADD,L %r31,%r26,%r31 ;th += t; + CMPCLR,*>>= %r5,%r24,%r0 ;if (l>32)); + DEPD,Z %r29,31,32,%r10 ; ret = q<<32 + b $0000001C + DEPD,Z %r28,31,32,%r5 ; l = l << 32 + +$D1 + OR %r10,%r29,%r28 ; ret |= q +$D3 + LDD -368(%r30),%r2 +$D0 + LDD -296(%r30),%r10 + LDD -304(%r30),%r9 + LDD -312(%r30),%r8 + LDD -320(%r30),%r7 + LDD -328(%r30),%r6 + LDD -336(%r30),%r5 + LDD -344(%r30),%r4 + BVE (%r2) + .EXIT + LDD,MB -352(%r30),%r3 + +bn_div_err_case + MFIA %r6 + ADDIL L'bn_div_words-bn_div_err_case,%r6,%r1 + LDO R'bn_div_words-bn_div_err_case(%r1),%r6 + ADDIL LT'__iob,%r27,%r1 + LDD RT'__iob(%r1),%r26 + ADDIL L'C$4-bn_div_words,%r6,%r1 + LDO R'C$4-bn_div_words(%r1),%r25 + LDO 64(%r26),%r26 + .CALL ;in=24,25,26,29;out=28; + B,L fprintf,%r2 + LDO -48(%r30),%r29 + LDD -288(%r30),%r27 + .CALL ;in=29; + B,L abort,%r2 + LDO -48(%r30),%r29 + LDD -288(%r30),%r27 + B $D0 + LDD -368(%r30),%r2 + .PROCEND ;in=24,25,26,29;out=28; + +;---------------------------------------------------------------------------- +; +; Registers to hold 64-bit values to manipulate. The "L" part +; of the register corresponds to the upper 32-bits, while the "R" +; part corresponds to the lower 32-bits +; +; Note, that when using b6 and b7, the code must save these before +; using them because they are callee save registers +; +; +; Floating point registers to use to save values that +; are manipulated. These don't collide with ftemp1-6 and +; are all caller save registers +; +a0 .reg %fr22 +a0L .reg %fr22L +a0R .reg %fr22R + +a1 .reg %fr23 +a1L .reg %fr23L +a1R .reg %fr23R + +a2 .reg %fr24 +a2L .reg %fr24L +a2R .reg %fr24R + +a3 .reg %fr25 +a3L .reg %fr25L +a3R .reg %fr25R + +a4 .reg %fr26 +a4L .reg %fr26L +a4R .reg %fr26R + +a5 .reg %fr27 +a5L .reg %fr27L +a5R .reg %fr27R + +a6 .reg %fr28 +a6L .reg %fr28L +a6R .reg %fr28R + +a7 .reg %fr29 +a7L .reg %fr29L +a7R .reg %fr29R + +b0 .reg %fr30 +b0L .reg %fr30L +b0R .reg %fr30R + +b1 .reg %fr31 +b1L .reg %fr31L +b1R .reg %fr31R + +; +; Temporary floating point variables, these are all caller save +; registers +; +ftemp1 .reg %fr4 +ftemp2 .reg %fr5 +ftemp3 .reg %fr6 +ftemp4 .reg %fr7 + +; +; The B set of registers when used. +; + +b2 .reg %fr8 +b2L .reg %fr8L +b2R .reg %fr8R + +b3 .reg %fr9 +b3L .reg %fr9L +b3R .reg %fr9R + +b4 .reg %fr10 +b4L .reg %fr10L +b4R .reg %fr10R + +b5 .reg %fr11 +b5L .reg %fr11L +b5R .reg %fr11R + +b6 .reg %fr12 +b6L .reg %fr12L +b6R .reg %fr12R + +b7 .reg %fr13 +b7L .reg %fr13L +b7R .reg %fr13R + +c1 .reg %r21 ; only reg +temp1 .reg %r20 ; only reg +temp2 .reg %r19 ; only reg +temp3 .reg %r31 ; only reg + +m1 .reg %r28 +c2 .reg %r23 +high_one .reg %r1 +ht .reg %r6 +lt .reg %r5 +m .reg %r4 +c3 .reg %r3 + +SQR_ADD_C .macro A0L,A0R,C1,C2,C3 + XMPYU A0L,A0R,ftemp1 ; m + FSTD ftemp1,-24(%sp) ; store m + + XMPYU A0R,A0R,ftemp2 ; lt + FSTD ftemp2,-16(%sp) ; store lt + + XMPYU A0L,A0L,ftemp3 ; ht + FSTD ftemp3,-8(%sp) ; store ht + + LDD -24(%sp),m ; load m + AND m,high_mask,temp2 ; m & Mask + DEPD,Z m,30,31,temp3 ; m << 32+1 + LDD -16(%sp),lt ; lt + + LDD -8(%sp),ht ; ht + EXTRD,U temp2,32,33,temp1 ; temp1 = m&Mask >> 32-1 + ADD temp3,lt,lt ; lt = lt+m + ADD,L ht,temp1,ht ; ht += temp1 + ADD,DC ht,%r0,ht ; ht++ + + ADD C1,lt,C1 ; c1=c1+lt + ADD,DC ht,%r0,ht ; ht++ + + ADD C2,ht,C2 ; c2=c2+ht + ADD,DC C3,%r0,C3 ; c3++ +.endm + +SQR_ADD_C2 .macro A0L,A0R,A1L,A1R,C1,C2,C3 + XMPYU A0L,A1R,ftemp1 ; m1 = bl*ht + FSTD ftemp1,-16(%sp) ; + XMPYU A0R,A1L,ftemp2 ; m = bh*lt + FSTD ftemp2,-8(%sp) ; + XMPYU A0R,A1R,ftemp3 ; lt = bl*lt + FSTD ftemp3,-32(%sp) + XMPYU A0L,A1L,ftemp4 ; ht = bh*ht + FSTD ftemp4,-24(%sp) ; + + LDD -8(%sp),m ; r21 = m + LDD -16(%sp),m1 ; r19 = m1 + ADD,L m,m1,m ; m+m1 + + DEPD,Z m,31,32,temp3 ; (m+m1<<32) + LDD -24(%sp),ht ; r24 = ht + + CMPCLR,*>>= m,m1,%r0 ; if (m < m1) + ADD,L ht,high_one,ht ; ht+=high_one + + EXTRD,U m,31,32,temp1 ; m >> 32 + LDD -32(%sp),lt ; lt + ADD,L ht,temp1,ht ; ht+= m>>32 + ADD lt,temp3,lt ; lt = lt+m1 + ADD,DC ht,%r0,ht ; ht++ + + ADD ht,ht,ht ; ht=ht+ht; + ADD,DC C3,%r0,C3 ; add in carry (c3++) + + ADD lt,lt,lt ; lt=lt+lt; + ADD,DC ht,%r0,ht ; add in carry (ht++) + + ADD C1,lt,C1 ; c1=c1+lt + ADD,DC,*NUV ht,%r0,ht ; add in carry (ht++) + LDO 1(C3),C3 ; bump c3 if overflow,nullify otherwise + + ADD C2,ht,C2 ; c2 = c2 + ht + ADD,DC C3,%r0,C3 ; add in carry (c3++) +.endm + +; +;void bn_sqr_comba8(BN_ULONG *r, BN_ULONG *a) +; arg0 = r_ptr +; arg1 = a_ptr +; + +bn_sqr_comba8 + .PROC + .CALLINFO FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_sqr_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .ENTRY + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + + ; + ; Zero out carries + ; + COPY %r0,c1 + COPY %r0,c2 + COPY %r0,c3 + + LDO 128(%sp),%sp ; bump stack + DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L + DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 + + ; + ; Load up all of the values we are going to use + ; + FLDD 0(a_ptr),a0 + FLDD 8(a_ptr),a1 + FLDD 16(a_ptr),a2 + FLDD 24(a_ptr),a3 + FLDD 32(a_ptr),a4 + FLDD 40(a_ptr),a5 + FLDD 48(a_ptr),a6 + FLDD 56(a_ptr),a7 + + SQR_ADD_C a0L,a0R,c1,c2,c3 + STD c1,0(r_ptr) ; r[0] = c1; + COPY %r0,c1 + + SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1 + STD c2,8(r_ptr) ; r[1] = c2; + COPY %r0,c2 + + SQR_ADD_C a1L,a1R,c3,c1,c2 + SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2 + STD c3,16(r_ptr) ; r[2] = c3; + COPY %r0,c3 + + SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3 + SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3 + STD c1,24(r_ptr) ; r[3] = c1; + COPY %r0,c1 + + SQR_ADD_C a2L,a2R,c2,c3,c1 + SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1 + SQR_ADD_C2 a4L,a4R,a0L,a0R,c2,c3,c1 + STD c2,32(r_ptr) ; r[4] = c2; + COPY %r0,c2 + + SQR_ADD_C2 a5L,a5R,a0L,a0R,c3,c1,c2 + SQR_ADD_C2 a4L,a4R,a1L,a1R,c3,c1,c2 + SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2 + STD c3,40(r_ptr) ; r[5] = c3; + COPY %r0,c3 + + SQR_ADD_C a3L,a3R,c1,c2,c3 + SQR_ADD_C2 a4L,a4R,a2L,a2R,c1,c2,c3 + SQR_ADD_C2 a5L,a5R,a1L,a1R,c1,c2,c3 + SQR_ADD_C2 a6L,a6R,a0L,a0R,c1,c2,c3 + STD c1,48(r_ptr) ; r[6] = c1; + COPY %r0,c1 + + SQR_ADD_C2 a7L,a7R,a0L,a0R,c2,c3,c1 + SQR_ADD_C2 a6L,a6R,a1L,a1R,c2,c3,c1 + SQR_ADD_C2 a5L,a5R,a2L,a2R,c2,c3,c1 + SQR_ADD_C2 a4L,a4R,a3L,a3R,c2,c3,c1 + STD c2,56(r_ptr) ; r[7] = c2; + COPY %r0,c2 + + SQR_ADD_C a4L,a4R,c3,c1,c2 + SQR_ADD_C2 a5L,a5R,a3L,a3R,c3,c1,c2 + SQR_ADD_C2 a6L,a6R,a2L,a2R,c3,c1,c2 + SQR_ADD_C2 a7L,a7R,a1L,a1R,c3,c1,c2 + STD c3,64(r_ptr) ; r[8] = c3; + COPY %r0,c3 + + SQR_ADD_C2 a7L,a7R,a2L,a2R,c1,c2,c3 + SQR_ADD_C2 a6L,a6R,a3L,a3R,c1,c2,c3 + SQR_ADD_C2 a5L,a5R,a4L,a4R,c1,c2,c3 + STD c1,72(r_ptr) ; r[9] = c1; + COPY %r0,c1 + + SQR_ADD_C a5L,a5R,c2,c3,c1 + SQR_ADD_C2 a6L,a6R,a4L,a4R,c2,c3,c1 + SQR_ADD_C2 a7L,a7R,a3L,a3R,c2,c3,c1 + STD c2,80(r_ptr) ; r[10] = c2; + COPY %r0,c2 + + SQR_ADD_C2 a7L,a7R,a4L,a4R,c3,c1,c2 + SQR_ADD_C2 a6L,a6R,a5L,a5R,c3,c1,c2 + STD c3,88(r_ptr) ; r[11] = c3; + COPY %r0,c3 + + SQR_ADD_C a6L,a6R,c1,c2,c3 + SQR_ADD_C2 a7L,a7R,a5L,a5R,c1,c2,c3 + STD c1,96(r_ptr) ; r[12] = c1; + COPY %r0,c1 + + SQR_ADD_C2 a7L,a7R,a6L,a6R,c2,c3,c1 + STD c2,104(r_ptr) ; r[13] = c2; + COPY %r0,c2 + + SQR_ADD_C a7L,a7R,c3,c1,c2 + STD c3, 112(r_ptr) ; r[14] = c3 + STD c1, 120(r_ptr) ; r[15] = c1 + + .EXIT + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + + .PROCEND + +;----------------------------------------------------------------------------- +; +;void bn_sqr_comba4(BN_ULONG *r, BN_ULONG *a) +; arg0 = r_ptr +; arg1 = a_ptr +; + +bn_sqr_comba4 + .proc + .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_sqr_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + + ; + ; Zero out carries + ; + COPY %r0,c1 + COPY %r0,c2 + COPY %r0,c3 + + LDO 128(%sp),%sp ; bump stack + DEPDI,Z -1,32,33,high_mask ; Create Mask 0xffffffff80000000L + DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 + + ; + ; Load up all of the values we are going to use + ; + FLDD 0(a_ptr),a0 + FLDD 8(a_ptr),a1 + FLDD 16(a_ptr),a2 + FLDD 24(a_ptr),a3 + FLDD 32(a_ptr),a4 + FLDD 40(a_ptr),a5 + FLDD 48(a_ptr),a6 + FLDD 56(a_ptr),a7 + + SQR_ADD_C a0L,a0R,c1,c2,c3 + + STD c1,0(r_ptr) ; r[0] = c1; + COPY %r0,c1 + + SQR_ADD_C2 a1L,a1R,a0L,a0R,c2,c3,c1 + + STD c2,8(r_ptr) ; r[1] = c2; + COPY %r0,c2 + + SQR_ADD_C a1L,a1R,c3,c1,c2 + SQR_ADD_C2 a2L,a2R,a0L,a0R,c3,c1,c2 + + STD c3,16(r_ptr) ; r[2] = c3; + COPY %r0,c3 + + SQR_ADD_C2 a3L,a3R,a0L,a0R,c1,c2,c3 + SQR_ADD_C2 a2L,a2R,a1L,a1R,c1,c2,c3 + + STD c1,24(r_ptr) ; r[3] = c1; + COPY %r0,c1 + + SQR_ADD_C a2L,a2R,c2,c3,c1 + SQR_ADD_C2 a3L,a3R,a1L,a1R,c2,c3,c1 + + STD c2,32(r_ptr) ; r[4] = c2; + COPY %r0,c2 + + SQR_ADD_C2 a3L,a3R,a2L,a2R,c3,c1,c2 + STD c3,40(r_ptr) ; r[5] = c3; + COPY %r0,c3 + + SQR_ADD_C a3L,a3R,c1,c2,c3 + STD c1,48(r_ptr) ; r[6] = c1; + STD c2,56(r_ptr) ; r[7] = c2; + + .EXIT + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + + .PROCEND + + +;--------------------------------------------------------------------------- + +MUL_ADD_C .macro A0L,A0R,B0L,B0R,C1,C2,C3 + XMPYU A0L,B0R,ftemp1 ; m1 = bl*ht + FSTD ftemp1,-16(%sp) ; + XMPYU A0R,B0L,ftemp2 ; m = bh*lt + FSTD ftemp2,-8(%sp) ; + XMPYU A0R,B0R,ftemp3 ; lt = bl*lt + FSTD ftemp3,-32(%sp) + XMPYU A0L,B0L,ftemp4 ; ht = bh*ht + FSTD ftemp4,-24(%sp) ; + + LDD -8(%sp),m ; r21 = m + LDD -16(%sp),m1 ; r19 = m1 + ADD,L m,m1,m ; m+m1 + + DEPD,Z m,31,32,temp3 ; (m+m1<<32) + LDD -24(%sp),ht ; r24 = ht + + CMPCLR,*>>= m,m1,%r0 ; if (m < m1) + ADD,L ht,high_one,ht ; ht+=high_one + + EXTRD,U m,31,32,temp1 ; m >> 32 + LDD -32(%sp),lt ; lt + ADD,L ht,temp1,ht ; ht+= m>>32 + ADD lt,temp3,lt ; lt = lt+m1 + ADD,DC ht,%r0,ht ; ht++ + + ADD C1,lt,C1 ; c1=c1+lt + ADD,DC ht,%r0,ht ; bump c3 if overflow,nullify otherwise + + ADD C2,ht,C2 ; c2 = c2 + ht + ADD,DC C3,%r0,C3 ; add in carry (c3++) +.endm + + +; +;void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) +; arg0 = r_ptr +; arg1 = a_ptr +; arg2 = b_ptr +; + +bn_mul_comba8 + .proc + .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_mul_comba8,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + FSTD %fr12,32(%sp) ; save r6 + FSTD %fr13,40(%sp) ; save r7 + + ; + ; Zero out carries + ; + COPY %r0,c1 + COPY %r0,c2 + COPY %r0,c3 + + LDO 128(%sp),%sp ; bump stack + DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 + + ; + ; Load up all of the values we are going to use + ; + FLDD 0(a_ptr),a0 + FLDD 8(a_ptr),a1 + FLDD 16(a_ptr),a2 + FLDD 24(a_ptr),a3 + FLDD 32(a_ptr),a4 + FLDD 40(a_ptr),a5 + FLDD 48(a_ptr),a6 + FLDD 56(a_ptr),a7 + + FLDD 0(b_ptr),b0 + FLDD 8(b_ptr),b1 + FLDD 16(b_ptr),b2 + FLDD 24(b_ptr),b3 + FLDD 32(b_ptr),b4 + FLDD 40(b_ptr),b5 + FLDD 48(b_ptr),b6 + FLDD 56(b_ptr),b7 + + MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3 + STD c1,0(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1 + STD c2,8(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2 + MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2 + MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2 + STD c3,16(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3 + MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3 + MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3 + MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3 + STD c1,24(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a4L,a4R,b0L,b0R,c2,c3,c1 + MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1 + MUL_ADD_C a0L,a0R,b4L,b4R,c2,c3,c1 + STD c2,32(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a0L,a0R,b5L,b5R,c3,c1,c2 + MUL_ADD_C a1L,a1R,b4L,b4R,c3,c1,c2 + MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2 + MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2 + MUL_ADD_C a4L,a4R,b1L,b1R,c3,c1,c2 + MUL_ADD_C a5L,a5R,b0L,b0R,c3,c1,c2 + STD c3,40(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a6L,a6R,b0L,b0R,c1,c2,c3 + MUL_ADD_C a5L,a5R,b1L,b1R,c1,c2,c3 + MUL_ADD_C a4L,a4R,b2L,b2R,c1,c2,c3 + MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3 + MUL_ADD_C a2L,a2R,b4L,b4R,c1,c2,c3 + MUL_ADD_C a1L,a1R,b5L,b5R,c1,c2,c3 + MUL_ADD_C a0L,a0R,b6L,b6R,c1,c2,c3 + STD c1,48(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a0L,a0R,b7L,b7R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b6L,b6R,c2,c3,c1 + MUL_ADD_C a2L,a2R,b5L,b5R,c2,c3,c1 + MUL_ADD_C a3L,a3R,b4L,b4R,c2,c3,c1 + MUL_ADD_C a4L,a4R,b3L,b3R,c2,c3,c1 + MUL_ADD_C a5L,a5R,b2L,b2R,c2,c3,c1 + MUL_ADD_C a6L,a6R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a7L,a7R,b0L,b0R,c2,c3,c1 + STD c2,56(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a7L,a7R,b1L,b1R,c3,c1,c2 + MUL_ADD_C a6L,a6R,b2L,b2R,c3,c1,c2 + MUL_ADD_C a5L,a5R,b3L,b3R,c3,c1,c2 + MUL_ADD_C a4L,a4R,b4L,b4R,c3,c1,c2 + MUL_ADD_C a3L,a3R,b5L,b5R,c3,c1,c2 + MUL_ADD_C a2L,a2R,b6L,b6R,c3,c1,c2 + MUL_ADD_C a1L,a1R,b7L,b7R,c3,c1,c2 + STD c3,64(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a2L,a2R,b7L,b7R,c1,c2,c3 + MUL_ADD_C a3L,a3R,b6L,b6R,c1,c2,c3 + MUL_ADD_C a4L,a4R,b5L,b5R,c1,c2,c3 + MUL_ADD_C a5L,a5R,b4L,b4R,c1,c2,c3 + MUL_ADD_C a6L,a6R,b3L,b3R,c1,c2,c3 + MUL_ADD_C a7L,a7R,b2L,b2R,c1,c2,c3 + STD c1,72(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a7L,a7R,b3L,b3R,c2,c3,c1 + MUL_ADD_C a6L,a6R,b4L,b4R,c2,c3,c1 + MUL_ADD_C a5L,a5R,b5L,b5R,c2,c3,c1 + MUL_ADD_C a4L,a4R,b6L,b6R,c2,c3,c1 + MUL_ADD_C a3L,a3R,b7L,b7R,c2,c3,c1 + STD c2,80(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a4L,a4R,b7L,b7R,c3,c1,c2 + MUL_ADD_C a5L,a5R,b6L,b6R,c3,c1,c2 + MUL_ADD_C a6L,a6R,b5L,b5R,c3,c1,c2 + MUL_ADD_C a7L,a7R,b4L,b4R,c3,c1,c2 + STD c3,88(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a7L,a7R,b5L,b5R,c1,c2,c3 + MUL_ADD_C a6L,a6R,b6L,b6R,c1,c2,c3 + MUL_ADD_C a5L,a5R,b7L,b7R,c1,c2,c3 + STD c1,96(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a6L,a6R,b7L,b7R,c2,c3,c1 + MUL_ADD_C a7L,a7R,b6L,b6R,c2,c3,c1 + STD c2,104(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a7L,a7R,b7L,b7R,c3,c1,c2 + STD c3,112(r_ptr) + STD c1,120(r_ptr) + + .EXIT + FLDD -88(%sp),%fr13 + FLDD -96(%sp),%fr12 + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + + .PROCEND + +;----------------------------------------------------------------------------- +; +;void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) +; arg0 = r_ptr +; arg1 = a_ptr +; arg2 = b_ptr +; + +bn_mul_comba4 + .proc + .callinfo FRAME=128,ENTRY_GR=%r3,ARGS_SAVED,ORDERING_AWARE + .EXPORT bn_mul_comba4,ENTRY,PRIV_LEV=3,NO_RELOCATION,LONG_RETURN + .entry + .align 64 + + STD %r3,0(%sp) ; save r3 + STD %r4,8(%sp) ; save r4 + STD %r5,16(%sp) ; save r5 + STD %r6,24(%sp) ; save r6 + FSTD %fr12,32(%sp) ; save r6 + FSTD %fr13,40(%sp) ; save r7 + + ; + ; Zero out carries + ; + COPY %r0,c1 + COPY %r0,c2 + COPY %r0,c3 + + LDO 128(%sp),%sp ; bump stack + DEPDI,Z 1,31,1,high_one ; Create Value 1 << 32 + + ; + ; Load up all of the values we are going to use + ; + FLDD 0(a_ptr),a0 + FLDD 8(a_ptr),a1 + FLDD 16(a_ptr),a2 + FLDD 24(a_ptr),a3 + + FLDD 0(b_ptr),b0 + FLDD 8(b_ptr),b1 + FLDD 16(b_ptr),b2 + FLDD 24(b_ptr),b3 + + MUL_ADD_C a0L,a0R,b0L,b0R,c1,c2,c3 + STD c1,0(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a0L,a0R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b0L,b0R,c2,c3,c1 + STD c2,8(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a2L,a2R,b0L,b0R,c3,c1,c2 + MUL_ADD_C a1L,a1R,b1L,b1R,c3,c1,c2 + MUL_ADD_C a0L,a0R,b2L,b2R,c3,c1,c2 + STD c3,16(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a0L,a0R,b3L,b3R,c1,c2,c3 + MUL_ADD_C a1L,a1R,b2L,b2R,c1,c2,c3 + MUL_ADD_C a2L,a2R,b1L,b1R,c1,c2,c3 + MUL_ADD_C a3L,a3R,b0L,b0R,c1,c2,c3 + STD c1,24(r_ptr) + COPY %r0,c1 + + MUL_ADD_C a3L,a3R,b1L,b1R,c2,c3,c1 + MUL_ADD_C a2L,a2R,b2L,b2R,c2,c3,c1 + MUL_ADD_C a1L,a1R,b3L,b3R,c2,c3,c1 + STD c2,32(r_ptr) + COPY %r0,c2 + + MUL_ADD_C a2L,a2R,b3L,b3R,c3,c1,c2 + MUL_ADD_C a3L,a3R,b2L,b2R,c3,c1,c2 + STD c3,40(r_ptr) + COPY %r0,c3 + + MUL_ADD_C a3L,a3R,b3L,b3R,c1,c2,c3 + STD c1,48(r_ptr) + STD c2,56(r_ptr) + + .EXIT + FLDD -88(%sp),%fr13 + FLDD -96(%sp),%fr12 + LDD -104(%sp),%r6 ; restore r6 + LDD -112(%sp),%r5 ; restore r5 + LDD -120(%sp),%r4 ; restore r4 + BVE (%rp) + LDD,MB -128(%sp),%r3 + + .PROCEND + + + .SPACE $TEXT$ + .SUBSPA $CODE$ + .SPACE $PRIVATE$,SORT=16 + .IMPORT $global$,DATA + .SPACE $TEXT$ + .SUBSPA $CODE$ + .SUBSPA $LIT$,ACCESS=0x2c +C$4 + .ALIGN 8 + .STRINGZ "Division would overflow (%d)\n" + .END diff --git a/libs/openssl/crypto/bn/asm/parisc-mont.pl b/libs/openssl/crypto/bn/asm/parisc-mont.pl new file mode 100644 index 00000000..c02ef6f0 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/parisc-mont.pl @@ -0,0 +1,995 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# On PA-7100LC this module performs ~90-50% better, less for longer +# keys, than code generated by gcc 3.2 for PA-RISC 1.1. Latter means +# that compiler utilized xmpyu instruction to perform 32x32=64-bit +# multiplication, which in turn means that "baseline" performance was +# optimal in respect to instruction set capabilities. Fair comparison +# with vendor compiler is problematic, because OpenSSL doesn't define +# BN_LLONG [presumably] for historical reasons, which drives compiler +# toward 4 times 16x16=32-bit multiplicatons [plus complementary +# shifts and additions] instead. This means that you should observe +# several times improvement over code generated by vendor compiler +# for PA-RISC 1.1, but the "baseline" is far from optimal. The actual +# improvement coefficient was never collected on PA-7100LC, or any +# other 1.1 CPU, because I don't have access to such machine with +# vendor compiler. But to give you a taste, PA-RISC 1.1 code path +# reportedly outperformed code generated by cc +DA1.1 +O3 by factor +# of ~5x on PA-8600. +# +# On PA-RISC 2.0 it has to compete with pa-risc2[W].s, which is +# reportedly ~2x faster than vendor compiler generated code [according +# to comment in pa-risc2[W].s]. Here comes a catch. Execution core of +# this implementation is actually 32-bit one, in the sense that it +# operates on 32-bit values. But pa-risc2[W].s operates on arrays of +# 64-bit BN_LONGs... How do they interoperate then? No problem. This +# module picks halves of 64-bit values in reverse order and pretends +# they were 32-bit BN_LONGs. But can 32-bit core compete with "pure" +# 64-bit code such as pa-risc2[W].s then? Well, the thing is that +# 32x32=64-bit multiplication is the best even PA-RISC 2.0 can do, +# i.e. there is no "wider" multiplication like on most other 64-bit +# platforms. This means that even being effectively 32-bit, this +# implementation performs "64-bit" computational task in same amount +# of arithmetic operations, most notably multiplications. It requires +# more memory references, most notably to tp[num], but this doesn't +# seem to exhaust memory port capacity. And indeed, dedicated PA-RISC +# 2.0 code path provides virtually same performance as pa-risc2[W].s: +# it's ~10% better for shortest key length and ~10% worse for longest +# one. +# +# In case it wasn't clear. The module has two distinct code paths: +# PA-RISC 1.1 and PA-RISC 2.0 ones. Latter features carry-free 64-bit +# additions and 64-bit integer loads, not to mention specific +# instruction scheduling. In 64-bit build naturally only 2.0 code path +# is assembled. In 32-bit application context both code paths are +# assembled, PA-RISC 2.0 CPU is detected at run-time and proper path +# is taken automatically. Also, in 32-bit build the module imposes +# couple of limitations: vector lengths has to be even and vector +# addresses has to be 64-bit aligned. Normally neither is a problem: +# most common key lengths are even and vectors are commonly malloc-ed, +# which ensures alignment. +# +# Special thanks to polarhome.com for providing HP-UX account on +# PA-RISC 1.1 machine, and to correspondent who chose to remain +# anonymous for testing the code on PA-RISC 2.0 machine. + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; + +$flavour = shift; +$output = shift; + +open STDOUT,">$output"; + +if ($flavour =~ /64/) { + $LEVEL ="2.0W"; + $SIZE_T =8; + $FRAME_MARKER =80; + $SAVED_RP =16; + $PUSH ="std"; + $PUSHMA ="std,ma"; + $POP ="ldd"; + $POPMB ="ldd,mb"; + $BN_SZ =$SIZE_T; +} else { + $LEVEL ="1.1"; #$LEVEL.="\n\t.ALLOW\t2.0"; + $SIZE_T =4; + $FRAME_MARKER =48; + $SAVED_RP =20; + $PUSH ="stw"; + $PUSHMA ="stwm"; + $POP ="ldw"; + $POPMB ="ldwm"; + $BN_SZ =$SIZE_T; + if (open CONF,"<${dir}../../opensslconf.h") { + while() { + if (m/#\s*define\s+SIXTY_FOUR_BIT/) { + $BN_SZ=8; + $LEVEL="2.0"; + last; + } + } + close CONF; + } +} + +$FRAME=8*$SIZE_T+$FRAME_MARKER; # 8 saved regs + frame marker + # [+ argument transfer] +$LOCALS=$FRAME-$FRAME_MARKER; +$FRAME+=32; # local variables + +$tp="%r31"; +$ti1="%r29"; +$ti0="%r28"; + +$rp="%r26"; +$ap="%r25"; +$bp="%r24"; +$np="%r23"; +$n0="%r22"; # passed through stack in 32-bit +$num="%r21"; # passed through stack in 32-bit +$idx="%r20"; +$arrsz="%r19"; + +$nm1="%r7"; +$nm0="%r6"; +$ab1="%r5"; +$ab0="%r4"; + +$fp="%r3"; +$hi1="%r2"; +$hi0="%r1"; + +$xfer=$n0; # accomodates [-16..15] offset in fld[dw]s + +$fm0="%fr4"; $fti=$fm0; +$fbi="%fr5L"; +$fn0="%fr5R"; +$fai="%fr6"; $fab0="%fr7"; $fab1="%fr8"; +$fni="%fr9"; $fnm0="%fr10"; $fnm1="%fr11"; + +$code=<<___; + .LEVEL $LEVEL + .SPACE \$TEXT\$ + .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY + + .EXPORT bn_mul_mont,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR + .ALIGN 64 +bn_mul_mont + .PROC + .CALLINFO FRAME=`$FRAME-8*$SIZE_T`,NO_CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=6 + .ENTRY + $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue + $PUSHMA %r3,$FRAME(%sp) + $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp) + $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp) + $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp) + $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp) + $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp) + $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp) + $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp) + ldo -$FRAME(%sp),$fp +___ +$code.=<<___ if ($SIZE_T==4); + ldw `-$FRAME_MARKER-4`($fp),$n0 + ldw `-$FRAME_MARKER-8`($fp),$num + nop + nop ; alignment +___ +$code.=<<___ if ($BN_SZ==4); + comiclr,<= 6,$num,%r0 ; are vectors long enough? + b L\$abort + ldi 0,%r28 ; signal "unhandled" + add,ev %r0,$num,$num ; is $num even? + b L\$abort + nop + or $ap,$np,$ti1 + extru,= $ti1,31,3,%r0 ; are ap and np 64-bit aligned? + b L\$abort + nop + nop ; alignment + nop + + fldws 0($n0),${fn0} + fldws,ma 4($bp),${fbi} ; bp[0] +___ +$code.=<<___ if ($BN_SZ==8); + comib,> 3,$num,L\$abort ; are vectors long enough? + ldi 0,%r28 ; signal "unhandled" + addl $num,$num,$num ; I operate on 32-bit values + + fldws 4($n0),${fn0} ; only low part of n0 + fldws 4($bp),${fbi} ; bp[0] in flipped word order +___ +$code.=<<___; + fldds 0($ap),${fai} ; ap[0,1] + fldds 0($np),${fni} ; np[0,1] + + sh2addl $num,%r0,$arrsz + ldi 31,$hi0 + ldo 36($arrsz),$hi1 ; space for tp[num+1] + andcm $hi1,$hi0,$hi1 ; align + addl $hi1,%sp,%sp + $PUSH $fp,-$SIZE_T(%sp) + + ldo `$LOCALS+16`($fp),$xfer + ldo `$LOCALS+32+4`($fp),$tp + + xmpyu ${fai}L,${fbi},${fab0} ; ap[0]*bp[0] + xmpyu ${fai}R,${fbi},${fab1} ; ap[1]*bp[0] + xmpyu ${fn0},${fab0}R,${fm0} + + addl $arrsz,$ap,$ap ; point at the end + addl $arrsz,$np,$np + subi 0,$arrsz,$idx ; j=0 + ldo 8($idx),$idx ; j++++ + + xmpyu ${fni}L,${fm0}R,${fnm0} ; np[0]*m + xmpyu ${fni}R,${fm0}R,${fnm1} ; np[1]*m + fstds ${fab0},-16($xfer) + fstds ${fnm0},-8($xfer) + fstds ${fab1},0($xfer) + fstds ${fnm1},8($xfer) + flddx $idx($ap),${fai} ; ap[2,3] + flddx $idx($np),${fni} ; np[2,3] +___ +$code.=<<___ if ($BN_SZ==4); + mtctl $hi0,%cr11 ; $hi0 still holds 31 + extrd,u,*= $hi0,%sar,1,$hi0 ; executes on PA-RISC 1.0 + b L\$parisc11 + nop +___ +$code.=<<___; # PA-RISC 2.0 code-path + xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[0] + xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m + ldd -16($xfer),$ab0 + fstds ${fab0},-16($xfer) + + extrd,u $ab0,31,32,$hi0 + extrd,u $ab0,63,32,$ab0 + ldd -8($xfer),$nm0 + fstds ${fnm0},-8($xfer) + ldo 8($idx),$idx ; j++++ + addl $ab0,$nm0,$nm0 ; low part is discarded + extrd,u $nm0,31,32,$hi1 + +L\$1st + xmpyu ${fai}R,${fbi},${fab1} ; ap[j+1]*bp[0] + xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j+1]*m + ldd 0($xfer),$ab1 + fstds ${fab1},0($xfer) + addl $hi0,$ab1,$ab1 + extrd,u $ab1,31,32,$hi0 + ldd 8($xfer),$nm1 + fstds ${fnm1},8($xfer) + extrd,u $ab1,63,32,$ab1 + addl $hi1,$nm1,$nm1 + flddx $idx($ap),${fai} ; ap[j,j+1] + flddx $idx($np),${fni} ; np[j,j+1] + addl $ab1,$nm1,$nm1 + extrd,u $nm1,31,32,$hi1 + + xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[0] + xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m + ldd -16($xfer),$ab0 + fstds ${fab0},-16($xfer) + addl $hi0,$ab0,$ab0 + extrd,u $ab0,31,32,$hi0 + ldd -8($xfer),$nm0 + fstds ${fnm0},-8($xfer) + extrd,u $ab0,63,32,$ab0 + addl $hi1,$nm0,$nm0 + stw $nm1,-4($tp) ; tp[j-1] + addl $ab0,$nm0,$nm0 + stw,ma $nm0,8($tp) ; tp[j-1] + addib,<> 8,$idx,L\$1st ; j++++ + extrd,u $nm0,31,32,$hi1 + + xmpyu ${fai}R,${fbi},${fab1} ; ap[j]*bp[0] + xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j]*m + ldd 0($xfer),$ab1 + fstds ${fab1},0($xfer) + addl $hi0,$ab1,$ab1 + extrd,u $ab1,31,32,$hi0 + ldd 8($xfer),$nm1 + fstds ${fnm1},8($xfer) + extrd,u $ab1,63,32,$ab1 + addl $hi1,$nm1,$nm1 + ldd -16($xfer),$ab0 + addl $ab1,$nm1,$nm1 + ldd -8($xfer),$nm0 + extrd,u $nm1,31,32,$hi1 + + addl $hi0,$ab0,$ab0 + extrd,u $ab0,31,32,$hi0 + stw $nm1,-4($tp) ; tp[j-1] + extrd,u $ab0,63,32,$ab0 + addl $hi1,$nm0,$nm0 + ldd 0($xfer),$ab1 + addl $ab0,$nm0,$nm0 + ldd,mb 8($xfer),$nm1 + extrd,u $nm0,31,32,$hi1 + stw,ma $nm0,8($tp) ; tp[j-1] + + ldo -1($num),$num ; i-- + subi 0,$arrsz,$idx ; j=0 +___ +$code.=<<___ if ($BN_SZ==4); + fldws,ma 4($bp),${fbi} ; bp[1] +___ +$code.=<<___ if ($BN_SZ==8); + fldws 0($bp),${fbi} ; bp[1] in flipped word order +___ +$code.=<<___; + flddx $idx($ap),${fai} ; ap[0,1] + flddx $idx($np),${fni} ; np[0,1] + fldws 8($xfer),${fti}R ; tp[0] + addl $hi0,$ab1,$ab1 + extrd,u $ab1,31,32,$hi0 + extrd,u $ab1,63,32,$ab1 + ldo 8($idx),$idx ; j++++ + xmpyu ${fai}L,${fbi},${fab0} ; ap[0]*bp[1] + xmpyu ${fai}R,${fbi},${fab1} ; ap[1]*bp[1] + addl $hi1,$nm1,$nm1 + addl $ab1,$nm1,$nm1 + extrd,u $nm1,31,32,$hi1 + fstws,mb ${fab0}L,-8($xfer) ; save high part + stw $nm1,-4($tp) ; tp[j-1] + + fcpy,sgl %fr0,${fti}L ; zero high part + fcpy,sgl %fr0,${fab0}L + addl $hi1,$hi0,$hi0 + extrd,u $hi0,31,32,$hi1 + fcnvxf,dbl,dbl ${fti},${fti} ; 32-bit unsigned int -> double + fcnvxf,dbl,dbl ${fab0},${fab0} + stw $hi0,0($tp) + stw $hi1,4($tp) + + fadd,dbl ${fti},${fab0},${fab0} ; add tp[0] + fcnvfx,dbl,dbl ${fab0},${fab0} ; double -> 33-bit unsigned int + xmpyu ${fn0},${fab0}R,${fm0} + ldo `$LOCALS+32+4`($fp),$tp +L\$outer + xmpyu ${fni}L,${fm0}R,${fnm0} ; np[0]*m + xmpyu ${fni}R,${fm0}R,${fnm1} ; np[1]*m + fstds ${fab0},-16($xfer) ; 33-bit value + fstds ${fnm0},-8($xfer) + flddx $idx($ap),${fai} ; ap[2] + flddx $idx($np),${fni} ; np[2] + ldo 8($idx),$idx ; j++++ + ldd -16($xfer),$ab0 ; 33-bit value + ldd -8($xfer),$nm0 + ldw 0($xfer),$hi0 ; high part + + xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[i] + xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m + extrd,u $ab0,31,32,$ti0 ; carry bit + extrd,u $ab0,63,32,$ab0 + fstds ${fab1},0($xfer) + addl $ti0,$hi0,$hi0 ; account carry bit + fstds ${fnm1},8($xfer) + addl $ab0,$nm0,$nm0 ; low part is discarded + ldw 0($tp),$ti1 ; tp[1] + extrd,u $nm0,31,32,$hi1 + fstds ${fab0},-16($xfer) + fstds ${fnm0},-8($xfer) + +L\$inner + xmpyu ${fai}R,${fbi},${fab1} ; ap[j+1]*bp[i] + xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j+1]*m + ldd 0($xfer),$ab1 + fstds ${fab1},0($xfer) + addl $hi0,$ti1,$ti1 + addl $ti1,$ab1,$ab1 + ldd 8($xfer),$nm1 + fstds ${fnm1},8($xfer) + extrd,u $ab1,31,32,$hi0 + extrd,u $ab1,63,32,$ab1 + flddx $idx($ap),${fai} ; ap[j,j+1] + flddx $idx($np),${fni} ; np[j,j+1] + addl $hi1,$nm1,$nm1 + addl $ab1,$nm1,$nm1 + ldw 4($tp),$ti0 ; tp[j] + stw $nm1,-4($tp) ; tp[j-1] + + xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[i] + xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m + ldd -16($xfer),$ab0 + fstds ${fab0},-16($xfer) + addl $hi0,$ti0,$ti0 + addl $ti0,$ab0,$ab0 + ldd -8($xfer),$nm0 + fstds ${fnm0},-8($xfer) + extrd,u $ab0,31,32,$hi0 + extrd,u $nm1,31,32,$hi1 + ldw 8($tp),$ti1 ; tp[j] + extrd,u $ab0,63,32,$ab0 + addl $hi1,$nm0,$nm0 + addl $ab0,$nm0,$nm0 + stw,ma $nm0,8($tp) ; tp[j-1] + addib,<> 8,$idx,L\$inner ; j++++ + extrd,u $nm0,31,32,$hi1 + + xmpyu ${fai}R,${fbi},${fab1} ; ap[j]*bp[i] + xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j]*m + ldd 0($xfer),$ab1 + fstds ${fab1},0($xfer) + addl $hi0,$ti1,$ti1 + addl $ti1,$ab1,$ab1 + ldd 8($xfer),$nm1 + fstds ${fnm1},8($xfer) + extrd,u $ab1,31,32,$hi0 + extrd,u $ab1,63,32,$ab1 + ldw 4($tp),$ti0 ; tp[j] + addl $hi1,$nm1,$nm1 + addl $ab1,$nm1,$nm1 + ldd -16($xfer),$ab0 + ldd -8($xfer),$nm0 + extrd,u $nm1,31,32,$hi1 + + addl $hi0,$ab0,$ab0 + addl $ti0,$ab0,$ab0 + stw $nm1,-4($tp) ; tp[j-1] + extrd,u $ab0,31,32,$hi0 + ldw 8($tp),$ti1 ; tp[j] + extrd,u $ab0,63,32,$ab0 + addl $hi1,$nm0,$nm0 + ldd 0($xfer),$ab1 + addl $ab0,$nm0,$nm0 + ldd,mb 8($xfer),$nm1 + extrd,u $nm0,31,32,$hi1 + stw,ma $nm0,8($tp) ; tp[j-1] + + addib,= -1,$num,L\$outerdone ; i-- + subi 0,$arrsz,$idx ; j=0 +___ +$code.=<<___ if ($BN_SZ==4); + fldws,ma 4($bp),${fbi} ; bp[i] +___ +$code.=<<___ if ($BN_SZ==8); + ldi 12,$ti0 ; bp[i] in flipped word order + addl,ev %r0,$num,$num + ldi -4,$ti0 + addl $ti0,$bp,$bp + fldws 0($bp),${fbi} +___ +$code.=<<___; + flddx $idx($ap),${fai} ; ap[0] + addl $hi0,$ab1,$ab1 + flddx $idx($np),${fni} ; np[0] + fldws 8($xfer),${fti}R ; tp[0] + addl $ti1,$ab1,$ab1 + extrd,u $ab1,31,32,$hi0 + extrd,u $ab1,63,32,$ab1 + + ldo 8($idx),$idx ; j++++ + xmpyu ${fai}L,${fbi},${fab0} ; ap[0]*bp[i] + xmpyu ${fai}R,${fbi},${fab1} ; ap[1]*bp[i] + ldw 4($tp),$ti0 ; tp[j] + + addl $hi1,$nm1,$nm1 + fstws,mb ${fab0}L,-8($xfer) ; save high part + addl $ab1,$nm1,$nm1 + extrd,u $nm1,31,32,$hi1 + fcpy,sgl %fr0,${fti}L ; zero high part + fcpy,sgl %fr0,${fab0}L + stw $nm1,-4($tp) ; tp[j-1] + + fcnvxf,dbl,dbl ${fti},${fti} ; 32-bit unsigned int -> double + fcnvxf,dbl,dbl ${fab0},${fab0} + addl $hi1,$hi0,$hi0 + fadd,dbl ${fti},${fab0},${fab0} ; add tp[0] + addl $ti0,$hi0,$hi0 + extrd,u $hi0,31,32,$hi1 + fcnvfx,dbl,dbl ${fab0},${fab0} ; double -> 33-bit unsigned int + stw $hi0,0($tp) + stw $hi1,4($tp) + xmpyu ${fn0},${fab0}R,${fm0} + + b L\$outer + ldo `$LOCALS+32+4`($fp),$tp + +L\$outerdone + addl $hi0,$ab1,$ab1 + addl $ti1,$ab1,$ab1 + extrd,u $ab1,31,32,$hi0 + extrd,u $ab1,63,32,$ab1 + + ldw 4($tp),$ti0 ; tp[j] + + addl $hi1,$nm1,$nm1 + addl $ab1,$nm1,$nm1 + extrd,u $nm1,31,32,$hi1 + stw $nm1,-4($tp) ; tp[j-1] + + addl $hi1,$hi0,$hi0 + addl $ti0,$hi0,$hi0 + extrd,u $hi0,31,32,$hi1 + stw $hi0,0($tp) + stw $hi1,4($tp) + + ldo `$LOCALS+32`($fp),$tp + sub %r0,%r0,%r0 ; clear borrow +___ +$code.=<<___ if ($BN_SZ==4); + ldws,ma 4($tp),$ti0 + extru,= $rp,31,3,%r0 ; is rp 64-bit aligned? + b L\$sub_pa11 + addl $tp,$arrsz,$tp +L\$sub + ldwx $idx($np),$hi0 + subb $ti0,$hi0,$hi1 + ldwx $idx($tp),$ti0 + addib,<> 4,$idx,L\$sub + stws,ma $hi1,4($rp) + + subb $ti0,%r0,$hi1 + ldo -4($tp),$tp +___ +$code.=<<___ if ($BN_SZ==8); + ldd,ma 8($tp),$ti0 +L\$sub + ldd $idx($np),$hi0 + shrpd $ti0,$ti0,32,$ti0 ; flip word order + std $ti0,-8($tp) ; save flipped value + sub,db $ti0,$hi0,$hi1 + ldd,ma 8($tp),$ti0 + addib,<> 8,$idx,L\$sub + std,ma $hi1,8($rp) + + extrd,u $ti0,31,32,$ti0 ; carry in flipped word order + sub,db $ti0,%r0,$hi1 + ldo -8($tp),$tp +___ +$code.=<<___; + and $tp,$hi1,$ap + andcm $rp,$hi1,$bp + or $ap,$bp,$np + + sub $rp,$arrsz,$rp ; rewind rp + subi 0,$arrsz,$idx + ldo `$LOCALS+32`($fp),$tp +L\$copy + ldd $idx($np),$hi0 + std,ma %r0,8($tp) + addib,<> 8,$idx,.-8 ; L\$copy + std,ma $hi0,8($rp) +___ + +if ($BN_SZ==4) { # PA-RISC 1.1 code-path +$ablo=$ab0; +$abhi=$ab1; +$nmlo0=$nm0; +$nmhi0=$nm1; +$nmlo1="%r9"; +$nmhi1="%r8"; + +$code.=<<___; + b L\$done + nop + + .ALIGN 8 +L\$parisc11 + xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[0] + xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m + ldw -12($xfer),$ablo + ldw -16($xfer),$hi0 + ldw -4($xfer),$nmlo0 + ldw -8($xfer),$nmhi0 + fstds ${fab0},-16($xfer) + fstds ${fnm0},-8($xfer) + + ldo 8($idx),$idx ; j++++ + add $ablo,$nmlo0,$nmlo0 ; discarded + addc %r0,$nmhi0,$hi1 + ldw 4($xfer),$ablo + ldw 0($xfer),$abhi + nop + +L\$1st_pa11 + xmpyu ${fai}R,${fbi},${fab1} ; ap[j+1]*bp[0] + flddx $idx($ap),${fai} ; ap[j,j+1] + xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j+1]*m + flddx $idx($np),${fni} ; np[j,j+1] + add $hi0,$ablo,$ablo + ldw 12($xfer),$nmlo1 + addc %r0,$abhi,$hi0 + ldw 8($xfer),$nmhi1 + add $ablo,$nmlo1,$nmlo1 + fstds ${fab1},0($xfer) + addc %r0,$nmhi1,$nmhi1 + fstds ${fnm1},8($xfer) + add $hi1,$nmlo1,$nmlo1 + ldw -12($xfer),$ablo + addc %r0,$nmhi1,$hi1 + ldw -16($xfer),$abhi + + xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[0] + ldw -4($xfer),$nmlo0 + xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m + ldw -8($xfer),$nmhi0 + add $hi0,$ablo,$ablo + stw $nmlo1,-4($tp) ; tp[j-1] + addc %r0,$abhi,$hi0 + fstds ${fab0},-16($xfer) + add $ablo,$nmlo0,$nmlo0 + fstds ${fnm0},-8($xfer) + addc %r0,$nmhi0,$nmhi0 + ldw 0($xfer),$abhi + add $hi1,$nmlo0,$nmlo0 + ldw 4($xfer),$ablo + stws,ma $nmlo0,8($tp) ; tp[j-1] + addib,<> 8,$idx,L\$1st_pa11 ; j++++ + addc %r0,$nmhi0,$hi1 + + ldw 8($xfer),$nmhi1 + ldw 12($xfer),$nmlo1 + xmpyu ${fai}R,${fbi},${fab1} ; ap[j]*bp[0] + xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j]*m + add $hi0,$ablo,$ablo + fstds ${fab1},0($xfer) + addc %r0,$abhi,$hi0 + fstds ${fnm1},8($xfer) + add $ablo,$nmlo1,$nmlo1 + ldw -16($xfer),$abhi + addc %r0,$nmhi1,$nmhi1 + ldw -12($xfer),$ablo + add $hi1,$nmlo1,$nmlo1 + ldw -8($xfer),$nmhi0 + addc %r0,$nmhi1,$hi1 + ldw -4($xfer),$nmlo0 + + add $hi0,$ablo,$ablo + stw $nmlo1,-4($tp) ; tp[j-1] + addc %r0,$abhi,$hi0 + ldw 0($xfer),$abhi + add $ablo,$nmlo0,$nmlo0 + ldw 4($xfer),$ablo + addc %r0,$nmhi0,$nmhi0 + ldws,mb 8($xfer),$nmhi1 + add $hi1,$nmlo0,$nmlo0 + ldw 4($xfer),$nmlo1 + addc %r0,$nmhi0,$hi1 + stws,ma $nmlo0,8($tp) ; tp[j-1] + + ldo -1($num),$num ; i-- + subi 0,$arrsz,$idx ; j=0 + + fldws,ma 4($bp),${fbi} ; bp[1] + flddx $idx($ap),${fai} ; ap[0,1] + flddx $idx($np),${fni} ; np[0,1] + fldws 8($xfer),${fti}R ; tp[0] + add $hi0,$ablo,$ablo + addc %r0,$abhi,$hi0 + ldo 8($idx),$idx ; j++++ + xmpyu ${fai}L,${fbi},${fab0} ; ap[0]*bp[1] + xmpyu ${fai}R,${fbi},${fab1} ; ap[1]*bp[1] + add $hi1,$nmlo1,$nmlo1 + addc %r0,$nmhi1,$nmhi1 + add $ablo,$nmlo1,$nmlo1 + addc %r0,$nmhi1,$hi1 + fstws,mb ${fab0}L,-8($xfer) ; save high part + stw $nmlo1,-4($tp) ; tp[j-1] + + fcpy,sgl %fr0,${fti}L ; zero high part + fcpy,sgl %fr0,${fab0}L + add $hi1,$hi0,$hi0 + addc %r0,%r0,$hi1 + fcnvxf,dbl,dbl ${fti},${fti} ; 32-bit unsigned int -> double + fcnvxf,dbl,dbl ${fab0},${fab0} + stw $hi0,0($tp) + stw $hi1,4($tp) + + fadd,dbl ${fti},${fab0},${fab0} ; add tp[0] + fcnvfx,dbl,dbl ${fab0},${fab0} ; double -> 33-bit unsigned int + xmpyu ${fn0},${fab0}R,${fm0} + ldo `$LOCALS+32+4`($fp),$tp +L\$outer_pa11 + xmpyu ${fni}L,${fm0}R,${fnm0} ; np[0]*m + xmpyu ${fni}R,${fm0}R,${fnm1} ; np[1]*m + fstds ${fab0},-16($xfer) ; 33-bit value + fstds ${fnm0},-8($xfer) + flddx $idx($ap),${fai} ; ap[2,3] + flddx $idx($np),${fni} ; np[2,3] + ldw -16($xfer),$abhi ; carry bit actually + ldo 8($idx),$idx ; j++++ + ldw -12($xfer),$ablo + ldw -8($xfer),$nmhi0 + ldw -4($xfer),$nmlo0 + ldw 0($xfer),$hi0 ; high part + + xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[i] + xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m + fstds ${fab1},0($xfer) + addl $abhi,$hi0,$hi0 ; account carry bit + fstds ${fnm1},8($xfer) + add $ablo,$nmlo0,$nmlo0 ; discarded + ldw 0($tp),$ti1 ; tp[1] + addc %r0,$nmhi0,$hi1 + fstds ${fab0},-16($xfer) + fstds ${fnm0},-8($xfer) + ldw 4($xfer),$ablo + ldw 0($xfer),$abhi + +L\$inner_pa11 + xmpyu ${fai}R,${fbi},${fab1} ; ap[j+1]*bp[i] + flddx $idx($ap),${fai} ; ap[j,j+1] + xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j+1]*m + flddx $idx($np),${fni} ; np[j,j+1] + add $hi0,$ablo,$ablo + ldw 4($tp),$ti0 ; tp[j] + addc %r0,$abhi,$abhi + ldw 12($xfer),$nmlo1 + add $ti1,$ablo,$ablo + ldw 8($xfer),$nmhi1 + addc %r0,$abhi,$hi0 + fstds ${fab1},0($xfer) + add $ablo,$nmlo1,$nmlo1 + fstds ${fnm1},8($xfer) + addc %r0,$nmhi1,$nmhi1 + ldw -12($xfer),$ablo + add $hi1,$nmlo1,$nmlo1 + ldw -16($xfer),$abhi + addc %r0,$nmhi1,$hi1 + + xmpyu ${fai}L,${fbi},${fab0} ; ap[j]*bp[i] + ldw 8($tp),$ti1 ; tp[j] + xmpyu ${fni}L,${fm0}R,${fnm0} ; np[j]*m + ldw -4($xfer),$nmlo0 + add $hi0,$ablo,$ablo + ldw -8($xfer),$nmhi0 + addc %r0,$abhi,$abhi + stw $nmlo1,-4($tp) ; tp[j-1] + add $ti0,$ablo,$ablo + fstds ${fab0},-16($xfer) + addc %r0,$abhi,$hi0 + fstds ${fnm0},-8($xfer) + add $ablo,$nmlo0,$nmlo0 + ldw 4($xfer),$ablo + addc %r0,$nmhi0,$nmhi0 + ldw 0($xfer),$abhi + add $hi1,$nmlo0,$nmlo0 + stws,ma $nmlo0,8($tp) ; tp[j-1] + addib,<> 8,$idx,L\$inner_pa11 ; j++++ + addc %r0,$nmhi0,$hi1 + + xmpyu ${fai}R,${fbi},${fab1} ; ap[j]*bp[i] + ldw 12($xfer),$nmlo1 + xmpyu ${fni}R,${fm0}R,${fnm1} ; np[j]*m + ldw 8($xfer),$nmhi1 + add $hi0,$ablo,$ablo + ldw 4($tp),$ti0 ; tp[j] + addc %r0,$abhi,$abhi + fstds ${fab1},0($xfer) + add $ti1,$ablo,$ablo + fstds ${fnm1},8($xfer) + addc %r0,$abhi,$hi0 + ldw -16($xfer),$abhi + add $ablo,$nmlo1,$nmlo1 + ldw -12($xfer),$ablo + addc %r0,$nmhi1,$nmhi1 + ldw -8($xfer),$nmhi0 + add $hi1,$nmlo1,$nmlo1 + ldw -4($xfer),$nmlo0 + addc %r0,$nmhi1,$hi1 + + add $hi0,$ablo,$ablo + stw $nmlo1,-4($tp) ; tp[j-1] + addc %r0,$abhi,$abhi + add $ti0,$ablo,$ablo + ldw 8($tp),$ti1 ; tp[j] + addc %r0,$abhi,$hi0 + ldw 0($xfer),$abhi + add $ablo,$nmlo0,$nmlo0 + ldw 4($xfer),$ablo + addc %r0,$nmhi0,$nmhi0 + ldws,mb 8($xfer),$nmhi1 + add $hi1,$nmlo0,$nmlo0 + ldw 4($xfer),$nmlo1 + addc %r0,$nmhi0,$hi1 + stws,ma $nmlo0,8($tp) ; tp[j-1] + + addib,= -1,$num,L\$outerdone_pa11; i-- + subi 0,$arrsz,$idx ; j=0 + + fldws,ma 4($bp),${fbi} ; bp[i] + flddx $idx($ap),${fai} ; ap[0] + add $hi0,$ablo,$ablo + addc %r0,$abhi,$abhi + flddx $idx($np),${fni} ; np[0] + fldws 8($xfer),${fti}R ; tp[0] + add $ti1,$ablo,$ablo + addc %r0,$abhi,$hi0 + + ldo 8($idx),$idx ; j++++ + xmpyu ${fai}L,${fbi},${fab0} ; ap[0]*bp[i] + xmpyu ${fai}R,${fbi},${fab1} ; ap[1]*bp[i] + ldw 4($tp),$ti0 ; tp[j] + + add $hi1,$nmlo1,$nmlo1 + addc %r0,$nmhi1,$nmhi1 + fstws,mb ${fab0}L,-8($xfer) ; save high part + add $ablo,$nmlo1,$nmlo1 + addc %r0,$nmhi1,$hi1 + fcpy,sgl %fr0,${fti}L ; zero high part + fcpy,sgl %fr0,${fab0}L + stw $nmlo1,-4($tp) ; tp[j-1] + + fcnvxf,dbl,dbl ${fti},${fti} ; 32-bit unsigned int -> double + fcnvxf,dbl,dbl ${fab0},${fab0} + add $hi1,$hi0,$hi0 + addc %r0,%r0,$hi1 + fadd,dbl ${fti},${fab0},${fab0} ; add tp[0] + add $ti0,$hi0,$hi0 + addc %r0,$hi1,$hi1 + fcnvfx,dbl,dbl ${fab0},${fab0} ; double -> 33-bit unsigned int + stw $hi0,0($tp) + stw $hi1,4($tp) + xmpyu ${fn0},${fab0}R,${fm0} + + b L\$outer_pa11 + ldo `$LOCALS+32+4`($fp),$tp + +L\$outerdone_pa11 + add $hi0,$ablo,$ablo + addc %r0,$abhi,$abhi + add $ti1,$ablo,$ablo + addc %r0,$abhi,$hi0 + + ldw 4($tp),$ti0 ; tp[j] + + add $hi1,$nmlo1,$nmlo1 + addc %r0,$nmhi1,$nmhi1 + add $ablo,$nmlo1,$nmlo1 + addc %r0,$nmhi1,$hi1 + stw $nmlo1,-4($tp) ; tp[j-1] + + add $hi1,$hi0,$hi0 + addc %r0,%r0,$hi1 + add $ti0,$hi0,$hi0 + addc %r0,$hi1,$hi1 + stw $hi0,0($tp) + stw $hi1,4($tp) + + ldo `$LOCALS+32+4`($fp),$tp + sub %r0,%r0,%r0 ; clear borrow + ldw -4($tp),$ti0 + addl $tp,$arrsz,$tp +L\$sub_pa11 + ldwx $idx($np),$hi0 + subb $ti0,$hi0,$hi1 + ldwx $idx($tp),$ti0 + addib,<> 4,$idx,L\$sub_pa11 + stws,ma $hi1,4($rp) + + subb $ti0,%r0,$hi1 + ldo -4($tp),$tp + and $tp,$hi1,$ap + andcm $rp,$hi1,$bp + or $ap,$bp,$np + + sub $rp,$arrsz,$rp ; rewind rp + subi 0,$arrsz,$idx + ldo `$LOCALS+32`($fp),$tp +L\$copy_pa11 + ldwx $idx($np),$hi0 + stws,ma %r0,4($tp) + addib,<> 4,$idx,L\$copy_pa11 + stws,ma $hi0,4($rp) + + nop ; alignment +L\$done +___ +} + +$code.=<<___; + ldi 1,%r28 ; signal "handled" + ldo $FRAME($fp),%sp ; destroy tp[num+1] + + $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue + $POP `-$FRAME+1*$SIZE_T`(%sp),%r4 + $POP `-$FRAME+2*$SIZE_T`(%sp),%r5 + $POP `-$FRAME+3*$SIZE_T`(%sp),%r6 + $POP `-$FRAME+4*$SIZE_T`(%sp),%r7 + $POP `-$FRAME+5*$SIZE_T`(%sp),%r8 + $POP `-$FRAME+6*$SIZE_T`(%sp),%r9 + $POP `-$FRAME+7*$SIZE_T`(%sp),%r10 +L\$abort + bv (%r2) + .EXIT + $POPMB -$FRAME(%sp),%r3 + .PROCEND + .STRINGZ "Montgomery Multiplication for PA-RISC, CRYPTOGAMS by " +___ + +# Explicitly encode PA-RISC 2.0 instructions used in this module, so +# that it can be compiled with .LEVEL 1.0. It should be noted that I +# wouldn't have to do this, if GNU assembler understood .ALLOW 2.0 +# directive... + +my $ldd = sub { + my ($mod,$args) = @_; + my $orig = "ldd$mod\t$args"; + + if ($args =~ /%r([0-9]+)\(%r([0-9]+)\),%r([0-9]+)/) # format 4 + { my $opcode=(0x03<<26)|($2<<21)|($1<<16)|(3<<6)|$3; + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + elsif ($args =~ /(\-?[0-9]+)\(%r([0-9]+)\),%r([0-9]+)/) # format 5 + { my $opcode=(0x03<<26)|($2<<21)|(1<<12)|(3<<6)|$3; + $opcode|=(($1&0xF)<<17)|(($1&0x10)<<12); # encode offset + $opcode|=(1<<5) if ($mod =~ /^,m/); + $opcode|=(1<<13) if ($mod =~ /^,mb/); + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + else { "\t".$orig; } +}; + +my $std = sub { + my ($mod,$args) = @_; + my $orig = "std$mod\t$args"; + + if ($args =~ /%r([0-9]+),(\-?[0-9]+)\(%r([0-9]+)\)/) # format 6 + { my $opcode=(0x03<<26)|($3<<21)|($1<<16)|(1<<12)|(0xB<<6); + $opcode|=(($2&0xF)<<1)|(($2&0x10)>>4); # encode offset + $opcode|=(1<<5) if ($mod =~ /^,m/); + $opcode|=(1<<13) if ($mod =~ /^,mb/); + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + else { "\t".$orig; } +}; + +my $extrd = sub { + my ($mod,$args) = @_; + my $orig = "extrd$mod\t$args"; + + # I only have ",u" completer, it's implicitly encoded... + if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/) # format 15 + { my $opcode=(0x36<<26)|($1<<21)|($4<<16); + my $len=32-$3; + $opcode |= (($2&0x20)<<6)|(($2&0x1f)<<5); # encode pos + $opcode |= (($len&0x20)<<7)|($len&0x1f); # encode len + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + elsif ($args =~ /%r([0-9]+),%sar,([0-9]+),%r([0-9]+)/) # format 12 + { my $opcode=(0x34<<26)|($1<<21)|($3<<16)|(2<<11)|(1<<9); + my $len=32-$2; + $opcode |= (($len&0x20)<<3)|($len&0x1f); # encode len + $opcode |= (1<<13) if ($mod =~ /,\**=/); + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + else { "\t".$orig; } +}; + +my $shrpd = sub { + my ($mod,$args) = @_; + my $orig = "shrpd$mod\t$args"; + + if ($args =~ /%r([0-9]+),%r([0-9]+),([0-9]+),%r([0-9]+)/) # format 14 + { my $opcode=(0x34<<26)|($2<<21)|($1<<16)|(1<<10)|$4; + my $cpos=63-$3; + $opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5); # encode sa + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + else { "\t".$orig; } +}; + +my $sub = sub { + my ($mod,$args) = @_; + my $orig = "sub$mod\t$args"; + + if ($mod eq ",db" && $args =~ /%r([0-9]+),%r([0-9]+),%r([0-9]+)/) { + my $opcode=(0x02<<26)|($2<<21)|($1<<16)|$3; + $opcode|=(1<<10); # e1 + $opcode|=(1<<8); # e2 + $opcode|=(1<<5); # d + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig + } + else { "\t".$orig; } +}; + +sub assemble { + my ($mnemonic,$mod,$args)=@_; + my $opcode = eval("\$$mnemonic"); + + ref($opcode) eq 'CODE' ? &$opcode($mod,$args) : "\t$mnemonic$mod\t$args"; +} + +foreach (split("\n",$code)) { + s/\`([^\`]*)\`/eval $1/ge; + # flip word order in 64-bit mode... + s/(xmpyu\s+)($fai|$fni)([LR])/$1.$2.($3 eq "L"?"R":"L")/e if ($BN_SZ==8); + # assemble 2.0 instructions in 32-bit mode... + s/^\s+([a-z]+)([\S]*)\s+([\S]*)/&assemble($1,$2,$3)/e if ($BN_SZ==4); + + s/\bbv\b/bve/gm if ($SIZE_T==8); + + print $_,"\n"; +} +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/ppc-mont.pl b/libs/openssl/crypto/bn/asm/ppc-mont.pl new file mode 100644 index 00000000..f9b6992c --- /dev/null +++ b/libs/openssl/crypto/bn/asm/ppc-mont.pl @@ -0,0 +1,334 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# April 2006 + +# "Teaser" Montgomery multiplication module for PowerPC. It's possible +# to gain a bit more by modulo-scheduling outer loop, then dedicated +# squaring procedure should give further 20% and code can be adapted +# for 32-bit application running on 64-bit CPU. As for the latter. +# It won't be able to achieve "native" 64-bit performance, because in +# 32-bit application context every addc instruction will have to be +# expanded as addc, twice right shift by 32 and finally adde, etc. +# So far RSA *sign* performance improvement over pre-bn_mul_mont asm +# for 64-bit application running on PPC970/G5 is: +# +# 512-bit +65% +# 1024-bit +35% +# 2048-bit +18% +# 4096-bit +4% + +$flavour = shift; + +if ($flavour =~ /32/) { + $BITS= 32; + $BNSZ= $BITS/8; + $SIZE_T=4; + $RZONE= 224; + + $LD= "lwz"; # load + $LDU= "lwzu"; # load and update + $LDX= "lwzx"; # load indexed + $ST= "stw"; # store + $STU= "stwu"; # store and update + $STX= "stwx"; # store indexed + $STUX= "stwux"; # store indexed and update + $UMULL= "mullw"; # unsigned multiply low + $UMULH= "mulhwu"; # unsigned multiply high + $UCMP= "cmplw"; # unsigned compare + $SHRI= "srwi"; # unsigned shift right by immediate + $PUSH= $ST; + $POP= $LD; +} elsif ($flavour =~ /64/) { + $BITS= 64; + $BNSZ= $BITS/8; + $SIZE_T=8; + $RZONE= 288; + + # same as above, but 64-bit mnemonics... + $LD= "ld"; # load + $LDU= "ldu"; # load and update + $LDX= "ldx"; # load indexed + $ST= "std"; # store + $STU= "stdu"; # store and update + $STX= "stdx"; # store indexed + $STUX= "stdux"; # store indexed and update + $UMULL= "mulld"; # unsigned multiply low + $UMULH= "mulhdu"; # unsigned multiply high + $UCMP= "cmpld"; # unsigned compare + $SHRI= "srdi"; # unsigned shift right by immediate + $PUSH= $ST; + $POP= $LD; +} else { die "nonsense $flavour"; } + +$FRAME=8*$SIZE_T+$RZONE; +$LOCALS=8*$SIZE_T; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or +die "can't locate ppc-xlate.pl"; + +open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; + +$sp="r1"; +$toc="r2"; +$rp="r3"; $ovf="r3"; +$ap="r4"; +$bp="r5"; +$np="r6"; +$n0="r7"; +$num="r8"; +$rp="r9"; # $rp is reassigned +$aj="r10"; +$nj="r11"; +$tj="r12"; +# non-volatile registers +$i="r20"; +$j="r21"; +$tp="r22"; +$m0="r23"; +$m1="r24"; +$lo0="r25"; +$hi0="r26"; +$lo1="r27"; +$hi1="r28"; +$alo="r29"; +$ahi="r30"; +$nlo="r31"; +# +$nhi="r0"; + +$code=<<___; +.machine "any" +.text + +.globl .bn_mul_mont_int +.align 4 +.bn_mul_mont_int: + cmpwi $num,4 + mr $rp,r3 ; $rp is reassigned + li r3,0 + bltlr +___ +$code.=<<___ if ($BNSZ==4); + cmpwi $num,32 ; longer key performance is not better + bgelr +___ +$code.=<<___; + slwi $num,$num,`log($BNSZ)/log(2)` + li $tj,-4096 + addi $ovf,$num,$FRAME + subf $ovf,$ovf,$sp ; $sp-$ovf + and $ovf,$ovf,$tj ; minimize TLB usage + subf $ovf,$sp,$ovf ; $ovf-$sp + mr $tj,$sp + srwi $num,$num,`log($BNSZ)/log(2)` + $STUX $sp,$sp,$ovf + + $PUSH r20,`-12*$SIZE_T`($tj) + $PUSH r21,`-11*$SIZE_T`($tj) + $PUSH r22,`-10*$SIZE_T`($tj) + $PUSH r23,`-9*$SIZE_T`($tj) + $PUSH r24,`-8*$SIZE_T`($tj) + $PUSH r25,`-7*$SIZE_T`($tj) + $PUSH r26,`-6*$SIZE_T`($tj) + $PUSH r27,`-5*$SIZE_T`($tj) + $PUSH r28,`-4*$SIZE_T`($tj) + $PUSH r29,`-3*$SIZE_T`($tj) + $PUSH r30,`-2*$SIZE_T`($tj) + $PUSH r31,`-1*$SIZE_T`($tj) + + $LD $n0,0($n0) ; pull n0[0] value + addi $num,$num,-2 ; adjust $num for counter register + + $LD $m0,0($bp) ; m0=bp[0] + $LD $aj,0($ap) ; ap[0] + addi $tp,$sp,$LOCALS + $UMULL $lo0,$aj,$m0 ; ap[0]*bp[0] + $UMULH $hi0,$aj,$m0 + + $LD $aj,$BNSZ($ap) ; ap[1] + $LD $nj,0($np) ; np[0] + + $UMULL $m1,$lo0,$n0 ; "tp[0]"*n0 + + $UMULL $alo,$aj,$m0 ; ap[1]*bp[0] + $UMULH $ahi,$aj,$m0 + + $UMULL $lo1,$nj,$m1 ; np[0]*m1 + $UMULH $hi1,$nj,$m1 + $LD $nj,$BNSZ($np) ; np[1] + addc $lo1,$lo1,$lo0 + addze $hi1,$hi1 + + $UMULL $nlo,$nj,$m1 ; np[1]*m1 + $UMULH $nhi,$nj,$m1 + + mtctr $num + li $j,`2*$BNSZ` +.align 4 +L1st: + $LDX $aj,$ap,$j ; ap[j] + addc $lo0,$alo,$hi0 + $LDX $nj,$np,$j ; np[j] + addze $hi0,$ahi + $UMULL $alo,$aj,$m0 ; ap[j]*bp[0] + addc $lo1,$nlo,$hi1 + $UMULH $ahi,$aj,$m0 + addze $hi1,$nhi + $UMULL $nlo,$nj,$m1 ; np[j]*m1 + addc $lo1,$lo1,$lo0 ; np[j]*m1+ap[j]*bp[0] + $UMULH $nhi,$nj,$m1 + addze $hi1,$hi1 + $ST $lo1,0($tp) ; tp[j-1] + + addi $j,$j,$BNSZ ; j++ + addi $tp,$tp,$BNSZ ; tp++ + bdnz- L1st +;L1st + addc $lo0,$alo,$hi0 + addze $hi0,$ahi + + addc $lo1,$nlo,$hi1 + addze $hi1,$nhi + addc $lo1,$lo1,$lo0 ; np[j]*m1+ap[j]*bp[0] + addze $hi1,$hi1 + $ST $lo1,0($tp) ; tp[j-1] + + li $ovf,0 + addc $hi1,$hi1,$hi0 + addze $ovf,$ovf ; upmost overflow bit + $ST $hi1,$BNSZ($tp) + + li $i,$BNSZ +.align 4 +Louter: + $LDX $m0,$bp,$i ; m0=bp[i] + $LD $aj,0($ap) ; ap[0] + addi $tp,$sp,$LOCALS + $LD $tj,$LOCALS($sp); tp[0] + $UMULL $lo0,$aj,$m0 ; ap[0]*bp[i] + $UMULH $hi0,$aj,$m0 + $LD $aj,$BNSZ($ap) ; ap[1] + $LD $nj,0($np) ; np[0] + addc $lo0,$lo0,$tj ; ap[0]*bp[i]+tp[0] + $UMULL $alo,$aj,$m0 ; ap[j]*bp[i] + addze $hi0,$hi0 + $UMULL $m1,$lo0,$n0 ; tp[0]*n0 + $UMULH $ahi,$aj,$m0 + $UMULL $lo1,$nj,$m1 ; np[0]*m1 + $UMULH $hi1,$nj,$m1 + $LD $nj,$BNSZ($np) ; np[1] + addc $lo1,$lo1,$lo0 + $UMULL $nlo,$nj,$m1 ; np[1]*m1 + addze $hi1,$hi1 + $UMULH $nhi,$nj,$m1 + + mtctr $num + li $j,`2*$BNSZ` +.align 4 +Linner: + $LDX $aj,$ap,$j ; ap[j] + addc $lo0,$alo,$hi0 + $LD $tj,$BNSZ($tp) ; tp[j] + addze $hi0,$ahi + $LDX $nj,$np,$j ; np[j] + addc $lo1,$nlo,$hi1 + $UMULL $alo,$aj,$m0 ; ap[j]*bp[i] + addze $hi1,$nhi + $UMULH $ahi,$aj,$m0 + addc $lo0,$lo0,$tj ; ap[j]*bp[i]+tp[j] + $UMULL $nlo,$nj,$m1 ; np[j]*m1 + addze $hi0,$hi0 + $UMULH $nhi,$nj,$m1 + addc $lo1,$lo1,$lo0 ; np[j]*m1+ap[j]*bp[i]+tp[j] + addi $j,$j,$BNSZ ; j++ + addze $hi1,$hi1 + $ST $lo1,0($tp) ; tp[j-1] + addi $tp,$tp,$BNSZ ; tp++ + bdnz- Linner +;Linner + $LD $tj,$BNSZ($tp) ; tp[j] + addc $lo0,$alo,$hi0 + addze $hi0,$ahi + addc $lo0,$lo0,$tj ; ap[j]*bp[i]+tp[j] + addze $hi0,$hi0 + + addc $lo1,$nlo,$hi1 + addze $hi1,$nhi + addc $lo1,$lo1,$lo0 ; np[j]*m1+ap[j]*bp[i]+tp[j] + addze $hi1,$hi1 + $ST $lo1,0($tp) ; tp[j-1] + + addic $ovf,$ovf,-1 ; move upmost overflow to XER[CA] + li $ovf,0 + adde $hi1,$hi1,$hi0 + addze $ovf,$ovf + $ST $hi1,$BNSZ($tp) +; + slwi $tj,$num,`log($BNSZ)/log(2)` + $UCMP $i,$tj + addi $i,$i,$BNSZ + ble- Louter + + addi $num,$num,2 ; restore $num + subfc $j,$j,$j ; j=0 and "clear" XER[CA] + addi $tp,$sp,$LOCALS + mtctr $num + +.align 4 +Lsub: $LDX $tj,$tp,$j + $LDX $nj,$np,$j + subfe $aj,$nj,$tj ; tp[j]-np[j] + $STX $aj,$rp,$j + addi $j,$j,$BNSZ + bdnz- Lsub + + li $j,0 + mtctr $num + subfe $ovf,$j,$ovf ; handle upmost overflow bit + and $ap,$tp,$ovf + andc $np,$rp,$ovf + or $ap,$ap,$np ; ap=borrow?tp:rp + +.align 4 +Lcopy: ; copy or in-place refresh + $LDX $tj,$ap,$j + $STX $tj,$rp,$j + $STX $j,$tp,$j ; zap at once + addi $j,$j,$BNSZ + bdnz- Lcopy + + $POP $tj,0($sp) + li r3,1 + $POP r20,`-12*$SIZE_T`($tj) + $POP r21,`-11*$SIZE_T`($tj) + $POP r22,`-10*$SIZE_T`($tj) + $POP r23,`-9*$SIZE_T`($tj) + $POP r24,`-8*$SIZE_T`($tj) + $POP r25,`-7*$SIZE_T`($tj) + $POP r26,`-6*$SIZE_T`($tj) + $POP r27,`-5*$SIZE_T`($tj) + $POP r28,`-4*$SIZE_T`($tj) + $POP r29,`-3*$SIZE_T`($tj) + $POP r30,`-2*$SIZE_T`($tj) + $POP r31,`-1*$SIZE_T`($tj) + mr $sp,$tj + blr + .long 0 + .byte 0,12,4,0,0x80,12,6,0 + .long 0 + +.asciz "Montgomery Multiplication for PPC, CRYPTOGAMS by " +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/ppc.pl b/libs/openssl/crypto/bn/asm/ppc.pl new file mode 100644 index 00000000..1249ce22 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/ppc.pl @@ -0,0 +1,1998 @@ +#!/usr/bin/env perl +# +# Implemented as a Perl wrapper as we want to support several different +# architectures with single file. We pick up the target based on the +# file name we are asked to generate. +# +# It should be noted though that this perl code is nothing like +# /crypto/perlasm/x86*. In this case perl is used pretty much +# as pre-processor to cover for platform differences in name decoration, +# linker tables, 32-/64-bit instruction sets... +# +# As you might know there're several PowerPC ABI in use. Most notably +# Linux and AIX use different 32-bit ABIs. Good news are that these ABIs +# are similar enough to implement leaf(!) functions, which would be ABI +# neutral. And that's what you find here: ABI neutral leaf functions. +# In case you wonder what that is... +# +# AIX performance +# +# MEASUREMENTS WITH cc ON a 200 MhZ PowerPC 604e. +# +# The following is the performance of 32-bit compiler +# generated code: +# +# OpenSSL 0.9.6c 21 dec 2001 +# built on: Tue Jun 11 11:06:51 EDT 2002 +# options:bn(64,32) ... +#compiler: cc -DTHREADS -DAIX -DB_ENDIAN -DBN_LLONG -O3 +# sign verify sign/s verify/s +#rsa 512 bits 0.0098s 0.0009s 102.0 1170.6 +#rsa 1024 bits 0.0507s 0.0026s 19.7 387.5 +#rsa 2048 bits 0.3036s 0.0085s 3.3 117.1 +#rsa 4096 bits 2.0040s 0.0299s 0.5 33.4 +#dsa 512 bits 0.0087s 0.0106s 114.3 94.5 +#dsa 1024 bits 0.0256s 0.0313s 39.0 32.0 +# +# Same bechmark with this assembler code: +# +#rsa 512 bits 0.0056s 0.0005s 178.6 2049.2 +#rsa 1024 bits 0.0283s 0.0015s 35.3 674.1 +#rsa 2048 bits 0.1744s 0.0050s 5.7 201.2 +#rsa 4096 bits 1.1644s 0.0179s 0.9 55.7 +#dsa 512 bits 0.0052s 0.0062s 191.6 162.0 +#dsa 1024 bits 0.0149s 0.0180s 67.0 55.5 +# +# Number of operations increases by at almost 75% +# +# Here are performance numbers for 64-bit compiler +# generated code: +# +# OpenSSL 0.9.6g [engine] 9 Aug 2002 +# built on: Fri Apr 18 16:59:20 EDT 2003 +# options:bn(64,64) ... +# compiler: cc -DTHREADS -D_REENTRANT -q64 -DB_ENDIAN -O3 +# sign verify sign/s verify/s +#rsa 512 bits 0.0028s 0.0003s 357.1 3844.4 +#rsa 1024 bits 0.0148s 0.0008s 67.5 1239.7 +#rsa 2048 bits 0.0963s 0.0028s 10.4 353.0 +#rsa 4096 bits 0.6538s 0.0102s 1.5 98.1 +#dsa 512 bits 0.0026s 0.0032s 382.5 313.7 +#dsa 1024 bits 0.0081s 0.0099s 122.8 100.6 +# +# Same benchmark with this assembler code: +# +#rsa 512 bits 0.0020s 0.0002s 510.4 6273.7 +#rsa 1024 bits 0.0088s 0.0005s 114.1 2128.3 +#rsa 2048 bits 0.0540s 0.0016s 18.5 622.5 +#rsa 4096 bits 0.3700s 0.0058s 2.7 171.0 +#dsa 512 bits 0.0016s 0.0020s 610.7 507.1 +#dsa 1024 bits 0.0047s 0.0058s 212.5 173.2 +# +# Again, performance increases by at about 75% +# +# Mac OS X, Apple G5 1.8GHz (Note this is 32 bit code) +# OpenSSL 0.9.7c 30 Sep 2003 +# +# Original code. +# +#rsa 512 bits 0.0011s 0.0001s 906.1 11012.5 +#rsa 1024 bits 0.0060s 0.0003s 166.6 3363.1 +#rsa 2048 bits 0.0370s 0.0010s 27.1 982.4 +#rsa 4096 bits 0.2426s 0.0036s 4.1 280.4 +#dsa 512 bits 0.0010s 0.0012s 1038.1 841.5 +#dsa 1024 bits 0.0030s 0.0037s 329.6 269.7 +#dsa 2048 bits 0.0101s 0.0127s 98.9 78.6 +# +# Same benchmark with this assembler code: +# +#rsa 512 bits 0.0007s 0.0001s 1416.2 16645.9 +#rsa 1024 bits 0.0036s 0.0002s 274.4 5380.6 +#rsa 2048 bits 0.0222s 0.0006s 45.1 1589.5 +#rsa 4096 bits 0.1469s 0.0022s 6.8 449.6 +#dsa 512 bits 0.0006s 0.0007s 1664.2 1376.2 +#dsa 1024 bits 0.0018s 0.0023s 545.0 442.2 +#dsa 2048 bits 0.0061s 0.0075s 163.5 132.8 +# +# Performance increase of ~60% +# +# If you have comments or suggestions to improve code send +# me a note at schari@us.ibm.com +# + +$flavour = shift; + +if ($flavour =~ /32/) { + $BITS= 32; + $BNSZ= $BITS/8; + $ISA= "\"ppc\""; + + $LD= "lwz"; # load + $LDU= "lwzu"; # load and update + $ST= "stw"; # store + $STU= "stwu"; # store and update + $UMULL= "mullw"; # unsigned multiply low + $UMULH= "mulhwu"; # unsigned multiply high + $UDIV= "divwu"; # unsigned divide + $UCMPI= "cmplwi"; # unsigned compare with immediate + $UCMP= "cmplw"; # unsigned compare + $CNTLZ= "cntlzw"; # count leading zeros + $SHL= "slw"; # shift left + $SHR= "srw"; # unsigned shift right + $SHRI= "srwi"; # unsigned shift right by immediate + $SHLI= "slwi"; # shift left by immediate + $CLRU= "clrlwi"; # clear upper bits + $INSR= "insrwi"; # insert right + $ROTL= "rotlwi"; # rotate left by immediate + $TR= "tw"; # conditional trap +} elsif ($flavour =~ /64/) { + $BITS= 64; + $BNSZ= $BITS/8; + $ISA= "\"ppc64\""; + + # same as above, but 64-bit mnemonics... + $LD= "ld"; # load + $LDU= "ldu"; # load and update + $ST= "std"; # store + $STU= "stdu"; # store and update + $UMULL= "mulld"; # unsigned multiply low + $UMULH= "mulhdu"; # unsigned multiply high + $UDIV= "divdu"; # unsigned divide + $UCMPI= "cmpldi"; # unsigned compare with immediate + $UCMP= "cmpld"; # unsigned compare + $CNTLZ= "cntlzd"; # count leading zeros + $SHL= "sld"; # shift left + $SHR= "srd"; # unsigned shift right + $SHRI= "srdi"; # unsigned shift right by immediate + $SHLI= "sldi"; # shift left by immediate + $CLRU= "clrldi"; # clear upper bits + $INSR= "insrdi"; # insert right + $ROTL= "rotldi"; # rotate left by immediate + $TR= "td"; # conditional trap +} else { die "nonsense $flavour"; } + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or +die "can't locate ppc-xlate.pl"; + +open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; + +$data=< 0 then result !=0 + # In either case carry bit is set. + beq Lppcasm_sub_adios + addi r4,r4,-$BNSZ + addi r3,r3,-$BNSZ + addi r5,r5,-$BNSZ + mtctr r6 +Lppcasm_sub_mainloop: + $LDU r7,$BNSZ(r4) + $LDU r8,$BNSZ(r5) + subfe r6,r8,r7 # r6 = r7+carry bit + onescomplement(r8) + # if carry = 1 this is r7-r8. Else it + # is r7-r8 -1 as we need. + $STU r6,$BNSZ(r3) + bdnz- Lppcasm_sub_mainloop +Lppcasm_sub_adios: + subfze r3,r0 # if carry bit is set then r3 = 0 else -1 + andi. r3,r3,1 # keep only last bit. + blr + .long 0 + .byte 0,12,0x14,0,0,0,4,0 + .long 0 + +# +# NOTE: The following label name should be changed to +# "bn_add_words" i.e. remove the first dot +# for the gcc compiler. This should be automatically +# done in the build +# + +.align 4 +.bn_add_words: +# +# Handcoded version of bn_add_words +# +#BN_ULONG bn_add_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) +# +# r3 = r +# r4 = a +# r5 = b +# r6 = n +# +# Note: No loop unrolling done since this is not a performance +# critical loop. + + xor r0,r0,r0 +# +# check for r6 = 0. Is this needed? +# + addic. r6,r6,0 #test r6 and clear carry bit. + beq Lppcasm_add_adios + addi r4,r4,-$BNSZ + addi r3,r3,-$BNSZ + addi r5,r5,-$BNSZ + mtctr r6 +Lppcasm_add_mainloop: + $LDU r7,$BNSZ(r4) + $LDU r8,$BNSZ(r5) + adde r8,r7,r8 + $STU r8,$BNSZ(r3) + bdnz- Lppcasm_add_mainloop +Lppcasm_add_adios: + addze r3,r0 #return carry bit. + blr + .long 0 + .byte 0,12,0x14,0,0,0,4,0 + .long 0 + +# +# NOTE: The following label name should be changed to +# "bn_div_words" i.e. remove the first dot +# for the gcc compiler. This should be automatically +# done in the build +# + +.align 4 +.bn_div_words: +# +# This is a cleaned up version of code generated by +# the AIX compiler. The only optimization is to use +# the PPC instruction to count leading zeros instead +# of call to num_bits_word. Since this was compiled +# only at level -O2 we can possibly squeeze it more? +# +# r3 = h +# r4 = l +# r5 = d + + $UCMPI 0,r5,0 # compare r5 and 0 + bne Lppcasm_div1 # proceed if d!=0 + li r3,-1 # d=0 return -1 + blr +Lppcasm_div1: + xor r0,r0,r0 #r0=0 + li r8,$BITS + $CNTLZ. r7,r5 #r7 = num leading 0s in d. + beq Lppcasm_div2 #proceed if no leading zeros + subf r8,r7,r8 #r8 = BN_num_bits_word(d) + $SHR. r9,r3,r8 #are there any bits above r8'th? + $TR 16,r9,r0 #if there're, signal to dump core... +Lppcasm_div2: + $UCMP 0,r3,r5 #h>=d? + blt Lppcasm_div3 #goto Lppcasm_div3 if not + subf r3,r5,r3 #h-=d ; +Lppcasm_div3: #r7 = BN_BITS2-i. so r7=i + cmpi 0,0,r7,0 # is (i == 0)? + beq Lppcasm_div4 + $SHL r3,r3,r7 # h = (h<< i) + $SHR r8,r4,r8 # r8 = (l >> BN_BITS2 -i) + $SHL r5,r5,r7 # d<<=i + or r3,r3,r8 # h = (h<>(BN_BITS2-i)) + $SHL r4,r4,r7 # l <<=i +Lppcasm_div4: + $SHRI r9,r5,`$BITS/2` # r9 = dh + # dl will be computed when needed + # as it saves registers. + li r6,2 #r6=2 + mtctr r6 #counter will be in count. +Lppcasm_divouterloop: + $SHRI r8,r3,`$BITS/2` #r8 = (h>>BN_BITS4) + $SHRI r11,r4,`$BITS/2` #r11= (l&BN_MASK2h)>>BN_BITS4 + # compute here for innerloop. + $UCMP 0,r8,r9 # is (h>>BN_BITS4)==dh + bne Lppcasm_div5 # goto Lppcasm_div5 if not + + li r8,-1 + $CLRU r8,r8,`$BITS/2` #q = BN_MASK2l + b Lppcasm_div6 +Lppcasm_div5: + $UDIV r8,r3,r9 #q = h/dh +Lppcasm_div6: + $UMULL r12,r9,r8 #th = q*dh + $CLRU r10,r5,`$BITS/2` #r10=dl + $UMULL r6,r8,r10 #tl = q*dl + +Lppcasm_divinnerloop: + subf r10,r12,r3 #t = h -th + $SHRI r7,r10,`$BITS/2` #r7= (t &BN_MASK2H), sort of... + addic. r7,r7,0 #test if r7 == 0. used below. + # now want to compute + # r7 = (t<>BN_BITS4) + # the following 2 instructions do that + $SHLI r7,r10,`$BITS/2` # r7 = (t<>BN_BITS4) + $UCMP cr1,r6,r7 # compare (tl <= r7) + bne Lppcasm_divinnerexit + ble cr1,Lppcasm_divinnerexit + addi r8,r8,-1 #q-- + subf r12,r9,r12 #th -=dh + $CLRU r10,r5,`$BITS/2` #r10=dl. t is no longer needed in loop. + subf r6,r10,r6 #tl -=dl + b Lppcasm_divinnerloop +Lppcasm_divinnerexit: + $SHRI r10,r6,`$BITS/2` #t=(tl>>BN_BITS4) + $SHLI r11,r6,`$BITS/2` #tl=(tl<=tl) goto Lppcasm_div7 + addi r12,r12,1 # th++ +Lppcasm_div7: + subf r11,r11,r4 #r11=l-tl + $UCMP cr1,r3,r12 #compare h and th + bge cr1,Lppcasm_div8 #if (h>=th) goto Lppcasm_div8 + addi r8,r8,-1 # q-- + add r3,r5,r3 # h+=d +Lppcasm_div8: + subf r12,r12,r3 #r12 = h-th + $SHLI r4,r11,`$BITS/2` #l=(l&BN_MASK2l)<>BN_BITS4))&BN_MASK2 + # the following 2 instructions will do this. + $INSR r11,r12,`$BITS/2`,`$BITS/2` # r11 is the value we want rotated $BITS/2. + $ROTL r3,r11,`$BITS/2` # rotate by $BITS/2 and store in r3 + bdz Lppcasm_div9 #if (count==0) break ; + $SHLI r0,r8,`$BITS/2` #ret =q<> 2 + beq Lppcasm_mw_REM + mtctr r7 +Lppcasm_mw_LOOP: + #mul(rp[0],ap[0],w,c1); + $LD r8,`0*$BNSZ`(r4) + $UMULL r9,r6,r8 + $UMULH r10,r6,r8 + addc r9,r9,r12 + #addze r10,r10 #carry is NOT ignored. + #will be taken care of + #in second spin below + #using adde. + $ST r9,`0*$BNSZ`(r3) + #mul(rp[1],ap[1],w,c1); + $LD r8,`1*$BNSZ`(r4) + $UMULL r11,r6,r8 + $UMULH r12,r6,r8 + adde r11,r11,r10 + #addze r12,r12 + $ST r11,`1*$BNSZ`(r3) + #mul(rp[2],ap[2],w,c1); + $LD r8,`2*$BNSZ`(r4) + $UMULL r9,r6,r8 + $UMULH r10,r6,r8 + adde r9,r9,r12 + #addze r10,r10 + $ST r9,`2*$BNSZ`(r3) + #mul_add(rp[3],ap[3],w,c1); + $LD r8,`3*$BNSZ`(r4) + $UMULL r11,r6,r8 + $UMULH r12,r6,r8 + adde r11,r11,r10 + addze r12,r12 #this spin we collect carry into + #r12 + $ST r11,`3*$BNSZ`(r3) + + addi r3,r3,`4*$BNSZ` + addi r4,r4,`4*$BNSZ` + bdnz- Lppcasm_mw_LOOP + +Lppcasm_mw_REM: + andi. r5,r5,0x3 + beq Lppcasm_mw_OVER + #mul(rp[0],ap[0],w,c1); + $LD r8,`0*$BNSZ`(r4) + $UMULL r9,r6,r8 + $UMULH r10,r6,r8 + addc r9,r9,r12 + addze r10,r10 + $ST r9,`0*$BNSZ`(r3) + addi r12,r10,0 + + addi r5,r5,-1 + cmpli 0,0,r5,0 + beq Lppcasm_mw_OVER + + + #mul(rp[1],ap[1],w,c1); + $LD r8,`1*$BNSZ`(r4) + $UMULL r9,r6,r8 + $UMULH r10,r6,r8 + addc r9,r9,r12 + addze r10,r10 + $ST r9,`1*$BNSZ`(r3) + addi r12,r10,0 + + addi r5,r5,-1 + cmpli 0,0,r5,0 + beq Lppcasm_mw_OVER + + #mul_add(rp[2],ap[2],w,c1); + $LD r8,`2*$BNSZ`(r4) + $UMULL r9,r6,r8 + $UMULH r10,r6,r8 + addc r9,r9,r12 + addze r10,r10 + $ST r9,`2*$BNSZ`(r3) + addi r12,r10,0 + +Lppcasm_mw_OVER: + addi r3,r12,0 + blr + .long 0 + .byte 0,12,0x14,0,0,0,4,0 + .long 0 + +# +# NOTE: The following label name should be changed to +# "bn_mul_add_words" i.e. remove the first dot +# for the gcc compiler. This should be automatically +# done in the build +# + +.align 4 +.bn_mul_add_words: +# +# BN_ULONG bn_mul_add_words(BN_ULONG *rp, BN_ULONG *ap, int num, BN_ULONG w) +# +# r3 = rp +# r4 = ap +# r5 = num +# r6 = w +# +# empirical evidence suggests that unrolled version performs best!! +# + xor r0,r0,r0 #r0 = 0 + xor r12,r12,r12 #r12 = 0 . used for carry + rlwinm. r7,r5,30,2,31 # num >> 2 + beq Lppcasm_maw_leftover # if (num < 4) go LPPCASM_maw_leftover + mtctr r7 +Lppcasm_maw_mainloop: + #mul_add(rp[0],ap[0],w,c1); + $LD r8,`0*$BNSZ`(r4) + $LD r11,`0*$BNSZ`(r3) + $UMULL r9,r6,r8 + $UMULH r10,r6,r8 + addc r9,r9,r12 #r12 is carry. + addze r10,r10 + addc r9,r9,r11 + #addze r10,r10 + #the above instruction addze + #is NOT needed. Carry will NOT + #be ignored. It's not affected + #by multiply and will be collected + #in the next spin + $ST r9,`0*$BNSZ`(r3) + + #mul_add(rp[1],ap[1],w,c1); + $LD r8,`1*$BNSZ`(r4) + $LD r9,`1*$BNSZ`(r3) + $UMULL r11,r6,r8 + $UMULH r12,r6,r8 + adde r11,r11,r10 #r10 is carry. + addze r12,r12 + addc r11,r11,r9 + #addze r12,r12 + $ST r11,`1*$BNSZ`(r3) + + #mul_add(rp[2],ap[2],w,c1); + $LD r8,`2*$BNSZ`(r4) + $UMULL r9,r6,r8 + $LD r11,`2*$BNSZ`(r3) + $UMULH r10,r6,r8 + adde r9,r9,r12 + addze r10,r10 + addc r9,r9,r11 + #addze r10,r10 + $ST r9,`2*$BNSZ`(r3) + + #mul_add(rp[3],ap[3],w,c1); + $LD r8,`3*$BNSZ`(r4) + $UMULL r11,r6,r8 + $LD r9,`3*$BNSZ`(r3) + $UMULH r12,r6,r8 + adde r11,r11,r10 + addze r12,r12 + addc r11,r11,r9 + addze r12,r12 + $ST r11,`3*$BNSZ`(r3) + addi r3,r3,`4*$BNSZ` + addi r4,r4,`4*$BNSZ` + bdnz- Lppcasm_maw_mainloop + +Lppcasm_maw_leftover: + andi. r5,r5,0x3 + beq Lppcasm_maw_adios + addi r3,r3,-$BNSZ + addi r4,r4,-$BNSZ + #mul_add(rp[0],ap[0],w,c1); + mtctr r5 + $LDU r8,$BNSZ(r4) + $UMULL r9,r6,r8 + $UMULH r10,r6,r8 + $LDU r11,$BNSZ(r3) + addc r9,r9,r11 + addze r10,r10 + addc r9,r9,r12 + addze r12,r10 + $ST r9,0(r3) + + bdz Lppcasm_maw_adios + #mul_add(rp[1],ap[1],w,c1); + $LDU r8,$BNSZ(r4) + $UMULL r9,r6,r8 + $UMULH r10,r6,r8 + $LDU r11,$BNSZ(r3) + addc r9,r9,r11 + addze r10,r10 + addc r9,r9,r12 + addze r12,r10 + $ST r9,0(r3) + + bdz Lppcasm_maw_adios + #mul_add(rp[2],ap[2],w,c1); + $LDU r8,$BNSZ(r4) + $UMULL r9,r6,r8 + $UMULH r10,r6,r8 + $LDU r11,$BNSZ(r3) + addc r9,r9,r11 + addze r10,r10 + addc r9,r9,r12 + addze r12,r10 + $ST r9,0(r3) + +Lppcasm_maw_adios: + addi r3,r12,0 + blr + .long 0 + .byte 0,12,0x14,0,0,0,4,0 + .long 0 + .align 4 +EOF +$data =~ s/\`([^\`]*)\`/eval $1/gem; +print $data; +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/ppc64-mont.pl b/libs/openssl/crypto/bn/asm/ppc64-mont.pl new file mode 100644 index 00000000..a14e769a --- /dev/null +++ b/libs/openssl/crypto/bn/asm/ppc64-mont.pl @@ -0,0 +1,1088 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# December 2007 + +# The reason for undertaken effort is basically following. Even though +# Power 6 CPU operates at incredible 4.7GHz clock frequency, its PKI +# performance was observed to be less than impressive, essentially as +# fast as 1.8GHz PPC970, or 2.6 times(!) slower than one would hope. +# Well, it's not surprising that IBM had to make some sacrifices to +# boost the clock frequency that much, but no overall improvement? +# Having observed how much difference did switching to FPU make on +# UltraSPARC, playing same stunt on Power 6 appeared appropriate... +# Unfortunately the resulting performance improvement is not as +# impressive, ~30%, and in absolute terms is still very far from what +# one would expect from 4.7GHz CPU. There is a chance that I'm doing +# something wrong, but in the lack of assembler level micro-profiling +# data or at least decent platform guide I can't tell... Or better +# results might be achieved with VMX... Anyway, this module provides +# *worse* performance on other PowerPC implementations, ~40-15% slower +# on PPC970 depending on key length and ~40% slower on Power 5 for all +# key lengths. As it's obviously inappropriate as "best all-round" +# alternative, it has to be complemented with run-time CPU family +# detection. Oh! It should also be noted that unlike other PowerPC +# implementation IALU ppc-mont.pl module performs *suboptimaly* on +# >=1024-bit key lengths on Power 6. It should also be noted that +# *everything* said so far applies to 64-bit builds! As far as 32-bit +# application executed on 64-bit CPU goes, this module is likely to +# become preferred choice, because it's easy to adapt it for such +# case and *is* faster than 32-bit ppc-mont.pl on *all* processors. + +# February 2008 + +# Micro-profiling assisted optimization results in ~15% improvement +# over original ppc64-mont.pl version, or overall ~50% improvement +# over ppc.pl module on Power 6. If compared to ppc-mont.pl on same +# Power 6 CPU, this module is 5-150% faster depending on key length, +# [hereafter] more for longer keys. But if compared to ppc-mont.pl +# on 1.8GHz PPC970, it's only 5-55% faster. Still far from impressive +# in absolute terms, but it's apparently the way Power 6 is... + +# December 2009 + +# Adapted for 32-bit build this module delivers 25-120%, yes, more +# than *twice* for longer keys, performance improvement over 32-bit +# ppc-mont.pl on 1.8GHz PPC970. However! This implementation utilizes +# even 64-bit integer operations and the trouble is that most PPC +# operating systems don't preserve upper halves of general purpose +# registers upon 32-bit signal delivery. They do preserve them upon +# context switch, but not signalling:-( This means that asynchronous +# signals have to be blocked upon entry to this subroutine. Signal +# masking (and of course complementary unmasking) has quite an impact +# on performance, naturally larger for shorter keys. It's so severe +# that 512-bit key performance can be as low as 1/3 of expected one. +# This is why this routine can be engaged for longer key operations +# only on these OSes, see crypto/ppccap.c for further details. MacOS X +# is an exception from this and doesn't require signal masking, and +# that's where above improvement coefficients were collected. For +# others alternative would be to break dependence on upper halves of +# GPRs by sticking to 32-bit integer operations... + +$flavour = shift; + +if ($flavour =~ /32/) { + $SIZE_T=4; + $RZONE= 224; + $fname= "bn_mul_mont_fpu64"; + + $STUX= "stwux"; # store indexed and update + $PUSH= "stw"; + $POP= "lwz"; +} elsif ($flavour =~ /64/) { + $SIZE_T=8; + $RZONE= 288; + $fname= "bn_mul_mont_fpu64"; + + # same as above, but 64-bit mnemonics... + $STUX= "stdux"; # store indexed and update + $PUSH= "std"; + $POP= "ld"; +} else { die "nonsense $flavour"; } + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or +die "can't locate ppc-xlate.pl"; + +open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; + +$FRAME=64; # padded frame header +$TRANSFER=16*8; + +$carry="r0"; +$sp="r1"; +$toc="r2"; +$rp="r3"; $ovf="r3"; +$ap="r4"; +$bp="r5"; +$np="r6"; +$n0="r7"; +$num="r8"; +$rp="r9"; # $rp is reassigned +$tp="r10"; +$j="r11"; +$i="r12"; +# non-volatile registers +$nap_d="r22"; # interleaved ap and np in double format +$a0="r23"; # ap[0] +$t0="r24"; # temporary registers +$t1="r25"; +$t2="r26"; +$t3="r27"; +$t4="r28"; +$t5="r29"; +$t6="r30"; +$t7="r31"; + +# PPC offers enough register bank capacity to unroll inner loops twice +# +# ..A3A2A1A0 +# dcba +# ----------- +# A0a +# A0b +# A0c +# A0d +# A1a +# A1b +# A1c +# A1d +# A2a +# A2b +# A2c +# A2d +# A3a +# A3b +# A3c +# A3d +# ..a +# ..b +# +$ba="f0"; $bb="f1"; $bc="f2"; $bd="f3"; +$na="f4"; $nb="f5"; $nc="f6"; $nd="f7"; +$dota="f8"; $dotb="f9"; +$A0="f10"; $A1="f11"; $A2="f12"; $A3="f13"; +$N0="f20"; $N1="f21"; $N2="f22"; $N3="f23"; +$T0a="f24"; $T0b="f25"; +$T1a="f26"; $T1b="f27"; +$T2a="f28"; $T2b="f29"; +$T3a="f30"; $T3b="f31"; + +# sp----------->+-------------------------------+ +# | saved sp | +# +-------------------------------+ +# . . +# +64 +-------------------------------+ +# | 16 gpr<->fpr transfer zone | +# . . +# . . +# +16*8 +-------------------------------+ +# | __int64 tmp[-1] | +# +-------------------------------+ +# | __int64 tmp[num] | +# . . +# . . +# . . +# +(num+1)*8 +-------------------------------+ +# | padding to 64 byte boundary | +# . . +# +X +-------------------------------+ +# | double nap_d[4*num] | +# . . +# . . +# . . +# +-------------------------------+ +# . . +# -12*size_t +-------------------------------+ +# | 10 saved gpr, r22-r31 | +# . . +# . . +# -12*8 +-------------------------------+ +# | 12 saved fpr, f20-f31 | +# . . +# . . +# +-------------------------------+ + +$code=<<___; +.machine "any" +.text + +.globl .$fname +.align 5 +.$fname: + cmpwi $num,`3*8/$SIZE_T` + mr $rp,r3 ; $rp is reassigned + li r3,0 ; possible "not handled" return code + bltlr- + andi. r0,$num,`16/$SIZE_T-1` ; $num has to be "even" + bnelr- + + slwi $num,$num,`log($SIZE_T)/log(2)` ; num*=sizeof(BN_LONG) + li $i,-4096 + slwi $tp,$num,2 ; place for {an}p_{lh}[num], i.e. 4*num + add $tp,$tp,$num ; place for tp[num+1] + addi $tp,$tp,`$FRAME+$TRANSFER+8+64+$RZONE` + subf $tp,$tp,$sp ; $sp-$tp + and $tp,$tp,$i ; minimize TLB usage + subf $tp,$sp,$tp ; $tp-$sp + mr $i,$sp + $STUX $sp,$sp,$tp ; alloca + + $PUSH r22,`-12*8-10*$SIZE_T`($i) + $PUSH r23,`-12*8-9*$SIZE_T`($i) + $PUSH r24,`-12*8-8*$SIZE_T`($i) + $PUSH r25,`-12*8-7*$SIZE_T`($i) + $PUSH r26,`-12*8-6*$SIZE_T`($i) + $PUSH r27,`-12*8-5*$SIZE_T`($i) + $PUSH r28,`-12*8-4*$SIZE_T`($i) + $PUSH r29,`-12*8-3*$SIZE_T`($i) + $PUSH r30,`-12*8-2*$SIZE_T`($i) + $PUSH r31,`-12*8-1*$SIZE_T`($i) + stfd f20,`-12*8`($i) + stfd f21,`-11*8`($i) + stfd f22,`-10*8`($i) + stfd f23,`-9*8`($i) + stfd f24,`-8*8`($i) + stfd f25,`-7*8`($i) + stfd f26,`-6*8`($i) + stfd f27,`-5*8`($i) + stfd f28,`-4*8`($i) + stfd f29,`-3*8`($i) + stfd f30,`-2*8`($i) + stfd f31,`-1*8`($i) +___ +$code.=<<___ if ($SIZE_T==8); + ld $a0,0($ap) ; pull ap[0] value + ld $n0,0($n0) ; pull n0[0] value + ld $t3,0($bp) ; bp[0] +___ +$code.=<<___ if ($SIZE_T==4); + mr $t1,$n0 + lwz $a0,0($ap) ; pull ap[0,1] value + lwz $t0,4($ap) + lwz $n0,0($t1) ; pull n0[0,1] value + lwz $t1,4($t1) + lwz $t3,0($bp) ; bp[0,1] + lwz $t2,4($bp) + insrdi $a0,$t0,32,0 + insrdi $n0,$t1,32,0 + insrdi $t3,$t2,32,0 +___ +$code.=<<___; + addi $tp,$sp,`$FRAME+$TRANSFER+8+64` + li $i,-64 + add $nap_d,$tp,$num + and $nap_d,$nap_d,$i ; align to 64 bytes + + mulld $t7,$a0,$t3 ; ap[0]*bp[0] + ; nap_d is off by 1, because it's used with stfdu/lfdu + addi $nap_d,$nap_d,-8 + srwi $j,$num,`3+1` ; counter register, num/2 + mulld $t7,$t7,$n0 ; tp[0]*n0 + addi $j,$j,-1 + addi $tp,$sp,`$FRAME+$TRANSFER-8` + li $carry,0 + mtctr $j + + ; transfer bp[0] to FPU as 4x16-bit values + extrdi $t0,$t3,16,48 + extrdi $t1,$t3,16,32 + extrdi $t2,$t3,16,16 + extrdi $t3,$t3,16,0 + std $t0,`$FRAME+0`($sp) + std $t1,`$FRAME+8`($sp) + std $t2,`$FRAME+16`($sp) + std $t3,`$FRAME+24`($sp) + ; transfer (ap[0]*bp[0])*n0 to FPU as 4x16-bit values + extrdi $t4,$t7,16,48 + extrdi $t5,$t7,16,32 + extrdi $t6,$t7,16,16 + extrdi $t7,$t7,16,0 + std $t4,`$FRAME+32`($sp) + std $t5,`$FRAME+40`($sp) + std $t6,`$FRAME+48`($sp) + std $t7,`$FRAME+56`($sp) +___ +$code.=<<___ if ($SIZE_T==8); + lwz $t0,4($ap) ; load a[j] as 32-bit word pair + lwz $t1,0($ap) + lwz $t2,12($ap) ; load a[j+1] as 32-bit word pair + lwz $t3,8($ap) + lwz $t4,4($np) ; load n[j] as 32-bit word pair + lwz $t5,0($np) + lwz $t6,12($np) ; load n[j+1] as 32-bit word pair + lwz $t7,8($np) +___ +$code.=<<___ if ($SIZE_T==4); + lwz $t0,0($ap) ; load a[j..j+3] as 32-bit word pairs + lwz $t1,4($ap) + lwz $t2,8($ap) + lwz $t3,12($ap) + lwz $t4,0($np) ; load n[j..j+3] as 32-bit word pairs + lwz $t5,4($np) + lwz $t6,8($np) + lwz $t7,12($np) +___ +$code.=<<___; + lfd $ba,`$FRAME+0`($sp) + lfd $bb,`$FRAME+8`($sp) + lfd $bc,`$FRAME+16`($sp) + lfd $bd,`$FRAME+24`($sp) + lfd $na,`$FRAME+32`($sp) + lfd $nb,`$FRAME+40`($sp) + lfd $nc,`$FRAME+48`($sp) + lfd $nd,`$FRAME+56`($sp) + std $t0,`$FRAME+64`($sp) + std $t1,`$FRAME+72`($sp) + std $t2,`$FRAME+80`($sp) + std $t3,`$FRAME+88`($sp) + std $t4,`$FRAME+96`($sp) + std $t5,`$FRAME+104`($sp) + std $t6,`$FRAME+112`($sp) + std $t7,`$FRAME+120`($sp) + fcfid $ba,$ba + fcfid $bb,$bb + fcfid $bc,$bc + fcfid $bd,$bd + fcfid $na,$na + fcfid $nb,$nb + fcfid $nc,$nc + fcfid $nd,$nd + + lfd $A0,`$FRAME+64`($sp) + lfd $A1,`$FRAME+72`($sp) + lfd $A2,`$FRAME+80`($sp) + lfd $A3,`$FRAME+88`($sp) + lfd $N0,`$FRAME+96`($sp) + lfd $N1,`$FRAME+104`($sp) + lfd $N2,`$FRAME+112`($sp) + lfd $N3,`$FRAME+120`($sp) + fcfid $A0,$A0 + fcfid $A1,$A1 + fcfid $A2,$A2 + fcfid $A3,$A3 + fcfid $N0,$N0 + fcfid $N1,$N1 + fcfid $N2,$N2 + fcfid $N3,$N3 + addi $ap,$ap,16 + addi $np,$np,16 + + fmul $T1a,$A1,$ba + fmul $T1b,$A1,$bb + stfd $A0,8($nap_d) ; save a[j] in double format + stfd $A1,16($nap_d) + fmul $T2a,$A2,$ba + fmul $T2b,$A2,$bb + stfd $A2,24($nap_d) ; save a[j+1] in double format + stfd $A3,32($nap_d) + fmul $T3a,$A3,$ba + fmul $T3b,$A3,$bb + stfd $N0,40($nap_d) ; save n[j] in double format + stfd $N1,48($nap_d) + fmul $T0a,$A0,$ba + fmul $T0b,$A0,$bb + stfd $N2,56($nap_d) ; save n[j+1] in double format + stfdu $N3,64($nap_d) + + fmadd $T1a,$A0,$bc,$T1a + fmadd $T1b,$A0,$bd,$T1b + fmadd $T2a,$A1,$bc,$T2a + fmadd $T2b,$A1,$bd,$T2b + fmadd $T3a,$A2,$bc,$T3a + fmadd $T3b,$A2,$bd,$T3b + fmul $dota,$A3,$bc + fmul $dotb,$A3,$bd + + fmadd $T1a,$N1,$na,$T1a + fmadd $T1b,$N1,$nb,$T1b + fmadd $T2a,$N2,$na,$T2a + fmadd $T2b,$N2,$nb,$T2b + fmadd $T3a,$N3,$na,$T3a + fmadd $T3b,$N3,$nb,$T3b + fmadd $T0a,$N0,$na,$T0a + fmadd $T0b,$N0,$nb,$T0b + + fmadd $T1a,$N0,$nc,$T1a + fmadd $T1b,$N0,$nd,$T1b + fmadd $T2a,$N1,$nc,$T2a + fmadd $T2b,$N1,$nd,$T2b + fmadd $T3a,$N2,$nc,$T3a + fmadd $T3b,$N2,$nd,$T3b + fmadd $dota,$N3,$nc,$dota + fmadd $dotb,$N3,$nd,$dotb + + fctid $T0a,$T0a + fctid $T0b,$T0b + fctid $T1a,$T1a + fctid $T1b,$T1b + fctid $T2a,$T2a + fctid $T2b,$T2b + fctid $T3a,$T3a + fctid $T3b,$T3b + + stfd $T0a,`$FRAME+0`($sp) + stfd $T0b,`$FRAME+8`($sp) + stfd $T1a,`$FRAME+16`($sp) + stfd $T1b,`$FRAME+24`($sp) + stfd $T2a,`$FRAME+32`($sp) + stfd $T2b,`$FRAME+40`($sp) + stfd $T3a,`$FRAME+48`($sp) + stfd $T3b,`$FRAME+56`($sp) + +.align 5 +L1st: +___ +$code.=<<___ if ($SIZE_T==8); + lwz $t0,4($ap) ; load a[j] as 32-bit word pair + lwz $t1,0($ap) + lwz $t2,12($ap) ; load a[j+1] as 32-bit word pair + lwz $t3,8($ap) + lwz $t4,4($np) ; load n[j] as 32-bit word pair + lwz $t5,0($np) + lwz $t6,12($np) ; load n[j+1] as 32-bit word pair + lwz $t7,8($np) +___ +$code.=<<___ if ($SIZE_T==4); + lwz $t0,0($ap) ; load a[j..j+3] as 32-bit word pairs + lwz $t1,4($ap) + lwz $t2,8($ap) + lwz $t3,12($ap) + lwz $t4,0($np) ; load n[j..j+3] as 32-bit word pairs + lwz $t5,4($np) + lwz $t6,8($np) + lwz $t7,12($np) +___ +$code.=<<___; + std $t0,`$FRAME+64`($sp) + std $t1,`$FRAME+72`($sp) + std $t2,`$FRAME+80`($sp) + std $t3,`$FRAME+88`($sp) + std $t4,`$FRAME+96`($sp) + std $t5,`$FRAME+104`($sp) + std $t6,`$FRAME+112`($sp) + std $t7,`$FRAME+120`($sp) + ld $t0,`$FRAME+0`($sp) + ld $t1,`$FRAME+8`($sp) + ld $t2,`$FRAME+16`($sp) + ld $t3,`$FRAME+24`($sp) + ld $t4,`$FRAME+32`($sp) + ld $t5,`$FRAME+40`($sp) + ld $t6,`$FRAME+48`($sp) + ld $t7,`$FRAME+56`($sp) + lfd $A0,`$FRAME+64`($sp) + lfd $A1,`$FRAME+72`($sp) + lfd $A2,`$FRAME+80`($sp) + lfd $A3,`$FRAME+88`($sp) + lfd $N0,`$FRAME+96`($sp) + lfd $N1,`$FRAME+104`($sp) + lfd $N2,`$FRAME+112`($sp) + lfd $N3,`$FRAME+120`($sp) + fcfid $A0,$A0 + fcfid $A1,$A1 + fcfid $A2,$A2 + fcfid $A3,$A3 + fcfid $N0,$N0 + fcfid $N1,$N1 + fcfid $N2,$N2 + fcfid $N3,$N3 + addi $ap,$ap,16 + addi $np,$np,16 + + fmul $T1a,$A1,$ba + fmul $T1b,$A1,$bb + fmul $T2a,$A2,$ba + fmul $T2b,$A2,$bb + stfd $A0,8($nap_d) ; save a[j] in double format + stfd $A1,16($nap_d) + fmul $T3a,$A3,$ba + fmul $T3b,$A3,$bb + fmadd $T0a,$A0,$ba,$dota + fmadd $T0b,$A0,$bb,$dotb + stfd $A2,24($nap_d) ; save a[j+1] in double format + stfd $A3,32($nap_d) + + fmadd $T1a,$A0,$bc,$T1a + fmadd $T1b,$A0,$bd,$T1b + fmadd $T2a,$A1,$bc,$T2a + fmadd $T2b,$A1,$bd,$T2b + stfd $N0,40($nap_d) ; save n[j] in double format + stfd $N1,48($nap_d) + fmadd $T3a,$A2,$bc,$T3a + fmadd $T3b,$A2,$bd,$T3b + add $t0,$t0,$carry ; can not overflow + fmul $dota,$A3,$bc + fmul $dotb,$A3,$bd + stfd $N2,56($nap_d) ; save n[j+1] in double format + stfdu $N3,64($nap_d) + srdi $carry,$t0,16 + add $t1,$t1,$carry + srdi $carry,$t1,16 + + fmadd $T1a,$N1,$na,$T1a + fmadd $T1b,$N1,$nb,$T1b + insrdi $t0,$t1,16,32 + fmadd $T2a,$N2,$na,$T2a + fmadd $T2b,$N2,$nb,$T2b + add $t2,$t2,$carry + fmadd $T3a,$N3,$na,$T3a + fmadd $T3b,$N3,$nb,$T3b + srdi $carry,$t2,16 + fmadd $T0a,$N0,$na,$T0a + fmadd $T0b,$N0,$nb,$T0b + insrdi $t0,$t2,16,16 + add $t3,$t3,$carry + srdi $carry,$t3,16 + + fmadd $T1a,$N0,$nc,$T1a + fmadd $T1b,$N0,$nd,$T1b + insrdi $t0,$t3,16,0 ; 0..63 bits + fmadd $T2a,$N1,$nc,$T2a + fmadd $T2b,$N1,$nd,$T2b + add $t4,$t4,$carry + fmadd $T3a,$N2,$nc,$T3a + fmadd $T3b,$N2,$nd,$T3b + srdi $carry,$t4,16 + fmadd $dota,$N3,$nc,$dota + fmadd $dotb,$N3,$nd,$dotb + add $t5,$t5,$carry + srdi $carry,$t5,16 + insrdi $t4,$t5,16,32 + + fctid $T0a,$T0a + fctid $T0b,$T0b + add $t6,$t6,$carry + fctid $T1a,$T1a + fctid $T1b,$T1b + srdi $carry,$t6,16 + fctid $T2a,$T2a + fctid $T2b,$T2b + insrdi $t4,$t6,16,16 + fctid $T3a,$T3a + fctid $T3b,$T3b + add $t7,$t7,$carry + insrdi $t4,$t7,16,0 ; 64..127 bits + srdi $carry,$t7,16 ; upper 33 bits + + stfd $T0a,`$FRAME+0`($sp) + stfd $T0b,`$FRAME+8`($sp) + stfd $T1a,`$FRAME+16`($sp) + stfd $T1b,`$FRAME+24`($sp) + stfd $T2a,`$FRAME+32`($sp) + stfd $T2b,`$FRAME+40`($sp) + stfd $T3a,`$FRAME+48`($sp) + stfd $T3b,`$FRAME+56`($sp) + std $t0,8($tp) ; tp[j-1] + stdu $t4,16($tp) ; tp[j] + bdnz- L1st + + fctid $dota,$dota + fctid $dotb,$dotb + + ld $t0,`$FRAME+0`($sp) + ld $t1,`$FRAME+8`($sp) + ld $t2,`$FRAME+16`($sp) + ld $t3,`$FRAME+24`($sp) + ld $t4,`$FRAME+32`($sp) + ld $t5,`$FRAME+40`($sp) + ld $t6,`$FRAME+48`($sp) + ld $t7,`$FRAME+56`($sp) + stfd $dota,`$FRAME+64`($sp) + stfd $dotb,`$FRAME+72`($sp) + + add $t0,$t0,$carry ; can not overflow + srdi $carry,$t0,16 + add $t1,$t1,$carry + srdi $carry,$t1,16 + insrdi $t0,$t1,16,32 + add $t2,$t2,$carry + srdi $carry,$t2,16 + insrdi $t0,$t2,16,16 + add $t3,$t3,$carry + srdi $carry,$t3,16 + insrdi $t0,$t3,16,0 ; 0..63 bits + add $t4,$t4,$carry + srdi $carry,$t4,16 + add $t5,$t5,$carry + srdi $carry,$t5,16 + insrdi $t4,$t5,16,32 + add $t6,$t6,$carry + srdi $carry,$t6,16 + insrdi $t4,$t6,16,16 + add $t7,$t7,$carry + insrdi $t4,$t7,16,0 ; 64..127 bits + srdi $carry,$t7,16 ; upper 33 bits + ld $t6,`$FRAME+64`($sp) + ld $t7,`$FRAME+72`($sp) + + std $t0,8($tp) ; tp[j-1] + stdu $t4,16($tp) ; tp[j] + + add $t6,$t6,$carry ; can not overflow + srdi $carry,$t6,16 + add $t7,$t7,$carry + insrdi $t6,$t7,48,0 + srdi $ovf,$t7,48 + std $t6,8($tp) ; tp[num-1] + + slwi $t7,$num,2 + subf $nap_d,$t7,$nap_d ; rewind pointer + + li $i,8 ; i=1 +.align 5 +Louter: +___ +$code.=<<___ if ($SIZE_T==8); + ldx $t3,$bp,$i ; bp[i] +___ +$code.=<<___ if ($SIZE_T==4); + add $t0,$bp,$i + lwz $t3,0($t0) ; bp[i,i+1] + lwz $t0,4($t0) + insrdi $t3,$t0,32,0 +___ +$code.=<<___; + ld $t6,`$FRAME+$TRANSFER+8`($sp) ; tp[0] + mulld $t7,$a0,$t3 ; ap[0]*bp[i] + + addi $tp,$sp,`$FRAME+$TRANSFER` + add $t7,$t7,$t6 ; ap[0]*bp[i]+tp[0] + li $carry,0 + mulld $t7,$t7,$n0 ; tp[0]*n0 + mtctr $j + + ; transfer bp[i] to FPU as 4x16-bit values + extrdi $t0,$t3,16,48 + extrdi $t1,$t3,16,32 + extrdi $t2,$t3,16,16 + extrdi $t3,$t3,16,0 + std $t0,`$FRAME+0`($sp) + std $t1,`$FRAME+8`($sp) + std $t2,`$FRAME+16`($sp) + std $t3,`$FRAME+24`($sp) + ; transfer (ap[0]*bp[i]+tp[0])*n0 to FPU as 4x16-bit values + extrdi $t4,$t7,16,48 + extrdi $t5,$t7,16,32 + extrdi $t6,$t7,16,16 + extrdi $t7,$t7,16,0 + std $t4,`$FRAME+32`($sp) + std $t5,`$FRAME+40`($sp) + std $t6,`$FRAME+48`($sp) + std $t7,`$FRAME+56`($sp) + + lfd $A0,8($nap_d) ; load a[j] in double format + lfd $A1,16($nap_d) + lfd $A2,24($nap_d) ; load a[j+1] in double format + lfd $A3,32($nap_d) + lfd $N0,40($nap_d) ; load n[j] in double format + lfd $N1,48($nap_d) + lfd $N2,56($nap_d) ; load n[j+1] in double format + lfdu $N3,64($nap_d) + + lfd $ba,`$FRAME+0`($sp) + lfd $bb,`$FRAME+8`($sp) + lfd $bc,`$FRAME+16`($sp) + lfd $bd,`$FRAME+24`($sp) + lfd $na,`$FRAME+32`($sp) + lfd $nb,`$FRAME+40`($sp) + lfd $nc,`$FRAME+48`($sp) + lfd $nd,`$FRAME+56`($sp) + + fcfid $ba,$ba + fcfid $bb,$bb + fcfid $bc,$bc + fcfid $bd,$bd + fcfid $na,$na + fcfid $nb,$nb + fcfid $nc,$nc + fcfid $nd,$nd + + fmul $T1a,$A1,$ba + fmul $T1b,$A1,$bb + fmul $T2a,$A2,$ba + fmul $T2b,$A2,$bb + fmul $T3a,$A3,$ba + fmul $T3b,$A3,$bb + fmul $T0a,$A0,$ba + fmul $T0b,$A0,$bb + + fmadd $T1a,$A0,$bc,$T1a + fmadd $T1b,$A0,$bd,$T1b + fmadd $T2a,$A1,$bc,$T2a + fmadd $T2b,$A1,$bd,$T2b + fmadd $T3a,$A2,$bc,$T3a + fmadd $T3b,$A2,$bd,$T3b + fmul $dota,$A3,$bc + fmul $dotb,$A3,$bd + + fmadd $T1a,$N1,$na,$T1a + fmadd $T1b,$N1,$nb,$T1b + lfd $A0,8($nap_d) ; load a[j] in double format + lfd $A1,16($nap_d) + fmadd $T2a,$N2,$na,$T2a + fmadd $T2b,$N2,$nb,$T2b + lfd $A2,24($nap_d) ; load a[j+1] in double format + lfd $A3,32($nap_d) + fmadd $T3a,$N3,$na,$T3a + fmadd $T3b,$N3,$nb,$T3b + fmadd $T0a,$N0,$na,$T0a + fmadd $T0b,$N0,$nb,$T0b + + fmadd $T1a,$N0,$nc,$T1a + fmadd $T1b,$N0,$nd,$T1b + fmadd $T2a,$N1,$nc,$T2a + fmadd $T2b,$N1,$nd,$T2b + fmadd $T3a,$N2,$nc,$T3a + fmadd $T3b,$N2,$nd,$T3b + fmadd $dota,$N3,$nc,$dota + fmadd $dotb,$N3,$nd,$dotb + + fctid $T0a,$T0a + fctid $T0b,$T0b + fctid $T1a,$T1a + fctid $T1b,$T1b + fctid $T2a,$T2a + fctid $T2b,$T2b + fctid $T3a,$T3a + fctid $T3b,$T3b + + stfd $T0a,`$FRAME+0`($sp) + stfd $T0b,`$FRAME+8`($sp) + stfd $T1a,`$FRAME+16`($sp) + stfd $T1b,`$FRAME+24`($sp) + stfd $T2a,`$FRAME+32`($sp) + stfd $T2b,`$FRAME+40`($sp) + stfd $T3a,`$FRAME+48`($sp) + stfd $T3b,`$FRAME+56`($sp) + +.align 5 +Linner: + fmul $T1a,$A1,$ba + fmul $T1b,$A1,$bb + fmul $T2a,$A2,$ba + fmul $T2b,$A2,$bb + lfd $N0,40($nap_d) ; load n[j] in double format + lfd $N1,48($nap_d) + fmul $T3a,$A3,$ba + fmul $T3b,$A3,$bb + fmadd $T0a,$A0,$ba,$dota + fmadd $T0b,$A0,$bb,$dotb + lfd $N2,56($nap_d) ; load n[j+1] in double format + lfdu $N3,64($nap_d) + + fmadd $T1a,$A0,$bc,$T1a + fmadd $T1b,$A0,$bd,$T1b + fmadd $T2a,$A1,$bc,$T2a + fmadd $T2b,$A1,$bd,$T2b + lfd $A0,8($nap_d) ; load a[j] in double format + lfd $A1,16($nap_d) + fmadd $T3a,$A2,$bc,$T3a + fmadd $T3b,$A2,$bd,$T3b + fmul $dota,$A3,$bc + fmul $dotb,$A3,$bd + lfd $A2,24($nap_d) ; load a[j+1] in double format + lfd $A3,32($nap_d) + + fmadd $T1a,$N1,$na,$T1a + fmadd $T1b,$N1,$nb,$T1b + ld $t0,`$FRAME+0`($sp) + ld $t1,`$FRAME+8`($sp) + fmadd $T2a,$N2,$na,$T2a + fmadd $T2b,$N2,$nb,$T2b + ld $t2,`$FRAME+16`($sp) + ld $t3,`$FRAME+24`($sp) + fmadd $T3a,$N3,$na,$T3a + fmadd $T3b,$N3,$nb,$T3b + add $t0,$t0,$carry ; can not overflow + ld $t4,`$FRAME+32`($sp) + ld $t5,`$FRAME+40`($sp) + fmadd $T0a,$N0,$na,$T0a + fmadd $T0b,$N0,$nb,$T0b + srdi $carry,$t0,16 + add $t1,$t1,$carry + srdi $carry,$t1,16 + ld $t6,`$FRAME+48`($sp) + ld $t7,`$FRAME+56`($sp) + + fmadd $T1a,$N0,$nc,$T1a + fmadd $T1b,$N0,$nd,$T1b + insrdi $t0,$t1,16,32 + ld $t1,8($tp) ; tp[j] + fmadd $T2a,$N1,$nc,$T2a + fmadd $T2b,$N1,$nd,$T2b + add $t2,$t2,$carry + fmadd $T3a,$N2,$nc,$T3a + fmadd $T3b,$N2,$nd,$T3b + srdi $carry,$t2,16 + insrdi $t0,$t2,16,16 + fmadd $dota,$N3,$nc,$dota + fmadd $dotb,$N3,$nd,$dotb + add $t3,$t3,$carry + ldu $t2,16($tp) ; tp[j+1] + srdi $carry,$t3,16 + insrdi $t0,$t3,16,0 ; 0..63 bits + add $t4,$t4,$carry + + fctid $T0a,$T0a + fctid $T0b,$T0b + srdi $carry,$t4,16 + fctid $T1a,$T1a + fctid $T1b,$T1b + add $t5,$t5,$carry + fctid $T2a,$T2a + fctid $T2b,$T2b + srdi $carry,$t5,16 + insrdi $t4,$t5,16,32 + fctid $T3a,$T3a + fctid $T3b,$T3b + add $t6,$t6,$carry + srdi $carry,$t6,16 + insrdi $t4,$t6,16,16 + + stfd $T0a,`$FRAME+0`($sp) + stfd $T0b,`$FRAME+8`($sp) + add $t7,$t7,$carry + addc $t3,$t0,$t1 +___ +$code.=<<___ if ($SIZE_T==4); # adjust XER[CA] + extrdi $t0,$t0,32,0 + extrdi $t1,$t1,32,0 + adde $t0,$t0,$t1 +___ +$code.=<<___; + stfd $T1a,`$FRAME+16`($sp) + stfd $T1b,`$FRAME+24`($sp) + insrdi $t4,$t7,16,0 ; 64..127 bits + srdi $carry,$t7,16 ; upper 33 bits + stfd $T2a,`$FRAME+32`($sp) + stfd $T2b,`$FRAME+40`($sp) + adde $t5,$t4,$t2 +___ +$code.=<<___ if ($SIZE_T==4); # adjust XER[CA] + extrdi $t4,$t4,32,0 + extrdi $t2,$t2,32,0 + adde $t4,$t4,$t2 +___ +$code.=<<___; + stfd $T3a,`$FRAME+48`($sp) + stfd $T3b,`$FRAME+56`($sp) + addze $carry,$carry + std $t3,-16($tp) ; tp[j-1] + std $t5,-8($tp) ; tp[j] + bdnz- Linner + + fctid $dota,$dota + fctid $dotb,$dotb + ld $t0,`$FRAME+0`($sp) + ld $t1,`$FRAME+8`($sp) + ld $t2,`$FRAME+16`($sp) + ld $t3,`$FRAME+24`($sp) + ld $t4,`$FRAME+32`($sp) + ld $t5,`$FRAME+40`($sp) + ld $t6,`$FRAME+48`($sp) + ld $t7,`$FRAME+56`($sp) + stfd $dota,`$FRAME+64`($sp) + stfd $dotb,`$FRAME+72`($sp) + + add $t0,$t0,$carry ; can not overflow + srdi $carry,$t0,16 + add $t1,$t1,$carry + srdi $carry,$t1,16 + insrdi $t0,$t1,16,32 + add $t2,$t2,$carry + ld $t1,8($tp) ; tp[j] + srdi $carry,$t2,16 + insrdi $t0,$t2,16,16 + add $t3,$t3,$carry + ldu $t2,16($tp) ; tp[j+1] + srdi $carry,$t3,16 + insrdi $t0,$t3,16,0 ; 0..63 bits + add $t4,$t4,$carry + srdi $carry,$t4,16 + add $t5,$t5,$carry + srdi $carry,$t5,16 + insrdi $t4,$t5,16,32 + add $t6,$t6,$carry + srdi $carry,$t6,16 + insrdi $t4,$t6,16,16 + add $t7,$t7,$carry + insrdi $t4,$t7,16,0 ; 64..127 bits + srdi $carry,$t7,16 ; upper 33 bits + ld $t6,`$FRAME+64`($sp) + ld $t7,`$FRAME+72`($sp) + + addc $t3,$t0,$t1 +___ +$code.=<<___ if ($SIZE_T==4); # adjust XER[CA] + extrdi $t0,$t0,32,0 + extrdi $t1,$t1,32,0 + adde $t0,$t0,$t1 +___ +$code.=<<___; + adde $t5,$t4,$t2 +___ +$code.=<<___ if ($SIZE_T==4); # adjust XER[CA] + extrdi $t4,$t4,32,0 + extrdi $t2,$t2,32,0 + adde $t4,$t4,$t2 +___ +$code.=<<___; + addze $carry,$carry + + std $t3,-16($tp) ; tp[j-1] + std $t5,-8($tp) ; tp[j] + + add $carry,$carry,$ovf ; comsume upmost overflow + add $t6,$t6,$carry ; can not overflow + srdi $carry,$t6,16 + add $t7,$t7,$carry + insrdi $t6,$t7,48,0 + srdi $ovf,$t7,48 + std $t6,0($tp) ; tp[num-1] + + slwi $t7,$num,2 + addi $i,$i,8 + subf $nap_d,$t7,$nap_d ; rewind pointer + cmpw $i,$num + blt- Louter +___ + +$code.=<<___ if ($SIZE_T==8); + subf $np,$num,$np ; rewind np + addi $j,$j,1 ; restore counter + subfc $i,$i,$i ; j=0 and "clear" XER[CA] + addi $tp,$sp,`$FRAME+$TRANSFER+8` + addi $t4,$sp,`$FRAME+$TRANSFER+16` + addi $t5,$np,8 + addi $t6,$rp,8 + mtctr $j + +.align 4 +Lsub: ldx $t0,$tp,$i + ldx $t1,$np,$i + ldx $t2,$t4,$i + ldx $t3,$t5,$i + subfe $t0,$t1,$t0 ; tp[j]-np[j] + subfe $t2,$t3,$t2 ; tp[j+1]-np[j+1] + stdx $t0,$rp,$i + stdx $t2,$t6,$i + addi $i,$i,16 + bdnz- Lsub + + li $i,0 + subfe $ovf,$i,$ovf ; handle upmost overflow bit + and $ap,$tp,$ovf + andc $np,$rp,$ovf + or $ap,$ap,$np ; ap=borrow?tp:rp + addi $t7,$ap,8 + mtctr $j + +.align 4 +Lcopy: ; copy or in-place refresh + ldx $t0,$ap,$i + ldx $t1,$t7,$i + std $i,8($nap_d) ; zap nap_d + std $i,16($nap_d) + std $i,24($nap_d) + std $i,32($nap_d) + std $i,40($nap_d) + std $i,48($nap_d) + std $i,56($nap_d) + stdu $i,64($nap_d) + stdx $t0,$rp,$i + stdx $t1,$t6,$i + stdx $i,$tp,$i ; zap tp at once + stdx $i,$t4,$i + addi $i,$i,16 + bdnz- Lcopy +___ +$code.=<<___ if ($SIZE_T==4); + subf $np,$num,$np ; rewind np + addi $j,$j,1 ; restore counter + subfc $i,$i,$i ; j=0 and "clear" XER[CA] + addi $tp,$sp,`$FRAME+$TRANSFER` + addi $np,$np,-4 + addi $rp,$rp,-4 + addi $ap,$sp,`$FRAME+$TRANSFER+4` + mtctr $j + +.align 4 +Lsub: ld $t0,8($tp) ; load tp[j..j+3] in 64-bit word order + ldu $t2,16($tp) + lwz $t4,4($np) ; load np[j..j+3] in 32-bit word order + lwz $t5,8($np) + lwz $t6,12($np) + lwzu $t7,16($np) + extrdi $t1,$t0,32,0 + extrdi $t3,$t2,32,0 + subfe $t4,$t4,$t0 ; tp[j]-np[j] + stw $t0,4($ap) ; save tp[j..j+3] in 32-bit word order + subfe $t5,$t5,$t1 ; tp[j+1]-np[j+1] + stw $t1,8($ap) + subfe $t6,$t6,$t2 ; tp[j+2]-np[j+2] + stw $t2,12($ap) + subfe $t7,$t7,$t3 ; tp[j+3]-np[j+3] + stwu $t3,16($ap) + stw $t4,4($rp) + stw $t5,8($rp) + stw $t6,12($rp) + stwu $t7,16($rp) + bdnz- Lsub + + li $i,0 + subfe $ovf,$i,$ovf ; handle upmost overflow bit + addi $tp,$sp,`$FRAME+$TRANSFER+4` + subf $rp,$num,$rp ; rewind rp + and $ap,$tp,$ovf + andc $np,$rp,$ovf + or $ap,$ap,$np ; ap=borrow?tp:rp + addi $tp,$sp,`$FRAME+$TRANSFER` + mtctr $j + +.align 4 +Lcopy: ; copy or in-place refresh + lwz $t0,4($ap) + lwz $t1,8($ap) + lwz $t2,12($ap) + lwzu $t3,16($ap) + std $i,8($nap_d) ; zap nap_d + std $i,16($nap_d) + std $i,24($nap_d) + std $i,32($nap_d) + std $i,40($nap_d) + std $i,48($nap_d) + std $i,56($nap_d) + stdu $i,64($nap_d) + stw $t0,4($rp) + stw $t1,8($rp) + stw $t2,12($rp) + stwu $t3,16($rp) + std $i,8($tp) ; zap tp at once + stdu $i,16($tp) + bdnz- Lcopy +___ + +$code.=<<___; + $POP $i,0($sp) + li r3,1 ; signal "handled" + $POP r22,`-12*8-10*$SIZE_T`($i) + $POP r23,`-12*8-9*$SIZE_T`($i) + $POP r24,`-12*8-8*$SIZE_T`($i) + $POP r25,`-12*8-7*$SIZE_T`($i) + $POP r26,`-12*8-6*$SIZE_T`($i) + $POP r27,`-12*8-5*$SIZE_T`($i) + $POP r28,`-12*8-4*$SIZE_T`($i) + $POP r29,`-12*8-3*$SIZE_T`($i) + $POP r30,`-12*8-2*$SIZE_T`($i) + $POP r31,`-12*8-1*$SIZE_T`($i) + lfd f20,`-12*8`($i) + lfd f21,`-11*8`($i) + lfd f22,`-10*8`($i) + lfd f23,`-9*8`($i) + lfd f24,`-8*8`($i) + lfd f25,`-7*8`($i) + lfd f26,`-6*8`($i) + lfd f27,`-5*8`($i) + lfd f28,`-4*8`($i) + lfd f29,`-3*8`($i) + lfd f30,`-2*8`($i) + lfd f31,`-1*8`($i) + mr $sp,$i + blr + .long 0 + .byte 0,12,4,0,0x8c,10,6,0 + .long 0 + +.asciz "Montgomery Multiplication for PPC64, CRYPTOGAMS by " +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/s390x-gf2m.pl b/libs/openssl/crypto/bn/asm/s390x-gf2m.pl new file mode 100644 index 00000000..9d18d40e --- /dev/null +++ b/libs/openssl/crypto/bn/asm/s390x-gf2m.pl @@ -0,0 +1,221 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# May 2011 +# +# The module implements bn_GF2m_mul_2x2 polynomial multiplication used +# in bn_gf2m.c. It's kind of low-hanging mechanical port from C for +# the time being... gcc 4.3 appeared to generate poor code, therefore +# the effort. And indeed, the module delivers 55%-90%(*) improvement +# on haviest ECDSA verify and ECDH benchmarks for 163- and 571-bit +# key lengths on z990, 30%-55%(*) - on z10, and 70%-110%(*) - on z196. +# This is for 64-bit build. In 32-bit "highgprs" case improvement is +# even higher, for example on z990 it was measured 80%-150%. ECDSA +# sign is modest 9%-12% faster. Keep in mind that these coefficients +# are not ones for bn_GF2m_mul_2x2 itself, as not all CPU time is +# burnt in it... +# +# (*) gcc 4.1 was observed to deliver better results than gcc 4.3, +# so that improvement coefficients can vary from one specific +# setup to another. + +$flavour = shift; + +if ($flavour =~ /3[12]/) { + $SIZE_T=4; + $g=""; +} else { + $SIZE_T=8; + $g="g"; +} + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +$stdframe=16*$SIZE_T+4*8; + +$rp="%r2"; +$a1="%r3"; +$a0="%r4"; +$b1="%r5"; +$b0="%r6"; + +$ra="%r14"; +$sp="%r15"; + +@T=("%r0","%r1"); +@i=("%r12","%r13"); + +($a1,$a2,$a4,$a8,$a12,$a48)=map("%r$_",(6..11)); +($lo,$hi,$b)=map("%r$_",(3..5)); $a=$lo; $mask=$a8; + +$code.=<<___; +.text + +.type _mul_1x1,\@function +.align 16 +_mul_1x1: + lgr $a1,$a + sllg $a2,$a,1 + sllg $a4,$a,2 + sllg $a8,$a,3 + + srag $lo,$a1,63 # broadcast 63rd bit + nihh $a1,0x1fff + srag @i[0],$a2,63 # broadcast 62nd bit + nihh $a2,0x3fff + srag @i[1],$a4,63 # broadcast 61st bit + nihh $a4,0x7fff + ngr $lo,$b + ngr @i[0],$b + ngr @i[1],$b + + lghi @T[0],0 + lgr $a12,$a1 + stg @T[0],`$stdframe+0*8`($sp) # tab[0]=0 + xgr $a12,$a2 + stg $a1,`$stdframe+1*8`($sp) # tab[1]=a1 + lgr $a48,$a4 + stg $a2,`$stdframe+2*8`($sp) # tab[2]=a2 + xgr $a48,$a8 + stg $a12,`$stdframe+3*8`($sp) # tab[3]=a1^a2 + xgr $a1,$a4 + + stg $a4,`$stdframe+4*8`($sp) # tab[4]=a4 + xgr $a2,$a4 + stg $a1,`$stdframe+5*8`($sp) # tab[5]=a1^a4 + xgr $a12,$a4 + stg $a2,`$stdframe+6*8`($sp) # tab[6]=a2^a4 + xgr $a1,$a48 + stg $a12,`$stdframe+7*8`($sp) # tab[7]=a1^a2^a4 + xgr $a2,$a48 + + stg $a8,`$stdframe+8*8`($sp) # tab[8]=a8 + xgr $a12,$a48 + stg $a1,`$stdframe+9*8`($sp) # tab[9]=a1^a8 + xgr $a1,$a4 + stg $a2,`$stdframe+10*8`($sp) # tab[10]=a2^a8 + xgr $a2,$a4 + stg $a12,`$stdframe+11*8`($sp) # tab[11]=a1^a2^a8 + + xgr $a12,$a4 + stg $a48,`$stdframe+12*8`($sp) # tab[12]=a4^a8 + srlg $hi,$lo,1 + stg $a1,`$stdframe+13*8`($sp) # tab[13]=a1^a4^a8 + sllg $lo,$lo,63 + stg $a2,`$stdframe+14*8`($sp) # tab[14]=a2^a4^a8 + srlg @T[0],@i[0],2 + stg $a12,`$stdframe+15*8`($sp) # tab[15]=a1^a2^a4^a8 + + lghi $mask,`0xf<<3` + sllg $a1,@i[0],62 + sllg @i[0],$b,3 + srlg @T[1],@i[1],3 + ngr @i[0],$mask + sllg $a2,@i[1],61 + srlg @i[1],$b,4-3 + xgr $hi,@T[0] + ngr @i[1],$mask + xgr $lo,$a1 + xgr $hi,@T[1] + xgr $lo,$a2 + + xg $lo,$stdframe(@i[0],$sp) + srlg @i[0],$b,8-3 + ngr @i[0],$mask +___ +for($n=1;$n<14;$n++) { +$code.=<<___; + lg @T[1],$stdframe(@i[1],$sp) + srlg @i[1],$b,`($n+2)*4`-3 + sllg @T[0],@T[1],`$n*4` + ngr @i[1],$mask + srlg @T[1],@T[1],`64-$n*4` + xgr $lo,@T[0] + xgr $hi,@T[1] +___ + push(@i,shift(@i)); push(@T,shift(@T)); +} +$code.=<<___; + lg @T[1],$stdframe(@i[1],$sp) + sllg @T[0],@T[1],`$n*4` + srlg @T[1],@T[1],`64-$n*4` + xgr $lo,@T[0] + xgr $hi,@T[1] + + lg @T[0],$stdframe(@i[0],$sp) + sllg @T[1],@T[0],`($n+1)*4` + srlg @T[0],@T[0],`64-($n+1)*4` + xgr $lo,@T[1] + xgr $hi,@T[0] + + br $ra +.size _mul_1x1,.-_mul_1x1 + +.globl bn_GF2m_mul_2x2 +.type bn_GF2m_mul_2x2,\@function +.align 16 +bn_GF2m_mul_2x2: + stm${g} %r3,%r15,3*$SIZE_T($sp) + + lghi %r1,-$stdframe-128 + la %r0,0($sp) + la $sp,0(%r1,$sp) # alloca + st${g} %r0,0($sp) # back chain +___ +if ($SIZE_T==8) { +my @r=map("%r$_",(6..9)); +$code.=<<___; + bras $ra,_mul_1x1 # a1·b1 + stmg $lo,$hi,16($rp) + + lg $a,`$stdframe+128+4*$SIZE_T`($sp) + lg $b,`$stdframe+128+6*$SIZE_T`($sp) + bras $ra,_mul_1x1 # a0·b0 + stmg $lo,$hi,0($rp) + + lg $a,`$stdframe+128+3*$SIZE_T`($sp) + lg $b,`$stdframe+128+5*$SIZE_T`($sp) + xg $a,`$stdframe+128+4*$SIZE_T`($sp) + xg $b,`$stdframe+128+6*$SIZE_T`($sp) + bras $ra,_mul_1x1 # (a0+a1)·(b0+b1) + lmg @r[0],@r[3],0($rp) + + xgr $lo,$hi + xgr $hi,@r[1] + xgr $lo,@r[0] + xgr $hi,@r[2] + xgr $lo,@r[3] + xgr $hi,@r[3] + xgr $lo,$hi + stg $hi,16($rp) + stg $lo,8($rp) +___ +} else { +$code.=<<___; + sllg %r3,%r3,32 + sllg %r5,%r5,32 + or %r3,%r4 + or %r5,%r6 + bras $ra,_mul_1x1 + rllg $lo,$lo,32 + rllg $hi,$hi,32 + stmg $lo,$hi,0($rp) +___ +} +$code.=<<___; + lm${g} %r6,%r15,`$stdframe+128+6*$SIZE_T`($sp) + br $ra +.size bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2 +.string "GF(2^m) Multiplication for s390x, CRYPTOGAMS by " +___ + +$code =~ s/\`([^\`]*)\`/eval($1)/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/s390x-mont.pl b/libs/openssl/crypto/bn/asm/s390x-mont.pl new file mode 100644 index 00000000..9fd64e81 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/s390x-mont.pl @@ -0,0 +1,277 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# April 2007. +# +# Performance improvement over vanilla C code varies from 85% to 45% +# depending on key length and benchmark. Unfortunately in this context +# these are not very impressive results [for code that utilizes "wide" +# 64x64=128-bit multiplication, which is not commonly available to C +# programmers], at least hand-coded bn_asm.c replacement is known to +# provide 30-40% better results for longest keys. Well, on a second +# thought it's not very surprising, because z-CPUs are single-issue +# and _strictly_ in-order execution, while bn_mul_mont is more or less +# dependent on CPU ability to pipe-line instructions and have several +# of them "in-flight" at the same time. I mean while other methods, +# for example Karatsuba, aim to minimize amount of multiplications at +# the cost of other operations increase, bn_mul_mont aim to neatly +# "overlap" multiplications and the other operations [and on most +# platforms even minimize the amount of the other operations, in +# particular references to memory]. But it's possible to improve this +# module performance by implementing dedicated squaring code-path and +# possibly by unrolling loops... + +# January 2009. +# +# Reschedule to minimize/avoid Address Generation Interlock hazard, +# make inner loops counter-based. + +# November 2010. +# +# Adapt for -m31 build. If kernel supports what's called "highgprs" +# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit +# instructions and achieve "64-bit" performance even in 31-bit legacy +# application context. The feature is not specific to any particular +# processor, as long as it's "z-CPU". Latter implies that the code +# remains z/Architecture specific. Compatibility with 32-bit BN_ULONG +# is achieved by swapping words after 64-bit loads, follow _dswap-s. +# On z990 it was measured to perform 2.6-2.2 times better than +# compiler-generated code, less for longer keys... + +$flavour = shift; + +if ($flavour =~ /3[12]/) { + $SIZE_T=4; + $g=""; +} else { + $SIZE_T=8; + $g="g"; +} + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +$stdframe=16*$SIZE_T+4*8; + +$mn0="%r0"; +$num="%r1"; + +# int bn_mul_mont( +$rp="%r2"; # BN_ULONG *rp, +$ap="%r3"; # const BN_ULONG *ap, +$bp="%r4"; # const BN_ULONG *bp, +$np="%r5"; # const BN_ULONG *np, +$n0="%r6"; # const BN_ULONG *n0, +#$num="160(%r15)" # int num); + +$bi="%r2"; # zaps rp +$j="%r7"; + +$ahi="%r8"; +$alo="%r9"; +$nhi="%r10"; +$nlo="%r11"; +$AHI="%r12"; +$NHI="%r13"; +$count="%r14"; +$sp="%r15"; + +$code.=<<___; +.text +.globl bn_mul_mont +.type bn_mul_mont,\@function +bn_mul_mont: + lgf $num,`$stdframe+$SIZE_T-4`($sp) # pull $num + sla $num,`log($SIZE_T)/log(2)` # $num to enumerate bytes + la $bp,0($num,$bp) + + st${g} %r2,2*$SIZE_T($sp) + + cghi $num,16 # + lghi %r2,0 # + blr %r14 # if($num<16) return 0; +___ +$code.=<<___ if ($flavour =~ /3[12]/); + tmll $num,4 + bnzr %r14 # if ($num&1) return 0; +___ +$code.=<<___ if ($flavour !~ /3[12]/); + cghi $num,96 # + bhr %r14 # if($num>96) return 0; +___ +$code.=<<___; + stm${g} %r3,%r15,3*$SIZE_T($sp) + + lghi $rp,-$stdframe-8 # leave room for carry bit + lcgr $j,$num # -$num + lgr %r0,$sp + la $rp,0($rp,$sp) + la $sp,0($j,$rp) # alloca + st${g} %r0,0($sp) # back chain + + sra $num,3 # restore $num + la $bp,0($j,$bp) # restore $bp + ahi $num,-1 # adjust $num for inner loop + lg $n0,0($n0) # pull n0 + _dswap $n0 + + lg $bi,0($bp) + _dswap $bi + lg $alo,0($ap) + _dswap $alo + mlgr $ahi,$bi # ap[0]*bp[0] + lgr $AHI,$ahi + + lgr $mn0,$alo # "tp[0]"*n0 + msgr $mn0,$n0 + + lg $nlo,0($np) # + _dswap $nlo + mlgr $nhi,$mn0 # np[0]*m1 + algr $nlo,$alo # +="tp[0]" + lghi $NHI,0 + alcgr $NHI,$nhi + + la $j,8(%r0) # j=1 + lr $count,$num + +.align 16 +.L1st: + lg $alo,0($j,$ap) + _dswap $alo + mlgr $ahi,$bi # ap[j]*bp[0] + algr $alo,$AHI + lghi $AHI,0 + alcgr $AHI,$ahi + + lg $nlo,0($j,$np) + _dswap $nlo + mlgr $nhi,$mn0 # np[j]*m1 + algr $nlo,$NHI + lghi $NHI,0 + alcgr $nhi,$NHI # +="tp[j]" + algr $nlo,$alo + alcgr $NHI,$nhi + + stg $nlo,$stdframe-8($j,$sp) # tp[j-1]= + la $j,8($j) # j++ + brct $count,.L1st + + algr $NHI,$AHI + lghi $AHI,0 + alcgr $AHI,$AHI # upmost overflow bit + stg $NHI,$stdframe-8($j,$sp) + stg $AHI,$stdframe($j,$sp) + la $bp,8($bp) # bp++ + +.Louter: + lg $bi,0($bp) # bp[i] + _dswap $bi + lg $alo,0($ap) + _dswap $alo + mlgr $ahi,$bi # ap[0]*bp[i] + alg $alo,$stdframe($sp) # +=tp[0] + lghi $AHI,0 + alcgr $AHI,$ahi + + lgr $mn0,$alo + msgr $mn0,$n0 # tp[0]*n0 + + lg $nlo,0($np) # np[0] + _dswap $nlo + mlgr $nhi,$mn0 # np[0]*m1 + algr $nlo,$alo # +="tp[0]" + lghi $NHI,0 + alcgr $NHI,$nhi + + la $j,8(%r0) # j=1 + lr $count,$num + +.align 16 +.Linner: + lg $alo,0($j,$ap) + _dswap $alo + mlgr $ahi,$bi # ap[j]*bp[i] + algr $alo,$AHI + lghi $AHI,0 + alcgr $ahi,$AHI + alg $alo,$stdframe($j,$sp)# +=tp[j] + alcgr $AHI,$ahi + + lg $nlo,0($j,$np) + _dswap $nlo + mlgr $nhi,$mn0 # np[j]*m1 + algr $nlo,$NHI + lghi $NHI,0 + alcgr $nhi,$NHI + algr $nlo,$alo # +="tp[j]" + alcgr $NHI,$nhi + + stg $nlo,$stdframe-8($j,$sp) # tp[j-1]= + la $j,8($j) # j++ + brct $count,.Linner + + algr $NHI,$AHI + lghi $AHI,0 + alcgr $AHI,$AHI + alg $NHI,$stdframe($j,$sp)# accumulate previous upmost overflow bit + lghi $ahi,0 + alcgr $AHI,$ahi # new upmost overflow bit + stg $NHI,$stdframe-8($j,$sp) + stg $AHI,$stdframe($j,$sp) + + la $bp,8($bp) # bp++ + cl${g} $bp,`$stdframe+8+4*$SIZE_T`($j,$sp) # compare to &bp[num] + jne .Louter + + l${g} $rp,`$stdframe+8+2*$SIZE_T`($j,$sp) # reincarnate rp + la $ap,$stdframe($sp) + ahi $num,1 # restore $num, incidentally clears "borrow" + + la $j,0(%r0) + lr $count,$num +.Lsub: lg $alo,0($j,$ap) + lg $nlo,0($j,$np) + _dswap $nlo + slbgr $alo,$nlo + stg $alo,0($j,$rp) + la $j,8($j) + brct $count,.Lsub + lghi $ahi,0 + slbgr $AHI,$ahi # handle upmost carry + + ngr $ap,$AHI + lghi $np,-1 + xgr $np,$AHI + ngr $np,$rp + ogr $ap,$np # ap=borrow?tp:rp + + la $j,0(%r0) + lgr $count,$num +.Lcopy: lg $alo,0($j,$ap) # copy or in-place refresh + _dswap $alo + stg $j,$stdframe($j,$sp) # zap tp + stg $alo,0($j,$rp) + la $j,8($j) + brct $count,.Lcopy + + la %r1,`$stdframe+8+6*$SIZE_T`($j,$sp) + lm${g} %r6,%r15,0(%r1) + lghi %r2,1 # signal "processed" + br %r14 +.size bn_mul_mont,.-bn_mul_mont +.string "Montgomery Multiplication for s390x, CRYPTOGAMS by " +___ + +foreach (split("\n",$code)) { + s/\`([^\`]*)\`/eval $1/ge; + s/_dswap\s+(%r[0-9]+)/sprintf("rllg\t%s,%s,32",$1,$1) if($SIZE_T==4)/e; + print $_,"\n"; +} +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/s390x.S b/libs/openssl/crypto/bn/asm/s390x.S new file mode 100755 index 00000000..43fcb79b --- /dev/null +++ b/libs/openssl/crypto/bn/asm/s390x.S @@ -0,0 +1,678 @@ +.ident "s390x.S, version 1.1" +// ==================================================================== +// Written by Andy Polyakov for the OpenSSL +// project. +// +// Rights for redistribution and usage in source and binary forms are +// granted according to the OpenSSL license. Warranty of any kind is +// disclaimed. +// ==================================================================== + +.text + +#define zero %r0 + +// BN_ULONG bn_mul_add_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5); +.globl bn_mul_add_words +.type bn_mul_add_words,@function +.align 4 +bn_mul_add_words: + lghi zero,0 // zero = 0 + la %r1,0(%r2) // put rp aside + lghi %r2,0 // i=0; + ltgfr %r4,%r4 + bler %r14 // if (len<=0) return 0; + + stmg %r6,%r10,48(%r15) + lghi %r10,3 + lghi %r8,0 // carry = 0 + nr %r10,%r4 // len%4 + sra %r4,2 // cnt=len/4 + jz .Loop1_madd // carry is incidentally cleared if branch taken + algr zero,zero // clear carry + +.Loop4_madd: + lg %r7,0(%r2,%r3) // ap[i] + mlgr %r6,%r5 // *=w + alcgr %r7,%r8 // +=carry + alcgr %r6,zero + alg %r7,0(%r2,%r1) // +=rp[i] + stg %r7,0(%r2,%r1) // rp[i]= + + lg %r9,8(%r2,%r3) + mlgr %r8,%r5 + alcgr %r9,%r6 + alcgr %r8,zero + alg %r9,8(%r2,%r1) + stg %r9,8(%r2,%r1) + + lg %r7,16(%r2,%r3) + mlgr %r6,%r5 + alcgr %r7,%r8 + alcgr %r6,zero + alg %r7,16(%r2,%r1) + stg %r7,16(%r2,%r1) + + lg %r9,24(%r2,%r3) + mlgr %r8,%r5 + alcgr %r9,%r6 + alcgr %r8,zero + alg %r9,24(%r2,%r1) + stg %r9,24(%r2,%r1) + + la %r2,32(%r2) // i+=4 + brct %r4,.Loop4_madd + + la %r10,1(%r10) // see if len%4 is zero ... + brct %r10,.Loop1_madd // without touching condition code:-) + +.Lend_madd: + alcgr %r8,zero // collect carry bit + lgr %r2,%r8 + lmg %r6,%r10,48(%r15) + br %r14 + +.Loop1_madd: + lg %r7,0(%r2,%r3) // ap[i] + mlgr %r6,%r5 // *=w + alcgr %r7,%r8 // +=carry + alcgr %r6,zero + alg %r7,0(%r2,%r1) // +=rp[i] + stg %r7,0(%r2,%r1) // rp[i]= + + lgr %r8,%r6 + la %r2,8(%r2) // i++ + brct %r10,.Loop1_madd + + j .Lend_madd +.size bn_mul_add_words,.-bn_mul_add_words + +// BN_ULONG bn_mul_words(BN_ULONG *r2,BN_ULONG *r3,int r4,BN_ULONG r5); +.globl bn_mul_words +.type bn_mul_words,@function +.align 4 +bn_mul_words: + lghi zero,0 // zero = 0 + la %r1,0(%r2) // put rp aside + lghi %r2,0 // i=0; + ltgfr %r4,%r4 + bler %r14 // if (len<=0) return 0; + + stmg %r6,%r10,48(%r15) + lghi %r10,3 + lghi %r8,0 // carry = 0 + nr %r10,%r4 // len%4 + sra %r4,2 // cnt=len/4 + jz .Loop1_mul // carry is incidentally cleared if branch taken + algr zero,zero // clear carry + +.Loop4_mul: + lg %r7,0(%r2,%r3) // ap[i] + mlgr %r6,%r5 // *=w + alcgr %r7,%r8 // +=carry + stg %r7,0(%r2,%r1) // rp[i]= + + lg %r9,8(%r2,%r3) + mlgr %r8,%r5 + alcgr %r9,%r6 + stg %r9,8(%r2,%r1) + + lg %r7,16(%r2,%r3) + mlgr %r6,%r5 + alcgr %r7,%r8 + stg %r7,16(%r2,%r1) + + lg %r9,24(%r2,%r3) + mlgr %r8,%r5 + alcgr %r9,%r6 + stg %r9,24(%r2,%r1) + + la %r2,32(%r2) // i+=4 + brct %r4,.Loop4_mul + + la %r10,1(%r10) // see if len%4 is zero ... + brct %r10,.Loop1_mul // without touching condition code:-) + +.Lend_mul: + alcgr %r8,zero // collect carry bit + lgr %r2,%r8 + lmg %r6,%r10,48(%r15) + br %r14 + +.Loop1_mul: + lg %r7,0(%r2,%r3) // ap[i] + mlgr %r6,%r5 // *=w + alcgr %r7,%r8 // +=carry + stg %r7,0(%r2,%r1) // rp[i]= + + lgr %r8,%r6 + la %r2,8(%r2) // i++ + brct %r10,.Loop1_mul + + j .Lend_mul +.size bn_mul_words,.-bn_mul_words + +// void bn_sqr_words(BN_ULONG *r2,BN_ULONG *r2,int r4) +.globl bn_sqr_words +.type bn_sqr_words,@function +.align 4 +bn_sqr_words: + ltgfr %r4,%r4 + bler %r14 + + stmg %r6,%r7,48(%r15) + srag %r1,%r4,2 // cnt=len/4 + jz .Loop1_sqr + +.Loop4_sqr: + lg %r7,0(%r3) + mlgr %r6,%r7 + stg %r7,0(%r2) + stg %r6,8(%r2) + + lg %r7,8(%r3) + mlgr %r6,%r7 + stg %r7,16(%r2) + stg %r6,24(%r2) + + lg %r7,16(%r3) + mlgr %r6,%r7 + stg %r7,32(%r2) + stg %r6,40(%r2) + + lg %r7,24(%r3) + mlgr %r6,%r7 + stg %r7,48(%r2) + stg %r6,56(%r2) + + la %r3,32(%r3) + la %r2,64(%r2) + brct %r1,.Loop4_sqr + + lghi %r1,3 + nr %r4,%r1 // cnt=len%4 + jz .Lend_sqr + +.Loop1_sqr: + lg %r7,0(%r3) + mlgr %r6,%r7 + stg %r7,0(%r2) + stg %r6,8(%r2) + + la %r3,8(%r3) + la %r2,16(%r2) + brct %r4,.Loop1_sqr + +.Lend_sqr: + lmg %r6,%r7,48(%r15) + br %r14 +.size bn_sqr_words,.-bn_sqr_words + +// BN_ULONG bn_div_words(BN_ULONG h,BN_ULONG l,BN_ULONG d); +.globl bn_div_words +.type bn_div_words,@function +.align 4 +bn_div_words: + dlgr %r2,%r4 + lgr %r2,%r3 + br %r14 +.size bn_div_words,.-bn_div_words + +// BN_ULONG bn_add_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5); +.globl bn_add_words +.type bn_add_words,@function +.align 4 +bn_add_words: + la %r1,0(%r2) // put rp aside + lghi %r2,0 // i=0 + ltgfr %r5,%r5 + bler %r14 // if (len<=0) return 0; + + stg %r6,48(%r15) + lghi %r6,3 + nr %r6,%r5 // len%4 + sra %r5,2 // len/4, use sra because it sets condition code + jz .Loop1_add // carry is incidentally cleared if branch taken + algr %r2,%r2 // clear carry + +.Loop4_add: + lg %r0,0(%r2,%r3) + alcg %r0,0(%r2,%r4) + stg %r0,0(%r2,%r1) + lg %r0,8(%r2,%r3) + alcg %r0,8(%r2,%r4) + stg %r0,8(%r2,%r1) + lg %r0,16(%r2,%r3) + alcg %r0,16(%r2,%r4) + stg %r0,16(%r2,%r1) + lg %r0,24(%r2,%r3) + alcg %r0,24(%r2,%r4) + stg %r0,24(%r2,%r1) + + la %r2,32(%r2) // i+=4 + brct %r5,.Loop4_add + + la %r6,1(%r6) // see if len%4 is zero ... + brct %r6,.Loop1_add // without touching condition code:-) + +.Lexit_add: + lghi %r2,0 + alcgr %r2,%r2 + lg %r6,48(%r15) + br %r14 + +.Loop1_add: + lg %r0,0(%r2,%r3) + alcg %r0,0(%r2,%r4) + stg %r0,0(%r2,%r1) + + la %r2,8(%r2) // i++ + brct %r6,.Loop1_add + + j .Lexit_add +.size bn_add_words,.-bn_add_words + +// BN_ULONG bn_sub_words(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4,int r5); +.globl bn_sub_words +.type bn_sub_words,@function +.align 4 +bn_sub_words: + la %r1,0(%r2) // put rp aside + lghi %r2,0 // i=0 + ltgfr %r5,%r5 + bler %r14 // if (len<=0) return 0; + + stg %r6,48(%r15) + lghi %r6,3 + nr %r6,%r5 // len%4 + sra %r5,2 // len/4, use sra because it sets condition code + jnz .Loop4_sub // borrow is incidentally cleared if branch taken + slgr %r2,%r2 // clear borrow + +.Loop1_sub: + lg %r0,0(%r2,%r3) + slbg %r0,0(%r2,%r4) + stg %r0,0(%r2,%r1) + + la %r2,8(%r2) // i++ + brct %r6,.Loop1_sub + j .Lexit_sub + +.Loop4_sub: + lg %r0,0(%r2,%r3) + slbg %r0,0(%r2,%r4) + stg %r0,0(%r2,%r1) + lg %r0,8(%r2,%r3) + slbg %r0,8(%r2,%r4) + stg %r0,8(%r2,%r1) + lg %r0,16(%r2,%r3) + slbg %r0,16(%r2,%r4) + stg %r0,16(%r2,%r1) + lg %r0,24(%r2,%r3) + slbg %r0,24(%r2,%r4) + stg %r0,24(%r2,%r1) + + la %r2,32(%r2) // i+=4 + brct %r5,.Loop4_sub + + la %r6,1(%r6) // see if len%4 is zero ... + brct %r6,.Loop1_sub // without touching condition code:-) + +.Lexit_sub: + lghi %r2,0 + slbgr %r2,%r2 + lcgr %r2,%r2 + lg %r6,48(%r15) + br %r14 +.size bn_sub_words,.-bn_sub_words + +#define c1 %r1 +#define c2 %r5 +#define c3 %r8 + +#define mul_add_c(ai,bi,c1,c2,c3) \ + lg %r7,ai*8(%r3); \ + mlg %r6,bi*8(%r4); \ + algr c1,%r7; \ + alcgr c2,%r6; \ + alcgr c3,zero + +// void bn_mul_comba8(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4); +.globl bn_mul_comba8 +.type bn_mul_comba8,@function +.align 4 +bn_mul_comba8: + stmg %r6,%r8,48(%r15) + + lghi c1,0 + lghi c2,0 + lghi c3,0 + lghi zero,0 + + mul_add_c(0,0,c1,c2,c3); + stg c1,0*8(%r2) + lghi c1,0 + + mul_add_c(0,1,c2,c3,c1); + mul_add_c(1,0,c2,c3,c1); + stg c2,1*8(%r2) + lghi c2,0 + + mul_add_c(2,0,c3,c1,c2); + mul_add_c(1,1,c3,c1,c2); + mul_add_c(0,2,c3,c1,c2); + stg c3,2*8(%r2) + lghi c3,0 + + mul_add_c(0,3,c1,c2,c3); + mul_add_c(1,2,c1,c2,c3); + mul_add_c(2,1,c1,c2,c3); + mul_add_c(3,0,c1,c2,c3); + stg c1,3*8(%r2) + lghi c1,0 + + mul_add_c(4,0,c2,c3,c1); + mul_add_c(3,1,c2,c3,c1); + mul_add_c(2,2,c2,c3,c1); + mul_add_c(1,3,c2,c3,c1); + mul_add_c(0,4,c2,c3,c1); + stg c2,4*8(%r2) + lghi c2,0 + + mul_add_c(0,5,c3,c1,c2); + mul_add_c(1,4,c3,c1,c2); + mul_add_c(2,3,c3,c1,c2); + mul_add_c(3,2,c3,c1,c2); + mul_add_c(4,1,c3,c1,c2); + mul_add_c(5,0,c3,c1,c2); + stg c3,5*8(%r2) + lghi c3,0 + + mul_add_c(6,0,c1,c2,c3); + mul_add_c(5,1,c1,c2,c3); + mul_add_c(4,2,c1,c2,c3); + mul_add_c(3,3,c1,c2,c3); + mul_add_c(2,4,c1,c2,c3); + mul_add_c(1,5,c1,c2,c3); + mul_add_c(0,6,c1,c2,c3); + stg c1,6*8(%r2) + lghi c1,0 + + mul_add_c(0,7,c2,c3,c1); + mul_add_c(1,6,c2,c3,c1); + mul_add_c(2,5,c2,c3,c1); + mul_add_c(3,4,c2,c3,c1); + mul_add_c(4,3,c2,c3,c1); + mul_add_c(5,2,c2,c3,c1); + mul_add_c(6,1,c2,c3,c1); + mul_add_c(7,0,c2,c3,c1); + stg c2,7*8(%r2) + lghi c2,0 + + mul_add_c(7,1,c3,c1,c2); + mul_add_c(6,2,c3,c1,c2); + mul_add_c(5,3,c3,c1,c2); + mul_add_c(4,4,c3,c1,c2); + mul_add_c(3,5,c3,c1,c2); + mul_add_c(2,6,c3,c1,c2); + mul_add_c(1,7,c3,c1,c2); + stg c3,8*8(%r2) + lghi c3,0 + + mul_add_c(2,7,c1,c2,c3); + mul_add_c(3,6,c1,c2,c3); + mul_add_c(4,5,c1,c2,c3); + mul_add_c(5,4,c1,c2,c3); + mul_add_c(6,3,c1,c2,c3); + mul_add_c(7,2,c1,c2,c3); + stg c1,9*8(%r2) + lghi c1,0 + + mul_add_c(7,3,c2,c3,c1); + mul_add_c(6,4,c2,c3,c1); + mul_add_c(5,5,c2,c3,c1); + mul_add_c(4,6,c2,c3,c1); + mul_add_c(3,7,c2,c3,c1); + stg c2,10*8(%r2) + lghi c2,0 + + mul_add_c(4,7,c3,c1,c2); + mul_add_c(5,6,c3,c1,c2); + mul_add_c(6,5,c3,c1,c2); + mul_add_c(7,4,c3,c1,c2); + stg c3,11*8(%r2) + lghi c3,0 + + mul_add_c(7,5,c1,c2,c3); + mul_add_c(6,6,c1,c2,c3); + mul_add_c(5,7,c1,c2,c3); + stg c1,12*8(%r2) + lghi c1,0 + + + mul_add_c(6,7,c2,c3,c1); + mul_add_c(7,6,c2,c3,c1); + stg c2,13*8(%r2) + lghi c2,0 + + mul_add_c(7,7,c3,c1,c2); + stg c3,14*8(%r2) + stg c1,15*8(%r2) + + lmg %r6,%r8,48(%r15) + br %r14 +.size bn_mul_comba8,.-bn_mul_comba8 + +// void bn_mul_comba4(BN_ULONG *r2,BN_ULONG *r3,BN_ULONG *r4); +.globl bn_mul_comba4 +.type bn_mul_comba4,@function +.align 4 +bn_mul_comba4: + stmg %r6,%r8,48(%r15) + + lghi c1,0 + lghi c2,0 + lghi c3,0 + lghi zero,0 + + mul_add_c(0,0,c1,c2,c3); + stg c1,0*8(%r3) + lghi c1,0 + + mul_add_c(0,1,c2,c3,c1); + mul_add_c(1,0,c2,c3,c1); + stg c2,1*8(%r2) + lghi c2,0 + + mul_add_c(2,0,c3,c1,c2); + mul_add_c(1,1,c3,c1,c2); + mul_add_c(0,2,c3,c1,c2); + stg c3,2*8(%r2) + lghi c3,0 + + mul_add_c(0,3,c1,c2,c3); + mul_add_c(1,2,c1,c2,c3); + mul_add_c(2,1,c1,c2,c3); + mul_add_c(3,0,c1,c2,c3); + stg c1,3*8(%r2) + lghi c1,0 + + mul_add_c(3,1,c2,c3,c1); + mul_add_c(2,2,c2,c3,c1); + mul_add_c(1,3,c2,c3,c1); + stg c2,4*8(%r2) + lghi c2,0 + + mul_add_c(2,3,c3,c1,c2); + mul_add_c(3,2,c3,c1,c2); + stg c3,5*8(%r2) + lghi c3,0 + + mul_add_c(3,3,c1,c2,c3); + stg c1,6*8(%r2) + stg c2,7*8(%r2) + + stmg %r6,%r8,48(%r15) + br %r14 +.size bn_mul_comba4,.-bn_mul_comba4 + +#define sqr_add_c(ai,c1,c2,c3) \ + lg %r7,ai*8(%r3); \ + mlgr %r6,%r7; \ + algr c1,%r7; \ + alcgr c2,%r6; \ + alcgr c3,zero + +#define sqr_add_c2(ai,aj,c1,c2,c3) \ + lg %r7,ai*8(%r3); \ + mlg %r6,aj*8(%r3); \ + algr c1,%r7; \ + alcgr c2,%r6; \ + alcgr c3,zero; \ + algr c1,%r7; \ + alcgr c2,%r6; \ + alcgr c3,zero + +// void bn_sqr_comba8(BN_ULONG *r2,BN_ULONG *r3); +.globl bn_sqr_comba8 +.type bn_sqr_comba8,@function +.align 4 +bn_sqr_comba8: + stmg %r6,%r8,48(%r15) + + lghi c1,0 + lghi c2,0 + lghi c3,0 + lghi zero,0 + + sqr_add_c(0,c1,c2,c3); + stg c1,0*8(%r2) + lghi c1,0 + + sqr_add_c2(1,0,c2,c3,c1); + stg c2,1*8(%r2) + lghi c2,0 + + sqr_add_c(1,c3,c1,c2); + sqr_add_c2(2,0,c3,c1,c2); + stg c3,2*8(%r2) + lghi c3,0 + + sqr_add_c2(3,0,c1,c2,c3); + sqr_add_c2(2,1,c1,c2,c3); + stg c1,3*8(%r2) + lghi c1,0 + + sqr_add_c(2,c2,c3,c1); + sqr_add_c2(3,1,c2,c3,c1); + sqr_add_c2(4,0,c2,c3,c1); + stg c2,4*8(%r2) + lghi c2,0 + + sqr_add_c2(5,0,c3,c1,c2); + sqr_add_c2(4,1,c3,c1,c2); + sqr_add_c2(3,2,c3,c1,c2); + stg c3,5*8(%r2) + lghi c3,0 + + sqr_add_c(3,c1,c2,c3); + sqr_add_c2(4,2,c1,c2,c3); + sqr_add_c2(5,1,c1,c2,c3); + sqr_add_c2(6,0,c1,c2,c3); + stg c1,6*8(%r2) + lghi c1,0 + + sqr_add_c2(7,0,c2,c3,c1); + sqr_add_c2(6,1,c2,c3,c1); + sqr_add_c2(5,2,c2,c3,c1); + sqr_add_c2(4,3,c2,c3,c1); + stg c2,7*8(%r2) + lghi c2,0 + + sqr_add_c(4,c3,c1,c2); + sqr_add_c2(5,3,c3,c1,c2); + sqr_add_c2(6,2,c3,c1,c2); + sqr_add_c2(7,1,c3,c1,c2); + stg c3,8*8(%r2) + lghi c3,0 + + sqr_add_c2(7,2,c1,c2,c3); + sqr_add_c2(6,3,c1,c2,c3); + sqr_add_c2(5,4,c1,c2,c3); + stg c1,9*8(%r2) + lghi c1,0 + + sqr_add_c(5,c2,c3,c1); + sqr_add_c2(6,4,c2,c3,c1); + sqr_add_c2(7,3,c2,c3,c1); + stg c2,10*8(%r2) + lghi c2,0 + + sqr_add_c2(7,4,c3,c1,c2); + sqr_add_c2(6,5,c3,c1,c2); + stg c3,11*8(%r2) + lghi c3,0 + + sqr_add_c(6,c1,c2,c3); + sqr_add_c2(7,5,c1,c2,c3); + stg c1,12*8(%r2) + lghi c1,0 + + sqr_add_c2(7,6,c2,c3,c1); + stg c2,13*8(%r2) + lghi c2,0 + + sqr_add_c(7,c3,c1,c2); + stg c3,14*8(%r2) + stg c1,15*8(%r2) + + lmg %r6,%r8,48(%r15) + br %r14 +.size bn_sqr_comba8,.-bn_sqr_comba8 + +// void bn_sqr_comba4(BN_ULONG *r2,BN_ULONG *r3); +.globl bn_sqr_comba4 +.type bn_sqr_comba4,@function +.align 4 +bn_sqr_comba4: + stmg %r6,%r8,48(%r15) + + lghi c1,0 + lghi c2,0 + lghi c3,0 + lghi zero,0 + + sqr_add_c(0,c1,c2,c3); + stg c1,0*8(%r2) + lghi c1,0 + + sqr_add_c2(1,0,c2,c3,c1); + stg c2,1*8(%r2) + lghi c2,0 + + sqr_add_c(1,c3,c1,c2); + sqr_add_c2(2,0,c3,c1,c2); + stg c3,2*8(%r2) + lghi c3,0 + + sqr_add_c2(3,0,c1,c2,c3); + sqr_add_c2(2,1,c1,c2,c3); + stg c1,3*8(%r2) + lghi c1,0 + + sqr_add_c(2,c2,c3,c1); + sqr_add_c2(3,1,c2,c3,c1); + stg c2,4*8(%r2) + lghi c2,0 + + sqr_add_c2(3,2,c3,c1,c2); + stg c3,5*8(%r2) + lghi c3,0 + + sqr_add_c(3,c1,c2,c3); + stg c1,6*8(%r2) + stg c2,7*8(%r2) + + lmg %r6,%r8,48(%r15) + br %r14 +.size bn_sqr_comba4,.-bn_sqr_comba4 diff --git a/libs/openssl/crypto/bn/asm/sparcv8.S b/libs/openssl/crypto/bn/asm/sparcv8.S new file mode 100644 index 00000000..88c5dc48 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/sparcv8.S @@ -0,0 +1,1458 @@ +.ident "sparcv8.s, Version 1.4" +.ident "SPARC v8 ISA artwork by Andy Polyakov " + +/* + * ==================================================================== + * Written by Andy Polyakov for the OpenSSL + * project. + * + * Rights for redistribution and usage in source and binary forms are + * granted according to the OpenSSL license. Warranty of any kind is + * disclaimed. + * ==================================================================== + */ + +/* + * This is my modest contributon to OpenSSL project (see + * http://www.openssl.org/ for more information about it) and is + * a drop-in SuperSPARC ISA replacement for crypto/bn/bn_asm.c + * module. For updates see http://fy.chalmers.se/~appro/hpe/. + * + * See bn_asm.sparc.v8plus.S for more details. + */ + +/* + * Revision history. + * + * 1.1 - new loop unrolling model(*); + * 1.2 - made gas friendly; + * 1.3 - fixed problem with /usr/ccs/lib/cpp; + * 1.4 - some retunes; + * + * (*) see bn_asm.sparc.v8plus.S for details + */ + +.section ".text",#alloc,#execinstr +.file "bn_asm.sparc.v8.S" + +.align 32 + +.global bn_mul_add_words +/* + * BN_ULONG bn_mul_add_words(rp,ap,num,w) + * BN_ULONG *rp,*ap; + * int num; + * BN_ULONG w; + */ +bn_mul_add_words: + cmp %o2,0 + bg,a .L_bn_mul_add_words_proceed + ld [%o1],%g2 + retl + clr %o0 + +.L_bn_mul_add_words_proceed: + andcc %o2,-4,%g0 + bz .L_bn_mul_add_words_tail + clr %o5 + +.L_bn_mul_add_words_loop: + ld [%o0],%o4 + ld [%o1+4],%g3 + umul %o3,%g2,%g2 + rd %y,%g1 + addcc %o4,%o5,%o4 + addx %g1,0,%g1 + addcc %o4,%g2,%o4 + st %o4,[%o0] + addx %g1,0,%o5 + + ld [%o0+4],%o4 + ld [%o1+8],%g2 + umul %o3,%g3,%g3 + dec 4,%o2 + rd %y,%g1 + addcc %o4,%o5,%o4 + addx %g1,0,%g1 + addcc %o4,%g3,%o4 + st %o4,[%o0+4] + addx %g1,0,%o5 + + ld [%o0+8],%o4 + ld [%o1+12],%g3 + umul %o3,%g2,%g2 + inc 16,%o1 + rd %y,%g1 + addcc %o4,%o5,%o4 + addx %g1,0,%g1 + addcc %o4,%g2,%o4 + st %o4,[%o0+8] + addx %g1,0,%o5 + + ld [%o0+12],%o4 + umul %o3,%g3,%g3 + inc 16,%o0 + rd %y,%g1 + addcc %o4,%o5,%o4 + addx %g1,0,%g1 + addcc %o4,%g3,%o4 + st %o4,[%o0-4] + addx %g1,0,%o5 + andcc %o2,-4,%g0 + bnz,a .L_bn_mul_add_words_loop + ld [%o1],%g2 + + tst %o2 + bnz,a .L_bn_mul_add_words_tail + ld [%o1],%g2 +.L_bn_mul_add_words_return: + retl + mov %o5,%o0 + nop + +.L_bn_mul_add_words_tail: + ld [%o0],%o4 + umul %o3,%g2,%g2 + addcc %o4,%o5,%o4 + rd %y,%g1 + addx %g1,0,%g1 + addcc %o4,%g2,%o4 + addx %g1,0,%o5 + deccc %o2 + bz .L_bn_mul_add_words_return + st %o4,[%o0] + + ld [%o1+4],%g2 + ld [%o0+4],%o4 + umul %o3,%g2,%g2 + rd %y,%g1 + addcc %o4,%o5,%o4 + addx %g1,0,%g1 + addcc %o4,%g2,%o4 + addx %g1,0,%o5 + deccc %o2 + bz .L_bn_mul_add_words_return + st %o4,[%o0+4] + + ld [%o1+8],%g2 + ld [%o0+8],%o4 + umul %o3,%g2,%g2 + rd %y,%g1 + addcc %o4,%o5,%o4 + addx %g1,0,%g1 + addcc %o4,%g2,%o4 + st %o4,[%o0+8] + retl + addx %g1,0,%o0 + +.type bn_mul_add_words,#function +.size bn_mul_add_words,(.-bn_mul_add_words) + +.align 32 + +.global bn_mul_words +/* + * BN_ULONG bn_mul_words(rp,ap,num,w) + * BN_ULONG *rp,*ap; + * int num; + * BN_ULONG w; + */ +bn_mul_words: + cmp %o2,0 + bg,a .L_bn_mul_words_proceeed + ld [%o1],%g2 + retl + clr %o0 + +.L_bn_mul_words_proceeed: + andcc %o2,-4,%g0 + bz .L_bn_mul_words_tail + clr %o5 + +.L_bn_mul_words_loop: + ld [%o1+4],%g3 + umul %o3,%g2,%g2 + addcc %g2,%o5,%g2 + rd %y,%g1 + addx %g1,0,%o5 + st %g2,[%o0] + + ld [%o1+8],%g2 + umul %o3,%g3,%g3 + addcc %g3,%o5,%g3 + rd %y,%g1 + dec 4,%o2 + addx %g1,0,%o5 + st %g3,[%o0+4] + + ld [%o1+12],%g3 + umul %o3,%g2,%g2 + addcc %g2,%o5,%g2 + rd %y,%g1 + inc 16,%o1 + st %g2,[%o0+8] + addx %g1,0,%o5 + + umul %o3,%g3,%g3 + addcc %g3,%o5,%g3 + rd %y,%g1 + inc 16,%o0 + addx %g1,0,%o5 + st %g3,[%o0-4] + andcc %o2,-4,%g0 + nop + bnz,a .L_bn_mul_words_loop + ld [%o1],%g2 + + tst %o2 + bnz,a .L_bn_mul_words_tail + ld [%o1],%g2 +.L_bn_mul_words_return: + retl + mov %o5,%o0 + nop + +.L_bn_mul_words_tail: + umul %o3,%g2,%g2 + addcc %g2,%o5,%g2 + rd %y,%g1 + addx %g1,0,%o5 + deccc %o2 + bz .L_bn_mul_words_return + st %g2,[%o0] + nop + + ld [%o1+4],%g2 + umul %o3,%g2,%g2 + addcc %g2,%o5,%g2 + rd %y,%g1 + addx %g1,0,%o5 + deccc %o2 + bz .L_bn_mul_words_return + st %g2,[%o0+4] + + ld [%o1+8],%g2 + umul %o3,%g2,%g2 + addcc %g2,%o5,%g2 + rd %y,%g1 + st %g2,[%o0+8] + retl + addx %g1,0,%o0 + +.type bn_mul_words,#function +.size bn_mul_words,(.-bn_mul_words) + +.align 32 +.global bn_sqr_words +/* + * void bn_sqr_words(r,a,n) + * BN_ULONG *r,*a; + * int n; + */ +bn_sqr_words: + cmp %o2,0 + bg,a .L_bn_sqr_words_proceeed + ld [%o1],%g2 + retl + clr %o0 + +.L_bn_sqr_words_proceeed: + andcc %o2,-4,%g0 + bz .L_bn_sqr_words_tail + clr %o5 + +.L_bn_sqr_words_loop: + ld [%o1+4],%g3 + umul %g2,%g2,%o4 + st %o4,[%o0] + rd %y,%o5 + st %o5,[%o0+4] + + ld [%o1+8],%g2 + umul %g3,%g3,%o4 + dec 4,%o2 + st %o4,[%o0+8] + rd %y,%o5 + st %o5,[%o0+12] + nop + + ld [%o1+12],%g3 + umul %g2,%g2,%o4 + st %o4,[%o0+16] + rd %y,%o5 + inc 16,%o1 + st %o5,[%o0+20] + + umul %g3,%g3,%o4 + inc 32,%o0 + st %o4,[%o0-8] + rd %y,%o5 + st %o5,[%o0-4] + andcc %o2,-4,%g2 + bnz,a .L_bn_sqr_words_loop + ld [%o1],%g2 + + tst %o2 + nop + bnz,a .L_bn_sqr_words_tail + ld [%o1],%g2 +.L_bn_sqr_words_return: + retl + clr %o0 + +.L_bn_sqr_words_tail: + umul %g2,%g2,%o4 + st %o4,[%o0] + deccc %o2 + rd %y,%o5 + bz .L_bn_sqr_words_return + st %o5,[%o0+4] + + ld [%o1+4],%g2 + umul %g2,%g2,%o4 + st %o4,[%o0+8] + deccc %o2 + rd %y,%o5 + nop + bz .L_bn_sqr_words_return + st %o5,[%o0+12] + + ld [%o1+8],%g2 + umul %g2,%g2,%o4 + st %o4,[%o0+16] + rd %y,%o5 + st %o5,[%o0+20] + retl + clr %o0 + +.type bn_sqr_words,#function +.size bn_sqr_words,(.-bn_sqr_words) + +.align 32 + +.global bn_div_words +/* + * BN_ULONG bn_div_words(h,l,d) + * BN_ULONG h,l,d; + */ +bn_div_words: + wr %o0,%y + udiv %o1,%o2,%o0 + retl + nop + +.type bn_div_words,#function +.size bn_div_words,(.-bn_div_words) + +.align 32 + +.global bn_add_words +/* + * BN_ULONG bn_add_words(rp,ap,bp,n) + * BN_ULONG *rp,*ap,*bp; + * int n; + */ +bn_add_words: + cmp %o3,0 + bg,a .L_bn_add_words_proceed + ld [%o1],%o4 + retl + clr %o0 + +.L_bn_add_words_proceed: + andcc %o3,-4,%g0 + bz .L_bn_add_words_tail + clr %g1 + ba .L_bn_add_words_warn_loop + addcc %g0,0,%g0 ! clear carry flag + +.L_bn_add_words_loop: + ld [%o1],%o4 +.L_bn_add_words_warn_loop: + ld [%o2],%o5 + ld [%o1+4],%g3 + ld [%o2+4],%g4 + dec 4,%o3 + addxcc %o5,%o4,%o5 + st %o5,[%o0] + + ld [%o1+8],%o4 + ld [%o2+8],%o5 + inc 16,%o1 + addxcc %g3,%g4,%g3 + st %g3,[%o0+4] + + ld [%o1-4],%g3 + ld [%o2+12],%g4 + inc 16,%o2 + addxcc %o5,%o4,%o5 + st %o5,[%o0+8] + + inc 16,%o0 + addxcc %g3,%g4,%g3 + st %g3,[%o0-4] + addx %g0,0,%g1 + andcc %o3,-4,%g0 + bnz,a .L_bn_add_words_loop + addcc %g1,-1,%g0 + + tst %o3 + bnz,a .L_bn_add_words_tail + ld [%o1],%o4 +.L_bn_add_words_return: + retl + mov %g1,%o0 + +.L_bn_add_words_tail: + addcc %g1,-1,%g0 + ld [%o2],%o5 + addxcc %o5,%o4,%o5 + addx %g0,0,%g1 + deccc %o3 + bz .L_bn_add_words_return + st %o5,[%o0] + + ld [%o1+4],%o4 + addcc %g1,-1,%g0 + ld [%o2+4],%o5 + addxcc %o5,%o4,%o5 + addx %g0,0,%g1 + deccc %o3 + bz .L_bn_add_words_return + st %o5,[%o0+4] + + ld [%o1+8],%o4 + addcc %g1,-1,%g0 + ld [%o2+8],%o5 + addxcc %o5,%o4,%o5 + st %o5,[%o0+8] + retl + addx %g0,0,%o0 + +.type bn_add_words,#function +.size bn_add_words,(.-bn_add_words) + +.align 32 + +.global bn_sub_words +/* + * BN_ULONG bn_sub_words(rp,ap,bp,n) + * BN_ULONG *rp,*ap,*bp; + * int n; + */ +bn_sub_words: + cmp %o3,0 + bg,a .L_bn_sub_words_proceed + ld [%o1],%o4 + retl + clr %o0 + +.L_bn_sub_words_proceed: + andcc %o3,-4,%g0 + bz .L_bn_sub_words_tail + clr %g1 + ba .L_bn_sub_words_warm_loop + addcc %g0,0,%g0 ! clear carry flag + +.L_bn_sub_words_loop: + ld [%o1],%o4 +.L_bn_sub_words_warm_loop: + ld [%o2],%o5 + ld [%o1+4],%g3 + ld [%o2+4],%g4 + dec 4,%o3 + subxcc %o4,%o5,%o5 + st %o5,[%o0] + + ld [%o1+8],%o4 + ld [%o2+8],%o5 + inc 16,%o1 + subxcc %g3,%g4,%g4 + st %g4,[%o0+4] + + ld [%o1-4],%g3 + ld [%o2+12],%g4 + inc 16,%o2 + subxcc %o4,%o5,%o5 + st %o5,[%o0+8] + + inc 16,%o0 + subxcc %g3,%g4,%g4 + st %g4,[%o0-4] + addx %g0,0,%g1 + andcc %o3,-4,%g0 + bnz,a .L_bn_sub_words_loop + addcc %g1,-1,%g0 + + tst %o3 + nop + bnz,a .L_bn_sub_words_tail + ld [%o1],%o4 +.L_bn_sub_words_return: + retl + mov %g1,%o0 + +.L_bn_sub_words_tail: + addcc %g1,-1,%g0 + ld [%o2],%o5 + subxcc %o4,%o5,%o5 + addx %g0,0,%g1 + deccc %o3 + bz .L_bn_sub_words_return + st %o5,[%o0] + nop + + ld [%o1+4],%o4 + addcc %g1,-1,%g0 + ld [%o2+4],%o5 + subxcc %o4,%o5,%o5 + addx %g0,0,%g1 + deccc %o3 + bz .L_bn_sub_words_return + st %o5,[%o0+4] + + ld [%o1+8],%o4 + addcc %g1,-1,%g0 + ld [%o2+8],%o5 + subxcc %o4,%o5,%o5 + st %o5,[%o0+8] + retl + addx %g0,0,%o0 + +.type bn_sub_words,#function +.size bn_sub_words,(.-bn_sub_words) + +#define FRAME_SIZE -96 + +/* + * Here is register usage map for *all* routines below. + */ +#define t_1 %o0 +#define t_2 %o1 +#define c_1 %o2 +#define c_2 %o3 +#define c_3 %o4 + +#define ap(I) [%i1+4*I] +#define bp(I) [%i2+4*I] +#define rp(I) [%i0+4*I] + +#define a_0 %l0 +#define a_1 %l1 +#define a_2 %l2 +#define a_3 %l3 +#define a_4 %l4 +#define a_5 %l5 +#define a_6 %l6 +#define a_7 %l7 + +#define b_0 %i3 +#define b_1 %i4 +#define b_2 %i5 +#define b_3 %o5 +#define b_4 %g1 +#define b_5 %g2 +#define b_6 %g3 +#define b_7 %g4 + +.align 32 +.global bn_mul_comba8 +/* + * void bn_mul_comba8(r,a,b) + * BN_ULONG *r,*a,*b; + */ +bn_mul_comba8: + save %sp,FRAME_SIZE,%sp + ld ap(0),a_0 + ld bp(0),b_0 + umul a_0,b_0,c_1 !=!mul_add_c(a[0],b[0],c1,c2,c3); + ld bp(1),b_1 + rd %y,c_2 + st c_1,rp(0) !r[0]=c1; + + umul a_0,b_1,t_1 !=!mul_add_c(a[0],b[1],c2,c3,c1); + ld ap(1),a_1 + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc %g0,t_2,c_3 != + addx %g0,%g0,c_1 + ld ap(2),a_2 + umul a_1,b_0,t_1 !mul_add_c(a[1],b[0],c2,c3,c1); + addcc c_2,t_1,c_2 != + rd %y,t_2 + addxcc c_3,t_2,c_3 + st c_2,rp(1) !r[1]=c2; + addx c_1,%g0,c_1 != + + umul a_2,b_0,t_1 !mul_add_c(a[2],b[0],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 != + addx %g0,%g0,c_2 + ld bp(2),b_2 + umul a_1,b_1,t_1 !mul_add_c(a[1],b[1],c3,c1,c2); + addcc c_3,t_1,c_3 != + rd %y,t_2 + addxcc c_1,t_2,c_1 + ld bp(3),b_3 + addx c_2,%g0,c_2 != + umul a_0,b_2,t_1 !mul_add_c(a[0],b[2],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 != + addx c_2,%g0,c_2 + st c_3,rp(2) !r[2]=c3; + + umul a_0,b_3,t_1 !mul_add_c(a[0],b[3],c1,c2,c3); + addcc c_1,t_1,c_1 != + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx %g0,%g0,c_3 + umul a_1,b_2,t_1 !=!mul_add_c(a[1],b[2],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 != + ld ap(3),a_3 + umul a_2,b_1,t_1 !mul_add_c(a[2],b[1],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 != + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 + ld ap(4),a_4 + umul a_3,b_0,t_1 !mul_add_c(a[3],b[0],c1,c2,c3);!= + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 != + st c_1,rp(3) !r[3]=c1; + + umul a_4,b_0,t_1 !mul_add_c(a[4],b[0],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx %g0,%g0,c_1 + umul a_3,b_1,t_1 !mul_add_c(a[3],b[1],c2,c3,c1); + addcc c_2,t_1,c_2 != + rd %y,t_2 + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + umul a_2,b_2,t_1 !=!mul_add_c(a[2],b[2],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 != + ld bp(4),b_4 + umul a_1,b_3,t_1 !mul_add_c(a[1],b[3],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + ld bp(5),b_5 + umul a_0,b_4,t_1 !=!mul_add_c(a[0],b[4],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 != + st c_2,rp(4) !r[4]=c2; + + umul a_0,b_5,t_1 !mul_add_c(a[0],b[5],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 != + addxcc c_1,t_2,c_1 + addx %g0,%g0,c_2 + umul a_1,b_4,t_1 !mul_add_c(a[1],b[4],c3,c1,c2); + addcc c_3,t_1,c_3 != + rd %y,t_2 + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 + umul a_2,b_3,t_1 !=!mul_add_c(a[2],b[3],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 != + umul a_3,b_2,t_1 !mul_add_c(a[3],b[2],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 != + addx c_2,%g0,c_2 + ld ap(5),a_5 + umul a_4,b_1,t_1 !mul_add_c(a[4],b[1],c3,c1,c2); + addcc c_3,t_1,c_3 != + rd %y,t_2 + addxcc c_1,t_2,c_1 + ld ap(6),a_6 + addx c_2,%g0,c_2 != + umul a_5,b_0,t_1 !mul_add_c(a[5],b[0],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 != + addx c_2,%g0,c_2 + st c_3,rp(5) !r[5]=c3; + + umul a_6,b_0,t_1 !mul_add_c(a[6],b[0],c1,c2,c3); + addcc c_1,t_1,c_1 != + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx %g0,%g0,c_3 + umul a_5,b_1,t_1 !=!mul_add_c(a[5],b[1],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 != + umul a_4,b_2,t_1 !mul_add_c(a[4],b[2],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + addx c_3,%g0,c_3 + umul a_3,b_3,t_1 !mul_add_c(a[3],b[3],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 != + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 + umul a_2,b_4,t_1 !mul_add_c(a[2],b[4],c1,c2,c3); + addcc c_1,t_1,c_1 != + rd %y,t_2 + addxcc c_2,t_2,c_2 + ld bp(6),b_6 + addx c_3,%g0,c_3 != + umul a_1,b_5,t_1 !mul_add_c(a[1],b[5],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + addx c_3,%g0,c_3 + ld bp(7),b_7 + umul a_0,b_6,t_1 !mul_add_c(a[0],b[6],c1,c2,c3); + addcc c_1,t_1,c_1 != + rd %y,t_2 + addxcc c_2,t_2,c_2 + st c_1,rp(6) !r[6]=c1; + addx c_3,%g0,c_3 != + + umul a_0,b_7,t_1 !mul_add_c(a[0],b[7],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc c_3,t_2,c_3 != + addx %g0,%g0,c_1 + umul a_1,b_6,t_1 !mul_add_c(a[1],b[6],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + umul a_2,b_5,t_1 !mul_add_c(a[2],b[5],c2,c3,c1); + addcc c_2,t_1,c_2 != + rd %y,t_2 + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + umul a_3,b_4,t_1 !=!mul_add_c(a[3],b[4],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 != + umul a_4,b_3,t_1 !mul_add_c(a[4],b[3],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc c_3,t_2,c_3 != + addx c_1,%g0,c_1 + umul a_5,b_2,t_1 !mul_add_c(a[5],b[2],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + ld ap(7),a_7 + umul a_6,b_1,t_1 !=!mul_add_c(a[6],b[1],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 != + umul a_7,b_0,t_1 !mul_add_c(a[7],b[0],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc c_3,t_2,c_3 != + addx c_1,%g0,c_1 + st c_2,rp(7) !r[7]=c2; + + umul a_7,b_1,t_1 !mul_add_c(a[7],b[1],c3,c1,c2); + addcc c_3,t_1,c_3 != + rd %y,t_2 + addxcc c_1,t_2,c_1 + addx %g0,%g0,c_2 + umul a_6,b_2,t_1 !=!mul_add_c(a[6],b[2],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 != + umul a_5,b_3,t_1 !mul_add_c(a[5],b[3],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 != + addx c_2,%g0,c_2 + umul a_4,b_4,t_1 !mul_add_c(a[4],b[4],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 != + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 + umul a_3,b_5,t_1 !mul_add_c(a[3],b[5],c3,c1,c2); + addcc c_3,t_1,c_3 != + rd %y,t_2 + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 + umul a_2,b_6,t_1 !=!mul_add_c(a[2],b[6],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 != + umul a_1,b_7,t_1 !mul_add_c(a[1],b[7],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 ! + addx c_2,%g0,c_2 + st c_3,rp(8) !r[8]=c3; + + umul a_2,b_7,t_1 !mul_add_c(a[2],b[7],c1,c2,c3); + addcc c_1,t_1,c_1 != + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx %g0,%g0,c_3 + umul a_3,b_6,t_1 !=!mul_add_c(a[3],b[6],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 != + umul a_4,b_5,t_1 !mul_add_c(a[4],b[5],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + addx c_3,%g0,c_3 + umul a_5,b_4,t_1 !mul_add_c(a[5],b[4],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 != + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 + umul a_6,b_3,t_1 !mul_add_c(a[6],b[3],c1,c2,c3); + addcc c_1,t_1,c_1 != + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 + umul a_7,b_2,t_1 !=!mul_add_c(a[7],b[2],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 != + st c_1,rp(9) !r[9]=c1; + + umul a_7,b_3,t_1 !mul_add_c(a[7],b[3],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx %g0,%g0,c_1 + umul a_6,b_4,t_1 !mul_add_c(a[6],b[4],c2,c3,c1); + addcc c_2,t_1,c_2 != + rd %y,t_2 + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + umul a_5,b_5,t_1 !=!mul_add_c(a[5],b[5],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 != + umul a_4,b_6,t_1 !mul_add_c(a[4],b[6],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc c_3,t_2,c_3 != + addx c_1,%g0,c_1 + umul a_3,b_7,t_1 !mul_add_c(a[3],b[7],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + st c_2,rp(10) !r[10]=c2; + + umul a_4,b_7,t_1 !=!mul_add_c(a[4],b[7],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 + addx %g0,%g0,c_2 != + umul a_5,b_6,t_1 !mul_add_c(a[5],b[6],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 != + addx c_2,%g0,c_2 + umul a_6,b_5,t_1 !mul_add_c(a[6],b[5],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 != + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 + umul a_7,b_4,t_1 !mul_add_c(a[7],b[4],c3,c1,c2); + addcc c_3,t_1,c_3 != + rd %y,t_2 + addxcc c_1,t_2,c_1 + st c_3,rp(11) !r[11]=c3; + addx c_2,%g0,c_2 != + + umul a_7,b_5,t_1 !mul_add_c(a[7],b[5],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + addx %g0,%g0,c_3 + umul a_6,b_6,t_1 !mul_add_c(a[6],b[6],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 != + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 + umul a_5,b_7,t_1 !mul_add_c(a[5],b[7],c1,c2,c3); + addcc c_1,t_1,c_1 != + rd %y,t_2 + addxcc c_2,t_2,c_2 + st c_1,rp(12) !r[12]=c1; + addx c_3,%g0,c_3 != + + umul a_6,b_7,t_1 !mul_add_c(a[6],b[7],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc c_3,t_2,c_3 != + addx %g0,%g0,c_1 + umul a_7,b_6,t_1 !mul_add_c(a[7],b[6],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + st c_2,rp(13) !r[13]=c2; + + umul a_7,b_7,t_1 !=!mul_add_c(a[7],b[7],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 + nop != + st c_3,rp(14) !r[14]=c3; + st c_1,rp(15) !r[15]=c1; + + ret + restore %g0,%g0,%o0 + +.type bn_mul_comba8,#function +.size bn_mul_comba8,(.-bn_mul_comba8) + +.align 32 + +.global bn_mul_comba4 +/* + * void bn_mul_comba4(r,a,b) + * BN_ULONG *r,*a,*b; + */ +bn_mul_comba4: + save %sp,FRAME_SIZE,%sp + ld ap(0),a_0 + ld bp(0),b_0 + umul a_0,b_0,c_1 !=!mul_add_c(a[0],b[0],c1,c2,c3); + ld bp(1),b_1 + rd %y,c_2 + st c_1,rp(0) !r[0]=c1; + + umul a_0,b_1,t_1 !=!mul_add_c(a[0],b[1],c2,c3,c1); + ld ap(1),a_1 + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc %g0,t_2,c_3 + addx %g0,%g0,c_1 + ld ap(2),a_2 + umul a_1,b_0,t_1 !=!mul_add_c(a[1],b[0],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 != + st c_2,rp(1) !r[1]=c2; + + umul a_2,b_0,t_1 !mul_add_c(a[2],b[0],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 != + addxcc c_1,t_2,c_1 + addx %g0,%g0,c_2 + ld bp(2),b_2 + umul a_1,b_1,t_1 !=!mul_add_c(a[1],b[1],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 != + ld bp(3),b_3 + umul a_0,b_2,t_1 !mul_add_c(a[0],b[2],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 != + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 + st c_3,rp(2) !r[2]=c3; + + umul a_0,b_3,t_1 !=!mul_add_c(a[0],b[3],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx %g0,%g0,c_3 != + umul a_1,b_2,t_1 !mul_add_c(a[1],b[2],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + addx c_3,%g0,c_3 + ld ap(3),a_3 + umul a_2,b_1,t_1 !mul_add_c(a[2],b[1],c1,c2,c3); + addcc c_1,t_1,c_1 != + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 + umul a_3,b_0,t_1 !=!mul_add_c(a[3],b[0],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 != + st c_1,rp(3) !r[3]=c1; + + umul a_3,b_1,t_1 !mul_add_c(a[3],b[1],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx %g0,%g0,c_1 + umul a_2,b_2,t_1 !mul_add_c(a[2],b[2],c2,c3,c1); + addcc c_2,t_1,c_2 != + rd %y,t_2 + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + umul a_1,b_3,t_1 !=!mul_add_c(a[1],b[3],c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 != + st c_2,rp(4) !r[4]=c2; + + umul a_2,b_3,t_1 !mul_add_c(a[2],b[3],c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 != + addxcc c_1,t_2,c_1 + addx %g0,%g0,c_2 + umul a_3,b_2,t_1 !mul_add_c(a[3],b[2],c3,c1,c2); + addcc c_3,t_1,c_3 != + rd %y,t_2 + addxcc c_1,t_2,c_1 + st c_3,rp(5) !r[5]=c3; + addx c_2,%g0,c_2 != + + umul a_3,b_3,t_1 !mul_add_c(a[3],b[3],c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + st c_1,rp(6) !r[6]=c1; + st c_2,rp(7) !r[7]=c2; + + ret + restore %g0,%g0,%o0 + +.type bn_mul_comba4,#function +.size bn_mul_comba4,(.-bn_mul_comba4) + +.align 32 + +.global bn_sqr_comba8 +bn_sqr_comba8: + save %sp,FRAME_SIZE,%sp + ld ap(0),a_0 + ld ap(1),a_1 + umul a_0,a_0,c_1 !=!sqr_add_c(a,0,c1,c2,c3); + rd %y,c_2 + st c_1,rp(0) !r[0]=c1; + + ld ap(2),a_2 + umul a_0,a_1,t_1 !=!sqr_add_c2(a,1,0,c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc %g0,t_2,c_3 + addx %g0,%g0,c_1 != + addcc c_2,t_1,c_2 + addxcc c_3,t_2,c_3 + st c_2,rp(1) !r[1]=c2; + addx c_1,%g0,c_1 != + + umul a_2,a_0,t_1 !sqr_add_c2(a,2,0,c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 != + addx %g0,%g0,c_2 + addcc c_3,t_1,c_3 + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 != + ld ap(3),a_3 + umul a_1,a_1,t_1 !sqr_add_c(a,1,c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 != + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 + st c_3,rp(2) !r[2]=c3; + + umul a_0,a_3,t_1 !=!sqr_add_c2(a,3,0,c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx %g0,%g0,c_3 != + addcc c_1,t_1,c_1 + addxcc c_2,t_2,c_2 + ld ap(4),a_4 + addx c_3,%g0,c_3 != + umul a_1,a_2,t_1 !sqr_add_c2(a,2,1,c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + addx c_3,%g0,c_3 + addcc c_1,t_1,c_1 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 != + st c_1,rp(3) !r[3]=c1; + + umul a_4,a_0,t_1 !sqr_add_c2(a,4,0,c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx %g0,%g0,c_1 + addcc c_2,t_1,c_2 + addxcc c_3,t_2,c_3 != + addx c_1,%g0,c_1 + umul a_3,a_1,t_1 !sqr_add_c2(a,3,1,c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + addcc c_2,t_1,c_2 + addxcc c_3,t_2,c_3 != + addx c_1,%g0,c_1 + ld ap(5),a_5 + umul a_2,a_2,t_1 !sqr_add_c(a,2,c2,c3,c1); + addcc c_2,t_1,c_2 != + rd %y,t_2 + addxcc c_3,t_2,c_3 + st c_2,rp(4) !r[4]=c2; + addx c_1,%g0,c_1 != + + umul a_0,a_5,t_1 !sqr_add_c2(a,5,0,c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 != + addx %g0,%g0,c_2 + addcc c_3,t_1,c_3 + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 != + umul a_1,a_4,t_1 !sqr_add_c2(a,4,1,c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 != + addx c_2,%g0,c_2 + addcc c_3,t_1,c_3 + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 != + ld ap(6),a_6 + umul a_2,a_3,t_1 !sqr_add_c2(a,3,2,c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 != + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 + addcc c_3,t_1,c_3 + addxcc c_1,t_2,c_1 != + addx c_2,%g0,c_2 + st c_3,rp(5) !r[5]=c3; + + umul a_6,a_0,t_1 !sqr_add_c2(a,6,0,c1,c2,c3); + addcc c_1,t_1,c_1 != + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx %g0,%g0,c_3 + addcc c_1,t_1,c_1 != + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 + umul a_5,a_1,t_1 !sqr_add_c2(a,5,1,c1,c2,c3); + addcc c_1,t_1,c_1 != + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 + addcc c_1,t_1,c_1 != + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 + umul a_4,a_2,t_1 !sqr_add_c2(a,4,2,c1,c2,c3); + addcc c_1,t_1,c_1 != + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 + addcc c_1,t_1,c_1 != + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 + ld ap(7),a_7 + umul a_3,a_3,t_1 !=!sqr_add_c(a,3,c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 != + st c_1,rp(6) !r[6]=c1; + + umul a_0,a_7,t_1 !sqr_add_c2(a,7,0,c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx %g0,%g0,c_1 + addcc c_2,t_1,c_2 + addxcc c_3,t_2,c_3 != + addx c_1,%g0,c_1 + umul a_1,a_6,t_1 !sqr_add_c2(a,6,1,c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + addcc c_2,t_1,c_2 + addxcc c_3,t_2,c_3 != + addx c_1,%g0,c_1 + umul a_2,a_5,t_1 !sqr_add_c2(a,5,2,c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + addcc c_2,t_1,c_2 + addxcc c_3,t_2,c_3 != + addx c_1,%g0,c_1 + umul a_3,a_4,t_1 !sqr_add_c2(a,4,3,c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + addcc c_2,t_1,c_2 + addxcc c_3,t_2,c_3 != + addx c_1,%g0,c_1 + st c_2,rp(7) !r[7]=c2; + + umul a_7,a_1,t_1 !sqr_add_c2(a,7,1,c3,c1,c2); + addcc c_3,t_1,c_3 != + rd %y,t_2 + addxcc c_1,t_2,c_1 + addx %g0,%g0,c_2 + addcc c_3,t_1,c_3 != + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 + umul a_6,a_2,t_1 !sqr_add_c2(a,6,2,c3,c1,c2); + addcc c_3,t_1,c_3 != + rd %y,t_2 + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 + addcc c_3,t_1,c_3 != + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 + umul a_5,a_3,t_1 !sqr_add_c2(a,5,3,c3,c1,c2); + addcc c_3,t_1,c_3 != + rd %y,t_2 + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 + addcc c_3,t_1,c_3 != + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 + umul a_4,a_4,t_1 !sqr_add_c(a,4,c3,c1,c2); + addcc c_3,t_1,c_3 != + rd %y,t_2 + addxcc c_1,t_2,c_1 + st c_3,rp(8) !r[8]=c3; + addx c_2,%g0,c_2 != + + umul a_2,a_7,t_1 !sqr_add_c2(a,7,2,c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + addx %g0,%g0,c_3 + addcc c_1,t_1,c_1 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 != + umul a_3,a_6,t_1 !sqr_add_c2(a,6,3,c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + addx c_3,%g0,c_3 + addcc c_1,t_1,c_1 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 != + umul a_4,a_5,t_1 !sqr_add_c2(a,5,4,c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + addx c_3,%g0,c_3 + addcc c_1,t_1,c_1 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 != + st c_1,rp(9) !r[9]=c1; + + umul a_7,a_3,t_1 !sqr_add_c2(a,7,3,c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx %g0,%g0,c_1 + addcc c_2,t_1,c_2 + addxcc c_3,t_2,c_3 != + addx c_1,%g0,c_1 + umul a_6,a_4,t_1 !sqr_add_c2(a,6,4,c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + addcc c_2,t_1,c_2 + addxcc c_3,t_2,c_3 != + addx c_1,%g0,c_1 + umul a_5,a_5,t_1 !sqr_add_c(a,5,c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + st c_2,rp(10) !r[10]=c2; + + umul a_4,a_7,t_1 !=!sqr_add_c2(a,7,4,c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 + addx %g0,%g0,c_2 != + addcc c_3,t_1,c_3 + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 + umul a_5,a_6,t_1 !=!sqr_add_c2(a,6,5,c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 + addx c_2,%g0,c_2 != + addcc c_3,t_1,c_3 + addxcc c_1,t_2,c_1 + st c_3,rp(11) !r[11]=c3; + addx c_2,%g0,c_2 != + + umul a_7,a_5,t_1 !sqr_add_c2(a,7,5,c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + addx %g0,%g0,c_3 + addcc c_1,t_1,c_1 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 != + umul a_6,a_6,t_1 !sqr_add_c(a,6,c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + addx c_3,%g0,c_3 + st c_1,rp(12) !r[12]=c1; + + umul a_6,a_7,t_1 !sqr_add_c2(a,7,6,c2,c3,c1); + addcc c_2,t_1,c_2 != + rd %y,t_2 + addxcc c_3,t_2,c_3 + addx %g0,%g0,c_1 + addcc c_2,t_1,c_2 != + addxcc c_3,t_2,c_3 + st c_2,rp(13) !r[13]=c2; + addx c_1,%g0,c_1 != + + umul a_7,a_7,t_1 !sqr_add_c(a,7,c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 != + st c_3,rp(14) !r[14]=c3; + st c_1,rp(15) !r[15]=c1; + + ret + restore %g0,%g0,%o0 + +.type bn_sqr_comba8,#function +.size bn_sqr_comba8,(.-bn_sqr_comba8) + +.align 32 + +.global bn_sqr_comba4 +/* + * void bn_sqr_comba4(r,a) + * BN_ULONG *r,*a; + */ +bn_sqr_comba4: + save %sp,FRAME_SIZE,%sp + ld ap(0),a_0 + umul a_0,a_0,c_1 !sqr_add_c(a,0,c1,c2,c3); + ld ap(1),a_1 != + rd %y,c_2 + st c_1,rp(0) !r[0]=c1; + + ld ap(2),a_2 + umul a_0,a_1,t_1 !=!sqr_add_c2(a,1,0,c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 + addxcc %g0,t_2,c_3 + addx %g0,%g0,c_1 != + addcc c_2,t_1,c_2 + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 != + st c_2,rp(1) !r[1]=c2; + + umul a_2,a_0,t_1 !sqr_add_c2(a,2,0,c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 != + addxcc c_1,t_2,c_1 + addx %g0,%g0,c_2 + addcc c_3,t_1,c_3 + addxcc c_1,t_2,c_1 != + addx c_2,%g0,c_2 + ld ap(3),a_3 + umul a_1,a_1,t_1 !sqr_add_c(a,1,c3,c1,c2); + addcc c_3,t_1,c_3 != + rd %y,t_2 + addxcc c_1,t_2,c_1 + st c_3,rp(2) !r[2]=c3; + addx c_2,%g0,c_2 != + + umul a_0,a_3,t_1 !sqr_add_c2(a,3,0,c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + addx %g0,%g0,c_3 + addcc c_1,t_1,c_1 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 != + umul a_1,a_2,t_1 !sqr_add_c2(a,2,1,c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + addx c_3,%g0,c_3 + addcc c_1,t_1,c_1 + addxcc c_2,t_2,c_2 + addx c_3,%g0,c_3 != + st c_1,rp(3) !r[3]=c1; + + umul a_3,a_1,t_1 !sqr_add_c2(a,3,1,c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx %g0,%g0,c_1 + addcc c_2,t_1,c_2 + addxcc c_3,t_2,c_3 != + addx c_1,%g0,c_1 + umul a_2,a_2,t_1 !sqr_add_c(a,2,c2,c3,c1); + addcc c_2,t_1,c_2 + rd %y,t_2 != + addxcc c_3,t_2,c_3 + addx c_1,%g0,c_1 + st c_2,rp(4) !r[4]=c2; + + umul a_2,a_3,t_1 !=!sqr_add_c2(a,3,2,c3,c1,c2); + addcc c_3,t_1,c_3 + rd %y,t_2 + addxcc c_1,t_2,c_1 + addx %g0,%g0,c_2 != + addcc c_3,t_1,c_3 + addxcc c_1,t_2,c_1 + st c_3,rp(5) !r[5]=c3; + addx c_2,%g0,c_2 != + + umul a_3,a_3,t_1 !sqr_add_c(a,3,c1,c2,c3); + addcc c_1,t_1,c_1 + rd %y,t_2 + addxcc c_2,t_2,c_2 != + st c_1,rp(6) !r[6]=c1; + st c_2,rp(7) !r[7]=c2; + + ret + restore %g0,%g0,%o0 + +.type bn_sqr_comba4,#function +.size bn_sqr_comba4,(.-bn_sqr_comba4) + +.align 32 diff --git a/libs/openssl/crypto/bn/asm/sparcv8plus.S b/libs/openssl/crypto/bn/asm/sparcv8plus.S new file mode 100644 index 00000000..63de1860 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/sparcv8plus.S @@ -0,0 +1,1558 @@ +.ident "sparcv8plus.s, Version 1.4" +.ident "SPARC v9 ISA artwork by Andy Polyakov " + +/* + * ==================================================================== + * Written by Andy Polyakov for the OpenSSL + * project. + * + * Rights for redistribution and usage in source and binary forms are + * granted according to the OpenSSL license. Warranty of any kind is + * disclaimed. + * ==================================================================== + */ + +/* + * This is my modest contributon to OpenSSL project (see + * http://www.openssl.org/ for more information about it) and is + * a drop-in UltraSPARC ISA replacement for crypto/bn/bn_asm.c + * module. For updates see http://fy.chalmers.se/~appro/hpe/. + * + * Questions-n-answers. + * + * Q. How to compile? + * A. With SC4.x/SC5.x: + * + * cc -xarch=v8plus -c bn_asm.sparc.v8plus.S -o bn_asm.o + * + * and with gcc: + * + * gcc -mcpu=ultrasparc -c bn_asm.sparc.v8plus.S -o bn_asm.o + * + * or if above fails (it does if you have gas installed): + * + * gcc -E bn_asm.sparc.v8plus.S | as -xarch=v8plus /dev/fd/0 -o bn_asm.o + * + * Quick-n-dirty way to fuse the module into the library. + * Provided that the library is already configured and built + * (in 0.9.2 case with no-asm option): + * + * # cd crypto/bn + * # cp /some/place/bn_asm.sparc.v8plus.S . + * # cc -xarch=v8plus -c bn_asm.sparc.v8plus.S -o bn_asm.o + * # make + * # cd ../.. + * # make; make test + * + * Quick-n-dirty way to get rid of it: + * + * # cd crypto/bn + * # touch bn_asm.c + * # make + * # cd ../.. + * # make; make test + * + * Q. V8plus achitecture? What kind of beast is that? + * A. Well, it's rather a programming model than an architecture... + * It's actually v9-compliant, i.e. *any* UltraSPARC, CPU under + * special conditions, namely when kernel doesn't preserve upper + * 32 bits of otherwise 64-bit registers during a context switch. + * + * Q. Why just UltraSPARC? What about SuperSPARC? + * A. Original release did target UltraSPARC only. Now SuperSPARC + * version is provided along. Both version share bn_*comba[48] + * implementations (see comment later in code for explanation). + * But what's so special about this UltraSPARC implementation? + * Why didn't I let compiler do the job? Trouble is that most of + * available compilers (well, SC5.0 is the only exception) don't + * attempt to take advantage of UltraSPARC's 64-bitness under + * 32-bit kernels even though it's perfectly possible (see next + * question). + * + * Q. 64-bit registers under 32-bit kernels? Didn't you just say it + * doesn't work? + * A. You can't adress *all* registers as 64-bit wide:-( The catch is + * that you actually may rely upon %o0-%o5 and %g1-%g4 being fully + * preserved if you're in a leaf function, i.e. such never calling + * any other functions. All functions in this module are leaf and + * 10 registers is a handful. And as a matter of fact none-"comba" + * routines don't require even that much and I could even afford to + * not allocate own stack frame for 'em:-) + * + * Q. What about 64-bit kernels? + * A. What about 'em? Just kidding:-) Pure 64-bit version is currently + * under evaluation and development... + * + * Q. What about shared libraries? + * A. What about 'em? Kidding again:-) Code does *not* contain any + * code position dependencies and it's safe to include it into + * shared library as is. + * + * Q. How much faster does it go? + * A. Do you have a good benchmark? In either case below is what I + * experience with crypto/bn/expspeed.c test program: + * + * v8plus module on U10/300MHz against bn_asm.c compiled with: + * + * cc-5.0 -xarch=v8plus -xO5 -xdepend +7-12% + * cc-4.2 -xarch=v8plus -xO5 -xdepend +25-35% + * egcs-1.1.2 -mcpu=ultrasparc -O3 +35-45% + * + * v8 module on SS10/60MHz against bn_asm.c compiled with: + * + * cc-5.0 -xarch=v8 -xO5 -xdepend +7-10% + * cc-4.2 -xarch=v8 -xO5 -xdepend +10% + * egcs-1.1.2 -mv8 -O3 +35-45% + * + * As you can see it's damn hard to beat the new Sun C compiler + * and it's in first place GNU C users who will appreciate this + * assembler implementation:-) + */ + +/* + * Revision history. + * + * 1.0 - initial release; + * 1.1 - new loop unrolling model(*); + * - some more fine tuning; + * 1.2 - made gas friendly; + * - updates to documentation concerning v9; + * - new performance comparison matrix; + * 1.3 - fixed problem with /usr/ccs/lib/cpp; + * 1.4 - native V9 bn_*_comba[48] implementation (15% more efficient) + * resulting in slight overall performance kick; + * - some retunes; + * - support for GNU as added; + * + * (*) Originally unrolled loop looked like this: + * for (;;) { + * op(p+0); if (--n==0) break; + * op(p+1); if (--n==0) break; + * op(p+2); if (--n==0) break; + * op(p+3); if (--n==0) break; + * p+=4; + * } + * I unroll according to following: + * while (n&~3) { + * op(p+0); op(p+1); op(p+2); op(p+3); + * p+=4; n=-4; + * } + * if (n) { + * op(p+0); if (--n==0) return; + * op(p+2); if (--n==0) return; + * op(p+3); return; + * } + */ + +#if defined(__SUNPRO_C) && defined(__sparcv9) + /* They've said -xarch=v9 at command line */ + .register %g2,#scratch + .register %g3,#scratch +# define FRAME_SIZE -192 +#elif defined(__GNUC__) && defined(__arch64__) + /* They've said -m64 at command line */ + .register %g2,#scratch + .register %g3,#scratch +# define FRAME_SIZE -192 +#else +# define FRAME_SIZE -96 +#endif +/* + * GNU assembler can't stand stuw:-( + */ +#define stuw st + +.section ".text",#alloc,#execinstr +.file "bn_asm.sparc.v8plus.S" + +.align 32 + +.global bn_mul_add_words +/* + * BN_ULONG bn_mul_add_words(rp,ap,num,w) + * BN_ULONG *rp,*ap; + * int num; + * BN_ULONG w; + */ +bn_mul_add_words: + sra %o2,%g0,%o2 ! signx %o2 + brgz,a %o2,.L_bn_mul_add_words_proceed + lduw [%o1],%g2 + retl + clr %o0 + nop + nop + nop + +.L_bn_mul_add_words_proceed: + srl %o3,%g0,%o3 ! clruw %o3 + andcc %o2,-4,%g0 + bz,pn %icc,.L_bn_mul_add_words_tail + clr %o5 + +.L_bn_mul_add_words_loop: ! wow! 32 aligned! + lduw [%o0],%g1 + lduw [%o1+4],%g3 + mulx %o3,%g2,%g2 + add %g1,%o5,%o4 + nop + add %o4,%g2,%o4 + stuw %o4,[%o0] + srlx %o4,32,%o5 + + lduw [%o0+4],%g1 + lduw [%o1+8],%g2 + mulx %o3,%g3,%g3 + add %g1,%o5,%o4 + dec 4,%o2 + add %o4,%g3,%o4 + stuw %o4,[%o0+4] + srlx %o4,32,%o5 + + lduw [%o0+8],%g1 + lduw [%o1+12],%g3 + mulx %o3,%g2,%g2 + add %g1,%o5,%o4 + inc 16,%o1 + add %o4,%g2,%o4 + stuw %o4,[%o0+8] + srlx %o4,32,%o5 + + lduw [%o0+12],%g1 + mulx %o3,%g3,%g3 + add %g1,%o5,%o4 + inc 16,%o0 + add %o4,%g3,%o4 + andcc %o2,-4,%g0 + stuw %o4,[%o0-4] + srlx %o4,32,%o5 + bnz,a,pt %icc,.L_bn_mul_add_words_loop + lduw [%o1],%g2 + + brnz,a,pn %o2,.L_bn_mul_add_words_tail + lduw [%o1],%g2 +.L_bn_mul_add_words_return: + retl + mov %o5,%o0 + +.L_bn_mul_add_words_tail: + lduw [%o0],%g1 + mulx %o3,%g2,%g2 + add %g1,%o5,%o4 + dec %o2 + add %o4,%g2,%o4 + srlx %o4,32,%o5 + brz,pt %o2,.L_bn_mul_add_words_return + stuw %o4,[%o0] + + lduw [%o1+4],%g2 + lduw [%o0+4],%g1 + mulx %o3,%g2,%g2 + add %g1,%o5,%o4 + dec %o2 + add %o4,%g2,%o4 + srlx %o4,32,%o5 + brz,pt %o2,.L_bn_mul_add_words_return + stuw %o4,[%o0+4] + + lduw [%o1+8],%g2 + lduw [%o0+8],%g1 + mulx %o3,%g2,%g2 + add %g1,%o5,%o4 + add %o4,%g2,%o4 + stuw %o4,[%o0+8] + retl + srlx %o4,32,%o0 + +.type bn_mul_add_words,#function +.size bn_mul_add_words,(.-bn_mul_add_words) + +.align 32 + +.global bn_mul_words +/* + * BN_ULONG bn_mul_words(rp,ap,num,w) + * BN_ULONG *rp,*ap; + * int num; + * BN_ULONG w; + */ +bn_mul_words: + sra %o2,%g0,%o2 ! signx %o2 + brgz,a %o2,.L_bn_mul_words_proceeed + lduw [%o1],%g2 + retl + clr %o0 + nop + nop + nop + +.L_bn_mul_words_proceeed: + srl %o3,%g0,%o3 ! clruw %o3 + andcc %o2,-4,%g0 + bz,pn %icc,.L_bn_mul_words_tail + clr %o5 + +.L_bn_mul_words_loop: ! wow! 32 aligned! + lduw [%o1+4],%g3 + mulx %o3,%g2,%g2 + add %g2,%o5,%o4 + nop + stuw %o4,[%o0] + srlx %o4,32,%o5 + + lduw [%o1+8],%g2 + mulx %o3,%g3,%g3 + add %g3,%o5,%o4 + dec 4,%o2 + stuw %o4,[%o0+4] + srlx %o4,32,%o5 + + lduw [%o1+12],%g3 + mulx %o3,%g2,%g2 + add %g2,%o5,%o4 + inc 16,%o1 + stuw %o4,[%o0+8] + srlx %o4,32,%o5 + + mulx %o3,%g3,%g3 + add %g3,%o5,%o4 + inc 16,%o0 + stuw %o4,[%o0-4] + srlx %o4,32,%o5 + andcc %o2,-4,%g0 + bnz,a,pt %icc,.L_bn_mul_words_loop + lduw [%o1],%g2 + nop + nop + + brnz,a,pn %o2,.L_bn_mul_words_tail + lduw [%o1],%g2 +.L_bn_mul_words_return: + retl + mov %o5,%o0 + +.L_bn_mul_words_tail: + mulx %o3,%g2,%g2 + add %g2,%o5,%o4 + dec %o2 + srlx %o4,32,%o5 + brz,pt %o2,.L_bn_mul_words_return + stuw %o4,[%o0] + + lduw [%o1+4],%g2 + mulx %o3,%g2,%g2 + add %g2,%o5,%o4 + dec %o2 + srlx %o4,32,%o5 + brz,pt %o2,.L_bn_mul_words_return + stuw %o4,[%o0+4] + + lduw [%o1+8],%g2 + mulx %o3,%g2,%g2 + add %g2,%o5,%o4 + stuw %o4,[%o0+8] + retl + srlx %o4,32,%o0 + +.type bn_mul_words,#function +.size bn_mul_words,(.-bn_mul_words) + +.align 32 +.global bn_sqr_words +/* + * void bn_sqr_words(r,a,n) + * BN_ULONG *r,*a; + * int n; + */ +bn_sqr_words: + sra %o2,%g0,%o2 ! signx %o2 + brgz,a %o2,.L_bn_sqr_words_proceeed + lduw [%o1],%g2 + retl + clr %o0 + nop + nop + nop + +.L_bn_sqr_words_proceeed: + andcc %o2,-4,%g0 + nop + bz,pn %icc,.L_bn_sqr_words_tail + nop + +.L_bn_sqr_words_loop: ! wow! 32 aligned! + lduw [%o1+4],%g3 + mulx %g2,%g2,%o4 + stuw %o4,[%o0] + srlx %o4,32,%o5 + stuw %o5,[%o0+4] + nop + + lduw [%o1+8],%g2 + mulx %g3,%g3,%o4 + dec 4,%o2 + stuw %o4,[%o0+8] + srlx %o4,32,%o5 + stuw %o5,[%o0+12] + + lduw [%o1+12],%g3 + mulx %g2,%g2,%o4 + srlx %o4,32,%o5 + stuw %o4,[%o0+16] + inc 16,%o1 + stuw %o5,[%o0+20] + + mulx %g3,%g3,%o4 + inc 32,%o0 + stuw %o4,[%o0-8] + srlx %o4,32,%o5 + andcc %o2,-4,%g2 + stuw %o5,[%o0-4] + bnz,a,pt %icc,.L_bn_sqr_words_loop + lduw [%o1],%g2 + nop + + brnz,a,pn %o2,.L_bn_sqr_words_tail + lduw [%o1],%g2 +.L_bn_sqr_words_return: + retl + clr %o0 + +.L_bn_sqr_words_tail: + mulx %g2,%g2,%o4 + dec %o2 + stuw %o4,[%o0] + srlx %o4,32,%o5 + brz,pt %o2,.L_bn_sqr_words_return + stuw %o5,[%o0+4] + + lduw [%o1+4],%g2 + mulx %g2,%g2,%o4 + dec %o2 + stuw %o4,[%o0+8] + srlx %o4,32,%o5 + brz,pt %o2,.L_bn_sqr_words_return + stuw %o5,[%o0+12] + + lduw [%o1+8],%g2 + mulx %g2,%g2,%o4 + srlx %o4,32,%o5 + stuw %o4,[%o0+16] + stuw %o5,[%o0+20] + retl + clr %o0 + +.type bn_sqr_words,#function +.size bn_sqr_words,(.-bn_sqr_words) + +.align 32 +.global bn_div_words +/* + * BN_ULONG bn_div_words(h,l,d) + * BN_ULONG h,l,d; + */ +bn_div_words: + sllx %o0,32,%o0 + or %o0,%o1,%o0 + udivx %o0,%o2,%o0 + retl + srl %o0,%g0,%o0 ! clruw %o0 + +.type bn_div_words,#function +.size bn_div_words,(.-bn_div_words) + +.align 32 + +.global bn_add_words +/* + * BN_ULONG bn_add_words(rp,ap,bp,n) + * BN_ULONG *rp,*ap,*bp; + * int n; + */ +bn_add_words: + sra %o3,%g0,%o3 ! signx %o3 + brgz,a %o3,.L_bn_add_words_proceed + lduw [%o1],%o4 + retl + clr %o0 + +.L_bn_add_words_proceed: + andcc %o3,-4,%g0 + bz,pn %icc,.L_bn_add_words_tail + addcc %g0,0,%g0 ! clear carry flag + +.L_bn_add_words_loop: ! wow! 32 aligned! + dec 4,%o3 + lduw [%o2],%o5 + lduw [%o1+4],%g1 + lduw [%o2+4],%g2 + lduw [%o1+8],%g3 + lduw [%o2+8],%g4 + addccc %o5,%o4,%o5 + stuw %o5,[%o0] + + lduw [%o1+12],%o4 + lduw [%o2+12],%o5 + inc 16,%o1 + addccc %g1,%g2,%g1 + stuw %g1,[%o0+4] + + inc 16,%o2 + addccc %g3,%g4,%g3 + stuw %g3,[%o0+8] + + inc 16,%o0 + addccc %o5,%o4,%o5 + stuw %o5,[%o0-4] + and %o3,-4,%g1 + brnz,a,pt %g1,.L_bn_add_words_loop + lduw [%o1],%o4 + + brnz,a,pn %o3,.L_bn_add_words_tail + lduw [%o1],%o4 +.L_bn_add_words_return: + clr %o0 + retl + movcs %icc,1,%o0 + nop + +.L_bn_add_words_tail: + lduw [%o2],%o5 + dec %o3 + addccc %o5,%o4,%o5 + brz,pt %o3,.L_bn_add_words_return + stuw %o5,[%o0] + + lduw [%o1+4],%o4 + lduw [%o2+4],%o5 + dec %o3 + addccc %o5,%o4,%o5 + brz,pt %o3,.L_bn_add_words_return + stuw %o5,[%o0+4] + + lduw [%o1+8],%o4 + lduw [%o2+8],%o5 + addccc %o5,%o4,%o5 + stuw %o5,[%o0+8] + clr %o0 + retl + movcs %icc,1,%o0 + +.type bn_add_words,#function +.size bn_add_words,(.-bn_add_words) + +.global bn_sub_words +/* + * BN_ULONG bn_sub_words(rp,ap,bp,n) + * BN_ULONG *rp,*ap,*bp; + * int n; + */ +bn_sub_words: + sra %o3,%g0,%o3 ! signx %o3 + brgz,a %o3,.L_bn_sub_words_proceed + lduw [%o1],%o4 + retl + clr %o0 + +.L_bn_sub_words_proceed: + andcc %o3,-4,%g0 + bz,pn %icc,.L_bn_sub_words_tail + addcc %g0,0,%g0 ! clear carry flag + +.L_bn_sub_words_loop: ! wow! 32 aligned! + dec 4,%o3 + lduw [%o2],%o5 + lduw [%o1+4],%g1 + lduw [%o2+4],%g2 + lduw [%o1+8],%g3 + lduw [%o2+8],%g4 + subccc %o4,%o5,%o5 + stuw %o5,[%o0] + + lduw [%o1+12],%o4 + lduw [%o2+12],%o5 + inc 16,%o1 + subccc %g1,%g2,%g2 + stuw %g2,[%o0+4] + + inc 16,%o2 + subccc %g3,%g4,%g4 + stuw %g4,[%o0+8] + + inc 16,%o0 + subccc %o4,%o5,%o5 + stuw %o5,[%o0-4] + and %o3,-4,%g1 + brnz,a,pt %g1,.L_bn_sub_words_loop + lduw [%o1],%o4 + + brnz,a,pn %o3,.L_bn_sub_words_tail + lduw [%o1],%o4 +.L_bn_sub_words_return: + clr %o0 + retl + movcs %icc,1,%o0 + nop + +.L_bn_sub_words_tail: ! wow! 32 aligned! + lduw [%o2],%o5 + dec %o3 + subccc %o4,%o5,%o5 + brz,pt %o3,.L_bn_sub_words_return + stuw %o5,[%o0] + + lduw [%o1+4],%o4 + lduw [%o2+4],%o5 + dec %o3 + subccc %o4,%o5,%o5 + brz,pt %o3,.L_bn_sub_words_return + stuw %o5,[%o0+4] + + lduw [%o1+8],%o4 + lduw [%o2+8],%o5 + subccc %o4,%o5,%o5 + stuw %o5,[%o0+8] + clr %o0 + retl + movcs %icc,1,%o0 + +.type bn_sub_words,#function +.size bn_sub_words,(.-bn_sub_words) + +/* + * Code below depends on the fact that upper parts of the %l0-%l7 + * and %i0-%i7 are zeroed by kernel after context switch. In + * previous versions this comment stated that "the trouble is that + * it's not feasible to implement the mumbo-jumbo in less V9 + * instructions:-(" which apparently isn't true thanks to + * 'bcs,a %xcc,.+8; inc %rd' pair. But the performance improvement + * results not from the shorter code, but from elimination of + * multicycle none-pairable 'rd %y,%rd' instructions. + * + * Andy. + */ + +/* + * Here is register usage map for *all* routines below. + */ +#define t_1 %o0 +#define t_2 %o1 +#define c_12 %o2 +#define c_3 %o3 + +#define ap(I) [%i1+4*I] +#define bp(I) [%i2+4*I] +#define rp(I) [%i0+4*I] + +#define a_0 %l0 +#define a_1 %l1 +#define a_2 %l2 +#define a_3 %l3 +#define a_4 %l4 +#define a_5 %l5 +#define a_6 %l6 +#define a_7 %l7 + +#define b_0 %i3 +#define b_1 %i4 +#define b_2 %i5 +#define b_3 %o4 +#define b_4 %o5 +#define b_5 %o7 +#define b_6 %g1 +#define b_7 %g4 + +.align 32 +.global bn_mul_comba8 +/* + * void bn_mul_comba8(r,a,b) + * BN_ULONG *r,*a,*b; + */ +bn_mul_comba8: + save %sp,FRAME_SIZE,%sp + mov 1,t_2 + lduw ap(0),a_0 + sllx t_2,32,t_2 + lduw bp(0),b_0 != + lduw bp(1),b_1 + mulx a_0,b_0,t_1 !mul_add_c(a[0],b[0],c1,c2,c3); + srlx t_1,32,c_12 + stuw t_1,rp(0) !=!r[0]=c1; + + lduw ap(1),a_1 + mulx a_0,b_1,t_1 !mul_add_c(a[0],b[1],c2,c3,c1); + addcc c_12,t_1,c_12 + clr c_3 != + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + lduw ap(2),a_2 + mulx a_1,b_0,t_1 !=!mul_add_c(a[1],b[0],c2,c3,c1); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 != + stuw t_1,rp(1) !r[1]=c2; + or c_12,c_3,c_12 + + mulx a_2,b_0,t_1 !mul_add_c(a[2],b[0],c3,c1,c2); + addcc c_12,t_1,c_12 != + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + lduw bp(2),b_2 != + mulx a_1,b_1,t_1 !mul_add_c(a[1],b[1],c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 != + lduw bp(3),b_3 + mulx a_0,b_2,t_1 !mul_add_c(a[0],b[2],c3,c1,c2); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(2) !r[2]=c3; + or c_12,c_3,c_12 != + + mulx a_0,b_3,t_1 !mul_add_c(a[0],b[3],c1,c2,c3); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_1,b_2,t_1 !=!mul_add_c(a[1],b[2],c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + lduw ap(3),a_3 + mulx a_2,b_1,t_1 !mul_add_c(a[2],b[1],c1,c2,c3); + addcc c_12,t_1,c_12 != + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + lduw ap(4),a_4 + mulx a_3,b_0,t_1 !=!mul_add_c(a[3],b[0],c1,c2,c3);!= + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 != + stuw t_1,rp(3) !r[3]=c1; + or c_12,c_3,c_12 + + mulx a_4,b_0,t_1 !mul_add_c(a[4],b[0],c2,c3,c1); + addcc c_12,t_1,c_12 != + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_3,b_1,t_1 !=!mul_add_c(a[3],b[1],c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_2,b_2,t_1 !=!mul_add_c(a[2],b[2],c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + lduw bp(4),b_4 != + mulx a_1,b_3,t_1 !mul_add_c(a[1],b[3],c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 != + lduw bp(5),b_5 + mulx a_0,b_4,t_1 !mul_add_c(a[0],b[4],c2,c3,c1); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(4) !r[4]=c2; + or c_12,c_3,c_12 != + + mulx a_0,b_5,t_1 !mul_add_c(a[0],b[5],c3,c1,c2); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_1,b_4,t_1 !mul_add_c(a[1],b[4],c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_2,b_3,t_1 !mul_add_c(a[2],b[3],c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_3,b_2,t_1 !mul_add_c(a[3],b[2],c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + lduw ap(5),a_5 + mulx a_4,b_1,t_1 !mul_add_c(a[4],b[1],c3,c1,c2); + addcc c_12,t_1,c_12 != + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + lduw ap(6),a_6 + mulx a_5,b_0,t_1 !=!mul_add_c(a[5],b[0],c3,c1,c2); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 != + stuw t_1,rp(5) !r[5]=c3; + or c_12,c_3,c_12 + + mulx a_6,b_0,t_1 !mul_add_c(a[6],b[0],c1,c2,c3); + addcc c_12,t_1,c_12 != + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_5,b_1,t_1 !=!mul_add_c(a[5],b[1],c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_4,b_2,t_1 !=!mul_add_c(a[4],b[2],c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_3,b_3,t_1 !=!mul_add_c(a[3],b[3],c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_2,b_4,t_1 !=!mul_add_c(a[2],b[4],c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + lduw bp(6),b_6 != + mulx a_1,b_5,t_1 !mul_add_c(a[1],b[5],c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 != + lduw bp(7),b_7 + mulx a_0,b_6,t_1 !mul_add_c(a[0],b[6],c1,c2,c3); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(6) !r[6]=c1; + or c_12,c_3,c_12 != + + mulx a_0,b_7,t_1 !mul_add_c(a[0],b[7],c2,c3,c1); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_1,b_6,t_1 !mul_add_c(a[1],b[6],c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_2,b_5,t_1 !mul_add_c(a[2],b[5],c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_3,b_4,t_1 !mul_add_c(a[3],b[4],c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_4,b_3,t_1 !mul_add_c(a[4],b[3],c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_5,b_2,t_1 !mul_add_c(a[5],b[2],c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + lduw ap(7),a_7 + mulx a_6,b_1,t_1 !=!mul_add_c(a[6],b[1],c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_7,b_0,t_1 !=!mul_add_c(a[7],b[0],c2,c3,c1); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 != + stuw t_1,rp(7) !r[7]=c2; + or c_12,c_3,c_12 + + mulx a_7,b_1,t_1 !=!mul_add_c(a[7],b[1],c3,c1,c2); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 != + mulx a_6,b_2,t_1 !mul_add_c(a[6],b[2],c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 != + mulx a_5,b_3,t_1 !mul_add_c(a[5],b[3],c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 != + mulx a_4,b_4,t_1 !mul_add_c(a[4],b[4],c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 != + mulx a_3,b_5,t_1 !mul_add_c(a[3],b[5],c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 != + mulx a_2,b_6,t_1 !mul_add_c(a[2],b[6],c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 != + mulx a_1,b_7,t_1 !mul_add_c(a[1],b[7],c3,c1,c2); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 != + srlx t_1,32,c_12 + stuw t_1,rp(8) !r[8]=c3; + or c_12,c_3,c_12 + + mulx a_2,b_7,t_1 !=!mul_add_c(a[2],b[7],c1,c2,c3); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 != + mulx a_3,b_6,t_1 !mul_add_c(a[3],b[6],c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_4,b_5,t_1 !mul_add_c(a[4],b[5],c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_5,b_4,t_1 !mul_add_c(a[5],b[4],c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_6,b_3,t_1 !mul_add_c(a[6],b[3],c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_7,b_2,t_1 !mul_add_c(a[7],b[2],c1,c2,c3); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(9) !r[9]=c1; + or c_12,c_3,c_12 != + + mulx a_7,b_3,t_1 !mul_add_c(a[7],b[3],c2,c3,c1); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_6,b_4,t_1 !mul_add_c(a[6],b[4],c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_5,b_5,t_1 !mul_add_c(a[5],b[5],c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_4,b_6,t_1 !mul_add_c(a[4],b[6],c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_3,b_7,t_1 !mul_add_c(a[3],b[7],c2,c3,c1); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(10) !r[10]=c2; + or c_12,c_3,c_12 != + + mulx a_4,b_7,t_1 !mul_add_c(a[4],b[7],c3,c1,c2); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_5,b_6,t_1 !mul_add_c(a[5],b[6],c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_6,b_5,t_1 !mul_add_c(a[6],b[5],c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_7,b_4,t_1 !mul_add_c(a[7],b[4],c3,c1,c2); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(11) !r[11]=c3; + or c_12,c_3,c_12 != + + mulx a_7,b_5,t_1 !mul_add_c(a[7],b[5],c1,c2,c3); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_6,b_6,t_1 !mul_add_c(a[6],b[6],c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_5,b_7,t_1 !mul_add_c(a[5],b[7],c1,c2,c3); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(12) !r[12]=c1; + or c_12,c_3,c_12 != + + mulx a_6,b_7,t_1 !mul_add_c(a[6],b[7],c2,c3,c1); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_7,b_6,t_1 !mul_add_c(a[7],b[6],c2,c3,c1); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + srlx t_1,32,c_12 + st t_1,rp(13) !r[13]=c2; + or c_12,c_3,c_12 != + + mulx a_7,b_7,t_1 !mul_add_c(a[7],b[7],c3,c1,c2); + addcc c_12,t_1,t_1 + srlx t_1,32,c_12 != + stuw t_1,rp(14) !r[14]=c3; + stuw c_12,rp(15) !r[15]=c1; + + ret + restore %g0,%g0,%o0 != + +.type bn_mul_comba8,#function +.size bn_mul_comba8,(.-bn_mul_comba8) + +.align 32 + +.global bn_mul_comba4 +/* + * void bn_mul_comba4(r,a,b) + * BN_ULONG *r,*a,*b; + */ +bn_mul_comba4: + save %sp,FRAME_SIZE,%sp + lduw ap(0),a_0 + mov 1,t_2 + lduw bp(0),b_0 + sllx t_2,32,t_2 != + lduw bp(1),b_1 + mulx a_0,b_0,t_1 !mul_add_c(a[0],b[0],c1,c2,c3); + srlx t_1,32,c_12 + stuw t_1,rp(0) !=!r[0]=c1; + + lduw ap(1),a_1 + mulx a_0,b_1,t_1 !mul_add_c(a[0],b[1],c2,c3,c1); + addcc c_12,t_1,c_12 + clr c_3 != + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + lduw ap(2),a_2 + mulx a_1,b_0,t_1 !=!mul_add_c(a[1],b[0],c2,c3,c1); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 != + stuw t_1,rp(1) !r[1]=c2; + or c_12,c_3,c_12 + + mulx a_2,b_0,t_1 !mul_add_c(a[2],b[0],c3,c1,c2); + addcc c_12,t_1,c_12 != + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + lduw bp(2),b_2 != + mulx a_1,b_1,t_1 !mul_add_c(a[1],b[1],c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 != + lduw bp(3),b_3 + mulx a_0,b_2,t_1 !mul_add_c(a[0],b[2],c3,c1,c2); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(2) !r[2]=c3; + or c_12,c_3,c_12 != + + mulx a_0,b_3,t_1 !mul_add_c(a[0],b[3],c1,c2,c3); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + mulx a_1,b_2,t_1 !mul_add_c(a[1],b[2],c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 != + add c_3,t_2,c_3 + lduw ap(3),a_3 + mulx a_2,b_1,t_1 !mul_add_c(a[2],b[1],c1,c2,c3); + addcc c_12,t_1,c_12 != + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_3,b_0,t_1 !mul_add_c(a[3],b[0],c1,c2,c3);!= + addcc c_12,t_1,t_1 != + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(3) !=!r[3]=c1; + or c_12,c_3,c_12 + + mulx a_3,b_1,t_1 !mul_add_c(a[3],b[1],c2,c3,c1); + addcc c_12,t_1,c_12 + clr c_3 != + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_2,b_2,t_1 !mul_add_c(a[2],b[2],c2,c3,c1); + addcc c_12,t_1,c_12 != + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_1,b_3,t_1 !mul_add_c(a[1],b[3],c2,c3,c1); + addcc c_12,t_1,t_1 != + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(4) !=!r[4]=c2; + or c_12,c_3,c_12 + + mulx a_2,b_3,t_1 !mul_add_c(a[2],b[3],c3,c1,c2); + addcc c_12,t_1,c_12 + clr c_3 != + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_3,b_2,t_1 !mul_add_c(a[3],b[2],c3,c1,c2); + addcc c_12,t_1,t_1 != + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(5) !=!r[5]=c3; + or c_12,c_3,c_12 + + mulx a_3,b_3,t_1 !mul_add_c(a[3],b[3],c1,c2,c3); + addcc c_12,t_1,t_1 + srlx t_1,32,c_12 != + stuw t_1,rp(6) !r[6]=c1; + stuw c_12,rp(7) !r[7]=c2; + + ret + restore %g0,%g0,%o0 + +.type bn_mul_comba4,#function +.size bn_mul_comba4,(.-bn_mul_comba4) + +.align 32 + +.global bn_sqr_comba8 +bn_sqr_comba8: + save %sp,FRAME_SIZE,%sp + mov 1,t_2 + lduw ap(0),a_0 + sllx t_2,32,t_2 + lduw ap(1),a_1 + mulx a_0,a_0,t_1 !sqr_add_c(a,0,c1,c2,c3); + srlx t_1,32,c_12 + stuw t_1,rp(0) !r[0]=c1; + + lduw ap(2),a_2 + mulx a_0,a_1,t_1 !=!sqr_add_c2(a,1,0,c2,c3,c1); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(1) !r[1]=c2; + or c_12,c_3,c_12 + + mulx a_2,a_0,t_1 !sqr_add_c2(a,2,0,c3,c1,c2); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + lduw ap(3),a_3 + mulx a_1,a_1,t_1 !sqr_add_c(a,1,c3,c1,c2); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(2) !r[2]=c3; + or c_12,c_3,c_12 + + mulx a_0,a_3,t_1 !sqr_add_c2(a,3,0,c1,c2,c3); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + lduw ap(4),a_4 + mulx a_1,a_2,t_1 !sqr_add_c2(a,2,1,c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + st t_1,rp(3) !r[3]=c1; + or c_12,c_3,c_12 + + mulx a_4,a_0,t_1 !sqr_add_c2(a,4,0,c2,c3,c1); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_3,a_1,t_1 !sqr_add_c2(a,3,1,c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + lduw ap(5),a_5 + mulx a_2,a_2,t_1 !sqr_add_c(a,2,c2,c3,c1); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(4) !r[4]=c2; + or c_12,c_3,c_12 + + mulx a_0,a_5,t_1 !sqr_add_c2(a,5,0,c3,c1,c2); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_1,a_4,t_1 !sqr_add_c2(a,4,1,c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + lduw ap(6),a_6 + mulx a_2,a_3,t_1 !sqr_add_c2(a,3,2,c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(5) !r[5]=c3; + or c_12,c_3,c_12 + + mulx a_6,a_0,t_1 !sqr_add_c2(a,6,0,c1,c2,c3); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_5,a_1,t_1 !sqr_add_c2(a,5,1,c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_4,a_2,t_1 !sqr_add_c2(a,4,2,c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + lduw ap(7),a_7 + mulx a_3,a_3,t_1 !=!sqr_add_c(a,3,c1,c2,c3); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(6) !r[6]=c1; + or c_12,c_3,c_12 + + mulx a_0,a_7,t_1 !sqr_add_c2(a,7,0,c2,c3,c1); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_1,a_6,t_1 !sqr_add_c2(a,6,1,c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_2,a_5,t_1 !sqr_add_c2(a,5,2,c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_3,a_4,t_1 !sqr_add_c2(a,4,3,c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(7) !r[7]=c2; + or c_12,c_3,c_12 + + mulx a_7,a_1,t_1 !sqr_add_c2(a,7,1,c3,c1,c2); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_6,a_2,t_1 !sqr_add_c2(a,6,2,c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_5,a_3,t_1 !sqr_add_c2(a,5,3,c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_4,a_4,t_1 !sqr_add_c(a,4,c3,c1,c2); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(8) !r[8]=c3; + or c_12,c_3,c_12 + + mulx a_2,a_7,t_1 !sqr_add_c2(a,7,2,c1,c2,c3); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_3,a_6,t_1 !sqr_add_c2(a,6,3,c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_4,a_5,t_1 !sqr_add_c2(a,5,4,c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(9) !r[9]=c1; + or c_12,c_3,c_12 + + mulx a_7,a_3,t_1 !sqr_add_c2(a,7,3,c2,c3,c1); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_6,a_4,t_1 !sqr_add_c2(a,6,4,c2,c3,c1); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_5,a_5,t_1 !sqr_add_c(a,5,c2,c3,c1); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(10) !r[10]=c2; + or c_12,c_3,c_12 + + mulx a_4,a_7,t_1 !sqr_add_c2(a,7,4,c3,c1,c2); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_5,a_6,t_1 !sqr_add_c2(a,6,5,c3,c1,c2); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(11) !r[11]=c3; + or c_12,c_3,c_12 + + mulx a_7,a_5,t_1 !sqr_add_c2(a,7,5,c1,c2,c3); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_6,a_6,t_1 !sqr_add_c(a,6,c1,c2,c3); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(12) !r[12]=c1; + or c_12,c_3,c_12 + + mulx a_6,a_7,t_1 !sqr_add_c2(a,7,6,c2,c3,c1); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(13) !r[13]=c2; + or c_12,c_3,c_12 + + mulx a_7,a_7,t_1 !sqr_add_c(a,7,c3,c1,c2); + addcc c_12,t_1,t_1 + srlx t_1,32,c_12 + stuw t_1,rp(14) !r[14]=c3; + stuw c_12,rp(15) !r[15]=c1; + + ret + restore %g0,%g0,%o0 + +.type bn_sqr_comba8,#function +.size bn_sqr_comba8,(.-bn_sqr_comba8) + +.align 32 + +.global bn_sqr_comba4 +/* + * void bn_sqr_comba4(r,a) + * BN_ULONG *r,*a; + */ +bn_sqr_comba4: + save %sp,FRAME_SIZE,%sp + mov 1,t_2 + lduw ap(0),a_0 + sllx t_2,32,t_2 + lduw ap(1),a_1 + mulx a_0,a_0,t_1 !sqr_add_c(a,0,c1,c2,c3); + srlx t_1,32,c_12 + stuw t_1,rp(0) !r[0]=c1; + + lduw ap(2),a_2 + mulx a_0,a_1,t_1 !sqr_add_c2(a,1,0,c2,c3,c1); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(1) !r[1]=c2; + or c_12,c_3,c_12 + + mulx a_2,a_0,t_1 !sqr_add_c2(a,2,0,c3,c1,c2); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + lduw ap(3),a_3 + mulx a_1,a_1,t_1 !sqr_add_c(a,1,c3,c1,c2); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(2) !r[2]=c3; + or c_12,c_3,c_12 + + mulx a_0,a_3,t_1 !sqr_add_c2(a,3,0,c1,c2,c3); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_1,a_2,t_1 !sqr_add_c2(a,2,1,c1,c2,c3); + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(3) !r[3]=c1; + or c_12,c_3,c_12 + + mulx a_3,a_1,t_1 !sqr_add_c2(a,3,1,c2,c3,c1); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,c_12 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + mulx a_2,a_2,t_1 !sqr_add_c(a,2,c2,c3,c1); + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(4) !r[4]=c2; + or c_12,c_3,c_12 + + mulx a_2,a_3,t_1 !sqr_add_c2(a,3,2,c3,c1,c2); + addcc c_12,t_1,c_12 + clr c_3 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + addcc c_12,t_1,t_1 + bcs,a %xcc,.+8 + add c_3,t_2,c_3 + srlx t_1,32,c_12 + stuw t_1,rp(5) !r[5]=c3; + or c_12,c_3,c_12 + + mulx a_3,a_3,t_1 !sqr_add_c(a,3,c1,c2,c3); + addcc c_12,t_1,t_1 + srlx t_1,32,c_12 + stuw t_1,rp(6) !r[6]=c1; + stuw c_12,rp(7) !r[7]=c2; + + ret + restore %g0,%g0,%o0 + +.type bn_sqr_comba4,#function +.size bn_sqr_comba4,(.-bn_sqr_comba4) + +.align 32 diff --git a/libs/openssl/crypto/bn/asm/sparcv9-mont.pl b/libs/openssl/crypto/bn/asm/sparcv9-mont.pl new file mode 100644 index 00000000..b8fb1e8a --- /dev/null +++ b/libs/openssl/crypto/bn/asm/sparcv9-mont.pl @@ -0,0 +1,606 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# December 2005 +# +# Pure SPARCv9/8+ and IALU-only bn_mul_mont implementation. The reasons +# for undertaken effort are multiple. First of all, UltraSPARC is not +# the whole SPARCv9 universe and other VIS-free implementations deserve +# optimized code as much. Secondly, newly introduced UltraSPARC T1, +# a.k.a. Niagara, has shared FPU and concurrent FPU-intensive pathes, +# such as sparcv9a-mont, will simply sink it. Yes, T1 is equipped with +# several integrated RSA/DSA accelerator circuits accessible through +# kernel driver [only(*)], but having decent user-land software +# implementation is important too. Finally, reasons like desire to +# experiment with dedicated squaring procedure. Yes, this module +# implements one, because it was easiest to draft it in SPARCv9 +# instructions... + +# (*) Engine accessing the driver in question is on my TODO list. +# For reference, acceleator is estimated to give 6 to 10 times +# improvement on single-threaded RSA sign. It should be noted +# that 6-10x improvement coefficient does not actually mean +# something extraordinary in terms of absolute [single-threaded] +# performance, as SPARCv9 instruction set is by all means least +# suitable for high performance crypto among other 64 bit +# platforms. 6-10x factor simply places T1 in same performance +# domain as say AMD64 and IA-64. Improvement of RSA verify don't +# appear impressive at all, but it's the sign operation which is +# far more critical/interesting. + +# You might notice that inner loops are modulo-scheduled:-) This has +# essentially negligible impact on UltraSPARC performance, it's +# Fujitsu SPARC64 V users who should notice and hopefully appreciate +# the advantage... Currently this module surpasses sparcv9a-mont.pl +# by ~20% on UltraSPARC-III and later cores, but recall that sparcv9a +# module still have hidden potential [see TODO list there], which is +# estimated to be larger than 20%... + +# int bn_mul_mont( +$rp="%i0"; # BN_ULONG *rp, +$ap="%i1"; # const BN_ULONG *ap, +$bp="%i2"; # const BN_ULONG *bp, +$np="%i3"; # const BN_ULONG *np, +$n0="%i4"; # const BN_ULONG *n0, +$num="%i5"; # int num); + +$bits=32; +for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); } +if ($bits==64) { $bias=2047; $frame=192; } +else { $bias=0; $frame=128; } + +$car0="%o0"; +$car1="%o1"; +$car2="%o2"; # 1 bit +$acc0="%o3"; +$acc1="%o4"; +$mask="%g1"; # 32 bits, what a waste... +$tmp0="%g4"; +$tmp1="%g5"; + +$i="%l0"; +$j="%l1"; +$mul0="%l2"; +$mul1="%l3"; +$tp="%l4"; +$apj="%l5"; +$npj="%l6"; +$tpj="%l7"; + +$fname="bn_mul_mont_int"; + +$code=<<___; +.section ".text",#alloc,#execinstr + +.global $fname +.align 32 +$fname: + cmp %o5,4 ! 128 bits minimum + bge,pt %icc,.Lenter + sethi %hi(0xffffffff),$mask + retl + clr %o0 +.align 32 +.Lenter: + save %sp,-$frame,%sp + sll $num,2,$num ! num*=4 + or $mask,%lo(0xffffffff),$mask + ld [$n0],$n0 + cmp $ap,$bp + and $num,$mask,$num + ld [$bp],$mul0 ! bp[0] + nop + + add %sp,$bias,%o7 ! real top of stack + ld [$ap],$car0 ! ap[0] ! redundant in squaring context + sub %o7,$num,%o7 + ld [$ap+4],$apj ! ap[1] + and %o7,-1024,%o7 + ld [$np],$car1 ! np[0] + sub %o7,$bias,%sp ! alloca + ld [$np+4],$npj ! np[1] + be,pt `$bits==32?"%icc":"%xcc"`,.Lbn_sqr_mont + mov 12,$j + + mulx $car0,$mul0,$car0 ! ap[0]*bp[0] + mulx $apj,$mul0,$tmp0 !prologue! ap[1]*bp[0] + and $car0,$mask,$acc0 + add %sp,$bias+$frame,$tp + ld [$ap+8],$apj !prologue! + + mulx $n0,$acc0,$mul1 ! "t[0]"*n0 + and $mul1,$mask,$mul1 + + mulx $car1,$mul1,$car1 ! np[0]*"t[0]"*n0 + mulx $npj,$mul1,$acc1 !prologue! np[1]*"t[0]"*n0 + srlx $car0,32,$car0 + add $acc0,$car1,$car1 + ld [$np+8],$npj !prologue! + srlx $car1,32,$car1 + mov $tmp0,$acc0 !prologue! + +.L1st: + mulx $apj,$mul0,$tmp0 + mulx $npj,$mul1,$tmp1 + add $acc0,$car0,$car0 + ld [$ap+$j],$apj ! ap[j] + and $car0,$mask,$acc0 + add $acc1,$car1,$car1 + ld [$np+$j],$npj ! np[j] + srlx $car0,32,$car0 + add $acc0,$car1,$car1 + add $j,4,$j ! j++ + mov $tmp0,$acc0 + st $car1,[$tp] + cmp $j,$num + mov $tmp1,$acc1 + srlx $car1,32,$car1 + bl %icc,.L1st + add $tp,4,$tp ! tp++ +!.L1st + + mulx $apj,$mul0,$tmp0 !epilogue! + mulx $npj,$mul1,$tmp1 + add $acc0,$car0,$car0 + and $car0,$mask,$acc0 + add $acc1,$car1,$car1 + srlx $car0,32,$car0 + add $acc0,$car1,$car1 + st $car1,[$tp] + srlx $car1,32,$car1 + + add $tmp0,$car0,$car0 + and $car0,$mask,$acc0 + add $tmp1,$car1,$car1 + srlx $car0,32,$car0 + add $acc0,$car1,$car1 + st $car1,[$tp+4] + srlx $car1,32,$car1 + + add $car0,$car1,$car1 + st $car1,[$tp+8] + srlx $car1,32,$car2 + + mov 4,$i ! i++ + ld [$bp+4],$mul0 ! bp[1] +.Louter: + add %sp,$bias+$frame,$tp + ld [$ap],$car0 ! ap[0] + ld [$ap+4],$apj ! ap[1] + ld [$np],$car1 ! np[0] + ld [$np+4],$npj ! np[1] + ld [$tp],$tmp1 ! tp[0] + ld [$tp+4],$tpj ! tp[1] + mov 12,$j + + mulx $car0,$mul0,$car0 + mulx $apj,$mul0,$tmp0 !prologue! + add $tmp1,$car0,$car0 + ld [$ap+8],$apj !prologue! + and $car0,$mask,$acc0 + + mulx $n0,$acc0,$mul1 + and $mul1,$mask,$mul1 + + mulx $car1,$mul1,$car1 + mulx $npj,$mul1,$acc1 !prologue! + srlx $car0,32,$car0 + add $acc0,$car1,$car1 + ld [$np+8],$npj !prologue! + srlx $car1,32,$car1 + mov $tmp0,$acc0 !prologue! + +.Linner: + mulx $apj,$mul0,$tmp0 + mulx $npj,$mul1,$tmp1 + add $tpj,$car0,$car0 + ld [$ap+$j],$apj ! ap[j] + add $acc0,$car0,$car0 + add $acc1,$car1,$car1 + ld [$np+$j],$npj ! np[j] + and $car0,$mask,$acc0 + ld [$tp+8],$tpj ! tp[j] + srlx $car0,32,$car0 + add $acc0,$car1,$car1 + add $j,4,$j ! j++ + mov $tmp0,$acc0 + st $car1,[$tp] ! tp[j-1] + srlx $car1,32,$car1 + mov $tmp1,$acc1 + cmp $j,$num + bl %icc,.Linner + add $tp,4,$tp ! tp++ +!.Linner + + mulx $apj,$mul0,$tmp0 !epilogue! + mulx $npj,$mul1,$tmp1 + add $tpj,$car0,$car0 + add $acc0,$car0,$car0 + ld [$tp+8],$tpj ! tp[j] + and $car0,$mask,$acc0 + add $acc1,$car1,$car1 + srlx $car0,32,$car0 + add $acc0,$car1,$car1 + st $car1,[$tp] ! tp[j-1] + srlx $car1,32,$car1 + + add $tpj,$car0,$car0 + add $tmp0,$car0,$car0 + and $car0,$mask,$acc0 + add $tmp1,$car1,$car1 + add $acc0,$car1,$car1 + st $car1,[$tp+4] ! tp[j-1] + srlx $car0,32,$car0 + add $i,4,$i ! i++ + srlx $car1,32,$car1 + + add $car0,$car1,$car1 + cmp $i,$num + add $car2,$car1,$car1 + st $car1,[$tp+8] + + srlx $car1,32,$car2 + bl,a %icc,.Louter + ld [$bp+$i],$mul0 ! bp[i] +!.Louter + + add $tp,12,$tp + +.Ltail: + add $np,$num,$np + add $rp,$num,$rp + mov $tp,$ap + sub %g0,$num,%o7 ! k=-num + ba .Lsub + subcc %g0,%g0,%g0 ! clear %icc.c +.align 16 +.Lsub: + ld [$tp+%o7],%o0 + ld [$np+%o7],%o1 + subccc %o0,%o1,%o1 ! tp[j]-np[j] + add $rp,%o7,$i + add %o7,4,%o7 + brnz %o7,.Lsub + st %o1,[$i] + subc $car2,0,$car2 ! handle upmost overflow bit + and $tp,$car2,$ap + andn $rp,$car2,$np + or $ap,$np,$ap + sub %g0,$num,%o7 + +.Lcopy: + ld [$ap+%o7],%o0 ! copy or in-place refresh + st %g0,[$tp+%o7] ! zap tp + st %o0,[$rp+%o7] + add %o7,4,%o7 + brnz %o7,.Lcopy + nop + mov 1,%i0 + ret + restore +___ + +######## +######## .Lbn_sqr_mont gives up to 20% *overall* improvement over +######## code without following dedicated squaring procedure. +######## +$sbit="%i2"; # re-use $bp! + +$code.=<<___; +.align 32 +.Lbn_sqr_mont: + mulx $mul0,$mul0,$car0 ! ap[0]*ap[0] + mulx $apj,$mul0,$tmp0 !prologue! + and $car0,$mask,$acc0 + add %sp,$bias+$frame,$tp + ld [$ap+8],$apj !prologue! + + mulx $n0,$acc0,$mul1 ! "t[0]"*n0 + srlx $car0,32,$car0 + and $mul1,$mask,$mul1 + + mulx $car1,$mul1,$car1 ! np[0]*"t[0]"*n0 + mulx $npj,$mul1,$acc1 !prologue! + and $car0,1,$sbit + ld [$np+8],$npj !prologue! + srlx $car0,1,$car0 + add $acc0,$car1,$car1 + srlx $car1,32,$car1 + mov $tmp0,$acc0 !prologue! + +.Lsqr_1st: + mulx $apj,$mul0,$tmp0 + mulx $npj,$mul1,$tmp1 + add $acc0,$car0,$car0 ! ap[j]*a0+c0 + add $acc1,$car1,$car1 + ld [$ap+$j],$apj ! ap[j] + and $car0,$mask,$acc0 + ld [$np+$j],$npj ! np[j] + srlx $car0,32,$car0 + add $acc0,$acc0,$acc0 + or $sbit,$acc0,$acc0 + mov $tmp1,$acc1 + srlx $acc0,32,$sbit + add $j,4,$j ! j++ + and $acc0,$mask,$acc0 + cmp $j,$num + add $acc0,$car1,$car1 + st $car1,[$tp] + mov $tmp0,$acc0 + srlx $car1,32,$car1 + bl %icc,.Lsqr_1st + add $tp,4,$tp ! tp++ +!.Lsqr_1st + + mulx $apj,$mul0,$tmp0 ! epilogue + mulx $npj,$mul1,$tmp1 + add $acc0,$car0,$car0 ! ap[j]*a0+c0 + add $acc1,$car1,$car1 + and $car0,$mask,$acc0 + srlx $car0,32,$car0 + add $acc0,$acc0,$acc0 + or $sbit,$acc0,$acc0 + srlx $acc0,32,$sbit + and $acc0,$mask,$acc0 + add $acc0,$car1,$car1 + st $car1,[$tp] + srlx $car1,32,$car1 + + add $tmp0,$car0,$car0 ! ap[j]*a0+c0 + add $tmp1,$car1,$car1 + and $car0,$mask,$acc0 + srlx $car0,32,$car0 + add $acc0,$acc0,$acc0 + or $sbit,$acc0,$acc0 + srlx $acc0,32,$sbit + and $acc0,$mask,$acc0 + add $acc0,$car1,$car1 + st $car1,[$tp+4] + srlx $car1,32,$car1 + + add $car0,$car0,$car0 + or $sbit,$car0,$car0 + add $car0,$car1,$car1 + st $car1,[$tp+8] + srlx $car1,32,$car2 + + ld [%sp+$bias+$frame],$tmp0 ! tp[0] + ld [%sp+$bias+$frame+4],$tmp1 ! tp[1] + ld [%sp+$bias+$frame+8],$tpj ! tp[2] + ld [$ap+4],$mul0 ! ap[1] + ld [$ap+8],$apj ! ap[2] + ld [$np],$car1 ! np[0] + ld [$np+4],$npj ! np[1] + mulx $n0,$tmp0,$mul1 + + mulx $mul0,$mul0,$car0 + and $mul1,$mask,$mul1 + + mulx $car1,$mul1,$car1 + mulx $npj,$mul1,$acc1 + add $tmp0,$car1,$car1 + and $car0,$mask,$acc0 + ld [$np+8],$npj ! np[2] + srlx $car1,32,$car1 + add $tmp1,$car1,$car1 + srlx $car0,32,$car0 + add $acc0,$car1,$car1 + and $car0,1,$sbit + add $acc1,$car1,$car1 + srlx $car0,1,$car0 + mov 12,$j + st $car1,[%sp+$bias+$frame] ! tp[0]= + srlx $car1,32,$car1 + add %sp,$bias+$frame+4,$tp + +.Lsqr_2nd: + mulx $apj,$mul0,$acc0 + mulx $npj,$mul1,$acc1 + add $acc0,$car0,$car0 + add $tpj,$car1,$car1 + ld [$ap+$j],$apj ! ap[j] + and $car0,$mask,$acc0 + ld [$np+$j],$npj ! np[j] + srlx $car0,32,$car0 + add $acc1,$car1,$car1 + ld [$tp+8],$tpj ! tp[j] + add $acc0,$acc0,$acc0 + add $j,4,$j ! j++ + or $sbit,$acc0,$acc0 + srlx $acc0,32,$sbit + and $acc0,$mask,$acc0 + cmp $j,$num + add $acc0,$car1,$car1 + st $car1,[$tp] ! tp[j-1] + srlx $car1,32,$car1 + bl %icc,.Lsqr_2nd + add $tp,4,$tp ! tp++ +!.Lsqr_2nd + + mulx $apj,$mul0,$acc0 + mulx $npj,$mul1,$acc1 + add $acc0,$car0,$car0 + add $tpj,$car1,$car1 + and $car0,$mask,$acc0 + srlx $car0,32,$car0 + add $acc1,$car1,$car1 + add $acc0,$acc0,$acc0 + or $sbit,$acc0,$acc0 + srlx $acc0,32,$sbit + and $acc0,$mask,$acc0 + add $acc0,$car1,$car1 + st $car1,[$tp] ! tp[j-1] + srlx $car1,32,$car1 + + add $car0,$car0,$car0 + or $sbit,$car0,$car0 + add $car0,$car1,$car1 + add $car2,$car1,$car1 + st $car1,[$tp+4] + srlx $car1,32,$car2 + + ld [%sp+$bias+$frame],$tmp1 ! tp[0] + ld [%sp+$bias+$frame+4],$tpj ! tp[1] + ld [$ap+8],$mul0 ! ap[2] + ld [$np],$car1 ! np[0] + ld [$np+4],$npj ! np[1] + mulx $n0,$tmp1,$mul1 + and $mul1,$mask,$mul1 + mov 8,$i + + mulx $mul0,$mul0,$car0 + mulx $car1,$mul1,$car1 + and $car0,$mask,$acc0 + add $tmp1,$car1,$car1 + srlx $car0,32,$car0 + add %sp,$bias+$frame,$tp + srlx $car1,32,$car1 + and $car0,1,$sbit + srlx $car0,1,$car0 + mov 4,$j + +.Lsqr_outer: +.Lsqr_inner1: + mulx $npj,$mul1,$acc1 + add $tpj,$car1,$car1 + add $j,4,$j + ld [$tp+8],$tpj + cmp $j,$i + add $acc1,$car1,$car1 + ld [$np+$j],$npj + st $car1,[$tp] + srlx $car1,32,$car1 + bl %icc,.Lsqr_inner1 + add $tp,4,$tp +!.Lsqr_inner1 + + add $j,4,$j + ld [$ap+$j],$apj ! ap[j] + mulx $npj,$mul1,$acc1 + add $tpj,$car1,$car1 + ld [$np+$j],$npj ! np[j] + add $acc0,$car1,$car1 + ld [$tp+8],$tpj ! tp[j] + add $acc1,$car1,$car1 + st $car1,[$tp] + srlx $car1,32,$car1 + + add $j,4,$j + cmp $j,$num + be,pn %icc,.Lsqr_no_inner2 + add $tp,4,$tp + +.Lsqr_inner2: + mulx $apj,$mul0,$acc0 + mulx $npj,$mul1,$acc1 + add $tpj,$car1,$car1 + add $acc0,$car0,$car0 + ld [$ap+$j],$apj ! ap[j] + and $car0,$mask,$acc0 + ld [$np+$j],$npj ! np[j] + srlx $car0,32,$car0 + add $acc0,$acc0,$acc0 + ld [$tp+8],$tpj ! tp[j] + or $sbit,$acc0,$acc0 + add $j,4,$j ! j++ + srlx $acc0,32,$sbit + and $acc0,$mask,$acc0 + cmp $j,$num + add $acc0,$car1,$car1 + add $acc1,$car1,$car1 + st $car1,[$tp] ! tp[j-1] + srlx $car1,32,$car1 + bl %icc,.Lsqr_inner2 + add $tp,4,$tp ! tp++ + +.Lsqr_no_inner2: + mulx $apj,$mul0,$acc0 + mulx $npj,$mul1,$acc1 + add $tpj,$car1,$car1 + add $acc0,$car0,$car0 + and $car0,$mask,$acc0 + srlx $car0,32,$car0 + add $acc0,$acc0,$acc0 + or $sbit,$acc0,$acc0 + srlx $acc0,32,$sbit + and $acc0,$mask,$acc0 + add $acc0,$car1,$car1 + add $acc1,$car1,$car1 + st $car1,[$tp] ! tp[j-1] + srlx $car1,32,$car1 + + add $car0,$car0,$car0 + or $sbit,$car0,$car0 + add $car0,$car1,$car1 + add $car2,$car1,$car1 + st $car1,[$tp+4] + srlx $car1,32,$car2 + + add $i,4,$i ! i++ + ld [%sp+$bias+$frame],$tmp1 ! tp[0] + ld [%sp+$bias+$frame+4],$tpj ! tp[1] + ld [$ap+$i],$mul0 ! ap[j] + ld [$np],$car1 ! np[0] + ld [$np+4],$npj ! np[1] + mulx $n0,$tmp1,$mul1 + and $mul1,$mask,$mul1 + add $i,4,$tmp0 + + mulx $mul0,$mul0,$car0 + mulx $car1,$mul1,$car1 + and $car0,$mask,$acc0 + add $tmp1,$car1,$car1 + srlx $car0,32,$car0 + add %sp,$bias+$frame,$tp + srlx $car1,32,$car1 + and $car0,1,$sbit + srlx $car0,1,$car0 + + cmp $tmp0,$num ! i" +.align 32 +___ +$code =~ s/\`([^\`]*)\`/eval($1)/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/sparcv9a-mont.pl b/libs/openssl/crypto/bn/asm/sparcv9a-mont.pl new file mode 100755 index 00000000..a14205f2 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/sparcv9a-mont.pl @@ -0,0 +1,882 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# October 2005 +# +# "Teaser" Montgomery multiplication module for UltraSPARC. Why FPU? +# Because unlike integer multiplier, which simply stalls whole CPU, +# FPU is fully pipelined and can effectively emit 48 bit partial +# product every cycle. Why not blended SPARC v9? One can argue that +# making this module dependent on UltraSPARC VIS extension limits its +# binary compatibility. Well yes, it does exclude SPARC64 prior-V(!) +# implementations from compatibility matrix. But the rest, whole Sun +# UltraSPARC family and brand new Fujitsu's SPARC64 V, all support +# VIS extension instructions used in this module. This is considered +# good enough to not care about HAL SPARC64 users [if any] who have +# integer-only pure SPARCv9 module to "fall down" to. + +# USI&II cores currently exhibit uniform 2x improvement [over pre- +# bn_mul_mont codebase] for all key lengths and benchmarks. On USIII +# performance improves few percents for shorter keys and worsens few +# percents for longer keys. This is because USIII integer multiplier +# is >3x faster than USI&II one, which is harder to match [but see +# TODO list below]. It should also be noted that SPARC64 V features +# out-of-order execution, which *might* mean that integer multiplier +# is pipelined, which in turn *might* be impossible to match... On +# additional note, SPARC64 V implements FP Multiply-Add instruction, +# which is perfectly usable in this context... In other words, as far +# as Fujitsu SPARC64 V goes, talk to the author:-) + +# The implementation implies following "non-natural" limitations on +# input arguments: +# - num may not be less than 4; +# - num has to be even; +# Failure to meet either condition has no fatal effects, simply +# doesn't give any performance gain. + +# TODO: +# - modulo-schedule inner loop for better performance (on in-order +# execution core such as UltraSPARC this shall result in further +# noticeable(!) improvement); +# - dedicated squaring procedure[?]; + +###################################################################### +# November 2006 +# +# Modulo-scheduled inner loops allow to interleave floating point and +# integer instructions and minimize Read-After-Write penalties. This +# results in *further* 20-50% perfromance improvement [depending on +# key length, more for longer keys] on USI&II cores and 30-80% - on +# USIII&IV. + +$fname="bn_mul_mont_fpu"; +$bits=32; +for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); } + +if ($bits==64) { + $bias=2047; + $frame=192; +} else { + $bias=0; + $frame=128; # 96 rounded up to largest known cache-line +} +$locals=64; + +# In order to provide for 32-/64-bit ABI duality, I keep integers wider +# than 32 bit in %g1-%g4 and %o0-%o5. %l0-%l7 and %i0-%i5 are used +# exclusively for pointers, indexes and other small values... +# int bn_mul_mont( +$rp="%i0"; # BN_ULONG *rp, +$ap="%i1"; # const BN_ULONG *ap, +$bp="%i2"; # const BN_ULONG *bp, +$np="%i3"; # const BN_ULONG *np, +$n0="%i4"; # const BN_ULONG *n0, +$num="%i5"; # int num); + +$tp="%l0"; # t[num] +$ap_l="%l1"; # a[num],n[num] are smashed to 32-bit words and saved +$ap_h="%l2"; # to these four vectors as double-precision FP values. +$np_l="%l3"; # This way a bunch of fxtods are eliminated in second +$np_h="%l4"; # loop and L1-cache aliasing is minimized... +$i="%l5"; +$j="%l6"; +$mask="%l7"; # 16-bit mask, 0xffff + +$n0="%g4"; # reassigned(!) to "64-bit" register +$carry="%i4"; # %i4 reused(!) for a carry bit + +# FP register naming chart +# +# ..HILO +# dcba +# -------- +# LOa +# LOb +# LOc +# LOd +# HIa +# HIb +# HIc +# HId +# ..a +# ..b +$ba="%f0"; $bb="%f2"; $bc="%f4"; $bd="%f6"; +$na="%f8"; $nb="%f10"; $nc="%f12"; $nd="%f14"; +$alo="%f16"; $alo_="%f17"; $ahi="%f18"; $ahi_="%f19"; +$nlo="%f20"; $nlo_="%f21"; $nhi="%f22"; $nhi_="%f23"; + +$dota="%f24"; $dotb="%f26"; + +$aloa="%f32"; $alob="%f34"; $aloc="%f36"; $alod="%f38"; +$ahia="%f40"; $ahib="%f42"; $ahic="%f44"; $ahid="%f46"; +$nloa="%f48"; $nlob="%f50"; $nloc="%f52"; $nlod="%f54"; +$nhia="%f56"; $nhib="%f58"; $nhic="%f60"; $nhid="%f62"; + +$ASI_FL16_P=0xD2; # magic ASI value to engage 16-bit FP load + +$code=<<___; +.section ".text",#alloc,#execinstr + +.global $fname +.align 32 +$fname: + save %sp,-$frame-$locals,%sp + + cmp $num,4 + bl,a,pn %icc,.Lret + clr %i0 + andcc $num,1,%g0 ! $num has to be even... + bnz,a,pn %icc,.Lret + clr %i0 ! signal "unsupported input value" + + srl $num,1,$num + sethi %hi(0xffff),$mask + ld [%i4+0],$n0 ! $n0 reassigned, remember? + or $mask,%lo(0xffff),$mask + ld [%i4+4],%o0 + sllx %o0,32,%o0 + or %o0,$n0,$n0 ! $n0=n0[1].n0[0] + + sll $num,3,$num ! num*=8 + + add %sp,$bias,%o0 ! real top of stack + sll $num,2,%o1 + add %o1,$num,%o1 ! %o1=num*5 + sub %o0,%o1,%o0 + and %o0,-2048,%o0 ! optimize TLB utilization + sub %o0,$bias,%sp ! alloca(5*num*8) + + rd %asi,%o7 ! save %asi + add %sp,$bias+$frame+$locals,$tp + add $tp,$num,$ap_l + add $ap_l,$num,$ap_l ! [an]p_[lh] point at the vectors' ends ! + add $ap_l,$num,$ap_h + add $ap_h,$num,$np_l + add $np_l,$num,$np_h + + wr %g0,$ASI_FL16_P,%asi ! setup %asi for 16-bit FP loads + + add $rp,$num,$rp ! readjust input pointers to point + add $ap,$num,$ap ! at the ends too... + add $bp,$num,$bp + add $np,$num,$np + + stx %o7,[%sp+$bias+$frame+48] ! save %asi + + sub %g0,$num,$i ! i=-num + sub %g0,$num,$j ! j=-num + + add $ap,$j,%o3 + add $bp,$i,%o4 + + ld [%o3+4],%g1 ! bp[0] + ld [%o3+0],%o0 + ld [%o4+4],%g5 ! ap[0] + sllx %g1,32,%g1 + ld [%o4+0],%o1 + sllx %g5,32,%g5 + or %g1,%o0,%o0 + or %g5,%o1,%o1 + + add $np,$j,%o5 + + mulx %o1,%o0,%o0 ! ap[0]*bp[0] + mulx $n0,%o0,%o0 ! ap[0]*bp[0]*n0 + stx %o0,[%sp+$bias+$frame+0] + + ld [%o3+0],$alo_ ! load a[j] as pair of 32-bit words + fzeros $alo + ld [%o3+4],$ahi_ + fzeros $ahi + ld [%o5+0],$nlo_ ! load n[j] as pair of 32-bit words + fzeros $nlo + ld [%o5+4],$nhi_ + fzeros $nhi + + ! transfer b[i] to FPU as 4x16-bit values + ldda [%o4+2]%asi,$ba + fxtod $alo,$alo + ldda [%o4+0]%asi,$bb + fxtod $ahi,$ahi + ldda [%o4+6]%asi,$bc + fxtod $nlo,$nlo + ldda [%o4+4]%asi,$bd + fxtod $nhi,$nhi + + ! transfer ap[0]*b[0]*n0 to FPU as 4x16-bit values + ldda [%sp+$bias+$frame+6]%asi,$na + fxtod $ba,$ba + ldda [%sp+$bias+$frame+4]%asi,$nb + fxtod $bb,$bb + ldda [%sp+$bias+$frame+2]%asi,$nc + fxtod $bc,$bc + ldda [%sp+$bias+$frame+0]%asi,$nd + fxtod $bd,$bd + + std $alo,[$ap_l+$j] ! save smashed ap[j] in double format + fxtod $na,$na + std $ahi,[$ap_h+$j] + fxtod $nb,$nb + std $nlo,[$np_l+$j] ! save smashed np[j] in double format + fxtod $nc,$nc + std $nhi,[$np_h+$j] + fxtod $nd,$nd + + fmuld $alo,$ba,$aloa + fmuld $nlo,$na,$nloa + fmuld $alo,$bb,$alob + fmuld $nlo,$nb,$nlob + fmuld $alo,$bc,$aloc + faddd $aloa,$nloa,$nloa + fmuld $nlo,$nc,$nloc + fmuld $alo,$bd,$alod + faddd $alob,$nlob,$nlob + fmuld $nlo,$nd,$nlod + fmuld $ahi,$ba,$ahia + faddd $aloc,$nloc,$nloc + fmuld $nhi,$na,$nhia + fmuld $ahi,$bb,$ahib + faddd $alod,$nlod,$nlod + fmuld $nhi,$nb,$nhib + fmuld $ahi,$bc,$ahic + faddd $ahia,$nhia,$nhia + fmuld $nhi,$nc,$nhic + fmuld $ahi,$bd,$ahid + faddd $ahib,$nhib,$nhib + fmuld $nhi,$nd,$nhid + + faddd $ahic,$nhic,$dota ! $nhic + faddd $ahid,$nhid,$dotb ! $nhid + + faddd $nloc,$nhia,$nloc + faddd $nlod,$nhib,$nlod + + fdtox $nloa,$nloa + fdtox $nlob,$nlob + fdtox $nloc,$nloc + fdtox $nlod,$nlod + + std $nloa,[%sp+$bias+$frame+0] + add $j,8,$j + std $nlob,[%sp+$bias+$frame+8] + add $ap,$j,%o4 + std $nloc,[%sp+$bias+$frame+16] + add $np,$j,%o5 + std $nlod,[%sp+$bias+$frame+24] + + ld [%o4+0],$alo_ ! load a[j] as pair of 32-bit words + fzeros $alo + ld [%o4+4],$ahi_ + fzeros $ahi + ld [%o5+0],$nlo_ ! load n[j] as pair of 32-bit words + fzeros $nlo + ld [%o5+4],$nhi_ + fzeros $nhi + + fxtod $alo,$alo + fxtod $ahi,$ahi + fxtod $nlo,$nlo + fxtod $nhi,$nhi + + ldx [%sp+$bias+$frame+0],%o0 + fmuld $alo,$ba,$aloa + ldx [%sp+$bias+$frame+8],%o1 + fmuld $nlo,$na,$nloa + ldx [%sp+$bias+$frame+16],%o2 + fmuld $alo,$bb,$alob + ldx [%sp+$bias+$frame+24],%o3 + fmuld $nlo,$nb,$nlob + + srlx %o0,16,%o7 + std $alo,[$ap_l+$j] ! save smashed ap[j] in double format + fmuld $alo,$bc,$aloc + add %o7,%o1,%o1 + std $ahi,[$ap_h+$j] + faddd $aloa,$nloa,$nloa + fmuld $nlo,$nc,$nloc + srlx %o1,16,%o7 + std $nlo,[$np_l+$j] ! save smashed np[j] in double format + fmuld $alo,$bd,$alod + add %o7,%o2,%o2 + std $nhi,[$np_h+$j] + faddd $alob,$nlob,$nlob + fmuld $nlo,$nd,$nlod + srlx %o2,16,%o7 + fmuld $ahi,$ba,$ahia + add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15] + faddd $aloc,$nloc,$nloc + fmuld $nhi,$na,$nhia + !and %o0,$mask,%o0 + !and %o1,$mask,%o1 + !and %o2,$mask,%o2 + !sllx %o1,16,%o1 + !sllx %o2,32,%o2 + !sllx %o3,48,%o7 + !or %o1,%o0,%o0 + !or %o2,%o0,%o0 + !or %o7,%o0,%o0 ! 64-bit result + srlx %o3,16,%g1 ! 34-bit carry + fmuld $ahi,$bb,$ahib + + faddd $alod,$nlod,$nlod + fmuld $nhi,$nb,$nhib + fmuld $ahi,$bc,$ahic + faddd $ahia,$nhia,$nhia + fmuld $nhi,$nc,$nhic + fmuld $ahi,$bd,$ahid + faddd $ahib,$nhib,$nhib + fmuld $nhi,$nd,$nhid + + faddd $dota,$nloa,$nloa + faddd $dotb,$nlob,$nlob + faddd $ahic,$nhic,$dota ! $nhic + faddd $ahid,$nhid,$dotb ! $nhid + + faddd $nloc,$nhia,$nloc + faddd $nlod,$nhib,$nlod + + fdtox $nloa,$nloa + fdtox $nlob,$nlob + fdtox $nloc,$nloc + fdtox $nlod,$nlod + + std $nloa,[%sp+$bias+$frame+0] + std $nlob,[%sp+$bias+$frame+8] + addcc $j,8,$j + std $nloc,[%sp+$bias+$frame+16] + bz,pn %icc,.L1stskip + std $nlod,[%sp+$bias+$frame+24] + +.align 32 ! incidentally already aligned ! +.L1st: + add $ap,$j,%o4 + add $np,$j,%o5 + ld [%o4+0],$alo_ ! load a[j] as pair of 32-bit words + fzeros $alo + ld [%o4+4],$ahi_ + fzeros $ahi + ld [%o5+0],$nlo_ ! load n[j] as pair of 32-bit words + fzeros $nlo + ld [%o5+4],$nhi_ + fzeros $nhi + + fxtod $alo,$alo + fxtod $ahi,$ahi + fxtod $nlo,$nlo + fxtod $nhi,$nhi + + ldx [%sp+$bias+$frame+0],%o0 + fmuld $alo,$ba,$aloa + ldx [%sp+$bias+$frame+8],%o1 + fmuld $nlo,$na,$nloa + ldx [%sp+$bias+$frame+16],%o2 + fmuld $alo,$bb,$alob + ldx [%sp+$bias+$frame+24],%o3 + fmuld $nlo,$nb,$nlob + + srlx %o0,16,%o7 + std $alo,[$ap_l+$j] ! save smashed ap[j] in double format + fmuld $alo,$bc,$aloc + add %o7,%o1,%o1 + std $ahi,[$ap_h+$j] + faddd $aloa,$nloa,$nloa + fmuld $nlo,$nc,$nloc + srlx %o1,16,%o7 + std $nlo,[$np_l+$j] ! save smashed np[j] in double format + fmuld $alo,$bd,$alod + add %o7,%o2,%o2 + std $nhi,[$np_h+$j] + faddd $alob,$nlob,$nlob + fmuld $nlo,$nd,$nlod + srlx %o2,16,%o7 + fmuld $ahi,$ba,$ahia + add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15] + and %o0,$mask,%o0 + faddd $aloc,$nloc,$nloc + fmuld $nhi,$na,$nhia + and %o1,$mask,%o1 + and %o2,$mask,%o2 + fmuld $ahi,$bb,$ahib + sllx %o1,16,%o1 + faddd $alod,$nlod,$nlod + fmuld $nhi,$nb,$nhib + sllx %o2,32,%o2 + fmuld $ahi,$bc,$ahic + sllx %o3,48,%o7 + or %o1,%o0,%o0 + faddd $ahia,$nhia,$nhia + fmuld $nhi,$nc,$nhic + or %o2,%o0,%o0 + fmuld $ahi,$bd,$ahid + or %o7,%o0,%o0 ! 64-bit result + faddd $ahib,$nhib,$nhib + fmuld $nhi,$nd,$nhid + addcc %g1,%o0,%o0 + faddd $dota,$nloa,$nloa + srlx %o3,16,%g1 ! 34-bit carry + faddd $dotb,$nlob,$nlob + bcs,a %xcc,.+8 + add %g1,1,%g1 + + stx %o0,[$tp] ! tp[j-1]= + + faddd $ahic,$nhic,$dota ! $nhic + faddd $ahid,$nhid,$dotb ! $nhid + + faddd $nloc,$nhia,$nloc + faddd $nlod,$nhib,$nlod + + fdtox $nloa,$nloa + fdtox $nlob,$nlob + fdtox $nloc,$nloc + fdtox $nlod,$nlod + + std $nloa,[%sp+$bias+$frame+0] + std $nlob,[%sp+$bias+$frame+8] + std $nloc,[%sp+$bias+$frame+16] + std $nlod,[%sp+$bias+$frame+24] + + addcc $j,8,$j + bnz,pt %icc,.L1st + add $tp,8,$tp + +.L1stskip: + fdtox $dota,$dota + fdtox $dotb,$dotb + + ldx [%sp+$bias+$frame+0],%o0 + ldx [%sp+$bias+$frame+8],%o1 + ldx [%sp+$bias+$frame+16],%o2 + ldx [%sp+$bias+$frame+24],%o3 + + srlx %o0,16,%o7 + std $dota,[%sp+$bias+$frame+32] + add %o7,%o1,%o1 + std $dotb,[%sp+$bias+$frame+40] + srlx %o1,16,%o7 + add %o7,%o2,%o2 + srlx %o2,16,%o7 + add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15] + and %o0,$mask,%o0 + and %o1,$mask,%o1 + and %o2,$mask,%o2 + sllx %o1,16,%o1 + sllx %o2,32,%o2 + sllx %o3,48,%o7 + or %o1,%o0,%o0 + or %o2,%o0,%o0 + or %o7,%o0,%o0 ! 64-bit result + ldx [%sp+$bias+$frame+32],%o4 + addcc %g1,%o0,%o0 + ldx [%sp+$bias+$frame+40],%o5 + srlx %o3,16,%g1 ! 34-bit carry + bcs,a %xcc,.+8 + add %g1,1,%g1 + + stx %o0,[$tp] ! tp[j-1]= + add $tp,8,$tp + + srlx %o4,16,%o7 + add %o7,%o5,%o5 + and %o4,$mask,%o4 + sllx %o5,16,%o7 + or %o7,%o4,%o4 + addcc %g1,%o4,%o4 + srlx %o5,48,%g1 + bcs,a %xcc,.+8 + add %g1,1,%g1 + + mov %g1,$carry + stx %o4,[$tp] ! tp[num-1]= + + ba .Louter + add $i,8,$i +.align 32 +.Louter: + sub %g0,$num,$j ! j=-num + add %sp,$bias+$frame+$locals,$tp + + add $ap,$j,%o3 + add $bp,$i,%o4 + + ld [%o3+4],%g1 ! bp[i] + ld [%o3+0],%o0 + ld [%o4+4],%g5 ! ap[0] + sllx %g1,32,%g1 + ld [%o4+0],%o1 + sllx %g5,32,%g5 + or %g1,%o0,%o0 + or %g5,%o1,%o1 + + ldx [$tp],%o2 ! tp[0] + mulx %o1,%o0,%o0 + addcc %o2,%o0,%o0 + mulx $n0,%o0,%o0 ! (ap[0]*bp[i]+t[0])*n0 + stx %o0,[%sp+$bias+$frame+0] + + ! transfer b[i] to FPU as 4x16-bit values + ldda [%o4+2]%asi,$ba + ldda [%o4+0]%asi,$bb + ldda [%o4+6]%asi,$bc + ldda [%o4+4]%asi,$bd + + ! transfer (ap[0]*b[i]+t[0])*n0 to FPU as 4x16-bit values + ldda [%sp+$bias+$frame+6]%asi,$na + fxtod $ba,$ba + ldda [%sp+$bias+$frame+4]%asi,$nb + fxtod $bb,$bb + ldda [%sp+$bias+$frame+2]%asi,$nc + fxtod $bc,$bc + ldda [%sp+$bias+$frame+0]%asi,$nd + fxtod $bd,$bd + ldd [$ap_l+$j],$alo ! load a[j] in double format + fxtod $na,$na + ldd [$ap_h+$j],$ahi + fxtod $nb,$nb + ldd [$np_l+$j],$nlo ! load n[j] in double format + fxtod $nc,$nc + ldd [$np_h+$j],$nhi + fxtod $nd,$nd + + fmuld $alo,$ba,$aloa + fmuld $nlo,$na,$nloa + fmuld $alo,$bb,$alob + fmuld $nlo,$nb,$nlob + fmuld $alo,$bc,$aloc + faddd $aloa,$nloa,$nloa + fmuld $nlo,$nc,$nloc + fmuld $alo,$bd,$alod + faddd $alob,$nlob,$nlob + fmuld $nlo,$nd,$nlod + fmuld $ahi,$ba,$ahia + faddd $aloc,$nloc,$nloc + fmuld $nhi,$na,$nhia + fmuld $ahi,$bb,$ahib + faddd $alod,$nlod,$nlod + fmuld $nhi,$nb,$nhib + fmuld $ahi,$bc,$ahic + faddd $ahia,$nhia,$nhia + fmuld $nhi,$nc,$nhic + fmuld $ahi,$bd,$ahid + faddd $ahib,$nhib,$nhib + fmuld $nhi,$nd,$nhid + + faddd $ahic,$nhic,$dota ! $nhic + faddd $ahid,$nhid,$dotb ! $nhid + + faddd $nloc,$nhia,$nloc + faddd $nlod,$nhib,$nlod + + fdtox $nloa,$nloa + fdtox $nlob,$nlob + fdtox $nloc,$nloc + fdtox $nlod,$nlod + + std $nloa,[%sp+$bias+$frame+0] + std $nlob,[%sp+$bias+$frame+8] + std $nloc,[%sp+$bias+$frame+16] + add $j,8,$j + std $nlod,[%sp+$bias+$frame+24] + + ldd [$ap_l+$j],$alo ! load a[j] in double format + ldd [$ap_h+$j],$ahi + ldd [$np_l+$j],$nlo ! load n[j] in double format + ldd [$np_h+$j],$nhi + + fmuld $alo,$ba,$aloa + fmuld $nlo,$na,$nloa + fmuld $alo,$bb,$alob + fmuld $nlo,$nb,$nlob + fmuld $alo,$bc,$aloc + ldx [%sp+$bias+$frame+0],%o0 + faddd $aloa,$nloa,$nloa + fmuld $nlo,$nc,$nloc + ldx [%sp+$bias+$frame+8],%o1 + fmuld $alo,$bd,$alod + ldx [%sp+$bias+$frame+16],%o2 + faddd $alob,$nlob,$nlob + fmuld $nlo,$nd,$nlod + ldx [%sp+$bias+$frame+24],%o3 + fmuld $ahi,$ba,$ahia + + srlx %o0,16,%o7 + faddd $aloc,$nloc,$nloc + fmuld $nhi,$na,$nhia + add %o7,%o1,%o1 + fmuld $ahi,$bb,$ahib + srlx %o1,16,%o7 + faddd $alod,$nlod,$nlod + fmuld $nhi,$nb,$nhib + add %o7,%o2,%o2 + fmuld $ahi,$bc,$ahic + srlx %o2,16,%o7 + faddd $ahia,$nhia,$nhia + fmuld $nhi,$nc,$nhic + add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15] + ! why? + and %o0,$mask,%o0 + fmuld $ahi,$bd,$ahid + and %o1,$mask,%o1 + and %o2,$mask,%o2 + faddd $ahib,$nhib,$nhib + fmuld $nhi,$nd,$nhid + sllx %o1,16,%o1 + faddd $dota,$nloa,$nloa + sllx %o2,32,%o2 + faddd $dotb,$nlob,$nlob + sllx %o3,48,%o7 + or %o1,%o0,%o0 + faddd $ahic,$nhic,$dota ! $nhic + or %o2,%o0,%o0 + faddd $ahid,$nhid,$dotb ! $nhid + or %o7,%o0,%o0 ! 64-bit result + ldx [$tp],%o7 + faddd $nloc,$nhia,$nloc + addcc %o7,%o0,%o0 + ! end-of-why? + faddd $nlod,$nhib,$nlod + srlx %o3,16,%g1 ! 34-bit carry + fdtox $nloa,$nloa + bcs,a %xcc,.+8 + add %g1,1,%g1 + + fdtox $nlob,$nlob + fdtox $nloc,$nloc + fdtox $nlod,$nlod + + std $nloa,[%sp+$bias+$frame+0] + std $nlob,[%sp+$bias+$frame+8] + addcc $j,8,$j + std $nloc,[%sp+$bias+$frame+16] + bz,pn %icc,.Linnerskip + std $nlod,[%sp+$bias+$frame+24] + + ba .Linner + nop +.align 32 +.Linner: + ldd [$ap_l+$j],$alo ! load a[j] in double format + ldd [$ap_h+$j],$ahi + ldd [$np_l+$j],$nlo ! load n[j] in double format + ldd [$np_h+$j],$nhi + + fmuld $alo,$ba,$aloa + fmuld $nlo,$na,$nloa + fmuld $alo,$bb,$alob + fmuld $nlo,$nb,$nlob + fmuld $alo,$bc,$aloc + ldx [%sp+$bias+$frame+0],%o0 + faddd $aloa,$nloa,$nloa + fmuld $nlo,$nc,$nloc + ldx [%sp+$bias+$frame+8],%o1 + fmuld $alo,$bd,$alod + ldx [%sp+$bias+$frame+16],%o2 + faddd $alob,$nlob,$nlob + fmuld $nlo,$nd,$nlod + ldx [%sp+$bias+$frame+24],%o3 + fmuld $ahi,$ba,$ahia + + srlx %o0,16,%o7 + faddd $aloc,$nloc,$nloc + fmuld $nhi,$na,$nhia + add %o7,%o1,%o1 + fmuld $ahi,$bb,$ahib + srlx %o1,16,%o7 + faddd $alod,$nlod,$nlod + fmuld $nhi,$nb,$nhib + add %o7,%o2,%o2 + fmuld $ahi,$bc,$ahic + srlx %o2,16,%o7 + faddd $ahia,$nhia,$nhia + fmuld $nhi,$nc,$nhic + add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15] + and %o0,$mask,%o0 + fmuld $ahi,$bd,$ahid + and %o1,$mask,%o1 + and %o2,$mask,%o2 + faddd $ahib,$nhib,$nhib + fmuld $nhi,$nd,$nhid + sllx %o1,16,%o1 + faddd $dota,$nloa,$nloa + sllx %o2,32,%o2 + faddd $dotb,$nlob,$nlob + sllx %o3,48,%o7 + or %o1,%o0,%o0 + faddd $ahic,$nhic,$dota ! $nhic + or %o2,%o0,%o0 + faddd $ahid,$nhid,$dotb ! $nhid + or %o7,%o0,%o0 ! 64-bit result + faddd $nloc,$nhia,$nloc + addcc %g1,%o0,%o0 + ldx [$tp+8],%o7 ! tp[j] + faddd $nlod,$nhib,$nlod + srlx %o3,16,%g1 ! 34-bit carry + fdtox $nloa,$nloa + bcs,a %xcc,.+8 + add %g1,1,%g1 + fdtox $nlob,$nlob + addcc %o7,%o0,%o0 + fdtox $nloc,$nloc + bcs,a %xcc,.+8 + add %g1,1,%g1 + + stx %o0,[$tp] ! tp[j-1] + fdtox $nlod,$nlod + + std $nloa,[%sp+$bias+$frame+0] + std $nlob,[%sp+$bias+$frame+8] + std $nloc,[%sp+$bias+$frame+16] + addcc $j,8,$j + std $nlod,[%sp+$bias+$frame+24] + bnz,pt %icc,.Linner + add $tp,8,$tp + +.Linnerskip: + fdtox $dota,$dota + fdtox $dotb,$dotb + + ldx [%sp+$bias+$frame+0],%o0 + ldx [%sp+$bias+$frame+8],%o1 + ldx [%sp+$bias+$frame+16],%o2 + ldx [%sp+$bias+$frame+24],%o3 + + srlx %o0,16,%o7 + std $dota,[%sp+$bias+$frame+32] + add %o7,%o1,%o1 + std $dotb,[%sp+$bias+$frame+40] + srlx %o1,16,%o7 + add %o7,%o2,%o2 + srlx %o2,16,%o7 + add %o7,%o3,%o3 ! %o3.%o2[0..15].%o1[0..15].%o0[0..15] + and %o0,$mask,%o0 + and %o1,$mask,%o1 + and %o2,$mask,%o2 + sllx %o1,16,%o1 + sllx %o2,32,%o2 + sllx %o3,48,%o7 + or %o1,%o0,%o0 + or %o2,%o0,%o0 + ldx [%sp+$bias+$frame+32],%o4 + or %o7,%o0,%o0 ! 64-bit result + ldx [%sp+$bias+$frame+40],%o5 + addcc %g1,%o0,%o0 + ldx [$tp+8],%o7 ! tp[j] + srlx %o3,16,%g1 ! 34-bit carry + bcs,a %xcc,.+8 + add %g1,1,%g1 + + addcc %o7,%o0,%o0 + bcs,a %xcc,.+8 + add %g1,1,%g1 + + stx %o0,[$tp] ! tp[j-1] + add $tp,8,$tp + + srlx %o4,16,%o7 + add %o7,%o5,%o5 + and %o4,$mask,%o4 + sllx %o5,16,%o7 + or %o7,%o4,%o4 + addcc %g1,%o4,%o4 + srlx %o5,48,%g1 + bcs,a %xcc,.+8 + add %g1,1,%g1 + + addcc $carry,%o4,%o4 + stx %o4,[$tp] ! tp[num-1] + mov %g1,$carry + bcs,a %xcc,.+8 + add $carry,1,$carry + + addcc $i,8,$i + bnz %icc,.Louter + nop + + add $tp,8,$tp ! adjust tp to point at the end + orn %g0,%g0,%g4 + sub %g0,$num,%o7 ! n=-num + ba .Lsub + subcc %g0,%g0,%g0 ! clear %icc.c + +.align 32 +.Lsub: + ldx [$tp+%o7],%o0 + add $np,%o7,%g1 + ld [%g1+0],%o2 + ld [%g1+4],%o3 + srlx %o0,32,%o1 + subccc %o0,%o2,%o2 + add $rp,%o7,%g1 + subccc %o1,%o3,%o3 + st %o2,[%g1+0] + add %o7,8,%o7 + brnz,pt %o7,.Lsub + st %o3,[%g1+4] + subc $carry,0,%g4 + sub %g0,$num,%o7 ! n=-num + ba .Lcopy + nop + +.align 32 +.Lcopy: + ldx [$tp+%o7],%o0 + add $rp,%o7,%g1 + ld [%g1+0],%o2 + ld [%g1+4],%o3 + stx %g0,[$tp+%o7] + and %o0,%g4,%o0 + srlx %o0,32,%o1 + andn %o2,%g4,%o2 + andn %o3,%g4,%o3 + or %o2,%o0,%o0 + or %o3,%o1,%o1 + st %o0,[%g1+0] + add %o7,8,%o7 + brnz,pt %o7,.Lcopy + st %o1,[%g1+4] + sub %g0,$num,%o7 ! n=-num + +.Lzap: + stx %g0,[$ap_l+%o7] + stx %g0,[$ap_h+%o7] + stx %g0,[$np_l+%o7] + stx %g0,[$np_h+%o7] + add %o7,8,%o7 + brnz,pt %o7,.Lzap + nop + + ldx [%sp+$bias+$frame+48],%o7 + wr %g0,%o7,%asi ! restore %asi + + mov 1,%i0 +.Lret: + ret + restore +.type $fname,#function +.size $fname,(.-$fname) +.asciz "Montgomery Multipltication for UltraSPARC, CRYPTOGAMS by " +.align 32 +___ + +$code =~ s/\`([^\`]*)\`/eval($1)/gem; + +# Below substitution makes it possible to compile without demanding +# VIS extentions on command line, e.g. -xarch=v9 vs. -xarch=v9a. I +# dare to do this, because VIS capability is detected at run-time now +# and this routine is not called on CPU not capable to execute it. Do +# note that fzeros is not the only VIS dependency! Another dependency +# is implicit and is just _a_ numerical value loaded to %asi register, +# which assembler can't recognize as VIS specific... +$code =~ s/fzeros\s+%f([0-9]+)/ + sprintf(".word\t0x%x\t! fzeros %%f%d",0x81b00c20|($1<<25),$1) + /gem; + +print $code; +# flush +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/via-mont.pl b/libs/openssl/crypto/bn/asm/via-mont.pl new file mode 100644 index 00000000..c046a514 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/via-mont.pl @@ -0,0 +1,242 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# Wrapper around 'rep montmul', VIA-specific instruction accessing +# PadLock Montgomery Multiplier. The wrapper is designed as drop-in +# replacement for OpenSSL bn_mul_mont [first implemented in 0.9.9]. +# +# Below are interleaved outputs from 'openssl speed rsa dsa' for 4 +# different software configurations on 1.5GHz VIA Esther processor. +# Lines marked with "software integer" denote performance of hand- +# coded integer-only assembler found in OpenSSL 0.9.7. "Software SSE2" +# refers to hand-coded SSE2 Montgomery multiplication procedure found +# OpenSSL 0.9.9. "Hardware VIA SDK" refers to padlock_pmm routine from +# Padlock SDK 2.0.1 available for download from VIA, which naturally +# utilizes the magic 'repz montmul' instruction. And finally "hardware +# this" refers to *this* implementation which also uses 'repz montmul' +# +# sign verify sign/s verify/s +# rsa 512 bits 0.001720s 0.000140s 581.4 7149.7 software integer +# rsa 512 bits 0.000690s 0.000086s 1450.3 11606.0 software SSE2 +# rsa 512 bits 0.006136s 0.000201s 163.0 4974.5 hardware VIA SDK +# rsa 512 bits 0.000712s 0.000050s 1404.9 19858.5 hardware this +# +# rsa 1024 bits 0.008518s 0.000413s 117.4 2420.8 software integer +# rsa 1024 bits 0.004275s 0.000277s 233.9 3609.7 software SSE2 +# rsa 1024 bits 0.012136s 0.000260s 82.4 3844.5 hardware VIA SDK +# rsa 1024 bits 0.002522s 0.000116s 396.5 8650.9 hardware this +# +# rsa 2048 bits 0.050101s 0.001371s 20.0 729.6 software integer +# rsa 2048 bits 0.030273s 0.001008s 33.0 991.9 software SSE2 +# rsa 2048 bits 0.030833s 0.000976s 32.4 1025.1 hardware VIA SDK +# rsa 2048 bits 0.011879s 0.000342s 84.2 2921.7 hardware this +# +# rsa 4096 bits 0.327097s 0.004859s 3.1 205.8 software integer +# rsa 4096 bits 0.229318s 0.003859s 4.4 259.2 software SSE2 +# rsa 4096 bits 0.233953s 0.003274s 4.3 305.4 hardware VIA SDK +# rsa 4096 bits 0.070493s 0.001166s 14.2 857.6 hardware this +# +# dsa 512 bits 0.001342s 0.001651s 745.2 605.7 software integer +# dsa 512 bits 0.000844s 0.000987s 1185.3 1013.1 software SSE2 +# dsa 512 bits 0.001902s 0.002247s 525.6 444.9 hardware VIA SDK +# dsa 512 bits 0.000458s 0.000524s 2182.2 1909.1 hardware this +# +# dsa 1024 bits 0.003964s 0.004926s 252.3 203.0 software integer +# dsa 1024 bits 0.002686s 0.003166s 372.3 315.8 software SSE2 +# dsa 1024 bits 0.002397s 0.002823s 417.1 354.3 hardware VIA SDK +# dsa 1024 bits 0.000978s 0.001170s 1022.2 855.0 hardware this +# +# dsa 2048 bits 0.013280s 0.016518s 75.3 60.5 software integer +# dsa 2048 bits 0.009911s 0.011522s 100.9 86.8 software SSE2 +# dsa 2048 bits 0.009542s 0.011763s 104.8 85.0 hardware VIA SDK +# dsa 2048 bits 0.002884s 0.003352s 346.8 298.3 hardware this +# +# To give you some other reference point here is output for 2.4GHz P4 +# running hand-coded SSE2 bn_mul_mont found in 0.9.9, i.e. "software +# SSE2" in above terms. +# +# rsa 512 bits 0.000407s 0.000047s 2454.2 21137.0 +# rsa 1024 bits 0.002426s 0.000141s 412.1 7100.0 +# rsa 2048 bits 0.015046s 0.000491s 66.5 2034.9 +# rsa 4096 bits 0.109770s 0.002379s 9.1 420.3 +# dsa 512 bits 0.000438s 0.000525s 2281.1 1904.1 +# dsa 1024 bits 0.001346s 0.001595s 742.7 627.0 +# dsa 2048 bits 0.004745s 0.005582s 210.7 179.1 +# +# Conclusions: +# - VIA SDK leaves a *lot* of room for improvement (which this +# implementation successfully fills:-); +# - 'rep montmul' gives up to >3x performance improvement depending on +# key length; +# - in terms of absolute performance it delivers approximately as much +# as modern out-of-order 32-bit cores [again, for longer keys]. + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"via-mont.pl"); + +# int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np,const BN_ULONG *n0, int num); +$func="bn_mul_mont_padlock"; + +$pad=16*1; # amount of reserved bytes on top of every vector + +# stack layout +$mZeroPrime=&DWP(0,"esp"); # these are specified by VIA +$A=&DWP(4,"esp"); +$B=&DWP(8,"esp"); +$T=&DWP(12,"esp"); +$M=&DWP(16,"esp"); +$scratch=&DWP(20,"esp"); +$rp=&DWP(24,"esp"); # these are mine +$sp=&DWP(28,"esp"); +# &DWP(32,"esp") # 32 byte scratch area +# &DWP(64+(4*$num+$pad)*0,"esp") # padded tp[num] +# &DWP(64+(4*$num+$pad)*1,"esp") # padded copy of ap[num] +# &DWP(64+(4*$num+$pad)*2,"esp") # padded copy of bp[num] +# &DWP(64+(4*$num+$pad)*3,"esp") # padded copy of np[num] +# Note that SDK suggests to unconditionally allocate 2K per vector. This +# has quite an impact on performance. It naturally depends on key length, +# but to give an example 1024 bit private RSA key operations suffer >30% +# penalty. I allocate only as much as actually required... + +&function_begin($func); + &xor ("eax","eax"); + &mov ("ecx",&wparam(5)); # num + # meet VIA's limitations for num [note that the specification + # expresses them in bits, while we work with amount of 32-bit words] + &test ("ecx",3); + &jnz (&label("leave")); # num % 4 != 0 + &cmp ("ecx",8); + &jb (&label("leave")); # num < 8 + &cmp ("ecx",1024); + &ja (&label("leave")); # num > 1024 + + &pushf (); + &cld (); + + &mov ("edi",&wparam(0)); # rp + &mov ("eax",&wparam(1)); # ap + &mov ("ebx",&wparam(2)); # bp + &mov ("edx",&wparam(3)); # np + &mov ("esi",&wparam(4)); # n0 + &mov ("esi",&DWP(0,"esi")); # *n0 + + &lea ("ecx",&DWP($pad,"","ecx",4)); # ecx becomes vector size in bytes + &lea ("ebp",&DWP(64,"","ecx",4)); # allocate 4 vectors + 64 bytes + &neg ("ebp"); + &add ("ebp","esp"); + &and ("ebp",-64); # align to cache-line + &xchg ("ebp","esp"); # alloca + + &mov ($rp,"edi"); # save rp + &mov ($sp,"ebp"); # save esp + + &mov ($mZeroPrime,"esi"); + &lea ("esi",&DWP(64,"esp")); # tp + &mov ($T,"esi"); + &lea ("edi",&DWP(32,"esp")); # scratch area + &mov ($scratch,"edi"); + &mov ("esi","eax"); + + &lea ("ebp",&DWP(-$pad,"ecx")); + &shr ("ebp",2); # restore original num value in ebp + + &xor ("eax","eax"); + + &mov ("ecx","ebp"); + &lea ("ecx",&DWP((32+$pad)/4,"ecx"));# padded tp + scratch + &data_byte(0xf3,0xab); # rep stosl, bzero + + &mov ("ecx","ebp"); + &lea ("edi",&DWP(64+$pad,"esp","ecx",4));# pointer to ap copy + &mov ($A,"edi"); + &data_byte(0xf3,0xa5); # rep movsl, memcpy + &mov ("ecx",$pad/4); + &data_byte(0xf3,0xab); # rep stosl, bzero pad + # edi points at the end of padded ap copy... + + &mov ("ecx","ebp"); + &mov ("esi","ebx"); + &mov ($B,"edi"); + &data_byte(0xf3,0xa5); # rep movsl, memcpy + &mov ("ecx",$pad/4); + &data_byte(0xf3,0xab); # rep stosl, bzero pad + # edi points at the end of padded bp copy... + + &mov ("ecx","ebp"); + &mov ("esi","edx"); + &mov ($M,"edi"); + &data_byte(0xf3,0xa5); # rep movsl, memcpy + &mov ("ecx",$pad/4); + &data_byte(0xf3,0xab); # rep stosl, bzero pad + # edi points at the end of padded np copy... + + # let magic happen... + &mov ("ecx","ebp"); + &mov ("esi","esp"); + &shl ("ecx",5); # convert word counter to bit counter + &align (4); + &data_byte(0xf3,0x0f,0xa6,0xc0);# rep montmul + + &mov ("ecx","ebp"); + &lea ("esi",&DWP(64,"esp")); # tp + # edi still points at the end of padded np copy... + &neg ("ebp"); + &lea ("ebp",&DWP(-$pad,"edi","ebp",4)); # so just "rewind" + &mov ("edi",$rp); # restore rp + &xor ("edx","edx"); # i=0 and clear CF + +&set_label("sub",8); + &mov ("eax",&DWP(0,"esi","edx",4)); + &sbb ("eax",&DWP(0,"ebp","edx",4)); + &mov (&DWP(0,"edi","edx",4),"eax"); # rp[i]=tp[i]-np[i] + &lea ("edx",&DWP(1,"edx")); # i++ + &loop (&label("sub")); # doesn't affect CF! + + &mov ("eax",&DWP(0,"esi","edx",4)); # upmost overflow bit + &sbb ("eax",0); + &and ("esi","eax"); + ¬ ("eax"); + &mov ("ebp","edi"); + &and ("ebp","eax"); + &or ("esi","ebp"); # tp=carry?tp:rp + + &mov ("ecx","edx"); # num + &xor ("edx","edx"); # i=0 + +&set_label("copy",8); + &mov ("eax",&DWP(0,"esi","edx",4)); + &mov (&DWP(64,"esp","edx",4),"ecx"); # zap tp + &mov (&DWP(0,"edi","edx",4),"eax"); + &lea ("edx",&DWP(1,"edx")); # i++ + &loop (&label("copy")); + + &mov ("ebp",$sp); + &xor ("eax","eax"); + + &mov ("ecx",64/4); + &mov ("edi","esp"); # zap frame including scratch area + &data_byte(0xf3,0xab); # rep stosl, bzero + + # zap copies of ap, bp and np + &lea ("edi",&DWP(64+$pad,"esp","edx",4));# pointer to ap + &lea ("ecx",&DWP(3*$pad/4,"edx","edx",2)); + &data_byte(0xf3,0xab); # rep stosl, bzero + + &mov ("esp","ebp"); + &inc ("eax"); # signal "done" + &popf (); +&set_label("leave"); +&function_end($func); + +&asciz("Padlock Montgomery Multiplication, CRYPTOGAMS by "); + +&asm_finish(); diff --git a/libs/openssl/crypto/bn/asm/vms.mar b/libs/openssl/crypto/bn/asm/vms.mar new file mode 100644 index 00000000..aefab15c --- /dev/null +++ b/libs/openssl/crypto/bn/asm/vms.mar @@ -0,0 +1,6440 @@ + .title vax_bn_mul_add_words unsigned multiply & add, 32*32+32+32=>64 +; +; w.j.m. 15-jan-1999 +; +; it's magic ... +; +; ULONG bn_mul_add_words(ULONG r[],ULONG a[],int n,ULONG w) { +; ULONG c = 0; +; int i; +; for(i = 0; i < n; i++) := r[i] + c + a[i] * w ; +; return c; +; } + +r=4 ;(AP) +a=8 ;(AP) +n=12 ;(AP) n by value (input) +w=16 ;(AP) w by value (input) + + + .psect code,nowrt + +.entry bn_mul_add_words,^m + + moval @r(ap),r2 + moval @a(ap),r3 + movl n(ap),r4 ; assumed >0 by C code + movl w(ap),r5 + clrl r6 ; c + +0$: + emul r5,(r3),(r2),r0 ; w, a[], r[] considered signed + + ; fixup for "negative" r[] + tstl (r2) + bgeq 10$ + incl r1 +10$: + + ; add in c + addl2 r6,r0 + adwc #0,r1 + + ; combined fixup for "negative" w, a[] + tstl r5 + bgeq 20$ + addl2 (r3),r1 +20$: + tstl (r3) + bgeq 30$ + addl2 r5,r1 +30$: + + movl r0,(r2)+ ; store lo result in r[] & advance + addl #4,r3 ; advance a[] + movl r1,r6 ; store hi result => c + + sobgtr r4,0$ + + movl r6,r0 ; return c + ret + + .title vax_bn_mul_words unsigned multiply & add, 32*32+32=>64 +; +; w.j.m. 15-jan-1999 +; +; it's magic ... +; +; ULONG bn_mul_words(ULONG r[],ULONG a[],int n,ULONG w) { +; ULONG c = 0; +; int i; +; for(i = 0; i < num; i++) := a[i] * w + c ; +; return(c); +; } + +r=4 ;(AP) +a=8 ;(AP) +n=12 ;(AP) n by value (input) +w=16 ;(AP) w by value (input) + + + .psect code,nowrt + +.entry bn_mul_words,^m + + moval @r(ap),r2 ; r2 -> r[] + moval @a(ap),r3 ; r3 -> a[] + movl n(ap),r4 ; r4 = loop count (assumed >0 by C code) + movl w(ap),r5 ; r5 = w + clrl r6 ; r6 = c + +0$: + ; := w * a[] + c + emul r5,(r3),r6,r0 ; w, a[], c considered signed + + ; fixup for "negative" c + tstl r6 ; c + bgeq 10$ + incl r1 +10$: + + ; combined fixup for "negative" w, a[] + tstl r5 ; w + bgeq 20$ + addl2 (r3),r1 ; a[] +20$: + tstl (r3) ; a[] + bgeq 30$ + addl2 r5,r1 ; w +30$: + + movl r0,(r2)+ ; store lo result in r[] & advance + addl #4,r3 ; advance a[] + movl r1,r6 ; store hi result => c + + sobgtr r4,0$ + + movl r6,r0 ; return c + ret + + .title vax_bn_sqr_words unsigned square, 32*32=>64 +; +; w.j.m. 15-jan-1999 +; +; it's magic ... +; +; void bn_sqr_words(ULONG r[],ULONG a[],int n) { +; int i; +; for(i = 0; i < n; i++) := a[i] * a[i] ; +; } + +r=4 ;(AP) +a=8 ;(AP) +n=12 ;(AP) n by value (input) + + + .psect code,nowrt + +.entry bn_sqr_words,^m + + moval @r(ap),r2 ; r2 -> r[] + moval @a(ap),r3 ; r3 -> a[] + movl n(ap),r4 ; r4 = n (assumed >0 by C code) + +0$: + movl (r3)+,r5 ; r5 = a[] & advance + + ; := a[] * a[] + emul r5,r5,#0,r0 ; a[] considered signed + + ; fixup for "negative" a[] + tstl r5 ; a[] + bgeq 30$ + addl2 r5,r1 ; a[] + addl2 r5,r1 ; a[] +30$: + + movl r0,(r2)+ ; store lo result in r[] & advance + movl r1,(r2)+ ; store hi result in r[] & advance + + sobgtr r4,0$ + + movl #1,r0 ; return SS$_NORMAL + ret + + .title vax_bn_div_words unsigned divide +; +; Richard Levitte 20-Nov-2000 +; +; ULONG bn_div_words(ULONG h, ULONG l, ULONG d) +; { +; return ((ULONG)((((ULLONG)h)<<32)|l) / (ULLONG)d); +; } +; +; Using EDIV would be very easy, if it didn't do signed calculations. +; Any time any of the input numbers are signed, there are problems, +; usually with integer overflow, at which point it returns useless +; data (the quotient gets the value of l, and the remainder becomes 0). +; +; If it was just for the dividend, it would be very easy, just divide +; it by 2 (unsigned), do the division, multiply the resulting quotient +; and remainder by 2, add the bit that was dropped when dividing by 2 +; to the remainder, and do some adjustment so the remainder doesn't +; end up larger than the divisor. For some cases when the divisor is +; negative (from EDIV's point of view, i.e. when the highest bit is set), +; dividing the dividend by 2 isn't enough, and since some operations +; might generate integer overflows even when the dividend is divided by +; 4 (when the high part of the shifted down dividend ends up being exactly +; half of the divisor, the result is the quotient 0x80000000, which is +; negative...) it needs to be divided by 8. Furthermore, the divisor needs +; to be divided by 2 (unsigned) as well, to avoid more problems with the sign. +; In this case, a little extra fiddling with the remainder is required. +; +; So, the simplest way to handle this is always to divide the dividend +; by 8, and to divide the divisor by 2 if it's highest bit is set. +; After EDIV has been used, the quotient gets multiplied by 8 if the +; original divisor was positive, otherwise 4. The remainder, oddly +; enough, is *always* multiplied by 8. +; NOTE: in the case mentioned above, where the high part of the shifted +; down dividend ends up being exactly half the shifted down divisor, we +; end up with a 33 bit quotient. That's no problem however, it usually +; means we have ended up with a too large remainder as well, and the +; problem is fixed by the last part of the algorithm (next paragraph). +; +; The routine ends with comparing the resulting remainder with the +; original divisor and if the remainder is larger, subtract the +; original divisor from it, and increase the quotient by 1. This is +; done until the remainder is smaller than the divisor. +; +; The complete algorithm looks like this: +; +; d' = d +; l' = l & 7 +; [h,l] = [h,l] >> 3 +; [q,r] = floor([h,l] / d) # This is the EDIV operation +; if (q < 0) q = -q # I doubt this is necessary any more +; +; r' = r >> 29 +; if (d' >= 0) +; q' = q >> 29 +; q = q << 3 +; else +; q' = q >> 30 +; q = q << 2 +; r = (r << 3) + l' +; +; if (d' < 0) +; { +; [r',r] = [r',r] - q +; while ([r',r] < 0) +; { +; [r',r] = [r',r] + d +; [q',q] = [q',q] - 1 +; } +; } +; +; while ([r',r] >= d') +; { +; [r',r] = [r',r] - d' +; [q',q] = [q',q] + 1 +; } +; +; return q + +h=4 ;(AP) h by value (input) +l=8 ;(AP) l by value (input) +d=12 ;(AP) d by value (input) + +;r2 = l, q +;r3 = h, r +;r4 = d +;r5 = l' +;r6 = r' +;r7 = d' +;r8 = q' + + .psect code,nowrt + +.entry bn_div_words,^m + movl l(ap),r2 + movl h(ap),r3 + movl d(ap),r4 + + bicl3 #^XFFFFFFF8,r2,r5 ; l' = l & 7 + bicl3 #^X00000007,r2,r2 + + bicl3 #^XFFFFFFF8,r3,r6 + bicl3 #^X00000007,r3,r3 + + addl r6,r2 + + rotl #-3,r2,r2 ; l = l >> 3 + rotl #-3,r3,r3 ; h = h >> 3 + + movl r4,r7 ; d' = d + + movl #0,r6 ; r' = 0 + movl #0,r8 ; q' = 0 + + tstl r4 + beql 666$ ; Uh-oh, the divisor is 0... + bgtr 1$ + rotl #-1,r4,r4 ; If d is negative, shift it right. + bicl2 #^X80000000,r4 ; Since d is then a large number, the + ; lowest bit is insignificant + ; (contradict that, and I'll fix the problem!) +1$: + ediv r4,r2,r2,r3 ; Do the actual division + + tstl r2 + bgeq 3$ + mnegl r2,r2 ; if q < 0, negate it +3$: + tstl r7 + blss 4$ + rotl #3,r2,r2 ; q = q << 3 + bicl3 #^XFFFFFFF8,r2,r8 ; q' gets the high bits from q + bicl3 #^X00000007,r2,r2 + bsb 41$ +4$: ; else + rotl #2,r2,r2 ; q = q << 2 + bicl3 #^XFFFFFFFC,r2,r8 ; q' gets the high bits from q + bicl3 #^X00000003,r2,r2 +41$: + rotl #3,r3,r3 ; r = r << 3 + bicl3 #^XFFFFFFF8,r3,r6 ; r' gets the high bits from r + bicl3 #^X00000007,r3,r3 + addl r5,r3 ; r = r + l' + + tstl r7 + bgeq 5$ + bitl #1,r7 + beql 5$ ; if d' < 0 && d' & 1 + subl r2,r3 ; [r',r] = [r',r] - [q',q] + sbwc r8,r6 +45$: + bgeq 5$ ; while r < 0 + decl r2 ; [q',q] = [q',q] - 1 + sbwc #0,r8 + addl r7,r3 ; [r',r] = [r',r] + d' + adwc #0,r6 + brb 45$ + +; The return points are placed in the middle to keep a short distance from +; all the branch points +42$: +; movl r3,r1 + movl r2,r0 + ret +666$: + movl #^XFFFFFFFF,r0 + ret + +5$: + tstl r6 + bneq 6$ + cmpl r3,r7 + blssu 42$ ; while [r',r] >= d' +6$: + subl r7,r3 ; [r',r] = [r',r] - d' + sbwc #0,r6 + incl r2 ; [q',q] = [q',q] + 1 + adwc #0,r8 + brb 5$ + + .title vax_bn_add_words unsigned add of two arrays +; +; Richard Levitte 20-Nov-2000 +; +; ULONG bn_add_words(ULONG r[], ULONG a[], ULONG b[], int n) { +; ULONG c = 0; +; int i; +; for (i = 0; i < n; i++) = a[i] + b[i] + c; +; return(c); +; } + +r=4 ;(AP) r by reference (output) +a=8 ;(AP) a by reference (input) +b=12 ;(AP) b by reference (input) +n=16 ;(AP) n by value (input) + + + .psect code,nowrt + +.entry bn_add_words,^m + + moval @r(ap),r2 + moval @a(ap),r3 + moval @b(ap),r4 + movl n(ap),r5 ; assumed >0 by C code + clrl r0 ; c + + tstl r5 ; carry = 0 + bleq 666$ + +0$: + movl (r3)+,r6 ; carry untouched + adwc (r4)+,r6 ; carry used and touched + movl r6,(r2)+ ; carry untouched + sobgtr r5,0$ ; carry untouched + + adwc #0,r0 +666$: + ret + + .title vax_bn_sub_words unsigned add of two arrays +; +; Richard Levitte 20-Nov-2000 +; +; ULONG bn_sub_words(ULONG r[], ULONG a[], ULONG b[], int n) { +; ULONG c = 0; +; int i; +; for (i = 0; i < n; i++) = a[i] - b[i] - c; +; return(c); +; } + +r=4 ;(AP) r by reference (output) +a=8 ;(AP) a by reference (input) +b=12 ;(AP) b by reference (input) +n=16 ;(AP) n by value (input) + + + .psect code,nowrt + +.entry bn_sub_words,^m + + moval @r(ap),r2 + moval @a(ap),r3 + moval @b(ap),r4 + movl n(ap),r5 ; assumed >0 by C code + clrl r0 ; c + + tstl r5 ; carry = 0 + bleq 666$ + +0$: + movl (r3)+,r6 ; carry untouched + sbwc (r4)+,r6 ; carry used and touched + movl r6,(r2)+ ; carry untouched + sobgtr r5,0$ ; carry untouched + + adwc #0,r0 +666$: + ret + + +;r=4 ;(AP) +;a=8 ;(AP) +;b=12 ;(AP) +;n=16 ;(AP) n by value (input) + + .psect code,nowrt + +.entry BN_MUL_COMBA8,^m + movab -924(sp),sp + clrq r8 + + clrl r10 + + movl 8(ap),r6 + movzwl 2(r6),r3 + movl 12(ap),r7 + bicl3 #-65536,(r7),r2 + movzwl 2(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,(r6),-12(fp) + bicl3 #-65536,r3,-16(fp) + mull3 r0,-12(fp),-4(fp) + mull2 r2,-12(fp) + mull3 r2,-16(fp),-8(fp) + mull2 r0,-16(fp) + addl3 -4(fp),-8(fp),r0 + bicl3 #0,r0,-4(fp) + cmpl -4(fp),-8(fp) + bgequ noname.45 + addl2 #65536,-16(fp) +noname.45: + movzwl -2(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-16(fp) + bicl3 #-65536,-4(fp),r0 + ashl #16,r0,-8(fp) + addl3 -8(fp),-12(fp),r0 + bicl3 #0,r0,-12(fp) + cmpl -12(fp),-8(fp) + bgequ noname.46 + incl -16(fp) +noname.46: + movl -12(fp),r1 + movl -16(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.47 + incl r2 +noname.47: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.48 + incl r10 +noname.48: + + movl 4(ap),r11 + movl r9,(r11) + + clrl r9 + + movzwl 2(r6),r2 + bicl3 #-65536,4(r7),r3 + movzwl 6(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,(r6),-28(fp) + bicl3 #-65536,r2,-32(fp) + mull3 r0,-28(fp),-20(fp) + mull2 r3,-28(fp) + mull3 r3,-32(fp),-24(fp) + mull2 r0,-32(fp) + addl3 -20(fp),-24(fp),r0 + bicl3 #0,r0,-20(fp) + cmpl -20(fp),-24(fp) + bgequ noname.49 + addl2 #65536,-32(fp) +noname.49: + movzwl -18(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-32(fp) + bicl3 #-65536,-20(fp),r0 + ashl #16,r0,-24(fp) + addl3 -24(fp),-28(fp),r0 + bicl3 #0,r0,-28(fp) + cmpl -28(fp),-24(fp) + bgequ noname.50 + incl -32(fp) +noname.50: + movl -28(fp),r1 + movl -32(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.51 + incl r2 +noname.51: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.52 + incl r9 +noname.52: + + movzwl 6(r6),r2 + bicl3 #-65536,(r7),r3 + movzwl 2(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,4(r6),-44(fp) + bicl3 #-65536,r2,-48(fp) + mull3 r0,-44(fp),-36(fp) + mull2 r3,-44(fp) + mull3 r3,-48(fp),-40(fp) + mull2 r0,-48(fp) + addl3 -36(fp),-40(fp),r0 + bicl3 #0,r0,-36(fp) + cmpl -36(fp),-40(fp) + bgequ noname.53 + addl2 #65536,-48(fp) +noname.53: + movzwl -34(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-48(fp) + bicl3 #-65536,-36(fp),r0 + ashl #16,r0,-40(fp) + addl3 -40(fp),-44(fp),r0 + bicl3 #0,r0,-44(fp) + cmpl -44(fp),-40(fp) + bgequ noname.54 + incl -48(fp) +noname.54: + movl -44(fp),r1 + movl -48(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.55 + incl r2 +noname.55: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.56 + incl r9 +noname.56: + + movl r8,4(r11) + + clrl r8 + + movzwl 10(r6),r2 + bicl3 #-65536,(r7),r3 + movzwl 2(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,8(r6),-60(fp) + bicl3 #-65536,r2,-64(fp) + mull3 r0,-60(fp),-52(fp) + mull2 r3,-60(fp) + mull3 r3,-64(fp),-56(fp) + mull2 r0,-64(fp) + addl3 -52(fp),-56(fp),r0 + bicl3 #0,r0,-52(fp) + cmpl -52(fp),-56(fp) + bgequ noname.57 + addl2 #65536,-64(fp) +noname.57: + movzwl -50(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-64(fp) + bicl3 #-65536,-52(fp),r0 + ashl #16,r0,-56(fp) + addl3 -56(fp),-60(fp),r0 + bicl3 #0,r0,-60(fp) + cmpl -60(fp),-56(fp) + bgequ noname.58 + incl -64(fp) +noname.58: + movl -60(fp),r1 + movl -64(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.59 + incl r2 +noname.59: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.60 + incl r8 +noname.60: + + movzwl 6(r6),r2 + bicl3 #-65536,4(r7),r3 + movzwl 6(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,4(r6),-76(fp) + bicl3 #-65536,r2,-80(fp) + mull3 r0,-76(fp),-68(fp) + mull2 r3,-76(fp) + mull3 r3,-80(fp),-72(fp) + mull2 r0,-80(fp) + addl3 -68(fp),-72(fp),r0 + bicl3 #0,r0,-68(fp) + cmpl -68(fp),-72(fp) + bgequ noname.61 + addl2 #65536,-80(fp) +noname.61: + movzwl -66(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-80(fp) + bicl3 #-65536,-68(fp),r0 + ashl #16,r0,-72(fp) + addl3 -72(fp),-76(fp),r0 + bicl3 #0,r0,-76(fp) + cmpl -76(fp),-72(fp) + bgequ noname.62 + incl -80(fp) +noname.62: + movl -76(fp),r1 + movl -80(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.63 + incl r2 +noname.63: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.64 + incl r8 +noname.64: + + movzwl 2(r6),r2 + bicl3 #-65536,8(r7),r3 + movzwl 10(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,(r6),-92(fp) + bicl3 #-65536,r2,-96(fp) + mull3 r0,-92(fp),-84(fp) + mull2 r3,-92(fp) + mull3 r3,-96(fp),-88(fp) + mull2 r0,-96(fp) + addl3 -84(fp),-88(fp),r0 + bicl3 #0,r0,-84(fp) + cmpl -84(fp),-88(fp) + bgequ noname.65 + addl2 #65536,-96(fp) +noname.65: + movzwl -82(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-96(fp) + bicl3 #-65536,-84(fp),r0 + ashl #16,r0,-88(fp) + addl3 -88(fp),-92(fp),r0 + bicl3 #0,r0,-92(fp) + cmpl -92(fp),-88(fp) + bgequ noname.66 + incl -96(fp) +noname.66: + movl -92(fp),r1 + movl -96(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.67 + incl r2 +noname.67: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.68 + incl r8 +noname.68: + + movl r10,8(r11) + + clrl r10 + + movzwl 2(r6),r2 + bicl3 #-65536,12(r7),r3 + movzwl 14(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,(r6),-108(fp) + bicl3 #-65536,r2,-112(fp) + mull3 r0,-108(fp),-100(fp) + mull2 r3,-108(fp) + mull3 r3,-112(fp),-104(fp) + mull2 r0,-112(fp) + addl3 -100(fp),-104(fp),r0 + bicl3 #0,r0,-100(fp) + cmpl -100(fp),-104(fp) + bgequ noname.69 + addl2 #65536,-112(fp) +noname.69: + movzwl -98(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-112(fp) + bicl3 #-65536,-100(fp),r0 + ashl #16,r0,-104(fp) + addl3 -104(fp),-108(fp),r0 + bicl3 #0,r0,-108(fp) + cmpl -108(fp),-104(fp) + bgequ noname.70 + incl -112(fp) +noname.70: + movl -108(fp),r1 + movl -112(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.71 + incl r2 +noname.71: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.72 + incl r10 +noname.72: + + movzwl 6(r6),r2 + bicl3 #-65536,8(r7),r3 + movzwl 10(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,4(r6),-124(fp) + bicl3 #-65536,r2,-128(fp) + mull3 r0,-124(fp),-116(fp) + mull2 r3,-124(fp) + mull3 r3,-128(fp),-120(fp) + mull2 r0,-128(fp) + addl3 -116(fp),-120(fp),r0 + bicl3 #0,r0,-116(fp) + cmpl -116(fp),-120(fp) + bgequ noname.73 + addl2 #65536,-128(fp) +noname.73: + movzwl -114(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-128(fp) + bicl3 #-65536,-116(fp),r0 + ashl #16,r0,-120(fp) + addl3 -120(fp),-124(fp),r0 + bicl3 #0,r0,-124(fp) + cmpl -124(fp),-120(fp) + bgequ noname.74 + incl -128(fp) +noname.74: + movl -124(fp),r1 + movl -128(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.75 + incl r2 +noname.75: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.76 + incl r10 +noname.76: + + movzwl 10(r6),r2 + bicl3 #-65536,4(r7),r3 + movzwl 6(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,8(r6),-140(fp) + bicl3 #-65536,r2,-144(fp) + mull3 r0,-140(fp),-132(fp) + mull2 r3,-140(fp) + mull3 r3,-144(fp),-136(fp) + mull2 r0,-144(fp) + addl3 -132(fp),-136(fp),r0 + bicl3 #0,r0,-132(fp) + cmpl -132(fp),-136(fp) + bgequ noname.77 + addl2 #65536,-144(fp) +noname.77: + movzwl -130(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-144(fp) + bicl3 #-65536,-132(fp),r0 + ashl #16,r0,-136(fp) + addl3 -136(fp),-140(fp),r0 + bicl3 #0,r0,-140(fp) + cmpl -140(fp),-136(fp) + bgequ noname.78 + incl -144(fp) +noname.78: + movl -140(fp),r1 + movl -144(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.79 + incl r2 +noname.79: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.80 + incl r10 +noname.80: + + movzwl 14(r6),r2 + bicl3 #-65536,(r7),r3 + movzwl 2(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,12(r6),-156(fp) + bicl3 #-65536,r2,-160(fp) + mull3 r0,-156(fp),-148(fp) + mull2 r3,-156(fp) + mull3 r3,-160(fp),-152(fp) + mull2 r0,-160(fp) + addl3 -148(fp),-152(fp),r0 + bicl3 #0,r0,-148(fp) + cmpl -148(fp),-152(fp) + bgequ noname.81 + addl2 #65536,-160(fp) +noname.81: + movzwl -146(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-160(fp) + bicl3 #-65536,-148(fp),r0 + ashl #16,r0,-152(fp) + addl3 -152(fp),-156(fp),r0 + bicl3 #0,r0,-156(fp) + cmpl -156(fp),-152(fp) + bgequ noname.82 + incl -160(fp) +noname.82: + movl -156(fp),r1 + movl -160(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.83 + incl r2 +noname.83: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.84 + incl r10 +noname.84: + + movl r9,12(r11) + + clrl r9 + + movzwl 18(r6),r2 + bicl3 #-65536,(r7),r3 + movzwl 2(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,16(r6),-172(fp) + bicl3 #-65536,r2,-176(fp) + mull3 r0,-172(fp),-164(fp) + mull2 r3,-172(fp) + mull3 r3,-176(fp),-168(fp) + mull2 r0,-176(fp) + addl3 -164(fp),-168(fp),r0 + bicl3 #0,r0,-164(fp) + cmpl -164(fp),-168(fp) + bgequ noname.85 + addl2 #65536,-176(fp) +noname.85: + movzwl -162(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-176(fp) + bicl3 #-65536,-164(fp),r0 + ashl #16,r0,-168(fp) + addl3 -168(fp),-172(fp),r0 + bicl3 #0,r0,-172(fp) + cmpl -172(fp),-168(fp) + bgequ noname.86 + incl -176(fp) +noname.86: + movl -172(fp),r1 + movl -176(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.87 + incl r2 +noname.87: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.88 + incl r9 +noname.88: + + movzwl 14(r6),r2 + bicl3 #-65536,4(r7),r3 + movzwl 6(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,12(r6),-188(fp) + bicl3 #-65536,r2,-192(fp) + mull3 r0,-188(fp),-180(fp) + mull2 r3,-188(fp) + mull3 r3,-192(fp),-184(fp) + mull2 r0,-192(fp) + addl3 -180(fp),-184(fp),r0 + bicl3 #0,r0,-180(fp) + cmpl -180(fp),-184(fp) + bgequ noname.89 + addl2 #65536,-192(fp) +noname.89: + movzwl -178(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-192(fp) + bicl3 #-65536,-180(fp),r0 + ashl #16,r0,-184(fp) + addl3 -184(fp),-188(fp),r0 + bicl3 #0,r0,-188(fp) + cmpl -188(fp),-184(fp) + bgequ noname.90 + incl -192(fp) +noname.90: + movl -188(fp),r1 + movl -192(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.91 + incl r2 +noname.91: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.92 + incl r9 +noname.92: + + movzwl 10(r6),r2 + bicl3 #-65536,8(r7),r3 + movzwl 10(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,8(r6),-204(fp) + bicl3 #-65536,r2,-208(fp) + mull3 r0,-204(fp),-196(fp) + mull2 r3,-204(fp) + mull3 r3,-208(fp),-200(fp) + mull2 r0,-208(fp) + addl3 -196(fp),-200(fp),r0 + bicl3 #0,r0,-196(fp) + cmpl -196(fp),-200(fp) + bgequ noname.93 + addl2 #65536,-208(fp) +noname.93: + movzwl -194(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-208(fp) + bicl3 #-65536,-196(fp),r0 + ashl #16,r0,-200(fp) + addl3 -200(fp),-204(fp),r0 + bicl3 #0,r0,-204(fp) + cmpl -204(fp),-200(fp) + bgequ noname.94 + incl -208(fp) +noname.94: + movl -204(fp),r1 + movl -208(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.95 + incl r2 +noname.95: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.96 + incl r9 +noname.96: + + movzwl 6(r6),r2 + bicl3 #-65536,12(r7),r3 + movzwl 14(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,4(r6),-220(fp) + bicl3 #-65536,r2,-224(fp) + mull3 r0,-220(fp),-212(fp) + mull2 r3,-220(fp) + mull3 r3,-224(fp),-216(fp) + mull2 r0,-224(fp) + addl3 -212(fp),-216(fp),r0 + bicl3 #0,r0,-212(fp) + cmpl -212(fp),-216(fp) + bgequ noname.97 + addl2 #65536,-224(fp) +noname.97: + movzwl -210(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-224(fp) + bicl3 #-65536,-212(fp),r0 + ashl #16,r0,-216(fp) + addl3 -216(fp),-220(fp),r0 + bicl3 #0,r0,-220(fp) + cmpl -220(fp),-216(fp) + bgequ noname.98 + incl -224(fp) +noname.98: + movl -220(fp),r1 + movl -224(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.99 + incl r2 +noname.99: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.100 + incl r9 +noname.100: + + movzwl 2(r6),r2 + bicl3 #-65536,16(r7),r3 + movzwl 18(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,(r6),-236(fp) + bicl3 #-65536,r2,-240(fp) + mull3 r0,-236(fp),-228(fp) + mull2 r3,-236(fp) + mull3 r3,-240(fp),-232(fp) + mull2 r0,-240(fp) + addl3 -228(fp),-232(fp),r0 + bicl3 #0,r0,-228(fp) + cmpl -228(fp),-232(fp) + bgequ noname.101 + addl2 #65536,-240(fp) +noname.101: + movzwl -226(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-240(fp) + bicl3 #-65536,-228(fp),r0 + ashl #16,r0,-232(fp) + addl3 -232(fp),-236(fp),r0 + bicl3 #0,r0,-236(fp) + cmpl -236(fp),-232(fp) + bgequ noname.102 + incl -240(fp) +noname.102: + movl -236(fp),r1 + movl -240(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.103 + incl r2 +noname.103: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.104 + incl r9 +noname.104: + + movl r8,16(r11) + + clrl r8 + + movzwl 2(r6),r2 + bicl3 #-65536,20(r7),r3 + movzwl 22(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,(r6),-252(fp) + bicl3 #-65536,r2,-256(fp) + mull3 r0,-252(fp),-244(fp) + mull2 r3,-252(fp) + mull3 r3,-256(fp),-248(fp) + mull2 r0,-256(fp) + addl3 -244(fp),-248(fp),r0 + bicl3 #0,r0,-244(fp) + cmpl -244(fp),-248(fp) + bgequ noname.105 + addl2 #65536,-256(fp) +noname.105: + movzwl -242(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-256(fp) + bicl3 #-65536,-244(fp),r0 + ashl #16,r0,-248(fp) + addl3 -248(fp),-252(fp),r0 + bicl3 #0,r0,-252(fp) + cmpl -252(fp),-248(fp) + bgequ noname.106 + incl -256(fp) +noname.106: + movl -252(fp),r1 + movl -256(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.107 + incl r2 +noname.107: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.108 + incl r8 +noname.108: + + movzwl 6(r6),r2 + bicl3 #-65536,16(r7),r3 + movzwl 18(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,4(r6),-268(fp) + bicl3 #-65536,r2,-272(fp) + mull3 r0,-268(fp),-260(fp) + mull2 r3,-268(fp) + mull3 r3,-272(fp),-264(fp) + mull2 r0,-272(fp) + addl3 -260(fp),-264(fp),r0 + bicl3 #0,r0,-260(fp) + cmpl -260(fp),-264(fp) + bgequ noname.109 + addl2 #65536,-272(fp) +noname.109: + movzwl -258(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-272(fp) + bicl3 #-65536,-260(fp),r0 + ashl #16,r0,-264(fp) + addl3 -264(fp),-268(fp),r0 + bicl3 #0,r0,-268(fp) + cmpl -268(fp),-264(fp) + bgequ noname.110 + incl -272(fp) +noname.110: + movl -268(fp),r1 + movl -272(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.111 + incl r2 +noname.111: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.112 + incl r8 +noname.112: + + movzwl 10(r6),r2 + bicl3 #-65536,12(r7),r3 + movzwl 14(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,8(r6),-284(fp) + bicl3 #-65536,r2,-288(fp) + mull3 r0,-284(fp),-276(fp) + mull2 r3,-284(fp) + mull3 r3,-288(fp),-280(fp) + mull2 r0,-288(fp) + addl3 -276(fp),-280(fp),r0 + bicl3 #0,r0,-276(fp) + cmpl -276(fp),-280(fp) + bgequ noname.113 + addl2 #65536,-288(fp) +noname.113: + movzwl -274(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-288(fp) + bicl3 #-65536,-276(fp),r0 + ashl #16,r0,-280(fp) + addl3 -280(fp),-284(fp),r0 + bicl3 #0,r0,-284(fp) + cmpl -284(fp),-280(fp) + bgequ noname.114 + incl -288(fp) +noname.114: + movl -284(fp),r1 + movl -288(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.115 + incl r2 +noname.115: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.116 + incl r8 +noname.116: + + movzwl 14(r6),r2 + bicl3 #-65536,8(r7),r3 + movzwl 10(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,12(r6),-300(fp) + bicl3 #-65536,r2,-304(fp) + mull3 r0,-300(fp),-292(fp) + mull2 r3,-300(fp) + mull3 r3,-304(fp),-296(fp) + mull2 r0,-304(fp) + addl3 -292(fp),-296(fp),r0 + bicl3 #0,r0,-292(fp) + cmpl -292(fp),-296(fp) + bgequ noname.117 + addl2 #65536,-304(fp) +noname.117: + movzwl -290(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-304(fp) + bicl3 #-65536,-292(fp),r0 + ashl #16,r0,-296(fp) + addl3 -296(fp),-300(fp),r0 + bicl3 #0,r0,-300(fp) + cmpl -300(fp),-296(fp) + bgequ noname.118 + incl -304(fp) +noname.118: + movl -300(fp),r1 + movl -304(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.119 + incl r2 +noname.119: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.120 + incl r8 +noname.120: + + movzwl 18(r6),r2 + bicl3 #-65536,4(r7),r3 + movzwl 6(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,16(r6),-316(fp) + bicl3 #-65536,r2,-320(fp) + mull3 r0,-316(fp),-308(fp) + mull2 r3,-316(fp) + mull3 r3,-320(fp),-312(fp) + mull2 r0,-320(fp) + addl3 -308(fp),-312(fp),r0 + bicl3 #0,r0,-308(fp) + cmpl -308(fp),-312(fp) + bgequ noname.121 + addl2 #65536,-320(fp) +noname.121: + movzwl -306(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-320(fp) + bicl3 #-65536,-308(fp),r0 + ashl #16,r0,-312(fp) + addl3 -312(fp),-316(fp),r0 + bicl3 #0,r0,-316(fp) + cmpl -316(fp),-312(fp) + bgequ noname.122 + incl -320(fp) +noname.122: + movl -316(fp),r1 + movl -320(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.123 + incl r2 + +noname.123: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.124 + incl r8 +noname.124: + + movzwl 22(r6),r2 + bicl3 #-65536,(r7),r3 + movzwl 2(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,20(r6),-332(fp) + bicl3 #-65536,r2,-336(fp) + mull3 r0,-332(fp),-324(fp) + mull2 r3,-332(fp) + mull3 r3,-336(fp),-328(fp) + mull2 r0,-336(fp) + addl3 -324(fp),-328(fp),r0 + bicl3 #0,r0,-324(fp) + cmpl -324(fp),-328(fp) + bgequ noname.125 + addl2 #65536,-336(fp) +noname.125: + movzwl -322(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-336(fp) + bicl3 #-65536,-324(fp),r0 + ashl #16,r0,-328(fp) + addl3 -328(fp),-332(fp),r0 + bicl3 #0,r0,-332(fp) + cmpl -332(fp),-328(fp) + bgequ noname.126 + incl -336(fp) +noname.126: + movl -332(fp),r1 + movl -336(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.127 + incl r2 +noname.127: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.128 + incl r8 +noname.128: + + movl r10,20(r11) + + clrl r10 + + movzwl 26(r6),r2 + bicl3 #-65536,(r7),r3 + movzwl 2(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,24(r6),-348(fp) + bicl3 #-65536,r2,-352(fp) + mull3 r0,-348(fp),-340(fp) + mull2 r3,-348(fp) + mull3 r3,-352(fp),-344(fp) + mull2 r0,-352(fp) + addl3 -340(fp),-344(fp),r0 + bicl3 #0,r0,-340(fp) + cmpl -340(fp),-344(fp) + bgequ noname.129 + addl2 #65536,-352(fp) +noname.129: + movzwl -338(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-352(fp) + bicl3 #-65536,-340(fp),r0 + ashl #16,r0,-344(fp) + addl3 -344(fp),-348(fp),r0 + bicl3 #0,r0,-348(fp) + cmpl -348(fp),-344(fp) + bgequ noname.130 + incl -352(fp) +noname.130: + movl -348(fp),r1 + movl -352(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.131 + incl r2 +noname.131: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.132 + incl r10 +noname.132: + + movzwl 22(r6),r2 + bicl3 #-65536,4(r7),r3 + movzwl 6(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,20(r6),-364(fp) + bicl3 #-65536,r2,-368(fp) + mull3 r0,-364(fp),-356(fp) + mull2 r3,-364(fp) + mull3 r3,-368(fp),-360(fp) + mull2 r0,-368(fp) + addl3 -356(fp),-360(fp),r0 + bicl3 #0,r0,-356(fp) + cmpl -356(fp),-360(fp) + bgequ noname.133 + addl2 #65536,-368(fp) +noname.133: + movzwl -354(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-368(fp) + bicl3 #-65536,-356(fp),r0 + ashl #16,r0,-360(fp) + addl3 -360(fp),-364(fp),r0 + bicl3 #0,r0,-364(fp) + cmpl -364(fp),-360(fp) + bgequ noname.134 + incl -368(fp) +noname.134: + movl -364(fp),r1 + movl -368(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.135 + incl r2 +noname.135: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.136 + incl r10 +noname.136: + + movzwl 18(r6),r2 + bicl3 #-65536,8(r7),r3 + movzwl 10(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,16(r6),-380(fp) + bicl3 #-65536,r2,-384(fp) + mull3 r0,-380(fp),-372(fp) + mull2 r3,-380(fp) + mull3 r3,-384(fp),-376(fp) + mull2 r0,-384(fp) + addl3 -372(fp),-376(fp),r0 + bicl3 #0,r0,-372(fp) + cmpl -372(fp),-376(fp) + bgequ noname.137 + addl2 #65536,-384(fp) +noname.137: + movzwl -370(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-384(fp) + bicl3 #-65536,-372(fp),r0 + ashl #16,r0,-376(fp) + addl3 -376(fp),-380(fp),r0 + bicl3 #0,r0,-380(fp) + cmpl -380(fp),-376(fp) + bgequ noname.138 + incl -384(fp) +noname.138: + movl -380(fp),r1 + movl -384(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.139 + incl r2 +noname.139: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.140 + incl r10 +noname.140: + + movzwl 14(r6),r2 + bicl3 #-65536,12(r7),r3 + movzwl 14(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,12(r6),-396(fp) + bicl3 #-65536,r2,-400(fp) + mull3 r0,-396(fp),-388(fp) + mull2 r3,-396(fp) + mull3 r3,-400(fp),-392(fp) + mull2 r0,-400(fp) + addl3 -388(fp),-392(fp),r0 + bicl3 #0,r0,-388(fp) + cmpl -388(fp),-392(fp) + bgequ noname.141 + addl2 #65536,-400(fp) +noname.141: + movzwl -386(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-400(fp) + bicl3 #-65536,-388(fp),r0 + ashl #16,r0,-392(fp) + addl3 -392(fp),-396(fp),r0 + bicl3 #0,r0,-396(fp) + cmpl -396(fp),-392(fp) + bgequ noname.142 + incl -400(fp) +noname.142: + movl -396(fp),r1 + movl -400(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.143 + incl r2 +noname.143: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.144 + incl r10 +noname.144: + + movzwl 10(r6),r2 + bicl3 #-65536,16(r7),r3 + movzwl 18(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,8(r6),-412(fp) + bicl3 #-65536,r2,-416(fp) + mull3 r0,-412(fp),-404(fp) + mull2 r3,-412(fp) + mull3 r3,-416(fp),-408(fp) + mull2 r0,-416(fp) + addl3 -404(fp),-408(fp),r0 + bicl3 #0,r0,-404(fp) + cmpl -404(fp),-408(fp) + bgequ noname.145 + addl2 #65536,-416(fp) +noname.145: + movzwl -402(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-416(fp) + bicl3 #-65536,-404(fp),r0 + ashl #16,r0,-408(fp) + addl3 -408(fp),-412(fp),r0 + bicl3 #0,r0,-412(fp) + cmpl -412(fp),-408(fp) + bgequ noname.146 + incl -416(fp) +noname.146: + movl -412(fp),r1 + movl -416(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.147 + incl r2 +noname.147: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.148 + incl r10 +noname.148: + + movzwl 6(r6),r2 + bicl3 #-65536,20(r7),r3 + movzwl 22(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,4(r6),-428(fp) + bicl3 #-65536,r2,-432(fp) + mull3 r0,-428(fp),-420(fp) + mull2 r3,-428(fp) + mull3 r3,-432(fp),-424(fp) + mull2 r0,-432(fp) + addl3 -420(fp),-424(fp),r0 + bicl3 #0,r0,-420(fp) + cmpl -420(fp),-424(fp) + bgequ noname.149 + addl2 #65536,-432(fp) +noname.149: + movzwl -418(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-432(fp) + bicl3 #-65536,-420(fp),r0 + ashl #16,r0,-424(fp) + addl3 -424(fp),-428(fp),r0 + bicl3 #0,r0,-428(fp) + cmpl -428(fp),-424(fp) + bgequ noname.150 + incl -432(fp) +noname.150: + movl -428(fp),r1 + movl -432(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.151 + incl r2 +noname.151: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.152 + incl r10 +noname.152: + + movzwl 2(r6),r2 + bicl3 #-65536,24(r7),r3 + movzwl 26(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,(r6),-444(fp) + bicl3 #-65536,r2,-448(fp) + mull3 r0,-444(fp),-436(fp) + mull2 r3,-444(fp) + mull3 r3,-448(fp),-440(fp) + mull2 r0,-448(fp) + addl3 -436(fp),-440(fp),r0 + bicl3 #0,r0,-436(fp) + cmpl -436(fp),-440(fp) + bgequ noname.153 + addl2 #65536,-448(fp) +noname.153: + movzwl -434(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-448(fp) + bicl3 #-65536,-436(fp),r0 + ashl #16,r0,-440(fp) + addl3 -440(fp),-444(fp),r0 + bicl3 #0,r0,-444(fp) + cmpl -444(fp),-440(fp) + bgequ noname.154 + incl -448(fp) +noname.154: + movl -444(fp),r1 + movl -448(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.155 + incl r2 +noname.155: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.156 + incl r10 +noname.156: + + movl r9,24(r11) + + clrl r9 + + movzwl 2(r6),r2 + bicl3 #-65536,28(r7),r3 + movzwl 30(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,(r6),-460(fp) + bicl3 #-65536,r2,-464(fp) + mull3 r0,-460(fp),-452(fp) + mull2 r3,-460(fp) + mull3 r3,-464(fp),-456(fp) + mull2 r0,-464(fp) + addl3 -452(fp),-456(fp),r0 + bicl3 #0,r0,-452(fp) + cmpl -452(fp),-456(fp) + bgequ noname.157 + addl2 #65536,-464(fp) +noname.157: + movzwl -450(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-464(fp) + bicl3 #-65536,-452(fp),r0 + ashl #16,r0,-456(fp) + addl3 -456(fp),-460(fp),r0 + bicl3 #0,r0,-460(fp) + cmpl -460(fp),-456(fp) + bgequ noname.158 + incl -464(fp) +noname.158: + movl -460(fp),r1 + movl -464(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.159 + incl r2 +noname.159: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.160 + incl r9 +noname.160: + + movzwl 6(r6),r2 + bicl3 #-65536,24(r7),r3 + movzwl 26(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,4(r6),-476(fp) + bicl3 #-65536,r2,-480(fp) + mull3 r0,-476(fp),-468(fp) + mull2 r3,-476(fp) + mull3 r3,-480(fp),-472(fp) + mull2 r0,-480(fp) + addl3 -468(fp),-472(fp),r0 + bicl3 #0,r0,-468(fp) + cmpl -468(fp),-472(fp) + bgequ noname.161 + addl2 #65536,-480(fp) +noname.161: + movzwl -466(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-480(fp) + bicl3 #-65536,-468(fp),r0 + ashl #16,r0,-472(fp) + addl3 -472(fp),-476(fp),r0 + bicl3 #0,r0,-476(fp) + cmpl -476(fp),-472(fp) + bgequ noname.162 + incl -480(fp) +noname.162: + movl -476(fp),r1 + movl -480(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.163 + incl r2 +noname.163: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.164 + incl r9 +noname.164: + + movzwl 10(r6),r2 + bicl3 #-65536,20(r7),r3 + movzwl 22(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,8(r6),-492(fp) + bicl3 #-65536,r2,-496(fp) + mull3 r0,-492(fp),-484(fp) + mull2 r3,-492(fp) + mull3 r3,-496(fp),-488(fp) + mull2 r0,-496(fp) + addl3 -484(fp),-488(fp),r0 + bicl3 #0,r0,-484(fp) + cmpl -484(fp),-488(fp) + bgequ noname.165 + addl2 #65536,-496(fp) +noname.165: + movzwl -482(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-496(fp) + bicl3 #-65536,-484(fp),r0 + ashl #16,r0,-488(fp) + addl3 -488(fp),-492(fp),r0 + bicl3 #0,r0,-492(fp) + cmpl -492(fp),-488(fp) + bgequ noname.166 + incl -496(fp) +noname.166: + movl -492(fp),r1 + movl -496(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.167 + incl r2 +noname.167: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.168 + incl r9 +noname.168: + + movzwl 14(r6),r2 + bicl3 #-65536,16(r7),r3 + movzwl 18(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,12(r6),-508(fp) + bicl3 #-65536,r2,-512(fp) + mull3 r0,-508(fp),-500(fp) + mull2 r3,-508(fp) + mull3 r3,-512(fp),-504(fp) + mull2 r0,-512(fp) + addl3 -500(fp),-504(fp),r0 + bicl3 #0,r0,-500(fp) + cmpl -500(fp),-504(fp) + bgequ noname.169 + addl2 #65536,-512(fp) +noname.169: + movzwl -498(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-512(fp) + bicl3 #-65536,-500(fp),r0 + ashl #16,r0,-504(fp) + addl3 -504(fp),-508(fp),r0 + bicl3 #0,r0,-508(fp) + cmpl -508(fp),-504(fp) + bgequ noname.170 + incl -512(fp) +noname.170: + movl -508(fp),r1 + movl -512(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.171 + incl r2 +noname.171: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.172 + incl r9 +noname.172: + + movzwl 18(r6),r2 + bicl3 #-65536,12(r7),r3 + movzwl 14(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,16(r6),-524(fp) + bicl3 #-65536,r2,-528(fp) + mull3 r0,-524(fp),-516(fp) + mull2 r3,-524(fp) + mull3 r3,-528(fp),-520(fp) + mull2 r0,-528(fp) + addl3 -516(fp),-520(fp),r0 + bicl3 #0,r0,-516(fp) + cmpl -516(fp),-520(fp) + bgequ noname.173 + addl2 #65536,-528(fp) +noname.173: + movzwl -514(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-528(fp) + bicl3 #-65536,-516(fp),r0 + ashl #16,r0,-520(fp) + addl3 -520(fp),-524(fp),r0 + bicl3 #0,r0,-524(fp) + cmpl -524(fp),-520(fp) + bgequ noname.174 + incl -528(fp) +noname.174: + movl -524(fp),r1 + movl -528(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.175 + incl r2 +noname.175: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.176 + incl r9 +noname.176: + + movzwl 22(r6),r2 + bicl3 #-65536,8(r7),r3 + movzwl 10(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,20(r6),-540(fp) + bicl3 #-65536,r2,-544(fp) + mull3 r0,-540(fp),-532(fp) + mull2 r3,-540(fp) + mull3 r3,-544(fp),-536(fp) + mull2 r0,-544(fp) + addl3 -532(fp),-536(fp),r0 + bicl3 #0,r0,-532(fp) + cmpl -532(fp),-536(fp) + bgequ noname.177 + addl2 #65536,-544(fp) +noname.177: + movzwl -530(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-544(fp) + bicl3 #-65536,-532(fp),r0 + ashl #16,r0,-536(fp) + addl3 -536(fp),-540(fp),r0 + bicl3 #0,r0,-540(fp) + cmpl -540(fp),-536(fp) + bgequ noname.178 + incl -544(fp) +noname.178: + movl -540(fp),r1 + movl -544(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.179 + incl r2 +noname.179: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.180 + incl r9 +noname.180: + + movzwl 26(r6),r2 + bicl3 #-65536,4(r7),r3 + movzwl 6(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,24(r6),-556(fp) + bicl3 #-65536,r2,-560(fp) + mull3 r0,-556(fp),-548(fp) + mull2 r3,-556(fp) + mull3 r3,-560(fp),-552(fp) + mull2 r0,-560(fp) + addl3 -548(fp),-552(fp),r0 + bicl3 #0,r0,-548(fp) + cmpl -548(fp),-552(fp) + bgequ noname.181 + addl2 #65536,-560(fp) +noname.181: + movzwl -546(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-560(fp) + bicl3 #-65536,-548(fp),r0 + ashl #16,r0,-552(fp) + addl3 -552(fp),-556(fp),r0 + bicl3 #0,r0,-556(fp) + cmpl -556(fp),-552(fp) + bgequ noname.182 + incl -560(fp) +noname.182: + movl -556(fp),r1 + movl -560(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.183 + incl r2 +noname.183: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.184 + incl r9 +noname.184: + + movzwl 30(r6),r2 + bicl3 #-65536,(r7),r3 + movzwl 2(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,28(r6),-572(fp) + bicl3 #-65536,r2,-576(fp) + mull3 r0,-572(fp),-564(fp) + mull2 r3,-572(fp) + mull3 r3,-576(fp),-568(fp) + mull2 r0,-576(fp) + addl3 -564(fp),-568(fp),r0 + bicl3 #0,r0,-564(fp) + cmpl -564(fp),-568(fp) + bgequ noname.185 + addl2 #65536,-576(fp) +noname.185: + movzwl -562(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-576(fp) + bicl3 #-65536,-564(fp),r0 + ashl #16,r0,-568(fp) + addl3 -568(fp),-572(fp),r0 + bicl3 #0,r0,-572(fp) + cmpl -572(fp),-568(fp) + bgequ noname.186 + incl -576(fp) +noname.186: + movl -572(fp),r1 + movl -576(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.187 + incl r2 +noname.187: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.188 + incl r9 +noname.188: + + movl r8,28(r11) + + clrl r8 + + movzwl 30(r6),r2 + bicl3 #-65536,4(r7),r3 + movzwl 6(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,28(r6),-588(fp) + bicl3 #-65536,r2,-592(fp) + mull3 r0,-588(fp),-580(fp) + mull2 r3,-588(fp) + mull3 r3,-592(fp),-584(fp) + mull2 r0,-592(fp) + addl3 -580(fp),-584(fp),r0 + bicl3 #0,r0,-580(fp) + cmpl -580(fp),-584(fp) + bgequ noname.189 + addl2 #65536,-592(fp) +noname.189: + movzwl -578(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-592(fp) + bicl3 #-65536,-580(fp),r0 + ashl #16,r0,-584(fp) + addl3 -584(fp),-588(fp),r0 + bicl3 #0,r0,-588(fp) + cmpl -588(fp),-584(fp) + bgequ noname.190 + incl -592(fp) +noname.190: + movl -588(fp),r1 + movl -592(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.191 + incl r2 +noname.191: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.192 + incl r8 +noname.192: + + movzwl 26(r6),r2 + bicl3 #-65536,8(r7),r3 + movzwl 10(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,24(r6),-604(fp) + bicl3 #-65536,r2,-608(fp) + mull3 r0,-604(fp),-596(fp) + mull2 r3,-604(fp) + mull3 r3,-608(fp),-600(fp) + mull2 r0,-608(fp) + addl3 -596(fp),-600(fp),r0 + bicl3 #0,r0,-596(fp) + cmpl -596(fp),-600(fp) + bgequ noname.193 + addl2 #65536,-608(fp) +noname.193: + movzwl -594(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-608(fp) + bicl3 #-65536,-596(fp),r0 + ashl #16,r0,-600(fp) + addl3 -600(fp),-604(fp),r0 + bicl3 #0,r0,-604(fp) + cmpl -604(fp),-600(fp) + bgequ noname.194 + incl -608(fp) +noname.194: + movl -604(fp),r1 + movl -608(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.195 + incl r2 +noname.195: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.196 + incl r8 +noname.196: + + movzwl 22(r6),r2 + bicl3 #-65536,12(r7),r3 + movzwl 14(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,20(r6),-620(fp) + bicl3 #-65536,r2,-624(fp) + mull3 r0,-620(fp),-612(fp) + mull2 r3,-620(fp) + mull3 r3,-624(fp),-616(fp) + mull2 r0,-624(fp) + addl3 -612(fp),-616(fp),r0 + bicl3 #0,r0,-612(fp) + cmpl -612(fp),-616(fp) + bgequ noname.197 + addl2 #65536,-624(fp) +noname.197: + movzwl -610(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-624(fp) + bicl3 #-65536,-612(fp),r0 + ashl #16,r0,-616(fp) + addl3 -616(fp),-620(fp),r0 + bicl3 #0,r0,-620(fp) + cmpl -620(fp),-616(fp) + bgequ noname.198 + incl -624(fp) +noname.198: + movl -620(fp),r1 + movl -624(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.199 + incl r2 +noname.199: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.200 + incl r8 +noname.200: + + movzwl 18(r6),r2 + bicl3 #-65536,16(r7),r3 + movzwl 18(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,16(r6),-636(fp) + bicl3 #-65536,r2,-640(fp) + mull3 r0,-636(fp),-628(fp) + mull2 r3,-636(fp) + mull3 r3,-640(fp),-632(fp) + mull2 r0,-640(fp) + addl3 -628(fp),-632(fp),r0 + bicl3 #0,r0,-628(fp) + cmpl -628(fp),-632(fp) + bgequ noname.201 + addl2 #65536,-640(fp) +noname.201: + movzwl -626(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-640(fp) + bicl3 #-65536,-628(fp),r0 + ashl #16,r0,-632(fp) + addl3 -632(fp),-636(fp),r0 + bicl3 #0,r0,-636(fp) + cmpl -636(fp),-632(fp) + bgequ noname.202 + incl -640(fp) +noname.202: + movl -636(fp),r1 + movl -640(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.203 + incl r2 +noname.203: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.204 + incl r8 +noname.204: + + movzwl 14(r6),r2 + bicl3 #-65536,20(r7),r3 + movzwl 22(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,12(r6),-652(fp) + bicl3 #-65536,r2,-656(fp) + mull3 r0,-652(fp),-644(fp) + mull2 r3,-652(fp) + mull3 r3,-656(fp),-648(fp) + mull2 r0,-656(fp) + addl3 -644(fp),-648(fp),r0 + bicl3 #0,r0,-644(fp) + cmpl -644(fp),-648(fp) + bgequ noname.205 + addl2 #65536,-656(fp) +noname.205: + movzwl -642(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-656(fp) + bicl3 #-65536,-644(fp),r0 + ashl #16,r0,-648(fp) + addl3 -648(fp),-652(fp),r0 + bicl3 #0,r0,-652(fp) + cmpl -652(fp),-648(fp) + bgequ noname.206 + incl -656(fp) +noname.206: + movl -652(fp),r1 + movl -656(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.207 + incl r2 +noname.207: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.208 + incl r8 +noname.208: + + movzwl 10(r6),r2 + bicl3 #-65536,24(r7),r3 + movzwl 26(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,8(r6),-668(fp) + bicl3 #-65536,r2,-672(fp) + mull3 r0,-668(fp),-660(fp) + mull2 r3,-668(fp) + mull3 r3,-672(fp),-664(fp) + mull2 r0,-672(fp) + addl3 -660(fp),-664(fp),r0 + bicl3 #0,r0,-660(fp) + cmpl -660(fp),-664(fp) + bgequ noname.209 + addl2 #65536,-672(fp) +noname.209: + movzwl -658(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-672(fp) + bicl3 #-65536,-660(fp),r0 + ashl #16,r0,-664(fp) + addl3 -664(fp),-668(fp),r0 + bicl3 #0,r0,-668(fp) + cmpl -668(fp),-664(fp) + bgequ noname.210 + incl -672(fp) +noname.210: + movl -668(fp),r1 + movl -672(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.211 + incl r2 +noname.211: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.212 + incl r8 +noname.212: + + movzwl 6(r6),r2 + bicl3 #-65536,28(r7),r3 + movzwl 30(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,4(r6),-684(fp) + bicl3 #-65536,r2,-688(fp) + mull3 r0,-684(fp),-676(fp) + mull2 r3,-684(fp) + mull3 r3,-688(fp),-680(fp) + mull2 r0,-688(fp) + addl3 -676(fp),-680(fp),r0 + bicl3 #0,r0,-676(fp) + cmpl -676(fp),-680(fp) + bgequ noname.213 + addl2 #65536,-688(fp) +noname.213: + movzwl -674(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-688(fp) + bicl3 #-65536,-676(fp),r0 + ashl #16,r0,-680(fp) + addl3 -680(fp),-684(fp),r0 + bicl3 #0,r0,-684(fp) + cmpl -684(fp),-680(fp) + bgequ noname.214 + incl -688(fp) +noname.214: + movl -684(fp),r1 + movl -688(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.215 + incl r2 +noname.215: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.216 + incl r8 +noname.216: + + movl r10,32(r11) + + clrl r10 + + movzwl 10(r6),r2 + bicl3 #-65536,28(r7),r3 + movzwl 30(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,8(r6),-700(fp) + bicl3 #-65536,r2,-704(fp) + mull3 r0,-700(fp),-692(fp) + mull2 r3,-700(fp) + mull3 r3,-704(fp),-696(fp) + mull2 r0,-704(fp) + addl3 -692(fp),-696(fp),r0 + bicl3 #0,r0,-692(fp) + cmpl -692(fp),-696(fp) + bgequ noname.217 + addl2 #65536,-704(fp) +noname.217: + movzwl -690(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-704(fp) + bicl3 #-65536,-692(fp),r0 + ashl #16,r0,-696(fp) + addl3 -696(fp),-700(fp),r0 + bicl3 #0,r0,-700(fp) + cmpl -700(fp),-696(fp) + bgequ noname.218 + incl -704(fp) +noname.218: + movl -700(fp),r1 + movl -704(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.219 + incl r2 +noname.219: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.220 + incl r10 +noname.220: + + movzwl 14(r6),r2 + bicl3 #-65536,24(r7),r3 + movzwl 26(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,12(r6),-716(fp) + bicl3 #-65536,r2,-720(fp) + mull3 r0,-716(fp),-708(fp) + mull2 r3,-716(fp) + mull3 r3,-720(fp),-712(fp) + mull2 r0,-720(fp) + addl3 -708(fp),-712(fp),r0 + bicl3 #0,r0,-708(fp) + cmpl -708(fp),-712(fp) + bgequ noname.221 + addl2 #65536,-720(fp) +noname.221: + movzwl -706(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-720(fp) + bicl3 #-65536,-708(fp),r0 + ashl #16,r0,-712(fp) + addl3 -712(fp),-716(fp),r0 + bicl3 #0,r0,-716(fp) + cmpl -716(fp),-712(fp) + bgequ noname.222 + incl -720(fp) +noname.222: + movl -716(fp),r1 + movl -720(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.223 + incl r2 +noname.223: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.224 + incl r10 +noname.224: + + movzwl 18(r6),r2 + bicl3 #-65536,20(r7),r3 + movzwl 22(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,16(r6),-732(fp) + bicl3 #-65536,r2,-736(fp) + mull3 r0,-732(fp),-724(fp) + mull2 r3,-732(fp) + mull3 r3,-736(fp),-728(fp) + mull2 r0,-736(fp) + addl3 -724(fp),-728(fp),r0 + bicl3 #0,r0,-724(fp) + cmpl -724(fp),-728(fp) + bgequ noname.225 + addl2 #65536,-736(fp) +noname.225: + movzwl -722(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-736(fp) + bicl3 #-65536,-724(fp),r0 + ashl #16,r0,-728(fp) + addl3 -728(fp),-732(fp),r0 + bicl3 #0,r0,-732(fp) + cmpl -732(fp),-728(fp) + bgequ noname.226 + incl -736(fp) +noname.226: + movl -732(fp),r1 + movl -736(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.227 + incl r2 +noname.227: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.228 + incl r10 +noname.228: + + movzwl 22(r6),r2 + bicl3 #-65536,16(r7),r3 + movzwl 18(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,20(r6),-748(fp) + bicl3 #-65536,r2,-752(fp) + mull3 r0,-748(fp),-740(fp) + mull2 r3,-748(fp) + mull3 r3,-752(fp),-744(fp) + mull2 r0,-752(fp) + addl3 -740(fp),-744(fp),r0 + bicl3 #0,r0,-740(fp) + cmpl -740(fp),-744(fp) + bgequ noname.229 + addl2 #65536,-752(fp) +noname.229: + movzwl -738(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-752(fp) + bicl3 #-65536,-740(fp),r0 + ashl #16,r0,-744(fp) + addl3 -744(fp),-748(fp),r0 + bicl3 #0,r0,-748(fp) + cmpl -748(fp),-744(fp) + bgequ noname.230 + incl -752(fp) +noname.230: + movl -748(fp),r1 + movl -752(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.231 + incl r2 +noname.231: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.232 + incl r10 +noname.232: + + movzwl 26(r6),r2 + bicl3 #-65536,12(r7),r3 + movzwl 14(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,24(r6),-764(fp) + bicl3 #-65536,r2,-768(fp) + mull3 r0,-764(fp),-756(fp) + mull2 r3,-764(fp) + mull3 r3,-768(fp),-760(fp) + mull2 r0,-768(fp) + addl3 -756(fp),-760(fp),r0 + bicl3 #0,r0,-756(fp) + cmpl -756(fp),-760(fp) + bgequ noname.233 + addl2 #65536,-768(fp) +noname.233: + movzwl -754(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-768(fp) + bicl3 #-65536,-756(fp),r0 + ashl #16,r0,-760(fp) + addl3 -760(fp),-764(fp),r0 + bicl3 #0,r0,-764(fp) + cmpl -764(fp),-760(fp) + bgequ noname.234 + incl -768(fp) +noname.234: + movl -764(fp),r1 + movl -768(fp),r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.235 + incl r2 +noname.235: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.236 + incl r10 +noname.236: + + bicl3 #-65536,28(r6),r3 + movzwl 30(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,8(r7),r2 + movzwl 10(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-772(fp) + mull2 r2,r5 + mull3 r2,r4,-776(fp) + mull2 r0,r4 + addl3 -772(fp),-776(fp),r0 + bicl3 #0,r0,-772(fp) + cmpl -772(fp),-776(fp) + bgequ noname.237 + addl2 #65536,r4 +noname.237: + movzwl -770(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-772(fp),r0 + ashl #16,r0,-776(fp) + addl2 -776(fp),r5 + bicl2 #0,r5 + cmpl r5,-776(fp) + bgequ noname.238 + incl r4 +noname.238: + movl r5,r1 + movl r4,r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.239 + incl r2 +noname.239: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.240 + incl r10 +noname.240: + + movl r9,36(r11) + + clrl r9 + + bicl3 #-65536,28(r6),r3 + movzwl 30(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,12(r7),r2 + movzwl 14(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-780(fp) + mull2 r2,r5 + mull3 r2,r4,-784(fp) + mull2 r0,r4 + addl3 -780(fp),-784(fp),r0 + bicl3 #0,r0,-780(fp) + cmpl -780(fp),-784(fp) + bgequ noname.241 + addl2 #65536,r4 +noname.241: + movzwl -778(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-780(fp),r0 + ashl #16,r0,-784(fp) + addl2 -784(fp),r5 + bicl2 #0,r5 + cmpl r5,-784(fp) + bgequ noname.242 + incl r4 +noname.242: + movl r5,r1 + movl r4,r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.243 + incl r2 +noname.243: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.244 + incl r9 +noname.244: + + bicl3 #-65536,24(r6),r3 + movzwl 26(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,16(r7),r2 + movzwl 18(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-788(fp) + mull2 r2,r5 + mull3 r2,r4,-792(fp) + mull2 r0,r4 + addl3 -788(fp),-792(fp),r0 + bicl3 #0,r0,-788(fp) + cmpl -788(fp),-792(fp) + bgequ noname.245 + addl2 #65536,r4 +noname.245: + movzwl -786(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-788(fp),r0 + ashl #16,r0,-792(fp) + addl2 -792(fp),r5 + bicl2 #0,r5 + cmpl r5,-792(fp) + bgequ noname.246 + incl r4 +noname.246: + movl r5,r1 + movl r4,r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.247 + incl r2 +noname.247: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.248 + incl r9 +noname.248: + + bicl3 #-65536,20(r6),r3 + movzwl 22(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,20(r7),r2 + movzwl 22(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-796(fp) + mull2 r2,r5 + mull3 r2,r4,-800(fp) + mull2 r0,r4 + addl3 -796(fp),-800(fp),r0 + bicl3 #0,r0,-796(fp) + cmpl -796(fp),-800(fp) + bgequ noname.249 + addl2 #65536,r4 +noname.249: + movzwl -794(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-796(fp),r0 + ashl #16,r0,-800(fp) + addl2 -800(fp),r5 + bicl2 #0,r5 + cmpl r5,-800(fp) + bgequ noname.250 + incl r4 +noname.250: + movl r5,r1 + movl r4,r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.251 + incl r2 +noname.251: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.252 + incl r9 +noname.252: + + bicl3 #-65536,16(r6),r3 + movzwl 18(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,24(r7),r2 + movzwl 26(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-804(fp) + mull2 r2,r5 + mull3 r2,r4,-808(fp) + mull2 r0,r4 + addl3 -804(fp),-808(fp),r0 + bicl3 #0,r0,-804(fp) + cmpl -804(fp),-808(fp) + bgequ noname.253 + addl2 #65536,r4 +noname.253: + movzwl -802(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-804(fp),r0 + ashl #16,r0,-808(fp) + addl2 -808(fp),r5 + bicl2 #0,r5 + cmpl r5,-808(fp) + bgequ noname.254 + incl r4 +noname.254: + movl r5,r1 + movl r4,r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.255 + incl r2 +noname.255: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.256 + incl r9 +noname.256: + + bicl3 #-65536,12(r6),r3 + movzwl 14(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,28(r7),r2 + movzwl 30(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-812(fp) + mull2 r2,r5 + mull3 r2,r4,-816(fp) + mull2 r0,r4 + addl3 -812(fp),-816(fp),r0 + bicl3 #0,r0,-812(fp) + cmpl -812(fp),-816(fp) + bgequ noname.257 + addl2 #65536,r4 +noname.257: + movzwl -810(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-812(fp),r0 + ashl #16,r0,-816(fp) + addl2 -816(fp),r5 + bicl2 #0,r5 + cmpl r5,-816(fp) + bgequ noname.258 + incl r4 +noname.258: + movl r5,r1 + movl r4,r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.259 + incl r2 +noname.259: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.260 + incl r9 +noname.260: + + movl r8,40(r11) + + clrl r8 + + bicl3 #-65536,16(r6),r3 + movzwl 18(r6),r2 + bicl3 #-65536,28(r7),r1 + movzwl 30(r7),r0 + bicl2 #-65536,r0 + movl r3,r4 + bicl3 #-65536,r2,-828(fp) + mull3 r0,r4,-820(fp) + mull2 r1,r4 + mull3 r1,-828(fp),-824(fp) + mull2 r0,-828(fp) + addl3 -820(fp),-824(fp),r0 + bicl3 #0,r0,-820(fp) + cmpl -820(fp),-824(fp) + bgequ noname.261 + addl2 #65536,-828(fp) +noname.261: + movzwl -818(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-828(fp) + bicl3 #-65536,-820(fp),r0 + ashl #16,r0,-824(fp) + addl2 -824(fp),r4 + bicl2 #0,r4 + cmpl r4,-824(fp) + bgequ noname.262 + incl -828(fp) +noname.262: + movl r4,r1 + movl -828(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.263 + incl r2 +noname.263: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.264 + incl r8 +noname.264: + + movzwl 22(r6),r2 + bicl3 #-65536,24(r7),r3 + movzwl 26(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,20(r6),-840(fp) + bicl3 #-65536,r2,-844(fp) + mull3 r0,-840(fp),-832(fp) + mull2 r3,-840(fp) + mull3 r3,-844(fp),-836(fp) + mull2 r0,-844(fp) + addl3 -832(fp),-836(fp),r0 + bicl3 #0,r0,-832(fp) + cmpl -832(fp),-836(fp) + bgequ noname.265 + addl2 #65536,-844(fp) +noname.265: + movzwl -830(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-844(fp) + bicl3 #-65536,-832(fp),r0 + ashl #16,r0,-836(fp) + addl3 -836(fp),-840(fp),r0 + bicl3 #0,r0,-840(fp) + cmpl -840(fp),-836(fp) + bgequ noname.266 + incl -844(fp) +noname.266: + movl -840(fp),r1 + movl -844(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.267 + incl r2 +noname.267: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.268 + incl r8 +noname.268: + + bicl3 #-65536,24(r6),r3 + movzwl 26(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,20(r7),r2 + movzwl 22(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-848(fp) + mull2 r2,r5 + mull3 r2,r4,-852(fp) + mull2 r0,r4 + addl3 -848(fp),-852(fp),r0 + bicl3 #0,r0,-848(fp) + cmpl -848(fp),-852(fp) + bgequ noname.269 + addl2 #65536,r4 +noname.269: + movzwl -846(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-848(fp),r0 + ashl #16,r0,-852(fp) + addl2 -852(fp),r5 + bicl2 #0,r5 + cmpl r5,-852(fp) + bgequ noname.270 + incl r4 +noname.270: + movl r5,r1 + movl r4,r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.271 + incl r2 +noname.271: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.272 + incl r8 +noname.272: + + bicl3 #-65536,28(r6),r3 + movzwl 30(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,16(r7),r2 + movzwl 18(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-856(fp) + mull2 r2,r5 + mull3 r2,r4,-860(fp) + mull2 r0,r4 + addl3 -856(fp),-860(fp),r0 + bicl3 #0,r0,-856(fp) + cmpl -856(fp),-860(fp) + bgequ noname.273 + addl2 #65536,r4 +noname.273: + movzwl -854(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-856(fp),r0 + ashl #16,r0,-860(fp) + addl2 -860(fp),r5 + bicl2 #0,r5 + cmpl r5,-860(fp) + bgequ noname.274 + incl r4 +noname.274: + movl r5,r1 + movl r4,r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.275 + incl r2 +noname.275: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.276 + incl r8 +noname.276: + + movl r10,44(r11) + + clrl r10 + + bicl3 #-65536,28(r6),r3 + movzwl 30(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,20(r7),r2 + movzwl 22(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-864(fp) + mull2 r2,r5 + mull3 r2,r4,-868(fp) + mull2 r0,r4 + addl3 -864(fp),-868(fp),r0 + bicl3 #0,r0,-864(fp) + cmpl -864(fp),-868(fp) + bgequ noname.277 + addl2 #65536,r4 +noname.277: + movzwl -862(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-864(fp),r0 + ashl #16,r0,-868(fp) + addl2 -868(fp),r5 + bicl2 #0,r5 + cmpl r5,-868(fp) + bgequ noname.278 + incl r4 +noname.278: + movl r5,r1 + movl r4,r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.279 + incl r2 +noname.279: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.280 + incl r10 +noname.280: + + bicl3 #-65536,24(r6),r3 + movzwl 26(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,24(r7),r2 + movzwl 26(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-872(fp) + mull2 r2,r5 + mull3 r2,r4,-876(fp) + mull2 r0,r4 + addl3 -872(fp),-876(fp),r0 + bicl3 #0,r0,-872(fp) + cmpl -872(fp),-876(fp) + bgequ noname.281 + addl2 #65536,r4 +noname.281: + movzwl -870(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-872(fp),r0 + ashl #16,r0,-876(fp) + addl2 -876(fp),r5 + bicl2 #0,r5 + cmpl r5,-876(fp) + bgequ noname.282 + incl r4 +noname.282: + movl r5,r1 + movl r4,r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.283 + incl r2 +noname.283: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.284 + incl r10 +noname.284: + + bicl3 #-65536,20(r6),r3 + movzwl 22(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,28(r7),r2 + movzwl 30(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-880(fp) + mull2 r2,r5 + mull3 r2,r4,-884(fp) + mull2 r0,r4 + addl3 -880(fp),-884(fp),r0 + bicl3 #0,r0,-880(fp) + cmpl -880(fp),-884(fp) + bgequ noname.285 + addl2 #65536,r4 +noname.285: + movzwl -878(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-880(fp),r0 + ashl #16,r0,-884(fp) + addl2 -884(fp),r5 + bicl2 #0,r5 + cmpl r5,-884(fp) + bgequ noname.286 + incl r4 +noname.286: + movl r5,r1 + movl r4,r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.287 + incl r2 +noname.287: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.288 + incl r10 +noname.288: + + movl r9,48(r11) + + clrl r9 + + bicl3 #-65536,24(r6),r3 + movzwl 26(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,28(r7),r2 + movzwl 30(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-888(fp) + mull2 r2,r5 + mull3 r2,r4,-892(fp) + mull2 r0,r4 + addl3 -888(fp),-892(fp),r0 + bicl3 #0,r0,-888(fp) + cmpl -888(fp),-892(fp) + bgequ noname.289 + addl2 #65536,r4 +noname.289: + movzwl -886(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-888(fp),r0 + ashl #16,r0,-892(fp) + addl2 -892(fp),r5 + bicl2 #0,r5 + cmpl r5,-892(fp) + bgequ noname.290 + incl r4 +noname.290: + movl r5,r1 + movl r4,r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.291 + incl r2 +noname.291: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.292 + incl r9 +noname.292: + + movzwl 30(r6),r2 + bicl3 #-65536,24(r7),r3 + movzwl 26(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,28(r6),-904(fp) + bicl3 #-65536,r2,-908(fp) + mull3 r0,-904(fp),-896(fp) + mull2 r3,-904(fp) + mull3 r3,-908(fp),-900(fp) + mull2 r0,-908(fp) + addl3 -896(fp),-900(fp),r0 + bicl3 #0,r0,-896(fp) + cmpl -896(fp),-900(fp) + bgequ noname.293 + addl2 #65536,-908(fp) +noname.293: + movzwl -894(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-908(fp) + bicl3 #-65536,-896(fp),r0 + ashl #16,r0,-900(fp) + addl3 -900(fp),-904(fp),r0 + bicl3 #0,r0,-904(fp) + cmpl -904(fp),-900(fp) + bgequ noname.294 + incl -908(fp) +noname.294: + movl -904(fp),r1 + movl -908(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.295 + incl r2 +noname.295: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.296 + incl r9 +noname.296: + + movl r8,52(r11) + + clrl r8 + + movzwl 30(r6),r2 + bicl3 #-65536,28(r7),r3 + movzwl 30(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,28(r6),-920(fp) + bicl3 #-65536,r2,-924(fp) + mull3 r0,-920(fp),-912(fp) + mull2 r3,-920(fp) + mull3 r3,-924(fp),-916(fp) + mull2 r0,-924(fp) + addl3 -912(fp),-916(fp),r0 + bicl3 #0,r0,-912(fp) + cmpl -912(fp),-916(fp) + bgequ noname.297 + addl2 #65536,-924(fp) +noname.297: + movzwl -910(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-924(fp) + bicl3 #-65536,-912(fp),r0 + ashl #16,r0,-916(fp) + addl3 -916(fp),-920(fp),r0 + bicl3 #0,r0,-920(fp) + cmpl -920(fp),-916(fp) + bgequ noname.298 + incl -924(fp) +noname.298: + movl -920(fp),r1 + movl -924(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.299 + incl r2 +noname.299: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.300 + incl r8 +noname.300: + + movl r10,56(r11) + + movl r9,60(r11) + + ret + + + +;r=4 ;(AP) +;a=8 ;(AP) +;b=12 ;(AP) +;n=16 ;(AP) n by value (input) + + .psect code,nowrt + +.entry BN_MUL_COMBA4,^m + movab -156(sp),sp + + clrq r9 + + clrl r8 + + movl 8(ap),r6 + bicl3 #-65536,(r6),r3 + movzwl 2(r6),r2 + bicl2 #-65536,r2 + movl 12(ap),r7 + bicl3 #-65536,(r7),r1 + movzwl 2(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r2,r4 + mull3 r0,r5,-4(fp) + mull2 r1,r5 + mull3 r1,r4,-8(fp) + mull2 r0,r4 + addl3 -4(fp),-8(fp),r0 + bicl3 #0,r0,-4(fp) + cmpl -4(fp),-8(fp) + bgequ noname.303 + addl2 #65536,r4 +noname.303: + movzwl -2(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-4(fp),r0 + ashl #16,r0,-8(fp) + addl2 -8(fp),r5 + bicl2 #0,r5 + cmpl r5,-8(fp) + bgequ noname.304 + incl r4 +noname.304: + movl r5,r1 + movl r4,r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.305 + incl r2 +noname.305: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.306 + incl r8 +noname.306: + + movl 4(ap),r11 + movl r10,(r11) + + clrl r10 + + bicl3 #-65536,(r6),r3 + movzwl 2(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,4(r7),r2 + movzwl 6(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-12(fp) + mull2 r2,r5 + mull3 r2,r4,-16(fp) + mull2 r0,r4 + addl3 -12(fp),-16(fp),r0 + bicl3 #0,r0,-12(fp) + cmpl -12(fp),-16(fp) + bgequ noname.307 + addl2 #65536,r4 +noname.307: + movzwl -10(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-12(fp),r0 + ashl #16,r0,-16(fp) + addl2 -16(fp),r5 + bicl2 #0,r5 + cmpl r5,-16(fp) + bgequ noname.308 + incl r4 +noname.308: + movl r5,r1 + movl r4,r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.309 + incl r2 +noname.309: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.310 + incl r10 +noname.310: + + bicl3 #-65536,4(r6),r3 + movzwl 6(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,(r7),r2 + movzwl 2(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-20(fp) + mull2 r2,r5 + mull3 r2,r4,-24(fp) + mull2 r0,r4 + addl3 -20(fp),-24(fp),r0 + bicl3 #0,r0,-20(fp) + cmpl -20(fp),-24(fp) + bgequ noname.311 + addl2 #65536,r4 +noname.311: + movzwl -18(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-20(fp),r0 + ashl #16,r0,-24(fp) + addl2 -24(fp),r5 + bicl2 #0,r5 + cmpl r5,-24(fp) + bgequ noname.312 + incl r4 +noname.312: + movl r5,r1 + movl r4,r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.313 + incl r2 +noname.313: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.314 + incl r10 +noname.314: + + movl r9,4(r11) + + clrl r9 + + bicl3 #-65536,8(r6),r3 + movzwl 10(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,(r7),r2 + movzwl 2(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-28(fp) + mull2 r2,r5 + mull3 r2,r4,-32(fp) + mull2 r0,r4 + addl3 -28(fp),-32(fp),r0 + bicl3 #0,r0,-28(fp) + cmpl -28(fp),-32(fp) + bgequ noname.315 + addl2 #65536,r4 +noname.315: + movzwl -26(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-28(fp),r0 + ashl #16,r0,-32(fp) + addl2 -32(fp),r5 + bicl2 #0,r5 + cmpl r5,-32(fp) + bgequ noname.316 + incl r4 +noname.316: + movl r5,r1 + movl r4,r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.317 + incl r2 +noname.317: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.318 + incl r9 +noname.318: + + bicl3 #-65536,4(r6),r3 + movzwl 6(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,4(r7),r2 + movzwl 6(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-36(fp) + mull2 r2,r5 + mull3 r2,r4,-40(fp) + mull2 r0,r4 + addl3 -36(fp),-40(fp),r0 + bicl3 #0,r0,-36(fp) + cmpl -36(fp),-40(fp) + bgequ noname.319 + addl2 #65536,r4 +noname.319: + movzwl -34(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-36(fp),r0 + ashl #16,r0,-40(fp) + addl2 -40(fp),r5 + bicl2 #0,r5 + cmpl r5,-40(fp) + bgequ noname.320 + incl r4 +noname.320: + movl r5,r1 + movl r4,r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.321 + incl r2 +noname.321: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.322 + incl r9 +noname.322: + + bicl3 #-65536,(r6),r3 + movzwl 2(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,8(r7),r2 + movzwl 10(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-44(fp) + mull2 r2,r5 + mull3 r2,r4,-48(fp) + mull2 r0,r4 + addl3 -44(fp),-48(fp),r0 + bicl3 #0,r0,-44(fp) + cmpl -44(fp),-48(fp) + bgequ noname.323 + addl2 #65536,r4 +noname.323: + movzwl -42(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-44(fp),r0 + ashl #16,r0,-48(fp) + addl2 -48(fp),r5 + bicl2 #0,r5 + cmpl r5,-48(fp) + bgequ noname.324 + incl r4 +noname.324: + movl r5,r1 + movl r4,r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.325 + incl r2 +noname.325: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.326 + incl r9 +noname.326: + + movl r8,8(r11) + + clrl r8 + + bicl3 #-65536,(r6),r3 + movzwl 2(r6),r2 + bicl3 #-65536,12(r7),r1 + movzwl 14(r7),r0 + bicl2 #-65536,r0 + movl r3,r4 + bicl3 #-65536,r2,-60(fp) + mull3 r0,r4,-52(fp) + mull2 r1,r4 + mull3 r1,-60(fp),-56(fp) + mull2 r0,-60(fp) + addl3 -52(fp),-56(fp),r0 + bicl3 #0,r0,-52(fp) + cmpl -52(fp),-56(fp) + bgequ noname.327 + addl2 #65536,-60(fp) +noname.327: + movzwl -50(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-60(fp) + bicl3 #-65536,-52(fp),r0 + ashl #16,r0,-56(fp) + addl2 -56(fp),r4 + bicl2 #0,r4 + cmpl r4,-56(fp) + bgequ noname.328 + incl -60(fp) +noname.328: + movl r4,r1 + movl -60(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.329 + incl r2 +noname.329: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.330 + incl r8 +noname.330: + + movzwl 6(r6),r2 + bicl3 #-65536,8(r7),r3 + movzwl 10(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,4(r6),-72(fp) + bicl3 #-65536,r2,-76(fp) + mull3 r0,-72(fp),-64(fp) + mull2 r3,-72(fp) + mull3 r3,-76(fp),-68(fp) + mull2 r0,-76(fp) + addl3 -64(fp),-68(fp),r0 + bicl3 #0,r0,-64(fp) + cmpl -64(fp),-68(fp) + bgequ noname.331 + addl2 #65536,-76(fp) +noname.331: + movzwl -62(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-76(fp) + bicl3 #-65536,-64(fp),r0 + ashl #16,r0,-68(fp) + addl3 -68(fp),-72(fp),r0 + bicl3 #0,r0,-72(fp) + cmpl -72(fp),-68(fp) + bgequ noname.332 + incl -76(fp) +noname.332: + movl -72(fp),r1 + movl -76(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.333 + incl r2 +noname.333: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.334 + incl r8 +noname.334: + + bicl3 #-65536,8(r6),r3 + movzwl 10(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,4(r7),r2 + movzwl 6(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-80(fp) + mull2 r2,r5 + mull3 r2,r4,-84(fp) + mull2 r0,r4 + addl3 -80(fp),-84(fp),r0 + bicl3 #0,r0,-80(fp) + cmpl -80(fp),-84(fp) + bgequ noname.335 + addl2 #65536,r4 +noname.335: + movzwl -78(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-80(fp),r0 + ashl #16,r0,-84(fp) + addl2 -84(fp),r5 + bicl2 #0,r5 + cmpl r5,-84(fp) + bgequ noname.336 + incl r4 +noname.336: + movl r5,r1 + movl r4,r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.337 + incl r2 +noname.337: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.338 + incl r8 +noname.338: + + bicl3 #-65536,12(r6),r3 + movzwl 14(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,(r7),r2 + movzwl 2(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-88(fp) + mull2 r2,r5 + mull3 r2,r4,-92(fp) + mull2 r0,r4 + addl3 -88(fp),-92(fp),r0 + bicl3 #0,r0,-88(fp) + cmpl -88(fp),-92(fp) + bgequ noname.339 + addl2 #65536,r4 +noname.339: + movzwl -86(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-88(fp),r0 + ashl #16,r0,-92(fp) + addl2 -92(fp),r5 + bicl2 #0,r5 + cmpl r5,-92(fp) + bgequ noname.340 + incl r4 +noname.340: + movl r5,r1 + movl r4,r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.341 + incl r2 +noname.341: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.342 + incl r8 +noname.342: + + movl r10,12(r11) + + clrl r10 + + bicl3 #-65536,12(r6),r3 + movzwl 14(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,4(r7),r2 + movzwl 6(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-96(fp) + mull2 r2,r5 + mull3 r2,r4,-100(fp) + mull2 r0,r4 + addl3 -96(fp),-100(fp),r0 + bicl3 #0,r0,-96(fp) + cmpl -96(fp),-100(fp) + bgequ noname.343 + addl2 #65536,r4 +noname.343: + movzwl -94(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-96(fp),r0 + ashl #16,r0,-100(fp) + addl2 -100(fp),r5 + bicl2 #0,r5 + cmpl r5,-100(fp) + bgequ noname.344 + incl r4 +noname.344: + movl r5,r1 + movl r4,r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.345 + incl r2 +noname.345: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.346 + incl r10 +noname.346: + + bicl3 #-65536,8(r6),r3 + movzwl 10(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,8(r7),r2 + movzwl 10(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-104(fp) + mull2 r2,r5 + mull3 r2,r4,-108(fp) + mull2 r0,r4 + addl3 -104(fp),-108(fp),r0 + bicl3 #0,r0,-104(fp) + cmpl -104(fp),-108(fp) + bgequ noname.347 + addl2 #65536,r4 +noname.347: + movzwl -102(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-104(fp),r0 + ashl #16,r0,-108(fp) + addl2 -108(fp),r5 + bicl2 #0,r5 + cmpl r5,-108(fp) + bgequ noname.348 + incl r4 +noname.348: + movl r5,r1 + movl r4,r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.349 + incl r2 +noname.349: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.350 + incl r10 +noname.350: + + bicl3 #-65536,4(r6),r3 + movzwl 6(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,12(r7),r2 + movzwl 14(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-112(fp) + mull2 r2,r5 + mull3 r2,r4,-116(fp) + mull2 r0,r4 + addl3 -112(fp),-116(fp),r0 + bicl3 #0,r0,-112(fp) + cmpl -112(fp),-116(fp) + bgequ noname.351 + addl2 #65536,r4 +noname.351: + movzwl -110(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-112(fp),r0 + ashl #16,r0,-116(fp) + addl2 -116(fp),r5 + bicl2 #0,r5 + cmpl r5,-116(fp) + bgequ noname.352 + incl r4 +noname.352: + movl r5,r1 + movl r4,r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.353 + incl r2 +noname.353: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.354 + incl r10 +noname.354: + + movl r9,16(r11) + + clrl r9 + + bicl3 #-65536,8(r6),r3 + movzwl 10(r6),r1 + bicl2 #-65536,r1 + bicl3 #-65536,12(r7),r2 + movzwl 14(r7),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-120(fp) + mull2 r2,r5 + mull3 r2,r4,-124(fp) + mull2 r0,r4 + addl3 -120(fp),-124(fp),r0 + bicl3 #0,r0,-120(fp) + cmpl -120(fp),-124(fp) + bgequ noname.355 + addl2 #65536,r4 +noname.355: + movzwl -118(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-120(fp),r0 + ashl #16,r0,-124(fp) + addl2 -124(fp),r5 + bicl2 #0,r5 + cmpl r5,-124(fp) + bgequ noname.356 + incl r4 +noname.356: + movl r5,r1 + movl r4,r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.357 + incl r2 +noname.357: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.358 + incl r9 +noname.358: + + movzwl 14(r6),r2 + bicl3 #-65536,8(r7),r3 + movzwl 10(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,12(r6),-136(fp) + bicl3 #-65536,r2,-140(fp) + mull3 r0,-136(fp),-128(fp) + mull2 r3,-136(fp) + mull3 r3,-140(fp),-132(fp) + mull2 r0,-140(fp) + addl3 -128(fp),-132(fp),r0 + bicl3 #0,r0,-128(fp) + cmpl -128(fp),-132(fp) + bgequ noname.359 + addl2 #65536,-140(fp) +noname.359: + movzwl -126(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-140(fp) + bicl3 #-65536,-128(fp),r0 + ashl #16,r0,-132(fp) + addl3 -132(fp),-136(fp),r0 + bicl3 #0,r0,-136(fp) + cmpl -136(fp),-132(fp) + bgequ noname.360 + incl -140(fp) +noname.360: + movl -136(fp),r1 + movl -140(fp),r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.361 + incl r2 +noname.361: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.362 + incl r9 +noname.362: + + movl r8,20(r11) + + clrl r8 + + movzwl 14(r6),r2 + bicl3 #-65536,12(r7),r3 + movzwl 14(r7),r0 + bicl2 #-65536,r0 + bicl3 #-65536,12(r6),-152(fp) + bicl3 #-65536,r2,-156(fp) + mull3 r0,-152(fp),-144(fp) + mull2 r3,-152(fp) + mull3 r3,-156(fp),-148(fp) + mull2 r0,-156(fp) + addl3 -144(fp),-148(fp),r0 + bicl3 #0,r0,-144(fp) + cmpl -144(fp),-148(fp) + bgequ noname.363 + addl2 #65536,-156(fp) +noname.363: + movzwl -142(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-156(fp) + bicl3 #-65536,-144(fp),r0 + ashl #16,r0,-148(fp) + addl3 -148(fp),-152(fp),r0 + bicl3 #0,r0,-152(fp) + cmpl -152(fp),-148(fp) + bgequ noname.364 + incl -156(fp) +noname.364: + movl -152(fp),r1 + movl -156(fp),r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.365 + incl r2 +noname.365: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.366 + incl r8 +noname.366: + + movl r10,24(r11) + + movl r9,28(r11) + + ret + + + +;r=4 ;(AP) +;a=8 ;(AP) +;b=12 ;(AP) +;n=16 ;(AP) n by value (input) + + .psect code,nowrt + +.entry BN_SQR_COMBA8,^m + movab -444(sp),sp + + clrq r8 + + clrl r7 + + movl 8(ap),r4 + movl (r4),r3 + bicl3 #-65536,r3,-4(fp) + extzv #16,#16,r3,r0 + bicl3 #-65536,r0,r3 + movl -4(fp),r0 + mull3 r0,r3,-8(fp) + mull3 r0,r0,-4(fp) + mull2 r3,r3 + bicl3 #32767,-8(fp),r0 + extzv #15,#17,r0,r0 + addl2 r0,r3 + bicl3 #-65536,-8(fp),r0 + ashl #17,r0,-8(fp) + addl3 -4(fp),-8(fp),r0 + bicl3 #0,r0,-4(fp) + cmpl -4(fp),-8(fp) + bgequ noname.369 + incl r3 +noname.369: + movl -4(fp),r1 + movl r3,r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.370 + incl r2 +noname.370: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.371 + incl r7 +noname.371: + + movl r9,@4(ap) + + clrl r9 + + movzwl 6(r4),r2 + bicl3 #-65536,(r4),r3 + movzwl 2(r4),r0 + bicl2 #-65536,r0 + bicl3 #-65536,4(r4),-20(fp) + bicl3 #-65536,r2,-24(fp) + mull3 r0,-20(fp),-12(fp) + mull2 r3,-20(fp) + mull3 r3,-24(fp),-16(fp) + mull2 r0,-24(fp) + addl3 -12(fp),-16(fp),r0 + bicl3 #0,r0,-12(fp) + cmpl -12(fp),-16(fp) + bgequ noname.372 + addl2 #65536,-24(fp) +noname.372: + movzwl -10(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-24(fp) + bicl3 #-65536,-12(fp),r0 + ashl #16,r0,-16(fp) + addl3 -16(fp),-20(fp),r0 + bicl3 #0,r0,-20(fp) + cmpl -20(fp),-16(fp) + bgequ noname.373 + incl -24(fp) +noname.373: + movl -20(fp),r3 + movl -24(fp),r2 + bbc #31,r2,noname.374 + incl r9 +noname.374: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.375 + incl r2 +noname.375: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r8 + bicl2 #0,r8 + cmpl r8,r3 + bgequ noname.376 + incl r2 + bicl3 #0,r2,r0 + bneq noname.376 + incl r9 +noname.376: + addl2 r2,r7 + bicl2 #0,r7 + cmpl r7,r2 + bgequ noname.377 + incl r9 +noname.377: + + movl 4(ap),r0 + movl r8,4(r0) + + clrl r8 + + movl 8(ap),r4 + movl 4(r4),r3 + bicl3 #-65536,r3,-28(fp) + extzv #16,#16,r3,r0 + bicl3 #-65536,r0,r3 + movl -28(fp),r0 + mull3 r0,r3,-32(fp) + mull3 r0,r0,-28(fp) + mull2 r3,r3 + bicl3 #32767,-32(fp),r0 + extzv #15,#17,r0,r0 + addl2 r0,r3 + bicl3 #-65536,-32(fp),r0 + ashl #17,r0,-32(fp) + addl3 -28(fp),-32(fp),r0 + bicl3 #0,r0,-28(fp) + cmpl -28(fp),-32(fp) + bgequ noname.378 + incl r3 +noname.378: + movl -28(fp),r1 + movl r3,r2 + addl2 r1,r7 + bicl2 #0,r7 + cmpl r7,r1 + bgequ noname.379 + incl r2 +noname.379: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.380 + incl r8 +noname.380: + + movzwl 10(r4),r2 + bicl3 #-65536,(r4),r3 + movzwl 2(r4),r0 + bicl2 #-65536,r0 + bicl3 #-65536,8(r4),-44(fp) + bicl3 #-65536,r2,-48(fp) + mull3 r0,-44(fp),-36(fp) + mull2 r3,-44(fp) + mull3 r3,-48(fp),-40(fp) + mull2 r0,-48(fp) + addl3 -36(fp),-40(fp),r0 + bicl3 #0,r0,-36(fp) + cmpl -36(fp),-40(fp) + bgequ noname.381 + addl2 #65536,-48(fp) +noname.381: + movzwl -34(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-48(fp) + bicl3 #-65536,-36(fp),r0 + ashl #16,r0,-40(fp) + addl3 -40(fp),-44(fp),r0 + bicl3 #0,r0,-44(fp) + cmpl -44(fp),-40(fp) + bgequ noname.382 + incl -48(fp) +noname.382: + movl -44(fp),r3 + movl -48(fp),r2 + bbc #31,r2,noname.383 + incl r8 +noname.383: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.384 + incl r2 +noname.384: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r7 + bicl2 #0,r7 + cmpl r7,r3 + bgequ noname.385 + incl r2 + bicl3 #0,r2,r0 + bneq noname.385 + incl r8 +noname.385: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.386 + incl r8 +noname.386: + + movl 4(ap),r0 + movl r7,8(r0) + + clrl r7 + + movl 8(ap),r0 + movzwl 14(r0),r2 + bicl3 #-65536,(r0),r3 + movzwl 2(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,12(r0),-60(fp) + bicl3 #-65536,r2,-64(fp) + mull3 r1,-60(fp),-52(fp) + mull2 r3,-60(fp) + mull3 r3,-64(fp),-56(fp) + mull2 r1,-64(fp) + addl3 -52(fp),-56(fp),r0 + bicl3 #0,r0,-52(fp) + cmpl -52(fp),-56(fp) + bgequ noname.387 + addl2 #65536,-64(fp) +noname.387: + movzwl -50(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-64(fp) + bicl3 #-65536,-52(fp),r0 + ashl #16,r0,-56(fp) + addl3 -56(fp),-60(fp),r0 + bicl3 #0,r0,-60(fp) + cmpl -60(fp),-56(fp) + bgequ noname.388 + incl -64(fp) +noname.388: + movl -60(fp),r3 + movl -64(fp),r2 + bbc #31,r2,noname.389 + incl r7 +noname.389: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.390 + incl r2 +noname.390: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r9 + bicl2 #0,r9 + cmpl r9,r3 + bgequ noname.391 + incl r2 + bicl3 #0,r2,r0 + bneq noname.391 + incl r7 +noname.391: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.392 + incl r7 +noname.392: + + movl 8(ap),r0 + movzwl 10(r0),r2 + bicl3 #-65536,4(r0),r3 + movzwl 6(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,8(r0),-76(fp) + bicl3 #-65536,r2,-80(fp) + mull3 r1,-76(fp),-68(fp) + mull2 r3,-76(fp) + mull3 r3,-80(fp),-72(fp) + mull2 r1,-80(fp) + addl3 -68(fp),-72(fp),r0 + bicl3 #0,r0,-68(fp) + cmpl -68(fp),-72(fp) + bgequ noname.393 + addl2 #65536,-80(fp) +noname.393: + movzwl -66(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-80(fp) + bicl3 #-65536,-68(fp),r0 + ashl #16,r0,-72(fp) + addl3 -72(fp),-76(fp),r0 + bicl3 #0,r0,-76(fp) + cmpl -76(fp),-72(fp) + bgequ noname.394 + incl -80(fp) +noname.394: + movl -76(fp),r3 + movl -80(fp),r2 + bbc #31,r2,noname.395 + incl r7 +noname.395: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.396 + incl r2 +noname.396: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r9 + bicl2 #0,r9 + cmpl r9,r3 + bgequ noname.397 + incl r2 + bicl3 #0,r2,r0 + bneq noname.397 + incl r7 +noname.397: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.398 + incl r7 +noname.398: + + movl 4(ap),r0 + movl r9,12(r0) + + clrl r9 + + movl 8(ap),r2 + movl 8(r2),r4 + bicl3 #-65536,r4,-84(fp) + extzv #16,#16,r4,r0 + bicl3 #-65536,r0,r4 + movl -84(fp),r0 + mull3 r0,r4,-88(fp) + mull3 r0,r0,-84(fp) + mull2 r4,r4 + bicl3 #32767,-88(fp),r0 + extzv #15,#17,r0,r0 + addl2 r0,r4 + bicl3 #-65536,-88(fp),r0 + ashl #17,r0,-88(fp) + addl3 -84(fp),-88(fp),r0 + bicl3 #0,r0,-84(fp) + cmpl -84(fp),-88(fp) + bgequ noname.399 + incl r4 +noname.399: + movl -84(fp),r1 + movl r4,r3 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.400 + incl r3 +noname.400: + addl2 r3,r7 + bicl2 #0,r7 + cmpl r7,r3 + bgequ noname.401 + incl r9 +noname.401: + + movzwl 14(r2),r3 + bicl3 #-65536,4(r2),r1 + movzwl 6(r2),r0 + bicl2 #-65536,r0 + bicl3 #-65536,12(r2),-100(fp) + bicl3 #-65536,r3,-104(fp) + mull3 r0,-100(fp),-92(fp) + mull2 r1,-100(fp) + mull3 r1,-104(fp),-96(fp) + mull2 r0,-104(fp) + addl3 -92(fp),-96(fp),r0 + bicl3 #0,r0,-92(fp) + cmpl -92(fp),-96(fp) + bgequ noname.402 + addl2 #65536,-104(fp) +noname.402: + movzwl -90(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-104(fp) + bicl3 #-65536,-92(fp),r0 + ashl #16,r0,-96(fp) + addl3 -96(fp),-100(fp),r0 + bicl3 #0,r0,-100(fp) + cmpl -100(fp),-96(fp) + bgequ noname.403 + incl -104(fp) +noname.403: + movl -100(fp),r3 + movl -104(fp),r2 + bbc #31,r2,noname.404 + incl r9 +noname.404: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.405 + incl r2 +noname.405: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r8 + bicl2 #0,r8 + cmpl r8,r3 + bgequ noname.406 + incl r2 + bicl3 #0,r2,r0 + bneq noname.406 + incl r9 +noname.406: + addl2 r2,r7 + bicl2 #0,r7 + cmpl r7,r2 + bgequ noname.407 + incl r9 +noname.407: + + movl 8(ap),r0 + movzwl 18(r0),r2 + bicl3 #-65536,(r0),r3 + movzwl 2(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,16(r0),-116(fp) + bicl3 #-65536,r2,-120(fp) + mull3 r1,-116(fp),-108(fp) + mull2 r3,-116(fp) + mull3 r3,-120(fp),-112(fp) + mull2 r1,-120(fp) + addl3 -108(fp),-112(fp),r0 + bicl3 #0,r0,-108(fp) + cmpl -108(fp),-112(fp) + bgequ noname.408 + addl2 #65536,-120(fp) +noname.408: + movzwl -106(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-120(fp) + bicl3 #-65536,-108(fp),r0 + ashl #16,r0,-112(fp) + addl3 -112(fp),-116(fp),r0 + bicl3 #0,r0,-116(fp) + cmpl -116(fp),-112(fp) + bgequ noname.409 + incl -120(fp) +noname.409: + movl -116(fp),r3 + movl -120(fp),r2 + bbc #31,r2,noname.410 + incl r9 +noname.410: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.411 + incl r2 +noname.411: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r8 + bicl2 #0,r8 + cmpl r8,r3 + bgequ noname.412 + incl r2 + bicl3 #0,r2,r0 + bneq noname.412 + incl r9 +noname.412: + addl2 r2,r7 + bicl2 #0,r7 + cmpl r7,r2 + bgequ noname.413 + incl r9 +noname.413: + + movl 4(ap),r0 + movl r8,16(r0) + + clrl r8 + + movl 8(ap),r0 + movzwl 22(r0),r2 + bicl3 #-65536,(r0),r3 + movzwl 2(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,20(r0),-132(fp) + bicl3 #-65536,r2,-136(fp) + mull3 r1,-132(fp),-124(fp) + mull2 r3,-132(fp) + mull3 r3,-136(fp),-128(fp) + mull2 r1,-136(fp) + addl3 -124(fp),-128(fp),r0 + bicl3 #0,r0,-124(fp) + cmpl -124(fp),-128(fp) + bgequ noname.414 + addl2 #65536,-136(fp) +noname.414: + movzwl -122(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-136(fp) + bicl3 #-65536,-124(fp),r0 + ashl #16,r0,-128(fp) + addl3 -128(fp),-132(fp),r0 + bicl3 #0,r0,-132(fp) + cmpl -132(fp),-128(fp) + bgequ noname.415 + incl -136(fp) +noname.415: + movl -132(fp),r3 + movl -136(fp),r2 + bbc #31,r2,noname.416 + incl r8 +noname.416: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.417 + incl r2 +noname.417: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r7 + bicl2 #0,r7 + cmpl r7,r3 + bgequ noname.418 + incl r2 + bicl3 #0,r2,r0 + bneq noname.418 + incl r8 +noname.418: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.419 + incl r8 +noname.419: + + movl 8(ap),r0 + movzwl 18(r0),r2 + bicl3 #-65536,4(r0),r3 + movzwl 6(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,16(r0),-148(fp) + bicl3 #-65536,r2,-152(fp) + mull3 r1,-148(fp),-140(fp) + mull2 r3,-148(fp) + mull3 r3,-152(fp),-144(fp) + mull2 r1,-152(fp) + addl3 -140(fp),-144(fp),r0 + bicl3 #0,r0,-140(fp) + cmpl -140(fp),-144(fp) + bgequ noname.420 + addl2 #65536,-152(fp) +noname.420: + movzwl -138(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-152(fp) + bicl3 #-65536,-140(fp),r0 + ashl #16,r0,-144(fp) + addl3 -144(fp),-148(fp),r0 + bicl3 #0,r0,-148(fp) + cmpl -148(fp),-144(fp) + bgequ noname.421 + incl -152(fp) +noname.421: + movl -148(fp),r3 + movl -152(fp),r2 + bbc #31,r2,noname.422 + incl r8 +noname.422: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.423 + incl r2 +noname.423: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r7 + bicl2 #0,r7 + cmpl r7,r3 + bgequ noname.424 + incl r2 + bicl3 #0,r2,r0 + bneq noname.424 + incl r8 +noname.424: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.425 + incl r8 +noname.425: + + movl 8(ap),r0 + movzwl 14(r0),r2 + bicl3 #-65536,8(r0),r3 + movzwl 10(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,12(r0),-164(fp) + bicl3 #-65536,r2,-168(fp) + mull3 r1,-164(fp),-156(fp) + mull2 r3,-164(fp) + mull3 r3,-168(fp),-160(fp) + mull2 r1,-168(fp) + addl3 -156(fp),-160(fp),r0 + bicl3 #0,r0,-156(fp) + cmpl -156(fp),-160(fp) + bgequ noname.426 + addl2 #65536,-168(fp) +noname.426: + movzwl -154(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-168(fp) + bicl3 #-65536,-156(fp),r0 + ashl #16,r0,-160(fp) + addl3 -160(fp),-164(fp),r0 + bicl3 #0,r0,-164(fp) + cmpl -164(fp),-160(fp) + bgequ noname.427 + incl -168(fp) +noname.427: + movl -164(fp),r3 + movl -168(fp),r2 + bbc #31,r2,noname.428 + incl r8 +noname.428: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.429 + incl r2 +noname.429: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r7 + bicl2 #0,r7 + cmpl r7,r3 + bgequ noname.430 + incl r2 + bicl3 #0,r2,r0 + bneq noname.430 + incl r8 +noname.430: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.431 + incl r8 +noname.431: + + movl 4(ap),r0 + movl r7,20(r0) + + clrl r7 + + movl 8(ap),r2 + movl 12(r2),r4 + bicl3 #-65536,r4,-172(fp) + extzv #16,#16,r4,r0 + bicl3 #-65536,r0,r4 + movl -172(fp),r0 + mull3 r0,r4,-176(fp) + mull3 r0,r0,-172(fp) + mull2 r4,r4 + bicl3 #32767,-176(fp),r0 + extzv #15,#17,r0,r0 + addl2 r0,r4 + bicl3 #-65536,-176(fp),r0 + ashl #17,r0,-176(fp) + addl3 -172(fp),-176(fp),r0 + bicl3 #0,r0,-172(fp) + cmpl -172(fp),-176(fp) + bgequ noname.432 + incl r4 +noname.432: + movl -172(fp),r1 + movl r4,r3 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.433 + incl r3 +noname.433: + addl2 r3,r8 + bicl2 #0,r8 + cmpl r8,r3 + bgequ noname.434 + incl r7 +noname.434: + + movzwl 18(r2),r3 + bicl3 #-65536,8(r2),r1 + movzwl 10(r2),r0 + bicl2 #-65536,r0 + bicl3 #-65536,16(r2),-188(fp) + bicl3 #-65536,r3,-192(fp) + mull3 r0,-188(fp),-180(fp) + mull2 r1,-188(fp) + mull3 r1,-192(fp),-184(fp) + mull2 r0,-192(fp) + addl3 -180(fp),-184(fp),r0 + bicl3 #0,r0,-180(fp) + cmpl -180(fp),-184(fp) + bgequ noname.435 + addl2 #65536,-192(fp) +noname.435: + movzwl -178(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-192(fp) + bicl3 #-65536,-180(fp),r0 + ashl #16,r0,-184(fp) + addl3 -184(fp),-188(fp),r0 + bicl3 #0,r0,-188(fp) + cmpl -188(fp),-184(fp) + bgequ noname.436 + incl -192(fp) +noname.436: + movl -188(fp),r3 + movl -192(fp),r2 + bbc #31,r2,noname.437 + incl r7 +noname.437: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.438 + incl r2 +noname.438: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r9 + bicl2 #0,r9 + cmpl r9,r3 + bgequ noname.439 + incl r2 + bicl3 #0,r2,r0 + bneq noname.439 + incl r7 +noname.439: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.440 + incl r7 +noname.440: + + movl 8(ap),r0 + movzwl 22(r0),r2 + bicl3 #-65536,4(r0),r3 + movzwl 6(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,20(r0),-204(fp) + bicl3 #-65536,r2,-208(fp) + mull3 r1,-204(fp),-196(fp) + mull2 r3,-204(fp) + mull3 r3,-208(fp),-200(fp) + mull2 r1,-208(fp) + addl3 -196(fp),-200(fp),r0 + bicl3 #0,r0,-196(fp) + cmpl -196(fp),-200(fp) + bgequ noname.441 + addl2 #65536,-208(fp) +noname.441: + movzwl -194(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-208(fp) + bicl3 #-65536,-196(fp),r0 + ashl #16,r0,-200(fp) + addl3 -200(fp),-204(fp),r0 + bicl3 #0,r0,-204(fp) + cmpl -204(fp),-200(fp) + bgequ noname.442 + incl -208(fp) +noname.442: + movl -204(fp),r3 + movl -208(fp),r2 + bbc #31,r2,noname.443 + incl r7 +noname.443: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.444 + incl r2 +noname.444: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r9 + bicl2 #0,r9 + cmpl r9,r3 + bgequ noname.445 + incl r2 + bicl3 #0,r2,r0 + bneq noname.445 + incl r7 +noname.445: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.446 + incl r7 +noname.446: + + movl 8(ap),r0 + movzwl 26(r0),r2 + bicl3 #-65536,(r0),r3 + movzwl 2(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,24(r0),-220(fp) + bicl3 #-65536,r2,-224(fp) + mull3 r1,-220(fp),-212(fp) + mull2 r3,-220(fp) + mull3 r3,-224(fp),-216(fp) + mull2 r1,-224(fp) + addl3 -212(fp),-216(fp),r0 + bicl3 #0,r0,-212(fp) + cmpl -212(fp),-216(fp) + bgequ noname.447 + addl2 #65536,-224(fp) +noname.447: + movzwl -210(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-224(fp) + bicl3 #-65536,-212(fp),r0 + ashl #16,r0,-216(fp) + addl3 -216(fp),-220(fp),r0 + bicl3 #0,r0,-220(fp) + cmpl -220(fp),-216(fp) + bgequ noname.448 + incl -224(fp) +noname.448: + movl -220(fp),r3 + movl -224(fp),r2 + bbc #31,r2,noname.449 + incl r7 +noname.449: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.450 + incl r2 +noname.450: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r9 + bicl2 #0,r9 + cmpl r9,r3 + bgequ noname.451 + incl r2 + bicl3 #0,r2,r0 + bneq noname.451 + incl r7 +noname.451: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.452 + incl r7 +noname.452: + + movl 4(ap),r0 + movl r9,24(r0) + + clrl r9 + + movl 8(ap),r0 + movzwl 30(r0),r2 + bicl3 #-65536,(r0),r3 + movzwl 2(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,28(r0),-236(fp) + bicl3 #-65536,r2,-240(fp) + mull3 r1,-236(fp),-228(fp) + mull2 r3,-236(fp) + mull3 r3,-240(fp),-232(fp) + mull2 r1,-240(fp) + addl3 -228(fp),-232(fp),r0 + bicl3 #0,r0,-228(fp) + cmpl -228(fp),-232(fp) + bgequ noname.453 + addl2 #65536,-240(fp) +noname.453: + movzwl -226(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-240(fp) + bicl3 #-65536,-228(fp),r0 + ashl #16,r0,-232(fp) + addl3 -232(fp),-236(fp),r0 + bicl3 #0,r0,-236(fp) + cmpl -236(fp),-232(fp) + bgequ noname.454 + incl -240(fp) +noname.454: + movl -236(fp),r3 + movl -240(fp),r2 + bbc #31,r2,noname.455 + incl r9 +noname.455: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.456 + incl r2 +noname.456: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r8 + bicl2 #0,r8 + cmpl r8,r3 + bgequ noname.457 + incl r2 + bicl3 #0,r2,r0 + bneq noname.457 + incl r9 +noname.457: + addl2 r2,r7 + bicl2 #0,r7 + cmpl r7,r2 + bgequ noname.458 + incl r9 +noname.458: + + movl 8(ap),r0 + movzwl 26(r0),r2 + bicl3 #-65536,4(r0),r3 + movzwl 6(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,24(r0),-252(fp) + bicl3 #-65536,r2,-256(fp) + mull3 r1,-252(fp),-244(fp) + mull2 r3,-252(fp) + mull3 r3,-256(fp),-248(fp) + mull2 r1,-256(fp) + addl3 -244(fp),-248(fp),r0 + bicl3 #0,r0,-244(fp) + cmpl -244(fp),-248(fp) + bgequ noname.459 + addl2 #65536,-256(fp) +noname.459: + movzwl -242(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-256(fp) + bicl3 #-65536,-244(fp),r0 + ashl #16,r0,-248(fp) + addl3 -248(fp),-252(fp),r0 + bicl3 #0,r0,-252(fp) + cmpl -252(fp),-248(fp) + bgequ noname.460 + incl -256(fp) +noname.460: + movl -252(fp),r3 + movl -256(fp),r2 + bbc #31,r2,noname.461 + incl r9 +noname.461: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.462 + incl r2 +noname.462: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r8 + bicl2 #0,r8 + cmpl r8,r3 + bgequ noname.463 + incl r2 + bicl3 #0,r2,r0 + bneq noname.463 + incl r9 +noname.463: + addl2 r2,r7 + bicl2 #0,r7 + cmpl r7,r2 + bgequ noname.464 + incl r9 +noname.464: + + movl 8(ap),r0 + movzwl 22(r0),r2 + bicl3 #-65536,8(r0),r3 + movzwl 10(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,20(r0),-268(fp) + bicl3 #-65536,r2,-272(fp) + mull3 r1,-268(fp),-260(fp) + mull2 r3,-268(fp) + mull3 r3,-272(fp),-264(fp) + mull2 r1,-272(fp) + addl3 -260(fp),-264(fp),r0 + bicl3 #0,r0,-260(fp) + cmpl -260(fp),-264(fp) + bgequ noname.465 + addl2 #65536,-272(fp) +noname.465: + movzwl -258(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-272(fp) + bicl3 #-65536,-260(fp),r0 + ashl #16,r0,-264(fp) + addl3 -264(fp),-268(fp),r0 + bicl3 #0,r0,-268(fp) + cmpl -268(fp),-264(fp) + bgequ noname.466 + incl -272(fp) +noname.466: + movl -268(fp),r3 + movl -272(fp),r2 + bbc #31,r2,noname.467 + incl r9 +noname.467: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.468 + incl r2 +noname.468: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r8 + bicl2 #0,r8 + cmpl r8,r3 + bgequ noname.469 + incl r2 + bicl3 #0,r2,r0 + bneq noname.469 + incl r9 +noname.469: + addl2 r2,r7 + bicl2 #0,r7 + cmpl r7,r2 + bgequ noname.470 + incl r9 +noname.470: + + movl 8(ap),r0 + movzwl 18(r0),r2 + bicl3 #-65536,12(r0),r3 + movzwl 14(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,16(r0),-284(fp) + bicl3 #-65536,r2,-288(fp) + mull3 r1,-284(fp),-276(fp) + mull2 r3,-284(fp) + mull3 r3,-288(fp),-280(fp) + mull2 r1,-288(fp) + addl3 -276(fp),-280(fp),r0 + bicl3 #0,r0,-276(fp) + cmpl -276(fp),-280(fp) + bgequ noname.471 + addl2 #65536,-288(fp) +noname.471: + movzwl -274(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-288(fp) + bicl3 #-65536,-276(fp),r0 + ashl #16,r0,-280(fp) + addl3 -280(fp),-284(fp),r0 + bicl3 #0,r0,-284(fp) + cmpl -284(fp),-280(fp) + bgequ noname.472 + incl -288(fp) +noname.472: + movl -284(fp),r3 + movl -288(fp),r2 + bbc #31,r2,noname.473 + incl r9 +noname.473: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.474 + incl r2 +noname.474: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r8 + bicl2 #0,r8 + cmpl r8,r3 + bgequ noname.475 + incl r2 + bicl3 #0,r2,r0 + bneq noname.475 + incl r9 +noname.475: + addl2 r2,r7 + bicl2 #0,r7 + cmpl r7,r2 + bgequ noname.476 + incl r9 +noname.476: + + movl 4(ap),r0 + movl r8,28(r0) + + clrl r8 + + movl 8(ap),r3 + movl 16(r3),r4 + bicl3 #-65536,r4,r5 + extzv #16,#16,r4,r0 + bicl3 #-65536,r0,r4 + mull3 r5,r4,-292(fp) + mull2 r5,r5 + mull2 r4,r4 + bicl3 #32767,-292(fp),r0 + extzv #15,#17,r0,r0 + addl2 r0,r4 + bicl3 #-65536,-292(fp),r0 + ashl #17,r0,-292(fp) + addl2 -292(fp),r5 + bicl2 #0,r5 + cmpl r5,-292(fp) + bgequ noname.477 + incl r4 +noname.477: + movl r5,r1 + movl r4,r2 + addl2 r1,r7 + bicl2 #0,r7 + cmpl r7,r1 + bgequ noname.478 + incl r2 +noname.478: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.479 + incl r8 +noname.479: + + bicl3 #-65536,20(r3),r4 + movzwl 22(r3),r1 + bicl2 #-65536,r1 + bicl3 #-65536,12(r3),r2 + movzwl 14(r3),r0 + bicl2 #-65536,r0 + movl r4,r6 + movl r1,r5 + mull3 r0,r6,-296(fp) + mull2 r2,r6 + mull3 r2,r5,-300(fp) + mull2 r0,r5 + addl3 -296(fp),-300(fp),r0 + bicl3 #0,r0,-296(fp) + cmpl -296(fp),-300(fp) + bgequ noname.480 + addl2 #65536,r5 +noname.480: + movzwl -294(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r5 + bicl3 #-65536,-296(fp),r0 + ashl #16,r0,-300(fp) + addl2 -300(fp),r6 + bicl2 #0,r6 + cmpl r6,-300(fp) + bgequ noname.481 + incl r5 +noname.481: + movl r6,r3 + movl r5,r2 + bbc #31,r2,noname.482 + incl r8 +noname.482: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.483 + incl r2 +noname.483: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r7 + bicl2 #0,r7 + cmpl r7,r3 + bgequ noname.484 + incl r2 + bicl3 #0,r2,r0 + bneq noname.484 + incl r8 +noname.484: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.485 + incl r8 +noname.485: + + movl 8(ap),r0 + bicl3 #-65536,24(r0),r3 + movzwl 26(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,8(r0),r2 + movzwl 10(r0),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-304(fp) + mull2 r2,r5 + mull3 r2,r4,-308(fp) + mull2 r0,r4 + addl3 -304(fp),-308(fp),r0 + bicl3 #0,r0,-304(fp) + cmpl -304(fp),-308(fp) + bgequ noname.486 + addl2 #65536,r4 +noname.486: + movzwl -302(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-304(fp),r0 + ashl #16,r0,-308(fp) + addl2 -308(fp),r5 + bicl2 #0,r5 + cmpl r5,-308(fp) + bgequ noname.487 + incl r4 +noname.487: + movl r5,r3 + movl r4,r2 + bbc #31,r2,noname.488 + incl r8 +noname.488: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.489 + incl r2 +noname.489: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r7 + bicl2 #0,r7 + cmpl r7,r3 + bgequ noname.490 + incl r2 + bicl3 #0,r2,r0 + bneq noname.490 + incl r8 +noname.490: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.491 + incl r8 +noname.491: + + movl 8(ap),r0 + bicl3 #-65536,28(r0),r3 + movzwl 30(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,4(r0),r2 + movzwl 6(r0),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-312(fp) + mull2 r2,r5 + mull3 r2,r4,-316(fp) + mull2 r0,r4 + addl3 -312(fp),-316(fp),r0 + bicl3 #0,r0,-312(fp) + cmpl -312(fp),-316(fp) + bgequ noname.492 + addl2 #65536,r4 +noname.492: + movzwl -310(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-312(fp),r0 + ashl #16,r0,-316(fp) + addl2 -316(fp),r5 + bicl2 #0,r5 + cmpl r5,-316(fp) + bgequ noname.493 + incl r4 +noname.493: + movl r5,r3 + movl r4,r2 + bbc #31,r2,noname.494 + incl r8 +noname.494: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.495 + incl r2 +noname.495: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r7 + bicl2 #0,r7 + cmpl r7,r3 + bgequ noname.496 + incl r2 + bicl3 #0,r2,r0 + bneq noname.496 + incl r8 +noname.496: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.497 + incl r8 +noname.497: + + movl 4(ap),r0 + movl r7,32(r0) + + clrl r7 + + movl 8(ap),r0 + bicl3 #-65536,28(r0),r3 + movzwl 30(r0),r2 + bicl3 #-65536,8(r0),r1 + movzwl 10(r0),r0 + bicl2 #-65536,r0 + movl r3,r4 + bicl3 #-65536,r2,-328(fp) + mull3 r0,r4,-320(fp) + mull2 r1,r4 + mull3 r1,-328(fp),-324(fp) + mull2 r0,-328(fp) + addl3 -320(fp),-324(fp),r0 + bicl3 #0,r0,-320(fp) + cmpl -320(fp),-324(fp) + bgequ noname.498 + addl2 #65536,-328(fp) +noname.498: + movzwl -318(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-328(fp) + bicl3 #-65536,-320(fp),r0 + ashl #16,r0,-324(fp) + addl2 -324(fp),r4 + bicl2 #0,r4 + cmpl r4,-324(fp) + bgequ noname.499 + incl -328(fp) +noname.499: + movl r4,r3 + movl -328(fp),r2 + bbc #31,r2,noname.500 + incl r7 +noname.500: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.501 + incl r2 +noname.501: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r9 + bicl2 #0,r9 + cmpl r9,r3 + bgequ noname.502 + incl r2 + bicl3 #0,r2,r0 + bneq noname.502 + incl r7 +noname.502: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.503 + incl r7 +noname.503: + + movl 8(ap),r0 + movzwl 26(r0),r2 + bicl3 #-65536,12(r0),r3 + movzwl 14(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,24(r0),-340(fp) + bicl3 #-65536,r2,-344(fp) + mull3 r1,-340(fp),-332(fp) + mull2 r3,-340(fp) + mull3 r3,-344(fp),-336(fp) + mull2 r1,-344(fp) + addl3 -332(fp),-336(fp),r0 + bicl3 #0,r0,-332(fp) + cmpl -332(fp),-336(fp) + bgequ noname.504 + addl2 #65536,-344(fp) +noname.504: + movzwl -330(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-344(fp) + bicl3 #-65536,-332(fp),r0 + ashl #16,r0,-336(fp) + addl3 -336(fp),-340(fp),r0 + bicl3 #0,r0,-340(fp) + cmpl -340(fp),-336(fp) + bgequ noname.505 + incl -344(fp) +noname.505: + movl -340(fp),r3 + movl -344(fp),r2 + bbc #31,r2,noname.506 + incl r7 +noname.506: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.507 + incl r2 +noname.507: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r9 + bicl2 #0,r9 + cmpl r9,r3 + bgequ noname.508 + incl r2 + bicl3 #0,r2,r0 + bneq noname.508 + incl r7 +noname.508: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.509 + incl r7 +noname.509: + + movl 8(ap),r0 + movzwl 22(r0),r2 + bicl3 #-65536,16(r0),r3 + movzwl 18(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,20(r0),-356(fp) + bicl3 #-65536,r2,-360(fp) + mull3 r1,-356(fp),-348(fp) + mull2 r3,-356(fp) + mull3 r3,-360(fp),-352(fp) + mull2 r1,-360(fp) + addl3 -348(fp),-352(fp),r0 + bicl3 #0,r0,-348(fp) + cmpl -348(fp),-352(fp) + bgequ noname.510 + addl2 #65536,-360(fp) +noname.510: + movzwl -346(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-360(fp) + bicl3 #-65536,-348(fp),r0 + ashl #16,r0,-352(fp) + addl3 -352(fp),-356(fp),r0 + bicl3 #0,r0,-356(fp) + cmpl -356(fp),-352(fp) + bgequ noname.511 + incl -360(fp) +noname.511: + movl -356(fp),r3 + movl -360(fp),r2 + bbc #31,r2,noname.512 + incl r7 +noname.512: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.513 + incl r2 +noname.513: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r9 + bicl2 #0,r9 + cmpl r9,r3 + bgequ noname.514 + incl r2 + bicl3 #0,r2,r0 + bneq noname.514 + incl r7 +noname.514: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.515 + incl r7 +noname.515: + + movl 4(ap),r0 + movl r9,36(r0) + + clrl r9 + + movl 8(ap),r3 + movl 20(r3),r4 + bicl3 #-65536,r4,-364(fp) + extzv #16,#16,r4,r0 + bicl3 #-65536,r0,r4 + movl -364(fp),r0 + mull3 r0,r4,-368(fp) + mull3 r0,r0,-364(fp) + mull2 r4,r4 + bicl3 #32767,-368(fp),r0 + extzv #15,#17,r0,r0 + addl2 r0,r4 + bicl3 #-65536,-368(fp),r0 + ashl #17,r0,-368(fp) + addl3 -364(fp),-368(fp),r0 + bicl3 #0,r0,-364(fp) + cmpl -364(fp),-368(fp) + bgequ noname.516 + incl r4 +noname.516: + movl -364(fp),r1 + movl r4,r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.517 + incl r2 +noname.517: + addl2 r2,r7 + bicl2 #0,r7 + cmpl r7,r2 + bgequ noname.518 + incl r9 +noname.518: + + bicl3 #-65536,24(r3),r4 + movzwl 26(r3),r1 + bicl2 #-65536,r1 + bicl3 #-65536,16(r3),r2 + movzwl 18(r3),r0 + bicl2 #-65536,r0 + movl r4,r6 + movl r1,r5 + mull3 r0,r6,-372(fp) + mull2 r2,r6 + mull3 r2,r5,-376(fp) + mull2 r0,r5 + addl3 -372(fp),-376(fp),r0 + bicl3 #0,r0,-372(fp) + cmpl -372(fp),-376(fp) + bgequ noname.519 + addl2 #65536,r5 +noname.519: + movzwl -370(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r5 + bicl3 #-65536,-372(fp),r0 + ashl #16,r0,-376(fp) + addl2 -376(fp),r6 + bicl2 #0,r6 + cmpl r6,-376(fp) + bgequ noname.520 + incl r5 +noname.520: + movl r6,r3 + movl r5,r2 + bbc #31,r2,noname.521 + incl r9 +noname.521: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.522 + incl r2 +noname.522: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r8 + bicl2 #0,r8 + cmpl r8,r3 + bgequ noname.523 + incl r2 + bicl3 #0,r2,r0 + bneq noname.523 + incl r9 +noname.523: + addl2 r2,r7 + bicl2 #0,r7 + cmpl r7,r2 + bgequ noname.524 + incl r9 +noname.524: + + movl 8(ap),r0 + bicl3 #-65536,28(r0),r3 + movzwl 30(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,12(r0),r2 + movzwl 14(r0),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-380(fp) + mull2 r2,r5 + mull3 r2,r4,-384(fp) + mull2 r0,r4 + addl3 -380(fp),-384(fp),r0 + bicl3 #0,r0,-380(fp) + cmpl -380(fp),-384(fp) + bgequ noname.525 + addl2 #65536,r4 +noname.525: + movzwl -378(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-380(fp),r0 + ashl #16,r0,-384(fp) + addl2 -384(fp),r5 + bicl2 #0,r5 + cmpl r5,-384(fp) + bgequ noname.526 + incl r4 +noname.526: + movl r5,r3 + movl r4,r2 + bbc #31,r2,noname.527 + incl r9 +noname.527: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.528 + incl r2 +noname.528: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r8 + bicl2 #0,r8 + cmpl r8,r3 + bgequ noname.529 + incl r2 + bicl3 #0,r2,r0 + bneq noname.529 + incl r9 +noname.529: + addl2 r2,r7 + bicl2 #0,r7 + cmpl r7,r2 + bgequ noname.530 + incl r9 +noname.530: + movl 4(ap),r0 + movl r8,40(r0) + + clrl r8 + + movl 8(ap),r0 + bicl3 #-65536,28(r0),r3 + movzwl 30(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,16(r0),r2 + movzwl 18(r0),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-388(fp) + mull2 r2,r5 + mull3 r2,r4,-392(fp) + mull2 r0,r4 + addl3 -388(fp),-392(fp),r0 + bicl3 #0,r0,-388(fp) + cmpl -388(fp),-392(fp) + bgequ noname.531 + addl2 #65536,r4 +noname.531: + movzwl -386(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-388(fp),r0 + ashl #16,r0,-392(fp) + addl2 -392(fp),r5 + bicl2 #0,r5 + cmpl r5,-392(fp) + bgequ noname.532 + incl r4 +noname.532: + movl r5,r3 + movl r4,r2 + bbc #31,r2,noname.533 + incl r8 +noname.533: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.534 + incl r2 +noname.534: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r7 + bicl2 #0,r7 + cmpl r7,r3 + bgequ noname.535 + incl r2 + bicl3 #0,r2,r0 + bneq noname.535 + incl r8 +noname.535: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.536 + incl r8 +noname.536: + + movl 8(ap),r0 + bicl3 #-65536,24(r0),r3 + movzwl 26(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,20(r0),r2 + movzwl 22(r0),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-396(fp) + mull2 r2,r5 + mull3 r2,r4,-400(fp) + mull2 r0,r4 + addl3 -396(fp),-400(fp),r0 + bicl3 #0,r0,-396(fp) + cmpl -396(fp),-400(fp) + bgequ noname.537 + addl2 #65536,r4 +noname.537: + movzwl -394(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-396(fp),r0 + ashl #16,r0,-400(fp) + addl2 -400(fp),r5 + bicl2 #0,r5 + cmpl r5,-400(fp) + bgequ noname.538 + incl r4 +noname.538: + movl r5,r3 + movl r4,r2 + bbc #31,r2,noname.539 + incl r8 +noname.539: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.540 + incl r2 +noname.540: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r7 + bicl2 #0,r7 + cmpl r7,r3 + bgequ noname.541 + incl r2 + bicl3 #0,r2,r0 + bneq noname.541 + incl r8 +noname.541: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.542 + incl r8 +noname.542: + + movl 4(ap),r0 + movl r7,44(r0) + + clrl r7 + + movl 8(ap),r3 + movl 24(r3),r4 + bicl3 #-65536,r4,r5 + extzv #16,#16,r4,r0 + bicl3 #-65536,r0,r4 + mull3 r5,r4,-404(fp) + mull2 r5,r5 + mull2 r4,r4 + bicl3 #32767,-404(fp),r0 + extzv #15,#17,r0,r0 + addl2 r0,r4 + bicl3 #-65536,-404(fp),r0 + ashl #17,r0,-404(fp) + addl2 -404(fp),r5 + bicl2 #0,r5 + cmpl r5,-404(fp) + bgequ noname.543 + incl r4 +noname.543: + movl r5,r1 + movl r4,r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.544 + incl r2 +noname.544: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.545 + incl r7 +noname.545: + + movzwl 30(r3),r2 + bicl3 #-65536,20(r3),r1 + movzwl 22(r3),r0 + bicl2 #-65536,r0 + bicl3 #-65536,28(r3),-416(fp) + bicl3 #-65536,r2,-420(fp) + mull3 r0,-416(fp),-408(fp) + mull2 r1,-416(fp) + mull3 r1,-420(fp),-412(fp) + mull2 r0,-420(fp) + addl3 -408(fp),-412(fp),r0 + bicl3 #0,r0,-408(fp) + cmpl -408(fp),-412(fp) + bgequ noname.546 + addl2 #65536,-420(fp) +noname.546: + movzwl -406(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-420(fp) + bicl3 #-65536,-408(fp),r0 + ashl #16,r0,-412(fp) + addl3 -412(fp),-416(fp),r0 + bicl3 #0,r0,-416(fp) + cmpl -416(fp),-412(fp) + bgequ noname.547 + incl -420(fp) +noname.547: + movl -416(fp),r3 + movl -420(fp),r2 + bbc #31,r2,noname.548 + incl r7 +noname.548: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.549 + incl r2 +noname.549: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r9 + bicl2 #0,r9 + cmpl r9,r3 + bgequ noname.550 + incl r2 + bicl3 #0,r2,r0 + bneq noname.550 + incl r7 +noname.550: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.551 + incl r7 +noname.551: + + movl 4(ap),r0 + movl r9,48(r0) + + clrl r9 + + movl 8(ap),r0 + movzwl 30(r0),r2 + bicl3 #-65536,24(r0),r3 + movzwl 26(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,28(r0),-432(fp) + bicl3 #-65536,r2,-436(fp) + mull3 r1,-432(fp),-424(fp) + mull2 r3,-432(fp) + mull3 r3,-436(fp),-428(fp) + mull2 r1,-436(fp) + addl3 -424(fp),-428(fp),r0 + bicl3 #0,r0,-424(fp) + cmpl -424(fp),-428(fp) + bgequ noname.552 + addl2 #65536,-436(fp) +noname.552: + movzwl -422(fp),r0 + bicl2 #-65536,r0 + addl2 r0,-436(fp) + bicl3 #-65536,-424(fp),r0 + ashl #16,r0,-428(fp) + addl3 -428(fp),-432(fp),r0 + bicl3 #0,r0,-432(fp) + cmpl -432(fp),-428(fp) + bgequ noname.553 + incl -436(fp) +noname.553: + movl -432(fp),r3 + movl -436(fp),r2 + bbc #31,r2,noname.554 + incl r9 +noname.554: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.555 + incl r2 +noname.555: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r8 + bicl2 #0,r8 + cmpl r8,r3 + bgequ noname.556 + incl r2 + bicl3 #0,r2,r0 + bneq noname.556 + incl r9 +noname.556: + addl2 r2,r7 + bicl2 #0,r7 + cmpl r7,r2 + bgequ noname.557 + incl r9 +noname.557: + + movl 4(ap),r4 + movl r8,52(r4) + + clrl r8 + + movl 8(ap),r0 + movl 28(r0),r3 + bicl3 #-65536,r3,-440(fp) + extzv #16,#16,r3,r0 + bicl3 #-65536,r0,r3 + movl -440(fp),r0 + mull3 r0,r3,-444(fp) + mull3 r0,r0,-440(fp) + mull2 r3,r3 + bicl3 #32767,-444(fp),r0 + extzv #15,#17,r0,r0 + addl2 r0,r3 + bicl3 #-65536,-444(fp),r0 + ashl #17,r0,-444(fp) + addl3 -440(fp),-444(fp),r0 + bicl3 #0,r0,-440(fp) + cmpl -440(fp),-444(fp) + bgequ noname.558 + incl r3 +noname.558: + movl -440(fp),r1 + movl r3,r2 + addl2 r1,r7 + bicl2 #0,r7 + cmpl r7,r1 + bgequ noname.559 + incl r2 +noname.559: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.560 + incl r8 +noname.560: + + movl r7,56(r4) + + movl r9,60(r4) + + ret + + + +;r=4 ;(AP) +;a=8 ;(AP) +;b=12 ;(AP) +;n=16 ;(AP) n by value (input) + + .psect code,nowrt + +.entry BN_SQR_COMBA4,^m + subl2 #44,sp + + clrq r8 + + clrl r10 + + movl 8(ap),r5 + movl (r5),r3 + bicl3 #-65536,r3,r4 + extzv #16,#16,r3,r0 + bicl3 #-65536,r0,r3 + mull3 r4,r3,-4(fp) + mull2 r4,r4 + mull2 r3,r3 + bicl3 #32767,-4(fp),r0 + extzv #15,#17,r0,r0 + addl2 r0,r3 + bicl3 #-65536,-4(fp),r0 + ashl #17,r0,-4(fp) + addl2 -4(fp),r4 + bicl2 #0,r4 + cmpl r4,-4(fp) + bgequ noname.563 + incl r3 +noname.563: + movl r4,r1 + movl r3,r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.564 + incl r2 +noname.564: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.565 + incl r10 +noname.565: + + movl r9,@4(ap) + + clrl r9 + + bicl3 #-65536,4(r5),r3 + movzwl 6(r5),r1 + bicl2 #-65536,r1 + bicl3 #-65536,(r5),r2 + movzwl 2(r5),r0 + bicl2 #-65536,r0 + movl r3,r6 + movl r1,r4 + mull3 r0,r6,-8(fp) + mull2 r2,r6 + mull2 r4,r2 + mull2 r0,r4 + addl3 -8(fp),r2,r0 + bicl3 #0,r0,-8(fp) + cmpl -8(fp),r2 + bgequ noname.566 + addl2 #65536,r4 +noname.566: + movzwl -6(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-8(fp),r0 + ashl #16,r0,r1 + addl2 r1,r6 + bicl2 #0,r6 + cmpl r6,r1 + bgequ noname.567 + incl r4 +noname.567: + movl r6,r3 + movl r4,r2 + bbc #31,r2,noname.568 + incl r9 +noname.568: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.569 + incl r2 +noname.569: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r8 + bicl2 #0,r8 + cmpl r8,r3 + bgequ noname.570 + incl r2 + bicl3 #0,r2,r0 + bneq noname.570 + incl r9 +noname.570: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.571 + incl r9 +noname.571: + + movl 4(ap),r0 + movl r8,4(r0) + + clrl r8 + + movl 8(ap),r4 + movl 4(r4),r3 + bicl3 #-65536,r3,r5 + extzv #16,#16,r3,r0 + bicl3 #-65536,r0,r3 + mull3 r5,r3,r1 + mull2 r5,r5 + mull2 r3,r3 + bicl3 #32767,r1,r0 + extzv #15,#17,r0,r0 + addl2 r0,r3 + bicl2 #-65536,r1 + ashl #17,r1,r1 + addl2 r1,r5 + bicl2 #0,r5 + cmpl r5,r1 + bgequ noname.572 + incl r3 +noname.572: + movl r5,r1 + movl r3,r2 + addl2 r1,r10 + bicl2 #0,r10 + cmpl r10,r1 + bgequ noname.573 + incl r2 +noname.573: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.574 + incl r8 +noname.574: + + bicl3 #-65536,8(r4),r3 + movzwl 10(r4),r1 + bicl2 #-65536,r1 + bicl3 #-65536,(r4),r2 + movzwl 2(r4),r0 + bicl2 #-65536,r0 + movl r3,r6 + movl r1,r5 + mull3 r0,r6,r7 + mull2 r2,r6 + mull2 r5,r2 + mull2 r0,r5 + addl2 r2,r7 + bicl2 #0,r7 + cmpl r7,r2 + bgequ noname.575 + addl2 #65536,r5 +noname.575: + extzv #16,#16,r7,r0 + bicl2 #-65536,r0 + addl2 r0,r5 + bicl3 #-65536,r7,r0 + ashl #16,r0,r1 + addl2 r1,r6 + bicl2 #0,r6 + cmpl r6,r1 + bgequ noname.576 + incl r5 +noname.576: + movl r6,r3 + movl r5,r2 + bbc #31,r2,noname.577 + incl r8 +noname.577: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.578 + incl r2 +noname.578: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r10 + bicl2 #0,r10 + cmpl r10,r3 + bgequ noname.579 + incl r2 + bicl3 #0,r2,r0 + bneq noname.579 + incl r8 +noname.579: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.580 + incl r8 +noname.580: + + movl 4(ap),r0 + movl r10,8(r0) + + clrl r10 + + movl 8(ap),r0 + bicl3 #-65536,12(r0),r3 + movzwl 14(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,(r0),r2 + movzwl 2(r0),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,r6 + mull2 r2,r5 + mull3 r2,r4,-12(fp) + mull2 r0,r4 + addl2 -12(fp),r6 + bicl2 #0,r6 + cmpl r6,-12(fp) + bgequ noname.581 + addl2 #65536,r4 +noname.581: + extzv #16,#16,r6,r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,r6,r0 + ashl #16,r0,-12(fp) + addl2 -12(fp),r5 + bicl2 #0,r5 + cmpl r5,-12(fp) + bgequ noname.582 + incl r4 +noname.582: + movl r5,r3 + movl r4,r2 + bbc #31,r2,noname.583 + incl r10 +noname.583: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.584 + incl r2 +noname.584: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r9 + bicl2 #0,r9 + cmpl r9,r3 + bgequ noname.585 + incl r2 + bicl3 #0,r2,r0 + bneq noname.585 + incl r10 +noname.585: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.586 + incl r10 +noname.586: + + movl 8(ap),r0 + bicl3 #-65536,8(r0),r3 + movzwl 10(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,4(r0),r2 + movzwl 6(r0),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-16(fp) + mull2 r2,r5 + mull3 r2,r4,-20(fp) + mull2 r0,r4 + addl3 -16(fp),-20(fp),r0 + bicl3 #0,r0,-16(fp) + cmpl -16(fp),-20(fp) + bgequ noname.587 + addl2 #65536,r4 +noname.587: + movzwl -14(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-16(fp),r0 + ashl #16,r0,-20(fp) + addl2 -20(fp),r5 + bicl2 #0,r5 + cmpl r5,-20(fp) + bgequ noname.588 + incl r4 +noname.588: + movl r5,r3 + movl r4,r2 + bbc #31,r2,noname.589 + incl r10 +noname.589: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.590 + incl r2 +noname.590: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r9 + bicl2 #0,r9 + cmpl r9,r3 + bgequ noname.591 + incl r2 + bicl3 #0,r2,r0 + bneq noname.591 + incl r10 +noname.591: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.592 + incl r10 +noname.592: + movl 4(ap),r0 + movl r9,12(r0) + + clrl r9 + + movl 8(ap),r3 + movl 8(r3),r4 + bicl3 #-65536,r4,r5 + extzv #16,#16,r4,r0 + bicl3 #-65536,r0,r4 + mull3 r5,r4,-24(fp) + mull2 r5,r5 + mull2 r4,r4 + bicl3 #32767,-24(fp),r0 + extzv #15,#17,r0,r0 + addl2 r0,r4 + bicl3 #-65536,-24(fp),r0 + ashl #17,r0,-24(fp) + addl2 -24(fp),r5 + bicl2 #0,r5 + cmpl r5,-24(fp) + bgequ noname.593 + incl r4 +noname.593: + movl r5,r1 + movl r4,r2 + addl2 r1,r8 + bicl2 #0,r8 + cmpl r8,r1 + bgequ noname.594 + incl r2 +noname.594: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.595 + incl r9 +noname.595: + + bicl3 #-65536,12(r3),r4 + movzwl 14(r3),r1 + bicl2 #-65536,r1 + bicl3 #-65536,4(r3),r2 + movzwl 6(r3),r0 + bicl2 #-65536,r0 + movl r4,r6 + movl r1,r5 + mull3 r0,r6,-28(fp) + mull2 r2,r6 + mull3 r2,r5,-32(fp) + mull2 r0,r5 + addl3 -28(fp),-32(fp),r0 + bicl3 #0,r0,-28(fp) + cmpl -28(fp),-32(fp) + bgequ noname.596 + addl2 #65536,r5 +noname.596: + movzwl -26(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r5 + bicl3 #-65536,-28(fp),r0 + ashl #16,r0,-32(fp) + addl2 -32(fp),r6 + bicl2 #0,r6 + cmpl r6,-32(fp) + bgequ noname.597 + incl r5 +noname.597: + movl r6,r3 + movl r5,r2 + bbc #31,r2,noname.598 + incl r9 +noname.598: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.599 + incl r2 +noname.599: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r8 + bicl2 #0,r8 + cmpl r8,r3 + bgequ noname.600 + incl r2 + bicl3 #0,r2,r0 + bneq noname.600 + incl r9 +noname.600: + addl2 r2,r10 + bicl2 #0,r10 + cmpl r10,r2 + bgequ noname.601 + incl r9 +noname.601: + + movl 4(ap),r0 + movl r8,16(r0) + + clrl r8 + + movl 8(ap),r0 + bicl3 #-65536,12(r0),r3 + movzwl 14(r0),r1 + bicl2 #-65536,r1 + bicl3 #-65536,8(r0),r2 + movzwl 10(r0),r0 + bicl2 #-65536,r0 + movl r3,r5 + movl r1,r4 + mull3 r0,r5,-36(fp) + mull2 r2,r5 + mull3 r2,r4,-40(fp) + mull2 r0,r4 + addl3 -36(fp),-40(fp),r0 + bicl3 #0,r0,-36(fp) + cmpl -36(fp),-40(fp) + bgequ noname.602 + addl2 #65536,r4 +noname.602: + movzwl -34(fp),r0 + bicl2 #-65536,r0 + addl2 r0,r4 + bicl3 #-65536,-36(fp),r0 + ashl #16,r0,-40(fp) + addl2 -40(fp),r5 + bicl2 #0,r5 + cmpl r5,-40(fp) + bgequ noname.603 + incl r4 +noname.603: + movl r5,r3 + movl r4,r2 + bbc #31,r2,noname.604 + incl r8 +noname.604: + addl2 r2,r2 + bicl2 #0,r2 + bbc #31,r3,noname.605 + incl r2 +noname.605: + addl2 r3,r3 + bicl2 #0,r3 + addl2 r3,r10 + bicl2 #0,r10 + cmpl r10,r3 + bgequ noname.606 + incl r2 + bicl3 #0,r2,r0 + bneq noname.606 + incl r8 +noname.606: + addl2 r2,r9 + bicl2 #0,r9 + cmpl r9,r2 + bgequ noname.607 + incl r8 +noname.607: + + movl 4(ap),r4 + movl r10,20(r4) + + clrl r10 + + movl 8(ap),r0 + movl 12(r0),r3 + bicl3 #-65536,r3,r5 + extzv #16,#16,r3,r0 + bicl3 #-65536,r0,r3 + mull3 r5,r3,-44(fp) + mull2 r5,r5 + mull2 r3,r3 + bicl3 #32767,-44(fp),r0 + extzv #15,#17,r0,r0 + addl2 r0,r3 + bicl3 #-65536,-44(fp),r0 + ashl #17,r0,-44(fp) + addl2 -44(fp),r5 + bicl2 #0,r5 + cmpl r5,-44(fp) + bgequ noname.608 + incl r3 +noname.608: + movl r5,r1 + movl r3,r2 + addl2 r1,r9 + bicl2 #0,r9 + cmpl r9,r1 + bgequ noname.609 + incl r2 +noname.609: + addl2 r2,r8 + bicl2 #0,r8 + cmpl r8,r2 + bgequ noname.610 + incl r10 +noname.610: + + movl r9,24(r4) + + movl r8,28(r4) + + ret + +; For now, the code below doesn't work, so I end this prematurely. +.end diff --git a/libs/openssl/crypto/bn/asm/x86-gf2m.pl b/libs/openssl/crypto/bn/asm/x86-gf2m.pl new file mode 100644 index 00000000..b5795302 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/x86-gf2m.pl @@ -0,0 +1,313 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# May 2011 +# +# The module implements bn_GF2m_mul_2x2 polynomial multiplication used +# in bn_gf2m.c. It's kind of low-hanging mechanical port from C for +# the time being... Except that it has three code paths: pure integer +# code suitable for any x86 CPU, MMX code suitable for PIII and later +# and PCLMULQDQ suitable for Westmere and later. Improvement varies +# from one benchmark and µ-arch to another. Below are interval values +# for 163- and 571-bit ECDH benchmarks relative to compiler-generated +# code: +# +# PIII 16%-30% +# P4 12%-12% +# Opteron 18%-40% +# Core2 19%-44% +# Atom 38%-64% +# Westmere 53%-121%(PCLMULQDQ)/20%-32%(MMX) +# Sandy Bridge 72%-127%(PCLMULQDQ)/27%-23%(MMX) +# +# Note that above improvement coefficients are not coefficients for +# bn_GF2m_mul_2x2 itself. For example 120% ECDH improvement is result +# of bn_GF2m_mul_2x2 being >4x faster. As it gets faster, benchmark +# is more and more dominated by other subroutines, most notably by +# BN_GF2m_mod[_mul]_arr... + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],$0,$x86only = $ARGV[$#ARGV] eq "386"); + +$sse2=0; +for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } + +&external_label("OPENSSL_ia32cap_P") if ($sse2); + +$a="eax"; +$b="ebx"; +($a1,$a2,$a4)=("ecx","edx","ebp"); + +$R="mm0"; +@T=("mm1","mm2"); +($A,$B,$B30,$B31)=("mm2","mm3","mm4","mm5"); +@i=("esi","edi"); + + if (!$x86only) { +&function_begin_B("_mul_1x1_mmx"); + &sub ("esp",32+4); + &mov ($a1,$a); + &lea ($a2,&DWP(0,$a,$a)); + &and ($a1,0x3fffffff); + &lea ($a4,&DWP(0,$a2,$a2)); + &mov (&DWP(0*4,"esp"),0); + &and ($a2,0x7fffffff); + &movd ($A,$a); + &movd ($B,$b); + &mov (&DWP(1*4,"esp"),$a1); # a1 + &xor ($a1,$a2); # a1^a2 + &pxor ($B31,$B31); + &pxor ($B30,$B30); + &mov (&DWP(2*4,"esp"),$a2); # a2 + &xor ($a2,$a4); # a2^a4 + &mov (&DWP(3*4,"esp"),$a1); # a1^a2 + &pcmpgtd($B31,$A); # broadcast 31st bit + &paddd ($A,$A); # $A<<=1 + &xor ($a1,$a2); # a1^a4=a1^a2^a2^a4 + &mov (&DWP(4*4,"esp"),$a4); # a4 + &xor ($a4,$a2); # a2=a4^a2^a4 + &pand ($B31,$B); + &pcmpgtd($B30,$A); # broadcast 30th bit + &mov (&DWP(5*4,"esp"),$a1); # a1^a4 + &xor ($a4,$a1); # a1^a2^a4 + &psllq ($B31,31); + &pand ($B30,$B); + &mov (&DWP(6*4,"esp"),$a2); # a2^a4 + &mov (@i[0],0x7); + &mov (&DWP(7*4,"esp"),$a4); # a1^a2^a4 + &mov ($a4,@i[0]); + &and (@i[0],$b); + &shr ($b,3); + &mov (@i[1],$a4); + &psllq ($B30,30); + &and (@i[1],$b); + &shr ($b,3); + &movd ($R,&DWP(0,"esp",@i[0],4)); + &mov (@i[0],$a4); + &and (@i[0],$b); + &shr ($b,3); + for($n=1;$n<9;$n++) { + &movd (@T[1],&DWP(0,"esp",@i[1],4)); + &mov (@i[1],$a4); + &psllq (@T[1],3*$n); + &and (@i[1],$b); + &shr ($b,3); + &pxor ($R,@T[1]); + + push(@i,shift(@i)); push(@T,shift(@T)); + } + &movd (@T[1],&DWP(0,"esp",@i[1],4)); + &pxor ($R,$B30); + &psllq (@T[1],3*$n++); + &pxor ($R,@T[1]); + + &movd (@T[0],&DWP(0,"esp",@i[0],4)); + &pxor ($R,$B31); + &psllq (@T[0],3*$n); + &add ("esp",32+4); + &pxor ($R,@T[0]); + &ret (); +&function_end_B("_mul_1x1_mmx"); + } + +($lo,$hi)=("eax","edx"); +@T=("ecx","ebp"); + +&function_begin_B("_mul_1x1_ialu"); + &sub ("esp",32+4); + &mov ($a1,$a); + &lea ($a2,&DWP(0,$a,$a)); + &lea ($a4,&DWP(0,"",$a,4)); + &and ($a1,0x3fffffff); + &lea (@i[1],&DWP(0,$lo,$lo)); + &sar ($lo,31); # broadcast 31st bit + &mov (&DWP(0*4,"esp"),0); + &and ($a2,0x7fffffff); + &mov (&DWP(1*4,"esp"),$a1); # a1 + &xor ($a1,$a2); # a1^a2 + &mov (&DWP(2*4,"esp"),$a2); # a2 + &xor ($a2,$a4); # a2^a4 + &mov (&DWP(3*4,"esp"),$a1); # a1^a2 + &xor ($a1,$a2); # a1^a4=a1^a2^a2^a4 + &mov (&DWP(4*4,"esp"),$a4); # a4 + &xor ($a4,$a2); # a2=a4^a2^a4 + &mov (&DWP(5*4,"esp"),$a1); # a1^a4 + &xor ($a4,$a1); # a1^a2^a4 + &sar (@i[1],31); # broardcast 30th bit + &and ($lo,$b); + &mov (&DWP(6*4,"esp"),$a2); # a2^a4 + &and (@i[1],$b); + &mov (&DWP(7*4,"esp"),$a4); # a1^a2^a4 + &mov ($hi,$lo); + &shl ($lo,31); + &mov (@T[0],@i[1]); + &shr ($hi,1); + + &mov (@i[0],0x7); + &shl (@i[1],30); + &and (@i[0],$b); + &shr (@T[0],2); + &xor ($lo,@i[1]); + + &shr ($b,3); + &mov (@i[1],0x7); # 5-byte instruction!? + &and (@i[1],$b); + &shr ($b,3); + &xor ($hi,@T[0]); + &xor ($lo,&DWP(0,"esp",@i[0],4)); + &mov (@i[0],0x7); + &and (@i[0],$b); + &shr ($b,3); + for($n=1;$n<9;$n++) { + &mov (@T[1],&DWP(0,"esp",@i[1],4)); + &mov (@i[1],0x7); + &mov (@T[0],@T[1]); + &shl (@T[1],3*$n); + &and (@i[1],$b); + &shr (@T[0],32-3*$n); + &xor ($lo,@T[1]); + &shr ($b,3); + &xor ($hi,@T[0]); + + push(@i,shift(@i)); push(@T,shift(@T)); + } + &mov (@T[1],&DWP(0,"esp",@i[1],4)); + &mov (@T[0],@T[1]); + &shl (@T[1],3*$n); + &mov (@i[1],&DWP(0,"esp",@i[0],4)); + &shr (@T[0],32-3*$n); $n++; + &mov (@i[0],@i[1]); + &xor ($lo,@T[1]); + &shl (@i[1],3*$n); + &xor ($hi,@T[0]); + &shr (@i[0],32-3*$n); + &xor ($lo,@i[1]); + &xor ($hi,@i[0]); + + &add ("esp",32+4); + &ret (); +&function_end_B("_mul_1x1_ialu"); + +# void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1, BN_ULONG b0); +&function_begin_B("bn_GF2m_mul_2x2"); +if (!$x86only) { + &picmeup("edx","OPENSSL_ia32cap_P"); + &mov ("eax",&DWP(0,"edx")); + &mov ("edx",&DWP(4,"edx")); + &test ("eax",1<<23); # check MMX bit + &jz (&label("ialu")); +if ($sse2) { + &test ("eax",1<<24); # check FXSR bit + &jz (&label("mmx")); + &test ("edx",1<<1); # check PCLMULQDQ bit + &jz (&label("mmx")); + + &movups ("xmm0",&QWP(8,"esp")); + &shufps ("xmm0","xmm0",0b10110001); + &pclmulqdq ("xmm0","xmm0",1); + &mov ("eax",&DWP(4,"esp")); + &movups (&QWP(0,"eax"),"xmm0"); + &ret (); + +&set_label("mmx",16); +} + &push ("ebp"); + &push ("ebx"); + &push ("esi"); + &push ("edi"); + &mov ($a,&wparam(1)); + &mov ($b,&wparam(3)); + &call ("_mul_1x1_mmx"); # a1·b1 + &movq ("mm7",$R); + + &mov ($a,&wparam(2)); + &mov ($b,&wparam(4)); + &call ("_mul_1x1_mmx"); # a0·b0 + &movq ("mm6",$R); + + &mov ($a,&wparam(1)); + &mov ($b,&wparam(3)); + &xor ($a,&wparam(2)); + &xor ($b,&wparam(4)); + &call ("_mul_1x1_mmx"); # (a0+a1)·(b0+b1) + &pxor ($R,"mm7"); + &mov ($a,&wparam(0)); + &pxor ($R,"mm6"); # (a0+a1)·(b0+b1)-a1·b1-a0·b0 + + &movq ($A,$R); + &psllq ($R,32); + &pop ("edi"); + &psrlq ($A,32); + &pop ("esi"); + &pxor ($R,"mm6"); + &pop ("ebx"); + &pxor ($A,"mm7"); + &movq (&QWP(0,$a),$R); + &pop ("ebp"); + &movq (&QWP(8,$a),$A); + &emms (); + &ret (); +&set_label("ialu",16); +} + &push ("ebp"); + &push ("ebx"); + &push ("esi"); + &push ("edi"); + &stack_push(4+1); + + &mov ($a,&wparam(1)); + &mov ($b,&wparam(3)); + &call ("_mul_1x1_ialu"); # a1·b1 + &mov (&DWP(8,"esp"),$lo); + &mov (&DWP(12,"esp"),$hi); + + &mov ($a,&wparam(2)); + &mov ($b,&wparam(4)); + &call ("_mul_1x1_ialu"); # a0·b0 + &mov (&DWP(0,"esp"),$lo); + &mov (&DWP(4,"esp"),$hi); + + &mov ($a,&wparam(1)); + &mov ($b,&wparam(3)); + &xor ($a,&wparam(2)); + &xor ($b,&wparam(4)); + &call ("_mul_1x1_ialu"); # (a0+a1)·(b0+b1) + + &mov ("ebp",&wparam(0)); + @r=("ebx","ecx","edi","esi"); + &mov (@r[0],&DWP(0,"esp")); + &mov (@r[1],&DWP(4,"esp")); + &mov (@r[2],&DWP(8,"esp")); + &mov (@r[3],&DWP(12,"esp")); + + &xor ($lo,$hi); + &xor ($hi,@r[1]); + &xor ($lo,@r[0]); + &mov (&DWP(0,"ebp"),@r[0]); + &xor ($hi,@r[2]); + &mov (&DWP(12,"ebp"),@r[3]); + &xor ($lo,@r[3]); + &stack_pop(4+1); + &xor ($hi,@r[3]); + &pop ("edi"); + &xor ($lo,$hi); + &pop ("esi"); + &mov (&DWP(8,"ebp"),$hi); + &pop ("ebx"); + &mov (&DWP(4,"ebp"),$lo); + &pop ("ebp"); + &ret (); +&function_end_B("bn_GF2m_mul_2x2"); + +&asciz ("GF(2^m) Multiplication for x86, CRYPTOGAMS by "); + +&asm_finish(); diff --git a/libs/openssl/crypto/bn/asm/x86-mont.pl b/libs/openssl/crypto/bn/asm/x86-mont.pl new file mode 100755 index 00000000..89f4de61 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/x86-mont.pl @@ -0,0 +1,608 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# October 2005 +# +# This is a "teaser" code, as it can be improved in several ways... +# First of all non-SSE2 path should be implemented (yes, for now it +# performs Montgomery multiplication/convolution only on SSE2-capable +# CPUs such as P4, others fall down to original code). Then inner loop +# can be unrolled and modulo-scheduled to improve ILP and possibly +# moved to 128-bit XMM register bank (though it would require input +# rearrangement and/or increase bus bandwidth utilization). Dedicated +# squaring procedure should give further performance improvement... +# Yet, for being draft, the code improves rsa512 *sign* benchmark by +# 110%(!), rsa1024 one - by 70% and rsa4096 - by 20%:-) + +# December 2006 +# +# Modulo-scheduling SSE2 loops results in further 15-20% improvement. +# Integer-only code [being equipped with dedicated squaring procedure] +# gives ~40% on rsa512 sign benchmark... + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],$0); + +$sse2=0; +for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } + +&external_label("OPENSSL_ia32cap_P") if ($sse2); + +&function_begin("bn_mul_mont"); + +$i="edx"; +$j="ecx"; +$ap="esi"; $tp="esi"; # overlapping variables!!! +$rp="edi"; $bp="edi"; # overlapping variables!!! +$np="ebp"; +$num="ebx"; + +$_num=&DWP(4*0,"esp"); # stack top layout +$_rp=&DWP(4*1,"esp"); +$_ap=&DWP(4*2,"esp"); +$_bp=&DWP(4*3,"esp"); +$_np=&DWP(4*4,"esp"); +$_n0=&DWP(4*5,"esp"); $_n0q=&QWP(4*5,"esp"); +$_sp=&DWP(4*6,"esp"); +$_bpend=&DWP(4*7,"esp"); +$frame=32; # size of above frame rounded up to 16n + + &xor ("eax","eax"); + &mov ("edi",&wparam(5)); # int num + &cmp ("edi",4); + &jl (&label("just_leave")); + + &lea ("esi",&wparam(0)); # put aside pointer to argument block + &lea ("edx",&wparam(1)); # load ap + &mov ("ebp","esp"); # saved stack pointer! + &add ("edi",2); # extra two words on top of tp + &neg ("edi"); + &lea ("esp",&DWP(-$frame,"esp","edi",4)); # alloca($frame+4*(num+2)) + &neg ("edi"); + + # minimize cache contention by arraning 2K window between stack + # pointer and ap argument [np is also position sensitive vector, + # but it's assumed to be near ap, as it's allocated at ~same + # time]. + &mov ("eax","esp"); + &sub ("eax","edx"); + &and ("eax",2047); + &sub ("esp","eax"); # this aligns sp and ap modulo 2048 + + &xor ("edx","esp"); + &and ("edx",2048); + &xor ("edx",2048); + &sub ("esp","edx"); # this splits them apart modulo 4096 + + &and ("esp",-64); # align to cache line + + # Some OSes, *cough*-dows, insist on stack being "wired" to + # physical memory in strictly sequential manner, i.e. if stack + # allocation spans two pages, then reference to farmost one can + # be punishable by SEGV. But page walking can do good even on + # other OSes, because it guarantees that villain thread hits + # the guard page before it can make damage to innocent one... + &mov ("eax","ebp"); + &sub ("eax","esp"); + &and ("eax",-4096); +&set_label("page_walk"); + &mov ("edx",&DWP(0,"esp","eax")); + &sub ("eax",4096); + &data_byte(0x2e); + &jnc (&label("page_walk")); + + ################################# load argument block... + &mov ("eax",&DWP(0*4,"esi"));# BN_ULONG *rp + &mov ("ebx",&DWP(1*4,"esi"));# const BN_ULONG *ap + &mov ("ecx",&DWP(2*4,"esi"));# const BN_ULONG *bp + &mov ("edx",&DWP(3*4,"esi"));# const BN_ULONG *np + &mov ("esi",&DWP(4*4,"esi"));# const BN_ULONG *n0 + #&mov ("edi",&DWP(5*4,"esi"));# int num + + &mov ("esi",&DWP(0,"esi")); # pull n0[0] + &mov ($_rp,"eax"); # ... save a copy of argument block + &mov ($_ap,"ebx"); + &mov ($_bp,"ecx"); + &mov ($_np,"edx"); + &mov ($_n0,"esi"); + &lea ($num,&DWP(-3,"edi")); # num=num-1 to assist modulo-scheduling + #&mov ($_num,$num); # redundant as $num is not reused + &mov ($_sp,"ebp"); # saved stack pointer! + +if($sse2) { +$acc0="mm0"; # mmx register bank layout +$acc1="mm1"; +$car0="mm2"; +$car1="mm3"; +$mul0="mm4"; +$mul1="mm5"; +$temp="mm6"; +$mask="mm7"; + + &picmeup("eax","OPENSSL_ia32cap_P"); + &bt (&DWP(0,"eax"),26); + &jnc (&label("non_sse2")); + + &mov ("eax",-1); + &movd ($mask,"eax"); # mask 32 lower bits + + &mov ($ap,$_ap); # load input pointers + &mov ($bp,$_bp); + &mov ($np,$_np); + + &xor ($i,$i); # i=0 + &xor ($j,$j); # j=0 + + &movd ($mul0,&DWP(0,$bp)); # bp[0] + &movd ($mul1,&DWP(0,$ap)); # ap[0] + &movd ($car1,&DWP(0,$np)); # np[0] + + &pmuludq($mul1,$mul0); # ap[0]*bp[0] + &movq ($car0,$mul1); + &movq ($acc0,$mul1); # I wish movd worked for + &pand ($acc0,$mask); # inter-register transfers + + &pmuludq($mul1,$_n0q); # *=n0 + + &pmuludq($car1,$mul1); # "t[0]"*np[0]*n0 + &paddq ($car1,$acc0); + + &movd ($acc1,&DWP(4,$np)); # np[1] + &movd ($acc0,&DWP(4,$ap)); # ap[1] + + &psrlq ($car0,32); + &psrlq ($car1,32); + + &inc ($j); # j++ +&set_label("1st",16); + &pmuludq($acc0,$mul0); # ap[j]*bp[0] + &pmuludq($acc1,$mul1); # np[j]*m1 + &paddq ($car0,$acc0); # +=c0 + &paddq ($car1,$acc1); # +=c1 + + &movq ($acc0,$car0); + &pand ($acc0,$mask); + &movd ($acc1,&DWP(4,$np,$j,4)); # np[j+1] + &paddq ($car1,$acc0); # +=ap[j]*bp[0]; + &movd ($acc0,&DWP(4,$ap,$j,4)); # ap[j+1] + &psrlq ($car0,32); + &movd (&DWP($frame-4,"esp",$j,4),$car1); # tp[j-1]= + &psrlq ($car1,32); + + &lea ($j,&DWP(1,$j)); + &cmp ($j,$num); + &jl (&label("1st")); + + &pmuludq($acc0,$mul0); # ap[num-1]*bp[0] + &pmuludq($acc1,$mul1); # np[num-1]*m1 + &paddq ($car0,$acc0); # +=c0 + &paddq ($car1,$acc1); # +=c1 + + &movq ($acc0,$car0); + &pand ($acc0,$mask); + &paddq ($car1,$acc0); # +=ap[num-1]*bp[0]; + &movd (&DWP($frame-4,"esp",$j,4),$car1); # tp[num-2]= + + &psrlq ($car0,32); + &psrlq ($car1,32); + + &paddq ($car1,$car0); + &movq (&QWP($frame,"esp",$num,4),$car1); # tp[num].tp[num-1] + + &inc ($i); # i++ +&set_label("outer"); + &xor ($j,$j); # j=0 + + &movd ($mul0,&DWP(0,$bp,$i,4)); # bp[i] + &movd ($mul1,&DWP(0,$ap)); # ap[0] + &movd ($temp,&DWP($frame,"esp")); # tp[0] + &movd ($car1,&DWP(0,$np)); # np[0] + &pmuludq($mul1,$mul0); # ap[0]*bp[i] + + &paddq ($mul1,$temp); # +=tp[0] + &movq ($acc0,$mul1); + &movq ($car0,$mul1); + &pand ($acc0,$mask); + + &pmuludq($mul1,$_n0q); # *=n0 + + &pmuludq($car1,$mul1); + &paddq ($car1,$acc0); + + &movd ($temp,&DWP($frame+4,"esp")); # tp[1] + &movd ($acc1,&DWP(4,$np)); # np[1] + &movd ($acc0,&DWP(4,$ap)); # ap[1] + + &psrlq ($car0,32); + &psrlq ($car1,32); + &paddq ($car0,$temp); # +=tp[1] + + &inc ($j); # j++ + &dec ($num); +&set_label("inner"); + &pmuludq($acc0,$mul0); # ap[j]*bp[i] + &pmuludq($acc1,$mul1); # np[j]*m1 + &paddq ($car0,$acc0); # +=c0 + &paddq ($car1,$acc1); # +=c1 + + &movq ($acc0,$car0); + &movd ($temp,&DWP($frame+4,"esp",$j,4));# tp[j+1] + &pand ($acc0,$mask); + &movd ($acc1,&DWP(4,$np,$j,4)); # np[j+1] + &paddq ($car1,$acc0); # +=ap[j]*bp[i]+tp[j] + &movd ($acc0,&DWP(4,$ap,$j,4)); # ap[j+1] + &psrlq ($car0,32); + &movd (&DWP($frame-4,"esp",$j,4),$car1);# tp[j-1]= + &psrlq ($car1,32); + &paddq ($car0,$temp); # +=tp[j+1] + + &dec ($num); + &lea ($j,&DWP(1,$j)); # j++ + &jnz (&label("inner")); + + &mov ($num,$j); + &pmuludq($acc0,$mul0); # ap[num-1]*bp[i] + &pmuludq($acc1,$mul1); # np[num-1]*m1 + &paddq ($car0,$acc0); # +=c0 + &paddq ($car1,$acc1); # +=c1 + + &movq ($acc0,$car0); + &pand ($acc0,$mask); + &paddq ($car1,$acc0); # +=ap[num-1]*bp[i]+tp[num-1] + &movd (&DWP($frame-4,"esp",$j,4),$car1); # tp[num-2]= + &psrlq ($car0,32); + &psrlq ($car1,32); + + &movd ($temp,&DWP($frame+4,"esp",$num,4)); # += tp[num] + &paddq ($car1,$car0); + &paddq ($car1,$temp); + &movq (&QWP($frame,"esp",$num,4),$car1); # tp[num].tp[num-1] + + &lea ($i,&DWP(1,$i)); # i++ + &cmp ($i,$num); + &jle (&label("outer")); + + &emms (); # done with mmx bank + &jmp (&label("common_tail")); + +&set_label("non_sse2",16); +} + +if (0) { + &mov ("esp",$_sp); + &xor ("eax","eax"); # signal "not fast enough [yet]" + &jmp (&label("just_leave")); + # While the below code provides competitive performance for + # all key lengthes on modern Intel cores, it's still more + # than 10% slower for 4096-bit key elsewhere:-( "Competitive" + # means compared to the original integer-only assembler. + # 512-bit RSA sign is better by ~40%, but that's about all + # one can say about all CPUs... +} else { +$inp="esi"; # integer path uses these registers differently +$word="edi"; +$carry="ebp"; + + &mov ($inp,$_ap); + &lea ($carry,&DWP(1,$num)); + &mov ($word,$_bp); + &xor ($j,$j); # j=0 + &mov ("edx",$inp); + &and ($carry,1); # see if num is even + &sub ("edx",$word); # see if ap==bp + &lea ("eax",&DWP(4,$word,$num,4)); # &bp[num] + &or ($carry,"edx"); + &mov ($word,&DWP(0,$word)); # bp[0] + &jz (&label("bn_sqr_mont")); + &mov ($_bpend,"eax"); + &mov ("eax",&DWP(0,$inp)); + &xor ("edx","edx"); + +&set_label("mull",16); + &mov ($carry,"edx"); + &mul ($word); # ap[j]*bp[0] + &add ($carry,"eax"); + &lea ($j,&DWP(1,$j)); + &adc ("edx",0); + &mov ("eax",&DWP(0,$inp,$j,4)); # ap[j+1] + &cmp ($j,$num); + &mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j]= + &jl (&label("mull")); + + &mov ($carry,"edx"); + &mul ($word); # ap[num-1]*bp[0] + &mov ($word,$_n0); + &add ("eax",$carry); + &mov ($inp,$_np); + &adc ("edx",0); + &imul ($word,&DWP($frame,"esp")); # n0*tp[0] + + &mov (&DWP($frame,"esp",$num,4),"eax"); # tp[num-1]= + &xor ($j,$j); + &mov (&DWP($frame+4,"esp",$num,4),"edx"); # tp[num]= + &mov (&DWP($frame+8,"esp",$num,4),$j); # tp[num+1]= + + &mov ("eax",&DWP(0,$inp)); # np[0] + &mul ($word); # np[0]*m + &add ("eax",&DWP($frame,"esp")); # +=tp[0] + &mov ("eax",&DWP(4,$inp)); # np[1] + &adc ("edx",0); + &inc ($j); + + &jmp (&label("2ndmadd")); + +&set_label("1stmadd",16); + &mov ($carry,"edx"); + &mul ($word); # ap[j]*bp[i] + &add ($carry,&DWP($frame,"esp",$j,4)); # +=tp[j] + &lea ($j,&DWP(1,$j)); + &adc ("edx",0); + &add ($carry,"eax"); + &mov ("eax",&DWP(0,$inp,$j,4)); # ap[j+1] + &adc ("edx",0); + &cmp ($j,$num); + &mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j]= + &jl (&label("1stmadd")); + + &mov ($carry,"edx"); + &mul ($word); # ap[num-1]*bp[i] + &add ("eax",&DWP($frame,"esp",$num,4)); # +=tp[num-1] + &mov ($word,$_n0); + &adc ("edx",0); + &mov ($inp,$_np); + &add ($carry,"eax"); + &adc ("edx",0); + &imul ($word,&DWP($frame,"esp")); # n0*tp[0] + + &xor ($j,$j); + &add ("edx",&DWP($frame+4,"esp",$num,4)); # carry+=tp[num] + &mov (&DWP($frame,"esp",$num,4),$carry); # tp[num-1]= + &adc ($j,0); + &mov ("eax",&DWP(0,$inp)); # np[0] + &mov (&DWP($frame+4,"esp",$num,4),"edx"); # tp[num]= + &mov (&DWP($frame+8,"esp",$num,4),$j); # tp[num+1]= + + &mul ($word); # np[0]*m + &add ("eax",&DWP($frame,"esp")); # +=tp[0] + &mov ("eax",&DWP(4,$inp)); # np[1] + &adc ("edx",0); + &mov ($j,1); + +&set_label("2ndmadd",16); + &mov ($carry,"edx"); + &mul ($word); # np[j]*m + &add ($carry,&DWP($frame,"esp",$j,4)); # +=tp[j] + &lea ($j,&DWP(1,$j)); + &adc ("edx",0); + &add ($carry,"eax"); + &mov ("eax",&DWP(0,$inp,$j,4)); # np[j+1] + &adc ("edx",0); + &cmp ($j,$num); + &mov (&DWP($frame-8,"esp",$j,4),$carry); # tp[j-1]= + &jl (&label("2ndmadd")); + + &mov ($carry,"edx"); + &mul ($word); # np[j]*m + &add ($carry,&DWP($frame,"esp",$num,4)); # +=tp[num-1] + &adc ("edx",0); + &add ($carry,"eax"); + &adc ("edx",0); + &mov (&DWP($frame-4,"esp",$num,4),$carry); # tp[num-2]= + + &xor ("eax","eax"); + &mov ($j,$_bp); # &bp[i] + &add ("edx",&DWP($frame+4,"esp",$num,4)); # carry+=tp[num] + &adc ("eax",&DWP($frame+8,"esp",$num,4)); # +=tp[num+1] + &lea ($j,&DWP(4,$j)); + &mov (&DWP($frame,"esp",$num,4),"edx"); # tp[num-1]= + &cmp ($j,$_bpend); + &mov (&DWP($frame+4,"esp",$num,4),"eax"); # tp[num]= + &je (&label("common_tail")); + + &mov ($word,&DWP(0,$j)); # bp[i+1] + &mov ($inp,$_ap); + &mov ($_bp,$j); # &bp[++i] + &xor ($j,$j); + &xor ("edx","edx"); + &mov ("eax",&DWP(0,$inp)); + &jmp (&label("1stmadd")); + +&set_label("bn_sqr_mont",16); +$sbit=$num; + &mov ($_num,$num); + &mov ($_bp,$j); # i=0 + + &mov ("eax",$word); # ap[0] + &mul ($word); # ap[0]*ap[0] + &mov (&DWP($frame,"esp"),"eax"); # tp[0]= + &mov ($sbit,"edx"); + &shr ("edx",1); + &and ($sbit,1); + &inc ($j); +&set_label("sqr",16); + &mov ("eax",&DWP(0,$inp,$j,4)); # ap[j] + &mov ($carry,"edx"); + &mul ($word); # ap[j]*ap[0] + &add ("eax",$carry); + &lea ($j,&DWP(1,$j)); + &adc ("edx",0); + &lea ($carry,&DWP(0,$sbit,"eax",2)); + &shr ("eax",31); + &cmp ($j,$_num); + &mov ($sbit,"eax"); + &mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j]= + &jl (&label("sqr")); + + &mov ("eax",&DWP(0,$inp,$j,4)); # ap[num-1] + &mov ($carry,"edx"); + &mul ($word); # ap[num-1]*ap[0] + &add ("eax",$carry); + &mov ($word,$_n0); + &adc ("edx",0); + &mov ($inp,$_np); + &lea ($carry,&DWP(0,$sbit,"eax",2)); + &imul ($word,&DWP($frame,"esp")); # n0*tp[0] + &shr ("eax",31); + &mov (&DWP($frame,"esp",$j,4),$carry); # tp[num-1]= + + &lea ($carry,&DWP(0,"eax","edx",2)); + &mov ("eax",&DWP(0,$inp)); # np[0] + &shr ("edx",31); + &mov (&DWP($frame+4,"esp",$j,4),$carry); # tp[num]= + &mov (&DWP($frame+8,"esp",$j,4),"edx"); # tp[num+1]= + + &mul ($word); # np[0]*m + &add ("eax",&DWP($frame,"esp")); # +=tp[0] + &mov ($num,$j); + &adc ("edx",0); + &mov ("eax",&DWP(4,$inp)); # np[1] + &mov ($j,1); + +&set_label("3rdmadd",16); + &mov ($carry,"edx"); + &mul ($word); # np[j]*m + &add ($carry,&DWP($frame,"esp",$j,4)); # +=tp[j] + &adc ("edx",0); + &add ($carry,"eax"); + &mov ("eax",&DWP(4,$inp,$j,4)); # np[j+1] + &adc ("edx",0); + &mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j-1]= + + &mov ($carry,"edx"); + &mul ($word); # np[j+1]*m + &add ($carry,&DWP($frame+4,"esp",$j,4)); # +=tp[j+1] + &lea ($j,&DWP(2,$j)); + &adc ("edx",0); + &add ($carry,"eax"); + &mov ("eax",&DWP(0,$inp,$j,4)); # np[j+2] + &adc ("edx",0); + &cmp ($j,$num); + &mov (&DWP($frame-8,"esp",$j,4),$carry); # tp[j]= + &jl (&label("3rdmadd")); + + &mov ($carry,"edx"); + &mul ($word); # np[j]*m + &add ($carry,&DWP($frame,"esp",$num,4)); # +=tp[num-1] + &adc ("edx",0); + &add ($carry,"eax"); + &adc ("edx",0); + &mov (&DWP($frame-4,"esp",$num,4),$carry); # tp[num-2]= + + &mov ($j,$_bp); # i + &xor ("eax","eax"); + &mov ($inp,$_ap); + &add ("edx",&DWP($frame+4,"esp",$num,4)); # carry+=tp[num] + &adc ("eax",&DWP($frame+8,"esp",$num,4)); # +=tp[num+1] + &mov (&DWP($frame,"esp",$num,4),"edx"); # tp[num-1]= + &cmp ($j,$num); + &mov (&DWP($frame+4,"esp",$num,4),"eax"); # tp[num]= + &je (&label("common_tail")); + + &mov ($word,&DWP(4,$inp,$j,4)); # ap[i] + &lea ($j,&DWP(1,$j)); + &mov ("eax",$word); + &mov ($_bp,$j); # ++i + &mul ($word); # ap[i]*ap[i] + &add ("eax",&DWP($frame,"esp",$j,4)); # +=tp[i] + &adc ("edx",0); + &mov (&DWP($frame,"esp",$j,4),"eax"); # tp[i]= + &xor ($carry,$carry); + &cmp ($j,$num); + &lea ($j,&DWP(1,$j)); + &je (&label("sqrlast")); + + &mov ($sbit,"edx"); # zaps $num + &shr ("edx",1); + &and ($sbit,1); +&set_label("sqradd",16); + &mov ("eax",&DWP(0,$inp,$j,4)); # ap[j] + &mov ($carry,"edx"); + &mul ($word); # ap[j]*ap[i] + &add ("eax",$carry); + &lea ($carry,&DWP(0,"eax","eax")); + &adc ("edx",0); + &shr ("eax",31); + &add ($carry,&DWP($frame,"esp",$j,4)); # +=tp[j] + &lea ($j,&DWP(1,$j)); + &adc ("eax",0); + &add ($carry,$sbit); + &adc ("eax",0); + &cmp ($j,$_num); + &mov (&DWP($frame-4,"esp",$j,4),$carry); # tp[j]= + &mov ($sbit,"eax"); + &jle (&label("sqradd")); + + &mov ($carry,"edx"); + &add ("edx","edx"); + &shr ($carry,31); + &add ("edx",$sbit); + &adc ($carry,0); +&set_label("sqrlast"); + &mov ($word,$_n0); + &mov ($inp,$_np); + &imul ($word,&DWP($frame,"esp")); # n0*tp[0] + + &add ("edx",&DWP($frame,"esp",$j,4)); # +=tp[num] + &mov ("eax",&DWP(0,$inp)); # np[0] + &adc ($carry,0); + &mov (&DWP($frame,"esp",$j,4),"edx"); # tp[num]= + &mov (&DWP($frame+4,"esp",$j,4),$carry); # tp[num+1]= + + &mul ($word); # np[0]*m + &add ("eax",&DWP($frame,"esp")); # +=tp[0] + &lea ($num,&DWP(-1,$j)); + &adc ("edx",0); + &mov ($j,1); + &mov ("eax",&DWP(4,$inp)); # np[1] + + &jmp (&label("3rdmadd")); +} + +&set_label("common_tail",16); + &mov ($np,$_np); # load modulus pointer + &mov ($rp,$_rp); # load result pointer + &lea ($tp,&DWP($frame,"esp")); # [$ap and $bp are zapped] + + &mov ("eax",&DWP(0,$tp)); # tp[0] + &mov ($j,$num); # j=num-1 + &xor ($i,$i); # i=0 and clear CF! + +&set_label("sub",16); + &sbb ("eax",&DWP(0,$np,$i,4)); + &mov (&DWP(0,$rp,$i,4),"eax"); # rp[i]=tp[i]-np[i] + &dec ($j); # doesn't affect CF! + &mov ("eax",&DWP(4,$tp,$i,4)); # tp[i+1] + &lea ($i,&DWP(1,$i)); # i++ + &jge (&label("sub")); + + &sbb ("eax",0); # handle upmost overflow bit + &and ($tp,"eax"); + ¬ ("eax"); + &mov ($np,$rp); + &and ($np,"eax"); + &or ($tp,$np); # tp=carry?tp:rp + +&set_label("copy",16); # copy or in-place refresh + &mov ("eax",&DWP(0,$tp,$num,4)); + &mov (&DWP(0,$rp,$num,4),"eax"); # rp[i]=tp[i] + &mov (&DWP($frame,"esp",$num,4),$j); # zap temporary vector + &dec ($num); + &jge (&label("copy")); + + &mov ("esp",$_sp); # pull saved stack pointer + &mov ("eax",1); +&set_label("just_leave"); +&function_end("bn_mul_mont"); + +&asciz("Montgomery Multiplication for x86, CRYPTOGAMS by "); + +&asm_finish(); diff --git a/libs/openssl/crypto/bn/asm/x86.pl b/libs/openssl/crypto/bn/asm/x86.pl new file mode 100644 index 00000000..1bc4f1bb --- /dev/null +++ b/libs/openssl/crypto/bn/asm/x86.pl @@ -0,0 +1,28 @@ +#!/usr/local/bin/perl + +push(@INC,"perlasm","../../perlasm"); +require "x86asm.pl"; + +require("x86/mul_add.pl"); +require("x86/mul.pl"); +require("x86/sqr.pl"); +require("x86/div.pl"); +require("x86/add.pl"); +require("x86/sub.pl"); +require("x86/comba.pl"); + +&asm_init($ARGV[0],$0); + +&bn_mul_add_words("bn_mul_add_words"); +&bn_mul_words("bn_mul_words"); +&bn_sqr_words("bn_sqr_words"); +&bn_div_words("bn_div_words"); +&bn_add_words("bn_add_words"); +&bn_sub_words("bn_sub_words"); +&bn_mul_comba("bn_mul_comba8",8); +&bn_mul_comba("bn_mul_comba4",4); +&bn_sqr_comba("bn_sqr_comba8",8); +&bn_sqr_comba("bn_sqr_comba4",4); + +&asm_finish(); + diff --git a/libs/openssl/crypto/bn/asm/x86/add.pl b/libs/openssl/crypto/bn/asm/x86/add.pl new file mode 100644 index 00000000..0b5cf583 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/x86/add.pl @@ -0,0 +1,76 @@ +#!/usr/local/bin/perl +# x86 assember + +sub bn_add_words + { + local($name)=@_; + + &function_begin($name,""); + + &comment(""); + $a="esi"; + $b="edi"; + $c="eax"; + $r="ebx"; + $tmp1="ecx"; + $tmp2="edx"; + $num="ebp"; + + &mov($r,&wparam(0)); # get r + &mov($a,&wparam(1)); # get a + &mov($b,&wparam(2)); # get b + &mov($num,&wparam(3)); # get num + &xor($c,$c); # clear carry + &and($num,0xfffffff8); # num / 8 + + &jz(&label("aw_finish")); + + &set_label("aw_loop",0); + for ($i=0; $i<8; $i++) + { + &comment("Round $i"); + + &mov($tmp1,&DWP($i*4,$a,"",0)); # *a + &mov($tmp2,&DWP($i*4,$b,"",0)); # *b + &add($tmp1,$c); + &mov($c,0); + &adc($c,$c); + &add($tmp1,$tmp2); + &adc($c,0); + &mov(&DWP($i*4,$r,"",0),$tmp1); # *r + } + + &comment(""); + &add($a,32); + &add($b,32); + &add($r,32); + &sub($num,8); + &jnz(&label("aw_loop")); + + &set_label("aw_finish",0); + &mov($num,&wparam(3)); # get num + &and($num,7); + &jz(&label("aw_end")); + + for ($i=0; $i<7; $i++) + { + &comment("Tail Round $i"); + &mov($tmp1,&DWP($i*4,$a,"",0)); # *a + &mov($tmp2,&DWP($i*4,$b,"",0));# *b + &add($tmp1,$c); + &mov($c,0); + &adc($c,$c); + &add($tmp1,$tmp2); + &adc($c,0); + &dec($num) if ($i != 6); + &mov(&DWP($i*4,$r,"",0),$tmp1); # *a + &jz(&label("aw_end")) if ($i != 6); + } + &set_label("aw_end",0); + +# &mov("eax",$c); # $c is "eax" + + &function_end($name); + } + +1; diff --git a/libs/openssl/crypto/bn/asm/x86/comba.pl b/libs/openssl/crypto/bn/asm/x86/comba.pl new file mode 100644 index 00000000..22912536 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/x86/comba.pl @@ -0,0 +1,277 @@ +#!/usr/local/bin/perl +# x86 assember + +sub mul_add_c + { + local($a,$ai,$b,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; + + # pos == -1 if eax and edx are pre-loaded, 0 to load from next + # words, and 1 if load return value + + &comment("mul a[$ai]*b[$bi]"); + + # "eax" and "edx" will always be pre-loaded. + # &mov("eax",&DWP($ai*4,$a,"",0)) ; + # &mov("edx",&DWP($bi*4,$b,"",0)); + + &mul("edx"); + &add($c0,"eax"); + &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # laod next a + &mov("eax",&wparam(0)) if $pos > 0; # load r[] + ### + &adc($c1,"edx"); + &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 0; # laod next b + &mov("edx",&DWP(($nb)*4,$b,"",0)) if $pos == 1; # laod next b + ### + &adc($c2,0); + # is pos > 1, it means it is the last loop + &mov(&DWP($i*4,"eax","",0),$c0) if $pos > 0; # save r[]; + &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # laod next a + } + +sub sqr_add_c + { + local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; + + # pos == -1 if eax and edx are pre-loaded, 0 to load from next + # words, and 1 if load return value + + &comment("sqr a[$ai]*a[$bi]"); + + # "eax" and "edx" will always be pre-loaded. + # &mov("eax",&DWP($ai*4,$a,"",0)) ; + # &mov("edx",&DWP($bi*4,$b,"",0)); + + if ($ai == $bi) + { &mul("eax");} + else + { &mul("edx");} + &add($c0,"eax"); + &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a + ### + &adc($c1,"edx"); + &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos == 1) && ($na != $nb); + ### + &adc($c2,0); + # is pos > 1, it means it is the last loop + &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[]; + &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b + } + +sub sqr_add_c2 + { + local($r,$a,$ai,$bi,$c0,$c1,$c2,$pos,$i,$na,$nb)=@_; + + # pos == -1 if eax and edx are pre-loaded, 0 to load from next + # words, and 1 if load return value + + &comment("sqr a[$ai]*a[$bi]"); + + # "eax" and "edx" will always be pre-loaded. + # &mov("eax",&DWP($ai*4,$a,"",0)) ; + # &mov("edx",&DWP($bi*4,$a,"",0)); + + if ($ai == $bi) + { &mul("eax");} + else + { &mul("edx");} + &add("eax","eax"); + ### + &adc("edx","edx"); + ### + &adc($c2,0); + &add($c0,"eax"); + &adc($c1,"edx"); + &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 0; # load next a + &mov("eax",&DWP(($na)*4,$a,"",0)) if $pos == 1; # load next b + &adc($c2,0); + &mov(&DWP($i*4,$r,"",0),$c0) if $pos > 0; # save r[]; + &mov("edx",&DWP(($nb)*4,$a,"",0)) if ($pos <= 1) && ($na != $nb); + ### + } + +sub bn_mul_comba + { + local($name,$num)=@_; + local($a,$b,$c0,$c1,$c2); + local($i,$as,$ae,$bs,$be,$ai,$bi); + local($tot,$end); + + &function_begin_B($name,""); + + $c0="ebx"; + $c1="ecx"; + $c2="ebp"; + $a="esi"; + $b="edi"; + + $as=0; + $ae=0; + $bs=0; + $be=0; + $tot=$num+$num-1; + + &push("esi"); + &mov($a,&wparam(1)); + &push("edi"); + &mov($b,&wparam(2)); + &push("ebp"); + &push("ebx"); + + &xor($c0,$c0); + &mov("eax",&DWP(0,$a,"",0)); # load the first word + &xor($c1,$c1); + &mov("edx",&DWP(0,$b,"",0)); # load the first second + + for ($i=0; $i<$tot; $i++) + { + $ai=$as; + $bi=$bs; + $end=$be+1; + + &comment("################## Calculate word $i"); + + for ($j=$bs; $j<$end; $j++) + { + &xor($c2,$c2) if ($j == $bs); + if (($j+1) == $end) + { + $v=1; + $v=2 if (($i+1) == $tot); + } + else + { $v=0; } + if (($j+1) != $end) + { + $na=($ai-1); + $nb=($bi+1); + } + else + { + $na=$as+($i < ($num-1)); + $nb=$bs+($i >= ($num-1)); + } +#printf STDERR "[$ai,$bi] -> [$na,$nb]\n"; + &mul_add_c($a,$ai,$b,$bi,$c0,$c1,$c2,$v,$i,$na,$nb); + if ($v) + { + &comment("saved r[$i]"); + # &mov("eax",&wparam(0)); + # &mov(&DWP($i*4,"eax","",0),$c0); + ($c0,$c1,$c2)=($c1,$c2,$c0); + } + $ai--; + $bi++; + } + $as++ if ($i < ($num-1)); + $ae++ if ($i >= ($num-1)); + + $bs++ if ($i >= ($num-1)); + $be++ if ($i < ($num-1)); + } + &comment("save r[$i]"); + # &mov("eax",&wparam(0)); + &mov(&DWP($i*4,"eax","",0),$c0); + + &pop("ebx"); + &pop("ebp"); + &pop("edi"); + &pop("esi"); + &ret(); + &function_end_B($name); + } + +sub bn_sqr_comba + { + local($name,$num)=@_; + local($r,$a,$c0,$c1,$c2)=@_; + local($i,$as,$ae,$bs,$be,$ai,$bi); + local($b,$tot,$end,$half); + + &function_begin_B($name,""); + + $c0="ebx"; + $c1="ecx"; + $c2="ebp"; + $a="esi"; + $r="edi"; + + &push("esi"); + &push("edi"); + &push("ebp"); + &push("ebx"); + &mov($r,&wparam(0)); + &mov($a,&wparam(1)); + &xor($c0,$c0); + &xor($c1,$c1); + &mov("eax",&DWP(0,$a,"",0)); # load the first word + + $as=0; + $ae=0; + $bs=0; + $be=0; + $tot=$num+$num-1; + + for ($i=0; $i<$tot; $i++) + { + $ai=$as; + $bi=$bs; + $end=$be+1; + + &comment("############### Calculate word $i"); + for ($j=$bs; $j<$end; $j++) + { + &xor($c2,$c2) if ($j == $bs); + if (($ai-1) < ($bi+1)) + { + $v=1; + $v=2 if ($i+1) == $tot; + } + else + { $v=0; } + if (!$v) + { + $na=$ai-1; + $nb=$bi+1; + } + else + { + $na=$as+($i < ($num-1)); + $nb=$bs+($i >= ($num-1)); + } + if ($ai == $bi) + { + &sqr_add_c($r,$a,$ai,$bi, + $c0,$c1,$c2,$v,$i,$na,$nb); + } + else + { + &sqr_add_c2($r,$a,$ai,$bi, + $c0,$c1,$c2,$v,$i,$na,$nb); + } + if ($v) + { + &comment("saved r[$i]"); + #&mov(&DWP($i*4,$r,"",0),$c0); + ($c0,$c1,$c2)=($c1,$c2,$c0); + last; + } + $ai--; + $bi++; + } + $as++ if ($i < ($num-1)); + $ae++ if ($i >= ($num-1)); + + $bs++ if ($i >= ($num-1)); + $be++ if ($i < ($num-1)); + } + &mov(&DWP($i*4,$r,"",0),$c0); + &pop("ebx"); + &pop("ebp"); + &pop("edi"); + &pop("esi"); + &ret(); + &function_end_B($name); + } + +1; diff --git a/libs/openssl/crypto/bn/asm/x86/div.pl b/libs/openssl/crypto/bn/asm/x86/div.pl new file mode 100644 index 00000000..0e90152c --- /dev/null +++ b/libs/openssl/crypto/bn/asm/x86/div.pl @@ -0,0 +1,15 @@ +#!/usr/local/bin/perl +# x86 assember + +sub bn_div_words + { + local($name)=@_; + + &function_begin($name,""); + &mov("edx",&wparam(0)); # + &mov("eax",&wparam(1)); # + &mov("ebx",&wparam(2)); # + &div("ebx"); + &function_end($name); + } +1; diff --git a/libs/openssl/crypto/bn/asm/x86/f b/libs/openssl/crypto/bn/asm/x86/f new file mode 100644 index 00000000..22e41122 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/x86/f @@ -0,0 +1,3 @@ +#!/usr/local/bin/perl +# x86 assember + diff --git a/libs/openssl/crypto/bn/asm/x86/mul.pl b/libs/openssl/crypto/bn/asm/x86/mul.pl new file mode 100644 index 00000000..674cb9b0 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/x86/mul.pl @@ -0,0 +1,77 @@ +#!/usr/local/bin/perl +# x86 assember + +sub bn_mul_words + { + local($name)=@_; + + &function_begin($name,""); + + &comment(""); + $Low="eax"; + $High="edx"; + $a="ebx"; + $w="ecx"; + $r="edi"; + $c="esi"; + $num="ebp"; + + &xor($c,$c); # clear carry + &mov($r,&wparam(0)); # + &mov($a,&wparam(1)); # + &mov($num,&wparam(2)); # + &mov($w,&wparam(3)); # + + &and($num,0xfffffff8); # num / 8 + &jz(&label("mw_finish")); + + &set_label("mw_loop",0); + for ($i=0; $i<32; $i+=4) + { + &comment("Round $i"); + + &mov("eax",&DWP($i,$a,"",0)); # *a + &mul($w); # *a * w + &add("eax",$c); # L(t)+=c + # XXX + + &adc("edx",0); # H(t)+=carry + &mov(&DWP($i,$r,"",0),"eax"); # *r= L(t); + + &mov($c,"edx"); # c= H(t); + } + + &comment(""); + &add($a,32); + &add($r,32); + &sub($num,8); + &jz(&label("mw_finish")); + &jmp(&label("mw_loop")); + + &set_label("mw_finish",0); + &mov($num,&wparam(2)); # get num + &and($num,7); + &jnz(&label("mw_finish2")); + &jmp(&label("mw_end")); + + &set_label("mw_finish2",1); + for ($i=0; $i<7; $i++) + { + &comment("Tail Round $i"); + &mov("eax",&DWP($i*4,$a,"",0));# *a + &mul($w); # *a * w + &add("eax",$c); # L(t)+=c + # XXX + &adc("edx",0); # H(t)+=carry + &mov(&DWP($i*4,$r,"",0),"eax");# *r= L(t); + &mov($c,"edx"); # c= H(t); + &dec($num) if ($i != 7-1); + &jz(&label("mw_end")) if ($i != 7-1); + } + &set_label("mw_end",0); + &mov("eax",$c); + + &function_end($name); + } + +1; diff --git a/libs/openssl/crypto/bn/asm/x86/mul_add.pl b/libs/openssl/crypto/bn/asm/x86/mul_add.pl new file mode 100644 index 00000000..61830d3a --- /dev/null +++ b/libs/openssl/crypto/bn/asm/x86/mul_add.pl @@ -0,0 +1,87 @@ +#!/usr/local/bin/perl +# x86 assember + +sub bn_mul_add_words + { + local($name)=@_; + + &function_begin($name,""); + + &comment(""); + $Low="eax"; + $High="edx"; + $a="ebx"; + $w="ebp"; + $r="edi"; + $c="esi"; + + &xor($c,$c); # clear carry + &mov($r,&wparam(0)); # + + &mov("ecx",&wparam(2)); # + &mov($a,&wparam(1)); # + + &and("ecx",0xfffffff8); # num / 8 + &mov($w,&wparam(3)); # + + &push("ecx"); # Up the stack for a tmp variable + + &jz(&label("maw_finish")); + + &set_label("maw_loop",0); + + &mov(&swtmp(0),"ecx"); # + + for ($i=0; $i<32; $i+=4) + { + &comment("Round $i"); + + &mov("eax",&DWP($i,$a,"",0)); # *a + &mul($w); # *a * w + &add("eax",$c); # L(t)+= *r + &mov($c,&DWP($i,$r,"",0)); # L(t)+= *r + &adc("edx",0); # H(t)+=carry + &add("eax",$c); # L(t)+=c + &adc("edx",0); # H(t)+=carry + &mov(&DWP($i,$r,"",0),"eax"); # *r= L(t); + &mov($c,"edx"); # c= H(t); + } + + &comment(""); + &mov("ecx",&swtmp(0)); # + &add($a,32); + &add($r,32); + &sub("ecx",8); + &jnz(&label("maw_loop")); + + &set_label("maw_finish",0); + &mov("ecx",&wparam(2)); # get num + &and("ecx",7); + &jnz(&label("maw_finish2")); # helps branch prediction + &jmp(&label("maw_end")); + + &set_label("maw_finish2",1); + for ($i=0; $i<7; $i++) + { + &comment("Tail Round $i"); + &mov("eax",&DWP($i*4,$a,"",0));# *a + &mul($w); # *a * w + &add("eax",$c); # L(t)+=c + &mov($c,&DWP($i*4,$r,"",0)); # L(t)+= *r + &adc("edx",0); # H(t)+=carry + &add("eax",$c); + &adc("edx",0); # H(t)+=carry + &dec("ecx") if ($i != 7-1); + &mov(&DWP($i*4,$r,"",0),"eax"); # *r= L(t); + &mov($c,"edx"); # c= H(t); + &jz(&label("maw_end")) if ($i != 7-1); + } + &set_label("maw_end",0); + &mov("eax",$c); + + &pop("ecx"); # clear variable from + + &function_end($name); + } + +1; diff --git a/libs/openssl/crypto/bn/asm/x86/sqr.pl b/libs/openssl/crypto/bn/asm/x86/sqr.pl new file mode 100644 index 00000000..1f90993c --- /dev/null +++ b/libs/openssl/crypto/bn/asm/x86/sqr.pl @@ -0,0 +1,60 @@ +#!/usr/local/bin/perl +# x86 assember + +sub bn_sqr_words + { + local($name)=@_; + + &function_begin($name,""); + + &comment(""); + $r="esi"; + $a="edi"; + $num="ebx"; + + &mov($r,&wparam(0)); # + &mov($a,&wparam(1)); # + &mov($num,&wparam(2)); # + + &and($num,0xfffffff8); # num / 8 + &jz(&label("sw_finish")); + + &set_label("sw_loop",0); + for ($i=0; $i<32; $i+=4) + { + &comment("Round $i"); + &mov("eax",&DWP($i,$a,"",0)); # *a + # XXX + &mul("eax"); # *a * *a + &mov(&DWP($i*2,$r,"",0),"eax"); # + &mov(&DWP($i*2+4,$r,"",0),"edx");# + } + + &comment(""); + &add($a,32); + &add($r,64); + &sub($num,8); + &jnz(&label("sw_loop")); + + &set_label("sw_finish",0); + &mov($num,&wparam(2)); # get num + &and($num,7); + &jz(&label("sw_end")); + + for ($i=0; $i<7; $i++) + { + &comment("Tail Round $i"); + &mov("eax",&DWP($i*4,$a,"",0)); # *a + # XXX + &mul("eax"); # *a * *a + &mov(&DWP($i*8,$r,"",0),"eax"); # + &dec($num) if ($i != 7-1); + &mov(&DWP($i*8+4,$r,"",0),"edx"); + &jz(&label("sw_end")) if ($i != 7-1); + } + &set_label("sw_end",0); + + &function_end($name); + } + +1; diff --git a/libs/openssl/crypto/bn/asm/x86/sub.pl b/libs/openssl/crypto/bn/asm/x86/sub.pl new file mode 100644 index 00000000..837b0e1b --- /dev/null +++ b/libs/openssl/crypto/bn/asm/x86/sub.pl @@ -0,0 +1,76 @@ +#!/usr/local/bin/perl +# x86 assember + +sub bn_sub_words + { + local($name)=@_; + + &function_begin($name,""); + + &comment(""); + $a="esi"; + $b="edi"; + $c="eax"; + $r="ebx"; + $tmp1="ecx"; + $tmp2="edx"; + $num="ebp"; + + &mov($r,&wparam(0)); # get r + &mov($a,&wparam(1)); # get a + &mov($b,&wparam(2)); # get b + &mov($num,&wparam(3)); # get num + &xor($c,$c); # clear carry + &and($num,0xfffffff8); # num / 8 + + &jz(&label("aw_finish")); + + &set_label("aw_loop",0); + for ($i=0; $i<8; $i++) + { + &comment("Round $i"); + + &mov($tmp1,&DWP($i*4,$a,"",0)); # *a + &mov($tmp2,&DWP($i*4,$b,"",0)); # *b + &sub($tmp1,$c); + &mov($c,0); + &adc($c,$c); + &sub($tmp1,$tmp2); + &adc($c,0); + &mov(&DWP($i*4,$r,"",0),$tmp1); # *r + } + + &comment(""); + &add($a,32); + &add($b,32); + &add($r,32); + &sub($num,8); + &jnz(&label("aw_loop")); + + &set_label("aw_finish",0); + &mov($num,&wparam(3)); # get num + &and($num,7); + &jz(&label("aw_end")); + + for ($i=0; $i<7; $i++) + { + &comment("Tail Round $i"); + &mov($tmp1,&DWP($i*4,$a,"",0)); # *a + &mov($tmp2,&DWP($i*4,$b,"",0));# *b + &sub($tmp1,$c); + &mov($c,0); + &adc($c,$c); + &sub($tmp1,$tmp2); + &adc($c,0); + &dec($num) if ($i != 6); + &mov(&DWP($i*4,$r,"",0),$tmp1); # *a + &jz(&label("aw_end")) if ($i != 6); + } + &set_label("aw_end",0); + +# &mov("eax",$c); # $c is "eax" + + &function_end($name); + } + +1; diff --git a/libs/openssl/crypto/bn/asm/x86_64-gcc.c b/libs/openssl/crypto/bn/asm/x86_64-gcc.c new file mode 100644 index 00000000..0a5bb285 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/x86_64-gcc.c @@ -0,0 +1,636 @@ +#include "../bn_lcl.h" +#if !(defined(__GNUC__) && __GNUC__>=2) +# include "../bn_asm.c" /* kind of dirty hack for Sun Studio */ +#else +/*- + * x86_64 BIGNUM accelerator version 0.1, December 2002. + * + * Implemented by Andy Polyakov for the OpenSSL + * project. + * + * Rights for redistribution and usage in source and binary forms are + * granted according to the OpenSSL license. Warranty of any kind is + * disclaimed. + * + * Q. Version 0.1? It doesn't sound like Andy, he used to assign real + * versions, like 1.0... + * A. Well, that's because this code is basically a quick-n-dirty + * proof-of-concept hack. As you can see it's implemented with + * inline assembler, which means that you're bound to GCC and that + * there might be enough room for further improvement. + * + * Q. Why inline assembler? + * A. x86_64 features own ABI which I'm not familiar with. This is + * why I decided to let the compiler take care of subroutine + * prologue/epilogue as well as register allocation. For reference. + * Win64 implements different ABI for AMD64, different from Linux. + * + * Q. How much faster does it get? + * A. 'apps/openssl speed rsa dsa' output with no-asm: + * + * sign verify sign/s verify/s + * rsa 512 bits 0.0006s 0.0001s 1683.8 18456.2 + * rsa 1024 bits 0.0028s 0.0002s 356.0 6407.0 + * rsa 2048 bits 0.0172s 0.0005s 58.0 1957.8 + * rsa 4096 bits 0.1155s 0.0018s 8.7 555.6 + * sign verify sign/s verify/s + * dsa 512 bits 0.0005s 0.0006s 2100.8 1768.3 + * dsa 1024 bits 0.0014s 0.0018s 692.3 559.2 + * dsa 2048 bits 0.0049s 0.0061s 204.7 165.0 + * + * 'apps/openssl speed rsa dsa' output with this module: + * + * sign verify sign/s verify/s + * rsa 512 bits 0.0004s 0.0000s 2767.1 33297.9 + * rsa 1024 bits 0.0012s 0.0001s 867.4 14674.7 + * rsa 2048 bits 0.0061s 0.0002s 164.0 5270.0 + * rsa 4096 bits 0.0384s 0.0006s 26.1 1650.8 + * sign verify sign/s verify/s + * dsa 512 bits 0.0002s 0.0003s 4442.2 3786.3 + * dsa 1024 bits 0.0005s 0.0007s 1835.1 1497.4 + * dsa 2048 bits 0.0016s 0.0020s 620.4 504.6 + * + * For the reference. IA-32 assembler implementation performs + * very much like 64-bit code compiled with no-asm on the same + * machine. + */ + +# ifdef _WIN64 +# define BN_ULONG unsigned long long +# else +# define BN_ULONG unsigned long +# endif + +# undef mul +# undef mul_add +# undef sqr + +/*- + * "m"(a), "+m"(r) is the way to favor DirectPath µ-code; + * "g"(0) let the compiler to decide where does it + * want to keep the value of zero; + */ +# define mul_add(r,a,word,carry) do { \ + register BN_ULONG high,low; \ + asm ("mulq %3" \ + : "=a"(low),"=d"(high) \ + : "a"(word),"m"(a) \ + : "cc"); \ + asm ("addq %2,%0; adcq %3,%1" \ + : "+r"(carry),"+d"(high)\ + : "a"(low),"g"(0) \ + : "cc"); \ + asm ("addq %2,%0; adcq %3,%1" \ + : "+m"(r),"+d"(high) \ + : "r"(carry),"g"(0) \ + : "cc"); \ + carry=high; \ + } while (0) + +# define mul(r,a,word,carry) do { \ + register BN_ULONG high,low; \ + asm ("mulq %3" \ + : "=a"(low),"=d"(high) \ + : "a"(word),"g"(a) \ + : "cc"); \ + asm ("addq %2,%0; adcq %3,%1" \ + : "+r"(carry),"+d"(high)\ + : "a"(low),"g"(0) \ + : "cc"); \ + (r)=carry, carry=high; \ + } while (0) + +# define sqr(r0,r1,a) \ + asm ("mulq %2" \ + : "=a"(r0),"=d"(r1) \ + : "a"(a) \ + : "cc"); + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, + BN_ULONG w) +{ + BN_ULONG c1 = 0; + + if (num <= 0) + return (c1); + + while (num & ~3) { + mul_add(rp[0], ap[0], w, c1); + mul_add(rp[1], ap[1], w, c1); + mul_add(rp[2], ap[2], w, c1); + mul_add(rp[3], ap[3], w, c1); + ap += 4; + rp += 4; + num -= 4; + } + if (num) { + mul_add(rp[0], ap[0], w, c1); + if (--num == 0) + return c1; + mul_add(rp[1], ap[1], w, c1); + if (--num == 0) + return c1; + mul_add(rp[2], ap[2], w, c1); + return c1; + } + + return (c1); +} + +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) +{ + BN_ULONG c1 = 0; + + if (num <= 0) + return (c1); + + while (num & ~3) { + mul(rp[0], ap[0], w, c1); + mul(rp[1], ap[1], w, c1); + mul(rp[2], ap[2], w, c1); + mul(rp[3], ap[3], w, c1); + ap += 4; + rp += 4; + num -= 4; + } + if (num) { + mul(rp[0], ap[0], w, c1); + if (--num == 0) + return c1; + mul(rp[1], ap[1], w, c1); + if (--num == 0) + return c1; + mul(rp[2], ap[2], w, c1); + } + return (c1); +} + +void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) +{ + if (n <= 0) + return; + + while (n & ~3) { + sqr(r[0], r[1], a[0]); + sqr(r[2], r[3], a[1]); + sqr(r[4], r[5], a[2]); + sqr(r[6], r[7], a[3]); + a += 4; + r += 8; + n -= 4; + } + if (n) { + sqr(r[0], r[1], a[0]); + if (--n == 0) + return; + sqr(r[2], r[3], a[1]); + if (--n == 0) + return; + sqr(r[4], r[5], a[2]); + } +} + +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) +{ + BN_ULONG ret, waste; + + asm("divq %4":"=a"(ret), "=d"(waste) + : "a"(l), "d"(h), "g"(d) + : "cc"); + + return ret; +} + +BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + int n) +{ + BN_ULONG ret = 0, i = 0; + + if (n <= 0) + return 0; + + asm volatile (" subq %2,%2 \n" + ".p2align 4 \n" + "1: movq (%4,%2,8),%0 \n" + " adcq (%5,%2,8),%0 \n" + " movq %0,(%3,%2,8) \n" + " leaq 1(%2),%2 \n" + " loop 1b \n" + " sbbq %0,%0 \n":"=&a" (ret), "+c"(n), + "=&r"(i) + :"r"(rp), "r"(ap), "r"(bp) + :"cc", "memory"); + + return ret & 1; +} + +# ifndef SIMICS +BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + int n) +{ + BN_ULONG ret = 0, i = 0; + + if (n <= 0) + return 0; + + asm volatile (" subq %2,%2 \n" + ".p2align 4 \n" + "1: movq (%4,%2,8),%0 \n" + " sbbq (%5,%2,8),%0 \n" + " movq %0,(%3,%2,8) \n" + " leaq 1(%2),%2 \n" + " loop 1b \n" + " sbbq %0,%0 \n":"=&a" (ret), "+c"(n), + "=&r"(i) + :"r"(rp), "r"(ap), "r"(bp) + :"cc", "memory"); + + return ret & 1; +} +# else +/* Simics 1.4<7 has buggy sbbq:-( */ +# define BN_MASK2 0xffffffffffffffffL +BN_ULONG bn_sub_words(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) +{ + BN_ULONG t1, t2; + int c = 0; + + if (n <= 0) + return ((BN_ULONG)0); + + for (;;) { + t1 = a[0]; + t2 = b[0]; + r[0] = (t1 - t2 - c) & BN_MASK2; + if (t1 != t2) + c = (t1 < t2); + if (--n <= 0) + break; + + t1 = a[1]; + t2 = b[1]; + r[1] = (t1 - t2 - c) & BN_MASK2; + if (t1 != t2) + c = (t1 < t2); + if (--n <= 0) + break; + + t1 = a[2]; + t2 = b[2]; + r[2] = (t1 - t2 - c) & BN_MASK2; + if (t1 != t2) + c = (t1 < t2); + if (--n <= 0) + break; + + t1 = a[3]; + t2 = b[3]; + r[3] = (t1 - t2 - c) & BN_MASK2; + if (t1 != t2) + c = (t1 < t2); + if (--n <= 0) + break; + + a += 4; + b += 4; + r += 4; + } + return (c); +} +# endif + +/* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */ +/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */ +/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */ +/* + * sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number + * c=(c2,c1,c0) + */ + +/* + * Keep in mind that carrying into high part of multiplication result + * can not overflow, because it cannot be all-ones. + */ +# if 0 +/* original macros are kept for reference purposes */ +# define mul_add_c(a,b,c0,c1,c2) { \ + BN_ULONG ta=(a),tb=(b); \ + t1 = ta * tb; \ + t2 = BN_UMULT_HIGH(ta,tb); \ + c0 += t1; t2 += (c0 for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# May 2011 +# +# The module implements bn_GF2m_mul_2x2 polynomial multiplication used +# in bn_gf2m.c. It's kind of low-hanging mechanical port from C for +# the time being... Except that it has two code paths: code suitable +# for any x86_64 CPU and PCLMULQDQ one suitable for Westmere and +# later. Improvement varies from one benchmark and µ-arch to another. +# Vanilla code path is at most 20% faster than compiler-generated code +# [not very impressive], while PCLMULQDQ - whole 85%-160% better on +# 163- and 571-bit ECDH benchmarks on Intel CPUs. Keep in mind that +# these coefficients are not ones for bn_GF2m_mul_2x2 itself, as not +# all CPU time is burnt in it... + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +($lo,$hi)=("%rax","%rdx"); $a=$lo; +($i0,$i1)=("%rsi","%rdi"); +($t0,$t1)=("%rbx","%rcx"); +($b,$mask)=("%rbp","%r8"); +($a1,$a2,$a4,$a8,$a12,$a48)=map("%r$_",(9..15)); +($R,$Tx)=("%xmm0","%xmm1"); + +$code.=<<___; +.text + +.type _mul_1x1,\@abi-omnipotent +.align 16 +_mul_1x1: + sub \$128+8,%rsp + mov \$-1,$a1 + lea ($a,$a),$i0 + shr \$3,$a1 + lea (,$a,4),$i1 + and $a,$a1 # a1=a&0x1fffffffffffffff + lea (,$a,8),$a8 + sar \$63,$a # broadcast 63rd bit + lea ($a1,$a1),$a2 + sar \$63,$i0 # broadcast 62nd bit + lea (,$a1,4),$a4 + and $b,$a + sar \$63,$i1 # boardcast 61st bit + mov $a,$hi # $a is $lo + shl \$63,$lo + and $b,$i0 + shr \$1,$hi + mov $i0,$t1 + shl \$62,$i0 + and $b,$i1 + shr \$2,$t1 + xor $i0,$lo + mov $i1,$t0 + shl \$61,$i1 + xor $t1,$hi + shr \$3,$t0 + xor $i1,$lo + xor $t0,$hi + + mov $a1,$a12 + movq \$0,0(%rsp) # tab[0]=0 + xor $a2,$a12 # a1^a2 + mov $a1,8(%rsp) # tab[1]=a1 + mov $a4,$a48 + mov $a2,16(%rsp) # tab[2]=a2 + xor $a8,$a48 # a4^a8 + mov $a12,24(%rsp) # tab[3]=a1^a2 + + xor $a4,$a1 + mov $a4,32(%rsp) # tab[4]=a4 + xor $a4,$a2 + mov $a1,40(%rsp) # tab[5]=a1^a4 + xor $a4,$a12 + mov $a2,48(%rsp) # tab[6]=a2^a4 + xor $a48,$a1 # a1^a4^a4^a8=a1^a8 + mov $a12,56(%rsp) # tab[7]=a1^a2^a4 + xor $a48,$a2 # a2^a4^a4^a8=a1^a8 + + mov $a8,64(%rsp) # tab[8]=a8 + xor $a48,$a12 # a1^a2^a4^a4^a8=a1^a2^a8 + mov $a1,72(%rsp) # tab[9]=a1^a8 + xor $a4,$a1 # a1^a8^a4 + mov $a2,80(%rsp) # tab[10]=a2^a8 + xor $a4,$a2 # a2^a8^a4 + mov $a12,88(%rsp) # tab[11]=a1^a2^a8 + + xor $a4,$a12 # a1^a2^a8^a4 + mov $a48,96(%rsp) # tab[12]=a4^a8 + mov $mask,$i0 + mov $a1,104(%rsp) # tab[13]=a1^a4^a8 + and $b,$i0 + mov $a2,112(%rsp) # tab[14]=a2^a4^a8 + shr \$4,$b + mov $a12,120(%rsp) # tab[15]=a1^a2^a4^a8 + mov $mask,$i1 + and $b,$i1 + shr \$4,$b + + movq (%rsp,$i0,8),$R # half of calculations is done in SSE2 + mov $mask,$i0 + and $b,$i0 + shr \$4,$b +___ + for ($n=1;$n<8;$n++) { + $code.=<<___; + mov (%rsp,$i1,8),$t1 + mov $mask,$i1 + mov $t1,$t0 + shl \$`8*$n-4`,$t1 + and $b,$i1 + movq (%rsp,$i0,8),$Tx + shr \$`64-(8*$n-4)`,$t0 + xor $t1,$lo + pslldq \$$n,$Tx + mov $mask,$i0 + shr \$4,$b + xor $t0,$hi + and $b,$i0 + shr \$4,$b + pxor $Tx,$R +___ + } +$code.=<<___; + mov (%rsp,$i1,8),$t1 + mov $t1,$t0 + shl \$`8*$n-4`,$t1 + movq $R,$i0 + shr \$`64-(8*$n-4)`,$t0 + xor $t1,$lo + psrldq \$8,$R + xor $t0,$hi + movq $R,$i1 + xor $i0,$lo + xor $i1,$hi + + add \$128+8,%rsp + ret +.Lend_mul_1x1: +.size _mul_1x1,.-_mul_1x1 +___ + +($rp,$a1,$a0,$b1,$b0) = $win64? ("%rcx","%rdx","%r8", "%r9","%r10") : # Win64 order + ("%rdi","%rsi","%rdx","%rcx","%r8"); # Unix order + +$code.=<<___; +.extern OPENSSL_ia32cap_P +.globl bn_GF2m_mul_2x2 +.type bn_GF2m_mul_2x2,\@abi-omnipotent +.align 16 +bn_GF2m_mul_2x2: + mov OPENSSL_ia32cap_P(%rip),%rax + bt \$33,%rax + jnc .Lvanilla_mul_2x2 + + movq $a1,%xmm0 + movq $b1,%xmm1 + movq $a0,%xmm2 +___ +$code.=<<___ if ($win64); + movq 40(%rsp),%xmm3 +___ +$code.=<<___ if (!$win64); + movq $b0,%xmm3 +___ +$code.=<<___; + movdqa %xmm0,%xmm4 + movdqa %xmm1,%xmm5 + pclmulqdq \$0,%xmm1,%xmm0 # a1·b1 + pxor %xmm2,%xmm4 + pxor %xmm3,%xmm5 + pclmulqdq \$0,%xmm3,%xmm2 # a0·b0 + pclmulqdq \$0,%xmm5,%xmm4 # (a0+a1)·(b0+b1) + xorps %xmm0,%xmm4 + xorps %xmm2,%xmm4 # (a0+a1)·(b0+b1)-a0·b0-a1·b1 + movdqa %xmm4,%xmm5 + pslldq \$8,%xmm4 + psrldq \$8,%xmm5 + pxor %xmm4,%xmm2 + pxor %xmm5,%xmm0 + movdqu %xmm2,0($rp) + movdqu %xmm0,16($rp) + ret + +.align 16 +.Lvanilla_mul_2x2: + lea -8*17(%rsp),%rsp +___ +$code.=<<___ if ($win64); + mov `8*17+40`(%rsp),$b0 + mov %rdi,8*15(%rsp) + mov %rsi,8*16(%rsp) +___ +$code.=<<___; + mov %r14,8*10(%rsp) + mov %r13,8*11(%rsp) + mov %r12,8*12(%rsp) + mov %rbp,8*13(%rsp) + mov %rbx,8*14(%rsp) +.Lbody_mul_2x2: + mov $rp,32(%rsp) # save the arguments + mov $a1,40(%rsp) + mov $a0,48(%rsp) + mov $b1,56(%rsp) + mov $b0,64(%rsp) + + mov \$0xf,$mask + mov $a1,$a + mov $b1,$b + call _mul_1x1 # a1·b1 + mov $lo,16(%rsp) + mov $hi,24(%rsp) + + mov 48(%rsp),$a + mov 64(%rsp),$b + call _mul_1x1 # a0·b0 + mov $lo,0(%rsp) + mov $hi,8(%rsp) + + mov 40(%rsp),$a + mov 56(%rsp),$b + xor 48(%rsp),$a + xor 64(%rsp),$b + call _mul_1x1 # (a0+a1)·(b0+b1) +___ + @r=("%rbx","%rcx","%rdi","%rsi"); +$code.=<<___; + mov 0(%rsp),@r[0] + mov 8(%rsp),@r[1] + mov 16(%rsp),@r[2] + mov 24(%rsp),@r[3] + mov 32(%rsp),%rbp + + xor $hi,$lo + xor @r[1],$hi + xor @r[0],$lo + mov @r[0],0(%rbp) + xor @r[2],$hi + mov @r[3],24(%rbp) + xor @r[3],$lo + xor @r[3],$hi + xor $hi,$lo + mov $hi,16(%rbp) + mov $lo,8(%rbp) + + mov 8*10(%rsp),%r14 + mov 8*11(%rsp),%r13 + mov 8*12(%rsp),%r12 + mov 8*13(%rsp),%rbp + mov 8*14(%rsp),%rbx +___ +$code.=<<___ if ($win64); + mov 8*15(%rsp),%rdi + mov 8*16(%rsp),%rsi +___ +$code.=<<___; + lea 8*17(%rsp),%rsp + ret +.Lend_mul_2x2: +.size bn_GF2m_mul_2x2,.-bn_GF2m_mul_2x2 +.asciz "GF(2^m) Multiplication for x86_64, CRYPTOGAMS by " +.align 16 +___ + +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind + +.type se_handler,\@abi-omnipotent +.align 16 +se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 152($context),%rax # pull context->Rsp + mov 248($context),%rbx # pull context->Rip + + lea .Lbody_mul_2x2(%rip),%r10 + cmp %r10,%rbx # context->Rip<"prologue" label + jb .Lin_prologue + + mov 8*10(%rax),%r14 # mimic epilogue + mov 8*11(%rax),%r13 + mov 8*12(%rax),%r12 + mov 8*13(%rax),%rbp + mov 8*14(%rax),%rbx + mov 8*15(%rax),%rdi + mov 8*16(%rax),%rsi + + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + mov %r14,232($context) # restore context->R14 + +.Lin_prologue: + lea 8*17(%rax),%rax + mov %rax,152($context) # restore context->Rsp + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$154,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size se_handler,.-se_handler + +.section .pdata +.align 4 + .rva _mul_1x1 + .rva .Lend_mul_1x1 + .rva .LSEH_info_1x1 + + .rva .Lvanilla_mul_2x2 + .rva .Lend_mul_2x2 + .rva .LSEH_info_2x2 +.section .xdata +.align 8 +.LSEH_info_1x1: + .byte 0x01,0x07,0x02,0x00 + .byte 0x07,0x01,0x11,0x00 # sub rsp,128+8 +.LSEH_info_2x2: + .byte 9,0,0,0 + .rva se_handler +___ +} + +$code =~ s/\`([^\`]*)\`/eval($1)/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/x86_64-mont.pl b/libs/openssl/crypto/bn/asm/x86_64-mont.pl new file mode 100755 index 00000000..c8ae019d --- /dev/null +++ b/libs/openssl/crypto/bn/asm/x86_64-mont.pl @@ -0,0 +1,1715 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# October 2005. +# +# Montgomery multiplication routine for x86_64. While it gives modest +# 9% improvement of rsa4096 sign on Opteron, rsa512 sign runs more +# than twice, >2x, as fast. Most common rsa1024 sign is improved by +# respectful 50%. It remains to be seen if loop unrolling and +# dedicated squaring routine can provide further improvement... + +# July 2011. +# +# Add dedicated squaring procedure. Performance improvement varies +# from platform to platform, but in average it's ~5%/15%/25%/33% +# for 512-/1024-/2048-/4096-bit RSA *sign* benchmarks respectively. + +# August 2011. +# +# Unroll and modulo-schedule inner loops in such manner that they +# are "fallen through" for input lengths of 8, which is critical for +# 1024-bit RSA *sign*. Average performance improvement in comparison +# to *initial* version of this module from 2005 is ~0%/30%/40%/45% +# for 512-/1024-/2048-/4096-bit RSA *sign* benchmarks respectively. + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +# int bn_mul_mont( +$rp="%rdi"; # BN_ULONG *rp, +$ap="%rsi"; # const BN_ULONG *ap, +$bp="%rdx"; # const BN_ULONG *bp, +$np="%rcx"; # const BN_ULONG *np, +$n0="%r8"; # const BN_ULONG *n0, +$num="%r9"; # int num); +$lo0="%r10"; +$hi0="%r11"; +$hi1="%r13"; +$i="%r14"; +$j="%r15"; +$m0="%rbx"; +$m1="%rbp"; + +$code=<<___; +.text + +.globl bn_mul_mont +.type bn_mul_mont,\@function,6 +.align 16 +bn_mul_mont: + test \$3,${num}d + jnz .Lmul_enter + cmp \$8,${num}d + jb .Lmul_enter + cmp $ap,$bp + jne .Lmul4x_enter + jmp .Lsqr4x_enter + +.align 16 +.Lmul_enter: + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + + mov ${num}d,${num}d + lea 2($num),%r10 + mov %rsp,%r11 + neg %r10 + lea (%rsp,%r10,8),%rsp # tp=alloca(8*(num+2)) + and \$-1024,%rsp # minimize TLB usage + + mov %r11,8(%rsp,$num,8) # tp[num+1]=%rsp +.Lmul_body: + # Some OSes, *cough*-dows, insist on stack being "wired" to + # physical memory in strictly sequential manner, i.e. if stack + # allocation spans two pages, then reference to farmost one can + # be punishable by SEGV. But page walking can do good even on + # other OSes, because it guarantees that villain thread hits + # the guard page before it can make damage to innocent one... + sub %rsp,%r11 + and \$-4096,%r11 +.Lmul_page_walk: + mov (%rsp,%r11),%r10 + sub \$4096,%r11 + .byte 0x66,0x2e # predict non-taken + jnc .Lmul_page_walk + + mov $bp,%r12 # reassign $bp +___ + $bp="%r12"; +$code.=<<___; + mov ($n0),$n0 # pull n0[0] value + mov ($bp),$m0 # m0=bp[0] + mov ($ap),%rax + + xor $i,$i # i=0 + xor $j,$j # j=0 + + mov $n0,$m1 + mulq $m0 # ap[0]*bp[0] + mov %rax,$lo0 + mov ($np),%rax + + imulq $lo0,$m1 # "tp[0]"*n0 + mov %rdx,$hi0 + + mulq $m1 # np[0]*m1 + add %rax,$lo0 # discarded + mov 8($ap),%rax + adc \$0,%rdx + mov %rdx,$hi1 + + lea 1($j),$j # j++ + jmp .L1st_enter + +.align 16 +.L1st: + add %rax,$hi1 + mov ($ap,$j,8),%rax + adc \$0,%rdx + add $hi0,$hi1 # np[j]*m1+ap[j]*bp[0] + mov $lo0,$hi0 + adc \$0,%rdx + mov $hi1,-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$hi1 + +.L1st_enter: + mulq $m0 # ap[j]*bp[0] + add %rax,$hi0 + mov ($np,$j,8),%rax + adc \$0,%rdx + lea 1($j),$j # j++ + mov %rdx,$lo0 + + mulq $m1 # np[j]*m1 + cmp $num,$j + jne .L1st + + add %rax,$hi1 + mov ($ap),%rax # ap[0] + adc \$0,%rdx + add $hi0,$hi1 # np[j]*m1+ap[j]*bp[0] + adc \$0,%rdx + mov $hi1,-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$hi1 + mov $lo0,$hi0 + + xor %rdx,%rdx + add $hi0,$hi1 + adc \$0,%rdx + mov $hi1,-8(%rsp,$num,8) + mov %rdx,(%rsp,$num,8) # store upmost overflow bit + + lea 1($i),$i # i++ + jmp .Louter +.align 16 +.Louter: + mov ($bp,$i,8),$m0 # m0=bp[i] + xor $j,$j # j=0 + mov $n0,$m1 + mov (%rsp),$lo0 + mulq $m0 # ap[0]*bp[i] + add %rax,$lo0 # ap[0]*bp[i]+tp[0] + mov ($np),%rax + adc \$0,%rdx + + imulq $lo0,$m1 # tp[0]*n0 + mov %rdx,$hi0 + + mulq $m1 # np[0]*m1 + add %rax,$lo0 # discarded + mov 8($ap),%rax + adc \$0,%rdx + mov 8(%rsp),$lo0 # tp[1] + mov %rdx,$hi1 + + lea 1($j),$j # j++ + jmp .Linner_enter + +.align 16 +.Linner: + add %rax,$hi1 + mov ($ap,$j,8),%rax + adc \$0,%rdx + add $lo0,$hi1 # np[j]*m1+ap[j]*bp[i]+tp[j] + mov (%rsp,$j,8),$lo0 + adc \$0,%rdx + mov $hi1,-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$hi1 + +.Linner_enter: + mulq $m0 # ap[j]*bp[i] + add %rax,$hi0 + mov ($np,$j,8),%rax + adc \$0,%rdx + add $hi0,$lo0 # ap[j]*bp[i]+tp[j] + mov %rdx,$hi0 + adc \$0,$hi0 + lea 1($j),$j # j++ + + mulq $m1 # np[j]*m1 + cmp $num,$j + jne .Linner + + add %rax,$hi1 + mov ($ap),%rax # ap[0] + adc \$0,%rdx + add $lo0,$hi1 # np[j]*m1+ap[j]*bp[i]+tp[j] + mov (%rsp,$j,8),$lo0 + adc \$0,%rdx + mov $hi1,-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$hi1 + + xor %rdx,%rdx + add $hi0,$hi1 + adc \$0,%rdx + add $lo0,$hi1 # pull upmost overflow bit + adc \$0,%rdx + mov $hi1,-8(%rsp,$num,8) + mov %rdx,(%rsp,$num,8) # store upmost overflow bit + + lea 1($i),$i # i++ + cmp $num,$i + jl .Louter + + xor $i,$i # i=0 and clear CF! + mov (%rsp),%rax # tp[0] + lea (%rsp),$ap # borrow ap for tp + mov $num,$j # j=num + jmp .Lsub +.align 16 +.Lsub: sbb ($np,$i,8),%rax + mov %rax,($rp,$i,8) # rp[i]=tp[i]-np[i] + mov 8($ap,$i,8),%rax # tp[i+1] + lea 1($i),$i # i++ + dec $j # doesnn't affect CF! + jnz .Lsub + + sbb \$0,%rax # handle upmost overflow bit + xor $i,$i + and %rax,$ap + not %rax + mov $rp,$np + and %rax,$np + mov $num,$j # j=num + or $np,$ap # ap=borrow?tp:rp +.align 16 +.Lcopy: # copy or in-place refresh + mov ($ap,$i,8),%rax + mov $i,(%rsp,$i,8) # zap temporary vector + mov %rax,($rp,$i,8) # rp[i]=tp[i] + lea 1($i),$i + sub \$1,$j + jnz .Lcopy + + mov 8(%rsp,$num,8),%rsi # restore %rsp + mov \$1,%rax + mov (%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 + mov 24(%rsi),%r12 + mov 32(%rsi),%rbp + mov 40(%rsi),%rbx + lea 48(%rsi),%rsp +.Lmul_epilogue: + ret +.size bn_mul_mont,.-bn_mul_mont +___ +{{{ +my @A=("%r10","%r11"); +my @N=("%r13","%rdi"); +$code.=<<___; +.type bn_mul4x_mont,\@function,6 +.align 16 +bn_mul4x_mont: +.Lmul4x_enter: + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + + mov ${num}d,${num}d + lea 4($num),%r10 + mov %rsp,%r11 + neg %r10 + lea (%rsp,%r10,8),%rsp # tp=alloca(8*(num+4)) + and \$-1024,%rsp # minimize TLB usage + + mov %r11,8(%rsp,$num,8) # tp[num+1]=%rsp +.Lmul4x_body: + sub %rsp,%r11 + and \$-4096,%r11 +.Lmul4x_page_walk: + mov (%rsp,%r11),%r10 + sub \$4096,%r11 + .byte 0x2e # predict non-taken + jnc .Lmul4x_page_walk + + mov $rp,16(%rsp,$num,8) # tp[num+2]=$rp + mov %rdx,%r12 # reassign $bp +___ + $bp="%r12"; +$code.=<<___; + mov ($n0),$n0 # pull n0[0] value + mov ($bp),$m0 # m0=bp[0] + mov ($ap),%rax + + xor $i,$i # i=0 + xor $j,$j # j=0 + + mov $n0,$m1 + mulq $m0 # ap[0]*bp[0] + mov %rax,$A[0] + mov ($np),%rax + + imulq $A[0],$m1 # "tp[0]"*n0 + mov %rdx,$A[1] + + mulq $m1 # np[0]*m1 + add %rax,$A[0] # discarded + mov 8($ap),%rax + adc \$0,%rdx + mov %rdx,$N[1] + + mulq $m0 + add %rax,$A[1] + mov 8($np),%rax + adc \$0,%rdx + mov %rdx,$A[0] + + mulq $m1 + add %rax,$N[1] + mov 16($ap),%rax + adc \$0,%rdx + add $A[1],$N[1] + lea 4($j),$j # j++ + adc \$0,%rdx + mov $N[1],(%rsp) + mov %rdx,$N[0] + jmp .L1st4x +.align 16 +.L1st4x: + mulq $m0 # ap[j]*bp[0] + add %rax,$A[0] + mov -16($np,$j,8),%rax + adc \$0,%rdx + mov %rdx,$A[1] + + mulq $m1 # np[j]*m1 + add %rax,$N[0] + mov -8($ap,$j,8),%rax + adc \$0,%rdx + add $A[0],$N[0] # np[j]*m1+ap[j]*bp[0] + adc \$0,%rdx + mov $N[0],-24(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[1] + + mulq $m0 # ap[j]*bp[0] + add %rax,$A[1] + mov -8($np,$j,8),%rax + adc \$0,%rdx + mov %rdx,$A[0] + + mulq $m1 # np[j]*m1 + add %rax,$N[1] + mov ($ap,$j,8),%rax + adc \$0,%rdx + add $A[1],$N[1] # np[j]*m1+ap[j]*bp[0] + adc \$0,%rdx + mov $N[1],-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[0] + + mulq $m0 # ap[j]*bp[0] + add %rax,$A[0] + mov ($np,$j,8),%rax + adc \$0,%rdx + mov %rdx,$A[1] + + mulq $m1 # np[j]*m1 + add %rax,$N[0] + mov 8($ap,$j,8),%rax + adc \$0,%rdx + add $A[0],$N[0] # np[j]*m1+ap[j]*bp[0] + adc \$0,%rdx + mov $N[0],-8(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[1] + + mulq $m0 # ap[j]*bp[0] + add %rax,$A[1] + mov 8($np,$j,8),%rax + adc \$0,%rdx + lea 4($j),$j # j++ + mov %rdx,$A[0] + + mulq $m1 # np[j]*m1 + add %rax,$N[1] + mov -16($ap,$j,8),%rax + adc \$0,%rdx + add $A[1],$N[1] # np[j]*m1+ap[j]*bp[0] + adc \$0,%rdx + mov $N[1],-32(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[0] + cmp $num,$j + jl .L1st4x + + mulq $m0 # ap[j]*bp[0] + add %rax,$A[0] + mov -16($np,$j,8),%rax + adc \$0,%rdx + mov %rdx,$A[1] + + mulq $m1 # np[j]*m1 + add %rax,$N[0] + mov -8($ap,$j,8),%rax + adc \$0,%rdx + add $A[0],$N[0] # np[j]*m1+ap[j]*bp[0] + adc \$0,%rdx + mov $N[0],-24(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[1] + + mulq $m0 # ap[j]*bp[0] + add %rax,$A[1] + mov -8($np,$j,8),%rax + adc \$0,%rdx + mov %rdx,$A[0] + + mulq $m1 # np[j]*m1 + add %rax,$N[1] + mov ($ap),%rax # ap[0] + adc \$0,%rdx + add $A[1],$N[1] # np[j]*m1+ap[j]*bp[0] + adc \$0,%rdx + mov $N[1],-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[0] + + xor $N[1],$N[1] + add $A[0],$N[0] + adc \$0,$N[1] + mov $N[0],-8(%rsp,$j,8) + mov $N[1],(%rsp,$j,8) # store upmost overflow bit + + lea 1($i),$i # i++ +.align 4 +.Louter4x: + mov ($bp,$i,8),$m0 # m0=bp[i] + xor $j,$j # j=0 + mov (%rsp),$A[0] + mov $n0,$m1 + mulq $m0 # ap[0]*bp[i] + add %rax,$A[0] # ap[0]*bp[i]+tp[0] + mov ($np),%rax + adc \$0,%rdx + + imulq $A[0],$m1 # tp[0]*n0 + mov %rdx,$A[1] + + mulq $m1 # np[0]*m1 + add %rax,$A[0] # "$N[0]", discarded + mov 8($ap),%rax + adc \$0,%rdx + mov %rdx,$N[1] + + mulq $m0 # ap[j]*bp[i] + add %rax,$A[1] + mov 8($np),%rax + adc \$0,%rdx + add 8(%rsp),$A[1] # +tp[1] + adc \$0,%rdx + mov %rdx,$A[0] + + mulq $m1 # np[j]*m1 + add %rax,$N[1] + mov 16($ap),%rax + adc \$0,%rdx + add $A[1],$N[1] # np[j]*m1+ap[j]*bp[i]+tp[j] + lea 4($j),$j # j+=2 + adc \$0,%rdx + mov $N[1],(%rsp) # tp[j-1] + mov %rdx,$N[0] + jmp .Linner4x +.align 16 +.Linner4x: + mulq $m0 # ap[j]*bp[i] + add %rax,$A[0] + mov -16($np,$j,8),%rax + adc \$0,%rdx + add -16(%rsp,$j,8),$A[0] # ap[j]*bp[i]+tp[j] + adc \$0,%rdx + mov %rdx,$A[1] + + mulq $m1 # np[j]*m1 + add %rax,$N[0] + mov -8($ap,$j,8),%rax + adc \$0,%rdx + add $A[0],$N[0] + adc \$0,%rdx + mov $N[0],-24(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[1] + + mulq $m0 # ap[j]*bp[i] + add %rax,$A[1] + mov -8($np,$j,8),%rax + adc \$0,%rdx + add -8(%rsp,$j,8),$A[1] + adc \$0,%rdx + mov %rdx,$A[0] + + mulq $m1 # np[j]*m1 + add %rax,$N[1] + mov ($ap,$j,8),%rax + adc \$0,%rdx + add $A[1],$N[1] + adc \$0,%rdx + mov $N[1],-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[0] + + mulq $m0 # ap[j]*bp[i] + add %rax,$A[0] + mov ($np,$j,8),%rax + adc \$0,%rdx + add (%rsp,$j,8),$A[0] # ap[j]*bp[i]+tp[j] + adc \$0,%rdx + mov %rdx,$A[1] + + mulq $m1 # np[j]*m1 + add %rax,$N[0] + mov 8($ap,$j,8),%rax + adc \$0,%rdx + add $A[0],$N[0] + adc \$0,%rdx + mov $N[0],-8(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[1] + + mulq $m0 # ap[j]*bp[i] + add %rax,$A[1] + mov 8($np,$j,8),%rax + adc \$0,%rdx + add 8(%rsp,$j,8),$A[1] + adc \$0,%rdx + lea 4($j),$j # j++ + mov %rdx,$A[0] + + mulq $m1 # np[j]*m1 + add %rax,$N[1] + mov -16($ap,$j,8),%rax + adc \$0,%rdx + add $A[1],$N[1] + adc \$0,%rdx + mov $N[1],-32(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[0] + cmp $num,$j + jl .Linner4x + + mulq $m0 # ap[j]*bp[i] + add %rax,$A[0] + mov -16($np,$j,8),%rax + adc \$0,%rdx + add -16(%rsp,$j,8),$A[0] # ap[j]*bp[i]+tp[j] + adc \$0,%rdx + mov %rdx,$A[1] + + mulq $m1 # np[j]*m1 + add %rax,$N[0] + mov -8($ap,$j,8),%rax + adc \$0,%rdx + add $A[0],$N[0] + adc \$0,%rdx + mov $N[0],-24(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[1] + + mulq $m0 # ap[j]*bp[i] + add %rax,$A[1] + mov -8($np,$j,8),%rax + adc \$0,%rdx + add -8(%rsp,$j,8),$A[1] + adc \$0,%rdx + lea 1($i),$i # i++ + mov %rdx,$A[0] + + mulq $m1 # np[j]*m1 + add %rax,$N[1] + mov ($ap),%rax # ap[0] + adc \$0,%rdx + add $A[1],$N[1] + adc \$0,%rdx + mov $N[1],-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[0] + + xor $N[1],$N[1] + add $A[0],$N[0] + adc \$0,$N[1] + add (%rsp,$num,8),$N[0] # pull upmost overflow bit + adc \$0,$N[1] + mov $N[0],-8(%rsp,$j,8) + mov $N[1],(%rsp,$j,8) # store upmost overflow bit + + cmp $num,$i + jl .Louter4x +___ +{ +my @ri=("%rax","%rdx",$m0,$m1); +$code.=<<___; + mov 16(%rsp,$num,8),$rp # restore $rp + mov 0(%rsp),@ri[0] # tp[0] + pxor %xmm0,%xmm0 + mov 8(%rsp),@ri[1] # tp[1] + shr \$2,$num # num/=4 + lea (%rsp),$ap # borrow ap for tp + xor $i,$i # i=0 and clear CF! + + sub 0($np),@ri[0] + mov 16($ap),@ri[2] # tp[2] + mov 24($ap),@ri[3] # tp[3] + sbb 8($np),@ri[1] + lea -1($num),$j # j=num/4-1 + jmp .Lsub4x +.align 16 +.Lsub4x: + mov @ri[0],0($rp,$i,8) # rp[i]=tp[i]-np[i] + mov @ri[1],8($rp,$i,8) # rp[i]=tp[i]-np[i] + sbb 16($np,$i,8),@ri[2] + mov 32($ap,$i,8),@ri[0] # tp[i+1] + mov 40($ap,$i,8),@ri[1] + sbb 24($np,$i,8),@ri[3] + mov @ri[2],16($rp,$i,8) # rp[i]=tp[i]-np[i] + mov @ri[3],24($rp,$i,8) # rp[i]=tp[i]-np[i] + sbb 32($np,$i,8),@ri[0] + mov 48($ap,$i,8),@ri[2] + mov 56($ap,$i,8),@ri[3] + sbb 40($np,$i,8),@ri[1] + lea 4($i),$i # i++ + dec $j # doesnn't affect CF! + jnz .Lsub4x + + mov @ri[0],0($rp,$i,8) # rp[i]=tp[i]-np[i] + mov 32($ap,$i,8),@ri[0] # load overflow bit + sbb 16($np,$i,8),@ri[2] + mov @ri[1],8($rp,$i,8) # rp[i]=tp[i]-np[i] + sbb 24($np,$i,8),@ri[3] + mov @ri[2],16($rp,$i,8) # rp[i]=tp[i]-np[i] + + sbb \$0,@ri[0] # handle upmost overflow bit + mov @ri[3],24($rp,$i,8) # rp[i]=tp[i]-np[i] + xor $i,$i # i=0 + and @ri[0],$ap + not @ri[0] + mov $rp,$np + and @ri[0],$np + lea -1($num),$j + or $np,$ap # ap=borrow?tp:rp + + movdqu ($ap),%xmm1 + movdqa %xmm0,(%rsp) + movdqu %xmm1,($rp) + jmp .Lcopy4x +.align 16 +.Lcopy4x: # copy or in-place refresh + movdqu 16($ap,$i),%xmm2 + movdqu 32($ap,$i),%xmm1 + movdqa %xmm0,16(%rsp,$i) + movdqu %xmm2,16($rp,$i) + movdqa %xmm0,32(%rsp,$i) + movdqu %xmm1,32($rp,$i) + lea 32($i),$i + dec $j + jnz .Lcopy4x + + shl \$2,$num + movdqu 16($ap,$i),%xmm2 + movdqa %xmm0,16(%rsp,$i) + movdqu %xmm2,16($rp,$i) +___ +} +$code.=<<___; + mov 8(%rsp,$num,8),%rsi # restore %rsp + mov \$1,%rax + mov (%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 + mov 24(%rsi),%r12 + mov 32(%rsi),%rbp + mov 40(%rsi),%rbx + lea 48(%rsi),%rsp +.Lmul4x_epilogue: + ret +.size bn_mul4x_mont,.-bn_mul4x_mont +___ +}}} + {{{ +###################################################################### +# void bn_sqr4x_mont( +my $rptr="%rdi"; # const BN_ULONG *rptr, +my $aptr="%rsi"; # const BN_ULONG *aptr, +my $bptr="%rdx"; # not used +my $nptr="%rcx"; # const BN_ULONG *nptr, +my $n0 ="%r8"; # const BN_ULONG *n0); +my $num ="%r9"; # int num, has to be divisible by 4 and + # not less than 8 + +my ($i,$j,$tptr)=("%rbp","%rcx",$rptr); +my @A0=("%r10","%r11"); +my @A1=("%r12","%r13"); +my ($a0,$a1,$ai)=("%r14","%r15","%rbx"); + +$code.=<<___; +.type bn_sqr4x_mont,\@function,6 +.align 16 +bn_sqr4x_mont: +.Lsqr4x_enter: + mov %rsp,%rax + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + + shl \$3,${num}d # convert $num to bytes + mov %rsp,%r11 # put aside %rsp + neg $num # -$num + mov ($n0),$n0 # *n0 + lea -72(%rsp,$num,2),%rsp # alloca(frame+2*$num) + and \$-1024,%rsp # minimize TLB usage + + sub %rsp,%r11 + and \$-4096,%r11 +.Lsqr4x_page_walk: + mov (%rsp,%r11),%r10 + sub \$4096,%r11 + .byte 0x2e # predict non-taken + jnc .Lsqr4x_page_walk + + mov $num,%r10 + neg $num # restore $num + lea -48(%rax),%r11 # restore saved %rsp + ############################################################## + # Stack layout + # + # +0 saved $num, used in reduction section + # +8 &t[2*$num], used in reduction section + # +32 saved $rptr + # +40 saved $nptr + # +48 saved *n0 + # +56 saved %rsp + # +64 t[2*$num] + # + mov $rptr,32(%rsp) # save $rptr + mov $nptr,40(%rsp) + mov $n0, 48(%rsp) + mov %r11, 56(%rsp) # save original %rsp +.Lsqr4x_body: + ############################################################## + # Squaring part: + # + # a) multiply-n-add everything but a[i]*a[i]; + # b) shift result of a) by 1 to the left and accumulate + # a[i]*a[i] products; + # + lea 32(%r10),$i # $i=-($num-32) + lea ($aptr,$num),$aptr # end of a[] buffer, ($aptr,$i)=&ap[2] + + mov $num,$j # $j=$num + + # comments apply to $num==8 case + mov -32($aptr,$i),$a0 # a[0] + lea 64(%rsp,$num,2),$tptr # end of tp[] buffer, &tp[2*$num] + mov -24($aptr,$i),%rax # a[1] + lea -32($tptr,$i),$tptr # end of tp[] window, &tp[2*$num-"$i"] + mov -16($aptr,$i),$ai # a[2] + mov %rax,$a1 + + mul $a0 # a[1]*a[0] + mov %rax,$A0[0] # a[1]*a[0] + mov $ai,%rax # a[2] + mov %rdx,$A0[1] + mov $A0[0],-24($tptr,$i) # t[1] + + xor $A0[0],$A0[0] + mul $a0 # a[2]*a[0] + add %rax,$A0[1] + mov $ai,%rax + adc %rdx,$A0[0] + mov $A0[1],-16($tptr,$i) # t[2] + + lea -16($i),$j # j=-16 + + + mov 8($aptr,$j),$ai # a[3] + mul $a1 # a[2]*a[1] + mov %rax,$A1[0] # a[2]*a[1]+t[3] + mov $ai,%rax + mov %rdx,$A1[1] + + xor $A0[1],$A0[1] + add $A1[0],$A0[0] + lea 16($j),$j + adc \$0,$A0[1] + mul $a0 # a[3]*a[0] + add %rax,$A0[0] # a[3]*a[0]+a[2]*a[1]+t[3] + mov $ai,%rax + adc %rdx,$A0[1] + mov $A0[0],-8($tptr,$j) # t[3] + jmp .Lsqr4x_1st + +.align 16 +.Lsqr4x_1st: + mov ($aptr,$j),$ai # a[4] + xor $A1[0],$A1[0] + mul $a1 # a[3]*a[1] + add %rax,$A1[1] # a[3]*a[1]+t[4] + mov $ai,%rax + adc %rdx,$A1[0] + + xor $A0[0],$A0[0] + add $A1[1],$A0[1] + adc \$0,$A0[0] + mul $a0 # a[4]*a[0] + add %rax,$A0[1] # a[4]*a[0]+a[3]*a[1]+t[4] + mov $ai,%rax # a[3] + adc %rdx,$A0[0] + mov $A0[1],($tptr,$j) # t[4] + + + mov 8($aptr,$j),$ai # a[5] + xor $A1[1],$A1[1] + mul $a1 # a[4]*a[3] + add %rax,$A1[0] # a[4]*a[3]+t[5] + mov $ai,%rax + adc %rdx,$A1[1] + + xor $A0[1],$A0[1] + add $A1[0],$A0[0] + adc \$0,$A0[1] + mul $a0 # a[5]*a[2] + add %rax,$A0[0] # a[5]*a[2]+a[4]*a[3]+t[5] + mov $ai,%rax + adc %rdx,$A0[1] + mov $A0[0],8($tptr,$j) # t[5] + + mov 16($aptr,$j),$ai # a[6] + xor $A1[0],$A1[0] + mul $a1 # a[5]*a[3] + add %rax,$A1[1] # a[5]*a[3]+t[6] + mov $ai,%rax + adc %rdx,$A1[0] + + xor $A0[0],$A0[0] + add $A1[1],$A0[1] + adc \$0,$A0[0] + mul $a0 # a[6]*a[2] + add %rax,$A0[1] # a[6]*a[2]+a[5]*a[3]+t[6] + mov $ai,%rax # a[3] + adc %rdx,$A0[0] + mov $A0[1],16($tptr,$j) # t[6] + + + mov 24($aptr,$j),$ai # a[7] + xor $A1[1],$A1[1] + mul $a1 # a[6]*a[5] + add %rax,$A1[0] # a[6]*a[5]+t[7] + mov $ai,%rax + adc %rdx,$A1[1] + + xor $A0[1],$A0[1] + add $A1[0],$A0[0] + lea 32($j),$j + adc \$0,$A0[1] + mul $a0 # a[7]*a[4] + add %rax,$A0[0] # a[7]*a[4]+a[6]*a[5]+t[6] + mov $ai,%rax + adc %rdx,$A0[1] + mov $A0[0],-8($tptr,$j) # t[7] + + cmp \$0,$j + jne .Lsqr4x_1st + + xor $A1[0],$A1[0] + add $A0[1],$A1[1] + adc \$0,$A1[0] + mul $a1 # a[7]*a[5] + add %rax,$A1[1] + adc %rdx,$A1[0] + + mov $A1[1],($tptr) # t[8] + lea 16($i),$i + mov $A1[0],8($tptr) # t[9] + jmp .Lsqr4x_outer + +.align 16 +.Lsqr4x_outer: # comments apply to $num==6 case + mov -32($aptr,$i),$a0 # a[0] + lea 64(%rsp,$num,2),$tptr # end of tp[] buffer, &tp[2*$num] + mov -24($aptr,$i),%rax # a[1] + lea -32($tptr,$i),$tptr # end of tp[] window, &tp[2*$num-"$i"] + mov -16($aptr,$i),$ai # a[2] + mov %rax,$a1 + + mov -24($tptr,$i),$A0[0] # t[1] + xor $A0[1],$A0[1] + mul $a0 # a[1]*a[0] + add %rax,$A0[0] # a[1]*a[0]+t[1] + mov $ai,%rax # a[2] + adc %rdx,$A0[1] + mov $A0[0],-24($tptr,$i) # t[1] + + xor $A0[0],$A0[0] + add -16($tptr,$i),$A0[1] # a[2]*a[0]+t[2] + adc \$0,$A0[0] + mul $a0 # a[2]*a[0] + add %rax,$A0[1] + mov $ai,%rax + adc %rdx,$A0[0] + mov $A0[1],-16($tptr,$i) # t[2] + + lea -16($i),$j # j=-16 + xor $A1[0],$A1[0] + + + mov 8($aptr,$j),$ai # a[3] + xor $A1[1],$A1[1] + add 8($tptr,$j),$A1[0] + adc \$0,$A1[1] + mul $a1 # a[2]*a[1] + add %rax,$A1[0] # a[2]*a[1]+t[3] + mov $ai,%rax + adc %rdx,$A1[1] + + xor $A0[1],$A0[1] + add $A1[0],$A0[0] + adc \$0,$A0[1] + mul $a0 # a[3]*a[0] + add %rax,$A0[0] # a[3]*a[0]+a[2]*a[1]+t[3] + mov $ai,%rax + adc %rdx,$A0[1] + mov $A0[0],8($tptr,$j) # t[3] + + lea 16($j),$j + jmp .Lsqr4x_inner + +.align 16 +.Lsqr4x_inner: + mov ($aptr,$j),$ai # a[4] + xor $A1[0],$A1[0] + add ($tptr,$j),$A1[1] + adc \$0,$A1[0] + mul $a1 # a[3]*a[1] + add %rax,$A1[1] # a[3]*a[1]+t[4] + mov $ai,%rax + adc %rdx,$A1[0] + + xor $A0[0],$A0[0] + add $A1[1],$A0[1] + adc \$0,$A0[0] + mul $a0 # a[4]*a[0] + add %rax,$A0[1] # a[4]*a[0]+a[3]*a[1]+t[4] + mov $ai,%rax # a[3] + adc %rdx,$A0[0] + mov $A0[1],($tptr,$j) # t[4] + + mov 8($aptr,$j),$ai # a[5] + xor $A1[1],$A1[1] + add 8($tptr,$j),$A1[0] + adc \$0,$A1[1] + mul $a1 # a[4]*a[3] + add %rax,$A1[0] # a[4]*a[3]+t[5] + mov $ai,%rax + adc %rdx,$A1[1] + + xor $A0[1],$A0[1] + add $A1[0],$A0[0] + lea 16($j),$j # j++ + adc \$0,$A0[1] + mul $a0 # a[5]*a[2] + add %rax,$A0[0] # a[5]*a[2]+a[4]*a[3]+t[5] + mov $ai,%rax + adc %rdx,$A0[1] + mov $A0[0],-8($tptr,$j) # t[5], "preloaded t[1]" below + + cmp \$0,$j + jne .Lsqr4x_inner + + xor $A1[0],$A1[0] + add $A0[1],$A1[1] + adc \$0,$A1[0] + mul $a1 # a[5]*a[3] + add %rax,$A1[1] + adc %rdx,$A1[0] + + mov $A1[1],($tptr) # t[6], "preloaded t[2]" below + mov $A1[0],8($tptr) # t[7], "preloaded t[3]" below + + add \$16,$i + jnz .Lsqr4x_outer + + # comments apply to $num==4 case + mov -32($aptr),$a0 # a[0] + lea 64(%rsp,$num,2),$tptr # end of tp[] buffer, &tp[2*$num] + mov -24($aptr),%rax # a[1] + lea -32($tptr,$i),$tptr # end of tp[] window, &tp[2*$num-"$i"] + mov -16($aptr),$ai # a[2] + mov %rax,$a1 + + xor $A0[1],$A0[1] + mul $a0 # a[1]*a[0] + add %rax,$A0[0] # a[1]*a[0]+t[1], preloaded t[1] + mov $ai,%rax # a[2] + adc %rdx,$A0[1] + mov $A0[0],-24($tptr) # t[1] + + xor $A0[0],$A0[0] + add $A1[1],$A0[1] # a[2]*a[0]+t[2], preloaded t[2] + adc \$0,$A0[0] + mul $a0 # a[2]*a[0] + add %rax,$A0[1] + mov $ai,%rax + adc %rdx,$A0[0] + mov $A0[1],-16($tptr) # t[2] + + mov -8($aptr),$ai # a[3] + mul $a1 # a[2]*a[1] + add %rax,$A1[0] # a[2]*a[1]+t[3], preloaded t[3] + mov $ai,%rax + adc \$0,%rdx + + xor $A0[1],$A0[1] + add $A1[0],$A0[0] + mov %rdx,$A1[1] + adc \$0,$A0[1] + mul $a0 # a[3]*a[0] + add %rax,$A0[0] # a[3]*a[0]+a[2]*a[1]+t[3] + mov $ai,%rax + adc %rdx,$A0[1] + mov $A0[0],-8($tptr) # t[3] + + xor $A1[0],$A1[0] + add $A0[1],$A1[1] + adc \$0,$A1[0] + mul $a1 # a[3]*a[1] + add %rax,$A1[1] + mov -16($aptr),%rax # a[2] + adc %rdx,$A1[0] + + mov $A1[1],($tptr) # t[4] + mov $A1[0],8($tptr) # t[5] + + mul $ai # a[2]*a[3] +___ +{ +my ($shift,$carry)=($a0,$a1); +my @S=(@A1,$ai,$n0); +$code.=<<___; + add \$16,$i + xor $shift,$shift + sub $num,$i # $i=16-$num + xor $carry,$carry + + add $A1[0],%rax # t[5] + adc \$0,%rdx + mov %rax,8($tptr) # t[5] + mov %rdx,16($tptr) # t[6] + mov $carry,24($tptr) # t[7] + + mov -16($aptr,$i),%rax # a[0] + lea 64(%rsp,$num,2),$tptr + xor $A0[0],$A0[0] # t[0] + mov -24($tptr,$i,2),$A0[1] # t[1] + + lea ($shift,$A0[0],2),$S[0] # t[2*i]<<1 | shift + shr \$63,$A0[0] + lea ($j,$A0[1],2),$S[1] # t[2*i+1]<<1 | + shr \$63,$A0[1] + or $A0[0],$S[1] # | t[2*i]>>63 + mov -16($tptr,$i,2),$A0[0] # t[2*i+2] # prefetch + mov $A0[1],$shift # shift=t[2*i+1]>>63 + mul %rax # a[i]*a[i] + neg $carry # mov $carry,cf + mov -8($tptr,$i,2),$A0[1] # t[2*i+2+1] # prefetch + adc %rax,$S[0] + mov -8($aptr,$i),%rax # a[i+1] # prefetch + mov $S[0],-32($tptr,$i,2) + adc %rdx,$S[1] + + lea ($shift,$A0[0],2),$S[2] # t[2*i]<<1 | shift + mov $S[1],-24($tptr,$i,2) + sbb $carry,$carry # mov cf,$carry + shr \$63,$A0[0] + lea ($j,$A0[1],2),$S[3] # t[2*i+1]<<1 | + shr \$63,$A0[1] + or $A0[0],$S[3] # | t[2*i]>>63 + mov 0($tptr,$i,2),$A0[0] # t[2*i+2] # prefetch + mov $A0[1],$shift # shift=t[2*i+1]>>63 + mul %rax # a[i]*a[i] + neg $carry # mov $carry,cf + mov 8($tptr,$i,2),$A0[1] # t[2*i+2+1] # prefetch + adc %rax,$S[2] + mov 0($aptr,$i),%rax # a[i+1] # prefetch + mov $S[2],-16($tptr,$i,2) + adc %rdx,$S[3] + lea 16($i),$i + mov $S[3],-40($tptr,$i,2) + sbb $carry,$carry # mov cf,$carry + jmp .Lsqr4x_shift_n_add + +.align 16 +.Lsqr4x_shift_n_add: + lea ($shift,$A0[0],2),$S[0] # t[2*i]<<1 | shift + shr \$63,$A0[0] + lea ($j,$A0[1],2),$S[1] # t[2*i+1]<<1 | + shr \$63,$A0[1] + or $A0[0],$S[1] # | t[2*i]>>63 + mov -16($tptr,$i,2),$A0[0] # t[2*i+2] # prefetch + mov $A0[1],$shift # shift=t[2*i+1]>>63 + mul %rax # a[i]*a[i] + neg $carry # mov $carry,cf + mov -8($tptr,$i,2),$A0[1] # t[2*i+2+1] # prefetch + adc %rax,$S[0] + mov -8($aptr,$i),%rax # a[i+1] # prefetch + mov $S[0],-32($tptr,$i,2) + adc %rdx,$S[1] + + lea ($shift,$A0[0],2),$S[2] # t[2*i]<<1 | shift + mov $S[1],-24($tptr,$i,2) + sbb $carry,$carry # mov cf,$carry + shr \$63,$A0[0] + lea ($j,$A0[1],2),$S[3] # t[2*i+1]<<1 | + shr \$63,$A0[1] + or $A0[0],$S[3] # | t[2*i]>>63 + mov 0($tptr,$i,2),$A0[0] # t[2*i+2] # prefetch + mov $A0[1],$shift # shift=t[2*i+1]>>63 + mul %rax # a[i]*a[i] + neg $carry # mov $carry,cf + mov 8($tptr,$i,2),$A0[1] # t[2*i+2+1] # prefetch + adc %rax,$S[2] + mov 0($aptr,$i),%rax # a[i+1] # prefetch + mov $S[2],-16($tptr,$i,2) + adc %rdx,$S[3] + + lea ($shift,$A0[0],2),$S[0] # t[2*i]<<1 | shift + mov $S[3],-8($tptr,$i,2) + sbb $carry,$carry # mov cf,$carry + shr \$63,$A0[0] + lea ($j,$A0[1],2),$S[1] # t[2*i+1]<<1 | + shr \$63,$A0[1] + or $A0[0],$S[1] # | t[2*i]>>63 + mov 16($tptr,$i,2),$A0[0] # t[2*i+2] # prefetch + mov $A0[1],$shift # shift=t[2*i+1]>>63 + mul %rax # a[i]*a[i] + neg $carry # mov $carry,cf + mov 24($tptr,$i,2),$A0[1] # t[2*i+2+1] # prefetch + adc %rax,$S[0] + mov 8($aptr,$i),%rax # a[i+1] # prefetch + mov $S[0],0($tptr,$i,2) + adc %rdx,$S[1] + + lea ($shift,$A0[0],2),$S[2] # t[2*i]<<1 | shift + mov $S[1],8($tptr,$i,2) + sbb $carry,$carry # mov cf,$carry + shr \$63,$A0[0] + lea ($j,$A0[1],2),$S[3] # t[2*i+1]<<1 | + shr \$63,$A0[1] + or $A0[0],$S[3] # | t[2*i]>>63 + mov 32($tptr,$i,2),$A0[0] # t[2*i+2] # prefetch + mov $A0[1],$shift # shift=t[2*i+1]>>63 + mul %rax # a[i]*a[i] + neg $carry # mov $carry,cf + mov 40($tptr,$i,2),$A0[1] # t[2*i+2+1] # prefetch + adc %rax,$S[2] + mov 16($aptr,$i),%rax # a[i+1] # prefetch + mov $S[2],16($tptr,$i,2) + adc %rdx,$S[3] + mov $S[3],24($tptr,$i,2) + sbb $carry,$carry # mov cf,$carry + add \$32,$i + jnz .Lsqr4x_shift_n_add + + lea ($shift,$A0[0],2),$S[0] # t[2*i]<<1 | shift + shr \$63,$A0[0] + lea ($j,$A0[1],2),$S[1] # t[2*i+1]<<1 | + shr \$63,$A0[1] + or $A0[0],$S[1] # | t[2*i]>>63 + mov -16($tptr),$A0[0] # t[2*i+2] # prefetch + mov $A0[1],$shift # shift=t[2*i+1]>>63 + mul %rax # a[i]*a[i] + neg $carry # mov $carry,cf + mov -8($tptr),$A0[1] # t[2*i+2+1] # prefetch + adc %rax,$S[0] + mov -8($aptr),%rax # a[i+1] # prefetch + mov $S[0],-32($tptr) + adc %rdx,$S[1] + + lea ($shift,$A0[0],2),$S[2] # t[2*i]<<1|shift + mov $S[1],-24($tptr) + sbb $carry,$carry # mov cf,$carry + shr \$63,$A0[0] + lea ($j,$A0[1],2),$S[3] # t[2*i+1]<<1 | + shr \$63,$A0[1] + or $A0[0],$S[3] # | t[2*i]>>63 + mul %rax # a[i]*a[i] + neg $carry # mov $carry,cf + adc %rax,$S[2] + adc %rdx,$S[3] + mov $S[2],-16($tptr) + mov $S[3],-8($tptr) +___ +} +############################################################## +# Montgomery reduction part, "word-by-word" algorithm. +# +{ +my ($topbit,$nptr)=("%rbp",$aptr); +my ($m0,$m1)=($a0,$a1); +my @Ni=("%rbx","%r9"); +$code.=<<___; + mov 40(%rsp),$nptr # restore $nptr + mov 48(%rsp),$n0 # restore *n0 + xor $j,$j + mov $num,0(%rsp) # save $num + sub $num,$j # $j=-$num + mov 64(%rsp),$A0[0] # t[0] # modsched # + mov $n0,$m0 # # modsched # + lea 64(%rsp,$num,2),%rax # end of t[] buffer + lea 64(%rsp,$num),$tptr # end of t[] window + mov %rax,8(%rsp) # save end of t[] buffer + lea ($nptr,$num),$nptr # end of n[] buffer + xor $topbit,$topbit # $topbit=0 + + mov 0($nptr,$j),%rax # n[0] # modsched # + mov 8($nptr,$j),$Ni[1] # n[1] # modsched # + imulq $A0[0],$m0 # m0=t[0]*n0 # modsched # + mov %rax,$Ni[0] # # modsched # + jmp .Lsqr4x_mont_outer + +.align 16 +.Lsqr4x_mont_outer: + xor $A0[1],$A0[1] + mul $m0 # n[0]*m0 + add %rax,$A0[0] # n[0]*m0+t[0] + mov $Ni[1],%rax + adc %rdx,$A0[1] + mov $n0,$m1 + + xor $A0[0],$A0[0] + add 8($tptr,$j),$A0[1] + adc \$0,$A0[0] + mul $m0 # n[1]*m0 + add %rax,$A0[1] # n[1]*m0+t[1] + mov $Ni[0],%rax + adc %rdx,$A0[0] + + imulq $A0[1],$m1 + + mov 16($nptr,$j),$Ni[0] # n[2] + xor $A1[1],$A1[1] + add $A0[1],$A1[0] + adc \$0,$A1[1] + mul $m1 # n[0]*m1 + add %rax,$A1[0] # n[0]*m1+"t[1]" + mov $Ni[0],%rax + adc %rdx,$A1[1] + mov $A1[0],8($tptr,$j) # "t[1]" + + xor $A0[1],$A0[1] + add 16($tptr,$j),$A0[0] + adc \$0,$A0[1] + mul $m0 # n[2]*m0 + add %rax,$A0[0] # n[2]*m0+t[2] + mov $Ni[1],%rax + adc %rdx,$A0[1] + + mov 24($nptr,$j),$Ni[1] # n[3] + xor $A1[0],$A1[0] + add $A0[0],$A1[1] + adc \$0,$A1[0] + mul $m1 # n[1]*m1 + add %rax,$A1[1] # n[1]*m1+"t[2]" + mov $Ni[1],%rax + adc %rdx,$A1[0] + mov $A1[1],16($tptr,$j) # "t[2]" + + xor $A0[0],$A0[0] + add 24($tptr,$j),$A0[1] + lea 32($j),$j + adc \$0,$A0[0] + mul $m0 # n[3]*m0 + add %rax,$A0[1] # n[3]*m0+t[3] + mov $Ni[0],%rax + adc %rdx,$A0[0] + jmp .Lsqr4x_mont_inner + +.align 16 +.Lsqr4x_mont_inner: + mov ($nptr,$j),$Ni[0] # n[4] + xor $A1[1],$A1[1] + add $A0[1],$A1[0] + adc \$0,$A1[1] + mul $m1 # n[2]*m1 + add %rax,$A1[0] # n[2]*m1+"t[3]" + mov $Ni[0],%rax + adc %rdx,$A1[1] + mov $A1[0],-8($tptr,$j) # "t[3]" + + xor $A0[1],$A0[1] + add ($tptr,$j),$A0[0] + adc \$0,$A0[1] + mul $m0 # n[4]*m0 + add %rax,$A0[0] # n[4]*m0+t[4] + mov $Ni[1],%rax + adc %rdx,$A0[1] + + mov 8($nptr,$j),$Ni[1] # n[5] + xor $A1[0],$A1[0] + add $A0[0],$A1[1] + adc \$0,$A1[0] + mul $m1 # n[3]*m1 + add %rax,$A1[1] # n[3]*m1+"t[4]" + mov $Ni[1],%rax + adc %rdx,$A1[0] + mov $A1[1],($tptr,$j) # "t[4]" + + xor $A0[0],$A0[0] + add 8($tptr,$j),$A0[1] + adc \$0,$A0[0] + mul $m0 # n[5]*m0 + add %rax,$A0[1] # n[5]*m0+t[5] + mov $Ni[0],%rax + adc %rdx,$A0[0] + + + mov 16($nptr,$j),$Ni[0] # n[6] + xor $A1[1],$A1[1] + add $A0[1],$A1[0] + adc \$0,$A1[1] + mul $m1 # n[4]*m1 + add %rax,$A1[0] # n[4]*m1+"t[5]" + mov $Ni[0],%rax + adc %rdx,$A1[1] + mov $A1[0],8($tptr,$j) # "t[5]" + + xor $A0[1],$A0[1] + add 16($tptr,$j),$A0[0] + adc \$0,$A0[1] + mul $m0 # n[6]*m0 + add %rax,$A0[0] # n[6]*m0+t[6] + mov $Ni[1],%rax + adc %rdx,$A0[1] + + mov 24($nptr,$j),$Ni[1] # n[7] + xor $A1[0],$A1[0] + add $A0[0],$A1[1] + adc \$0,$A1[0] + mul $m1 # n[5]*m1 + add %rax,$A1[1] # n[5]*m1+"t[6]" + mov $Ni[1],%rax + adc %rdx,$A1[0] + mov $A1[1],16($tptr,$j) # "t[6]" + + xor $A0[0],$A0[0] + add 24($tptr,$j),$A0[1] + lea 32($j),$j + adc \$0,$A0[0] + mul $m0 # n[7]*m0 + add %rax,$A0[1] # n[7]*m0+t[7] + mov $Ni[0],%rax + adc %rdx,$A0[0] + cmp \$0,$j + jne .Lsqr4x_mont_inner + + sub 0(%rsp),$j # $j=-$num # modsched # + mov $n0,$m0 # # modsched # + + xor $A1[1],$A1[1] + add $A0[1],$A1[0] + adc \$0,$A1[1] + mul $m1 # n[6]*m1 + add %rax,$A1[0] # n[6]*m1+"t[7]" + mov $Ni[1],%rax + adc %rdx,$A1[1] + mov $A1[0],-8($tptr) # "t[7]" + + xor $A0[1],$A0[1] + add ($tptr),$A0[0] # +t[8] + adc \$0,$A0[1] + mov 0($nptr,$j),$Ni[0] # n[0] # modsched # + add $topbit,$A0[0] + adc \$0,$A0[1] + + imulq 16($tptr,$j),$m0 # m0=t[0]*n0 # modsched # + xor $A1[0],$A1[0] + mov 8($nptr,$j),$Ni[1] # n[1] # modsched # + add $A0[0],$A1[1] + mov 16($tptr,$j),$A0[0] # t[0] # modsched # + adc \$0,$A1[0] + mul $m1 # n[7]*m1 + add %rax,$A1[1] # n[7]*m1+"t[8]" + mov $Ni[0],%rax # # modsched # + adc %rdx,$A1[0] + mov $A1[1],($tptr) # "t[8]" + + xor $topbit,$topbit + add 8($tptr),$A1[0] # +t[9] + adc $topbit,$topbit + add $A0[1],$A1[0] + lea 16($tptr),$tptr # "t[$num]>>128" + adc \$0,$topbit + mov $A1[0],-8($tptr) # "t[9]" + cmp 8(%rsp),$tptr # are we done? + jb .Lsqr4x_mont_outer + + mov 0(%rsp),$num # restore $num + mov $topbit,($tptr) # save $topbit +___ +} +############################################################## +# Post-condition, 4x unrolled copy from bn_mul_mont +# +{ +my ($tptr,$nptr)=("%rbx",$aptr); +my @ri=("%rax","%rdx","%r10","%r11"); +$code.=<<___; + mov 64(%rsp,$num),@ri[0] # tp[0] + lea 64(%rsp,$num),$tptr # upper half of t[2*$num] holds result + mov 40(%rsp),$nptr # restore $nptr + shr \$5,$num # num/4 + mov 8($tptr),@ri[1] # t[1] + xor $i,$i # i=0 and clear CF! + + mov 32(%rsp),$rptr # restore $rptr + sub 0($nptr),@ri[0] + mov 16($tptr),@ri[2] # t[2] + mov 24($tptr),@ri[3] # t[3] + sbb 8($nptr),@ri[1] + lea -1($num),$j # j=num/4-1 + jmp .Lsqr4x_sub +.align 16 +.Lsqr4x_sub: + mov @ri[0],0($rptr,$i,8) # rp[i]=tp[i]-np[i] + mov @ri[1],8($rptr,$i,8) # rp[i]=tp[i]-np[i] + sbb 16($nptr,$i,8),@ri[2] + mov 32($tptr,$i,8),@ri[0] # tp[i+1] + mov 40($tptr,$i,8),@ri[1] + sbb 24($nptr,$i,8),@ri[3] + mov @ri[2],16($rptr,$i,8) # rp[i]=tp[i]-np[i] + mov @ri[3],24($rptr,$i,8) # rp[i]=tp[i]-np[i] + sbb 32($nptr,$i,8),@ri[0] + mov 48($tptr,$i,8),@ri[2] + mov 56($tptr,$i,8),@ri[3] + sbb 40($nptr,$i,8),@ri[1] + lea 4($i),$i # i++ + dec $j # doesn't affect CF! + jnz .Lsqr4x_sub + + mov @ri[0],0($rptr,$i,8) # rp[i]=tp[i]-np[i] + mov 32($tptr,$i,8),@ri[0] # load overflow bit + sbb 16($nptr,$i,8),@ri[2] + mov @ri[1],8($rptr,$i,8) # rp[i]=tp[i]-np[i] + sbb 24($nptr,$i,8),@ri[3] + mov @ri[2],16($rptr,$i,8) # rp[i]=tp[i]-np[i] + + sbb \$0,@ri[0] # handle upmost overflow bit + mov @ri[3],24($rptr,$i,8) # rp[i]=tp[i]-np[i] + xor $i,$i # i=0 + and @ri[0],$tptr + not @ri[0] + mov $rptr,$nptr + and @ri[0],$nptr + lea -1($num),$j + or $nptr,$tptr # tp=borrow?tp:rp + + pxor %xmm0,%xmm0 + lea 64(%rsp,$num,8),$nptr + movdqu ($tptr),%xmm1 + lea ($nptr,$num,8),$nptr + movdqa %xmm0,64(%rsp) # zap lower half of temporary vector + movdqa %xmm0,($nptr) # zap upper half of temporary vector + movdqu %xmm1,($rptr) + jmp .Lsqr4x_copy +.align 16 +.Lsqr4x_copy: # copy or in-place refresh + movdqu 16($tptr,$i),%xmm2 + movdqu 32($tptr,$i),%xmm1 + movdqa %xmm0,80(%rsp,$i) # zap lower half of temporary vector + movdqa %xmm0,96(%rsp,$i) # zap lower half of temporary vector + movdqa %xmm0,16($nptr,$i) # zap upper half of temporary vector + movdqa %xmm0,32($nptr,$i) # zap upper half of temporary vector + movdqu %xmm2,16($rptr,$i) + movdqu %xmm1,32($rptr,$i) + lea 32($i),$i + dec $j + jnz .Lsqr4x_copy + + movdqu 16($tptr,$i),%xmm2 + movdqa %xmm0,80(%rsp,$i) # zap lower half of temporary vector + movdqa %xmm0,16($nptr,$i) # zap upper half of temporary vector + movdqu %xmm2,16($rptr,$i) +___ +} +$code.=<<___; + mov 56(%rsp),%rsi # restore %rsp + mov \$1,%rax + mov 0(%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 + mov 24(%rsi),%r12 + mov 32(%rsi),%rbp + mov 40(%rsi),%rbx + lea 48(%rsi),%rsp +.Lsqr4x_epilogue: + ret +.size bn_sqr4x_mont,.-bn_sqr4x_mont +___ +}}} +$code.=<<___; +.asciz "Montgomery Multiplication for x86_64, CRYPTOGAMS by " +.align 16 +___ + +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type mul_handler,\@abi-omnipotent +.align 16 +mul_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + mov 8($disp),%rsi # disp->ImageBase + mov 56($disp),%r11 # disp->HandlerData + + mov 0(%r11),%r10d # HandlerData[0] + lea (%rsi,%r10),%r10 # end of prologue label + cmp %r10,%rbx # context->RipRsp + + mov 4(%r11),%r10d # HandlerData[1] + lea (%rsi,%r10),%r10 # epilogue label + cmp %r10,%rbx # context->Rip>=epilogue label + jae .Lcommon_seh_tail + + mov 192($context),%r10 # pull $num + mov 8(%rax,%r10,8),%rax # pull saved stack pointer + lea 48(%rax),%rax + + mov -8(%rax),%rbx + mov -16(%rax),%rbp + mov -24(%rax),%r12 + mov -32(%rax),%r13 + mov -40(%rax),%r14 + mov -48(%rax),%r15 + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + + jmp .Lcommon_seh_tail +.size mul_handler,.-mul_handler + +.type sqr_handler,\@abi-omnipotent +.align 16 +sqr_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + lea .Lsqr4x_body(%rip),%r10 + cmp %r10,%rbx # context->Rip<.Lsqr_body + jb .Lcommon_seh_tail + + mov 152($context),%rax # pull context->Rsp + + lea .Lsqr4x_epilogue(%rip),%r10 + cmp %r10,%rbx # context->Rip>=.Lsqr_epilogue + jae .Lcommon_seh_tail + + mov 56(%rax),%rax # pull saved stack pointer + lea 48(%rax),%rax + + mov -8(%rax),%rbx + mov -16(%rax),%rbp + mov -24(%rax),%r12 + mov -32(%rax),%r13 + mov -40(%rax),%r14 + mov -48(%rax),%r15 + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + +.Lcommon_seh_tail: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$154,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size sqr_handler,.-sqr_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_bn_mul_mont + .rva .LSEH_end_bn_mul_mont + .rva .LSEH_info_bn_mul_mont + + .rva .LSEH_begin_bn_mul4x_mont + .rva .LSEH_end_bn_mul4x_mont + .rva .LSEH_info_bn_mul4x_mont + + .rva .LSEH_begin_bn_sqr4x_mont + .rva .LSEH_end_bn_sqr4x_mont + .rva .LSEH_info_bn_sqr4x_mont + +.section .xdata +.align 8 +.LSEH_info_bn_mul_mont: + .byte 9,0,0,0 + .rva mul_handler + .rva .Lmul_body,.Lmul_epilogue # HandlerData[] +.LSEH_info_bn_mul4x_mont: + .byte 9,0,0,0 + .rva mul_handler + .rva .Lmul4x_body,.Lmul4x_epilogue # HandlerData[] +.LSEH_info_bn_sqr4x_mont: + .byte 9,0,0,0 + .rva sqr_handler +___ +} + +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/bn/asm/x86_64-mont5.pl b/libs/openssl/crypto/bn/asm/x86_64-mont5.pl new file mode 100755 index 00000000..99243ae3 --- /dev/null +++ b/libs/openssl/crypto/bn/asm/x86_64-mont5.pl @@ -0,0 +1,1208 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# August 2011. +# +# Companion to x86_64-mont.pl that optimizes cache-timing attack +# countermeasures. The subroutines are produced by replacing bp[i] +# references in their x86_64-mont.pl counterparts with cache-neutral +# references to powers table computed in BN_mod_exp_mont_consttime. +# In addition subroutine that scatters elements of the powers table +# is implemented, so that scatter-/gathering can be tuned without +# bn_exp.c modifications. + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +# int bn_mul_mont_gather5( +$rp="%rdi"; # BN_ULONG *rp, +$ap="%rsi"; # const BN_ULONG *ap, +$bp="%rdx"; # const BN_ULONG *bp, +$np="%rcx"; # const BN_ULONG *np, +$n0="%r8"; # const BN_ULONG *n0, +$num="%r9"; # int num, + # int idx); # 0 to 2^5-1, "index" in $bp holding + # pre-computed powers of a', interlaced + # in such manner that b[0] is $bp[idx], + # b[1] is [2^5+idx], etc. +$lo0="%r10"; +$hi0="%r11"; +$hi1="%r13"; +$i="%r14"; +$j="%r15"; +$m0="%rbx"; +$m1="%rbp"; + +$code=<<___; +.text + +.globl bn_mul_mont_gather5 +.type bn_mul_mont_gather5,\@function,6 +.align 64 +bn_mul_mont_gather5: + test \$3,${num}d + jnz .Lmul_enter + cmp \$8,${num}d + jb .Lmul_enter + jmp .Lmul4x_enter + +.align 16 +.Lmul_enter: + mov ${num}d,${num}d + movd `($win64?56:8)`(%rsp),%xmm5 # load 7th argument + lea .Linc(%rip),%r10 + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + +.Lmul_alloca: + mov %rsp,%rax + lea 2($num),%r11 + neg %r11 + lea -264(%rsp,%r11,8),%rsp # tp=alloca(8*(num+2)+256+8) + and \$-1024,%rsp # minimize TLB usage + + mov %rax,8(%rsp,$num,8) # tp[num+1]=%rsp +.Lmul_body: + # Some OSes, *cough*-dows, insist on stack being "wired" to + # physical memory in strictly sequential manner, i.e. if stack + # allocation spans two pages, then reference to farmost one can + # be punishable by SEGV. But page walking can do good even on + # other OSes, because it guarantees that villain thread hits + # the guard page before it can make damage to innocent one... + sub %rsp,%rax + and \$-4096,%rax +.Lmul_page_walk: + mov (%rsp,%rax),%r11 + sub \$4096,%rax + .byte 0x2e # predict non-taken + jnc .Lmul_page_walk + + lea 128($bp),%r12 # reassign $bp (+size optimization) +___ + $bp="%r12"; + $STRIDE=2**5*8; # 5 is "window size" + $N=$STRIDE/4; # should match cache line size +$code.=<<___; + movdqa 0(%r10),%xmm0 # 00000001000000010000000000000000 + movdqa 16(%r10),%xmm1 # 00000002000000020000000200000002 + lea 24-112(%rsp,$num,8),%r10# place the mask after tp[num+3] (+ICache optimization) + and \$-16,%r10 + + pshufd \$0,%xmm5,%xmm5 # broadcast index + movdqa %xmm1,%xmm4 + movdqa %xmm1,%xmm2 +___ +######################################################################## +# calculate mask by comparing 0..31 to index and save result to stack +# +$code.=<<___; + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 # compare to 1,0 + .byte 0x67 + movdqa %xmm4,%xmm3 +___ +for($k=0;$k<$STRIDE/16-4;$k+=4) { +$code.=<<___; + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 # compare to 3,2 + movdqa %xmm0,`16*($k+0)+112`(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 # compare to 5,4 + movdqa %xmm1,`16*($k+1)+112`(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 # compare to 7,6 + movdqa %xmm2,`16*($k+2)+112`(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,`16*($k+3)+112`(%r10) + movdqa %xmm4,%xmm3 +___ +} +$code.=<<___; # last iteration can be optimized + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,`16*($k+0)+112`(%r10) + + paddd %xmm2,%xmm3 + .byte 0x67 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,`16*($k+1)+112`(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,`16*($k+2)+112`(%r10) + pand `16*($k+0)-128`($bp),%xmm0 # while it's still in register + + pand `16*($k+1)-128`($bp),%xmm1 + pand `16*($k+2)-128`($bp),%xmm2 + movdqa %xmm3,`16*($k+3)+112`(%r10) + pand `16*($k+3)-128`($bp),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 +___ +for($k=0;$k<$STRIDE/16-4;$k+=4) { +$code.=<<___; + movdqa `16*($k+0)-128`($bp),%xmm4 + movdqa `16*($k+1)-128`($bp),%xmm5 + movdqa `16*($k+2)-128`($bp),%xmm2 + pand `16*($k+0)+112`(%r10),%xmm4 + movdqa `16*($k+3)-128`($bp),%xmm3 + pand `16*($k+1)+112`(%r10),%xmm5 + por %xmm4,%xmm0 + pand `16*($k+2)+112`(%r10),%xmm2 + por %xmm5,%xmm1 + pand `16*($k+3)+112`(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 +___ +} +$code.=<<___; + por %xmm1,%xmm0 + pshufd \$0x4e,%xmm0,%xmm1 + por %xmm1,%xmm0 + lea $STRIDE($bp),$bp + movq %xmm0,$m0 # m0=bp[0] + + mov ($n0),$n0 # pull n0[0] value + mov ($ap),%rax + + xor $i,$i # i=0 + xor $j,$j # j=0 + + mov $n0,$m1 + mulq $m0 # ap[0]*bp[0] + mov %rax,$lo0 + mov ($np),%rax + + imulq $lo0,$m1 # "tp[0]"*n0 + mov %rdx,$hi0 + + mulq $m1 # np[0]*m1 + add %rax,$lo0 # discarded + mov 8($ap),%rax + adc \$0,%rdx + mov %rdx,$hi1 + + lea 1($j),$j # j++ + jmp .L1st_enter + +.align 16 +.L1st: + add %rax,$hi1 + mov ($ap,$j,8),%rax + adc \$0,%rdx + add $hi0,$hi1 # np[j]*m1+ap[j]*bp[0] + mov $lo0,$hi0 + adc \$0,%rdx + mov $hi1,-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$hi1 + +.L1st_enter: + mulq $m0 # ap[j]*bp[0] + add %rax,$hi0 + mov ($np,$j,8),%rax + adc \$0,%rdx + lea 1($j),$j # j++ + mov %rdx,$lo0 + + mulq $m1 # np[j]*m1 + cmp $num,$j + jne .L1st + + add %rax,$hi1 + mov ($ap),%rax # ap[0] + adc \$0,%rdx + add $hi0,$hi1 # np[j]*m1+ap[j]*bp[0] + adc \$0,%rdx + mov $hi1,-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$hi1 + mov $lo0,$hi0 + + xor %rdx,%rdx + add $hi0,$hi1 + adc \$0,%rdx + mov $hi1,-8(%rsp,$num,8) + mov %rdx,(%rsp,$num,8) # store upmost overflow bit + + lea 1($i),$i # i++ + jmp .Louter +.align 16 +.Louter: + lea 24+128(%rsp,$num,8),%rdx # where 256-byte mask is (+size optimization) + and \$-16,%rdx + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 +___ +for($k=0;$k<$STRIDE/16;$k+=4) { +$code.=<<___; + movdqa `16*($k+0)-128`($bp),%xmm0 + movdqa `16*($k+1)-128`($bp),%xmm1 + movdqa `16*($k+2)-128`($bp),%xmm2 + movdqa `16*($k+3)-128`($bp),%xmm3 + pand `16*($k+0)-128`(%rdx),%xmm0 + pand `16*($k+1)-128`(%rdx),%xmm1 + por %xmm0,%xmm4 + pand `16*($k+2)-128`(%rdx),%xmm2 + por %xmm1,%xmm5 + pand `16*($k+3)-128`(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 +___ +} +$code.=<<___; + por %xmm5,%xmm4 + pshufd \$0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + lea $STRIDE($bp),$bp + movq %xmm0,$m0 # m0=bp[i] + + xor $j,$j # j=0 + mov $n0,$m1 + mov (%rsp),$lo0 + + mulq $m0 # ap[0]*bp[i] + add %rax,$lo0 # ap[0]*bp[i]+tp[0] + mov ($np),%rax + adc \$0,%rdx + + imulq $lo0,$m1 # tp[0]*n0 + mov %rdx,$hi0 + + mulq $m1 # np[0]*m1 + add %rax,$lo0 # discarded + mov 8($ap),%rax + adc \$0,%rdx + mov 8(%rsp),$lo0 # tp[1] + mov %rdx,$hi1 + + lea 1($j),$j # j++ + jmp .Linner_enter + +.align 16 +.Linner: + add %rax,$hi1 + mov ($ap,$j,8),%rax + adc \$0,%rdx + add $lo0,$hi1 # np[j]*m1+ap[j]*bp[i]+tp[j] + mov (%rsp,$j,8),$lo0 + adc \$0,%rdx + mov $hi1,-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$hi1 + +.Linner_enter: + mulq $m0 # ap[j]*bp[i] + add %rax,$hi0 + mov ($np,$j,8),%rax + adc \$0,%rdx + add $hi0,$lo0 # ap[j]*bp[i]+tp[j] + mov %rdx,$hi0 + adc \$0,$hi0 + lea 1($j),$j # j++ + + mulq $m1 # np[j]*m1 + cmp $num,$j + jne .Linner + + add %rax,$hi1 + mov ($ap),%rax # ap[0] + adc \$0,%rdx + add $lo0,$hi1 # np[j]*m1+ap[j]*bp[i]+tp[j] + mov (%rsp,$j,8),$lo0 + adc \$0,%rdx + mov $hi1,-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$hi1 + + xor %rdx,%rdx + add $hi0,$hi1 + adc \$0,%rdx + add $lo0,$hi1 # pull upmost overflow bit + adc \$0,%rdx + mov $hi1,-8(%rsp,$num,8) + mov %rdx,(%rsp,$num,8) # store upmost overflow bit + + lea 1($i),$i # i++ + cmp $num,$i + jl .Louter + + xor $i,$i # i=0 and clear CF! + mov (%rsp),%rax # tp[0] + lea (%rsp),$ap # borrow ap for tp + mov $num,$j # j=num + jmp .Lsub +.align 16 +.Lsub: sbb ($np,$i,8),%rax + mov %rax,($rp,$i,8) # rp[i]=tp[i]-np[i] + mov 8($ap,$i,8),%rax # tp[i+1] + lea 1($i),$i # i++ + dec $j # doesnn't affect CF! + jnz .Lsub + + sbb \$0,%rax # handle upmost overflow bit + xor $i,$i + and %rax,$ap + not %rax + mov $rp,$np + and %rax,$np + mov $num,$j # j=num + or $np,$ap # ap=borrow?tp:rp +.align 16 +.Lcopy: # copy or in-place refresh + mov ($ap,$i,8),%rax + mov $i,(%rsp,$i,8) # zap temporary vector + mov %rax,($rp,$i,8) # rp[i]=tp[i] + lea 1($i),$i + sub \$1,$j + jnz .Lcopy + + mov 8(%rsp,$num,8),%rsi # restore %rsp + mov \$1,%rax + + mov (%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 + mov 24(%rsi),%r12 + mov 32(%rsi),%rbp + mov 40(%rsi),%rbx + lea 48(%rsi),%rsp +.Lmul_epilogue: + ret +.size bn_mul_mont_gather5,.-bn_mul_mont_gather5 +___ +{{{ +my @A=("%r10","%r11"); +my @N=("%r13","%rdi"); +$code.=<<___; +.type bn_mul4x_mont_gather5,\@function,6 +.align 16 +bn_mul4x_mont_gather5: +.Lmul4x_enter: + mov ${num}d,${num}d + movd `($win64?56:8)`(%rsp),%xmm5 # load 7th argument + lea .Linc(%rip),%r10 + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + +.Lmul4x_alloca: + mov %rsp,%rax + lea 4($num),%r11 + neg %r11 + lea -256(%rsp,%r11,8),%rsp # tp=alloca(8*(num+4)+256) + and \$-1024,%rsp # minimize TLB usage + + mov %rax,8(%rsp,$num,8) # tp[num+1]=%rsp +.Lmul4x_body: + sub %rsp,%rax + and \$-4096,%rax +.Lmul4x_page_walk: + mov (%rsp,%rax),%r11 + sub \$4096,%rax + .byte 0x2e # predict non-taken + jnc .Lmul4x_page_walk + + mov $rp,16(%rsp,$num,8) # tp[num+2]=$rp + lea 128(%rdx),%r12 # reassign $bp (+size optimization) +___ + $bp="%r12"; + $STRIDE=2**5*8; # 5 is "window size" + $N=$STRIDE/4; # should match cache line size +$code.=<<___; + movdqa 0(%r10),%xmm0 # 00000001000000010000000000000000 + movdqa 16(%r10),%xmm1 # 00000002000000020000000200000002 + lea 32-112(%rsp,$num,8),%r10# place the mask after tp[num+4] (+ICache optimization) + + pshufd \$0,%xmm5,%xmm5 # broadcast index + movdqa %xmm1,%xmm4 + .byte 0x67,0x67 + movdqa %xmm1,%xmm2 +___ +######################################################################## +# calculate mask by comparing 0..31 to index and save result to stack +# +$code.=<<___; + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 # compare to 1,0 + .byte 0x67 + movdqa %xmm4,%xmm3 +___ +for($k=0;$k<$STRIDE/16-4;$k+=4) { +$code.=<<___; + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 # compare to 3,2 + movdqa %xmm0,`16*($k+0)+112`(%r10) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 # compare to 5,4 + movdqa %xmm1,`16*($k+1)+112`(%r10) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 # compare to 7,6 + movdqa %xmm2,`16*($k+2)+112`(%r10) + movdqa %xmm4,%xmm2 + + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 + movdqa %xmm3,`16*($k+3)+112`(%r10) + movdqa %xmm4,%xmm3 +___ +} +$code.=<<___; # last iteration can be optimized + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 + movdqa %xmm0,`16*($k+0)+112`(%r10) + + paddd %xmm2,%xmm3 + .byte 0x67 + pcmpeqd %xmm5,%xmm2 + movdqa %xmm1,`16*($k+1)+112`(%r10) + + pcmpeqd %xmm5,%xmm3 + movdqa %xmm2,`16*($k+2)+112`(%r10) + pand `16*($k+0)-128`($bp),%xmm0 # while it's still in register + + pand `16*($k+1)-128`($bp),%xmm1 + pand `16*($k+2)-128`($bp),%xmm2 + movdqa %xmm3,`16*($k+3)+112`(%r10) + pand `16*($k+3)-128`($bp),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 +___ +for($k=0;$k<$STRIDE/16-4;$k+=4) { +$code.=<<___; + movdqa `16*($k+0)-128`($bp),%xmm4 + movdqa `16*($k+1)-128`($bp),%xmm5 + movdqa `16*($k+2)-128`($bp),%xmm2 + pand `16*($k+0)+112`(%r10),%xmm4 + movdqa `16*($k+3)-128`($bp),%xmm3 + pand `16*($k+1)+112`(%r10),%xmm5 + por %xmm4,%xmm0 + pand `16*($k+2)+112`(%r10),%xmm2 + por %xmm5,%xmm1 + pand `16*($k+3)+112`(%r10),%xmm3 + por %xmm2,%xmm0 + por %xmm3,%xmm1 +___ +} +$code.=<<___; + por %xmm1,%xmm0 + pshufd \$0x4e,%xmm0,%xmm1 + por %xmm1,%xmm0 + lea $STRIDE($bp),$bp + movq %xmm0,$m0 # m0=bp[0] + + mov ($n0),$n0 # pull n0[0] value + mov ($ap),%rax + + xor $i,$i # i=0 + xor $j,$j # j=0 + + mov $n0,$m1 + mulq $m0 # ap[0]*bp[0] + mov %rax,$A[0] + mov ($np),%rax + + imulq $A[0],$m1 # "tp[0]"*n0 + mov %rdx,$A[1] + + mulq $m1 # np[0]*m1 + add %rax,$A[0] # discarded + mov 8($ap),%rax + adc \$0,%rdx + mov %rdx,$N[1] + + mulq $m0 + add %rax,$A[1] + mov 8($np),%rax + adc \$0,%rdx + mov %rdx,$A[0] + + mulq $m1 + add %rax,$N[1] + mov 16($ap),%rax + adc \$0,%rdx + add $A[1],$N[1] + lea 4($j),$j # j++ + adc \$0,%rdx + mov $N[1],(%rsp) + mov %rdx,$N[0] + jmp .L1st4x +.align 16 +.L1st4x: + mulq $m0 # ap[j]*bp[0] + add %rax,$A[0] + mov -16($np,$j,8),%rax + adc \$0,%rdx + mov %rdx,$A[1] + + mulq $m1 # np[j]*m1 + add %rax,$N[0] + mov -8($ap,$j,8),%rax + adc \$0,%rdx + add $A[0],$N[0] # np[j]*m1+ap[j]*bp[0] + adc \$0,%rdx + mov $N[0],-24(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[1] + + mulq $m0 # ap[j]*bp[0] + add %rax,$A[1] + mov -8($np,$j,8),%rax + adc \$0,%rdx + mov %rdx,$A[0] + + mulq $m1 # np[j]*m1 + add %rax,$N[1] + mov ($ap,$j,8),%rax + adc \$0,%rdx + add $A[1],$N[1] # np[j]*m1+ap[j]*bp[0] + adc \$0,%rdx + mov $N[1],-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[0] + + mulq $m0 # ap[j]*bp[0] + add %rax,$A[0] + mov ($np,$j,8),%rax + adc \$0,%rdx + mov %rdx,$A[1] + + mulq $m1 # np[j]*m1 + add %rax,$N[0] + mov 8($ap,$j,8),%rax + adc \$0,%rdx + add $A[0],$N[0] # np[j]*m1+ap[j]*bp[0] + adc \$0,%rdx + mov $N[0],-8(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[1] + + mulq $m0 # ap[j]*bp[0] + add %rax,$A[1] + mov 8($np,$j,8),%rax + adc \$0,%rdx + lea 4($j),$j # j++ + mov %rdx,$A[0] + + mulq $m1 # np[j]*m1 + add %rax,$N[1] + mov -16($ap,$j,8),%rax + adc \$0,%rdx + add $A[1],$N[1] # np[j]*m1+ap[j]*bp[0] + adc \$0,%rdx + mov $N[1],-32(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[0] + cmp $num,$j + jl .L1st4x + + mulq $m0 # ap[j]*bp[0] + add %rax,$A[0] + mov -16($np,$j,8),%rax + adc \$0,%rdx + mov %rdx,$A[1] + + mulq $m1 # np[j]*m1 + add %rax,$N[0] + mov -8($ap,$j,8),%rax + adc \$0,%rdx + add $A[0],$N[0] # np[j]*m1+ap[j]*bp[0] + adc \$0,%rdx + mov $N[0],-24(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[1] + + mulq $m0 # ap[j]*bp[0] + add %rax,$A[1] + mov -8($np,$j,8),%rax + adc \$0,%rdx + mov %rdx,$A[0] + + mulq $m1 # np[j]*m1 + add %rax,$N[1] + mov ($ap),%rax # ap[0] + adc \$0,%rdx + add $A[1],$N[1] # np[j]*m1+ap[j]*bp[0] + adc \$0,%rdx + mov $N[1],-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[0] + + xor $N[1],$N[1] + add $A[0],$N[0] + adc \$0,$N[1] + mov $N[0],-8(%rsp,$j,8) + mov $N[1],(%rsp,$j,8) # store upmost overflow bit + + lea 1($i),$i # i++ +.align 4 +.Louter4x: + lea 32+128(%rsp,$num,8),%rdx # where 256-byte mask is (+size optimization) + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 +___ +for($k=0;$k<$STRIDE/16;$k+=4) { +$code.=<<___; + movdqa `16*($k+0)-128`($bp),%xmm0 + movdqa `16*($k+1)-128`($bp),%xmm1 + movdqa `16*($k+2)-128`($bp),%xmm2 + movdqa `16*($k+3)-128`($bp),%xmm3 + pand `16*($k+0)-128`(%rdx),%xmm0 + pand `16*($k+1)-128`(%rdx),%xmm1 + por %xmm0,%xmm4 + pand `16*($k+2)-128`(%rdx),%xmm2 + por %xmm1,%xmm5 + pand `16*($k+3)-128`(%rdx),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 +___ +} +$code.=<<___; + por %xmm5,%xmm4 + pshufd \$0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + lea $STRIDE($bp),$bp + movq %xmm0,$m0 # m0=bp[i] + + xor $j,$j # j=0 + + mov (%rsp),$A[0] + mov $n0,$m1 + mulq $m0 # ap[0]*bp[i] + add %rax,$A[0] # ap[0]*bp[i]+tp[0] + mov ($np),%rax + adc \$0,%rdx + + imulq $A[0],$m1 # tp[0]*n0 + mov %rdx,$A[1] + + mulq $m1 # np[0]*m1 + add %rax,$A[0] # "$N[0]", discarded + mov 8($ap),%rax + adc \$0,%rdx + mov %rdx,$N[1] + + mulq $m0 # ap[j]*bp[i] + add %rax,$A[1] + mov 8($np),%rax + adc \$0,%rdx + add 8(%rsp),$A[1] # +tp[1] + adc \$0,%rdx + mov %rdx,$A[0] + + mulq $m1 # np[j]*m1 + add %rax,$N[1] + mov 16($ap),%rax + adc \$0,%rdx + add $A[1],$N[1] # np[j]*m1+ap[j]*bp[i]+tp[j] + lea 4($j),$j # j+=2 + adc \$0,%rdx + mov %rdx,$N[0] + jmp .Linner4x +.align 16 +.Linner4x: + mulq $m0 # ap[j]*bp[i] + add %rax,$A[0] + mov -16($np,$j,8),%rax + adc \$0,%rdx + add -16(%rsp,$j,8),$A[0] # ap[j]*bp[i]+tp[j] + adc \$0,%rdx + mov %rdx,$A[1] + + mulq $m1 # np[j]*m1 + add %rax,$N[0] + mov -8($ap,$j,8),%rax + adc \$0,%rdx + add $A[0],$N[0] + adc \$0,%rdx + mov $N[1],-32(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[1] + + mulq $m0 # ap[j]*bp[i] + add %rax,$A[1] + mov -8($np,$j,8),%rax + adc \$0,%rdx + add -8(%rsp,$j,8),$A[1] + adc \$0,%rdx + mov %rdx,$A[0] + + mulq $m1 # np[j]*m1 + add %rax,$N[1] + mov ($ap,$j,8),%rax + adc \$0,%rdx + add $A[1],$N[1] + adc \$0,%rdx + mov $N[0],-24(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[0] + + mulq $m0 # ap[j]*bp[i] + add %rax,$A[0] + mov ($np,$j,8),%rax + adc \$0,%rdx + add (%rsp,$j,8),$A[0] # ap[j]*bp[i]+tp[j] + adc \$0,%rdx + mov %rdx,$A[1] + + mulq $m1 # np[j]*m1 + add %rax,$N[0] + mov 8($ap,$j,8),%rax + adc \$0,%rdx + add $A[0],$N[0] + adc \$0,%rdx + mov $N[1],-16(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[1] + + mulq $m0 # ap[j]*bp[i] + add %rax,$A[1] + mov 8($np,$j,8),%rax + adc \$0,%rdx + add 8(%rsp,$j,8),$A[1] + adc \$0,%rdx + lea 4($j),$j # j++ + mov %rdx,$A[0] + + mulq $m1 # np[j]*m1 + add %rax,$N[1] + mov -16($ap,$j,8),%rax + adc \$0,%rdx + add $A[1],$N[1] + adc \$0,%rdx + mov $N[0],-40(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[0] + cmp $num,$j + jl .Linner4x + + mulq $m0 # ap[j]*bp[i] + add %rax,$A[0] + mov -16($np,$j,8),%rax + adc \$0,%rdx + add -16(%rsp,$j,8),$A[0] # ap[j]*bp[i]+tp[j] + adc \$0,%rdx + mov %rdx,$A[1] + + mulq $m1 # np[j]*m1 + add %rax,$N[0] + mov -8($ap,$j,8),%rax + adc \$0,%rdx + add $A[0],$N[0] + adc \$0,%rdx + mov $N[1],-32(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[1] + + mulq $m0 # ap[j]*bp[i] + add %rax,$A[1] + mov -8($np,$j,8),%rax + adc \$0,%rdx + add -8(%rsp,$j,8),$A[1] + adc \$0,%rdx + lea 1($i),$i # i++ + mov %rdx,$A[0] + + mulq $m1 # np[j]*m1 + add %rax,$N[1] + mov ($ap),%rax # ap[0] + adc \$0,%rdx + add $A[1],$N[1] + adc \$0,%rdx + mov $N[0],-24(%rsp,$j,8) # tp[j-1] + mov %rdx,$N[0] + + mov $N[1],-16(%rsp,$j,8) # tp[j-1] + + xor $N[1],$N[1] + add $A[0],$N[0] + adc \$0,$N[1] + add (%rsp,$num,8),$N[0] # pull upmost overflow bit + adc \$0,$N[1] + mov $N[0],-8(%rsp,$j,8) + mov $N[1],(%rsp,$j,8) # store upmost overflow bit + + cmp $num,$i + jl .Louter4x +___ +{ +my @ri=("%rax","%rdx",$m0,$m1); +$code.=<<___; + mov 16(%rsp,$num,8),$rp # restore $rp + mov 0(%rsp),@ri[0] # tp[0] + pxor %xmm0,%xmm0 + mov 8(%rsp),@ri[1] # tp[1] + shr \$2,$num # num/=4 + lea (%rsp),$ap # borrow ap for tp + xor $i,$i # i=0 and clear CF! + + sub 0($np),@ri[0] + mov 16($ap),@ri[2] # tp[2] + mov 24($ap),@ri[3] # tp[3] + sbb 8($np),@ri[1] + lea -1($num),$j # j=num/4-1 + jmp .Lsub4x +.align 16 +.Lsub4x: + mov @ri[0],0($rp,$i,8) # rp[i]=tp[i]-np[i] + mov @ri[1],8($rp,$i,8) # rp[i]=tp[i]-np[i] + sbb 16($np,$i,8),@ri[2] + mov 32($ap,$i,8),@ri[0] # tp[i+1] + mov 40($ap,$i,8),@ri[1] + sbb 24($np,$i,8),@ri[3] + mov @ri[2],16($rp,$i,8) # rp[i]=tp[i]-np[i] + mov @ri[3],24($rp,$i,8) # rp[i]=tp[i]-np[i] + sbb 32($np,$i,8),@ri[0] + mov 48($ap,$i,8),@ri[2] + mov 56($ap,$i,8),@ri[3] + sbb 40($np,$i,8),@ri[1] + lea 4($i),$i # i++ + dec $j # doesnn't affect CF! + jnz .Lsub4x + + mov @ri[0],0($rp,$i,8) # rp[i]=tp[i]-np[i] + mov 32($ap,$i,8),@ri[0] # load overflow bit + sbb 16($np,$i,8),@ri[2] + mov @ri[1],8($rp,$i,8) # rp[i]=tp[i]-np[i] + sbb 24($np,$i,8),@ri[3] + mov @ri[2],16($rp,$i,8) # rp[i]=tp[i]-np[i] + + sbb \$0,@ri[0] # handle upmost overflow bit + mov @ri[3],24($rp,$i,8) # rp[i]=tp[i]-np[i] + xor $i,$i # i=0 + and @ri[0],$ap + not @ri[0] + mov $rp,$np + and @ri[0],$np + lea -1($num),$j + or $np,$ap # ap=borrow?tp:rp + + movdqu ($ap),%xmm1 + movdqa %xmm0,(%rsp) + movdqu %xmm1,($rp) + jmp .Lcopy4x +.align 16 +.Lcopy4x: # copy or in-place refresh + movdqu 16($ap,$i),%xmm2 + movdqu 32($ap,$i),%xmm1 + movdqa %xmm0,16(%rsp,$i) + movdqu %xmm2,16($rp,$i) + movdqa %xmm0,32(%rsp,$i) + movdqu %xmm1,32($rp,$i) + lea 32($i),$i + dec $j + jnz .Lcopy4x + + shl \$2,$num + movdqu 16($ap,$i),%xmm2 + movdqa %xmm0,16(%rsp,$i) + movdqu %xmm2,16($rp,$i) +___ +} +$code.=<<___; + mov 8(%rsp,$num,8),%rsi # restore %rsp + mov \$1,%rax + + mov (%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 + mov 24(%rsi),%r12 + mov 32(%rsi),%rbp + mov 40(%rsi),%rbx + lea 48(%rsi),%rsp +.Lmul4x_epilogue: + ret +.size bn_mul4x_mont_gather5,.-bn_mul4x_mont_gather5 +___ +}}} + +{ +my ($inp,$num,$tbl,$idx)=$win64?("%rcx","%rdx","%r8", "%r9d") : # Win64 order + ("%rdi","%rsi","%rdx","%ecx"); # Unix order +my $out=$inp; +my $STRIDE=2**5*8; +my $N=$STRIDE/4; + +$code.=<<___; +.globl bn_scatter5 +.type bn_scatter5,\@abi-omnipotent +.align 16 +bn_scatter5: + cmp \$0, $num + jz .Lscatter_epilogue + lea ($tbl,$idx,8),$tbl +.Lscatter: + mov ($inp),%rax + lea 8($inp),$inp + mov %rax,($tbl) + lea 32*8($tbl),$tbl + sub \$1,$num + jnz .Lscatter +.Lscatter_epilogue: + ret +.size bn_scatter5,.-bn_scatter5 + +.globl bn_gather5 +.type bn_gather5,\@abi-omnipotent +.align 16 +bn_gather5: +.LSEH_begin_bn_gather5: # Win64 thing, but harmless in other cases + # I can't trust assembler to use specific encoding:-( + .byte 0x4c,0x8d,0x14,0x24 # lea (%rsp),%r10 + .byte 0x48,0x81,0xec,0x08,0x01,0x00,0x00 # sub $0x108,%rsp + lea .Linc(%rip),%rax + and \$-16,%rsp # shouldn't be formally required + + movd $idx,%xmm5 + movdqa 0(%rax),%xmm0 # 00000001000000010000000000000000 + movdqa 16(%rax),%xmm1 # 00000002000000020000000200000002 + lea 128($tbl),%r11 # size optimization + lea 128(%rsp),%rax # size optimization + + pshufd \$0,%xmm5,%xmm5 # broadcast $idx + movdqa %xmm1,%xmm4 + movdqa %xmm1,%xmm2 +___ +######################################################################## +# calculate mask by comparing 0..31 to $idx and save result to stack +# +for($i=0;$i<$STRIDE/16;$i+=4) { +$code.=<<___; + paddd %xmm0,%xmm1 + pcmpeqd %xmm5,%xmm0 # compare to 1,0 +___ +$code.=<<___ if ($i); + movdqa %xmm3,`16*($i-1)-128`(%rax) +___ +$code.=<<___; + movdqa %xmm4,%xmm3 + + paddd %xmm1,%xmm2 + pcmpeqd %xmm5,%xmm1 # compare to 3,2 + movdqa %xmm0,`16*($i+0)-128`(%rax) + movdqa %xmm4,%xmm0 + + paddd %xmm2,%xmm3 + pcmpeqd %xmm5,%xmm2 # compare to 5,4 + movdqa %xmm1,`16*($i+1)-128`(%rax) + movdqa %xmm4,%xmm1 + + paddd %xmm3,%xmm0 + pcmpeqd %xmm5,%xmm3 # compare to 7,6 + movdqa %xmm2,`16*($i+2)-128`(%rax) + movdqa %xmm4,%xmm2 +___ +} +$code.=<<___; + movdqa %xmm3,`16*($i-1)-128`(%rax) + jmp .Lgather + +.align 32 +.Lgather: + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 +___ +for($i=0;$i<$STRIDE/16;$i+=4) { +$code.=<<___; + movdqa `16*($i+0)-128`(%r11),%xmm0 + movdqa `16*($i+1)-128`(%r11),%xmm1 + movdqa `16*($i+2)-128`(%r11),%xmm2 + pand `16*($i+0)-128`(%rax),%xmm0 + movdqa `16*($i+3)-128`(%r11),%xmm3 + pand `16*($i+1)-128`(%rax),%xmm1 + por %xmm0,%xmm4 + pand `16*($i+2)-128`(%rax),%xmm2 + por %xmm1,%xmm5 + pand `16*($i+3)-128`(%rax),%xmm3 + por %xmm2,%xmm4 + por %xmm3,%xmm5 +___ +} +$code.=<<___; + por %xmm5,%xmm4 + lea $STRIDE(%r11),%r11 + pshufd \$0x4e,%xmm4,%xmm0 + por %xmm4,%xmm0 + movq %xmm0,($out) # m0=bp[0] + lea 8($out),$out + sub \$1,$num + jnz .Lgather + + lea (%r10),%rsp + ret +.LSEH_end_bn_gather5: +.size bn_gather5,.-bn_gather5 +___ +} +$code.=<<___; +.align 64 +.Linc: + .long 0,0, 1,1 + .long 2,2, 2,2 +.asciz "Montgomery Multiplication with scatter/gather for x86_64, CRYPTOGAMS by " +___ + +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type mul_handler,\@abi-omnipotent +.align 16 +mul_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + mov 8($disp),%rsi # disp->ImageBase + mov 56($disp),%r11 # disp->HandlerData + + mov 0(%r11),%r10d # HandlerData[0] + lea (%rsi,%r10),%r10 # end of prologue label + cmp %r10,%rbx # context->RipRipRsp + + mov 8(%r11),%r10d # HandlerData[2] + lea (%rsi,%r10),%r10 # epilogue label + cmp %r10,%rbx # context->Rip>=epilogue label + jae .Lcommon_seh_tail + + mov 192($context),%r10 # pull $num + mov 8(%rax,%r10,8),%rax # pull saved stack pointer + + lea 48(%rax),%rax + + mov -8(%rax),%rbx + mov -16(%rax),%rbp + mov -24(%rax),%r12 + mov -32(%rax),%r13 + mov -40(%rax),%r14 + mov -48(%rax),%r15 + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + +.Lcommon_seh_tail: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$154,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size mul_handler,.-mul_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_bn_mul_mont_gather5 + .rva .LSEH_end_bn_mul_mont_gather5 + .rva .LSEH_info_bn_mul_mont_gather5 + + .rva .LSEH_begin_bn_mul4x_mont_gather5 + .rva .LSEH_end_bn_mul4x_mont_gather5 + .rva .LSEH_info_bn_mul4x_mont_gather5 + + .rva .LSEH_begin_bn_gather5 + .rva .LSEH_end_bn_gather5 + .rva .LSEH_info_bn_gather5 + +.section .xdata +.align 8 +.LSEH_info_bn_mul_mont_gather5: + .byte 9,0,0,0 + .rva mul_handler + .rva .Lmul_alloca,.Lmul_body,.Lmul_epilogue # HandlerData[] +.align 8 +.LSEH_info_bn_mul4x_mont_gather5: + .byte 9,0,0,0 + .rva mul_handler + .rva .Lmul4x_alloca,.Lmul4x_body,.Lmul4x_epilogue # HandlerData[] +.align 8 +.LSEH_info_bn_gather5: + .byte 0x01,0x0b,0x03,0x0a + .byte 0x0b,0x01,0x21,0x00 # sub rsp,0x108 + .byte 0x04,0xa3,0x00,0x00 # lea r10,(rsp), set_frame r10 +.align 8 +___ +} + +$code =~ s/\`([^\`]*)\`/eval($1)/gem; + +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/bn/bn.h b/libs/openssl/crypto/bn/bn.h new file mode 100644 index 00000000..b39258d4 --- /dev/null +++ b/libs/openssl/crypto/bn/bn.h @@ -0,0 +1,967 @@ +/* crypto/bn/bn.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the Eric Young open source + * license provided above. + * + * The binary polynomial arithmetic software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#ifndef HEADER_BN_H +# define HEADER_BN_H + +# include +# include +# ifndef OPENSSL_NO_FP_API +# include /* FILE */ +# endif +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * These preprocessor symbols control various aspects of the bignum headers + * and library code. They're not defined by any "normal" configuration, as + * they are intended for development and testing purposes. NB: defining all + * three can be useful for debugging application code as well as openssl + * itself. BN_DEBUG - turn on various debugging alterations to the bignum + * code BN_DEBUG_RAND - uses random poisoning of unused words to trip up + * mismanagement of bignum internals. You must also define BN_DEBUG. + */ +/* #define BN_DEBUG */ +/* #define BN_DEBUG_RAND */ + +# ifndef OPENSSL_SMALL_FOOTPRINT +# define BN_MUL_COMBA +# define BN_SQR_COMBA +# define BN_RECURSION +# endif + +/* + * This next option uses the C libraries (2 word)/(1 word) function. If it is + * not defined, I use my C version (which is slower). The reason for this + * flag is that when the particular C compiler library routine is used, and + * the library is linked with a different compiler, the library is missing. + * This mostly happens when the library is built with gcc and then linked + * using normal cc. This would be a common occurrence because gcc normally + * produces code that is 2 times faster than system compilers for the big + * number stuff. For machines with only one compiler (or shared libraries), + * this should be on. Again this in only really a problem on machines using + * "long long's", are 32bit, and are not using my assembler code. + */ +# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || \ + defined(OPENSSL_SYS_WIN32) || defined(linux) +# ifndef BN_DIV2W +# define BN_DIV2W +# endif +# endif + +/* + * assuming long is 64bit - this is the DEC Alpha unsigned long long is only + * 64 bits :-(, don't define BN_LLONG for the DEC Alpha + */ +# ifdef SIXTY_FOUR_BIT_LONG +# define BN_ULLONG unsigned long long +# define BN_ULONG unsigned long +# define BN_LONG long +# define BN_BITS 128 +# define BN_BYTES 8 +# define BN_BITS2 64 +# define BN_BITS4 32 +# define BN_MASK (0xffffffffffffffffffffffffffffffffLL) +# define BN_MASK2 (0xffffffffffffffffL) +# define BN_MASK2l (0xffffffffL) +# define BN_MASK2h (0xffffffff00000000L) +# define BN_MASK2h1 (0xffffffff80000000L) +# define BN_TBIT (0x8000000000000000L) +# define BN_DEC_CONV (10000000000000000000UL) +# define BN_DEC_FMT1 "%lu" +# define BN_DEC_FMT2 "%019lu" +# define BN_DEC_NUM 19 +# define BN_HEX_FMT1 "%lX" +# define BN_HEX_FMT2 "%016lX" +# endif + +/* + * This is where the long long data type is 64 bits, but long is 32. For + * machines where there are 64bit registers, this is the mode to use. IRIX, + * on R4000 and above should use this mode, along with the relevant assembler + * code :-). Do NOT define BN_LLONG. + */ +# ifdef SIXTY_FOUR_BIT +# undef BN_LLONG +# undef BN_ULLONG +# define BN_ULONG unsigned long long +# define BN_LONG long long +# define BN_BITS 128 +# define BN_BYTES 8 +# define BN_BITS2 64 +# define BN_BITS4 32 +# define BN_MASK2 (0xffffffffffffffffLL) +# define BN_MASK2l (0xffffffffL) +# define BN_MASK2h (0xffffffff00000000LL) +# define BN_MASK2h1 (0xffffffff80000000LL) +# define BN_TBIT (0x8000000000000000LL) +# define BN_DEC_CONV (10000000000000000000ULL) +# define BN_DEC_FMT1 "%llu" +# define BN_DEC_FMT2 "%019llu" +# define BN_DEC_NUM 19 +# define BN_HEX_FMT1 "%llX" +# define BN_HEX_FMT2 "%016llX" +# endif + +# ifdef THIRTY_TWO_BIT +# ifdef BN_LLONG +# if defined(_WIN32) && !defined(__GNUC__) +# define BN_ULLONG unsigned __int64 +# define BN_MASK (0xffffffffffffffffI64) +# else +# define BN_ULLONG unsigned long long +# define BN_MASK (0xffffffffffffffffLL) +# endif +# endif +# define BN_ULONG unsigned int +# define BN_LONG int +# define BN_BITS 64 +# define BN_BYTES 4 +# define BN_BITS2 32 +# define BN_BITS4 16 +# define BN_MASK2 (0xffffffffL) +# define BN_MASK2l (0xffff) +# define BN_MASK2h1 (0xffff8000L) +# define BN_MASK2h (0xffff0000L) +# define BN_TBIT (0x80000000L) +# define BN_DEC_CONV (1000000000L) +# define BN_DEC_FMT1 "%u" +# define BN_DEC_FMT2 "%09u" +# define BN_DEC_NUM 9 +# define BN_HEX_FMT1 "%X" +# define BN_HEX_FMT2 "%08X" +# endif + +/* + * 2011-02-22 SMS. In various places, a size_t variable or a type cast to + * size_t was used to perform integer-only operations on pointers. This + * failed on VMS with 64-bit pointers (CC /POINTER_SIZE = 64) because size_t + * is still only 32 bits. What's needed in these cases is an integer type + * with the same size as a pointer, which size_t is not certain to be. The + * only fix here is VMS-specific. + */ +# if defined(OPENSSL_SYS_VMS) +# if __INITIAL_POINTER_SIZE == 64 +# define PTR_SIZE_INT long long +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define PTR_SIZE_INT int +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ +# else /* defined(OPENSSL_SYS_VMS) */ +# define PTR_SIZE_INT size_t +# endif /* defined(OPENSSL_SYS_VMS) [else] */ + +# define BN_DEFAULT_BITS 1280 + +# define BN_FLG_MALLOCED 0x01 +# define BN_FLG_STATIC_DATA 0x02 + +/* + * avoid leaking exponent information through timing, + * BN_mod_exp_mont() will call BN_mod_exp_mont_consttime, + * BN_div() will call BN_div_no_branch, + * BN_mod_inverse() will call BN_mod_inverse_no_branch. + */ +# define BN_FLG_CONSTTIME 0x04 + +# ifdef OPENSSL_NO_DEPRECATED +/* deprecated name for the flag */ +# define BN_FLG_EXP_CONSTTIME BN_FLG_CONSTTIME +/* + * avoid leaking exponent information through timings + * (BN_mod_exp_mont() will call BN_mod_exp_mont_consttime) + */ +# endif + +# ifndef OPENSSL_NO_DEPRECATED +# define BN_FLG_FREE 0x8000 + /* used for debuging */ +# endif +# define BN_set_flags(b,n) ((b)->flags|=(n)) +# define BN_get_flags(b,n) ((b)->flags&(n)) + +/* + * get a clone of a BIGNUM with changed flags, for *temporary* use only (the + * two BIGNUMs cannot not be used in parallel!) + */ +# define BN_with_flags(dest,b,n) ((dest)->d=(b)->d, \ + (dest)->top=(b)->top, \ + (dest)->dmax=(b)->dmax, \ + (dest)->neg=(b)->neg, \ + (dest)->flags=(((dest)->flags & BN_FLG_MALLOCED) \ + | ((b)->flags & ~BN_FLG_MALLOCED) \ + | BN_FLG_STATIC_DATA \ + | (n))) + +/* Already declared in ossl_typ.h */ +# if 0 +typedef struct bignum_st BIGNUM; +/* Used for temp variables (declaration hidden in bn_lcl.h) */ +typedef struct bignum_ctx BN_CTX; +typedef struct bn_blinding_st BN_BLINDING; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct bn_recp_ctx_st BN_RECP_CTX; +typedef struct bn_gencb_st BN_GENCB; +# endif + +struct bignum_st { + BN_ULONG *d; /* Pointer to an array of 'BN_BITS2' bit + * chunks. */ + int top; /* Index of last used d +1. */ + /* The next are internal book keeping for bn_expand. */ + int dmax; /* Size of the d array. */ + int neg; /* one if the number is negative */ + int flags; +}; + +/* Used for montgomery multiplication */ +struct bn_mont_ctx_st { + int ri; /* number of bits in R */ + BIGNUM RR; /* used to convert to montgomery form */ + BIGNUM N; /* The modulus */ + BIGNUM Ni; /* R*(1/R mod N) - N*Ni = 1 (Ni is only + * stored for bignum algorithm) */ + BN_ULONG n0[2]; /* least significant word(s) of Ni; (type + * changed with 0.9.9, was "BN_ULONG n0;" + * before) */ + int flags; +}; + +/* + * Used for reciprocal division/mod functions It cannot be shared between + * threads + */ +struct bn_recp_ctx_st { + BIGNUM N; /* the divisor */ + BIGNUM Nr; /* the reciprocal */ + int num_bits; + int shift; + int flags; +}; + +/* Used for slow "generation" functions. */ +struct bn_gencb_st { + unsigned int ver; /* To handle binary (in)compatibility */ + void *arg; /* callback-specific data */ + union { + /* if(ver==1) - handles old style callbacks */ + void (*cb_1) (int, int, void *); + /* if(ver==2) - new callback style */ + int (*cb_2) (int, int, BN_GENCB *); + } cb; +}; +/* Wrapper function to make using BN_GENCB easier, */ +int BN_GENCB_call(BN_GENCB *cb, int a, int b); +/* Macro to populate a BN_GENCB structure with an "old"-style callback */ +# define BN_GENCB_set_old(gencb, callback, cb_arg) { \ + BN_GENCB *tmp_gencb = (gencb); \ + tmp_gencb->ver = 1; \ + tmp_gencb->arg = (cb_arg); \ + tmp_gencb->cb.cb_1 = (callback); } +/* Macro to populate a BN_GENCB structure with a "new"-style callback */ +# define BN_GENCB_set(gencb, callback, cb_arg) { \ + BN_GENCB *tmp_gencb = (gencb); \ + tmp_gencb->ver = 2; \ + tmp_gencb->arg = (cb_arg); \ + tmp_gencb->cb.cb_2 = (callback); } + +# define BN_prime_checks 0 /* default: select number of iterations based + * on the size of the number */ + +/* + * number of Miller-Rabin iterations for an error rate of less than 2^-80 for + * random 'b'-bit input, b >= 100 (taken from table 4.4 in the Handbook of + * Applied Cryptography [Menezes, van Oorschot, Vanstone; CRC Press 1996]; + * original paper: Damgaard, Landrock, Pomerance: Average case error + * estimates for the strong probable prime test. -- Math. Comp. 61 (1993) + * 177-194) + */ +# define BN_prime_checks_for_size(b) ((b) >= 1300 ? 2 : \ + (b) >= 850 ? 3 : \ + (b) >= 650 ? 4 : \ + (b) >= 550 ? 5 : \ + (b) >= 450 ? 6 : \ + (b) >= 400 ? 7 : \ + (b) >= 350 ? 8 : \ + (b) >= 300 ? 9 : \ + (b) >= 250 ? 12 : \ + (b) >= 200 ? 15 : \ + (b) >= 150 ? 18 : \ + /* b >= 100 */ 27) + +# define BN_num_bytes(a) ((BN_num_bits(a)+7)/8) + +/* Note that BN_abs_is_word didn't work reliably for w == 0 until 0.9.8 */ +# define BN_abs_is_word(a,w) ((((a)->top == 1) && ((a)->d[0] == (BN_ULONG)(w))) || \ + (((w) == 0) && ((a)->top == 0))) +# define BN_is_zero(a) ((a)->top == 0) +# define BN_is_one(a) (BN_abs_is_word((a),1) && !(a)->neg) +# define BN_is_word(a,w) (BN_abs_is_word((a),(w)) && (!(w) || !(a)->neg)) +# define BN_is_odd(a) (((a)->top > 0) && ((a)->d[0] & 1)) + +# define BN_one(a) (BN_set_word((a),1)) +# define BN_zero_ex(a) \ + do { \ + BIGNUM *_tmp_bn = (a); \ + _tmp_bn->top = 0; \ + _tmp_bn->neg = 0; \ + } while(0) +# ifdef OPENSSL_NO_DEPRECATED +# define BN_zero(a) BN_zero_ex(a) +# else +# define BN_zero(a) (BN_set_word((a),0)) +# endif + +const BIGNUM *BN_value_one(void); +char *BN_options(void); +BN_CTX *BN_CTX_new(void); +# ifndef OPENSSL_NO_DEPRECATED +void BN_CTX_init(BN_CTX *c); +# endif +void BN_CTX_free(BN_CTX *c); +void BN_CTX_start(BN_CTX *ctx); +BIGNUM *BN_CTX_get(BN_CTX *ctx); +void BN_CTX_end(BN_CTX *ctx); +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); +int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); +int BN_num_bits(const BIGNUM *a); +int BN_num_bits_word(BN_ULONG); +BIGNUM *BN_new(void); +void BN_init(BIGNUM *); +void BN_clear_free(BIGNUM *a); +BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b); +void BN_swap(BIGNUM *a, BIGNUM *b); +BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2bin(const BIGNUM *a, unsigned char *to); +BIGNUM *BN_mpi2bn(const unsigned char *s, int len, BIGNUM *ret); +int BN_bn2mpi(const BIGNUM *a, unsigned char *to); +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); +/** BN_set_negative sets sign of a BIGNUM + * \param b pointer to the BIGNUM object + * \param n 0 if the BIGNUM b should be positive and a value != 0 otherwise + */ +void BN_set_negative(BIGNUM *b, int n); +/** BN_is_negative returns 1 if the BIGNUM is negative + * \param a pointer to the BIGNUM object + * \return 1 if a < 0 and 0 otherwise + */ +# define BN_is_negative(a) ((a)->neg != 0) + +int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, + BN_CTX *ctx); +# define BN_mod(rem,m,d,ctx) BN_div(NULL,(rem),(m),(d),(ctx)) +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx); +int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx); +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m); +int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx); +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m); + +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w); +int BN_mul_word(BIGNUM *a, BN_ULONG w); +int BN_add_word(BIGNUM *a, BN_ULONG w); +int BN_sub_word(BIGNUM *a, BN_ULONG w); +int BN_set_word(BIGNUM *a, BN_ULONG w); +BN_ULONG BN_get_word(const BIGNUM *a); + +int BN_cmp(const BIGNUM *a, const BIGNUM *b); +void BN_free(BIGNUM *a); +int BN_is_bit_set(const BIGNUM *a, int n); +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_lshift1(BIGNUM *r, const BIGNUM *a); +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont); +int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp2_mont(BIGNUM *r, const BIGNUM *a1, const BIGNUM *p1, + const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *m_ctx); +int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +int BN_mask_bits(BIGNUM *a, int n); +# ifndef OPENSSL_NO_FP_API +int BN_print_fp(FILE *fp, const BIGNUM *a); +# endif +# ifdef HEADER_BIO_H +int BN_print(BIO *fp, const BIGNUM *a); +# else +int BN_print(void *fp, const BIGNUM *a); +# endif +int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx); +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n); +int BN_rshift1(BIGNUM *r, const BIGNUM *a); +void BN_clear(BIGNUM *a); +BIGNUM *BN_dup(const BIGNUM *a); +int BN_ucmp(const BIGNUM *a, const BIGNUM *b); +int BN_set_bit(BIGNUM *a, int n); +int BN_clear_bit(BIGNUM *a, int n); +char *BN_bn2hex(const BIGNUM *a); +char *BN_bn2dec(const BIGNUM *a); +int BN_hex2bn(BIGNUM **a, const char *str); +int BN_dec2bn(BIGNUM **a, const char *str); +int BN_asc2bn(BIGNUM **a, const char *str); +int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); +int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); /* returns + * -2 for + * error */ +BIGNUM *BN_mod_inverse(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); +BIGNUM *BN_mod_sqrt(BIGNUM *ret, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx); + +void BN_consttime_swap(BN_ULONG swap, BIGNUM *a, BIGNUM *b, int nwords); + +/* Deprecated versions */ +# ifndef OPENSSL_NO_DEPRECATED +BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, + void (*callback) (int, int, void *), void *cb_arg); +int BN_is_prime(const BIGNUM *p, int nchecks, + void (*callback) (int, int, void *), + BN_CTX *ctx, void *cb_arg); +int BN_is_prime_fasttest(const BIGNUM *p, int nchecks, + void (*callback) (int, int, void *), BN_CTX *ctx, + void *cb_arg, int do_trial_division); +# endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* Newer versions */ +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, const BIGNUM *add, + const BIGNUM *rem, BN_GENCB *cb); +int BN_is_prime_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, BN_GENCB *cb); +int BN_is_prime_fasttest_ex(const BIGNUM *p, int nchecks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb); + +int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx); + +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + const BIGNUM *Xp, const BIGNUM *Xp1, + const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb); +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, BIGNUM *Xp1, + BIGNUM *Xp2, const BIGNUM *Xp, const BIGNUM *e, + BN_CTX *ctx, BN_GENCB *cb); + +BN_MONT_CTX *BN_MONT_CTX_new(void); +void BN_MONT_CTX_init(BN_MONT_CTX *ctx); +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx); +# define BN_to_montgomery(r,a,mont,ctx) BN_mod_mul_montgomery(\ + (r),(a),&((mont)->RR),(mont),(ctx)) +int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, + BN_MONT_CTX *mont, BN_CTX *ctx); +void BN_MONT_CTX_free(BN_MONT_CTX *mont); +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx); +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from); +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, + const BIGNUM *mod, BN_CTX *ctx); + +/* BN_BLINDING flags */ +# define BN_BLINDING_NO_UPDATE 0x00000001 +# define BN_BLINDING_NO_RECREATE 0x00000002 + +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod); +void BN_BLINDING_free(BN_BLINDING *b); +int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx); +int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *); +int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, + BN_CTX *); +# ifndef OPENSSL_NO_DEPRECATED +unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *); +void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long); +# endif +CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *); +unsigned long BN_BLINDING_get_flags(const BN_BLINDING *); +void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); +BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, + const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, + int (*bn_mod_exp) (BIGNUM *r, + const BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx), + BN_MONT_CTX *m_ctx); + +# ifndef OPENSSL_NO_DEPRECATED +void BN_set_params(int mul, int high, int low, int mont); +int BN_get_params(int which); /* 0, mul, 1 high, 2 low, 3 mont */ +# endif + +void BN_RECP_CTX_init(BN_RECP_CTX *recp); +BN_RECP_CTX *BN_RECP_CTX_new(void); +void BN_RECP_CTX_free(BN_RECP_CTX *recp); +int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *rdiv, BN_CTX *ctx); +int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, + BN_RECP_CTX *recp, BN_CTX *ctx); +int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); +int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, + BN_RECP_CTX *recp, BN_CTX *ctx); + +# ifndef OPENSSL_NO_EC2M + +/* + * Functions for arithmetic over binary polynomials represented by BIGNUMs. + * The BIGNUM::neg property of BIGNUMs representing binary polynomials is + * ignored. Note that input arguments are not const so that their bit arrays + * can be expanded to the appropriate size if needed. + */ + +/* + * r = a + b + */ +int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); +# define BN_GF2m_sub(r, a, b) BN_GF2m_add(r, a, b) +/* + * r=a mod p + */ +int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p); +/* r = (a * b) mod p */ +int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = (a * a) mod p */ +int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +/* r = (1 / b) mod p */ +int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *b, const BIGNUM *p, BN_CTX *ctx); +/* r = (a / b) mod p */ +int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = (a ^ b) mod p */ +int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx); +/* r = sqrt(a) mod p */ +int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); +/* r^2 + r = a mod p */ +int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); +# define BN_GF2m_cmp(a, b) BN_ucmp((a), (b)) +/*- + * Some functions allow for representation of the irreducible polynomials + * as an unsigned int[], say p. The irreducible f(t) is then of the form: + * t^p[0] + t^p[1] + ... + t^p[k] + * where m = p[0] > p[1] > ... > p[k] = 0. + */ +/* r = a mod p */ +int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]); +/* r = (a * b) mod p */ +int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = (a * a) mod p */ +int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], + BN_CTX *ctx); +/* r = (1 / b) mod p */ +int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *b, const int p[], + BN_CTX *ctx); +/* r = (a / b) mod p */ +int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = (a ^ b) mod p */ +int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx); +/* r = sqrt(a) mod p */ +int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); +/* r^2 + r = a mod p */ +int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a, + const int p[], BN_CTX *ctx); +int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max); +int BN_GF2m_arr2poly(const int p[], BIGNUM *a); + +# endif + +/* + * faster mod functions for the 'NIST primes' 0 <= a < p^2 + */ +int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); +int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx); + +const BIGNUM *BN_get0_nist_prime_192(void); +const BIGNUM *BN_get0_nist_prime_224(void); +const BIGNUM *BN_get0_nist_prime_256(void); +const BIGNUM *BN_get0_nist_prime_384(void); +const BIGNUM *BN_get0_nist_prime_521(void); + +/* library internal functions */ + +# define bn_expand(a,bits) \ + ( \ + bits > (INT_MAX - BN_BITS2 + 1) ? \ + NULL \ + : \ + (((bits+BN_BITS2-1)/BN_BITS2) <= (a)->dmax) ? \ + (a) \ + : \ + bn_expand2((a),(bits+BN_BITS2-1)/BN_BITS2) \ + ) + +# define bn_wexpand(a,words) (((words) <= (a)->dmax)?(a):bn_expand2((a),(words))) +BIGNUM *bn_expand2(BIGNUM *a, int words); +# ifndef OPENSSL_NO_DEPRECATED +BIGNUM *bn_dup_expand(const BIGNUM *a, int words); /* unused */ +# endif + +/*- + * Bignum consistency macros + * There is one "API" macro, bn_fix_top(), for stripping leading zeroes from + * bignum data after direct manipulations on the data. There is also an + * "internal" macro, bn_check_top(), for verifying that there are no leading + * zeroes. Unfortunately, some auditing is required due to the fact that + * bn_fix_top() has become an overabused duct-tape because bignum data is + * occasionally passed around in an inconsistent state. So the following + * changes have been made to sort this out; + * - bn_fix_top()s implementation has been moved to bn_correct_top() + * - if BN_DEBUG isn't defined, bn_fix_top() maps to bn_correct_top(), and + * bn_check_top() is as before. + * - if BN_DEBUG *is* defined; + * - bn_check_top() tries to pollute unused words even if the bignum 'top' is + * consistent. (ed: only if BN_DEBUG_RAND is defined) + * - bn_fix_top() maps to bn_check_top() rather than "fixing" anything. + * The idea is to have debug builds flag up inconsistent bignums when they + * occur. If that occurs in a bn_fix_top(), we examine the code in question; if + * the use of bn_fix_top() was appropriate (ie. it follows directly after code + * that manipulates the bignum) it is converted to bn_correct_top(), and if it + * was not appropriate, we convert it permanently to bn_check_top() and track + * down the cause of the bug. Eventually, no internal code should be using the + * bn_fix_top() macro. External applications and libraries should try this with + * their own code too, both in terms of building against the openssl headers + * with BN_DEBUG defined *and* linking with a version of OpenSSL built with it + * defined. This not only improves external code, it provides more test + * coverage for openssl's own code. + */ + +# ifdef BN_DEBUG + +/* We only need assert() when debugging */ +# include + +# ifdef BN_DEBUG_RAND +/* To avoid "make update" cvs wars due to BN_DEBUG, use some tricks */ +# ifndef RAND_pseudo_bytes +int RAND_pseudo_bytes(unsigned char *buf, int num); +# define BN_DEBUG_TRIX +# endif +# define bn_pollute(a) \ + do { \ + const BIGNUM *_bnum1 = (a); \ + if(_bnum1->top < _bnum1->dmax) { \ + unsigned char _tmp_char; \ + /* We cast away const without the compiler knowing, any \ + * *genuinely* constant variables that aren't mutable \ + * wouldn't be constructed with top!=dmax. */ \ + BN_ULONG *_not_const; \ + memcpy(&_not_const, &_bnum1->d, sizeof(BN_ULONG*)); \ + /* Debug only - safe to ignore error return */ \ + RAND_pseudo_bytes(&_tmp_char, 1); \ + memset((unsigned char *)(_not_const + _bnum1->top), _tmp_char, \ + (_bnum1->dmax - _bnum1->top) * sizeof(BN_ULONG)); \ + } \ + } while(0) +# ifdef BN_DEBUG_TRIX +# undef RAND_pseudo_bytes +# endif +# else +# define bn_pollute(a) +# endif +# define bn_check_top(a) \ + do { \ + const BIGNUM *_bnum2 = (a); \ + if (_bnum2 != NULL) { \ + assert((_bnum2->top == 0) || \ + (_bnum2->d[_bnum2->top - 1] != 0)); \ + bn_pollute(_bnum2); \ + } \ + } while(0) + +# define bn_fix_top(a) bn_check_top(a) + +# define bn_check_size(bn, bits) bn_wcheck_size(bn, ((bits+BN_BITS2-1))/BN_BITS2) +# define bn_wcheck_size(bn, words) \ + do { \ + const BIGNUM *_bnum2 = (bn); \ + assert((words) <= (_bnum2)->dmax && (words) >= (_bnum2)->top); \ + /* avoid unused variable warning with NDEBUG */ \ + (void)(_bnum2); \ + } while(0) + +# else /* !BN_DEBUG */ + +# define bn_pollute(a) +# define bn_check_top(a) +# define bn_fix_top(a) bn_correct_top(a) +# define bn_check_size(bn, bits) +# define bn_wcheck_size(bn, words) + +# endif + +# define bn_correct_top(a) \ + { \ + BN_ULONG *ftl; \ + int tmp_top = (a)->top; \ + if (tmp_top > 0) \ + { \ + for (ftl= &((a)->d[tmp_top-1]); tmp_top > 0; tmp_top--) \ + if (*(ftl--)) break; \ + (a)->top = tmp_top; \ + } \ + bn_pollute(a); \ + } + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, + BN_ULONG w); +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w); +void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, int num); +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d); +BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + int num); +BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + int num); + +/* Primes from RFC 2409 */ +BIGNUM *get_rfc2409_prime_768(BIGNUM *bn); +BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn); + +/* Primes from RFC 3526 */ +BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn); +BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn); + +int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BN_strings(void); + +/* Error codes for the BN functions. */ + +/* Function codes. */ +# define BN_F_BNRAND 127 +# define BN_F_BN_BLINDING_CONVERT_EX 100 +# define BN_F_BN_BLINDING_CREATE_PARAM 128 +# define BN_F_BN_BLINDING_INVERT_EX 101 +# define BN_F_BN_BLINDING_NEW 102 +# define BN_F_BN_BLINDING_UPDATE 103 +# define BN_F_BN_BN2DEC 104 +# define BN_F_BN_BN2HEX 105 +# define BN_F_BN_CTX_GET 116 +# define BN_F_BN_CTX_NEW 106 +# define BN_F_BN_CTX_START 129 +# define BN_F_BN_DIV 107 +# define BN_F_BN_DIV_NO_BRANCH 138 +# define BN_F_BN_DIV_RECP 130 +# define BN_F_BN_EXP 123 +# define BN_F_BN_EXPAND2 108 +# define BN_F_BN_EXPAND_INTERNAL 120 +# define BN_F_BN_GF2M_MOD 131 +# define BN_F_BN_GF2M_MOD_EXP 132 +# define BN_F_BN_GF2M_MOD_MUL 133 +# define BN_F_BN_GF2M_MOD_SOLVE_QUAD 134 +# define BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR 135 +# define BN_F_BN_GF2M_MOD_SQR 136 +# define BN_F_BN_GF2M_MOD_SQRT 137 +# define BN_F_BN_LSHIFT 145 +# define BN_F_BN_MOD_EXP2_MONT 118 +# define BN_F_BN_MOD_EXP_MONT 109 +# define BN_F_BN_MOD_EXP_MONT_CONSTTIME 124 +# define BN_F_BN_MOD_EXP_MONT_WORD 117 +# define BN_F_BN_MOD_EXP_RECP 125 +# define BN_F_BN_MOD_EXP_SIMPLE 126 +# define BN_F_BN_MOD_INVERSE 110 +# define BN_F_BN_MOD_INVERSE_NO_BRANCH 139 +# define BN_F_BN_MOD_LSHIFT_QUICK 119 +# define BN_F_BN_MOD_MUL_RECIPROCAL 111 +# define BN_F_BN_MOD_SQRT 121 +# define BN_F_BN_MPI2BN 112 +# define BN_F_BN_NEW 113 +# define BN_F_BN_RAND 114 +# define BN_F_BN_RAND_RANGE 122 +# define BN_F_BN_RSHIFT 146 +# define BN_F_BN_USUB 115 + +/* Reason codes. */ +# define BN_R_ARG2_LT_ARG3 100 +# define BN_R_BAD_RECIPROCAL 101 +# define BN_R_BIGNUM_TOO_LONG 114 +# define BN_R_BITS_TOO_SMALL 118 +# define BN_R_CALLED_WITH_EVEN_MODULUS 102 +# define BN_R_DIV_BY_ZERO 103 +# define BN_R_ENCODING_ERROR 104 +# define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 105 +# define BN_R_INPUT_NOT_REDUCED 110 +# define BN_R_INVALID_LENGTH 106 +# define BN_R_INVALID_RANGE 115 +# define BN_R_INVALID_SHIFT 119 +# define BN_R_NOT_A_SQUARE 111 +# define BN_R_NOT_INITIALIZED 107 +# define BN_R_NO_INVERSE 108 +# define BN_R_NO_SOLUTION 116 +# define BN_R_P_IS_NOT_PRIME 112 +# define BN_R_TOO_MANY_ITERATIONS 113 +# define BN_R_TOO_MANY_TEMPORARY_VARIABLES 109 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/bn/bn.mul b/libs/openssl/crypto/bn/bn.mul new file mode 100644 index 00000000..9728870d --- /dev/null +++ b/libs/openssl/crypto/bn/bn.mul @@ -0,0 +1,19 @@ +We need + +* bn_mul_comba8 +* bn_mul_comba4 +* bn_mul_normal +* bn_mul_recursive + +* bn_sqr_comba8 +* bn_sqr_comba4 +bn_sqr_normal -> BN_sqr +* bn_sqr_recursive + +* bn_mul_low_recursive +* bn_mul_low_normal +* bn_mul_high + +* bn_mul_part_recursive # symetric but not power of 2 + +bn_mul_asymetric_recursive # uneven, but do the chop up. diff --git a/libs/openssl/crypto/bn/bn_add.c b/libs/openssl/crypto/bn/bn_add.c new file mode 100644 index 00000000..2f3d1104 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_add.c @@ -0,0 +1,313 @@ +/* crypto/bn/bn_add.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +/* r can == a or b */ +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) +{ + const BIGNUM *tmp; + int a_neg = a->neg, ret; + + bn_check_top(a); + bn_check_top(b); + + /*- + * a + b a+b + * a + -b a-b + * -a + b b-a + * -a + -b -(a+b) + */ + if (a_neg ^ b->neg) { + /* only one is negative */ + if (a_neg) { + tmp = a; + a = b; + b = tmp; + } + + /* we are now a - b */ + + if (BN_ucmp(a, b) < 0) { + if (!BN_usub(r, b, a)) + return (0); + r->neg = 1; + } else { + if (!BN_usub(r, a, b)) + return (0); + r->neg = 0; + } + return (1); + } + + ret = BN_uadd(r, a, b); + r->neg = a_neg; + bn_check_top(r); + return ret; +} + +/* unsigned add of b to a */ +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) +{ + int max, min, dif; + BN_ULONG *ap, *bp, *rp, carry, t1, t2; + const BIGNUM *tmp; + + bn_check_top(a); + bn_check_top(b); + + if (a->top < b->top) { + tmp = a; + a = b; + b = tmp; + } + max = a->top; + min = b->top; + dif = max - min; + + if (bn_wexpand(r, max + 1) == NULL) + return 0; + + r->top = max; + + ap = a->d; + bp = b->d; + rp = r->d; + + carry = bn_add_words(rp, ap, bp, min); + rp += min; + ap += min; + bp += min; + + if (carry) { + while (dif) { + dif--; + t1 = *(ap++); + t2 = (t1 + 1) & BN_MASK2; + *(rp++) = t2; + if (t2) { + carry = 0; + break; + } + } + if (carry) { + /* carry != 0 => dif == 0 */ + *rp = 1; + r->top++; + } + } + if (dif && rp != ap) + while (dif--) + /* copy remaining words if ap != rp */ + *(rp++) = *(ap++); + r->neg = 0; + bn_check_top(r); + return 1; +} + +/* unsigned subtraction of b from a, a must be larger than b. */ +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) +{ + int max, min, dif; + register BN_ULONG t1, t2, *ap, *bp, *rp; + int i, carry; +#if defined(IRIX_CC_BUG) && !defined(LINT) + int dummy; +#endif + + bn_check_top(a); + bn_check_top(b); + + max = a->top; + min = b->top; + dif = max - min; + + if (dif < 0) { /* hmm... should not be happening */ + BNerr(BN_F_BN_USUB, BN_R_ARG2_LT_ARG3); + return (0); + } + + if (bn_wexpand(r, max) == NULL) + return (0); + + ap = a->d; + bp = b->d; + rp = r->d; + +#if 1 + carry = 0; + for (i = min; i != 0; i--) { + t1 = *(ap++); + t2 = *(bp++); + if (carry) { + carry = (t1 <= t2); + t1 = (t1 - t2 - 1) & BN_MASK2; + } else { + carry = (t1 < t2); + t1 = (t1 - t2) & BN_MASK2; + } +# if defined(IRIX_CC_BUG) && !defined(LINT) + dummy = t1; +# endif + *(rp++) = t1 & BN_MASK2; + } +#else + carry = bn_sub_words(rp, ap, bp, min); + ap += min; + bp += min; + rp += min; +#endif + if (carry) { /* subtracted */ + if (!dif) + /* error: a < b */ + return 0; + while (dif) { + dif--; + t1 = *(ap++); + t2 = (t1 - 1) & BN_MASK2; + *(rp++) = t2; + if (t1) + break; + } + } +#if 0 + memcpy(rp, ap, sizeof(*rp) * (max - i)); +#else + if (rp != ap) { + for (;;) { + if (!dif--) + break; + rp[0] = ap[0]; + if (!dif--) + break; + rp[1] = ap[1]; + if (!dif--) + break; + rp[2] = ap[2]; + if (!dif--) + break; + rp[3] = ap[3]; + rp += 4; + ap += 4; + } + } +#endif + + r->top = max; + r->neg = 0; + bn_correct_top(r); + return (1); +} + +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) +{ + int max; + int add = 0, neg = 0; + const BIGNUM *tmp; + + bn_check_top(a); + bn_check_top(b); + + /*- + * a - b a-b + * a - -b a+b + * -a - b -(a+b) + * -a - -b b-a + */ + if (a->neg) { + if (b->neg) { + tmp = a; + a = b; + b = tmp; + } else { + add = 1; + neg = 1; + } + } else { + if (b->neg) { + add = 1; + neg = 0; + } + } + + if (add) { + if (!BN_uadd(r, a, b)) + return (0); + r->neg = neg; + return (1); + } + + /* We are actually doing a - b :-) */ + + max = (a->top > b->top) ? a->top : b->top; + if (bn_wexpand(r, max) == NULL) + return (0); + if (BN_ucmp(a, b) < 0) { + if (!BN_usub(r, b, a)) + return (0); + r->neg = 1; + } else { + if (!BN_usub(r, a, b)) + return (0); + r->neg = 0; + } + bn_check_top(r); + return (1); +} diff --git a/libs/openssl/crypto/bn/bn_asm.c b/libs/openssl/crypto/bn/bn_asm.c new file mode 100644 index 00000000..114acf3d --- /dev/null +++ b/libs/openssl/crypto/bn/bn_asm.c @@ -0,0 +1,1094 @@ +/* crypto/bn/bn_asm.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef BN_DEBUG +# undef NDEBUG /* avoid conflicting definitions */ +# define NDEBUG +#endif + +#include +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +#if defined(BN_LLONG) || defined(BN_UMULT_HIGH) + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, + BN_ULONG w) +{ + BN_ULONG c1 = 0; + + assert(num >= 0); + if (num <= 0) + return (c1); + +# ifndef OPENSSL_SMALL_FOOTPRINT + while (num & ~3) { + mul_add(rp[0], ap[0], w, c1); + mul_add(rp[1], ap[1], w, c1); + mul_add(rp[2], ap[2], w, c1); + mul_add(rp[3], ap[3], w, c1); + ap += 4; + rp += 4; + num -= 4; + } +# endif + while (num) { + mul_add(rp[0], ap[0], w, c1); + ap++; + rp++; + num--; + } + + return (c1); +} + +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) +{ + BN_ULONG c1 = 0; + + assert(num >= 0); + if (num <= 0) + return (c1); + +# ifndef OPENSSL_SMALL_FOOTPRINT + while (num & ~3) { + mul(rp[0], ap[0], w, c1); + mul(rp[1], ap[1], w, c1); + mul(rp[2], ap[2], w, c1); + mul(rp[3], ap[3], w, c1); + ap += 4; + rp += 4; + num -= 4; + } +# endif + while (num) { + mul(rp[0], ap[0], w, c1); + ap++; + rp++; + num--; + } + return (c1); +} + +void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) +{ + assert(n >= 0); + if (n <= 0) + return; + +# ifndef OPENSSL_SMALL_FOOTPRINT + while (n & ~3) { + sqr(r[0], r[1], a[0]); + sqr(r[2], r[3], a[1]); + sqr(r[4], r[5], a[2]); + sqr(r[6], r[7], a[3]); + a += 4; + r += 8; + n -= 4; + } +# endif + while (n) { + sqr(r[0], r[1], a[0]); + a++; + r += 2; + n--; + } +} + +#else /* !(defined(BN_LLONG) || + * defined(BN_UMULT_HIGH)) */ + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, int num, + BN_ULONG w) +{ + BN_ULONG c = 0; + BN_ULONG bl, bh; + + assert(num >= 0); + if (num <= 0) + return ((BN_ULONG)0); + + bl = LBITS(w); + bh = HBITS(w); + +# ifndef OPENSSL_SMALL_FOOTPRINT + while (num & ~3) { + mul_add(rp[0], ap[0], bl, bh, c); + mul_add(rp[1], ap[1], bl, bh, c); + mul_add(rp[2], ap[2], bl, bh, c); + mul_add(rp[3], ap[3], bl, bh, c); + ap += 4; + rp += 4; + num -= 4; + } +# endif + while (num) { + mul_add(rp[0], ap[0], bl, bh, c); + ap++; + rp++; + num--; + } + return (c); +} + +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, int num, BN_ULONG w) +{ + BN_ULONG carry = 0; + BN_ULONG bl, bh; + + assert(num >= 0); + if (num <= 0) + return ((BN_ULONG)0); + + bl = LBITS(w); + bh = HBITS(w); + +# ifndef OPENSSL_SMALL_FOOTPRINT + while (num & ~3) { + mul(rp[0], ap[0], bl, bh, carry); + mul(rp[1], ap[1], bl, bh, carry); + mul(rp[2], ap[2], bl, bh, carry); + mul(rp[3], ap[3], bl, bh, carry); + ap += 4; + rp += 4; + num -= 4; + } +# endif + while (num) { + mul(rp[0], ap[0], bl, bh, carry); + ap++; + rp++; + num--; + } + return (carry); +} + +void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, int n) +{ + assert(n >= 0); + if (n <= 0) + return; + +# ifndef OPENSSL_SMALL_FOOTPRINT + while (n & ~3) { + sqr64(r[0], r[1], a[0]); + sqr64(r[2], r[3], a[1]); + sqr64(r[4], r[5], a[2]); + sqr64(r[6], r[7], a[3]); + a += 4; + r += 8; + n -= 4; + } +# endif + while (n) { + sqr64(r[0], r[1], a[0]); + a++; + r += 2; + n--; + } +} + +#endif /* !(defined(BN_LLONG) || + * defined(BN_UMULT_HIGH)) */ + +#if defined(BN_LLONG) && defined(BN_DIV2W) + +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) +{ + return ((BN_ULONG)(((((BN_ULLONG) h) << BN_BITS2) | l) / (BN_ULLONG) d)); +} + +#else + +/* Divide h,l by d and return the result. */ +/* I need to test this some more :-( */ +BN_ULONG bn_div_words(BN_ULONG h, BN_ULONG l, BN_ULONG d) +{ + BN_ULONG dh, dl, q, ret = 0, th, tl, t; + int i, count = 2; + + if (d == 0) + return (BN_MASK2); + + i = BN_num_bits_word(d); + assert((i == BN_BITS2) || (h <= (BN_ULONG)1 << i)); + + i = BN_BITS2 - i; + if (h >= d) + h -= d; + + if (i) { + d <<= i; + h = (h << i) | (l >> (BN_BITS2 - i)); + l <<= i; + } + dh = (d & BN_MASK2h) >> BN_BITS4; + dl = (d & BN_MASK2l); + for (;;) { + if ((h >> BN_BITS4) == dh) + q = BN_MASK2l; + else + q = h / dh; + + th = q * dh; + tl = dl * q; + for (;;) { + t = h - th; + if ((t & BN_MASK2h) || + ((tl) <= ((t << BN_BITS4) | ((l & BN_MASK2h) >> BN_BITS4)))) + break; + q--; + th -= dh; + tl -= dl; + } + t = (tl >> BN_BITS4); + tl = (tl << BN_BITS4) & BN_MASK2h; + th += t; + + if (l < tl) + th++; + l -= tl; + if (h < th) { + h += d; + q--; + } + h -= th; + + if (--count == 0) + break; + + ret = q << BN_BITS4; + h = ((h << BN_BITS4) | (l >> BN_BITS4)) & BN_MASK2; + l = (l & BN_MASK2l) << BN_BITS4; + } + ret |= q; + return (ret); +} +#endif /* !defined(BN_LLONG) && defined(BN_DIV2W) */ + +#ifdef BN_LLONG +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int n) +{ + BN_ULLONG ll = 0; + + assert(n >= 0); + if (n <= 0) + return ((BN_ULONG)0); + +# ifndef OPENSSL_SMALL_FOOTPRINT + while (n & ~3) { + ll += (BN_ULLONG) a[0] + b[0]; + r[0] = (BN_ULONG)ll & BN_MASK2; + ll >>= BN_BITS2; + ll += (BN_ULLONG) a[1] + b[1]; + r[1] = (BN_ULONG)ll & BN_MASK2; + ll >>= BN_BITS2; + ll += (BN_ULLONG) a[2] + b[2]; + r[2] = (BN_ULONG)ll & BN_MASK2; + ll >>= BN_BITS2; + ll += (BN_ULLONG) a[3] + b[3]; + r[3] = (BN_ULONG)ll & BN_MASK2; + ll >>= BN_BITS2; + a += 4; + b += 4; + r += 4; + n -= 4; + } +# endif + while (n) { + ll += (BN_ULLONG) a[0] + b[0]; + r[0] = (BN_ULONG)ll & BN_MASK2; + ll >>= BN_BITS2; + a++; + b++; + r++; + n--; + } + return ((BN_ULONG)ll); +} +#else /* !BN_LLONG */ +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int n) +{ + BN_ULONG c, l, t; + + assert(n >= 0); + if (n <= 0) + return ((BN_ULONG)0); + + c = 0; +# ifndef OPENSSL_SMALL_FOOTPRINT + while (n & ~3) { + t = a[0]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[0]) & BN_MASK2; + c += (l < t); + r[0] = l; + t = a[1]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[1]) & BN_MASK2; + c += (l < t); + r[1] = l; + t = a[2]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[2]) & BN_MASK2; + c += (l < t); + r[2] = l; + t = a[3]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[3]) & BN_MASK2; + c += (l < t); + r[3] = l; + a += 4; + b += 4; + r += 4; + n -= 4; + } +# endif + while (n) { + t = a[0]; + t = (t + c) & BN_MASK2; + c = (t < c); + l = (t + b[0]) & BN_MASK2; + c += (l < t); + r[0] = l; + a++; + b++; + r++; + n--; + } + return ((BN_ULONG)c); +} +#endif /* !BN_LLONG */ + +BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int n) +{ + BN_ULONG t1, t2; + int c = 0; + + assert(n >= 0); + if (n <= 0) + return ((BN_ULONG)0); + +#ifndef OPENSSL_SMALL_FOOTPRINT + while (n & ~3) { + t1 = a[0]; + t2 = b[0]; + r[0] = (t1 - t2 - c) & BN_MASK2; + if (t1 != t2) + c = (t1 < t2); + t1 = a[1]; + t2 = b[1]; + r[1] = (t1 - t2 - c) & BN_MASK2; + if (t1 != t2) + c = (t1 < t2); + t1 = a[2]; + t2 = b[2]; + r[2] = (t1 - t2 - c) & BN_MASK2; + if (t1 != t2) + c = (t1 < t2); + t1 = a[3]; + t2 = b[3]; + r[3] = (t1 - t2 - c) & BN_MASK2; + if (t1 != t2) + c = (t1 < t2); + a += 4; + b += 4; + r += 4; + n -= 4; + } +#endif + while (n) { + t1 = a[0]; + t2 = b[0]; + r[0] = (t1 - t2 - c) & BN_MASK2; + if (t1 != t2) + c = (t1 < t2); + a++; + b++; + r++; + n--; + } + return (c); +} + +#if defined(BN_MUL_COMBA) && !defined(OPENSSL_SMALL_FOOTPRINT) + +# undef bn_mul_comba8 +# undef bn_mul_comba4 +# undef bn_sqr_comba8 +# undef bn_sqr_comba4 + +/* mul_add_c(a,b,c0,c1,c2) -- c+=a*b for three word number c=(c2,c1,c0) */ +/* mul_add_c2(a,b,c0,c1,c2) -- c+=2*a*b for three word number c=(c2,c1,c0) */ +/* sqr_add_c(a,i,c0,c1,c2) -- c+=a[i]^2 for three word number c=(c2,c1,c0) */ +/* + * sqr_add_c2(a,i,c0,c1,c2) -- c+=2*a[i]*a[j] for three word number + * c=(c2,c1,c0) + */ + +/* + * Keep in mind that carrying into high part of multiplication result + * can not overflow, because it cannot be all-ones. + */ +# ifdef BN_LLONG +# define mul_add_c(a,b,c0,c1,c2) \ + t=(BN_ULLONG)a*b; \ + t1=(BN_ULONG)Lw(t); \ + t2=(BN_ULONG)Hw(t); \ + c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \ + c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; + +# define mul_add_c2(a,b,c0,c1,c2) \ + t=(BN_ULLONG)a*b; \ + tt=(t+t)&BN_MASK; \ + if (tt < t) c2++; \ + t1=(BN_ULONG)Lw(tt); \ + t2=(BN_ULONG)Hw(tt); \ + c0=(c0+t1)&BN_MASK2; \ + if ((c0 < t1) && (((++t2)&BN_MASK2) == 0)) c2++; \ + c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; + +# define sqr_add_c(a,i,c0,c1,c2) \ + t=(BN_ULLONG)a[i]*a[i]; \ + t1=(BN_ULONG)Lw(t); \ + t2=(BN_ULONG)Hw(t); \ + c0=(c0+t1)&BN_MASK2; if ((c0) < t1) t2++; \ + c1=(c1+t2)&BN_MASK2; if ((c1) < t2) c2++; + +# define sqr_add_c2(a,i,j,c0,c1,c2) \ + mul_add_c2((a)[i],(a)[j],c0,c1,c2) + +# elif defined(BN_UMULT_LOHI) + +# define mul_add_c(a,b,c0,c1,c2) { \ + BN_ULONG ta=(a),tb=(b); \ + BN_UMULT_LOHI(t1,t2,ta,tb); \ + c0 += t1; t2 += (c0 +/* + * This is essentially reference implementation, which may or may not + * result in performance improvement. E.g. on IA-32 this routine was + * observed to give 40% faster rsa1024 private key operations and 10% + * faster rsa4096 ones, while on AMD64 it improves rsa1024 sign only + * by 10% and *worsens* rsa4096 sign by 15%. Once again, it's a + * reference implementation, one to be used as starting point for + * platform-specific assembler. Mentioned numbers apply to compiler + * generated code compiled with and without -DOPENSSL_BN_ASM_MONT and + * can vary not only from platform to platform, but even for compiler + * versions. Assembler vs. assembler improvement coefficients can + * [and are known to] differ and are to be documented elsewhere. + */ +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0p, int num) +{ + BN_ULONG c0, c1, ml, *tp, n0; +# ifdef mul64 + BN_ULONG mh; +# endif + volatile BN_ULONG *vp; + int i = 0, j; + +# if 0 /* template for platform-specific + * implementation */ + if (ap == bp) + return bn_sqr_mont(rp, ap, np, n0p, num); +# endif + vp = tp = alloca((num + 2) * sizeof(BN_ULONG)); + + n0 = *n0p; + + c0 = 0; + ml = bp[0]; +# ifdef mul64 + mh = HBITS(ml); + ml = LBITS(ml); + for (j = 0; j < num; ++j) + mul(tp[j], ap[j], ml, mh, c0); +# else + for (j = 0; j < num; ++j) + mul(tp[j], ap[j], ml, c0); +# endif + + tp[num] = c0; + tp[num + 1] = 0; + goto enter; + + for (i = 0; i < num; i++) { + c0 = 0; + ml = bp[i]; +# ifdef mul64 + mh = HBITS(ml); + ml = LBITS(ml); + for (j = 0; j < num; ++j) + mul_add(tp[j], ap[j], ml, mh, c0); +# else + for (j = 0; j < num; ++j) + mul_add(tp[j], ap[j], ml, c0); +# endif + c1 = (tp[num] + c0) & BN_MASK2; + tp[num] = c1; + tp[num + 1] = (c1 < c0 ? 1 : 0); + enter: + c1 = tp[0]; + ml = (c1 * n0) & BN_MASK2; + c0 = 0; +# ifdef mul64 + mh = HBITS(ml); + ml = LBITS(ml); + mul_add(c1, np[0], ml, mh, c0); +# else + mul_add(c1, ml, np[0], c0); +# endif + for (j = 1; j < num; j++) { + c1 = tp[j]; +# ifdef mul64 + mul_add(c1, np[j], ml, mh, c0); +# else + mul_add(c1, ml, np[j], c0); +# endif + tp[j - 1] = c1 & BN_MASK2; + } + c1 = (tp[num] + c0) & BN_MASK2; + tp[num - 1] = c1; + tp[num] = tp[num + 1] + (c1 < c0 ? 1 : 0); + } + + if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) { + c0 = bn_sub_words(rp, tp, np, num); + if (tp[num] != 0 || c0 == 0) { + for (i = 0; i < num + 2; i++) + vp[i] = 0; + return 1; + } + } + for (i = 0; i < num; i++) + rp[i] = tp[i], vp[i] = 0; + vp[num] = 0; + vp[num + 1] = 0; + return 1; +} +# else +/* + * Return value of 0 indicates that multiplication/convolution was not + * performed to signal the caller to fall down to alternative/original + * code-path. + */ +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num) +{ + return 0; +} +# endif /* OPENSSL_BN_ASM_MONT */ +# endif + +#else /* !BN_MUL_COMBA */ + +/* hmm... is it faster just to do a multiply? */ +# undef bn_sqr_comba4 +void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a) +{ + BN_ULONG t[8]; + bn_sqr_normal(r, a, 4, t); +} + +# undef bn_sqr_comba8 +void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a) +{ + BN_ULONG t[16]; + bn_sqr_normal(r, a, 8, t); +} + +void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) +{ + r[4] = bn_mul_words(&(r[0]), a, 4, b[0]); + r[5] = bn_mul_add_words(&(r[1]), a, 4, b[1]); + r[6] = bn_mul_add_words(&(r[2]), a, 4, b[2]); + r[7] = bn_mul_add_words(&(r[3]), a, 4, b[3]); +} + +void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b) +{ + r[8] = bn_mul_words(&(r[0]), a, 8, b[0]); + r[9] = bn_mul_add_words(&(r[1]), a, 8, b[1]); + r[10] = bn_mul_add_words(&(r[2]), a, 8, b[2]); + r[11] = bn_mul_add_words(&(r[3]), a, 8, b[3]); + r[12] = bn_mul_add_words(&(r[4]), a, 8, b[4]); + r[13] = bn_mul_add_words(&(r[5]), a, 8, b[5]); + r[14] = bn_mul_add_words(&(r[6]), a, 8, b[6]); + r[15] = bn_mul_add_words(&(r[7]), a, 8, b[7]); +} + +# ifdef OPENSSL_NO_ASM +# ifdef OPENSSL_BN_ASM_MONT +# include +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0p, int num) +{ + BN_ULONG c0, c1, *tp, n0 = *n0p; + volatile BN_ULONG *vp; + int i = 0, j; + + vp = tp = alloca((num + 2) * sizeof(BN_ULONG)); + + for (i = 0; i <= num; i++) + tp[i] = 0; + + for (i = 0; i < num; i++) { + c0 = bn_mul_add_words(tp, ap, num, bp[i]); + c1 = (tp[num] + c0) & BN_MASK2; + tp[num] = c1; + tp[num + 1] = (c1 < c0 ? 1 : 0); + + c0 = bn_mul_add_words(tp, np, num, tp[0] * n0); + c1 = (tp[num] + c0) & BN_MASK2; + tp[num] = c1; + tp[num + 1] += (c1 < c0 ? 1 : 0); + for (j = 0; j <= num; j++) + tp[j] = tp[j + 1]; + } + + if (tp[num] != 0 || tp[num - 1] >= np[num - 1]) { + c0 = bn_sub_words(rp, tp, np, num); + if (tp[num] != 0 || c0 == 0) { + for (i = 0; i < num + 2; i++) + vp[i] = 0; + return 1; + } + } + for (i = 0; i < num; i++) + rp[i] = tp[i], vp[i] = 0; + vp[num] = 0; + vp[num + 1] = 0; + return 1; +} +# else +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num) +{ + return 0; +} +# endif /* OPENSSL_BN_ASM_MONT */ +# endif + +#endif /* !BN_MUL_COMBA */ diff --git a/libs/openssl/crypto/bn/bn_blind.c b/libs/openssl/crypto/bn/bn_blind.c new file mode 100644 index 00000000..d448daa3 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_blind.c @@ -0,0 +1,385 @@ +/* crypto/bn/bn_blind.c */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +#define BN_BLINDING_COUNTER 32 + +struct bn_blinding_st { + BIGNUM *A; + BIGNUM *Ai; + BIGNUM *e; + BIGNUM *mod; /* just a reference */ +#ifndef OPENSSL_NO_DEPRECATED + unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b; used + * only by crypto/rsa/rsa_eay.c, rsa_lib.c */ +#endif + CRYPTO_THREADID tid; + int counter; + unsigned long flags; + BN_MONT_CTX *m_ctx; + int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +}; + +BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod) +{ + BN_BLINDING *ret = NULL; + + bn_check_top(mod); + + if ((ret = (BN_BLINDING *)OPENSSL_malloc(sizeof(BN_BLINDING))) == NULL) { + BNerr(BN_F_BN_BLINDING_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + memset(ret, 0, sizeof(BN_BLINDING)); + if (A != NULL) { + if ((ret->A = BN_dup(A)) == NULL) + goto err; + } + if (Ai != NULL) { + if ((ret->Ai = BN_dup(Ai)) == NULL) + goto err; + } + + /* save a copy of mod in the BN_BLINDING structure */ + if ((ret->mod = BN_dup(mod)) == NULL) + goto err; + if (BN_get_flags(mod, BN_FLG_CONSTTIME) != 0) + BN_set_flags(ret->mod, BN_FLG_CONSTTIME); + + /* + * Set the counter to the special value -1 to indicate that this is + * never-used fresh blinding that does not need updating before first + * use. + */ + ret->counter = -1; + CRYPTO_THREADID_current(&ret->tid); + return (ret); + err: + if (ret != NULL) + BN_BLINDING_free(ret); + return (NULL); +} + +void BN_BLINDING_free(BN_BLINDING *r) +{ + if (r == NULL) + return; + + if (r->A != NULL) + BN_free(r->A); + if (r->Ai != NULL) + BN_free(r->Ai); + if (r->e != NULL) + BN_free(r->e); + if (r->mod != NULL) + BN_free(r->mod); + OPENSSL_free(r); +} + +int BN_BLINDING_update(BN_BLINDING *b, BN_CTX *ctx) +{ + int ret = 0; + + if ((b->A == NULL) || (b->Ai == NULL)) { + BNerr(BN_F_BN_BLINDING_UPDATE, BN_R_NOT_INITIALIZED); + goto err; + } + + if (b->counter == -1) + b->counter = 0; + + if (++b->counter == BN_BLINDING_COUNTER && b->e != NULL && + !(b->flags & BN_BLINDING_NO_RECREATE)) { + /* re-create blinding parameters */ + if (!BN_BLINDING_create_param(b, NULL, NULL, ctx, NULL, NULL)) + goto err; + } else if (!(b->flags & BN_BLINDING_NO_UPDATE)) { + if (!BN_mod_mul(b->A, b->A, b->A, b->mod, ctx)) + goto err; + if (!BN_mod_mul(b->Ai, b->Ai, b->Ai, b->mod, ctx)) + goto err; + } + + ret = 1; + err: + if (b->counter == BN_BLINDING_COUNTER) + b->counter = 0; + return (ret); +} + +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) +{ + return BN_BLINDING_convert_ex(n, NULL, b, ctx); +} + +int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *ctx) +{ + int ret = 1; + + bn_check_top(n); + + if ((b->A == NULL) || (b->Ai == NULL)) { + BNerr(BN_F_BN_BLINDING_CONVERT_EX, BN_R_NOT_INITIALIZED); + return (0); + } + + if (b->counter == -1) + /* Fresh blinding, doesn't need updating. */ + b->counter = 0; + else if (!BN_BLINDING_update(b, ctx)) + return (0); + + if (r != NULL) { + if (!BN_copy(r, b->Ai)) + ret = 0; + } + + if (!BN_mod_mul(n, n, b->A, b->mod, ctx)) + ret = 0; + + return ret; +} + +int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx) +{ + return BN_BLINDING_invert_ex(n, NULL, b, ctx); +} + +int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, + BN_CTX *ctx) +{ + int ret; + + bn_check_top(n); + + if (r != NULL) + ret = BN_mod_mul(n, n, r, b->mod, ctx); + else { + if (b->Ai == NULL) { + BNerr(BN_F_BN_BLINDING_INVERT_EX, BN_R_NOT_INITIALIZED); + return (0); + } + ret = BN_mod_mul(n, n, b->Ai, b->mod, ctx); + } + + bn_check_top(n); + return (ret); +} + +#ifndef OPENSSL_NO_DEPRECATED +unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b) +{ + return b->thread_id; +} + +void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n) +{ + b->thread_id = n; +} +#endif + +CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *b) +{ + return &b->tid; +} + +unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b) +{ + return b->flags; +} + +void BN_BLINDING_set_flags(BN_BLINDING *b, unsigned long flags) +{ + b->flags = flags; +} + +BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, + const BIGNUM *e, BIGNUM *m, BN_CTX *ctx, + int (*bn_mod_exp) (BIGNUM *r, + const BIGNUM *a, + const BIGNUM *p, + const BIGNUM *m, + BN_CTX *ctx, + BN_MONT_CTX *m_ctx), + BN_MONT_CTX *m_ctx) +{ + int retry_counter = 32; + BN_BLINDING *ret = NULL; + + if (b == NULL) + ret = BN_BLINDING_new(NULL, NULL, m); + else + ret = b; + + if (ret == NULL) + goto err; + + if (ret->A == NULL && (ret->A = BN_new()) == NULL) + goto err; + if (ret->Ai == NULL && (ret->Ai = BN_new()) == NULL) + goto err; + + if (e != NULL) { + if (ret->e != NULL) + BN_free(ret->e); + ret->e = BN_dup(e); + } + if (ret->e == NULL) + goto err; + + if (bn_mod_exp != NULL) + ret->bn_mod_exp = bn_mod_exp; + if (m_ctx != NULL) + ret->m_ctx = m_ctx; + + do { + if (!BN_rand_range(ret->A, ret->mod)) + goto err; + if (BN_mod_inverse(ret->Ai, ret->A, ret->mod, ctx) == NULL) { + /* + * this should almost never happen for good RSA keys + */ + unsigned long error = ERR_peek_last_error(); + if (ERR_GET_REASON(error) == BN_R_NO_INVERSE) { + if (retry_counter-- == 0) { + BNerr(BN_F_BN_BLINDING_CREATE_PARAM, + BN_R_TOO_MANY_ITERATIONS); + goto err; + } + ERR_clear_error(); + } else + goto err; + } else + break; + } while (1); + + if (ret->bn_mod_exp != NULL && ret->m_ctx != NULL) { + if (!ret->bn_mod_exp + (ret->A, ret->A, ret->e, ret->mod, ctx, ret->m_ctx)) + goto err; + } else { + if (!BN_mod_exp(ret->A, ret->A, ret->e, ret->mod, ctx)) + goto err; + } + + return ret; + err: + if (b == NULL && ret != NULL) { + BN_BLINDING_free(ret); + ret = NULL; + } + + return ret; +} diff --git a/libs/openssl/crypto/bn/bn_const.c b/libs/openssl/crypto/bn/bn_const.c new file mode 100644 index 00000000..12c3208c --- /dev/null +++ b/libs/openssl/crypto/bn/bn_const.c @@ -0,0 +1,547 @@ +/* crypto/bn/knownprimes.c */ +/* Insert boilerplate */ + +#include "bn.h" + +/*- + * "First Oakley Default Group" from RFC2409, section 6.1. + * + * The prime is: 2^768 - 2 ^704 - 1 + 2^64 * { [2^638 pi] + 149686 } + * + * RFC2409 specifies a generator of 2. + * RFC2412 specifies a generator of of 22. + */ + +BIGNUM *get_rfc2409_prime_768(BIGNUM *bn) +{ + static const unsigned char RFC2409_PRIME_768[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x3A, 0x36, 0x20, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC2409_PRIME_768, sizeof(RFC2409_PRIME_768), bn); +} + +/*- + * "Second Oakley Default Group" from RFC2409, section 6.2. + * + * The prime is: 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 }. + * + * RFC2409 specifies a generator of 2. + * RFC2412 specifies a generator of 22. + */ + +BIGNUM *get_rfc2409_prime_1024(BIGNUM *bn) +{ + static const unsigned char RFC2409_PRIME_1024[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC2409_PRIME_1024, sizeof(RFC2409_PRIME_1024), bn); +} + +/*- + * "1536-bit MODP Group" from RFC3526, Section 2. + * + * The prime is: 2^1536 - 2^1472 - 1 + 2^64 * { [2^1406 pi] + 741804 } + * + * RFC3526 specifies a generator of 2. + * RFC2312 specifies a generator of 22. + */ + +BIGNUM *get_rfc3526_prime_1536(BIGNUM *bn) +{ + static const unsigned char RFC3526_PRIME_1536[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC3526_PRIME_1536, sizeof(RFC3526_PRIME_1536), bn); +} + +/*- + * "2048-bit MODP Group" from RFC3526, Section 3. + * + * The prime is: 2^2048 - 2^1984 - 1 + 2^64 * { [2^1918 pi] + 124476 } + * + * RFC3526 specifies a generator of 2. + */ + +BIGNUM *get_rfc3526_prime_2048(BIGNUM *bn) +{ + static const unsigned char RFC3526_PRIME_2048[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAC, 0xAA, 0x68, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC3526_PRIME_2048, sizeof(RFC3526_PRIME_2048), bn); +} + +/*- + * "3072-bit MODP Group" from RFC3526, Section 4. + * + * The prime is: 2^3072 - 2^3008 - 1 + 2^64 * { [2^2942 pi] + 1690314 } + * + * RFC3526 specifies a generator of 2. + */ + +BIGNUM *get_rfc3526_prime_3072(BIGNUM *bn) +{ + static const unsigned char RFC3526_PRIME_3072[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x3A, 0xD2, 0xCA, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC3526_PRIME_3072, sizeof(RFC3526_PRIME_3072), bn); +} + +/*- + * "4096-bit MODP Group" from RFC3526, Section 5. + * + * The prime is: 2^4096 - 2^4032 - 1 + 2^64 * { [2^3966 pi] + 240904 } + * + * RFC3526 specifies a generator of 2. + */ + +BIGNUM *get_rfc3526_prime_4096(BIGNUM *bn) +{ + static const unsigned char RFC3526_PRIME_4096[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, + 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, + 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, + 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, + 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, + 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, + 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, + 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, + 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, + 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, + 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, + 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, + 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, + 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x06, 0x31, 0x99, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC3526_PRIME_4096, sizeof(RFC3526_PRIME_4096), bn); +} + +/*- + * "6144-bit MODP Group" from RFC3526, Section 6. + * + * The prime is: 2^6144 - 2^6080 - 1 + 2^64 * { [2^6014 pi] + 929484 } + * + * RFC3526 specifies a generator of 2. + */ + +BIGNUM *get_rfc3526_prime_6144(BIGNUM *bn) +{ + static const unsigned char RFC3526_PRIME_6144[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, + 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, + 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, + 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, + 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, + 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, + 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, + 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, + 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, + 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, + 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, + 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, + 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, + 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, + 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, + 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE, + 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, + 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, + 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE, + 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, + 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, + 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED, + 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, + 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, + 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42, + 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, + 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, + 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03, + 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, + 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, + 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E, + 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, + 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, + 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5, + 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, + 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, + 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0, + 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, + 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, + 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0, + 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, + 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, + 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68, + 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, + 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, + 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xCC, 0x40, 0x24, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC3526_PRIME_6144, sizeof(RFC3526_PRIME_6144), bn); +} + +/*- + * "8192-bit MODP Group" from RFC3526, Section 7. + * + * The prime is: 2^8192 - 2^8128 - 1 + 2^64 * { [2^8062 pi] + 4743158 } + * + * RFC3526 specifies a generator of 2. + */ + +BIGNUM *get_rfc3526_prime_8192(BIGNUM *bn) +{ + static const unsigned char RFC3526_PRIME_8192[] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, + 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, + 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, + 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, + 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, + 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, + 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, + 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, + 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, + 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, + 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, + 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, + 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, + 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, + 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, + 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, + 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, + 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, + 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, + 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, + 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, + 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x18, 0x21, 0x7C, + 0x32, 0x90, 0x5E, 0x46, 0x2E, 0x36, 0xCE, 0x3B, + 0xE3, 0x9E, 0x77, 0x2C, 0x18, 0x0E, 0x86, 0x03, + 0x9B, 0x27, 0x83, 0xA2, 0xEC, 0x07, 0xA2, 0x8F, + 0xB5, 0xC5, 0x5D, 0xF0, 0x6F, 0x4C, 0x52, 0xC9, + 0xDE, 0x2B, 0xCB, 0xF6, 0x95, 0x58, 0x17, 0x18, + 0x39, 0x95, 0x49, 0x7C, 0xEA, 0x95, 0x6A, 0xE5, + 0x15, 0xD2, 0x26, 0x18, 0x98, 0xFA, 0x05, 0x10, + 0x15, 0x72, 0x8E, 0x5A, 0x8A, 0xAA, 0xC4, 0x2D, + 0xAD, 0x33, 0x17, 0x0D, 0x04, 0x50, 0x7A, 0x33, + 0xA8, 0x55, 0x21, 0xAB, 0xDF, 0x1C, 0xBA, 0x64, + 0xEC, 0xFB, 0x85, 0x04, 0x58, 0xDB, 0xEF, 0x0A, + 0x8A, 0xEA, 0x71, 0x57, 0x5D, 0x06, 0x0C, 0x7D, + 0xB3, 0x97, 0x0F, 0x85, 0xA6, 0xE1, 0xE4, 0xC7, + 0xAB, 0xF5, 0xAE, 0x8C, 0xDB, 0x09, 0x33, 0xD7, + 0x1E, 0x8C, 0x94, 0xE0, 0x4A, 0x25, 0x61, 0x9D, + 0xCE, 0xE3, 0xD2, 0x26, 0x1A, 0xD2, 0xEE, 0x6B, + 0xF1, 0x2F, 0xFA, 0x06, 0xD9, 0x8A, 0x08, 0x64, + 0xD8, 0x76, 0x02, 0x73, 0x3E, 0xC8, 0x6A, 0x64, + 0x52, 0x1F, 0x2B, 0x18, 0x17, 0x7B, 0x20, 0x0C, + 0xBB, 0xE1, 0x17, 0x57, 0x7A, 0x61, 0x5D, 0x6C, + 0x77, 0x09, 0x88, 0xC0, 0xBA, 0xD9, 0x46, 0xE2, + 0x08, 0xE2, 0x4F, 0xA0, 0x74, 0xE5, 0xAB, 0x31, + 0x43, 0xDB, 0x5B, 0xFC, 0xE0, 0xFD, 0x10, 0x8E, + 0x4B, 0x82, 0xD1, 0x20, 0xA9, 0x21, 0x08, 0x01, + 0x1A, 0x72, 0x3C, 0x12, 0xA7, 0x87, 0xE6, 0xD7, + 0x88, 0x71, 0x9A, 0x10, 0xBD, 0xBA, 0x5B, 0x26, + 0x99, 0xC3, 0x27, 0x18, 0x6A, 0xF4, 0xE2, 0x3C, + 0x1A, 0x94, 0x68, 0x34, 0xB6, 0x15, 0x0B, 0xDA, + 0x25, 0x83, 0xE9, 0xCA, 0x2A, 0xD4, 0x4C, 0xE8, + 0xDB, 0xBB, 0xC2, 0xDB, 0x04, 0xDE, 0x8E, 0xF9, + 0x2E, 0x8E, 0xFC, 0x14, 0x1F, 0xBE, 0xCA, 0xA6, + 0x28, 0x7C, 0x59, 0x47, 0x4E, 0x6B, 0xC0, 0x5D, + 0x99, 0xB2, 0x96, 0x4F, 0xA0, 0x90, 0xC3, 0xA2, + 0x23, 0x3B, 0xA1, 0x86, 0x51, 0x5B, 0xE7, 0xED, + 0x1F, 0x61, 0x29, 0x70, 0xCE, 0xE2, 0xD7, 0xAF, + 0xB8, 0x1B, 0xDD, 0x76, 0x21, 0x70, 0x48, 0x1C, + 0xD0, 0x06, 0x91, 0x27, 0xD5, 0xB0, 0x5A, 0xA9, + 0x93, 0xB4, 0xEA, 0x98, 0x8D, 0x8F, 0xDD, 0xC1, + 0x86, 0xFF, 0xB7, 0xDC, 0x90, 0xA6, 0xC0, 0x8F, + 0x4D, 0xF4, 0x35, 0xC9, 0x34, 0x02, 0x84, 0x92, + 0x36, 0xC3, 0xFA, 0xB4, 0xD2, 0x7C, 0x70, 0x26, + 0xC1, 0xD4, 0xDC, 0xB2, 0x60, 0x26, 0x46, 0xDE, + 0xC9, 0x75, 0x1E, 0x76, 0x3D, 0xBA, 0x37, 0xBD, + 0xF8, 0xFF, 0x94, 0x06, 0xAD, 0x9E, 0x53, 0x0E, + 0xE5, 0xDB, 0x38, 0x2F, 0x41, 0x30, 0x01, 0xAE, + 0xB0, 0x6A, 0x53, 0xED, 0x90, 0x27, 0xD8, 0x31, + 0x17, 0x97, 0x27, 0xB0, 0x86, 0x5A, 0x89, 0x18, + 0xDA, 0x3E, 0xDB, 0xEB, 0xCF, 0x9B, 0x14, 0xED, + 0x44, 0xCE, 0x6C, 0xBA, 0xCE, 0xD4, 0xBB, 0x1B, + 0xDB, 0x7F, 0x14, 0x47, 0xE6, 0xCC, 0x25, 0x4B, + 0x33, 0x20, 0x51, 0x51, 0x2B, 0xD7, 0xAF, 0x42, + 0x6F, 0xB8, 0xF4, 0x01, 0x37, 0x8C, 0xD2, 0xBF, + 0x59, 0x83, 0xCA, 0x01, 0xC6, 0x4B, 0x92, 0xEC, + 0xF0, 0x32, 0xEA, 0x15, 0xD1, 0x72, 0x1D, 0x03, + 0xF4, 0x82, 0xD7, 0xCE, 0x6E, 0x74, 0xFE, 0xF6, + 0xD5, 0x5E, 0x70, 0x2F, 0x46, 0x98, 0x0C, 0x82, + 0xB5, 0xA8, 0x40, 0x31, 0x90, 0x0B, 0x1C, 0x9E, + 0x59, 0xE7, 0xC9, 0x7F, 0xBE, 0xC7, 0xE8, 0xF3, + 0x23, 0xA9, 0x7A, 0x7E, 0x36, 0xCC, 0x88, 0xBE, + 0x0F, 0x1D, 0x45, 0xB7, 0xFF, 0x58, 0x5A, 0xC5, + 0x4B, 0xD4, 0x07, 0xB2, 0x2B, 0x41, 0x54, 0xAA, + 0xCC, 0x8F, 0x6D, 0x7E, 0xBF, 0x48, 0xE1, 0xD8, + 0x14, 0xCC, 0x5E, 0xD2, 0x0F, 0x80, 0x37, 0xE0, + 0xA7, 0x97, 0x15, 0xEE, 0xF2, 0x9B, 0xE3, 0x28, + 0x06, 0xA1, 0xD5, 0x8B, 0xB7, 0xC5, 0xDA, 0x76, + 0xF5, 0x50, 0xAA, 0x3D, 0x8A, 0x1F, 0xBF, 0xF0, + 0xEB, 0x19, 0xCC, 0xB1, 0xA3, 0x13, 0xD5, 0x5C, + 0xDA, 0x56, 0xC9, 0xEC, 0x2E, 0xF2, 0x96, 0x32, + 0x38, 0x7F, 0xE8, 0xD7, 0x6E, 0x3C, 0x04, 0x68, + 0x04, 0x3E, 0x8F, 0x66, 0x3F, 0x48, 0x60, 0xEE, + 0x12, 0xBF, 0x2D, 0x5B, 0x0B, 0x74, 0x74, 0xD6, + 0xE6, 0x94, 0xF9, 0x1E, 0x6D, 0xBE, 0x11, 0x59, + 0x74, 0xA3, 0x92, 0x6F, 0x12, 0xFE, 0xE5, 0xE4, + 0x38, 0x77, 0x7C, 0xB6, 0xA9, 0x32, 0xDF, 0x8C, + 0xD8, 0xBE, 0xC4, 0xD0, 0x73, 0xB9, 0x31, 0xBA, + 0x3B, 0xC8, 0x32, 0xB6, 0x8D, 0x9D, 0xD3, 0x00, + 0x74, 0x1F, 0xA7, 0xBF, 0x8A, 0xFC, 0x47, 0xED, + 0x25, 0x76, 0xF6, 0x93, 0x6B, 0xA4, 0x24, 0x66, + 0x3A, 0xAB, 0x63, 0x9C, 0x5A, 0xE4, 0xF5, 0x68, + 0x34, 0x23, 0xB4, 0x74, 0x2B, 0xF1, 0xC9, 0x78, + 0x23, 0x8F, 0x16, 0xCB, 0xE3, 0x9D, 0x65, 0x2D, + 0xE3, 0xFD, 0xB8, 0xBE, 0xFC, 0x84, 0x8A, 0xD9, + 0x22, 0x22, 0x2E, 0x04, 0xA4, 0x03, 0x7C, 0x07, + 0x13, 0xEB, 0x57, 0xA8, 0x1A, 0x23, 0xF0, 0xC7, + 0x34, 0x73, 0xFC, 0x64, 0x6C, 0xEA, 0x30, 0x6B, + 0x4B, 0xCB, 0xC8, 0x86, 0x2F, 0x83, 0x85, 0xDD, + 0xFA, 0x9D, 0x4B, 0x7F, 0xA2, 0xC0, 0x87, 0xE8, + 0x79, 0x68, 0x33, 0x03, 0xED, 0x5B, 0xDD, 0x3A, + 0x06, 0x2B, 0x3C, 0xF5, 0xB3, 0xA2, 0x78, 0xA6, + 0x6D, 0x2A, 0x13, 0xF8, 0x3F, 0x44, 0xF8, 0x2D, + 0xDF, 0x31, 0x0E, 0xE0, 0x74, 0xAB, 0x6A, 0x36, + 0x45, 0x97, 0xE8, 0x99, 0xA0, 0x25, 0x5D, 0xC1, + 0x64, 0xF3, 0x1C, 0xC5, 0x08, 0x46, 0x85, 0x1D, + 0xF9, 0xAB, 0x48, 0x19, 0x5D, 0xED, 0x7E, 0xA1, + 0xB1, 0xD5, 0x10, 0xBD, 0x7E, 0xE7, 0x4D, 0x73, + 0xFA, 0xF3, 0x6B, 0xC3, 0x1E, 0xCF, 0xA2, 0x68, + 0x35, 0x90, 0x46, 0xF4, 0xEB, 0x87, 0x9F, 0x92, + 0x40, 0x09, 0x43, 0x8B, 0x48, 0x1C, 0x6C, 0xD7, + 0x88, 0x9A, 0x00, 0x2E, 0xD5, 0xEE, 0x38, 0x2B, + 0xC9, 0x19, 0x0D, 0xA6, 0xFC, 0x02, 0x6E, 0x47, + 0x95, 0x58, 0xE4, 0x47, 0x56, 0x77, 0xE9, 0xAA, + 0x9E, 0x30, 0x50, 0xE2, 0x76, 0x56, 0x94, 0xDF, + 0xC8, 0x1F, 0x56, 0xE8, 0x80, 0xB9, 0x6E, 0x71, + 0x60, 0xC9, 0x80, 0xDD, 0x98, 0xED, 0xD3, 0xDF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + }; + return BN_bin2bn(RFC3526_PRIME_8192, sizeof(RFC3526_PRIME_8192), bn); +} diff --git a/libs/openssl/crypto/bn/bn_ctx.c b/libs/openssl/crypto/bn/bn_ctx.c new file mode 100644 index 00000000..526c6a04 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_ctx.c @@ -0,0 +1,448 @@ +/* crypto/bn/bn_ctx.c */ +/* Written by Ulf Moeller for the OpenSSL project. */ +/* ==================================================================== + * Copyright (c) 1998-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#if !defined(BN_CTX_DEBUG) && !defined(BN_DEBUG) +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +#include +#include + +#include "cryptlib.h" +#include "bn_lcl.h" + +/*- + * TODO list + * + * 1. Check a bunch of "(words+1)" type hacks in various bignum functions and + * check they can be safely removed. + * - Check +1 and other ugliness in BN_from_montgomery() + * + * 2. Consider allowing a BN_new_ex() that, at least, lets you specify an + * appropriate 'block' size that will be honoured by bn_expand_internal() to + * prevent piddly little reallocations. OTOH, profiling bignum expansions in + * BN_CTX doesn't show this to be a big issue. + */ + +/* How many bignums are in each "pool item"; */ +#define BN_CTX_POOL_SIZE 16 +/* The stack frame info is resizing, set a first-time expansion size; */ +#define BN_CTX_START_FRAMES 32 + +/***********/ +/* BN_POOL */ +/***********/ + +/* A bundle of bignums that can be linked with other bundles */ +typedef struct bignum_pool_item { + /* The bignum values */ + BIGNUM vals[BN_CTX_POOL_SIZE]; + /* Linked-list admin */ + struct bignum_pool_item *prev, *next; +} BN_POOL_ITEM; +/* A linked-list of bignums grouped in bundles */ +typedef struct bignum_pool { + /* Linked-list admin */ + BN_POOL_ITEM *head, *current, *tail; + /* Stack depth and allocation size */ + unsigned used, size; +} BN_POOL; +static void BN_POOL_init(BN_POOL *); +static void BN_POOL_finish(BN_POOL *); +#ifndef OPENSSL_NO_DEPRECATED +static void BN_POOL_reset(BN_POOL *); +#endif +static BIGNUM *BN_POOL_get(BN_POOL *); +static void BN_POOL_release(BN_POOL *, unsigned int); + +/************/ +/* BN_STACK */ +/************/ + +/* A wrapper to manage the "stack frames" */ +typedef struct bignum_ctx_stack { + /* Array of indexes into the bignum stack */ + unsigned int *indexes; + /* Number of stack frames, and the size of the allocated array */ + unsigned int depth, size; +} BN_STACK; +static void BN_STACK_init(BN_STACK *); +static void BN_STACK_finish(BN_STACK *); +#ifndef OPENSSL_NO_DEPRECATED +static void BN_STACK_reset(BN_STACK *); +#endif +static int BN_STACK_push(BN_STACK *, unsigned int); +static unsigned int BN_STACK_pop(BN_STACK *); + +/**********/ +/* BN_CTX */ +/**********/ + +/* The opaque BN_CTX type */ +struct bignum_ctx { + /* The bignum bundles */ + BN_POOL pool; + /* The "stack frames", if you will */ + BN_STACK stack; + /* The number of bignums currently assigned */ + unsigned int used; + /* Depth of stack overflow */ + int err_stack; + /* Block "gets" until an "end" (compatibility behaviour) */ + int too_many; +}; + +/* Enable this to find BN_CTX bugs */ +#ifdef BN_CTX_DEBUG +static const char *ctxdbg_cur = NULL; +static void ctxdbg(BN_CTX *ctx) +{ + unsigned int bnidx = 0, fpidx = 0; + BN_POOL_ITEM *item = ctx->pool.head; + BN_STACK *stack = &ctx->stack; + fprintf(stderr, "(%16p): ", ctx); + while (bnidx < ctx->used) { + fprintf(stderr, "%03x ", item->vals[bnidx++ % BN_CTX_POOL_SIZE].dmax); + if (!(bnidx % BN_CTX_POOL_SIZE)) + item = item->next; + } + fprintf(stderr, "\n"); + bnidx = 0; + fprintf(stderr, " : "); + while (fpidx < stack->depth) { + while (bnidx++ < stack->indexes[fpidx]) + fprintf(stderr, " "); + fprintf(stderr, "^^^ "); + bnidx++; + fpidx++; + } + fprintf(stderr, "\n"); +} + +# define CTXDBG_ENTRY(str, ctx) do { \ + ctxdbg_cur = (str); \ + fprintf(stderr,"Starting %s\n", ctxdbg_cur); \ + ctxdbg(ctx); \ + } while(0) +# define CTXDBG_EXIT(ctx) do { \ + fprintf(stderr,"Ending %s\n", ctxdbg_cur); \ + ctxdbg(ctx); \ + } while(0) +# define CTXDBG_RET(ctx,ret) +#else +# define CTXDBG_ENTRY(str, ctx) +# define CTXDBG_EXIT(ctx) +# define CTXDBG_RET(ctx,ret) +#endif + +/* + * This function is an evil legacy and should not be used. This + * implementation is WYSIWYG, though I've done my best. + */ +#ifndef OPENSSL_NO_DEPRECATED +void BN_CTX_init(BN_CTX *ctx) +{ + /* + * Assume the caller obtained the context via BN_CTX_new() and so is + * trying to reset it for use. Nothing else makes sense, least of all + * binary compatibility from a time when they could declare a static + * variable. + */ + BN_POOL_reset(&ctx->pool); + BN_STACK_reset(&ctx->stack); + ctx->used = 0; + ctx->err_stack = 0; + ctx->too_many = 0; +} +#endif + +BN_CTX *BN_CTX_new(void) +{ + BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX)); + if (!ret) { + BNerr(BN_F_BN_CTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + /* Initialise the structure */ + BN_POOL_init(&ret->pool); + BN_STACK_init(&ret->stack); + ret->used = 0; + ret->err_stack = 0; + ret->too_many = 0; + return ret; +} + +void BN_CTX_free(BN_CTX *ctx) +{ + if (ctx == NULL) + return; +#ifdef BN_CTX_DEBUG + { + BN_POOL_ITEM *pool = ctx->pool.head; + fprintf(stderr, "BN_CTX_free, stack-size=%d, pool-bignums=%d\n", + ctx->stack.size, ctx->pool.size); + fprintf(stderr, "dmaxs: "); + while (pool) { + unsigned loop = 0; + while (loop < BN_CTX_POOL_SIZE) + fprintf(stderr, "%02x ", pool->vals[loop++].dmax); + pool = pool->next; + } + fprintf(stderr, "\n"); + } +#endif + BN_STACK_finish(&ctx->stack); + BN_POOL_finish(&ctx->pool); + OPENSSL_free(ctx); +} + +void BN_CTX_start(BN_CTX *ctx) +{ + CTXDBG_ENTRY("BN_CTX_start", ctx); + /* If we're already overflowing ... */ + if (ctx->err_stack || ctx->too_many) + ctx->err_stack++; + /* (Try to) get a new frame pointer */ + else if (!BN_STACK_push(&ctx->stack, ctx->used)) { + BNerr(BN_F_BN_CTX_START, BN_R_TOO_MANY_TEMPORARY_VARIABLES); + ctx->err_stack++; + } + CTXDBG_EXIT(ctx); +} + +void BN_CTX_end(BN_CTX *ctx) +{ + CTXDBG_ENTRY("BN_CTX_end", ctx); + if (ctx->err_stack) + ctx->err_stack--; + else { + unsigned int fp = BN_STACK_pop(&ctx->stack); + /* Does this stack frame have anything to release? */ + if (fp < ctx->used) + BN_POOL_release(&ctx->pool, ctx->used - fp); + ctx->used = fp; + /* Unjam "too_many" in case "get" had failed */ + ctx->too_many = 0; + } + CTXDBG_EXIT(ctx); +} + +BIGNUM *BN_CTX_get(BN_CTX *ctx) +{ + BIGNUM *ret; + CTXDBG_ENTRY("BN_CTX_get", ctx); + if (ctx->err_stack || ctx->too_many) + return NULL; + if ((ret = BN_POOL_get(&ctx->pool)) == NULL) { + /* + * Setting too_many prevents repeated "get" attempts from cluttering + * the error stack. + */ + ctx->too_many = 1; + BNerr(BN_F_BN_CTX_GET, BN_R_TOO_MANY_TEMPORARY_VARIABLES); + return NULL; + } + /* OK, make sure the returned bignum is "zero" */ + BN_zero(ret); + ctx->used++; + CTXDBG_RET(ctx, ret); + return ret; +} + +/************/ +/* BN_STACK */ +/************/ + +static void BN_STACK_init(BN_STACK *st) +{ + st->indexes = NULL; + st->depth = st->size = 0; +} + +static void BN_STACK_finish(BN_STACK *st) +{ + if (st->size) + OPENSSL_free(st->indexes); +} + +#ifndef OPENSSL_NO_DEPRECATED +static void BN_STACK_reset(BN_STACK *st) +{ + st->depth = 0; +} +#endif + +static int BN_STACK_push(BN_STACK *st, unsigned int idx) +{ + if (st->depth == st->size) + /* Need to expand */ + { + unsigned int newsize = (st->size ? + (st->size * 3 / 2) : BN_CTX_START_FRAMES); + unsigned int *newitems = OPENSSL_malloc(newsize * + sizeof(unsigned int)); + if (!newitems) + return 0; + if (st->depth) + memcpy(newitems, st->indexes, st->depth * sizeof(unsigned int)); + if (st->size) + OPENSSL_free(st->indexes); + st->indexes = newitems; + st->size = newsize; + } + st->indexes[(st->depth)++] = idx; + return 1; +} + +static unsigned int BN_STACK_pop(BN_STACK *st) +{ + return st->indexes[--(st->depth)]; +} + +/***********/ +/* BN_POOL */ +/***********/ + +static void BN_POOL_init(BN_POOL *p) +{ + p->head = p->current = p->tail = NULL; + p->used = p->size = 0; +} + +static void BN_POOL_finish(BN_POOL *p) +{ + while (p->head) { + unsigned int loop = 0; + BIGNUM *bn = p->head->vals; + while (loop++ < BN_CTX_POOL_SIZE) { + if (bn->d) + BN_clear_free(bn); + bn++; + } + p->current = p->head->next; + OPENSSL_free(p->head); + p->head = p->current; + } +} + +#ifndef OPENSSL_NO_DEPRECATED +static void BN_POOL_reset(BN_POOL *p) +{ + BN_POOL_ITEM *item = p->head; + while (item) { + unsigned int loop = 0; + BIGNUM *bn = item->vals; + while (loop++ < BN_CTX_POOL_SIZE) { + if (bn->d) + BN_clear(bn); + bn++; + } + item = item->next; + } + p->current = p->head; + p->used = 0; +} +#endif + +static BIGNUM *BN_POOL_get(BN_POOL *p) +{ + if (p->used == p->size) { + BIGNUM *bn; + unsigned int loop = 0; + BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(BN_POOL_ITEM)); + if (!item) + return NULL; + /* Initialise the structure */ + bn = item->vals; + while (loop++ < BN_CTX_POOL_SIZE) + BN_init(bn++); + item->prev = p->tail; + item->next = NULL; + /* Link it in */ + if (!p->head) + p->head = p->current = p->tail = item; + else { + p->tail->next = item; + p->tail = item; + p->current = item; + } + p->size += BN_CTX_POOL_SIZE; + p->used++; + /* Return the first bignum from the new pool */ + return item->vals; + } + if (!p->used) + p->current = p->head; + else if ((p->used % BN_CTX_POOL_SIZE) == 0) + p->current = p->current->next; + return p->current->vals + ((p->used++) % BN_CTX_POOL_SIZE); +} + +static void BN_POOL_release(BN_POOL *p, unsigned int num) +{ + unsigned int offset = (p->used - 1) % BN_CTX_POOL_SIZE; + p->used -= num; + while (num--) { + bn_check_top(p->current->vals + offset); + if (!offset) { + offset = BN_CTX_POOL_SIZE - 1; + p->current = p->current->prev; + } else + offset--; + } +} diff --git a/libs/openssl/crypto/bn/bn_depr.c b/libs/openssl/crypto/bn/bn_depr.c new file mode 100644 index 00000000..34895f59 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_depr.c @@ -0,0 +1,115 @@ +/* crypto/bn/bn_depr.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Support for deprecated functions goes here - static linkage will only + * slurp this code if applications are using them directly. + */ + +#include +#include +#include "cryptlib.h" +#include "bn_lcl.h" +#include + +static void *dummy = &dummy; + +#ifndef OPENSSL_NO_DEPRECATED +BIGNUM *BN_generate_prime(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, + void (*callback) (int, int, void *), void *cb_arg) +{ + BN_GENCB cb; + BIGNUM *rnd = NULL; + int found = 0; + + BN_GENCB_set_old(&cb, callback, cb_arg); + + if (ret == NULL) { + if ((rnd = BN_new()) == NULL) + goto err; + } else + rnd = ret; + if (!BN_generate_prime_ex(rnd, bits, safe, add, rem, &cb)) + goto err; + + /* we have a prime :-) */ + found = 1; + err: + if (!found && (ret == NULL) && (rnd != NULL)) + BN_free(rnd); + return (found ? rnd : NULL); +} + +int BN_is_prime(const BIGNUM *a, int checks, + void (*callback) (int, int, void *), BN_CTX *ctx_passed, + void *cb_arg) +{ + BN_GENCB cb; + BN_GENCB_set_old(&cb, callback, cb_arg); + return BN_is_prime_ex(a, checks, ctx_passed, &cb); +} + +int BN_is_prime_fasttest(const BIGNUM *a, int checks, + void (*callback) (int, int, void *), + BN_CTX *ctx_passed, void *cb_arg, + int do_trial_division) +{ + BN_GENCB cb; + BN_GENCB_set_old(&cb, callback, cb_arg); + return BN_is_prime_fasttest_ex(a, checks, ctx_passed, + do_trial_division, &cb); +} +#endif diff --git a/libs/openssl/crypto/bn/bn_div.c b/libs/openssl/crypto/bn/bn_div.c new file mode 100644 index 00000000..72e6ce3f --- /dev/null +++ b/libs/openssl/crypto/bn/bn_div.c @@ -0,0 +1,477 @@ +/* crypto/bn/bn_div.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +/* The old slow way */ +#if 0 +int BN_div(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, + BN_CTX *ctx) +{ + int i, nm, nd; + int ret = 0; + BIGNUM *D; + + bn_check_top(m); + bn_check_top(d); + if (BN_is_zero(d)) { + BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO); + return (0); + } + + if (BN_ucmp(m, d) < 0) { + if (rem != NULL) { + if (BN_copy(rem, m) == NULL) + return (0); + } + if (dv != NULL) + BN_zero(dv); + return (1); + } + + BN_CTX_start(ctx); + D = BN_CTX_get(ctx); + if (dv == NULL) + dv = BN_CTX_get(ctx); + if (rem == NULL) + rem = BN_CTX_get(ctx); + if (D == NULL || dv == NULL || rem == NULL) + goto end; + + nd = BN_num_bits(d); + nm = BN_num_bits(m); + if (BN_copy(D, d) == NULL) + goto end; + if (BN_copy(rem, m) == NULL) + goto end; + + /* + * The next 2 are needed so we can do a dv->d[0]|=1 later since + * BN_lshift1 will only work once there is a value :-) + */ + BN_zero(dv); + if (bn_wexpand(dv, 1) == NULL) + goto end; + dv->top = 1; + + if (!BN_lshift(D, D, nm - nd)) + goto end; + for (i = nm - nd; i >= 0; i--) { + if (!BN_lshift1(dv, dv)) + goto end; + if (BN_ucmp(rem, D) >= 0) { + dv->d[0] |= 1; + if (!BN_usub(rem, rem, D)) + goto end; + } +/* CAN IMPROVE (and have now :=) */ + if (!BN_rshift1(D, D)) + goto end; + } + rem->neg = BN_is_zero(rem) ? 0 : m->neg; + dv->neg = m->neg ^ d->neg; + ret = 1; + end: + BN_CTX_end(ctx); + return (ret); +} + +#else + +# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) \ + && !defined(PEDANTIC) && !defined(BN_DIV3W) +# if defined(__GNUC__) && __GNUC__>=2 +# if defined(__i386) || defined (__i386__) + /*- + * There were two reasons for implementing this template: + * - GNU C generates a call to a function (__udivdi3 to be exact) + * in reply to ((((BN_ULLONG)n0)< + */ +# undef bn_div_words +# define bn_div_words(n0,n1,d0) \ + ({ asm volatile ( \ + "divl %4" \ + : "=a"(q), "=d"(rem) \ + : "a"(n1), "d"(n0), "g"(d0) \ + : "cc"); \ + q; \ + }) +# define REMAINDER_IS_ALREADY_CALCULATED +# elif defined(__x86_64) && defined(SIXTY_FOUR_BIT_LONG) + /* + * Same story here, but it's 128-bit by 64-bit division. Wow! + * + */ +# undef bn_div_words +# define bn_div_words(n0,n1,d0) \ + ({ asm volatile ( \ + "divq %4" \ + : "=a"(q), "=d"(rem) \ + : "a"(n1), "d"(n0), "g"(d0) \ + : "cc"); \ + q; \ + }) +# define REMAINDER_IS_ALREADY_CALCULATED +# endif /* __ */ +# endif /* __GNUC__ */ +# endif /* OPENSSL_NO_ASM */ + +/*- + * BN_div computes dv := num / divisor, rounding towards + * zero, and sets up rm such that dv*divisor + rm = num holds. + * Thus: + * dv->neg == num->neg ^ divisor->neg (unless the result is zero) + * rm->neg == num->neg (unless the remainder is zero) + * If 'dv' or 'rm' is NULL, the respective value is not returned. + */ +int BN_div(BIGNUM *dv, BIGNUM *rm, const BIGNUM *num, const BIGNUM *divisor, + BN_CTX *ctx) +{ + int norm_shift, i, loop; + BIGNUM *tmp, wnum, *snum, *sdiv, *res; + BN_ULONG *resp, *wnump; + BN_ULONG d0, d1; + int num_n, div_n; + int no_branch = 0; + + /* + * Invalid zero-padding would have particularly bad consequences so don't + * just rely on bn_check_top() here (bn_check_top() works only for + * BN_DEBUG builds) + */ + if ((num->top > 0 && num->d[num->top - 1] == 0) || + (divisor->top > 0 && divisor->d[divisor->top - 1] == 0)) { + BNerr(BN_F_BN_DIV, BN_R_NOT_INITIALIZED); + return 0; + } + + bn_check_top(num); + bn_check_top(divisor); + + if ((BN_get_flags(num, BN_FLG_CONSTTIME) != 0) + || (BN_get_flags(divisor, BN_FLG_CONSTTIME) != 0)) { + no_branch = 1; + } + + bn_check_top(dv); + bn_check_top(rm); + /*- bn_check_top(num); *//* + * 'num' has been checked already + */ + /*- bn_check_top(divisor); *//* + * 'divisor' has been checked already + */ + + if (BN_is_zero(divisor)) { + BNerr(BN_F_BN_DIV, BN_R_DIV_BY_ZERO); + return (0); + } + + if (!no_branch && BN_ucmp(num, divisor) < 0) { + if (rm != NULL) { + if (BN_copy(rm, num) == NULL) + return (0); + } + if (dv != NULL) + BN_zero(dv); + return (1); + } + + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + snum = BN_CTX_get(ctx); + sdiv = BN_CTX_get(ctx); + if (dv == NULL) + res = BN_CTX_get(ctx); + else + res = dv; + if (sdiv == NULL || res == NULL || tmp == NULL || snum == NULL) + goto err; + + /* First we normalise the numbers */ + norm_shift = BN_BITS2 - ((BN_num_bits(divisor)) % BN_BITS2); + if (!(BN_lshift(sdiv, divisor, norm_shift))) + goto err; + sdiv->neg = 0; + norm_shift += BN_BITS2; + if (!(BN_lshift(snum, num, norm_shift))) + goto err; + snum->neg = 0; + + if (no_branch) { + /* + * Since we don't know whether snum is larger than sdiv, we pad snum + * with enough zeroes without changing its value. + */ + if (snum->top <= sdiv->top + 1) { + if (bn_wexpand(snum, sdiv->top + 2) == NULL) + goto err; + for (i = snum->top; i < sdiv->top + 2; i++) + snum->d[i] = 0; + snum->top = sdiv->top + 2; + } else { + if (bn_wexpand(snum, snum->top + 1) == NULL) + goto err; + snum->d[snum->top] = 0; + snum->top++; + } + } + + div_n = sdiv->top; + num_n = snum->top; + loop = num_n - div_n; + /* + * Lets setup a 'window' into snum This is the part that corresponds to + * the current 'area' being divided + */ + wnum.neg = 0; + wnum.d = &(snum->d[loop]); + wnum.top = div_n; + /* + * only needed when BN_ucmp messes up the values between top and max + */ + wnum.dmax = snum->dmax - loop; /* so we don't step out of bounds */ + + /* Get the top 2 words of sdiv */ + /* div_n=sdiv->top; */ + d0 = sdiv->d[div_n - 1]; + d1 = (div_n == 1) ? 0 : sdiv->d[div_n - 2]; + + /* pointer to the 'top' of snum */ + wnump = &(snum->d[num_n - 1]); + + /* Setup to 'res' */ + res->neg = (num->neg ^ divisor->neg); + if (!bn_wexpand(res, (loop + 1))) + goto err; + res->top = loop - no_branch; + resp = &(res->d[loop - 1]); + + /* space for temp */ + if (!bn_wexpand(tmp, (div_n + 1))) + goto err; + + if (!no_branch) { + if (BN_ucmp(&wnum, sdiv) >= 0) { + /* + * If BN_DEBUG_RAND is defined BN_ucmp changes (via bn_pollute) + * the const bignum arguments => clean the values between top and + * max again + */ + bn_clear_top2max(&wnum); + bn_sub_words(wnum.d, wnum.d, sdiv->d, div_n); + *resp = 1; + } else + res->top--; + } + + /* + * if res->top == 0 then clear the neg value otherwise decrease the resp + * pointer + */ + if (res->top == 0) + res->neg = 0; + else + resp--; + + for (i = 0; i < loop - 1; i++, wnump--, resp--) { + BN_ULONG q, l0; + /* + * the first part of the loop uses the top two words of snum and sdiv + * to calculate a BN_ULONG q such that | wnum - sdiv * q | < sdiv + */ +# if defined(BN_DIV3W) && !defined(OPENSSL_NO_ASM) + BN_ULONG bn_div_3_words(BN_ULONG *, BN_ULONG, BN_ULONG); + q = bn_div_3_words(wnump, d1, d0); +# else + BN_ULONG n0, n1, rem = 0; + + n0 = wnump[0]; + n1 = wnump[-1]; + if (n0 == d0) + q = BN_MASK2; + else { /* n0 < d0 */ + +# ifdef BN_LLONG + BN_ULLONG t2; + +# if defined(BN_LLONG) && defined(BN_DIV2W) && !defined(bn_div_words) + q = (BN_ULONG)(((((BN_ULLONG) n0) << BN_BITS2) | n1) / d0); +# else + q = bn_div_words(n0, n1, d0); +# ifdef BN_DEBUG_LEVITTE + fprintf(stderr, "DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\ +X) -> 0x%08X\n", n0, n1, d0, q); +# endif +# endif + +# ifndef REMAINDER_IS_ALREADY_CALCULATED + /* + * rem doesn't have to be BN_ULLONG. The least we + * know it's less that d0, isn't it? + */ + rem = (n1 - q * d0) & BN_MASK2; +# endif + t2 = (BN_ULLONG) d1 *q; + + for (;;) { + if (t2 <= ((((BN_ULLONG) rem) << BN_BITS2) | wnump[-2])) + break; + q--; + rem += d0; + if (rem < d0) + break; /* don't let rem overflow */ + t2 -= d1; + } +# else /* !BN_LLONG */ + BN_ULONG t2l, t2h; + + q = bn_div_words(n0, n1, d0); +# ifdef BN_DEBUG_LEVITTE + fprintf(stderr, "DEBUG: bn_div_words(0x%08X,0x%08X,0x%08\ +X) -> 0x%08X\n", n0, n1, d0, q); +# endif +# ifndef REMAINDER_IS_ALREADY_CALCULATED + rem = (n1 - q * d0) & BN_MASK2; +# endif + +# if defined(BN_UMULT_LOHI) + BN_UMULT_LOHI(t2l, t2h, d1, q); +# elif defined(BN_UMULT_HIGH) + t2l = d1 * q; + t2h = BN_UMULT_HIGH(d1, q); +# else + { + BN_ULONG ql, qh; + t2l = LBITS(d1); + t2h = HBITS(d1); + ql = LBITS(q); + qh = HBITS(q); + mul64(t2l, t2h, ql, qh); /* t2=(BN_ULLONG)d1*q; */ + } +# endif + + for (;;) { + if ((t2h < rem) || ((t2h == rem) && (t2l <= wnump[-2]))) + break; + q--; + rem += d0; + if (rem < d0) + break; /* don't let rem overflow */ + if (t2l < d1) + t2h--; + t2l -= d1; + } +# endif /* !BN_LLONG */ + } +# endif /* !BN_DIV3W */ + + l0 = bn_mul_words(tmp->d, sdiv->d, div_n, q); + tmp->d[div_n] = l0; + wnum.d--; + /* + * ingore top values of the bignums just sub the two BN_ULONG arrays + * with bn_sub_words + */ + if (bn_sub_words(wnum.d, wnum.d, tmp->d, div_n + 1)) { + /* + * Note: As we have considered only the leading two BN_ULONGs in + * the calculation of q, sdiv * q might be greater than wnum (but + * then (q-1) * sdiv is less or equal than wnum) + */ + q--; + if (bn_add_words(wnum.d, wnum.d, sdiv->d, div_n)) + /* + * we can't have an overflow here (assuming that q != 0, but + * if q == 0 then tmp is zero anyway) + */ + (*wnump)++; + } + /* store part of the result */ + *resp = q; + } + bn_correct_top(snum); + if (rm != NULL) { + /* + * Keep a copy of the neg flag in num because if rm==num BN_rshift() + * will overwrite it. + */ + int neg = num->neg; + BN_rshift(rm, snum, norm_shift); + if (!BN_is_zero(rm)) + rm->neg = neg; + bn_check_top(rm); + } + if (no_branch) + bn_correct_top(res); + BN_CTX_end(ctx); + return (1); + err: + bn_check_top(rm); + BN_CTX_end(ctx); + return (0); +} +#endif diff --git a/libs/openssl/crypto/bn/bn_err.c b/libs/openssl/crypto/bn/bn_err.c new file mode 100644 index 00000000..e7a70382 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_err.c @@ -0,0 +1,154 @@ +/* crypto/bn/bn_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2015 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BN,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BN,0,reason) + +static ERR_STRING_DATA BN_str_functs[] = { + {ERR_FUNC(BN_F_BNRAND), "BNRAND"}, + {ERR_FUNC(BN_F_BN_BLINDING_CONVERT_EX), "BN_BLINDING_convert_ex"}, + {ERR_FUNC(BN_F_BN_BLINDING_CREATE_PARAM), "BN_BLINDING_create_param"}, + {ERR_FUNC(BN_F_BN_BLINDING_INVERT_EX), "BN_BLINDING_invert_ex"}, + {ERR_FUNC(BN_F_BN_BLINDING_NEW), "BN_BLINDING_new"}, + {ERR_FUNC(BN_F_BN_BLINDING_UPDATE), "BN_BLINDING_update"}, + {ERR_FUNC(BN_F_BN_BN2DEC), "BN_bn2dec"}, + {ERR_FUNC(BN_F_BN_BN2HEX), "BN_bn2hex"}, + {ERR_FUNC(BN_F_BN_CTX_GET), "BN_CTX_get"}, + {ERR_FUNC(BN_F_BN_CTX_NEW), "BN_CTX_new"}, + {ERR_FUNC(BN_F_BN_CTX_START), "BN_CTX_start"}, + {ERR_FUNC(BN_F_BN_DIV), "BN_div"}, + {ERR_FUNC(BN_F_BN_DIV_NO_BRANCH), "BN_div_no_branch"}, + {ERR_FUNC(BN_F_BN_DIV_RECP), "BN_div_recp"}, + {ERR_FUNC(BN_F_BN_EXP), "BN_exp"}, + {ERR_FUNC(BN_F_BN_EXPAND2), "bn_expand2"}, + {ERR_FUNC(BN_F_BN_EXPAND_INTERNAL), "BN_EXPAND_INTERNAL"}, + {ERR_FUNC(BN_F_BN_GF2M_MOD), "BN_GF2m_mod"}, + {ERR_FUNC(BN_F_BN_GF2M_MOD_EXP), "BN_GF2m_mod_exp"}, + {ERR_FUNC(BN_F_BN_GF2M_MOD_MUL), "BN_GF2m_mod_mul"}, + {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD), "BN_GF2m_mod_solve_quad"}, + {ERR_FUNC(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR), "BN_GF2m_mod_solve_quad_arr"}, + {ERR_FUNC(BN_F_BN_GF2M_MOD_SQR), "BN_GF2m_mod_sqr"}, + {ERR_FUNC(BN_F_BN_GF2M_MOD_SQRT), "BN_GF2m_mod_sqrt"}, + {ERR_FUNC(BN_F_BN_LSHIFT), "BN_lshift"}, + {ERR_FUNC(BN_F_BN_MOD_EXP2_MONT), "BN_mod_exp2_mont"}, + {ERR_FUNC(BN_F_BN_MOD_EXP_MONT), "BN_mod_exp_mont"}, + {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_CONSTTIME), "BN_mod_exp_mont_consttime"}, + {ERR_FUNC(BN_F_BN_MOD_EXP_MONT_WORD), "BN_mod_exp_mont_word"}, + {ERR_FUNC(BN_F_BN_MOD_EXP_RECP), "BN_mod_exp_recp"}, + {ERR_FUNC(BN_F_BN_MOD_EXP_SIMPLE), "BN_mod_exp_simple"}, + {ERR_FUNC(BN_F_BN_MOD_INVERSE), "BN_mod_inverse"}, + {ERR_FUNC(BN_F_BN_MOD_INVERSE_NO_BRANCH), "BN_mod_inverse_no_branch"}, + {ERR_FUNC(BN_F_BN_MOD_LSHIFT_QUICK), "BN_mod_lshift_quick"}, + {ERR_FUNC(BN_F_BN_MOD_MUL_RECIPROCAL), "BN_mod_mul_reciprocal"}, + {ERR_FUNC(BN_F_BN_MOD_SQRT), "BN_mod_sqrt"}, + {ERR_FUNC(BN_F_BN_MPI2BN), "BN_mpi2bn"}, + {ERR_FUNC(BN_F_BN_NEW), "BN_new"}, + {ERR_FUNC(BN_F_BN_RAND), "BN_rand"}, + {ERR_FUNC(BN_F_BN_RAND_RANGE), "BN_rand_range"}, + {ERR_FUNC(BN_F_BN_RSHIFT), "BN_rshift"}, + {ERR_FUNC(BN_F_BN_USUB), "BN_usub"}, + {0, NULL} +}; + +static ERR_STRING_DATA BN_str_reasons[] = { + {ERR_REASON(BN_R_ARG2_LT_ARG3), "arg2 lt arg3"}, + {ERR_REASON(BN_R_BAD_RECIPROCAL), "bad reciprocal"}, + {ERR_REASON(BN_R_BIGNUM_TOO_LONG), "bignum too long"}, + {ERR_REASON(BN_R_BITS_TOO_SMALL), "bits too small"}, + {ERR_REASON(BN_R_CALLED_WITH_EVEN_MODULUS), "called with even modulus"}, + {ERR_REASON(BN_R_DIV_BY_ZERO), "div by zero"}, + {ERR_REASON(BN_R_ENCODING_ERROR), "encoding error"}, + {ERR_REASON(BN_R_EXPAND_ON_STATIC_BIGNUM_DATA), + "expand on static bignum data"}, + {ERR_REASON(BN_R_INPUT_NOT_REDUCED), "input not reduced"}, + {ERR_REASON(BN_R_INVALID_LENGTH), "invalid length"}, + {ERR_REASON(BN_R_INVALID_RANGE), "invalid range"}, + {ERR_REASON(BN_R_INVALID_SHIFT), "invalid shift"}, + {ERR_REASON(BN_R_NOT_A_SQUARE), "not a square"}, + {ERR_REASON(BN_R_NOT_INITIALIZED), "not initialized"}, + {ERR_REASON(BN_R_NO_INVERSE), "no inverse"}, + {ERR_REASON(BN_R_NO_SOLUTION), "no solution"}, + {ERR_REASON(BN_R_P_IS_NOT_PRIME), "p is not prime"}, + {ERR_REASON(BN_R_TOO_MANY_ITERATIONS), "too many iterations"}, + {ERR_REASON(BN_R_TOO_MANY_TEMPORARY_VARIABLES), + "too many temporary variables"}, + {0, NULL} +}; + +#endif + +void ERR_load_BN_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(BN_str_functs[0].error) == NULL) { + ERR_load_strings(0, BN_str_functs); + ERR_load_strings(0, BN_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/bn/bn_exp.c b/libs/openssl/crypto/bn/bn_exp.c new file mode 100644 index 00000000..c095ac46 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_exp.c @@ -0,0 +1,1183 @@ +/* crypto/bn/bn_exp.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include "constant_time_locl.h" +#include "bn_lcl.h" + +#include +#ifdef _WIN32 +# include +# ifndef alloca +# define alloca _alloca +# endif +#elif defined(__GNUC__) +# ifndef alloca +# define alloca(s) __builtin_alloca((s)) +# endif +#endif + +/* maximum precomputation table size for *variable* sliding windows */ +#define TABLE_SIZE 32 + +/* this one works - simple but works */ +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) +{ + int i, bits, ret = 0; + BIGNUM *v, *rr; + + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ + BNerr(BN_F_BN_EXP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + BN_CTX_start(ctx); + if ((r == a) || (r == p)) + rr = BN_CTX_get(ctx); + else + rr = r; + v = BN_CTX_get(ctx); + if (rr == NULL || v == NULL) + goto err; + + if (BN_copy(v, a) == NULL) + goto err; + bits = BN_num_bits(p); + + if (BN_is_odd(p)) { + if (BN_copy(rr, a) == NULL) + goto err; + } else { + if (!BN_one(rr)) + goto err; + } + + for (i = 1; i < bits; i++) { + if (!BN_sqr(v, v, ctx)) + goto err; + if (BN_is_bit_set(p, i)) { + if (!BN_mul(rr, rr, v, ctx)) + goto err; + } + } + if (r != rr) + BN_copy(r, rr); + ret = 1; + err: + BN_CTX_end(ctx); + bn_check_top(r); + return (ret); +} + +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx) +{ + int ret; + + bn_check_top(a); + bn_check_top(p); + bn_check_top(m); + + /*- + * For even modulus m = 2^k*m_odd, it might make sense to compute + * a^p mod m_odd and a^p mod 2^k separately (with Montgomery + * exponentiation for the odd part), using appropriate exponent + * reductions, and combine the results using the CRT. + * + * For now, we use Montgomery only if the modulus is odd; otherwise, + * exponentiation using the reciprocal-based quick remaindering + * algorithm is used. + * + * (Timing obtained with expspeed.c [computations a^p mod m + * where a, p, m are of the same length: 256, 512, 1024, 2048, + * 4096, 8192 bits], compared to the running time of the + * standard algorithm: + * + * BN_mod_exp_mont 33 .. 40 % [AMD K6-2, Linux, debug configuration] + * 55 .. 77 % [UltraSparc processor, but + * debug-solaris-sparcv8-gcc conf.] + * + * BN_mod_exp_recp 50 .. 70 % [AMD K6-2, Linux, debug configuration] + * 62 .. 118 % [UltraSparc, debug-solaris-sparcv8-gcc] + * + * On the Sparc, BN_mod_exp_recp was faster than BN_mod_exp_mont + * at 2048 and more bits, but at 512 and 1024 bits, it was + * slower even than the standard algorithm! + * + * "Real" timings [linux-elf, solaris-sparcv9-gcc configurations] + * should be obtained when the new Montgomery reduction code + * has been integrated into OpenSSL.) + */ + +#define MONT_MUL_MOD +#define MONT_EXP_WORD +#define RECP_MUL_MOD + +#ifdef MONT_MUL_MOD + /* + * I have finally been able to take out this pre-condition of the top bit + * being set. It was caused by an error in BN_div with negatives. There + * was also another problem when for a^b%m a >= m. eay 07-May-97 + */ + /* if ((m->d[m->top-1]&BN_TBIT) && BN_is_odd(m)) */ + + if (BN_is_odd(m)) { +# ifdef MONT_EXP_WORD + if (a->top == 1 && !a->neg + && (BN_get_flags(p, BN_FLG_CONSTTIME) == 0)) { + BN_ULONG A = a->d[0]; + ret = BN_mod_exp_mont_word(r, A, p, m, ctx, NULL); + } else +# endif + ret = BN_mod_exp_mont(r, a, p, m, ctx, NULL); + } else +#endif +#ifdef RECP_MUL_MOD + { + ret = BN_mod_exp_recp(r, a, p, m, ctx); + } +#else + { + ret = BN_mod_exp_simple(r, a, p, m, ctx); + } +#endif + + bn_check_top(r); + return (ret); +} + +int BN_mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) +{ + int i, j, bits, ret = 0, wstart, wend, window, wvalue; + int start = 1; + BIGNUM *aa; + /* Table of variables obtained from 'ctx' */ + BIGNUM *val[TABLE_SIZE]; + BN_RECP_CTX recp; + + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ + BNerr(BN_F_BN_MOD_EXP_RECP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + bits = BN_num_bits(p); + if (bits == 0) { + /* x**0 mod 1 is still zero. */ + if (BN_is_one(m)) { + ret = 1; + BN_zero(r); + } else { + ret = BN_one(r); + } + return ret; + } + + BN_CTX_start(ctx); + aa = BN_CTX_get(ctx); + val[0] = BN_CTX_get(ctx); + if (!aa || !val[0]) + goto err; + + BN_RECP_CTX_init(&recp); + if (m->neg) { + /* ignore sign of 'm' */ + if (!BN_copy(aa, m)) + goto err; + aa->neg = 0; + if (BN_RECP_CTX_set(&recp, aa, ctx) <= 0) + goto err; + } else { + if (BN_RECP_CTX_set(&recp, m, ctx) <= 0) + goto err; + } + + if (!BN_nnmod(val[0], a, m, ctx)) + goto err; /* 1 */ + if (BN_is_zero(val[0])) { + BN_zero(r); + ret = 1; + goto err; + } + + window = BN_window_bits_for_exponent_size(bits); + if (window > 1) { + if (!BN_mod_mul_reciprocal(aa, val[0], val[0], &recp, ctx)) + goto err; /* 2 */ + j = 1 << (window - 1); + for (i = 1; i < j; i++) { + if (((val[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul_reciprocal(val[i], val[i - 1], aa, &recp, ctx)) + goto err; + } + } + + start = 1; /* This is used to avoid multiplication etc + * when there is only the value '1' in the + * buffer. */ + wvalue = 0; /* The 'value' of the window */ + wstart = bits - 1; /* The top bit of the window */ + wend = 0; /* The bottom bit of the window */ + + if (!BN_one(r)) + goto err; + + for (;;) { + if (BN_is_bit_set(p, wstart) == 0) { + if (!start) + if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) + goto err; + if (wstart == 0) + break; + wstart--; + continue; + } + /* + * We now have wstart on a 'set' bit, we now need to work out how bit + * a window to do. To do this we need to scan forward until the last + * set bit before the end of the window + */ + j = wstart; + wvalue = 1; + wend = 0; + for (i = 1; i < window; i++) { + if (wstart - i < 0) + break; + if (BN_is_bit_set(p, wstart - i)) { + wvalue <<= (i - wend); + wvalue |= 1; + wend = i; + } + } + + /* wend is the size of the current window */ + j = wend + 1; + /* add the 'bytes above' */ + if (!start) + for (i = 0; i < j; i++) { + if (!BN_mod_mul_reciprocal(r, r, r, &recp, ctx)) + goto err; + } + + /* wvalue will be an odd number < 2^window */ + if (!BN_mod_mul_reciprocal(r, r, val[wvalue >> 1], &recp, ctx)) + goto err; + + /* move the 'window' down further */ + wstart -= wend + 1; + wvalue = 0; + start = 0; + if (wstart < 0) + break; + } + ret = 1; + err: + BN_CTX_end(ctx); + BN_RECP_CTX_free(&recp); + bn_check_top(r); + return (ret); +} + +int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + int i, j, bits, ret = 0, wstart, wend, window, wvalue; + int start = 1; + BIGNUM *d, *r; + const BIGNUM *aa; + /* Table of variables obtained from 'ctx' */ + BIGNUM *val[TABLE_SIZE]; + BN_MONT_CTX *mont = NULL; + + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + return BN_mod_exp_mont_consttime(rr, a, p, m, ctx, in_mont); + } + + bn_check_top(a); + bn_check_top(p); + bn_check_top(m); + + if (!BN_is_odd(m)) { + BNerr(BN_F_BN_MOD_EXP_MONT, BN_R_CALLED_WITH_EVEN_MODULUS); + return (0); + } + bits = BN_num_bits(p); + if (bits == 0) { + /* x**0 mod 1 is still zero. */ + if (BN_is_one(m)) { + ret = 1; + BN_zero(rr); + } else { + ret = BN_one(rr); + } + return ret; + } + + BN_CTX_start(ctx); + d = BN_CTX_get(ctx); + r = BN_CTX_get(ctx); + val[0] = BN_CTX_get(ctx); + if (!d || !r || !val[0]) + goto err; + + /* + * If this is not done, things will break in the montgomery part + */ + + if (in_mont != NULL) + mont = in_mont; + else { + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, m, ctx)) + goto err; + } + + if (a->neg || BN_ucmp(a, m) >= 0) { + if (!BN_nnmod(val[0], a, m, ctx)) + goto err; + aa = val[0]; + } else + aa = a; + if (BN_is_zero(aa)) { + BN_zero(rr); + ret = 1; + goto err; + } + if (!BN_to_montgomery(val[0], aa, mont, ctx)) + goto err; /* 1 */ + + window = BN_window_bits_for_exponent_size(bits); + if (window > 1) { + if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx)) + goto err; /* 2 */ + j = 1 << (window - 1); + for (i = 1; i < j; i++) { + if (((val[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx)) + goto err; + } + } + + start = 1; /* This is used to avoid multiplication etc + * when there is only the value '1' in the + * buffer. */ + wvalue = 0; /* The 'value' of the window */ + wstart = bits - 1; /* The top bit of the window */ + wend = 0; /* The bottom bit of the window */ + + if (!BN_to_montgomery(r, BN_value_one(), mont, ctx)) + goto err; + for (;;) { + if (BN_is_bit_set(p, wstart) == 0) { + if (!start) { + if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) + goto err; + } + if (wstart == 0) + break; + wstart--; + continue; + } + /* + * We now have wstart on a 'set' bit, we now need to work out how bit + * a window to do. To do this we need to scan forward until the last + * set bit before the end of the window + */ + j = wstart; + wvalue = 1; + wend = 0; + for (i = 1; i < window; i++) { + if (wstart - i < 0) + break; + if (BN_is_bit_set(p, wstart - i)) { + wvalue <<= (i - wend); + wvalue |= 1; + wend = i; + } + } + + /* wend is the size of the current window */ + j = wend + 1; + /* add the 'bytes above' */ + if (!start) + for (i = 0; i < j; i++) { + if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) + goto err; + } + + /* wvalue will be an odd number < 2^window */ + if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx)) + goto err; + + /* move the 'window' down further */ + wstart -= wend + 1; + wvalue = 0; + start = 0; + if (wstart < 0) + break; + } + if (!BN_from_montgomery(rr, r, mont, ctx)) + goto err; + ret = 1; + err: + if ((in_mont == NULL) && (mont != NULL)) + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + bn_check_top(rr); + return (ret); +} + +/* + * BN_mod_exp_mont_consttime() stores the precomputed powers in a specific + * layout so that accessing any of these table values shows the same access + * pattern as far as cache lines are concerned. The following functions are + * used to transfer a BIGNUM from/to that table. + */ + +static int MOD_EXP_CTIME_COPY_TO_PREBUF(const BIGNUM *b, int top, + unsigned char *buf, int idx, + int window) +{ + int i, j; + int width = 1 << window; + BN_ULONG *table = (BN_ULONG *)buf; + + if (top > b->top) + top = b->top; /* this works because 'buf' is explicitly + * zeroed */ + for (i = 0, j = idx; i < top; i++, j += width) { + table[j] = b->d[i]; + } + + return 1; +} + +static int MOD_EXP_CTIME_COPY_FROM_PREBUF(BIGNUM *b, int top, + unsigned char *buf, int idx, + int window) +{ + int i, j; + int width = 1 << window; + volatile BN_ULONG *table = (volatile BN_ULONG *)buf; + + if (bn_wexpand(b, top) == NULL) + return 0; + + if (window <= 3) { + for (i = 0; i < top; i++, table += width) { + BN_ULONG acc = 0; + + for (j = 0; j < width; j++) { + acc |= table[j] & + ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1)); + } + + b->d[i] = acc; + } + } else { + int xstride = 1 << (window - 2); + BN_ULONG y0, y1, y2, y3; + + i = idx >> (window - 2); /* equivalent of idx / xstride */ + idx &= xstride - 1; /* equivalent of idx % xstride */ + + y0 = (BN_ULONG)0 - (constant_time_eq_int(i,0)&1); + y1 = (BN_ULONG)0 - (constant_time_eq_int(i,1)&1); + y2 = (BN_ULONG)0 - (constant_time_eq_int(i,2)&1); + y3 = (BN_ULONG)0 - (constant_time_eq_int(i,3)&1); + + for (i = 0; i < top; i++, table += width) { + BN_ULONG acc = 0; + + for (j = 0; j < xstride; j++) { + acc |= ( (table[j + 0 * xstride] & y0) | + (table[j + 1 * xstride] & y1) | + (table[j + 2 * xstride] & y2) | + (table[j + 3 * xstride] & y3) ) + & ((BN_ULONG)0 - (constant_time_eq_int(j,idx)&1)); + } + + b->d[i] = acc; + } + } + + b->top = top; + bn_correct_top(b); + return 1; +} + +/* + * Given a pointer value, compute the next address that is a cache line + * multiple. + */ +#define MOD_EXP_CTIME_ALIGN(x_) \ + ((unsigned char*)(x_) + (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - (((size_t)(x_)) & (MOD_EXP_CTIME_MIN_CACHE_LINE_MASK)))) + +/* + * This variant of BN_mod_exp_mont() uses fixed windows and the special + * precomputation memory layout to limit data-dependency to a minimum to + * protect secret exponents (cf. the hyper-threading timing attacks pointed + * out by Colin Percival, + * http://www.daemonology.net/hyperthreading-considered-harmful/) + */ +int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont) +{ + int i, bits, ret = 0, window, wvalue; + int top; + BN_MONT_CTX *mont = NULL; + + int numPowers; + unsigned char *powerbufFree = NULL; + int powerbufLen = 0; + unsigned char *powerbuf = NULL; + BIGNUM tmp, am; + + bn_check_top(a); + bn_check_top(p); + bn_check_top(m); + + if (!BN_is_odd(m)) { + BNerr(BN_F_BN_MOD_EXP_MONT_CONSTTIME, BN_R_CALLED_WITH_EVEN_MODULUS); + return (0); + } + + top = m->top; + + bits = BN_num_bits(p); + if (bits == 0) { + /* x**0 mod 1 is still zero. */ + if (BN_is_one(m)) { + ret = 1; + BN_zero(rr); + } else { + ret = BN_one(rr); + } + return ret; + } + + BN_CTX_start(ctx); + + /* + * Allocate a montgomery context if it was not supplied by the caller. If + * this is not done, things will break in the montgomery part. + */ + if (in_mont != NULL) + mont = in_mont; + else { + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, m, ctx)) + goto err; + } + + /* Get the window size to use with size of p. */ + window = BN_window_bits_for_ctime_exponent_size(bits); +#if defined(OPENSSL_BN_ASM_MONT5) + if (window == 6 && bits <= 1024) + window = 5; /* ~5% improvement of 2048-bit RSA sign */ +#endif + + /* + * Allocate a buffer large enough to hold all of the pre-computed powers + * of am, am itself and tmp. + */ + numPowers = 1 << window; + powerbufLen = sizeof(m->d[0]) * (top * numPowers + + ((2 * top) > + numPowers ? (2 * top) : numPowers)); +#ifdef alloca + if (powerbufLen < 3072) + powerbufFree = + alloca(powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH); + else +#endif + if ((powerbufFree = + (unsigned char *)OPENSSL_malloc(powerbufLen + + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) + == NULL) + goto err; + + powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree); + memset(powerbuf, 0, powerbufLen); + +#ifdef alloca + if (powerbufLen < 3072) + powerbufFree = NULL; +#endif + + /* lay down tmp and am right after powers table */ + tmp.d = (BN_ULONG *)(powerbuf + sizeof(m->d[0]) * top * numPowers); + am.d = tmp.d + top; + tmp.top = am.top = 0; + tmp.dmax = am.dmax = top; + tmp.neg = am.neg = 0; + tmp.flags = am.flags = BN_FLG_STATIC_DATA; + + /* prepare a^0 in Montgomery domain */ +#if 1 + if (!BN_to_montgomery(&tmp, BN_value_one(), mont, ctx)) + goto err; +#else + tmp.d[0] = (0 - m->d[0]) & BN_MASK2; /* 2^(top*BN_BITS2) - m */ + for (i = 1; i < top; i++) + tmp.d[i] = (~m->d[i]) & BN_MASK2; + tmp.top = top; +#endif + + /* prepare a^1 in Montgomery domain */ + if (a->neg || BN_ucmp(a, m) >= 0) { + if (!BN_mod(&am, a, m, ctx)) + goto err; + if (!BN_to_montgomery(&am, &am, mont, ctx)) + goto err; + } else if (!BN_to_montgomery(&am, a, mont, ctx)) + goto err; + +#if defined(OPENSSL_BN_ASM_MONT5) + if (window == 5 && top > 1) { + /* + * This optimization uses ideas from http://eprint.iacr.org/2011/239, + * specifically optimization of cache-timing attack countermeasures + * and pre-computation optimization. + */ + + /* + * Dedicated window==4 case improves 512-bit RSA sign by ~15%, but as + * 512-bit RSA is hardly relevant, we omit it to spare size... + */ + void bn_mul_mont_gather5(BN_ULONG *rp, const BN_ULONG *ap, + const void *table, const BN_ULONG *np, + const BN_ULONG *n0, int num, int power); + void bn_scatter5(const BN_ULONG *inp, size_t num, + void *table, size_t power); + void bn_gather5(BN_ULONG *out, size_t num, void *table, size_t power); + + BN_ULONG *np = mont->N.d, *n0 = mont->n0; + + /* + * BN_to_montgomery can contaminate words above .top [in + * BN_DEBUG[_DEBUG] build]... + */ + for (i = am.top; i < top; i++) + am.d[i] = 0; + for (i = tmp.top; i < top; i++) + tmp.d[i] = 0; + + bn_scatter5(tmp.d, top, powerbuf, 0); + bn_scatter5(am.d, am.top, powerbuf, 1); + bn_mul_mont(tmp.d, am.d, am.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, 2); + +# if 0 + for (i = 3; i < 32; i++) { + /* Calculate a^i = a^(i-1) * a */ + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + } +# else + /* same as above, but uses squaring for 1/2 of operations */ + for (i = 4; i < 32; i *= 2) { + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, i); + } + for (i = 3; i < 8; i += 2) { + int j; + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + for (j = 2 * i; j < 32; j *= 2) { + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, j); + } + } + for (; i < 16; i += 2) { + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, 2 * i); + } + for (; i < 32; i += 2) { + bn_mul_mont_gather5(tmp.d, am.d, powerbuf, np, n0, top, i - 1); + bn_scatter5(tmp.d, top, powerbuf, i); + } +# endif + bits--; + for (wvalue = 0, i = bits % 5; i >= 0; i--, bits--) + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + bn_gather5(tmp.d, top, powerbuf, wvalue); + + /* + * Scan the exponent one window at a time starting from the most + * significant bits. + */ + while (bits >= 0) { + for (wvalue = 0, i = 0; i < 5; i++, bits--) + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont(tmp.d, tmp.d, tmp.d, np, n0, top); + bn_mul_mont_gather5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue); + } + + tmp.top = top; + bn_correct_top(&tmp); + } else +#endif + { + if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 0, window)) + goto err; + if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&am, top, powerbuf, 1, window)) + goto err; + + /* + * If the window size is greater than 1, then calculate + * val[i=2..2^winsize-1]. Powers are computed as a*a^(i-1) (even + * powers could instead be computed as (a^(i/2))^2 to use the slight + * performance advantage of sqr over mul). + */ + if (window > 1) { + if (!BN_mod_mul_montgomery(&tmp, &am, &am, mont, ctx)) + goto err; + if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, 2, + window)) + goto err; + for (i = 3; i < numPowers; i++) { + /* Calculate a^i = a^(i-1) * a */ + if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx)) + goto err; + if (!MOD_EXP_CTIME_COPY_TO_PREBUF(&tmp, top, powerbuf, i, + window)) + goto err; + } + } + + bits--; + for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&tmp, top, powerbuf, wvalue, + window)) + goto err; + + /* + * Scan the exponent one window at a time starting from the most + * significant bits. + */ + while (bits >= 0) { + wvalue = 0; /* The 'value' of the window */ + + /* Scan the window, squaring the result as we go */ + for (i = 0; i < window; i++, bits--) { + if (!BN_mod_mul_montgomery(&tmp, &tmp, &tmp, mont, ctx)) + goto err; + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + } + + /* + * Fetch the appropriate pre-computed value from the pre-buf + */ + if (!MOD_EXP_CTIME_COPY_FROM_PREBUF(&am, top, powerbuf, wvalue, + window)) + goto err; + + /* Multiply the result into the intermediate result */ + if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx)) + goto err; + } + } + + /* Convert the final result from montgomery to standard format */ + if (!BN_from_montgomery(rr, &tmp, mont, ctx)) + goto err; + ret = 1; + err: + if ((in_mont == NULL) && (mont != NULL)) + BN_MONT_CTX_free(mont); + if (powerbuf != NULL) { + OPENSSL_cleanse(powerbuf, powerbufLen); + if (powerbufFree) + OPENSSL_free(powerbufFree); + } + BN_CTX_end(ctx); + return (ret); +} + +int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + BN_MONT_CTX *mont = NULL; + int b, bits, ret = 0; + int r_is_one; + BN_ULONG w, next_w; + BIGNUM *d, *r, *t; + BIGNUM *swap_tmp; +#define BN_MOD_MUL_WORD(r, w, m) \ + (BN_mul_word(r, (w)) && \ + (/* BN_ucmp(r, (m)) < 0 ? 1 :*/ \ + (BN_mod(t, r, m, ctx) && (swap_tmp = r, r = t, t = swap_tmp, 1)))) + /* + * BN_MOD_MUL_WORD is only used with 'w' large, so the BN_ucmp test is + * probably more overhead than always using BN_mod (which uses BN_copy if + * a similar test returns true). + */ + /* + * We can use BN_mod and do not need BN_nnmod because our accumulator is + * never negative (the result of BN_mod does not depend on the sign of + * the modulus). + */ +#define BN_TO_MONTGOMERY_WORD(r, w, mont) \ + (BN_set_word(r, (w)) && BN_to_montgomery(r, r, (mont), ctx)) + + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ + BNerr(BN_F_BN_MOD_EXP_MONT_WORD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + bn_check_top(p); + bn_check_top(m); + + if (!BN_is_odd(m)) { + BNerr(BN_F_BN_MOD_EXP_MONT_WORD, BN_R_CALLED_WITH_EVEN_MODULUS); + return (0); + } + if (m->top == 1) + a %= m->d[0]; /* make sure that 'a' is reduced */ + + bits = BN_num_bits(p); + if (bits == 0) { + /* x**0 mod 1 is still zero. */ + if (BN_is_one(m)) { + ret = 1; + BN_zero(rr); + } else { + ret = BN_one(rr); + } + return ret; + } + if (a == 0) { + BN_zero(rr); + ret = 1; + return ret; + } + + BN_CTX_start(ctx); + d = BN_CTX_get(ctx); + r = BN_CTX_get(ctx); + t = BN_CTX_get(ctx); + if (d == NULL || r == NULL || t == NULL) + goto err; + + if (in_mont != NULL) + mont = in_mont; + else { + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, m, ctx)) + goto err; + } + + r_is_one = 1; /* except for Montgomery factor */ + + /* bits-1 >= 0 */ + + /* The result is accumulated in the product r*w. */ + w = a; /* bit 'bits-1' of 'p' is always set */ + for (b = bits - 2; b >= 0; b--) { + /* First, square r*w. */ + next_w = w * w; + if ((next_w / w) != w) { /* overflow */ + if (r_is_one) { + if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) + goto err; + r_is_one = 0; + } else { + if (!BN_MOD_MUL_WORD(r, w, m)) + goto err; + } + next_w = 1; + } + w = next_w; + if (!r_is_one) { + if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) + goto err; + } + + /* Second, multiply r*w by 'a' if exponent bit is set. */ + if (BN_is_bit_set(p, b)) { + next_w = w * a; + if ((next_w / a) != w) { /* overflow */ + if (r_is_one) { + if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) + goto err; + r_is_one = 0; + } else { + if (!BN_MOD_MUL_WORD(r, w, m)) + goto err; + } + next_w = a; + } + w = next_w; + } + } + + /* Finally, set r:=r*w. */ + if (w != 1) { + if (r_is_one) { + if (!BN_TO_MONTGOMERY_WORD(r, w, mont)) + goto err; + r_is_one = 0; + } else { + if (!BN_MOD_MUL_WORD(r, w, m)) + goto err; + } + } + + if (r_is_one) { /* can happen only if a == 1 */ + if (!BN_one(rr)) + goto err; + } else { + if (!BN_from_montgomery(rr, r, mont, ctx)) + goto err; + } + ret = 1; + err: + if ((in_mont == NULL) && (mont != NULL)) + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + bn_check_top(rr); + return (ret); +} + +/* The old fallback, simple version :-) */ +int BN_mod_exp_simple(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) +{ + int i, j, bits, ret = 0, wstart, wend, window, wvalue; + int start = 1; + BIGNUM *d; + /* Table of variables obtained from 'ctx' */ + BIGNUM *val[TABLE_SIZE]; + + if (BN_get_flags(p, BN_FLG_CONSTTIME) != 0) { + /* BN_FLG_CONSTTIME only supported by BN_mod_exp_mont() */ + BNerr(BN_F_BN_MOD_EXP_SIMPLE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + bits = BN_num_bits(p); + if (bits == 0) { + /* x**0 mod 1 is still zero. */ + if (BN_is_one(m)) { + ret = 1; + BN_zero(r); + } else { + ret = BN_one(r); + } + return ret; + } + + BN_CTX_start(ctx); + d = BN_CTX_get(ctx); + val[0] = BN_CTX_get(ctx); + if (!d || !val[0]) + goto err; + + if (!BN_nnmod(val[0], a, m, ctx)) + goto err; /* 1 */ + if (BN_is_zero(val[0])) { + BN_zero(r); + ret = 1; + goto err; + } + + window = BN_window_bits_for_exponent_size(bits); + if (window > 1) { + if (!BN_mod_mul(d, val[0], val[0], m, ctx)) + goto err; /* 2 */ + j = 1 << (window - 1); + for (i = 1; i < j; i++) { + if (((val[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul(val[i], val[i - 1], d, m, ctx)) + goto err; + } + } + + start = 1; /* This is used to avoid multiplication etc + * when there is only the value '1' in the + * buffer. */ + wvalue = 0; /* The 'value' of the window */ + wstart = bits - 1; /* The top bit of the window */ + wend = 0; /* The bottom bit of the window */ + + if (!BN_one(r)) + goto err; + + for (;;) { + if (BN_is_bit_set(p, wstart) == 0) { + if (!start) + if (!BN_mod_mul(r, r, r, m, ctx)) + goto err; + if (wstart == 0) + break; + wstart--; + continue; + } + /* + * We now have wstart on a 'set' bit, we now need to work out how bit + * a window to do. To do this we need to scan forward until the last + * set bit before the end of the window + */ + j = wstart; + wvalue = 1; + wend = 0; + for (i = 1; i < window; i++) { + if (wstart - i < 0) + break; + if (BN_is_bit_set(p, wstart - i)) { + wvalue <<= (i - wend); + wvalue |= 1; + wend = i; + } + } + + /* wend is the size of the current window */ + j = wend + 1; + /* add the 'bytes above' */ + if (!start) + for (i = 0; i < j; i++) { + if (!BN_mod_mul(r, r, r, m, ctx)) + goto err; + } + + /* wvalue will be an odd number < 2^window */ + if (!BN_mod_mul(r, r, val[wvalue >> 1], m, ctx)) + goto err; + + /* move the 'window' down further */ + wstart -= wend + 1; + wvalue = 0; + start = 0; + if (wstart < 0) + break; + } + ret = 1; + err: + BN_CTX_end(ctx); + bn_check_top(r); + return (ret); +} diff --git a/libs/openssl/crypto/bn/bn_exp2.c b/libs/openssl/crypto/bn/bn_exp2.c new file mode 100644 index 00000000..43fd2044 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_exp2.c @@ -0,0 +1,303 @@ +/* crypto/bn/bn_exp2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +#define TABLE_SIZE 32 + +int BN_mod_exp2_mont(BIGNUM *rr, const BIGNUM *a1, const BIGNUM *p1, + const BIGNUM *a2, const BIGNUM *p2, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + int i, j, bits, b, bits1, bits2, ret = + 0, wpos1, wpos2, window1, window2, wvalue1, wvalue2; + int r_is_one = 1; + BIGNUM *d, *r; + const BIGNUM *a_mod_m; + /* Tables of variables obtained from 'ctx' */ + BIGNUM *val1[TABLE_SIZE], *val2[TABLE_SIZE]; + BN_MONT_CTX *mont = NULL; + + bn_check_top(a1); + bn_check_top(p1); + bn_check_top(a2); + bn_check_top(p2); + bn_check_top(m); + + if (!(m->d[0] & 1)) { + BNerr(BN_F_BN_MOD_EXP2_MONT, BN_R_CALLED_WITH_EVEN_MODULUS); + return (0); + } + bits1 = BN_num_bits(p1); + bits2 = BN_num_bits(p2); + if ((bits1 == 0) && (bits2 == 0)) { + ret = BN_one(rr); + return ret; + } + + bits = (bits1 > bits2) ? bits1 : bits2; + + BN_CTX_start(ctx); + d = BN_CTX_get(ctx); + r = BN_CTX_get(ctx); + val1[0] = BN_CTX_get(ctx); + val2[0] = BN_CTX_get(ctx); + if (!d || !r || !val1[0] || !val2[0]) + goto err; + + if (in_mont != NULL) + mont = in_mont; + else { + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, m, ctx)) + goto err; + } + + window1 = BN_window_bits_for_exponent_size(bits1); + window2 = BN_window_bits_for_exponent_size(bits2); + + /* + * Build table for a1: val1[i] := a1^(2*i + 1) mod m for i = 0 .. 2^(window1-1) + */ + if (a1->neg || BN_ucmp(a1, m) >= 0) { + if (!BN_mod(val1[0], a1, m, ctx)) + goto err; + a_mod_m = val1[0]; + } else + a_mod_m = a1; + if (BN_is_zero(a_mod_m)) { + BN_zero(rr); + ret = 1; + goto err; + } + + if (!BN_to_montgomery(val1[0], a_mod_m, mont, ctx)) + goto err; + if (window1 > 1) { + if (!BN_mod_mul_montgomery(d, val1[0], val1[0], mont, ctx)) + goto err; + + j = 1 << (window1 - 1); + for (i = 1; i < j; i++) { + if (((val1[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul_montgomery(val1[i], val1[i - 1], d, mont, ctx)) + goto err; + } + } + + /* + * Build table for a2: val2[i] := a2^(2*i + 1) mod m for i = 0 .. 2^(window2-1) + */ + if (a2->neg || BN_ucmp(a2, m) >= 0) { + if (!BN_mod(val2[0], a2, m, ctx)) + goto err; + a_mod_m = val2[0]; + } else + a_mod_m = a2; + if (BN_is_zero(a_mod_m)) { + BN_zero(rr); + ret = 1; + goto err; + } + if (!BN_to_montgomery(val2[0], a_mod_m, mont, ctx)) + goto err; + if (window2 > 1) { + if (!BN_mod_mul_montgomery(d, val2[0], val2[0], mont, ctx)) + goto err; + + j = 1 << (window2 - 1); + for (i = 1; i < j; i++) { + if (((val2[i] = BN_CTX_get(ctx)) == NULL) || + !BN_mod_mul_montgomery(val2[i], val2[i - 1], d, mont, ctx)) + goto err; + } + } + + /* Now compute the power product, using independent windows. */ + r_is_one = 1; + wvalue1 = 0; /* The 'value' of the first window */ + wvalue2 = 0; /* The 'value' of the second window */ + wpos1 = 0; /* If wvalue1 > 0, the bottom bit of the + * first window */ + wpos2 = 0; /* If wvalue2 > 0, the bottom bit of the + * second window */ + + if (!BN_to_montgomery(r, BN_value_one(), mont, ctx)) + goto err; + for (b = bits - 1; b >= 0; b--) { + if (!r_is_one) { + if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) + goto err; + } + + if (!wvalue1) + if (BN_is_bit_set(p1, b)) { + /* + * consider bits b-window1+1 .. b for this window + */ + i = b - window1 + 1; + while (!BN_is_bit_set(p1, i)) /* works for i<0 */ + i++; + wpos1 = i; + wvalue1 = 1; + for (i = b - 1; i >= wpos1; i--) { + wvalue1 <<= 1; + if (BN_is_bit_set(p1, i)) + wvalue1++; + } + } + + if (!wvalue2) + if (BN_is_bit_set(p2, b)) { + /* + * consider bits b-window2+1 .. b for this window + */ + i = b - window2 + 1; + while (!BN_is_bit_set(p2, i)) + i++; + wpos2 = i; + wvalue2 = 1; + for (i = b - 1; i >= wpos2; i--) { + wvalue2 <<= 1; + if (BN_is_bit_set(p2, i)) + wvalue2++; + } + } + + if (wvalue1 && b == wpos1) { + /* wvalue1 is odd and < 2^window1 */ + if (!BN_mod_mul_montgomery(r, r, val1[wvalue1 >> 1], mont, ctx)) + goto err; + wvalue1 = 0; + r_is_one = 0; + } + + if (wvalue2 && b == wpos2) { + /* wvalue2 is odd and < 2^window2 */ + if (!BN_mod_mul_montgomery(r, r, val2[wvalue2 >> 1], mont, ctx)) + goto err; + wvalue2 = 0; + r_is_one = 0; + } + } + if (!BN_from_montgomery(rr, r, mont, ctx)) + goto err; + ret = 1; + err: + if ((in_mont == NULL) && (mont != NULL)) + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + bn_check_top(rr); + return (ret); +} diff --git a/libs/openssl/crypto/bn/bn_gcd.c b/libs/openssl/crypto/bn/bn_gcd.c new file mode 100644 index 00000000..ce59fe70 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_gcd.c @@ -0,0 +1,702 @@ +/* crypto/bn/bn_gcd.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include "bn_lcl.h" + +static BIGNUM *euclid(BIGNUM *a, BIGNUM *b); + +int BN_gcd(BIGNUM *r, const BIGNUM *in_a, const BIGNUM *in_b, BN_CTX *ctx) +{ + BIGNUM *a, *b, *t; + int ret = 0; + + bn_check_top(in_a); + bn_check_top(in_b); + + BN_CTX_start(ctx); + a = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + if (a == NULL || b == NULL) + goto err; + + if (BN_copy(a, in_a) == NULL) + goto err; + if (BN_copy(b, in_b) == NULL) + goto err; + a->neg = 0; + b->neg = 0; + + if (BN_cmp(a, b) < 0) { + t = a; + a = b; + b = t; + } + t = euclid(a, b); + if (t == NULL) + goto err; + + if (BN_copy(r, t) == NULL) + goto err; + ret = 1; + err: + BN_CTX_end(ctx); + bn_check_top(r); + return (ret); +} + +static BIGNUM *euclid(BIGNUM *a, BIGNUM *b) +{ + BIGNUM *t; + int shifts = 0; + + bn_check_top(a); + bn_check_top(b); + + /* 0 <= b <= a */ + while (!BN_is_zero(b)) { + /* 0 < b <= a */ + + if (BN_is_odd(a)) { + if (BN_is_odd(b)) { + if (!BN_sub(a, a, b)) + goto err; + if (!BN_rshift1(a, a)) + goto err; + if (BN_cmp(a, b) < 0) { + t = a; + a = b; + b = t; + } + } else { /* a odd - b even */ + + if (!BN_rshift1(b, b)) + goto err; + if (BN_cmp(a, b) < 0) { + t = a; + a = b; + b = t; + } + } + } else { /* a is even */ + + if (BN_is_odd(b)) { + if (!BN_rshift1(a, a)) + goto err; + if (BN_cmp(a, b) < 0) { + t = a; + a = b; + b = t; + } + } else { /* a even - b even */ + + if (!BN_rshift1(a, a)) + goto err; + if (!BN_rshift1(b, b)) + goto err; + shifts++; + } + } + /* 0 <= b <= a */ + } + + if (shifts) { + if (!BN_lshift(a, a, shifts)) + goto err; + } + bn_check_top(a); + return (a); + err: + return (NULL); +} + +/* solves ax == 1 (mod n) */ +static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *ctx); + +BIGNUM *BN_mod_inverse(BIGNUM *in, + const BIGNUM *a, const BIGNUM *n, BN_CTX *ctx) +{ + BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; + BIGNUM *ret = NULL; + int sign; + + if ((BN_get_flags(a, BN_FLG_CONSTTIME) != 0) + || (BN_get_flags(n, BN_FLG_CONSTTIME) != 0)) { + return BN_mod_inverse_no_branch(in, a, n, ctx); + } + + bn_check_top(a); + bn_check_top(n); + + BN_CTX_start(ctx); + A = BN_CTX_get(ctx); + B = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + D = BN_CTX_get(ctx); + M = BN_CTX_get(ctx); + Y = BN_CTX_get(ctx); + T = BN_CTX_get(ctx); + if (T == NULL) + goto err; + + if (in == NULL) + R = BN_new(); + else + R = in; + if (R == NULL) + goto err; + + BN_one(X); + BN_zero(Y); + if (BN_copy(B, a) == NULL) + goto err; + if (BN_copy(A, n) == NULL) + goto err; + A->neg = 0; + if (B->neg || (BN_ucmp(B, A) >= 0)) { + if (!BN_nnmod(B, B, A, ctx)) + goto err; + } + sign = -1; + /*- + * From B = a mod |n|, A = |n| it follows that + * + * 0 <= B < A, + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + */ + + if (BN_is_odd(n) && (BN_num_bits(n) <= (BN_BITS <= 32 ? 450 : 2048))) { + /* + * Binary inversion algorithm; requires odd modulus. This is faster + * than the general algorithm if the modulus is sufficiently small + * (about 400 .. 500 bits on 32-bit sytems, but much more on 64-bit + * systems) + */ + int shift; + + while (!BN_is_zero(B)) { + /*- + * 0 < B < |n|, + * 0 < A <= |n|, + * (1) -sign*X*a == B (mod |n|), + * (2) sign*Y*a == A (mod |n|) + */ + + /* + * Now divide B by the maximum possible power of two in the + * integers, and divide X by the same value mod |n|. When we're + * done, (1) still holds. + */ + shift = 0; + while (!BN_is_bit_set(B, shift)) { /* note that 0 < B */ + shift++; + + if (BN_is_odd(X)) { + if (!BN_uadd(X, X, n)) + goto err; + } + /* + * now X is even, so we can easily divide it by two + */ + if (!BN_rshift1(X, X)) + goto err; + } + if (shift > 0) { + if (!BN_rshift(B, B, shift)) + goto err; + } + + /* + * Same for A and Y. Afterwards, (2) still holds. + */ + shift = 0; + while (!BN_is_bit_set(A, shift)) { /* note that 0 < A */ + shift++; + + if (BN_is_odd(Y)) { + if (!BN_uadd(Y, Y, n)) + goto err; + } + /* now Y is even */ + if (!BN_rshift1(Y, Y)) + goto err; + } + if (shift > 0) { + if (!BN_rshift(A, A, shift)) + goto err; + } + + /*- + * We still have (1) and (2). + * Both A and B are odd. + * The following computations ensure that + * + * 0 <= B < |n|, + * 0 < A < |n|, + * (1) -sign*X*a == B (mod |n|), + * (2) sign*Y*a == A (mod |n|), + * + * and that either A or B is even in the next iteration. + */ + if (BN_ucmp(B, A) >= 0) { + /* -sign*(X + Y)*a == B - A (mod |n|) */ + if (!BN_uadd(X, X, Y)) + goto err; + /* + * NB: we could use BN_mod_add_quick(X, X, Y, n), but that + * actually makes the algorithm slower + */ + if (!BN_usub(B, B, A)) + goto err; + } else { + /* sign*(X + Y)*a == A - B (mod |n|) */ + if (!BN_uadd(Y, Y, X)) + goto err; + /* + * as above, BN_mod_add_quick(Y, Y, X, n) would slow things + * down + */ + if (!BN_usub(A, A, B)) + goto err; + } + } + } else { + /* general inversion algorithm */ + + while (!BN_is_zero(B)) { + BIGNUM *tmp; + + /*- + * 0 < B < A, + * (*) -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|) + */ + + /* (D, M) := (A/B, A%B) ... */ + if (BN_num_bits(A) == BN_num_bits(B)) { + if (!BN_one(D)) + goto err; + if (!BN_sub(M, A, B)) + goto err; + } else if (BN_num_bits(A) == BN_num_bits(B) + 1) { + /* A/B is 1, 2, or 3 */ + if (!BN_lshift1(T, B)) + goto err; + if (BN_ucmp(A, T) < 0) { + /* A < 2*B, so D=1 */ + if (!BN_one(D)) + goto err; + if (!BN_sub(M, A, B)) + goto err; + } else { + /* A >= 2*B, so D=2 or D=3 */ + if (!BN_sub(M, A, T)) + goto err; + if (!BN_add(D, T, B)) + goto err; /* use D (:= 3*B) as temp */ + if (BN_ucmp(A, D) < 0) { + /* A < 3*B, so D=2 */ + if (!BN_set_word(D, 2)) + goto err; + /* + * M (= A - 2*B) already has the correct value + */ + } else { + /* only D=3 remains */ + if (!BN_set_word(D, 3)) + goto err; + /* + * currently M = A - 2*B, but we need M = A - 3*B + */ + if (!BN_sub(M, M, B)) + goto err; + } + } + } else { + if (!BN_div(D, M, A, B, ctx)) + goto err; + } + + /*- + * Now + * A = D*B + M; + * thus we have + * (**) sign*Y*a == D*B + M (mod |n|). + */ + + tmp = A; /* keep the BIGNUM object, the value does not + * matter */ + + /* (A, B) := (B, A mod B) ... */ + A = B; + B = M; + /* ... so we have 0 <= B < A again */ + + /*- + * Since the former M is now B and the former B is now A, + * (**) translates into + * sign*Y*a == D*A + B (mod |n|), + * i.e. + * sign*Y*a - D*A == B (mod |n|). + * Similarly, (*) translates into + * -sign*X*a == A (mod |n|). + * + * Thus, + * sign*Y*a + D*sign*X*a == B (mod |n|), + * i.e. + * sign*(Y + D*X)*a == B (mod |n|). + * + * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + * Note that X and Y stay non-negative all the time. + */ + + /* + * most of the time D is very small, so we can optimize tmp := + * D*X+Y + */ + if (BN_is_one(D)) { + if (!BN_add(tmp, X, Y)) + goto err; + } else { + if (BN_is_word(D, 2)) { + if (!BN_lshift1(tmp, X)) + goto err; + } else if (BN_is_word(D, 4)) { + if (!BN_lshift(tmp, X, 2)) + goto err; + } else if (D->top == 1) { + if (!BN_copy(tmp, X)) + goto err; + if (!BN_mul_word(tmp, D->d[0])) + goto err; + } else { + if (!BN_mul(tmp, D, X, ctx)) + goto err; + } + if (!BN_add(tmp, tmp, Y)) + goto err; + } + + M = Y; /* keep the BIGNUM object, the value does not + * matter */ + Y = X; + X = tmp; + sign = -sign; + } + } + + /*- + * The while loop (Euclid's algorithm) ends when + * A == gcd(a,n); + * we have + * sign*Y*a == A (mod |n|), + * where Y is non-negative. + */ + + if (sign < 0) { + if (!BN_sub(Y, n, Y)) + goto err; + } + /* Now Y*a == A (mod |n|). */ + + if (BN_is_one(A)) { + /* Y*a == 1 (mod |n|) */ + if (!Y->neg && BN_ucmp(Y, n) < 0) { + if (!BN_copy(R, Y)) + goto err; + } else { + if (!BN_nnmod(R, Y, n, ctx)) + goto err; + } + } else { + BNerr(BN_F_BN_MOD_INVERSE, BN_R_NO_INVERSE); + goto err; + } + ret = R; + err: + if ((ret == NULL) && (in == NULL)) + BN_free(R); + BN_CTX_end(ctx); + bn_check_top(ret); + return (ret); +} + +/* + * BN_mod_inverse_no_branch is a special version of BN_mod_inverse. It does + * not contain branches that may leak sensitive information. + */ +static BIGNUM *BN_mod_inverse_no_branch(BIGNUM *in, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *ctx) +{ + BIGNUM *A, *B, *X, *Y, *M, *D, *T, *R = NULL; + BIGNUM local_A, local_B; + BIGNUM *pA, *pB; + BIGNUM *ret = NULL; + int sign; + + bn_check_top(a); + bn_check_top(n); + + BN_CTX_start(ctx); + A = BN_CTX_get(ctx); + B = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + D = BN_CTX_get(ctx); + M = BN_CTX_get(ctx); + Y = BN_CTX_get(ctx); + T = BN_CTX_get(ctx); + if (T == NULL) + goto err; + + if (in == NULL) + R = BN_new(); + else + R = in; + if (R == NULL) + goto err; + + BN_one(X); + BN_zero(Y); + if (BN_copy(B, a) == NULL) + goto err; + if (BN_copy(A, n) == NULL) + goto err; + A->neg = 0; + + if (B->neg || (BN_ucmp(B, A) >= 0)) { + /* + * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, + * BN_div_no_branch will be called eventually. + */ + pB = &local_B; + local_B.flags = 0; + BN_with_flags(pB, B, BN_FLG_CONSTTIME); + if (!BN_nnmod(B, pB, A, ctx)) + goto err; + } + sign = -1; + /*- + * From B = a mod |n|, A = |n| it follows that + * + * 0 <= B < A, + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + */ + + while (!BN_is_zero(B)) { + BIGNUM *tmp; + + /*- + * 0 < B < A, + * (*) -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|) + */ + + /* + * Turn BN_FLG_CONSTTIME flag on, so that when BN_div is invoked, + * BN_div_no_branch will be called eventually. + */ + pA = &local_A; + local_A.flags = 0; + BN_with_flags(pA, A, BN_FLG_CONSTTIME); + + /* (D, M) := (A/B, A%B) ... */ + if (!BN_div(D, M, pA, B, ctx)) + goto err; + + /*- + * Now + * A = D*B + M; + * thus we have + * (**) sign*Y*a == D*B + M (mod |n|). + */ + + tmp = A; /* keep the BIGNUM object, the value does not + * matter */ + + /* (A, B) := (B, A mod B) ... */ + A = B; + B = M; + /* ... so we have 0 <= B < A again */ + + /*- + * Since the former M is now B and the former B is now A, + * (**) translates into + * sign*Y*a == D*A + B (mod |n|), + * i.e. + * sign*Y*a - D*A == B (mod |n|). + * Similarly, (*) translates into + * -sign*X*a == A (mod |n|). + * + * Thus, + * sign*Y*a + D*sign*X*a == B (mod |n|), + * i.e. + * sign*(Y + D*X)*a == B (mod |n|). + * + * So if we set (X, Y, sign) := (Y + D*X, X, -sign), we arrive back at + * -sign*X*a == B (mod |n|), + * sign*Y*a == A (mod |n|). + * Note that X and Y stay non-negative all the time. + */ + + if (!BN_mul(tmp, D, X, ctx)) + goto err; + if (!BN_add(tmp, tmp, Y)) + goto err; + + M = Y; /* keep the BIGNUM object, the value does not + * matter */ + Y = X; + X = tmp; + sign = -sign; + } + + /*- + * The while loop (Euclid's algorithm) ends when + * A == gcd(a,n); + * we have + * sign*Y*a == A (mod |n|), + * where Y is non-negative. + */ + + if (sign < 0) { + if (!BN_sub(Y, n, Y)) + goto err; + } + /* Now Y*a == A (mod |n|). */ + + if (BN_is_one(A)) { + /* Y*a == 1 (mod |n|) */ + if (!Y->neg && BN_ucmp(Y, n) < 0) { + if (!BN_copy(R, Y)) + goto err; + } else { + if (!BN_nnmod(R, Y, n, ctx)) + goto err; + } + } else { + BNerr(BN_F_BN_MOD_INVERSE_NO_BRANCH, BN_R_NO_INVERSE); + goto err; + } + ret = R; + err: + if ((ret == NULL) && (in == NULL)) + BN_free(R); + BN_CTX_end(ctx); + bn_check_top(ret); + return (ret); +} diff --git a/libs/openssl/crypto/bn/bn_gf2m.c b/libs/openssl/crypto/bn/bn_gf2m.c new file mode 100644 index 00000000..8ad44b48 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_gf2m.c @@ -0,0 +1,1301 @@ +/* crypto/bn/bn_gf2m.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * In addition, Sun covenants to all licensees who provide a reciprocal + * covenant with respect to their own patents if any, not to sue under + * current and future patent claims necessarily infringed by the making, + * using, practicing, selling, offering for sale and/or otherwise + * disposing of the ECC Code as delivered hereunder (or portions thereof), + * provided that such covenant shall not apply: + * 1) for code that a licensee deletes from the ECC Code; + * 2) separates from the ECC Code; or + * 3) for infringements caused by: + * i) the modification of the ECC Code or + * ii) the combination of the ECC Code with other software or + * devices where such combination causes the infringement. + * + * The software is originally written by Sheueling Chang Shantz and + * Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +/* + * NOTE: This file is licensed pursuant to the OpenSSL license below and may + * be modified; but after modifications, the above covenant may no longer + * apply! In such cases, the corresponding paragraph ["In addition, Sun + * covenants ... causes the infringement."] and this note can be edited out; + * but please keep the Sun copyright notice and attribution. + */ + +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +#ifndef OPENSSL_NO_EC2M + +/* + * Maximum number of iterations before BN_GF2m_mod_solve_quad_arr should + * fail. + */ +# define MAX_ITERATIONS 50 + +static const BN_ULONG SQR_tb[16] = { 0, 1, 4, 5, 16, 17, 20, 21, + 64, 65, 68, 69, 80, 81, 84, 85 +}; + +/* Platform-specific macros to accelerate squaring. */ +# if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) +# define SQR1(w) \ + SQR_tb[(w) >> 60 & 0xF] << 56 | SQR_tb[(w) >> 56 & 0xF] << 48 | \ + SQR_tb[(w) >> 52 & 0xF] << 40 | SQR_tb[(w) >> 48 & 0xF] << 32 | \ + SQR_tb[(w) >> 44 & 0xF] << 24 | SQR_tb[(w) >> 40 & 0xF] << 16 | \ + SQR_tb[(w) >> 36 & 0xF] << 8 | SQR_tb[(w) >> 32 & 0xF] +# define SQR0(w) \ + SQR_tb[(w) >> 28 & 0xF] << 56 | SQR_tb[(w) >> 24 & 0xF] << 48 | \ + SQR_tb[(w) >> 20 & 0xF] << 40 | SQR_tb[(w) >> 16 & 0xF] << 32 | \ + SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >> 8 & 0xF] << 16 | \ + SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF] +# endif +# ifdef THIRTY_TWO_BIT +# define SQR1(w) \ + SQR_tb[(w) >> 28 & 0xF] << 24 | SQR_tb[(w) >> 24 & 0xF] << 16 | \ + SQR_tb[(w) >> 20 & 0xF] << 8 | SQR_tb[(w) >> 16 & 0xF] +# define SQR0(w) \ + SQR_tb[(w) >> 12 & 0xF] << 24 | SQR_tb[(w) >> 8 & 0xF] << 16 | \ + SQR_tb[(w) >> 4 & 0xF] << 8 | SQR_tb[(w) & 0xF] +# endif + +# if !defined(OPENSSL_BN_ASM_GF2m) +/* + * Product of two polynomials a, b each with degree < BN_BITS2 - 1, result is + * a polynomial r with degree < 2 * BN_BITS - 1 The caller MUST ensure that + * the variables have the right amount of space allocated. + */ +# ifdef THIRTY_TWO_BIT +static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, + const BN_ULONG b) +{ + register BN_ULONG h, l, s; + BN_ULONG tab[8], top2b = a >> 30; + register BN_ULONG a1, a2, a4; + + a1 = a & (0x3FFFFFFF); + a2 = a1 << 1; + a4 = a2 << 1; + + tab[0] = 0; + tab[1] = a1; + tab[2] = a2; + tab[3] = a1 ^ a2; + tab[4] = a4; + tab[5] = a1 ^ a4; + tab[6] = a2 ^ a4; + tab[7] = a1 ^ a2 ^ a4; + + s = tab[b & 0x7]; + l = s; + s = tab[b >> 3 & 0x7]; + l ^= s << 3; + h = s >> 29; + s = tab[b >> 6 & 0x7]; + l ^= s << 6; + h ^= s >> 26; + s = tab[b >> 9 & 0x7]; + l ^= s << 9; + h ^= s >> 23; + s = tab[b >> 12 & 0x7]; + l ^= s << 12; + h ^= s >> 20; + s = tab[b >> 15 & 0x7]; + l ^= s << 15; + h ^= s >> 17; + s = tab[b >> 18 & 0x7]; + l ^= s << 18; + h ^= s >> 14; + s = tab[b >> 21 & 0x7]; + l ^= s << 21; + h ^= s >> 11; + s = tab[b >> 24 & 0x7]; + l ^= s << 24; + h ^= s >> 8; + s = tab[b >> 27 & 0x7]; + l ^= s << 27; + h ^= s >> 5; + s = tab[b >> 30]; + l ^= s << 30; + h ^= s >> 2; + + /* compensate for the top two bits of a */ + + if (top2b & 01) { + l ^= b << 30; + h ^= b >> 2; + } + if (top2b & 02) { + l ^= b << 31; + h ^= b >> 1; + } + + *r1 = h; + *r0 = l; +} +# endif +# if defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) +static void bn_GF2m_mul_1x1(BN_ULONG *r1, BN_ULONG *r0, const BN_ULONG a, + const BN_ULONG b) +{ + register BN_ULONG h, l, s; + BN_ULONG tab[16], top3b = a >> 61; + register BN_ULONG a1, a2, a4, a8; + + a1 = a & (0x1FFFFFFFFFFFFFFFULL); + a2 = a1 << 1; + a4 = a2 << 1; + a8 = a4 << 1; + + tab[0] = 0; + tab[1] = a1; + tab[2] = a2; + tab[3] = a1 ^ a2; + tab[4] = a4; + tab[5] = a1 ^ a4; + tab[6] = a2 ^ a4; + tab[7] = a1 ^ a2 ^ a4; + tab[8] = a8; + tab[9] = a1 ^ a8; + tab[10] = a2 ^ a8; + tab[11] = a1 ^ a2 ^ a8; + tab[12] = a4 ^ a8; + tab[13] = a1 ^ a4 ^ a8; + tab[14] = a2 ^ a4 ^ a8; + tab[15] = a1 ^ a2 ^ a4 ^ a8; + + s = tab[b & 0xF]; + l = s; + s = tab[b >> 4 & 0xF]; + l ^= s << 4; + h = s >> 60; + s = tab[b >> 8 & 0xF]; + l ^= s << 8; + h ^= s >> 56; + s = tab[b >> 12 & 0xF]; + l ^= s << 12; + h ^= s >> 52; + s = tab[b >> 16 & 0xF]; + l ^= s << 16; + h ^= s >> 48; + s = tab[b >> 20 & 0xF]; + l ^= s << 20; + h ^= s >> 44; + s = tab[b >> 24 & 0xF]; + l ^= s << 24; + h ^= s >> 40; + s = tab[b >> 28 & 0xF]; + l ^= s << 28; + h ^= s >> 36; + s = tab[b >> 32 & 0xF]; + l ^= s << 32; + h ^= s >> 32; + s = tab[b >> 36 & 0xF]; + l ^= s << 36; + h ^= s >> 28; + s = tab[b >> 40 & 0xF]; + l ^= s << 40; + h ^= s >> 24; + s = tab[b >> 44 & 0xF]; + l ^= s << 44; + h ^= s >> 20; + s = tab[b >> 48 & 0xF]; + l ^= s << 48; + h ^= s >> 16; + s = tab[b >> 52 & 0xF]; + l ^= s << 52; + h ^= s >> 12; + s = tab[b >> 56 & 0xF]; + l ^= s << 56; + h ^= s >> 8; + s = tab[b >> 60]; + l ^= s << 60; + h ^= s >> 4; + + /* compensate for the top three bits of a */ + + if (top3b & 01) { + l ^= b << 61; + h ^= b >> 3; + } + if (top3b & 02) { + l ^= b << 62; + h ^= b >> 2; + } + if (top3b & 04) { + l ^= b << 63; + h ^= b >> 1; + } + + *r1 = h; + *r0 = l; +} +# endif + +/* + * Product of two polynomials a, b each with degree < 2 * BN_BITS2 - 1, + * result is a polynomial r with degree < 4 * BN_BITS2 - 1 The caller MUST + * ensure that the variables have the right amount of space allocated. + */ +static void bn_GF2m_mul_2x2(BN_ULONG *r, const BN_ULONG a1, const BN_ULONG a0, + const BN_ULONG b1, const BN_ULONG b0) +{ + BN_ULONG m1, m0; + /* r[3] = h1, r[2] = h0; r[1] = l1; r[0] = l0 */ + bn_GF2m_mul_1x1(r + 3, r + 2, a1, b1); + bn_GF2m_mul_1x1(r + 1, r, a0, b0); + bn_GF2m_mul_1x1(&m1, &m0, a0 ^ a1, b0 ^ b1); + /* Correction on m1 ^= l1 ^ h1; m0 ^= l0 ^ h0; */ + r[2] ^= m1 ^ r[1] ^ r[3]; /* h0 ^= m1 ^ l1 ^ h1; */ + r[1] = r[3] ^ r[2] ^ r[0] ^ m1 ^ m0; /* l1 ^= l0 ^ h0 ^ m0; */ +} +# else +void bn_GF2m_mul_2x2(BN_ULONG *r, BN_ULONG a1, BN_ULONG a0, BN_ULONG b1, + BN_ULONG b0); +# endif + +/* + * Add polynomials a and b and store result in r; r could be a or b, a and b + * could be equal; r is the bitwise XOR of a and b. + */ +int BN_GF2m_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) +{ + int i; + const BIGNUM *at, *bt; + + bn_check_top(a); + bn_check_top(b); + + if (a->top < b->top) { + at = b; + bt = a; + } else { + at = a; + bt = b; + } + + if (bn_wexpand(r, at->top) == NULL) + return 0; + + for (i = 0; i < bt->top; i++) { + r->d[i] = at->d[i] ^ bt->d[i]; + } + for (; i < at->top; i++) { + r->d[i] = at->d[i]; + } + + r->top = at->top; + bn_correct_top(r); + + return 1; +} + +/*- + * Some functions allow for representation of the irreducible polynomials + * as an int[], say p. The irreducible f(t) is then of the form: + * t^p[0] + t^p[1] + ... + t^p[k] + * where m = p[0] > p[1] > ... > p[k] = 0. + */ + +/* Performs modular reduction of a and store result in r. r could be a. */ +int BN_GF2m_mod_arr(BIGNUM *r, const BIGNUM *a, const int p[]) +{ + int j, k; + int n, dN, d0, d1; + BN_ULONG zz, *z; + + bn_check_top(a); + + if (!p[0]) { + /* reduction mod 1 => return 0 */ + BN_zero(r); + return 1; + } + + /* + * Since the algorithm does reduction in the r value, if a != r, copy the + * contents of a into r so we can do reduction in r. + */ + if (a != r) { + if (!bn_wexpand(r, a->top)) + return 0; + for (j = 0; j < a->top; j++) { + r->d[j] = a->d[j]; + } + r->top = a->top; + } + z = r->d; + + /* start reduction */ + dN = p[0] / BN_BITS2; + for (j = r->top - 1; j > dN;) { + zz = z[j]; + if (z[j] == 0) { + j--; + continue; + } + z[j] = 0; + + for (k = 1; p[k] != 0; k++) { + /* reducing component t^p[k] */ + n = p[0] - p[k]; + d0 = n % BN_BITS2; + d1 = BN_BITS2 - d0; + n /= BN_BITS2; + z[j - n] ^= (zz >> d0); + if (d0) + z[j - n - 1] ^= (zz << d1); + } + + /* reducing component t^0 */ + n = dN; + d0 = p[0] % BN_BITS2; + d1 = BN_BITS2 - d0; + z[j - n] ^= (zz >> d0); + if (d0) + z[j - n - 1] ^= (zz << d1); + } + + /* final round of reduction */ + while (j == dN) { + + d0 = p[0] % BN_BITS2; + zz = z[dN] >> d0; + if (zz == 0) + break; + d1 = BN_BITS2 - d0; + + /* clear up the top d1 bits */ + if (d0) + z[dN] = (z[dN] << d1) >> d1; + else + z[dN] = 0; + z[0] ^= zz; /* reduction t^0 component */ + + for (k = 1; p[k] != 0; k++) { + BN_ULONG tmp_ulong; + + /* reducing component t^p[k] */ + n = p[k] / BN_BITS2; + d0 = p[k] % BN_BITS2; + d1 = BN_BITS2 - d0; + z[n] ^= (zz << d0); + tmp_ulong = zz >> d1; + if (d0 && tmp_ulong) + z[n + 1] ^= tmp_ulong; + } + + } + + bn_correct_top(r); + return 1; +} + +/* + * Performs modular reduction of a by p and store result in r. r could be a. + * This function calls down to the BN_GF2m_mod_arr implementation; this wrapper + * function is only provided for convenience; for best performance, use the + * BN_GF2m_mod_arr function. + */ +int BN_GF2m_mod(BIGNUM *r, const BIGNUM *a, const BIGNUM *p) +{ + int ret = 0; + int arr[6]; + bn_check_top(a); + bn_check_top(p); + ret = BN_GF2m_poly2arr(p, arr, sizeof(arr) / sizeof(arr[0])); + if (!ret || ret > (int)(sizeof(arr) / sizeof(arr[0]))) { + BNerr(BN_F_BN_GF2M_MOD, BN_R_INVALID_LENGTH); + return 0; + } + ret = BN_GF2m_mod_arr(r, a, arr); + bn_check_top(r); + return ret; +} + +/* + * Compute the product of two polynomials a and b, reduce modulo p, and store + * the result in r. r could be a or b; a could be b. + */ +int BN_GF2m_mod_mul_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx) +{ + int zlen, i, j, k, ret = 0; + BIGNUM *s; + BN_ULONG x1, x0, y1, y0, zz[4]; + + bn_check_top(a); + bn_check_top(b); + + if (a == b) { + return BN_GF2m_mod_sqr_arr(r, a, p, ctx); + } + + BN_CTX_start(ctx); + if ((s = BN_CTX_get(ctx)) == NULL) + goto err; + + zlen = a->top + b->top + 4; + if (!bn_wexpand(s, zlen)) + goto err; + s->top = zlen; + + for (i = 0; i < zlen; i++) + s->d[i] = 0; + + for (j = 0; j < b->top; j += 2) { + y0 = b->d[j]; + y1 = ((j + 1) == b->top) ? 0 : b->d[j + 1]; + for (i = 0; i < a->top; i += 2) { + x0 = a->d[i]; + x1 = ((i + 1) == a->top) ? 0 : a->d[i + 1]; + bn_GF2m_mul_2x2(zz, x1, x0, y1, y0); + for (k = 0; k < 4; k++) + s->d[i + j + k] ^= zz[k]; + } + } + + bn_correct_top(s); + if (BN_GF2m_mod_arr(r, s, p)) + ret = 1; + bn_check_top(r); + + err: + BN_CTX_end(ctx); + return ret; +} + +/* + * Compute the product of two polynomials a and b, reduce modulo p, and store + * the result in r. r could be a or b; a could equal b. This function calls + * down to the BN_GF2m_mod_mul_arr implementation; this wrapper function is + * only provided for convenience; for best performance, use the + * BN_GF2m_mod_mul_arr function. + */ +int BN_GF2m_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx) +{ + int ret = 0; + const int max = BN_num_bits(p) + 1; + int *arr = NULL; + bn_check_top(a); + bn_check_top(b); + bn_check_top(p); + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) + goto err; + ret = BN_GF2m_poly2arr(p, arr, max); + if (!ret || ret > max) { + BNerr(BN_F_BN_GF2M_MOD_MUL, BN_R_INVALID_LENGTH); + goto err; + } + ret = BN_GF2m_mod_mul_arr(r, a, b, arr, ctx); + bn_check_top(r); + err: + if (arr) + OPENSSL_free(arr); + return ret; +} + +/* Square a, reduce the result mod p, and store it in a. r could be a. */ +int BN_GF2m_mod_sqr_arr(BIGNUM *r, const BIGNUM *a, const int p[], + BN_CTX *ctx) +{ + int i, ret = 0; + BIGNUM *s; + + bn_check_top(a); + BN_CTX_start(ctx); + if ((s = BN_CTX_get(ctx)) == NULL) + goto err; + if (!bn_wexpand(s, 2 * a->top)) + goto err; + + for (i = a->top - 1; i >= 0; i--) { + s->d[2 * i + 1] = SQR1(a->d[i]); + s->d[2 * i] = SQR0(a->d[i]); + } + + s->top = 2 * a->top; + bn_correct_top(s); + if (!BN_GF2m_mod_arr(r, s, p)) + goto err; + bn_check_top(r); + ret = 1; + err: + BN_CTX_end(ctx); + return ret; +} + +/* + * Square a, reduce the result mod p, and store it in a. r could be a. This + * function calls down to the BN_GF2m_mod_sqr_arr implementation; this + * wrapper function is only provided for convenience; for best performance, + * use the BN_GF2m_mod_sqr_arr function. + */ +int BN_GF2m_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) +{ + int ret = 0; + const int max = BN_num_bits(p) + 1; + int *arr = NULL; + + bn_check_top(a); + bn_check_top(p); + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) + goto err; + ret = BN_GF2m_poly2arr(p, arr, max); + if (!ret || ret > max) { + BNerr(BN_F_BN_GF2M_MOD_SQR, BN_R_INVALID_LENGTH); + goto err; + } + ret = BN_GF2m_mod_sqr_arr(r, a, arr, ctx); + bn_check_top(r); + err: + if (arr) + OPENSSL_free(arr); + return ret; +} + +/* + * Invert a, reduce modulo p, and store the result in r. r could be a. Uses + * Modified Almost Inverse Algorithm (Algorithm 10) from Hankerson, D., + * Hernandez, J.L., and Menezes, A. "Software Implementation of Elliptic + * Curve Cryptography Over Binary Fields". + */ +int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) +{ + BIGNUM *b, *c = NULL, *u = NULL, *v = NULL, *tmp; + int ret = 0; + + bn_check_top(a); + bn_check_top(p); + + BN_CTX_start(ctx); + + if ((b = BN_CTX_get(ctx)) == NULL) + goto err; + if ((c = BN_CTX_get(ctx)) == NULL) + goto err; + if ((u = BN_CTX_get(ctx)) == NULL) + goto err; + if ((v = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_GF2m_mod(u, a, p)) + goto err; + if (BN_is_zero(u)) + goto err; + + if (!BN_copy(v, p)) + goto err; +# if 0 + if (!BN_one(b)) + goto err; + + while (1) { + while (!BN_is_odd(u)) { + if (BN_is_zero(u)) + goto err; + if (!BN_rshift1(u, u)) + goto err; + if (BN_is_odd(b)) { + if (!BN_GF2m_add(b, b, p)) + goto err; + } + if (!BN_rshift1(b, b)) + goto err; + } + + if (BN_abs_is_word(u, 1)) + break; + + if (BN_num_bits(u) < BN_num_bits(v)) { + tmp = u; + u = v; + v = tmp; + tmp = b; + b = c; + c = tmp; + } + + if (!BN_GF2m_add(u, u, v)) + goto err; + if (!BN_GF2m_add(b, b, c)) + goto err; + } +# else + { + int i; + int ubits = BN_num_bits(u); + int vbits = BN_num_bits(v); /* v is copy of p */ + int top = p->top; + BN_ULONG *udp, *bdp, *vdp, *cdp; + + if (!bn_wexpand(u, top)) + goto err; + udp = u->d; + for (i = u->top; i < top; i++) + udp[i] = 0; + u->top = top; + if (!bn_wexpand(b, top)) + goto err; + bdp = b->d; + bdp[0] = 1; + for (i = 1; i < top; i++) + bdp[i] = 0; + b->top = top; + if (!bn_wexpand(c, top)) + goto err; + cdp = c->d; + for (i = 0; i < top; i++) + cdp[i] = 0; + c->top = top; + vdp = v->d; /* It pays off to "cache" *->d pointers, + * because it allows optimizer to be more + * aggressive. But we don't have to "cache" + * p->d, because *p is declared 'const'... */ + while (1) { + while (ubits && !(udp[0] & 1)) { + BN_ULONG u0, u1, b0, b1, mask; + + u0 = udp[0]; + b0 = bdp[0]; + mask = (BN_ULONG)0 - (b0 & 1); + b0 ^= p->d[0] & mask; + for (i = 0; i < top - 1; i++) { + u1 = udp[i + 1]; + udp[i] = ((u0 >> 1) | (u1 << (BN_BITS2 - 1))) & BN_MASK2; + u0 = u1; + b1 = bdp[i + 1] ^ (p->d[i + 1] & mask); + bdp[i] = ((b0 >> 1) | (b1 << (BN_BITS2 - 1))) & BN_MASK2; + b0 = b1; + } + udp[i] = u0 >> 1; + bdp[i] = b0 >> 1; + ubits--; + } + + if (ubits <= BN_BITS2) { + if (udp[0] == 0) /* poly was reducible */ + goto err; + if (udp[0] == 1) + break; + } + + if (ubits < vbits) { + i = ubits; + ubits = vbits; + vbits = i; + tmp = u; + u = v; + v = tmp; + tmp = b; + b = c; + c = tmp; + udp = vdp; + vdp = v->d; + bdp = cdp; + cdp = c->d; + } + for (i = 0; i < top; i++) { + udp[i] ^= vdp[i]; + bdp[i] ^= cdp[i]; + } + if (ubits == vbits) { + BN_ULONG ul; + int utop = (ubits - 1) / BN_BITS2; + + while ((ul = udp[utop]) == 0 && utop) + utop--; + ubits = utop * BN_BITS2 + BN_num_bits_word(ul); + } + } + bn_correct_top(b); + } +# endif + + if (!BN_copy(r, b)) + goto err; + bn_check_top(r); + ret = 1; + + err: +# ifdef BN_DEBUG /* BN_CTX_end would complain about the + * expanded form */ + bn_correct_top(c); + bn_correct_top(u); + bn_correct_top(v); +# endif + BN_CTX_end(ctx); + return ret; +} + +/* + * Invert xx, reduce modulo p, and store the result in r. r could be xx. + * This function calls down to the BN_GF2m_mod_inv implementation; this + * wrapper function is only provided for convenience; for best performance, + * use the BN_GF2m_mod_inv function. + */ +int BN_GF2m_mod_inv_arr(BIGNUM *r, const BIGNUM *xx, const int p[], + BN_CTX *ctx) +{ + BIGNUM *field; + int ret = 0; + + bn_check_top(xx); + BN_CTX_start(ctx); + if ((field = BN_CTX_get(ctx)) == NULL) + goto err; + if (!BN_GF2m_arr2poly(p, field)) + goto err; + + ret = BN_GF2m_mod_inv(r, xx, field, ctx); + bn_check_top(r); + + err: + BN_CTX_end(ctx); + return ret; +} + +# ifndef OPENSSL_SUN_GF2M_DIV +/* + * Divide y by x, reduce modulo p, and store the result in r. r could be x + * or y, x could equal y. + */ +int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, + const BIGNUM *p, BN_CTX *ctx) +{ + BIGNUM *xinv = NULL; + int ret = 0; + + bn_check_top(y); + bn_check_top(x); + bn_check_top(p); + + BN_CTX_start(ctx); + xinv = BN_CTX_get(ctx); + if (xinv == NULL) + goto err; + + if (!BN_GF2m_mod_inv(xinv, x, p, ctx)) + goto err; + if (!BN_GF2m_mod_mul(r, y, xinv, p, ctx)) + goto err; + bn_check_top(r); + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} +# else +/* + * Divide y by x, reduce modulo p, and store the result in r. r could be x + * or y, x could equal y. Uses algorithm Modular_Division_GF(2^m) from + * Chang-Shantz, S. "From Euclid's GCD to Montgomery Multiplication to the + * Great Divide". + */ +int BN_GF2m_mod_div(BIGNUM *r, const BIGNUM *y, const BIGNUM *x, + const BIGNUM *p, BN_CTX *ctx) +{ + BIGNUM *a, *b, *u, *v; + int ret = 0; + + bn_check_top(y); + bn_check_top(x); + bn_check_top(p); + + BN_CTX_start(ctx); + + a = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + u = BN_CTX_get(ctx); + v = BN_CTX_get(ctx); + if (v == NULL) + goto err; + + /* reduce x and y mod p */ + if (!BN_GF2m_mod(u, y, p)) + goto err; + if (!BN_GF2m_mod(a, x, p)) + goto err; + if (!BN_copy(b, p)) + goto err; + + while (!BN_is_odd(a)) { + if (!BN_rshift1(a, a)) + goto err; + if (BN_is_odd(u)) + if (!BN_GF2m_add(u, u, p)) + goto err; + if (!BN_rshift1(u, u)) + goto err; + } + + do { + if (BN_GF2m_cmp(b, a) > 0) { + if (!BN_GF2m_add(b, b, a)) + goto err; + if (!BN_GF2m_add(v, v, u)) + goto err; + do { + if (!BN_rshift1(b, b)) + goto err; + if (BN_is_odd(v)) + if (!BN_GF2m_add(v, v, p)) + goto err; + if (!BN_rshift1(v, v)) + goto err; + } while (!BN_is_odd(b)); + } else if (BN_abs_is_word(a, 1)) + break; + else { + if (!BN_GF2m_add(a, a, b)) + goto err; + if (!BN_GF2m_add(u, u, v)) + goto err; + do { + if (!BN_rshift1(a, a)) + goto err; + if (BN_is_odd(u)) + if (!BN_GF2m_add(u, u, p)) + goto err; + if (!BN_rshift1(u, u)) + goto err; + } while (!BN_is_odd(a)); + } + } while (1); + + if (!BN_copy(r, u)) + goto err; + bn_check_top(r); + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} +# endif + +/* + * Divide yy by xx, reduce modulo p, and store the result in r. r could be xx + * * or yy, xx could equal yy. This function calls down to the + * BN_GF2m_mod_div implementation; this wrapper function is only provided for + * convenience; for best performance, use the BN_GF2m_mod_div function. + */ +int BN_GF2m_mod_div_arr(BIGNUM *r, const BIGNUM *yy, const BIGNUM *xx, + const int p[], BN_CTX *ctx) +{ + BIGNUM *field; + int ret = 0; + + bn_check_top(yy); + bn_check_top(xx); + + BN_CTX_start(ctx); + if ((field = BN_CTX_get(ctx)) == NULL) + goto err; + if (!BN_GF2m_arr2poly(p, field)) + goto err; + + ret = BN_GF2m_mod_div(r, yy, xx, field, ctx); + bn_check_top(r); + + err: + BN_CTX_end(ctx); + return ret; +} + +/* + * Compute the bth power of a, reduce modulo p, and store the result in r. r + * could be a. Uses simple square-and-multiply algorithm A.5.1 from IEEE + * P1363. + */ +int BN_GF2m_mod_exp_arr(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const int p[], BN_CTX *ctx) +{ + int ret = 0, i, n; + BIGNUM *u; + + bn_check_top(a); + bn_check_top(b); + + if (BN_is_zero(b)) + return (BN_one(r)); + + if (BN_abs_is_word(b, 1)) + return (BN_copy(r, a) != NULL); + + BN_CTX_start(ctx); + if ((u = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_GF2m_mod_arr(u, a, p)) + goto err; + + n = BN_num_bits(b) - 1; + for (i = n - 1; i >= 0; i--) { + if (!BN_GF2m_mod_sqr_arr(u, u, p, ctx)) + goto err; + if (BN_is_bit_set(b, i)) { + if (!BN_GF2m_mod_mul_arr(u, u, a, p, ctx)) + goto err; + } + } + if (!BN_copy(r, u)) + goto err; + bn_check_top(r); + ret = 1; + err: + BN_CTX_end(ctx); + return ret; +} + +/* + * Compute the bth power of a, reduce modulo p, and store the result in r. r + * could be a. This function calls down to the BN_GF2m_mod_exp_arr + * implementation; this wrapper function is only provided for convenience; + * for best performance, use the BN_GF2m_mod_exp_arr function. + */ +int BN_GF2m_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *p, BN_CTX *ctx) +{ + int ret = 0; + const int max = BN_num_bits(p) + 1; + int *arr = NULL; + bn_check_top(a); + bn_check_top(b); + bn_check_top(p); + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) + goto err; + ret = BN_GF2m_poly2arr(p, arr, max); + if (!ret || ret > max) { + BNerr(BN_F_BN_GF2M_MOD_EXP, BN_R_INVALID_LENGTH); + goto err; + } + ret = BN_GF2m_mod_exp_arr(r, a, b, arr, ctx); + bn_check_top(r); + err: + if (arr) + OPENSSL_free(arr); + return ret; +} + +/* + * Compute the square root of a, reduce modulo p, and store the result in r. + * r could be a. Uses exponentiation as in algorithm A.4.1 from IEEE P1363. + */ +int BN_GF2m_mod_sqrt_arr(BIGNUM *r, const BIGNUM *a, const int p[], + BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *u; + + bn_check_top(a); + + if (!p[0]) { + /* reduction mod 1 => return 0 */ + BN_zero(r); + return 1; + } + + BN_CTX_start(ctx); + if ((u = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_set_bit(u, p[0] - 1)) + goto err; + ret = BN_GF2m_mod_exp_arr(r, a, u, p, ctx); + bn_check_top(r); + + err: + BN_CTX_end(ctx); + return ret; +} + +/* + * Compute the square root of a, reduce modulo p, and store the result in r. + * r could be a. This function calls down to the BN_GF2m_mod_sqrt_arr + * implementation; this wrapper function is only provided for convenience; + * for best performance, use the BN_GF2m_mod_sqrt_arr function. + */ +int BN_GF2m_mod_sqrt(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) +{ + int ret = 0; + const int max = BN_num_bits(p) + 1; + int *arr = NULL; + bn_check_top(a); + bn_check_top(p); + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) + goto err; + ret = BN_GF2m_poly2arr(p, arr, max); + if (!ret || ret > max) { + BNerr(BN_F_BN_GF2M_MOD_SQRT, BN_R_INVALID_LENGTH); + goto err; + } + ret = BN_GF2m_mod_sqrt_arr(r, a, arr, ctx); + bn_check_top(r); + err: + if (arr) + OPENSSL_free(arr); + return ret; +} + +/* + * Find r such that r^2 + r = a mod p. r could be a. If no r exists returns + * 0. Uses algorithms A.4.7 and A.4.6 from IEEE P1363. + */ +int BN_GF2m_mod_solve_quad_arr(BIGNUM *r, const BIGNUM *a_, const int p[], + BN_CTX *ctx) +{ + int ret = 0, count = 0, j; + BIGNUM *a, *z, *rho, *w, *w2, *tmp; + + bn_check_top(a_); + + if (!p[0]) { + /* reduction mod 1 => return 0 */ + BN_zero(r); + return 1; + } + + BN_CTX_start(ctx); + a = BN_CTX_get(ctx); + z = BN_CTX_get(ctx); + w = BN_CTX_get(ctx); + if (w == NULL) + goto err; + + if (!BN_GF2m_mod_arr(a, a_, p)) + goto err; + + if (BN_is_zero(a)) { + BN_zero(r); + ret = 1; + goto err; + } + + if (p[0] & 0x1) { /* m is odd */ + /* compute half-trace of a */ + if (!BN_copy(z, a)) + goto err; + for (j = 1; j <= (p[0] - 1) / 2; j++) { + if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) + goto err; + if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) + goto err; + if (!BN_GF2m_add(z, z, a)) + goto err; + } + + } else { /* m is even */ + + rho = BN_CTX_get(ctx); + w2 = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + if (tmp == NULL) + goto err; + do { + if (!BN_rand(rho, p[0], 0, 0)) + goto err; + if (!BN_GF2m_mod_arr(rho, rho, p)) + goto err; + BN_zero(z); + if (!BN_copy(w, rho)) + goto err; + for (j = 1; j <= p[0] - 1; j++) { + if (!BN_GF2m_mod_sqr_arr(z, z, p, ctx)) + goto err; + if (!BN_GF2m_mod_sqr_arr(w2, w, p, ctx)) + goto err; + if (!BN_GF2m_mod_mul_arr(tmp, w2, a, p, ctx)) + goto err; + if (!BN_GF2m_add(z, z, tmp)) + goto err; + if (!BN_GF2m_add(w, w2, rho)) + goto err; + } + count++; + } while (BN_is_zero(w) && (count < MAX_ITERATIONS)); + if (BN_is_zero(w)) { + BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_TOO_MANY_ITERATIONS); + goto err; + } + } + + if (!BN_GF2m_mod_sqr_arr(w, z, p, ctx)) + goto err; + if (!BN_GF2m_add(w, z, w)) + goto err; + if (BN_GF2m_cmp(w, a)) { + BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD_ARR, BN_R_NO_SOLUTION); + goto err; + } + + if (!BN_copy(r, z)) + goto err; + bn_check_top(r); + + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} + +/* + * Find r such that r^2 + r = a mod p. r could be a. If no r exists returns + * 0. This function calls down to the BN_GF2m_mod_solve_quad_arr + * implementation; this wrapper function is only provided for convenience; + * for best performance, use the BN_GF2m_mod_solve_quad_arr function. + */ +int BN_GF2m_mod_solve_quad(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx) +{ + int ret = 0; + const int max = BN_num_bits(p) + 1; + int *arr = NULL; + bn_check_top(a); + bn_check_top(p); + if ((arr = (int *)OPENSSL_malloc(sizeof(int) * max)) == NULL) + goto err; + ret = BN_GF2m_poly2arr(p, arr, max); + if (!ret || ret > max) { + BNerr(BN_F_BN_GF2M_MOD_SOLVE_QUAD, BN_R_INVALID_LENGTH); + goto err; + } + ret = BN_GF2m_mod_solve_quad_arr(r, a, arr, ctx); + bn_check_top(r); + err: + if (arr) + OPENSSL_free(arr); + return ret; +} + +/* + * Convert the bit-string representation of a polynomial ( \sum_{i=0}^n a_i * + * x^i) into an array of integers corresponding to the bits with non-zero + * coefficient. Array is terminated with -1. Up to max elements of the array + * will be filled. Return value is total number of array elements that would + * be filled if array was large enough. + */ +int BN_GF2m_poly2arr(const BIGNUM *a, int p[], int max) +{ + int i, j, k = 0; + BN_ULONG mask; + + if (BN_is_zero(a)) + return 0; + + for (i = a->top - 1; i >= 0; i--) { + if (!a->d[i]) + /* skip word if a->d[i] == 0 */ + continue; + mask = BN_TBIT; + for (j = BN_BITS2 - 1; j >= 0; j--) { + if (a->d[i] & mask) { + if (k < max) + p[k] = BN_BITS2 * i + j; + k++; + } + mask >>= 1; + } + } + + if (k < max) { + p[k] = -1; + k++; + } + + return k; +} + +/* + * Convert the coefficient array representation of a polynomial to a + * bit-string. The array must be terminated by -1. + */ +int BN_GF2m_arr2poly(const int p[], BIGNUM *a) +{ + int i; + + bn_check_top(a); + BN_zero(a); + for (i = 0; p[i] != -1; i++) { + if (BN_set_bit(a, p[i]) == 0) + return 0; + } + bn_check_top(a); + + return 1; +} + +#endif diff --git a/libs/openssl/crypto/bn/bn_kron.c b/libs/openssl/crypto/bn/bn_kron.c new file mode 100644 index 00000000..88d731ac --- /dev/null +++ b/libs/openssl/crypto/bn/bn_kron.c @@ -0,0 +1,186 @@ +/* crypto/bn/bn_kron.c */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include "bn_lcl.h" + +/* least significant word */ +#define BN_lsw(n) (((n)->top == 0) ? (BN_ULONG) 0 : (n)->d[0]) + +/* Returns -2 for errors because both -1 and 0 are valid results. */ +int BN_kronecker(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + int i; + int ret = -2; /* avoid 'uninitialized' warning */ + int err = 0; + BIGNUM *A, *B, *tmp; + /*- + * In 'tab', only odd-indexed entries are relevant: + * For any odd BIGNUM n, + * tab[BN_lsw(n) & 7] + * is $(-1)^{(n^2-1)/8}$ (using TeX notation). + * Note that the sign of n does not matter. + */ + static const int tab[8] = { 0, 1, 0, -1, 0, -1, 0, 1 }; + + bn_check_top(a); + bn_check_top(b); + + BN_CTX_start(ctx); + A = BN_CTX_get(ctx); + B = BN_CTX_get(ctx); + if (B == NULL) + goto end; + + err = !BN_copy(A, a); + if (err) + goto end; + err = !BN_copy(B, b); + if (err) + goto end; + + /* + * Kronecker symbol, imlemented according to Henri Cohen, + * "A Course in Computational Algebraic Number Theory" + * (algorithm 1.4.10). + */ + + /* Cohen's step 1: */ + + if (BN_is_zero(B)) { + ret = BN_abs_is_word(A, 1); + goto end; + } + + /* Cohen's step 2: */ + + if (!BN_is_odd(A) && !BN_is_odd(B)) { + ret = 0; + goto end; + } + + /* now B is non-zero */ + i = 0; + while (!BN_is_bit_set(B, i)) + i++; + err = !BN_rshift(B, B, i); + if (err) + goto end; + if (i & 1) { + /* i is odd */ + /* (thus B was even, thus A must be odd!) */ + + /* set 'ret' to $(-1)^{(A^2-1)/8}$ */ + ret = tab[BN_lsw(A) & 7]; + } else { + /* i is even */ + ret = 1; + } + + if (B->neg) { + B->neg = 0; + if (A->neg) + ret = -ret; + } + + /* + * now B is positive and odd, so what remains to be done is to compute + * the Jacobi symbol (A/B) and multiply it by 'ret' + */ + + while (1) { + /* Cohen's step 3: */ + + /* B is positive and odd */ + + if (BN_is_zero(A)) { + ret = BN_is_one(B) ? ret : 0; + goto end; + } + + /* now A is non-zero */ + i = 0; + while (!BN_is_bit_set(A, i)) + i++; + err = !BN_rshift(A, A, i); + if (err) + goto end; + if (i & 1) { + /* i is odd */ + /* multiply 'ret' by $(-1)^{(B^2-1)/8}$ */ + ret = ret * tab[BN_lsw(B) & 7]; + } + + /* Cohen's step 4: */ + /* multiply 'ret' by $(-1)^{(A-1)(B-1)/4}$ */ + if ((A->neg ? ~BN_lsw(A) : BN_lsw(A)) & BN_lsw(B) & 2) + ret = -ret; + + /* (A, B) := (B mod |A|, |A|) */ + err = !BN_nnmod(B, B, A, ctx); + if (err) + goto end; + tmp = A; + A = B; + B = tmp; + tmp->neg = 0; + } + end: + BN_CTX_end(ctx); + if (err) + return -2; + else + return ret; +} diff --git a/libs/openssl/crypto/bn/bn_lcl.h b/libs/openssl/crypto/bn/bn_lcl.h new file mode 100644 index 00000000..904a7234 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_lcl.h @@ -0,0 +1,510 @@ +/* crypto/bn/bn_lcl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_BN_LCL_H +# define HEADER_BN_LCL_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/*- + * BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions + * + * + * For window size 'w' (w >= 2) and a random 'b' bits exponent, + * the number of multiplications is a constant plus on average + * + * 2^(w-1) + (b-w)/(w+1); + * + * here 2^(w-1) is for precomputing the table (we actually need + * entries only for windows that have the lowest bit set), and + * (b-w)/(w+1) is an approximation for the expected number of + * w-bit windows, not counting the first one. + * + * Thus we should use + * + * w >= 6 if b > 671 + * w = 5 if 671 > b > 239 + * w = 4 if 239 > b > 79 + * w = 3 if 79 > b > 23 + * w <= 2 if 23 > b + * + * (with draws in between). Very small exponents are often selected + * with low Hamming weight, so we use w = 1 for b <= 23. + */ +# if 1 +# define BN_window_bits_for_exponent_size(b) \ + ((b) > 671 ? 6 : \ + (b) > 239 ? 5 : \ + (b) > 79 ? 4 : \ + (b) > 23 ? 3 : 1) +# else +/* + * Old SSLeay/OpenSSL table. Maximum window size was 5, so this table differs + * for b==1024; but it coincides for other interesting values (b==160, + * b==512). + */ +# define BN_window_bits_for_exponent_size(b) \ + ((b) > 255 ? 5 : \ + (b) > 127 ? 4 : \ + (b) > 17 ? 3 : 1) +# endif + +/* + * BN_mod_exp_mont_conttime is based on the assumption that the L1 data cache + * line width of the target processor is at least the following value. + */ +# define MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH ( 64 ) +# define MOD_EXP_CTIME_MIN_CACHE_LINE_MASK (MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH - 1) + +/* + * Window sizes optimized for fixed window size modular exponentiation + * algorithm (BN_mod_exp_mont_consttime). To achieve the security goals of + * BN_mode_exp_mont_consttime, the maximum size of the window must not exceed + * log_2(MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH). Window size thresholds are + * defined for cache line sizes of 32 and 64, cache line sizes where + * log_2(32)=5 and log_2(64)=6 respectively. A window size of 7 should only be + * used on processors that have a 128 byte or greater cache line size. + */ +# if MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 64 + +# define BN_window_bits_for_ctime_exponent_size(b) \ + ((b) > 937 ? 6 : \ + (b) > 306 ? 5 : \ + (b) > 89 ? 4 : \ + (b) > 22 ? 3 : 1) +# define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (6) + +# elif MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH == 32 + +# define BN_window_bits_for_ctime_exponent_size(b) \ + ((b) > 306 ? 5 : \ + (b) > 89 ? 4 : \ + (b) > 22 ? 3 : 1) +# define BN_MAX_WINDOW_BITS_FOR_CTIME_EXPONENT_SIZE (5) + +# endif + +/* Pentium pro 16,16,16,32,64 */ +/* Alpha 16,16,16,16.64 */ +# define BN_MULL_SIZE_NORMAL (16)/* 32 */ +# define BN_MUL_RECURSIVE_SIZE_NORMAL (16)/* 32 less than */ +# define BN_SQR_RECURSIVE_SIZE_NORMAL (16)/* 32 */ +# define BN_MUL_LOW_RECURSIVE_SIZE_NORMAL (32)/* 32 */ +# define BN_MONT_CTX_SET_SIZE_WORD (64)/* 32 */ + +# if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC) +/* + * BN_UMULT_HIGH section. + * + * No, I'm not trying to overwhelm you when stating that the + * product of N-bit numbers is 2*N bits wide:-) No, I don't expect + * you to be impressed when I say that if the compiler doesn't + * support 2*N integer type, then you have to replace every N*N + * multiplication with 4 (N/2)*(N/2) accompanied by some shifts + * and additions which unavoidably results in severe performance + * penalties. Of course provided that the hardware is capable of + * producing 2*N result... That's when you normally start + * considering assembler implementation. However! It should be + * pointed out that some CPUs (most notably Alpha, PowerPC and + * upcoming IA-64 family:-) provide *separate* instruction + * calculating the upper half of the product placing the result + * into a general purpose register. Now *if* the compiler supports + * inline assembler, then it's not impossible to implement the + * "bignum" routines (and have the compiler optimize 'em) + * exhibiting "native" performance in C. That's what BN_UMULT_HIGH + * macro is about:-) + * + * + */ +# if defined(__alpha) && (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT)) +# if defined(__DECC) +# include +# define BN_UMULT_HIGH(a,b) (BN_ULONG)asm("umulh %a0,%a1,%v0",(a),(b)) +# elif defined(__GNUC__) && __GNUC__>=2 +# define BN_UMULT_HIGH(a,b) ({ \ + register BN_ULONG ret; \ + asm ("umulh %1,%2,%0" \ + : "=r"(ret) \ + : "r"(a), "r"(b)); \ + ret; }) +# endif /* compiler */ +# elif defined(_ARCH_PPC) && defined(__64BIT__) && defined(SIXTY_FOUR_BIT_LONG) +# if defined(__GNUC__) && __GNUC__>=2 +# define BN_UMULT_HIGH(a,b) ({ \ + register BN_ULONG ret; \ + asm ("mulhdu %0,%1,%2" \ + : "=r"(ret) \ + : "r"(a), "r"(b)); \ + ret; }) +# endif /* compiler */ +# elif (defined(__x86_64) || defined(__x86_64__)) && \ + (defined(SIXTY_FOUR_BIT_LONG) || defined(SIXTY_FOUR_BIT)) +# if defined(__GNUC__) && __GNUC__>=2 +# define BN_UMULT_HIGH(a,b) ({ \ + register BN_ULONG ret,discard; \ + asm ("mulq %3" \ + : "=a"(discard),"=d"(ret) \ + : "a"(a), "g"(b) \ + : "cc"); \ + ret; }) +# define BN_UMULT_LOHI(low,high,a,b) \ + asm ("mulq %3" \ + : "=a"(low),"=d"(high) \ + : "a"(a),"g"(b) \ + : "cc"); +# endif +# elif (defined(_M_AMD64) || defined(_M_X64)) && defined(SIXTY_FOUR_BIT) +# if defined(_MSC_VER) && _MSC_VER>=1400 +unsigned __int64 __umulh(unsigned __int64 a, unsigned __int64 b); +unsigned __int64 _umul128(unsigned __int64 a, unsigned __int64 b, + unsigned __int64 *h); +# pragma intrinsic(__umulh,_umul128) +# define BN_UMULT_HIGH(a,b) __umulh((a),(b)) +# define BN_UMULT_LOHI(low,high,a,b) ((low)=_umul128((a),(b),&(high))) +# endif +# elif defined(__mips) && (defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)) +# if defined(__GNUC__) && __GNUC__>=2 +# if __GNUC__>4 || (__GNUC__>=4 && __GNUC_MINOR__>=4) + /* "h" constraint is no more since 4.4 */ +# define BN_UMULT_HIGH(a,b) (((__uint128_t)(a)*(b))>>64) +# define BN_UMULT_LOHI(low,high,a,b) ({ \ + __uint128_t ret=(__uint128_t)(a)*(b); \ + (high)=ret>>64; (low)=ret; }) +# else +# define BN_UMULT_HIGH(a,b) ({ \ + register BN_ULONG ret; \ + asm ("dmultu %1,%2" \ + : "=h"(ret) \ + : "r"(a), "r"(b) : "l"); \ + ret; }) +# define BN_UMULT_LOHI(low,high,a,b)\ + asm ("dmultu %2,%3" \ + : "=l"(low),"=h"(high) \ + : "r"(a), "r"(b)); +# endif +# endif +# endif /* cpu */ +# endif /* OPENSSL_NO_ASM */ + +/************************************************************* + * Using the long long type + */ +# define Lw(t) (((BN_ULONG)(t))&BN_MASK2) +# define Hw(t) (((BN_ULONG)((t)>>BN_BITS2))&BN_MASK2) + +# ifdef BN_DEBUG_RAND +# define bn_clear_top2max(a) \ + { \ + int ind = (a)->dmax - (a)->top; \ + BN_ULONG *ftl = &(a)->d[(a)->top-1]; \ + for (; ind != 0; ind--) \ + *(++ftl) = 0x0; \ + } +# else +# define bn_clear_top2max(a) +# endif + +# ifdef BN_LLONG +# define mul_add(r,a,w,c) { \ + BN_ULLONG t; \ + t=(BN_ULLONG)w * (a) + (r) + (c); \ + (r)= Lw(t); \ + (c)= Hw(t); \ + } + +# define mul(r,a,w,c) { \ + BN_ULLONG t; \ + t=(BN_ULLONG)w * (a) + (c); \ + (r)= Lw(t); \ + (c)= Hw(t); \ + } + +# define sqr(r0,r1,a) { \ + BN_ULLONG t; \ + t=(BN_ULLONG)(a)*(a); \ + (r0)=Lw(t); \ + (r1)=Hw(t); \ + } + +# elif defined(BN_UMULT_LOHI) +# define mul_add(r,a,w,c) { \ + BN_ULONG high,low,ret,tmp=(a); \ + ret = (r); \ + BN_UMULT_LOHI(low,high,w,tmp); \ + ret += (c); \ + (c) = (ret<(c))?1:0; \ + (c) += high; \ + ret += low; \ + (c) += (ret>BN_BITS4)&BN_MASK2l) +# define L2HBITS(a) (((a)<>BN_BITS2)&BN_MASKl) +# define LL2HBITS(a) ((BN_ULLONG)((a)&BN_MASKl)<>(BN_BITS4-1); \ + m =(m&BN_MASK2l)<<(BN_BITS4+1); \ + l=(l+m)&BN_MASK2; if (l < m) h++; \ + (lo)=l; \ + (ho)=h; \ + } + +# define mul_add(r,a,bl,bh,c) { \ + BN_ULONG l,h; \ + \ + h= (a); \ + l=LBITS(h); \ + h=HBITS(h); \ + mul64(l,h,(bl),(bh)); \ + \ + /* non-multiply part */ \ + l=(l+(c))&BN_MASK2; if (l < (c)) h++; \ + (c)=(r); \ + l=(l+(c))&BN_MASK2; if (l < (c)) h++; \ + (c)=h&BN_MASK2; \ + (r)=l; \ + } + +# define mul(r,a,bl,bh,c) { \ + BN_ULONG l,h; \ + \ + h= (a); \ + l=LBITS(h); \ + h=HBITS(h); \ + mul64(l,h,(bl),(bh)); \ + \ + /* non-multiply part */ \ + l+=(c); if ((l&BN_MASK2) < (c)) h++; \ + (c)=h&BN_MASK2; \ + (r)=l&BN_MASK2; \ + } +# endif /* !BN_LLONG */ + +# if defined(OPENSSL_DOING_MAKEDEPEND) && defined(OPENSSL_FIPS) +# undef bn_div_words +# endif + +void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb); +void bn_mul_comba8(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); +void bn_mul_comba4(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b); +void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp); +void bn_sqr_comba8(BN_ULONG *r, const BN_ULONG *a); +void bn_sqr_comba4(BN_ULONG *r, const BN_ULONG *a); +int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n); +int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl); +void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, + int dna, int dnb, BN_ULONG *t); +void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, + int n, int tna, int tnb, BN_ULONG *t); +void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t); +void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n); +void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, + BN_ULONG *t); +void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2, + BN_ULONG *t); +BN_ULONG bn_add_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int cl, int dl); +BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int cl, int dl); +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/bn/bn_lib.c b/libs/openssl/crypto/bn/bn_lib.c new file mode 100644 index 00000000..80105fff --- /dev/null +++ b/libs/openssl/crypto/bn/bn_lib.c @@ -0,0 +1,916 @@ +/* crypto/bn/bn_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef BN_DEBUG +# undef NDEBUG /* avoid conflicting definitions */ +# define NDEBUG +#endif + +#include +#include +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +const char BN_version[] = "Big Number" OPENSSL_VERSION_PTEXT; + +/* This stuff appears to be completely unused, so is deprecated */ +#ifndef OPENSSL_NO_DEPRECATED +/*- + * For a 32 bit machine + * 2 - 4 == 128 + * 3 - 8 == 256 + * 4 - 16 == 512 + * 5 - 32 == 1024 + * 6 - 64 == 2048 + * 7 - 128 == 4096 + * 8 - 256 == 8192 + */ +static int bn_limit_bits = 0; +static int bn_limit_num = 8; /* (1<= 0) { + if (mult > (int)(sizeof(int) * 8) - 1) + mult = sizeof(int) * 8 - 1; + bn_limit_bits = mult; + bn_limit_num = 1 << mult; + } + if (high >= 0) { + if (high > (int)(sizeof(int) * 8) - 1) + high = sizeof(int) * 8 - 1; + bn_limit_bits_high = high; + bn_limit_num_high = 1 << high; + } + if (low >= 0) { + if (low > (int)(sizeof(int) * 8) - 1) + low = sizeof(int) * 8 - 1; + bn_limit_bits_low = low; + bn_limit_num_low = 1 << low; + } + if (mont >= 0) { + if (mont > (int)(sizeof(int) * 8) - 1) + mont = sizeof(int) * 8 - 1; + bn_limit_bits_mont = mont; + bn_limit_num_mont = 1 << mont; + } +} + +int BN_get_params(int which) +{ + if (which == 0) + return (bn_limit_bits); + else if (which == 1) + return (bn_limit_bits_high); + else if (which == 2) + return (bn_limit_bits_low); + else if (which == 3) + return (bn_limit_bits_mont); + else + return (0); +} +#endif + +const BIGNUM *BN_value_one(void) +{ + static const BN_ULONG data_one = 1L; + static const BIGNUM const_one = + { (BN_ULONG *)&data_one, 1, 1, 0, BN_FLG_STATIC_DATA }; + + return (&const_one); +} + +int BN_num_bits_word(BN_ULONG l) +{ + static const unsigned char bits[256] = { + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + }; + +#if defined(SIXTY_FOUR_BIT_LONG) + if (l & 0xffffffff00000000L) { + if (l & 0xffff000000000000L) { + if (l & 0xff00000000000000L) { + return (bits[(int)(l >> 56)] + 56); + } else + return (bits[(int)(l >> 48)] + 48); + } else { + if (l & 0x0000ff0000000000L) { + return (bits[(int)(l >> 40)] + 40); + } else + return (bits[(int)(l >> 32)] + 32); + } + } else +#else +# ifdef SIXTY_FOUR_BIT + if (l & 0xffffffff00000000LL) { + if (l & 0xffff000000000000LL) { + if (l & 0xff00000000000000LL) { + return (bits[(int)(l >> 56)] + 56); + } else + return (bits[(int)(l >> 48)] + 48); + } else { + if (l & 0x0000ff0000000000LL) { + return (bits[(int)(l >> 40)] + 40); + } else + return (bits[(int)(l >> 32)] + 32); + } + } else +# endif +#endif + { +#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) + if (l & 0xffff0000L) { + if (l & 0xff000000L) + return (bits[(int)(l >> 24L)] + 24); + else + return (bits[(int)(l >> 16L)] + 16); + } else +#endif + { +#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG) + if (l & 0xff00L) + return (bits[(int)(l >> 8)] + 8); + else +#endif + return (bits[(int)(l)]); + } + } +} + +int BN_num_bits(const BIGNUM *a) +{ + int i = a->top - 1; + bn_check_top(a); + + if (BN_is_zero(a)) + return 0; + return ((i * BN_BITS2) + BN_num_bits_word(a->d[i])); +} + +void BN_clear_free(BIGNUM *a) +{ + int i; + + if (a == NULL) + return; + bn_check_top(a); + if (a->d != NULL) { + OPENSSL_cleanse(a->d, a->dmax * sizeof(a->d[0])); + if (!(BN_get_flags(a, BN_FLG_STATIC_DATA))) + OPENSSL_free(a->d); + } + i = BN_get_flags(a, BN_FLG_MALLOCED); + OPENSSL_cleanse(a, sizeof(BIGNUM)); + if (i) + OPENSSL_free(a); +} + +void BN_free(BIGNUM *a) +{ + if (a == NULL) + return; + bn_check_top(a); + if ((a->d != NULL) && !(BN_get_flags(a, BN_FLG_STATIC_DATA))) + OPENSSL_free(a->d); + if (a->flags & BN_FLG_MALLOCED) + OPENSSL_free(a); + else { +#ifndef OPENSSL_NO_DEPRECATED + a->flags |= BN_FLG_FREE; +#endif + a->d = NULL; + } +} + +void BN_init(BIGNUM *a) +{ + memset(a, 0, sizeof(BIGNUM)); + bn_check_top(a); +} + +BIGNUM *BN_new(void) +{ + BIGNUM *ret; + + if ((ret = (BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL) { + BNerr(BN_F_BN_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->flags = BN_FLG_MALLOCED; + ret->top = 0; + ret->neg = 0; + ret->dmax = 0; + ret->d = NULL; + bn_check_top(ret); + return (ret); +} + +/* This is used both by bn_expand2() and bn_dup_expand() */ +/* The caller MUST check that words > b->dmax before calling this */ +static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words) +{ + BN_ULONG *A, *a = NULL; + const BN_ULONG *B; + int i; + + bn_check_top(b); + + if (words > (INT_MAX / (4 * BN_BITS2))) { + BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_BIGNUM_TOO_LONG); + return NULL; + } + if (BN_get_flags(b, BN_FLG_STATIC_DATA)) { + BNerr(BN_F_BN_EXPAND_INTERNAL, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); + return (NULL); + } + a = A = (BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG) * words); + if (A == NULL) { + BNerr(BN_F_BN_EXPAND_INTERNAL, ERR_R_MALLOC_FAILURE); + return (NULL); + } +#ifdef PURIFY + /* + * Valgrind complains in BN_consttime_swap because we process the whole + * array even if it's not initialised yet. This doesn't matter in that + * function - what's important is constant time operation (we're not + * actually going to use the data) + */ + memset(a, 0, sizeof(BN_ULONG) * words); +#endif + +#if 1 + B = b->d; + /* Check if the previous number needs to be copied */ + if (B != NULL) { + for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) { + /* + * The fact that the loop is unrolled + * 4-wise is a tribute to Intel. It's + * the one that doesn't have enough + * registers to accomodate more data. + * I'd unroll it 8-wise otherwise:-) + * + * + */ + BN_ULONG a0, a1, a2, a3; + a0 = B[0]; + a1 = B[1]; + a2 = B[2]; + a3 = B[3]; + A[0] = a0; + A[1] = a1; + A[2] = a2; + A[3] = a3; + } + /* + * workaround for ultrix cc: without 'case 0', the optimizer does + * the switch table by doing a=top&3; a--; goto jump_table[a]; + * which fails for top== 0 + */ + switch (b->top & 3) { + case 3: + A[2] = B[2]; + case 2: + A[1] = B[1]; + case 1: + A[0] = B[0]; + case 0: + ; + } + } +#else + memset(A, 0, sizeof(BN_ULONG) * words); + memcpy(A, b->d, sizeof(b->d[0]) * b->top); +#endif + + return (a); +} + +/* + * This is an internal function that can be used instead of bn_expand2() when + * there is a need to copy BIGNUMs instead of only expanding the data part, + * while still expanding them. Especially useful when needing to expand + * BIGNUMs that are declared 'const' and should therefore not be changed. The + * reason to use this instead of a BN_dup() followed by a bn_expand2() is + * memory allocation overhead. A BN_dup() followed by a bn_expand2() will + * allocate new memory for the BIGNUM data twice, and free it once, while + * bn_dup_expand() makes sure allocation is made only once. + */ + +#ifndef OPENSSL_NO_DEPRECATED +BIGNUM *bn_dup_expand(const BIGNUM *b, int words) +{ + BIGNUM *r = NULL; + + bn_check_top(b); + + /* + * This function does not work if words <= b->dmax && top < words because + * BN_dup() does not preserve 'dmax'! (But bn_dup_expand() is not used + * anywhere yet.) + */ + + if (words > b->dmax) { + BN_ULONG *a = bn_expand_internal(b, words); + + if (a) { + r = BN_new(); + if (r) { + r->top = b->top; + r->dmax = words; + r->neg = b->neg; + r->d = a; + } else { + /* r == NULL, BN_new failure */ + OPENSSL_free(a); + } + } + /* + * If a == NULL, there was an error in allocation in + * bn_expand_internal(), and NULL should be returned + */ + } else { + r = BN_dup(b); + } + + bn_check_top(r); + return r; +} +#endif + +/* + * This is an internal function that should not be used in applications. It + * ensures that 'b' has enough room for a 'words' word number and initialises + * any unused part of b->d with leading zeros. It is mostly used by the + * various BIGNUM routines. If there is an error, NULL is returned. If not, + * 'b' is returned. + */ + +BIGNUM *bn_expand2(BIGNUM *b, int words) +{ + bn_check_top(b); + + if (words > b->dmax) { + BN_ULONG *a = bn_expand_internal(b, words); + if (!a) + return NULL; + if (b->d) + OPENSSL_free(b->d); + b->d = a; + b->dmax = words; + } + +/* None of this should be necessary because of what b->top means! */ +#if 0 + /* + * NB: bn_wexpand() calls this only if the BIGNUM really has to grow + */ + if (b->top < b->dmax) { + int i; + BN_ULONG *A = &(b->d[b->top]); + for (i = (b->dmax - b->top) >> 3; i > 0; i--, A += 8) { + A[0] = 0; + A[1] = 0; + A[2] = 0; + A[3] = 0; + A[4] = 0; + A[5] = 0; + A[6] = 0; + A[7] = 0; + } + for (i = (b->dmax - b->top) & 7; i > 0; i--, A++) + A[0] = 0; + assert(A == &(b->d[b->dmax])); + } +#endif + bn_check_top(b); + return b; +} + +BIGNUM *BN_dup(const BIGNUM *a) +{ + BIGNUM *t; + + if (a == NULL) + return NULL; + bn_check_top(a); + + t = BN_new(); + if (t == NULL) + return NULL; + if (!BN_copy(t, a)) { + BN_free(t); + return NULL; + } + bn_check_top(t); + return t; +} + +BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b) +{ + int i; + BN_ULONG *A; + const BN_ULONG *B; + + bn_check_top(b); + + if (a == b) + return (a); + if (bn_wexpand(a, b->top) == NULL) + return (NULL); + +#if 1 + A = a->d; + B = b->d; + for (i = b->top >> 2; i > 0; i--, A += 4, B += 4) { + BN_ULONG a0, a1, a2, a3; + a0 = B[0]; + a1 = B[1]; + a2 = B[2]; + a3 = B[3]; + A[0] = a0; + A[1] = a1; + A[2] = a2; + A[3] = a3; + } + /* ultrix cc workaround, see comments in bn_expand_internal */ + switch (b->top & 3) { + case 3: + A[2] = B[2]; + case 2: + A[1] = B[1]; + case 1: + A[0] = B[0]; + case 0:; + } +#else + memcpy(a->d, b->d, sizeof(b->d[0]) * b->top); +#endif + + a->top = b->top; + a->neg = b->neg; + bn_check_top(a); + return (a); +} + +void BN_swap(BIGNUM *a, BIGNUM *b) +{ + int flags_old_a, flags_old_b; + BN_ULONG *tmp_d; + int tmp_top, tmp_dmax, tmp_neg; + + bn_check_top(a); + bn_check_top(b); + + flags_old_a = a->flags; + flags_old_b = b->flags; + + tmp_d = a->d; + tmp_top = a->top; + tmp_dmax = a->dmax; + tmp_neg = a->neg; + + a->d = b->d; + a->top = b->top; + a->dmax = b->dmax; + a->neg = b->neg; + + b->d = tmp_d; + b->top = tmp_top; + b->dmax = tmp_dmax; + b->neg = tmp_neg; + + a->flags = + (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA); + b->flags = + (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA); + bn_check_top(a); + bn_check_top(b); +} + +void BN_clear(BIGNUM *a) +{ + bn_check_top(a); + if (a->d != NULL) + memset(a->d, 0, a->dmax * sizeof(a->d[0])); + a->top = 0; + a->neg = 0; +} + +BN_ULONG BN_get_word(const BIGNUM *a) +{ + if (a->top > 1) + return BN_MASK2; + else if (a->top == 1) + return a->d[0]; + /* a->top == 0 */ + return 0; +} + +int BN_set_word(BIGNUM *a, BN_ULONG w) +{ + bn_check_top(a); + if (bn_expand(a, (int)sizeof(BN_ULONG) * 8) == NULL) + return (0); + a->neg = 0; + a->d[0] = w; + a->top = (w ? 1 : 0); + bn_check_top(a); + return (1); +} + +BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) +{ + unsigned int i, m; + unsigned int n; + BN_ULONG l; + BIGNUM *bn = NULL; + + if (ret == NULL) + ret = bn = BN_new(); + if (ret == NULL) + return (NULL); + bn_check_top(ret); + l = 0; + n = len; + if (n == 0) { + ret->top = 0; + return (ret); + } + i = ((n - 1) / BN_BYTES) + 1; + m = ((n - 1) % (BN_BYTES)); + if (bn_wexpand(ret, (int)i) == NULL) { + if (bn) + BN_free(bn); + return NULL; + } + ret->top = i; + ret->neg = 0; + while (n--) { + l = (l << 8L) | *(s++); + if (m-- == 0) { + ret->d[--i] = l; + l = 0; + m = BN_BYTES - 1; + } + } + /* + * need to call this due to clear byte at top if avoiding having the top + * bit set (-ve number) + */ + bn_correct_top(ret); + return (ret); +} + +/* ignore negative */ +int BN_bn2bin(const BIGNUM *a, unsigned char *to) +{ + int n, i; + BN_ULONG l; + + bn_check_top(a); + n = i = BN_num_bytes(a); + while (i--) { + l = a->d[i / BN_BYTES]; + *(to++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff; + } + return (n); +} + +int BN_ucmp(const BIGNUM *a, const BIGNUM *b) +{ + int i; + BN_ULONG t1, t2, *ap, *bp; + + bn_check_top(a); + bn_check_top(b); + + i = a->top - b->top; + if (i != 0) + return (i); + ap = a->d; + bp = b->d; + for (i = a->top - 1; i >= 0; i--) { + t1 = ap[i]; + t2 = bp[i]; + if (t1 != t2) + return ((t1 > t2) ? 1 : -1); + } + return (0); +} + +int BN_cmp(const BIGNUM *a, const BIGNUM *b) +{ + int i; + int gt, lt; + BN_ULONG t1, t2; + + if ((a == NULL) || (b == NULL)) { + if (a != NULL) + return (-1); + else if (b != NULL) + return (1); + else + return (0); + } + + bn_check_top(a); + bn_check_top(b); + + if (a->neg != b->neg) { + if (a->neg) + return (-1); + else + return (1); + } + if (a->neg == 0) { + gt = 1; + lt = -1; + } else { + gt = -1; + lt = 1; + } + + if (a->top > b->top) + return (gt); + if (a->top < b->top) + return (lt); + for (i = a->top - 1; i >= 0; i--) { + t1 = a->d[i]; + t2 = b->d[i]; + if (t1 > t2) + return (gt); + if (t1 < t2) + return (lt); + } + return (0); +} + +int BN_set_bit(BIGNUM *a, int n) +{ + int i, j, k; + + if (n < 0) + return 0; + + i = n / BN_BITS2; + j = n % BN_BITS2; + if (a->top <= i) { + if (bn_wexpand(a, i + 1) == NULL) + return (0); + for (k = a->top; k < i + 1; k++) + a->d[k] = 0; + a->top = i + 1; + } + + a->d[i] |= (((BN_ULONG)1) << j); + bn_check_top(a); + return (1); +} + +int BN_clear_bit(BIGNUM *a, int n) +{ + int i, j; + + bn_check_top(a); + if (n < 0) + return 0; + + i = n / BN_BITS2; + j = n % BN_BITS2; + if (a->top <= i) + return (0); + + a->d[i] &= (~(((BN_ULONG)1) << j)); + bn_correct_top(a); + return (1); +} + +int BN_is_bit_set(const BIGNUM *a, int n) +{ + int i, j; + + bn_check_top(a); + if (n < 0) + return 0; + i = n / BN_BITS2; + j = n % BN_BITS2; + if (a->top <= i) + return 0; + return (int)(((a->d[i]) >> j) & ((BN_ULONG)1)); +} + +int BN_mask_bits(BIGNUM *a, int n) +{ + int b, w; + + bn_check_top(a); + if (n < 0) + return 0; + + w = n / BN_BITS2; + b = n % BN_BITS2; + if (w >= a->top) + return 0; + if (b == 0) + a->top = w; + else { + a->top = w + 1; + a->d[w] &= ~(BN_MASK2 << b); + } + bn_correct_top(a); + return (1); +} + +void BN_set_negative(BIGNUM *a, int b) +{ + if (b && !BN_is_zero(a)) + a->neg = 1; + else + a->neg = 0; +} + +int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n) +{ + int i; + BN_ULONG aa, bb; + + aa = a[n - 1]; + bb = b[n - 1]; + if (aa != bb) + return ((aa > bb) ? 1 : -1); + for (i = n - 2; i >= 0; i--) { + aa = a[i]; + bb = b[i]; + if (aa != bb) + return ((aa > bb) ? 1 : -1); + } + return (0); +} + +/* + * Here follows a specialised variants of bn_cmp_words(). It has the + * property of performing the operation on arrays of different sizes. The + * sizes of those arrays is expressed through cl, which is the common length + * ( basicall, min(len(a),len(b)) ), and dl, which is the delta between the + * two lengths, calculated as len(a)-len(b). All lengths are the number of + * BN_ULONGs... + */ + +int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b, int cl, int dl) +{ + int n, i; + n = cl - 1; + + if (dl < 0) { + for (i = dl; i < 0; i++) { + if (b[n - i] != 0) + return -1; /* a < b */ + } + } + if (dl > 0) { + for (i = dl; i > 0; i--) { + if (a[n + i] != 0) + return 1; /* a > b */ + } + } + return bn_cmp_words(a, b, cl); +} + +/* + * Constant-time conditional swap of a and b. + * a and b are swapped if condition is not 0. The code assumes that at most one bit of condition is set. + * nwords is the number of words to swap. The code assumes that at least nwords are allocated in both a and b, + * and that no more than nwords are used by either a or b. + * a and b cannot be the same number + */ +void BN_consttime_swap(BN_ULONG condition, BIGNUM *a, BIGNUM *b, int nwords) +{ + BN_ULONG t; + int i; + + bn_wcheck_size(a, nwords); + bn_wcheck_size(b, nwords); + + assert(a != b); + assert((condition & (condition - 1)) == 0); + assert(sizeof(BN_ULONG) >= sizeof(int)); + + condition = ((condition - 1) >> (BN_BITS2 - 1)) - 1; + + t = (a->top ^ b->top) & condition; + a->top ^= t; + b->top ^= t; + +#define BN_CONSTTIME_SWAP(ind) \ + do { \ + t = (a->d[ind] ^ b->d[ind]) & condition; \ + a->d[ind] ^= t; \ + b->d[ind] ^= t; \ + } while (0) + + switch (nwords) { + default: + for (i = 10; i < nwords; i++) + BN_CONSTTIME_SWAP(i); + /* Fallthrough */ + case 10: + BN_CONSTTIME_SWAP(9); /* Fallthrough */ + case 9: + BN_CONSTTIME_SWAP(8); /* Fallthrough */ + case 8: + BN_CONSTTIME_SWAP(7); /* Fallthrough */ + case 7: + BN_CONSTTIME_SWAP(6); /* Fallthrough */ + case 6: + BN_CONSTTIME_SWAP(5); /* Fallthrough */ + case 5: + BN_CONSTTIME_SWAP(4); /* Fallthrough */ + case 4: + BN_CONSTTIME_SWAP(3); /* Fallthrough */ + case 3: + BN_CONSTTIME_SWAP(2); /* Fallthrough */ + case 2: + BN_CONSTTIME_SWAP(1); /* Fallthrough */ + case 1: + BN_CONSTTIME_SWAP(0); + } +#undef BN_CONSTTIME_SWAP +} diff --git a/libs/openssl/crypto/bn/bn_mod.c b/libs/openssl/crypto/bn/bn_mod.c new file mode 100644 index 00000000..ffbce890 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_mod.c @@ -0,0 +1,316 @@ +/* crypto/bn/bn_mod.c */ +/* + * Includes code written by Lenka Fibikova + * for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "cryptlib.h" +#include "bn_lcl.h" + +#if 0 /* now just a #define */ +int BN_mod(BIGNUM *rem, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) +{ + return (BN_div(NULL, rem, m, d, ctx)); + /* note that rem->neg == m->neg (unless the remainder is zero) */ +} +#endif + +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) +{ + /* + * like BN_mod, but returns non-negative remainder (i.e., 0 <= r < |d| + * always holds) + */ + + if (!(BN_mod(r, m, d, ctx))) + return 0; + if (!r->neg) + return 1; + /* now -|d| < r < 0, so we have to set r := r + |d| */ + return (d->neg ? BN_sub : BN_add) (r, r, d); +} + +int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx) +{ + if (!BN_add(r, a, b)) + return 0; + return BN_nnmod(r, r, m, ctx); +} + +/* + * BN_mod_add variant that may be used if both a and b are non-negative and + * less than m + */ +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) +{ + if (!BN_uadd(r, a, b)) + return 0; + if (BN_ucmp(r, m) >= 0) + return BN_usub(r, r, m); + return 1; +} + +int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx) +{ + if (!BN_sub(r, a, b)) + return 0; + return BN_nnmod(r, r, m, ctx); +} + +/* + * BN_mod_sub variant that may be used if both a and b are non-negative and + * less than m + */ +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) +{ + if (!BN_sub(r, a, b)) + return 0; + if (r->neg) + return BN_add(r, r, m); + return 1; +} + +/* slow but works */ +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx) +{ + BIGNUM *t; + int ret = 0; + + bn_check_top(a); + bn_check_top(b); + bn_check_top(m); + + BN_CTX_start(ctx); + if ((t = BN_CTX_get(ctx)) == NULL) + goto err; + if (a == b) { + if (!BN_sqr(t, a, ctx)) + goto err; + } else { + if (!BN_mul(t, a, b, ctx)) + goto err; + } + if (!BN_nnmod(r, t, m, ctx)) + goto err; + bn_check_top(r); + ret = 1; + err: + BN_CTX_end(ctx); + return (ret); +} + +int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) +{ + if (!BN_sqr(r, a, ctx)) + return 0; + /* r->neg == 0, thus we don't need BN_nnmod */ + return BN_mod(r, r, m, ctx); +} + +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) +{ + if (!BN_lshift1(r, a)) + return 0; + bn_check_top(r); + return BN_nnmod(r, r, m, ctx); +} + +/* + * BN_mod_lshift1 variant that may be used if a is non-negative and less than + * m + */ +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) +{ + if (!BN_lshift1(r, a)) + return 0; + bn_check_top(r); + if (BN_cmp(r, m) >= 0) + return BN_sub(r, r, m); + return 1; +} + +int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx) +{ + BIGNUM *abs_m = NULL; + int ret; + + if (!BN_nnmod(r, a, m, ctx)) + return 0; + + if (m->neg) { + abs_m = BN_dup(m); + if (abs_m == NULL) + return 0; + abs_m->neg = 0; + } + + ret = BN_mod_lshift_quick(r, r, n, (abs_m ? abs_m : m)); + bn_check_top(r); + + if (abs_m) + BN_free(abs_m); + return ret; +} + +/* + * BN_mod_lshift variant that may be used if a is non-negative and less than + * m + */ +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) +{ + if (r != a) { + if (BN_copy(r, a) == NULL) + return 0; + } + + while (n > 0) { + int max_shift; + + /* 0 < r < m */ + max_shift = BN_num_bits(m) - BN_num_bits(r); + /* max_shift >= 0 */ + + if (max_shift < 0) { + BNerr(BN_F_BN_MOD_LSHIFT_QUICK, BN_R_INPUT_NOT_REDUCED); + return 0; + } + + if (max_shift > n) + max_shift = n; + + if (max_shift) { + if (!BN_lshift(r, r, max_shift)) + return 0; + n -= max_shift; + } else { + if (!BN_lshift1(r, r)) + return 0; + --n; + } + + /* BN_num_bits(r) <= BN_num_bits(m) */ + + if (BN_cmp(r, m) >= 0) { + if (!BN_sub(r, r, m)) + return 0; + } + } + bn_check_top(r); + + return 1; +} diff --git a/libs/openssl/crypto/bn/bn_mont.c b/libs/openssl/crypto/bn/bn_mont.c new file mode 100644 index 00000000..be95bd55 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_mont.c @@ -0,0 +1,558 @@ +/* crypto/bn/bn_mont.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Details about Montgomery multiplication algorithms can be found at + * http://security.ece.orst.edu/publications.html, e.g. + * http://security.ece.orst.edu/koc/papers/j37acmon.pdf and + * sections 3.8 and 4.2 in http://security.ece.orst.edu/koc/papers/r01rsasw.pdf + */ + +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +#define MONT_WORD /* use the faster word-based algorithm */ + +#ifdef MONT_WORD +static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont); +#endif + +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_MONT_CTX *mont, BN_CTX *ctx) +{ + BIGNUM *tmp; + int ret = 0; +#if defined(OPENSSL_BN_ASM_MONT) && defined(MONT_WORD) + int num = mont->N.top; + + if (num > 1 && a->top == num && b->top == num) { + if (bn_wexpand(r, num) == NULL) + return (0); + if (bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { + r->neg = a->neg ^ b->neg; + r->top = num; + bn_correct_top(r); + return (1); + } + } +#endif + + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + if (tmp == NULL) + goto err; + + bn_check_top(tmp); + if (a == b) { + if (!BN_sqr(tmp, a, ctx)) + goto err; + } else { + if (!BN_mul(tmp, a, b, ctx)) + goto err; + } + /* reduce from aRR to aR */ +#ifdef MONT_WORD + if (!BN_from_montgomery_word(r, tmp, mont)) + goto err; +#else + if (!BN_from_montgomery(r, tmp, mont, ctx)) + goto err; +#endif + bn_check_top(r); + ret = 1; + err: + BN_CTX_end(ctx); + return (ret); +} + +#ifdef MONT_WORD +static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, BN_MONT_CTX *mont) +{ + BIGNUM *n; + BN_ULONG *ap, *np, *rp, n0, v, carry; + int nl, max, i; + + n = &(mont->N); + nl = n->top; + if (nl == 0) { + ret->top = 0; + return (1); + } + + max = (2 * nl); /* carry is stored separately */ + if (bn_wexpand(r, max) == NULL) + return (0); + + r->neg ^= n->neg; + np = n->d; + rp = r->d; + + /* clear the top words of T */ +# if 1 + for (i = r->top; i < max; i++) /* memset? XXX */ + rp[i] = 0; +# else + memset(&(rp[r->top]), 0, (max - r->top) * sizeof(BN_ULONG)); +# endif + + r->top = max; + n0 = mont->n0[0]; + +# ifdef BN_COUNT + fprintf(stderr, "word BN_from_montgomery_word %d * %d\n", nl, nl); +# endif + for (carry = 0, i = 0; i < nl; i++, rp++) { +# ifdef __TANDEM + { + long long t1; + long long t2; + long long t3; + t1 = rp[0] * (n0 & 0177777); + t2 = 037777600000l; + t2 = n0 & t2; + t3 = rp[0] & 0177777; + t2 = (t3 * t2) & BN_MASK2; + t1 = t1 + t2; + v = bn_mul_add_words(rp, np, nl, (BN_ULONG)t1); + } +# else + v = bn_mul_add_words(rp, np, nl, (rp[0] * n0) & BN_MASK2); +# endif + v = (v + carry + rp[nl]) & BN_MASK2; + carry |= (v != rp[nl]); + carry &= (v <= rp[nl]); + rp[nl] = v; + } + + if (bn_wexpand(ret, nl) == NULL) + return (0); + ret->top = nl; + ret->neg = r->neg; + + rp = ret->d; + ap = &(r->d[nl]); + +# define BRANCH_FREE 1 +# if BRANCH_FREE + { + BN_ULONG *nrp; + size_t m; + + v = bn_sub_words(rp, ap, np, nl) - carry; + /* + * if subtraction result is real, then trick unconditional memcpy + * below to perform in-place "refresh" instead of actual copy. + */ + m = (0 - (size_t)v); + nrp = + (BN_ULONG *)(((PTR_SIZE_INT) rp & ~m) | ((PTR_SIZE_INT) ap & m)); + + for (i = 0, nl -= 4; i < nl; i += 4) { + BN_ULONG t1, t2, t3, t4; + + t1 = nrp[i + 0]; + t2 = nrp[i + 1]; + t3 = nrp[i + 2]; + ap[i + 0] = 0; + t4 = nrp[i + 3]; + ap[i + 1] = 0; + rp[i + 0] = t1; + ap[i + 2] = 0; + rp[i + 1] = t2; + ap[i + 3] = 0; + rp[i + 2] = t3; + rp[i + 3] = t4; + } + for (nl += 4; i < nl; i++) + rp[i] = nrp[i], ap[i] = 0; + } +# else + if (bn_sub_words(rp, ap, np, nl) - carry) + memcpy(rp, ap, nl * sizeof(BN_ULONG)); +# endif + bn_correct_top(r); + bn_correct_top(ret); + bn_check_top(ret); + + return (1); +} +#endif /* MONT_WORD */ + +int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, BN_MONT_CTX *mont, + BN_CTX *ctx) +{ + int retn = 0; +#ifdef MONT_WORD + BIGNUM *t; + + BN_CTX_start(ctx); + if ((t = BN_CTX_get(ctx)) && BN_copy(t, a)) + retn = BN_from_montgomery_word(ret, t, mont); + BN_CTX_end(ctx); +#else /* !MONT_WORD */ + BIGNUM *t1, *t2; + + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + t2 = BN_CTX_get(ctx); + if (t1 == NULL || t2 == NULL) + goto err; + + if (!BN_copy(t1, a)) + goto err; + BN_mask_bits(t1, mont->ri); + + if (!BN_mul(t2, t1, &mont->Ni, ctx)) + goto err; + BN_mask_bits(t2, mont->ri); + + if (!BN_mul(t1, t2, &mont->N, ctx)) + goto err; + if (!BN_add(t2, a, t1)) + goto err; + if (!BN_rshift(ret, t2, mont->ri)) + goto err; + + if (BN_ucmp(ret, &(mont->N)) >= 0) { + if (!BN_usub(ret, ret, &(mont->N))) + goto err; + } + retn = 1; + bn_check_top(ret); + err: + BN_CTX_end(ctx); +#endif /* MONT_WORD */ + return (retn); +} + +BN_MONT_CTX *BN_MONT_CTX_new(void) +{ + BN_MONT_CTX *ret; + + if ((ret = (BN_MONT_CTX *)OPENSSL_malloc(sizeof(BN_MONT_CTX))) == NULL) + return (NULL); + + BN_MONT_CTX_init(ret); + ret->flags = BN_FLG_MALLOCED; + return (ret); +} + +void BN_MONT_CTX_init(BN_MONT_CTX *ctx) +{ + ctx->ri = 0; + BN_init(&(ctx->RR)); + BN_init(&(ctx->N)); + BN_init(&(ctx->Ni)); + ctx->n0[0] = ctx->n0[1] = 0; + ctx->flags = 0; +} + +void BN_MONT_CTX_free(BN_MONT_CTX *mont) +{ + if (mont == NULL) + return; + + BN_clear_free(&(mont->RR)); + BN_clear_free(&(mont->N)); + BN_clear_free(&(mont->Ni)); + if (mont->flags & BN_FLG_MALLOCED) + OPENSSL_free(mont); +} + +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *Ri, *R; + + if (BN_is_zero(mod)) + return 0; + + BN_CTX_start(ctx); + if ((Ri = BN_CTX_get(ctx)) == NULL) + goto err; + R = &(mont->RR); /* grab RR as a temp */ + if (!BN_copy(&(mont->N), mod)) + goto err; /* Set N */ + mont->N.neg = 0; + +#ifdef MONT_WORD + { + BIGNUM tmod; + BN_ULONG buf[2]; + + BN_init(&tmod); + tmod.d = buf; + tmod.dmax = 2; + tmod.neg = 0; + + mont->ri = (BN_num_bits(mod) + (BN_BITS2 - 1)) / BN_BITS2 * BN_BITS2; + +# if defined(OPENSSL_BN_ASM_MONT) && (BN_BITS2<=32) + /* + * Only certain BN_BITS2<=32 platforms actually make use of n0[1], + * and we could use the #else case (with a shorter R value) for the + * others. However, currently only the assembler files do know which + * is which. + */ + + BN_zero(R); + if (!(BN_set_bit(R, 2 * BN_BITS2))) + goto err; + + tmod.top = 0; + if ((buf[0] = mod->d[0])) + tmod.top = 1; + if ((buf[1] = mod->top > 1 ? mod->d[1] : 0)) + tmod.top = 2; + + if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL) + goto err; + if (!BN_lshift(Ri, Ri, 2 * BN_BITS2)) + goto err; /* R*Ri */ + if (!BN_is_zero(Ri)) { + if (!BN_sub_word(Ri, 1)) + goto err; + } else { /* if N mod word size == 1 */ + + if (bn_expand(Ri, (int)sizeof(BN_ULONG) * 2) == NULL) + goto err; + /* Ri-- (mod double word size) */ + Ri->neg = 0; + Ri->d[0] = BN_MASK2; + Ri->d[1] = BN_MASK2; + Ri->top = 2; + } + if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) + goto err; + /* + * Ni = (R*Ri-1)/N, keep only couple of least significant words: + */ + mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; + mont->n0[1] = (Ri->top > 1) ? Ri->d[1] : 0; +# else + BN_zero(R); + if (!(BN_set_bit(R, BN_BITS2))) + goto err; /* R */ + + buf[0] = mod->d[0]; /* tmod = N mod word size */ + buf[1] = 0; + tmod.top = buf[0] != 0 ? 1 : 0; + /* Ri = R^-1 mod N */ + if ((BN_mod_inverse(Ri, R, &tmod, ctx)) == NULL) + goto err; + if (!BN_lshift(Ri, Ri, BN_BITS2)) + goto err; /* R*Ri */ + if (!BN_is_zero(Ri)) { + if (!BN_sub_word(Ri, 1)) + goto err; + } else { /* if N mod word size == 1 */ + + if (!BN_set_word(Ri, BN_MASK2)) + goto err; /* Ri-- (mod word size) */ + } + if (!BN_div(Ri, NULL, Ri, &tmod, ctx)) + goto err; + /* + * Ni = (R*Ri-1)/N, keep only least significant word: + */ + mont->n0[0] = (Ri->top > 0) ? Ri->d[0] : 0; + mont->n0[1] = 0; +# endif + } +#else /* !MONT_WORD */ + { /* bignum version */ + mont->ri = BN_num_bits(&mont->N); + BN_zero(R); + if (!BN_set_bit(R, mont->ri)) + goto err; /* R = 2^ri */ + /* Ri = R^-1 mod N */ + if ((BN_mod_inverse(Ri, R, &mont->N, ctx)) == NULL) + goto err; + if (!BN_lshift(Ri, Ri, mont->ri)) + goto err; /* R*Ri */ + if (!BN_sub_word(Ri, 1)) + goto err; + /* + * Ni = (R*Ri-1) / N + */ + if (!BN_div(&(mont->Ni), NULL, Ri, &mont->N, ctx)) + goto err; + } +#endif + + /* setup RR for conversions */ + BN_zero(&(mont->RR)); + if (!BN_set_bit(&(mont->RR), mont->ri * 2)) + goto err; + if (!BN_mod(&(mont->RR), &(mont->RR), &(mont->N), ctx)) + goto err; + + ret = 1; + err: + BN_CTX_end(ctx); + return ret; +} + +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, BN_MONT_CTX *from) +{ + if (to == from) + return (to); + + if (!BN_copy(&(to->RR), &(from->RR))) + return NULL; + if (!BN_copy(&(to->N), &(from->N))) + return NULL; + if (!BN_copy(&(to->Ni), &(from->Ni))) + return NULL; + to->ri = from->ri; + to->n0[0] = from->n0[0]; + to->n0[1] = from->n0[1]; + return (to); +} + +BN_MONT_CTX *BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, int lock, + const BIGNUM *mod, BN_CTX *ctx) +{ + BN_MONT_CTX *ret; + + CRYPTO_r_lock(lock); + ret = *pmont; + CRYPTO_r_unlock(lock); + if (ret) + return ret; + + /* + * We don't want to serialise globally while doing our lazy-init math in + * BN_MONT_CTX_set. That punishes threads that are doing independent + * things. Instead, punish the case where more than one thread tries to + * lazy-init the same 'pmont', by having each do the lazy-init math work + * independently and only use the one from the thread that wins the race + * (the losers throw away the work they've done). + */ + ret = BN_MONT_CTX_new(); + if (!ret) + return NULL; + if (!BN_MONT_CTX_set(ret, mod, ctx)) { + BN_MONT_CTX_free(ret); + return NULL; + } + + /* The locked compare-and-set, after the local work is done. */ + CRYPTO_w_lock(lock); + if (*pmont) { + BN_MONT_CTX_free(ret); + ret = *pmont; + } else + *pmont = ret; + CRYPTO_w_unlock(lock); + return ret; +} diff --git a/libs/openssl/crypto/bn/bn_mpi.c b/libs/openssl/crypto/bn/bn_mpi.c new file mode 100644 index 00000000..3bd40bbd --- /dev/null +++ b/libs/openssl/crypto/bn/bn_mpi.c @@ -0,0 +1,128 @@ +/* crypto/bn/bn_mpi.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +int BN_bn2mpi(const BIGNUM *a, unsigned char *d) +{ + int bits; + int num = 0; + int ext = 0; + long l; + + bits = BN_num_bits(a); + num = (bits + 7) / 8; + if (bits > 0) { + ext = ((bits & 0x07) == 0); + } + if (d == NULL) + return (num + 4 + ext); + + l = num + ext; + d[0] = (unsigned char)(l >> 24) & 0xff; + d[1] = (unsigned char)(l >> 16) & 0xff; + d[2] = (unsigned char)(l >> 8) & 0xff; + d[3] = (unsigned char)(l) & 0xff; + if (ext) + d[4] = 0; + num = BN_bn2bin(a, &(d[4 + ext])); + if (a->neg) + d[4] |= 0x80; + return (num + 4 + ext); +} + +BIGNUM *BN_mpi2bn(const unsigned char *d, int n, BIGNUM *a) +{ + long len; + int neg = 0; + + if (n < 4) { + BNerr(BN_F_BN_MPI2BN, BN_R_INVALID_LENGTH); + return (NULL); + } + len = ((long)d[0] << 24) | ((long)d[1] << 16) | ((int)d[2] << 8) | (int) + d[3]; + if ((len + 4) != n) { + BNerr(BN_F_BN_MPI2BN, BN_R_ENCODING_ERROR); + return (NULL); + } + + if (a == NULL) + a = BN_new(); + if (a == NULL) + return (NULL); + + if (len == 0) { + a->neg = 0; + a->top = 0; + return (a); + } + d += 4; + if ((*d) & 0x80) + neg = 1; + if (BN_bin2bn(d, (int)len, a) == NULL) + return (NULL); + a->neg = neg; + if (neg) { + BN_clear_bit(a, BN_num_bits(a) - 1); + } + bn_check_top(a); + return (a); +} diff --git a/libs/openssl/crypto/bn/bn_mul.c b/libs/openssl/crypto/bn/bn_mul.c new file mode 100644 index 00000000..b174850b --- /dev/null +++ b/libs/openssl/crypto/bn/bn_mul.c @@ -0,0 +1,1164 @@ +/* crypto/bn/bn_mul.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef BN_DEBUG +# undef NDEBUG /* avoid conflicting definitions */ +# define NDEBUG +#endif + +#include +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +#if defined(OPENSSL_NO_ASM) || !defined(OPENSSL_BN_ASM_PART_WORDS) +/* + * Here follows specialised variants of bn_add_words() and bn_sub_words(). + * They have the property performing operations on arrays of different sizes. + * The sizes of those arrays is expressed through cl, which is the common + * length ( basicall, min(len(a),len(b)) ), and dl, which is the delta + * between the two lengths, calculated as len(a)-len(b). All lengths are the + * number of BN_ULONGs... For the operations that require a result array as + * parameter, it must have the length cl+abs(dl). These functions should + * probably end up in bn_asm.c as soon as there are assembler counterparts + * for the systems that use assembler files. + */ + +BN_ULONG bn_sub_part_words(BN_ULONG *r, + const BN_ULONG *a, const BN_ULONG *b, + int cl, int dl) +{ + BN_ULONG c, t; + + assert(cl >= 0); + c = bn_sub_words(r, a, b, cl); + + if (dl == 0) + return c; + + r += cl; + a += cl; + b += cl; + + if (dl < 0) { +# ifdef BN_COUNT + fprintf(stderr, " bn_sub_part_words %d + %d (dl < 0, c = %d)\n", cl, + dl, c); +# endif + for (;;) { + t = b[0]; + r[0] = (0 - t - c) & BN_MASK2; + if (t != 0) + c = 1; + if (++dl >= 0) + break; + + t = b[1]; + r[1] = (0 - t - c) & BN_MASK2; + if (t != 0) + c = 1; + if (++dl >= 0) + break; + + t = b[2]; + r[2] = (0 - t - c) & BN_MASK2; + if (t != 0) + c = 1; + if (++dl >= 0) + break; + + t = b[3]; + r[3] = (0 - t - c) & BN_MASK2; + if (t != 0) + c = 1; + if (++dl >= 0) + break; + + b += 4; + r += 4; + } + } else { + int save_dl = dl; +# ifdef BN_COUNT + fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c = %d)\n", cl, + dl, c); +# endif + while (c) { + t = a[0]; + r[0] = (t - c) & BN_MASK2; + if (t != 0) + c = 0; + if (--dl <= 0) + break; + + t = a[1]; + r[1] = (t - c) & BN_MASK2; + if (t != 0) + c = 0; + if (--dl <= 0) + break; + + t = a[2]; + r[2] = (t - c) & BN_MASK2; + if (t != 0) + c = 0; + if (--dl <= 0) + break; + + t = a[3]; + r[3] = (t - c) & BN_MASK2; + if (t != 0) + c = 0; + if (--dl <= 0) + break; + + save_dl = dl; + a += 4; + r += 4; + } + if (dl > 0) { +# ifdef BN_COUNT + fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, c == 0)\n", + cl, dl); +# endif + if (save_dl > dl) { + switch (save_dl - dl) { + case 1: + r[1] = a[1]; + if (--dl <= 0) + break; + case 2: + r[2] = a[2]; + if (--dl <= 0) + break; + case 3: + r[3] = a[3]; + if (--dl <= 0) + break; + } + a += 4; + r += 4; + } + } + if (dl > 0) { +# ifdef BN_COUNT + fprintf(stderr, " bn_sub_part_words %d + %d (dl > 0, copy)\n", + cl, dl); +# endif + for (;;) { + r[0] = a[0]; + if (--dl <= 0) + break; + r[1] = a[1]; + if (--dl <= 0) + break; + r[2] = a[2]; + if (--dl <= 0) + break; + r[3] = a[3]; + if (--dl <= 0) + break; + + a += 4; + r += 4; + } + } + } + return c; +} +#endif + +BN_ULONG bn_add_part_words(BN_ULONG *r, + const BN_ULONG *a, const BN_ULONG *b, + int cl, int dl) +{ + BN_ULONG c, l, t; + + assert(cl >= 0); + c = bn_add_words(r, a, b, cl); + + if (dl == 0) + return c; + + r += cl; + a += cl; + b += cl; + + if (dl < 0) { + int save_dl = dl; +#ifdef BN_COUNT + fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c = %d)\n", cl, + dl, c); +#endif + while (c) { + l = (c + b[0]) & BN_MASK2; + c = (l < c); + r[0] = l; + if (++dl >= 0) + break; + + l = (c + b[1]) & BN_MASK2; + c = (l < c); + r[1] = l; + if (++dl >= 0) + break; + + l = (c + b[2]) & BN_MASK2; + c = (l < c); + r[2] = l; + if (++dl >= 0) + break; + + l = (c + b[3]) & BN_MASK2; + c = (l < c); + r[3] = l; + if (++dl >= 0) + break; + + save_dl = dl; + b += 4; + r += 4; + } + if (dl < 0) { +#ifdef BN_COUNT + fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, c == 0)\n", + cl, dl); +#endif + if (save_dl < dl) { + switch (dl - save_dl) { + case 1: + r[1] = b[1]; + if (++dl >= 0) + break; + case 2: + r[2] = b[2]; + if (++dl >= 0) + break; + case 3: + r[3] = b[3]; + if (++dl >= 0) + break; + } + b += 4; + r += 4; + } + } + if (dl < 0) { +#ifdef BN_COUNT + fprintf(stderr, " bn_add_part_words %d + %d (dl < 0, copy)\n", + cl, dl); +#endif + for (;;) { + r[0] = b[0]; + if (++dl >= 0) + break; + r[1] = b[1]; + if (++dl >= 0) + break; + r[2] = b[2]; + if (++dl >= 0) + break; + r[3] = b[3]; + if (++dl >= 0) + break; + + b += 4; + r += 4; + } + } + } else { + int save_dl = dl; +#ifdef BN_COUNT + fprintf(stderr, " bn_add_part_words %d + %d (dl > 0)\n", cl, dl); +#endif + while (c) { + t = (a[0] + c) & BN_MASK2; + c = (t < c); + r[0] = t; + if (--dl <= 0) + break; + + t = (a[1] + c) & BN_MASK2; + c = (t < c); + r[1] = t; + if (--dl <= 0) + break; + + t = (a[2] + c) & BN_MASK2; + c = (t < c); + r[2] = t; + if (--dl <= 0) + break; + + t = (a[3] + c) & BN_MASK2; + c = (t < c); + r[3] = t; + if (--dl <= 0) + break; + + save_dl = dl; + a += 4; + r += 4; + } +#ifdef BN_COUNT + fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, c == 0)\n", cl, + dl); +#endif + if (dl > 0) { + if (save_dl > dl) { + switch (save_dl - dl) { + case 1: + r[1] = a[1]; + if (--dl <= 0) + break; + case 2: + r[2] = a[2]; + if (--dl <= 0) + break; + case 3: + r[3] = a[3]; + if (--dl <= 0) + break; + } + a += 4; + r += 4; + } + } + if (dl > 0) { +#ifdef BN_COUNT + fprintf(stderr, " bn_add_part_words %d + %d (dl > 0, copy)\n", + cl, dl); +#endif + for (;;) { + r[0] = a[0]; + if (--dl <= 0) + break; + r[1] = a[1]; + if (--dl <= 0) + break; + r[2] = a[2]; + if (--dl <= 0) + break; + r[3] = a[3]; + if (--dl <= 0) + break; + + a += 4; + r += 4; + } + } + } + return c; +} + +#ifdef BN_RECURSION +/* + * Karatsuba recursive multiplication algorithm (cf. Knuth, The Art of + * Computer Programming, Vol. 2) + */ + +/*- + * r is 2*n2 words in size, + * a and b are both n2 words in size. + * n2 must be a power of 2. + * We multiply and return the result. + * t must be 2*n2 words in size + * We calculate + * a[0]*b[0] + * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0]) + * a[1]*b[1] + */ +/* dnX may not be positive, but n2/2+dnX has to be */ +void bn_mul_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, + int dna, int dnb, BN_ULONG *t) +{ + int n = n2 / 2, c1, c2; + int tna = n + dna, tnb = n + dnb; + unsigned int neg, zero; + BN_ULONG ln, lo, *p; + +# ifdef BN_COUNT + fprintf(stderr, " bn_mul_recursive %d%+d * %d%+d\n", n2, dna, n2, dnb); +# endif +# ifdef BN_MUL_COMBA +# if 0 + if (n2 == 4) { + bn_mul_comba4(r, a, b); + return; + } +# endif + /* + * Only call bn_mul_comba 8 if n2 == 8 and the two arrays are complete + * [steve] + */ + if (n2 == 8 && dna == 0 && dnb == 0) { + bn_mul_comba8(r, a, b); + return; + } +# endif /* BN_MUL_COMBA */ + /* Else do normal multiply */ + if (n2 < BN_MUL_RECURSIVE_SIZE_NORMAL) { + bn_mul_normal(r, a, n2 + dna, b, n2 + dnb); + if ((dna + dnb) < 0) + memset(&r[2 * n2 + dna + dnb], 0, + sizeof(BN_ULONG) * -(dna + dnb)); + return; + } + /* r=(a[0]-a[1])*(b[1]-b[0]) */ + c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna); + c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n); + zero = neg = 0; + switch (c1 * 3 + c2) { + case -4: + bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */ + bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */ + break; + case -3: + zero = 1; + break; + case -2: + bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */ + bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */ + neg = 1; + break; + case -1: + case 0: + case 1: + zero = 1; + break; + case 2: + bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */ + bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */ + neg = 1; + break; + case 3: + zero = 1; + break; + case 4: + bn_sub_part_words(t, a, &(a[n]), tna, n - tna); + bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); + break; + } + +# ifdef BN_MUL_COMBA + if (n == 4 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba4 could take + * extra args to do this well */ + if (!zero) + bn_mul_comba4(&(t[n2]), t, &(t[n])); + else + memset(&(t[n2]), 0, 8 * sizeof(BN_ULONG)); + + bn_mul_comba4(r, a, b); + bn_mul_comba4(&(r[n2]), &(a[n]), &(b[n])); + } else if (n == 8 && dna == 0 && dnb == 0) { /* XXX: bn_mul_comba8 could + * take extra args to do + * this well */ + if (!zero) + bn_mul_comba8(&(t[n2]), t, &(t[n])); + else + memset(&(t[n2]), 0, 16 * sizeof(BN_ULONG)); + + bn_mul_comba8(r, a, b); + bn_mul_comba8(&(r[n2]), &(a[n]), &(b[n])); + } else +# endif /* BN_MUL_COMBA */ + { + p = &(t[n2 * 2]); + if (!zero) + bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p); + else + memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG)); + bn_mul_recursive(r, a, b, n, 0, 0, p); + bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), n, dna, dnb, p); + } + + /*- + * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign + * r[10] holds (a[0]*b[0]) + * r[32] holds (b[1]*b[1]) + */ + + c1 = (int)(bn_add_words(t, r, &(r[n2]), n2)); + + if (neg) { /* if t[32] is negative */ + c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2)); + } else { + /* Might have a carry */ + c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2)); + } + + /*- + * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1]) + * r[10] holds (a[0]*b[0]) + * r[32] holds (b[1]*b[1]) + * c1 holds the carry bits + */ + c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2)); + if (c1) { + p = &(r[n + n2]); + lo = *p; + ln = (lo + c1) & BN_MASK2; + *p = ln; + + /* + * The overflow will stop before we over write words we should not + * overwrite + */ + if (ln < (BN_ULONG)c1) { + do { + p++; + lo = *p; + ln = (lo + 1) & BN_MASK2; + *p = ln; + } while (ln == 0); + } + } +} + +/* + * n+tn is the word length t needs to be n*4 is size, as does r + */ +/* tnX may not be negative but less than n */ +void bn_mul_part_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n, + int tna, int tnb, BN_ULONG *t) +{ + int i, j, n2 = n * 2; + int c1, c2, neg; + BN_ULONG ln, lo, *p; + +# ifdef BN_COUNT + fprintf(stderr, " bn_mul_part_recursive (%d%+d) * (%d%+d)\n", + n, tna, n, tnb); +# endif + if (n < 8) { + bn_mul_normal(r, a, n + tna, b, n + tnb); + return; + } + + /* r=(a[0]-a[1])*(b[1]-b[0]) */ + c1 = bn_cmp_part_words(a, &(a[n]), tna, n - tna); + c2 = bn_cmp_part_words(&(b[n]), b, tnb, tnb - n); + neg = 0; + switch (c1 * 3 + c2) { + case -4: + bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */ + bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */ + break; + case -3: + /* break; */ + case -2: + bn_sub_part_words(t, &(a[n]), a, tna, tna - n); /* - */ + bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); /* + */ + neg = 1; + break; + case -1: + case 0: + case 1: + /* break; */ + case 2: + bn_sub_part_words(t, a, &(a[n]), tna, n - tna); /* + */ + bn_sub_part_words(&(t[n]), b, &(b[n]), tnb, n - tnb); /* - */ + neg = 1; + break; + case 3: + /* break; */ + case 4: + bn_sub_part_words(t, a, &(a[n]), tna, n - tna); + bn_sub_part_words(&(t[n]), &(b[n]), b, tnb, tnb - n); + break; + } + /* + * The zero case isn't yet implemented here. The speedup would probably + * be negligible. + */ +# if 0 + if (n == 4) { + bn_mul_comba4(&(t[n2]), t, &(t[n])); + bn_mul_comba4(r, a, b); + bn_mul_normal(&(r[n2]), &(a[n]), tn, &(b[n]), tn); + memset(&(r[n2 + tn * 2]), 0, sizeof(BN_ULONG) * (n2 - tn * 2)); + } else +# endif + if (n == 8) { + bn_mul_comba8(&(t[n2]), t, &(t[n])); + bn_mul_comba8(r, a, b); + bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb); + memset(&(r[n2 + tna + tnb]), 0, sizeof(BN_ULONG) * (n2 - tna - tnb)); + } else { + p = &(t[n2 * 2]); + bn_mul_recursive(&(t[n2]), t, &(t[n]), n, 0, 0, p); + bn_mul_recursive(r, a, b, n, 0, 0, p); + i = n / 2; + /* + * If there is only a bottom half to the number, just do it + */ + if (tna > tnb) + j = tna - i; + else + j = tnb - i; + if (j == 0) { + bn_mul_recursive(&(r[n2]), &(a[n]), &(b[n]), + i, tna - i, tnb - i, p); + memset(&(r[n2 + i * 2]), 0, sizeof(BN_ULONG) * (n2 - i * 2)); + } else if (j > 0) { /* eg, n == 16, i == 8 and tn == 11 */ + bn_mul_part_recursive(&(r[n2]), &(a[n]), &(b[n]), + i, tna - i, tnb - i, p); + memset(&(r[n2 + tna + tnb]), 0, + sizeof(BN_ULONG) * (n2 - tna - tnb)); + } else { /* (j < 0) eg, n == 16, i == 8 and tn == 5 */ + + memset(&(r[n2]), 0, sizeof(BN_ULONG) * n2); + if (tna < BN_MUL_RECURSIVE_SIZE_NORMAL + && tnb < BN_MUL_RECURSIVE_SIZE_NORMAL) { + bn_mul_normal(&(r[n2]), &(a[n]), tna, &(b[n]), tnb); + } else { + for (;;) { + i /= 2; + /* + * these simplified conditions work exclusively because + * difference between tna and tnb is 1 or 0 + */ + if (i < tna || i < tnb) { + bn_mul_part_recursive(&(r[n2]), + &(a[n]), &(b[n]), + i, tna - i, tnb - i, p); + break; + } else if (i == tna || i == tnb) { + bn_mul_recursive(&(r[n2]), + &(a[n]), &(b[n]), + i, tna - i, tnb - i, p); + break; + } + } + } + } + } + + /*- + * t[32] holds (a[0]-a[1])*(b[1]-b[0]), c1 is the sign + * r[10] holds (a[0]*b[0]) + * r[32] holds (b[1]*b[1]) + */ + + c1 = (int)(bn_add_words(t, r, &(r[n2]), n2)); + + if (neg) { /* if t[32] is negative */ + c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2)); + } else { + /* Might have a carry */ + c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), t, n2)); + } + + /*- + * t[32] holds (a[0]-a[1])*(b[1]-b[0])+(a[0]*b[0])+(a[1]*b[1]) + * r[10] holds (a[0]*b[0]) + * r[32] holds (b[1]*b[1]) + * c1 holds the carry bits + */ + c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2)); + if (c1) { + p = &(r[n + n2]); + lo = *p; + ln = (lo + c1) & BN_MASK2; + *p = ln; + + /* + * The overflow will stop before we over write words we should not + * overwrite + */ + if (ln < (BN_ULONG)c1) { + do { + p++; + lo = *p; + ln = (lo + 1) & BN_MASK2; + *p = ln; + } while (ln == 0); + } + } +} + +/*- + * a and b must be the same size, which is n2. + * r needs to be n2 words and t needs to be n2*2 + */ +void bn_mul_low_recursive(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n2, + BN_ULONG *t) +{ + int n = n2 / 2; + +# ifdef BN_COUNT + fprintf(stderr, " bn_mul_low_recursive %d * %d\n", n2, n2); +# endif + + bn_mul_recursive(r, a, b, n, 0, 0, &(t[0])); + if (n >= BN_MUL_LOW_RECURSIVE_SIZE_NORMAL) { + bn_mul_low_recursive(&(t[0]), &(a[0]), &(b[n]), n, &(t[n2])); + bn_add_words(&(r[n]), &(r[n]), &(t[0]), n); + bn_mul_low_recursive(&(t[0]), &(a[n]), &(b[0]), n, &(t[n2])); + bn_add_words(&(r[n]), &(r[n]), &(t[0]), n); + } else { + bn_mul_low_normal(&(t[0]), &(a[0]), &(b[n]), n); + bn_mul_low_normal(&(t[n]), &(a[n]), &(b[0]), n); + bn_add_words(&(r[n]), &(r[n]), &(t[0]), n); + bn_add_words(&(r[n]), &(r[n]), &(t[n]), n); + } +} + +/*- + * a and b must be the same size, which is n2. + * r needs to be n2 words and t needs to be n2*2 + * l is the low words of the output. + * t needs to be n2*3 + */ +void bn_mul_high(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, BN_ULONG *l, int n2, + BN_ULONG *t) +{ + int i, n; + int c1, c2; + int neg, oneg, zero; + BN_ULONG ll, lc, *lp, *mp; + +# ifdef BN_COUNT + fprintf(stderr, " bn_mul_high %d * %d\n", n2, n2); +# endif + n = n2 / 2; + + /* Calculate (al-ah)*(bh-bl) */ + neg = zero = 0; + c1 = bn_cmp_words(&(a[0]), &(a[n]), n); + c2 = bn_cmp_words(&(b[n]), &(b[0]), n); + switch (c1 * 3 + c2) { + case -4: + bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n); + bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n); + break; + case -3: + zero = 1; + break; + case -2: + bn_sub_words(&(r[0]), &(a[n]), &(a[0]), n); + bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n); + neg = 1; + break; + case -1: + case 0: + case 1: + zero = 1; + break; + case 2: + bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n); + bn_sub_words(&(r[n]), &(b[0]), &(b[n]), n); + neg = 1; + break; + case 3: + zero = 1; + break; + case 4: + bn_sub_words(&(r[0]), &(a[0]), &(a[n]), n); + bn_sub_words(&(r[n]), &(b[n]), &(b[0]), n); + break; + } + + oneg = neg; + /* t[10] = (a[0]-a[1])*(b[1]-b[0]) */ + /* r[10] = (a[1]*b[1]) */ +# ifdef BN_MUL_COMBA + if (n == 8) { + bn_mul_comba8(&(t[0]), &(r[0]), &(r[n])); + bn_mul_comba8(r, &(a[n]), &(b[n])); + } else +# endif + { + bn_mul_recursive(&(t[0]), &(r[0]), &(r[n]), n, 0, 0, &(t[n2])); + bn_mul_recursive(r, &(a[n]), &(b[n]), n, 0, 0, &(t[n2])); + } + + /*- + * s0 == low(al*bl) + * s1 == low(ah*bh)+low((al-ah)*(bh-bl))+low(al*bl)+high(al*bl) + * We know s0 and s1 so the only unknown is high(al*bl) + * high(al*bl) == s1 - low(ah*bh+s0+(al-ah)*(bh-bl)) + * high(al*bl) == s1 - (r[0]+l[0]+t[0]) + */ + if (l != NULL) { + lp = &(t[n2 + n]); + c1 = (int)(bn_add_words(lp, &(r[0]), &(l[0]), n)); + } else { + c1 = 0; + lp = &(r[0]); + } + + if (neg) + neg = (int)(bn_sub_words(&(t[n2]), lp, &(t[0]), n)); + else { + bn_add_words(&(t[n2]), lp, &(t[0]), n); + neg = 0; + } + + if (l != NULL) { + bn_sub_words(&(t[n2 + n]), &(l[n]), &(t[n2]), n); + } else { + lp = &(t[n2 + n]); + mp = &(t[n2]); + for (i = 0; i < n; i++) + lp[i] = ((~mp[i]) + 1) & BN_MASK2; + } + + /*- + * s[0] = low(al*bl) + * t[3] = high(al*bl) + * t[10] = (a[0]-a[1])*(b[1]-b[0]) neg is the sign + * r[10] = (a[1]*b[1]) + */ + /*- + * R[10] = al*bl + * R[21] = al*bl + ah*bh + (a[0]-a[1])*(b[1]-b[0]) + * R[32] = ah*bh + */ + /*- + * R[1]=t[3]+l[0]+r[0](+-)t[0] (have carry/borrow) + * R[2]=r[0]+t[3]+r[1](+-)t[1] (have carry/borrow) + * R[3]=r[1]+(carry/borrow) + */ + if (l != NULL) { + lp = &(t[n2]); + c1 = (int)(bn_add_words(lp, &(t[n2 + n]), &(l[0]), n)); + } else { + lp = &(t[n2 + n]); + c1 = 0; + } + c1 += (int)(bn_add_words(&(t[n2]), lp, &(r[0]), n)); + if (oneg) + c1 -= (int)(bn_sub_words(&(t[n2]), &(t[n2]), &(t[0]), n)); + else + c1 += (int)(bn_add_words(&(t[n2]), &(t[n2]), &(t[0]), n)); + + c2 = (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n2 + n]), n)); + c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(r[n]), n)); + if (oneg) + c2 -= (int)(bn_sub_words(&(r[0]), &(r[0]), &(t[n]), n)); + else + c2 += (int)(bn_add_words(&(r[0]), &(r[0]), &(t[n]), n)); + + if (c1 != 0) { /* Add starting at r[0], could be +ve or -ve */ + i = 0; + if (c1 > 0) { + lc = c1; + do { + ll = (r[i] + lc) & BN_MASK2; + r[i++] = ll; + lc = (lc > ll); + } while (lc); + } else { + lc = -c1; + do { + ll = r[i]; + r[i++] = (ll - lc) & BN_MASK2; + lc = (lc > ll); + } while (lc); + } + } + if (c2 != 0) { /* Add starting at r[1] */ + i = n; + if (c2 > 0) { + lc = c2; + do { + ll = (r[i] + lc) & BN_MASK2; + r[i++] = ll; + lc = (lc > ll); + } while (lc); + } else { + lc = -c2; + do { + ll = r[i]; + r[i++] = (ll - lc) & BN_MASK2; + lc = (lc > ll); + } while (lc); + } + } +} +#endif /* BN_RECURSION */ + +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + int ret = 0; + int top, al, bl; + BIGNUM *rr; +#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) + int i; +#endif +#ifdef BN_RECURSION + BIGNUM *t = NULL; + int j = 0, k; +#endif + +#ifdef BN_COUNT + fprintf(stderr, "BN_mul %d * %d\n", a->top, b->top); +#endif + + bn_check_top(a); + bn_check_top(b); + bn_check_top(r); + + al = a->top; + bl = b->top; + + if ((al == 0) || (bl == 0)) { + BN_zero(r); + return (1); + } + top = al + bl; + + BN_CTX_start(ctx); + if ((r == a) || (r == b)) { + if ((rr = BN_CTX_get(ctx)) == NULL) + goto err; + } else + rr = r; + rr->neg = a->neg ^ b->neg; + +#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) + i = al - bl; +#endif +#ifdef BN_MUL_COMBA + if (i == 0) { +# if 0 + if (al == 4) { + if (bn_wexpand(rr, 8) == NULL) + goto err; + rr->top = 8; + bn_mul_comba4(rr->d, a->d, b->d); + goto end; + } +# endif + if (al == 8) { + if (bn_wexpand(rr, 16) == NULL) + goto err; + rr->top = 16; + bn_mul_comba8(rr->d, a->d, b->d); + goto end; + } + } +#endif /* BN_MUL_COMBA */ +#ifdef BN_RECURSION + if ((al >= BN_MULL_SIZE_NORMAL) && (bl >= BN_MULL_SIZE_NORMAL)) { + if (i >= -1 && i <= 1) { + /* + * Find out the power of two lower or equal to the longest of the + * two numbers + */ + if (i >= 0) { + j = BN_num_bits_word((BN_ULONG)al); + } + if (i == -1) { + j = BN_num_bits_word((BN_ULONG)bl); + } + j = 1 << (j - 1); + assert(j <= al || j <= bl); + k = j + j; + t = BN_CTX_get(ctx); + if (t == NULL) + goto err; + if (al > j || bl > j) { + if (bn_wexpand(t, k * 4) == NULL) + goto err; + if (bn_wexpand(rr, k * 4) == NULL) + goto err; + bn_mul_part_recursive(rr->d, a->d, b->d, + j, al - j, bl - j, t->d); + } else { /* al <= j || bl <= j */ + + if (bn_wexpand(t, k * 2) == NULL) + goto err; + if (bn_wexpand(rr, k * 2) == NULL) + goto err; + bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); + } + rr->top = top; + goto end; + } +# if 0 + if (i == 1 && !BN_get_flags(b, BN_FLG_STATIC_DATA)) { + BIGNUM *tmp_bn = (BIGNUM *)b; + if (bn_wexpand(tmp_bn, al) == NULL) + goto err; + tmp_bn->d[bl] = 0; + bl++; + i--; + } else if (i == -1 && !BN_get_flags(a, BN_FLG_STATIC_DATA)) { + BIGNUM *tmp_bn = (BIGNUM *)a; + if (bn_wexpand(tmp_bn, bl) == NULL) + goto err; + tmp_bn->d[al] = 0; + al++; + i++; + } + if (i == 0) { + /* symmetric and > 4 */ + /* 16 or larger */ + j = BN_num_bits_word((BN_ULONG)al); + j = 1 << (j - 1); + k = j + j; + t = BN_CTX_get(ctx); + if (al == j) { /* exact multiple */ + if (bn_wexpand(t, k * 2) == NULL) + goto err; + if (bn_wexpand(rr, k * 2) == NULL) + goto err; + bn_mul_recursive(rr->d, a->d, b->d, al, t->d); + } else { + if (bn_wexpand(t, k * 4) == NULL) + goto err; + if (bn_wexpand(rr, k * 4) == NULL) + goto err; + bn_mul_part_recursive(rr->d, a->d, b->d, al - j, j, t->d); + } + rr->top = top; + goto end; + } +# endif + } +#endif /* BN_RECURSION */ + if (bn_wexpand(rr, top) == NULL) + goto err; + rr->top = top; + bn_mul_normal(rr->d, a->d, al, b->d, bl); + +#if defined(BN_MUL_COMBA) || defined(BN_RECURSION) + end: +#endif + bn_correct_top(rr); + if (r != rr) + BN_copy(r, rr); + ret = 1; + err: + bn_check_top(r); + BN_CTX_end(ctx); + return (ret); +} + +void bn_mul_normal(BN_ULONG *r, BN_ULONG *a, int na, BN_ULONG *b, int nb) +{ + BN_ULONG *rr; + +#ifdef BN_COUNT + fprintf(stderr, " bn_mul_normal %d * %d\n", na, nb); +#endif + + if (na < nb) { + int itmp; + BN_ULONG *ltmp; + + itmp = na; + na = nb; + nb = itmp; + ltmp = a; + a = b; + b = ltmp; + + } + rr = &(r[na]); + if (nb <= 0) { + (void)bn_mul_words(r, a, na, 0); + return; + } else + rr[0] = bn_mul_words(r, a, na, b[0]); + + for (;;) { + if (--nb <= 0) + return; + rr[1] = bn_mul_add_words(&(r[1]), a, na, b[1]); + if (--nb <= 0) + return; + rr[2] = bn_mul_add_words(&(r[2]), a, na, b[2]); + if (--nb <= 0) + return; + rr[3] = bn_mul_add_words(&(r[3]), a, na, b[3]); + if (--nb <= 0) + return; + rr[4] = bn_mul_add_words(&(r[4]), a, na, b[4]); + rr += 4; + r += 4; + b += 4; + } +} + +void bn_mul_low_normal(BN_ULONG *r, BN_ULONG *a, BN_ULONG *b, int n) +{ +#ifdef BN_COUNT + fprintf(stderr, " bn_mul_low_normal %d * %d\n", n, n); +#endif + bn_mul_words(r, a, n, b[0]); + + for (;;) { + if (--n <= 0) + return; + bn_mul_add_words(&(r[1]), a, n, b[1]); + if (--n <= 0) + return; + bn_mul_add_words(&(r[2]), a, n, b[2]); + if (--n <= 0) + return; + bn_mul_add_words(&(r[3]), a, n, b[3]); + if (--n <= 0) + return; + bn_mul_add_words(&(r[4]), a, n, b[4]); + r += 4; + b += 4; + } +} diff --git a/libs/openssl/crypto/bn/bn_nist.c b/libs/openssl/crypto/bn/bn_nist.c new file mode 100644 index 00000000..4a45404c --- /dev/null +++ b/libs/openssl/crypto/bn/bn_nist.c @@ -0,0 +1,1262 @@ +/* crypto/bn/bn_nist.c */ +/* + * Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "bn_lcl.h" +#include "cryptlib.h" + +#define BN_NIST_192_TOP (192+BN_BITS2-1)/BN_BITS2 +#define BN_NIST_224_TOP (224+BN_BITS2-1)/BN_BITS2 +#define BN_NIST_256_TOP (256+BN_BITS2-1)/BN_BITS2 +#define BN_NIST_384_TOP (384+BN_BITS2-1)/BN_BITS2 +#define BN_NIST_521_TOP (521+BN_BITS2-1)/BN_BITS2 + +/* pre-computed tables are "carry-less" values of modulus*(i+1) */ +#if BN_BITS2 == 64 +static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = { + {0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFFULL}, + {0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL}, + {0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFCULL, 0xFFFFFFFFFFFFFFFFULL} +}; + +static const BN_ULONG _nist_p_192_sqr[] = { + 0x0000000000000001ULL, 0x0000000000000002ULL, 0x0000000000000001ULL, + 0xFFFFFFFFFFFFFFFEULL, 0xFFFFFFFFFFFFFFFDULL, 0xFFFFFFFFFFFFFFFFULL +}; + +static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = { + {0x0000000000000001ULL, 0xFFFFFFFF00000000ULL, + 0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL}, + {0x0000000000000002ULL, 0xFFFFFFFE00000000ULL, + 0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFFULL} /* this one is + * "carry-full" */ +}; + +static const BN_ULONG _nist_p_224_sqr[] = { + 0x0000000000000001ULL, 0xFFFFFFFE00000000ULL, + 0xFFFFFFFFFFFFFFFFULL, 0x0000000200000000ULL, + 0x0000000000000000ULL, 0xFFFFFFFFFFFFFFFEULL, + 0xFFFFFFFFFFFFFFFFULL +}; + +static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = { + {0xFFFFFFFFFFFFFFFFULL, 0x00000000FFFFFFFFULL, + 0x0000000000000000ULL, 0xFFFFFFFF00000001ULL}, + {0xFFFFFFFFFFFFFFFEULL, 0x00000001FFFFFFFFULL, + 0x0000000000000000ULL, 0xFFFFFFFE00000002ULL}, + {0xFFFFFFFFFFFFFFFDULL, 0x00000002FFFFFFFFULL, + 0x0000000000000000ULL, 0xFFFFFFFD00000003ULL}, + {0xFFFFFFFFFFFFFFFCULL, 0x00000003FFFFFFFFULL, + 0x0000000000000000ULL, 0xFFFFFFFC00000004ULL}, + {0xFFFFFFFFFFFFFFFBULL, 0x00000004FFFFFFFFULL, + 0x0000000000000000ULL, 0xFFFFFFFB00000005ULL}, +}; + +static const BN_ULONG _nist_p_256_sqr[] = { + 0x0000000000000001ULL, 0xFFFFFFFE00000000ULL, + 0xFFFFFFFFFFFFFFFFULL, 0x00000001FFFFFFFEULL, + 0x00000001FFFFFFFEULL, 0x00000001FFFFFFFEULL, + 0xFFFFFFFE00000001ULL, 0xFFFFFFFE00000002ULL +}; + +static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = { + {0x00000000FFFFFFFFULL, 0xFFFFFFFF00000000ULL, 0xFFFFFFFFFFFFFFFEULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, + {0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, + {0x00000002FFFFFFFDULL, 0xFFFFFFFD00000000ULL, 0xFFFFFFFFFFFFFFFCULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, + {0x00000003FFFFFFFCULL, 0xFFFFFFFC00000000ULL, 0xFFFFFFFFFFFFFFFBULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, + {0x00000004FFFFFFFBULL, 0xFFFFFFFB00000000ULL, 0xFFFFFFFFFFFFFFFAULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL}, +}; + +static const BN_ULONG _nist_p_384_sqr[] = { + 0xFFFFFFFE00000001ULL, 0x0000000200000000ULL, 0xFFFFFFFE00000000ULL, + 0x0000000200000000ULL, 0x0000000000000001ULL, 0x0000000000000000ULL, + 0x00000001FFFFFFFEULL, 0xFFFFFFFE00000000ULL, 0xFFFFFFFFFFFFFFFDULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL +}; + +static const BN_ULONG _nist_p_521[] = + { 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0x00000000000001FFULL +}; + +static const BN_ULONG _nist_p_521_sqr[] = { + 0x0000000000000001ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, + 0x0000000000000000ULL, 0x0000000000000000ULL, 0x0000000000000000ULL, + 0x0000000000000000ULL, 0x0000000000000000ULL, 0xFFFFFFFFFFFFFC00ULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, 0xFFFFFFFFFFFFFFFFULL, + 0xFFFFFFFFFFFFFFFFULL, 0x000000000003FFFFULL +}; +#elif BN_BITS2 == 32 +static const BN_ULONG _nist_p_192[][BN_NIST_192_TOP] = { + {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} +}; + +static const BN_ULONG _nist_p_192_sqr[] = { + 0x00000001, 0x00000000, 0x00000002, 0x00000000, 0x00000001, 0x00000000, + 0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF +}; + +static const BN_ULONG _nist_p_224[][BN_NIST_224_TOP] = { + {0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0x00000002, 0x00000000, 0x00000000, 0xFFFFFFFE, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF} +}; + +static const BN_ULONG _nist_p_224_sqr[] = { + 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, + 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, 0x00000002, + 0x00000000, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF +}; + +static const BN_ULONG _nist_p_256[][BN_NIST_256_TOP] = { + {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000000, + 0x00000000, 0x00000000, 0x00000001, 0xFFFFFFFF}, + {0xFFFFFFFE, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000001, + 0x00000000, 0x00000000, 0x00000002, 0xFFFFFFFE}, + {0xFFFFFFFD, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000002, + 0x00000000, 0x00000000, 0x00000003, 0xFFFFFFFD}, + {0xFFFFFFFC, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000003, + 0x00000000, 0x00000000, 0x00000004, 0xFFFFFFFC}, + {0xFFFFFFFB, 0xFFFFFFFF, 0xFFFFFFFF, 0x00000004, + 0x00000000, 0x00000000, 0x00000005, 0xFFFFFFFB}, +}; + +static const BN_ULONG _nist_p_256_sqr[] = { + 0x00000001, 0x00000000, 0x00000000, 0xFFFFFFFE, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFE, 0x00000001, + 0xFFFFFFFE, 0x00000001, 0xFFFFFFFE, 0x00000001, + 0x00000001, 0xFFFFFFFE, 0x00000002, 0xFFFFFFFE +}; + +static const BN_ULONG _nist_p_384[][BN_NIST_384_TOP] = { + {0xFFFFFFFF, 0x00000000, 0x00000000, 0xFFFFFFFF, 0xFFFFFFFE, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFD, 0x00000002, 0x00000000, 0xFFFFFFFD, 0xFFFFFFFC, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFC, 0x00000003, 0x00000000, 0xFFFFFFFC, 0xFFFFFFFB, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, + {0xFFFFFFFB, 0x00000004, 0x00000000, 0xFFFFFFFB, 0xFFFFFFFA, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}, +}; + +static const BN_ULONG _nist_p_384_sqr[] = { + 0x00000001, 0xFFFFFFFE, 0x00000000, 0x00000002, 0x00000000, 0xFFFFFFFE, + 0x00000000, 0x00000002, 0x00000001, 0x00000000, 0x00000000, 0x00000000, + 0xFFFFFFFE, 0x00000001, 0x00000000, 0xFFFFFFFE, 0xFFFFFFFD, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF +}; + +static const BN_ULONG _nist_p_521[] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0x000001FF +}; + +static const BN_ULONG _nist_p_521_sqr[] = { + 0x00000001, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, + 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0xFFFFFC00, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, + 0xFFFFFFFF, 0xFFFFFFFF, 0x0003FFFF +}; +#else +# error "unsupported BN_BITS2" +#endif + +static const BIGNUM _bignum_nist_p_192 = { + (BN_ULONG *)_nist_p_192[0], + BN_NIST_192_TOP, + BN_NIST_192_TOP, + 0, + BN_FLG_STATIC_DATA +}; + +static const BIGNUM _bignum_nist_p_224 = { + (BN_ULONG *)_nist_p_224[0], + BN_NIST_224_TOP, + BN_NIST_224_TOP, + 0, + BN_FLG_STATIC_DATA +}; + +static const BIGNUM _bignum_nist_p_256 = { + (BN_ULONG *)_nist_p_256[0], + BN_NIST_256_TOP, + BN_NIST_256_TOP, + 0, + BN_FLG_STATIC_DATA +}; + +static const BIGNUM _bignum_nist_p_384 = { + (BN_ULONG *)_nist_p_384[0], + BN_NIST_384_TOP, + BN_NIST_384_TOP, + 0, + BN_FLG_STATIC_DATA +}; + +static const BIGNUM _bignum_nist_p_521 = { + (BN_ULONG *)_nist_p_521, + BN_NIST_521_TOP, + BN_NIST_521_TOP, + 0, + BN_FLG_STATIC_DATA +}; + +const BIGNUM *BN_get0_nist_prime_192(void) +{ + return &_bignum_nist_p_192; +} + +const BIGNUM *BN_get0_nist_prime_224(void) +{ + return &_bignum_nist_p_224; +} + +const BIGNUM *BN_get0_nist_prime_256(void) +{ + return &_bignum_nist_p_256; +} + +const BIGNUM *BN_get0_nist_prime_384(void) +{ + return &_bignum_nist_p_384; +} + +const BIGNUM *BN_get0_nist_prime_521(void) +{ + return &_bignum_nist_p_521; +} + +static void nist_cp_bn_0(BN_ULONG *dst, const BN_ULONG *src, int top, int max) +{ + int i; + +#ifdef BN_DEBUG + OPENSSL_assert(top <= max); +#endif + for (i = 0; i < top; i++) + dst[i] = src[i]; + for (; i < max; i++) + dst[i] = 0; +} + +static void nist_cp_bn(BN_ULONG *dst, const BN_ULONG *src, int top) +{ + int i; + + for (i = 0; i < top; i++) + dst[i] = src[i]; +} + +#if BN_BITS2 == 64 +# define bn_cp_64(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; +# define bn_64_set_0(to, n) (to)[n] = (BN_ULONG)0; +/* + * two following macros are implemented under assumption that they + * are called in a sequence with *ascending* n, i.e. as they are... + */ +# define bn_cp_32_naked(to, n, from, m) (((n)&1)?(to[(n)/2]|=((m)&1)?(from[(m)/2]&BN_MASK2h):(from[(m)/2]<<32))\ + :(to[(n)/2] =((m)&1)?(from[(m)/2]>>32):(from[(m)/2]&BN_MASK2l))) +# define bn_32_set_0(to, n) (((n)&1)?(to[(n)/2]&=BN_MASK2l):(to[(n)/2]=0)); +# define bn_cp_32(to,n,from,m) ((m)>=0)?bn_cp_32_naked(to,n,from,m):bn_32_set_0(to,n) +# if defined(L_ENDIAN) +# if defined(__arch64__) +# define NIST_INT64 long +# else +# define NIST_INT64 long long +# endif +# endif +#else +# define bn_cp_64(to, n, from, m) \ + { \ + bn_cp_32(to, (n)*2, from, (m)*2); \ + bn_cp_32(to, (n)*2+1, from, (m)*2+1); \ + } +# define bn_64_set_0(to, n) \ + { \ + bn_32_set_0(to, (n)*2); \ + bn_32_set_0(to, (n)*2+1); \ + } +# define bn_cp_32(to, n, from, m) (to)[n] = (m>=0)?((from)[m]):0; +# define bn_32_set_0(to, n) (to)[n] = (BN_ULONG)0; +# if defined(_WIN32) && !defined(__GNUC__) +# define NIST_INT64 __int64 +# elif defined(BN_LLONG) +# define NIST_INT64 long long +# endif +#endif /* BN_BITS2 != 64 */ + +#define nist_set_192(to, from, a1, a2, a3) \ + { \ + bn_cp_64(to, 0, from, (a3) - 3) \ + bn_cp_64(to, 1, from, (a2) - 3) \ + bn_cp_64(to, 2, from, (a1) - 3) \ + } + +int BN_nist_mod_192(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, + BN_CTX *ctx) +{ + int top = a->top, i; + int carry; + register BN_ULONG *r_d, *a_d = a->d; + union { + BN_ULONG bn[BN_NIST_192_TOP]; + unsigned int ui[BN_NIST_192_TOP * sizeof(BN_ULONG) / + sizeof(unsigned int)]; + } buf; + BN_ULONG c_d[BN_NIST_192_TOP], *res; + PTR_SIZE_INT mask; + static const BIGNUM _bignum_nist_p_192_sqr = { + (BN_ULONG *)_nist_p_192_sqr, + sizeof(_nist_p_192_sqr) / sizeof(_nist_p_192_sqr[0]), + sizeof(_nist_p_192_sqr) / sizeof(_nist_p_192_sqr[0]), + 0, BN_FLG_STATIC_DATA + }; + + field = &_bignum_nist_p_192; /* just to make sure */ + + if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_192_sqr) >= 0) + return BN_nnmod(r, a, field, ctx); + + i = BN_ucmp(field, a); + if (i == 0) { + BN_zero(r); + return 1; + } else if (i > 0) + return (r == a) ? 1 : (BN_copy(r, a) != NULL); + + if (r != a) { + if (!bn_wexpand(r, BN_NIST_192_TOP)) + return 0; + r_d = r->d; + nist_cp_bn(r_d, a_d, BN_NIST_192_TOP); + } else + r_d = a_d; + + nist_cp_bn_0(buf.bn, a_d + BN_NIST_192_TOP, top - BN_NIST_192_TOP, + BN_NIST_192_TOP); + +#if defined(NIST_INT64) + { + NIST_INT64 acc; /* accumulator */ + unsigned int *rp = (unsigned int *)r_d; + const unsigned int *bp = (const unsigned int *)buf.ui; + + acc = rp[0]; + acc += bp[3 * 2 - 6]; + acc += bp[5 * 2 - 6]; + rp[0] = (unsigned int)acc; + acc >>= 32; + + acc += rp[1]; + acc += bp[3 * 2 - 5]; + acc += bp[5 * 2 - 5]; + rp[1] = (unsigned int)acc; + acc >>= 32; + + acc += rp[2]; + acc += bp[3 * 2 - 6]; + acc += bp[4 * 2 - 6]; + acc += bp[5 * 2 - 6]; + rp[2] = (unsigned int)acc; + acc >>= 32; + + acc += rp[3]; + acc += bp[3 * 2 - 5]; + acc += bp[4 * 2 - 5]; + acc += bp[5 * 2 - 5]; + rp[3] = (unsigned int)acc; + acc >>= 32; + + acc += rp[4]; + acc += bp[4 * 2 - 6]; + acc += bp[5 * 2 - 6]; + rp[4] = (unsigned int)acc; + acc >>= 32; + + acc += rp[5]; + acc += bp[4 * 2 - 5]; + acc += bp[5 * 2 - 5]; + rp[5] = (unsigned int)acc; + + carry = (int)(acc >> 32); + } +#else + { + BN_ULONG t_d[BN_NIST_192_TOP]; + + nist_set_192(t_d, buf.bn, 0, 3, 3); + carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); + nist_set_192(t_d, buf.bn, 4, 4, 0); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); + nist_set_192(t_d, buf.bn, 5, 5, 5) + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_192_TOP); + } +#endif + if (carry > 0) + carry = + (int)bn_sub_words(r_d, r_d, _nist_p_192[carry - 1], + BN_NIST_192_TOP); + else + carry = 1; + + /* + * we need 'if (carry==0 || result>=modulus) result-=modulus;' + * as comparison implies subtraction, we can write + * 'tmp=result-modulus; if (!carry || !borrow) result=tmp;' + * this is what happens below, but without explicit if:-) a. + */ + mask = + 0 - (PTR_SIZE_INT) bn_sub_words(c_d, r_d, _nist_p_192[0], + BN_NIST_192_TOP); + mask &= 0 - (PTR_SIZE_INT) carry; + res = c_d; + res = (BN_ULONG *) + (((PTR_SIZE_INT) res & ~mask) | ((PTR_SIZE_INT) r_d & mask)); + nist_cp_bn(r_d, res, BN_NIST_192_TOP); + r->top = BN_NIST_192_TOP; + bn_correct_top(r); + + return 1; +} + +typedef BN_ULONG (*bn_addsub_f) (BN_ULONG *, const BN_ULONG *, + const BN_ULONG *, int); + +#define nist_set_224(to, from, a1, a2, a3, a4, a5, a6, a7) \ + { \ + bn_cp_32(to, 0, from, (a7) - 7) \ + bn_cp_32(to, 1, from, (a6) - 7) \ + bn_cp_32(to, 2, from, (a5) - 7) \ + bn_cp_32(to, 3, from, (a4) - 7) \ + bn_cp_32(to, 4, from, (a3) - 7) \ + bn_cp_32(to, 5, from, (a2) - 7) \ + bn_cp_32(to, 6, from, (a1) - 7) \ + } + +int BN_nist_mod_224(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, + BN_CTX *ctx) +{ + int top = a->top, i; + int carry; + BN_ULONG *r_d, *a_d = a->d; + union { + BN_ULONG bn[BN_NIST_224_TOP]; + unsigned int ui[BN_NIST_224_TOP * sizeof(BN_ULONG) / + sizeof(unsigned int)]; + } buf; + BN_ULONG c_d[BN_NIST_224_TOP], *res; + PTR_SIZE_INT mask; + union { + bn_addsub_f f; + PTR_SIZE_INT p; + } u; + static const BIGNUM _bignum_nist_p_224_sqr = { + (BN_ULONG *)_nist_p_224_sqr, + sizeof(_nist_p_224_sqr) / sizeof(_nist_p_224_sqr[0]), + sizeof(_nist_p_224_sqr) / sizeof(_nist_p_224_sqr[0]), + 0, BN_FLG_STATIC_DATA + }; + + field = &_bignum_nist_p_224; /* just to make sure */ + + if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_224_sqr) >= 0) + return BN_nnmod(r, a, field, ctx); + + i = BN_ucmp(field, a); + if (i == 0) { + BN_zero(r); + return 1; + } else if (i > 0) + return (r == a) ? 1 : (BN_copy(r, a) != NULL); + + if (r != a) { + if (!bn_wexpand(r, BN_NIST_224_TOP)) + return 0; + r_d = r->d; + nist_cp_bn(r_d, a_d, BN_NIST_224_TOP); + } else + r_d = a_d; + +#if BN_BITS2==64 + /* copy upper 256 bits of 448 bit number ... */ + nist_cp_bn_0(c_d, a_d + (BN_NIST_224_TOP - 1), + top - (BN_NIST_224_TOP - 1), BN_NIST_224_TOP); + /* ... and right shift by 32 to obtain upper 224 bits */ + nist_set_224(buf.bn, c_d, 14, 13, 12, 11, 10, 9, 8); + /* truncate lower part to 224 bits too */ + r_d[BN_NIST_224_TOP - 1] &= BN_MASK2l; +#else + nist_cp_bn_0(buf.bn, a_d + BN_NIST_224_TOP, top - BN_NIST_224_TOP, + BN_NIST_224_TOP); +#endif + +#if defined(NIST_INT64) && BN_BITS2!=64 + { + NIST_INT64 acc; /* accumulator */ + unsigned int *rp = (unsigned int *)r_d; + const unsigned int *bp = (const unsigned int *)buf.ui; + + acc = rp[0]; + acc -= bp[7 - 7]; + acc -= bp[11 - 7]; + rp[0] = (unsigned int)acc; + acc >>= 32; + + acc += rp[1]; + acc -= bp[8 - 7]; + acc -= bp[12 - 7]; + rp[1] = (unsigned int)acc; + acc >>= 32; + + acc += rp[2]; + acc -= bp[9 - 7]; + acc -= bp[13 - 7]; + rp[2] = (unsigned int)acc; + acc >>= 32; + + acc += rp[3]; + acc += bp[7 - 7]; + acc += bp[11 - 7]; + acc -= bp[10 - 7]; + rp[3] = (unsigned int)acc; + acc >>= 32; + + acc += rp[4]; + acc += bp[8 - 7]; + acc += bp[12 - 7]; + acc -= bp[11 - 7]; + rp[4] = (unsigned int)acc; + acc >>= 32; + + acc += rp[5]; + acc += bp[9 - 7]; + acc += bp[13 - 7]; + acc -= bp[12 - 7]; + rp[5] = (unsigned int)acc; + acc >>= 32; + + acc += rp[6]; + acc += bp[10 - 7]; + acc -= bp[13 - 7]; + rp[6] = (unsigned int)acc; + + carry = (int)(acc >> 32); +# if BN_BITS2==64 + rp[7] = carry; +# endif + } +#else + { + BN_ULONG t_d[BN_NIST_224_TOP]; + + nist_set_224(t_d, buf.bn, 10, 9, 8, 7, 0, 0, 0); + carry = (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP); + nist_set_224(t_d, buf.bn, 0, 13, 12, 11, 0, 0, 0); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_224_TOP); + nist_set_224(t_d, buf.bn, 13, 12, 11, 10, 9, 8, 7); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP); + nist_set_224(t_d, buf.bn, 0, 0, 0, 0, 13, 12, 11); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_224_TOP); + +# if BN_BITS2==64 + carry = (int)(r_d[BN_NIST_224_TOP - 1] >> 32); +# endif + } +#endif + u.f = bn_sub_words; + if (carry > 0) { + carry = + (int)bn_sub_words(r_d, r_d, _nist_p_224[carry - 1], + BN_NIST_224_TOP); +#if BN_BITS2==64 + carry = (int)(~(r_d[BN_NIST_224_TOP - 1] >> 32)) & 1; +#endif + } else if (carry < 0) { + /* + * it's a bit more comlicated logic in this case. if bn_add_words + * yields no carry, then result has to be adjusted by unconditionally + * *adding* the modulus. but if it does, then result has to be + * compared to the modulus and conditionally adjusted by + * *subtracting* the latter. + */ + carry = + (int)bn_add_words(r_d, r_d, _nist_p_224[-carry - 1], + BN_NIST_224_TOP); + mask = 0 - (PTR_SIZE_INT) carry; + u.p = ((PTR_SIZE_INT) bn_sub_words & mask) | + ((PTR_SIZE_INT) bn_add_words & ~mask); + } else + carry = 1; + + /* otherwise it's effectively same as in BN_nist_mod_192... */ + mask = + 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_224[0], BN_NIST_224_TOP); + mask &= 0 - (PTR_SIZE_INT) carry; + res = c_d; + res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) | + ((PTR_SIZE_INT) r_d & mask)); + nist_cp_bn(r_d, res, BN_NIST_224_TOP); + r->top = BN_NIST_224_TOP; + bn_correct_top(r); + + return 1; +} + +#define nist_set_256(to, from, a1, a2, a3, a4, a5, a6, a7, a8) \ + { \ + bn_cp_32(to, 0, from, (a8) - 8) \ + bn_cp_32(to, 1, from, (a7) - 8) \ + bn_cp_32(to, 2, from, (a6) - 8) \ + bn_cp_32(to, 3, from, (a5) - 8) \ + bn_cp_32(to, 4, from, (a4) - 8) \ + bn_cp_32(to, 5, from, (a3) - 8) \ + bn_cp_32(to, 6, from, (a2) - 8) \ + bn_cp_32(to, 7, from, (a1) - 8) \ + } + +int BN_nist_mod_256(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, + BN_CTX *ctx) +{ + int i, top = a->top; + int carry = 0; + register BN_ULONG *a_d = a->d, *r_d; + union { + BN_ULONG bn[BN_NIST_256_TOP]; + unsigned int ui[BN_NIST_256_TOP * sizeof(BN_ULONG) / + sizeof(unsigned int)]; + } buf; + BN_ULONG c_d[BN_NIST_256_TOP], *res; + PTR_SIZE_INT mask; + union { + bn_addsub_f f; + PTR_SIZE_INT p; + } u; + static const BIGNUM _bignum_nist_p_256_sqr = { + (BN_ULONG *)_nist_p_256_sqr, + sizeof(_nist_p_256_sqr) / sizeof(_nist_p_256_sqr[0]), + sizeof(_nist_p_256_sqr) / sizeof(_nist_p_256_sqr[0]), + 0, BN_FLG_STATIC_DATA + }; + + field = &_bignum_nist_p_256; /* just to make sure */ + + if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_256_sqr) >= 0) + return BN_nnmod(r, a, field, ctx); + + i = BN_ucmp(field, a); + if (i == 0) { + BN_zero(r); + return 1; + } else if (i > 0) + return (r == a) ? 1 : (BN_copy(r, a) != NULL); + + if (r != a) { + if (!bn_wexpand(r, BN_NIST_256_TOP)) + return 0; + r_d = r->d; + nist_cp_bn(r_d, a_d, BN_NIST_256_TOP); + } else + r_d = a_d; + + nist_cp_bn_0(buf.bn, a_d + BN_NIST_256_TOP, top - BN_NIST_256_TOP, + BN_NIST_256_TOP); + +#if defined(NIST_INT64) + { + NIST_INT64 acc; /* accumulator */ + unsigned int *rp = (unsigned int *)r_d; + const unsigned int *bp = (const unsigned int *)buf.ui; + + acc = rp[0]; + acc += bp[8 - 8]; + acc += bp[9 - 8]; + acc -= bp[11 - 8]; + acc -= bp[12 - 8]; + acc -= bp[13 - 8]; + acc -= bp[14 - 8]; + rp[0] = (unsigned int)acc; + acc >>= 32; + + acc += rp[1]; + acc += bp[9 - 8]; + acc += bp[10 - 8]; + acc -= bp[12 - 8]; + acc -= bp[13 - 8]; + acc -= bp[14 - 8]; + acc -= bp[15 - 8]; + rp[1] = (unsigned int)acc; + acc >>= 32; + + acc += rp[2]; + acc += bp[10 - 8]; + acc += bp[11 - 8]; + acc -= bp[13 - 8]; + acc -= bp[14 - 8]; + acc -= bp[15 - 8]; + rp[2] = (unsigned int)acc; + acc >>= 32; + + acc += rp[3]; + acc += bp[11 - 8]; + acc += bp[11 - 8]; + acc += bp[12 - 8]; + acc += bp[12 - 8]; + acc += bp[13 - 8]; + acc -= bp[15 - 8]; + acc -= bp[8 - 8]; + acc -= bp[9 - 8]; + rp[3] = (unsigned int)acc; + acc >>= 32; + + acc += rp[4]; + acc += bp[12 - 8]; + acc += bp[12 - 8]; + acc += bp[13 - 8]; + acc += bp[13 - 8]; + acc += bp[14 - 8]; + acc -= bp[9 - 8]; + acc -= bp[10 - 8]; + rp[4] = (unsigned int)acc; + acc >>= 32; + + acc += rp[5]; + acc += bp[13 - 8]; + acc += bp[13 - 8]; + acc += bp[14 - 8]; + acc += bp[14 - 8]; + acc += bp[15 - 8]; + acc -= bp[10 - 8]; + acc -= bp[11 - 8]; + rp[5] = (unsigned int)acc; + acc >>= 32; + + acc += rp[6]; + acc += bp[14 - 8]; + acc += bp[14 - 8]; + acc += bp[15 - 8]; + acc += bp[15 - 8]; + acc += bp[14 - 8]; + acc += bp[13 - 8]; + acc -= bp[8 - 8]; + acc -= bp[9 - 8]; + rp[6] = (unsigned int)acc; + acc >>= 32; + + acc += rp[7]; + acc += bp[15 - 8]; + acc += bp[15 - 8]; + acc += bp[15 - 8]; + acc += bp[8 - 8]; + acc -= bp[10 - 8]; + acc -= bp[11 - 8]; + acc -= bp[12 - 8]; + acc -= bp[13 - 8]; + rp[7] = (unsigned int)acc; + + carry = (int)(acc >> 32); + } +#else + { + BN_ULONG t_d[BN_NIST_256_TOP]; + + /* + * S1 + */ + nist_set_256(t_d, buf.bn, 15, 14, 13, 12, 11, 0, 0, 0); + /* + * S2 + */ + nist_set_256(c_d, buf.bn, 0, 15, 14, 13, 12, 0, 0, 0); + carry = (int)bn_add_words(t_d, t_d, c_d, BN_NIST_256_TOP); + /* left shift */ + { + register BN_ULONG *ap, t, c; + ap = t_d; + c = 0; + for (i = BN_NIST_256_TOP; i != 0; --i) { + t = *ap; + *(ap++) = ((t << 1) | c) & BN_MASK2; + c = (t & BN_TBIT) ? 1 : 0; + } + carry <<= 1; + carry |= c; + } + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); + /* + * S3 + */ + nist_set_256(t_d, buf.bn, 15, 14, 0, 0, 0, 10, 9, 8); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); + /* + * S4 + */ + nist_set_256(t_d, buf.bn, 8, 13, 15, 14, 13, 11, 10, 9); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_256_TOP); + /* + * D1 + */ + nist_set_256(t_d, buf.bn, 10, 8, 0, 0, 0, 13, 12, 11); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); + /* + * D2 + */ + nist_set_256(t_d, buf.bn, 11, 9, 0, 0, 15, 14, 13, 12); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); + /* + * D3 + */ + nist_set_256(t_d, buf.bn, 12, 0, 10, 9, 8, 15, 14, 13); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); + /* + * D4 + */ + nist_set_256(t_d, buf.bn, 13, 0, 11, 10, 9, 0, 15, 14); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_256_TOP); + + } +#endif + /* see BN_nist_mod_224 for explanation */ + u.f = bn_sub_words; + if (carry > 0) + carry = + (int)bn_sub_words(r_d, r_d, _nist_p_256[carry - 1], + BN_NIST_256_TOP); + else if (carry < 0) { + carry = + (int)bn_add_words(r_d, r_d, _nist_p_256[-carry - 1], + BN_NIST_256_TOP); + mask = 0 - (PTR_SIZE_INT) carry; + u.p = ((PTR_SIZE_INT) bn_sub_words & mask) | + ((PTR_SIZE_INT) bn_add_words & ~mask); + } else + carry = 1; + + mask = + 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_256[0], BN_NIST_256_TOP); + mask &= 0 - (PTR_SIZE_INT) carry; + res = c_d; + res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) | + ((PTR_SIZE_INT) r_d & mask)); + nist_cp_bn(r_d, res, BN_NIST_256_TOP); + r->top = BN_NIST_256_TOP; + bn_correct_top(r); + + return 1; +} + +#define nist_set_384(to,from,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) \ + { \ + bn_cp_32(to, 0, from, (a12) - 12) \ + bn_cp_32(to, 1, from, (a11) - 12) \ + bn_cp_32(to, 2, from, (a10) - 12) \ + bn_cp_32(to, 3, from, (a9) - 12) \ + bn_cp_32(to, 4, from, (a8) - 12) \ + bn_cp_32(to, 5, from, (a7) - 12) \ + bn_cp_32(to, 6, from, (a6) - 12) \ + bn_cp_32(to, 7, from, (a5) - 12) \ + bn_cp_32(to, 8, from, (a4) - 12) \ + bn_cp_32(to, 9, from, (a3) - 12) \ + bn_cp_32(to, 10, from, (a2) - 12) \ + bn_cp_32(to, 11, from, (a1) - 12) \ + } + +int BN_nist_mod_384(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, + BN_CTX *ctx) +{ + int i, top = a->top; + int carry = 0; + register BN_ULONG *r_d, *a_d = a->d; + union { + BN_ULONG bn[BN_NIST_384_TOP]; + unsigned int ui[BN_NIST_384_TOP * sizeof(BN_ULONG) / + sizeof(unsigned int)]; + } buf; + BN_ULONG c_d[BN_NIST_384_TOP], *res; + PTR_SIZE_INT mask; + union { + bn_addsub_f f; + PTR_SIZE_INT p; + } u; + static const BIGNUM _bignum_nist_p_384_sqr = { + (BN_ULONG *)_nist_p_384_sqr, + sizeof(_nist_p_384_sqr) / sizeof(_nist_p_384_sqr[0]), + sizeof(_nist_p_384_sqr) / sizeof(_nist_p_384_sqr[0]), + 0, BN_FLG_STATIC_DATA + }; + + field = &_bignum_nist_p_384; /* just to make sure */ + + if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_384_sqr) >= 0) + return BN_nnmod(r, a, field, ctx); + + i = BN_ucmp(field, a); + if (i == 0) { + BN_zero(r); + return 1; + } else if (i > 0) + return (r == a) ? 1 : (BN_copy(r, a) != NULL); + + if (r != a) { + if (!bn_wexpand(r, BN_NIST_384_TOP)) + return 0; + r_d = r->d; + nist_cp_bn(r_d, a_d, BN_NIST_384_TOP); + } else + r_d = a_d; + + nist_cp_bn_0(buf.bn, a_d + BN_NIST_384_TOP, top - BN_NIST_384_TOP, + BN_NIST_384_TOP); + +#if defined(NIST_INT64) + { + NIST_INT64 acc; /* accumulator */ + unsigned int *rp = (unsigned int *)r_d; + const unsigned int *bp = (const unsigned int *)buf.ui; + + acc = rp[0]; + acc += bp[12 - 12]; + acc += bp[21 - 12]; + acc += bp[20 - 12]; + acc -= bp[23 - 12]; + rp[0] = (unsigned int)acc; + acc >>= 32; + + acc += rp[1]; + acc += bp[13 - 12]; + acc += bp[22 - 12]; + acc += bp[23 - 12]; + acc -= bp[12 - 12]; + acc -= bp[20 - 12]; + rp[1] = (unsigned int)acc; + acc >>= 32; + + acc += rp[2]; + acc += bp[14 - 12]; + acc += bp[23 - 12]; + acc -= bp[13 - 12]; + acc -= bp[21 - 12]; + rp[2] = (unsigned int)acc; + acc >>= 32; + + acc += rp[3]; + acc += bp[15 - 12]; + acc += bp[12 - 12]; + acc += bp[20 - 12]; + acc += bp[21 - 12]; + acc -= bp[14 - 12]; + acc -= bp[22 - 12]; + acc -= bp[23 - 12]; + rp[3] = (unsigned int)acc; + acc >>= 32; + + acc += rp[4]; + acc += bp[21 - 12]; + acc += bp[21 - 12]; + acc += bp[16 - 12]; + acc += bp[13 - 12]; + acc += bp[12 - 12]; + acc += bp[20 - 12]; + acc += bp[22 - 12]; + acc -= bp[15 - 12]; + acc -= bp[23 - 12]; + acc -= bp[23 - 12]; + rp[4] = (unsigned int)acc; + acc >>= 32; + + acc += rp[5]; + acc += bp[22 - 12]; + acc += bp[22 - 12]; + acc += bp[17 - 12]; + acc += bp[14 - 12]; + acc += bp[13 - 12]; + acc += bp[21 - 12]; + acc += bp[23 - 12]; + acc -= bp[16 - 12]; + rp[5] = (unsigned int)acc; + acc >>= 32; + + acc += rp[6]; + acc += bp[23 - 12]; + acc += bp[23 - 12]; + acc += bp[18 - 12]; + acc += bp[15 - 12]; + acc += bp[14 - 12]; + acc += bp[22 - 12]; + acc -= bp[17 - 12]; + rp[6] = (unsigned int)acc; + acc >>= 32; + + acc += rp[7]; + acc += bp[19 - 12]; + acc += bp[16 - 12]; + acc += bp[15 - 12]; + acc += bp[23 - 12]; + acc -= bp[18 - 12]; + rp[7] = (unsigned int)acc; + acc >>= 32; + + acc += rp[8]; + acc += bp[20 - 12]; + acc += bp[17 - 12]; + acc += bp[16 - 12]; + acc -= bp[19 - 12]; + rp[8] = (unsigned int)acc; + acc >>= 32; + + acc += rp[9]; + acc += bp[21 - 12]; + acc += bp[18 - 12]; + acc += bp[17 - 12]; + acc -= bp[20 - 12]; + rp[9] = (unsigned int)acc; + acc >>= 32; + + acc += rp[10]; + acc += bp[22 - 12]; + acc += bp[19 - 12]; + acc += bp[18 - 12]; + acc -= bp[21 - 12]; + rp[10] = (unsigned int)acc; + acc >>= 32; + + acc += rp[11]; + acc += bp[23 - 12]; + acc += bp[20 - 12]; + acc += bp[19 - 12]; + acc -= bp[22 - 12]; + rp[11] = (unsigned int)acc; + + carry = (int)(acc >> 32); + } +#else + { + BN_ULONG t_d[BN_NIST_384_TOP]; + + /* + * S1 + */ + nist_set_256(t_d, buf.bn, 0, 0, 0, 0, 0, 23 - 4, 22 - 4, 21 - 4); + /* left shift */ + { + register BN_ULONG *ap, t, c; + ap = t_d; + c = 0; + for (i = 3; i != 0; --i) { + t = *ap; + *(ap++) = ((t << 1) | c) & BN_MASK2; + c = (t & BN_TBIT) ? 1 : 0; + } + *ap = c; + } + carry = + (int)bn_add_words(r_d + (128 / BN_BITS2), r_d + (128 / BN_BITS2), + t_d, BN_NIST_256_TOP); + /* + * S2 + */ + carry += (int)bn_add_words(r_d, r_d, buf.bn, BN_NIST_384_TOP); + /* + * S3 + */ + nist_set_384(t_d, buf.bn, 20, 19, 18, 17, 16, 15, 14, 13, 12, 23, 22, + 21); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); + /* + * S4 + */ + nist_set_384(t_d, buf.bn, 19, 18, 17, 16, 15, 14, 13, 12, 20, 0, 23, + 0); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); + /* + * S5 + */ + nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 23, 22, 21, 20, 0, 0, 0, 0); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); + /* + * S6 + */ + nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 23, 22, 21, 0, 0, 20); + carry += (int)bn_add_words(r_d, r_d, t_d, BN_NIST_384_TOP); + /* + * D1 + */ + nist_set_384(t_d, buf.bn, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, + 23); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); + /* + * D2 + */ + nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 22, 21, 20, 0); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); + /* + * D3 + */ + nist_set_384(t_d, buf.bn, 0, 0, 0, 0, 0, 0, 0, 23, 23, 0, 0, 0); + carry -= (int)bn_sub_words(r_d, r_d, t_d, BN_NIST_384_TOP); + + } +#endif + /* see BN_nist_mod_224 for explanation */ + u.f = bn_sub_words; + if (carry > 0) + carry = + (int)bn_sub_words(r_d, r_d, _nist_p_384[carry - 1], + BN_NIST_384_TOP); + else if (carry < 0) { + carry = + (int)bn_add_words(r_d, r_d, _nist_p_384[-carry - 1], + BN_NIST_384_TOP); + mask = 0 - (PTR_SIZE_INT) carry; + u.p = ((PTR_SIZE_INT) bn_sub_words & mask) | + ((PTR_SIZE_INT) bn_add_words & ~mask); + } else + carry = 1; + + mask = + 0 - (PTR_SIZE_INT) (*u.f) (c_d, r_d, _nist_p_384[0], BN_NIST_384_TOP); + mask &= 0 - (PTR_SIZE_INT) carry; + res = c_d; + res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) | + ((PTR_SIZE_INT) r_d & mask)); + nist_cp_bn(r_d, res, BN_NIST_384_TOP); + r->top = BN_NIST_384_TOP; + bn_correct_top(r); + + return 1; +} + +#define BN_NIST_521_RSHIFT (521%BN_BITS2) +#define BN_NIST_521_LSHIFT (BN_BITS2-BN_NIST_521_RSHIFT) +#define BN_NIST_521_TOP_MASK ((BN_ULONG)BN_MASK2>>BN_NIST_521_LSHIFT) + +int BN_nist_mod_521(BIGNUM *r, const BIGNUM *a, const BIGNUM *field, + BN_CTX *ctx) +{ + int top = a->top, i; + BN_ULONG *r_d, *a_d = a->d, t_d[BN_NIST_521_TOP], val, tmp, *res; + PTR_SIZE_INT mask; + static const BIGNUM _bignum_nist_p_521_sqr = { + (BN_ULONG *)_nist_p_521_sqr, + sizeof(_nist_p_521_sqr) / sizeof(_nist_p_521_sqr[0]), + sizeof(_nist_p_521_sqr) / sizeof(_nist_p_521_sqr[0]), + 0, BN_FLG_STATIC_DATA + }; + + field = &_bignum_nist_p_521; /* just to make sure */ + + if (BN_is_negative(a) || BN_ucmp(a, &_bignum_nist_p_521_sqr) >= 0) + return BN_nnmod(r, a, field, ctx); + + i = BN_ucmp(field, a); + if (i == 0) { + BN_zero(r); + return 1; + } else if (i > 0) + return (r == a) ? 1 : (BN_copy(r, a) != NULL); + + if (r != a) { + if (!bn_wexpand(r, BN_NIST_521_TOP)) + return 0; + r_d = r->d; + nist_cp_bn(r_d, a_d, BN_NIST_521_TOP); + } else + r_d = a_d; + + /* upper 521 bits, copy ... */ + nist_cp_bn_0(t_d, a_d + (BN_NIST_521_TOP - 1), + top - (BN_NIST_521_TOP - 1), BN_NIST_521_TOP); + /* ... and right shift */ + for (val = t_d[0], i = 0; i < BN_NIST_521_TOP - 1; i++) { + t_d[i] = (val >> BN_NIST_521_RSHIFT | + (tmp = t_d[i + 1]) << BN_NIST_521_LSHIFT) & BN_MASK2; + val = tmp; + } + t_d[i] = val >> BN_NIST_521_RSHIFT; + /* lower 521 bits */ + r_d[i] &= BN_NIST_521_TOP_MASK; + + bn_add_words(r_d, r_d, t_d, BN_NIST_521_TOP); + mask = + 0 - (PTR_SIZE_INT) bn_sub_words(t_d, r_d, _nist_p_521, + BN_NIST_521_TOP); + res = t_d; + res = (BN_ULONG *)(((PTR_SIZE_INT) res & ~mask) | + ((PTR_SIZE_INT) r_d & mask)); + nist_cp_bn(r_d, res, BN_NIST_521_TOP); + r->top = BN_NIST_521_TOP; + bn_correct_top(r); + + return 1; +} diff --git a/libs/openssl/crypto/bn/bn_prime.c b/libs/openssl/crypto/bn/bn_prime.c new file mode 100644 index 00000000..1d256874 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_prime.c @@ -0,0 +1,515 @@ +/* crypto/bn/bn_prime.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include "bn_lcl.h" +#include + +/* + * NB: these functions have been "upgraded", the deprecated versions (which + * are compatibility wrappers using these functions) are in bn_depr.c. - + * Geoff + */ + +/* + * The quick sieve algorithm approach to weeding out primes is Philip + * Zimmermann's, as implemented in PGP. I have had a read of his comments + * and implemented my own version. + */ +#include "bn_prime.h" + +static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, + const BIGNUM *a1_odd, int k, BN_CTX *ctx, + BN_MONT_CTX *mont); +static int probable_prime(BIGNUM *rnd, int bits); +static int probable_prime_dh(BIGNUM *rnd, int bits, + const BIGNUM *add, const BIGNUM *rem, + BN_CTX *ctx); +static int probable_prime_dh_safe(BIGNUM *rnd, int bits, const BIGNUM *add, + const BIGNUM *rem, BN_CTX *ctx); + +int BN_GENCB_call(BN_GENCB *cb, int a, int b) +{ + /* No callback means continue */ + if (!cb) + return 1; + switch (cb->ver) { + case 1: + /* Deprecated-style callbacks */ + if (!cb->cb.cb_1) + return 1; + cb->cb.cb_1(a, b, cb->arg); + return 1; + case 2: + /* New-style callbacks */ + return cb->cb.cb_2(a, b, cb); + default: + break; + } + /* Unrecognised callback type */ + return 0; +} + +int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, BN_GENCB *cb) +{ + BIGNUM *t; + int found = 0; + int i, j, c1 = 0; + BN_CTX *ctx; + int checks = BN_prime_checks_for_size(bits); + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + if (!t) + goto err; + loop: + /* make a random number and set the top and bottom bits */ + if (add == NULL) { + if (!probable_prime(ret, bits)) + goto err; + } else { + if (safe) { + if (!probable_prime_dh_safe(ret, bits, add, rem, ctx)) + goto err; + } else { + if (!probable_prime_dh(ret, bits, add, rem, ctx)) + goto err; + } + } + /* if (BN_mod_word(ret,(BN_ULONG)3) == 1) goto loop; */ + if (!BN_GENCB_call(cb, 0, c1++)) + /* aborted */ + goto err; + + if (!safe) { + i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb); + if (i == -1) + goto err; + if (i == 0) + goto loop; + } else { + /* + * for "safe prime" generation, check that (p-1)/2 is prime. Since a + * prime is odd, We just need to divide by 2 + */ + if (!BN_rshift1(t, ret)) + goto err; + + for (i = 0; i < checks; i++) { + j = BN_is_prime_fasttest_ex(ret, 1, ctx, 0, cb); + if (j == -1) + goto err; + if (j == 0) + goto loop; + + j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, cb); + if (j == -1) + goto err; + if (j == 0) + goto loop; + + if (!BN_GENCB_call(cb, 2, c1 - 1)) + goto err; + /* We have a safe prime test pass */ + } + } + /* we have a prime :-) */ + found = 1; + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + bn_check_top(ret); + return found; +} + +int BN_is_prime_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, + BN_GENCB *cb) +{ + return BN_is_prime_fasttest_ex(a, checks, ctx_passed, 0, cb); +} + +int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx_passed, + int do_trial_division, BN_GENCB *cb) +{ + int i, j, ret = -1; + int k; + BN_CTX *ctx = NULL; + BIGNUM *A1, *A1_odd, *check; /* taken from ctx */ + BN_MONT_CTX *mont = NULL; + const BIGNUM *A = NULL; + + if (BN_cmp(a, BN_value_one()) <= 0) + return 0; + + if (checks == BN_prime_checks) + checks = BN_prime_checks_for_size(BN_num_bits(a)); + + /* first look for small factors */ + if (!BN_is_odd(a)) + /* a is even => a is prime if and only if a == 2 */ + return BN_is_word(a, 2); + if (do_trial_division) { + for (i = 1; i < NUMPRIMES; i++) + if (BN_mod_word(a, primes[i]) == 0) + return 0; + if (!BN_GENCB_call(cb, 1, -1)) + goto err; + } + + if (ctx_passed != NULL) + ctx = ctx_passed; + else if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + + /* A := abs(a) */ + if (a->neg) { + BIGNUM *t; + if ((t = BN_CTX_get(ctx)) == NULL) + goto err; + BN_copy(t, a); + t->neg = 0; + A = t; + } else + A = a; + A1 = BN_CTX_get(ctx); + A1_odd = BN_CTX_get(ctx); + check = BN_CTX_get(ctx); + if (check == NULL) + goto err; + + /* compute A1 := A - 1 */ + if (!BN_copy(A1, A)) + goto err; + if (!BN_sub_word(A1, 1)) + goto err; + if (BN_is_zero(A1)) { + ret = 0; + goto err; + } + + /* write A1 as A1_odd * 2^k */ + k = 1; + while (!BN_is_bit_set(A1, k)) + k++; + if (!BN_rshift(A1_odd, A1, k)) + goto err; + + /* Montgomery setup for computations mod A */ + mont = BN_MONT_CTX_new(); + if (mont == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, A, ctx)) + goto err; + + for (i = 0; i < checks; i++) { + if (!BN_pseudo_rand_range(check, A1)) + goto err; + if (!BN_add_word(check, 1)) + goto err; + /* now 1 <= check < A */ + + j = witness(check, A, A1, A1_odd, k, ctx, mont); + if (j == -1) + goto err; + if (j) { + ret = 0; + goto err; + } + if (!BN_GENCB_call(cb, 1, i)) + goto err; + } + ret = 1; + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + if (ctx_passed == NULL) + BN_CTX_free(ctx); + } + if (mont != NULL) + BN_MONT_CTX_free(mont); + + return (ret); +} + +static int witness(BIGNUM *w, const BIGNUM *a, const BIGNUM *a1, + const BIGNUM *a1_odd, int k, BN_CTX *ctx, + BN_MONT_CTX *mont) +{ + if (!BN_mod_exp_mont(w, w, a1_odd, a, ctx, mont)) /* w := w^a1_odd mod a */ + return -1; + if (BN_is_one(w)) + return 0; /* probably prime */ + if (BN_cmp(w, a1) == 0) + return 0; /* w == -1 (mod a), 'a' is probably prime */ + while (--k) { + if (!BN_mod_mul(w, w, w, a, ctx)) /* w := w^2 mod a */ + return -1; + if (BN_is_one(w)) + return 1; /* 'a' is composite, otherwise a previous 'w' + * would have been == -1 (mod 'a') */ + if (BN_cmp(w, a1) == 0) + return 0; /* w == -1 (mod a), 'a' is probably prime */ + } + /* + * If we get here, 'w' is the (a-1)/2-th power of the original 'w', and + * it is neither -1 nor +1 -- so 'a' cannot be prime + */ + bn_check_top(w); + return 1; +} + +static int probable_prime(BIGNUM *rnd, int bits) +{ + int i; + prime_t mods[NUMPRIMES]; + BN_ULONG delta, maxdelta; + + again: + if (!BN_rand(rnd, bits, 1, 1)) + return (0); + /* we now have a random number 'rand' to test. */ + for (i = 1; i < NUMPRIMES; i++) + mods[i] = (prime_t) BN_mod_word(rnd, (BN_ULONG)primes[i]); + maxdelta = BN_MASK2 - primes[NUMPRIMES - 1]; + delta = 0; + loop:for (i = 1; i < NUMPRIMES; i++) { + /* + * check that rnd is not a prime and also that gcd(rnd-1,primes) == 1 + * (except for 2) + */ + if (((mods[i] + delta) % primes[i]) <= 1) { + delta += 2; + if (delta > maxdelta) + goto again; + goto loop; + } + } + if (!BN_add_word(rnd, delta)) + return (0); + bn_check_top(rnd); + return (1); +} + +static int probable_prime_dh(BIGNUM *rnd, int bits, + const BIGNUM *add, const BIGNUM *rem, + BN_CTX *ctx) +{ + int i, ret = 0; + BIGNUM *t1; + + BN_CTX_start(ctx); + if ((t1 = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_rand(rnd, bits, 0, 1)) + goto err; + + /* we need ((rnd-rem) % add) == 0 */ + + if (!BN_mod(t1, rnd, add, ctx)) + goto err; + if (!BN_sub(rnd, rnd, t1)) + goto err; + if (rem == NULL) { + if (!BN_add_word(rnd, 1)) + goto err; + } else { + if (!BN_add(rnd, rnd, rem)) + goto err; + } + + /* we now have a random number 'rand' to test. */ + + loop:for (i = 1; i < NUMPRIMES; i++) { + /* check that rnd is a prime */ + if (BN_mod_word(rnd, (BN_ULONG)primes[i]) <= 1) { + if (!BN_add(rnd, rnd, add)) + goto err; + goto loop; + } + } + ret = 1; + err: + BN_CTX_end(ctx); + bn_check_top(rnd); + return (ret); +} + +static int probable_prime_dh_safe(BIGNUM *p, int bits, const BIGNUM *padd, + const BIGNUM *rem, BN_CTX *ctx) +{ + int i, ret = 0; + BIGNUM *t1, *qadd, *q; + + bits--; + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + qadd = BN_CTX_get(ctx); + if (qadd == NULL) + goto err; + + if (!BN_rshift1(qadd, padd)) + goto err; + + if (!BN_rand(q, bits, 0, 1)) + goto err; + + /* we need ((rnd-rem) % add) == 0 */ + if (!BN_mod(t1, q, qadd, ctx)) + goto err; + if (!BN_sub(q, q, t1)) + goto err; + if (rem == NULL) { + if (!BN_add_word(q, 1)) + goto err; + } else { + if (!BN_rshift1(t1, rem)) + goto err; + if (!BN_add(q, q, t1)) + goto err; + } + + /* we now have a random number 'rand' to test. */ + if (!BN_lshift1(p, q)) + goto err; + if (!BN_add_word(p, 1)) + goto err; + + loop:for (i = 1; i < NUMPRIMES; i++) { + /* check that p and q are prime */ + /* + * check that for p and q gcd(p-1,primes) == 1 (except for 2) + */ + if ((BN_mod_word(p, (BN_ULONG)primes[i]) == 0) || + (BN_mod_word(q, (BN_ULONG)primes[i]) == 0)) { + if (!BN_add(p, p, padd)) + goto err; + if (!BN_add(q, q, qadd)) + goto err; + goto loop; + } + } + ret = 1; + err: + BN_CTX_end(ctx); + bn_check_top(p); + return (ret); +} diff --git a/libs/openssl/crypto/bn/bn_prime.h b/libs/openssl/crypto/bn/bn_prime.h new file mode 100644 index 00000000..5cf0de16 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_prime.h @@ -0,0 +1,326 @@ +/* Auto generated by bn_prime.pl */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef EIGHT_BIT +# define NUMPRIMES 2048 +typedef unsigned short prime_t; +#else +# define NUMPRIMES 54 +typedef unsigned char prime_t; +#endif +static const prime_t primes[NUMPRIMES] = { + 2, 3, 5, 7, 11, 13, 17, 19, + 23, 29, 31, 37, 41, 43, 47, 53, + 59, 61, 67, 71, 73, 79, 83, 89, + 97, 101, 103, 107, 109, 113, 127, 131, + 137, 139, 149, 151, 157, 163, 167, 173, + 179, 181, 191, 193, 197, 199, 211, 223, + 227, 229, 233, 239, 241, 251, +#ifndef EIGHT_BIT + 257, 263, + 269, 271, 277, 281, 283, 293, 307, 311, + 313, 317, 331, 337, 347, 349, 353, 359, + 367, 373, 379, 383, 389, 397, 401, 409, + 419, 421, 431, 433, 439, 443, 449, 457, + 461, 463, 467, 479, 487, 491, 499, 503, + 509, 521, 523, 541, 547, 557, 563, 569, + 571, 577, 587, 593, 599, 601, 607, 613, + 617, 619, 631, 641, 643, 647, 653, 659, + 661, 673, 677, 683, 691, 701, 709, 719, + 727, 733, 739, 743, 751, 757, 761, 769, + 773, 787, 797, 809, 811, 821, 823, 827, + 829, 839, 853, 857, 859, 863, 877, 881, + 883, 887, 907, 911, 919, 929, 937, 941, + 947, 953, 967, 971, 977, 983, 991, 997, + 1009, 1013, 1019, 1021, 1031, 1033, 1039, 1049, + 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097, + 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, + 1171, 1181, 1187, 1193, 1201, 1213, 1217, 1223, + 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, + 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, + 1327, 1361, 1367, 1373, 1381, 1399, 1409, 1423, + 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459, + 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, + 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, + 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619, + 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, + 1697, 1699, 1709, 1721, 1723, 1733, 1741, 1747, + 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811, + 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, + 1879, 1889, 1901, 1907, 1913, 1931, 1933, 1949, + 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003, + 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, + 2081, 2083, 2087, 2089, 2099, 2111, 2113, 2129, + 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203, + 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, + 2269, 2273, 2281, 2287, 2293, 2297, 2309, 2311, + 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377, + 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, + 2437, 2441, 2447, 2459, 2467, 2473, 2477, 2503, + 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579, + 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, + 2659, 2663, 2671, 2677, 2683, 2687, 2689, 2693, + 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741, + 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, + 2803, 2819, 2833, 2837, 2843, 2851, 2857, 2861, + 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939, + 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, + 3019, 3023, 3037, 3041, 3049, 3061, 3067, 3079, + 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167, + 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, + 3229, 3251, 3253, 3257, 3259, 3271, 3299, 3301, + 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347, + 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, + 3433, 3449, 3457, 3461, 3463, 3467, 3469, 3491, + 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541, + 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, + 3613, 3617, 3623, 3631, 3637, 3643, 3659, 3671, + 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727, + 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, + 3803, 3821, 3823, 3833, 3847, 3851, 3853, 3863, + 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923, + 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, + 4007, 4013, 4019, 4021, 4027, 4049, 4051, 4057, + 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129, + 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, + 4217, 4219, 4229, 4231, 4241, 4243, 4253, 4259, + 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337, + 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, + 4421, 4423, 4441, 4447, 4451, 4457, 4463, 4481, + 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547, + 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, + 4637, 4639, 4643, 4649, 4651, 4657, 4663, 4673, + 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751, + 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, + 4817, 4831, 4861, 4871, 4877, 4889, 4903, 4909, + 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967, + 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, + 5021, 5023, 5039, 5051, 5059, 5077, 5081, 5087, + 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167, + 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, + 5237, 5261, 5273, 5279, 5281, 5297, 5303, 5309, + 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399, + 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, + 5449, 5471, 5477, 5479, 5483, 5501, 5503, 5507, + 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573, + 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, + 5657, 5659, 5669, 5683, 5689, 5693, 5701, 5711, + 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791, + 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, + 5851, 5857, 5861, 5867, 5869, 5879, 5881, 5897, + 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007, + 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, + 6079, 6089, 6091, 6101, 6113, 6121, 6131, 6133, + 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211, + 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, + 6277, 6287, 6299, 6301, 6311, 6317, 6323, 6329, + 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379, + 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, + 6481, 6491, 6521, 6529, 6547, 6551, 6553, 6563, + 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637, + 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, + 6703, 6709, 6719, 6733, 6737, 6761, 6763, 6779, + 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833, + 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, + 6911, 6917, 6947, 6949, 6959, 6961, 6967, 6971, + 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027, + 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, + 7127, 7129, 7151, 7159, 7177, 7187, 7193, 7207, + 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253, + 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, + 7351, 7369, 7393, 7411, 7417, 7433, 7451, 7457, + 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517, + 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, + 7573, 7577, 7583, 7589, 7591, 7603, 7607, 7621, + 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691, + 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, + 7759, 7789, 7793, 7817, 7823, 7829, 7841, 7853, + 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919, + 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, + 8011, 8017, 8039, 8053, 8059, 8069, 8081, 8087, + 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161, + 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, + 8233, 8237, 8243, 8263, 8269, 8273, 8287, 8291, + 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369, + 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, + 8447, 8461, 8467, 8501, 8513, 8521, 8527, 8537, + 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609, + 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, + 8681, 8689, 8693, 8699, 8707, 8713, 8719, 8731, + 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803, + 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, + 8863, 8867, 8887, 8893, 8923, 8929, 8933, 8941, + 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011, + 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, + 9103, 9109, 9127, 9133, 9137, 9151, 9157, 9161, + 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227, + 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, + 9319, 9323, 9337, 9341, 9343, 9349, 9371, 9377, + 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433, + 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, + 9497, 9511, 9521, 9533, 9539, 9547, 9551, 9587, + 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649, + 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, + 9739, 9743, 9749, 9767, 9769, 9781, 9787, 9791, + 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857, + 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, + 9931, 9941, 9949, 9967, 9973, 10007, 10009, 10037, + 10039, 10061, 10067, 10069, 10079, 10091, 10093, 10099, + 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163, + 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247, + 10253, 10259, 10267, 10271, 10273, 10289, 10301, 10303, + 10313, 10321, 10331, 10333, 10337, 10343, 10357, 10369, + 10391, 10399, 10427, 10429, 10433, 10453, 10457, 10459, + 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531, + 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, + 10631, 10639, 10651, 10657, 10663, 10667, 10687, 10691, + 10709, 10711, 10723, 10729, 10733, 10739, 10753, 10771, + 10781, 10789, 10799, 10831, 10837, 10847, 10853, 10859, + 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937, + 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, + 11027, 11047, 11057, 11059, 11069, 11071, 11083, 11087, + 11093, 11113, 11117, 11119, 11131, 11149, 11159, 11161, + 11171, 11173, 11177, 11197, 11213, 11239, 11243, 11251, + 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317, + 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, + 11411, 11423, 11437, 11443, 11447, 11467, 11471, 11483, + 11489, 11491, 11497, 11503, 11519, 11527, 11549, 11551, + 11579, 11587, 11593, 11597, 11617, 11621, 11633, 11657, + 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731, + 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, + 11821, 11827, 11831, 11833, 11839, 11863, 11867, 11887, + 11897, 11903, 11909, 11923, 11927, 11933, 11939, 11941, + 11953, 11959, 11969, 11971, 11981, 11987, 12007, 12011, + 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101, + 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, + 12163, 12197, 12203, 12211, 12227, 12239, 12241, 12251, + 12253, 12263, 12269, 12277, 12281, 12289, 12301, 12323, + 12329, 12343, 12347, 12373, 12377, 12379, 12391, 12401, + 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473, + 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, + 12539, 12541, 12547, 12553, 12569, 12577, 12583, 12589, + 12601, 12611, 12613, 12619, 12637, 12641, 12647, 12653, + 12659, 12671, 12689, 12697, 12703, 12713, 12721, 12739, + 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821, + 12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907, + 12911, 12917, 12919, 12923, 12941, 12953, 12959, 12967, + 12973, 12979, 12983, 13001, 13003, 13007, 13009, 13033, + 13037, 13043, 13049, 13063, 13093, 13099, 13103, 13109, + 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177, + 13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, + 13267, 13291, 13297, 13309, 13313, 13327, 13331, 13337, + 13339, 13367, 13381, 13397, 13399, 13411, 13417, 13421, + 13441, 13451, 13457, 13463, 13469, 13477, 13487, 13499, + 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597, + 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, + 13687, 13691, 13693, 13697, 13709, 13711, 13721, 13723, + 13729, 13751, 13757, 13759, 13763, 13781, 13789, 13799, + 13807, 13829, 13831, 13841, 13859, 13873, 13877, 13879, + 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933, + 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, + 14051, 14057, 14071, 14081, 14083, 14087, 14107, 14143, + 14149, 14153, 14159, 14173, 14177, 14197, 14207, 14221, + 14243, 14249, 14251, 14281, 14293, 14303, 14321, 14323, + 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407, + 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, + 14479, 14489, 14503, 14519, 14533, 14537, 14543, 14549, + 14551, 14557, 14561, 14563, 14591, 14593, 14621, 14627, + 14629, 14633, 14639, 14653, 14657, 14669, 14683, 14699, + 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753, + 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, + 14827, 14831, 14843, 14851, 14867, 14869, 14879, 14887, + 14891, 14897, 14923, 14929, 14939, 14947, 14951, 14957, + 14969, 14983, 15013, 15017, 15031, 15053, 15061, 15073, + 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137, + 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217, + 15227, 15233, 15241, 15259, 15263, 15269, 15271, 15277, + 15287, 15289, 15299, 15307, 15313, 15319, 15329, 15331, + 15349, 15359, 15361, 15373, 15377, 15383, 15391, 15401, + 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473, + 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, + 15581, 15583, 15601, 15607, 15619, 15629, 15641, 15643, + 15647, 15649, 15661, 15667, 15671, 15679, 15683, 15727, + 15731, 15733, 15737, 15739, 15749, 15761, 15767, 15773, + 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859, + 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, + 15923, 15937, 15959, 15971, 15973, 15991, 16001, 16007, + 16033, 16057, 16061, 16063, 16067, 16069, 16073, 16087, + 16091, 16097, 16103, 16111, 16127, 16139, 16141, 16183, + 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249, + 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, + 16361, 16363, 16369, 16381, 16411, 16417, 16421, 16427, + 16433, 16447, 16451, 16453, 16477, 16481, 16487, 16493, + 16519, 16529, 16547, 16553, 16561, 16567, 16573, 16603, + 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661, + 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, + 16759, 16763, 16787, 16811, 16823, 16829, 16831, 16843, + 16871, 16879, 16883, 16889, 16901, 16903, 16921, 16927, + 16931, 16937, 16943, 16963, 16979, 16981, 16987, 16993, + 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053, + 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, + 17167, 17183, 17189, 17191, 17203, 17207, 17209, 17231, + 17239, 17257, 17291, 17293, 17299, 17317, 17321, 17327, + 17333, 17341, 17351, 17359, 17377, 17383, 17387, 17389, + 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467, + 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, + 17539, 17551, 17569, 17573, 17579, 17581, 17597, 17599, + 17609, 17623, 17627, 17657, 17659, 17669, 17681, 17683, + 17707, 17713, 17729, 17737, 17747, 17749, 17761, 17783, + 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863, +#endif +}; diff --git a/libs/openssl/crypto/bn/bn_prime.pl b/libs/openssl/crypto/bn/bn_prime.pl new file mode 100644 index 00000000..3fafb6f3 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_prime.pl @@ -0,0 +1,119 @@ +#!/usr/local/bin/perl +# bn_prime.pl + +$num=2048; +$num=$ARGV[0] if ($#ARGV >= 0); + +push(@primes,2); +$p=1; +loop: while ($#primes < $num-1) + { + $p+=2; + $s=int(sqrt($p)); + + for ($i=0; defined($primes[$i]) && $primes[$i]<=$s; $i++) + { + next loop if (($p%$primes[$i]) == 0); + } + push(@primes,$p); + } + +# print <<"EOF"; +# /* Auto generated by bn_prime.pl */ +# /* Copyright (C) 1995-1997 Eric Young (eay\@mincom.oz.au). +# * All rights reserved. +# * Copyright remains Eric Young's, and as such any Copyright notices in +# * the code are not to be removed. +# * See the COPYRIGHT file in the SSLeay distribution for more details. +# */ +# +# EOF + +print <<\EOF; +/* Auto generated by bn_prime.pl */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +EOF + +for ($i=0; $i <= $#primes; $i++) + { + if ($primes[$i] > 256) + { + $eight=$i; + last; + } + } + +printf "#ifndef EIGHT_BIT\n"; +printf "#define NUMPRIMES %d\n",$num; +printf "typedef unsigned short prime_t;\n"; +printf "#else\n"; +printf "#define NUMPRIMES %d\n",$eight; +printf "typedef unsigned char prime_t;\n"; +printf "#endif\n"; +print "static const prime_t primes[NUMPRIMES]=\n\t{\n\t"; +$init=0; +for ($i=0; $i <= $#primes; $i++) + { + printf "\n#ifndef EIGHT_BIT\n\t" if ($primes[$i] > 256) && !($init++); + printf("\n\t") if (($i%8) == 0) && ($i != 0); + printf("%4d,",$primes[$i]); + } +print "\n#endif\n\t};\n"; + + diff --git a/libs/openssl/crypto/bn/bn_print.c b/libs/openssl/crypto/bn/bn_print.c new file mode 100644 index 00000000..bfa31efc --- /dev/null +++ b/libs/openssl/crypto/bn/bn_print.c @@ -0,0 +1,397 @@ +/* crypto/bn/bn_print.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include "cryptlib.h" +#include +#include "bn_lcl.h" + +static const char Hex[] = "0123456789ABCDEF"; + +/* Must 'OPENSSL_free' the returned data */ +char *BN_bn2hex(const BIGNUM *a) +{ + int i, j, v, z = 0; + char *buf; + char *p; + + if (a->neg && BN_is_zero(a)) { + /* "-0" == 3 bytes including NULL terminator */ + buf = OPENSSL_malloc(3); + } else { + buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2); + } + if (buf == NULL) { + BNerr(BN_F_BN_BN2HEX, ERR_R_MALLOC_FAILURE); + goto err; + } + p = buf; + if (a->neg) + *(p++) = '-'; + if (BN_is_zero(a)) + *(p++) = '0'; + for (i = a->top - 1; i >= 0; i--) { + for (j = BN_BITS2 - 8; j >= 0; j -= 8) { + /* strip leading zeros */ + v = ((int)(a->d[i] >> (long)j)) & 0xff; + if (z || (v != 0)) { + *(p++) = Hex[v >> 4]; + *(p++) = Hex[v & 0x0f]; + z = 1; + } + } + } + *p = '\0'; + err: + return (buf); +} + +/* Must 'OPENSSL_free' the returned data */ +char *BN_bn2dec(const BIGNUM *a) +{ + int i = 0, num, ok = 0; + char *buf = NULL; + char *p; + BIGNUM *t = NULL; + BN_ULONG *bn_data = NULL, *lp; + + /*- + * get an upper bound for the length of the decimal integer + * num <= (BN_num_bits(a) + 1) * log(2) + * <= 3 * BN_num_bits(a) * 0.1001 + log(2) + 1 (rounding error) + * <= BN_num_bits(a)/10 + BN_num_bits/1000 + 1 + 1 + */ + i = BN_num_bits(a) * 3; + num = (i / 10 + i / 1000 + 1) + 1; + bn_data = + (BN_ULONG *)OPENSSL_malloc((num / BN_DEC_NUM + 1) * sizeof(BN_ULONG)); + buf = (char *)OPENSSL_malloc(num + 3); + if ((buf == NULL) || (bn_data == NULL)) { + BNerr(BN_F_BN_BN2DEC, ERR_R_MALLOC_FAILURE); + goto err; + } + if ((t = BN_dup(a)) == NULL) + goto err; + +#define BUF_REMAIN (num+3 - (size_t)(p - buf)) + p = buf; + lp = bn_data; + if (BN_is_zero(t)) { + *(p++) = '0'; + *(p++) = '\0'; + } else { + if (BN_is_negative(t)) + *p++ = '-'; + + i = 0; + while (!BN_is_zero(t)) { + *lp = BN_div_word(t, BN_DEC_CONV); + lp++; + } + lp--; + /* + * We now have a series of blocks, BN_DEC_NUM chars in length, where + * the last one needs truncation. The blocks need to be reversed in + * order. + */ + BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT1, *lp); + while (*p) + p++; + while (lp != bn_data) { + lp--; + BIO_snprintf(p, BUF_REMAIN, BN_DEC_FMT2, *lp); + while (*p) + p++; + } + } + ok = 1; + err: + if (bn_data != NULL) + OPENSSL_free(bn_data); + if (t != NULL) + BN_free(t); + if (!ok && buf) { + OPENSSL_free(buf); + buf = NULL; + } + + return (buf); +} + +int BN_hex2bn(BIGNUM **bn, const char *a) +{ + BIGNUM *ret = NULL; + BN_ULONG l = 0; + int neg = 0, h, m, i, j, k, c; + int num; + + if ((a == NULL) || (*a == '\0')) + return (0); + + if (*a == '-') { + neg = 1; + a++; + } + + for (i = 0; i <= (INT_MAX/4) && isxdigit((unsigned char)a[i]); i++) + continue; + + if (i > INT_MAX/4) + goto err; + + num = i + neg; + if (bn == NULL) + return (num); + + /* a is the start of the hex digits, and it is 'i' long */ + if (*bn == NULL) { + if ((ret = BN_new()) == NULL) + return (0); + } else { + ret = *bn; + BN_zero(ret); + } + + /* i is the number of hex digits */ + if (bn_expand(ret, i * 4) == NULL) + goto err; + + j = i; /* least significant 'hex' */ + m = 0; + h = 0; + while (j > 0) { + m = ((BN_BYTES * 2) <= j) ? (BN_BYTES * 2) : j; + l = 0; + for (;;) { + c = a[j - m]; + if ((c >= '0') && (c <= '9')) + k = c - '0'; + else if ((c >= 'a') && (c <= 'f')) + k = c - 'a' + 10; + else if ((c >= 'A') && (c <= 'F')) + k = c - 'A' + 10; + else + k = 0; /* paranoia */ + l = (l << 4) | k; + + if (--m <= 0) { + ret->d[h++] = l; + break; + } + } + j -= (BN_BYTES * 2); + } + ret->top = h; + bn_correct_top(ret); + ret->neg = neg; + + *bn = ret; + bn_check_top(ret); + return (num); + err: + if (*bn == NULL) + BN_free(ret); + return (0); +} + +int BN_dec2bn(BIGNUM **bn, const char *a) +{ + BIGNUM *ret = NULL; + BN_ULONG l = 0; + int neg = 0, i, j; + int num; + + if ((a == NULL) || (*a == '\0')) + return (0); + if (*a == '-') { + neg = 1; + a++; + } + + for (i = 0; i <= (INT_MAX/4) && isdigit((unsigned char)a[i]); i++) + continue; + + if (i > INT_MAX/4) + goto err; + + num = i + neg; + if (bn == NULL) + return (num); + + /* + * a is the start of the digits, and it is 'i' long. We chop it into + * BN_DEC_NUM digits at a time + */ + if (*bn == NULL) { + if ((ret = BN_new()) == NULL) + return (0); + } else { + ret = *bn; + BN_zero(ret); + } + + /* i is the number of digits, a bit of an over expand */ + if (bn_expand(ret, i * 4) == NULL) + goto err; + + j = BN_DEC_NUM - (i % BN_DEC_NUM); + if (j == BN_DEC_NUM) + j = 0; + l = 0; + while (*a) { + l *= 10; + l += *a - '0'; + a++; + if (++j == BN_DEC_NUM) { + BN_mul_word(ret, BN_DEC_CONV); + BN_add_word(ret, l); + l = 0; + j = 0; + } + } + ret->neg = neg; + + bn_correct_top(ret); + *bn = ret; + bn_check_top(ret); + return (num); + err: + if (*bn == NULL) + BN_free(ret); + return (0); +} + +int BN_asc2bn(BIGNUM **bn, const char *a) +{ + const char *p = a; + if (*p == '-') + p++; + + if (p[0] == '0' && (p[1] == 'X' || p[1] == 'x')) { + if (!BN_hex2bn(bn, p + 2)) + return 0; + } else { + if (!BN_dec2bn(bn, p)) + return 0; + } + if (*a == '-') + (*bn)->neg = 1; + return 1; +} + +#ifndef OPENSSL_NO_BIO +# ifndef OPENSSL_NO_FP_API +int BN_print_fp(FILE *fp, const BIGNUM *a) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) + return (0); + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = BN_print(b, a); + BIO_free(b); + return (ret); +} +# endif + +int BN_print(BIO *bp, const BIGNUM *a) +{ + int i, j, v, z = 0; + int ret = 0; + + if ((a->neg) && (BIO_write(bp, "-", 1) != 1)) + goto end; + if (BN_is_zero(a) && (BIO_write(bp, "0", 1) != 1)) + goto end; + for (i = a->top - 1; i >= 0; i--) { + for (j = BN_BITS2 - 4; j >= 0; j -= 4) { + /* strip leading zeros */ + v = ((int)(a->d[i] >> (long)j)) & 0x0f; + if (z || (v != 0)) { + if (BIO_write(bp, &(Hex[v]), 1) != 1) + goto end; + z = 1; + } + } + } + ret = 1; + end: + return (ret); +} +#endif + +char *BN_options(void) +{ + static int init = 0; + static char data[16]; + + if (!init) { + init++; +#ifdef BN_LLONG + BIO_snprintf(data, sizeof data, "bn(%d,%d)", + (int)sizeof(BN_ULLONG) * 8, (int)sizeof(BN_ULONG) * 8); +#else + BIO_snprintf(data, sizeof data, "bn(%d,%d)", + (int)sizeof(BN_ULONG) * 8, (int)sizeof(BN_ULONG) * 8); +#endif + } + return (data); +} diff --git a/libs/openssl/crypto/bn/bn_rand.c b/libs/openssl/crypto/bn/bn_rand.c new file mode 100644 index 00000000..f9fb2e9e --- /dev/null +++ b/libs/openssl/crypto/bn/bn_rand.c @@ -0,0 +1,295 @@ +/* crypto/bn/bn_rand.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include "bn_lcl.h" +#include + +static int bnrand(int pseudorand, BIGNUM *rnd, int bits, int top, int bottom) +{ + unsigned char *buf = NULL; + int ret = 0, bit, bytes, mask; + time_t tim; + + if (bits < 0 || (bits == 1 && top > 0)) { + BNerr(BN_F_BNRAND, BN_R_BITS_TOO_SMALL); + return 0; + } + + if (bits == 0) { + BN_zero(rnd); + return 1; + } + + bytes = (bits + 7) / 8; + bit = (bits - 1) % 8; + mask = 0xff << (bit + 1); + + buf = (unsigned char *)OPENSSL_malloc(bytes); + if (buf == NULL) { + BNerr(BN_F_BNRAND, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* make a random number and set the top and bottom bits */ + time(&tim); + RAND_add(&tim, sizeof(tim), 0.0); + + if (pseudorand) { + if (RAND_pseudo_bytes(buf, bytes) == -1) + goto err; + } else { + if (RAND_bytes(buf, bytes) <= 0) + goto err; + } + +#if 1 + if (pseudorand == 2) { + /* + * generate patterns that are more likely to trigger BN library bugs + */ + int i; + unsigned char c; + + for (i = 0; i < bytes; i++) { + if (RAND_pseudo_bytes(&c, 1) < 0) + goto err; + if (c >= 128 && i > 0) + buf[i] = buf[i - 1]; + else if (c < 42) + buf[i] = 0; + else if (c < 84) + buf[i] = 255; + } + } +#endif + + if (top >= 0) { + if (top) { + if (bit == 0) { + buf[0] = 1; + buf[1] |= 0x80; + } else { + buf[0] |= (3 << (bit - 1)); + } + } else { + buf[0] |= (1 << bit); + } + } + buf[0] &= ~mask; + if (bottom) /* set bottom bit if requested */ + buf[bytes - 1] |= 1; + if (!BN_bin2bn(buf, bytes, rnd)) + goto err; + ret = 1; + err: + if (buf != NULL) { + OPENSSL_cleanse(buf, bytes); + OPENSSL_free(buf); + } + bn_check_top(rnd); + return (ret); +} + +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) +{ + return bnrand(0, rnd, bits, top, bottom); +} + +int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) +{ + return bnrand(1, rnd, bits, top, bottom); +} + +#if 1 +int BN_bntest_rand(BIGNUM *rnd, int bits, int top, int bottom) +{ + return bnrand(2, rnd, bits, top, bottom); +} +#endif + +/* random number r: 0 <= r < range */ +static int bn_rand_range(int pseudo, BIGNUM *r, const BIGNUM *range) +{ + int (*bn_rand) (BIGNUM *, int, int, int) = + pseudo ? BN_pseudo_rand : BN_rand; + int n; + int count = 100; + + if (range->neg || BN_is_zero(range)) { + BNerr(BN_F_BN_RAND_RANGE, BN_R_INVALID_RANGE); + return 0; + } + + n = BN_num_bits(range); /* n > 0 */ + + /* BN_is_bit_set(range, n - 1) always holds */ + + if (n == 1) + BN_zero(r); + else if (!BN_is_bit_set(range, n - 2) && !BN_is_bit_set(range, n - 3)) { + /* + * range = 100..._2, so 3*range (= 11..._2) is exactly one bit longer + * than range + */ + do { + if (!bn_rand(r, n + 1, -1, 0)) + return 0; + /* + * If r < 3*range, use r := r MOD range (which is either r, r - + * range, or r - 2*range). Otherwise, iterate once more. Since + * 3*range = 11..._2, each iteration succeeds with probability >= + * .75. + */ + if (BN_cmp(r, range) >= 0) { + if (!BN_sub(r, r, range)) + return 0; + if (BN_cmp(r, range) >= 0) + if (!BN_sub(r, r, range)) + return 0; + } + + if (!--count) { + BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS); + return 0; + } + + } + while (BN_cmp(r, range) >= 0); + } else { + do { + /* range = 11..._2 or range = 101..._2 */ + if (!bn_rand(r, n, -1, 0)) + return 0; + + if (!--count) { + BNerr(BN_F_BN_RAND_RANGE, BN_R_TOO_MANY_ITERATIONS); + return 0; + } + } + while (BN_cmp(r, range) >= 0); + } + + bn_check_top(r); + return 1; +} + +int BN_rand_range(BIGNUM *r, const BIGNUM *range) +{ + return bn_rand_range(0, r, range); +} + +int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range) +{ + return bn_rand_range(1, r, range); +} diff --git a/libs/openssl/crypto/bn/bn_recp.c b/libs/openssl/crypto/bn/bn_recp.c new file mode 100644 index 00000000..f047040e --- /dev/null +++ b/libs/openssl/crypto/bn/bn_recp.c @@ -0,0 +1,252 @@ +/* crypto/bn/bn_recp.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +void BN_RECP_CTX_init(BN_RECP_CTX *recp) +{ + BN_init(&(recp->N)); + BN_init(&(recp->Nr)); + recp->num_bits = 0; + recp->shift = 0; + recp->flags = 0; +} + +BN_RECP_CTX *BN_RECP_CTX_new(void) +{ + BN_RECP_CTX *ret; + + if ((ret = (BN_RECP_CTX *)OPENSSL_malloc(sizeof(BN_RECP_CTX))) == NULL) + return (NULL); + + BN_RECP_CTX_init(ret); + ret->flags = BN_FLG_MALLOCED; + return (ret); +} + +void BN_RECP_CTX_free(BN_RECP_CTX *recp) +{ + if (recp == NULL) + return; + + BN_free(&(recp->N)); + BN_free(&(recp->Nr)); + if (recp->flags & BN_FLG_MALLOCED) + OPENSSL_free(recp); +} + +int BN_RECP_CTX_set(BN_RECP_CTX *recp, const BIGNUM *d, BN_CTX *ctx) +{ + if (!BN_copy(&(recp->N), d)) + return 0; + BN_zero(&(recp->Nr)); + recp->num_bits = BN_num_bits(d); + recp->shift = 0; + return (1); +} + +int BN_mod_mul_reciprocal(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, + BN_RECP_CTX *recp, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *a; + const BIGNUM *ca; + + BN_CTX_start(ctx); + if ((a = BN_CTX_get(ctx)) == NULL) + goto err; + if (y != NULL) { + if (x == y) { + if (!BN_sqr(a, x, ctx)) + goto err; + } else { + if (!BN_mul(a, x, y, ctx)) + goto err; + } + ca = a; + } else + ca = x; /* Just do the mod */ + + ret = BN_div_recp(NULL, r, ca, recp, ctx); + err: + BN_CTX_end(ctx); + bn_check_top(r); + return (ret); +} + +int BN_div_recp(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m, + BN_RECP_CTX *recp, BN_CTX *ctx) +{ + int i, j, ret = 0; + BIGNUM *a, *b, *d, *r; + + BN_CTX_start(ctx); + a = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + if (dv != NULL) + d = dv; + else + d = BN_CTX_get(ctx); + if (rem != NULL) + r = rem; + else + r = BN_CTX_get(ctx); + if (a == NULL || b == NULL || d == NULL || r == NULL) + goto err; + + if (BN_ucmp(m, &(recp->N)) < 0) { + BN_zero(d); + if (!BN_copy(r, m)) { + BN_CTX_end(ctx); + return 0; + } + BN_CTX_end(ctx); + return (1); + } + + /* + * We want the remainder Given input of ABCDEF / ab we need multiply + * ABCDEF by 3 digests of the reciprocal of ab + */ + + /* i := max(BN_num_bits(m), 2*BN_num_bits(N)) */ + i = BN_num_bits(m); + j = recp->num_bits << 1; + if (j > i) + i = j; + + /* Nr := round(2^i / N) */ + if (i != recp->shift) + recp->shift = BN_reciprocal(&(recp->Nr), &(recp->N), i, ctx); + /* BN_reciprocal could have returned -1 for an error */ + if (recp->shift == -1) + goto err; + + /*- + * d := |round(round(m / 2^BN_num_bits(N)) * recp->Nr / 2^(i - BN_num_bits(N)))| + * = |round(round(m / 2^BN_num_bits(N)) * round(2^i / N) / 2^(i - BN_num_bits(N)))| + * <= |(m / 2^BN_num_bits(N)) * (2^i / N) * (2^BN_num_bits(N) / 2^i)| + * = |m/N| + */ + if (!BN_rshift(a, m, recp->num_bits)) + goto err; + if (!BN_mul(b, a, &(recp->Nr), ctx)) + goto err; + if (!BN_rshift(d, b, i - recp->num_bits)) + goto err; + d->neg = 0; + + if (!BN_mul(b, &(recp->N), d, ctx)) + goto err; + if (!BN_usub(r, m, b)) + goto err; + r->neg = 0; + +#if 1 + j = 0; + while (BN_ucmp(r, &(recp->N)) >= 0) { + if (j++ > 2) { + BNerr(BN_F_BN_DIV_RECP, BN_R_BAD_RECIPROCAL); + goto err; + } + if (!BN_usub(r, r, &(recp->N))) + goto err; + if (!BN_add_word(d, 1)) + goto err; + } +#endif + + r->neg = BN_is_zero(r) ? 0 : m->neg; + d->neg = m->neg ^ recp->N.neg; + ret = 1; + err: + BN_CTX_end(ctx); + bn_check_top(dv); + bn_check_top(rem); + return (ret); +} + +/* + * len is the expected size of the result We actually calculate with an extra + * word of precision, so we can do faster division if the remainder is not + * required. + */ +/* r := 2^len / m */ +int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx) +{ + int ret = -1; + BIGNUM *t; + + BN_CTX_start(ctx); + if ((t = BN_CTX_get(ctx)) == NULL) + goto err; + + if (!BN_set_bit(t, len)) + goto err; + + if (!BN_div(r, NULL, t, m, ctx)) + goto err; + + ret = len; + err: + bn_check_top(r); + BN_CTX_end(ctx); + return (ret); +} diff --git a/libs/openssl/crypto/bn/bn_shift.c b/libs/openssl/crypto/bn/bn_shift.c new file mode 100644 index 00000000..9673d9a3 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_shift.c @@ -0,0 +1,224 @@ +/* crypto/bn/bn_shift.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +int BN_lshift1(BIGNUM *r, const BIGNUM *a) +{ + register BN_ULONG *ap, *rp, t, c; + int i; + + bn_check_top(r); + bn_check_top(a); + + if (r != a) { + r->neg = a->neg; + if (bn_wexpand(r, a->top + 1) == NULL) + return (0); + r->top = a->top; + } else { + if (bn_wexpand(r, a->top + 1) == NULL) + return (0); + } + ap = a->d; + rp = r->d; + c = 0; + for (i = 0; i < a->top; i++) { + t = *(ap++); + *(rp++) = ((t << 1) | c) & BN_MASK2; + c = (t & BN_TBIT) ? 1 : 0; + } + if (c) { + *rp = 1; + r->top++; + } + bn_check_top(r); + return (1); +} + +int BN_rshift1(BIGNUM *r, const BIGNUM *a) +{ + BN_ULONG *ap, *rp, t, c; + int i, j; + + bn_check_top(r); + bn_check_top(a); + + if (BN_is_zero(a)) { + BN_zero(r); + return (1); + } + i = a->top; + ap = a->d; + j = i - (ap[i - 1] == 1); + if (a != r) { + if (bn_wexpand(r, j) == NULL) + return (0); + r->neg = a->neg; + } + rp = r->d; + t = ap[--i]; + c = (t & 1) ? BN_TBIT : 0; + if (t >>= 1) + rp[i] = t; + while (i > 0) { + t = ap[--i]; + rp[i] = ((t >> 1) & BN_MASK2) | c; + c = (t & 1) ? BN_TBIT : 0; + } + r->top = j; + bn_check_top(r); + return (1); +} + +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) +{ + int i, nw, lb, rb; + BN_ULONG *t, *f; + BN_ULONG l; + + bn_check_top(r); + bn_check_top(a); + + if (n < 0) { + BNerr(BN_F_BN_LSHIFT, BN_R_INVALID_SHIFT); + return 0; + } + + r->neg = a->neg; + nw = n / BN_BITS2; + if (bn_wexpand(r, a->top + nw + 1) == NULL) + return (0); + lb = n % BN_BITS2; + rb = BN_BITS2 - lb; + f = a->d; + t = r->d; + t[a->top + nw] = 0; + if (lb == 0) + for (i = a->top - 1; i >= 0; i--) + t[nw + i] = f[i]; + else + for (i = a->top - 1; i >= 0; i--) { + l = f[i]; + t[nw + i + 1] |= (l >> rb) & BN_MASK2; + t[nw + i] = (l << lb) & BN_MASK2; + } + memset(t, 0, nw * sizeof(t[0])); + /* + * for (i=0; itop = a->top + nw + 1; + bn_correct_top(r); + bn_check_top(r); + return (1); +} + +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) +{ + int i, j, nw, lb, rb; + BN_ULONG *t, *f; + BN_ULONG l, tmp; + + bn_check_top(r); + bn_check_top(a); + + if (n < 0) { + BNerr(BN_F_BN_RSHIFT, BN_R_INVALID_SHIFT); + return 0; + } + + nw = n / BN_BITS2; + rb = n % BN_BITS2; + lb = BN_BITS2 - rb; + if (nw >= a->top || a->top == 0) { + BN_zero(r); + return (1); + } + i = (BN_num_bits(a) - n + (BN_BITS2 - 1)) / BN_BITS2; + if (r != a) { + r->neg = a->neg; + if (bn_wexpand(r, i) == NULL) + return (0); + } else { + if (n == 0) + return 1; /* or the copying loop will go berserk */ + } + + f = &(a->d[nw]); + t = r->d; + j = a->top - nw; + r->top = i; + + if (rb == 0) { + for (i = j; i != 0; i--) + *(t++) = *(f++); + } else { + l = *(f++); + for (i = j - 1; i != 0; i--) { + tmp = (l >> rb) & BN_MASK2; + l = *(f++); + *(t++) = (tmp | (l << lb)) & BN_MASK2; + } + if ((l = (l >> rb) & BN_MASK2)) + *(t) = l; + } + bn_check_top(r); + return (1); +} diff --git a/libs/openssl/crypto/bn/bn_sqr.c b/libs/openssl/crypto/bn/bn_sqr.c new file mode 100644 index 00000000..3ca69879 --- /dev/null +++ b/libs/openssl/crypto/bn/bn_sqr.c @@ -0,0 +1,290 @@ +/* crypto/bn/bn_sqr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +/* r must not be a */ +/* + * I've just gone over this and it is now %20 faster on x86 - eay - 27 Jun 96 + */ +int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) +{ + int max, al; + int ret = 0; + BIGNUM *tmp, *rr; + +#ifdef BN_COUNT + fprintf(stderr, "BN_sqr %d * %d\n", a->top, a->top); +#endif + bn_check_top(a); + + al = a->top; + if (al <= 0) { + r->top = 0; + r->neg = 0; + return 1; + } + + BN_CTX_start(ctx); + rr = (a != r) ? r : BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + if (!rr || !tmp) + goto err; + + max = 2 * al; /* Non-zero (from above) */ + if (bn_wexpand(rr, max) == NULL) + goto err; + + if (al == 4) { +#ifndef BN_SQR_COMBA + BN_ULONG t[8]; + bn_sqr_normal(rr->d, a->d, 4, t); +#else + bn_sqr_comba4(rr->d, a->d); +#endif + } else if (al == 8) { +#ifndef BN_SQR_COMBA + BN_ULONG t[16]; + bn_sqr_normal(rr->d, a->d, 8, t); +#else + bn_sqr_comba8(rr->d, a->d); +#endif + } else { +#if defined(BN_RECURSION) + if (al < BN_SQR_RECURSIVE_SIZE_NORMAL) { + BN_ULONG t[BN_SQR_RECURSIVE_SIZE_NORMAL * 2]; + bn_sqr_normal(rr->d, a->d, al, t); + } else { + int j, k; + + j = BN_num_bits_word((BN_ULONG)al); + j = 1 << (j - 1); + k = j + j; + if (al == j) { + if (bn_wexpand(tmp, k * 2) == NULL) + goto err; + bn_sqr_recursive(rr->d, a->d, al, tmp->d); + } else { + if (bn_wexpand(tmp, max) == NULL) + goto err; + bn_sqr_normal(rr->d, a->d, al, tmp->d); + } + } +#else + if (bn_wexpand(tmp, max) == NULL) + goto err; + bn_sqr_normal(rr->d, a->d, al, tmp->d); +#endif + } + + rr->neg = 0; + /* + * If the most-significant half of the top word of 'a' is zero, then the + * square of 'a' will max-1 words. + */ + if (a->d[al - 1] == (a->d[al - 1] & BN_MASK2l)) + rr->top = max - 1; + else + rr->top = max; + if (rr != r) + BN_copy(r, rr); + ret = 1; + err: + bn_check_top(rr); + bn_check_top(tmp); + BN_CTX_end(ctx); + return (ret); +} + +/* tmp must have 2*n words */ +void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, int n, BN_ULONG *tmp) +{ + int i, j, max; + const BN_ULONG *ap; + BN_ULONG *rp; + + max = n * 2; + ap = a; + rp = r; + rp[0] = rp[max - 1] = 0; + rp++; + j = n; + + if (--j > 0) { + ap++; + rp[j] = bn_mul_words(rp, ap, j, ap[-1]); + rp += 2; + } + + for (i = n - 2; i > 0; i--) { + j--; + ap++; + rp[j] = bn_mul_add_words(rp, ap, j, ap[-1]); + rp += 2; + } + + bn_add_words(r, r, r, max); + + /* There will not be a carry */ + + bn_sqr_words(tmp, a, n); + + bn_add_words(r, r, tmp, max); +} + +#ifdef BN_RECURSION +/*- + * r is 2*n words in size, + * a and b are both n words in size. (There's not actually a 'b' here ...) + * n must be a power of 2. + * We multiply and return the result. + * t must be 2*n words in size + * We calculate + * a[0]*b[0] + * a[0]*b[0]+a[1]*b[1]+(a[0]-a[1])*(b[1]-b[0]) + * a[1]*b[1] + */ +void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, int n2, BN_ULONG *t) +{ + int n = n2 / 2; + int zero, c1; + BN_ULONG ln, lo, *p; + +# ifdef BN_COUNT + fprintf(stderr, " bn_sqr_recursive %d * %d\n", n2, n2); +# endif + if (n2 == 4) { +# ifndef BN_SQR_COMBA + bn_sqr_normal(r, a, 4, t); +# else + bn_sqr_comba4(r, a); +# endif + return; + } else if (n2 == 8) { +# ifndef BN_SQR_COMBA + bn_sqr_normal(r, a, 8, t); +# else + bn_sqr_comba8(r, a); +# endif + return; + } + if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL) { + bn_sqr_normal(r, a, n2, t); + return; + } + /* r=(a[0]-a[1])*(a[1]-a[0]) */ + c1 = bn_cmp_words(a, &(a[n]), n); + zero = 0; + if (c1 > 0) + bn_sub_words(t, a, &(a[n]), n); + else if (c1 < 0) + bn_sub_words(t, &(a[n]), a, n); + else + zero = 1; + + /* The result will always be negative unless it is zero */ + p = &(t[n2 * 2]); + + if (!zero) + bn_sqr_recursive(&(t[n2]), t, n, p); + else + memset(&(t[n2]), 0, n2 * sizeof(BN_ULONG)); + bn_sqr_recursive(r, a, n, p); + bn_sqr_recursive(&(r[n2]), &(a[n]), n, p); + + /*- + * t[32] holds (a[0]-a[1])*(a[1]-a[0]), it is negative or zero + * r[10] holds (a[0]*b[0]) + * r[32] holds (b[1]*b[1]) + */ + + c1 = (int)(bn_add_words(t, r, &(r[n2]), n2)); + + /* t[32] is negative */ + c1 -= (int)(bn_sub_words(&(t[n2]), t, &(t[n2]), n2)); + + /*- + * t[32] holds (a[0]-a[1])*(a[1]-a[0])+(a[0]*a[0])+(a[1]*a[1]) + * r[10] holds (a[0]*a[0]) + * r[32] holds (a[1]*a[1]) + * c1 holds the carry bits + */ + c1 += (int)(bn_add_words(&(r[n]), &(r[n]), &(t[n2]), n2)); + if (c1) { + p = &(r[n + n2]); + lo = *p; + ln = (lo + c1) & BN_MASK2; + *p = ln; + + /* + * The overflow will stop before we over write words we should not + * overwrite + */ + if (ln < (BN_ULONG)c1) { + do { + p++; + lo = *p; + ln = (lo + 1) & BN_MASK2; + *p = ln; + } while (ln == 0); + } + } +} +#endif diff --git a/libs/openssl/crypto/bn/bn_sqrt.c b/libs/openssl/crypto/bn/bn_sqrt.c new file mode 100644 index 00000000..232af99a --- /dev/null +++ b/libs/openssl/crypto/bn/bn_sqrt.c @@ -0,0 +1,409 @@ +/* crypto/bn/bn_sqrt.c */ +/* + * Written by Lenka Fibikova and Bodo + * Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include "bn_lcl.h" + +BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) +/* + * Returns 'ret' such that ret^2 == a (mod p), using the Tonelli/Shanks + * algorithm (cf. Henri Cohen, "A Course in Algebraic Computational Number + * Theory", algorithm 1.5.1). 'p' must be prime! + */ +{ + BIGNUM *ret = in; + int err = 1; + int r; + BIGNUM *A, *b, *q, *t, *x, *y; + int e, i, j; + + if (!BN_is_odd(p) || BN_abs_is_word(p, 1)) { + if (BN_abs_is_word(p, 2)) { + if (ret == NULL) + ret = BN_new(); + if (ret == NULL) + goto end; + if (!BN_set_word(ret, BN_is_bit_set(a, 0))) { + if (ret != in) + BN_free(ret); + return NULL; + } + bn_check_top(ret); + return ret; + } + + BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); + return (NULL); + } + + if (BN_is_zero(a) || BN_is_one(a)) { + if (ret == NULL) + ret = BN_new(); + if (ret == NULL) + goto end; + if (!BN_set_word(ret, BN_is_one(a))) { + if (ret != in) + BN_free(ret); + return NULL; + } + bn_check_top(ret); + return ret; + } + + BN_CTX_start(ctx); + A = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + t = BN_CTX_get(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto end; + + if (ret == NULL) + ret = BN_new(); + if (ret == NULL) + goto end; + + /* A = a mod p */ + if (!BN_nnmod(A, a, p, ctx)) + goto end; + + /* now write |p| - 1 as 2^e*q where q is odd */ + e = 1; + while (!BN_is_bit_set(p, e)) + e++; + /* we'll set q later (if needed) */ + + if (e == 1) { + /*- + * The easy case: (|p|-1)/2 is odd, so 2 has an inverse + * modulo (|p|-1)/2, and square roots can be computed + * directly by modular exponentiation. + * We have + * 2 * (|p|+1)/4 == 1 (mod (|p|-1)/2), + * so we can use exponent (|p|+1)/4, i.e. (|p|-3)/4 + 1. + */ + if (!BN_rshift(q, p, 2)) + goto end; + q->neg = 0; + if (!BN_add_word(q, 1)) + goto end; + if (!BN_mod_exp(ret, A, q, p, ctx)) + goto end; + err = 0; + goto vrfy; + } + + if (e == 2) { + /*- + * |p| == 5 (mod 8) + * + * In this case 2 is always a non-square since + * Legendre(2,p) = (-1)^((p^2-1)/8) for any odd prime. + * So if a really is a square, then 2*a is a non-square. + * Thus for + * b := (2*a)^((|p|-5)/8), + * i := (2*a)*b^2 + * we have + * i^2 = (2*a)^((1 + (|p|-5)/4)*2) + * = (2*a)^((p-1)/2) + * = -1; + * so if we set + * x := a*b*(i-1), + * then + * x^2 = a^2 * b^2 * (i^2 - 2*i + 1) + * = a^2 * b^2 * (-2*i) + * = a*(-i)*(2*a*b^2) + * = a*(-i)*i + * = a. + * + * (This is due to A.O.L. Atkin, + * , + * November 1992.) + */ + + /* t := 2*a */ + if (!BN_mod_lshift1_quick(t, A, p)) + goto end; + + /* b := (2*a)^((|p|-5)/8) */ + if (!BN_rshift(q, p, 3)) + goto end; + q->neg = 0; + if (!BN_mod_exp(b, t, q, p, ctx)) + goto end; + + /* y := b^2 */ + if (!BN_mod_sqr(y, b, p, ctx)) + goto end; + + /* t := (2*a)*b^2 - 1 */ + if (!BN_mod_mul(t, t, y, p, ctx)) + goto end; + if (!BN_sub_word(t, 1)) + goto end; + + /* x = a*b*t */ + if (!BN_mod_mul(x, A, b, p, ctx)) + goto end; + if (!BN_mod_mul(x, x, t, p, ctx)) + goto end; + + if (!BN_copy(ret, x)) + goto end; + err = 0; + goto vrfy; + } + + /* + * e > 2, so we really have to use the Tonelli/Shanks algorithm. First, + * find some y that is not a square. + */ + if (!BN_copy(q, p)) + goto end; /* use 'q' as temp */ + q->neg = 0; + i = 2; + do { + /* + * For efficiency, try small numbers first; if this fails, try random + * numbers. + */ + if (i < 22) { + if (!BN_set_word(y, i)) + goto end; + } else { + if (!BN_pseudo_rand(y, BN_num_bits(p), 0, 0)) + goto end; + if (BN_ucmp(y, p) >= 0) { + if (!(p->neg ? BN_add : BN_sub) (y, y, p)) + goto end; + } + /* now 0 <= y < |p| */ + if (BN_is_zero(y)) + if (!BN_set_word(y, i)) + goto end; + } + + r = BN_kronecker(y, q, ctx); /* here 'q' is |p| */ + if (r < -1) + goto end; + if (r == 0) { + /* m divides p */ + BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); + goto end; + } + } + while (r == 1 && ++i < 82); + + if (r != -1) { + /* + * Many rounds and still no non-square -- this is more likely a bug + * than just bad luck. Even if p is not prime, we should have found + * some y such that r == -1. + */ + BNerr(BN_F_BN_MOD_SQRT, BN_R_TOO_MANY_ITERATIONS); + goto end; + } + + /* Here's our actual 'q': */ + if (!BN_rshift(q, q, e)) + goto end; + + /* + * Now that we have some non-square, we can find an element of order 2^e + * by computing its q'th power. + */ + if (!BN_mod_exp(y, y, q, p, ctx)) + goto end; + if (BN_is_one(y)) { + BNerr(BN_F_BN_MOD_SQRT, BN_R_P_IS_NOT_PRIME); + goto end; + } + + /*- + * Now we know that (if p is indeed prime) there is an integer + * k, 0 <= k < 2^e, such that + * + * a^q * y^k == 1 (mod p). + * + * As a^q is a square and y is not, k must be even. + * q+1 is even, too, so there is an element + * + * X := a^((q+1)/2) * y^(k/2), + * + * and it satisfies + * + * X^2 = a^q * a * y^k + * = a, + * + * so it is the square root that we are looking for. + */ + + /* t := (q-1)/2 (note that q is odd) */ + if (!BN_rshift1(t, q)) + goto end; + + /* x := a^((q-1)/2) */ + if (BN_is_zero(t)) { /* special case: p = 2^e + 1 */ + if (!BN_nnmod(t, A, p, ctx)) + goto end; + if (BN_is_zero(t)) { + /* special case: a == 0 (mod p) */ + BN_zero(ret); + err = 0; + goto end; + } else if (!BN_one(x)) + goto end; + } else { + if (!BN_mod_exp(x, A, t, p, ctx)) + goto end; + if (BN_is_zero(x)) { + /* special case: a == 0 (mod p) */ + BN_zero(ret); + err = 0; + goto end; + } + } + + /* b := a*x^2 (= a^q) */ + if (!BN_mod_sqr(b, x, p, ctx)) + goto end; + if (!BN_mod_mul(b, b, A, p, ctx)) + goto end; + + /* x := a*x (= a^((q+1)/2)) */ + if (!BN_mod_mul(x, x, A, p, ctx)) + goto end; + + while (1) { + /*- + * Now b is a^q * y^k for some even k (0 <= k < 2^E + * where E refers to the original value of e, which we + * don't keep in a variable), and x is a^((q+1)/2) * y^(k/2). + * + * We have a*b = x^2, + * y^2^(e-1) = -1, + * b^2^(e-1) = 1. + */ + + if (BN_is_one(b)) { + if (!BN_copy(ret, x)) + goto end; + err = 0; + goto vrfy; + } + + /* find smallest i such that b^(2^i) = 1 */ + i = 1; + if (!BN_mod_sqr(t, b, p, ctx)) + goto end; + while (!BN_is_one(t)) { + i++; + if (i == e) { + BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); + goto end; + } + if (!BN_mod_mul(t, t, t, p, ctx)) + goto end; + } + + /* t := y^2^(e - i - 1) */ + if (!BN_copy(t, y)) + goto end; + for (j = e - i - 1; j > 0; j--) { + if (!BN_mod_sqr(t, t, p, ctx)) + goto end; + } + if (!BN_mod_mul(y, t, t, p, ctx)) + goto end; + if (!BN_mod_mul(x, x, t, p, ctx)) + goto end; + if (!BN_mod_mul(b, b, y, p, ctx)) + goto end; + e = i; + } + + vrfy: + if (!err) { + /* + * verify the result -- the input might have been not a square (test + * added in 0.9.8) + */ + + if (!BN_mod_sqr(x, ret, p, ctx)) + err = 1; + + if (!err && 0 != BN_cmp(x, A)) { + BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE); + err = 1; + } + } + + end: + if (err) { + if (ret != NULL && ret != in) { + BN_clear_free(ret); + } + ret = NULL; + } + BN_CTX_end(ctx); + bn_check_top(ret); + return ret; +} diff --git a/libs/openssl/crypto/bn/bn_word.c b/libs/openssl/crypto/bn/bn_word.c new file mode 100644 index 00000000..b031a60b --- /dev/null +++ b/libs/openssl/crypto/bn/bn_word.c @@ -0,0 +1,227 @@ +/* crypto/bn/bn_word.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) +{ +#ifndef BN_LLONG + BN_ULONG ret = 0; +#else + BN_ULLONG ret = 0; +#endif + int i; + + if (w == 0) + return (BN_ULONG)-1; + + bn_check_top(a); + w &= BN_MASK2; + for (i = a->top - 1; i >= 0; i--) { +#ifndef BN_LLONG + ret = ((ret << BN_BITS4) | ((a->d[i] >> BN_BITS4) & BN_MASK2l)) % w; + ret = ((ret << BN_BITS4) | (a->d[i] & BN_MASK2l)) % w; +#else + ret = (BN_ULLONG) (((ret << (BN_ULLONG) BN_BITS2) | a->d[i]) % + (BN_ULLONG) w); +#endif + } + return ((BN_ULONG)ret); +} + +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) +{ + BN_ULONG ret = 0; + int i, j; + + bn_check_top(a); + w &= BN_MASK2; + + if (!w) + /* actually this an error (division by zero) */ + return (BN_ULONG)-1; + if (a->top == 0) + return 0; + + /* normalize input (so bn_div_words doesn't complain) */ + j = BN_BITS2 - BN_num_bits_word(w); + w <<= j; + if (!BN_lshift(a, a, j)) + return (BN_ULONG)-1; + + for (i = a->top - 1; i >= 0; i--) { + BN_ULONG l, d; + + l = a->d[i]; + d = bn_div_words(ret, l, w); + ret = (l - ((d * w) & BN_MASK2)) & BN_MASK2; + a->d[i] = d; + } + if ((a->top > 0) && (a->d[a->top - 1] == 0)) + a->top--; + ret >>= j; + bn_check_top(a); + return (ret); +} + +int BN_add_word(BIGNUM *a, BN_ULONG w) +{ + BN_ULONG l; + int i; + + bn_check_top(a); + w &= BN_MASK2; + + /* degenerate case: w is zero */ + if (!w) + return 1; + /* degenerate case: a is zero */ + if (BN_is_zero(a)) + return BN_set_word(a, w); + /* handle 'a' when negative */ + if (a->neg) { + a->neg = 0; + i = BN_sub_word(a, w); + if (!BN_is_zero(a)) + a->neg = !(a->neg); + return (i); + } + for (i = 0; w != 0 && i < a->top; i++) { + a->d[i] = l = (a->d[i] + w) & BN_MASK2; + w = (w > l) ? 1 : 0; + } + if (w && i == a->top) { + if (bn_wexpand(a, a->top + 1) == NULL) + return 0; + a->top++; + a->d[i] = w; + } + bn_check_top(a); + return (1); +} + +int BN_sub_word(BIGNUM *a, BN_ULONG w) +{ + int i; + + bn_check_top(a); + w &= BN_MASK2; + + /* degenerate case: w is zero */ + if (!w) + return 1; + /* degenerate case: a is zero */ + if (BN_is_zero(a)) { + i = BN_set_word(a, w); + if (i != 0) + BN_set_negative(a, 1); + return i; + } + /* handle 'a' when negative */ + if (a->neg) { + a->neg = 0; + i = BN_add_word(a, w); + a->neg = 1; + return (i); + } + + if ((a->top == 1) && (a->d[0] < w)) { + a->d[0] = w - a->d[0]; + a->neg = 1; + return (1); + } + i = 0; + for (;;) { + if (a->d[i] >= w) { + a->d[i] -= w; + break; + } else { + a->d[i] = (a->d[i] - w) & BN_MASK2; + i++; + w = 1; + } + } + if ((a->d[i] == 0) && (i == (a->top - 1))) + a->top--; + bn_check_top(a); + return (1); +} + +int BN_mul_word(BIGNUM *a, BN_ULONG w) +{ + BN_ULONG ll; + + bn_check_top(a); + w &= BN_MASK2; + if (a->top) { + if (w == 0) + BN_zero(a); + else { + ll = bn_mul_words(a->d, a->d, a->top, w); + if (ll) { + if (bn_wexpand(a, a->top + 1) == NULL) + return (0); + a->d[a->top++] = ll; + } + } + } + bn_check_top(a); + return (1); +} diff --git a/libs/openssl/crypto/bn/bn_x931p.c b/libs/openssl/crypto/bn/bn_x931p.c new file mode 100644 index 00000000..efa48bdf --- /dev/null +++ b/libs/openssl/crypto/bn/bn_x931p.c @@ -0,0 +1,277 @@ +/* bn_x931p.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +/* X9.31 routines for prime derivation */ + +/* + * X9.31 prime derivation. This is used to generate the primes pi (p1, p2, + * q1, q2) from a parameter Xpi by checking successive odd integers. + */ + +static int bn_x931_derive_pi(BIGNUM *pi, const BIGNUM *Xpi, BN_CTX *ctx, + BN_GENCB *cb) +{ + int i = 0; + if (!BN_copy(pi, Xpi)) + return 0; + if (!BN_is_odd(pi) && !BN_add_word(pi, 1)) + return 0; + for (;;) { + i++; + BN_GENCB_call(cb, 0, i); + /* NB 27 MR is specificed in X9.31 */ + if (BN_is_prime_fasttest_ex(pi, 27, ctx, 1, cb)) + break; + if (!BN_add_word(pi, 2)) + return 0; + } + BN_GENCB_call(cb, 2, i); + return 1; +} + +/* + * This is the main X9.31 prime derivation function. From parameters Xp1, Xp2 + * and Xp derive the prime p. If the parameters p1 or p2 are not NULL they + * will be returned too: this is needed for testing. + */ + +int BN_X931_derive_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + const BIGNUM *Xp, const BIGNUM *Xp1, + const BIGNUM *Xp2, const BIGNUM *e, BN_CTX *ctx, + BN_GENCB *cb) +{ + int ret = 0; + + BIGNUM *t, *p1p2, *pm1; + + /* Only even e supported */ + if (!BN_is_odd(e)) + return 0; + + BN_CTX_start(ctx); + if (!p1) + p1 = BN_CTX_get(ctx); + + if (!p2) + p2 = BN_CTX_get(ctx); + + t = BN_CTX_get(ctx); + + p1p2 = BN_CTX_get(ctx); + + pm1 = BN_CTX_get(ctx); + + if (!bn_x931_derive_pi(p1, Xp1, ctx, cb)) + goto err; + + if (!bn_x931_derive_pi(p2, Xp2, ctx, cb)) + goto err; + + if (!BN_mul(p1p2, p1, p2, ctx)) + goto err; + + /* First set p to value of Rp */ + + if (!BN_mod_inverse(p, p2, p1, ctx)) + goto err; + + if (!BN_mul(p, p, p2, ctx)) + goto err; + + if (!BN_mod_inverse(t, p1, p2, ctx)) + goto err; + + if (!BN_mul(t, t, p1, ctx)) + goto err; + + if (!BN_sub(p, p, t)) + goto err; + + if (p->neg && !BN_add(p, p, p1p2)) + goto err; + + /* p now equals Rp */ + + if (!BN_mod_sub(p, p, Xp, p1p2, ctx)) + goto err; + + if (!BN_add(p, p, Xp)) + goto err; + + /* p now equals Yp0 */ + + for (;;) { + int i = 1; + BN_GENCB_call(cb, 0, i++); + if (!BN_copy(pm1, p)) + goto err; + if (!BN_sub_word(pm1, 1)) + goto err; + if (!BN_gcd(t, pm1, e, ctx)) + goto err; + if (BN_is_one(t) + /* + * X9.31 specifies 8 MR and 1 Lucas test or any prime test + * offering similar or better guarantees 50 MR is considerably + * better. + */ + && BN_is_prime_fasttest_ex(p, 50, ctx, 1, cb)) + break; + if (!BN_add(p, p, p1p2)) + goto err; + } + + BN_GENCB_call(cb, 3, 0); + + ret = 1; + + err: + + BN_CTX_end(ctx); + + return ret; +} + +/* + * Generate pair of paramters Xp, Xq for X9.31 prime generation. Note: nbits + * paramter is sum of number of bits in both. + */ + +int BN_X931_generate_Xpq(BIGNUM *Xp, BIGNUM *Xq, int nbits, BN_CTX *ctx) +{ + BIGNUM *t; + int i; + /* + * Number of bits for each prime is of the form 512+128s for s = 0, 1, + * ... + */ + if ((nbits < 1024) || (nbits & 0xff)) + return 0; + nbits >>= 1; + /* + * The random value Xp must be between sqrt(2) * 2^(nbits-1) and 2^nbits + * - 1. By setting the top two bits we ensure that the lower bound is + * exceeded. + */ + if (!BN_rand(Xp, nbits, 1, 0)) + goto err; + + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + + for (i = 0; i < 1000; i++) { + if (!BN_rand(Xq, nbits, 1, 0)) + goto err; + /* Check that |Xp - Xq| > 2^(nbits - 100) */ + BN_sub(t, Xp, Xq); + if (BN_num_bits(t) > (nbits - 100)) + break; + } + + BN_CTX_end(ctx); + + if (i < 1000) + return 1; + + return 0; + + err: + BN_CTX_end(ctx); + return 0; +} + +/* + * Generate primes using X9.31 algorithm. Of the values p, p1, p2, Xp1 and + * Xp2 only 'p' needs to be non-NULL. If any of the others are not NULL the + * relevant parameter will be stored in it. Due to the fact that |Xp - Xq| > + * 2^(nbits - 100) must be satisfied Xp and Xq are generated using the + * previous function and supplied as input. + */ + +int BN_X931_generate_prime_ex(BIGNUM *p, BIGNUM *p1, BIGNUM *p2, + BIGNUM *Xp1, BIGNUM *Xp2, + const BIGNUM *Xp, + const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb) +{ + int ret = 0; + + BN_CTX_start(ctx); + if (!Xp1) + Xp1 = BN_CTX_get(ctx); + if (!Xp2) + Xp2 = BN_CTX_get(ctx); + + if (!BN_rand(Xp1, 101, 0, 0)) + goto error; + if (!BN_rand(Xp2, 101, 0, 0)) + goto error; + if (!BN_X931_derive_prime_ex(p, p1, p2, Xp, Xp1, Xp2, e, ctx, cb)) + goto error; + + ret = 1; + + error: + BN_CTX_end(ctx); + + return ret; + +} diff --git a/libs/openssl/crypto/bn/bnspeed.c b/libs/openssl/crypto/bn/bnspeed.c new file mode 100644 index 00000000..e387fdfb --- /dev/null +++ b/libs/openssl/crypto/bn/bnspeed.c @@ -0,0 +1,232 @@ +/* unused */ + +/* crypto/bn/bnspeed.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* most of this code has been pilfered from my libdes speed.c program */ + +#define BASENUM 1000000 +#undef PROG +#define PROG bnspeed_main + +#include +#include +#include +#include +#include +#include + +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX) +# define TIMES +#endif + +#ifndef _IRIX +# include +#endif +#ifdef TIMES +# include +# include +#endif + +/* + * Depending on the VMS version, the tms structure is perhaps defined. The + * __TMS macro will show if it was. If it wasn't defined, we should undefine + * TIMES, since that tells the rest of the program how things should be + * handled. -- Richard Levitte + */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) +# undef TIMES +#endif + +#ifndef TIMES +# include +#endif + +#if defined(sun) || defined(__ultrix) +# define _POSIX_SOURCE +# include +# include +#endif + +#include +#include + +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# ifndef _BSD_CLK_TCK_ /* FreeBSD hack */ +# define HZ 100.0 +# else /* _BSD_CLK_TCK_ */ +# define HZ ((double)_BSD_CLK_TCK_) +# endif +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +#endif + +#undef BUFSIZE +#define BUFSIZE ((long)1024*8) +int run = 0; + +static double Time_F(int s); +#define START 0 +#define STOP 1 + +static double Time_F(int s) +{ + double ret; +#ifdef TIMES + static struct tms tstart, tend; + + if (s == START) { + times(&tstart); + return (0); + } else { + times(&tend); + ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ; + return ((ret < 1e-3) ? 1e-3 : ret); + } +#else /* !times() */ + static struct timeb tstart, tend; + long i; + + if (s == START) { + ftime(&tstart); + return (0); + } else { + ftime(&tend); + i = (long)tend.millitm - (long)tstart.millitm; + ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1000.0; + return ((ret < 0.001) ? 0.001 : ret); + } +#endif +} + +#define NUM_SIZES 5 +static int sizes[NUM_SIZES] = { 128, 256, 512, 1024, 2048 }; + +/* + * static int sizes[NUM_SIZES]={59,179,299,419,539}; + */ + +void do_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx); + +int main(int argc, char **argv) +{ + BN_CTX *ctx; + BIGNUM a, b, c; + + ctx = BN_CTX_new(); + BN_init(&a); + BN_init(&b); + BN_init(&c); + + do_mul(&a, &b, &c, ctx); +} + +void do_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BN_CTX *ctx) +{ + int i, j, k; + double tm; + long num; + + for (i = 0; i < NUM_SIZES; i++) { + num = BASENUM; + if (i) + num /= (i * 3); + BN_rand(a, sizes[i], 1, 0); + for (j = i; j < NUM_SIZES; j++) { + BN_rand(b, sizes[j], 1, 0); + Time_F(START); + for (k = 0; k < num; k++) + BN_mul(r, b, a, ctx); + tm = Time_F(STOP); + printf("mul %4d x %4d -> %8.3fms\n", sizes[i], sizes[j], + tm * 1000.0 / num); + } + } + + for (i = 0; i < NUM_SIZES; i++) { + num = BASENUM; + if (i) + num /= (i * 3); + BN_rand(a, sizes[i], 1, 0); + Time_F(START); + for (k = 0; k < num; k++) + BN_sqr(r, a, ctx); + tm = Time_F(STOP); + printf("sqr %4d x %4d -> %8.3fms\n", sizes[i], sizes[i], + tm * 1000.0 / num); + } + + for (i = 0; i < NUM_SIZES; i++) { + num = BASENUM / 10; + if (i) + num /= (i * 3); + BN_rand(a, sizes[i] - 1, 1, 0); + for (j = i; j < NUM_SIZES; j++) { + BN_rand(b, sizes[j], 1, 0); + Time_F(START); + for (k = 0; k < 100000; k++) + BN_div(r, NULL, b, a, ctx); + tm = Time_F(STOP); + printf("div %4d / %4d -> %8.3fms\n", sizes[j], sizes[i] - 1, + tm * 1000.0 / num); + } + } +} diff --git a/libs/openssl/crypto/bn/bntest.c b/libs/openssl/crypto/bn/bntest.c new file mode 100644 index 00000000..6d55049e --- /dev/null +++ b/libs/openssl/crypto/bn/bntest.c @@ -0,0 +1,2137 @@ +/* crypto/bn/bntest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the Eric Young open source + * license provided above. + * + * The binary polynomial arithmetic software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +/* + * Until the key-gen callbacks are modified to use newer prototypes, we allow + * deprecated functions for openssl-internal code + */ +#ifdef OPENSSL_NO_DEPRECATED +# undef OPENSSL_NO_DEPRECATED +#endif + +#include +#include +#include + +#include "e_os.h" + +#include +#include +#include +#include +#include + +const int num0 = 100; /* number of tests */ +const int num1 = 50; /* additional tests for some functions */ +const int num2 = 5; /* number of tests for slow functions */ + +int test_add(BIO *bp); +int test_sub(BIO *bp); +int test_lshift1(BIO *bp); +int test_lshift(BIO *bp, BN_CTX *ctx, BIGNUM *a_); +int test_rshift1(BIO *bp); +int test_rshift(BIO *bp, BN_CTX *ctx); +int test_div(BIO *bp, BN_CTX *ctx); +int test_div_word(BIO *bp); +int test_div_recp(BIO *bp, BN_CTX *ctx); +int test_mul(BIO *bp); +int test_sqr(BIO *bp, BN_CTX *ctx); +int test_mont(BIO *bp, BN_CTX *ctx); +int test_mod(BIO *bp, BN_CTX *ctx); +int test_mod_mul(BIO *bp, BN_CTX *ctx); +int test_mod_exp(BIO *bp, BN_CTX *ctx); +int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx); +int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx); +int test_exp(BIO *bp, BN_CTX *ctx); +int test_gf2m_add(BIO *bp); +int test_gf2m_mod(BIO *bp); +int test_gf2m_mod_mul(BIO *bp, BN_CTX *ctx); +int test_gf2m_mod_sqr(BIO *bp, BN_CTX *ctx); +int test_gf2m_mod_inv(BIO *bp, BN_CTX *ctx); +int test_gf2m_mod_div(BIO *bp, BN_CTX *ctx); +int test_gf2m_mod_exp(BIO *bp, BN_CTX *ctx); +int test_gf2m_mod_sqrt(BIO *bp, BN_CTX *ctx); +int test_gf2m_mod_solve_quad(BIO *bp, BN_CTX *ctx); +int test_kron(BIO *bp, BN_CTX *ctx); +int test_sqrt(BIO *bp, BN_CTX *ctx); +int rand_neg(void); +static int results = 0; + +static unsigned char lst[] = + "\xC6\x4F\x43\x04\x2A\xEA\xCA\x6E\x58\x36\x80\x5B\xE8\xC9" + "\x9B\x04\x5D\x48\x36\xC2\xFD\x16\xC9\x64\xF0"; + +static const char rnd_seed[] = + "string to make the random number generator think it has entropy"; + +static void message(BIO *out, char *m) +{ + fprintf(stderr, "test %s\n", m); + BIO_puts(out, "print \"test "); + BIO_puts(out, m); + BIO_puts(out, "\\n\"\n"); +} + +int main(int argc, char *argv[]) +{ + BN_CTX *ctx; + BIO *out; + char *outfile = NULL; + + results = 0; + + RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */ + + argc--; + argv++; + while (argc >= 1) { + if (strcmp(*argv, "-results") == 0) + results = 1; + else if (strcmp(*argv, "-out") == 0) { + if (--argc < 1) + break; + outfile = *(++argv); + } + argc--; + argv++; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) + EXIT(1); + + out = BIO_new(BIO_s_file()); + if (out == NULL) + EXIT(1); + if (outfile == NULL) { + BIO_set_fp(out, stdout, BIO_NOCLOSE); + } else { + if (!BIO_write_filename(out, outfile)) { + perror(outfile); + EXIT(1); + } + } + + if (!results) + BIO_puts(out, "obase=16\nibase=16\n"); + + message(out, "BN_add"); + if (!test_add(out)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_sub"); + if (!test_sub(out)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_lshift1"); + if (!test_lshift1(out)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_lshift (fixed)"); + if (!test_lshift(out, ctx, BN_bin2bn(lst, sizeof(lst) - 1, NULL))) + goto err; + (void)BIO_flush(out); + + message(out, "BN_lshift"); + if (!test_lshift(out, ctx, NULL)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_rshift1"); + if (!test_rshift1(out)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_rshift"); + if (!test_rshift(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_sqr"); + if (!test_sqr(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mul"); + if (!test_mul(out)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_div"); + if (!test_div(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_div_word"); + if (!test_div_word(out)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_div_recp"); + if (!test_div_recp(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mod"); + if (!test_mod(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mod_mul"); + if (!test_mod_mul(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mont"); + if (!test_mont(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mod_exp"); + if (!test_mod_exp(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mod_exp_mont_consttime"); + if (!test_mod_exp_mont_consttime(out, ctx)) + goto err; + if (!test_mod_exp_mont5(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_exp"); + if (!test_exp(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_kronecker"); + if (!test_kron(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_mod_sqrt"); + if (!test_sqrt(out, ctx)) + goto err; + (void)BIO_flush(out); +#ifndef OPENSSL_NO_EC2M + message(out, "BN_GF2m_add"); + if (!test_gf2m_add(out)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_GF2m_mod"); + if (!test_gf2m_mod(out)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_GF2m_mod_mul"); + if (!test_gf2m_mod_mul(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_GF2m_mod_sqr"); + if (!test_gf2m_mod_sqr(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_GF2m_mod_inv"); + if (!test_gf2m_mod_inv(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_GF2m_mod_div"); + if (!test_gf2m_mod_div(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_GF2m_mod_exp"); + if (!test_gf2m_mod_exp(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_GF2m_mod_sqrt"); + if (!test_gf2m_mod_sqrt(out, ctx)) + goto err; + (void)BIO_flush(out); + + message(out, "BN_GF2m_mod_solve_quad"); + if (!test_gf2m_mod_solve_quad(out, ctx)) + goto err; + (void)BIO_flush(out); +#endif + BN_CTX_free(ctx); + BIO_free(out); + + EXIT(0); + err: + BIO_puts(out, "1\n"); /* make sure the Perl script fed by bc + * notices the failure, see test_bn in + * test/Makefile.ssl */ + (void)BIO_flush(out); + ERR_load_crypto_strings(); + ERR_print_errors_fp(stderr); + EXIT(1); + return (1); +} + +int test_add(BIO *bp) +{ + BIGNUM a, b, c; + int i; + + BN_init(&a); + BN_init(&b); + BN_init(&c); + + BN_bntest_rand(&a, 512, 0, 0); + for (i = 0; i < num0; i++) { + BN_bntest_rand(&b, 450 + i, 0, 0); + a.neg = rand_neg(); + b.neg = rand_neg(); + BN_add(&c, &a, &b); + if (bp != NULL) { + if (!results) { + BN_print(bp, &a); + BIO_puts(bp, " + "); + BN_print(bp, &b); + BIO_puts(bp, " - "); + } + BN_print(bp, &c); + BIO_puts(bp, "\n"); + } + a.neg = !a.neg; + b.neg = !b.neg; + BN_add(&c, &c, &b); + BN_add(&c, &c, &a); + if (!BN_is_zero(&c)) { + fprintf(stderr, "Add test failed!\n"); + return 0; + } + } + BN_free(&a); + BN_free(&b); + BN_free(&c); + return (1); +} + +int test_sub(BIO *bp) +{ + BIGNUM a, b, c; + int i; + + BN_init(&a); + BN_init(&b); + BN_init(&c); + + for (i = 0; i < num0 + num1; i++) { + if (i < num1) { + BN_bntest_rand(&a, 512, 0, 0); + BN_copy(&b, &a); + if (BN_set_bit(&a, i) == 0) + return (0); + BN_add_word(&b, i); + } else { + BN_bntest_rand(&b, 400 + i - num1, 0, 0); + a.neg = rand_neg(); + b.neg = rand_neg(); + } + BN_sub(&c, &a, &b); + if (bp != NULL) { + if (!results) { + BN_print(bp, &a); + BIO_puts(bp, " - "); + BN_print(bp, &b); + BIO_puts(bp, " - "); + } + BN_print(bp, &c); + BIO_puts(bp, "\n"); + } + BN_add(&c, &c, &b); + BN_sub(&c, &c, &a); + if (!BN_is_zero(&c)) { + fprintf(stderr, "Subtract test failed!\n"); + return 0; + } + } + BN_free(&a); + BN_free(&b); + BN_free(&c); + return (1); +} + +int test_div(BIO *bp, BN_CTX *ctx) +{ + BIGNUM a, b, c, d, e; + int i; + + BN_init(&a); + BN_init(&b); + BN_init(&c); + BN_init(&d); + BN_init(&e); + + BN_one(&a); + BN_zero(&b); + + if (BN_div(&d, &c, &a, &b, ctx)) { + fprintf(stderr, "Division by zero succeeded!\n"); + return 0; + } + + for (i = 0; i < num0 + num1; i++) { + if (i < num1) { + BN_bntest_rand(&a, 400, 0, 0); + BN_copy(&b, &a); + BN_lshift(&a, &a, i); + BN_add_word(&a, i); + } else + BN_bntest_rand(&b, 50 + 3 * (i - num1), 0, 0); + a.neg = rand_neg(); + b.neg = rand_neg(); + BN_div(&d, &c, &a, &b, ctx); + if (bp != NULL) { + if (!results) { + BN_print(bp, &a); + BIO_puts(bp, " / "); + BN_print(bp, &b); + BIO_puts(bp, " - "); + } + BN_print(bp, &d); + BIO_puts(bp, "\n"); + + if (!results) { + BN_print(bp, &a); + BIO_puts(bp, " % "); + BN_print(bp, &b); + BIO_puts(bp, " - "); + } + BN_print(bp, &c); + BIO_puts(bp, "\n"); + } + BN_mul(&e, &d, &b, ctx); + BN_add(&d, &e, &c); + BN_sub(&d, &d, &a); + if (!BN_is_zero(&d)) { + fprintf(stderr, "Division test failed!\n"); + return 0; + } + } + BN_free(&a); + BN_free(&b); + BN_free(&c); + BN_free(&d); + BN_free(&e); + return (1); +} + +static void print_word(BIO *bp, BN_ULONG w) +{ +#ifdef SIXTY_FOUR_BIT + if (sizeof(w) > sizeof(unsigned long)) { + unsigned long h = (unsigned long)(w >> 32), l = (unsigned long)(w); + + if (h) + BIO_printf(bp, "%lX%08lX", h, l); + else + BIO_printf(bp, "%lX", l); + return; + } +#endif + BIO_printf(bp, BN_HEX_FMT1, w); +} + +int test_div_word(BIO *bp) +{ + BIGNUM a, b; + BN_ULONG r, s; + int i; + + BN_init(&a); + BN_init(&b); + + for (i = 0; i < num0; i++) { + do { + BN_bntest_rand(&a, 512, -1, 0); + BN_bntest_rand(&b, BN_BITS2, -1, 0); + } while (BN_is_zero(&b)); + + s = b.d[0]; + BN_copy(&b, &a); + r = BN_div_word(&b, s); + + if (bp != NULL) { + if (!results) { + BN_print(bp, &a); + BIO_puts(bp, " / "); + print_word(bp, s); + BIO_puts(bp, " - "); + } + BN_print(bp, &b); + BIO_puts(bp, "\n"); + + if (!results) { + BN_print(bp, &a); + BIO_puts(bp, " % "); + print_word(bp, s); + BIO_puts(bp, " - "); + } + print_word(bp, r); + BIO_puts(bp, "\n"); + } + BN_mul_word(&b, s); + BN_add_word(&b, r); + BN_sub(&b, &a, &b); + if (!BN_is_zero(&b)) { + fprintf(stderr, "Division (word) test failed!\n"); + return 0; + } + } + BN_free(&a); + BN_free(&b); + return (1); +} + +int test_div_recp(BIO *bp, BN_CTX *ctx) +{ + BIGNUM a, b, c, d, e; + BN_RECP_CTX recp; + int i; + + BN_RECP_CTX_init(&recp); + BN_init(&a); + BN_init(&b); + BN_init(&c); + BN_init(&d); + BN_init(&e); + + for (i = 0; i < num0 + num1; i++) { + if (i < num1) { + BN_bntest_rand(&a, 400, 0, 0); + BN_copy(&b, &a); + BN_lshift(&a, &a, i); + BN_add_word(&a, i); + } else + BN_bntest_rand(&b, 50 + 3 * (i - num1), 0, 0); + a.neg = rand_neg(); + b.neg = rand_neg(); + BN_RECP_CTX_set(&recp, &b, ctx); + BN_div_recp(&d, &c, &a, &recp, ctx); + if (bp != NULL) { + if (!results) { + BN_print(bp, &a); + BIO_puts(bp, " / "); + BN_print(bp, &b); + BIO_puts(bp, " - "); + } + BN_print(bp, &d); + BIO_puts(bp, "\n"); + + if (!results) { + BN_print(bp, &a); + BIO_puts(bp, " % "); + BN_print(bp, &b); + BIO_puts(bp, " - "); + } + BN_print(bp, &c); + BIO_puts(bp, "\n"); + } + BN_mul(&e, &d, &b, ctx); + BN_add(&d, &e, &c); + BN_sub(&d, &d, &a); + if (!BN_is_zero(&d)) { + fprintf(stderr, "Reciprocal division test failed!\n"); + fprintf(stderr, "a="); + BN_print_fp(stderr, &a); + fprintf(stderr, "\nb="); + BN_print_fp(stderr, &b); + fprintf(stderr, "\n"); + return 0; + } + } + BN_free(&a); + BN_free(&b); + BN_free(&c); + BN_free(&d); + BN_free(&e); + BN_RECP_CTX_free(&recp); + return (1); +} + +int test_mul(BIO *bp) +{ + BIGNUM a, b, c, d, e; + int i; + BN_CTX *ctx; + + ctx = BN_CTX_new(); + if (ctx == NULL) + EXIT(1); + + BN_init(&a); + BN_init(&b); + BN_init(&c); + BN_init(&d); + BN_init(&e); + + for (i = 0; i < num0 + num1; i++) { + if (i <= num1) { + BN_bntest_rand(&a, 100, 0, 0); + BN_bntest_rand(&b, 100, 0, 0); + } else + BN_bntest_rand(&b, i - num1, 0, 0); + a.neg = rand_neg(); + b.neg = rand_neg(); + BN_mul(&c, &a, &b, ctx); + if (bp != NULL) { + if (!results) { + BN_print(bp, &a); + BIO_puts(bp, " * "); + BN_print(bp, &b); + BIO_puts(bp, " - "); + } + BN_print(bp, &c); + BIO_puts(bp, "\n"); + } + BN_div(&d, &e, &c, &a, ctx); + BN_sub(&d, &d, &b); + if (!BN_is_zero(&d) || !BN_is_zero(&e)) { + fprintf(stderr, "Multiplication test failed!\n"); + return 0; + } + } + BN_free(&a); + BN_free(&b); + BN_free(&c); + BN_free(&d); + BN_free(&e); + BN_CTX_free(ctx); + return (1); +} + +int test_sqr(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *c, *d, *e; + int i, ret = 0; + + a = BN_new(); + c = BN_new(); + d = BN_new(); + e = BN_new(); + if (a == NULL || c == NULL || d == NULL || e == NULL) { + goto err; + } + + for (i = 0; i < num0; i++) { + BN_bntest_rand(a, 40 + i * 10, 0, 0); + a->neg = rand_neg(); + BN_sqr(c, a, ctx); + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " * "); + BN_print(bp, a); + BIO_puts(bp, " - "); + } + BN_print(bp, c); + BIO_puts(bp, "\n"); + } + BN_div(d, e, c, a, ctx); + BN_sub(d, d, a); + if (!BN_is_zero(d) || !BN_is_zero(e)) { + fprintf(stderr, "Square test failed!\n"); + goto err; + } + } + + /* Regression test for a BN_sqr overflow bug. */ + BN_hex2bn(&a, + "80000000000000008000000000000001" + "FFFFFFFFFFFFFFFE0000000000000000"); + BN_sqr(c, a, ctx); + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " * "); + BN_print(bp, a); + BIO_puts(bp, " - "); + } + BN_print(bp, c); + BIO_puts(bp, "\n"); + } + BN_mul(d, a, a, ctx); + if (BN_cmp(c, d)) { + fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce " + "different results!\n"); + goto err; + } + + /* Regression test for a BN_sqr overflow bug. */ + BN_hex2bn(&a, + "80000000000000000000000080000001" + "FFFFFFFE000000000000000000000000"); + BN_sqr(c, a, ctx); + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " * "); + BN_print(bp, a); + BIO_puts(bp, " - "); + } + BN_print(bp, c); + BIO_puts(bp, "\n"); + } + BN_mul(d, a, a, ctx); + if (BN_cmp(c, d)) { + fprintf(stderr, "Square test failed: BN_sqr and BN_mul produce " + "different results!\n"); + goto err; + } + ret = 1; + err: + if (a != NULL) + BN_free(a); + if (c != NULL) + BN_free(c); + if (d != NULL) + BN_free(d); + if (e != NULL) + BN_free(e); + return ret; +} + +int test_mont(BIO *bp, BN_CTX *ctx) +{ + BIGNUM a, b, c, d, A, B; + BIGNUM n; + int i; + BN_MONT_CTX *mont; + + BN_init(&a); + BN_init(&b); + BN_init(&c); + BN_init(&d); + BN_init(&A); + BN_init(&B); + BN_init(&n); + + mont = BN_MONT_CTX_new(); + if (mont == NULL) + return 0; + + BN_zero(&n); + if (BN_MONT_CTX_set(mont, &n, ctx)) { + fprintf(stderr, "BN_MONT_CTX_set succeeded for zero modulus!\n"); + return 0; + } + + BN_set_word(&n, 16); + if (BN_MONT_CTX_set(mont, &n, ctx)) { + fprintf(stderr, "BN_MONT_CTX_set succeeded for even modulus!\n"); + return 0; + } + + BN_bntest_rand(&a, 100, 0, 0); + BN_bntest_rand(&b, 100, 0, 0); + for (i = 0; i < num2; i++) { + int bits = (200 * (i + 1)) / num2; + + if (bits == 0) + continue; + BN_bntest_rand(&n, bits, 0, 1); + BN_MONT_CTX_set(mont, &n, ctx); + + BN_nnmod(&a, &a, &n, ctx); + BN_nnmod(&b, &b, &n, ctx); + + BN_to_montgomery(&A, &a, mont, ctx); + BN_to_montgomery(&B, &b, mont, ctx); + + BN_mod_mul_montgomery(&c, &A, &B, mont, ctx); + BN_from_montgomery(&A, &c, mont, ctx); + if (bp != NULL) { + if (!results) { +#ifdef undef + fprintf(stderr, "%d * %d %% %d\n", + BN_num_bits(&a), + BN_num_bits(&b), BN_num_bits(mont->N)); +#endif + BN_print(bp, &a); + BIO_puts(bp, " * "); + BN_print(bp, &b); + BIO_puts(bp, " % "); + BN_print(bp, &(mont->N)); + BIO_puts(bp, " - "); + } + BN_print(bp, &A); + BIO_puts(bp, "\n"); + } + BN_mod_mul(&d, &a, &b, &n, ctx); + BN_sub(&d, &d, &A); + if (!BN_is_zero(&d)) { + fprintf(stderr, "Montgomery multiplication test failed!\n"); + return 0; + } + } + BN_MONT_CTX_free(mont); + BN_free(&a); + BN_free(&b); + BN_free(&c); + BN_free(&d); + BN_free(&A); + BN_free(&B); + BN_free(&n); + return (1); +} + +int test_mod(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c, *d, *e; + int i; + + a = BN_new(); + b = BN_new(); + c = BN_new(); + d = BN_new(); + e = BN_new(); + + BN_bntest_rand(a, 1024, 0, 0); + for (i = 0; i < num0; i++) { + BN_bntest_rand(b, 450 + i * 10, 0, 0); + a->neg = rand_neg(); + b->neg = rand_neg(); + BN_mod(c, a, b, ctx); + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " % "); + BN_print(bp, b); + BIO_puts(bp, " - "); + } + BN_print(bp, c); + BIO_puts(bp, "\n"); + } + BN_div(d, e, a, b, ctx); + BN_sub(e, e, c); + if (!BN_is_zero(e)) { + fprintf(stderr, "Modulo test failed!\n"); + return 0; + } + } + BN_free(a); + BN_free(b); + BN_free(c); + BN_free(d); + BN_free(e); + return (1); +} + +int test_mod_mul(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c, *d, *e; + int i, j; + + a = BN_new(); + b = BN_new(); + c = BN_new(); + d = BN_new(); + e = BN_new(); + + BN_one(a); + BN_one(b); + BN_zero(c); + if (BN_mod_mul(e, a, b, c, ctx)) { + fprintf(stderr, "BN_mod_mul with zero modulus succeeded!\n"); + return 0; + } + + for (j = 0; j < 3; j++) { + BN_bntest_rand(c, 1024, 0, 0); + for (i = 0; i < num0; i++) { + BN_bntest_rand(a, 475 + i * 10, 0, 0); + BN_bntest_rand(b, 425 + i * 11, 0, 0); + a->neg = rand_neg(); + b->neg = rand_neg(); + if (!BN_mod_mul(e, a, b, c, ctx)) { + unsigned long l; + + while ((l = ERR_get_error())) + fprintf(stderr, "ERROR:%s\n", ERR_error_string(l, NULL)); + EXIT(1); + } + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " * "); + BN_print(bp, b); + BIO_puts(bp, " % "); + BN_print(bp, c); + if ((a->neg ^ b->neg) && !BN_is_zero(e)) { + /* + * If (a*b) % c is negative, c must be added in order + * to obtain the normalized remainder (new with + * OpenSSL 0.9.7, previous versions of BN_mod_mul + * could generate negative results) + */ + BIO_puts(bp, " + "); + BN_print(bp, c); + } + BIO_puts(bp, " - "); + } + BN_print(bp, e); + BIO_puts(bp, "\n"); + } + BN_mul(d, a, b, ctx); + BN_sub(d, d, e); + BN_div(a, b, d, c, ctx); + if (!BN_is_zero(b)) { + fprintf(stderr, "Modulo multiply test failed!\n"); + ERR_print_errors_fp(stderr); + return 0; + } + } + } + BN_free(a); + BN_free(b); + BN_free(c); + BN_free(d); + BN_free(e); + return (1); +} + +int test_mod_exp(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c, *d, *e; + int i; + + a = BN_new(); + b = BN_new(); + c = BN_new(); + d = BN_new(); + e = BN_new(); + + BN_one(a); + BN_one(b); + BN_zero(c); + if (BN_mod_exp(d, a, b, c, ctx)) { + fprintf(stderr, "BN_mod_exp with zero modulus succeeded!\n"); + return 0; + } + + BN_bntest_rand(c, 30, 0, 1); /* must be odd for montgomery */ + for (i = 0; i < num2; i++) { + BN_bntest_rand(a, 20 + i * 5, 0, 0); + BN_bntest_rand(b, 2 + i, 0, 0); + + if (!BN_mod_exp(d, a, b, c, ctx)) + return (0); + + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " ^ "); + BN_print(bp, b); + BIO_puts(bp, " % "); + BN_print(bp, c); + BIO_puts(bp, " - "); + } + BN_print(bp, d); + BIO_puts(bp, "\n"); + } + BN_exp(e, a, b, ctx); + BN_sub(e, e, d); + BN_div(a, b, e, c, ctx); + if (!BN_is_zero(b)) { + fprintf(stderr, "Modulo exponentiation test failed!\n"); + return 0; + } + } + BN_free(a); + BN_free(b); + BN_free(c); + BN_free(d); + BN_free(e); + return (1); +} + +int test_mod_exp_mont_consttime(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c, *d, *e; + int i; + + a = BN_new(); + b = BN_new(); + c = BN_new(); + d = BN_new(); + e = BN_new(); + + BN_one(a); + BN_one(b); + BN_zero(c); + if (BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) { + fprintf(stderr, "BN_mod_exp_mont_consttime with zero modulus " + "succeeded\n"); + return 0; + } + + BN_set_word(c, 16); + if (BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) { + fprintf(stderr, "BN_mod_exp_mont_consttime with even modulus " + "succeeded\n"); + return 0; + } + + BN_bntest_rand(c, 30, 0, 1); /* must be odd for montgomery */ + for (i = 0; i < num2; i++) { + BN_bntest_rand(a, 20 + i * 5, 0, 0); + BN_bntest_rand(b, 2 + i, 0, 0); + + if (!BN_mod_exp_mont_consttime(d, a, b, c, ctx, NULL)) + return (00); + + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " ^ "); + BN_print(bp, b); + BIO_puts(bp, " % "); + BN_print(bp, c); + BIO_puts(bp, " - "); + } + BN_print(bp, d); + BIO_puts(bp, "\n"); + } + BN_exp(e, a, b, ctx); + BN_sub(e, e, d); + BN_div(a, b, e, c, ctx); + if (!BN_is_zero(b)) { + fprintf(stderr, "Modulo exponentiation test failed!\n"); + return 0; + } + } + BN_free(a); + BN_free(b); + BN_free(c); + BN_free(d); + BN_free(e); + return (1); +} + +/* + * Test constant-time modular exponentiation with 1024-bit inputs, which on + * x86_64 cause a different code branch to be taken. + */ +int test_mod_exp_mont5(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *p, *m, *d, *e; + + BN_MONT_CTX *mont; + + a = BN_new(); + p = BN_new(); + m = BN_new(); + d = BN_new(); + e = BN_new(); + + mont = BN_MONT_CTX_new(); + + BN_bntest_rand(m, 1024, 0, 1); /* must be odd for montgomery */ + /* Zero exponent */ + BN_bntest_rand(a, 1024, 0, 0); + BN_zero(p); + if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL)) + return 0; + if (!BN_is_one(d)) { + fprintf(stderr, "Modular exponentiation test failed!\n"); + return 0; + } + /* Zero input */ + BN_bntest_rand(p, 1024, 0, 0); + BN_zero(a); + if (!BN_mod_exp_mont_consttime(d, a, p, m, ctx, NULL)) + return 0; + if (!BN_is_zero(d)) { + fprintf(stderr, "Modular exponentiation test failed!\n"); + return 0; + } + /* + * Craft an input whose Montgomery representation is 1, i.e., shorter + * than the modulus m, in order to test the const time precomputation + * scattering/gathering. + */ + BN_one(a); + BN_MONT_CTX_set(mont, m, ctx); + if (!BN_from_montgomery(e, a, mont, ctx)) + return 0; + if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL)) + return 0; + if (!BN_mod_exp_simple(a, e, p, m, ctx)) + return 0; + if (BN_cmp(a, d) != 0) { + fprintf(stderr, "Modular exponentiation test failed!\n"); + return 0; + } + /* Finally, some regular test vectors. */ + BN_bntest_rand(e, 1024, 0, 0); + if (!BN_mod_exp_mont_consttime(d, e, p, m, ctx, NULL)) + return 0; + if (!BN_mod_exp_simple(a, e, p, m, ctx)) + return 0; + if (BN_cmp(a, d) != 0) { + fprintf(stderr, "Modular exponentiation test failed!\n"); + return 0; + } + BN_free(a); + BN_free(p); + BN_free(m); + BN_free(d); + BN_free(e); + return (1); +} + +int test_exp(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *d, *e, *one; + int i; + + a = BN_new(); + b = BN_new(); + d = BN_new(); + e = BN_new(); + one = BN_new(); + BN_one(one); + + for (i = 0; i < num2; i++) { + BN_bntest_rand(a, 20 + i * 5, 0, 0); + BN_bntest_rand(b, 2 + i, 0, 0); + + if (BN_exp(d, a, b, ctx) <= 0) + return (0); + + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " ^ "); + BN_print(bp, b); + BIO_puts(bp, " - "); + } + BN_print(bp, d); + BIO_puts(bp, "\n"); + } + BN_one(e); + for (; !BN_is_zero(b); BN_sub(b, b, one)) + BN_mul(e, e, a, ctx); + BN_sub(e, e, d); + if (!BN_is_zero(e)) { + fprintf(stderr, "Exponentiation test failed!\n"); + return 0; + } + } + BN_free(a); + BN_free(b); + BN_free(d); + BN_free(e); + BN_free(one); + return (1); +} + +#ifndef OPENSSL_NO_EC2M +int test_gf2m_add(BIO *bp) +{ + BIGNUM a, b, c; + int i, ret = 0; + + BN_init(&a); + BN_init(&b); + BN_init(&c); + + for (i = 0; i < num0; i++) { + BN_rand(&a, 512, 0, 0); + BN_copy(&b, BN_value_one()); + a.neg = rand_neg(); + b.neg = rand_neg(); + BN_GF2m_add(&c, &a, &b); +# if 0 /* make test uses ouput in bc but bc can't + * handle GF(2^m) arithmetic */ + if (bp != NULL) { + if (!results) { + BN_print(bp, &a); + BIO_puts(bp, " ^ "); + BN_print(bp, &b); + BIO_puts(bp, " = "); + } + BN_print(bp, &c); + BIO_puts(bp, "\n"); + } +# endif + /* Test that two added values have the correct parity. */ + if ((BN_is_odd(&a) && BN_is_odd(&c)) + || (!BN_is_odd(&a) && !BN_is_odd(&c))) { + fprintf(stderr, "GF(2^m) addition test (a) failed!\n"); + goto err; + } + BN_GF2m_add(&c, &c, &c); + /* Test that c + c = 0. */ + if (!BN_is_zero(&c)) { + fprintf(stderr, "GF(2^m) addition test (b) failed!\n"); + goto err; + } + } + ret = 1; + err: + BN_free(&a); + BN_free(&b); + BN_free(&c); + return ret; +} + +int test_gf2m_mod(BIO *bp) +{ + BIGNUM *a, *b[2], *c, *d, *e; + int i, j, ret = 0; + int p0[] = { 163, 7, 6, 3, 0, -1 }; + int p1[] = { 193, 15, 0, -1 }; + + a = BN_new(); + b[0] = BN_new(); + b[1] = BN_new(); + c = BN_new(); + d = BN_new(); + e = BN_new(); + + BN_GF2m_arr2poly(p0, b[0]); + BN_GF2m_arr2poly(p1, b[1]); + + for (i = 0; i < num0; i++) { + BN_bntest_rand(a, 1024, 0, 0); + for (j = 0; j < 2; j++) { + BN_GF2m_mod(c, a, b[j]); +# if 0 /* make test uses ouput in bc but bc can't + * handle GF(2^m) arithmetic */ + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " % "); + BN_print(bp, b[j]); + BIO_puts(bp, " - "); + BN_print(bp, c); + BIO_puts(bp, "\n"); + } + } +# endif + BN_GF2m_add(d, a, c); + BN_GF2m_mod(e, d, b[j]); + /* Test that a + (a mod p) mod p == 0. */ + if (!BN_is_zero(e)) { + fprintf(stderr, "GF(2^m) modulo test failed!\n"); + goto err; + } + } + } + ret = 1; + err: + BN_free(a); + BN_free(b[0]); + BN_free(b[1]); + BN_free(c); + BN_free(d); + BN_free(e); + return ret; +} + +int test_gf2m_mod_mul(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b[2], *c, *d, *e, *f, *g, *h; + int i, j, ret = 0; + int p0[] = { 163, 7, 6, 3, 0, -1 }; + int p1[] = { 193, 15, 0, -1 }; + + a = BN_new(); + b[0] = BN_new(); + b[1] = BN_new(); + c = BN_new(); + d = BN_new(); + e = BN_new(); + f = BN_new(); + g = BN_new(); + h = BN_new(); + + BN_GF2m_arr2poly(p0, b[0]); + BN_GF2m_arr2poly(p1, b[1]); + + for (i = 0; i < num0; i++) { + BN_bntest_rand(a, 1024, 0, 0); + BN_bntest_rand(c, 1024, 0, 0); + BN_bntest_rand(d, 1024, 0, 0); + for (j = 0; j < 2; j++) { + BN_GF2m_mod_mul(e, a, c, b[j], ctx); +# if 0 /* make test uses ouput in bc but bc can't + * handle GF(2^m) arithmetic */ + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " * "); + BN_print(bp, c); + BIO_puts(bp, " % "); + BN_print(bp, b[j]); + BIO_puts(bp, " - "); + BN_print(bp, e); + BIO_puts(bp, "\n"); + } + } +# endif + BN_GF2m_add(f, a, d); + BN_GF2m_mod_mul(g, f, c, b[j], ctx); + BN_GF2m_mod_mul(h, d, c, b[j], ctx); + BN_GF2m_add(f, e, g); + BN_GF2m_add(f, f, h); + /* Test that (a+d)*c = a*c + d*c. */ + if (!BN_is_zero(f)) { + fprintf(stderr, + "GF(2^m) modular multiplication test failed!\n"); + goto err; + } + } + } + ret = 1; + err: + BN_free(a); + BN_free(b[0]); + BN_free(b[1]); + BN_free(c); + BN_free(d); + BN_free(e); + BN_free(f); + BN_free(g); + BN_free(h); + return ret; +} + +int test_gf2m_mod_sqr(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b[2], *c, *d; + int i, j, ret = 0; + int p0[] = { 163, 7, 6, 3, 0, -1 }; + int p1[] = { 193, 15, 0, -1 }; + + a = BN_new(); + b[0] = BN_new(); + b[1] = BN_new(); + c = BN_new(); + d = BN_new(); + + BN_GF2m_arr2poly(p0, b[0]); + BN_GF2m_arr2poly(p1, b[1]); + + for (i = 0; i < num0; i++) { + BN_bntest_rand(a, 1024, 0, 0); + for (j = 0; j < 2; j++) { + BN_GF2m_mod_sqr(c, a, b[j], ctx); + BN_copy(d, a); + BN_GF2m_mod_mul(d, a, d, b[j], ctx); +# if 0 /* make test uses ouput in bc but bc can't + * handle GF(2^m) arithmetic */ + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " ^ 2 % "); + BN_print(bp, b[j]); + BIO_puts(bp, " = "); + BN_print(bp, c); + BIO_puts(bp, "; a * a = "); + BN_print(bp, d); + BIO_puts(bp, "\n"); + } + } +# endif + BN_GF2m_add(d, c, d); + /* Test that a*a = a^2. */ + if (!BN_is_zero(d)) { + fprintf(stderr, "GF(2^m) modular squaring test failed!\n"); + goto err; + } + } + } + ret = 1; + err: + BN_free(a); + BN_free(b[0]); + BN_free(b[1]); + BN_free(c); + BN_free(d); + return ret; +} + +int test_gf2m_mod_inv(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b[2], *c, *d; + int i, j, ret = 0; + int p0[] = { 163, 7, 6, 3, 0, -1 }; + int p1[] = { 193, 15, 0, -1 }; + + a = BN_new(); + b[0] = BN_new(); + b[1] = BN_new(); + c = BN_new(); + d = BN_new(); + + BN_GF2m_arr2poly(p0, b[0]); + BN_GF2m_arr2poly(p1, b[1]); + + for (i = 0; i < num0; i++) { + BN_bntest_rand(a, 512, 0, 0); + for (j = 0; j < 2; j++) { + BN_GF2m_mod_inv(c, a, b[j], ctx); + BN_GF2m_mod_mul(d, a, c, b[j], ctx); +# if 0 /* make test uses ouput in bc but bc can't + * handle GF(2^m) arithmetic */ + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " * "); + BN_print(bp, c); + BIO_puts(bp, " - 1 % "); + BN_print(bp, b[j]); + BIO_puts(bp, "\n"); + } + } +# endif + /* Test that ((1/a)*a) = 1. */ + if (!BN_is_one(d)) { + fprintf(stderr, "GF(2^m) modular inversion test failed!\n"); + goto err; + } + } + } + ret = 1; + err: + BN_free(a); + BN_free(b[0]); + BN_free(b[1]); + BN_free(c); + BN_free(d); + return ret; +} + +int test_gf2m_mod_div(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b[2], *c, *d, *e, *f; + int i, j, ret = 0; + int p0[] = { 163, 7, 6, 3, 0, -1 }; + int p1[] = { 193, 15, 0, -1 }; + + a = BN_new(); + b[0] = BN_new(); + b[1] = BN_new(); + c = BN_new(); + d = BN_new(); + e = BN_new(); + f = BN_new(); + + BN_GF2m_arr2poly(p0, b[0]); + BN_GF2m_arr2poly(p1, b[1]); + + for (i = 0; i < num0; i++) { + BN_bntest_rand(a, 512, 0, 0); + BN_bntest_rand(c, 512, 0, 0); + for (j = 0; j < 2; j++) { + BN_GF2m_mod_div(d, a, c, b[j], ctx); + BN_GF2m_mod_mul(e, d, c, b[j], ctx); + BN_GF2m_mod_div(f, a, e, b[j], ctx); +# if 0 /* make test uses ouput in bc but bc can't + * handle GF(2^m) arithmetic */ + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " = "); + BN_print(bp, c); + BIO_puts(bp, " * "); + BN_print(bp, d); + BIO_puts(bp, " % "); + BN_print(bp, b[j]); + BIO_puts(bp, "\n"); + } + } +# endif + /* Test that ((a/c)*c)/a = 1. */ + if (!BN_is_one(f)) { + fprintf(stderr, "GF(2^m) modular division test failed!\n"); + goto err; + } + } + } + ret = 1; + err: + BN_free(a); + BN_free(b[0]); + BN_free(b[1]); + BN_free(c); + BN_free(d); + BN_free(e); + BN_free(f); + return ret; +} + +int test_gf2m_mod_exp(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b[2], *c, *d, *e, *f; + int i, j, ret = 0; + int p0[] = { 163, 7, 6, 3, 0, -1 }; + int p1[] = { 193, 15, 0, -1 }; + + a = BN_new(); + b[0] = BN_new(); + b[1] = BN_new(); + c = BN_new(); + d = BN_new(); + e = BN_new(); + f = BN_new(); + + BN_GF2m_arr2poly(p0, b[0]); + BN_GF2m_arr2poly(p1, b[1]); + + for (i = 0; i < num0; i++) { + BN_bntest_rand(a, 512, 0, 0); + BN_bntest_rand(c, 512, 0, 0); + BN_bntest_rand(d, 512, 0, 0); + for (j = 0; j < 2; j++) { + BN_GF2m_mod_exp(e, a, c, b[j], ctx); + BN_GF2m_mod_exp(f, a, d, b[j], ctx); + BN_GF2m_mod_mul(e, e, f, b[j], ctx); + BN_add(f, c, d); + BN_GF2m_mod_exp(f, a, f, b[j], ctx); +# if 0 /* make test uses ouput in bc but bc can't + * handle GF(2^m) arithmetic */ + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " ^ ("); + BN_print(bp, c); + BIO_puts(bp, " + "); + BN_print(bp, d); + BIO_puts(bp, ") = "); + BN_print(bp, e); + BIO_puts(bp, "; - "); + BN_print(bp, f); + BIO_puts(bp, " % "); + BN_print(bp, b[j]); + BIO_puts(bp, "\n"); + } + } +# endif + BN_GF2m_add(f, e, f); + /* Test that a^(c+d)=a^c*a^d. */ + if (!BN_is_zero(f)) { + fprintf(stderr, + "GF(2^m) modular exponentiation test failed!\n"); + goto err; + } + } + } + ret = 1; + err: + BN_free(a); + BN_free(b[0]); + BN_free(b[1]); + BN_free(c); + BN_free(d); + BN_free(e); + BN_free(f); + return ret; +} + +int test_gf2m_mod_sqrt(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b[2], *c, *d, *e, *f; + int i, j, ret = 0; + int p0[] = { 163, 7, 6, 3, 0, -1 }; + int p1[] = { 193, 15, 0, -1 }; + + a = BN_new(); + b[0] = BN_new(); + b[1] = BN_new(); + c = BN_new(); + d = BN_new(); + e = BN_new(); + f = BN_new(); + + BN_GF2m_arr2poly(p0, b[0]); + BN_GF2m_arr2poly(p1, b[1]); + + for (i = 0; i < num0; i++) { + BN_bntest_rand(a, 512, 0, 0); + for (j = 0; j < 2; j++) { + BN_GF2m_mod(c, a, b[j]); + BN_GF2m_mod_sqrt(d, a, b[j], ctx); + BN_GF2m_mod_sqr(e, d, b[j], ctx); +# if 0 /* make test uses ouput in bc but bc can't + * handle GF(2^m) arithmetic */ + if (bp != NULL) { + if (!results) { + BN_print(bp, d); + BIO_puts(bp, " ^ 2 - "); + BN_print(bp, a); + BIO_puts(bp, "\n"); + } + } +# endif + BN_GF2m_add(f, c, e); + /* Test that d^2 = a, where d = sqrt(a). */ + if (!BN_is_zero(f)) { + fprintf(stderr, "GF(2^m) modular square root test failed!\n"); + goto err; + } + } + } + ret = 1; + err: + BN_free(a); + BN_free(b[0]); + BN_free(b[1]); + BN_free(c); + BN_free(d); + BN_free(e); + BN_free(f); + return ret; +} + +int test_gf2m_mod_solve_quad(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b[2], *c, *d, *e; + int i, j, s = 0, t, ret = 0; + int p0[] = { 163, 7, 6, 3, 0, -1 }; + int p1[] = { 193, 15, 0, -1 }; + + a = BN_new(); + b[0] = BN_new(); + b[1] = BN_new(); + c = BN_new(); + d = BN_new(); + e = BN_new(); + + BN_GF2m_arr2poly(p0, b[0]); + BN_GF2m_arr2poly(p1, b[1]); + + for (i = 0; i < num0; i++) { + BN_bntest_rand(a, 512, 0, 0); + for (j = 0; j < 2; j++) { + t = BN_GF2m_mod_solve_quad(c, a, b[j], ctx); + if (t) { + s++; + BN_GF2m_mod_sqr(d, c, b[j], ctx); + BN_GF2m_add(d, c, d); + BN_GF2m_mod(e, a, b[j]); +# if 0 /* make test uses ouput in bc but bc can't + * handle GF(2^m) arithmetic */ + if (bp != NULL) { + if (!results) { + BN_print(bp, c); + BIO_puts(bp, " is root of z^2 + z = "); + BN_print(bp, a); + BIO_puts(bp, " % "); + BN_print(bp, b[j]); + BIO_puts(bp, "\n"); + } + } +# endif + BN_GF2m_add(e, e, d); + /* + * Test that solution of quadratic c satisfies c^2 + c = a. + */ + if (!BN_is_zero(e)) { + fprintf(stderr, + "GF(2^m) modular solve quadratic test failed!\n"); + goto err; + } + + } else { +# if 0 /* make test uses ouput in bc but bc can't + * handle GF(2^m) arithmetic */ + if (bp != NULL) { + if (!results) { + BIO_puts(bp, "There are no roots of z^2 + z = "); + BN_print(bp, a); + BIO_puts(bp, " % "); + BN_print(bp, b[j]); + BIO_puts(bp, "\n"); + } + } +# endif + } + } + } + if (s == 0) { + fprintf(stderr, + "All %i tests of GF(2^m) modular solve quadratic resulted in no roots;\n", + num0); + fprintf(stderr, + "this is very unlikely and probably indicates an error.\n"); + goto err; + } + ret = 1; + err: + BN_free(a); + BN_free(b[0]); + BN_free(b[1]); + BN_free(c); + BN_free(d); + BN_free(e); + return ret; +} +#endif +static int genprime_cb(int p, int n, BN_GENCB *arg) +{ + char c = '*'; + + if (p == 0) + c = '.'; + if (p == 1) + c = '+'; + if (p == 2) + c = '*'; + if (p == 3) + c = '\n'; + putc(c, stderr); + fflush(stderr); + return 1; +} + +int test_kron(BIO *bp, BN_CTX *ctx) +{ + BN_GENCB cb; + BIGNUM *a, *b, *r, *t; + int i; + int legendre, kronecker; + int ret = 0; + + a = BN_new(); + b = BN_new(); + r = BN_new(); + t = BN_new(); + if (a == NULL || b == NULL || r == NULL || t == NULL) + goto err; + + BN_GENCB_set(&cb, genprime_cb, NULL); + + /* + * We test BN_kronecker(a, b, ctx) just for b odd (Jacobi symbol). In + * this case we know that if b is prime, then BN_kronecker(a, b, ctx) is + * congruent to $a^{(b-1)/2}$, modulo $b$ (Legendre symbol). So we + * generate a random prime b and compare these values for a number of + * random a's. (That is, we run the Solovay-Strassen primality test to + * confirm that b is prime, except that we don't want to test whether b + * is prime but whether BN_kronecker works.) + */ + + if (!BN_generate_prime_ex(b, 512, 0, NULL, NULL, &cb)) + goto err; + b->neg = rand_neg(); + putc('\n', stderr); + + for (i = 0; i < num0; i++) { + if (!BN_bntest_rand(a, 512, 0, 0)) + goto err; + a->neg = rand_neg(); + + /* t := (|b|-1)/2 (note that b is odd) */ + if (!BN_copy(t, b)) + goto err; + t->neg = 0; + if (!BN_sub_word(t, 1)) + goto err; + if (!BN_rshift1(t, t)) + goto err; + /* r := a^t mod b */ + b->neg = 0; + + if (!BN_mod_exp_recp(r, a, t, b, ctx)) + goto err; + b->neg = 1; + + if (BN_is_word(r, 1)) + legendre = 1; + else if (BN_is_zero(r)) + legendre = 0; + else { + if (!BN_add_word(r, 1)) + goto err; + if (0 != BN_ucmp(r, b)) { + fprintf(stderr, "Legendre symbol computation failed\n"); + goto err; + } + legendre = -1; + } + + kronecker = BN_kronecker(a, b, ctx); + if (kronecker < -1) + goto err; + /* we actually need BN_kronecker(a, |b|) */ + if (a->neg && b->neg) + kronecker = -kronecker; + + if (legendre != kronecker) { + fprintf(stderr, "legendre != kronecker; a = "); + BN_print_fp(stderr, a); + fprintf(stderr, ", b = "); + BN_print_fp(stderr, b); + fprintf(stderr, "\n"); + goto err; + } + + putc('.', stderr); + fflush(stderr); + } + + putc('\n', stderr); + fflush(stderr); + ret = 1; + err: + if (a != NULL) + BN_free(a); + if (b != NULL) + BN_free(b); + if (r != NULL) + BN_free(r); + if (t != NULL) + BN_free(t); + return ret; +} + +int test_sqrt(BIO *bp, BN_CTX *ctx) +{ + BN_GENCB cb; + BIGNUM *a, *p, *r; + int i, j; + int ret = 0; + + a = BN_new(); + p = BN_new(); + r = BN_new(); + if (a == NULL || p == NULL || r == NULL) + goto err; + + BN_GENCB_set(&cb, genprime_cb, NULL); + + for (i = 0; i < 16; i++) { + if (i < 8) { + unsigned primes[8] = { 2, 3, 5, 7, 11, 13, 17, 19 }; + + if (!BN_set_word(p, primes[i])) + goto err; + } else { + if (!BN_set_word(a, 32)) + goto err; + if (!BN_set_word(r, 2 * i + 1)) + goto err; + + if (!BN_generate_prime_ex(p, 256, 0, a, r, &cb)) + goto err; + putc('\n', stderr); + } + p->neg = rand_neg(); + + for (j = 0; j < num2; j++) { + /* + * construct 'a' such that it is a square modulo p, but in + * general not a proper square and not reduced modulo p + */ + if (!BN_bntest_rand(r, 256, 0, 3)) + goto err; + if (!BN_nnmod(r, r, p, ctx)) + goto err; + if (!BN_mod_sqr(r, r, p, ctx)) + goto err; + if (!BN_bntest_rand(a, 256, 0, 3)) + goto err; + if (!BN_nnmod(a, a, p, ctx)) + goto err; + if (!BN_mod_sqr(a, a, p, ctx)) + goto err; + if (!BN_mul(a, a, r, ctx)) + goto err; + if (rand_neg()) + if (!BN_sub(a, a, p)) + goto err; + + if (!BN_mod_sqrt(r, a, p, ctx)) + goto err; + if (!BN_mod_sqr(r, r, p, ctx)) + goto err; + + if (!BN_nnmod(a, a, p, ctx)) + goto err; + + if (BN_cmp(a, r) != 0) { + fprintf(stderr, "BN_mod_sqrt failed: a = "); + BN_print_fp(stderr, a); + fprintf(stderr, ", r = "); + BN_print_fp(stderr, r); + fprintf(stderr, ", p = "); + BN_print_fp(stderr, p); + fprintf(stderr, "\n"); + goto err; + } + + putc('.', stderr); + fflush(stderr); + } + + putc('\n', stderr); + fflush(stderr); + } + ret = 1; + err: + if (a != NULL) + BN_free(a); + if (p != NULL) + BN_free(p); + if (r != NULL) + BN_free(r); + return ret; +} + +int test_lshift(BIO *bp, BN_CTX *ctx, BIGNUM *a_) +{ + BIGNUM *a, *b, *c, *d; + int i; + + b = BN_new(); + c = BN_new(); + d = BN_new(); + BN_one(c); + + if (a_) + a = a_; + else { + a = BN_new(); + BN_bntest_rand(a, 200, 0, 0); + a->neg = rand_neg(); + } + for (i = 0; i < num0; i++) { + BN_lshift(b, a, i + 1); + BN_add(c, c, c); + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " * "); + BN_print(bp, c); + BIO_puts(bp, " - "); + } + BN_print(bp, b); + BIO_puts(bp, "\n"); + } + BN_mul(d, a, c, ctx); + BN_sub(d, d, b); + if (!BN_is_zero(d)) { + fprintf(stderr, "Left shift test failed!\n"); + fprintf(stderr, "a="); + BN_print_fp(stderr, a); + fprintf(stderr, "\nb="); + BN_print_fp(stderr, b); + fprintf(stderr, "\nc="); + BN_print_fp(stderr, c); + fprintf(stderr, "\nd="); + BN_print_fp(stderr, d); + fprintf(stderr, "\n"); + return 0; + } + } + BN_free(a); + BN_free(b); + BN_free(c); + BN_free(d); + return (1); +} + +int test_lshift1(BIO *bp) +{ + BIGNUM *a, *b, *c; + int i; + + a = BN_new(); + b = BN_new(); + c = BN_new(); + + BN_bntest_rand(a, 200, 0, 0); + a->neg = rand_neg(); + for (i = 0; i < num0; i++) { + BN_lshift1(b, a); + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " * 2"); + BIO_puts(bp, " - "); + } + BN_print(bp, b); + BIO_puts(bp, "\n"); + } + BN_add(c, a, a); + BN_sub(a, b, c); + if (!BN_is_zero(a)) { + fprintf(stderr, "Left shift one test failed!\n"); + return 0; + } + + BN_copy(a, b); + } + BN_free(a); + BN_free(b); + BN_free(c); + return (1); +} + +int test_rshift(BIO *bp, BN_CTX *ctx) +{ + BIGNUM *a, *b, *c, *d, *e; + int i; + + a = BN_new(); + b = BN_new(); + c = BN_new(); + d = BN_new(); + e = BN_new(); + BN_one(c); + + BN_bntest_rand(a, 200, 0, 0); + a->neg = rand_neg(); + for (i = 0; i < num0; i++) { + BN_rshift(b, a, i + 1); + BN_add(c, c, c); + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " / "); + BN_print(bp, c); + BIO_puts(bp, " - "); + } + BN_print(bp, b); + BIO_puts(bp, "\n"); + } + BN_div(d, e, a, c, ctx); + BN_sub(d, d, b); + if (!BN_is_zero(d)) { + fprintf(stderr, "Right shift test failed!\n"); + return 0; + } + } + BN_free(a); + BN_free(b); + BN_free(c); + BN_free(d); + BN_free(e); + return (1); +} + +int test_rshift1(BIO *bp) +{ + BIGNUM *a, *b, *c; + int i; + + a = BN_new(); + b = BN_new(); + c = BN_new(); + + BN_bntest_rand(a, 200, 0, 0); + a->neg = rand_neg(); + for (i = 0; i < num0; i++) { + BN_rshift1(b, a); + if (bp != NULL) { + if (!results) { + BN_print(bp, a); + BIO_puts(bp, " / 2"); + BIO_puts(bp, " - "); + } + BN_print(bp, b); + BIO_puts(bp, "\n"); + } + BN_sub(c, a, b); + BN_sub(c, c, b); + if (!BN_is_zero(c) && !BN_abs_is_word(c, 1)) { + fprintf(stderr, "Right shift one test failed!\n"); + return 0; + } + BN_copy(a, b); + } + BN_free(a); + BN_free(b); + BN_free(c); + return (1); +} + +int rand_neg(void) +{ + static unsigned int neg = 0; + static int sign[8] = { 0, 0, 0, 1, 1, 0, 1, 1 }; + + return (sign[(neg++) % 8]); +} diff --git a/libs/openssl/crypto/bn/divtest.c b/libs/openssl/crypto/bn/divtest.c new file mode 100644 index 00000000..2590b458 --- /dev/null +++ b/libs/openssl/crypto/bn/divtest.c @@ -0,0 +1,42 @@ +#include +#include + +static int Rand(n) +{ + unsigned char x[2]; + RAND_pseudo_bytes(x, 2); + return (x[0] + 2 * x[1]); +} + +static void bug(char *m, BIGNUM *a, BIGNUM *b) +{ + printf("%s!\na=", m); + BN_print_fp(stdout, a); + printf("\nb="); + BN_print_fp(stdout, b); + printf("\n"); + fflush(stdout); +} + +main() +{ + BIGNUM *a = BN_new(), *b = BN_new(), *c = BN_new(), *d = BN_new(), + *C = BN_new(), *D = BN_new(); + BN_RECP_CTX *recp = BN_RECP_CTX_new(); + BN_CTX *ctx = BN_CTX_new(); + + for (;;) { + BN_pseudo_rand(a, Rand(), 0, 0); + BN_pseudo_rand(b, Rand(), 0, 0); + if (BN_is_zero(b)) + continue; + + BN_RECP_CTX_set(recp, b, ctx); + if (BN_div(C, D, a, b, ctx) != 1) + bug("BN_div failed", a, b); + if (BN_div_recp(c, d, a, recp, ctx) != 1) + bug("BN_div_recp failed", a, b); + else if (BN_cmp(c, C) != 0 || BN_cmp(c, C) != 0) + bug("mismatch", a, b); + } +} diff --git a/libs/openssl/crypto/bn/exp.c b/libs/openssl/crypto/bn/exp.c new file mode 100644 index 00000000..fbce28c5 --- /dev/null +++ b/libs/openssl/crypto/bn/exp.c @@ -0,0 +1,61 @@ +/* unused */ + +#include +#include +#include "bn_lcl.h" + +#define SIZE 256 +#define NUM (8*8*8) +#define MOD (8*8*8*8*8) + +main(argc, argv) +int argc; +char *argv[]; +{ + BN_CTX ctx; + BIGNUM a, b, c, r, rr, t, l; + int j, i, size = SIZE, num = NUM, mod = MOD; + char *start, *end; + BN_MONT_CTX mont; + double d, md; + + BN_MONT_CTX_init(&mont); + BN_CTX_init(&ctx); + BN_init(&a); + BN_init(&b); + BN_init(&c); + BN_init(&r); + + start = ms_time_new(); + end = ms_time_new(); + while (size <= 1024 * 8) { + BN_rand(&a, size, 0, 0); + BN_rand(&b, size, 1, 0); + BN_rand(&c, size, 0, 1); + + BN_mod(&a, &a, &c, &ctx); + + ms_time_get(start); + for (i = 0; i < 10; i++) + BN_MONT_CTX_set(&mont, &c, &ctx); + ms_time_get(end); + md = ms_time_diff(start, end); + + ms_time_get(start); + for (i = 0; i < num; i++) { + /* bn_mull(&r,&a,&b,&ctx); */ + /* BN_sqr(&r,&a,&ctx); */ + BN_mod_exp_mont(&r, &a, &b, &c, &ctx, &mont); + } + ms_time_get(end); + d = ms_time_diff(start, end) /* *50/33 */ ; + printf("%5d bit:%6.2f %6d %6.4f %4d m_set(%5.4f)\n", size, + d, num, d / num, (int)((d / num) * mod), md / 10.0); + num /= 8; + mod /= 8; + if (num <= 0) + num = 1; + size *= 2; + } + +} diff --git a/libs/openssl/crypto/bn/expspeed.c b/libs/openssl/crypto/bn/expspeed.c new file mode 100644 index 00000000..513a568a --- /dev/null +++ b/libs/openssl/crypto/bn/expspeed.c @@ -0,0 +1,381 @@ +/* unused */ + +/* crypto/bn/expspeed.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* most of this code has been pilfered from my libdes speed.c program */ + +#define BASENUM 5000 +#define NUM_START 0 + +/* + * determine timings for modexp, modmul, modsqr, gcd, Kronecker symbol, + * modular inverse, or modular square roots + */ +#define TEST_EXP +#undef TEST_MUL +#undef TEST_SQR +#undef TEST_GCD +#undef TEST_KRON +#undef TEST_INV +#undef TEST_SQRT +#define P_MOD_64 9 /* least significant 6 bits for prime to be + * used for BN_sqrt timings */ + +#if defined(TEST_EXP) + defined(TEST_MUL) + defined(TEST_SQR) + defined(TEST_GCD) + defined(TEST_KRON) + defined(TEST_INV) +defined(TEST_SQRT) != 1 +# error "choose one test" +#endif + +#if defined(TEST_INV) || defined(TEST_SQRT) +# define C_PRIME +static void genprime_cb(int p, int n, void *arg); +#endif + +#undef PROG +#define PROG bnspeed_main + +#include +#include +#include +#include +#include +#include +#include + +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX) +# define TIMES +#endif + +#ifndef _IRIX +# include +#endif +#ifdef TIMES +# include +# include +#endif + +/* + * Depending on the VMS version, the tms structure is perhaps defined. The + * __TMS macro will show if it was. If it wasn't defined, we should undefine + * TIMES, since that tells the rest of the program how things should be + * handled. -- Richard Levitte + */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) +# undef TIMES +#endif + +#ifndef TIMES +# include +#endif + +#if defined(sun) || defined(__ultrix) +# define _POSIX_SOURCE +# include +# include +#endif + +#include +#include + +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# ifndef _BSD_CLK_TCK_ /* FreeBSD hack */ +# define HZ 100.0 +# else /* _BSD_CLK_TCK_ */ +# define HZ ((double)_BSD_CLK_TCK_) +# endif +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +#endif + +#undef BUFSIZE +#define BUFSIZE ((long)1024*8) +int run = 0; + +static double Time_F(int s); +#define START 0 +#define STOP 1 + +static double Time_F(int s) +{ + double ret; +#ifdef TIMES + static struct tms tstart, tend; + + if (s == START) { + times(&tstart); + return (0); + } else { + times(&tend); + ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ; + return ((ret < 1e-3) ? 1e-3 : ret); + } +#else /* !times() */ + static struct timeb tstart, tend; + long i; + + if (s == START) { + ftime(&tstart); + return (0); + } else { + ftime(&tend); + i = (long)tend.millitm - (long)tstart.millitm; + ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1000.0; + return ((ret < 0.001) ? 0.001 : ret); + } +#endif +} + +#define NUM_SIZES 7 +#if NUM_START > NUM_SIZES +# error "NUM_START > NUM_SIZES" +#endif +static int sizes[NUM_SIZES] = { 128, 256, 512, 1024, 2048, 4096, 8192 }; + +static int mul_c[NUM_SIZES] = + { 8 * 8 * 8 * 8 * 8 * 8, 8 * 8 * 8 * 8 * 8, 8 * 8 * 8 * 8, 8 * 8 * 8, + 8 * 8, 8, 1 +}; + +/* + * static int sizes[NUM_SIZES]={59,179,299,419,539}; + */ + +#define RAND_SEED(string) { const char str[] = string; RAND_seed(string, sizeof str); } + +void do_mul_exp(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx); + +int main(int argc, char **argv) +{ + BN_CTX *ctx; + BIGNUM *a, *b, *c, *r; + +#if 1 + if (!CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0)) + abort(); +#endif + + ctx = BN_CTX_new(); + a = BN_new(); + b = BN_new(); + c = BN_new(); + r = BN_new(); + + while (!RAND_status()) + /* not enough bits */ + RAND_SEED("I demand a manual recount!"); + + do_mul_exp(r, a, b, c, ctx); + return 0; +} + +void do_mul_exp(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *c, BN_CTX *ctx) +{ + int i, k; + double tm; + long num; + + num = BASENUM; + for (i = NUM_START; i < NUM_SIZES; i++) { +#ifdef C_PRIME +# ifdef TEST_SQRT + if (!BN_set_word(a, 64)) + goto err; + if (!BN_set_word(b, P_MOD_64)) + goto err; +# define ADD a +# define REM b +# else +# define ADD NULL +# define REM NULL +# endif + if (!BN_generate_prime(c, sizes[i], 0, ADD, REM, genprime_cb, NULL)) + goto err; + putc('\n', stderr); + fflush(stderr); +#endif + + for (k = 0; k < num; k++) { + if (k % 50 == 0) { /* Average over num/50 different choices of + * random numbers. */ + if (!BN_pseudo_rand(a, sizes[i], 1, 0)) + goto err; + + if (!BN_pseudo_rand(b, sizes[i], 1, 0)) + goto err; + +#ifndef C_PRIME + if (!BN_pseudo_rand(c, sizes[i], 1, 1)) + goto err; +#endif + +#ifdef TEST_SQRT + if (!BN_mod_sqr(a, a, c, ctx)) + goto err; + if (!BN_mod_sqr(b, b, c, ctx)) + goto err; +#else + if (!BN_nnmod(a, a, c, ctx)) + goto err; + if (!BN_nnmod(b, b, c, ctx)) + goto err; +#endif + + if (k == 0) + Time_F(START); + } +#if defined(TEST_EXP) + if (!BN_mod_exp(r, a, b, c, ctx)) + goto err; +#elif defined(TEST_MUL) + { + int i = 0; + for (i = 0; i < 50; i++) + if (!BN_mod_mul(r, a, b, c, ctx)) + goto err; + } +#elif defined(TEST_SQR) + { + int i = 0; + for (i = 0; i < 50; i++) { + if (!BN_mod_sqr(r, a, c, ctx)) + goto err; + if (!BN_mod_sqr(r, b, c, ctx)) + goto err; + } + } +#elif defined(TEST_GCD) + if (!BN_gcd(r, a, b, ctx)) + goto err; + if (!BN_gcd(r, b, c, ctx)) + goto err; + if (!BN_gcd(r, c, a, ctx)) + goto err; +#elif defined(TEST_KRON) + if (-2 == BN_kronecker(a, b, ctx)) + goto err; + if (-2 == BN_kronecker(b, c, ctx)) + goto err; + if (-2 == BN_kronecker(c, a, ctx)) + goto err; +#elif defined(TEST_INV) + if (!BN_mod_inverse(r, a, c, ctx)) + goto err; + if (!BN_mod_inverse(r, b, c, ctx)) + goto err; +#else /* TEST_SQRT */ + if (!BN_mod_sqrt(r, a, c, ctx)) + goto err; + if (!BN_mod_sqrt(r, b, c, ctx)) + goto err; +#endif + } + tm = Time_F(STOP); + printf( +#if defined(TEST_EXP) + "modexp %4d ^ %4d %% %4d" +#elif defined(TEST_MUL) + "50*modmul %4d %4d %4d" +#elif defined(TEST_SQR) + "100*modsqr %4d %4d %4d" +#elif defined(TEST_GCD) + "3*gcd %4d %4d %4d" +#elif defined(TEST_KRON) + "3*kronecker %4d %4d %4d" +#elif defined(TEST_INV) + "2*inv %4d %4d mod %4d" +#else /* TEST_SQRT */ + "2*sqrt [prime == %d (mod 64)] %4d %4d mod %4d" +#endif + " -> %8.6fms %5.1f (%ld)\n", +#ifdef TEST_SQRT + P_MOD_64, +#endif + sizes[i], sizes[i], sizes[i], tm * 1000.0 / num, + tm * mul_c[i] / num, num); + num /= 7; + if (num <= 0) + num = 1; + } + return; + + err: + ERR_print_errors_fp(stderr); +} + +#ifdef C_PRIME +static void genprime_cb(int p, int n, void *arg) +{ + char c = '*'; + + if (p == 0) + c = '.'; + if (p == 1) + c = '+'; + if (p == 2) + c = '*'; + if (p == 3) + c = '\n'; + putc(c, stderr); + fflush(stderr); + (void)n; + (void)arg; +} +#endif diff --git a/libs/openssl/crypto/bn/exptest.c b/libs/openssl/crypto/bn/exptest.c new file mode 100644 index 00000000..ac611c2e --- /dev/null +++ b/libs/openssl/crypto/bn/exptest.c @@ -0,0 +1,313 @@ +/* crypto/bn/exptest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "../e_os.h" + +#include +#include +#include +#include + +#define NUM_BITS (BN_BITS*2) + +static const char rnd_seed[] = + "string to make the random number generator think it has entropy"; + +/* + * Test that r == 0 in test_exp_mod_zero(). Returns one on success, + * returns zero and prints debug output otherwise. + */ +static int a_is_zero_mod_one(const char *method, const BIGNUM *r, + const BIGNUM *a) { + if (!BN_is_zero(r)) { + fprintf(stderr, "%s failed:\n", method); + fprintf(stderr, "a ** 0 mod 1 = r (should be 0)\n"); + fprintf(stderr, "a = "); + BN_print_fp(stderr, a); + fprintf(stderr, "\nr = "); + BN_print_fp(stderr, r); + fprintf(stderr, "\n"); + return 0; + } + return 1; +} + +/* + * test_exp_mod_zero tests that x**0 mod 1 == 0. It returns zero on success. + */ +static int test_exp_mod_zero() +{ + BIGNUM a, p, m; + BIGNUM r; + BN_ULONG one_word = 1; + BN_CTX *ctx = BN_CTX_new(); + int ret = 1, failed = 0; + + BN_init(&m); + BN_one(&m); + + BN_init(&a); + BN_one(&a); + + BN_init(&p); + BN_zero(&p); + + BN_init(&r); + + if (!BN_rand(&a, 1024, 0, 0)) + goto err; + + if (!BN_mod_exp(&r, &a, &p, &m, ctx)) + goto err; + + if (!a_is_zero_mod_one("BN_mod_exp", &r, &a)) + failed = 1; + + if (!BN_mod_exp_recp(&r, &a, &p, &m, ctx)) + goto err; + + if (!a_is_zero_mod_one("BN_mod_exp_recp", &r, &a)) + failed = 1; + + if (!BN_mod_exp_simple(&r, &a, &p, &m, ctx)) + goto err; + + if (!a_is_zero_mod_one("BN_mod_exp_simple", &r, &a)) + failed = 1; + + if (!BN_mod_exp_mont(&r, &a, &p, &m, ctx, NULL)) + goto err; + + if (!a_is_zero_mod_one("BN_mod_exp_mont", &r, &a)) + failed = 1; + + if (!BN_mod_exp_mont_consttime(&r, &a, &p, &m, ctx, NULL)) { + goto err; + } + + if (!a_is_zero_mod_one("BN_mod_exp_mont_consttime", &r, &a)) + failed = 1; + + /* + * A different codepath exists for single word multiplication + * in non-constant-time only. + */ + if (!BN_mod_exp_mont_word(&r, one_word, &p, &m, ctx, NULL)) + goto err; + + if (!BN_is_zero(&r)) { + fprintf(stderr, "BN_mod_exp_mont_word failed:\n"); + fprintf(stderr, "1 ** 0 mod 1 = r (should be 0)\n"); + fprintf(stderr, "r = "); + BN_print_fp(stderr, &r); + fprintf(stderr, "\n"); + return 0; + } + + ret = failed; + + err: + BN_free(&r); + BN_free(&a); + BN_free(&p); + BN_free(&m); + BN_CTX_free(ctx); + + return ret; +} + +int main(int argc, char *argv[]) +{ + BN_CTX *ctx; + BIO *out = NULL; + int i, ret; + unsigned char c; + BIGNUM *r_mont, *r_mont_const, *r_recp, *r_simple, *a, *b, *m; + + RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_rand may fail, and we + * don't even check its return + * value (which we should) */ + + ERR_load_BN_strings(); + + ctx = BN_CTX_new(); + if (ctx == NULL) + EXIT(1); + r_mont = BN_new(); + r_mont_const = BN_new(); + r_recp = BN_new(); + r_simple = BN_new(); + a = BN_new(); + b = BN_new(); + m = BN_new(); + if ((r_mont == NULL) || (r_recp == NULL) || (a == NULL) || (b == NULL)) + goto err; + + out = BIO_new(BIO_s_file()); + + if (out == NULL) + EXIT(1); + BIO_set_fp(out, stdout, BIO_NOCLOSE); + + for (i = 0; i < 200; i++) { + RAND_bytes(&c, 1); + c = (c % BN_BITS) - BN_BITS2; + BN_rand(a, NUM_BITS + c, 0, 0); + + RAND_bytes(&c, 1); + c = (c % BN_BITS) - BN_BITS2; + BN_rand(b, NUM_BITS + c, 0, 0); + + RAND_bytes(&c, 1); + c = (c % BN_BITS) - BN_BITS2; + BN_rand(m, NUM_BITS + c, 0, 1); + + BN_mod(a, a, m, ctx); + BN_mod(b, b, m, ctx); + + ret = BN_mod_exp_mont(r_mont, a, b, m, ctx, NULL); + if (ret <= 0) { + printf("BN_mod_exp_mont() problems\n"); + ERR_print_errors(out); + EXIT(1); + } + + ret = BN_mod_exp_recp(r_recp, a, b, m, ctx); + if (ret <= 0) { + printf("BN_mod_exp_recp() problems\n"); + ERR_print_errors(out); + EXIT(1); + } + + ret = BN_mod_exp_simple(r_simple, a, b, m, ctx); + if (ret <= 0) { + printf("BN_mod_exp_simple() problems\n"); + ERR_print_errors(out); + EXIT(1); + } + + ret = BN_mod_exp_mont_consttime(r_mont_const, a, b, m, ctx, NULL); + if (ret <= 0) { + printf("BN_mod_exp_mont_consttime() problems\n"); + ERR_print_errors(out); + EXIT(1); + } + + if (BN_cmp(r_simple, r_mont) == 0 + && BN_cmp(r_simple, r_recp) == 0 + && BN_cmp(r_simple, r_mont_const) == 0) { + printf("."); + fflush(stdout); + } else { + if (BN_cmp(r_simple, r_mont) != 0) + printf("\nsimple and mont results differ\n"); + if (BN_cmp(r_simple, r_mont_const) != 0) + printf("\nsimple and mont const time results differ\n"); + if (BN_cmp(r_simple, r_recp) != 0) + printf("\nsimple and recp results differ\n"); + + printf("a (%3d) = ", BN_num_bits(a)); + BN_print(out, a); + printf("\nb (%3d) = ", BN_num_bits(b)); + BN_print(out, b); + printf("\nm (%3d) = ", BN_num_bits(m)); + BN_print(out, m); + printf("\nsimple ="); + BN_print(out, r_simple); + printf("\nrecp ="); + BN_print(out, r_recp); + printf("\nmont ="); + BN_print(out, r_mont); + printf("\nmont_ct ="); + BN_print(out, r_mont_const); + printf("\n"); + EXIT(1); + } + } + BN_free(r_mont); + BN_free(r_mont_const); + BN_free(r_recp); + BN_free(r_simple); + BN_free(a); + BN_free(b); + BN_free(m); + BN_CTX_free(ctx); + ERR_remove_thread_state(NULL); + CRYPTO_mem_leaks(out); + BIO_free(out); + printf("\n"); + + if (test_exp_mod_zero() != 0) + goto err; + + printf("done\n"); + + EXIT(0); + err: + ERR_load_crypto_strings(); + ERR_print_errors(out); +#ifdef OPENSSL_SYS_NETWARE + printf("ERROR\n"); +#endif + EXIT(1); + return (1); +} diff --git a/libs/openssl/crypto/bn/todo b/libs/openssl/crypto/bn/todo new file mode 100644 index 00000000..e47e381a --- /dev/null +++ b/libs/openssl/crypto/bn/todo @@ -0,0 +1,3 @@ +Cache RECP_CTX values +make the result argument independant of the inputs. +split up the _exp_ functions diff --git a/libs/openssl/crypto/bn/vms-helper.c b/libs/openssl/crypto/bn/vms-helper.c new file mode 100644 index 00000000..f342e90c --- /dev/null +++ b/libs/openssl/crypto/bn/vms-helper.c @@ -0,0 +1,68 @@ +/* vms-helper.c */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include "bn_lcl.h" + +bn_div_words_abort(int i) +{ +#ifdef BN_DEBUG +# if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) + fprintf(stderr, "Division would overflow (%d)\n", i); +# endif + abort(); +#endif +} diff --git a/libs/openssl/crypto/buffer/buf_err.c b/libs/openssl/crypto/buffer/buf_err.c new file mode 100644 index 00000000..631eec38 --- /dev/null +++ b/libs/openssl/crypto/buffer/buf_err.c @@ -0,0 +1,97 @@ +/* crypto/buffer/buf_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_BUF,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_BUF,0,reason) + +static ERR_STRING_DATA BUF_str_functs[] = { + {ERR_FUNC(BUF_F_BUF_MEMDUP), "BUF_memdup"}, + {ERR_FUNC(BUF_F_BUF_MEM_GROW), "BUF_MEM_grow"}, + {ERR_FUNC(BUF_F_BUF_MEM_GROW_CLEAN), "BUF_MEM_grow_clean"}, + {ERR_FUNC(BUF_F_BUF_MEM_NEW), "BUF_MEM_new"}, + {ERR_FUNC(BUF_F_BUF_STRDUP), "BUF_strdup"}, + {ERR_FUNC(BUF_F_BUF_STRNDUP), "BUF_strndup"}, + {0, NULL} +}; + +static ERR_STRING_DATA BUF_str_reasons[] = { + {0, NULL} +}; + +#endif + +void ERR_load_BUF_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(BUF_str_functs[0].error) == NULL) { + ERR_load_strings(0, BUF_str_functs); + ERR_load_strings(0, BUF_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/buffer/buf_str.c b/libs/openssl/crypto/buffer/buf_str.c new file mode 100644 index 00000000..233af246 --- /dev/null +++ b/libs/openssl/crypto/buffer/buf_str.c @@ -0,0 +1,126 @@ +/* crypto/buffer/buffer.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +char *BUF_strdup(const char *str) +{ + if (str == NULL) + return NULL; + return BUF_strndup(str, strlen(str)); +} + +char *BUF_strndup(const char *str, size_t siz) +{ + char *ret; + + if (str == NULL) + return NULL; + + if (siz >= INT_MAX) + return NULL; + + ret = OPENSSL_malloc(siz + 1); + if (ret == NULL) { + BUFerr(BUF_F_BUF_STRNDUP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + memcpy(ret, str, siz); + ret[siz] = '\0'; + + return (ret); +} + +void *BUF_memdup(const void *data, size_t siz) +{ + void *ret; + + if (data == NULL || siz >= INT_MAX) + return NULL; + + ret = OPENSSL_malloc(siz); + if (ret == NULL) { + BUFerr(BUF_F_BUF_MEMDUP, ERR_R_MALLOC_FAILURE); + return NULL; + } + return memcpy(ret, data, siz); +} + +size_t BUF_strlcpy(char *dst, const char *src, size_t size) +{ + size_t l = 0; + for (; size > 1 && *src; size--) { + *dst++ = *src++; + l++; + } + if (size) + *dst = '\0'; + return l + strlen(src); +} + +size_t BUF_strlcat(char *dst, const char *src, size_t size) +{ + size_t l = 0; + for (; size > 0 && *dst; size--, dst++) + l++; + return l + BUF_strlcpy(dst, src, size); +} diff --git a/libs/openssl/crypto/buffer/buffer.c b/libs/openssl/crypto/buffer/buffer.c new file mode 100644 index 00000000..eff3e081 --- /dev/null +++ b/libs/openssl/crypto/buffer/buffer.c @@ -0,0 +1,187 @@ +/* crypto/buffer/buffer.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include + +/* + * LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That + * function is applied in several functions in this file and this limit + * ensures that the result fits in an int. + */ +#define LIMIT_BEFORE_EXPANSION 0x5ffffffc + +BUF_MEM *BUF_MEM_new(void) +{ + BUF_MEM *ret; + + ret = OPENSSL_malloc(sizeof(BUF_MEM)); + if (ret == NULL) { + BUFerr(BUF_F_BUF_MEM_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->length = 0; + ret->max = 0; + ret->data = NULL; + return (ret); +} + +void BUF_MEM_free(BUF_MEM *a) +{ + if (a == NULL) + return; + + if (a->data != NULL) { + OPENSSL_cleanse(a->data, a->max); + OPENSSL_free(a->data); + } + OPENSSL_free(a); +} + +int BUF_MEM_grow(BUF_MEM *str, size_t len) +{ + char *ret; + size_t n; + + if (str->length >= len) { + str->length = len; + return (len); + } + if (str->max >= len) { + memset(&str->data[str->length], 0, len - str->length); + str->length = len; + return (len); + } + /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ + if (len > LIMIT_BEFORE_EXPANSION) { + BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE); + return 0; + } + n = (len + 3) / 3 * 4; + if (str->data == NULL) + ret = OPENSSL_malloc(n); + else + ret = OPENSSL_realloc(str->data, n); + if (ret == NULL) { + BUFerr(BUF_F_BUF_MEM_GROW, ERR_R_MALLOC_FAILURE); + len = 0; + } else { + str->data = ret; + str->max = n; + memset(&str->data[str->length], 0, len - str->length); + str->length = len; + } + return (len); +} + +int BUF_MEM_grow_clean(BUF_MEM *str, size_t len) +{ + char *ret; + size_t n; + + if (str->length >= len) { + memset(&str->data[len], 0, str->length - len); + str->length = len; + return (len); + } + if (str->max >= len) { + memset(&str->data[str->length], 0, len - str->length); + str->length = len; + return (len); + } + /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ + if (len > LIMIT_BEFORE_EXPANSION) { + BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE); + return 0; + } + n = (len + 3) / 3 * 4; + if (str->data == NULL) + ret = OPENSSL_malloc(n); + else + ret = OPENSSL_realloc_clean(str->data, str->max, n); + if (ret == NULL) { + BUFerr(BUF_F_BUF_MEM_GROW_CLEAN, ERR_R_MALLOC_FAILURE); + len = 0; + } else { + str->data = ret; + str->max = n; + memset(&str->data[str->length], 0, len - str->length); + str->length = len; + } + return (len); +} + +void BUF_reverse(unsigned char *out, const unsigned char *in, size_t size) +{ + size_t i; + if (in) { + out += size - 1; + for (i = 0; i < size; i++) + *out-- = *in++; + } else { + unsigned char *q; + char c; + q = out + size - 1; + for (i = 0; i < size / 2; i++) { + c = *q; + *q-- = *out; + *out++ = c; + } + } +} diff --git a/libs/openssl/crypto/buffer/buffer.h b/libs/openssl/crypto/buffer/buffer.h new file mode 100644 index 00000000..89183adb --- /dev/null +++ b/libs/openssl/crypto/buffer/buffer.h @@ -0,0 +1,124 @@ +/* crypto/buffer/buffer.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_BUFFER_H +# define HEADER_BUFFER_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +# if !defined(NO_SYS_TYPES_H) +# include +# endif + +/* Already declared in ossl_typ.h */ +/* typedef struct buf_mem_st BUF_MEM; */ + +struct buf_mem_st { + size_t length; /* current number of bytes */ + char *data; + size_t max; /* size of buffer */ +}; + +BUF_MEM *BUF_MEM_new(void); +void BUF_MEM_free(BUF_MEM *a); +int BUF_MEM_grow(BUF_MEM *str, size_t len); +int BUF_MEM_grow_clean(BUF_MEM *str, size_t len); +char *BUF_strdup(const char *str); + +/* + * Like strndup, but in addition, explicitly guarantees to never read past the + * first |siz| bytes of |str|. + */ +char *BUF_strndup(const char *str, size_t siz); + +void *BUF_memdup(const void *data, size_t siz); +void BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz); + +/* safe string functions */ +size_t BUF_strlcpy(char *dst, const char *src, size_t siz); +size_t BUF_strlcat(char *dst, const char *src, size_t siz); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_BUF_strings(void); + +/* Error codes for the BUF functions. */ + +/* Function codes. */ +# define BUF_F_BUF_MEMDUP 103 +# define BUF_F_BUF_MEM_GROW 100 +# define BUF_F_BUF_MEM_GROW_CLEAN 105 +# define BUF_F_BUF_MEM_NEW 101 +# define BUF_F_BUF_STRDUP 102 +# define BUF_F_BUF_STRNDUP 104 + +/* Reason codes. */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/camellia/asm/cmll-x86.pl b/libs/openssl/crypto/camellia/asm/cmll-x86.pl new file mode 100644 index 00000000..c314d623 --- /dev/null +++ b/libs/openssl/crypto/camellia/asm/cmll-x86.pl @@ -0,0 +1,1138 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Copyright (c) 2008 Andy Polyakov +# +# This module may be used under the terms of either the GNU General +# Public License version 2 or later, the GNU Lesser General Public +# License version 2.1 or later, the Mozilla Public License version +# 1.1 or the BSD License. The exact terms of either license are +# distributed along with this module. For further details see +# http://www.openssl.org/~appro/camellia/. +# ==================================================================== + +# Performance in cycles per processed byte (less is better) in +# 'openssl speed ...' benchmark: +# +# AMD K8 Core2 PIII P4 +# -evp camellia-128-ecb 21.5 22.8 27.0 28.9 +# + over gcc 3.4.6 +90/11% +70/10% +53/4% +160/64% +# + over icc 8.0 +48/19% +21/15% +21/17% +55/37% +# +# camellia-128-cbc 17.3 21.1 23.9 25.9 +# +# 128-bit key setup 196 280 256 240 cycles/key +# + over gcc 3.4.6 +30/0% +17/11% +11/0% +63/40% +# + over icc 8.0 +18/3% +10/0% +10/3% +21/10% +# +# Pairs of numbers in "+" rows represent performance improvement over +# compiler generated position-independent code, PIC, and non-PIC +# respectively. PIC results are of greater relevance, as this module +# is position-independent, i.e. suitable for a shared library or PIE. +# Position independence "costs" one register, which is why compilers +# are so close with non-PIC results, they have an extra register to +# spare. CBC results are better than ECB ones thanks to "zero-copy" +# private _x86_* interface, and are ~30-40% better than with compiler +# generated cmll_cbc.o, and reach ~80-90% of x86_64 performance on +# same CPU (where applicable). + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +$OPENSSL=1; + +&asm_init($ARGV[0],"cmll-586.pl",$ARGV[$#ARGV] eq "386"); + +@T=("eax","ebx","ecx","edx"); +$idx="esi"; +$key="edi"; +$Tbl="ebp"; + +# stack frame layout in _x86_Camellia_* routines, frame is allocated +# by caller +$__ra=&DWP(0,"esp"); # return address +$__s0=&DWP(4,"esp"); # s0 backing store +$__s1=&DWP(8,"esp"); # s1 backing store +$__s2=&DWP(12,"esp"); # s2 backing store +$__s3=&DWP(16,"esp"); # s3 backing store +$__end=&DWP(20,"esp"); # pointer to end/start of key schedule + +# stack frame layout in Camellia_[en|crypt] routines, which differs from +# above by 4 and overlaps by pointer to end/start of key schedule +$_end=&DWP(16,"esp"); +$_esp=&DWP(20,"esp"); + +# const unsigned int Camellia_SBOX[4][256]; +# Well, sort of... Camellia_SBOX[0][] is interleaved with [1][], +# and [2][] - with [3][]. This is done to optimize code size. +$SBOX1_1110=0; # Camellia_SBOX[0] +$SBOX4_4404=4; # Camellia_SBOX[1] +$SBOX2_0222=2048; # Camellia_SBOX[2] +$SBOX3_3033=2052; # Camellia_SBOX[3] +&static_label("Camellia_SIGMA"); +&static_label("Camellia_SBOX"); + +sub Camellia_Feistel { +my $i=@_[0]; +my $seed=defined(@_[1])?@_[1]:0; +my $scale=$seed<0?-8:8; +my $frame=defined(@_[2])?@_[2]:0; +my $j=($i&1)*2; +my $t0=@T[($j)%4],$t1=@T[($j+1)%4],$t2=@T[($j+2)%4],$t3=@T[($j+3)%4]; + + &xor ($t0,$idx); # t0^=key[0] + &xor ($t1,&DWP($seed+$i*$scale+4,$key)); # t1^=key[1] + &movz ($idx,&HB($t0)); # (t0>>8)&0xff + &mov ($t3,&DWP($SBOX3_3033,$Tbl,$idx,8)); # t3=SBOX3_3033[0] + &movz ($idx,&LB($t0)); # (t0>>0)&0xff + &xor ($t3,&DWP($SBOX4_4404,$Tbl,$idx,8)); # t3^=SBOX4_4404[0] + &shr ($t0,16); + &movz ($idx,&LB($t1)); # (t1>>0)&0xff + &mov ($t2,&DWP($SBOX1_1110,$Tbl,$idx,8)); # t2=SBOX1_1110[1] + &movz ($idx,&HB($t0)); # (t0>>24)&0xff + &xor ($t3,&DWP($SBOX1_1110,$Tbl,$idx,8)); # t3^=SBOX1_1110[0] + &movz ($idx,&HB($t1)); # (t1>>8)&0xff + &xor ($t2,&DWP($SBOX4_4404,$Tbl,$idx,8)); # t2^=SBOX4_4404[1] + &shr ($t1,16); + &movz ($t0,&LB($t0)); # (t0>>16)&0xff + &xor ($t3,&DWP($SBOX2_0222,$Tbl,$t0,8)); # t3^=SBOX2_0222[0] + &movz ($idx,&HB($t1)); # (t1>>24)&0xff + &mov ($t0,&DWP($frame+4*(($j+3)%4),"esp")); # prefetch "s3" + &xor ($t2,$t3); # t2^=t3 + &rotr ($t3,8); # t3=RightRotate(t3,8) + &xor ($t2,&DWP($SBOX2_0222,$Tbl,$idx,8)); # t2^=SBOX2_0222[1] + &movz ($idx,&LB($t1)); # (t1>>16)&0xff + &mov ($t1,&DWP($frame+4*(($j+2)%4),"esp")); # prefetch "s2" + &xor ($t3,$t0); # t3^=s3 + &xor ($t2,&DWP($SBOX3_3033,$Tbl,$idx,8)); # t2^=SBOX3_3033[1] + &mov ($idx,&DWP($seed+($i+1)*$scale,$key)); # prefetch key[i+1] + &xor ($t3,$t2); # t3^=t2 + &mov (&DWP($frame+4*(($j+3)%4),"esp"),$t3); # s3=t3 + &xor ($t2,$t1); # t2^=s2 + &mov (&DWP($frame+4*(($j+2)%4),"esp"),$t2); # s2=t2 +} + +# void Camellia_EncryptBlock_Rounds( +# int grandRounds, +# const Byte plaintext[], +# const KEY_TABLE_TYPE keyTable, +# Byte ciphertext[]) +&function_begin("Camellia_EncryptBlock_Rounds"); + &mov ("eax",&wparam(0)); # load grandRounds + &mov ($idx,&wparam(1)); # load plaintext pointer + &mov ($key,&wparam(2)); # load key schedule pointer + + &mov ("ebx","esp"); + &sub ("esp",7*4); # place for s[0-3],keyEnd,esp and ra + &and ("esp",-64); + + # place stack frame just "above mod 1024" the key schedule + # this ensures that cache associativity of 2 suffices + &lea ("ecx",&DWP(-64-63,$key)); + &sub ("ecx","esp"); + &neg ("ecx"); + &and ("ecx",0x3C0); # modulo 1024, but aligned to cache-line + &sub ("esp","ecx"); + &add ("esp",4); # 4 is reserved for callee's return address + + &shl ("eax",6); + &lea ("eax",&DWP(0,$key,"eax")); + &mov ($_esp,"ebx"); # save %esp + &mov ($_end,"eax"); # save keyEnd + + &call (&label("pic_point")); + &set_label("pic_point"); + &blindpop($Tbl); + &lea ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl)); + + &mov (@T[0],&DWP(0,$idx)); # load plaintext + &mov (@T[1],&DWP(4,$idx)); + &mov (@T[2],&DWP(8,$idx)); + &bswap (@T[0]); + &mov (@T[3],&DWP(12,$idx)); + &bswap (@T[1]); + &bswap (@T[2]); + &bswap (@T[3]); + + &call ("_x86_Camellia_encrypt"); + + &mov ("esp",$_esp); + &bswap (@T[0]); + &mov ($idx,&wparam(3)); # load ciphertext pointer + &bswap (@T[1]); + &bswap (@T[2]); + &bswap (@T[3]); + &mov (&DWP(0,$idx),@T[0]); # write ciphertext + &mov (&DWP(4,$idx),@T[1]); + &mov (&DWP(8,$idx),@T[2]); + &mov (&DWP(12,$idx),@T[3]); +&function_end("Camellia_EncryptBlock_Rounds"); +# V1.x API +&function_begin_B("Camellia_EncryptBlock"); + &mov ("eax",128); + &sub ("eax",&wparam(0)); # load keyBitLength + &mov ("eax",3); + &adc ("eax",0); # keyBitLength==128?3:4 + &mov (&wparam(0),"eax"); + &jmp (&label("Camellia_EncryptBlock_Rounds")); +&function_end_B("Camellia_EncryptBlock"); + +if ($OPENSSL) { +# void Camellia_encrypt( +# const unsigned char *in, +# unsigned char *out, +# const CAMELLIA_KEY *key) +&function_begin("Camellia_encrypt"); + &mov ($idx,&wparam(0)); # load plaintext pointer + &mov ($key,&wparam(2)); # load key schedule pointer + + &mov ("ebx","esp"); + &sub ("esp",7*4); # place for s[0-3],keyEnd,esp and ra + &and ("esp",-64); + &mov ("eax",&DWP(272,$key)); # load grandRounds counter + + # place stack frame just "above mod 1024" the key schedule + # this ensures that cache associativity of 2 suffices + &lea ("ecx",&DWP(-64-63,$key)); + &sub ("ecx","esp"); + &neg ("ecx"); + &and ("ecx",0x3C0); # modulo 1024, but aligned to cache-line + &sub ("esp","ecx"); + &add ("esp",4); # 4 is reserved for callee's return address + + &shl ("eax",6); + &lea ("eax",&DWP(0,$key,"eax")); + &mov ($_esp,"ebx"); # save %esp + &mov ($_end,"eax"); # save keyEnd + + &call (&label("pic_point")); + &set_label("pic_point"); + &blindpop($Tbl); + &lea ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl)); + + &mov (@T[0],&DWP(0,$idx)); # load plaintext + &mov (@T[1],&DWP(4,$idx)); + &mov (@T[2],&DWP(8,$idx)); + &bswap (@T[0]); + &mov (@T[3],&DWP(12,$idx)); + &bswap (@T[1]); + &bswap (@T[2]); + &bswap (@T[3]); + + &call ("_x86_Camellia_encrypt"); + + &mov ("esp",$_esp); + &bswap (@T[0]); + &mov ($idx,&wparam(1)); # load ciphertext pointer + &bswap (@T[1]); + &bswap (@T[2]); + &bswap (@T[3]); + &mov (&DWP(0,$idx),@T[0]); # write ciphertext + &mov (&DWP(4,$idx),@T[1]); + &mov (&DWP(8,$idx),@T[2]); + &mov (&DWP(12,$idx),@T[3]); +&function_end("Camellia_encrypt"); +} + +&function_begin_B("_x86_Camellia_encrypt"); + &xor (@T[0],&DWP(0,$key)); # ^=key[0-3] + &xor (@T[1],&DWP(4,$key)); + &xor (@T[2],&DWP(8,$key)); + &xor (@T[3],&DWP(12,$key)); + &mov ($idx,&DWP(16,$key)); # prefetch key[4] + + &mov ($__s0,@T[0]); # save s[0-3] + &mov ($__s1,@T[1]); + &mov ($__s2,@T[2]); + &mov ($__s3,@T[3]); + +&set_label("loop",16); + for ($i=0;$i<6;$i++) { Camellia_Feistel($i,16,4); } + + &add ($key,16*4); + &cmp ($key,$__end); + &je (&label("done")); + + # @T[0-1] are preloaded, $idx is preloaded with key[0] + &and ($idx,@T[0]); + &mov (@T[3],$__s3); + &rotl ($idx,1); + &mov (@T[2],@T[3]); + &xor (@T[1],$idx); + &or (@T[2],&DWP(12,$key)); + &mov ($__s1,@T[1]); # s1^=LeftRotate(s0&key[0],1); + &xor (@T[2],$__s2); + + &mov ($idx,&DWP(4,$key)); + &mov ($__s2,@T[2]); # s2^=s3|key[3]; + &or ($idx,@T[1]); + &and (@T[2],&DWP(8,$key)); + &xor (@T[0],$idx); + &rotl (@T[2],1); + &mov ($__s0,@T[0]); # s0^=s1|key[1]; + &xor (@T[3],@T[2]); + &mov ($idx,&DWP(16,$key)); # prefetch key[4] + &mov ($__s3,@T[3]); # s3^=LeftRotate(s2&key[2],1); + &jmp (&label("loop")); + +&set_label("done",8); + &mov (@T[2],@T[0]); # SwapHalf + &mov (@T[3],@T[1]); + &mov (@T[0],$__s2); + &mov (@T[1],$__s3); + &xor (@T[0],$idx); # $idx is preloaded with key[0] + &xor (@T[1],&DWP(4,$key)); + &xor (@T[2],&DWP(8,$key)); + &xor (@T[3],&DWP(12,$key)); + &ret (); +&function_end_B("_x86_Camellia_encrypt"); + +# void Camellia_DecryptBlock_Rounds( +# int grandRounds, +# const Byte ciphertext[], +# const KEY_TABLE_TYPE keyTable, +# Byte plaintext[]) +&function_begin("Camellia_DecryptBlock_Rounds"); + &mov ("eax",&wparam(0)); # load grandRounds + &mov ($idx,&wparam(1)); # load ciphertext pointer + &mov ($key,&wparam(2)); # load key schedule pointer + + &mov ("ebx","esp"); + &sub ("esp",7*4); # place for s[0-3],keyEnd,esp and ra + &and ("esp",-64); + + # place stack frame just "above mod 1024" the key schedule + # this ensures that cache associativity of 2 suffices + &lea ("ecx",&DWP(-64-63,$key)); + &sub ("ecx","esp"); + &neg ("ecx"); + &and ("ecx",0x3C0); # modulo 1024, but aligned to cache-line + &sub ("esp","ecx"); + &add ("esp",4); # 4 is reserved for callee's return address + + &shl ("eax",6); + &mov (&DWP(4*4,"esp"),$key); # save keyStart + &lea ($key,&DWP(0,$key,"eax")); + &mov (&DWP(5*4,"esp"),"ebx");# save %esp + + &call (&label("pic_point")); + &set_label("pic_point"); + &blindpop($Tbl); + &lea ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl)); + + &mov (@T[0],&DWP(0,$idx)); # load ciphertext + &mov (@T[1],&DWP(4,$idx)); + &mov (@T[2],&DWP(8,$idx)); + &bswap (@T[0]); + &mov (@T[3],&DWP(12,$idx)); + &bswap (@T[1]); + &bswap (@T[2]); + &bswap (@T[3]); + + &call ("_x86_Camellia_decrypt"); + + &mov ("esp",&DWP(5*4,"esp")); + &bswap (@T[0]); + &mov ($idx,&wparam(3)); # load plaintext pointer + &bswap (@T[1]); + &bswap (@T[2]); + &bswap (@T[3]); + &mov (&DWP(0,$idx),@T[0]); # write plaintext + &mov (&DWP(4,$idx),@T[1]); + &mov (&DWP(8,$idx),@T[2]); + &mov (&DWP(12,$idx),@T[3]); +&function_end("Camellia_DecryptBlock_Rounds"); +# V1.x API +&function_begin_B("Camellia_DecryptBlock"); + &mov ("eax",128); + &sub ("eax",&wparam(0)); # load keyBitLength + &mov ("eax",3); + &adc ("eax",0); # keyBitLength==128?3:4 + &mov (&wparam(0),"eax"); + &jmp (&label("Camellia_DecryptBlock_Rounds")); +&function_end_B("Camellia_DecryptBlock"); + +if ($OPENSSL) { +# void Camellia_decrypt( +# const unsigned char *in, +# unsigned char *out, +# const CAMELLIA_KEY *key) +&function_begin("Camellia_decrypt"); + &mov ($idx,&wparam(0)); # load ciphertext pointer + &mov ($key,&wparam(2)); # load key schedule pointer + + &mov ("ebx","esp"); + &sub ("esp",7*4); # place for s[0-3],keyEnd,esp and ra + &and ("esp",-64); + &mov ("eax",&DWP(272,$key)); # load grandRounds counter + + # place stack frame just "above mod 1024" the key schedule + # this ensures that cache associativity of 2 suffices + &lea ("ecx",&DWP(-64-63,$key)); + &sub ("ecx","esp"); + &neg ("ecx"); + &and ("ecx",0x3C0); # modulo 1024, but aligned to cache-line + &sub ("esp","ecx"); + &add ("esp",4); # 4 is reserved for callee's return address + + &shl ("eax",6); + &mov (&DWP(4*4,"esp"),$key); # save keyStart + &lea ($key,&DWP(0,$key,"eax")); + &mov (&DWP(5*4,"esp"),"ebx");# save %esp + + &call (&label("pic_point")); + &set_label("pic_point"); + &blindpop($Tbl); + &lea ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl)); + + &mov (@T[0],&DWP(0,$idx)); # load ciphertext + &mov (@T[1],&DWP(4,$idx)); + &mov (@T[2],&DWP(8,$idx)); + &bswap (@T[0]); + &mov (@T[3],&DWP(12,$idx)); + &bswap (@T[1]); + &bswap (@T[2]); + &bswap (@T[3]); + + &call ("_x86_Camellia_decrypt"); + + &mov ("esp",&DWP(5*4,"esp")); + &bswap (@T[0]); + &mov ($idx,&wparam(1)); # load plaintext pointer + &bswap (@T[1]); + &bswap (@T[2]); + &bswap (@T[3]); + &mov (&DWP(0,$idx),@T[0]); # write plaintext + &mov (&DWP(4,$idx),@T[1]); + &mov (&DWP(8,$idx),@T[2]); + &mov (&DWP(12,$idx),@T[3]); +&function_end("Camellia_decrypt"); +} + +&function_begin_B("_x86_Camellia_decrypt"); + &xor (@T[0],&DWP(0,$key)); # ^=key[0-3] + &xor (@T[1],&DWP(4,$key)); + &xor (@T[2],&DWP(8,$key)); + &xor (@T[3],&DWP(12,$key)); + &mov ($idx,&DWP(-8,$key)); # prefetch key[-2] + + &mov ($__s0,@T[0]); # save s[0-3] + &mov ($__s1,@T[1]); + &mov ($__s2,@T[2]); + &mov ($__s3,@T[3]); + +&set_label("loop",16); + for ($i=0;$i<6;$i++) { Camellia_Feistel($i,-8,4); } + + &sub ($key,16*4); + &cmp ($key,$__end); + &je (&label("done")); + + # @T[0-1] are preloaded, $idx is preloaded with key[2] + &and ($idx,@T[0]); + &mov (@T[3],$__s3); + &rotl ($idx,1); + &mov (@T[2],@T[3]); + &xor (@T[1],$idx); + &or (@T[2],&DWP(4,$key)); + &mov ($__s1,@T[1]); # s1^=LeftRotate(s0&key[0],1); + &xor (@T[2],$__s2); + + &mov ($idx,&DWP(12,$key)); + &mov ($__s2,@T[2]); # s2^=s3|key[3]; + &or ($idx,@T[1]); + &and (@T[2],&DWP(0,$key)); + &xor (@T[0],$idx); + &rotl (@T[2],1); + &mov ($__s0,@T[0]); # s0^=s1|key[1]; + &xor (@T[3],@T[2]); + &mov ($idx,&DWP(-8,$key)); # prefetch key[4] + &mov ($__s3,@T[3]); # s3^=LeftRotate(s2&key[2],1); + &jmp (&label("loop")); + +&set_label("done",8); + &mov (@T[2],@T[0]); # SwapHalf + &mov (@T[3],@T[1]); + &mov (@T[0],$__s2); + &mov (@T[1],$__s3); + &xor (@T[2],$idx); # $idx is preloaded with key[2] + &xor (@T[3],&DWP(12,$key)); + &xor (@T[0],&DWP(0,$key)); + &xor (@T[1],&DWP(4,$key)); + &ret (); +&function_end_B("_x86_Camellia_decrypt"); + +# shld is very slow on Intel P4 family. Even on AMD it limits +# instruction decode rate [because it's VectorPath] and consequently +# performance. PIII, PM and Core[2] seem to be the only ones which +# execute this code ~7% faster... +sub __rotl128 { + my ($i0,$i1,$i2,$i3,$rot,$rnd,@T)=@_; + + $rnd *= 2; + if ($rot) { + &mov ($idx,$i0); + &shld ($i0,$i1,$rot); + &shld ($i1,$i2,$rot); + &shld ($i2,$i3,$rot); + &shld ($i3,$idx,$rot); + } + &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i0 eq @T[0]); + &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i1 eq @T[0]); + &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i2 eq @T[0]); + &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i3 eq @T[0]); +} + +# ... Implementing 128-bit rotate without shld gives >3x performance +# improvement on P4, only ~7% degradation on other Intel CPUs and +# not worse performance on AMD. This is therefore preferred. +sub _rotl128 { + my ($i0,$i1,$i2,$i3,$rot,$rnd,@T)=@_; + + $rnd *= 2; + if ($rot) { + &mov ($Tbl,$i0); + &shl ($i0,$rot); + &mov ($idx,$i1); + &shr ($idx,32-$rot); + &shl ($i1,$rot); + &or ($i0,$idx); + &mov ($idx,$i2); + &shl ($i2,$rot); + &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i0 eq @T[0]); + &shr ($idx,32-$rot); + &or ($i1,$idx); + &shr ($Tbl,32-$rot); + &mov ($idx,$i3); + &shr ($idx,32-$rot); + &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i1 eq @T[0]); + &shl ($i3,$rot); + &or ($i2,$idx); + &or ($i3,$Tbl); + &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i2 eq @T[0]); + &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i3 eq @T[0]); + } else { + &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i0 eq @T[0]); + &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i1 eq @T[0]); + &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i2 eq @T[0]); + &mov (&DWP(-128+4*$rnd++,$key),shift(@T)) if ($i3 eq @T[0]); + } +} + +sub _saveround { +my ($rnd,$key,@T)=@_; +my $bias=int(@T[0])?shift(@T):0; + + &mov (&DWP($bias+$rnd*8+0,$key),@T[0]); + &mov (&DWP($bias+$rnd*8+4,$key),@T[1]) if ($#T>=1); + &mov (&DWP($bias+$rnd*8+8,$key),@T[2]) if ($#T>=2); + &mov (&DWP($bias+$rnd*8+12,$key),@T[3]) if ($#T>=3); +} + +sub _loadround { +my ($rnd,$key,@T)=@_; +my $bias=int(@T[0])?shift(@T):0; + + &mov (@T[0],&DWP($bias+$rnd*8+0,$key)); + &mov (@T[1],&DWP($bias+$rnd*8+4,$key)) if ($#T>=1); + &mov (@T[2],&DWP($bias+$rnd*8+8,$key)) if ($#T>=2); + &mov (@T[3],&DWP($bias+$rnd*8+12,$key)) if ($#T>=3); +} + +# void Camellia_Ekeygen( +# const int keyBitLength, +# const Byte *rawKey, +# KEY_TABLE_TYPE keyTable) +&function_begin("Camellia_Ekeygen"); +{ my $step=0; + + &stack_push(4); # place for s[0-3] + + &mov ($Tbl,&wparam(0)); # load arguments + &mov ($idx,&wparam(1)); + &mov ($key,&wparam(2)); + + &mov (@T[0],&DWP(0,$idx)); # load 0-127 bits + &mov (@T[1],&DWP(4,$idx)); + &mov (@T[2],&DWP(8,$idx)); + &mov (@T[3],&DWP(12,$idx)); + + &bswap (@T[0]); + &bswap (@T[1]); + &bswap (@T[2]); + &bswap (@T[3]); + + &_saveround (0,$key,@T); # KL<<<0 + + &cmp ($Tbl,128); + &je (&label("1st128")); + + &mov (@T[0],&DWP(16,$idx)); # load 128-191 bits + &mov (@T[1],&DWP(20,$idx)); + &cmp ($Tbl,192); + &je (&label("1st192")); + &mov (@T[2],&DWP(24,$idx)); # load 192-255 bits + &mov (@T[3],&DWP(28,$idx)); + &jmp (&label("1st256")); +&set_label("1st192",4); + &mov (@T[2],@T[0]); + &mov (@T[3],@T[1]); + ¬ (@T[2]); + ¬ (@T[3]); +&set_label("1st256",4); + &bswap (@T[0]); + &bswap (@T[1]); + &bswap (@T[2]); + &bswap (@T[3]); + + &_saveround (4,$key,@T); # temporary storage for KR! + + &xor (@T[0],&DWP(0*8+0,$key)); # KR^KL + &xor (@T[1],&DWP(0*8+4,$key)); + &xor (@T[2],&DWP(1*8+0,$key)); + &xor (@T[3],&DWP(1*8+4,$key)); + +&set_label("1st128",4); + &call (&label("pic_point")); + &set_label("pic_point"); + &blindpop($Tbl); + &lea ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl)); + &lea ($key,&DWP(&label("Camellia_SIGMA")."-".&label("Camellia_SBOX"),$Tbl)); + + &mov ($idx,&DWP($step*8,$key)); # prefetch SIGMA[0] + &mov (&swtmp(0),@T[0]); # save s[0-3] + &mov (&swtmp(1),@T[1]); + &mov (&swtmp(2),@T[2]); + &mov (&swtmp(3),@T[3]); + &Camellia_Feistel($step++); + &Camellia_Feistel($step++); + &mov (@T[2],&swtmp(2)); + &mov (@T[3],&swtmp(3)); + + &mov ($idx,&wparam(2)); + &xor (@T[0],&DWP(0*8+0,$idx)); # ^KL + &xor (@T[1],&DWP(0*8+4,$idx)); + &xor (@T[2],&DWP(1*8+0,$idx)); + &xor (@T[3],&DWP(1*8+4,$idx)); + + &mov ($idx,&DWP($step*8,$key)); # prefetch SIGMA[4] + &mov (&swtmp(0),@T[0]); # save s[0-3] + &mov (&swtmp(1),@T[1]); + &mov (&swtmp(2),@T[2]); + &mov (&swtmp(3),@T[3]); + &Camellia_Feistel($step++); + &Camellia_Feistel($step++); + &mov (@T[2],&swtmp(2)); + &mov (@T[3],&swtmp(3)); + + &mov ($idx,&wparam(0)); + &cmp ($idx,128); + &jne (&label("2nd256")); + + &mov ($key,&wparam(2)); + &lea ($key,&DWP(128,$key)); # size optimization + + ####### process KA + &_saveround (2,$key,-128,@T); # KA<<<0 + &_rotl128 (@T,15,6,@T); # KA<<<15 + &_rotl128 (@T,15,8,@T); # KA<<<(15+15=30) + &_rotl128 (@T,15,12,@T[0],@T[1]); # KA<<<(30+15=45) + &_rotl128 (@T,15,14,@T); # KA<<<(45+15=60) + push (@T,shift(@T)); # rotl128(@T,32); + &_rotl128 (@T,2,20,@T); # KA<<<(60+32+2=94) + &_rotl128 (@T,17,24,@T); # KA<<<(94+17=111) + + ####### process KL + &_loadround (0,$key,-128,@T); # load KL + &_rotl128 (@T,15,4,@T); # KL<<<15 + &_rotl128 (@T,30,10,@T); # KL<<<(15+30=45) + &_rotl128 (@T,15,13,@T[2],@T[3]); # KL<<<(45+15=60) + &_rotl128 (@T,17,16,@T); # KL<<<(60+17=77) + &_rotl128 (@T,17,18,@T); # KL<<<(77+17=94) + &_rotl128 (@T,17,22,@T); # KL<<<(94+17=111) + + while (@T[0] ne "eax") # restore order + { unshift (@T,pop(@T)); } + + &mov ("eax",3); # 3 grandRounds + &jmp (&label("done")); + +&set_label("2nd256",16); + &mov ($idx,&wparam(2)); + &_saveround (6,$idx,@T); # temporary storage for KA! + + &xor (@T[0],&DWP(4*8+0,$idx)); # KA^KR + &xor (@T[1],&DWP(4*8+4,$idx)); + &xor (@T[2],&DWP(5*8+0,$idx)); + &xor (@T[3],&DWP(5*8+4,$idx)); + + &mov ($idx,&DWP($step*8,$key)); # prefetch SIGMA[8] + &mov (&swtmp(0),@T[0]); # save s[0-3] + &mov (&swtmp(1),@T[1]); + &mov (&swtmp(2),@T[2]); + &mov (&swtmp(3),@T[3]); + &Camellia_Feistel($step++); + &Camellia_Feistel($step++); + &mov (@T[2],&swtmp(2)); + &mov (@T[3],&swtmp(3)); + + &mov ($key,&wparam(2)); + &lea ($key,&DWP(128,$key)); # size optimization + + ####### process KB + &_saveround (2,$key,-128,@T); # KB<<<0 + &_rotl128 (@T,30,10,@T); # KB<<<30 + &_rotl128 (@T,30,20,@T); # KB<<<(30+30=60) + push (@T,shift(@T)); # rotl128(@T,32); + &_rotl128 (@T,19,32,@T); # KB<<<(60+32+19=111) + + ####### process KR + &_loadround (4,$key,-128,@T); # load KR + &_rotl128 (@T,15,4,@T); # KR<<<15 + &_rotl128 (@T,15,8,@T); # KR<<<(15+15=30) + &_rotl128 (@T,30,18,@T); # KR<<<(30+30=60) + push (@T,shift(@T)); # rotl128(@T,32); + &_rotl128 (@T,2,26,@T); # KR<<<(60+32+2=94) + + ####### process KA + &_loadround (6,$key,-128,@T); # load KA + &_rotl128 (@T,15,6,@T); # KA<<<15 + &_rotl128 (@T,30,14,@T); # KA<<<(15+30=45) + push (@T,shift(@T)); # rotl128(@T,32); + &_rotl128 (@T,0,24,@T); # KA<<<(45+32+0=77) + &_rotl128 (@T,17,28,@T); # KA<<<(77+17=94) + + ####### process KL + &_loadround (0,$key,-128,@T); # load KL + push (@T,shift(@T)); # rotl128(@T,32); + &_rotl128 (@T,13,12,@T); # KL<<<(32+13=45) + &_rotl128 (@T,15,16,@T); # KL<<<(45+15=60) + &_rotl128 (@T,17,22,@T); # KL<<<(60+17=77) + push (@T,shift(@T)); # rotl128(@T,32); + &_rotl128 (@T,2,30,@T); # KL<<<(77+32+2=111) + + while (@T[0] ne "eax") # restore order + { unshift (@T,pop(@T)); } + + &mov ("eax",4); # 4 grandRounds +&set_label("done"); + &lea ("edx",&DWP(272-128,$key)); # end of key schedule + &stack_pop(4); +} +&function_end("Camellia_Ekeygen"); + +if ($OPENSSL) { +# int private_Camellia_set_key ( +# const unsigned char *userKey, +# int bits, +# CAMELLIA_KEY *key) +&function_begin_B("private_Camellia_set_key"); + &push ("ebx"); + &mov ("ecx",&wparam(0)); # pull arguments + &mov ("ebx",&wparam(1)); + &mov ("edx",&wparam(2)); + + &mov ("eax",-1); + &test ("ecx","ecx"); + &jz (&label("done")); # userKey==NULL? + &test ("edx","edx"); + &jz (&label("done")); # key==NULL? + + &mov ("eax",-2); + &cmp ("ebx",256); + &je (&label("arg_ok")); # bits==256? + &cmp ("ebx",192); + &je (&label("arg_ok")); # bits==192? + &cmp ("ebx",128); + &jne (&label("done")); # bits!=128? +&set_label("arg_ok",4); + + &push ("edx"); # push arguments + &push ("ecx"); + &push ("ebx"); + &call ("Camellia_Ekeygen"); + &stack_pop(3); + + # eax holds grandRounds and edx points at where to put it + &mov (&DWP(0,"edx"),"eax"); + &xor ("eax","eax"); +&set_label("done",4); + &pop ("ebx"); + &ret (); +&function_end_B("private_Camellia_set_key"); +} + +@SBOX=( +112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65, + 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189, +134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26, +166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77, +139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153, +223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215, + 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34, +254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80, +170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210, + 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148, +135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226, + 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46, +233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89, +120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250, +114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164, + 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158); + +sub S1110 { my $i=shift; $i=@SBOX[$i]; return $i<<24|$i<<16|$i<<8; } +sub S4404 { my $i=shift; $i=($i<<1|$i>>7)&0xff; $i=@SBOX[$i]; return $i<<24|$i<<16|$i; } +sub S0222 { my $i=shift; $i=@SBOX[$i]; $i=($i<<1|$i>>7)&0xff; return $i<<16|$i<<8|$i; } +sub S3033 { my $i=shift; $i=@SBOX[$i]; $i=($i>>1|$i<<7)&0xff; return $i<<24|$i<<8|$i; } + +&set_label("Camellia_SIGMA",64); +&data_word( + 0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, + 0xc6ef372f, 0xe94f82be, 0x54ff53a5, 0xf1d36f1c, + 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd, + 0, 0, 0, 0); +&set_label("Camellia_SBOX",64); +# tables are interleaved, remember? +for ($i=0;$i<256;$i++) { &data_word(&S1110($i),&S4404($i)); } +for ($i=0;$i<256;$i++) { &data_word(&S0222($i),&S3033($i)); } + +# void Camellia_cbc_encrypt (const void char *inp, unsigned char *out, +# size_t length, const CAMELLIA_KEY *key, +# unsigned char *ivp,const int enc); +{ +# stack frame layout +# -4(%esp) # return address 0(%esp) +# 0(%esp) # s0 4(%esp) +# 4(%esp) # s1 8(%esp) +# 8(%esp) # s2 12(%esp) +# 12(%esp) # s3 16(%esp) +# 16(%esp) # end of key schedule 20(%esp) +# 20(%esp) # %esp backup +my $_inp=&DWP(24,"esp"); #copy of wparam(0) +my $_out=&DWP(28,"esp"); #copy of wparam(1) +my $_len=&DWP(32,"esp"); #copy of wparam(2) +my $_key=&DWP(36,"esp"); #copy of wparam(3) +my $_ivp=&DWP(40,"esp"); #copy of wparam(4) +my $ivec=&DWP(44,"esp"); #ivec[16] +my $_tmp=&DWP(44,"esp"); #volatile variable [yes, aliases with ivec] +my ($s0,$s1,$s2,$s3) = @T; + +&function_begin("Camellia_cbc_encrypt"); + &mov ($s2 eq "ecx"? $s2 : "",&wparam(2)); # load len + &cmp ($s2,0); + &je (&label("enc_out")); + + &pushf (); + &cld (); + + &mov ($s0,&wparam(0)); # load inp + &mov ($s1,&wparam(1)); # load out + #&mov ($s2,&wparam(2)); # load len + &mov ($s3,&wparam(3)); # load key + &mov ($Tbl,&wparam(4)); # load ivp + + # allocate aligned stack frame... + &lea ($idx,&DWP(-64,"esp")); + &and ($idx,-64); + + # place stack frame just "above mod 1024" the key schedule + # this ensures that cache associativity of 2 suffices + &lea ($key,&DWP(-64-63,$s3)); + &sub ($key,$idx); + &neg ($key); + &and ($key,0x3C0); # modulo 1024, but aligned to cache-line + &sub ($idx,$key); + + &mov ($key,&wparam(5)); # load enc + + &exch ("esp",$idx); + &add ("esp",4); # reserve for return address! + &mov ($_esp,$idx); # save %esp + + &mov ($_inp,$s0); # save copy of inp + &mov ($_out,$s1); # save copy of out + &mov ($_len,$s2); # save copy of len + &mov ($_key,$s3); # save copy of key + &mov ($_ivp,$Tbl); # save copy of ivp + + &call (&label("pic_point")); # make it PIC! + &set_label("pic_point"); + &blindpop($Tbl); + &lea ($Tbl,&DWP(&label("Camellia_SBOX")."-".&label("pic_point"),$Tbl)); + + &mov ($idx,32); + &set_label("prefetch_sbox",4); + &mov ($s0,&DWP(0,$Tbl)); + &mov ($s1,&DWP(32,$Tbl)); + &mov ($s2,&DWP(64,$Tbl)); + &mov ($s3,&DWP(96,$Tbl)); + &lea ($Tbl,&DWP(128,$Tbl)); + &dec ($idx); + &jnz (&label("prefetch_sbox")); + &mov ($s0,$_key); + &sub ($Tbl,4096); + &mov ($idx,$_inp); + &mov ($s3,&DWP(272,$s0)); # load grandRounds + + &cmp ($key,0); + &je (&label("DECRYPT")); + + &mov ($s2,$_len); + &mov ($key,$_ivp); + &shl ($s3,6); + &lea ($s3,&DWP(0,$s0,$s3)); + &mov ($_end,$s3); + + &test ($s2,0xFFFFFFF0); + &jz (&label("enc_tail")); # short input... + + &mov ($s0,&DWP(0,$key)); # load iv + &mov ($s1,&DWP(4,$key)); + + &set_label("enc_loop",4); + &mov ($s2,&DWP(8,$key)); + &mov ($s3,&DWP(12,$key)); + + &xor ($s0,&DWP(0,$idx)); # xor input data + &xor ($s1,&DWP(4,$idx)); + &xor ($s2,&DWP(8,$idx)); + &bswap ($s0); + &xor ($s3,&DWP(12,$idx)); + &bswap ($s1); + &mov ($key,$_key); # load key + &bswap ($s2); + &bswap ($s3); + + &call ("_x86_Camellia_encrypt"); + + &mov ($idx,$_inp); # load inp + &mov ($key,$_out); # load out + + &bswap ($s0); + &bswap ($s1); + &bswap ($s2); + &mov (&DWP(0,$key),$s0); # save output data + &bswap ($s3); + &mov (&DWP(4,$key),$s1); + &mov (&DWP(8,$key),$s2); + &mov (&DWP(12,$key),$s3); + + &mov ($s2,$_len); # load len + + &lea ($idx,&DWP(16,$idx)); + &mov ($_inp,$idx); # save inp + + &lea ($s3,&DWP(16,$key)); + &mov ($_out,$s3); # save out + + &sub ($s2,16); + &test ($s2,0xFFFFFFF0); + &mov ($_len,$s2); # save len + &jnz (&label("enc_loop")); + &test ($s2,15); + &jnz (&label("enc_tail")); + &mov ($idx,$_ivp); # load ivp + &mov ($s2,&DWP(8,$key)); # restore last dwords + &mov ($s3,&DWP(12,$key)); + &mov (&DWP(0,$idx),$s0); # save ivec + &mov (&DWP(4,$idx),$s1); + &mov (&DWP(8,$idx),$s2); + &mov (&DWP(12,$idx),$s3); + + &mov ("esp",$_esp); + &popf (); + &set_label("enc_out"); + &function_end_A(); + &pushf (); # kludge, never executed + + &set_label("enc_tail",4); + &mov ($s0,$key eq "edi" ? $key : ""); + &mov ($key,$_out); # load out + &push ($s0); # push ivp + &mov ($s1,16); + &sub ($s1,$s2); + &cmp ($key,$idx); # compare with inp + &je (&label("enc_in_place")); + &align (4); + &data_word(0xA4F3F689); # rep movsb # copy input + &jmp (&label("enc_skip_in_place")); + &set_label("enc_in_place"); + &lea ($key,&DWP(0,$key,$s2)); + &set_label("enc_skip_in_place"); + &mov ($s2,$s1); + &xor ($s0,$s0); + &align (4); + &data_word(0xAAF3F689); # rep stosb # zero tail + &pop ($key); # pop ivp + + &mov ($idx,$_out); # output as input + &mov ($s0,&DWP(0,$key)); + &mov ($s1,&DWP(4,$key)); + &mov ($_len,16); # len=16 + &jmp (&label("enc_loop")); # one more spin... + +#----------------------------- DECRYPT -----------------------------# +&set_label("DECRYPT",16); + &shl ($s3,6); + &lea ($s3,&DWP(0,$s0,$s3)); + &mov ($_end,$s0); + &mov ($_key,$s3); + + &cmp ($idx,$_out); + &je (&label("dec_in_place")); # in-place processing... + + &mov ($key,$_ivp); # load ivp + &mov ($_tmp,$key); + + &set_label("dec_loop",4); + &mov ($s0,&DWP(0,$idx)); # read input + &mov ($s1,&DWP(4,$idx)); + &mov ($s2,&DWP(8,$idx)); + &bswap ($s0); + &mov ($s3,&DWP(12,$idx)); + &bswap ($s1); + &mov ($key,$_key); # load key + &bswap ($s2); + &bswap ($s3); + + &call ("_x86_Camellia_decrypt"); + + &mov ($key,$_tmp); # load ivp + &mov ($idx,$_len); # load len + + &bswap ($s0); + &bswap ($s1); + &bswap ($s2); + &xor ($s0,&DWP(0,$key)); # xor iv + &bswap ($s3); + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + + &sub ($idx,16); + &jc (&label("dec_partial")); + &mov ($_len,$idx); # save len + &mov ($idx,$_inp); # load inp + &mov ($key,$_out); # load out + + &mov (&DWP(0,$key),$s0); # write output + &mov (&DWP(4,$key),$s1); + &mov (&DWP(8,$key),$s2); + &mov (&DWP(12,$key),$s3); + + &mov ($_tmp,$idx); # save ivp + &lea ($idx,&DWP(16,$idx)); + &mov ($_inp,$idx); # save inp + + &lea ($key,&DWP(16,$key)); + &mov ($_out,$key); # save out + + &jnz (&label("dec_loop")); + &mov ($key,$_tmp); # load temp ivp + &set_label("dec_end"); + &mov ($idx,$_ivp); # load user ivp + &mov ($s0,&DWP(0,$key)); # load iv + &mov ($s1,&DWP(4,$key)); + &mov ($s2,&DWP(8,$key)); + &mov ($s3,&DWP(12,$key)); + &mov (&DWP(0,$idx),$s0); # copy back to user + &mov (&DWP(4,$idx),$s1); + &mov (&DWP(8,$idx),$s2); + &mov (&DWP(12,$idx),$s3); + &jmp (&label("dec_out")); + + &set_label("dec_partial",4); + &lea ($key,$ivec); + &mov (&DWP(0,$key),$s0); # dump output to stack + &mov (&DWP(4,$key),$s1); + &mov (&DWP(8,$key),$s2); + &mov (&DWP(12,$key),$s3); + &lea ($s2 eq "ecx" ? $s2 : "",&DWP(16,$idx)); + &mov ($idx eq "esi" ? $idx : "",$key); + &mov ($key eq "edi" ? $key : "",$_out); # load out + &data_word(0xA4F3F689); # rep movsb # copy output + &mov ($key,$_inp); # use inp as temp ivp + &jmp (&label("dec_end")); + + &set_label("dec_in_place",4); + &set_label("dec_in_place_loop"); + &lea ($key,$ivec); + &mov ($s0,&DWP(0,$idx)); # read input + &mov ($s1,&DWP(4,$idx)); + &mov ($s2,&DWP(8,$idx)); + &mov ($s3,&DWP(12,$idx)); + + &mov (&DWP(0,$key),$s0); # copy to temp + &mov (&DWP(4,$key),$s1); + &mov (&DWP(8,$key),$s2); + &bswap ($s0); + &mov (&DWP(12,$key),$s3); + &bswap ($s1); + &mov ($key,$_key); # load key + &bswap ($s2); + &bswap ($s3); + + &call ("_x86_Camellia_decrypt"); + + &mov ($key,$_ivp); # load ivp + &mov ($idx,$_out); # load out + + &bswap ($s0); + &bswap ($s1); + &bswap ($s2); + &xor ($s0,&DWP(0,$key)); # xor iv + &bswap ($s3); + &xor ($s1,&DWP(4,$key)); + &xor ($s2,&DWP(8,$key)); + &xor ($s3,&DWP(12,$key)); + + &mov (&DWP(0,$idx),$s0); # write output + &mov (&DWP(4,$idx),$s1); + &mov (&DWP(8,$idx),$s2); + &mov (&DWP(12,$idx),$s3); + + &lea ($idx,&DWP(16,$idx)); + &mov ($_out,$idx); # save out + + &lea ($idx,$ivec); + &mov ($s0,&DWP(0,$idx)); # read temp + &mov ($s1,&DWP(4,$idx)); + &mov ($s2,&DWP(8,$idx)); + &mov ($s3,&DWP(12,$idx)); + + &mov (&DWP(0,$key),$s0); # copy iv + &mov (&DWP(4,$key),$s1); + &mov (&DWP(8,$key),$s2); + &mov (&DWP(12,$key),$s3); + + &mov ($idx,$_inp); # load inp + + &lea ($idx,&DWP(16,$idx)); + &mov ($_inp,$idx); # save inp + + &mov ($s2,$_len); # load len + &sub ($s2,16); + &jc (&label("dec_in_place_partial")); + &mov ($_len,$s2); # save len + &jnz (&label("dec_in_place_loop")); + &jmp (&label("dec_out")); + + &set_label("dec_in_place_partial",4); + # one can argue if this is actually required... + &mov ($key eq "edi" ? $key : "",$_out); + &lea ($idx eq "esi" ? $idx : "",$ivec); + &lea ($key,&DWP(0,$key,$s2)); + &lea ($idx,&DWP(16,$idx,$s2)); + &neg ($s2 eq "ecx" ? $s2 : ""); + &data_word(0xA4F3F689); # rep movsb # restore tail + + &set_label("dec_out",4); + &mov ("esp",$_esp); + &popf (); +&function_end("Camellia_cbc_encrypt"); +} + +&asciz("Camellia for x86 by "); + +&asm_finish(); diff --git a/libs/openssl/crypto/camellia/asm/cmll-x86_64.pl b/libs/openssl/crypto/camellia/asm/cmll-x86_64.pl new file mode 100644 index 00000000..9f4b82fa --- /dev/null +++ b/libs/openssl/crypto/camellia/asm/cmll-x86_64.pl @@ -0,0 +1,1081 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Copyright (c) 2008 Andy Polyakov +# +# This module may be used under the terms of either the GNU General +# Public License version 2 or later, the GNU Lesser General Public +# License version 2.1 or later, the Mozilla Public License version +# 1.1 or the BSD License. The exact terms of either license are +# distributed along with this module. For further details see +# http://www.openssl.org/~appro/camellia/. +# ==================================================================== + +# Performance in cycles per processed byte (less is better) in +# 'openssl speed ...' benchmark: +# +# AMD64 Core2 EM64T +# -evp camellia-128-ecb 16.7 21.0 22.7 +# + over gcc 3.4.6 +25% +5% 0% +# +# camellia-128-cbc 15.7 20.4 21.1 +# +# 128-bit key setup 128 216 205 cycles/key +# + over gcc 3.4.6 +54% +39% +15% +# +# Numbers in "+" rows represent performance improvement over compiler +# generated code. Key setup timings are impressive on AMD and Core2 +# thanks to 64-bit operations being covertly deployed. Improvement on +# EM64T, pre-Core2 Intel x86_64 CPU, is not as impressive, because it +# apparently emulates some of 64-bit operations in [32-bit] microcode. + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +sub hi() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1h/; $r; } +sub lo() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/; + $r =~ s/%[er]([sd]i)/%\1l/; + $r =~ s/%(r[0-9]+)[d]?/%\1b/; $r; } + +$t0="%eax";$t1="%ebx";$t2="%ecx";$t3="%edx"; +@S=("%r8d","%r9d","%r10d","%r11d"); +$i0="%esi"; +$i1="%edi"; +$Tbl="%rbp"; # size optimization +$inp="%r12"; +$out="%r13"; +$key="%r14"; +$keyend="%r15"; +$arg0d=$win64?"%ecx":"%edi"; + +# const unsigned int Camellia_SBOX[4][256]; +# Well, sort of... Camellia_SBOX[0][] is interleaved with [1][], +# and [2][] - with [3][]. This is done to minimize code size. +$SBOX1_1110=0; # Camellia_SBOX[0] +$SBOX4_4404=4; # Camellia_SBOX[1] +$SBOX2_0222=2048; # Camellia_SBOX[2] +$SBOX3_3033=2052; # Camellia_SBOX[3] + +sub Camellia_Feistel { +my $i=@_[0]; +my $seed=defined(@_[1])?@_[1]:0; +my $scale=$seed<0?-8:8; +my $j=($i&1)*2; +my $s0=@S[($j)%4],$s1=@S[($j+1)%4],$s2=@S[($j+2)%4],$s3=@S[($j+3)%4]; + +$code.=<<___; + xor $s0,$t0 # t0^=key[0] + xor $s1,$t1 # t1^=key[1] + movz `&hi("$t0")`,$i0 # (t0>>8)&0xff + movz `&lo("$t1")`,$i1 # (t1>>0)&0xff + mov $SBOX3_3033($Tbl,$i0,8),$t3 # t3=SBOX3_3033[0] + mov $SBOX1_1110($Tbl,$i1,8),$t2 # t2=SBOX1_1110[1] + movz `&lo("$t0")`,$i0 # (t0>>0)&0xff + shr \$16,$t0 + movz `&hi("$t1")`,$i1 # (t1>>8)&0xff + xor $SBOX4_4404($Tbl,$i0,8),$t3 # t3^=SBOX4_4404[0] + shr \$16,$t1 + xor $SBOX4_4404($Tbl,$i1,8),$t2 # t2^=SBOX4_4404[1] + movz `&hi("$t0")`,$i0 # (t0>>24)&0xff + movz `&lo("$t1")`,$i1 # (t1>>16)&0xff + xor $SBOX1_1110($Tbl,$i0,8),$t3 # t3^=SBOX1_1110[0] + xor $SBOX3_3033($Tbl,$i1,8),$t2 # t2^=SBOX3_3033[1] + movz `&lo("$t0")`,$i0 # (t0>>16)&0xff + movz `&hi("$t1")`,$i1 # (t1>>24)&0xff + xor $SBOX2_0222($Tbl,$i0,8),$t3 # t3^=SBOX2_0222[0] + xor $SBOX2_0222($Tbl,$i1,8),$t2 # t2^=SBOX2_0222[1] + mov `$seed+($i+1)*$scale`($key),$t1 # prefetch key[i+1] + mov `$seed+($i+1)*$scale+4`($key),$t0 + xor $t3,$t2 # t2^=t3 + ror \$8,$t3 # t3=RightRotate(t3,8) + xor $t2,$s2 + xor $t2,$s3 + xor $t3,$s3 +___ +} + +# void Camellia_EncryptBlock_Rounds( +# int grandRounds, +# const Byte plaintext[], +# const KEY_TABLE_TYPE keyTable, +# Byte ciphertext[]) +$code=<<___; +.text + +# V1.x API +.globl Camellia_EncryptBlock +.type Camellia_EncryptBlock,\@abi-omnipotent +.align 16 +Camellia_EncryptBlock: + movl \$128,%eax + subl $arg0d,%eax + movl \$3,$arg0d + adcl \$0,$arg0d # keyBitLength==128?3:4 + jmp .Lenc_rounds +.size Camellia_EncryptBlock,.-Camellia_EncryptBlock +# V2 +.globl Camellia_EncryptBlock_Rounds +.type Camellia_EncryptBlock_Rounds,\@function,4 +.align 16 +.Lenc_rounds: +Camellia_EncryptBlock_Rounds: + push %rbx + push %rbp + push %r13 + push %r14 + push %r15 +.Lenc_prologue: + + #mov %rsi,$inp # put away arguments + mov %rcx,$out + mov %rdx,$key + + shl \$6,%edi # process grandRounds + lea .LCamellia_SBOX(%rip),$Tbl + lea ($key,%rdi),$keyend + + mov 0(%rsi),@S[0] # load plaintext + mov 4(%rsi),@S[1] + mov 8(%rsi),@S[2] + bswap @S[0] + mov 12(%rsi),@S[3] + bswap @S[1] + bswap @S[2] + bswap @S[3] + + call _x86_64_Camellia_encrypt + + bswap @S[0] + bswap @S[1] + bswap @S[2] + mov @S[0],0($out) + bswap @S[3] + mov @S[1],4($out) + mov @S[2],8($out) + mov @S[3],12($out) + + mov 0(%rsp),%r15 + mov 8(%rsp),%r14 + mov 16(%rsp),%r13 + mov 24(%rsp),%rbp + mov 32(%rsp),%rbx + lea 40(%rsp),%rsp +.Lenc_epilogue: + ret +.size Camellia_EncryptBlock_Rounds,.-Camellia_EncryptBlock_Rounds + +.type _x86_64_Camellia_encrypt,\@abi-omnipotent +.align 16 +_x86_64_Camellia_encrypt: + xor 0($key),@S[1] + xor 4($key),@S[0] # ^=key[0-3] + xor 8($key),@S[3] + xor 12($key),@S[2] +.align 16 +.Leloop: + mov 16($key),$t1 # prefetch key[4-5] + mov 20($key),$t0 + +___ + for ($i=0;$i<6;$i++) { Camellia_Feistel($i,16); } +$code.=<<___; + lea 16*4($key),$key + cmp $keyend,$key + mov 8($key),$t3 # prefetch key[2-3] + mov 12($key),$t2 + je .Ledone + + and @S[0],$t0 + or @S[3],$t3 + rol \$1,$t0 + xor $t3,@S[2] # s2^=s3|key[3]; + xor $t0,@S[1] # s1^=LeftRotate(s0&key[0],1); + and @S[2],$t2 + or @S[1],$t1 + rol \$1,$t2 + xor $t1,@S[0] # s0^=s1|key[1]; + xor $t2,@S[3] # s3^=LeftRotate(s2&key[2],1); + jmp .Leloop + +.align 16 +.Ledone: + xor @S[2],$t0 # SwapHalf + xor @S[3],$t1 + xor @S[0],$t2 + xor @S[1],$t3 + + mov $t0,@S[0] + mov $t1,@S[1] + mov $t2,@S[2] + mov $t3,@S[3] + + .byte 0xf3,0xc3 # rep ret +.size _x86_64_Camellia_encrypt,.-_x86_64_Camellia_encrypt + +# V1.x API +.globl Camellia_DecryptBlock +.type Camellia_DecryptBlock,\@abi-omnipotent +.align 16 +Camellia_DecryptBlock: + movl \$128,%eax + subl $arg0d,%eax + movl \$3,$arg0d + adcl \$0,$arg0d # keyBitLength==128?3:4 + jmp .Ldec_rounds +.size Camellia_DecryptBlock,.-Camellia_DecryptBlock +# V2 +.globl Camellia_DecryptBlock_Rounds +.type Camellia_DecryptBlock_Rounds,\@function,4 +.align 16 +.Ldec_rounds: +Camellia_DecryptBlock_Rounds: + push %rbx + push %rbp + push %r13 + push %r14 + push %r15 +.Ldec_prologue: + + #mov %rsi,$inp # put away arguments + mov %rcx,$out + mov %rdx,$keyend + + shl \$6,%edi # process grandRounds + lea .LCamellia_SBOX(%rip),$Tbl + lea ($keyend,%rdi),$key + + mov 0(%rsi),@S[0] # load plaintext + mov 4(%rsi),@S[1] + mov 8(%rsi),@S[2] + bswap @S[0] + mov 12(%rsi),@S[3] + bswap @S[1] + bswap @S[2] + bswap @S[3] + + call _x86_64_Camellia_decrypt + + bswap @S[0] + bswap @S[1] + bswap @S[2] + mov @S[0],0($out) + bswap @S[3] + mov @S[1],4($out) + mov @S[2],8($out) + mov @S[3],12($out) + + mov 0(%rsp),%r15 + mov 8(%rsp),%r14 + mov 16(%rsp),%r13 + mov 24(%rsp),%rbp + mov 32(%rsp),%rbx + lea 40(%rsp),%rsp +.Ldec_epilogue: + ret +.size Camellia_DecryptBlock_Rounds,.-Camellia_DecryptBlock_Rounds + +.type _x86_64_Camellia_decrypt,\@abi-omnipotent +.align 16 +_x86_64_Camellia_decrypt: + xor 0($key),@S[1] + xor 4($key),@S[0] # ^=key[0-3] + xor 8($key),@S[3] + xor 12($key),@S[2] +.align 16 +.Ldloop: + mov -8($key),$t1 # prefetch key[4-5] + mov -4($key),$t0 + +___ + for ($i=0;$i<6;$i++) { Camellia_Feistel($i,-8); } +$code.=<<___; + lea -16*4($key),$key + cmp $keyend,$key + mov 0($key),$t3 # prefetch key[2-3] + mov 4($key),$t2 + je .Lddone + + and @S[0],$t0 + or @S[3],$t3 + rol \$1,$t0 + xor $t3,@S[2] # s2^=s3|key[3]; + xor $t0,@S[1] # s1^=LeftRotate(s0&key[0],1); + and @S[2],$t2 + or @S[1],$t1 + rol \$1,$t2 + xor $t1,@S[0] # s0^=s1|key[1]; + xor $t2,@S[3] # s3^=LeftRotate(s2&key[2],1); + + jmp .Ldloop + +.align 16 +.Lddone: + xor @S[2],$t2 + xor @S[3],$t3 + xor @S[0],$t0 + xor @S[1],$t1 + + mov $t2,@S[0] # SwapHalf + mov $t3,@S[1] + mov $t0,@S[2] + mov $t1,@S[3] + + .byte 0xf3,0xc3 # rep ret +.size _x86_64_Camellia_decrypt,.-_x86_64_Camellia_decrypt +___ + +sub _saveround { +my ($rnd,$key,@T)=@_; +my $bias=int(@T[0])?shift(@T):0; + + if ($#T==3) { + $code.=<<___; + mov @T[1],`$bias+$rnd*8+0`($key) + mov @T[0],`$bias+$rnd*8+4`($key) + mov @T[3],`$bias+$rnd*8+8`($key) + mov @T[2],`$bias+$rnd*8+12`($key) +___ + } else { + $code.=" mov @T[0],`$bias+$rnd*8+0`($key)\n"; + $code.=" mov @T[1],`$bias+$rnd*8+8`($key)\n" if ($#T>=1); + } +} + +sub _loadround { +my ($rnd,$key,@T)=@_; +my $bias=int(@T[0])?shift(@T):0; + +$code.=" mov `$bias+$rnd*8+0`($key),@T[0]\n"; +$code.=" mov `$bias+$rnd*8+8`($key),@T[1]\n" if ($#T>=1); +} + +# shld is very slow on Intel EM64T family. Even on AMD it limits +# instruction decode rate [because it's VectorPath] and consequently +# performance... +sub __rotl128 { +my ($i0,$i1,$rot)=@_; + + if ($rot) { + $code.=<<___; + mov $i0,%r11 + shld \$$rot,$i1,$i0 + shld \$$rot,%r11,$i1 +___ + } +} + +# ... Implementing 128-bit rotate without shld gives 80% better +# performance EM64T, +15% on AMD64 and only ~7% degradation on +# Core2. This is therefore preferred. +sub _rotl128 { +my ($i0,$i1,$rot)=@_; + + if ($rot) { + $code.=<<___; + mov $i0,%r11 + shl \$$rot,$i0 + mov $i1,%r9 + shr \$`64-$rot`,%r9 + shr \$`64-$rot`,%r11 + or %r9,$i0 + shl \$$rot,$i1 + or %r11,$i1 +___ + } +} + +{ my $step=0; + +$code.=<<___; +.globl Camellia_Ekeygen +.type Camellia_Ekeygen,\@function,3 +.align 16 +Camellia_Ekeygen: + push %rbx + push %rbp + push %r13 + push %r14 + push %r15 +.Lkey_prologue: + + mov %rdi,$keyend # put away arguments, keyBitLength + mov %rdx,$out # keyTable + + mov 0(%rsi),@S[0] # load 0-127 bits + mov 4(%rsi),@S[1] + mov 8(%rsi),@S[2] + mov 12(%rsi),@S[3] + + bswap @S[0] + bswap @S[1] + bswap @S[2] + bswap @S[3] +___ + &_saveround (0,$out,@S); # KL<<<0 +$code.=<<___; + cmp \$128,$keyend # check keyBitLength + je .L1st128 + + mov 16(%rsi),@S[0] # load 128-191 bits + mov 20(%rsi),@S[1] + cmp \$192,$keyend + je .L1st192 + mov 24(%rsi),@S[2] # load 192-255 bits + mov 28(%rsi),@S[3] + jmp .L1st256 +.L1st192: + mov @S[0],@S[2] + mov @S[1],@S[3] + not @S[2] + not @S[3] +.L1st256: + bswap @S[0] + bswap @S[1] + bswap @S[2] + bswap @S[3] +___ + &_saveround (4,$out,@S); # temp storage for KR! +$code.=<<___; + xor 0($out),@S[1] # KR^KL + xor 4($out),@S[0] + xor 8($out),@S[3] + xor 12($out),@S[2] + +.L1st128: + lea .LCamellia_SIGMA(%rip),$key + lea .LCamellia_SBOX(%rip),$Tbl + + mov 0($key),$t1 + mov 4($key),$t0 +___ + &Camellia_Feistel($step++); + &Camellia_Feistel($step++); +$code.=<<___; + xor 0($out),@S[1] # ^KL + xor 4($out),@S[0] + xor 8($out),@S[3] + xor 12($out),@S[2] +___ + &Camellia_Feistel($step++); + &Camellia_Feistel($step++); +$code.=<<___; + cmp \$128,$keyend + jne .L2nd256 + + lea 128($out),$out # size optimization + shl \$32,%r8 # @S[0]|| + shl \$32,%r10 # @S[2]|| + or %r9,%r8 # ||@S[1] + or %r11,%r10 # ||@S[3] +___ + &_loadround (0,$out,-128,"%rax","%rbx"); # KL + &_saveround (2,$out,-128,"%r8","%r10"); # KA<<<0 + &_rotl128 ("%rax","%rbx",15); + &_saveround (4,$out,-128,"%rax","%rbx"); # KL<<<15 + &_rotl128 ("%r8","%r10",15); + &_saveround (6,$out,-128,"%r8","%r10"); # KA<<<15 + &_rotl128 ("%r8","%r10",15); # 15+15=30 + &_saveround (8,$out,-128,"%r8","%r10"); # KA<<<30 + &_rotl128 ("%rax","%rbx",30); # 15+30=45 + &_saveround (10,$out,-128,"%rax","%rbx"); # KL<<<45 + &_rotl128 ("%r8","%r10",15); # 30+15=45 + &_saveround (12,$out,-128,"%r8"); # KA<<<45 + &_rotl128 ("%rax","%rbx",15); # 45+15=60 + &_saveround (13,$out,-128,"%rbx"); # KL<<<60 + &_rotl128 ("%r8","%r10",15); # 45+15=60 + &_saveround (14,$out,-128,"%r8","%r10"); # KA<<<60 + &_rotl128 ("%rax","%rbx",17); # 60+17=77 + &_saveround (16,$out,-128,"%rax","%rbx"); # KL<<<77 + &_rotl128 ("%rax","%rbx",17); # 77+17=94 + &_saveround (18,$out,-128,"%rax","%rbx"); # KL<<<94 + &_rotl128 ("%r8","%r10",34); # 60+34=94 + &_saveround (20,$out,-128,"%r8","%r10"); # KA<<<94 + &_rotl128 ("%rax","%rbx",17); # 94+17=111 + &_saveround (22,$out,-128,"%rax","%rbx"); # KL<<<111 + &_rotl128 ("%r8","%r10",17); # 94+17=111 + &_saveround (24,$out,-128,"%r8","%r10"); # KA<<<111 +$code.=<<___; + mov \$3,%eax + jmp .Ldone +.align 16 +.L2nd256: +___ + &_saveround (6,$out,@S); # temp storage for KA! +$code.=<<___; + xor `4*8+0`($out),@S[1] # KA^KR + xor `4*8+4`($out),@S[0] + xor `5*8+0`($out),@S[3] + xor `5*8+4`($out),@S[2] +___ + &Camellia_Feistel($step++); + &Camellia_Feistel($step++); + + &_loadround (0,$out,"%rax","%rbx"); # KL + &_loadround (4,$out,"%rcx","%rdx"); # KR + &_loadround (6,$out,"%r14","%r15"); # KA +$code.=<<___; + lea 128($out),$out # size optimization + shl \$32,%r8 # @S[0]|| + shl \$32,%r10 # @S[2]|| + or %r9,%r8 # ||@S[1] + or %r11,%r10 # ||@S[3] +___ + &_saveround (2,$out,-128,"%r8","%r10"); # KB<<<0 + &_rotl128 ("%rcx","%rdx",15); + &_saveround (4,$out,-128,"%rcx","%rdx"); # KR<<<15 + &_rotl128 ("%r14","%r15",15); + &_saveround (6,$out,-128,"%r14","%r15"); # KA<<<15 + &_rotl128 ("%rcx","%rdx",15); # 15+15=30 + &_saveround (8,$out,-128,"%rcx","%rdx"); # KR<<<30 + &_rotl128 ("%r8","%r10",30); + &_saveround (10,$out,-128,"%r8","%r10"); # KB<<<30 + &_rotl128 ("%rax","%rbx",45); + &_saveround (12,$out,-128,"%rax","%rbx"); # KL<<<45 + &_rotl128 ("%r14","%r15",30); # 15+30=45 + &_saveround (14,$out,-128,"%r14","%r15"); # KA<<<45 + &_rotl128 ("%rax","%rbx",15); # 45+15=60 + &_saveround (16,$out,-128,"%rax","%rbx"); # KL<<<60 + &_rotl128 ("%rcx","%rdx",30); # 30+30=60 + &_saveround (18,$out,-128,"%rcx","%rdx"); # KR<<<60 + &_rotl128 ("%r8","%r10",30); # 30+30=60 + &_saveround (20,$out,-128,"%r8","%r10"); # KB<<<60 + &_rotl128 ("%rax","%rbx",17); # 60+17=77 + &_saveround (22,$out,-128,"%rax","%rbx"); # KL<<<77 + &_rotl128 ("%r14","%r15",32); # 45+32=77 + &_saveround (24,$out,-128,"%r14","%r15"); # KA<<<77 + &_rotl128 ("%rcx","%rdx",34); # 60+34=94 + &_saveround (26,$out,-128,"%rcx","%rdx"); # KR<<<94 + &_rotl128 ("%r14","%r15",17); # 77+17=94 + &_saveround (28,$out,-128,"%r14","%r15"); # KA<<<77 + &_rotl128 ("%rax","%rbx",34); # 77+34=111 + &_saveround (30,$out,-128,"%rax","%rbx"); # KL<<<111 + &_rotl128 ("%r8","%r10",51); # 60+51=111 + &_saveround (32,$out,-128,"%r8","%r10"); # KB<<<111 +$code.=<<___; + mov \$4,%eax +.Ldone: + mov 0(%rsp),%r15 + mov 8(%rsp),%r14 + mov 16(%rsp),%r13 + mov 24(%rsp),%rbp + mov 32(%rsp),%rbx + lea 40(%rsp),%rsp +.Lkey_epilogue: + ret +.size Camellia_Ekeygen,.-Camellia_Ekeygen +___ +} + +@SBOX=( +112,130, 44,236,179, 39,192,229,228,133, 87, 53,234, 12,174, 65, + 35,239,107,147, 69, 25,165, 33,237, 14, 79, 78, 29,101,146,189, +134,184,175,143,124,235, 31,206, 62, 48,220, 95, 94,197, 11, 26, +166,225, 57,202,213, 71, 93, 61,217, 1, 90,214, 81, 86,108, 77, +139, 13,154,102,251,204,176, 45,116, 18, 43, 32,240,177,132,153, +223, 76,203,194, 52,126,118, 5,109,183,169, 49,209, 23, 4,215, + 20, 88, 58, 97,222, 27, 17, 28, 50, 15,156, 22, 83, 24,242, 34, +254, 68,207,178,195,181,122,145, 36, 8,232,168, 96,252,105, 80, +170,208,160,125,161,137, 98,151, 84, 91, 30,149,224,255,100,210, + 16,196, 0, 72,163,247,117,219,138, 3,230,218, 9, 63,221,148, +135, 92,131, 2,205, 74,144, 51,115,103,246,243,157,127,191,226, + 82,155,216, 38,200, 55,198, 59,129,150,111, 75, 19,190, 99, 46, +233,121,167,140,159,110,188,142, 41,245,249,182, 47,253,180, 89, +120,152, 6,106,231, 70,113,186,212, 37,171, 66,136,162,141,250, +114, 7,185, 85,248,238,172, 10, 54, 73, 42,104, 60, 56,241,164, + 64, 40,211,123,187,201, 67,193, 21,227,173,244,119,199,128,158); + +sub S1110 { my $i=shift; $i=@SBOX[$i]; $i=$i<<24|$i<<16|$i<<8; sprintf("0x%08x",$i); } +sub S4404 { my $i=shift; $i=($i<<1|$i>>7)&0xff; $i=@SBOX[$i]; $i=$i<<24|$i<<16|$i; sprintf("0x%08x",$i); } +sub S0222 { my $i=shift; $i=@SBOX[$i]; $i=($i<<1|$i>>7)&0xff; $i=$i<<16|$i<<8|$i; sprintf("0x%08x",$i); } +sub S3033 { my $i=shift; $i=@SBOX[$i]; $i=($i>>1|$i<<7)&0xff; $i=$i<<24|$i<<8|$i; sprintf("0x%08x",$i); } + +$code.=<<___; +.align 64 +.LCamellia_SIGMA: +.long 0x3bcc908b, 0xa09e667f, 0x4caa73b2, 0xb67ae858 +.long 0xe94f82be, 0xc6ef372f, 0xf1d36f1c, 0x54ff53a5 +.long 0xde682d1d, 0x10e527fa, 0xb3e6c1fd, 0xb05688c2 +.long 0, 0, 0, 0 +.LCamellia_SBOX: +___ +# tables are interleaved, remember? +sub data_word { $code.=".long\t".join(',',@_)."\n"; } +for ($i=0;$i<256;$i++) { &data_word(&S1110($i),&S4404($i)); } +for ($i=0;$i<256;$i++) { &data_word(&S0222($i),&S3033($i)); } + +# void Camellia_cbc_encrypt (const void char *inp, unsigned char *out, +# size_t length, const CAMELLIA_KEY *key, +# unsigned char *ivp,const int enc); +{ +$_key="0(%rsp)"; +$_end="8(%rsp)"; # inp+len&~15 +$_res="16(%rsp)"; # len&15 +$ivec="24(%rsp)"; +$_ivp="40(%rsp)"; +$_rsp="48(%rsp)"; + +$code.=<<___; +.globl Camellia_cbc_encrypt +.type Camellia_cbc_encrypt,\@function,6 +.align 16 +Camellia_cbc_encrypt: + cmp \$0,%rdx + je .Lcbc_abort + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 +.Lcbc_prologue: + + mov %rsp,%rbp + sub \$64,%rsp + and \$-64,%rsp + + # place stack frame just "above mod 1024" the key schedule, + # this ensures that cache associativity suffices + lea -64-63(%rcx),%r10 + sub %rsp,%r10 + neg %r10 + and \$0x3C0,%r10 + sub %r10,%rsp + #add \$8,%rsp # 8 is reserved for callee's ra + + mov %rdi,$inp # inp argument + mov %rsi,$out # out argument + mov %r8,%rbx # ivp argument + mov %rcx,$key # key argument + mov 272(%rcx),${keyend}d # grandRounds + + mov %r8,$_ivp + mov %rbp,$_rsp + +.Lcbc_body: + lea .LCamellia_SBOX(%rip),$Tbl + + mov \$32,%ecx +.align 4 +.Lcbc_prefetch_sbox: + mov 0($Tbl),%rax + mov 32($Tbl),%rsi + mov 64($Tbl),%rdi + mov 96($Tbl),%r11 + lea 128($Tbl),$Tbl + loop .Lcbc_prefetch_sbox + sub \$4096,$Tbl + shl \$6,$keyend + mov %rdx,%rcx # len argument + lea ($key,$keyend),$keyend + + cmp \$0,%r9d # enc argument + je .LCBC_DECRYPT + + and \$-16,%rdx + and \$15,%rcx # length residue + lea ($inp,%rdx),%rdx + mov $key,$_key + mov %rdx,$_end + mov %rcx,$_res + + cmp $inp,%rdx + mov 0(%rbx),@S[0] # load IV + mov 4(%rbx),@S[1] + mov 8(%rbx),@S[2] + mov 12(%rbx),@S[3] + je .Lcbc_enc_tail + jmp .Lcbc_eloop + +.align 16 +.Lcbc_eloop: + xor 0($inp),@S[0] + xor 4($inp),@S[1] + xor 8($inp),@S[2] + bswap @S[0] + xor 12($inp),@S[3] + bswap @S[1] + bswap @S[2] + bswap @S[3] + + call _x86_64_Camellia_encrypt + + mov $_key,$key # "rewind" the key + bswap @S[0] + mov $_end,%rdx + bswap @S[1] + mov $_res,%rcx + bswap @S[2] + mov @S[0],0($out) + bswap @S[3] + mov @S[1],4($out) + mov @S[2],8($out) + lea 16($inp),$inp + mov @S[3],12($out) + cmp %rdx,$inp + lea 16($out),$out + jne .Lcbc_eloop + + cmp \$0,%rcx + jne .Lcbc_enc_tail + + mov $_ivp,$out + mov @S[0],0($out) # write out IV residue + mov @S[1],4($out) + mov @S[2],8($out) + mov @S[3],12($out) + jmp .Lcbc_done + +.align 16 +.Lcbc_enc_tail: + xor %rax,%rax + mov %rax,0+$ivec + mov %rax,8+$ivec + mov %rax,$_res + +.Lcbc_enc_pushf: + pushfq + cld + mov $inp,%rsi + lea 8+$ivec,%rdi + .long 0x9066A4F3 # rep movsb + popfq +.Lcbc_enc_popf: + + lea $ivec,$inp + lea 16+$ivec,%rax + mov %rax,$_end + jmp .Lcbc_eloop # one more time + +.align 16 +.LCBC_DECRYPT: + xchg $key,$keyend + add \$15,%rdx + and \$15,%rcx # length residue + and \$-16,%rdx + mov $key,$_key + lea ($inp,%rdx),%rdx + mov %rdx,$_end + mov %rcx,$_res + + mov (%rbx),%rax # load IV + mov 8(%rbx),%rbx + jmp .Lcbc_dloop +.align 16 +.Lcbc_dloop: + mov 0($inp),@S[0] + mov 4($inp),@S[1] + mov 8($inp),@S[2] + bswap @S[0] + mov 12($inp),@S[3] + bswap @S[1] + mov %rax,0+$ivec # save IV to temporary storage + bswap @S[2] + mov %rbx,8+$ivec + bswap @S[3] + + call _x86_64_Camellia_decrypt + + mov $_key,$key # "rewind" the key + mov $_end,%rdx + mov $_res,%rcx + + bswap @S[0] + mov ($inp),%rax # load IV for next iteration + bswap @S[1] + mov 8($inp),%rbx + bswap @S[2] + xor 0+$ivec,@S[0] + bswap @S[3] + xor 4+$ivec,@S[1] + xor 8+$ivec,@S[2] + lea 16($inp),$inp + xor 12+$ivec,@S[3] + cmp %rdx,$inp + je .Lcbc_ddone + + mov @S[0],0($out) + mov @S[1],4($out) + mov @S[2],8($out) + mov @S[3],12($out) + + lea 16($out),$out + jmp .Lcbc_dloop + +.align 16 +.Lcbc_ddone: + mov $_ivp,%rdx + cmp \$0,%rcx + jne .Lcbc_dec_tail + + mov @S[0],0($out) + mov @S[1],4($out) + mov @S[2],8($out) + mov @S[3],12($out) + + mov %rax,(%rdx) # write out IV residue + mov %rbx,8(%rdx) + jmp .Lcbc_done +.align 16 +.Lcbc_dec_tail: + mov @S[0],0+$ivec + mov @S[1],4+$ivec + mov @S[2],8+$ivec + mov @S[3],12+$ivec + +.Lcbc_dec_pushf: + pushfq + cld + lea 8+$ivec,%rsi + lea ($out),%rdi + .long 0x9066A4F3 # rep movsb + popfq +.Lcbc_dec_popf: + + mov %rax,(%rdx) # write out IV residue + mov %rbx,8(%rdx) + jmp .Lcbc_done + +.align 16 +.Lcbc_done: + mov $_rsp,%rcx + mov 0(%rcx),%r15 + mov 8(%rcx),%r14 + mov 16(%rcx),%r13 + mov 24(%rcx),%r12 + mov 32(%rcx),%rbp + mov 40(%rcx),%rbx + lea 48(%rcx),%rsp +.Lcbc_abort: + ret +.size Camellia_cbc_encrypt,.-Camellia_cbc_encrypt + +.asciz "Camellia for x86_64 by " +___ +} + +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type common_se_handler,\@abi-omnipotent +.align 16 +common_se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + lea -64(%rsp),%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + mov 8($disp),%rsi # disp->ImageBase + mov 56($disp),%r11 # disp->HandlerData + + mov 0(%r11),%r10d # HandlerData[0] + lea (%rsi,%r10),%r10 # prologue label + cmp %r10,%rbx # context->RipRsp + + mov 4(%r11),%r10d # HandlerData[1] + lea (%rsi,%r10),%r10 # epilogue label + cmp %r10,%rbx # context->Rip>=epilogue label + jae .Lin_prologue + + lea 40(%rax),%rax + mov -8(%rax),%rbx + mov -16(%rax),%rbp + mov -24(%rax),%r13 + mov -32(%rax),%r14 + mov -40(%rax),%r15 + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r13,224($context) # restore context->R13 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + +.Lin_prologue: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + jmp .Lcommon_seh_exit +.size common_se_handler,.-common_se_handler + +.type cbc_se_handler,\@abi-omnipotent +.align 16 +cbc_se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + lea -64(%rsp),%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + lea .Lcbc_prologue(%rip),%r10 + cmp %r10,%rbx # context->Rip<.Lcbc_prologue + jb .Lin_cbc_prologue + + lea .Lcbc_body(%rip),%r10 + cmp %r10,%rbx # context->Rip<.Lcbc_body + jb .Lin_cbc_frame_setup + + mov 152($context),%rax # pull context->Rsp + + lea .Lcbc_abort(%rip),%r10 + cmp %r10,%rbx # context->Rip>=.Lcbc_abort + jae .Lin_cbc_prologue + + # handle pushf/popf in Camellia_cbc_encrypt + lea .Lcbc_enc_pushf(%rip),%r10 + cmp %r10,%rbx # context->Rip<=.Lcbc_enc_pushf + jbe .Lin_cbc_no_flag + lea 8(%rax),%rax + lea .Lcbc_enc_popf(%rip),%r10 + cmp %r10,%rbx # context->Rip<.Lcbc_enc_popf + jb .Lin_cbc_no_flag + lea -8(%rax),%rax + lea .Lcbc_dec_pushf(%rip),%r10 + cmp %r10,%rbx # context->Rip<=.Lcbc_dec_pushf + jbe .Lin_cbc_no_flag + lea 8(%rax),%rax + lea .Lcbc_dec_popf(%rip),%r10 + cmp %r10,%rbx # context->Rip<.Lcbc_dec_popf + jb .Lin_cbc_no_flag + lea -8(%rax),%rax + +.Lin_cbc_no_flag: + mov 48(%rax),%rax # $_rsp + lea 48(%rax),%rax + +.Lin_cbc_frame_setup: + mov -8(%rax),%rbx + mov -16(%rax),%rbp + mov -24(%rax),%r12 + mov -32(%rax),%r13 + mov -40(%rax),%r14 + mov -48(%rax),%r15 + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + +.Lin_cbc_prologue: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + +.align 4 +.Lcommon_seh_exit: + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$`1232/8`,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + lea 64(%rsp),%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size cbc_se_handler,.-cbc_se_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_Camellia_EncryptBlock_Rounds + .rva .LSEH_end_Camellia_EncryptBlock_Rounds + .rva .LSEH_info_Camellia_EncryptBlock_Rounds + + .rva .LSEH_begin_Camellia_DecryptBlock_Rounds + .rva .LSEH_end_Camellia_DecryptBlock_Rounds + .rva .LSEH_info_Camellia_DecryptBlock_Rounds + + .rva .LSEH_begin_Camellia_Ekeygen + .rva .LSEH_end_Camellia_Ekeygen + .rva .LSEH_info_Camellia_Ekeygen + + .rva .LSEH_begin_Camellia_cbc_encrypt + .rva .LSEH_end_Camellia_cbc_encrypt + .rva .LSEH_info_Camellia_cbc_encrypt + +.section .xdata +.align 8 +.LSEH_info_Camellia_EncryptBlock_Rounds: + .byte 9,0,0,0 + .rva common_se_handler + .rva .Lenc_prologue,.Lenc_epilogue # HandlerData[] +.LSEH_info_Camellia_DecryptBlock_Rounds: + .byte 9,0,0,0 + .rva common_se_handler + .rva .Ldec_prologue,.Ldec_epilogue # HandlerData[] +.LSEH_info_Camellia_Ekeygen: + .byte 9,0,0,0 + .rva common_se_handler + .rva .Lkey_prologue,.Lkey_epilogue # HandlerData[] +.LSEH_info_Camellia_cbc_encrypt: + .byte 9,0,0,0 + .rva cbc_se_handler +___ +} + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/camellia/camellia.c b/libs/openssl/crypto/camellia/camellia.c new file mode 100644 index 00000000..719fa61c --- /dev/null +++ b/libs/openssl/crypto/camellia/camellia.c @@ -0,0 +1,584 @@ +/* crypto/camellia/camellia.c */ +/* ==================================================================== + * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . + * ALL RIGHTS RESERVED. + * + * Intellectual Property information for Camellia: + * http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html + * + * News Release for Announcement of Camellia open source: + * http://www.ntt.co.jp/news/news06e/0604/060413a.html + * + * The Camellia Code included herein is developed by + * NTT (Nippon Telegraph and Telephone Corporation), and is contributed + * to the OpenSSL project. + * + * The Camellia Code is licensed pursuant to the OpenSSL open source + * license provided below. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +/* + * Algorithm Specification + * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html + */ + +/* + * This release balances code size and performance. In particular key + * schedule setup is fully unrolled, because doing so *significantly* + * reduces amount of instructions per setup round and code increase is + * justifiable. In block functions on the other hand only inner loops + * are unrolled, as full unroll gives only nominal performance boost, + * while code size grows 4 or 7 times. Also, unlike previous versions + * this one "encourages" compiler to keep intermediate variables in + * registers, which should give better "all round" results, in other + * words reasonable performance even with not so modern compilers. + */ + +#include "camellia.h" +#include "cmll_locl.h" +#include +#include + +/* 32-bit rotations */ +#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) +# define RightRotate(x, s) _lrotr(x, s) +# define LeftRotate(x, s) _lrotl(x, s) +# if _MSC_VER >= 1400 +# define SWAP(x) _byteswap_ulong(x) +# else +# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00) +# endif +# define GETU32(p) SWAP(*((u32 *)(p))) +# define PUTU32(p,v) (*((u32 *)(p)) = SWAP((v))) +# elif defined(__GNUC__) && __GNUC__>=2 +# if defined(__i386) || defined(__x86_64) +# define RightRotate(x,s) ({u32 ret; asm ("rorl %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; }) +# define LeftRotate(x,s) ({u32 ret; asm ("roll %1,%0":"=r"(ret):"I"(s),"0"(x):"cc"); ret; }) +# if defined(B_ENDIAN) /* stratus.com does it */ +# define GETU32(p) (*(u32 *)(p)) +# define PUTU32(p,v) (*(u32 *)(p)=(v)) +# else +# define GETU32(p) ({u32 r=*(const u32 *)(p); asm("bswapl %0":"=r"(r):"0"(r)); r; }) +# define PUTU32(p,v) ({u32 r=(v); asm("bswapl %0":"=r"(r):"0"(r)); *(u32 *)(p)=r; }) +# endif +# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ + defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__) +# define LeftRotate(x,s) ({u32 ret; asm ("rlwinm %0,%1,%2,0,31":"=r"(ret):"r"(x),"I"(s)); ret; }) +# define RightRotate(x,s) LeftRotate(x,(32-s)) +# elif defined(__s390x__) +# define LeftRotate(x,s) ({u32 ret; asm ("rll %0,%1,%2":"=r"(ret):"r"(x),"I"(s)); ret; }) +# define RightRotate(x,s) LeftRotate(x,(32-s)) +# define GETU32(p) (*(u32 *)(p)) +# define PUTU32(p,v) (*(u32 *)(p)=(v)) +# endif +# endif +#endif + +#if !defined(RightRotate) && !defined(LeftRotate) +# define RightRotate(x, s) ( ((x) >> (s)) + ((x) << (32 - s)) ) +# define LeftRotate(x, s) ( ((x) << (s)) + ((x) >> (32 - s)) ) +#endif + +#if !defined(GETU32) && !defined(PUTU32) +# define GETU32(p) (((u32)(p)[0] << 24) ^ ((u32)(p)[1] << 16) ^ ((u32)(p)[2] << 8) ^ ((u32)(p)[3])) +# define PUTU32(p,v) ((p)[0] = (u8)((v) >> 24), (p)[1] = (u8)((v) >> 16), (p)[2] = (u8)((v) >> 8), (p)[3] = (u8)(v)) +#endif + +/* S-box data */ +#define SBOX1_1110 Camellia_SBOX[0] +#define SBOX4_4404 Camellia_SBOX[1] +#define SBOX2_0222 Camellia_SBOX[2] +#define SBOX3_3033 Camellia_SBOX[3] +static const u32 Camellia_SBOX[][256] = { + {0x70707000, 0x82828200, 0x2c2c2c00, 0xececec00, 0xb3b3b300, 0x27272700, + 0xc0c0c000, 0xe5e5e500, 0xe4e4e400, 0x85858500, 0x57575700, 0x35353500, + 0xeaeaea00, 0x0c0c0c00, 0xaeaeae00, 0x41414100, 0x23232300, 0xefefef00, + 0x6b6b6b00, 0x93939300, 0x45454500, 0x19191900, 0xa5a5a500, 0x21212100, + 0xededed00, 0x0e0e0e00, 0x4f4f4f00, 0x4e4e4e00, 0x1d1d1d00, 0x65656500, + 0x92929200, 0xbdbdbd00, 0x86868600, 0xb8b8b800, 0xafafaf00, 0x8f8f8f00, + 0x7c7c7c00, 0xebebeb00, 0x1f1f1f00, 0xcecece00, 0x3e3e3e00, 0x30303000, + 0xdcdcdc00, 0x5f5f5f00, 0x5e5e5e00, 0xc5c5c500, 0x0b0b0b00, 0x1a1a1a00, + 0xa6a6a600, 0xe1e1e100, 0x39393900, 0xcacaca00, 0xd5d5d500, 0x47474700, + 0x5d5d5d00, 0x3d3d3d00, 0xd9d9d900, 0x01010100, 0x5a5a5a00, 0xd6d6d600, + 0x51515100, 0x56565600, 0x6c6c6c00, 0x4d4d4d00, 0x8b8b8b00, 0x0d0d0d00, + 0x9a9a9a00, 0x66666600, 0xfbfbfb00, 0xcccccc00, 0xb0b0b000, 0x2d2d2d00, + 0x74747400, 0x12121200, 0x2b2b2b00, 0x20202000, 0xf0f0f000, 0xb1b1b100, + 0x84848400, 0x99999900, 0xdfdfdf00, 0x4c4c4c00, 0xcbcbcb00, 0xc2c2c200, + 0x34343400, 0x7e7e7e00, 0x76767600, 0x05050500, 0x6d6d6d00, 0xb7b7b700, + 0xa9a9a900, 0x31313100, 0xd1d1d100, 0x17171700, 0x04040400, 0xd7d7d700, + 0x14141400, 0x58585800, 0x3a3a3a00, 0x61616100, 0xdedede00, 0x1b1b1b00, + 0x11111100, 0x1c1c1c00, 0x32323200, 0x0f0f0f00, 0x9c9c9c00, 0x16161600, + 0x53535300, 0x18181800, 0xf2f2f200, 0x22222200, 0xfefefe00, 0x44444400, + 0xcfcfcf00, 0xb2b2b200, 0xc3c3c300, 0xb5b5b500, 0x7a7a7a00, 0x91919100, + 0x24242400, 0x08080800, 0xe8e8e800, 0xa8a8a800, 0x60606000, 0xfcfcfc00, + 0x69696900, 0x50505000, 0xaaaaaa00, 0xd0d0d000, 0xa0a0a000, 0x7d7d7d00, + 0xa1a1a100, 0x89898900, 0x62626200, 0x97979700, 0x54545400, 0x5b5b5b00, + 0x1e1e1e00, 0x95959500, 0xe0e0e000, 0xffffff00, 0x64646400, 0xd2d2d200, + 0x10101000, 0xc4c4c400, 0x00000000, 0x48484800, 0xa3a3a300, 0xf7f7f700, + 0x75757500, 0xdbdbdb00, 0x8a8a8a00, 0x03030300, 0xe6e6e600, 0xdadada00, + 0x09090900, 0x3f3f3f00, 0xdddddd00, 0x94949400, 0x87878700, 0x5c5c5c00, + 0x83838300, 0x02020200, 0xcdcdcd00, 0x4a4a4a00, 0x90909000, 0x33333300, + 0x73737300, 0x67676700, 0xf6f6f600, 0xf3f3f300, 0x9d9d9d00, 0x7f7f7f00, + 0xbfbfbf00, 0xe2e2e200, 0x52525200, 0x9b9b9b00, 0xd8d8d800, 0x26262600, + 0xc8c8c800, 0x37373700, 0xc6c6c600, 0x3b3b3b00, 0x81818100, 0x96969600, + 0x6f6f6f00, 0x4b4b4b00, 0x13131300, 0xbebebe00, 0x63636300, 0x2e2e2e00, + 0xe9e9e900, 0x79797900, 0xa7a7a700, 0x8c8c8c00, 0x9f9f9f00, 0x6e6e6e00, + 0xbcbcbc00, 0x8e8e8e00, 0x29292900, 0xf5f5f500, 0xf9f9f900, 0xb6b6b600, + 0x2f2f2f00, 0xfdfdfd00, 0xb4b4b400, 0x59595900, 0x78787800, 0x98989800, + 0x06060600, 0x6a6a6a00, 0xe7e7e700, 0x46464600, 0x71717100, 0xbababa00, + 0xd4d4d400, 0x25252500, 0xababab00, 0x42424200, 0x88888800, 0xa2a2a200, + 0x8d8d8d00, 0xfafafa00, 0x72727200, 0x07070700, 0xb9b9b900, 0x55555500, + 0xf8f8f800, 0xeeeeee00, 0xacacac00, 0x0a0a0a00, 0x36363600, 0x49494900, + 0x2a2a2a00, 0x68686800, 0x3c3c3c00, 0x38383800, 0xf1f1f100, 0xa4a4a400, + 0x40404000, 0x28282800, 0xd3d3d300, 0x7b7b7b00, 0xbbbbbb00, 0xc9c9c900, + 0x43434300, 0xc1c1c100, 0x15151500, 0xe3e3e300, 0xadadad00, 0xf4f4f400, + 0x77777700, 0xc7c7c700, 0x80808000, 0x9e9e9e00}, + {0x70700070, 0x2c2c002c, 0xb3b300b3, 0xc0c000c0, 0xe4e400e4, 0x57570057, + 0xeaea00ea, 0xaeae00ae, 0x23230023, 0x6b6b006b, 0x45450045, 0xa5a500a5, + 0xeded00ed, 0x4f4f004f, 0x1d1d001d, 0x92920092, 0x86860086, 0xafaf00af, + 0x7c7c007c, 0x1f1f001f, 0x3e3e003e, 0xdcdc00dc, 0x5e5e005e, 0x0b0b000b, + 0xa6a600a6, 0x39390039, 0xd5d500d5, 0x5d5d005d, 0xd9d900d9, 0x5a5a005a, + 0x51510051, 0x6c6c006c, 0x8b8b008b, 0x9a9a009a, 0xfbfb00fb, 0xb0b000b0, + 0x74740074, 0x2b2b002b, 0xf0f000f0, 0x84840084, 0xdfdf00df, 0xcbcb00cb, + 0x34340034, 0x76760076, 0x6d6d006d, 0xa9a900a9, 0xd1d100d1, 0x04040004, + 0x14140014, 0x3a3a003a, 0xdede00de, 0x11110011, 0x32320032, 0x9c9c009c, + 0x53530053, 0xf2f200f2, 0xfefe00fe, 0xcfcf00cf, 0xc3c300c3, 0x7a7a007a, + 0x24240024, 0xe8e800e8, 0x60600060, 0x69690069, 0xaaaa00aa, 0xa0a000a0, + 0xa1a100a1, 0x62620062, 0x54540054, 0x1e1e001e, 0xe0e000e0, 0x64640064, + 0x10100010, 0x00000000, 0xa3a300a3, 0x75750075, 0x8a8a008a, 0xe6e600e6, + 0x09090009, 0xdddd00dd, 0x87870087, 0x83830083, 0xcdcd00cd, 0x90900090, + 0x73730073, 0xf6f600f6, 0x9d9d009d, 0xbfbf00bf, 0x52520052, 0xd8d800d8, + 0xc8c800c8, 0xc6c600c6, 0x81810081, 0x6f6f006f, 0x13130013, 0x63630063, + 0xe9e900e9, 0xa7a700a7, 0x9f9f009f, 0xbcbc00bc, 0x29290029, 0xf9f900f9, + 0x2f2f002f, 0xb4b400b4, 0x78780078, 0x06060006, 0xe7e700e7, 0x71710071, + 0xd4d400d4, 0xabab00ab, 0x88880088, 0x8d8d008d, 0x72720072, 0xb9b900b9, + 0xf8f800f8, 0xacac00ac, 0x36360036, 0x2a2a002a, 0x3c3c003c, 0xf1f100f1, + 0x40400040, 0xd3d300d3, 0xbbbb00bb, 0x43430043, 0x15150015, 0xadad00ad, + 0x77770077, 0x80800080, 0x82820082, 0xecec00ec, 0x27270027, 0xe5e500e5, + 0x85850085, 0x35350035, 0x0c0c000c, 0x41410041, 0xefef00ef, 0x93930093, + 0x19190019, 0x21210021, 0x0e0e000e, 0x4e4e004e, 0x65650065, 0xbdbd00bd, + 0xb8b800b8, 0x8f8f008f, 0xebeb00eb, 0xcece00ce, 0x30300030, 0x5f5f005f, + 0xc5c500c5, 0x1a1a001a, 0xe1e100e1, 0xcaca00ca, 0x47470047, 0x3d3d003d, + 0x01010001, 0xd6d600d6, 0x56560056, 0x4d4d004d, 0x0d0d000d, 0x66660066, + 0xcccc00cc, 0x2d2d002d, 0x12120012, 0x20200020, 0xb1b100b1, 0x99990099, + 0x4c4c004c, 0xc2c200c2, 0x7e7e007e, 0x05050005, 0xb7b700b7, 0x31310031, + 0x17170017, 0xd7d700d7, 0x58580058, 0x61610061, 0x1b1b001b, 0x1c1c001c, + 0x0f0f000f, 0x16160016, 0x18180018, 0x22220022, 0x44440044, 0xb2b200b2, + 0xb5b500b5, 0x91910091, 0x08080008, 0xa8a800a8, 0xfcfc00fc, 0x50500050, + 0xd0d000d0, 0x7d7d007d, 0x89890089, 0x97970097, 0x5b5b005b, 0x95950095, + 0xffff00ff, 0xd2d200d2, 0xc4c400c4, 0x48480048, 0xf7f700f7, 0xdbdb00db, + 0x03030003, 0xdada00da, 0x3f3f003f, 0x94940094, 0x5c5c005c, 0x02020002, + 0x4a4a004a, 0x33330033, 0x67670067, 0xf3f300f3, 0x7f7f007f, 0xe2e200e2, + 0x9b9b009b, 0x26260026, 0x37370037, 0x3b3b003b, 0x96960096, 0x4b4b004b, + 0xbebe00be, 0x2e2e002e, 0x79790079, 0x8c8c008c, 0x6e6e006e, 0x8e8e008e, + 0xf5f500f5, 0xb6b600b6, 0xfdfd00fd, 0x59590059, 0x98980098, 0x6a6a006a, + 0x46460046, 0xbaba00ba, 0x25250025, 0x42420042, 0xa2a200a2, 0xfafa00fa, + 0x07070007, 0x55550055, 0xeeee00ee, 0x0a0a000a, 0x49490049, 0x68680068, + 0x38380038, 0xa4a400a4, 0x28280028, 0x7b7b007b, 0xc9c900c9, 0xc1c100c1, + 0xe3e300e3, 0xf4f400f4, 0xc7c700c7, 0x9e9e009e}, + {0x00e0e0e0, 0x00050505, 0x00585858, 0x00d9d9d9, 0x00676767, 0x004e4e4e, + 0x00818181, 0x00cbcbcb, 0x00c9c9c9, 0x000b0b0b, 0x00aeaeae, 0x006a6a6a, + 0x00d5d5d5, 0x00181818, 0x005d5d5d, 0x00828282, 0x00464646, 0x00dfdfdf, + 0x00d6d6d6, 0x00272727, 0x008a8a8a, 0x00323232, 0x004b4b4b, 0x00424242, + 0x00dbdbdb, 0x001c1c1c, 0x009e9e9e, 0x009c9c9c, 0x003a3a3a, 0x00cacaca, + 0x00252525, 0x007b7b7b, 0x000d0d0d, 0x00717171, 0x005f5f5f, 0x001f1f1f, + 0x00f8f8f8, 0x00d7d7d7, 0x003e3e3e, 0x009d9d9d, 0x007c7c7c, 0x00606060, + 0x00b9b9b9, 0x00bebebe, 0x00bcbcbc, 0x008b8b8b, 0x00161616, 0x00343434, + 0x004d4d4d, 0x00c3c3c3, 0x00727272, 0x00959595, 0x00ababab, 0x008e8e8e, + 0x00bababa, 0x007a7a7a, 0x00b3b3b3, 0x00020202, 0x00b4b4b4, 0x00adadad, + 0x00a2a2a2, 0x00acacac, 0x00d8d8d8, 0x009a9a9a, 0x00171717, 0x001a1a1a, + 0x00353535, 0x00cccccc, 0x00f7f7f7, 0x00999999, 0x00616161, 0x005a5a5a, + 0x00e8e8e8, 0x00242424, 0x00565656, 0x00404040, 0x00e1e1e1, 0x00636363, + 0x00090909, 0x00333333, 0x00bfbfbf, 0x00989898, 0x00979797, 0x00858585, + 0x00686868, 0x00fcfcfc, 0x00ececec, 0x000a0a0a, 0x00dadada, 0x006f6f6f, + 0x00535353, 0x00626262, 0x00a3a3a3, 0x002e2e2e, 0x00080808, 0x00afafaf, + 0x00282828, 0x00b0b0b0, 0x00747474, 0x00c2c2c2, 0x00bdbdbd, 0x00363636, + 0x00222222, 0x00383838, 0x00646464, 0x001e1e1e, 0x00393939, 0x002c2c2c, + 0x00a6a6a6, 0x00303030, 0x00e5e5e5, 0x00444444, 0x00fdfdfd, 0x00888888, + 0x009f9f9f, 0x00656565, 0x00878787, 0x006b6b6b, 0x00f4f4f4, 0x00232323, + 0x00484848, 0x00101010, 0x00d1d1d1, 0x00515151, 0x00c0c0c0, 0x00f9f9f9, + 0x00d2d2d2, 0x00a0a0a0, 0x00555555, 0x00a1a1a1, 0x00414141, 0x00fafafa, + 0x00434343, 0x00131313, 0x00c4c4c4, 0x002f2f2f, 0x00a8a8a8, 0x00b6b6b6, + 0x003c3c3c, 0x002b2b2b, 0x00c1c1c1, 0x00ffffff, 0x00c8c8c8, 0x00a5a5a5, + 0x00202020, 0x00898989, 0x00000000, 0x00909090, 0x00474747, 0x00efefef, + 0x00eaeaea, 0x00b7b7b7, 0x00151515, 0x00060606, 0x00cdcdcd, 0x00b5b5b5, + 0x00121212, 0x007e7e7e, 0x00bbbbbb, 0x00292929, 0x000f0f0f, 0x00b8b8b8, + 0x00070707, 0x00040404, 0x009b9b9b, 0x00949494, 0x00212121, 0x00666666, + 0x00e6e6e6, 0x00cecece, 0x00ededed, 0x00e7e7e7, 0x003b3b3b, 0x00fefefe, + 0x007f7f7f, 0x00c5c5c5, 0x00a4a4a4, 0x00373737, 0x00b1b1b1, 0x004c4c4c, + 0x00919191, 0x006e6e6e, 0x008d8d8d, 0x00767676, 0x00030303, 0x002d2d2d, + 0x00dedede, 0x00969696, 0x00262626, 0x007d7d7d, 0x00c6c6c6, 0x005c5c5c, + 0x00d3d3d3, 0x00f2f2f2, 0x004f4f4f, 0x00191919, 0x003f3f3f, 0x00dcdcdc, + 0x00797979, 0x001d1d1d, 0x00525252, 0x00ebebeb, 0x00f3f3f3, 0x006d6d6d, + 0x005e5e5e, 0x00fbfbfb, 0x00696969, 0x00b2b2b2, 0x00f0f0f0, 0x00313131, + 0x000c0c0c, 0x00d4d4d4, 0x00cfcfcf, 0x008c8c8c, 0x00e2e2e2, 0x00757575, + 0x00a9a9a9, 0x004a4a4a, 0x00575757, 0x00848484, 0x00111111, 0x00454545, + 0x001b1b1b, 0x00f5f5f5, 0x00e4e4e4, 0x000e0e0e, 0x00737373, 0x00aaaaaa, + 0x00f1f1f1, 0x00dddddd, 0x00595959, 0x00141414, 0x006c6c6c, 0x00929292, + 0x00545454, 0x00d0d0d0, 0x00787878, 0x00707070, 0x00e3e3e3, 0x00494949, + 0x00808080, 0x00505050, 0x00a7a7a7, 0x00f6f6f6, 0x00777777, 0x00939393, + 0x00868686, 0x00838383, 0x002a2a2a, 0x00c7c7c7, 0x005b5b5b, 0x00e9e9e9, + 0x00eeeeee, 0x008f8f8f, 0x00010101, 0x003d3d3d}, + {0x38003838, 0x41004141, 0x16001616, 0x76007676, 0xd900d9d9, 0x93009393, + 0x60006060, 0xf200f2f2, 0x72007272, 0xc200c2c2, 0xab00abab, 0x9a009a9a, + 0x75007575, 0x06000606, 0x57005757, 0xa000a0a0, 0x91009191, 0xf700f7f7, + 0xb500b5b5, 0xc900c9c9, 0xa200a2a2, 0x8c008c8c, 0xd200d2d2, 0x90009090, + 0xf600f6f6, 0x07000707, 0xa700a7a7, 0x27002727, 0x8e008e8e, 0xb200b2b2, + 0x49004949, 0xde00dede, 0x43004343, 0x5c005c5c, 0xd700d7d7, 0xc700c7c7, + 0x3e003e3e, 0xf500f5f5, 0x8f008f8f, 0x67006767, 0x1f001f1f, 0x18001818, + 0x6e006e6e, 0xaf00afaf, 0x2f002f2f, 0xe200e2e2, 0x85008585, 0x0d000d0d, + 0x53005353, 0xf000f0f0, 0x9c009c9c, 0x65006565, 0xea00eaea, 0xa300a3a3, + 0xae00aeae, 0x9e009e9e, 0xec00ecec, 0x80008080, 0x2d002d2d, 0x6b006b6b, + 0xa800a8a8, 0x2b002b2b, 0x36003636, 0xa600a6a6, 0xc500c5c5, 0x86008686, + 0x4d004d4d, 0x33003333, 0xfd00fdfd, 0x66006666, 0x58005858, 0x96009696, + 0x3a003a3a, 0x09000909, 0x95009595, 0x10001010, 0x78007878, 0xd800d8d8, + 0x42004242, 0xcc00cccc, 0xef00efef, 0x26002626, 0xe500e5e5, 0x61006161, + 0x1a001a1a, 0x3f003f3f, 0x3b003b3b, 0x82008282, 0xb600b6b6, 0xdb00dbdb, + 0xd400d4d4, 0x98009898, 0xe800e8e8, 0x8b008b8b, 0x02000202, 0xeb00ebeb, + 0x0a000a0a, 0x2c002c2c, 0x1d001d1d, 0xb000b0b0, 0x6f006f6f, 0x8d008d8d, + 0x88008888, 0x0e000e0e, 0x19001919, 0x87008787, 0x4e004e4e, 0x0b000b0b, + 0xa900a9a9, 0x0c000c0c, 0x79007979, 0x11001111, 0x7f007f7f, 0x22002222, + 0xe700e7e7, 0x59005959, 0xe100e1e1, 0xda00dada, 0x3d003d3d, 0xc800c8c8, + 0x12001212, 0x04000404, 0x74007474, 0x54005454, 0x30003030, 0x7e007e7e, + 0xb400b4b4, 0x28002828, 0x55005555, 0x68006868, 0x50005050, 0xbe00bebe, + 0xd000d0d0, 0xc400c4c4, 0x31003131, 0xcb00cbcb, 0x2a002a2a, 0xad00adad, + 0x0f000f0f, 0xca00caca, 0x70007070, 0xff00ffff, 0x32003232, 0x69006969, + 0x08000808, 0x62006262, 0x00000000, 0x24002424, 0xd100d1d1, 0xfb00fbfb, + 0xba00baba, 0xed00eded, 0x45004545, 0x81008181, 0x73007373, 0x6d006d6d, + 0x84008484, 0x9f009f9f, 0xee00eeee, 0x4a004a4a, 0xc300c3c3, 0x2e002e2e, + 0xc100c1c1, 0x01000101, 0xe600e6e6, 0x25002525, 0x48004848, 0x99009999, + 0xb900b9b9, 0xb300b3b3, 0x7b007b7b, 0xf900f9f9, 0xce00cece, 0xbf00bfbf, + 0xdf00dfdf, 0x71007171, 0x29002929, 0xcd00cdcd, 0x6c006c6c, 0x13001313, + 0x64006464, 0x9b009b9b, 0x63006363, 0x9d009d9d, 0xc000c0c0, 0x4b004b4b, + 0xb700b7b7, 0xa500a5a5, 0x89008989, 0x5f005f5f, 0xb100b1b1, 0x17001717, + 0xf400f4f4, 0xbc00bcbc, 0xd300d3d3, 0x46004646, 0xcf00cfcf, 0x37003737, + 0x5e005e5e, 0x47004747, 0x94009494, 0xfa00fafa, 0xfc00fcfc, 0x5b005b5b, + 0x97009797, 0xfe00fefe, 0x5a005a5a, 0xac00acac, 0x3c003c3c, 0x4c004c4c, + 0x03000303, 0x35003535, 0xf300f3f3, 0x23002323, 0xb800b8b8, 0x5d005d5d, + 0x6a006a6a, 0x92009292, 0xd500d5d5, 0x21002121, 0x44004444, 0x51005151, + 0xc600c6c6, 0x7d007d7d, 0x39003939, 0x83008383, 0xdc00dcdc, 0xaa00aaaa, + 0x7c007c7c, 0x77007777, 0x56005656, 0x05000505, 0x1b001b1b, 0xa400a4a4, + 0x15001515, 0x34003434, 0x1e001e1e, 0x1c001c1c, 0xf800f8f8, 0x52005252, + 0x20002020, 0x14001414, 0xe900e9e9, 0xbd00bdbd, 0xdd00dddd, 0xe400e4e4, + 0xa100a1a1, 0xe000e0e0, 0x8a008a8a, 0xf100f1f1, 0xd600d6d6, 0x7a007a7a, + 0xbb00bbbb, 0xe300e3e3, 0x40004040, 0x4f004f4f} +}; + +/* Key generation constants */ +static const u32 SIGMA[] = { + 0xa09e667f, 0x3bcc908b, 0xb67ae858, 0x4caa73b2, 0xc6ef372f, 0xe94f82be, + 0x54ff53a5, 0xf1d36f1c, 0x10e527fa, 0xde682d1d, 0xb05688c2, 0xb3e6c1fd +}; + +/* The phi algorithm given in C.2.7 of the Camellia spec document. */ +/* + * This version does not attempt to minimize amount of temporary + * variables, but instead explicitly exposes algorithm's parallelism. + * It is therefore most appropriate for platforms with not less than + * ~16 registers. For platforms with less registers [well, x86 to be + * specific] assembler version should be/is provided anyway... + */ +#define Camellia_Feistel(_s0,_s1,_s2,_s3,_key) do {\ + register u32 _t0,_t1,_t2,_t3;\ +\ + _t0 = _s0 ^ (_key)[0];\ + _t3 = SBOX4_4404[_t0&0xff];\ + _t1 = _s1 ^ (_key)[1];\ + _t3 ^= SBOX3_3033[(_t0 >> 8)&0xff];\ + _t2 = SBOX1_1110[_t1&0xff];\ + _t3 ^= SBOX2_0222[(_t0 >> 16)&0xff];\ + _t2 ^= SBOX4_4404[(_t1 >> 8)&0xff];\ + _t3 ^= SBOX1_1110[(_t0 >> 24)];\ + _t2 ^= _t3;\ + _t3 = RightRotate(_t3,8);\ + _t2 ^= SBOX3_3033[(_t1 >> 16)&0xff];\ + _s3 ^= _t3;\ + _t2 ^= SBOX2_0222[(_t1 >> 24)];\ + _s2 ^= _t2; \ + _s3 ^= _t2;\ +} while(0) + +/* + * Note that n has to be less than 32. Rotations for larger amount + * of bits are achieved by "rotating" order of s-elements and + * adjusting n accordingly, e.g. RotLeft128(s1,s2,s3,s0,n-32). + */ +#define RotLeft128(_s0,_s1,_s2,_s3,_n) do {\ + u32 _t0=_s0>>(32-_n);\ + _s0 = (_s0<<_n) | (_s1>>(32-_n));\ + _s1 = (_s1<<_n) | (_s2>>(32-_n));\ + _s2 = (_s2<<_n) | (_s3>>(32-_n));\ + _s3 = (_s3<<_n) | _t0;\ +} while (0) + +int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, KEY_TABLE_TYPE k) +{ + register u32 s0, s1, s2, s3; + + k[0] = s0 = GETU32(rawKey); + k[1] = s1 = GETU32(rawKey + 4); + k[2] = s2 = GETU32(rawKey + 8); + k[3] = s3 = GETU32(rawKey + 12); + + if (keyBitLength != 128) { + k[8] = s0 = GETU32(rawKey + 16); + k[9] = s1 = GETU32(rawKey + 20); + if (keyBitLength == 192) { + k[10] = s2 = ~s0; + k[11] = s3 = ~s1; + } else { + k[10] = s2 = GETU32(rawKey + 24); + k[11] = s3 = GETU32(rawKey + 28); + } + s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3]; + } + + /* Use the Feistel routine to scramble the key material */ + Camellia_Feistel(s0, s1, s2, s3, SIGMA + 0); + Camellia_Feistel(s2, s3, s0, s1, SIGMA + 2); + + s0 ^= k[0], s1 ^= k[1], s2 ^= k[2], s3 ^= k[3]; + Camellia_Feistel(s0, s1, s2, s3, SIGMA + 4); + Camellia_Feistel(s2, s3, s0, s1, SIGMA + 6); + + /* Fill the keyTable. Requires many block rotations. */ + if (keyBitLength == 128) { + k[4] = s0, k[5] = s1, k[6] = s2, k[7] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */ + k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 30 */ + k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 45 */ + k[24] = s0, k[25] = s1; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 60 */ + k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3; + RotLeft128(s1, s2, s3, s0, 2); /* KA <<< 94 */ + k[40] = s1, k[41] = s2, k[42] = s3, k[43] = s0; + RotLeft128(s1, s2, s3, s0, 17); /* KA <<<111 */ + k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0; + + s0 = k[0], s1 = k[1], s2 = k[2], s3 = k[3]; + RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 15 */ + k[8] = s0, k[9] = s1, k[10] = s2, k[11] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KL <<< 45 */ + k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KL <<< 60 */ + k[26] = s2, k[27] = s3; + RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 77 */ + k[32] = s0, k[33] = s1, k[34] = s2, k[35] = s3; + RotLeft128(s0, s1, s2, s3, 17); /* KL <<< 94 */ + k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3; + RotLeft128(s0, s1, s2, s3, 17); /* KL <<<111 */ + k[44] = s0, k[45] = s1, k[46] = s2, k[47] = s3; + + return 3; /* grand rounds */ + } else { + k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; + s0 ^= k[8], s1 ^= k[9], s2 ^= k[10], s3 ^= k[11]; + Camellia_Feistel(s0, s1, s2, s3, (SIGMA + 8)); + Camellia_Feistel(s2, s3, s0, s1, (SIGMA + 10)); + + k[4] = s0, k[5] = s1, k[6] = s2, k[7] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 30 */ + k[20] = s0, k[21] = s1, k[22] = s2, k[23] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KB <<< 60 */ + k[40] = s0, k[41] = s1, k[42] = s2, k[43] = s3; + RotLeft128(s1, s2, s3, s0, 19); /* KB <<<111 */ + k[64] = s1, k[65] = s2, k[66] = s3, k[67] = s0; + + s0 = k[8], s1 = k[9], s2 = k[10], s3 = k[11]; + RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 15 */ + k[8] = s0, k[9] = s1, k[10] = s2, k[11] = s3; + RotLeft128(s0, s1, s2, s3, 15); /* KR <<< 30 */ + k[16] = s0, k[17] = s1, k[18] = s2, k[19] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KR <<< 60 */ + k[36] = s0, k[37] = s1, k[38] = s2, k[39] = s3; + RotLeft128(s1, s2, s3, s0, 2); /* KR <<< 94 */ + k[52] = s1, k[53] = s2, k[54] = s3, k[55] = s0; + + s0 = k[12], s1 = k[13], s2 = k[14], s3 = k[15]; + RotLeft128(s0, s1, s2, s3, 15); /* KA <<< 15 */ + k[12] = s0, k[13] = s1, k[14] = s2, k[15] = s3; + RotLeft128(s0, s1, s2, s3, 30); /* KA <<< 45 */ + k[28] = s0, k[29] = s1, k[30] = s2, k[31] = s3; + /* KA <<< 77 */ + k[48] = s1, k[49] = s2, k[50] = s3, k[51] = s0; + RotLeft128(s1, s2, s3, s0, 17); /* KA <<< 94 */ + k[56] = s1, k[57] = s2, k[58] = s3, k[59] = s0; + + s0 = k[0], s1 = k[1], s2 = k[2], s3 = k[3]; + RotLeft128(s1, s2, s3, s0, 13); /* KL <<< 45 */ + k[24] = s1, k[25] = s2, k[26] = s3, k[27] = s0; + RotLeft128(s1, s2, s3, s0, 15); /* KL <<< 60 */ + k[32] = s1, k[33] = s2, k[34] = s3, k[35] = s0; + RotLeft128(s1, s2, s3, s0, 17); /* KL <<< 77 */ + k[44] = s1, k[45] = s2, k[46] = s3, k[47] = s0; + RotLeft128(s2, s3, s0, s1, 2); /* KL <<<111 */ + k[60] = s2, k[61] = s3, k[62] = s0, k[63] = s1; + + return 4; /* grand rounds */ + } + /* + * It is possible to perform certain precalculations, which + * would spare few cycles in block procedure. It's not done, + * because it upsets the performance balance between key + * setup and block procedures, negatively affecting overall + * throughput in applications operating on short messages + * and volatile keys. + */ +} + +void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, + u8 ciphertext[]) +{ + register u32 s0, s1, s2, s3; + const u32 *k = keyTable, *kend = keyTable + grandRounds * 16; + + s0 = GETU32(plaintext) ^ k[0]; + s1 = GETU32(plaintext + 4) ^ k[1]; + s2 = GETU32(plaintext + 8) ^ k[2]; + s3 = GETU32(plaintext + 12) ^ k[3]; + k += 4; + + while (1) { + /* Camellia makes 6 Feistel rounds */ + Camellia_Feistel(s0, s1, s2, s3, k + 0); + Camellia_Feistel(s2, s3, s0, s1, k + 2); + Camellia_Feistel(s0, s1, s2, s3, k + 4); + Camellia_Feistel(s2, s3, s0, s1, k + 6); + Camellia_Feistel(s0, s1, s2, s3, k + 8); + Camellia_Feistel(s2, s3, s0, s1, k + 10); + k += 12; + + if (k == kend) + break; + + /* + * This is the same function as the diffusion function D of the + * accompanying documentation. See section 3.2 for properties of the + * FLlayer function. + */ + s1 ^= LeftRotate(s0 & k[0], 1); + s2 ^= s3 | k[3]; + s0 ^= s1 | k[1]; + s3 ^= LeftRotate(s2 & k[2], 1); + k += 4; + } + + s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3]; + + PUTU32(ciphertext, s2); + PUTU32(ciphertext + 4, s3); + PUTU32(ciphertext + 8, s0); + PUTU32(ciphertext + 12, s1); +} + +void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) +{ + Camellia_EncryptBlock_Rounds(keyBitLength == 128 ? 3 : 4, + plaintext, keyTable, ciphertext); +} + +void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], + const KEY_TABLE_TYPE keyTable, + u8 plaintext[]) +{ + u32 s0, s1, s2, s3; + const u32 *k = keyTable + grandRounds * 16, *kend = keyTable + 4; + + s0 = GETU32(ciphertext) ^ k[0]; + s1 = GETU32(ciphertext + 4) ^ k[1]; + s2 = GETU32(ciphertext + 8) ^ k[2]; + s3 = GETU32(ciphertext + 12) ^ k[3]; + + while (1) { + /* Camellia makes 6 Feistel rounds */ + k -= 12; + Camellia_Feistel(s0, s1, s2, s3, k + 10); + Camellia_Feistel(s2, s3, s0, s1, k + 8); + Camellia_Feistel(s0, s1, s2, s3, k + 6); + Camellia_Feistel(s2, s3, s0, s1, k + 4); + Camellia_Feistel(s0, s1, s2, s3, k + 2); + Camellia_Feistel(s2, s3, s0, s1, k + 0); + + if (k == kend) + break; + + /* + * This is the same function as the diffusion function D of the + * accompanying documentation. See section 3.2 for properties of the + * FLlayer function. + */ + k -= 4; + s1 ^= LeftRotate(s0 & k[2], 1); + s2 ^= s3 | k[1]; + s0 ^= s1 | k[3]; + s3 ^= LeftRotate(s2 & k[0], 1); + } + + k -= 4; + s2 ^= k[0], s3 ^= k[1], s0 ^= k[2], s1 ^= k[3]; + + PUTU32(plaintext, s2); + PUTU32(plaintext + 4, s3); + PUTU32(plaintext + 8, s0); + PUTU32(plaintext + 12, s1); +} + +void Camellia_DecryptBlock(int keyBitLength, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]) +{ + Camellia_DecryptBlock_Rounds(keyBitLength == 128 ? 3 : 4, + plaintext, keyTable, ciphertext); +} diff --git a/libs/openssl/crypto/camellia/camellia.h b/libs/openssl/crypto/camellia/camellia.h new file mode 100644 index 00000000..45e8d25b --- /dev/null +++ b/libs/openssl/crypto/camellia/camellia.h @@ -0,0 +1,132 @@ +/* crypto/camellia/camellia.h */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef HEADER_CAMELLIA_H +# define HEADER_CAMELLIA_H + +# include + +# ifdef OPENSSL_NO_CAMELLIA +# error CAMELLIA is disabled. +# endif + +# include + +# define CAMELLIA_ENCRYPT 1 +# define CAMELLIA_DECRYPT 0 + +/* + * Because array size can't be a const in C, the following two are macros. + * Both sizes are in bytes. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* This should be a hidden type, but EVP requires that the size be known */ + +# define CAMELLIA_BLOCK_SIZE 16 +# define CAMELLIA_TABLE_BYTE_LEN 272 +# define CAMELLIA_TABLE_WORD_LEN (CAMELLIA_TABLE_BYTE_LEN / 4) + +typedef unsigned int KEY_TABLE_TYPE[CAMELLIA_TABLE_WORD_LEN]; /* to match + * with WORD */ + +struct camellia_key_st { + union { + double d; /* ensures 64-bit align */ + KEY_TABLE_TYPE rd_key; + } u; + int grand_rounds; +}; +typedef struct camellia_key_st CAMELLIA_KEY; + +# ifdef OPENSSL_FIPS +int private_Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); +# endif +int Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); + +void Camellia_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); +void Camellia_decrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key); + +void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key, const int enc); +void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, const int enc); +void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc); +void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num); +void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char ivec[CAMELLIA_BLOCK_SIZE], + unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], + unsigned int *num); + +#ifdef __cplusplus +} +#endif + +#endif /* !HEADER_Camellia_H */ diff --git a/libs/openssl/crypto/camellia/cmll_cbc.c b/libs/openssl/crypto/camellia/cmll_cbc.c new file mode 100644 index 00000000..4017e00d --- /dev/null +++ b/libs/openssl/crypto/camellia/cmll_cbc.c @@ -0,0 +1,66 @@ +/* crypto/camellia/camellia_cbc.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include + +void Camellia_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const CAMELLIA_KEY *key, + unsigned char *ivec, const int enc) +{ + + if (enc) + CRYPTO_cbc128_encrypt(in, out, len, key, ivec, + (block128_f) Camellia_encrypt); + else + CRYPTO_cbc128_decrypt(in, out, len, key, ivec, + (block128_f) Camellia_decrypt); +} diff --git a/libs/openssl/crypto/camellia/cmll_cfb.c b/libs/openssl/crypto/camellia/cmll_cfb.c new file mode 100644 index 00000000..78f2ae45 --- /dev/null +++ b/libs/openssl/crypto/camellia/cmll_cfb.c @@ -0,0 +1,141 @@ +/* crypto/camellia/camellia_cfb.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +/* + * The input and output encrypted as though 128bit cfb mode is being used. + * The extra state information to record how much of the 128bit block we have + * used is contained in *num; + */ + +void Camellia_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc) +{ + + CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc, + (block128_f) Camellia_encrypt); +} + +/* N.B. This expects the input to be packed, MS bit first */ +void Camellia_cfb1_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc) +{ + CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc, + (block128_f) Camellia_encrypt); +} + +void Camellia_cfb8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num, const int enc) +{ + CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc, + (block128_f) Camellia_encrypt); +} diff --git a/libs/openssl/crypto/camellia/cmll_ctr.c b/libs/openssl/crypto/camellia/cmll_ctr.c new file mode 100644 index 00000000..95e26621 --- /dev/null +++ b/libs/openssl/crypto/camellia/cmll_ctr.c @@ -0,0 +1,64 @@ +/* crypto/camellia/camellia_ctr.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include + +void Camellia_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char ivec[CAMELLIA_BLOCK_SIZE], + unsigned char ecount_buf[CAMELLIA_BLOCK_SIZE], + unsigned int *num) +{ + + CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num, + (block128_f) Camellia_encrypt); +} diff --git a/libs/openssl/crypto/camellia/cmll_ecb.c b/libs/openssl/crypto/camellia/cmll_ecb.c new file mode 100644 index 00000000..b030791b --- /dev/null +++ b/libs/openssl/crypto/camellia/cmll_ecb.c @@ -0,0 +1,73 @@ +/* crypto/camellia/camellia_ecb.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#ifndef CAMELLIA_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +#include +#include "cmll_locl.h" + +void Camellia_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key, const int enc) +{ + + assert(in && out && key); + assert((CAMELLIA_ENCRYPT == enc) || (CAMELLIA_DECRYPT == enc)); + + if (CAMELLIA_ENCRYPT == enc) + Camellia_encrypt(in, out, key); + else + Camellia_decrypt(in, out, key); +} diff --git a/libs/openssl/crypto/camellia/cmll_locl.h b/libs/openssl/crypto/camellia/cmll_locl.h new file mode 100644 index 00000000..2bd79b8c --- /dev/null +++ b/libs/openssl/crypto/camellia/cmll_locl.h @@ -0,0 +1,88 @@ +/* crypto/camellia/camellia_locl.h */ +/* ==================================================================== + * Copyright 2006 NTT (Nippon Telegraph and Telephone Corporation) . + * ALL RIGHTS RESERVED. + * + * Intellectual Property information for Camellia: + * http://info.isl.ntt.co.jp/crypt/eng/info/chiteki.html + * + * News Release for Announcement of Camellia open source: + * http://www.ntt.co.jp/news/news06e/0604/060413a.html + * + * The Camellia Code included herein is developed by + * NTT (Nippon Telegraph and Telephone Corporation), and is contributed + * to the OpenSSL project. + * + * The Camellia Code is licensed pursuant to the OpenSSL open source + * license provided below. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CAMELLIA_LOCL_H +# define HEADER_CAMELLIA_LOCL_H + +typedef unsigned int u32; +typedef unsigned char u8; + +int Camellia_Ekeygen(int keyBitLength, const u8 *rawKey, + KEY_TABLE_TYPE keyTable); +void Camellia_EncryptBlock_Rounds(int grandRounds, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, + u8 ciphertext[]); +void Camellia_DecryptBlock_Rounds(int grandRounds, const u8 ciphertext[], + const KEY_TABLE_TYPE keyTable, + u8 plaintext[]); +void Camellia_EncryptBlock(int keyBitLength, const u8 plaintext[], + const KEY_TABLE_TYPE keyTable, u8 ciphertext[]); +void Camellia_DecryptBlock(int keyBitLength, const u8 ciphertext[], + const KEY_TABLE_TYPE keyTable, u8 plaintext[]); +int private_Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key); +#endif /* #ifndef HEADER_CAMELLIA_LOCL_H */ diff --git a/libs/openssl/crypto/camellia/cmll_misc.c b/libs/openssl/crypto/camellia/cmll_misc.c new file mode 100644 index 00000000..694d2fac --- /dev/null +++ b/libs/openssl/crypto/camellia/cmll_misc.c @@ -0,0 +1,80 @@ +/* crypto/camellia/camellia_misc.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include +#include "cmll_locl.h" + +const char CAMELLIA_version[] = "CAMELLIA" OPENSSL_VERSION_PTEXT; + +int private_Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key) +{ + if (!userKey || !key) + return -1; + if (bits != 128 && bits != 192 && bits != 256) + return -2; + key->grand_rounds = Camellia_Ekeygen(bits, userKey, key->u.rd_key); + return 0; +} + +void Camellia_encrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key) +{ + Camellia_EncryptBlock_Rounds(key->grand_rounds, in, key->u.rd_key, out); +} + +void Camellia_decrypt(const unsigned char *in, unsigned char *out, + const CAMELLIA_KEY *key) +{ + Camellia_DecryptBlock_Rounds(key->grand_rounds, in, key->u.rd_key, out); +} diff --git a/libs/openssl/crypto/camellia/cmll_ofb.c b/libs/openssl/crypto/camellia/cmll_ofb.c new file mode 100644 index 00000000..85eb8921 --- /dev/null +++ b/libs/openssl/crypto/camellia/cmll_ofb.c @@ -0,0 +1,122 @@ +/* crypto/camellia/camellia_ofb.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +/* + * The input and output encrypted as though 128bit ofb mode is being used. + * The extra state information to record how much of the 128bit block we have + * used is contained in *num; + */ +void Camellia_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const CAMELLIA_KEY *key, + unsigned char *ivec, int *num) +{ + CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num, + (block128_f) Camellia_encrypt); +} diff --git a/libs/openssl/crypto/camellia/cmll_utl.c b/libs/openssl/crypto/camellia/cmll_utl.c new file mode 100644 index 00000000..d5eb6b4d --- /dev/null +++ b/libs/openssl/crypto/camellia/cmll_utl.c @@ -0,0 +1,64 @@ +/* crypto/camellia/cmll_utl.c */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include +#include "cmll_locl.h" + +int Camellia_set_key(const unsigned char *userKey, const int bits, + CAMELLIA_KEY *key) +{ +#ifdef OPENSSL_FIPS + fips_cipher_abort(Camellia); +#endif + return private_Camellia_set_key(userKey, bits, key); +} diff --git a/libs/openssl/crypto/cast/asm/cast-586.pl b/libs/openssl/crypto/cast/asm/cast-586.pl new file mode 100644 index 00000000..bf6810d3 --- /dev/null +++ b/libs/openssl/crypto/cast/asm/cast-586.pl @@ -0,0 +1,177 @@ +#!/usr/local/bin/perl + +# define for pentium pro friendly version +$ppro=1; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; +require "cbc.pl"; + +&asm_init($ARGV[0],"cast-586.pl",$ARGV[$#ARGV] eq "386"); + +$CAST_ROUNDS=16; +$L="edi"; +$R="esi"; +$K="ebp"; +$tmp1="ecx"; +$tmp2="ebx"; +$tmp3="eax"; +$tmp4="edx"; +$S1="CAST_S_table0"; +$S2="CAST_S_table1"; +$S3="CAST_S_table2"; +$S4="CAST_S_table3"; + +@F1=("add","xor","sub"); +@F2=("xor","sub","add"); +@F3=("sub","add","xor"); + +&CAST_encrypt("CAST_encrypt",1); +&CAST_encrypt("CAST_decrypt",0); +&cbc("CAST_cbc_encrypt","CAST_encrypt","CAST_decrypt",1,4,5,3,-1,-1); + +&asm_finish(); + +sub CAST_encrypt { + local($name,$enc)=@_; + + local($win_ex)=<<"EOF"; +EXTERN _CAST_S_table0:DWORD +EXTERN _CAST_S_table1:DWORD +EXTERN _CAST_S_table2:DWORD +EXTERN _CAST_S_table3:DWORD +EOF + &main::external_label( + "CAST_S_table0", + "CAST_S_table1", + "CAST_S_table2", + "CAST_S_table3", + ); + + &function_begin_B($name,$win_ex); + + &comment(""); + + &push("ebp"); + &push("ebx"); + &mov($tmp2,&wparam(0)); + &mov($K,&wparam(1)); + &push("esi"); + &push("edi"); + + &comment("Load the 2 words"); + &mov($L,&DWP(0,$tmp2,"",0)); + &mov($R,&DWP(4,$tmp2,"",0)); + + &comment('Get short key flag'); + &mov($tmp3,&DWP(128,$K,"",0)); + if($enc) { + &push($tmp3); + } else { + &or($tmp3,$tmp3); + &jnz(&label('cast_dec_skip')); + } + + &xor($tmp3, $tmp3); + + # encrypting part + + if ($enc) { + &E_CAST( 0,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 1,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 2,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 3,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 4,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 5,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 6,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 7,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 8,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 9,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(10,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(11,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &comment('test short key flag'); + &pop($tmp4); + &or($tmp4,$tmp4); + &jnz(&label('cast_enc_done')); + &E_CAST(12,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(13,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(14,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(15,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + } else { + &E_CAST(15,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(14,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(13,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(12,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &set_label('cast_dec_skip'); + &E_CAST(11,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST(10,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 9,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 8,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 7,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 6,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 5,$S,$L,$R,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 4,$S,$R,$L,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 3,$S,$L,$R,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 2,$S,$R,$L,$K,@F3,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 1,$S,$L,$R,$K,@F2,$tmp1,$tmp2,$tmp3,$tmp4); + &E_CAST( 0,$S,$R,$L,$K,@F1,$tmp1,$tmp2,$tmp3,$tmp4); + } + + &set_label('cast_enc_done') if $enc; +# Why the nop? - Ben 17/1/99 + &nop(); + &mov($tmp3,&wparam(0)); + &mov(&DWP(4,$tmp3,"",0),$L); + &mov(&DWP(0,$tmp3,"",0),$R); + &function_end($name); +} + +sub E_CAST { + local($i,$S,$L,$R,$K,$OP1,$OP2,$OP3,$tmp1,$tmp2,$tmp3,$tmp4)=@_; + # Ri needs to have 16 pre added. + + &comment("round $i"); + &mov( $tmp4, &DWP($i*8,$K,"",1)); + + &mov( $tmp1, &DWP($i*8+4,$K,"",1)); + &$OP1( $tmp4, $R); + + &rotl( $tmp4, &LB($tmp1)); + + if ($ppro) { + &mov( $tmp2, $tmp4); # B + &xor( $tmp1, $tmp1); + + &movb( &LB($tmp1), &HB($tmp4)); # A + &and( $tmp2, 0xff); + + &shr( $tmp4, 16); # + &xor( $tmp3, $tmp3); + } else { + &mov( $tmp2, $tmp4); # B + &movb( &LB($tmp1), &HB($tmp4)); # A # BAD BAD BAD + + &shr( $tmp4, 16); # + &and( $tmp2, 0xff); + } + + &movb( &LB($tmp3), &HB($tmp4)); # C # BAD BAD BAD + &and( $tmp4, 0xff); # D + + &mov( $tmp1, &DWP($S1,"",$tmp1,4)); + &mov( $tmp2, &DWP($S2,"",$tmp2,4)); + + &$OP2( $tmp1, $tmp2); + &mov( $tmp2, &DWP($S3,"",$tmp3,4)); + + &$OP3( $tmp1, $tmp2); + &mov( $tmp2, &DWP($S4,"",$tmp4,4)); + + &$OP1( $tmp1, $tmp2); + # XXX + + &xor( $L, $tmp1); + # XXX +} + diff --git a/libs/openssl/crypto/cast/asm/readme b/libs/openssl/crypto/cast/asm/readme new file mode 100644 index 00000000..fbcd7628 --- /dev/null +++ b/libs/openssl/crypto/cast/asm/readme @@ -0,0 +1,7 @@ +There is a ppro flag in cast-586 which turns on/off +generation of pentium pro/II friendly code + +This flag makes the inner loop one cycle longer, but generates +code that runs %30 faster on the pentium pro/II, while only %7 slower +on the pentium. By default, this flag is on. + diff --git a/libs/openssl/crypto/cast/c_cfb64.c b/libs/openssl/crypto/cast/c_cfb64.c new file mode 100644 index 00000000..f2f16e5d --- /dev/null +++ b/libs/openssl/crypto/cast/c_cfb64.c @@ -0,0 +1,123 @@ +/* crypto/cast/c_cfb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cast_lcl.h" + +/* + * The input and output encrypted as though 64bit cfb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ + +void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num, int enc) +{ + register CAST_LONG v0, v1, t; + register int n = *num; + register long l = length; + CAST_LONG ti[2]; + unsigned char *iv, c, cc; + + iv = ivec; + if (enc) { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + CAST_encrypt((CAST_LONG *)ti, schedule); + iv = ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = ivec; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + CAST_encrypt((CAST_LONG *)ti, schedule); + iv = ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = ivec; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; + *num = n; +} diff --git a/libs/openssl/crypto/cast/c_ecb.c b/libs/openssl/crypto/cast/c_ecb.c new file mode 100644 index 00000000..4793f28e --- /dev/null +++ b/libs/openssl/crypto/cast/c_ecb.c @@ -0,0 +1,83 @@ +/* crypto/cast/c_ecb.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cast_lcl.h" +#include + +const char CAST_version[] = "CAST" OPENSSL_VERSION_PTEXT; + +void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAST_KEY *ks, int enc) +{ + CAST_LONG l, d[2]; + + n2l(in, l); + d[0] = l; + n2l(in, l); + d[1] = l; + if (enc) + CAST_encrypt(d, ks); + else + CAST_decrypt(d, ks); + l = d[0]; + l2n(l, out); + l = d[1]; + l2n(l, out); + l = d[0] = d[1] = 0; +} diff --git a/libs/openssl/crypto/cast/c_enc.c b/libs/openssl/crypto/cast/c_enc.c new file mode 100644 index 00000000..6e1d50f1 --- /dev/null +++ b/libs/openssl/crypto/cast/c_enc.c @@ -0,0 +1,200 @@ +/* crypto/cast/c_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cast_lcl.h" + +void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key) +{ + register CAST_LONG l, r, t; + const register CAST_LONG *k; + + k = &(key->data[0]); + l = data[0]; + r = data[1]; + + E_CAST(0, k, l, r, +, ^, -); + E_CAST(1, k, r, l, ^, -, +); + E_CAST(2, k, l, r, -, +, ^); + E_CAST(3, k, r, l, +, ^, -); + E_CAST(4, k, l, r, ^, -, +); + E_CAST(5, k, r, l, -, +, ^); + E_CAST(6, k, l, r, +, ^, -); + E_CAST(7, k, r, l, ^, -, +); + E_CAST(8, k, l, r, -, +, ^); + E_CAST(9, k, r, l, +, ^, -); + E_CAST(10, k, l, r, ^, -, +); + E_CAST(11, k, r, l, -, +, ^); + if (!key->short_key) { + E_CAST(12, k, l, r, +, ^, -); + E_CAST(13, k, r, l, ^, -, +); + E_CAST(14, k, l, r, -, +, ^); + E_CAST(15, k, r, l, +, ^, -); + } + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +} + +void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key) +{ + register CAST_LONG l, r, t; + const register CAST_LONG *k; + + k = &(key->data[0]); + l = data[0]; + r = data[1]; + + if (!key->short_key) { + E_CAST(15, k, l, r, +, ^, -); + E_CAST(14, k, r, l, -, +, ^); + E_CAST(13, k, l, r, ^, -, +); + E_CAST(12, k, r, l, +, ^, -); + } + E_CAST(11, k, l, r, -, +, ^); + E_CAST(10, k, r, l, ^, -, +); + E_CAST(9, k, l, r, +, ^, -); + E_CAST(8, k, r, l, -, +, ^); + E_CAST(7, k, l, r, ^, -, +); + E_CAST(6, k, r, l, +, ^, -); + E_CAST(5, k, l, r, -, +, ^); + E_CAST(4, k, r, l, ^, -, +); + E_CAST(3, k, l, r, +, ^, -); + E_CAST(2, k, r, l, -, +, ^); + E_CAST(1, k, l, r, ^, -, +); + E_CAST(0, k, r, l, +, ^, -); + + data[1] = l & 0xffffffffL; + data[0] = r & 0xffffffffL; +} + +void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *ks, unsigned char *iv, + int enc) +{ + register CAST_LONG tin0, tin1; + register CAST_LONG tout0, tout1, xor0, xor1; + register long l = length; + CAST_LONG tin[2]; + + if (enc) { + n2l(iv, tout0); + n2l(iv, tout1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + CAST_encrypt(tin, ks); + tout0 = tin[0]; + tout1 = tin[1]; + l2n(tout0, out); + l2n(tout1, out); + } + if (l != -8) { + n2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + CAST_encrypt(tin, ks); + tout0 = tin[0]; + tout1 = tin[1]; + l2n(tout0, out); + l2n(tout1, out); + } + l2n(tout0, iv); + l2n(tout1, iv); + } else { + n2l(iv, xor0); + n2l(iv, xor1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin[0] = tin0; + tin[1] = tin1; + CAST_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2n(tout0, out); + l2n(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + n2l(in, tin0); + n2l(in, tin1); + tin[0] = tin0; + tin[1] = tin1; + CAST_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2nn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2n(xor0, iv); + l2n(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} diff --git a/libs/openssl/crypto/cast/c_ofb64.c b/libs/openssl/crypto/cast/c_ofb64.c new file mode 100644 index 00000000..4e0a7c2e --- /dev/null +++ b/libs/openssl/crypto/cast/c_ofb64.c @@ -0,0 +1,110 @@ +/* crypto/cast/c_ofb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cast_lcl.h" + +/* + * The input and output encrypted as though 64bit ofb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ +void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num) +{ + register CAST_LONG v0, v1, t; + register int n = *num; + register long l = length; + unsigned char d[8]; + register char *dp; + CAST_LONG ti[2]; + unsigned char *iv; + int save = 0; + + iv = ivec; + n2l(iv, v0); + n2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2n(v0, dp); + l2n(v1, dp); + while (l--) { + if (n == 0) { + CAST_encrypt((CAST_LONG *)ti, schedule); + dp = (char *)d; + t = ti[0]; + l2n(t, dp); + t = ti[1]; + l2n(t, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = ivec; + l2n(v0, iv); + l2n(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} diff --git a/libs/openssl/crypto/cast/c_skey.c b/libs/openssl/crypto/cast/c_skey.c new file mode 100644 index 00000000..bbb6d560 --- /dev/null +++ b/libs/openssl/crypto/cast/c_skey.c @@ -0,0 +1,175 @@ +/* crypto/cast/c_skey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cast_lcl.h" +#include "cast_s.h" + +#define CAST_exp(l,A,a,n) \ + A[n/4]=l; \ + a[n+3]=(l )&0xff; \ + a[n+2]=(l>> 8)&0xff; \ + a[n+1]=(l>>16)&0xff; \ + a[n+0]=(l>>24)&0xff; + +#define S4 CAST_S_table4 +#define S5 CAST_S_table5 +#define S6 CAST_S_table6 +#define S7 CAST_S_table7 +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data) +#ifdef OPENSSL_FIPS +{ + fips_cipher_abort(CAST); + private_CAST_set_key(key, len, data); +} + +void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data) +#endif +{ + CAST_LONG x[16]; + CAST_LONG z[16]; + CAST_LONG k[32]; + CAST_LONG X[4], Z[4]; + CAST_LONG l, *K; + int i; + + for (i = 0; i < 16; i++) + x[i] = 0; + if (len > 16) + len = 16; + for (i = 0; i < len; i++) + x[i] = data[i]; + if (len <= 10) + key->short_key = 1; + else + key->short_key = 0; + + K = &k[0]; + X[0] = ((x[0] << 24) | (x[1] << 16) | (x[2] << 8) | x[3]) & 0xffffffffL; + X[1] = ((x[4] << 24) | (x[5] << 16) | (x[6] << 8) | x[7]) & 0xffffffffL; + X[2] = ((x[8] << 24) | (x[9] << 16) | (x[10] << 8) | x[11]) & 0xffffffffL; + X[3] = + ((x[12] << 24) | (x[13] << 16) | (x[14] << 8) | x[15]) & 0xffffffffL; + + for (;;) { + l = X[0] ^ S4[x[13]] ^ S5[x[15]] ^ S6[x[12]] ^ S7[x[14]] ^ S6[x[8]]; + CAST_exp(l, Z, z, 0); + l = X[2] ^ S4[z[0]] ^ S5[z[2]] ^ S6[z[1]] ^ S7[z[3]] ^ S7[x[10]]; + CAST_exp(l, Z, z, 4); + l = X[3] ^ S4[z[7]] ^ S5[z[6]] ^ S6[z[5]] ^ S7[z[4]] ^ S4[x[9]]; + CAST_exp(l, Z, z, 8); + l = X[1] ^ S4[z[10]] ^ S5[z[9]] ^ S6[z[11]] ^ S7[z[8]] ^ S5[x[11]]; + CAST_exp(l, Z, z, 12); + + K[0] = S4[z[8]] ^ S5[z[9]] ^ S6[z[7]] ^ S7[z[6]] ^ S4[z[2]]; + K[1] = S4[z[10]] ^ S5[z[11]] ^ S6[z[5]] ^ S7[z[4]] ^ S5[z[6]]; + K[2] = S4[z[12]] ^ S5[z[13]] ^ S6[z[3]] ^ S7[z[2]] ^ S6[z[9]]; + K[3] = S4[z[14]] ^ S5[z[15]] ^ S6[z[1]] ^ S7[z[0]] ^ S7[z[12]]; + + l = Z[2] ^ S4[z[5]] ^ S5[z[7]] ^ S6[z[4]] ^ S7[z[6]] ^ S6[z[0]]; + CAST_exp(l, X, x, 0); + l = Z[0] ^ S4[x[0]] ^ S5[x[2]] ^ S6[x[1]] ^ S7[x[3]] ^ S7[z[2]]; + CAST_exp(l, X, x, 4); + l = Z[1] ^ S4[x[7]] ^ S5[x[6]] ^ S6[x[5]] ^ S7[x[4]] ^ S4[z[1]]; + CAST_exp(l, X, x, 8); + l = Z[3] ^ S4[x[10]] ^ S5[x[9]] ^ S6[x[11]] ^ S7[x[8]] ^ S5[z[3]]; + CAST_exp(l, X, x, 12); + + K[4] = S4[x[3]] ^ S5[x[2]] ^ S6[x[12]] ^ S7[x[13]] ^ S4[x[8]]; + K[5] = S4[x[1]] ^ S5[x[0]] ^ S6[x[14]] ^ S7[x[15]] ^ S5[x[13]]; + K[6] = S4[x[7]] ^ S5[x[6]] ^ S6[x[8]] ^ S7[x[9]] ^ S6[x[3]]; + K[7] = S4[x[5]] ^ S5[x[4]] ^ S6[x[10]] ^ S7[x[11]] ^ S7[x[7]]; + + l = X[0] ^ S4[x[13]] ^ S5[x[15]] ^ S6[x[12]] ^ S7[x[14]] ^ S6[x[8]]; + CAST_exp(l, Z, z, 0); + l = X[2] ^ S4[z[0]] ^ S5[z[2]] ^ S6[z[1]] ^ S7[z[3]] ^ S7[x[10]]; + CAST_exp(l, Z, z, 4); + l = X[3] ^ S4[z[7]] ^ S5[z[6]] ^ S6[z[5]] ^ S7[z[4]] ^ S4[x[9]]; + CAST_exp(l, Z, z, 8); + l = X[1] ^ S4[z[10]] ^ S5[z[9]] ^ S6[z[11]] ^ S7[z[8]] ^ S5[x[11]]; + CAST_exp(l, Z, z, 12); + + K[8] = S4[z[3]] ^ S5[z[2]] ^ S6[z[12]] ^ S7[z[13]] ^ S4[z[9]]; + K[9] = S4[z[1]] ^ S5[z[0]] ^ S6[z[14]] ^ S7[z[15]] ^ S5[z[12]]; + K[10] = S4[z[7]] ^ S5[z[6]] ^ S6[z[8]] ^ S7[z[9]] ^ S6[z[2]]; + K[11] = S4[z[5]] ^ S5[z[4]] ^ S6[z[10]] ^ S7[z[11]] ^ S7[z[6]]; + + l = Z[2] ^ S4[z[5]] ^ S5[z[7]] ^ S6[z[4]] ^ S7[z[6]] ^ S6[z[0]]; + CAST_exp(l, X, x, 0); + l = Z[0] ^ S4[x[0]] ^ S5[x[2]] ^ S6[x[1]] ^ S7[x[3]] ^ S7[z[2]]; + CAST_exp(l, X, x, 4); + l = Z[1] ^ S4[x[7]] ^ S5[x[6]] ^ S6[x[5]] ^ S7[x[4]] ^ S4[z[1]]; + CAST_exp(l, X, x, 8); + l = Z[3] ^ S4[x[10]] ^ S5[x[9]] ^ S6[x[11]] ^ S7[x[8]] ^ S5[z[3]]; + CAST_exp(l, X, x, 12); + + K[12] = S4[x[8]] ^ S5[x[9]] ^ S6[x[7]] ^ S7[x[6]] ^ S4[x[3]]; + K[13] = S4[x[10]] ^ S5[x[11]] ^ S6[x[5]] ^ S7[x[4]] ^ S5[x[7]]; + K[14] = S4[x[12]] ^ S5[x[13]] ^ S6[x[3]] ^ S7[x[2]] ^ S6[x[8]]; + K[15] = S4[x[14]] ^ S5[x[15]] ^ S6[x[1]] ^ S7[x[0]] ^ S7[x[13]]; + if (K != k) + break; + K += 16; + } + + for (i = 0; i < 16; i++) { + key->data[i * 2] = k[i]; + key->data[i * 2 + 1] = ((k[i + 16]) + 16) & 0x1f; + } +} diff --git a/libs/openssl/crypto/cast/cast.h b/libs/openssl/crypto/cast/cast.h new file mode 100644 index 00000000..0003ec9c --- /dev/null +++ b/libs/openssl/crypto/cast/cast.h @@ -0,0 +1,107 @@ +/* crypto/cast/cast.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CAST_H +# define HEADER_CAST_H + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +# ifdef OPENSSL_NO_CAST +# error CAST is disabled. +# endif + +# define CAST_ENCRYPT 1 +# define CAST_DECRYPT 0 + +# define CAST_LONG unsigned int + +# define CAST_BLOCK 8 +# define CAST_KEY_LENGTH 16 + +typedef struct cast_key_st { + CAST_LONG data[32]; + int short_key; /* Use reduced rounds for short key */ +} CAST_KEY; + +# ifdef OPENSSL_FIPS +void private_CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); +# endif +void CAST_set_key(CAST_KEY *key, int len, const unsigned char *data); +void CAST_ecb_encrypt(const unsigned char *in, unsigned char *out, + const CAST_KEY *key, int enc); +void CAST_encrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_decrypt(CAST_LONG *data, const CAST_KEY *key); +void CAST_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *ks, unsigned char *iv, + int enc); +void CAST_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void CAST_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, const CAST_KEY *schedule, + unsigned char *ivec, int *num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/cast/cast_lcl.h b/libs/openssl/crypto/cast/cast_lcl.h new file mode 100644 index 00000000..7c4ad41b --- /dev/null +++ b/libs/openssl/crypto/cast/cast_lcl.h @@ -0,0 +1,225 @@ +/* crypto/cast/cast_lcl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "e_os.h" + +#ifdef OPENSSL_SYS_WIN32 +# include +#endif + +#undef c2l +#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +#undef c2ln +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +#undef l2c +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#undef l2cn +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +/* NOTE - c is not incremented as per n2l */ +#define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + } \ + } + +#undef n2l +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +#undef l2n +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +#if defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER) +# define ROTL(a,n) (_lrotl(a,n)) +#else +# define ROTL(a,n) ((((a)<<(n))&0xffffffffL)|((a)>>(32-(n)))) +#endif + +#define C_M 0x3fc +#define C_0 22L +#define C_1 14L +#define C_2 6L +#define C_3 2L /* left shift */ + +/* The rotate has an extra 16 added to it to help the x86 asm */ +#if defined(CAST_PTR) +# define E_CAST(n,key,L,R,OP1,OP2,OP3) \ + { \ + int i; \ + t=(key[n*2] OP1 R)&0xffffffffL; \ + i=key[n*2+1]; \ + t=ROTL(t,i); \ + L^= (((((*(CAST_LONG *)((unsigned char *) \ + CAST_S_table0+((t>>C_2)&C_M)) OP2 \ + *(CAST_LONG *)((unsigned char *) \ + CAST_S_table1+((t<>C_0)&C_M)))&0xffffffffL) OP1 \ + *(CAST_LONG *)((unsigned char *) \ + CAST_S_table3+((t>>C_1)&C_M)))&0xffffffffL; \ + } +#elif defined(CAST_PTR2) +# define E_CAST(n,key,L,R,OP1,OP2,OP3) \ + { \ + int i; \ + CAST_LONG u,v,w; \ + w=(key[n*2] OP1 R)&0xffffffffL; \ + i=key[n*2+1]; \ + w=ROTL(w,i); \ + u=w>>C_2; \ + v=w<>C_0; \ + t=(t OP2 *(CAST_LONG *)((unsigned char *)CAST_S_table1+v))&0xffffffffL;\ + v=w>>C_1; \ + u&=C_M; \ + v&=C_M; \ + t=(t OP3 *(CAST_LONG *)((unsigned char *)CAST_S_table2+u)&0xffffffffL);\ + t=(t OP1 *(CAST_LONG *)((unsigned char *)CAST_S_table3+v)&0xffffffffL);\ + L^=(t&0xffffffff); \ + } +#else +# define E_CAST(n,key,L,R,OP1,OP2,OP3) \ + { \ + CAST_LONG a,b,c,d; \ + t=(key[n*2] OP1 R)&0xffffffff; \ + t=ROTL(t,(key[n*2+1])); \ + a=CAST_S_table0[(t>> 8)&0xff]; \ + b=CAST_S_table1[(t )&0xff]; \ + c=CAST_S_table2[(t>>24)&0xff]; \ + d=CAST_S_table3[(t>>16)&0xff]; \ + L^=(((((a OP2 b)&0xffffffffL) OP3 c)&0xffffffffL) OP1 d)&0xffffffffL; \ + } +#endif + +extern const CAST_LONG CAST_S_table0[256]; +extern const CAST_LONG CAST_S_table1[256]; +extern const CAST_LONG CAST_S_table2[256]; +extern const CAST_LONG CAST_S_table3[256]; +extern const CAST_LONG CAST_S_table4[256]; +extern const CAST_LONG CAST_S_table5[256]; +extern const CAST_LONG CAST_S_table6[256]; +extern const CAST_LONG CAST_S_table7[256]; diff --git a/libs/openssl/crypto/cast/cast_s.h b/libs/openssl/crypto/cast/cast_s.h new file mode 100644 index 00000000..380dc81a --- /dev/null +++ b/libs/openssl/crypto/cast/cast_s.h @@ -0,0 +1,592 @@ +/* crypto/cast/cast_s.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +OPENSSL_GLOBAL const CAST_LONG CAST_S_table0[256] = { + 0x30fb40d4, 0x9fa0ff0b, 0x6beccd2f, 0x3f258c7a, + 0x1e213f2f, 0x9c004dd3, 0x6003e540, 0xcf9fc949, + 0xbfd4af27, 0x88bbbdb5, 0xe2034090, 0x98d09675, + 0x6e63a0e0, 0x15c361d2, 0xc2e7661d, 0x22d4ff8e, + 0x28683b6f, 0xc07fd059, 0xff2379c8, 0x775f50e2, + 0x43c340d3, 0xdf2f8656, 0x887ca41a, 0xa2d2bd2d, + 0xa1c9e0d6, 0x346c4819, 0x61b76d87, 0x22540f2f, + 0x2abe32e1, 0xaa54166b, 0x22568e3a, 0xa2d341d0, + 0x66db40c8, 0xa784392f, 0x004dff2f, 0x2db9d2de, + 0x97943fac, 0x4a97c1d8, 0x527644b7, 0xb5f437a7, + 0xb82cbaef, 0xd751d159, 0x6ff7f0ed, 0x5a097a1f, + 0x827b68d0, 0x90ecf52e, 0x22b0c054, 0xbc8e5935, + 0x4b6d2f7f, 0x50bb64a2, 0xd2664910, 0xbee5812d, + 0xb7332290, 0xe93b159f, 0xb48ee411, 0x4bff345d, + 0xfd45c240, 0xad31973f, 0xc4f6d02e, 0x55fc8165, + 0xd5b1caad, 0xa1ac2dae, 0xa2d4b76d, 0xc19b0c50, + 0x882240f2, 0x0c6e4f38, 0xa4e4bfd7, 0x4f5ba272, + 0x564c1d2f, 0xc59c5319, 0xb949e354, 0xb04669fe, + 0xb1b6ab8a, 0xc71358dd, 0x6385c545, 0x110f935d, + 0x57538ad5, 0x6a390493, 0xe63d37e0, 0x2a54f6b3, + 0x3a787d5f, 0x6276a0b5, 0x19a6fcdf, 0x7a42206a, + 0x29f9d4d5, 0xf61b1891, 0xbb72275e, 0xaa508167, + 0x38901091, 0xc6b505eb, 0x84c7cb8c, 0x2ad75a0f, + 0x874a1427, 0xa2d1936b, 0x2ad286af, 0xaa56d291, + 0xd7894360, 0x425c750d, 0x93b39e26, 0x187184c9, + 0x6c00b32d, 0x73e2bb14, 0xa0bebc3c, 0x54623779, + 0x64459eab, 0x3f328b82, 0x7718cf82, 0x59a2cea6, + 0x04ee002e, 0x89fe78e6, 0x3fab0950, 0x325ff6c2, + 0x81383f05, 0x6963c5c8, 0x76cb5ad6, 0xd49974c9, + 0xca180dcf, 0x380782d5, 0xc7fa5cf6, 0x8ac31511, + 0x35e79e13, 0x47da91d0, 0xf40f9086, 0xa7e2419e, + 0x31366241, 0x051ef495, 0xaa573b04, 0x4a805d8d, + 0x548300d0, 0x00322a3c, 0xbf64cddf, 0xba57a68e, + 0x75c6372b, 0x50afd341, 0xa7c13275, 0x915a0bf5, + 0x6b54bfab, 0x2b0b1426, 0xab4cc9d7, 0x449ccd82, + 0xf7fbf265, 0xab85c5f3, 0x1b55db94, 0xaad4e324, + 0xcfa4bd3f, 0x2deaa3e2, 0x9e204d02, 0xc8bd25ac, + 0xeadf55b3, 0xd5bd9e98, 0xe31231b2, 0x2ad5ad6c, + 0x954329de, 0xadbe4528, 0xd8710f69, 0xaa51c90f, + 0xaa786bf6, 0x22513f1e, 0xaa51a79b, 0x2ad344cc, + 0x7b5a41f0, 0xd37cfbad, 0x1b069505, 0x41ece491, + 0xb4c332e6, 0x032268d4, 0xc9600acc, 0xce387e6d, + 0xbf6bb16c, 0x6a70fb78, 0x0d03d9c9, 0xd4df39de, + 0xe01063da, 0x4736f464, 0x5ad328d8, 0xb347cc96, + 0x75bb0fc3, 0x98511bfb, 0x4ffbcc35, 0xb58bcf6a, + 0xe11f0abc, 0xbfc5fe4a, 0xa70aec10, 0xac39570a, + 0x3f04442f, 0x6188b153, 0xe0397a2e, 0x5727cb79, + 0x9ceb418f, 0x1cacd68d, 0x2ad37c96, 0x0175cb9d, + 0xc69dff09, 0xc75b65f0, 0xd9db40d8, 0xec0e7779, + 0x4744ead4, 0xb11c3274, 0xdd24cb9e, 0x7e1c54bd, + 0xf01144f9, 0xd2240eb1, 0x9675b3fd, 0xa3ac3755, + 0xd47c27af, 0x51c85f4d, 0x56907596, 0xa5bb15e6, + 0x580304f0, 0xca042cf1, 0x011a37ea, 0x8dbfaadb, + 0x35ba3e4a, 0x3526ffa0, 0xc37b4d09, 0xbc306ed9, + 0x98a52666, 0x5648f725, 0xff5e569d, 0x0ced63d0, + 0x7c63b2cf, 0x700b45e1, 0xd5ea50f1, 0x85a92872, + 0xaf1fbda7, 0xd4234870, 0xa7870bf3, 0x2d3b4d79, + 0x42e04198, 0x0cd0ede7, 0x26470db8, 0xf881814c, + 0x474d6ad7, 0x7c0c5e5c, 0xd1231959, 0x381b7298, + 0xf5d2f4db, 0xab838653, 0x6e2f1e23, 0x83719c9e, + 0xbd91e046, 0x9a56456e, 0xdc39200c, 0x20c8c571, + 0x962bda1c, 0xe1e696ff, 0xb141ab08, 0x7cca89b9, + 0x1a69e783, 0x02cc4843, 0xa2f7c579, 0x429ef47d, + 0x427b169c, 0x5ac9f049, 0xdd8f0f00, 0x5c8165bf, +}; + +OPENSSL_GLOBAL const CAST_LONG CAST_S_table1[256] = { + 0x1f201094, 0xef0ba75b, 0x69e3cf7e, 0x393f4380, + 0xfe61cf7a, 0xeec5207a, 0x55889c94, 0x72fc0651, + 0xada7ef79, 0x4e1d7235, 0xd55a63ce, 0xde0436ba, + 0x99c430ef, 0x5f0c0794, 0x18dcdb7d, 0xa1d6eff3, + 0xa0b52f7b, 0x59e83605, 0xee15b094, 0xe9ffd909, + 0xdc440086, 0xef944459, 0xba83ccb3, 0xe0c3cdfb, + 0xd1da4181, 0x3b092ab1, 0xf997f1c1, 0xa5e6cf7b, + 0x01420ddb, 0xe4e7ef5b, 0x25a1ff41, 0xe180f806, + 0x1fc41080, 0x179bee7a, 0xd37ac6a9, 0xfe5830a4, + 0x98de8b7f, 0x77e83f4e, 0x79929269, 0x24fa9f7b, + 0xe113c85b, 0xacc40083, 0xd7503525, 0xf7ea615f, + 0x62143154, 0x0d554b63, 0x5d681121, 0xc866c359, + 0x3d63cf73, 0xcee234c0, 0xd4d87e87, 0x5c672b21, + 0x071f6181, 0x39f7627f, 0x361e3084, 0xe4eb573b, + 0x602f64a4, 0xd63acd9c, 0x1bbc4635, 0x9e81032d, + 0x2701f50c, 0x99847ab4, 0xa0e3df79, 0xba6cf38c, + 0x10843094, 0x2537a95e, 0xf46f6ffe, 0xa1ff3b1f, + 0x208cfb6a, 0x8f458c74, 0xd9e0a227, 0x4ec73a34, + 0xfc884f69, 0x3e4de8df, 0xef0e0088, 0x3559648d, + 0x8a45388c, 0x1d804366, 0x721d9bfd, 0xa58684bb, + 0xe8256333, 0x844e8212, 0x128d8098, 0xfed33fb4, + 0xce280ae1, 0x27e19ba5, 0xd5a6c252, 0xe49754bd, + 0xc5d655dd, 0xeb667064, 0x77840b4d, 0xa1b6a801, + 0x84db26a9, 0xe0b56714, 0x21f043b7, 0xe5d05860, + 0x54f03084, 0x066ff472, 0xa31aa153, 0xdadc4755, + 0xb5625dbf, 0x68561be6, 0x83ca6b94, 0x2d6ed23b, + 0xeccf01db, 0xa6d3d0ba, 0xb6803d5c, 0xaf77a709, + 0x33b4a34c, 0x397bc8d6, 0x5ee22b95, 0x5f0e5304, + 0x81ed6f61, 0x20e74364, 0xb45e1378, 0xde18639b, + 0x881ca122, 0xb96726d1, 0x8049a7e8, 0x22b7da7b, + 0x5e552d25, 0x5272d237, 0x79d2951c, 0xc60d894c, + 0x488cb402, 0x1ba4fe5b, 0xa4b09f6b, 0x1ca815cf, + 0xa20c3005, 0x8871df63, 0xb9de2fcb, 0x0cc6c9e9, + 0x0beeff53, 0xe3214517, 0xb4542835, 0x9f63293c, + 0xee41e729, 0x6e1d2d7c, 0x50045286, 0x1e6685f3, + 0xf33401c6, 0x30a22c95, 0x31a70850, 0x60930f13, + 0x73f98417, 0xa1269859, 0xec645c44, 0x52c877a9, + 0xcdff33a6, 0xa02b1741, 0x7cbad9a2, 0x2180036f, + 0x50d99c08, 0xcb3f4861, 0xc26bd765, 0x64a3f6ab, + 0x80342676, 0x25a75e7b, 0xe4e6d1fc, 0x20c710e6, + 0xcdf0b680, 0x17844d3b, 0x31eef84d, 0x7e0824e4, + 0x2ccb49eb, 0x846a3bae, 0x8ff77888, 0xee5d60f6, + 0x7af75673, 0x2fdd5cdb, 0xa11631c1, 0x30f66f43, + 0xb3faec54, 0x157fd7fa, 0xef8579cc, 0xd152de58, + 0xdb2ffd5e, 0x8f32ce19, 0x306af97a, 0x02f03ef8, + 0x99319ad5, 0xc242fa0f, 0xa7e3ebb0, 0xc68e4906, + 0xb8da230c, 0x80823028, 0xdcdef3c8, 0xd35fb171, + 0x088a1bc8, 0xbec0c560, 0x61a3c9e8, 0xbca8f54d, + 0xc72feffa, 0x22822e99, 0x82c570b4, 0xd8d94e89, + 0x8b1c34bc, 0x301e16e6, 0x273be979, 0xb0ffeaa6, + 0x61d9b8c6, 0x00b24869, 0xb7ffce3f, 0x08dc283b, + 0x43daf65a, 0xf7e19798, 0x7619b72f, 0x8f1c9ba4, + 0xdc8637a0, 0x16a7d3b1, 0x9fc393b7, 0xa7136eeb, + 0xc6bcc63e, 0x1a513742, 0xef6828bc, 0x520365d6, + 0x2d6a77ab, 0x3527ed4b, 0x821fd216, 0x095c6e2e, + 0xdb92f2fb, 0x5eea29cb, 0x145892f5, 0x91584f7f, + 0x5483697b, 0x2667a8cc, 0x85196048, 0x8c4bacea, + 0x833860d4, 0x0d23e0f9, 0x6c387e8a, 0x0ae6d249, + 0xb284600c, 0xd835731d, 0xdcb1c647, 0xac4c56ea, + 0x3ebd81b3, 0x230eabb0, 0x6438bc87, 0xf0b5b1fa, + 0x8f5ea2b3, 0xfc184642, 0x0a036b7a, 0x4fb089bd, + 0x649da589, 0xa345415e, 0x5c038323, 0x3e5d3bb9, + 0x43d79572, 0x7e6dd07c, 0x06dfdf1e, 0x6c6cc4ef, + 0x7160a539, 0x73bfbe70, 0x83877605, 0x4523ecf1, +}; + +OPENSSL_GLOBAL const CAST_LONG CAST_S_table2[256] = { + 0x8defc240, 0x25fa5d9f, 0xeb903dbf, 0xe810c907, + 0x47607fff, 0x369fe44b, 0x8c1fc644, 0xaececa90, + 0xbeb1f9bf, 0xeefbcaea, 0xe8cf1950, 0x51df07ae, + 0x920e8806, 0xf0ad0548, 0xe13c8d83, 0x927010d5, + 0x11107d9f, 0x07647db9, 0xb2e3e4d4, 0x3d4f285e, + 0xb9afa820, 0xfade82e0, 0xa067268b, 0x8272792e, + 0x553fb2c0, 0x489ae22b, 0xd4ef9794, 0x125e3fbc, + 0x21fffcee, 0x825b1bfd, 0x9255c5ed, 0x1257a240, + 0x4e1a8302, 0xbae07fff, 0x528246e7, 0x8e57140e, + 0x3373f7bf, 0x8c9f8188, 0xa6fc4ee8, 0xc982b5a5, + 0xa8c01db7, 0x579fc264, 0x67094f31, 0xf2bd3f5f, + 0x40fff7c1, 0x1fb78dfc, 0x8e6bd2c1, 0x437be59b, + 0x99b03dbf, 0xb5dbc64b, 0x638dc0e6, 0x55819d99, + 0xa197c81c, 0x4a012d6e, 0xc5884a28, 0xccc36f71, + 0xb843c213, 0x6c0743f1, 0x8309893c, 0x0feddd5f, + 0x2f7fe850, 0xd7c07f7e, 0x02507fbf, 0x5afb9a04, + 0xa747d2d0, 0x1651192e, 0xaf70bf3e, 0x58c31380, + 0x5f98302e, 0x727cc3c4, 0x0a0fb402, 0x0f7fef82, + 0x8c96fdad, 0x5d2c2aae, 0x8ee99a49, 0x50da88b8, + 0x8427f4a0, 0x1eac5790, 0x796fb449, 0x8252dc15, + 0xefbd7d9b, 0xa672597d, 0xada840d8, 0x45f54504, + 0xfa5d7403, 0xe83ec305, 0x4f91751a, 0x925669c2, + 0x23efe941, 0xa903f12e, 0x60270df2, 0x0276e4b6, + 0x94fd6574, 0x927985b2, 0x8276dbcb, 0x02778176, + 0xf8af918d, 0x4e48f79e, 0x8f616ddf, 0xe29d840e, + 0x842f7d83, 0x340ce5c8, 0x96bbb682, 0x93b4b148, + 0xef303cab, 0x984faf28, 0x779faf9b, 0x92dc560d, + 0x224d1e20, 0x8437aa88, 0x7d29dc96, 0x2756d3dc, + 0x8b907cee, 0xb51fd240, 0xe7c07ce3, 0xe566b4a1, + 0xc3e9615e, 0x3cf8209d, 0x6094d1e3, 0xcd9ca341, + 0x5c76460e, 0x00ea983b, 0xd4d67881, 0xfd47572c, + 0xf76cedd9, 0xbda8229c, 0x127dadaa, 0x438a074e, + 0x1f97c090, 0x081bdb8a, 0x93a07ebe, 0xb938ca15, + 0x97b03cff, 0x3dc2c0f8, 0x8d1ab2ec, 0x64380e51, + 0x68cc7bfb, 0xd90f2788, 0x12490181, 0x5de5ffd4, + 0xdd7ef86a, 0x76a2e214, 0xb9a40368, 0x925d958f, + 0x4b39fffa, 0xba39aee9, 0xa4ffd30b, 0xfaf7933b, + 0x6d498623, 0x193cbcfa, 0x27627545, 0x825cf47a, + 0x61bd8ba0, 0xd11e42d1, 0xcead04f4, 0x127ea392, + 0x10428db7, 0x8272a972, 0x9270c4a8, 0x127de50b, + 0x285ba1c8, 0x3c62f44f, 0x35c0eaa5, 0xe805d231, + 0x428929fb, 0xb4fcdf82, 0x4fb66a53, 0x0e7dc15b, + 0x1f081fab, 0x108618ae, 0xfcfd086d, 0xf9ff2889, + 0x694bcc11, 0x236a5cae, 0x12deca4d, 0x2c3f8cc5, + 0xd2d02dfe, 0xf8ef5896, 0xe4cf52da, 0x95155b67, + 0x494a488c, 0xb9b6a80c, 0x5c8f82bc, 0x89d36b45, + 0x3a609437, 0xec00c9a9, 0x44715253, 0x0a874b49, + 0xd773bc40, 0x7c34671c, 0x02717ef6, 0x4feb5536, + 0xa2d02fff, 0xd2bf60c4, 0xd43f03c0, 0x50b4ef6d, + 0x07478cd1, 0x006e1888, 0xa2e53f55, 0xb9e6d4bc, + 0xa2048016, 0x97573833, 0xd7207d67, 0xde0f8f3d, + 0x72f87b33, 0xabcc4f33, 0x7688c55d, 0x7b00a6b0, + 0x947b0001, 0x570075d2, 0xf9bb88f8, 0x8942019e, + 0x4264a5ff, 0x856302e0, 0x72dbd92b, 0xee971b69, + 0x6ea22fde, 0x5f08ae2b, 0xaf7a616d, 0xe5c98767, + 0xcf1febd2, 0x61efc8c2, 0xf1ac2571, 0xcc8239c2, + 0x67214cb8, 0xb1e583d1, 0xb7dc3e62, 0x7f10bdce, + 0xf90a5c38, 0x0ff0443d, 0x606e6dc6, 0x60543a49, + 0x5727c148, 0x2be98a1d, 0x8ab41738, 0x20e1be24, + 0xaf96da0f, 0x68458425, 0x99833be5, 0x600d457d, + 0x282f9350, 0x8334b362, 0xd91d1120, 0x2b6d8da0, + 0x642b1e31, 0x9c305a00, 0x52bce688, 0x1b03588a, + 0xf7baefd5, 0x4142ed9c, 0xa4315c11, 0x83323ec5, + 0xdfef4636, 0xa133c501, 0xe9d3531c, 0xee353783, +}; + +OPENSSL_GLOBAL const CAST_LONG CAST_S_table3[256] = { + 0x9db30420, 0x1fb6e9de, 0xa7be7bef, 0xd273a298, + 0x4a4f7bdb, 0x64ad8c57, 0x85510443, 0xfa020ed1, + 0x7e287aff, 0xe60fb663, 0x095f35a1, 0x79ebf120, + 0xfd059d43, 0x6497b7b1, 0xf3641f63, 0x241e4adf, + 0x28147f5f, 0x4fa2b8cd, 0xc9430040, 0x0cc32220, + 0xfdd30b30, 0xc0a5374f, 0x1d2d00d9, 0x24147b15, + 0xee4d111a, 0x0fca5167, 0x71ff904c, 0x2d195ffe, + 0x1a05645f, 0x0c13fefe, 0x081b08ca, 0x05170121, + 0x80530100, 0xe83e5efe, 0xac9af4f8, 0x7fe72701, + 0xd2b8ee5f, 0x06df4261, 0xbb9e9b8a, 0x7293ea25, + 0xce84ffdf, 0xf5718801, 0x3dd64b04, 0xa26f263b, + 0x7ed48400, 0x547eebe6, 0x446d4ca0, 0x6cf3d6f5, + 0x2649abdf, 0xaea0c7f5, 0x36338cc1, 0x503f7e93, + 0xd3772061, 0x11b638e1, 0x72500e03, 0xf80eb2bb, + 0xabe0502e, 0xec8d77de, 0x57971e81, 0xe14f6746, + 0xc9335400, 0x6920318f, 0x081dbb99, 0xffc304a5, + 0x4d351805, 0x7f3d5ce3, 0xa6c866c6, 0x5d5bcca9, + 0xdaec6fea, 0x9f926f91, 0x9f46222f, 0x3991467d, + 0xa5bf6d8e, 0x1143c44f, 0x43958302, 0xd0214eeb, + 0x022083b8, 0x3fb6180c, 0x18f8931e, 0x281658e6, + 0x26486e3e, 0x8bd78a70, 0x7477e4c1, 0xb506e07c, + 0xf32d0a25, 0x79098b02, 0xe4eabb81, 0x28123b23, + 0x69dead38, 0x1574ca16, 0xdf871b62, 0x211c40b7, + 0xa51a9ef9, 0x0014377b, 0x041e8ac8, 0x09114003, + 0xbd59e4d2, 0xe3d156d5, 0x4fe876d5, 0x2f91a340, + 0x557be8de, 0x00eae4a7, 0x0ce5c2ec, 0x4db4bba6, + 0xe756bdff, 0xdd3369ac, 0xec17b035, 0x06572327, + 0x99afc8b0, 0x56c8c391, 0x6b65811c, 0x5e146119, + 0x6e85cb75, 0xbe07c002, 0xc2325577, 0x893ff4ec, + 0x5bbfc92d, 0xd0ec3b25, 0xb7801ab7, 0x8d6d3b24, + 0x20c763ef, 0xc366a5fc, 0x9c382880, 0x0ace3205, + 0xaac9548a, 0xeca1d7c7, 0x041afa32, 0x1d16625a, + 0x6701902c, 0x9b757a54, 0x31d477f7, 0x9126b031, + 0x36cc6fdb, 0xc70b8b46, 0xd9e66a48, 0x56e55a79, + 0x026a4ceb, 0x52437eff, 0x2f8f76b4, 0x0df980a5, + 0x8674cde3, 0xedda04eb, 0x17a9be04, 0x2c18f4df, + 0xb7747f9d, 0xab2af7b4, 0xefc34d20, 0x2e096b7c, + 0x1741a254, 0xe5b6a035, 0x213d42f6, 0x2c1c7c26, + 0x61c2f50f, 0x6552daf9, 0xd2c231f8, 0x25130f69, + 0xd8167fa2, 0x0418f2c8, 0x001a96a6, 0x0d1526ab, + 0x63315c21, 0x5e0a72ec, 0x49bafefd, 0x187908d9, + 0x8d0dbd86, 0x311170a7, 0x3e9b640c, 0xcc3e10d7, + 0xd5cad3b6, 0x0caec388, 0xf73001e1, 0x6c728aff, + 0x71eae2a1, 0x1f9af36e, 0xcfcbd12f, 0xc1de8417, + 0xac07be6b, 0xcb44a1d8, 0x8b9b0f56, 0x013988c3, + 0xb1c52fca, 0xb4be31cd, 0xd8782806, 0x12a3a4e2, + 0x6f7de532, 0x58fd7eb6, 0xd01ee900, 0x24adffc2, + 0xf4990fc5, 0x9711aac5, 0x001d7b95, 0x82e5e7d2, + 0x109873f6, 0x00613096, 0xc32d9521, 0xada121ff, + 0x29908415, 0x7fbb977f, 0xaf9eb3db, 0x29c9ed2a, + 0x5ce2a465, 0xa730f32c, 0xd0aa3fe8, 0x8a5cc091, + 0xd49e2ce7, 0x0ce454a9, 0xd60acd86, 0x015f1919, + 0x77079103, 0xdea03af6, 0x78a8565e, 0xdee356df, + 0x21f05cbe, 0x8b75e387, 0xb3c50651, 0xb8a5c3ef, + 0xd8eeb6d2, 0xe523be77, 0xc2154529, 0x2f69efdf, + 0xafe67afb, 0xf470c4b2, 0xf3e0eb5b, 0xd6cc9876, + 0x39e4460c, 0x1fda8538, 0x1987832f, 0xca007367, + 0xa99144f8, 0x296b299e, 0x492fc295, 0x9266beab, + 0xb5676e69, 0x9bd3ddda, 0xdf7e052f, 0xdb25701c, + 0x1b5e51ee, 0xf65324e6, 0x6afce36c, 0x0316cc04, + 0x8644213e, 0xb7dc59d0, 0x7965291f, 0xccd6fd43, + 0x41823979, 0x932bcdf6, 0xb657c34d, 0x4edfd282, + 0x7ae5290c, 0x3cb9536b, 0x851e20fe, 0x9833557e, + 0x13ecf0b0, 0xd3ffb372, 0x3f85c5c1, 0x0aef7ed2, +}; + +OPENSSL_GLOBAL const CAST_LONG CAST_S_table4[256] = { + 0x7ec90c04, 0x2c6e74b9, 0x9b0e66df, 0xa6337911, + 0xb86a7fff, 0x1dd358f5, 0x44dd9d44, 0x1731167f, + 0x08fbf1fa, 0xe7f511cc, 0xd2051b00, 0x735aba00, + 0x2ab722d8, 0x386381cb, 0xacf6243a, 0x69befd7a, + 0xe6a2e77f, 0xf0c720cd, 0xc4494816, 0xccf5c180, + 0x38851640, 0x15b0a848, 0xe68b18cb, 0x4caadeff, + 0x5f480a01, 0x0412b2aa, 0x259814fc, 0x41d0efe2, + 0x4e40b48d, 0x248eb6fb, 0x8dba1cfe, 0x41a99b02, + 0x1a550a04, 0xba8f65cb, 0x7251f4e7, 0x95a51725, + 0xc106ecd7, 0x97a5980a, 0xc539b9aa, 0x4d79fe6a, + 0xf2f3f763, 0x68af8040, 0xed0c9e56, 0x11b4958b, + 0xe1eb5a88, 0x8709e6b0, 0xd7e07156, 0x4e29fea7, + 0x6366e52d, 0x02d1c000, 0xc4ac8e05, 0x9377f571, + 0x0c05372a, 0x578535f2, 0x2261be02, 0xd642a0c9, + 0xdf13a280, 0x74b55bd2, 0x682199c0, 0xd421e5ec, + 0x53fb3ce8, 0xc8adedb3, 0x28a87fc9, 0x3d959981, + 0x5c1ff900, 0xfe38d399, 0x0c4eff0b, 0x062407ea, + 0xaa2f4fb1, 0x4fb96976, 0x90c79505, 0xb0a8a774, + 0xef55a1ff, 0xe59ca2c2, 0xa6b62d27, 0xe66a4263, + 0xdf65001f, 0x0ec50966, 0xdfdd55bc, 0x29de0655, + 0x911e739a, 0x17af8975, 0x32c7911c, 0x89f89468, + 0x0d01e980, 0x524755f4, 0x03b63cc9, 0x0cc844b2, + 0xbcf3f0aa, 0x87ac36e9, 0xe53a7426, 0x01b3d82b, + 0x1a9e7449, 0x64ee2d7e, 0xcddbb1da, 0x01c94910, + 0xb868bf80, 0x0d26f3fd, 0x9342ede7, 0x04a5c284, + 0x636737b6, 0x50f5b616, 0xf24766e3, 0x8eca36c1, + 0x136e05db, 0xfef18391, 0xfb887a37, 0xd6e7f7d4, + 0xc7fb7dc9, 0x3063fcdf, 0xb6f589de, 0xec2941da, + 0x26e46695, 0xb7566419, 0xf654efc5, 0xd08d58b7, + 0x48925401, 0xc1bacb7f, 0xe5ff550f, 0xb6083049, + 0x5bb5d0e8, 0x87d72e5a, 0xab6a6ee1, 0x223a66ce, + 0xc62bf3cd, 0x9e0885f9, 0x68cb3e47, 0x086c010f, + 0xa21de820, 0xd18b69de, 0xf3f65777, 0xfa02c3f6, + 0x407edac3, 0xcbb3d550, 0x1793084d, 0xb0d70eba, + 0x0ab378d5, 0xd951fb0c, 0xded7da56, 0x4124bbe4, + 0x94ca0b56, 0x0f5755d1, 0xe0e1e56e, 0x6184b5be, + 0x580a249f, 0x94f74bc0, 0xe327888e, 0x9f7b5561, + 0xc3dc0280, 0x05687715, 0x646c6bd7, 0x44904db3, + 0x66b4f0a3, 0xc0f1648a, 0x697ed5af, 0x49e92ff6, + 0x309e374f, 0x2cb6356a, 0x85808573, 0x4991f840, + 0x76f0ae02, 0x083be84d, 0x28421c9a, 0x44489406, + 0x736e4cb8, 0xc1092910, 0x8bc95fc6, 0x7d869cf4, + 0x134f616f, 0x2e77118d, 0xb31b2be1, 0xaa90b472, + 0x3ca5d717, 0x7d161bba, 0x9cad9010, 0xaf462ba2, + 0x9fe459d2, 0x45d34559, 0xd9f2da13, 0xdbc65487, + 0xf3e4f94e, 0x176d486f, 0x097c13ea, 0x631da5c7, + 0x445f7382, 0x175683f4, 0xcdc66a97, 0x70be0288, + 0xb3cdcf72, 0x6e5dd2f3, 0x20936079, 0x459b80a5, + 0xbe60e2db, 0xa9c23101, 0xeba5315c, 0x224e42f2, + 0x1c5c1572, 0xf6721b2c, 0x1ad2fff3, 0x8c25404e, + 0x324ed72f, 0x4067b7fd, 0x0523138e, 0x5ca3bc78, + 0xdc0fd66e, 0x75922283, 0x784d6b17, 0x58ebb16e, + 0x44094f85, 0x3f481d87, 0xfcfeae7b, 0x77b5ff76, + 0x8c2302bf, 0xaaf47556, 0x5f46b02a, 0x2b092801, + 0x3d38f5f7, 0x0ca81f36, 0x52af4a8a, 0x66d5e7c0, + 0xdf3b0874, 0x95055110, 0x1b5ad7a8, 0xf61ed5ad, + 0x6cf6e479, 0x20758184, 0xd0cefa65, 0x88f7be58, + 0x4a046826, 0x0ff6f8f3, 0xa09c7f70, 0x5346aba0, + 0x5ce96c28, 0xe176eda3, 0x6bac307f, 0x376829d2, + 0x85360fa9, 0x17e3fe2a, 0x24b79767, 0xf5a96b20, + 0xd6cd2595, 0x68ff1ebf, 0x7555442c, 0xf19f06be, + 0xf9e0659a, 0xeeb9491d, 0x34010718, 0xbb30cab8, + 0xe822fe15, 0x88570983, 0x750e6249, 0xda627e55, + 0x5e76ffa8, 0xb1534546, 0x6d47de08, 0xefe9e7d4, +}; + +OPENSSL_GLOBAL const CAST_LONG CAST_S_table5[256] = { + 0xf6fa8f9d, 0x2cac6ce1, 0x4ca34867, 0xe2337f7c, + 0x95db08e7, 0x016843b4, 0xeced5cbc, 0x325553ac, + 0xbf9f0960, 0xdfa1e2ed, 0x83f0579d, 0x63ed86b9, + 0x1ab6a6b8, 0xde5ebe39, 0xf38ff732, 0x8989b138, + 0x33f14961, 0xc01937bd, 0xf506c6da, 0xe4625e7e, + 0xa308ea99, 0x4e23e33c, 0x79cbd7cc, 0x48a14367, + 0xa3149619, 0xfec94bd5, 0xa114174a, 0xeaa01866, + 0xa084db2d, 0x09a8486f, 0xa888614a, 0x2900af98, + 0x01665991, 0xe1992863, 0xc8f30c60, 0x2e78ef3c, + 0xd0d51932, 0xcf0fec14, 0xf7ca07d2, 0xd0a82072, + 0xfd41197e, 0x9305a6b0, 0xe86be3da, 0x74bed3cd, + 0x372da53c, 0x4c7f4448, 0xdab5d440, 0x6dba0ec3, + 0x083919a7, 0x9fbaeed9, 0x49dbcfb0, 0x4e670c53, + 0x5c3d9c01, 0x64bdb941, 0x2c0e636a, 0xba7dd9cd, + 0xea6f7388, 0xe70bc762, 0x35f29adb, 0x5c4cdd8d, + 0xf0d48d8c, 0xb88153e2, 0x08a19866, 0x1ae2eac8, + 0x284caf89, 0xaa928223, 0x9334be53, 0x3b3a21bf, + 0x16434be3, 0x9aea3906, 0xefe8c36e, 0xf890cdd9, + 0x80226dae, 0xc340a4a3, 0xdf7e9c09, 0xa694a807, + 0x5b7c5ecc, 0x221db3a6, 0x9a69a02f, 0x68818a54, + 0xceb2296f, 0x53c0843a, 0xfe893655, 0x25bfe68a, + 0xb4628abc, 0xcf222ebf, 0x25ac6f48, 0xa9a99387, + 0x53bddb65, 0xe76ffbe7, 0xe967fd78, 0x0ba93563, + 0x8e342bc1, 0xe8a11be9, 0x4980740d, 0xc8087dfc, + 0x8de4bf99, 0xa11101a0, 0x7fd37975, 0xda5a26c0, + 0xe81f994f, 0x9528cd89, 0xfd339fed, 0xb87834bf, + 0x5f04456d, 0x22258698, 0xc9c4c83b, 0x2dc156be, + 0x4f628daa, 0x57f55ec5, 0xe2220abe, 0xd2916ebf, + 0x4ec75b95, 0x24f2c3c0, 0x42d15d99, 0xcd0d7fa0, + 0x7b6e27ff, 0xa8dc8af0, 0x7345c106, 0xf41e232f, + 0x35162386, 0xe6ea8926, 0x3333b094, 0x157ec6f2, + 0x372b74af, 0x692573e4, 0xe9a9d848, 0xf3160289, + 0x3a62ef1d, 0xa787e238, 0xf3a5f676, 0x74364853, + 0x20951063, 0x4576698d, 0xb6fad407, 0x592af950, + 0x36f73523, 0x4cfb6e87, 0x7da4cec0, 0x6c152daa, + 0xcb0396a8, 0xc50dfe5d, 0xfcd707ab, 0x0921c42f, + 0x89dff0bb, 0x5fe2be78, 0x448f4f33, 0x754613c9, + 0x2b05d08d, 0x48b9d585, 0xdc049441, 0xc8098f9b, + 0x7dede786, 0xc39a3373, 0x42410005, 0x6a091751, + 0x0ef3c8a6, 0x890072d6, 0x28207682, 0xa9a9f7be, + 0xbf32679d, 0xd45b5b75, 0xb353fd00, 0xcbb0e358, + 0x830f220a, 0x1f8fb214, 0xd372cf08, 0xcc3c4a13, + 0x8cf63166, 0x061c87be, 0x88c98f88, 0x6062e397, + 0x47cf8e7a, 0xb6c85283, 0x3cc2acfb, 0x3fc06976, + 0x4e8f0252, 0x64d8314d, 0xda3870e3, 0x1e665459, + 0xc10908f0, 0x513021a5, 0x6c5b68b7, 0x822f8aa0, + 0x3007cd3e, 0x74719eef, 0xdc872681, 0x073340d4, + 0x7e432fd9, 0x0c5ec241, 0x8809286c, 0xf592d891, + 0x08a930f6, 0x957ef305, 0xb7fbffbd, 0xc266e96f, + 0x6fe4ac98, 0xb173ecc0, 0xbc60b42a, 0x953498da, + 0xfba1ae12, 0x2d4bd736, 0x0f25faab, 0xa4f3fceb, + 0xe2969123, 0x257f0c3d, 0x9348af49, 0x361400bc, + 0xe8816f4a, 0x3814f200, 0xa3f94043, 0x9c7a54c2, + 0xbc704f57, 0xda41e7f9, 0xc25ad33a, 0x54f4a084, + 0xb17f5505, 0x59357cbe, 0xedbd15c8, 0x7f97c5ab, + 0xba5ac7b5, 0xb6f6deaf, 0x3a479c3a, 0x5302da25, + 0x653d7e6a, 0x54268d49, 0x51a477ea, 0x5017d55b, + 0xd7d25d88, 0x44136c76, 0x0404a8c8, 0xb8e5a121, + 0xb81a928a, 0x60ed5869, 0x97c55b96, 0xeaec991b, + 0x29935913, 0x01fdb7f1, 0x088e8dfa, 0x9ab6f6f5, + 0x3b4cbf9f, 0x4a5de3ab, 0xe6051d35, 0xa0e1d855, + 0xd36b4cf1, 0xf544edeb, 0xb0e93524, 0xbebb8fbd, + 0xa2d762cf, 0x49c92f54, 0x38b5f331, 0x7128a454, + 0x48392905, 0xa65b1db8, 0x851c97bd, 0xd675cf2f, +}; + +OPENSSL_GLOBAL const CAST_LONG CAST_S_table6[256] = { + 0x85e04019, 0x332bf567, 0x662dbfff, 0xcfc65693, + 0x2a8d7f6f, 0xab9bc912, 0xde6008a1, 0x2028da1f, + 0x0227bce7, 0x4d642916, 0x18fac300, 0x50f18b82, + 0x2cb2cb11, 0xb232e75c, 0x4b3695f2, 0xb28707de, + 0xa05fbcf6, 0xcd4181e9, 0xe150210c, 0xe24ef1bd, + 0xb168c381, 0xfde4e789, 0x5c79b0d8, 0x1e8bfd43, + 0x4d495001, 0x38be4341, 0x913cee1d, 0x92a79c3f, + 0x089766be, 0xbaeeadf4, 0x1286becf, 0xb6eacb19, + 0x2660c200, 0x7565bde4, 0x64241f7a, 0x8248dca9, + 0xc3b3ad66, 0x28136086, 0x0bd8dfa8, 0x356d1cf2, + 0x107789be, 0xb3b2e9ce, 0x0502aa8f, 0x0bc0351e, + 0x166bf52a, 0xeb12ff82, 0xe3486911, 0xd34d7516, + 0x4e7b3aff, 0x5f43671b, 0x9cf6e037, 0x4981ac83, + 0x334266ce, 0x8c9341b7, 0xd0d854c0, 0xcb3a6c88, + 0x47bc2829, 0x4725ba37, 0xa66ad22b, 0x7ad61f1e, + 0x0c5cbafa, 0x4437f107, 0xb6e79962, 0x42d2d816, + 0x0a961288, 0xe1a5c06e, 0x13749e67, 0x72fc081a, + 0xb1d139f7, 0xf9583745, 0xcf19df58, 0xbec3f756, + 0xc06eba30, 0x07211b24, 0x45c28829, 0xc95e317f, + 0xbc8ec511, 0x38bc46e9, 0xc6e6fa14, 0xbae8584a, + 0xad4ebc46, 0x468f508b, 0x7829435f, 0xf124183b, + 0x821dba9f, 0xaff60ff4, 0xea2c4e6d, 0x16e39264, + 0x92544a8b, 0x009b4fc3, 0xaba68ced, 0x9ac96f78, + 0x06a5b79a, 0xb2856e6e, 0x1aec3ca9, 0xbe838688, + 0x0e0804e9, 0x55f1be56, 0xe7e5363b, 0xb3a1f25d, + 0xf7debb85, 0x61fe033c, 0x16746233, 0x3c034c28, + 0xda6d0c74, 0x79aac56c, 0x3ce4e1ad, 0x51f0c802, + 0x98f8f35a, 0x1626a49f, 0xeed82b29, 0x1d382fe3, + 0x0c4fb99a, 0xbb325778, 0x3ec6d97b, 0x6e77a6a9, + 0xcb658b5c, 0xd45230c7, 0x2bd1408b, 0x60c03eb7, + 0xb9068d78, 0xa33754f4, 0xf430c87d, 0xc8a71302, + 0xb96d8c32, 0xebd4e7be, 0xbe8b9d2d, 0x7979fb06, + 0xe7225308, 0x8b75cf77, 0x11ef8da4, 0xe083c858, + 0x8d6b786f, 0x5a6317a6, 0xfa5cf7a0, 0x5dda0033, + 0xf28ebfb0, 0xf5b9c310, 0xa0eac280, 0x08b9767a, + 0xa3d9d2b0, 0x79d34217, 0x021a718d, 0x9ac6336a, + 0x2711fd60, 0x438050e3, 0x069908a8, 0x3d7fedc4, + 0x826d2bef, 0x4eeb8476, 0x488dcf25, 0x36c9d566, + 0x28e74e41, 0xc2610aca, 0x3d49a9cf, 0xbae3b9df, + 0xb65f8de6, 0x92aeaf64, 0x3ac7d5e6, 0x9ea80509, + 0xf22b017d, 0xa4173f70, 0xdd1e16c3, 0x15e0d7f9, + 0x50b1b887, 0x2b9f4fd5, 0x625aba82, 0x6a017962, + 0x2ec01b9c, 0x15488aa9, 0xd716e740, 0x40055a2c, + 0x93d29a22, 0xe32dbf9a, 0x058745b9, 0x3453dc1e, + 0xd699296e, 0x496cff6f, 0x1c9f4986, 0xdfe2ed07, + 0xb87242d1, 0x19de7eae, 0x053e561a, 0x15ad6f8c, + 0x66626c1c, 0x7154c24c, 0xea082b2a, 0x93eb2939, + 0x17dcb0f0, 0x58d4f2ae, 0x9ea294fb, 0x52cf564c, + 0x9883fe66, 0x2ec40581, 0x763953c3, 0x01d6692e, + 0xd3a0c108, 0xa1e7160e, 0xe4f2dfa6, 0x693ed285, + 0x74904698, 0x4c2b0edd, 0x4f757656, 0x5d393378, + 0xa132234f, 0x3d321c5d, 0xc3f5e194, 0x4b269301, + 0xc79f022f, 0x3c997e7e, 0x5e4f9504, 0x3ffafbbd, + 0x76f7ad0e, 0x296693f4, 0x3d1fce6f, 0xc61e45be, + 0xd3b5ab34, 0xf72bf9b7, 0x1b0434c0, 0x4e72b567, + 0x5592a33d, 0xb5229301, 0xcfd2a87f, 0x60aeb767, + 0x1814386b, 0x30bcc33d, 0x38a0c07d, 0xfd1606f2, + 0xc363519b, 0x589dd390, 0x5479f8e6, 0x1cb8d647, + 0x97fd61a9, 0xea7759f4, 0x2d57539d, 0x569a58cf, + 0xe84e63ad, 0x462e1b78, 0x6580f87e, 0xf3817914, + 0x91da55f4, 0x40a230f3, 0xd1988f35, 0xb6e318d2, + 0x3ffa50bc, 0x3d40f021, 0xc3c0bdae, 0x4958c24c, + 0x518f36b2, 0x84b1d370, 0x0fedce83, 0x878ddada, + 0xf2a279c7, 0x94e01be8, 0x90716f4b, 0x954b8aa3, +}; + +OPENSSL_GLOBAL const CAST_LONG CAST_S_table7[256] = { + 0xe216300d, 0xbbddfffc, 0xa7ebdabd, 0x35648095, + 0x7789f8b7, 0xe6c1121b, 0x0e241600, 0x052ce8b5, + 0x11a9cfb0, 0xe5952f11, 0xece7990a, 0x9386d174, + 0x2a42931c, 0x76e38111, 0xb12def3a, 0x37ddddfc, + 0xde9adeb1, 0x0a0cc32c, 0xbe197029, 0x84a00940, + 0xbb243a0f, 0xb4d137cf, 0xb44e79f0, 0x049eedfd, + 0x0b15a15d, 0x480d3168, 0x8bbbde5a, 0x669ded42, + 0xc7ece831, 0x3f8f95e7, 0x72df191b, 0x7580330d, + 0x94074251, 0x5c7dcdfa, 0xabbe6d63, 0xaa402164, + 0xb301d40a, 0x02e7d1ca, 0x53571dae, 0x7a3182a2, + 0x12a8ddec, 0xfdaa335d, 0x176f43e8, 0x71fb46d4, + 0x38129022, 0xce949ad4, 0xb84769ad, 0x965bd862, + 0x82f3d055, 0x66fb9767, 0x15b80b4e, 0x1d5b47a0, + 0x4cfde06f, 0xc28ec4b8, 0x57e8726e, 0x647a78fc, + 0x99865d44, 0x608bd593, 0x6c200e03, 0x39dc5ff6, + 0x5d0b00a3, 0xae63aff2, 0x7e8bd632, 0x70108c0c, + 0xbbd35049, 0x2998df04, 0x980cf42a, 0x9b6df491, + 0x9e7edd53, 0x06918548, 0x58cb7e07, 0x3b74ef2e, + 0x522fffb1, 0xd24708cc, 0x1c7e27cd, 0xa4eb215b, + 0x3cf1d2e2, 0x19b47a38, 0x424f7618, 0x35856039, + 0x9d17dee7, 0x27eb35e6, 0xc9aff67b, 0x36baf5b8, + 0x09c467cd, 0xc18910b1, 0xe11dbf7b, 0x06cd1af8, + 0x7170c608, 0x2d5e3354, 0xd4de495a, 0x64c6d006, + 0xbcc0c62c, 0x3dd00db3, 0x708f8f34, 0x77d51b42, + 0x264f620f, 0x24b8d2bf, 0x15c1b79e, 0x46a52564, + 0xf8d7e54e, 0x3e378160, 0x7895cda5, 0x859c15a5, + 0xe6459788, 0xc37bc75f, 0xdb07ba0c, 0x0676a3ab, + 0x7f229b1e, 0x31842e7b, 0x24259fd7, 0xf8bef472, + 0x835ffcb8, 0x6df4c1f2, 0x96f5b195, 0xfd0af0fc, + 0xb0fe134c, 0xe2506d3d, 0x4f9b12ea, 0xf215f225, + 0xa223736f, 0x9fb4c428, 0x25d04979, 0x34c713f8, + 0xc4618187, 0xea7a6e98, 0x7cd16efc, 0x1436876c, + 0xf1544107, 0xbedeee14, 0x56e9af27, 0xa04aa441, + 0x3cf7c899, 0x92ecbae6, 0xdd67016d, 0x151682eb, + 0xa842eedf, 0xfdba60b4, 0xf1907b75, 0x20e3030f, + 0x24d8c29e, 0xe139673b, 0xefa63fb8, 0x71873054, + 0xb6f2cf3b, 0x9f326442, 0xcb15a4cc, 0xb01a4504, + 0xf1e47d8d, 0x844a1be5, 0xbae7dfdc, 0x42cbda70, + 0xcd7dae0a, 0x57e85b7a, 0xd53f5af6, 0x20cf4d8c, + 0xcea4d428, 0x79d130a4, 0x3486ebfb, 0x33d3cddc, + 0x77853b53, 0x37effcb5, 0xc5068778, 0xe580b3e6, + 0x4e68b8f4, 0xc5c8b37e, 0x0d809ea2, 0x398feb7c, + 0x132a4f94, 0x43b7950e, 0x2fee7d1c, 0x223613bd, + 0xdd06caa2, 0x37df932b, 0xc4248289, 0xacf3ebc3, + 0x5715f6b7, 0xef3478dd, 0xf267616f, 0xc148cbe4, + 0x9052815e, 0x5e410fab, 0xb48a2465, 0x2eda7fa4, + 0xe87b40e4, 0xe98ea084, 0x5889e9e1, 0xefd390fc, + 0xdd07d35b, 0xdb485694, 0x38d7e5b2, 0x57720101, + 0x730edebc, 0x5b643113, 0x94917e4f, 0x503c2fba, + 0x646f1282, 0x7523d24a, 0xe0779695, 0xf9c17a8f, + 0x7a5b2121, 0xd187b896, 0x29263a4d, 0xba510cdf, + 0x81f47c9f, 0xad1163ed, 0xea7b5965, 0x1a00726e, + 0x11403092, 0x00da6d77, 0x4a0cdd61, 0xad1f4603, + 0x605bdfb0, 0x9eedc364, 0x22ebe6a8, 0xcee7d28a, + 0xa0e736a0, 0x5564a6b9, 0x10853209, 0xc7eb8f37, + 0x2de705ca, 0x8951570f, 0xdf09822b, 0xbd691a6c, + 0xaa12e4f2, 0x87451c0f, 0xe0f6a27a, 0x3ada4819, + 0x4cf1764f, 0x0d771c2b, 0x67cdb156, 0x350d8384, + 0x5938fa0f, 0x42399ef3, 0x36997b07, 0x0e84093d, + 0x4aa93e61, 0x8360d87b, 0x1fa98b0c, 0x1149382c, + 0xe97625a5, 0x0614d1b7, 0x0e25244b, 0x0c768347, + 0x589e8d82, 0x0d2059d1, 0xa466bb1e, 0xf8da0a82, + 0x04f19130, 0xba6e4ec0, 0x99265164, 0x1ee7230d, + 0x50b2ad80, 0xeaee6801, 0x8db2a283, 0xea8bf59e, +}; diff --git a/libs/openssl/crypto/cast/cast_spd.c b/libs/openssl/crypto/cast/cast_spd.c new file mode 100644 index 00000000..91d2ce23 --- /dev/null +++ b/libs/openssl/crypto/cast/cast_spd.c @@ -0,0 +1,262 @@ +/* crypto/cast/cast_spd.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */ +/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */ + +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX) +# define TIMES +#endif + +#include + +#include +#include OPENSSL_UNISTD_IO +OPENSSL_DECLARE_EXIT +#ifndef OPENSSL_SYS_NETWARE +# include +#endif +#ifndef _IRIX +# include +#endif +#ifdef TIMES +# include +# include +#endif + /* + * Depending on the VMS version, the tms structure is perhaps defined. + * The __TMS macro will show if it was. If it wasn't defined, we should + * undefine TIMES, since that tells the rest of the program how things + * should be handled. -- Richard Levitte + */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) +# undef TIMES +#endif +#ifndef TIMES +# include +#endif +#if defined(sun) || defined(__ultrix) +# define _POSIX_SOURCE +# include +# include +#endif +#include +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# define HZ 100.0 +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +#endif +#define BUFSIZE ((long)1024) +long run = 0; + +double Time_F(int s); +#ifdef SIGALRM +# if defined(__STDC__) || defined(sgi) || defined(_AIX) +# define SIGRETTYPE void +# else +# define SIGRETTYPE int +# endif + +SIGRETTYPE sig_done(int sig); +SIGRETTYPE sig_done(int sig) +{ + signal(SIGALRM, sig_done); + run = 0; +# ifdef LINT + sig = sig; +# endif +} +#endif + +#define START 0 +#define STOP 1 + +double Time_F(int s) +{ + double ret; +#ifdef TIMES + static struct tms tstart, tend; + + if (s == START) { + times(&tstart); + return (0); + } else { + times(&tend); + ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ; + return ((ret == 0.0) ? 1e-6 : ret); + } +#else /* !times() */ + static struct timeb tstart, tend; + long i; + + if (s == START) { + ftime(&tstart); + return (0); + } else { + ftime(&tend); + i = (long)tend.millitm - (long)tstart.millitm; + ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1e3; + return ((ret == 0.0) ? 1e-6 : ret); + } +#endif +} + +int main(int argc, char **argv) +{ + long count; + static unsigned char buf[BUFSIZE]; + static unsigned char key[] = { + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + CAST_KEY sch; + double a, b, c, d; +#ifndef SIGALRM + long ca, cb, cc; +#endif + +#ifndef TIMES + printf("To get the most accurate results, try to run this\n"); + printf("program when this computer is idle.\n"); +#endif + +#ifndef SIGALRM + printf("First we calculate the approximate speed ...\n"); + CAST_set_key(&sch, 16, key); + count = 10; + do { + long i; + CAST_LONG data[2]; + + count *= 2; + Time_F(START); + for (i = count; i; i--) + CAST_encrypt(data, &sch); + d = Time_F(STOP); + } while (d < 3.0); + ca = count / 512; + cb = count; + cc = count * 8 / BUFSIZE + 1; + printf("Doing CAST_set_key %ld times\n", ca); +# define COND(d) (count != (d)) +# define COUNT(d) (d) +#else +# define COND(c) (run) +# define COUNT(d) (count) + signal(SIGALRM, sig_done); + printf("Doing CAST_set_key for 10 seconds\n"); + alarm(10); +#endif + + Time_F(START); + for (count = 0, run = 1; COND(ca); count += 4) { + CAST_set_key(&sch, 16, key); + CAST_set_key(&sch, 16, key); + CAST_set_key(&sch, 16, key); + CAST_set_key(&sch, 16, key); + } + d = Time_F(STOP); + printf("%ld cast set_key's in %.2f seconds\n", count, d); + a = ((double)COUNT(ca)) / d; + +#ifdef SIGALRM + printf("Doing CAST_encrypt's for 10 seconds\n"); + alarm(10); +#else + printf("Doing CAST_encrypt %ld times\n", cb); +#endif + Time_F(START); + for (count = 0, run = 1; COND(cb); count += 4) { + CAST_LONG data[2]; + + CAST_encrypt(data, &sch); + CAST_encrypt(data, &sch); + CAST_encrypt(data, &sch); + CAST_encrypt(data, &sch); + } + d = Time_F(STOP); + printf("%ld CAST_encrypt's in %.2f second\n", count, d); + b = ((double)COUNT(cb) * 8) / d; + +#ifdef SIGALRM + printf("Doing CAST_cbc_encrypt on %ld byte blocks for 10 seconds\n", + BUFSIZE); + alarm(10); +#else + printf("Doing CAST_cbc_encrypt %ld times on %ld byte blocks\n", cc, + BUFSIZE); +#endif + Time_F(START); + for (count = 0, run = 1; COND(cc); count++) + CAST_cbc_encrypt(buf, buf, BUFSIZE, &sch, &(key[0]), CAST_ENCRYPT); + d = Time_F(STOP); + printf("%ld CAST_cbc_encrypt's of %ld byte blocks in %.2f second\n", + count, BUFSIZE, d); + c = ((double)COUNT(cc) * BUFSIZE) / d; + + printf("CAST set_key per sec = %12.2f (%9.3fuS)\n", a, 1.0e6 / a); + printf("CAST raw ecb bytes per sec = %12.2f (%9.3fuS)\n", b, 8.0e6 / b); + printf("CAST cbc bytes per sec = %12.2f (%9.3fuS)\n", c, 8.0e6 / c); + exit(0); +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS) + return (0); +#endif +} diff --git a/libs/openssl/crypto/cast/castopts.c b/libs/openssl/crypto/cast/castopts.c new file mode 100644 index 00000000..42687f28 --- /dev/null +++ b/libs/openssl/crypto/cast/castopts.c @@ -0,0 +1,334 @@ +/* crypto/cast/castopts.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * define PART1, PART2, PART3 or PART4 to build only with a few of the + * options. This is for machines with 64k code segment size restrictions. + */ + +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) +# define TIMES +#endif + +#include + +#include +#include OPENSSL_UNISTD_IO +OPENSSL_DECLARE_EXIT +#ifndef OPENSSL_SYS_NETWARE +# include +#endif +#ifndef _IRIX +# include +#endif +#ifdef TIMES +# include +# include +#endif + /* + * Depending on the VMS version, the tms structure is perhaps defined. + * The __TMS macro will show if it was. If it wasn't defined, we should + * undefine TIMES, since that tells the rest of the program how things + * should be handled. -- Richard Levitte + */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) +# undef TIMES +#endif +#ifndef TIMES +# include +#endif +#if defined(sun) || defined(__ultrix) +# define _POSIX_SOURCE +# include +# include +#endif +#include +#define CAST_DEFAULT_OPTIONS +#undef E_CAST +#define CAST_encrypt CAST_encrypt_normal +#define CAST_decrypt CAST_decrypt_normal +#define CAST_cbc_encrypt CAST_cbc_encrypt_normal +#undef HEADER_CAST_LOCL_H +#include "c_enc.c" +#define CAST_PTR +#undef CAST_PTR2 +#undef E_CAST +#undef CAST_encrypt +#undef CAST_decrypt +#undef CAST_cbc_encrypt +#define CAST_encrypt CAST_encrypt_ptr +#define CAST_decrypt CAST_decrypt_ptr +#define CAST_cbc_encrypt CAST_cbc_encrypt_ptr +#undef HEADER_CAST_LOCL_H +#include "c_enc.c" +#undef CAST_PTR +#define CAST_PTR2 +#undef E_CAST +#undef CAST_encrypt +#undef CAST_decrypt +#undef CAST_cbc_encrypt +#define CAST_encrypt CAST_encrypt_ptr2 +#define CAST_decrypt CAST_decrypt_ptr2 +#define CAST_cbc_encrypt CAST_cbc_encrypt_ptr2 +#undef HEADER_CAST_LOCL_H +#include "c_enc.c" +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */ +# define HZ 100.0 +# else /* _BSD_CLK_TCK_ */ +# define HZ ((double)_BSD_CLK_TCK_) +# endif +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +#endif +#define BUFSIZE ((long)1024) +long run = 0; + +double Time_F(int s); +#ifdef SIGALRM +# if defined(__STDC__) || defined(sgi) +# define SIGRETTYPE void +# else +# define SIGRETTYPE int +# endif + +SIGRETTYPE sig_done(int sig); +SIGRETTYPE sig_done(int sig) +{ + signal(SIGALRM, sig_done); + run = 0; +# ifdef LINT + sig = sig; +# endif +} +#endif + +#define START 0 +#define STOP 1 + +double Time_F(int s) +{ + double ret; +#ifdef TIMES + static struct tms tstart, tend; + + if (s == START) { + times(&tstart); + return (0); + } else { + times(&tend); + ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ; + return ((ret == 0.0) ? 1e-6 : ret); + } +#else /* !times() */ + static struct timeb tstart, tend; + long i; + + if (s == START) { + ftime(&tstart); + return (0); + } else { + ftime(&tend); + i = (long)tend.millitm - (long)tstart.millitm; + ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1000.0; + return ((ret == 0.0) ? 1e-6 : ret); + } +#endif +} + +#ifdef SIGALRM +# define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10); +#else +# define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb); +#endif + +#define time_it(func,name,index) \ + print_name(name); \ + Time_F(START); \ + for (count=0,run=1; COND(cb); count+=4) \ + { \ + unsigned long d[2]; \ + func(d,&sch); \ + func(d,&sch); \ + func(d,&sch); \ + func(d,&sch); \ + } \ + tm[index]=Time_F(STOP); \ + fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \ + tm[index]=((double)COUNT(cb))/tm[index]; + +#define print_it(name,index) \ + fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \ + tm[index]*8,1.0e6/tm[index]); + +int main(int argc, char **argv) +{ + long count; + static unsigned char buf[BUFSIZE]; + static char key[16] = { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 + }; + CAST_KEY sch; + double d, tm[16], max = 0; + int rank[16]; + char *str[16]; + int max_idx = 0, i, num = 0, j; +#ifndef SIGALARM + long ca, cb, cc, cd, ce; +#endif + + for (i = 0; i < 12; i++) { + tm[i] = 0.0; + rank[i] = 0; + } + +#ifndef TIMES + fprintf(stderr, "To get the most accurate results, try to run this\n"); + fprintf(stderr, "program when this computer is idle.\n"); +#endif + + CAST_set_key(&sch, 16, key); + +#ifndef SIGALRM + fprintf(stderr, "First we calculate the approximate speed ...\n"); + count = 10; + do { + long i; + unsigned long data[2]; + + count *= 2; + Time_F(START); + for (i = count; i; i--) + CAST_encrypt(data, &sch); + d = Time_F(STOP); + } while (d < 3.0); + ca = count; + cb = count * 3; + cc = count * 3 * 8 / BUFSIZE + 1; + cd = count * 8 / BUFSIZE + 1; + + ce = count / 20 + 1; +# define COND(d) (count != (d)) +# define COUNT(d) (d) +#else +# define COND(c) (run) +# define COUNT(d) (count) + signal(SIGALRM, sig_done); + alarm(10); +#endif + + time_it(CAST_encrypt_normal, "CAST_encrypt_normal ", 0); + time_it(CAST_encrypt_ptr, "CAST_encrypt_ptr ", 1); + time_it(CAST_encrypt_ptr2, "CAST_encrypt_ptr2 ", 2); + num += 3; + + str[0] = ""; + print_it("CAST_encrypt_normal ", 0); + max = tm[0]; + max_idx = 0; + str[1] = "ptr "; + print_it("CAST_encrypt_ptr ", 1); + if (max < tm[1]) { + max = tm[1]; + max_idx = 1; + } + str[2] = "ptr2 "; + print_it("CAST_encrypt_ptr2 ", 2); + if (max < tm[2]) { + max = tm[2]; + max_idx = 2; + } + + printf("options CAST ecb/s\n"); + printf("%s %12.2f 100.0%%\n", str[max_idx], tm[max_idx]); + d = tm[max_idx]; + tm[max_idx] = -2.0; + max = -1.0; + for (;;) { + for (i = 0; i < 3; i++) { + if (max < tm[i]) { + max = tm[i]; + j = i; + } + } + if (max < 0.0) + break; + printf("%s %12.2f %4.1f%%\n", str[j], tm[j], tm[j] / d * 100.0); + tm[j] = -2.0; + max = -1.0; + } + + switch (max_idx) { + case 0: + printf("-DCAST_DEFAULT_OPTIONS\n"); + break; + case 1: + printf("-DCAST_PTR\n"); + break; + case 2: + printf("-DCAST_PTR2\n"); + break; + } + exit(0); +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS) + return (0); +#endif +} diff --git a/libs/openssl/crypto/cast/casts.cpp b/libs/openssl/crypto/cast/casts.cpp new file mode 100644 index 00000000..8d7bd468 --- /dev/null +++ b/libs/openssl/crypto/cast/casts.cpp @@ -0,0 +1,70 @@ +// +// gettsc.inl +// +// gives access to the Pentium's (secret) cycle counter +// +// This software was written by Leonard Janke (janke@unixg.ubc.ca) +// in 1996-7 and is entered, by him, into the public domain. + +#if defined(__WATCOMC__) +void GetTSC(unsigned long&); +#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax]; +#elif defined(__GNUC__) +inline +void GetTSC(unsigned long& tsc) +{ + asm volatile(".byte 15, 49\n\t" + : "=eax" (tsc) + : + : "%edx", "%eax"); +} +#elif defined(_MSC_VER) +inline +void GetTSC(unsigned long& tsc) +{ + unsigned long a; + __asm _emit 0fh + __asm _emit 31h + __asm mov a, eax; + tsc=a; +} +#endif + +#include +#include +#include + +void main(int argc,char *argv[]) + { + CAST_KEY key; + unsigned long s1,s2,e1,e2; + unsigned long data[2]; + int i,j; + static unsigned char d[16]={0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}; + + CAST_set_key(&key, 16,d); + + for (j=0; j<6; j++) + { + for (i=0; i<1000; i++) /**/ + { + CAST_encrypt(&data[0],&key); + GetTSC(s1); + CAST_encrypt(&data[0],&key); + CAST_encrypt(&data[0],&key); + CAST_encrypt(&data[0],&key); + GetTSC(e1); + GetTSC(s2); + CAST_encrypt(&data[0],&key); + CAST_encrypt(&data[0],&key); + CAST_encrypt(&data[0],&key); + CAST_encrypt(&data[0],&key); + GetTSC(e2); + CAST_encrypt(&data[0],&key); + } + + printf("cast %d %d (%d)\n", + e1-s1,e2-s2,((e2-s2)-(e1-s1))); + } + } + diff --git a/libs/openssl/crypto/cast/casttest.c b/libs/openssl/crypto/cast/casttest.c new file mode 100644 index 00000000..dc31bc66 --- /dev/null +++ b/libs/openssl/crypto/cast/casttest.c @@ -0,0 +1,241 @@ +/* crypto/cast/casttest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include /* To see if OPENSSL_NO_CAST is defined */ + +#include "../e_os.h" + +#ifdef OPENSSL_NO_CAST +int main(int argc, char *argv[]) +{ + printf("No CAST support\n"); + return (0); +} +#else +# include + +# define FULL_TEST + +static unsigned char k[16] = { + 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A +}; + +static unsigned char in[8] = + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF }; + +static int k_len[3] = { 16, 10, 5 }; + +static unsigned char c[3][8] = { + {0x23, 0x8B, 0x4F, 0xE5, 0x84, 0x7E, 0x44, 0xB2}, + {0xEB, 0x6A, 0x71, 0x1A, 0x2C, 0x02, 0x27, 0x1B}, + {0x7A, 0xC8, 0x16, 0xD1, 0x6E, 0x9B, 0x30, 0x2E}, +}; + +static unsigned char out[80]; + +static unsigned char in_a[16] = { + 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A +}; + +static unsigned char in_b[16] = { + 0x01, 0x23, 0x45, 0x67, 0x12, 0x34, 0x56, 0x78, + 0x23, 0x45, 0x67, 0x89, 0x34, 0x56, 0x78, 0x9A +}; + +static unsigned char c_a[16] = { + 0xEE, 0xA9, 0xD0, 0xA2, 0x49, 0xFD, 0x3B, 0xA6, + 0xB3, 0x43, 0x6F, 0xB8, 0x9D, 0x6D, 0xCA, 0x92 +}; + +static unsigned char c_b[16] = { + 0xB2, 0xC9, 0x5E, 0xB0, 0x0C, 0x31, 0xAD, 0x71, + 0x80, 0xAC, 0x05, 0xB8, 0xE8, 0x3D, 0x69, 0x6E +}; + +# if 0 +char *text = "Hello to all people out there"; + +static unsigned char cfb_key[16] = { + 0xe1, 0xf0, 0xc3, 0xd2, 0xa5, 0xb4, 0x87, 0x96, + 0x69, 0x78, 0x4b, 0x5a, 0x2d, 0x3c, 0x0f, 0x1e, +}; +static unsigned char cfb_iv[80] = + { 0x34, 0x12, 0x78, 0x56, 0xab, 0x90, 0xef, 0xcd }; +static unsigned char cfb_buf1[40], cfb_buf2[40], cfb_tmp[8]; +# define CFB_TEST_SIZE 24 +static unsigned char plain[CFB_TEST_SIZE] = { + 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, + 0x69, 0x6d, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 +}; + +static unsigned char cfb_cipher64[CFB_TEST_SIZE] = { + 0x59, 0xD8, 0xE2, 0x65, 0x00, 0x58, 0x6C, 0x3F, + 0x2C, 0x17, 0x25, 0xD0, 0x1A, 0x38, 0xB7, 0x2A, + 0x39, 0x61, 0x37, 0xDC, 0x79, 0xFB, 0x9F, 0x45 +/*- 0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38, + 0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9, + 0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/ +}; +# endif + +int main(int argc, char *argv[]) +{ +# ifdef FULL_TEST + long l; + CAST_KEY key_b; +# endif + int i, z, err = 0; + CAST_KEY key; + + for (z = 0; z < 3; z++) { + CAST_set_key(&key, k_len[z], k); + + CAST_ecb_encrypt(in, out, &key, CAST_ENCRYPT); + if (memcmp(out, &(c[z][0]), 8) != 0) { + printf("ecb cast error encrypting for keysize %d\n", + k_len[z] * 8); + printf("got :"); + for (i = 0; i < 8; i++) + printf("%02X ", out[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 8; i++) + printf("%02X ", c[z][i]); + err = 20; + printf("\n"); + } + + CAST_ecb_encrypt(out, out, &key, CAST_DECRYPT); + if (memcmp(out, in, 8) != 0) { + printf("ecb cast error decrypting for keysize %d\n", + k_len[z] * 8); + printf("got :"); + for (i = 0; i < 8; i++) + printf("%02X ", out[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 8; i++) + printf("%02X ", in[i]); + printf("\n"); + err = 3; + } + } + if (err == 0) + printf("ecb cast5 ok\n"); + +# ifdef FULL_TEST + { + unsigned char out_a[16], out_b[16]; + static char *hex = "0123456789ABCDEF"; + + printf("This test will take some time...."); + fflush(stdout); + memcpy(out_a, in_a, sizeof(in_a)); + memcpy(out_b, in_b, sizeof(in_b)); + i = 1; + + for (l = 0; l < 1000000L; l++) { + CAST_set_key(&key_b, 16, out_b); + CAST_ecb_encrypt(&(out_a[0]), &(out_a[0]), &key_b, CAST_ENCRYPT); + CAST_ecb_encrypt(&(out_a[8]), &(out_a[8]), &key_b, CAST_ENCRYPT); + CAST_set_key(&key, 16, out_a); + CAST_ecb_encrypt(&(out_b[0]), &(out_b[0]), &key, CAST_ENCRYPT); + CAST_ecb_encrypt(&(out_b[8]), &(out_b[8]), &key, CAST_ENCRYPT); + if ((l & 0xffff) == 0xffff) { + printf("%c", hex[i & 0x0f]); + fflush(stdout); + i++; + } + } + + if ((memcmp(out_a, c_a, sizeof(c_a)) != 0) || + (memcmp(out_b, c_b, sizeof(c_b)) != 0)) { + printf("\n"); + printf("Error\n"); + + printf("A out ="); + for (i = 0; i < 16; i++) + printf("%02X ", out_a[i]); + printf("\nactual="); + for (i = 0; i < 16; i++) + printf("%02X ", c_a[i]); + printf("\n"); + + printf("B out ="); + for (i = 0; i < 16; i++) + printf("%02X ", out_b[i]); + printf("\nactual="); + for (i = 0; i < 16; i++) + printf("%02X ", c_b[i]); + printf("\n"); + } else + printf(" ok\n"); + } +# endif + + EXIT(err); + return (err); +} +#endif diff --git a/libs/openssl/crypto/cmac/cm_ameth.c b/libs/openssl/crypto/cmac/cm_ameth.c new file mode 100644 index 00000000..bf933e08 --- /dev/null +++ b/libs/openssl/crypto/cmac/cm_ameth.c @@ -0,0 +1,96 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2010. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include "cryptlib.h" +#include +#include +#include "asn1_locl.h" + +/* + * CMAC "ASN1" method. This is just here to indicate the maximum CMAC output + * length and to free up a CMAC key. + */ + +static int cmac_size(const EVP_PKEY *pkey) +{ + return EVP_MAX_BLOCK_LENGTH; +} + +static void cmac_key_free(EVP_PKEY *pkey) +{ + CMAC_CTX *cmctx = (CMAC_CTX *)pkey->pkey.ptr; + if (cmctx) + CMAC_CTX_free(cmctx); +} + +const EVP_PKEY_ASN1_METHOD cmac_asn1_meth = { + EVP_PKEY_CMAC, + EVP_PKEY_CMAC, + 0, + + "CMAC", + "OpenSSL CMAC method", + + 0, 0, 0, 0, + + 0, 0, 0, + + cmac_size, + 0, + 0, 0, 0, 0, 0, 0, 0, + + cmac_key_free, + 0, + 0, 0 +}; diff --git a/libs/openssl/crypto/cmac/cm_pmeth.c b/libs/openssl/crypto/cmac/cm_pmeth.c new file mode 100644 index 00000000..a2300df1 --- /dev/null +++ b/libs/openssl/crypto/cmac/cm_pmeth.c @@ -0,0 +1,216 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2010. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include "evp_locl.h" + +/* The context structure and "key" is simply a CMAC_CTX */ + +static int pkey_cmac_init(EVP_PKEY_CTX *ctx) +{ + ctx->data = CMAC_CTX_new(); + if (!ctx->data) + return 0; + ctx->keygen_info_count = 0; + return 1; +} + +static int pkey_cmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + if (!pkey_cmac_init(dst)) + return 0; + if (!CMAC_CTX_copy(dst->data, src->data)) + return 0; + return 1; +} + +static void pkey_cmac_cleanup(EVP_PKEY_CTX *ctx) +{ + CMAC_CTX_free(ctx->data); +} + +static int pkey_cmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + CMAC_CTX *cmkey = CMAC_CTX_new(); + CMAC_CTX *cmctx = ctx->data; + if (!cmkey) + return 0; + if (!CMAC_CTX_copy(cmkey, cmctx)) { + CMAC_CTX_free(cmkey); + return 0; + } + EVP_PKEY_assign(pkey, EVP_PKEY_CMAC, cmkey); + + return 1; +} + +static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + if (!CMAC_Update(ctx->pctx->data, data, count)) + return 0; + return 1; +} + +static int cmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) +{ + EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); + mctx->update = int_update; + return 1; +} + +static int cmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx) +{ + return CMAC_Final(ctx->data, sig, siglen); +} + +static int pkey_cmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + CMAC_CTX *cmctx = ctx->data; + switch (type) { + + case EVP_PKEY_CTRL_SET_MAC_KEY: + if (!p2 || p1 < 0) + return 0; + if (!CMAC_Init(cmctx, p2, p1, NULL, NULL)) + return 0; + break; + + case EVP_PKEY_CTRL_CIPHER: + if (!CMAC_Init(cmctx, NULL, 0, p2, ctx->engine)) + return 0; + break; + + case EVP_PKEY_CTRL_MD: + if (ctx->pkey && !CMAC_CTX_copy(ctx->data, + (CMAC_CTX *)ctx->pkey->pkey.ptr)) + return 0; + if (!CMAC_Init(cmctx, NULL, 0, NULL, NULL)) + return 0; + break; + + default: + return -2; + + } + return 1; +} + +static int pkey_cmac_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (!value) { + return 0; + } + if (!strcmp(type, "key")) { + void *p = (void *)value; + return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, strlen(p), p); + } + if (!strcmp(type, "cipher")) { + const EVP_CIPHER *c; + c = EVP_get_cipherbyname(value); + if (!c) + return 0; + return pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_CIPHER, -1, (void *)c); + } + if (!strcmp(type, "hexkey")) { + unsigned char *key; + int r; + long keylen; + key = string_to_hex(value, &keylen); + if (!key) + return 0; + r = pkey_cmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key); + OPENSSL_free(key); + return r; + } + return -2; +} + +const EVP_PKEY_METHOD cmac_pkey_meth = { + EVP_PKEY_CMAC, + EVP_PKEY_FLAG_SIGCTX_CUSTOM, + pkey_cmac_init, + pkey_cmac_copy, + pkey_cmac_cleanup, + + 0, 0, + + 0, + pkey_cmac_keygen, + + 0, 0, + + 0, 0, + + 0, 0, + + cmac_signctx_init, + cmac_signctx, + + 0, 0, + + 0, 0, + + 0, 0, + + 0, 0, + + pkey_cmac_ctrl, + pkey_cmac_ctrl_str +}; diff --git a/libs/openssl/crypto/cmac/cmac.c b/libs/openssl/crypto/cmac/cmac.c new file mode 100644 index 00000000..774e6dc9 --- /dev/null +++ b/libs/openssl/crypto/cmac/cmac.c @@ -0,0 +1,298 @@ +/* crypto/cmac/cmac.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include "cryptlib.h" +#include + +#ifdef OPENSSL_FIPS +# include +#endif + +struct CMAC_CTX_st { + /* Cipher context to use */ + EVP_CIPHER_CTX cctx; + /* Keys k1 and k2 */ + unsigned char k1[EVP_MAX_BLOCK_LENGTH]; + unsigned char k2[EVP_MAX_BLOCK_LENGTH]; + /* Temporary block */ + unsigned char tbl[EVP_MAX_BLOCK_LENGTH]; + /* Last (possibly partial) block */ + unsigned char last_block[EVP_MAX_BLOCK_LENGTH]; + /* Number of bytes in last block: -1 means context not initialised */ + int nlast_block; +}; + +/* Make temporary keys K1 and K2 */ + +static void make_kn(unsigned char *k1, unsigned char *l, int bl) +{ + int i; + /* Shift block to left, including carry */ + for (i = 0; i < bl; i++) { + k1[i] = l[i] << 1; + if (i < bl - 1 && l[i + 1] & 0x80) + k1[i] |= 1; + } + /* If MSB set fixup with R */ + if (l[0] & 0x80) + k1[bl - 1] ^= bl == 16 ? 0x87 : 0x1b; +} + +CMAC_CTX *CMAC_CTX_new(void) +{ + CMAC_CTX *ctx; + ctx = OPENSSL_malloc(sizeof(CMAC_CTX)); + if (!ctx) + return NULL; + EVP_CIPHER_CTX_init(&ctx->cctx); + ctx->nlast_block = -1; + return ctx; +} + +void CMAC_CTX_cleanup(CMAC_CTX *ctx) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !ctx->cctx.engine) { + FIPS_cmac_ctx_cleanup(ctx); + return; + } +#endif + EVP_CIPHER_CTX_cleanup(&ctx->cctx); + OPENSSL_cleanse(ctx->tbl, EVP_MAX_BLOCK_LENGTH); + OPENSSL_cleanse(ctx->k1, EVP_MAX_BLOCK_LENGTH); + OPENSSL_cleanse(ctx->k2, EVP_MAX_BLOCK_LENGTH); + OPENSSL_cleanse(ctx->last_block, EVP_MAX_BLOCK_LENGTH); + ctx->nlast_block = -1; +} + +EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx) +{ + return &ctx->cctx; +} + +void CMAC_CTX_free(CMAC_CTX *ctx) +{ + if (!ctx) + return; + CMAC_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in) +{ + int bl; + if (in->nlast_block == -1) + return 0; + if (!EVP_CIPHER_CTX_copy(&out->cctx, &in->cctx)) + return 0; + bl = EVP_CIPHER_CTX_block_size(&in->cctx); + memcpy(out->k1, in->k1, bl); + memcpy(out->k2, in->k2, bl); + memcpy(out->tbl, in->tbl, bl); + memcpy(out->last_block, in->last_block, bl); + out->nlast_block = in->nlast_block; + return 1; +} + +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, + const EVP_CIPHER *cipher, ENGINE *impl) +{ + static unsigned char zero_iv[EVP_MAX_BLOCK_LENGTH]; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) { + /* If we have an ENGINE need to allow non FIPS */ + if ((impl || ctx->cctx.engine) + && !(ctx->cctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) { + EVPerr(EVP_F_CMAC_INIT, EVP_R_DISABLED_FOR_FIPS); + return 0; + } + /* + * Other algorithm blocking will be done in FIPS_cmac_init, via + * FIPS_cipherinit(). + */ + if (!impl && !ctx->cctx.engine) + return FIPS_cmac_init(ctx, key, keylen, cipher, NULL); + } +#endif + /* All zeros means restart */ + if (!key && !cipher && !impl && keylen == 0) { + /* Not initialised */ + if (ctx->nlast_block == -1) + return 0; + if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) + return 0; + memset(ctx->tbl, 0, EVP_CIPHER_CTX_block_size(&ctx->cctx)); + ctx->nlast_block = 0; + return 1; + } + /* Initialiase context */ + if (cipher && !EVP_EncryptInit_ex(&ctx->cctx, cipher, impl, NULL, NULL)) + return 0; + /* Non-NULL key means initialisation complete */ + if (key) { + int bl; + if (!EVP_CIPHER_CTX_cipher(&ctx->cctx)) + return 0; + if (!EVP_CIPHER_CTX_set_key_length(&ctx->cctx, keylen)) + return 0; + if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, key, zero_iv)) + return 0; + bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); + if (!EVP_Cipher(&ctx->cctx, ctx->tbl, zero_iv, bl)) + return 0; + make_kn(ctx->k1, ctx->tbl, bl); + make_kn(ctx->k2, ctx->k1, bl); + OPENSSL_cleanse(ctx->tbl, bl); + /* Reset context again ready for first data block */ + if (!EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, zero_iv)) + return 0; + /* Zero tbl so resume works */ + memset(ctx->tbl, 0, bl); + ctx->nlast_block = 0; + } + return 1; +} + +int CMAC_Update(CMAC_CTX *ctx, const void *in, size_t dlen) +{ + const unsigned char *data = in; + size_t bl; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !ctx->cctx.engine) + return FIPS_cmac_update(ctx, in, dlen); +#endif + if (ctx->nlast_block == -1) + return 0; + if (dlen == 0) + return 1; + bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); + /* Copy into partial block if we need to */ + if (ctx->nlast_block > 0) { + size_t nleft; + nleft = bl - ctx->nlast_block; + if (dlen < nleft) + nleft = dlen; + memcpy(ctx->last_block + ctx->nlast_block, data, nleft); + dlen -= nleft; + ctx->nlast_block += nleft; + /* If no more to process return */ + if (dlen == 0) + return 1; + data += nleft; + /* Else not final block so encrypt it */ + if (!EVP_Cipher(&ctx->cctx, ctx->tbl, ctx->last_block, bl)) + return 0; + } + /* Encrypt all but one of the complete blocks left */ + while (dlen > bl) { + if (!EVP_Cipher(&ctx->cctx, ctx->tbl, data, bl)) + return 0; + dlen -= bl; + data += bl; + } + /* Copy any data left to last block buffer */ + memcpy(ctx->last_block, data, dlen); + ctx->nlast_block = dlen; + return 1; + +} + +int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen) +{ + int i, bl, lb; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !ctx->cctx.engine) + return FIPS_cmac_final(ctx, out, poutlen); +#endif + if (ctx->nlast_block == -1) + return 0; + bl = EVP_CIPHER_CTX_block_size(&ctx->cctx); + *poutlen = (size_t)bl; + if (!out) + return 1; + lb = ctx->nlast_block; + /* Is last block complete? */ + if (lb == bl) { + for (i = 0; i < bl; i++) + out[i] = ctx->last_block[i] ^ ctx->k1[i]; + } else { + ctx->last_block[lb] = 0x80; + if (bl - lb > 1) + memset(ctx->last_block + lb + 1, 0, bl - lb - 1); + for (i = 0; i < bl; i++) + out[i] = ctx->last_block[i] ^ ctx->k2[i]; + } + if (!EVP_Cipher(&ctx->cctx, out, out, bl)) { + OPENSSL_cleanse(out, bl); + return 0; + } + return 1; +} + +int CMAC_resume(CMAC_CTX *ctx) +{ + if (ctx->nlast_block == -1) + return 0; + /* + * The buffer "tbl" containes the last fully encrypted block which is the + * last IV (or all zeroes if no last encrypted block). The last block has + * not been modified since CMAC_final(). So reinitliasing using the last + * decrypted block will allow CMAC to continue after calling + * CMAC_Final(). + */ + return EVP_EncryptInit_ex(&ctx->cctx, NULL, NULL, NULL, ctx->tbl); +} diff --git a/libs/openssl/crypto/cmac/cmac.h b/libs/openssl/crypto/cmac/cmac.h new file mode 100644 index 00000000..175be834 --- /dev/null +++ b/libs/openssl/crypto/cmac/cmac.h @@ -0,0 +1,82 @@ +/* crypto/cmac/cmac.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CMAC_H +# define HEADER_CMAC_H + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +/* Opaque */ +typedef struct CMAC_CTX_st CMAC_CTX; + +CMAC_CTX *CMAC_CTX_new(void); +void CMAC_CTX_cleanup(CMAC_CTX *ctx); +void CMAC_CTX_free(CMAC_CTX *ctx); +EVP_CIPHER_CTX *CMAC_CTX_get0_cipher_ctx(CMAC_CTX *ctx); +int CMAC_CTX_copy(CMAC_CTX *out, const CMAC_CTX *in); + +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t keylen, + const EVP_CIPHER *cipher, ENGINE *impl); +int CMAC_Update(CMAC_CTX *ctx, const void *data, size_t dlen); +int CMAC_Final(CMAC_CTX *ctx, unsigned char *out, size_t *poutlen); +int CMAC_resume(CMAC_CTX *ctx); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/cms/cms.h b/libs/openssl/crypto/cms/cms.h new file mode 100644 index 00000000..a2281eda --- /dev/null +++ b/libs/openssl/crypto/cms/cms.h @@ -0,0 +1,505 @@ +/* crypto/cms/cms.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CMS_H +# define HEADER_CMS_H + +# include + +# ifdef OPENSSL_NO_CMS +# error CMS is disabled. +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct CMS_ContentInfo_st CMS_ContentInfo; +typedef struct CMS_SignerInfo_st CMS_SignerInfo; +typedef struct CMS_CertificateChoices CMS_CertificateChoices; +typedef struct CMS_RevocationInfoChoice_st CMS_RevocationInfoChoice; +typedef struct CMS_RecipientInfo_st CMS_RecipientInfo; +typedef struct CMS_ReceiptRequest_st CMS_ReceiptRequest; +typedef struct CMS_Receipt_st CMS_Receipt; + +DECLARE_STACK_OF(CMS_SignerInfo) +DECLARE_STACK_OF(GENERAL_NAMES) +DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) +DECLARE_ASN1_FUNCTIONS(CMS_ReceiptRequest) +DECLARE_ASN1_PRINT_FUNCTION(CMS_ContentInfo) + +# define CMS_SIGNERINFO_ISSUER_SERIAL 0 +# define CMS_SIGNERINFO_KEYIDENTIFIER 1 + +# define CMS_RECIPINFO_TRANS 0 +# define CMS_RECIPINFO_AGREE 1 +# define CMS_RECIPINFO_KEK 2 +# define CMS_RECIPINFO_PASS 3 +# define CMS_RECIPINFO_OTHER 4 + +/* S/MIME related flags */ + +# define CMS_TEXT 0x1 +# define CMS_NOCERTS 0x2 +# define CMS_NO_CONTENT_VERIFY 0x4 +# define CMS_NO_ATTR_VERIFY 0x8 +# define CMS_NOSIGS \ + (CMS_NO_CONTENT_VERIFY|CMS_NO_ATTR_VERIFY) +# define CMS_NOINTERN 0x10 +# define CMS_NO_SIGNER_CERT_VERIFY 0x20 +# define CMS_NOVERIFY 0x20 +# define CMS_DETACHED 0x40 +# define CMS_BINARY 0x80 +# define CMS_NOATTR 0x100 +# define CMS_NOSMIMECAP 0x200 +# define CMS_NOOLDMIMETYPE 0x400 +# define CMS_CRLFEOL 0x800 +# define CMS_STREAM 0x1000 +# define CMS_NOCRL 0x2000 +# define CMS_PARTIAL 0x4000 +# define CMS_REUSE_DIGEST 0x8000 +# define CMS_USE_KEYID 0x10000 +# define CMS_DEBUG_DECRYPT 0x20000 + +const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms); + +BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont); +int CMS_dataFinal(CMS_ContentInfo *cms, BIO *bio); + +ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms); +int CMS_is_detached(CMS_ContentInfo *cms); +int CMS_set_detached(CMS_ContentInfo *cms, int detached); + +# ifdef HEADER_PEM_H +DECLARE_PEM_rw_const(CMS, CMS_ContentInfo) +# endif +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms); +CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms); +int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms); + +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms); +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags); +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, + int flags); +CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont); +int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags); + +int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, + unsigned int flags); + +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, + unsigned int flags); + +CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, + X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, unsigned int flags); + +int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags); +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags); + +int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, + unsigned int flags); + +int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, + const unsigned char *key, size_t keylen, + BIO *dcont, BIO *out, unsigned int flags); + +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags); + +int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, + const unsigned char *key, size_t keylen); + +int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags); + +int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, + STACK_OF(X509) *certs, + X509_STORE *store, unsigned int flags); + +STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms); + +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *in, + const EVP_CIPHER *cipher, unsigned int flags); + +int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pkey, X509 *cert, + BIO *dcont, BIO *out, unsigned int flags); + +int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert); +int CMS_decrypt_set1_key(CMS_ContentInfo *cms, + unsigned char *key, size_t keylen, + unsigned char *id, size_t idlen); +int CMS_decrypt_set1_password(CMS_ContentInfo *cms, + unsigned char *pass, ossl_ssize_t passlen); + +STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms); +int CMS_RecipientInfo_type(CMS_RecipientInfo *ri); +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher); +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, + X509 *recip, unsigned int flags); +int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey); +int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert); +int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, + EVP_PKEY **pk, X509 **recip, + X509_ALGOR **palg); +int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); + +CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, + unsigned char *key, size_t keylen, + unsigned char *id, size_t idlen, + ASN1_GENERALIZEDTIME *date, + ASN1_OBJECT *otherTypeId, + ASN1_TYPE *otherType); + +int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pid, + ASN1_GENERALIZEDTIME **pdate, + ASN1_OBJECT **potherid, + ASN1_TYPE **pothertype); + +int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, + unsigned char *key, size_t keylen); + +int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, + const unsigned char *id, size_t idlen); + +int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, + unsigned char *pass, + ossl_ssize_t passlen); + +CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, + int iter, int wrap_nid, + int pbe_nid, + unsigned char *pass, + ossl_ssize_t passlen, + const EVP_CIPHER *kekciph); + +int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri); + +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags); +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags); + +int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid); +const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms); + +CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms); +int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert); +int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert); +STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms); + +CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms); +int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl); +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl); +STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms); + +int CMS_SignedData_init(CMS_ContentInfo *cms); +CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, + X509 *signer, EVP_PKEY *pk, const EVP_MD *md, + unsigned int flags); +STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms); + +void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer); +int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, ASN1_INTEGER **sno); +int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert); +int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + unsigned int flags); +void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, + X509 **signer, X509_ALGOR **pdig, + X509_ALGOR **psig); +int CMS_SignerInfo_sign(CMS_SignerInfo *si); +int CMS_SignerInfo_verify(CMS_SignerInfo *si); +int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain); + +int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs); +int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, + int algnid, int keysize); +int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap); + +int CMS_signed_get_attr_count(const CMS_SignerInfo *si); +int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len); +int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len); +void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type); + +int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si); +int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos); +int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc); +X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc); +int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr); +int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len); +int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len); +void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type); + +# ifdef HEADER_X509V3_H + +int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr); +CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, + int allorfirst, + STACK_OF(GENERAL_NAMES) + *receiptList, STACK_OF(GENERAL_NAMES) + *receiptsTo); +int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr); +void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, + ASN1_STRING **pcid, + int *pallorfirst, + STACK_OF(GENERAL_NAMES) **plist, + STACK_OF(GENERAL_NAMES) **prto); + +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_CMS_strings(void); + +/* Error codes for the CMS functions. */ + +/* Function codes. */ +# define CMS_F_CHECK_CONTENT 99 +# define CMS_F_CMS_ADD0_CERT 164 +# define CMS_F_CMS_ADD0_RECIPIENT_KEY 100 +# define CMS_F_CMS_ADD0_RECIPIENT_PASSWORD 165 +# define CMS_F_CMS_ADD1_RECEIPTREQUEST 158 +# define CMS_F_CMS_ADD1_RECIPIENT_CERT 101 +# define CMS_F_CMS_ADD1_SIGNER 102 +# define CMS_F_CMS_ADD1_SIGNINGTIME 103 +# define CMS_F_CMS_COMPRESS 104 +# define CMS_F_CMS_COMPRESSEDDATA_CREATE 105 +# define CMS_F_CMS_COMPRESSEDDATA_INIT_BIO 106 +# define CMS_F_CMS_COPY_CONTENT 107 +# define CMS_F_CMS_COPY_MESSAGEDIGEST 108 +# define CMS_F_CMS_DATA 109 +# define CMS_F_CMS_DATAFINAL 110 +# define CMS_F_CMS_DATAINIT 111 +# define CMS_F_CMS_DECRYPT 112 +# define CMS_F_CMS_DECRYPT_SET1_KEY 113 +# define CMS_F_CMS_DECRYPT_SET1_PASSWORD 166 +# define CMS_F_CMS_DECRYPT_SET1_PKEY 114 +# define CMS_F_CMS_DIGESTALGORITHM_FIND_CTX 115 +# define CMS_F_CMS_DIGESTALGORITHM_INIT_BIO 116 +# define CMS_F_CMS_DIGESTEDDATA_DO_FINAL 117 +# define CMS_F_CMS_DIGEST_VERIFY 118 +# define CMS_F_CMS_ENCODE_RECEIPT 161 +# define CMS_F_CMS_ENCRYPT 119 +# define CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO 120 +# define CMS_F_CMS_ENCRYPTEDDATA_DECRYPT 121 +# define CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT 122 +# define CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY 123 +# define CMS_F_CMS_ENVELOPEDDATA_CREATE 124 +# define CMS_F_CMS_ENVELOPEDDATA_INIT_BIO 125 +# define CMS_F_CMS_ENVELOPED_DATA_INIT 126 +# define CMS_F_CMS_FINAL 127 +# define CMS_F_CMS_GET0_CERTIFICATE_CHOICES 128 +# define CMS_F_CMS_GET0_CONTENT 129 +# define CMS_F_CMS_GET0_ECONTENT_TYPE 130 +# define CMS_F_CMS_GET0_ENVELOPED 131 +# define CMS_F_CMS_GET0_REVOCATION_CHOICES 132 +# define CMS_F_CMS_GET0_SIGNED 133 +# define CMS_F_CMS_MSGSIGDIGEST_ADD1 162 +# define CMS_F_CMS_RECEIPTREQUEST_CREATE0 159 +# define CMS_F_CMS_RECEIPT_VERIFY 160 +# define CMS_F_CMS_RECIPIENTINFO_DECRYPT 134 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT 135 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT 136 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID 137 +# define CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP 138 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP 139 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT 140 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT 141 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS 142 +# define CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID 143 +# define CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT 167 +# define CMS_F_CMS_RECIPIENTINFO_SET0_KEY 144 +# define CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD 168 +# define CMS_F_CMS_RECIPIENTINFO_SET0_PKEY 145 +# define CMS_F_CMS_SET1_SIGNERIDENTIFIER 146 +# define CMS_F_CMS_SET_DETACHED 147 +# define CMS_F_CMS_SIGN 148 +# define CMS_F_CMS_SIGNED_DATA_INIT 149 +# define CMS_F_CMS_SIGNERINFO_CONTENT_SIGN 150 +# define CMS_F_CMS_SIGNERINFO_SIGN 151 +# define CMS_F_CMS_SIGNERINFO_VERIFY 152 +# define CMS_F_CMS_SIGNERINFO_VERIFY_CERT 153 +# define CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT 154 +# define CMS_F_CMS_SIGN_RECEIPT 163 +# define CMS_F_CMS_STREAM 155 +# define CMS_F_CMS_UNCOMPRESS 156 +# define CMS_F_CMS_VERIFY 157 + +/* Reason codes. */ +# define CMS_R_ADD_SIGNER_ERROR 99 +# define CMS_R_CERTIFICATE_ALREADY_PRESENT 175 +# define CMS_R_CERTIFICATE_HAS_NO_KEYID 160 +# define CMS_R_CERTIFICATE_VERIFY_ERROR 100 +# define CMS_R_CIPHER_INITIALISATION_ERROR 101 +# define CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR 102 +# define CMS_R_CMS_DATAFINAL_ERROR 103 +# define CMS_R_CMS_LIB 104 +# define CMS_R_CONTENTIDENTIFIER_MISMATCH 170 +# define CMS_R_CONTENT_NOT_FOUND 105 +# define CMS_R_CONTENT_TYPE_MISMATCH 171 +# define CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA 106 +# define CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA 107 +# define CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA 108 +# define CMS_R_CONTENT_VERIFY_ERROR 109 +# define CMS_R_CTRL_ERROR 110 +# define CMS_R_CTRL_FAILURE 111 +# define CMS_R_DECRYPT_ERROR 112 +# define CMS_R_DIGEST_ERROR 161 +# define CMS_R_ERROR_GETTING_PUBLIC_KEY 113 +# define CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE 114 +# define CMS_R_ERROR_SETTING_KEY 115 +# define CMS_R_ERROR_SETTING_RECIPIENTINFO 116 +# define CMS_R_INVALID_ENCRYPTED_KEY_LENGTH 117 +# define CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER 176 +# define CMS_R_INVALID_KEY_LENGTH 118 +# define CMS_R_MD_BIO_INIT_ERROR 119 +# define CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH 120 +# define CMS_R_MESSAGEDIGEST_WRONG_LENGTH 121 +# define CMS_R_MSGSIGDIGEST_ERROR 172 +# define CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE 162 +# define CMS_R_MSGSIGDIGEST_WRONG_LENGTH 163 +# define CMS_R_NEED_ONE_SIGNER 164 +# define CMS_R_NOT_A_SIGNED_RECEIPT 165 +# define CMS_R_NOT_ENCRYPTED_DATA 122 +# define CMS_R_NOT_KEK 123 +# define CMS_R_NOT_KEY_TRANSPORT 124 +# define CMS_R_NOT_PWRI 177 +# define CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 125 +# define CMS_R_NO_CIPHER 126 +# define CMS_R_NO_CONTENT 127 +# define CMS_R_NO_CONTENT_TYPE 173 +# define CMS_R_NO_DEFAULT_DIGEST 128 +# define CMS_R_NO_DIGEST_SET 129 +# define CMS_R_NO_KEY 130 +# define CMS_R_NO_KEY_OR_CERT 174 +# define CMS_R_NO_MATCHING_DIGEST 131 +# define CMS_R_NO_MATCHING_RECIPIENT 132 +# define CMS_R_NO_MATCHING_SIGNATURE 166 +# define CMS_R_NO_MSGSIGDIGEST 167 +# define CMS_R_NO_PASSWORD 178 +# define CMS_R_NO_PRIVATE_KEY 133 +# define CMS_R_NO_PUBLIC_KEY 134 +# define CMS_R_NO_RECEIPT_REQUEST 168 +# define CMS_R_NO_SIGNERS 135 +# define CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 136 +# define CMS_R_RECEIPT_DECODE_ERROR 169 +# define CMS_R_RECIPIENT_ERROR 137 +# define CMS_R_SIGNER_CERTIFICATE_NOT_FOUND 138 +# define CMS_R_SIGNFINAL_ERROR 139 +# define CMS_R_SMIME_TEXT_ERROR 140 +# define CMS_R_STORE_INIT_ERROR 141 +# define CMS_R_TYPE_NOT_COMPRESSED_DATA 142 +# define CMS_R_TYPE_NOT_DATA 143 +# define CMS_R_TYPE_NOT_DIGESTED_DATA 144 +# define CMS_R_TYPE_NOT_ENCRYPTED_DATA 145 +# define CMS_R_TYPE_NOT_ENVELOPED_DATA 146 +# define CMS_R_UNABLE_TO_FINALIZE_CONTEXT 147 +# define CMS_R_UNKNOWN_CIPHER 148 +# define CMS_R_UNKNOWN_DIGEST_ALGORIHM 149 +# define CMS_R_UNKNOWN_ID 150 +# define CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM 151 +# define CMS_R_UNSUPPORTED_CONTENT_TYPE 152 +# define CMS_R_UNSUPPORTED_KEK_ALGORITHM 153 +# define CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM 179 +# define CMS_R_UNSUPPORTED_RECIPIENT_TYPE 154 +# define CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE 155 +# define CMS_R_UNSUPPORTED_TYPE 156 +# define CMS_R_UNWRAP_ERROR 157 +# define CMS_R_UNWRAP_FAILURE 180 +# define CMS_R_VERIFICATION_FAILURE 158 +# define CMS_R_WRAP_ERROR 159 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/cms/cms_asn1.c b/libs/openssl/crypto/cms/cms_asn1.c new file mode 100644 index 00000000..f9f267af --- /dev/null +++ b/libs/openssl/crypto/cms/cms_asn1.c @@ -0,0 +1,381 @@ +/* crypto/cms/cms_asn1.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include "cms.h" +#include "cms_lcl.h" + + +ASN1_SEQUENCE(CMS_IssuerAndSerialNumber) = { + ASN1_SIMPLE(CMS_IssuerAndSerialNumber, issuer, X509_NAME), + ASN1_SIMPLE(CMS_IssuerAndSerialNumber, serialNumber, ASN1_INTEGER) +} ASN1_SEQUENCE_END(CMS_IssuerAndSerialNumber) + +ASN1_SEQUENCE(CMS_OtherCertificateFormat) = { + ASN1_SIMPLE(CMS_OtherCertificateFormat, otherCertFormat, ASN1_OBJECT), + ASN1_OPT(CMS_OtherCertificateFormat, otherCert, ASN1_ANY) +} ASN1_SEQUENCE_END(CMS_OtherCertificateFormat) + +ASN1_CHOICE(CMS_CertificateChoices) = { + ASN1_SIMPLE(CMS_CertificateChoices, d.certificate, X509), + ASN1_IMP(CMS_CertificateChoices, d.extendedCertificate, ASN1_SEQUENCE, 0), + ASN1_IMP(CMS_CertificateChoices, d.v1AttrCert, ASN1_SEQUENCE, 1), + ASN1_IMP(CMS_CertificateChoices, d.v2AttrCert, ASN1_SEQUENCE, 2), + ASN1_IMP(CMS_CertificateChoices, d.other, CMS_OtherCertificateFormat, 3) +} ASN1_CHOICE_END(CMS_CertificateChoices) + +ASN1_CHOICE(CMS_SignerIdentifier) = { + ASN1_SIMPLE(CMS_SignerIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber), + ASN1_IMP(CMS_SignerIdentifier, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0) +} ASN1_CHOICE_END(CMS_SignerIdentifier) + +ASN1_NDEF_SEQUENCE(CMS_EncapsulatedContentInfo) = { + ASN1_SIMPLE(CMS_EncapsulatedContentInfo, eContentType, ASN1_OBJECT), + ASN1_NDEF_EXP_OPT(CMS_EncapsulatedContentInfo, eContent, ASN1_OCTET_STRING_NDEF, 0) +} ASN1_NDEF_SEQUENCE_END(CMS_EncapsulatedContentInfo) + +/* Minor tweak to operation: free up signer key, cert */ +static int cms_si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_FREE_POST) { + CMS_SignerInfo *si = (CMS_SignerInfo *)*pval; + if (si->pkey) + EVP_PKEY_free(si->pkey); + if (si->signer) + X509_free(si->signer); + } + return 1; +} + +ASN1_SEQUENCE_cb(CMS_SignerInfo, cms_si_cb) = { + ASN1_SIMPLE(CMS_SignerInfo, version, LONG), + ASN1_SIMPLE(CMS_SignerInfo, sid, CMS_SignerIdentifier), + ASN1_SIMPLE(CMS_SignerInfo, digestAlgorithm, X509_ALGOR), + ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, signedAttrs, X509_ATTRIBUTE, 0), + ASN1_SIMPLE(CMS_SignerInfo, signatureAlgorithm, X509_ALGOR), + ASN1_SIMPLE(CMS_SignerInfo, signature, ASN1_OCTET_STRING), + ASN1_IMP_SET_OF_OPT(CMS_SignerInfo, unsignedAttrs, X509_ATTRIBUTE, 1) +} ASN1_SEQUENCE_END_cb(CMS_SignerInfo, CMS_SignerInfo) + +ASN1_SEQUENCE(CMS_OtherRevocationInfoFormat) = { + ASN1_SIMPLE(CMS_OtherRevocationInfoFormat, otherRevInfoFormat, ASN1_OBJECT), + ASN1_OPT(CMS_OtherRevocationInfoFormat, otherRevInfo, ASN1_ANY) +} ASN1_SEQUENCE_END(CMS_OtherRevocationInfoFormat) + +ASN1_CHOICE(CMS_RevocationInfoChoice) = { + ASN1_SIMPLE(CMS_RevocationInfoChoice, d.crl, X509_CRL), + ASN1_IMP(CMS_RevocationInfoChoice, d.other, CMS_OtherRevocationInfoFormat, 1) +} ASN1_CHOICE_END(CMS_RevocationInfoChoice) + +ASN1_NDEF_SEQUENCE(CMS_SignedData) = { + ASN1_SIMPLE(CMS_SignedData, version, LONG), + ASN1_SET_OF(CMS_SignedData, digestAlgorithms, X509_ALGOR), + ASN1_SIMPLE(CMS_SignedData, encapContentInfo, CMS_EncapsulatedContentInfo), + ASN1_IMP_SET_OF_OPT(CMS_SignedData, certificates, CMS_CertificateChoices, 0), + ASN1_IMP_SET_OF_OPT(CMS_SignedData, crls, CMS_RevocationInfoChoice, 1), + ASN1_SET_OF(CMS_SignedData, signerInfos, CMS_SignerInfo) +} ASN1_NDEF_SEQUENCE_END(CMS_SignedData) + +ASN1_SEQUENCE(CMS_OriginatorInfo) = { + ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, certificates, CMS_CertificateChoices, 0), + ASN1_IMP_SET_OF_OPT(CMS_OriginatorInfo, crls, CMS_RevocationInfoChoice, 1) +} ASN1_SEQUENCE_END(CMS_OriginatorInfo) + +ASN1_NDEF_SEQUENCE(CMS_EncryptedContentInfo) = { + ASN1_SIMPLE(CMS_EncryptedContentInfo, contentType, ASN1_OBJECT), + ASN1_SIMPLE(CMS_EncryptedContentInfo, contentEncryptionAlgorithm, X509_ALGOR), + ASN1_IMP_OPT(CMS_EncryptedContentInfo, encryptedContent, ASN1_OCTET_STRING_NDEF, 0) +} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedContentInfo) + +ASN1_SEQUENCE(CMS_KeyTransRecipientInfo) = { + ASN1_SIMPLE(CMS_KeyTransRecipientInfo, version, LONG), + ASN1_SIMPLE(CMS_KeyTransRecipientInfo, rid, CMS_SignerIdentifier), + ASN1_SIMPLE(CMS_KeyTransRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), + ASN1_SIMPLE(CMS_KeyTransRecipientInfo, encryptedKey, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(CMS_KeyTransRecipientInfo) + +ASN1_SEQUENCE(CMS_OtherKeyAttribute) = { + ASN1_SIMPLE(CMS_OtherKeyAttribute, keyAttrId, ASN1_OBJECT), + ASN1_OPT(CMS_OtherKeyAttribute, keyAttr, ASN1_ANY) +} ASN1_SEQUENCE_END(CMS_OtherKeyAttribute) + +ASN1_SEQUENCE(CMS_RecipientKeyIdentifier) = { + ASN1_SIMPLE(CMS_RecipientKeyIdentifier, subjectKeyIdentifier, ASN1_OCTET_STRING), + ASN1_OPT(CMS_RecipientKeyIdentifier, date, ASN1_GENERALIZEDTIME), + ASN1_OPT(CMS_RecipientKeyIdentifier, other, CMS_OtherKeyAttribute) +} ASN1_SEQUENCE_END(CMS_RecipientKeyIdentifier) + +ASN1_CHOICE(CMS_KeyAgreeRecipientIdentifier) = { + ASN1_SIMPLE(CMS_KeyAgreeRecipientIdentifier, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber), + ASN1_IMP(CMS_KeyAgreeRecipientIdentifier, d.rKeyId, CMS_RecipientKeyIdentifier, 0) +} ASN1_CHOICE_END(CMS_KeyAgreeRecipientIdentifier) + +ASN1_SEQUENCE(CMS_RecipientEncryptedKey) = { + ASN1_SIMPLE(CMS_RecipientEncryptedKey, rid, CMS_KeyAgreeRecipientIdentifier), + ASN1_SIMPLE(CMS_RecipientEncryptedKey, encryptedKey, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(CMS_RecipientEncryptedKey) + +ASN1_SEQUENCE(CMS_OriginatorPublicKey) = { + ASN1_SIMPLE(CMS_OriginatorPublicKey, algorithm, X509_ALGOR), + ASN1_SIMPLE(CMS_OriginatorPublicKey, publicKey, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(CMS_OriginatorPublicKey) + +ASN1_CHOICE(CMS_OriginatorIdentifierOrKey) = { + ASN1_SIMPLE(CMS_OriginatorIdentifierOrKey, d.issuerAndSerialNumber, CMS_IssuerAndSerialNumber), + ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.subjectKeyIdentifier, ASN1_OCTET_STRING, 0), + ASN1_IMP(CMS_OriginatorIdentifierOrKey, d.originatorKey, CMS_OriginatorPublicKey, 1) +} ASN1_CHOICE_END(CMS_OriginatorIdentifierOrKey) + +ASN1_SEQUENCE(CMS_KeyAgreeRecipientInfo) = { + ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, version, LONG), + ASN1_EXP(CMS_KeyAgreeRecipientInfo, originator, CMS_OriginatorIdentifierOrKey, 0), + ASN1_EXP_OPT(CMS_KeyAgreeRecipientInfo, ukm, ASN1_OCTET_STRING, 1), + ASN1_SIMPLE(CMS_KeyAgreeRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), + ASN1_SEQUENCE_OF(CMS_KeyAgreeRecipientInfo, recipientEncryptedKeys, CMS_RecipientEncryptedKey) +} ASN1_SEQUENCE_END(CMS_KeyAgreeRecipientInfo) + +ASN1_SEQUENCE(CMS_KEKIdentifier) = { + ASN1_SIMPLE(CMS_KEKIdentifier, keyIdentifier, ASN1_OCTET_STRING), + ASN1_OPT(CMS_KEKIdentifier, date, ASN1_GENERALIZEDTIME), + ASN1_OPT(CMS_KEKIdentifier, other, CMS_OtherKeyAttribute) +} ASN1_SEQUENCE_END(CMS_KEKIdentifier) + +ASN1_SEQUENCE(CMS_KEKRecipientInfo) = { + ASN1_SIMPLE(CMS_KEKRecipientInfo, version, LONG), + ASN1_SIMPLE(CMS_KEKRecipientInfo, kekid, CMS_KEKIdentifier), + ASN1_SIMPLE(CMS_KEKRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), + ASN1_SIMPLE(CMS_KEKRecipientInfo, encryptedKey, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(CMS_KEKRecipientInfo) + +ASN1_SEQUENCE(CMS_PasswordRecipientInfo) = { + ASN1_SIMPLE(CMS_PasswordRecipientInfo, version, LONG), + ASN1_IMP_OPT(CMS_PasswordRecipientInfo, keyDerivationAlgorithm, X509_ALGOR, 0), + ASN1_SIMPLE(CMS_PasswordRecipientInfo, keyEncryptionAlgorithm, X509_ALGOR), + ASN1_SIMPLE(CMS_PasswordRecipientInfo, encryptedKey, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(CMS_PasswordRecipientInfo) + +ASN1_SEQUENCE(CMS_OtherRecipientInfo) = { + ASN1_SIMPLE(CMS_OtherRecipientInfo, oriType, ASN1_OBJECT), + ASN1_OPT(CMS_OtherRecipientInfo, oriValue, ASN1_ANY) +} ASN1_SEQUENCE_END(CMS_OtherRecipientInfo) + +/* Free up RecipientInfo additional data */ +static int cms_ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_FREE_PRE) { + CMS_RecipientInfo *ri = (CMS_RecipientInfo *)*pval; + if (ri->type == CMS_RECIPINFO_TRANS) { + CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; + if (ktri->pkey) + EVP_PKEY_free(ktri->pkey); + if (ktri->recip) + X509_free(ktri->recip); + } else if (ri->type == CMS_RECIPINFO_KEK) { + CMS_KEKRecipientInfo *kekri = ri->d.kekri; + if (kekri->key) { + OPENSSL_cleanse(kekri->key, kekri->keylen); + OPENSSL_free(kekri->key); + } + } else if (ri->type == CMS_RECIPINFO_PASS) { + CMS_PasswordRecipientInfo *pwri = ri->d.pwri; + if (pwri->pass) { + OPENSSL_cleanse(pwri->pass, pwri->passlen); + OPENSSL_free(pwri->pass); + } + } + } + return 1; +} + +ASN1_CHOICE_cb(CMS_RecipientInfo, cms_ri_cb) = { + ASN1_SIMPLE(CMS_RecipientInfo, d.ktri, CMS_KeyTransRecipientInfo), + ASN1_IMP(CMS_RecipientInfo, d.kari, CMS_KeyAgreeRecipientInfo, 1), + ASN1_IMP(CMS_RecipientInfo, d.kekri, CMS_KEKRecipientInfo, 2), + ASN1_IMP(CMS_RecipientInfo, d.pwri, CMS_PasswordRecipientInfo, 3), + ASN1_IMP(CMS_RecipientInfo, d.ori, CMS_OtherRecipientInfo, 4) +} ASN1_CHOICE_END_cb(CMS_RecipientInfo, CMS_RecipientInfo, type) + +ASN1_NDEF_SEQUENCE(CMS_EnvelopedData) = { + ASN1_SIMPLE(CMS_EnvelopedData, version, LONG), + ASN1_IMP_OPT(CMS_EnvelopedData, originatorInfo, CMS_OriginatorInfo, 0), + ASN1_SET_OF(CMS_EnvelopedData, recipientInfos, CMS_RecipientInfo), + ASN1_SIMPLE(CMS_EnvelopedData, encryptedContentInfo, CMS_EncryptedContentInfo), + ASN1_IMP_SET_OF_OPT(CMS_EnvelopedData, unprotectedAttrs, X509_ATTRIBUTE, 1) +} ASN1_NDEF_SEQUENCE_END(CMS_EnvelopedData) + +ASN1_NDEF_SEQUENCE(CMS_DigestedData) = { + ASN1_SIMPLE(CMS_DigestedData, version, LONG), + ASN1_SIMPLE(CMS_DigestedData, digestAlgorithm, X509_ALGOR), + ASN1_SIMPLE(CMS_DigestedData, encapContentInfo, CMS_EncapsulatedContentInfo), + ASN1_SIMPLE(CMS_DigestedData, digest, ASN1_OCTET_STRING) +} ASN1_NDEF_SEQUENCE_END(CMS_DigestedData) + +ASN1_NDEF_SEQUENCE(CMS_EncryptedData) = { + ASN1_SIMPLE(CMS_EncryptedData, version, LONG), + ASN1_SIMPLE(CMS_EncryptedData, encryptedContentInfo, CMS_EncryptedContentInfo), + ASN1_IMP_SET_OF_OPT(CMS_EncryptedData, unprotectedAttrs, X509_ATTRIBUTE, 1) +} ASN1_NDEF_SEQUENCE_END(CMS_EncryptedData) + +ASN1_NDEF_SEQUENCE(CMS_AuthenticatedData) = { + ASN1_SIMPLE(CMS_AuthenticatedData, version, LONG), + ASN1_IMP_OPT(CMS_AuthenticatedData, originatorInfo, CMS_OriginatorInfo, 0), + ASN1_SET_OF(CMS_AuthenticatedData, recipientInfos, CMS_RecipientInfo), + ASN1_SIMPLE(CMS_AuthenticatedData, macAlgorithm, X509_ALGOR), + ASN1_IMP(CMS_AuthenticatedData, digestAlgorithm, X509_ALGOR, 1), + ASN1_SIMPLE(CMS_AuthenticatedData, encapContentInfo, CMS_EncapsulatedContentInfo), + ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, authAttrs, X509_ALGOR, 2), + ASN1_SIMPLE(CMS_AuthenticatedData, mac, ASN1_OCTET_STRING), + ASN1_IMP_SET_OF_OPT(CMS_AuthenticatedData, unauthAttrs, X509_ALGOR, 3) +} ASN1_NDEF_SEQUENCE_END(CMS_AuthenticatedData) + +ASN1_NDEF_SEQUENCE(CMS_CompressedData) = { + ASN1_SIMPLE(CMS_CompressedData, version, LONG), + ASN1_SIMPLE(CMS_CompressedData, compressionAlgorithm, X509_ALGOR), + ASN1_SIMPLE(CMS_CompressedData, encapContentInfo, CMS_EncapsulatedContentInfo), +} ASN1_NDEF_SEQUENCE_END(CMS_CompressedData) + +/* This is the ANY DEFINED BY table for the top level ContentInfo structure */ + +ASN1_ADB_TEMPLATE(cms_default) = ASN1_EXP(CMS_ContentInfo, d.other, ASN1_ANY, 0); + +ASN1_ADB(CMS_ContentInfo) = { + ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP(CMS_ContentInfo, d.data, ASN1_OCTET_STRING_NDEF, 0)), + ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP(CMS_ContentInfo, d.signedData, CMS_SignedData, 0)), + ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP(CMS_ContentInfo, d.envelopedData, CMS_EnvelopedData, 0)), + ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP(CMS_ContentInfo, d.digestedData, CMS_DigestedData, 0)), + ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP(CMS_ContentInfo, d.encryptedData, CMS_EncryptedData, 0)), + ADB_ENTRY(NID_id_smime_ct_authData, ASN1_NDEF_EXP(CMS_ContentInfo, d.authenticatedData, CMS_AuthenticatedData, 0)), + ADB_ENTRY(NID_id_smime_ct_compressedData, ASN1_NDEF_EXP(CMS_ContentInfo, d.compressedData, CMS_CompressedData, 0)), +} ASN1_ADB_END(CMS_ContentInfo, 0, contentType, 0, &cms_default_tt, NULL); + +/* CMS streaming support */ +static int cms_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + ASN1_STREAM_ARG *sarg = exarg; + CMS_ContentInfo *cms = NULL; + if (pval) + cms = (CMS_ContentInfo *)*pval; + else + return 1; + switch (operation) { + + case ASN1_OP_STREAM_PRE: + if (CMS_stream(&sarg->boundary, cms) <= 0) + return 0; + case ASN1_OP_DETACHED_PRE: + sarg->ndef_bio = CMS_dataInit(cms, sarg->out); + if (!sarg->ndef_bio) + return 0; + break; + + case ASN1_OP_STREAM_POST: + case ASN1_OP_DETACHED_POST: + if (CMS_dataFinal(cms, sarg->ndef_bio) <= 0) + return 0; + break; + + } + return 1; +} + +ASN1_NDEF_SEQUENCE_cb(CMS_ContentInfo, cms_cb) = { + ASN1_SIMPLE(CMS_ContentInfo, contentType, ASN1_OBJECT), + ASN1_ADB_OBJECT(CMS_ContentInfo) +} ASN1_NDEF_SEQUENCE_END_cb(CMS_ContentInfo, CMS_ContentInfo) + +/* Specials for signed attributes */ + +/* + * When signing attributes we want to reorder them to match the sorted + * encoding. + */ + +ASN1_ITEM_TEMPLATE(CMS_Attributes_Sign) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, CMS_ATTRIBUTES, X509_ATTRIBUTE) +ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Sign) + +/* + * When verifying attributes we need to use the received order. So we use + * SEQUENCE OF and tag it to SET OF + */ + +ASN1_ITEM_TEMPLATE(CMS_Attributes_Verify) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, + V_ASN1_SET, CMS_ATTRIBUTES, X509_ATTRIBUTE) +ASN1_ITEM_TEMPLATE_END(CMS_Attributes_Verify) + + + +ASN1_CHOICE(CMS_ReceiptsFrom) = { + ASN1_IMP(CMS_ReceiptsFrom, d.allOrFirstTier, LONG, 0), + ASN1_IMP_SEQUENCE_OF(CMS_ReceiptsFrom, d.receiptList, GENERAL_NAMES, 1) +} ASN1_CHOICE_END(CMS_ReceiptsFrom) + +ASN1_SEQUENCE(CMS_ReceiptRequest) = { + ASN1_SIMPLE(CMS_ReceiptRequest, signedContentIdentifier, ASN1_OCTET_STRING), + ASN1_SIMPLE(CMS_ReceiptRequest, receiptsFrom, CMS_ReceiptsFrom), + ASN1_SEQUENCE_OF(CMS_ReceiptRequest, receiptsTo, GENERAL_NAMES) +} ASN1_SEQUENCE_END(CMS_ReceiptRequest) + +ASN1_SEQUENCE(CMS_Receipt) = { + ASN1_SIMPLE(CMS_Receipt, version, LONG), + ASN1_SIMPLE(CMS_Receipt, contentType, ASN1_OBJECT), + ASN1_SIMPLE(CMS_Receipt, signedContentIdentifier, ASN1_OCTET_STRING), + ASN1_SIMPLE(CMS_Receipt, originatorSignatureValue, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(CMS_Receipt) diff --git a/libs/openssl/crypto/cms/cms_att.c b/libs/openssl/crypto/cms/cms_att.c new file mode 100644 index 00000000..f79a49d5 --- /dev/null +++ b/libs/openssl/crypto/cms/cms_att.c @@ -0,0 +1,197 @@ +/* crypto/cms/cms_att.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include "cms.h" +#include "cms_lcl.h" + +/* CMS SignedData Attribute utilities */ + +int CMS_signed_get_attr_count(const CMS_SignerInfo *si) +{ + return X509at_get_attr_count(si->signedAttrs); +} + +int CMS_signed_get_attr_by_NID(const CMS_SignerInfo *si, int nid, int lastpos) +{ + return X509at_get_attr_by_NID(si->signedAttrs, nid, lastpos); +} + +int CMS_signed_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(si->signedAttrs, obj, lastpos); +} + +X509_ATTRIBUTE *CMS_signed_get_attr(const CMS_SignerInfo *si, int loc) +{ + return X509at_get_attr(si->signedAttrs, loc); +} + +X509_ATTRIBUTE *CMS_signed_delete_attr(CMS_SignerInfo *si, int loc) +{ + return X509at_delete_attr(si->signedAttrs, loc); +} + +int CMS_signed_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr) +{ + if (X509at_add1_attr(&si->signedAttrs, attr)) + return 1; + return 0; +} + +int CMS_signed_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len) +{ + if (X509at_add1_attr_by_OBJ(&si->signedAttrs, obj, type, bytes, len)) + return 1; + return 0; +} + +int CMS_signed_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, const void *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&si->signedAttrs, nid, type, bytes, len)) + return 1; + return 0; +} + +int CMS_signed_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&si->signedAttrs, attrname, type, bytes, len)) + return 1; + return 0; +} + +void *CMS_signed_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type) +{ + return X509at_get0_data_by_OBJ(si->signedAttrs, oid, lastpos, type); +} + +int CMS_unsigned_get_attr_count(const CMS_SignerInfo *si) +{ + return X509at_get_attr_count(si->unsignedAttrs); +} + +int CMS_unsigned_get_attr_by_NID(const CMS_SignerInfo *si, int nid, + int lastpos) +{ + return X509at_get_attr_by_NID(si->unsignedAttrs, nid, lastpos); +} + +int CMS_unsigned_get_attr_by_OBJ(const CMS_SignerInfo *si, ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(si->unsignedAttrs, obj, lastpos); +} + +X509_ATTRIBUTE *CMS_unsigned_get_attr(const CMS_SignerInfo *si, int loc) +{ + return X509at_get_attr(si->unsignedAttrs, loc); +} + +X509_ATTRIBUTE *CMS_unsigned_delete_attr(CMS_SignerInfo *si, int loc) +{ + return X509at_delete_attr(si->unsignedAttrs, loc); +} + +int CMS_unsigned_add1_attr(CMS_SignerInfo *si, X509_ATTRIBUTE *attr) +{ + if (X509at_add1_attr(&si->unsignedAttrs, attr)) + return 1; + return 0; +} + +int CMS_unsigned_add1_attr_by_OBJ(CMS_SignerInfo *si, + const ASN1_OBJECT *obj, int type, + const void *bytes, int len) +{ + if (X509at_add1_attr_by_OBJ(&si->unsignedAttrs, obj, type, bytes, len)) + return 1; + return 0; +} + +int CMS_unsigned_add1_attr_by_NID(CMS_SignerInfo *si, + int nid, int type, + const void *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&si->unsignedAttrs, nid, type, bytes, len)) + return 1; + return 0; +} + +int CMS_unsigned_add1_attr_by_txt(CMS_SignerInfo *si, + const char *attrname, int type, + const void *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&si->unsignedAttrs, attrname, + type, bytes, len)) + return 1; + return 0; +} + +void *CMS_unsigned_get0_data_by_OBJ(CMS_SignerInfo *si, ASN1_OBJECT *oid, + int lastpos, int type) +{ + return X509at_get0_data_by_OBJ(si->unsignedAttrs, oid, lastpos, type); +} + +/* Specific attribute cases */ diff --git a/libs/openssl/crypto/cms/cms_cd.c b/libs/openssl/crypto/cms/cms_cd.c new file mode 100644 index 00000000..aa3238f5 --- /dev/null +++ b/libs/openssl/crypto/cms/cms_cd.c @@ -0,0 +1,134 @@ +/* crypto/cms/cms_cd.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_COMP +# include +#endif +#include "cms_lcl.h" + +DECLARE_ASN1_ITEM(CMS_CompressedData) + +#ifdef ZLIB + +/* CMS CompressedData Utilities */ + +CMS_ContentInfo *cms_CompressedData_create(int comp_nid) +{ + CMS_ContentInfo *cms; + CMS_CompressedData *cd; + /* + * Will need something cleverer if there is ever more than one + * compression algorithm or parameters have some meaning... + */ + if (comp_nid != NID_zlib_compression) { + CMSerr(CMS_F_CMS_COMPRESSEDDATA_CREATE, + CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + return NULL; + } + cms = CMS_ContentInfo_new(); + if (!cms) + return NULL; + + cd = M_ASN1_new_of(CMS_CompressedData); + + if (!cd) + goto err; + + cms->contentType = OBJ_nid2obj(NID_id_smime_ct_compressedData); + cms->d.compressedData = cd; + + cd->version = 0; + + X509_ALGOR_set0(cd->compressionAlgorithm, + OBJ_nid2obj(NID_zlib_compression), V_ASN1_UNDEF, NULL); + + cd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data); + + return cms; + + err: + + if (cms) + CMS_ContentInfo_free(cms); + + return NULL; +} + +BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms) +{ + CMS_CompressedData *cd; + ASN1_OBJECT *compoid; + if (OBJ_obj2nid(cms->contentType) != NID_id_smime_ct_compressedData) { + CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, + CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA); + return NULL; + } + cd = cms->d.compressedData; + X509_ALGOR_get0(&compoid, NULL, NULL, cd->compressionAlgorithm); + if (OBJ_obj2nid(compoid) != NID_zlib_compression) { + CMSerr(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO, + CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + return NULL; + } + return BIO_new(BIO_f_zlib()); +} + +#endif diff --git a/libs/openssl/crypto/cms/cms_dd.c b/libs/openssl/crypto/cms/cms_dd.c new file mode 100644 index 00000000..23e9f2d3 --- /dev/null +++ b/libs/openssl/crypto/cms/cms_dd.c @@ -0,0 +1,145 @@ +/* crypto/cms/cms_dd.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include "cms_lcl.h" + +DECLARE_ASN1_ITEM(CMS_DigestedData) + +/* CMS DigestedData Utilities */ + +CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md) +{ + CMS_ContentInfo *cms; + CMS_DigestedData *dd; + cms = CMS_ContentInfo_new(); + if (!cms) + return NULL; + + dd = M_ASN1_new_of(CMS_DigestedData); + + if (!dd) + goto err; + + cms->contentType = OBJ_nid2obj(NID_pkcs7_digest); + cms->d.digestedData = dd; + + dd->version = 0; + dd->encapContentInfo->eContentType = OBJ_nid2obj(NID_pkcs7_data); + + cms_DigestAlgorithm_set(dd->digestAlgorithm, md); + + return cms; + + err: + + if (cms) + CMS_ContentInfo_free(cms); + + return NULL; +} + +BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms) +{ + CMS_DigestedData *dd; + dd = cms->d.digestedData; + return cms_DigestAlgorithm_init_bio(dd->digestAlgorithm); +} + +int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify) +{ + EVP_MD_CTX mctx; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + int r = 0; + CMS_DigestedData *dd; + EVP_MD_CTX_init(&mctx); + + dd = cms->d.digestedData; + + if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, dd->digestAlgorithm)) + goto err; + + if (EVP_DigestFinal_ex(&mctx, md, &mdlen) <= 0) + goto err; + + if (verify) { + if (mdlen != (unsigned int)dd->digest->length) { + CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, + CMS_R_MESSAGEDIGEST_WRONG_LENGTH); + goto err; + } + + if (memcmp(md, dd->digest->data, mdlen)) + CMSerr(CMS_F_CMS_DIGESTEDDATA_DO_FINAL, + CMS_R_VERIFICATION_FAILURE); + else + r = 1; + } else { + if (!ASN1_STRING_set(dd->digest, md, mdlen)) + goto err; + r = 1; + } + + err: + EVP_MD_CTX_cleanup(&mctx); + + return r; + +} diff --git a/libs/openssl/crypto/cms/cms_enc.c b/libs/openssl/crypto/cms/cms_enc.c new file mode 100644 index 00000000..b14b4b68 --- /dev/null +++ b/libs/openssl/crypto/cms/cms_enc.c @@ -0,0 +1,260 @@ +/* crypto/cms/cms_enc.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include "cms_lcl.h" + +/* CMS EncryptedData Utilities */ + +DECLARE_ASN1_ITEM(CMS_EncryptedData) + +/* Return BIO based on EncryptedContentInfo and key */ + +BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec) +{ + BIO *b; + EVP_CIPHER_CTX *ctx; + const EVP_CIPHER *ciph; + X509_ALGOR *calg = ec->contentEncryptionAlgorithm; + unsigned char iv[EVP_MAX_IV_LENGTH], *piv = NULL; + unsigned char *tkey = NULL; + size_t tkeylen = 0; + + int ok = 0; + + int enc, keep_key = 0; + + enc = ec->cipher ? 1 : 0; + + b = BIO_new(BIO_f_cipher()); + if (!b) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); + return NULL; + } + + BIO_get_cipher_ctx(b, &ctx); + + if (enc) { + ciph = ec->cipher; + /* + * If not keeping key set cipher to NULL so subsequent calls decrypt. + */ + if (ec->key) + ec->cipher = NULL; + } else { + ciph = EVP_get_cipherbyobj(calg->algorithm); + + if (!ciph) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, CMS_R_UNKNOWN_CIPHER); + goto err; + } + } + + if (EVP_CipherInit_ex(ctx, ciph, NULL, NULL, NULL, enc) <= 0) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_CIPHER_INITIALISATION_ERROR); + goto err; + } + + if (enc) { + int ivlen; + calg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(ctx)); + /* Generate a random IV if we need one */ + ivlen = EVP_CIPHER_CTX_iv_length(ctx); + if (ivlen > 0) { + if (RAND_pseudo_bytes(iv, ivlen) <= 0) + goto err; + piv = iv; + } + } else if (EVP_CIPHER_asn1_to_param(ctx, calg->parameter) <= 0) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + tkeylen = EVP_CIPHER_CTX_key_length(ctx); + /* Generate random session key */ + if (!enc || !ec->key) { + tkey = OPENSSL_malloc(tkeylen); + if (!tkey) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + if (EVP_CIPHER_CTX_rand_key(ctx, tkey) <= 0) + goto err; + } + + if (!ec->key) { + ec->key = tkey; + ec->keylen = tkeylen; + tkey = NULL; + if (enc) + keep_key = 1; + else + ERR_clear_error(); + + } + + if (ec->keylen != tkeylen) { + /* If necessary set key length */ + if (EVP_CIPHER_CTX_set_key_length(ctx, ec->keylen) <= 0) { + /* + * Only reveal failure if debugging so we don't leak information + * which may be useful in MMA. + */ + if (enc || ec->debug) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_INVALID_KEY_LENGTH); + goto err; + } else { + /* Use random key */ + OPENSSL_cleanse(ec->key, ec->keylen); + OPENSSL_free(ec->key); + ec->key = tkey; + ec->keylen = tkeylen; + tkey = NULL; + ERR_clear_error(); + } + } + } + + if (EVP_CipherInit_ex(ctx, NULL, NULL, ec->key, piv, enc) <= 0) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_CIPHER_INITIALISATION_ERROR); + goto err; + } + + if (piv) { + calg->parameter = ASN1_TYPE_new(); + if (!calg->parameter) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + if (EVP_CIPHER_param_to_asn1(ctx, calg->parameter) <= 0) { + CMSerr(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO, + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + } + ok = 1; + + err: + if (ec->key && (!keep_key || !ok)) { + OPENSSL_cleanse(ec->key, ec->keylen); + OPENSSL_free(ec->key); + ec->key = NULL; + } + if (tkey) { + OPENSSL_cleanse(tkey, tkeylen); + OPENSSL_free(tkey); + } + if (ok) + return b; + BIO_free(b); + return NULL; +} + +int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, + const EVP_CIPHER *cipher, + const unsigned char *key, size_t keylen) +{ + ec->cipher = cipher; + if (key) { + ec->key = OPENSSL_malloc(keylen); + if (!ec->key) + return 0; + memcpy(ec->key, key, keylen); + } + ec->keylen = keylen; + if (cipher) + ec->contentType = OBJ_nid2obj(NID_pkcs7_data); + return 1; +} + +int CMS_EncryptedData_set1_key(CMS_ContentInfo *cms, const EVP_CIPHER *ciph, + const unsigned char *key, size_t keylen) +{ + CMS_EncryptedContentInfo *ec; + if (!key || !keylen) { + CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NO_KEY); + return 0; + } + if (ciph) { + cms->d.encryptedData = M_ASN1_new_of(CMS_EncryptedData); + if (!cms->d.encryptedData) { + CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, ERR_R_MALLOC_FAILURE); + return 0; + } + cms->contentType = OBJ_nid2obj(NID_pkcs7_encrypted); + cms->d.encryptedData->version = 0; + } else if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_encrypted) { + CMSerr(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY, CMS_R_NOT_ENCRYPTED_DATA); + return 0; + } + ec = cms->d.encryptedData->encryptedContentInfo; + return cms_EncryptedContent_init(ec, ciph, key, keylen); +} + +BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms) +{ + CMS_EncryptedData *enc = cms->d.encryptedData; + if (enc->encryptedContentInfo->cipher && enc->unprotectedAttrs) + enc->version = 2; + return cms_EncryptedContent_init_bio(enc->encryptedContentInfo); +} diff --git a/libs/openssl/crypto/cms/cms_env.c b/libs/openssl/crypto/cms/cms_env.c new file mode 100644 index 00000000..1c3046ce --- /dev/null +++ b/libs/openssl/crypto/cms/cms_env.c @@ -0,0 +1,814 @@ +/* crypto/cms/cms_env.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include +#include "cms_lcl.h" +#include "asn1_locl.h" + +/* CMS EnvelopedData Utilities */ + +DECLARE_ASN1_ITEM(CMS_EnvelopedData) +DECLARE_ASN1_ITEM(CMS_KeyTransRecipientInfo) +DECLARE_ASN1_ITEM(CMS_KEKRecipientInfo) +DECLARE_ASN1_ITEM(CMS_OtherKeyAttribute) + +DECLARE_STACK_OF(CMS_RecipientInfo) + +CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms) +{ + if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_enveloped) { + CMSerr(CMS_F_CMS_GET0_ENVELOPED, + CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA); + return NULL; + } + return cms->d.envelopedData; +} + +static CMS_EnvelopedData *cms_enveloped_data_init(CMS_ContentInfo *cms) +{ + if (cms->d.other == NULL) { + cms->d.envelopedData = M_ASN1_new_of(CMS_EnvelopedData); + if (!cms->d.envelopedData) { + CMSerr(CMS_F_CMS_ENVELOPED_DATA_INIT, ERR_R_MALLOC_FAILURE); + return NULL; + } + cms->d.envelopedData->version = 0; + cms->d.envelopedData->encryptedContentInfo->contentType = + OBJ_nid2obj(NID_pkcs7_data); + ASN1_OBJECT_free(cms->contentType); + cms->contentType = OBJ_nid2obj(NID_pkcs7_enveloped); + return cms->d.envelopedData; + } + return cms_get0_enveloped(cms); +} + +STACK_OF(CMS_RecipientInfo) *CMS_get0_RecipientInfos(CMS_ContentInfo *cms) +{ + CMS_EnvelopedData *env; + env = cms_get0_enveloped(cms); + if (!env) + return NULL; + return env->recipientInfos; +} + +int CMS_RecipientInfo_type(CMS_RecipientInfo *ri) +{ + return ri->type; +} + +CMS_ContentInfo *CMS_EnvelopedData_create(const EVP_CIPHER *cipher) +{ + CMS_ContentInfo *cms; + CMS_EnvelopedData *env; + cms = CMS_ContentInfo_new(); + if (!cms) + goto merr; + env = cms_enveloped_data_init(cms); + if (!env) + goto merr; + if (!cms_EncryptedContent_init(env->encryptedContentInfo, + cipher, NULL, 0)) + goto merr; + return cms; + merr: + if (cms) + CMS_ContentInfo_free(cms); + CMSerr(CMS_F_CMS_ENVELOPEDDATA_CREATE, ERR_R_MALLOC_FAILURE); + return NULL; +} + +/* Key Transport Recipient Info (KTRI) routines */ + +/* + * Add a recipient certificate. For now only handle key transport. If we ever + * handle key agreement will need updating. + */ + +CMS_RecipientInfo *CMS_add1_recipient_cert(CMS_ContentInfo *cms, + X509 *recip, unsigned int flags) +{ + CMS_RecipientInfo *ri = NULL; + CMS_KeyTransRecipientInfo *ktri; + CMS_EnvelopedData *env; + EVP_PKEY *pk = NULL; + int i, type; + env = cms_get0_enveloped(cms); + if (!env) + goto err; + + /* Initialize recipient info */ + ri = M_ASN1_new_of(CMS_RecipientInfo); + if (!ri) + goto merr; + + /* Initialize and add key transport recipient info */ + + ri->d.ktri = M_ASN1_new_of(CMS_KeyTransRecipientInfo); + if (!ri->d.ktri) + goto merr; + ri->type = CMS_RECIPINFO_TRANS; + + ktri = ri->d.ktri; + + X509_check_purpose(recip, -1, -1); + pk = X509_get_pubkey(recip); + if (!pk) { + CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_ERROR_GETTING_PUBLIC_KEY); + goto err; + } + CRYPTO_add(&recip->references, 1, CRYPTO_LOCK_X509); + ktri->pkey = pk; + ktri->recip = recip; + + if (flags & CMS_USE_KEYID) { + ktri->version = 2; + if (env->version < 2) + env->version = 2; + type = CMS_RECIPINFO_KEYIDENTIFIER; + } else { + ktri->version = 0; + type = CMS_RECIPINFO_ISSUER_SERIAL; + } + + /* + * Not a typo: RecipientIdentifier and SignerIdentifier are the same + * structure. + */ + + if (!cms_set1_SignerIdentifier(ktri->rid, recip, type)) + goto err; + + if (pk->ameth && pk->ameth->pkey_ctrl) { + i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_ENVELOPE, 0, ri); + if (i == -2) { + CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, + CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; + } + if (i <= 0) { + CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, CMS_R_CTRL_FAILURE); + goto err; + } + } + + if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + goto merr; + + return ri; + + merr: + CMSerr(CMS_F_CMS_ADD1_RECIPIENT_CERT, ERR_R_MALLOC_FAILURE); + err: + if (ri) + M_ASN1_free_of(ri, CMS_RecipientInfo); + return NULL; + +} + +int CMS_RecipientInfo_ktri_get0_algs(CMS_RecipientInfo *ri, + EVP_PKEY **pk, X509 **recip, + X509_ALGOR **palg) +{ + CMS_KeyTransRecipientInfo *ktri; + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS, + CMS_R_NOT_KEY_TRANSPORT); + return 0; + } + + ktri = ri->d.ktri; + + if (pk) + *pk = ktri->pkey; + if (recip) + *recip = ktri->recip; + if (palg) + *palg = ktri->keyEncryptionAlgorithm; + return 1; +} + +int CMS_RecipientInfo_ktri_get0_signer_id(CMS_RecipientInfo *ri, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno) +{ + CMS_KeyTransRecipientInfo *ktri; + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID, + CMS_R_NOT_KEY_TRANSPORT); + return 0; + } + ktri = ri->d.ktri; + + return cms_SignerIdentifier_get0_signer_id(ktri->rid, keyid, issuer, sno); +} + +int CMS_RecipientInfo_ktri_cert_cmp(CMS_RecipientInfo *ri, X509 *cert) +{ + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP, + CMS_R_NOT_KEY_TRANSPORT); + return -2; + } + return cms_SignerIdentifier_cert_cmp(ri->d.ktri->rid, cert); +} + +int CMS_RecipientInfo_set0_pkey(CMS_RecipientInfo *ri, EVP_PKEY *pkey) +{ + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY, CMS_R_NOT_KEY_TRANSPORT); + return 0; + } + ri->d.ktri->pkey = pkey; + return 1; +} + +/* Encrypt content key in key transport recipient info */ + +static int cms_RecipientInfo_ktri_encrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri) +{ + CMS_KeyTransRecipientInfo *ktri; + CMS_EncryptedContentInfo *ec; + EVP_PKEY_CTX *pctx = NULL; + unsigned char *ek = NULL; + size_t eklen; + + int ret = 0; + + if (ri->type != CMS_RECIPINFO_TRANS) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_NOT_KEY_TRANSPORT); + return 0; + } + ktri = ri->d.ktri; + ec = cms->d.envelopedData->encryptedContentInfo; + + pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); + if (!pctx) + return 0; + + if (EVP_PKEY_encrypt_init(pctx) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, + EVP_PKEY_CTRL_CMS_ENCRYPT, 0, ri) <= 0) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, CMS_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, NULL, &eklen, ec->key, ec->keylen) <= 0) + goto err; + + ek = OPENSSL_malloc(eklen); + + if (ek == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, ek, &eklen, ec->key, ec->keylen) <= 0) + goto err; + + ASN1_STRING_set0(ktri->encryptedKey, ek, eklen); + ek = NULL; + + ret = 1; + + err: + if (pctx) + EVP_PKEY_CTX_free(pctx); + if (ek) + OPENSSL_free(ek); + return ret; + +} + +/* Decrypt content key from KTRI */ + +static int cms_RecipientInfo_ktri_decrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri) +{ + CMS_KeyTransRecipientInfo *ktri = ri->d.ktri; + EVP_PKEY_CTX *pctx = NULL; + unsigned char *ek = NULL; + size_t eklen; + int ret = 0; + CMS_EncryptedContentInfo *ec; + ec = cms->d.envelopedData->encryptedContentInfo; + + if (ktri->pkey == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_NO_PRIVATE_KEY); + return 0; + } + + pctx = EVP_PKEY_CTX_new(ktri->pkey, NULL); + if (!pctx) + return 0; + + if (EVP_PKEY_decrypt_init(pctx) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, + EVP_PKEY_CTRL_CMS_DECRYPT, 0, ri) <= 0) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_decrypt(pctx, NULL, &eklen, + ktri->encryptedKey->data, + ktri->encryptedKey->length) <= 0) + goto err; + + ek = OPENSSL_malloc(eklen); + + if (ek == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_decrypt(pctx, ek, &eklen, + ktri->encryptedKey->data, + ktri->encryptedKey->length) <= 0) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT, CMS_R_CMS_LIB); + goto err; + } + + ret = 1; + + if (ec->key) { + OPENSSL_cleanse(ec->key, ec->keylen); + OPENSSL_free(ec->key); + } + + ec->key = ek; + ec->keylen = eklen; + + err: + if (pctx) + EVP_PKEY_CTX_free(pctx); + if (!ret && ek) + OPENSSL_free(ek); + + return ret; +} + +/* Key Encrypted Key (KEK) RecipientInfo routines */ + +int CMS_RecipientInfo_kekri_id_cmp(CMS_RecipientInfo *ri, + const unsigned char *id, size_t idlen) +{ + ASN1_OCTET_STRING tmp_os; + CMS_KEKRecipientInfo *kekri; + if (ri->type != CMS_RECIPINFO_KEK) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP, CMS_R_NOT_KEK); + return -2; + } + kekri = ri->d.kekri; + tmp_os.type = V_ASN1_OCTET_STRING; + tmp_os.flags = 0; + tmp_os.data = (unsigned char *)id; + tmp_os.length = (int)idlen; + return ASN1_OCTET_STRING_cmp(&tmp_os, kekri->kekid->keyIdentifier); +} + +/* For now hard code AES key wrap info */ + +static size_t aes_wrap_keylen(int nid) +{ + switch (nid) { + case NID_id_aes128_wrap: + return 16; + + case NID_id_aes192_wrap: + return 24; + + case NID_id_aes256_wrap: + return 32; + + default: + return 0; + } +} + +CMS_RecipientInfo *CMS_add0_recipient_key(CMS_ContentInfo *cms, int nid, + unsigned char *key, size_t keylen, + unsigned char *id, size_t idlen, + ASN1_GENERALIZEDTIME *date, + ASN1_OBJECT *otherTypeId, + ASN1_TYPE *otherType) +{ + CMS_RecipientInfo *ri = NULL; + CMS_EnvelopedData *env; + CMS_KEKRecipientInfo *kekri; + env = cms_get0_enveloped(cms); + if (!env) + goto err; + + if (nid == NID_undef) { + switch (keylen) { + case 16: + nid = NID_id_aes128_wrap; + break; + + case 24: + nid = NID_id_aes192_wrap; + break; + + case 32: + nid = NID_id_aes256_wrap; + break; + + default: + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH); + goto err; + } + + } else { + + size_t exp_keylen = aes_wrap_keylen(nid); + + if (!exp_keylen) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, + CMS_R_UNSUPPORTED_KEK_ALGORITHM); + goto err; + } + + if (keylen != exp_keylen) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, CMS_R_INVALID_KEY_LENGTH); + goto err; + } + + } + + /* Initialize recipient info */ + ri = M_ASN1_new_of(CMS_RecipientInfo); + if (!ri) + goto merr; + + ri->d.kekri = M_ASN1_new_of(CMS_KEKRecipientInfo); + if (!ri->d.kekri) + goto merr; + ri->type = CMS_RECIPINFO_KEK; + + kekri = ri->d.kekri; + + if (otherTypeId) { + kekri->kekid->other = M_ASN1_new_of(CMS_OtherKeyAttribute); + if (kekri->kekid->other == NULL) + goto merr; + } + + if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + goto merr; + + /* After this point no calls can fail */ + + kekri->version = 4; + + kekri->key = key; + kekri->keylen = keylen; + + ASN1_STRING_set0(kekri->kekid->keyIdentifier, id, idlen); + + kekri->kekid->date = date; + + if (kekri->kekid->other) { + kekri->kekid->other->keyAttrId = otherTypeId; + kekri->kekid->other->keyAttr = otherType; + } + + X509_ALGOR_set0(kekri->keyEncryptionAlgorithm, + OBJ_nid2obj(nid), V_ASN1_UNDEF, NULL); + + return ri; + + merr: + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_KEY, ERR_R_MALLOC_FAILURE); + err: + if (ri) + M_ASN1_free_of(ri, CMS_RecipientInfo); + return NULL; + +} + +int CMS_RecipientInfo_kekri_get0_id(CMS_RecipientInfo *ri, + X509_ALGOR **palg, + ASN1_OCTET_STRING **pid, + ASN1_GENERALIZEDTIME **pdate, + ASN1_OBJECT **potherid, + ASN1_TYPE **pothertype) +{ + CMS_KEKIdentifier *rkid; + if (ri->type != CMS_RECIPINFO_KEK) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID, CMS_R_NOT_KEK); + return 0; + } + rkid = ri->d.kekri->kekid; + if (palg) + *palg = ri->d.kekri->keyEncryptionAlgorithm; + if (pid) + *pid = rkid->keyIdentifier; + if (pdate) + *pdate = rkid->date; + if (potherid) { + if (rkid->other) + *potherid = rkid->other->keyAttrId; + else + *potherid = NULL; + } + if (pothertype) { + if (rkid->other) + *pothertype = rkid->other->keyAttr; + else + *pothertype = NULL; + } + return 1; +} + +int CMS_RecipientInfo_set0_key(CMS_RecipientInfo *ri, + unsigned char *key, size_t keylen) +{ + CMS_KEKRecipientInfo *kekri; + if (ri->type != CMS_RECIPINFO_KEK) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_KEY, CMS_R_NOT_KEK); + return 0; + } + + kekri = ri->d.kekri; + kekri->key = key; + kekri->keylen = keylen; + return 1; +} + +/* Encrypt content key in KEK recipient info */ + +static int cms_RecipientInfo_kekri_encrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri) +{ + CMS_EncryptedContentInfo *ec; + CMS_KEKRecipientInfo *kekri; + AES_KEY actx; + unsigned char *wkey = NULL; + int wkeylen; + int r = 0; + + ec = cms->d.envelopedData->encryptedContentInfo; + + kekri = ri->d.kekri; + + if (!kekri->key) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_NO_KEY); + return 0; + } + + if (AES_set_encrypt_key(kekri->key, kekri->keylen << 3, &actx)) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, + CMS_R_ERROR_SETTING_KEY); + goto err; + } + + wkey = OPENSSL_malloc(ec->keylen + 8); + + if (!wkey) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + wkeylen = AES_wrap_key(&actx, NULL, wkey, ec->key, ec->keylen); + + if (wkeylen <= 0) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT, CMS_R_WRAP_ERROR); + goto err; + } + + ASN1_STRING_set0(kekri->encryptedKey, wkey, wkeylen); + + r = 1; + + err: + + if (!r && wkey) + OPENSSL_free(wkey); + OPENSSL_cleanse(&actx, sizeof(actx)); + + return r; + +} + +/* Decrypt content key in KEK recipient info */ + +static int cms_RecipientInfo_kekri_decrypt(CMS_ContentInfo *cms, + CMS_RecipientInfo *ri) +{ + CMS_EncryptedContentInfo *ec; + CMS_KEKRecipientInfo *kekri; + AES_KEY actx; + unsigned char *ukey = NULL; + int ukeylen; + int r = 0, wrap_nid; + + ec = cms->d.envelopedData->encryptedContentInfo; + + kekri = ri->d.kekri; + + if (!kekri->key) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_NO_KEY); + return 0; + } + + wrap_nid = OBJ_obj2nid(kekri->keyEncryptionAlgorithm->algorithm); + if (aes_wrap_keylen(wrap_nid) != kekri->keylen) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, + CMS_R_INVALID_KEY_LENGTH); + return 0; + } + + /* If encrypted key length is invalid don't bother */ + + if (kekri->encryptedKey->length < 16) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, + CMS_R_INVALID_ENCRYPTED_KEY_LENGTH); + goto err; + } + + if (AES_set_decrypt_key(kekri->key, kekri->keylen << 3, &actx)) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, + CMS_R_ERROR_SETTING_KEY); + goto err; + } + + ukey = OPENSSL_malloc(kekri->encryptedKey->length - 8); + + if (!ukey) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + ukeylen = AES_unwrap_key(&actx, NULL, ukey, + kekri->encryptedKey->data, + kekri->encryptedKey->length); + + if (ukeylen <= 0) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT, CMS_R_UNWRAP_ERROR); + goto err; + } + + ec->key = ukey; + ec->keylen = ukeylen; + + r = 1; + + err: + + if (!r && ukey) + OPENSSL_free(ukey); + OPENSSL_cleanse(&actx, sizeof(actx)); + + return r; + +} + +int CMS_RecipientInfo_decrypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri) +{ + switch (ri->type) { + case CMS_RECIPINFO_TRANS: + return cms_RecipientInfo_ktri_decrypt(cms, ri); + + case CMS_RECIPINFO_KEK: + return cms_RecipientInfo_kekri_decrypt(cms, ri); + + case CMS_RECIPINFO_PASS: + return cms_RecipientInfo_pwri_crypt(cms, ri, 0); + + default: + CMSerr(CMS_F_CMS_RECIPIENTINFO_DECRYPT, + CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE); + return 0; + } +} + +BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms) +{ + CMS_EncryptedContentInfo *ec; + STACK_OF(CMS_RecipientInfo) *rinfos; + CMS_RecipientInfo *ri; + int i, r, ok = 0; + BIO *ret; + + /* Get BIO first to set up key */ + + ec = cms->d.envelopedData->encryptedContentInfo; + ret = cms_EncryptedContent_init_bio(ec); + + /* If error or no cipher end of processing */ + + if (!ret || !ec->cipher) + return ret; + + /* Now encrypt content key according to each RecipientInfo type */ + + rinfos = cms->d.envelopedData->recipientInfos; + + for (i = 0; i < sk_CMS_RecipientInfo_num(rinfos); i++) { + ri = sk_CMS_RecipientInfo_value(rinfos, i); + + switch (ri->type) { + case CMS_RECIPINFO_TRANS: + r = cms_RecipientInfo_ktri_encrypt(cms, ri); + break; + + case CMS_RECIPINFO_KEK: + r = cms_RecipientInfo_kekri_encrypt(cms, ri); + break; + + case CMS_RECIPINFO_PASS: + r = cms_RecipientInfo_pwri_crypt(cms, ri, 1); + break; + + default: + CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, + CMS_R_UNSUPPORTED_RECIPIENT_TYPE); + goto err; + } + + if (r <= 0) { + CMSerr(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO, + CMS_R_ERROR_SETTING_RECIPIENTINFO); + goto err; + } + } + + ok = 1; + + err: + ec->cipher = NULL; + if (ec->key) { + OPENSSL_cleanse(ec->key, ec->keylen); + OPENSSL_free(ec->key); + ec->key = NULL; + ec->keylen = 0; + } + if (ok) + return ret; + BIO_free(ret); + return NULL; + +} diff --git a/libs/openssl/crypto/cms/cms_err.c b/libs/openssl/crypto/cms/cms_err.c new file mode 100644 index 00000000..faf2fccd --- /dev/null +++ b/libs/openssl/crypto/cms/cms_err.c @@ -0,0 +1,293 @@ +/* crypto/cms/cms_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2009 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CMS,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CMS,0,reason) + +static ERR_STRING_DATA CMS_str_functs[] = { + {ERR_FUNC(CMS_F_CHECK_CONTENT), "CHECK_CONTENT"}, + {ERR_FUNC(CMS_F_CMS_ADD0_CERT), "CMS_add0_cert"}, + {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_KEY), "CMS_add0_recipient_key"}, + {ERR_FUNC(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD), + "CMS_add0_recipient_password"}, + {ERR_FUNC(CMS_F_CMS_ADD1_RECEIPTREQUEST), "CMS_add1_ReceiptRequest"}, + {ERR_FUNC(CMS_F_CMS_ADD1_RECIPIENT_CERT), "CMS_add1_recipient_cert"}, + {ERR_FUNC(CMS_F_CMS_ADD1_SIGNER), "CMS_add1_signer"}, + {ERR_FUNC(CMS_F_CMS_ADD1_SIGNINGTIME), "CMS_ADD1_SIGNINGTIME"}, + {ERR_FUNC(CMS_F_CMS_COMPRESS), "CMS_compress"}, + {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_CREATE), "cms_CompressedData_create"}, + {ERR_FUNC(CMS_F_CMS_COMPRESSEDDATA_INIT_BIO), + "cms_CompressedData_init_bio"}, + {ERR_FUNC(CMS_F_CMS_COPY_CONTENT), "CMS_COPY_CONTENT"}, + {ERR_FUNC(CMS_F_CMS_COPY_MESSAGEDIGEST), "CMS_COPY_MESSAGEDIGEST"}, + {ERR_FUNC(CMS_F_CMS_DATA), "CMS_data"}, + {ERR_FUNC(CMS_F_CMS_DATAFINAL), "CMS_dataFinal"}, + {ERR_FUNC(CMS_F_CMS_DATAINIT), "CMS_dataInit"}, + {ERR_FUNC(CMS_F_CMS_DECRYPT), "CMS_decrypt"}, + {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_KEY), "CMS_decrypt_set1_key"}, + {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PASSWORD), "CMS_decrypt_set1_password"}, + {ERR_FUNC(CMS_F_CMS_DECRYPT_SET1_PKEY), "CMS_decrypt_set1_pkey"}, + {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX), + "cms_DigestAlgorithm_find_ctx"}, + {ERR_FUNC(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO), + "cms_DigestAlgorithm_init_bio"}, + {ERR_FUNC(CMS_F_CMS_DIGESTEDDATA_DO_FINAL), "cms_DigestedData_do_final"}, + {ERR_FUNC(CMS_F_CMS_DIGEST_VERIFY), "CMS_digest_verify"}, + {ERR_FUNC(CMS_F_CMS_ENCODE_RECEIPT), "cms_encode_Receipt"}, + {ERR_FUNC(CMS_F_CMS_ENCRYPT), "CMS_encrypt"}, + {ERR_FUNC(CMS_F_CMS_ENCRYPTEDCONTENT_INIT_BIO), + "cms_EncryptedContent_init_bio"}, + {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT), "CMS_EncryptedData_decrypt"}, + {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT), "CMS_EncryptedData_encrypt"}, + {ERR_FUNC(CMS_F_CMS_ENCRYPTEDDATA_SET1_KEY), + "CMS_EncryptedData_set1_key"}, + {ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_CREATE), "CMS_EnvelopedData_create"}, + {ERR_FUNC(CMS_F_CMS_ENVELOPEDDATA_INIT_BIO), + "cms_EnvelopedData_init_bio"}, + {ERR_FUNC(CMS_F_CMS_ENVELOPED_DATA_INIT), "CMS_ENVELOPED_DATA_INIT"}, + {ERR_FUNC(CMS_F_CMS_FINAL), "CMS_final"}, + {ERR_FUNC(CMS_F_CMS_GET0_CERTIFICATE_CHOICES), + "CMS_GET0_CERTIFICATE_CHOICES"}, + {ERR_FUNC(CMS_F_CMS_GET0_CONTENT), "CMS_get0_content"}, + {ERR_FUNC(CMS_F_CMS_GET0_ECONTENT_TYPE), "CMS_GET0_ECONTENT_TYPE"}, + {ERR_FUNC(CMS_F_CMS_GET0_ENVELOPED), "cms_get0_enveloped"}, + {ERR_FUNC(CMS_F_CMS_GET0_REVOCATION_CHOICES), + "CMS_GET0_REVOCATION_CHOICES"}, + {ERR_FUNC(CMS_F_CMS_GET0_SIGNED), "CMS_GET0_SIGNED"}, + {ERR_FUNC(CMS_F_CMS_MSGSIGDIGEST_ADD1), "cms_msgSigDigest_add1"}, + {ERR_FUNC(CMS_F_CMS_RECEIPTREQUEST_CREATE0), + "CMS_ReceiptRequest_create0"}, + {ERR_FUNC(CMS_F_CMS_RECEIPT_VERIFY), "cms_Receipt_verify"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_DECRYPT), "CMS_RecipientInfo_decrypt"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_DECRYPT), + "CMS_RECIPIENTINFO_KEKRI_DECRYPT"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ENCRYPT), + "CMS_RECIPIENTINFO_KEKRI_ENCRYPT"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_GET0_ID), + "CMS_RecipientInfo_kekri_get0_id"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KEKRI_ID_CMP), + "CMS_RecipientInfo_kekri_id_cmp"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_CERT_CMP), + "CMS_RecipientInfo_ktri_cert_cmp"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_DECRYPT), + "CMS_RECIPIENTINFO_KTRI_DECRYPT"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_ENCRYPT), + "CMS_RECIPIENTINFO_KTRI_ENCRYPT"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_ALGS), + "CMS_RecipientInfo_ktri_get0_algs"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_KTRI_GET0_SIGNER_ID), + "CMS_RecipientInfo_ktri_get0_signer_id"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT), + "cms_RecipientInfo_pwri_crypt"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_KEY), + "CMS_RecipientInfo_set0_key"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD), + "CMS_RecipientInfo_set0_password"}, + {ERR_FUNC(CMS_F_CMS_RECIPIENTINFO_SET0_PKEY), + "CMS_RecipientInfo_set0_pkey"}, + {ERR_FUNC(CMS_F_CMS_SET1_SIGNERIDENTIFIER), "cms_set1_SignerIdentifier"}, + {ERR_FUNC(CMS_F_CMS_SET_DETACHED), "CMS_set_detached"}, + {ERR_FUNC(CMS_F_CMS_SIGN), "CMS_sign"}, + {ERR_FUNC(CMS_F_CMS_SIGNED_DATA_INIT), "CMS_SIGNED_DATA_INIT"}, + {ERR_FUNC(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN), + "CMS_SIGNERINFO_CONTENT_SIGN"}, + {ERR_FUNC(CMS_F_CMS_SIGNERINFO_SIGN), "CMS_SignerInfo_sign"}, + {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY), "CMS_SignerInfo_verify"}, + {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CERT), + "CMS_SIGNERINFO_VERIFY_CERT"}, + {ERR_FUNC(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT), + "CMS_SignerInfo_verify_content"}, + {ERR_FUNC(CMS_F_CMS_SIGN_RECEIPT), "CMS_sign_receipt"}, + {ERR_FUNC(CMS_F_CMS_STREAM), "CMS_stream"}, + {ERR_FUNC(CMS_F_CMS_UNCOMPRESS), "CMS_uncompress"}, + {ERR_FUNC(CMS_F_CMS_VERIFY), "CMS_verify"}, + {0, NULL} +}; + +static ERR_STRING_DATA CMS_str_reasons[] = { + {ERR_REASON(CMS_R_ADD_SIGNER_ERROR), "add signer error"}, + {ERR_REASON(CMS_R_CERTIFICATE_ALREADY_PRESENT), + "certificate already present"}, + {ERR_REASON(CMS_R_CERTIFICATE_HAS_NO_KEYID), "certificate has no keyid"}, + {ERR_REASON(CMS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, + {ERR_REASON(CMS_R_CIPHER_INITIALISATION_ERROR), + "cipher initialisation error"}, + {ERR_REASON(CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR), + "cipher parameter initialisation error"}, + {ERR_REASON(CMS_R_CMS_DATAFINAL_ERROR), "cms datafinal error"}, + {ERR_REASON(CMS_R_CMS_LIB), "cms lib"}, + {ERR_REASON(CMS_R_CONTENTIDENTIFIER_MISMATCH), + "contentidentifier mismatch"}, + {ERR_REASON(CMS_R_CONTENT_NOT_FOUND), "content not found"}, + {ERR_REASON(CMS_R_CONTENT_TYPE_MISMATCH), "content type mismatch"}, + {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_COMPRESSED_DATA), + "content type not compressed data"}, + {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_ENVELOPED_DATA), + "content type not enveloped data"}, + {ERR_REASON(CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA), + "content type not signed data"}, + {ERR_REASON(CMS_R_CONTENT_VERIFY_ERROR), "content verify error"}, + {ERR_REASON(CMS_R_CTRL_ERROR), "ctrl error"}, + {ERR_REASON(CMS_R_CTRL_FAILURE), "ctrl failure"}, + {ERR_REASON(CMS_R_DECRYPT_ERROR), "decrypt error"}, + {ERR_REASON(CMS_R_DIGEST_ERROR), "digest error"}, + {ERR_REASON(CMS_R_ERROR_GETTING_PUBLIC_KEY), "error getting public key"}, + {ERR_REASON(CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE), + "error reading messagedigest attribute"}, + {ERR_REASON(CMS_R_ERROR_SETTING_KEY), "error setting key"}, + {ERR_REASON(CMS_R_ERROR_SETTING_RECIPIENTINFO), + "error setting recipientinfo"}, + {ERR_REASON(CMS_R_INVALID_ENCRYPTED_KEY_LENGTH), + "invalid encrypted key length"}, + {ERR_REASON(CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER), + "invalid key encryption parameter"}, + {ERR_REASON(CMS_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_REASON(CMS_R_MD_BIO_INIT_ERROR), "md bio init error"}, + {ERR_REASON(CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH), + "messagedigest attribute wrong length"}, + {ERR_REASON(CMS_R_MESSAGEDIGEST_WRONG_LENGTH), + "messagedigest wrong length"}, + {ERR_REASON(CMS_R_MSGSIGDIGEST_ERROR), "msgsigdigest error"}, + {ERR_REASON(CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE), + "msgsigdigest verification failure"}, + {ERR_REASON(CMS_R_MSGSIGDIGEST_WRONG_LENGTH), + "msgsigdigest wrong length"}, + {ERR_REASON(CMS_R_NEED_ONE_SIGNER), "need one signer"}, + {ERR_REASON(CMS_R_NOT_A_SIGNED_RECEIPT), "not a signed receipt"}, + {ERR_REASON(CMS_R_NOT_ENCRYPTED_DATA), "not encrypted data"}, + {ERR_REASON(CMS_R_NOT_KEK), "not kek"}, + {ERR_REASON(CMS_R_NOT_KEY_TRANSPORT), "not key transport"}, + {ERR_REASON(CMS_R_NOT_PWRI), "not pwri"}, + {ERR_REASON(CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), + "not supported for this key type"}, + {ERR_REASON(CMS_R_NO_CIPHER), "no cipher"}, + {ERR_REASON(CMS_R_NO_CONTENT), "no content"}, + {ERR_REASON(CMS_R_NO_CONTENT_TYPE), "no content type"}, + {ERR_REASON(CMS_R_NO_DEFAULT_DIGEST), "no default digest"}, + {ERR_REASON(CMS_R_NO_DIGEST_SET), "no digest set"}, + {ERR_REASON(CMS_R_NO_KEY), "no key"}, + {ERR_REASON(CMS_R_NO_KEY_OR_CERT), "no key or cert"}, + {ERR_REASON(CMS_R_NO_MATCHING_DIGEST), "no matching digest"}, + {ERR_REASON(CMS_R_NO_MATCHING_RECIPIENT), "no matching recipient"}, + {ERR_REASON(CMS_R_NO_MATCHING_SIGNATURE), "no matching signature"}, + {ERR_REASON(CMS_R_NO_MSGSIGDIGEST), "no msgsigdigest"}, + {ERR_REASON(CMS_R_NO_PASSWORD), "no password"}, + {ERR_REASON(CMS_R_NO_PRIVATE_KEY), "no private key"}, + {ERR_REASON(CMS_R_NO_PUBLIC_KEY), "no public key"}, + {ERR_REASON(CMS_R_NO_RECEIPT_REQUEST), "no receipt request"}, + {ERR_REASON(CMS_R_NO_SIGNERS), "no signers"}, + {ERR_REASON(CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), + "private key does not match certificate"}, + {ERR_REASON(CMS_R_RECEIPT_DECODE_ERROR), "receipt decode error"}, + {ERR_REASON(CMS_R_RECIPIENT_ERROR), "recipient error"}, + {ERR_REASON(CMS_R_SIGNER_CERTIFICATE_NOT_FOUND), + "signer certificate not found"}, + {ERR_REASON(CMS_R_SIGNFINAL_ERROR), "signfinal error"}, + {ERR_REASON(CMS_R_SMIME_TEXT_ERROR), "smime text error"}, + {ERR_REASON(CMS_R_STORE_INIT_ERROR), "store init error"}, + {ERR_REASON(CMS_R_TYPE_NOT_COMPRESSED_DATA), "type not compressed data"}, + {ERR_REASON(CMS_R_TYPE_NOT_DATA), "type not data"}, + {ERR_REASON(CMS_R_TYPE_NOT_DIGESTED_DATA), "type not digested data"}, + {ERR_REASON(CMS_R_TYPE_NOT_ENCRYPTED_DATA), "type not encrypted data"}, + {ERR_REASON(CMS_R_TYPE_NOT_ENVELOPED_DATA), "type not enveloped data"}, + {ERR_REASON(CMS_R_UNABLE_TO_FINALIZE_CONTEXT), + "unable to finalize context"}, + {ERR_REASON(CMS_R_UNKNOWN_CIPHER), "unknown cipher"}, + {ERR_REASON(CMS_R_UNKNOWN_DIGEST_ALGORIHM), "unknown digest algorihm"}, + {ERR_REASON(CMS_R_UNKNOWN_ID), "unknown id"}, + {ERR_REASON(CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM), + "unsupported compression algorithm"}, + {ERR_REASON(CMS_R_UNSUPPORTED_CONTENT_TYPE), "unsupported content type"}, + {ERR_REASON(CMS_R_UNSUPPORTED_KEK_ALGORITHM), + "unsupported kek algorithm"}, + {ERR_REASON(CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM), + "unsupported key encryption algorithm"}, + {ERR_REASON(CMS_R_UNSUPPORTED_RECIPIENT_TYPE), + "unsupported recipient type"}, + {ERR_REASON(CMS_R_UNSUPPORTED_RECPIENTINFO_TYPE), + "unsupported recpientinfo type"}, + {ERR_REASON(CMS_R_UNSUPPORTED_TYPE), "unsupported type"}, + {ERR_REASON(CMS_R_UNWRAP_ERROR), "unwrap error"}, + {ERR_REASON(CMS_R_UNWRAP_FAILURE), "unwrap failure"}, + {ERR_REASON(CMS_R_VERIFICATION_FAILURE), "verification failure"}, + {ERR_REASON(CMS_R_WRAP_ERROR), "wrap error"}, + {0, NULL} +}; + +#endif + +void ERR_load_CMS_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(CMS_str_functs[0].error) == NULL) { + ERR_load_strings(0, CMS_str_functs); + ERR_load_strings(0, CMS_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/cms/cms_ess.c b/libs/openssl/crypto/cms/cms_ess.c new file mode 100644 index 00000000..8631a2eb --- /dev/null +++ b/libs/openssl/crypto/cms/cms_ess.c @@ -0,0 +1,395 @@ +/* crypto/cms/cms_ess.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include "cms_lcl.h" + +DECLARE_ASN1_ITEM(CMS_ReceiptRequest) +DECLARE_ASN1_ITEM(CMS_Receipt) + +IMPLEMENT_ASN1_FUNCTIONS(CMS_ReceiptRequest) + +/* ESS services: for now just Signed Receipt related */ + +int CMS_get1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest **prr) +{ + ASN1_STRING *str; + CMS_ReceiptRequest *rr = NULL; + if (prr) + *prr = NULL; + str = CMS_signed_get0_data_by_OBJ(si, + OBJ_nid2obj + (NID_id_smime_aa_receiptRequest), -3, + V_ASN1_SEQUENCE); + if (!str) + return 0; + + rr = ASN1_item_unpack(str, ASN1_ITEM_rptr(CMS_ReceiptRequest)); + if (!rr) + return -1; + if (prr) + *prr = rr; + else + CMS_ReceiptRequest_free(rr); + return 1; +} + +CMS_ReceiptRequest *CMS_ReceiptRequest_create0(unsigned char *id, int idlen, + int allorfirst, + STACK_OF(GENERAL_NAMES) + *receiptList, STACK_OF(GENERAL_NAMES) + *receiptsTo) +{ + CMS_ReceiptRequest *rr = NULL; + + rr = CMS_ReceiptRequest_new(); + if (!rr) + goto merr; + if (id) + ASN1_STRING_set0(rr->signedContentIdentifier, id, idlen); + else { + if (!ASN1_STRING_set(rr->signedContentIdentifier, NULL, 32)) + goto merr; + if (RAND_pseudo_bytes(rr->signedContentIdentifier->data, 32) + <= 0) + goto err; + } + + sk_GENERAL_NAMES_pop_free(rr->receiptsTo, GENERAL_NAMES_free); + rr->receiptsTo = receiptsTo; + + if (receiptList) { + rr->receiptsFrom->type = 1; + rr->receiptsFrom->d.receiptList = receiptList; + } else { + rr->receiptsFrom->type = 0; + rr->receiptsFrom->d.allOrFirstTier = allorfirst; + } + + return rr; + + merr: + CMSerr(CMS_F_CMS_RECEIPTREQUEST_CREATE0, ERR_R_MALLOC_FAILURE); + + err: + if (rr) + CMS_ReceiptRequest_free(rr); + + return NULL; + +} + +int CMS_add1_ReceiptRequest(CMS_SignerInfo *si, CMS_ReceiptRequest *rr) +{ + unsigned char *rrder = NULL; + int rrderlen, r = 0; + + rrderlen = i2d_CMS_ReceiptRequest(rr, &rrder); + if (rrderlen < 0) + goto merr; + + if (!CMS_signed_add1_attr_by_NID(si, NID_id_smime_aa_receiptRequest, + V_ASN1_SEQUENCE, rrder, rrderlen)) + goto merr; + + r = 1; + + merr: + if (!r) + CMSerr(CMS_F_CMS_ADD1_RECEIPTREQUEST, ERR_R_MALLOC_FAILURE); + + if (rrder) + OPENSSL_free(rrder); + + return r; + +} + +void CMS_ReceiptRequest_get0_values(CMS_ReceiptRequest *rr, + ASN1_STRING **pcid, + int *pallorfirst, + STACK_OF(GENERAL_NAMES) **plist, + STACK_OF(GENERAL_NAMES) **prto) +{ + if (pcid) + *pcid = rr->signedContentIdentifier; + if (rr->receiptsFrom->type == 0) { + if (pallorfirst) + *pallorfirst = (int)rr->receiptsFrom->d.allOrFirstTier; + if (plist) + *plist = NULL; + } else { + if (pallorfirst) + *pallorfirst = -1; + if (plist) + *plist = rr->receiptsFrom->d.receiptList; + } + if (prto) + *prto = rr->receiptsTo; +} + +/* Digest a SignerInfo structure for msgSigDigest attribute processing */ + +static int cms_msgSigDigest(CMS_SignerInfo *si, + unsigned char *dig, unsigned int *diglen) +{ + const EVP_MD *md; + md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); + if (md == NULL) + return 0; + if (!ASN1_item_digest(ASN1_ITEM_rptr(CMS_Attributes_Verify), md, + si->signedAttrs, dig, diglen)) + return 0; + return 1; +} + +/* Add a msgSigDigest attribute to a SignerInfo */ + +int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src) +{ + unsigned char dig[EVP_MAX_MD_SIZE]; + unsigned int diglen; + if (!cms_msgSigDigest(src, dig, &diglen)) { + CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, CMS_R_MSGSIGDIGEST_ERROR); + return 0; + } + if (!CMS_signed_add1_attr_by_NID(dest, NID_id_smime_aa_msgSigDigest, + V_ASN1_OCTET_STRING, dig, diglen)) { + CMSerr(CMS_F_CMS_MSGSIGDIGEST_ADD1, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +/* Verify signed receipt after it has already passed normal CMS verify */ + +int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms) +{ + int r = 0, i; + CMS_ReceiptRequest *rr = NULL; + CMS_Receipt *rct = NULL; + STACK_OF(CMS_SignerInfo) *sis, *osis; + CMS_SignerInfo *si, *osi = NULL; + ASN1_OCTET_STRING *msig, **pcont; + ASN1_OBJECT *octype; + unsigned char dig[EVP_MAX_MD_SIZE]; + unsigned int diglen; + + /* Get SignerInfos, also checks SignedData content type */ + osis = CMS_get0_SignerInfos(req_cms); + sis = CMS_get0_SignerInfos(cms); + if (!osis || !sis) + goto err; + + if (sk_CMS_SignerInfo_num(sis) != 1) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NEED_ONE_SIGNER); + goto err; + } + + /* Check receipt content type */ + if (OBJ_obj2nid(CMS_get0_eContentType(cms)) != NID_id_smime_ct_receipt) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NOT_A_SIGNED_RECEIPT); + goto err; + } + + /* Extract and decode receipt content */ + pcont = CMS_get0_content(cms); + if (!pcont || !*pcont) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT); + goto err; + } + + rct = ASN1_item_unpack(*pcont, ASN1_ITEM_rptr(CMS_Receipt)); + + if (!rct) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_RECEIPT_DECODE_ERROR); + goto err; + } + + /* Locate original request */ + + for (i = 0; i < sk_CMS_SignerInfo_num(osis); i++) { + osi = sk_CMS_SignerInfo_value(osis, i); + if (!ASN1_STRING_cmp(osi->signature, rct->originatorSignatureValue)) + break; + } + + if (i == sk_CMS_SignerInfo_num(osis)) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MATCHING_SIGNATURE); + goto err; + } + + si = sk_CMS_SignerInfo_value(sis, 0); + + /* Get msgSigDigest value and compare */ + + msig = CMS_signed_get0_data_by_OBJ(si, + OBJ_nid2obj + (NID_id_smime_aa_msgSigDigest), -3, + V_ASN1_OCTET_STRING); + + if (!msig) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_MSGSIGDIGEST); + goto err; + } + + if (!cms_msgSigDigest(osi, dig, &diglen)) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_ERROR); + goto err; + } + + if (diglen != (unsigned int)msig->length) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_MSGSIGDIGEST_WRONG_LENGTH); + goto err; + } + + if (memcmp(dig, msig->data, diglen)) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, + CMS_R_MSGSIGDIGEST_VERIFICATION_FAILURE); + goto err; + } + + /* Compare content types */ + + octype = CMS_signed_get0_data_by_OBJ(osi, + OBJ_nid2obj(NID_pkcs9_contentType), + -3, V_ASN1_OBJECT); + if (!octype) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_CONTENT_TYPE); + goto err; + } + + /* Compare details in receipt request */ + + if (OBJ_cmp(octype, rct->contentType)) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENT_TYPE_MISMATCH); + goto err; + } + + /* Get original receipt request details */ + + if (CMS_get1_ReceiptRequest(osi, &rr) <= 0) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_NO_RECEIPT_REQUEST); + goto err; + } + + if (ASN1_STRING_cmp(rr->signedContentIdentifier, + rct->signedContentIdentifier)) { + CMSerr(CMS_F_CMS_RECEIPT_VERIFY, CMS_R_CONTENTIDENTIFIER_MISMATCH); + goto err; + } + + r = 1; + + err: + if (rr) + CMS_ReceiptRequest_free(rr); + if (rct) + M_ASN1_free_of(rct, CMS_Receipt); + + return r; + +} + +/* + * Encode a Receipt into an OCTET STRING read for including into content of a + * SignedData ContentInfo. + */ + +ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si) +{ + CMS_Receipt rct; + CMS_ReceiptRequest *rr = NULL; + ASN1_OBJECT *ctype; + ASN1_OCTET_STRING *os = NULL; + + /* Get original receipt request */ + + /* Get original receipt request details */ + + if (CMS_get1_ReceiptRequest(si, &rr) <= 0) { + CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_RECEIPT_REQUEST); + goto err; + } + + /* Get original content type */ + + ctype = CMS_signed_get0_data_by_OBJ(si, + OBJ_nid2obj(NID_pkcs9_contentType), + -3, V_ASN1_OBJECT); + if (!ctype) { + CMSerr(CMS_F_CMS_ENCODE_RECEIPT, CMS_R_NO_CONTENT_TYPE); + goto err; + } + + rct.version = 1; + rct.contentType = ctype; + rct.signedContentIdentifier = rr->signedContentIdentifier; + rct.originatorSignatureValue = si->signature; + + os = ASN1_item_pack(&rct, ASN1_ITEM_rptr(CMS_Receipt), NULL); + + err: + if (rr) + CMS_ReceiptRequest_free(rr); + + return os; + +} diff --git a/libs/openssl/crypto/cms/cms_io.c b/libs/openssl/crypto/cms/cms_io.c new file mode 100644 index 00000000..ec51f8e6 --- /dev/null +++ b/libs/openssl/crypto/cms/cms_io.c @@ -0,0 +1,133 @@ +/* crypto/cms/cms_io.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include "cms.h" +#include "cms_lcl.h" + +int CMS_stream(unsigned char ***boundary, CMS_ContentInfo *cms) +{ + ASN1_OCTET_STRING **pos; + pos = CMS_get0_content(cms); + if (!pos) + return 0; + if (!*pos) + *pos = ASN1_OCTET_STRING_new(); + if (*pos) { + (*pos)->flags |= ASN1_STRING_FLAG_NDEF; + (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; + *boundary = &(*pos)->data; + return 1; + } + CMSerr(CMS_F_CMS_STREAM, ERR_R_MALLOC_FAILURE); + return 0; +} + +CMS_ContentInfo *d2i_CMS_bio(BIO *bp, CMS_ContentInfo **cms) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); +} + +int i2d_CMS_bio(BIO *bp, CMS_ContentInfo *cms) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(CMS_ContentInfo), bp, cms); +} + +IMPLEMENT_PEM_rw_const(CMS, CMS_ContentInfo, PEM_STRING_CMS, CMS_ContentInfo) + +BIO *BIO_new_CMS(BIO *out, CMS_ContentInfo *cms) +{ + return BIO_new_NDEF(out, (ASN1_VALUE *)cms, + ASN1_ITEM_rptr(CMS_ContentInfo)); +} + +/* CMS wrappers round generalised stream and MIME routines */ + +int i2d_CMS_bio_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, int flags) +{ + return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)cms, in, flags, + ASN1_ITEM_rptr(CMS_ContentInfo)); +} + +int PEM_write_bio_CMS_stream(BIO *out, CMS_ContentInfo *cms, BIO *in, + int flags) +{ + return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *)cms, in, flags, + "CMS", ASN1_ITEM_rptr(CMS_ContentInfo)); +} + +int SMIME_write_CMS(BIO *bio, CMS_ContentInfo *cms, BIO *data, int flags) +{ + STACK_OF(X509_ALGOR) *mdalgs; + int ctype_nid = OBJ_obj2nid(cms->contentType); + int econt_nid = OBJ_obj2nid(CMS_get0_eContentType(cms)); + if (ctype_nid == NID_pkcs7_signed) + mdalgs = cms->d.signedData->digestAlgorithms; + else + mdalgs = NULL; + + return SMIME_write_ASN1(bio, (ASN1_VALUE *)cms, data, flags, + ctype_nid, econt_nid, mdalgs, + ASN1_ITEM_rptr(CMS_ContentInfo)); +} + +CMS_ContentInfo *SMIME_read_CMS(BIO *bio, BIO **bcont) +{ + return (CMS_ContentInfo *)SMIME_read_ASN1(bio, bcont, + ASN1_ITEM_rptr + (CMS_ContentInfo)); +} diff --git a/libs/openssl/crypto/cms/cms_lcl.h b/libs/openssl/crypto/cms/cms_lcl.h new file mode 100644 index 00000000..4f4c4c74 --- /dev/null +++ b/libs/openssl/crypto/cms/cms_lcl.h @@ -0,0 +1,443 @@ +/* crypto/cms/cms_lcl.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#ifndef HEADER_CMS_LCL_H +# define HEADER_CMS_LCL_H + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +/* + * Cryptographic message syntax (CMS) structures: taken from RFC3852 + */ + +/* Forward references */ + +typedef struct CMS_IssuerAndSerialNumber_st CMS_IssuerAndSerialNumber; +typedef struct CMS_EncapsulatedContentInfo_st CMS_EncapsulatedContentInfo; +typedef struct CMS_SignerIdentifier_st CMS_SignerIdentifier; +typedef struct CMS_SignedData_st CMS_SignedData; +typedef struct CMS_OtherRevocationInfoFormat_st CMS_OtherRevocationInfoFormat; +typedef struct CMS_OriginatorInfo_st CMS_OriginatorInfo; +typedef struct CMS_EncryptedContentInfo_st CMS_EncryptedContentInfo; +typedef struct CMS_EnvelopedData_st CMS_EnvelopedData; +typedef struct CMS_DigestedData_st CMS_DigestedData; +typedef struct CMS_EncryptedData_st CMS_EncryptedData; +typedef struct CMS_AuthenticatedData_st CMS_AuthenticatedData; +typedef struct CMS_CompressedData_st CMS_CompressedData; +typedef struct CMS_OtherCertificateFormat_st CMS_OtherCertificateFormat; +typedef struct CMS_KeyTransRecipientInfo_st CMS_KeyTransRecipientInfo; +typedef struct CMS_OriginatorPublicKey_st CMS_OriginatorPublicKey; +typedef struct CMS_OriginatorIdentifierOrKey_st CMS_OriginatorIdentifierOrKey; +typedef struct CMS_KeyAgreeRecipientInfo_st CMS_KeyAgreeRecipientInfo; +typedef struct CMS_OtherKeyAttribute_st CMS_OtherKeyAttribute; +typedef struct CMS_RecipientKeyIdentifier_st CMS_RecipientKeyIdentifier; +typedef struct CMS_KeyAgreeRecipientIdentifier_st + CMS_KeyAgreeRecipientIdentifier; +typedef struct CMS_RecipientEncryptedKey_st CMS_RecipientEncryptedKey; +typedef struct CMS_KEKIdentifier_st CMS_KEKIdentifier; +typedef struct CMS_KEKRecipientInfo_st CMS_KEKRecipientInfo; +typedef struct CMS_PasswordRecipientInfo_st CMS_PasswordRecipientInfo; +typedef struct CMS_OtherRecipientInfo_st CMS_OtherRecipientInfo; +typedef struct CMS_ReceiptsFrom_st CMS_ReceiptsFrom; + +struct CMS_ContentInfo_st { + ASN1_OBJECT *contentType; + union { + ASN1_OCTET_STRING *data; + CMS_SignedData *signedData; + CMS_EnvelopedData *envelopedData; + CMS_DigestedData *digestedData; + CMS_EncryptedData *encryptedData; + CMS_AuthenticatedData *authenticatedData; + CMS_CompressedData *compressedData; + ASN1_TYPE *other; + /* Other types ... */ + void *otherData; + } d; +}; + +struct CMS_SignedData_st { + long version; + STACK_OF(X509_ALGOR) *digestAlgorithms; + CMS_EncapsulatedContentInfo *encapContentInfo; + STACK_OF(CMS_CertificateChoices) *certificates; + STACK_OF(CMS_RevocationInfoChoice) *crls; + STACK_OF(CMS_SignerInfo) *signerInfos; +}; + +struct CMS_EncapsulatedContentInfo_st { + ASN1_OBJECT *eContentType; + ASN1_OCTET_STRING *eContent; + /* Set to 1 if incomplete structure only part set up */ + int partial; +}; + +struct CMS_SignerInfo_st { + long version; + CMS_SignerIdentifier *sid; + X509_ALGOR *digestAlgorithm; + STACK_OF(X509_ATTRIBUTE) *signedAttrs; + X509_ALGOR *signatureAlgorithm; + ASN1_OCTET_STRING *signature; + STACK_OF(X509_ATTRIBUTE) *unsignedAttrs; + /* Signing certificate and key */ + X509 *signer; + EVP_PKEY *pkey; +}; + +struct CMS_SignerIdentifier_st { + int type; + union { + CMS_IssuerAndSerialNumber *issuerAndSerialNumber; + ASN1_OCTET_STRING *subjectKeyIdentifier; + } d; +}; + +struct CMS_EnvelopedData_st { + long version; + CMS_OriginatorInfo *originatorInfo; + STACK_OF(CMS_RecipientInfo) *recipientInfos; + CMS_EncryptedContentInfo *encryptedContentInfo; + STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs; +}; + +struct CMS_OriginatorInfo_st { + STACK_OF(CMS_CertificateChoices) *certificates; + STACK_OF(CMS_RevocationInfoChoice) *crls; +}; + +struct CMS_EncryptedContentInfo_st { + ASN1_OBJECT *contentType; + X509_ALGOR *contentEncryptionAlgorithm; + ASN1_OCTET_STRING *encryptedContent; + /* Content encryption algorithm and key */ + const EVP_CIPHER *cipher; + unsigned char *key; + size_t keylen; + /* Set to 1 if we are debugging decrypt and don't fake keys for MMA */ + int debug; +}; + +struct CMS_RecipientInfo_st { + int type; + union { + CMS_KeyTransRecipientInfo *ktri; + CMS_KeyAgreeRecipientInfo *kari; + CMS_KEKRecipientInfo *kekri; + CMS_PasswordRecipientInfo *pwri; + CMS_OtherRecipientInfo *ori; + } d; +}; + +typedef CMS_SignerIdentifier CMS_RecipientIdentifier; + +struct CMS_KeyTransRecipientInfo_st { + long version; + CMS_RecipientIdentifier *rid; + X509_ALGOR *keyEncryptionAlgorithm; + ASN1_OCTET_STRING *encryptedKey; + /* Recipient Key and cert */ + X509 *recip; + EVP_PKEY *pkey; +}; + +struct CMS_KeyAgreeRecipientInfo_st { + long version; + CMS_OriginatorIdentifierOrKey *originator; + ASN1_OCTET_STRING *ukm; + X509_ALGOR *keyEncryptionAlgorithm; + STACK_OF(CMS_RecipientEncryptedKey) *recipientEncryptedKeys; +}; + +struct CMS_OriginatorIdentifierOrKey_st { + int type; + union { + CMS_IssuerAndSerialNumber *issuerAndSerialNumber; + ASN1_OCTET_STRING *subjectKeyIdentifier; + CMS_OriginatorPublicKey *originatorKey; + } d; +}; + +struct CMS_OriginatorPublicKey_st { + X509_ALGOR *algorithm; + ASN1_BIT_STRING *publicKey; +}; + +struct CMS_RecipientEncryptedKey_st { + CMS_KeyAgreeRecipientIdentifier *rid; + ASN1_OCTET_STRING *encryptedKey; +}; + +struct CMS_KeyAgreeRecipientIdentifier_st { + int type; + union { + CMS_IssuerAndSerialNumber *issuerAndSerialNumber; + CMS_RecipientKeyIdentifier *rKeyId; + } d; +}; + +struct CMS_RecipientKeyIdentifier_st { + ASN1_OCTET_STRING *subjectKeyIdentifier; + ASN1_GENERALIZEDTIME *date; + CMS_OtherKeyAttribute *other; +}; + +struct CMS_KEKRecipientInfo_st { + long version; + CMS_KEKIdentifier *kekid; + X509_ALGOR *keyEncryptionAlgorithm; + ASN1_OCTET_STRING *encryptedKey; + /* Extra info: symmetric key to use */ + unsigned char *key; + size_t keylen; +}; + +struct CMS_KEKIdentifier_st { + ASN1_OCTET_STRING *keyIdentifier; + ASN1_GENERALIZEDTIME *date; + CMS_OtherKeyAttribute *other; +}; + +struct CMS_PasswordRecipientInfo_st { + long version; + X509_ALGOR *keyDerivationAlgorithm; + X509_ALGOR *keyEncryptionAlgorithm; + ASN1_OCTET_STRING *encryptedKey; + /* Extra info: password to use */ + unsigned char *pass; + size_t passlen; +}; + +struct CMS_OtherRecipientInfo_st { + ASN1_OBJECT *oriType; + ASN1_TYPE *oriValue; +}; + +struct CMS_DigestedData_st { + long version; + X509_ALGOR *digestAlgorithm; + CMS_EncapsulatedContentInfo *encapContentInfo; + ASN1_OCTET_STRING *digest; +}; + +struct CMS_EncryptedData_st { + long version; + CMS_EncryptedContentInfo *encryptedContentInfo; + STACK_OF(X509_ATTRIBUTE) *unprotectedAttrs; +}; + +struct CMS_AuthenticatedData_st { + long version; + CMS_OriginatorInfo *originatorInfo; + STACK_OF(CMS_RecipientInfo) *recipientInfos; + X509_ALGOR *macAlgorithm; + X509_ALGOR *digestAlgorithm; + CMS_EncapsulatedContentInfo *encapContentInfo; + STACK_OF(X509_ATTRIBUTE) *authAttrs; + ASN1_OCTET_STRING *mac; + STACK_OF(X509_ATTRIBUTE) *unauthAttrs; +}; + +struct CMS_CompressedData_st { + long version; + X509_ALGOR *compressionAlgorithm; + STACK_OF(CMS_RecipientInfo) *recipientInfos; + CMS_EncapsulatedContentInfo *encapContentInfo; +}; + +struct CMS_RevocationInfoChoice_st { + int type; + union { + X509_CRL *crl; + CMS_OtherRevocationInfoFormat *other; + } d; +}; + +# define CMS_REVCHOICE_CRL 0 +# define CMS_REVCHOICE_OTHER 1 + +struct CMS_OtherRevocationInfoFormat_st { + ASN1_OBJECT *otherRevInfoFormat; + ASN1_TYPE *otherRevInfo; +}; + +struct CMS_CertificateChoices { + int type; + union { + X509 *certificate; + ASN1_STRING *extendedCertificate; /* Obsolete */ + ASN1_STRING *v1AttrCert; /* Left encoded for now */ + ASN1_STRING *v2AttrCert; /* Left encoded for now */ + CMS_OtherCertificateFormat *other; + } d; +}; + +# define CMS_CERTCHOICE_CERT 0 +# define CMS_CERTCHOICE_EXCERT 1 +# define CMS_CERTCHOICE_V1ACERT 2 +# define CMS_CERTCHOICE_V2ACERT 3 +# define CMS_CERTCHOICE_OTHER 4 + +struct CMS_OtherCertificateFormat_st { + ASN1_OBJECT *otherCertFormat; + ASN1_TYPE *otherCert; +}; + +/* + * This is also defined in pkcs7.h but we duplicate it to allow the CMS code + * to be independent of PKCS#7 + */ + +struct CMS_IssuerAndSerialNumber_st { + X509_NAME *issuer; + ASN1_INTEGER *serialNumber; +}; + +struct CMS_OtherKeyAttribute_st { + ASN1_OBJECT *keyAttrId; + ASN1_TYPE *keyAttr; +}; + +/* ESS structures */ + +# ifdef HEADER_X509V3_H + +struct CMS_ReceiptRequest_st { + ASN1_OCTET_STRING *signedContentIdentifier; + CMS_ReceiptsFrom *receiptsFrom; + STACK_OF(GENERAL_NAMES) *receiptsTo; +}; + +struct CMS_ReceiptsFrom_st { + int type; + union { + long allOrFirstTier; + STACK_OF(GENERAL_NAMES) *receiptList; + } d; +}; +# endif + +struct CMS_Receipt_st { + long version; + ASN1_OBJECT *contentType; + ASN1_OCTET_STRING *signedContentIdentifier; + ASN1_OCTET_STRING *originatorSignatureValue; +}; + +DECLARE_ASN1_FUNCTIONS(CMS_ContentInfo) +DECLARE_ASN1_ITEM(CMS_SignerInfo) +DECLARE_ASN1_ITEM(CMS_IssuerAndSerialNumber) +DECLARE_ASN1_ITEM(CMS_Attributes_Sign) +DECLARE_ASN1_ITEM(CMS_Attributes_Verify) +DECLARE_ASN1_ITEM(CMS_RecipientInfo) +DECLARE_ASN1_ITEM(CMS_PasswordRecipientInfo) +DECLARE_ASN1_ALLOC_FUNCTIONS(CMS_IssuerAndSerialNumber) + +# define CMS_SIGNERINFO_ISSUER_SERIAL 0 +# define CMS_SIGNERINFO_KEYIDENTIFIER 1 + +# define CMS_RECIPINFO_ISSUER_SERIAL 0 +# define CMS_RECIPINFO_KEYIDENTIFIER 1 + +BIO *cms_content_bio(CMS_ContentInfo *cms); + +CMS_ContentInfo *cms_Data_create(void); + +CMS_ContentInfo *cms_DigestedData_create(const EVP_MD *md); +BIO *cms_DigestedData_init_bio(CMS_ContentInfo *cms); +int cms_DigestedData_do_final(CMS_ContentInfo *cms, BIO *chain, int verify); + +BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms); +int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain); +int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, + int type); +int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno); +int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert); + +CMS_ContentInfo *cms_CompressedData_create(int comp_nid); +BIO *cms_CompressedData_init_bio(CMS_ContentInfo *cms); + +void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md); +BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm); +int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, + X509_ALGOR *mdalg); + +BIO *cms_EncryptedContent_init_bio(CMS_EncryptedContentInfo *ec); +BIO *cms_EncryptedData_init_bio(CMS_ContentInfo *cms); +int cms_EncryptedContent_init(CMS_EncryptedContentInfo *ec, + const EVP_CIPHER *cipher, + const unsigned char *key, size_t keylen); + +int cms_Receipt_verify(CMS_ContentInfo *cms, CMS_ContentInfo *req_cms); +int cms_msgSigDigest_add1(CMS_SignerInfo *dest, CMS_SignerInfo *src); +ASN1_OCTET_STRING *cms_encode_Receipt(CMS_SignerInfo *si); + +BIO *cms_EnvelopedData_init_bio(CMS_ContentInfo *cms); +CMS_EnvelopedData *cms_get0_enveloped(CMS_ContentInfo *cms); + +/* PWRI routines */ +int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, + int en_de); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/cms/cms_lib.c b/libs/openssl/crypto/cms/cms_lib.c new file mode 100644 index 00000000..e9384616 --- /dev/null +++ b/libs/openssl/crypto/cms/cms_lib.c @@ -0,0 +1,595 @@ +/* crypto/cms/cms_lib.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include +#include +#include +#include +#include "cms.h" +#include "cms_lcl.h" + +IMPLEMENT_ASN1_FUNCTIONS(CMS_ContentInfo) +IMPLEMENT_ASN1_PRINT_FUNCTION(CMS_ContentInfo) + +DECLARE_ASN1_ITEM(CMS_CertificateChoices) +DECLARE_ASN1_ITEM(CMS_RevocationInfoChoice) +DECLARE_STACK_OF(CMS_CertificateChoices) +DECLARE_STACK_OF(CMS_RevocationInfoChoice) + +const ASN1_OBJECT *CMS_get0_type(CMS_ContentInfo *cms) +{ + return cms->contentType; +} + +CMS_ContentInfo *cms_Data_create(void) +{ + CMS_ContentInfo *cms; + cms = CMS_ContentInfo_new(); + if (cms) { + cms->contentType = OBJ_nid2obj(NID_pkcs7_data); + /* Never detached */ + CMS_set_detached(cms, 0); + } + return cms; +} + +BIO *cms_content_bio(CMS_ContentInfo *cms) +{ + ASN1_OCTET_STRING **pos = CMS_get0_content(cms); + if (!pos) + return NULL; + /* If content detached data goes nowhere: create NULL BIO */ + if (!*pos) + return BIO_new(BIO_s_null()); + /* + * If content not detached and created return memory BIO + */ + if (!*pos || ((*pos)->flags == ASN1_STRING_FLAG_CONT)) + return BIO_new(BIO_s_mem()); + /* Else content was read in: return read only BIO for it */ + return BIO_new_mem_buf((*pos)->data, (*pos)->length); +} + +BIO *CMS_dataInit(CMS_ContentInfo *cms, BIO *icont) +{ + BIO *cmsbio, *cont; + if (icont) + cont = icont; + else + cont = cms_content_bio(cms); + if (!cont) { + CMSerr(CMS_F_CMS_DATAINIT, CMS_R_NO_CONTENT); + return NULL; + } + switch (OBJ_obj2nid(cms->contentType)) { + + case NID_pkcs7_data: + return cont; + + case NID_pkcs7_signed: + cmsbio = cms_SignedData_init_bio(cms); + break; + + case NID_pkcs7_digest: + cmsbio = cms_DigestedData_init_bio(cms); + break; +#ifdef ZLIB + case NID_id_smime_ct_compressedData: + cmsbio = cms_CompressedData_init_bio(cms); + break; +#endif + + case NID_pkcs7_encrypted: + cmsbio = cms_EncryptedData_init_bio(cms); + break; + + case NID_pkcs7_enveloped: + cmsbio = cms_EnvelopedData_init_bio(cms); + break; + + default: + CMSerr(CMS_F_CMS_DATAINIT, CMS_R_UNSUPPORTED_TYPE); + return NULL; + } + + if (cmsbio) + return BIO_push(cmsbio, cont); + + if (!icont) + BIO_free(cont); + return NULL; + +} + +int CMS_dataFinal(CMS_ContentInfo *cms, BIO *cmsbio) +{ + ASN1_OCTET_STRING **pos = CMS_get0_content(cms); + if (!pos) + return 0; + /* If ebmedded content find memory BIO and set content */ + if (*pos && ((*pos)->flags & ASN1_STRING_FLAG_CONT)) { + BIO *mbio; + unsigned char *cont; + long contlen; + mbio = BIO_find_type(cmsbio, BIO_TYPE_MEM); + if (!mbio) { + CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_CONTENT_NOT_FOUND); + return 0; + } + contlen = BIO_get_mem_data(mbio, &cont); + /* Set bio as read only so its content can't be clobbered */ + BIO_set_flags(mbio, BIO_FLAGS_MEM_RDONLY); + BIO_set_mem_eof_return(mbio, 0); + ASN1_STRING_set0(*pos, cont, contlen); + (*pos)->flags &= ~ASN1_STRING_FLAG_CONT; + } + + switch (OBJ_obj2nid(cms->contentType)) { + + case NID_pkcs7_data: + case NID_pkcs7_enveloped: + case NID_pkcs7_encrypted: + case NID_id_smime_ct_compressedData: + /* Nothing to do */ + return 1; + + case NID_pkcs7_signed: + return cms_SignedData_final(cms, cmsbio); + + case NID_pkcs7_digest: + return cms_DigestedData_do_final(cms, cmsbio, 0); + + default: + CMSerr(CMS_F_CMS_DATAFINAL, CMS_R_UNSUPPORTED_TYPE); + return 0; + } +} + +/* + * Return an OCTET STRING pointer to content. This allows it to be accessed + * or set later. + */ + +ASN1_OCTET_STRING **CMS_get0_content(CMS_ContentInfo *cms) +{ + switch (OBJ_obj2nid(cms->contentType)) { + + case NID_pkcs7_data: + return &cms->d.data; + + case NID_pkcs7_signed: + return &cms->d.signedData->encapContentInfo->eContent; + + case NID_pkcs7_enveloped: + return &cms->d.envelopedData->encryptedContentInfo->encryptedContent; + + case NID_pkcs7_digest: + return &cms->d.digestedData->encapContentInfo->eContent; + + case NID_pkcs7_encrypted: + return &cms->d.encryptedData->encryptedContentInfo->encryptedContent; + + case NID_id_smime_ct_authData: + return &cms->d.authenticatedData->encapContentInfo->eContent; + + case NID_id_smime_ct_compressedData: + return &cms->d.compressedData->encapContentInfo->eContent; + + default: + if (cms->d.other->type == V_ASN1_OCTET_STRING) + return &cms->d.other->value.octet_string; + CMSerr(CMS_F_CMS_GET0_CONTENT, CMS_R_UNSUPPORTED_CONTENT_TYPE); + return NULL; + + } +} + +/* + * Return an ASN1_OBJECT pointer to content type. This allows it to be + * accessed or set later. + */ + +static ASN1_OBJECT **cms_get0_econtent_type(CMS_ContentInfo *cms) +{ + switch (OBJ_obj2nid(cms->contentType)) { + + case NID_pkcs7_signed: + return &cms->d.signedData->encapContentInfo->eContentType; + + case NID_pkcs7_enveloped: + return &cms->d.envelopedData->encryptedContentInfo->contentType; + + case NID_pkcs7_digest: + return &cms->d.digestedData->encapContentInfo->eContentType; + + case NID_pkcs7_encrypted: + return &cms->d.encryptedData->encryptedContentInfo->contentType; + + case NID_id_smime_ct_authData: + return &cms->d.authenticatedData->encapContentInfo->eContentType; + + case NID_id_smime_ct_compressedData: + return &cms->d.compressedData->encapContentInfo->eContentType; + + default: + CMSerr(CMS_F_CMS_GET0_ECONTENT_TYPE, CMS_R_UNSUPPORTED_CONTENT_TYPE); + return NULL; + + } +} + +const ASN1_OBJECT *CMS_get0_eContentType(CMS_ContentInfo *cms) +{ + ASN1_OBJECT **petype; + petype = cms_get0_econtent_type(cms); + if (petype) + return *petype; + return NULL; +} + +int CMS_set1_eContentType(CMS_ContentInfo *cms, const ASN1_OBJECT *oid) +{ + ASN1_OBJECT **petype, *etype; + petype = cms_get0_econtent_type(cms); + if (!petype) + return 0; + if (!oid) + return 1; + etype = OBJ_dup(oid); + if (!etype) + return 0; + ASN1_OBJECT_free(*petype); + *petype = etype; + return 1; +} + +int CMS_is_detached(CMS_ContentInfo *cms) +{ + ASN1_OCTET_STRING **pos; + pos = CMS_get0_content(cms); + if (!pos) + return -1; + if (*pos) + return 0; + return 1; +} + +int CMS_set_detached(CMS_ContentInfo *cms, int detached) +{ + ASN1_OCTET_STRING **pos; + pos = CMS_get0_content(cms); + if (!pos) + return 0; + if (detached) { + if (*pos) { + ASN1_OCTET_STRING_free(*pos); + *pos = NULL; + } + return 1; + } + if (!*pos) + *pos = ASN1_OCTET_STRING_new(); + if (*pos) { + /* + * NB: special flag to show content is created and not read in. + */ + (*pos)->flags |= ASN1_STRING_FLAG_CONT; + return 1; + } + CMSerr(CMS_F_CMS_SET_DETACHED, ERR_R_MALLOC_FAILURE); + return 0; +} + +/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */ + +void cms_DigestAlgorithm_set(X509_ALGOR *alg, const EVP_MD *md) +{ + int param_type; + + if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT) + param_type = V_ASN1_UNDEF; + else + param_type = V_ASN1_NULL; + + X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL); + +} + +/* Create a digest BIO from an X509_ALGOR structure */ + +BIO *cms_DigestAlgorithm_init_bio(X509_ALGOR *digestAlgorithm) +{ + BIO *mdbio = NULL; + ASN1_OBJECT *digestoid; + const EVP_MD *digest; + X509_ALGOR_get0(&digestoid, NULL, NULL, digestAlgorithm); + digest = EVP_get_digestbyobj(digestoid); + if (!digest) { + CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, + CMS_R_UNKNOWN_DIGEST_ALGORIHM); + goto err; + } + mdbio = BIO_new(BIO_f_md()); + if (!mdbio || !BIO_set_md(mdbio, digest)) { + CMSerr(CMS_F_CMS_DIGESTALGORITHM_INIT_BIO, CMS_R_MD_BIO_INIT_ERROR); + goto err; + } + return mdbio; + err: + if (mdbio) + BIO_free(mdbio); + return NULL; +} + +/* Locate a message digest content from a BIO chain based on SignerInfo */ + +int cms_DigestAlgorithm_find_ctx(EVP_MD_CTX *mctx, BIO *chain, + X509_ALGOR *mdalg) +{ + int nid; + ASN1_OBJECT *mdoid; + X509_ALGOR_get0(&mdoid, NULL, NULL, mdalg); + nid = OBJ_obj2nid(mdoid); + /* Look for digest type to match signature */ + for (;;) { + EVP_MD_CTX *mtmp; + chain = BIO_find_type(chain, BIO_TYPE_MD); + if (chain == NULL) { + CMSerr(CMS_F_CMS_DIGESTALGORITHM_FIND_CTX, + CMS_R_NO_MATCHING_DIGEST); + return 0; + } + BIO_get_md_ctx(chain, &mtmp); + if (EVP_MD_CTX_type(mtmp) == nid + /* + * Workaround for broken implementations that use signature + * algorithm OID instead of digest. + */ + || EVP_MD_pkey_type(EVP_MD_CTX_md(mtmp)) == nid) + return EVP_MD_CTX_copy_ex(mctx, mtmp); + chain = BIO_next(chain); + } +} + +static STACK_OF(CMS_CertificateChoices) +**cms_get0_certificate_choices(CMS_ContentInfo *cms) +{ + switch (OBJ_obj2nid(cms->contentType)) { + + case NID_pkcs7_signed: + return &cms->d.signedData->certificates; + + case NID_pkcs7_enveloped: + return &cms->d.envelopedData->originatorInfo->certificates; + + default: + CMSerr(CMS_F_CMS_GET0_CERTIFICATE_CHOICES, + CMS_R_UNSUPPORTED_CONTENT_TYPE); + return NULL; + + } +} + +CMS_CertificateChoices *CMS_add0_CertificateChoices(CMS_ContentInfo *cms) +{ + STACK_OF(CMS_CertificateChoices) **pcerts; + CMS_CertificateChoices *cch; + pcerts = cms_get0_certificate_choices(cms); + if (!pcerts) + return NULL; + if (!*pcerts) + *pcerts = sk_CMS_CertificateChoices_new_null(); + if (!*pcerts) + return NULL; + cch = M_ASN1_new_of(CMS_CertificateChoices); + if (!cch) + return NULL; + if (!sk_CMS_CertificateChoices_push(*pcerts, cch)) { + M_ASN1_free_of(cch, CMS_CertificateChoices); + return NULL; + } + return cch; +} + +int CMS_add0_cert(CMS_ContentInfo *cms, X509 *cert) +{ + CMS_CertificateChoices *cch; + STACK_OF(CMS_CertificateChoices) **pcerts; + int i; + pcerts = cms_get0_certificate_choices(cms); + if (!pcerts) + return 0; + for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { + cch = sk_CMS_CertificateChoices_value(*pcerts, i); + if (cch->type == CMS_CERTCHOICE_CERT) { + if (!X509_cmp(cch->d.certificate, cert)) { + CMSerr(CMS_F_CMS_ADD0_CERT, + CMS_R_CERTIFICATE_ALREADY_PRESENT); + return 0; + } + } + } + cch = CMS_add0_CertificateChoices(cms); + if (!cch) + return 0; + cch->type = CMS_CERTCHOICE_CERT; + cch->d.certificate = cert; + return 1; +} + +int CMS_add1_cert(CMS_ContentInfo *cms, X509 *cert) +{ + int r; + r = CMS_add0_cert(cms, cert); + if (r > 0) + CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); + return r; +} + +static STACK_OF(CMS_RevocationInfoChoice) +**cms_get0_revocation_choices(CMS_ContentInfo *cms) +{ + switch (OBJ_obj2nid(cms->contentType)) { + + case NID_pkcs7_signed: + return &cms->d.signedData->crls; + + case NID_pkcs7_enveloped: + return &cms->d.envelopedData->originatorInfo->crls; + + default: + CMSerr(CMS_F_CMS_GET0_REVOCATION_CHOICES, + CMS_R_UNSUPPORTED_CONTENT_TYPE); + return NULL; + + } +} + +CMS_RevocationInfoChoice *CMS_add0_RevocationInfoChoice(CMS_ContentInfo *cms) +{ + STACK_OF(CMS_RevocationInfoChoice) **pcrls; + CMS_RevocationInfoChoice *rch; + pcrls = cms_get0_revocation_choices(cms); + if (!pcrls) + return NULL; + if (!*pcrls) + *pcrls = sk_CMS_RevocationInfoChoice_new_null(); + if (!*pcrls) + return NULL; + rch = M_ASN1_new_of(CMS_RevocationInfoChoice); + if (!rch) + return NULL; + if (!sk_CMS_RevocationInfoChoice_push(*pcrls, rch)) { + M_ASN1_free_of(rch, CMS_RevocationInfoChoice); + return NULL; + } + return rch; +} + +int CMS_add0_crl(CMS_ContentInfo *cms, X509_CRL *crl) +{ + CMS_RevocationInfoChoice *rch; + rch = CMS_add0_RevocationInfoChoice(cms); + if (!rch) + return 0; + rch->type = CMS_REVCHOICE_CRL; + rch->d.crl = crl; + return 1; +} + +int CMS_add1_crl(CMS_ContentInfo *cms, X509_CRL *crl) +{ + int r; + r = CMS_add0_crl(cms, crl); + if (r > 0) + CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); + return r; +} + +STACK_OF(X509) *CMS_get1_certs(CMS_ContentInfo *cms) +{ + STACK_OF(X509) *certs = NULL; + CMS_CertificateChoices *cch; + STACK_OF(CMS_CertificateChoices) **pcerts; + int i; + pcerts = cms_get0_certificate_choices(cms); + if (!pcerts) + return NULL; + for (i = 0; i < sk_CMS_CertificateChoices_num(*pcerts); i++) { + cch = sk_CMS_CertificateChoices_value(*pcerts, i); + if (cch->type == 0) { + if (!certs) { + certs = sk_X509_new_null(); + if (!certs) + return NULL; + } + if (!sk_X509_push(certs, cch->d.certificate)) { + sk_X509_pop_free(certs, X509_free); + return NULL; + } + CRYPTO_add(&cch->d.certificate->references, 1, CRYPTO_LOCK_X509); + } + } + return certs; + +} + +STACK_OF(X509_CRL) *CMS_get1_crls(CMS_ContentInfo *cms) +{ + STACK_OF(X509_CRL) *crls = NULL; + STACK_OF(CMS_RevocationInfoChoice) **pcrls; + CMS_RevocationInfoChoice *rch; + int i; + pcrls = cms_get0_revocation_choices(cms); + if (!pcrls) + return NULL; + for (i = 0; i < sk_CMS_RevocationInfoChoice_num(*pcrls); i++) { + rch = sk_CMS_RevocationInfoChoice_value(*pcrls, i); + if (rch->type == 0) { + if (!crls) { + crls = sk_X509_CRL_new_null(); + if (!crls) + return NULL; + } + if (!sk_X509_CRL_push(crls, rch->d.crl)) { + sk_X509_CRL_pop_free(crls, X509_CRL_free); + return NULL; + } + CRYPTO_add(&rch->d.crl->references, 1, CRYPTO_LOCK_X509_CRL); + } + } + return crls; +} diff --git a/libs/openssl/crypto/cms/cms_pwri.c b/libs/openssl/crypto/cms/cms_pwri.c new file mode 100644 index 00000000..b91c0169 --- /dev/null +++ b/libs/openssl/crypto/cms/cms_pwri.c @@ -0,0 +1,435 @@ +/* crypto/cms/cms_pwri.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2009 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include +#include "cms_lcl.h" +#include "asn1_locl.h" + +int CMS_RecipientInfo_set0_password(CMS_RecipientInfo *ri, + unsigned char *pass, ossl_ssize_t passlen) +{ + CMS_PasswordRecipientInfo *pwri; + if (ri->type != CMS_RECIPINFO_PASS) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_SET0_PASSWORD, CMS_R_NOT_PWRI); + return 0; + } + + pwri = ri->d.pwri; + pwri->pass = pass; + if (pass && passlen < 0) + passlen = strlen((char *)pass); + pwri->passlen = passlen; + return 1; +} + +CMS_RecipientInfo *CMS_add0_recipient_password(CMS_ContentInfo *cms, + int iter, int wrap_nid, + int pbe_nid, + unsigned char *pass, + ossl_ssize_t passlen, + const EVP_CIPHER *kekciph) +{ + CMS_RecipientInfo *ri = NULL; + CMS_EnvelopedData *env; + CMS_PasswordRecipientInfo *pwri; + EVP_CIPHER_CTX ctx; + X509_ALGOR *encalg = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + int ivlen; + + env = cms_get0_enveloped(cms); + if (!env) + return NULL; + + if (wrap_nid <= 0) + wrap_nid = NID_id_alg_PWRI_KEK; + + if (pbe_nid <= 0) + pbe_nid = NID_id_pbkdf2; + + /* Get from enveloped data */ + if (kekciph == NULL) + kekciph = env->encryptedContentInfo->cipher; + + if (kekciph == NULL) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, CMS_R_NO_CIPHER); + return NULL; + } + if (wrap_nid != NID_id_alg_PWRI_KEK) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, + CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); + return NULL; + } + + /* Setup algorithm identifier for cipher */ + encalg = X509_ALGOR_new(); + if (encalg == NULL) { + goto merr; + } + EVP_CIPHER_CTX_init(&ctx); + + if (EVP_EncryptInit_ex(&ctx, kekciph, NULL, NULL, NULL) <= 0) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); + goto err; + } + + ivlen = EVP_CIPHER_CTX_iv_length(&ctx); + + if (ivlen > 0) { + if (RAND_pseudo_bytes(iv, ivlen) <= 0) + goto err; + if (EVP_EncryptInit_ex(&ctx, NULL, NULL, NULL, iv) <= 0) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_EVP_LIB); + goto err; + } + encalg->parameter = ASN1_TYPE_new(); + if (!encalg->parameter) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); + goto err; + } + if (EVP_CIPHER_param_to_asn1(&ctx, encalg->parameter) <= 0) { + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + } + + encalg->algorithm = OBJ_nid2obj(EVP_CIPHER_CTX_type(&ctx)); + + EVP_CIPHER_CTX_cleanup(&ctx); + + /* Initialize recipient info */ + ri = M_ASN1_new_of(CMS_RecipientInfo); + if (!ri) + goto merr; + + ri->d.pwri = M_ASN1_new_of(CMS_PasswordRecipientInfo); + if (!ri->d.pwri) + goto merr; + ri->type = CMS_RECIPINFO_PASS; + + pwri = ri->d.pwri; + /* Since this is overwritten, free up empty structure already there */ + X509_ALGOR_free(pwri->keyEncryptionAlgorithm); + pwri->keyEncryptionAlgorithm = X509_ALGOR_new(); + if (!pwri->keyEncryptionAlgorithm) + goto merr; + pwri->keyEncryptionAlgorithm->algorithm = OBJ_nid2obj(wrap_nid); + pwri->keyEncryptionAlgorithm->parameter = ASN1_TYPE_new(); + if (!pwri->keyEncryptionAlgorithm->parameter) + goto merr; + + if (!ASN1_item_pack(encalg, ASN1_ITEM_rptr(X509_ALGOR), + &pwri->keyEncryptionAlgorithm->parameter-> + value.sequence)) + goto merr; + pwri->keyEncryptionAlgorithm->parameter->type = V_ASN1_SEQUENCE; + + X509_ALGOR_free(encalg); + encalg = NULL; + + /* Setup PBE algorithm */ + + pwri->keyDerivationAlgorithm = PKCS5_pbkdf2_set(iter, NULL, 0, -1, -1); + + if (!pwri->keyDerivationAlgorithm) + goto err; + + CMS_RecipientInfo_set0_password(ri, pass, passlen); + pwri->version = 0; + + if (!sk_CMS_RecipientInfo_push(env->recipientInfos, ri)) + goto merr; + + return ri; + + merr: + CMSerr(CMS_F_CMS_ADD0_RECIPIENT_PASSWORD, ERR_R_MALLOC_FAILURE); + err: + EVP_CIPHER_CTX_cleanup(&ctx); + if (ri) + M_ASN1_free_of(ri, CMS_RecipientInfo); + if (encalg) + X509_ALGOR_free(encalg); + return NULL; + +} + +/* + * This is an implementation of the key wrapping mechanism in RFC3211, at + * some point this should go into EVP. + */ + +static int kek_unwrap_key(unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen, + EVP_CIPHER_CTX *ctx) +{ + size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); + unsigned char *tmp; + int outl, rv = 0; + if (inlen < 2 * blocklen) { + /* too small */ + return 0; + } + if (inlen % blocklen) { + /* Invalid size */ + return 0; + } + tmp = OPENSSL_malloc(inlen); + if (!tmp) + return 0; + /* setup IV by decrypting last two blocks */ + EVP_DecryptUpdate(ctx, tmp + inlen - 2 * blocklen, &outl, + in + inlen - 2 * blocklen, blocklen * 2); + /* + * Do a decrypt of last decrypted block to set IV to correct value output + * it to start of buffer so we don't corrupt decrypted block this works + * because buffer is at least two block lengths long. + */ + EVP_DecryptUpdate(ctx, tmp, &outl, tmp + inlen - blocklen, blocklen); + /* Can now decrypt first n - 1 blocks */ + EVP_DecryptUpdate(ctx, tmp, &outl, in, inlen - blocklen); + + /* Reset IV to original value */ + EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL); + /* Decrypt again */ + EVP_DecryptUpdate(ctx, tmp, &outl, tmp, inlen); + /* Check check bytes */ + if (((tmp[1] ^ tmp[4]) & (tmp[2] ^ tmp[5]) & (tmp[3] ^ tmp[6])) != 0xff) { + /* Check byte failure */ + goto err; + } + if (inlen < (size_t)(tmp[0] - 4)) { + /* Invalid length value */ + goto err; + } + *outlen = (size_t)tmp[0]; + memcpy(out, tmp + 4, *outlen); + rv = 1; + err: + OPENSSL_cleanse(tmp, inlen); + OPENSSL_free(tmp); + return rv; + +} + +static int kek_wrap_key(unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen, + EVP_CIPHER_CTX *ctx) +{ + size_t blocklen = EVP_CIPHER_CTX_block_size(ctx); + size_t olen; + int dummy; + /* + * First decide length of output buffer: need header and round up to + * multiple of block length. + */ + olen = (inlen + 4 + blocklen - 1) / blocklen; + olen *= blocklen; + if (olen < 2 * blocklen) { + /* Key too small */ + return 0; + } + if (inlen > 0xFF) { + /* Key too large */ + return 0; + } + if (out) { + /* Set header */ + out[0] = (unsigned char)inlen; + out[1] = in[0] ^ 0xFF; + out[2] = in[1] ^ 0xFF; + out[3] = in[2] ^ 0xFF; + memcpy(out + 4, in, inlen); + /* Add random padding to end */ + if (olen > inlen + 4 + && RAND_pseudo_bytes(out + 4 + inlen, olen - 4 - inlen) < 0) + return 0; + /* Encrypt twice */ + EVP_EncryptUpdate(ctx, out, &dummy, out, olen); + EVP_EncryptUpdate(ctx, out, &dummy, out, olen); + } + + *outlen = olen; + + return 1; +} + +/* Encrypt/Decrypt content key in PWRI recipient info */ + +int cms_RecipientInfo_pwri_crypt(CMS_ContentInfo *cms, CMS_RecipientInfo *ri, + int en_de) +{ + CMS_EncryptedContentInfo *ec; + CMS_PasswordRecipientInfo *pwri; + const unsigned char *p = NULL; + int plen; + int r = 0; + X509_ALGOR *algtmp, *kekalg = NULL; + EVP_CIPHER_CTX kekctx; + const EVP_CIPHER *kekcipher; + unsigned char *key = NULL; + size_t keylen; + + ec = cms->d.envelopedData->encryptedContentInfo; + + pwri = ri->d.pwri; + EVP_CIPHER_CTX_init(&kekctx); + + if (!pwri->pass) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_NO_PASSWORD); + return 0; + } + algtmp = pwri->keyEncryptionAlgorithm; + + if (!algtmp || OBJ_obj2nid(algtmp->algorithm) != NID_id_alg_PWRI_KEK) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, + CMS_R_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM); + return 0; + } + + if (algtmp->parameter->type == V_ASN1_SEQUENCE) { + p = algtmp->parameter->value.sequence->data; + plen = algtmp->parameter->value.sequence->length; + kekalg = d2i_X509_ALGOR(NULL, &p, plen); + } + if (kekalg == NULL) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, + CMS_R_INVALID_KEY_ENCRYPTION_PARAMETER); + return 0; + } + + kekcipher = EVP_get_cipherbyobj(kekalg->algorithm); + + if (!kekcipher) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNKNOWN_CIPHER); + goto err; + } + + /* Fixup cipher based on AlgorithmIdentifier to set IV etc */ + if (!EVP_CipherInit_ex(&kekctx, kekcipher, NULL, NULL, NULL, en_de)) + goto err; + EVP_CIPHER_CTX_set_padding(&kekctx, 0); + if (EVP_CIPHER_asn1_to_param(&kekctx, kekalg->parameter) < 0) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, + CMS_R_CIPHER_PARAMETER_INITIALISATION_ERROR); + goto err; + } + + algtmp = pwri->keyDerivationAlgorithm; + + /* Finish password based key derivation to setup key in "ctx" */ + + if (EVP_PBE_CipherInit(algtmp->algorithm, + (char *)pwri->pass, pwri->passlen, + algtmp->parameter, &kekctx, en_de) < 0) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_EVP_LIB); + goto err; + } + + /* Finally wrap/unwrap the key */ + + if (en_de) { + + if (!kek_wrap_key(NULL, &keylen, ec->key, ec->keylen, &kekctx)) + goto err; + + key = OPENSSL_malloc(keylen); + + if (!key) + goto err; + + if (!kek_wrap_key(key, &keylen, ec->key, ec->keylen, &kekctx)) + goto err; + pwri->encryptedKey->data = key; + pwri->encryptedKey->length = keylen; + } else { + key = OPENSSL_malloc(pwri->encryptedKey->length); + + if (!key) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!kek_unwrap_key(key, &keylen, + pwri->encryptedKey->data, + pwri->encryptedKey->length, &kekctx)) { + CMSerr(CMS_F_CMS_RECIPIENTINFO_PWRI_CRYPT, CMS_R_UNWRAP_FAILURE); + goto err; + } + + ec->key = key; + ec->keylen = keylen; + + } + + r = 1; + + err: + + EVP_CIPHER_CTX_cleanup(&kekctx); + + if (!r && key) + OPENSSL_free(key); + X509_ALGOR_free(kekalg); + + return r; + +} diff --git a/libs/openssl/crypto/cms/cms_sd.c b/libs/openssl/crypto/cms/cms_sd.c new file mode 100644 index 00000000..6daa2627 --- /dev/null +++ b/libs/openssl/crypto/cms/cms_sd.c @@ -0,0 +1,902 @@ +/* crypto/cms/cms_sd.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include "cms_lcl.h" +#include "asn1_locl.h" + +/* CMS SignedData Utilities */ + +DECLARE_ASN1_ITEM(CMS_SignedData) + +static CMS_SignedData *cms_get0_signed(CMS_ContentInfo *cms) +{ + if (OBJ_obj2nid(cms->contentType) != NID_pkcs7_signed) { + CMSerr(CMS_F_CMS_GET0_SIGNED, CMS_R_CONTENT_TYPE_NOT_SIGNED_DATA); + return NULL; + } + return cms->d.signedData; +} + +static CMS_SignedData *cms_signed_data_init(CMS_ContentInfo *cms) +{ + if (cms->d.other == NULL) { + cms->d.signedData = M_ASN1_new_of(CMS_SignedData); + if (!cms->d.signedData) { + CMSerr(CMS_F_CMS_SIGNED_DATA_INIT, ERR_R_MALLOC_FAILURE); + return NULL; + } + cms->d.signedData->version = 1; + cms->d.signedData->encapContentInfo->eContentType = + OBJ_nid2obj(NID_pkcs7_data); + cms->d.signedData->encapContentInfo->partial = 1; + ASN1_OBJECT_free(cms->contentType); + cms->contentType = OBJ_nid2obj(NID_pkcs7_signed); + return cms->d.signedData; + } + return cms_get0_signed(cms); +} + +/* Just initialize SignedData e.g. for certs only structure */ + +int CMS_SignedData_init(CMS_ContentInfo *cms) +{ + if (cms_signed_data_init(cms)) + return 1; + else + return 0; +} + +/* Check structures and fixup version numbers (if necessary) */ + +static void cms_sd_set_version(CMS_SignedData *sd) +{ + int i; + CMS_CertificateChoices *cch; + CMS_RevocationInfoChoice *rch; + CMS_SignerInfo *si; + + for (i = 0; i < sk_CMS_CertificateChoices_num(sd->certificates); i++) { + cch = sk_CMS_CertificateChoices_value(sd->certificates, i); + if (cch->type == CMS_CERTCHOICE_OTHER) { + if (sd->version < 5) + sd->version = 5; + } else if (cch->type == CMS_CERTCHOICE_V2ACERT) { + if (sd->version < 4) + sd->version = 4; + } else if (cch->type == CMS_CERTCHOICE_V1ACERT) { + if (sd->version < 3) + sd->version = 3; + } + } + + for (i = 0; i < sk_CMS_RevocationInfoChoice_num(sd->crls); i++) { + rch = sk_CMS_RevocationInfoChoice_value(sd->crls, i); + if (rch->type == CMS_REVCHOICE_OTHER) { + if (sd->version < 5) + sd->version = 5; + } + } + + if ((OBJ_obj2nid(sd->encapContentInfo->eContentType) != NID_pkcs7_data) + && (sd->version < 3)) + sd->version = 3; + + for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { + si = sk_CMS_SignerInfo_value(sd->signerInfos, i); + if (si->sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { + if (si->version < 3) + si->version = 3; + if (sd->version < 3) + sd->version = 3; + } else if (si->version < 1) + si->version = 1; + } + + if (sd->version < 1) + sd->version = 1; + +} + +/* Copy an existing messageDigest value */ + +static int cms_copy_messageDigest(CMS_ContentInfo *cms, CMS_SignerInfo *si) +{ + STACK_OF(CMS_SignerInfo) *sinfos; + CMS_SignerInfo *sitmp; + int i; + sinfos = CMS_get0_SignerInfos(cms); + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + ASN1_OCTET_STRING *messageDigest; + sitmp = sk_CMS_SignerInfo_value(sinfos, i); + if (sitmp == si) + continue; + if (CMS_signed_get_attr_count(sitmp) < 0) + continue; + if (OBJ_cmp(si->digestAlgorithm->algorithm, + sitmp->digestAlgorithm->algorithm)) + continue; + messageDigest = CMS_signed_get0_data_by_OBJ(sitmp, + OBJ_nid2obj + (NID_pkcs9_messageDigest), + -3, V_ASN1_OCTET_STRING); + if (!messageDigest) { + CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, + CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); + return 0; + } + + if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, + V_ASN1_OCTET_STRING, + messageDigest, -1)) + return 1; + else + return 0; + } + CMSerr(CMS_F_CMS_COPY_MESSAGEDIGEST, CMS_R_NO_MATCHING_DIGEST); + return 0; +} + +int cms_set1_SignerIdentifier(CMS_SignerIdentifier *sid, X509 *cert, int type) +{ + switch (type) { + case CMS_SIGNERINFO_ISSUER_SERIAL: + sid->d.issuerAndSerialNumber = + M_ASN1_new_of(CMS_IssuerAndSerialNumber); + if (!sid->d.issuerAndSerialNumber) + goto merr; + if (!X509_NAME_set(&sid->d.issuerAndSerialNumber->issuer, + X509_get_issuer_name(cert))) + goto merr; + if (!ASN1_STRING_copy(sid->d.issuerAndSerialNumber->serialNumber, + X509_get_serialNumber(cert))) + goto merr; + break; + + case CMS_SIGNERINFO_KEYIDENTIFIER: + if (!cert->skid) { + CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, + CMS_R_CERTIFICATE_HAS_NO_KEYID); + return 0; + } + sid->d.subjectKeyIdentifier = ASN1_STRING_dup(cert->skid); + if (!sid->d.subjectKeyIdentifier) + goto merr; + break; + + default: + CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, CMS_R_UNKNOWN_ID); + return 0; + } + + sid->type = type; + + return 1; + + merr: + CMSerr(CMS_F_CMS_SET1_SIGNERIDENTIFIER, ERR_R_MALLOC_FAILURE); + return 0; + +} + +int cms_SignerIdentifier_get0_signer_id(CMS_SignerIdentifier *sid, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, + ASN1_INTEGER **sno) +{ + if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) { + if (issuer) + *issuer = sid->d.issuerAndSerialNumber->issuer; + if (sno) + *sno = sid->d.issuerAndSerialNumber->serialNumber; + } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { + if (keyid) + *keyid = sid->d.subjectKeyIdentifier; + } else + return 0; + return 1; +} + +int cms_SignerIdentifier_cert_cmp(CMS_SignerIdentifier *sid, X509 *cert) +{ + int ret; + if (sid->type == CMS_SIGNERINFO_ISSUER_SERIAL) { + ret = X509_NAME_cmp(sid->d.issuerAndSerialNumber->issuer, + X509_get_issuer_name(cert)); + if (ret) + return ret; + return ASN1_INTEGER_cmp(sid->d.issuerAndSerialNumber->serialNumber, + X509_get_serialNumber(cert)); + } else if (sid->type == CMS_SIGNERINFO_KEYIDENTIFIER) { + X509_check_purpose(cert, -1, -1); + if (!cert->skid) + return -1; + return ASN1_OCTET_STRING_cmp(sid->d.subjectKeyIdentifier, cert->skid); + } else + return -1; +} + +CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms, + X509 *signer, EVP_PKEY *pk, const EVP_MD *md, + unsigned int flags) +{ + CMS_SignedData *sd; + CMS_SignerInfo *si = NULL; + X509_ALGOR *alg; + int i, type; + if (!X509_check_private_key(signer, pk)) { + CMSerr(CMS_F_CMS_ADD1_SIGNER, + CMS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + return NULL; + } + sd = cms_signed_data_init(cms); + if (!sd) + goto err; + si = M_ASN1_new_of(CMS_SignerInfo); + if (!si) + goto merr; + X509_check_purpose(signer, -1, -1); + + CRYPTO_add(&pk->references, 1, CRYPTO_LOCK_EVP_PKEY); + CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); + + si->pkey = pk; + si->signer = signer; + + if (flags & CMS_USE_KEYID) { + si->version = 3; + if (sd->version < 3) + sd->version = 3; + type = CMS_SIGNERINFO_KEYIDENTIFIER; + } else { + type = CMS_SIGNERINFO_ISSUER_SERIAL; + si->version = 1; + } + + if (!cms_set1_SignerIdentifier(si->sid, signer, type)) + goto err; + + if (md == NULL) { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pk, &def_nid) <= 0) + goto err; + md = EVP_get_digestbynid(def_nid); + if (md == NULL) { + CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DEFAULT_DIGEST); + goto err; + } + } + + if (!md) { + CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_NO_DIGEST_SET); + goto err; + } + + cms_DigestAlgorithm_set(si->digestAlgorithm, md); + + /* See if digest is present in digestAlgorithms */ + for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { + ASN1_OBJECT *aoid; + alg = sk_X509_ALGOR_value(sd->digestAlgorithms, i); + X509_ALGOR_get0(&aoid, NULL, NULL, alg); + if (OBJ_obj2nid(aoid) == EVP_MD_type(md)) + break; + } + + if (i == sk_X509_ALGOR_num(sd->digestAlgorithms)) { + alg = X509_ALGOR_new(); + if (!alg) + goto merr; + cms_DigestAlgorithm_set(alg, md); + if (!sk_X509_ALGOR_push(sd->digestAlgorithms, alg)) { + X509_ALGOR_free(alg); + goto merr; + } + } + + if (pk->ameth && pk->ameth->pkey_ctrl) { + i = pk->ameth->pkey_ctrl(pk, ASN1_PKEY_CTRL_CMS_SIGN, 0, si); + if (i == -2) { + CMSerr(CMS_F_CMS_ADD1_SIGNER, + CMS_R_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; + } + if (i <= 0) { + CMSerr(CMS_F_CMS_ADD1_SIGNER, CMS_R_CTRL_FAILURE); + goto err; + } + } + + if (!(flags & CMS_NOATTR)) { + /* + * Initialialize signed attributes strutucture so other attributes + * such as signing time etc are added later even if we add none here. + */ + if (!si->signedAttrs) { + si->signedAttrs = sk_X509_ATTRIBUTE_new_null(); + if (!si->signedAttrs) + goto merr; + } + + if (!(flags & CMS_NOSMIMECAP)) { + STACK_OF(X509_ALGOR) *smcap = NULL; + i = CMS_add_standard_smimecap(&smcap); + if (i) + i = CMS_add_smimecap(si, smcap); + sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); + if (!i) + goto merr; + } + if (flags & CMS_REUSE_DIGEST) { + if (!cms_copy_messageDigest(cms, si)) + goto err; + if (!(flags & CMS_PARTIAL) && !CMS_SignerInfo_sign(si)) + goto err; + } + } + + if (!(flags & CMS_NOCERTS)) { + /* NB ignore -1 return for duplicate cert */ + if (!CMS_add1_cert(cms, signer)) + goto merr; + } + + if (!sd->signerInfos) + sd->signerInfos = sk_CMS_SignerInfo_new_null(); + if (!sd->signerInfos || !sk_CMS_SignerInfo_push(sd->signerInfos, si)) + goto merr; + + return si; + + merr: + CMSerr(CMS_F_CMS_ADD1_SIGNER, ERR_R_MALLOC_FAILURE); + err: + if (si) + M_ASN1_free_of(si, CMS_SignerInfo); + return NULL; + +} + +static int cms_add1_signingTime(CMS_SignerInfo *si, ASN1_TIME *t) +{ + ASN1_TIME *tt; + int r = 0; + if (t) + tt = t; + else + tt = X509_gmtime_adj(NULL, 0); + + if (!tt) + goto merr; + + if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_signingTime, + tt->type, tt, -1) <= 0) + goto merr; + + r = 1; + + merr: + + if (!t) + ASN1_TIME_free(tt); + + if (!r) + CMSerr(CMS_F_CMS_ADD1_SIGNINGTIME, ERR_R_MALLOC_FAILURE); + + return r; + +} + +STACK_OF(CMS_SignerInfo) *CMS_get0_SignerInfos(CMS_ContentInfo *cms) +{ + CMS_SignedData *sd; + sd = cms_get0_signed(cms); + if (!sd) + return NULL; + return sd->signerInfos; +} + +STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms) +{ + STACK_OF(X509) *signers = NULL; + STACK_OF(CMS_SignerInfo) *sinfos; + CMS_SignerInfo *si; + int i; + sinfos = CMS_get0_SignerInfos(cms); + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (si->signer) { + if (!signers) { + signers = sk_X509_new_null(); + if (!signers) + return NULL; + } + if (!sk_X509_push(signers, si->signer)) { + sk_X509_free(signers); + return NULL; + } + } + } + return signers; +} + +void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer) +{ + if (signer) { + CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); + if (si->pkey) + EVP_PKEY_free(si->pkey); + si->pkey = X509_get_pubkey(signer); + } + if (si->signer) + X509_free(si->signer); + si->signer = signer; +} + +int CMS_SignerInfo_get0_signer_id(CMS_SignerInfo *si, + ASN1_OCTET_STRING **keyid, + X509_NAME **issuer, ASN1_INTEGER **sno) +{ + return cms_SignerIdentifier_get0_signer_id(si->sid, keyid, issuer, sno); +} + +int CMS_SignerInfo_cert_cmp(CMS_SignerInfo *si, X509 *cert) +{ + return cms_SignerIdentifier_cert_cmp(si->sid, cert); +} + +int CMS_set1_signers_certs(CMS_ContentInfo *cms, STACK_OF(X509) *scerts, + unsigned int flags) +{ + CMS_SignedData *sd; + CMS_SignerInfo *si; + CMS_CertificateChoices *cch; + STACK_OF(CMS_CertificateChoices) *certs; + X509 *x; + int i, j; + int ret = 0; + sd = cms_get0_signed(cms); + if (!sd) + return -1; + certs = sd->certificates; + for (i = 0; i < sk_CMS_SignerInfo_num(sd->signerInfos); i++) { + si = sk_CMS_SignerInfo_value(sd->signerInfos, i); + if (si->signer) + continue; + + for (j = 0; j < sk_X509_num(scerts); j++) { + x = sk_X509_value(scerts, j); + if (CMS_SignerInfo_cert_cmp(si, x) == 0) { + CMS_SignerInfo_set1_signer_cert(si, x); + ret++; + break; + } + } + + if (si->signer || (flags & CMS_NOINTERN)) + continue; + + for (j = 0; j < sk_CMS_CertificateChoices_num(certs); j++) { + cch = sk_CMS_CertificateChoices_value(certs, j); + if (cch->type != 0) + continue; + x = cch->d.certificate; + if (CMS_SignerInfo_cert_cmp(si, x) == 0) { + CMS_SignerInfo_set1_signer_cert(si, x); + ret++; + break; + } + } + } + return ret; +} + +void CMS_SignerInfo_get0_algs(CMS_SignerInfo *si, EVP_PKEY **pk, + X509 **signer, X509_ALGOR **pdig, + X509_ALGOR **psig) +{ + if (pk) + *pk = si->pkey; + if (signer) + *signer = si->signer; + if (pdig) + *pdig = si->digestAlgorithm; + if (psig) + *psig = si->signatureAlgorithm; +} + +static int cms_SignerInfo_content_sign(CMS_ContentInfo *cms, + CMS_SignerInfo *si, BIO *chain) +{ + EVP_MD_CTX mctx; + int r = 0; + EVP_MD_CTX_init(&mctx); + + if (!si->pkey) { + CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_NO_PRIVATE_KEY); + return 0; + } + + if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm)) + goto err; + + /* + * If any signed attributes calculate and add messageDigest attribute + */ + + if (CMS_signed_get_attr_count(si) >= 0) { + ASN1_OBJECT *ctype = + cms->d.signedData->encapContentInfo->eContentType; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + if (!EVP_DigestFinal_ex(&mctx, md, &mdlen)) + goto err; + if (!CMS_signed_add1_attr_by_NID(si, NID_pkcs9_messageDigest, + V_ASN1_OCTET_STRING, md, mdlen)) + goto err; + /* Copy content type across */ + if (CMS_signed_add1_attr_by_NID(si, NID_pkcs9_contentType, + V_ASN1_OBJECT, ctype, -1) <= 0) + goto err; + if (!CMS_SignerInfo_sign(si)) + goto err; + } else { + unsigned char *sig; + unsigned int siglen; + sig = OPENSSL_malloc(EVP_PKEY_size(si->pkey)); + if (!sig) { + CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EVP_SignFinal(&mctx, sig, &siglen, si->pkey)) { + CMSerr(CMS_F_CMS_SIGNERINFO_CONTENT_SIGN, CMS_R_SIGNFINAL_ERROR); + OPENSSL_free(sig); + goto err; + } + ASN1_STRING_set0(si->signature, sig, siglen); + } + + r = 1; + + err: + EVP_MD_CTX_cleanup(&mctx); + return r; + +} + +int cms_SignedData_final(CMS_ContentInfo *cms, BIO *chain) +{ + STACK_OF(CMS_SignerInfo) *sinfos; + CMS_SignerInfo *si; + int i; + sinfos = CMS_get0_SignerInfos(cms); + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (!cms_SignerInfo_content_sign(cms, si, chain)) + return 0; + } + cms->d.signedData->encapContentInfo->partial = 0; + return 1; +} + +int CMS_SignerInfo_sign(CMS_SignerInfo *si) +{ + EVP_MD_CTX mctx; + EVP_PKEY_CTX *pctx; + unsigned char *abuf = NULL; + int alen; + size_t siglen; + const EVP_MD *md = NULL; + + md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); + if (md == NULL) + return 0; + + EVP_MD_CTX_init(&mctx); + + if (CMS_signed_get_attr_by_NID(si, NID_pkcs9_signingTime, -1) < 0) { + if (!cms_add1_signingTime(si, NULL)) + goto err; + } + + if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_CMS_SIGN, 0, si) <= 0) { + CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); + goto err; + } + + alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, + ASN1_ITEM_rptr(CMS_Attributes_Sign)); + if (!abuf) + goto err; + if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) + goto err; + if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) + goto err; + OPENSSL_free(abuf); + abuf = OPENSSL_malloc(siglen); + if (!abuf) + goto err; + if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_CMS_SIGN, 1, si) <= 0) { + CMSerr(CMS_F_CMS_SIGNERINFO_SIGN, CMS_R_CTRL_ERROR); + goto err; + } + + EVP_MD_CTX_cleanup(&mctx); + + ASN1_STRING_set0(si->signature, abuf, siglen); + + return 1; + + err: + if (abuf) + OPENSSL_free(abuf); + EVP_MD_CTX_cleanup(&mctx); + return 0; + +} + +int CMS_SignerInfo_verify(CMS_SignerInfo *si) +{ + EVP_MD_CTX mctx; + EVP_PKEY_CTX *pctx; + unsigned char *abuf = NULL; + int alen, r = -1; + const EVP_MD *md = NULL; + + if (!si->pkey) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_NO_PUBLIC_KEY); + return -1; + } + + md = EVP_get_digestbyobj(si->digestAlgorithm->algorithm); + if (md == NULL) + return -1; + EVP_MD_CTX_init(&mctx); + if (EVP_DigestVerifyInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) + goto err; + + alen = ASN1_item_i2d((ASN1_VALUE *)si->signedAttrs, &abuf, + ASN1_ITEM_rptr(CMS_Attributes_Verify)); + if (!abuf) + goto err; + r = EVP_DigestVerifyUpdate(&mctx, abuf, alen); + OPENSSL_free(abuf); + if (r <= 0) { + r = -1; + goto err; + } + r = EVP_DigestVerifyFinal(&mctx, + si->signature->data, si->signature->length); + if (r <= 0) + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY, CMS_R_VERIFICATION_FAILURE); + err: + EVP_MD_CTX_cleanup(&mctx); + return r; +} + +/* Create a chain of digest BIOs from a CMS ContentInfo */ + +BIO *cms_SignedData_init_bio(CMS_ContentInfo *cms) +{ + int i; + CMS_SignedData *sd; + BIO *chain = NULL; + sd = cms_get0_signed(cms); + if (!sd) + return NULL; + if (cms->d.signedData->encapContentInfo->partial) + cms_sd_set_version(sd); + for (i = 0; i < sk_X509_ALGOR_num(sd->digestAlgorithms); i++) { + X509_ALGOR *digestAlgorithm; + BIO *mdbio; + digestAlgorithm = sk_X509_ALGOR_value(sd->digestAlgorithms, i); + mdbio = cms_DigestAlgorithm_init_bio(digestAlgorithm); + if (!mdbio) + goto err; + if (chain) + BIO_push(chain, mdbio); + else + chain = mdbio; + } + return chain; + err: + if (chain) + BIO_free_all(chain); + return NULL; +} + +int CMS_SignerInfo_verify_content(CMS_SignerInfo *si, BIO *chain) +{ + ASN1_OCTET_STRING *os = NULL; + EVP_MD_CTX mctx; + int r = -1; + EVP_MD_CTX_init(&mctx); + /* If we have any signed attributes look for messageDigest value */ + if (CMS_signed_get_attr_count(si) >= 0) { + os = CMS_signed_get0_data_by_OBJ(si, + OBJ_nid2obj(NID_pkcs9_messageDigest), + -3, V_ASN1_OCTET_STRING); + if (!os) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, + CMS_R_ERROR_READING_MESSAGEDIGEST_ATTRIBUTE); + goto err; + } + } + + if (!cms_DigestAlgorithm_find_ctx(&mctx, chain, si->digestAlgorithm)) + goto err; + + /* If messageDigest found compare it */ + + if (os) { + unsigned char mval[EVP_MAX_MD_SIZE]; + unsigned int mlen; + if (EVP_DigestFinal_ex(&mctx, mval, &mlen) <= 0) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, + CMS_R_UNABLE_TO_FINALIZE_CONTEXT); + goto err; + } + if (mlen != (unsigned int)os->length) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, + CMS_R_MESSAGEDIGEST_ATTRIBUTE_WRONG_LENGTH); + goto err; + } + + if (memcmp(mval, os->data, mlen)) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, + CMS_R_VERIFICATION_FAILURE); + r = 0; + } else + r = 1; + } else { + r = EVP_VerifyFinal(&mctx, si->signature->data, + si->signature->length, si->pkey); + if (r <= 0) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CONTENT, + CMS_R_VERIFICATION_FAILURE); + r = 0; + } + } + + err: + EVP_MD_CTX_cleanup(&mctx); + return r; + +} + +int CMS_add_smimecap(CMS_SignerInfo *si, STACK_OF(X509_ALGOR) *algs) +{ + unsigned char *smder = NULL; + int smderlen, r; + smderlen = i2d_X509_ALGORS(algs, &smder); + if (smderlen <= 0) + return 0; + r = CMS_signed_add1_attr_by_NID(si, NID_SMIMECapabilities, + V_ASN1_SEQUENCE, smder, smderlen); + OPENSSL_free(smder); + return r; +} + +int CMS_add_simple_smimecap(STACK_OF(X509_ALGOR) **algs, + int algnid, int keysize) +{ + X509_ALGOR *alg; + ASN1_INTEGER *key = NULL; + if (keysize > 0) { + key = ASN1_INTEGER_new(); + if (!key || !ASN1_INTEGER_set(key, keysize)) + return 0; + } + alg = X509_ALGOR_new(); + if (!alg) { + if (key) + ASN1_INTEGER_free(key); + return 0; + } + + X509_ALGOR_set0(alg, OBJ_nid2obj(algnid), + key ? V_ASN1_INTEGER : V_ASN1_UNDEF, key); + if (!*algs) + *algs = sk_X509_ALGOR_new_null(); + if (!*algs || !sk_X509_ALGOR_push(*algs, alg)) { + X509_ALGOR_free(alg); + return 0; + } + return 1; +} + +/* Check to see if a cipher exists and if so add S/MIME capabilities */ + +static int cms_add_cipher_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) +{ + if (EVP_get_cipherbynid(nid)) + return CMS_add_simple_smimecap(sk, nid, arg); + return 1; +} + +static int cms_add_digest_smcap(STACK_OF(X509_ALGOR) **sk, int nid, int arg) +{ + if (EVP_get_digestbynid(nid)) + return CMS_add_simple_smimecap(sk, nid, arg); + return 1; +} + +int CMS_add_standard_smimecap(STACK_OF(X509_ALGOR) **smcap) +{ + if (!cms_add_cipher_smcap(smcap, NID_aes_256_cbc, -1) + || !cms_add_digest_smcap(smcap, NID_id_GostR3411_94, -1) + || !cms_add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) + || !cms_add_cipher_smcap(smcap, NID_aes_192_cbc, -1) + || !cms_add_cipher_smcap(smcap, NID_aes_128_cbc, -1) + || !cms_add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) + || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 128) + || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 64) + || !cms_add_cipher_smcap(smcap, NID_des_cbc, -1) + || !cms_add_cipher_smcap(smcap, NID_rc2_cbc, 40)) + return 0; + return 1; +} diff --git a/libs/openssl/crypto/cms/cms_smime.c b/libs/openssl/crypto/cms/cms_smime.c new file mode 100644 index 00000000..f45693ac --- /dev/null +++ b/libs/openssl/crypto/cms/cms_smime.c @@ -0,0 +1,796 @@ +/* crypto/cms/cms_smime.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include "cms_lcl.h" + +static int cms_copy_content(BIO *out, BIO *in, unsigned int flags) +{ + unsigned char buf[4096]; + int r = 0, i; + BIO *tmpout = NULL; + + if (out == NULL) + tmpout = BIO_new(BIO_s_null()); + else if (flags & CMS_TEXT) { + tmpout = BIO_new(BIO_s_mem()); + BIO_set_mem_eof_return(tmpout, 0); + } else + tmpout = out; + + if (!tmpout) { + CMSerr(CMS_F_CMS_COPY_CONTENT, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Read all content through chain to process digest, decrypt etc */ + for (;;) { + i = BIO_read(in, buf, sizeof(buf)); + if (i <= 0) { + if (BIO_method_type(in) == BIO_TYPE_CIPHER) { + if (!BIO_get_cipher_status(in)) + goto err; + } + if (i < 0) + goto err; + break; + } + + if (tmpout && (BIO_write(tmpout, buf, i) != i)) + goto err; + } + + if (flags & CMS_TEXT) { + if (!SMIME_text(tmpout, out)) { + CMSerr(CMS_F_CMS_COPY_CONTENT, CMS_R_SMIME_TEXT_ERROR); + goto err; + } + } + + r = 1; + + err: + if (tmpout && (tmpout != out)) + BIO_free(tmpout); + return r; + +} + +static int check_content(CMS_ContentInfo *cms) +{ + ASN1_OCTET_STRING **pos = CMS_get0_content(cms); + if (!pos || !*pos) { + CMSerr(CMS_F_CHECK_CONTENT, CMS_R_NO_CONTENT); + return 0; + } + return 1; +} + +static void do_free_upto(BIO *f, BIO *upto) +{ + if (upto) { + BIO *tbio; + do { + tbio = BIO_pop(f); + BIO_free(f); + f = tbio; + } + while (f && f != upto); + } else + BIO_free_all(f); +} + +int CMS_data(CMS_ContentInfo *cms, BIO *out, unsigned int flags) +{ + BIO *cont; + int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_data) { + CMSerr(CMS_F_CMS_DATA, CMS_R_TYPE_NOT_DATA); + return 0; + } + cont = CMS_dataInit(cms, NULL); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + BIO_free_all(cont); + return r; +} + +CMS_ContentInfo *CMS_data_create(BIO *in, unsigned int flags) +{ + CMS_ContentInfo *cms; + cms = cms_Data_create(); + if (!cms) + return NULL; + + if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) + return cms; + + CMS_ContentInfo_free(cms); + + return NULL; +} + +int CMS_digest_verify(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags) +{ + BIO *cont; + int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_digest) { + CMSerr(CMS_F_CMS_DIGEST_VERIFY, CMS_R_TYPE_NOT_DIGESTED_DATA); + return 0; + } + + if (!dcont && !check_content(cms)) + return 0; + + cont = CMS_dataInit(cms, dcont); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + if (r) + r = cms_DigestedData_do_final(cms, cont, 1); + do_free_upto(cont, dcont); + return r; +} + +CMS_ContentInfo *CMS_digest_create(BIO *in, const EVP_MD *md, + unsigned int flags) +{ + CMS_ContentInfo *cms; + if (!md) + md = EVP_sha1(); + cms = cms_DigestedData_create(md); + if (!cms) + return NULL; + + if (!(flags & CMS_DETACHED)) + CMS_set_detached(cms, 0); + + if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) + return cms; + + CMS_ContentInfo_free(cms); + return NULL; +} + +int CMS_EncryptedData_decrypt(CMS_ContentInfo *cms, + const unsigned char *key, size_t keylen, + BIO *dcont, BIO *out, unsigned int flags) +{ + BIO *cont; + int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_encrypted) { + CMSerr(CMS_F_CMS_ENCRYPTEDDATA_DECRYPT, + CMS_R_TYPE_NOT_ENCRYPTED_DATA); + return 0; + } + + if (!dcont && !check_content(cms)) + return 0; + + if (CMS_EncryptedData_set1_key(cms, NULL, key, keylen) <= 0) + return 0; + cont = CMS_dataInit(cms, dcont); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + do_free_upto(cont, dcont); + return r; +} + +CMS_ContentInfo *CMS_EncryptedData_encrypt(BIO *in, const EVP_CIPHER *cipher, + const unsigned char *key, + size_t keylen, unsigned int flags) +{ + CMS_ContentInfo *cms; + if (!cipher) { + CMSerr(CMS_F_CMS_ENCRYPTEDDATA_ENCRYPT, CMS_R_NO_CIPHER); + return NULL; + } + cms = CMS_ContentInfo_new(); + if (!cms) + return NULL; + if (!CMS_EncryptedData_set1_key(cms, cipher, key, keylen)) + return NULL; + + if (!(flags & CMS_DETACHED)) + CMS_set_detached(cms, 0); + + if ((flags & (CMS_STREAM | CMS_PARTIAL)) + || CMS_final(cms, in, NULL, flags)) + return cms; + + CMS_ContentInfo_free(cms); + return NULL; +} + +static int cms_signerinfo_verify_cert(CMS_SignerInfo *si, + X509_STORE *store, + STACK_OF(X509) *certs, + STACK_OF(X509_CRL) *crls, + unsigned int flags) +{ + X509_STORE_CTX ctx; + X509 *signer; + int i, j, r = 0; + CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); + if (!X509_STORE_CTX_init(&ctx, store, signer, certs)) { + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, CMS_R_STORE_INIT_ERROR); + goto err; + } + X509_STORE_CTX_set_default(&ctx, "smime_sign"); + if (crls) + X509_STORE_CTX_set0_crls(&ctx, crls); + + i = X509_verify_cert(&ctx); + if (i <= 0) { + j = X509_STORE_CTX_get_error(&ctx); + CMSerr(CMS_F_CMS_SIGNERINFO_VERIFY_CERT, + CMS_R_CERTIFICATE_VERIFY_ERROR); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(j)); + goto err; + } + r = 1; + err: + X509_STORE_CTX_cleanup(&ctx); + return r; + +} + +int CMS_verify(CMS_ContentInfo *cms, STACK_OF(X509) *certs, + X509_STORE *store, BIO *dcont, BIO *out, unsigned int flags) +{ + CMS_SignerInfo *si; + STACK_OF(CMS_SignerInfo) *sinfos; + STACK_OF(X509) *cms_certs = NULL; + STACK_OF(X509_CRL) *crls = NULL; + X509 *signer; + int i, scount = 0, ret = 0; + BIO *cmsbio = NULL, *tmpin = NULL; + + if (!dcont && !check_content(cms)) + return 0; + + /* Attempt to find all signer certificates */ + + sinfos = CMS_get0_SignerInfos(cms); + + if (sk_CMS_SignerInfo_num(sinfos) <= 0) { + CMSerr(CMS_F_CMS_VERIFY, CMS_R_NO_SIGNERS); + goto err; + } + + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + CMS_SignerInfo_get0_algs(si, NULL, &signer, NULL, NULL); + if (signer) + scount++; + } + + if (scount != sk_CMS_SignerInfo_num(sinfos)) + scount += CMS_set1_signers_certs(cms, certs, flags); + + if (scount != sk_CMS_SignerInfo_num(sinfos)) { + CMSerr(CMS_F_CMS_VERIFY, CMS_R_SIGNER_CERTIFICATE_NOT_FOUND); + goto err; + } + + /* Attempt to verify all signers certs */ + + if (!(flags & CMS_NO_SIGNER_CERT_VERIFY)) { + cms_certs = CMS_get1_certs(cms); + if (!(flags & CMS_NOCRL)) + crls = CMS_get1_crls(cms); + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (!cms_signerinfo_verify_cert(si, store, + cms_certs, crls, flags)) + goto err; + } + } + + /* Attempt to verify all SignerInfo signed attribute signatures */ + + if (!(flags & CMS_NO_ATTR_VERIFY)) { + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (CMS_signed_get_attr_count(si) < 0) + continue; + if (CMS_SignerInfo_verify(si) <= 0) + goto err; + } + } + + /* + * Performance optimization: if the content is a memory BIO then store + * its contents in a temporary read only memory BIO. This avoids + * potentially large numbers of slow copies of data which will occur when + * reading from a read write memory BIO when signatures are calculated. + */ + + if (dcont && (BIO_method_type(dcont) == BIO_TYPE_MEM)) { + char *ptr; + long len; + len = BIO_get_mem_data(dcont, &ptr); + tmpin = BIO_new_mem_buf(ptr, len); + if (tmpin == NULL) { + CMSerr(CMS_F_CMS_VERIFY, ERR_R_MALLOC_FAILURE); + return 0; + } + } else + tmpin = dcont; + + cmsbio = CMS_dataInit(cms, tmpin); + if (!cmsbio) + goto err; + + if (!cms_copy_content(out, cmsbio, flags)) + goto err; + + if (!(flags & CMS_NO_CONTENT_VERIFY)) { + for (i = 0; i < sk_CMS_SignerInfo_num(sinfos); i++) { + si = sk_CMS_SignerInfo_value(sinfos, i); + if (CMS_SignerInfo_verify_content(si, cmsbio) <= 0) { + CMSerr(CMS_F_CMS_VERIFY, CMS_R_CONTENT_VERIFY_ERROR); + goto err; + } + } + } + + ret = 1; + + err: + + if (dcont && (tmpin == dcont)) + do_free_upto(cmsbio, dcont); + else + BIO_free_all(cmsbio); + + if (cms_certs) + sk_X509_pop_free(cms_certs, X509_free); + if (crls) + sk_X509_CRL_pop_free(crls, X509_CRL_free); + + return ret; +} + +int CMS_verify_receipt(CMS_ContentInfo *rcms, CMS_ContentInfo *ocms, + STACK_OF(X509) *certs, + X509_STORE *store, unsigned int flags) +{ + int r; + flags &= ~(CMS_DETACHED | CMS_TEXT); + r = CMS_verify(rcms, certs, store, NULL, NULL, flags); + if (r <= 0) + return r; + return cms_Receipt_verify(rcms, ocms); +} + +CMS_ContentInfo *CMS_sign(X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, BIO *data, + unsigned int flags) +{ + CMS_ContentInfo *cms; + int i; + + cms = CMS_ContentInfo_new(); + if (!cms || !CMS_SignedData_init(cms)) + goto merr; + + if (pkey && !CMS_add1_signer(cms, signcert, pkey, NULL, flags)) { + CMSerr(CMS_F_CMS_SIGN, CMS_R_ADD_SIGNER_ERROR); + goto err; + } + + for (i = 0; i < sk_X509_num(certs); i++) { + X509 *x = sk_X509_value(certs, i); + if (!CMS_add1_cert(cms, x)) + goto merr; + } + + if (!(flags & CMS_DETACHED)) + CMS_set_detached(cms, 0); + + if ((flags & (CMS_STREAM | CMS_PARTIAL)) + || CMS_final(cms, data, NULL, flags)) + return cms; + else + goto err; + + merr: + CMSerr(CMS_F_CMS_SIGN, ERR_R_MALLOC_FAILURE); + + err: + if (cms) + CMS_ContentInfo_free(cms); + return NULL; +} + +CMS_ContentInfo *CMS_sign_receipt(CMS_SignerInfo *si, + X509 *signcert, EVP_PKEY *pkey, + STACK_OF(X509) *certs, unsigned int flags) +{ + CMS_SignerInfo *rct_si; + CMS_ContentInfo *cms = NULL; + ASN1_OCTET_STRING **pos, *os; + BIO *rct_cont = NULL; + int r = 0; + + flags &= ~(CMS_STREAM | CMS_TEXT); + /* Not really detached but avoids content being allocated */ + flags |= CMS_PARTIAL | CMS_BINARY | CMS_DETACHED; + if (!pkey || !signcert) { + CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_NO_KEY_OR_CERT); + return NULL; + } + + /* Initialize signed data */ + + cms = CMS_sign(NULL, NULL, certs, NULL, flags); + if (!cms) + goto err; + + /* Set inner content type to signed receipt */ + if (!CMS_set1_eContentType(cms, OBJ_nid2obj(NID_id_smime_ct_receipt))) + goto err; + + rct_si = CMS_add1_signer(cms, signcert, pkey, NULL, flags); + if (!rct_si) { + CMSerr(CMS_F_CMS_SIGN_RECEIPT, CMS_R_ADD_SIGNER_ERROR); + goto err; + } + + os = cms_encode_Receipt(si); + + if (!os) + goto err; + + /* Set content to digest */ + rct_cont = BIO_new_mem_buf(os->data, os->length); + if (!rct_cont) + goto err; + + /* Add msgSigDigest attribute */ + + if (!cms_msgSigDigest_add1(rct_si, si)) + goto err; + + /* Finalize structure */ + if (!CMS_final(cms, rct_cont, NULL, flags)) + goto err; + + /* Set embedded content */ + pos = CMS_get0_content(cms); + *pos = os; + + r = 1; + + err: + if (rct_cont) + BIO_free(rct_cont); + if (r) + return cms; + CMS_ContentInfo_free(cms); + return NULL; + +} + +CMS_ContentInfo *CMS_encrypt(STACK_OF(X509) *certs, BIO *data, + const EVP_CIPHER *cipher, unsigned int flags) +{ + CMS_ContentInfo *cms; + int i; + X509 *recip; + cms = CMS_EnvelopedData_create(cipher); + if (!cms) + goto merr; + for (i = 0; i < sk_X509_num(certs); i++) { + recip = sk_X509_value(certs, i); + if (!CMS_add1_recipient_cert(cms, recip, flags)) { + CMSerr(CMS_F_CMS_ENCRYPT, CMS_R_RECIPIENT_ERROR); + goto err; + } + } + + if (!(flags & CMS_DETACHED)) + CMS_set_detached(cms, 0); + + if ((flags & (CMS_STREAM | CMS_PARTIAL)) + || CMS_final(cms, data, NULL, flags)) + return cms; + else + goto err; + + merr: + CMSerr(CMS_F_CMS_ENCRYPT, ERR_R_MALLOC_FAILURE); + err: + if (cms) + CMS_ContentInfo_free(cms); + return NULL; +} + +int CMS_decrypt_set1_pkey(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert) +{ + STACK_OF(CMS_RecipientInfo) *ris; + CMS_RecipientInfo *ri; + int i, r; + int debug = 0, ri_match = 0; + ris = CMS_get0_RecipientInfos(cms); + if (ris) + debug = cms->d.envelopedData->encryptedContentInfo->debug; + for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { + ri = sk_CMS_RecipientInfo_value(ris, i); + if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_TRANS) + continue; + ri_match = 1; + /* + * If we have a cert try matching RecipientInfo otherwise try them + * all. + */ + if (!cert || (CMS_RecipientInfo_ktri_cert_cmp(ri, cert) == 0)) { + CMS_RecipientInfo_set0_pkey(ri, pk); + r = CMS_RecipientInfo_decrypt(cms, ri); + CMS_RecipientInfo_set0_pkey(ri, NULL); + if (cert) { + /* + * If not debugging clear any error and return success to + * avoid leaking of information useful to MMA + */ + if (!debug) { + ERR_clear_error(); + return 1; + } + if (r > 0) + return 1; + CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_DECRYPT_ERROR); + return 0; + } + /* + * If no cert and not debugging don't leave loop after first + * successful decrypt. Always attempt to decrypt all recipients + * to avoid leaking timing of a successful decrypt. + */ + else if (r > 0 && debug) + return 1; + } + } + /* If no cert and not debugging always return success */ + if (ri_match && !cert && !debug) { + ERR_clear_error(); + return 1; + } + + CMSerr(CMS_F_CMS_DECRYPT_SET1_PKEY, CMS_R_NO_MATCHING_RECIPIENT); + return 0; + +} + +int CMS_decrypt_set1_key(CMS_ContentInfo *cms, + unsigned char *key, size_t keylen, + unsigned char *id, size_t idlen) +{ + STACK_OF(CMS_RecipientInfo) *ris; + CMS_RecipientInfo *ri; + int i, r; + ris = CMS_get0_RecipientInfos(cms); + for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { + ri = sk_CMS_RecipientInfo_value(ris, i); + if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_KEK) + continue; + + /* + * If we have an id try matching RecipientInfo otherwise try them + * all. + */ + if (!id || (CMS_RecipientInfo_kekri_id_cmp(ri, id, idlen) == 0)) { + CMS_RecipientInfo_set0_key(ri, key, keylen); + r = CMS_RecipientInfo_decrypt(cms, ri); + CMS_RecipientInfo_set0_key(ri, NULL, 0); + if (r > 0) + return 1; + if (id) { + CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_DECRYPT_ERROR); + return 0; + } + ERR_clear_error(); + } + } + + CMSerr(CMS_F_CMS_DECRYPT_SET1_KEY, CMS_R_NO_MATCHING_RECIPIENT); + return 0; + +} + +int CMS_decrypt_set1_password(CMS_ContentInfo *cms, + unsigned char *pass, ossl_ssize_t passlen) +{ + STACK_OF(CMS_RecipientInfo) *ris; + CMS_RecipientInfo *ri; + int i, r; + ris = CMS_get0_RecipientInfos(cms); + for (i = 0; i < sk_CMS_RecipientInfo_num(ris); i++) { + ri = sk_CMS_RecipientInfo_value(ris, i); + if (CMS_RecipientInfo_type(ri) != CMS_RECIPINFO_PASS) + continue; + CMS_RecipientInfo_set0_password(ri, pass, passlen); + r = CMS_RecipientInfo_decrypt(cms, ri); + CMS_RecipientInfo_set0_password(ri, NULL, 0); + if (r > 0) + return 1; + } + + CMSerr(CMS_F_CMS_DECRYPT_SET1_PASSWORD, CMS_R_NO_MATCHING_RECIPIENT); + return 0; + +} + +int CMS_decrypt(CMS_ContentInfo *cms, EVP_PKEY *pk, X509 *cert, + BIO *dcont, BIO *out, unsigned int flags) +{ + int r; + BIO *cont; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_pkcs7_enveloped) { + CMSerr(CMS_F_CMS_DECRYPT, CMS_R_TYPE_NOT_ENVELOPED_DATA); + return 0; + } + if (!dcont && !check_content(cms)) + return 0; + if (flags & CMS_DEBUG_DECRYPT) + cms->d.envelopedData->encryptedContentInfo->debug = 1; + else + cms->d.envelopedData->encryptedContentInfo->debug = 0; + if (!pk && !cert && !dcont && !out) + return 1; + if (pk && !CMS_decrypt_set1_pkey(cms, pk, cert)) + return 0; + cont = CMS_dataInit(cms, dcont); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + do_free_upto(cont, dcont); + return r; +} + +int CMS_final(CMS_ContentInfo *cms, BIO *data, BIO *dcont, unsigned int flags) +{ + BIO *cmsbio; + int ret = 0; + if (!(cmsbio = CMS_dataInit(cms, dcont))) { + CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_LIB); + return 0; + } + + SMIME_crlf_copy(data, cmsbio, flags); + + (void)BIO_flush(cmsbio); + + if (!CMS_dataFinal(cms, cmsbio)) { + CMSerr(CMS_F_CMS_FINAL, CMS_R_CMS_DATAFINAL_ERROR); + goto err; + } + + ret = 1; + + err: + do_free_upto(cmsbio, dcont); + + return ret; + +} + +#ifdef ZLIB + +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags) +{ + BIO *cont; + int r; + if (OBJ_obj2nid(CMS_get0_type(cms)) != NID_id_smime_ct_compressedData) { + CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_TYPE_NOT_COMPRESSED_DATA); + return 0; + } + + if (!dcont && !check_content(cms)) + return 0; + + cont = CMS_dataInit(cms, dcont); + if (!cont) + return 0; + r = cms_copy_content(out, cont, flags); + do_free_upto(cont, dcont); + return r; +} + +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) +{ + CMS_ContentInfo *cms; + if (comp_nid <= 0) + comp_nid = NID_zlib_compression; + cms = cms_CompressedData_create(comp_nid); + if (!cms) + return NULL; + + if (!(flags & CMS_DETACHED)) + CMS_set_detached(cms, 0); + + if ((flags & CMS_STREAM) || CMS_final(cms, in, NULL, flags)) + return cms; + + CMS_ContentInfo_free(cms); + return NULL; +} + +#else + +int CMS_uncompress(CMS_ContentInfo *cms, BIO *dcont, BIO *out, + unsigned int flags) +{ + CMSerr(CMS_F_CMS_UNCOMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + return 0; +} + +CMS_ContentInfo *CMS_compress(BIO *in, int comp_nid, unsigned int flags) +{ + CMSerr(CMS_F_CMS_COMPRESS, CMS_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + return NULL; +} + +#endif diff --git a/libs/openssl/crypto/comp/c_rle.c b/libs/openssl/crypto/comp/c_rle.c new file mode 100644 index 00000000..e9aabbd1 --- /dev/null +++ b/libs/openssl/crypto/comp/c_rle.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include + +static int rle_compress_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen); +static int rle_expand_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen); + +static COMP_METHOD rle_method = { + NID_rle_compression, + LN_rle_compression, + NULL, + NULL, + rle_compress_block, + rle_expand_block, + NULL, + NULL, +}; + +COMP_METHOD *COMP_rle(void) +{ + return (&rle_method); +} + +static int rle_compress_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen) +{ + /* int i; */ + + if (ilen == 0 || olen < (ilen - 1)) { + /* ZZZZZZZZZZZZZZZZZZZZZZ */ + return (-1); + } + + *(out++) = 0; + memcpy(out, in, ilen); + return (ilen + 1); +} + +static int rle_expand_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen) +{ + int i; + + if (olen < (ilen - 1)) { + /* ZZZZZZZZZZZZZZZZZZZZZZ */ + return (-1); + } + + i = *(in++); + if (i == 0) { + memcpy(out, in, ilen - 1); + } + return (ilen - 1); +} diff --git a/libs/openssl/crypto/comp/c_zlib.c b/libs/openssl/crypto/comp/c_zlib.c new file mode 100644 index 00000000..9c32614d --- /dev/null +++ b/libs/openssl/crypto/comp/c_zlib.c @@ -0,0 +1,763 @@ +#include +#include +#include +#include +#include +#include + +COMP_METHOD *COMP_zlib(void); + +static COMP_METHOD zlib_method_nozlib = { + NID_undef, + "(undef)", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, +}; + +#ifndef ZLIB +# undef ZLIB_SHARED +#else + +# include + +static int zlib_stateful_init(COMP_CTX *ctx); +static void zlib_stateful_finish(COMP_CTX *ctx); +static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen); +static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen); + +/* memory allocations functions for zlib intialization */ +static void *zlib_zalloc(void *opaque, unsigned int no, unsigned int size) +{ + void *p; + + p = OPENSSL_malloc(no * size); + if (p) + memset(p, 0, no * size); + return p; +} + +static void zlib_zfree(void *opaque, void *address) +{ + OPENSSL_free(address); +} + +# if 0 +static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen); +static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen); + +static int zz_uncompress(Bytef *dest, uLongf * destLen, const Bytef *source, + uLong sourceLen); + +static COMP_METHOD zlib_stateless_method = { + NID_zlib_compression, + LN_zlib_compression, + NULL, + NULL, + zlib_compress_block, + zlib_expand_block, + NULL, + NULL, +}; +# endif + +static COMP_METHOD zlib_stateful_method = { + NID_zlib_compression, + LN_zlib_compression, + zlib_stateful_init, + zlib_stateful_finish, + zlib_stateful_compress_block, + zlib_stateful_expand_block, + NULL, + NULL, +}; + +/* + * When OpenSSL is built on Windows, we do not want to require that + * the ZLIB.DLL be available in order for the OpenSSL DLLs to + * work. Therefore, all ZLIB routines are loaded at run time + * and we do not link to a .LIB file when ZLIB_SHARED is set. + */ +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +# include +# endif /* !(OPENSSL_SYS_WINDOWS || + * OPENSSL_SYS_WIN32) */ + +# ifdef ZLIB_SHARED +# include + +/* Function pointers */ +typedef int (*compress_ft) (Bytef *dest, uLongf * destLen, + const Bytef *source, uLong sourceLen); +typedef int (*inflateEnd_ft) (z_streamp strm); +typedef int (*inflate_ft) (z_streamp strm, int flush); +typedef int (*inflateInit__ft) (z_streamp strm, + const char *version, int stream_size); +typedef int (*deflateEnd_ft) (z_streamp strm); +typedef int (*deflate_ft) (z_streamp strm, int flush); +typedef int (*deflateInit__ft) (z_streamp strm, int level, + const char *version, int stream_size); +typedef const char *(*zError__ft) (int err); +static compress_ft p_compress = NULL; +static inflateEnd_ft p_inflateEnd = NULL; +static inflate_ft p_inflate = NULL; +static inflateInit__ft p_inflateInit_ = NULL; +static deflateEnd_ft p_deflateEnd = NULL; +static deflate_ft p_deflate = NULL; +static deflateInit__ft p_deflateInit_ = NULL; +static zError__ft p_zError = NULL; + +static int zlib_loaded = 0; /* only attempt to init func pts once */ +static DSO *zlib_dso = NULL; + +# define compress p_compress +# define inflateEnd p_inflateEnd +# define inflate p_inflate +# define inflateInit_ p_inflateInit_ +# define deflateEnd p_deflateEnd +# define deflate p_deflate +# define deflateInit_ p_deflateInit_ +# define zError p_zError +# endif /* ZLIB_SHARED */ + +struct zlib_state { + z_stream istream; + z_stream ostream; +}; + +static int zlib_stateful_ex_idx = -1; + +static int zlib_stateful_init(COMP_CTX *ctx) +{ + int err; + struct zlib_state *state = + (struct zlib_state *)OPENSSL_malloc(sizeof(struct zlib_state)); + + if (state == NULL) + goto err; + + state->istream.zalloc = zlib_zalloc; + state->istream.zfree = zlib_zfree; + state->istream.opaque = Z_NULL; + state->istream.next_in = Z_NULL; + state->istream.next_out = Z_NULL; + state->istream.avail_in = 0; + state->istream.avail_out = 0; + err = inflateInit_(&state->istream, ZLIB_VERSION, sizeof(z_stream)); + if (err != Z_OK) + goto err; + + state->ostream.zalloc = zlib_zalloc; + state->ostream.zfree = zlib_zfree; + state->ostream.opaque = Z_NULL; + state->ostream.next_in = Z_NULL; + state->ostream.next_out = Z_NULL; + state->ostream.avail_in = 0; + state->ostream.avail_out = 0; + err = deflateInit_(&state->ostream, Z_DEFAULT_COMPRESSION, + ZLIB_VERSION, sizeof(z_stream)); + if (err != Z_OK) + goto err; + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data); + CRYPTO_set_ex_data(&ctx->ex_data, zlib_stateful_ex_idx, state); + return 1; + err: + if (state) + OPENSSL_free(state); + return 0; +} + +static void zlib_stateful_finish(COMP_CTX *ctx) +{ + struct zlib_state *state = + (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, + zlib_stateful_ex_idx); + inflateEnd(&state->istream); + deflateEnd(&state->ostream); + OPENSSL_free(state); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data); +} + +static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen) +{ + int err = Z_OK; + struct zlib_state *state = + (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, + zlib_stateful_ex_idx); + + if (state == NULL) + return -1; + + state->ostream.next_in = in; + state->ostream.avail_in = ilen; + state->ostream.next_out = out; + state->ostream.avail_out = olen; + if (ilen > 0) + err = deflate(&state->ostream, Z_SYNC_FLUSH); + if (err != Z_OK) + return -1; +# ifdef DEBUG_ZLIB + fprintf(stderr, "compress(%4d)->%4d %s\n", + ilen, olen - state->ostream.avail_out, + (ilen != olen - state->ostream.avail_out) ? "zlib" : "clear"); +# endif + return olen - state->ostream.avail_out; +} + +static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen) +{ + int err = Z_OK; + + struct zlib_state *state = + (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data, + zlib_stateful_ex_idx); + + if (state == NULL) + return 0; + + state->istream.next_in = in; + state->istream.avail_in = ilen; + state->istream.next_out = out; + state->istream.avail_out = olen; + if (ilen > 0) + err = inflate(&state->istream, Z_SYNC_FLUSH); + if (err != Z_OK) + return -1; +# ifdef DEBUG_ZLIB + fprintf(stderr, "expand(%4d)->%4d %s\n", + ilen, olen - state->istream.avail_out, + (ilen != olen - state->istream.avail_out) ? "zlib" : "clear"); +# endif + return olen - state->istream.avail_out; +} + +# if 0 +static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen) +{ + unsigned long l; + int i; + int clear = 1; + + if (ilen > 128) { + out[0] = 1; + l = olen - 1; + i = compress(&(out[1]), &l, in, (unsigned long)ilen); + if (i != Z_OK) + return (-1); + if (ilen > l) { + clear = 0; + l++; + } + } + if (clear) { + out[0] = 0; + memcpy(&(out[1]), in, ilen); + l = ilen + 1; + } +# ifdef DEBUG_ZLIB + fprintf(stderr, "compress(%4d)->%4d %s\n", + ilen, (int)l, (clear) ? "clear" : "zlib"); +# endif + return ((int)l); +} + +static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out, + unsigned int olen, unsigned char *in, + unsigned int ilen) +{ + unsigned long l; + int i; + + if (in[0]) { + l = olen; + i = zz_uncompress(out, &l, &(in[1]), (unsigned long)ilen - 1); + if (i != Z_OK) + return (-1); + } else { + memcpy(out, &(in[1]), ilen - 1); + l = ilen - 1; + } +# ifdef DEBUG_ZLIB + fprintf(stderr, "expand (%4d)->%4d %s\n", + ilen, (int)l, in[0] ? "zlib" : "clear"); +# endif + return ((int)l); +} + +static int zz_uncompress(Bytef *dest, uLongf * destLen, const Bytef *source, + uLong sourceLen) +{ + z_stream stream; + int err; + + stream.next_in = (Bytef *)source; + stream.avail_in = (uInt) sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong) stream.avail_in != sourceLen) + return Z_BUF_ERROR; + + stream.next_out = dest; + stream.avail_out = (uInt) * destLen; + if ((uLong) stream.avail_out != *destLen) + return Z_BUF_ERROR; + + stream.zalloc = (alloc_func) 0; + stream.zfree = (free_func) 0; + + err = inflateInit_(&stream, ZLIB_VERSION, sizeof(z_stream)); + if (err != Z_OK) + return err; + + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + inflateEnd(&stream); + return err; + } + *destLen = stream.total_out; + + err = inflateEnd(&stream); + return err; +} +# endif + +#endif + +COMP_METHOD *COMP_zlib(void) +{ + COMP_METHOD *meth = &zlib_method_nozlib; + +#ifdef ZLIB_SHARED + if (!zlib_loaded) { +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) + zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0); +# else + zlib_dso = DSO_load(NULL, "z", NULL, 0); +# endif + if (zlib_dso != NULL) { + p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress"); + p_inflateEnd + = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd"); + p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate"); + p_inflateInit_ + = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_"); + p_deflateEnd + = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd"); + p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate"); + p_deflateInit_ + = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_"); + p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError"); + + if (p_compress && p_inflateEnd && p_inflate + && p_inflateInit_ && p_deflateEnd + && p_deflate && p_deflateInit_ && p_zError) + zlib_loaded++; + } + } +#endif +#ifdef ZLIB_SHARED + if (zlib_loaded) +#endif +#if defined(ZLIB) || defined(ZLIB_SHARED) + { + /* + * init zlib_stateful_ex_idx here so that in a multi-process + * application it's enough to intialize openssl before forking (idx + * will be inherited in all the children) + */ + if (zlib_stateful_ex_idx == -1) { + CRYPTO_w_lock(CRYPTO_LOCK_COMP); + if (zlib_stateful_ex_idx == -1) + zlib_stateful_ex_idx = + CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP, + 0, NULL, NULL, NULL, NULL); + CRYPTO_w_unlock(CRYPTO_LOCK_COMP); + if (zlib_stateful_ex_idx == -1) + goto err; + } + + meth = &zlib_stateful_method; + } + err: +#endif + + return (meth); +} + +void COMP_zlib_cleanup(void) +{ +#ifdef ZLIB_SHARED + if (zlib_dso != NULL) + DSO_free(zlib_dso); + zlib_dso = NULL; +#endif +} + +#ifdef ZLIB + +/* Zlib based compression/decompression filter BIO */ + +typedef struct { + unsigned char *ibuf; /* Input buffer */ + int ibufsize; /* Buffer size */ + z_stream zin; /* Input decompress context */ + unsigned char *obuf; /* Output buffer */ + int obufsize; /* Output buffer size */ + unsigned char *optr; /* Position in output buffer */ + int ocount; /* Amount of data in output buffer */ + int odone; /* deflate EOF */ + int comp_level; /* Compression level to use */ + z_stream zout; /* Output compression context */ +} BIO_ZLIB_CTX; + +# define ZLIB_DEFAULT_BUFSIZE 1024 + +static int bio_zlib_new(BIO *bi); +static int bio_zlib_free(BIO *bi); +static int bio_zlib_read(BIO *b, char *out, int outl); +static int bio_zlib_write(BIO *b, const char *in, int inl); +static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr); +static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp); + +static BIO_METHOD bio_meth_zlib = { + BIO_TYPE_COMP, + "zlib", + bio_zlib_write, + bio_zlib_read, + NULL, + NULL, + bio_zlib_ctrl, + bio_zlib_new, + bio_zlib_free, + bio_zlib_callback_ctrl +}; + +BIO_METHOD *BIO_f_zlib(void) +{ + return &bio_meth_zlib; +} + +static int bio_zlib_new(BIO *bi) +{ + BIO_ZLIB_CTX *ctx; +# ifdef ZLIB_SHARED + (void)COMP_zlib(); + if (!zlib_loaded) { + COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED); + return 0; + } +# endif + ctx = OPENSSL_malloc(sizeof(BIO_ZLIB_CTX)); + if (!ctx) { + COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE); + return 0; + } + ctx->ibuf = NULL; + ctx->obuf = NULL; + ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE; + ctx->obufsize = ZLIB_DEFAULT_BUFSIZE; + ctx->zin.zalloc = Z_NULL; + ctx->zin.zfree = Z_NULL; + ctx->zin.next_in = NULL; + ctx->zin.avail_in = 0; + ctx->zin.next_out = NULL; + ctx->zin.avail_out = 0; + ctx->zout.zalloc = Z_NULL; + ctx->zout.zfree = Z_NULL; + ctx->zout.next_in = NULL; + ctx->zout.avail_in = 0; + ctx->zout.next_out = NULL; + ctx->zout.avail_out = 0; + ctx->odone = 0; + ctx->comp_level = Z_DEFAULT_COMPRESSION; + bi->init = 1; + bi->ptr = (char *)ctx; + bi->flags = 0; + return 1; +} + +static int bio_zlib_free(BIO *bi) +{ + BIO_ZLIB_CTX *ctx; + if (!bi) + return 0; + ctx = (BIO_ZLIB_CTX *) bi->ptr; + if (ctx->ibuf) { + /* Destroy decompress context */ + inflateEnd(&ctx->zin); + OPENSSL_free(ctx->ibuf); + } + if (ctx->obuf) { + /* Destroy compress context */ + deflateEnd(&ctx->zout); + OPENSSL_free(ctx->obuf); + } + OPENSSL_free(ctx); + bi->ptr = NULL; + bi->init = 0; + bi->flags = 0; + return 1; +} + +static int bio_zlib_read(BIO *b, char *out, int outl) +{ + BIO_ZLIB_CTX *ctx; + int ret; + z_stream *zin; + if (!out || !outl) + return 0; + ctx = (BIO_ZLIB_CTX *) b->ptr; + zin = &ctx->zin; + BIO_clear_retry_flags(b); + if (!ctx->ibuf) { + ctx->ibuf = OPENSSL_malloc(ctx->ibufsize); + if (!ctx->ibuf) { + COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE); + return 0; + } + inflateInit(zin); + zin->next_in = ctx->ibuf; + zin->avail_in = 0; + } + + /* Copy output data directly to supplied buffer */ + zin->next_out = (unsigned char *)out; + zin->avail_out = (unsigned int)outl; + for (;;) { + /* Decompress while data available */ + while (zin->avail_in) { + ret = inflate(zin, 0); + if ((ret != Z_OK) && (ret != Z_STREAM_END)) { + COMPerr(COMP_F_BIO_ZLIB_READ, COMP_R_ZLIB_INFLATE_ERROR); + ERR_add_error_data(2, "zlib error:", zError(ret)); + return 0; + } + /* If EOF or we've read everything then return */ + if ((ret == Z_STREAM_END) || !zin->avail_out) + return outl - zin->avail_out; + } + + /* + * No data in input buffer try to read some in, if an error then + * return the total data read. + */ + ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize); + if (ret <= 0) { + /* Total data read */ + int tot = outl - zin->avail_out; + BIO_copy_next_retry(b); + if (ret < 0) + return (tot > 0) ? tot : ret; + return tot; + } + zin->avail_in = ret; + zin->next_in = ctx->ibuf; + } +} + +static int bio_zlib_write(BIO *b, const char *in, int inl) +{ + BIO_ZLIB_CTX *ctx; + int ret; + z_stream *zout; + if (!in || !inl) + return 0; + ctx = (BIO_ZLIB_CTX *) b->ptr; + if (ctx->odone) + return 0; + zout = &ctx->zout; + BIO_clear_retry_flags(b); + if (!ctx->obuf) { + ctx->obuf = OPENSSL_malloc(ctx->obufsize); + /* Need error here */ + if (!ctx->obuf) { + COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE); + return 0; + } + ctx->optr = ctx->obuf; + ctx->ocount = 0; + deflateInit(zout, ctx->comp_level); + zout->next_out = ctx->obuf; + zout->avail_out = ctx->obufsize; + } + /* Obtain input data directly from supplied buffer */ + zout->next_in = (void *)in; + zout->avail_in = inl; + for (;;) { + /* If data in output buffer write it first */ + while (ctx->ocount) { + ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount); + if (ret <= 0) { + /* Total data written */ + int tot = inl - zout->avail_in; + BIO_copy_next_retry(b); + if (ret < 0) + return (tot > 0) ? tot : ret; + return tot; + } + ctx->optr += ret; + ctx->ocount -= ret; + } + + /* Have we consumed all supplied data? */ + if (!zout->avail_in) + return inl; + + /* Compress some more */ + + /* Reset buffer */ + ctx->optr = ctx->obuf; + zout->next_out = ctx->obuf; + zout->avail_out = ctx->obufsize; + /* Compress some more */ + ret = deflate(zout, 0); + if (ret != Z_OK) { + COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR); + ERR_add_error_data(2, "zlib error:", zError(ret)); + return 0; + } + ctx->ocount = ctx->obufsize - zout->avail_out; + } +} + +static int bio_zlib_flush(BIO *b) +{ + BIO_ZLIB_CTX *ctx; + int ret; + z_stream *zout; + ctx = (BIO_ZLIB_CTX *) b->ptr; + /* If no data written or already flush show success */ + if (!ctx->obuf || (ctx->odone && !ctx->ocount)) + return 1; + zout = &ctx->zout; + BIO_clear_retry_flags(b); + /* No more input data */ + zout->next_in = NULL; + zout->avail_in = 0; + for (;;) { + /* If data in output buffer write it first */ + while (ctx->ocount) { + ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount); + if (ret <= 0) { + BIO_copy_next_retry(b); + return ret; + } + ctx->optr += ret; + ctx->ocount -= ret; + } + if (ctx->odone) + return 1; + + /* Compress some more */ + + /* Reset buffer */ + ctx->optr = ctx->obuf; + zout->next_out = ctx->obuf; + zout->avail_out = ctx->obufsize; + /* Compress some more */ + ret = deflate(zout, Z_FINISH); + if (ret == Z_STREAM_END) + ctx->odone = 1; + else if (ret != Z_OK) { + COMPerr(COMP_F_BIO_ZLIB_FLUSH, COMP_R_ZLIB_DEFLATE_ERROR); + ERR_add_error_data(2, "zlib error:", zError(ret)); + return 0; + } + ctx->ocount = ctx->obufsize - zout->avail_out; + } +} + +static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO_ZLIB_CTX *ctx; + int ret, *ip; + int ibs, obs; + if (!b->next_bio) + return 0; + ctx = (BIO_ZLIB_CTX *) b->ptr; + switch (cmd) { + + case BIO_CTRL_RESET: + ctx->ocount = 0; + ctx->odone = 0; + ret = 1; + break; + + case BIO_CTRL_FLUSH: + ret = bio_zlib_flush(b); + if (ret > 0) + ret = BIO_flush(b->next_bio); + break; + + case BIO_C_SET_BUFF_SIZE: + ibs = -1; + obs = -1; + if (ptr != NULL) { + ip = ptr; + if (*ip == 0) + ibs = (int)num; + else + obs = (int)num; + } else { + ibs = (int)num; + obs = ibs; + } + + if (ibs != -1) { + if (ctx->ibuf) { + OPENSSL_free(ctx->ibuf); + ctx->ibuf = NULL; + } + ctx->ibufsize = ibs; + } + + if (obs != -1) { + if (ctx->obuf) { + OPENSSL_free(ctx->obuf); + ctx->obuf = NULL; + } + ctx->obufsize = obs; + } + ret = 1; + break; + + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + + } + + return ret; +} + +static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + if (!b->next_bio) + return 0; + return BIO_callback_ctrl(b->next_bio, cmd, fp); +} + +#endif diff --git a/libs/openssl/crypto/comp/comp.h b/libs/openssl/crypto/comp/comp.h new file mode 100644 index 00000000..60a07340 --- /dev/null +++ b/libs/openssl/crypto/comp/comp.h @@ -0,0 +1,83 @@ + +#ifndef HEADER_COMP_H +# define HEADER_COMP_H + +# include + +# ifdef OPENSSL_NO_COMP +# error COMP is disabled. +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct comp_ctx_st COMP_CTX; + +typedef struct comp_method_st { + int type; /* NID for compression library */ + const char *name; /* A text string to identify the library */ + int (*init) (COMP_CTX *ctx); + void (*finish) (COMP_CTX *ctx); + int (*compress) (COMP_CTX *ctx, + unsigned char *out, unsigned int olen, + unsigned char *in, unsigned int ilen); + int (*expand) (COMP_CTX *ctx, + unsigned char *out, unsigned int olen, + unsigned char *in, unsigned int ilen); + /* + * The following two do NOTHING, but are kept for backward compatibility + */ + long (*ctrl) (void); + long (*callback_ctrl) (void); +} COMP_METHOD; + +struct comp_ctx_st { + COMP_METHOD *meth; + unsigned long compress_in; + unsigned long compress_out; + unsigned long expand_in; + unsigned long expand_out; + CRYPTO_EX_DATA ex_data; +}; + +COMP_CTX *COMP_CTX_new(COMP_METHOD *meth); +void COMP_CTX_free(COMP_CTX *ctx); +int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); +int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen); +COMP_METHOD *COMP_rle(void); +COMP_METHOD *COMP_zlib(void); +void COMP_zlib_cleanup(void); + +# ifdef HEADER_BIO_H +# ifdef ZLIB +BIO_METHOD *BIO_f_zlib(void); +# endif +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_COMP_strings(void); + +/* Error codes for the COMP functions. */ + +/* Function codes. */ +# define COMP_F_BIO_ZLIB_FLUSH 99 +# define COMP_F_BIO_ZLIB_NEW 100 +# define COMP_F_BIO_ZLIB_READ 101 +# define COMP_F_BIO_ZLIB_WRITE 102 + +/* Reason codes. */ +# define COMP_R_ZLIB_DEFLATE_ERROR 99 +# define COMP_R_ZLIB_INFLATE_ERROR 100 +# define COMP_R_ZLIB_NOT_SUPPORTED 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/comp/comp_err.c b/libs/openssl/crypto/comp/comp_err.c new file mode 100644 index 00000000..8ca159b6 --- /dev/null +++ b/libs/openssl/crypto/comp/comp_err.c @@ -0,0 +1,98 @@ +/* crypto/comp/comp_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_COMP,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_COMP,0,reason) + +static ERR_STRING_DATA COMP_str_functs[] = { + {ERR_FUNC(COMP_F_BIO_ZLIB_FLUSH), "BIO_ZLIB_FLUSH"}, + {ERR_FUNC(COMP_F_BIO_ZLIB_NEW), "BIO_ZLIB_NEW"}, + {ERR_FUNC(COMP_F_BIO_ZLIB_READ), "BIO_ZLIB_READ"}, + {ERR_FUNC(COMP_F_BIO_ZLIB_WRITE), "BIO_ZLIB_WRITE"}, + {0, NULL} +}; + +static ERR_STRING_DATA COMP_str_reasons[] = { + {ERR_REASON(COMP_R_ZLIB_DEFLATE_ERROR), "zlib deflate error"}, + {ERR_REASON(COMP_R_ZLIB_INFLATE_ERROR), "zlib inflate error"}, + {ERR_REASON(COMP_R_ZLIB_NOT_SUPPORTED), "zlib not supported"}, + {0, NULL} +}; + +#endif + +void ERR_load_COMP_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(COMP_str_functs[0].error) == NULL) { + ERR_load_strings(0, COMP_str_functs); + ERR_load_strings(0, COMP_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/comp/comp_lib.c b/libs/openssl/crypto/comp/comp_lib.c new file mode 100644 index 00000000..bd4eb7a1 --- /dev/null +++ b/libs/openssl/crypto/comp/comp_lib.c @@ -0,0 +1,66 @@ +#include +#include +#include +#include +#include + +COMP_CTX *COMP_CTX_new(COMP_METHOD *meth) +{ + COMP_CTX *ret; + + if ((ret = (COMP_CTX *)OPENSSL_malloc(sizeof(COMP_CTX))) == NULL) { + /* ZZZZZZZZZZZZZZZZ */ + return (NULL); + } + memset(ret, 0, sizeof(COMP_CTX)); + ret->meth = meth; + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { + OPENSSL_free(ret); + ret = NULL; + } + return (ret); +} + +void COMP_CTX_free(COMP_CTX *ctx) +{ + if (ctx == NULL) + return; + + if (ctx->meth->finish != NULL) + ctx->meth->finish(ctx); + + OPENSSL_free(ctx); +} + +int COMP_compress_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen) +{ + int ret; + if (ctx->meth->compress == NULL) { + /* ZZZZZZZZZZZZZZZZZ */ + return (-1); + } + ret = ctx->meth->compress(ctx, out, olen, in, ilen); + if (ret > 0) { + ctx->compress_in += ilen; + ctx->compress_out += ret; + } + return (ret); +} + +int COMP_expand_block(COMP_CTX *ctx, unsigned char *out, int olen, + unsigned char *in, int ilen) +{ + int ret; + + if (ctx->meth->expand == NULL) { + /* ZZZZZZZZZZZZZZZZZ */ + return (-1); + } + ret = ctx->meth->expand(ctx, out, olen, in, ilen); + if (ret > 0) { + ctx->expand_in += ilen; + ctx->expand_out += ret; + } + return (ret); +} diff --git a/libs/openssl/crypto/conf/README b/libs/openssl/crypto/conf/README new file mode 100644 index 00000000..96e53b34 --- /dev/null +++ b/libs/openssl/crypto/conf/README @@ -0,0 +1,73 @@ +Configuration modules. These are a set of modules which can perform +various configuration functions. + +Currently the routines should be called at most once when an application +starts up: that is before it starts any threads. + +The routines read a configuration file set up like this: + +----- +#default section +openssl_conf=init_section + +[init_section] + +module1=value1 +#Second instance of module1 +module1.1=valueX +module2=value2 +module3=dso_literal +module4=dso_section + +[dso_section] + +path=/some/path/to/some/dso.so +other_stuff=other_value +---- + +When this file is loaded a configuration module with the specified string +(module* in the above example) is looked up and its init function called as: + +int conf_init_func(CONF_IMODULE *md, CONF *cnf); + +The function can then take whatever action is appropriate, for example further +lookups based on the value. Multiple instances of the same config module can be +loaded. + +When the application closes down the modules are cleaned up by calling an +optional finish function: + +void conf_finish_func(CONF_IMODULE *md); + +The finish functions are called in reverse order: that is the last module +loaded is the first one cleaned up. + +If no module exists with a given name then an attempt is made to load a DSO +with the supplied name. This might mean that "module3" attempts to load a DSO +called libmodule3.so or module3.dll for example. An explicit DSO name can be +given by including a separate section as in the module4 example above. + +The DSO is expected to at least contain an initialization function: + +int OPENSSL_init(CONF_IMODULE *md, CONF *cnf); + +and may also include a finish function: + +void OPENSSL_finish(CONF_IMODULE *md); + +Static modules can also be added using, + +int CONF_module_add(char *name, dso_mod_init_func *ifunc, dso_mod_finish_func +*ffunc); + +where "name" is the name in the configuration file this function corresponds +to. + +A set of builtin modules (currently only an ASN1 non functional test module) +can be added by calling OPENSSL_load_builtin_modules(). + +The function OPENSSL_config() is intended as a simple configuration function +that any application can call to perform various default configuration tasks. +It uses the file openssl.cnf in the usual locations. + + diff --git a/libs/openssl/crypto/conf/cnf_save.c b/libs/openssl/crypto/conf/cnf_save.c new file mode 100644 index 00000000..71c43174 --- /dev/null +++ b/libs/openssl/crypto/conf/cnf_save.c @@ -0,0 +1,104 @@ +/* crypto/conf/cnf_save.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +static void print_conf(CONF_VALUE *cv); +static IMPLEMENT_LHASH_DOALL_FN(print_conf, CONF_VALUE *); + +main() +{ + LHASH *conf; + long l; + + conf = CONF_load(NULL, "../../apps/openssl.cnf", &l); + if (conf == NULL) { + fprintf(stderr, "error loading config, line %ld\n", l); + exit(1); + } + + lh_doall(conf, LHASH_DOALL_FN(print_conf)); +} + +static void print_conf(CONF_VALUE *cv) +{ + int i; + CONF_VALUE *v; + char *section; + char *name; + char *value; + STACK *s; + + /* If it is a single entry, return */ + + if (cv->name != NULL) + return; + + printf("[ %s ]\n", cv->section); + s = (STACK *) cv->value; + + for (i = 0; i < sk_num(s); i++) { + v = (CONF_VALUE *)sk_value(s, i); + section = (v->section == NULL) ? "None" : v->section; + name = (v->name == NULL) ? "None" : v->name; + value = (v->value == NULL) ? "None" : v->value; + printf("%s=%s\n", name, value); + } + printf("\n"); +} diff --git a/libs/openssl/crypto/conf/conf.h b/libs/openssl/crypto/conf/conf.h new file mode 100644 index 00000000..8d926d5d --- /dev/null +++ b/libs/openssl/crypto/conf/conf.h @@ -0,0 +1,267 @@ +/* crypto/conf/conf.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONF_H +# define HEADER_CONF_H + +# include +# include +# include +# include +# include + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct { + char *section; + char *name; + char *value; +} CONF_VALUE; + +DECLARE_STACK_OF(CONF_VALUE) +DECLARE_LHASH_OF(CONF_VALUE); + +struct conf_st; +struct conf_method_st; +typedef struct conf_method_st CONF_METHOD; + +struct conf_method_st { + const char *name; + CONF *(*create) (CONF_METHOD *meth); + int (*init) (CONF *conf); + int (*destroy) (CONF *conf); + int (*destroy_data) (CONF *conf); + int (*load_bio) (CONF *conf, BIO *bp, long *eline); + int (*dump) (const CONF *conf, BIO *bp); + int (*is_number) (const CONF *conf, char c); + int (*to_int) (const CONF *conf, char c); + int (*load) (CONF *conf, const char *name, long *eline); +}; + +/* Module definitions */ + +typedef struct conf_imodule_st CONF_IMODULE; +typedef struct conf_module_st CONF_MODULE; + +DECLARE_STACK_OF(CONF_MODULE) +DECLARE_STACK_OF(CONF_IMODULE) + +/* DSO module function typedefs */ +typedef int conf_init_func (CONF_IMODULE *md, const CONF *cnf); +typedef void conf_finish_func (CONF_IMODULE *md); + +# define CONF_MFLAGS_IGNORE_ERRORS 0x1 +# define CONF_MFLAGS_IGNORE_RETURN_CODES 0x2 +# define CONF_MFLAGS_SILENT 0x4 +# define CONF_MFLAGS_NO_DSO 0x8 +# define CONF_MFLAGS_IGNORE_MISSING_FILE 0x10 +# define CONF_MFLAGS_DEFAULT_SECTION 0x20 + +int CONF_set_default_method(CONF_METHOD *meth); +void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash); +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, + long *eline); +# ifndef OPENSSL_NO_FP_API +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline); +# endif +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, + long *eline); +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section); +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name); +void CONF_free(LHASH_OF(CONF_VALUE) *conf); +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out); +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out); + +void OPENSSL_config(const char *config_name); +void OPENSSL_no_config(void); + +/* + * New conf code. The semantics are different from the functions above. If + * that wasn't the case, the above functions would have been replaced + */ + +struct conf_st { + CONF_METHOD *meth; + void *meth_data; + LHASH_OF(CONF_VALUE) *data; +}; + +CONF *NCONF_new(CONF_METHOD *meth); +CONF_METHOD *NCONF_default(void); +CONF_METHOD *NCONF_WIN32(void); +# if 0 /* Just to give you an idea of what I have in + * mind */ +CONF_METHOD *NCONF_XML(void); +# endif +void NCONF_free(CONF *conf); +void NCONF_free_data(CONF *conf); + +int NCONF_load(CONF *conf, const char *file, long *eline); +# ifndef OPENSSL_NO_FP_API +int NCONF_load_fp(CONF *conf, FILE *fp, long *eline); +# endif +int NCONF_load_bio(CONF *conf, BIO *bp, long *eline); +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, + const char *section); +char *NCONF_get_string(const CONF *conf, const char *group, const char *name); +int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, + long *result); +int NCONF_dump_fp(const CONF *conf, FILE *out); +int NCONF_dump_bio(const CONF *conf, BIO *out); + +# if 0 /* The following function has no error + * checking, and should therefore be avoided */ +long NCONF_get_number(CONF *conf, char *group, char *name); +# else +# define NCONF_get_number(c,g,n,r) NCONF_get_number_e(c,g,n,r) +# endif + +/* Module functions */ + +int CONF_modules_load(const CONF *cnf, const char *appname, + unsigned long flags); +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags); +void CONF_modules_unload(int all); +void CONF_modules_finish(void); +void CONF_modules_free(void); +int CONF_module_add(const char *name, conf_init_func *ifunc, + conf_finish_func *ffunc); + +const char *CONF_imodule_get_name(const CONF_IMODULE *md); +const char *CONF_imodule_get_value(const CONF_IMODULE *md); +void *CONF_imodule_get_usr_data(const CONF_IMODULE *md); +void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data); +CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md); +unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md); +void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags); +void *CONF_module_get_usr_data(CONF_MODULE *pmod); +void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data); + +char *CONF_get1_default_config_file(void); + +int CONF_parse_list(const char *list, int sep, int nospc, + int (*list_cb) (const char *elem, int len, void *usr), + void *arg); + +void OPENSSL_load_builtin_modules(void); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_CONF_strings(void); + +/* Error codes for the CONF functions. */ + +/* Function codes. */ +# define CONF_F_CONF_DUMP_FP 104 +# define CONF_F_CONF_LOAD 100 +# define CONF_F_CONF_LOAD_BIO 102 +# define CONF_F_CONF_LOAD_FP 103 +# define CONF_F_CONF_MODULES_LOAD 116 +# define CONF_F_CONF_PARSE_LIST 119 +# define CONF_F_DEF_LOAD 120 +# define CONF_F_DEF_LOAD_BIO 121 +# define CONF_F_MODULE_INIT 115 +# define CONF_F_MODULE_LOAD_DSO 117 +# define CONF_F_MODULE_RUN 118 +# define CONF_F_NCONF_DUMP_BIO 105 +# define CONF_F_NCONF_DUMP_FP 106 +# define CONF_F_NCONF_GET_NUMBER 107 +# define CONF_F_NCONF_GET_NUMBER_E 112 +# define CONF_F_NCONF_GET_SECTION 108 +# define CONF_F_NCONF_GET_STRING 109 +# define CONF_F_NCONF_LOAD 113 +# define CONF_F_NCONF_LOAD_BIO 110 +# define CONF_F_NCONF_LOAD_FP 114 +# define CONF_F_NCONF_NEW 111 +# define CONF_F_STR_COPY 101 + +/* Reason codes. */ +# define CONF_R_ERROR_LOADING_DSO 110 +# define CONF_R_LIST_CANNOT_BE_NULL 115 +# define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 100 +# define CONF_R_MISSING_EQUAL_SIGN 101 +# define CONF_R_MISSING_FINISH_FUNCTION 111 +# define CONF_R_MISSING_INIT_FUNCTION 112 +# define CONF_R_MODULE_INITIALIZATION_ERROR 109 +# define CONF_R_NO_CLOSE_BRACE 102 +# define CONF_R_NO_CONF 105 +# define CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE 106 +# define CONF_R_NO_SECTION 107 +# define CONF_R_NO_SUCH_FILE 114 +# define CONF_R_NO_VALUE 108 +# define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 103 +# define CONF_R_UNKNOWN_MODULE_NAME 113 +# define CONF_R_VARIABLE_HAS_NO_VALUE 104 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/conf/conf_api.c b/libs/openssl/crypto/conf/conf_api.c new file mode 100644 index 00000000..4cf75533 --- /dev/null +++ b/libs/openssl/crypto/conf/conf_api.c @@ -0,0 +1,305 @@ +/* conf_api.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Part of the code in here was originally in conf.c, which is now removed */ + +#ifndef CONF_DEBUG +# undef NDEBUG /* avoid conflicting definitions */ +# define NDEBUG +#endif + +#include +#include +#include +#include +#include +#include "e_os.h" + +static void value_free_hash_doall_arg(CONF_VALUE *a, + LHASH_OF(CONF_VALUE) *conf); +static void value_free_stack_doall(CONF_VALUE *a); +static IMPLEMENT_LHASH_DOALL_ARG_FN(value_free_hash, CONF_VALUE, + LHASH_OF(CONF_VALUE)) +static IMPLEMENT_LHASH_DOALL_FN(value_free_stack, CONF_VALUE) + +/* Up until OpenSSL 0.9.5a, this was get_section */ +CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section) +{ + CONF_VALUE *v, vv; + + if ((conf == NULL) || (section == NULL)) + return (NULL); + vv.name = NULL; + vv.section = (char *)section; + v = lh_CONF_VALUE_retrieve(conf->data, &vv); + return (v); +} + +/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ +STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, + const char *section) +{ + CONF_VALUE *v; + + v = _CONF_get_section(conf, section); + if (v != NULL) + return ((STACK_OF(CONF_VALUE) *)v->value); + else + return (NULL); +} + +int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value) +{ + CONF_VALUE *v = NULL; + STACK_OF(CONF_VALUE) *ts; + + ts = (STACK_OF(CONF_VALUE) *)section->value; + + value->section = section->section; + if (!sk_CONF_VALUE_push(ts, value)) { + return 0; + } + + v = lh_CONF_VALUE_insert(conf->data, value); + if (v != NULL) { + (void)sk_CONF_VALUE_delete_ptr(ts, v); + OPENSSL_free(v->name); + OPENSSL_free(v->value); + OPENSSL_free(v); + } + return 1; +} + +char *_CONF_get_string(const CONF *conf, const char *section, + const char *name) +{ + CONF_VALUE *v, vv; + char *p; + + if (name == NULL) + return (NULL); + if (conf != NULL) { + if (section != NULL) { + vv.name = (char *)name; + vv.section = (char *)section; + v = lh_CONF_VALUE_retrieve(conf->data, &vv); + if (v != NULL) + return (v->value); + if (strcmp(section, "ENV") == 0) { + p = getenv(name); + if (p != NULL) + return (p); + } + } + vv.section = "default"; + vv.name = (char *)name; + v = lh_CONF_VALUE_retrieve(conf->data, &vv); + if (v != NULL) + return (v->value); + else + return (NULL); + } else + return (getenv(name)); +} + +#if 0 /* There's no way to provide error checking + * with this function, so force implementors + * of the higher levels to get a string and + * read the number themselves. */ +long _CONF_get_number(CONF *conf, char *section, char *name) +{ + char *str; + long ret = 0; + + str = _CONF_get_string(conf, section, name); + if (str == NULL) + return (0); + for (;;) { + if (conf->meth->is_number(conf, *str)) + ret = ret * 10 + conf->meth->to_int(conf, *str); + else + return (ret); + str++; + } +} +#endif + +static unsigned long conf_value_hash(const CONF_VALUE *v) +{ + return (lh_strhash(v->section) << 2) ^ lh_strhash(v->name); +} + +static IMPLEMENT_LHASH_HASH_FN(conf_value, CONF_VALUE) + +static int conf_value_cmp(const CONF_VALUE *a, const CONF_VALUE *b) +{ + int i; + + if (a->section != b->section) { + i = strcmp(a->section, b->section); + if (i) + return (i); + } + + if ((a->name != NULL) && (b->name != NULL)) { + i = strcmp(a->name, b->name); + return (i); + } else if (a->name == b->name) + return (0); + else + return ((a->name == NULL) ? -1 : 1); +} + +static IMPLEMENT_LHASH_COMP_FN(conf_value, CONF_VALUE) + +int _CONF_new_data(CONF *conf) +{ + if (conf == NULL) { + return 0; + } + if (conf->data == NULL) + if ((conf->data = lh_CONF_VALUE_new()) == NULL) { + return 0; + } + return 1; +} + +void _CONF_free_data(CONF *conf) +{ + if (conf == NULL || conf->data == NULL) + return; + + lh_CONF_VALUE_down_load(conf->data) = 0; /* evil thing to make * sure the + * 'OPENSSL_free()' works as * + * expected */ + lh_CONF_VALUE_doall_arg(conf->data, + LHASH_DOALL_ARG_FN(value_free_hash), + LHASH_OF(CONF_VALUE), conf->data); + + /* + * We now have only 'section' entries in the hash table. Due to problems + * with + */ + + lh_CONF_VALUE_doall(conf->data, LHASH_DOALL_FN(value_free_stack)); + lh_CONF_VALUE_free(conf->data); +} + +static void value_free_hash_doall_arg(CONF_VALUE *a, + LHASH_OF(CONF_VALUE) *conf) +{ + if (a->name != NULL) + (void)lh_CONF_VALUE_delete(conf, a); +} + +static void value_free_stack_doall(CONF_VALUE *a) +{ + CONF_VALUE *vv; + STACK_OF(CONF_VALUE) *sk; + int i; + + if (a->name != NULL) + return; + + sk = (STACK_OF(CONF_VALUE) *)a->value; + for (i = sk_CONF_VALUE_num(sk) - 1; i >= 0; i--) { + vv = sk_CONF_VALUE_value(sk, i); + OPENSSL_free(vv->value); + OPENSSL_free(vv->name); + OPENSSL_free(vv); + } + if (sk != NULL) + sk_CONF_VALUE_free(sk); + OPENSSL_free(a->section); + OPENSSL_free(a); +} + +/* Up until OpenSSL 0.9.5a, this was new_section */ +CONF_VALUE *_CONF_new_section(CONF *conf, const char *section) +{ + STACK_OF(CONF_VALUE) *sk = NULL; + int ok = 0, i; + CONF_VALUE *v = NULL, *vv; + + if ((sk = sk_CONF_VALUE_new_null()) == NULL) + goto err; + if ((v = OPENSSL_malloc(sizeof(CONF_VALUE))) == NULL) + goto err; + i = strlen(section) + 1; + if ((v->section = OPENSSL_malloc(i)) == NULL) + goto err; + + memcpy(v->section, section, i); + v->name = NULL; + v->value = (char *)sk; + + vv = lh_CONF_VALUE_insert(conf->data, v); + OPENSSL_assert(vv == NULL); + ok = 1; + err: + if (!ok) { + if (sk != NULL) + sk_CONF_VALUE_free(sk); + if (v != NULL) + OPENSSL_free(v); + v = NULL; + } + return (v); +} + +IMPLEMENT_STACK_OF(CONF_VALUE) diff --git a/libs/openssl/crypto/conf/conf_api.h b/libs/openssl/crypto/conf/conf_api.h new file mode 100644 index 00000000..e478f7df --- /dev/null +++ b/libs/openssl/crypto/conf/conf_api.h @@ -0,0 +1,89 @@ +/* conf_api.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONF_API_H +# define HEADER_CONF_API_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Up until OpenSSL 0.9.5a, this was new_section */ +CONF_VALUE *_CONF_new_section(CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was get_section */ +CONF_VALUE *_CONF_get_section(const CONF *conf, const char *section); +/* Up until OpenSSL 0.9.5a, this was CONF_get_section */ +STACK_OF(CONF_VALUE) *_CONF_get_section_values(const CONF *conf, + const char *section); + +int _CONF_add_string(CONF *conf, CONF_VALUE *section, CONF_VALUE *value); +char *_CONF_get_string(const CONF *conf, const char *section, + const char *name); +long _CONF_get_number(const CONF *conf, const char *section, + const char *name); + +int _CONF_new_data(CONF *conf); +void _CONF_free_data(CONF *conf); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/conf/conf_def.c b/libs/openssl/crypto/conf/conf_def.c new file mode 100644 index 00000000..68c77cec --- /dev/null +++ b/libs/openssl/crypto/conf/conf_def.c @@ -0,0 +1,706 @@ +/* crypto/conf/conf.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Part of the code in here was originally in conf.c, which is now removed */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include "conf_def.h" +#include +#include + +static char *eat_ws(CONF *conf, char *p); +static char *eat_alpha_numeric(CONF *conf, char *p); +static void clear_comments(CONF *conf, char *p); +static int str_copy(CONF *conf, char *section, char **to, char *from); +static char *scan_quote(CONF *conf, char *p); +static char *scan_dquote(CONF *conf, char *p); +#define scan_esc(conf,p) (((IS_EOF((conf),(p)[1]))?((p)+1):((p)+2))) + +static CONF *def_create(CONF_METHOD *meth); +static int def_init_default(CONF *conf); +static int def_init_WIN32(CONF *conf); +static int def_destroy(CONF *conf); +static int def_destroy_data(CONF *conf); +static int def_load(CONF *conf, const char *name, long *eline); +static int def_load_bio(CONF *conf, BIO *bp, long *eline); +static int def_dump(const CONF *conf, BIO *bp); +static int def_is_number(const CONF *conf, char c); +static int def_to_int(const CONF *conf, char c); + +const char CONF_def_version[] = "CONF_def" OPENSSL_VERSION_PTEXT; + +static CONF_METHOD default_method = { + "OpenSSL default", + def_create, + def_init_default, + def_destroy, + def_destroy_data, + def_load_bio, + def_dump, + def_is_number, + def_to_int, + def_load +}; + +static CONF_METHOD WIN32_method = { + "WIN32", + def_create, + def_init_WIN32, + def_destroy, + def_destroy_data, + def_load_bio, + def_dump, + def_is_number, + def_to_int, + def_load +}; + +CONF_METHOD *NCONF_default() +{ + return &default_method; +} + +CONF_METHOD *NCONF_WIN32() +{ + return &WIN32_method; +} + +static CONF *def_create(CONF_METHOD *meth) +{ + CONF *ret; + + ret = OPENSSL_malloc(sizeof(CONF) + sizeof(unsigned short *)); + if (ret) + if (meth->init(ret) == 0) { + OPENSSL_free(ret); + ret = NULL; + } + return ret; +} + +static int def_init_default(CONF *conf) +{ + if (conf == NULL) + return 0; + + conf->meth = &default_method; + conf->meth_data = CONF_type_default; + conf->data = NULL; + + return 1; +} + +static int def_init_WIN32(CONF *conf) +{ + if (conf == NULL) + return 0; + + conf->meth = &WIN32_method; + conf->meth_data = (void *)CONF_type_win32; + conf->data = NULL; + + return 1; +} + +static int def_destroy(CONF *conf) +{ + if (def_destroy_data(conf)) { + OPENSSL_free(conf); + return 1; + } + return 0; +} + +static int def_destroy_data(CONF *conf) +{ + if (conf == NULL) + return 0; + _CONF_free_data(conf); + return 1; +} + +static int def_load(CONF *conf, const char *name, long *line) +{ + int ret; + BIO *in = NULL; + +#ifdef OPENSSL_SYS_VMS + in = BIO_new_file(name, "r"); +#else + in = BIO_new_file(name, "rb"); +#endif + if (in == NULL) { + if (ERR_GET_REASON(ERR_peek_last_error()) == BIO_R_NO_SUCH_FILE) + CONFerr(CONF_F_DEF_LOAD, CONF_R_NO_SUCH_FILE); + else + CONFerr(CONF_F_DEF_LOAD, ERR_R_SYS_LIB); + return 0; + } + + ret = def_load_bio(conf, in, line); + BIO_free(in); + + return ret; +} + +static int def_load_bio(CONF *conf, BIO *in, long *line) +{ +/* The macro BUFSIZE conflicts with a system macro in VxWorks */ +#define CONFBUFSIZE 512 + int bufnum = 0, i, ii; + BUF_MEM *buff = NULL; + char *s, *p, *end; + int again; + long eline = 0; + char btmp[DECIMAL_SIZE(eline) + 1]; + CONF_VALUE *v = NULL, *tv; + CONF_VALUE *sv = NULL; + char *section = NULL, *buf; + char *start, *psection, *pname; + void *h = (void *)(conf->data); + + if ((buff = BUF_MEM_new()) == NULL) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); + goto err; + } + + section = BUF_strdup("default"); + if (section == NULL) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (_CONF_new_data(conf) == 0) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + + sv = _CONF_new_section(conf, section); + if (sv == NULL) { + CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + + bufnum = 0; + again = 0; + for (;;) { + if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_BUF_LIB); + goto err; + } + p = &(buff->data[bufnum]); + *p = '\0'; + BIO_gets(in, p, CONFBUFSIZE - 1); + p[CONFBUFSIZE - 1] = '\0'; + ii = i = strlen(p); + if (i == 0 && !again) + break; + again = 0; + while (i > 0) { + if ((p[i - 1] != '\r') && (p[i - 1] != '\n')) + break; + else + i--; + } + /* + * we removed some trailing stuff so there is a new line on the end. + */ + if (ii && i == ii) + again = 1; /* long line */ + else { + p[i] = '\0'; + eline++; /* another input line */ + } + + /* we now have a line with trailing \r\n removed */ + + /* i is the number of bytes */ + bufnum += i; + + v = NULL; + /* check for line continuation */ + if (bufnum >= 1) { + /* + * If we have bytes and the last char '\\' and second last char + * is not '\\' + */ + p = &(buff->data[bufnum - 1]); + if (IS_ESC(conf, p[0]) && ((bufnum <= 1) || !IS_ESC(conf, p[-1]))) { + bufnum--; + again = 1; + } + } + if (again) + continue; + bufnum = 0; + buf = buff->data; + + clear_comments(conf, buf); + s = eat_ws(conf, buf); + if (IS_EOF(conf, *s)) + continue; /* blank line */ + if (*s == '[') { + char *ss; + + s++; + start = eat_ws(conf, s); + ss = start; + again: + end = eat_alpha_numeric(conf, ss); + p = eat_ws(conf, end); + if (*p != ']') { + if (*p != '\0' && ss != p) { + ss = p; + goto again; + } + CONFerr(CONF_F_DEF_LOAD_BIO, + CONF_R_MISSING_CLOSE_SQUARE_BRACKET); + goto err; + } + *end = '\0'; + if (!str_copy(conf, NULL, §ion, start)) + goto err; + if ((sv = _CONF_get_section(conf, section)) == NULL) + sv = _CONF_new_section(conf, section); + if (sv == NULL) { + CONFerr(CONF_F_DEF_LOAD_BIO, + CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + continue; + } else { + pname = s; + psection = NULL; + end = eat_alpha_numeric(conf, s); + if ((end[0] == ':') && (end[1] == ':')) { + *end = '\0'; + end += 2; + psection = pname; + pname = end; + end = eat_alpha_numeric(conf, end); + } + p = eat_ws(conf, end); + if (*p != '=') { + CONFerr(CONF_F_DEF_LOAD_BIO, CONF_R_MISSING_EQUAL_SIGN); + goto err; + } + *end = '\0'; + p++; + start = eat_ws(conf, p); + while (!IS_EOF(conf, *p)) + p++; + p--; + while ((p != start) && (IS_WS(conf, *p))) + p--; + p++; + *p = '\0'; + + if (!(v = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + if (psection == NULL) + psection = section; + v->name = (char *)OPENSSL_malloc(strlen(pname) + 1); + v->value = NULL; + if (v->name == NULL) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + BUF_strlcpy(v->name, pname, strlen(pname) + 1); + if (!str_copy(conf, psection, &(v->value), start)) + goto err; + + if (strcmp(psection, section) != 0) { + if ((tv = _CONF_get_section(conf, psection)) + == NULL) + tv = _CONF_new_section(conf, psection); + if (tv == NULL) { + CONFerr(CONF_F_DEF_LOAD_BIO, + CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + } else + tv = sv; +#if 1 + if (_CONF_add_string(conf, tv, v) == 0) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } +#else + v->section = tv->section; + if (!sk_CONF_VALUE_push(ts, v)) { + CONFerr(CONF_F_DEF_LOAD_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + vv = (CONF_VALUE *)lh_insert(conf->data, v); + if (vv != NULL) { + sk_CONF_VALUE_delete_ptr(ts, vv); + OPENSSL_free(vv->name); + OPENSSL_free(vv->value); + OPENSSL_free(vv); + } +#endif + v = NULL; + } + } + if (buff != NULL) + BUF_MEM_free(buff); + if (section != NULL) + OPENSSL_free(section); + return (1); + err: + if (buff != NULL) + BUF_MEM_free(buff); + if (section != NULL) + OPENSSL_free(section); + if (line != NULL) + *line = eline; + BIO_snprintf(btmp, sizeof btmp, "%ld", eline); + ERR_add_error_data(2, "line ", btmp); + if ((h != conf->data) && (conf->data != NULL)) { + CONF_free(conf->data); + conf->data = NULL; + } + if (v != NULL) { + if (v->name != NULL) + OPENSSL_free(v->name); + if (v->value != NULL) + OPENSSL_free(v->value); + if (v != NULL) + OPENSSL_free(v); + } + return (0); +} + +static void clear_comments(CONF *conf, char *p) +{ + for (;;) { + if (IS_FCOMMENT(conf, *p)) { + *p = '\0'; + return; + } + if (!IS_WS(conf, *p)) { + break; + } + p++; + } + + for (;;) { + if (IS_COMMENT(conf, *p)) { + *p = '\0'; + return; + } + if (IS_DQUOTE(conf, *p)) { + p = scan_dquote(conf, p); + continue; + } + if (IS_QUOTE(conf, *p)) { + p = scan_quote(conf, p); + continue; + } + if (IS_ESC(conf, *p)) { + p = scan_esc(conf, p); + continue; + } + if (IS_EOF(conf, *p)) + return; + else + p++; + } +} + +static int str_copy(CONF *conf, char *section, char **pto, char *from) +{ + int q, r, rr = 0, to = 0, len = 0; + char *s, *e, *rp, *p, *rrp, *np, *cp, v; + BUF_MEM *buf; + + if ((buf = BUF_MEM_new()) == NULL) + return (0); + + len = strlen(from) + 1; + if (!BUF_MEM_grow(buf, len)) + goto err; + + for (;;) { + if (IS_QUOTE(conf, *from)) { + q = *from; + from++; + while (!IS_EOF(conf, *from) && (*from != q)) { + if (IS_ESC(conf, *from)) { + from++; + if (IS_EOF(conf, *from)) + break; + } + buf->data[to++] = *(from++); + } + if (*from == q) + from++; + } else if (IS_DQUOTE(conf, *from)) { + q = *from; + from++; + while (!IS_EOF(conf, *from)) { + if (*from == q) { + if (*(from + 1) == q) { + from++; + } else { + break; + } + } + buf->data[to++] = *(from++); + } + if (*from == q) + from++; + } else if (IS_ESC(conf, *from)) { + from++; + v = *(from++); + if (IS_EOF(conf, v)) + break; + else if (v == 'r') + v = '\r'; + else if (v == 'n') + v = '\n'; + else if (v == 'b') + v = '\b'; + else if (v == 't') + v = '\t'; + buf->data[to++] = v; + } else if (IS_EOF(conf, *from)) + break; + else if (*from == '$') { + /* try to expand it */ + rrp = NULL; + s = &(from[1]); + if (*s == '{') + q = '}'; + else if (*s == '(') + q = ')'; + else + q = 0; + + if (q) + s++; + cp = section; + e = np = s; + while (IS_ALPHA_NUMERIC(conf, *e)) + e++; + if ((e[0] == ':') && (e[1] == ':')) { + cp = np; + rrp = e; + rr = *e; + *rrp = '\0'; + e += 2; + np = e; + while (IS_ALPHA_NUMERIC(conf, *e)) + e++; + } + r = *e; + *e = '\0'; + rp = e; + if (q) { + if (r != q) { + CONFerr(CONF_F_STR_COPY, CONF_R_NO_CLOSE_BRACE); + goto err; + } + e++; + } + /*- + * So at this point we have + * np which is the start of the name string which is + * '\0' terminated. + * cp which is the start of the section string which is + * '\0' terminated. + * e is the 'next point after'. + * r and rr are the chars replaced by the '\0' + * rp and rrp is where 'r' and 'rr' came from. + */ + p = _CONF_get_string(conf, cp, np); + if (rrp != NULL) + *rrp = rr; + *rp = r; + if (p == NULL) { + CONFerr(CONF_F_STR_COPY, CONF_R_VARIABLE_HAS_NO_VALUE); + goto err; + } + if (!BUF_MEM_grow_clean(buf, + (strlen(p) + buf->length - (e - from)))) { + CONFerr(CONF_F_STR_COPY, ERR_R_MALLOC_FAILURE); + goto err; + } + while (*p) + buf->data[to++] = *(p++); + + /* + * Since we change the pointer 'from', we also have to change the + * perceived length of the string it points at. /RL + */ + len -= e - from; + from = e; + + /* + * In case there were no braces or parenthesis around the + * variable reference, we have to put back the character that was + * replaced with a '\0'. /RL + */ + *rp = r; + } else + buf->data[to++] = *(from++); + } + buf->data[to] = '\0'; + if (*pto != NULL) + OPENSSL_free(*pto); + *pto = buf->data; + OPENSSL_free(buf); + return (1); + err: + if (buf != NULL) + BUF_MEM_free(buf); + return (0); +} + +static char *eat_ws(CONF *conf, char *p) +{ + while (IS_WS(conf, *p) && (!IS_EOF(conf, *p))) + p++; + return (p); +} + +static char *eat_alpha_numeric(CONF *conf, char *p) +{ + for (;;) { + if (IS_ESC(conf, *p)) { + p = scan_esc(conf, p); + continue; + } + if (!IS_ALPHA_NUMERIC_PUNCT(conf, *p)) + return (p); + p++; + } +} + +static char *scan_quote(CONF *conf, char *p) +{ + int q = *p; + + p++; + while (!(IS_EOF(conf, *p)) && (*p != q)) { + if (IS_ESC(conf, *p)) { + p++; + if (IS_EOF(conf, *p)) + return (p); + } + p++; + } + if (*p == q) + p++; + return (p); +} + +static char *scan_dquote(CONF *conf, char *p) +{ + int q = *p; + + p++; + while (!(IS_EOF(conf, *p))) { + if (*p == q) { + if (*(p + 1) == q) { + p++; + } else { + break; + } + } + p++; + } + if (*p == q) + p++; + return (p); +} + +static void dump_value_doall_arg(CONF_VALUE *a, BIO *out) +{ + if (a->name) + BIO_printf(out, "[%s] %s=%s\n", a->section, a->name, a->value); + else + BIO_printf(out, "[[%s]]\n", a->section); +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(dump_value, CONF_VALUE, BIO) + +static int def_dump(const CONF *conf, BIO *out) +{ + lh_CONF_VALUE_doall_arg(conf->data, LHASH_DOALL_ARG_FN(dump_value), + BIO, out); + return 1; +} + +static int def_is_number(const CONF *conf, char c) +{ + return IS_NUMBER(conf, c); +} + +static int def_to_int(const CONF *conf, char c) +{ + return c - '0'; +} diff --git a/libs/openssl/crypto/conf/conf_def.h b/libs/openssl/crypto/conf/conf_def.h new file mode 100644 index 00000000..7d897b89 --- /dev/null +++ b/libs/openssl/crypto/conf/conf_def.h @@ -0,0 +1,181 @@ +/* crypto/conf/conf_def.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * THIS FILE WAS AUTOMAGICALLY GENERATED! Please modify and use keysets.pl to + * regenerate it. + */ + +#define CONF_NUMBER 1 +#define CONF_UPPER 2 +#define CONF_LOWER 4 +#define CONF_UNDER 256 +#define CONF_PUNCTUATION 512 +#define CONF_WS 16 +#define CONF_ESC 32 +#define CONF_QUOTE 64 +#define CONF_DQUOTE 1024 +#define CONF_COMMENT 128 +#define CONF_FCOMMENT 2048 +#define CONF_EOF 8 +#define CONF_HIGHBIT 4096 +#define CONF_ALPHA (CONF_UPPER|CONF_LOWER) +#define CONF_ALPHA_NUMERIC (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) +#define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \ + CONF_PUNCTUATION) + +#define KEYTYPES(c) ((unsigned short *)((c)->meth_data)) +#ifndef CHARSET_EBCDIC +# define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT) +# define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT) +# define IS_EOF(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_EOF) +# define IS_ESC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ESC) +# define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER) +# define IS_WS(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_WS) +# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC) +# define IS_ALPHA_NUMERIC_PUNCT(c,a) \ + (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT) +# define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE) +# define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE) +# define IS_HIGHBIT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT) + +#else /* CHARSET_EBCDIC */ + +# define IS_COMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT) +# define IS_FCOMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT) +# define IS_EOF(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF) +# define IS_ESC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC) +# define IS_NUMBER(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER) +# define IS_WS(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS) +# define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC) +# define IS_ALPHA_NUMERIC_PUNCT(c,a) \ + (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC_PUNCT) +# define IS_QUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE) +# define IS_DQUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE) +# define IS_HIGHBIT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT) +#endif /* CHARSET_EBCDIC */ + +static unsigned short CONF_type_default[256] = { + 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0010, 0x0200, 0x0040, 0x0080, 0x0000, 0x0200, 0x0200, 0x0040, + 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0x0200, + 0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0000, 0x0020, 0x0000, 0x0200, 0x0100, + 0x0040, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, +}; + +static unsigned short CONF_type_win32[256] = { + 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0010, 0x0010, 0x0000, 0x0000, 0x0010, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0010, 0x0200, 0x0400, 0x0000, 0x0000, 0x0200, 0x0200, 0x0000, + 0x0000, 0x0000, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, 0x0200, + 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, 0x0001, + 0x0001, 0x0001, 0x0000, 0x0A00, 0x0000, 0x0000, 0x0000, 0x0200, + 0x0200, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, 0x0002, + 0x0002, 0x0002, 0x0002, 0x0000, 0x0000, 0x0000, 0x0200, 0x0100, + 0x0000, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, 0x0004, + 0x0004, 0x0004, 0x0004, 0x0000, 0x0200, 0x0000, 0x0200, 0x0000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, + 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, 0x1000, +}; diff --git a/libs/openssl/crypto/conf/conf_err.c b/libs/openssl/crypto/conf/conf_err.c new file mode 100644 index 00000000..bb5e2fe2 --- /dev/null +++ b/libs/openssl/crypto/conf/conf_err.c @@ -0,0 +1,133 @@ +/* crypto/conf/conf_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CONF,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CONF,0,reason) + +static ERR_STRING_DATA CONF_str_functs[] = { + {ERR_FUNC(CONF_F_CONF_DUMP_FP), "CONF_dump_fp"}, + {ERR_FUNC(CONF_F_CONF_LOAD), "CONF_load"}, + {ERR_FUNC(CONF_F_CONF_LOAD_BIO), "CONF_load_bio"}, + {ERR_FUNC(CONF_F_CONF_LOAD_FP), "CONF_load_fp"}, + {ERR_FUNC(CONF_F_CONF_MODULES_LOAD), "CONF_modules_load"}, + {ERR_FUNC(CONF_F_CONF_PARSE_LIST), "CONF_parse_list"}, + {ERR_FUNC(CONF_F_DEF_LOAD), "DEF_LOAD"}, + {ERR_FUNC(CONF_F_DEF_LOAD_BIO), "DEF_LOAD_BIO"}, + {ERR_FUNC(CONF_F_MODULE_INIT), "MODULE_INIT"}, + {ERR_FUNC(CONF_F_MODULE_LOAD_DSO), "MODULE_LOAD_DSO"}, + {ERR_FUNC(CONF_F_MODULE_RUN), "MODULE_RUN"}, + {ERR_FUNC(CONF_F_NCONF_DUMP_BIO), "NCONF_dump_bio"}, + {ERR_FUNC(CONF_F_NCONF_DUMP_FP), "NCONF_dump_fp"}, + {ERR_FUNC(CONF_F_NCONF_GET_NUMBER), "NCONF_get_number"}, + {ERR_FUNC(CONF_F_NCONF_GET_NUMBER_E), "NCONF_get_number_e"}, + {ERR_FUNC(CONF_F_NCONF_GET_SECTION), "NCONF_get_section"}, + {ERR_FUNC(CONF_F_NCONF_GET_STRING), "NCONF_get_string"}, + {ERR_FUNC(CONF_F_NCONF_LOAD), "NCONF_load"}, + {ERR_FUNC(CONF_F_NCONF_LOAD_BIO), "NCONF_load_bio"}, + {ERR_FUNC(CONF_F_NCONF_LOAD_FP), "NCONF_load_fp"}, + {ERR_FUNC(CONF_F_NCONF_NEW), "NCONF_new"}, + {ERR_FUNC(CONF_F_STR_COPY), "STR_COPY"}, + {0, NULL} +}; + +static ERR_STRING_DATA CONF_str_reasons[] = { + {ERR_REASON(CONF_R_ERROR_LOADING_DSO), "error loading dso"}, + {ERR_REASON(CONF_R_LIST_CANNOT_BE_NULL), "list cannot be null"}, + {ERR_REASON(CONF_R_MISSING_CLOSE_SQUARE_BRACKET), + "missing close square bracket"}, + {ERR_REASON(CONF_R_MISSING_EQUAL_SIGN), "missing equal sign"}, + {ERR_REASON(CONF_R_MISSING_FINISH_FUNCTION), "missing finish function"}, + {ERR_REASON(CONF_R_MISSING_INIT_FUNCTION), "missing init function"}, + {ERR_REASON(CONF_R_MODULE_INITIALIZATION_ERROR), + "module initialization error"}, + {ERR_REASON(CONF_R_NO_CLOSE_BRACE), "no close brace"}, + {ERR_REASON(CONF_R_NO_CONF), "no conf"}, + {ERR_REASON(CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE), + "no conf or environment variable"}, + {ERR_REASON(CONF_R_NO_SECTION), "no section"}, + {ERR_REASON(CONF_R_NO_SUCH_FILE), "no such file"}, + {ERR_REASON(CONF_R_NO_VALUE), "no value"}, + {ERR_REASON(CONF_R_UNABLE_TO_CREATE_NEW_SECTION), + "unable to create new section"}, + {ERR_REASON(CONF_R_UNKNOWN_MODULE_NAME), "unknown module name"}, + {ERR_REASON(CONF_R_VARIABLE_HAS_NO_VALUE), "variable has no value"}, + {0, NULL} +}; + +#endif + +void ERR_load_CONF_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(CONF_str_functs[0].error) == NULL) { + ERR_load_strings(0, CONF_str_functs); + ERR_load_strings(0, CONF_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/conf/conf_lib.c b/libs/openssl/crypto/conf/conf_lib.c new file mode 100644 index 00000000..52813848 --- /dev/null +++ b/libs/openssl/crypto/conf/conf_lib.c @@ -0,0 +1,391 @@ +/* conf_lib.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include + +const char CONF_version[] = "CONF" OPENSSL_VERSION_PTEXT; + +static CONF_METHOD *default_CONF_method = NULL; + +/* Init a 'CONF' structure from an old LHASH */ + +void CONF_set_nconf(CONF *conf, LHASH_OF(CONF_VALUE) *hash) +{ + if (default_CONF_method == NULL) + default_CONF_method = NCONF_default(); + + default_CONF_method->init(conf); + conf->data = hash; +} + +/* + * The following section contains the "CONF classic" functions, rewritten in + * terms of the new CONF interface. + */ + +int CONF_set_default_method(CONF_METHOD *meth) +{ + default_CONF_method = meth; + return 1; +} + +LHASH_OF(CONF_VALUE) *CONF_load(LHASH_OF(CONF_VALUE) *conf, const char *file, + long *eline) +{ + LHASH_OF(CONF_VALUE) *ltmp; + BIO *in = NULL; + +#ifdef OPENSSL_SYS_VMS + in = BIO_new_file(file, "r"); +#else + in = BIO_new_file(file, "rb"); +#endif + if (in == NULL) { + CONFerr(CONF_F_CONF_LOAD, ERR_R_SYS_LIB); + return NULL; + } + + ltmp = CONF_load_bio(conf, in, eline); + BIO_free(in); + + return ltmp; +} + +#ifndef OPENSSL_NO_FP_API +LHASH_OF(CONF_VALUE) *CONF_load_fp(LHASH_OF(CONF_VALUE) *conf, FILE *fp, + long *eline) +{ + BIO *btmp; + LHASH_OF(CONF_VALUE) *ltmp; + if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { + CONFerr(CONF_F_CONF_LOAD_FP, ERR_R_BUF_LIB); + return NULL; + } + ltmp = CONF_load_bio(conf, btmp, eline); + BIO_free(btmp); + return ltmp; +} +#endif + +LHASH_OF(CONF_VALUE) *CONF_load_bio(LHASH_OF(CONF_VALUE) *conf, BIO *bp, + long *eline) +{ + CONF ctmp; + int ret; + + CONF_set_nconf(&ctmp, conf); + + ret = NCONF_load_bio(&ctmp, bp, eline); + if (ret) + return ctmp.data; + return NULL; +} + +STACK_OF(CONF_VALUE) *CONF_get_section(LHASH_OF(CONF_VALUE) *conf, + const char *section) +{ + if (conf == NULL) { + return NULL; + } else { + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return NCONF_get_section(&ctmp, section); + } +} + +char *CONF_get_string(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name) +{ + if (conf == NULL) { + return NCONF_get_string(NULL, group, name); + } else { + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return NCONF_get_string(&ctmp, group, name); + } +} + +long CONF_get_number(LHASH_OF(CONF_VALUE) *conf, const char *group, + const char *name) +{ + int status; + long result = 0; + + if (conf == NULL) { + status = NCONF_get_number_e(NULL, group, name, &result); + } else { + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + status = NCONF_get_number_e(&ctmp, group, name, &result); + } + + if (status == 0) { + /* This function does not believe in errors... */ + ERR_clear_error(); + } + return result; +} + +void CONF_free(LHASH_OF(CONF_VALUE) *conf) +{ + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + NCONF_free_data(&ctmp); +} + +#ifndef OPENSSL_NO_FP_API +int CONF_dump_fp(LHASH_OF(CONF_VALUE) *conf, FILE *out) +{ + BIO *btmp; + int ret; + + if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { + CONFerr(CONF_F_CONF_DUMP_FP, ERR_R_BUF_LIB); + return 0; + } + ret = CONF_dump_bio(conf, btmp); + BIO_free(btmp); + return ret; +} +#endif + +int CONF_dump_bio(LHASH_OF(CONF_VALUE) *conf, BIO *out) +{ + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return NCONF_dump_bio(&ctmp, out); +} + +/* + * The following section contains the "New CONF" functions. They are + * completely centralised around a new CONF structure that may contain + * basically anything, but at least a method pointer and a table of data. + * These functions are also written in terms of the bridge functions used by + * the "CONF classic" functions, for consistency. + */ + +CONF *NCONF_new(CONF_METHOD *meth) +{ + CONF *ret; + + if (meth == NULL) + meth = NCONF_default(); + + ret = meth->create(meth); + if (ret == NULL) { + CONFerr(CONF_F_NCONF_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + return ret; +} + +void NCONF_free(CONF *conf) +{ + if (conf == NULL) + return; + conf->meth->destroy(conf); +} + +void NCONF_free_data(CONF *conf) +{ + if (conf == NULL) + return; + conf->meth->destroy_data(conf); +} + +int NCONF_load(CONF *conf, const char *file, long *eline) +{ + if (conf == NULL) { + CONFerr(CONF_F_NCONF_LOAD, CONF_R_NO_CONF); + return 0; + } + + return conf->meth->load(conf, file, eline); +} + +#ifndef OPENSSL_NO_FP_API +int NCONF_load_fp(CONF *conf, FILE *fp, long *eline) +{ + BIO *btmp; + int ret; + if (!(btmp = BIO_new_fp(fp, BIO_NOCLOSE))) { + CONFerr(CONF_F_NCONF_LOAD_FP, ERR_R_BUF_LIB); + return 0; + } + ret = NCONF_load_bio(conf, btmp, eline); + BIO_free(btmp); + return ret; +} +#endif + +int NCONF_load_bio(CONF *conf, BIO *bp, long *eline) +{ + if (conf == NULL) { + CONFerr(CONF_F_NCONF_LOAD_BIO, CONF_R_NO_CONF); + return 0; + } + + return conf->meth->load_bio(conf, bp, eline); +} + +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) +{ + if (conf == NULL) { + CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_CONF); + return NULL; + } + + if (section == NULL) { + CONFerr(CONF_F_NCONF_GET_SECTION, CONF_R_NO_SECTION); + return NULL; + } + + return _CONF_get_section_values(conf, section); +} + +char *NCONF_get_string(const CONF *conf, const char *group, const char *name) +{ + char *s = _CONF_get_string(conf, group, name); + + /* + * Since we may get a value from an environment variable even if conf is + * NULL, let's check the value first + */ + if (s) + return s; + + if (conf == NULL) { + CONFerr(CONF_F_NCONF_GET_STRING, + CONF_R_NO_CONF_OR_ENVIRONMENT_VARIABLE); + return NULL; + } + CONFerr(CONF_F_NCONF_GET_STRING, CONF_R_NO_VALUE); + ERR_add_error_data(4, "group=", group, " name=", name); + return NULL; +} + +int NCONF_get_number_e(const CONF *conf, const char *group, const char *name, + long *result) +{ + char *str; + + if (result == NULL) { + CONFerr(CONF_F_NCONF_GET_NUMBER_E, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + str = NCONF_get_string(conf, group, name); + + if (str == NULL) + return 0; + + for (*result = 0; conf->meth->is_number(conf, *str);) { + *result = (*result) * 10 + conf->meth->to_int(conf, *str); + str++; + } + + return 1; +} + +#ifndef OPENSSL_NO_FP_API +int NCONF_dump_fp(const CONF *conf, FILE *out) +{ + BIO *btmp; + int ret; + if (!(btmp = BIO_new_fp(out, BIO_NOCLOSE))) { + CONFerr(CONF_F_NCONF_DUMP_FP, ERR_R_BUF_LIB); + return 0; + } + ret = NCONF_dump_bio(conf, btmp); + BIO_free(btmp); + return ret; +} +#endif + +int NCONF_dump_bio(const CONF *conf, BIO *out) +{ + if (conf == NULL) { + CONFerr(CONF_F_NCONF_DUMP_BIO, CONF_R_NO_CONF); + return 0; + } + + return conf->meth->dump(conf, out); +} + +/* This function should be avoided */ +#if 0 +long NCONF_get_number(CONF *conf, char *group, char *name) +{ + int status; + long ret = 0; + + status = NCONF_get_number_e(conf, group, name, &ret); + if (status == 0) { + /* This function does not believe in errors... */ + ERR_get_error(); + } + return ret; +} +#endif diff --git a/libs/openssl/crypto/conf/conf_mall.c b/libs/openssl/crypto/conf/conf_mall.c new file mode 100644 index 00000000..b4dbd662 --- /dev/null +++ b/libs/openssl/crypto/conf/conf_mall.c @@ -0,0 +1,81 @@ +/* conf_mall.c */ +/* + * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif + +/* Load all OpenSSL builtin modules */ + +void OPENSSL_load_builtin_modules(void) +{ + /* Add builtin modules here */ + ASN1_add_oid_module(); +#ifndef OPENSSL_NO_ENGINE + ENGINE_add_conf_module(); +#endif + EVP_add_alg_module(); +} diff --git a/libs/openssl/crypto/conf/conf_mod.c b/libs/openssl/crypto/conf/conf_mod.c new file mode 100644 index 00000000..9acfca4f --- /dev/null +++ b/libs/openssl/crypto/conf/conf_mod.c @@ -0,0 +1,597 @@ +/* conf_mod.c */ +/* + * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include "cryptlib.h" +#include +#include +#include + +#define DSO_mod_init_name "OPENSSL_init" +#define DSO_mod_finish_name "OPENSSL_finish" + +/* + * This structure contains a data about supported modules. entries in this + * table correspond to either dynamic or static modules. + */ + +struct conf_module_st { + /* DSO of this module or NULL if static */ + DSO *dso; + /* Name of the module */ + char *name; + /* Init function */ + conf_init_func *init; + /* Finish function */ + conf_finish_func *finish; + /* Number of successfully initialized modules */ + int links; + void *usr_data; +}; + +/* + * This structure contains information about modules that have been + * successfully initialized. There may be more than one entry for a given + * module. + */ + +struct conf_imodule_st { + CONF_MODULE *pmod; + char *name; + char *value; + unsigned long flags; + void *usr_data; +}; + +static STACK_OF(CONF_MODULE) *supported_modules = NULL; +static STACK_OF(CONF_IMODULE) *initialized_modules = NULL; + +static void module_free(CONF_MODULE *md); +static void module_finish(CONF_IMODULE *imod); +static int module_run(const CONF *cnf, char *name, char *value, + unsigned long flags); +static CONF_MODULE *module_add(DSO *dso, const char *name, + conf_init_func *ifunc, + conf_finish_func *ffunc); +static CONF_MODULE *module_find(char *name); +static int module_init(CONF_MODULE *pmod, char *name, char *value, + const CONF *cnf); +static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value, + unsigned long flags); + +/* Main function: load modules from a CONF structure */ + +int CONF_modules_load(const CONF *cnf, const char *appname, + unsigned long flags) +{ + STACK_OF(CONF_VALUE) *values; + CONF_VALUE *vl; + char *vsection = NULL; + + int ret, i; + + if (!cnf) + return 1; + + if (appname) + vsection = NCONF_get_string(cnf, NULL, appname); + + if (!appname || (!vsection && (flags & CONF_MFLAGS_DEFAULT_SECTION))) + vsection = NCONF_get_string(cnf, NULL, "openssl_conf"); + + if (!vsection) { + ERR_clear_error(); + return 1; + } + + values = NCONF_get_section(cnf, vsection); + + if (!values) + return 0; + + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + vl = sk_CONF_VALUE_value(values, i); + ret = module_run(cnf, vl->name, vl->value, flags); + if (ret <= 0) + if (!(flags & CONF_MFLAGS_IGNORE_ERRORS)) + return ret; + } + + return 1; + +} + +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags) +{ + char *file = NULL; + CONF *conf = NULL; + int ret = 0; + conf = NCONF_new(NULL); + if (!conf) + goto err; + + if (filename == NULL) { + file = CONF_get1_default_config_file(); + if (!file) + goto err; + } else + file = (char *)filename; + + if (NCONF_load(conf, file, NULL) <= 0) { + if ((flags & CONF_MFLAGS_IGNORE_MISSING_FILE) && + (ERR_GET_REASON(ERR_peek_last_error()) == CONF_R_NO_SUCH_FILE)) { + ERR_clear_error(); + ret = 1; + } + goto err; + } + + ret = CONF_modules_load(conf, appname, flags); + + err: + if (filename == NULL) + OPENSSL_free(file); + NCONF_free(conf); + + return ret; +} + +static int module_run(const CONF *cnf, char *name, char *value, + unsigned long flags) +{ + CONF_MODULE *md; + int ret; + + md = module_find(name); + + /* Module not found: try to load DSO */ + if (!md && !(flags & CONF_MFLAGS_NO_DSO)) + md = module_load_dso(cnf, name, value, flags); + + if (!md) { + if (!(flags & CONF_MFLAGS_SILENT)) { + CONFerr(CONF_F_MODULE_RUN, CONF_R_UNKNOWN_MODULE_NAME); + ERR_add_error_data(2, "module=", name); + } + return -1; + } + + ret = module_init(md, name, value, cnf); + + if (ret <= 0) { + if (!(flags & CONF_MFLAGS_SILENT)) { + char rcode[DECIMAL_SIZE(ret) + 1]; + CONFerr(CONF_F_MODULE_RUN, CONF_R_MODULE_INITIALIZATION_ERROR); + BIO_snprintf(rcode, sizeof rcode, "%-8d", ret); + ERR_add_error_data(6, "module=", name, ", value=", value, + ", retcode=", rcode); + } + } + + return ret; +} + +/* Load a module from a DSO */ +static CONF_MODULE *module_load_dso(const CONF *cnf, char *name, char *value, + unsigned long flags) +{ + DSO *dso = NULL; + conf_init_func *ifunc; + conf_finish_func *ffunc; + char *path = NULL; + int errcode = 0; + CONF_MODULE *md; + /* Look for alternative path in module section */ + path = NCONF_get_string(cnf, value, "path"); + if (!path) { + ERR_clear_error(); + path = name; + } + dso = DSO_load(NULL, path, NULL, 0); + if (!dso) { + errcode = CONF_R_ERROR_LOADING_DSO; + goto err; + } + ifunc = (conf_init_func *)DSO_bind_func(dso, DSO_mod_init_name); + if (!ifunc) { + errcode = CONF_R_MISSING_INIT_FUNCTION; + goto err; + } + ffunc = (conf_finish_func *)DSO_bind_func(dso, DSO_mod_finish_name); + /* All OK, add module */ + md = module_add(dso, name, ifunc, ffunc); + + if (!md) + goto err; + + return md; + + err: + if (dso) + DSO_free(dso); + CONFerr(CONF_F_MODULE_LOAD_DSO, errcode); + ERR_add_error_data(4, "module=", name, ", path=", path); + return NULL; +} + +/* add module to list */ +static CONF_MODULE *module_add(DSO *dso, const char *name, + conf_init_func *ifunc, conf_finish_func *ffunc) +{ + CONF_MODULE *tmod = NULL; + if (supported_modules == NULL) + supported_modules = sk_CONF_MODULE_new_null(); + if (supported_modules == NULL) + return NULL; + tmod = OPENSSL_malloc(sizeof(CONF_MODULE)); + if (tmod == NULL) + return NULL; + + tmod->dso = dso; + tmod->name = BUF_strdup(name); + tmod->init = ifunc; + tmod->finish = ffunc; + tmod->links = 0; + + if (!sk_CONF_MODULE_push(supported_modules, tmod)) { + OPENSSL_free(tmod); + return NULL; + } + + return tmod; +} + +/* + * Find a module from the list. We allow module names of the form + * modname.XXXX to just search for modname to allow the same module to be + * initialized more than once. + */ + +static CONF_MODULE *module_find(char *name) +{ + CONF_MODULE *tmod; + int i, nchar; + char *p; + p = strrchr(name, '.'); + + if (p) + nchar = p - name; + else + nchar = strlen(name); + + for (i = 0; i < sk_CONF_MODULE_num(supported_modules); i++) { + tmod = sk_CONF_MODULE_value(supported_modules, i); + if (!strncmp(tmod->name, name, nchar)) + return tmod; + } + + return NULL; + +} + +/* initialize a module */ +static int module_init(CONF_MODULE *pmod, char *name, char *value, + const CONF *cnf) +{ + int ret = 1; + int init_called = 0; + CONF_IMODULE *imod = NULL; + + /* Otherwise add initialized module to list */ + imod = OPENSSL_malloc(sizeof(CONF_IMODULE)); + if (!imod) + goto err; + + imod->pmod = pmod; + imod->name = BUF_strdup(name); + imod->value = BUF_strdup(value); + imod->usr_data = NULL; + + if (!imod->name || !imod->value) + goto memerr; + + /* Try to initialize module */ + if (pmod->init) { + ret = pmod->init(imod, cnf); + init_called = 1; + /* Error occurred, exit */ + if (ret <= 0) + goto err; + } + + if (initialized_modules == NULL) { + initialized_modules = sk_CONF_IMODULE_new_null(); + if (!initialized_modules) { + CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (!sk_CONF_IMODULE_push(initialized_modules, imod)) { + CONFerr(CONF_F_MODULE_INIT, ERR_R_MALLOC_FAILURE); + goto err; + } + + pmod->links++; + + return ret; + + err: + + /* We've started the module so we'd better finish it */ + if (pmod->finish && init_called) + pmod->finish(imod); + + memerr: + if (imod) { + if (imod->name) + OPENSSL_free(imod->name); + if (imod->value) + OPENSSL_free(imod->value); + OPENSSL_free(imod); + } + + return -1; + +} + +/* + * Unload any dynamic modules that have a link count of zero: i.e. have no + * active initialized modules. If 'all' is set then all modules are unloaded + * including static ones. + */ + +void CONF_modules_unload(int all) +{ + int i; + CONF_MODULE *md; + CONF_modules_finish(); + /* unload modules in reverse order */ + for (i = sk_CONF_MODULE_num(supported_modules) - 1; i >= 0; i--) { + md = sk_CONF_MODULE_value(supported_modules, i); + /* If static or in use and 'all' not set ignore it */ + if (((md->links > 0) || !md->dso) && !all) + continue; + /* Since we're working in reverse this is OK */ + (void)sk_CONF_MODULE_delete(supported_modules, i); + module_free(md); + } + if (sk_CONF_MODULE_num(supported_modules) == 0) { + sk_CONF_MODULE_free(supported_modules); + supported_modules = NULL; + } +} + +/* unload a single module */ +static void module_free(CONF_MODULE *md) +{ + if (md->dso) + DSO_free(md->dso); + OPENSSL_free(md->name); + OPENSSL_free(md); +} + +/* finish and free up all modules instances */ + +void CONF_modules_finish(void) +{ + CONF_IMODULE *imod; + while (sk_CONF_IMODULE_num(initialized_modules) > 0) { + imod = sk_CONF_IMODULE_pop(initialized_modules); + module_finish(imod); + } + sk_CONF_IMODULE_free(initialized_modules); + initialized_modules = NULL; +} + +/* finish a module instance */ + +static void module_finish(CONF_IMODULE *imod) +{ + if (imod->pmod->finish) + imod->pmod->finish(imod); + imod->pmod->links--; + OPENSSL_free(imod->name); + OPENSSL_free(imod->value); + OPENSSL_free(imod); +} + +/* Add a static module to OpenSSL */ + +int CONF_module_add(const char *name, conf_init_func *ifunc, + conf_finish_func *ffunc) +{ + if (module_add(NULL, name, ifunc, ffunc)) + return 1; + else + return 0; +} + +void CONF_modules_free(void) +{ + CONF_modules_finish(); + CONF_modules_unload(1); +} + +/* Utility functions */ + +const char *CONF_imodule_get_name(const CONF_IMODULE *md) +{ + return md->name; +} + +const char *CONF_imodule_get_value(const CONF_IMODULE *md) +{ + return md->value; +} + +void *CONF_imodule_get_usr_data(const CONF_IMODULE *md) +{ + return md->usr_data; +} + +void CONF_imodule_set_usr_data(CONF_IMODULE *md, void *usr_data) +{ + md->usr_data = usr_data; +} + +CONF_MODULE *CONF_imodule_get_module(const CONF_IMODULE *md) +{ + return md->pmod; +} + +unsigned long CONF_imodule_get_flags(const CONF_IMODULE *md) +{ + return md->flags; +} + +void CONF_imodule_set_flags(CONF_IMODULE *md, unsigned long flags) +{ + md->flags = flags; +} + +void *CONF_module_get_usr_data(CONF_MODULE *pmod) +{ + return pmod->usr_data; +} + +void CONF_module_set_usr_data(CONF_MODULE *pmod, void *usr_data) +{ + pmod->usr_data = usr_data; +} + +/* Return default config file name */ + +char *CONF_get1_default_config_file(void) +{ + char *file; + int len; + + file = getenv("OPENSSL_CONF"); + if (file) + return BUF_strdup(file); + + len = strlen(X509_get_default_cert_area()); +#ifndef OPENSSL_SYS_VMS + len++; +#endif + len += strlen(OPENSSL_CONF); + + file = OPENSSL_malloc(len + 1); + + if (!file) + return NULL; + BUF_strlcpy(file, X509_get_default_cert_area(), len + 1); +#ifndef OPENSSL_SYS_VMS + BUF_strlcat(file, "/", len + 1); +#endif + BUF_strlcat(file, OPENSSL_CONF, len + 1); + + return file; +} + +/* + * This function takes a list separated by 'sep' and calls the callback + * function giving the start and length of each member optionally stripping + * leading and trailing whitespace. This can be used to parse comma separated + * lists for example. + */ + +int CONF_parse_list(const char *list_, int sep, int nospc, + int (*list_cb) (const char *elem, int len, void *usr), + void *arg) +{ + int ret; + const char *lstart, *tmpend, *p; + + if (list_ == NULL) { + CONFerr(CONF_F_CONF_PARSE_LIST, CONF_R_LIST_CANNOT_BE_NULL); + return 0; + } + + lstart = list_; + for (;;) { + if (nospc) { + while (*lstart && isspace((unsigned char)*lstart)) + lstart++; + } + p = strchr(lstart, sep); + if (p == lstart || !*lstart) + ret = list_cb(NULL, 0, arg); + else { + if (p) + tmpend = p - 1; + else + tmpend = lstart + strlen(lstart) - 1; + if (nospc) { + while (isspace((unsigned char)*tmpend)) + tmpend--; + } + ret = list_cb(lstart, tmpend - lstart + 1, arg); + } + if (ret <= 0) + return ret; + if (p == NULL) + return 1; + lstart = p + 1; + } +} diff --git a/libs/openssl/crypto/conf/conf_sap.c b/libs/openssl/crypto/conf/conf_sap.c new file mode 100644 index 00000000..c042cf22 --- /dev/null +++ b/libs/openssl/crypto/conf/conf_sap.c @@ -0,0 +1,99 @@ +/* conf_sap.c */ +/* + * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif + +/* + * This is the automatic configuration loader: it is called automatically by + * OpenSSL when any of a number of standard initialisation functions are + * called, unless this is overridden by calling OPENSSL_no_config() + */ + +static int openssl_configured = 0; + +void OPENSSL_config(const char *config_name) +{ + if (openssl_configured) + return; + + OPENSSL_load_builtin_modules(); +#ifndef OPENSSL_NO_ENGINE + /* Need to load ENGINEs */ + ENGINE_load_builtin_engines(); +#endif + ERR_clear_error(); + CONF_modules_load_file(NULL, config_name, + CONF_MFLAGS_DEFAULT_SECTION | + CONF_MFLAGS_IGNORE_MISSING_FILE); + openssl_configured = 1; +} + +void OPENSSL_no_config() +{ + openssl_configured = 1; +} diff --git a/libs/openssl/crypto/conf/keysets.pl b/libs/openssl/crypto/conf/keysets.pl new file mode 100644 index 00000000..50ed67fa --- /dev/null +++ b/libs/openssl/crypto/conf/keysets.pl @@ -0,0 +1,185 @@ +#!/usr/local/bin/perl + +$NUMBER=0x01; +$UPPER=0x02; +$LOWER=0x04; +$UNDER=0x100; +$PUNCTUATION=0x200; +$WS=0x10; +$ESC=0x20; +$QUOTE=0x40; +$DQUOTE=0x400; +$COMMENT=0x80; +$FCOMMENT=0x800; +$EOF=0x08; +$HIGHBIT=0x1000; + +foreach (0 .. 255) + { + $v=0; + $c=sprintf("%c",$_); + $v|=$NUMBER if ($c =~ /[0-9]/); + $v|=$UPPER if ($c =~ /[A-Z]/); + $v|=$LOWER if ($c =~ /[a-z]/); + $v|=$UNDER if ($c =~ /_/); + $v|=$PUNCTUATION if ($c =~ /[!\.%&\*\+,\/;\?\@\^\~\|-]/); + $v|=$WS if ($c =~ /[ \t\r\n]/); + $v|=$ESC if ($c =~ /\\/); + $v|=$QUOTE if ($c =~ /['`"]/); # for emacs: "`'}/) + $v|=$COMMENT if ($c =~ /\#/); + $v|=$EOF if ($c =~ /\0/); + $v|=$HIGHBIT if ($c =~/[\x80-\xff]/); + + push(@V_def,$v); + } + +foreach (0 .. 255) + { + $v=0; + $c=sprintf("%c",$_); + $v|=$NUMBER if ($c =~ /[0-9]/); + $v|=$UPPER if ($c =~ /[A-Z]/); + $v|=$LOWER if ($c =~ /[a-z]/); + $v|=$UNDER if ($c =~ /_/); + $v|=$PUNCTUATION if ($c =~ /[!\.%&\*\+,\/;\?\@\^\~\|-]/); + $v|=$WS if ($c =~ /[ \t\r\n]/); + $v|=$DQUOTE if ($c =~ /["]/); # for emacs: "}/) + $v|=$FCOMMENT if ($c =~ /;/); + $v|=$EOF if ($c =~ /\0/); + $v|=$HIGHBIT if ($c =~/[\x80-\xff]/); + + push(@V_w32,$v); + } + +print <<"EOF"; +/* crypto/conf/conf_def.h */ +/* Copyright (C) 1995-1998 Eric Young (eay\@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay\@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh\@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay\@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh\@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* THIS FILE WAS AUTOMAGICALLY GENERATED! + Please modify and use keysets.pl to regenerate it. */ + +#define CONF_NUMBER $NUMBER +#define CONF_UPPER $UPPER +#define CONF_LOWER $LOWER +#define CONF_UNDER $UNDER +#define CONF_PUNCTUATION $PUNCTUATION +#define CONF_WS $WS +#define CONF_ESC $ESC +#define CONF_QUOTE $QUOTE +#define CONF_DQUOTE $DQUOTE +#define CONF_COMMENT $COMMENT +#define CONF_FCOMMENT $FCOMMENT +#define CONF_EOF $EOF +#define CONF_HIGHBIT $HIGHBIT +#define CONF_ALPHA (CONF_UPPER|CONF_LOWER) +#define CONF_ALPHA_NUMERIC (CONF_ALPHA|CONF_NUMBER|CONF_UNDER) +#define CONF_ALPHA_NUMERIC_PUNCT (CONF_ALPHA|CONF_NUMBER|CONF_UNDER| \\ + CONF_PUNCTUATION) + +#define KEYTYPES(c) ((unsigned short *)((c)->meth_data)) +#ifndef CHARSET_EBCDIC +#define IS_COMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_COMMENT) +#define IS_FCOMMENT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_FCOMMENT) +#define IS_EOF(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_EOF) +#define IS_ESC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ESC) +#define IS_NUMBER(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_NUMBER) +#define IS_WS(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_WS) +#define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC) +#define IS_ALPHA_NUMERIC_PUNCT(c,a) \\ + (KEYTYPES(c)[(a)&0xff]&CONF_ALPHA_NUMERIC_PUNCT) +#define IS_QUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_QUOTE) +#define IS_DQUOTE(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_DQUOTE) +#define IS_HIGHBIT(c,a) (KEYTYPES(c)[(a)&0xff]&CONF_HIGHBIT) + +#else /*CHARSET_EBCDIC*/ + +#define IS_COMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_COMMENT) +#define IS_FCOMMENT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_FCOMMENT) +#define IS_EOF(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_EOF) +#define IS_ESC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ESC) +#define IS_NUMBER(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_NUMBER) +#define IS_WS(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_WS) +#define IS_ALPHA_NUMERIC(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC) +#define IS_ALPHA_NUMERIC_PUNCT(c,a) \\ + (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_ALPHA_NUMERIC_PUNCT) +#define IS_QUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_QUOTE) +#define IS_DQUOTE(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_DQUOTE) +#define IS_HIGHBIT(c,a) (KEYTYPES(c)[os_toascii[a]&0xff]&CONF_HIGHBIT) +#endif /*CHARSET_EBCDIC*/ + +EOF + +print "static unsigned short CONF_type_default[256]={"; + +for ($i=0; $i<256; $i++) + { + print "\n\t" if ($i % 8) == 0; + printf "0x%04X,",$V_def[$i]; + } + +print "\n\t};\n\n"; + +print "static unsigned short CONF_type_win32[256]={"; + +for ($i=0; $i<256; $i++) + { + print "\n\t" if ($i % 8) == 0; + printf "0x%04X,",$V_w32[$i]; + } + +print "\n\t};\n\n"; diff --git a/libs/openssl/crypto/conf/ssleay.cnf b/libs/openssl/crypto/conf/ssleay.cnf new file mode 100644 index 00000000..ed33af60 --- /dev/null +++ b/libs/openssl/crypto/conf/ssleay.cnf @@ -0,0 +1,78 @@ +# +# This is a test configuration file for use in SSLeay etc... +# + +init = 5 +in\#it1 =10 +init2='10' +init3='10\'' +init4="10'" +init5='='10\'' again' + +SSLeay::version = 0.5.0 + +[genrsa] +default_bits = 512 +SSLEAY::version = 0.5.0 + +[gendh] +default_bits = 512 +def_generator = 2 + +[s_client] +cipher1 = DES_CBC_MD5:DES_CBC_SHA:DES_EDE_SHA:RC4_MD5\ +cipher2 = 'DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5' +cipher3 = "DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5" +cipher4 = DES_CBC_MD5 DES_CBC_SHA DES_EDE_SHA RC4_MD5 + +[ default ] +cert_dir = $ENV::HOME/.ca_certs + +HOME = /tmp/eay + +tmp_cert_dir = $HOME/.ca_certs +tmp2_cert_dir = thisis$(HOME)stuff + +LOGNAME = Eric Young (home=$HOME) + +[ special ] + +H=$HOME +H=$default::HOME +H=$ENV::HOME +# +# SSLeay example configuration file. +# This is mostly being used for generation of certificate requests. +# + +RANDFILE = $HOME/.rand + +[ req ] +default_bits = 512 +default_keyfile = privkey.pem + +Attribute_type_1 = countryName +Attribute_text_1 = Country Name (2 letter code) +Attribute_default_1 = AU + +Attribute_type_2 = stateOrProvinceName +Attribute_text_2 = State or Province Name (full name) +Attribute_default_2 = Queensland + +Attribute_type_3 = localityName +Attribute_text_3 = Locality Name (eg, city) + +Attribute_type_4 = organizationName +Attribute_text_4 = Organization Name (eg, company) +Attribute_default_4 = Mincom Pty Ltd + +Attribute_type_5 = organizationalUnitName +Attribute_text_5 = Organizational Unit Name (eg, section) +Attribute_default_5 = TR + +Attribute_type_6 = commonName +Attribute_text_6 = Common Name (eg, YOUR name) + +Attribute_type_7 = emailAddress +Attribute_text_7 = Email Address + diff --git a/libs/openssl/crypto/conf/test.c b/libs/openssl/crypto/conf/test.c new file mode 100644 index 00000000..cc1efcca --- /dev/null +++ b/libs/openssl/crypto/conf/test.c @@ -0,0 +1,97 @@ +/* crypto/conf/test.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +main() +{ + LHASH *conf; + long eline; + char *s, *s2; + +#ifdef USE_WIN32 + CONF_set_default_method(CONF_WIN32); +#endif + conf = CONF_load(NULL, "ssleay.cnf", &eline); + if (conf == NULL) { + ERR_load_crypto_strings(); + printf("unable to load configuration, line %ld\n", eline); + ERR_print_errors_fp(stderr); + exit(1); + } + lh_stats(conf, stdout); + lh_node_stats(conf, stdout); + lh_node_usage_stats(conf, stdout); + + s = CONF_get_string(conf, NULL, "init2"); + printf("init2=%s\n", (s == NULL) ? "NULL" : s); + + s = CONF_get_string(conf, NULL, "cipher1"); + printf("cipher1=%s\n", (s == NULL) ? "NULL" : s); + + s = CONF_get_string(conf, "s_client", "cipher1"); + printf("s_client:cipher1=%s\n", (s == NULL) ? "NULL" : s); + + printf("---------------------------- DUMP ------------------------\n"); + CONF_dump_fp(conf, stdout); + + exit(0); +} diff --git a/libs/openssl/crypto/constant_time_locl.h b/libs/openssl/crypto/constant_time_locl.h new file mode 100644 index 00000000..c786aea9 --- /dev/null +++ b/libs/openssl/crypto/constant_time_locl.h @@ -0,0 +1,211 @@ +/* crypto/constant_time_locl.h */ +/*- + * Utilities for constant-time cryptography. + * + * Author: Emilia Kasper (emilia@openssl.org) + * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley + * (Google). + * ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CONSTANT_TIME_LOCL_H +# define HEADER_CONSTANT_TIME_LOCL_H + +# include "e_os.h" /* For 'inline' */ + +#ifdef __cplusplus +extern "C" { +#endif + +/*- + * The boolean methods return a bitmask of all ones (0xff...f) for true + * and 0 for false. This is useful for choosing a value based on the result + * of a conditional in constant time. For example, + * + * if (a < b) { + * c = a; + * } else { + * c = b; + * } + * + * can be written as + * + * unsigned int lt = constant_time_lt(a, b); + * c = constant_time_select(lt, a, b); + */ + +/* + * Returns the given value with the MSB copied to all the other + * bits. Uses the fact that arithmetic shift shifts-in the sign bit. + * However, this is not ensured by the C standard so you may need to + * replace this with something else on odd CPUs. + */ +static inline unsigned int constant_time_msb(unsigned int a); + +/* + * Returns 0xff..f if a < b and 0 otherwise. + */ +static inline unsigned int constant_time_lt(unsigned int a, unsigned int b); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_lt_8(unsigned int a, + unsigned int b); + +/* + * Returns 0xff..f if a >= b and 0 otherwise. + */ +static inline unsigned int constant_time_ge(unsigned int a, unsigned int b); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_ge_8(unsigned int a, + unsigned int b); + +/* + * Returns 0xff..f if a == 0 and 0 otherwise. + */ +static inline unsigned int constant_time_is_zero(unsigned int a); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_is_zero_8(unsigned int a); + +/* + * Returns 0xff..f if a == b and 0 otherwise. + */ +static inline unsigned int constant_time_eq(unsigned int a, unsigned int b); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_eq_8(unsigned int a, + unsigned int b); +/* Signed integers. */ +static inline unsigned int constant_time_eq_int(int a, int b); +/* Convenience method for getting an 8-bit mask. */ +static inline unsigned char constant_time_eq_int_8(int a, int b); + +/*- + * Returns (mask & a) | (~mask & b). + * + * When |mask| is all 1s or all 0s (as returned by the methods above), + * the select methods return either |a| (if |mask| is nonzero) or |b| + * (if |mask| is zero). + */ +static inline unsigned int constant_time_select(unsigned int mask, + unsigned int a, + unsigned int b); +/* Convenience method for unsigned chars. */ +static inline unsigned char constant_time_select_8(unsigned char mask, + unsigned char a, + unsigned char b); +/* Convenience method for signed integers. */ +static inline int constant_time_select_int(unsigned int mask, int a, int b); + +static inline unsigned int constant_time_msb(unsigned int a) +{ + return 0 - (a >> (sizeof(a) * 8 - 1)); +} + +static inline unsigned int constant_time_lt(unsigned int a, unsigned int b) +{ + return constant_time_msb(a ^ ((a ^ b) | ((a - b) ^ b))); +} + +static inline unsigned char constant_time_lt_8(unsigned int a, unsigned int b) +{ + return (unsigned char)(constant_time_lt(a, b)); +} + +static inline unsigned int constant_time_ge(unsigned int a, unsigned int b) +{ + return ~constant_time_lt(a, b); +} + +static inline unsigned char constant_time_ge_8(unsigned int a, unsigned int b) +{ + return (unsigned char)(constant_time_ge(a, b)); +} + +static inline unsigned int constant_time_is_zero(unsigned int a) +{ + return constant_time_msb(~a & (a - 1)); +} + +static inline unsigned char constant_time_is_zero_8(unsigned int a) +{ + return (unsigned char)(constant_time_is_zero(a)); +} + +static inline unsigned int constant_time_eq(unsigned int a, unsigned int b) +{ + return constant_time_is_zero(a ^ b); +} + +static inline unsigned char constant_time_eq_8(unsigned int a, unsigned int b) +{ + return (unsigned char)(constant_time_eq(a, b)); +} + +static inline unsigned int constant_time_eq_int(int a, int b) +{ + return constant_time_eq((unsigned)(a), (unsigned)(b)); +} + +static inline unsigned char constant_time_eq_int_8(int a, int b) +{ + return constant_time_eq_8((unsigned)(a), (unsigned)(b)); +} + +static inline unsigned int constant_time_select(unsigned int mask, + unsigned int a, + unsigned int b) +{ + return (mask & a) | (~mask & b); +} + +static inline unsigned char constant_time_select_8(unsigned char mask, + unsigned char a, + unsigned char b) +{ + return (unsigned char)(constant_time_select(mask, a, b)); +} + +static inline int constant_time_select_int(unsigned int mask, int a, int b) +{ + return (int)(constant_time_select(mask, (unsigned)(a), (unsigned)(b))); +} + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_CONSTANT_TIME_LOCL_H */ diff --git a/libs/openssl/crypto/constant_time_test.c b/libs/openssl/crypto/constant_time_test.c new file mode 100644 index 00000000..d313d0c7 --- /dev/null +++ b/libs/openssl/crypto/constant_time_test.c @@ -0,0 +1,304 @@ +/* crypto/constant_time_test.c */ +/*- + * Utilities for constant-time cryptography. + * + * Author: Emilia Kasper (emilia@openssl.org) + * Based on previous work by Bodo Moeller, Emilia Kasper, Adam Langley + * (Google). + * ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "../crypto/constant_time_locl.h" + +#include +#include +#include + +static const unsigned int CONSTTIME_TRUE = (unsigned)(~0); +static const unsigned int CONSTTIME_FALSE = 0; +static const unsigned char CONSTTIME_TRUE_8 = 0xff; +static const unsigned char CONSTTIME_FALSE_8 = 0; + +static int test_binary_op(unsigned int (*op) (unsigned int a, unsigned int b), + const char *op_name, unsigned int a, unsigned int b, + int is_true) +{ + unsigned c = op(a, b); + if (is_true && c != CONSTTIME_TRUE) { + fprintf(stderr, "Test failed for %s(%du, %du): expected %du " + "(TRUE), got %du\n", op_name, a, b, CONSTTIME_TRUE, c); + return 1; + } else if (!is_true && c != CONSTTIME_FALSE) { + fprintf(stderr, "Test failed for %s(%du, %du): expected %du " + "(FALSE), got %du\n", op_name, a, b, CONSTTIME_FALSE, c); + return 1; + } + return 0; +} + +static int test_binary_op_8(unsigned + char (*op) (unsigned int a, unsigned int b), + const char *op_name, unsigned int a, + unsigned int b, int is_true) +{ + unsigned char c = op(a, b); + if (is_true && c != CONSTTIME_TRUE_8) { + fprintf(stderr, "Test failed for %s(%du, %du): expected %u " + "(TRUE), got %u\n", op_name, a, b, CONSTTIME_TRUE_8, c); + return 1; + } else if (!is_true && c != CONSTTIME_FALSE_8) { + fprintf(stderr, "Test failed for %s(%du, %du): expected %u " + "(FALSE), got %u\n", op_name, a, b, CONSTTIME_FALSE_8, c); + return 1; + } + return 0; +} + +static int test_is_zero(unsigned int a) +{ + unsigned int c = constant_time_is_zero(a); + if (a == 0 && c != CONSTTIME_TRUE) { + fprintf(stderr, "Test failed for constant_time_is_zero(%du): " + "expected %du (TRUE), got %du\n", a, CONSTTIME_TRUE, c); + return 1; + } else if (a != 0 && c != CONSTTIME_FALSE) { + fprintf(stderr, "Test failed for constant_time_is_zero(%du): " + "expected %du (FALSE), got %du\n", a, CONSTTIME_FALSE, c); + return 1; + } + return 0; +} + +static int test_is_zero_8(unsigned int a) +{ + unsigned char c = constant_time_is_zero_8(a); + if (a == 0 && c != CONSTTIME_TRUE_8) { + fprintf(stderr, "Test failed for constant_time_is_zero(%du): " + "expected %u (TRUE), got %u\n", a, CONSTTIME_TRUE_8, c); + return 1; + } else if (a != 0 && c != CONSTTIME_FALSE) { + fprintf(stderr, "Test failed for constant_time_is_zero(%du): " + "expected %u (FALSE), got %u\n", a, CONSTTIME_FALSE_8, c); + return 1; + } + return 0; +} + +static int test_select(unsigned int a, unsigned int b) +{ + unsigned int selected = constant_time_select(CONSTTIME_TRUE, a, b); + if (selected != a) { + fprintf(stderr, "Test failed for constant_time_select(%du, %du," + "%du): expected %du(first value), got %du\n", + CONSTTIME_TRUE, a, b, a, selected); + return 1; + } + selected = constant_time_select(CONSTTIME_FALSE, a, b); + if (selected != b) { + fprintf(stderr, "Test failed for constant_time_select(%du, %du," + "%du): expected %du(second value), got %du\n", + CONSTTIME_FALSE, a, b, b, selected); + return 1; + } + return 0; +} + +static int test_select_8(unsigned char a, unsigned char b) +{ + unsigned char selected = constant_time_select_8(CONSTTIME_TRUE_8, a, b); + if (selected != a) { + fprintf(stderr, "Test failed for constant_time_select(%u, %u," + "%u): expected %u(first value), got %u\n", + CONSTTIME_TRUE, a, b, a, selected); + return 1; + } + selected = constant_time_select_8(CONSTTIME_FALSE_8, a, b); + if (selected != b) { + fprintf(stderr, "Test failed for constant_time_select(%u, %u," + "%u): expected %u(second value), got %u\n", + CONSTTIME_FALSE, a, b, b, selected); + return 1; + } + return 0; +} + +static int test_select_int(int a, int b) +{ + int selected = constant_time_select_int(CONSTTIME_TRUE, a, b); + if (selected != a) { + fprintf(stderr, "Test failed for constant_time_select(%du, %d," + "%d): expected %d(first value), got %d\n", + CONSTTIME_TRUE, a, b, a, selected); + return 1; + } + selected = constant_time_select_int(CONSTTIME_FALSE, a, b); + if (selected != b) { + fprintf(stderr, "Test failed for constant_time_select(%du, %d," + "%d): expected %d(second value), got %d\n", + CONSTTIME_FALSE, a, b, b, selected); + return 1; + } + return 0; +} + +static int test_eq_int(int a, int b) +{ + unsigned int equal = constant_time_eq_int(a, b); + if (a == b && equal != CONSTTIME_TRUE) { + fprintf(stderr, "Test failed for constant_time_eq_int(%d, %d): " + "expected %du(TRUE), got %du\n", a, b, CONSTTIME_TRUE, equal); + return 1; + } else if (a != b && equal != CONSTTIME_FALSE) { + fprintf(stderr, "Test failed for constant_time_eq_int(%d, %d): " + "expected %du(FALSE), got %du\n", + a, b, CONSTTIME_FALSE, equal); + return 1; + } + return 0; +} + +static int test_eq_int_8(int a, int b) +{ + unsigned char equal = constant_time_eq_int_8(a, b); + if (a == b && equal != CONSTTIME_TRUE_8) { + fprintf(stderr, "Test failed for constant_time_eq_int_8(%d, %d): " + "expected %u(TRUE), got %u\n", a, b, CONSTTIME_TRUE_8, equal); + return 1; + } else if (a != b && equal != CONSTTIME_FALSE_8) { + fprintf(stderr, "Test failed for constant_time_eq_int_8(%d, %d): " + "expected %u(FALSE), got %u\n", + a, b, CONSTTIME_FALSE_8, equal); + return 1; + } + return 0; +} + +static unsigned int test_values[] = + { 0, 1, 1024, 12345, 32000, UINT_MAX / 2 - 1, + UINT_MAX / 2, UINT_MAX / 2 + 1, UINT_MAX - 1, + UINT_MAX +}; + +static unsigned char test_values_8[] = + { 0, 1, 2, 20, 32, 127, 128, 129, 255 }; + +static int signed_test_values[] = { 0, 1, -1, 1024, -1024, 12345, -12345, + 32000, -32000, INT_MAX, INT_MIN, INT_MAX - 1, + INT_MIN + 1 +}; + +int main(int argc, char *argv[]) +{ + unsigned int a, b, i, j; + int c, d; + unsigned char e, f; + int num_failed = 0, num_all = 0; + fprintf(stdout, "Testing constant time operations...\n"); + + for (i = 0; i < sizeof(test_values) / sizeof(int); ++i) { + a = test_values[i]; + num_failed += test_is_zero(a); + num_failed += test_is_zero_8(a); + num_all += 2; + for (j = 0; j < sizeof(test_values) / sizeof(int); ++j) { + b = test_values[j]; + num_failed += test_binary_op(&constant_time_lt, + "constant_time_lt", a, b, a < b); + num_failed += test_binary_op_8(&constant_time_lt_8, + "constant_time_lt_8", a, b, a < b); + num_failed += test_binary_op(&constant_time_lt, + "constant_time_lt_8", b, a, b < a); + num_failed += test_binary_op_8(&constant_time_lt_8, + "constant_time_lt_8", b, a, b < a); + num_failed += test_binary_op(&constant_time_ge, + "constant_time_ge", a, b, a >= b); + num_failed += test_binary_op_8(&constant_time_ge_8, + "constant_time_ge_8", a, b, + a >= b); + num_failed += + test_binary_op(&constant_time_ge, "constant_time_ge", b, a, + b >= a); + num_failed += + test_binary_op_8(&constant_time_ge_8, "constant_time_ge_8", b, + a, b >= a); + num_failed += + test_binary_op(&constant_time_eq, "constant_time_eq", a, b, + a == b); + num_failed += + test_binary_op_8(&constant_time_eq_8, "constant_time_eq_8", a, + b, a == b); + num_failed += + test_binary_op(&constant_time_eq, "constant_time_eq", b, a, + b == a); + num_failed += + test_binary_op_8(&constant_time_eq_8, "constant_time_eq_8", b, + a, b == a); + num_failed += test_select(a, b); + num_all += 13; + } + } + + for (i = 0; i < sizeof(signed_test_values) / sizeof(int); ++i) { + c = signed_test_values[i]; + for (j = 0; j < sizeof(signed_test_values) / sizeof(int); ++j) { + d = signed_test_values[j]; + num_failed += test_select_int(c, d); + num_failed += test_eq_int(c, d); + num_failed += test_eq_int_8(c, d); + num_all += 3; + } + } + + for (i = 0; i < sizeof(test_values_8); ++i) { + e = test_values_8[i]; + for (j = 0; j < sizeof(test_values_8); ++j) { + f = test_values_8[j]; + num_failed += test_select_8(e, f); + num_all += 1; + } + } + + if (!num_failed) { + fprintf(stdout, "ok (ran %d tests)\n", num_all); + return EXIT_SUCCESS; + } else { + fprintf(stdout, "%d of %d tests failed!\n", num_failed, num_all); + return EXIT_FAILURE; + } +} diff --git a/libs/openssl/crypto/cpt_err.c b/libs/openssl/crypto/cpt_err.c new file mode 100644 index 00000000..a5138381 --- /dev/null +++ b/libs/openssl/crypto/cpt_err.c @@ -0,0 +1,104 @@ +/* crypto/cpt_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_CRYPTO,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_CRYPTO,0,reason) + +static ERR_STRING_DATA CRYPTO_str_functs[] = { + {ERR_FUNC(CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX), "CRYPTO_get_ex_new_index"}, + {ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID), "CRYPTO_get_new_dynlockid"}, + {ERR_FUNC(CRYPTO_F_CRYPTO_GET_NEW_LOCKID), "CRYPTO_get_new_lockid"}, + {ERR_FUNC(CRYPTO_F_CRYPTO_SET_EX_DATA), "CRYPTO_set_ex_data"}, + {ERR_FUNC(CRYPTO_F_DEF_ADD_INDEX), "DEF_ADD_INDEX"}, + {ERR_FUNC(CRYPTO_F_DEF_GET_CLASS), "DEF_GET_CLASS"}, + {ERR_FUNC(CRYPTO_F_FIPS_MODE_SET), "FIPS_mode_set"}, + {ERR_FUNC(CRYPTO_F_INT_DUP_EX_DATA), "INT_DUP_EX_DATA"}, + {ERR_FUNC(CRYPTO_F_INT_FREE_EX_DATA), "INT_FREE_EX_DATA"}, + {ERR_FUNC(CRYPTO_F_INT_NEW_EX_DATA), "INT_NEW_EX_DATA"}, + {0, NULL} +}; + +static ERR_STRING_DATA CRYPTO_str_reasons[] = { + {ERR_REASON(CRYPTO_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"}, + {ERR_REASON(CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK), + "no dynlock create callback"}, + {0, NULL} +}; + +#endif + +void ERR_load_CRYPTO_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(CRYPTO_str_functs[0].error) == NULL) { + ERR_load_strings(0, CRYPTO_str_functs); + ERR_load_strings(0, CRYPTO_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/cryptlib.c b/libs/openssl/crypto/cryptlib.c new file mode 100644 index 00000000..eccee723 --- /dev/null +++ b/libs/openssl/crypto/cryptlib.c @@ -0,0 +1,1005 @@ +/* crypto/cryptlib.c */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include "cryptlib.h" +#include + +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) +static double SSLeay_MSVC5_hack = 0.0; /* and for VC1.5 */ +#endif + +DECLARE_STACK_OF(CRYPTO_dynlock) + +/* real #defines in crypto.h, keep these upto date */ +static const char *const lock_names[CRYPTO_NUM_LOCKS] = { + "<>", + "err", + "ex_data", + "x509", + "x509_info", + "x509_pkey", + "x509_crl", + "x509_req", + "dsa", + "rsa", + "evp_pkey", + "x509_store", + "ssl_ctx", + "ssl_cert", + "ssl_session", + "ssl_sess_cert", + "ssl", + "ssl_method", + "rand", + "rand2", + "debug_malloc", + "BIO", + "gethostbyname", + "getservbyname", + "readdir", + "RSA_blinding", + "dh", + "debug_malloc2", + "dso", + "dynlock", + "engine", + "ui", + "ecdsa", + "ec", + "ecdh", + "bn", + "ec_pre_comp", + "store", + "comp", + "fips", + "fips2", +#if CRYPTO_NUM_LOCKS != 41 +# error "Inconsistency between crypto.h and cryptlib.c" +#endif +}; + +/* + * This is for applications to allocate new type names in the non-dynamic + * array of lock names. These are numbered with positive numbers. + */ +static STACK_OF(OPENSSL_STRING) *app_locks = NULL; + +/* + * For applications that want a more dynamic way of handling threads, the + * following stack is used. These are externally numbered with negative + * numbers. + */ +static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL; + +static void (MS_FAR *locking_callback) (int mode, int type, + const char *file, int line) = 0; +static int (MS_FAR *add_lock_callback) (int *pointer, int amount, + int type, const char *file, + int line) = 0; +#ifndef OPENSSL_NO_DEPRECATED +static unsigned long (MS_FAR *id_callback) (void) = 0; +#endif +static void (MS_FAR *threadid_callback) (CRYPTO_THREADID *) = 0; +static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback) + (const char *file, int line) = 0; +static void (MS_FAR *dynlock_lock_callback) (int mode, + struct CRYPTO_dynlock_value *l, + const char *file, int line) = 0; +static void (MS_FAR *dynlock_destroy_callback) (struct CRYPTO_dynlock_value + *l, const char *file, + int line) = 0; + +int CRYPTO_get_new_lockid(char *name) +{ + char *str; + int i; + +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) + /* + * A hack to make Visual C++ 5.0 work correctly when linking as a DLL + * using /MT. Without this, the application cannot use any floating point + * printf's. It also seems to be needed for Visual C 1.5 (win16) + */ + SSLeay_MSVC5_hack = (double)name[0] * (double)name[1]; +#endif + + if ((app_locks == NULL) + && ((app_locks = sk_OPENSSL_STRING_new_null()) == NULL)) { + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE); + return (0); + } + if ((str = BUF_strdup(name)) == NULL) { + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_LOCKID, ERR_R_MALLOC_FAILURE); + return (0); + } + i = sk_OPENSSL_STRING_push(app_locks, str); + if (!i) + OPENSSL_free(str); + else + i += CRYPTO_NUM_LOCKS; /* gap of one :-) */ + return (i); +} + +int CRYPTO_num_locks(void) +{ + return CRYPTO_NUM_LOCKS; +} + +int CRYPTO_get_new_dynlockid(void) +{ + int i = 0; + CRYPTO_dynlock *pointer = NULL; + + if (dynlock_create_callback == NULL) { + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, + CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK); + return (0); + } + CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + if ((dyn_locks == NULL) + && ((dyn_locks = sk_CRYPTO_dynlock_new_null()) == NULL)) { + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE); + return (0); + } + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + + pointer = (CRYPTO_dynlock *) OPENSSL_malloc(sizeof(CRYPTO_dynlock)); + if (pointer == NULL) { + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE); + return (0); + } + pointer->references = 1; + pointer->data = dynlock_create_callback(__FILE__, __LINE__); + if (pointer->data == NULL) { + OPENSSL_free(pointer); + CRYPTOerr(CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID, ERR_R_MALLOC_FAILURE); + return (0); + } + + CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + /* First, try to find an existing empty slot */ + i = sk_CRYPTO_dynlock_find(dyn_locks, NULL); + /* If there was none, push, thereby creating a new one */ + if (i == -1) + /* + * Since sk_push() returns the number of items on the stack, not the + * location of the pushed item, we need to transform the returned + * number into a position, by decreasing it. + */ + i = sk_CRYPTO_dynlock_push(dyn_locks, pointer) - 1; + else + /* + * If we found a place with a NULL pointer, put our pointer in it. + */ + (void)sk_CRYPTO_dynlock_set(dyn_locks, i, pointer); + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + + if (i == -1) { + dynlock_destroy_callback(pointer->data, __FILE__, __LINE__); + OPENSSL_free(pointer); + } else + i += 1; /* to avoid 0 */ + return -i; +} + +void CRYPTO_destroy_dynlockid(int i) +{ + CRYPTO_dynlock *pointer = NULL; + if (i) + i = -i - 1; + if (dynlock_destroy_callback == NULL) + return; + + CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + + if (dyn_locks == NULL || i >= sk_CRYPTO_dynlock_num(dyn_locks)) { + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + return; + } + pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); + if (pointer != NULL) { + --pointer->references; +#ifdef REF_CHECK + if (pointer->references < 0) { + fprintf(stderr, + "CRYPTO_destroy_dynlockid, bad reference count\n"); + abort(); + } else +#endif + if (pointer->references <= 0) { + (void)sk_CRYPTO_dynlock_set(dyn_locks, i, NULL); + } else + pointer = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + + if (pointer) { + dynlock_destroy_callback(pointer->data, __FILE__, __LINE__); + OPENSSL_free(pointer); + } +} + +struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i) +{ + CRYPTO_dynlock *pointer = NULL; + if (i) + i = -i - 1; + + CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + + if (dyn_locks != NULL && i < sk_CRYPTO_dynlock_num(dyn_locks)) + pointer = sk_CRYPTO_dynlock_value(dyn_locks, i); + if (pointer) + pointer->references++; + + CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + + if (pointer) + return pointer->data; + return NULL; +} + +struct CRYPTO_dynlock_value *(*CRYPTO_get_dynlock_create_callback(void)) + (const char *file, int line) { + return (dynlock_create_callback); +} + +void (*CRYPTO_get_dynlock_lock_callback(void)) (int mode, + struct CRYPTO_dynlock_value + *l, const char *file, + int line) { + return (dynlock_lock_callback); +} + +void (*CRYPTO_get_dynlock_destroy_callback(void)) + (struct CRYPTO_dynlock_value *l, const char *file, int line) { + return (dynlock_destroy_callback); +} + +void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func) + (const char *file, int line)) +{ + dynlock_create_callback = func; +} + +void CRYPTO_set_dynlock_lock_callback(void (*func) (int mode, + struct + CRYPTO_dynlock_value *l, + const char *file, + int line)) +{ + dynlock_lock_callback = func; +} + +void CRYPTO_set_dynlock_destroy_callback(void (*func) + (struct CRYPTO_dynlock_value *l, + const char *file, int line)) +{ + dynlock_destroy_callback = func; +} + +void (*CRYPTO_get_locking_callback(void)) (int mode, int type, + const char *file, int line) { + return (locking_callback); +} + +int (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type, + const char *file, int line) { + return (add_lock_callback); +} + +void CRYPTO_set_locking_callback(void (*func) (int mode, int type, + const char *file, int line)) +{ + /* + * Calling this here ensures initialisation before any threads are + * started. + */ + OPENSSL_init(); + locking_callback = func; +} + +void CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type, + const char *file, int line)) +{ + add_lock_callback = func; +} + +/* + * the memset() here and in set_pointer() seem overkill, but for the sake of + * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause + * two "equal" THREADID structs to not be memcmp()-identical. + */ +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) +{ + memset(id, 0, sizeof(*id)); + id->val = val; +} + +static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 }; + +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) +{ + unsigned char *dest = (void *)&id->val; + unsigned int accum = 0; + unsigned char dnum = sizeof(id->val); + + memset(id, 0, sizeof(*id)); + id->ptr = ptr; + if (sizeof(id->val) >= sizeof(id->ptr)) { + /* + * 'ptr' can be embedded in 'val' without loss of uniqueness + */ + id->val = (unsigned long)id->ptr; + return; + } + /* + * hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a + * linear function over the bytes in 'ptr', the co-efficients of which + * are a sequence of low-primes (hash_coeffs is an 8-element cycle) - the + * starting prime for the sequence varies for each byte of 'val' (unique + * polynomials unless pointers are >64-bit). For added spice, the totals + * accumulate rather than restarting from zero, and the index of the + * 'val' byte is added each time (position dependence). If I was a + * black-belt, I'd scan big-endian pointers in reverse to give low-order + * bits more play, but this isn't crypto and I'd prefer nobody mistake it + * as such. Plus I'm lazy. + */ + while (dnum--) { + const unsigned char *src = (void *)&id->ptr; + unsigned char snum = sizeof(id->ptr); + while (snum--) + accum += *(src++) * hash_coeffs[(snum + dnum) & 7]; + accum += dnum; + *(dest++) = accum & 255; + } +} + +int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *)) +{ + if (threadid_callback) + return 0; + threadid_callback = func; + return 1; +} + +void (*CRYPTO_THREADID_get_callback(void)) (CRYPTO_THREADID *) { + return threadid_callback; +} + +void CRYPTO_THREADID_current(CRYPTO_THREADID *id) +{ + if (threadid_callback) { + threadid_callback(id); + return; + } +#ifndef OPENSSL_NO_DEPRECATED + /* If the deprecated callback was set, fall back to that */ + if (id_callback) { + CRYPTO_THREADID_set_numeric(id, id_callback()); + return; + } +#endif + /* Else pick a backup */ +#ifdef OPENSSL_SYS_WIN16 + CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask()); +#elif defined(OPENSSL_SYS_WIN32) + CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId()); +#elif defined(OPENSSL_SYS_BEOS) + CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL)); +#else + /* For everything else, default to using the address of 'errno' */ + CRYPTO_THREADID_set_pointer(id, (void *)&errno); +#endif +} + +int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b) +{ + return memcmp(a, b, sizeof(*a)); +} + +void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src) +{ + memcpy(dest, src, sizeof(*src)); +} + +unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id) +{ + return id->val; +} + +#ifndef OPENSSL_NO_DEPRECATED +unsigned long (*CRYPTO_get_id_callback(void)) (void) { + return (id_callback); +} + +void CRYPTO_set_id_callback(unsigned long (*func) (void)) +{ + id_callback = func; +} + +unsigned long CRYPTO_thread_id(void) +{ + unsigned long ret = 0; + + if (id_callback == NULL) { +# ifdef OPENSSL_SYS_WIN16 + ret = (unsigned long)GetCurrentTask(); +# elif defined(OPENSSL_SYS_WIN32) + ret = (unsigned long)GetCurrentThreadId(); +# elif defined(GETPID_IS_MEANINGLESS) + ret = 1L; +# elif defined(OPENSSL_SYS_BEOS) + ret = (unsigned long)find_thread(NULL); +# else + ret = (unsigned long)getpid(); +# endif + } else + ret = id_callback(); + return (ret); +} +#endif + +void CRYPTO_lock(int mode, int type, const char *file, int line) +{ +#ifdef LOCK_DEBUG + { + CRYPTO_THREADID id; + char *rw_text, *operation_text; + + if (mode & CRYPTO_LOCK) + operation_text = "lock "; + else if (mode & CRYPTO_UNLOCK) + operation_text = "unlock"; + else + operation_text = "ERROR "; + + if (mode & CRYPTO_READ) + rw_text = "r"; + else if (mode & CRYPTO_WRITE) + rw_text = "w"; + else + rw_text = "ERROR"; + + CRYPTO_THREADID_current(&id); + fprintf(stderr, "lock:%08lx:(%s)%s %-18s %s:%d\n", + CRYPTO_THREADID_hash(&id), rw_text, operation_text, + CRYPTO_get_lock_name(type), file, line); + } +#endif + if (type < 0) { + if (dynlock_lock_callback != NULL) { + struct CRYPTO_dynlock_value *pointer + = CRYPTO_get_dynlock_value(type); + + OPENSSL_assert(pointer != NULL); + + dynlock_lock_callback(mode, pointer, file, line); + + CRYPTO_destroy_dynlockid(type); + } + } else if (locking_callback != NULL) + locking_callback(mode, type, file, line); +} + +int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, + int line) +{ + int ret = 0; + + if (add_lock_callback != NULL) { +#ifdef LOCK_DEBUG + int before = *pointer; +#endif + + ret = add_lock_callback(pointer, amount, type, file, line); +#ifdef LOCK_DEBUG + { + CRYPTO_THREADID id; + CRYPTO_THREADID_current(&id); + fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", + CRYPTO_THREADID_hash(&id), before, amount, ret, + CRYPTO_get_lock_name(type), file, line); + } +#endif + } else { + CRYPTO_lock(CRYPTO_LOCK | CRYPTO_WRITE, type, file, line); + + ret = *pointer + amount; +#ifdef LOCK_DEBUG + { + CRYPTO_THREADID id; + CRYPTO_THREADID_current(&id); + fprintf(stderr, "ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", + CRYPTO_THREADID_hash(&id), + *pointer, amount, ret, + CRYPTO_get_lock_name(type), file, line); + } +#endif + *pointer = ret; + CRYPTO_lock(CRYPTO_UNLOCK | CRYPTO_WRITE, type, file, line); + } + return (ret); +} + +const char *CRYPTO_get_lock_name(int type) +{ + if (type < 0) + return ("dynamic"); + else if (type < CRYPTO_NUM_LOCKS) + return (lock_names[type]); + else if (type - CRYPTO_NUM_LOCKS > sk_OPENSSL_STRING_num(app_locks)) + return ("ERROR"); + else + return (sk_OPENSSL_STRING_value(app_locks, type - CRYPTO_NUM_LOCKS)); +} + +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__INTEL__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) + +unsigned int OPENSSL_ia32cap_P[2]; +unsigned long *OPENSSL_ia32cap_loc(void) +{ + if (sizeof(long) == 4) + /* + * If 32-bit application pulls address of OPENSSL_ia32cap_P[0] + * clear second element to maintain the illusion that vector + * is 32-bit. + */ + OPENSSL_ia32cap_P[1] = 0; + return (unsigned long *)OPENSSL_ia32cap_P; +} + +# if defined(OPENSSL_CPUID_OBJ) && !defined(OPENSSL_NO_ASM) && !defined(I386_ONLY) +# define OPENSSL_CPUID_SETUP +# if defined(_WIN32) +typedef unsigned __int64 IA32CAP; +# else +typedef unsigned long long IA32CAP; +# endif +void OPENSSL_cpuid_setup(void) +{ + static int trigger = 0; + IA32CAP OPENSSL_ia32_cpuid(void); + IA32CAP vec; + char *env; + + if (trigger) + return; + + trigger = 1; + if ((env = getenv("OPENSSL_ia32cap"))) { + int off = (env[0] == '~') ? 1 : 0; +# if defined(_WIN32) + if (!sscanf(env + off, "%I64i", &vec)) + vec = strtoul(env + off, NULL, 0); +# else + if (!sscanf(env + off, "%lli", (long long *)&vec)) + vec = strtoul(env + off, NULL, 0); +# endif + if (off) + vec = OPENSSL_ia32_cpuid() & ~vec; + } else + vec = OPENSSL_ia32_cpuid(); + + /* + * |(1<<10) sets a reserved bit to signal that variable + * was initialized already... This is to avoid interference + * with cpuid snippets in ELF .init segment. + */ + OPENSSL_ia32cap_P[0] = (unsigned int)vec | (1 << 10); + OPENSSL_ia32cap_P[1] = (unsigned int)(vec >> 32); +} +# endif + +#else +unsigned long *OPENSSL_ia32cap_loc(void) +{ + return NULL; +} +#endif +int OPENSSL_NONPIC_relocated = 0; +#if !defined(OPENSSL_CPUID_SETUP) && !defined(OPENSSL_CPUID_OBJ) +void OPENSSL_cpuid_setup(void) +{ +} +#endif + +#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(_WINDLL) +# ifdef __CYGWIN__ +/* pick DLL_[PROCESS|THREAD]_[ATTACH|DETACH] definitions */ +# include +/* + * this has side-effect of _WIN32 getting defined, which otherwise is + * mutually exclusive with __CYGWIN__... + */ +# endif + +/* + * All we really need to do is remove the 'error' state when a thread + * detaches + */ + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + switch (fdwReason) { + case DLL_PROCESS_ATTACH: + OPENSSL_cpuid_setup(); +# if defined(_WIN32_WINNT) + { + IMAGE_DOS_HEADER *dos_header = (IMAGE_DOS_HEADER *) hinstDLL; + IMAGE_NT_HEADERS *nt_headers; + + if (dos_header->e_magic == IMAGE_DOS_SIGNATURE) { + nt_headers = (IMAGE_NT_HEADERS *) ((char *)dos_header + + dos_header->e_lfanew); + if (nt_headers->Signature == IMAGE_NT_SIGNATURE && + hinstDLL != + (HINSTANCE) (nt_headers->OptionalHeader.ImageBase)) + OPENSSL_NONPIC_relocated = 1; + } + } +# endif + break; + case DLL_THREAD_ATTACH: + break; + case DLL_THREAD_DETACH: + break; + case DLL_PROCESS_DETACH: + break; + } + return (TRUE); +} +#endif + +#if defined(_WIN32) && !defined(__CYGWIN__) +# include +# include +# ifdef __WATCOMC__ +# if defined(_UNICODE) || defined(__UNICODE__) +# define _vsntprintf _vsnwprintf +# else +# define _vsntprintf _vsnprintf +# endif +# endif +# ifdef _MSC_VER +# define alloca _alloca +# endif + +# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 +int OPENSSL_isservice(void) +{ + HWINSTA h; + DWORD len; + WCHAR *name; + static union { + void *p; + int (*f) (void); + } _OPENSSL_isservice = { + NULL + }; + + if (_OPENSSL_isservice.p == NULL) { + HANDLE h = GetModuleHandle(NULL); + if (h != NULL) + _OPENSSL_isservice.p = GetProcAddress(h, "_OPENSSL_isservice"); + if (_OPENSSL_isservice.p == NULL) + _OPENSSL_isservice.p = (void *)-1; + } + + if (_OPENSSL_isservice.p != (void *)-1) + return (*_OPENSSL_isservice.f) (); + + h = GetProcessWindowStation(); + if (h == NULL) + return -1; + + if (GetUserObjectInformationW(h, UOI_NAME, NULL, 0, &len) || + GetLastError() != ERROR_INSUFFICIENT_BUFFER) + return -1; + + if (len > 512) + return -1; /* paranoia */ + len++, len &= ~1; /* paranoia */ + name = (WCHAR *)alloca(len + sizeof(WCHAR)); + if (!GetUserObjectInformationW(h, UOI_NAME, name, len, &len)) + return -1; + + len++, len &= ~1; /* paranoia */ + name[len / sizeof(WCHAR)] = L'\0'; /* paranoia */ +# if 1 + /* + * This doesn't cover "interactive" services [working with real + * WinSta0's] nor programs started non-interactively by Task Scheduler + * [those are working with SAWinSta]. + */ + if (wcsstr(name, L"Service-0x")) + return 1; +# else + /* This covers all non-interactive programs such as services. */ + if (!wcsstr(name, L"WinSta0")) + return 1; +# endif + else + return 0; +} +# else +int OPENSSL_isservice(void) +{ + return 0; +} +# endif + +void OPENSSL_showfatal(const char *fmta, ...) +{ + va_list ap; + TCHAR buf[256]; + const TCHAR *fmt; +# ifdef STD_ERROR_HANDLE /* what a dirty trick! */ + HANDLE h; + + if ((h = GetStdHandle(STD_ERROR_HANDLE)) != NULL && + GetFileType(h) != FILE_TYPE_UNKNOWN) { + /* must be console application */ + va_start(ap, fmta); + vfprintf(stderr, fmta, ap); + va_end(ap); + return; + } +# endif + + if (sizeof(TCHAR) == sizeof(char)) + fmt = (const TCHAR *)fmta; + else + do { + int keepgoing; + size_t len_0 = strlen(fmta) + 1, i; + WCHAR *fmtw; + + fmtw = (WCHAR *)alloca(len_0 * sizeof(WCHAR)); + if (fmtw == NULL) { + fmt = (const TCHAR *)L"no stack?"; + break; + } +# ifndef OPENSSL_NO_MULTIBYTE + if (!MultiByteToWideChar(CP_ACP, 0, fmta, len_0, fmtw, len_0)) +# endif + for (i = 0; i < len_0; i++) + fmtw[i] = (WCHAR)fmta[i]; + + for (i = 0; i < len_0; i++) { + if (fmtw[i] == L'%') + do { + keepgoing = 0; + switch (fmtw[i + 1]) { + case L'0': + case L'1': + case L'2': + case L'3': + case L'4': + case L'5': + case L'6': + case L'7': + case L'8': + case L'9': + case L'.': + case L'*': + case L'-': + i++; + keepgoing = 1; + break; + case L's': + fmtw[i + 1] = L'S'; + break; + case L'S': + fmtw[i + 1] = L's'; + break; + case L'c': + fmtw[i + 1] = L'C'; + break; + case L'C': + fmtw[i + 1] = L'c'; + break; + } + } while (keepgoing); + } + fmt = (const TCHAR *)fmtw; + } while (0); + + va_start(ap, fmta); + _vsntprintf(buf, sizeof(buf) / sizeof(TCHAR) - 1, fmt, ap); + buf[sizeof(buf) / sizeof(TCHAR) - 1] = _T('\0'); + va_end(ap); + +# if defined(_WIN32_WINNT) && _WIN32_WINNT>=0x0333 + /* this -------------v--- guards NT-specific calls */ + if (check_winnt() && OPENSSL_isservice() > 0) { + HANDLE hEventLog = RegisterEventSource(NULL, _T("OpenSSL")); + + if (hEventLog != NULL) { + const TCHAR *pmsg = buf; + + if (!ReportEvent(hEventLog, EVENTLOG_ERROR_TYPE, 0, 0, NULL, + 1, 0, &pmsg, NULL)) { +#if defined(DEBUG) + /* + * We are in a situation where we tried to report a critical + * error and this failed for some reason. As a last resort, + * in debug builds, send output to the debugger or any other + * tool like DebugView which can monitor the output. + */ + OutputDebugString(pmsg); +#endif + } + + (void)DeregisterEventSource(hEventLog); + } + } else +# endif + MessageBox(NULL, buf, _T("OpenSSL: FATAL"), MB_OK | MB_ICONERROR); +} +#else +void OPENSSL_showfatal(const char *fmta, ...) +{ + va_list ap; + + va_start(ap, fmta); + vfprintf(stderr, fmta, ap); + va_end(ap); +} + +int OPENSSL_isservice(void) +{ + return 0; +} +#endif + +void OpenSSLDie(const char *file, int line, const char *assertion) +{ + OPENSSL_showfatal + ("%s(%d): OpenSSL internal error, assertion failed: %s\n", file, line, + assertion); +#if !defined(_WIN32) || defined(__CYGWIN__) + abort(); +#else + /* + * Win32 abort() customarily shows a dialog, but we just did that... + */ + raise(SIGABRT); + _exit(3); +#endif +} + +void *OPENSSL_stderr(void) +{ + return stderr; +} + +int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) +{ + size_t i; + const unsigned char *a = in_a; + const unsigned char *b = in_b; + unsigned char x = 0; + + for (i = 0; i < len; i++) + x |= a[i] ^ b[i]; + + return x; +} diff --git a/libs/openssl/crypto/cryptlib.h b/libs/openssl/crypto/cryptlib.h new file mode 100644 index 00000000..fba180a6 --- /dev/null +++ b/libs/openssl/crypto/cryptlib.h @@ -0,0 +1,111 @@ +/* crypto/cryptlib.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_CRYPTLIB_H +# define HEADER_CRYPTLIB_H + +# include +# include + +# include "e_os.h" + +# ifdef OPENSSL_USE_APPLINK +# define BIO_FLAGS_UPLINK 0x8000 +# include "ms/uplink.h" +# endif + +# include +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_SYS_VMS +# define X509_CERT_AREA OPENSSLDIR +# define X509_CERT_DIR OPENSSLDIR "/certs" +# define X509_CERT_FILE OPENSSLDIR "/cert.pem" +# define X509_PRIVATE_DIR OPENSSLDIR "/private" +# else +# define X509_CERT_AREA "SSLROOT:[000000]" +# define X509_CERT_DIR "SSLCERTS:" +# define X509_CERT_FILE "SSLCERTS:cert.pem" +# define X509_PRIVATE_DIR "SSLPRIVATE:" +# endif + +# define X509_CERT_DIR_EVP "SSL_CERT_DIR" +# define X509_CERT_FILE_EVP "SSL_CERT_FILE" + +/* size of string representations */ +# define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) +# define HEX_SIZE(type) (sizeof(type)*2) + +void OPENSSL_cpuid_setup(void); +extern unsigned int OPENSSL_ia32cap_P[]; +void OPENSSL_showfatal(const char *fmta, ...); +void *OPENSSL_stderr(void); +extern int OPENSSL_NONPIC_relocated; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/crypto-lib.com b/libs/openssl/crypto/crypto-lib.com new file mode 100644 index 00000000..a136f4b0 --- /dev/null +++ b/libs/openssl/crypto/crypto-lib.com @@ -0,0 +1,1537 @@ +$! +$! CRYPTO-LIB.COM +$! Written By: Robert Byer +$! Vice-President +$! A-Com Computing, Inc. +$! byer@mail.all-net.net +$! +$! Changes by Richard Levitte +$! Zoltan Arpadffy +$! +$! This command files compiles and creates the "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" +$! library for OpenSSL. The "xxx" denotes the machine architecture, ALPHA, +$! IA64 or VAX. +$! +$! It was re-written so it would try to determine what "C" compiler to use +$! or you can specify which "C" compiler to use. +$! +$! Specify the following as P1 to build just that part or ALL to just +$! build everything. +$! +$! LIBRARY To just compile the [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library. +$! APPS To just compile the [.xxx.EXE.CRYPTO]*.EXE +$! ALL To do both LIBRARY and APPS +$! +$! Specify DEBUG or NODEBUG as P2 to compile with or without debugger +$! information. +$! +$! Specify which compiler at P3 to try to compile under. +$! +$! VAXC For VAX C. +$! DECC For DEC C. +$! GNUC For GNU C. +$! +$! If you don't specify a compiler, it will try to determine which +$! "C" compiler to use. +$! +$! P4, if defined, sets a TCP/IP library to use, through one of the following +$! keywords: +$! +$! UCX For UCX +$! TCPIP For TCPIP (post UCX) +$! SOCKETSHR For SOCKETSHR+NETLIB +$! +$! P5, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up) +$! +$! P6, if defined, sets a choice of crypto methods to compile. +$! WARNING: this should only be done to recompile some part of an already +$! fully compiled library. +$! +$! P7, if defined, specifies the C pointer size. Ignored on VAX. +$! ("64=ARGV" gives more efficient code with HP C V7.3 or newer.) +$! Supported values are: +$! +$! "" Compile with default (/NOPOINTER_SIZE) +$! 32 Compile with /POINTER_SIZE=32 (SHORT) +$! 64 Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV]). +$! (Automatically select ARGV if compiler supports it.) +$! 64= Compile with /POINTER_SIZE=64 (LONG). +$! 64=ARGV Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV). +$! +$! P8, if defined, specifies a directory where ZLIB files (zlib.h, +$! libz.olb) may be found. Optionally, a non-default object library +$! name may be included ("dev:[dir]libz_64.olb", for example). +$! +$! +$! Announce/identify. +$! +$ proc = f$environment( "procedure") +$ write sys$output "@@@ "+ - + f$parse( proc, , , "name")+ f$parse( proc, , , "type") +$! +$! Define A TCP/IP Library That We Will Need To Link To. +$! (That Is, If We Need To Link To One.) +$! +$ TCPIP_LIB = "" +$ ZLIB_LIB = "" +$! +$! Check Which Architecture We Are Using. +$! +$ IF (F$GETSYI("CPU").LT.128) +$ THEN +$! +$! The Architecture Is VAX +$! +$ ARCH = "VAX" +$! +$! Else... +$! +$ ELSE +$! +$! The Architecture Is Alpha, IA64 or whatever comes in the future. +$! +$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE") +$ IF (ARCH .EQS. "") THEN ARCH = "UNK" +$! +$! End The Architecture Check. +$! +$ ENDIF +$! +$ ARCHD = ARCH +$ LIB32 = "32" +$ OPT_FILE = "" +$ POINTER_SIZE = "" +$! +$! Define The Different Encryption Types. +$! NOTE: Some might think this list ugly. However, it's made this way to +$! reflect the SDIRS variable in [-]Makefile.org as closely as possible, +$! thereby making it fairly easy to verify that the lists are the same. +$! +$ ET_WHIRLPOOL = "WHRLPOOL" +$ IF ARCH .EQS. "VAX" THEN ET_WHIRLPOOL = "" +$ ENCRYPT_TYPES = "Basic,"+ - + "OBJECTS,"+ - + "MD4,MD5,SHA,MDC2,HMAC,RIPEMD,"+ET_WHIRLPOOL+","+ - + "DES,AES,RC2,RC4,IDEA,BF,CAST,CAMELLIA,SEED,MODES,"+ - + "BN,EC,RSA,DSA,ECDSA,DH,ECDH,DSO,ENGINE,"+ - + "BUFFER,BIO,STACK,LHASH,RAND,ERR,"+ - + "EVP,EVP_2,EVP_3,ASN1,ASN1_2,PEM,X509,X509V3,"+ - + "CONF,TXT_DB,PKCS7,PKCS12,COMP,OCSP,UI,KRB5,"+ - + "CMS,PQUEUE,TS,JPAKE,SRP,STORE,CMAC" +$! +$! Check To Make Sure We Have Valid Command Line Parameters. +$! +$ GOSUB CHECK_OPTIONS +$! +$! Define The OBJ and EXE Directories. +$! +$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.CRYPTO] +$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO] +$! +$! Specify the destination directory in any /MAP option. +$! +$ if (LINKMAP .eqs. "MAP") +$ then +$ LINKMAP = LINKMAP+ "=''EXE_DIR'" +$ endif +$! +$! Add the location prefix to the linker options file name. +$! +$ if (OPT_FILE .nes. "") +$ then +$ OPT_FILE = EXE_DIR+ OPT_FILE +$ endif +$! +$! Initialise logical names and such +$! +$ GOSUB INITIALISE +$! +$! Tell The User What Kind of Machine We Run On. +$! +$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'" +$! +$! +$! Check To See If The Architecture Specific OBJ Directory Exists. +$! +$ IF (F$PARSE(OBJ_DIR).EQS."") +$ THEN +$! +$! It Dosen't Exist, So Create It. +$! +$ CREATE/DIR 'OBJ_DIR' +$! +$! End The Architecture Specific OBJ Directory Check. +$! +$ ENDIF +$! +$! Check To See If The Architecture Specific Directory Exists. +$! +$ IF (F$PARSE(EXE_DIR).EQS."") +$ THEN +$! +$! It Dosen't Exist, So Create It. +$! +$ CREATE/DIRECTORY 'EXE_DIR' +$! +$! End The Architecture Specific Directory Check. +$! +$ ENDIF +$! +$! Define The Library Name. +$! +$ LIB_NAME := 'EXE_DIR'SSL_LIBCRYPTO'LIB32'.OLB +$! +$! Define The CRYPTO-LIB We Are To Use. +$! +$ CRYPTO_LIB := 'EXE_DIR'SSL_LIBCRYPTO'LIB32'.OLB +$! +$! Check To See If We Already Have A "[.xxx.EXE.CRYPTO]LIBCRYPTO.OLB" Library... +$! +$ IF (F$SEARCH(LIB_NAME).EQS."") +$ THEN +$! +$! Guess Not, Create The Library. +$! +$ LIBRARY/CREATE/OBJECT 'LIB_NAME' +$! +$! End The Library Check. +$! +$ ENDIF +$! +$! Build our options file for the application +$! +$ GOSUB CHECK_OPT_FILE +$! +$! Define The Different Encryption "library" Strings. +$! +$!!! Test apps disabled, as they aren't supported at all, +$!!! not even in the unix build +$!!! APPS_DES = "DES/DES,CBC3_ENC" +$!!! APPS_PKCS7 = "ENC/ENC;DEC/DEC;SIGN/SIGN;VERIFY/VERIFY,EXAMPLE" +$ +$! These variables are ordered as the SDIRS variable from the top Makefile.org +$! The contents of these variables are copied from the LIBOBJ variable in the +$! corresponding Makefile from each corresponding subdirectory, with .o stripped +$! and spaces replaced with commas. +$ LIB_ = "cryptlib,mem,mem_dbg,cversion,ex_data,cpt_err,ebcdic,"+ - + "uid,o_time,o_str,o_dir,o_fips.c,o_init,fips_ers,mem_clr" +$ LIB_OBJECTS = "o_names,obj_dat,obj_lib,obj_err,obj_xref" +$ LIB_MD2 = "md2_dgst,md2_one" +$ LIB_MD4 = "md4_dgst,md4_one" +$ LIB_MD5 = "md5_dgst,md5_one" +$ LIB_SHA = "sha_dgst,sha1dgst,sha_one,sha1_one,sha256,sha512" +$ LIB_MDC2 = "mdc2dgst,mdc2_one" +$ LIB_HMAC = "hmac,hm_ameth,hm_pmeth" +$ LIB_RIPEMD = "rmd_dgst,rmd_one" +$ LIB_WHRLPOOL = "wp_dgst,wp_block" +$ LIB_DES = "set_key,ecb_enc,cbc_enc,"+ - + "ecb3_enc,cfb64enc,cfb64ede,cfb_enc,ofb64ede,"+ - + "enc_read,enc_writ,ofb64enc,"+ - + "ofb_enc,str2key,pcbc_enc,qud_cksm,rand_key,"+ - + "des_enc,fcrypt_b,"+ - + "fcrypt,xcbc_enc,rpc_enc,cbc_cksm,"+ - + "ede_cbcm_enc,des_old,des_old2,read2pwd" +$ LIB_RC2 = "rc2_ecb,rc2_skey,rc2_cbc,rc2cfb64,rc2ofb64" +$ LIB_RC4 = "rc4_enc,rc4_skey,rc4_utl" +$ LIB_RC5 = "rc5_skey,rc5_ecb,rc5_enc,rc5cfb64,rc5ofb64" +$ LIB_IDEA = "i_cbc,i_cfb64,i_ofb64,i_ecb,i_skey" +$ LIB_BF = "bf_skey,bf_ecb,bf_enc,bf_cfb64,bf_ofb64" +$ LIB_CAST = "c_skey,c_ecb,c_enc,c_cfb64,c_ofb64" +$ LIB_CAMELLIA = "cmll_ecb,cmll_ofb,cmll_cfb,cmll_ctr,cmll_utl,"+ - + "camellia,cmll_misc,cmll_cbc" +$ LIB_SEED = "seed,seed_ecb,seed_cbc,seed_cfb,seed_ofb" +$ LIB_MODES = "cbc128,ctr128,cts128,cfb128,ofb128,gcm128,"+ - + "ccm128,xts128" +$ LIB_BN_ASM = "[.asm]vms.mar,vms-helper" +$ IF F$TRNLNM("OPENSSL_NO_ASM") .OR. ARCH .NES. "VAX" THEN - + LIB_BN_ASM = "bn_asm" +$ LIB_BN = "bn_add,bn_div,bn_exp,bn_lib,bn_ctx,bn_mul,bn_mod,"+ - + "bn_print,bn_rand,bn_shift,bn_word,bn_blind,"+ - + "bn_kron,bn_sqrt,bn_gcd,bn_prime,bn_err,bn_sqr,"+LIB_BN_ASM+","+ - + "bn_recp,bn_mont,bn_mpi,bn_exp2,bn_gf2m,bn_nist,"+ - + "bn_depr,bn_const,bn_x931p" +$ LIB_EC = "ec_lib,ecp_smpl,ecp_mont,ecp_nist,ec_cvt,ec_mult,"+ - + "ec_err,ec_curve,ec_check,ec_print,ec_asn1,ec_key,"+ - + "ec2_smpl,ec2_mult,ec_ameth,ec_pmeth,eck_prn,"+ - + "ecp_nistp224,ecp_nistp256,ecp_nistp521,ecp_nistputil,"+ - + "ecp_oct,ec2_oct,ec_oct" +$ LIB_RSA = "rsa_eay,rsa_gen,rsa_lib,rsa_sign,rsa_saos,rsa_err,"+ - + "rsa_pk1,rsa_ssl,rsa_none,rsa_oaep,rsa_chk,rsa_null,"+ - + "rsa_pss,rsa_x931,rsa_asn1,rsa_depr,rsa_ameth,rsa_prn,"+ - + "rsa_pmeth,rsa_crpt" +$ LIB_DSA = "dsa_gen,dsa_key,dsa_lib,dsa_asn1,dsa_vrf,dsa_sign,"+ - + "dsa_err,dsa_ossl,dsa_depr,dsa_ameth,dsa_pmeth,dsa_prn" +$ LIB_ECDSA = "ecs_lib,ecs_asn1,ecs_ossl,ecs_sign,ecs_vrf,ecs_err" +$ LIB_DH = "dh_asn1,dh_gen,dh_key,dh_lib,dh_check,dh_err,dh_depr,"+ - + "dh_ameth,dh_pmeth,dh_prn" +$ LIB_ECDH = "ech_lib,ech_ossl,ech_key,ech_err" +$ LIB_DSO = "dso_dl,dso_dlfcn,dso_err,dso_lib,dso_null,"+ - + "dso_openssl,dso_win32,dso_vms,dso_beos" +$ LIB_ENGINE = "eng_err,eng_lib,eng_list,eng_init,eng_ctrl,"+ - + "eng_table,eng_pkey,eng_fat,eng_all,"+ - + "tb_rsa,tb_dsa,tb_ecdsa,tb_dh,tb_ecdh,tb_rand,tb_store,"+ - + "tb_cipher,tb_digest,tb_pkmeth,tb_asnmth,"+ - + "eng_openssl,eng_cnf,eng_dyn,eng_cryptodev,"+ - + "eng_rsax,eng_rdrand" +$ LIB_AES = "aes_misc,aes_ecb,aes_cfb,aes_ofb,aes_ctr,aes_ige,aes_wrap,"+ - + "aes_core,aes_cbc" +$ LIB_BUFFER = "buffer,buf_str,buf_err" +$ LIB_BIO = "bio_lib,bio_cb,bio_err,"+ - + "bss_mem,bss_null,bss_fd,"+ - + "bss_file,bss_sock,bss_conn,"+ - + "bf_null,bf_buff,b_print,b_dump,"+ - + "b_sock,bss_acpt,bf_nbio,bss_log,bss_bio,"+ - + "bss_dgram,"+ - + "bf_lbuf,bss_rtcp" ! The last two are VMS specific +$ LIB_STACK = "stack" +$ LIB_LHASH = "lhash,lh_stats" +$ LIB_RAND = "md_rand,randfile,rand_lib,rand_err,rand_egd,"+ - + "rand_vms" ! The last one is VMS specific +$ LIB_ERR = "err,err_all,err_prn" +$ LIB_EVP = "encode,digest,evp_enc,evp_key,evp_acnf,evp_cnf,"+ - + "e_des,e_bf,e_idea,e_des3,e_camellia,"+ - + "e_rc4,e_aes,names,e_seed,"+ - + "e_xcbc_d,e_rc2,e_cast,e_rc5" +$ LIB_EVP_2 = "m_null,m_md2,m_md4,m_md5,m_sha,m_sha1,m_wp," + - + "m_dss,m_dss1,m_mdc2,m_ripemd,m_ecdsa,"+ - + "p_open,p_seal,p_sign,p_verify,p_lib,p_enc,p_dec,"+ - + "bio_md,bio_b64,bio_enc,evp_err,e_null,"+ - + "c_all,c_allc,c_alld,evp_lib,bio_ok,"+- + "evp_pkey,evp_pbe,p5_crpt,p5_crpt2" +$ LIB_EVP_3 = "e_old,pmeth_lib,pmeth_fn,pmeth_gn,m_sigver,evp_fips,"+ - + "e_aes_cbc_hmac_sha1,e_rc4_hmac_md5" +$ LIB_ASN1 = "a_object,a_bitstr,a_utctm,a_gentm,a_time,a_int,a_octet,"+ - + "a_print,a_type,a_set,a_dup,a_d2i_fp,a_i2d_fp,"+ - + "a_enum,a_utf8,a_sign,a_digest,a_verify,a_mbstr,a_strex,"+ - + "x_algor,x_val,x_pubkey,x_sig,x_req,x_attrib,x_bignum,"+ - + "x_long,x_name,x_x509,x_x509a,x_crl,x_info,x_spki,nsseq,"+ - + "x_nx509,d2i_pu,d2i_pr,i2d_pu,i2d_pr" +$ LIB_ASN1_2 = "t_req,t_x509,t_x509a,t_crl,t_pkey,t_spki,t_bitst,"+ - + "tasn_new,tasn_fre,tasn_enc,tasn_dec,tasn_utl,tasn_typ,"+ - + "tasn_prn,ameth_lib,"+ - + "f_int,f_string,n_pkey,"+ - + "f_enum,x_pkey,a_bool,x_exten,bio_asn1,bio_ndef,asn_mime,"+ - + "asn1_gen,asn1_par,asn1_lib,asn1_err,a_bytes,a_strnid,"+ - + "evp_asn1,asn_pack,p5_pbe,p5_pbev2,p8_pkey,asn_moid" +$ LIB_PEM = "pem_sign,pem_seal,pem_info,pem_lib,pem_all,pem_err,"+ - + "pem_x509,pem_xaux,pem_oth,pem_pk8,pem_pkey,pvkfmt" +$ LIB_X509 = "x509_def,x509_d2,x509_r2x,x509_cmp,"+ - + "x509_obj,x509_req,x509spki,x509_vfy,"+ - + "x509_set,x509cset,x509rset,x509_err,"+ - + "x509name,x509_v3,x509_ext,x509_att,"+ - + "x509type,x509_lu,x_all,x509_txt,"+ - + "x509_trs,by_file,by_dir,x509_vpm" +$ LIB_X509V3 = "v3_bcons,v3_bitst,v3_conf,v3_extku,v3_ia5,v3_lib,"+ - + "v3_prn,v3_utl,v3err,v3_genn,v3_alt,v3_skey,v3_akey,v3_pku,"+ - + "v3_int,v3_enum,v3_sxnet,v3_cpols,v3_crld,v3_purp,v3_info,"+ - + "v3_ocsp,v3_akeya,v3_pmaps,v3_pcons,v3_ncons,v3_pcia,v3_pci,"+ - + "pcy_cache,pcy_node,pcy_data,pcy_map,pcy_tree,pcy_lib,"+ - + "v3_asid,v3_addr" +$ LIB_CONF = "conf_err,conf_lib,conf_api,conf_def,conf_mod,conf_mall,conf_sap" +$ LIB_TXT_DB = "txt_db" +$ LIB_PKCS7 = "pk7_asn1,pk7_lib,pkcs7err,pk7_doit,pk7_smime,pk7_attr,"+ - + "pk7_mime,bio_pk7" +$ LIB_PKCS12 = "p12_add,p12_asn,p12_attr,p12_crpt,p12_crt,p12_decr,"+ - + "p12_init,p12_key,p12_kiss,p12_mutl,"+ - + "p12_utl,p12_npas,pk12err,p12_p8d,p12_p8e" +$ LIB_COMP = "comp_lib,comp_err,"+ - + "c_rle,c_zlib" +$ LIB_OCSP = "ocsp_asn,ocsp_ext,ocsp_ht,ocsp_lib,ocsp_cl,"+ - + "ocsp_srv,ocsp_prn,ocsp_vfy,ocsp_err" +$ LIB_UI_COMPAT = ",ui_compat" +$ LIB_UI = "ui_err,ui_lib,ui_openssl,ui_util"+LIB_UI_COMPAT +$ LIB_KRB5 = "krb5_asn" +$ LIB_CMS = "cms_lib,cms_asn1,cms_att,cms_io,cms_smime,cms_err,"+ - + "cms_sd,cms_dd,cms_cd,cms_env,cms_enc,cms_ess,"+ - + "cms_pwri" +$ LIB_PQUEUE = "pqueue" +$ LIB_TS = "ts_err,ts_req_utils,ts_req_print,ts_rsp_utils,ts_rsp_print,"+ - + "ts_rsp_sign,ts_rsp_verify,ts_verify_ctx,ts_lib,ts_conf,"+ - + "ts_asn1" +$ LIB_JPAKE = "jpake,jpake_err" +$ LIB_SRP = "srp_lib,srp_vfy" +$ LIB_STORE = "str_err,str_lib,str_meth,str_mem" +$ LIB_CMAC = "cmac,cm_ameth,cm_pmeth" +$! +$! Setup exceptional compilations +$! +$ CC3_SHOWN = 0 +$ CC4_SHOWN = 0 +$ CC5_SHOWN = 0 +$ CC6_SHOWN = 0 +$! +$! The following lists must have leading and trailing commas, and no +$! embedded spaces. (They are scanned for ",name,".) +$! +$ ! Add definitions for no threads on OpenVMS 7.1 and higher. +$ COMPILEWITH_CC3 = ",bss_rtcp," +$ ! Disable the DOLLARID warning. Not needed with /STANDARD=RELAXED. +$ COMPILEWITH_CC4 = "" !!! ",a_utctm,bss_log,o_time,o_dir," +$ ! Disable disjoint optimization on VAX with DECC. +$ COMPILEWITH_CC5 = ",md2_dgst,md4_dgst,md5_dgst,mdc2dgst," + - + "seed,sha_dgst,sha1dgst,rmd_dgst,bf_enc," +$ ! Disable the MIXLINKAGE warning. +$ COMPILEWITH_CC6 = "" !!! ",enc_read,set_key," +$! +$! Figure Out What Other Modules We Are To Build. +$! +$ BUILD_SET: +$! +$! Define A Module Counter. +$! +$ MODULE_COUNTER = 0 +$! +$! Top Of The Loop. +$! +$ MODULE_NEXT: +$! +$! Extract The Module Name From The Encryption List. +$! +$ MODULE_NAME = F$EDIT(F$ELEMENT(MODULE_COUNTER,",",ENCRYPT_TYPES),"COLLAPSE") +$ IF MODULE_NAME.EQS."Basic" THEN MODULE_NAME = "" +$ MODULE_NAME1 = MODULE_NAME +$! +$! Check To See If We Are At The End Of The Module List. +$! +$ IF (MODULE_NAME.EQS.",") +$ THEN +$! +$! We Are At The End Of The Module List, Go To MODULE_DONE. +$! +$ GOTO MODULE_DONE +$! +$! End The Module List Check. +$! +$ ENDIF +$! +$! Increment The Moudle Counter. +$! +$ MODULE_COUNTER = MODULE_COUNTER + 1 +$! +$! Create The Library and Apps Module Names. +$! +$ LIB_MODULE = "LIB_" + MODULE_NAME +$ APPS_MODULE = "APPS_" + MODULE_NAME +$ IF (F$EXTRACT(0,5,MODULE_NAME).EQS."ASN1_") +$ THEN +$ MODULE_NAME = "ASN1" +$ ENDIF +$ IF (F$EXTRACT(0,4,MODULE_NAME).EQS."EVP_") +$ THEN +$ MODULE_NAME = "EVP" +$ ENDIF +$! +$! Set state (can be LIB and APPS) +$! +$ STATE = "LIB" +$ IF BUILDALL .EQS. "APPS" THEN STATE = "APPS" +$! +$! Check if the library module name actually is defined +$! +$ IF F$TYPE('LIB_MODULE') .EQS. "" +$ THEN +$ WRITE SYS$ERROR "" +$ WRITE SYS$ERROR "The module ",MODULE_NAME1," does not exist. Continuing..." +$ WRITE SYS$ERROR "" +$ GOTO MODULE_NEXT +$ ENDIF +$! +$! Top Of The Module Loop. +$! +$ MODULE_AGAIN: +$! +$! Tell The User What Module We Are Building. +$! +$ IF (MODULE_NAME1.NES."") +$ THEN +$ IF STATE .EQS. "LIB" +$ THEN +$ WRITE SYS$OUTPUT "Compiling The ",MODULE_NAME1," Library Files. (",BUILDALL,",",STATE,")" +$ ELSE IF F$TYPE('APPS_MODULE') .NES. "" +$ THEN +$ WRITE SYS$OUTPUT "Compiling The ",MODULE_NAME1," Applications. (",BUILDALL,",",STATE,")" +$ ENDIF +$ ENDIF +$ ENDIF +$! +$! Define A File Counter And Set It To "0". +$! +$ FILE_COUNTER = 0 +$ APPLICATION = "" +$ APPLICATION_COUNTER = 0 +$! +$! Top Of The File Loop. +$! +$ NEXT_FILE: +$! +$! Look in the LIB_MODULE is we're in state LIB +$! +$ IF STATE .EQS. "LIB" +$ THEN +$! +$! O.K, Extract The File Name From The File List. +$! +$ FILE_NAME = F$EDIT(F$ELEMENT(FILE_COUNTER,",",'LIB_MODULE'),"COLLAPSE") +$! +$! else +$! +$ ELSE +$ FILE_NAME = "," +$! +$ IF F$TYPE('APPS_MODULE') .NES. "" +$ THEN +$! +$! Extract The File Name From The File List. +$! This part is a bit more complicated. +$! +$ IF APPLICATION .EQS. "" +$ THEN +$ APPLICATION = F$ELEMENT(APPLICATION_COUNTER,";",'APPS_MODULE') +$ APPLICATION_COUNTER = APPLICATION_COUNTER + 1 +$ APPLICATION_OBJECTS = F$ELEMENT(1,"/",APPLICATION) +$ APPLICATION = F$ELEMENT(0,"/",APPLICATION) +$ FILE_COUNTER = 0 +$ ENDIF +$ +$! WRITE SYS$OUTPUT "DEBUG: SHOW SYMBOL APPLICATION*" +$! SHOW SYMBOL APPLICATION* +$! +$ IF APPLICATION .NES. ";" +$ THEN +$ FILE_NAME = F$EDIT(F$ELEMENT(FILE_COUNTER,",",APPLICATION_OBJECTS),"COLLAPSE") +$ IF FILE_NAME .EQS. "," +$ THEN +$ APPLICATION = "" +$ GOTO NEXT_FILE +$ ENDIF +$ ENDIF +$ ENDIF +$ ENDIF +$! +$! Check To See If We Are At The End Of The File List. +$! +$ IF (FILE_NAME.EQS.",") +$ THEN +$! +$! We Are At The End Of The File List, Change State Or Goto FILE_DONE. +$! +$ IF STATE .EQS. "LIB" .AND. BUILDALL .NES. "LIBRARY" +$ THEN +$ STATE = "APPS" +$ GOTO MODULE_AGAIN +$ ELSE +$ GOTO FILE_DONE +$ ENDIF +$! +$! End The File List Check. +$! +$ ENDIF +$! +$! Increment The Counter. +$! +$ FILE_COUNTER = FILE_COUNTER + 1 +$! +$! Create The Source File Name. +$! +$ TMP_FILE_NAME = F$ELEMENT(1,"]",FILE_NAME) +$ IF TMP_FILE_NAME .EQS. "]" THEN TMP_FILE_NAME = FILE_NAME +$ IF F$ELEMENT(0,".",TMP_FILE_NAME) .EQS. TMP_FILE_NAME THEN - + FILE_NAME = FILE_NAME + ".c" +$ IF (MODULE_NAME.NES."") +$ THEN +$ SOURCE_FILE = "SYS$DISK:[." + MODULE_NAME+ "]" + FILE_NAME +$ ELSE +$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME +$ ENDIF +$ SOURCE_FILE = SOURCE_FILE - "][" +$! +$! Create The Object File Name. +$! +$ OBJECT_FILE = OBJ_DIR + F$PARSE(FILE_NAME,,,"NAME","SYNTAX_ONLY") + ".OBJ" +$ ON WARNING THEN GOTO NEXT_FILE +$! +$! Check To See If The File We Want To Compile Is Actually There. +$! +$ IF (F$SEARCH(SOURCE_FILE).EQS."") +$ THEN +$! +$! Tell The User That The File Doesn't Exist. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Doesn't Exist." +$ WRITE SYS$OUTPUT "" +$! +$! Exit The Build. +$! +$ GOTO EXIT +$! +$! End The File Exist Check. +$! +$ ENDIF +$! +$! Tell The User We Are Compiling The File. +$! +$ IF (MODULE_NAME.EQS."") +$ THEN +$ WRITE SYS$OUTPUT "Compiling The ",FILE_NAME," File. (",BUILDALL,",",STATE,")" +$ ENDIF +$ IF (MODULE_NAME.NES."") +$ THEN +$ WRITE SYS$OUTPUT " ",FILE_NAME,"" +$ ENDIF +$! +$! Compile The File. +$! +$ ON ERROR THEN GOTO NEXT_FILE +$ FILE_NAME0 = ","+ F$ELEMENT(0,".",FILE_NAME)+ "," +$ IF FILE_NAME - ".mar" .NES. FILE_NAME +$ THEN +$ MACRO/OBJECT='OBJECT_FILE' 'SOURCE_FILE' +$ ELSE +$ IF COMPILEWITH_CC3 - FILE_NAME0 .NES. COMPILEWITH_CC3 +$ THEN +$ write sys$output " \Using special rule (3)" +$ if (.not. CC3_SHOWN) +$ then +$ CC3_SHOWN = 1 +$ x = " "+ CC3 +$ write /symbol sys$output x +$ endif +$ CC3/OBJECT='OBJECT_FILE' 'SOURCE_FILE' +$ ELSE +$ IF COMPILEWITH_CC4 - FILE_NAME0 .NES. COMPILEWITH_CC4 +$ THEN +$ write /symbol sys$output " \Using special rule (4)" +$ if (.not. CC4_SHOWN) +$ then +$ CC4_SHOWN = 1 +$ x = " "+ CC4 +$ write /symbol sys$output x +$ endif +$ CC4/OBJECT='OBJECT_FILE' 'SOURCE_FILE' +$ ELSE +$ IF CC5_DIFFERENT .AND. - + (COMPILEWITH_CC5 - FILE_NAME0 .NES. COMPILEWITH_CC5) +$ THEN +$ write sys$output " \Using special rule (5)" +$ if (.not. CC5_SHOWN) +$ then +$ CC5_SHOWN = 1 +$ x = " "+ CC5 +$ write /symbol sys$output x +$ endif +$ CC5/OBJECT='OBJECT_FILE' 'SOURCE_FILE' +$ ELSE +$ IF COMPILEWITH_CC6 - FILE_NAME0 .NES. COMPILEWITH_CC6 +$ THEN +$ write sys$output " \Using special rule (6)" +$ if (.not. CC6_SHOWN) +$ then +$ CC6_SHOWN = 1 +$ x = " "+ CC6 +$ write /symbol sys$output x +$ endif +$ CC6/OBJECT='OBJECT_FILE' 'SOURCE_FILE' +$ ELSE +$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE' +$ ENDIF +$ ENDIF +$ ENDIF +$ ENDIF +$ ENDIF +$ IF STATE .EQS. "LIB" +$ THEN +$! +$! Add It To The Library. +$! +$ LIBRARY/REPLACE 'LIB_NAME' 'OBJECT_FILE' +$! +$! Time To Clean Up The Object File. +$! +$ DELETE 'OBJECT_FILE';* +$ ENDIF +$! +$! Go Back And Do It Again. +$! +$ GOTO NEXT_FILE +$! +$! All Done With This Library Part. +$! +$ FILE_DONE: +$! +$! Time To Build Some Applications +$! +$ IF F$TYPE('APPS_MODULE') .NES. "" .AND. BUILDALL .NES. "LIBRARY" +$ THEN +$ APPLICATION_COUNTER = 0 +$ NEXT_APPLICATION: +$ APPLICATION = F$ELEMENT(APPLICATION_COUNTER,";",'APPS_MODULE') +$ IF APPLICATION .EQS. ";" THEN GOTO APPLICATION_DONE +$ +$ APPLICATION_COUNTER = APPLICATION_COUNTER + 1 +$ APPLICATION_OBJECTS = F$ELEMENT(1,"/",APPLICATION) +$ APPLICATION = F$ELEMENT(0,"/",APPLICATION) +$ +$! WRITE SYS$OUTPUT "DEBUG: SHOW SYMBOL APPLICATION*" +$! SHOW SYMBOL APPLICATION* +$! +$! Tell the user what happens +$! +$ WRITE SYS$OUTPUT " ",APPLICATION,".exe" +$! +$! Link The Program. +$! +$ ON ERROR THEN GOTO NEXT_APPLICATION +$! +$! Link With A TCP/IP Library. +$! +$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' - + /EXE='EXE_DIR''APPLICATION'.EXE - + 'OBJ_DIR''APPLICATION_OBJECTS', - + 'CRYPTO_LIB'/LIBRARY - + 'TCPIP_LIB' - + 'ZLIB_LIB' - + ,'OPT_FILE' /OPTIONS +$! +$ GOTO NEXT_APPLICATION +$ APPLICATION_DONE: +$ ENDIF +$! +$! Go Back And Get The Next Module. +$! +$ GOTO MODULE_NEXT +$! +$! All Done With This Module. +$! +$ MODULE_DONE: +$! +$! Tell The User That We Are All Done. +$! +$ WRITE SYS$OUTPUT "All Done..." +$ EXIT: +$ GOSUB CLEANUP +$ EXIT +$! +$! Check For The Link Option FIle. +$! +$ CHECK_OPT_FILE: +$! +$! Check To See If We Need To Make A VAX C Option File. +$! +$ IF (COMPILER.EQS."VAXC") +$ THEN +$! +$! Check To See If We Already Have A VAX C Linker Option File. +$! +$ IF (F$SEARCH(OPT_FILE).EQS."") +$ THEN +$! +$! We Need A VAX C Linker Option File. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File To Link Against +! The Sharable VAX C Runtime Library. +! +SYS$SHARE:VAXCRTL.EXE/SHARE +$EOD +$! +$! End The Option File Check. +$! +$ ENDIF +$! +$! End The VAXC Check. +$! +$ ENDIF +$! +$! Check To See If We Need A GNU C Option File. +$! +$ IF (COMPILER.EQS."GNUC") +$ THEN +$! +$! Check To See If We Already Have A GNU C Linker Option File. +$! +$ IF (F$SEARCH(OPT_FILE).EQS."") +$ THEN +$! +$! We Need A GNU C Linker Option File. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File To Link Against +! The Sharable C Runtime Library. +! +GNU_CC:[000000]GCCLIB/LIBRARY +SYS$SHARE:VAXCRTL/SHARE +$EOD +$! +$! End The Option File Check. +$! +$ ENDIF +$! +$! End The GNU C Check. +$! +$ ENDIF +$! +$! Check To See If We Need A DEC C Option File. +$! +$ IF (COMPILER.EQS."DECC") +$ THEN +$! +$! Check To See If We Already Have A DEC C Linker Option File. +$! +$ IF (F$SEARCH(OPT_FILE).EQS."") +$ THEN +$! +$! Figure Out If We Need A non-VAX Or A VAX Linker Option File. +$! +$ IF ARCH .EQS. "VAX" +$ THEN +$! +$! We Need A DEC C Linker Option File For VAX. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File To Link Against +! The Sharable DEC C Runtime Library. +! +SYS$SHARE:DECC$SHR.EXE/SHARE +$EOD +$! +$! Else... +$! +$ ELSE +$! +$! Create The non-VAX Linker Option File. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File For non-VAX To Link Against +! The Sharable C Runtime Library. +! +SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE +SYS$SHARE:CMA$OPEN_RTL/SHARE +$EOD +$! +$! End The DEC C Option File Check. +$! +$ ENDIF +$! +$! End The Option File Search. +$! +$ ENDIF +$! +$! End The DEC C Check. +$! +$ ENDIF +$! +$! Tell The User What Linker Option File We Are Using. +$! +$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"." +$! +$! Time To RETURN. +$! +$ RETURN +$! +$! Check The User's Options. +$! +$ CHECK_OPTIONS: +$! +$! Check To See If P1 Is Blank. +$! +$ IF (P1.EQS."ALL") +$ THEN +$! +$! P1 Is Blank, So Build Everything. +$! +$ BUILDALL = "TRUE" +$! +$! Else... +$! +$ ELSE +$! +$! Else, Check To See If P1 Has A Valid Argument. +$! +$ IF (P1.EQS."LIBRARY").OR.(P1.EQS."APPS") +$ THEN +$! +$! A Valid Argument. +$! +$ BUILDALL = P1 +$! +$! Else... +$! +$ ELSE +$! +$! Tell The User We Don't Know What They Want. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " ALL : Just Build Everything." +$ WRITE SYS$OUTPUT " LIBRARY : To Compile Just The [.xxx.EXE.CRYPTO]LIBCRYPTO.OLB Library." +$ WRITE SYS$OUTPUT " APPS : To Compile Just The [.xxx.EXE.CRYPTO]*.EXE Programs." +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " Where 'xxx' Stands For:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " ALPHA[64]: Alpha Architecture." +$ WRITE SYS$OUTPUT " IA64[64] : IA64 Architecture." +$ WRITE SYS$OUTPUT " VAX : VAX Architecture." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$! End The Valid Argument Check. +$! +$ ENDIF +$! +$! End The P1 Check. +$! +$ ENDIF +$! +$! Check To See If P2 Is Blank. +$! +$ IF (P2.EQS."NODEBUG") +$ THEN +$! +$! P2 Is NODEBUG, So Compile Without The Debugger Information. +$! +$ DEBUGGER = "NODEBUG" +$ LINKMAP = "NOMAP" +$ TRACEBACK = "NOTRACEBACK" +$ GCC_OPTIMIZE = "OPTIMIZE" +$ CC_OPTIMIZE = "OPTIMIZE" +$ MACRO_OPTIMIZE = "OPTIMIZE" +$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile." +$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization." +$ ELSE +$! +$! Check To See If We Are To Compile With Debugger Information. +$! +$ IF (P2.EQS."DEBUG") +$ THEN +$! +$! Compile With Debugger Information. +$! +$ DEBUGGER = "DEBUG" +$ LINKMAP = "MAP" +$ TRACEBACK = "TRACEBACK" +$ GCC_OPTIMIZE = "NOOPTIMIZE" +$ CC_OPTIMIZE = "NOOPTIMIZE" +$ MACRO_OPTIMIZE = "NOOPTIMIZE" +$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile." +$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization." +$ ELSE +$! +$! They Entered An Invalid Option. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information." +$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$! End The Valid Argument Check. +$! +$ ENDIF +$! +$! End The P2 Check. +$! +$ ENDIF +$! +$! Special Threads For OpenVMS v7.1 Or Later +$! +$! Written By: Richard Levitte +$! richard@levitte.org +$! +$! +$! Check To See If We Have A Option For P5. +$! +$ IF (P5.EQS."") +$ THEN +$! +$! Get The Version Of VMS We Are Using. +$! +$ ISSEVEN := +$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION"))) +$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP)) +$! +$! Check To See If The VMS Version Is v7.1 Or Later. +$! +$ IF (TMP.GE.71) +$ THEN +$! +$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads. +$! +$ ISSEVEN := ,PTHREAD_USE_D4 +$! +$! End The VMS Version Check. +$! +$ ENDIF +$! +$! End The P5 Check. +$! +$ ENDIF +$! +$! Check P7 (POINTER_SIZE). +$! +$ IF (P7 .NES. "") .AND. (ARCH .NES. "VAX") +$ THEN +$! +$ IF (P7 .EQS. "32") +$ THEN +$ POINTER_SIZE = " /POINTER_SIZE=32" +$ ELSE +$ POINTER_SIZE = F$EDIT( P7, "COLLAPSE, UPCASE") +$ IF ((POINTER_SIZE .EQS. "64") .OR. - + (POINTER_SIZE .EQS. "64=") .OR. - + (POINTER_SIZE .EQS. "64=ARGV")) +$ THEN +$ ARCHD = ARCH+ "_64" +$ LIB32 = "" +$ POINTER_SIZE = " /POINTER_SIZE=64" +$ ELSE +$! +$! Tell The User Entered An Invalid Option. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ", P7, - + " Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT - + " """" : Compile with default (short) pointers." +$ WRITE SYS$OUTPUT - + " 32 : Compile with 32-bit (short) pointers." +$ WRITE SYS$OUTPUT - + " 64 : Compile with 64-bit (long) pointers (auto ARGV)." +$ WRITE SYS$OUTPUT - + " 64= : Compile with 64-bit (long) pointers (no ARGV)." +$ WRITE SYS$OUTPUT - + " 64=ARGV : Compile with 64-bit (long) pointers (ARGV)." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$ ENDIF +$! +$ ENDIF +$! +$! End The P7 (POINTER_SIZE) Check. +$! +$ ENDIF +$! +$! Set basic C compiler /INCLUDE directories. +$! +$ CC_INCLUDES = "SYS$DISK:[.''ARCHD'],SYS$DISK:[],SYS$DISK:[-],"+ - + "SYS$DISK:[.ENGINE.VENDOR_DEFNS],SYS$DISK:[.MODES],SYS$DISK:[.ASN1],SYS$DISK:[.EVP]" +$! +$! Check To See If P3 Is Blank. +$! +$ IF (P3.EQS."") +$ THEN +$! +$! O.K., The User Didn't Specify A Compiler, Let's Try To +$! Find Out Which One To Use. +$! +$! Check To See If We Have GNU C. +$! +$ IF (F$TRNLNM("GNU_CC").NES."") +$ THEN +$! +$! Looks Like GNUC, Set To Use GNUC. +$! +$ P3 = "GNUC" +$! +$! Else... +$! +$ ELSE +$! +$! Check To See If We Have VAXC Or DECC. +$! +$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."") +$ THEN +$! +$! Looks Like DECC, Set To Use DECC. +$! +$ P3 = "DECC" +$! +$! Else... +$! +$ ELSE +$! +$! Looks Like VAXC, Set To Use VAXC. +$! +$ P3 = "VAXC" +$! +$! End The VAXC Compiler Check. +$! +$ ENDIF +$! +$! End The DECC & VAXC Compiler Check. +$! +$ ENDIF +$! +$! End The Compiler Check. +$! +$ ENDIF +$! +$! Check To See If We Have A Option For P4. +$! +$ IF (P4.EQS."") +$ THEN +$! +$! Find out what socket library we have available +$! +$ IF F$PARSE("SOCKETSHR:") .NES. "" +$ THEN +$! +$! We have SOCKETSHR, and it is my opinion that it's the best to use. +$! +$ P4 = "SOCKETSHR" +$! +$! Tell the user +$! +$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP" +$! +$! Else, let's look for something else +$! +$ ELSE +$! +$! Like UCX (the reason to do this before Multinet is that the UCX +$! emulation is easier to use...) +$! +$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" - + .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" - + .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. "" +$ THEN +$! +$! Last resort: a UCX or UCX-compatible library +$! +$ P4 = "UCX" +$! +$! Tell the user +$! +$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP" +$! +$! That was all... +$! +$ ENDIF +$ ENDIF +$ ENDIF +$! +$! Set Up Initial CC Definitions, Possibly With User Ones +$! +$ CCDEFS = "TCPIP_TYPE_''P4',DSO_VMS" +$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS +$ CCEXTRAFLAGS = "" +$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS +$ CCDISABLEWARNINGS = "" !!! "MAYLOSEDATA3" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR" +$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" +$ THEN +$ IF CCDISABLEWARNINGS .NES. "" THEN CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," +$ CCDISABLEWARNINGS = CCDISABLEWARNINGS + USER_CCDISABLEWARNINGS +$ ENDIF +$! +$! Check To See If We Have A ZLIB Option. +$! +$ ZLIB = P8 +$ IF (ZLIB .NES. "") +$ THEN +$! +$! Check for expected ZLIB files. +$! +$ err = 0 +$ file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY") +$ if (f$search( file1) .eqs. "") +$ then +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid." +$ WRITE SYS$OUTPUT " Can't find header: ''file1'" +$ err = 1 +$ endif +$ file1 = f$parse( "A.;", ZLIB)- "A.;" +$! +$ file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY") +$ if (f$search( file2) .eqs. "") +$ then +$ if (err .eq. 0) +$ then +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid." +$ endif +$ WRITE SYS$OUTPUT " Can't find library: ''file2'" +$ WRITE SYS$OUTPUT "" +$ err = err+ 2 +$ endif +$ if (err .eq. 1) +$ then +$ WRITE SYS$OUTPUT "" +$ endif +$! +$ if (err .ne. 0) +$ then +$ EXIT +$ endif +$! +$ CCDEFS = """ZLIB=1"", "+ CCDEFS +$ CC_INCLUDES = CC_INCLUDES+ ", "+ file1 +$ ZLIB_LIB = ", ''file2' /library" +$! +$! Print info +$! +$ WRITE SYS$OUTPUT "ZLIB library spec: ", file2 +$! +$! End The ZLIB Check. +$! +$ ENDIF +$! +$! Check To See If The User Entered A Valid Parameter. +$! +$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC") +$ THEN +$! +$! Check To See If The User Wanted DECC. +$! +$ IF (P3.EQS."DECC") +$ THEN +$! +$! Looks Like DECC, Set To Use DECC. +$! +$ COMPILER = "DECC" +$! +$! Tell The User We Are Using DECC. +$! +$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler." +$! +$! Use DECC... +$! +$ CC = "CC" +$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" - + THEN CC = "CC/DECC" +$ CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ - + "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + - + " /INCLUDE=(''CC_INCLUDES')"+ - + CCEXTRAFLAGS +$! +$! Define The Linker Options File Name. +$! +$ OPT_FILE = "VAX_DECC_OPTIONS.OPT" +$! +$! End DECC Check. +$! +$ ENDIF +$! +$! Check To See If We Are To Use VAXC. +$! +$ IF (P3.EQS."VAXC") +$ THEN +$! +$! Looks Like VAXC, Set To Use VAXC. +$! +$ COMPILER = "VAXC" +$! +$! Tell The User We Are Using VAX C. +$! +$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler." +$! +$! Compile Using VAXC. +$! +$ CC = "CC" +$ IF ARCH.NES."VAX" +$ THEN +$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!" +$ EXIT +$ ENDIF +$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC" +$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + - + "/INCLUDE=(''CC_INCLUDES')"+ - + CCEXTRAFLAGS +$ CCDEFS = """VAXC""," + CCDEFS +$! +$! Define As SYS$COMMON:[SYSLIB] +$! +$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB] +$! +$! Define The Linker Options File Name. +$! +$ OPT_FILE = "VAX_VAXC_OPTIONS.OPT" +$! +$! End VAXC Check +$! +$ ENDIF +$! +$! Check To See If We Are To Use GNU C. +$! +$ IF (P3.EQS."GNUC") +$ THEN +$! +$! Looks Like GNUC, Set To Use GNUC. +$! +$ COMPILER = "GNUC" +$! +$! Tell The User We Are Using GNUC. +$! +$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler." +$! +$! Use GNU C... +$! +$ CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + - + "/INCLUDE=(''CC_INCLUDES')"+ - + CCEXTRAFLAGS +$! +$! Define The Linker Options File Name. +$! +$ OPT_FILE = "VAX_GNUC_OPTIONS.OPT" +$! +$! End The GNU C Check. +$! +$ ENDIF +$! +$! Set up default defines +$! +$ CCDEFS = """FLAT_INC=1""," + CCDEFS +$! +$! Finish up the definition of CC. +$! +$ IF COMPILER .EQS. "DECC" +$ THEN +$! Not all compiler versions support MAYLOSEDATA3. +$ OPT_TEST = "MAYLOSEDATA3" +$ DEFINE /USER_MODE SYS$ERROR NL: +$ DEFINE /USER_MODE SYS$OUTPUT NL: +$ 'CC' /NOCROSS_REFERENCE /NOLIST /NOOBJECT - + /WARNINGS = DISABLE = ('OPT_TEST', EMPTYFILE) NL: +$ IF ($SEVERITY) +$ THEN +$ IF CCDISABLEWARNINGS .NES. "" THEN - + CCDISABLEWARNINGS = CCDISABLEWARNINGS+ "," +$ CCDISABLEWARNINGS = CCDISABLEWARNINGS+ OPT_TEST +$ ENDIF +$ IF CCDISABLEWARNINGS .EQS. "" +$ THEN +$ CC4DISABLEWARNINGS = "DOLLARID" +$ CC6DISABLEWARNINGS = "MIXLINKAGE" +$ ELSE +$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID" +$ CC6DISABLEWARNINGS = CCDISABLEWARNINGS + ",MIXLINKAGE" +$ CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))" +$ ENDIF +$ CC4DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))" +$ CC6DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC6DISABLEWARNINGS + "))" +$ ELSE +$ CCDISABLEWARNINGS = "" +$ CC4DISABLEWARNINGS = "" +$ CC6DISABLEWARNINGS = "" +$ ENDIF +$ CC3 = CC + " /DEFINE=(" + CCDEFS + ISSEVEN + ")" + CCDISABLEWARNINGS +$ CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS +$ IF ARCH .EQS. "VAX" .AND. COMPILER .EQS. "DECC" .AND. P2 .NES. "DEBUG" +$ THEN +$ CC5 = CC + " /OPTIMIZE=NODISJOINT" +$ CC5_DIFFERENT = 1 +$ ELSE +$ CC5 = CC +$ CC5_DIFFERENT = 0 +$ ENDIF +$ CC4 = CC - CCDISABLEWARNINGS + CC4DISABLEWARNINGS +$ CC6 = CC - CCDISABLEWARNINGS + CC6DISABLEWARNINGS +$! +$! Show user the result +$! +$ WRITE/SYMBOL SYS$OUTPUT "Main C Compiling Command: ",CC +$! +$! Else The User Entered An Invalid Argument. +$! +$ ELSE +$! +$! Tell The User We Don't Know What They Want. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C." +$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C." +$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$! End The Valid Argument Check. +$! +$ ENDIF +$! +$! Build a MACRO command for the architecture at hand +$! +$ IF ARCH .EQS. "VAX" THEN MACRO = "MACRO/''DEBUGGER'" +$ IF ARCH .NES. "VAX" THEN MACRO = "MACRO/MIGRATION/''DEBUGGER'/''MACRO_OPTIMIZE'" +$! +$! Show user the result +$! +$ WRITE/SYMBOL SYS$OUTPUT "Main MACRO Compiling Command: ",MACRO +$! +$! Time to check the contents, and to make sure we get the correct library. +$! +$ IF P4.EQS."SOCKETSHR" .OR. P4.EQS."MULTINET" .OR. P4.EQS."UCX" - + .OR. P4.EQS."TCPIP" .OR. P4.EQS."NONE" +$ THEN +$! +$! Check to see if SOCKETSHR was chosen +$! +$ IF P4.EQS."SOCKETSHR" +$ THEN +$! +$! Set the library to use SOCKETSHR +$! +$ TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS" +$! +$! Done with SOCKETSHR +$! +$ ENDIF +$! +$! Check to see if MULTINET was chosen +$! +$ IF P4.EQS."MULTINET" +$ THEN +$! +$! Set the library to use UCX emulation. +$! +$ P4 = "UCX" +$! +$! Done with MULTINET +$! +$ ENDIF +$! +$! Check to see if UCX was chosen +$! +$ IF P4.EQS."UCX" +$ THEN +$! +$! Set the library to use UCX. +$! +$ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS" +$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" +$ THEN +$ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS" +$ ELSE +$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN - + TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS" +$ ENDIF +$! +$! Done with UCX +$! +$ ENDIF +$! +$! Check to see if TCPIP was chosen +$! +$ IF P4.EQS."TCPIP" +$ THEN +$! +$! Set the library to use TCPIP (post UCX). +$! +$ TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS" +$! +$! Done with TCPIP +$! +$ ENDIF +$! +$! Check to see if NONE was chosen +$! +$ IF P4.EQS."NONE" +$ THEN +$! +$! Do not use a TCPIP library. +$! +$ TCPIP_LIB = "" +$! +$! Done with TCPIP +$! +$ ENDIF +$! +$! Print info +$! +$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- "," +$! +$! Else The User Entered An Invalid Argument. +$! +$ ELSE +$! +$! Tell The User We Don't Know What They Want. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P4," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library." +$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library." +$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$! Done with TCP/IP libraries +$! +$ ENDIF +$! +$! Check if the user wanted to compile just a subset of all the encryption +$! methods. +$! +$ IF P6 .NES. "" +$ THEN +$ ENCRYPT_TYPES = P6 +$ ENDIF +$! +$! Time To RETURN... +$! +$ RETURN +$! +$ INITIALISE: +$! +$! Save old value of the logical name OPENSSL +$! +$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE") +$! +$! Save directory information +$! +$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;" +$ __HERE = F$EDIT(__HERE,"UPCASE") +$ __TOP = __HERE - "CRYPTO]" +$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]" +$! +$! Set up the logical name OPENSSL to point at the include directory +$! +$ DEFINE OPENSSL/NOLOG '__INCLUDE' +$! +$! Done +$! +$ RETURN +$! +$ CLEANUP: +$! +$! Restore the logical name OPENSSL if it had a value +$! +$ IF __SAVE_OPENSSL .EQS. "" +$ THEN +$ DEASSIGN OPENSSL +$ ELSE +$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL' +$ ENDIF +$! +$! Done +$! +$ RETURN diff --git a/libs/openssl/crypto/crypto.h b/libs/openssl/crypto/crypto.h new file mode 100644 index 00000000..c450d7a3 --- /dev/null +++ b/libs/openssl/crypto/crypto.h @@ -0,0 +1,661 @@ +/* crypto/crypto.h */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_CRYPTO_H +# define HEADER_CRYPTO_H + +# include + +# include + +# ifndef OPENSSL_NO_FP_API +# include +# endif + +# include +# include +# include +# include + +# ifdef CHARSET_EBCDIC +# include +# endif + +/* + * Resolve problems on some operating systems with symbol names that clash + * one way or another + */ +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Backward compatibility to SSLeay */ +/* + * This is more to be used to check the correct DLL is being used in the MS + * world. + */ +# define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER +# define SSLEAY_VERSION 0 +/* #define SSLEAY_OPTIONS 1 no longer supported */ +# define SSLEAY_CFLAGS 2 +# define SSLEAY_BUILT_ON 3 +# define SSLEAY_PLATFORM 4 +# define SSLEAY_DIR 5 + +/* Already declared in ossl_typ.h */ +# if 0 +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; +/* Called when a new object is created */ +typedef int CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +/* Called when an object is free()ed */ +typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +/* Called when we need to dup an object */ +typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, + void *from_d, int idx, long argl, void *argp); +# endif + +/* A generic structure to pass assorted data in a expandable way */ +typedef struct openssl_item_st { + int code; + void *value; /* Not used for flag attributes */ + size_t value_size; /* Max size of value for output, length for + * input */ + size_t *value_length; /* Returned length of value for output */ +} OPENSSL_ITEM; + +/* + * When changing the CRYPTO_LOCK_* list, be sure to maintin the text lock + * names in cryptlib.c + */ + +# define CRYPTO_LOCK_ERR 1 +# define CRYPTO_LOCK_EX_DATA 2 +# define CRYPTO_LOCK_X509 3 +# define CRYPTO_LOCK_X509_INFO 4 +# define CRYPTO_LOCK_X509_PKEY 5 +# define CRYPTO_LOCK_X509_CRL 6 +# define CRYPTO_LOCK_X509_REQ 7 +# define CRYPTO_LOCK_DSA 8 +# define CRYPTO_LOCK_RSA 9 +# define CRYPTO_LOCK_EVP_PKEY 10 +# define CRYPTO_LOCK_X509_STORE 11 +# define CRYPTO_LOCK_SSL_CTX 12 +# define CRYPTO_LOCK_SSL_CERT 13 +# define CRYPTO_LOCK_SSL_SESSION 14 +# define CRYPTO_LOCK_SSL_SESS_CERT 15 +# define CRYPTO_LOCK_SSL 16 +# define CRYPTO_LOCK_SSL_METHOD 17 +# define CRYPTO_LOCK_RAND 18 +# define CRYPTO_LOCK_RAND2 19 +# define CRYPTO_LOCK_MALLOC 20 +# define CRYPTO_LOCK_BIO 21 +# define CRYPTO_LOCK_GETHOSTBYNAME 22 +# define CRYPTO_LOCK_GETSERVBYNAME 23 +# define CRYPTO_LOCK_READDIR 24 +# define CRYPTO_LOCK_RSA_BLINDING 25 +# define CRYPTO_LOCK_DH 26 +# define CRYPTO_LOCK_MALLOC2 27 +# define CRYPTO_LOCK_DSO 28 +# define CRYPTO_LOCK_DYNLOCK 29 +# define CRYPTO_LOCK_ENGINE 30 +# define CRYPTO_LOCK_UI 31 +# define CRYPTO_LOCK_ECDSA 32 +# define CRYPTO_LOCK_EC 33 +# define CRYPTO_LOCK_ECDH 34 +# define CRYPTO_LOCK_BN 35 +# define CRYPTO_LOCK_EC_PRE_COMP 36 +# define CRYPTO_LOCK_STORE 37 +# define CRYPTO_LOCK_COMP 38 +# define CRYPTO_LOCK_FIPS 39 +# define CRYPTO_LOCK_FIPS2 40 +# define CRYPTO_NUM_LOCKS 41 + +# define CRYPTO_LOCK 1 +# define CRYPTO_UNLOCK 2 +# define CRYPTO_READ 4 +# define CRYPTO_WRITE 8 + +# ifndef OPENSSL_NO_LOCKING +# ifndef CRYPTO_w_lock +# define CRYPTO_w_lock(type) \ + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) +# define CRYPTO_w_unlock(type) \ + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,__FILE__,__LINE__) +# define CRYPTO_r_lock(type) \ + CRYPTO_lock(CRYPTO_LOCK|CRYPTO_READ,type,__FILE__,__LINE__) +# define CRYPTO_r_unlock(type) \ + CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_READ,type,__FILE__,__LINE__) +# define CRYPTO_add(addr,amount,type) \ + CRYPTO_add_lock(addr,amount,type,__FILE__,__LINE__) +# endif +# else +# define CRYPTO_w_lock(a) +# define CRYPTO_w_unlock(a) +# define CRYPTO_r_lock(a) +# define CRYPTO_r_unlock(a) +# define CRYPTO_add(a,b,c) ((*(a))+=(b)) +# endif + +/* + * Some applications as well as some parts of OpenSSL need to allocate and + * deallocate locks in a dynamic fashion. The following typedef makes this + * possible in a type-safe manner. + */ +/* struct CRYPTO_dynlock_value has to be defined by the application. */ +typedef struct { + int references; + struct CRYPTO_dynlock_value *data; +} CRYPTO_dynlock; + +/* + * The following can be used to detect memory leaks in the SSLeay library. It + * used, it turns on malloc checking + */ + +# define CRYPTO_MEM_CHECK_OFF 0x0/* an enume */ +# define CRYPTO_MEM_CHECK_ON 0x1/* a bit */ +# define CRYPTO_MEM_CHECK_ENABLE 0x2/* a bit */ +# define CRYPTO_MEM_CHECK_DISABLE 0x3/* an enume */ + +/* + * The following are bit values to turn on or off options connected to the + * malloc checking functionality + */ + +/* Adds time to the memory checking information */ +# define V_CRYPTO_MDEBUG_TIME 0x1/* a bit */ +/* Adds thread number to the memory checking information */ +# define V_CRYPTO_MDEBUG_THREAD 0x2/* a bit */ + +# define V_CRYPTO_MDEBUG_ALL (V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD) + +/* predec of the BIO type */ +typedef struct bio_st BIO_dummy; + +struct crypto_ex_data_st { + STACK_OF(void) *sk; + /* gcc is screwing up this data structure :-( */ + int dummy; +}; +DECLARE_STACK_OF(void) + +/* + * This stuff is basically class callback functions The current classes are + * SSL_CTX, SSL, SSL_SESSION, and a few more + */ + +typedef struct crypto_ex_data_func_st { + long argl; /* Arbitary long */ + void *argp; /* Arbitary void * */ + CRYPTO_EX_new *new_func; + CRYPTO_EX_free *free_func; + CRYPTO_EX_dup *dup_func; +} CRYPTO_EX_DATA_FUNCS; + +DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS) + +/* + * Per class, we have a STACK of CRYPTO_EX_DATA_FUNCS for each CRYPTO_EX_DATA + * entry. + */ + +# define CRYPTO_EX_INDEX_BIO 0 +# define CRYPTO_EX_INDEX_SSL 1 +# define CRYPTO_EX_INDEX_SSL_CTX 2 +# define CRYPTO_EX_INDEX_SSL_SESSION 3 +# define CRYPTO_EX_INDEX_X509_STORE 4 +# define CRYPTO_EX_INDEX_X509_STORE_CTX 5 +# define CRYPTO_EX_INDEX_RSA 6 +# define CRYPTO_EX_INDEX_DSA 7 +# define CRYPTO_EX_INDEX_DH 8 +# define CRYPTO_EX_INDEX_ENGINE 9 +# define CRYPTO_EX_INDEX_X509 10 +# define CRYPTO_EX_INDEX_UI 11 +# define CRYPTO_EX_INDEX_ECDSA 12 +# define CRYPTO_EX_INDEX_ECDH 13 +# define CRYPTO_EX_INDEX_COMP 14 +# define CRYPTO_EX_INDEX_STORE 15 + +/* + * Dynamically assigned indexes start from this value (don't use directly, + * use via CRYPTO_ex_data_new_class). + */ +# define CRYPTO_EX_INDEX_USER 100 + +/* + * This is the default callbacks, but we can have others as well: this is + * needed in Win32 where the application malloc and the library malloc may + * not be the same. + */ +# define CRYPTO_malloc_init() CRYPTO_set_mem_functions(\ + malloc, realloc, free) + +# if defined CRYPTO_MDEBUG_ALL || defined CRYPTO_MDEBUG_TIME || defined CRYPTO_MDEBUG_THREAD +# ifndef CRYPTO_MDEBUG /* avoid duplicate #define */ +# define CRYPTO_MDEBUG +# endif +# endif + +/* + * Set standard debugging functions (not done by default unless CRYPTO_MDEBUG + * is defined) + */ +# define CRYPTO_malloc_debug_init() do {\ + CRYPTO_set_mem_debug_functions(\ + CRYPTO_dbg_malloc,\ + CRYPTO_dbg_realloc,\ + CRYPTO_dbg_free,\ + CRYPTO_dbg_set_options,\ + CRYPTO_dbg_get_options);\ + } while(0) + +int CRYPTO_mem_ctrl(int mode); +int CRYPTO_is_mem_check_on(void); + +/* for applications */ +# define MemCheck_start() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON) +# define MemCheck_stop() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF) + +/* for library-internal use */ +# define MemCheck_on() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE) +# define MemCheck_off() CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE) +# define is_MemCheck_on() CRYPTO_is_mem_check_on() + +# define OPENSSL_malloc(num) CRYPTO_malloc((int)num,__FILE__,__LINE__) +# define OPENSSL_strdup(str) CRYPTO_strdup((str),__FILE__,__LINE__) +# define OPENSSL_realloc(addr,num) \ + CRYPTO_realloc((char *)addr,(int)num,__FILE__,__LINE__) +# define OPENSSL_realloc_clean(addr,old_num,num) \ + CRYPTO_realloc_clean(addr,old_num,num,__FILE__,__LINE__) +# define OPENSSL_remalloc(addr,num) \ + CRYPTO_remalloc((char **)addr,(int)num,__FILE__,__LINE__) +# define OPENSSL_freeFunc CRYPTO_free +# define OPENSSL_free(addr) CRYPTO_free(addr) + +# define OPENSSL_malloc_locked(num) \ + CRYPTO_malloc_locked((int)num,__FILE__,__LINE__) +# define OPENSSL_free_locked(addr) CRYPTO_free_locked(addr) + +const char *SSLeay_version(int type); +unsigned long SSLeay(void); + +int OPENSSL_issetugid(void); + +/* An opaque type representing an implementation of "ex_data" support */ +typedef struct st_CRYPTO_EX_DATA_IMPL CRYPTO_EX_DATA_IMPL; +/* Return an opaque pointer to the current "ex_data" implementation */ +const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void); +/* Sets the "ex_data" implementation to be used (if it's not too late) */ +int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i); +/* Get a new "ex_data" class, and return the corresponding "class_index" */ +int CRYPTO_ex_data_new_class(void); +/* Within a given class, get/register a new index */ +int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +/* + * Initialise/duplicate/free CRYPTO_EX_DATA variables corresponding to a + * given class (invokes whatever per-class callbacks are applicable) + */ +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from); +void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +/* + * Get/set data in a CRYPTO_EX_DATA variable corresponding to a particular + * index (relative to the class type involved) + */ +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val); +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx); +/* + * This function cleans up all "ex_data" state. It mustn't be called under + * potential race-conditions. + */ +void CRYPTO_cleanup_all_ex_data(void); + +int CRYPTO_get_new_lockid(char *name); + +int CRYPTO_num_locks(void); /* return CRYPTO_NUM_LOCKS (shared libs!) */ +void CRYPTO_lock(int mode, int type, const char *file, int line); +void CRYPTO_set_locking_callback(void (*func) (int mode, int type, + const char *file, int line)); +void (*CRYPTO_get_locking_callback(void)) (int mode, int type, + const char *file, int line); +void CRYPTO_set_add_lock_callback(int (*func) + (int *num, int mount, int type, + const char *file, int line)); +int (*CRYPTO_get_add_lock_callback(void)) (int *num, int mount, int type, + const char *file, int line); + +/* Don't use this structure directly. */ +typedef struct crypto_threadid_st { + void *ptr; + unsigned long val; +} CRYPTO_THREADID; +/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */ +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val); +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); +int CRYPTO_THREADID_set_callback(void (*threadid_func) (CRYPTO_THREADID *)); +void (*CRYPTO_THREADID_get_callback(void)) (CRYPTO_THREADID *); +void CRYPTO_THREADID_current(CRYPTO_THREADID *id); +int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b); +void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src); +unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id); +# ifndef OPENSSL_NO_DEPRECATED +void CRYPTO_set_id_callback(unsigned long (*func) (void)); +unsigned long (*CRYPTO_get_id_callback(void)) (void); +unsigned long CRYPTO_thread_id(void); +# endif + +const char *CRYPTO_get_lock_name(int type); +int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, + int line); + +int CRYPTO_get_new_dynlockid(void); +void CRYPTO_destroy_dynlockid(int i); +struct CRYPTO_dynlock_value *CRYPTO_get_dynlock_value(int i); +void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value + *(*dyn_create_function) (const char + *file, + int line)); +void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function) + (int mode, + struct CRYPTO_dynlock_value *l, + const char *file, int line)); +void CRYPTO_set_dynlock_destroy_callback(void (*dyn_destroy_function) + (struct CRYPTO_dynlock_value *l, + const char *file, int line)); +struct CRYPTO_dynlock_value +*(*CRYPTO_get_dynlock_create_callback(void)) (const char *file, int line); +void (*CRYPTO_get_dynlock_lock_callback(void)) (int mode, + struct CRYPTO_dynlock_value + *l, const char *file, + int line); +void (*CRYPTO_get_dynlock_destroy_callback(void)) (struct CRYPTO_dynlock_value + *l, const char *file, + int line); + +/* + * CRYPTO_set_mem_functions includes CRYPTO_set_locked_mem_functions -- call + * the latter last if you need different functions + */ +int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t), + void (*f) (void *)); +int CRYPTO_set_locked_mem_functions(void *(*m) (size_t), + void (*free_func) (void *)); +int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int), + void *(*r) (void *, size_t, const char *, + int), void (*f) (void *)); +int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int), + void (*free_func) (void *)); +int CRYPTO_set_mem_debug_functions(void (*m) + (void *, int, const char *, int, int), + void (*r) (void *, void *, int, + const char *, int, int), + void (*f) (void *, int), void (*so) (long), + long (*go) (void)); +void CRYPTO_get_mem_functions(void *(**m) (size_t), + void *(**r) (void *, size_t), + void (**f) (void *)); +void CRYPTO_get_locked_mem_functions(void *(**m) (size_t), + void (**f) (void *)); +void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int), + void *(**r) (void *, size_t, const char *, + int), void (**f) (void *)); +void CRYPTO_get_locked_mem_ex_functions(void + *(**m) (size_t, const char *, int), + void (**f) (void *)); +void CRYPTO_get_mem_debug_functions(void (**m) + (void *, int, const char *, int, int), + void (**r) (void *, void *, int, + const char *, int, int), + void (**f) (void *, int), + void (**so) (long), long (**go) (void)); + +void *CRYPTO_malloc_locked(int num, const char *file, int line); +void CRYPTO_free_locked(void *ptr); +void *CRYPTO_malloc(int num, const char *file, int line); +char *CRYPTO_strdup(const char *str, const char *file, int line); +void CRYPTO_free(void *ptr); +void *CRYPTO_realloc(void *addr, int num, const char *file, int line); +void *CRYPTO_realloc_clean(void *addr, int old_num, int num, const char *file, + int line); +void *CRYPTO_remalloc(void *addr, int num, const char *file, int line); + +void OPENSSL_cleanse(void *ptr, size_t len); + +void CRYPTO_set_mem_debug_options(long bits); +long CRYPTO_get_mem_debug_options(void); + +# define CRYPTO_push_info(info) \ + CRYPTO_push_info_(info, __FILE__, __LINE__); +int CRYPTO_push_info_(const char *info, const char *file, int line); +int CRYPTO_pop_info(void); +int CRYPTO_remove_all_info(void); + +/* + * Default debugging functions (enabled by CRYPTO_malloc_debug_init() macro; + * used as default in CRYPTO_MDEBUG compilations): + */ +/*- + * The last argument has the following significance: + * + * 0: called before the actual memory allocation has taken place + * 1: called after the actual memory allocation has taken place + */ +void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, + int before_p); +void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, const char *file, + int line, int before_p); +void CRYPTO_dbg_free(void *addr, int before_p); +/*- + * Tell the debugging code about options. By default, the following values + * apply: + * + * 0: Clear all options. + * V_CRYPTO_MDEBUG_TIME (1): Set the "Show Time" option. + * V_CRYPTO_MDEBUG_THREAD (2): Set the "Show Thread Number" option. + * V_CRYPTO_MDEBUG_ALL (3): 1 + 2 + */ +void CRYPTO_dbg_set_options(long bits); +long CRYPTO_dbg_get_options(void); + +# ifndef OPENSSL_NO_FP_API +void CRYPTO_mem_leaks_fp(FILE *); +# endif +void CRYPTO_mem_leaks(struct bio_st *bio); +/* unsigned long order, char *file, int line, int num_bytes, char *addr */ +typedef void *CRYPTO_MEM_LEAK_CB (unsigned long, const char *, int, int, + void *); +void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb); + +/* die if we have to */ +void OpenSSLDie(const char *file, int line, const char *assertion); +# define OPENSSL_assert(e) (void)((e) ? 0 : (OpenSSLDie(__FILE__, __LINE__, #e),1)) + +unsigned long *OPENSSL_ia32cap_loc(void); +# define OPENSSL_ia32cap (*(OPENSSL_ia32cap_loc())) +int OPENSSL_isservice(void); + +int FIPS_mode(void); +int FIPS_mode_set(int r); + +void OPENSSL_init(void); + +# define fips_md_init(alg) fips_md_init_ctx(alg, alg) + +# ifdef OPENSSL_FIPS +# define fips_md_init_ctx(alg, cx) \ + int alg##_Init(cx##_CTX *c) \ + { \ + if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \ + "Low level API call to digest " #alg " forbidden in FIPS mode!"); \ + return private_##alg##_Init(c); \ + } \ + int private_##alg##_Init(cx##_CTX *c) + +# define fips_cipher_abort(alg) \ + if (FIPS_mode()) OpenSSLDie(__FILE__, __LINE__, \ + "Low level API call to cipher " #alg " forbidden in FIPS mode!") + +# else +# define fips_md_init_ctx(alg, cx) \ + int alg##_Init(cx##_CTX *c) +# define fips_cipher_abort(alg) while(0) +# endif + +/* + * CRYPTO_memcmp returns zero iff the |len| bytes at |a| and |b| are equal. + * It takes an amount of time dependent on |len|, but independent of the + * contents of |a| and |b|. Unlike memcmp, it cannot be used to put elements + * into a defined order as the return value when a != b is undefined, other + * than to be non-zero. + */ +int CRYPTO_memcmp(const void *a, const void *b, size_t len); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_CRYPTO_strings(void); + +/* Error codes for the CRYPTO functions. */ + +/* Function codes. */ +# define CRYPTO_F_CRYPTO_GET_EX_NEW_INDEX 100 +# define CRYPTO_F_CRYPTO_GET_NEW_DYNLOCKID 103 +# define CRYPTO_F_CRYPTO_GET_NEW_LOCKID 101 +# define CRYPTO_F_CRYPTO_SET_EX_DATA 102 +# define CRYPTO_F_DEF_ADD_INDEX 104 +# define CRYPTO_F_DEF_GET_CLASS 105 +# define CRYPTO_F_FIPS_MODE_SET 109 +# define CRYPTO_F_INT_DUP_EX_DATA 106 +# define CRYPTO_F_INT_FREE_EX_DATA 107 +# define CRYPTO_F_INT_NEW_EX_DATA 108 + +/* Reason codes. */ +# define CRYPTO_R_FIPS_MODE_NOT_SUPPORTED 101 +# define CRYPTO_R_NO_DYNLOCK_CREATE_CALLBACK 100 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/cversion.c b/libs/openssl/crypto/cversion.c new file mode 100644 index 00000000..9e6f50d7 --- /dev/null +++ b/libs/openssl/crypto/cversion.c @@ -0,0 +1,103 @@ +/* crypto/cversion.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "cryptlib.h" + +#ifndef NO_WINDOWS_BRAINDEATH +# include "buildinf.h" +#endif + +const char *SSLeay_version(int t) +{ + if (t == SSLEAY_VERSION) + return OPENSSL_VERSION_TEXT; + if (t == SSLEAY_BUILT_ON) { +#ifdef DATE + return (DATE); +#else + return ("built on: date not available"); +#endif + } + if (t == SSLEAY_CFLAGS) { +#ifdef CFLAGS + return (CFLAGS); +#else + return ("compiler: information not available"); +#endif + } + if (t == SSLEAY_PLATFORM) { +#ifdef PLATFORM + return (PLATFORM); +#else + return ("platform: information not available"); +#endif + } + if (t == SSLEAY_DIR) { +#ifdef OPENSSLDIR + return "OPENSSLDIR: \"" OPENSSLDIR "\""; +#else + return "OPENSSLDIR: N/A"; +#endif + } + return ("not available"); +} + +unsigned long SSLeay(void) +{ + return (SSLEAY_VERSION_NUMBER); +} diff --git a/libs/openssl/crypto/des/COPYRIGHT b/libs/openssl/crypto/des/COPYRIGHT new file mode 100644 index 00000000..5469e1e4 --- /dev/null +++ b/libs/openssl/crypto/des/COPYRIGHT @@ -0,0 +1,50 @@ +Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +All rights reserved. + +This package is an DES implementation written by Eric Young (eay@cryptsoft.com). +The implementation was written so as to conform with MIT's libdes. + +This library is free for commercial and non-commercial use as long as +the following conditions are aheared to. The following conditions +apply to all code found in this distribution. + +Copyright remains Eric Young's, and as such any Copyright notices in +the code are not to be removed. +If this package is used in a product, Eric Young should be given attribution +as the author of that the SSL library. This can be in the form of a textual +message at program startup or in documentation (online or textual) provided +with the package. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + This product includes software developed by Eric Young (eay@cryptsoft.com) + +THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +SUCH DAMAGE. + +The license and distribution terms for any publically available version or +derivative of this code cannot be changed. i.e. this code cannot simply be +copied and put under another distrubution license +[including the GNU Public License.] + +The reason behind this being stated in this direct manner is past +experience in code simply being copied and the attribution removed +from it and then being distributed as part of other packages. This +implementation was a non-trivial and unpaid effort. diff --git a/libs/openssl/crypto/des/DES.pm b/libs/openssl/crypto/des/DES.pm new file mode 100644 index 00000000..6a175b6c --- /dev/null +++ b/libs/openssl/crypto/des/DES.pm @@ -0,0 +1,19 @@ +package DES; + +require Exporter; +require DynaLoader; +@ISA = qw(Exporter DynaLoader); +# Items to export into callers namespace by default +# (move infrequently used names to @EXPORT_OK below) +@EXPORT = qw( +); +# Other items we are prepared to export if requested +@EXPORT_OK = qw( +crypt +); + +# Preloaded methods go here. Autoload methods go after __END__, and are +# processed by the autosplit program. +bootstrap DES; +1; +__END__ diff --git a/libs/openssl/crypto/des/DES.xs b/libs/openssl/crypto/des/DES.xs new file mode 100644 index 00000000..b8050b9e --- /dev/null +++ b/libs/openssl/crypto/des/DES.xs @@ -0,0 +1,268 @@ +#include "EXTERN.h" +#include "perl.h" +#include "XSUB.h" +#include "des.h" + +#define deschar char +static STRLEN len; + +static int +not_here(s) +char *s; +{ + croak("%s not implemented on this architecture", s); + return -1; +} + +MODULE = DES PACKAGE = DES PREFIX = des_ + +char * +des_crypt(buf,salt) + char * buf + char * salt + +void +des_set_odd_parity(key) + des_cblock * key +PPCODE: + { + SV *s; + + s=sv_newmortal(); + sv_setpvn(s,(char *)key,8); + des_set_odd_parity((des_cblock *)SvPV(s,na)); + PUSHs(s); + } + +int +des_is_weak_key(key) + des_cblock * key + +des_key_schedule +des_set_key(key) + des_cblock * key +CODE: + des_set_key(key,RETVAL); +OUTPUT: +RETVAL + +des_cblock +des_ecb_encrypt(input,ks,encrypt) + des_cblock * input + des_key_schedule * ks + int encrypt +CODE: + des_ecb_encrypt(input,&RETVAL,*ks,encrypt); +OUTPUT: +RETVAL + +void +des_cbc_encrypt(input,ks,ivec,encrypt) + char * input + des_key_schedule * ks + des_cblock * ivec + int encrypt +PPCODE: + { + SV *s; + STRLEN len,l; + char *c; + + l=SvCUR(ST(0)); + len=((((unsigned long)l)+7)/8)*8; + s=sv_newmortal(); + sv_setpvn(s,"",0); + SvGROW(s,len); + SvCUR_set(s,len); + c=(char *)SvPV(s,na); + des_cbc_encrypt((des_cblock *)input,(des_cblock *)c, + l,*ks,ivec,encrypt); + sv_setpvn(ST(2),(char *)c[len-8],8); + PUSHs(s); + } + +void +des_cbc3_encrypt(input,ks1,ks2,ivec1,ivec2,encrypt) + char * input + des_key_schedule * ks1 + des_key_schedule * ks2 + des_cblock * ivec1 + des_cblock * ivec2 + int encrypt +PPCODE: + { + SV *s; + STRLEN len,l; + + l=SvCUR(ST(0)); + len=((((unsigned long)l)+7)/8)*8; + s=sv_newmortal(); + sv_setpvn(s,"",0); + SvGROW(s,len); + SvCUR_set(s,len); + des_3cbc_encrypt((des_cblock *)input,(des_cblock *)SvPV(s,na), + l,*ks1,*ks2,ivec1,ivec2,encrypt); + sv_setpvn(ST(3),(char *)ivec1,8); + sv_setpvn(ST(4),(char *)ivec2,8); + PUSHs(s); + } + +void +des_cbc_cksum(input,ks,ivec) + char * input + des_key_schedule * ks + des_cblock * ivec +PPCODE: + { + SV *s1,*s2; + STRLEN len,l; + des_cblock c; + unsigned long i1,i2; + + s1=sv_newmortal(); + s2=sv_newmortal(); + l=SvCUR(ST(0)); + des_cbc_cksum((des_cblock *)input,(des_cblock *)c, + l,*ks,ivec); + i1=c[4]|(c[5]<<8)|(c[6]<<16)|(c[7]<<24); + i2=c[0]|(c[1]<<8)|(c[2]<<16)|(c[3]<<24); + sv_setiv(s1,i1); + sv_setiv(s2,i2); + sv_setpvn(ST(2),(char *)c,8); + PUSHs(s1); + PUSHs(s2); + } + +void +des_cfb_encrypt(input,numbits,ks,ivec,encrypt) + char * input + int numbits + des_key_schedule * ks + des_cblock * ivec + int encrypt +PPCODE: + { + SV *s; + STRLEN len; + char *c; + + len=SvCUR(ST(0)); + s=sv_newmortal(); + sv_setpvn(s,"",0); + SvGROW(s,len); + SvCUR_set(s,len); + c=(char *)SvPV(s,na); + des_cfb_encrypt((unsigned char *)input,(unsigned char *)c, + (int)numbits,(long)len,*ks,ivec,encrypt); + sv_setpvn(ST(3),(char *)ivec,8); + PUSHs(s); + } + +des_cblock * +des_ecb3_encrypt(input,ks1,ks2,encrypt) + des_cblock * input + des_key_schedule * ks1 + des_key_schedule * ks2 + int encrypt +CODE: + { + des_cblock c; + + des_ecb3_encrypt((des_cblock *)input,(des_cblock *)&c, + *ks1,*ks2,encrypt); + RETVAL= &c; + } +OUTPUT: +RETVAL + +void +des_ofb_encrypt(input,numbits,ks,ivec) + unsigned char * input + int numbits + des_key_schedule * ks + des_cblock * ivec +PPCODE: + { + SV *s; + STRLEN len,l; + unsigned char *c; + + len=SvCUR(ST(0)); + s=sv_newmortal(); + sv_setpvn(s,"",0); + SvGROW(s,len); + SvCUR_set(s,len); + c=(unsigned char *)SvPV(s,na); + des_ofb_encrypt((unsigned char *)input,(unsigned char *)c, + numbits,len,*ks,ivec); + sv_setpvn(ST(3),(char *)ivec,8); + PUSHs(s); + } + +void +des_pcbc_encrypt(input,ks,ivec,encrypt) + char * input + des_key_schedule * ks + des_cblock * ivec + int encrypt +PPCODE: + { + SV *s; + STRLEN len,l; + char *c; + + l=SvCUR(ST(0)); + len=((((unsigned long)l)+7)/8)*8; + s=sv_newmortal(); + sv_setpvn(s,"",0); + SvGROW(s,len); + SvCUR_set(s,len); + c=(char *)SvPV(s,na); + des_pcbc_encrypt((des_cblock *)input,(des_cblock *)c, + l,*ks,ivec,encrypt); + sv_setpvn(ST(2),(char *)c[len-8],8); + PUSHs(s); + } + +des_cblock * +des_random_key() +CODE: + { + des_cblock c; + + des_random_key(c); + RETVAL=&c; + } +OUTPUT: +RETVAL + +des_cblock * +des_string_to_key(str) +char * str +CODE: + { + des_cblock c; + + des_string_to_key(str,&c); + RETVAL=&c; + } +OUTPUT: +RETVAL + +void +des_string_to_2keys(str) +char * str +PPCODE: + { + des_cblock c1,c2; + SV *s1,*s2; + + des_string_to_2keys(str,&c1,&c2); + EXTEND(sp,2); + s1=sv_newmortal(); + sv_setpvn(s1,(char *)c1,8); + s2=sv_newmortal(); + sv_setpvn(s2,(char *)c2,8); + PUSHs(s1); + PUSHs(s2); + } diff --git a/libs/openssl/crypto/des/FILES0 b/libs/openssl/crypto/des/FILES0 new file mode 100644 index 00000000..4c7ea2de --- /dev/null +++ b/libs/openssl/crypto/des/FILES0 @@ -0,0 +1,96 @@ +/* General stuff */ +COPYRIGHT - Copyright info. +MODES.DES - A description of the features of the different modes of DES. +FILES - This file. +INSTALL - How to make things compile. +Imakefile - For use with kerberos. +README - What this package is. +VERSION - Which version this is and what was changed. +KERBEROS - Kerberos version 4 notes. +Makefile.PL - An old makefile to build with perl5, not current. +Makefile.ssl - The SSLeay makefile +Makefile.uni - The normal unix makefile. +GNUmakefile - The makefile for use with glibc. +makefile.bc - A Borland C makefile +times - Some outputs from 'speed' on some machines. +vms.com - For use when compiling under VMS + +/* My SunOS des(1) replacement */ +des.c - des(1) source code. +des.man - des(1) manual. + +/* Testing and timing programs. */ +destest.c - Source for libdes.a test program. +speed.c - Source for libdes.a timing program. +rpw.c - Source for libdes.a testing password reading routines. + +/* libdes.a source code */ +des_crypt.man - libdes.a manual page. +des.h - Public libdes.a header file. +ecb_enc.c - des_ecb_encrypt() source, this contains the basic DES code. +ecb3_enc.c - des_ecb3_encrypt() source. +cbc_ckm.c - des_cbc_cksum() source. +cbc_enc.c - des_cbc_encrypt() source. +ncbc_enc.c - des_cbc_encrypt() that is 'normal' in that it copies + the new iv values back in the passed iv vector. +ede_enc.c - des_ede3_cbc_encrypt() cbc mode des using triple DES. +cbc3_enc.c - des_3cbc_encrypt() source, don't use this function. +cfb_enc.c - des_cfb_encrypt() source. +cfb64enc.c - des_cfb64_encrypt() cfb in 64 bit mode but setup to be + used as a stream cipher. +cfb64ede.c - des_ede3_cfb64_encrypt() cfb in 64 bit mode but setup to be + used as a stream cipher and using triple DES. +ofb_enc.c - des_cfb_encrypt() source. +ofb64_enc.c - des_ofb_encrypt() ofb in 64 bit mode but setup to be + used as a stream cipher. +ofb64ede.c - des_ede3_ofb64_encrypt() ofb in 64 bit mode but setup to be + used as a stream cipher and using triple DES. +enc_read.c - des_enc_read() source. +enc_writ.c - des_enc_write() source. +pcbc_enc.c - des_pcbc_encrypt() source. +qud_cksm.c - quad_cksum() source. +rand_key.c - des_random_key() source. +read_pwd.c - Source for des_read_password() plus related functions. +set_key.c - Source for des_set_key(). +str2key.c - Covert a string of any length into a key. +fcrypt.c - A small, fast version of crypt(3). +des_locl.h - Internal libdes.a header file. +podd.h - Odd parity tables - used in des_set_key(). +sk.h - Lookup tables used in des_set_key(). +spr.h - What is left of the S tables - used in ecb_encrypt(). +des_ver.h - header file for the external definition of the + version string. +des.doc - SSLeay documentation for the library. + +/* The perl scripts - you can ignore these files they are only + * included for the curious */ +des.pl - des in perl anyone? des_set_key and des_ecb_encrypt + both done in a perl library. +testdes.pl - Testing program for des.pl +doIP - Perl script used to develop IP xor/shift code. +doPC1 - Perl script used to develop PC1 xor/shift code. +doPC2 - Generates sk.h. +PC1 - Output of doPC1 should be the same as output from PC1. +PC2 - used in development of doPC2. +shifts.pl - Perl library used by my perl scripts. + +/* I started making a perl5 dynamic library for libdes + * but did not fully finish, these files are part of that effort. */ +DES.pm +DES.pod +DES.xs +t +typemap + +/* The following are for use with sun RPC implementaions. */ +rpc_des.h +rpc_enc.c + +/* The following are contibuted by Mark Murray . They + * are not normally built into libdes due to machine specific routines + * contained in them. They are for use in the most recent incarnation of + * export kerberos v 4 (eBones). */ +supp.c +new_rkey.c + + diff --git a/libs/openssl/crypto/des/INSTALL b/libs/openssl/crypto/des/INSTALL new file mode 100644 index 00000000..8aebdfe1 --- /dev/null +++ b/libs/openssl/crypto/des/INSTALL @@ -0,0 +1,69 @@ +Check the CC and CFLAGS lines in the makefile + +If your C library does not support the times(3) function, change the +#define TIMES to +#undef TIMES in speed.c +If it does, check the HZ value for the times(3) function. +If your system does not define CLK_TCK it will be assumed to +be 100.0. + +If possible use gcc v 2.7.? +Turn on the maximum optimising (normally '-O3 -fomit-frame-pointer' for gcc) +In recent times, some system compilers give better performace. + +type 'make' + +run './destest' to check things are ok. +run './rpw' to check the tty code for reading passwords works. +run './speed' to see how fast those optimisations make the library run :-) +run './des_opts' to determin the best compile time options. + +The output from des_opts should be put in the makefile options and des_enc.c +should be rebuilt. For 64 bit computers, do not use the DES_PTR option. +For the DEC Alpha, edit des.h and change DES_LONG to 'unsigned int' +and then you can use the 'DES_PTR' option. + +The file options.txt has the options listed for best speed on quite a +few systems. Look and the options (UNROLL, PTR, RISC2 etc) and then +turn on the relevant option in the Makefile. + +There are some special Makefile targets that make life easier. +make cc - standard cc build +make gcc - standard gcc build +make x86-elf - x86 assembler (elf), linux-elf. +make x86-out - x86 assembler (a.out), FreeBSD +make x86-solaris- x86 assembler +make x86-bsdi - x86 assembler (a.out with primative assembler). + +If at all possible use the assembler (for Windows NT/95, use +asm/win32.obj to link with). The x86 assembler is very very fast. + +A make install will by default install +libdes.a in /usr/local/lib/libdes.a +des in /usr/local/bin/des +des_crypt.man in /usr/local/man/man3/des_crypt.3 +des.man in /usr/local/man/man1/des.1 +des.h in /usr/include/des.h + +des(1) should be compatible with sunOS's but I have been unable to +test it. + +These routines should compile on MSDOS, most 32bit and 64bit version +of Unix (BSD and SYSV) and VMS, without modification. +The only problems should be #include files that are in the wrong places. + +These routines can be compiled under MSDOS. +I have successfully encrypted files using des(1) under MSDOS and then +decrypted the files on a SparcStation. +I have been able to compile and test the routines with +Microsoft C v 5.1 and Turbo C v 2.0. +The code in this library is in no way optimised for the 16bit +operation of MSDOS. + +When building for glibc, ignore all of the above and just unpack into +glibc-1.??/des and then gmake as per normal. + +As a final note on performace. Certain CPUs like sparcs and Alpha often give +a %10 speed difference depending on the link order. It is rather anoying +when one program reports 'x' DES encrypts a second and another reports +'x*0.9' the speed. diff --git a/libs/openssl/crypto/des/Imakefile b/libs/openssl/crypto/des/Imakefile new file mode 100644 index 00000000..1b9b5629 --- /dev/null +++ b/libs/openssl/crypto/des/Imakefile @@ -0,0 +1,35 @@ +# This Imakefile has not been tested for a while but it should still +# work when placed in the correct directory in the kerberos v 4 distribution + +SRCS= cbc_cksm.c cbc_enc.c ecb_enc.c pcbc_enc.c \ + qud_cksm.c rand_key.c read_pwd.c set_key.c str2key.c \ + enc_read.c enc_writ.c fcrypt.c cfb_enc.c \ + ecb3_enc.c ofb_enc.c ofb64enc.c + +OBJS= cbc_cksm.o cbc_enc.o ecb_enc.o pcbc_enc.o \ + qud_cksm.o rand_key.o read_pwd.o set_key.o str2key.o \ + enc_read.o enc_writ.o fcrypt.o cfb_enc.o \ + ecb3_enc.o ofb_enc.o ofb64enc.o + +GENERAL=COPYRIGHT FILES INSTALL Imakefile README VERSION makefile times \ + vms.com KERBEROS +DES= des.c des.man +TESTING=destest.c speed.c rpw.c +LIBDES= des_crypt.man des.h des_locl.h podd.h sk.h spr.h + +PERL= des.pl testdes.pl doIP doPC1 doPC2 PC1 PC2 shifts.pl + +CODE= $(GENERAL) $(DES) $(TESTING) $(SRCS) $(LIBDES) $(PERL) + +SRCDIR=$(SRCTOP)/lib/des + +DBG= -O +INCLUDE= -I$(SRCDIR) +CC= cc + +library_obj_rule() + +install_library_target(des,$(OBJS),$(SRCS),) + +test(destest,libdes.a,) +test(rpw,libdes.a,) diff --git a/libs/openssl/crypto/des/KERBEROS b/libs/openssl/crypto/des/KERBEROS new file mode 100644 index 00000000..f401b100 --- /dev/null +++ b/libs/openssl/crypto/des/KERBEROS @@ -0,0 +1,41 @@ + [ This is an old file, I don't know if it is true anymore + but I will leave the file here - eay 21/11/95 ] + +To use this library with Bones (kerberos without DES): +1) Get my modified Bones - eBones. It can be found on + gondwana.ecr.mu.oz.au (128.250.1.63) /pub/athena/eBones-p9.tar.Z + and + nic.funet.fi (128.214.6.100) /pub/unix/security/Kerberos/eBones-p9.tar.Z + +2) Unpack this library in src/lib/des, makeing sure it is version + 3.00 or greater (libdes.tar.93-10-07.Z). This versions differences + from the version in comp.sources.misc volume 29 patchlevel2. + The primarily difference is that it should compile under kerberos :-). + It can be found at. + ftp.psy.uq.oz.au (130.102.32.1) /pub/DES/libdes.tar.93-10-07.Z + +Now do a normal kerberos build and things should work. + +One problem I found when I was build on my local sun. +--- +For sunOS 4.1.1 apply the following patch to src/util/ss/make_commands.c + +*** make_commands.c.orig Fri Jul 3 04:18:35 1987 +--- make_commands.c Wed May 20 08:47:42 1992 +*************** +*** 98,104 **** + if (!rename(o_file, z_file)) { + if (!vfork()) { + chdir("/tmp"); +! execl("/bin/ld", "ld", "-o", o_file+5, "-s", "-r", "-n", + z_file+5, 0); + perror("/bin/ld"); + _exit(1); +--- 98,104 ---- + if (!rename(o_file, z_file)) { + if (!vfork()) { + chdir("/tmp"); +! execl("/bin/ld", "ld", "-o", o_file+5, "-s", "-r", + z_file+5, 0); + perror("/bin/ld"); + _exit(1); diff --git a/libs/openssl/crypto/des/README b/libs/openssl/crypto/des/README new file mode 100644 index 00000000..621a5ab4 --- /dev/null +++ b/libs/openssl/crypto/des/README @@ -0,0 +1,54 @@ + + libdes, Version 4.01 10-Jan-97 + + Copyright (c) 1997, Eric Young + All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms specified in COPYRIGHT. + +-- +The primary ftp site for this library is +ftp://ftp.psy.uq.oz.au/pub/Crypto/DES/libdes-x.xx.tar.gz +libdes is now also shipped with SSLeay. Primary ftp site of +ftp://ftp.psy.uq.oz.au/pub/Crypto/SSL/SSLeay-x.x.x.tar.gz + +The best way to build this library is to build it as part of SSLeay. + +This kit builds a DES encryption library and a DES encryption program. +It supports ecb, cbc, ofb, cfb, triple ecb, triple cbc, triple ofb, +triple cfb, desx, and MIT's pcbc encryption modes and also has a fast +implementation of crypt(3). +It contains support routines to read keys from a terminal, +generate a random key, generate a key from an arbitrary length string, +read/write encrypted data from/to a file descriptor. + +The implementation was written so as to conform with the manual entry +for the des_crypt(3) library routines from MIT's project Athena. + +destest should be run after compilation to test the des routines. +rpw should be run after compilation to test the read password routines. +The des program is a replacement for the sun des command. I believe it +conforms to the sun version. + +The Imakefile is setup for use in the kerberos distribution. + +These routines are best compiled with gcc or any other good +optimising compiler. +Just turn you optimiser up to the highest settings and run destest +after the build to make sure everything works. + +I believe these routines are close to the fastest and most portable DES +routines that use small lookup tables (4.5k) that are publicly available. +The fcrypt routine is faster than ufc's fcrypt (when compiling with +gcc2 -O2) on the sparc 2 (1410 vs 1270) but is not so good on other machines +(on a sun3/260 168 vs 336). It is a function of CPU on chip cache size. +[ 10-Jan-97 and a function of an incorrect speed testing program in + ufc which gave much better test figures that reality ]. + +It is worth noting that on sparc and Alpha CPUs, performance of the DES +library can vary by upto %10 due to the positioning of files after application +linkage. + +Eric Young (eay@cryptsoft.com) + diff --git a/libs/openssl/crypto/des/VERSION b/libs/openssl/crypto/des/VERSION new file mode 100644 index 00000000..c7d01542 --- /dev/null +++ b/libs/openssl/crypto/des/VERSION @@ -0,0 +1,412 @@ + Fixed the weak key values which were wrong :-( + Defining SIGACTION causes sigaction() to be used instead of signal(). + SIGUSR1/SIGUSR2 are no longer mapped in the read tty stuff because it + can cause problems. This should hopefully not affect normal + applications. + +Version 4.04 + Fixed a few tests in destest. Also added x86 assember for + des_ncbc_encrypt() which is the standard cbc mode function. + This makes a very very large performace difference. + Ariel Glenn ariel@columbia.edu reports that the terminal + 'turn echo off' can return (errno == EINVAL) under solaris + when redirection is used. So I now catch that as well as ENOTTY. + + +Version 4.03 + Left a static out of enc_write.c, which caused to buffer to be + continiously malloc()ed. Does anyone use these functions? I keep + on feeling like removing them since I only had these in there + for a version of kerberised login. Anyway, this was pointed out + by Theo de Raadt + The 'n' bit ofb code was wrong, it was not shifting the shift + register. It worked correctly for n == 64. Thanks to + Gigi Ankeny for pointing this one out. + +Version 4.02 + I was doing 'if (memcmp(weak_keys[i],key,sizeof(key)) == 0)' + when checking for weak keys which is wrong :-(, pointed out by + Markus F.X.J. Oberhumer . + +Version 4.01 + Even faster inner loop in the DES assembler for x86 and a modification + for IP/FP which is faster on x86. Both of these changes are + from Svend Olaf Mikkelsen . His + changes make the assembler run %40 faster on a pentium. This is just + a case of getting the instruction sequence 'just right'. + All credit to 'Svend' :-) + Quite a few special x86 'make' targets. + A libdes-l (lite) distribution. + +Version 4.00 + After a bit of a pause, I'll up the major version number since this + is mostly a performace release. I've added x86 assembler and + added more options for performance. A %28 speedup for gcc + on a pentium and the assembler is a %50 speedup. + MIPS CPU's, sparc and Alpha are the main CPU's with speedups. + Run des_opts to work out which options should be used. + DES_RISC1/DES_RISC2 use alternative inner loops which use + more registers but should give speedups on any CPU that does + dual issue (pentium). DES_UNROLL unrolls the inner loop, + which costs in code size. + +Version 3.26 + I've finally removed one of the shifts in D_ENCRYPT. This + meant I've changed the des_SPtrans table (spr.h), the set_key() + function and some things in des_enc.c. This has definitly + made things faster :-). I've known about this one for some + time but I've been too lazy to follow it up :-). + Noticed that in the D_ENCRYPT() macro, we can just do L^=(..)^(..)^.. + instead of L^=((..)|(..)|(..).. This should save a register at + least. + Assember for x86. The file to replace is des_enc.c, which is replaced + by one of the assembler files found in asm. Look at des/asm/readme + for more info. + + /* Modification to fcrypt so it can be compiled to support + HPUX 10.x's long password format, define -DLONGCRYPT to use this. + Thanks to Jens Kupferschmidt . */ + + SIGWINCH case put in des_read_passwd() so the function does not + 'exit' if this function is recieved. + +Version 3.25 17/07/96 + Modified read_pwd.c so that stdin can be read if not a tty. + Thanks to Jeff Barber for the patches. + des_init_random_number_generator() shortened due to VMS linker + limits. + Added RSA's DESX cbc mode. It is a form of cbc encryption, with 2 + 8 byte quantites xored before and after encryption. + des_xcbc_encryption() - the name is funny to preserve the des_ + prefix on all functions. + +Version 3.24 20/04/96 + The DES_PTR macro option checked and used by SSLeay configuration + +Version 3.23 11/04/96 + Added DES_LONG. If defined to 'unsigned int' on the DEC Alpha, + it gives a %20 speedup :-) + Fixed the problem with des.pl under perl5. The patches were + sent by Ed Kubaitis (ejk@uiuc.edu). + if fcrypt.c, changed values to handle illegal salt values the way + normal crypt() implementations do. Some programs apparently use + them :-(. The patch was sent by Bjorn Gronvall + +Version 3.22 29/11/95 + Bug in des(1), an error with the uuencoding stuff when the + 'data' is small, thanks to Geoff Keating + for the patch. + +Version 3.21 22/11/95 + After some emailing back and forth with + Colin Plumb , I've tweaked a few things + and in a future version I will probably put in some of the + optimisation he suggested for use with the DES_USE_PTR option. + Extra routines from Mark Murray for use in + freeBSD. They mostly involve random number generation for use + with kerberos. They involve evil machine specific system calls + etc so I would normally suggest pushing this stuff into the + application and/or using RAND_seed()/RAND_bytes() if you are + using this DES library as part of SSLeay. + Redone the read_pw() function so that it is cleaner and + supports termios, thanks to Sameer Parekh + for the initial patches for this. + Renamed 3ecb_encrypt() to ecb3_encrypt(). This has been + done just to make things more consistent. + I have also now added triple DES versions of cfb and ofb. + +Version 3.20 + Damn, Damn, Damn, as pointed out by Mike_Spreitzer.PARC@xerox.com, + my des_random_seed() function was only copying 4 bytes of the + passed seed into the init structure. It is now fixed to copy 8. + My own suggestion is to used something like MD5 :-) + +Version 3.19 + While looking at my code one day, I though, why do I keep on + calling des_encrypt(in,out,ks,enc) when every function that + calls it has in and out the same. So I dropped the 'out' + parameter, people should not be using this function. + +Version 3.18 30/08/95 + Fixed a few bit with the distribution and the filenames. + 3.17 had been munged via a move to DOS and back again. + NO CODE CHANGES + +Version 3.17 14/07/95 + Fixed ede3 cbc which I had broken in 3.16. I have also + removed some unneeded variables in 7-8 of the routines. + +Version 3.16 26/06/95 + Added des_encrypt2() which does not use IP/FP, used by triple + des routines. Tweaked things a bit elsewhere. %13 speedup on + sparc and %6 on a R4400 for ede3 cbc mode. + +Version 3.15 06/06/95 + Added des_ncbc_encrypt(), it is des_cbc mode except that it is + 'normal' and copies the new iv value back over the top of the + passed parameter. + CHANGED des_ede3_cbc_encrypt() so that it too now overwrites + the iv. THIS WILL BREAK EXISTING CODE, but since this function + only new, I feel I can change it, not so with des_cbc_encrypt :-(. + I need to update the documentation. + +Version 3.14 31/05/95 + New release upon the world, as part of my SSL implementation. + New copyright and usage stuff. Basically free for all to use + as long as you say it came from me :-) + +Version 3.13 31/05/95 + A fix in speed.c, if HZ is not defined, I set it to 100.0 + which is reasonable for most unixes except SunOS 4.x. + I now have a #ifdef sun but timing for SunOS 4.x looked very + good :-(. At my last job where I used SunOS 4.x, it was + defined to be 60.0 (look at the old INSTALL documentation), at + the last release had it changed to 100.0 since I now work with + Solaris2 and SVR4 boxes. + Thanks to Rory Chisholm for pointing this + one out. + +Version 3.12 08/05/95 + As pointed out by The Crypt Keeper , + my D_ENCRYPT macro in crypt() had an un-necessary variable. + It has been removed. + +Version 3.11 03/05/95 + Added des_ede3_cbc_encrypt() which is cbc mode des with 3 keys + and one iv. It is a standard and I needed it for my SSL code. + It makes more sense to use this for triple DES than + 3cbc_encrypt(). I have also added (or should I say tested :-) + cfb64_encrypt() which is cfb64 but it will encrypt a partial + number of bytes - 3 bytes in 3 bytes out. Again this is for + my SSL library, as a form of encryption to use with SSL + telnet. + +Version 3.10 22/03/95 + Fixed a bug in 3cbc_encrypt() :-(. When making repeated calls + to cbc3_encrypt, the 2 iv values that were being returned to + be used in the next call were reversed :-(. + Many thanks to Bill Wade for pointing out + this error. + +Version 3.09 01/02/95 + Fixed des_random_key to far more random, it was rather feeble + with regards to picking the initial seed. The problem was + pointed out by Olaf Kirch . + +Version 3.08 14/12/94 + Added Makefile.PL so libdes can be built into perl5. + Changed des_locl.h so RAND is always defined. + +Version 3.07 05/12/94 + Added GNUmake and stuff so the library can be build with + glibc. + +Version 3.06 30/08/94 + Added rpc_enc.c which contains _des_crypt. This is for use in + secure_rpc v 4.0 + Finally fixed the cfb_enc problems. + Fixed a few parameter parsing bugs in des (-3 and -b), thanks + to Rob McMillan + +Version 3.05 21/04/94 + for unsigned long l; gcc does not produce ((l>>34) == 0) + This causes bugs in cfb_enc. + Thanks to Hadmut Danisch + +Version 3.04 20/04/94 + Added a version number to des.c and libdes.a + +Version 3.03 12/01/94 + Fixed a bug in non zero iv in 3cbc_enc. + +Version 3.02 29/10/93 + I now work in a place where there are 6+ architectures and 14+ + OS versions :-). + Fixed TERMIO definition so the most sys V boxes will work :-) + +Release upon comp.sources.misc +Version 3.01 08/10/93 + Added des_3cbc_encrypt() + +Version 3.00 07/10/93 + Fixed up documentation. + quad_cksum definitely compatible with MIT's now. + +Version 2.30 24/08/93 + Triple DES now defaults to triple cbc but can do triple ecb + with the -b flag. + Fixed some MSDOS uuen/uudecoding problems, thanks to + Added prototypes. + +Version 2.22 29/06/93 + Fixed a bug in des_is_weak_key() which stopped it working :-( + thanks to engineering@MorningStar.Com. + +Version 2.21 03/06/93 + des(1) with no arguments gives quite a bit of help. + Added -c (generate ckecksum) flag to des(1). + Added -3 (triple DES) flag to des(1). + Added cfb and ofb routines to the library. + +Version 2.20 11/03/93 + Added -u (uuencode) flag to des(1). + I have been playing with byte order in quad_cksum to make it + compatible with MIT's version. All I can say is avid this + function if possible since MIT's output is endian dependent. + +Version 2.12 14/10/92 + Added MSDOS specific macro in ecb_encrypt which gives a %70 + speed up when the code is compiled with turbo C. + +Version 2.11 12/10/92 + Speedup in set_key (recoding of PC-1) + I now do it in 47 simple operations, down from 60. + Thanks to John Fletcher (john_fletcher@lccmail.ocf.llnl.gov) + for motivating me to look for a faster system :-) + The speedup is probably less that 1% but it is still 13 + instructions less :-). + +Version 2.10 06/10/92 + The code now works on the 64bit ETA10 and CRAY without modifications or + #defines. I believe the code should work on any machine that + defines long, int or short to be 8 bytes long. + Thanks to Shabbir J. Safdar (shabby@mentor.cc.purdue.edu) + for helping me fix the code to run on 64bit machines (he had + access to an ETA10). + Thanks also to John Fletcher + for testing the routines on a CRAY. + read_password.c has been renamed to read_passwd.c + string_to_key.c has been renamed to string2key.c + +Version 2.00 14/09/92 + Made mods so that the library should work on 64bit CPU's. + Removed all my uchar and ulong defs. To many different + versions of unix define them in their header files in too many + different combinations :-) + IRIX - Sillicon Graphics mods (mostly in read_password.c). + Thanks to Andrew Daviel (advax@erich.triumf.ca) + +Version 1.99 26/08/92 + Fixed a bug or 2 in enc_read.c + Fixed a bug in enc_write.c + Fixed a pseudo bug in fcrypt.c (very obscure). + +Version 1.98 31/07/92 + Support for the ETA10. This is a strange machine that defines + longs and ints as 8 bytes and shorts as 4 bytes. + Since I do evil things with long * that assume that they are 4 + bytes. Look in the Makefile for the option to compile for + this machine. quad_cksum appears to have problems but I + will don't have the time to fix it right now, and this is not + a function that uses DES and so will not effect the main uses + of the library. + +Version 1.97 20/05/92 eay + Fixed the Imakefile and made some changes to des.h to fix some + problems when building this package with Kerberos v 4. + +Version 1.96 18/05/92 eay + Fixed a small bug in string_to_key() where problems could + occur if des_check_key was set to true and the string + generated a weak key. + +Patch2 posted to comp.sources.misc +Version 1.95 13/05/92 eay + Added an alternative version of the D_ENCRYPT macro in + ecb_encrypt and fcrypt. Depending on the compiler, one version or the + other will be faster. This was inspired by + Dana How , and her pointers about doing the + *(ulong *)((uchar *)ptr+(value&0xfc)) + vs + ptr[value&0x3f] + to stop the C compiler doing a <<2 to convert the long array index. + +Version 1.94 05/05/92 eay + Fixed an incompatibility between my string_to_key and the MIT + version. When the key is longer than 8 chars, I was wrapping + with a different method. To use the old version, define + OLD_STR_TO_KEY in the makefile. Thanks to + viktor@newsu.shearson.com (Viktor Dukhovni). + +Version 1.93 28/04/92 eay + Fixed the VMS mods so that echo is now turned off in + read_password. Thanks again to brennan@coco.cchs.su.oz.AU. + MSDOS support added. The routines can be compiled with + Turbo C (v2.0) and MSC (v5.1). Make sure MSDOS is defined. + +Patch1 posted to comp.sources.misc +Version 1.92 13/04/92 eay + Changed D_ENCRYPT so that the rotation of R occurs outside of + the loop. This required rotating all the longs in sp.h (now + called spr.h). Thanks to Richard Outerbridge <71755.204@CompuServe.COM> + speed.c has been changed so it will work without SIGALRM. If + times(3) is not present it will try to use ftime() instead. + +Version 1.91 08/04/92 eay + Added -E/-D options to des(1) so it can use string_to_key. + Added SVR4 mods suggested by witr@rwwa.COM + Added VMS mods suggested by brennan@coco.cchs.su.oz.AU. If + anyone knows how to turn of tty echo in VMS please tell me or + implement it yourself :-). + Changed FILE *IN/*OUT to *DES_IN/*DES_OUT since it appears VMS + does not like IN/OUT being used. + +Libdes posted to comp.sources.misc +Version 1.9 24/03/92 eay + Now contains a fast small crypt replacement. + Added des(1) command. + Added des_rw_mode so people can use cbc encryption with + enc_read and enc_write. + +Version 1.8 15/10/91 eay + Bug in cbc_cksum. + Many thanks to Keith Reynolds (keithr@sco.COM) for pointing this + one out. + +Version 1.7 24/09/91 eay + Fixed set_key :-) + set_key is 4 times faster and takes less space. + There are a few minor changes that could be made. + +Version 1.6 19/09/1991 eay + Finally go IP and FP finished. + Now I need to fix set_key. + This version is quite a bit faster that 1.51 + +Version 1.52 15/06/1991 eay + 20% speedup in ecb_encrypt by changing the E bit selection + to use 2 32bit words. This also required modification of the + sp table. There is still a way to speedup the IP and IP-1 + (hints from outer@sq.com) still working on this one :-(. + +Version 1.51 07/06/1991 eay + Faster des_encrypt by loop unrolling + Fixed bug in quad_cksum.c (thanks to hughes@logos.ucs.indiana.edu) + +Version 1.50 28/05/1991 eay + Optimised the code a bit more for the sparc. I have improved the + speed of the inner des_encrypt by speeding up the initial and + final permutations. + +Version 1.40 23/10/1990 eay + Fixed des_random_key, it did not produce a random key :-( + +Version 1.30 2/10/1990 eay + Have made des_quad_cksum the same as MIT's, the full package + should be compatible with MIT's + Have tested on a DECstation 3100 + Still need to fix des_set_key (make it faster). + Does des_cbc_encrypts at 70.5k/sec on a 3100. + +Version 1.20 18/09/1990 eay + Fixed byte order dependencies. + Fixed (I hope) all the word alignment problems. + Speedup in des_ecb_encrypt. + +Version 1.10 11/09/1990 eay + Added des_enc_read and des_enc_write. + Still need to fix des_quad_cksum. + Still need to document des_enc_read and des_enc_write. + +Version 1.00 27/08/1990 eay + diff --git a/libs/openssl/crypto/des/asm/crypt586.pl b/libs/openssl/crypto/des/asm/crypt586.pl new file mode 100644 index 00000000..e36f7d44 --- /dev/null +++ b/libs/openssl/crypto/des/asm/crypt586.pl @@ -0,0 +1,209 @@ +#!/usr/local/bin/perl +# +# The inner loop instruction sequence and the IP/FP modifications are from +# Svend Olaf Mikkelsen +# I've added the stuff needed for crypt() but I've not worried about making +# things perfect. +# + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"crypt586.pl"); + +$L="edi"; +$R="esi"; + +&external_label("DES_SPtrans"); +&fcrypt_body("fcrypt_body"); +&asm_finish(); + +sub fcrypt_body + { + local($name,$do_ip)=@_; + + &function_begin($name); + + &comment(""); + &comment("Load the 2 words"); + $trans="ebp"; + + &xor( $L, $L); + &xor( $R, $R); + + # PIC-ification:-) + &picmeup("edx","DES_SPtrans"); + #if ($cpp) { &picmeup("edx","DES_SPtrans"); } + #else { &lea("edx",&DWP("DES_SPtrans")); } + &push("edx"); # becomes &swtmp(1) + # + &mov($trans,&wparam(1)); # reloaded with DES_SPtrans in D_ENCRYPT + + &push(&DWC(25)); # add a variable + + &set_label("start"); + for ($i=0; $i<16; $i+=2) + { + &comment(""); + &comment("Round $i"); + &D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx"); + + &comment(""); + &comment("Round ".sprintf("%d",$i+1)); + &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx"); + } + &mov("ebx", &swtmp(0)); + &mov("eax", $L); + &dec("ebx"); + &mov($L, $R); + &mov($R, "eax"); + &mov(&swtmp(0), "ebx"); + &jnz(&label("start")); + + &comment(""); + &comment("FP"); + &mov("edx",&wparam(0)); + + &FP_new($R,$L,"eax",3); + &mov(&DWP(0,"edx","",0),"eax"); + &mov(&DWP(4,"edx","",0),$L); + + &add("esp",8); # remove variables + + &function_end($name); + } + +sub D_ENCRYPT + { + local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t)=@_; + + &mov( $u, &wparam(2)); # 2 + &mov( $t, $R); + &shr( $t, 16); # 1 + &mov( $tmp2, &wparam(3)); # 2 + &xor( $t, $R); # 1 + + &and( $u, $t); # 2 + &and( $t, $tmp2); # 2 + + &mov( $tmp1, $u); + &shl( $tmp1, 16); # 1 + &mov( $tmp2, $t); + &shl( $tmp2, 16); # 1 + &xor( $u, $tmp1); # 2 + &xor( $t, $tmp2); # 2 + &mov( $tmp1, &DWP(&n2a($S*4),$trans,"",0)); # 2 + &xor( $u, $tmp1); + &mov( $tmp2, &DWP(&n2a(($S+1)*4),$trans,"",0)); # 2 + &xor( $u, $R); + &xor( $t, $R); + &xor( $t, $tmp2); + + &and( $u, "0xfcfcfcfc" ); # 2 + &xor( $tmp1, $tmp1); # 1 + &and( $t, "0xcfcfcfcf" ); # 2 + &xor( $tmp2, $tmp2); + &movb( &LB($tmp1), &LB($u) ); + &movb( &LB($tmp2), &HB($u) ); + &rotr( $t, 4 ); + &mov( $trans, &swtmp(1)); + &xor( $L, &DWP(" ",$trans,$tmp1,0)); + &movb( &LB($tmp1), &LB($t) ); + &xor( $L, &DWP("0x200",$trans,$tmp2,0)); + &movb( &LB($tmp2), &HB($t) ); + &shr( $u, 16); + &xor( $L, &DWP("0x100",$trans,$tmp1,0)); + &movb( &LB($tmp1), &HB($u) ); + &shr( $t, 16); + &xor( $L, &DWP("0x300",$trans,$tmp2,0)); + &movb( &LB($tmp2), &HB($t) ); + &and( $u, "0xff" ); + &and( $t, "0xff" ); + &mov( $tmp1, &DWP("0x600",$trans,$tmp1,0)); + &xor( $L, $tmp1); + &mov( $tmp1, &DWP("0x700",$trans,$tmp2,0)); + &xor( $L, $tmp1); + &mov( $tmp1, &DWP("0x400",$trans,$u,0)); + &xor( $L, $tmp1); + &mov( $tmp1, &DWP("0x500",$trans,$t,0)); + &xor( $L, $tmp1); + &mov( $trans, &wparam(1)); + } + +sub n2a + { + sprintf("%d",$_[0]); + } + +# now has a side affect of rotating $a by $shift +sub R_PERM_OP + { + local($a,$b,$tt,$shift,$mask,$last)=@_; + + &rotl( $a, $shift ) if ($shift != 0); + &mov( $tt, $a ); + &xor( $a, $b ); + &and( $a, $mask ); + if ($notlast eq $b) + { + &xor( $b, $a ); + &xor( $tt, $a ); + } + else + { + &xor( $tt, $a ); + &xor( $b, $a ); + } + &comment(""); + } + +sub IP_new + { + local($l,$r,$tt,$lr)=@_; + + &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l); + &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l); + &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r); + &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r); + &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r); + + if ($lr != 3) + { + if (($lr-3) < 0) + { &rotr($tt, 3-$lr); } + else { &rotl($tt, $lr-3); } + } + if ($lr != 2) + { + if (($lr-2) < 0) + { &rotr($r, 2-$lr); } + else { &rotl($r, $lr-2); } + } + } + +sub FP_new + { + local($l,$r,$tt,$lr)=@_; + + if ($lr != 2) + { + if (($lr-2) < 0) + { &rotl($r, 2-$lr); } + else { &rotr($r, $lr-2); } + } + if ($lr != 3) + { + if (($lr-3) < 0) + { &rotl($l, 3-$lr); } + else { &rotr($l, $lr-3); } + } + + &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r); + &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r); + &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l); + &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l); + &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r); + &rotr($tt , 4); + } + diff --git a/libs/openssl/crypto/des/asm/des-586.pl b/libs/openssl/crypto/des/asm/des-586.pl new file mode 100644 index 00000000..5b5f39ce --- /dev/null +++ b/libs/openssl/crypto/des/asm/des-586.pl @@ -0,0 +1,453 @@ +#!/usr/local/bin/perl +# +# The inner loop instruction sequence and the IP/FP modifications are from +# Svend Olaf Mikkelsen +# + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; +require "cbc.pl"; +require "desboth.pl"; + +# base code is in microsft +# op dest, source +# format. +# + +&asm_init($ARGV[0],"des-586.pl"); + +$L="edi"; +$R="esi"; +$trans="ebp"; +$small_footprint=1 if (grep(/\-DOPENSSL_SMALL_FOOTPRINT/,@ARGV)); +# one can discuss setting this variable to 1 unconditionally, as +# the folded loop is only 3% slower than unrolled, but >7 times smaller + +&public_label("DES_SPtrans"); + +&DES_encrypt_internal(); +&DES_decrypt_internal(); +&DES_encrypt("DES_encrypt1",1); +&DES_encrypt("DES_encrypt2",0); +&DES_encrypt3("DES_encrypt3",1); +&DES_encrypt3("DES_decrypt3",0); +&cbc("DES_ncbc_encrypt","DES_encrypt1","DES_encrypt1",0,4,5,3,5,-1); +&cbc("DES_ede3_cbc_encrypt","DES_encrypt3","DES_decrypt3",0,6,7,3,4,5); +&DES_SPtrans(); + +&asm_finish(); + +sub DES_encrypt_internal() + { + &function_begin_B("_x86_DES_encrypt"); + + if ($small_footprint) + { + &lea("edx",&DWP(128,"ecx")); + &push("edx"); + &push("ecx"); + &set_label("eloop"); + &D_ENCRYPT(0,$L,$R,0,$trans,"eax","ebx","ecx","edx",&swtmp(0)); + &comment(""); + &D_ENCRYPT(1,$R,$L,2,$trans,"eax","ebx","ecx","edx",&swtmp(0)); + &comment(""); + &add("ecx",16); + &cmp("ecx",&swtmp(1)); + &mov(&swtmp(0),"ecx"); + &jb(&label("eloop")); + &add("esp",8); + } + else + { + &push("ecx"); + for ($i=0; $i<16; $i+=2) + { + &comment("Round $i"); + &D_ENCRYPT($i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx",&swtmp(0)); + &comment("Round ".sprintf("%d",$i+1)); + &D_ENCRYPT($i+1,$R,$L,($i+1)*2,$trans,"eax","ebx","ecx","edx",&swtmp(0)); + } + &add("esp",4); + } + &ret(); + + &function_end_B("_x86_DES_encrypt"); + } + +sub DES_decrypt_internal() + { + &function_begin_B("_x86_DES_decrypt"); + + if ($small_footprint) + { + &push("ecx"); + &lea("ecx",&DWP(128,"ecx")); + &push("ecx"); + &set_label("dloop"); + &D_ENCRYPT(0,$L,$R,-2,$trans,"eax","ebx","ecx","edx",&swtmp(0)); + &comment(""); + &D_ENCRYPT(1,$R,$L,-4,$trans,"eax","ebx","ecx","edx",&swtmp(0)); + &comment(""); + &sub("ecx",16); + &cmp("ecx",&swtmp(1)); + &mov(&swtmp(0),"ecx"); + &ja(&label("dloop")); + &add("esp",8); + } + else + { + &push("ecx"); + for ($i=15; $i>0; $i-=2) + { + &comment("Round $i"); + &D_ENCRYPT(15-$i,$L,$R,$i*2,$trans,"eax","ebx","ecx","edx",&swtmp(0)); + &comment("Round ".sprintf("%d",$i-1)); + &D_ENCRYPT(15-$i+1,$R,$L,($i-1)*2,$trans,"eax","ebx","ecx","edx",&swtmp(0)); + } + &add("esp",4); + } + &ret(); + + &function_end_B("_x86_DES_decrypt"); + } + +sub DES_encrypt + { + local($name,$do_ip)=@_; + + &function_begin_B($name); + + &push("esi"); + &push("edi"); + + &comment(""); + &comment("Load the 2 words"); + + if ($do_ip) + { + &mov($R,&wparam(0)); + &xor( "ecx", "ecx" ); + + &push("ebx"); + &push("ebp"); + + &mov("eax",&DWP(0,$R,"",0)); + &mov("ebx",&wparam(2)); # get encrypt flag + &mov($L,&DWP(4,$R,"",0)); + &comment(""); + &comment("IP"); + &IP_new("eax",$L,$R,3); + } + else + { + &mov("eax",&wparam(0)); + &xor( "ecx", "ecx" ); + + &push("ebx"); + &push("ebp"); + + &mov($R,&DWP(0,"eax","",0)); + &mov("ebx",&wparam(2)); # get encrypt flag + &rotl($R,3); + &mov($L,&DWP(4,"eax","",0)); + &rotl($L,3); + } + + # PIC-ification:-) + &call (&label("pic_point")); + &set_label("pic_point"); + &blindpop($trans); + &lea ($trans,&DWP(&label("DES_SPtrans")."-".&label("pic_point"),$trans)); + + &mov( "ecx", &wparam(1) ); + + &cmp("ebx","0"); + &je(&label("decrypt")); + &call("_x86_DES_encrypt"); + &jmp(&label("done")); + &set_label("decrypt"); + &call("_x86_DES_decrypt"); + &set_label("done"); + + if ($do_ip) + { + &comment(""); + &comment("FP"); + &mov("edx",&wparam(0)); + &FP_new($L,$R,"eax",3); + + &mov(&DWP(0,"edx","",0),"eax"); + &mov(&DWP(4,"edx","",0),$R); + } + else + { + &comment(""); + &comment("Fixup"); + &rotr($L,3); # r + &mov("eax",&wparam(0)); + &rotr($R,3); # l + &mov(&DWP(0,"eax","",0),$L); + &mov(&DWP(4,"eax","",0),$R); + } + + &pop("ebp"); + &pop("ebx"); + &pop("edi"); + &pop("esi"); + &ret(); + + &function_end_B($name); + } + +sub D_ENCRYPT + { + local($r,$L,$R,$S,$trans,$u,$tmp1,$tmp2,$t,$wp1)=@_; + + &mov( $u, &DWP(&n2a($S*4),$tmp2,"",0)); + &xor( $tmp1, $tmp1); + &mov( $t, &DWP(&n2a(($S+1)*4),$tmp2,"",0)); + &xor( $u, $R); + &xor( $tmp2, $tmp2); + &xor( $t, $R); + &and( $u, "0xfcfcfcfc" ); + &and( $t, "0xcfcfcfcf" ); + &movb( &LB($tmp1), &LB($u) ); + &movb( &LB($tmp2), &HB($u) ); + &rotr( $t, 4 ); + &xor( $L, &DWP(" ",$trans,$tmp1,0)); + &movb( &LB($tmp1), &LB($t) ); + &xor( $L, &DWP("0x200",$trans,$tmp2,0)); + &movb( &LB($tmp2), &HB($t) ); + &shr( $u, 16); + &xor( $L, &DWP("0x100",$trans,$tmp1,0)); + &movb( &LB($tmp1), &HB($u) ); + &shr( $t, 16); + &xor( $L, &DWP("0x300",$trans,$tmp2,0)); + &movb( &LB($tmp2), &HB($t) ); + &and( $u, "0xff" ); + &and( $t, "0xff" ); + &xor( $L, &DWP("0x600",$trans,$tmp1,0)); + &xor( $L, &DWP("0x700",$trans,$tmp2,0)); + &mov( $tmp2, $wp1 ); + &xor( $L, &DWP("0x400",$trans,$u,0)); + &xor( $L, &DWP("0x500",$trans,$t,0)); + } + +sub n2a + { + sprintf("%d",$_[0]); + } + +# now has a side affect of rotating $a by $shift +sub R_PERM_OP + { + local($a,$b,$tt,$shift,$mask,$last)=@_; + + &rotl( $a, $shift ) if ($shift != 0); + &mov( $tt, $a ); + &xor( $a, $b ); + &and( $a, $mask ); + # This can never succeed, and besides it is difficult to see what the + # idea was - Ben 13 Feb 99 + if (!$last eq $b) + { + &xor( $b, $a ); + &xor( $tt, $a ); + } + else + { + &xor( $tt, $a ); + &xor( $b, $a ); + } + &comment(""); + } + +sub IP_new + { + local($l,$r,$tt,$lr)=@_; + + &R_PERM_OP($l,$r,$tt, 4,"0xf0f0f0f0",$l); + &R_PERM_OP($r,$tt,$l,20,"0xfff0000f",$l); + &R_PERM_OP($l,$tt,$r,14,"0x33333333",$r); + &R_PERM_OP($tt,$r,$l,22,"0x03fc03fc",$r); + &R_PERM_OP($l,$r,$tt, 9,"0xaaaaaaaa",$r); + + if ($lr != 3) + { + if (($lr-3) < 0) + { &rotr($tt, 3-$lr); } + else { &rotl($tt, $lr-3); } + } + if ($lr != 2) + { + if (($lr-2) < 0) + { &rotr($r, 2-$lr); } + else { &rotl($r, $lr-2); } + } + } + +sub FP_new + { + local($l,$r,$tt,$lr)=@_; + + if ($lr != 2) + { + if (($lr-2) < 0) + { &rotl($r, 2-$lr); } + else { &rotr($r, $lr-2); } + } + if ($lr != 3) + { + if (($lr-3) < 0) + { &rotl($l, 3-$lr); } + else { &rotr($l, $lr-3); } + } + + &R_PERM_OP($l,$r,$tt, 0,"0xaaaaaaaa",$r); + &R_PERM_OP($tt,$r,$l,23,"0x03fc03fc",$r); + &R_PERM_OP($l,$r,$tt,10,"0x33333333",$l); + &R_PERM_OP($r,$tt,$l,18,"0xfff0000f",$l); + &R_PERM_OP($l,$tt,$r,12,"0xf0f0f0f0",$r); + &rotr($tt , 4); + } + +sub DES_SPtrans + { + &set_label("DES_SPtrans",64); + &data_word(0x02080800, 0x00080000, 0x02000002, 0x02080802); + &data_word(0x02000000, 0x00080802, 0x00080002, 0x02000002); + &data_word(0x00080802, 0x02080800, 0x02080000, 0x00000802); + &data_word(0x02000802, 0x02000000, 0x00000000, 0x00080002); + &data_word(0x00080000, 0x00000002, 0x02000800, 0x00080800); + &data_word(0x02080802, 0x02080000, 0x00000802, 0x02000800); + &data_word(0x00000002, 0x00000800, 0x00080800, 0x02080002); + &data_word(0x00000800, 0x02000802, 0x02080002, 0x00000000); + &data_word(0x00000000, 0x02080802, 0x02000800, 0x00080002); + &data_word(0x02080800, 0x00080000, 0x00000802, 0x02000800); + &data_word(0x02080002, 0x00000800, 0x00080800, 0x02000002); + &data_word(0x00080802, 0x00000002, 0x02000002, 0x02080000); + &data_word(0x02080802, 0x00080800, 0x02080000, 0x02000802); + &data_word(0x02000000, 0x00000802, 0x00080002, 0x00000000); + &data_word(0x00080000, 0x02000000, 0x02000802, 0x02080800); + &data_word(0x00000002, 0x02080002, 0x00000800, 0x00080802); + # nibble 1 + &data_word(0x40108010, 0x00000000, 0x00108000, 0x40100000); + &data_word(0x40000010, 0x00008010, 0x40008000, 0x00108000); + &data_word(0x00008000, 0x40100010, 0x00000010, 0x40008000); + &data_word(0x00100010, 0x40108000, 0x40100000, 0x00000010); + &data_word(0x00100000, 0x40008010, 0x40100010, 0x00008000); + &data_word(0x00108010, 0x40000000, 0x00000000, 0x00100010); + &data_word(0x40008010, 0x00108010, 0x40108000, 0x40000010); + &data_word(0x40000000, 0x00100000, 0x00008010, 0x40108010); + &data_word(0x00100010, 0x40108000, 0x40008000, 0x00108010); + &data_word(0x40108010, 0x00100010, 0x40000010, 0x00000000); + &data_word(0x40000000, 0x00008010, 0x00100000, 0x40100010); + &data_word(0x00008000, 0x40000000, 0x00108010, 0x40008010); + &data_word(0x40108000, 0x00008000, 0x00000000, 0x40000010); + &data_word(0x00000010, 0x40108010, 0x00108000, 0x40100000); + &data_word(0x40100010, 0x00100000, 0x00008010, 0x40008000); + &data_word(0x40008010, 0x00000010, 0x40100000, 0x00108000); + # nibble 2 + &data_word(0x04000001, 0x04040100, 0x00000100, 0x04000101); + &data_word(0x00040001, 0x04000000, 0x04000101, 0x00040100); + &data_word(0x04000100, 0x00040000, 0x04040000, 0x00000001); + &data_word(0x04040101, 0x00000101, 0x00000001, 0x04040001); + &data_word(0x00000000, 0x00040001, 0x04040100, 0x00000100); + &data_word(0x00000101, 0x04040101, 0x00040000, 0x04000001); + &data_word(0x04040001, 0x04000100, 0x00040101, 0x04040000); + &data_word(0x00040100, 0x00000000, 0x04000000, 0x00040101); + &data_word(0x04040100, 0x00000100, 0x00000001, 0x00040000); + &data_word(0x00000101, 0x00040001, 0x04040000, 0x04000101); + &data_word(0x00000000, 0x04040100, 0x00040100, 0x04040001); + &data_word(0x00040001, 0x04000000, 0x04040101, 0x00000001); + &data_word(0x00040101, 0x04000001, 0x04000000, 0x04040101); + &data_word(0x00040000, 0x04000100, 0x04000101, 0x00040100); + &data_word(0x04000100, 0x00000000, 0x04040001, 0x00000101); + &data_word(0x04000001, 0x00040101, 0x00000100, 0x04040000); + # nibble 3 + &data_word(0x00401008, 0x10001000, 0x00000008, 0x10401008); + &data_word(0x00000000, 0x10400000, 0x10001008, 0x00400008); + &data_word(0x10401000, 0x10000008, 0x10000000, 0x00001008); + &data_word(0x10000008, 0x00401008, 0x00400000, 0x10000000); + &data_word(0x10400008, 0x00401000, 0x00001000, 0x00000008); + &data_word(0x00401000, 0x10001008, 0x10400000, 0x00001000); + &data_word(0x00001008, 0x00000000, 0x00400008, 0x10401000); + &data_word(0x10001000, 0x10400008, 0x10401008, 0x00400000); + &data_word(0x10400008, 0x00001008, 0x00400000, 0x10000008); + &data_word(0x00401000, 0x10001000, 0x00000008, 0x10400000); + &data_word(0x10001008, 0x00000000, 0x00001000, 0x00400008); + &data_word(0x00000000, 0x10400008, 0x10401000, 0x00001000); + &data_word(0x10000000, 0x10401008, 0x00401008, 0x00400000); + &data_word(0x10401008, 0x00000008, 0x10001000, 0x00401008); + &data_word(0x00400008, 0x00401000, 0x10400000, 0x10001008); + &data_word(0x00001008, 0x10000000, 0x10000008, 0x10401000); + # nibble 4 + &data_word(0x08000000, 0x00010000, 0x00000400, 0x08010420); + &data_word(0x08010020, 0x08000400, 0x00010420, 0x08010000); + &data_word(0x00010000, 0x00000020, 0x08000020, 0x00010400); + &data_word(0x08000420, 0x08010020, 0x08010400, 0x00000000); + &data_word(0x00010400, 0x08000000, 0x00010020, 0x00000420); + &data_word(0x08000400, 0x00010420, 0x00000000, 0x08000020); + &data_word(0x00000020, 0x08000420, 0x08010420, 0x00010020); + &data_word(0x08010000, 0x00000400, 0x00000420, 0x08010400); + &data_word(0x08010400, 0x08000420, 0x00010020, 0x08010000); + &data_word(0x00010000, 0x00000020, 0x08000020, 0x08000400); + &data_word(0x08000000, 0x00010400, 0x08010420, 0x00000000); + &data_word(0x00010420, 0x08000000, 0x00000400, 0x00010020); + &data_word(0x08000420, 0x00000400, 0x00000000, 0x08010420); + &data_word(0x08010020, 0x08010400, 0x00000420, 0x00010000); + &data_word(0x00010400, 0x08010020, 0x08000400, 0x00000420); + &data_word(0x00000020, 0x00010420, 0x08010000, 0x08000020); + # nibble 5 + &data_word(0x80000040, 0x00200040, 0x00000000, 0x80202000); + &data_word(0x00200040, 0x00002000, 0x80002040, 0x00200000); + &data_word(0x00002040, 0x80202040, 0x00202000, 0x80000000); + &data_word(0x80002000, 0x80000040, 0x80200000, 0x00202040); + &data_word(0x00200000, 0x80002040, 0x80200040, 0x00000000); + &data_word(0x00002000, 0x00000040, 0x80202000, 0x80200040); + &data_word(0x80202040, 0x80200000, 0x80000000, 0x00002040); + &data_word(0x00000040, 0x00202000, 0x00202040, 0x80002000); + &data_word(0x00002040, 0x80000000, 0x80002000, 0x00202040); + &data_word(0x80202000, 0x00200040, 0x00000000, 0x80002000); + &data_word(0x80000000, 0x00002000, 0x80200040, 0x00200000); + &data_word(0x00200040, 0x80202040, 0x00202000, 0x00000040); + &data_word(0x80202040, 0x00202000, 0x00200000, 0x80002040); + &data_word(0x80000040, 0x80200000, 0x00202040, 0x00000000); + &data_word(0x00002000, 0x80000040, 0x80002040, 0x80202000); + &data_word(0x80200000, 0x00002040, 0x00000040, 0x80200040); + # nibble 6 + &data_word(0x00004000, 0x00000200, 0x01000200, 0x01000004); + &data_word(0x01004204, 0x00004004, 0x00004200, 0x00000000); + &data_word(0x01000000, 0x01000204, 0x00000204, 0x01004000); + &data_word(0x00000004, 0x01004200, 0x01004000, 0x00000204); + &data_word(0x01000204, 0x00004000, 0x00004004, 0x01004204); + &data_word(0x00000000, 0x01000200, 0x01000004, 0x00004200); + &data_word(0x01004004, 0x00004204, 0x01004200, 0x00000004); + &data_word(0x00004204, 0x01004004, 0x00000200, 0x01000000); + &data_word(0x00004204, 0x01004000, 0x01004004, 0x00000204); + &data_word(0x00004000, 0x00000200, 0x01000000, 0x01004004); + &data_word(0x01000204, 0x00004204, 0x00004200, 0x00000000); + &data_word(0x00000200, 0x01000004, 0x00000004, 0x01000200); + &data_word(0x00000000, 0x01000204, 0x01000200, 0x00004200); + &data_word(0x00000204, 0x00004000, 0x01004204, 0x01000000); + &data_word(0x01004200, 0x00000004, 0x00004004, 0x01004204); + &data_word(0x01000004, 0x01004200, 0x01004000, 0x00004004); + # nibble 7 + &data_word(0x20800080, 0x20820000, 0x00020080, 0x00000000); + &data_word(0x20020000, 0x00800080, 0x20800000, 0x20820080); + &data_word(0x00000080, 0x20000000, 0x00820000, 0x00020080); + &data_word(0x00820080, 0x20020080, 0x20000080, 0x20800000); + &data_word(0x00020000, 0x00820080, 0x00800080, 0x20020000); + &data_word(0x20820080, 0x20000080, 0x00000000, 0x00820000); + &data_word(0x20000000, 0x00800000, 0x20020080, 0x20800080); + &data_word(0x00800000, 0x00020000, 0x20820000, 0x00000080); + &data_word(0x00800000, 0x00020000, 0x20000080, 0x20820080); + &data_word(0x00020080, 0x20000000, 0x00000000, 0x00820000); + &data_word(0x20800080, 0x20020080, 0x20020000, 0x00800080); + &data_word(0x20820000, 0x00000080, 0x00800080, 0x20020000); + &data_word(0x20820080, 0x00800000, 0x20800000, 0x20000080); + &data_word(0x00820000, 0x00020080, 0x20020080, 0x20800000); + &data_word(0x00000080, 0x20820000, 0x00820080, 0x00000000); + &data_word(0x20000000, 0x20800080, 0x00020000, 0x00820080); + } diff --git a/libs/openssl/crypto/des/asm/des_enc.m4 b/libs/openssl/crypto/des/asm/des_enc.m4 new file mode 100644 index 00000000..32805954 --- /dev/null +++ b/libs/openssl/crypto/des/asm/des_enc.m4 @@ -0,0 +1,2099 @@ +! des_enc.m4 +! des_enc.S (generated from des_enc.m4) +! +! UltraSPARC assembler version of the LibDES/SSLeay/OpenSSL des_enc.c file. +! +! Version 1.0. 32-bit version. +! +! June 8, 2000. +! +! Version 2.0. 32/64-bit, PIC-ification, blended CPU adaptation +! by Andy Polyakov. +! +! January 1, 2003. +! +! Assembler version: Copyright Svend Olaf Mikkelsen. +! +! Original C code: Copyright Eric A. Young. +! +! This code can be freely used by LibDES/SSLeay/OpenSSL users. +! +! The LibDES/SSLeay/OpenSSL copyright notices must be respected. +! +! This version can be redistributed. +! +! To expand the m4 macros: m4 -B 8192 des_enc.m4 > des_enc.S +! +! Global registers 1 to 5 are used. This is the same as done by the +! cc compiler. The UltraSPARC load/store little endian feature is used. +! +! Instruction grouping often refers to one CPU cycle. +! +! Assemble through gcc: gcc -c -mcpu=ultrasparc -o des_enc.o des_enc.S +! +! Assemble through cc: cc -c -xarch=v8plusa -o des_enc.o des_enc.S +! +! Performance improvement according to './apps/openssl speed des' +! +! 32-bit build: +! 23% faster than cc-5.2 -xarch=v8plus -xO5 +! 115% faster than gcc-3.2.1 -m32 -mcpu=ultrasparc -O5 +! 64-bit build: +! 50% faster than cc-5.2 -xarch=v9 -xO5 +! 100% faster than gcc-3.2.1 -m64 -mcpu=ultrasparc -O5 +! + +.ident "des_enc.m4 2.1" +.file "des_enc-sparc.S" + +#if defined(__SUNPRO_C) && defined(__sparcv9) +# define ABI64 /* They've said -xarch=v9 at command line */ +#elif defined(__GNUC__) && defined(__arch64__) +# define ABI64 /* They've said -m64 at command line */ +#endif + +#ifdef ABI64 + .register %g2,#scratch + .register %g3,#scratch +# define FRAME -192 +# define BIAS 2047 +# define LDPTR ldx +# define STPTR stx +# define ARG0 128 +# define ARGSZ 8 +# ifndef OPENSSL_SYSNAME_ULTRASPARC +# define OPENSSL_SYSNAME_ULTRASPARC +# endif +#else +# define FRAME -96 +# define BIAS 0 +# define LDPTR ld +# define STPTR st +# define ARG0 68 +# define ARGSZ 4 +#endif + +#define LOOPS 7 + +#define global0 %g0 +#define global1 %g1 +#define global2 %g2 +#define global3 %g3 +#define global4 %g4 +#define global5 %g5 + +#define local0 %l0 +#define local1 %l1 +#define local2 %l2 +#define local3 %l3 +#define local4 %l4 +#define local5 %l5 +#define local7 %l6 +#define local6 %l7 + +#define in0 %i0 +#define in1 %i1 +#define in2 %i2 +#define in3 %i3 +#define in4 %i4 +#define in5 %i5 +#define in6 %i6 +#define in7 %i7 + +#define out0 %o0 +#define out1 %o1 +#define out2 %o2 +#define out3 %o3 +#define out4 %o4 +#define out5 %o5 +#define out6 %o6 +#define out7 %o7 + +#define stub stb + +changequote({,}) + + +! Macro definitions: + + +! {ip_macro} +! +! The logic used in initial and final permutations is the same as in +! the C code. The permutations are done with a clever shift, xor, and +! technique. +! +! The macro also loads address sbox 1 to 5 to global 1 to 5, address +! sbox 6 to local6, and addres sbox 8 to out3. +! +! Rotates the halfs 3 left to bring the sbox bits in convenient positions. +! +! Loads key first round from address in parameter 5 to out0, out1. +! +! After the the original LibDES initial permutation, the resulting left +! is in the variable initially used for right and vice versa. The macro +! implements the possibility to keep the halfs in the original registers. +! +! parameter 1 left +! parameter 2 right +! parameter 3 result left (modify in first round) +! parameter 4 result right (use in first round) +! parameter 5 key address +! parameter 6 1/2 for include encryption/decryption +! parameter 7 1 for move in1 to in3 +! parameter 8 1 for move in3 to in4, 2 for move in4 to in3 +! parameter 9 1 for load ks3 and ks2 to in4 and in3 + +define(ip_macro, { + +! {ip_macro} +! $1 $2 $4 $3 $5 $6 $7 $8 $9 + + ld [out2+256], local1 + srl $2, 4, local4 + + xor local4, $1, local4 + ifelse($7,1,{mov in1, in3},{nop}) + + ld [out2+260], local2 + and local4, local1, local4 + ifelse($8,1,{mov in3, in4},{}) + ifelse($8,2,{mov in4, in3},{}) + + ld [out2+280], out4 ! loop counter + sll local4, 4, local1 + xor $1, local4, $1 + + ld [out2+264], local3 + srl $1, 16, local4 + xor $2, local1, $2 + + ifelse($9,1,{LDPTR KS3, in4},{}) + xor local4, $2, local4 + nop !sethi %hi(DES_SPtrans), global1 ! sbox addr + + ifelse($9,1,{LDPTR KS2, in3},{}) + and local4, local2, local4 + nop !or global1, %lo(DES_SPtrans), global1 ! sbox addr + + sll local4, 16, local1 + xor $2, local4, $2 + + srl $2, 2, local4 + xor $1, local1, $1 + + sethi %hi(16711680), local5 + xor local4, $1, local4 + + and local4, local3, local4 + or local5, 255, local5 + + sll local4, 2, local2 + xor $1, local4, $1 + + srl $1, 8, local4 + xor $2, local2, $2 + + xor local4, $2, local4 + add global1, 768, global4 + + and local4, local5, local4 + add global1, 1024, global5 + + ld [out2+272], local7 + sll local4, 8, local1 + xor $2, local4, $2 + + srl $2, 1, local4 + xor $1, local1, $1 + + ld [$5], out0 ! key 7531 + xor local4, $1, local4 + add global1, 256, global2 + + ld [$5+4], out1 ! key 8642 + and local4, local7, local4 + add global1, 512, global3 + + sll local4, 1, local1 + xor $1, local4, $1 + + sll $1, 3, local3 + xor $2, local1, $2 + + sll $2, 3, local2 + add global1, 1280, local6 ! address sbox 8 + + srl $1, 29, local4 + add global1, 1792, out3 ! address sbox 8 + + srl $2, 29, local1 + or local4, local3, $4 + + or local2, local1, $3 + + ifelse($6, 1, { + + ld [out2+284], local5 ! 0x0000FC00 used in the rounds + or local2, local1, $3 + xor $4, out0, local1 + + call .des_enc.1 + and local1, 252, local1 + + },{}) + + ifelse($6, 2, { + + ld [out2+284], local5 ! 0x0000FC00 used in the rounds + or local2, local1, $3 + xor $4, out0, local1 + + call .des_dec.1 + and local1, 252, local1 + + },{}) +}) + + +! {rounds_macro} +! +! The logic used in the DES rounds is the same as in the C code, +! except that calculations for sbox 1 and sbox 5 begin before +! the previous round is finished. +! +! In each round one half (work) is modified based on key and the +! other half (use). +! +! In this version we do two rounds in a loop repeated 7 times +! and two rounds seperately. +! +! One half has the bits for the sboxes in the following positions: +! +! 777777xx555555xx333333xx111111xx +! +! 88xx666666xx444444xx222222xx8888 +! +! The bits for each sbox are xor-ed with the key bits for that box. +! The above xx bits are cleared, and the result used for lookup in +! the sbox table. Each sbox entry contains the 4 output bits permuted +! into 32 bits according to the P permutation. +! +! In the description of DES, left and right are switched after +! each round, except after last round. In this code the original +! left and right are kept in the same register in all rounds, meaning +! that after the 16 rounds the result for right is in the register +! originally used for left. +! +! parameter 1 first work (left in first round) +! parameter 2 first use (right in first round) +! parameter 3 enc/dec 1/-1 +! parameter 4 loop label +! parameter 5 key address register +! parameter 6 optional address for key next encryption/decryption +! parameter 7 not empty for include retl +! +! also compares in2 to 8 + +define(rounds_macro, { + +! {rounds_macro} +! $1 $2 $3 $4 $5 $6 $7 $8 $9 + + xor $2, out0, local1 + + ld [out2+284], local5 ! 0x0000FC00 + ba $4 + and local1, 252, local1 + + .align 32 + +$4: + ! local6 is address sbox 6 + ! out3 is address sbox 8 + ! out4 is loop counter + + ld [global1+local1], local1 + xor $2, out1, out1 ! 8642 + xor $2, out0, out0 ! 7531 + ! fmovs %f0, %f0 ! fxor used for alignment + + srl out1, 4, local0 ! rotate 4 right + and out0, local5, local3 ! 3 + ! fmovs %f0, %f0 + + ld [$5+$3*8], local7 ! key 7531 next round + srl local3, 8, local3 ! 3 + and local0, 252, local2 ! 2 + ! fmovs %f0, %f0 + + ld [global3+local3],local3 ! 3 + sll out1, 28, out1 ! rotate + xor $1, local1, $1 ! 1 finished, local1 now sbox 7 + + ld [global2+local2], local2 ! 2 + srl out0, 24, local1 ! 7 + or out1, local0, out1 ! rotate + + ldub [out2+local1], local1 ! 7 (and 0xFC) + srl out1, 24, local0 ! 8 + and out1, local5, local4 ! 4 + + ldub [out2+local0], local0 ! 8 (and 0xFC) + srl local4, 8, local4 ! 4 + xor $1, local2, $1 ! 2 finished local2 now sbox 6 + + ld [global4+local4],local4 ! 4 + srl out1, 16, local2 ! 6 + xor $1, local3, $1 ! 3 finished local3 now sbox 5 + + ld [out3+local0],local0 ! 8 + and local2, 252, local2 ! 6 + add global1, 1536, local5 ! address sbox 7 + + ld [local6+local2], local2 ! 6 + srl out0, 16, local3 ! 5 + xor $1, local4, $1 ! 4 finished + + ld [local5+local1],local1 ! 7 + and local3, 252, local3 ! 5 + xor $1, local0, $1 ! 8 finished + + ld [global5+local3],local3 ! 5 + xor $1, local2, $1 ! 6 finished + subcc out4, 1, out4 + + ld [$5+$3*8+4], out0 ! key 8642 next round + xor $1, local7, local2 ! sbox 5 next round + xor $1, local1, $1 ! 7 finished + + srl local2, 16, local2 ! sbox 5 next round + xor $1, local3, $1 ! 5 finished + + ld [$5+$3*16+4], out1 ! key 8642 next round again + and local2, 252, local2 ! sbox5 next round +! next round + xor $1, local7, local7 ! 7531 + + ld [global5+local2], local2 ! 5 + srl local7, 24, local3 ! 7 + xor $1, out0, out0 ! 8642 + + ldub [out2+local3], local3 ! 7 (and 0xFC) + srl out0, 4, local0 ! rotate 4 right + and local7, 252, local1 ! 1 + + sll out0, 28, out0 ! rotate + xor $2, local2, $2 ! 5 finished local2 used + + srl local0, 8, local4 ! 4 + and local0, 252, local2 ! 2 + ld [local5+local3], local3 ! 7 + + srl local0, 16, local5 ! 6 + or out0, local0, out0 ! rotate + ld [global2+local2], local2 ! 2 + + srl out0, 24, local0 + ld [$5+$3*16], out0 ! key 7531 next round + and local4, 252, local4 ! 4 + + and local5, 252, local5 ! 6 + ld [global4+local4], local4 ! 4 + xor $2, local3, $2 ! 7 finished local3 used + + and local0, 252, local0 ! 8 + ld [local6+local5], local5 ! 6 + xor $2, local2, $2 ! 2 finished local2 now sbox 3 + + srl local7, 8, local2 ! 3 start + ld [out3+local0], local0 ! 8 + xor $2, local4, $2 ! 4 finished + + and local2, 252, local2 ! 3 + ld [global1+local1], local1 ! 1 + xor $2, local5, $2 ! 6 finished local5 used + + ld [global3+local2], local2 ! 3 + xor $2, local0, $2 ! 8 finished + add $5, $3*16, $5 ! enc add 8, dec add -8 to key pointer + + ld [out2+284], local5 ! 0x0000FC00 + xor $2, out0, local4 ! sbox 1 next round + xor $2, local1, $2 ! 1 finished + + xor $2, local2, $2 ! 3 finished +#ifdef OPENSSL_SYSNAME_ULTRASPARC + bne,pt %icc, $4 +#else + bne $4 +#endif + and local4, 252, local1 ! sbox 1 next round + +! two rounds more: + + ld [global1+local1], local1 + xor $2, out1, out1 + xor $2, out0, out0 + + srl out1, 4, local0 ! rotate + and out0, local5, local3 + + ld [$5+$3*8], local7 ! key 7531 + srl local3, 8, local3 + and local0, 252, local2 + + ld [global3+local3],local3 + sll out1, 28, out1 ! rotate + xor $1, local1, $1 ! 1 finished, local1 now sbox 7 + + ld [global2+local2], local2 + srl out0, 24, local1 + or out1, local0, out1 ! rotate + + ldub [out2+local1], local1 + srl out1, 24, local0 + and out1, local5, local4 + + ldub [out2+local0], local0 + srl local4, 8, local4 + xor $1, local2, $1 ! 2 finished local2 now sbox 6 + + ld [global4+local4],local4 + srl out1, 16, local2 + xor $1, local3, $1 ! 3 finished local3 now sbox 5 + + ld [out3+local0],local0 + and local2, 252, local2 + add global1, 1536, local5 ! address sbox 7 + + ld [local6+local2], local2 + srl out0, 16, local3 + xor $1, local4, $1 ! 4 finished + + ld [local5+local1],local1 + and local3, 252, local3 + xor $1, local0, $1 + + ld [global5+local3],local3 + xor $1, local2, $1 ! 6 finished + cmp in2, 8 + + ifelse($6,{}, {}, {ld [out2+280], out4}) ! loop counter + xor $1, local7, local2 ! sbox 5 next round + xor $1, local1, $1 ! 7 finished + + ld [$5+$3*8+4], out0 + srl local2, 16, local2 ! sbox 5 next round + xor $1, local3, $1 ! 5 finished + + and local2, 252, local2 +! next round (two rounds more) + xor $1, local7, local7 ! 7531 + + ld [global5+local2], local2 + srl local7, 24, local3 + xor $1, out0, out0 ! 8642 + + ldub [out2+local3], local3 + srl out0, 4, local0 ! rotate + and local7, 252, local1 + + sll out0, 28, out0 ! rotate + xor $2, local2, $2 ! 5 finished local2 used + + srl local0, 8, local4 + and local0, 252, local2 + ld [local5+local3], local3 + + srl local0, 16, local5 + or out0, local0, out0 ! rotate + ld [global2+local2], local2 + + srl out0, 24, local0 + ifelse($6,{}, {}, {ld [$6], out0}) ! key next encryption/decryption + and local4, 252, local4 + + and local5, 252, local5 + ld [global4+local4], local4 + xor $2, local3, $2 ! 7 finished local3 used + + and local0, 252, local0 + ld [local6+local5], local5 + xor $2, local2, $2 ! 2 finished local2 now sbox 3 + + srl local7, 8, local2 ! 3 start + ld [out3+local0], local0 + xor $2, local4, $2 + + and local2, 252, local2 + ld [global1+local1], local1 + xor $2, local5, $2 ! 6 finished local5 used + + ld [global3+local2], local2 + srl $1, 3, local3 + xor $2, local0, $2 + + ifelse($6,{}, {}, {ld [$6+4], out1}) ! key next encryption/decryption + sll $1, 29, local4 + xor $2, local1, $2 + + ifelse($7,{}, {}, {retl}) + xor $2, local2, $2 +}) + + +! {fp_macro} +! +! parameter 1 right (original left) +! parameter 2 left (original right) +! parameter 3 1 for optional store to [in0] +! parameter 4 1 for load input/output address to local5/7 +! +! The final permutation logic switches the halfes, meaning that +! left and right ends up the the registers originally used. + +define(fp_macro, { + +! {fp_macro} +! $1 $2 $3 $4 $5 $6 $7 $8 $9 + + ! initially undo the rotate 3 left done after initial permutation + ! original left is received shifted 3 right and 29 left in local3/4 + + sll $2, 29, local1 + or local3, local4, $1 + + srl $2, 3, $2 + sethi %hi(0x55555555), local2 + + or $2, local1, $2 + or local2, %lo(0x55555555), local2 + + srl $2, 1, local3 + sethi %hi(0x00ff00ff), local1 + xor local3, $1, local3 + or local1, %lo(0x00ff00ff), local1 + and local3, local2, local3 + sethi %hi(0x33333333), local4 + sll local3, 1, local2 + + xor $1, local3, $1 + + srl $1, 8, local3 + xor $2, local2, $2 + xor local3, $2, local3 + or local4, %lo(0x33333333), local4 + and local3, local1, local3 + sethi %hi(0x0000ffff), local1 + sll local3, 8, local2 + + xor $2, local3, $2 + + srl $2, 2, local3 + xor $1, local2, $1 + xor local3, $1, local3 + or local1, %lo(0x0000ffff), local1 + and local3, local4, local3 + sethi %hi(0x0f0f0f0f), local4 + sll local3, 2, local2 + + ifelse($4,1, {LDPTR INPUT, local5}) + xor $1, local3, $1 + + ifelse($4,1, {LDPTR OUTPUT, local7}) + srl $1, 16, local3 + xor $2, local2, $2 + xor local3, $2, local3 + or local4, %lo(0x0f0f0f0f), local4 + and local3, local1, local3 + sll local3, 16, local2 + + xor $2, local3, local1 + + srl local1, 4, local3 + xor $1, local2, $1 + xor local3, $1, local3 + and local3, local4, local3 + sll local3, 4, local2 + + xor $1, local3, $1 + + ! optional store: + + ifelse($3,1, {st $1, [in0]}) + + xor local1, local2, $2 + + ifelse($3,1, {st $2, [in0+4]}) + +}) + + +! {fp_ip_macro} +! +! Does initial permutation for next block mixed with +! final permutation for current block. +! +! parameter 1 original left +! parameter 2 original right +! parameter 3 left ip +! parameter 4 right ip +! parameter 5 1: load ks1/ks2 to in3/in4, add 120 to in4 +! 2: mov in4 to in3 +! +! also adds -8 to length in2 and loads loop counter to out4 + +define(fp_ip_macro, { + +! {fp_ip_macro} +! $1 $2 $3 $4 $5 $6 $7 $8 $9 + + define({temp1},{out4}) + define({temp2},{local3}) + + define({ip1},{local1}) + define({ip2},{local2}) + define({ip4},{local4}) + define({ip5},{local5}) + + ! $1 in local3, local4 + + ld [out2+256], ip1 + sll out5, 29, temp1 + or local3, local4, $1 + + srl out5, 3, $2 + ifelse($5,2,{mov in4, in3}) + + ld [out2+272], ip5 + srl $4, 4, local0 + or $2, temp1, $2 + + srl $2, 1, temp1 + xor temp1, $1, temp1 + + and temp1, ip5, temp1 + xor local0, $3, local0 + + sll temp1, 1, temp2 + xor $1, temp1, $1 + + and local0, ip1, local0 + add in2, -8, in2 + + sll local0, 4, local7 + xor $3, local0, $3 + + ld [out2+268], ip4 + srl $1, 8, temp1 + xor $2, temp2, $2 + ld [out2+260], ip2 + srl $3, 16, local0 + xor $4, local7, $4 + xor temp1, $2, temp1 + xor local0, $4, local0 + and temp1, ip4, temp1 + and local0, ip2, local0 + sll temp1, 8, temp2 + xor $2, temp1, $2 + sll local0, 16, local7 + xor $4, local0, $4 + + srl $2, 2, temp1 + xor $1, temp2, $1 + + ld [out2+264], temp2 ! ip3 + srl $4, 2, local0 + xor $3, local7, $3 + xor temp1, $1, temp1 + xor local0, $3, local0 + and temp1, temp2, temp1 + and local0, temp2, local0 + sll temp1, 2, temp2 + xor $1, temp1, $1 + sll local0, 2, local7 + xor $3, local0, $3 + + srl $1, 16, temp1 + xor $2, temp2, $2 + srl $3, 8, local0 + xor $4, local7, $4 + xor temp1, $2, temp1 + xor local0, $4, local0 + and temp1, ip2, temp1 + and local0, ip4, local0 + sll temp1, 16, temp2 + xor $2, temp1, local4 + sll local0, 8, local7 + xor $4, local0, $4 + + srl $4, 1, local0 + xor $3, local7, $3 + + srl local4, 4, temp1 + xor local0, $3, local0 + + xor $1, temp2, $1 + and local0, ip5, local0 + + sll local0, 1, local7 + xor temp1, $1, temp1 + + xor $3, local0, $3 + xor $4, local7, $4 + + sll $3, 3, local5 + and temp1, ip1, temp1 + + sll temp1, 4, temp2 + xor $1, temp1, $1 + + ifelse($5,1,{LDPTR KS2, in4}) + sll $4, 3, local2 + xor local4, temp2, $2 + + ! reload since used as temporar: + + ld [out2+280], out4 ! loop counter + + srl $3, 29, local0 + ifelse($5,1,{add in4, 120, in4}) + + ifelse($5,1,{LDPTR KS1, in3}) + srl $4, 29, local7 + + or local0, local5, $4 + or local2, local7, $3 + +}) + + + +! {load_little_endian} +! +! parameter 1 address +! parameter 2 destination left +! parameter 3 destination right +! parameter 4 temporar +! parameter 5 label + +define(load_little_endian, { + +! {load_little_endian} +! $1 $2 $3 $4 $5 $6 $7 $8 $9 + + ! first in memory to rightmost in register + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + andcc $1, 3, global0 + bne,pn %icc, $5 + nop + + lda [$1] 0x88, $2 + add $1, 4, $4 + + ba,pt %icc, $5a + lda [$4] 0x88, $3 +#endif + +$5: + ldub [$1+3], $2 + + ldub [$1+2], $4 + sll $2, 8, $2 + or $2, $4, $2 + + ldub [$1+1], $4 + sll $2, 8, $2 + or $2, $4, $2 + + ldub [$1+0], $4 + sll $2, 8, $2 + or $2, $4, $2 + + + ldub [$1+3+4], $3 + + ldub [$1+2+4], $4 + sll $3, 8, $3 + or $3, $4, $3 + + ldub [$1+1+4], $4 + sll $3, 8, $3 + or $3, $4, $3 + + ldub [$1+0+4], $4 + sll $3, 8, $3 + or $3, $4, $3 +$5a: + +}) + + +! {load_little_endian_inc} +! +! parameter 1 address +! parameter 2 destination left +! parameter 3 destination right +! parameter 4 temporar +! parameter 4 label +! +! adds 8 to address + +define(load_little_endian_inc, { + +! {load_little_endian_inc} +! $1 $2 $3 $4 $5 $6 $7 $8 $9 + + ! first in memory to rightmost in register + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + andcc $1, 3, global0 + bne,pn %icc, $5 + nop + + lda [$1] 0x88, $2 + add $1, 4, $1 + + lda [$1] 0x88, $3 + ba,pt %icc, $5a + add $1, 4, $1 +#endif + +$5: + ldub [$1+3], $2 + + ldub [$1+2], $4 + sll $2, 8, $2 + or $2, $4, $2 + + ldub [$1+1], $4 + sll $2, 8, $2 + or $2, $4, $2 + + ldub [$1+0], $4 + sll $2, 8, $2 + or $2, $4, $2 + + ldub [$1+3+4], $3 + add $1, 8, $1 + + ldub [$1+2+4-8], $4 + sll $3, 8, $3 + or $3, $4, $3 + + ldub [$1+1+4-8], $4 + sll $3, 8, $3 + or $3, $4, $3 + + ldub [$1+0+4-8], $4 + sll $3, 8, $3 + or $3, $4, $3 +$5a: + +}) + + +! {load_n_bytes} +! +! Loads 1 to 7 bytes little endian +! Remaining bytes are zeroed. +! +! parameter 1 address +! parameter 2 length +! parameter 3 destination register left +! parameter 4 destination register right +! parameter 5 temp +! parameter 6 temp2 +! parameter 7 label +! parameter 8 return label + +define(load_n_bytes, { + +! {load_n_bytes} +! $1 $2 $5 $6 $7 $8 $7 $8 $9 + +$7.0: call .+8 + sll $2, 2, $6 + + add %o7,$7.jmp.table-$7.0,$5 + + add $5, $6, $5 + mov 0, $4 + + ld [$5], $5 + + jmp %o7+$5 + mov 0, $3 + +$7.7: + ldub [$1+6], $5 + sll $5, 16, $5 + or $3, $5, $3 +$7.6: + ldub [$1+5], $5 + sll $5, 8, $5 + or $3, $5, $3 +$7.5: + ldub [$1+4], $5 + or $3, $5, $3 +$7.4: + ldub [$1+3], $5 + sll $5, 24, $5 + or $4, $5, $4 +$7.3: + ldub [$1+2], $5 + sll $5, 16, $5 + or $4, $5, $4 +$7.2: + ldub [$1+1], $5 + sll $5, 8, $5 + or $4, $5, $4 +$7.1: + ldub [$1+0], $5 + ba $8 + or $4, $5, $4 + + .align 4 + +$7.jmp.table: + .word 0 + .word $7.1-$7.0 + .word $7.2-$7.0 + .word $7.3-$7.0 + .word $7.4-$7.0 + .word $7.5-$7.0 + .word $7.6-$7.0 + .word $7.7-$7.0 +}) + + +! {store_little_endian} +! +! parameter 1 address +! parameter 2 source left +! parameter 3 source right +! parameter 4 temporar + +define(store_little_endian, { + +! {store_little_endian} +! $1 $2 $3 $4 $5 $6 $7 $8 $9 + + ! rightmost in register to first in memory + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + andcc $1, 3, global0 + bne,pn %icc, $5 + nop + + sta $2, [$1] 0x88 + add $1, 4, $4 + + ba,pt %icc, $5a + sta $3, [$4] 0x88 +#endif + +$5: + and $2, 255, $4 + stub $4, [$1+0] + + srl $2, 8, $4 + and $4, 255, $4 + stub $4, [$1+1] + + srl $2, 16, $4 + and $4, 255, $4 + stub $4, [$1+2] + + srl $2, 24, $4 + stub $4, [$1+3] + + + and $3, 255, $4 + stub $4, [$1+0+4] + + srl $3, 8, $4 + and $4, 255, $4 + stub $4, [$1+1+4] + + srl $3, 16, $4 + and $4, 255, $4 + stub $4, [$1+2+4] + + srl $3, 24, $4 + stub $4, [$1+3+4] + +$5a: + +}) + + +! {store_n_bytes} +! +! Stores 1 to 7 bytes little endian +! +! parameter 1 address +! parameter 2 length +! parameter 3 source register left +! parameter 4 source register right +! parameter 5 temp +! parameter 6 temp2 +! parameter 7 label +! parameter 8 return label + +define(store_n_bytes, { + +! {store_n_bytes} +! $1 $2 $5 $6 $7 $8 $7 $8 $9 + +$7.0: call .+8 + sll $2, 2, $6 + + add %o7,$7.jmp.table-$7.0,$5 + + add $5, $6, $5 + + ld [$5], $5 + + jmp %o7+$5 + nop + +$7.7: + srl $3, 16, $5 + and $5, 0xff, $5 + stub $5, [$1+6] +$7.6: + srl $3, 8, $5 + and $5, 0xff, $5 + stub $5, [$1+5] +$7.5: + and $3, 0xff, $5 + stub $5, [$1+4] +$7.4: + srl $4, 24, $5 + stub $5, [$1+3] +$7.3: + srl $4, 16, $5 + and $5, 0xff, $5 + stub $5, [$1+2] +$7.2: + srl $4, 8, $5 + and $5, 0xff, $5 + stub $5, [$1+1] +$7.1: + and $4, 0xff, $5 + + + ba $8 + stub $5, [$1] + + .align 4 + +$7.jmp.table: + + .word 0 + .word $7.1-$7.0 + .word $7.2-$7.0 + .word $7.3-$7.0 + .word $7.4-$7.0 + .word $7.5-$7.0 + .word $7.6-$7.0 + .word $7.7-$7.0 +}) + + +define(testvalue,{1}) + +define(register_init, { + +! For test purposes: + + sethi %hi(testvalue), local0 + or local0, %lo(testvalue), local0 + + ifelse($1,{},{}, {mov local0, $1}) + ifelse($2,{},{}, {mov local0, $2}) + ifelse($3,{},{}, {mov local0, $3}) + ifelse($4,{},{}, {mov local0, $4}) + ifelse($5,{},{}, {mov local0, $5}) + ifelse($6,{},{}, {mov local0, $6}) + ifelse($7,{},{}, {mov local0, $7}) + ifelse($8,{},{}, {mov local0, $8}) + + mov local0, local1 + mov local0, local2 + mov local0, local3 + mov local0, local4 + mov local0, local5 + mov local0, local7 + mov local0, local6 + mov local0, out0 + mov local0, out1 + mov local0, out2 + mov local0, out3 + mov local0, out4 + mov local0, out5 + mov local0, global1 + mov local0, global2 + mov local0, global3 + mov local0, global4 + mov local0, global5 + +}) + +.section ".text" + + .align 32 + +.des_enc: + + ! key address in3 + ! loads key next encryption/decryption first round from [in4] + + rounds_macro(in5, out5, 1, .des_enc.1, in3, in4, retl) + + + .align 32 + +.des_dec: + + ! implemented with out5 as first parameter to avoid + ! register exchange in ede modes + + ! key address in4 + ! loads key next encryption/decryption first round from [in3] + + rounds_macro(out5, in5, -1, .des_dec.1, in4, in3, retl) + + + +! void DES_encrypt1(data, ks, enc) +! ******************************* + + .align 32 + .global DES_encrypt1 + .type DES_encrypt1,#function + +DES_encrypt1: + + save %sp, FRAME, %sp + + sethi %hi(.PIC.DES_SPtrans-1f),global1 + or global1,%lo(.PIC.DES_SPtrans-1f),global1 +1: call .+8 + add %o7,global1,global1 + sub global1,.PIC.DES_SPtrans-.des_and,out2 + + ld [in0], in5 ! left + cmp in2, 0 ! enc + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + be,pn %icc, .encrypt.dec ! enc/dec +#else + be .encrypt.dec +#endif + ld [in0+4], out5 ! right + + ! parameter 6 1/2 for include encryption/decryption + ! parameter 7 1 for move in1 to in3 + ! parameter 8 1 for move in3 to in4, 2 for move in4 to in3 + + ip_macro(in5, out5, in5, out5, in3, 0, 1, 1) + + rounds_macro(in5, out5, 1, .des_encrypt1.1, in3, in4) ! in4 not used + + fp_macro(in5, out5, 1) ! 1 for store to [in0] + + ret + restore + +.encrypt.dec: + + add in1, 120, in3 ! use last subkey for first round + + ! parameter 6 1/2 for include encryption/decryption + ! parameter 7 1 for move in1 to in3 + ! parameter 8 1 for move in3 to in4, 2 for move in4 to in3 + + ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include dec, ks in4 + + fp_macro(out5, in5, 1) ! 1 for store to [in0] + + ret + restore + +.DES_encrypt1.end: + .size DES_encrypt1,.DES_encrypt1.end-DES_encrypt1 + + +! void DES_encrypt2(data, ks, enc) +!********************************* + + ! encrypts/decrypts without initial/final permutation + + .align 32 + .global DES_encrypt2 + .type DES_encrypt2,#function + +DES_encrypt2: + + save %sp, FRAME, %sp + + sethi %hi(.PIC.DES_SPtrans-1f),global1 + or global1,%lo(.PIC.DES_SPtrans-1f),global1 +1: call .+8 + add %o7,global1,global1 + sub global1,.PIC.DES_SPtrans-.des_and,out2 + + ! Set sbox address 1 to 6 and rotate halfs 3 left + ! Errors caught by destest? Yes. Still? *NO* + + !sethi %hi(DES_SPtrans), global1 ! address sbox 1 + + !or global1, %lo(DES_SPtrans), global1 ! sbox 1 + + add global1, 256, global2 ! sbox 2 + add global1, 512, global3 ! sbox 3 + + ld [in0], out5 ! right + add global1, 768, global4 ! sbox 4 + add global1, 1024, global5 ! sbox 5 + + ld [in0+4], in5 ! left + add global1, 1280, local6 ! sbox 6 + add global1, 1792, out3 ! sbox 8 + + ! rotate + + sll in5, 3, local5 + mov in1, in3 ! key address to in3 + + sll out5, 3, local7 + srl in5, 29, in5 + + srl out5, 29, out5 + add in5, local5, in5 + + add out5, local7, out5 + cmp in2, 0 + + ! we use our own stackframe + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + be,pn %icc, .encrypt2.dec ! decryption +#else + be .encrypt2.dec +#endif + STPTR in0, [%sp+BIAS+ARG0+0*ARGSZ] + + ld [in3], out0 ! key 7531 first round + mov LOOPS, out4 ! loop counter + + ld [in3+4], out1 ! key 8642 first round + sethi %hi(0x0000FC00), local5 + + call .des_enc + mov in3, in4 + + ! rotate + sll in5, 29, in0 + srl in5, 3, in5 + sll out5, 29, in1 + add in5, in0, in5 + srl out5, 3, out5 + LDPTR [%sp+BIAS+ARG0+0*ARGSZ], in0 + add out5, in1, out5 + st in5, [in0] + st out5, [in0+4] + + ret + restore + + +.encrypt2.dec: + + add in3, 120, in4 + + ld [in4], out0 ! key 7531 first round + mov LOOPS, out4 ! loop counter + + ld [in4+4], out1 ! key 8642 first round + sethi %hi(0x0000FC00), local5 + + mov in5, local1 ! left expected in out5 + mov out5, in5 + + call .des_dec + mov local1, out5 + +.encrypt2.finish: + + ! rotate + sll in5, 29, in0 + srl in5, 3, in5 + sll out5, 29, in1 + add in5, in0, in5 + srl out5, 3, out5 + LDPTR [%sp+BIAS+ARG0+0*ARGSZ], in0 + add out5, in1, out5 + st out5, [in0] + st in5, [in0+4] + + ret + restore + +.DES_encrypt2.end: + .size DES_encrypt2, .DES_encrypt2.end-DES_encrypt2 + + +! void DES_encrypt3(data, ks1, ks2, ks3) +! ************************************** + + .align 32 + .global DES_encrypt3 + .type DES_encrypt3,#function + +DES_encrypt3: + + save %sp, FRAME, %sp + + sethi %hi(.PIC.DES_SPtrans-1f),global1 + or global1,%lo(.PIC.DES_SPtrans-1f),global1 +1: call .+8 + add %o7,global1,global1 + sub global1,.PIC.DES_SPtrans-.des_and,out2 + + ld [in0], in5 ! left + add in2, 120, in4 ! ks2 + + ld [in0+4], out5 ! right + mov in3, in2 ! save ks3 + + ! parameter 6 1/2 for include encryption/decryption + ! parameter 7 1 for mov in1 to in3 + ! parameter 8 1 for mov in3 to in4 + ! parameter 9 1 for load ks3 and ks2 to in4 and in3 + + ip_macro(in5, out5, in5, out5, in3, 1, 1, 0, 0) + + call .des_dec + mov in2, in3 ! preload ks3 + + call .des_enc + nop + + fp_macro(in5, out5, 1) + + ret + restore + +.DES_encrypt3.end: + .size DES_encrypt3,.DES_encrypt3.end-DES_encrypt3 + + +! void DES_decrypt3(data, ks1, ks2, ks3) +! ************************************** + + .align 32 + .global DES_decrypt3 + .type DES_decrypt3,#function + +DES_decrypt3: + + save %sp, FRAME, %sp + + sethi %hi(.PIC.DES_SPtrans-1f),global1 + or global1,%lo(.PIC.DES_SPtrans-1f),global1 +1: call .+8 + add %o7,global1,global1 + sub global1,.PIC.DES_SPtrans-.des_and,out2 + + ld [in0], in5 ! left + add in3, 120, in4 ! ks3 + + ld [in0+4], out5 ! right + mov in2, in3 ! ks2 + + ! parameter 6 1/2 for include encryption/decryption + ! parameter 7 1 for mov in1 to in3 + ! parameter 8 1 for mov in3 to in4 + ! parameter 9 1 for load ks3 and ks2 to in4 and in3 + + ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 0) + + call .des_enc + add in1, 120, in4 ! preload ks1 + + call .des_dec + nop + + fp_macro(out5, in5, 1) + + ret + restore + +.DES_decrypt3.end: + .size DES_decrypt3,.DES_decrypt3.end-DES_decrypt3 + +! void DES_ncbc_encrypt(input, output, length, schedule, ivec, enc) +! ***************************************************************** + + + .align 32 + .global DES_ncbc_encrypt + .type DES_ncbc_encrypt,#function + +DES_ncbc_encrypt: + + save %sp, FRAME, %sp + + define({INPUT}, { [%sp+BIAS+ARG0+0*ARGSZ] }) + define({OUTPUT}, { [%sp+BIAS+ARG0+1*ARGSZ] }) + define({IVEC}, { [%sp+BIAS+ARG0+4*ARGSZ] }) + + sethi %hi(.PIC.DES_SPtrans-1f),global1 + or global1,%lo(.PIC.DES_SPtrans-1f),global1 +1: call .+8 + add %o7,global1,global1 + sub global1,.PIC.DES_SPtrans-.des_and,out2 + + cmp in5, 0 ! enc + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + be,pn %icc, .ncbc.dec +#else + be .ncbc.dec +#endif + STPTR in4, IVEC + + ! addr left right temp label + load_little_endian(in4, in5, out5, local3, .LLE1) ! iv + + addcc in2, -8, in2 ! bytes missing when first block done + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + bl,pn %icc, .ncbc.enc.seven.or.less +#else + bl .ncbc.enc.seven.or.less +#endif + mov in3, in4 ! schedule + +.ncbc.enc.next.block: + + load_little_endian(in0, out4, global4, local3, .LLE2) ! block + +.ncbc.enc.next.block_1: + + xor in5, out4, in5 ! iv xor + xor out5, global4, out5 ! iv xor + + ! parameter 8 1 for move in3 to in4, 2 for move in4 to in3 + ip_macro(in5, out5, in5, out5, in3, 0, 0, 2) + +.ncbc.enc.next.block_2: + +!// call .des_enc ! compares in2 to 8 +! rounds inlined for alignment purposes + + add global1, 768, global4 ! address sbox 4 since register used below + + rounds_macro(in5, out5, 1, .ncbc.enc.1, in3, in4) ! include encryption ks in3 + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + bl,pn %icc, .ncbc.enc.next.block_fp +#else + bl .ncbc.enc.next.block_fp +#endif + add in0, 8, in0 ! input address + + ! If 8 or more bytes are to be encrypted after this block, + ! we combine final permutation for this block with initial + ! permutation for next block. Load next block: + + load_little_endian(in0, global3, global4, local5, .LLE12) + + ! parameter 1 original left + ! parameter 2 original right + ! parameter 3 left ip + ! parameter 4 right ip + ! parameter 5 1: load ks1/ks2 to in3/in4, add 120 to in4 + ! 2: mov in4 to in3 + ! + ! also adds -8 to length in2 and loads loop counter to out4 + + fp_ip_macro(out0, out1, global3, global4, 2) + + store_little_endian(in1, out0, out1, local3, .SLE10) ! block + + ld [in3], out0 ! key 7531 first round next block + mov in5, local1 + xor global3, out5, in5 ! iv xor next block + + ld [in3+4], out1 ! key 8642 + add global1, 512, global3 ! address sbox 3 since register used + xor global4, local1, out5 ! iv xor next block + + ba .ncbc.enc.next.block_2 + add in1, 8, in1 ! output adress + +.ncbc.enc.next.block_fp: + + fp_macro(in5, out5) + + store_little_endian(in1, in5, out5, local3, .SLE1) ! block + + addcc in2, -8, in2 ! bytes missing when next block done + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + bpos,pt %icc, .ncbc.enc.next.block ! also jumps if 0 +#else + bpos .ncbc.enc.next.block +#endif + add in1, 8, in1 + +.ncbc.enc.seven.or.less: + + cmp in2, -8 + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + ble,pt %icc, .ncbc.enc.finish +#else + ble .ncbc.enc.finish +#endif + nop + + add in2, 8, local1 ! bytes to load + + ! addr, length, dest left, dest right, temp, temp2, label, ret label + load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB1, .ncbc.enc.next.block_1) + + ! Loads 1 to 7 bytes little endian to global4, out4 + + +.ncbc.enc.finish: + + LDPTR IVEC, local4 + store_little_endian(local4, in5, out5, local5, .SLE2) ! ivec + + ret + restore + + +.ncbc.dec: + + STPTR in0, INPUT + cmp in2, 0 ! length + add in3, 120, in3 + + LDPTR IVEC, local7 ! ivec +#ifdef OPENSSL_SYSNAME_ULTRASPARC + ble,pn %icc, .ncbc.dec.finish +#else + ble .ncbc.dec.finish +#endif + mov in3, in4 ! schedule + + STPTR in1, OUTPUT + mov in0, local5 ! input + + load_little_endian(local7, in0, in1, local3, .LLE3) ! ivec + +.ncbc.dec.next.block: + + load_little_endian(local5, in5, out5, local3, .LLE4) ! block + + ! parameter 6 1/2 for include encryption/decryption + ! parameter 7 1 for mov in1 to in3 + ! parameter 8 1 for mov in3 to in4 + + ip_macro(in5, out5, out5, in5, in4, 2, 0, 1) ! include decryprion ks in4 + + fp_macro(out5, in5, 0, 1) ! 1 for input and output address to local5/7 + + ! in2 is bytes left to be stored + ! in2 is compared to 8 in the rounds + + xor out5, in0, out4 ! iv xor +#ifdef OPENSSL_SYSNAME_ULTRASPARC + bl,pn %icc, .ncbc.dec.seven.or.less +#else + bl .ncbc.dec.seven.or.less +#endif + xor in5, in1, global4 ! iv xor + + ! Load ivec next block now, since input and output address might be the same. + + load_little_endian_inc(local5, in0, in1, local3, .LLE5) ! iv + + store_little_endian(local7, out4, global4, local3, .SLE3) + + STPTR local5, INPUT + add local7, 8, local7 + addcc in2, -8, in2 + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + bg,pt %icc, .ncbc.dec.next.block +#else + bg .ncbc.dec.next.block +#endif + STPTR local7, OUTPUT + + +.ncbc.dec.store.iv: + + LDPTR IVEC, local4 ! ivec + store_little_endian(local4, in0, in1, local5, .SLE4) + +.ncbc.dec.finish: + + ret + restore + +.ncbc.dec.seven.or.less: + + load_little_endian_inc(local5, in0, in1, local3, .LLE13) ! ivec + + store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB1, .ncbc.dec.store.iv) + + +.DES_ncbc_encrypt.end: + .size DES_ncbc_encrypt, .DES_ncbc_encrypt.end-DES_ncbc_encrypt + + +! void DES_ede3_cbc_encrypt(input, output, lenght, ks1, ks2, ks3, ivec, enc) +! ************************************************************************** + + + .align 32 + .global DES_ede3_cbc_encrypt + .type DES_ede3_cbc_encrypt,#function + +DES_ede3_cbc_encrypt: + + save %sp, FRAME, %sp + + define({KS1}, { [%sp+BIAS+ARG0+3*ARGSZ] }) + define({KS2}, { [%sp+BIAS+ARG0+4*ARGSZ] }) + define({KS3}, { [%sp+BIAS+ARG0+5*ARGSZ] }) + + sethi %hi(.PIC.DES_SPtrans-1f),global1 + or global1,%lo(.PIC.DES_SPtrans-1f),global1 +1: call .+8 + add %o7,global1,global1 + sub global1,.PIC.DES_SPtrans-.des_and,out2 + + LDPTR [%fp+BIAS+ARG0+7*ARGSZ], local3 ! enc + LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local4 ! ivec + cmp local3, 0 ! enc + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + be,pn %icc, .ede3.dec +#else + be .ede3.dec +#endif + STPTR in4, KS2 + + STPTR in5, KS3 + + load_little_endian(local4, in5, out5, local3, .LLE6) ! ivec + + addcc in2, -8, in2 ! bytes missing after next block + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + bl,pn %icc, .ede3.enc.seven.or.less +#else + bl .ede3.enc.seven.or.less +#endif + STPTR in3, KS1 + +.ede3.enc.next.block: + + load_little_endian(in0, out4, global4, local3, .LLE7) + +.ede3.enc.next.block_1: + + LDPTR KS2, in4 + xor in5, out4, in5 ! iv xor + xor out5, global4, out5 ! iv xor + + LDPTR KS1, in3 + add in4, 120, in4 ! for decryption we use last subkey first + nop + + ip_macro(in5, out5, in5, out5, in3) + +.ede3.enc.next.block_2: + + call .des_enc ! ks1 in3 + nop + + call .des_dec ! ks2 in4 + LDPTR KS3, in3 + + call .des_enc ! ks3 in3 compares in2 to 8 + nop + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + bl,pn %icc, .ede3.enc.next.block_fp +#else + bl .ede3.enc.next.block_fp +#endif + add in0, 8, in0 + + ! If 8 or more bytes are to be encrypted after this block, + ! we combine final permutation for this block with initial + ! permutation for next block. Load next block: + + load_little_endian(in0, global3, global4, local5, .LLE11) + + ! parameter 1 original left + ! parameter 2 original right + ! parameter 3 left ip + ! parameter 4 right ip + ! parameter 5 1: load ks1/ks2 to in3/in4, add 120 to in4 + ! 2: mov in4 to in3 + ! + ! also adds -8 to length in2 and loads loop counter to out4 + + fp_ip_macro(out0, out1, global3, global4, 1) + + store_little_endian(in1, out0, out1, local3, .SLE9) ! block + + mov in5, local1 + xor global3, out5, in5 ! iv xor next block + + ld [in3], out0 ! key 7531 + add global1, 512, global3 ! address sbox 3 + xor global4, local1, out5 ! iv xor next block + + ld [in3+4], out1 ! key 8642 + add global1, 768, global4 ! address sbox 4 + ba .ede3.enc.next.block_2 + add in1, 8, in1 + +.ede3.enc.next.block_fp: + + fp_macro(in5, out5) + + store_little_endian(in1, in5, out5, local3, .SLE5) ! block + + addcc in2, -8, in2 ! bytes missing when next block done + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + bpos,pt %icc, .ede3.enc.next.block +#else + bpos .ede3.enc.next.block +#endif + add in1, 8, in1 + +.ede3.enc.seven.or.less: + + cmp in2, -8 + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + ble,pt %icc, .ede3.enc.finish +#else + ble .ede3.enc.finish +#endif + nop + + add in2, 8, local1 ! bytes to load + + ! addr, length, dest left, dest right, temp, temp2, label, ret label + load_n_bytes(in0, local1, global4, out4, local2, local3, .LNB2, .ede3.enc.next.block_1) + +.ede3.enc.finish: + + LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local4 ! ivec + store_little_endian(local4, in5, out5, local5, .SLE6) ! ivec + + ret + restore + +.ede3.dec: + + STPTR in0, INPUT + add in5, 120, in5 + + STPTR in1, OUTPUT + mov in0, local5 + add in3, 120, in3 + + STPTR in3, KS1 + cmp in2, 0 + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + ble %icc, .ede3.dec.finish +#else + ble .ede3.dec.finish +#endif + STPTR in5, KS3 + + LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local7 ! iv + load_little_endian(local7, in0, in1, local3, .LLE8) + +.ede3.dec.next.block: + + load_little_endian(local5, in5, out5, local3, .LLE9) + + ! parameter 6 1/2 for include encryption/decryption + ! parameter 7 1 for mov in1 to in3 + ! parameter 8 1 for mov in3 to in4 + ! parameter 9 1 for load ks3 and ks2 to in4 and in3 + + ip_macro(in5, out5, out5, in5, in4, 2, 0, 0, 1) ! inc .des_dec ks3 in4 + + call .des_enc ! ks2 in3 + LDPTR KS1, in4 + + call .des_dec ! ks1 in4 + nop + + fp_macro(out5, in5, 0, 1) ! 1 for input and output address local5/7 + + ! in2 is bytes left to be stored + ! in2 is compared to 8 in the rounds + + xor out5, in0, out4 +#ifdef OPENSSL_SYSNAME_ULTRASPARC + bl,pn %icc, .ede3.dec.seven.or.less +#else + bl .ede3.dec.seven.or.less +#endif + xor in5, in1, global4 + + load_little_endian_inc(local5, in0, in1, local3, .LLE10) ! iv next block + + store_little_endian(local7, out4, global4, local3, .SLE7) ! block + + STPTR local5, INPUT + addcc in2, -8, in2 + add local7, 8, local7 + +#ifdef OPENSSL_SYSNAME_ULTRASPARC + bg,pt %icc, .ede3.dec.next.block +#else + bg .ede3.dec.next.block +#endif + STPTR local7, OUTPUT + +.ede3.dec.store.iv: + + LDPTR [%fp+BIAS+ARG0+6*ARGSZ], local4 ! ivec + store_little_endian(local4, in0, in1, local5, .SLE8) ! ivec + +.ede3.dec.finish: + + ret + restore + +.ede3.dec.seven.or.less: + + load_little_endian_inc(local5, in0, in1, local3, .LLE14) ! iv + + store_n_bytes(local7, in2, global4, out4, local3, local4, .SNB2, .ede3.dec.store.iv) + + +.DES_ede3_cbc_encrypt.end: + .size DES_ede3_cbc_encrypt,.DES_ede3_cbc_encrypt.end-DES_ede3_cbc_encrypt + + .align 256 + .type .des_and,#object + .size .des_and,284 + +.des_and: + +! This table is used for AND 0xFC when it is known that register +! bits 8-31 are zero. Makes it possible to do three arithmetic +! operations in one cycle. + + .byte 0, 0, 0, 0, 4, 4, 4, 4 + .byte 8, 8, 8, 8, 12, 12, 12, 12 + .byte 16, 16, 16, 16, 20, 20, 20, 20 + .byte 24, 24, 24, 24, 28, 28, 28, 28 + .byte 32, 32, 32, 32, 36, 36, 36, 36 + .byte 40, 40, 40, 40, 44, 44, 44, 44 + .byte 48, 48, 48, 48, 52, 52, 52, 52 + .byte 56, 56, 56, 56, 60, 60, 60, 60 + .byte 64, 64, 64, 64, 68, 68, 68, 68 + .byte 72, 72, 72, 72, 76, 76, 76, 76 + .byte 80, 80, 80, 80, 84, 84, 84, 84 + .byte 88, 88, 88, 88, 92, 92, 92, 92 + .byte 96, 96, 96, 96, 100, 100, 100, 100 + .byte 104, 104, 104, 104, 108, 108, 108, 108 + .byte 112, 112, 112, 112, 116, 116, 116, 116 + .byte 120, 120, 120, 120, 124, 124, 124, 124 + .byte 128, 128, 128, 128, 132, 132, 132, 132 + .byte 136, 136, 136, 136, 140, 140, 140, 140 + .byte 144, 144, 144, 144, 148, 148, 148, 148 + .byte 152, 152, 152, 152, 156, 156, 156, 156 + .byte 160, 160, 160, 160, 164, 164, 164, 164 + .byte 168, 168, 168, 168, 172, 172, 172, 172 + .byte 176, 176, 176, 176, 180, 180, 180, 180 + .byte 184, 184, 184, 184, 188, 188, 188, 188 + .byte 192, 192, 192, 192, 196, 196, 196, 196 + .byte 200, 200, 200, 200, 204, 204, 204, 204 + .byte 208, 208, 208, 208, 212, 212, 212, 212 + .byte 216, 216, 216, 216, 220, 220, 220, 220 + .byte 224, 224, 224, 224, 228, 228, 228, 228 + .byte 232, 232, 232, 232, 236, 236, 236, 236 + .byte 240, 240, 240, 240, 244, 244, 244, 244 + .byte 248, 248, 248, 248, 252, 252, 252, 252 + + ! 5 numbers for initil/final permutation + + .word 0x0f0f0f0f ! offset 256 + .word 0x0000ffff ! 260 + .word 0x33333333 ! 264 + .word 0x00ff00ff ! 268 + .word 0x55555555 ! 272 + + .word 0 ! 276 + .word LOOPS ! 280 + .word 0x0000FC00 ! 284 + + .global DES_SPtrans + .type DES_SPtrans,#object + .size DES_SPtrans,2048 +.align 64 +DES_SPtrans: +.PIC.DES_SPtrans: + ! nibble 0 + .word 0x02080800, 0x00080000, 0x02000002, 0x02080802 + .word 0x02000000, 0x00080802, 0x00080002, 0x02000002 + .word 0x00080802, 0x02080800, 0x02080000, 0x00000802 + .word 0x02000802, 0x02000000, 0x00000000, 0x00080002 + .word 0x00080000, 0x00000002, 0x02000800, 0x00080800 + .word 0x02080802, 0x02080000, 0x00000802, 0x02000800 + .word 0x00000002, 0x00000800, 0x00080800, 0x02080002 + .word 0x00000800, 0x02000802, 0x02080002, 0x00000000 + .word 0x00000000, 0x02080802, 0x02000800, 0x00080002 + .word 0x02080800, 0x00080000, 0x00000802, 0x02000800 + .word 0x02080002, 0x00000800, 0x00080800, 0x02000002 + .word 0x00080802, 0x00000002, 0x02000002, 0x02080000 + .word 0x02080802, 0x00080800, 0x02080000, 0x02000802 + .word 0x02000000, 0x00000802, 0x00080002, 0x00000000 + .word 0x00080000, 0x02000000, 0x02000802, 0x02080800 + .word 0x00000002, 0x02080002, 0x00000800, 0x00080802 + ! nibble 1 + .word 0x40108010, 0x00000000, 0x00108000, 0x40100000 + .word 0x40000010, 0x00008010, 0x40008000, 0x00108000 + .word 0x00008000, 0x40100010, 0x00000010, 0x40008000 + .word 0x00100010, 0x40108000, 0x40100000, 0x00000010 + .word 0x00100000, 0x40008010, 0x40100010, 0x00008000 + .word 0x00108010, 0x40000000, 0x00000000, 0x00100010 + .word 0x40008010, 0x00108010, 0x40108000, 0x40000010 + .word 0x40000000, 0x00100000, 0x00008010, 0x40108010 + .word 0x00100010, 0x40108000, 0x40008000, 0x00108010 + .word 0x40108010, 0x00100010, 0x40000010, 0x00000000 + .word 0x40000000, 0x00008010, 0x00100000, 0x40100010 + .word 0x00008000, 0x40000000, 0x00108010, 0x40008010 + .word 0x40108000, 0x00008000, 0x00000000, 0x40000010 + .word 0x00000010, 0x40108010, 0x00108000, 0x40100000 + .word 0x40100010, 0x00100000, 0x00008010, 0x40008000 + .word 0x40008010, 0x00000010, 0x40100000, 0x00108000 + ! nibble 2 + .word 0x04000001, 0x04040100, 0x00000100, 0x04000101 + .word 0x00040001, 0x04000000, 0x04000101, 0x00040100 + .word 0x04000100, 0x00040000, 0x04040000, 0x00000001 + .word 0x04040101, 0x00000101, 0x00000001, 0x04040001 + .word 0x00000000, 0x00040001, 0x04040100, 0x00000100 + .word 0x00000101, 0x04040101, 0x00040000, 0x04000001 + .word 0x04040001, 0x04000100, 0x00040101, 0x04040000 + .word 0x00040100, 0x00000000, 0x04000000, 0x00040101 + .word 0x04040100, 0x00000100, 0x00000001, 0x00040000 + .word 0x00000101, 0x00040001, 0x04040000, 0x04000101 + .word 0x00000000, 0x04040100, 0x00040100, 0x04040001 + .word 0x00040001, 0x04000000, 0x04040101, 0x00000001 + .word 0x00040101, 0x04000001, 0x04000000, 0x04040101 + .word 0x00040000, 0x04000100, 0x04000101, 0x00040100 + .word 0x04000100, 0x00000000, 0x04040001, 0x00000101 + .word 0x04000001, 0x00040101, 0x00000100, 0x04040000 + ! nibble 3 + .word 0x00401008, 0x10001000, 0x00000008, 0x10401008 + .word 0x00000000, 0x10400000, 0x10001008, 0x00400008 + .word 0x10401000, 0x10000008, 0x10000000, 0x00001008 + .word 0x10000008, 0x00401008, 0x00400000, 0x10000000 + .word 0x10400008, 0x00401000, 0x00001000, 0x00000008 + .word 0x00401000, 0x10001008, 0x10400000, 0x00001000 + .word 0x00001008, 0x00000000, 0x00400008, 0x10401000 + .word 0x10001000, 0x10400008, 0x10401008, 0x00400000 + .word 0x10400008, 0x00001008, 0x00400000, 0x10000008 + .word 0x00401000, 0x10001000, 0x00000008, 0x10400000 + .word 0x10001008, 0x00000000, 0x00001000, 0x00400008 + .word 0x00000000, 0x10400008, 0x10401000, 0x00001000 + .word 0x10000000, 0x10401008, 0x00401008, 0x00400000 + .word 0x10401008, 0x00000008, 0x10001000, 0x00401008 + .word 0x00400008, 0x00401000, 0x10400000, 0x10001008 + .word 0x00001008, 0x10000000, 0x10000008, 0x10401000 + ! nibble 4 + .word 0x08000000, 0x00010000, 0x00000400, 0x08010420 + .word 0x08010020, 0x08000400, 0x00010420, 0x08010000 + .word 0x00010000, 0x00000020, 0x08000020, 0x00010400 + .word 0x08000420, 0x08010020, 0x08010400, 0x00000000 + .word 0x00010400, 0x08000000, 0x00010020, 0x00000420 + .word 0x08000400, 0x00010420, 0x00000000, 0x08000020 + .word 0x00000020, 0x08000420, 0x08010420, 0x00010020 + .word 0x08010000, 0x00000400, 0x00000420, 0x08010400 + .word 0x08010400, 0x08000420, 0x00010020, 0x08010000 + .word 0x00010000, 0x00000020, 0x08000020, 0x08000400 + .word 0x08000000, 0x00010400, 0x08010420, 0x00000000 + .word 0x00010420, 0x08000000, 0x00000400, 0x00010020 + .word 0x08000420, 0x00000400, 0x00000000, 0x08010420 + .word 0x08010020, 0x08010400, 0x00000420, 0x00010000 + .word 0x00010400, 0x08010020, 0x08000400, 0x00000420 + .word 0x00000020, 0x00010420, 0x08010000, 0x08000020 + ! nibble 5 + .word 0x80000040, 0x00200040, 0x00000000, 0x80202000 + .word 0x00200040, 0x00002000, 0x80002040, 0x00200000 + .word 0x00002040, 0x80202040, 0x00202000, 0x80000000 + .word 0x80002000, 0x80000040, 0x80200000, 0x00202040 + .word 0x00200000, 0x80002040, 0x80200040, 0x00000000 + .word 0x00002000, 0x00000040, 0x80202000, 0x80200040 + .word 0x80202040, 0x80200000, 0x80000000, 0x00002040 + .word 0x00000040, 0x00202000, 0x00202040, 0x80002000 + .word 0x00002040, 0x80000000, 0x80002000, 0x00202040 + .word 0x80202000, 0x00200040, 0x00000000, 0x80002000 + .word 0x80000000, 0x00002000, 0x80200040, 0x00200000 + .word 0x00200040, 0x80202040, 0x00202000, 0x00000040 + .word 0x80202040, 0x00202000, 0x00200000, 0x80002040 + .word 0x80000040, 0x80200000, 0x00202040, 0x00000000 + .word 0x00002000, 0x80000040, 0x80002040, 0x80202000 + .word 0x80200000, 0x00002040, 0x00000040, 0x80200040 + ! nibble 6 + .word 0x00004000, 0x00000200, 0x01000200, 0x01000004 + .word 0x01004204, 0x00004004, 0x00004200, 0x00000000 + .word 0x01000000, 0x01000204, 0x00000204, 0x01004000 + .word 0x00000004, 0x01004200, 0x01004000, 0x00000204 + .word 0x01000204, 0x00004000, 0x00004004, 0x01004204 + .word 0x00000000, 0x01000200, 0x01000004, 0x00004200 + .word 0x01004004, 0x00004204, 0x01004200, 0x00000004 + .word 0x00004204, 0x01004004, 0x00000200, 0x01000000 + .word 0x00004204, 0x01004000, 0x01004004, 0x00000204 + .word 0x00004000, 0x00000200, 0x01000000, 0x01004004 + .word 0x01000204, 0x00004204, 0x00004200, 0x00000000 + .word 0x00000200, 0x01000004, 0x00000004, 0x01000200 + .word 0x00000000, 0x01000204, 0x01000200, 0x00004200 + .word 0x00000204, 0x00004000, 0x01004204, 0x01000000 + .word 0x01004200, 0x00000004, 0x00004004, 0x01004204 + .word 0x01000004, 0x01004200, 0x01004000, 0x00004004 + ! nibble 7 + .word 0x20800080, 0x20820000, 0x00020080, 0x00000000 + .word 0x20020000, 0x00800080, 0x20800000, 0x20820080 + .word 0x00000080, 0x20000000, 0x00820000, 0x00020080 + .word 0x00820080, 0x20020080, 0x20000080, 0x20800000 + .word 0x00020000, 0x00820080, 0x00800080, 0x20020000 + .word 0x20820080, 0x20000080, 0x00000000, 0x00820000 + .word 0x20000000, 0x00800000, 0x20020080, 0x20800080 + .word 0x00800000, 0x00020000, 0x20820000, 0x00000080 + .word 0x00800000, 0x00020000, 0x20000080, 0x20820080 + .word 0x00020080, 0x20000000, 0x00000000, 0x00820000 + .word 0x20800080, 0x20020080, 0x20020000, 0x00800080 + .word 0x20820000, 0x00000080, 0x00800080, 0x20020000 + .word 0x20820080, 0x00800000, 0x20800000, 0x20000080 + .word 0x00820000, 0x00020080, 0x20020080, 0x20800000 + .word 0x00000080, 0x20820000, 0x00820080, 0x00000000 + .word 0x20000000, 0x20800080, 0x00020000, 0x00820080 + diff --git a/libs/openssl/crypto/des/asm/desboth.pl b/libs/openssl/crypto/des/asm/desboth.pl new file mode 100644 index 00000000..eec00886 --- /dev/null +++ b/libs/openssl/crypto/des/asm/desboth.pl @@ -0,0 +1,79 @@ +#!/usr/local/bin/perl + +$L="edi"; +$R="esi"; + +sub DES_encrypt3 + { + local($name,$enc)=@_; + + &function_begin_B($name,""); + &push("ebx"); + &mov("ebx",&wparam(0)); + + &push("ebp"); + &push("esi"); + + &push("edi"); + + &comment(""); + &comment("Load the data words"); + &mov($L,&DWP(0,"ebx","",0)); + &mov($R,&DWP(4,"ebx","",0)); + &stack_push(3); + + &comment(""); + &comment("IP"); + &IP_new($L,$R,"edx",0); + + # put them back + + if ($enc) + { + &mov(&DWP(4,"ebx","",0),$R); + &mov("eax",&wparam(1)); + &mov(&DWP(0,"ebx","",0),"edx"); + &mov("edi",&wparam(2)); + &mov("esi",&wparam(3)); + } + else + { + &mov(&DWP(4,"ebx","",0),$R); + &mov("esi",&wparam(1)); + &mov(&DWP(0,"ebx","",0),"edx"); + &mov("edi",&wparam(2)); + &mov("eax",&wparam(3)); + } + &mov(&swtmp(2), (DWC(($enc)?"1":"0"))); + &mov(&swtmp(1), "eax"); + &mov(&swtmp(0), "ebx"); + &call("DES_encrypt2"); + &mov(&swtmp(2), (DWC(($enc)?"0":"1"))); + &mov(&swtmp(1), "edi"); + &mov(&swtmp(0), "ebx"); + &call("DES_encrypt2"); + &mov(&swtmp(2), (DWC(($enc)?"1":"0"))); + &mov(&swtmp(1), "esi"); + &mov(&swtmp(0), "ebx"); + &call("DES_encrypt2"); + + &stack_pop(3); + &mov($L,&DWP(0,"ebx","",0)); + &mov($R,&DWP(4,"ebx","",0)); + + &comment(""); + &comment("FP"); + &FP_new($L,$R,"eax",0); + + &mov(&DWP(0,"ebx","",0),"eax"); + &mov(&DWP(4,"ebx","",0),$R); + + &pop("edi"); + &pop("esi"); + &pop("ebp"); + &pop("ebx"); + &ret(); + &function_end_B($name); + } + + diff --git a/libs/openssl/crypto/des/asm/readme b/libs/openssl/crypto/des/asm/readme new file mode 100644 index 00000000..1beafe25 --- /dev/null +++ b/libs/openssl/crypto/des/asm/readme @@ -0,0 +1,131 @@ +First up, let me say I don't like writing in assembler. It is not portable, +dependant on the particular CPU architecture release and is generally a pig +to debug and get right. Having said that, the x86 architecture is probably +the most important for speed due to number of boxes and since +it appears to be the worst architecture to to get +good C compilers for. So due to this, I have lowered myself to do +assembler for the inner DES routines in libdes :-). + +The file to implement in assembler is des_enc.c. Replace the following +4 functions +des_encrypt1(DES_LONG data[2],des_key_schedule ks, int encrypt); +des_encrypt2(DES_LONG data[2],des_key_schedule ks, int encrypt); +des_encrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3); +des_decrypt3(DES_LONG data[2],des_key_schedule ks1,ks2,ks3); + +They encrypt/decrypt the 64 bits held in 'data' using +the 'ks' key schedules. The only difference between the 4 functions is that +des_encrypt2() does not perform IP() or FP() on the data (this is an +optimization for when doing triple DES and des_encrypt3() and des_decrypt3() +perform triple des. The triple DES routines are in here because it does +make a big difference to have them located near the des_encrypt2 function +at link time.. + +Now as we all know, there are lots of different operating systems running on +x86 boxes, and unfortunately they normally try to make sure their assembler +formating is not the same as the other peoples. +The 4 main formats I know of are +Microsoft Windows 95/Windows NT +Elf Includes Linux and FreeBSD(?). +a.out The older Linux. +Solaris Same as Elf but different comments :-(. + +Now I was not overly keen to write 4 different copies of the same code, +so I wrote a few perl routines to output the correct assembler, given +a target assembler type. This code is ugly and is just a hack. +The libraries are x86unix.pl and x86ms.pl. +des586.pl, des686.pl and des-som[23].pl are the programs to actually +generate the assembler. + +So to generate elf assembler +perl des-som3.pl elf >dx86-elf.s +For Windows 95/NT +perl des-som2.pl win32 >win32.asm + +[ update 4 Jan 1996 ] +I have added another way to do things. +perl des-som3.pl cpp >dx86-cpp.s +generates a file that will be included by dx86unix.cpp when it is compiled. +To build for elf, a.out, solaris, bsdi etc, +cc -E -DELF asm/dx86unix.cpp | as -o asm/dx86-elf.o +cc -E -DSOL asm/dx86unix.cpp | as -o asm/dx86-sol.o +cc -E -DOUT asm/dx86unix.cpp | as -o asm/dx86-out.o +cc -E -DBSDI asm/dx86unix.cpp | as -o asm/dx86bsdi.o +This was done to cut down the number of files in the distribution. + +Now the ugly part. I acquired my copy of Intels +"Optimization's For Intel's 32-Bit Processors" and found a few interesting +things. First, the aim of the exersize is to 'extract' one byte at a time +from a word and do an array lookup. This involves getting the byte from +the 4 locations in the word and moving it to a new word and doing the lookup. +The most obvious way to do this is +xor eax, eax # clear word +movb al, cl # get low byte +xor edi DWORD PTR 0x100+des_SP[eax] # xor in word +movb al, ch # get next byte +xor edi DWORD PTR 0x300+des_SP[eax] # xor in word +shr ecx 16 +which seems ok. For the pentium, this system appears to be the best. +One has to do instruction interleaving to keep both functional units +operating, but it is basically very efficient. + +Now the crunch. When a full register is used after a partial write, eg. +mov al, cl +xor edi, DWORD PTR 0x100+des_SP[eax] +386 - 1 cycle stall +486 - 1 cycle stall +586 - 0 cycle stall +686 - at least 7 cycle stall (page 22 of the above mentioned document). + +So the technique that produces the best results on a pentium, according to +the documentation, will produce hideous results on a pentium pro. + +To get around this, des686.pl will generate code that is not as fast on +a pentium, should be very good on a pentium pro. +mov eax, ecx # copy word +shr ecx, 8 # line up next byte +and eax, 0fch # mask byte +xor edi DWORD PTR 0x100+des_SP[eax] # xor in array lookup +mov eax, ecx # get word +shr ecx 8 # line up next byte +and eax, 0fch # mask byte +xor edi DWORD PTR 0x300+des_SP[eax] # xor in array lookup + +Due to the execution units in the pentium, this actually works quite well. +For a pentium pro it should be very good. This is the type of output +Visual C++ generates. + +There is a third option. instead of using +mov al, ch +which is bad on the pentium pro, one may be able to use +movzx eax, ch +which may not incur the partial write penalty. On the pentium, +this instruction takes 4 cycles so is not worth using but on the +pentium pro it appears it may be worth while. I need access to one to +experiment :-). + +eric (20 Oct 1996) + +22 Nov 1996 - I have asked people to run the 2 different version on pentium +pros and it appears that the intel documentation is wrong. The +mov al,bh is still faster on a pentium pro, so just use the des586.pl +install des686.pl + +3 Dec 1996 - I added des_encrypt3/des_decrypt3 because I have moved these +functions into des_enc.c because it does make a massive performance +difference on some boxes to have the functions code located close to +the des_encrypt2() function. + +9 Jan 1997 - des-som2.pl is now the correct perl script to use for +pentiums. It contains an inner loop from +Svend Olaf Mikkelsen which does raw ecb DES calls at +273,000 per second. He had a previous version at 250,000 and the best +I was able to get was 203,000. The content has not changed, this is all +due to instruction sequencing (and actual instructions choice) which is able +to keep both functional units of the pentium going. +We may have lost the ugly register usage restrictions when x86 went 32 bit +but for the pentium it has been replaced by evil instruction ordering tricks. + +13 Jan 1997 - des-som3.pl, more optimizations from Svend Olaf. +raw DES at 281,000 per second on a pentium 100. + diff --git a/libs/openssl/crypto/des/cbc3_enc.c b/libs/openssl/crypto/des/cbc3_enc.c new file mode 100644 index 00000000..249518a6 --- /dev/null +++ b/libs/openssl/crypto/des/cbc3_enc.c @@ -0,0 +1,95 @@ +/* crypto/des/cbc3_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +/* HAS BUGS! DON'T USE - this is only present for use in des.c */ +void DES_3cbc_encrypt(DES_cblock *input, DES_cblock *output, long length, + DES_key_schedule ks1, DES_key_schedule ks2, + DES_cblock *iv1, DES_cblock *iv2, int enc) +{ + int off = ((int)length - 1) / 8; + long l8 = ((length + 7) / 8) * 8; + DES_cblock niv1, niv2; + + if (enc == DES_ENCRYPT) { + DES_cbc_encrypt((unsigned char *)input, + (unsigned char *)output, length, &ks1, iv1, enc); + if (length >= sizeof(DES_cblock)) + memcpy(niv1, output[off], sizeof(DES_cblock)); + DES_cbc_encrypt((unsigned char *)output, + (unsigned char *)output, l8, &ks2, iv1, !enc); + DES_cbc_encrypt((unsigned char *)output, + (unsigned char *)output, l8, &ks1, iv2, enc); + if (length >= sizeof(DES_cblock)) + memcpy(niv2, output[off], sizeof(DES_cblock)); + } else { + if (length >= sizeof(DES_cblock)) + memcpy(niv2, input[off], sizeof(DES_cblock)); + DES_cbc_encrypt((unsigned char *)input, + (unsigned char *)output, l8, &ks1, iv2, enc); + DES_cbc_encrypt((unsigned char *)output, + (unsigned char *)output, l8, &ks2, iv1, !enc); + if (length >= sizeof(DES_cblock)) + memcpy(niv1, output[off], sizeof(DES_cblock)); + DES_cbc_encrypt((unsigned char *)output, + (unsigned char *)output, length, &ks1, iv1, enc); + } + memcpy(*iv1, niv1, sizeof(DES_cblock)); + memcpy(*iv2, niv2, sizeof(DES_cblock)); +} diff --git a/libs/openssl/crypto/des/cbc_cksm.c b/libs/openssl/crypto/des/cbc_cksm.c new file mode 100644 index 00000000..f89b5b98 --- /dev/null +++ b/libs/openssl/crypto/des/cbc_cksm.c @@ -0,0 +1,103 @@ +/* crypto/des/cbc_cksm.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +DES_LONG DES_cbc_cksum(const unsigned char *in, DES_cblock *output, + long length, DES_key_schedule *schedule, + const_DES_cblock *ivec) +{ + register DES_LONG tout0, tout1, tin0, tin1; + register long l = length; + DES_LONG tin[2]; + unsigned char *out = &(*output)[0]; + const unsigned char *iv = &(*ivec)[0]; + + c2l(iv, tout0); + c2l(iv, tout1); + for (; l > 0; l -= 8) { + if (l >= 8) { + c2l(in, tin0); + c2l(in, tin1); + } else + c2ln(in, tin0, tin1, l); + + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT); + /* fix 15/10/91 eay - thanks to keithr@sco.COM */ + tout0 = tin[0]; + tout1 = tin[1]; + } + if (out != NULL) { + l2c(tout0, out); + l2c(tout1, out); + } + tout0 = tin0 = tin1 = tin[0] = tin[1] = 0; + /* + * Transform the data in tout1 so that it will match the return value + * that the MIT Kerberos mit_des_cbc_cksum API returns. + */ + tout1 = ((tout1 >> 24L) & 0x000000FF) + | ((tout1 >> 8L) & 0x0000FF00) + | ((tout1 << 8L) & 0x00FF0000) + | ((tout1 << 24L) & 0xFF000000); + return (tout1); +} diff --git a/libs/openssl/crypto/des/cbc_enc.c b/libs/openssl/crypto/des/cbc_enc.c new file mode 100644 index 00000000..7ee35992 --- /dev/null +++ b/libs/openssl/crypto/des/cbc_enc.c @@ -0,0 +1,61 @@ +/* crypto/des/cbc_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#define CBC_ENC_C__DONT_UPDATE_IV + +#include "ncbc_enc.c" /* des_cbc_encrypt */ diff --git a/libs/openssl/crypto/des/cfb64ede.c b/libs/openssl/crypto/des/cfb64ede.c new file mode 100644 index 00000000..5d709c12 --- /dev/null +++ b/libs/openssl/crypto/des/cfb64ede.c @@ -0,0 +1,249 @@ +/* crypto/des/cfb64ede.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" +#include "e_os.h" + +/* + * The input and output encrypted as though 64bit cfb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ + +void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num, int enc) +{ + register DES_LONG v0, v1; + register long l = length; + register int n = *num; + DES_LONG ti[2]; + unsigned char *iv, c, cc; + + iv = &(*ivec)[0]; + if (enc) { + while (l--) { + if (n == 0) { + c2l(iv, v0); + c2l(iv, v1); + + ti[0] = v0; + ti[1] = v1; + DES_encrypt3(ti, ks1, ks2, ks3); + v0 = ti[0]; + v1 = ti[1]; + + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + iv = &(*ivec)[0]; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + c2l(iv, v0); + c2l(iv, v1); + + ti[0] = v0; + ti[1] = v1; + DES_encrypt3(ti, ks1, ks2, ks3); + v0 = ti[0]; + v1 = ti[1]; + + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + iv = &(*ivec)[0]; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = c = cc = 0; + *num = n; +} + +#ifdef undef /* MACRO */ +void DES_ede2_cfb64_encrypt(unsigned char *in, unsigned char *out, + long length, DES_key_schedule ks1, + DES_key_schedule ks2, DES_cblock (*ivec), + int *num, int enc) +{ + DES_ede3_cfb64_encrypt(in, out, length, ks1, ks2, ks1, ivec, num, enc); +} +#endif + +/* + * This is compatible with the single key CFB-r for DES, even thought that's + * not what EVP needs. + */ + +void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out, + int numbits, long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int enc) +{ + register DES_LONG d0, d1, v0, v1; + register unsigned long l = length, n = ((unsigned int)numbits + 7) / 8; + register int num = numbits, i; + DES_LONG ti[2]; + unsigned char *iv; + unsigned char ovec[16]; + + if (num > 64) + return; + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + if (enc) { + while (l >= n) { + l -= n; + ti[0] = v0; + ti[1] = v1; + DES_encrypt3(ti, ks1, ks2, ks3); + c2ln(in, d0, d1, n); + in += n; + d0 ^= ti[0]; + d1 ^= ti[1]; + l2cn(d0, d1, out, n); + out += n; + /* + * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under + * gcc :-( + */ + if (num == 32) { + v0 = v1; + v1 = d0; + } else if (num == 64) { + v0 = d0; + v1 = d1; + } else { + iv = &ovec[0]; + l2c(v0, iv); + l2c(v1, iv); + l2c(d0, iv); + l2c(d1, iv); + /* shift ovec left most of the bits... */ + memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0)); + /* now the remaining bits */ + if (num % 8 != 0) + for (i = 0; i < 8; ++i) { + ovec[i] <<= num % 8; + ovec[i] |= ovec[i + 1] >> (8 - num % 8); + } + iv = &ovec[0]; + c2l(iv, v0); + c2l(iv, v1); + } + } + } else { + while (l >= n) { + l -= n; + ti[0] = v0; + ti[1] = v1; + DES_encrypt3(ti, ks1, ks2, ks3); + c2ln(in, d0, d1, n); + in += n; + /* + * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under + * gcc :-( + */ + if (num == 32) { + v0 = v1; + v1 = d0; + } else if (num == 64) { + v0 = d0; + v1 = d1; + } else { + iv = &ovec[0]; + l2c(v0, iv); + l2c(v1, iv); + l2c(d0, iv); + l2c(d1, iv); + /* shift ovec left most of the bits... */ + memmove(ovec, ovec + num / 8, 8 + (num % 8 ? 1 : 0)); + /* now the remaining bits */ + if (num % 8 != 0) + for (i = 0; i < 8; ++i) { + ovec[i] <<= num % 8; + ovec[i] |= ovec[i + 1] >> (8 - num % 8); + } + iv = &ovec[0]; + c2l(iv, v0); + c2l(iv, v1); + } + d0 ^= ti[0]; + d1 ^= ti[1]; + l2cn(d0, d1, out, n); + out += n; + } + } + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0; +} diff --git a/libs/openssl/crypto/des/cfb64enc.c b/libs/openssl/crypto/des/cfb64enc.c new file mode 100644 index 00000000..7346774e --- /dev/null +++ b/libs/openssl/crypto/des/cfb64enc.c @@ -0,0 +1,122 @@ +/* crypto/des/cfb64enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +/* + * The input and output encrypted as though 64bit cfb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ + +void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num, int enc) +{ + register DES_LONG v0, v1; + register long l = length; + register int n = *num; + DES_LONG ti[2]; + unsigned char *iv, c, cc; + + iv = &(*ivec)[0]; + if (enc) { + while (l--) { + if (n == 0) { + c2l(iv, v0); + ti[0] = v0; + c2l(iv, v1); + ti[1] = v1; + DES_encrypt1(ti, schedule, DES_ENCRYPT); + iv = &(*ivec)[0]; + v0 = ti[0]; + l2c(v0, iv); + v0 = ti[1]; + l2c(v0, iv); + iv = &(*ivec)[0]; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + c2l(iv, v0); + ti[0] = v0; + c2l(iv, v1); + ti[1] = v1; + DES_encrypt1(ti, schedule, DES_ENCRYPT); + iv = &(*ivec)[0]; + v0 = ti[0]; + l2c(v0, iv); + v0 = ti[1]; + l2c(v0, iv); + iv = &(*ivec)[0]; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = c = cc = 0; + *num = n; +} diff --git a/libs/openssl/crypto/des/cfb_enc.c b/libs/openssl/crypto/des/cfb_enc.c new file mode 100644 index 00000000..bd0e2997 --- /dev/null +++ b/libs/openssl/crypto/des/cfb_enc.c @@ -0,0 +1,199 @@ +/* crypto/des/cfb_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "e_os.h" +#include "des_locl.h" +#include + +/* + * The input and output are loaded in multiples of 8 bits. What this means is + * that if you hame numbits=12 and length=2 the first 12 bits will be + * retrieved from the first byte and half the second. The second 12 bits + * will come from the 3rd and half the 4th byte. + */ +/* + * Until Aug 1 2003 this function did not correctly implement CFB-r, so it + * will not be compatible with any encryption prior to that date. Ben. + */ +void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc) +{ + register DES_LONG d0, d1, v0, v1; + register unsigned long l = length; + register int num = numbits / 8, n = (numbits + 7) / 8, i, rem = + numbits % 8; + DES_LONG ti[2]; + unsigned char *iv; +#ifndef L_ENDIAN + unsigned char ovec[16]; +#else + unsigned int sh[4]; + unsigned char *ovec = (unsigned char *)sh; + + /* I kind of count that compiler optimizes away this assertioni, */ + assert(sizeof(sh[0]) == 4); /* as this holds true for all, */ + /* but 16-bit platforms... */ + +#endif + + if (numbits <= 0 || numbits > 64) + return; + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + if (enc) { + while (l >= (unsigned long)n) { + l -= n; + ti[0] = v0; + ti[1] = v1; + DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); + c2ln(in, d0, d1, n); + in += n; + d0 ^= ti[0]; + d1 ^= ti[1]; + l2cn(d0, d1, out, n); + out += n; + /* + * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under + * gcc :-( + */ + if (numbits == 32) { + v0 = v1; + v1 = d0; + } else if (numbits == 64) { + v0 = d0; + v1 = d1; + } else { +#ifndef L_ENDIAN + iv = &ovec[0]; + l2c(v0, iv); + l2c(v1, iv); + l2c(d0, iv); + l2c(d1, iv); +#else + sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1; +#endif + if (rem == 0) + memmove(ovec, ovec + num, 8); + else + for (i = 0; i < 8; ++i) + ovec[i] = ovec[i + num] << rem | + ovec[i + num + 1] >> (8 - rem); +#ifdef L_ENDIAN + v0 = sh[0], v1 = sh[1]; +#else + iv = &ovec[0]; + c2l(iv, v0); + c2l(iv, v1); +#endif + } + } + } else { + while (l >= (unsigned long)n) { + l -= n; + ti[0] = v0; + ti[1] = v1; + DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); + c2ln(in, d0, d1, n); + in += n; + /* + * 30-08-94 - eay - changed because l>>32 and l<<32 are bad under + * gcc :-( + */ + if (numbits == 32) { + v0 = v1; + v1 = d0; + } else if (numbits == 64) { + v0 = d0; + v1 = d1; + } else { +#ifndef L_ENDIAN + iv = &ovec[0]; + l2c(v0, iv); + l2c(v1, iv); + l2c(d0, iv); + l2c(d1, iv); +#else + sh[0] = v0, sh[1] = v1, sh[2] = d0, sh[3] = d1; +#endif + if (rem == 0) + memmove(ovec, ovec + num, 8); + else + for (i = 0; i < 8; ++i) + ovec[i] = ovec[i + num] << rem | + ovec[i + num + 1] >> (8 - rem); +#ifdef L_ENDIAN + v0 = sh[0], v1 = sh[1]; +#else + iv = &ovec[0]; + c2l(iv, v0); + c2l(iv, v1); +#endif + } + d0 ^= ti[0]; + d1 ^= ti[1]; + l2cn(d0, d1, out, n); + out += n; + } + } + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + v0 = v1 = d0 = d1 = ti[0] = ti[1] = 0; +} diff --git a/libs/openssl/crypto/des/des-lib.com b/libs/openssl/crypto/des/des-lib.com new file mode 100644 index 00000000..348f1c04 --- /dev/null +++ b/libs/openssl/crypto/des/des-lib.com @@ -0,0 +1,1005 @@ +$! +$! DES-LIB.COM +$! Written By: Robert Byer +$! Vice-President +$! A-Com Computing, Inc. +$! byer@mail.all-net.net +$! +$! Changes by Richard Levitte +$! +$! This command files compiles and creates the +$! "[.xxx.EXE.CRYPTO.DES]LIBDES.OLB" library. The "xxx" denotes the machine +$! architecture of ALPHA, IA64 or VAX. +$! +$! It was re-written to try to determine which "C" compiler to try to use +$! or the user can specify a compiler in P3. +$! +$! Specify one of the following to build just that part, specify "ALL" to +$! just build everything. +$! +$! ALL To Just Build "Everything". +$! LIBRARY To Just Build The [.xxx.EXE.CRYPTO.DES]LIBDES.OLB Library. +$! DESTEST To Just Build The [.xxx.EXE.CRYPTO.DES]DESTEST.EXE Program. +$! SPEED To Just Build The [.xxx.EXE.CRYPTO.DES]SPEED.EXE Program. +$! RPW To Just Build The [.xxx.EXE.CRYPTO.DES]RPW.EXE Program. +$! DES To Just Build The [.xxx.EXE.CRYPTO.DES]DES.EXE Program. +$! DES_OPTS To Just Build The [.xxx.EXE.CRYPTO.DES]DES_OPTS.EXE Program. +$! +$! Specify either DEBUG or NODEBUG as P2 to compile with or without +$! debugging information. +$! +$! Specify which compiler at P3 to try to compile under. +$! +$! VAXC For VAX C. +$! DECC For DEC C. +$! GNUC For GNU C. +$! +$! If you don't speficy a compiler, it will try to determine which +$! "C" compiler to try to use. +$! +$! P4, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up) +$! +$! +$! Make sure we know what architecture we run on. +$! +$! +$! Check Which Architecture We Are Using. +$! +$ IF (F$GETSYI("CPU").LT.128) +$ THEN +$! +$! The Architecture Is VAX +$! +$ ARCH := VAX +$! +$! Else... +$! +$ ELSE +$! +$! The Architecture Is Alpha, IA64 or whatever comes in the future. +$! +$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE") +$ IF (ARCH .EQS. "") THEN ARCH = "UNK" +$! +$! End The Architecture Check. +$! +$ ENDIF +$! +$! Define The OBJ Directory Name. +$! +$ OBJ_DIR := SYS$DISK:[--.'ARCH'.OBJ.CRYPTO.DES] +$! +$! Define The EXE Directory Name. +$! +$ EXE_DIR :== SYS$DISK:[--.'ARCH'.EXE.CRYPTO.DES] +$! +$! Check To Make Sure We Have Valid Command Line Parameters. +$! +$ GOSUB CHECK_OPTIONS +$! +$! Tell The User What Kind of Machine We Run On. +$! +$ WRITE SYS$OUTPUT "Compiling On A ",ARCH," Machine." +$! +$! Check To See If The Architecture Specific OBJ Directory Exists. +$! +$ IF (F$PARSE(OBJ_DIR).EQS."") +$ THEN +$! +$! It Dosen't Exist, So Create It. +$! +$ CREATE/DIR 'OBJ_DIR' +$! +$! End The Architecture Specific OBJ Directory Check. +$! +$ ENDIF +$! +$! Check To See If The Architecture Specific Directory Exists. +$! +$ IF (F$PARSE(EXE_DIR).EQS."") +$ THEN +$! +$! It Dosen't Exist, So Create It. +$! +$ CREATE/DIR 'EXE_DIR' +$! +$! End The Architecture Specific Directory Check. +$! +$ ENDIF +$! +$! Define The Library Name. +$! +$ LIB_NAME := 'EXE_DIR'LIBDES.OLB +$! +$! Check To See What We Are To Do. +$! +$ IF (BUILDALL.EQS."TRUE") +$ THEN +$! +$! Since Nothing Special Was Specified, Do Everything. +$! +$ GOSUB LIBRARY +$ GOSUB DESTEST +$ GOSUB SPEED +$ GOSUB RPW +$ GOSUB DES +$ GOSUB DES_OPTS +$! +$! Else... +$! +$ ELSE +$! +$! Build Just What The User Wants Us To Build. +$! +$ GOSUB 'BUILDALL' +$! +$! End The BUILDALL Check. +$! +$ ENDIF +$! +$! Time To EXIT. +$! +$ EXIT +$ LIBRARY: +$! +$! Tell The User That We Are Compiling. +$! +$ WRITE SYS$OUTPUT "Compiling The ",LIB_NAME," Files." +$! +$! Check To See If We Already Have A "[.xxx.EXE.CRYPTO.DES]LIBDES.OLB" Library... +$! +$ IF (F$SEARCH(LIB_NAME).EQS."") +$ THEN +$! +$! Guess Not, Create The Library. +$! +$ LIBRARY/CREATE/OBJECT 'LIB_NAME' +$! +$! End The Library Exist Check. +$! +$ ENDIF +$! +$! Define The DES Library Files. +$! +$ LIB_DES = "set_key,ecb_enc,cbc_enc,"+ - + "ecb3_enc,cfb64enc,cfb64ede,cfb_enc,ofb64ede,"+ - + "enc_read,enc_writ,ofb64enc,"+ - + "ofb_enc,str2key,pcbc_enc,qud_cksm,rand_key,"+ - + "des_enc,fcrypt_b,read2pwd,"+ - + "fcrypt,xcbc_enc,read_pwd,rpc_enc,cbc_cksm,supp" +$! +$! Define A File Counter And Set It To "0". +$! +$ FILE_COUNTER = 0 +$! +$! Top Of The File Loop. +$! +$ NEXT_FILE: +$! +$! O.K, Extract The File Name From The File List. +$! +$ FILE_NAME = F$ELEMENT(FILE_COUNTER,",",LIB_DES) +$! +$! Check To See If We Are At The End Of The File List. +$! +$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE +$! +$! Increment The Counter. +$! +$ FILE_COUNTER = FILE_COUNTER + 1 +$! +$! Create The Source File Name. +$! +$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C" +$! +$! Tell The User We Are Compiling The Source File. +$! +$ WRITE SYS$OUTPUT " ",FILE_NAME,".C" +$! +$! Create The Object File Name. +$! +$ OBJECT_FILE = OBJ_DIR + FILE_NAME + "." + ARCH + "OBJ" +$ ON WARNING THEN GOTO NEXT_FILE +$! +$! Check To See If The File We Want To Compile Actually Exists. +$! +$ IF (F$SEARCH(SOURCE_FILE).EQS."") +$ THEN +$! +$! Tell The User That The File Dosen't Exist. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist." +$ WRITE SYS$OUTPUT "" +$! +$! Exit The Build. +$! +$ EXIT +$! +$! End The File Exists Check. +$! +$ ENDIF +$! +$! Compile The File. +$! +$ ON ERROR THEN GOTO NEXT_FILE +$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE' +$! +$! Add It To The Library. +$! +$ LIBRARY/REPLACE/OBJECT 'LIB_NAME' 'OBJECT_FILE' +$! +$! Time To Clean Up The Object File. +$! +$ DELETE 'OBJECT_FILE';* +$! +$! Go Back And Do It Again. +$! +$ GOTO NEXT_FILE +$! +$! All Done With This Library Part. +$! +$ FILE_DONE: +$! +$! Tell The User That We Are All Done. +$! +$ WRITE SYS$OUTPUT "Library ",LIB_NAME," Built." +$! +$! All Done, Time To Return. +$! +$ RETURN +$! +$! Compile The DESTEST Program. +$! +$ DESTEST: +$! +$! Check To See If We Have The Proper Libraries. +$! +$ GOSUB LIB_CHECK +$! +$! Check To See If We Have A Linker Option File. +$! +$ GOSUB CHECK_OPT_FILE +$! +$! Check To See If The File We Want To Compile Actually Exists. +$! +$ IF (F$SEARCH("SYS$DISK:[]DESTEST.C").EQS."") +$ THEN +$! +$! Tell The User That The File Dosen't Exist. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The File DESTEST.C Dosen't Exist." +$ WRITE SYS$OUTPUT "" +$! +$! Exit The Build. +$! +$ EXIT +$! +$! End The DESTEST.C File Check. +$! +$ ENDIF +$! +$! Tell The User What We Are Building. +$! +$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"DESTEST.EXE" +$! +$! Compile The DESTEST Program. +$! +$ CC/OBJECT='OBJ_DIR'DESTEST.OBJ SYS$DISK:[]DESTEST.C +$! +$! Link The DESTEST Program. +$! +$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'DESTEST.EXE - + 'OBJ_DIR'DESTEST.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION +$! +$! All Done, Time To Return. +$! +$ RETURN +$! +$! Compile The SPEED Program. +$! +$ SPEED: +$! +$! Check To See If We Have The Proper Libraries. +$! +$ GOSUB LIB_CHECK +$! +$! Check To See If We Have A Linker Option File. +$! +$ GOSUB CHECK_OPT_FILE +$! +$! Check To See If The File We Want To Compile Actually Exists. +$! +$ IF (F$SEARCH("SYS$DISK:[]SPEED.C").EQS."") +$ THEN +$! +$! Tell The User That The File Dosen't Exist. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The File SPEED.C Dosen't Exist." +$ WRITE SYS$OUTPUT "" +$! +$! Exit The Build. +$! +$ EXIT +$! +$! End The SPEED.C File Check. +$! +$ ENDIF +$! +$! Tell The User What We Are Building. +$! +$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"SPEED.EXE" +$! +$! Compile The SPEED Program. +$! +$ CC/OBJECT='OBJ_DIR'SPEED.OBJ SYS$DISK:[]SPEED.C +$! +$! Link The SPEED Program. +$! +$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'SPEED.EXE - + 'OBJ_DIR'SPEED.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION +$! +$! All Done, Time To Return. +$! +$ RETURN +$! +$! Compile The RPW Program. +$! +$ RPW: +$! +$! Check To See If We Have The Proper Libraries. +$! +$ GOSUB LIB_CHECK +$! +$! Check To See If We Have A Linker Option File. +$! +$ GOSUB CHECK_OPT_FILE +$! +$! Check To See If The File We Want To Compile Actually Exists. +$! +$ IF (F$SEARCH("SYS$DISK:[]RPW.C").EQS."") +$ THEN +$! +$! Tell The User That The File Dosen't Exist. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The File RPW.C Dosen't Exist." +$ WRITE SYS$OUTPUT "" +$! +$! Exit The Build. +$! +$ EXIT +$! +$! End The RPW.C File Check. +$! +$ ENDIF +$! +$! Tell The User What We Are Building. +$! +$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"RPW.EXE" +$! +$! Compile The RPW Program. +$! +$ CC/OBJECT='OBJ_DIR'RPW.OBJ SYS$DISK:[]RPW.C +$! +$! Link The RPW Program. +$! +$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'RPW.EXE - + 'OBJ_DIR'RPW.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION +$! +$! All Done, Time To Return. +$! +$ RETURN +$! +$! Compile The DES Program. +$! +$ DES: +$! +$! Check To See If We Have The Proper Libraries. +$! +$ GOSUB LIB_CHECK +$! +$! Check To See If We Have A Linker Option File. +$! +$ GOSUB CHECK_OPT_FILE +$! +$! Check To See If The File We Want To Compile Actually Exists. +$! +$ IF (F$SEARCH("SYS$DISK:[]DES.C").EQS."") +$ THEN +$! +$! Tell The User That The File Dosen't Exist. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The File DES.C Dosen't Exist." +$ WRITE SYS$OUTPUT "" +$! +$! Exit The Build. +$! +$ EXIT +$! +$! End The DES.C File Check. +$! +$ ENDIF +$! +$! Tell The User What We Are Building. +$! +$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"DES.EXE" +$! +$! Compile The DES Program. +$! +$ CC/OBJECT='OBJ_DIR'DES.OBJ SYS$DISK:[]DES.C +$ CC/OBJECT='OBJ_DIR'DES.OBJ SYS$DISK:[]CBC3_ENC.C +$! +$! Link The DES Program. +$! +$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'DES.EXE - + 'OBJ_DIR'DES.OBJ,'OBJ_DIR'CBC3_ENC.OBJ,- + 'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION +$! +$! All Done, Time To Return. +$! +$ RETURN +$! +$! Compile The DES_OPTS Program. +$! +$ DES_OPTS: +$! +$! Check To See If We Have The Proper Libraries. +$! +$ GOSUB LIB_CHECK +$! +$! Check To See If We Have A Linker Option File. +$! +$ GOSUB CHECK_OPT_FILE +$! +$! Check To See If The File We Want To Compile Actually Exists. +$! +$ IF (F$SEARCH("SYS$DISK:[]DES_OPTS.C").EQS."") +$ THEN +$! +$! Tell The User That The File Dosen't Exist. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The File DES_OPTS.C Dosen't Exist." +$ WRITE SYS$OUTPUT "" +$! +$! Exit The Build. +$! +$ EXIT +$! +$! End The DES_OPTS.C File Check. +$! +$ ENDIF +$! +$! Tell The User What We Are Building. +$! +$ WRITE SYS$OUTPUT "Building ",EXE_DIR,"DES_OPTS.EXE" +$! +$! Compile The DES_OPTS Program. +$! +$ CC/OBJECT='OBJ_DIR'DES_OPTS.OBJ SYS$DISK:[]DES_OPTS.C +$! +$! Link The DES_OPTS Program. +$! +$ LINK/'DEBUGGER'/'TRACEBACK'/CONTIGUOUS/EXE='EXE_DIR'DES_OPTS.EXE - + 'OBJ_DIR'DES_OPTS.OBJ,'LIB_NAME'/LIBRARY,'OPT_FILE'/OPTION +$! +$! All Done, Time To Return. +$! +$ RETURN +$ EXIT +$! +$! Check For The Link Option FIle. +$! +$ CHECK_OPT_FILE: +$! +$! Check To See If We Need To Make A VAX C Option File. +$! +$ IF (COMPILER.EQS."VAXC") +$ THEN +$! +$! Check To See If We Already Have A VAX C Linker Option File. +$! +$ IF (F$SEARCH(OPT_FILE).EQS."") +$ THEN +$! +$! We Need A VAX C Linker Option File. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File To Link Agianst +! The Sharable VAX C Runtime Library. +! +SYS$SHARE:VAXCRTL.EXE/SHARE +$EOD +$! +$! End The Option File Check. +$! +$ ENDIF +$! +$! End The VAXC Check. +$! +$ ENDIF +$! +$! Check To See If We Need A GNU C Option File. +$! +$ IF (COMPILER.EQS."GNUC") +$ THEN +$! +$! Check To See If We Already Have A GNU C Linker Option File. +$! +$ IF (F$SEARCH(OPT_FILE).EQS."") +$ THEN +$! +$! We Need A GNU C Linker Option File. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File To Link Agianst +! The Sharable C Runtime Library. +! +GNU_CC:[000000]GCCLIB/LIBRARY +SYS$SHARE:VAXCRTL/SHARE +$EOD +$! +$! End The Option File Check. +$! +$ ENDIF +$! +$! End The GNU C Check. +$! +$ ENDIF +$! +$! Check To See If We Need A DEC C Option File. +$! +$ IF (COMPILER.EQS."DECC") +$ THEN +$! +$! Check To See If We Already Have A DEC C Linker Option File. +$! +$ IF (F$SEARCH(OPT_FILE).EQS."") +$ THEN +$! +$! Figure Out If We Need An non-VAX Or A VAX Linker Option File. +$! +$ IF (F$GETSYI("CPU").LT.128) +$ THEN +$! +$! We Need A DEC C Linker Option File For VAX. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File To Link Agianst +! The Sharable DEC C Runtime Library. +! +SYS$SHARE:DECC$SHR.EXE/SHARE +$EOD +$! +$! Else... +$! +$ ELSE +$! +$! Create The non-VAX Linker Option File. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File For non-VAX To Link Agianst +! The Sharable C Runtime Library. +! +SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE +SYS$SHARE:CMA$OPEN_RTL/SHARE +$EOD +$! +$! End The DEC C Option File Check. +$! +$ ENDIF +$! +$! End The Option File Search. +$! +$ ENDIF +$! +$! End The DEC C Check. +$! +$ ENDIF +$! +$! Tell The User What Linker Option File We Are Using. +$! +$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"." +$! +$! Time To RETURN. +$! +$ RETURN +$! +$! Library Check. +$! +$ LIB_CHECK: +$! +$! Look For The Library LIBDES.OLB. +$! +$ IF (F$SEARCH(LIB_NAME).EQS."") +$ THEN +$! +$! Tell The User We Can't Find The [.xxx.CRYPTO.DES]LIBDES.OLB Library. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "Can't Find The Library ",LIB_NAME,"." +$ WRITE SYS$OUTPUT "We Can't Link Without It." +$ WRITE SYS$OUTPUT "" +$! +$! Since We Can't Link Without It, Exit. +$! +$ EXIT +$ ENDIF +$! +$! Time To Return. +$! +$ RETURN +$! +$! Check The User's Options. +$! +$ CHECK_OPTIONS: +$! +$! Check To See If We Are To "Just Build Everything". +$! +$ IF (P1.EQS."ALL") +$ THEN +$! +$! P1 Is "ALL", So Build Everything. +$! +$ BUILDALL = "TRUE" +$! +$! Else... +$! +$ ELSE +$! +$! Else, Check To See If P1 Has A Valid Argument. +$! +$ IF (P1.EQS."LIBRARY").OR.(P1.EQS."DESTEST").OR.(P1.EQS."SPEED") - + .OR.(P1.EQS."RPW").OR.(P1.EQS."DES").OR.(P1.EQS."DES_OPTS") +$ THEN +$! +$! A Valid Argument. +$! +$ BUILDALL = P1 +$! +$! Else... +$! +$ ELSE +$! +$! Tell The User We Don't Know What They Want. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " ALL : Just Build Everything." +$ WRITE SYS$OUTPUT " LIBRARY : To Compile Just The [.xxx.EXE.CRYPTO.DES]LIBDES.OLB Library." +$ WRITE SYS$OUTPUT " DESTEST : To Compile Just The [.xxx.EXE.CRYPTO.DES]DESTEST.EXE Program." +$ WRITE SYS$OUTPUT " SPEED : To Compile Just The [.xxx.EXE.CRYPTO.DES]SPEED.EXE Program." +$ WRITE SYS$OUTPUT " RPW : To Compile Just The [.xxx.EXE.CRYPTO.DES]RPW.EXE Program." +$ WRITE SYS$OUTPUT " DES : To Compile Just The [.xxx.EXE.CRYPTO.DES]DES.EXE Program." +$ WRITE SYS$OUTPUT " DES_OPTS : To Compile Just The [.xxx.EXE.CRYTPO.DES]DES_OPTS.EXE Program." +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " Where 'xxx' Stands For: " +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " ALPHA : Alpha Architecture." +$ WRITE SYS$OUTPUT " IA64 : IA64 Architecture." +$ WRITE SYS$OUTPUT " VAX : VAX Architecture." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$! End The Valid Argument Check. +$! +$ ENDIF +$! +$! End The P1 Check. +$! +$ ENDIF +$! +$! Check To See If We Are To Compile Without Debugger Information. +$! +$ IF (P2.EQS."NODEBUG") +$ THEN +$! +$! P2 Is Blank, So Compile Without Debugger Information. +$! +$ DEBUGGER = "NODEBUG" +$ TRACEBACK = "NOTRACEBACK" +$ GCC_OPTIMIZE = "OPTIMIZE" +$ CC_OPTIMIZE = "OPTIMIZE" +$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile." +$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization." +$! +$! Else... +$! +$ ELSE +$! +$! Check To See If We Are To Compile With Debugger Information. +$! +$ IF (P2.EQS."DEBUG") +$ THEN +$! +$! Compile With Debugger Information. +$! +$ DEBUGGER = "DEBUG" +$ TRACEBACK = "TRACEBACK" +$ GCC_OPTIMIZE = "NOOPTIMIZE" +$ CC_OPTIMIZE = "NOOPTIMIZE" +$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile." +$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization." +$! +$! Else... +$! +$ ELSE +$! +$! Tell The User Entered An Invalid Option.. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information." +$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$! End The Valid Argument Check. +$! +$ ENDIF +$! +$! End The P2 Check. +$! +$ ENDIF +$! +$! Special Threads For OpenVMS v7.1 Or Later. +$! +$! Written By: Richard Levitte +$! richard@levitte.org +$! +$! +$! Check To See If We Have A Option For P4. +$! +$ IF (P4.EQS."") +$ THEN +$! +$! Get The Version Of VMS We Are Using. +$! +$ ISSEVEN := "" +$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION"))) +$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP)) +$! +$! Check To See If The VMS Version Is v7.1 Or Later. +$! +$ IF (TMP.GE.71) +$ THEN +$! +$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads. +$! +$ ISSEVEN := ,PTHREAD_USE_D4 +$! +$! End The VMS Version Check. +$! +$ ENDIF +$! +$! End The P4 Check. +$! +$ ENDIF +$! +$! Check To See If P3 Is Blank. +$! +$ IF (P3.EQS."") +$ THEN +$! +$! O.K., The User Didn't Specify A Compiler, Let's Try To +$! Find Out Which One To Use. +$! +$! Check To See If We Have GNU C. +$! +$ IF (F$TRNLNM("GNU_CC").NES."") +$ THEN +$! +$! Looks Like GNUC, Set To Use GNUC. +$! +$ P3 = "GNUC" +$! +$! Else... +$! +$ ELSE +$! +$! Check To See If We Have VAXC Or DECC. +$! +$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."") +$ THEN +$! +$! Looks Like DECC, Set To Use DECC. +$! +$ P3 = "DECC" +$! +$! Else... +$! +$ ELSE +$! +$! Looks Like VAXC, Set To Use VAXC. +$! +$ P3 = "VAXC" +$! +$! End The VAXC Compiler Check. +$! +$ ENDIF +$! +$! End The DECC & VAXC Compiler Check. +$! +$ ENDIF +$! +$! End The Compiler Check. +$! +$ ENDIF +$! +$! Set Up Initial CC Definitions, Possibly With User Ones +$! +$ CCDEFS = "" +$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = USER_CCDEFS +$ CCEXTRAFLAGS = "" +$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS +$ CCDISABLEWARNINGS = "" +$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" THEN - + CCDISABLEWARNINGS = USER_CCDISABLEWARNINGS +$! +$! Check To See If The User Entered A Valid Paramter. +$! +$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC") +$ THEN +$! +$! Check To See If The User Wanted DECC. +$! +$ IF (P3.EQS."DECC") +$ THEN +$! +$! Looks Like DECC, Set To Use DECC. +$! +$ COMPILER = "DECC" +$! +$! Tell The User We Are Using DECC. +$! +$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler." +$! +$! Use DECC... +$! +$ CC = "CC" +$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" - + THEN CC = "CC/DECC" +$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/STANDARD=ANSI89" + - + "/NOLIST/PREFIX=ALL" + CCEXTRAFLAGS +$! +$! Define The Linker Options File Name. +$! +$ OPT_FILE = "''EXE_DIR'VAX_DECC_OPTIONS.OPT" +$! +$! End DECC Check. +$! +$ ENDIF +$! +$! Check To See If We Are To Use VAXC. +$! +$ IF (P3.EQS."VAXC") +$ THEN +$! +$! Looks Like VAXC, Set To Use VAXC. +$! +$ COMPILER = "VAXC" +$! +$! Tell The User We Are Using VAX C. +$! +$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler." +$! +$! Compile Using VAXC. +$! +$ CC = "CC" +$ IF ARCH.NES."VAX" +$ THEN +$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!" +$ EXIT +$ ENDIF +$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC" +$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + CCEXTRAFLAGS +$ CCDEFS = """VAXC""," + CCDEFS +$! +$! Define As SYS$COMMON:[SYSLIB] +$! +$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB] +$! +$! Define The Linker Options File Name. +$! +$ OPT_FILE = "''EXE_DIR'VAX_VAXC_OPTIONS.OPT" +$! +$! End VAXC Check +$! +$ ENDIF +$! +$! Check To See If We Are To Use GNU C. +$! +$ IF (P3.EQS."GNUC") +$ THEN +$! +$! Looks Like GNUC, Set To Use GNUC. +$! +$ COMPILER = "GNUC" +$! +$! Tell The User We Are Using GNUC. +$! +$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler." +$! +$! Use GNU C... +$! +$ CC = "GCC/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + CCEXTRAFLAGS +$! +$! Define The Linker Options File Name. +$! +$ OPT_FILE = "''EXE_DIR'VAX_GNUC_OPTIONS.OPT" +$! +$! End The GNU C Check. +$! +$ ENDIF +$! +$! Set up default defines +$! +$ CCDEFS = """FLAT_INC=1""," + CCDEFS +$! +$! Finish up the definition of CC. +$! +$ IF COMPILER .EQS. "DECC" +$ THEN +$ IF CCDISABLEWARNINGS .EQS. "" +$ THEN +$ CC4DISABLEWARNINGS = "DOLLARID" +$ ELSE +$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID" +$ CCDISABLEWARNINGS = "/WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))" +$ ENDIF +$ CC4DISABLEWARNINGS = "/WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))" +$ ELSE +$ CCDISABLEWARNINGS = "" +$ CC4DISABLEWARNINGS = "" +$ ENDIF +$ CC = CC + "/DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS +$! +$! Show user the result +$! +$ WRITE SYS$OUTPUT "Main Compiling Command: ",CC +$! +$! Else The User Entered An Invalid Argument. +$! +$ ELSE +$! +$! Tell The User We Don't Know What They Want. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C." +$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C." +$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$! End The P3 Check. +$! +$ ENDIF +$! +$! Time To RETURN... +$! +$ RETURN diff --git a/libs/openssl/crypto/des/des.c b/libs/openssl/crypto/des/des.c new file mode 100644 index 00000000..586aed72 --- /dev/null +++ b/libs/openssl/crypto/des/des.c @@ -0,0 +1,868 @@ +/* crypto/des/des.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#ifndef OPENSSL_SYS_MSDOS +# ifndef OPENSSL_SYS_VMS +# include OPENSSL_UNISTD +# else /* OPENSSL_SYS_VMS */ +# ifdef __DECC +# include +# else /* not __DECC */ +# include +# endif /* __DECC */ +# endif /* OPENSSL_SYS_VMS */ +#else /* OPENSSL_SYS_MSDOS */ +# include +#endif + +#include +#include "des_ver.h" + +#ifdef OPENSSL_SYS_VMS +# include +# include +#else +# ifndef _IRIX +# include +# endif +# include +#endif +#include +#include +#include + +void usage(void); +void doencryption(void); +int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp); +void uufwriteEnd(FILE *fp); +int uufread(unsigned char *out, int size, unsigned int num, FILE *fp); +int uuencode(unsigned char *in, int num, unsigned char *out); +int uudecode(unsigned char *in, int num, unsigned char *out); +void DES_3cbc_encrypt(DES_cblock *input, DES_cblock *output, long length, + DES_key_schedule sk1, DES_key_schedule sk2, + DES_cblock *ivec1, DES_cblock *ivec2, int enc); +#ifdef OPENSSL_SYS_VMS +# define EXIT(a) exit(a&0x10000000L) +#else +# define EXIT(a) exit(a) +#endif + +#define BUFSIZE (8*1024) +#define VERIFY 1 +#define KEYSIZ 8 +#define KEYSIZB 1024 /* should hit tty line limit first :-) */ +char key[KEYSIZB + 1]; +int do_encrypt, longk = 0; +FILE *DES_IN, *DES_OUT, *CKSUM_OUT; +char uuname[200]; +unsigned char uubuf[50]; +int uubufnum = 0; +#define INUUBUFN (45*100) +#define OUTUUBUF (65*100) +unsigned char b[OUTUUBUF]; +unsigned char bb[300]; +DES_cblock cksum = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; + +char cksumname[200] = ""; + +int vflag, cflag, eflag, dflag, kflag, bflag, fflag, sflag, uflag, flag3, + hflag, error; + +int main(int argc, char **argv) +{ + int i; + struct stat ins, outs; + char *p; + char *in = NULL, *out = NULL; + + vflag = cflag = eflag = dflag = kflag = hflag = bflag = fflag = sflag = + uflag = flag3 = 0; + error = 0; + memset(key, 0, sizeof(key)); + + for (i = 1; i < argc; i++) { + p = argv[i]; + if ((p[0] == '-') && (p[1] != '\0')) { + p++; + while (*p) { + switch (*(p++)) { + case '3': + flag3 = 1; + longk = 1; + break; + case 'c': + cflag = 1; + strncpy(cksumname, p, 200); + cksumname[sizeof(cksumname) - 1] = '\0'; + p += strlen(cksumname); + break; + case 'C': + cflag = 1; + longk = 1; + strncpy(cksumname, p, 200); + cksumname[sizeof(cksumname) - 1] = '\0'; + p += strlen(cksumname); + break; + case 'e': + eflag = 1; + break; + case 'v': + vflag = 1; + break; + case 'E': + eflag = 1; + longk = 1; + break; + case 'd': + dflag = 1; + break; + case 'D': + dflag = 1; + longk = 1; + break; + case 'b': + bflag = 1; + break; + case 'f': + fflag = 1; + break; + case 's': + sflag = 1; + break; + case 'u': + uflag = 1; + strncpy(uuname, p, 200); + uuname[sizeof(uuname) - 1] = '\0'; + p += strlen(uuname); + break; + case 'h': + hflag = 1; + break; + case 'k': + kflag = 1; + if ((i + 1) == argc) { + fputs("must have a key with the -k option\n", stderr); + error = 1; + } else { + int j; + + i++; + strncpy(key, argv[i], KEYSIZB); + for (j = strlen(argv[i]) - 1; j >= 0; j--) + argv[i][j] = '\0'; + } + break; + default: + fprintf(stderr, "'%c' unknown flag\n", p[-1]); + error = 1; + break; + } + } + } else { + if (in == NULL) + in = argv[i]; + else if (out == NULL) + out = argv[i]; + else + error = 1; + } + } + if (error) + usage(); + /*- + * We either + * do checksum or + * do encrypt or + * do decrypt or + * do decrypt then ckecksum or + * do checksum then encrypt + */ + if (((eflag + dflag) == 1) || cflag) { + if (eflag) + do_encrypt = DES_ENCRYPT; + if (dflag) + do_encrypt = DES_DECRYPT; + } else { + if (vflag) { +#ifndef _Windows + fprintf(stderr, "des(1) built with %s\n", libdes_version); +#endif + EXIT(1); + } else + usage(); + } + +#ifndef _Windows + if (vflag) + fprintf(stderr, "des(1) built with %s\n", libdes_version); +#endif + if ((in != NULL) && (out != NULL) && +#ifndef OPENSSL_SYS_MSDOS + (stat(in, &ins) != -1) && + (stat(out, &outs) != -1) && + (ins.st_dev == outs.st_dev) && (ins.st_ino == outs.st_ino)) +#else /* OPENSSL_SYS_MSDOS */ + (strcmp(in, out) == 0)) +#endif + { + fputs("input and output file are the same\n", stderr); + EXIT(3); + } + + if (!kflag) + if (des_read_pw_string + (key, KEYSIZB + 1, "Enter key:", eflag ? VERIFY : 0)) { + fputs("password error\n", stderr); + EXIT(2); + } + + if (in == NULL) + DES_IN = stdin; + else if ((DES_IN = fopen(in, "r")) == NULL) { + perror("opening input file"); + EXIT(4); + } + + CKSUM_OUT = stdout; + if (out == NULL) { + DES_OUT = stdout; + CKSUM_OUT = stderr; + } else if ((DES_OUT = fopen(out, "w")) == NULL) { + perror("opening output file"); + EXIT(5); + } +#ifdef OPENSSL_SYS_MSDOS + /* This should set the file to binary mode. */ + { +# include + if (!(uflag && dflag)) + setmode(fileno(DES_IN), O_BINARY); + if (!(uflag && eflag)) + setmode(fileno(DES_OUT), O_BINARY); + } +#endif + + doencryption(); + fclose(DES_IN); + fclose(DES_OUT); + EXIT(0); +} + +void usage(void) +{ + char **u; + static const char *Usage[] = { + "des [input-file [output-file]]", + "options:", + "-v : des(1) version number", + "-e : encrypt using SunOS compatible user key to DES key conversion.", + "-E : encrypt ", + "-d : decrypt using SunOS compatible user key to DES key conversion.", + "-D : decrypt ", + "-c[ckname] : generate a cbc_cksum using SunOS compatible user key to", + " DES key conversion and output to ckname (stdout default,", + " stderr if data being output on stdout). The checksum is", + " generated before encryption and after decryption if used", + " in conjunction with -[eEdD].", + "-C[ckname] : generate a cbc_cksum as for -c but compatible with -[ED].", + "-k key : use key 'key'", + "-h : the key that is entered will be a hexadecimal number", + " that is used directly as the des key", + "-u[uuname] : input file is uudecoded if -[dD] or output uuencoded data if -[eE]", + " (uuname is the filename to put in the uuencode header).", + "-b : encrypt using DES in ecb encryption mode, the default is cbc mode.", + "-3 : encrypt using triple DES encryption. This uses 2 keys", + " generated from the input key. If the input key is less", + " than 8 characters long, this is equivalent to normal", + " encryption. Default is triple cbc, -b makes it triple ecb.", + NULL + }; + for (u = (char **)Usage; *u; u++) { + fputs(*u, stderr); + fputc('\n', stderr); + } + + EXIT(1); +} + +void doencryption(void) +{ +#ifdef _LIBC + extern unsigned long time(); +#endif + + register int i; + DES_key_schedule ks, ks2; + DES_cblock iv, iv2; + char *p; + int num = 0, j, k, l, rem, ll, len, last, ex = 0; + DES_cblock kk, k2; + FILE *O; + int Exit = 0; +#ifndef OPENSSL_SYS_MSDOS + static unsigned char buf[BUFSIZE + 8], obuf[BUFSIZE + 8]; +#else + static unsigned char *buf = NULL, *obuf = NULL; + + if (buf == NULL) { + if (((buf = OPENSSL_malloc(BUFSIZE + 8)) == NULL) || + ((obuf = OPENSSL_malloc(BUFSIZE + 8)) == NULL)) { + fputs("Not enough memory\n", stderr); + Exit = 10; + goto problems; + } + } +#endif + + if (hflag) { + j = (flag3 ? 16 : 8); + p = key; + for (i = 0; i < j; i++) { + k = 0; + if ((*p <= '9') && (*p >= '0')) + k = (*p - '0') << 4; + else if ((*p <= 'f') && (*p >= 'a')) + k = (*p - 'a' + 10) << 4; + else if ((*p <= 'F') && (*p >= 'A')) + k = (*p - 'A' + 10) << 4; + else { + fputs("Bad hex key\n", stderr); + Exit = 9; + goto problems; + } + p++; + if ((*p <= '9') && (*p >= '0')) + k |= (*p - '0'); + else if ((*p <= 'f') && (*p >= 'a')) + k |= (*p - 'a' + 10); + else if ((*p <= 'F') && (*p >= 'A')) + k |= (*p - 'A' + 10); + else { + fputs("Bad hex key\n", stderr); + Exit = 9; + goto problems; + } + p++; + if (i < 8) + kk[i] = k; + else + k2[i - 8] = k; + } + DES_set_key_unchecked(&k2, &ks2); + OPENSSL_cleanse(k2, sizeof(k2)); + } else if (longk || flag3) { + if (flag3) { + DES_string_to_2keys(key, &kk, &k2); + DES_set_key_unchecked(&k2, &ks2); + OPENSSL_cleanse(k2, sizeof(k2)); + } else + DES_string_to_key(key, &kk); + } else + for (i = 0; i < KEYSIZ; i++) { + l = 0; + k = key[i]; + for (j = 0; j < 8; j++) { + if (k & 1) + l++; + k >>= 1; + } + if (l & 1) + kk[i] = key[i] & 0x7f; + else + kk[i] = key[i] | 0x80; + } + + DES_set_key_unchecked(&kk, &ks); + OPENSSL_cleanse(key, sizeof(key)); + OPENSSL_cleanse(kk, sizeof(kk)); + /* woops - A bug that does not showup under unix :-( */ + memset(iv, 0, sizeof(iv)); + memset(iv2, 0, sizeof(iv2)); + + l = 1; + rem = 0; + /* first read */ + if (eflag || (!dflag && cflag)) { + for (;;) { + num = l = fread(&(buf[rem]), 1, BUFSIZE, DES_IN); + l += rem; + num += rem; + if (l < 0) { + perror("read error"); + Exit = 6; + goto problems; + } + + rem = l % 8; + len = l - rem; + if (feof(DES_IN)) { + for (i = 7 - rem; i > 0; i--) { + if (RAND_pseudo_bytes(buf + l++, 1) < 0) + goto problems; + } + buf[l++] = rem; + ex = 1; + len += rem; + } else + l -= rem; + + if (cflag) { + DES_cbc_cksum(buf, &cksum, (long)len, &ks, &cksum); + if (!eflag) { + if (feof(DES_IN)) + break; + else + continue; + } + } + + if (bflag && !flag3) + for (i = 0; i < l; i += 8) + DES_ecb_encrypt((DES_cblock *)&(buf[i]), + (DES_cblock *)&(obuf[i]), + &ks, do_encrypt); + else if (flag3 && bflag) + for (i = 0; i < l; i += 8) + DES_ecb2_encrypt((DES_cblock *)&(buf[i]), + (DES_cblock *)&(obuf[i]), + &ks, &ks2, do_encrypt); + else if (flag3 && !bflag) { + char tmpbuf[8]; + + if (rem) + memcpy(tmpbuf, &(buf[l]), (unsigned int)rem); + DES_3cbc_encrypt((DES_cblock *)buf, (DES_cblock *)obuf, + (long)l, ks, ks2, &iv, &iv2, do_encrypt); + if (rem) + memcpy(&(buf[l]), tmpbuf, (unsigned int)rem); + } else { + DES_cbc_encrypt(buf, obuf, (long)l, &ks, &iv, do_encrypt); + if (l >= 8) + memcpy(iv, &(obuf[l - 8]), 8); + } + if (rem) + memcpy(buf, &(buf[l]), (unsigned int)rem); + + i = 0; + while (i < l) { + if (uflag) + j = uufwrite(obuf, 1, (unsigned int)l - i, DES_OUT); + else + j = fwrite(obuf, 1, (unsigned int)l - i, DES_OUT); + if (j == -1) { + perror("Write error"); + Exit = 7; + goto problems; + } + i += j; + } + if (feof(DES_IN)) { + if (uflag) + uufwriteEnd(DES_OUT); + break; + } + } + } else { /* decrypt */ + + ex = 1; + for (;;) { + if (ex) { + if (uflag) + l = uufread(buf, 1, BUFSIZE, DES_IN); + else + l = fread(buf, 1, BUFSIZE, DES_IN); + ex = 0; + rem = l % 8; + l -= rem; + } + if (l < 0) { + perror("read error"); + Exit = 6; + goto problems; + } + + if (bflag && !flag3) + for (i = 0; i < l; i += 8) + DES_ecb_encrypt((DES_cblock *)&(buf[i]), + (DES_cblock *)&(obuf[i]), + &ks, do_encrypt); + else if (flag3 && bflag) + for (i = 0; i < l; i += 8) + DES_ecb2_encrypt((DES_cblock *)&(buf[i]), + (DES_cblock *)&(obuf[i]), + &ks, &ks2, do_encrypt); + else if (flag3 && !bflag) { + DES_3cbc_encrypt((DES_cblock *)buf, (DES_cblock *)obuf, + (long)l, ks, ks2, &iv, &iv2, do_encrypt); + } else { + DES_cbc_encrypt(buf, obuf, (long)l, &ks, &iv, do_encrypt); + if (l >= 8) + memcpy(iv, &(buf[l - 8]), 8); + } + + if (uflag) + ll = uufread(&(buf[rem]), 1, BUFSIZE, DES_IN); + else + ll = fread(&(buf[rem]), 1, BUFSIZE, DES_IN); + ll += rem; + rem = ll % 8; + ll -= rem; + if (feof(DES_IN) && (ll == 0)) { + last = obuf[l - 1]; + + if ((last > 7) || (last < 0)) { + fputs("The file was not decrypted correctly.\n", stderr); + Exit = 8; + last = 0; + } + l = l - 8 + last; + } + i = 0; + if (cflag) + DES_cbc_cksum(obuf, + (DES_cblock *)cksum, (long)l / 8 * 8, &ks, + (DES_cblock *)cksum); + while (i != l) { + j = fwrite(obuf, 1, (unsigned int)l - i, DES_OUT); + if (j == -1) { + perror("Write error"); + Exit = 7; + goto problems; + } + i += j; + } + l = ll; + if ((l == 0) && feof(DES_IN)) + break; + } + } + if (cflag) { + l = 0; + if (cksumname[0] != '\0') { + if ((O = fopen(cksumname, "w")) != NULL) { + CKSUM_OUT = O; + l = 1; + } + } + for (i = 0; i < 8; i++) + fprintf(CKSUM_OUT, "%02X", cksum[i]); + fprintf(CKSUM_OUT, "\n"); + if (l) + fclose(CKSUM_OUT); + } + problems: + OPENSSL_cleanse(buf, sizeof(buf)); + OPENSSL_cleanse(obuf, sizeof(obuf)); + OPENSSL_cleanse(&ks, sizeof(ks)); + OPENSSL_cleanse(&ks2, sizeof(ks2)); + OPENSSL_cleanse(iv, sizeof(iv)); + OPENSSL_cleanse(iv2, sizeof(iv2)); + OPENSSL_cleanse(kk, sizeof(kk)); + OPENSSL_cleanse(k2, sizeof(k2)); + OPENSSL_cleanse(uubuf, sizeof(uubuf)); + OPENSSL_cleanse(b, sizeof(b)); + OPENSSL_cleanse(bb, sizeof(bb)); + OPENSSL_cleanse(cksum, sizeof(cksum)); + if (Exit) + EXIT(Exit); +} + +/* We ignore this parameter but it should be > ~50 I believe */ +int uufwrite(unsigned char *data, int size, unsigned int num, FILE *fp) +{ + int i, j, left, rem, ret = num; + static int start = 1; + + if (start) { + fprintf(fp, "begin 600 %s\n", + (uuname[0] == '\0') ? "text.d" : uuname); + start = 0; + } + + if (uubufnum) { + if (uubufnum + num < 45) { + memcpy(&(uubuf[uubufnum]), data, (unsigned int)num); + uubufnum += num; + return (num); + } else { + i = 45 - uubufnum; + memcpy(&(uubuf[uubufnum]), data, (unsigned int)i); + j = uuencode((unsigned char *)uubuf, 45, b); + fwrite(b, 1, (unsigned int)j, fp); + uubufnum = 0; + data += i; + num -= i; + } + } + + for (i = 0; i < (((int)num) - INUUBUFN); i += INUUBUFN) { + j = uuencode(&(data[i]), INUUBUFN, b); + fwrite(b, 1, (unsigned int)j, fp); + } + rem = (num - i) % 45; + left = (num - i - rem); + if (left) { + j = uuencode(&(data[i]), left, b); + fwrite(b, 1, (unsigned int)j, fp); + i += left; + } + if (i != num) { + memcpy(uubuf, &(data[i]), (unsigned int)rem); + uubufnum = rem; + } + return (ret); +} + +void uufwriteEnd(FILE *fp) +{ + int j; + static const char *end = " \nend\n"; + + if (uubufnum != 0) { + uubuf[uubufnum] = '\0'; + uubuf[uubufnum + 1] = '\0'; + uubuf[uubufnum + 2] = '\0'; + j = uuencode(uubuf, uubufnum, b); + fwrite(b, 1, (unsigned int)j, fp); + } + fwrite(end, 1, strlen(end), fp); +} + +/* + * int size: should always be > ~ 60; I actually ignore this parameter :-) + */ +int uufread(unsigned char *out, int size, unsigned int num, FILE *fp) +{ + int i, j, tot; + static int done = 0; + static int valid = 0; + static int start = 1; + + if (start) { + for (;;) { + b[0] = '\0'; + fgets((char *)b, 300, fp); + if (b[0] == '\0') { + fprintf(stderr, "no 'begin' found in uuencoded input\n"); + return (-1); + } + if (strncmp((char *)b, "begin ", 6) == 0) + break; + } + start = 0; + } + if (done) + return (0); + tot = 0; + if (valid) { + memcpy(out, bb, (unsigned int)valid); + tot = valid; + valid = 0; + } + for (;;) { + b[0] = '\0'; + fgets((char *)b, 300, fp); + if (b[0] == '\0') + break; + i = strlen((char *)b); + if ((b[0] == 'e') && (b[1] == 'n') && (b[2] == 'd')) { + done = 1; + while (!feof(fp)) { + fgets((char *)b, 300, fp); + } + break; + } + i = uudecode(b, i, bb); + if (i < 0) + break; + if ((i + tot + 8) > num) { + /* num to copy to make it a multiple of 8 */ + j = (num / 8 * 8) - tot - 8; + memcpy(&(out[tot]), bb, (unsigned int)j); + tot += j; + memcpy(bb, &(bb[j]), (unsigned int)i - j); + valid = i - j; + break; + } + memcpy(&(out[tot]), bb, (unsigned int)i); + tot += i; + } + return (tot); +} + +#define ccc2l(c,l) (l =((DES_LONG)(*((c)++)))<<16, \ + l|=((DES_LONG)(*((c)++)))<< 8, \ + l|=((DES_LONG)(*((c)++)))) + +#define l2ccc(l,c) (*((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +int uuencode(unsigned char *in, int num, unsigned char *out) +{ + int j, i, n, tot = 0; + DES_LONG l; + register unsigned char *p; + p = out; + + for (j = 0; j < num; j += 45) { + if (j + 45 > num) + i = (num - j); + else + i = 45; + *(p++) = i + ' '; + for (n = 0; n < i; n += 3) { + ccc2l(in, l); + *(p++) = ((l >> 18) & 0x3f) + ' '; + *(p++) = ((l >> 12) & 0x3f) + ' '; + *(p++) = ((l >> 6) & 0x3f) + ' '; + *(p++) = ((l) & 0x3f) + ' '; + tot += 4; + } + *(p++) = '\n'; + tot += 2; + } + *p = '\0'; + l = 0; + return (tot); +} + +int uudecode(unsigned char *in, int num, unsigned char *out) +{ + int j, i, k; + unsigned int n = 0, space = 0; + DES_LONG l; + DES_LONG w, x, y, z; + unsigned int blank = (unsigned int)'\n' - ' '; + + for (j = 0; j < num;) { + n = *(in++) - ' '; + if (n == blank) { + n = 0; + in--; + } + if (n > 60) { + fprintf(stderr, "uuencoded line length too long\n"); + return (-1); + } + j++; + + for (i = 0; i < n; j += 4, i += 3) { + /* + * the following is for cases where spaces are removed from + * lines. + */ + if (space) { + w = x = y = z = 0; + } else { + w = *(in++) - ' '; + x = *(in++) - ' '; + y = *(in++) - ' '; + z = *(in++) - ' '; + } + if ((w > 63) || (x > 63) || (y > 63) || (z > 63)) { + k = 0; + if (w == blank) + k = 1; + if (x == blank) + k = 2; + if (y == blank) + k = 3; + if (z == blank) + k = 4; + space = 1; + switch (k) { + case 1: + w = 0; + in--; + case 2: + x = 0; + in--; + case 3: + y = 0; + in--; + case 4: + z = 0; + in--; + break; + case 0: + space = 0; + fprintf(stderr, "bad uuencoded data values\n"); + w = x = y = z = 0; + return (-1); + break; + } + } + l = (w << 18) | (x << 12) | (y << 6) | (z); + l2ccc(l, out); + } + if (*(in++) != '\n') { + fprintf(stderr, "missing nl in uuencoded line\n"); + w = x = y = z = 0; + return (-1); + } + j++; + } + *out = '\0'; + w = x = y = z = 0; + return (n); +} diff --git a/libs/openssl/crypto/des/des.h b/libs/openssl/crypto/des/des.h new file mode 100644 index 00000000..1b40144e --- /dev/null +++ b/libs/openssl/crypto/des/des.h @@ -0,0 +1,257 @@ +/* crypto/des/des.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_NEW_DES_H +# define HEADER_NEW_DES_H + +# include /* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG + * (via openssl/opensslconf.h */ + +# ifdef OPENSSL_NO_DES +# error DES is disabled. +# endif + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned char DES_cblock[8]; +typedef /* const */ unsigned char const_DES_cblock[8]; +/* + * With "const", gcc 2.8.1 on Solaris thinks that DES_cblock * and + * const_DES_cblock * are incompatible pointer types. + */ + +typedef struct DES_ks { + union { + DES_cblock cblock; + /* + * make sure things are correct size on machines with 8 byte longs + */ + DES_LONG deslong[2]; + } ks[16]; +} DES_key_schedule; + +# ifndef OPENSSL_DISABLE_OLD_DES_SUPPORT +# ifndef OPENSSL_ENABLE_OLD_DES_SUPPORT +# define OPENSSL_ENABLE_OLD_DES_SUPPORT +# endif +# endif + +# ifdef OPENSSL_ENABLE_OLD_DES_SUPPORT +# include +# endif + +# define DES_KEY_SZ (sizeof(DES_cblock)) +# define DES_SCHEDULE_SZ (sizeof(DES_key_schedule)) + +# define DES_ENCRYPT 1 +# define DES_DECRYPT 0 + +# define DES_CBC_MODE 0 +# define DES_PCBC_MODE 1 + +# define DES_ecb2_encrypt(i,o,k1,k2,e) \ + DES_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +# define DES_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + DES_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +# define DES_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + DES_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +# define DES_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + DES_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +OPENSSL_DECLARE_GLOBAL(int, DES_check_key); /* defaults to false */ +# define DES_check_key OPENSSL_GLOBAL_REF(DES_check_key) +OPENSSL_DECLARE_GLOBAL(int, DES_rw_mode); /* defaults to DES_PCBC_MODE */ +# define DES_rw_mode OPENSSL_GLOBAL_REF(DES_rw_mode) + +const char *DES_options(void); +void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, int enc); +DES_LONG DES_cbc_cksum(const unsigned char *input, DES_cblock *output, + long length, DES_key_schedule *schedule, + const_DES_cblock *ivec); +/* DES_cbc_encrypt does not update the IV! Use DES_ncbc_encrypt instead. */ +void DES_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_ncbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_xcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, const_DES_cblock *inw, + const_DES_cblock *outw, int enc); +void DES_cfb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks, int enc); + +/* + * This is the DES encryption function that gets called by just about every + * other DES routine in the library. You should not use this function except + * to implement 'modes' of DES. I say this because the functions that call + * this routine do the conversion from 'char *' to long, and this needs to be + * done to make sure 'non-aligned' memory access do not occur. The + * characters are loaded 'little endian'. Data is a pointer to 2 unsigned + * long's and ks is the DES_key_schedule to use. enc, is non zero specifies + * encryption, zero if decryption. + */ +void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc); + +/* + * This functions is the same as DES_encrypt1() except that the DES initial + * permutation (IP) and final permutation (FP) have been left out. As for + * DES_encrypt1(), you should not use this function. It is used by the + * routines in the library that implement triple DES. IP() DES_encrypt2() + * DES_encrypt2() DES_encrypt2() FP() is the same as DES_encrypt1() + * DES_encrypt1() DES_encrypt1() except faster :-). + */ +void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc); + +void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3); +void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, DES_cblock *ivec, int enc); +void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out, + long length, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, + DES_cblock *ivec1, DES_cblock *ivec2, int enc); +void DES_ede3_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num, int enc); +void DES_ede3_cfb_encrypt(const unsigned char *in, unsigned char *out, + int numbits, long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int enc); +void DES_ede3_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int *num); +# if 0 +void DES_xwhite_in2out(const_DES_cblock *DES_key, const_DES_cblock *in_white, + DES_cblock *out_white); +# endif + +int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, + DES_cblock *iv); +int DES_enc_write(int fd, const void *buf, int len, DES_key_schedule *sched, + DES_cblock *iv); +char *DES_fcrypt(const char *buf, const char *salt, char *ret); +char *DES_crypt(const char *buf, const char *salt); +void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec); +void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc); +DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[], + long length, int out_count, DES_cblock *seed); +int DES_random_key(DES_cblock *ret); +void DES_set_odd_parity(DES_cblock *key); +int DES_check_key_parity(const_DES_cblock *key); +int DES_is_weak_key(const_DES_cblock *key); +/* + * DES_set_key (= set_key = DES_key_sched = key_sched) calls + * DES_set_key_checked if global variable DES_check_key is set, + * DES_set_key_unchecked otherwise. + */ +int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule); +int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule); +int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule); +void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule); +# ifdef OPENSSL_FIPS +void private_DES_set_key_unchecked(const_DES_cblock *key, + DES_key_schedule *schedule); +# endif +void DES_string_to_key(const char *str, DES_cblock *key); +void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2); +void DES_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num, int enc); +void DES_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int *num); + +int DES_read_password(DES_cblock *key, const char *prompt, int verify); +int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2, + const char *prompt, int verify); + +# define DES_fixup_key_parity DES_set_odd_parity + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/des/des.pod b/libs/openssl/crypto/des/des.pod new file mode 100644 index 00000000..bf479e83 --- /dev/null +++ b/libs/openssl/crypto/des/des.pod @@ -0,0 +1,217 @@ +=pod + +=head1 NAME + +des - encrypt or decrypt data using Data Encryption Standard + +=head1 SYNOPSIS + +B +( +B<-e> +| +B<-E> +) | ( +B<-d> +| +B<-D> +) | ( +B<->[B][B] +) | +[ +B<-b3hfs> +] [ +B<-k> +I +] +] [ +B<-u>[I] +[ +I +[ +I +] ] + +=head1 NOTE + +This page describes the B stand-alone program, not the B +command. + +=head1 DESCRIPTION + +B +encrypts and decrypts data using the +Data Encryption Standard algorithm. +One of +B<-e>, B<-E> +(for encrypt) or +B<-d>, B<-D> +(for decrypt) must be specified. +It is also possible to use +B<-c> +or +B<-C> +in conjunction or instead of the a encrypt/decrypt option to generate +a 16 character hexadecimal checksum, generated via the +I. + +Two standard encryption modes are supported by the +B +program, Cipher Block Chaining (the default) and Electronic Code Book +(specified with +B<-b>). + +The key used for the DES +algorithm is obtained by prompting the user unless the +B<-k> +I +option is given. +If the key is an argument to the +B +command, it is potentially visible to users executing +ps(1) +or a derivative. To minimise this possibility, +B +takes care to destroy the key argument immediately upon entry. +If your shell keeps a history file be careful to make sure it is not +world readable. + +Since this program attempts to maintain compatibility with sunOS's +des(1) command, there are 2 different methods used to convert the user +supplied key to a des key. +Whenever and one or more of +B<-E>, B<-D>, B<-C> +or +B<-3> +options are used, the key conversion procedure will not be compatible +with the sunOS des(1) version but will use all the user supplied +character to generate the des key. +B +command reads from standard input unless +I +is specified and writes to standard output unless +I +is given. + +=head1 OPTIONS + +=over 4 + +=item B<-b> + +Select ECB +(eight bytes at a time) encryption mode. + +=item B<-3> + +Encrypt using triple encryption. +By default triple cbc encryption is used but if the +B<-b> +option is used then triple ECB encryption is performed. +If the key is less than 8 characters long, the flag has no effect. + +=item B<-e> + +Encrypt data using an 8 byte key in a manner compatible with sunOS +des(1). + +=item B<-E> + +Encrypt data using a key of nearly unlimited length (1024 bytes). +This will product a more secure encryption. + +=item B<-d> + +Decrypt data that was encrypted with the B<-e> option. + +=item B<-D> + +Decrypt data that was encrypted with the B<-E> option. + +=item B<-c> + +Generate a 16 character hexadecimal cbc checksum and output this to +stderr. +If a filename was specified after the +B<-c> +option, the checksum is output to that file. +The checksum is generated using a key generated in a sunOS compatible +manner. + +=item B<-C> + +A cbc checksum is generated in the same manner as described for the +B<-c> +option but the DES key is generated in the same manner as used for the +B<-E> +and +B<-D> +options + +=item B<-f> + +Does nothing - allowed for compatibility with sunOS des(1) command. + +=item B<-s> + +Does nothing - allowed for compatibility with sunOS des(1) command. + +=item B<-k> I + +Use the encryption +I +specified. + +=item B<-h> + +The +I +is assumed to be a 16 character hexadecimal number. +If the +B<-3> +option is used the key is assumed to be a 32 character hexadecimal +number. + +=item B<-u> + +This flag is used to read and write uuencoded files. If decrypting, +the input file is assumed to contain uuencoded, DES encrypted data. +If encrypting, the characters following the B<-u> are used as the name of +the uuencoded file to embed in the begin line of the uuencoded +output. If there is no name specified after the B<-u>, the name text.des +will be embedded in the header. + +=head1 SEE ALSO + +ps(1), +L + +=head1 BUGS + +The problem with using the +B<-e> +option is the short key length. +It would be better to use a real 56-bit key rather than an +ASCII-based 56-bit pattern. Knowing that the key was derived from ASCII +radically reduces the time necessary for a brute-force cryptographic attack. +My attempt to remove this problem is to add an alternative text-key to +DES-key function. This alternative function (accessed via +B<-E>, B<-D>, B<-S> +and +B<-3>) +uses DES to help generate the key. + +Be carefully when using the B<-u> option. Doing B I will +not decrypt filename (the B<-u> option will gobble the B<-d> option). + +The VMS operating system operates in a world where files are always a +multiple of 512 bytes. This causes problems when encrypted data is +send from Unix to VMS since a 88 byte file will suddenly be padded +with 424 null bytes. To get around this problem, use the B<-u> option +to uuencode the data before it is send to the VMS system. + +=head1 AUTHOR + +Eric Young (eay@cryptsoft.com) + +=cut diff --git a/libs/openssl/crypto/des/des3s.cpp b/libs/openssl/crypto/des/des3s.cpp new file mode 100644 index 00000000..02d527c0 --- /dev/null +++ b/libs/openssl/crypto/des/des3s.cpp @@ -0,0 +1,67 @@ +// +// gettsc.inl +// +// gives access to the Pentium's (secret) cycle counter +// +// This software was written by Leonard Janke (janke@unixg.ubc.ca) +// in 1996-7 and is entered, by him, into the public domain. + +#if defined(__WATCOMC__) +void GetTSC(unsigned long&); +#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax]; +#elif defined(__GNUC__) +inline +void GetTSC(unsigned long& tsc) +{ + asm volatile(".byte 15, 49\n\t" + : "=eax" (tsc) + : + : "%edx", "%eax"); +} +#elif defined(_MSC_VER) +inline +void GetTSC(unsigned long& tsc) +{ + unsigned long a; + __asm _emit 0fh + __asm _emit 31h + __asm mov a, eax; + tsc=a; +} +#endif + +#include +#include +#include + +void main(int argc,char *argv[]) + { + des_key_schedule key1,key2,key3; + unsigned long s1,s2,e1,e2; + unsigned long data[2]; + int i,j; + + for (j=0; j<6; j++) + { + for (i=0; i<1000; i++) /**/ + { + des_encrypt3(&data[0],key1,key2,key3); + GetTSC(s1); + des_encrypt3(&data[0],key1,key2,key3); + des_encrypt3(&data[0],key1,key2,key3); + des_encrypt3(&data[0],key1,key2,key3); + GetTSC(e1); + GetTSC(s2); + des_encrypt3(&data[0],key1,key2,key3); + des_encrypt3(&data[0],key1,key2,key3); + des_encrypt3(&data[0],key1,key2,key3); + des_encrypt3(&data[0],key1,key2,key3); + GetTSC(e2); + des_encrypt3(&data[0],key1,key2,key3); + } + + printf("des %d %d (%d)\n", + e1-s1,e2-s2,((e2-s2)-(e1-s1))); + } + } + diff --git a/libs/openssl/crypto/des/des_enc.c b/libs/openssl/crypto/des/des_enc.c new file mode 100644 index 00000000..c0b062da --- /dev/null +++ b/libs/openssl/crypto/des/des_enc.c @@ -0,0 +1,389 @@ +/* crypto/des/des_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" +#include "spr.h" + +void DES_encrypt1(DES_LONG *data, DES_key_schedule *ks, int enc) +{ + register DES_LONG l, r, t, u; +#ifdef DES_PTR + register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans; +#endif +#ifndef DES_UNROLL + register int i; +#endif + register DES_LONG *s; + + r = data[0]; + l = data[1]; + + IP(r, l); + /* + * Things have been modified so that the initial rotate is done outside + * the loop. This required the DES_SPtrans values in sp.h to be rotated + * 1 bit to the right. One perl script later and things have a 5% speed + * up on a sparc2. Thanks to Richard Outerbridge + * <71755.204@CompuServe.COM> for pointing this out. + */ + /* clear the top bits on machines with 8byte longs */ + /* shift left by 2 */ + r = ROTATE(r, 29) & 0xffffffffL; + l = ROTATE(l, 29) & 0xffffffffL; + + s = ks->ks->deslong; + /* + * I don't know if it is worth the effort of loop unrolling the inner + * loop + */ + if (enc) { +#ifdef DES_UNROLL + D_ENCRYPT(l, r, 0); /* 1 */ + D_ENCRYPT(r, l, 2); /* 2 */ + D_ENCRYPT(l, r, 4); /* 3 */ + D_ENCRYPT(r, l, 6); /* 4 */ + D_ENCRYPT(l, r, 8); /* 5 */ + D_ENCRYPT(r, l, 10); /* 6 */ + D_ENCRYPT(l, r, 12); /* 7 */ + D_ENCRYPT(r, l, 14); /* 8 */ + D_ENCRYPT(l, r, 16); /* 9 */ + D_ENCRYPT(r, l, 18); /* 10 */ + D_ENCRYPT(l, r, 20); /* 11 */ + D_ENCRYPT(r, l, 22); /* 12 */ + D_ENCRYPT(l, r, 24); /* 13 */ + D_ENCRYPT(r, l, 26); /* 14 */ + D_ENCRYPT(l, r, 28); /* 15 */ + D_ENCRYPT(r, l, 30); /* 16 */ +#else + for (i = 0; i < 32; i += 4) { + D_ENCRYPT(l, r, i + 0); /* 1 */ + D_ENCRYPT(r, l, i + 2); /* 2 */ + } +#endif + } else { +#ifdef DES_UNROLL + D_ENCRYPT(l, r, 30); /* 16 */ + D_ENCRYPT(r, l, 28); /* 15 */ + D_ENCRYPT(l, r, 26); /* 14 */ + D_ENCRYPT(r, l, 24); /* 13 */ + D_ENCRYPT(l, r, 22); /* 12 */ + D_ENCRYPT(r, l, 20); /* 11 */ + D_ENCRYPT(l, r, 18); /* 10 */ + D_ENCRYPT(r, l, 16); /* 9 */ + D_ENCRYPT(l, r, 14); /* 8 */ + D_ENCRYPT(r, l, 12); /* 7 */ + D_ENCRYPT(l, r, 10); /* 6 */ + D_ENCRYPT(r, l, 8); /* 5 */ + D_ENCRYPT(l, r, 6); /* 4 */ + D_ENCRYPT(r, l, 4); /* 3 */ + D_ENCRYPT(l, r, 2); /* 2 */ + D_ENCRYPT(r, l, 0); /* 1 */ +#else + for (i = 30; i > 0; i -= 4) { + D_ENCRYPT(l, r, i - 0); /* 16 */ + D_ENCRYPT(r, l, i - 2); /* 15 */ + } +#endif + } + + /* rotate and clear the top bits on machines with 8byte longs */ + l = ROTATE(l, 3) & 0xffffffffL; + r = ROTATE(r, 3) & 0xffffffffL; + + FP(r, l); + data[0] = l; + data[1] = r; + l = r = t = u = 0; +} + +void DES_encrypt2(DES_LONG *data, DES_key_schedule *ks, int enc) +{ + register DES_LONG l, r, t, u; +#ifdef DES_PTR + register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans; +#endif +#ifndef DES_UNROLL + register int i; +#endif + register DES_LONG *s; + + r = data[0]; + l = data[1]; + + /* + * Things have been modified so that the initial rotate is done outside + * the loop. This required the DES_SPtrans values in sp.h to be rotated + * 1 bit to the right. One perl script later and things have a 5% speed + * up on a sparc2. Thanks to Richard Outerbridge + * <71755.204@CompuServe.COM> for pointing this out. + */ + /* clear the top bits on machines with 8byte longs */ + r = ROTATE(r, 29) & 0xffffffffL; + l = ROTATE(l, 29) & 0xffffffffL; + + s = ks->ks->deslong; + /* + * I don't know if it is worth the effort of loop unrolling the inner + * loop + */ + if (enc) { +#ifdef DES_UNROLL + D_ENCRYPT(l, r, 0); /* 1 */ + D_ENCRYPT(r, l, 2); /* 2 */ + D_ENCRYPT(l, r, 4); /* 3 */ + D_ENCRYPT(r, l, 6); /* 4 */ + D_ENCRYPT(l, r, 8); /* 5 */ + D_ENCRYPT(r, l, 10); /* 6 */ + D_ENCRYPT(l, r, 12); /* 7 */ + D_ENCRYPT(r, l, 14); /* 8 */ + D_ENCRYPT(l, r, 16); /* 9 */ + D_ENCRYPT(r, l, 18); /* 10 */ + D_ENCRYPT(l, r, 20); /* 11 */ + D_ENCRYPT(r, l, 22); /* 12 */ + D_ENCRYPT(l, r, 24); /* 13 */ + D_ENCRYPT(r, l, 26); /* 14 */ + D_ENCRYPT(l, r, 28); /* 15 */ + D_ENCRYPT(r, l, 30); /* 16 */ +#else + for (i = 0; i < 32; i += 4) { + D_ENCRYPT(l, r, i + 0); /* 1 */ + D_ENCRYPT(r, l, i + 2); /* 2 */ + } +#endif + } else { +#ifdef DES_UNROLL + D_ENCRYPT(l, r, 30); /* 16 */ + D_ENCRYPT(r, l, 28); /* 15 */ + D_ENCRYPT(l, r, 26); /* 14 */ + D_ENCRYPT(r, l, 24); /* 13 */ + D_ENCRYPT(l, r, 22); /* 12 */ + D_ENCRYPT(r, l, 20); /* 11 */ + D_ENCRYPT(l, r, 18); /* 10 */ + D_ENCRYPT(r, l, 16); /* 9 */ + D_ENCRYPT(l, r, 14); /* 8 */ + D_ENCRYPT(r, l, 12); /* 7 */ + D_ENCRYPT(l, r, 10); /* 6 */ + D_ENCRYPT(r, l, 8); /* 5 */ + D_ENCRYPT(l, r, 6); /* 4 */ + D_ENCRYPT(r, l, 4); /* 3 */ + D_ENCRYPT(l, r, 2); /* 2 */ + D_ENCRYPT(r, l, 0); /* 1 */ +#else + for (i = 30; i > 0; i -= 4) { + D_ENCRYPT(l, r, i - 0); /* 16 */ + D_ENCRYPT(r, l, i - 2); /* 15 */ + } +#endif + } + /* rotate and clear the top bits on machines with 8byte longs */ + data[0] = ROTATE(l, 3) & 0xffffffffL; + data[1] = ROTATE(r, 3) & 0xffffffffL; + l = r = t = u = 0; +} + +void DES_encrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3) +{ + register DES_LONG l, r; + + l = data[0]; + r = data[1]; + IP(l, r); + data[0] = l; + data[1] = r; + DES_encrypt2((DES_LONG *)data, ks1, DES_ENCRYPT); + DES_encrypt2((DES_LONG *)data, ks2, DES_DECRYPT); + DES_encrypt2((DES_LONG *)data, ks3, DES_ENCRYPT); + l = data[0]; + r = data[1]; + FP(r, l); + data[0] = l; + data[1] = r; +} + +void DES_decrypt3(DES_LONG *data, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3) +{ + register DES_LONG l, r; + + l = data[0]; + r = data[1]; + IP(l, r); + data[0] = l; + data[1] = r; + DES_encrypt2((DES_LONG *)data, ks3, DES_DECRYPT); + DES_encrypt2((DES_LONG *)data, ks2, DES_ENCRYPT); + DES_encrypt2((DES_LONG *)data, ks1, DES_DECRYPT); + l = data[0]; + r = data[1]; + FP(r, l); + data[0] = l; + data[1] = r; +} + +#ifndef DES_DEFAULT_OPTIONS + +# undef CBC_ENC_C__DONT_UPDATE_IV +# include "ncbc_enc.c" /* DES_ncbc_encrypt */ + +void DES_ede3_cbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec, int enc) +{ + register DES_LONG tin0, tin1; + register DES_LONG tout0, tout1, xor0, xor1; + register const unsigned char *in; + unsigned char *out; + register long l = length; + DES_LONG tin[2]; + unsigned char *iv; + + in = input; + out = output; + iv = &(*ivec)[0]; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt3((DES_LONG *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + iv = &(*ivec)[0]; + l2c(tout0, iv); + l2c(tout1, iv); + } else { + register DES_LONG t0, t1; + + c2l(iv, xor0); + c2l(iv, xor1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + tout0 ^= xor0; + tout1 ^= xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = t0; + xor1 = t1; + } + if (l != -8) { + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_decrypt3((DES_LONG *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + tout0 ^= xor0; + tout1 ^= xor1; + l2cn(tout0, tout1, out, l + 8); + xor0 = t0; + xor1 = t1; + } + + iv = &(*ivec)[0]; + l2c(xor0, iv); + l2c(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} + +#endif /* DES_DEFAULT_OPTIONS */ diff --git a/libs/openssl/crypto/des/des_locl.h b/libs/openssl/crypto/des/des_locl.h new file mode 100644 index 00000000..1a8e41dd --- /dev/null +++ b/libs/openssl/crypto/des/des_locl.h @@ -0,0 +1,441 @@ +/* crypto/des/des_locl.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_DES_LOCL_H +# define HEADER_DES_LOCL_H + +# include + +# if defined(OPENSSL_SYS_WIN32) +# ifndef OPENSSL_SYS_MSDOS +# define OPENSSL_SYS_MSDOS +# endif +# endif + +# include +# include + +# ifndef OPENSSL_SYS_MSDOS +# if !defined(OPENSSL_SYS_VMS) || defined(__DECC) +# ifdef OPENSSL_UNISTD +# include OPENSSL_UNISTD +# else +# include +# endif +# include +# endif +# endif +# include + +# ifdef OPENSSL_SYS_MSDOS /* Visual C++ 2.1 (Windows NT/95) */ +# include +# include +# include +# include +# endif + +# if defined(__STDC__) || defined(OPENSSL_SYS_VMS) || defined(M_XENIX) || defined(OPENSSL_SYS_MSDOS) +# include +# endif + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +# define ITERATIONS 16 +# define HALF_ITERATIONS 8 + +/* used in des_read and des_write */ +# define MAXWRITE (1024*16) +# define BSIZE (MAXWRITE+4) + +# define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ + l|=((DES_LONG)(*((c)++)))<< 8L, \ + l|=((DES_LONG)(*((c)++)))<<16L, \ + l|=((DES_LONG)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +# define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((DES_LONG)(*(--(c))))<<24L; \ + case 7: l2|=((DES_LONG)(*(--(c))))<<16L; \ + case 6: l2|=((DES_LONG)(*(--(c))))<< 8L; \ + case 5: l2|=((DES_LONG)(*(--(c)))); \ + case 4: l1 =((DES_LONG)(*(--(c))))<<24L; \ + case 3: l1|=((DES_LONG)(*(--(c))))<<16L; \ + case 2: l1|=((DES_LONG)(*(--(c))))<< 8L; \ + case 1: l1|=((DES_LONG)(*(--(c)))); \ + } \ + } + +# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* + * replacements for htonl and ntohl since I have no idea what to do when + * faced with machines with 8 byte longs. + */ +# define HDRSIZE 4 + +# define n2l(c,l) (l =((DES_LONG)(*((c)++)))<<24L, \ + l|=((DES_LONG)(*((c)++)))<<16L, \ + l|=((DES_LONG)(*((c)++)))<< 8L, \ + l|=((DES_LONG)(*((c)++)))) + +# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +/* NOTE - c is not incremented as per l2c */ +# define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +# if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC) +# define ROTATE(a,n) (_lrotr(a,n)) +# elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC) +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ("rorl %1,%0" \ + : "=r"(ret) \ + : "I"(n),"0"(a) \ + : "cc"); \ + ret; \ + }) +# endif +# endif +# ifndef ROTATE +# define ROTATE(a,n) (((a)>>(n))+((a)<<(32-(n)))) +# endif + +/* + * Don't worry about the LOAD_DATA() stuff, that is used by fcrypt() to add + * it's little bit to the front + */ + +# ifdef DES_FCRYPT + +# define LOAD_DATA_tmp(R,S,u,t,E0,E1) \ + { DES_LONG tmp; LOAD_DATA(R,S,u,t,E0,E1,tmp); } + +# define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ + t=R^(R>>16L); \ + u=t&E0; t&=E1; \ + tmp=(u<<16); u^=R^s[S ]; u^=tmp; \ + tmp=(t<<16); t^=R^s[S+1]; t^=tmp +# else +# define LOAD_DATA_tmp(a,b,c,d,e,f) LOAD_DATA(a,b,c,d,e,f,g) +# define LOAD_DATA(R,S,u,t,E0,E1,tmp) \ + u=R^s[S ]; \ + t=R^s[S+1] +# endif + +/* + * The changes to this macro may help or hinder, depending on the compiler + * and the architecture. gcc2 always seems to do well :-). Inspired by Dana + * How DO NOT use the alternative version on machines + * with 8 byte longs. It does not seem to work on the Alpha, even when + * DES_LONG is 4 bytes, probably an issue of accessing non-word aligned + * objects :-( + */ +# ifdef DES_PTR + +/* + * It recently occurred to me that 0^0^0^0^0^0^0 == 0, so there is no reason + * to not xor all the sub items together. This potentially saves a register + * since things can be xored directly into L + */ + +# if defined(DES_RISC1) || defined(DES_RISC2) +# ifdef DES_RISC1 +# define D_ENCRYPT(LL,R,S) { \ + unsigned int u1,u2,u3; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u2=(int)u>>8L; \ + u1=(int)u&0xfc; \ + u2&=0xfc; \ + t=ROTATE(t,4); \ + u>>=16L; \ + LL^= *(const DES_LONG *)(des_SP +u1); \ + LL^= *(const DES_LONG *)(des_SP+0x200+u2); \ + u3=(int)(u>>8L); \ + u1=(int)u&0xfc; \ + u3&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x400+u1); \ + LL^= *(const DES_LONG *)(des_SP+0x600+u3); \ + u2=(int)t>>8L; \ + u1=(int)t&0xfc; \ + u2&=0xfc; \ + t>>=16L; \ + LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ + LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ + u3=(int)t>>8L; \ + u1=(int)t&0xfc; \ + u3&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x500+u1); \ + LL^= *(const DES_LONG *)(des_SP+0x700+u3); } +# endif +# ifdef DES_RISC2 +# define D_ENCRYPT(LL,R,S) { \ + unsigned int u1,u2,s1,s2; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u2=(int)u>>8L; \ + u1=(int)u&0xfc; \ + u2&=0xfc; \ + t=ROTATE(t,4); \ + LL^= *(const DES_LONG *)(des_SP +u1); \ + LL^= *(const DES_LONG *)(des_SP+0x200+u2); \ + s1=(int)(u>>16L); \ + s2=(int)(u>>24L); \ + s1&=0xfc; \ + s2&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x400+s1); \ + LL^= *(const DES_LONG *)(des_SP+0x600+s2); \ + u2=(int)t>>8L; \ + u1=(int)t&0xfc; \ + u2&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x100+u1); \ + LL^= *(const DES_LONG *)(des_SP+0x300+u2); \ + s1=(int)(t>>16L); \ + s2=(int)(t>>24L); \ + s1&=0xfc; \ + s2&=0xfc; \ + LL^= *(const DES_LONG *)(des_SP+0x500+s1); \ + LL^= *(const DES_LONG *)(des_SP+0x700+s2); } +# endif +# else +# define D_ENCRYPT(LL,R,S) { \ + LOAD_DATA_tmp(R,S,u,t,E0,E1); \ + t=ROTATE(t,4); \ + LL^= \ + *(const DES_LONG *)(des_SP +((u )&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x200+((u>> 8L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x400+((u>>16L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x600+((u>>24L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x100+((t )&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x300+((t>> 8L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x500+((t>>16L)&0xfc))^ \ + *(const DES_LONG *)(des_SP+0x700+((t>>24L)&0xfc)); } +# endif + +# else /* original version */ + +# if defined(DES_RISC1) || defined(DES_RISC2) +# ifdef DES_RISC1 +# define D_ENCRYPT(LL,R,S) {\ + unsigned int u1,u2,u3; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u>>=2L; \ + t=ROTATE(t,6); \ + u2=(int)u>>8L; \ + u1=(int)u&0x3f; \ + u2&=0x3f; \ + u>>=16L; \ + LL^=DES_SPtrans[0][u1]; \ + LL^=DES_SPtrans[2][u2]; \ + u3=(int)u>>8L; \ + u1=(int)u&0x3f; \ + u3&=0x3f; \ + LL^=DES_SPtrans[4][u1]; \ + LL^=DES_SPtrans[6][u3]; \ + u2=(int)t>>8L; \ + u1=(int)t&0x3f; \ + u2&=0x3f; \ + t>>=16L; \ + LL^=DES_SPtrans[1][u1]; \ + LL^=DES_SPtrans[3][u2]; \ + u3=(int)t>>8L; \ + u1=(int)t&0x3f; \ + u3&=0x3f; \ + LL^=DES_SPtrans[5][u1]; \ + LL^=DES_SPtrans[7][u3]; } +# endif +# ifdef DES_RISC2 +# define D_ENCRYPT(LL,R,S) {\ + unsigned int u1,u2,s1,s2; \ + LOAD_DATA(R,S,u,t,E0,E1,u1); \ + u>>=2L; \ + t=ROTATE(t,6); \ + u2=(int)u>>8L; \ + u1=(int)u&0x3f; \ + u2&=0x3f; \ + LL^=DES_SPtrans[0][u1]; \ + LL^=DES_SPtrans[2][u2]; \ + s1=(int)u>>16L; \ + s2=(int)u>>24L; \ + s1&=0x3f; \ + s2&=0x3f; \ + LL^=DES_SPtrans[4][s1]; \ + LL^=DES_SPtrans[6][s2]; \ + u2=(int)t>>8L; \ + u1=(int)t&0x3f; \ + u2&=0x3f; \ + LL^=DES_SPtrans[1][u1]; \ + LL^=DES_SPtrans[3][u2]; \ + s1=(int)t>>16; \ + s2=(int)t>>24L; \ + s1&=0x3f; \ + s2&=0x3f; \ + LL^=DES_SPtrans[5][s1]; \ + LL^=DES_SPtrans[7][s2]; } +# endif + +# else + +# define D_ENCRYPT(LL,R,S) {\ + LOAD_DATA_tmp(R,S,u,t,E0,E1); \ + t=ROTATE(t,4); \ + LL^=\ + DES_SPtrans[0][(u>> 2L)&0x3f]^ \ + DES_SPtrans[2][(u>>10L)&0x3f]^ \ + DES_SPtrans[4][(u>>18L)&0x3f]^ \ + DES_SPtrans[6][(u>>26L)&0x3f]^ \ + DES_SPtrans[1][(t>> 2L)&0x3f]^ \ + DES_SPtrans[3][(t>>10L)&0x3f]^ \ + DES_SPtrans[5][(t>>18L)&0x3f]^ \ + DES_SPtrans[7][(t>>26L)&0x3f]; } +# endif +# endif + + /*- + * IP and FP + * The problem is more of a geometric problem that random bit fiddling. + 0 1 2 3 4 5 6 7 62 54 46 38 30 22 14 6 + 8 9 10 11 12 13 14 15 60 52 44 36 28 20 12 4 + 16 17 18 19 20 21 22 23 58 50 42 34 26 18 10 2 + 24 25 26 27 28 29 30 31 to 56 48 40 32 24 16 8 0 + + 32 33 34 35 36 37 38 39 63 55 47 39 31 23 15 7 + 40 41 42 43 44 45 46 47 61 53 45 37 29 21 13 5 + 48 49 50 51 52 53 54 55 59 51 43 35 27 19 11 3 + 56 57 58 59 60 61 62 63 57 49 41 33 25 17 9 1 + + The output has been subject to swaps of the form + 0 1 -> 3 1 but the odd and even bits have been put into + 2 3 2 0 + different words. The main trick is to remember that + t=((l>>size)^r)&(mask); + r^=t; + l^=(t<>(n))^(b))&(m)),\ + (b)^=(t),\ + (a)^=((t)<<(n))) + +# define IP(l,r) \ + { \ + register DES_LONG tt; \ + PERM_OP(r,l,tt, 4,0x0f0f0f0fL); \ + PERM_OP(l,r,tt,16,0x0000ffffL); \ + PERM_OP(r,l,tt, 2,0x33333333L); \ + PERM_OP(l,r,tt, 8,0x00ff00ffL); \ + PERM_OP(r,l,tt, 1,0x55555555L); \ + } + +# define FP(l,r) \ + { \ + register DES_LONG tt; \ + PERM_OP(l,r,tt, 1,0x55555555L); \ + PERM_OP(r,l,tt, 8,0x00ff00ffL); \ + PERM_OP(l,r,tt, 2,0x33333333L); \ + PERM_OP(r,l,tt,16,0x0000ffffL); \ + PERM_OP(l,r,tt, 4,0x0f0f0f0fL); \ + } + +extern const DES_LONG DES_SPtrans[8][64]; + +void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, + DES_LONG Eswap0, DES_LONG Eswap1); + +# ifdef OPENSSL_SMALL_FOOTPRINT +# undef DES_UNROLL +# endif +#endif diff --git a/libs/openssl/crypto/des/des_old.c b/libs/openssl/crypto/des/des_old.c new file mode 100644 index 00000000..c5c5a00f --- /dev/null +++ b/libs/openssl/crypto/des/des_old.c @@ -0,0 +1,345 @@ +/* crypto/des/des_old.c */ + +/*- + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * + * The function names in here are deprecated and are only present to + * provide an interface compatible with libdes. OpenSSL now provides + * functions where "des_" has been replaced with "DES_" in the names, + * to make it possible to make incompatible changes that are needed + * for C type security and other stuff. + * + * Please consider starting to use the DES_ functions rather than the + * des_ ones. The des_ functions will dissapear completely before + * OpenSSL 1.0! + * + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ + +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#define OPENSSL_DES_LIBDES_COMPATIBILITY +#include +#include + +const char *_ossl_old_des_options(void) +{ + return DES_options(); +} + +void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, + des_key_schedule ks1, des_key_schedule ks2, + des_key_schedule ks3, int enc) +{ + DES_ecb3_encrypt((const_DES_cblock *)input, output, + (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, + (DES_key_schedule *)ks3, enc); +} + +DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + des_key_schedule schedule, + _ossl_old_des_cblock *ivec) +{ + return DES_cbc_cksum((unsigned char *)input, output, length, + (DES_key_schedule *)schedule, ivec); +} + +void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc) +{ + DES_cbc_encrypt((unsigned char *)input, (unsigned char *)output, + length, (DES_key_schedule *)schedule, ivec, enc); +} + +void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc) +{ + DES_ncbc_encrypt((unsigned char *)input, (unsigned char *)output, + length, (DES_key_schedule *)schedule, ivec, enc); +} + +void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + des_key_schedule schedule, + _ossl_old_des_cblock *ivec, + _ossl_old_des_cblock *inw, + _ossl_old_des_cblock *outw, int enc) +{ + DES_xcbc_encrypt((unsigned char *)input, (unsigned char *)output, + length, (DES_key_schedule *)schedule, ivec, inw, outw, + enc); +} + +void _ossl_old_des_cfb_encrypt(unsigned char *in, unsigned char *out, + int numbits, long length, + des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc) +{ + DES_cfb_encrypt(in, out, numbits, length, + (DES_key_schedule *)schedule, ivec, enc); +} + +void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, + des_key_schedule ks, int enc) +{ + DES_ecb_encrypt(input, output, (DES_key_schedule *)ks, enc); +} + +void _ossl_old_des_encrypt(DES_LONG *data, des_key_schedule ks, int enc) +{ + DES_encrypt1(data, (DES_key_schedule *)ks, enc); +} + +void _ossl_old_des_encrypt2(DES_LONG *data, des_key_schedule ks, int enc) +{ + DES_encrypt2(data, (DES_key_schedule *)ks, enc); +} + +void _ossl_old_des_encrypt3(DES_LONG *data, des_key_schedule ks1, + des_key_schedule ks2, des_key_schedule ks3) +{ + DES_encrypt3(data, (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, + (DES_key_schedule *)ks3); +} + +void _ossl_old_des_decrypt3(DES_LONG *data, des_key_schedule ks1, + des_key_schedule ks2, des_key_schedule ks3) +{ + DES_decrypt3(data, (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, + (DES_key_schedule *)ks3); +} + +void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + des_key_schedule ks1, + des_key_schedule ks2, + des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int enc) +{ + DES_ede3_cbc_encrypt((unsigned char *)input, (unsigned char *)output, + length, (DES_key_schedule *)ks1, + (DES_key_schedule *)ks2, (DES_key_schedule *)ks3, + ivec, enc); +} + +void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out, + long length, des_key_schedule ks1, + des_key_schedule ks2, + des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int *num, + int enc) +{ + DES_ede3_cfb64_encrypt(in, out, length, + (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, + (DES_key_schedule *)ks3, ivec, num, enc); +} + +void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out, + long length, des_key_schedule ks1, + des_key_schedule ks2, + des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int *num) +{ + DES_ede3_ofb64_encrypt(in, out, length, + (DES_key_schedule *)ks1, (DES_key_schedule *)ks2, + (DES_key_schedule *)ks3, ivec, num); +} + +#if 0 /* broken code, preserved just in case anyone + * specifically looks for this */ +void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key), + _ossl_old_des_cblock (*in_white), + _ossl_old_des_cblock (*out_white)) +{ + DES_xwhite_in2out(des_key, in_white, out_white); +} +#endif + +int _ossl_old_des_enc_read(int fd, char *buf, int len, des_key_schedule sched, + _ossl_old_des_cblock *iv) +{ + return DES_enc_read(fd, buf, len, (DES_key_schedule *)sched, iv); +} + +int _ossl_old_des_enc_write(int fd, char *buf, int len, + des_key_schedule sched, _ossl_old_des_cblock *iv) +{ + return DES_enc_write(fd, buf, len, (DES_key_schedule *)sched, iv); +} + +char *_ossl_old_des_fcrypt(const char *buf, const char *salt, char *ret) +{ + return DES_fcrypt(buf, salt, ret); +} + +char *_ossl_old_des_crypt(const char *buf, const char *salt) +{ + return DES_crypt(buf, salt); +} + +char *_ossl_old_crypt(const char *buf, const char *salt) +{ + return DES_crypt(buf, salt); +} + +void _ossl_old_des_ofb_encrypt(unsigned char *in, unsigned char *out, + int numbits, long length, + des_key_schedule schedule, + _ossl_old_des_cblock *ivec) +{ + DES_ofb_encrypt(in, out, numbits, length, (DES_key_schedule *)schedule, + ivec); +} + +void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc) +{ + DES_pcbc_encrypt((unsigned char *)input, (unsigned char *)output, + length, (DES_key_schedule *)schedule, ivec, enc); +} + +DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + int out_count, _ossl_old_des_cblock *seed) +{ + return DES_quad_cksum((unsigned char *)input, output, length, + out_count, seed); +} + +void _ossl_old_des_random_seed(_ossl_old_des_cblock key) +{ + RAND_seed(key, sizeof(_ossl_old_des_cblock)); +} + +void _ossl_old_des_random_key(_ossl_old_des_cblock ret) +{ + DES_random_key((DES_cblock *)ret); +} + +int _ossl_old_des_read_password(_ossl_old_des_cblock *key, const char *prompt, + int verify) +{ + return DES_read_password(key, prompt, verify); +} + +int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1, + _ossl_old_des_cblock *key2, + const char *prompt, int verify) +{ + return DES_read_2passwords(key1, key2, prompt, verify); +} + +void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key) +{ + DES_set_odd_parity(key); +} + +int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key) +{ + return DES_is_weak_key(key); +} + +int _ossl_old_des_set_key(_ossl_old_des_cblock *key, + des_key_schedule schedule) +{ + return DES_set_key(key, (DES_key_schedule *)schedule); +} + +int _ossl_old_des_key_sched(_ossl_old_des_cblock *key, + des_key_schedule schedule) +{ + return DES_key_sched(key, (DES_key_schedule *)schedule); +} + +void _ossl_old_des_string_to_key(char *str, _ossl_old_des_cblock *key) +{ + DES_string_to_key(str, key); +} + +void _ossl_old_des_string_to_2keys(char *str, _ossl_old_des_cblock *key1, + _ossl_old_des_cblock *key2) +{ + DES_string_to_2keys(str, key1, key2); +} + +void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out, + long length, des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int *num, + int enc) +{ + DES_cfb64_encrypt(in, out, length, (DES_key_schedule *)schedule, + ivec, num, enc); +} + +void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out, + long length, des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int *num) +{ + DES_ofb64_encrypt(in, out, length, (DES_key_schedule *)schedule, + ivec, num); +} diff --git a/libs/openssl/crypto/des/des_old.h b/libs/openssl/crypto/des/des_old.h new file mode 100644 index 00000000..ee7607a2 --- /dev/null +++ b/libs/openssl/crypto/des/des_old.h @@ -0,0 +1,497 @@ +/* crypto/des/des_old.h */ + +/*- + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + * + * The function names in here are deprecated and are only present to + * provide an interface compatible with openssl 0.9.6 and older as + * well as libdes. OpenSSL now provides functions where "des_" has + * been replaced with "DES_" in the names, to make it possible to + * make incompatible changes that are needed for C type security and + * other stuff. + * + * This include files has two compatibility modes: + * + * - If OPENSSL_DES_LIBDES_COMPATIBILITY is defined, you get an API + * that is compatible with libdes and SSLeay. + * - If OPENSSL_DES_LIBDES_COMPATIBILITY isn't defined, you get an + * API that is compatible with OpenSSL 0.9.5x to 0.9.6x. + * + * Note that these modes break earlier snapshots of OpenSSL, where + * libdes compatibility was the only available mode or (later on) the + * prefered compatibility mode. However, after much consideration + * (and more or less violent discussions with external parties), it + * was concluded that OpenSSL should be compatible with earlier versions + * of itself before anything else. Also, in all honesty, libdes is + * an old beast that shouldn't really be used any more. + * + * Please consider starting to use the DES_ functions rather than the + * des_ ones. The des_ functions will disappear completely before + * OpenSSL 1.0! + * + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING + */ + +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_DES_H +# define HEADER_DES_H + +# include /* OPENSSL_EXTERN, OPENSSL_NO_DES, DES_LONG */ + +# ifdef OPENSSL_NO_DES +# error DES is disabled. +# endif + +# ifndef HEADER_NEW_DES_H +# error You must include des.h, not des_old.h directly. +# endif + +# ifdef _KERBEROS_DES_H +# error replaces . +# endif + +# include + +# ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef _ +# undef _ +# endif + +typedef unsigned char _ossl_old_des_cblock[8]; +typedef struct _ossl_old_des_ks_struct { + union { + _ossl_old_des_cblock _; + /* + * make sure things are correct size on machines with 8 byte longs + */ + DES_LONG pad[2]; + } ks; +} _ossl_old_des_key_schedule[16]; + +# ifndef OPENSSL_DES_LIBDES_COMPATIBILITY +# define des_cblock DES_cblock +# define const_des_cblock const_DES_cblock +# define des_key_schedule DES_key_schedule +# define des_ecb3_encrypt(i,o,k1,k2,k3,e)\ + DES_ecb3_encrypt((i),(o),&(k1),&(k2),&(k3),(e)) +# define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\ + DES_ede3_cbc_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(e)) +# define des_ede3_cbcm_encrypt(i,o,l,k1,k2,k3,iv1,iv2,e)\ + DES_ede3_cbcm_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv1),(iv2),(e)) +# define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\ + DES_ede3_cfb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n),(e)) +# define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\ + DES_ede3_ofb64_encrypt((i),(o),(l),&(k1),&(k2),&(k3),(iv),(n)) +# define des_options()\ + DES_options() +# define des_cbc_cksum(i,o,l,k,iv)\ + DES_cbc_cksum((i),(o),(l),&(k),(iv)) +# define des_cbc_encrypt(i,o,l,k,iv,e)\ + DES_cbc_encrypt((i),(o),(l),&(k),(iv),(e)) +# define des_ncbc_encrypt(i,o,l,k,iv,e)\ + DES_ncbc_encrypt((i),(o),(l),&(k),(iv),(e)) +# define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\ + DES_xcbc_encrypt((i),(o),(l),&(k),(iv),(inw),(outw),(e)) +# define des_cfb_encrypt(i,o,n,l,k,iv,e)\ + DES_cfb_encrypt((i),(o),(n),(l),&(k),(iv),(e)) +# define des_ecb_encrypt(i,o,k,e)\ + DES_ecb_encrypt((i),(o),&(k),(e)) +# define des_encrypt1(d,k,e)\ + DES_encrypt1((d),&(k),(e)) +# define des_encrypt2(d,k,e)\ + DES_encrypt2((d),&(k),(e)) +# define des_encrypt3(d,k1,k2,k3)\ + DES_encrypt3((d),&(k1),&(k2),&(k3)) +# define des_decrypt3(d,k1,k2,k3)\ + DES_decrypt3((d),&(k1),&(k2),&(k3)) +# define des_xwhite_in2out(k,i,o)\ + DES_xwhite_in2out((k),(i),(o)) +# define des_enc_read(f,b,l,k,iv)\ + DES_enc_read((f),(b),(l),&(k),(iv)) +# define des_enc_write(f,b,l,k,iv)\ + DES_enc_write((f),(b),(l),&(k),(iv)) +# define des_fcrypt(b,s,r)\ + DES_fcrypt((b),(s),(r)) +# if 0 +# define des_crypt(b,s)\ + DES_crypt((b),(s)) +# if !defined(PERL5) && !defined(__FreeBSD__) && !defined(NeXT) && !defined(__OpenBSD__) +# define crypt(b,s)\ + DES_crypt((b),(s)) +# endif +# endif +# define des_ofb_encrypt(i,o,n,l,k,iv)\ + DES_ofb_encrypt((i),(o),(n),(l),&(k),(iv)) +# define des_pcbc_encrypt(i,o,l,k,iv,e)\ + DES_pcbc_encrypt((i),(o),(l),&(k),(iv),(e)) +# define des_quad_cksum(i,o,l,c,s)\ + DES_quad_cksum((i),(o),(l),(c),(s)) +# define des_random_seed(k)\ + _ossl_096_des_random_seed((k)) +# define des_random_key(r)\ + DES_random_key((r)) +# define des_read_password(k,p,v) \ + DES_read_password((k),(p),(v)) +# define des_read_2passwords(k1,k2,p,v) \ + DES_read_2passwords((k1),(k2),(p),(v)) +# define des_set_odd_parity(k)\ + DES_set_odd_parity((k)) +# define des_check_key_parity(k)\ + DES_check_key_parity((k)) +# define des_is_weak_key(k)\ + DES_is_weak_key((k)) +# define des_set_key(k,ks)\ + DES_set_key((k),&(ks)) +# define des_key_sched(k,ks)\ + DES_key_sched((k),&(ks)) +# define des_set_key_checked(k,ks)\ + DES_set_key_checked((k),&(ks)) +# define des_set_key_unchecked(k,ks)\ + DES_set_key_unchecked((k),&(ks)) +# define des_string_to_key(s,k)\ + DES_string_to_key((s),(k)) +# define des_string_to_2keys(s,k1,k2)\ + DES_string_to_2keys((s),(k1),(k2)) +# define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\ + DES_cfb64_encrypt((i),(o),(l),&(ks),(iv),(n),(e)) +# define des_ofb64_encrypt(i,o,l,ks,iv,n)\ + DES_ofb64_encrypt((i),(o),(l),&(ks),(iv),(n)) + +# define des_ecb2_encrypt(i,o,k1,k2,e) \ + des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +# define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +# define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +# define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +# define des_check_key DES_check_key +# define des_rw_mode DES_rw_mode +# else /* libdes compatibility */ +/* + * Map all symbol names to _ossl_old_des_* form, so we avoid all clashes with + * libdes + */ +# define des_cblock _ossl_old_des_cblock +# define des_key_schedule _ossl_old_des_key_schedule +# define des_ecb3_encrypt(i,o,k1,k2,k3,e)\ + _ossl_old_des_ecb3_encrypt((i),(o),(k1),(k2),(k3),(e)) +# define des_ede3_cbc_encrypt(i,o,l,k1,k2,k3,iv,e)\ + _ossl_old_des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(e)) +# define des_ede3_cfb64_encrypt(i,o,l,k1,k2,k3,iv,n,e)\ + _ossl_old_des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n),(e)) +# define des_ede3_ofb64_encrypt(i,o,l,k1,k2,k3,iv,n)\ + _ossl_old_des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k3),(iv),(n)) +# define des_options()\ + _ossl_old_des_options() +# define des_cbc_cksum(i,o,l,k,iv)\ + _ossl_old_des_cbc_cksum((i),(o),(l),(k),(iv)) +# define des_cbc_encrypt(i,o,l,k,iv,e)\ + _ossl_old_des_cbc_encrypt((i),(o),(l),(k),(iv),(e)) +# define des_ncbc_encrypt(i,o,l,k,iv,e)\ + _ossl_old_des_ncbc_encrypt((i),(o),(l),(k),(iv),(e)) +# define des_xcbc_encrypt(i,o,l,k,iv,inw,outw,e)\ + _ossl_old_des_xcbc_encrypt((i),(o),(l),(k),(iv),(inw),(outw),(e)) +# define des_cfb_encrypt(i,o,n,l,k,iv,e)\ + _ossl_old_des_cfb_encrypt((i),(o),(n),(l),(k),(iv),(e)) +# define des_ecb_encrypt(i,o,k,e)\ + _ossl_old_des_ecb_encrypt((i),(o),(k),(e)) +# define des_encrypt(d,k,e)\ + _ossl_old_des_encrypt((d),(k),(e)) +# define des_encrypt2(d,k,e)\ + _ossl_old_des_encrypt2((d),(k),(e)) +# define des_encrypt3(d,k1,k2,k3)\ + _ossl_old_des_encrypt3((d),(k1),(k2),(k3)) +# define des_decrypt3(d,k1,k2,k3)\ + _ossl_old_des_decrypt3((d),(k1),(k2),(k3)) +# define des_xwhite_in2out(k,i,o)\ + _ossl_old_des_xwhite_in2out((k),(i),(o)) +# define des_enc_read(f,b,l,k,iv)\ + _ossl_old_des_enc_read((f),(b),(l),(k),(iv)) +# define des_enc_write(f,b,l,k,iv)\ + _ossl_old_des_enc_write((f),(b),(l),(k),(iv)) +# define des_fcrypt(b,s,r)\ + _ossl_old_des_fcrypt((b),(s),(r)) +# define des_crypt(b,s)\ + _ossl_old_des_crypt((b),(s)) +# if 0 +# define crypt(b,s)\ + _ossl_old_crypt((b),(s)) +# endif +# define des_ofb_encrypt(i,o,n,l,k,iv)\ + _ossl_old_des_ofb_encrypt((i),(o),(n),(l),(k),(iv)) +# define des_pcbc_encrypt(i,o,l,k,iv,e)\ + _ossl_old_des_pcbc_encrypt((i),(o),(l),(k),(iv),(e)) +# define des_quad_cksum(i,o,l,c,s)\ + _ossl_old_des_quad_cksum((i),(o),(l),(c),(s)) +# define des_random_seed(k)\ + _ossl_old_des_random_seed((k)) +# define des_random_key(r)\ + _ossl_old_des_random_key((r)) +# define des_read_password(k,p,v) \ + _ossl_old_des_read_password((k),(p),(v)) +# define des_read_2passwords(k1,k2,p,v) \ + _ossl_old_des_read_2passwords((k1),(k2),(p),(v)) +# define des_set_odd_parity(k)\ + _ossl_old_des_set_odd_parity((k)) +# define des_is_weak_key(k)\ + _ossl_old_des_is_weak_key((k)) +# define des_set_key(k,ks)\ + _ossl_old_des_set_key((k),(ks)) +# define des_key_sched(k,ks)\ + _ossl_old_des_key_sched((k),(ks)) +# define des_string_to_key(s,k)\ + _ossl_old_des_string_to_key((s),(k)) +# define des_string_to_2keys(s,k1,k2)\ + _ossl_old_des_string_to_2keys((s),(k1),(k2)) +# define des_cfb64_encrypt(i,o,l,ks,iv,n,e)\ + _ossl_old_des_cfb64_encrypt((i),(o),(l),(ks),(iv),(n),(e)) +# define des_ofb64_encrypt(i,o,l,ks,iv,n)\ + _ossl_old_des_ofb64_encrypt((i),(o),(l),(ks),(iv),(n)) + +# define des_ecb2_encrypt(i,o,k1,k2,e) \ + des_ecb3_encrypt((i),(o),(k1),(k2),(k1),(e)) + +# define des_ede2_cbc_encrypt(i,o,l,k1,k2,iv,e) \ + des_ede3_cbc_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(e)) + +# define des_ede2_cfb64_encrypt(i,o,l,k1,k2,iv,n,e) \ + des_ede3_cfb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n),(e)) + +# define des_ede2_ofb64_encrypt(i,o,l,k1,k2,iv,n) \ + des_ede3_ofb64_encrypt((i),(o),(l),(k1),(k2),(k1),(iv),(n)) + +# define des_check_key DES_check_key +# define des_rw_mode DES_rw_mode +# endif + +const char *_ossl_old_des_options(void); +void _ossl_old_des_ecb3_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, + _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3, int enc); +DES_LONG _ossl_old_des_cbc_cksum(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec); +void _ossl_old_des_cbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc); +void _ossl_old_des_ncbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc); +void _ossl_old_des_xcbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, + _ossl_old_des_cblock *inw, + _ossl_old_des_cblock *outw, int enc); +void _ossl_old_des_cfb_encrypt(unsigned char *in, unsigned char *out, + int numbits, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc); +void _ossl_old_des_ecb_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, + _ossl_old_des_key_schedule ks, int enc); +void _ossl_old_des_encrypt(DES_LONG *data, _ossl_old_des_key_schedule ks, + int enc); +void _ossl_old_des_encrypt2(DES_LONG *data, _ossl_old_des_key_schedule ks, + int enc); +void _ossl_old_des_encrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3); +void _ossl_old_des_decrypt3(DES_LONG *data, _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3); +void _ossl_old_des_ede3_cbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int enc); +void _ossl_old_des_ede3_cfb64_encrypt(unsigned char *in, unsigned char *out, + long length, + _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int *num, + int enc); +void _ossl_old_des_ede3_ofb64_encrypt(unsigned char *in, unsigned char *out, + long length, + _ossl_old_des_key_schedule ks1, + _ossl_old_des_key_schedule ks2, + _ossl_old_des_key_schedule ks3, + _ossl_old_des_cblock *ivec, int *num); +# if 0 +void _ossl_old_des_xwhite_in2out(_ossl_old_des_cblock (*des_key), + _ossl_old_des_cblock (*in_white), + _ossl_old_des_cblock (*out_white)); +# endif + +int _ossl_old_des_enc_read(int fd, char *buf, int len, + _ossl_old_des_key_schedule sched, + _ossl_old_des_cblock *iv); +int _ossl_old_des_enc_write(int fd, char *buf, int len, + _ossl_old_des_key_schedule sched, + _ossl_old_des_cblock *iv); +char *_ossl_old_des_fcrypt(const char *buf, const char *salt, char *ret); +char *_ossl_old_des_crypt(const char *buf, const char *salt); +# if !defined(PERL5) && !defined(NeXT) +char *_ossl_old_crypt(const char *buf, const char *salt); +# endif +void _ossl_old_des_ofb_encrypt(unsigned char *in, unsigned char *out, + int numbits, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec); +void _ossl_old_des_pcbc_encrypt(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int enc); +DES_LONG _ossl_old_des_quad_cksum(_ossl_old_des_cblock *input, + _ossl_old_des_cblock *output, long length, + int out_count, _ossl_old_des_cblock *seed); +void _ossl_old_des_random_seed(_ossl_old_des_cblock key); +void _ossl_old_des_random_key(_ossl_old_des_cblock ret); +int _ossl_old_des_read_password(_ossl_old_des_cblock *key, const char *prompt, + int verify); +int _ossl_old_des_read_2passwords(_ossl_old_des_cblock *key1, + _ossl_old_des_cblock *key2, + const char *prompt, int verify); +void _ossl_old_des_set_odd_parity(_ossl_old_des_cblock *key); +int _ossl_old_des_is_weak_key(_ossl_old_des_cblock *key); +int _ossl_old_des_set_key(_ossl_old_des_cblock *key, + _ossl_old_des_key_schedule schedule); +int _ossl_old_des_key_sched(_ossl_old_des_cblock *key, + _ossl_old_des_key_schedule schedule); +void _ossl_old_des_string_to_key(char *str, _ossl_old_des_cblock *key); +void _ossl_old_des_string_to_2keys(char *str, _ossl_old_des_cblock *key1, + _ossl_old_des_cblock *key2); +void _ossl_old_des_cfb64_encrypt(unsigned char *in, unsigned char *out, + long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int *num, + int enc); +void _ossl_old_des_ofb64_encrypt(unsigned char *in, unsigned char *out, + long length, + _ossl_old_des_key_schedule schedule, + _ossl_old_des_cblock *ivec, int *num); + +void _ossl_096_des_random_seed(des_cblock *key); + +/* + * The following definitions provide compatibility with the MIT Kerberos + * library. The _ossl_old_des_key_schedule structure is not binary + * compatible. + */ + +# define _KERBEROS_DES_H + +# define KRBDES_ENCRYPT DES_ENCRYPT +# define KRBDES_DECRYPT DES_DECRYPT + +# ifdef KERBEROS +# define ENCRYPT DES_ENCRYPT +# define DECRYPT DES_DECRYPT +# endif + +# ifndef NCOMPAT +# define C_Block des_cblock +# define Key_schedule des_key_schedule +# define KEY_SZ DES_KEY_SZ +# define string_to_key des_string_to_key +# define read_pw_string des_read_pw_string +# define random_key des_random_key +# define pcbc_encrypt des_pcbc_encrypt +# define set_key des_set_key +# define key_sched des_key_sched +# define ecb_encrypt des_ecb_encrypt +# define cbc_encrypt des_cbc_encrypt +# define ncbc_encrypt des_ncbc_encrypt +# define xcbc_encrypt des_xcbc_encrypt +# define cbc_cksum des_cbc_cksum +# define quad_cksum des_quad_cksum +# define check_parity des_check_key_parity +# endif + +# define des_fixup_key_parity DES_fixup_key_parity + +#ifdef __cplusplus +} +#endif + +/* for DES_read_pw_string et al */ +# include + +#endif diff --git a/libs/openssl/crypto/des/des_old2.c b/libs/openssl/crypto/des/des_old2.c new file mode 100644 index 00000000..247ff8dc --- /dev/null +++ b/libs/openssl/crypto/des/des_old2.c @@ -0,0 +1,80 @@ +/* crypto/des/des_old.c */ + +/* + * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING The + * function names in here are deprecated and are only present to provide an + * interface compatible with OpenSSL 0.9.6c. OpenSSL now provides functions + * where "des_" has been replaced with "DES_" in the names, to make it + * possible to make incompatible changes that are needed for C type security + * and other stuff. Please consider starting to use the DES_ functions + * rather than the des_ ones. The des_ functions will dissapear completely + * before OpenSSL 1.0! WARNING WARNING WARNING WARNING WARNING WARNING + * WARNING WARNING + */ + +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#undef OPENSSL_DES_LIBDES_COMPATIBILITY +#include +#include + +void _ossl_096_des_random_seed(DES_cblock *key) +{ + RAND_seed(key, sizeof(DES_cblock)); +} diff --git a/libs/openssl/crypto/des/des_opts.c b/libs/openssl/crypto/des/des_opts.c new file mode 100644 index 00000000..ec50e94f --- /dev/null +++ b/libs/openssl/crypto/des/des_opts.c @@ -0,0 +1,641 @@ +/* crypto/des/des_opts.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * define PART1, PART2, PART3 or PART4 to build only with a few of the + * options. This is for machines with 64k code segment size restrictions. + */ + +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX) +# define TIMES +#endif + +#include +#ifndef OPENSSL_SYS_MSDOS +# include +# include OPENSSL_UNISTD +#else +# include +extern void exit(); +#endif + +#ifndef OPENSSL_SYS_NETWARE +# include +#endif + +#ifndef _IRIX +# include +#endif +#ifdef TIMES +# include +# include +#endif + +/* + * Depending on the VMS version, the tms structure is perhaps defined. The + * __TMS macro will show if it was. If it wasn't defined, we should undefine + * TIMES, since that tells the rest of the program how things should be + * handled. -- Richard Levitte + */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) +# undef TIMES +#endif + +#ifndef TIMES +# include +#endif + +#if defined(sun) || defined(__ultrix) +# define _POSIX_SOURCE +# include +# include +#endif + +#include +#include "spr.h" + +#define DES_DEFAULT_OPTIONS + +#if !defined(PART1) && !defined(PART2) && !defined(PART3) && !defined(PART4) +# define PART1 +# define PART2 +# define PART3 +# define PART4 +#endif + +#ifdef PART1 + +# undef DES_UNROLL +# undef DES_RISC1 +# undef DES_RISC2 +# undef DES_PTR +# undef D_ENCRYPT +# define DES_encrypt1 des_encrypt_u4_cisc_idx +# define DES_encrypt2 des_encrypt2_u4_cisc_idx +# define DES_encrypt3 des_encrypt3_u4_cisc_idx +# define DES_decrypt3 des_decrypt3_u4_cisc_idx +# undef HEADER_DES_LOCL_H +# include "des_enc.c" + +# define DES_UNROLL +# undef DES_RISC1 +# undef DES_RISC2 +# undef DES_PTR +# undef D_ENCRYPT +# undef DES_encrypt1 +# undef DES_encrypt2 +# undef DES_encrypt3 +# undef DES_decrypt3 +# define DES_encrypt1 des_encrypt_u16_cisc_idx +# define DES_encrypt2 des_encrypt2_u16_cisc_idx +# define DES_encrypt3 des_encrypt3_u16_cisc_idx +# define DES_decrypt3 des_decrypt3_u16_cisc_idx +# undef HEADER_DES_LOCL_H +# include "des_enc.c" + +# undef DES_UNROLL +# define DES_RISC1 +# undef DES_RISC2 +# undef DES_PTR +# undef D_ENCRYPT +# undef DES_encrypt1 +# undef DES_encrypt2 +# undef DES_encrypt3 +# undef DES_decrypt3 +# define DES_encrypt1 des_encrypt_u4_risc1_idx +# define DES_encrypt2 des_encrypt2_u4_risc1_idx +# define DES_encrypt3 des_encrypt3_u4_risc1_idx +# define DES_decrypt3 des_decrypt3_u4_risc1_idx +# undef HEADER_DES_LOCL_H +# include "des_enc.c" + +#endif + +#ifdef PART2 + +# undef DES_UNROLL +# undef DES_RISC1 +# define DES_RISC2 +# undef DES_PTR +# undef D_ENCRYPT +# undef DES_encrypt1 +# undef DES_encrypt2 +# undef DES_encrypt3 +# undef DES_decrypt3 +# define DES_encrypt1 des_encrypt_u4_risc2_idx +# define DES_encrypt2 des_encrypt2_u4_risc2_idx +# define DES_encrypt3 des_encrypt3_u4_risc2_idx +# define DES_decrypt3 des_decrypt3_u4_risc2_idx +# undef HEADER_DES_LOCL_H +# include "des_enc.c" + +# define DES_UNROLL +# define DES_RISC1 +# undef DES_RISC2 +# undef DES_PTR +# undef D_ENCRYPT +# undef DES_encrypt1 +# undef DES_encrypt2 +# undef DES_encrypt3 +# undef DES_decrypt3 +# define DES_encrypt1 des_encrypt_u16_risc1_idx +# define DES_encrypt2 des_encrypt2_u16_risc1_idx +# define DES_encrypt3 des_encrypt3_u16_risc1_idx +# define DES_decrypt3 des_decrypt3_u16_risc1_idx +# undef HEADER_DES_LOCL_H +# include "des_enc.c" + +# define DES_UNROLL +# undef DES_RISC1 +# define DES_RISC2 +# undef DES_PTR +# undef D_ENCRYPT +# undef DES_encrypt1 +# undef DES_encrypt2 +# undef DES_encrypt3 +# undef DES_decrypt3 +# define DES_encrypt1 des_encrypt_u16_risc2_idx +# define DES_encrypt2 des_encrypt2_u16_risc2_idx +# define DES_encrypt3 des_encrypt3_u16_risc2_idx +# define DES_decrypt3 des_decrypt3_u16_risc2_idx +# undef HEADER_DES_LOCL_H +# include "des_enc.c" + +#endif + +#ifdef PART3 + +# undef DES_UNROLL +# undef DES_RISC1 +# undef DES_RISC2 +# define DES_PTR +# undef D_ENCRYPT +# undef DES_encrypt1 +# undef DES_encrypt2 +# undef DES_encrypt3 +# undef DES_decrypt3 +# define DES_encrypt1 des_encrypt_u4_cisc_ptr +# define DES_encrypt2 des_encrypt2_u4_cisc_ptr +# define DES_encrypt3 des_encrypt3_u4_cisc_ptr +# define DES_decrypt3 des_decrypt3_u4_cisc_ptr +# undef HEADER_DES_LOCL_H +# include "des_enc.c" + +# define DES_UNROLL +# undef DES_RISC1 +# undef DES_RISC2 +# define DES_PTR +# undef D_ENCRYPT +# undef DES_encrypt1 +# undef DES_encrypt2 +# undef DES_encrypt3 +# undef DES_decrypt3 +# define DES_encrypt1 des_encrypt_u16_cisc_ptr +# define DES_encrypt2 des_encrypt2_u16_cisc_ptr +# define DES_encrypt3 des_encrypt3_u16_cisc_ptr +# define DES_decrypt3 des_decrypt3_u16_cisc_ptr +# undef HEADER_DES_LOCL_H +# include "des_enc.c" + +# undef DES_UNROLL +# define DES_RISC1 +# undef DES_RISC2 +# define DES_PTR +# undef D_ENCRYPT +# undef DES_encrypt1 +# undef DES_encrypt2 +# undef DES_encrypt3 +# undef DES_decrypt3 +# define DES_encrypt1 des_encrypt_u4_risc1_ptr +# define DES_encrypt2 des_encrypt2_u4_risc1_ptr +# define DES_encrypt3 des_encrypt3_u4_risc1_ptr +# define DES_decrypt3 des_decrypt3_u4_risc1_ptr +# undef HEADER_DES_LOCL_H +# include "des_enc.c" + +#endif + +#ifdef PART4 + +# undef DES_UNROLL +# undef DES_RISC1 +# define DES_RISC2 +# define DES_PTR +# undef D_ENCRYPT +# undef DES_encrypt1 +# undef DES_encrypt2 +# undef DES_encrypt3 +# undef DES_decrypt3 +# define DES_encrypt1 des_encrypt_u4_risc2_ptr +# define DES_encrypt2 des_encrypt2_u4_risc2_ptr +# define DES_encrypt3 des_encrypt3_u4_risc2_ptr +# define DES_decrypt3 des_decrypt3_u4_risc2_ptr +# undef HEADER_DES_LOCL_H +# include "des_enc.c" + +# define DES_UNROLL +# define DES_RISC1 +# undef DES_RISC2 +# define DES_PTR +# undef D_ENCRYPT +# undef DES_encrypt1 +# undef DES_encrypt2 +# undef DES_encrypt3 +# undef DES_decrypt3 +# define DES_encrypt1 des_encrypt_u16_risc1_ptr +# define DES_encrypt2 des_encrypt2_u16_risc1_ptr +# define DES_encrypt3 des_encrypt3_u16_risc1_ptr +# define DES_decrypt3 des_decrypt3_u16_risc1_ptr +# undef HEADER_DES_LOCL_H +# include "des_enc.c" + +# define DES_UNROLL +# undef DES_RISC1 +# define DES_RISC2 +# define DES_PTR +# undef D_ENCRYPT +# undef DES_encrypt1 +# undef DES_encrypt2 +# undef DES_encrypt3 +# undef DES_decrypt3 +# define DES_encrypt1 des_encrypt_u16_risc2_ptr +# define DES_encrypt2 des_encrypt2_u16_risc2_ptr +# define DES_encrypt3 des_encrypt3_u16_risc2_ptr +# define DES_decrypt3 des_decrypt3_u16_risc2_ptr +# undef HEADER_DES_LOCL_H +# include "des_enc.c" + +#endif + +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */ +# define HZ 100.0 +# else /* _BSD_CLK_TCK_ */ +# define HZ ((double)_BSD_CLK_TCK_) +# endif +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +#endif + +#define BUFSIZE ((long)1024) +long run = 0; + +double Time_F(int s); +#ifdef SIGALRM +# if defined(__STDC__) || defined(sgi) +# define SIGRETTYPE void +# else +# define SIGRETTYPE int +# endif + +SIGRETTYPE sig_done(int sig); +SIGRETTYPE sig_done(int sig) +{ + signal(SIGALRM, sig_done); + run = 0; +# ifdef LINT + sig = sig; +# endif +} +#endif + +#define START 0 +#define STOP 1 + +double Time_F(int s) +{ + double ret; +#ifdef TIMES + static struct tms tstart, tend; + + if (s == START) { + times(&tstart); + return (0); + } else { + times(&tend); + ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ; + return ((ret == 0.0) ? 1e-6 : ret); + } +#else /* !times() */ + static struct timeb tstart, tend; + long i; + + if (s == START) { + ftime(&tstart); + return (0); + } else { + ftime(&tend); + i = (long)tend.millitm - (long)tstart.millitm; + ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1000.0; + return ((ret == 0.0) ? 1e-6 : ret); + } +#endif +} + +#ifdef SIGALRM +# define print_name(name) fprintf(stderr,"Doing %s's for 10 seconds\n",name); alarm(10); +#else +# define print_name(name) fprintf(stderr,"Doing %s %ld times\n",name,cb); +#endif + +#define time_it(func,name,index) \ + print_name(name); \ + Time_F(START); \ + for (count=0,run=1; COND(cb); count++) \ + { \ + unsigned long d[2]; \ + func(d,&sch,DES_ENCRYPT); \ + } \ + tm[index]=Time_F(STOP); \ + fprintf(stderr,"%ld %s's in %.2f second\n",count,name,tm[index]); \ + tm[index]=((double)COUNT(cb))/tm[index]; + +#define print_it(name,index) \ + fprintf(stderr,"%s bytes per sec = %12.2f (%5.1fuS)\n",name, \ + tm[index]*8,1.0e6/tm[index]); + +int main(int argc, char **argv) +{ + long count; + static unsigned char buf[BUFSIZE]; + static DES_cblock key = + { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 }; + static DES_cblock key2 = + { 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12 }; + static DES_cblock key3 = + { 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 }; + DES_key_schedule sch, sch2, sch3; + double d, tm[16], max = 0; + int rank[16]; + char *str[16]; + int max_idx = 0, i, num = 0, j; +#ifndef SIGALARM + long ca, cb, cc, cd, ce; +#endif + + for (i = 0; i < 12; i++) { + tm[i] = 0.0; + rank[i] = 0; + } + +#ifndef TIMES + fprintf(stderr, "To get the most accurate results, try to run this\n"); + fprintf(stderr, "program when this computer is idle.\n"); +#endif + + DES_set_key_unchecked(&key, &sch); + DES_set_key_unchecked(&key2, &sch2); + DES_set_key_unchecked(&key3, &sch3); + +#ifndef SIGALRM + fprintf(stderr, "First we calculate the approximate speed ...\n"); + DES_set_key_unchecked(&key, sch); + count = 10; + do { + long i; + unsigned long data[2]; + + count *= 2; + Time_F(START); + for (i = count; i; i--) + DES_encrypt1(data, &(sch[0]), DES_ENCRYPT); + d = Time_F(STOP); + } while (d < 3.0); + ca = count; + cb = count * 3; + cc = count * 3 * 8 / BUFSIZE + 1; + cd = count * 8 / BUFSIZE + 1; + + ce = count / 20 + 1; +# define COND(d) (count != (d)) +# define COUNT(d) (d) +#else +# define COND(c) (run) +# define COUNT(d) (count) + signal(SIGALRM, sig_done); + alarm(10); +#endif + +#ifdef PART1 + time_it(des_encrypt_u4_cisc_idx, "des_encrypt_u4_cisc_idx ", 0); + time_it(des_encrypt_u16_cisc_idx, "des_encrypt_u16_cisc_idx ", 1); + time_it(des_encrypt_u4_risc1_idx, "des_encrypt_u4_risc1_idx ", 2); + num += 3; +#endif +#ifdef PART2 + time_it(des_encrypt_u16_risc1_idx, "des_encrypt_u16_risc1_idx", 3); + time_it(des_encrypt_u4_risc2_idx, "des_encrypt_u4_risc2_idx ", 4); + time_it(des_encrypt_u16_risc2_idx, "des_encrypt_u16_risc2_idx", 5); + num += 3; +#endif +#ifdef PART3 + time_it(des_encrypt_u4_cisc_ptr, "des_encrypt_u4_cisc_ptr ", 6); + time_it(des_encrypt_u16_cisc_ptr, "des_encrypt_u16_cisc_ptr ", 7); + time_it(des_encrypt_u4_risc1_ptr, "des_encrypt_u4_risc1_ptr ", 8); + num += 3; +#endif +#ifdef PART4 + time_it(des_encrypt_u16_risc1_ptr, "des_encrypt_u16_risc1_ptr", 9); + time_it(des_encrypt_u4_risc2_ptr, "des_encrypt_u4_risc2_ptr ", 10); + time_it(des_encrypt_u16_risc2_ptr, "des_encrypt_u16_risc2_ptr", 11); + num += 3; +#endif + +#ifdef PART1 + str[0] = " 4 c i"; + print_it("des_encrypt_u4_cisc_idx ", 0); + max = tm[0]; + max_idx = 0; + str[1] = "16 c i"; + print_it("des_encrypt_u16_cisc_idx ", 1); + if (max < tm[1]) { + max = tm[1]; + max_idx = 1; + } + str[2] = " 4 r1 i"; + print_it("des_encrypt_u4_risc1_idx ", 2); + if (max < tm[2]) { + max = tm[2]; + max_idx = 2; + } +#endif +#ifdef PART2 + str[3] = "16 r1 i"; + print_it("des_encrypt_u16_risc1_idx", 3); + if (max < tm[3]) { + max = tm[3]; + max_idx = 3; + } + str[4] = " 4 r2 i"; + print_it("des_encrypt_u4_risc2_idx ", 4); + if (max < tm[4]) { + max = tm[4]; + max_idx = 4; + } + str[5] = "16 r2 i"; + print_it("des_encrypt_u16_risc2_idx", 5); + if (max < tm[5]) { + max = tm[5]; + max_idx = 5; + } +#endif +#ifdef PART3 + str[6] = " 4 c p"; + print_it("des_encrypt_u4_cisc_ptr ", 6); + if (max < tm[6]) { + max = tm[6]; + max_idx = 6; + } + str[7] = "16 c p"; + print_it("des_encrypt_u16_cisc_ptr ", 7); + if (max < tm[7]) { + max = tm[7]; + max_idx = 7; + } + str[8] = " 4 r1 p"; + print_it("des_encrypt_u4_risc1_ptr ", 8); + if (max < tm[8]) { + max = tm[8]; + max_idx = 8; + } +#endif +#ifdef PART4 + str[9] = "16 r1 p"; + print_it("des_encrypt_u16_risc1_ptr", 9); + if (max < tm[9]) { + max = tm[9]; + max_idx = 9; + } + str[10] = " 4 r2 p"; + print_it("des_encrypt_u4_risc2_ptr ", 10); + if (max < tm[10]) { + max = tm[10]; + max_idx = 10; + } + str[11] = "16 r2 p"; + print_it("des_encrypt_u16_risc2_ptr", 11); + if (max < tm[11]) { + max = tm[11]; + max_idx = 11; + } +#endif + printf("options des ecb/s\n"); + printf("%s %12.2f 100.0%%\n", str[max_idx], tm[max_idx]); + d = tm[max_idx]; + tm[max_idx] = -2.0; + max = -1.0; + for (;;) { + for (i = 0; i < 12; i++) { + if (max < tm[i]) { + max = tm[i]; + j = i; + } + } + if (max < 0.0) + break; + printf("%s %12.2f %4.1f%%\n", str[j], tm[j], tm[j] / d * 100.0); + tm[j] = -2.0; + max = -1.0; + } + + switch (max_idx) { + case 0: + printf("-DDES_DEFAULT_OPTIONS\n"); + break; + case 1: + printf("-DDES_UNROLL\n"); + break; + case 2: + printf("-DDES_RISC1\n"); + break; + case 3: + printf("-DDES_UNROLL -DDES_RISC1\n"); + break; + case 4: + printf("-DDES_RISC2\n"); + break; + case 5: + printf("-DDES_UNROLL -DDES_RISC2\n"); + break; + case 6: + printf("-DDES_PTR\n"); + break; + case 7: + printf("-DDES_UNROLL -DDES_PTR\n"); + break; + case 8: + printf("-DDES_RISC1 -DDES_PTR\n"); + break; + case 9: + printf("-DDES_UNROLL -DDES_RISC1 -DDES_PTR\n"); + break; + case 10: + printf("-DDES_RISC2 -DDES_PTR\n"); + break; + case 11: + printf("-DDES_UNROLL -DDES_RISC2 -DDES_PTR\n"); + break; + } + exit(0); +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS) + return (0); +#endif +} diff --git a/libs/openssl/crypto/des/des_ver.h b/libs/openssl/crypto/des/des_ver.h new file mode 100644 index 00000000..276de2b6 --- /dev/null +++ b/libs/openssl/crypto/des/des_ver.h @@ -0,0 +1,73 @@ +/* crypto/des/des_ver.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#ifdef OPENSSL_BUILD_SHLIBCRYPTO +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +#endif + +/* The following macros make sure the names are different from libdes names */ +#define DES_version OSSL_DES_version +#define libdes_version OSSL_libdes_version + +/* SSLeay version string */ +OPENSSL_EXTERN const char OSSL_DES_version[]; +/* old libdes version string */ +OPENSSL_EXTERN const char OSSL_libdes_version[]; diff --git a/libs/openssl/crypto/des/dess.cpp b/libs/openssl/crypto/des/dess.cpp new file mode 100644 index 00000000..5549bab9 --- /dev/null +++ b/libs/openssl/crypto/des/dess.cpp @@ -0,0 +1,67 @@ +// +// gettsc.inl +// +// gives access to the Pentium's (secret) cycle counter +// +// This software was written by Leonard Janke (janke@unixg.ubc.ca) +// in 1996-7 and is entered, by him, into the public domain. + +#if defined(__WATCOMC__) +void GetTSC(unsigned long&); +#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax]; +#elif defined(__GNUC__) +inline +void GetTSC(unsigned long& tsc) +{ + asm volatile(".byte 15, 49\n\t" + : "=eax" (tsc) + : + : "%edx", "%eax"); +} +#elif defined(_MSC_VER) +inline +void GetTSC(unsigned long& tsc) +{ + unsigned long a; + __asm _emit 0fh + __asm _emit 31h + __asm mov a, eax; + tsc=a; +} +#endif + +#include +#include +#include + +void main(int argc,char *argv[]) + { + des_key_schedule key; + unsigned long s1,s2,e1,e2; + unsigned long data[2]; + int i,j; + + for (j=0; j<6; j++) + { + for (i=0; i<1000; i++) /**/ + { + des_encrypt1(&data[0],key,1); + GetTSC(s1); + des_encrypt1(&data[0],key,1); + des_encrypt1(&data[0],key,1); + des_encrypt1(&data[0],key,1); + GetTSC(e1); + GetTSC(s2); + des_encrypt1(&data[0],key,1); + des_encrypt1(&data[0],key,1); + des_encrypt1(&data[0],key,1); + des_encrypt1(&data[0],key,1); + GetTSC(e2); + des_encrypt1(&data[0],key,1); + } + + printf("des %d %d (%d)\n", + e1-s1,e2-s2,((e2-s2)-(e1-s1))); + } + } + diff --git a/libs/openssl/crypto/des/destest.c b/libs/openssl/crypto/des/destest.c new file mode 100644 index 00000000..c6be3420 --- /dev/null +++ b/libs/openssl/crypto/des/destest.c @@ -0,0 +1,929 @@ +/* crypto/des/destest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16) || defined(OPENSSL_SYS_WINDOWS) +# ifndef OPENSSL_SYS_MSDOS +# define OPENSSL_SYS_MSDOS +# endif +#endif + +#ifndef OPENSSL_SYS_MSDOS +# if !defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_VMS_DECC) +# include OPENSSL_UNISTD +# endif +#else +# include +#endif +#include + +#ifdef OPENSSL_NO_DES +int main(int argc, char *argv[]) +{ + printf("No DES support\n"); + return (0); +} +#else +# include + +# define crypt(c,s) (DES_crypt((c),(s))) + +/* tisk tisk - the test keys don't all have odd parity :-( */ +/* test data */ +# define NUM_TESTS 34 +static unsigned char key_data[NUM_TESTS][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10}, + {0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57}, + {0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E}, + {0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86}, + {0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E}, + {0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6}, + {0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE}, + {0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6}, + {0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE}, + {0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16}, + {0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F}, + {0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46}, + {0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E}, + {0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76}, + {0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07}, + {0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F}, + {0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7}, + {0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF}, + {0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6}, + {0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF}, + {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E}, + {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10} +}; + +static unsigned char plain_data[NUM_TESTS][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42}, + {0x5C, 0xD5, 0x4C, 0xA8, 0x3D, 0xEF, 0x57, 0xDA}, + {0x02, 0x48, 0xD4, 0x38, 0x06, 0xF6, 0x71, 0x72}, + {0x51, 0x45, 0x4B, 0x58, 0x2D, 0xDF, 0x44, 0x0A}, + {0x42, 0xFD, 0x44, 0x30, 0x59, 0x57, 0x7F, 0xA2}, + {0x05, 0x9B, 0x5E, 0x08, 0x51, 0xCF, 0x14, 0x3A}, + {0x07, 0x56, 0xD8, 0xE0, 0x77, 0x47, 0x61, 0xD2}, + {0x76, 0x25, 0x14, 0xB8, 0x29, 0xBF, 0x48, 0x6A}, + {0x3B, 0xDD, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02}, + {0x26, 0x95, 0x5F, 0x68, 0x35, 0xAF, 0x60, 0x9A}, + {0x16, 0x4D, 0x5E, 0x40, 0x4F, 0x27, 0x52, 0x32}, + {0x6B, 0x05, 0x6E, 0x18, 0x75, 0x9F, 0x5C, 0xCA}, + {0x00, 0x4B, 0xD6, 0xEF, 0x09, 0x17, 0x60, 0x62}, + {0x48, 0x0D, 0x39, 0x00, 0x6E, 0xE7, 0x62, 0xF2}, + {0x43, 0x75, 0x40, 0xC8, 0x69, 0x8F, 0x3C, 0xFA}, + {0x07, 0x2D, 0x43, 0xA0, 0x77, 0x07, 0x52, 0x92}, + {0x02, 0xFE, 0x55, 0x77, 0x81, 0x17, 0xF1, 0x2A}, + {0x1D, 0x9D, 0x5C, 0x50, 0x18, 0xF7, 0x28, 0xC2}, + {0x30, 0x55, 0x32, 0x28, 0x6D, 0x6F, 0x29, 0x5A}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} +}; + +static unsigned char cipher_data[NUM_TESTS][8] = { + {0x8C, 0xA6, 0x4D, 0xE9, 0xC1, 0xB1, 0x23, 0xA7}, + {0x73, 0x59, 0xB2, 0x16, 0x3E, 0x4E, 0xDC, 0x58}, + {0x95, 0x8E, 0x6E, 0x62, 0x7A, 0x05, 0x55, 0x7B}, + {0xF4, 0x03, 0x79, 0xAB, 0x9E, 0x0E, 0xC5, 0x33}, + {0x17, 0x66, 0x8D, 0xFC, 0x72, 0x92, 0x53, 0x2D}, + {0x8A, 0x5A, 0xE1, 0xF8, 0x1A, 0xB8, 0xF2, 0xDD}, + {0x8C, 0xA6, 0x4D, 0xE9, 0xC1, 0xB1, 0x23, 0xA7}, + {0xED, 0x39, 0xD9, 0x50, 0xFA, 0x74, 0xBC, 0xC4}, + {0x69, 0x0F, 0x5B, 0x0D, 0x9A, 0x26, 0x93, 0x9B}, + {0x7A, 0x38, 0x9D, 0x10, 0x35, 0x4B, 0xD2, 0x71}, + {0x86, 0x8E, 0xBB, 0x51, 0xCA, 0xB4, 0x59, 0x9A}, + {0x71, 0x78, 0x87, 0x6E, 0x01, 0xF1, 0x9B, 0x2A}, + {0xAF, 0x37, 0xFB, 0x42, 0x1F, 0x8C, 0x40, 0x95}, + {0x86, 0xA5, 0x60, 0xF1, 0x0E, 0xC6, 0xD8, 0x5B}, + {0x0C, 0xD3, 0xDA, 0x02, 0x00, 0x21, 0xDC, 0x09}, + {0xEA, 0x67, 0x6B, 0x2C, 0xB7, 0xDB, 0x2B, 0x7A}, + {0xDF, 0xD6, 0x4A, 0x81, 0x5C, 0xAF, 0x1A, 0x0F}, + {0x5C, 0x51, 0x3C, 0x9C, 0x48, 0x86, 0xC0, 0x88}, + {0x0A, 0x2A, 0xEE, 0xAE, 0x3F, 0xF4, 0xAB, 0x77}, + {0xEF, 0x1B, 0xF0, 0x3E, 0x5D, 0xFA, 0x57, 0x5A}, + {0x88, 0xBF, 0x0D, 0xB6, 0xD7, 0x0D, 0xEE, 0x56}, + {0xA1, 0xF9, 0x91, 0x55, 0x41, 0x02, 0x0B, 0x56}, + {0x6F, 0xBF, 0x1C, 0xAF, 0xCF, 0xFD, 0x05, 0x56}, + {0x2F, 0x22, 0xE4, 0x9B, 0xAB, 0x7C, 0xA1, 0xAC}, + {0x5A, 0x6B, 0x61, 0x2C, 0xC2, 0x6C, 0xCE, 0x4A}, + {0x5F, 0x4C, 0x03, 0x8E, 0xD1, 0x2B, 0x2E, 0x41}, + {0x63, 0xFA, 0xC0, 0xD0, 0x34, 0xD9, 0xF7, 0x93}, + {0x61, 0x7B, 0x3A, 0x0C, 0xE8, 0xF0, 0x71, 0x00}, + {0xDB, 0x95, 0x86, 0x05, 0xF8, 0xC8, 0xC6, 0x06}, + {0xED, 0xBF, 0xD1, 0xC6, 0x6C, 0x29, 0xCC, 0xC7}, + {0x35, 0x55, 0x50, 0xB2, 0x15, 0x0E, 0x24, 0x51}, + {0xCA, 0xAA, 0xAF, 0x4D, 0xEA, 0xF1, 0xDB, 0xAE}, + {0xD5, 0xD4, 0x4F, 0xF7, 0x20, 0x68, 0x3D, 0x0D}, + {0x2A, 0x2B, 0xB0, 0x08, 0xDF, 0x97, 0xC2, 0xF2} +}; + +static unsigned char cipher_ecb2[NUM_TESTS - 1][8] = { + {0x92, 0x95, 0xB5, 0x9B, 0xB3, 0x84, 0x73, 0x6E}, + {0x19, 0x9E, 0x9D, 0x6D, 0xF3, 0x9A, 0xA8, 0x16}, + {0x2A, 0x4B, 0x4D, 0x24, 0x52, 0x43, 0x84, 0x27}, + {0x35, 0x84, 0x3C, 0x01, 0x9D, 0x18, 0xC5, 0xB6}, + {0x4A, 0x5B, 0x2F, 0x42, 0xAA, 0x77, 0x19, 0x25}, + {0xA0, 0x6B, 0xA9, 0xB8, 0xCA, 0x5B, 0x17, 0x8A}, + {0xAB, 0x9D, 0xB7, 0xFB, 0xED, 0x95, 0xF2, 0x74}, + {0x3D, 0x25, 0x6C, 0x23, 0xA7, 0x25, 0x2F, 0xD6}, + {0xB7, 0x6F, 0xAB, 0x4F, 0xBD, 0xBD, 0xB7, 0x67}, + {0x8F, 0x68, 0x27, 0xD6, 0x9C, 0xF4, 0x1A, 0x10}, + {0x82, 0x57, 0xA1, 0xD6, 0x50, 0x5E, 0x81, 0x85}, + {0xA2, 0x0F, 0x0A, 0xCD, 0x80, 0x89, 0x7D, 0xFA}, + {0xCD, 0x2A, 0x53, 0x3A, 0xDB, 0x0D, 0x7E, 0xF3}, + {0xD2, 0xC2, 0xBE, 0x27, 0xE8, 0x1B, 0x68, 0xE3}, + {0xE9, 0x24, 0xCF, 0x4F, 0x89, 0x3C, 0x5B, 0x0A}, + {0xA7, 0x18, 0xC3, 0x9F, 0xFA, 0x9F, 0xD7, 0x69}, + {0x77, 0x2C, 0x79, 0xB1, 0xD2, 0x31, 0x7E, 0xB1}, + {0x49, 0xAB, 0x92, 0x7F, 0xD0, 0x22, 0x00, 0xB7}, + {0xCE, 0x1C, 0x6C, 0x7D, 0x85, 0xE3, 0x4A, 0x6F}, + {0xBE, 0x91, 0xD6, 0xE1, 0x27, 0xB2, 0xE9, 0x87}, + {0x70, 0x28, 0xAE, 0x8F, 0xD1, 0xF5, 0x74, 0x1A}, + {0xAA, 0x37, 0x80, 0xBB, 0xF3, 0x22, 0x1D, 0xDE}, + {0xA6, 0xC4, 0xD2, 0x5E, 0x28, 0x93, 0xAC, 0xB3}, + {0x22, 0x07, 0x81, 0x5A, 0xE4, 0xB7, 0x1A, 0xAD}, + {0xDC, 0xCE, 0x05, 0xE7, 0x07, 0xBD, 0xF5, 0x84}, + {0x26, 0x1D, 0x39, 0x2C, 0xB3, 0xBA, 0xA5, 0x85}, + {0xB4, 0xF7, 0x0F, 0x72, 0xFB, 0x04, 0xF0, 0xDC}, + {0x95, 0xBA, 0xA9, 0x4E, 0x87, 0x36, 0xF2, 0x89}, + {0xD4, 0x07, 0x3A, 0xF1, 0x5A, 0x17, 0x82, 0x0E}, + {0xEF, 0x6F, 0xAF, 0xA7, 0x66, 0x1A, 0x7E, 0x89}, + {0xC1, 0x97, 0xF5, 0x58, 0x74, 0x8A, 0x20, 0xE7}, + {0x43, 0x34, 0xCF, 0xDA, 0x22, 0xC4, 0x86, 0xC8}, + {0x08, 0xD7, 0xB4, 0xFB, 0x62, 0x9D, 0x08, 0x85} +}; + +static unsigned char cbc_key[8] = + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; +static unsigned char cbc2_key[8] = + { 0xf1, 0xe0, 0xd3, 0xc2, 0xb5, 0xa4, 0x97, 0x86 }; +static unsigned char cbc3_key[8] = + { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }; +static unsigned char cbc_iv[8] = + { 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10 }; +/* + * Changed the following text constant to binary so it will work on ebcdic + * machines :-) + */ +/* static char cbc_data[40]="7654321 Now is the time for \0001"; */ +static unsigned char cbc_data[40] = { + 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20, + 0x4E, 0x6F, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74, + 0x68, 0x65, 0x20, 0x74, 0x69, 0x6D, 0x65, 0x20, + 0x66, 0x6F, 0x72, 0x20, 0x00, 0x31, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +static unsigned char cbc_ok[32] = { + 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, + 0xac, 0xd8, 0xae, 0xfd, 0xdf, 0xd8, 0xa1, 0xeb, + 0x46, 0x8e, 0x91, 0x15, 0x78, 0x88, 0xba, 0x68, + 0x1d, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4 +}; + +# ifdef SCREW_THE_PARITY +# error "SCREW_THE_PARITY is not ment to be defined." +# error "Original vectors are preserved for reference only." +static unsigned char cbc2_key[8] = + { 0xf0, 0xe1, 0xd2, 0xc3, 0xb4, 0xa5, 0x96, 0x87 }; +static unsigned char xcbc_ok[32] = { + 0x86, 0x74, 0x81, 0x0D, 0x61, 0xA4, 0xA5, 0x48, + 0xB9, 0x93, 0x03, 0xE1, 0xB8, 0xBB, 0xBD, 0xBD, + 0x64, 0x30, 0x0B, 0xB9, 0x06, 0x65, 0x81, 0x76, + 0x04, 0x1D, 0x77, 0x62, 0x17, 0xCA, 0x2B, 0xD2, +}; +# else +static unsigned char xcbc_ok[32] = { + 0x84, 0x6B, 0x29, 0x14, 0x85, 0x1E, 0x9A, 0x29, + 0x54, 0x73, 0x2F, 0x8A, 0xA0, 0xA6, 0x11, 0xC1, + 0x15, 0xCD, 0xC2, 0xD7, 0x95, 0x1B, 0x10, 0x53, + 0xA6, 0x3C, 0x5E, 0x03, 0xB2, 0x1A, 0xA3, 0xC4, +}; +# endif + +static unsigned char cbc3_ok[32] = { + 0x3F, 0xE3, 0x01, 0xC9, 0x62, 0xAC, 0x01, 0xD0, + 0x22, 0x13, 0x76, 0x3C, 0x1C, 0xBD, 0x4C, 0xDC, + 0x79, 0x96, 0x57, 0xC0, 0x64, 0xEC, 0xF5, 0xD4, + 0x1C, 0x67, 0x38, 0x12, 0xCF, 0xDE, 0x96, 0x75 +}; + +static unsigned char pcbc_ok[32] = { + 0xcc, 0xd1, 0x73, 0xff, 0xab, 0x20, 0x39, 0xf4, + 0x6d, 0xec, 0xb4, 0x70, 0xa0, 0xe5, 0x6b, 0x15, + 0xae, 0xa6, 0xbf, 0x61, 0xed, 0x7d, 0x9c, 0x9f, + 0xf7, 0x17, 0x46, 0x3b, 0x8a, 0xb3, 0xcc, 0x88 +}; + +static unsigned char cfb_key[8] = + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; +static unsigned char cfb_iv[8] = + { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef }; +static unsigned char cfb_buf1[40], cfb_buf2[40], cfb_tmp[8]; +static unsigned char plain[24] = { + 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, + 0x69, 0x6d, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 +}; + +static unsigned char cfb_cipher8[24] = { + 0xf3, 0x1f, 0xda, 0x07, 0x01, 0x14, 0x62, 0xee, 0x18, 0x7f, 0x43, 0xd8, + 0x0a, 0x7c, 0xd9, 0xb5, 0xb0, 0xd2, 0x90, 0xda, 0x6e, 0x5b, 0x9a, 0x87 +}; + +static unsigned char cfb_cipher16[24] = { + 0xF3, 0x09, 0x87, 0x87, 0x7F, 0x57, 0xF7, 0x3C, 0x36, 0xB6, 0xDB, 0x70, + 0xD8, 0xD5, 0x34, 0x19, 0xD3, 0x86, 0xB2, 0x23, 0xB7, 0xB2, 0xAD, 0x1B +}; + +static unsigned char cfb_cipher32[24] = { + 0xF3, 0x09, 0x62, 0x49, 0xA4, 0xDF, 0xA4, 0x9F, 0x33, 0xDC, 0x7B, 0xAD, + 0x4C, 0xC8, 0x9F, 0x64, 0xE4, 0x53, 0xE5, 0xEC, 0x67, 0x20, 0xDA, 0xB6 +}; + +static unsigned char cfb_cipher48[24] = { + 0xF3, 0x09, 0x62, 0x49, 0xC7, 0xF4, 0x30, 0xB5, 0x15, 0xEC, 0xBB, 0x85, + 0x97, 0x5A, 0x13, 0x8C, 0x68, 0x60, 0xE2, 0x38, 0x34, 0x3C, 0xDC, 0x1F +}; + +static unsigned char cfb_cipher64[24] = { + 0xF3, 0x09, 0x62, 0x49, 0xC7, 0xF4, 0x6E, 0x51, 0xA6, 0x9E, 0x83, 0x9B, + 0x1A, 0x92, 0xF7, 0x84, 0x03, 0x46, 0x71, 0x33, 0x89, 0x8E, 0xA6, 0x22 +}; + +static unsigned char ofb_key[8] = + { 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef }; +static unsigned char ofb_iv[8] = + { 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef }; +static unsigned char ofb_buf1[24], ofb_buf2[24], ofb_tmp[8]; +static unsigned char ofb_cipher[24] = { + 0xf3, 0x09, 0x62, 0x49, 0xc7, 0xf4, 0x6e, 0x51, + 0x35, 0xf2, 0x4a, 0x24, 0x2e, 0xeb, 0x3d, 0x3f, + 0x3d, 0x6d, 0x5b, 0xe3, 0x25, 0x5a, 0xf8, 0xc3 +}; + +# if 0 +static DES_LONG cbc_cksum_ret = 0xB462FEF7L; +# else +static DES_LONG cbc_cksum_ret = 0xF7FE62B4L; +# endif +static unsigned char cbc_cksum_data[8] = + { 0x1D, 0x26, 0x93, 0x97, 0xf7, 0xfe, 0x62, 0xb4 }; + +static char *pt(unsigned char *p); +static int cfb_test(int bits, unsigned char *cfb_cipher); +static int cfb64_test(unsigned char *cfb_cipher); +static int ede_cfb64_test(unsigned char *cfb_cipher); +int main(int argc, char *argv[]) +{ + int j, err = 0; + unsigned int i; + des_cblock in, out, outin, iv3, iv2; + des_key_schedule ks, ks2, ks3; + unsigned char cbc_in[40]; + unsigned char cbc_out[40]; + DES_LONG cs; + unsigned char cret[8]; +# ifdef _CRAY + struct { + int a:32; + int b:32; + } lqret[2]; +# else + DES_LONG lqret[4]; +# endif + int num; + char *str; + +# ifndef OPENSSL_NO_DESCBCM + printf("Doing cbcm\n"); + if ((j = DES_set_key_checked(&cbc_key, &ks)) != 0) { + printf("Key error %d\n", j); + err = 1; + } + if ((j = DES_set_key_checked(&cbc2_key, &ks2)) != 0) { + printf("Key error %d\n", j); + err = 1; + } + if ((j = DES_set_key_checked(&cbc3_key, &ks3)) != 0) { + printf("Key error %d\n", j); + err = 1; + } + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + i = strlen((char *)cbc_data) + 1; + /* i=((i+7)/8)*8; */ + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + memset(iv2, '\0', sizeof iv2); + + DES_ede3_cbcm_encrypt(cbc_data, cbc_out, 16L, &ks, &ks2, &ks3, &iv3, &iv2, + DES_ENCRYPT); + DES_ede3_cbcm_encrypt(&cbc_data[16], &cbc_out[16], i - 16, &ks, &ks2, + &ks3, &iv3, &iv2, DES_ENCRYPT); +/*- if (memcmp(cbc_out,cbc3_ok, + (unsigned int)(strlen((char *)cbc_data)+1+7)/8*8) != 0) + { + printf("des_ede3_cbc_encrypt encrypt error\n"); + err=1; + } +*/ + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + memset(iv2, '\0', sizeof iv2); + DES_ede3_cbcm_encrypt(cbc_out, cbc_in, i, &ks, &ks2, &ks3, &iv3, &iv2, + DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *)cbc_data) + 1) != 0) { + unsigned int n; + + printf("des_ede3_cbcm_encrypt decrypt error\n"); + for (n = 0; n < i; ++n) + printf(" %02x", cbc_data[n]); + printf("\n"); + for (n = 0; n < i; ++n) + printf(" %02x", cbc_in[n]); + printf("\n"); + err = 1; + } +# endif + + printf("Doing ecb\n"); + for (i = 0; i < NUM_TESTS; i++) { + DES_set_key_unchecked(&key_data[i], &ks); + memcpy(in, plain_data[i], 8); + memset(out, 0, 8); + memset(outin, 0, 8); + des_ecb_encrypt(&in, &out, ks, DES_ENCRYPT); + des_ecb_encrypt(&out, &outin, ks, DES_DECRYPT); + + if (memcmp(out, cipher_data[i], 8) != 0) { + printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n", + i + 1, pt(key_data[i]), pt(in), pt(cipher_data[i]), + pt(out)); + err = 1; + } + if (memcmp(in, outin, 8) != 0) { + printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n", + i + 1, pt(key_data[i]), pt(out), pt(in), pt(outin)); + err = 1; + } + } + +# ifndef LIBDES_LIT + printf("Doing ede ecb\n"); + for (i = 0; i < (NUM_TESTS - 2); i++) { + DES_set_key_unchecked(&key_data[i], &ks); + DES_set_key_unchecked(&key_data[i + 1], &ks2); + DES_set_key_unchecked(&key_data[i + 2], &ks3); + memcpy(in, plain_data[i], 8); + memset(out, 0, 8); + memset(outin, 0, 8); + des_ecb2_encrypt(&in, &out, ks, ks2, DES_ENCRYPT); + des_ecb2_encrypt(&out, &outin, ks, ks2, DES_DECRYPT); + + if (memcmp(out, cipher_ecb2[i], 8) != 0) { + printf("Encryption error %2d\nk=%s p=%s o=%s act=%s\n", + i + 1, pt(key_data[i]), pt(in), pt(cipher_ecb2[i]), + pt(out)); + err = 1; + } + if (memcmp(in, outin, 8) != 0) { + printf("Decryption error %2d\nk=%s p=%s o=%s act=%s\n", + i + 1, pt(key_data[i]), pt(out), pt(in), pt(outin)); + err = 1; + } + } +# endif + + printf("Doing cbc\n"); + if ((j = DES_set_key_checked(&cbc_key, &ks)) != 0) { + printf("Key error %d\n", j); + err = 1; + } + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_ncbc_encrypt(cbc_data, cbc_out, strlen((char *)cbc_data) + 1, ks, + &iv3, DES_ENCRYPT); + if (memcmp(cbc_out, cbc_ok, 32) != 0) { + printf("cbc_encrypt encrypt error\n"); + err = 1; + } + + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_ncbc_encrypt(cbc_out, cbc_in, strlen((char *)cbc_data) + 1, ks, + &iv3, DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *)cbc_data)) != 0) { + printf("cbc_encrypt decrypt error\n"); + err = 1; + } +# ifndef LIBDES_LIT + printf("Doing desx cbc\n"); + if ((j = DES_set_key_checked(&cbc_key, &ks)) != 0) { + printf("Key error %d\n", j); + err = 1; + } + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_xcbc_encrypt(cbc_data, cbc_out, strlen((char *)cbc_data) + 1, ks, + &iv3, &cbc2_key, &cbc3_key, DES_ENCRYPT); + if (memcmp(cbc_out, xcbc_ok, 32) != 0) { + printf("des_xcbc_encrypt encrypt error\n"); + err = 1; + } + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_xcbc_encrypt(cbc_out, cbc_in, strlen((char *)cbc_data) + 1, ks, + &iv3, &cbc2_key, &cbc3_key, DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *)cbc_data) + 1) != 0) { + printf("des_xcbc_encrypt decrypt error\n"); + err = 1; + } +# endif + + printf("Doing ede cbc\n"); + if ((j = DES_set_key_checked(&cbc_key, &ks)) != 0) { + printf("Key error %d\n", j); + err = 1; + } + if ((j = DES_set_key_checked(&cbc2_key, &ks2)) != 0) { + printf("Key error %d\n", j); + err = 1; + } + if ((j = DES_set_key_checked(&cbc3_key, &ks3)) != 0) { + printf("Key error %d\n", j); + err = 1; + } + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + i = strlen((char *)cbc_data) + 1; + /* i=((i+7)/8)*8; */ + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + + des_ede3_cbc_encrypt(cbc_data, cbc_out, 16L, ks, ks2, ks3, &iv3, + DES_ENCRYPT); + des_ede3_cbc_encrypt(&(cbc_data[16]), &(cbc_out[16]), i - 16, ks, ks2, + ks3, &iv3, DES_ENCRYPT); + if (memcmp + (cbc_out, cbc3_ok, + (unsigned int)(strlen((char *)cbc_data) + 1 + 7) / 8 * 8) != 0) { + unsigned int n; + + printf("des_ede3_cbc_encrypt encrypt error\n"); + for (n = 0; n < i; ++n) + printf(" %02x", cbc_out[n]); + printf("\n"); + for (n = 0; n < i; ++n) + printf(" %02x", cbc3_ok[n]); + printf("\n"); + err = 1; + } + + memcpy(iv3, cbc_iv, sizeof(cbc_iv)); + des_ede3_cbc_encrypt(cbc_out, cbc_in, i, ks, ks2, ks3, &iv3, DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *)cbc_data) + 1) != 0) { + unsigned int n; + + printf("des_ede3_cbc_encrypt decrypt error\n"); + for (n = 0; n < i; ++n) + printf(" %02x", cbc_data[n]); + printf("\n"); + for (n = 0; n < i; ++n) + printf(" %02x", cbc_in[n]); + printf("\n"); + err = 1; + } +# ifndef LIBDES_LIT + printf("Doing pcbc\n"); + if ((j = DES_set_key_checked(&cbc_key, &ks)) != 0) { + printf("Key error %d\n", j); + err = 1; + } + memset(cbc_out, 0, 40); + memset(cbc_in, 0, 40); + des_pcbc_encrypt(cbc_data, cbc_out, strlen((char *)cbc_data) + 1, ks, + &cbc_iv, DES_ENCRYPT); + if (memcmp(cbc_out, pcbc_ok, 32) != 0) { + printf("pcbc_encrypt encrypt error\n"); + err = 1; + } + des_pcbc_encrypt(cbc_out, cbc_in, strlen((char *)cbc_data) + 1, ks, + &cbc_iv, DES_DECRYPT); + if (memcmp(cbc_in, cbc_data, strlen((char *)cbc_data) + 1) != 0) { + printf("pcbc_encrypt decrypt error\n"); + err = 1; + } + + printf("Doing "); + printf("cfb8 "); + err += cfb_test(8, cfb_cipher8); + printf("cfb16 "); + err += cfb_test(16, cfb_cipher16); + printf("cfb32 "); + err += cfb_test(32, cfb_cipher32); + printf("cfb48 "); + err += cfb_test(48, cfb_cipher48); + printf("cfb64 "); + err += cfb_test(64, cfb_cipher64); + + printf("cfb64() "); + err += cfb64_test(cfb_cipher64); + + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + for (i = 0; i < sizeof(plain); i++) + des_cfb_encrypt(&(plain[i]), &(cfb_buf1[i]), + 8, 1, ks, &cfb_tmp, DES_ENCRYPT); + if (memcmp(cfb_cipher8, cfb_buf1, sizeof(plain)) != 0) { + printf("cfb_encrypt small encrypt error\n"); + err = 1; + } + + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + for (i = 0; i < sizeof(plain); i++) + des_cfb_encrypt(&(cfb_buf1[i]), &(cfb_buf2[i]), + 8, 1, ks, &cfb_tmp, DES_DECRYPT); + if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0) { + printf("cfb_encrypt small decrypt error\n"); + err = 1; + } + + printf("ede_cfb64() "); + err += ede_cfb64_test(cfb_cipher64); + + printf("done\n"); + + printf("Doing ofb\n"); + DES_set_key_checked(&ofb_key, &ks); + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + des_ofb_encrypt(plain, ofb_buf1, 64, sizeof(plain) / 8, ks, &ofb_tmp); + if (memcmp(ofb_cipher, ofb_buf1, sizeof(ofb_buf1)) != 0) { + printf("ofb_encrypt encrypt error\n"); + printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", + ofb_buf1[8 + 0], ofb_buf1[8 + 1], ofb_buf1[8 + 2], + ofb_buf1[8 + 3], ofb_buf1[8 + 4], ofb_buf1[8 + 5], + ofb_buf1[8 + 6], ofb_buf1[8 + 7]); + printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", ofb_buf1[8 + 0], + ofb_cipher[8 + 1], ofb_cipher[8 + 2], ofb_cipher[8 + 3], + ofb_buf1[8 + 4], ofb_cipher[8 + 5], ofb_cipher[8 + 6], + ofb_cipher[8 + 7]); + err = 1; + } + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + des_ofb_encrypt(ofb_buf1, ofb_buf2, 64, sizeof(ofb_buf1) / 8, ks, + &ofb_tmp); + if (memcmp(plain, ofb_buf2, sizeof(ofb_buf2)) != 0) { + printf("ofb_encrypt decrypt error\n"); + printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", + ofb_buf2[8 + 0], ofb_buf2[8 + 1], ofb_buf2[8 + 2], + ofb_buf2[8 + 3], ofb_buf2[8 + 4], ofb_buf2[8 + 5], + ofb_buf2[8 + 6], ofb_buf2[8 + 7]); + printf("%02X %02X %02X %02X %02X %02X %02X %02X\n", plain[8 + 0], + plain[8 + 1], plain[8 + 2], plain[8 + 3], plain[8 + 4], + plain[8 + 5], plain[8 + 6], plain[8 + 7]); + err = 1; + } + + printf("Doing ofb64\n"); + DES_set_key_checked(&ofb_key, &ks); + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + memset(ofb_buf1, 0, sizeof(ofb_buf1)); + memset(ofb_buf2, 0, sizeof(ofb_buf1)); + num = 0; + for (i = 0; i < sizeof(plain); i++) { + des_ofb64_encrypt(&(plain[i]), &(ofb_buf1[i]), 1, ks, &ofb_tmp, &num); + } + if (memcmp(ofb_cipher, ofb_buf1, sizeof(ofb_buf1)) != 0) { + printf("ofb64_encrypt encrypt error\n"); + err = 1; + } + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + num = 0; + des_ofb64_encrypt(ofb_buf1, ofb_buf2, sizeof(ofb_buf1), ks, &ofb_tmp, + &num); + if (memcmp(plain, ofb_buf2, sizeof(ofb_buf2)) != 0) { + printf("ofb64_encrypt decrypt error\n"); + err = 1; + } + + printf("Doing ede_ofb64\n"); + DES_set_key_checked(&ofb_key, &ks); + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + memset(ofb_buf1, 0, sizeof(ofb_buf1)); + memset(ofb_buf2, 0, sizeof(ofb_buf1)); + num = 0; + for (i = 0; i < sizeof(plain); i++) { + des_ede3_ofb64_encrypt(&(plain[i]), &(ofb_buf1[i]), 1, ks, ks, + ks, &ofb_tmp, &num); + } + if (memcmp(ofb_cipher, ofb_buf1, sizeof(ofb_buf1)) != 0) { + printf("ede_ofb64_encrypt encrypt error\n"); + err = 1; + } + memcpy(ofb_tmp, ofb_iv, sizeof(ofb_iv)); + num = 0; + des_ede3_ofb64_encrypt(ofb_buf1, ofb_buf2, sizeof(ofb_buf1), ks, ks, ks, + &ofb_tmp, &num); + if (memcmp(plain, ofb_buf2, sizeof(ofb_buf2)) != 0) { + printf("ede_ofb64_encrypt decrypt error\n"); + err = 1; + } + + printf("Doing cbc_cksum\n"); + DES_set_key_checked(&cbc_key, &ks); + cs = des_cbc_cksum(cbc_data, &cret, strlen((char *)cbc_data), ks, + &cbc_iv); + if (cs != cbc_cksum_ret) { + printf("bad return value (%08lX), should be %08lX\n", + (unsigned long)cs, (unsigned long)cbc_cksum_ret); + err = 1; + } + if (memcmp(cret, cbc_cksum_data, 8) != 0) { + printf("bad cbc_cksum block returned\n"); + err = 1; + } + + printf("Doing quad_cksum\n"); + cs = des_quad_cksum(cbc_data, (des_cblock *)lqret, + (long)strlen((char *)cbc_data), 2, + (des_cblock *)cbc_iv); + if (cs != 0x70d7a63aL) { + printf("quad_cksum error, ret %08lx should be 70d7a63a\n", + (unsigned long)cs); + err = 1; + } +# ifdef _CRAY + if (lqret[0].a != 0x327eba8dL) { + printf("quad_cksum error, out[0] %08lx is not %08lx\n", + (unsigned long)lqret[0].a, 0x327eba8dUL); + err = 1; + } + if (lqret[0].b != 0x201a49ccL) { + printf("quad_cksum error, out[1] %08lx is not %08lx\n", + (unsigned long)lqret[0].b, 0x201a49ccUL); + err = 1; + } + if (lqret[1].a != 0x70d7a63aL) { + printf("quad_cksum error, out[2] %08lx is not %08lx\n", + (unsigned long)lqret[1].a, 0x70d7a63aUL); + err = 1; + } + if (lqret[1].b != 0x501c2c26L) { + printf("quad_cksum error, out[3] %08lx is not %08lx\n", + (unsigned long)lqret[1].b, 0x501c2c26UL); + err = 1; + } +# else + if (lqret[0] != 0x327eba8dL) { + printf("quad_cksum error, out[0] %08lx is not %08lx\n", + (unsigned long)lqret[0], 0x327eba8dUL); + err = 1; + } + if (lqret[1] != 0x201a49ccL) { + printf("quad_cksum error, out[1] %08lx is not %08lx\n", + (unsigned long)lqret[1], 0x201a49ccUL); + err = 1; + } + if (lqret[2] != 0x70d7a63aL) { + printf("quad_cksum error, out[2] %08lx is not %08lx\n", + (unsigned long)lqret[2], 0x70d7a63aUL); + err = 1; + } + if (lqret[3] != 0x501c2c26L) { + printf("quad_cksum error, out[3] %08lx is not %08lx\n", + (unsigned long)lqret[3], 0x501c2c26UL); + err = 1; + } +# endif +# endif + + printf("input word alignment test"); + for (i = 0; i < 4; i++) { + printf(" %d", i); + des_ncbc_encrypt(&(cbc_out[i]), cbc_in, + strlen((char *)cbc_data) + 1, ks, + &cbc_iv, DES_ENCRYPT); + } + printf("\noutput word alignment test"); + for (i = 0; i < 4; i++) { + printf(" %d", i); + des_ncbc_encrypt(cbc_out, &(cbc_in[i]), + strlen((char *)cbc_data) + 1, ks, + &cbc_iv, DES_ENCRYPT); + } + printf("\n"); + printf("fast crypt test "); + str = crypt("testing", "ef"); + if (strcmp("efGnQx2725bI2", str) != 0) { + printf("fast crypt error, %s should be efGnQx2725bI2\n", str); + err = 1; + } + str = crypt("bca76;23", "yA"); + if (strcmp("yA1Rp/1hZXIJk", str) != 0) { + printf("fast crypt error, %s should be yA1Rp/1hZXIJk\n", str); + err = 1; + } +# ifdef OPENSSL_SYS_NETWARE + if (err) + printf("ERROR: %d\n", err); +# endif + printf("\n"); + return (err); +} + +static char *pt(unsigned char *p) +{ + static char bufs[10][20]; + static int bnum = 0; + char *ret; + int i; + static char *f = "0123456789ABCDEF"; + + ret = &(bufs[bnum++][0]); + bnum %= 10; + for (i = 0; i < 8; i++) { + ret[i * 2] = f[(p[i] >> 4) & 0xf]; + ret[i * 2 + 1] = f[p[i] & 0xf]; + } + ret[16] = '\0'; + return (ret); +} + +# ifndef LIBDES_LIT + +static int cfb_test(int bits, unsigned char *cfb_cipher) +{ + des_key_schedule ks; + int i, err = 0; + + DES_set_key_checked(&cfb_key, &ks); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + des_cfb_encrypt(plain, cfb_buf1, bits, sizeof(plain), ks, &cfb_tmp, + DES_ENCRYPT); + if (memcmp(cfb_cipher, cfb_buf1, sizeof(plain)) != 0) { + err = 1; + printf("cfb_encrypt encrypt error\n"); + for (i = 0; i < 24; i += 8) + printf("%s\n", pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + des_cfb_encrypt(cfb_buf1, cfb_buf2, bits, sizeof(plain), ks, &cfb_tmp, + DES_DECRYPT); + if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0) { + err = 1; + printf("cfb_encrypt decrypt error\n"); + for (i = 0; i < 24; i += 8) + printf("%s\n", pt(&(cfb_buf1[i]))); + } + return (err); +} + +static int cfb64_test(unsigned char *cfb_cipher) +{ + des_key_schedule ks; + int err = 0, i, n; + + DES_set_key_checked(&cfb_key, &ks); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + n = 0; + des_cfb64_encrypt(plain, cfb_buf1, 12, ks, &cfb_tmp, &n, DES_ENCRYPT); + des_cfb64_encrypt(&(plain[12]), &(cfb_buf1[12]), sizeof(plain) - 12, ks, + &cfb_tmp, &n, DES_ENCRYPT); + if (memcmp(cfb_cipher, cfb_buf1, sizeof(plain)) != 0) { + err = 1; + printf("cfb_encrypt encrypt error\n"); + for (i = 0; i < 24; i += 8) + printf("%s\n", pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + n = 0; + des_cfb64_encrypt(cfb_buf1, cfb_buf2, 17, ks, &cfb_tmp, &n, DES_DECRYPT); + des_cfb64_encrypt(&(cfb_buf1[17]), &(cfb_buf2[17]), + sizeof(plain) - 17, ks, &cfb_tmp, &n, DES_DECRYPT); + if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0) { + err = 1; + printf("cfb_encrypt decrypt error\n"); + for (i = 0; i < 24; i += 8) + printf("%s\n", pt(&(cfb_buf2[i]))); + } + return (err); +} + +static int ede_cfb64_test(unsigned char *cfb_cipher) +{ + des_key_schedule ks; + int err = 0, i, n; + + DES_set_key_checked(&cfb_key, &ks); + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + n = 0; + des_ede3_cfb64_encrypt(plain, cfb_buf1, 12, ks, ks, ks, &cfb_tmp, &n, + DES_ENCRYPT); + des_ede3_cfb64_encrypt(&(plain[12]), &(cfb_buf1[12]), + sizeof(plain) - 12, ks, ks, ks, + &cfb_tmp, &n, DES_ENCRYPT); + if (memcmp(cfb_cipher, cfb_buf1, sizeof(plain)) != 0) { + err = 1; + printf("ede_cfb_encrypt encrypt error\n"); + for (i = 0; i < 24; i += 8) + printf("%s\n", pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp, cfb_iv, sizeof(cfb_iv)); + n = 0; + des_ede3_cfb64_encrypt(cfb_buf1, cfb_buf2, (long)17, ks, ks, ks, + &cfb_tmp, &n, DES_DECRYPT); + des_ede3_cfb64_encrypt(&(cfb_buf1[17]), &(cfb_buf2[17]), + sizeof(plain) - 17, ks, ks, ks, + &cfb_tmp, &n, DES_DECRYPT); + if (memcmp(plain, cfb_buf2, sizeof(plain)) != 0) { + err = 1; + printf("ede_cfb_encrypt decrypt error\n"); + for (i = 0; i < 24; i += 8) + printf("%s\n", pt(&(cfb_buf2[i]))); + } + return (err); +} + +# endif +#endif diff --git a/libs/openssl/crypto/des/ecb3_enc.c b/libs/openssl/crypto/des/ecb3_enc.c new file mode 100644 index 00000000..c49fbd41 --- /dev/null +++ b/libs/openssl/crypto/des/ecb3_enc.c @@ -0,0 +1,82 @@ +/* crypto/des/ecb3_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +void DES_ecb3_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks1, DES_key_schedule *ks2, + DES_key_schedule *ks3, int enc) +{ + register DES_LONG l0, l1; + DES_LONG ll[2]; + const unsigned char *in = &(*input)[0]; + unsigned char *out = &(*output)[0]; + + c2l(in, l0); + c2l(in, l1); + ll[0] = l0; + ll[1] = l1; + if (enc) + DES_encrypt3(ll, ks1, ks2, ks3); + else + DES_decrypt3(ll, ks1, ks2, ks3); + l0 = ll[0]; + l1 = ll[1]; + l2c(l0, out); + l2c(l1, out); +} diff --git a/libs/openssl/crypto/des/ecb_enc.c b/libs/openssl/crypto/des/ecb_enc.c new file mode 100644 index 00000000..f97fd971 --- /dev/null +++ b/libs/openssl/crypto/des/ecb_enc.c @@ -0,0 +1,124 @@ +/* crypto/des/ecb_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" +#include "des_ver.h" +#include +#include + +OPENSSL_GLOBAL const char libdes_version[] = "libdes" OPENSSL_VERSION_PTEXT; +OPENSSL_GLOBAL const char DES_version[] = "DES" OPENSSL_VERSION_PTEXT; + +const char *DES_options(void) +{ + static int init = 1; + static char buf[32]; + + if (init) { + const char *ptr, *unroll, *risc, *size; + +#ifdef DES_PTR + ptr = "ptr"; +#else + ptr = "idx"; +#endif +#if defined(DES_RISC1) || defined(DES_RISC2) +# ifdef DES_RISC1 + risc = "risc1"; +# endif +# ifdef DES_RISC2 + risc = "risc2"; +# endif +#else + risc = "cisc"; +#endif +#ifdef DES_UNROLL + unroll = "16"; +#else + unroll = "2"; +#endif + if (sizeof(DES_LONG) != sizeof(long)) + size = "int"; + else + size = "long"; + BIO_snprintf(buf, sizeof buf, "des(%s,%s,%s,%s)", ptr, risc, unroll, + size); + init = 0; + } + return (buf); +} + +void DES_ecb_encrypt(const_DES_cblock *input, DES_cblock *output, + DES_key_schedule *ks, int enc) +{ + register DES_LONG l; + DES_LONG ll[2]; + const unsigned char *in = &(*input)[0]; + unsigned char *out = &(*output)[0]; + + c2l(in, l); + ll[0] = l; + c2l(in, l); + ll[1] = l; + DES_encrypt1(ll, ks, enc); + l = ll[0]; + l2c(l, out); + l = ll[1]; + l2c(l, out); + l = ll[0] = ll[1] = 0; +} diff --git a/libs/openssl/crypto/des/ede_cbcm_enc.c b/libs/openssl/crypto/des/ede_cbcm_enc.c new file mode 100644 index 00000000..86f27d07 --- /dev/null +++ b/libs/openssl/crypto/des/ede_cbcm_enc.c @@ -0,0 +1,189 @@ +/* ede_cbcm_enc.c */ +/* + * Written by Ben Laurie for the OpenSSL project 13 Feb + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * + * This is an implementation of Triple DES Cipher Block Chaining with Output + * Feedback Masking, by Coppersmith, Johnson and Matyas, (IBM and Certicom). + * + * Note that there is a known attack on this by Biham and Knudsen but it + * takes a lot of work: + * + * http://www.cs.technion.ac.il/users/wwwb/cgi-bin/tr-get.cgi/1998/CS/CS0928.ps.gz + * + */ + +#include /* To see if OPENSSL_NO_DESCBCM is defined */ + +#ifndef OPENSSL_NO_DESCBCM +# include "des_locl.h" + +void DES_ede3_cbcm_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, DES_key_schedule *ks3, + DES_cblock *ivec1, DES_cblock *ivec2, int enc) +{ + register DES_LONG tin0, tin1; + register DES_LONG tout0, tout1, xor0, xor1, m0, m1; + register long l = length; + DES_LONG tin[2]; + unsigned char *iv1, *iv2; + + iv1 = &(*ivec1)[0]; + iv2 = &(*ivec2)[0]; + + if (enc) { + c2l(iv1, m0); + c2l(iv1, m1); + c2l(iv2, tout0); + c2l(iv2, tout1); + for (l -= 8; l >= -7; l -= 8) { + tin[0] = m0; + tin[1] = m1; + DES_encrypt1(tin, ks3, 1); + m0 = tin[0]; + m1 = tin[1]; + + if (l < 0) { + c2ln(in, tin0, tin1, l + 8); + } else { + c2l(in, tin0); + c2l(in, tin1); + } + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt1(tin, ks1, 1); + tin[0] ^= m0; + tin[1] ^= m1; + DES_encrypt1(tin, ks2, 0); + tin[0] ^= m0; + tin[1] ^= m1; + DES_encrypt1(tin, ks1, 1); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + iv1 = &(*ivec1)[0]; + l2c(m0, iv1); + l2c(m1, iv1); + + iv2 = &(*ivec2)[0]; + l2c(tout0, iv2); + l2c(tout1, iv2); + } else { + register DES_LONG t0, t1; + + c2l(iv1, m0); + c2l(iv1, m1); + c2l(iv2, xor0); + c2l(iv2, xor1); + for (l -= 8; l >= -7; l -= 8) { + tin[0] = m0; + tin[1] = m1; + DES_encrypt1(tin, ks3, 1); + m0 = tin[0]; + m1 = tin[1]; + + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt1(tin, ks1, 0); + tin[0] ^= m0; + tin[1] ^= m1; + DES_encrypt1(tin, ks2, 1); + tin[0] ^= m0; + tin[1] ^= m1; + DES_encrypt1(tin, ks1, 0); + tout0 = tin[0]; + tout1 = tin[1]; + + tout0 ^= xor0; + tout1 ^= xor1; + if (l < 0) { + l2cn(tout0, tout1, out, l + 8); + } else { + l2c(tout0, out); + l2c(tout1, out); + } + xor0 = t0; + xor1 = t1; + } + + iv1 = &(*ivec1)[0]; + l2c(m0, iv1); + l2c(m1, iv1); + + iv2 = &(*ivec2)[0]; + l2c(xor0, iv2); + l2c(xor1, iv2); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} +#endif diff --git a/libs/openssl/crypto/des/enc_read.c b/libs/openssl/crypto/des/enc_read.c new file mode 100644 index 00000000..fcb66541 --- /dev/null +++ b/libs/openssl/crypto/des/enc_read.c @@ -0,0 +1,235 @@ +/* crypto/des/enc_read.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include "des_locl.h" + +/* This has some uglies in it but it works - even over sockets. */ +/* + * extern int errno; + */ +OPENSSL_IMPLEMENT_GLOBAL(int, DES_rw_mode, DES_PCBC_MODE) + +/*- + * WARNINGS: + * + * - The data format used by DES_enc_write() and DES_enc_read() + * has a cryptographic weakness: When asked to write more + * than MAXWRITE bytes, DES_enc_write will split the data + * into several chunks that are all encrypted + * using the same IV. So don't use these functions unless you + * are sure you know what you do (in which case you might + * not want to use them anyway). + * + * - This code cannot handle non-blocking sockets. + * + * - This function uses an internal state and thus cannot be + * used on multiple files. + */ +int DES_enc_read(int fd, void *buf, int len, DES_key_schedule *sched, + DES_cblock *iv) +{ +#if defined(OPENSSL_NO_POSIX_IO) + return (0); +#else + /* data to be unencrypted */ + int net_num = 0; + static unsigned char *net = NULL; + /* + * extra unencrypted data for when a block of 100 comes in but is + * des_read one byte at a time. + */ + static unsigned char *unnet = NULL; + static int unnet_start = 0; + static int unnet_left = 0; + static unsigned char *tmpbuf = NULL; + int i; + long num = 0, rnum; + unsigned char *p; + + if (tmpbuf == NULL) { + tmpbuf = OPENSSL_malloc(BSIZE); + if (tmpbuf == NULL) + return (-1); + } + if (net == NULL) { + net = OPENSSL_malloc(BSIZE); + if (net == NULL) + return (-1); + } + if (unnet == NULL) { + unnet = OPENSSL_malloc(BSIZE); + if (unnet == NULL) + return (-1); + } + /* left over data from last decrypt */ + if (unnet_left != 0) { + if (unnet_left < len) { + /* + * we still still need more data but will return with the number + * of bytes we have - should always check the return value + */ + memcpy(buf, &(unnet[unnet_start]), unnet_left); + /* + * eay 26/08/92 I had the next 2 lines reversed :-( + */ + i = unnet_left; + unnet_start = unnet_left = 0; + } else { + memcpy(buf, &(unnet[unnet_start]), len); + unnet_start += len; + unnet_left -= len; + i = len; + } + return (i); + } + + /* We need to get more data. */ + if (len > MAXWRITE) + len = MAXWRITE; + + /* first - get the length */ + while (net_num < HDRSIZE) { +# ifndef OPENSSL_SYS_WIN32 + i = read(fd, (void *)&(net[net_num]), HDRSIZE - net_num); +# else + i = _read(fd, (void *)&(net[net_num]), HDRSIZE - net_num); +# endif +# ifdef EINTR + if ((i == -1) && (errno == EINTR)) + continue; +# endif + if (i <= 0) + return (0); + net_num += i; + } + + /* we now have at net_num bytes in net */ + p = net; + /* num=0; */ + n2l(p, num); + /* + * num should be rounded up to the next group of eight we make sure that + * we have read a multiple of 8 bytes from the net. + */ + if ((num > MAXWRITE) || (num < 0)) /* error */ + return (-1); + rnum = (num < 8) ? 8 : ((num + 7) / 8 * 8); + + net_num = 0; + while (net_num < rnum) { +# ifndef OPENSSL_SYS_WIN32 + i = read(fd, (void *)&(net[net_num]), rnum - net_num); +# else + i = _read(fd, (void *)&(net[net_num]), rnum - net_num); +# endif +# ifdef EINTR + if ((i == -1) && (errno == EINTR)) + continue; +# endif + if (i <= 0) + return (0); + net_num += i; + } + + /* Check if there will be data left over. */ + if (len < num) { + if (DES_rw_mode & DES_PCBC_MODE) + DES_pcbc_encrypt(net, unnet, num, sched, iv, DES_DECRYPT); + else + DES_cbc_encrypt(net, unnet, num, sched, iv, DES_DECRYPT); + memcpy(buf, unnet, len); + unnet_start = len; + unnet_left = num - len; + + /* + * The following line is done because we return num as the number of + * bytes read. + */ + num = len; + } else { + /*- + * >output is a multiple of 8 byes, if len < rnum + * >we must be careful. The user must be aware that this + * >routine will write more bytes than he asked for. + * >The length of the buffer must be correct. + * FIXED - Should be ok now 18-9-90 - eay */ + if (len < rnum) { + + if (DES_rw_mode & DES_PCBC_MODE) + DES_pcbc_encrypt(net, tmpbuf, num, sched, iv, DES_DECRYPT); + else + DES_cbc_encrypt(net, tmpbuf, num, sched, iv, DES_DECRYPT); + + /* + * eay 26/08/92 fix a bug that returned more bytes than you asked + * for (returned len bytes :-( + */ + memcpy(buf, tmpbuf, num); + } else { + if (DES_rw_mode & DES_PCBC_MODE) + DES_pcbc_encrypt(net, buf, num, sched, iv, DES_DECRYPT); + else + DES_cbc_encrypt(net, buf, num, sched, iv, DES_DECRYPT); + } + } + return num; +#endif /* OPENSSL_NO_POSIX_IO */ +} diff --git a/libs/openssl/crypto/des/enc_writ.c b/libs/openssl/crypto/des/enc_writ.c new file mode 100644 index 00000000..bfaabde5 --- /dev/null +++ b/libs/openssl/crypto/des/enc_writ.c @@ -0,0 +1,182 @@ +/* crypto/des/enc_writ.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include "cryptlib.h" +#include "des_locl.h" +#include + +/*- + * WARNINGS: + * + * - The data format used by DES_enc_write() and DES_enc_read() + * has a cryptographic weakness: When asked to write more + * than MAXWRITE bytes, DES_enc_write will split the data + * into several chunks that are all encrypted + * using the same IV. So don't use these functions unless you + * are sure you know what you do (in which case you might + * not want to use them anyway). + * + * - This code cannot handle non-blocking sockets. + */ + +int DES_enc_write(int fd, const void *_buf, int len, + DES_key_schedule *sched, DES_cblock *iv) +{ +#if defined(OPENSSL_NO_POSIX_IO) + return (-1); +#else +# ifdef _LIBC + extern unsigned long time(); + extern int write(); +# endif + const unsigned char *buf = _buf; + long rnum; + int i, j, k, outnum; + static unsigned char *outbuf = NULL; + unsigned char shortbuf[8]; + unsigned char *p; + const unsigned char *cp; + static int start = 1; + + if (len < 0) + return -1; + + if (outbuf == NULL) { + outbuf = OPENSSL_malloc(BSIZE + HDRSIZE); + if (outbuf == NULL) + return (-1); + } + /* + * If we are sending less than 8 bytes, the same char will look the same + * if we don't pad it out with random bytes + */ + if (start) { + start = 0; + } + + /* lets recurse if we want to send the data in small chunks */ + if (len > MAXWRITE) { + j = 0; + for (i = 0; i < len; i += k) { + k = DES_enc_write(fd, &(buf[i]), + ((len - i) > MAXWRITE) ? MAXWRITE : (len - i), + sched, iv); + if (k < 0) + return (k); + else + j += k; + } + return (j); + } + + /* write length first */ + p = outbuf; + l2n(len, p); + + /* pad short strings */ + if (len < 8) { + cp = shortbuf; + memcpy(shortbuf, buf, len); + if (RAND_pseudo_bytes(shortbuf + len, 8 - len) < 0) { + return -1; + } + rnum = 8; + } else { + cp = buf; + rnum = ((len + 7) / 8 * 8); /* round up to nearest eight */ + } + + if (DES_rw_mode & DES_PCBC_MODE) + DES_pcbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, sched, + iv, DES_ENCRYPT); + else + DES_cbc_encrypt(cp, &(outbuf[HDRSIZE]), (len < 8) ? 8 : len, sched, + iv, DES_ENCRYPT); + + /* output */ + outnum = rnum + HDRSIZE; + + for (j = 0; j < outnum; j += i) { + /* + * eay 26/08/92 I was not doing writing from where we got up to. + */ +# ifndef _WIN32 + i = write(fd, (void *)&(outbuf[j]), outnum - j); +# else + i = _write(fd, (void *)&(outbuf[j]), outnum - j); +# endif + if (i == -1) { +# ifdef EINTR + if (errno == EINTR) + i = 0; + else +# endif + /* + * This is really a bad error - very bad It will stuff-up + * both ends. + */ + return (-1); + } + } + + return (len); +#endif /* OPENSSL_NO_POSIX_IO */ +} diff --git a/libs/openssl/crypto/des/fcrypt.c b/libs/openssl/crypto/des/fcrypt.c new file mode 100644 index 00000000..111f1e46 --- /dev/null +++ b/libs/openssl/crypto/des/fcrypt.c @@ -0,0 +1,167 @@ +/* NOCW */ +#include +#ifdef _OSD_POSIX +# ifndef CHARSET_EBCDIC +# define CHARSET_EBCDIC 1 +# endif +#endif +#ifdef CHARSET_EBCDIC +# include +#endif + +/* + * This version of crypt has been developed from my MIT compatible DES + * library. Eric Young (eay@cryptsoft.com) + */ + +/* + * Modification by Jens Kupferschmidt (Cu) I have included directive PARA for + * shared memory computers. I have included a directive LONGCRYPT to using + * this routine to cipher passwords with more then 8 bytes like HP-UX 10.x it + * used. The MAXPLEN definition is the maximum of length of password and can + * changed. I have defined 24. + */ + +#include "des_locl.h" + +/* + * Added more values to handle illegal salt values the way normal crypt() + * implementations do. The patch was sent by Bjorn Gronvall + */ +static unsigned const char con_salt[128] = { + 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, + 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, + 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, + 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, + 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, + 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x00, 0x01, + 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, + 0x0A, 0x0B, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, + 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, + 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, + 0x23, 0x24, 0x25, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, + 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, + 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, +}; + +static unsigned const char cov_2char[64] = { + 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, + 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, + 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, + 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x61, 0x62, + 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, + 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, + 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A +}; + +char *DES_crypt(const char *buf, const char *salt) +{ + static char buff[14]; + +#ifndef CHARSET_EBCDIC + return (DES_fcrypt(buf, salt, buff)); +#else + char e_salt[2 + 1]; + char e_buf[32 + 1]; /* replace 32 by 8 ? */ + char *ret; + + /* Copy at most 2 chars of salt */ + if ((e_salt[0] = salt[0]) != '\0') + e_salt[1] = salt[1]; + + /* Copy at most 32 chars of password */ + strncpy(e_buf, buf, sizeof(e_buf)); + + /* Make sure we have a delimiter */ + e_salt[sizeof(e_salt) - 1] = e_buf[sizeof(e_buf) - 1] = '\0'; + + /* Convert the e_salt to ASCII, as that's what DES_fcrypt works on */ + ebcdic2ascii(e_salt, e_salt, sizeof e_salt); + + /* Convert the cleartext password to ASCII */ + ebcdic2ascii(e_buf, e_buf, sizeof e_buf); + + /* Encrypt it (from/to ASCII) */ + ret = DES_fcrypt(e_buf, e_salt, buff); + + /* Convert the result back to EBCDIC */ + ascii2ebcdic(ret, ret, strlen(ret)); + + return ret; +#endif +} + +char *DES_fcrypt(const char *buf, const char *salt, char *ret) +{ + unsigned int i, j, x, y; + DES_LONG Eswap0, Eswap1; + DES_LONG out[2], ll; + DES_cblock key; + DES_key_schedule ks; + unsigned char bb[9]; + unsigned char *b = bb; + unsigned char c, u; + + /* + * eay 25/08/92 If you call crypt("pwd","*") as often happens when you + * have * as the pwd field in /etc/passwd, the function returns + * *\0XXXXXXXXX The \0 makes the string look like * so the pwd "*" would + * crypt to "*". This was found when replacing the crypt in our shared + * libraries. People found that the disabled accounts effectively had no + * passwd :-(. + */ +#ifndef CHARSET_EBCDIC + x = ret[0] = ((salt[0] == '\0') ? 'A' : salt[0]); + Eswap0 = con_salt[x] << 2; + x = ret[1] = ((salt[1] == '\0') ? 'A' : salt[1]); + Eswap1 = con_salt[x] << 6; +#else + x = ret[0] = ((salt[0] == '\0') ? os_toascii['A'] : salt[0]); + Eswap0 = con_salt[x] << 2; + x = ret[1] = ((salt[1] == '\0') ? os_toascii['A'] : salt[1]); + Eswap1 = con_salt[x] << 6; +#endif + + /* + * EAY r=strlen(buf); r=(r+7)/8; + */ + for (i = 0; i < 8; i++) { + c = *(buf++); + if (!c) + break; + key[i] = (c << 1); + } + for (; i < 8; i++) + key[i] = 0; + + DES_set_key_unchecked(&key, &ks); + fcrypt_body(&(out[0]), &ks, Eswap0, Eswap1); + + ll = out[0]; + l2c(ll, b); + ll = out[1]; + l2c(ll, b); + y = 0; + u = 0x80; + bb[8] = 0; + for (i = 2; i < 13; i++) { + c = 0; + for (j = 0; j < 6; j++) { + c <<= 1; + if (bb[y] & u) + c |= 1; + u >>= 1; + if (!u) { + y++; + u = 0x80; + } + } + ret[i] = cov_2char[c]; + } + ret[13] = '\0'; + return (ret); +} diff --git a/libs/openssl/crypto/des/fcrypt_b.c b/libs/openssl/crypto/des/fcrypt_b.c new file mode 100644 index 00000000..b9e87383 --- /dev/null +++ b/libs/openssl/crypto/des/fcrypt_b.c @@ -0,0 +1,140 @@ +/* crypto/des/fcrypt_b.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +/* + * This version of crypt has been developed from my MIT compatible DES + * library. The library is available at pub/Crypto/DES at ftp.psy.uq.oz.au + * Eric Young (eay@cryptsoft.com) + */ + +#define DES_FCRYPT +#include "des_locl.h" +#undef DES_FCRYPT + +#undef PERM_OP +#define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ + (b)^=(t),\ + (a)^=((t)<<(n))) + +#undef HPERM_OP +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ + (a)=(a)^(t)^(t>>(16-(n))))\ + +void fcrypt_body(DES_LONG *out, DES_key_schedule *ks, DES_LONG Eswap0, + DES_LONG Eswap1) +{ + register DES_LONG l, r, t, u; +#ifdef DES_PTR + register const unsigned char *des_SP = (const unsigned char *)DES_SPtrans; +#endif + register DES_LONG *s; + register int j; + register DES_LONG E0, E1; + + l = 0; + r = 0; + + s = (DES_LONG *)ks; + E0 = Eswap0; + E1 = Eswap1; + + for (j = 0; j < 25; j++) { +#ifndef DES_UNROLL + register int i; + + for (i = 0; i < 32; i += 4) { + D_ENCRYPT(l, r, i + 0); /* 1 */ + D_ENCRYPT(r, l, i + 2); /* 2 */ + } +#else + D_ENCRYPT(l, r, 0); /* 1 */ + D_ENCRYPT(r, l, 2); /* 2 */ + D_ENCRYPT(l, r, 4); /* 3 */ + D_ENCRYPT(r, l, 6); /* 4 */ + D_ENCRYPT(l, r, 8); /* 5 */ + D_ENCRYPT(r, l, 10); /* 6 */ + D_ENCRYPT(l, r, 12); /* 7 */ + D_ENCRYPT(r, l, 14); /* 8 */ + D_ENCRYPT(l, r, 16); /* 9 */ + D_ENCRYPT(r, l, 18); /* 10 */ + D_ENCRYPT(l, r, 20); /* 11 */ + D_ENCRYPT(r, l, 22); /* 12 */ + D_ENCRYPT(l, r, 24); /* 13 */ + D_ENCRYPT(r, l, 26); /* 14 */ + D_ENCRYPT(l, r, 28); /* 15 */ + D_ENCRYPT(r, l, 30); /* 16 */ +#endif + + t = l; + l = r; + r = t; + } + l = ROTATE(l, 3) & 0xffffffffL; + r = ROTATE(r, 3) & 0xffffffffL; + + PERM_OP(l, r, t, 1, 0x55555555L); + PERM_OP(r, l, t, 8, 0x00ff00ffL); + PERM_OP(l, r, t, 2, 0x33333333L); + PERM_OP(r, l, t, 16, 0x0000ffffL); + PERM_OP(l, r, t, 4, 0x0f0f0f0fL); + + out[0] = r; + out[1] = l; +} diff --git a/libs/openssl/crypto/des/makefile.bc b/libs/openssl/crypto/des/makefile.bc new file mode 100644 index 00000000..1fe6d491 --- /dev/null +++ b/libs/openssl/crypto/des/makefile.bc @@ -0,0 +1,50 @@ +# +# Origional BC Makefile from Teun +# +# +CC = bcc +TLIB = tlib /0 /C +# note: the -3 flag produces code for 386, 486, Pentium etc; omit it for 286s +OPTIMIZE= -3 -O2 +#WINDOWS= -W +CFLAGS = -c -ml -d $(OPTIMIZE) $(WINDOWS) -DMSDOS +LFLAGS = -ml $(WINDOWS) + +.c.obj: + $(CC) $(CFLAGS) $*.c + +.obj.exe: + $(CC) $(LFLAGS) -e$*.exe $*.obj libdes.lib + +all: $(LIB) destest.exe rpw.exe des.exe speed.exe + +# "make clean": use a directory containing only libdes .exe and .obj files... +clean: + del *.exe + del *.obj + del libdes.lib + del libdes.rsp + +OBJS= cbc_cksm.obj cbc_enc.obj ecb_enc.obj pcbc_enc.obj \ + qud_cksm.obj rand_key.obj set_key.obj str2key.obj \ + enc_read.obj enc_writ.obj fcrypt.obj cfb_enc.obj \ + ecb3_enc.obj ofb_enc.obj cbc3_enc.obj read_pwd.obj\ + cfb64enc.obj ofb64enc.obj ede_enc.obj cfb64ede.obj\ + ofb64ede.obj supp.obj + +LIB= libdes.lib + +$(LIB): $(OBJS) + del $(LIB) + makersp "+%s &\n" &&| + $(OBJS) +| >libdes.rsp + $(TLIB) libdes.lib @libdes.rsp,nul + del libdes.rsp + +destest.exe: destest.obj libdes.lib +rpw.exe: rpw.obj libdes.lib +speed.exe: speed.obj libdes.lib +des.exe: des.obj libdes.lib + + diff --git a/libs/openssl/crypto/des/ncbc_enc.c b/libs/openssl/crypto/des/ncbc_enc.c new file mode 100644 index 00000000..ab267cbf --- /dev/null +++ b/libs/openssl/crypto/des/ncbc_enc.c @@ -0,0 +1,154 @@ +/* crypto/des/ncbc_enc.c */ +/*- + * #included by: + * cbc_enc.c (DES_cbc_encrypt) + * des_enc.c (DES_ncbc_encrypt) + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +#ifdef CBC_ENC_C__DONT_UPDATE_IV +void DES_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + DES_key_schedule *_schedule, DES_cblock *ivec, int enc) +#else +void DES_ncbc_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *_schedule, + DES_cblock *ivec, int enc) +#endif +{ + register DES_LONG tin0, tin1; + register DES_LONG tout0, tout1, xor0, xor1; + register long l = length; + DES_LONG tin[2]; + unsigned char *iv; + + iv = &(*ivec)[0]; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, _schedule, DES_ENCRYPT); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } +#ifndef CBC_ENC_C__DONT_UPDATE_IV + iv = &(*ivec)[0]; + l2c(tout0, iv); + l2c(tout1, iv); +#endif + } else { + c2l(iv, xor0); + c2l(iv, xor1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + DES_encrypt1((DES_LONG *)tin, _schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2cn(tout0, tout1, out, l + 8); +#ifndef CBC_ENC_C__DONT_UPDATE_IV + xor0 = tin0; + xor1 = tin1; +#endif + } +#ifndef CBC_ENC_C__DONT_UPDATE_IV + iv = &(*ivec)[0]; + l2c(xor0, iv); + l2c(xor1, iv); +#endif + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} diff --git a/libs/openssl/crypto/des/ofb64ede.c b/libs/openssl/crypto/des/ofb64ede.c new file mode 100644 index 00000000..45c67505 --- /dev/null +++ b/libs/openssl/crypto/des/ofb64ede.c @@ -0,0 +1,123 @@ +/* crypto/des/ofb64ede.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +/* + * The input and output encrypted as though 64bit ofb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ +void DES_ede3_ofb64_encrypt(register const unsigned char *in, + register unsigned char *out, long length, + DES_key_schedule *k1, DES_key_schedule *k2, + DES_key_schedule *k3, DES_cblock *ivec, int *num) +{ + register DES_LONG v0, v1; + register int n = *num; + register long l = length; + DES_cblock d; + register char *dp; + DES_LONG ti[2]; + unsigned char *iv; + int save = 0; + + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2c(v0, dp); + l2c(v1, dp); + while (l--) { + if (n == 0) { + /* ti[0]=v0; */ + /* ti[1]=v1; */ + DES_encrypt3(ti, k1, k2, k3); + v0 = ti[0]; + v1 = ti[1]; + + dp = (char *)d; + l2c(v0, dp); + l2c(v1, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { +/*- v0=ti[0]; + v1=ti[1];*/ + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + } + v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} + +#ifdef undef /* MACRO */ +void DES_ede2_ofb64_encrypt(register unsigned char *in, + register unsigned char *out, long length, + DES_key_schedule k1, DES_key_schedule k2, + DES_cblock (*ivec), int *num) +{ + DES_ede3_ofb64_encrypt(in, out, length, k1, k2, k1, ivec, num); +} +#endif diff --git a/libs/openssl/crypto/des/ofb64enc.c b/libs/openssl/crypto/des/ofb64enc.c new file mode 100644 index 00000000..8e72dece --- /dev/null +++ b/libs/openssl/crypto/des/ofb64enc.c @@ -0,0 +1,109 @@ +/* crypto/des/ofb64enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +/* + * The input and output encrypted as though 64bit ofb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ +void DES_ofb64_encrypt(register const unsigned char *in, + register unsigned char *out, long length, + DES_key_schedule *schedule, DES_cblock *ivec, int *num) +{ + register DES_LONG v0, v1, t; + register int n = *num; + register long l = length; + DES_cblock d; + register unsigned char *dp; + DES_LONG ti[2]; + unsigned char *iv; + int save = 0; + + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = d; + l2c(v0, dp); + l2c(v1, dp); + while (l--) { + if (n == 0) { + DES_encrypt1(ti, schedule, DES_ENCRYPT); + dp = d; + t = ti[0]; + l2c(t, dp); + t = ti[1]; + l2c(t, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} diff --git a/libs/openssl/crypto/des/ofb_enc.c b/libs/openssl/crypto/des/ofb_enc.c new file mode 100644 index 00000000..02a78775 --- /dev/null +++ b/libs/openssl/crypto/des/ofb_enc.c @@ -0,0 +1,131 @@ +/* crypto/des/ofb_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +/* + * The input and output are loaded in multiples of 8 bits. What this means is + * that if you hame numbits=12 and length=2 the first 12 bits will be + * retrieved from the first byte and half the second. The second 12 bits + * will come from the 3rd and half the 4th byte. + */ +void DES_ofb_encrypt(const unsigned char *in, unsigned char *out, int numbits, + long length, DES_key_schedule *schedule, + DES_cblock *ivec) +{ + register DES_LONG d0, d1, vv0, vv1, v0, v1, n = (numbits + 7) / 8; + register DES_LONG mask0, mask1; + register long l = length; + register int num = numbits; + DES_LONG ti[2]; + unsigned char *iv; + + if (num > 64) + return; + if (num > 32) { + mask0 = 0xffffffffL; + if (num >= 64) + mask1 = mask0; + else + mask1 = (1L << (num - 32)) - 1; + } else { + if (num == 32) + mask0 = 0xffffffffL; + else + mask0 = (1L << num) - 1; + mask1 = 0x00000000L; + } + + iv = &(*ivec)[0]; + c2l(iv, v0); + c2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + while (l-- > 0) { + ti[0] = v0; + ti[1] = v1; + DES_encrypt1((DES_LONG *)ti, schedule, DES_ENCRYPT); + vv0 = ti[0]; + vv1 = ti[1]; + c2ln(in, d0, d1, n); + in += n; + d0 = (d0 ^ vv0) & mask0; + d1 = (d1 ^ vv1) & mask1; + l2cn(d0, d1, out, n); + out += n; + + if (num == 32) { + v0 = v1; + v1 = vv0; + } else if (num == 64) { + v0 = vv0; + v1 = vv1; + } else if (num > 32) { /* && num != 64 */ + v0 = ((v1 >> (num - 32)) | (vv0 << (64 - num))) & 0xffffffffL; + v1 = ((vv0 >> (num - 32)) | (vv1 << (64 - num))) & 0xffffffffL; + } else { /* num < 32 */ + + v0 = ((v0 >> num) | (v1 << (32 - num))) & 0xffffffffL; + v1 = ((v1 >> num) | (vv0 << (32 - num))) & 0xffffffffL; + } + } + iv = &(*ivec)[0]; + l2c(v0, iv); + l2c(v1, iv); + v0 = v1 = d0 = d1 = ti[0] = ti[1] = vv0 = vv1 = 0; +} diff --git a/libs/openssl/crypto/des/options.txt b/libs/openssl/crypto/des/options.txt new file mode 100644 index 00000000..6e2b50f7 --- /dev/null +++ b/libs/openssl/crypto/des/options.txt @@ -0,0 +1,39 @@ +Note that the UNROLL option makes the 'inner' des loop unroll all 16 rounds +instead of the default 4. +RISC1 and RISC2 are 2 alternatives for the inner loop and +PTR means to use pointers arithmatic instead of arrays. + +FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - assembler 577,000 4620k/s +IRIX 6.2 - R10000 195mhz - cc (-O3 -n32) - UNROLL RISC2 PTR 496,000 3968k/s +solaris 2.5.1 usparc 167mhz?? - SC4.0 - UNROLL RISC1 PTR [1] 459,400 3672k/s +FreeBSD - Pentium Pro 200mhz - gcc 2.7.2.2 - UNROLL RISC1 433,000 3468k/s +solaris 2.5.1 usparc 167mhz?? - gcc 2.7.2 - UNROLL 380,000 3041k/s +linux - pentium 100mhz - gcc 2.7.0 - assembler 281,000 2250k/s +NT 4.0 - pentium 100mhz - VC 4.2 - assembler 281,000 2250k/s +AIX 4.1? - PPC604 100mhz - cc - UNROLL 275,000 2200k/s +IRIX 5.3 - R4400 200mhz - gcc 2.6.3 - UNROLL RISC2 PTR 235,300 1882k/s +IRIX 5.3 - R4400 200mhz - cc - UNROLL RISC2 PTR 233,700 1869k/s +NT 4.0 - pentium 100mhz - VC 4.2 - UNROLL RISC1 PTR 191,000 1528k/s +DEC Alpha 165mhz?? - cc - RISC2 PTR [2] 181,000 1448k/s +linux - pentium 100mhz - gcc 2.7.0 - UNROLL RISC1 PTR 158,500 1268k/s +HPUX 10 - 9000/887 - cc - UNROLL [3] 148,000 1190k/s +solaris 2.5.1 - sparc 10 50mhz - gcc 2.7.2 - UNROLL 123,600 989k/s +IRIX 5.3 - R4000 100mhz - cc - UNROLL RISC2 PTR 101,000 808k/s +DGUX - 88100 50mhz(?) - gcc 2.6.3 - UNROLL 81,000 648k/s +solaris 2.4 486 50mhz - gcc 2.6.3 - assembler 65,000 522k/s +HPUX 10 - 9000/887 - k&r cc (default compiler) - UNROLL PTR 76,000 608k/s +solaris 2.4 486 50mhz - gcc 2.6.3 - UNROLL RISC2 43,500 344k/s +AIX - old slow one :-) - cc - 39,000 312k/s + +Notes. +[1] For the ultra sparc, SunC 4.0 + cc -xtarget=ultra -xarch=v8plus -Xa -xO5, running 'des_opts' + gives a speed of 344,000 des/s while 'speed' gives 459,000 des/s. + I'll record the higher since it is coming from the library but it + is all rather weird. +[2] Similar to the ultra sparc ([1]), 181,000 for 'des_opts' vs 175,000. +[3] I was unable to get access to this machine when it was not heavily loaded. + As such, my timing program was never able to get more that %30 of the CPU. + This would cause the program to give much lower speed numbers because + it would be 'fighting' to stay in the cache with the other CPU burning + processes. diff --git a/libs/openssl/crypto/des/pcbc_enc.c b/libs/openssl/crypto/des/pcbc_enc.c new file mode 100644 index 00000000..144d5ed8 --- /dev/null +++ b/libs/openssl/crypto/des/pcbc_enc.c @@ -0,0 +1,115 @@ +/* crypto/des/pcbc_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +void DES_pcbc_encrypt(const unsigned char *input, unsigned char *output, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, int enc) +{ + register DES_LONG sin0, sin1, xor0, xor1, tout0, tout1; + DES_LONG tin[2]; + const unsigned char *in; + unsigned char *out, *iv; + + in = input; + out = output; + iv = &(*ivec)[0]; + + if (enc) { + c2l(iv, xor0); + c2l(iv, xor1); + for (; length > 0; length -= 8) { + if (length >= 8) { + c2l(in, sin0); + c2l(in, sin1); + } else + c2ln(in, sin0, sin1, length); + tin[0] = sin0 ^ xor0; + tin[1] = sin1 ^ xor1; + DES_encrypt1((DES_LONG *)tin, schedule, DES_ENCRYPT); + tout0 = tin[0]; + tout1 = tin[1]; + xor0 = sin0 ^ tout0; + xor1 = sin1 ^ tout1; + l2c(tout0, out); + l2c(tout1, out); + } + } else { + c2l(iv, xor0); + c2l(iv, xor1); + for (; length > 0; length -= 8) { + c2l(in, sin0); + c2l(in, sin1); + tin[0] = sin0; + tin[1] = sin1; + DES_encrypt1((DES_LONG *)tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + if (length >= 8) { + l2c(tout0, out); + l2c(tout1, out); + } else + l2cn(tout0, tout1, out, length); + xor0 = tout0 ^ sin0; + xor1 = tout1 ^ sin1; + } + } + tin[0] = tin[1] = 0; + sin0 = sin1 = xor0 = xor1 = tout0 = tout1 = 0; +} diff --git a/libs/openssl/crypto/des/qud_cksm.c b/libs/openssl/crypto/des/qud_cksm.c new file mode 100644 index 00000000..2a168a57 --- /dev/null +++ b/libs/openssl/crypto/des/qud_cksm.c @@ -0,0 +1,143 @@ +/* crypto/des/qud_cksm.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * From "Message Authentication" R.R. Jueneman, S.M. Matyas, C.H. Meyer IEEE + * Communications Magazine Sept 1985 Vol. 23 No. 9 p 29-40 This module in + * only based on the code in this paper and is almost definitely not the same + * as the MIT implementation. + */ +#include "des_locl.h" + +/* bug fix for dos - 7/6/91 - Larry hughes@logos.ucs.indiana.edu */ +#define Q_B0(a) (((DES_LONG)(a))) +#define Q_B1(a) (((DES_LONG)(a))<<8) +#define Q_B2(a) (((DES_LONG)(a))<<16) +#define Q_B3(a) (((DES_LONG)(a))<<24) + +/* used to scramble things a bit */ +/* Got the value MIT uses via brute force :-) 2/10/90 eay */ +#define NOISE ((DES_LONG)83653421L) + +DES_LONG DES_quad_cksum(const unsigned char *input, DES_cblock output[], + long length, int out_count, DES_cblock *seed) +{ + DES_LONG z0, z1, t0, t1; + int i; + long l; + const unsigned char *cp; +#ifdef _CRAY + struct lp_st { + int a:32; + int b:32; + } *lp; +#else + DES_LONG *lp; +#endif + + if (out_count < 1) + out_count = 1; +#ifdef _CRAY + lp = (struct lp_st *)&(output[0])[0]; +#else + lp = (DES_LONG *)&(output[0])[0]; +#endif + + z0 = Q_B0((*seed)[0]) | Q_B1((*seed)[1]) | Q_B2((*seed)[2]) | + Q_B3((*seed)[3]); + z1 = Q_B0((*seed)[4]) | Q_B1((*seed)[5]) | Q_B2((*seed)[6]) | + Q_B3((*seed)[7]); + + for (i = 0; ((i < 4) && (i < out_count)); i++) { + cp = input; + l = length; + while (l > 0) { + if (l > 1) { + t0 = (DES_LONG)(*(cp++)); + t0 |= (DES_LONG)Q_B1(*(cp++)); + l--; + } else + t0 = (DES_LONG)(*(cp++)); + l--; + /* add */ + t0 += z0; + t0 &= 0xffffffffL; + t1 = z1; + /* square, well sort of square */ + z0 = ((((t0 * t0) & 0xffffffffL) + ((t1 * t1) & 0xffffffffL)) + & 0xffffffffL) % 0x7fffffffL; + z1 = ((t0 * ((t1 + NOISE) & 0xffffffffL)) & 0xffffffffL) % + 0x7fffffffL; + } + if (lp != NULL) { + /* + * The MIT library assumes that the checksum is composed of + * 2*out_count 32 bit ints + */ +#ifdef _CRAY + (*lp).a = z0; + (*lp).b = z1; + lp++; +#else + *lp++ = z0; + *lp++ = z1; +#endif + } + } + return (z0); +} diff --git a/libs/openssl/crypto/des/rand_key.c b/libs/openssl/crypto/des/rand_key.c new file mode 100644 index 00000000..b75cc5f9 --- /dev/null +++ b/libs/openssl/crypto/des/rand_key.c @@ -0,0 +1,67 @@ +/* crypto/des/rand_key.c */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +int DES_random_key(DES_cblock *ret) +{ + do { + if (RAND_bytes((unsigned char *)ret, sizeof(DES_cblock)) != 1) + return (0); + } while (DES_is_weak_key(ret)); + DES_set_odd_parity(ret); + return (1); +} diff --git a/libs/openssl/crypto/des/read2pwd.c b/libs/openssl/crypto/des/read2pwd.c new file mode 100644 index 00000000..01e275f3 --- /dev/null +++ b/libs/openssl/crypto/des/read2pwd.c @@ -0,0 +1,140 @@ +/* crypto/des/read2pwd.c */ +/* ==================================================================== + * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +int DES_read_password(DES_cblock *key, const char *prompt, int verify) +{ + int ok; + char buf[BUFSIZ], buff[BUFSIZ]; + + if ((ok = UI_UTIL_read_pw(buf, buff, BUFSIZ, prompt, verify)) == 0) + DES_string_to_key(buf, key); + OPENSSL_cleanse(buf, BUFSIZ); + OPENSSL_cleanse(buff, BUFSIZ); + return (ok); +} + +int DES_read_2passwords(DES_cblock *key1, DES_cblock *key2, + const char *prompt, int verify) +{ + int ok; + char buf[BUFSIZ], buff[BUFSIZ]; + + if ((ok = UI_UTIL_read_pw(buf, buff, BUFSIZ, prompt, verify)) == 0) + DES_string_to_2keys(buf, key1, key2); + OPENSSL_cleanse(buf, BUFSIZ); + OPENSSL_cleanse(buff, BUFSIZ); + return (ok); +} diff --git a/libs/openssl/crypto/des/read_pwd.c b/libs/openssl/crypto/des/read_pwd.c new file mode 100644 index 00000000..16ba0a9e --- /dev/null +++ b/libs/openssl/crypto/des/read_pwd.c @@ -0,0 +1,533 @@ +/* crypto/des/read_pwd.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_WIN32) +# ifdef OPENSSL_UNISTD +# include OPENSSL_UNISTD +# else +# include +# endif +/* + * If unistd.h defines _POSIX_VERSION, we conclude that we are on a POSIX + * system and have sigaction and termios. + */ +# if defined(_POSIX_VERSION) + +# define SIGACTION +# if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) +# define TERMIOS +# endif + +# endif +#endif + +/* Define this if you have sigaction() */ +/* #define SIGACTION */ + +#ifdef WIN16TTY +# undef OPENSSL_SYS_WIN16 +# undef _WINDOWS +# include +#endif + +/* 06-Apr-92 Luke Brennan Support for VMS */ +#include "des_locl.h" +#include "cryptlib.h" +#include +#include +#include +#include +#include + +#ifdef OPENSSL_SYS_VMS /* prototypes for sys$whatever */ +# include +# ifdef __DECC +# pragma message disable DOLLARID +# endif +#endif + +#ifdef WIN_CONSOLE_BUG +# include +# ifndef OPENSSL_SYS_WINCE +# include +# endif +#endif + +/* + * There are 5 types of terminal interface supported, TERMIO, TERMIOS, VMS, + * MSDOS and SGTTY + */ + +#if defined(__sgi) && !defined(TERMIOS) +# define TERMIOS +# undef TERMIO +# undef SGTTY +#endif + +#if defined(linux) && !defined(TERMIO) +# undef TERMIOS +# define TERMIO +# undef SGTTY +#endif + +#ifdef _LIBC +# undef TERMIOS +# define TERMIO +# undef SGTTY +#endif + +#if !defined(TERMIO) && !defined(TERMIOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MSDOS) && !defined(MAC_OS_pre_X) && !defined(MAC_OS_GUSI_SOURCE) +# undef TERMIOS +# undef TERMIO +# define SGTTY +#endif + +#if defined(OPENSSL_SYS_VXWORKS) +# undef TERMIOS +# undef TERMIO +# undef SGTTY +#endif + +#ifdef TERMIOS +# include +# define TTY_STRUCT struct termios +# define TTY_FLAGS c_lflag +# define TTY_get(tty,data) tcgetattr(tty,data) +# define TTY_set(tty,data) tcsetattr(tty,TCSANOW,data) +#endif + +#ifdef TERMIO +# include +# define TTY_STRUCT struct termio +# define TTY_FLAGS c_lflag +# define TTY_get(tty,data) ioctl(tty,TCGETA,data) +# define TTY_set(tty,data) ioctl(tty,TCSETA,data) +#endif + +#ifdef SGTTY +# include +# define TTY_STRUCT struct sgttyb +# define TTY_FLAGS sg_flags +# define TTY_get(tty,data) ioctl(tty,TIOCGETP,data) +# define TTY_set(tty,data) ioctl(tty,TIOCSETP,data) +#endif + +#if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(MAC_OS_pre_X) +# include +#endif + +#if defined(OPENSSL_SYS_MSDOS) && !defined(__CYGWIN32__) && !defined(OPENSSL_SYS_WINCE) +# include +# define fgets(a,b,c) noecho_fgets(a,b,c) +#endif + +#ifdef OPENSSL_SYS_VMS +# include +# include +# include +# include +struct IOSB { + short iosb$w_value; + short iosb$w_count; + long iosb$l_info; +}; +#endif + +#if defined(MAC_OS_pre_X) || defined(MAC_OS_GUSI_SOURCE) +/* + * This one needs work. As a matter of fact the code is unoperational + * and this is only a trick to get it compiled. + * + */ +# define TTY_STRUCT int +#endif + +#ifndef NX509_SIG +# define NX509_SIG 32 +#endif + +static void read_till_nl(FILE *); +static void recsig(int); +static void pushsig(void); +static void popsig(void); +#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) +static int noecho_fgets(char *buf, int size, FILE *tty); +#endif +#ifdef SIGACTION +static struct sigaction savsig[NX509_SIG]; +#else +static void (*savsig[NX509_SIG]) (int); +#endif +static jmp_buf save; + +int des_read_pw_string(char *buf, int length, const char *prompt, int verify) +{ + char buff[BUFSIZ]; + int ret; + + ret = + des_read_pw(buf, buff, (length > BUFSIZ) ? BUFSIZ : length, prompt, + verify); + OPENSSL_cleanse(buff, BUFSIZ); + return (ret); +} + +#ifdef OPENSSL_SYS_WINCE + +int des_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify) +{ + memset(buf, 0, size); + memset(buff, 0, size); + return (0); +} + +#elif defined(OPENSSL_SYS_WIN16) + +int des_read_pw(char *buf, char *buff, int size, char *prompt, int verify) +{ + memset(buf, 0, size); + memset(buff, 0, size); + return (0); +} + +#else /* !OPENSSL_SYS_WINCE && !OPENSSL_SYS_WIN16 */ + +static void read_till_nl(FILE *in) +{ +# define SIZE 4 + char buf[SIZE + 1]; + + do { + fgets(buf, SIZE, in); + } while (strchr(buf, '\n') == NULL); +} + +/* return 0 if ok, 1 (or -1) otherwise */ +int des_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify) +{ +# ifdef OPENSSL_SYS_VMS + struct IOSB iosb; + $DESCRIPTOR(terminal, "TT"); + long tty_orig[3], tty_new[3]; + long status; + unsigned short channel = 0; +# else +# if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) + TTY_STRUCT tty_orig, tty_new; +# endif +# endif + int number; + int ok; + /* + * statics are simply to avoid warnings about longjmp clobbering things + */ + static int ps; + int is_a_tty; + static FILE *tty; + char *p; + + if (setjmp(save)) { + ok = 0; + goto error; + } + + number = 5; + ok = 0; + ps = 0; + is_a_tty = 1; + tty = NULL; + +# ifdef OPENSSL_SYS_MSDOS + if ((tty = fopen("con", "r")) == NULL) + tty = stdin; +# elif defined(MAC_OS_pre_X) || defined(OPENSSL_SYS_VXWORKS) + tty = stdin; +# else +# ifndef OPENSSL_SYS_MPE + if ((tty = fopen("/dev/tty", "r")) == NULL) +# endif + tty = stdin; +# endif + +# if defined(TTY_get) && !defined(OPENSSL_SYS_VMS) + if (TTY_get(fileno(tty), &tty_orig) == -1) { +# ifdef ENOTTY + if (errno == ENOTTY) + is_a_tty = 0; + else +# endif +# ifdef EINVAL + /* + * Ariel Glenn ariel@columbia.edu reports that solaris can return + * EINVAL instead. This should be ok + */ + if (errno == EINVAL) + is_a_tty = 0; + else +# endif + return (-1); + } + memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig)); +# endif +# ifdef OPENSSL_SYS_VMS + status = sys$assign(&terminal, &channel, 0, 0); + if (status != SS$_NORMAL) + return (-1); + status = + sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12, 0, 0, + 0, 0); + if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) + return (-1); +# endif + + pushsig(); + ps = 1; + +# ifdef TTY_FLAGS + tty_new.TTY_FLAGS &= ~ECHO; +# endif + +# if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) + if (is_a_tty && (TTY_set(fileno(tty), &tty_new) == -1)) +# ifdef OPENSSL_SYS_MPE + ; /* MPE lies -- echo really has been disabled */ +# else + return (-1); +# endif +# endif +# ifdef OPENSSL_SYS_VMS + tty_new[0] = tty_orig[0]; + tty_new[1] = tty_orig[1] | TT$M_NOECHO; + tty_new[2] = tty_orig[2]; + status = + sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0, + 0); + if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) + return (-1); +# endif + ps = 2; + + while ((!ok) && (number--)) { + fputs(prompt, stderr); + fflush(stderr); + + buf[0] = '\0'; + fgets(buf, size, tty); + if (feof(tty)) + goto error; + if (ferror(tty)) + goto error; + if ((p = (char *)strchr(buf, '\n')) != NULL) + *p = '\0'; + else + read_till_nl(tty); + if (verify) { + fprintf(stderr, "\nVerifying password - %s", prompt); + fflush(stderr); + buff[0] = '\0'; + fgets(buff, size, tty); + if (feof(tty)) + goto error; + if ((p = (char *)strchr(buff, '\n')) != NULL) + *p = '\0'; + else + read_till_nl(tty); + + if (strcmp(buf, buff) != 0) { + fprintf(stderr, "\nVerify failure"); + fflush(stderr); + break; + /* continue; */ + } + } + ok = 1; + } + + error: + fprintf(stderr, "\n"); +# if 0 + perror("fgets(tty)"); +# endif + /* What can we do if there is an error? */ +# if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) + if (ps >= 2) + TTY_set(fileno(tty), &tty_orig); +# endif +# ifdef OPENSSL_SYS_VMS + if (ps >= 2) + status = + sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_orig, 12, 0, 0, + 0, 0); +# endif + + if (ps >= 1) + popsig(); + if (stdin != tty) + fclose(tty); +# ifdef OPENSSL_SYS_VMS + status = sys$dassgn(channel); +# endif + return (!ok); +} + +static void pushsig(void) +{ + int i; +# ifdef SIGACTION + struct sigaction sa; + + memset(&sa, 0, sizeof sa); + sa.sa_handler = recsig; +# endif + + for (i = 1; i < NX509_SIG; i++) { +# ifdef SIGUSR1 + if (i == SIGUSR1) + continue; +# endif +# ifdef SIGUSR2 + if (i == SIGUSR2) + continue; +# endif +# ifdef SIGACTION + sigaction(i, &sa, &savsig[i]); +# else + savsig[i] = signal(i, recsig); +# endif + } + +# ifdef SIGWINCH + signal(SIGWINCH, SIG_DFL); +# endif +} + +static void popsig(void) +{ + int i; + + for (i = 1; i < NX509_SIG; i++) { +# ifdef SIGUSR1 + if (i == SIGUSR1) + continue; +# endif +# ifdef SIGUSR2 + if (i == SIGUSR2) + continue; +# endif +# ifdef SIGACTION + sigaction(i, &savsig[i], NULL); +# else + signal(i, savsig[i]); +# endif + } +} + +static void recsig(int i) +{ + longjmp(save, 1); +# ifdef LINT + i = i; +# endif +} + +# ifdef OPENSSL_SYS_MSDOS +static int noecho_fgets(char *buf, int size, FILE *tty) +{ + int i; + char *p; + + p = buf; + for (;;) { + if (size == 0) { + *p = '\0'; + break; + } + size--; +# ifdef WIN16TTY + i = _inchar(); +# else + i = getch(); +# endif + if (i == '\r') + i = '\n'; + *(p++) = i; + if (i == '\n') { + *p = '\0'; + break; + } + } +# ifdef WIN_CONSOLE_BUG + /* + * Win95 has several evil console bugs: one of these is that the last + * character read using getch() is passed to the next read: this is + * usually a CR so this can be trouble. No STDIO fix seems to work but + * flushing the console appears to do the trick. + */ + { + HANDLE inh; + inh = GetStdHandle(STD_INPUT_HANDLE); + FlushConsoleInputBuffer(inh); + } +# endif + return (strlen(buf)); +} +# endif +#endif /* !OPENSSL_SYS_WINCE && !WIN16 */ diff --git a/libs/openssl/crypto/des/rpc_des.h b/libs/openssl/crypto/des/rpc_des.h new file mode 100644 index 00000000..4db9062d --- /dev/null +++ b/libs/openssl/crypto/des/rpc_des.h @@ -0,0 +1,130 @@ +/* crypto/des/rpc_des.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* @(#)des.h 2.2 88/08/10 4.0 RPCSRC; from 2.7 88/02/08 SMI */ +/*- + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* + * Generic DES driver interface + * Keep this file hardware independent! + * Copyright (c) 1986 by Sun Microsystems, Inc. + */ + +#define DES_MAXLEN 65536 /* maximum # of bytes to encrypt */ +#define DES_QUICKLEN 16 /* maximum # of bytes to encrypt quickly */ + +#ifdef HEADER_DES_H +# undef ENCRYPT +# undef DECRYPT +#endif + +enum desdir { ENCRYPT, DECRYPT }; +enum desmode { CBC, ECB }; + +/* + * parameters to ioctl call + */ +struct desparams { + unsigned char des_key[8]; /* key (with low bit parity) */ + enum desdir des_dir; /* direction */ + enum desmode des_mode; /* mode */ + unsigned char des_ivec[8]; /* input vector */ + unsigned des_len; /* number of bytes to crypt */ + union { + unsigned char UDES_data[DES_QUICKLEN]; + unsigned char *UDES_buf; + } UDES; +#define des_data UDES.UDES_data /* direct data here if quick */ +#define des_buf UDES.UDES_buf /* otherwise, pointer to data */ +}; + +/* + * Encrypt an arbitrary sized buffer + */ +#define DESIOCBLOCK _IOWR('d', 6, struct desparams) + +/* + * Encrypt of small amount of data, quickly + */ +#define DESIOCQUICK _IOWR('d', 7, struct desparams) diff --git a/libs/openssl/crypto/des/rpc_enc.c b/libs/openssl/crypto/des/rpc_enc.c new file mode 100644 index 00000000..f5a84c5b --- /dev/null +++ b/libs/openssl/crypto/des/rpc_enc.c @@ -0,0 +1,100 @@ +/* crypto/des/rpc_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "rpc_des.h" +#include "des_locl.h" +#include "des_ver.h" + +int _des_crypt(char *buf, int len, struct desparams *desp); +int _des_crypt(char *buf, int len, struct desparams *desp) +{ + DES_key_schedule ks; + int enc; + + DES_set_key_unchecked(&desp->des_key, &ks); + enc = (desp->des_dir == ENCRYPT) ? DES_ENCRYPT : DES_DECRYPT; + + if (desp->des_mode == CBC) + DES_ecb_encrypt((const_DES_cblock *)desp->UDES.UDES_buf, + (DES_cblock *)desp->UDES.UDES_buf, &ks, enc); + else { + DES_ncbc_encrypt(desp->UDES.UDES_buf, desp->UDES.UDES_buf, + len, &ks, &desp->des_ivec, enc); +#ifdef undef + /* + * len will always be %8 if called from common_crypt in secure_rpc. + * Libdes's cbc encrypt does not copy back the iv, so we have to do + * it here. + */ + /* It does now :-) eay 20/09/95 */ + + a = (char *)&(desp->UDES.UDES_buf[len - 8]); + b = (char *)&(desp->des_ivec[0]); + + *(a++) = *(b++); + *(a++) = *(b++); + *(a++) = *(b++); + *(a++) = *(b++); + *(a++) = *(b++); + *(a++) = *(b++); + *(a++) = *(b++); + *(a++) = *(b++); +#endif + } + return (1); +} diff --git a/libs/openssl/crypto/des/rpw.c b/libs/openssl/crypto/des/rpw.c new file mode 100644 index 00000000..ab65eaca --- /dev/null +++ b/libs/openssl/crypto/des/rpw.c @@ -0,0 +1,94 @@ +/* crypto/des/rpw.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +int main(int argc, char *argv[]) +{ + DES_cblock k, k1; + int i; + + printf("read passwd\n"); + if ((i = des_read_password(&k, "Enter password:", 0)) == 0) { + printf("password = "); + for (i = 0; i < 8; i++) + printf("%02x ", k[i]); + } else + printf("error %d\n", i); + printf("\n"); + printf("read 2passwds and verify\n"); + if ((i = des_read_2passwords(&k, &k1, + "Enter verified password:", 1)) == 0) { + printf("password1 = "); + for (i = 0; i < 8; i++) + printf("%02x ", k[i]); + printf("\n"); + printf("password2 = "); + for (i = 0; i < 8; i++) + printf("%02x ", k1[i]); + printf("\n"); + exit(1); + } else { + printf("error %d\n", i); + exit(0); + } +#ifdef LINT + return (0); +#endif +} diff --git a/libs/openssl/crypto/des/set_key.c b/libs/openssl/crypto/des/set_key.c new file mode 100644 index 00000000..8fd8fe14 --- /dev/null +++ b/libs/openssl/crypto/des/set_key.c @@ -0,0 +1,447 @@ +/* crypto/des/set_key.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/*- + * set_key.c v 1.4 eay 24/9/91 + * 1.4 Speed up by 400% :-) + * 1.3 added register declarations. + * 1.2 unrolled make_key_sched a bit more + * 1.1 added norm_expand_bits + * 1.0 First working version + */ +#include +#include "des_locl.h" + +OPENSSL_IMPLEMENT_GLOBAL(int, DES_check_key, 0) + /* + * defaults to false + */ +static const unsigned char odd_parity[256] = { + 1, 1, 2, 2, 4, 4, 7, 7, 8, 8, 11, 11, 13, 13, 14, 14, + 16, 16, 19, 19, 21, 21, 22, 22, 25, 25, 26, 26, 28, 28, 31, 31, + 32, 32, 35, 35, 37, 37, 38, 38, 41, 41, 42, 42, 44, 44, 47, 47, + 49, 49, 50, 50, 52, 52, 55, 55, 56, 56, 59, 59, 61, 61, 62, 62, + 64, 64, 67, 67, 69, 69, 70, 70, 73, 73, 74, 74, 76, 76, 79, 79, + 81, 81, 82, 82, 84, 84, 87, 87, 88, 88, 91, 91, 93, 93, 94, 94, + 97, 97, 98, 98, 100, 100, 103, 103, 104, 104, 107, 107, 109, 109, 110, + 110, + 112, 112, 115, 115, 117, 117, 118, 118, 121, 121, 122, 122, 124, 124, 127, + 127, + 128, 128, 131, 131, 133, 133, 134, 134, 137, 137, 138, 138, 140, 140, 143, + 143, + 145, 145, 146, 146, 148, 148, 151, 151, 152, 152, 155, 155, 157, 157, 158, + 158, + 161, 161, 162, 162, 164, 164, 167, 167, 168, 168, 171, 171, 173, 173, 174, + 174, + 176, 176, 179, 179, 181, 181, 182, 182, 185, 185, 186, 186, 188, 188, 191, + 191, + 193, 193, 194, 194, 196, 196, 199, 199, 200, 200, 203, 203, 205, 205, 206, + 206, + 208, 208, 211, 211, 213, 213, 214, 214, 217, 217, 218, 218, 220, 220, 223, + 223, + 224, 224, 227, 227, 229, 229, 230, 230, 233, 233, 234, 234, 236, 236, 239, + 239, + 241, 241, 242, 242, 244, 244, 247, 247, 248, 248, 251, 251, 253, 253, 254, + 254 +}; + +void DES_set_odd_parity(DES_cblock *key) +{ + unsigned int i; + + for (i = 0; i < DES_KEY_SZ; i++) + (*key)[i] = odd_parity[(*key)[i]]; +} + +int DES_check_key_parity(const_DES_cblock *key) +{ + unsigned int i; + + for (i = 0; i < DES_KEY_SZ; i++) { + if ((*key)[i] != odd_parity[(*key)[i]]) + return (0); + } + return (1); +} + +/*- + * Weak and semi week keys as take from + * %A D.W. Davies + * %A W.L. Price + * %T Security for Computer Networks + * %I John Wiley & Sons + * %D 1984 + * Many thanks to smb@ulysses.att.com (Steven Bellovin) for the reference + * (and actual cblock values). + */ +#define NUM_WEAK_KEY 16 +static const DES_cblock weak_keys[NUM_WEAK_KEY] = { + /* weak keys */ + {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}, + {0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE}, + {0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E}, + {0xE0, 0xE0, 0xE0, 0xE0, 0xF1, 0xF1, 0xF1, 0xF1}, + /* semi-weak keys */ + {0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE}, + {0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01, 0xFE, 0x01}, + {0x1F, 0xE0, 0x1F, 0xE0, 0x0E, 0xF1, 0x0E, 0xF1}, + {0xE0, 0x1F, 0xE0, 0x1F, 0xF1, 0x0E, 0xF1, 0x0E}, + {0x01, 0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1}, + {0xE0, 0x01, 0xE0, 0x01, 0xF1, 0x01, 0xF1, 0x01}, + {0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E, 0xFE}, + {0xFE, 0x1F, 0xFE, 0x1F, 0xFE, 0x0E, 0xFE, 0x0E}, + {0x01, 0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E}, + {0x1F, 0x01, 0x1F, 0x01, 0x0E, 0x01, 0x0E, 0x01}, + {0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE}, + {0xFE, 0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1} +}; + +int DES_is_weak_key(const_DES_cblock *key) +{ + int i; + + for (i = 0; i < NUM_WEAK_KEY; i++) + /* + * Added == 0 to comparison, I obviously don't run this section very + * often :-(, thanks to engineering@MorningStar.Com for the fix eay + * 93/06/29 Another problem, I was comparing only the first 4 bytes, + * 97/03/18 + */ + if (memcmp(weak_keys[i], key, sizeof(DES_cblock)) == 0) + return (1); + return (0); +} + +/*- + * NOW DEFINED IN des_local.h + * See ecb_encrypt.c for a pseudo description of these macros. + * #define PERM_OP(a,b,t,n,m) ((t)=((((a)>>(n))^(b))&(m)),\ + * (b)^=(t),\ + * (a)=((a)^((t)<<(n)))) + */ + +#define HPERM_OP(a,t,n,m) ((t)=((((a)<<(16-(n)))^(a))&(m)),\ + (a)=(a)^(t)^(t>>(16-(n)))) + +static const DES_LONG des_skb[8][64] = { + { + /* for C bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ + 0x00000000L, 0x00000010L, 0x20000000L, 0x20000010L, + 0x00010000L, 0x00010010L, 0x20010000L, 0x20010010L, + 0x00000800L, 0x00000810L, 0x20000800L, 0x20000810L, + 0x00010800L, 0x00010810L, 0x20010800L, 0x20010810L, + 0x00000020L, 0x00000030L, 0x20000020L, 0x20000030L, + 0x00010020L, 0x00010030L, 0x20010020L, 0x20010030L, + 0x00000820L, 0x00000830L, 0x20000820L, 0x20000830L, + 0x00010820L, 0x00010830L, 0x20010820L, 0x20010830L, + 0x00080000L, 0x00080010L, 0x20080000L, 0x20080010L, + 0x00090000L, 0x00090010L, 0x20090000L, 0x20090010L, + 0x00080800L, 0x00080810L, 0x20080800L, 0x20080810L, + 0x00090800L, 0x00090810L, 0x20090800L, 0x20090810L, + 0x00080020L, 0x00080030L, 0x20080020L, 0x20080030L, + 0x00090020L, 0x00090030L, 0x20090020L, 0x20090030L, + 0x00080820L, 0x00080830L, 0x20080820L, 0x20080830L, + 0x00090820L, 0x00090830L, 0x20090820L, 0x20090830L, + }, + { + /* for C bits (numbered as per FIPS 46) 7 8 10 11 12 13 */ + 0x00000000L, 0x02000000L, 0x00002000L, 0x02002000L, + 0x00200000L, 0x02200000L, 0x00202000L, 0x02202000L, + 0x00000004L, 0x02000004L, 0x00002004L, 0x02002004L, + 0x00200004L, 0x02200004L, 0x00202004L, 0x02202004L, + 0x00000400L, 0x02000400L, 0x00002400L, 0x02002400L, + 0x00200400L, 0x02200400L, 0x00202400L, 0x02202400L, + 0x00000404L, 0x02000404L, 0x00002404L, 0x02002404L, + 0x00200404L, 0x02200404L, 0x00202404L, 0x02202404L, + 0x10000000L, 0x12000000L, 0x10002000L, 0x12002000L, + 0x10200000L, 0x12200000L, 0x10202000L, 0x12202000L, + 0x10000004L, 0x12000004L, 0x10002004L, 0x12002004L, + 0x10200004L, 0x12200004L, 0x10202004L, 0x12202004L, + 0x10000400L, 0x12000400L, 0x10002400L, 0x12002400L, + 0x10200400L, 0x12200400L, 0x10202400L, 0x12202400L, + 0x10000404L, 0x12000404L, 0x10002404L, 0x12002404L, + 0x10200404L, 0x12200404L, 0x10202404L, 0x12202404L, + }, + { + /* for C bits (numbered as per FIPS 46) 14 15 16 17 19 20 */ + 0x00000000L, 0x00000001L, 0x00040000L, 0x00040001L, + 0x01000000L, 0x01000001L, 0x01040000L, 0x01040001L, + 0x00000002L, 0x00000003L, 0x00040002L, 0x00040003L, + 0x01000002L, 0x01000003L, 0x01040002L, 0x01040003L, + 0x00000200L, 0x00000201L, 0x00040200L, 0x00040201L, + 0x01000200L, 0x01000201L, 0x01040200L, 0x01040201L, + 0x00000202L, 0x00000203L, 0x00040202L, 0x00040203L, + 0x01000202L, 0x01000203L, 0x01040202L, 0x01040203L, + 0x08000000L, 0x08000001L, 0x08040000L, 0x08040001L, + 0x09000000L, 0x09000001L, 0x09040000L, 0x09040001L, + 0x08000002L, 0x08000003L, 0x08040002L, 0x08040003L, + 0x09000002L, 0x09000003L, 0x09040002L, 0x09040003L, + 0x08000200L, 0x08000201L, 0x08040200L, 0x08040201L, + 0x09000200L, 0x09000201L, 0x09040200L, 0x09040201L, + 0x08000202L, 0x08000203L, 0x08040202L, 0x08040203L, + 0x09000202L, 0x09000203L, 0x09040202L, 0x09040203L, + }, + { + /* for C bits (numbered as per FIPS 46) 21 23 24 26 27 28 */ + 0x00000000L, 0x00100000L, 0x00000100L, 0x00100100L, + 0x00000008L, 0x00100008L, 0x00000108L, 0x00100108L, + 0x00001000L, 0x00101000L, 0x00001100L, 0x00101100L, + 0x00001008L, 0x00101008L, 0x00001108L, 0x00101108L, + 0x04000000L, 0x04100000L, 0x04000100L, 0x04100100L, + 0x04000008L, 0x04100008L, 0x04000108L, 0x04100108L, + 0x04001000L, 0x04101000L, 0x04001100L, 0x04101100L, + 0x04001008L, 0x04101008L, 0x04001108L, 0x04101108L, + 0x00020000L, 0x00120000L, 0x00020100L, 0x00120100L, + 0x00020008L, 0x00120008L, 0x00020108L, 0x00120108L, + 0x00021000L, 0x00121000L, 0x00021100L, 0x00121100L, + 0x00021008L, 0x00121008L, 0x00021108L, 0x00121108L, + 0x04020000L, 0x04120000L, 0x04020100L, 0x04120100L, + 0x04020008L, 0x04120008L, 0x04020108L, 0x04120108L, + 0x04021000L, 0x04121000L, 0x04021100L, 0x04121100L, + 0x04021008L, 0x04121008L, 0x04021108L, 0x04121108L, + }, + { + /* for D bits (numbered as per FIPS 46) 1 2 3 4 5 6 */ + 0x00000000L, 0x10000000L, 0x00010000L, 0x10010000L, + 0x00000004L, 0x10000004L, 0x00010004L, 0x10010004L, + 0x20000000L, 0x30000000L, 0x20010000L, 0x30010000L, + 0x20000004L, 0x30000004L, 0x20010004L, 0x30010004L, + 0x00100000L, 0x10100000L, 0x00110000L, 0x10110000L, + 0x00100004L, 0x10100004L, 0x00110004L, 0x10110004L, + 0x20100000L, 0x30100000L, 0x20110000L, 0x30110000L, + 0x20100004L, 0x30100004L, 0x20110004L, 0x30110004L, + 0x00001000L, 0x10001000L, 0x00011000L, 0x10011000L, + 0x00001004L, 0x10001004L, 0x00011004L, 0x10011004L, + 0x20001000L, 0x30001000L, 0x20011000L, 0x30011000L, + 0x20001004L, 0x30001004L, 0x20011004L, 0x30011004L, + 0x00101000L, 0x10101000L, 0x00111000L, 0x10111000L, + 0x00101004L, 0x10101004L, 0x00111004L, 0x10111004L, + 0x20101000L, 0x30101000L, 0x20111000L, 0x30111000L, + 0x20101004L, 0x30101004L, 0x20111004L, 0x30111004L, + }, + { + /* for D bits (numbered as per FIPS 46) 8 9 11 12 13 14 */ + 0x00000000L, 0x08000000L, 0x00000008L, 0x08000008L, + 0x00000400L, 0x08000400L, 0x00000408L, 0x08000408L, + 0x00020000L, 0x08020000L, 0x00020008L, 0x08020008L, + 0x00020400L, 0x08020400L, 0x00020408L, 0x08020408L, + 0x00000001L, 0x08000001L, 0x00000009L, 0x08000009L, + 0x00000401L, 0x08000401L, 0x00000409L, 0x08000409L, + 0x00020001L, 0x08020001L, 0x00020009L, 0x08020009L, + 0x00020401L, 0x08020401L, 0x00020409L, 0x08020409L, + 0x02000000L, 0x0A000000L, 0x02000008L, 0x0A000008L, + 0x02000400L, 0x0A000400L, 0x02000408L, 0x0A000408L, + 0x02020000L, 0x0A020000L, 0x02020008L, 0x0A020008L, + 0x02020400L, 0x0A020400L, 0x02020408L, 0x0A020408L, + 0x02000001L, 0x0A000001L, 0x02000009L, 0x0A000009L, + 0x02000401L, 0x0A000401L, 0x02000409L, 0x0A000409L, + 0x02020001L, 0x0A020001L, 0x02020009L, 0x0A020009L, + 0x02020401L, 0x0A020401L, 0x02020409L, 0x0A020409L, + }, + { + /* for D bits (numbered as per FIPS 46) 16 17 18 19 20 21 */ + 0x00000000L, 0x00000100L, 0x00080000L, 0x00080100L, + 0x01000000L, 0x01000100L, 0x01080000L, 0x01080100L, + 0x00000010L, 0x00000110L, 0x00080010L, 0x00080110L, + 0x01000010L, 0x01000110L, 0x01080010L, 0x01080110L, + 0x00200000L, 0x00200100L, 0x00280000L, 0x00280100L, + 0x01200000L, 0x01200100L, 0x01280000L, 0x01280100L, + 0x00200010L, 0x00200110L, 0x00280010L, 0x00280110L, + 0x01200010L, 0x01200110L, 0x01280010L, 0x01280110L, + 0x00000200L, 0x00000300L, 0x00080200L, 0x00080300L, + 0x01000200L, 0x01000300L, 0x01080200L, 0x01080300L, + 0x00000210L, 0x00000310L, 0x00080210L, 0x00080310L, + 0x01000210L, 0x01000310L, 0x01080210L, 0x01080310L, + 0x00200200L, 0x00200300L, 0x00280200L, 0x00280300L, + 0x01200200L, 0x01200300L, 0x01280200L, 0x01280300L, + 0x00200210L, 0x00200310L, 0x00280210L, 0x00280310L, + 0x01200210L, 0x01200310L, 0x01280210L, 0x01280310L, + }, + { + /* for D bits (numbered as per FIPS 46) 22 23 24 25 27 28 */ + 0x00000000L, 0x04000000L, 0x00040000L, 0x04040000L, + 0x00000002L, 0x04000002L, 0x00040002L, 0x04040002L, + 0x00002000L, 0x04002000L, 0x00042000L, 0x04042000L, + 0x00002002L, 0x04002002L, 0x00042002L, 0x04042002L, + 0x00000020L, 0x04000020L, 0x00040020L, 0x04040020L, + 0x00000022L, 0x04000022L, 0x00040022L, 0x04040022L, + 0x00002020L, 0x04002020L, 0x00042020L, 0x04042020L, + 0x00002022L, 0x04002022L, 0x00042022L, 0x04042022L, + 0x00000800L, 0x04000800L, 0x00040800L, 0x04040800L, + 0x00000802L, 0x04000802L, 0x00040802L, 0x04040802L, + 0x00002800L, 0x04002800L, 0x00042800L, 0x04042800L, + 0x00002802L, 0x04002802L, 0x00042802L, 0x04042802L, + 0x00000820L, 0x04000820L, 0x00040820L, 0x04040820L, + 0x00000822L, 0x04000822L, 0x00040822L, 0x04040822L, + 0x00002820L, 0x04002820L, 0x00042820L, 0x04042820L, + 0x00002822L, 0x04002822L, 0x00042822L, 0x04042822L, + } +}; + +int DES_set_key(const_DES_cblock *key, DES_key_schedule *schedule) +{ + if (DES_check_key) { + return DES_set_key_checked(key, schedule); + } else { + DES_set_key_unchecked(key, schedule); + return 0; + } +} + +/*- + * return 0 if key parity is odd (correct), + * return -1 if key parity error, + * return -2 if illegal weak key. + */ +int DES_set_key_checked(const_DES_cblock *key, DES_key_schedule *schedule) +{ + if (!DES_check_key_parity(key)) + return (-1); + if (DES_is_weak_key(key)) + return (-2); + DES_set_key_unchecked(key, schedule); + return 0; +} + +void DES_set_key_unchecked(const_DES_cblock *key, DES_key_schedule *schedule) +#ifdef OPENSSL_FIPS +{ + fips_cipher_abort(DES); + private_DES_set_key_unchecked(key, schedule); +} + +void private_DES_set_key_unchecked(const_DES_cblock *key, + DES_key_schedule *schedule) +#endif +{ + static const int shifts2[16] = + { 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0 }; + register DES_LONG c, d, t, s, t2; + register const unsigned char *in; + register DES_LONG *k; + register int i; + +#ifdef OPENBSD_DEV_CRYPTO + memcpy(schedule->key, key, sizeof schedule->key); + schedule->session = NULL; +#endif + k = &schedule->ks->deslong[0]; + in = &(*key)[0]; + + c2l(in, c); + c2l(in, d); + + /* + * do PC1 in 47 simple operations :-) Thanks to John Fletcher + * (john_fletcher@lccmail.ocf.llnl.gov) for the inspiration. :-) + */ + PERM_OP(d, c, t, 4, 0x0f0f0f0fL); + HPERM_OP(c, t, -2, 0xcccc0000L); + HPERM_OP(d, t, -2, 0xcccc0000L); + PERM_OP(d, c, t, 1, 0x55555555L); + PERM_OP(c, d, t, 8, 0x00ff00ffL); + PERM_OP(d, c, t, 1, 0x55555555L); + d = (((d & 0x000000ffL) << 16L) | (d & 0x0000ff00L) | + ((d & 0x00ff0000L) >> 16L) | ((c & 0xf0000000L) >> 4L)); + c &= 0x0fffffffL; + + for (i = 0; i < ITERATIONS; i++) { + if (shifts2[i]) { + c = ((c >> 2L) | (c << 26L)); + d = ((d >> 2L) | (d << 26L)); + } else { + c = ((c >> 1L) | (c << 27L)); + d = ((d >> 1L) | (d << 27L)); + } + c &= 0x0fffffffL; + d &= 0x0fffffffL; + /* + * could be a few less shifts but I am to lazy at this point in time + * to investigate + */ + s = des_skb[0][(c) & 0x3f] | + des_skb[1][((c >> 6L) & 0x03) | ((c >> 7L) & 0x3c)] | + des_skb[2][((c >> 13L) & 0x0f) | ((c >> 14L) & 0x30)] | + des_skb[3][((c >> 20L) & 0x01) | ((c >> 21L) & 0x06) | + ((c >> 22L) & 0x38)]; + t = des_skb[4][(d) & 0x3f] | + des_skb[5][((d >> 7L) & 0x03) | ((d >> 8L) & 0x3c)] | + des_skb[6][(d >> 15L) & 0x3f] | + des_skb[7][((d >> 21L) & 0x0f) | ((d >> 22L) & 0x30)]; + + /* table contained 0213 4657 */ + t2 = ((t << 16L) | (s & 0x0000ffffL)) & 0xffffffffL; + *(k++) = ROTATE(t2, 30) & 0xffffffffL; + + t2 = ((s >> 16L) | (t & 0xffff0000L)); + *(k++) = ROTATE(t2, 26) & 0xffffffffL; + } +} + +int DES_key_sched(const_DES_cblock *key, DES_key_schedule *schedule) +{ + return (DES_set_key(key, schedule)); +} + +/*- +#undef des_fixup_key_parity +void des_fixup_key_parity(des_cblock *key) + { + des_set_odd_parity(key); + } +*/ diff --git a/libs/openssl/crypto/des/speed.c b/libs/openssl/crypto/des/speed.c new file mode 100644 index 00000000..9a3d929d --- /dev/null +++ b/libs/openssl/crypto/des/speed.c @@ -0,0 +1,299 @@ +/* crypto/des/speed.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */ +/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */ + +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX) +# define TIMES +#endif + +#include + +#include +#include OPENSSL_UNISTD_IO +OPENSSL_DECLARE_EXIT +#ifndef OPENSSL_SYS_NETWARE +# include +# define crypt(c,s) (des_crypt((c),(s))) +#endif +#ifndef _IRIX +# include +#endif +#ifdef TIMES +# include +# include +#endif + /* + * Depending on the VMS version, the tms structure is perhaps defined. + * The __TMS macro will show if it was. If it wasn't defined, we should + * undefine TIMES, since that tells the rest of the program how things + * should be handled. -- Richard Levitte + */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) +# undef TIMES +#endif +#ifndef TIMES +# include +#endif +#if defined(sun) || defined(__ultrix) +# define _POSIX_SOURCE +# include +# include +#endif +#include +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# ifndef _BSD_CLK_TCK_ /* FreeBSD fix */ +# define HZ 100.0 +# else /* _BSD_CLK_TCK_ */ +# define HZ ((double)_BSD_CLK_TCK_) +# endif +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +#endif +#define BUFSIZE ((long)1024) +long run = 0; + +double Time_F(int s); +#ifdef SIGALRM +# if defined(__STDC__) || defined(sgi) || defined(_AIX) +# define SIGRETTYPE void +# else +# define SIGRETTYPE int +# endif + +SIGRETTYPE sig_done(int sig); +SIGRETTYPE sig_done(int sig) +{ + signal(SIGALRM, sig_done); + run = 0; +# ifdef LINT + sig = sig; +# endif +} +#endif + +#define START 0 +#define STOP 1 + +double Time_F(int s) +{ + double ret; +#ifdef TIMES + static struct tms tstart, tend; + + if (s == START) { + times(&tstart); + return (0); + } else { + times(&tend); + ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ; + return ((ret == 0.0) ? 1e-6 : ret); + } +#else /* !times() */ + static struct timeb tstart, tend; + long i; + + if (s == START) { + ftime(&tstart); + return (0); + } else { + ftime(&tend); + i = (long)tend.millitm - (long)tstart.millitm; + ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1e3; + return ((ret == 0.0) ? 1e-6 : ret); + } +#endif +} + +int main(int argc, char **argv) +{ + long count; + static unsigned char buf[BUFSIZE]; + static DES_cblock key = + { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 }; + static DES_cblock key2 = + { 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12 }; + static DES_cblock key3 = + { 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, 0x12, 0x34 }; + DES_key_schedule sch, sch2, sch3; + double a, b, c, d, e; +#ifndef SIGALRM + long ca, cb, cc, cd, ce; +#endif + +#ifndef TIMES + printf("To get the most accurate results, try to run this\n"); + printf("program when this computer is idle.\n"); +#endif + + DES_set_key_unchecked(&key2, &sch2); + DES_set_key_unchecked(&key3, &sch3); + +#ifndef SIGALRM + printf("First we calculate the approximate speed ...\n"); + DES_set_key_unchecked(&key, &sch); + count = 10; + do { + long i; + DES_LONG data[2]; + + count *= 2; + Time_F(START); + for (i = count; i; i--) + DES_encrypt1(data, &sch, DES_ENCRYPT); + d = Time_F(STOP); + } while (d < 3.0); + ca = count; + cb = count * 3; + cc = count * 3 * 8 / BUFSIZE + 1; + cd = count * 8 / BUFSIZE + 1; + ce = count / 20 + 1; + printf("Doing set_key %ld times\n", ca); +# define COND(d) (count != (d)) +# define COUNT(d) (d) +#else +# define COND(c) (run) +# define COUNT(d) (count) + signal(SIGALRM, sig_done); + printf("Doing set_key for 10 seconds\n"); + alarm(10); +#endif + + Time_F(START); + for (count = 0, run = 1; COND(ca); count++) + DES_set_key_unchecked(&key, &sch); + d = Time_F(STOP); + printf("%ld set_key's in %.2f seconds\n", count, d); + a = ((double)COUNT(ca)) / d; + +#ifdef SIGALRM + printf("Doing DES_encrypt's for 10 seconds\n"); + alarm(10); +#else + printf("Doing DES_encrypt %ld times\n", cb); +#endif + Time_F(START); + for (count = 0, run = 1; COND(cb); count++) { + DES_LONG data[2]; + + DES_encrypt1(data, &sch, DES_ENCRYPT); + } + d = Time_F(STOP); + printf("%ld DES_encrypt's in %.2f second\n", count, d); + b = ((double)COUNT(cb) * 8) / d; + +#ifdef SIGALRM + printf("Doing DES_cbc_encrypt on %ld byte blocks for 10 seconds\n", + BUFSIZE); + alarm(10); +#else + printf("Doing DES_cbc_encrypt %ld times on %ld byte blocks\n", cc, + BUFSIZE); +#endif + Time_F(START); + for (count = 0, run = 1; COND(cc); count++) + DES_ncbc_encrypt(buf, buf, BUFSIZE, &sch, &key, DES_ENCRYPT); + d = Time_F(STOP); + printf("%ld DES_cbc_encrypt's of %ld byte blocks in %.2f second\n", + count, BUFSIZE, d); + c = ((double)COUNT(cc) * BUFSIZE) / d; + +#ifdef SIGALRM + printf("Doing DES_ede_cbc_encrypt on %ld byte blocks for 10 seconds\n", + BUFSIZE); + alarm(10); +#else + printf("Doing DES_ede_cbc_encrypt %ld times on %ld byte blocks\n", cd, + BUFSIZE); +#endif + Time_F(START); + for (count = 0, run = 1; COND(cd); count++) + DES_ede3_cbc_encrypt(buf, buf, BUFSIZE, + &sch, &sch2, &sch3, &key, DES_ENCRYPT); + d = Time_F(STOP); + printf("%ld DES_ede_cbc_encrypt's of %ld byte blocks in %.2f second\n", + count, BUFSIZE, d); + d = ((double)COUNT(cd) * BUFSIZE) / d; + +#ifdef SIGALRM + printf("Doing crypt for 10 seconds\n"); + alarm(10); +#else + printf("Doing crypt %ld times\n", ce); +#endif + Time_F(START); + for (count = 0, run = 1; COND(ce); count++) + crypt("testing1", "ef"); + e = Time_F(STOP); + printf("%ld crypts in %.2f second\n", count, e); + e = ((double)COUNT(ce)) / e; + + printf("set_key per sec = %12.2f (%9.3fuS)\n", a, 1.0e6 / a); + printf("DES raw ecb bytes per sec = %12.2f (%9.3fuS)\n", b, 8.0e6 / b); + printf("DES cbc bytes per sec = %12.2f (%9.3fuS)\n", c, 8.0e6 / c); + printf("DES ede cbc bytes per sec = %12.2f (%9.3fuS)\n", d, 8.0e6 / d); + printf("crypt per sec = %12.2f (%9.3fuS)\n", e, 1.0e6 / e); + exit(0); +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS) + return (0); +#endif +} diff --git a/libs/openssl/crypto/des/spr.h b/libs/openssl/crypto/des/spr.h new file mode 100644 index 00000000..e85d3100 --- /dev/null +++ b/libs/openssl/crypto/des/spr.h @@ -0,0 +1,212 @@ +/* crypto/des/spr.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +OPENSSL_GLOBAL const DES_LONG DES_SPtrans[8][64] = { + { + /* nibble 0 */ + 0x02080800L, 0x00080000L, 0x02000002L, 0x02080802L, + 0x02000000L, 0x00080802L, 0x00080002L, 0x02000002L, + 0x00080802L, 0x02080800L, 0x02080000L, 0x00000802L, + 0x02000802L, 0x02000000L, 0x00000000L, 0x00080002L, + 0x00080000L, 0x00000002L, 0x02000800L, 0x00080800L, + 0x02080802L, 0x02080000L, 0x00000802L, 0x02000800L, + 0x00000002L, 0x00000800L, 0x00080800L, 0x02080002L, + 0x00000800L, 0x02000802L, 0x02080002L, 0x00000000L, + 0x00000000L, 0x02080802L, 0x02000800L, 0x00080002L, + 0x02080800L, 0x00080000L, 0x00000802L, 0x02000800L, + 0x02080002L, 0x00000800L, 0x00080800L, 0x02000002L, + 0x00080802L, 0x00000002L, 0x02000002L, 0x02080000L, + 0x02080802L, 0x00080800L, 0x02080000L, 0x02000802L, + 0x02000000L, 0x00000802L, 0x00080002L, 0x00000000L, + 0x00080000L, 0x02000000L, 0x02000802L, 0x02080800L, + 0x00000002L, 0x02080002L, 0x00000800L, 0x00080802L, + }, + { + /* nibble 1 */ + 0x40108010L, 0x00000000L, 0x00108000L, 0x40100000L, + 0x40000010L, 0x00008010L, 0x40008000L, 0x00108000L, + 0x00008000L, 0x40100010L, 0x00000010L, 0x40008000L, + 0x00100010L, 0x40108000L, 0x40100000L, 0x00000010L, + 0x00100000L, 0x40008010L, 0x40100010L, 0x00008000L, + 0x00108010L, 0x40000000L, 0x00000000L, 0x00100010L, + 0x40008010L, 0x00108010L, 0x40108000L, 0x40000010L, + 0x40000000L, 0x00100000L, 0x00008010L, 0x40108010L, + 0x00100010L, 0x40108000L, 0x40008000L, 0x00108010L, + 0x40108010L, 0x00100010L, 0x40000010L, 0x00000000L, + 0x40000000L, 0x00008010L, 0x00100000L, 0x40100010L, + 0x00008000L, 0x40000000L, 0x00108010L, 0x40008010L, + 0x40108000L, 0x00008000L, 0x00000000L, 0x40000010L, + 0x00000010L, 0x40108010L, 0x00108000L, 0x40100000L, + 0x40100010L, 0x00100000L, 0x00008010L, 0x40008000L, + 0x40008010L, 0x00000010L, 0x40100000L, 0x00108000L, + }, + { + /* nibble 2 */ + 0x04000001L, 0x04040100L, 0x00000100L, 0x04000101L, + 0x00040001L, 0x04000000L, 0x04000101L, 0x00040100L, + 0x04000100L, 0x00040000L, 0x04040000L, 0x00000001L, + 0x04040101L, 0x00000101L, 0x00000001L, 0x04040001L, + 0x00000000L, 0x00040001L, 0x04040100L, 0x00000100L, + 0x00000101L, 0x04040101L, 0x00040000L, 0x04000001L, + 0x04040001L, 0x04000100L, 0x00040101L, 0x04040000L, + 0x00040100L, 0x00000000L, 0x04000000L, 0x00040101L, + 0x04040100L, 0x00000100L, 0x00000001L, 0x00040000L, + 0x00000101L, 0x00040001L, 0x04040000L, 0x04000101L, + 0x00000000L, 0x04040100L, 0x00040100L, 0x04040001L, + 0x00040001L, 0x04000000L, 0x04040101L, 0x00000001L, + 0x00040101L, 0x04000001L, 0x04000000L, 0x04040101L, + 0x00040000L, 0x04000100L, 0x04000101L, 0x00040100L, + 0x04000100L, 0x00000000L, 0x04040001L, 0x00000101L, + 0x04000001L, 0x00040101L, 0x00000100L, 0x04040000L, + }, + { + /* nibble 3 */ + 0x00401008L, 0x10001000L, 0x00000008L, 0x10401008L, + 0x00000000L, 0x10400000L, 0x10001008L, 0x00400008L, + 0x10401000L, 0x10000008L, 0x10000000L, 0x00001008L, + 0x10000008L, 0x00401008L, 0x00400000L, 0x10000000L, + 0x10400008L, 0x00401000L, 0x00001000L, 0x00000008L, + 0x00401000L, 0x10001008L, 0x10400000L, 0x00001000L, + 0x00001008L, 0x00000000L, 0x00400008L, 0x10401000L, + 0x10001000L, 0x10400008L, 0x10401008L, 0x00400000L, + 0x10400008L, 0x00001008L, 0x00400000L, 0x10000008L, + 0x00401000L, 0x10001000L, 0x00000008L, 0x10400000L, + 0x10001008L, 0x00000000L, 0x00001000L, 0x00400008L, + 0x00000000L, 0x10400008L, 0x10401000L, 0x00001000L, + 0x10000000L, 0x10401008L, 0x00401008L, 0x00400000L, + 0x10401008L, 0x00000008L, 0x10001000L, 0x00401008L, + 0x00400008L, 0x00401000L, 0x10400000L, 0x10001008L, + 0x00001008L, 0x10000000L, 0x10000008L, 0x10401000L, + }, + { + /* nibble 4 */ + 0x08000000L, 0x00010000L, 0x00000400L, 0x08010420L, + 0x08010020L, 0x08000400L, 0x00010420L, 0x08010000L, + 0x00010000L, 0x00000020L, 0x08000020L, 0x00010400L, + 0x08000420L, 0x08010020L, 0x08010400L, 0x00000000L, + 0x00010400L, 0x08000000L, 0x00010020L, 0x00000420L, + 0x08000400L, 0x00010420L, 0x00000000L, 0x08000020L, + 0x00000020L, 0x08000420L, 0x08010420L, 0x00010020L, + 0x08010000L, 0x00000400L, 0x00000420L, 0x08010400L, + 0x08010400L, 0x08000420L, 0x00010020L, 0x08010000L, + 0x00010000L, 0x00000020L, 0x08000020L, 0x08000400L, + 0x08000000L, 0x00010400L, 0x08010420L, 0x00000000L, + 0x00010420L, 0x08000000L, 0x00000400L, 0x00010020L, + 0x08000420L, 0x00000400L, 0x00000000L, 0x08010420L, + 0x08010020L, 0x08010400L, 0x00000420L, 0x00010000L, + 0x00010400L, 0x08010020L, 0x08000400L, 0x00000420L, + 0x00000020L, 0x00010420L, 0x08010000L, 0x08000020L, + }, + { + /* nibble 5 */ + 0x80000040L, 0x00200040L, 0x00000000L, 0x80202000L, + 0x00200040L, 0x00002000L, 0x80002040L, 0x00200000L, + 0x00002040L, 0x80202040L, 0x00202000L, 0x80000000L, + 0x80002000L, 0x80000040L, 0x80200000L, 0x00202040L, + 0x00200000L, 0x80002040L, 0x80200040L, 0x00000000L, + 0x00002000L, 0x00000040L, 0x80202000L, 0x80200040L, + 0x80202040L, 0x80200000L, 0x80000000L, 0x00002040L, + 0x00000040L, 0x00202000L, 0x00202040L, 0x80002000L, + 0x00002040L, 0x80000000L, 0x80002000L, 0x00202040L, + 0x80202000L, 0x00200040L, 0x00000000L, 0x80002000L, + 0x80000000L, 0x00002000L, 0x80200040L, 0x00200000L, + 0x00200040L, 0x80202040L, 0x00202000L, 0x00000040L, + 0x80202040L, 0x00202000L, 0x00200000L, 0x80002040L, + 0x80000040L, 0x80200000L, 0x00202040L, 0x00000000L, + 0x00002000L, 0x80000040L, 0x80002040L, 0x80202000L, + 0x80200000L, 0x00002040L, 0x00000040L, 0x80200040L, + }, + { + /* nibble 6 */ + 0x00004000L, 0x00000200L, 0x01000200L, 0x01000004L, + 0x01004204L, 0x00004004L, 0x00004200L, 0x00000000L, + 0x01000000L, 0x01000204L, 0x00000204L, 0x01004000L, + 0x00000004L, 0x01004200L, 0x01004000L, 0x00000204L, + 0x01000204L, 0x00004000L, 0x00004004L, 0x01004204L, + 0x00000000L, 0x01000200L, 0x01000004L, 0x00004200L, + 0x01004004L, 0x00004204L, 0x01004200L, 0x00000004L, + 0x00004204L, 0x01004004L, 0x00000200L, 0x01000000L, + 0x00004204L, 0x01004000L, 0x01004004L, 0x00000204L, + 0x00004000L, 0x00000200L, 0x01000000L, 0x01004004L, + 0x01000204L, 0x00004204L, 0x00004200L, 0x00000000L, + 0x00000200L, 0x01000004L, 0x00000004L, 0x01000200L, + 0x00000000L, 0x01000204L, 0x01000200L, 0x00004200L, + 0x00000204L, 0x00004000L, 0x01004204L, 0x01000000L, + 0x01004200L, 0x00000004L, 0x00004004L, 0x01004204L, + 0x01000004L, 0x01004200L, 0x01004000L, 0x00004004L, + }, + { + /* nibble 7 */ + 0x20800080L, 0x20820000L, 0x00020080L, 0x00000000L, + 0x20020000L, 0x00800080L, 0x20800000L, 0x20820080L, + 0x00000080L, 0x20000000L, 0x00820000L, 0x00020080L, + 0x00820080L, 0x20020080L, 0x20000080L, 0x20800000L, + 0x00020000L, 0x00820080L, 0x00800080L, 0x20020000L, + 0x20820080L, 0x20000080L, 0x00000000L, 0x00820000L, + 0x20000000L, 0x00800000L, 0x20020080L, 0x20800080L, + 0x00800000L, 0x00020000L, 0x20820000L, 0x00000080L, + 0x00800000L, 0x00020000L, 0x20000080L, 0x20820080L, + 0x00020080L, 0x20000000L, 0x00000000L, 0x00820000L, + 0x20800080L, 0x20020080L, 0x20020000L, 0x00800080L, + 0x20820000L, 0x00000080L, 0x00800080L, 0x20020000L, + 0x20820080L, 0x00800000L, 0x20800000L, 0x20000080L, + 0x00820000L, 0x00020080L, 0x20020080L, 0x20800000L, + 0x00000080L, 0x20820000L, 0x00820080L, 0x00000000L, + 0x20000000L, 0x20800080L, 0x00020000L, 0x00820080L, + } +}; diff --git a/libs/openssl/crypto/des/str2key.c b/libs/openssl/crypto/des/str2key.c new file mode 100644 index 00000000..38a478cf --- /dev/null +++ b/libs/openssl/crypto/des/str2key.c @@ -0,0 +1,164 @@ +/* crypto/des/str2key.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "des_locl.h" + +void DES_string_to_key(const char *str, DES_cblock *key) +{ + DES_key_schedule ks; + int i, length; + register unsigned char j; + + memset(key, 0, 8); + length = strlen(str); +#ifdef OLD_STR_TO_KEY + for (i = 0; i < length; i++) + (*key)[i % 8] ^= (str[i] << 1); +#else /* MIT COMPATIBLE */ + for (i = 0; i < length; i++) { + j = str[i]; + if ((i % 16) < 8) + (*key)[i % 8] ^= (j << 1); + else { + /* Reverse the bit order 05/05/92 eay */ + j = ((j << 4) & 0xf0) | ((j >> 4) & 0x0f); + j = ((j << 2) & 0xcc) | ((j >> 2) & 0x33); + j = ((j << 1) & 0xaa) | ((j >> 1) & 0x55); + (*key)[7 - (i % 8)] ^= j; + } + } +#endif + DES_set_odd_parity(key); +#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY + if (DES_is_weak_key(key)) + (*key)[7] ^= 0xF0; + DES_set_key(key, &ks); +#else + DES_set_key_unchecked(key, &ks); +#endif + DES_cbc_cksum((const unsigned char *)str, key, length, &ks, key); + OPENSSL_cleanse(&ks, sizeof(ks)); + DES_set_odd_parity(key); +} + +void DES_string_to_2keys(const char *str, DES_cblock *key1, DES_cblock *key2) +{ + DES_key_schedule ks; + int i, length; + register unsigned char j; + + memset(key1, 0, 8); + memset(key2, 0, 8); + length = strlen(str); +#ifdef OLD_STR_TO_KEY + if (length <= 8) { + for (i = 0; i < length; i++) { + (*key2)[i] = (*key1)[i] = (str[i] << 1); + } + } else { + for (i = 0; i < length; i++) { + if ((i / 8) & 1) + (*key2)[i % 8] ^= (str[i] << 1); + else + (*key1)[i % 8] ^= (str[i] << 1); + } + } +#else /* MIT COMPATIBLE */ + for (i = 0; i < length; i++) { + j = str[i]; + if ((i % 32) < 16) { + if ((i % 16) < 8) + (*key1)[i % 8] ^= (j << 1); + else + (*key2)[i % 8] ^= (j << 1); + } else { + j = ((j << 4) & 0xf0) | ((j >> 4) & 0x0f); + j = ((j << 2) & 0xcc) | ((j >> 2) & 0x33); + j = ((j << 1) & 0xaa) | ((j >> 1) & 0x55); + if ((i % 16) < 8) + (*key1)[7 - (i % 8)] ^= j; + else + (*key2)[7 - (i % 8)] ^= j; + } + } + if (length <= 8) + memcpy(key2, key1, 8); +#endif + DES_set_odd_parity(key1); + DES_set_odd_parity(key2); +#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY + if (DES_is_weak_key(key1)) + (*key1)[7] ^= 0xF0; + DES_set_key(key1, &ks); +#else + DES_set_key_unchecked(key1, &ks); +#endif + DES_cbc_cksum((const unsigned char *)str, key1, length, &ks, key1); +#ifdef EXPERIMENTAL_STR_TO_STRONG_KEY + if (DES_is_weak_key(key2)) + (*key2)[7] ^= 0xF0; + DES_set_key(key2, &ks); +#else + DES_set_key_unchecked(key2, &ks); +#endif + DES_cbc_cksum((const unsigned char *)str, key2, length, &ks, key2); + OPENSSL_cleanse(&ks, sizeof(ks)); + DES_set_odd_parity(key1); + DES_set_odd_parity(key2); +} diff --git a/libs/openssl/crypto/des/times/486-50.sol b/libs/openssl/crypto/des/times/486-50.sol new file mode 100644 index 00000000..0de62d6d --- /dev/null +++ b/libs/openssl/crypto/des/times/486-50.sol @@ -0,0 +1,16 @@ +Solaris 2.4, 486 50mhz, gcc 2.6.3 +options des ecb/s +16 r2 i 43552.51 100.0% +16 r1 i 43487.45 99.9% +16 c p 43003.23 98.7% +16 r2 p 42339.00 97.2% +16 c i 41900.91 96.2% +16 r1 p 41360.64 95.0% + 4 c i 38728.48 88.9% + 4 c p 38225.63 87.8% + 4 r1 i 38085.79 87.4% + 4 r2 i 37825.64 86.9% + 4 r2 p 34611.00 79.5% + 4 r1 p 31802.00 73.0% +-DDES_UNROLL -DDES_RISC2 + diff --git a/libs/openssl/crypto/des/times/586-100.lnx b/libs/openssl/crypto/des/times/586-100.lnx new file mode 100644 index 00000000..4323914a --- /dev/null +++ b/libs/openssl/crypto/des/times/586-100.lnx @@ -0,0 +1,20 @@ +Pentium 100 +Linux 2 kernel +gcc 2.7.0 -O3 -fomit-frame-pointer +No X server running, just a console, it makes the top speed jump from 151,000 +to 158,000 :-). +options des ecb/s +assember 281000.00 177.1% +16 r1 p 158667.40 100.0% +16 r1 i 148471.70 93.6% +16 r2 p 143961.80 90.7% +16 r2 i 141689.20 89.3% + 4 r1 i 140100.00 88.3% + 4 r2 i 134049.40 84.5% +16 c i 124145.20 78.2% +16 c p 121584.20 76.6% + 4 c i 118116.00 74.4% + 4 r2 p 117977.90 74.4% + 4 c p 114971.40 72.5% + 4 r1 p 114578.40 72.2% +-DDES_UNROLL -DDES_RISC1 -DDES_PTR diff --git a/libs/openssl/crypto/des/times/686-200.fre b/libs/openssl/crypto/des/times/686-200.fre new file mode 100644 index 00000000..7d83f6ad --- /dev/null +++ b/libs/openssl/crypto/des/times/686-200.fre @@ -0,0 +1,18 @@ +Pentium 100 +Free BSD 2.1.5 kernel +gcc 2.7.2.2 -O3 -fomit-frame-pointer +options des ecb/s +assember 578000.00 133.1% +16 r2 i 434454.80 100.0% +16 r1 i 433621.43 99.8% +16 r2 p 431375.69 99.3% + 4 r1 i 423722.30 97.5% + 4 r2 i 422399.40 97.2% +16 r1 p 421739.40 97.1% +16 c i 399027.94 91.8% +16 c p 372251.70 85.7% + 4 c i 365118.35 84.0% + 4 c p 352880.51 81.2% + 4 r2 p 255104.90 58.7% + 4 r1 p 251289.18 57.8% +-DDES_UNROLL -DDES_RISC2 diff --git a/libs/openssl/crypto/des/times/aix.cc b/libs/openssl/crypto/des/times/aix.cc new file mode 100644 index 00000000..d96b74e2 --- /dev/null +++ b/libs/openssl/crypto/des/times/aix.cc @@ -0,0 +1,26 @@ +From: Paco Garcia + +This machine is a Bull Estrella Minitower Model MT604-100 +Processor : PPC604 +P.Speed : 100Mhz +Data/Instr Cache : 16 K +L2 Cache : 256 K +PCI BUS Speed : 33 Mhz +TransfRate PCI : 132 MB/s +Memory : 96 MB + +options des ecb/s + 4 c p 275118.61 100.0% + 4 c i 273545.07 99.4% + 4 r2 p 270441.02 98.3% + 4 r1 p 253052.15 92.0% + 4 r2 i 240842.97 87.5% + 4 r1 i 240556.66 87.4% +16 c i 224603.99 81.6% +16 c p 224483.98 81.6% +16 r2 p 215691.19 78.4% +16 r1 p 208332.83 75.7% +16 r1 i 199206.50 72.4% +16 r2 i 198963.70 72.3% +-DDES_PTR + diff --git a/libs/openssl/crypto/des/times/alpha.cc b/libs/openssl/crypto/des/times/alpha.cc new file mode 100644 index 00000000..95c17efa --- /dev/null +++ b/libs/openssl/crypto/des/times/alpha.cc @@ -0,0 +1,18 @@ +cc -O2 +DES_LONG is 'unsigned int' + +options des ecb/s + 4 r2 p 181146.14 100.0% +16 r2 p 172102.94 95.0% + 4 r2 i 165424.11 91.3% +16 c p 160468.64 88.6% + 4 c p 156653.59 86.5% + 4 c i 155245.18 85.7% + 4 r1 p 154729.68 85.4% +16 r2 i 154137.69 85.1% +16 r1 p 152357.96 84.1% +16 c i 148743.91 82.1% + 4 r1 i 146695.59 81.0% +16 r1 i 144961.00 80.0% +-DDES_RISC2 -DDES_PTR + diff --git a/libs/openssl/crypto/des/times/hpux.cc b/libs/openssl/crypto/des/times/hpux.cc new file mode 100644 index 00000000..3de856dd --- /dev/null +++ b/libs/openssl/crypto/des/times/hpux.cc @@ -0,0 +1,17 @@ +HPUX 10 - 9000/887 - cc -D_HPUX_SOURCE -Aa +ESlit +O2 -Wl,-a,archive + +options des ecb/s +16 c i 149448.90 100.0% + 4 c i 145861.79 97.6% +16 r2 i 141710.96 94.8% +16 r1 i 139455.33 93.3% + 4 r2 i 138800.00 92.9% + 4 r1 i 136692.65 91.5% +16 r2 p 110228.17 73.8% +16 r1 p 109397.07 73.2% +16 c p 109209.89 73.1% + 4 c p 108014.71 72.3% + 4 r2 p 107873.88 72.2% + 4 r1 p 107685.83 72.1% +-DDES_UNROLL + diff --git a/libs/openssl/crypto/des/times/sparc.gcc b/libs/openssl/crypto/des/times/sparc.gcc new file mode 100644 index 00000000..8eaa0421 --- /dev/null +++ b/libs/openssl/crypto/des/times/sparc.gcc @@ -0,0 +1,17 @@ +solaris 2.5.1 - sparc 10 50mhz - gcc 2.7.2 + +options des ecb/s +16 c i 124382.70 100.0% + 4 c i 118884.68 95.6% +16 c p 112261.20 90.3% +16 r2 i 111777.10 89.9% +16 r2 p 108896.30 87.5% +16 r1 p 108791.59 87.5% + 4 c p 107290.10 86.3% + 4 r1 p 104583.80 84.1% +16 r1 i 104206.20 83.8% + 4 r2 p 103709.80 83.4% + 4 r2 i 98306.43 79.0% + 4 r1 i 91525.80 73.6% +-DDES_UNROLL + diff --git a/libs/openssl/crypto/des/times/usparc.cc b/libs/openssl/crypto/des/times/usparc.cc new file mode 100644 index 00000000..0864285e --- /dev/null +++ b/libs/openssl/crypto/des/times/usparc.cc @@ -0,0 +1,31 @@ +solaris 2.5.1 usparc 167mhz?? - SC4.0 cc -fast -Xa -xO5 + +For the ultra sparc, SunC 4.0 cc -fast -Xa -xO5, running 'des_opts' +gives a speed of 475,000 des/s while 'speed' gives 417,000 des/s. +I believe the difference is tied up in optimisation that the compiler +is able to perform when the code is 'inlined'. For 'speed', the DES +routines are being linked from a library. I'll record the higher +speed since if performance is everything, you can always inline +'des_enc.c'. + +[ 16-Jan-06 - I've been playing with the + '-xtarget=ultra -xarch=v8plus -Xa -xO5 -Xa' + and while it makes the des_opts numbers much slower, it makes the + actual 'speed' numbers look better which is a realistic version of + using the libraries. ] + +options des ecb/s +16 r1 p 475516.90 100.0% +16 r2 p 439388.10 92.4% +16 c i 427001.40 89.8% +16 c p 419516.50 88.2% + 4 r2 p 409491.70 86.1% + 4 r1 p 404266.90 85.0% + 4 c p 398121.00 83.7% + 4 c i 370588.40 77.9% + 4 r1 i 362742.20 76.3% +16 r2 i 331275.50 69.7% +16 r1 i 324730.60 68.3% + 4 r2 i 63535.10 13.4% <-- very very weird, must be cache problems. +-DDES_UNROLL -DDES_RISC1 -DDES_PTR + diff --git a/libs/openssl/crypto/des/typemap b/libs/openssl/crypto/des/typemap new file mode 100644 index 00000000..a524f536 --- /dev/null +++ b/libs/openssl/crypto/des/typemap @@ -0,0 +1,34 @@ +# +# DES SECTION +# +deschar * T_DESCHARP +des_cblock * T_CBLOCK +des_cblock T_CBLOCK +des_key_schedule T_SCHEDULE +des_key_schedule * T_SCHEDULE + +INPUT +T_CBLOCK + $var=(des_cblock *)SvPV($arg,len); + if (len < DES_KEY_SZ) + { + croak(\"$var needs to be at least %u bytes long\",DES_KEY_SZ); + } + +T_SCHEDULE + $var=(des_key_schedule *)SvPV($arg,len); + if (len < DES_SCHEDULE_SZ) + { + croak(\"$var needs to be at least %u bytes long\", + DES_SCHEDULE_SZ); + } + +OUTPUT +T_CBLOCK + sv_setpvn($arg,(char *)$var,DES_KEY_SZ); + +T_SCHEDULE + sv_setpvn($arg,(char *)$var,DES_SCHEDULE_SZ); + +T_DESCHARP + sv_setpvn($arg,(char *)$var,len); diff --git a/libs/openssl/crypto/des/xcbc_enc.c b/libs/openssl/crypto/des/xcbc_enc.c new file mode 100644 index 00000000..6fe021be --- /dev/null +++ b/libs/openssl/crypto/des/xcbc_enc.c @@ -0,0 +1,216 @@ +/* crypto/des/xcbc_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "des_locl.h" + +/* RSA's DESX */ + +#if 0 /* broken code, preserved just in case anyone + * specifically looks for this */ +static const unsigned char desx_white_in2out[256] = { + 0xBD, 0x56, 0xEA, 0xF2, 0xA2, 0xF1, 0xAC, 0x2A, 0xB0, 0x93, 0xD1, 0x9C, + 0x1B, 0x33, 0xFD, 0xD0, + 0x30, 0x04, 0xB6, 0xDC, 0x7D, 0xDF, 0x32, 0x4B, 0xF7, 0xCB, 0x45, 0x9B, + 0x31, 0xBB, 0x21, 0x5A, + 0x41, 0x9F, 0xE1, 0xD9, 0x4A, 0x4D, 0x9E, 0xDA, 0xA0, 0x68, 0x2C, 0xC3, + 0x27, 0x5F, 0x80, 0x36, + 0x3E, 0xEE, 0xFB, 0x95, 0x1A, 0xFE, 0xCE, 0xA8, 0x34, 0xA9, 0x13, 0xF0, + 0xA6, 0x3F, 0xD8, 0x0C, + 0x78, 0x24, 0xAF, 0x23, 0x52, 0xC1, 0x67, 0x17, 0xF5, 0x66, 0x90, 0xE7, + 0xE8, 0x07, 0xB8, 0x60, + 0x48, 0xE6, 0x1E, 0x53, 0xF3, 0x92, 0xA4, 0x72, 0x8C, 0x08, 0x15, 0x6E, + 0x86, 0x00, 0x84, 0xFA, + 0xF4, 0x7F, 0x8A, 0x42, 0x19, 0xF6, 0xDB, 0xCD, 0x14, 0x8D, 0x50, 0x12, + 0xBA, 0x3C, 0x06, 0x4E, + 0xEC, 0xB3, 0x35, 0x11, 0xA1, 0x88, 0x8E, 0x2B, 0x94, 0x99, 0xB7, 0x71, + 0x74, 0xD3, 0xE4, 0xBF, + 0x3A, 0xDE, 0x96, 0x0E, 0xBC, 0x0A, 0xED, 0x77, 0xFC, 0x37, 0x6B, 0x03, + 0x79, 0x89, 0x62, 0xC6, + 0xD7, 0xC0, 0xD2, 0x7C, 0x6A, 0x8B, 0x22, 0xA3, 0x5B, 0x05, 0x5D, 0x02, + 0x75, 0xD5, 0x61, 0xE3, + 0x18, 0x8F, 0x55, 0x51, 0xAD, 0x1F, 0x0B, 0x5E, 0x85, 0xE5, 0xC2, 0x57, + 0x63, 0xCA, 0x3D, 0x6C, + 0xB4, 0xC5, 0xCC, 0x70, 0xB2, 0x91, 0x59, 0x0D, 0x47, 0x20, 0xC8, 0x4F, + 0x58, 0xE0, 0x01, 0xE2, + 0x16, 0x38, 0xC4, 0x6F, 0x3B, 0x0F, 0x65, 0x46, 0xBE, 0x7E, 0x2D, 0x7B, + 0x82, 0xF9, 0x40, 0xB5, + 0x1D, 0x73, 0xF8, 0xEB, 0x26, 0xC7, 0x87, 0x97, 0x25, 0x54, 0xB1, 0x28, + 0xAA, 0x98, 0x9D, 0xA5, + 0x64, 0x6D, 0x7A, 0xD4, 0x10, 0x81, 0x44, 0xEF, 0x49, 0xD6, 0xAE, 0x2E, + 0xDD, 0x76, 0x5C, 0x2F, + 0xA7, 0x1C, 0xC9, 0x09, 0x69, 0x9A, 0x83, 0xCF, 0x29, 0x39, 0xB9, 0xE9, + 0x4C, 0xFF, 0x43, 0xAB, +}; + +void DES_xwhite_in2out(const_DES_cblock *des_key, const_DES_cblock *in_white, + DES_cblock *out_white) +{ + int out0, out1; + int i; + const unsigned char *key = &(*des_key)[0]; + const unsigned char *in = &(*in_white)[0]; + unsigned char *out = &(*out_white)[0]; + + out[0] = out[1] = out[2] = out[3] = out[4] = out[5] = out[6] = out[7] = 0; + out0 = out1 = 0; + for (i = 0; i < 8; i++) { + out[i] = key[i] ^ desx_white_in2out[out0 ^ out1]; + out0 = out1; + out1 = (int)out[i & 0x07]; + } + + out0 = out[0]; + out1 = out[i]; /* BUG: out-of-bounds read */ + for (i = 0; i < 8; i++) { + out[i] = in[i] ^ desx_white_in2out[out0 ^ out1]; + out0 = out1; + out1 = (int)out[i & 0x07]; + } +} +#endif + +void DES_xcbc_encrypt(const unsigned char *in, unsigned char *out, + long length, DES_key_schedule *schedule, + DES_cblock *ivec, const_DES_cblock *inw, + const_DES_cblock *outw, int enc) +{ + register DES_LONG tin0, tin1; + register DES_LONG tout0, tout1, xor0, xor1; + register DES_LONG inW0, inW1, outW0, outW1; + register const unsigned char *in2; + register long l = length; + DES_LONG tin[2]; + unsigned char *iv; + + in2 = &(*inw)[0]; + c2l(in2, inW0); + c2l(in2, inW1); + in2 = &(*outw)[0]; + c2l(in2, outW0); + c2l(in2, outW1); + + iv = &(*ivec)[0]; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0 ^ inW0; + tin[0] = tin0; + tin1 ^= tout1 ^ inW1; + tin[1] = tin1; + DES_encrypt1(tin, schedule, DES_ENCRYPT); + tout0 = tin[0] ^ outW0; + l2c(tout0, out); + tout1 = tin[1] ^ outW1; + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0 ^ inW0; + tin[0] = tin0; + tin1 ^= tout1 ^ inW1; + tin[1] = tin1; + DES_encrypt1(tin, schedule, DES_ENCRYPT); + tout0 = tin[0] ^ outW0; + l2c(tout0, out); + tout1 = tin[1] ^ outW1; + l2c(tout1, out); + } + iv = &(*ivec)[0]; + l2c(tout0, iv); + l2c(tout1, iv); + } else { + c2l(iv, xor0); + c2l(iv, xor1); + for (l -= 8; l > 0; l -= 8) { + c2l(in, tin0); + tin[0] = tin0 ^ outW0; + c2l(in, tin1); + tin[1] = tin1 ^ outW1; + DES_encrypt1(tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0 ^ inW0; + tout1 = tin[1] ^ xor1 ^ inW1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + c2l(in, tin0); + tin[0] = tin0 ^ outW0; + c2l(in, tin1); + tin[1] = tin1 ^ outW1; + DES_encrypt1(tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0 ^ inW0; + tout1 = tin[1] ^ xor1 ^ inW1; + l2cn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + + iv = &(*ivec)[0]; + l2c(xor0, iv); + l2c(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + inW0 = inW1 = outW0 = outW1 = 0; + tin[0] = tin[1] = 0; +} diff --git a/libs/openssl/crypto/dh/dh.h b/libs/openssl/crypto/dh/dh.h new file mode 100644 index 00000000..4cbaa978 --- /dev/null +++ b/libs/openssl/crypto/dh/dh.h @@ -0,0 +1,287 @@ +/* crypto/dh/dh.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_DH_H +# define HEADER_DH_H + +# include + +# ifdef OPENSSL_NO_DH +# error DH is disabled. +# endif + +# ifndef OPENSSL_NO_BIO +# include +# endif +# include +# ifndef OPENSSL_NO_DEPRECATED +# include +# endif + +# ifndef OPENSSL_DH_MAX_MODULUS_BITS +# define OPENSSL_DH_MAX_MODULUS_BITS 10000 +# endif + +# define DH_FLAG_CACHE_MONT_P 0x01 + +/* + * new with 0.9.7h; the built-in DH + * implementation now uses constant time + * modular exponentiation for secret exponents + * by default. This flag causes the + * faster variable sliding window method to + * be used for all exponents. + */ +# define DH_FLAG_NO_EXP_CONSTTIME 0x02 + +/* + * If this flag is set the DH method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its reposibility to ensure the + * result is compliant. + */ + +# define DH_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define DH_FLAG_NON_FIPS_ALLOW 0x0400 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Already defined in ossl_typ.h */ +/* typedef struct dh_st DH; */ +/* typedef struct dh_method DH_METHOD; */ + +struct dh_method { + const char *name; + /* Methods here */ + int (*generate_key) (DH *dh); + int (*compute_key) (unsigned char *key, const BIGNUM *pub_key, DH *dh); + /* Can be null */ + int (*bn_mod_exp) (const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); + int (*init) (DH *dh); + int (*finish) (DH *dh); + int flags; + char *app_data; + /* If this is non-NULL, it will be used to generate parameters */ + int (*generate_params) (DH *dh, int prime_len, int generator, + BN_GENCB *cb); +}; + +struct dh_st { + /* + * This first argument is used to pick up errors when a DH is passed + * instead of a EVP_PKEY + */ + int pad; + int version; + BIGNUM *p; + BIGNUM *g; + long length; /* optional */ + BIGNUM *pub_key; /* g^x */ + BIGNUM *priv_key; /* x */ + int flags; + BN_MONT_CTX *method_mont_p; + /* Place holders if we want to do X9.42 DH */ + BIGNUM *q; + BIGNUM *j; + unsigned char *seed; + int seedlen; + BIGNUM *counter; + int references; + CRYPTO_EX_DATA ex_data; + const DH_METHOD *meth; + ENGINE *engine; +}; + +# define DH_GENERATOR_2 2 +/* #define DH_GENERATOR_3 3 */ +# define DH_GENERATOR_5 5 + +/* DH_check error codes */ +# define DH_CHECK_P_NOT_PRIME 0x01 +# define DH_CHECK_P_NOT_SAFE_PRIME 0x02 +# define DH_UNABLE_TO_CHECK_GENERATOR 0x04 +# define DH_NOT_SUITABLE_GENERATOR 0x08 + +/* DH_check_pub_key error codes */ +# define DH_CHECK_PUBKEY_TOO_SMALL 0x01 +# define DH_CHECK_PUBKEY_TOO_LARGE 0x02 + +/* + * primes p where (p-1)/2 is prime too are called "safe"; we define this for + * backward compatibility: + */ +# define DH_CHECK_P_NOT_STRONG_PRIME DH_CHECK_P_NOT_SAFE_PRIME + +# define d2i_DHparams_fp(fp,x) (DH *)ASN1_d2i_fp((char *(*)())DH_new, \ + (char *(*)())d2i_DHparams,(fp),(unsigned char **)(x)) +# define i2d_DHparams_fp(fp,x) ASN1_i2d_fp(i2d_DHparams,(fp), \ + (unsigned char *)(x)) +# define d2i_DHparams_bio(bp,x) ASN1_d2i_bio_of(DH,DH_new,d2i_DHparams,bp,x) +# define i2d_DHparams_bio(bp,x) ASN1_i2d_bio_of_const(DH,i2d_DHparams,bp,x) + +DH *DHparams_dup(DH *); + +const DH_METHOD *DH_OpenSSL(void); + +void DH_set_default_method(const DH_METHOD *meth); +const DH_METHOD *DH_get_default_method(void); +int DH_set_method(DH *dh, const DH_METHOD *meth); +DH *DH_new_method(ENGINE *engine); + +DH *DH_new(void); +void DH_free(DH *dh); +int DH_up_ref(DH *dh); +int DH_size(const DH *dh); +int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int DH_set_ex_data(DH *d, int idx, void *arg); +void *DH_get_ex_data(DH *d, int idx); + +/* Deprecated version */ +# ifndef OPENSSL_NO_DEPRECATED +DH *DH_generate_parameters(int prime_len, int generator, + void (*callback) (int, int, void *), void *cb_arg); +# endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int DH_generate_parameters_ex(DH *dh, int prime_len, int generator, + BN_GENCB *cb); + +int DH_check(const DH *dh, int *codes); +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *codes); +int DH_generate_key(DH *dh); +int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); +DH *d2i_DHparams(DH **a, const unsigned char **pp, long length); +int i2d_DHparams(const DH *a, unsigned char **pp); +# ifndef OPENSSL_NO_FP_API +int DHparams_print_fp(FILE *fp, const DH *x); +# endif +# ifndef OPENSSL_NO_BIO +int DHparams_print(BIO *bp, const DH *x); +# else +int DHparams_print(char *bp, const DH *x); +# endif + +# define EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN, len, NULL) + +# define EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, gen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DH, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR, gen, NULL) + +# define EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR (EVP_PKEY_ALG_CTRL + 2) + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_DH_strings(void); + +/* Error codes for the DH functions. */ + +/* Function codes. */ +# define DH_F_COMPUTE_KEY 102 +# define DH_F_DHPARAMS_PRINT_FP 101 +# define DH_F_DH_BUILTIN_GENPARAMS 106 +# define DH_F_DH_COMPUTE_KEY 114 +# define DH_F_DH_GENERATE_KEY 115 +# define DH_F_DH_GENERATE_PARAMETERS_EX 116 +# define DH_F_DH_NEW_METHOD 105 +# define DH_F_DH_PARAM_DECODE 107 +# define DH_F_DH_PRIV_DECODE 110 +# define DH_F_DH_PRIV_ENCODE 111 +# define DH_F_DH_PUB_DECODE 108 +# define DH_F_DH_PUB_ENCODE 109 +# define DH_F_DO_DH_PRINT 100 +# define DH_F_GENERATE_KEY 103 +# define DH_F_GENERATE_PARAMETERS 104 +# define DH_F_PKEY_DH_DERIVE 112 +# define DH_F_PKEY_DH_KEYGEN 113 + +/* Reason codes. */ +# define DH_R_BAD_GENERATOR 101 +# define DH_R_BN_DECODE_ERROR 109 +# define DH_R_BN_ERROR 106 +# define DH_R_DECODE_ERROR 104 +# define DH_R_INVALID_PUBKEY 102 +# define DH_R_KEYS_NOT_SET 108 +# define DH_R_KEY_SIZE_TOO_SMALL 110 +# define DH_R_MODULUS_TOO_LARGE 103 +# define DH_R_NON_FIPS_METHOD 111 +# define DH_R_NO_PARAMETERS_SET 107 +# define DH_R_NO_PRIVATE_VALUE 100 +# define DH_R_PARAMETER_ENCODING_ERROR 105 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/dh/dh1024.pem b/libs/openssl/crypto/dh/dh1024.pem new file mode 100644 index 00000000..81d43f6a --- /dev/null +++ b/libs/openssl/crypto/dh/dh1024.pem @@ -0,0 +1,5 @@ +-----BEGIN DH PARAMETERS----- +MIGHAoGBAJf2QmHKtQXdKCjhPx1ottPb0PMTBH9A6FbaWMsTuKG/K3g6TG1Z1fkq +/Gz/PWk/eLI9TzFgqVAuPvr3q14a1aZeVUMTgo2oO5/y2UHe6VaJ+trqCTat3xlx +/mNbIK9HA2RgPC3gWfVLZQrY+gz3ASHHR5nXWHEyvpuZm7m3h+irAgEC +-----END DH PARAMETERS----- diff --git a/libs/openssl/crypto/dh/dh192.pem b/libs/openssl/crypto/dh/dh192.pem new file mode 100644 index 00000000..521c0727 --- /dev/null +++ b/libs/openssl/crypto/dh/dh192.pem @@ -0,0 +1,3 @@ +-----BEGIN DH PARAMETERS----- +MB4CGQDUoLoCULb9LsYm5+/WN992xxbiLQlEuIsCAQM= +-----END DH PARAMETERS----- diff --git a/libs/openssl/crypto/dh/dh2048.pem b/libs/openssl/crypto/dh/dh2048.pem new file mode 100644 index 00000000..295460f5 --- /dev/null +++ b/libs/openssl/crypto/dh/dh2048.pem @@ -0,0 +1,16 @@ +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEA7ZKJNYJFVcs7+6J2WmkEYb8h86tT0s0h2v94GRFS8Q7B4lW9aG9o +AFO5Imov5Jo0H2XMWTKKvbHbSe3fpxJmw/0hBHAY8H/W91hRGXKCeyKpNBgdL8sh +z22SrkO2qCnHJ6PLAMXy5fsKpFmFor2tRfCzrfnggTXu2YOzzK7q62bmqVdmufEo +pT8igNcLpvZxk5uBDvhakObMym9mX3rAEBoe8PwttggMYiiw7NuJKO4MqD1llGkW +aVM8U2ATsCun1IKHrRxynkE1/MJ86VHeYYX8GZt2YA8z+GuzylIOKcMH6JAWzMwA +Gbatw6QwizOhr9iMjZ0B26TE3X8LvW84wwIBAg== +-----END DH PARAMETERS----- +-----BEGIN DH PARAMETERS----- +MIIBCAKCAQEArtA3w73zP6Lu3EOQtwogiXt3AXXpuS6yD4BhzNS1pZFyPHk0/an5 +8ydEkPhQZHKDW+BZJxxPLANaTudWo2YT8TgtvUdN6KSgMiEi6McwqDw+SADuvW+F +SKUYFxG6VFIxyEP6xBdf+vhJxEDbRG2EYsHDRRtJ76gp9cSKTHusf2R+4AAVGqnt +gRAbNqtcOar/7FSj+Pl8G3v0Bty0LcCSpbqgYlnv6z+rErQmmC6PPvSz97TDMCok +yKpCE9hFA1zkqK3TH4FmFvGeIaXJUIBZf4mArWuBTjWFW3nmhESRUn1VK3K3x42N +a5k6c2+EhrMFiLjxuH6JZoqL0/E93FF9SwIBAg== +-----END DH PARAMETERS----- diff --git a/libs/openssl/crypto/dh/dh4096.pem b/libs/openssl/crypto/dh/dh4096.pem new file mode 100644 index 00000000..390943a2 --- /dev/null +++ b/libs/openssl/crypto/dh/dh4096.pem @@ -0,0 +1,14 @@ +-----BEGIN DH PARAMETERS----- +MIICCAKCAgEA/urRnb6vkPYc/KEGXWnbCIOaKitq7ySIq9dTH7s+Ri59zs77zty7 +vfVlSe6VFTBWgYjD2XKUFmtqq6CqXMhVX5ElUDoYDpAyTH85xqNFLzFC7nKrff/H +TFKNttp22cZE9V0IPpzedPfnQkE7aUdmF9JnDyv21Z/818O93u1B4r0szdnmEvEF +bKuIxEHX+bp0ZR7RqE1AeifXGJX3d6tsd2PMAObxwwsv55RGkn50vHO4QxtTARr1 +rRUV5j3B3oPMgC7Offxx+98Xn45B1/G0Prp11anDsR1PGwtaCYipqsvMwQUSJtyE +EOQWk+yFkeMe4vWv367eEi0Sd/wnC+TSXBE3pYvpYerJ8n1MceI5GQTdarJ77OW9 +bGTHmxRsLSCM1jpLdPja5jjb4siAa6EHc4qN9c/iFKS3PQPJEnX7pXKBRs5f7AF3 +W3RIGt+G9IVNZfXaS7Z/iCpgzgvKCs0VeqN38QsJGtC1aIkwOeyjPNy2G6jJ4yqH +ovXYt/0mc00vCWeSNS1wren0pR2EiLxX0ypjjgsU1mk/Z3b/+zVf7fZSIB+nDLjb +NPtUlJCVGnAeBK1J1nG3TQicqowOXoM6ISkdaXj5GPJdXHab2+S7cqhKGv5qC7rR +jT6sx7RUr0CNTxzLI7muV2/a4tGmj0PSdXQdsZ7tw7gbXlaWT1+MM2MCAQI= +-----END DH PARAMETERS----- + diff --git a/libs/openssl/crypto/dh/dh512.pem b/libs/openssl/crypto/dh/dh512.pem new file mode 100644 index 00000000..0a4d863e --- /dev/null +++ b/libs/openssl/crypto/dh/dh512.pem @@ -0,0 +1,4 @@ +-----BEGIN DH PARAMETERS----- +MEYCQQDaWDwW2YUiidDkr3VvTMqS3UvlM7gE+w/tlO+cikQD7VdGUNNpmdsp13Yn +a6LT1BLiGPTdHghM9tgAPnxHdOgzAgEC +-----END DH PARAMETERS----- diff --git a/libs/openssl/crypto/dh/dh_ameth.c b/libs/openssl/crypto/dh/dh_ameth.c new file mode 100644 index 00000000..873eb2e2 --- /dev/null +++ b/libs/openssl/crypto/dh/dh_ameth.c @@ -0,0 +1,492 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include "asn1_locl.h" + +static void int_dh_free(EVP_PKEY *pkey) +{ + DH_free(pkey->pkey.dh); +} + +static int dh_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +{ + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + void *pval; + ASN1_STRING *pstr; + X509_ALGOR *palg; + ASN1_INTEGER *public_key = NULL; + + DH *dh = NULL; + + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (ptype != V_ASN1_SEQUENCE) { + DHerr(DH_F_DH_PUB_DECODE, DH_R_PARAMETER_ENCODING_ERROR); + goto err; + } + + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + + if (!(dh = d2i_DHparams(NULL, &pm, pmlen))) { + DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); + goto err; + } + + if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, pklen))) { + DHerr(DH_F_DH_PUB_DECODE, DH_R_DECODE_ERROR); + goto err; + } + + /* We have parameters now set public key */ + if (!(dh->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { + DHerr(DH_F_DH_PUB_DECODE, DH_R_BN_DECODE_ERROR); + goto err; + } + + ASN1_INTEGER_free(public_key); + EVP_PKEY_assign_DH(pkey, dh); + return 1; + + err: + if (public_key) + ASN1_INTEGER_free(public_key); + if (dh) + DH_free(dh); + return 0; + +} + +static int dh_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) +{ + DH *dh; + int ptype; + unsigned char *penc = NULL; + int penclen; + ASN1_STRING *str; + ASN1_INTEGER *pub_key = NULL; + + dh = pkey->pkey.dh; + + str = ASN1_STRING_new(); + if (!str) { + DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + str->length = i2d_DHparams(dh, &str->data); + if (str->length <= 0) { + DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + ptype = V_ASN1_SEQUENCE; + + pub_key = BN_to_ASN1_INTEGER(dh->pub_key, NULL); + if (!pub_key) + goto err; + + penclen = i2d_ASN1_INTEGER(pub_key, &penc); + + ASN1_INTEGER_free(pub_key); + + if (penclen <= 0) { + DHerr(DH_F_DH_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DH), + ptype, str, penc, penclen)) + return 1; + + err: + if (penc) + OPENSSL_free(penc); + if (str) + ASN1_STRING_free(str); + + return 0; +} + +/* + * PKCS#8 DH is defined in PKCS#11 of all places. It is similar to DH in that + * the AlgorithmIdentifier contains the paramaters, the private key is + * explcitly included and the pubkey must be recalculated. + */ + +static int dh_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) +{ + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + void *pval; + ASN1_STRING *pstr; + X509_ALGOR *palg; + ASN1_INTEGER *privkey = NULL; + + DH *dh = NULL; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) + return 0; + + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (ptype != V_ASN1_SEQUENCE) + goto decerr; + + if (!(privkey = d2i_ASN1_INTEGER(NULL, &p, pklen))) + goto decerr; + + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + if (!(dh = d2i_DHparams(NULL, &pm, pmlen))) + goto decerr; + /* We have parameters now set private key */ + if (!(dh->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { + DHerr(DH_F_DH_PRIV_DECODE, DH_R_BN_ERROR); + goto dherr; + } + /* Calculate public key */ + if (!DH_generate_key(dh)) + goto dherr; + + EVP_PKEY_assign_DH(pkey, dh); + + ASN1_STRING_clear_free(privkey); + + return 1; + + decerr: + DHerr(DH_F_DH_PRIV_DECODE, EVP_R_DECODE_ERROR); + dherr: + DH_free(dh); + ASN1_STRING_clear_free(privkey); + return 0; +} + +static int dh_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + ASN1_STRING *params = NULL; + ASN1_INTEGER *prkey = NULL; + unsigned char *dp = NULL; + int dplen; + + params = ASN1_STRING_new(); + + if (!params) { + DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + + params->length = i2d_DHparams(pkey->pkey.dh, ¶ms->data); + if (params->length <= 0) { + DHerr(DH_F_DH_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + params->type = V_ASN1_SEQUENCE; + + /* Get private key into integer */ + prkey = BN_to_ASN1_INTEGER(pkey->pkey.dh->priv_key, NULL); + + if (!prkey) { + DHerr(DH_F_DH_PRIV_ENCODE, DH_R_BN_ERROR); + goto err; + } + + dplen = i2d_ASN1_INTEGER(prkey, &dp); + + ASN1_STRING_clear_free(prkey); + prkey = NULL; + + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dhKeyAgreement), 0, + V_ASN1_SEQUENCE, params, dp, dplen)) + goto err; + + return 1; + + err: + if (dp != NULL) + OPENSSL_free(dp); + if (params != NULL) + ASN1_STRING_free(params); + if (prkey != NULL) + ASN1_STRING_clear_free(prkey); + return 0; +} + +static void update_buflen(const BIGNUM *b, size_t *pbuflen) +{ + size_t i; + if (!b) + return; + if (*pbuflen < (i = (size_t)BN_num_bytes(b))) + *pbuflen = i; +} + +static int dh_param_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + DH *dh; + if (!(dh = d2i_DHparams(NULL, pder, derlen))) { + DHerr(DH_F_DH_PARAM_DECODE, ERR_R_DH_LIB); + return 0; + } + EVP_PKEY_assign_DH(pkey, dh); + return 1; +} + +static int dh_param_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_DHparams(pkey->pkey.dh, pder); +} + +static int do_dh_print(BIO *bp, const DH *x, int indent, + ASN1_PCTX *ctx, int ptype) +{ + unsigned char *m = NULL; + int reason = ERR_R_BUF_LIB, ret = 0; + size_t buf_len = 0; + + const char *ktype = NULL; + + BIGNUM *priv_key, *pub_key; + + if (ptype == 2) + priv_key = x->priv_key; + else + priv_key = NULL; + + if (ptype > 0) + pub_key = x->pub_key; + else + pub_key = NULL; + + update_buflen(x->p, &buf_len); + + if (buf_len == 0) { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + update_buflen(x->g, &buf_len); + update_buflen(pub_key, &buf_len); + update_buflen(priv_key, &buf_len); + + if (ptype == 2) + ktype = "PKCS#3 DH Private-Key"; + else if (ptype == 1) + ktype = "PKCS#3 DH Public-Key"; + else + ktype = "PKCS#3 DH Parameters"; + + m = OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + BIO_indent(bp, indent, 128); + if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) + goto err; + indent += 4; + + if (!ASN1_bn_print(bp, "private-key:", priv_key, m, indent)) + goto err; + if (!ASN1_bn_print(bp, "public-key:", pub_key, m, indent)) + goto err; + + if (!ASN1_bn_print(bp, "prime:", x->p, m, indent)) + goto err; + if (!ASN1_bn_print(bp, "generator:", x->g, m, indent)) + goto err; + if (x->length != 0) { + BIO_indent(bp, indent, 128); + if (BIO_printf(bp, "recommended-private-length: %d bits\n", + (int)x->length) <= 0) + goto err; + } + + ret = 1; + if (0) { + err: + DHerr(DH_F_DO_DH_PRINT, reason); + } + if (m != NULL) + OPENSSL_free(m); + return (ret); +} + +static int int_dh_size(const EVP_PKEY *pkey) +{ + return (DH_size(pkey->pkey.dh)); +} + +static int dh_bits(const EVP_PKEY *pkey) +{ + return BN_num_bits(pkey->pkey.dh->p); +} + +static int dh_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (BN_cmp(a->pkey.dh->p, b->pkey.dh->p) || + BN_cmp(a->pkey.dh->g, b->pkey.dh->g)) + return 0; + else + return 1; +} + +static int dh_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) +{ + BIGNUM *a; + + if ((a = BN_dup(from->pkey.dh->p)) == NULL) + return 0; + if (to->pkey.dh->p != NULL) + BN_free(to->pkey.dh->p); + to->pkey.dh->p = a; + + if ((a = BN_dup(from->pkey.dh->g)) == NULL) + return 0; + if (to->pkey.dh->g != NULL) + BN_free(to->pkey.dh->g); + to->pkey.dh->g = a; + + return 1; +} + +static int dh_missing_parameters(const EVP_PKEY *a) +{ + if (!a->pkey.dh->p || !a->pkey.dh->g) + return 1; + return 0; +} + +static int dh_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (dh_cmp_parameters(a, b) == 0) + return 0; + if (BN_cmp(b->pkey.dh->pub_key, a->pkey.dh->pub_key) != 0) + return 0; + else + return 1; +} + +static int dh_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 0); +} + +static int dh_public_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 1); +} + +static int dh_private_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_dh_print(bp, pkey->pkey.dh, indent, ctx, 2); +} + +int DHparams_print(BIO *bp, const DH *x) +{ + return do_dh_print(bp, x, 4, NULL, 0); +} + +const EVP_PKEY_ASN1_METHOD dh_asn1_meth = { + EVP_PKEY_DH, + EVP_PKEY_DH, + 0, + + "DH", + "OpenSSL PKCS#3 DH method", + + dh_pub_decode, + dh_pub_encode, + dh_pub_cmp, + dh_public_print, + + dh_priv_decode, + dh_priv_encode, + dh_private_print, + + int_dh_size, + dh_bits, + + dh_param_decode, + dh_param_encode, + dh_missing_parameters, + dh_copy_parameters, + dh_cmp_parameters, + dh_param_print, + 0, + + int_dh_free, + 0 +}; diff --git a/libs/openssl/crypto/dh/dh_asn1.c b/libs/openssl/crypto/dh/dh_asn1.c new file mode 100644 index 00000000..e6ee3cfc --- /dev/null +++ b/libs/openssl/crypto/dh/dh_asn1.c @@ -0,0 +1,95 @@ +/* dh_asn1.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +/* Override the default free and new methods */ +static int dh_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_NEW_PRE) { + *pval = (ASN1_VALUE *)DH_new(); + if (*pval) + return 2; + return 0; + } else if (operation == ASN1_OP_FREE_PRE) { + DH_free((DH *)*pval); + *pval = NULL; + return 2; + } + return 1; +} + +ASN1_SEQUENCE_cb(DHparams, dh_cb) = { + ASN1_SIMPLE(DH, p, BIGNUM), + ASN1_SIMPLE(DH, g, BIGNUM), + ASN1_OPT(DH, length, ZLONG), +} ASN1_SEQUENCE_END_cb(DH, DHparams) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DH, DHparams, DHparams) + +DH *DHparams_dup(DH *dh) +{ + return ASN1_item_dup(ASN1_ITEM_rptr(DHparams), dh); +} diff --git a/libs/openssl/crypto/dh/dh_check.c b/libs/openssl/crypto/dh/dh_check.c new file mode 100644 index 00000000..c39ed97b --- /dev/null +++ b/libs/openssl/crypto/dh/dh_check.c @@ -0,0 +1,147 @@ +/* crypto/dh/dh_check.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +/*- + * Check that p is a safe prime and + * if g is 2, 3 or 5, check that it is a suitable generator + * where + * for 2, p mod 24 == 11 + * for 3, p mod 12 == 5 + * for 5, p mod 10 == 3 or 7 + * should hold. + */ + +int DH_check(const DH *dh, int *ret) +{ + int ok = 0; + BN_CTX *ctx = NULL; + BN_ULONG l; + BIGNUM *q = NULL; + + *ret = 0; + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + q = BN_new(); + if (q == NULL) + goto err; + + if (BN_is_word(dh->g, DH_GENERATOR_2)) { + l = BN_mod_word(dh->p, 24); + if (l != 11) + *ret |= DH_NOT_SUITABLE_GENERATOR; + } +#if 0 + else if (BN_is_word(dh->g, DH_GENERATOR_3)) { + l = BN_mod_word(dh->p, 12); + if (l != 5) + *ret |= DH_NOT_SUITABLE_GENERATOR; + } +#endif + else if (BN_is_word(dh->g, DH_GENERATOR_5)) { + l = BN_mod_word(dh->p, 10); + if ((l != 3) && (l != 7)) + *ret |= DH_NOT_SUITABLE_GENERATOR; + } else + *ret |= DH_UNABLE_TO_CHECK_GENERATOR; + + if (!BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL)) + *ret |= DH_CHECK_P_NOT_PRIME; + else { + if (!BN_rshift1(q, dh->p)) + goto err; + if (!BN_is_prime_ex(q, BN_prime_checks, ctx, NULL)) + *ret |= DH_CHECK_P_NOT_SAFE_PRIME; + } + ok = 1; + err: + if (ctx != NULL) + BN_CTX_free(ctx); + if (q != NULL) + BN_free(q); + return (ok); +} + +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret) +{ + int ok = 0; + BIGNUM *q = NULL; + + *ret = 0; + q = BN_new(); + if (q == NULL) + goto err; + BN_set_word(q, 1); + if (BN_cmp(pub_key, q) <= 0) + *ret |= DH_CHECK_PUBKEY_TOO_SMALL; + BN_copy(q, dh->p); + BN_sub_word(q, 1); + if (BN_cmp(pub_key, q) >= 0) + *ret |= DH_CHECK_PUBKEY_TOO_LARGE; + + ok = 1; + err: + if (q != NULL) + BN_free(q); + return (ok); +} diff --git a/libs/openssl/crypto/dh/dh_depr.c b/libs/openssl/crypto/dh/dh_depr.c new file mode 100644 index 00000000..b6221199 --- /dev/null +++ b/libs/openssl/crypto/dh/dh_depr.c @@ -0,0 +1,82 @@ +/* crypto/dh/dh_depr.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* This file contains deprecated functions as wrappers to the new ones */ + +#include +#include "cryptlib.h" +#include +#include + +static void *dummy = &dummy; + +#ifndef OPENSSL_NO_DEPRECATED +DH *DH_generate_parameters(int prime_len, int generator, + void (*callback) (int, int, void *), void *cb_arg) +{ + BN_GENCB cb; + DH *ret = NULL; + + if ((ret = DH_new()) == NULL) + return NULL; + + BN_GENCB_set_old(&cb, callback, cb_arg); + + if (DH_generate_parameters_ex(ret, prime_len, generator, &cb)) + return ret; + DH_free(ret); + return NULL; +} +#endif diff --git a/libs/openssl/crypto/dh/dh_err.c b/libs/openssl/crypto/dh/dh_err.c new file mode 100644 index 00000000..6ed5eb78 --- /dev/null +++ b/libs/openssl/crypto/dh/dh_err.c @@ -0,0 +1,120 @@ +/* crypto/dh/dh_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DH,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DH,0,reason) + +static ERR_STRING_DATA DH_str_functs[] = { + {ERR_FUNC(DH_F_COMPUTE_KEY), "COMPUTE_KEY"}, + {ERR_FUNC(DH_F_DHPARAMS_PRINT_FP), "DHparams_print_fp"}, + {ERR_FUNC(DH_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"}, + {ERR_FUNC(DH_F_DH_COMPUTE_KEY), "DH_compute_key"}, + {ERR_FUNC(DH_F_DH_GENERATE_KEY), "DH_generate_key"}, + {ERR_FUNC(DH_F_DH_GENERATE_PARAMETERS_EX), "DH_generate_parameters_ex"}, + {ERR_FUNC(DH_F_DH_NEW_METHOD), "DH_new_method"}, + {ERR_FUNC(DH_F_DH_PARAM_DECODE), "DH_PARAM_DECODE"}, + {ERR_FUNC(DH_F_DH_PRIV_DECODE), "DH_PRIV_DECODE"}, + {ERR_FUNC(DH_F_DH_PRIV_ENCODE), "DH_PRIV_ENCODE"}, + {ERR_FUNC(DH_F_DH_PUB_DECODE), "DH_PUB_DECODE"}, + {ERR_FUNC(DH_F_DH_PUB_ENCODE), "DH_PUB_ENCODE"}, + {ERR_FUNC(DH_F_DO_DH_PRINT), "DO_DH_PRINT"}, + {ERR_FUNC(DH_F_GENERATE_KEY), "GENERATE_KEY"}, + {ERR_FUNC(DH_F_GENERATE_PARAMETERS), "GENERATE_PARAMETERS"}, + {ERR_FUNC(DH_F_PKEY_DH_DERIVE), "PKEY_DH_DERIVE"}, + {ERR_FUNC(DH_F_PKEY_DH_KEYGEN), "PKEY_DH_KEYGEN"}, + {0, NULL} +}; + +static ERR_STRING_DATA DH_str_reasons[] = { + {ERR_REASON(DH_R_BAD_GENERATOR), "bad generator"}, + {ERR_REASON(DH_R_BN_DECODE_ERROR), "bn decode error"}, + {ERR_REASON(DH_R_BN_ERROR), "bn error"}, + {ERR_REASON(DH_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(DH_R_INVALID_PUBKEY), "invalid public key"}, + {ERR_REASON(DH_R_KEYS_NOT_SET), "keys not set"}, + {ERR_REASON(DH_R_KEY_SIZE_TOO_SMALL), "key size too small"}, + {ERR_REASON(DH_R_MODULUS_TOO_LARGE), "modulus too large"}, + {ERR_REASON(DH_R_NON_FIPS_METHOD), "non fips method"}, + {ERR_REASON(DH_R_NO_PARAMETERS_SET), "no parameters set"}, + {ERR_REASON(DH_R_NO_PRIVATE_VALUE), "no private value"}, + {ERR_REASON(DH_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"}, + {0, NULL} +}; + +#endif + +void ERR_load_DH_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(DH_str_functs[0].error) == NULL) { + ERR_load_strings(0, DH_str_functs); + ERR_load_strings(0, DH_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/dh/dh_gen.c b/libs/openssl/crypto/dh/dh_gen.c new file mode 100644 index 00000000..5bedb665 --- /dev/null +++ b/libs/openssl/crypto/dh/dh_gen.c @@ -0,0 +1,204 @@ +/* crypto/dh/dh_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * NB: These functions have been upgraded - the previous prototypes are in + * dh_depr.c as wrappers to these ones. - Geoff + */ + +#include +#include "cryptlib.h" +#include +#include + +#ifdef OPENSSL_FIPS +# include +#endif + +static int dh_builtin_genparams(DH *ret, int prime_len, int generator, + BN_GENCB *cb); + +int DH_generate_parameters_ex(DH *ret, int prime_len, int generator, + BN_GENCB *cb) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(ret->meth->flags & DH_FLAG_FIPS_METHOD) + && !(ret->flags & DH_FLAG_NON_FIPS_ALLOW)) { + DHerr(DH_F_DH_GENERATE_PARAMETERS_EX, DH_R_NON_FIPS_METHOD); + return 0; + } +#endif + if (ret->meth->generate_params) + return ret->meth->generate_params(ret, prime_len, generator, cb); +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_dh_generate_parameters_ex(ret, prime_len, generator, cb); +#endif + return dh_builtin_genparams(ret, prime_len, generator, cb); +} + +/*- + * We generate DH parameters as follows + * find a prime q which is prime_len/2 bits long. + * p=(2*q)+1 or (p-1)/2 = q + * For this case, g is a generator if + * g^((p-1)/q) mod p != 1 for values of q which are the factors of p-1. + * Since the factors of p-1 are q and 2, we just need to check + * g^2 mod p != 1 and g^q mod p != 1. + * + * Having said all that, + * there is another special case method for the generators 2, 3 and 5. + * for 2, p mod 24 == 11 + * for 3, p mod 12 == 5 <<<<< does not work for safe primes. + * for 5, p mod 10 == 3 or 7 + * + * Thanks to Phil Karn for the pointers about the + * special generators and for answering some of my questions. + * + * I've implemented the second simple method :-). + * Since DH should be using a safe prime (both p and q are prime), + * this generator function can take a very very long time to run. + */ +/* + * Actually there is no reason to insist that 'generator' be a generator. + * It's just as OK (and in some sense better) to use a generator of the + * order-q subgroup. + */ +static int dh_builtin_genparams(DH *ret, int prime_len, int generator, + BN_GENCB *cb) +{ + BIGNUM *t1, *t2; + int g, ok = -1; + BN_CTX *ctx = NULL; + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + t2 = BN_CTX_get(ctx); + if (t1 == NULL || t2 == NULL) + goto err; + + /* Make sure 'ret' has the necessary elements */ + if (!ret->p && ((ret->p = BN_new()) == NULL)) + goto err; + if (!ret->g && ((ret->g = BN_new()) == NULL)) + goto err; + + if (generator <= 1) { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, DH_R_BAD_GENERATOR); + goto err; + } + if (generator == DH_GENERATOR_2) { + if (!BN_set_word(t1, 24)) + goto err; + if (!BN_set_word(t2, 11)) + goto err; + g = 2; + } +#if 0 /* does not work for safe primes */ + else if (generator == DH_GENERATOR_3) { + if (!BN_set_word(t1, 12)) + goto err; + if (!BN_set_word(t2, 5)) + goto err; + g = 3; + } +#endif + else if (generator == DH_GENERATOR_5) { + if (!BN_set_word(t1, 10)) + goto err; + if (!BN_set_word(t2, 3)) + goto err; + /* + * BN_set_word(t3,7); just have to miss out on these ones :-( + */ + g = 5; + } else { + /* + * in the general case, don't worry if 'generator' is a generator or + * not: since we are using safe primes, it will generate either an + * order-q or an order-2q group, which both is OK + */ + if (!BN_set_word(t1, 2)) + goto err; + if (!BN_set_word(t2, 1)) + goto err; + g = generator; + } + + if (!BN_generate_prime_ex(ret->p, prime_len, 1, t1, t2, cb)) + goto err; + if (!BN_GENCB_call(cb, 3, 0)) + goto err; + if (!BN_set_word(ret->g, g)) + goto err; + ok = 1; + err: + if (ok == -1) { + DHerr(DH_F_DH_BUILTIN_GENPARAMS, ERR_R_BN_LIB); + ok = 0; + } + + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} diff --git a/libs/openssl/crypto/dh/dh_key.c b/libs/openssl/crypto/dh/dh_key.c new file mode 100644 index 00000000..9e1d8e58 --- /dev/null +++ b/libs/openssl/crypto/dh/dh_key.c @@ -0,0 +1,275 @@ +/* crypto/dh/dh_key.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +static int generate_key(DH *dh); +static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh); +static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); +static int dh_init(DH *dh); +static int dh_finish(DH *dh); + +int DH_generate_key(DH *dh) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD) + && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW)) { + DHerr(DH_F_DH_GENERATE_KEY, DH_R_NON_FIPS_METHOD); + return 0; + } +#endif + return dh->meth->generate_key(dh); +} + +int DH_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dh->meth->flags & DH_FLAG_FIPS_METHOD) + && !(dh->flags & DH_FLAG_NON_FIPS_ALLOW)) { + DHerr(DH_F_DH_COMPUTE_KEY, DH_R_NON_FIPS_METHOD); + return 0; + } +#endif + return dh->meth->compute_key(key, pub_key, dh); +} + +static DH_METHOD dh_ossl = { + "OpenSSL DH Method", + generate_key, + compute_key, + dh_bn_mod_exp, + dh_init, + dh_finish, + 0, + NULL, + NULL +}; + +const DH_METHOD *DH_OpenSSL(void) +{ + return &dh_ossl; +} + +static int generate_key(DH *dh) +{ + int ok = 0; + int generate_new_key = 0; + unsigned l; + BN_CTX *ctx; + BN_MONT_CTX *mont = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + + if (dh->priv_key == NULL) { + priv_key = BN_new(); + if (priv_key == NULL) + goto err; + generate_new_key = 1; + } else + priv_key = dh->priv_key; + + if (dh->pub_key == NULL) { + pub_key = BN_new(); + if (pub_key == NULL) + goto err; + } else + pub_key = dh->pub_key; + + if (dh->flags & DH_FLAG_CACHE_MONT_P) { + mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, + CRYPTO_LOCK_DH, dh->p, ctx); + if (!mont) + goto err; + } + + if (generate_new_key) { + if (dh->q) { + do { + if (!BN_rand_range(priv_key, dh->q)) + goto err; + } + while (BN_is_zero(priv_key) || BN_is_one(priv_key)); + } else { + /* secret exponent length */ + l = dh->length ? dh->length : BN_num_bits(dh->p) - 1; + if (!BN_rand(priv_key, l, 0, 0)) + goto err; + } + } + + { + BIGNUM local_prk; + BIGNUM *prk; + + if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) { + BN_init(&local_prk); + prk = &local_prk; + BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); + } else + prk = priv_key; + + if (!dh->meth->bn_mod_exp(dh, pub_key, dh->g, prk, dh->p, ctx, mont)) + goto err; + } + + dh->pub_key = pub_key; + dh->priv_key = priv_key; + ok = 1; + err: + if (ok != 1) + DHerr(DH_F_GENERATE_KEY, ERR_R_BN_LIB); + + if ((pub_key != NULL) && (dh->pub_key == NULL)) + BN_free(pub_key); + if ((priv_key != NULL) && (dh->priv_key == NULL)) + BN_free(priv_key); + BN_CTX_free(ctx); + return (ok); +} + +static int compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) +{ + BN_CTX *ctx = NULL; + BN_MONT_CTX *mont = NULL; + BIGNUM *tmp; + int ret = -1; + int check_result; + + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + DHerr(DH_F_COMPUTE_KEY, DH_R_MODULUS_TOO_LARGE); + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + + if (dh->priv_key == NULL) { + DHerr(DH_F_COMPUTE_KEY, DH_R_NO_PRIVATE_VALUE); + goto err; + } + + if (dh->flags & DH_FLAG_CACHE_MONT_P) { + mont = BN_MONT_CTX_set_locked(&dh->method_mont_p, + CRYPTO_LOCK_DH, dh->p, ctx); + if ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) == 0) { + /* XXX */ + BN_set_flags(dh->priv_key, BN_FLG_CONSTTIME); + } + if (!mont) + goto err; + } + + if (!DH_check_pub_key(dh, pub_key, &check_result) || check_result) { + DHerr(DH_F_COMPUTE_KEY, DH_R_INVALID_PUBKEY); + goto err; + } + + if (!dh-> + meth->bn_mod_exp(dh, tmp, pub_key, dh->priv_key, dh->p, ctx, mont)) { + DHerr(DH_F_COMPUTE_KEY, ERR_R_BN_LIB); + goto err; + } + + ret = BN_bn2bin(tmp, key); + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return (ret); +} + +static int dh_bn_mod_exp(const DH *dh, BIGNUM *r, + const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + /* + * If a is only one word long and constant time is false, use the faster + * exponenentiation function. + */ + if (a->top == 1 && ((dh->flags & DH_FLAG_NO_EXP_CONSTTIME) != 0)) { + BN_ULONG A = a->d[0]; + return BN_mod_exp_mont_word(r, A, p, m, ctx, m_ctx); + } else + return BN_mod_exp_mont(r, a, p, m, ctx, m_ctx); +} + +static int dh_init(DH *dh) +{ + dh->flags |= DH_FLAG_CACHE_MONT_P; + return (1); +} + +static int dh_finish(DH *dh) +{ + if (dh->method_mont_p) + BN_MONT_CTX_free(dh->method_mont_p); + return (1); +} diff --git a/libs/openssl/crypto/dh/dh_lib.c b/libs/openssl/crypto/dh/dh_lib.c new file mode 100644 index 00000000..bebc160e --- /dev/null +++ b/libs/openssl/crypto/dh/dh_lib.c @@ -0,0 +1,263 @@ +/* crypto/dh/dh_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif + +#ifdef OPENSSL_FIPS +# include +#endif + +const char DH_version[] = "Diffie-Hellman" OPENSSL_VERSION_PTEXT; + +static const DH_METHOD *default_DH_method = NULL; + +void DH_set_default_method(const DH_METHOD *meth) +{ + default_DH_method = meth; +} + +const DH_METHOD *DH_get_default_method(void) +{ + if (!default_DH_method) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_dh_openssl(); + else + return DH_OpenSSL(); +#else + default_DH_method = DH_OpenSSL(); +#endif + } + return default_DH_method; +} + +int DH_set_method(DH *dh, const DH_METHOD *meth) +{ + /* + * NB: The caller is specifically setting a method, so it's not up to us + * to deal with which ENGINE it comes from. + */ + const DH_METHOD *mtmp; + mtmp = dh->meth; + if (mtmp->finish) + mtmp->finish(dh); +#ifndef OPENSSL_NO_ENGINE + if (dh->engine) { + ENGINE_finish(dh->engine); + dh->engine = NULL; + } +#endif + dh->meth = meth; + if (meth->init) + meth->init(dh); + return 1; +} + +DH *DH_new(void) +{ + return DH_new_method(NULL); +} + +DH *DH_new_method(ENGINE *engine) +{ + DH *ret; + + ret = (DH *)OPENSSL_malloc(sizeof(DH)); + if (ret == NULL) { + DHerr(DH_F_DH_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + ret->meth = DH_get_default_method(); +#ifndef OPENSSL_NO_ENGINE + if (engine) { + if (!ENGINE_init(engine)) { + DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB); + OPENSSL_free(ret); + return NULL; + } + ret->engine = engine; + } else + ret->engine = ENGINE_get_default_DH(); + if (ret->engine) { + ret->meth = ENGINE_get_DH(ret->engine); + if (!ret->meth) { + DHerr(DH_F_DH_NEW_METHOD, ERR_R_ENGINE_LIB); + ENGINE_finish(ret->engine); + OPENSSL_free(ret); + return NULL; + } + } +#endif + + ret->pad = 0; + ret->version = 0; + ret->p = NULL; + ret->g = NULL; + ret->length = 0; + ret->pub_key = NULL; + ret->priv_key = NULL; + ret->q = NULL; + ret->j = NULL; + ret->seed = NULL; + ret->seedlen = 0; + ret->counter = NULL; + ret->method_mont_p = NULL; + ret->references = 1; + ret->flags = ret->meth->flags & ~DH_FLAG_NON_FIPS_ALLOW; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data); + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, ret, &ret->ex_data); + OPENSSL_free(ret); + ret = NULL; + } + return (ret); +} + +void DH_free(DH *r) +{ + int i; + if (r == NULL) + return; + i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DH); +#ifdef REF_PRINT + REF_PRINT("DH", r); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "DH_free, bad reference count\n"); + abort(); + } +#endif + + if (r->meth->finish) + r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE + if (r->engine) + ENGINE_finish(r->engine); +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DH, r, &r->ex_data); + + if (r->p != NULL) + BN_clear_free(r->p); + if (r->g != NULL) + BN_clear_free(r->g); + if (r->q != NULL) + BN_clear_free(r->q); + if (r->j != NULL) + BN_clear_free(r->j); + if (r->seed) + OPENSSL_free(r->seed); + if (r->counter != NULL) + BN_clear_free(r->counter); + if (r->pub_key != NULL) + BN_clear_free(r->pub_key); + if (r->priv_key != NULL) + BN_clear_free(r->priv_key); + OPENSSL_free(r); +} + +int DH_up_ref(DH *r) +{ + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DH); +#ifdef REF_PRINT + REF_PRINT("DH", r); +#endif +#ifdef REF_CHECK + if (i < 2) { + fprintf(stderr, "DH_up, bad reference count\n"); + abort(); + } +#endif + return ((i > 1) ? 1 : 0); +} + +int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DH, argl, argp, + new_func, dup_func, free_func); +} + +int DH_set_ex_data(DH *d, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&d->ex_data, idx, arg)); +} + +void *DH_get_ex_data(DH *d, int idx) +{ + return (CRYPTO_get_ex_data(&d->ex_data, idx)); +} + +int DH_size(const DH *dh) +{ + return (BN_num_bytes(dh->p)); +} diff --git a/libs/openssl/crypto/dh/dh_pmeth.c b/libs/openssl/crypto/dh/dh_pmeth.c new file mode 100644 index 00000000..65bc3882 --- /dev/null +++ b/libs/openssl/crypto/dh/dh_pmeth.c @@ -0,0 +1,245 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include "evp_locl.h" + +/* DH pkey context structure */ + +typedef struct { + /* Parameter gen parameters */ + int prime_len; + int generator; + int use_dsa; + /* Keygen callback info */ + int gentmp[2]; + /* message digest */ +} DH_PKEY_CTX; + +static int pkey_dh_init(EVP_PKEY_CTX *ctx) +{ + DH_PKEY_CTX *dctx; + dctx = OPENSSL_malloc(sizeof(DH_PKEY_CTX)); + if (!dctx) + return 0; + dctx->prime_len = 1024; + dctx->generator = 2; + dctx->use_dsa = 0; + + ctx->data = dctx; + ctx->keygen_info = dctx->gentmp; + ctx->keygen_info_count = 2; + + return 1; +} + +static int pkey_dh_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + DH_PKEY_CTX *dctx, *sctx; + if (!pkey_dh_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->prime_len = sctx->prime_len; + dctx->generator = sctx->generator; + dctx->use_dsa = sctx->use_dsa; + return 1; +} + +static void pkey_dh_cleanup(EVP_PKEY_CTX *ctx) +{ + DH_PKEY_CTX *dctx = ctx->data; + if (dctx) + OPENSSL_free(dctx); +} + +static int pkey_dh_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + DH_PKEY_CTX *dctx = ctx->data; + switch (type) { + case EVP_PKEY_CTRL_DH_PARAMGEN_PRIME_LEN: + if (p1 < 256) + return -2; + dctx->prime_len = p1; + return 1; + + case EVP_PKEY_CTRL_DH_PARAMGEN_GENERATOR: + dctx->generator = p1; + return 1; + + case EVP_PKEY_CTRL_PEER_KEY: + /* Default behaviour is OK */ + return 1; + + default: + return -2; + + } +} + +static int pkey_dh_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (!strcmp(type, "dh_paramgen_prime_len")) { + int len; + len = atoi(value); + return EVP_PKEY_CTX_set_dh_paramgen_prime_len(ctx, len); + } + if (!strcmp(type, "dh_paramgen_generator")) { + int len; + len = atoi(value); + return EVP_PKEY_CTX_set_dh_paramgen_generator(ctx, len); + } + return -2; +} + +static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + DH *dh = NULL; + DH_PKEY_CTX *dctx = ctx->data; + BN_GENCB *pcb, cb; + int ret; + if (ctx->pkey_gencb) { + pcb = &cb; + evp_pkey_set_cb_translate(pcb, ctx); + } else + pcb = NULL; + dh = DH_new(); + if (!dh) + return 0; + ret = DH_generate_parameters_ex(dh, + dctx->prime_len, dctx->generator, pcb); + if (ret) + EVP_PKEY_assign_DH(pkey, dh); + else + DH_free(dh); + return ret; +} + +static int pkey_dh_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + DH *dh = NULL; + if (ctx->pkey == NULL) { + DHerr(DH_F_PKEY_DH_KEYGEN, DH_R_NO_PARAMETERS_SET); + return 0; + } + dh = DH_new(); + if (!dh) + return 0; + EVP_PKEY_assign_DH(pkey, dh); + /* Note: if error return, pkey is freed by parent routine */ + if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) + return 0; + return DH_generate_key(pkey->pkey.dh); +} + +static int pkey_dh_derive(EVP_PKEY_CTX *ctx, unsigned char *key, + size_t *keylen) +{ + int ret; + if (!ctx->pkey || !ctx->peerkey) { + DHerr(DH_F_PKEY_DH_DERIVE, DH_R_KEYS_NOT_SET); + return 0; + } + ret = DH_compute_key(key, ctx->peerkey->pkey.dh->pub_key, + ctx->pkey->pkey.dh); + if (ret < 0) + return ret; + *keylen = ret; + return 1; +} + +const EVP_PKEY_METHOD dh_pkey_meth = { + EVP_PKEY_DH, + EVP_PKEY_FLAG_AUTOARGLEN, + pkey_dh_init, + pkey_dh_copy, + pkey_dh_cleanup, + + 0, + pkey_dh_paramgen, + + 0, + pkey_dh_keygen, + + 0, + 0, + + 0, + 0, + + 0, 0, + + 0, 0, 0, 0, + + 0, 0, + + 0, 0, + + 0, + pkey_dh_derive, + + pkey_dh_ctrl, + pkey_dh_ctrl_str +}; diff --git a/libs/openssl/crypto/dh/dh_prn.c b/libs/openssl/crypto/dh/dh_prn.c new file mode 100644 index 00000000..5d6c3a37 --- /dev/null +++ b/libs/openssl/crypto/dh/dh_prn.c @@ -0,0 +1,79 @@ +/* crypto/asn1/t_pkey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +#ifndef OPENSSL_NO_FP_API +int DHparams_print_fp(FILE *fp, const DH *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + DHerr(DH_F_DHPARAMS_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = DHparams_print(b, x); + BIO_free(b); + return (ret); +} +#endif diff --git a/libs/openssl/crypto/dh/dhtest.c b/libs/openssl/crypto/dh/dhtest.c new file mode 100644 index 00000000..5a4ee9a3 --- /dev/null +++ b/libs/openssl/crypto/dh/dhtest.c @@ -0,0 +1,241 @@ +/* crypto/dh/dhtest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * Until the key-gen callbacks are modified to use newer prototypes, we allow + * deprecated functions for openssl-internal code + */ +#ifdef OPENSSL_NO_DEPRECATED +# undef OPENSSL_NO_DEPRECATED +#endif + +#include +#include +#include + +#include "../e_os.h" + +#include +#include +#include +#include +#include + +#ifdef OPENSSL_NO_DH +int main(int argc, char *argv[]) +{ + printf("No DH support\n"); + return (0); +} +#else +# include + +# ifdef OPENSSL_SYS_WIN16 +# define MS_CALLBACK _far _loadds +# else +# define MS_CALLBACK +# endif + +static int MS_CALLBACK cb(int p, int n, BN_GENCB *arg); + +static const char rnd_seed[] = + "string to make the random number generator think it has entropy"; + +int main(int argc, char *argv[]) +{ + BN_GENCB _cb; + DH *a; + DH *b = NULL; + char buf[12]; + unsigned char *abuf = NULL, *bbuf = NULL; + int i, alen, blen, aout, bout, ret = 1; + BIO *out; + + CRYPTO_malloc_debug_init(); + CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + +# ifdef OPENSSL_SYS_WIN32 + CRYPTO_malloc_init(); +# endif + + RAND_seed(rnd_seed, sizeof rnd_seed); + + out = BIO_new(BIO_s_file()); + if (out == NULL) + EXIT(1); + BIO_set_fp(out, stdout, BIO_NOCLOSE); + + BN_GENCB_set(&_cb, &cb, out); + if (((a = DH_new()) == NULL) || !DH_generate_parameters_ex(a, 64, + DH_GENERATOR_5, + &_cb)) + goto err; + + if (!DH_check(a, &i)) + goto err; + if (i & DH_CHECK_P_NOT_PRIME) + BIO_puts(out, "p value is not prime\n"); + if (i & DH_CHECK_P_NOT_SAFE_PRIME) + BIO_puts(out, "p value is not a safe prime\n"); + if (i & DH_UNABLE_TO_CHECK_GENERATOR) + BIO_puts(out, "unable to check the generator value\n"); + if (i & DH_NOT_SUITABLE_GENERATOR) + BIO_puts(out, "the g value is not a generator\n"); + + BIO_puts(out, "\np ="); + BN_print(out, a->p); + BIO_puts(out, "\ng ="); + BN_print(out, a->g); + BIO_puts(out, "\n"); + + b = DH_new(); + if (b == NULL) + goto err; + + b->p = BN_dup(a->p); + b->g = BN_dup(a->g); + if ((b->p == NULL) || (b->g == NULL)) + goto err; + + /* Set a to run with normal modexp and b to use constant time */ + a->flags &= ~DH_FLAG_NO_EXP_CONSTTIME; + b->flags |= DH_FLAG_NO_EXP_CONSTTIME; + + if (!DH_generate_key(a)) + goto err; + BIO_puts(out, "pri 1="); + BN_print(out, a->priv_key); + BIO_puts(out, "\npub 1="); + BN_print(out, a->pub_key); + BIO_puts(out, "\n"); + + if (!DH_generate_key(b)) + goto err; + BIO_puts(out, "pri 2="); + BN_print(out, b->priv_key); + BIO_puts(out, "\npub 2="); + BN_print(out, b->pub_key); + BIO_puts(out, "\n"); + + alen = DH_size(a); + abuf = (unsigned char *)OPENSSL_malloc(alen); + aout = DH_compute_key(abuf, b->pub_key, a); + + BIO_puts(out, "key1 ="); + for (i = 0; i < aout; i++) { + sprintf(buf, "%02X", abuf[i]); + BIO_puts(out, buf); + } + BIO_puts(out, "\n"); + + blen = DH_size(b); + bbuf = (unsigned char *)OPENSSL_malloc(blen); + bout = DH_compute_key(bbuf, a->pub_key, b); + + BIO_puts(out, "key2 ="); + for (i = 0; i < bout; i++) { + sprintf(buf, "%02X", bbuf[i]); + BIO_puts(out, buf); + } + BIO_puts(out, "\n"); + if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) { + fprintf(stderr, "Error in DH routines\n"); + ret = 1; + } else + ret = 0; + err: + ERR_print_errors_fp(stderr); + + if (abuf != NULL) + OPENSSL_free(abuf); + if (bbuf != NULL) + OPENSSL_free(bbuf); + if (b != NULL) + DH_free(b); + if (a != NULL) + DH_free(a); + BIO_free(out); +# ifdef OPENSSL_SYS_NETWARE + if (ret) + printf("ERROR: %d\n", ret); +# endif + EXIT(ret); + return (ret); +} + +static int MS_CALLBACK cb(int p, int n, BN_GENCB *arg) +{ + char c = '*'; + + if (p == 0) + c = '.'; + if (p == 1) + c = '+'; + if (p == 2) + c = '*'; + if (p == 3) + c = '\n'; + BIO_write(arg->arg, &c, 1); + (void)BIO_flush(arg->arg); +# ifdef LINT + p = n; +# endif + return 1; +} +#endif diff --git a/libs/openssl/crypto/dh/example b/libs/openssl/crypto/dh/example new file mode 100644 index 00000000..16a33d29 --- /dev/null +++ b/libs/openssl/crypto/dh/example @@ -0,0 +1,50 @@ +From owner-cypherpunks@toad.com Mon Sep 25 10:50:51 1995 +Received: from minbne.mincom.oz.au by orb.mincom.oz.au with SMTP id AA10562 + (5.65c/IDA-1.4.4 for eay); Wed, 27 Sep 1995 19:41:55 +1000 +Received: by minbne.mincom.oz.au id AA19958 + (5.65c/IDA-1.4.4 for eay@orb.mincom.oz.au); Wed, 27 Sep 1995 19:34:59 +1000 +Received: from relay3.UU.NET by bunyip.cc.uq.oz.au with SMTP (PP); + Wed, 27 Sep 1995 19:13:05 +1000 +Received: from toad.com by relay3.UU.NET with SMTP id QQzizb16156; + Wed, 27 Sep 1995 04:48:46 -0400 +Received: by toad.com id AA07905; Tue, 26 Sep 95 06:31:45 PDT +Received: from by toad.com id AB07851; Tue, 26 Sep 95 06:31:40 PDT +Received: from servo.qualcomm.com (servo.qualcomm.com [129.46.128.14]) + by cygnus.com (8.6.12/8.6.9) with ESMTP id RAA18442 + for ; Mon, 25 Sep 1995 17:52:47 -0700 +Received: (karn@localhost) by servo.qualcomm.com (8.6.12/QC-BSD-2.5.1) + id RAA14732; Mon, 25 Sep 1995 17:50:51 -0700 +Date: Mon, 25 Sep 1995 17:50:51 -0700 +From: Phil Karn +Message-Id: <199509260050.RAA14732@servo.qualcomm.com> +To: cypherpunks@toad.com, ipsec-dev@eit.com +Subject: Primality verification needed +Sender: owner-cypherpunks@toad.com +Precedence: bulk +Status: RO +X-Status: + +Hi. I've generated a 2047-bit "strong" prime number that I would like to +use with Diffie-Hellman key exchange. I assert that not only is this number +'p' prime, but so is (p-1)/2. + +I've used the mpz_probab_prime() function in the Gnu Math Package (GMP) version +1.3.2 to test this number. This function uses the Miller-Rabin primality test. +However, to increase my confidence that this number really is a strong prime, +I'd like to ask others to confirm it with other tests. Here's the number in hex: + +72a925f760b2f954ed287f1b0953f3e6aef92e456172f9fe86fdd8822241b9c9788fbc289982743e +fbcd2ccf062b242d7a567ba8bbb40d79bca7b8e0b6c05f835a5b938d985816bc648985adcff5402a +a76756b36c845a840a1d059ce02707e19cf47af0b5a882f32315c19d1b86a56c5389c5e9bee16b65 +fde7b1a8d74a7675de9b707d4c5a4633c0290c95ff30a605aeb7ae864ff48370f13cf01d49adb9f2 +3d19a439f753ee7703cf342d87f431105c843c78ca4df639931f3458fae8a94d1687e99a76ed99d0 +ba87189f42fd31ad8262c54a8cf5914ae6c28c540d714a5f6087a171fb74f4814c6f968d72386ef3 +56a05180c3bec7ddd5ef6fe76b1f717b + +The generator, g, for this prime is 2. + +Thanks! + +Phil Karn + + diff --git a/libs/openssl/crypto/dh/generate b/libs/openssl/crypto/dh/generate new file mode 100644 index 00000000..5d407231 --- /dev/null +++ b/libs/openssl/crypto/dh/generate @@ -0,0 +1,65 @@ +From: stewarts@ix.netcom.com (Bill Stewart) +Newsgroups: sci.crypt +Subject: Re: Diffie-Hellman key exchange +Date: Wed, 11 Oct 1995 23:08:28 GMT +Organization: Freelance Information Architect +Lines: 32 +Message-ID: <45hir2$7l8@ixnews7.ix.netcom.com> +References: <458rhn$76m$1@mhadf.production.compuserve.com> +NNTP-Posting-Host: ix-pl4-16.ix.netcom.com +X-NETCOM-Date: Wed Oct 11 4:09:22 PM PDT 1995 +X-Newsreader: Forte Free Agent 1.0.82 + +Kent Briggs <72124.3234@CompuServe.COM> wrote: + +>I have a copy of the 1976 IEEE article describing the +>Diffie-Hellman public key exchange algorithm: y=a^x mod q. I'm +>looking for sources that give examples of secure a,q pairs and +>possible some source code that I could examine. + +q should be prime, and ideally should be a "strong prime", +which means it's of the form 2n+1 where n is also prime. +q also needs to be long enough to prevent the attacks LaMacchia and +Odlyzko described (some variant on a factoring attack which generates +a large pile of simultaneous equations and then solves them); +long enough is about the same size as factoring, so 512 bits may not +be secure enough for most applications. (The 192 bits used by +"secure NFS" was certainly not long enough.) + +a should be a generator for q, which means it needs to be +relatively prime to q-1. Usually a small prime like 2, 3 or 5 will +work. + +.... + +Date: Tue, 26 Sep 1995 13:52:36 MST +From: "Richard Schroeppel" +To: karn +Cc: ho@cs.arizona.edu +Subject: random large primes + +Since your prime is really random, proving it is hard. +My personal limit on rigorously proved primes is ~350 digits. +If you really want a proof, we should talk to Francois Morain, +or the Australian group. + +If you want 2 to be a generator (mod P), then you need it +to be a non-square. If (P-1)/2 is also prime, then +non-square == primitive-root for bases << P. + +In the case at hand, this means 2 is a generator iff P = 11 (mod 24). +If you want this, you should restrict your sieve accordingly. + +3 is a generator iff P = 5 (mod 12). + +5 is a generator iff P = 3 or 7 (mod 10). + +2 is perfectly usable as a base even if it's a non-generator, since +it still covers half the space of possible residues. And an +eavesdropper can always determine the low-bit of your exponent for +a generator anyway. + +Rich rcs@cs.arizona.edu + + + diff --git a/libs/openssl/crypto/dh/p1024.c b/libs/openssl/crypto/dh/p1024.c new file mode 100644 index 00000000..a4b014b6 --- /dev/null +++ b/libs/openssl/crypto/dh/p1024.c @@ -0,0 +1,92 @@ +/* crypto/dh/p1024.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include + +unsigned char data[] = { 0x97, 0xF6, 0x42, 0x61, 0xCA, 0xB5, 0x05, 0xDD, + 0x28, 0x28, 0xE1, 0x3F, 0x1D, 0x68, 0xB6, 0xD3, + 0xDB, 0xD0, 0xF3, 0x13, 0x04, 0x7F, 0x40, 0xE8, + 0x56, 0xDA, 0x58, 0xCB, 0x13, 0xB8, 0xA1, 0xBF, + 0x2B, 0x78, 0x3A, 0x4C, 0x6D, 0x59, 0xD5, 0xF9, + 0x2A, 0xFC, 0x6C, 0xFF, 0x3D, 0x69, 0x3F, 0x78, + 0xB2, 0x3D, 0x4F, 0x31, 0x60, 0xA9, 0x50, 0x2E, + 0x3E, 0xFA, 0xF7, 0xAB, 0x5E, 0x1A, 0xD5, 0xA6, + 0x5E, 0x55, 0x43, 0x13, 0x82, 0x8D, 0xA8, 0x3B, + 0x9F, 0xF2, 0xD9, 0x41, 0xDE, 0xE9, 0x56, 0x89, + 0xFA, 0xDA, 0xEA, 0x09, 0x36, 0xAD, 0xDF, 0x19, + 0x71, 0xFE, 0x63, 0x5B, 0x20, 0xAF, 0x47, 0x03, + 0x64, 0x60, 0x3C, 0x2D, 0xE0, 0x59, 0xF5, 0x4B, + 0x65, 0x0A, 0xD8, 0xFA, 0x0C, 0xF7, 0x01, 0x21, + 0xC7, 0x47, 0x99, 0xD7, 0x58, 0x71, 0x32, 0xBE, + 0x9B, 0x99, 0x9B, 0xB9, 0xB7, 0x87, 0xE8, 0xAB, +}; + +main() +{ + DH *dh; + + dh = DH_new(); + dh->p = BN_bin2bn(data, sizeof(data), NULL); + dh->g = BN_new(); + BN_set_word(dh->g, 2); + PEM_write_DHparams(stdout, dh); +} diff --git a/libs/openssl/crypto/dh/p192.c b/libs/openssl/crypto/dh/p192.c new file mode 100644 index 00000000..9f49f768 --- /dev/null +++ b/libs/openssl/crypto/dh/p192.c @@ -0,0 +1,80 @@ +/* crypto/dh/p192.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include + +unsigned char data[] = { + 0xD4, 0xA0, 0xBA, 0x02, 0x50, 0xB6, 0xFD, 0x2E, + 0xC6, 0x26, 0xE7, 0xEF, 0xD6, 0x37, 0xDF, 0x76, + 0xC7, 0x16, 0xE2, 0x2D, 0x09, 0x44, 0xB8, 0x8B, +}; + +main() +{ + DH *dh; + + dh = DH_new(); + dh->p = BN_bin2bn(data, sizeof(data), NULL); + dh->g = BN_new(); + BN_set_word(dh->g, 3); + PEM_write_DHparams(stdout, dh); +} diff --git a/libs/openssl/crypto/dh/p512.c b/libs/openssl/crypto/dh/p512.c new file mode 100644 index 00000000..606fa4d6 --- /dev/null +++ b/libs/openssl/crypto/dh/p512.c @@ -0,0 +1,85 @@ +/* crypto/dh/p512.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include + +unsigned char data[] = { + 0xDA, 0x58, 0x3C, 0x16, 0xD9, 0x85, 0x22, 0x89, + 0xD0, 0xE4, 0xAF, 0x75, 0x6F, 0x4C, 0xCA, 0x92, + 0xDD, 0x4B, 0xE5, 0x33, 0xB8, 0x04, 0xFB, 0x0F, + 0xED, 0x94, 0xEF, 0x9C, 0x8A, 0x44, 0x03, 0xED, + 0x57, 0x46, 0x50, 0xD3, 0x69, 0x99, 0xDB, 0x29, + 0xD7, 0x76, 0x27, 0x6B, 0xA2, 0xD3, 0xD4, 0x12, + 0xE2, 0x18, 0xF4, 0xDD, 0x1E, 0x08, 0x4C, 0xF6, + 0xD8, 0x00, 0x3E, 0x7C, 0x47, 0x74, 0xE8, 0x33, +}; + +main() +{ + DH *dh; + + dh = DH_new(); + dh->p = BN_bin2bn(data, sizeof(data), NULL); + dh->g = BN_new(); + BN_set_word(dh->g, 2); + PEM_write_DHparams(stdout, dh); +} diff --git a/libs/openssl/crypto/dsa/README b/libs/openssl/crypto/dsa/README new file mode 100644 index 00000000..6a7e9c17 --- /dev/null +++ b/libs/openssl/crypto/dsa/README @@ -0,0 +1,4 @@ +The stuff in here is based on patches supplied to me by +Steven Schoch to do DSS. +I have since modified a them a little but a debt of gratitude +is due for doing the initial work. diff --git a/libs/openssl/crypto/dsa/dsa.h b/libs/openssl/crypto/dsa/dsa.h new file mode 100644 index 00000000..a2f0ee78 --- /dev/null +++ b/libs/openssl/crypto/dsa/dsa.h @@ -0,0 +1,329 @@ +/* crypto/dsa/dsa.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * The DSS routines are based on patches supplied by + * Steven Schoch . He basically did the + * work and I have just tweaked them a little to fit into my + * stylistic vision for SSLeay :-) */ + +#ifndef HEADER_DSA_H +# define HEADER_DSA_H + +# include + +# ifdef OPENSSL_NO_DSA +# error DSA is disabled. +# endif + +# ifndef OPENSSL_NO_BIO +# include +# endif +# include +# include + +# ifndef OPENSSL_NO_DEPRECATED +# include +# ifndef OPENSSL_NO_DH +# include +# endif +# endif + +# ifndef OPENSSL_DSA_MAX_MODULUS_BITS +# define OPENSSL_DSA_MAX_MODULUS_BITS 10000 +# endif + +# define DSA_FLAG_CACHE_MONT_P 0x01 +/* + * new with 0.9.7h; the built-in DSA implementation now uses constant time + * modular exponentiation for secret exponents by default. This flag causes + * the faster variable sliding window method to be used for all exponents. + */ +# define DSA_FLAG_NO_EXP_CONSTTIME 0x02 + +/* + * If this flag is set the DSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its reposibility to ensure the + * result is compliant. + */ + +# define DSA_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define DSA_FLAG_NON_FIPS_ALLOW 0x0400 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Already defined in ossl_typ.h */ +/* typedef struct dsa_st DSA; */ +/* typedef struct dsa_method DSA_METHOD; */ + +typedef struct DSA_SIG_st { + BIGNUM *r; + BIGNUM *s; +} DSA_SIG; + +struct dsa_method { + const char *name; + DSA_SIG *(*dsa_do_sign) (const unsigned char *dgst, int dlen, DSA *dsa); + int (*dsa_sign_setup) (DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); + int (*dsa_do_verify) (const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); + int (*dsa_mod_exp) (DSA *dsa, BIGNUM *rr, BIGNUM *a1, BIGNUM *p1, + BIGNUM *a2, BIGNUM *p2, BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont); + /* Can be null */ + int (*bn_mod_exp) (DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + int (*init) (DSA *dsa); + int (*finish) (DSA *dsa); + int flags; + char *app_data; + /* If this is non-NULL, it is used to generate DSA parameters */ + int (*dsa_paramgen) (DSA *dsa, int bits, + const unsigned char *seed, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); + /* If this is non-NULL, it is used to generate DSA keys */ + int (*dsa_keygen) (DSA *dsa); +}; + +struct dsa_st { + /* + * This first variable is used to pick up errors where a DSA is passed + * instead of of a EVP_PKEY + */ + int pad; + long version; + int write_params; + BIGNUM *p; + BIGNUM *q; /* == 20 */ + BIGNUM *g; + BIGNUM *pub_key; /* y public key */ + BIGNUM *priv_key; /* x private key */ + BIGNUM *kinv; /* Signing pre-calc */ + BIGNUM *r; /* Signing pre-calc */ + int flags; + /* Normally used to cache montgomery values */ + BN_MONT_CTX *method_mont_p; + int references; + CRYPTO_EX_DATA ex_data; + const DSA_METHOD *meth; + /* functional reference if 'meth' is ENGINE-provided */ + ENGINE *engine; +}; + +# define d2i_DSAparams_fp(fp,x) (DSA *)ASN1_d2i_fp((char *(*)())DSA_new, \ + (char *(*)())d2i_DSAparams,(fp),(unsigned char **)(x)) +# define i2d_DSAparams_fp(fp,x) ASN1_i2d_fp(i2d_DSAparams,(fp), \ + (unsigned char *)(x)) +# define d2i_DSAparams_bio(bp,x) ASN1_d2i_bio_of(DSA,DSA_new,d2i_DSAparams,bp,x) +# define i2d_DSAparams_bio(bp,x) ASN1_i2d_bio_of_const(DSA,i2d_DSAparams,bp,x) + +DSA *DSAparams_dup(DSA *x); +DSA_SIG *DSA_SIG_new(void); +void DSA_SIG_free(DSA_SIG *a); +int i2d_DSA_SIG(const DSA_SIG *a, unsigned char **pp); +DSA_SIG *d2i_DSA_SIG(DSA_SIG **v, const unsigned char **pp, long length); + +DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); +int DSA_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); + +const DSA_METHOD *DSA_OpenSSL(void); + +void DSA_set_default_method(const DSA_METHOD *); +const DSA_METHOD *DSA_get_default_method(void); +int DSA_set_method(DSA *dsa, const DSA_METHOD *); + +DSA *DSA_new(void); +DSA *DSA_new_method(ENGINE *engine); +void DSA_free(DSA *r); +/* "up" the DSA object's reference count */ +int DSA_up_ref(DSA *r); +int DSA_size(const DSA *); + /* next 4 return -1 on error */ +int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp); +int DSA_sign(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa); +int DSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa); +int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int DSA_set_ex_data(DSA *d, int idx, void *arg); +void *DSA_get_ex_data(DSA *d, int idx); + +DSA *d2i_DSAPublicKey(DSA **a, const unsigned char **pp, long length); +DSA *d2i_DSAPrivateKey(DSA **a, const unsigned char **pp, long length); +DSA *d2i_DSAparams(DSA **a, const unsigned char **pp, long length); + +/* Deprecated version */ +# ifndef OPENSSL_NO_DEPRECATED +DSA *DSA_generate_parameters(int bits, + unsigned char *seed, int seed_len, + int *counter_ret, unsigned long *h_ret, void + (*callback) (int, int, void *), void *cb_arg); +# endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int DSA_generate_parameters_ex(DSA *dsa, int bits, + const unsigned char *seed, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); + +int DSA_generate_key(DSA *a); +int i2d_DSAPublicKey(const DSA *a, unsigned char **pp); +int i2d_DSAPrivateKey(const DSA *a, unsigned char **pp); +int i2d_DSAparams(const DSA *a, unsigned char **pp); + +# ifndef OPENSSL_NO_BIO +int DSAparams_print(BIO *bp, const DSA *x); +int DSA_print(BIO *bp, const DSA *x, int off); +# endif +# ifndef OPENSSL_NO_FP_API +int DSAparams_print_fp(FILE *fp, const DSA *x); +int DSA_print_fp(FILE *bp, const DSA *x, int off); +# endif + +# define DSS_prime_checks 50 +/* + * Primality test according to FIPS PUB 186[-1], Appendix 2.1: 50 rounds of + * Rabin-Miller + */ +# define DSA_is_prime(n, callback, cb_arg) \ + BN_is_prime(n, DSS_prime_checks, callback, NULL, cb_arg) + +# ifndef OPENSSL_NO_DH +/* + * Convert DSA structure (key or just parameters) into DH structure (be + * careful to avoid small subgroup attacks when using this!) + */ +DH *DSA_dup_DH(const DSA *r); +# endif + +# define EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_DSA_PARAMGEN_BITS, nbits, NULL) + +# define EVP_PKEY_CTRL_DSA_PARAMGEN_BITS (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS (EVP_PKEY_ALG_CTRL + 2) +# define EVP_PKEY_CTRL_DSA_PARAMGEN_MD (EVP_PKEY_ALG_CTRL + 3) + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_DSA_strings(void); + +/* Error codes for the DSA functions. */ + +/* Function codes. */ +# define DSA_F_D2I_DSA_SIG 110 +# define DSA_F_DO_DSA_PRINT 104 +# define DSA_F_DSAPARAMS_PRINT 100 +# define DSA_F_DSAPARAMS_PRINT_FP 101 +# define DSA_F_DSA_DO_SIGN 112 +# define DSA_F_DSA_DO_VERIFY 113 +# define DSA_F_DSA_GENERATE_KEY 124 +# define DSA_F_DSA_GENERATE_PARAMETERS_EX 123 +# define DSA_F_DSA_NEW_METHOD 103 +# define DSA_F_DSA_PARAM_DECODE 119 +# define DSA_F_DSA_PRINT_FP 105 +# define DSA_F_DSA_PRIV_DECODE 115 +# define DSA_F_DSA_PRIV_ENCODE 116 +# define DSA_F_DSA_PUB_DECODE 117 +# define DSA_F_DSA_PUB_ENCODE 118 +# define DSA_F_DSA_SIGN 106 +# define DSA_F_DSA_SIGN_SETUP 107 +# define DSA_F_DSA_SIG_NEW 109 +# define DSA_F_DSA_SIG_PRINT 125 +# define DSA_F_DSA_VERIFY 108 +# define DSA_F_I2D_DSA_SIG 111 +# define DSA_F_OLD_DSA_PRIV_DECODE 122 +# define DSA_F_PKEY_DSA_CTRL 120 +# define DSA_F_PKEY_DSA_KEYGEN 121 +# define DSA_F_SIG_CB 114 + +/* Reason codes. */ +# define DSA_R_BAD_Q_VALUE 102 +# define DSA_R_BN_DECODE_ERROR 108 +# define DSA_R_BN_ERROR 109 +# define DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 100 +# define DSA_R_DECODE_ERROR 104 +# define DSA_R_INVALID_DIGEST_TYPE 106 +# define DSA_R_MISSING_PARAMETERS 101 +# define DSA_R_MODULUS_TOO_LARGE 103 +# define DSA_R_NEED_NEW_SETUP_VALUES 110 +# define DSA_R_NON_FIPS_DSA_METHOD 111 +# define DSA_R_NO_PARAMETERS_SET 107 +# define DSA_R_PARAMETER_ENCODING_ERROR 105 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/dsa/dsa_ameth.c b/libs/openssl/crypto/dsa/dsa_ameth.c new file mode 100644 index 00000000..f5443e30 --- /dev/null +++ b/libs/openssl/crypto/dsa/dsa_ameth.c @@ -0,0 +1,674 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#ifndef OPENSSL_NO_CMS +# include +#endif +#include "asn1_locl.h" + +static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +{ + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + void *pval; + ASN1_STRING *pstr; + X509_ALGOR *palg; + ASN1_INTEGER *public_key = NULL; + + DSA *dsa = NULL; + + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + if (ptype == V_ASN1_SEQUENCE) { + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + + if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) { + DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); + goto err; + } + + } else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) { + if (!(dsa = DSA_new())) { + DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE); + goto err; + } + } else { + DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR); + goto err; + } + + if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, pklen))) { + DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR); + goto err; + } + + if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) { + DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR); + goto err; + } + + ASN1_INTEGER_free(public_key); + EVP_PKEY_assign_DSA(pkey, dsa); + return 1; + + err: + if (public_key) + ASN1_INTEGER_free(public_key); + if (dsa) + DSA_free(dsa); + return 0; + +} + +static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) +{ + DSA *dsa; + int ptype; + unsigned char *penc = NULL; + int penclen; + ASN1_STRING *str = NULL; + + dsa = pkey->pkey.dsa; + if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) { + str = ASN1_STRING_new(); + if (!str) { + DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + str->length = i2d_DSAparams(dsa, &str->data); + if (str->length <= 0) { + DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + ptype = V_ASN1_SEQUENCE; + } else + ptype = V_ASN1_UNDEF; + + dsa->write_params = 0; + + penclen = i2d_DSAPublicKey(dsa, &penc); + + if (penclen <= 0) { + DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), + ptype, str, penc, penclen)) + return 1; + + err: + if (penc) + OPENSSL_free(penc); + if (str) + ASN1_STRING_free(str); + + return 0; +} + +/* + * In PKCS#8 DSA: you just get a private key integer and parameters in the + * AlgorithmIdentifier the pubkey must be recalculated. + */ + +static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) +{ + const unsigned char *p, *pm; + int pklen, pmlen; + int ptype; + void *pval; + ASN1_STRING *pstr; + X509_ALGOR *palg; + ASN1_INTEGER *privkey = NULL; + BN_CTX *ctx = NULL; + + STACK_OF(ASN1_TYPE) *ndsa = NULL; + DSA *dsa = NULL; + + int ret = 0; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + /* Check for broken DSA PKCS#8, UGH! */ + if (*p == (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) { + ASN1_TYPE *t1, *t2; + if (!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen))) + goto decerr; + if (sk_ASN1_TYPE_num(ndsa) != 2) + goto decerr; + /*- + * Handle Two broken types: + * SEQUENCE {parameters, priv_key} + * SEQUENCE {pub_key, priv_key} + */ + + t1 = sk_ASN1_TYPE_value(ndsa, 0); + t2 = sk_ASN1_TYPE_value(ndsa, 1); + if (t1->type == V_ASN1_SEQUENCE) { + p8->broken = PKCS8_EMBEDDED_PARAM; + pval = t1->value.ptr; + } else if (ptype == V_ASN1_SEQUENCE) + p8->broken = PKCS8_NS_DB; + else + goto decerr; + + if (t2->type != V_ASN1_INTEGER) + goto decerr; + + privkey = t2->value.integer; + } else { + const unsigned char *q = p; + if (!(privkey = d2i_ASN1_INTEGER(NULL, &p, pklen))) + goto decerr; + if (privkey->type == V_ASN1_NEG_INTEGER) { + p8->broken = PKCS8_NEG_PRIVKEY; + ASN1_STRING_clear_free(privkey); + if (!(privkey = d2i_ASN1_UINTEGER(NULL, &q, pklen))) + goto decerr; + } + if (ptype != V_ASN1_SEQUENCE) + goto decerr; + } + + pstr = pval; + pm = pstr->data; + pmlen = pstr->length; + if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) + goto decerr; + /* We have parameters now set private key */ + if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) { + DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR); + goto dsaerr; + } + /* Calculate public key */ + if (!(dsa->pub_key = BN_new())) { + DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); + goto dsaerr; + } + if (!(ctx = BN_CTX_new())) { + DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE); + goto dsaerr; + } + + if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { + DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR); + goto dsaerr; + } + + EVP_PKEY_assign_DSA(pkey, dsa); + + ret = 1; + goto done; + + decerr: + DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR); + dsaerr: + DSA_free(dsa); + done: + BN_CTX_free(ctx); + if (ndsa) + sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free); + else + ASN1_STRING_clear_free(privkey); + return ret; +} + +static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + ASN1_STRING *params = NULL; + ASN1_INTEGER *prkey = NULL; + unsigned char *dp = NULL; + int dplen; + + if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) { + DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_MISSING_PARAMETERS); + goto err; + } + + params = ASN1_STRING_new(); + + if (!params) { + DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + + params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data); + if (params->length <= 0) { + DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + goto err; + } + params->type = V_ASN1_SEQUENCE; + + /* Get private key into integer */ + prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL); + + if (!prkey) { + DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_BN_ERROR); + goto err; + } + + dplen = i2d_ASN1_INTEGER(prkey, &dp); + + ASN1_STRING_clear_free(prkey); + prkey = NULL; + + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0, + V_ASN1_SEQUENCE, params, dp, dplen)) + goto err; + + return 1; + + err: + if (dp != NULL) + OPENSSL_free(dp); + if (params != NULL) + ASN1_STRING_free(params); + if (prkey != NULL) + ASN1_STRING_clear_free(prkey); + return 0; +} + +static int int_dsa_size(const EVP_PKEY *pkey) +{ + return (DSA_size(pkey->pkey.dsa)); +} + +static int dsa_bits(const EVP_PKEY *pkey) +{ + return BN_num_bits(pkey->pkey.dsa->p); +} + +static int dsa_missing_parameters(const EVP_PKEY *pkey) +{ + DSA *dsa; + dsa = pkey->pkey.dsa; + if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL)) + return 1; + return 0; +} + +static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) +{ + BIGNUM *a; + + if ((a = BN_dup(from->pkey.dsa->p)) == NULL) + return 0; + if (to->pkey.dsa->p != NULL) + BN_free(to->pkey.dsa->p); + to->pkey.dsa->p = a; + + if ((a = BN_dup(from->pkey.dsa->q)) == NULL) + return 0; + if (to->pkey.dsa->q != NULL) + BN_free(to->pkey.dsa->q); + to->pkey.dsa->q = a; + + if ((a = BN_dup(from->pkey.dsa->g)) == NULL) + return 0; + if (to->pkey.dsa->g != NULL) + BN_free(to->pkey.dsa->g); + to->pkey.dsa->g = a; + return 1; +} + +static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) || + BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) || + BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g)) + return 0; + else + return 1; +} + +static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0) + return 0; + else + return 1; +} + +static void int_dsa_free(EVP_PKEY *pkey) +{ + DSA_free(pkey->pkey.dsa); +} + +static void update_buflen(const BIGNUM *b, size_t *pbuflen) +{ + size_t i; + if (!b) + return; + if (*pbuflen < (i = (size_t)BN_num_bytes(b))) + *pbuflen = i; +} + +static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) +{ + unsigned char *m = NULL; + int ret = 0; + size_t buf_len = 0; + const char *ktype = NULL; + + const BIGNUM *priv_key, *pub_key; + + if (ptype == 2) + priv_key = x->priv_key; + else + priv_key = NULL; + + if (ptype > 0) + pub_key = x->pub_key; + else + pub_key = NULL; + + if (ptype == 2) + ktype = "Private-Key"; + else if (ptype == 1) + ktype = "Public-Key"; + else + ktype = "DSA-Parameters"; + + update_buflen(x->p, &buf_len); + update_buflen(x->q, &buf_len); + update_buflen(x->g, &buf_len); + update_buflen(priv_key, &buf_len); + update_buflen(pub_key, &buf_len); + + m = (unsigned char *)OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + DSAerr(DSA_F_DO_DSA_PRINT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (priv_key) { + if (!BIO_indent(bp, off, 128)) + goto err; + if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) + <= 0) + goto err; + } + + if (!ASN1_bn_print(bp, "priv:", priv_key, m, off)) + goto err; + if (!ASN1_bn_print(bp, "pub: ", pub_key, m, off)) + goto err; + if (!ASN1_bn_print(bp, "P: ", x->p, m, off)) + goto err; + if (!ASN1_bn_print(bp, "Q: ", x->q, m, off)) + goto err; + if (!ASN1_bn_print(bp, "G: ", x->g, m, off)) + goto err; + ret = 1; + err: + if (m != NULL) + OPENSSL_free(m); + return (ret); +} + +static int dsa_param_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + DSA *dsa; + if (!(dsa = d2i_DSAparams(NULL, pder, derlen))) { + DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB); + return 0; + } + EVP_PKEY_assign_DSA(pkey, dsa); + return 1; +} + +static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_DSAparams(pkey->pkey.dsa, pder); +} + +static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); +} + +static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); +} + +static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); +} + +static int old_dsa_priv_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + DSA *dsa; + if (!(dsa = d2i_DSAPrivateKey(NULL, pder, derlen))) { + DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB); + return 0; + } + EVP_PKEY_assign_DSA(pkey, dsa); + return 1; +} + +static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_DSAPrivateKey(pkey->pkey.dsa, pder); +} + +static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, + const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) +{ + DSA_SIG *dsa_sig; + const unsigned char *p; + if (!sig) { + if (BIO_puts(bp, "\n") <= 0) + return 0; + else + return 1; + } + p = sig->data; + dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); + if (dsa_sig) { + int rv = 0; + size_t buf_len = 0; + unsigned char *m = NULL; + update_buflen(dsa_sig->r, &buf_len); + update_buflen(dsa_sig->s, &buf_len); + m = OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + DSAerr(DSA_F_DSA_SIG_PRINT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (BIO_write(bp, "\n", 1) != 1) + goto err; + + if (!ASN1_bn_print(bp, "r: ", dsa_sig->r, m, indent)) + goto err; + if (!ASN1_bn_print(bp, "s: ", dsa_sig->s, m, indent)) + goto err; + rv = 1; + err: + if (m) + OPENSSL_free(m); + DSA_SIG_free(dsa_sig); + return rv; + } + return X509_signature_dump(bp, sig, indent); +} + +static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +#endif + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha1; + return 2; + + default: + return -2; + + } + +} + +/* NB these are sorted in pkey_id order, lowest first */ + +const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = { + + { + EVP_PKEY_DSA2, + EVP_PKEY_DSA, + ASN1_PKEY_ALIAS}, + + { + EVP_PKEY_DSA1, + EVP_PKEY_DSA, + ASN1_PKEY_ALIAS}, + + { + EVP_PKEY_DSA4, + EVP_PKEY_DSA, + ASN1_PKEY_ALIAS}, + + { + EVP_PKEY_DSA3, + EVP_PKEY_DSA, + ASN1_PKEY_ALIAS}, + + { + EVP_PKEY_DSA, + EVP_PKEY_DSA, + 0, + + "DSA", + "OpenSSL DSA method", + + dsa_pub_decode, + dsa_pub_encode, + dsa_pub_cmp, + dsa_pub_print, + + dsa_priv_decode, + dsa_priv_encode, + dsa_priv_print, + + int_dsa_size, + dsa_bits, + + dsa_param_decode, + dsa_param_encode, + dsa_missing_parameters, + dsa_copy_parameters, + dsa_cmp_parameters, + dsa_param_print, + dsa_sig_print, + + int_dsa_free, + dsa_pkey_ctrl, + old_dsa_priv_decode, + old_dsa_priv_encode} +}; diff --git a/libs/openssl/crypto/dsa/dsa_asn1.c b/libs/openssl/crypto/dsa/dsa_asn1.c new file mode 100644 index 00000000..3283a229 --- /dev/null +++ b/libs/openssl/crypto/dsa/dsa_asn1.c @@ -0,0 +1,202 @@ +/* dsa_asn1.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +/* Override the default new methods */ +static int sig_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_NEW_PRE) { + DSA_SIG *sig; + sig = OPENSSL_malloc(sizeof(DSA_SIG)); + if (!sig) { + DSAerr(DSA_F_SIG_CB, ERR_R_MALLOC_FAILURE); + return 0; + } + sig->r = NULL; + sig->s = NULL; + *pval = (ASN1_VALUE *)sig; + return 2; + } + return 1; +} + +ASN1_SEQUENCE_cb(DSA_SIG, sig_cb) = { + ASN1_SIMPLE(DSA_SIG, r, CBIGNUM), + ASN1_SIMPLE(DSA_SIG, s, CBIGNUM) +} ASN1_SEQUENCE_END_cb(DSA_SIG, DSA_SIG) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA_SIG, DSA_SIG, DSA_SIG) + +/* Override the default free and new methods */ +static int dsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_NEW_PRE) { + *pval = (ASN1_VALUE *)DSA_new(); + if (*pval) + return 2; + return 0; + } else if (operation == ASN1_OP_FREE_PRE) { + DSA_free((DSA *)*pval); + *pval = NULL; + return 2; + } + return 1; +} + +ASN1_SEQUENCE_cb(DSAPrivateKey, dsa_cb) = { + ASN1_SIMPLE(DSA, version, LONG), + ASN1_SIMPLE(DSA, p, BIGNUM), + ASN1_SIMPLE(DSA, q, BIGNUM), + ASN1_SIMPLE(DSA, g, BIGNUM), + ASN1_SIMPLE(DSA, pub_key, BIGNUM), + ASN1_SIMPLE(DSA, priv_key, BIGNUM) +} ASN1_SEQUENCE_END_cb(DSA, DSAPrivateKey) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPrivateKey, DSAPrivateKey) + +ASN1_SEQUENCE_cb(DSAparams, dsa_cb) = { + ASN1_SIMPLE(DSA, p, BIGNUM), + ASN1_SIMPLE(DSA, q, BIGNUM), + ASN1_SIMPLE(DSA, g, BIGNUM), +} ASN1_SEQUENCE_END_cb(DSA, DSAparams) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAparams, DSAparams) + +/* + * DSA public key is a bit trickier... its effectively a CHOICE type decided + * by a field called write_params which can either write out just the public + * key as an INTEGER or the parameters and public key in a SEQUENCE + */ + +ASN1_SEQUENCE(dsa_pub_internal) = { + ASN1_SIMPLE(DSA, pub_key, BIGNUM), + ASN1_SIMPLE(DSA, p, BIGNUM), + ASN1_SIMPLE(DSA, q, BIGNUM), + ASN1_SIMPLE(DSA, g, BIGNUM) +} ASN1_SEQUENCE_END_name(DSA, dsa_pub_internal) + +ASN1_CHOICE_cb(DSAPublicKey, dsa_cb) = { + ASN1_SIMPLE(DSA, pub_key, BIGNUM), + ASN1_EX_COMBINE(0, 0, dsa_pub_internal) +} ASN1_CHOICE_END_cb(DSA, DSAPublicKey, write_params) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(DSA, DSAPublicKey, DSAPublicKey) + +DSA *DSAparams_dup(DSA *dsa) +{ + return ASN1_item_dup(ASN1_ITEM_rptr(DSAparams), dsa); +} + +int DSA_sign(int type, const unsigned char *dgst, int dlen, + unsigned char *sig, unsigned int *siglen, DSA *dsa) +{ + DSA_SIG *s; + RAND_seed(dgst, dlen); + s = DSA_do_sign(dgst, dlen, dsa); + if (s == NULL) { + *siglen = 0; + return (0); + } + *siglen = i2d_DSA_SIG(s, &sig); + DSA_SIG_free(s); + return (1); +} + +/* data has already been hashed (probably with SHA or SHA-1). */ +/*- + * returns + * 1: correct signature + * 0: incorrect signature + * -1: error + */ +int DSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int siglen, DSA *dsa) +{ + DSA_SIG *s; + const unsigned char *p = sigbuf; + unsigned char *der = NULL; + int derlen = -1; + int ret = -1; + + s = DSA_SIG_new(); + if (s == NULL) + return (ret); + if (d2i_DSA_SIG(&s, &p, siglen) == NULL) + goto err; + /* Ensure signature uses DER and doesn't have trailing garbage */ + derlen = i2d_DSA_SIG(s, &der); + if (derlen != siglen || memcmp(sigbuf, der, derlen)) + goto err; + ret = DSA_do_verify(dgst, dgst_len, s, dsa); + err: + if (derlen > 0) { + OPENSSL_cleanse(der, derlen); + OPENSSL_free(der); + } + DSA_SIG_free(s); + return (ret); +} diff --git a/libs/openssl/crypto/dsa/dsa_depr.c b/libs/openssl/crypto/dsa/dsa_depr.c new file mode 100644 index 00000000..54f88bc4 --- /dev/null +++ b/libs/openssl/crypto/dsa/dsa_depr.c @@ -0,0 +1,113 @@ +/* crypto/dsa/dsa_depr.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * This file contains deprecated function(s) that are now wrappers to the new + * version(s). + */ + +#undef GENUINE_DSA + +#ifdef GENUINE_DSA +/* + * Parameter generation follows the original release of FIPS PUB 186, + * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) + */ +# define HASH EVP_sha() +#else +/* + * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186, + * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB + * 180-1) + */ +# define HASH EVP_sha1() +#endif + +static void *dummy = &dummy; + +#ifndef OPENSSL_NO_SHA + +# include +# include +# include "cryptlib.h" +# include +# include +# include +# include +# include + +# ifndef OPENSSL_NO_DEPRECATED +DSA *DSA_generate_parameters(int bits, + unsigned char *seed_in, int seed_len, + int *counter_ret, unsigned long *h_ret, + void (*callback) (int, int, void *), + void *cb_arg) +{ + BN_GENCB cb; + DSA *ret; + + if ((ret = DSA_new()) == NULL) + return NULL; + + BN_GENCB_set_old(&cb, callback, cb_arg); + + if (DSA_generate_parameters_ex(ret, bits, seed_in, seed_len, + counter_ret, h_ret, &cb)) + return ret; + DSA_free(ret); + return NULL; +} +# endif +#endif diff --git a/libs/openssl/crypto/dsa/dsa_err.c b/libs/openssl/crypto/dsa/dsa_err.c new file mode 100644 index 00000000..746f5dfe --- /dev/null +++ b/libs/openssl/crypto/dsa/dsa_err.c @@ -0,0 +1,130 @@ +/* crypto/dsa/dsa_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSA,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSA,0,reason) + +static ERR_STRING_DATA DSA_str_functs[] = { + {ERR_FUNC(DSA_F_D2I_DSA_SIG), "d2i_DSA_SIG"}, + {ERR_FUNC(DSA_F_DO_DSA_PRINT), "DO_DSA_PRINT"}, + {ERR_FUNC(DSA_F_DSAPARAMS_PRINT), "DSAparams_print"}, + {ERR_FUNC(DSA_F_DSAPARAMS_PRINT_FP), "DSAparams_print_fp"}, + {ERR_FUNC(DSA_F_DSA_DO_SIGN), "DSA_do_sign"}, + {ERR_FUNC(DSA_F_DSA_DO_VERIFY), "DSA_do_verify"}, + {ERR_FUNC(DSA_F_DSA_GENERATE_KEY), "DSA_generate_key"}, + {ERR_FUNC(DSA_F_DSA_GENERATE_PARAMETERS_EX), + "DSA_generate_parameters_ex"}, + {ERR_FUNC(DSA_F_DSA_NEW_METHOD), "DSA_new_method"}, + {ERR_FUNC(DSA_F_DSA_PARAM_DECODE), "DSA_PARAM_DECODE"}, + {ERR_FUNC(DSA_F_DSA_PRINT_FP), "DSA_print_fp"}, + {ERR_FUNC(DSA_F_DSA_PRIV_DECODE), "DSA_PRIV_DECODE"}, + {ERR_FUNC(DSA_F_DSA_PRIV_ENCODE), "DSA_PRIV_ENCODE"}, + {ERR_FUNC(DSA_F_DSA_PUB_DECODE), "DSA_PUB_DECODE"}, + {ERR_FUNC(DSA_F_DSA_PUB_ENCODE), "DSA_PUB_ENCODE"}, + {ERR_FUNC(DSA_F_DSA_SIGN), "DSA_sign"}, + {ERR_FUNC(DSA_F_DSA_SIGN_SETUP), "DSA_sign_setup"}, + {ERR_FUNC(DSA_F_DSA_SIG_NEW), "DSA_SIG_new"}, + {ERR_FUNC(DSA_F_DSA_SIG_PRINT), "DSA_SIG_PRINT"}, + {ERR_FUNC(DSA_F_DSA_VERIFY), "DSA_verify"}, + {ERR_FUNC(DSA_F_I2D_DSA_SIG), "i2d_DSA_SIG"}, + {ERR_FUNC(DSA_F_OLD_DSA_PRIV_DECODE), "OLD_DSA_PRIV_DECODE"}, + {ERR_FUNC(DSA_F_PKEY_DSA_CTRL), "PKEY_DSA_CTRL"}, + {ERR_FUNC(DSA_F_PKEY_DSA_KEYGEN), "PKEY_DSA_KEYGEN"}, + {ERR_FUNC(DSA_F_SIG_CB), "SIG_CB"}, + {0, NULL} +}; + +static ERR_STRING_DATA DSA_str_reasons[] = { + {ERR_REASON(DSA_R_BAD_Q_VALUE), "bad q value"}, + {ERR_REASON(DSA_R_BN_DECODE_ERROR), "bn decode error"}, + {ERR_REASON(DSA_R_BN_ERROR), "bn error"}, + {ERR_REASON(DSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), + "data too large for key size"}, + {ERR_REASON(DSA_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(DSA_R_INVALID_DIGEST_TYPE), "invalid digest type"}, + {ERR_REASON(DSA_R_MISSING_PARAMETERS), "missing parameters"}, + {ERR_REASON(DSA_R_MODULUS_TOO_LARGE), "modulus too large"}, + {ERR_REASON(DSA_R_NEED_NEW_SETUP_VALUES), "need new setup values"}, + {ERR_REASON(DSA_R_NON_FIPS_DSA_METHOD), "non fips dsa method"}, + {ERR_REASON(DSA_R_NO_PARAMETERS_SET), "no parameters set"}, + {ERR_REASON(DSA_R_PARAMETER_ENCODING_ERROR), "parameter encoding error"}, + {0, NULL} +}; + +#endif + +void ERR_load_DSA_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(DSA_str_functs[0].error) == NULL) { + ERR_load_strings(0, DSA_str_functs); + ERR_load_strings(0, DSA_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/dsa/dsa_gen.c b/libs/openssl/crypto/dsa/dsa_gen.c new file mode 100644 index 00000000..34c6113c --- /dev/null +++ b/libs/openssl/crypto/dsa/dsa_gen.c @@ -0,0 +1,379 @@ +/* crypto/dsa/dsa_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#undef GENUINE_DSA + +#ifdef GENUINE_DSA +/* + * Parameter generation follows the original release of FIPS PUB 186, + * Appendix 2.2 (i.e. use SHA as defined in FIPS PUB 180) + */ +# define HASH EVP_sha() +#else +/* + * Parameter generation follows the updated Appendix 2.2 for FIPS PUB 186, + * also Appendix 2.2 of FIPS PUB 186-1 (i.e. use SHA as defined in FIPS PUB + * 180-1) + */ +# define HASH EVP_sha1() +#endif + +#include /* To see if OPENSSL_NO_SHA is defined */ + +#ifndef OPENSSL_NO_SHA + +# include +# include "cryptlib.h" +# include +# include +# include +# include +# include "dsa_locl.h" + +# ifdef OPENSSL_FIPS +# include +# endif + +int DSA_generate_parameters_ex(DSA *ret, int bits, + const unsigned char *seed_in, int seed_len, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb) +{ +# ifdef OPENSSL_FIPS + if (FIPS_mode() && !(ret->meth->flags & DSA_FLAG_FIPS_METHOD) + && !(ret->flags & DSA_FLAG_NON_FIPS_ALLOW)) { + DSAerr(DSA_F_DSA_GENERATE_PARAMETERS_EX, DSA_R_NON_FIPS_DSA_METHOD); + return 0; + } +# endif + if (ret->meth->dsa_paramgen) + return ret->meth->dsa_paramgen(ret, bits, seed_in, seed_len, + counter_ret, h_ret, cb); +# ifdef OPENSSL_FIPS + else if (FIPS_mode()) { + return FIPS_dsa_generate_parameters_ex(ret, bits, + seed_in, seed_len, + counter_ret, h_ret, cb); + } +# endif + else { + const EVP_MD *evpmd = bits >= 2048 ? EVP_sha256() : EVP_sha1(); + size_t qbits = EVP_MD_size(evpmd) * 8; + + return dsa_builtin_paramgen(ret, bits, qbits, evpmd, + seed_in, seed_len, NULL, counter_ret, + h_ret, cb); + } +} + +int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, + const EVP_MD *evpmd, const unsigned char *seed_in, + size_t seed_len, unsigned char *seed_out, + int *counter_ret, unsigned long *h_ret, BN_GENCB *cb) +{ + int ok = 0; + unsigned char seed[SHA256_DIGEST_LENGTH]; + unsigned char md[SHA256_DIGEST_LENGTH]; + unsigned char buf[SHA256_DIGEST_LENGTH], buf2[SHA256_DIGEST_LENGTH]; + BIGNUM *r0, *W, *X, *c, *test; + BIGNUM *g = NULL, *q = NULL, *p = NULL; + BN_MONT_CTX *mont = NULL; + int i, k, n = 0, m = 0, qsize = qbits >> 3; + int counter = 0; + int r = 0; + BN_CTX *ctx = NULL; + unsigned int h = 2; + + if (qsize != SHA_DIGEST_LENGTH && qsize != SHA224_DIGEST_LENGTH && + qsize != SHA256_DIGEST_LENGTH) + /* invalid q size */ + return 0; + + if (evpmd == NULL) + /* use SHA1 as default */ + evpmd = EVP_sha1(); + + if (bits < 512) + bits = 512; + + bits = (bits + 63) / 64 * 64; + + /* + * NB: seed_len == 0 is special case: copy generated seed to seed_in if + * it is not NULL. + */ + if (seed_len && (seed_len < (size_t)qsize)) + seed_in = NULL; /* seed buffer too small -- ignore */ + if (seed_len > (size_t)qsize) + seed_len = qsize; /* App. 2.2 of FIPS PUB 186 allows larger + * SEED, but our internal buffers are + * restricted to 160 bits */ + if (seed_in != NULL) + memcpy(seed, seed_in, seed_len); + + if ((mont = BN_MONT_CTX_new()) == NULL) + goto err; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + BN_CTX_start(ctx); + + r0 = BN_CTX_get(ctx); + g = BN_CTX_get(ctx); + W = BN_CTX_get(ctx); + q = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + c = BN_CTX_get(ctx); + p = BN_CTX_get(ctx); + test = BN_CTX_get(ctx); + + if (!BN_lshift(test, BN_value_one(), bits - 1)) + goto err; + + for (;;) { + for (;;) { /* find q */ + int seed_is_random; + + /* step 1 */ + if (!BN_GENCB_call(cb, 0, m++)) + goto err; + + if (!seed_len || !seed_in) { + if (RAND_pseudo_bytes(seed, qsize) < 0) + goto err; + seed_is_random = 1; + } else { + seed_is_random = 0; + seed_len = 0; /* use random seed if 'seed_in' turns out to + * be bad */ + } + memcpy(buf, seed, qsize); + memcpy(buf2, seed, qsize); + /* precompute "SEED + 1" for step 7: */ + for (i = qsize - 1; i >= 0; i--) { + buf[i]++; + if (buf[i] != 0) + break; + } + + /* step 2 */ + if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL)) + goto err; + if (!EVP_Digest(buf, qsize, buf2, NULL, evpmd, NULL)) + goto err; + for (i = 0; i < qsize; i++) + md[i] ^= buf2[i]; + + /* step 3 */ + md[0] |= 0x80; + md[qsize - 1] |= 0x01; + if (!BN_bin2bn(md, qsize, q)) + goto err; + + /* step 4 */ + r = BN_is_prime_fasttest_ex(q, DSS_prime_checks, ctx, + seed_is_random, cb); + if (r > 0) + break; + if (r != 0) + goto err; + + /* do a callback call */ + /* step 5 */ + } + + if (!BN_GENCB_call(cb, 2, 0)) + goto err; + if (!BN_GENCB_call(cb, 3, 0)) + goto err; + + /* step 6 */ + counter = 0; + /* "offset = 2" */ + + n = (bits - 1) / 160; + + for (;;) { + if ((counter != 0) && !BN_GENCB_call(cb, 0, counter)) + goto err; + + /* step 7 */ + BN_zero(W); + /* now 'buf' contains "SEED + offset - 1" */ + for (k = 0; k <= n; k++) { + /* + * obtain "SEED + offset + k" by incrementing: + */ + for (i = qsize - 1; i >= 0; i--) { + buf[i]++; + if (buf[i] != 0) + break; + } + + if (!EVP_Digest(buf, qsize, md, NULL, evpmd, NULL)) + goto err; + + /* step 8 */ + if (!BN_bin2bn(md, qsize, r0)) + goto err; + if (!BN_lshift(r0, r0, (qsize << 3) * k)) + goto err; + if (!BN_add(W, W, r0)) + goto err; + } + + /* more of step 8 */ + if (!BN_mask_bits(W, bits - 1)) + goto err; + if (!BN_copy(X, W)) + goto err; + if (!BN_add(X, X, test)) + goto err; + + /* step 9 */ + if (!BN_lshift1(r0, q)) + goto err; + if (!BN_mod(c, X, r0, ctx)) + goto err; + if (!BN_sub(r0, c, BN_value_one())) + goto err; + if (!BN_sub(p, X, r0)) + goto err; + + /* step 10 */ + if (BN_cmp(p, test) >= 0) { + /* step 11 */ + r = BN_is_prime_fasttest_ex(p, DSS_prime_checks, ctx, 1, cb); + if (r > 0) + goto end; /* found it */ + if (r != 0) + goto err; + } + + /* step 13 */ + counter++; + /* "offset = offset + n + 1" */ + + /* step 14 */ + if (counter >= 4096) + break; + } + } + end: + if (!BN_GENCB_call(cb, 2, 1)) + goto err; + + /* We now need to generate g */ + /* Set r0=(p-1)/q */ + if (!BN_sub(test, p, BN_value_one())) + goto err; + if (!BN_div(r0, NULL, test, q, ctx)) + goto err; + + if (!BN_set_word(test, h)) + goto err; + if (!BN_MONT_CTX_set(mont, p, ctx)) + goto err; + + for (;;) { + /* g=test^r0%p */ + if (!BN_mod_exp_mont(g, test, r0, p, ctx, mont)) + goto err; + if (!BN_is_one(g)) + break; + if (!BN_add(test, test, BN_value_one())) + goto err; + h++; + } + + if (!BN_GENCB_call(cb, 3, 1)) + goto err; + + ok = 1; + err: + if (ok) { + if (ret->p) + BN_free(ret->p); + if (ret->q) + BN_free(ret->q); + if (ret->g) + BN_free(ret->g); + ret->p = BN_dup(p); + ret->q = BN_dup(q); + ret->g = BN_dup(g); + if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { + ok = 0; + goto err; + } + if (counter_ret != NULL) + *counter_ret = counter; + if (h_ret != NULL) + *h_ret = h; + if (seed_out) + memcpy(seed_out, seed, qsize); + } + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (mont != NULL) + BN_MONT_CTX_free(mont); + return ok; +} +#endif diff --git a/libs/openssl/crypto/dsa/dsa_key.c b/libs/openssl/crypto/dsa/dsa_key.c new file mode 100644 index 00000000..e8c8d2e6 --- /dev/null +++ b/libs/openssl/crypto/dsa/dsa_key.c @@ -0,0 +1,145 @@ +/* crypto/dsa/dsa_key.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#ifndef OPENSSL_NO_SHA +# include +# include +# include + +# ifdef OPENSSL_FIPS +# include +# endif + +static int dsa_builtin_keygen(DSA *dsa); + +int DSA_generate_key(DSA *dsa) +{ +# ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) + && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { + DSAerr(DSA_F_DSA_GENERATE_KEY, DSA_R_NON_FIPS_DSA_METHOD); + return 0; + } +# endif + if (dsa->meth->dsa_keygen) + return dsa->meth->dsa_keygen(dsa); +# ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_dsa_generate_key(dsa); +# endif + return dsa_builtin_keygen(dsa); +} + +static int dsa_builtin_keygen(DSA *dsa) +{ + int ok = 0; + BN_CTX *ctx = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + if (dsa->priv_key == NULL) { + if ((priv_key = BN_new()) == NULL) + goto err; + } else + priv_key = dsa->priv_key; + + do + if (!BN_rand_range(priv_key, dsa->q)) + goto err; + while (BN_is_zero(priv_key)) ; + + if (dsa->pub_key == NULL) { + if ((pub_key = BN_new()) == NULL) + goto err; + } else + pub_key = dsa->pub_key; + + { + BIGNUM local_prk; + BIGNUM *prk; + + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { + BN_init(&local_prk); + prk = &local_prk; + BN_with_flags(prk, priv_key, BN_FLG_CONSTTIME); + } else + prk = priv_key; + + if (!BN_mod_exp(pub_key, dsa->g, prk, dsa->p, ctx)) + goto err; + } + + dsa->priv_key = priv_key; + dsa->pub_key = pub_key; + ok = 1; + + err: + if ((pub_key != NULL) && (dsa->pub_key == NULL)) + BN_free(pub_key); + if ((priv_key != NULL) && (dsa->priv_key == NULL)) + BN_free(priv_key); + if (ctx != NULL) + BN_CTX_free(ctx); + return (ok); +} +#endif diff --git a/libs/openssl/crypto/dsa/dsa_lib.c b/libs/openssl/crypto/dsa/dsa_lib.c new file mode 100644 index 00000000..eb9d21d9 --- /dev/null +++ b/libs/openssl/crypto/dsa/dsa_lib.c @@ -0,0 +1,329 @@ +/* crypto/dsa/dsa_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Original version from Steven Schoch */ + +#include +#include "cryptlib.h" +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#ifndef OPENSSL_NO_DH +# include +#endif + +#ifdef OPENSSL_FIPS +# include +#endif + +const char DSA_version[] = "DSA" OPENSSL_VERSION_PTEXT; + +static const DSA_METHOD *default_DSA_method = NULL; + +void DSA_set_default_method(const DSA_METHOD *meth) +{ + default_DSA_method = meth; +} + +const DSA_METHOD *DSA_get_default_method(void) +{ + if (!default_DSA_method) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_dsa_openssl(); + else + return DSA_OpenSSL(); +#else + default_DSA_method = DSA_OpenSSL(); +#endif + } + return default_DSA_method; +} + +DSA *DSA_new(void) +{ + return DSA_new_method(NULL); +} + +int DSA_set_method(DSA *dsa, const DSA_METHOD *meth) +{ + /* + * NB: The caller is specifically setting a method, so it's not up to us + * to deal with which ENGINE it comes from. + */ + const DSA_METHOD *mtmp; + mtmp = dsa->meth; + if (mtmp->finish) + mtmp->finish(dsa); +#ifndef OPENSSL_NO_ENGINE + if (dsa->engine) { + ENGINE_finish(dsa->engine); + dsa->engine = NULL; + } +#endif + dsa->meth = meth; + if (meth->init) + meth->init(dsa); + return 1; +} + +DSA *DSA_new_method(ENGINE *engine) +{ + DSA *ret; + + ret = (DSA *)OPENSSL_malloc(sizeof(DSA)); + if (ret == NULL) { + DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->meth = DSA_get_default_method(); +#ifndef OPENSSL_NO_ENGINE + if (engine) { + if (!ENGINE_init(engine)) { + DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); + OPENSSL_free(ret); + return NULL; + } + ret->engine = engine; + } else + ret->engine = ENGINE_get_default_DSA(); + if (ret->engine) { + ret->meth = ENGINE_get_DSA(ret->engine); + if (!ret->meth) { + DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); + ENGINE_finish(ret->engine); + OPENSSL_free(ret); + return NULL; + } + } +#endif + + ret->pad = 0; + ret->version = 0; + ret->write_params = 1; + ret->p = NULL; + ret->q = NULL; + ret->g = NULL; + + ret->pub_key = NULL; + ret->priv_key = NULL; + + ret->kinv = NULL; + ret->r = NULL; + ret->method_mont_p = NULL; + + ret->references = 1; + ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data); + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data); + OPENSSL_free(ret); + ret = NULL; + } + + return (ret); +} + +void DSA_free(DSA *r) +{ + int i; + + if (r == NULL) + return; + + i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_DSA); +#ifdef REF_PRINT + REF_PRINT("DSA", r); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "DSA_free, bad reference count\n"); + abort(); + } +#endif + + if (r->meth->finish) + r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE + if (r->engine) + ENGINE_finish(r->engine); +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data); + + if (r->p != NULL) + BN_clear_free(r->p); + if (r->q != NULL) + BN_clear_free(r->q); + if (r->g != NULL) + BN_clear_free(r->g); + if (r->pub_key != NULL) + BN_clear_free(r->pub_key); + if (r->priv_key != NULL) + BN_clear_free(r->priv_key); + if (r->kinv != NULL) + BN_clear_free(r->kinv); + if (r->r != NULL) + BN_clear_free(r->r); + OPENSSL_free(r); +} + +int DSA_up_ref(DSA *r) +{ + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DSA); +#ifdef REF_PRINT + REF_PRINT("DSA", r); +#endif +#ifdef REF_CHECK + if (i < 2) { + fprintf(stderr, "DSA_up_ref, bad reference count\n"); + abort(); + } +#endif + return ((i > 1) ? 1 : 0); +} + +int DSA_size(const DSA *r) +{ + int ret, i; + ASN1_INTEGER bs; + unsigned char buf[4]; /* 4 bytes looks really small. However, + * i2d_ASN1_INTEGER() will not look beyond + * the first byte, as long as the second + * parameter is NULL. */ + + i = BN_num_bits(r->q); + bs.length = (i + 7) / 8; + bs.data = buf; + bs.type = V_ASN1_INTEGER; + /* If the top bit is set the asn1 encoding is 1 larger. */ + buf[0] = 0xff; + + i = i2d_ASN1_INTEGER(&bs, NULL); + i += i; /* r and s */ + ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); + return (ret); +} + +int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DSA, argl, argp, + new_func, dup_func, free_func); +} + +int DSA_set_ex_data(DSA *d, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&d->ex_data, idx, arg)); +} + +void *DSA_get_ex_data(DSA *d, int idx) +{ + return (CRYPTO_get_ex_data(&d->ex_data, idx)); +} + +#ifndef OPENSSL_NO_DH +DH *DSA_dup_DH(const DSA *r) +{ + /* + * DSA has p, q, g, optional pub_key, optional priv_key. DH has p, + * optional length, g, optional pub_key, optional priv_key, optional q. + */ + + DH *ret = NULL; + + if (r == NULL) + goto err; + ret = DH_new(); + if (ret == NULL) + goto err; + if (r->p != NULL) + if ((ret->p = BN_dup(r->p)) == NULL) + goto err; + if (r->q != NULL) { + ret->length = BN_num_bits(r->q); + if ((ret->q = BN_dup(r->q)) == NULL) + goto err; + } + if (r->g != NULL) + if ((ret->g = BN_dup(r->g)) == NULL) + goto err; + if (r->pub_key != NULL) + if ((ret->pub_key = BN_dup(r->pub_key)) == NULL) + goto err; + if (r->priv_key != NULL) + if ((ret->priv_key = BN_dup(r->priv_key)) == NULL) + goto err; + + return ret; + + err: + if (ret != NULL) + DH_free(ret); + return NULL; +} +#endif diff --git a/libs/openssl/crypto/dsa/dsa_locl.h b/libs/openssl/crypto/dsa/dsa_locl.h new file mode 100644 index 00000000..f32ee964 --- /dev/null +++ b/libs/openssl/crypto/dsa/dsa_locl.h @@ -0,0 +1,61 @@ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +int dsa_builtin_paramgen(DSA *ret, size_t bits, size_t qbits, + const EVP_MD *evpmd, const unsigned char *seed_in, + size_t seed_len, unsigned char *seed_out, + int *counter_ret, unsigned long *h_ret, + BN_GENCB *cb); diff --git a/libs/openssl/crypto/dsa/dsa_ossl.c b/libs/openssl/crypto/dsa/dsa_ossl.c new file mode 100644 index 00000000..9a3772e0 --- /dev/null +++ b/libs/openssl/crypto/dsa/dsa_ossl.c @@ -0,0 +1,426 @@ +/* crypto/dsa/dsa_ossl.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Original version from Steven Schoch */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include + +static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa); +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); +static int dsa_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); +static int dsa_init(DSA *dsa); +static int dsa_finish(DSA *dsa); + +static DSA_METHOD openssl_dsa_meth = { + "OpenSSL DSA method", + dsa_do_sign, + dsa_sign_setup, + dsa_do_verify, + NULL, /* dsa_mod_exp, */ + NULL, /* dsa_bn_mod_exp, */ + dsa_init, + dsa_finish, + 0, + NULL, + NULL, + NULL +}; + +/*- + * These macro wrappers replace attempts to use the dsa_mod_exp() and + * bn_mod_exp() handlers in the DSA_METHOD structure. We avoid the problem of + * having a the macro work as an expression by bundling an "err_instr". So; + * + * if (!dsa->meth->bn_mod_exp(dsa, r,dsa->g,&k,dsa->p,ctx, + * dsa->method_mont_p)) goto err; + * + * can be replaced by; + * + * DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, &k, dsa->p, ctx, + * dsa->method_mont_p); + */ + +#define DSA_MOD_EXP(err_instr,dsa,rr,a1,p1,a2,p2,m,ctx,in_mont) \ + do { \ + int _tmp_res53; \ + if ((dsa)->meth->dsa_mod_exp) \ + _tmp_res53 = (dsa)->meth->dsa_mod_exp((dsa), (rr), (a1), (p1), \ + (a2), (p2), (m), (ctx), (in_mont)); \ + else \ + _tmp_res53 = BN_mod_exp2_mont((rr), (a1), (p1), (a2), (p2), \ + (m), (ctx), (in_mont)); \ + if (!_tmp_res53) err_instr; \ + } while(0) +#define DSA_BN_MOD_EXP(err_instr,dsa,r,a,p,m,ctx,m_ctx) \ + do { \ + int _tmp_res53; \ + if ((dsa)->meth->bn_mod_exp) \ + _tmp_res53 = (dsa)->meth->bn_mod_exp((dsa), (r), (a), (p), \ + (m), (ctx), (m_ctx)); \ + else \ + _tmp_res53 = BN_mod_exp_mont((r), (a), (p), (m), (ctx), (m_ctx)); \ + if (!_tmp_res53) err_instr; \ + } while(0) + +const DSA_METHOD *DSA_OpenSSL(void) +{ + return &openssl_dsa_meth; +} + +static DSA_SIG *dsa_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) +{ + BIGNUM *kinv = NULL, *r = NULL, *s = NULL; + BIGNUM m; + BIGNUM xr; + BN_CTX *ctx = NULL; + int reason = ERR_R_BN_LIB; + DSA_SIG *ret = NULL; + int noredo = 0; + + BN_init(&m); + BN_init(&xr); + + if (!dsa->p || !dsa->q || !dsa->g) { + reason = DSA_R_MISSING_PARAMETERS; + goto err; + } + + s = BN_new(); + if (s == NULL) + goto err; + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + redo: + if ((dsa->kinv == NULL) || (dsa->r == NULL)) { + if (!DSA_sign_setup(dsa, ctx, &kinv, &r)) + goto err; + } else { + kinv = dsa->kinv; + dsa->kinv = NULL; + r = dsa->r; + dsa->r = NULL; + noredo = 1; + } + + if (dlen > BN_num_bytes(dsa->q)) + /* + * if the digest length is greater than the size of q use the + * BN_num_bits(dsa->q) leftmost bits of the digest, see fips 186-3, + * 4.2 + */ + dlen = BN_num_bytes(dsa->q); + if (BN_bin2bn(dgst, dlen, &m) == NULL) + goto err; + + /* Compute s = inv(k) (m + xr) mod q */ + if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx)) + goto err; /* s = xr */ + if (!BN_add(s, &xr, &m)) + goto err; /* s = m + xr */ + if (BN_cmp(s, dsa->q) > 0) + if (!BN_sub(s, s, dsa->q)) + goto err; + if (!BN_mod_mul(s, s, kinv, dsa->q, ctx)) + goto err; + + /* + * Redo if r or s is zero as required by FIPS 186-3: this is very + * unlikely. + */ + if (BN_is_zero(r) || BN_is_zero(s)) { + if (noredo) { + reason = DSA_R_NEED_NEW_SETUP_VALUES; + goto err; + } + goto redo; + } + ret = DSA_SIG_new(); + if (ret == NULL) + goto err; + ret->r = r; + ret->s = s; + + err: + if (ret == NULL) { + DSAerr(DSA_F_DSA_DO_SIGN, reason); + BN_free(r); + BN_free(s); + } + if (ctx != NULL) + BN_CTX_free(ctx); + BN_clear_free(&m); + BN_clear_free(&xr); + if (kinv != NULL) /* dsa->kinv is NULL now if we used it */ + BN_clear_free(kinv); + return (ret); +} + +static int dsa_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp) +{ + BN_CTX *ctx; + BIGNUM k, kq, *K, *kinv = NULL, *r = NULL; + int ret = 0; + + if (!dsa->p || !dsa->q || !dsa->g) { + DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_MISSING_PARAMETERS); + return 0; + } + + BN_init(&k); + BN_init(&kq); + + if (ctx_in == NULL) { + if ((ctx = BN_CTX_new()) == NULL) + goto err; + } else + ctx = ctx_in; + + if ((r = BN_new()) == NULL) + goto err; + + /* Get random k */ + do + if (!BN_rand_range(&k, dsa->q)) + goto err; + while (BN_is_zero(&k)) ; + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { + BN_set_flags(&k, BN_FLG_CONSTTIME); + } + + if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { + if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, + CRYPTO_LOCK_DSA, dsa->p, ctx)) + goto err; + } + + /* Compute r = (g^k mod p) mod q */ + + if ((dsa->flags & DSA_FLAG_NO_EXP_CONSTTIME) == 0) { + if (!BN_copy(&kq, &k)) + goto err; + + /* + * We do not want timing information to leak the length of k, so we + * compute g^k using an equivalent exponent of fixed length. (This + * is a kludge that we need because the BN_mod_exp_mont() does not + * let us specify the desired timing behaviour.) + */ + + if (!BN_add(&kq, &kq, dsa->q)) + goto err; + if (BN_num_bits(&kq) <= BN_num_bits(dsa->q)) { + if (!BN_add(&kq, &kq, dsa->q)) + goto err; + } + + K = &kq; + } else { + K = &k; + } + DSA_BN_MOD_EXP(goto err, dsa, r, dsa->g, K, dsa->p, ctx, + dsa->method_mont_p); + if (!BN_mod(r, r, dsa->q, ctx)) + goto err; + + /* Compute part of 's = inv(k) (m + xr) mod q' */ + if ((kinv = BN_mod_inverse(NULL, &k, dsa->q, ctx)) == NULL) + goto err; + + if (*kinvp != NULL) + BN_clear_free(*kinvp); + *kinvp = kinv; + kinv = NULL; + if (*rp != NULL) + BN_clear_free(*rp); + *rp = r; + ret = 1; + err: + if (!ret) { + DSAerr(DSA_F_DSA_SIGN_SETUP, ERR_R_BN_LIB); + if (r != NULL) + BN_clear_free(r); + } + if (ctx_in == NULL) + BN_CTX_free(ctx); + BN_clear_free(&k); + BN_clear_free(&kq); + return (ret); +} + +static int dsa_do_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa) +{ + BN_CTX *ctx; + BIGNUM u1, u2, t1; + BN_MONT_CTX *mont = NULL; + int ret = -1, i; + if (!dsa->p || !dsa->q || !dsa->g) { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MISSING_PARAMETERS); + return -1; + } + + i = BN_num_bits(dsa->q); + /* fips 186-3 allows only different sizes for q */ + if (i != 160 && i != 224 && i != 256) { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_BAD_Q_VALUE); + return -1; + } + + if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_MODULUS_TOO_LARGE); + return -1; + } + BN_init(&u1); + BN_init(&u2); + BN_init(&t1); + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || + BN_ucmp(sig->r, dsa->q) >= 0) { + ret = 0; + goto err; + } + if (BN_is_zero(sig->s) || BN_is_negative(sig->s) || + BN_ucmp(sig->s, dsa->q) >= 0) { + ret = 0; + goto err; + } + + /* + * Calculate W = inv(S) mod Q save W in u2 + */ + if ((BN_mod_inverse(&u2, sig->s, dsa->q, ctx)) == NULL) + goto err; + + /* save M in u1 */ + if (dgst_len > (i >> 3)) + /* + * if the digest length is greater than the size of q use the + * BN_num_bits(dsa->q) leftmost bits of the digest, see fips 186-3, + * 4.2 + */ + dgst_len = (i >> 3); + if (BN_bin2bn(dgst, dgst_len, &u1) == NULL) + goto err; + + /* u1 = M * w mod q */ + if (!BN_mod_mul(&u1, &u1, &u2, dsa->q, ctx)) + goto err; + + /* u2 = r * w mod q */ + if (!BN_mod_mul(&u2, sig->r, &u2, dsa->q, ctx)) + goto err; + + if (dsa->flags & DSA_FLAG_CACHE_MONT_P) { + mont = BN_MONT_CTX_set_locked(&dsa->method_mont_p, + CRYPTO_LOCK_DSA, dsa->p, ctx); + if (!mont) + goto err; + } + + DSA_MOD_EXP(goto err, dsa, &t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, + ctx, mont); + /* BN_copy(&u1,&t1); */ + /* let u1 = u1 mod q */ + if (!BN_mod(&u1, &t1, dsa->q, ctx)) + goto err; + + /* + * V is now in u1. If the signature is correct, it will be equal to R. + */ + ret = (BN_ucmp(&u1, sig->r) == 0); + + err: + /* + * XXX: surely this is wrong - if ret is 0, it just didn't verify; there + * is no error in BN. Test should be ret == -1 (Ben) + */ + if (ret != 1) + DSAerr(DSA_F_DSA_DO_VERIFY, ERR_R_BN_LIB); + if (ctx != NULL) + BN_CTX_free(ctx); + BN_free(&u1); + BN_free(&u2); + BN_free(&t1); + return (ret); +} + +static int dsa_init(DSA *dsa) +{ + dsa->flags |= DSA_FLAG_CACHE_MONT_P; + return (1); +} + +static int dsa_finish(DSA *dsa) +{ + if (dsa->method_mont_p) + BN_MONT_CTX_free(dsa->method_mont_p); + return (1); +} diff --git a/libs/openssl/crypto/dsa/dsa_pmeth.c b/libs/openssl/crypto/dsa/dsa_pmeth.c new file mode 100644 index 00000000..0d480f6a --- /dev/null +++ b/libs/openssl/crypto/dsa/dsa_pmeth.c @@ -0,0 +1,308 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include "evp_locl.h" +#include "dsa_locl.h" + +/* DSA pkey context structure */ + +typedef struct { + /* Parameter gen parameters */ + int nbits; /* size of p in bits (default: 1024) */ + int qbits; /* size of q in bits (default: 160) */ + const EVP_MD *pmd; /* MD for parameter generation */ + /* Keygen callback info */ + int gentmp[2]; + /* message digest */ + const EVP_MD *md; /* MD for the signature */ +} DSA_PKEY_CTX; + +static int pkey_dsa_init(EVP_PKEY_CTX *ctx) +{ + DSA_PKEY_CTX *dctx; + dctx = OPENSSL_malloc(sizeof(DSA_PKEY_CTX)); + if (!dctx) + return 0; + dctx->nbits = 1024; + dctx->qbits = 160; + dctx->pmd = NULL; + dctx->md = NULL; + + ctx->data = dctx; + ctx->keygen_info = dctx->gentmp; + ctx->keygen_info_count = 2; + + return 1; +} + +static int pkey_dsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + DSA_PKEY_CTX *dctx, *sctx; + if (!pkey_dsa_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->nbits = sctx->nbits; + dctx->qbits = sctx->qbits; + dctx->pmd = sctx->pmd; + dctx->md = sctx->md; + return 1; +} + +static void pkey_dsa_cleanup(EVP_PKEY_CTX *ctx) +{ + DSA_PKEY_CTX *dctx = ctx->data; + if (dctx) + OPENSSL_free(dctx); +} + +static int pkey_dsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, + size_t *siglen, const unsigned char *tbs, + size_t tbslen) +{ + int ret, type; + unsigned int sltmp; + DSA_PKEY_CTX *dctx = ctx->data; + DSA *dsa = ctx->pkey->pkey.dsa; + + if (dctx->md) + type = EVP_MD_type(dctx->md); + else + type = NID_sha1; + + ret = DSA_sign(type, tbs, tbslen, sig, &sltmp, dsa); + + if (ret <= 0) + return ret; + *siglen = sltmp; + return 1; +} + +static int pkey_dsa_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + int ret, type; + DSA_PKEY_CTX *dctx = ctx->data; + DSA *dsa = ctx->pkey->pkey.dsa; + + if (dctx->md) + type = EVP_MD_type(dctx->md); + else + type = NID_sha1; + + ret = DSA_verify(type, tbs, tbslen, sig, siglen, dsa); + + return ret; +} + +static int pkey_dsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + DSA_PKEY_CTX *dctx = ctx->data; + switch (type) { + case EVP_PKEY_CTRL_DSA_PARAMGEN_BITS: + if (p1 < 256) + return -2; + dctx->nbits = p1; + return 1; + + case EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS: + if (p1 != 160 && p1 != 224 && p1 && p1 != 256) + return -2; + dctx->qbits = p1; + return 1; + + case EVP_PKEY_CTRL_DSA_PARAMGEN_MD: + if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha256) { + DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); + return 0; + } + dctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_MD: + if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && + EVP_MD_type((const EVP_MD *)p2) != NID_dsa && + EVP_MD_type((const EVP_MD *)p2) != NID_dsaWithSHA && + EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha512) { + DSAerr(DSA_F_PKEY_DSA_CTRL, DSA_R_INVALID_DIGEST_TYPE); + return 0; + } + dctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_DIGESTINIT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + case EVP_PKEY_CTRL_CMS_SIGN: + return 1; + + case EVP_PKEY_CTRL_PEER_KEY: + DSAerr(DSA_F_PKEY_DSA_CTRL, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + default: + return -2; + + } +} + +static int pkey_dsa_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (!strcmp(type, "dsa_paramgen_bits")) { + int nbits; + nbits = atoi(value); + return EVP_PKEY_CTX_set_dsa_paramgen_bits(ctx, nbits); + } + if (!strcmp(type, "dsa_paramgen_q_bits")) { + int qbits = atoi(value); + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DSA_PARAMGEN_Q_BITS, qbits, + NULL); + } + if (!strcmp(type, "dsa_paramgen_md")) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_DSA, EVP_PKEY_OP_PARAMGEN, + EVP_PKEY_CTRL_DSA_PARAMGEN_MD, 0, + (void *)EVP_get_digestbyname(value)); + } + return -2; +} + +static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + DSA *dsa = NULL; + DSA_PKEY_CTX *dctx = ctx->data; + BN_GENCB *pcb, cb; + int ret; + if (ctx->pkey_gencb) { + pcb = &cb; + evp_pkey_set_cb_translate(pcb, ctx); + } else + pcb = NULL; + dsa = DSA_new(); + if (!dsa) + return 0; + ret = dsa_builtin_paramgen(dsa, dctx->nbits, dctx->qbits, dctx->pmd, + NULL, 0, NULL, NULL, NULL, pcb); + if (ret) + EVP_PKEY_assign_DSA(pkey, dsa); + else + DSA_free(dsa); + return ret; +} + +static int pkey_dsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + DSA *dsa = NULL; + if (ctx->pkey == NULL) { + DSAerr(DSA_F_PKEY_DSA_KEYGEN, DSA_R_NO_PARAMETERS_SET); + return 0; + } + dsa = DSA_new(); + if (!dsa) + return 0; + EVP_PKEY_assign_DSA(pkey, dsa); + /* Note: if error return, pkey is freed by parent routine */ + if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) + return 0; + return DSA_generate_key(pkey->pkey.dsa); +} + +const EVP_PKEY_METHOD dsa_pkey_meth = { + EVP_PKEY_DSA, + EVP_PKEY_FLAG_AUTOARGLEN, + pkey_dsa_init, + pkey_dsa_copy, + pkey_dsa_cleanup, + + 0, + pkey_dsa_paramgen, + + 0, + pkey_dsa_keygen, + + 0, + pkey_dsa_sign, + + 0, + pkey_dsa_verify, + + 0, 0, + + 0, 0, 0, 0, + + 0, 0, + + 0, 0, + + 0, 0, + + pkey_dsa_ctrl, + pkey_dsa_ctrl_str +}; diff --git a/libs/openssl/crypto/dsa/dsa_prn.c b/libs/openssl/crypto/dsa/dsa_prn.c new file mode 100644 index 00000000..ce690dfc --- /dev/null +++ b/libs/openssl/crypto/dsa/dsa_prn.c @@ -0,0 +1,119 @@ +/* crypto/dsa/dsa_prn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include + +#ifndef OPENSSL_NO_FP_API +int DSA_print_fp(FILE *fp, const DSA *x, int off) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + DSAerr(DSA_F_DSA_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = DSA_print(b, x, off); + BIO_free(b); + return (ret); +} + +int DSAparams_print_fp(FILE *fp, const DSA *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + DSAerr(DSA_F_DSAPARAMS_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = DSAparams_print(b, x); + BIO_free(b); + return (ret); +} +#endif + +int DSA_print(BIO *bp, const DSA *x, int off) +{ + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x)) + return 0; + ret = EVP_PKEY_print_private(bp, pk, off, NULL); + EVP_PKEY_free(pk); + return ret; +} + +int DSAparams_print(BIO *bp, const DSA *x) +{ + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_DSA(pk, (DSA *)x)) + return 0; + ret = EVP_PKEY_print_params(bp, pk, 4, NULL); + EVP_PKEY_free(pk); + return ret; +} diff --git a/libs/openssl/crypto/dsa/dsa_sign.c b/libs/openssl/crypto/dsa/dsa_sign.c new file mode 100644 index 00000000..c2b71d85 --- /dev/null +++ b/libs/openssl/crypto/dsa/dsa_sign.c @@ -0,0 +1,110 @@ +/* crypto/dsa/dsa_sign.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Original version from Steven Schoch */ + +#include "cryptlib.h" +#include +#include +#include + +DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) + && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { + DSAerr(DSA_F_DSA_DO_SIGN, DSA_R_NON_FIPS_DSA_METHOD); + return NULL; + } +#endif + return dsa->meth->dsa_do_sign(dgst, dlen, dsa); +} + +int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) + && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { + DSAerr(DSA_F_DSA_SIGN_SETUP, DSA_R_NON_FIPS_DSA_METHOD); + return 0; + } +#endif + return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); +} + +DSA_SIG *DSA_SIG_new(void) +{ + DSA_SIG *sig; + sig = OPENSSL_malloc(sizeof(DSA_SIG)); + if (!sig) + return NULL; + sig->r = NULL; + sig->s = NULL; + return sig; +} + +void DSA_SIG_free(DSA_SIG *sig) +{ + if (sig) { + if (sig->r) + BN_free(sig->r); + if (sig->s) + BN_free(sig->s); + OPENSSL_free(sig); + } +} diff --git a/libs/openssl/crypto/dsa/dsa_vrf.c b/libs/openssl/crypto/dsa/dsa_vrf.c new file mode 100644 index 00000000..7dbd0ca2 --- /dev/null +++ b/libs/openssl/crypto/dsa/dsa_vrf.c @@ -0,0 +1,75 @@ +/* crypto/dsa/dsa_vrf.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* Original version from Steven Schoch */ + +#include "cryptlib.h" +#include + +int DSA_do_verify(const unsigned char *dgst, int dgst_len, DSA_SIG *sig, + DSA *dsa) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(dsa->meth->flags & DSA_FLAG_FIPS_METHOD) + && !(dsa->flags & DSA_FLAG_NON_FIPS_ALLOW)) { + DSAerr(DSA_F_DSA_DO_VERIFY, DSA_R_NON_FIPS_DSA_METHOD); + return -1; + } +#endif + return dsa->meth->dsa_do_verify(dgst, dgst_len, sig, dsa); +} diff --git a/libs/openssl/crypto/dsa/dsagen.c b/libs/openssl/crypto/dsa/dsagen.c new file mode 100644 index 00000000..e7d346b1 --- /dev/null +++ b/libs/openssl/crypto/dsa/dsagen.c @@ -0,0 +1,115 @@ +/* crypto/dsa/dsagen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#define TEST +#define GENUINE_DSA + +#ifdef GENUINE_DSA +# define LAST_VALUE 0xbd +#else +# define LAST_VALUE 0xd3 +#endif + +#ifdef TEST +unsigned char seed[20] = { + 0xd5, 0x01, 0x4e, 0x4b, + 0x60, 0xef, 0x2b, 0xa8, + 0xb6, 0x21, 0x1b, 0x40, + 0x62, 0xba, 0x32, 0x24, + 0xe0, 0x42, 0x7d, LAST_VALUE +}; +#endif + +int cb(int p, int n) +{ + char c = '*'; + + if (p == 0) + c = '.'; + if (p == 1) + c = '+'; + if (p == 2) + c = '*'; + if (p == 3) + c = '\n'; + printf("%c", c); + fflush(stdout); +} + +main() +{ + int i; + BIGNUM *n; + BN_CTX *ctx; + unsigned char seed_buf[20]; + DSA *dsa; + int counter, h; + BIO *bio_err = NULL; + + if (bio_err == NULL) + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + + memcpy(seed_buf, seed, 20); + dsa = DSA_generate_parameters(1024, seed, 20, &counter, &h, cb, bio_err); + + if (dsa == NULL) + DSA_print(bio_err, dsa, 0); +} diff --git a/libs/openssl/crypto/dsa/dsatest.c b/libs/openssl/crypto/dsa/dsatest.c new file mode 100644 index 00000000..8a224a88 --- /dev/null +++ b/libs/openssl/crypto/dsa/dsatest.c @@ -0,0 +1,268 @@ +/* crypto/dsa/dsatest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * Until the key-gen callbacks are modified to use newer prototypes, we allow + * deprecated functions for openssl-internal code + */ +#ifdef OPENSSL_NO_DEPRECATED +# undef OPENSSL_NO_DEPRECATED +#endif + +#include +#include +#include +#include +#include + +#include "../e_os.h" + +#include +#include +#include +#include +#include + +#ifdef OPENSSL_NO_DSA +int main(int argc, char *argv[]) +{ + printf("No DSA support\n"); + return (0); +} +#else +# include + +# ifdef OPENSSL_SYS_WIN16 +# define MS_CALLBACK _far _loadds +# else +# define MS_CALLBACK +# endif + +static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *arg); + +/* + * seed, out_p, out_q, out_g are taken from the updated Appendix 5 to FIPS + * PUB 186 and also appear in Appendix 5 to FIPS PIB 186-1 + */ +static unsigned char seed[20] = { + 0xd5, 0x01, 0x4e, 0x4b, 0x60, 0xef, 0x2b, 0xa8, 0xb6, 0x21, 0x1b, 0x40, + 0x62, 0xba, 0x32, 0x24, 0xe0, 0x42, 0x7d, 0xd3, +}; + +static unsigned char out_p[] = { + 0x8d, 0xf2, 0xa4, 0x94, 0x49, 0x22, 0x76, 0xaa, + 0x3d, 0x25, 0x75, 0x9b, 0xb0, 0x68, 0x69, 0xcb, + 0xea, 0xc0, 0xd8, 0x3a, 0xfb, 0x8d, 0x0c, 0xf7, + 0xcb, 0xb8, 0x32, 0x4f, 0x0d, 0x78, 0x82, 0xe5, + 0xd0, 0x76, 0x2f, 0xc5, 0xb7, 0x21, 0x0e, 0xaf, + 0xc2, 0xe9, 0xad, 0xac, 0x32, 0xab, 0x7a, 0xac, + 0x49, 0x69, 0x3d, 0xfb, 0xf8, 0x37, 0x24, 0xc2, + 0xec, 0x07, 0x36, 0xee, 0x31, 0xc8, 0x02, 0x91, +}; + +static unsigned char out_q[] = { + 0xc7, 0x73, 0x21, 0x8c, 0x73, 0x7e, 0xc8, 0xee, + 0x99, 0x3b, 0x4f, 0x2d, 0xed, 0x30, 0xf4, 0x8e, + 0xda, 0xce, 0x91, 0x5f, +}; + +static unsigned char out_g[] = { + 0x62, 0x6d, 0x02, 0x78, 0x39, 0xea, 0x0a, 0x13, + 0x41, 0x31, 0x63, 0xa5, 0x5b, 0x4c, 0xb5, 0x00, + 0x29, 0x9d, 0x55, 0x22, 0x95, 0x6c, 0xef, 0xcb, + 0x3b, 0xff, 0x10, 0xf3, 0x99, 0xce, 0x2c, 0x2e, + 0x71, 0xcb, 0x9d, 0xe5, 0xfa, 0x24, 0xba, 0xbf, + 0x58, 0xe5, 0xb7, 0x95, 0x21, 0x92, 0x5c, 0x9c, + 0xc4, 0x2e, 0x9f, 0x6f, 0x46, 0x4b, 0x08, 0x8c, + 0xc5, 0x72, 0xaf, 0x53, 0xe6, 0xd7, 0x88, 0x02, +}; + +static const unsigned char str1[] = "12345678901234567890"; + +static const char rnd_seed[] = + "string to make the random number generator think it has entropy"; + +static BIO *bio_err = NULL; + +int main(int argc, char **argv) +{ + BN_GENCB cb; + DSA *dsa = NULL; + int counter, ret = 0, i, j; + unsigned char buf[256]; + unsigned long h; + unsigned char sig[256]; + unsigned int siglen; + + if (bio_err == NULL) + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + + CRYPTO_malloc_debug_init(); + CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + + ERR_load_crypto_strings(); + RAND_seed(rnd_seed, sizeof rnd_seed); + + BIO_printf(bio_err, "test generation of DSA parameters\n"); + + BN_GENCB_set(&cb, dsa_cb, bio_err); + if (((dsa = DSA_new()) == NULL) || !DSA_generate_parameters_ex(dsa, 512, + seed, 20, + &counter, + &h, &cb)) + goto end; + + BIO_printf(bio_err, "seed\n"); + for (i = 0; i < 20; i += 4) { + BIO_printf(bio_err, "%02X%02X%02X%02X ", + seed[i], seed[i + 1], seed[i + 2], seed[i + 3]); + } + BIO_printf(bio_err, "\ncounter=%d h=%ld\n", counter, h); + + DSA_print(bio_err, dsa, 0); + if (counter != 105) { + BIO_printf(bio_err, "counter should be 105\n"); + goto end; + } + if (h != 2) { + BIO_printf(bio_err, "h should be 2\n"); + goto end; + } + + i = BN_bn2bin(dsa->q, buf); + j = sizeof(out_q); + if ((i != j) || (memcmp(buf, out_q, i) != 0)) { + BIO_printf(bio_err, "q value is wrong\n"); + goto end; + } + + i = BN_bn2bin(dsa->p, buf); + j = sizeof(out_p); + if ((i != j) || (memcmp(buf, out_p, i) != 0)) { + BIO_printf(bio_err, "p value is wrong\n"); + goto end; + } + + i = BN_bn2bin(dsa->g, buf); + j = sizeof(out_g); + if ((i != j) || (memcmp(buf, out_g, i) != 0)) { + BIO_printf(bio_err, "g value is wrong\n"); + goto end; + } + + dsa->flags |= DSA_FLAG_NO_EXP_CONSTTIME; + DSA_generate_key(dsa); + DSA_sign(0, str1, 20, sig, &siglen, dsa); + if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1) + ret = 1; + + dsa->flags &= ~DSA_FLAG_NO_EXP_CONSTTIME; + DSA_generate_key(dsa); + DSA_sign(0, str1, 20, sig, &siglen, dsa); + if (DSA_verify(0, str1, 20, sig, siglen, dsa) == 1) + ret = 1; + + end: + if (!ret) + ERR_print_errors(bio_err); + if (dsa != NULL) + DSA_free(dsa); + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + ERR_free_strings(); + CRYPTO_mem_leaks(bio_err); + if (bio_err != NULL) { + BIO_free(bio_err); + bio_err = NULL; + } +# ifdef OPENSSL_SYS_NETWARE + if (!ret) + printf("ERROR\n"); +# endif + EXIT(!ret); + return (0); +} + +static int MS_CALLBACK dsa_cb(int p, int n, BN_GENCB *arg) +{ + char c = '*'; + static int ok = 0, num = 0; + + if (p == 0) { + c = '.'; + num++; + }; + if (p == 1) + c = '+'; + if (p == 2) { + c = '*'; + ok++; + } + if (p == 3) + c = '\n'; + BIO_write(arg->arg, &c, 1); + (void)BIO_flush(arg->arg); + + if (!ok && (p == 0) && (num > 1)) { + BIO_printf((BIO *)arg, "error in dsatest\n"); + return 0; + } + return 1; +} +#endif diff --git a/libs/openssl/crypto/dsa/fips186a.txt b/libs/openssl/crypto/dsa/fips186a.txt new file mode 100644 index 00000000..3a2e0a0d --- /dev/null +++ b/libs/openssl/crypto/dsa/fips186a.txt @@ -0,0 +1,122 @@ +The origional FIPE 180 used SHA-0 (FIPS 180) for its appendix 5 +examples. This is an updated version that uses SHA-1 (FIPS 180-1) +supplied to me by Wei Dai +-- + APPENDIX 5. EXAMPLE OF THE DSA + + +This appendix is for informational purposes only and is not required to meet +the standard. + +Let L = 512 (size of p). The values in this example are expressed in +hexadecimal notation. The p and q given here were generated by the prime +generation standard described in appendix 2 using the 160-bit SEED: + + d5014e4b 60ef2ba8 b6211b40 62ba3224 e0427dd3 + +With this SEED, the algorithm found p and q when the counter was at 105. + +x was generated by the algorithm described in appendix 3, section 3.1, using +the SHA to construct G (as in appendix 3, section 3.3) and a 160-bit XSEED: + +XSEED = + + bd029bbe 7f51960b cf9edb2b 61f06f0f eb5a38b6 + +t = + 67452301 EFCDAB89 98BADCFE 10325476 C3D2E1F0 + +x = G(t,XSEED) mod q + +k was generated by the algorithm described in appendix 3, section 3.2, using +the SHA to construct G (as in appendix 3, section 3.3) and a 160-bit KSEED: + +KSEED = + + 687a66d9 0648f993 867e121f 4ddf9ddb 01205584 + +t = + EFCDAB89 98BADCFE 10325476 C3D2E1F0 67452301 + +k = G(t,KSEED) mod q + +Finally: + +h = 2 + +p = + 8df2a494 492276aa 3d25759b b06869cb eac0d83a fb8d0cf7 + cbb8324f 0d7882e5 d0762fc5 b7210eaf c2e9adac 32ab7aac + 49693dfb f83724c2 ec0736ee 31c80291 + + +q = + c773218c 737ec8ee 993b4f2d ed30f48e dace915f + + +g = + 626d0278 39ea0a13 413163a5 5b4cb500 299d5522 956cefcb + 3bff10f3 99ce2c2e 71cb9de5 fa24babf 58e5b795 21925c9c + c42e9f6f 464b088c c572af53 e6d78802 + + +x = + 2070b322 3dba372f de1c0ffc 7b2e3b49 8b260614 + + +k = + 358dad57 1462710f 50e254cf 1a376b2b deaadfbf + + +kinv = + + 0d516729 8202e49b 4116ac10 4fc3f415 ae52f917 + +M = ASCII form of "abc" (See FIPS PUB 180-1, Appendix A) + +SHA(M) = + + a9993e36 4706816a ba3e2571 7850c26c 9cd0d89d + + +y = + + 19131871 d75b1612 a819f29d 78d1b0d7 346f7aa7 7bb62a85 + 9bfd6c56 75da9d21 2d3a36ef 1672ef66 0b8c7c25 5cc0ec74 + 858fba33 f44c0669 9630a76b 030ee333 + + +r = + 8bac1ab6 6410435c b7181f95 b16ab97c 92b341c0 + +s = + 41e2345f 1f56df24 58f426d1 55b4ba2d b6dcd8c8 + + +w = + 9df4ece5 826be95f ed406d41 b43edc0b 1c18841b + + +u1 = + bf655bd0 46f0b35e c791b004 804afcbb 8ef7d69d + + +u2 = + 821a9263 12e97ade abcc8d08 2b527897 8a2df4b0 + + +gu1 mod p = + + 51b1bf86 7888e5f3 af6fb476 9dd016bc fe667a65 aafc2753 + 9063bd3d 2b138b4c e02cc0c0 2ec62bb6 7306c63e 4db95bbf + 6f96662a 1987a21b e4ec1071 010b6069 + + +yu2 mod p = + + 8b510071 2957e950 50d6b8fd 376a668e 4b0d633c 1e46e665 + 5c611a72 e2b28483 be52c74d 4b30de61 a668966e dc307a67 + c19441f4 22bf3c34 08aeba1f 0a4dbec7 + +v = + 8bac1ab6 6410435c b7181f95 b16ab97c 92b341c0 diff --git a/libs/openssl/crypto/dso/README b/libs/openssl/crypto/dso/README new file mode 100644 index 00000000..d0bc9a89 --- /dev/null +++ b/libs/openssl/crypto/dso/README @@ -0,0 +1,22 @@ +NOTES +----- + +I've checked out HPUX (well, version 11 at least) and shl_t is +a pointer type so it's safe to use in the way it has been in +dso_dl.c. On the other hand, HPUX11 support dlfcn too and +according to their man page, prefer developers to move to that. +I'll leave Richard's changes there as I guess dso_dl is needed +for HPUX10.20. + +There is now a callback scheme in place where filename conversion can +(a) be turned off altogether through the use of the + DSO_FLAG_NO_NAME_TRANSLATION flag, +(b) be handled by default using the default DSO_METHOD's converter +(c) overriden per-DSO by setting the override callback +(d) a mix of (b) and (c) - eg. implement an override callback that; + (i) checks if we're win32 (if(strstr(dso->meth->name, "win32")....) + and if so, convert "blah" into "blah32.dll" (the default is + otherwise to make it "blah.dll"). + (ii) default to the normal behaviour - we're not on win32, eg. + finish with (return dso->meth->dso_name_converter(dso,NULL)). + diff --git a/libs/openssl/crypto/dso/dso.h b/libs/openssl/crypto/dso/dso.h new file mode 100644 index 00000000..c9013f5c --- /dev/null +++ b/libs/openssl/crypto/dso/dso.h @@ -0,0 +1,451 @@ +/* dso.h */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_DSO_H +# define HEADER_DSO_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* These values are used as commands to DSO_ctrl() */ +# define DSO_CTRL_GET_FLAGS 1 +# define DSO_CTRL_SET_FLAGS 2 +# define DSO_CTRL_OR_FLAGS 3 + +/* + * By default, DSO_load() will translate the provided filename into a form + * typical for the platform (more specifically the DSO_METHOD) using the + * dso_name_converter function of the method. Eg. win32 will transform "blah" + * into "blah.dll", and dlfcn will transform it into "libblah.so". The + * behaviour can be overriden by setting the name_converter callback in the + * DSO object (using DSO_set_name_converter()). This callback could even + * utilise the DSO_METHOD's converter too if it only wants to override + * behaviour for one or two possible DSO methods. However, the following flag + * can be set in a DSO to prevent *any* native name-translation at all - eg. + * if the caller has prompted the user for a path to a driver library so the + * filename should be interpreted as-is. + */ +# define DSO_FLAG_NO_NAME_TRANSLATION 0x01 +/* + * An extra flag to give if only the extension should be added as + * translation. This is obviously only of importance on Unix and other + * operating systems where the translation also may prefix the name with + * something, like 'lib', and ignored everywhere else. This flag is also + * ignored if DSO_FLAG_NO_NAME_TRANSLATION is used at the same time. + */ +# define DSO_FLAG_NAME_TRANSLATION_EXT_ONLY 0x02 + +/* + * The following flag controls the translation of symbol names to upper case. + * This is currently only being implemented for OpenVMS. + */ +# define DSO_FLAG_UPCASE_SYMBOL 0x10 + +/* + * This flag loads the library with public symbols. Meaning: The exported + * symbols of this library are public to all libraries loaded after this + * library. At the moment only implemented in unix. + */ +# define DSO_FLAG_GLOBAL_SYMBOLS 0x20 + +typedef void (*DSO_FUNC_TYPE) (void); + +typedef struct dso_st DSO; + +/* + * The function prototype used for method functions (or caller-provided + * callbacks) that transform filenames. They are passed a DSO structure + * pointer (or NULL if they are to be used independantly of a DSO object) and + * a filename to transform. They should either return NULL (if there is an + * error condition) or a newly allocated string containing the transformed + * form that the caller will need to free with OPENSSL_free() when done. + */ +typedef char *(*DSO_NAME_CONVERTER_FUNC)(DSO *, const char *); +/* + * The function prototype used for method functions (or caller-provided + * callbacks) that merge two file specifications. They are passed a DSO + * structure pointer (or NULL if they are to be used independantly of a DSO + * object) and two file specifications to merge. They should either return + * NULL (if there is an error condition) or a newly allocated string + * containing the result of merging that the caller will need to free with + * OPENSSL_free() when done. Here, merging means that bits and pieces are + * taken from each of the file specifications and added together in whatever + * fashion that is sensible for the DSO method in question. The only rule + * that really applies is that if the two specification contain pieces of the + * same type, the copy from the first string takes priority. One could see + * it as the first specification is the one given by the user and the second + * being a bunch of defaults to add on if they're missing in the first. + */ +typedef char *(*DSO_MERGER_FUNC)(DSO *, const char *, const char *); + +typedef struct dso_meth_st { + const char *name; + /* + * Loads a shared library, NB: new DSO_METHODs must ensure that a + * successful load populates the loaded_filename field, and likewise a + * successful unload OPENSSL_frees and NULLs it out. + */ + int (*dso_load) (DSO *dso); + /* Unloads a shared library */ + int (*dso_unload) (DSO *dso); + /* Binds a variable */ + void *(*dso_bind_var) (DSO *dso, const char *symname); + /* + * Binds a function - assumes a return type of DSO_FUNC_TYPE. This should + * be cast to the real function prototype by the caller. Platforms that + * don't have compatible representations for different prototypes (this + * is possible within ANSI C) are highly unlikely to have shared + * libraries at all, let alone a DSO_METHOD implemented for them. + */ + DSO_FUNC_TYPE (*dso_bind_func) (DSO *dso, const char *symname); +/* I don't think this would actually be used in any circumstances. */ +# if 0 + /* Unbinds a variable */ + int (*dso_unbind_var) (DSO *dso, char *symname, void *symptr); + /* Unbinds a function */ + int (*dso_unbind_func) (DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +# endif + /* + * The generic (yuck) "ctrl()" function. NB: Negative return values + * (rather than zero) indicate errors. + */ + long (*dso_ctrl) (DSO *dso, int cmd, long larg, void *parg); + /* + * The default DSO_METHOD-specific function for converting filenames to a + * canonical native form. + */ + DSO_NAME_CONVERTER_FUNC dso_name_converter; + /* + * The default DSO_METHOD-specific function for converting filenames to a + * canonical native form. + */ + DSO_MERGER_FUNC dso_merger; + /* [De]Initialisation handlers. */ + int (*init) (DSO *dso); + int (*finish) (DSO *dso); + /* Return pathname of the module containing location */ + int (*pathbyaddr) (void *addr, char *path, int sz); + /* Perform global symbol lookup, i.e. among *all* modules */ + void *(*globallookup) (const char *symname); +} DSO_METHOD; + +/**********************************************************************/ +/* The low-level handle type used to refer to a loaded shared library */ + +struct dso_st { + DSO_METHOD *meth; + /* + * Standard dlopen uses a (void *). Win32 uses a HANDLE. VMS doesn't use + * anything but will need to cache the filename for use in the dso_bind + * handler. All in all, let each method control its own destiny. + * "Handles" and such go in a STACK. + */ + STACK_OF(void) *meth_data; + int references; + int flags; + /* + * For use by applications etc ... use this for your bits'n'pieces, don't + * touch meth_data! + */ + CRYPTO_EX_DATA ex_data; + /* + * If this callback function pointer is set to non-NULL, then it will be + * used in DSO_load() in place of meth->dso_name_converter. NB: This + * should normally set using DSO_set_name_converter(). + */ + DSO_NAME_CONVERTER_FUNC name_converter; + /* + * If this callback function pointer is set to non-NULL, then it will be + * used in DSO_load() in place of meth->dso_merger. NB: This should + * normally set using DSO_set_merger(). + */ + DSO_MERGER_FUNC merger; + /* + * This is populated with (a copy of) the platform-independant filename + * used for this DSO. + */ + char *filename; + /* + * This is populated with (a copy of) the translated filename by which + * the DSO was actually loaded. It is NULL iff the DSO is not currently + * loaded. NB: This is here because the filename translation process may + * involve a callback being invoked more than once not only to convert to + * a platform-specific form, but also to try different filenames in the + * process of trying to perform a load. As such, this variable can be + * used to indicate (a) whether this DSO structure corresponds to a + * loaded library or not, and (b) the filename with which it was actually + * loaded. + */ + char *loaded_filename; +}; + +DSO *DSO_new(void); +DSO *DSO_new_method(DSO_METHOD *method); +int DSO_free(DSO *dso); +int DSO_flags(DSO *dso); +int DSO_up_ref(DSO *dso); +long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg); + +/* + * This function sets the DSO's name_converter callback. If it is non-NULL, + * then it will be used instead of the associated DSO_METHOD's function. If + * oldcb is non-NULL then it is set to the function pointer value being + * replaced. Return value is non-zero for success. + */ +int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb, + DSO_NAME_CONVERTER_FUNC *oldcb); +/* + * These functions can be used to get/set the platform-independant filename + * used for a DSO. NB: set will fail if the DSO is already loaded. + */ +const char *DSO_get_filename(DSO *dso); +int DSO_set_filename(DSO *dso, const char *filename); +/* + * This function will invoke the DSO's name_converter callback to translate a + * filename, or if the callback isn't set it will instead use the DSO_METHOD's + * converter. If "filename" is NULL, the "filename" in the DSO itself will be + * used. If the DSO_FLAG_NO_NAME_TRANSLATION flag is set, then the filename is + * simply duplicated. NB: This function is usually called from within a + * DSO_METHOD during the processing of a DSO_load() call, and is exposed so + * that caller-created DSO_METHODs can do the same thing. A non-NULL return + * value will need to be OPENSSL_free()'d. + */ +char *DSO_convert_filename(DSO *dso, const char *filename); +/* + * This function will invoke the DSO's merger callback to merge two file + * specifications, or if the callback isn't set it will instead use the + * DSO_METHOD's merger. A non-NULL return value will need to be + * OPENSSL_free()'d. + */ +char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2); +/* + * If the DSO is currently loaded, this returns the filename that it was + * loaded under, otherwise it returns NULL. So it is also useful as a test as + * to whether the DSO is currently loaded. NB: This will not necessarily + * return the same value as DSO_convert_filename(dso, dso->filename), because + * the DSO_METHOD's load function may have tried a variety of filenames (with + * and/or without the aid of the converters) before settling on the one it + * actually loaded. + */ +const char *DSO_get_loaded_filename(DSO *dso); + +void DSO_set_default_method(DSO_METHOD *meth); +DSO_METHOD *DSO_get_default_method(void); +DSO_METHOD *DSO_get_method(DSO *dso); +DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth); + +/* + * The all-singing all-dancing load function, you normally pass NULL for the + * first and third parameters. Use DSO_up and DSO_free for subsequent + * reference count handling. Any flags passed in will be set in the + * constructed DSO after its init() function but before the load operation. + * If 'dso' is non-NULL, 'flags' is ignored. + */ +DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags); + +/* This function binds to a variable inside a shared library. */ +void *DSO_bind_var(DSO *dso, const char *symname); + +/* This function binds to a function inside a shared library. */ +DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname); + +/* + * This method is the default, but will beg, borrow, or steal whatever method + * should be the default on any particular platform (including + * DSO_METH_null() if necessary). + */ +DSO_METHOD *DSO_METHOD_openssl(void); + +/* + * This method is defined for all platforms - if a platform has no DSO + * support then this will be the only method! + */ +DSO_METHOD *DSO_METHOD_null(void); + +/* + * If DSO_DLFCN is defined, the standard dlfcn.h-style functions (dlopen, + * dlclose, dlsym, etc) will be used and incorporated into this method. If + * not, this method will return NULL. + */ +DSO_METHOD *DSO_METHOD_dlfcn(void); + +/* + * If DSO_DL is defined, the standard dl.h-style functions (shl_load, + * shl_unload, shl_findsym, etc) will be used and incorporated into this + * method. If not, this method will return NULL. + */ +DSO_METHOD *DSO_METHOD_dl(void); + +/* If WIN32 is defined, use DLLs. If not, return NULL. */ +DSO_METHOD *DSO_METHOD_win32(void); + +/* If VMS is defined, use shared images. If not, return NULL. */ +DSO_METHOD *DSO_METHOD_vms(void); + +/* + * This function writes null-terminated pathname of DSO module containing + * 'addr' into 'sz' large caller-provided 'path' and returns the number of + * characters [including trailing zero] written to it. If 'sz' is 0 or + * negative, 'path' is ignored and required amount of charachers [including + * trailing zero] to accomodate pathname is returned. If 'addr' is NULL, then + * pathname of cryptolib itself is returned. Negative or zero return value + * denotes error. + */ +int DSO_pathbyaddr(void *addr, char *path, int sz); + +/* + * This function should be used with caution! It looks up symbols in *all* + * loaded modules and if module gets unloaded by somebody else attempt to + * dereference the pointer is doomed to have fatal consequences. Primary + * usage for this function is to probe *core* system functionality, e.g. + * check if getnameinfo(3) is available at run-time without bothering about + * OS-specific details such as libc.so.versioning or where does it actually + * reside: in libc itself or libsocket. + */ +void *DSO_global_lookup(const char *name); + +/* If BeOS is defined, use shared images. If not, return NULL. */ +DSO_METHOD *DSO_METHOD_beos(void); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_DSO_strings(void); + +/* Error codes for the DSO functions. */ + +/* Function codes. */ +# define DSO_F_BEOS_BIND_FUNC 144 +# define DSO_F_BEOS_BIND_VAR 145 +# define DSO_F_BEOS_LOAD 146 +# define DSO_F_BEOS_NAME_CONVERTER 147 +# define DSO_F_BEOS_UNLOAD 148 +# define DSO_F_DLFCN_BIND_FUNC 100 +# define DSO_F_DLFCN_BIND_VAR 101 +# define DSO_F_DLFCN_LOAD 102 +# define DSO_F_DLFCN_MERGER 130 +# define DSO_F_DLFCN_NAME_CONVERTER 123 +# define DSO_F_DLFCN_UNLOAD 103 +# define DSO_F_DL_BIND_FUNC 104 +# define DSO_F_DL_BIND_VAR 105 +# define DSO_F_DL_LOAD 106 +# define DSO_F_DL_MERGER 131 +# define DSO_F_DL_NAME_CONVERTER 124 +# define DSO_F_DL_UNLOAD 107 +# define DSO_F_DSO_BIND_FUNC 108 +# define DSO_F_DSO_BIND_VAR 109 +# define DSO_F_DSO_CONVERT_FILENAME 126 +# define DSO_F_DSO_CTRL 110 +# define DSO_F_DSO_FREE 111 +# define DSO_F_DSO_GET_FILENAME 127 +# define DSO_F_DSO_GET_LOADED_FILENAME 128 +# define DSO_F_DSO_GLOBAL_LOOKUP 139 +# define DSO_F_DSO_LOAD 112 +# define DSO_F_DSO_MERGE 132 +# define DSO_F_DSO_NEW_METHOD 113 +# define DSO_F_DSO_PATHBYADDR 140 +# define DSO_F_DSO_SET_FILENAME 129 +# define DSO_F_DSO_SET_NAME_CONVERTER 122 +# define DSO_F_DSO_UP_REF 114 +# define DSO_F_GLOBAL_LOOKUP_FUNC 138 +# define DSO_F_PATHBYADDR 137 +# define DSO_F_VMS_BIND_SYM 115 +# define DSO_F_VMS_LOAD 116 +# define DSO_F_VMS_MERGER 133 +# define DSO_F_VMS_UNLOAD 117 +# define DSO_F_WIN32_BIND_FUNC 118 +# define DSO_F_WIN32_BIND_VAR 119 +# define DSO_F_WIN32_GLOBALLOOKUP 142 +# define DSO_F_WIN32_GLOBALLOOKUP_FUNC 143 +# define DSO_F_WIN32_JOINER 135 +# define DSO_F_WIN32_LOAD 120 +# define DSO_F_WIN32_MERGER 134 +# define DSO_F_WIN32_NAME_CONVERTER 125 +# define DSO_F_WIN32_PATHBYADDR 141 +# define DSO_F_WIN32_SPLITTER 136 +# define DSO_F_WIN32_UNLOAD 121 + +/* Reason codes. */ +# define DSO_R_CTRL_FAILED 100 +# define DSO_R_DSO_ALREADY_LOADED 110 +# define DSO_R_EMPTY_FILE_STRUCTURE 113 +# define DSO_R_FAILURE 114 +# define DSO_R_FILENAME_TOO_BIG 101 +# define DSO_R_FINISH_FAILED 102 +# define DSO_R_INCORRECT_FILE_SYNTAX 115 +# define DSO_R_LOAD_FAILED 103 +# define DSO_R_NAME_TRANSLATION_FAILED 109 +# define DSO_R_NO_FILENAME 111 +# define DSO_R_NO_FILE_SPECIFICATION 116 +# define DSO_R_NULL_HANDLE 104 +# define DSO_R_SET_FILENAME_FAILED 112 +# define DSO_R_STACK_ERROR 105 +# define DSO_R_SYM_FAILURE 106 +# define DSO_R_UNLOAD_FAILED 107 +# define DSO_R_UNSUPPORTED 108 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/dso/dso_beos.c b/libs/openssl/crypto/dso/dso_beos.c new file mode 100644 index 00000000..68ebcd8a --- /dev/null +++ b/libs/openssl/crypto/dso/dso_beos.c @@ -0,0 +1,253 @@ +/* dso_beos.c */ +/* + * Written by Marcin Konicki (ahwayakchih@neoni.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include + +#if !defined(OPENSSL_SYS_BEOS) +DSO_METHOD *DSO_METHOD_beos(void) +{ + return NULL; +} +#else + +# include + +static int beos_load(DSO *dso); +static int beos_unload(DSO *dso); +static void *beos_bind_var(DSO *dso, const char *symname); +static DSO_FUNC_TYPE beos_bind_func(DSO *dso, const char *symname); +# if 0 +static int beos_unbind_var(DSO *dso, char *symname, void *symptr); +static int beos_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +static int beos_init(DSO *dso); +static int beos_finish(DSO *dso); +static long beos_ctrl(DSO *dso, int cmd, long larg, void *parg); +# endif +static char *beos_name_converter(DSO *dso, const char *filename); + +static DSO_METHOD dso_meth_beos = { + "OpenSSL 'beos' shared library method", + beos_load, + beos_unload, + beos_bind_var, + beos_bind_func, +/* For now, "unbind" doesn't exist */ +# if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +# endif + NULL, /* ctrl */ + beos_name_converter, + NULL, /* init */ + NULL /* finish */ +}; + +DSO_METHOD *DSO_METHOD_beos(void) +{ + return (&dso_meth_beos); +} + +/* + * For this DSO_METHOD, our meth_data STACK will contain; (i) a pointer to + * the handle (image_id) returned from load_add_on(). + */ + +static int beos_load(DSO *dso) +{ + image_id id; + /* See applicable comments from dso_dl.c */ + char *filename = DSO_convert_filename(dso, NULL); + + if (filename == NULL) { + DSOerr(DSO_F_BEOS_LOAD, DSO_R_NO_FILENAME); + goto err; + } + id = load_add_on(filename); + if (id < 1) { + DSOerr(DSO_F_BEOS_LOAD, DSO_R_LOAD_FAILED); + ERR_add_error_data(3, "filename(", filename, ")"); + goto err; + } + if (!sk_push(dso->meth_data, (char *)id)) { + DSOerr(DSO_F_BEOS_LOAD, DSO_R_STACK_ERROR); + goto err; + } + /* Success */ + dso->loaded_filename = filename; + return (1); + err: + /* Cleanup ! */ + if (filename != NULL) + OPENSSL_free(filename); + if (id > 0) + unload_add_on(id); + return (0); +} + +static int beos_unload(DSO *dso) +{ + image_id id; + if (dso == NULL) { + DSOerr(DSO_F_BEOS_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (sk_num(dso->meth_data) < 1) + return (1); + id = (image_id) sk_pop(dso->meth_data); + if (id < 1) { + DSOerr(DSO_F_BEOS_UNLOAD, DSO_R_NULL_HANDLE); + return (0); + } + if (unload_add_on(id) != B_OK) { + DSOerr(DSO_F_BEOS_UNLOAD, DSO_R_UNLOAD_FAILED); + /* + * We should push the value back onto the stack in case of a retry. + */ + sk_push(dso->meth_data, (char *)id); + return (0); + } + return (1); +} + +static void *beos_bind_var(DSO *dso, const char *symname) +{ + image_id id; + void *sym; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_BEOS_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_num(dso->meth_data) < 1) { + DSOerr(DSO_F_BEOS_BIND_VAR, DSO_R_STACK_ERROR); + return (NULL); + } + id = (image_id) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + if (id < 1) { + DSOerr(DSO_F_BEOS_BIND_VAR, DSO_R_NULL_HANDLE); + return (NULL); + } + if (get_image_symbol(id, symname, B_SYMBOL_TYPE_DATA, &sym) != B_OK) { + DSOerr(DSO_F_BEOS_BIND_VAR, DSO_R_SYM_FAILURE); + ERR_add_error_data(3, "symname(", symname, ")"); + return (NULL); + } + return (sym); +} + +static DSO_FUNC_TYPE beos_bind_func(DSO *dso, const char *symname) +{ + image_id id; + void *sym; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_BEOS_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_num(dso->meth_data) < 1) { + DSOerr(DSO_F_BEOS_BIND_FUNC, DSO_R_STACK_ERROR); + return (NULL); + } + id = (image_id) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + if (id < 1) { + DSOerr(DSO_F_BEOS_BIND_FUNC, DSO_R_NULL_HANDLE); + return (NULL); + } + if (get_image_symbol(id, symname, B_SYMBOL_TYPE_TEXT, &sym) != B_OK) { + DSOerr(DSO_F_BEOS_BIND_FUNC, DSO_R_SYM_FAILURE); + ERR_add_error_data(3, "symname(", symname, ")"); + return (NULL); + } + return ((DSO_FUNC_TYPE)sym); +} + +/* This one is the same as the one in dlfcn */ +static char *beos_name_converter(DSO *dso, const char *filename) +{ + char *translated; + int len, rsize, transform; + + len = strlen(filename); + rsize = len + 1; + transform = (strstr(filename, "/") == NULL); + if (transform) { + /* We will convert this to "%s.so" or "lib%s.so" */ + rsize += 3; /* The length of ".so" */ + if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) + rsize += 3; /* The length of "lib" */ + } + translated = OPENSSL_malloc(rsize); + if (translated == NULL) { + DSOerr(DSO_F_BEOS_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); + return (NULL); + } + if (transform) { + if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) + sprintf(translated, "lib%s.so", filename); + else + sprintf(translated, "%s.so", filename); + } else + sprintf(translated, "%s", filename); + return (translated); +} + +#endif diff --git a/libs/openssl/crypto/dso/dso_dl.c b/libs/openssl/crypto/dso/dso_dl.c new file mode 100644 index 00000000..ceedf66e --- /dev/null +++ b/libs/openssl/crypto/dso/dso_dl.c @@ -0,0 +1,380 @@ +/* dso_dl.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +#ifndef DSO_DL +DSO_METHOD *DSO_METHOD_dl(void) +{ + return NULL; +} +#else + +# include + +/* Part of the hack in "dl_load" ... */ +# define DSO_MAX_TRANSLATED_SIZE 256 + +static int dl_load(DSO *dso); +static int dl_unload(DSO *dso); +static void *dl_bind_var(DSO *dso, const char *symname); +static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname); +# if 0 +static int dl_unbind_var(DSO *dso, char *symname, void *symptr); +static int dl_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +static int dl_init(DSO *dso); +static int dl_finish(DSO *dso); +static int dl_ctrl(DSO *dso, int cmd, long larg, void *parg); +# endif +static char *dl_name_converter(DSO *dso, const char *filename); +static char *dl_merger(DSO *dso, const char *filespec1, + const char *filespec2); +static int dl_pathbyaddr(void *addr, char *path, int sz); +static void *dl_globallookup(const char *name); + +static DSO_METHOD dso_meth_dl = { + "OpenSSL 'dl' shared library method", + dl_load, + dl_unload, + dl_bind_var, + dl_bind_func, +/* For now, "unbind" doesn't exist */ +# if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +# endif + NULL, /* ctrl */ + dl_name_converter, + dl_merger, + NULL, /* init */ + NULL, /* finish */ + dl_pathbyaddr, + dl_globallookup +}; + +DSO_METHOD *DSO_METHOD_dl(void) +{ + return (&dso_meth_dl); +} + +/* + * For this DSO_METHOD, our meth_data STACK will contain; (i) the handle + * (shl_t) returned from shl_load(). NB: I checked on HPUX11 and shl_t is + * itself a pointer type so the cast is safe. + */ + +static int dl_load(DSO *dso) +{ + shl_t ptr = NULL; + /* + * We don't do any fancy retries or anything, just take the method's (or + * DSO's if it has the callback set) best translation of the + * platform-independant filename and try once with that. + */ + char *filename = DSO_convert_filename(dso, NULL); + + if (filename == NULL) { + DSOerr(DSO_F_DL_LOAD, DSO_R_NO_FILENAME); + goto err; + } + ptr = shl_load(filename, BIND_IMMEDIATE | + (dso->flags & DSO_FLAG_NO_NAME_TRANSLATION ? 0 : + DYNAMIC_PATH), 0L); + if (ptr == NULL) { + DSOerr(DSO_F_DL_LOAD, DSO_R_LOAD_FAILED); + ERR_add_error_data(4, "filename(", filename, "): ", strerror(errno)); + goto err; + } + if (!sk_push(dso->meth_data, (char *)ptr)) { + DSOerr(DSO_F_DL_LOAD, DSO_R_STACK_ERROR); + goto err; + } + /* + * Success, stick the converted filename we've loaded under into the DSO + * (it also serves as the indicator that we are currently loaded). + */ + dso->loaded_filename = filename; + return (1); + err: + /* Cleanup! */ + if (filename != NULL) + OPENSSL_free(filename); + if (ptr != NULL) + shl_unload(ptr); + return (0); +} + +static int dl_unload(DSO *dso) +{ + shl_t ptr; + if (dso == NULL) { + DSOerr(DSO_F_DL_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (sk_num(dso->meth_data) < 1) + return (1); + /* Is this statement legal? */ + ptr = (shl_t) sk_pop(dso->meth_data); + if (ptr == NULL) { + DSOerr(DSO_F_DL_UNLOAD, DSO_R_NULL_HANDLE); + /* + * Should push the value back onto the stack in case of a retry. + */ + sk_push(dso->meth_data, (char *)ptr); + return (0); + } + shl_unload(ptr); + return (1); +} + +static void *dl_bind_var(DSO *dso, const char *symname) +{ + shl_t ptr; + void *sym; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_DL_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_num(dso->meth_data) < 1) { + DSOerr(DSO_F_DL_BIND_VAR, DSO_R_STACK_ERROR); + return (NULL); + } + ptr = (shl_t) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + if (ptr == NULL) { + DSOerr(DSO_F_DL_BIND_VAR, DSO_R_NULL_HANDLE); + return (NULL); + } + if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) { + DSOerr(DSO_F_DL_BIND_VAR, DSO_R_SYM_FAILURE); + ERR_add_error_data(4, "symname(", symname, "): ", strerror(errno)); + return (NULL); + } + return (sym); +} + +static DSO_FUNC_TYPE dl_bind_func(DSO *dso, const char *symname) +{ + shl_t ptr; + void *sym; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_DL_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_num(dso->meth_data) < 1) { + DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_STACK_ERROR); + return (NULL); + } + ptr = (shl_t) sk_value(dso->meth_data, sk_num(dso->meth_data) - 1); + if (ptr == NULL) { + DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_NULL_HANDLE); + return (NULL); + } + if (shl_findsym(&ptr, symname, TYPE_UNDEFINED, &sym) < 0) { + DSOerr(DSO_F_DL_BIND_FUNC, DSO_R_SYM_FAILURE); + ERR_add_error_data(4, "symname(", symname, "): ", strerror(errno)); + return (NULL); + } + return ((DSO_FUNC_TYPE)sym); +} + +static char *dl_merger(DSO *dso, const char *filespec1, const char *filespec2) +{ + char *merged; + + if (!filespec1 && !filespec2) { + DSOerr(DSO_F_DL_MERGER, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + /* + * If the first file specification is a rooted path, it rules. same goes + * if the second file specification is missing. + */ + if (!filespec2 || filespec1[0] == '/') { + merged = OPENSSL_malloc(strlen(filespec1) + 1); + if (!merged) { + DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec1); + } + /* + * If the first file specification is missing, the second one rules. + */ + else if (!filespec1) { + merged = OPENSSL_malloc(strlen(filespec2) + 1); + if (!merged) { + DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec2); + } else + /* + * This part isn't as trivial as it looks. It assumes that the + * second file specification really is a directory, and makes no + * checks whatsoever. Therefore, the result becomes the + * concatenation of filespec2 followed by a slash followed by + * filespec1. + */ + { + int spec2len, len; + + spec2len = (filespec2 ? strlen(filespec2) : 0); + len = spec2len + (filespec1 ? strlen(filespec1) : 0); + + if (filespec2 && filespec2[spec2len - 1] == '/') { + spec2len--; + len--; + } + merged = OPENSSL_malloc(len + 2); + if (!merged) { + DSOerr(DSO_F_DL_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec2); + merged[spec2len] = '/'; + strcpy(&merged[spec2len + 1], filespec1); + } + return (merged); +} + +/* + * This function is identical to the one in dso_dlfcn.c, but as it is highly + * unlikely that both the "dl" *and* "dlfcn" variants are being compiled at + * the same time, there's no great duplicating the code. Figuring out an + * elegant way to share one copy of the code would be more difficult and + * would not leave the implementations independant. + */ +# if defined(__hpux) +static const char extension[] = ".sl"; +# else +static const char extension[] = ".so"; +# endif +static char *dl_name_converter(DSO *dso, const char *filename) +{ + char *translated; + int len, rsize, transform; + + len = strlen(filename); + rsize = len + 1; + transform = (strstr(filename, "/") == NULL); + { + /* We will convert this to "%s.s?" or "lib%s.s?" */ + rsize += strlen(extension); /* The length of ".s?" */ + if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) + rsize += 3; /* The length of "lib" */ + } + translated = OPENSSL_malloc(rsize); + if (translated == NULL) { + DSOerr(DSO_F_DL_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); + return (NULL); + } + if (transform) { + if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) + sprintf(translated, "lib%s%s", filename, extension); + else + sprintf(translated, "%s%s", filename, extension); + } else + sprintf(translated, "%s", filename); + return (translated); +} + +static int dl_pathbyaddr(void *addr, char *path, int sz) +{ + struct shl_descriptor inf; + int i, len; + + if (addr == NULL) { + union { + int (*f) (void *, char *, int); + void *p; + } t = { + dl_pathbyaddr + }; + addr = t.p; + } + + for (i = -1; shl_get_r(i, &inf) == 0; i++) { + if (((size_t)addr >= inf.tstart && (size_t)addr < inf.tend) || + ((size_t)addr >= inf.dstart && (size_t)addr < inf.dend)) { + len = (int)strlen(inf.filename); + if (sz <= 0) + return len + 1; + if (len >= sz) + len = sz - 1; + memcpy(path, inf.filename, len); + path[len++] = 0; + return len; + } + } + + return -1; +} + +static void *dl_globallookup(const char *name) +{ + void *ret; + shl_t h = NULL; + + return shl_findsym(&h, name, TYPE_UNDEFINED, &ret) ? NULL : ret; +} +#endif /* DSO_DL */ diff --git a/libs/openssl/crypto/dso/dso_dlfcn.c b/libs/openssl/crypto/dso/dso_dlfcn.c new file mode 100644 index 00000000..78df723f --- /dev/null +++ b/libs/openssl/crypto/dso/dso_dlfcn.c @@ -0,0 +1,465 @@ +/* dso_dlfcn.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * We need to do this early, because stdio.h includes the header files that + * handle _GNU_SOURCE and other similar macros. Defining it later is simply + * too late, because those headers are protected from re- inclusion. + */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE /* make sure dladdr is declared */ +#endif + +#include +#include "cryptlib.h" +#include + +#ifndef DSO_DLFCN +DSO_METHOD *DSO_METHOD_dlfcn(void) +{ + return NULL; +} +#else + +# ifdef HAVE_DLFCN_H +# ifdef __osf__ +# define __EXTENSIONS__ +# endif +# include +# define HAVE_DLINFO 1 +# if defined(_AIX) || defined(__CYGWIN__) || \ + defined(__SCO_VERSION__) || defined(_SCO_ELF) || \ + (defined(__osf__) && !defined(RTLD_NEXT)) || \ + (defined(__OpenBSD__) && !defined(RTLD_SELF)) || \ + defined(__ANDROID__) +# undef HAVE_DLINFO +# endif +# endif + +/* Part of the hack in "dlfcn_load" ... */ +# define DSO_MAX_TRANSLATED_SIZE 256 + +static int dlfcn_load(DSO *dso); +static int dlfcn_unload(DSO *dso); +static void *dlfcn_bind_var(DSO *dso, const char *symname); +static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname); +# if 0 +static int dlfcn_unbind(DSO *dso, char *symname, void *symptr); +static int dlfcn_init(DSO *dso); +static int dlfcn_finish(DSO *dso); +static long dlfcn_ctrl(DSO *dso, int cmd, long larg, void *parg); +# endif +static char *dlfcn_name_converter(DSO *dso, const char *filename); +static char *dlfcn_merger(DSO *dso, const char *filespec1, + const char *filespec2); +static int dlfcn_pathbyaddr(void *addr, char *path, int sz); +static void *dlfcn_globallookup(const char *name); + +static DSO_METHOD dso_meth_dlfcn = { + "OpenSSL 'dlfcn' shared library method", + dlfcn_load, + dlfcn_unload, + dlfcn_bind_var, + dlfcn_bind_func, +/* For now, "unbind" doesn't exist */ +# if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +# endif + NULL, /* ctrl */ + dlfcn_name_converter, + dlfcn_merger, + NULL, /* init */ + NULL, /* finish */ + dlfcn_pathbyaddr, + dlfcn_globallookup +}; + +DSO_METHOD *DSO_METHOD_dlfcn(void) +{ + return (&dso_meth_dlfcn); +} + +/* + * Prior to using the dlopen() function, we should decide on the flag we + * send. There's a few different ways of doing this and it's a messy + * venn-diagram to match up which platforms support what. So as we don't have + * autoconf yet, I'm implementing a hack that could be hacked further + * relatively easily to deal with cases as we find them. Initially this is to + * cope with OpenBSD. + */ +# if defined(__OpenBSD__) || defined(__NetBSD__) +# ifdef DL_LAZY +# define DLOPEN_FLAG DL_LAZY +# else +# ifdef RTLD_NOW +# define DLOPEN_FLAG RTLD_NOW +# else +# define DLOPEN_FLAG 0 +# endif +# endif +# else +# ifdef OPENSSL_SYS_SUNOS +# define DLOPEN_FLAG 1 +# else +# define DLOPEN_FLAG RTLD_NOW /* Hope this works everywhere else */ +# endif +# endif + +/* + * For this DSO_METHOD, our meth_data STACK will contain; (i) the handle + * (void*) returned from dlopen(). + */ + +static int dlfcn_load(DSO *dso) +{ + void *ptr = NULL; + /* See applicable comments in dso_dl.c */ + char *filename = DSO_convert_filename(dso, NULL); + int flags = DLOPEN_FLAG; + + if (filename == NULL) { + DSOerr(DSO_F_DLFCN_LOAD, DSO_R_NO_FILENAME); + goto err; + } +# ifdef RTLD_GLOBAL + if (dso->flags & DSO_FLAG_GLOBAL_SYMBOLS) + flags |= RTLD_GLOBAL; +# endif + ptr = dlopen(filename, flags); + if (ptr == NULL) { + DSOerr(DSO_F_DLFCN_LOAD, DSO_R_LOAD_FAILED); + ERR_add_error_data(4, "filename(", filename, "): ", dlerror()); + goto err; + } + if (!sk_void_push(dso->meth_data, (char *)ptr)) { + DSOerr(DSO_F_DLFCN_LOAD, DSO_R_STACK_ERROR); + goto err; + } + /* Success */ + dso->loaded_filename = filename; + return (1); + err: + /* Cleanup! */ + if (filename != NULL) + OPENSSL_free(filename); + if (ptr != NULL) + dlclose(ptr); + return (0); +} + +static int dlfcn_unload(DSO *dso) +{ + void *ptr; + if (dso == NULL) { + DSOerr(DSO_F_DLFCN_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (sk_void_num(dso->meth_data) < 1) + return (1); + ptr = sk_void_pop(dso->meth_data); + if (ptr == NULL) { + DSOerr(DSO_F_DLFCN_UNLOAD, DSO_R_NULL_HANDLE); + /* + * Should push the value back onto the stack in case of a retry. + */ + sk_void_push(dso->meth_data, ptr); + return (0); + } + /* For now I'm not aware of any errors associated with dlclose() */ + dlclose(ptr); + return (1); +} + +static void *dlfcn_bind_var(DSO *dso, const char *symname) +{ + void *ptr, *sym; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_DLFCN_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_void_num(dso->meth_data) < 1) { + DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_STACK_ERROR); + return (NULL); + } + ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); + if (ptr == NULL) { + DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_NULL_HANDLE); + return (NULL); + } + sym = dlsym(ptr, symname); + if (sym == NULL) { + DSOerr(DSO_F_DLFCN_BIND_VAR, DSO_R_SYM_FAILURE); + ERR_add_error_data(4, "symname(", symname, "): ", dlerror()); + return (NULL); + } + return (sym); +} + +static DSO_FUNC_TYPE dlfcn_bind_func(DSO *dso, const char *symname) +{ + void *ptr; + union { + DSO_FUNC_TYPE sym; + void *dlret; + } u; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_DLFCN_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_void_num(dso->meth_data) < 1) { + DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_STACK_ERROR); + return (NULL); + } + ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); + if (ptr == NULL) { + DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_NULL_HANDLE); + return (NULL); + } + u.dlret = dlsym(ptr, symname); + if (u.dlret == NULL) { + DSOerr(DSO_F_DLFCN_BIND_FUNC, DSO_R_SYM_FAILURE); + ERR_add_error_data(4, "symname(", symname, "): ", dlerror()); + return (NULL); + } + return u.sym; +} + +static char *dlfcn_merger(DSO *dso, const char *filespec1, + const char *filespec2) +{ + char *merged; + + if (!filespec1 && !filespec2) { + DSOerr(DSO_F_DLFCN_MERGER, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + /* + * If the first file specification is a rooted path, it rules. same goes + * if the second file specification is missing. + */ + if (!filespec2 || (filespec1 != NULL && filespec1[0] == '/')) { + merged = OPENSSL_malloc(strlen(filespec1) + 1); + if (!merged) { + DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec1); + } + /* + * If the first file specification is missing, the second one rules. + */ + else if (!filespec1) { + merged = OPENSSL_malloc(strlen(filespec2) + 1); + if (!merged) { + DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec2); + } else { + /* + * This part isn't as trivial as it looks. It assumes that the + * second file specification really is a directory, and makes no + * checks whatsoever. Therefore, the result becomes the + * concatenation of filespec2 followed by a slash followed by + * filespec1. + */ + int spec2len, len; + + spec2len = strlen(filespec2); + len = spec2len + strlen(filespec1); + + if (spec2len && filespec2[spec2len - 1] == '/') { + spec2len--; + len--; + } + merged = OPENSSL_malloc(len + 2); + if (!merged) { + DSOerr(DSO_F_DLFCN_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec2); + merged[spec2len] = '/'; + strcpy(&merged[spec2len + 1], filespec1); + } + return (merged); +} + +# ifdef OPENSSL_SYS_MACOSX +# define DSO_ext ".dylib" +# define DSO_extlen 6 +# else +# define DSO_ext ".so" +# define DSO_extlen 3 +# endif + +static char *dlfcn_name_converter(DSO *dso, const char *filename) +{ + char *translated; + int len, rsize, transform; + + len = strlen(filename); + rsize = len + 1; + transform = (strstr(filename, "/") == NULL); + if (transform) { + /* We will convert this to "%s.so" or "lib%s.so" etc */ + rsize += DSO_extlen; /* The length of ".so" */ + if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) + rsize += 3; /* The length of "lib" */ + } + translated = OPENSSL_malloc(rsize); + if (translated == NULL) { + DSOerr(DSO_F_DLFCN_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); + return (NULL); + } + if (transform) { + if ((DSO_flags(dso) & DSO_FLAG_NAME_TRANSLATION_EXT_ONLY) == 0) + sprintf(translated, "lib%s" DSO_ext, filename); + else + sprintf(translated, "%s" DSO_ext, filename); + } else + sprintf(translated, "%s", filename); + return (translated); +} + +# ifdef __sgi +/*- +This is a quote from IRIX manual for dladdr(3c): + + does not contain a prototype for dladdr or definition of + Dl_info. The #include in the SYNOPSIS line is traditional, + but contains no dladdr prototype and no IRIX library contains an + implementation. Write your own declaration based on the code below. + + The following code is dependent on internal interfaces that are not + part of the IRIX compatibility guarantee; however, there is no future + intention to change this interface, so on a practical level, the code + below is safe to use on IRIX. +*/ +# include +# ifndef _RLD_INTERFACE_DLFCN_H_DLADDR +# define _RLD_INTERFACE_DLFCN_H_DLADDR +typedef struct Dl_info { + const char *dli_fname; + void *dli_fbase; + const char *dli_sname; + void *dli_saddr; + int dli_version; + int dli_reserved1; + long dli_reserved[4]; +} Dl_info; +# else +typedef struct Dl_info Dl_info; +# endif +# define _RLD_DLADDR 14 + +static int dladdr(void *address, Dl_info *dl) +{ + void *v; + v = _rld_new_interface(_RLD_DLADDR, address, dl); + return (int)v; +} +# endif /* __sgi */ + +static int dlfcn_pathbyaddr(void *addr, char *path, int sz) +{ +# ifdef HAVE_DLINFO + Dl_info dli; + int len; + + if (addr == NULL) { + union { + int (*f) (void *, char *, int); + void *p; + } t = { + dlfcn_pathbyaddr + }; + addr = t.p; + } + + if (dladdr(addr, &dli)) { + len = (int)strlen(dli.dli_fname); + if (sz <= 0) + return len + 1; + if (len >= sz) + len = sz - 1; + memcpy(path, dli.dli_fname, len); + path[len++] = 0; + return len; + } + + ERR_add_error_data(2, "dlfcn_pathbyaddr(): ", dlerror()); +# endif + return -1; +} + +static void *dlfcn_globallookup(const char *name) +{ + void *ret = NULL, *handle = dlopen(NULL, RTLD_LAZY); + + if (handle) { + ret = dlsym(handle, name); + dlclose(handle); + } + + return ret; +} +#endif /* DSO_DLFCN */ diff --git a/libs/openssl/crypto/dso/dso_err.c b/libs/openssl/crypto/dso/dso_err.c new file mode 100644 index 00000000..e143cc01 --- /dev/null +++ b/libs/openssl/crypto/dso/dso_err.c @@ -0,0 +1,158 @@ +/* crypto/dso/dso_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_DSO,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_DSO,0,reason) + +static ERR_STRING_DATA DSO_str_functs[] = { + {ERR_FUNC(DSO_F_BEOS_BIND_FUNC), "BEOS_BIND_FUNC"}, + {ERR_FUNC(DSO_F_BEOS_BIND_VAR), "BEOS_BIND_VAR"}, + {ERR_FUNC(DSO_F_BEOS_LOAD), "BEOS_LOAD"}, + {ERR_FUNC(DSO_F_BEOS_NAME_CONVERTER), "BEOS_NAME_CONVERTER"}, + {ERR_FUNC(DSO_F_BEOS_UNLOAD), "BEOS_UNLOAD"}, + {ERR_FUNC(DSO_F_DLFCN_BIND_FUNC), "DLFCN_BIND_FUNC"}, + {ERR_FUNC(DSO_F_DLFCN_BIND_VAR), "DLFCN_BIND_VAR"}, + {ERR_FUNC(DSO_F_DLFCN_LOAD), "DLFCN_LOAD"}, + {ERR_FUNC(DSO_F_DLFCN_MERGER), "DLFCN_MERGER"}, + {ERR_FUNC(DSO_F_DLFCN_NAME_CONVERTER), "DLFCN_NAME_CONVERTER"}, + {ERR_FUNC(DSO_F_DLFCN_UNLOAD), "DLFCN_UNLOAD"}, + {ERR_FUNC(DSO_F_DL_BIND_FUNC), "DL_BIND_FUNC"}, + {ERR_FUNC(DSO_F_DL_BIND_VAR), "DL_BIND_VAR"}, + {ERR_FUNC(DSO_F_DL_LOAD), "DL_LOAD"}, + {ERR_FUNC(DSO_F_DL_MERGER), "DL_MERGER"}, + {ERR_FUNC(DSO_F_DL_NAME_CONVERTER), "DL_NAME_CONVERTER"}, + {ERR_FUNC(DSO_F_DL_UNLOAD), "DL_UNLOAD"}, + {ERR_FUNC(DSO_F_DSO_BIND_FUNC), "DSO_bind_func"}, + {ERR_FUNC(DSO_F_DSO_BIND_VAR), "DSO_bind_var"}, + {ERR_FUNC(DSO_F_DSO_CONVERT_FILENAME), "DSO_convert_filename"}, + {ERR_FUNC(DSO_F_DSO_CTRL), "DSO_ctrl"}, + {ERR_FUNC(DSO_F_DSO_FREE), "DSO_free"}, + {ERR_FUNC(DSO_F_DSO_GET_FILENAME), "DSO_get_filename"}, + {ERR_FUNC(DSO_F_DSO_GET_LOADED_FILENAME), "DSO_get_loaded_filename"}, + {ERR_FUNC(DSO_F_DSO_GLOBAL_LOOKUP), "DSO_global_lookup"}, + {ERR_FUNC(DSO_F_DSO_LOAD), "DSO_load"}, + {ERR_FUNC(DSO_F_DSO_MERGE), "DSO_merge"}, + {ERR_FUNC(DSO_F_DSO_NEW_METHOD), "DSO_new_method"}, + {ERR_FUNC(DSO_F_DSO_PATHBYADDR), "DSO_pathbyaddr"}, + {ERR_FUNC(DSO_F_DSO_SET_FILENAME), "DSO_set_filename"}, + {ERR_FUNC(DSO_F_DSO_SET_NAME_CONVERTER), "DSO_set_name_converter"}, + {ERR_FUNC(DSO_F_DSO_UP_REF), "DSO_up_ref"}, + {ERR_FUNC(DSO_F_GLOBAL_LOOKUP_FUNC), "GLOBAL_LOOKUP_FUNC"}, + {ERR_FUNC(DSO_F_PATHBYADDR), "PATHBYADDR"}, + {ERR_FUNC(DSO_F_VMS_BIND_SYM), "VMS_BIND_SYM"}, + {ERR_FUNC(DSO_F_VMS_LOAD), "VMS_LOAD"}, + {ERR_FUNC(DSO_F_VMS_MERGER), "VMS_MERGER"}, + {ERR_FUNC(DSO_F_VMS_UNLOAD), "VMS_UNLOAD"}, + {ERR_FUNC(DSO_F_WIN32_BIND_FUNC), "WIN32_BIND_FUNC"}, + {ERR_FUNC(DSO_F_WIN32_BIND_VAR), "WIN32_BIND_VAR"}, + {ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP), "WIN32_GLOBALLOOKUP"}, + {ERR_FUNC(DSO_F_WIN32_GLOBALLOOKUP_FUNC), "WIN32_GLOBALLOOKUP_FUNC"}, + {ERR_FUNC(DSO_F_WIN32_JOINER), "WIN32_JOINER"}, + {ERR_FUNC(DSO_F_WIN32_LOAD), "WIN32_LOAD"}, + {ERR_FUNC(DSO_F_WIN32_MERGER), "WIN32_MERGER"}, + {ERR_FUNC(DSO_F_WIN32_NAME_CONVERTER), "WIN32_NAME_CONVERTER"}, + {ERR_FUNC(DSO_F_WIN32_PATHBYADDR), "WIN32_PATHBYADDR"}, + {ERR_FUNC(DSO_F_WIN32_SPLITTER), "WIN32_SPLITTER"}, + {ERR_FUNC(DSO_F_WIN32_UNLOAD), "WIN32_UNLOAD"}, + {0, NULL} +}; + +static ERR_STRING_DATA DSO_str_reasons[] = { + {ERR_REASON(DSO_R_CTRL_FAILED), "control command failed"}, + {ERR_REASON(DSO_R_DSO_ALREADY_LOADED), "dso already loaded"}, + {ERR_REASON(DSO_R_EMPTY_FILE_STRUCTURE), "empty file structure"}, + {ERR_REASON(DSO_R_FAILURE), "failure"}, + {ERR_REASON(DSO_R_FILENAME_TOO_BIG), "filename too big"}, + {ERR_REASON(DSO_R_FINISH_FAILED), "cleanup method function failed"}, + {ERR_REASON(DSO_R_INCORRECT_FILE_SYNTAX), "incorrect file syntax"}, + {ERR_REASON(DSO_R_LOAD_FAILED), "could not load the shared library"}, + {ERR_REASON(DSO_R_NAME_TRANSLATION_FAILED), "name translation failed"}, + {ERR_REASON(DSO_R_NO_FILENAME), "no filename"}, + {ERR_REASON(DSO_R_NO_FILE_SPECIFICATION), "no file specification"}, + {ERR_REASON(DSO_R_NULL_HANDLE), "a null shared library handle was used"}, + {ERR_REASON(DSO_R_SET_FILENAME_FAILED), "set filename failed"}, + {ERR_REASON(DSO_R_STACK_ERROR), "the meth_data stack is corrupt"}, + {ERR_REASON(DSO_R_SYM_FAILURE), + "could not bind to the requested symbol name"}, + {ERR_REASON(DSO_R_UNLOAD_FAILED), "could not unload the shared library"}, + {ERR_REASON(DSO_R_UNSUPPORTED), "functionality not supported"}, + {0, NULL} +}; + +#endif + +void ERR_load_DSO_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(DSO_str_functs[0].error) == NULL) { + ERR_load_strings(0, DSO_str_functs); + ERR_load_strings(0, DSO_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/dso/dso_lib.c b/libs/openssl/crypto/dso/dso_lib.c new file mode 100644 index 00000000..3312450e --- /dev/null +++ b/libs/openssl/crypto/dso/dso_lib.c @@ -0,0 +1,447 @@ +/* dso_lib.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include + +static DSO_METHOD *default_DSO_meth = NULL; + +DSO *DSO_new(void) +{ + return (DSO_new_method(NULL)); +} + +void DSO_set_default_method(DSO_METHOD *meth) +{ + default_DSO_meth = meth; +} + +DSO_METHOD *DSO_get_default_method(void) +{ + return (default_DSO_meth); +} + +DSO_METHOD *DSO_get_method(DSO *dso) +{ + return (dso->meth); +} + +DSO_METHOD *DSO_set_method(DSO *dso, DSO_METHOD *meth) +{ + DSO_METHOD *mtmp; + mtmp = dso->meth; + dso->meth = meth; + return (mtmp); +} + +DSO *DSO_new_method(DSO_METHOD *meth) +{ + DSO *ret; + + if (default_DSO_meth == NULL) + /* + * We default to DSO_METH_openssl() which in turn defaults to + * stealing the "best available" method. Will fallback to + * DSO_METH_null() in the worst case. + */ + default_DSO_meth = DSO_METHOD_openssl(); + ret = (DSO *)OPENSSL_malloc(sizeof(DSO)); + if (ret == NULL) { + DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return (NULL); + } + memset(ret, 0, sizeof(DSO)); + ret->meth_data = sk_void_new_null(); + if (ret->meth_data == NULL) { + /* sk_new doesn't generate any errors so we do */ + DSOerr(DSO_F_DSO_NEW_METHOD, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ret); + return (NULL); + } + if (meth == NULL) + ret->meth = default_DSO_meth; + else + ret->meth = meth; + ret->references = 1; + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { + OPENSSL_free(ret); + ret = NULL; + } + return (ret); +} + +int DSO_free(DSO *dso) +{ + int i; + + if (dso == NULL) { + DSOerr(DSO_F_DSO_FREE, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + + i = CRYPTO_add(&dso->references, -1, CRYPTO_LOCK_DSO); +#ifdef REF_PRINT + REF_PRINT("DSO", dso); +#endif + if (i > 0) + return (1); +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "DSO_free, bad reference count\n"); + abort(); + } +#endif + + if ((dso->meth->dso_unload != NULL) && !dso->meth->dso_unload(dso)) { + DSOerr(DSO_F_DSO_FREE, DSO_R_UNLOAD_FAILED); + return (0); + } + + if ((dso->meth->finish != NULL) && !dso->meth->finish(dso)) { + DSOerr(DSO_F_DSO_FREE, DSO_R_FINISH_FAILED); + return (0); + } + + sk_void_free(dso->meth_data); + if (dso->filename != NULL) + OPENSSL_free(dso->filename); + if (dso->loaded_filename != NULL) + OPENSSL_free(dso->loaded_filename); + + OPENSSL_free(dso); + return (1); +} + +int DSO_flags(DSO *dso) +{ + return ((dso == NULL) ? 0 : dso->flags); +} + +int DSO_up_ref(DSO *dso) +{ + if (dso == NULL) { + DSOerr(DSO_F_DSO_UP_REF, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + + CRYPTO_add(&dso->references, 1, CRYPTO_LOCK_DSO); + return (1); +} + +DSO *DSO_load(DSO *dso, const char *filename, DSO_METHOD *meth, int flags) +{ + DSO *ret; + int allocated = 0; + + if (dso == NULL) { + ret = DSO_new_method(meth); + if (ret == NULL) { + DSOerr(DSO_F_DSO_LOAD, ERR_R_MALLOC_FAILURE); + goto err; + } + allocated = 1; + /* Pass the provided flags to the new DSO object */ + if (DSO_ctrl(ret, DSO_CTRL_SET_FLAGS, flags, NULL) < 0) { + DSOerr(DSO_F_DSO_LOAD, DSO_R_CTRL_FAILED); + goto err; + } + } else + ret = dso; + /* Don't load if we're currently already loaded */ + if (ret->filename != NULL) { + DSOerr(DSO_F_DSO_LOAD, DSO_R_DSO_ALREADY_LOADED); + goto err; + } + /* + * filename can only be NULL if we were passed a dso that already has one + * set. + */ + if (filename != NULL) + if (!DSO_set_filename(ret, filename)) { + DSOerr(DSO_F_DSO_LOAD, DSO_R_SET_FILENAME_FAILED); + goto err; + } + filename = ret->filename; + if (filename == NULL) { + DSOerr(DSO_F_DSO_LOAD, DSO_R_NO_FILENAME); + goto err; + } + if (ret->meth->dso_load == NULL) { + DSOerr(DSO_F_DSO_LOAD, DSO_R_UNSUPPORTED); + goto err; + } + if (!ret->meth->dso_load(ret)) { + DSOerr(DSO_F_DSO_LOAD, DSO_R_LOAD_FAILED); + goto err; + } + /* Load succeeded */ + return (ret); + err: + if (allocated) + DSO_free(ret); + return (NULL); +} + +void *DSO_bind_var(DSO *dso, const char *symname) +{ + void *ret = NULL; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_DSO_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (dso->meth->dso_bind_var == NULL) { + DSOerr(DSO_F_DSO_BIND_VAR, DSO_R_UNSUPPORTED); + return (NULL); + } + if ((ret = dso->meth->dso_bind_var(dso, symname)) == NULL) { + DSOerr(DSO_F_DSO_BIND_VAR, DSO_R_SYM_FAILURE); + return (NULL); + } + /* Success */ + return (ret); +} + +DSO_FUNC_TYPE DSO_bind_func(DSO *dso, const char *symname) +{ + DSO_FUNC_TYPE ret = NULL; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_DSO_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (dso->meth->dso_bind_func == NULL) { + DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_UNSUPPORTED); + return (NULL); + } + if ((ret = dso->meth->dso_bind_func(dso, symname)) == NULL) { + DSOerr(DSO_F_DSO_BIND_FUNC, DSO_R_SYM_FAILURE); + return (NULL); + } + /* Success */ + return (ret); +} + +/* + * I don't really like these *_ctrl functions very much to be perfectly + * honest. For one thing, I think I have to return a negative value for any + * error because possible DSO_ctrl() commands may return values such as + * "size"s that can legitimately be zero (making the standard + * "if (DSO_cmd(...))" form that works almost everywhere else fail at odd + * times. I'd prefer "output" values to be passed by reference and the return + * value as success/failure like usual ... but we conform when we must... :-) + */ +long DSO_ctrl(DSO *dso, int cmd, long larg, void *parg) +{ + if (dso == NULL) { + DSOerr(DSO_F_DSO_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return (-1); + } + /* + * We should intercept certain generic commands and only pass control to + * the method-specific ctrl() function if it's something we don't handle. + */ + switch (cmd) { + case DSO_CTRL_GET_FLAGS: + return dso->flags; + case DSO_CTRL_SET_FLAGS: + dso->flags = (int)larg; + return (0); + case DSO_CTRL_OR_FLAGS: + dso->flags |= (int)larg; + return (0); + default: + break; + } + if ((dso->meth == NULL) || (dso->meth->dso_ctrl == NULL)) { + DSOerr(DSO_F_DSO_CTRL, DSO_R_UNSUPPORTED); + return (-1); + } + return (dso->meth->dso_ctrl(dso, cmd, larg, parg)); +} + +int DSO_set_name_converter(DSO *dso, DSO_NAME_CONVERTER_FUNC cb, + DSO_NAME_CONVERTER_FUNC *oldcb) +{ + if (dso == NULL) { + DSOerr(DSO_F_DSO_SET_NAME_CONVERTER, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (oldcb) + *oldcb = dso->name_converter; + dso->name_converter = cb; + return (1); +} + +const char *DSO_get_filename(DSO *dso) +{ + if (dso == NULL) { + DSOerr(DSO_F_DSO_GET_FILENAME, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + return (dso->filename); +} + +int DSO_set_filename(DSO *dso, const char *filename) +{ + char *copied; + + if ((dso == NULL) || (filename == NULL)) { + DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (dso->loaded_filename) { + DSOerr(DSO_F_DSO_SET_FILENAME, DSO_R_DSO_ALREADY_LOADED); + return (0); + } + /* We'll duplicate filename */ + copied = OPENSSL_malloc(strlen(filename) + 1); + if (copied == NULL) { + DSOerr(DSO_F_DSO_SET_FILENAME, ERR_R_MALLOC_FAILURE); + return (0); + } + BUF_strlcpy(copied, filename, strlen(filename) + 1); + if (dso->filename) + OPENSSL_free(dso->filename); + dso->filename = copied; + return (1); +} + +char *DSO_merge(DSO *dso, const char *filespec1, const char *filespec2) +{ + char *result = NULL; + + if (dso == NULL || filespec1 == NULL) { + DSOerr(DSO_F_DSO_MERGE, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) { + if (dso->merger != NULL) + result = dso->merger(dso, filespec1, filespec2); + else if (dso->meth->dso_merger != NULL) + result = dso->meth->dso_merger(dso, filespec1, filespec2); + } + return (result); +} + +char *DSO_convert_filename(DSO *dso, const char *filename) +{ + char *result = NULL; + + if (dso == NULL) { + DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (filename == NULL) + filename = dso->filename; + if (filename == NULL) { + DSOerr(DSO_F_DSO_CONVERT_FILENAME, DSO_R_NO_FILENAME); + return (NULL); + } + if ((dso->flags & DSO_FLAG_NO_NAME_TRANSLATION) == 0) { + if (dso->name_converter != NULL) + result = dso->name_converter(dso, filename); + else if (dso->meth->dso_name_converter != NULL) + result = dso->meth->dso_name_converter(dso, filename); + } + if (result == NULL) { + result = OPENSSL_malloc(strlen(filename) + 1); + if (result == NULL) { + DSOerr(DSO_F_DSO_CONVERT_FILENAME, ERR_R_MALLOC_FAILURE); + return (NULL); + } + BUF_strlcpy(result, filename, strlen(filename) + 1); + } + return (result); +} + +const char *DSO_get_loaded_filename(DSO *dso) +{ + if (dso == NULL) { + DSOerr(DSO_F_DSO_GET_LOADED_FILENAME, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + return (dso->loaded_filename); +} + +int DSO_pathbyaddr(void *addr, char *path, int sz) +{ + DSO_METHOD *meth = default_DSO_meth; + if (meth == NULL) + meth = DSO_METHOD_openssl(); + if (meth->pathbyaddr == NULL) { + DSOerr(DSO_F_DSO_PATHBYADDR, DSO_R_UNSUPPORTED); + return -1; + } + return (*meth->pathbyaddr) (addr, path, sz); +} + +void *DSO_global_lookup(const char *name) +{ + DSO_METHOD *meth = default_DSO_meth; + if (meth == NULL) + meth = DSO_METHOD_openssl(); + if (meth->globallookup == NULL) { + DSOerr(DSO_F_DSO_GLOBAL_LOOKUP, DSO_R_UNSUPPORTED); + return NULL; + } + return (*meth->globallookup) (name); +} diff --git a/libs/openssl/crypto/dso/dso_null.c b/libs/openssl/crypto/dso/dso_null.c new file mode 100644 index 00000000..20122d1c --- /dev/null +++ b/libs/openssl/crypto/dso/dso_null.c @@ -0,0 +1,92 @@ +/* dso_null.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * This "NULL" method is provided as the fallback for systems that have no + * appropriate support for "shared-libraries". + */ + +#include +#include "cryptlib.h" +#include + +static DSO_METHOD dso_meth_null = { + "NULL shared library method", + NULL, /* load */ + NULL, /* unload */ + NULL, /* bind_var */ + NULL, /* bind_func */ +/* For now, "unbind" doesn't exist */ +#if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +#endif + NULL, /* ctrl */ + NULL, /* dso_name_converter */ + NULL, /* dso_merger */ + NULL, /* init */ + NULL, /* finish */ + NULL, /* pathbyaddr */ + NULL /* globallookup */ +}; + +DSO_METHOD *DSO_METHOD_null(void) +{ + return (&dso_meth_null); +} diff --git a/libs/openssl/crypto/dso/dso_openssl.c b/libs/openssl/crypto/dso/dso_openssl.c new file mode 100644 index 00000000..087e989e --- /dev/null +++ b/libs/openssl/crypto/dso/dso_openssl.c @@ -0,0 +1,83 @@ +/* dso_openssl.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +/* We just pinch the method from an appropriate "default" method. */ + +DSO_METHOD *DSO_METHOD_openssl(void) +{ +#ifdef DEF_DSO_METHOD + return (DEF_DSO_METHOD()); +#elif defined(DSO_DLFCN) + return (DSO_METHOD_dlfcn()); +#elif defined(DSO_DL) + return (DSO_METHOD_dl()); +#elif defined(DSO_WIN32) + return (DSO_METHOD_win32()); +#elif defined(DSO_VMS) + return (DSO_METHOD_vms()); +#elif defined(DSO_BEOS) + return (DSO_METHOD_beos()); +#else + return (DSO_METHOD_null()); +#endif +} diff --git a/libs/openssl/crypto/dso/dso_vms.c b/libs/openssl/crypto/dso/dso_vms.c new file mode 100644 index 00000000..1efd84b9 --- /dev/null +++ b/libs/openssl/crypto/dso/dso_vms.c @@ -0,0 +1,547 @@ +/* dso_vms.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include "cryptlib.h" +#include + +#ifndef OPENSSL_SYS_VMS +DSO_METHOD *DSO_METHOD_vms(void) +{ + return NULL; +} +#else + +# pragma message disable DOLLARID +# include +# include +# include +# include +# include +# include "vms_rms.h" + +/* Some compiler options may mask the declaration of "_malloc32". */ +# if __INITIAL_POINTER_SIZE && defined _ANSI_C_SOURCE +# if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size save +# pragma pointer_size 32 +void *_malloc32(__size_t); +# pragma pointer_size restore +# endif /* __INITIAL_POINTER_SIZE == 64 */ +# endif /* __INITIAL_POINTER_SIZE && defined + * _ANSI_C_SOURCE */ + +# pragma message disable DOLLARID + +static int vms_load(DSO *dso); +static int vms_unload(DSO *dso); +static void *vms_bind_var(DSO *dso, const char *symname); +static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname); +# if 0 +static int vms_unbind_var(DSO *dso, char *symname, void *symptr); +static int vms_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +static int vms_init(DSO *dso); +static int vms_finish(DSO *dso); +static long vms_ctrl(DSO *dso, int cmd, long larg, void *parg); +# endif +static char *vms_name_converter(DSO *dso, const char *filename); +static char *vms_merger(DSO *dso, const char *filespec1, + const char *filespec2); + +static DSO_METHOD dso_meth_vms = { + "OpenSSL 'VMS' shared library method", + vms_load, + NULL, /* unload */ + vms_bind_var, + vms_bind_func, +/* For now, "unbind" doesn't exist */ +# if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +# endif + NULL, /* ctrl */ + vms_name_converter, + vms_merger, + NULL, /* init */ + NULL /* finish */ +}; + +/* + * On VMS, the only "handle" is the file name. LIB$FIND_IMAGE_SYMBOL depends + * on the reference to the file name being the same for all calls regarding + * one shared image, so we'll just store it in an instance of the following + * structure and put a pointer to that instance in the meth_data stack. + */ +typedef struct dso_internal_st { + /* + * This should contain the name only, no directory, no extension, nothing + * but a name. + */ + struct dsc$descriptor_s filename_dsc; + char filename[NAMX_MAXRSS + 1]; + /* + * This contains whatever is not in filename, if needed. Normally not + * defined. + */ + struct dsc$descriptor_s imagename_dsc; + char imagename[NAMX_MAXRSS + 1]; +} DSO_VMS_INTERNAL; + +DSO_METHOD *DSO_METHOD_vms(void) +{ + return (&dso_meth_vms); +} + +static int vms_load(DSO *dso) +{ + void *ptr = NULL; + /* See applicable comments in dso_dl.c */ + char *filename = DSO_convert_filename(dso, NULL); + +/* Ensure 32-bit pointer for "p", and appropriate malloc() function. */ +# if __INITIAL_POINTER_SIZE == 64 +# define DSO_MALLOC _malloc32 +# pragma pointer_size save +# pragma pointer_size 32 +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define DSO_MALLOC OPENSSL_malloc +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + DSO_VMS_INTERNAL *p = NULL; + +# if __INITIAL_POINTER_SIZE == 64 +# pragma pointer_size restore +# endif /* __INITIAL_POINTER_SIZE == 64 */ + + const char *sp1, *sp2; /* Search result */ + const char *ext = NULL; /* possible extension to add */ + + if (filename == NULL) { + DSOerr(DSO_F_VMS_LOAD, DSO_R_NO_FILENAME); + goto err; + } + + /*- + * A file specification may look like this: + * + * node::dev:[dir-spec]name.type;ver + * + * or (for compatibility with TOPS-20): + * + * node::dev:name.type;ver + * + * and the dir-spec uses '.' as separator. Also, a dir-spec + * may consist of several parts, with mixed use of [] and <>: + * + * [dir1.] + * + * We need to split the file specification into the name and + * the rest (both before and after the name itself). + */ + /* + * Start with trying to find the end of a dir-spec, and save the position + * of the byte after in sp1 + */ + sp1 = strrchr(filename, ']'); + sp2 = strrchr(filename, '>'); + if (sp1 == NULL) + sp1 = sp2; + if (sp2 != NULL && sp2 > sp1) + sp1 = sp2; + if (sp1 == NULL) + sp1 = strrchr(filename, ':'); + if (sp1 == NULL) + sp1 = filename; + else + sp1++; /* The byte after the found character */ + /* Now, let's see if there's a type, and save the position in sp2 */ + sp2 = strchr(sp1, '.'); + /* + * If there is a period and the next character is a semi-colon, + * we need to add an extension + */ + if (sp2 != NULL && sp2[1] == ';') + ext = ".EXE"; + /* + * If we found it, that's where we'll cut. Otherwise, look for a version + * number and save the position in sp2 + */ + if (sp2 == NULL) { + sp2 = strchr(sp1, ';'); + ext = ".EXE"; + } + /* + * If there was still nothing to find, set sp2 to point at the end of the + * string + */ + if (sp2 == NULL) + sp2 = sp1 + strlen(sp1); + + /* Check that we won't get buffer overflows */ + if (sp2 - sp1 > FILENAME_MAX + || (sp1 - filename) + strlen(sp2) > FILENAME_MAX) { + DSOerr(DSO_F_VMS_LOAD, DSO_R_FILENAME_TOO_BIG); + goto err; + } + + p = DSO_MALLOC(sizeof(DSO_VMS_INTERNAL)); + if (p == NULL) { + DSOerr(DSO_F_VMS_LOAD, ERR_R_MALLOC_FAILURE); + goto err; + } + + strncpy(p->filename, sp1, sp2 - sp1); + p->filename[sp2 - sp1] = '\0'; + + strncpy(p->imagename, filename, sp1 - filename); + p->imagename[sp1 - filename] = '\0'; + if (ext) { + strcat(p->imagename, ext); + if (*sp2 == '.') + sp2++; + } + strcat(p->imagename, sp2); + + p->filename_dsc.dsc$w_length = strlen(p->filename); + p->filename_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + p->filename_dsc.dsc$b_class = DSC$K_CLASS_S; + p->filename_dsc.dsc$a_pointer = p->filename; + p->imagename_dsc.dsc$w_length = strlen(p->imagename); + p->imagename_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + p->imagename_dsc.dsc$b_class = DSC$K_CLASS_S; + p->imagename_dsc.dsc$a_pointer = p->imagename; + + if (!sk_void_push(dso->meth_data, (char *)p)) { + DSOerr(DSO_F_VMS_LOAD, DSO_R_STACK_ERROR); + goto err; + } + + /* Success (for now, we lie. We actually do not know...) */ + dso->loaded_filename = filename; + return (1); + err: + /* Cleanup! */ + if (p != NULL) + OPENSSL_free(p); + if (filename != NULL) + OPENSSL_free(filename); + return (0); +} + +/* + * Note that this doesn't actually unload the shared image, as there is no + * such thing in VMS. Next time it get loaded again, a new copy will + * actually be loaded. + */ +static int vms_unload(DSO *dso) +{ + DSO_VMS_INTERNAL *p; + if (dso == NULL) { + DSOerr(DSO_F_VMS_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (sk_void_num(dso->meth_data) < 1) + return (1); + p = (DSO_VMS_INTERNAL *)sk_void_pop(dso->meth_data); + if (p == NULL) { + DSOerr(DSO_F_VMS_UNLOAD, DSO_R_NULL_HANDLE); + return (0); + } + /* Cleanup */ + OPENSSL_free(p); + return (1); +} + +/* + * We must do this in a separate function because of the way the exception + * handler works (it makes this function return + */ +static int do_find_symbol(DSO_VMS_INTERNAL *ptr, + struct dsc$descriptor_s *symname_dsc, void **sym, + unsigned long flags) +{ + /* + * Make sure that signals are caught and returned instead of aborting the + * program. The exception handler gets unestablished automatically on + * return from this function. + */ + lib$establish(lib$sig_to_ret); + + if (ptr->imagename_dsc.dsc$w_length) + return lib$find_image_symbol(&ptr->filename_dsc, + symname_dsc, sym, + &ptr->imagename_dsc, flags); + else + return lib$find_image_symbol(&ptr->filename_dsc, + symname_dsc, sym, 0, flags); +} + +void vms_bind_sym(DSO *dso, const char *symname, void **sym) +{ + DSO_VMS_INTERNAL *ptr; + int status; +# if 0 + int flags = (1 << 4); /* LIB$M_FIS_MIXEDCASE, but this symbol isn't + * defined in VMS older than 7.0 or so */ +# else + int flags = 0; +# endif + struct dsc$descriptor_s symname_dsc; + +/* Arrange 32-bit pointer to (copied) string storage, if needed. */ +# if __INITIAL_POINTER_SIZE == 64 +# define SYMNAME symname_32p +# pragma pointer_size save +# pragma pointer_size 32 + char *symname_32p; +# pragma pointer_size restore + char symname_32[NAMX_MAXRSS + 1]; +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define SYMNAME ((char *) symname) +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + *sym = NULL; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_VMS_BIND_SYM, ERR_R_PASSED_NULL_PARAMETER); + return; + } +# if __INITIAL_POINTER_SIZE == 64 + /* Copy the symbol name to storage with a 32-bit pointer. */ + symname_32p = symname_32; + strcpy(symname_32p, symname); +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + symname_dsc.dsc$w_length = strlen(SYMNAME); + symname_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + symname_dsc.dsc$b_class = DSC$K_CLASS_S; + symname_dsc.dsc$a_pointer = SYMNAME; + + if (sk_void_num(dso->meth_data) < 1) { + DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_STACK_ERROR); + return; + } + ptr = (DSO_VMS_INTERNAL *)sk_void_value(dso->meth_data, + sk_void_num(dso->meth_data) - 1); + if (ptr == NULL) { + DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_NULL_HANDLE); + return; + } + + if (dso->flags & DSO_FLAG_UPCASE_SYMBOL) + flags = 0; + + status = do_find_symbol(ptr, &symname_dsc, sym, flags); + + if (!$VMS_STATUS_SUCCESS(status)) { + unsigned short length; + char errstring[257]; + struct dsc$descriptor_s errstring_dsc; + + errstring_dsc.dsc$w_length = sizeof(errstring); + errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + errstring_dsc.dsc$b_class = DSC$K_CLASS_S; + errstring_dsc.dsc$a_pointer = errstring; + + *sym = NULL; + + status = sys$getmsg(status, &length, &errstring_dsc, 1, 0); + + if (!$VMS_STATUS_SUCCESS(status)) + lib$signal(status); /* This is really bad. Abort! */ + else { + errstring[length] = '\0'; + + DSOerr(DSO_F_VMS_BIND_SYM, DSO_R_SYM_FAILURE); + if (ptr->imagename_dsc.dsc$w_length) + ERR_add_error_data(9, + "Symbol ", symname, + " in ", ptr->filename, + " (", ptr->imagename, ")", + ": ", errstring); + else + ERR_add_error_data(6, + "Symbol ", symname, + " in ", ptr->filename, ": ", errstring); + } + return; + } + return; +} + +static void *vms_bind_var(DSO *dso, const char *symname) +{ + void *sym = 0; + vms_bind_sym(dso, symname, &sym); + return sym; +} + +static DSO_FUNC_TYPE vms_bind_func(DSO *dso, const char *symname) +{ + DSO_FUNC_TYPE sym = 0; + vms_bind_sym(dso, symname, (void **)&sym); + return sym; +} + +static char *vms_merger(DSO *dso, const char *filespec1, + const char *filespec2) +{ + int status; + int filespec1len, filespec2len; + struct FAB fab; + struct NAMX_STRUCT nam; + char esa[NAMX_MAXRSS + 1]; + char *merged; + +/* Arrange 32-bit pointer to (copied) string storage, if needed. */ +# if __INITIAL_POINTER_SIZE == 64 +# define FILESPEC1 filespec1_32p; +# define FILESPEC2 filespec2_32p; +# pragma pointer_size save +# pragma pointer_size 32 + char *filespec1_32p; + char *filespec2_32p; +# pragma pointer_size restore + char filespec1_32[NAMX_MAXRSS + 1]; + char filespec2_32[NAMX_MAXRSS + 1]; +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define FILESPEC1 ((char *) filespec1) +# define FILESPEC2 ((char *) filespec2) +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + if (!filespec1) + filespec1 = ""; + if (!filespec2) + filespec2 = ""; + filespec1len = strlen(filespec1); + filespec2len = strlen(filespec2); + +# if __INITIAL_POINTER_SIZE == 64 + /* Copy the file names to storage with a 32-bit pointer. */ + filespec1_32p = filespec1_32; + filespec2_32p = filespec2_32; + strcpy(filespec1_32p, filespec1); + strcpy(filespec2_32p, filespec2); +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + + fab = cc$rms_fab; + nam = CC_RMS_NAMX; + + FAB_OR_NAML(fab, nam).FAB_OR_NAML_FNA = FILESPEC1; + FAB_OR_NAML(fab, nam).FAB_OR_NAML_FNS = filespec1len; + FAB_OR_NAML(fab, nam).FAB_OR_NAML_DNA = FILESPEC2; + FAB_OR_NAML(fab, nam).FAB_OR_NAML_DNS = filespec2len; + NAMX_DNA_FNA_SET(fab) + + nam.NAMX_ESA = esa; + nam.NAMX_ESS = NAMX_MAXRSS; + nam.NAMX_NOP = NAM$M_SYNCHK | NAM$M_PWD; + SET_NAMX_NO_SHORT_UPCASE(nam); + + fab.FAB_NAMX = &nam; + + status = sys$parse(&fab, 0, 0); + + if (!$VMS_STATUS_SUCCESS(status)) { + unsigned short length; + char errstring[257]; + struct dsc$descriptor_s errstring_dsc; + + errstring_dsc.dsc$w_length = sizeof(errstring); + errstring_dsc.dsc$b_dtype = DSC$K_DTYPE_T; + errstring_dsc.dsc$b_class = DSC$K_CLASS_S; + errstring_dsc.dsc$a_pointer = errstring; + + status = sys$getmsg(status, &length, &errstring_dsc, 1, 0); + + if (!$VMS_STATUS_SUCCESS(status)) + lib$signal(status); /* This is really bad. Abort! */ + else { + errstring[length] = '\0'; + + DSOerr(DSO_F_VMS_MERGER, DSO_R_FAILURE); + ERR_add_error_data(7, + "filespec \"", filespec1, "\", ", + "defaults \"", filespec2, "\": ", errstring); + } + return (NULL); + } + + merged = OPENSSL_malloc(nam.NAMX_ESL + 1); + if (!merged) + goto malloc_err; + strncpy(merged, nam.NAMX_ESA, nam.NAMX_ESL); + merged[nam.NAMX_ESL] = '\0'; + return (merged); + malloc_err: + DSOerr(DSO_F_VMS_MERGER, ERR_R_MALLOC_FAILURE); +} + +static char *vms_name_converter(DSO *dso, const char *filename) +{ + int len = strlen(filename); + char *not_translated = OPENSSL_malloc(len + 1); + if (not_translated) + strcpy(not_translated, filename); + return (not_translated); +} + +#endif /* OPENSSL_SYS_VMS */ diff --git a/libs/openssl/crypto/dso/dso_win32.c b/libs/openssl/crypto/dso/dso_win32.c new file mode 100644 index 00000000..eaf1831a --- /dev/null +++ b/libs/openssl/crypto/dso/dso_win32.c @@ -0,0 +1,785 @@ +/* dso_win32.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include + +#if !defined(DSO_WIN32) +DSO_METHOD *DSO_METHOD_win32(void) +{ + return NULL; +} +#else + +# ifdef _WIN32_WCE +# if _WIN32_WCE < 300 +static FARPROC GetProcAddressA(HMODULE hModule, LPCSTR lpProcName) +{ + WCHAR lpProcNameW[64]; + int i; + + for (i = 0; lpProcName[i] && i < 64; i++) + lpProcNameW[i] = (WCHAR)lpProcName[i]; + if (i == 64) + return NULL; + lpProcNameW[i] = 0; + + return GetProcAddressW(hModule, lpProcNameW); +} +# endif +# undef GetProcAddress +# define GetProcAddress GetProcAddressA + +static HINSTANCE LoadLibraryA(LPCSTR lpLibFileName) +{ + WCHAR *fnamw; + size_t len_0 = strlen(lpLibFileName) + 1, i; + +# ifdef _MSC_VER + fnamw = (WCHAR *)_alloca(len_0 * sizeof(WCHAR)); +# else + fnamw = (WCHAR *)alloca(len_0 * sizeof(WCHAR)); +# endif + if (fnamw == NULL) { + SetLastError(ERROR_NOT_ENOUGH_MEMORY); + return NULL; + } +# if defined(_WIN32_WCE) && _WIN32_WCE>=101 + if (!MultiByteToWideChar(CP_ACP, 0, lpLibFileName, len_0, fnamw, len_0)) +# endif + for (i = 0; i < len_0; i++) + fnamw[i] = (WCHAR)lpLibFileName[i]; + + return LoadLibraryW(fnamw); +} +# endif + +/* Part of the hack in "win32_load" ... */ +# define DSO_MAX_TRANSLATED_SIZE 256 + +static int win32_load(DSO *dso); +static int win32_unload(DSO *dso); +static void *win32_bind_var(DSO *dso, const char *symname); +static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname); +# if 0 +static int win32_unbind_var(DSO *dso, char *symname, void *symptr); +static int win32_unbind_func(DSO *dso, char *symname, DSO_FUNC_TYPE symptr); +static int win32_init(DSO *dso); +static int win32_finish(DSO *dso); +static long win32_ctrl(DSO *dso, int cmd, long larg, void *parg); +# endif +static char *win32_name_converter(DSO *dso, const char *filename); +static char *win32_merger(DSO *dso, const char *filespec1, + const char *filespec2); +static int win32_pathbyaddr(void *addr, char *path, int sz); +static void *win32_globallookup(const char *name); + +static const char *openssl_strnchr(const char *string, int c, size_t len); + +static DSO_METHOD dso_meth_win32 = { + "OpenSSL 'win32' shared library method", + win32_load, + win32_unload, + win32_bind_var, + win32_bind_func, +/* For now, "unbind" doesn't exist */ +# if 0 + NULL, /* unbind_var */ + NULL, /* unbind_func */ +# endif + NULL, /* ctrl */ + win32_name_converter, + win32_merger, + NULL, /* init */ + NULL, /* finish */ + win32_pathbyaddr, + win32_globallookup +}; + +DSO_METHOD *DSO_METHOD_win32(void) +{ + return (&dso_meth_win32); +} + +/* + * For this DSO_METHOD, our meth_data STACK will contain; (i) a pointer to + * the handle (HINSTANCE) returned from LoadLibrary(), and copied. + */ + +static int win32_load(DSO *dso) +{ + HINSTANCE h = NULL, *p = NULL; + /* See applicable comments from dso_dl.c */ + char *filename = DSO_convert_filename(dso, NULL); + + if (filename == NULL) { + DSOerr(DSO_F_WIN32_LOAD, DSO_R_NO_FILENAME); + goto err; + } + h = LoadLibraryA(filename); + if (h == NULL) { + DSOerr(DSO_F_WIN32_LOAD, DSO_R_LOAD_FAILED); + ERR_add_error_data(3, "filename(", filename, ")"); + goto err; + } + p = (HINSTANCE *) OPENSSL_malloc(sizeof(HINSTANCE)); + if (p == NULL) { + DSOerr(DSO_F_WIN32_LOAD, ERR_R_MALLOC_FAILURE); + goto err; + } + *p = h; + if (!sk_void_push(dso->meth_data, p)) { + DSOerr(DSO_F_WIN32_LOAD, DSO_R_STACK_ERROR); + goto err; + } + /* Success */ + dso->loaded_filename = filename; + return (1); + err: + /* Cleanup ! */ + if (filename != NULL) + OPENSSL_free(filename); + if (p != NULL) + OPENSSL_free(p); + if (h != NULL) + FreeLibrary(h); + return (0); +} + +static int win32_unload(DSO *dso) +{ + HINSTANCE *p; + if (dso == NULL) { + DSOerr(DSO_F_WIN32_UNLOAD, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (sk_void_num(dso->meth_data) < 1) + return (1); + p = sk_void_pop(dso->meth_data); + if (p == NULL) { + DSOerr(DSO_F_WIN32_UNLOAD, DSO_R_NULL_HANDLE); + return (0); + } + if (!FreeLibrary(*p)) { + DSOerr(DSO_F_WIN32_UNLOAD, DSO_R_UNLOAD_FAILED); + /* + * We should push the value back onto the stack in case of a retry. + */ + sk_void_push(dso->meth_data, p); + return (0); + } + /* Cleanup */ + OPENSSL_free(p); + return (1); +} + +/* + * Using GetProcAddress for variables? TODO: Check this out in the Win32 API + * docs, there's probably a variant for variables. + */ +static void *win32_bind_var(DSO *dso, const char *symname) +{ + HINSTANCE *ptr; + void *sym; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_WIN32_BIND_VAR, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_void_num(dso->meth_data) < 1) { + DSOerr(DSO_F_WIN32_BIND_VAR, DSO_R_STACK_ERROR); + return (NULL); + } + ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); + if (ptr == NULL) { + DSOerr(DSO_F_WIN32_BIND_VAR, DSO_R_NULL_HANDLE); + return (NULL); + } + sym = GetProcAddress(*ptr, symname); + if (sym == NULL) { + DSOerr(DSO_F_WIN32_BIND_VAR, DSO_R_SYM_FAILURE); + ERR_add_error_data(3, "symname(", symname, ")"); + return (NULL); + } + return (sym); +} + +static DSO_FUNC_TYPE win32_bind_func(DSO *dso, const char *symname) +{ + HINSTANCE *ptr; + void *sym; + + if ((dso == NULL) || (symname == NULL)) { + DSOerr(DSO_F_WIN32_BIND_FUNC, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (sk_void_num(dso->meth_data) < 1) { + DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_STACK_ERROR); + return (NULL); + } + ptr = sk_void_value(dso->meth_data, sk_void_num(dso->meth_data) - 1); + if (ptr == NULL) { + DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_NULL_HANDLE); + return (NULL); + } + sym = GetProcAddress(*ptr, symname); + if (sym == NULL) { + DSOerr(DSO_F_WIN32_BIND_FUNC, DSO_R_SYM_FAILURE); + ERR_add_error_data(3, "symname(", symname, ")"); + return (NULL); + } + return ((DSO_FUNC_TYPE)sym); +} + +struct file_st { + const char *node; + int nodelen; + const char *device; + int devicelen; + const char *predir; + int predirlen; + const char *dir; + int dirlen; + const char *file; + int filelen; +}; + +static struct file_st *win32_splitter(DSO *dso, const char *filename, + int assume_last_is_dir) +{ + struct file_st *result = NULL; + enum { IN_NODE, IN_DEVICE, IN_FILE } position; + const char *start = filename; + char last; + + if (!filename) { + DSOerr(DSO_F_WIN32_SPLITTER, DSO_R_NO_FILENAME); + /* + * goto err; + */ + return (NULL); + } + + result = OPENSSL_malloc(sizeof(struct file_st)); + if (result == NULL) { + DSOerr(DSO_F_WIN32_SPLITTER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + memset(result, 0, sizeof(struct file_st)); + position = IN_DEVICE; + + if ((filename[0] == '\\' && filename[1] == '\\') + || (filename[0] == '/' && filename[1] == '/')) { + position = IN_NODE; + filename += 2; + start = filename; + result->node = start; + } + + do { + last = filename[0]; + switch (last) { + case ':': + if (position != IN_DEVICE) { + DSOerr(DSO_F_WIN32_SPLITTER, DSO_R_INCORRECT_FILE_SYNTAX); + /* + * goto err; + */ + OPENSSL_free(result); + return (NULL); + } + result->device = start; + result->devicelen = (int)(filename - start); + position = IN_FILE; + start = ++filename; + result->dir = start; + break; + case '\\': + case '/': + if (position == IN_NODE) { + result->nodelen = (int)(filename - start); + position = IN_FILE; + start = ++filename; + result->dir = start; + } else if (position == IN_DEVICE) { + position = IN_FILE; + filename++; + result->dir = start; + result->dirlen = (int)(filename - start); + start = filename; + } else { + filename++; + result->dirlen += (int)(filename - start); + start = filename; + } + break; + case '\0': + if (position == IN_NODE) { + result->nodelen = (int)(filename - start); + } else { + if (filename - start > 0) { + if (assume_last_is_dir) { + if (position == IN_DEVICE) { + result->dir = start; + result->dirlen = 0; + } + result->dirlen += (int)(filename - start); + } else { + result->file = start; + result->filelen = (int)(filename - start); + } + } + } + break; + default: + filename++; + break; + } + } + while (last); + + if (!result->nodelen) + result->node = NULL; + if (!result->devicelen) + result->device = NULL; + if (!result->dirlen) + result->dir = NULL; + if (!result->filelen) + result->file = NULL; + + return (result); +} + +static char *win32_joiner(DSO *dso, const struct file_st *file_split) +{ + int len = 0, offset = 0; + char *result = NULL; + const char *start; + + if (!file_split) { + DSOerr(DSO_F_WIN32_JOINER, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (file_split->node) { + len += 2 + file_split->nodelen; /* 2 for starting \\ */ + if (file_split->predir || file_split->dir || file_split->file) + len++; /* 1 for ending \ */ + } else if (file_split->device) { + len += file_split->devicelen + 1; /* 1 for ending : */ + } + len += file_split->predirlen; + if (file_split->predir && (file_split->dir || file_split->file)) { + len++; /* 1 for ending \ */ + } + len += file_split->dirlen; + if (file_split->dir && file_split->file) { + len++; /* 1 for ending \ */ + } + len += file_split->filelen; + + if (!len) { + DSOerr(DSO_F_WIN32_JOINER, DSO_R_EMPTY_FILE_STRUCTURE); + return (NULL); + } + + result = OPENSSL_malloc(len + 1); + if (!result) { + DSOerr(DSO_F_WIN32_JOINER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + if (file_split->node) { + strcpy(&result[offset], "\\\\"); + offset += 2; + strncpy(&result[offset], file_split->node, file_split->nodelen); + offset += file_split->nodelen; + if (file_split->predir || file_split->dir || file_split->file) { + result[offset] = '\\'; + offset++; + } + } else if (file_split->device) { + strncpy(&result[offset], file_split->device, file_split->devicelen); + offset += file_split->devicelen; + result[offset] = ':'; + offset++; + } + start = file_split->predir; + while (file_split->predirlen > (start - file_split->predir)) { + const char *end = openssl_strnchr(start, '/', + file_split->predirlen - (start - + file_split->predir)); + if (!end) + end = start + + file_split->predirlen - (start - file_split->predir); + strncpy(&result[offset], start, end - start); + offset += (int)(end - start); + result[offset] = '\\'; + offset++; + start = end + 1; + } +# if 0 /* Not needed, since the directory converter + * above already appeneded a backslash */ + if (file_split->predir && (file_split->dir || file_split->file)) { + result[offset] = '\\'; + offset++; + } +# endif + start = file_split->dir; + while (file_split->dirlen > (start - file_split->dir)) { + const char *end = openssl_strnchr(start, '/', + file_split->dirlen - (start - + file_split->dir)); + if (!end) + end = start + file_split->dirlen - (start - file_split->dir); + strncpy(&result[offset], start, end - start); + offset += (int)(end - start); + result[offset] = '\\'; + offset++; + start = end + 1; + } +# if 0 /* Not needed, since the directory converter + * above already appeneded a backslash */ + if (file_split->dir && file_split->file) { + result[offset] = '\\'; + offset++; + } +# endif + strncpy(&result[offset], file_split->file, file_split->filelen); + offset += file_split->filelen; + result[offset] = '\0'; + return (result); +} + +static char *win32_merger(DSO *dso, const char *filespec1, + const char *filespec2) +{ + char *merged = NULL; + struct file_st *filespec1_split = NULL; + struct file_st *filespec2_split = NULL; + + if (!filespec1 && !filespec2) { + DSOerr(DSO_F_WIN32_MERGER, ERR_R_PASSED_NULL_PARAMETER); + return (NULL); + } + if (!filespec2) { + merged = OPENSSL_malloc(strlen(filespec1) + 1); + if (!merged) { + DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec1); + } else if (!filespec1) { + merged = OPENSSL_malloc(strlen(filespec2) + 1); + if (!merged) { + DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + strcpy(merged, filespec2); + } else { + filespec1_split = win32_splitter(dso, filespec1, 0); + if (!filespec1_split) { + DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE); + return (NULL); + } + filespec2_split = win32_splitter(dso, filespec2, 1); + if (!filespec2_split) { + DSOerr(DSO_F_WIN32_MERGER, ERR_R_MALLOC_FAILURE); + OPENSSL_free(filespec1_split); + return (NULL); + } + + /* Fill in into filespec1_split */ + if (!filespec1_split->node && !filespec1_split->device) { + filespec1_split->node = filespec2_split->node; + filespec1_split->nodelen = filespec2_split->nodelen; + filespec1_split->device = filespec2_split->device; + filespec1_split->devicelen = filespec2_split->devicelen; + } + if (!filespec1_split->dir) { + filespec1_split->dir = filespec2_split->dir; + filespec1_split->dirlen = filespec2_split->dirlen; + } else if (filespec1_split->dir[0] != '\\' + && filespec1_split->dir[0] != '/') { + filespec1_split->predir = filespec2_split->dir; + filespec1_split->predirlen = filespec2_split->dirlen; + } + if (!filespec1_split->file) { + filespec1_split->file = filespec2_split->file; + filespec1_split->filelen = filespec2_split->filelen; + } + + merged = win32_joiner(dso, filespec1_split); + } + OPENSSL_free(filespec1_split); + OPENSSL_free(filespec2_split); + return (merged); +} + +static char *win32_name_converter(DSO *dso, const char *filename) +{ + char *translated; + int len, transform; + + len = strlen(filename); + transform = ((strstr(filename, "/") == NULL) && + (strstr(filename, "\\") == NULL) && + (strstr(filename, ":") == NULL)); + if (transform) + /* We will convert this to "%s.dll" */ + translated = OPENSSL_malloc(len + 5); + else + /* We will simply duplicate filename */ + translated = OPENSSL_malloc(len + 1); + if (translated == NULL) { + DSOerr(DSO_F_WIN32_NAME_CONVERTER, DSO_R_NAME_TRANSLATION_FAILED); + return (NULL); + } + if (transform) + sprintf(translated, "%s.dll", filename); + else + sprintf(translated, "%s", filename); + return (translated); +} + +static const char *openssl_strnchr(const char *string, int c, size_t len) +{ + size_t i; + const char *p; + for (i = 0, p = string; i < len && *p; i++, p++) { + if (*p == c) + return p; + } + return NULL; +} + +# include +# ifdef _WIN32_WCE +# define DLLNAME "TOOLHELP.DLL" +# else +# ifdef MODULEENTRY32 +# undef MODULEENTRY32 /* unmask the ASCII version! */ +# endif +# define DLLNAME "KERNEL32.DLL" +# endif + +typedef HANDLE(WINAPI *CREATETOOLHELP32SNAPSHOT) (DWORD, DWORD); +typedef BOOL(WINAPI *CLOSETOOLHELP32SNAPSHOT) (HANDLE); +typedef BOOL(WINAPI *MODULE32) (HANDLE, MODULEENTRY32 *); + +static int win32_pathbyaddr(void *addr, char *path, int sz) +{ + HMODULE dll; + HANDLE hModuleSnap = INVALID_HANDLE_VALUE; + MODULEENTRY32 me32; + CREATETOOLHELP32SNAPSHOT create_snap; + CLOSETOOLHELP32SNAPSHOT close_snap; + MODULE32 module_first, module_next; + int len; + + if (addr == NULL) { + union { + int (*f) (void *, char *, int); + void *p; + } t = { + win32_pathbyaddr + }; + addr = t.p; + } + + dll = LoadLibrary(TEXT(DLLNAME)); + if (dll == NULL) { + DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED); + return -1; + } + + create_snap = (CREATETOOLHELP32SNAPSHOT) + GetProcAddress(dll, "CreateToolhelp32Snapshot"); + if (create_snap == NULL) { + FreeLibrary(dll); + DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED); + return -1; + } + /* We take the rest for granted... */ +# ifdef _WIN32_WCE + close_snap = (CLOSETOOLHELP32SNAPSHOT) + GetProcAddress(dll, "CloseToolhelp32Snapshot"); +# else + close_snap = (CLOSETOOLHELP32SNAPSHOT) CloseHandle; +# endif + module_first = (MODULE32) GetProcAddress(dll, "Module32First"); + module_next = (MODULE32) GetProcAddress(dll, "Module32Next"); + + hModuleSnap = (*create_snap) (TH32CS_SNAPMODULE, 0); + if (hModuleSnap == INVALID_HANDLE_VALUE) { + FreeLibrary(dll); + DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_UNSUPPORTED); + return -1; + } + + me32.dwSize = sizeof(me32); + + if (!(*module_first) (hModuleSnap, &me32)) { + (*close_snap) (hModuleSnap); + FreeLibrary(dll); + DSOerr(DSO_F_WIN32_PATHBYADDR, DSO_R_FAILURE); + return -1; + } + + do { + if ((BYTE *) addr >= me32.modBaseAddr && + (BYTE *) addr < me32.modBaseAddr + me32.modBaseSize) { + (*close_snap) (hModuleSnap); + FreeLibrary(dll); +# ifdef _WIN32_WCE +# if _WIN32_WCE >= 101 + return WideCharToMultiByte(CP_ACP, 0, me32.szExePath, -1, + path, sz, NULL, NULL); +# else + len = (int)wcslen(me32.szExePath); + if (sz <= 0) + return len + 1; + if (len >= sz) + len = sz - 1; + for (i = 0; i < len; i++) + path[i] = (char)me32.szExePath[i]; + path[len++] = 0; + return len; +# endif +# else + len = (int)strlen(me32.szExePath); + if (sz <= 0) + return len + 1; + if (len >= sz) + len = sz - 1; + memcpy(path, me32.szExePath, len); + path[len++] = 0; + return len; +# endif + } + } while ((*module_next) (hModuleSnap, &me32)); + + (*close_snap) (hModuleSnap); + FreeLibrary(dll); + return 0; +} + +static void *win32_globallookup(const char *name) +{ + HMODULE dll; + HANDLE hModuleSnap = INVALID_HANDLE_VALUE; + MODULEENTRY32 me32; + CREATETOOLHELP32SNAPSHOT create_snap; + CLOSETOOLHELP32SNAPSHOT close_snap; + MODULE32 module_first, module_next; + FARPROC ret = NULL; + + dll = LoadLibrary(TEXT(DLLNAME)); + if (dll == NULL) { + DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED); + return NULL; + } + + create_snap = (CREATETOOLHELP32SNAPSHOT) + GetProcAddress(dll, "CreateToolhelp32Snapshot"); + if (create_snap == NULL) { + FreeLibrary(dll); + DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED); + return NULL; + } + /* We take the rest for granted... */ +# ifdef _WIN32_WCE + close_snap = (CLOSETOOLHELP32SNAPSHOT) + GetProcAddress(dll, "CloseToolhelp32Snapshot"); +# else + close_snap = (CLOSETOOLHELP32SNAPSHOT) CloseHandle; +# endif + module_first = (MODULE32) GetProcAddress(dll, "Module32First"); + module_next = (MODULE32) GetProcAddress(dll, "Module32Next"); + + hModuleSnap = (*create_snap) (TH32CS_SNAPMODULE, 0); + if (hModuleSnap == INVALID_HANDLE_VALUE) { + FreeLibrary(dll); + DSOerr(DSO_F_WIN32_GLOBALLOOKUP, DSO_R_UNSUPPORTED); + return NULL; + } + + me32.dwSize = sizeof(me32); + + if (!(*module_first) (hModuleSnap, &me32)) { + (*close_snap) (hModuleSnap); + FreeLibrary(dll); + return NULL; + } + + do { + if ((ret = GetProcAddress(me32.hModule, name))) { + (*close_snap) (hModuleSnap); + FreeLibrary(dll); + return ret; + } + } while ((*module_next) (hModuleSnap, &me32)); + + (*close_snap) (hModuleSnap); + FreeLibrary(dll); + return NULL; +} +#endif /* DSO_WIN32 */ diff --git a/libs/openssl/crypto/ebcdic.c b/libs/openssl/crypto/ebcdic.c new file mode 100644 index 00000000..4b7652c0 --- /dev/null +++ b/libs/openssl/crypto/ebcdic.c @@ -0,0 +1,284 @@ +/* crypto/ebcdic.c */ + +#ifndef CHARSET_EBCDIC + +# include +# if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX) +static void *dummy = &dummy; +# endif + +#else /* CHARSET_EBCDIC */ + +# include "ebcdic.h" +/*- + * Initial Port for Apache-1.3 by + * Adapted for OpenSSL-0.9.4 by + */ + +# ifdef _OSD_POSIX +/* + * "BS2000 OSD" is a POSIX subsystem on a main frame. It is made by Siemens + * AG, Germany, for their BS2000 mainframe machines. Within the POSIX + * subsystem, the same character set was chosen as in "native BS2000", namely + * EBCDIC. (EDF04) + * + * The name "ASCII" in these routines is misleading: actually, conversion is + * not between EBCDIC and ASCII, but EBCDIC(EDF04) and ISO-8859.1; that means + * that (western european) national characters are preserved. + * + * This table is identical to the one used by rsh/rcp/ftp and other POSIX + * tools. + */ + +/* Here's the bijective ebcdic-to-ascii table: */ +const unsigned char os_toascii[256] = { + /* + * 00 + */ 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, + 0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ + /* + * 10 + */ 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, + 0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ + /* + * 20 + */ 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */ + /* + * 30 + */ 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, + 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */ + /* + * 40 + */ 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, + 0xe7, 0xf1, 0x60, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* .........`.<(+| */ + /* + * 50 + */ 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, + 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x9f, /* &.........!$*);. */ + /* + * 60 + */ 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, + 0xc7, 0xd1, 0x5e, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /*-/........^,%_>?*/ + /* + * 70 + */ 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, + 0xcc, 0xa8, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* ..........:#@'=" */ + /* + * 80 + */ 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, + 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */ + /* + * 90 + */ 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, + 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */ + /* + * a0 + */ 0xb5, 0xaf, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0xdd, 0xde, 0xae, /* ..stuvwxyz...... */ + /* + * b0 + */ 0xa2, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, + 0xbd, 0xbe, 0xac, 0x5b, 0x5c, 0x5d, 0xb4, 0xd7, /* ...........[\].. */ + /* + * c0 + */ 0xf9, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, + 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* .ABCDEFGHI...... */ + /* + * d0 + */ 0xa6, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, + 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xdb, 0xfa, 0xff, /* .JKLMNOPQR...... */ + /* + * e0 + */ 0xd9, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, + 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* ..STUVWXYZ...... */ + /* + * f0 + */ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, + 0x38, 0x39, 0xb3, 0x7b, 0xdc, 0x7d, 0xda, 0x7e /* 0123456789.{.}.~ */ +}; + +/* The ascii-to-ebcdic table: */ +const unsigned char os_toebcdic[256] = { + /* + * 00 + */ 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, + 0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ + /* + * 10 + */ 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, + 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ + /* + * 20 + */ 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, + 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */ + /* + * 30 + */ 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, + 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */ + /* + * 40 + */ 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, + 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */ + /* + * 50 + */ 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, + 0xe7, 0xe8, 0xe9, 0xbb, 0xbc, 0xbd, 0x6a, 0x6d, /* PQRSTUVWXYZ[\]^_ */ + /* + * 60 + */ 0x4a, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */ + /* + * 70 + */ 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, + 0xa7, 0xa8, 0xa9, 0xfb, 0x4f, 0xfd, 0xff, 0x07, /* pqrstuvwxyz{|}~. */ + /* + * 80 + */ 0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08, + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */ + /* + * 90 + */ 0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17, + 0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0x5f, /* ................ */ + /* + * a0 + */ 0x41, 0xaa, 0xb0, 0xb1, 0x9f, 0xb2, 0xd0, 0xb5, + 0x79, 0xb4, 0x9a, 0x8a, 0xba, 0xca, 0xaf, 0xa1, /* ................ */ + /* + * b0 + */ 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, + 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */ + /* + * c0 + */ 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, + 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */ + /* + * d0 + */ 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, + 0x80, 0xe0, 0xfe, 0xdd, 0xfc, 0xad, 0xae, 0x59, /* ................ */ + /* + * e0 + */ 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, + 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */ + /* + * f0 + */ 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, + 0x70, 0xc0, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /* ................ */ +}; + +# else /*_OSD_POSIX*/ + +/* + * This code does basic character mapping for IBM's TPF and OS/390 operating + * systems. It is a modified version of the BS2000 table. + * + * Bijective EBCDIC (character set IBM-1047) to US-ASCII table: This table is + * bijective - there are no ambigous or duplicate characters. + */ +const unsigned char os_toascii[256] = { + 0x00, 0x01, 0x02, 0x03, 0x85, 0x09, 0x86, 0x7f, /* 00-0f: */ + 0x87, 0x8d, 0x8e, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ + 0x10, 0x11, 0x12, 0x13, 0x8f, 0x0a, 0x08, 0x97, /* 10-1f: */ + 0x18, 0x19, 0x9c, 0x9d, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ + 0x80, 0x81, 0x82, 0x83, 0x84, 0x92, 0x17, 0x1b, /* 20-2f: */ + 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x05, 0x06, 0x07, /* ................ */ + 0x90, 0x91, 0x16, 0x93, 0x94, 0x95, 0x96, 0x04, /* 30-3f: */ + 0x98, 0x99, 0x9a, 0x9b, 0x14, 0x15, 0x9e, 0x1a, /* ................ */ + 0x20, 0xa0, 0xe2, 0xe4, 0xe0, 0xe1, 0xe3, 0xe5, /* 40-4f: */ + 0xe7, 0xf1, 0xa2, 0x2e, 0x3c, 0x28, 0x2b, 0x7c, /* ...........<(+| */ + 0x26, 0xe9, 0xea, 0xeb, 0xe8, 0xed, 0xee, 0xef, /* 50-5f: */ + 0xec, 0xdf, 0x21, 0x24, 0x2a, 0x29, 0x3b, 0x5e, /* &.........!$*);^ */ + 0x2d, 0x2f, 0xc2, 0xc4, 0xc0, 0xc1, 0xc3, 0xc5, /* 60-6f: */ + 0xc7, 0xd1, 0xa6, 0x2c, 0x25, 0x5f, 0x3e, 0x3f, /* -/.........,%_>? */ + 0xf8, 0xc9, 0xca, 0xcb, 0xc8, 0xcd, 0xce, 0xcf, /* 70-7f: */ + 0xcc, 0x60, 0x3a, 0x23, 0x40, 0x27, 0x3d, 0x22, /* .........`:#@'=" */ + 0xd8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, /* 80-8f: */ + 0x68, 0x69, 0xab, 0xbb, 0xf0, 0xfd, 0xfe, 0xb1, /* .abcdefghi...... */ + 0xb0, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x70, /* 90-9f: */ + 0x71, 0x72, 0xaa, 0xba, 0xe6, 0xb8, 0xc6, 0xa4, /* .jklmnopqr...... */ + 0xb5, 0x7e, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, /* a0-af: */ + 0x79, 0x7a, 0xa1, 0xbf, 0xd0, 0x5b, 0xde, 0xae, /* .~stuvwxyz...[.. */ + 0xac, 0xa3, 0xa5, 0xb7, 0xa9, 0xa7, 0xb6, 0xbc, /* b0-bf: */ + 0xbd, 0xbe, 0xdd, 0xa8, 0xaf, 0x5d, 0xb4, 0xd7, /* .............].. */ + 0x7b, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, /* c0-cf: */ + 0x48, 0x49, 0xad, 0xf4, 0xf6, 0xf2, 0xf3, 0xf5, /* {ABCDEFGHI...... */ + 0x7d, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, 0x50, /* d0-df: */ + 0x51, 0x52, 0xb9, 0xfb, 0xfc, 0xf9, 0xfa, 0xff, /* }JKLMNOPQR...... */ + 0x5c, 0xf7, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, /* e0-ef: */ + 0x59, 0x5a, 0xb2, 0xd4, 0xd6, 0xd2, 0xd3, 0xd5, /* \.STUVWXYZ...... */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, /* f0-ff: */ + 0x38, 0x39, 0xb3, 0xdb, 0xdc, 0xd9, 0xda, 0x9f /* 0123456789...... */ +}; + +/* + * The US-ASCII to EBCDIC (character set IBM-1047) table: This table is + * bijective (no ambiguous or duplicate characters) + */ +const unsigned char os_toebcdic[256] = { + 0x00, 0x01, 0x02, 0x03, 0x37, 0x2d, 0x2e, 0x2f, /* 00-0f: */ + 0x16, 0x05, 0x15, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* ................ */ + 0x10, 0x11, 0x12, 0x13, 0x3c, 0x3d, 0x32, 0x26, /* 10-1f: */ + 0x18, 0x19, 0x3f, 0x27, 0x1c, 0x1d, 0x1e, 0x1f, /* ................ */ + 0x40, 0x5a, 0x7f, 0x7b, 0x5b, 0x6c, 0x50, 0x7d, /* 20-2f: */ + 0x4d, 0x5d, 0x5c, 0x4e, 0x6b, 0x60, 0x4b, 0x61, /* !"#$%&'()*+,-./ */ + 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, /* 30-3f: */ + 0xf8, 0xf9, 0x7a, 0x5e, 0x4c, 0x7e, 0x6e, 0x6f, /* 0123456789:;<=>? */ + 0x7c, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, /* 40-4f: */ + 0xc8, 0xc9, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, /* @ABCDEFGHIJKLMNO */ + 0xd7, 0xd8, 0xd9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, /* 50-5f: */ + 0xe7, 0xe8, 0xe9, 0xad, 0xe0, 0xbd, 0x5f, 0x6d, /* PQRSTUVWXYZ[\]^_ */ + 0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, /* 60-6f: */ + 0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, /* `abcdefghijklmno */ + 0x97, 0x98, 0x99, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, /* 70-7f: */ + 0xa7, 0xa8, 0xa9, 0xc0, 0x4f, 0xd0, 0xa1, 0x07, /* pqrstuvwxyz{|}~. */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x04, 0x06, 0x08, /* 80-8f: */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x09, 0x0a, 0x14, /* ................ */ + 0x30, 0x31, 0x25, 0x33, 0x34, 0x35, 0x36, 0x17, /* 90-9f: */ + 0x38, 0x39, 0x3a, 0x3b, 0x1a, 0x1b, 0x3e, 0xff, /* ................ */ + 0x41, 0xaa, 0x4a, 0xb1, 0x9f, 0xb2, 0x6a, 0xb5, /* a0-af: */ + 0xbb, 0xb4, 0x9a, 0x8a, 0xb0, 0xca, 0xaf, 0xbc, /* ................ */ + 0x90, 0x8f, 0xea, 0xfa, 0xbe, 0xa0, 0xb6, 0xb3, /* b0-bf: */ + 0x9d, 0xda, 0x9b, 0x8b, 0xb7, 0xb8, 0xb9, 0xab, /* ................ */ + 0x64, 0x65, 0x62, 0x66, 0x63, 0x67, 0x9e, 0x68, /* c0-cf: */ + 0x74, 0x71, 0x72, 0x73, 0x78, 0x75, 0x76, 0x77, /* ................ */ + 0xac, 0x69, 0xed, 0xee, 0xeb, 0xef, 0xec, 0xbf, /* d0-df: */ + 0x80, 0xfd, 0xfe, 0xfb, 0xfc, 0xba, 0xae, 0x59, /* ................ */ + 0x44, 0x45, 0x42, 0x46, 0x43, 0x47, 0x9c, 0x48, /* e0-ef: */ + 0x54, 0x51, 0x52, 0x53, 0x58, 0x55, 0x56, 0x57, /* ................ */ + 0x8c, 0x49, 0xcd, 0xce, 0xcb, 0xcf, 0xcc, 0xe1, /* f0-ff: */ + 0x70, 0xdd, 0xde, 0xdb, 0xdc, 0x8d, 0x8e, 0xdf /* ................ */ +}; +# endif/*_OSD_POSIX*/ + +/* + * Translate a memory block from EBCDIC (host charset) to ASCII (net charset) + * dest and srce may be identical, or separate memory blocks, but should not + * overlap. These functions intentionally have an interface compatible to + * memcpy(3). + */ + +void *ebcdic2ascii(void *dest, const void *srce, size_t count) +{ + unsigned char *udest = dest; + const unsigned char *usrce = srce; + + while (count-- != 0) { + *udest++ = os_toascii[*usrce++]; + } + + return dest; +} + +void *ascii2ebcdic(void *dest, const void *srce, size_t count) +{ + unsigned char *udest = dest; + const unsigned char *usrce = srce; + + while (count-- != 0) { + *udest++ = os_toebcdic[*usrce++]; + } + + return dest; +} + +#endif diff --git a/libs/openssl/crypto/ebcdic.h b/libs/openssl/crypto/ebcdic.h new file mode 100644 index 00000000..4cbdfeb7 --- /dev/null +++ b/libs/openssl/crypto/ebcdic.h @@ -0,0 +1,26 @@ +/* crypto/ebcdic.h */ + +#ifndef HEADER_EBCDIC_H +# define HEADER_EBCDIC_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Avoid name clashes with other applications */ +# define os_toascii _openssl_os_toascii +# define os_toebcdic _openssl_os_toebcdic +# define ebcdic2ascii _openssl_ebcdic2ascii +# define ascii2ebcdic _openssl_ascii2ebcdic + +extern const unsigned char os_toascii[256]; +extern const unsigned char os_toebcdic[256]; +void *ebcdic2ascii(void *dest, const void *srce, size_t count); +void *ascii2ebcdic(void *dest, const void *srce, size_t count); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/ec/ec.h b/libs/openssl/crypto/ec/ec.h new file mode 100644 index 00000000..2a935fdb --- /dev/null +++ b/libs/openssl/crypto/ec/ec.h @@ -0,0 +1,1193 @@ +/* crypto/ec/ec.h */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/** + * \file crypto/ec/ec.h Include file for the OpenSSL EC functions + * \author Originally written by Bodo Moeller for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#ifndef HEADER_EC_H +# define HEADER_EC_H + +# include + +# ifdef OPENSSL_NO_EC +# error EC is disabled. +# endif + +# include +# include +# ifndef OPENSSL_NO_DEPRECATED +# include +# endif + +# ifdef __cplusplus +extern "C" { +# elif defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +# endif + +# ifndef OPENSSL_ECC_MAX_FIELD_BITS +# define OPENSSL_ECC_MAX_FIELD_BITS 661 +# endif + +/** Enum for the point conversion form as defined in X9.62 (ECDSA) + * for the encoding of a elliptic curve point (x,y) */ +typedef enum { + /** the point is encoded as z||x, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_COMPRESSED = 2, + /** the point is encoded as z||x||y, where z is the octet 0x04 */ + POINT_CONVERSION_UNCOMPRESSED = 4, + /** the point is encoded as z||x||y, where the octet z specifies + * which solution of the quadratic equation y is */ + POINT_CONVERSION_HYBRID = 6 +} point_conversion_form_t; + +typedef struct ec_method_st EC_METHOD; + +typedef struct ec_group_st + /*- + EC_METHOD *meth; + -- field definition + -- curve coefficients + -- optional generator with associated information (order, cofactor) + -- optional extra data (precomputed table for fast computation of multiples of generator) + -- ASN1 stuff + */ + EC_GROUP; + +typedef struct ec_point_st EC_POINT; + +/********************************************************************/ +/* EC_METHODs for curves over GF(p) */ +/********************************************************************/ + +/** Returns the basic GFp ec methods which provides the basis for the + * optimized methods. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_simple_method(void); + +/** Returns GFp methods using montgomery multiplication. + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_mont_method(void); + +/** Returns GFp methods using optimized methods for NIST recommended curves + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nist_method(void); + +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +/** Returns 64-bit optimized methods for nistp224 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp224_method(void); + +/** Returns 64-bit optimized methods for nistp256 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp256_method(void); + +/** Returns 64-bit optimized methods for nistp521 + * \return EC_METHOD object + */ +const EC_METHOD *EC_GFp_nistp521_method(void); +# endif + +# ifndef OPENSSL_NO_EC2M +/********************************************************************/ +/* EC_METHOD for curves over GF(2^m) */ +/********************************************************************/ + +/** Returns the basic GF2m ec method + * \return EC_METHOD object + */ +const EC_METHOD *EC_GF2m_simple_method(void); + +# endif + +/********************************************************************/ +/* EC_GROUP functions */ +/********************************************************************/ + +/** Creates a new EC_GROUP object + * \param meth EC_METHOD to use + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth); + +/** Frees a EC_GROUP object + * \param group EC_GROUP object to be freed. + */ +void EC_GROUP_free(EC_GROUP *group); + +/** Clears and frees a EC_GROUP object + * \param group EC_GROUP object to be cleared and freed. + */ +void EC_GROUP_clear_free(EC_GROUP *group); + +/** Copies EC_GROUP objects. Note: both EC_GROUPs must use the same EC_METHOD. + * \param dst destination EC_GROUP object + * \param src source EC_GROUP object + * \return 1 on success and 0 if an error occurred. + */ +int EC_GROUP_copy(EC_GROUP *dst, const EC_GROUP *src); + +/** Creates a new EC_GROUP object and copies the copies the content + * form src to the newly created EC_KEY object + * \param src source EC_GROUP object + * \return newly created EC_GROUP object or NULL in case of an error. + */ +EC_GROUP *EC_GROUP_dup(const EC_GROUP *src); + +/** Returns the EC_METHOD of the EC_GROUP object. + * \param group EC_GROUP object + * \return EC_METHOD used in this EC_GROUP object. + */ +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); + +/** Returns the field type of the EC_METHOD. + * \param meth EC_METHOD object + * \return NID of the underlying field type OID. + */ +int EC_METHOD_get_field_type(const EC_METHOD *meth); + +/** Sets the generator and it's order/cofactor of a EC_GROUP object. + * \param group EC_GROUP object + * \param generator EC_POINT object with the generator. + * \param order the order of the group generated by the generator. + * \param cofactor the index of the sub-group generated by the generator + * in the group of all points on the elliptic curve. + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor); + +/** Returns the generator of a EC_GROUP object. + * \param group EC_GROUP object + * \return the currently used generator (possibly NULL). + */ +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); + +/** Gets the order of a EC_GROUP + * \param group EC_GROUP object + * \param order BIGNUM to which the order is copied + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx); + +/** Gets the cofactor of a EC_GROUP + * \param group EC_GROUP object + * \param cofactor BIGNUM to which the cofactor is copied + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, + BN_CTX *ctx); + +/** Sets the name of a EC_GROUP object + * \param group EC_GROUP object + * \param nid NID of the curve name OID + */ +void EC_GROUP_set_curve_name(EC_GROUP *group, int nid); + +/** Returns the curve name of a EC_GROUP object + * \param group EC_GROUP object + * \return NID of the curve name OID or 0 if not set. + */ +int EC_GROUP_get_curve_name(const EC_GROUP *group); + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); +int EC_GROUP_get_asn1_flag(const EC_GROUP *group); + +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, + point_conversion_form_t form); +point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP *); + +unsigned char *EC_GROUP_get0_seed(const EC_GROUP *x); +size_t EC_GROUP_get_seed_len(const EC_GROUP *); +size_t EC_GROUP_set_seed(EC_GROUP *, const unsigned char *, size_t len); + +/** Sets the parameter of a ec over GFp defined by y^2 = x^3 + a*x + b + * \param group EC_GROUP object + * \param p BIGNUM with the prime number + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameter of the ec over GFp defined by y^2 = x^3 + a*x + b + * \param group EC_GROUP object + * \param p BIGNUM for the prime number + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx); + +# ifndef OPENSSL_NO_EC2M +/** Sets the parameter of a ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b + * \param group EC_GROUP object + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with parameter a of the equation + * \param b BIGNUM with parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +/** Gets the parameter of the ec over GF2m defined by y^2 + x*y = x^3 + a*x^2 + b + * \param group EC_GROUP object + * \param p BIGNUM for the polynomial defining the underlying field + * \param a BIGNUM for parameter a of the equation + * \param b BIGNUM for parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx); +# endif +/** Returns the number of bits needed to represent a field element + * \param group EC_GROUP object + * \return number of bits needed to represent a field element + */ +int EC_GROUP_get_degree(const EC_GROUP *group); + +/** Checks whether the parameter in the EC_GROUP define a valid ec group + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if group is a valid ec group and 0 otherwise + */ +int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx); + +/** Checks whether the discriminant of the elliptic curve is zero or not + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 if the discriminant is not zero and 0 otherwise + */ +int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx); + +/** Compares two EC_GROUP objects + * \param a first EC_GROUP object + * \param b second EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 0 if both groups are equal and 1 otherwise + */ +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx); + +/* + * EC_GROUP_new_GF*() calls EC_GROUP_new() and EC_GROUP_set_GF*() after + * choosing an appropriate EC_METHOD + */ + +/** Creates a new EC_GROUP object with the specified parameters defined + * over GFp (defined by the equation y^2 = x^3 + a*x + b) + * \param p BIGNUM with the prime number + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +# ifndef OPENSSL_NO_EC2M +/** Creates a new EC_GROUP object with the specified parameters defined + * over GF2m (defined by the equation y^2 + x*y = x^3 + a*x^2 + b) + * \param p BIGNUM with the polynomial defining the underlying field + * \param a BIGNUM with the parameter a of the equation + * \param b BIGNUM with the parameter b of the equation + * \param ctx BN_CTX object (optional) + * \return newly created EC_GROUP object with the specified parameters + */ +EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); +# endif +/** Creates a EC_GROUP object with a curve specified by a NID + * \param nid NID of the OID of the curve name + * \return newly created EC_GROUP object with specified curve or NULL + * if an error occurred + */ +EC_GROUP *EC_GROUP_new_by_curve_name(int nid); + +/********************************************************************/ +/* handling of internal curves */ +/********************************************************************/ + +typedef struct { + int nid; + const char *comment; +} EC_builtin_curve; + +/* + * EC_builtin_curves(EC_builtin_curve *r, size_t size) returns number of all + * available curves or zero if a error occurred. In case r ist not zero + * nitems EC_builtin_curve structures are filled with the data of the first + * nitems internal groups + */ +size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems); + +/********************************************************************/ +/* EC_POINT functions */ +/********************************************************************/ + +/** Creates a new EC_POINT object for the specified EC_GROUP + * \param group EC_GROUP the underlying EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_new(const EC_GROUP *group); + +/** Frees a EC_POINT object + * \param point EC_POINT object to be freed + */ +void EC_POINT_free(EC_POINT *point); + +/** Clears and frees a EC_POINT object + * \param point EC_POINT object to be cleared and freed + */ +void EC_POINT_clear_free(EC_POINT *point); + +/** Copies EC_POINT object + * \param dst destination EC_POINT object + * \param src source EC_POINT object + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_copy(EC_POINT *dst, const EC_POINT *src); + +/** Creates a new EC_POINT object and copies the content of the supplied + * EC_POINT + * \param src source EC_POINT object + * \param group underlying the EC_GROUP object + * \return newly created EC_POINT object or NULL if an error occurred + */ +EC_POINT *EC_POINT_dup(const EC_POINT *src, const EC_GROUP *group); + +/** Returns the EC_METHOD used in EC_POINT object + * \param point EC_POINT object + * \return the EC_METHOD used + */ +const EC_METHOD *EC_POINT_method_of(const EC_POINT *point); + +/** Sets a point to infinity (neutral element) + * \param group underlying EC_GROUP object + * \param point EC_POINT to set to infinity + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point); + +/** Sets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param z BIGNUM with the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, const BIGNUM *x, + const BIGNUM *y, const BIGNUM *z, + BN_CTX *ctx); + +/** Gets the jacobian projective coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param z BIGNUM for the z-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, + BIGNUM *y, BIGNUM *z, + BN_CTX *ctx); + +/** Sets the affine coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *ctx); + +/** Gets the affine coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, + BIGNUM *y, BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT over GFp + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, + EC_POINT *p, const BIGNUM *x, + int y_bit, BN_CTX *ctx); +# ifndef OPENSSL_NO_EC2M +/** Sets the affine coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with the x-coordinate + * \param y BIGNUM with the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, EC_POINT *p, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *ctx); + +/** Gets the affine coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM for the x-coordinate + * \param y BIGNUM for the y-coordinate + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, + const EC_POINT *p, BIGNUM *x, + BIGNUM *y, BN_CTX *ctx); + +/** Sets the x9.62 compressed coordinates of a EC_POINT over GF2m + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param x BIGNUM with x-coordinate + * \param y_bit integer with the y-Bit (either 0 or 1) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, + EC_POINT *p, const BIGNUM *x, + int y_bit, BN_CTX *ctx); +# endif +/** Encodes a EC_POINT object to a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param form point conversion form + * \param buf memory buffer for the result. If NULL the function returns + * required buffer size. + * \param len length of the memory buffer + * \param ctx BN_CTX object (optional) + * \return the length of the encoded octet string or 0 if an error occurred + */ +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *p, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx); + +/** Decodes a EC_POINT from a octet string + * \param group underlying EC_GROUP object + * \param p EC_POINT object + * \param buf memory buffer with the encoded ec point + * \param len length of the encoded ec point + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *p, + const unsigned char *buf, size_t len, BN_CTX *ctx); + +/* other interfaces to point2oct/oct2point: */ +BIGNUM *EC_POINT_point2bn(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BIGNUM *, BN_CTX *); +EC_POINT *EC_POINT_bn2point(const EC_GROUP *, const BIGNUM *, + EC_POINT *, BN_CTX *); +char *EC_POINT_point2hex(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, BN_CTX *); +EC_POINT *EC_POINT_hex2point(const EC_GROUP *, const char *, + EC_POINT *, BN_CTX *); + +/********************************************************************/ +/* functions for doing EC_POINT arithmetic */ +/********************************************************************/ + +/** Computes the sum of two EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = a + b) + * \param a EC_POINT object with the first summand + * \param b EC_POINT object with the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx); + +/** Computes the double of a EC_POINT + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result (r = 2 * a) + * \param a EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx); + +/** Computes the inverse of a EC_POINT + * \param group underlying EC_GROUP object + * \param a EC_POINT object to be inverted (it's used for the result as well) + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx); + +/** Checks whether the point is the neutral element of the group + * \param group the underlying EC_GROUP object + * \param p EC_POINT object + * \return 1 if the point is the neutral element and 0 otherwise + */ +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *p); + +/** Checks whether the point is on the curve + * \param group underlying EC_GROUP object + * \param point EC_POINT object to check + * \param ctx BN_CTX object (optional) + * \return 1 if point if on the curve and 0 otherwise + */ +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx); + +/** Compares two EC_POINTs + * \param group underlying EC_GROUP object + * \param a first EC_POINT object + * \param b second EC_POINT object + * \param ctx BN_CTX object (optional) + * \return 0 if both points are equal and a value != 0 otherwise + */ +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, + BN_CTX *ctx); + +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx); +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx); + +/** Computes r = generator * n sum_{i=0}^{num-1} p[i] * m[i] + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param num number futher summands + * \param p array of size num of EC_POINT objects + * \param m array of size num of BIGNUM objects + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + size_t num, const EC_POINT *p[], const BIGNUM *m[], + BN_CTX *ctx); + +/** Computes r = generator * n + q * m + * \param group underlying EC_GROUP object + * \param r EC_POINT object for the result + * \param n BIGNUM with the multiplier for the group generator (optional) + * \param q EC_POINT object with the first factor of the second summand + * \param m BIGNUM with the second factor of the second summand + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *n, + const EC_POINT *q, const BIGNUM *m, BN_CTX *ctx); + +/** Stores multiples of generator for faster point multiplication + * \param group EC_GROUP object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occured + */ +int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx); + +/** Reports whether a precomputation has been done + * \param group EC_GROUP object + * \return 1 if a pre-computation has been done and 0 otherwise + */ +int EC_GROUP_have_precompute_mult(const EC_GROUP *group); + +/********************************************************************/ +/* ASN1 stuff */ +/********************************************************************/ + +/* + * EC_GROUP_get_basis_type() returns the NID of the basis type used to + * represent the field elements + */ +int EC_GROUP_get_basis_type(const EC_GROUP *); +# ifndef OPENSSL_NO_EC2M +int EC_GROUP_get_trinomial_basis(const EC_GROUP *, unsigned int *k); +int EC_GROUP_get_pentanomial_basis(const EC_GROUP *, unsigned int *k1, + unsigned int *k2, unsigned int *k3); +# endif + +# define OPENSSL_EC_NAMED_CURVE 0x001 + +typedef struct ecpk_parameters_st ECPKPARAMETERS; + +EC_GROUP *d2i_ECPKParameters(EC_GROUP **, const unsigned char **in, long len); +int i2d_ECPKParameters(const EC_GROUP *, unsigned char **out); + +# define d2i_ECPKParameters_bio(bp,x) ASN1_d2i_bio_of(EC_GROUP,NULL,d2i_ECPKParameters,bp,x) +# define i2d_ECPKParameters_bio(bp,x) ASN1_i2d_bio_of_const(EC_GROUP,i2d_ECPKParameters,bp,x) +# define d2i_ECPKParameters_fp(fp,x) (EC_GROUP *)ASN1_d2i_fp(NULL, \ + (char *(*)())d2i_ECPKParameters,(fp),(unsigned char **)(x)) +# define i2d_ECPKParameters_fp(fp,x) ASN1_i2d_fp(i2d_ECPKParameters,(fp), \ + (unsigned char *)(x)) + +# ifndef OPENSSL_NO_BIO +int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off); +# endif +# ifndef OPENSSL_NO_FP_API +int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off); +# endif + +/********************************************************************/ +/* EC_KEY functions */ +/********************************************************************/ + +typedef struct ec_key_st EC_KEY; + +/* some values for the encoding_flag */ +# define EC_PKEY_NO_PARAMETERS 0x001 +# define EC_PKEY_NO_PUBKEY 0x002 + +/* some values for the flags field */ +# define EC_FLAG_NON_FIPS_ALLOW 0x1 +# define EC_FLAG_FIPS_CHECKED 0x2 + +/** Creates a new EC_KEY object. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new(void); + +int EC_KEY_get_flags(const EC_KEY *key); + +void EC_KEY_set_flags(EC_KEY *key, int flags); + +void EC_KEY_clear_flags(EC_KEY *key, int flags); + +/** Creates a new EC_KEY object using a named curve as underlying + * EC_GROUP object. + * \param nid NID of the named curve. + * \return EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_new_by_curve_name(int nid); + +/** Frees a EC_KEY object. + * \param key EC_KEY object to be freed. + */ +void EC_KEY_free(EC_KEY *key); + +/** Copies a EC_KEY object. + * \param dst destination EC_KEY object + * \param src src EC_KEY object + * \return dst or NULL if an error occurred. + */ +EC_KEY *EC_KEY_copy(EC_KEY *dst, const EC_KEY *src); + +/** Creates a new EC_KEY object and copies the content from src to it. + * \param src the source EC_KEY object + * \return newly created EC_KEY object or NULL if an error occurred. + */ +EC_KEY *EC_KEY_dup(const EC_KEY *src); + +/** Increases the internal reference count of a EC_KEY object. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_up_ref(EC_KEY *key); + +/** Returns the EC_GROUP object of a EC_KEY object + * \param key EC_KEY object + * \return the EC_GROUP object (possibly NULL). + */ +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); + +/** Sets the EC_GROUP of a EC_KEY object. + * \param key EC_KEY object + * \param group EC_GROUP to use in the EC_KEY object (note: the EC_KEY + * object will use an own copy of the EC_GROUP). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); + +/** Returns the private key of a EC_KEY object. + * \param key EC_KEY object + * \return a BIGNUM with the private key (possibly NULL). + */ +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); + +/** Sets the private key of a EC_KEY object. + * \param key EC_KEY object + * \param prv BIGNUM with the private key (note: the EC_KEY object + * will use an own copy of the BIGNUM). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); + +/** Returns the public key of a EC_KEY object. + * \param key the EC_KEY object + * \return a EC_POINT object with the public key (possibly NULL) + */ +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); + +/** Sets the public key of a EC_KEY object. + * \param key EC_KEY object + * \param pub EC_POINT object with the public key (note: the EC_KEY object + * will use an own copy of the EC_POINT object). + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); + +unsigned EC_KEY_get_enc_flags(const EC_KEY *key); +void EC_KEY_set_enc_flags(EC_KEY *eckey, unsigned int flags); +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); +void EC_KEY_set_conv_form(EC_KEY *eckey, point_conversion_form_t cform); +/* functions to set/get method specific data */ +void *EC_KEY_get_key_method_data(EC_KEY *key, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)); +/** Sets the key method data of an EC_KEY object, if none has yet been set. + * \param key EC_KEY object + * \param data opaque data to install. + * \param dup_func a function that duplicates |data|. + * \param free_func a function that frees |data|. + * \param clear_free_func a function that wipes and frees |data|. + * \return the previously set data pointer, or NULL if |data| was inserted. + */ +void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)); +/* wrapper functions for the underlying EC_GROUP object */ +void EC_KEY_set_asn1_flag(EC_KEY *eckey, int asn1_flag); + +/** Creates a table of pre-computed multiples of the generator to + * accelerate further EC_KEY operations. + * \param key EC_KEY object + * \param ctx BN_CTX object (optional) + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx); + +/** Creates a new ec private (and optional a new public) key. + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred. + */ +int EC_KEY_generate_key(EC_KEY *key); + +/** Verifies that a private and/or public key is valid. + * \param key the EC_KEY object + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_check_key(const EC_KEY *key); + +/** Sets a public key from affine coordindates performing + * neccessary NIST PKV tests. + * \param key the EC_KEY object + * \param x public key x coordinate + * \param y public key y coordinate + * \return 1 on success and 0 otherwise. + */ +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, + BIGNUM *y); + +/********************************************************************/ +/* de- and encoding functions for SEC1 ECPrivateKey */ +/********************************************************************/ + +/** Decodes a private key from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded private key + * \param len length of the DER encoded private key + * \return the decoded private key or NULL if an error occurred. + */ +EC_KEY *d2i_ECPrivateKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a private key object and stores the result in a buffer. + * \param key the EC_KEY object to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECPrivateKey(EC_KEY *key, unsigned char **out); + +/********************************************************************/ +/* de- and encoding functions for EC parameters */ +/********************************************************************/ + +/** Decodes ec parameter from a memory buffer. + * \param key a pointer to a EC_KEY object which should be used (or NULL) + * \param in pointer to memory with the DER encoded ec parameters + * \param len length of the DER encoded ec parameters + * \return a EC_KEY object with the decoded parameters or NULL if an error + * occurred. + */ +EC_KEY *d2i_ECParameters(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes ec parameter and stores the result in a buffer. + * \param key the EC_KEY object with ec paramters to encode + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred. + */ +int i2d_ECParameters(EC_KEY *key, unsigned char **out); + +/********************************************************************/ +/* de- and encoding functions for EC public key */ +/* (octet string, not DER -- hence 'o2i' and 'i2o') */ +/********************************************************************/ + +/** Decodes a ec public key from a octet string. + * \param key a pointer to a EC_KEY object which should be used + * \param in memory buffer with the encoded public key + * \param len length of the encoded public key + * \return EC_KEY object with decoded public key or NULL if an error + * occurred. + */ +EC_KEY *o2i_ECPublicKey(EC_KEY **key, const unsigned char **in, long len); + +/** Encodes a ec public key in an octet string. + * \param key the EC_KEY object with the public key + * \param out the buffer for the result (if NULL the function returns number + * of bytes needed). + * \return 1 on success and 0 if an error occurred + */ +int i2o_ECPublicKey(EC_KEY *key, unsigned char **out); + +# ifndef OPENSSL_NO_BIO +/** Prints out the ec parameters on human readable form. + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print(BIO *bp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param bp BIO object to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print(BIO *bp, const EC_KEY *key, int off); + +# endif +# ifndef OPENSSL_NO_FP_API +/** Prints out the ec parameters on human readable form. + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \return 1 on success and 0 if an error occurred + */ +int ECParameters_print_fp(FILE *fp, const EC_KEY *key); + +/** Prints out the contents of a EC_KEY object + * \param fp file descriptor to which the information is printed + * \param key EC_KEY object + * \param off line offset + * \return 1 on success and 0 if an error occurred + */ +int EC_KEY_print_fp(FILE *fp, const EC_KEY *key, int off); + +# endif + +# define ECParameters_dup(x) ASN1_dup_of(EC_KEY,i2d_ECParameters,d2i_ECParameters,x) + +# ifndef __cplusplus +# if defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (default,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +# endif +# endif + +# define EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_EC, EVP_PKEY_OP_PARAMGEN, \ + EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID, nid, NULL) + +# define EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID (EVP_PKEY_ALG_CTRL + 1) + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_EC_strings(void); + +/* Error codes for the EC functions. */ + +/* Function codes. */ +# define EC_F_BN_TO_FELEM 224 +# define EC_F_COMPUTE_WNAF 143 +# define EC_F_D2I_ECPARAMETERS 144 +# define EC_F_D2I_ECPKPARAMETERS 145 +# define EC_F_D2I_ECPRIVATEKEY 146 +# define EC_F_DO_EC_KEY_PRINT 221 +# define EC_F_ECKEY_PARAM2TYPE 223 +# define EC_F_ECKEY_PARAM_DECODE 212 +# define EC_F_ECKEY_PRIV_DECODE 213 +# define EC_F_ECKEY_PRIV_ENCODE 214 +# define EC_F_ECKEY_PUB_DECODE 215 +# define EC_F_ECKEY_PUB_ENCODE 216 +# define EC_F_ECKEY_TYPE2PARAM 220 +# define EC_F_ECPARAMETERS_PRINT 147 +# define EC_F_ECPARAMETERS_PRINT_FP 148 +# define EC_F_ECPKPARAMETERS_PRINT 149 +# define EC_F_ECPKPARAMETERS_PRINT_FP 150 +# define EC_F_ECP_NIST_MOD_192 203 +# define EC_F_ECP_NIST_MOD_224 204 +# define EC_F_ECP_NIST_MOD_256 205 +# define EC_F_ECP_NIST_MOD_521 206 +# define EC_F_EC_ASN1_GROUP2CURVE 153 +# define EC_F_EC_ASN1_GROUP2FIELDID 154 +# define EC_F_EC_ASN1_GROUP2PARAMETERS 155 +# define EC_F_EC_ASN1_GROUP2PKPARAMETERS 156 +# define EC_F_EC_ASN1_PARAMETERS2GROUP 157 +# define EC_F_EC_ASN1_PKPARAMETERS2GROUP 158 +# define EC_F_EC_EX_DATA_SET_DATA 211 +# define EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY 208 +# define EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT 159 +# define EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE 195 +# define EC_F_EC_GF2M_SIMPLE_OCT2POINT 160 +# define EC_F_EC_GF2M_SIMPLE_POINT2OCT 161 +# define EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES 162 +# define EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES 163 +# define EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES 164 +# define EC_F_EC_GFP_MONT_FIELD_DECODE 133 +# define EC_F_EC_GFP_MONT_FIELD_ENCODE 134 +# define EC_F_EC_GFP_MONT_FIELD_MUL 131 +# define EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE 209 +# define EC_F_EC_GFP_MONT_FIELD_SQR 132 +# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE 189 +# define EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP 135 +# define EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE 225 +# define EC_F_EC_GFP_NISTP224_POINTS_MUL 228 +# define EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES 226 +# define EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE 230 +# define EC_F_EC_GFP_NISTP256_POINTS_MUL 231 +# define EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES 232 +# define EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE 233 +# define EC_F_EC_GFP_NISTP521_POINTS_MUL 234 +# define EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES 235 +# define EC_F_EC_GFP_NIST_FIELD_MUL 200 +# define EC_F_EC_GFP_NIST_FIELD_SQR 201 +# define EC_F_EC_GFP_NIST_GROUP_SET_CURVE 202 +# define EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT 165 +# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE 166 +# define EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP 100 +# define EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR 101 +# define EC_F_EC_GFP_SIMPLE_MAKE_AFFINE 102 +# define EC_F_EC_GFP_SIMPLE_OCT2POINT 103 +# define EC_F_EC_GFP_SIMPLE_POINT2OCT 104 +# define EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE 137 +# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES 167 +# define EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP 105 +# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES 168 +# define EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP 128 +# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES 169 +# define EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP 129 +# define EC_F_EC_GROUP_CHECK 170 +# define EC_F_EC_GROUP_CHECK_DISCRIMINANT 171 +# define EC_F_EC_GROUP_COPY 106 +# define EC_F_EC_GROUP_GET0_GENERATOR 139 +# define EC_F_EC_GROUP_GET_COFACTOR 140 +# define EC_F_EC_GROUP_GET_CURVE_GF2M 172 +# define EC_F_EC_GROUP_GET_CURVE_GFP 130 +# define EC_F_EC_GROUP_GET_DEGREE 173 +# define EC_F_EC_GROUP_GET_ORDER 141 +# define EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS 193 +# define EC_F_EC_GROUP_GET_TRINOMIAL_BASIS 194 +# define EC_F_EC_GROUP_NEW 108 +# define EC_F_EC_GROUP_NEW_BY_CURVE_NAME 174 +# define EC_F_EC_GROUP_NEW_FROM_DATA 175 +# define EC_F_EC_GROUP_PRECOMPUTE_MULT 142 +# define EC_F_EC_GROUP_SET_CURVE_GF2M 176 +# define EC_F_EC_GROUP_SET_CURVE_GFP 109 +# define EC_F_EC_GROUP_SET_EXTRA_DATA 110 +# define EC_F_EC_GROUP_SET_GENERATOR 111 +# define EC_F_EC_KEY_CHECK_KEY 177 +# define EC_F_EC_KEY_COPY 178 +# define EC_F_EC_KEY_GENERATE_KEY 179 +# define EC_F_EC_KEY_NEW 182 +# define EC_F_EC_KEY_PRINT 180 +# define EC_F_EC_KEY_PRINT_FP 181 +# define EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES 229 +# define EC_F_EC_POINTS_MAKE_AFFINE 136 +# define EC_F_EC_POINT_ADD 112 +# define EC_F_EC_POINT_CMP 113 +# define EC_F_EC_POINT_COPY 114 +# define EC_F_EC_POINT_DBL 115 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M 183 +# define EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP 116 +# define EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP 117 +# define EC_F_EC_POINT_INVERT 210 +# define EC_F_EC_POINT_IS_AT_INFINITY 118 +# define EC_F_EC_POINT_IS_ON_CURVE 119 +# define EC_F_EC_POINT_MAKE_AFFINE 120 +# define EC_F_EC_POINT_MUL 184 +# define EC_F_EC_POINT_NEW 121 +# define EC_F_EC_POINT_OCT2POINT 122 +# define EC_F_EC_POINT_POINT2OCT 123 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M 185 +# define EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP 124 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M 186 +# define EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP 125 +# define EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP 126 +# define EC_F_EC_POINT_SET_TO_INFINITY 127 +# define EC_F_EC_PRE_COMP_DUP 207 +# define EC_F_EC_PRE_COMP_NEW 196 +# define EC_F_EC_WNAF_MUL 187 +# define EC_F_EC_WNAF_PRECOMPUTE_MULT 188 +# define EC_F_I2D_ECPARAMETERS 190 +# define EC_F_I2D_ECPKPARAMETERS 191 +# define EC_F_I2D_ECPRIVATEKEY 192 +# define EC_F_I2O_ECPUBLICKEY 151 +# define EC_F_NISTP224_PRE_COMP_NEW 227 +# define EC_F_NISTP256_PRE_COMP_NEW 236 +# define EC_F_NISTP521_PRE_COMP_NEW 237 +# define EC_F_O2I_ECPUBLICKEY 152 +# define EC_F_OLD_EC_PRIV_DECODE 222 +# define EC_F_PKEY_EC_CTRL 197 +# define EC_F_PKEY_EC_CTRL_STR 198 +# define EC_F_PKEY_EC_DERIVE 217 +# define EC_F_PKEY_EC_KEYGEN 199 +# define EC_F_PKEY_EC_PARAMGEN 219 +# define EC_F_PKEY_EC_SIGN 218 + +/* Reason codes. */ +# define EC_R_ASN1_ERROR 115 +# define EC_R_ASN1_UNKNOWN_FIELD 116 +# define EC_R_BIGNUM_OUT_OF_RANGE 144 +# define EC_R_BUFFER_TOO_SMALL 100 +# define EC_R_COORDINATES_OUT_OF_RANGE 146 +# define EC_R_D2I_ECPKPARAMETERS_FAILURE 117 +# define EC_R_DECODE_ERROR 142 +# define EC_R_DISCRIMINANT_IS_ZERO 118 +# define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 119 +# define EC_R_FIELD_TOO_LARGE 143 +# define EC_R_GF2M_NOT_SUPPORTED 147 +# define EC_R_GROUP2PKPARAMETERS_FAILURE 120 +# define EC_R_I2D_ECPKPARAMETERS_FAILURE 121 +# define EC_R_INCOMPATIBLE_OBJECTS 101 +# define EC_R_INVALID_ARGUMENT 112 +# define EC_R_INVALID_COMPRESSED_POINT 110 +# define EC_R_INVALID_COMPRESSION_BIT 109 +# define EC_R_INVALID_CURVE 141 +# define EC_R_INVALID_DIGEST_TYPE 138 +# define EC_R_INVALID_ENCODING 102 +# define EC_R_INVALID_FIELD 103 +# define EC_R_INVALID_FORM 104 +# define EC_R_INVALID_GROUP_ORDER 122 +# define EC_R_INVALID_PENTANOMIAL_BASIS 132 +# define EC_R_INVALID_PRIVATE_KEY 123 +# define EC_R_INVALID_TRINOMIAL_BASIS 137 +# define EC_R_KEYS_NOT_SET 140 +# define EC_R_MISSING_PARAMETERS 124 +# define EC_R_MISSING_PRIVATE_KEY 125 +# define EC_R_NOT_A_NIST_PRIME 135 +# define EC_R_NOT_A_SUPPORTED_NIST_PRIME 136 +# define EC_R_NOT_IMPLEMENTED 126 +# define EC_R_NOT_INITIALIZED 111 +# define EC_R_NO_FIELD_MOD 133 +# define EC_R_NO_PARAMETERS_SET 139 +# define EC_R_PASSED_NULL_PARAMETER 134 +# define EC_R_PKPARAMETERS2GROUP_FAILURE 127 +# define EC_R_POINT_AT_INFINITY 106 +# define EC_R_POINT_IS_NOT_ON_CURVE 107 +# define EC_R_SLOT_FULL 108 +# define EC_R_UNDEFINED_GENERATOR 113 +# define EC_R_UNDEFINED_ORDER 128 +# define EC_R_UNKNOWN_GROUP 129 +# define EC_R_UNKNOWN_ORDER 114 +# define EC_R_UNSUPPORTED_FIELD 131 +# define EC_R_WRONG_CURVE_PARAMETERS 145 +# define EC_R_WRONG_ORDER 130 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/ec/ec2_mult.c b/libs/openssl/crypto/ec/ec2_mult.c new file mode 100644 index 00000000..68cc8771 --- /dev/null +++ b/libs/openssl/crypto/ec/ec2_mult.c @@ -0,0 +1,463 @@ +/* crypto/ec/ec2_mult.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The software is originally written by Sheueling Chang Shantz and + * Douglas Stebila of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include "ec_lcl.h" + +#ifndef OPENSSL_NO_EC2M + +/*- + * Compute the x-coordinate x/z for the point 2*(x/z) in Montgomery projective + * coordinates. + * Uses algorithm Mdouble in appendix of + * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over + * GF(2^m) without precomputation" (CHES '99, LNCS 1717). + * modified to not require precomputation of c=b^{2^{m-1}}. + */ +static int gf2m_Mdouble(const EC_GROUP *group, BIGNUM *x, BIGNUM *z, + BN_CTX *ctx) +{ + BIGNUM *t1; + int ret = 0; + + /* Since Mdouble is static we can guarantee that ctx != NULL. */ + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + if (t1 == NULL) + goto err; + + if (!group->meth->field_sqr(group, x, x, ctx)) + goto err; + if (!group->meth->field_sqr(group, t1, z, ctx)) + goto err; + if (!group->meth->field_mul(group, z, x, t1, ctx)) + goto err; + if (!group->meth->field_sqr(group, x, x, ctx)) + goto err; + if (!group->meth->field_sqr(group, t1, t1, ctx)) + goto err; + if (!group->meth->field_mul(group, t1, &group->b, t1, ctx)) + goto err; + if (!BN_GF2m_add(x, x, t1)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} + +/*- + * Compute the x-coordinate x1/z1 for the point (x1/z1)+(x2/x2) in Montgomery + * projective coordinates. + * Uses algorithm Madd in appendix of + * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over + * GF(2^m) without precomputation" (CHES '99, LNCS 1717). + */ +static int gf2m_Madd(const EC_GROUP *group, const BIGNUM *x, BIGNUM *x1, + BIGNUM *z1, const BIGNUM *x2, const BIGNUM *z2, + BN_CTX *ctx) +{ + BIGNUM *t1, *t2; + int ret = 0; + + /* Since Madd is static we can guarantee that ctx != NULL. */ + BN_CTX_start(ctx); + t1 = BN_CTX_get(ctx); + t2 = BN_CTX_get(ctx); + if (t2 == NULL) + goto err; + + if (!BN_copy(t1, x)) + goto err; + if (!group->meth->field_mul(group, x1, x1, z2, ctx)) + goto err; + if (!group->meth->field_mul(group, z1, z1, x2, ctx)) + goto err; + if (!group->meth->field_mul(group, t2, x1, z1, ctx)) + goto err; + if (!BN_GF2m_add(z1, z1, x1)) + goto err; + if (!group->meth->field_sqr(group, z1, z1, ctx)) + goto err; + if (!group->meth->field_mul(group, x1, z1, t1, ctx)) + goto err; + if (!BN_GF2m_add(x1, x1, t2)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} + +/*- + * Compute the x, y affine coordinates from the point (x1, z1) (x2, z2) + * using Montgomery point multiplication algorithm Mxy() in appendix of + * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over + * GF(2^m) without precomputation" (CHES '99, LNCS 1717). + * Returns: + * 0 on error + * 1 if return value should be the point at infinity + * 2 otherwise + */ +static int gf2m_Mxy(const EC_GROUP *group, const BIGNUM *x, const BIGNUM *y, + BIGNUM *x1, BIGNUM *z1, BIGNUM *x2, BIGNUM *z2, + BN_CTX *ctx) +{ + BIGNUM *t3, *t4, *t5; + int ret = 0; + + if (BN_is_zero(z1)) { + BN_zero(x2); + BN_zero(z2); + return 1; + } + + if (BN_is_zero(z2)) { + if (!BN_copy(x2, x)) + return 0; + if (!BN_GF2m_add(z2, x, y)) + return 0; + return 2; + } + + /* Since Mxy is static we can guarantee that ctx != NULL. */ + BN_CTX_start(ctx); + t3 = BN_CTX_get(ctx); + t4 = BN_CTX_get(ctx); + t5 = BN_CTX_get(ctx); + if (t5 == NULL) + goto err; + + if (!BN_one(t5)) + goto err; + + if (!group->meth->field_mul(group, t3, z1, z2, ctx)) + goto err; + + if (!group->meth->field_mul(group, z1, z1, x, ctx)) + goto err; + if (!BN_GF2m_add(z1, z1, x1)) + goto err; + if (!group->meth->field_mul(group, z2, z2, x, ctx)) + goto err; + if (!group->meth->field_mul(group, x1, z2, x1, ctx)) + goto err; + if (!BN_GF2m_add(z2, z2, x2)) + goto err; + + if (!group->meth->field_mul(group, z2, z2, z1, ctx)) + goto err; + if (!group->meth->field_sqr(group, t4, x, ctx)) + goto err; + if (!BN_GF2m_add(t4, t4, y)) + goto err; + if (!group->meth->field_mul(group, t4, t4, t3, ctx)) + goto err; + if (!BN_GF2m_add(t4, t4, z2)) + goto err; + + if (!group->meth->field_mul(group, t3, t3, x, ctx)) + goto err; + if (!group->meth->field_div(group, t3, t5, t3, ctx)) + goto err; + if (!group->meth->field_mul(group, t4, t3, t4, ctx)) + goto err; + if (!group->meth->field_mul(group, x2, x1, t3, ctx)) + goto err; + if (!BN_GF2m_add(z2, x2, x)) + goto err; + + if (!group->meth->field_mul(group, z2, z2, t4, ctx)) + goto err; + if (!BN_GF2m_add(z2, z2, y)) + goto err; + + ret = 2; + + err: + BN_CTX_end(ctx); + return ret; +} + +/*- + * Computes scalar*point and stores the result in r. + * point can not equal r. + * Uses a modified algorithm 2P of + * Lopez, J. and Dahab, R. "Fast multiplication on elliptic curves over + * GF(2^m) without precomputation" (CHES '99, LNCS 1717). + * + * To protect against side-channel attack the function uses constant time swap, + * avoiding conditional branches. + */ +static int ec_GF2m_montgomery_point_multiply(const EC_GROUP *group, + EC_POINT *r, + const BIGNUM *scalar, + const EC_POINT *point, + BN_CTX *ctx) +{ + BIGNUM *x1, *x2, *z1, *z2; + int ret = 0, i; + BN_ULONG mask, word; + + if (r == point) { + ECerr(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY, EC_R_INVALID_ARGUMENT); + return 0; + } + + /* if result should be point at infinity */ + if ((scalar == NULL) || BN_is_zero(scalar) || (point == NULL) || + EC_POINT_is_at_infinity(group, point)) { + return EC_POINT_set_to_infinity(group, r); + } + + /* only support affine coordinates */ + if (!point->Z_is_one) + return 0; + + /* + * Since point_multiply is static we can guarantee that ctx != NULL. + */ + BN_CTX_start(ctx); + x1 = BN_CTX_get(ctx); + z1 = BN_CTX_get(ctx); + if (z1 == NULL) + goto err; + + x2 = &r->X; + z2 = &r->Y; + + bn_wexpand(x1, group->field.top); + bn_wexpand(z1, group->field.top); + bn_wexpand(x2, group->field.top); + bn_wexpand(z2, group->field.top); + + if (!BN_GF2m_mod_arr(x1, &point->X, group->poly)) + goto err; /* x1 = x */ + if (!BN_one(z1)) + goto err; /* z1 = 1 */ + if (!group->meth->field_sqr(group, z2, x1, ctx)) + goto err; /* z2 = x1^2 = x^2 */ + if (!group->meth->field_sqr(group, x2, z2, ctx)) + goto err; + if (!BN_GF2m_add(x2, x2, &group->b)) + goto err; /* x2 = x^4 + b */ + + /* find top most bit and go one past it */ + i = scalar->top - 1; + mask = BN_TBIT; + word = scalar->d[i]; + while (!(word & mask)) + mask >>= 1; + mask >>= 1; + /* if top most bit was at word break, go to next word */ + if (!mask) { + i--; + mask = BN_TBIT; + } + + for (; i >= 0; i--) { + word = scalar->d[i]; + while (mask) { + BN_consttime_swap(word & mask, x1, x2, group->field.top); + BN_consttime_swap(word & mask, z1, z2, group->field.top); + if (!gf2m_Madd(group, &point->X, x2, z2, x1, z1, ctx)) + goto err; + if (!gf2m_Mdouble(group, x1, z1, ctx)) + goto err; + BN_consttime_swap(word & mask, x1, x2, group->field.top); + BN_consttime_swap(word & mask, z1, z2, group->field.top); + mask >>= 1; + } + mask = BN_TBIT; + } + + /* convert out of "projective" coordinates */ + i = gf2m_Mxy(group, &point->X, &point->Y, x1, z1, x2, z2, ctx); + if (i == 0) + goto err; + else if (i == 1) { + if (!EC_POINT_set_to_infinity(group, r)) + goto err; + } else { + if (!BN_one(&r->Z)) + goto err; + r->Z_is_one = 1; + } + + /* GF(2^m) field elements should always have BIGNUM::neg = 0 */ + BN_set_negative(&r->X, 0); + BN_set_negative(&r->Y, 0); + + ret = 1; + + err: + BN_CTX_end(ctx); + return ret; +} + +/*- + * Computes the sum + * scalar*group->generator + scalars[0]*points[0] + ... + scalars[num-1]*points[num-1] + * gracefully ignoring NULL scalar values. + */ +int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + int ret = 0; + size_t i; + EC_POINT *p = NULL; + EC_POINT *acc = NULL; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + /* + * This implementation is more efficient than the wNAF implementation for + * 2 or fewer points. Use the ec_wNAF_mul implementation for 3 or more + * points, or if we can perform a fast multiplication based on + * precomputation. + */ + if ((scalar && (num > 1)) || (num > 2) + || (num == 0 && EC_GROUP_have_precompute_mult(group))) { + ret = ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); + goto err; + } + + if ((p = EC_POINT_new(group)) == NULL) + goto err; + if ((acc = EC_POINT_new(group)) == NULL) + goto err; + + if (!EC_POINT_set_to_infinity(group, acc)) + goto err; + + if (scalar) { + if (!ec_GF2m_montgomery_point_multiply + (group, p, scalar, group->generator, ctx)) + goto err; + if (BN_is_negative(scalar)) + if (!group->meth->invert(group, p, ctx)) + goto err; + if (!group->meth->add(group, acc, acc, p, ctx)) + goto err; + } + + for (i = 0; i < num; i++) { + if (!ec_GF2m_montgomery_point_multiply + (group, p, scalars[i], points[i], ctx)) + goto err; + if (BN_is_negative(scalars[i])) + if (!group->meth->invert(group, p, ctx)) + goto err; + if (!group->meth->add(group, acc, acc, p, ctx)) + goto err; + } + + if (!EC_POINT_copy(r, acc)) + goto err; + + ret = 1; + + err: + if (p) + EC_POINT_free(p); + if (acc) + EC_POINT_free(acc); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +/* + * Precomputation for point multiplication: fall back to wNAF methods because + * ec_GF2m_simple_mul() uses ec_wNAF_mul() if appropriate + */ + +int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +{ + return ec_wNAF_precompute_mult(group, ctx); +} + +int ec_GF2m_have_precompute_mult(const EC_GROUP *group) +{ + return ec_wNAF_have_precompute_mult(group); +} + +#endif diff --git a/libs/openssl/crypto/ec/ec2_oct.c b/libs/openssl/crypto/ec/ec2_oct.c new file mode 100644 index 00000000..0d04cc69 --- /dev/null +++ b/libs/openssl/crypto/ec/ec2_oct.c @@ -0,0 +1,403 @@ +/* crypto/ec/ec2_oct.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The software is originally written by Sheueling Chang Shantz and + * Douglas Stebila of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include "ec_lcl.h" + +#ifndef OPENSSL_NO_EC2M + +/*- + * Calculates and sets the affine coordinates of an EC_POINT from the given + * compressed coordinates. Uses algorithm 2.3.4 of SEC 1. + * Note that the simple implementation only uses affine coordinates. + * + * The method is from the following publication: + * + * Harper, Menezes, Vanstone: + * "Public-Key Cryptosystems with Very Small Key Lengths", + * EUROCRYPT '92, Springer-Verlag LNCS 658, + * published February 1993 + * + * US Patents 6,141,420 and 6,618,483 (Vanstone, Mullin, Agnew) describe + * the same method, but claim no priority date earlier than July 29, 1994 + * (and additionally fail to cite the EUROCRYPT '92 publication as prior art). + */ +int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x_, int y_bit, + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BIGNUM *tmp, *x, *y, *z; + int ret = 0, z0; + + /* clear error queue */ + ERR_clear_error(); + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + y_bit = (y_bit != 0) ? 1 : 0; + + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + z = BN_CTX_get(ctx); + if (z == NULL) + goto err; + + if (!BN_GF2m_mod_arr(x, x_, group->poly)) + goto err; + if (BN_is_zero(x)) { + if (!BN_GF2m_mod_sqrt_arr(y, &group->b, group->poly, ctx)) + goto err; + } else { + if (!group->meth->field_sqr(group, tmp, x, ctx)) + goto err; + if (!group->meth->field_div(group, tmp, &group->b, tmp, ctx)) + goto err; + if (!BN_GF2m_add(tmp, &group->a, tmp)) + goto err; + if (!BN_GF2m_add(tmp, x, tmp)) + goto err; + if (!BN_GF2m_mod_solve_quad_arr(z, tmp, group->poly, ctx)) { + unsigned long err = ERR_peek_last_error(); + + if (ERR_GET_LIB(err) == ERR_LIB_BN + && ERR_GET_REASON(err) == BN_R_NO_SOLUTION) { + ERR_clear_error(); + ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, + EC_R_INVALID_COMPRESSED_POINT); + } else + ECerr(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES, + ERR_R_BN_LIB); + goto err; + } + z0 = (BN_is_odd(z)) ? 1 : 0; + if (!group->meth->field_mul(group, y, x, z, ctx)) + goto err; + if (z0 != y_bit) { + if (!BN_GF2m_add(y, y, x)) + goto err; + } + } + + if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +/* + * Converts an EC_POINT to an octet string. If buf is NULL, the encoded + * length will be returned. If the length len of buf is smaller than required + * an error will be returned. + */ +size_t ec_GF2m_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx) +{ + size_t ret; + BN_CTX *new_ctx = NULL; + int used_ctx = 0; + BIGNUM *x, *y, *yxi; + size_t field_len, i, skip; + + if ((form != POINT_CONVERSION_COMPRESSED) + && (form != POINT_CONVERSION_UNCOMPRESSED) + && (form != POINT_CONVERSION_HYBRID)) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_INVALID_FORM); + goto err; + } + + if (EC_POINT_is_at_infinity(group, point)) { + /* encodes to a single 0 octet */ + if (buf != NULL) { + if (len < 1) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); + return 0; + } + buf[0] = 0; + } + return 1; + } + + /* ret := required output buffer length */ + field_len = (EC_GROUP_get_degree(group) + 7) / 8; + ret = + (form == + POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; + + /* if 'buf' is NULL, just return required length */ + if (buf != NULL) { + if (len < ret) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); + goto err; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + used_ctx = 1; + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + yxi = BN_CTX_get(ctx); + if (yxi == NULL) + goto err; + + if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) + goto err; + + buf[0] = form; + if ((form != POINT_CONVERSION_UNCOMPRESSED) && !BN_is_zero(x)) { + if (!group->meth->field_div(group, yxi, y, x, ctx)) + goto err; + if (BN_is_odd(yxi)) + buf[0]++; + } + + i = 1; + + skip = field_len - BN_num_bytes(x); + if (skip > field_len) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + while (skip > 0) { + buf[i++] = 0; + skip--; + } + skip = BN_bn2bin(x, buf + i); + i += skip; + if (i != 1 + field_len) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (form == POINT_CONVERSION_UNCOMPRESSED + || form == POINT_CONVERSION_HYBRID) { + skip = field_len - BN_num_bytes(y); + if (skip > field_len) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + while (skip > 0) { + buf[i++] = 0; + skip--; + } + skip = BN_bn2bin(y, buf + i); + i += skip; + } + + if (i != ret) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (used_ctx) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; + + err: + if (used_ctx) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return 0; +} + +/* + * Converts an octet string representation to an EC_POINT. Note that the + * simple implementation only uses affine coordinates. + */ +int ec_GF2m_simple_oct2point(const EC_GROUP *group, EC_POINT *point, + const unsigned char *buf, size_t len, + BN_CTX *ctx) +{ + point_conversion_form_t form; + int y_bit; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y, *yxi; + size_t field_len, enc_len; + int ret = 0; + + if (len == 0) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL); + return 0; + } + form = buf[0]; + y_bit = form & 1; + form = form & ~1U; + if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) + && (form != POINT_CONVERSION_UNCOMPRESSED) + && (form != POINT_CONVERSION_HYBRID)) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + + if (form == 0) { + if (len != 1) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + + return EC_POINT_set_to_infinity(group, point); + } + + field_len = (EC_GROUP_get_degree(group) + 7) / 8; + enc_len = + (form == + POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; + + if (len != enc_len) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + yxi = BN_CTX_get(ctx); + if (yxi == NULL) + goto err; + + if (!BN_bin2bn(buf + 1, field_len, x)) + goto err; + if (BN_ucmp(x, &group->field) >= 0) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + goto err; + } + + if (form == POINT_CONVERSION_COMPRESSED) { + if (!EC_POINT_set_compressed_coordinates_GF2m + (group, point, x, y_bit, ctx)) + goto err; + } else { + if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) + goto err; + if (BN_ucmp(y, &group->field) >= 0) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + goto err; + } + if (form == POINT_CONVERSION_HYBRID) { + if (!group->meth->field_div(group, yxi, y, x, ctx)) + goto err; + if (y_bit != BN_is_odd(yxi)) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + goto err; + } + } + + if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) + goto err; + } + + /* test required by X9.62 */ + if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} +#endif diff --git a/libs/openssl/crypto/ec/ec2_smpl.c b/libs/openssl/crypto/ec/ec2_smpl.c new file mode 100644 index 00000000..077c7fc8 --- /dev/null +++ b/libs/openssl/crypto/ec/ec2_smpl.c @@ -0,0 +1,797 @@ +/* crypto/ec/ec2_smpl.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The software is originally written by Sheueling Chang Shantz and + * Douglas Stebila of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include "ec_lcl.h" + +#ifndef OPENSSL_NO_EC2M + +# ifdef OPENSSL_FIPS +# include +# endif + +const EC_METHOD *EC_GF2m_simple_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_characteristic_two_field, + ec_GF2m_simple_group_init, + ec_GF2m_simple_group_finish, + ec_GF2m_simple_group_clear_finish, + ec_GF2m_simple_group_copy, + ec_GF2m_simple_group_set_curve, + ec_GF2m_simple_group_get_curve, + ec_GF2m_simple_group_get_degree, + ec_GF2m_simple_group_check_discriminant, + ec_GF2m_simple_point_init, + ec_GF2m_simple_point_finish, + ec_GF2m_simple_point_clear_finish, + ec_GF2m_simple_point_copy, + ec_GF2m_simple_point_set_to_infinity, + 0 /* set_Jprojective_coordinates_GFp */ , + 0 /* get_Jprojective_coordinates_GFp */ , + ec_GF2m_simple_point_set_affine_coordinates, + ec_GF2m_simple_point_get_affine_coordinates, + 0, 0, 0, + ec_GF2m_simple_add, + ec_GF2m_simple_dbl, + ec_GF2m_simple_invert, + ec_GF2m_simple_is_at_infinity, + ec_GF2m_simple_is_on_curve, + ec_GF2m_simple_cmp, + ec_GF2m_simple_make_affine, + ec_GF2m_simple_points_make_affine, + + /* + * the following three method functions are defined in ec2_mult.c + */ + ec_GF2m_simple_mul, + ec_GF2m_precompute_mult, + ec_GF2m_have_precompute_mult, + + ec_GF2m_simple_field_mul, + ec_GF2m_simple_field_sqr, + ec_GF2m_simple_field_div, + 0 /* field_encode */ , + 0 /* field_decode */ , + 0 /* field_set_to_one */ + }; + +# ifdef OPENSSL_FIPS + if (FIPS_mode()) + return fips_ec_gf2m_simple_method(); +# endif + + return &ret; +} + +/* + * Initialize a GF(2^m)-based EC_GROUP structure. Note that all other members + * are handled by EC_GROUP_new. + */ +int ec_GF2m_simple_group_init(EC_GROUP *group) +{ + BN_init(&group->field); + BN_init(&group->a); + BN_init(&group->b); + return 1; +} + +/* + * Free a GF(2^m)-based EC_GROUP structure. Note that all other members are + * handled by EC_GROUP_free. + */ +void ec_GF2m_simple_group_finish(EC_GROUP *group) +{ + BN_free(&group->field); + BN_free(&group->a); + BN_free(&group->b); +} + +/* + * Clear and free a GF(2^m)-based EC_GROUP structure. Note that all other + * members are handled by EC_GROUP_clear_free. + */ +void ec_GF2m_simple_group_clear_finish(EC_GROUP *group) +{ + BN_clear_free(&group->field); + BN_clear_free(&group->a); + BN_clear_free(&group->b); + group->poly[0] = 0; + group->poly[1] = 0; + group->poly[2] = 0; + group->poly[3] = 0; + group->poly[4] = 0; + group->poly[5] = -1; +} + +/* + * Copy a GF(2^m)-based EC_GROUP structure. Note that all other members are + * handled by EC_GROUP_copy. + */ +int ec_GF2m_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) +{ + int i; + if (!BN_copy(&dest->field, &src->field)) + return 0; + if (!BN_copy(&dest->a, &src->a)) + return 0; + if (!BN_copy(&dest->b, &src->b)) + return 0; + dest->poly[0] = src->poly[0]; + dest->poly[1] = src->poly[1]; + dest->poly[2] = src->poly[2]; + dest->poly[3] = src->poly[3]; + dest->poly[4] = src->poly[4]; + dest->poly[5] = src->poly[5]; + if (bn_wexpand(&dest->a, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) + == NULL) + return 0; + if (bn_wexpand(&dest->b, (int)(dest->poly[0] + BN_BITS2 - 1) / BN_BITS2) + == NULL) + return 0; + for (i = dest->a.top; i < dest->a.dmax; i++) + dest->a.d[i] = 0; + for (i = dest->b.top; i < dest->b.dmax; i++) + dest->b.d[i] = 0; + return 1; +} + +/* Set the curve parameters of an EC_GROUP structure. */ +int ec_GF2m_simple_group_set_curve(EC_GROUP *group, + const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + int ret = 0, i; + + /* group->field */ + if (!BN_copy(&group->field, p)) + goto err; + i = BN_GF2m_poly2arr(&group->field, group->poly, 6) - 1; + if ((i != 5) && (i != 3)) { + ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE, EC_R_UNSUPPORTED_FIELD); + goto err; + } + + /* group->a */ + if (!BN_GF2m_mod_arr(&group->a, a, group->poly)) + goto err; + if (bn_wexpand(&group->a, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) + == NULL) + goto err; + for (i = group->a.top; i < group->a.dmax; i++) + group->a.d[i] = 0; + + /* group->b */ + if (!BN_GF2m_mod_arr(&group->b, b, group->poly)) + goto err; + if (bn_wexpand(&group->b, (int)(group->poly[0] + BN_BITS2 - 1) / BN_BITS2) + == NULL) + goto err; + for (i = group->b.top; i < group->b.dmax; i++) + group->b.d[i] = 0; + + ret = 1; + err: + return ret; +} + +/* + * Get the curve parameters of an EC_GROUP structure. If p, a, or b are NULL + * then there values will not be set but the method will return with success. + */ +int ec_GF2m_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, + BIGNUM *a, BIGNUM *b, BN_CTX *ctx) +{ + int ret = 0; + + if (p != NULL) { + if (!BN_copy(p, &group->field)) + return 0; + } + + if (a != NULL) { + if (!BN_copy(a, &group->a)) + goto err; + } + + if (b != NULL) { + if (!BN_copy(b, &group->b)) + goto err; + } + + ret = 1; + + err: + return ret; +} + +/* + * Gets the degree of the field. For a curve over GF(2^m) this is the value + * m. + */ +int ec_GF2m_simple_group_get_degree(const EC_GROUP *group) +{ + return BN_num_bits(&group->field) - 1; +} + +/* + * Checks the discriminant of the curve. y^2 + x*y = x^3 + a*x^2 + b is an + * elliptic curve <=> b != 0 (mod p) + */ +int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *group, + BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *b; + BN_CTX *new_ctx = NULL; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + ECerr(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT, + ERR_R_MALLOC_FAILURE); + goto err; + } + } + BN_CTX_start(ctx); + b = BN_CTX_get(ctx); + if (b == NULL) + goto err; + + if (!BN_GF2m_mod_arr(b, &group->b, group->poly)) + goto err; + + /* + * check the discriminant: y^2 + x*y = x^3 + a*x^2 + b is an elliptic + * curve <=> b != 0 (mod p) + */ + if (BN_is_zero(b)) + goto err; + + ret = 1; + + err: + if (ctx != NULL) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +/* Initializes an EC_POINT. */ +int ec_GF2m_simple_point_init(EC_POINT *point) +{ + BN_init(&point->X); + BN_init(&point->Y); + BN_init(&point->Z); + return 1; +} + +/* Frees an EC_POINT. */ +void ec_GF2m_simple_point_finish(EC_POINT *point) +{ + BN_free(&point->X); + BN_free(&point->Y); + BN_free(&point->Z); +} + +/* Clears and frees an EC_POINT. */ +void ec_GF2m_simple_point_clear_finish(EC_POINT *point) +{ + BN_clear_free(&point->X); + BN_clear_free(&point->Y); + BN_clear_free(&point->Z); + point->Z_is_one = 0; +} + +/* + * Copy the contents of one EC_POINT into another. Assumes dest is + * initialized. + */ +int ec_GF2m_simple_point_copy(EC_POINT *dest, const EC_POINT *src) +{ + if (!BN_copy(&dest->X, &src->X)) + return 0; + if (!BN_copy(&dest->Y, &src->Y)) + return 0; + if (!BN_copy(&dest->Z, &src->Z)) + return 0; + dest->Z_is_one = src->Z_is_one; + + return 1; +} + +/* + * Set an EC_POINT to the point at infinity. A point at infinity is + * represented by having Z=0. + */ +int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *group, + EC_POINT *point) +{ + point->Z_is_one = 0; + BN_zero(&point->Z); + return 1; +} + +/* + * Set the coordinates of an EC_POINT using affine coordinates. Note that + * the simple implementation only uses affine coordinates. + */ +int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) +{ + int ret = 0; + if (x == NULL || y == NULL) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (!BN_copy(&point->X, x)) + goto err; + BN_set_negative(&point->X, 0); + if (!BN_copy(&point->Y, y)) + goto err; + BN_set_negative(&point->Y, 0); + if (!BN_copy(&point->Z, BN_value_one())) + goto err; + BN_set_negative(&point->Z, 0); + point->Z_is_one = 1; + ret = 1; + + err: + return ret; +} + +/* + * Gets the affine coordinates of an EC_POINT. Note that the simple + * implementation only uses affine coordinates. + */ +int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) +{ + int ret = 0; + + if (EC_POINT_is_at_infinity(group, point)) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, + EC_R_POINT_AT_INFINITY); + return 0; + } + + if (BN_cmp(&point->Z, BN_value_one())) { + ECerr(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (x != NULL) { + if (!BN_copy(x, &point->X)) + goto err; + BN_set_negative(x, 0); + } + if (y != NULL) { + if (!BN_copy(y, &point->Y)) + goto err; + BN_set_negative(y, 0); + } + ret = 1; + + err: + return ret; +} + +/* + * Computes a + b and stores the result in r. r could be a or b, a could be + * b. Uses algorithm A.10.2 of IEEE P1363. + */ +int ec_GF2m_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BIGNUM *x0, *y0, *x1, *y1, *x2, *y2, *s, *t; + int ret = 0; + + if (EC_POINT_is_at_infinity(group, a)) { + if (!EC_POINT_copy(r, b)) + return 0; + return 1; + } + + if (EC_POINT_is_at_infinity(group, b)) { + if (!EC_POINT_copy(r, a)) + return 0; + return 1; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + x0 = BN_CTX_get(ctx); + y0 = BN_CTX_get(ctx); + x1 = BN_CTX_get(ctx); + y1 = BN_CTX_get(ctx); + x2 = BN_CTX_get(ctx); + y2 = BN_CTX_get(ctx); + s = BN_CTX_get(ctx); + t = BN_CTX_get(ctx); + if (t == NULL) + goto err; + + if (a->Z_is_one) { + if (!BN_copy(x0, &a->X)) + goto err; + if (!BN_copy(y0, &a->Y)) + goto err; + } else { + if (!EC_POINT_get_affine_coordinates_GF2m(group, a, x0, y0, ctx)) + goto err; + } + if (b->Z_is_one) { + if (!BN_copy(x1, &b->X)) + goto err; + if (!BN_copy(y1, &b->Y)) + goto err; + } else { + if (!EC_POINT_get_affine_coordinates_GF2m(group, b, x1, y1, ctx)) + goto err; + } + + if (BN_GF2m_cmp(x0, x1)) { + if (!BN_GF2m_add(t, x0, x1)) + goto err; + if (!BN_GF2m_add(s, y0, y1)) + goto err; + if (!group->meth->field_div(group, s, s, t, ctx)) + goto err; + if (!group->meth->field_sqr(group, x2, s, ctx)) + goto err; + if (!BN_GF2m_add(x2, x2, &group->a)) + goto err; + if (!BN_GF2m_add(x2, x2, s)) + goto err; + if (!BN_GF2m_add(x2, x2, t)) + goto err; + } else { + if (BN_GF2m_cmp(y0, y1) || BN_is_zero(x1)) { + if (!EC_POINT_set_to_infinity(group, r)) + goto err; + ret = 1; + goto err; + } + if (!group->meth->field_div(group, s, y1, x1, ctx)) + goto err; + if (!BN_GF2m_add(s, s, x1)) + goto err; + + if (!group->meth->field_sqr(group, x2, s, ctx)) + goto err; + if (!BN_GF2m_add(x2, x2, s)) + goto err; + if (!BN_GF2m_add(x2, x2, &group->a)) + goto err; + } + + if (!BN_GF2m_add(y2, x1, x2)) + goto err; + if (!group->meth->field_mul(group, y2, y2, s, ctx)) + goto err; + if (!BN_GF2m_add(y2, y2, x2)) + goto err; + if (!BN_GF2m_add(y2, y2, y1)) + goto err; + + if (!EC_POINT_set_affine_coordinates_GF2m(group, r, x2, y2, ctx)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +/* + * Computes 2 * a and stores the result in r. r could be a. Uses algorithm + * A.10.2 of IEEE P1363. + */ +int ec_GF2m_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx) +{ + return ec_GF2m_simple_add(group, r, a, a, ctx); +} + +int ec_GF2m_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) +{ + if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) + /* point is its own inverse */ + return 1; + + if (!EC_POINT_make_affine(group, point, ctx)) + return 0; + return BN_GF2m_add(&point->Y, &point->X, &point->Y); +} + +/* Indicates whether the given point is the point at infinity. */ +int ec_GF2m_simple_is_at_infinity(const EC_GROUP *group, + const EC_POINT *point) +{ + return BN_is_zero(&point->Z); +} + +/*- + * Determines whether the given EC_POINT is an actual point on the curve defined + * in the EC_GROUP. A point is valid if it satisfies the Weierstrass equation: + * y^2 + x*y = x^3 + a*x^2 + b. + */ +int ec_GF2m_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx) +{ + int ret = -1; + BN_CTX *new_ctx = NULL; + BIGNUM *lh, *y2; + int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + + if (EC_POINT_is_at_infinity(group, point)) + return 1; + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + + /* only support affine coordinates */ + if (!point->Z_is_one) + return -1; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return -1; + } + + BN_CTX_start(ctx); + y2 = BN_CTX_get(ctx); + lh = BN_CTX_get(ctx); + if (lh == NULL) + goto err; + + /*- + * We have a curve defined by a Weierstrass equation + * y^2 + x*y = x^3 + a*x^2 + b. + * <=> x^3 + a*x^2 + x*y + b + y^2 = 0 + * <=> ((x + a) * x + y ) * x + b + y^2 = 0 + */ + if (!BN_GF2m_add(lh, &point->X, &group->a)) + goto err; + if (!field_mul(group, lh, lh, &point->X, ctx)) + goto err; + if (!BN_GF2m_add(lh, lh, &point->Y)) + goto err; + if (!field_mul(group, lh, lh, &point->X, ctx)) + goto err; + if (!BN_GF2m_add(lh, lh, &group->b)) + goto err; + if (!field_sqr(group, y2, &point->Y, ctx)) + goto err; + if (!BN_GF2m_add(lh, lh, y2)) + goto err; + ret = BN_is_zero(lh); + err: + if (ctx) + BN_CTX_end(ctx); + if (new_ctx) + BN_CTX_free(new_ctx); + return ret; +} + +/*- + * Indicates whether two points are equal. + * Return values: + * -1 error + * 0 equal (in affine coordinates) + * 1 not equal + */ +int ec_GF2m_simple_cmp(const EC_GROUP *group, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) +{ + BIGNUM *aX, *aY, *bX, *bY; + BN_CTX *new_ctx = NULL; + int ret = -1; + + if (EC_POINT_is_at_infinity(group, a)) { + return EC_POINT_is_at_infinity(group, b) ? 0 : 1; + } + + if (EC_POINT_is_at_infinity(group, b)) + return 1; + + if (a->Z_is_one && b->Z_is_one) { + return ((BN_cmp(&a->X, &b->X) == 0) + && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return -1; + } + + BN_CTX_start(ctx); + aX = BN_CTX_get(ctx); + aY = BN_CTX_get(ctx); + bX = BN_CTX_get(ctx); + bY = BN_CTX_get(ctx); + if (bY == NULL) + goto err; + + if (!EC_POINT_get_affine_coordinates_GF2m(group, a, aX, aY, ctx)) + goto err; + if (!EC_POINT_get_affine_coordinates_GF2m(group, b, bX, bY, ctx)) + goto err; + ret = ((BN_cmp(aX, bX) == 0) && BN_cmp(aY, bY) == 0) ? 0 : 1; + + err: + if (ctx) + BN_CTX_end(ctx); + if (new_ctx) + BN_CTX_free(new_ctx); + return ret; +} + +/* Forces the given EC_POINT to internally use affine coordinates. */ +int ec_GF2m_simple_make_affine(const EC_GROUP *group, EC_POINT *point, + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y; + int ret = 0; + + if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) + return 1; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto err; + + if (!EC_POINT_get_affine_coordinates_GF2m(group, point, x, y, ctx)) + goto err; + if (!BN_copy(&point->X, x)) + goto err; + if (!BN_copy(&point->Y, y)) + goto err; + if (!BN_one(&point->Z)) + goto err; + + ret = 1; + + err: + if (ctx) + BN_CTX_end(ctx); + if (new_ctx) + BN_CTX_free(new_ctx); + return ret; +} + +/* + * Forces each of the EC_POINTs in the given array to use affine coordinates. + */ +int ec_GF2m_simple_points_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx) +{ + size_t i; + + for (i = 0; i < num; i++) { + if (!group->meth->make_affine(group, points[i], ctx)) + return 0; + } + + return 1; +} + +/* Wrapper to simple binary polynomial field multiplication implementation. */ +int ec_GF2m_simple_field_mul(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + return BN_GF2m_mod_mul_arr(r, a, b, group->poly, ctx); +} + +/* Wrapper to simple binary polynomial field squaring implementation. */ +int ec_GF2m_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, BN_CTX *ctx) +{ + return BN_GF2m_mod_sqr_arr(r, a, group->poly, ctx); +} + +/* Wrapper to simple binary polynomial field division implementation. */ +int ec_GF2m_simple_field_div(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + return BN_GF2m_mod_div(r, a, b, &group->field, ctx); +} + +#endif diff --git a/libs/openssl/crypto/ec/ec_ameth.c b/libs/openssl/crypto/ec/ec_ameth.c new file mode 100644 index 00000000..5cefb5ad --- /dev/null +++ b/libs/openssl/crypto/ec/ec_ameth.c @@ -0,0 +1,627 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#ifndef OPENSSL_NO_CMS +# include +#endif +#include "asn1_locl.h" + +static int eckey_param2type(int *pptype, void **ppval, EC_KEY *ec_key) +{ + const EC_GROUP *group; + int nid; + if (ec_key == NULL || (group = EC_KEY_get0_group(ec_key)) == NULL) { + ECerr(EC_F_ECKEY_PARAM2TYPE, EC_R_MISSING_PARAMETERS); + return 0; + } + if (EC_GROUP_get_asn1_flag(group) + && (nid = EC_GROUP_get_curve_name(group))) + /* we have a 'named curve' => just set the OID */ + { + *ppval = OBJ_nid2obj(nid); + *pptype = V_ASN1_OBJECT; + } else { /* explicit parameters */ + + ASN1_STRING *pstr = NULL; + pstr = ASN1_STRING_new(); + if (!pstr) + return 0; + pstr->length = i2d_ECParameters(ec_key, &pstr->data); + if (pstr->length <= 0) { + ASN1_STRING_free(pstr); + ECerr(EC_F_ECKEY_PARAM2TYPE, ERR_R_EC_LIB); + return 0; + } + *ppval = pstr; + *pptype = V_ASN1_SEQUENCE; + } + return 1; +} + +static int eckey_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) +{ + EC_KEY *ec_key = pkey->pkey.ec; + void *pval = NULL; + int ptype; + unsigned char *penc = NULL, *p; + int penclen; + + if (!eckey_param2type(&ptype, &pval, ec_key)) { + ECerr(EC_F_ECKEY_PUB_ENCODE, ERR_R_EC_LIB); + return 0; + } + penclen = i2o_ECPublicKey(ec_key, NULL); + if (penclen <= 0) + goto err; + penc = OPENSSL_malloc(penclen); + if (!penc) + goto err; + p = penc; + penclen = i2o_ECPublicKey(ec_key, &p); + if (penclen <= 0) + goto err; + if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_EC), + ptype, pval, penc, penclen)) + return 1; + err: + if (ptype == V_ASN1_OBJECT) + ASN1_OBJECT_free(pval); + else + ASN1_STRING_free(pval); + if (penc) + OPENSSL_free(penc); + return 0; +} + +static EC_KEY *eckey_type2param(int ptype, void *pval) +{ + EC_KEY *eckey = NULL; + if (ptype == V_ASN1_SEQUENCE) { + ASN1_STRING *pstr = pval; + const unsigned char *pm = NULL; + int pmlen; + pm = pstr->data; + pmlen = pstr->length; + if (!(eckey = d2i_ECParameters(NULL, &pm, pmlen))) { + ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); + goto ecerr; + } + } else if (ptype == V_ASN1_OBJECT) { + ASN1_OBJECT *poid = pval; + EC_GROUP *group; + + /* + * type == V_ASN1_OBJECT => the parameters are given by an asn1 OID + */ + if ((eckey = EC_KEY_new()) == NULL) { + ECerr(EC_F_ECKEY_TYPE2PARAM, ERR_R_MALLOC_FAILURE); + goto ecerr; + } + group = EC_GROUP_new_by_curve_name(OBJ_obj2nid(poid)); + if (group == NULL) + goto ecerr; + EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE); + if (EC_KEY_set_group(eckey, group) == 0) + goto ecerr; + EC_GROUP_free(group); + } else { + ECerr(EC_F_ECKEY_TYPE2PARAM, EC_R_DECODE_ERROR); + goto ecerr; + } + + return eckey; + + ecerr: + if (eckey) + EC_KEY_free(eckey); + return NULL; +} + +static int eckey_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +{ + const unsigned char *p = NULL; + void *pval; + int ptype, pklen; + EC_KEY *eckey = NULL; + X509_ALGOR *palg; + + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + eckey = eckey_type2param(ptype, pval); + + if (!eckey) { + ECerr(EC_F_ECKEY_PUB_DECODE, ERR_R_EC_LIB); + return 0; + } + + /* We have parameters now set public key */ + if (!o2i_ECPublicKey(&eckey, &p, pklen)) { + ECerr(EC_F_ECKEY_PUB_DECODE, EC_R_DECODE_ERROR); + goto ecerr; + } + + EVP_PKEY_assign_EC_KEY(pkey, eckey); + return 1; + + ecerr: + if (eckey) + EC_KEY_free(eckey); + return 0; +} + +static int eckey_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + int r; + const EC_GROUP *group = EC_KEY_get0_group(b->pkey.ec); + const EC_POINT *pa = EC_KEY_get0_public_key(a->pkey.ec), + *pb = EC_KEY_get0_public_key(b->pkey.ec); + r = EC_POINT_cmp(group, pa, pb, NULL); + if (r == 0) + return 1; + if (r == 1) + return 0; + return -2; +} + +static int eckey_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) +{ + const unsigned char *p = NULL; + void *pval; + int ptype, pklen; + EC_KEY *eckey = NULL; + X509_ALGOR *palg; + + if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) + return 0; + X509_ALGOR_get0(NULL, &ptype, &pval, palg); + + eckey = eckey_type2param(ptype, pval); + + if (!eckey) + goto ecliberr; + + /* We have parameters now set private key */ + if (!d2i_ECPrivateKey(&eckey, &p, pklen)) { + ECerr(EC_F_ECKEY_PRIV_DECODE, EC_R_DECODE_ERROR); + goto ecerr; + } + + /* calculate public key (if necessary) */ + if (EC_KEY_get0_public_key(eckey) == NULL) { + const BIGNUM *priv_key; + const EC_GROUP *group; + EC_POINT *pub_key; + /* + * the public key was not included in the SEC1 private key => + * calculate the public key + */ + group = EC_KEY_get0_group(eckey); + pub_key = EC_POINT_new(group); + if (pub_key == NULL) { + ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + goto ecliberr; + } + if (!EC_POINT_copy(pub_key, EC_GROUP_get0_generator(group))) { + EC_POINT_free(pub_key); + ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + goto ecliberr; + } + priv_key = EC_KEY_get0_private_key(eckey); + if (!EC_POINT_mul(group, pub_key, priv_key, NULL, NULL, NULL)) { + EC_POINT_free(pub_key); + ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + goto ecliberr; + } + if (EC_KEY_set_public_key(eckey, pub_key) == 0) { + EC_POINT_free(pub_key); + ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + goto ecliberr; + } + EC_POINT_free(pub_key); + } + + EVP_PKEY_assign_EC_KEY(pkey, eckey); + return 1; + + ecliberr: + ECerr(EC_F_ECKEY_PRIV_DECODE, ERR_R_EC_LIB); + ecerr: + if (eckey) + EC_KEY_free(eckey); + return 0; +} + +static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + EC_KEY *ec_key; + unsigned char *ep, *p; + int eplen, ptype; + void *pval; + unsigned int tmp_flags, old_flags; + + ec_key = pkey->pkey.ec; + + if (!eckey_param2type(&ptype, &pval, ec_key)) { + ECerr(EC_F_ECKEY_PRIV_ENCODE, EC_R_DECODE_ERROR); + return 0; + } + + /* set the private key */ + + /* + * do not include the parameters in the SEC1 private key see PKCS#11 + * 12.11 + */ + old_flags = EC_KEY_get_enc_flags(ec_key); + tmp_flags = old_flags | EC_PKEY_NO_PARAMETERS; + EC_KEY_set_enc_flags(ec_key, tmp_flags); + eplen = i2d_ECPrivateKey(ec_key, NULL); + if (!eplen) { + EC_KEY_set_enc_flags(ec_key, old_flags); + ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); + return 0; + } + ep = (unsigned char *)OPENSSL_malloc(eplen); + if (!ep) { + EC_KEY_set_enc_flags(ec_key, old_flags); + ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + return 0; + } + p = ep; + if (!i2d_ECPrivateKey(ec_key, &p)) { + EC_KEY_set_enc_flags(ec_key, old_flags); + OPENSSL_free(ep); + ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); + return 0; + } + /* restore old encoding flags */ + EC_KEY_set_enc_flags(ec_key, old_flags); + + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_X9_62_id_ecPublicKey), 0, + ptype, pval, ep, eplen)) + return 0; + + return 1; +} + +static int int_ec_size(const EVP_PKEY *pkey) +{ + return ECDSA_size(pkey->pkey.ec); +} + +static int ec_bits(const EVP_PKEY *pkey) +{ + BIGNUM *order = BN_new(); + const EC_GROUP *group; + int ret; + + if (!order) { + ERR_clear_error(); + return 0; + } + group = EC_KEY_get0_group(pkey->pkey.ec); + if (!EC_GROUP_get_order(group, order, NULL)) { + ERR_clear_error(); + return 0; + } + + ret = BN_num_bits(order); + BN_free(order); + return ret; +} + +static int ec_missing_parameters(const EVP_PKEY *pkey) +{ + if (EC_KEY_get0_group(pkey->pkey.ec) == NULL) + return 1; + return 0; +} + +static int ec_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) +{ + EC_GROUP *group = EC_GROUP_dup(EC_KEY_get0_group(from->pkey.ec)); + if (group == NULL) + return 0; + if (EC_KEY_set_group(to->pkey.ec, group) == 0) + return 0; + EC_GROUP_free(group); + return 1; +} + +static int ec_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) +{ + const EC_GROUP *group_a = EC_KEY_get0_group(a->pkey.ec), + *group_b = EC_KEY_get0_group(b->pkey.ec); + if (EC_GROUP_cmp(group_a, group_b, NULL)) + return 0; + else + return 1; +} + +static void int_ec_free(EVP_PKEY *pkey) +{ + EC_KEY_free(pkey->pkey.ec); +} + +static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) +{ + unsigned char *buffer = NULL; + const char *ecstr; + size_t buf_len = 0, i; + int ret = 0, reason = ERR_R_BIO_LIB; + BIGNUM *pub_key = NULL, *order = NULL; + BN_CTX *ctx = NULL; + const EC_GROUP *group; + const EC_POINT *public_key; + const BIGNUM *priv_key; + + if (x == NULL || (group = EC_KEY_get0_group(x)) == NULL) { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (ktype > 0) { + public_key = EC_KEY_get0_public_key(x); + if (public_key != NULL) { + if ((pub_key = EC_POINT_point2bn(group, public_key, + EC_KEY_get_conv_form(x), NULL, + ctx)) == NULL) { + reason = ERR_R_EC_LIB; + goto err; + } + buf_len = (size_t)BN_num_bytes(pub_key); + } + } + + if (ktype == 2) { + priv_key = EC_KEY_get0_private_key(x); + if (priv_key && (i = (size_t)BN_num_bytes(priv_key)) > buf_len) + buf_len = i; + } else + priv_key = NULL; + + if (ktype > 0) { + buf_len += 10; + if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + } + if (ktype == 2) + ecstr = "Private-Key"; + else if (ktype == 1) + ecstr = "Public-Key"; + else + ecstr = "ECDSA-Parameters"; + + if (!BIO_indent(bp, off, 128)) + goto err; + if ((order = BN_new()) == NULL) + goto err; + if (!EC_GROUP_get_order(group, order, NULL)) + goto err; + if (BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) + goto err; + + if ((priv_key != NULL) && !ASN1_bn_print(bp, "priv:", priv_key, + buffer, off)) + goto err; + if ((pub_key != NULL) && !ASN1_bn_print(bp, "pub: ", pub_key, + buffer, off)) + goto err; + if (!ECPKParameters_print(bp, group, off)) + goto err; + ret = 1; + err: + if (!ret) + ECerr(EC_F_DO_EC_KEY_PRINT, reason); + if (pub_key) + BN_free(pub_key); + if (order) + BN_free(order); + if (ctx) + BN_CTX_free(ctx); + if (buffer != NULL) + OPENSSL_free(buffer); + return (ret); +} + +static int eckey_param_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + EC_KEY *eckey; + if (!(eckey = d2i_ECParameters(NULL, pder, derlen))) { + ECerr(EC_F_ECKEY_PARAM_DECODE, ERR_R_EC_LIB); + return 0; + } + EVP_PKEY_assign_EC_KEY(pkey, eckey); + return 1; +} + +static int eckey_param_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_ECParameters(pkey->pkey.ec, pder); +} + +static int eckey_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 0); +} + +static int eckey_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 1); +} + +static int eckey_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_EC_KEY_print(bp, pkey->pkey.ec, indent, 2); +} + +static int old_ec_priv_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + EC_KEY *ec; + if (!(ec = d2i_ECPrivateKey(NULL, pder, derlen))) { + ECerr(EC_F_OLD_EC_PRIV_DECODE, EC_R_DECODE_ERROR); + return 0; + } + EVP_PKEY_assign_EC_KEY(pkey, ec); + return 1; +} + +static int old_ec_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_ECPrivateKey(pkey->pkey.ec, pder); +} + +static int ec_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) { + int snid, hnid; + X509_ALGOR *alg1, *alg2; + CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2); + if (alg1 == NULL || alg1->algorithm == NULL) + return -1; + hnid = OBJ_obj2nid(alg1->algorithm); + if (hnid == NID_undef) + return -1; + if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey))) + return -1; + X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0); + } + return 1; +#endif + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha1; + return 2; + + default: + return -2; + + } + +} + +const EVP_PKEY_ASN1_METHOD eckey_asn1_meth = { + EVP_PKEY_EC, + EVP_PKEY_EC, + 0, + "EC", + "OpenSSL EC algorithm", + + eckey_pub_decode, + eckey_pub_encode, + eckey_pub_cmp, + eckey_pub_print, + + eckey_priv_decode, + eckey_priv_encode, + eckey_priv_print, + + int_ec_size, + ec_bits, + + eckey_param_decode, + eckey_param_encode, + ec_missing_parameters, + ec_copy_parameters, + ec_cmp_parameters, + eckey_param_print, + 0, + + int_ec_free, + ec_pkey_ctrl, + old_ec_priv_decode, + old_ec_priv_encode +}; diff --git a/libs/openssl/crypto/ec/ec_asn1.c b/libs/openssl/crypto/ec/ec_asn1.c new file mode 100644 index 00000000..33abf61f --- /dev/null +++ b/libs/openssl/crypto/ec/ec_asn1.c @@ -0,0 +1,1326 @@ +/* crypto/ec/ec_asn1.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 2000-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "ec_lcl.h" +#include +#include +#include + +int EC_GROUP_get_basis_type(const EC_GROUP *group) +{ + int i = 0; + + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != + NID_X9_62_characteristic_two_field) + /* everything else is currently not supported */ + return 0; + + while (group->poly[i] != 0) + i++; + + if (i == 4) + return NID_X9_62_ppBasis; + else if (i == 2) + return NID_X9_62_tpBasis; + else + /* everything else is currently not supported */ + return 0; +} + +#ifndef OPENSSL_NO_EC2M +int EC_GROUP_get_trinomial_basis(const EC_GROUP *group, unsigned int *k) +{ + if (group == NULL) + return 0; + + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != + NID_X9_62_characteristic_two_field + || !((group->poly[0] != 0) && (group->poly[1] != 0) + && (group->poly[2] == 0))) { + ECerr(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (k) + *k = group->poly[1]; + + return 1; +} + +int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1, + unsigned int *k2, unsigned int *k3) +{ + if (group == NULL) + return 0; + + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) != + NID_X9_62_characteristic_two_field + || !((group->poly[0] != 0) && (group->poly[1] != 0) + && (group->poly[2] != 0) && (group->poly[3] != 0) + && (group->poly[4] == 0))) { + ECerr(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (k1) + *k1 = group->poly[3]; + if (k2) + *k2 = group->poly[2]; + if (k3) + *k3 = group->poly[1]; + + return 1; +} +#endif + +/* some structures needed for the asn1 encoding */ +typedef struct x9_62_pentanomial_st { + long k1; + long k2; + long k3; +} X9_62_PENTANOMIAL; + +typedef struct x9_62_characteristic_two_st { + long m; + ASN1_OBJECT *type; + union { + char *ptr; + /* NID_X9_62_onBasis */ + ASN1_NULL *onBasis; + /* NID_X9_62_tpBasis */ + ASN1_INTEGER *tpBasis; + /* NID_X9_62_ppBasis */ + X9_62_PENTANOMIAL *ppBasis; + /* anything else */ + ASN1_TYPE *other; + } p; +} X9_62_CHARACTERISTIC_TWO; + +typedef struct x9_62_fieldid_st { + ASN1_OBJECT *fieldType; + union { + char *ptr; + /* NID_X9_62_prime_field */ + ASN1_INTEGER *prime; + /* NID_X9_62_characteristic_two_field */ + X9_62_CHARACTERISTIC_TWO *char_two; + /* anything else */ + ASN1_TYPE *other; + } p; +} X9_62_FIELDID; + +typedef struct x9_62_curve_st { + ASN1_OCTET_STRING *a; + ASN1_OCTET_STRING *b; + ASN1_BIT_STRING *seed; +} X9_62_CURVE; + +typedef struct ec_parameters_st { + long version; + X9_62_FIELDID *fieldID; + X9_62_CURVE *curve; + ASN1_OCTET_STRING *base; + ASN1_INTEGER *order; + ASN1_INTEGER *cofactor; +} ECPARAMETERS; + +struct ecpk_parameters_st { + int type; + union { + ASN1_OBJECT *named_curve; + ECPARAMETERS *parameters; + ASN1_NULL *implicitlyCA; + } value; +} /* ECPKPARAMETERS */ ; + +/* SEC1 ECPrivateKey */ +typedef struct ec_privatekey_st { + long version; + ASN1_OCTET_STRING *privateKey; + ECPKPARAMETERS *parameters; + ASN1_BIT_STRING *publicKey; +} EC_PRIVATEKEY; + +/* the OpenSSL ASN.1 definitions */ +ASN1_SEQUENCE(X9_62_PENTANOMIAL) = { + ASN1_SIMPLE(X9_62_PENTANOMIAL, k1, LONG), + ASN1_SIMPLE(X9_62_PENTANOMIAL, k2, LONG), + ASN1_SIMPLE(X9_62_PENTANOMIAL, k3, LONG) +} ASN1_SEQUENCE_END(X9_62_PENTANOMIAL) + +DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_PENTANOMIAL) + +ASN1_ADB_TEMPLATE(char_two_def) = ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.other, ASN1_ANY); + +ASN1_ADB(X9_62_CHARACTERISTIC_TWO) = { + ADB_ENTRY(NID_X9_62_onBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.onBasis, ASN1_NULL)), + ADB_ENTRY(NID_X9_62_tpBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.tpBasis, ASN1_INTEGER)), + ADB_ENTRY(NID_X9_62_ppBasis, ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, p.ppBasis, X9_62_PENTANOMIAL)) +} ASN1_ADB_END(X9_62_CHARACTERISTIC_TWO, 0, type, 0, &char_two_def_tt, NULL); + +ASN1_SEQUENCE(X9_62_CHARACTERISTIC_TWO) = { + ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, m, LONG), + ASN1_SIMPLE(X9_62_CHARACTERISTIC_TWO, type, ASN1_OBJECT), + ASN1_ADB_OBJECT(X9_62_CHARACTERISTIC_TWO) +} ASN1_SEQUENCE_END(X9_62_CHARACTERISTIC_TWO) + +DECLARE_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(X9_62_CHARACTERISTIC_TWO) + +ASN1_ADB_TEMPLATE(fieldID_def) = ASN1_SIMPLE(X9_62_FIELDID, p.other, ASN1_ANY); + +ASN1_ADB(X9_62_FIELDID) = { + ADB_ENTRY(NID_X9_62_prime_field, ASN1_SIMPLE(X9_62_FIELDID, p.prime, ASN1_INTEGER)), + ADB_ENTRY(NID_X9_62_characteristic_two_field, ASN1_SIMPLE(X9_62_FIELDID, p.char_two, X9_62_CHARACTERISTIC_TWO)) +} ASN1_ADB_END(X9_62_FIELDID, 0, fieldType, 0, &fieldID_def_tt, NULL); + +ASN1_SEQUENCE(X9_62_FIELDID) = { + ASN1_SIMPLE(X9_62_FIELDID, fieldType, ASN1_OBJECT), + ASN1_ADB_OBJECT(X9_62_FIELDID) +} ASN1_SEQUENCE_END(X9_62_FIELDID) + +ASN1_SEQUENCE(X9_62_CURVE) = { + ASN1_SIMPLE(X9_62_CURVE, a, ASN1_OCTET_STRING), + ASN1_SIMPLE(X9_62_CURVE, b, ASN1_OCTET_STRING), + ASN1_OPT(X9_62_CURVE, seed, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(X9_62_CURVE) + +ASN1_SEQUENCE(ECPARAMETERS) = { + ASN1_SIMPLE(ECPARAMETERS, version, LONG), + ASN1_SIMPLE(ECPARAMETERS, fieldID, X9_62_FIELDID), + ASN1_SIMPLE(ECPARAMETERS, curve, X9_62_CURVE), + ASN1_SIMPLE(ECPARAMETERS, base, ASN1_OCTET_STRING), + ASN1_SIMPLE(ECPARAMETERS, order, ASN1_INTEGER), + ASN1_OPT(ECPARAMETERS, cofactor, ASN1_INTEGER) +} ASN1_SEQUENCE_END(ECPARAMETERS) + +DECLARE_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(ECPARAMETERS) + +ASN1_CHOICE(ECPKPARAMETERS) = { + ASN1_SIMPLE(ECPKPARAMETERS, value.named_curve, ASN1_OBJECT), + ASN1_SIMPLE(ECPKPARAMETERS, value.parameters, ECPARAMETERS), + ASN1_SIMPLE(ECPKPARAMETERS, value.implicitlyCA, ASN1_NULL) +} ASN1_CHOICE_END(ECPKPARAMETERS) + +DECLARE_ASN1_FUNCTIONS_const(ECPKPARAMETERS) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECPKPARAMETERS, ECPKPARAMETERS) +IMPLEMENT_ASN1_FUNCTIONS_const(ECPKPARAMETERS) + +ASN1_SEQUENCE(EC_PRIVATEKEY) = { + ASN1_SIMPLE(EC_PRIVATEKEY, version, LONG), + ASN1_SIMPLE(EC_PRIVATEKEY, privateKey, ASN1_OCTET_STRING), + ASN1_EXP_OPT(EC_PRIVATEKEY, parameters, ECPKPARAMETERS, 0), + ASN1_EXP_OPT(EC_PRIVATEKEY, publicKey, ASN1_BIT_STRING, 1) +} ASN1_SEQUENCE_END(EC_PRIVATEKEY) + +DECLARE_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(EC_PRIVATEKEY, EC_PRIVATEKEY) +IMPLEMENT_ASN1_FUNCTIONS_const(EC_PRIVATEKEY) + +/* some declarations of internal function */ + +/* ec_asn1_group2field() sets the values in a X9_62_FIELDID object */ +static int ec_asn1_group2fieldid(const EC_GROUP *, X9_62_FIELDID *); +/* ec_asn1_group2curve() sets the values in a X9_62_CURVE object */ +static int ec_asn1_group2curve(const EC_GROUP *, X9_62_CURVE *); +/* + * ec_asn1_parameters2group() creates a EC_GROUP object from a ECPARAMETERS + * object + */ +static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *); +/* + * ec_asn1_group2parameters() creates a ECPARAMETERS object from a EC_GROUP + * object + */ +static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *, + ECPARAMETERS *); +/* + * ec_asn1_pkparameters2group() creates a EC_GROUP object from a + * ECPKPARAMETERS object + */ +static EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *); +/* + * ec_asn1_group2pkparameters() creates a ECPKPARAMETERS object from a + * EC_GROUP object + */ +static ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *, + ECPKPARAMETERS *); + +/* the function definitions */ + +static int ec_asn1_group2fieldid(const EC_GROUP *group, X9_62_FIELDID *field) +{ + int ok = 0, nid; + BIGNUM *tmp = NULL; + + if (group == NULL || field == NULL) + return 0; + + /* clear the old values (if necessary) */ + if (field->fieldType != NULL) + ASN1_OBJECT_free(field->fieldType); + if (field->p.other != NULL) + ASN1_TYPE_free(field->p.other); + + nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); + /* set OID for the field */ + if ((field->fieldType = OBJ_nid2obj(nid)) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); + goto err; + } + + if (nid == NID_X9_62_prime_field) { + if ((tmp = BN_new()) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + goto err; + } + /* the parameters are specified by the prime number p */ + if (!EC_GROUP_get_curve_GFp(group, tmp, NULL, NULL, NULL)) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); + goto err; + } + /* set the prime number */ + field->p.prime = BN_to_ASN1_INTEGER(tmp, NULL); + if (field->p.prime == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); + goto err; + } + } else /* nid == NID_X9_62_characteristic_two_field */ +#ifdef OPENSSL_NO_EC2M + { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, EC_R_GF2M_NOT_SUPPORTED); + goto err; + } +#else + { + int field_type; + X9_62_CHARACTERISTIC_TWO *char_two; + + field->p.char_two = X9_62_CHARACTERISTIC_TWO_new(); + char_two = field->p.char_two; + + if (char_two == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + goto err; + } + + char_two->m = (long)EC_GROUP_get_degree(group); + + field_type = EC_GROUP_get_basis_type(group); + + if (field_type == 0) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_EC_LIB); + goto err; + } + /* set base type OID */ + if ((char_two->type = OBJ_nid2obj(field_type)) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_OBJ_LIB); + goto err; + } + + if (field_type == NID_X9_62_tpBasis) { + unsigned int k; + + if (!EC_GROUP_get_trinomial_basis(group, &k)) + goto err; + + char_two->p.tpBasis = ASN1_INTEGER_new(); + if (!char_two->p.tpBasis) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!ASN1_INTEGER_set(char_two->p.tpBasis, (long)k)) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_ASN1_LIB); + goto err; + } + } else if (field_type == NID_X9_62_ppBasis) { + unsigned int k1, k2, k3; + + if (!EC_GROUP_get_pentanomial_basis(group, &k1, &k2, &k3)) + goto err; + + char_two->p.ppBasis = X9_62_PENTANOMIAL_new(); + if (!char_two->p.ppBasis) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* set k? values */ + char_two->p.ppBasis->k1 = (long)k1; + char_two->p.ppBasis->k2 = (long)k2; + char_two->p.ppBasis->k3 = (long)k3; + } else { /* field_type == NID_X9_62_onBasis */ + + /* for ONB the parameters are (asn1) NULL */ + char_two->p.onBasis = ASN1_NULL_new(); + if (!char_two->p.onBasis) { + ECerr(EC_F_EC_ASN1_GROUP2FIELDID, ERR_R_MALLOC_FAILURE); + goto err; + } + } + } +#endif + + ok = 1; + + err:if (tmp) + BN_free(tmp); + return (ok); +} + +static int ec_asn1_group2curve(const EC_GROUP *group, X9_62_CURVE *curve) +{ + int ok = 0, nid; + BIGNUM *tmp_1 = NULL, *tmp_2 = NULL; + unsigned char *buffer_1 = NULL, *buffer_2 = NULL, + *a_buf = NULL, *b_buf = NULL; + size_t len_1, len_2; + unsigned char char_zero = 0; + + if (!group || !curve || !curve->a || !curve->b) + return 0; + + if ((tmp_1 = BN_new()) == NULL || (tmp_2 = BN_new()) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); + goto err; + } + + nid = EC_METHOD_get_field_type(EC_GROUP_method_of(group)); + + /* get a and b */ + if (nid == NID_X9_62_prime_field) { + if (!EC_GROUP_get_curve_GFp(group, NULL, tmp_1, tmp_2, NULL)) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); + goto err; + } + } +#ifndef OPENSSL_NO_EC2M + else { /* nid == NID_X9_62_characteristic_two_field */ + + if (!EC_GROUP_get_curve_GF2m(group, NULL, tmp_1, tmp_2, NULL)) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_EC_LIB); + goto err; + } + } +#endif + len_1 = (size_t)BN_num_bytes(tmp_1); + len_2 = (size_t)BN_num_bytes(tmp_2); + + if (len_1 == 0) { + /* len_1 == 0 => a == 0 */ + a_buf = &char_zero; + len_1 = 1; + } else { + if ((buffer_1 = OPENSSL_malloc(len_1)) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); + goto err; + } + if ((len_1 = BN_bn2bin(tmp_1, buffer_1)) == 0) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); + goto err; + } + a_buf = buffer_1; + } + + if (len_2 == 0) { + /* len_2 == 0 => b == 0 */ + b_buf = &char_zero; + len_2 = 1; + } else { + if ((buffer_2 = OPENSSL_malloc(len_2)) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); + goto err; + } + if ((len_2 = BN_bn2bin(tmp_2, buffer_2)) == 0) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_BN_LIB); + goto err; + } + b_buf = buffer_2; + } + + /* set a and b */ + if (!M_ASN1_OCTET_STRING_set(curve->a, a_buf, len_1) || + !M_ASN1_OCTET_STRING_set(curve->b, b_buf, len_2)) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); + goto err; + } + + /* set the seed (optional) */ + if (group->seed) { + if (!curve->seed) + if ((curve->seed = ASN1_BIT_STRING_new()) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_MALLOC_FAILURE); + goto err; + } + curve->seed->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + curve->seed->flags |= ASN1_STRING_FLAG_BITS_LEFT; + if (!ASN1_BIT_STRING_set(curve->seed, group->seed, + (int)group->seed_len)) { + ECerr(EC_F_EC_ASN1_GROUP2CURVE, ERR_R_ASN1_LIB); + goto err; + } + } else { + if (curve->seed) { + ASN1_BIT_STRING_free(curve->seed); + curve->seed = NULL; + } + } + + ok = 1; + + err:if (buffer_1) + OPENSSL_free(buffer_1); + if (buffer_2) + OPENSSL_free(buffer_2); + if (tmp_1) + BN_free(tmp_1); + if (tmp_2) + BN_free(tmp_2); + return (ok); +} + +static ECPARAMETERS *ec_asn1_group2parameters(const EC_GROUP *group, + ECPARAMETERS *param) +{ + int ok = 0; + size_t len = 0; + ECPARAMETERS *ret = NULL; + BIGNUM *tmp = NULL; + unsigned char *buffer = NULL; + const EC_POINT *point = NULL; + point_conversion_form_t form; + + if ((tmp = BN_new()) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (param == NULL) { + if ((ret = ECPARAMETERS_new()) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); + goto err; + } + } else + ret = param; + + /* set the version (always one) */ + ret->version = (long)0x1; + + /* set the fieldID */ + if (!ec_asn1_group2fieldid(group, ret->fieldID)) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); + goto err; + } + + /* set the curve */ + if (!ec_asn1_group2curve(group, ret->curve)) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); + goto err; + } + + /* set the base point */ + if ((point = EC_GROUP_get0_generator(group)) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, EC_R_UNDEFINED_GENERATOR); + goto err; + } + + form = EC_GROUP_get_point_conversion_form(group); + + len = EC_POINT_point2oct(group, point, form, NULL, len, NULL); + if (len == 0) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); + goto err; + } + if ((buffer = OPENSSL_malloc(len)) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_POINT_point2oct(group, point, form, buffer, len, NULL)) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); + goto err; + } + if (ret->base == NULL && (ret->base = ASN1_OCTET_STRING_new()) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!ASN1_OCTET_STRING_set(ret->base, buffer, len)) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); + goto err; + } + + /* set the order */ + if (!EC_GROUP_get_order(group, tmp, NULL)) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_EC_LIB); + goto err; + } + ret->order = BN_to_ASN1_INTEGER(tmp, ret->order); + if (ret->order == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); + goto err; + } + + /* set the cofactor (optional) */ + if (EC_GROUP_get_cofactor(group, tmp, NULL)) { + ret->cofactor = BN_to_ASN1_INTEGER(tmp, ret->cofactor); + if (ret->cofactor == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PARAMETERS, ERR_R_ASN1_LIB); + goto err; + } + } + + ok = 1; + + err:if (!ok) { + if (ret && !param) + ECPARAMETERS_free(ret); + ret = NULL; + } + if (tmp) + BN_free(tmp); + if (buffer) + OPENSSL_free(buffer); + return (ret); +} + +ECPKPARAMETERS *ec_asn1_group2pkparameters(const EC_GROUP *group, + ECPKPARAMETERS *params) +{ + int ok = 1, tmp; + ECPKPARAMETERS *ret = params; + + if (ret == NULL) { + if ((ret = ECPKPARAMETERS_new()) == NULL) { + ECerr(EC_F_EC_ASN1_GROUP2PKPARAMETERS, ERR_R_MALLOC_FAILURE); + return NULL; + } + } else { + if (ret->type == 0 && ret->value.named_curve) + ASN1_OBJECT_free(ret->value.named_curve); + else if (ret->type == 1 && ret->value.parameters) + ECPARAMETERS_free(ret->value.parameters); + } + + if (EC_GROUP_get_asn1_flag(group)) { + /* + * use the asn1 OID to describe the the elliptic curve parameters + */ + tmp = EC_GROUP_get_curve_name(group); + if (tmp) { + ret->type = 0; + if ((ret->value.named_curve = OBJ_nid2obj(tmp)) == NULL) + ok = 0; + } else + /* we don't kmow the nid => ERROR */ + ok = 0; + } else { + /* use the ECPARAMETERS structure */ + ret->type = 1; + if ((ret->value.parameters = + ec_asn1_group2parameters(group, NULL)) == NULL) + ok = 0; + } + + if (!ok) { + ECPKPARAMETERS_free(ret); + return NULL; + } + return ret; +} + +static EC_GROUP *ec_asn1_parameters2group(const ECPARAMETERS *params) +{ + int ok = 0, tmp; + EC_GROUP *ret = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL; + EC_POINT *point = NULL; + long field_bits; + + if (!params->fieldID || !params->fieldID->fieldType || + !params->fieldID->p.ptr) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); + goto err; + } + + /* now extract the curve parameters a and b */ + if (!params->curve || !params->curve->a || + !params->curve->a->data || !params->curve->b || + !params->curve->b->data) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); + goto err; + } + a = BN_bin2bn(params->curve->a->data, params->curve->a->length, NULL); + if (a == NULL) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); + goto err; + } + b = BN_bin2bn(params->curve->b->data, params->curve->b->length, NULL); + if (b == NULL) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_BN_LIB); + goto err; + } + + /* get the field parameters */ + tmp = OBJ_obj2nid(params->fieldID->fieldType); + if (tmp == NID_X9_62_characteristic_two_field) +#ifdef OPENSSL_NO_EC2M + { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_GF2M_NOT_SUPPORTED); + goto err; + } +#else + { + X9_62_CHARACTERISTIC_TWO *char_two; + + char_two = params->fieldID->p.char_two; + + field_bits = char_two->m; + if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); + goto err; + } + + if ((p = BN_new()) == NULL) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* get the base type */ + tmp = OBJ_obj2nid(char_two->type); + + if (tmp == NID_X9_62_tpBasis) { + long tmp_long; + + if (!char_two->p.tpBasis) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); + goto err; + } + + tmp_long = ASN1_INTEGER_get(char_two->p.tpBasis); + + if (!(char_two->m > tmp_long && tmp_long > 0)) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, + EC_R_INVALID_TRINOMIAL_BASIS); + goto err; + } + + /* create the polynomial */ + if (!BN_set_bit(p, (int)char_two->m)) + goto err; + if (!BN_set_bit(p, (int)tmp_long)) + goto err; + if (!BN_set_bit(p, 0)) + goto err; + } else if (tmp == NID_X9_62_ppBasis) { + X9_62_PENTANOMIAL *penta; + + penta = char_two->p.ppBasis; + if (!penta) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); + goto err; + } + + if (! + (char_two->m > penta->k3 && penta->k3 > penta->k2 + && penta->k2 > penta->k1 && penta->k1 > 0)) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, + EC_R_INVALID_PENTANOMIAL_BASIS); + goto err; + } + + /* create the polynomial */ + if (!BN_set_bit(p, (int)char_two->m)) + goto err; + if (!BN_set_bit(p, (int)penta->k1)) + goto err; + if (!BN_set_bit(p, (int)penta->k2)) + goto err; + if (!BN_set_bit(p, (int)penta->k3)) + goto err; + if (!BN_set_bit(p, 0)) + goto err; + } else if (tmp == NID_X9_62_onBasis) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_NOT_IMPLEMENTED); + goto err; + } else { /* error */ + + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); + goto err; + } + + /* create the EC_GROUP structure */ + ret = EC_GROUP_new_curve_GF2m(p, a, b, NULL); + } +#endif + else if (tmp == NID_X9_62_prime_field) { + /* we have a curve over a prime field */ + /* extract the prime number */ + if (!params->fieldID->p.prime) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); + goto err; + } + p = ASN1_INTEGER_to_BN(params->fieldID->p.prime, NULL); + if (p == NULL) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); + goto err; + } + + if (BN_is_negative(p) || BN_is_zero(p)) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); + goto err; + } + + field_bits = BN_num_bits(p); + if (field_bits > OPENSSL_ECC_MAX_FIELD_BITS) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_FIELD_TOO_LARGE); + goto err; + } + + /* create the EC_GROUP structure */ + ret = EC_GROUP_new_curve_GFp(p, a, b, NULL); + } else { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_FIELD); + goto err; + } + + if (ret == NULL) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); + goto err; + } + + /* extract seed (optional) */ + if (params->curve->seed != NULL) { + if (ret->seed != NULL) + OPENSSL_free(ret->seed); + if (!(ret->seed = OPENSSL_malloc(params->curve->seed->length))) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_MALLOC_FAILURE); + goto err; + } + memcpy(ret->seed, params->curve->seed->data, + params->curve->seed->length); + ret->seed_len = params->curve->seed->length; + } + + if (!params->order || !params->base || !params->base->data) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_ASN1_ERROR); + goto err; + } + + if ((point = EC_POINT_new(ret)) == NULL) + goto err; + + /* set the point conversion form */ + EC_GROUP_set_point_conversion_form(ret, (point_conversion_form_t) + (params->base->data[0] & ~0x01)); + + /* extract the ec point */ + if (!EC_POINT_oct2point(ret, point, params->base->data, + params->base->length, NULL)) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); + goto err; + } + + /* extract the order */ + if ((a = ASN1_INTEGER_to_BN(params->order, a)) == NULL) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); + goto err; + } + if (BN_is_negative(a) || BN_is_zero(a)) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); + goto err; + } + if (BN_num_bits(a) > (int)field_bits + 1) { /* Hasse bound */ + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, EC_R_INVALID_GROUP_ORDER); + goto err; + } + + /* extract the cofactor (optional) */ + if (params->cofactor == NULL) { + if (b) { + BN_free(b); + b = NULL; + } + } else if ((b = ASN1_INTEGER_to_BN(params->cofactor, b)) == NULL) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_ASN1_LIB); + goto err; + } + /* set the generator, order and cofactor (if present) */ + if (!EC_GROUP_set_generator(ret, point, a, b)) { + ECerr(EC_F_EC_ASN1_PARAMETERS2GROUP, ERR_R_EC_LIB); + goto err; + } + + ok = 1; + + err:if (!ok) { + if (ret) + EC_GROUP_clear_free(ret); + ret = NULL; + } + + if (p) + BN_free(p); + if (a) + BN_free(a); + if (b) + BN_free(b); + if (point) + EC_POINT_free(point); + return (ret); +} + +EC_GROUP *ec_asn1_pkparameters2group(const ECPKPARAMETERS *params) +{ + EC_GROUP *ret = NULL; + int tmp = 0; + + if (params == NULL) { + ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_MISSING_PARAMETERS); + return NULL; + } + + if (params->type == 0) { /* the curve is given by an OID */ + tmp = OBJ_obj2nid(params->value.named_curve); + if ((ret = EC_GROUP_new_by_curve_name(tmp)) == NULL) { + ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, + EC_R_EC_GROUP_NEW_BY_NAME_FAILURE); + return NULL; + } + EC_GROUP_set_asn1_flag(ret, OPENSSL_EC_NAMED_CURVE); + } else if (params->type == 1) { /* the parameters are given by a + * ECPARAMETERS structure */ + ret = ec_asn1_parameters2group(params->value.parameters); + if (!ret) { + ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, ERR_R_EC_LIB); + return NULL; + } + EC_GROUP_set_asn1_flag(ret, 0x0); + } else if (params->type == 2) { /* implicitlyCA */ + return NULL; + } else { + ECerr(EC_F_EC_ASN1_PKPARAMETERS2GROUP, EC_R_ASN1_ERROR); + return NULL; + } + + return ret; +} + +/* EC_GROUP <-> DER encoding of ECPKPARAMETERS */ + +EC_GROUP *d2i_ECPKParameters(EC_GROUP **a, const unsigned char **in, long len) +{ + EC_GROUP *group = NULL; + ECPKPARAMETERS *params = NULL; + const unsigned char *p = *in; + + if ((params = d2i_ECPKPARAMETERS(NULL, &p, len)) == NULL) { + ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_D2I_ECPKPARAMETERS_FAILURE); + ECPKPARAMETERS_free(params); + return NULL; + } + + if ((group = ec_asn1_pkparameters2group(params)) == NULL) { + ECerr(EC_F_D2I_ECPKPARAMETERS, EC_R_PKPARAMETERS2GROUP_FAILURE); + ECPKPARAMETERS_free(params); + return NULL; + } + + if (a && *a) + EC_GROUP_clear_free(*a); + if (a) + *a = group; + + ECPKPARAMETERS_free(params); + *in = p; + return (group); +} + +int i2d_ECPKParameters(const EC_GROUP *a, unsigned char **out) +{ + int ret = 0; + ECPKPARAMETERS *tmp = ec_asn1_group2pkparameters(a, NULL); + if (tmp == NULL) { + ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_GROUP2PKPARAMETERS_FAILURE); + return 0; + } + if ((ret = i2d_ECPKPARAMETERS(tmp, out)) == 0) { + ECerr(EC_F_I2D_ECPKPARAMETERS, EC_R_I2D_ECPKPARAMETERS_FAILURE); + ECPKPARAMETERS_free(tmp); + return 0; + } + ECPKPARAMETERS_free(tmp); + return (ret); +} + +/* some EC_KEY functions */ + +EC_KEY *d2i_ECPrivateKey(EC_KEY **a, const unsigned char **in, long len) +{ + int ok = 0; + EC_KEY *ret = NULL; + EC_PRIVATEKEY *priv_key = NULL; + const unsigned char *p = *in; + + if ((priv_key = d2i_EC_PRIVATEKEY(NULL, &p, len)) == NULL) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + return NULL; + } + + if (a == NULL || *a == NULL) { + if ((ret = EC_KEY_new()) == NULL) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + } else + ret = *a; + + if (priv_key->parameters) { + if (ret->group) + EC_GROUP_clear_free(ret->group); + ret->group = ec_asn1_pkparameters2group(priv_key->parameters); + } + + if (ret->group == NULL) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + goto err; + } + + ret->version = priv_key->version; + + if (priv_key->privateKey) { + ret->priv_key = BN_bin2bn(M_ASN1_STRING_data(priv_key->privateKey), + M_ASN1_STRING_length(priv_key->privateKey), + ret->priv_key); + if (ret->priv_key == NULL) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_BN_LIB); + goto err; + } + } else { + ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_MISSING_PRIVATE_KEY); + goto err; + } + + if (ret->pub_key) + EC_POINT_clear_free(ret->pub_key); + ret->pub_key = EC_POINT_new(ret->group); + if (ret->pub_key == NULL) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + goto err; + } + + if (priv_key->publicKey) { + const unsigned char *pub_oct; + int pub_oct_len; + + pub_oct = M_ASN1_STRING_data(priv_key->publicKey); + pub_oct_len = M_ASN1_STRING_length(priv_key->publicKey); + /* + * The first byte - point conversion form - must be present. + */ + if (pub_oct_len <= 0) { + ECerr(EC_F_D2I_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); + goto err; + } + /* Save the point conversion form. */ + ret->conv_form = (point_conversion_form_t) (pub_oct[0] & ~0x01); + if (!EC_POINT_oct2point(ret->group, ret->pub_key, + pub_oct, (size_t)(pub_oct_len), NULL)) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + goto err; + } + } else { + if (!EC_POINT_mul + (ret->group, ret->pub_key, ret->priv_key, NULL, NULL, NULL)) { + ECerr(EC_F_D2I_ECPRIVATEKEY, ERR_R_EC_LIB); + goto err; + } + /* Remember the original private-key-only encoding. */ + ret->enc_flag |= EC_PKEY_NO_PUBKEY; + } + + if (a) + *a = ret; + *in = p; + ok = 1; + err: + if (!ok) { + if (ret && (a == NULL || *a != ret)) + EC_KEY_free(ret); + ret = NULL; + } + + if (priv_key) + EC_PRIVATEKEY_free(priv_key); + + return (ret); +} + +int i2d_ECPrivateKey(EC_KEY *a, unsigned char **out) +{ + int ret = 0, ok = 0; + unsigned char *buffer = NULL; + size_t buf_len = 0, tmp_len, bn_len; + EC_PRIVATEKEY *priv_key = NULL; + + if (a == NULL || a->group == NULL || a->priv_key == NULL || + (!(a->enc_flag & EC_PKEY_NO_PUBKEY) && a->pub_key == NULL)) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + + if ((priv_key = EC_PRIVATEKEY_new()) == NULL) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + priv_key->version = a->version; + + bn_len = (size_t)BN_num_bytes(a->priv_key); + + /* Octetstring may need leading zeros if BN is to short */ + + buf_len = (EC_GROUP_get_degree(a->group) + 7) / 8; + + if (bn_len > buf_len) { + ECerr(EC_F_I2D_ECPRIVATEKEY, EC_R_BUFFER_TOO_SMALL); + goto err; + } + + buffer = OPENSSL_malloc(buf_len); + if (buffer == NULL) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BN_bn2bin(a->priv_key, buffer + buf_len - bn_len)) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_BN_LIB); + goto err; + } + + if (buf_len - bn_len > 0) { + memset(buffer, 0, buf_len - bn_len); + } + + if (!M_ASN1_OCTET_STRING_set(priv_key->privateKey, buffer, buf_len)) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); + goto err; + } + + if (!(a->enc_flag & EC_PKEY_NO_PARAMETERS)) { + if ((priv_key->parameters = + ec_asn1_group2pkparameters(a->group, + priv_key->parameters)) == NULL) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); + goto err; + } + } + + if (!(a->enc_flag & EC_PKEY_NO_PUBKEY)) { + priv_key->publicKey = M_ASN1_BIT_STRING_new(); + if (priv_key->publicKey == NULL) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + tmp_len = EC_POINT_point2oct(a->group, a->pub_key, + a->conv_form, NULL, 0, NULL); + + if (tmp_len > buf_len) { + unsigned char *tmp_buffer = OPENSSL_realloc(buffer, tmp_len); + if (!tmp_buffer) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_MALLOC_FAILURE); + goto err; + } + buffer = tmp_buffer; + buf_len = tmp_len; + } + + if (!EC_POINT_point2oct(a->group, a->pub_key, + a->conv_form, buffer, buf_len, NULL)) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); + goto err; + } + + priv_key->publicKey->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); + priv_key->publicKey->flags |= ASN1_STRING_FLAG_BITS_LEFT; + if (!M_ASN1_BIT_STRING_set(priv_key->publicKey, buffer, buf_len)) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_ASN1_LIB); + goto err; + } + } + + if ((ret = i2d_EC_PRIVATEKEY(priv_key, out)) == 0) { + ECerr(EC_F_I2D_ECPRIVATEKEY, ERR_R_EC_LIB); + goto err; + } + ok = 1; + err: + if (buffer) + OPENSSL_free(buffer); + if (priv_key) + EC_PRIVATEKEY_free(priv_key); + return (ok ? ret : 0); +} + +int i2d_ECParameters(EC_KEY *a, unsigned char **out) +{ + if (a == NULL) { + ECerr(EC_F_I2D_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + return i2d_ECPKParameters(a->group, out); +} + +EC_KEY *d2i_ECParameters(EC_KEY **a, const unsigned char **in, long len) +{ + EC_KEY *ret; + + if (in == NULL || *in == NULL) { + ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + if (a == NULL || *a == NULL) { + if ((ret = EC_KEY_new()) == NULL) { + ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_MALLOC_FAILURE); + return NULL; + } + } else + ret = *a; + + if (!d2i_ECPKParameters(&ret->group, in, len)) { + ECerr(EC_F_D2I_ECPARAMETERS, ERR_R_EC_LIB); + if (a == NULL || *a != ret) + EC_KEY_free(ret); + return NULL; + } + + if (a) + *a = ret; + + return ret; +} + +EC_KEY *o2i_ECPublicKey(EC_KEY **a, const unsigned char **in, long len) +{ + EC_KEY *ret = NULL; + + if (a == NULL || (*a) == NULL || (*a)->group == NULL) { + /* + * sorry, but a EC_GROUP-structur is necessary to set the public key + */ + ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ret = *a; + if (ret->pub_key == NULL && + (ret->pub_key = EC_POINT_new(ret->group)) == NULL) { + ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!EC_POINT_oct2point(ret->group, ret->pub_key, *in, len, NULL)) { + ECerr(EC_F_O2I_ECPUBLICKEY, ERR_R_EC_LIB); + return 0; + } + /* save the point conversion form */ + ret->conv_form = (point_conversion_form_t) (*in[0] & ~0x01); + *in += len; + return ret; +} + +int i2o_ECPublicKey(EC_KEY *a, unsigned char **out) +{ + size_t buf_len = 0; + int new_buffer = 0; + + if (a == NULL) { + ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + buf_len = EC_POINT_point2oct(a->group, a->pub_key, + a->conv_form, NULL, 0, NULL); + + if (out == NULL || buf_len == 0) + /* out == NULL => just return the length of the octet string */ + return buf_len; + + if (*out == NULL) { + if ((*out = OPENSSL_malloc(buf_len)) == NULL) { + ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_MALLOC_FAILURE); + return 0; + } + new_buffer = 1; + } + if (!EC_POINT_point2oct(a->group, a->pub_key, a->conv_form, + *out, buf_len, NULL)) { + ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB); + if (new_buffer) { + OPENSSL_free(*out); + *out = NULL; + } + return 0; + } + if (!new_buffer) + *out += buf_len; + return buf_len; +} diff --git a/libs/openssl/crypto/ec/ec_check.c b/libs/openssl/crypto/ec/ec_check.c new file mode 100644 index 00000000..dd6f0ac4 --- /dev/null +++ b/libs/openssl/crypto/ec/ec_check.c @@ -0,0 +1,120 @@ +/* crypto/ec/ec_check.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ec_lcl.h" +#include + +int EC_GROUP_check(const EC_GROUP *group, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *order; + BN_CTX *new_ctx = NULL; + EC_POINT *point = NULL; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + ECerr(EC_F_EC_GROUP_CHECK, ERR_R_MALLOC_FAILURE); + goto err; + } + } + BN_CTX_start(ctx); + if ((order = BN_CTX_get(ctx)) == NULL) + goto err; + + /* check the discriminant */ + if (!EC_GROUP_check_discriminant(group, ctx)) { + ECerr(EC_F_EC_GROUP_CHECK, EC_R_DISCRIMINANT_IS_ZERO); + goto err; + } + + /* check the generator */ + if (group->generator == NULL) { + ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR); + goto err; + } + if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) { + ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + + /* check the order of the generator */ + if ((point = EC_POINT_new(group)) == NULL) + goto err; + if (!EC_GROUP_get_order(group, order, ctx)) + goto err; + if (BN_is_zero(order)) { + ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_ORDER); + goto err; + } + + if (!EC_POINT_mul(group, point, order, NULL, NULL, ctx)) + goto err; + if (!EC_POINT_is_at_infinity(group, point)) { + ECerr(EC_F_EC_GROUP_CHECK, EC_R_INVALID_GROUP_ORDER); + goto err; + } + + ret = 1; + + err: + if (ctx != NULL) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (point) + EC_POINT_free(point); + return ret; +} diff --git a/libs/openssl/crypto/ec/ec_curve.c b/libs/openssl/crypto/ec/ec_curve.c new file mode 100644 index 00000000..e4bcb5dd --- /dev/null +++ b/libs/openssl/crypto/ec/ec_curve.c @@ -0,0 +1,2615 @@ +/* crypto/ec/ec_curve.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include "ec_lcl.h" +#include +#include +#include + +typedef struct { + int field_type, /* either NID_X9_62_prime_field or + * NID_X9_62_characteristic_two_field */ + seed_len, param_len; + unsigned int cofactor; /* promoted to BN_ULONG */ +} EC_CURVE_DATA; + +/* the nist prime curves */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 24 * 6]; +} _EC_NIST_PRIME_192 = { + { + NID_X9_62_prime_field, 20, 24, 1 + }, + { + /* seed */ + 0x30, 0x45, 0xAE, 0x6F, 0xC8, 0x42, 0x2F, 0x64, 0xED, 0x57, 0x95, 0x28, + 0xD3, 0x81, 0x20, 0xEA, 0xE1, 0x21, 0x96, 0xD5, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x64, 0x21, 0x05, 0x19, 0xE5, 0x9C, 0x80, 0xE7, 0x0F, 0xA7, 0xE9, 0xAB, + 0x72, 0x24, 0x30, 0x49, 0xFE, 0xB8, 0xDE, 0xEC, 0xC1, 0x46, 0xB9, 0xB1, + /* x */ + 0x18, 0x8D, 0xA8, 0x0E, 0xB0, 0x30, 0x90, 0xF6, 0x7C, 0xBF, 0x20, 0xEB, + 0x43, 0xA1, 0x88, 0x00, 0xF4, 0xFF, 0x0A, 0xFD, 0x82, 0xFF, 0x10, 0x12, + /* y */ + 0x07, 0x19, 0x2b, 0x95, 0xff, 0xc8, 0xda, 0x78, 0x63, 0x10, 0x11, 0xed, + 0x6b, 0x24, 0xcd, 0xd5, 0x73, 0xf9, 0x77, 0xa1, 0x1e, 0x79, 0x48, 0x11, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x99, 0xDE, 0xF8, 0x36, 0x14, 0x6B, 0xC9, 0xB1, 0xB4, 0xD2, 0x28, 0x31 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 28 * 6]; +} _EC_NIST_PRIME_224 = { + { + NID_X9_62_prime_field, 20, 28, 1 + }, + { + /* seed */ + 0xBD, 0x71, 0x34, 0x47, 0x99, 0xD5, 0xC7, 0xFC, 0xDC, 0x45, 0xB5, 0x9F, + 0xA3, 0xB9, 0xAB, 0x8F, 0x6A, 0x94, 0x8B, 0xC5, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, + /* b */ + 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56, + 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, + 0x23, 0x55, 0xFF, 0xB4, + /* x */ + 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9, + 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, + 0x11, 0x5C, 0x1D, 0x21, + /* y */ + 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, + 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, + 0x85, 0x00, 0x7e, 0x34, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, + 0x5C, 0x5C, 0x2A, 0x3D + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 48 * 6]; +} _EC_NIST_PRIME_384 = { + { + NID_X9_62_prime_field, 20, 48, 1 + }, + { + /* seed */ + 0xA3, 0x35, 0x92, 0x6A, 0xA3, 0x19, 0xA2, 0x7A, 0x1D, 0x00, 0x89, 0x6A, + 0x67, 0x73, 0xA4, 0x82, 0x7A, 0xCD, 0xAC, 0x73, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, + 0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12, + 0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D, + 0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF, + /* x */ + 0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, + 0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98, + 0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D, + 0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7, + /* y */ + 0x36, 0x17, 0xde, 0x4a, 0x96, 0x26, 0x2c, 0x6f, 0x5d, 0x9e, 0x98, 0xbf, + 0x92, 0x92, 0xdc, 0x29, 0xf8, 0xf4, 0x1d, 0xbd, 0x28, 0x9a, 0x14, 0x7c, + 0xe9, 0xda, 0x31, 0x13, 0xb5, 0xf0, 0xb8, 0xc0, 0x0a, 0x60, 0xb1, 0xce, + 0x1d, 0x7e, 0x81, 0x9d, 0x7a, 0x43, 0x1d, 0x7c, 0x90, 0xea, 0x0e, 0x5f, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xC7, 0x63, 0x4D, 0x81, 0xF4, 0x37, 0x2D, 0xDF, 0x58, 0x1A, 0x0D, 0xB2, + 0x48, 0xB0, 0xA7, 0x7A, 0xEC, 0xEC, 0x19, 0x6A, 0xCC, 0xC5, 0x29, 0x73 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 66 * 6]; +} _EC_NIST_PRIME_521 = { + { + NID_X9_62_prime_field, 20, 66, 1 + }, + { + /* seed */ + 0xD0, 0x9E, 0x88, 0x00, 0x29, 0x1C, 0xB8, 0x53, 0x96, 0xCC, 0x67, 0x17, + 0x39, 0x32, 0x84, 0xAA, 0xA0, 0xDA, 0x64, 0xBA, + /* p */ + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x00, 0x51, 0x95, 0x3E, 0xB9, 0x61, 0x8E, 0x1C, 0x9A, 0x1F, 0x92, 0x9A, + 0x21, 0xA0, 0xB6, 0x85, 0x40, 0xEE, 0xA2, 0xDA, 0x72, 0x5B, 0x99, 0xB3, + 0x15, 0xF3, 0xB8, 0xB4, 0x89, 0x91, 0x8E, 0xF1, 0x09, 0xE1, 0x56, 0x19, + 0x39, 0x51, 0xEC, 0x7E, 0x93, 0x7B, 0x16, 0x52, 0xC0, 0xBD, 0x3B, 0xB1, + 0xBF, 0x07, 0x35, 0x73, 0xDF, 0x88, 0x3D, 0x2C, 0x34, 0xF1, 0xEF, 0x45, + 0x1F, 0xD4, 0x6B, 0x50, 0x3F, 0x00, + /* x */ + 0x00, 0xC6, 0x85, 0x8E, 0x06, 0xB7, 0x04, 0x04, 0xE9, 0xCD, 0x9E, 0x3E, + 0xCB, 0x66, 0x23, 0x95, 0xB4, 0x42, 0x9C, 0x64, 0x81, 0x39, 0x05, 0x3F, + 0xB5, 0x21, 0xF8, 0x28, 0xAF, 0x60, 0x6B, 0x4D, 0x3D, 0xBA, 0xA1, 0x4B, + 0x5E, 0x77, 0xEF, 0xE7, 0x59, 0x28, 0xFE, 0x1D, 0xC1, 0x27, 0xA2, 0xFF, + 0xA8, 0xDE, 0x33, 0x48, 0xB3, 0xC1, 0x85, 0x6A, 0x42, 0x9B, 0xF9, 0x7E, + 0x7E, 0x31, 0xC2, 0xE5, 0xBD, 0x66, + /* y */ + 0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, 0xc0, 0x04, 0x5c, 0x8a, + 0x5f, 0xb4, 0x2c, 0x7d, 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, + 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, 0x66, 0x2c, 0x97, 0xee, + 0x72, 0x99, 0x5e, 0xf4, 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, + 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, 0xc2, 0x40, 0x88, 0xbe, + 0x94, 0x76, 0x9f, 0xd1, 0x66, 0x50, + /* order */ + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFA, 0x51, 0x86, + 0x87, 0x83, 0xBF, 0x2F, 0x96, 0x6B, 0x7F, 0xCC, 0x01, 0x48, 0xF7, 0x09, + 0xA5, 0xD0, 0x3B, 0xB5, 0xC9, 0xB8, 0x89, 0x9C, 0x47, 0xAE, 0xBB, 0x6F, + 0xB7, 0x1E, 0x91, 0x38, 0x64, 0x09 + } +}; + +/* the x9.62 prime curves (minus the nist prime curves) */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 24 * 6]; +} _EC_X9_62_PRIME_192V2 = { + { + NID_X9_62_prime_field, 20, 24, 1 + }, + { + /* seed */ + 0x31, 0xA9, 0x2E, 0xE2, 0x02, 0x9F, 0xD1, 0x0D, 0x90, 0x1B, 0x11, 0x3E, + 0x99, 0x07, 0x10, 0xF0, 0xD2, 0x1A, 0xC6, 0xB6, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0xCC, 0x22, 0xD6, 0xDF, 0xB9, 0x5C, 0x6B, 0x25, 0xE4, 0x9C, 0x0D, 0x63, + 0x64, 0xA4, 0xE5, 0x98, 0x0C, 0x39, 0x3A, 0xA2, 0x16, 0x68, 0xD9, 0x53, + /* x */ + 0xEE, 0xA2, 0xBA, 0xE7, 0xE1, 0x49, 0x78, 0x42, 0xF2, 0xDE, 0x77, 0x69, + 0xCF, 0xE9, 0xC9, 0x89, 0xC0, 0x72, 0xAD, 0x69, 0x6F, 0x48, 0x03, 0x4A, + /* y */ + 0x65, 0x74, 0xd1, 0x1d, 0x69, 0xb6, 0xec, 0x7a, 0x67, 0x2b, 0xb8, 0x2a, + 0x08, 0x3d, 0xf2, 0xf2, 0xb0, 0x84, 0x7d, 0xe9, 0x70, 0xb2, 0xde, 0x15, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x5F, 0xB1, 0xA7, 0x24, 0xDC, 0x80, 0x41, 0x86, 0x48, 0xD8, 0xDD, 0x31 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 24 * 6]; +} _EC_X9_62_PRIME_192V3 = { + { + NID_X9_62_prime_field, 20, 24, 1 + }, + { + /* seed */ + 0xC4, 0x69, 0x68, 0x44, 0x35, 0xDE, 0xB3, 0x78, 0xC4, 0xB6, 0x5C, 0xA9, + 0x59, 0x1E, 0x2A, 0x57, 0x63, 0x05, 0x9A, 0x2E, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x22, 0x12, 0x3D, 0xC2, 0x39, 0x5A, 0x05, 0xCA, 0xA7, 0x42, 0x3D, 0xAE, + 0xCC, 0xC9, 0x47, 0x60, 0xA7, 0xD4, 0x62, 0x25, 0x6B, 0xD5, 0x69, 0x16, + /* x */ + 0x7D, 0x29, 0x77, 0x81, 0x00, 0xC6, 0x5A, 0x1D, 0xA1, 0x78, 0x37, 0x16, + 0x58, 0x8D, 0xCE, 0x2B, 0x8B, 0x4A, 0xEE, 0x8E, 0x22, 0x8F, 0x18, 0x96, + /* y */ + 0x38, 0xa9, 0x0f, 0x22, 0x63, 0x73, 0x37, 0x33, 0x4b, 0x49, 0xdc, 0xb6, + 0x6a, 0x6d, 0xc8, 0xf9, 0x97, 0x8a, 0xca, 0x76, 0x48, 0xa9, 0x43, 0xb0, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7A, 0x62, 0xD0, 0x31, 0xC8, 0x3F, 0x42, 0x94, 0xF6, 0x40, 0xEC, 0x13 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 30 * 6]; +} _EC_X9_62_PRIME_239V1 = { + { + NID_X9_62_prime_field, 20, 30, 1 + }, + { + /* seed */ + 0xE4, 0x3B, 0xB4, 0x60, 0xF0, 0xB8, 0x0C, 0xC0, 0xC0, 0xB0, 0x75, 0x79, + 0x8E, 0x94, 0x80, 0x60, 0xF8, 0x32, 0x1B, 0x7D, + /* p */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x6B, 0x01, 0x6C, 0x3B, 0xDC, 0xF1, 0x89, 0x41, 0xD0, 0xD6, 0x54, 0x92, + 0x14, 0x75, 0xCA, 0x71, 0xA9, 0xDB, 0x2F, 0xB2, 0x7D, 0x1D, 0x37, 0x79, + 0x61, 0x85, 0xC2, 0x94, 0x2C, 0x0A, + /* x */ + 0x0F, 0xFA, 0x96, 0x3C, 0xDC, 0xA8, 0x81, 0x6C, 0xCC, 0x33, 0xB8, 0x64, + 0x2B, 0xED, 0xF9, 0x05, 0xC3, 0xD3, 0x58, 0x57, 0x3D, 0x3F, 0x27, 0xFB, + 0xBD, 0x3B, 0x3C, 0xB9, 0xAA, 0xAF, + /* y */ + 0x7d, 0xeb, 0xe8, 0xe4, 0xe9, 0x0a, 0x5d, 0xae, 0x6e, 0x40, 0x54, 0xca, + 0x53, 0x0b, 0xa0, 0x46, 0x54, 0xb3, 0x68, 0x18, 0xce, 0x22, 0x6b, 0x39, + 0xfc, 0xcb, 0x7b, 0x02, 0xf1, 0xae, + /* order */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0x9E, 0x5E, 0x9A, 0x9F, 0x5D, 0x90, 0x71, 0xFB, 0xD1, + 0x52, 0x26, 0x88, 0x90, 0x9D, 0x0B + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 30 * 6]; +} _EC_X9_62_PRIME_239V2 = { + { + NID_X9_62_prime_field, 20, 30, 1 + }, + { + /* seed */ + 0xE8, 0xB4, 0x01, 0x16, 0x04, 0x09, 0x53, 0x03, 0xCA, 0x3B, 0x80, 0x99, + 0x98, 0x2B, 0xE0, 0x9F, 0xCB, 0x9A, 0xE6, 0x16, + /* p */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x61, 0x7F, 0xAB, 0x68, 0x32, 0x57, 0x6C, 0xBB, 0xFE, 0xD5, 0x0D, 0x99, + 0xF0, 0x24, 0x9C, 0x3F, 0xEE, 0x58, 0xB9, 0x4B, 0xA0, 0x03, 0x8C, 0x7A, + 0xE8, 0x4C, 0x8C, 0x83, 0x2F, 0x2C, + /* x */ + 0x38, 0xAF, 0x09, 0xD9, 0x87, 0x27, 0x70, 0x51, 0x20, 0xC9, 0x21, 0xBB, + 0x5E, 0x9E, 0x26, 0x29, 0x6A, 0x3C, 0xDC, 0xF2, 0xF3, 0x57, 0x57, 0xA0, + 0xEA, 0xFD, 0x87, 0xB8, 0x30, 0xE7, + /* y */ + 0x5b, 0x01, 0x25, 0xe4, 0xdb, 0xea, 0x0e, 0xc7, 0x20, 0x6d, 0xa0, 0xfc, + 0x01, 0xd9, 0xb0, 0x81, 0x32, 0x9f, 0xb5, 0x55, 0xde, 0x6e, 0xf4, 0x60, + 0x23, 0x7d, 0xff, 0x8b, 0xe4, 0xba, + /* order */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x80, 0x00, 0x00, 0xCF, 0xA7, 0xE8, 0x59, 0x43, 0x77, 0xD4, 0x14, 0xC0, + 0x38, 0x21, 0xBC, 0x58, 0x20, 0x63 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 30 * 6]; +} _EC_X9_62_PRIME_239V3 = { + { + NID_X9_62_prime_field, 20, 30, 1 + }, + { + /* seed */ + 0x7D, 0x73, 0x74, 0x16, 0x8F, 0xFE, 0x34, 0x71, 0xB6, 0x0A, 0x85, 0x76, + 0x86, 0xA1, 0x94, 0x75, 0xD3, 0xBF, 0xA2, 0xFF, + /* p */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x25, 0x57, 0x05, 0xFA, 0x2A, 0x30, 0x66, 0x54, 0xB1, 0xF4, 0xCB, 0x03, + 0xD6, 0xA7, 0x50, 0xA3, 0x0C, 0x25, 0x01, 0x02, 0xD4, 0x98, 0x87, 0x17, + 0xD9, 0xBA, 0x15, 0xAB, 0x6D, 0x3E, + /* x */ + 0x67, 0x68, 0xAE, 0x8E, 0x18, 0xBB, 0x92, 0xCF, 0xCF, 0x00, 0x5C, 0x94, + 0x9A, 0xA2, 0xC6, 0xD9, 0x48, 0x53, 0xD0, 0xE6, 0x60, 0xBB, 0xF8, 0x54, + 0xB1, 0xC9, 0x50, 0x5F, 0xE9, 0x5A, + /* y */ + 0x16, 0x07, 0xe6, 0x89, 0x8f, 0x39, 0x0c, 0x06, 0xbc, 0x1d, 0x55, 0x2b, + 0xad, 0x22, 0x6f, 0x3b, 0x6f, 0xcf, 0xe4, 0x8b, 0x6e, 0x81, 0x84, 0x99, + 0xaf, 0x18, 0xe3, 0xed, 0x6c, 0xf3, + /* order */ + 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0x7F, 0xFF, 0xFF, 0x97, 0x5D, 0xEB, 0x41, 0xB3, 0xA6, 0x05, 0x7C, 0x3C, + 0x43, 0x21, 0x46, 0x52, 0x65, 0x51 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 32 * 6]; +} _EC_X9_62_PRIME_256V1 = { + { + NID_X9_62_prime_field, 20, 32, 1 + }, + { + /* seed */ + 0xC4, 0x9D, 0x36, 0x08, 0x86, 0xE7, 0x04, 0x93, 0x6A, 0x66, 0x78, 0xE1, + 0x13, 0x9D, 0x26, 0xB7, 0x81, 0x9F, 0x7E, 0x90, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0x5A, 0xC6, 0x35, 0xD8, 0xAA, 0x3A, 0x93, 0xE7, 0xB3, 0xEB, 0xBD, 0x55, + 0x76, 0x98, 0x86, 0xBC, 0x65, 0x1D, 0x06, 0xB0, 0xCC, 0x53, 0xB0, 0xF6, + 0x3B, 0xCE, 0x3C, 0x3E, 0x27, 0xD2, 0x60, 0x4B, + /* x */ + 0x6B, 0x17, 0xD1, 0xF2, 0xE1, 0x2C, 0x42, 0x47, 0xF8, 0xBC, 0xE6, 0xE5, + 0x63, 0xA4, 0x40, 0xF2, 0x77, 0x03, 0x7D, 0x81, 0x2D, 0xEB, 0x33, 0xA0, + 0xF4, 0xA1, 0x39, 0x45, 0xD8, 0x98, 0xC2, 0x96, + /* y */ + 0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, 0x8e, 0xe7, 0xeb, 0x4a, + 0x7c, 0x0f, 0x9e, 0x16, 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, + 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, + 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 + } +}; + +/* the secg prime curves (minus the nist and x9.62 prime curves) */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 14 * 6]; +} _EC_SECG_PRIME_112R1 = { + { + NID_X9_62_prime_field, 20, 14, 1 + }, + { + /* seed */ + 0x00, 0xF5, 0x0B, 0x02, 0x8E, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, + 0x51, 0x75, 0x29, 0x04, 0x72, 0x78, 0x3F, 0xB1, + /* p */ + 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, + 0x20, 0x8B, + /* a */ + 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, + 0x20, 0x88, + /* b */ + 0x65, 0x9E, 0xF8, 0xBA, 0x04, 0x39, 0x16, 0xEE, 0xDE, 0x89, 0x11, 0x70, + 0x2B, 0x22, + /* x */ + 0x09, 0x48, 0x72, 0x39, 0x99, 0x5A, 0x5E, 0xE7, 0x6B, 0x55, 0xF9, 0xC2, + 0xF0, 0x98, + /* y */ + 0xa8, 0x9c, 0xe5, 0xaf, 0x87, 0x24, 0xc0, 0xa2, 0x3e, 0x0e, 0x0f, 0xf7, + 0x75, 0x00, + /* order */ + 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x76, 0x28, 0xDF, 0xAC, 0x65, + 0x61, 0xC5 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 14 * 6]; +} _EC_SECG_PRIME_112R2 = { + { + NID_X9_62_prime_field, 20, 14, 4 + }, + { + /* seed */ + 0x00, 0x27, 0x57, 0xA1, 0x11, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, + 0x51, 0x75, 0x53, 0x16, 0xC0, 0x5E, 0x0B, 0xD4, + /* p */ + 0xDB, 0x7C, 0x2A, 0xBF, 0x62, 0xE3, 0x5E, 0x66, 0x80, 0x76, 0xBE, 0xAD, + 0x20, 0x8B, + /* a */ + 0x61, 0x27, 0xC2, 0x4C, 0x05, 0xF3, 0x8A, 0x0A, 0xAA, 0xF6, 0x5C, 0x0E, + 0xF0, 0x2C, + /* b */ + 0x51, 0xDE, 0xF1, 0x81, 0x5D, 0xB5, 0xED, 0x74, 0xFC, 0xC3, 0x4C, 0x85, + 0xD7, 0x09, + /* x */ + 0x4B, 0xA3, 0x0A, 0xB5, 0xE8, 0x92, 0xB4, 0xE1, 0x64, 0x9D, 0xD0, 0x92, + 0x86, 0x43, + /* y */ + 0xad, 0xcd, 0x46, 0xf5, 0x88, 0x2e, 0x37, 0x47, 0xde, 0xf3, 0x6e, 0x95, + 0x6e, 0x97, + /* order */ + 0x36, 0xDF, 0x0A, 0xAF, 0xD8, 0xB8, 0xD7, 0x59, 0x7C, 0xA1, 0x05, 0x20, + 0xD0, 0x4B + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 16 * 6]; +} _EC_SECG_PRIME_128R1 = { + { + NID_X9_62_prime_field, 20, 16, 1 + }, + { + /* seed */ + 0x00, 0x0E, 0x0D, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, + 0x0C, 0xC0, 0x3A, 0x44, 0x73, 0xD0, 0x36, 0x79, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFC, + /* b */ + 0xE8, 0x75, 0x79, 0xC1, 0x10, 0x79, 0xF4, 0x3D, 0xD8, 0x24, 0x99, 0x3C, + 0x2C, 0xEE, 0x5E, 0xD3, + /* x */ + 0x16, 0x1F, 0xF7, 0x52, 0x8B, 0x89, 0x9B, 0x2D, 0x0C, 0x28, 0x60, 0x7C, + 0xA5, 0x2C, 0x5B, 0x86, + /* y */ + 0xcf, 0x5a, 0xc8, 0x39, 0x5b, 0xaf, 0xeb, 0x13, 0xc0, 0x2d, 0xa2, 0x92, + 0xdd, 0xed, 0x7a, 0x83, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFE, 0x00, 0x00, 0x00, 0x00, 0x75, 0xA3, 0x0D, 0x1B, + 0x90, 0x38, 0xA1, 0x15 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 16 * 6]; +} _EC_SECG_PRIME_128R2 = { + { + NID_X9_62_prime_field, 20, 16, 4 + }, + { + /* seed */ + 0x00, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, 0x12, 0xD8, + 0xF0, 0x34, 0x31, 0xFC, 0xE6, 0x3B, 0x88, 0xF4, + /* p */ + 0xFF, 0xFF, 0xFF, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, + /* a */ + 0xD6, 0x03, 0x19, 0x98, 0xD1, 0xB3, 0xBB, 0xFE, 0xBF, 0x59, 0xCC, 0x9B, + 0xBF, 0xF9, 0xAE, 0xE1, + /* b */ + 0x5E, 0xEE, 0xFC, 0xA3, 0x80, 0xD0, 0x29, 0x19, 0xDC, 0x2C, 0x65, 0x58, + 0xBB, 0x6D, 0x8A, 0x5D, + /* x */ + 0x7B, 0x6A, 0xA5, 0xD8, 0x5E, 0x57, 0x29, 0x83, 0xE6, 0xFB, 0x32, 0xA7, + 0xCD, 0xEB, 0xC1, 0x40, + /* y */ + 0x27, 0xb6, 0x91, 0x6a, 0x89, 0x4d, 0x3a, 0xee, 0x71, 0x06, 0xfe, 0x80, + 0x5f, 0xc3, 0x4b, 0x44, + /* order */ + 0x3F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xBE, 0x00, 0x24, 0x72, + 0x06, 0x13, 0xB5, 0xA3 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 21 * 6]; +} _EC_SECG_PRIME_160K1 = { + { + NID_X9_62_prime_field, 0, 21, 1 + }, + { + /* no seed */ + /* p */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x73, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + /* x */ + 0x00, 0x3B, 0x4C, 0x38, 0x2C, 0xE3, 0x7A, 0xA1, 0x92, 0xA4, 0x01, 0x9E, + 0x76, 0x30, 0x36, 0xF4, 0xF5, 0xDD, 0x4D, 0x7E, 0xBB, + /* y */ + 0x00, 0x93, 0x8c, 0xf9, 0x35, 0x31, 0x8f, 0xdc, 0xed, 0x6b, 0xc2, 0x82, + 0x86, 0x53, 0x17, 0x33, 0xc3, 0xf0, 0x3c, 0x4f, 0xee, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xB8, + 0xFA, 0x16, 0xDF, 0xAB, 0x9A, 0xCA, 0x16, 0xB6, 0xB3 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 21 * 6]; +} _EC_SECG_PRIME_160R1 = { + { + NID_X9_62_prime_field, 20, 21, 1 + }, + { + /* seed */ + 0x10, 0x53, 0xCD, 0xE4, 0x2C, 0x14, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x53, 0x3B, 0xF3, 0xF8, 0x33, 0x45, + /* p */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, + /* a */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFC, + /* b */ + 0x00, 0x1C, 0x97, 0xBE, 0xFC, 0x54, 0xBD, 0x7A, 0x8B, 0x65, 0xAC, 0xF8, + 0x9F, 0x81, 0xD4, 0xD4, 0xAD, 0xC5, 0x65, 0xFA, 0x45, + /* x */ + 0x00, 0x4A, 0x96, 0xB5, 0x68, 0x8E, 0xF5, 0x73, 0x28, 0x46, 0x64, 0x69, + 0x89, 0x68, 0xC3, 0x8B, 0xB9, 0x13, 0xCB, 0xFC, 0x82, + /* y */ + 0x00, 0x23, 0xa6, 0x28, 0x55, 0x31, 0x68, 0x94, 0x7d, 0x59, 0xdc, 0xc9, + 0x12, 0x04, 0x23, 0x51, 0x37, 0x7a, 0xc5, 0xfb, 0x32, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xF4, + 0xC8, 0xF9, 0x27, 0xAE, 0xD3, 0xCA, 0x75, 0x22, 0x57 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 21 * 6]; +} _EC_SECG_PRIME_160R2 = { + { + NID_X9_62_prime_field, 20, 21, 1 + }, + { + /* seed */ + 0xB9, 0x9B, 0x99, 0xB0, 0x99, 0xB3, 0x23, 0xE0, 0x27, 0x09, 0xA4, 0xD6, + 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x51, + /* p */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x73, + /* a */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xAC, 0x70, + /* b */ + 0x00, 0xB4, 0xE1, 0x34, 0xD3, 0xFB, 0x59, 0xEB, 0x8B, 0xAB, 0x57, 0x27, + 0x49, 0x04, 0x66, 0x4D, 0x5A, 0xF5, 0x03, 0x88, 0xBA, + /* x */ + 0x00, 0x52, 0xDC, 0xB0, 0x34, 0x29, 0x3A, 0x11, 0x7E, 0x1F, 0x4F, 0xF1, + 0x1B, 0x30, 0xF7, 0x19, 0x9D, 0x31, 0x44, 0xCE, 0x6D, + /* y */ + 0x00, 0xfe, 0xaf, 0xfe, 0xf2, 0xe3, 0x31, 0xf2, 0x96, 0xe0, 0x71, 0xfa, + 0x0d, 0xf9, 0x98, 0x2c, 0xfe, 0xa7, 0xd4, 0x3f, 0x2e, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, + 0x1E, 0xE7, 0x86, 0xA8, 0x18, 0xF3, 0xA1, 0xA1, 0x6B + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 24 * 6]; +} _EC_SECG_PRIME_192K1 = { + { + NID_X9_62_prime_field, 0, 24, 1 + }, + { + /* no seed */ + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xEE, 0x37, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + /* x */ + 0xDB, 0x4F, 0xF1, 0x0E, 0xC0, 0x57, 0xE9, 0xAE, 0x26, 0xB0, 0x7D, 0x02, + 0x80, 0xB7, 0xF4, 0x34, 0x1D, 0xA5, 0xD1, 0xB1, 0xEA, 0xE0, 0x6C, 0x7D, + /* y */ + 0x9b, 0x2f, 0x2f, 0x6d, 0x9c, 0x56, 0x28, 0xa7, 0x84, 0x41, 0x63, 0xd0, + 0x15, 0xbe, 0x86, 0x34, 0x40, 0x82, 0xaa, 0x88, 0xd9, 0x5e, 0x2f, 0x9d, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, + 0x26, 0xF2, 0xFC, 0x17, 0x0F, 0x69, 0x46, 0x6A, 0x74, 0xDE, 0xFD, 0x8D + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 29 * 6]; +} _EC_SECG_PRIME_224K1 = { + { + NID_X9_62_prime_field, 0, 29, 1 + }, + { + /* no seed */ + /* p */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFE, 0xFF, 0xFF, 0xE5, 0x6D, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x05, + /* x */ + 0x00, 0xA1, 0x45, 0x5B, 0x33, 0x4D, 0xF0, 0x99, 0xDF, 0x30, 0xFC, 0x28, + 0xA1, 0x69, 0xA4, 0x67, 0xE9, 0xE4, 0x70, 0x75, 0xA9, 0x0F, 0x7E, 0x65, + 0x0E, 0xB6, 0xB7, 0xA4, 0x5C, + /* y */ + 0x00, 0x7e, 0x08, 0x9f, 0xed, 0x7f, 0xba, 0x34, 0x42, 0x82, 0xca, 0xfb, + 0xd6, 0xf7, 0xe3, 0x19, 0xf7, 0xc0, 0xb0, 0xbd, 0x59, 0xe2, 0xca, 0x4b, + 0xdb, 0x55, 0x6d, 0x61, 0xa5, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xDC, 0xE8, 0xD2, 0xEC, 0x61, 0x84, 0xCA, 0xF0, 0xA9, + 0x71, 0x76, 0x9F, 0xB1, 0xF7 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 32 * 6]; +} _EC_SECG_PRIME_256K1 = { + { + NID_X9_62_prime_field, 0, 32, 1 + }, + { + /* no seed */ + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFC, 0x2F, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + /* x */ + 0x79, 0xBE, 0x66, 0x7E, 0xF9, 0xDC, 0xBB, 0xAC, 0x55, 0xA0, 0x62, 0x95, + 0xCE, 0x87, 0x0B, 0x07, 0x02, 0x9B, 0xFC, 0xDB, 0x2D, 0xCE, 0x28, 0xD9, + 0x59, 0xF2, 0x81, 0x5B, 0x16, 0xF8, 0x17, 0x98, + /* y */ + 0x48, 0x3a, 0xda, 0x77, 0x26, 0xa3, 0xc4, 0x65, 0x5d, 0xa4, 0xfb, 0xfc, + 0x0e, 0x11, 0x08, 0xa8, 0xfd, 0x17, 0xb4, 0x48, 0xa6, 0x85, 0x54, 0x19, + 0x9c, 0x47, 0xd0, 0x8f, 0xfb, 0x10, 0xd4, 0xb8, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xBA, 0xAE, 0xDC, 0xE6, 0xAF, 0x48, 0xA0, 0x3B, + 0xBF, 0xD2, 0x5E, 0x8C, 0xD0, 0x36, 0x41, 0x41 + } +}; + +/* some wap/wtls curves */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 15 * 6]; +} _EC_WTLS_8 = { + { + NID_X9_62_prime_field, 0, 15, 1 + }, + { + /* no seed */ + /* p */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFD, 0xE7, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x03, + /* x */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, + /* y */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x02, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xEC, 0xEA, 0x55, 0x1A, + 0xD8, 0x37, 0xE9 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 21 * 6]; +} _EC_WTLS_9 = { + { + NID_X9_62_prime_field, 0, 21, 1 + }, + { + /* no seed */ + /* p */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFC, 0x80, 0x8F, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, + /* x */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* y */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xCD, + 0xC9, 0x8A, 0xE0, 0xE2, 0xDE, 0x57, 0x4A, 0xBF, 0x33 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 28 * 6]; +} _EC_WTLS_12 = { + { + NID_X9_62_prime_field, 0, 28, 1 + }, + { + /* no seed */ + /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFE, + /* b */ + 0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, 0x32, 0x56, + 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, 0x27, 0x0B, 0x39, 0x43, + 0x23, 0x55, 0xFF, 0xB4, + /* x */ + 0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, 0x90, 0xB9, + 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, 0x34, 0x32, 0x80, 0xD6, + 0x11, 0x5C, 0x1D, 0x21, + /* y */ + 0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, 0xdf, 0xe6, + 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, 0x44, 0xd5, 0x81, 0x99, + 0x85, 0x00, 0x7e, 0x34, + /* order */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0x16, 0xA2, 0xE0, 0xB8, 0xF0, 0x3E, 0x13, 0xDD, 0x29, 0x45, + 0x5C, 0x5C, 0x2A, 0x3D + } +}; + +#ifndef OPENSSL_NO_EC2M + +/* characteristic two curves */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 15 * 6]; +} _EC_SECG_CHAR2_113R1 = { + { + NID_X9_62_characteristic_two_field, 20, 15, 2 + }, + { + /* seed */ + 0x10, 0xE7, 0x23, 0xAB, 0x14, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, + 0x17, 0x56, 0xFE, 0xBF, 0x8F, 0xCB, 0x49, 0xA9, + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x01, + /* a */ + 0x00, 0x30, 0x88, 0x25, 0x0C, 0xA6, 0xE7, 0xC7, 0xFE, 0x64, 0x9C, 0xE8, + 0x58, 0x20, 0xF7, + /* b */ + 0x00, 0xE8, 0xBE, 0xE4, 0xD3, 0xE2, 0x26, 0x07, 0x44, 0x18, 0x8B, 0xE0, + 0xE9, 0xC7, 0x23, + /* x */ + 0x00, 0x9D, 0x73, 0x61, 0x6F, 0x35, 0xF4, 0xAB, 0x14, 0x07, 0xD7, 0x35, + 0x62, 0xC1, 0x0F, + /* y */ + 0x00, 0xA5, 0x28, 0x30, 0x27, 0x79, 0x58, 0xEE, 0x84, 0xD1, 0x31, 0x5E, + 0xD3, 0x18, 0x86, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD9, 0xCC, 0xEC, 0x8A, + 0x39, 0xE5, 0x6F + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 15 * 6]; +} _EC_SECG_CHAR2_113R2 = { + { + NID_X9_62_characteristic_two_field, 20, 15, 2 + }, + { + /* seed */ + 0x10, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE, 0xF4, 0xD6, + 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x5D, + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x01, + /* a */ + 0x00, 0x68, 0x99, 0x18, 0xDB, 0xEC, 0x7E, 0x5A, 0x0D, 0xD6, 0xDF, 0xC0, + 0xAA, 0x55, 0xC7, + /* b */ + 0x00, 0x95, 0xE9, 0xA9, 0xEC, 0x9B, 0x29, 0x7B, 0xD4, 0xBF, 0x36, 0xE0, + 0x59, 0x18, 0x4F, + /* x */ + 0x01, 0xA5, 0x7A, 0x6A, 0x7B, 0x26, 0xCA, 0x5E, 0xF5, 0x2F, 0xCD, 0xB8, + 0x16, 0x47, 0x97, + /* y */ + 0x00, 0xB3, 0xAD, 0xC9, 0x4E, 0xD1, 0xFE, 0x67, 0x4C, 0x06, 0xE6, 0x95, + 0xBA, 0xBA, 0x1D, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x08, 0x78, 0x9B, 0x24, + 0x96, 0xAF, 0x93 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 17 * 6]; +} _EC_SECG_CHAR2_131R1 = { + { + NID_X9_62_characteristic_two_field, 20, 17, 2 + }, + { + /* seed */ + 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, 0x98, 0x5B, 0xD3, + 0xAD, 0xBA, 0xDA, 0x21, 0xB4, 0x3A, 0x97, 0xE2, + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x0D, + /* a */ + 0x07, 0xA1, 0x1B, 0x09, 0xA7, 0x6B, 0x56, 0x21, 0x44, 0x41, 0x8F, 0xF3, + 0xFF, 0x8C, 0x25, 0x70, 0xB8, + /* b */ + 0x02, 0x17, 0xC0, 0x56, 0x10, 0x88, 0x4B, 0x63, 0xB9, 0xC6, 0xC7, 0x29, + 0x16, 0x78, 0xF9, 0xD3, 0x41, + /* x */ + 0x00, 0x81, 0xBA, 0xF9, 0x1F, 0xDF, 0x98, 0x33, 0xC4, 0x0F, 0x9C, 0x18, + 0x13, 0x43, 0x63, 0x83, 0x99, + /* y */ + 0x07, 0x8C, 0x6E, 0x7E, 0xA3, 0x8C, 0x00, 0x1F, 0x73, 0xC8, 0x13, 0x4B, + 0x1B, 0x4E, 0xF9, 0xE1, 0x50, + /* order */ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x31, 0x23, 0x95, + 0x3A, 0x94, 0x64, 0xB5, 0x4D + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 17 * 6]; +} _EC_SECG_CHAR2_131R2 = { + { + NID_X9_62_characteristic_two_field, 20, 17, 2 + }, + { + /* seed */ + 0x98, 0x5B, 0xD3, 0xAD, 0xBA, 0xD4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x5A, 0x21, 0xB4, 0x3A, 0x97, 0xE3, + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x0D, + /* a */ + 0x03, 0xE5, 0xA8, 0x89, 0x19, 0xD7, 0xCA, 0xFC, 0xBF, 0x41, 0x5F, 0x07, + 0xC2, 0x17, 0x65, 0x73, 0xB2, + /* b */ + 0x04, 0xB8, 0x26, 0x6A, 0x46, 0xC5, 0x56, 0x57, 0xAC, 0x73, 0x4C, 0xE3, + 0x8F, 0x01, 0x8F, 0x21, 0x92, + /* x */ + 0x03, 0x56, 0xDC, 0xD8, 0xF2, 0xF9, 0x50, 0x31, 0xAD, 0x65, 0x2D, 0x23, + 0x95, 0x1B, 0xB3, 0x66, 0xA8, + /* y */ + 0x06, 0x48, 0xF0, 0x6D, 0x86, 0x79, 0x40, 0xA5, 0x36, 0x6D, 0x9E, 0x26, + 0x5D, 0xE9, 0xEB, 0x24, 0x0F, + /* order */ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x69, 0x54, 0xA2, + 0x33, 0x04, 0x9B, 0xA9, 0x8F + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 21 * 6]; +} _EC_NIST_CHAR2_163K = { + { + NID_X9_62_characteristic_two_field, 0, 21, 2 + }, + { + /* no seed */ + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* x */ + 0x02, 0xFE, 0x13, 0xC0, 0x53, 0x7B, 0xBC, 0x11, 0xAC, 0xAA, 0x07, 0xD7, + 0x93, 0xDE, 0x4E, 0x6D, 0x5E, 0x5C, 0x94, 0xEE, 0xE8, + /* y */ + 0x02, 0x89, 0x07, 0x0F, 0xB0, 0x5D, 0x38, 0xFF, 0x58, 0x32, 0x1F, 0x2E, + 0x80, 0x05, 0x36, 0xD5, 0x38, 0xCC, 0xDA, 0xA3, 0xD9, + /* order */ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, + 0x08, 0xA2, 0xE0, 0xCC, 0x0D, 0x99, 0xF8, 0xA5, 0xEF + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 21 * 6]; +} _EC_SECG_CHAR2_163R1 = { + { + NID_X9_62_characteristic_two_field, 0, 21, 2 + }, + { + /* no seed */ +# if 0 + /* + * The algorithm used to derive the curve parameters from the seed + * used here is slightly different than the algorithm described in + * X9.62 . + */ + 0x24, 0xB7, 0xB1, 0x37, 0xC8, 0xA1, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, + 0x61, 0x51, 0x75, 0x6F, 0xD0, 0xDA, 0x2E, 0x5C, +# endif + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, + /* a */ + 0x07, 0xB6, 0x88, 0x2C, 0xAA, 0xEF, 0xA8, 0x4F, 0x95, 0x54, 0xFF, 0x84, + 0x28, 0xBD, 0x88, 0xE2, 0x46, 0xD2, 0x78, 0x2A, 0xE2, + /* b */ + 0x07, 0x13, 0x61, 0x2D, 0xCD, 0xDC, 0xB4, 0x0A, 0xAB, 0x94, 0x6B, 0xDA, + 0x29, 0xCA, 0x91, 0xF7, 0x3A, 0xF9, 0x58, 0xAF, 0xD9, + /* x */ + 0x03, 0x69, 0x97, 0x96, 0x97, 0xAB, 0x43, 0x89, 0x77, 0x89, 0x56, 0x67, + 0x89, 0x56, 0x7F, 0x78, 0x7A, 0x78, 0x76, 0xA6, 0x54, + /* y */ + 0x00, 0x43, 0x5E, 0xDB, 0x42, 0xEF, 0xAF, 0xB2, 0x98, 0x9D, 0x51, 0xFE, + 0xFC, 0xE3, 0xC8, 0x09, 0x88, 0xF4, 0x1F, 0xF8, 0x83, + /* order */ + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x48, + 0xAA, 0xB6, 0x89, 0xC2, 0x9C, 0xA7, 0x10, 0x27, 0x9B + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 21 * 6]; +} _EC_NIST_CHAR2_163B = { + { + NID_X9_62_characteristic_two_field, 0, 21, 2 + }, + { + /* no seed */ +# if 0 + /* + * The seed here was used to created the curve parameters in normal + * basis representation (and not the polynomial representation used + * here) + */ + 0x85, 0xE2, 0x5B, 0xFE, 0x5C, 0x86, 0x22, 0x6C, 0xDB, 0x12, 0x01, 0x6F, + 0x75, 0x53, 0xF9, 0xD0, 0xE6, 0x93, 0xA2, 0x68, +# endif + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC9, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* b */ + 0x02, 0x0A, 0x60, 0x19, 0x07, 0xB8, 0xC9, 0x53, 0xCA, 0x14, 0x81, 0xEB, + 0x10, 0x51, 0x2F, 0x78, 0x74, 0x4A, 0x32, 0x05, 0xFD, + /* x */ + 0x03, 0xF0, 0xEB, 0xA1, 0x62, 0x86, 0xA2, 0xD5, 0x7E, 0xA0, 0x99, 0x11, + 0x68, 0xD4, 0x99, 0x46, 0x37, 0xE8, 0x34, 0x3E, 0x36, + /* y */ + 0x00, 0xD5, 0x1F, 0xBC, 0x6C, 0x71, 0xA0, 0x09, 0x4F, 0xA2, 0xCD, 0xD5, + 0x45, 0xB1, 0x1C, 0x5C, 0x0C, 0x79, 0x73, 0x24, 0xF1, + /* order */ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x92, + 0xFE, 0x77, 0xE7, 0x0C, 0x12, 0xA4, 0x23, 0x4C, 0x33 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 25 * 6]; +} _EC_SECG_CHAR2_193R1 = { + { + NID_X9_62_characteristic_two_field, 20, 25, 2 + }, + { + /* seed */ + 0x10, 0x3F, 0xAE, 0xC7, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, + 0x75, 0x77, 0x7F, 0xC5, 0xB1, 0x91, 0xEF, 0x30, + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x01, + /* a */ + 0x00, 0x17, 0x85, 0x8F, 0xEB, 0x7A, 0x98, 0x97, 0x51, 0x69, 0xE1, 0x71, + 0xF7, 0x7B, 0x40, 0x87, 0xDE, 0x09, 0x8A, 0xC8, 0xA9, 0x11, 0xDF, 0x7B, + 0x01, + /* b */ + 0x00, 0xFD, 0xFB, 0x49, 0xBF, 0xE6, 0xC3, 0xA8, 0x9F, 0xAC, 0xAD, 0xAA, + 0x7A, 0x1E, 0x5B, 0xBC, 0x7C, 0xC1, 0xC2, 0xE5, 0xD8, 0x31, 0x47, 0x88, + 0x14, + /* x */ + 0x01, 0xF4, 0x81, 0xBC, 0x5F, 0x0F, 0xF8, 0x4A, 0x74, 0xAD, 0x6C, 0xDF, + 0x6F, 0xDE, 0xF4, 0xBF, 0x61, 0x79, 0x62, 0x53, 0x72, 0xD8, 0xC0, 0xC5, + 0xE1, + /* y */ + 0x00, 0x25, 0xE3, 0x99, 0xF2, 0x90, 0x37, 0x12, 0xCC, 0xF3, 0xEA, 0x9E, + 0x3A, 0x1A, 0xD1, 0x7F, 0xB0, 0xB3, 0x20, 0x1B, 0x6A, 0xF7, 0xCE, 0x1B, + 0x05, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0xC7, 0xF3, 0x4A, 0x77, 0x8F, 0x44, 0x3A, 0xCC, 0x92, 0x0E, 0xBA, + 0x49 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 25 * 6]; +} _EC_SECG_CHAR2_193R2 = { + { + NID_X9_62_characteristic_two_field, 20, 25, 2 + }, + { + /* seed */ + 0x10, 0xB7, 0xB4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x51, + 0x37, 0xC8, 0xA1, 0x6F, 0xD0, 0xDA, 0x22, 0x11, + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, + 0x01, + /* a */ + 0x01, 0x63, 0xF3, 0x5A, 0x51, 0x37, 0xC2, 0xCE, 0x3E, 0xA6, 0xED, 0x86, + 0x67, 0x19, 0x0B, 0x0B, 0xC4, 0x3E, 0xCD, 0x69, 0x97, 0x77, 0x02, 0x70, + 0x9B, + /* b */ + 0x00, 0xC9, 0xBB, 0x9E, 0x89, 0x27, 0xD4, 0xD6, 0x4C, 0x37, 0x7E, 0x2A, + 0xB2, 0x85, 0x6A, 0x5B, 0x16, 0xE3, 0xEF, 0xB7, 0xF6, 0x1D, 0x43, 0x16, + 0xAE, + /* x */ + 0x00, 0xD9, 0xB6, 0x7D, 0x19, 0x2E, 0x03, 0x67, 0xC8, 0x03, 0xF3, 0x9E, + 0x1A, 0x7E, 0x82, 0xCA, 0x14, 0xA6, 0x51, 0x35, 0x0A, 0xAE, 0x61, 0x7E, + 0x8F, + /* y */ + 0x01, 0xCE, 0x94, 0x33, 0x56, 0x07, 0xC3, 0x04, 0xAC, 0x29, 0xE7, 0xDE, + 0xFB, 0xD9, 0xCA, 0x01, 0xF5, 0x96, 0xF9, 0x27, 0x22, 0x4C, 0xDE, 0xCF, + 0x6C, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x5A, 0xAB, 0x56, 0x1B, 0x00, 0x54, 0x13, 0xCC, 0xD4, 0xEE, 0x99, + 0xD5 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 30 * 6]; +} _EC_NIST_CHAR2_233K = { + { + NID_X9_62_characteristic_two_field, 0, 30, 4 + }, + { + /* no seed */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* x */ + 0x01, 0x72, 0x32, 0xBA, 0x85, 0x3A, 0x7E, 0x73, 0x1A, 0xF1, 0x29, 0xF2, + 0x2F, 0xF4, 0x14, 0x95, 0x63, 0xA4, 0x19, 0xC2, 0x6B, 0xF5, 0x0A, 0x4C, + 0x9D, 0x6E, 0xEF, 0xAD, 0x61, 0x26, + /* y */ + 0x01, 0xDB, 0x53, 0x7D, 0xEC, 0xE8, 0x19, 0xB7, 0xF7, 0x0F, 0x55, 0x5A, + 0x67, 0xC4, 0x27, 0xA8, 0xCD, 0x9B, 0xF1, 0x8A, 0xEB, 0x9B, 0x56, 0xE0, + 0xC1, 0x10, 0x56, 0xFA, 0xE6, 0xA3, + /* order */ + 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x06, 0x9D, 0x5B, 0xB9, 0x15, 0xBC, 0xD4, 0x6E, 0xFB, + 0x1A, 0xD5, 0xF1, 0x73, 0xAB, 0xDF + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 30 * 6]; +} _EC_NIST_CHAR2_233B = { + { + NID_X9_62_characteristic_two_field, 20, 30, 2 + }, + { + /* seed */ + 0x74, 0xD5, 0x9F, 0xF0, 0x7F, 0x6B, 0x41, 0x3D, 0x0E, 0xA1, 0x4B, 0x34, + 0x4B, 0x20, 0xA2, 0xDB, 0x04, 0x9B, 0x50, 0xC3, + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* b */ + 0x00, 0x66, 0x64, 0x7E, 0xDE, 0x6C, 0x33, 0x2C, 0x7F, 0x8C, 0x09, 0x23, + 0xBB, 0x58, 0x21, 0x3B, 0x33, 0x3B, 0x20, 0xE9, 0xCE, 0x42, 0x81, 0xFE, + 0x11, 0x5F, 0x7D, 0x8F, 0x90, 0xAD, + /* x */ + 0x00, 0xFA, 0xC9, 0xDF, 0xCB, 0xAC, 0x83, 0x13, 0xBB, 0x21, 0x39, 0xF1, + 0xBB, 0x75, 0x5F, 0xEF, 0x65, 0xBC, 0x39, 0x1F, 0x8B, 0x36, 0xF8, 0xF8, + 0xEB, 0x73, 0x71, 0xFD, 0x55, 0x8B, + /* y */ + 0x01, 0x00, 0x6A, 0x08, 0xA4, 0x19, 0x03, 0x35, 0x06, 0x78, 0xE5, 0x85, + 0x28, 0xBE, 0xBF, 0x8A, 0x0B, 0xEF, 0xF8, 0x67, 0xA7, 0xCA, 0x36, 0x71, + 0x6F, 0x7E, 0x01, 0xF8, 0x10, 0x52, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x13, 0xE9, 0x74, 0xE7, 0x2F, 0x8A, 0x69, 0x22, 0x03, + 0x1D, 0x26, 0x03, 0xCF, 0xE0, 0xD7 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 30 * 6]; +} _EC_SECG_CHAR2_239K1 = { + { + NID_X9_62_characteristic_two_field, 0, 30, 4 + }, + { + /* no seed */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* x */ + 0x29, 0xA0, 0xB6, 0xA8, 0x87, 0xA9, 0x83, 0xE9, 0x73, 0x09, 0x88, 0xA6, + 0x87, 0x27, 0xA8, 0xB2, 0xD1, 0x26, 0xC4, 0x4C, 0xC2, 0xCC, 0x7B, 0x2A, + 0x65, 0x55, 0x19, 0x30, 0x35, 0xDC, + /* y */ + 0x76, 0x31, 0x08, 0x04, 0xF1, 0x2E, 0x54, 0x9B, 0xDB, 0x01, 0x1C, 0x10, + 0x30, 0x89, 0xE7, 0x35, 0x10, 0xAC, 0xB2, 0x75, 0xFC, 0x31, 0x2A, 0x5D, + 0xC6, 0xB7, 0x65, 0x53, 0xF0, 0xCA, + /* order */ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x5A, 0x79, 0xFE, 0xC6, 0x7C, 0xB6, 0xE9, 0x1F, 0x1C, + 0x1D, 0xA8, 0x00, 0xE4, 0x78, 0xA5 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 36 * 6]; +} _EC_NIST_CHAR2_283K = { + { + NID_X9_62_characteristic_two_field, 0, 36, 4 + }, + { + /* no seed */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* x */ + 0x05, 0x03, 0x21, 0x3F, 0x78, 0xCA, 0x44, 0x88, 0x3F, 0x1A, 0x3B, 0x81, + 0x62, 0xF1, 0x88, 0xE5, 0x53, 0xCD, 0x26, 0x5F, 0x23, 0xC1, 0x56, 0x7A, + 0x16, 0x87, 0x69, 0x13, 0xB0, 0xC2, 0xAC, 0x24, 0x58, 0x49, 0x28, 0x36, + /* y */ + 0x01, 0xCC, 0xDA, 0x38, 0x0F, 0x1C, 0x9E, 0x31, 0x8D, 0x90, 0xF9, 0x5D, + 0x07, 0xE5, 0x42, 0x6F, 0xE8, 0x7E, 0x45, 0xC0, 0xE8, 0x18, 0x46, 0x98, + 0xE4, 0x59, 0x62, 0x36, 0x4E, 0x34, 0x11, 0x61, 0x77, 0xDD, 0x22, 0x59, + /* order */ + 0x01, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xE9, 0xAE, 0x2E, 0xD0, 0x75, 0x77, + 0x26, 0x5D, 0xFF, 0x7F, 0x94, 0x45, 0x1E, 0x06, 0x1E, 0x16, 0x3C, 0x61 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 36 * 6]; +} _EC_NIST_CHAR2_283B = { + { + NID_X9_62_characteristic_two_field, 20, 36, 2 + }, + { + /* no seed */ + 0x77, 0xE2, 0xB0, 0x73, 0x70, 0xEB, 0x0F, 0x83, 0x2A, 0x6D, 0xD5, 0xB6, + 0x2D, 0xFC, 0x88, 0xCD, 0x06, 0xBB, 0x84, 0xBE, + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xA1, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* b */ + 0x02, 0x7B, 0x68, 0x0A, 0xC8, 0xB8, 0x59, 0x6D, 0xA5, 0xA4, 0xAF, 0x8A, + 0x19, 0xA0, 0x30, 0x3F, 0xCA, 0x97, 0xFD, 0x76, 0x45, 0x30, 0x9F, 0xA2, + 0xA5, 0x81, 0x48, 0x5A, 0xF6, 0x26, 0x3E, 0x31, 0x3B, 0x79, 0xA2, 0xF5, + /* x */ + 0x05, 0xF9, 0x39, 0x25, 0x8D, 0xB7, 0xDD, 0x90, 0xE1, 0x93, 0x4F, 0x8C, + 0x70, 0xB0, 0xDF, 0xEC, 0x2E, 0xED, 0x25, 0xB8, 0x55, 0x7E, 0xAC, 0x9C, + 0x80, 0xE2, 0xE1, 0x98, 0xF8, 0xCD, 0xBE, 0xCD, 0x86, 0xB1, 0x20, 0x53, + /* y */ + 0x03, 0x67, 0x68, 0x54, 0xFE, 0x24, 0x14, 0x1C, 0xB9, 0x8F, 0xE6, 0xD4, + 0xB2, 0x0D, 0x02, 0xB4, 0x51, 0x6F, 0xF7, 0x02, 0x35, 0x0E, 0xDD, 0xB0, + 0x82, 0x67, 0x79, 0xC8, 0x13, 0xF0, 0xDF, 0x45, 0xBE, 0x81, 0x12, 0xF4, + /* order */ + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x90, 0x39, 0x96, 0x60, 0xFC, + 0x93, 0x8A, 0x90, 0x16, 0x5B, 0x04, 0x2A, 0x7C, 0xEF, 0xAD, 0xB3, 0x07 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 52 * 6]; +} _EC_NIST_CHAR2_409K = { + { + NID_X9_62_characteristic_two_field, 0, 52, 4 + }, + { + /* no seed */ + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + /* x */ + 0x00, 0x60, 0xF0, 0x5F, 0x65, 0x8F, 0x49, 0xC1, 0xAD, 0x3A, 0xB1, 0x89, + 0x0F, 0x71, 0x84, 0x21, 0x0E, 0xFD, 0x09, 0x87, 0xE3, 0x07, 0xC8, 0x4C, + 0x27, 0xAC, 0xCF, 0xB8, 0xF9, 0xF6, 0x7C, 0xC2, 0xC4, 0x60, 0x18, 0x9E, + 0xB5, 0xAA, 0xAA, 0x62, 0xEE, 0x22, 0x2E, 0xB1, 0xB3, 0x55, 0x40, 0xCF, + 0xE9, 0x02, 0x37, 0x46, + /* y */ + 0x01, 0xE3, 0x69, 0x05, 0x0B, 0x7C, 0x4E, 0x42, 0xAC, 0xBA, 0x1D, 0xAC, + 0xBF, 0x04, 0x29, 0x9C, 0x34, 0x60, 0x78, 0x2F, 0x91, 0x8E, 0xA4, 0x27, + 0xE6, 0x32, 0x51, 0x65, 0xE9, 0xEA, 0x10, 0xE3, 0xDA, 0x5F, 0x6C, 0x42, + 0xE9, 0xC5, 0x52, 0x15, 0xAA, 0x9C, 0xA2, 0x7A, 0x58, 0x63, 0xEC, 0x48, + 0xD8, 0xE0, 0x28, 0x6B, + /* order */ + 0x00, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFE, 0x5F, 0x83, 0xB2, 0xD4, 0xEA, 0x20, 0x40, 0x0E, 0xC4, + 0x55, 0x7D, 0x5E, 0xD3, 0xE3, 0xE7, 0xCA, 0x5B, 0x4B, 0x5C, 0x83, 0xB8, + 0xE0, 0x1E, 0x5F, 0xCF + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 52 * 6]; +} _EC_NIST_CHAR2_409B = { + { + NID_X9_62_characteristic_two_field, 20, 52, 2 + }, + { + /* seed */ + 0x40, 0x99, 0xB5, 0xA4, 0x57, 0xF9, 0xD6, 0x9F, 0x79, 0x21, 0x3D, 0x09, + 0x4C, 0x4B, 0xCD, 0x4D, 0x42, 0x62, 0x21, 0x0B, + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, + /* b */ + 0x00, 0x21, 0xA5, 0xC2, 0xC8, 0xEE, 0x9F, 0xEB, 0x5C, 0x4B, 0x9A, 0x75, + 0x3B, 0x7B, 0x47, 0x6B, 0x7F, 0xD6, 0x42, 0x2E, 0xF1, 0xF3, 0xDD, 0x67, + 0x47, 0x61, 0xFA, 0x99, 0xD6, 0xAC, 0x27, 0xC8, 0xA9, 0xA1, 0x97, 0xB2, + 0x72, 0x82, 0x2F, 0x6C, 0xD5, 0x7A, 0x55, 0xAA, 0x4F, 0x50, 0xAE, 0x31, + 0x7B, 0x13, 0x54, 0x5F, + /* x */ + 0x01, 0x5D, 0x48, 0x60, 0xD0, 0x88, 0xDD, 0xB3, 0x49, 0x6B, 0x0C, 0x60, + 0x64, 0x75, 0x62, 0x60, 0x44, 0x1C, 0xDE, 0x4A, 0xF1, 0x77, 0x1D, 0x4D, + 0xB0, 0x1F, 0xFE, 0x5B, 0x34, 0xE5, 0x97, 0x03, 0xDC, 0x25, 0x5A, 0x86, + 0x8A, 0x11, 0x80, 0x51, 0x56, 0x03, 0xAE, 0xAB, 0x60, 0x79, 0x4E, 0x54, + 0xBB, 0x79, 0x96, 0xA7, + /* y */ + 0x00, 0x61, 0xB1, 0xCF, 0xAB, 0x6B, 0xE5, 0xF3, 0x2B, 0xBF, 0xA7, 0x83, + 0x24, 0xED, 0x10, 0x6A, 0x76, 0x36, 0xB9, 0xC5, 0xA7, 0xBD, 0x19, 0x8D, + 0x01, 0x58, 0xAA, 0x4F, 0x54, 0x88, 0xD0, 0x8F, 0x38, 0x51, 0x4F, 0x1F, + 0xDF, 0x4B, 0x4F, 0x40, 0xD2, 0x18, 0x1B, 0x36, 0x81, 0xC3, 0x64, 0xBA, + 0x02, 0x73, 0xC7, 0x06, + /* order */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0xE2, 0xAA, 0xD6, 0xA6, 0x12, 0xF3, 0x33, 0x07, 0xBE, + 0x5F, 0xA4, 0x7C, 0x3C, 0x9E, 0x05, 0x2F, 0x83, 0x81, 0x64, 0xCD, 0x37, + 0xD9, 0xA2, 0x11, 0x73 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 72 * 6]; +} _EC_NIST_CHAR2_571K = { + { + NID_X9_62_characteristic_two_field, 0, 72, 4 + }, + { + /* no seed */ + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x25, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* x */ + 0x02, 0x6E, 0xB7, 0xA8, 0x59, 0x92, 0x3F, 0xBC, 0x82, 0x18, 0x96, 0x31, + 0xF8, 0x10, 0x3F, 0xE4, 0xAC, 0x9C, 0xA2, 0x97, 0x00, 0x12, 0xD5, 0xD4, + 0x60, 0x24, 0x80, 0x48, 0x01, 0x84, 0x1C, 0xA4, 0x43, 0x70, 0x95, 0x84, + 0x93, 0xB2, 0x05, 0xE6, 0x47, 0xDA, 0x30, 0x4D, 0xB4, 0xCE, 0xB0, 0x8C, + 0xBB, 0xD1, 0xBA, 0x39, 0x49, 0x47, 0x76, 0xFB, 0x98, 0x8B, 0x47, 0x17, + 0x4D, 0xCA, 0x88, 0xC7, 0xE2, 0x94, 0x52, 0x83, 0xA0, 0x1C, 0x89, 0x72, + /* y */ + 0x03, 0x49, 0xDC, 0x80, 0x7F, 0x4F, 0xBF, 0x37, 0x4F, 0x4A, 0xEA, 0xDE, + 0x3B, 0xCA, 0x95, 0x31, 0x4D, 0xD5, 0x8C, 0xEC, 0x9F, 0x30, 0x7A, 0x54, + 0xFF, 0xC6, 0x1E, 0xFC, 0x00, 0x6D, 0x8A, 0x2C, 0x9D, 0x49, 0x79, 0xC0, + 0xAC, 0x44, 0xAE, 0xA7, 0x4F, 0xBE, 0xBB, 0xB9, 0xF7, 0x72, 0xAE, 0xDC, + 0xB6, 0x20, 0xB0, 0x1A, 0x7B, 0xA7, 0xAF, 0x1B, 0x32, 0x04, 0x30, 0xC8, + 0x59, 0x19, 0x84, 0xF6, 0x01, 0xCD, 0x4C, 0x14, 0x3E, 0xF1, 0xC7, 0xA3, + /* order */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x13, 0x18, 0x50, 0xE1, 0xF1, 0x9A, 0x63, 0xE4, 0xB3, 0x91, 0xA8, 0xDB, + 0x91, 0x7F, 0x41, 0x38, 0xB6, 0x30, 0xD8, 0x4B, 0xE5, 0xD6, 0x39, 0x38, + 0x1E, 0x91, 0xDE, 0xB4, 0x5C, 0xFE, 0x77, 0x8F, 0x63, 0x7C, 0x10, 0x01 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 72 * 6]; +} _EC_NIST_CHAR2_571B = { + { + NID_X9_62_characteristic_two_field, 20, 72, 2 + }, + { + /* seed */ + 0x2A, 0xA0, 0x58, 0xF7, 0x3A, 0x0E, 0x33, 0xAB, 0x48, 0x6B, 0x0F, 0x61, + 0x04, 0x10, 0xC5, 0x3A, 0x7F, 0x13, 0x23, 0x10, + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x25, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* b */ + 0x02, 0xF4, 0x0E, 0x7E, 0x22, 0x21, 0xF2, 0x95, 0xDE, 0x29, 0x71, 0x17, + 0xB7, 0xF3, 0xD6, 0x2F, 0x5C, 0x6A, 0x97, 0xFF, 0xCB, 0x8C, 0xEF, 0xF1, + 0xCD, 0x6B, 0xA8, 0xCE, 0x4A, 0x9A, 0x18, 0xAD, 0x84, 0xFF, 0xAB, 0xBD, + 0x8E, 0xFA, 0x59, 0x33, 0x2B, 0xE7, 0xAD, 0x67, 0x56, 0xA6, 0x6E, 0x29, + 0x4A, 0xFD, 0x18, 0x5A, 0x78, 0xFF, 0x12, 0xAA, 0x52, 0x0E, 0x4D, 0xE7, + 0x39, 0xBA, 0xCA, 0x0C, 0x7F, 0xFE, 0xFF, 0x7F, 0x29, 0x55, 0x72, 0x7A, + /* x */ + 0x03, 0x03, 0x00, 0x1D, 0x34, 0xB8, 0x56, 0x29, 0x6C, 0x16, 0xC0, 0xD4, + 0x0D, 0x3C, 0xD7, 0x75, 0x0A, 0x93, 0xD1, 0xD2, 0x95, 0x5F, 0xA8, 0x0A, + 0xA5, 0xF4, 0x0F, 0xC8, 0xDB, 0x7B, 0x2A, 0xBD, 0xBD, 0xE5, 0x39, 0x50, + 0xF4, 0xC0, 0xD2, 0x93, 0xCD, 0xD7, 0x11, 0xA3, 0x5B, 0x67, 0xFB, 0x14, + 0x99, 0xAE, 0x60, 0x03, 0x86, 0x14, 0xF1, 0x39, 0x4A, 0xBF, 0xA3, 0xB4, + 0xC8, 0x50, 0xD9, 0x27, 0xE1, 0xE7, 0x76, 0x9C, 0x8E, 0xEC, 0x2D, 0x19, + /* y */ + 0x03, 0x7B, 0xF2, 0x73, 0x42, 0xDA, 0x63, 0x9B, 0x6D, 0xCC, 0xFF, 0xFE, + 0xB7, 0x3D, 0x69, 0xD7, 0x8C, 0x6C, 0x27, 0xA6, 0x00, 0x9C, 0xBB, 0xCA, + 0x19, 0x80, 0xF8, 0x53, 0x39, 0x21, 0xE8, 0xA6, 0x84, 0x42, 0x3E, 0x43, + 0xBA, 0xB0, 0x8A, 0x57, 0x62, 0x91, 0xAF, 0x8F, 0x46, 0x1B, 0xB2, 0xA8, + 0xB3, 0x53, 0x1D, 0x2F, 0x04, 0x85, 0xC1, 0x9B, 0x16, 0xE2, 0xF1, 0x51, + 0x6E, 0x23, 0xDD, 0x3C, 0x1A, 0x48, 0x27, 0xAF, 0x1B, 0x8A, 0xC1, 0x5B, + /* order */ + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE6, 0x61, 0xCE, 0x18, 0xFF, 0x55, 0x98, 0x73, 0x08, 0x05, 0x9B, 0x18, + 0x68, 0x23, 0x85, 0x1E, 0xC7, 0xDD, 0x9C, 0xA1, 0x16, 0x1D, 0xE9, 0x3D, + 0x51, 0x74, 0xD6, 0x6E, 0x83, 0x82, 0xE9, 0xBB, 0x2F, 0xE8, 0x4E, 0x47 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 21 * 6]; +} _EC_X9_62_CHAR2_163V1 = { + { + NID_X9_62_characteristic_two_field, 20, 21, 2 + }, + { + /* seed */ + 0xD2, 0xC0, 0xFB, 0x15, 0x76, 0x08, 0x60, 0xDE, 0xF1, 0xEE, 0xF4, 0xD6, + 0x96, 0xE6, 0x76, 0x87, 0x56, 0x15, 0x17, 0x54, + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, + /* a */ + 0x07, 0x25, 0x46, 0xB5, 0x43, 0x52, 0x34, 0xA4, 0x22, 0xE0, 0x78, 0x96, + 0x75, 0xF4, 0x32, 0xC8, 0x94, 0x35, 0xDE, 0x52, 0x42, + /* b */ + 0x00, 0xC9, 0x51, 0x7D, 0x06, 0xD5, 0x24, 0x0D, 0x3C, 0xFF, 0x38, 0xC7, + 0x4B, 0x20, 0xB6, 0xCD, 0x4D, 0x6F, 0x9D, 0xD4, 0xD9, + /* x */ + 0x07, 0xAF, 0x69, 0x98, 0x95, 0x46, 0x10, 0x3D, 0x79, 0x32, 0x9F, 0xCC, + 0x3D, 0x74, 0x88, 0x0F, 0x33, 0xBB, 0xE8, 0x03, 0xCB, + /* y */ + 0x01, 0xEC, 0x23, 0x21, 0x1B, 0x59, 0x66, 0xAD, 0xEA, 0x1D, 0x3F, 0x87, + 0xF7, 0xEA, 0x58, 0x48, 0xAE, 0xF0, 0xB7, 0xCA, 0x9F, + /* order */ + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xE6, + 0x0F, 0xC8, 0x82, 0x1C, 0xC7, 0x4D, 0xAE, 0xAF, 0xC1 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 21 * 6]; +} _EC_X9_62_CHAR2_163V2 = { + { + NID_X9_62_characteristic_two_field, 20, 21, 2 + }, + { + /* seed */ + 0x53, 0x81, 0x4C, 0x05, 0x0D, 0x44, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x58, 0x0C, 0xA4, 0xE2, 0x9F, 0xFD, + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, + /* a */ + 0x01, 0x08, 0xB3, 0x9E, 0x77, 0xC4, 0xB1, 0x08, 0xBE, 0xD9, 0x81, 0xED, + 0x0E, 0x89, 0x0E, 0x11, 0x7C, 0x51, 0x1C, 0xF0, 0x72, + /* b */ + 0x06, 0x67, 0xAC, 0xEB, 0x38, 0xAF, 0x4E, 0x48, 0x8C, 0x40, 0x74, 0x33, + 0xFF, 0xAE, 0x4F, 0x1C, 0x81, 0x16, 0x38, 0xDF, 0x20, + /* x */ + 0x00, 0x24, 0x26, 0x6E, 0x4E, 0xB5, 0x10, 0x6D, 0x0A, 0x96, 0x4D, 0x92, + 0xC4, 0x86, 0x0E, 0x26, 0x71, 0xDB, 0x9B, 0x6C, 0xC5, + /* y */ + 0x07, 0x9F, 0x68, 0x4D, 0xDF, 0x66, 0x84, 0xC5, 0xCD, 0x25, 0x8B, 0x38, + 0x90, 0x02, 0x1B, 0x23, 0x86, 0xDF, 0xD1, 0x9F, 0xC5, + /* order */ + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xF6, + 0x4D, 0xE1, 0x15, 0x1A, 0xDB, 0xB7, 0x8F, 0x10, 0xA7 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 21 * 6]; +} _EC_X9_62_CHAR2_163V3 = { + { + NID_X9_62_characteristic_two_field, 20, 21, 2 + }, + { + /* seed */ + 0x50, 0xCB, 0xF1, 0xD9, 0x5C, 0xA9, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, + 0x61, 0x51, 0x75, 0xF1, 0x6A, 0x36, 0xA3, 0xB8, + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, + /* a */ + 0x07, 0xA5, 0x26, 0xC6, 0x3D, 0x3E, 0x25, 0xA2, 0x56, 0xA0, 0x07, 0x69, + 0x9F, 0x54, 0x47, 0xE3, 0x2A, 0xE4, 0x56, 0xB5, 0x0E, + /* b */ + 0x03, 0xF7, 0x06, 0x17, 0x98, 0xEB, 0x99, 0xE2, 0x38, 0xFD, 0x6F, 0x1B, + 0xF9, 0x5B, 0x48, 0xFE, 0xEB, 0x48, 0x54, 0x25, 0x2B, + /* x */ + 0x02, 0xF9, 0xF8, 0x7B, 0x7C, 0x57, 0x4D, 0x0B, 0xDE, 0xCF, 0x8A, 0x22, + 0xE6, 0x52, 0x47, 0x75, 0xF9, 0x8C, 0xDE, 0xBD, 0xCB, + /* y */ + 0x05, 0xB9, 0x35, 0x59, 0x0C, 0x15, 0x5E, 0x17, 0xEA, 0x48, 0xEB, 0x3F, + 0xF3, 0x71, 0x8B, 0x89, 0x3D, 0xF5, 0x9A, 0x05, 0xD0, + /* order */ + 0x03, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0x1A, + 0xEE, 0x14, 0x0F, 0x11, 0x0A, 0xFF, 0x96, 0x13, 0x09 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 23 * 6]; +} _EC_X9_62_CHAR2_176V1 = { + { + NID_X9_62_characteristic_two_field, 0, 23, 0xFF6E + }, + { + /* no seed */ + /* p */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x07, + /* a */ + 0x00, 0xE4, 0xE6, 0xDB, 0x29, 0x95, 0x06, 0x5C, 0x40, 0x7D, 0x9D, 0x39, + 0xB8, 0xD0, 0x96, 0x7B, 0x96, 0x70, 0x4B, 0xA8, 0xE9, 0xC9, 0x0B, + /* b */ + 0x00, 0x5D, 0xDA, 0x47, 0x0A, 0xBE, 0x64, 0x14, 0xDE, 0x8E, 0xC1, 0x33, + 0xAE, 0x28, 0xE9, 0xBB, 0xD7, 0xFC, 0xEC, 0x0A, 0xE0, 0xFF, 0xF2, + /* x */ + 0x00, 0x8D, 0x16, 0xC2, 0x86, 0x67, 0x98, 0xB6, 0x00, 0xF9, 0xF0, 0x8B, + 0xB4, 0xA8, 0xE8, 0x60, 0xF3, 0x29, 0x8C, 0xE0, 0x4A, 0x57, 0x98, + /* y */ + 0x00, 0x6F, 0xA4, 0x53, 0x9C, 0x2D, 0xAD, 0xDD, 0xD6, 0xBA, 0xB5, 0x16, + 0x7D, 0x61, 0xB4, 0x36, 0xE1, 0xD9, 0x2B, 0xB1, 0x6A, 0x56, 0x2C, + /* order */ + 0x00, 0x00, 0x01, 0x00, 0x92, 0x53, 0x73, 0x97, 0xEC, 0xA4, 0xF6, 0x14, + 0x57, 0x99, 0xD6, 0x2B, 0x0A, 0x19, 0xCE, 0x06, 0xFE, 0x26, 0xAD + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 24 * 6]; +} _EC_X9_62_CHAR2_191V1 = { + { + NID_X9_62_characteristic_two_field, 20, 24, 2 + }, + { + /* seed */ + 0x4E, 0x13, 0xCA, 0x54, 0x27, 0x44, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x55, 0x2F, 0x27, 0x9A, 0x8C, 0x84, + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, + /* a */ + 0x28, 0x66, 0x53, 0x7B, 0x67, 0x67, 0x52, 0x63, 0x6A, 0x68, 0xF5, 0x65, + 0x54, 0xE1, 0x26, 0x40, 0x27, 0x6B, 0x64, 0x9E, 0xF7, 0x52, 0x62, 0x67, + /* b */ + 0x2E, 0x45, 0xEF, 0x57, 0x1F, 0x00, 0x78, 0x6F, 0x67, 0xB0, 0x08, 0x1B, + 0x94, 0x95, 0xA3, 0xD9, 0x54, 0x62, 0xF5, 0xDE, 0x0A, 0xA1, 0x85, 0xEC, + /* x */ + 0x36, 0xB3, 0xDA, 0xF8, 0xA2, 0x32, 0x06, 0xF9, 0xC4, 0xF2, 0x99, 0xD7, + 0xB2, 0x1A, 0x9C, 0x36, 0x91, 0x37, 0xF2, 0xC8, 0x4A, 0xE1, 0xAA, 0x0D, + /* y */ + 0x76, 0x5B, 0xE7, 0x34, 0x33, 0xB3, 0xF9, 0x5E, 0x33, 0x29, 0x32, 0xE7, + 0x0E, 0xA2, 0x45, 0xCA, 0x24, 0x18, 0xEA, 0x0E, 0xF9, 0x80, 0x18, 0xFB, + /* order */ + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x04, 0xA2, 0x0E, 0x90, 0xC3, 0x90, 0x67, 0xC8, 0x93, 0xBB, 0xB9, 0xA5 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 24 * 6]; +} _EC_X9_62_CHAR2_191V2 = { + { + NID_X9_62_characteristic_two_field, 20, 24, 4 + }, + { + /* seed */ + 0x08, 0x71, 0xEF, 0x2F, 0xEF, 0x24, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x58, 0xBE, 0xE0, 0xD9, 0x5C, 0x15, + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, + /* a */ + 0x40, 0x10, 0x28, 0x77, 0x4D, 0x77, 0x77, 0xC7, 0xB7, 0x66, 0x6D, 0x13, + 0x66, 0xEA, 0x43, 0x20, 0x71, 0x27, 0x4F, 0x89, 0xFF, 0x01, 0xE7, 0x18, + /* b */ + 0x06, 0x20, 0x04, 0x8D, 0x28, 0xBC, 0xBD, 0x03, 0xB6, 0x24, 0x9C, 0x99, + 0x18, 0x2B, 0x7C, 0x8C, 0xD1, 0x97, 0x00, 0xC3, 0x62, 0xC4, 0x6A, 0x01, + /* x */ + 0x38, 0x09, 0xB2, 0xB7, 0xCC, 0x1B, 0x28, 0xCC, 0x5A, 0x87, 0x92, 0x6A, + 0xAD, 0x83, 0xFD, 0x28, 0x78, 0x9E, 0x81, 0xE2, 0xC9, 0xE3, 0xBF, 0x10, + /* y */ + 0x17, 0x43, 0x43, 0x86, 0x62, 0x6D, 0x14, 0xF3, 0xDB, 0xF0, 0x17, 0x60, + 0xD9, 0x21, 0x3A, 0x3E, 0x1C, 0xF3, 0x7A, 0xEC, 0x43, 0x7D, 0x66, 0x8A, + /* order */ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x50, 0x50, 0x8C, 0xB8, 0x9F, 0x65, 0x28, 0x24, 0xE0, 0x6B, 0x81, 0x73 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 24 * 6]; +} _EC_X9_62_CHAR2_191V3 = { + { + NID_X9_62_characteristic_two_field, 20, 24, 6 + }, + { + /* seed */ + 0xE0, 0x53, 0x51, 0x2D, 0xC6, 0x84, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x50, 0x67, 0xAE, 0x78, 0x6D, 0x1F, + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, + /* a */ + 0x6C, 0x01, 0x07, 0x47, 0x56, 0x09, 0x91, 0x22, 0x22, 0x10, 0x56, 0x91, + 0x1C, 0x77, 0xD7, 0x7E, 0x77, 0xA7, 0x77, 0xE7, 0xE7, 0xE7, 0x7F, 0xCB, + /* b */ + 0x71, 0xFE, 0x1A, 0xF9, 0x26, 0xCF, 0x84, 0x79, 0x89, 0xEF, 0xEF, 0x8D, + 0xB4, 0x59, 0xF6, 0x63, 0x94, 0xD9, 0x0F, 0x32, 0xAD, 0x3F, 0x15, 0xE8, + /* x */ + 0x37, 0x5D, 0x4C, 0xE2, 0x4F, 0xDE, 0x43, 0x44, 0x89, 0xDE, 0x87, 0x46, + 0xE7, 0x17, 0x86, 0x01, 0x50, 0x09, 0xE6, 0x6E, 0x38, 0xA9, 0x26, 0xDD, + /* y */ + 0x54, 0x5A, 0x39, 0x17, 0x61, 0x96, 0x57, 0x5D, 0x98, 0x59, 0x99, 0x36, + 0x6E, 0x6A, 0xD3, 0x4C, 0xE0, 0xA7, 0x7C, 0xD7, 0x12, 0x7B, 0x06, 0xBE, + /* order */ + 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x61, 0x0C, 0x0B, 0x19, 0x68, 0x12, 0xBF, 0xB6, 0x28, 0x8A, 0x3E, 0xA3 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 27 * 6]; +} _EC_X9_62_CHAR2_208W1 = { + { + NID_X9_62_characteristic_two_field, 0, 27, 0xFE48 + }, + { + /* no seed */ + /* p */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x07, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, + /* b */ + 0x00, 0xC8, 0x61, 0x9E, 0xD4, 0x5A, 0x62, 0xE6, 0x21, 0x2E, 0x11, 0x60, + 0x34, 0x9E, 0x2B, 0xFA, 0x84, 0x44, 0x39, 0xFA, 0xFC, 0x2A, 0x3F, 0xD1, + 0x63, 0x8F, 0x9E, + /* x */ + 0x00, 0x89, 0xFD, 0xFB, 0xE4, 0xAB, 0xE1, 0x93, 0xDF, 0x95, 0x59, 0xEC, + 0xF0, 0x7A, 0xC0, 0xCE, 0x78, 0x55, 0x4E, 0x27, 0x84, 0xEB, 0x8C, 0x1E, + 0xD1, 0xA5, 0x7A, + /* y */ + 0x00, 0x0F, 0x55, 0xB5, 0x1A, 0x06, 0xE7, 0x8E, 0x9A, 0xC3, 0x8A, 0x03, + 0x5F, 0xF5, 0x20, 0xD8, 0xB0, 0x17, 0x81, 0xBE, 0xB1, 0xA6, 0xBB, 0x08, + 0x61, 0x7D, 0xE3, + /* order */ + 0x00, 0x00, 0x01, 0x01, 0xBA, 0xF9, 0x5C, 0x97, 0x23, 0xC5, 0x7B, 0x6C, + 0x21, 0xDA, 0x2E, 0xFF, 0x2D, 0x5E, 0xD5, 0x88, 0xBD, 0xD5, 0x71, 0x7E, + 0x21, 0x2F, 0x9D + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 30 * 6]; +} _EC_X9_62_CHAR2_239V1 = { + { + NID_X9_62_characteristic_two_field, 20, 30, 4 + }, + { + /* seed */ + 0xD3, 0x4B, 0x9A, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, + 0xCA, 0x71, 0xB9, 0x20, 0xBF, 0xEF, 0xB0, 0x5D, + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x32, 0x01, 0x08, 0x57, 0x07, 0x7C, 0x54, 0x31, 0x12, 0x3A, 0x46, 0xB8, + 0x08, 0x90, 0x67, 0x56, 0xF5, 0x43, 0x42, 0x3E, 0x8D, 0x27, 0x87, 0x75, + 0x78, 0x12, 0x57, 0x78, 0xAC, 0x76, + /* b */ + 0x79, 0x04, 0x08, 0xF2, 0xEE, 0xDA, 0xF3, 0x92, 0xB0, 0x12, 0xED, 0xEF, + 0xB3, 0x39, 0x2F, 0x30, 0xF4, 0x32, 0x7C, 0x0C, 0xA3, 0xF3, 0x1F, 0xC3, + 0x83, 0xC4, 0x22, 0xAA, 0x8C, 0x16, + /* x */ + 0x57, 0x92, 0x70, 0x98, 0xFA, 0x93, 0x2E, 0x7C, 0x0A, 0x96, 0xD3, 0xFD, + 0x5B, 0x70, 0x6E, 0xF7, 0xE5, 0xF5, 0xC1, 0x56, 0xE1, 0x6B, 0x7E, 0x7C, + 0x86, 0x03, 0x85, 0x52, 0xE9, 0x1D, + /* y */ + 0x61, 0xD8, 0xEE, 0x50, 0x77, 0xC3, 0x3F, 0xEC, 0xF6, 0xF1, 0xA1, 0x6B, + 0x26, 0x8D, 0xE4, 0x69, 0xC3, 0xC7, 0x74, 0x4E, 0xA9, 0xA9, 0x71, 0x64, + 0x9F, 0xC7, 0xA9, 0x61, 0x63, 0x05, + /* order */ + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0F, 0x4D, 0x42, 0xFF, 0xE1, 0x49, 0x2A, 0x49, 0x93, + 0xF1, 0xCA, 0xD6, 0x66, 0xE4, 0x47 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 30 * 6]; +} _EC_X9_62_CHAR2_239V2 = { + { + NID_X9_62_characteristic_two_field, 20, 30, 6 + }, + { + /* seed */ + 0x2A, 0xA6, 0x98, 0x2F, 0xDF, 0xA4, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x5D, 0x26, 0x67, 0x27, 0x27, 0x7D, + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x42, 0x30, 0x01, 0x77, 0x57, 0xA7, 0x67, 0xFA, 0xE4, 0x23, 0x98, 0x56, + 0x9B, 0x74, 0x63, 0x25, 0xD4, 0x53, 0x13, 0xAF, 0x07, 0x66, 0x26, 0x64, + 0x79, 0xB7, 0x56, 0x54, 0xE6, 0x5F, + /* b */ + 0x50, 0x37, 0xEA, 0x65, 0x41, 0x96, 0xCF, 0xF0, 0xCD, 0x82, 0xB2, 0xC1, + 0x4A, 0x2F, 0xCF, 0x2E, 0x3F, 0xF8, 0x77, 0x52, 0x85, 0xB5, 0x45, 0x72, + 0x2F, 0x03, 0xEA, 0xCD, 0xB7, 0x4B, + /* x */ + 0x28, 0xF9, 0xD0, 0x4E, 0x90, 0x00, 0x69, 0xC8, 0xDC, 0x47, 0xA0, 0x85, + 0x34, 0xFE, 0x76, 0xD2, 0xB9, 0x00, 0xB7, 0xD7, 0xEF, 0x31, 0xF5, 0x70, + 0x9F, 0x20, 0x0C, 0x4C, 0xA2, 0x05, + /* y */ + 0x56, 0x67, 0x33, 0x4C, 0x45, 0xAF, 0xF3, 0xB5, 0xA0, 0x3B, 0xAD, 0x9D, + 0xD7, 0x5E, 0x2C, 0x71, 0xA9, 0x93, 0x62, 0x56, 0x7D, 0x54, 0x53, 0xF7, + 0xFA, 0x6E, 0x22, 0x7E, 0xC8, 0x33, + /* order */ + 0x15, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, + 0x55, 0x55, 0x55, 0x3C, 0x6F, 0x28, 0x85, 0x25, 0x9C, 0x31, 0xE3, 0xFC, + 0xDF, 0x15, 0x46, 0x24, 0x52, 0x2D + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 30 * 6]; +} _EC_X9_62_CHAR2_239V3 = { + { + NID_X9_62_characteristic_two_field, 20, 30, 0xA + }, + { + /* seed */ + 0x9E, 0x07, 0x6F, 0x4D, 0x69, 0x6E, 0x67, 0x68, 0x75, 0x61, 0x51, 0x75, + 0xE1, 0x1E, 0x9F, 0xDD, 0x77, 0xF9, 0x20, 0x41, + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x10, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x01, 0x23, 0x87, 0x74, 0x66, 0x6A, 0x67, 0x76, 0x6D, 0x66, 0x76, 0xF7, + 0x78, 0xE6, 0x76, 0xB6, 0x69, 0x99, 0x17, 0x66, 0x66, 0xE6, 0x87, 0x66, + 0x6D, 0x87, 0x66, 0xC6, 0x6A, 0x9F, + /* b */ + 0x6A, 0x94, 0x19, 0x77, 0xBA, 0x9F, 0x6A, 0x43, 0x51, 0x99, 0xAC, 0xFC, + 0x51, 0x06, 0x7E, 0xD5, 0x87, 0xF5, 0x19, 0xC5, 0xEC, 0xB5, 0x41, 0xB8, + 0xE4, 0x41, 0x11, 0xDE, 0x1D, 0x40, + /* x */ + 0x70, 0xF6, 0xE9, 0xD0, 0x4D, 0x28, 0x9C, 0x4E, 0x89, 0x91, 0x3C, 0xE3, + 0x53, 0x0B, 0xFD, 0xE9, 0x03, 0x97, 0x7D, 0x42, 0xB1, 0x46, 0xD5, 0x39, + 0xBF, 0x1B, 0xDE, 0x4E, 0x9C, 0x92, + /* y */ + 0x2E, 0x5A, 0x0E, 0xAF, 0x6E, 0x5E, 0x13, 0x05, 0xB9, 0x00, 0x4D, 0xCE, + 0x5C, 0x0E, 0xD7, 0xFE, 0x59, 0xA3, 0x56, 0x08, 0xF3, 0x38, 0x37, 0xC8, + 0x16, 0xD8, 0x0B, 0x79, 0xF4, 0x61, + /* order */ + 0x0C, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, + 0xCC, 0xCC, 0xCC, 0xAC, 0x49, 0x12, 0xD2, 0xD9, 0xDF, 0x90, 0x3E, 0xF9, + 0x88, 0x8B, 0x8A, 0x0E, 0x4C, 0xFF + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 35 * 6]; +} _EC_X9_62_CHAR2_272W1 = { + { + NID_X9_62_characteristic_two_field, 0, 35, 0xFF06 + }, + { + /* no seed */ + /* p */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B, + /* a */ + 0x00, 0x91, 0xA0, 0x91, 0xF0, 0x3B, 0x5F, 0xBA, 0x4A, 0xB2, 0xCC, 0xF4, + 0x9C, 0x4E, 0xDD, 0x22, 0x0F, 0xB0, 0x28, 0x71, 0x2D, 0x42, 0xBE, 0x75, + 0x2B, 0x2C, 0x40, 0x09, 0x4D, 0xBA, 0xCD, 0xB5, 0x86, 0xFB, 0x20, + /* b */ + 0x00, 0x71, 0x67, 0xEF, 0xC9, 0x2B, 0xB2, 0xE3, 0xCE, 0x7C, 0x8A, 0xAA, + 0xFF, 0x34, 0xE1, 0x2A, 0x9C, 0x55, 0x70, 0x03, 0xD7, 0xC7, 0x3A, 0x6F, + 0xAF, 0x00, 0x3F, 0x99, 0xF6, 0xCC, 0x84, 0x82, 0xE5, 0x40, 0xF7, + /* x */ + 0x00, 0x61, 0x08, 0xBA, 0xBB, 0x2C, 0xEE, 0xBC, 0xF7, 0x87, 0x05, 0x8A, + 0x05, 0x6C, 0xBE, 0x0C, 0xFE, 0x62, 0x2D, 0x77, 0x23, 0xA2, 0x89, 0xE0, + 0x8A, 0x07, 0xAE, 0x13, 0xEF, 0x0D, 0x10, 0xD1, 0x71, 0xDD, 0x8D, + /* y */ + 0x00, 0x10, 0xC7, 0x69, 0x57, 0x16, 0x85, 0x1E, 0xEF, 0x6B, 0xA7, 0xF6, + 0x87, 0x2E, 0x61, 0x42, 0xFB, 0xD2, 0x41, 0xB8, 0x30, 0xFF, 0x5E, 0xFC, + 0xAC, 0xEC, 0xCA, 0xB0, 0x5E, 0x02, 0x00, 0x5D, 0xDE, 0x9D, 0x23, + /* order */ + 0x00, 0x00, 0x01, 0x00, 0xFA, 0xF5, 0x13, 0x54, 0xE0, 0xE3, 0x9E, 0x48, + 0x92, 0xDF, 0x6E, 0x31, 0x9C, 0x72, 0xC8, 0x16, 0x16, 0x03, 0xFA, 0x45, + 0xAA, 0x7B, 0x99, 0x8A, 0x16, 0x7B, 0x8F, 0x1E, 0x62, 0x95, 0x21 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 39 * 6]; +} _EC_X9_62_CHAR2_304W1 = { + { + NID_X9_62_characteristic_two_field, 0, 39, 0xFE2E + }, + { + /* no seed */ + /* p */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x08, 0x07, + /* a */ + 0x00, 0xFD, 0x0D, 0x69, 0x31, 0x49, 0xA1, 0x18, 0xF6, 0x51, 0xE6, 0xDC, + 0xE6, 0x80, 0x20, 0x85, 0x37, 0x7E, 0x5F, 0x88, 0x2D, 0x1B, 0x51, 0x0B, + 0x44, 0x16, 0x00, 0x74, 0xC1, 0x28, 0x80, 0x78, 0x36, 0x5A, 0x03, 0x96, + 0xC8, 0xE6, 0x81, + /* b */ + 0x00, 0xBD, 0xDB, 0x97, 0xE5, 0x55, 0xA5, 0x0A, 0x90, 0x8E, 0x43, 0xB0, + 0x1C, 0x79, 0x8E, 0xA5, 0xDA, 0xA6, 0x78, 0x8F, 0x1E, 0xA2, 0x79, 0x4E, + 0xFC, 0xF5, 0x71, 0x66, 0xB8, 0xC1, 0x40, 0x39, 0x60, 0x1E, 0x55, 0x82, + 0x73, 0x40, 0xBE, + /* x */ + 0x00, 0x19, 0x7B, 0x07, 0x84, 0x5E, 0x9B, 0xE2, 0xD9, 0x6A, 0xDB, 0x0F, + 0x5F, 0x3C, 0x7F, 0x2C, 0xFF, 0xBD, 0x7A, 0x3E, 0xB8, 0xB6, 0xFE, 0xC3, + 0x5C, 0x7F, 0xD6, 0x7F, 0x26, 0xDD, 0xF6, 0x28, 0x5A, 0x64, 0x4F, 0x74, + 0x0A, 0x26, 0x14, + /* y */ + 0x00, 0xE1, 0x9F, 0xBE, 0xB7, 0x6E, 0x0D, 0xA1, 0x71, 0x51, 0x7E, 0xCF, + 0x40, 0x1B, 0x50, 0x28, 0x9B, 0xF0, 0x14, 0x10, 0x32, 0x88, 0x52, 0x7A, + 0x9B, 0x41, 0x6A, 0x10, 0x5E, 0x80, 0x26, 0x0B, 0x54, 0x9F, 0xDC, 0x1B, + 0x92, 0xC0, 0x3B, + /* order */ + 0x00, 0x00, 0x01, 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, 0x80, 0x01, + 0x01, 0xD5, 0x56, 0x57, 0x2A, 0xAB, 0xAC, 0x80, 0x01, 0x02, 0x2D, 0x5C, + 0x91, 0xDD, 0x17, 0x3F, 0x8F, 0xB5, 0x61, 0xDA, 0x68, 0x99, 0x16, 0x44, + 0x43, 0x05, 0x1D + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[20 + 45 * 6]; +} _EC_X9_62_CHAR2_359V1 = { + { + NID_X9_62_characteristic_two_field, 20, 45, 0x4C + }, + { + /* seed */ + 0x2B, 0x35, 0x49, 0x20, 0xB7, 0x24, 0xD6, 0x96, 0xE6, 0x76, 0x87, 0x56, + 0x15, 0x17, 0x58, 0x5B, 0xA1, 0x33, 0x2D, 0xC6, + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x56, 0x67, 0x67, 0x6A, 0x65, 0x4B, 0x20, 0x75, 0x4F, 0x35, 0x6E, 0xA9, + 0x20, 0x17, 0xD9, 0x46, 0x56, 0x7C, 0x46, 0x67, 0x55, 0x56, 0xF1, 0x95, + 0x56, 0xA0, 0x46, 0x16, 0xB5, 0x67, 0xD2, 0x23, 0xA5, 0xE0, 0x56, 0x56, + 0xFB, 0x54, 0x90, 0x16, 0xA9, 0x66, 0x56, 0xA5, 0x57, + /* b */ + 0x24, 0x72, 0xE2, 0xD0, 0x19, 0x7C, 0x49, 0x36, 0x3F, 0x1F, 0xE7, 0xF5, + 0xB6, 0xDB, 0x07, 0x5D, 0x52, 0xB6, 0x94, 0x7D, 0x13, 0x5D, 0x8C, 0xA4, + 0x45, 0x80, 0x5D, 0x39, 0xBC, 0x34, 0x56, 0x26, 0x08, 0x96, 0x87, 0x74, + 0x2B, 0x63, 0x29, 0xE7, 0x06, 0x80, 0x23, 0x19, 0x88, + /* x */ + 0x3C, 0x25, 0x8E, 0xF3, 0x04, 0x77, 0x67, 0xE7, 0xED, 0xE0, 0xF1, 0xFD, + 0xAA, 0x79, 0xDA, 0xEE, 0x38, 0x41, 0x36, 0x6A, 0x13, 0x2E, 0x16, 0x3A, + 0xCE, 0xD4, 0xED, 0x24, 0x01, 0xDF, 0x9C, 0x6B, 0xDC, 0xDE, 0x98, 0xE8, + 0xE7, 0x07, 0xC0, 0x7A, 0x22, 0x39, 0xB1, 0xB0, 0x97, + /* y */ + 0x53, 0xD7, 0xE0, 0x85, 0x29, 0x54, 0x70, 0x48, 0x12, 0x1E, 0x9C, 0x95, + 0xF3, 0x79, 0x1D, 0xD8, 0x04, 0x96, 0x39, 0x48, 0xF3, 0x4F, 0xAE, 0x7B, + 0xF4, 0x4E, 0xA8, 0x23, 0x65, 0xDC, 0x78, 0x68, 0xFE, 0x57, 0xE4, 0xAE, + 0x2D, 0xE2, 0x11, 0x30, 0x5A, 0x40, 0x71, 0x04, 0xBD, + /* order */ + 0x01, 0xAF, 0x28, 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, 0xAF, 0x28, + 0x6B, 0xCA, 0x1A, 0xF2, 0x86, 0xBC, 0xA1, 0xAF, 0x28, 0x6B, 0xC9, 0xFB, + 0x8F, 0x6B, 0x85, 0xC5, 0x56, 0x89, 0x2C, 0x20, 0xA7, 0xEB, 0x96, 0x4F, + 0xE7, 0x71, 0x9E, 0x74, 0xF4, 0x90, 0x75, 0x8D, 0x3B + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 47 * 6]; +} _EC_X9_62_CHAR2_368W1 = { + { + NID_X9_62_characteristic_two_field, 0, 47, 0xFF70 + }, + { + /* no seed */ + /* p */ + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, + /* a */ + 0x00, 0xE0, 0xD2, 0xEE, 0x25, 0x09, 0x52, 0x06, 0xF5, 0xE2, 0xA4, 0xF9, + 0xED, 0x22, 0x9F, 0x1F, 0x25, 0x6E, 0x79, 0xA0, 0xE2, 0xB4, 0x55, 0x97, + 0x0D, 0x8D, 0x0D, 0x86, 0x5B, 0xD9, 0x47, 0x78, 0xC5, 0x76, 0xD6, 0x2F, + 0x0A, 0xB7, 0x51, 0x9C, 0xCD, 0x2A, 0x1A, 0x90, 0x6A, 0xE3, 0x0D, + /* b */ + 0x00, 0xFC, 0x12, 0x17, 0xD4, 0x32, 0x0A, 0x90, 0x45, 0x2C, 0x76, 0x0A, + 0x58, 0xED, 0xCD, 0x30, 0xC8, 0xDD, 0x06, 0x9B, 0x3C, 0x34, 0x45, 0x38, + 0x37, 0xA3, 0x4E, 0xD5, 0x0C, 0xB5, 0x49, 0x17, 0xE1, 0xC2, 0x11, 0x2D, + 0x84, 0xD1, 0x64, 0xF4, 0x44, 0xF8, 0xF7, 0x47, 0x86, 0x04, 0x6A, + /* x */ + 0x00, 0x10, 0x85, 0xE2, 0x75, 0x53, 0x81, 0xDC, 0xCC, 0xE3, 0xC1, 0x55, + 0x7A, 0xFA, 0x10, 0xC2, 0xF0, 0xC0, 0xC2, 0x82, 0x56, 0x46, 0xC5, 0xB3, + 0x4A, 0x39, 0x4C, 0xBC, 0xFA, 0x8B, 0xC1, 0x6B, 0x22, 0xE7, 0xE7, 0x89, + 0xE9, 0x27, 0xBE, 0x21, 0x6F, 0x02, 0xE1, 0xFB, 0x13, 0x6A, 0x5F, + /* y */ + 0x00, 0x7B, 0x3E, 0xB1, 0xBD, 0xDC, 0xBA, 0x62, 0xD5, 0xD8, 0xB2, 0x05, + 0x9B, 0x52, 0x57, 0x97, 0xFC, 0x73, 0x82, 0x2C, 0x59, 0x05, 0x9C, 0x62, + 0x3A, 0x45, 0xFF, 0x38, 0x43, 0xCE, 0xE8, 0xF8, 0x7C, 0xD1, 0x85, 0x5A, + 0xDA, 0xA8, 0x1E, 0x2A, 0x07, 0x50, 0xB8, 0x0F, 0xDA, 0x23, 0x10, + /* order */ + 0x00, 0x00, 0x01, 0x00, 0x90, 0x51, 0x2D, 0xA9, 0xAF, 0x72, 0xB0, 0x83, + 0x49, 0xD9, 0x8A, 0x5D, 0xD4, 0xC7, 0xB0, 0x53, 0x2E, 0xCA, 0x51, 0xCE, + 0x03, 0xE2, 0xD1, 0x0F, 0x3B, 0x7A, 0xC5, 0x79, 0xBD, 0x87, 0xE9, 0x09, + 0xAE, 0x40, 0xA6, 0xF1, 0x31, 0xE9, 0xCF, 0xCE, 0x5B, 0xD9, 0x67 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 54 * 6]; +} _EC_X9_62_CHAR2_431R1 = { + { + NID_X9_62_characteristic_two_field, 0, 54, 0x2760 + }, + { + /* no seed */ + /* p */ + 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x1A, 0x82, 0x7E, 0xF0, 0x0D, 0xD6, 0xFC, 0x0E, 0x23, 0x4C, 0xAF, 0x04, + 0x6C, 0x6A, 0x5D, 0x8A, 0x85, 0x39, 0x5B, 0x23, 0x6C, 0xC4, 0xAD, 0x2C, + 0xF3, 0x2A, 0x0C, 0xAD, 0xBD, 0xC9, 0xDD, 0xF6, 0x20, 0xB0, 0xEB, 0x99, + 0x06, 0xD0, 0x95, 0x7F, 0x6C, 0x6F, 0xEA, 0xCD, 0x61, 0x54, 0x68, 0xDF, + 0x10, 0x4D, 0xE2, 0x96, 0xCD, 0x8F, + /* b */ + 0x10, 0xD9, 0xB4, 0xA3, 0xD9, 0x04, 0x7D, 0x8B, 0x15, 0x43, 0x59, 0xAB, + 0xFB, 0x1B, 0x7F, 0x54, 0x85, 0xB0, 0x4C, 0xEB, 0x86, 0x82, 0x37, 0xDD, + 0xC9, 0xDE, 0xDA, 0x98, 0x2A, 0x67, 0x9A, 0x5A, 0x91, 0x9B, 0x62, 0x6D, + 0x4E, 0x50, 0xA8, 0xDD, 0x73, 0x1B, 0x10, 0x7A, 0x99, 0x62, 0x38, 0x1F, + 0xB5, 0xD8, 0x07, 0xBF, 0x26, 0x18, + /* x */ + 0x12, 0x0F, 0xC0, 0x5D, 0x3C, 0x67, 0xA9, 0x9D, 0xE1, 0x61, 0xD2, 0xF4, + 0x09, 0x26, 0x22, 0xFE, 0xCA, 0x70, 0x1B, 0xE4, 0xF5, 0x0F, 0x47, 0x58, + 0x71, 0x4E, 0x8A, 0x87, 0xBB, 0xF2, 0xA6, 0x58, 0xEF, 0x8C, 0x21, 0xE7, + 0xC5, 0xEF, 0xE9, 0x65, 0x36, 0x1F, 0x6C, 0x29, 0x99, 0xC0, 0xC2, 0x47, + 0xB0, 0xDB, 0xD7, 0x0C, 0xE6, 0xB7, + /* y */ + 0x20, 0xD0, 0xAF, 0x89, 0x03, 0xA9, 0x6F, 0x8D, 0x5F, 0xA2, 0xC2, 0x55, + 0x74, 0x5D, 0x3C, 0x45, 0x1B, 0x30, 0x2C, 0x93, 0x46, 0xD9, 0xB7, 0xE4, + 0x85, 0xE7, 0xBC, 0xE4, 0x1F, 0x6B, 0x59, 0x1F, 0x3E, 0x8F, 0x6A, 0xDD, + 0xCB, 0xB0, 0xBC, 0x4C, 0x2F, 0x94, 0x7A, 0x7D, 0xE1, 0xA8, 0x9B, 0x62, + 0x5D, 0x6A, 0x59, 0x8B, 0x37, 0x60, + /* order */ + 0x00, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, + 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, 0x34, 0x03, 0x40, + 0x34, 0x03, 0x40, 0x34, 0x03, 0x23, 0xC3, 0x13, 0xFA, 0xB5, 0x05, 0x89, + 0x70, 0x3B, 0x5E, 0xC6, 0x8D, 0x35, 0x87, 0xFE, 0xC6, 0x0D, 0x16, 0x1C, + 0xC1, 0x49, 0xC1, 0xAD, 0x4A, 0x91 + } +}; + +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 15 * 6]; +} _EC_WTLS_1 = { + { + NID_X9_62_characteristic_two_field, 0, 15, 2 + }, + { + /* no seed */ + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x02, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, + /* x */ + 0x01, 0x66, 0x79, 0x79, 0xA4, 0x0B, 0xA4, 0x97, 0xE5, 0xD5, 0xC2, 0x70, + 0x78, 0x06, 0x17, + /* y */ + 0x00, 0xF4, 0x4B, 0x4A, 0xF1, 0xEC, 0xC2, 0x63, 0x0E, 0x08, 0x78, 0x5C, + 0xEB, 0xCC, 0x15, + /* order */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFD, 0xBF, 0x91, 0xAF, + 0x6D, 0xEA, 0x73 + } +}; + +/* IPSec curves */ +/* + * NOTE: The of curves over a extension field of non prime degree is not + * recommended (Weil-descent). As the group order is not a prime this curve + * is not suitable for ECDSA. + */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 20 * 6]; +} _EC_IPSEC_155_ID3 = { + { + NID_X9_62_characteristic_two_field, 0, 20, 3 + }, + { + /* no seed */ + /* p */ + 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x33, 0x8f, + /* x */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7b, + /* y */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc8, + /* order */ + 0x02, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xC7, 0xF3, + 0xC7, 0x88, 0x1B, 0xD0, 0x86, 0x8F, 0xA8, 0x6C + } +}; + +/* + * NOTE: The of curves over a extension field of non prime degree is not + * recommended (Weil-descent). As the group order is not a prime this curve + * is not suitable for ECDSA. + */ +static const struct { + EC_CURVE_DATA h; + unsigned char data[0 + 24 * 6]; +} _EC_IPSEC_185_ID4 = { + { + NID_X9_62_characteristic_two_field, 0, 24, 2 + }, + { + /* no seed */ + /* p */ + 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, + /* a */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + /* b */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0xe9, + /* x */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, + /* y */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, + /* order */ + 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xED, 0xF9, 0x7C, 0x44, 0xDB, 0x9F, 0x24, 0x20, 0xBA, 0xFC, 0xA7, 0x5E + } +}; + +#endif + +typedef struct _ec_list_element_st { + int nid; + const EC_CURVE_DATA *data; + const EC_METHOD *(*meth) (void); + const char *comment; +} ec_list_element; + +static const ec_list_element curve_list[] = { + /* prime field curves */ + /* secg curves */ + {NID_secp112r1, &_EC_SECG_PRIME_112R1.h, 0, + "SECG/WTLS curve over a 112 bit prime field"}, + {NID_secp112r2, &_EC_SECG_PRIME_112R2.h, 0, + "SECG curve over a 112 bit prime field"}, + {NID_secp128r1, &_EC_SECG_PRIME_128R1.h, 0, + "SECG curve over a 128 bit prime field"}, + {NID_secp128r2, &_EC_SECG_PRIME_128R2.h, 0, + "SECG curve over a 128 bit prime field"}, + {NID_secp160k1, &_EC_SECG_PRIME_160K1.h, 0, + "SECG curve over a 160 bit prime field"}, + {NID_secp160r1, &_EC_SECG_PRIME_160R1.h, 0, + "SECG curve over a 160 bit prime field"}, + {NID_secp160r2, &_EC_SECG_PRIME_160R2.h, 0, + "SECG/WTLS curve over a 160 bit prime field"}, + /* SECG secp192r1 is the same as X9.62 prime192v1 and hence omitted */ + {NID_secp192k1, &_EC_SECG_PRIME_192K1.h, 0, + "SECG curve over a 192 bit prime field"}, + {NID_secp224k1, &_EC_SECG_PRIME_224K1.h, 0, + "SECG curve over a 224 bit prime field"}, +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + {NID_secp224r1, &_EC_NIST_PRIME_224.h, EC_GFp_nistp224_method, + "NIST/SECG curve over a 224 bit prime field"}, +#else + {NID_secp224r1, &_EC_NIST_PRIME_224.h, 0, + "NIST/SECG curve over a 224 bit prime field"}, +#endif + {NID_secp256k1, &_EC_SECG_PRIME_256K1.h, 0, + "SECG curve over a 256 bit prime field"}, + /* SECG secp256r1 is the same as X9.62 prime256v1 and hence omitted */ + {NID_secp384r1, &_EC_NIST_PRIME_384.h, 0, + "NIST/SECG curve over a 384 bit prime field"}, +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + {NID_secp521r1, &_EC_NIST_PRIME_521.h, EC_GFp_nistp521_method, + "NIST/SECG curve over a 521 bit prime field"}, +#else + {NID_secp521r1, &_EC_NIST_PRIME_521.h, 0, + "NIST/SECG curve over a 521 bit prime field"}, +#endif + /* X9.62 curves */ + {NID_X9_62_prime192v1, &_EC_NIST_PRIME_192.h, 0, + "NIST/X9.62/SECG curve over a 192 bit prime field"}, + {NID_X9_62_prime192v2, &_EC_X9_62_PRIME_192V2.h, 0, + "X9.62 curve over a 192 bit prime field"}, + {NID_X9_62_prime192v3, &_EC_X9_62_PRIME_192V3.h, 0, + "X9.62 curve over a 192 bit prime field"}, + {NID_X9_62_prime239v1, &_EC_X9_62_PRIME_239V1.h, 0, + "X9.62 curve over a 239 bit prime field"}, + {NID_X9_62_prime239v2, &_EC_X9_62_PRIME_239V2.h, 0, + "X9.62 curve over a 239 bit prime field"}, + {NID_X9_62_prime239v3, &_EC_X9_62_PRIME_239V3.h, 0, + "X9.62 curve over a 239 bit prime field"}, +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, EC_GFp_nistp256_method, + "X9.62/SECG curve over a 256 bit prime field"}, +#else + {NID_X9_62_prime256v1, &_EC_X9_62_PRIME_256V1.h, 0, + "X9.62/SECG curve over a 256 bit prime field"}, +#endif +#ifndef OPENSSL_NO_EC2M + /* characteristic two field curves */ + /* NIST/SECG curves */ + {NID_sect113r1, &_EC_SECG_CHAR2_113R1.h, 0, + "SECG curve over a 113 bit binary field"}, + {NID_sect113r2, &_EC_SECG_CHAR2_113R2.h, 0, + "SECG curve over a 113 bit binary field"}, + {NID_sect131r1, &_EC_SECG_CHAR2_131R1.h, 0, + "SECG/WTLS curve over a 131 bit binary field"}, + {NID_sect131r2, &_EC_SECG_CHAR2_131R2.h, 0, + "SECG curve over a 131 bit binary field"}, + {NID_sect163k1, &_EC_NIST_CHAR2_163K.h, 0, + "NIST/SECG/WTLS curve over a 163 bit binary field"}, + {NID_sect163r1, &_EC_SECG_CHAR2_163R1.h, 0, + "SECG curve over a 163 bit binary field"}, + {NID_sect163r2, &_EC_NIST_CHAR2_163B.h, 0, + "NIST/SECG curve over a 163 bit binary field"}, + {NID_sect193r1, &_EC_SECG_CHAR2_193R1.h, 0, + "SECG curve over a 193 bit binary field"}, + {NID_sect193r2, &_EC_SECG_CHAR2_193R2.h, 0, + "SECG curve over a 193 bit binary field"}, + {NID_sect233k1, &_EC_NIST_CHAR2_233K.h, 0, + "NIST/SECG/WTLS curve over a 233 bit binary field"}, + {NID_sect233r1, &_EC_NIST_CHAR2_233B.h, 0, + "NIST/SECG/WTLS curve over a 233 bit binary field"}, + {NID_sect239k1, &_EC_SECG_CHAR2_239K1.h, 0, + "SECG curve over a 239 bit binary field"}, + {NID_sect283k1, &_EC_NIST_CHAR2_283K.h, 0, + "NIST/SECG curve over a 283 bit binary field"}, + {NID_sect283r1, &_EC_NIST_CHAR2_283B.h, 0, + "NIST/SECG curve over a 283 bit binary field"}, + {NID_sect409k1, &_EC_NIST_CHAR2_409K.h, 0, + "NIST/SECG curve over a 409 bit binary field"}, + {NID_sect409r1, &_EC_NIST_CHAR2_409B.h, 0, + "NIST/SECG curve over a 409 bit binary field"}, + {NID_sect571k1, &_EC_NIST_CHAR2_571K.h, 0, + "NIST/SECG curve over a 571 bit binary field"}, + {NID_sect571r1, &_EC_NIST_CHAR2_571B.h, 0, + "NIST/SECG curve over a 571 bit binary field"}, + /* X9.62 curves */ + {NID_X9_62_c2pnb163v1, &_EC_X9_62_CHAR2_163V1.h, 0, + "X9.62 curve over a 163 bit binary field"}, + {NID_X9_62_c2pnb163v2, &_EC_X9_62_CHAR2_163V2.h, 0, + "X9.62 curve over a 163 bit binary field"}, + {NID_X9_62_c2pnb163v3, &_EC_X9_62_CHAR2_163V3.h, 0, + "X9.62 curve over a 163 bit binary field"}, + {NID_X9_62_c2pnb176v1, &_EC_X9_62_CHAR2_176V1.h, 0, + "X9.62 curve over a 176 bit binary field"}, + {NID_X9_62_c2tnb191v1, &_EC_X9_62_CHAR2_191V1.h, 0, + "X9.62 curve over a 191 bit binary field"}, + {NID_X9_62_c2tnb191v2, &_EC_X9_62_CHAR2_191V2.h, 0, + "X9.62 curve over a 191 bit binary field"}, + {NID_X9_62_c2tnb191v3, &_EC_X9_62_CHAR2_191V3.h, 0, + "X9.62 curve over a 191 bit binary field"}, + {NID_X9_62_c2pnb208w1, &_EC_X9_62_CHAR2_208W1.h, 0, + "X9.62 curve over a 208 bit binary field"}, + {NID_X9_62_c2tnb239v1, &_EC_X9_62_CHAR2_239V1.h, 0, + "X9.62 curve over a 239 bit binary field"}, + {NID_X9_62_c2tnb239v2, &_EC_X9_62_CHAR2_239V2.h, 0, + "X9.62 curve over a 239 bit binary field"}, + {NID_X9_62_c2tnb239v3, &_EC_X9_62_CHAR2_239V3.h, 0, + "X9.62 curve over a 239 bit binary field"}, + {NID_X9_62_c2pnb272w1, &_EC_X9_62_CHAR2_272W1.h, 0, + "X9.62 curve over a 272 bit binary field"}, + {NID_X9_62_c2pnb304w1, &_EC_X9_62_CHAR2_304W1.h, 0, + "X9.62 curve over a 304 bit binary field"}, + {NID_X9_62_c2tnb359v1, &_EC_X9_62_CHAR2_359V1.h, 0, + "X9.62 curve over a 359 bit binary field"}, + {NID_X9_62_c2pnb368w1, &_EC_X9_62_CHAR2_368W1.h, 0, + "X9.62 curve over a 368 bit binary field"}, + {NID_X9_62_c2tnb431r1, &_EC_X9_62_CHAR2_431R1.h, 0, + "X9.62 curve over a 431 bit binary field"}, + /* + * the WAP/WTLS curves [unlike SECG, spec has its own OIDs for curves + * from X9.62] + */ + {NID_wap_wsg_idm_ecid_wtls1, &_EC_WTLS_1.h, 0, + "WTLS curve over a 113 bit binary field"}, + {NID_wap_wsg_idm_ecid_wtls3, &_EC_NIST_CHAR2_163K.h, 0, + "NIST/SECG/WTLS curve over a 163 bit binary field"}, + {NID_wap_wsg_idm_ecid_wtls4, &_EC_SECG_CHAR2_113R1.h, 0, + "SECG curve over a 113 bit binary field"}, + {NID_wap_wsg_idm_ecid_wtls5, &_EC_X9_62_CHAR2_163V1.h, 0, + "X9.62 curve over a 163 bit binary field"}, +#endif + {NID_wap_wsg_idm_ecid_wtls6, &_EC_SECG_PRIME_112R1.h, 0, + "SECG/WTLS curve over a 112 bit prime field"}, + {NID_wap_wsg_idm_ecid_wtls7, &_EC_SECG_PRIME_160R2.h, 0, + "SECG/WTLS curve over a 160 bit prime field"}, + {NID_wap_wsg_idm_ecid_wtls8, &_EC_WTLS_8.h, 0, + "WTLS curve over a 112 bit prime field"}, + {NID_wap_wsg_idm_ecid_wtls9, &_EC_WTLS_9.h, 0, + "WTLS curve over a 160 bit prime field"}, +#ifndef OPENSSL_NO_EC2M + {NID_wap_wsg_idm_ecid_wtls10, &_EC_NIST_CHAR2_233K.h, 0, + "NIST/SECG/WTLS curve over a 233 bit binary field"}, + {NID_wap_wsg_idm_ecid_wtls11, &_EC_NIST_CHAR2_233B.h, 0, + "NIST/SECG/WTLS curve over a 233 bit binary field"}, +#endif + {NID_wap_wsg_idm_ecid_wtls12, &_EC_WTLS_12.h, 0, + "WTLS curvs over a 224 bit prime field"}, +#ifndef OPENSSL_NO_EC2M + /* IPSec curves */ + {NID_ipsec3, &_EC_IPSEC_155_ID3.h, 0, + "\n\tIPSec/IKE/Oakley curve #3 over a 155 bit binary field.\n" + "\tNot suitable for ECDSA.\n\tQuestionable extension field!"}, + {NID_ipsec4, &_EC_IPSEC_185_ID4.h, 0, + "\n\tIPSec/IKE/Oakley curve #4 over a 185 bit binary field.\n" + "\tNot suitable for ECDSA.\n\tQuestionable extension field!"}, +#endif +}; + +#define curve_list_length (sizeof(curve_list)/sizeof(ec_list_element)) + +static EC_GROUP *ec_group_new_from_data(const ec_list_element curve) +{ + EC_GROUP *group = NULL; + EC_POINT *P = NULL; + BN_CTX *ctx = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL, *order = + NULL; + int ok = 0; + int seed_len, param_len; + const EC_METHOD *meth; + const EC_CURVE_DATA *data; + const unsigned char *params; + + if ((ctx = BN_CTX_new()) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_MALLOC_FAILURE); + goto err; + } + + data = curve.data; + seed_len = data->seed_len; + param_len = data->param_len; + params = (const unsigned char *)(data + 1); /* skip header */ + params += seed_len; /* skip seed */ + + if (!(p = BN_bin2bn(params + 0 * param_len, param_len, NULL)) + || !(a = BN_bin2bn(params + 1 * param_len, param_len, NULL)) + || !(b = BN_bin2bn(params + 2 * param_len, param_len, NULL))) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); + goto err; + } + + if (curve.meth != 0) { + meth = curve.meth(); + if (((group = EC_GROUP_new(meth)) == NULL) || + (!(group->meth->group_set_curve(group, p, a, b, ctx)))) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + } else if (data->field_type == NID_X9_62_prime_field) { + if ((group = EC_GROUP_new_curve_GFp(p, a, b, ctx)) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + } +#ifndef OPENSSL_NO_EC2M + else { /* field_type == + * NID_X9_62_characteristic_two_field */ + + if ((group = EC_GROUP_new_curve_GF2m(p, a, b, ctx)) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + } +#endif + + if ((P = EC_POINT_new(group)) == NULL) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + + if (!(x = BN_bin2bn(params + 3 * param_len, param_len, NULL)) + || !(y = BN_bin2bn(params + 4 * param_len, param_len, NULL))) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); + goto err; + } + if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + if (!(order = BN_bin2bn(params + 5 * param_len, param_len, NULL)) + || !BN_set_word(x, (BN_ULONG)data->cofactor)) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_BN_LIB); + goto err; + } + if (!EC_GROUP_set_generator(group, P, order, x)) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + if (seed_len) { + if (!EC_GROUP_set_seed(group, params - seed_len, seed_len)) { + ECerr(EC_F_EC_GROUP_NEW_FROM_DATA, ERR_R_EC_LIB); + goto err; + } + } + ok = 1; + err: + if (!ok) { + EC_GROUP_free(group); + group = NULL; + } + if (P) + EC_POINT_free(P); + if (ctx) + BN_CTX_free(ctx); + if (p) + BN_free(p); + if (a) + BN_free(a); + if (b) + BN_free(b); + if (order) + BN_free(order); + if (x) + BN_free(x); + if (y) + BN_free(y); + return group; +} + +EC_GROUP *EC_GROUP_new_by_curve_name(int nid) +{ + size_t i; + EC_GROUP *ret = NULL; + + if (nid <= 0) + return NULL; + + for (i = 0; i < curve_list_length; i++) + if (curve_list[i].nid == nid) { + ret = ec_group_new_from_data(curve_list[i]); + break; + } + + if (ret == NULL) { + ECerr(EC_F_EC_GROUP_NEW_BY_CURVE_NAME, EC_R_UNKNOWN_GROUP); + return NULL; + } + + EC_GROUP_set_curve_name(ret, nid); + + return ret; +} + +size_t EC_get_builtin_curves(EC_builtin_curve *r, size_t nitems) +{ + size_t i, min; + + if (r == NULL || nitems == 0) + return curve_list_length; + + min = nitems < curve_list_length ? nitems : curve_list_length; + + for (i = 0; i < min; i++) { + r[i].nid = curve_list[i].nid; + r[i].comment = curve_list[i].comment; + } + + return curve_list_length; +} diff --git a/libs/openssl/crypto/ec/ec_cvt.c b/libs/openssl/crypto/ec/ec_cvt.c new file mode 100644 index 00000000..487d7274 --- /dev/null +++ b/libs/openssl/crypto/ec/ec_cvt.c @@ -0,0 +1,168 @@ +/* crypto/ec/ec_cvt.c */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include +#include "ec_lcl.h" + +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + const EC_METHOD *meth; + EC_GROUP *ret; + +#if defined(OPENSSL_BN_ASM_MONT) + /* + * This might appear controversial, but the fact is that generic + * prime method was observed to deliver better performance even + * for NIST primes on a range of platforms, e.g.: 60%-15% + * improvement on IA-64, ~25% on ARM, 30%-90% on P4, 20%-25% + * in 32-bit build and 35%--12% in 64-bit build on Core2... + * Coefficients are relative to optimized bn_nist.c for most + * intensive ECDSA verify and ECDH operations for 192- and 521- + * bit keys respectively. Choice of these boundary values is + * arguable, because the dependency of improvement coefficient + * from key length is not a "monotone" curve. For example while + * 571-bit result is 23% on ARM, 384-bit one is -1%. But it's + * generally faster, sometimes "respectfully" faster, sometimes + * "tolerably" slower... What effectively happens is that loop + * with bn_mul_add_words is put against bn_mul_mont, and the + * latter "wins" on short vectors. Correct solution should be + * implementing dedicated NxN multiplication subroutines for + * small N. But till it materializes, let's stick to generic + * prime method... + * + */ + meth = EC_GFp_mont_method(); +#else + meth = EC_GFp_nist_method(); +#endif + + ret = EC_GROUP_new(meth); + if (ret == NULL) + return NULL; + + if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) { + unsigned long err; + + err = ERR_peek_last_error(); + + if (!(ERR_GET_LIB(err) == ERR_LIB_EC && + ((ERR_GET_REASON(err) == EC_R_NOT_A_NIST_PRIME) || + (ERR_GET_REASON(err) == EC_R_NOT_A_SUPPORTED_NIST_PRIME)))) { + /* real error */ + + EC_GROUP_clear_free(ret); + return NULL; + } + + /* + * not an actual error, we just cannot use EC_GFp_nist_method + */ + + ERR_clear_error(); + + EC_GROUP_clear_free(ret); + meth = EC_GFp_mont_method(); + + ret = EC_GROUP_new(meth); + if (ret == NULL) + return NULL; + + if (!EC_GROUP_set_curve_GFp(ret, p, a, b, ctx)) { + EC_GROUP_clear_free(ret); + return NULL; + } + } + + return ret; +} + +#ifndef OPENSSL_NO_EC2M +EC_GROUP *EC_GROUP_new_curve_GF2m(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + const EC_METHOD *meth; + EC_GROUP *ret; + + meth = EC_GF2m_simple_method(); + + ret = EC_GROUP_new(meth); + if (ret == NULL) + return NULL; + + if (!EC_GROUP_set_curve_GF2m(ret, p, a, b, ctx)) { + EC_GROUP_clear_free(ret); + return NULL; + } + + return ret; +} +#endif diff --git a/libs/openssl/crypto/ec/ec_err.c b/libs/openssl/crypto/ec/ec_err.c new file mode 100644 index 00000000..58eae7c6 --- /dev/null +++ b/libs/openssl/crypto/ec/ec_err.c @@ -0,0 +1,319 @@ +/* crypto/ec/ec_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EC,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EC,0,reason) + +static ERR_STRING_DATA EC_str_functs[] = { + {ERR_FUNC(EC_F_BN_TO_FELEM), "BN_TO_FELEM"}, + {ERR_FUNC(EC_F_COMPUTE_WNAF), "COMPUTE_WNAF"}, + {ERR_FUNC(EC_F_D2I_ECPARAMETERS), "d2i_ECParameters"}, + {ERR_FUNC(EC_F_D2I_ECPKPARAMETERS), "d2i_ECPKParameters"}, + {ERR_FUNC(EC_F_D2I_ECPRIVATEKEY), "d2i_ECPrivateKey"}, + {ERR_FUNC(EC_F_DO_EC_KEY_PRINT), "DO_EC_KEY_PRINT"}, + {ERR_FUNC(EC_F_ECKEY_PARAM2TYPE), "ECKEY_PARAM2TYPE"}, + {ERR_FUNC(EC_F_ECKEY_PARAM_DECODE), "ECKEY_PARAM_DECODE"}, + {ERR_FUNC(EC_F_ECKEY_PRIV_DECODE), "ECKEY_PRIV_DECODE"}, + {ERR_FUNC(EC_F_ECKEY_PRIV_ENCODE), "ECKEY_PRIV_ENCODE"}, + {ERR_FUNC(EC_F_ECKEY_PUB_DECODE), "ECKEY_PUB_DECODE"}, + {ERR_FUNC(EC_F_ECKEY_PUB_ENCODE), "ECKEY_PUB_ENCODE"}, + {ERR_FUNC(EC_F_ECKEY_TYPE2PARAM), "ECKEY_TYPE2PARAM"}, + {ERR_FUNC(EC_F_ECPARAMETERS_PRINT), "ECParameters_print"}, + {ERR_FUNC(EC_F_ECPARAMETERS_PRINT_FP), "ECParameters_print_fp"}, + {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT), "ECPKParameters_print"}, + {ERR_FUNC(EC_F_ECPKPARAMETERS_PRINT_FP), "ECPKParameters_print_fp"}, + {ERR_FUNC(EC_F_ECP_NIST_MOD_192), "ECP_NIST_MOD_192"}, + {ERR_FUNC(EC_F_ECP_NIST_MOD_224), "ECP_NIST_MOD_224"}, + {ERR_FUNC(EC_F_ECP_NIST_MOD_256), "ECP_NIST_MOD_256"}, + {ERR_FUNC(EC_F_ECP_NIST_MOD_521), "ECP_NIST_MOD_521"}, + {ERR_FUNC(EC_F_EC_ASN1_GROUP2CURVE), "EC_ASN1_GROUP2CURVE"}, + {ERR_FUNC(EC_F_EC_ASN1_GROUP2FIELDID), "EC_ASN1_GROUP2FIELDID"}, + {ERR_FUNC(EC_F_EC_ASN1_GROUP2PARAMETERS), "EC_ASN1_GROUP2PARAMETERS"}, + {ERR_FUNC(EC_F_EC_ASN1_GROUP2PKPARAMETERS), "EC_ASN1_GROUP2PKPARAMETERS"}, + {ERR_FUNC(EC_F_EC_ASN1_PARAMETERS2GROUP), "EC_ASN1_PARAMETERS2GROUP"}, + {ERR_FUNC(EC_F_EC_ASN1_PKPARAMETERS2GROUP), "EC_ASN1_PKPARAMETERS2GROUP"}, + {ERR_FUNC(EC_F_EC_EX_DATA_SET_DATA), "EC_EX_DATA_set_data"}, + {ERR_FUNC(EC_F_EC_GF2M_MONTGOMERY_POINT_MULTIPLY), + "EC_GF2M_MONTGOMERY_POINT_MULTIPLY"}, + {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_CHECK_DISCRIMINANT), + "ec_GF2m_simple_group_check_discriminant"}, + {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_GROUP_SET_CURVE), + "ec_GF2m_simple_group_set_curve"}, + {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_OCT2POINT), "ec_GF2m_simple_oct2point"}, + {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT2OCT), "ec_GF2m_simple_point2oct"}, + {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_GET_AFFINE_COORDINATES), + "ec_GF2m_simple_point_get_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_POINT_SET_AFFINE_COORDINATES), + "ec_GF2m_simple_point_set_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_GF2M_SIMPLE_SET_COMPRESSED_COORDINATES), + "ec_GF2m_simple_set_compressed_coordinates"}, + {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_DECODE), "ec_GFp_mont_field_decode"}, + {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_ENCODE), "ec_GFp_mont_field_encode"}, + {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_MUL), "ec_GFp_mont_field_mul"}, + {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE), + "ec_GFp_mont_field_set_to_one"}, + {ERR_FUNC(EC_F_EC_GFP_MONT_FIELD_SQR), "ec_GFp_mont_field_sqr"}, + {ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE), + "ec_GFp_mont_group_set_curve"}, + {ERR_FUNC(EC_F_EC_GFP_MONT_GROUP_SET_CURVE_GFP), + "EC_GFP_MONT_GROUP_SET_CURVE_GFP"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE), + "ec_GFp_nistp224_group_set_curve"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINTS_MUL), "ec_GFp_nistp224_points_mul"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES), + "ec_GFp_nistp224_point_get_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE), + "ec_GFp_nistp256_group_set_curve"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINTS_MUL), "ec_GFp_nistp256_points_mul"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES), + "ec_GFp_nistp256_point_get_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE), + "ec_GFp_nistp521_group_set_curve"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINTS_MUL), "ec_GFp_nistp521_points_mul"}, + {ERR_FUNC(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES), + "ec_GFp_nistp521_point_get_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_MUL), "ec_GFp_nist_field_mul"}, + {ERR_FUNC(EC_F_EC_GFP_NIST_FIELD_SQR), "ec_GFp_nist_field_sqr"}, + {ERR_FUNC(EC_F_EC_GFP_NIST_GROUP_SET_CURVE), + "ec_GFp_nist_group_set_curve"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT), + "ec_GFp_simple_group_check_discriminant"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE), + "ec_GFp_simple_group_set_curve"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP), + "EC_GFP_SIMPLE_GROUP_SET_CURVE_GFP"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_GROUP_SET_GENERATOR), + "EC_GFP_SIMPLE_GROUP_SET_GENERATOR"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE), "ec_GFp_simple_make_affine"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_OCT2POINT), "ec_GFp_simple_oct2point"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT2OCT), "ec_GFp_simple_point2oct"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE), + "ec_GFp_simple_points_make_affine"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES), + "ec_GFp_simple_point_get_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP), + "EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES_GFP"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES), + "ec_GFp_simple_point_set_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP), + "EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES_GFP"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES), + "ec_GFp_simple_set_compressed_coordinates"}, + {ERR_FUNC(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP), + "EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES_GFP"}, + {ERR_FUNC(EC_F_EC_GROUP_CHECK), "EC_GROUP_check"}, + {ERR_FUNC(EC_F_EC_GROUP_CHECK_DISCRIMINANT), + "EC_GROUP_check_discriminant"}, + {ERR_FUNC(EC_F_EC_GROUP_COPY), "EC_GROUP_copy"}, + {ERR_FUNC(EC_F_EC_GROUP_GET0_GENERATOR), "EC_GROUP_get0_generator"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_COFACTOR), "EC_GROUP_get_cofactor"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GF2M), "EC_GROUP_get_curve_GF2m"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_CURVE_GFP), "EC_GROUP_get_curve_GFp"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_DEGREE), "EC_GROUP_get_degree"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_ORDER), "EC_GROUP_get_order"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_PENTANOMIAL_BASIS), + "EC_GROUP_get_pentanomial_basis"}, + {ERR_FUNC(EC_F_EC_GROUP_GET_TRINOMIAL_BASIS), + "EC_GROUP_get_trinomial_basis"}, + {ERR_FUNC(EC_F_EC_GROUP_NEW), "EC_GROUP_new"}, + {ERR_FUNC(EC_F_EC_GROUP_NEW_BY_CURVE_NAME), "EC_GROUP_new_by_curve_name"}, + {ERR_FUNC(EC_F_EC_GROUP_NEW_FROM_DATA), "EC_GROUP_NEW_FROM_DATA"}, + {ERR_FUNC(EC_F_EC_GROUP_PRECOMPUTE_MULT), "EC_GROUP_precompute_mult"}, + {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GF2M), "EC_GROUP_set_curve_GF2m"}, + {ERR_FUNC(EC_F_EC_GROUP_SET_CURVE_GFP), "EC_GROUP_set_curve_GFp"}, + {ERR_FUNC(EC_F_EC_GROUP_SET_EXTRA_DATA), "EC_GROUP_SET_EXTRA_DATA"}, + {ERR_FUNC(EC_F_EC_GROUP_SET_GENERATOR), "EC_GROUP_set_generator"}, + {ERR_FUNC(EC_F_EC_KEY_CHECK_KEY), "EC_KEY_check_key"}, + {ERR_FUNC(EC_F_EC_KEY_COPY), "EC_KEY_copy"}, + {ERR_FUNC(EC_F_EC_KEY_GENERATE_KEY), "EC_KEY_generate_key"}, + {ERR_FUNC(EC_F_EC_KEY_NEW), "EC_KEY_new"}, + {ERR_FUNC(EC_F_EC_KEY_PRINT), "EC_KEY_print"}, + {ERR_FUNC(EC_F_EC_KEY_PRINT_FP), "EC_KEY_print_fp"}, + {ERR_FUNC(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES), + "EC_KEY_set_public_key_affine_coordinates"}, + {ERR_FUNC(EC_F_EC_POINTS_MAKE_AFFINE), "EC_POINTs_make_affine"}, + {ERR_FUNC(EC_F_EC_POINT_ADD), "EC_POINT_add"}, + {ERR_FUNC(EC_F_EC_POINT_CMP), "EC_POINT_cmp"}, + {ERR_FUNC(EC_F_EC_POINT_COPY), "EC_POINT_copy"}, + {ERR_FUNC(EC_F_EC_POINT_DBL), "EC_POINT_dbl"}, + {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M), + "EC_POINT_get_affine_coordinates_GF2m"}, + {ERR_FUNC(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP), + "EC_POINT_get_affine_coordinates_GFp"}, + {ERR_FUNC(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP), + "EC_POINT_get_Jprojective_coordinates_GFp"}, + {ERR_FUNC(EC_F_EC_POINT_INVERT), "EC_POINT_invert"}, + {ERR_FUNC(EC_F_EC_POINT_IS_AT_INFINITY), "EC_POINT_is_at_infinity"}, + {ERR_FUNC(EC_F_EC_POINT_IS_ON_CURVE), "EC_POINT_is_on_curve"}, + {ERR_FUNC(EC_F_EC_POINT_MAKE_AFFINE), "EC_POINT_make_affine"}, + {ERR_FUNC(EC_F_EC_POINT_MUL), "EC_POINT_mul"}, + {ERR_FUNC(EC_F_EC_POINT_NEW), "EC_POINT_new"}, + {ERR_FUNC(EC_F_EC_POINT_OCT2POINT), "EC_POINT_oct2point"}, + {ERR_FUNC(EC_F_EC_POINT_POINT2OCT), "EC_POINT_point2oct"}, + {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M), + "EC_POINT_set_affine_coordinates_GF2m"}, + {ERR_FUNC(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP), + "EC_POINT_set_affine_coordinates_GFp"}, + {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M), + "EC_POINT_set_compressed_coordinates_GF2m"}, + {ERR_FUNC(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP), + "EC_POINT_set_compressed_coordinates_GFp"}, + {ERR_FUNC(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP), + "EC_POINT_set_Jprojective_coordinates_GFp"}, + {ERR_FUNC(EC_F_EC_POINT_SET_TO_INFINITY), "EC_POINT_set_to_infinity"}, + {ERR_FUNC(EC_F_EC_PRE_COMP_DUP), "EC_PRE_COMP_DUP"}, + {ERR_FUNC(EC_F_EC_PRE_COMP_NEW), "EC_PRE_COMP_NEW"}, + {ERR_FUNC(EC_F_EC_WNAF_MUL), "ec_wNAF_mul"}, + {ERR_FUNC(EC_F_EC_WNAF_PRECOMPUTE_MULT), "ec_wNAF_precompute_mult"}, + {ERR_FUNC(EC_F_I2D_ECPARAMETERS), "i2d_ECParameters"}, + {ERR_FUNC(EC_F_I2D_ECPKPARAMETERS), "i2d_ECPKParameters"}, + {ERR_FUNC(EC_F_I2D_ECPRIVATEKEY), "i2d_ECPrivateKey"}, + {ERR_FUNC(EC_F_I2O_ECPUBLICKEY), "i2o_ECPublicKey"}, + {ERR_FUNC(EC_F_NISTP224_PRE_COMP_NEW), "NISTP224_PRE_COMP_NEW"}, + {ERR_FUNC(EC_F_NISTP256_PRE_COMP_NEW), "NISTP256_PRE_COMP_NEW"}, + {ERR_FUNC(EC_F_NISTP521_PRE_COMP_NEW), "NISTP521_PRE_COMP_NEW"}, + {ERR_FUNC(EC_F_O2I_ECPUBLICKEY), "o2i_ECPublicKey"}, + {ERR_FUNC(EC_F_OLD_EC_PRIV_DECODE), "OLD_EC_PRIV_DECODE"}, + {ERR_FUNC(EC_F_PKEY_EC_CTRL), "PKEY_EC_CTRL"}, + {ERR_FUNC(EC_F_PKEY_EC_CTRL_STR), "PKEY_EC_CTRL_STR"}, + {ERR_FUNC(EC_F_PKEY_EC_DERIVE), "PKEY_EC_DERIVE"}, + {ERR_FUNC(EC_F_PKEY_EC_KEYGEN), "PKEY_EC_KEYGEN"}, + {ERR_FUNC(EC_F_PKEY_EC_PARAMGEN), "PKEY_EC_PARAMGEN"}, + {ERR_FUNC(EC_F_PKEY_EC_SIGN), "PKEY_EC_SIGN"}, + {0, NULL} +}; + +static ERR_STRING_DATA EC_str_reasons[] = { + {ERR_REASON(EC_R_ASN1_ERROR), "asn1 error"}, + {ERR_REASON(EC_R_ASN1_UNKNOWN_FIELD), "asn1 unknown field"}, + {ERR_REASON(EC_R_BIGNUM_OUT_OF_RANGE), "bignum out of range"}, + {ERR_REASON(EC_R_BUFFER_TOO_SMALL), "buffer too small"}, + {ERR_REASON(EC_R_COORDINATES_OUT_OF_RANGE), "coordinates out of range"}, + {ERR_REASON(EC_R_D2I_ECPKPARAMETERS_FAILURE), + "d2i ecpkparameters failure"}, + {ERR_REASON(EC_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(EC_R_DISCRIMINANT_IS_ZERO), "discriminant is zero"}, + {ERR_REASON(EC_R_EC_GROUP_NEW_BY_NAME_FAILURE), + "ec group new by name failure"}, + {ERR_REASON(EC_R_FIELD_TOO_LARGE), "field too large"}, + {ERR_REASON(EC_R_GF2M_NOT_SUPPORTED), "gf2m not supported"}, + {ERR_REASON(EC_R_GROUP2PKPARAMETERS_FAILURE), + "group2pkparameters failure"}, + {ERR_REASON(EC_R_I2D_ECPKPARAMETERS_FAILURE), + "i2d ecpkparameters failure"}, + {ERR_REASON(EC_R_INCOMPATIBLE_OBJECTS), "incompatible objects"}, + {ERR_REASON(EC_R_INVALID_ARGUMENT), "invalid argument"}, + {ERR_REASON(EC_R_INVALID_COMPRESSED_POINT), "invalid compressed point"}, + {ERR_REASON(EC_R_INVALID_COMPRESSION_BIT), "invalid compression bit"}, + {ERR_REASON(EC_R_INVALID_CURVE), "invalid curve"}, + {ERR_REASON(EC_R_INVALID_DIGEST_TYPE), "invalid digest type"}, + {ERR_REASON(EC_R_INVALID_ENCODING), "invalid encoding"}, + {ERR_REASON(EC_R_INVALID_FIELD), "invalid field"}, + {ERR_REASON(EC_R_INVALID_FORM), "invalid form"}, + {ERR_REASON(EC_R_INVALID_GROUP_ORDER), "invalid group order"}, + {ERR_REASON(EC_R_INVALID_PENTANOMIAL_BASIS), "invalid pentanomial basis"}, + {ERR_REASON(EC_R_INVALID_PRIVATE_KEY), "invalid private key"}, + {ERR_REASON(EC_R_INVALID_TRINOMIAL_BASIS), "invalid trinomial basis"}, + {ERR_REASON(EC_R_KEYS_NOT_SET), "keys not set"}, + {ERR_REASON(EC_R_MISSING_PARAMETERS), "missing parameters"}, + {ERR_REASON(EC_R_MISSING_PRIVATE_KEY), "missing private key"}, + {ERR_REASON(EC_R_NOT_A_NIST_PRIME), "not a NIST prime"}, + {ERR_REASON(EC_R_NOT_A_SUPPORTED_NIST_PRIME), + "not a supported NIST prime"}, + {ERR_REASON(EC_R_NOT_IMPLEMENTED), "not implemented"}, + {ERR_REASON(EC_R_NOT_INITIALIZED), "not initialized"}, + {ERR_REASON(EC_R_NO_FIELD_MOD), "no field mod"}, + {ERR_REASON(EC_R_NO_PARAMETERS_SET), "no parameters set"}, + {ERR_REASON(EC_R_PASSED_NULL_PARAMETER), "passed null parameter"}, + {ERR_REASON(EC_R_PKPARAMETERS2GROUP_FAILURE), + "pkparameters2group failure"}, + {ERR_REASON(EC_R_POINT_AT_INFINITY), "point at infinity"}, + {ERR_REASON(EC_R_POINT_IS_NOT_ON_CURVE), "point is not on curve"}, + {ERR_REASON(EC_R_SLOT_FULL), "slot full"}, + {ERR_REASON(EC_R_UNDEFINED_GENERATOR), "undefined generator"}, + {ERR_REASON(EC_R_UNDEFINED_ORDER), "undefined order"}, + {ERR_REASON(EC_R_UNKNOWN_GROUP), "unknown group"}, + {ERR_REASON(EC_R_UNKNOWN_ORDER), "unknown order"}, + {ERR_REASON(EC_R_UNSUPPORTED_FIELD), "unsupported field"}, + {ERR_REASON(EC_R_WRONG_CURVE_PARAMETERS), "wrong curve parameters"}, + {ERR_REASON(EC_R_WRONG_ORDER), "wrong order"}, + {0, NULL} +}; + +#endif + +void ERR_load_EC_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(EC_str_functs[0].error) == NULL) { + ERR_load_strings(0, EC_str_functs); + ERR_load_strings(0, EC_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/ec/ec_key.c b/libs/openssl/crypto/ec/ec_key.c new file mode 100644 index 00000000..c784b6fd --- /dev/null +++ b/libs/openssl/crypto/ec/ec_key.c @@ -0,0 +1,563 @@ +/* crypto/ec/ec_key.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions originally developed by SUN MICROSYSTEMS, INC., and + * contributed to the OpenSSL project. + */ + +#include +#include "ec_lcl.h" +#include +#ifdef OPENSSL_FIPS +# include +#endif + +EC_KEY *EC_KEY_new(void) +{ + EC_KEY *ret; + + ret = (EC_KEY *)OPENSSL_malloc(sizeof(EC_KEY)); + if (ret == NULL) { + ECerr(EC_F_EC_KEY_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + ret->version = 1; + ret->flags = 0; + ret->group = NULL; + ret->pub_key = NULL; + ret->priv_key = NULL; + ret->enc_flag = 0; + ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; + ret->references = 1; + ret->method_data = NULL; + return (ret); +} + +EC_KEY *EC_KEY_new_by_curve_name(int nid) +{ + EC_KEY *ret = EC_KEY_new(); + if (ret == NULL) + return NULL; + ret->group = EC_GROUP_new_by_curve_name(nid); + if (ret->group == NULL) { + EC_KEY_free(ret); + return NULL; + } + return ret; +} + +void EC_KEY_free(EC_KEY *r) +{ + int i; + + if (r == NULL) + return; + + i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC); +#ifdef REF_PRINT + REF_PRINT("EC_KEY", r); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "EC_KEY_free, bad reference count\n"); + abort(); + } +#endif + + if (r->group != NULL) + EC_GROUP_free(r->group); + if (r->pub_key != NULL) + EC_POINT_free(r->pub_key); + if (r->priv_key != NULL) + BN_clear_free(r->priv_key); + + EC_EX_DATA_free_all_data(&r->method_data); + + OPENSSL_cleanse((void *)r, sizeof(EC_KEY)); + + OPENSSL_free(r); +} + +EC_KEY *EC_KEY_copy(EC_KEY *dest, const EC_KEY *src) +{ + EC_EXTRA_DATA *d; + + if (dest == NULL || src == NULL) { + ECerr(EC_F_EC_KEY_COPY, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + /* copy the parameters */ + if (src->group) { + const EC_METHOD *meth = EC_GROUP_method_of(src->group); + /* clear the old group */ + if (dest->group) + EC_GROUP_free(dest->group); + dest->group = EC_GROUP_new(meth); + if (dest->group == NULL) + return NULL; + if (!EC_GROUP_copy(dest->group, src->group)) + return NULL; + } + /* copy the public key */ + if (src->pub_key && src->group) { + if (dest->pub_key) + EC_POINT_free(dest->pub_key); + dest->pub_key = EC_POINT_new(src->group); + if (dest->pub_key == NULL) + return NULL; + if (!EC_POINT_copy(dest->pub_key, src->pub_key)) + return NULL; + } + /* copy the private key */ + if (src->priv_key) { + if (dest->priv_key == NULL) { + dest->priv_key = BN_new(); + if (dest->priv_key == NULL) + return NULL; + } + if (!BN_copy(dest->priv_key, src->priv_key)) + return NULL; + } + /* copy method/extra data */ + EC_EX_DATA_free_all_data(&dest->method_data); + + for (d = src->method_data; d != NULL; d = d->next) { + void *t = d->dup_func(d->data); + + if (t == NULL) + return 0; + if (!EC_EX_DATA_set_data + (&dest->method_data, t, d->dup_func, d->free_func, + d->clear_free_func)) + return 0; + } + + /* copy the rest */ + dest->enc_flag = src->enc_flag; + dest->conv_form = src->conv_form; + dest->version = src->version; + dest->flags = src->flags; + + return dest; +} + +EC_KEY *EC_KEY_dup(const EC_KEY *ec_key) +{ + EC_KEY *ret = EC_KEY_new(); + if (ret == NULL) + return NULL; + if (EC_KEY_copy(ret, ec_key) == NULL) { + EC_KEY_free(ret); + return NULL; + } + return ret; +} + +int EC_KEY_up_ref(EC_KEY *r) +{ + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC); +#ifdef REF_PRINT + REF_PRINT("EC_KEY", r); +#endif +#ifdef REF_CHECK + if (i < 2) { + fprintf(stderr, "EC_KEY_up, bad reference count\n"); + abort(); + } +#endif + return ((i > 1) ? 1 : 0); +} + +int EC_KEY_generate_key(EC_KEY *eckey) +{ + int ok = 0; + BN_CTX *ctx = NULL; + BIGNUM *priv_key = NULL, *order = NULL; + EC_POINT *pub_key = NULL; + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_ec_key_generate_key(eckey); +#endif + + if (!eckey || !eckey->group) { + ECerr(EC_F_EC_KEY_GENERATE_KEY, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if ((order = BN_new()) == NULL) + goto err; + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + if (eckey->priv_key == NULL) { + priv_key = BN_new(); + if (priv_key == NULL) + goto err; + } else + priv_key = eckey->priv_key; + + if (!EC_GROUP_get_order(eckey->group, order, ctx)) + goto err; + + do + if (!BN_rand_range(priv_key, order)) + goto err; + while (BN_is_zero(priv_key)) ; + + if (eckey->pub_key == NULL) { + pub_key = EC_POINT_new(eckey->group); + if (pub_key == NULL) + goto err; + } else + pub_key = eckey->pub_key; + + if (!EC_POINT_mul(eckey->group, pub_key, priv_key, NULL, NULL, ctx)) + goto err; + + eckey->priv_key = priv_key; + eckey->pub_key = pub_key; + + ok = 1; + + err: + if (order) + BN_free(order); + if (pub_key != NULL && eckey->pub_key == NULL) + EC_POINT_free(pub_key); + if (priv_key != NULL && eckey->priv_key == NULL) + BN_free(priv_key); + if (ctx != NULL) + BN_CTX_free(ctx); + return (ok); +} + +int EC_KEY_check_key(const EC_KEY *eckey) +{ + int ok = 0; + BN_CTX *ctx = NULL; + const BIGNUM *order = NULL; + EC_POINT *point = NULL; + + if (!eckey || !eckey->group || !eckey->pub_key) { + ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_AT_INFINITY); + goto err; + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + if ((point = EC_POINT_new(eckey->group)) == NULL) + goto err; + + /* testing whether the pub_key is on the elliptic curve */ + if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + /* testing whether pub_key * order is the point at infinity */ + order = &eckey->group->order; + if (BN_is_zero(order)) { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_GROUP_ORDER); + goto err; + } + if (!EC_POINT_mul(eckey->group, point, NULL, eckey->pub_key, order, ctx)) { + ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); + goto err; + } + if (!EC_POINT_is_at_infinity(eckey->group, point)) { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); + goto err; + } + /* + * in case the priv_key is present : check if generator * priv_key == + * pub_key + */ + if (eckey->priv_key) { + if (BN_cmp(eckey->priv_key, order) >= 0) { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_WRONG_ORDER); + goto err; + } + if (!EC_POINT_mul(eckey->group, point, eckey->priv_key, + NULL, NULL, ctx)) { + ECerr(EC_F_EC_KEY_CHECK_KEY, ERR_R_EC_LIB); + goto err; + } + if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_INVALID_PRIVATE_KEY); + goto err; + } + } + ok = 1; + err: + if (ctx != NULL) + BN_CTX_free(ctx); + if (point != NULL) + EC_POINT_free(point); + return (ok); +} + +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, + BIGNUM *y) +{ + BN_CTX *ctx = NULL; + BIGNUM *tx, *ty; + EC_POINT *point = NULL; + int ok = 0; +#ifndef OPENSSL_NO_EC2M + int tmp_nid, is_char_two = 0; +#endif + + if (!key || !key->group || !x || !y) { + ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + ctx = BN_CTX_new(); + if (!ctx) + goto err; + + point = EC_POINT_new(key->group); + + if (!point) + goto err; + + tx = BN_CTX_get(ctx); + ty = BN_CTX_get(ctx); + +#ifndef OPENSSL_NO_EC2M + tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(key->group)); + + if (tmp_nid == NID_X9_62_characteristic_two_field) + is_char_two = 1; + + if (is_char_two) { + if (!EC_POINT_set_affine_coordinates_GF2m(key->group, point, + x, y, ctx)) + goto err; + if (!EC_POINT_get_affine_coordinates_GF2m(key->group, point, + tx, ty, ctx)) + goto err; + } else +#endif + { + if (!EC_POINT_set_affine_coordinates_GFp(key->group, point, + x, y, ctx)) + goto err; + if (!EC_POINT_get_affine_coordinates_GFp(key->group, point, + tx, ty, ctx)) + goto err; + } + /* + * Check if retrieved coordinates match originals: if not values are out + * of range. + */ + if (BN_cmp(x, tx) || BN_cmp(y, ty)) { + ECerr(EC_F_EC_KEY_SET_PUBLIC_KEY_AFFINE_COORDINATES, + EC_R_COORDINATES_OUT_OF_RANGE); + goto err; + } + + if (!EC_KEY_set_public_key(key, point)) + goto err; + + if (EC_KEY_check_key(key) == 0) + goto err; + + ok = 1; + + err: + if (ctx) + BN_CTX_free(ctx); + if (point) + EC_POINT_free(point); + return ok; + +} + +const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key) +{ + return key->group; +} + +int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group) +{ + if (key->group != NULL) + EC_GROUP_free(key->group); + key->group = EC_GROUP_dup(group); + return (key->group == NULL) ? 0 : 1; +} + +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) +{ + return key->priv_key; +} + +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) +{ + if (key->priv_key) + BN_clear_free(key->priv_key); + key->priv_key = BN_dup(priv_key); + return (key->priv_key == NULL) ? 0 : 1; +} + +const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key) +{ + return key->pub_key; +} + +int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub_key) +{ + if (key->pub_key != NULL) + EC_POINT_free(key->pub_key); + key->pub_key = EC_POINT_dup(pub_key, key->group); + return (key->pub_key == NULL) ? 0 : 1; +} + +unsigned int EC_KEY_get_enc_flags(const EC_KEY *key) +{ + return key->enc_flag; +} + +void EC_KEY_set_enc_flags(EC_KEY *key, unsigned int flags) +{ + key->enc_flag = flags; +} + +point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key) +{ + return key->conv_form; +} + +void EC_KEY_set_conv_form(EC_KEY *key, point_conversion_form_t cform) +{ + key->conv_form = cform; + if (key->group != NULL) + EC_GROUP_set_point_conversion_form(key->group, cform); +} + +void *EC_KEY_get_key_method_data(EC_KEY *key, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)) +{ + void *ret; + + CRYPTO_r_lock(CRYPTO_LOCK_EC); + ret = + EC_EX_DATA_get_data(key->method_data, dup_func, free_func, + clear_free_func); + CRYPTO_r_unlock(CRYPTO_LOCK_EC); + + return ret; +} + +void *EC_KEY_insert_key_method_data(EC_KEY *key, void *data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)) +{ + EC_EXTRA_DATA *ex_data; + + CRYPTO_w_lock(CRYPTO_LOCK_EC); + ex_data = + EC_EX_DATA_get_data(key->method_data, dup_func, free_func, + clear_free_func); + if (ex_data == NULL) + EC_EX_DATA_set_data(&key->method_data, data, dup_func, free_func, + clear_free_func); + CRYPTO_w_unlock(CRYPTO_LOCK_EC); + + return ex_data; +} + +void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) +{ + if (key->group != NULL) + EC_GROUP_set_asn1_flag(key->group, flag); +} + +int EC_KEY_precompute_mult(EC_KEY *key, BN_CTX *ctx) +{ + if (key->group == NULL) + return 0; + return EC_GROUP_precompute_mult(key->group, ctx); +} + +int EC_KEY_get_flags(const EC_KEY *key) +{ + return key->flags; +} + +void EC_KEY_set_flags(EC_KEY *key, int flags) +{ + key->flags |= flags; +} + +void EC_KEY_clear_flags(EC_KEY *key, int flags) +{ + key->flags &= ~flags; +} diff --git a/libs/openssl/crypto/ec/ec_lcl.h b/libs/openssl/crypto/ec/ec_lcl.h new file mode 100644 index 00000000..d79ed1e4 --- /dev/null +++ b/libs/openssl/crypto/ec/ec_lcl.h @@ -0,0 +1,543 @@ +/* crypto/ec/ec_lcl.h */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include + +#include +#include +#include + +#if defined(__SUNPRO_C) +# if __SUNPRO_C >= 0x520 +# pragma error_messages (off,E_ARRAY_OF_INCOMPLETE_NONAME,E_ARRAY_OF_INCOMPLETE) +# endif +#endif + +/* Use default functions for poin2oct, oct2point and compressed coordinates */ +#define EC_FLAGS_DEFAULT_OCT 0x1 + +/* + * Structure details are not part of the exported interface, so all this may + * change in future versions. + */ + +struct ec_method_st { + /* Various method flags */ + int flags; + /* used by EC_METHOD_get_field_type: */ + int field_type; /* a NID */ + /* + * used by EC_GROUP_new, EC_GROUP_free, EC_GROUP_clear_free, + * EC_GROUP_copy: + */ + int (*group_init) (EC_GROUP *); + void (*group_finish) (EC_GROUP *); + void (*group_clear_finish) (EC_GROUP *); + int (*group_copy) (EC_GROUP *, const EC_GROUP *); + /* used by EC_GROUP_set_curve_GFp, EC_GROUP_get_curve_GFp, */ + /* EC_GROUP_set_curve_GF2m, and EC_GROUP_get_curve_GF2m: */ + int (*group_set_curve) (EC_GROUP *, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); + int (*group_get_curve) (const EC_GROUP *, BIGNUM *p, BIGNUM *a, BIGNUM *b, + BN_CTX *); + /* used by EC_GROUP_get_degree: */ + int (*group_get_degree) (const EC_GROUP *); + /* used by EC_GROUP_check: */ + int (*group_check_discriminant) (const EC_GROUP *, BN_CTX *); + /* + * used by EC_POINT_new, EC_POINT_free, EC_POINT_clear_free, + * EC_POINT_copy: + */ + int (*point_init) (EC_POINT *); + void (*point_finish) (EC_POINT *); + void (*point_clear_finish) (EC_POINT *); + int (*point_copy) (EC_POINT *, const EC_POINT *); + /*- + * used by EC_POINT_set_to_infinity, + * EC_POINT_set_Jprojective_coordinates_GFp, + * EC_POINT_get_Jprojective_coordinates_GFp, + * EC_POINT_set_affine_coordinates_GFp, ..._GF2m, + * EC_POINT_get_affine_coordinates_GFp, ..._GF2m, + * EC_POINT_set_compressed_coordinates_GFp, ..._GF2m: + */ + int (*point_set_to_infinity) (const EC_GROUP *, EC_POINT *); + int (*point_set_Jprojective_coordinates_GFp) (const EC_GROUP *, + EC_POINT *, const BIGNUM *x, + const BIGNUM *y, + const BIGNUM *z, BN_CTX *); + int (*point_get_Jprojective_coordinates_GFp) (const EC_GROUP *, + const EC_POINT *, BIGNUM *x, + BIGNUM *y, BIGNUM *z, + BN_CTX *); + int (*point_set_affine_coordinates) (const EC_GROUP *, EC_POINT *, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *); + int (*point_get_affine_coordinates) (const EC_GROUP *, const EC_POINT *, + BIGNUM *x, BIGNUM *y, BN_CTX *); + int (*point_set_compressed_coordinates) (const EC_GROUP *, EC_POINT *, + const BIGNUM *x, int y_bit, + BN_CTX *); + /* used by EC_POINT_point2oct, EC_POINT_oct2point: */ + size_t (*point2oct) (const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, unsigned char *buf, + size_t len, BN_CTX *); + int (*oct2point) (const EC_GROUP *, EC_POINT *, const unsigned char *buf, + size_t len, BN_CTX *); + /* used by EC_POINT_add, EC_POINT_dbl, ECP_POINT_invert: */ + int (*add) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *); + int (*dbl) (const EC_GROUP *, EC_POINT *r, const EC_POINT *a, BN_CTX *); + int (*invert) (const EC_GROUP *, EC_POINT *, BN_CTX *); + /* + * used by EC_POINT_is_at_infinity, EC_POINT_is_on_curve, EC_POINT_cmp: + */ + int (*is_at_infinity) (const EC_GROUP *, const EC_POINT *); + int (*is_on_curve) (const EC_GROUP *, const EC_POINT *, BN_CTX *); + int (*point_cmp) (const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, + BN_CTX *); + /* used by EC_POINT_make_affine, EC_POINTs_make_affine: */ + int (*make_affine) (const EC_GROUP *, EC_POINT *, BN_CTX *); + int (*points_make_affine) (const EC_GROUP *, size_t num, EC_POINT *[], + BN_CTX *); + /* + * used by EC_POINTs_mul, EC_POINT_mul, EC_POINT_precompute_mult, + * EC_POINT_have_precompute_mult (default implementations are used if the + * 'mul' pointer is 0): + */ + int (*mul) (const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + size_t num, const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); + int (*precompute_mult) (EC_GROUP *group, BN_CTX *); + int (*have_precompute_mult) (const EC_GROUP *group); + /* internal functions */ + /* + * 'field_mul', 'field_sqr', and 'field_div' can be used by 'add' and + * 'dbl' so that the same implementations of point operations can be used + * with different optimized implementations of expensive field + * operations: + */ + int (*field_mul) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, BN_CTX *); + int (*field_div) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); + /* e.g. to Montgomery */ + int (*field_encode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); + /* e.g. from Montgomery */ + int (*field_decode) (const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); + int (*field_set_to_one) (const EC_GROUP *, BIGNUM *r, BN_CTX *); +} /* EC_METHOD */ ; + +typedef struct ec_extra_data_st { + struct ec_extra_data_st *next; + void *data; + void *(*dup_func) (void *); + void (*free_func) (void *); + void (*clear_free_func) (void *); +} EC_EXTRA_DATA; /* used in EC_GROUP */ + +struct ec_group_st { + const EC_METHOD *meth; + EC_POINT *generator; /* optional */ + BIGNUM order, cofactor; + int curve_name; /* optional NID for named curve */ + int asn1_flag; /* flag to control the asn1 encoding */ + point_conversion_form_t asn1_form; + unsigned char *seed; /* optional seed for parameters (appears in + * ASN1) */ + size_t seed_len; + EC_EXTRA_DATA *extra_data; /* linked list */ + /* + * The following members are handled by the method functions, even if + * they appear generic + */ + /* + * Field specification. For curves over GF(p), this is the modulus; for + * curves over GF(2^m), this is the irreducible polynomial defining the + * field. + */ + BIGNUM field; + /* + * Field specification for curves over GF(2^m). The irreducible f(t) is + * then of the form: t^poly[0] + t^poly[1] + ... + t^poly[k] where m = + * poly[0] > poly[1] > ... > poly[k] = 0. The array is terminated with + * poly[k+1]=-1. All elliptic curve irreducibles have at most 5 non-zero + * terms. + */ + int poly[6]; + /* + * Curve coefficients. (Here the assumption is that BIGNUMs can be used + * or abused for all kinds of fields, not just GF(p).) For characteristic + * > 3, the curve is defined by a Weierstrass equation of the form y^2 = + * x^3 + a*x + b. For characteristic 2, the curve is defined by an + * equation of the form y^2 + x*y = x^3 + a*x^2 + b. + */ + BIGNUM a, b; + /* enable optimized point arithmetics for special case */ + int a_is_minus3; + /* method-specific (e.g., Montgomery structure) */ + void *field_data1; + /* method-specific */ + void *field_data2; + /* method-specific */ + int (*field_mod_func) (BIGNUM *, const BIGNUM *, const BIGNUM *, + BN_CTX *); +} /* EC_GROUP */ ; + +struct ec_key_st { + int version; + EC_GROUP *group; + EC_POINT *pub_key; + BIGNUM *priv_key; + unsigned int enc_flag; + point_conversion_form_t conv_form; + int references; + int flags; + EC_EXTRA_DATA *method_data; +} /* EC_KEY */ ; + +/* + * Basically a 'mixin' for extra data, but available for EC_GROUPs/EC_KEYs + * only (with visibility limited to 'package' level for now). We use the + * function pointers as index for retrieval; this obviates global + * ex_data-style index tables. + */ +int EC_EX_DATA_set_data(EC_EXTRA_DATA **, void *data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)); +void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *, void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)); +void EC_EX_DATA_free_data(EC_EXTRA_DATA **, void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)); +void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **, void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)); +void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **); +void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **); + +struct ec_point_st { + const EC_METHOD *meth; + /* + * All members except 'meth' are handled by the method functions, even if + * they appear generic + */ + BIGNUM X; + BIGNUM Y; + BIGNUM Z; /* Jacobian projective coordinates: (X, Y, Z) + * represents (X/Z^2, Y/Z^3) if Z != 0 */ + int Z_is_one; /* enable optimized point arithmetics for + * special case */ +} /* EC_POINT */ ; + +/* + * method functions in ec_mult.c (ec_lib.c uses these as defaults if + * group->method->mul is 0) + */ +int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + size_t num, const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); +int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *); +int ec_wNAF_have_precompute_mult(const EC_GROUP *group); + +/* method functions in ecp_smpl.c */ +int ec_GFp_simple_group_init(EC_GROUP *); +void ec_GFp_simple_group_finish(EC_GROUP *); +void ec_GFp_simple_group_clear_finish(EC_GROUP *); +int ec_GFp_simple_group_copy(EC_GROUP *, const EC_GROUP *); +int ec_GFp_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, BN_CTX *); +int ec_GFp_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *); +int ec_GFp_simple_group_get_degree(const EC_GROUP *); +int ec_GFp_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); +int ec_GFp_simple_point_init(EC_POINT *); +void ec_GFp_simple_point_finish(EC_POINT *); +void ec_GFp_simple_point_clear_finish(EC_POINT *); +int ec_GFp_simple_point_copy(EC_POINT *, const EC_POINT *); +int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); +int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *, + EC_POINT *, const BIGNUM *x, + const BIGNUM *y, + const BIGNUM *z, BN_CTX *); +int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *, + const EC_POINT *, BIGNUM *x, + BIGNUM *y, BIGNUM *z, + BN_CTX *); +int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, + const BIGNUM *y, BN_CTX *); +int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *, + const EC_POINT *, BIGNUM *x, + BIGNUM *y, BN_CTX *); +int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, int y_bit, + BN_CTX *); +size_t ec_GFp_simple_point2oct(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *); +int ec_GFp_simple_oct2point(const EC_GROUP *, EC_POINT *, + const unsigned char *buf, size_t len, BN_CTX *); +int ec_GFp_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *); +int ec_GFp_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + BN_CTX *); +int ec_GFp_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); +int ec_GFp_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); +int ec_GFp_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); +int ec_GFp_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, + BN_CTX *); +int ec_GFp_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); +int ec_GFp_simple_points_make_affine(const EC_GROUP *, size_t num, + EC_POINT *[], BN_CTX *); +int ec_GFp_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ec_GFp_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); + +/* method functions in ecp_mont.c */ +int ec_GFp_mont_group_init(EC_GROUP *); +int ec_GFp_mont_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +void ec_GFp_mont_group_finish(EC_GROUP *); +void ec_GFp_mont_group_clear_finish(EC_GROUP *); +int ec_GFp_mont_group_copy(EC_GROUP *, const EC_GROUP *); +int ec_GFp_mont_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ec_GFp_mont_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ec_GFp_mont_field_encode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ec_GFp_mont_field_decode(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ec_GFp_mont_field_set_to_one(const EC_GROUP *, BIGNUM *r, BN_CTX *); + +/* method functions in ecp_nist.c */ +int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src); +int ec_GFp_nist_group_set_curve(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ec_GFp_nist_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ec_GFp_nist_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); + +/* method functions in ec2_smpl.c */ +int ec_GF2m_simple_group_init(EC_GROUP *); +void ec_GF2m_simple_group_finish(EC_GROUP *); +void ec_GF2m_simple_group_clear_finish(EC_GROUP *); +int ec_GF2m_simple_group_copy(EC_GROUP *, const EC_GROUP *); +int ec_GF2m_simple_group_set_curve(EC_GROUP *, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *); +int ec_GF2m_simple_group_get_curve(const EC_GROUP *, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *); +int ec_GF2m_simple_group_get_degree(const EC_GROUP *); +int ec_GF2m_simple_group_check_discriminant(const EC_GROUP *, BN_CTX *); +int ec_GF2m_simple_point_init(EC_POINT *); +void ec_GF2m_simple_point_finish(EC_POINT *); +void ec_GF2m_simple_point_clear_finish(EC_POINT *); +int ec_GF2m_simple_point_copy(EC_POINT *, const EC_POINT *); +int ec_GF2m_simple_point_set_to_infinity(const EC_GROUP *, EC_POINT *); +int ec_GF2m_simple_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, + const BIGNUM *y, BN_CTX *); +int ec_GF2m_simple_point_get_affine_coordinates(const EC_GROUP *, + const EC_POINT *, BIGNUM *x, + BIGNUM *y, BN_CTX *); +int ec_GF2m_simple_set_compressed_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, int y_bit, + BN_CTX *); +size_t ec_GF2m_simple_point2oct(const EC_GROUP *, const EC_POINT *, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *); +int ec_GF2m_simple_oct2point(const EC_GROUP *, EC_POINT *, + const unsigned char *buf, size_t len, BN_CTX *); +int ec_GF2m_simple_add(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *); +int ec_GF2m_simple_dbl(const EC_GROUP *, EC_POINT *r, const EC_POINT *a, + BN_CTX *); +int ec_GF2m_simple_invert(const EC_GROUP *, EC_POINT *, BN_CTX *); +int ec_GF2m_simple_is_at_infinity(const EC_GROUP *, const EC_POINT *); +int ec_GF2m_simple_is_on_curve(const EC_GROUP *, const EC_POINT *, BN_CTX *); +int ec_GF2m_simple_cmp(const EC_GROUP *, const EC_POINT *a, const EC_POINT *b, + BN_CTX *); +int ec_GF2m_simple_make_affine(const EC_GROUP *, EC_POINT *, BN_CTX *); +int ec_GF2m_simple_points_make_affine(const EC_GROUP *, size_t num, + EC_POINT *[], BN_CTX *); +int ec_GF2m_simple_field_mul(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); +int ec_GF2m_simple_field_sqr(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); +int ec_GF2m_simple_field_div(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); + +/* method functions in ec2_mult.c */ +int ec_GF2m_simple_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); +int ec_GF2m_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +int ec_GF2m_have_precompute_mult(const EC_GROUP *group); + +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +/* method functions in ecp_nistp224.c */ +int ec_GFp_nistp224_group_init(EC_GROUP *group); +int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *); +int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx); +int ec_GFp_nistp224_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); +int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx); +int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group); + +/* method functions in ecp_nistp256.c */ +int ec_GFp_nistp256_group_init(EC_GROUP *group); +int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *); +int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx); +int ec_GFp_nistp256_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); +int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx); +int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group); + +/* method functions in ecp_nistp521.c */ +int ec_GFp_nistp521_group_init(EC_GROUP *group); +int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *); +int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx); +int ec_GFp_nistp521_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *); +int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx); +int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx); +int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group); + +/* utility functions in ecp_nistputil.c */ +void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, + size_t felem_size, + void *tmp_felems, + void (*felem_one) (void *out), + int (*felem_is_zero) (const void + *in), + void (*felem_assign) (void *out, + const void + *in), + void (*felem_square) (void *out, + const void + *in), + void (*felem_mul) (void *out, + const void + *in1, + const void + *in2), + void (*felem_inv) (void *out, + const void + *in), + void (*felem_contract) (void + *out, + const + void + *in)); +void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, + unsigned char *digit, unsigned char in); +#endif diff --git a/libs/openssl/crypto/ec/ec_lib.c b/libs/openssl/crypto/ec/ec_lib.c new file mode 100644 index 00000000..e2275207 --- /dev/null +++ b/libs/openssl/crypto/ec/ec_lib.c @@ -0,0 +1,1059 @@ +/* crypto/ec/ec_lib.c */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Binary polynomial ECC support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include + +#include +#include + +#include "ec_lcl.h" + +const char EC_version[] = "EC" OPENSSL_VERSION_PTEXT; + +/* functions for EC_GROUP objects */ + +EC_GROUP *EC_GROUP_new(const EC_METHOD *meth) +{ + EC_GROUP *ret; + + if (meth == NULL) { + ECerr(EC_F_EC_GROUP_NEW, EC_R_SLOT_FULL); + return NULL; + } + if (meth->group_init == 0) { + ECerr(EC_F_EC_GROUP_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return NULL; + } + + ret = OPENSSL_malloc(sizeof *ret); + if (ret == NULL) { + ECerr(EC_F_EC_GROUP_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->meth = meth; + + ret->extra_data = NULL; + + ret->generator = NULL; + BN_init(&ret->order); + BN_init(&ret->cofactor); + + ret->curve_name = 0; + ret->asn1_flag = 0; + ret->asn1_form = POINT_CONVERSION_UNCOMPRESSED; + + ret->seed = NULL; + ret->seed_len = 0; + + if (!meth->group_init(ret)) { + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +void EC_GROUP_free(EC_GROUP *group) +{ + if (!group) + return; + + if (group->meth->group_finish != 0) + group->meth->group_finish(group); + + EC_EX_DATA_free_all_data(&group->extra_data); + + if (group->generator != NULL) + EC_POINT_free(group->generator); + BN_free(&group->order); + BN_free(&group->cofactor); + + if (group->seed) + OPENSSL_free(group->seed); + + OPENSSL_free(group); +} + +void EC_GROUP_clear_free(EC_GROUP *group) +{ + if (!group) + return; + + if (group->meth->group_clear_finish != 0) + group->meth->group_clear_finish(group); + else if (group->meth->group_finish != 0) + group->meth->group_finish(group); + + EC_EX_DATA_clear_free_all_data(&group->extra_data); + + if (group->generator != NULL) + EC_POINT_clear_free(group->generator); + BN_clear_free(&group->order); + BN_clear_free(&group->cofactor); + + if (group->seed) { + OPENSSL_cleanse(group->seed, group->seed_len); + OPENSSL_free(group->seed); + } + + OPENSSL_cleanse(group, sizeof *group); + OPENSSL_free(group); +} + +int EC_GROUP_copy(EC_GROUP *dest, const EC_GROUP *src) +{ + EC_EXTRA_DATA *d; + + if (dest->meth->group_copy == 0) { + ECerr(EC_F_EC_GROUP_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (dest->meth != src->meth) { + ECerr(EC_F_EC_GROUP_COPY, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (dest == src) + return 1; + + EC_EX_DATA_free_all_data(&dest->extra_data); + + for (d = src->extra_data; d != NULL; d = d->next) { + void *t = d->dup_func(d->data); + + if (t == NULL) + return 0; + if (!EC_EX_DATA_set_data + (&dest->extra_data, t, d->dup_func, d->free_func, + d->clear_free_func)) + return 0; + } + + if (src->generator != NULL) { + if (dest->generator == NULL) { + dest->generator = EC_POINT_new(dest); + if (dest->generator == NULL) + return 0; + } + if (!EC_POINT_copy(dest->generator, src->generator)) + return 0; + } else { + /* src->generator == NULL */ + if (dest->generator != NULL) { + EC_POINT_clear_free(dest->generator); + dest->generator = NULL; + } + } + + if (!BN_copy(&dest->order, &src->order)) + return 0; + if (!BN_copy(&dest->cofactor, &src->cofactor)) + return 0; + + dest->curve_name = src->curve_name; + dest->asn1_flag = src->asn1_flag; + dest->asn1_form = src->asn1_form; + + if (src->seed) { + if (dest->seed) + OPENSSL_free(dest->seed); + dest->seed = OPENSSL_malloc(src->seed_len); + if (dest->seed == NULL) + return 0; + if (!memcpy(dest->seed, src->seed, src->seed_len)) + return 0; + dest->seed_len = src->seed_len; + } else { + if (dest->seed) + OPENSSL_free(dest->seed); + dest->seed = NULL; + dest->seed_len = 0; + } + + return dest->meth->group_copy(dest, src); +} + +EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) +{ + EC_GROUP *t = NULL; + int ok = 0; + + if (a == NULL) + return NULL; + + if ((t = EC_GROUP_new(a->meth)) == NULL) + return (NULL); + if (!EC_GROUP_copy(t, a)) + goto err; + + ok = 1; + + err: + if (!ok) { + if (t) + EC_GROUP_free(t); + return NULL; + } else + return t; +} + +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) +{ + return group->meth; +} + +int EC_METHOD_get_field_type(const EC_METHOD *meth) +{ + return meth->field_type; +} + +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor) +{ + if (generator == NULL) { + ECerr(EC_F_EC_GROUP_SET_GENERATOR, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (group->generator == NULL) { + group->generator = EC_POINT_new(group); + if (group->generator == NULL) + return 0; + } + if (!EC_POINT_copy(group->generator, generator)) + return 0; + + if (order != NULL) { + if (!BN_copy(&group->order, order)) + return 0; + } else + BN_zero(&group->order); + + if (cofactor != NULL) { + if (!BN_copy(&group->cofactor, cofactor)) + return 0; + } else + BN_zero(&group->cofactor); + + return 1; +} + +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) +{ + return group->generator; +} + +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) +{ + if (!BN_copy(order, &group->order)) + return 0; + + return !BN_is_zero(order); +} + +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, + BN_CTX *ctx) +{ + if (!BN_copy(cofactor, &group->cofactor)) + return 0; + + return !BN_is_zero(&group->cofactor); +} + +void EC_GROUP_set_curve_name(EC_GROUP *group, int nid) +{ + group->curve_name = nid; +} + +int EC_GROUP_get_curve_name(const EC_GROUP *group) +{ + return group->curve_name; +} + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) +{ + group->asn1_flag = flag; +} + +int EC_GROUP_get_asn1_flag(const EC_GROUP *group) +{ + return group->asn1_flag; +} + +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, + point_conversion_form_t form) +{ + group->asn1_form = form; +} + +point_conversion_form_t EC_GROUP_get_point_conversion_form(const EC_GROUP + *group) +{ + return group->asn1_form; +} + +size_t EC_GROUP_set_seed(EC_GROUP *group, const unsigned char *p, size_t len) +{ + if (group->seed) { + OPENSSL_free(group->seed); + group->seed = NULL; + group->seed_len = 0; + } + + if (!len || !p) + return 1; + + if ((group->seed = OPENSSL_malloc(len)) == NULL) + return 0; + memcpy(group->seed, p, len); + group->seed_len = len; + + return len; +} + +unsigned char *EC_GROUP_get0_seed(const EC_GROUP *group) +{ + return group->seed; +} + +size_t EC_GROUP_get_seed_len(const EC_GROUP *group) +{ + return group->seed_len; +} + +int EC_GROUP_set_curve_GFp(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + if (group->meth->group_set_curve == 0) { + ECerr(EC_F_EC_GROUP_SET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->group_set_curve(group, p, a, b, ctx); +} + +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx) +{ + if (group->meth->group_get_curve == 0) { + ECerr(EC_F_EC_GROUP_GET_CURVE_GFP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->group_get_curve(group, p, a, b, ctx); +} + +#ifndef OPENSSL_NO_EC2M +int EC_GROUP_set_curve_GF2m(EC_GROUP *group, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + if (group->meth->group_set_curve == 0) { + ECerr(EC_F_EC_GROUP_SET_CURVE_GF2M, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->group_set_curve(group, p, a, b, ctx); +} + +int EC_GROUP_get_curve_GF2m(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx) +{ + if (group->meth->group_get_curve == 0) { + ECerr(EC_F_EC_GROUP_GET_CURVE_GF2M, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->group_get_curve(group, p, a, b, ctx); +} +#endif + +int EC_GROUP_get_degree(const EC_GROUP *group) +{ + if (group->meth->group_get_degree == 0) { + ECerr(EC_F_EC_GROUP_GET_DEGREE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->group_get_degree(group); +} + +int EC_GROUP_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) +{ + if (group->meth->group_check_discriminant == 0) { + ECerr(EC_F_EC_GROUP_CHECK_DISCRIMINANT, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + return group->meth->group_check_discriminant(group, ctx); +} + +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ctx) +{ + int r = 0; + BIGNUM *a1, *a2, *a3, *b1, *b2, *b3; + BN_CTX *ctx_new = NULL; + + /* compare the field types */ + if (EC_METHOD_get_field_type(EC_GROUP_method_of(a)) != + EC_METHOD_get_field_type(EC_GROUP_method_of(b))) + return 1; + /* compare the curve name (if present in both) */ + if (EC_GROUP_get_curve_name(a) && EC_GROUP_get_curve_name(b) && + EC_GROUP_get_curve_name(a) != EC_GROUP_get_curve_name(b)) + return 1; + + if (!ctx) + ctx_new = ctx = BN_CTX_new(); + if (!ctx) + return -1; + + BN_CTX_start(ctx); + a1 = BN_CTX_get(ctx); + a2 = BN_CTX_get(ctx); + a3 = BN_CTX_get(ctx); + b1 = BN_CTX_get(ctx); + b2 = BN_CTX_get(ctx); + b3 = BN_CTX_get(ctx); + if (!b3) { + BN_CTX_end(ctx); + if (ctx_new) + BN_CTX_free(ctx); + return -1; + } + + /* + * XXX This approach assumes that the external representation of curves + * over the same field type is the same. + */ + if (!a->meth->group_get_curve(a, a1, a2, a3, ctx) || + !b->meth->group_get_curve(b, b1, b2, b3, ctx)) + r = 1; + + if (r || BN_cmp(a1, b1) || BN_cmp(a2, b2) || BN_cmp(a3, b3)) + r = 1; + + /* XXX EC_POINT_cmp() assumes that the methods are equal */ + if (r || EC_POINT_cmp(a, EC_GROUP_get0_generator(a), + EC_GROUP_get0_generator(b), ctx)) + r = 1; + + if (!r) { + /* compare the order and cofactor */ + if (!EC_GROUP_get_order(a, a1, ctx) || + !EC_GROUP_get_order(b, b1, ctx) || + !EC_GROUP_get_cofactor(a, a2, ctx) || + !EC_GROUP_get_cofactor(b, b2, ctx)) { + BN_CTX_end(ctx); + if (ctx_new) + BN_CTX_free(ctx); + return -1; + } + if (BN_cmp(a1, b1) || BN_cmp(a2, b2)) + r = 1; + } + + BN_CTX_end(ctx); + if (ctx_new) + BN_CTX_free(ctx); + + return r; +} + +/* this has 'package' visibility */ +int EC_EX_DATA_set_data(EC_EXTRA_DATA **ex_data, void *data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)) +{ + EC_EXTRA_DATA *d; + + if (ex_data == NULL) + return 0; + + for (d = *ex_data; d != NULL; d = d->next) { + if (d->dup_func == dup_func && d->free_func == free_func + && d->clear_free_func == clear_free_func) { + ECerr(EC_F_EC_EX_DATA_SET_DATA, EC_R_SLOT_FULL); + return 0; + } + } + + if (data == NULL) + /* no explicit entry needed */ + return 1; + + d = OPENSSL_malloc(sizeof *d); + if (d == NULL) + return 0; + + d->data = data; + d->dup_func = dup_func; + d->free_func = free_func; + d->clear_free_func = clear_free_func; + + d->next = *ex_data; + *ex_data = d; + + return 1; +} + +/* this has 'package' visibility */ +void *EC_EX_DATA_get_data(const EC_EXTRA_DATA *ex_data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)) +{ + const EC_EXTRA_DATA *d; + + for (d = ex_data; d != NULL; d = d->next) { + if (d->dup_func == dup_func && d->free_func == free_func + && d->clear_free_func == clear_free_func) + return d->data; + } + + return NULL; +} + +/* this has 'package' visibility */ +void EC_EX_DATA_free_data(EC_EXTRA_DATA **ex_data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)) +{ + EC_EXTRA_DATA **p; + + if (ex_data == NULL) + return; + + for (p = ex_data; *p != NULL; p = &((*p)->next)) { + if ((*p)->dup_func == dup_func && (*p)->free_func == free_func + && (*p)->clear_free_func == clear_free_func) { + EC_EXTRA_DATA *next = (*p)->next; + + (*p)->free_func((*p)->data); + OPENSSL_free(*p); + + *p = next; + return; + } + } +} + +/* this has 'package' visibility */ +void EC_EX_DATA_clear_free_data(EC_EXTRA_DATA **ex_data, + void *(*dup_func) (void *), + void (*free_func) (void *), + void (*clear_free_func) (void *)) +{ + EC_EXTRA_DATA **p; + + if (ex_data == NULL) + return; + + for (p = ex_data; *p != NULL; p = &((*p)->next)) { + if ((*p)->dup_func == dup_func && (*p)->free_func == free_func + && (*p)->clear_free_func == clear_free_func) { + EC_EXTRA_DATA *next = (*p)->next; + + (*p)->clear_free_func((*p)->data); + OPENSSL_free(*p); + + *p = next; + return; + } + } +} + +/* this has 'package' visibility */ +void EC_EX_DATA_free_all_data(EC_EXTRA_DATA **ex_data) +{ + EC_EXTRA_DATA *d; + + if (ex_data == NULL) + return; + + d = *ex_data; + while (d) { + EC_EXTRA_DATA *next = d->next; + + d->free_func(d->data); + OPENSSL_free(d); + + d = next; + } + *ex_data = NULL; +} + +/* this has 'package' visibility */ +void EC_EX_DATA_clear_free_all_data(EC_EXTRA_DATA **ex_data) +{ + EC_EXTRA_DATA *d; + + if (ex_data == NULL) + return; + + d = *ex_data; + while (d) { + EC_EXTRA_DATA *next = d->next; + + d->clear_free_func(d->data); + OPENSSL_free(d); + + d = next; + } + *ex_data = NULL; +} + +/* functions for EC_POINT objects */ + +EC_POINT *EC_POINT_new(const EC_GROUP *group) +{ + EC_POINT *ret; + + if (group == NULL) { + ECerr(EC_F_EC_POINT_NEW, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (group->meth->point_init == 0) { + ECerr(EC_F_EC_POINT_NEW, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return NULL; + } + + ret = OPENSSL_malloc(sizeof *ret); + if (ret == NULL) { + ECerr(EC_F_EC_POINT_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->meth = group->meth; + + if (!ret->meth->point_init(ret)) { + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +void EC_POINT_free(EC_POINT *point) +{ + if (!point) + return; + + if (point->meth->point_finish != 0) + point->meth->point_finish(point); + OPENSSL_free(point); +} + +void EC_POINT_clear_free(EC_POINT *point) +{ + if (!point) + return; + + if (point->meth->point_clear_finish != 0) + point->meth->point_clear_finish(point); + else if (point->meth->point_finish != 0) + point->meth->point_finish(point); + OPENSSL_cleanse(point, sizeof *point); + OPENSSL_free(point); +} + +int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) +{ + if (dest->meth->point_copy == 0) { + ECerr(EC_F_EC_POINT_COPY, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (dest->meth != src->meth) { + ECerr(EC_F_EC_POINT_COPY, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (dest == src) + return 1; + return dest->meth->point_copy(dest, src); +} + +EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) +{ + EC_POINT *t; + int r; + + if (a == NULL) + return NULL; + + t = EC_POINT_new(group); + if (t == NULL) + return (NULL); + r = EC_POINT_copy(t, a); + if (!r) { + EC_POINT_free(t); + return NULL; + } else + return t; +} + +const EC_METHOD *EC_POINT_method_of(const EC_POINT *point) +{ + return point->meth; +} + +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) +{ + if (group->meth->point_set_to_infinity == 0) { + ECerr(EC_F_EC_POINT_SET_TO_INFINITY, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_SET_TO_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_set_to_infinity(group, point); +} + +int EC_POINT_set_Jprojective_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x, + const BIGNUM *y, const BIGNUM *z, + BN_CTX *ctx) +{ + if (group->meth->point_set_Jprojective_coordinates_GFp == 0) { + ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_SET_JPROJECTIVE_COORDINATES_GFP, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_set_Jprojective_coordinates_GFp(group, point, x, + y, z, ctx); +} + +int EC_POINT_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *point, BIGNUM *x, + BIGNUM *y, BIGNUM *z, + BN_CTX *ctx) +{ + if (group->meth->point_get_Jprojective_coordinates_GFp == 0) { + ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_GET_JPROJECTIVE_COORDINATES_GFP, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_get_Jprojective_coordinates_GFp(group, point, x, + y, z, ctx); +} + +int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) +{ + if (group->meth->point_set_affine_coordinates == 0) { + ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GFP, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); +} + +#ifndef OPENSSL_NO_EC2M +int EC_POINT_set_affine_coordinates_GF2m(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) +{ + if (group->meth->point_set_affine_coordinates == 0) { + ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_SET_AFFINE_COORDINATES_GF2M, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_set_affine_coordinates(group, point, x, y, ctx); +} +#endif + +int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *point, BIGNUM *x, + BIGNUM *y, BN_CTX *ctx) +{ + if (group->meth->point_get_affine_coordinates == 0) { + ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GFP, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); +} + +#ifndef OPENSSL_NO_EC2M +int EC_POINT_get_affine_coordinates_GF2m(const EC_GROUP *group, + const EC_POINT *point, BIGNUM *x, + BIGNUM *y, BN_CTX *ctx) +{ + if (group->meth->point_get_affine_coordinates == 0) { + ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_GET_AFFINE_COORDINATES_GF2M, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_get_affine_coordinates(group, point, x, y, ctx); +} +#endif + +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) +{ + if (group->meth->add == 0) { + ECerr(EC_F_EC_POINT_ADD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if ((group->meth != r->meth) || (r->meth != a->meth) + || (a->meth != b->meth)) { + ECerr(EC_F_EC_POINT_ADD, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->add(group, r, a, b, ctx); +} + +int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx) +{ + if (group->meth->dbl == 0) { + ECerr(EC_F_EC_POINT_DBL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if ((group->meth != r->meth) || (r->meth != a->meth)) { + ECerr(EC_F_EC_POINT_DBL, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->dbl(group, r, a, ctx); +} + +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) +{ + if (group->meth->invert == 0) { + ECerr(EC_F_EC_POINT_INVERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != a->meth) { + ECerr(EC_F_EC_POINT_INVERT, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->invert(group, a, ctx); +} + +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) +{ + if (group->meth->is_at_infinity == 0) { + ECerr(EC_F_EC_POINT_IS_AT_INFINITY, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_IS_AT_INFINITY, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->is_at_infinity(group, point); +} + +/* + * Check whether an EC_POINT is on the curve or not. Note that the return + * value for this function should NOT be treated as a boolean. Return values: + * 1: The point is on the curve + * 0: The point is not on the curve + * -1: An error occurred + */ +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx) +{ + if (group->meth->is_on_curve == 0) { + ECerr(EC_F_EC_POINT_IS_ON_CURVE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_IS_ON_CURVE, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->is_on_curve(group, point, ctx); +} + +int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, const EC_POINT *b, + BN_CTX *ctx) +{ + if (group->meth->point_cmp == 0) { + ECerr(EC_F_EC_POINT_CMP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + if ((group->meth != a->meth) || (a->meth != b->meth)) { + ECerr(EC_F_EC_POINT_CMP, EC_R_INCOMPATIBLE_OBJECTS); + return -1; + } + return group->meth->point_cmp(group, a, b, ctx); +} + +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) +{ + if (group->meth->make_affine == 0) { + ECerr(EC_F_EC_POINT_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->make_affine(group, point, ctx); +} + +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx) +{ + size_t i; + + if (group->meth->points_make_affine == 0) { + ECerr(EC_F_EC_POINTS_MAKE_AFFINE, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + for (i = 0; i < num; i++) { + if (group->meth != points[i]->meth) { + ECerr(EC_F_EC_POINTS_MAKE_AFFINE, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + } + return group->meth->points_make_affine(group, num, points, ctx); +} + +/* + * Functions for point multiplication. If group->meth->mul is 0, we use the + * wNAF-based implementations in ec_mult.c; otherwise we dispatch through + * methods. + */ + +int EC_POINTs_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + size_t num, const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx) +{ + if (group->meth->mul == 0) + /* use default */ + return ec_wNAF_mul(group, r, scalar, num, points, scalars, ctx); + + return group->meth->mul(group, r, scalar, num, points, scalars, ctx); +} + +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, + const EC_POINT *point, const BIGNUM *p_scalar, BN_CTX *ctx) +{ + /* just a convenient interface to EC_POINTs_mul() */ + + const EC_POINT *points[1]; + const BIGNUM *scalars[1]; + + points[0] = point; + scalars[0] = p_scalar; + + return EC_POINTs_mul(group, r, g_scalar, + (point != NULL + && p_scalar != NULL), points, scalars, ctx); +} + +int EC_GROUP_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +{ + if (group->meth->mul == 0) + /* use default */ + return ec_wNAF_precompute_mult(group, ctx); + + if (group->meth->precompute_mult != 0) + return group->meth->precompute_mult(group, ctx); + else + return 1; /* nothing to do, so report success */ +} + +int EC_GROUP_have_precompute_mult(const EC_GROUP *group) +{ + if (group->meth->mul == 0) + /* use default */ + return ec_wNAF_have_precompute_mult(group); + + if (group->meth->have_precompute_mult != 0) + return group->meth->have_precompute_mult(group); + else + return 0; /* cannot tell whether precomputation has + * been performed */ +} diff --git a/libs/openssl/crypto/ec/ec_mult.c b/libs/openssl/crypto/ec/ec_mult.c new file mode 100644 index 00000000..23b8c308 --- /dev/null +++ b/libs/openssl/crypto/ec/ec_mult.c @@ -0,0 +1,913 @@ +/* crypto/ec/ec_mult.c */ +/* + * Originally written by Bodo Moeller and Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions of this software developed by SUN MICROSYSTEMS, INC., + * and contributed to the OpenSSL project. + */ + +#include + +#include + +#include "ec_lcl.h" + +/* + * This file implements the wNAF-based interleaving multi-exponentation method + * (); + * for multiplication with precomputation, we use wNAF splitting + * (). + */ + +/* structure for precomputed multiples of the generator */ +typedef struct ec_pre_comp_st { + const EC_GROUP *group; /* parent EC_GROUP object */ + size_t blocksize; /* block size for wNAF splitting */ + size_t numblocks; /* max. number of blocks for which we have + * precomputation */ + size_t w; /* window size */ + EC_POINT **points; /* array with pre-calculated multiples of + * generator: 'num' pointers to EC_POINT + * objects followed by a NULL */ + size_t num; /* numblocks * 2^(w-1) */ + int references; +} EC_PRE_COMP; + +/* functions to manage EC_PRE_COMP within the EC_GROUP extra_data framework */ +static void *ec_pre_comp_dup(void *); +static void ec_pre_comp_free(void *); +static void ec_pre_comp_clear_free(void *); + +static EC_PRE_COMP *ec_pre_comp_new(const EC_GROUP *group) +{ + EC_PRE_COMP *ret = NULL; + + if (!group) + return NULL; + + ret = (EC_PRE_COMP *)OPENSSL_malloc(sizeof(EC_PRE_COMP)); + if (!ret) { + ECerr(EC_F_EC_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + return ret; + } + ret->group = group; + ret->blocksize = 8; /* default */ + ret->numblocks = 0; + ret->w = 4; /* default */ + ret->points = NULL; + ret->num = 0; + ret->references = 1; + return ret; +} + +static void *ec_pre_comp_dup(void *src_) +{ + EC_PRE_COMP *src = src_; + + /* no need to actually copy, these objects never change! */ + + CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); + + return src_; +} + +static void ec_pre_comp_free(void *pre_) +{ + int i; + EC_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + if (pre->points) { + EC_POINT **p; + + for (p = pre->points; *p != NULL; p++) + EC_POINT_free(*p); + OPENSSL_free(pre->points); + } + OPENSSL_free(pre); +} + +static void ec_pre_comp_clear_free(void *pre_) +{ + int i; + EC_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + if (pre->points) { + EC_POINT **p; + + for (p = pre->points; *p != NULL; p++) { + EC_POINT_clear_free(*p); + OPENSSL_cleanse(p, sizeof *p); + } + OPENSSL_free(pre->points); + } + OPENSSL_cleanse(pre, sizeof *pre); + OPENSSL_free(pre); +} + +/*- + * Determine the modified width-(w+1) Non-Adjacent Form (wNAF) of 'scalar'. + * This is an array r[] of values that are either zero or odd with an + * absolute value less than 2^w satisfying + * scalar = \sum_j r[j]*2^j + * where at most one of any w+1 consecutive digits is non-zero + * with the exception that the most significant digit may be only + * w-1 zeros away from that next non-zero digit. + */ +static signed char *compute_wNAF(const BIGNUM *scalar, int w, size_t *ret_len) +{ + int window_val; + int ok = 0; + signed char *r = NULL; + int sign = 1; + int bit, next_bit, mask; + size_t len = 0, j; + + if (BN_is_zero(scalar)) { + r = OPENSSL_malloc(1); + if (!r) { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); + goto err; + } + r[0] = 0; + *ret_len = 1; + return r; + } + + if (w <= 0 || w > 7) { /* 'signed char' can represent integers with + * absolute values less than 2^7 */ + ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + goto err; + } + bit = 1 << w; /* at most 128 */ + next_bit = bit << 1; /* at most 256 */ + mask = next_bit - 1; /* at most 255 */ + + if (BN_is_negative(scalar)) { + sign = -1; + } + + if (scalar->d == NULL || scalar->top == 0) { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + goto err; + } + + len = BN_num_bits(scalar); + r = OPENSSL_malloc(len + 1); /* modified wNAF may be one digit longer + * than binary representation (*ret_len will + * be set to the actual length, i.e. at most + * BN_num_bits(scalar) + 1) */ + if (r == NULL) { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_MALLOC_FAILURE); + goto err; + } + window_val = scalar->d[0] & mask; + j = 0; + while ((window_val != 0) || (j + w + 1 < len)) { /* if j+w+1 >= len, + * window_val will not + * increase */ + int digit = 0; + + /* 0 <= window_val <= 2^(w+1) */ + + if (window_val & 1) { + /* 0 < window_val < 2^(w+1) */ + + if (window_val & bit) { + digit = window_val - next_bit; /* -2^w < digit < 0 */ + +#if 1 /* modified wNAF */ + if (j + w + 1 >= len) { + /* + * special case for generating modified wNAFs: no new + * bits will be added into window_val, so using a + * positive digit here will decrease the total length of + * the representation + */ + + digit = window_val & (mask >> 1); /* 0 < digit < 2^w */ + } +#endif + } else { + digit = window_val; /* 0 < digit < 2^w */ + } + + if (digit <= -bit || digit >= bit || !(digit & 1)) { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + goto err; + } + + window_val -= digit; + + /* + * now window_val is 0 or 2^(w+1) in standard wNAF generation; + * for modified window NAFs, it may also be 2^w + */ + if (window_val != 0 && window_val != next_bit + && window_val != bit) { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + r[j++] = sign * digit; + + window_val >>= 1; + window_val += bit * BN_is_bit_set(scalar, j + w); + + if (window_val > next_bit) { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (j > len + 1) { + ECerr(EC_F_COMPUTE_WNAF, ERR_R_INTERNAL_ERROR); + goto err; + } + len = j; + ok = 1; + + err: + if (!ok) { + OPENSSL_free(r); + r = NULL; + } + if (ok) + *ret_len = len; + return r; +} + +/* + * TODO: table should be optimised for the wNAF-based implementation, + * sometimes smaller windows will give better performance (thus the + * boundaries should be increased) + */ +#define EC_window_bits_for_scalar_size(b) \ + ((size_t) \ + ((b) >= 2000 ? 6 : \ + (b) >= 800 ? 5 : \ + (b) >= 300 ? 4 : \ + (b) >= 70 ? 3 : \ + (b) >= 20 ? 2 : \ + 1)) + +/*- + * Compute + * \sum scalars[i]*points[i], + * also including + * scalar*generator + * in the addition if scalar != NULL + */ +int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *scalar, + size_t num, const EC_POINT *points[], const BIGNUM *scalars[], + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + const EC_POINT *generator = NULL; + EC_POINT *tmp = NULL; + size_t totalnum; + size_t blocksize = 0, numblocks = 0; /* for wNAF splitting */ + size_t pre_points_per_block = 0; + size_t i, j; + int k; + int r_is_inverted = 0; + int r_is_at_infinity = 1; + size_t *wsize = NULL; /* individual window sizes */ + signed char **wNAF = NULL; /* individual wNAFs */ + size_t *wNAF_len = NULL; + size_t max_len = 0; + size_t num_val; + EC_POINT **val = NULL; /* precomputation */ + EC_POINT **v; + EC_POINT ***val_sub = NULL; /* pointers to sub-arrays of 'val' or + * 'pre_comp->points' */ + const EC_PRE_COMP *pre_comp = NULL; + int num_scalar = 0; /* flag: will be set to 1 if 'scalar' must be + * treated like other scalars, i.e. + * precomputation is not available */ + int ret = 0; + + if (group->meth != r->meth) { + ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + + if ((scalar == NULL) && (num == 0)) { + return EC_POINT_set_to_infinity(group, r); + } + + for (i = 0; i < num; i++) { + if (group->meth != points[i]->meth) { + ECerr(EC_F_EC_WNAF_MUL, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + } + + if (scalar != NULL) { + generator = EC_GROUP_get0_generator(group); + if (generator == NULL) { + ECerr(EC_F_EC_WNAF_MUL, EC_R_UNDEFINED_GENERATOR); + goto err; + } + + /* look if we can use precomputed multiples of generator */ + + pre_comp = + EC_EX_DATA_get_data(group->extra_data, ec_pre_comp_dup, + ec_pre_comp_free, ec_pre_comp_clear_free); + + if (pre_comp && pre_comp->numblocks + && (EC_POINT_cmp(group, generator, pre_comp->points[0], ctx) == + 0)) { + blocksize = pre_comp->blocksize; + + /* + * determine maximum number of blocks that wNAF splitting may + * yield (NB: maximum wNAF length is bit length plus one) + */ + numblocks = (BN_num_bits(scalar) / blocksize) + 1; + + /* + * we cannot use more blocks than we have precomputation for + */ + if (numblocks > pre_comp->numblocks) + numblocks = pre_comp->numblocks; + + pre_points_per_block = (size_t)1 << (pre_comp->w - 1); + + /* check that pre_comp looks sane */ + if (pre_comp->num != (pre_comp->numblocks * pre_points_per_block)) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + goto err; + } + } else { + /* can't use precomputation */ + pre_comp = NULL; + numblocks = 1; + num_scalar = 1; /* treat 'scalar' like 'num'-th element of + * 'scalars' */ + } + } + + totalnum = num + numblocks; + + wsize = OPENSSL_malloc(totalnum * sizeof wsize[0]); + wNAF_len = OPENSSL_malloc(totalnum * sizeof wNAF_len[0]); + wNAF = OPENSSL_malloc((totalnum + 1) * sizeof wNAF[0]); /* includes space + * for pivot */ + val_sub = OPENSSL_malloc(totalnum * sizeof val_sub[0]); + + /* Ensure wNAF is initialised in case we end up going to err */ + if (wNAF) + wNAF[0] = NULL; /* preliminary pivot */ + + if (!wsize || !wNAF_len || !wNAF || !val_sub) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * num_val will be the total number of temporarily precomputed points + */ + num_val = 0; + + for (i = 0; i < num + num_scalar; i++) { + size_t bits; + + bits = i < num ? BN_num_bits(scalars[i]) : BN_num_bits(scalar); + wsize[i] = EC_window_bits_for_scalar_size(bits); + num_val += (size_t)1 << (wsize[i] - 1); + wNAF[i + 1] = NULL; /* make sure we always have a pivot */ + wNAF[i] = + compute_wNAF((i < num ? scalars[i] : scalar), wsize[i], + &wNAF_len[i]); + if (wNAF[i] == NULL) + goto err; + if (wNAF_len[i] > max_len) + max_len = wNAF_len[i]; + } + + if (numblocks) { + /* we go here iff scalar != NULL */ + + if (pre_comp == NULL) { + if (num_scalar != 1) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + goto err; + } + /* we have already generated a wNAF for 'scalar' */ + } else { + signed char *tmp_wNAF = NULL; + size_t tmp_len = 0; + + if (num_scalar != 0) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + goto err; + } + + /* + * use the window size for which we have precomputation + */ + wsize[num] = pre_comp->w; + tmp_wNAF = compute_wNAF(scalar, wsize[num], &tmp_len); + if (!tmp_wNAF) + goto err; + + if (tmp_len <= max_len) { + /* + * One of the other wNAFs is at least as long as the wNAF + * belonging to the generator, so wNAF splitting will not buy + * us anything. + */ + + numblocks = 1; + totalnum = num + 1; /* don't use wNAF splitting */ + wNAF[num] = tmp_wNAF; + wNAF[num + 1] = NULL; + wNAF_len[num] = tmp_len; + if (tmp_len > max_len) + max_len = tmp_len; + /* + * pre_comp->points starts with the points that we need here: + */ + val_sub[num] = pre_comp->points; + } else { + /* + * don't include tmp_wNAF directly into wNAF array - use wNAF + * splitting and include the blocks + */ + + signed char *pp; + EC_POINT **tmp_points; + + if (tmp_len < numblocks * blocksize) { + /* + * possibly we can do with fewer blocks than estimated + */ + numblocks = (tmp_len + blocksize - 1) / blocksize; + if (numblocks > pre_comp->numblocks) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + goto err; + } + totalnum = num + numblocks; + } + + /* split wNAF in 'numblocks' parts */ + pp = tmp_wNAF; + tmp_points = pre_comp->points; + + for (i = num; i < totalnum; i++) { + if (i < totalnum - 1) { + wNAF_len[i] = blocksize; + if (tmp_len < blocksize) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + goto err; + } + tmp_len -= blocksize; + } else + /* + * last block gets whatever is left (this could be + * more or less than 'blocksize'!) + */ + wNAF_len[i] = tmp_len; + + wNAF[i + 1] = NULL; + wNAF[i] = OPENSSL_malloc(wNAF_len[i]); + if (wNAF[i] == NULL) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); + OPENSSL_free(tmp_wNAF); + goto err; + } + memcpy(wNAF[i], pp, wNAF_len[i]); + if (wNAF_len[i] > max_len) + max_len = wNAF_len[i]; + + if (*tmp_points == NULL) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + OPENSSL_free(tmp_wNAF); + goto err; + } + val_sub[i] = tmp_points; + tmp_points += pre_points_per_block; + pp += blocksize; + } + OPENSSL_free(tmp_wNAF); + } + } + } + + /* + * All points we precompute now go into a single array 'val'. + * 'val_sub[i]' is a pointer to the subarray for the i-th point, or to a + * subarray of 'pre_comp->points' if we already have precomputation. + */ + val = OPENSSL_malloc((num_val + 1) * sizeof val[0]); + if (val == NULL) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_MALLOC_FAILURE); + goto err; + } + val[num_val] = NULL; /* pivot element */ + + /* allocate points for precomputation */ + v = val; + for (i = 0; i < num + num_scalar; i++) { + val_sub[i] = v; + for (j = 0; j < ((size_t)1 << (wsize[i] - 1)); j++) { + *v = EC_POINT_new(group); + if (*v == NULL) + goto err; + v++; + } + } + if (!(v == val + num_val)) { + ECerr(EC_F_EC_WNAF_MUL, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!(tmp = EC_POINT_new(group))) + goto err; + + /*- + * prepare precomputed values: + * val_sub[i][0] := points[i] + * val_sub[i][1] := 3 * points[i] + * val_sub[i][2] := 5 * points[i] + * ... + */ + for (i = 0; i < num + num_scalar; i++) { + if (i < num) { + if (!EC_POINT_copy(val_sub[i][0], points[i])) + goto err; + } else { + if (!EC_POINT_copy(val_sub[i][0], generator)) + goto err; + } + + if (wsize[i] > 1) { + if (!EC_POINT_dbl(group, tmp, val_sub[i][0], ctx)) + goto err; + for (j = 1; j < ((size_t)1 << (wsize[i] - 1)); j++) { + if (!EC_POINT_add + (group, val_sub[i][j], val_sub[i][j - 1], tmp, ctx)) + goto err; + } + } + } + +#if 1 /* optional; EC_window_bits_for_scalar_size + * assumes we do this step */ + if (!EC_POINTs_make_affine(group, num_val, val, ctx)) + goto err; +#endif + + r_is_at_infinity = 1; + + for (k = max_len - 1; k >= 0; k--) { + if (!r_is_at_infinity) { + if (!EC_POINT_dbl(group, r, r, ctx)) + goto err; + } + + for (i = 0; i < totalnum; i++) { + if (wNAF_len[i] > (size_t)k) { + int digit = wNAF[i][k]; + int is_neg; + + if (digit) { + is_neg = digit < 0; + + if (is_neg) + digit = -digit; + + if (is_neg != r_is_inverted) { + if (!r_is_at_infinity) { + if (!EC_POINT_invert(group, r, ctx)) + goto err; + } + r_is_inverted = !r_is_inverted; + } + + /* digit > 0 */ + + if (r_is_at_infinity) { + if (!EC_POINT_copy(r, val_sub[i][digit >> 1])) + goto err; + r_is_at_infinity = 0; + } else { + if (!EC_POINT_add + (group, r, r, val_sub[i][digit >> 1], ctx)) + goto err; + } + } + } + } + } + + if (r_is_at_infinity) { + if (!EC_POINT_set_to_infinity(group, r)) + goto err; + } else { + if (r_is_inverted) + if (!EC_POINT_invert(group, r, ctx)) + goto err; + } + + ret = 1; + + err: + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (tmp != NULL) + EC_POINT_free(tmp); + if (wsize != NULL) + OPENSSL_free(wsize); + if (wNAF_len != NULL) + OPENSSL_free(wNAF_len); + if (wNAF != NULL) { + signed char **w; + + for (w = wNAF; *w != NULL; w++) + OPENSSL_free(*w); + + OPENSSL_free(wNAF); + } + if (val != NULL) { + for (v = val; *v != NULL; v++) + EC_POINT_clear_free(*v); + + OPENSSL_free(val); + } + if (val_sub != NULL) { + OPENSSL_free(val_sub); + } + return ret; +} + +/*- + * ec_wNAF_precompute_mult() + * creates an EC_PRE_COMP object with preprecomputed multiples of the generator + * for use with wNAF splitting as implemented in ec_wNAF_mul(). + * + * 'pre_comp->points' is an array of multiples of the generator + * of the following form: + * points[0] = generator; + * points[1] = 3 * generator; + * ... + * points[2^(w-1)-1] = (2^(w-1)-1) * generator; + * points[2^(w-1)] = 2^blocksize * generator; + * points[2^(w-1)+1] = 3 * 2^blocksize * generator; + * ... + * points[2^(w-1)*(numblocks-1)-1] = (2^(w-1)) * 2^(blocksize*(numblocks-2)) * generator + * points[2^(w-1)*(numblocks-1)] = 2^(blocksize*(numblocks-1)) * generator + * ... + * points[2^(w-1)*numblocks-1] = (2^(w-1)) * 2^(blocksize*(numblocks-1)) * generator + * points[2^(w-1)*numblocks] = NULL + */ +int ec_wNAF_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +{ + const EC_POINT *generator; + EC_POINT *tmp_point = NULL, *base = NULL, **var; + BN_CTX *new_ctx = NULL; + BIGNUM *order; + size_t i, bits, w, pre_points_per_block, blocksize, numblocks, num; + EC_POINT **points = NULL; + EC_PRE_COMP *pre_comp; + int ret = 0; + + /* if there is an old EC_PRE_COMP object, throw it away */ + EC_EX_DATA_free_data(&group->extra_data, ec_pre_comp_dup, + ec_pre_comp_free, ec_pre_comp_clear_free); + + if ((pre_comp = ec_pre_comp_new(group)) == NULL) + return 0; + + generator = EC_GROUP_get0_generator(group); + if (generator == NULL) { + ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNDEFINED_GENERATOR); + goto err; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + } + + BN_CTX_start(ctx); + order = BN_CTX_get(ctx); + if (order == NULL) + goto err; + + if (!EC_GROUP_get_order(group, order, ctx)) + goto err; + if (BN_is_zero(order)) { + ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, EC_R_UNKNOWN_ORDER); + goto err; + } + + bits = BN_num_bits(order); + /* + * The following parameters mean we precompute (approximately) one point + * per bit. TBD: The combination 8, 4 is perfect for 160 bits; for other + * bit lengths, other parameter combinations might provide better + * efficiency. + */ + blocksize = 8; + w = 4; + if (EC_window_bits_for_scalar_size(bits) > w) { + /* let's not make the window too small ... */ + w = EC_window_bits_for_scalar_size(bits); + } + + numblocks = (bits + blocksize - 1) / blocksize; /* max. number of blocks + * to use for wNAF + * splitting */ + + pre_points_per_block = (size_t)1 << (w - 1); + num = pre_points_per_block * numblocks; /* number of points to compute + * and store */ + + points = OPENSSL_malloc(sizeof(EC_POINT *) * (num + 1)); + if (!points) { + ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); + goto err; + } + + var = points; + var[num] = NULL; /* pivot */ + for (i = 0; i < num; i++) { + if ((var[i] = EC_POINT_new(group)) == NULL) { + ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (!(tmp_point = EC_POINT_new(group)) || !(base = EC_POINT_new(group))) { + ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_POINT_copy(base, generator)) + goto err; + + /* do the precomputation */ + for (i = 0; i < numblocks; i++) { + size_t j; + + if (!EC_POINT_dbl(group, tmp_point, base, ctx)) + goto err; + + if (!EC_POINT_copy(*var++, base)) + goto err; + + for (j = 1; j < pre_points_per_block; j++, var++) { + /* + * calculate odd multiples of the current base point + */ + if (!EC_POINT_add(group, *var, tmp_point, *(var - 1), ctx)) + goto err; + } + + if (i < numblocks - 1) { + /* + * get the next base (multiply current one by 2^blocksize) + */ + size_t k; + + if (blocksize <= 2) { + ECerr(EC_F_EC_WNAF_PRECOMPUTE_MULT, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!EC_POINT_dbl(group, base, tmp_point, ctx)) + goto err; + for (k = 2; k < blocksize; k++) { + if (!EC_POINT_dbl(group, base, base, ctx)) + goto err; + } + } + } + + if (!EC_POINTs_make_affine(group, num, points, ctx)) + goto err; + + pre_comp->group = group; + pre_comp->blocksize = blocksize; + pre_comp->numblocks = numblocks; + pre_comp->w = w; + pre_comp->points = points; + points = NULL; + pre_comp->num = num; + + if (!EC_EX_DATA_set_data(&group->extra_data, pre_comp, + ec_pre_comp_dup, ec_pre_comp_free, + ec_pre_comp_clear_free)) + goto err; + pre_comp = NULL; + + ret = 1; + err: + if (ctx != NULL) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (pre_comp) + ec_pre_comp_free(pre_comp); + if (points) { + EC_POINT **p; + + for (p = points; *p != NULL; p++) + EC_POINT_free(*p); + OPENSSL_free(points); + } + if (tmp_point) + EC_POINT_free(tmp_point); + if (base) + EC_POINT_free(base); + return ret; +} + +int ec_wNAF_have_precompute_mult(const EC_GROUP *group) +{ + if (EC_EX_DATA_get_data + (group->extra_data, ec_pre_comp_dup, ec_pre_comp_free, + ec_pre_comp_clear_free) != NULL) + return 1; + else + return 0; +} diff --git a/libs/openssl/crypto/ec/ec_oct.c b/libs/openssl/crypto/ec/ec_oct.c new file mode 100644 index 00000000..040c414a --- /dev/null +++ b/libs/openssl/crypto/ec/ec_oct.c @@ -0,0 +1,192 @@ +/* crypto/ec/ec_lib.c */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Binary polynomial ECC support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include + +#include +#include + +#include "ec_lcl.h" + +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x, + int y_bit, BN_CTX *ctx) +{ + if (group->meth->point_set_compressed_coordinates == 0 + && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { + ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { + if (group->meth->field_type == NID_X9_62_prime_field) + return ec_GFp_simple_set_compressed_coordinates(group, point, x, + y_bit, ctx); + else +#ifdef OPENSSL_NO_EC2M + { + ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GFP, + EC_R_GF2M_NOT_SUPPORTED); + return 0; + } +#else + return ec_GF2m_simple_set_compressed_coordinates(group, point, x, + y_bit, ctx); +#endif + } + return group->meth->point_set_compressed_coordinates(group, point, x, + y_bit, ctx); +} + +#ifndef OPENSSL_NO_EC2M +int EC_POINT_set_compressed_coordinates_GF2m(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x, + int y_bit, BN_CTX *ctx) +{ + if (group->meth->point_set_compressed_coordinates == 0 + && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { + ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_SET_COMPRESSED_COORDINATES_GF2M, + EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { + if (group->meth->field_type == NID_X9_62_prime_field) + return ec_GFp_simple_set_compressed_coordinates(group, point, x, + y_bit, ctx); + else + return ec_GF2m_simple_set_compressed_coordinates(group, point, x, + y_bit, ctx); + } + return group->meth->point_set_compressed_coordinates(group, point, x, + y_bit, ctx); +} +#endif + +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, unsigned char *buf, + size_t len, BN_CTX *ctx) +{ + if (group->meth->point2oct == 0 + && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { + ECerr(EC_F_EC_POINT_POINT2OCT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { + if (group->meth->field_type == NID_X9_62_prime_field) + return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx); + else +#ifdef OPENSSL_NO_EC2M + { + ECerr(EC_F_EC_POINT_POINT2OCT, EC_R_GF2M_NOT_SUPPORTED); + return 0; + } +#else + return ec_GF2m_simple_point2oct(group, point, + form, buf, len, ctx); +#endif + } + + return group->meth->point2oct(group, point, form, buf, len, ctx); +} + +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, + const unsigned char *buf, size_t len, BN_CTX *ctx) +{ + if (group->meth->oct2point == 0 + && !(group->meth->flags & EC_FLAGS_DEFAULT_OCT)) { + ECerr(EC_F_EC_POINT_OCT2POINT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (group->meth != point->meth) { + ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (group->meth->flags & EC_FLAGS_DEFAULT_OCT) { + if (group->meth->field_type == NID_X9_62_prime_field) + return ec_GFp_simple_oct2point(group, point, buf, len, ctx); + else +#ifdef OPENSSL_NO_EC2M + { + ECerr(EC_F_EC_POINT_OCT2POINT, EC_R_GF2M_NOT_SUPPORTED); + return 0; + } +#else + return ec_GF2m_simple_oct2point(group, point, buf, len, ctx); +#endif + } + return group->meth->oct2point(group, point, buf, len, ctx); +} diff --git a/libs/openssl/crypto/ec/ec_pmeth.c b/libs/openssl/crypto/ec/ec_pmeth.c new file mode 100644 index 00000000..c189d3ff --- /dev/null +++ b/libs/openssl/crypto/ec/ec_pmeth.c @@ -0,0 +1,332 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include "evp_locl.h" + +/* EC pkey context structure */ + +typedef struct { + /* Key and paramgen group */ + EC_GROUP *gen_group; + /* message digest */ + const EVP_MD *md; +} EC_PKEY_CTX; + +static int pkey_ec_init(EVP_PKEY_CTX *ctx) +{ + EC_PKEY_CTX *dctx; + dctx = OPENSSL_malloc(sizeof(EC_PKEY_CTX)); + if (!dctx) + return 0; + dctx->gen_group = NULL; + dctx->md = NULL; + + ctx->data = dctx; + + return 1; +} + +static int pkey_ec_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + EC_PKEY_CTX *dctx, *sctx; + if (!pkey_ec_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + if (sctx->gen_group) { + dctx->gen_group = EC_GROUP_dup(sctx->gen_group); + if (!dctx->gen_group) + return 0; + } + dctx->md = sctx->md; + return 1; +} + +static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) +{ + EC_PKEY_CTX *dctx = ctx->data; + if (dctx) { + if (dctx->gen_group) + EC_GROUP_free(dctx->gen_group); + OPENSSL_free(dctx); + } +} + +static int pkey_ec_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) +{ + int ret, type; + unsigned int sltmp; + EC_PKEY_CTX *dctx = ctx->data; + EC_KEY *ec = ctx->pkey->pkey.ec; + + if (!sig) { + *siglen = ECDSA_size(ec); + return 1; + } else if (*siglen < (size_t)ECDSA_size(ec)) { + ECerr(EC_F_PKEY_EC_SIGN, EC_R_BUFFER_TOO_SMALL); + return 0; + } + + if (dctx->md) + type = EVP_MD_type(dctx->md); + else + type = NID_sha1; + + ret = ECDSA_sign(type, tbs, tbslen, sig, &sltmp, ec); + + if (ret <= 0) + return ret; + *siglen = (size_t)sltmp; + return 1; +} + +static int pkey_ec_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + int ret, type; + EC_PKEY_CTX *dctx = ctx->data; + EC_KEY *ec = ctx->pkey->pkey.ec; + + if (dctx->md) + type = EVP_MD_type(dctx->md); + else + type = NID_sha1; + + ret = ECDSA_verify(type, tbs, tbslen, sig, siglen, ec); + + return ret; +} + +#ifndef OPENSSL_NO_ECDH +static int pkey_ec_derive(EVP_PKEY_CTX *ctx, unsigned char *key, + size_t *keylen) +{ + int ret; + size_t outlen; + const EC_POINT *pubkey = NULL; + if (!ctx->pkey || !ctx->peerkey) { + ECerr(EC_F_PKEY_EC_DERIVE, EC_R_KEYS_NOT_SET); + return 0; + } + + if (!key) { + const EC_GROUP *group; + group = EC_KEY_get0_group(ctx->pkey->pkey.ec); + *keylen = (EC_GROUP_get_degree(group) + 7) / 8; + return 1; + } + + pubkey = EC_KEY_get0_public_key(ctx->peerkey->pkey.ec); + + /* + * NB: unlike PKCS#3 DH, if *outlen is less than maximum size this is not + * an error, the result is truncated. + */ + + outlen = *keylen; + + ret = ECDH_compute_key(key, outlen, pubkey, ctx->pkey->pkey.ec, 0); + if (ret < 0) + return ret; + *keylen = ret; + return 1; +} +#endif + +static int pkey_ec_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + EC_PKEY_CTX *dctx = ctx->data; + EC_GROUP *group; + switch (type) { + case EVP_PKEY_CTRL_EC_PARAMGEN_CURVE_NID: + group = EC_GROUP_new_by_curve_name(p1); + if (group == NULL) { + ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_CURVE); + return 0; + } + if (dctx->gen_group) + EC_GROUP_free(dctx->gen_group); + dctx->gen_group = group; + return 1; + + case EVP_PKEY_CTRL_MD: + if (EVP_MD_type((const EVP_MD *)p2) != NID_sha1 && + EVP_MD_type((const EVP_MD *)p2) != NID_ecdsa_with_SHA1 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha224 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha256 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha384 && + EVP_MD_type((const EVP_MD *)p2) != NID_sha512) { + ECerr(EC_F_PKEY_EC_CTRL, EC_R_INVALID_DIGEST_TYPE); + return 0; + } + dctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_PEER_KEY: + /* Default behaviour is OK */ + case EVP_PKEY_CTRL_DIGESTINIT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + case EVP_PKEY_CTRL_CMS_SIGN: + return 1; + + default: + return -2; + + } +} + +static int pkey_ec_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (!strcmp(type, "ec_paramgen_curve")) { + int nid; + nid = OBJ_sn2nid(value); + if (nid == NID_undef) + nid = OBJ_ln2nid(value); + if (nid == NID_undef) { + ECerr(EC_F_PKEY_EC_CTRL_STR, EC_R_INVALID_CURVE); + return 0; + } + return EVP_PKEY_CTX_set_ec_paramgen_curve_nid(ctx, nid); + } + return -2; +} + +static int pkey_ec_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + EC_KEY *ec = NULL; + EC_PKEY_CTX *dctx = ctx->data; + int ret = 0; + if (dctx->gen_group == NULL) { + ECerr(EC_F_PKEY_EC_PARAMGEN, EC_R_NO_PARAMETERS_SET); + return 0; + } + ec = EC_KEY_new(); + if (!ec) + return 0; + ret = EC_KEY_set_group(ec, dctx->gen_group); + if (ret) + EVP_PKEY_assign_EC_KEY(pkey, ec); + else + EC_KEY_free(ec); + return ret; +} + +static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + EC_KEY *ec = NULL; + if (ctx->pkey == NULL) { + ECerr(EC_F_PKEY_EC_KEYGEN, EC_R_NO_PARAMETERS_SET); + return 0; + } + ec = EC_KEY_new(); + if (!ec) + return 0; + EVP_PKEY_assign_EC_KEY(pkey, ec); + /* Note: if error return, pkey is freed by parent routine */ + if (!EVP_PKEY_copy_parameters(pkey, ctx->pkey)) + return 0; + return EC_KEY_generate_key(pkey->pkey.ec); +} + +const EVP_PKEY_METHOD ec_pkey_meth = { + EVP_PKEY_EC, + 0, + pkey_ec_init, + pkey_ec_copy, + pkey_ec_cleanup, + + 0, + pkey_ec_paramgen, + + 0, + pkey_ec_keygen, + + 0, + pkey_ec_sign, + + 0, + pkey_ec_verify, + + 0, 0, + + 0, 0, 0, 0, + + 0, 0, + + 0, 0, + + 0, +#ifndef OPENSSL_NO_ECDH + pkey_ec_derive, +#else + 0, +#endif + + pkey_ec_ctrl, + pkey_ec_ctrl_str +}; diff --git a/libs/openssl/crypto/ec/ec_print.c b/libs/openssl/crypto/ec/ec_print.c new file mode 100644 index 00000000..96b294d8 --- /dev/null +++ b/libs/openssl/crypto/ec/ec_print.c @@ -0,0 +1,179 @@ +/* crypto/ec/ec_print.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "ec_lcl.h" + +BIGNUM *EC_POINT_point2bn(const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + BIGNUM *ret, BN_CTX *ctx) +{ + size_t buf_len = 0; + unsigned char *buf; + + buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); + if (buf_len == 0) + return NULL; + + if ((buf = OPENSSL_malloc(buf_len)) == NULL) + return NULL; + + if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) { + OPENSSL_free(buf); + return NULL; + } + + ret = BN_bin2bn(buf, buf_len, ret); + + OPENSSL_free(buf); + + return ret; +} + +EC_POINT *EC_POINT_bn2point(const EC_GROUP *group, + const BIGNUM *bn, EC_POINT *point, BN_CTX *ctx) +{ + size_t buf_len = 0; + unsigned char *buf; + EC_POINT *ret; + + if ((buf_len = BN_num_bytes(bn)) == 0) + return NULL; + buf = OPENSSL_malloc(buf_len); + if (buf == NULL) + return NULL; + + if (!BN_bn2bin(bn, buf)) { + OPENSSL_free(buf); + return NULL; + } + + if (point == NULL) { + if ((ret = EC_POINT_new(group)) == NULL) { + OPENSSL_free(buf); + return NULL; + } + } else + ret = point; + + if (!EC_POINT_oct2point(group, ret, buf, buf_len, ctx)) { + if (point == NULL) + EC_POINT_clear_free(ret); + OPENSSL_free(buf); + return NULL; + } + + OPENSSL_free(buf); + return ret; +} + +static const char *HEX_DIGITS = "0123456789ABCDEF"; + +/* the return value must be freed (using OPENSSL_free()) */ +char *EC_POINT_point2hex(const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, BN_CTX *ctx) +{ + char *ret, *p; + size_t buf_len = 0, i; + unsigned char *buf, *pbuf; + + buf_len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); + if (buf_len == 0) + return NULL; + + if ((buf = OPENSSL_malloc(buf_len)) == NULL) + return NULL; + + if (!EC_POINT_point2oct(group, point, form, buf, buf_len, ctx)) { + OPENSSL_free(buf); + return NULL; + } + + ret = (char *)OPENSSL_malloc(buf_len * 2 + 2); + if (ret == NULL) { + OPENSSL_free(buf); + return NULL; + } + p = ret; + pbuf = buf; + for (i = buf_len; i > 0; i--) { + int v = (int)*(pbuf++); + *(p++) = HEX_DIGITS[v >> 4]; + *(p++) = HEX_DIGITS[v & 0x0F]; + } + *p = '\0'; + + OPENSSL_free(buf); + + return ret; +} + +EC_POINT *EC_POINT_hex2point(const EC_GROUP *group, + const char *buf, EC_POINT *point, BN_CTX *ctx) +{ + EC_POINT *ret = NULL; + BIGNUM *tmp_bn = NULL; + + if (!BN_hex2bn(&tmp_bn, buf)) + return NULL; + + ret = EC_POINT_bn2point(group, tmp_bn, point, ctx); + + BN_clear_free(tmp_bn); + + return ret; +} diff --git a/libs/openssl/crypto/ec/eck_prn.c b/libs/openssl/crypto/ec/eck_prn.c new file mode 100644 index 00000000..5ef12ec0 --- /dev/null +++ b/libs/openssl/crypto/ec/eck_prn.c @@ -0,0 +1,369 @@ +/* crypto/ec/eck_prn.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions originally developed by SUN MICROSYSTEMS, INC., and + * contributed to the OpenSSL project. + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +#ifndef OPENSSL_NO_FP_API +int ECPKParameters_print_fp(FILE *fp, const EC_GROUP *x, int off) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ECerr(EC_F_ECPKPARAMETERS_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = ECPKParameters_print(b, x, off); + BIO_free(b); + return (ret); +} + +int EC_KEY_print_fp(FILE *fp, const EC_KEY *x, int off) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ECerr(EC_F_EC_KEY_PRINT_FP, ERR_R_BIO_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = EC_KEY_print(b, x, off); + BIO_free(b); + return (ret); +} + +int ECParameters_print_fp(FILE *fp, const EC_KEY *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + ECerr(EC_F_ECPARAMETERS_PRINT_FP, ERR_R_BIO_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = ECParameters_print(b, x); + BIO_free(b); + return (ret); +} +#endif + +int EC_KEY_print(BIO *bp, const EC_KEY *x, int off) +{ + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) + return 0; + ret = EVP_PKEY_print_private(bp, pk, off, NULL); + EVP_PKEY_free(pk); + return ret; +} + +int ECParameters_print(BIO *bp, const EC_KEY *x) +{ + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_EC_KEY(pk, (EC_KEY *)x)) + return 0; + ret = EVP_PKEY_print_params(bp, pk, 4, NULL); + EVP_PKEY_free(pk); + return ret; +} + +static int print_bin(BIO *fp, const char *str, const unsigned char *num, + size_t len, int off); + +int ECPKParameters_print(BIO *bp, const EC_GROUP *x, int off) +{ + unsigned char *buffer = NULL; + size_t buf_len = 0, i; + int ret = 0, reason = ERR_R_BIO_LIB; + BN_CTX *ctx = NULL; + const EC_POINT *point = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL, *gen = NULL, + *order = NULL, *cofactor = NULL; + const unsigned char *seed; + size_t seed_len = 0; + + static const char *gen_compressed = "Generator (compressed):"; + static const char *gen_uncompressed = "Generator (uncompressed):"; + static const char *gen_hybrid = "Generator (hybrid):"; + + if (!x) { + reason = ERR_R_PASSED_NULL_PARAMETER; + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (EC_GROUP_get_asn1_flag(x)) { + /* the curve parameter are given by an asn1 OID */ + int nid; + + if (!BIO_indent(bp, off, 128)) + goto err; + + nid = EC_GROUP_get_curve_name(x); + if (nid == 0) + goto err; + + if (BIO_printf(bp, "ASN1 OID: %s", OBJ_nid2sn(nid)) <= 0) + goto err; + if (BIO_printf(bp, "\n") <= 0) + goto err; + } else { + /* explicit parameters */ + int is_char_two = 0; + point_conversion_form_t form; + int tmp_nid = EC_METHOD_get_field_type(EC_GROUP_method_of(x)); + + if (tmp_nid == NID_X9_62_characteristic_two_field) + is_char_two = 1; + + if ((p = BN_new()) == NULL || (a = BN_new()) == NULL || + (b = BN_new()) == NULL || (order = BN_new()) == NULL || + (cofactor = BN_new()) == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } +#ifndef OPENSSL_NO_EC2M + if (is_char_two) { + if (!EC_GROUP_get_curve_GF2m(x, p, a, b, ctx)) { + reason = ERR_R_EC_LIB; + goto err; + } + } else /* prime field */ +#endif + { + if (!EC_GROUP_get_curve_GFp(x, p, a, b, ctx)) { + reason = ERR_R_EC_LIB; + goto err; + } + } + + if ((point = EC_GROUP_get0_generator(x)) == NULL) { + reason = ERR_R_EC_LIB; + goto err; + } + if (!EC_GROUP_get_order(x, order, NULL) || + !EC_GROUP_get_cofactor(x, cofactor, NULL)) { + reason = ERR_R_EC_LIB; + goto err; + } + + form = EC_GROUP_get_point_conversion_form(x); + + if ((gen = EC_POINT_point2bn(x, point, form, NULL, ctx)) == NULL) { + reason = ERR_R_EC_LIB; + goto err; + } + + buf_len = (size_t)BN_num_bytes(p); + if (buf_len < (i = (size_t)BN_num_bytes(a))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(b))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(gen))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(order))) + buf_len = i; + if (buf_len < (i = (size_t)BN_num_bytes(cofactor))) + buf_len = i; + + if ((seed = EC_GROUP_get0_seed(x)) != NULL) + seed_len = EC_GROUP_get_seed_len(x); + + buf_len += 10; + if ((buffer = OPENSSL_malloc(buf_len)) == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + if (!BIO_indent(bp, off, 128)) + goto err; + + /* print the 'short name' of the field type */ + if (BIO_printf(bp, "Field Type: %s\n", OBJ_nid2sn(tmp_nid)) + <= 0) + goto err; + + if (is_char_two) { + /* print the 'short name' of the base type OID */ + int basis_type = EC_GROUP_get_basis_type(x); + if (basis_type == 0) + goto err; + + if (!BIO_indent(bp, off, 128)) + goto err; + + if (BIO_printf(bp, "Basis Type: %s\n", + OBJ_nid2sn(basis_type)) <= 0) + goto err; + + /* print the polynomial */ + if ((p != NULL) && !ASN1_bn_print(bp, "Polynomial:", p, buffer, + off)) + goto err; + } else { + if ((p != NULL) && !ASN1_bn_print(bp, "Prime:", p, buffer, off)) + goto err; + } + if ((a != NULL) && !ASN1_bn_print(bp, "A: ", a, buffer, off)) + goto err; + if ((b != NULL) && !ASN1_bn_print(bp, "B: ", b, buffer, off)) + goto err; + if (form == POINT_CONVERSION_COMPRESSED) { + if ((gen != NULL) && !ASN1_bn_print(bp, gen_compressed, gen, + buffer, off)) + goto err; + } else if (form == POINT_CONVERSION_UNCOMPRESSED) { + if ((gen != NULL) && !ASN1_bn_print(bp, gen_uncompressed, gen, + buffer, off)) + goto err; + } else { /* form == POINT_CONVERSION_HYBRID */ + + if ((gen != NULL) && !ASN1_bn_print(bp, gen_hybrid, gen, + buffer, off)) + goto err; + } + if ((order != NULL) && !ASN1_bn_print(bp, "Order: ", order, + buffer, off)) + goto err; + if ((cofactor != NULL) && !ASN1_bn_print(bp, "Cofactor: ", cofactor, + buffer, off)) + goto err; + if (seed && !print_bin(bp, "Seed:", seed, seed_len, off)) + goto err; + } + ret = 1; + err: + if (!ret) + ECerr(EC_F_ECPKPARAMETERS_PRINT, reason); + if (p) + BN_free(p); + if (a) + BN_free(a); + if (b) + BN_free(b); + if (gen) + BN_free(gen); + if (order) + BN_free(order); + if (cofactor) + BN_free(cofactor); + if (ctx) + BN_CTX_free(ctx); + if (buffer != NULL) + OPENSSL_free(buffer); + return (ret); +} + +static int print_bin(BIO *fp, const char *name, const unsigned char *buf, + size_t len, int off) +{ + size_t i; + char str[128]; + + if (buf == NULL) + return 1; + if (off > 0) { + if (off > 128) + off = 128; + memset(str, ' ', off); + if (BIO_write(fp, str, off) <= 0) + return 0; + } else { + off = 0; + } + + if (BIO_printf(fp, "%s", name) <= 0) + return 0; + + for (i = 0; i < len; i++) { + if ((i % 15) == 0) { + str[0] = '\n'; + memset(&(str[1]), ' ', off + 4); + if (BIO_write(fp, str, off + 1 + 4) <= 0) + return 0; + } + if (BIO_printf(fp, "%02x%s", buf[i], ((i + 1) == len) ? "" : ":") <= + 0) + return 0; + } + if (BIO_write(fp, "\n", 1) <= 0) + return 0; + + return 1; +} diff --git a/libs/openssl/crypto/ec/ecp_mont.c b/libs/openssl/crypto/ec/ecp_mont.c new file mode 100644 index 00000000..b2de7fae --- /dev/null +++ b/libs/openssl/crypto/ec/ecp_mont.c @@ -0,0 +1,308 @@ +/* crypto/ec/ecp_mont.c */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions of this software developed by SUN MICROSYSTEMS, INC., + * and contributed to the OpenSSL project. + */ + +#include + +#ifdef OPENSSL_FIPS +# include +#endif + +#include "ec_lcl.h" + +const EC_METHOD *EC_GFp_mont_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, + ec_GFp_mont_group_init, + ec_GFp_mont_group_finish, + ec_GFp_mont_group_clear_finish, + ec_GFp_mont_group_copy, + ec_GFp_mont_group_set_curve, + ec_GFp_simple_group_get_curve, + ec_GFp_simple_group_get_degree, + ec_GFp_simple_group_check_discriminant, + ec_GFp_simple_point_init, + ec_GFp_simple_point_finish, + ec_GFp_simple_point_clear_finish, + ec_GFp_simple_point_copy, + ec_GFp_simple_point_set_to_infinity, + ec_GFp_simple_set_Jprojective_coordinates_GFp, + ec_GFp_simple_get_Jprojective_coordinates_GFp, + ec_GFp_simple_point_set_affine_coordinates, + ec_GFp_simple_point_get_affine_coordinates, + 0, 0, 0, + ec_GFp_simple_add, + ec_GFp_simple_dbl, + ec_GFp_simple_invert, + ec_GFp_simple_is_at_infinity, + ec_GFp_simple_is_on_curve, + ec_GFp_simple_cmp, + ec_GFp_simple_make_affine, + ec_GFp_simple_points_make_affine, + 0 /* mul */ , + 0 /* precompute_mult */ , + 0 /* have_precompute_mult */ , + ec_GFp_mont_field_mul, + ec_GFp_mont_field_sqr, + 0 /* field_div */ , + ec_GFp_mont_field_encode, + ec_GFp_mont_field_decode, + ec_GFp_mont_field_set_to_one + }; + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return fips_ec_gfp_mont_method(); +#endif + + return &ret; +} + +int ec_GFp_mont_group_init(EC_GROUP *group) +{ + int ok; + + ok = ec_GFp_simple_group_init(group); + group->field_data1 = NULL; + group->field_data2 = NULL; + return ok; +} + +void ec_GFp_mont_group_finish(EC_GROUP *group) +{ + if (group->field_data1 != NULL) { + BN_MONT_CTX_free(group->field_data1); + group->field_data1 = NULL; + } + if (group->field_data2 != NULL) { + BN_free(group->field_data2); + group->field_data2 = NULL; + } + ec_GFp_simple_group_finish(group); +} + +void ec_GFp_mont_group_clear_finish(EC_GROUP *group) +{ + if (group->field_data1 != NULL) { + BN_MONT_CTX_free(group->field_data1); + group->field_data1 = NULL; + } + if (group->field_data2 != NULL) { + BN_clear_free(group->field_data2); + group->field_data2 = NULL; + } + ec_GFp_simple_group_clear_finish(group); +} + +int ec_GFp_mont_group_copy(EC_GROUP *dest, const EC_GROUP *src) +{ + if (dest->field_data1 != NULL) { + BN_MONT_CTX_free(dest->field_data1); + dest->field_data1 = NULL; + } + if (dest->field_data2 != NULL) { + BN_clear_free(dest->field_data2); + dest->field_data2 = NULL; + } + + if (!ec_GFp_simple_group_copy(dest, src)) + return 0; + + if (src->field_data1 != NULL) { + dest->field_data1 = BN_MONT_CTX_new(); + if (dest->field_data1 == NULL) + return 0; + if (!BN_MONT_CTX_copy(dest->field_data1, src->field_data1)) + goto err; + } + if (src->field_data2 != NULL) { + dest->field_data2 = BN_dup(src->field_data2); + if (dest->field_data2 == NULL) + goto err; + } + + return 1; + + err: + if (dest->field_data1 != NULL) { + BN_MONT_CTX_free(dest->field_data1); + dest->field_data1 = NULL; + } + return 0; +} + +int ec_GFp_mont_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BN_MONT_CTX *mont = NULL; + BIGNUM *one = NULL; + int ret = 0; + + if (group->field_data1 != NULL) { + BN_MONT_CTX_free(group->field_data1); + group->field_data1 = NULL; + } + if (group->field_data2 != NULL) { + BN_free(group->field_data2); + group->field_data2 = NULL; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + mont = BN_MONT_CTX_new(); + if (mont == NULL) + goto err; + if (!BN_MONT_CTX_set(mont, p, ctx)) { + ECerr(EC_F_EC_GFP_MONT_GROUP_SET_CURVE, ERR_R_BN_LIB); + goto err; + } + one = BN_new(); + if (one == NULL) + goto err; + if (!BN_to_montgomery(one, BN_value_one(), mont, ctx)) + goto err; + + group->field_data1 = mont; + mont = NULL; + group->field_data2 = one; + one = NULL; + + ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + + if (!ret) { + BN_MONT_CTX_free(group->field_data1); + group->field_data1 = NULL; + BN_free(group->field_data2); + group->field_data2 = NULL; + } + + err: + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (mont != NULL) + BN_MONT_CTX_free(mont); + return ret; +} + +int ec_GFp_mont_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + if (group->field_data1 == NULL) { + ECerr(EC_F_EC_GFP_MONT_FIELD_MUL, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_mod_mul_montgomery(r, a, b, group->field_data1, ctx); +} + +int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) +{ + if (group->field_data1 == NULL) { + ECerr(EC_F_EC_GFP_MONT_FIELD_SQR, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_mod_mul_montgomery(r, a, a, group->field_data1, ctx); +} + +int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, BN_CTX *ctx) +{ + if (group->field_data1 == NULL) { + ECerr(EC_F_EC_GFP_MONT_FIELD_ENCODE, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_to_montgomery(r, a, (BN_MONT_CTX *)group->field_data1, ctx); +} + +int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, + const BIGNUM *a, BN_CTX *ctx) +{ + if (group->field_data1 == NULL) { + ECerr(EC_F_EC_GFP_MONT_FIELD_DECODE, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_from_montgomery(r, a, group->field_data1, ctx); +} + +int ec_GFp_mont_field_set_to_one(const EC_GROUP *group, BIGNUM *r, + BN_CTX *ctx) +{ + if (group->field_data2 == NULL) { + ECerr(EC_F_EC_GFP_MONT_FIELD_SET_TO_ONE, EC_R_NOT_INITIALIZED); + return 0; + } + + if (!BN_copy(r, group->field_data2)) + return 0; + return 1; +} diff --git a/libs/openssl/crypto/ec/ecp_nist.c b/libs/openssl/crypto/ec/ecp_nist.c new file mode 100644 index 00000000..3944e249 --- /dev/null +++ b/libs/openssl/crypto/ec/ecp_nist.c @@ -0,0 +1,220 @@ +/* crypto/ec/ecp_nist.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions of this software developed by SUN MICROSYSTEMS, INC., + * and contributed to the OpenSSL project. + */ + +#include + +#include +#include +#include "ec_lcl.h" + +#ifdef OPENSSL_FIPS +# include +#endif + +const EC_METHOD *EC_GFp_nist_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, + ec_GFp_simple_group_init, + ec_GFp_simple_group_finish, + ec_GFp_simple_group_clear_finish, + ec_GFp_nist_group_copy, + ec_GFp_nist_group_set_curve, + ec_GFp_simple_group_get_curve, + ec_GFp_simple_group_get_degree, + ec_GFp_simple_group_check_discriminant, + ec_GFp_simple_point_init, + ec_GFp_simple_point_finish, + ec_GFp_simple_point_clear_finish, + ec_GFp_simple_point_copy, + ec_GFp_simple_point_set_to_infinity, + ec_GFp_simple_set_Jprojective_coordinates_GFp, + ec_GFp_simple_get_Jprojective_coordinates_GFp, + ec_GFp_simple_point_set_affine_coordinates, + ec_GFp_simple_point_get_affine_coordinates, + 0, 0, 0, + ec_GFp_simple_add, + ec_GFp_simple_dbl, + ec_GFp_simple_invert, + ec_GFp_simple_is_at_infinity, + ec_GFp_simple_is_on_curve, + ec_GFp_simple_cmp, + ec_GFp_simple_make_affine, + ec_GFp_simple_points_make_affine, + 0 /* mul */ , + 0 /* precompute_mult */ , + 0 /* have_precompute_mult */ , + ec_GFp_nist_field_mul, + ec_GFp_nist_field_sqr, + 0 /* field_div */ , + 0 /* field_encode */ , + 0 /* field_decode */ , + 0 /* field_set_to_one */ + }; + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return fips_ec_gfp_nist_method(); +#endif + + return &ret; +} + +int ec_GFp_nist_group_copy(EC_GROUP *dest, const EC_GROUP *src) +{ + dest->field_mod_func = src->field_mod_func; + + return ec_GFp_simple_group_copy(dest, src); +} + +int ec_GFp_nist_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *tmp_bn; + + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + + BN_CTX_start(ctx); + if ((tmp_bn = BN_CTX_get(ctx)) == NULL) + goto err; + + if (BN_ucmp(BN_get0_nist_prime_192(), p) == 0) + group->field_mod_func = BN_nist_mod_192; + else if (BN_ucmp(BN_get0_nist_prime_224(), p) == 0) + group->field_mod_func = BN_nist_mod_224; + else if (BN_ucmp(BN_get0_nist_prime_256(), p) == 0) + group->field_mod_func = BN_nist_mod_256; + else if (BN_ucmp(BN_get0_nist_prime_384(), p) == 0) + group->field_mod_func = BN_nist_mod_384; + else if (BN_ucmp(BN_get0_nist_prime_521(), p) == 0) + group->field_mod_func = BN_nist_mod_521; + else { + ECerr(EC_F_EC_GFP_NIST_GROUP_SET_CURVE, EC_R_NOT_A_NIST_PRIME); + goto err; + } + + ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_nist_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *ctx_new = NULL; + + if (!group || !r || !a || !b) { + ECerr(EC_F_EC_GFP_NIST_FIELD_MUL, ERR_R_PASSED_NULL_PARAMETER); + goto err; + } + if (!ctx) + if ((ctx_new = ctx = BN_CTX_new()) == NULL) + goto err; + + if (!BN_mul(r, a, b, ctx)) + goto err; + if (!group->field_mod_func(r, r, &group->field, ctx)) + goto err; + + ret = 1; + err: + if (ctx_new) + BN_CTX_free(ctx_new); + return ret; +} + +int ec_GFp_nist_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *ctx_new = NULL; + + if (!group || !r || !a) { + ECerr(EC_F_EC_GFP_NIST_FIELD_SQR, EC_R_PASSED_NULL_PARAMETER); + goto err; + } + if (!ctx) + if ((ctx_new = ctx = BN_CTX_new()) == NULL) + goto err; + + if (!BN_sqr(r, a, ctx)) + goto err; + if (!group->field_mod_func(r, r, &group->field, ctx)) + goto err; + + ret = 1; + err: + if (ctx_new) + BN_CTX_free(ctx_new); + return ret; +} diff --git a/libs/openssl/crypto/ec/ecp_nistp224.c b/libs/openssl/crypto/ec/ecp_nistp224.c new file mode 100644 index 00000000..ed09f97a --- /dev/null +++ b/libs/openssl/crypto/ec/ecp_nistp224.c @@ -0,0 +1,1769 @@ +/* crypto/ec/ecp_nistp224.c */ +/* + * Written by Emilia Kasper (Google) for the OpenSSL project. + */ +/* Copyright 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * A 64-bit implementation of the NIST P-224 elliptic curve point multiplication + * + * Inspired by Daniel J. Bernstein's public domain nistp224 implementation + * and Adam Langley's public domain 64-bit C implementation of curve25519 + */ + +#include +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + +# ifndef OPENSSL_SYS_VMS +# include +# else +# include +# endif + +# include +# include +# include "ec_lcl.h" + +# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) + /* even with gcc, the typedef won't work for 32-bit platforms */ +typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit + * platforms */ +# else +# error "Need GCC 3.1 or later to define type uint128_t" +# endif + +typedef uint8_t u8; +typedef uint64_t u64; +typedef int64_t s64; + +/******************************************************************************/ +/*- + * INTERNAL REPRESENTATION OF FIELD ELEMENTS + * + * Field elements are represented as a_0 + 2^56*a_1 + 2^112*a_2 + 2^168*a_3 + * using 64-bit coefficients called 'limbs', + * and sometimes (for multiplication results) as + * b_0 + 2^56*b_1 + 2^112*b_2 + 2^168*b_3 + 2^224*b_4 + 2^280*b_5 + 2^336*b_6 + * using 128-bit coefficients called 'widelimbs'. + * A 4-limb representation is an 'felem'; + * a 7-widelimb representation is a 'widefelem'. + * Even within felems, bits of adjacent limbs overlap, and we don't always + * reduce the representations: we ensure that inputs to each felem + * multiplication satisfy a_i < 2^60, so outputs satisfy b_i < 4*2^60*2^60, + * and fit into a 128-bit word without overflow. The coefficients are then + * again partially reduced to obtain an felem satisfying a_i < 2^57. + * We only reduce to the unique minimal representation at the end of the + * computation. + */ + +typedef uint64_t limb; +typedef uint128_t widelimb; + +typedef limb felem[4]; +typedef widelimb widefelem[7]; + +/* + * Field element represented as a byte arrary. 28*8 = 224 bits is also the + * group order size for the elliptic curve, and we also use this type for + * scalars for point multiplication. + */ +typedef u8 felem_bytearray[28]; + +static const felem_bytearray nistp224_curve_params[5] = { + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a */ + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE}, + {0xB4, 0x05, 0x0A, 0x85, 0x0C, 0x04, 0xB3, 0xAB, 0xF5, 0x41, /* b */ + 0x32, 0x56, 0x50, 0x44, 0xB0, 0xB7, 0xD7, 0xBF, 0xD8, 0xBA, + 0x27, 0x0B, 0x39, 0x43, 0x23, 0x55, 0xFF, 0xB4}, + {0xB7, 0x0E, 0x0C, 0xBD, 0x6B, 0xB4, 0xBF, 0x7F, 0x32, 0x13, /* x */ + 0x90, 0xB9, 0x4A, 0x03, 0xC1, 0xD3, 0x56, 0xC2, 0x11, 0x22, + 0x34, 0x32, 0x80, 0xD6, 0x11, 0x5C, 0x1D, 0x21}, + {0xbd, 0x37, 0x63, 0x88, 0xb5, 0xf7, 0x23, 0xfb, 0x4c, 0x22, /* y */ + 0xdf, 0xe6, 0xcd, 0x43, 0x75, 0xa0, 0x5a, 0x07, 0x47, 0x64, + 0x44, 0xd5, 0x81, 0x99, 0x85, 0x00, 0x7e, 0x34} +}; + +/*- + * Precomputed multiples of the standard generator + * Points are given in coordinates (X, Y, Z) where Z normally is 1 + * (0 for the point at infinity). + * For each field element, slice a_0 is word 0, etc. + * + * The table has 2 * 16 elements, starting with the following: + * index | bits | point + * ------+---------+------------------------------ + * 0 | 0 0 0 0 | 0G + * 1 | 0 0 0 1 | 1G + * 2 | 0 0 1 0 | 2^56G + * 3 | 0 0 1 1 | (2^56 + 1)G + * 4 | 0 1 0 0 | 2^112G + * 5 | 0 1 0 1 | (2^112 + 1)G + * 6 | 0 1 1 0 | (2^112 + 2^56)G + * 7 | 0 1 1 1 | (2^112 + 2^56 + 1)G + * 8 | 1 0 0 0 | 2^168G + * 9 | 1 0 0 1 | (2^168 + 1)G + * 10 | 1 0 1 0 | (2^168 + 2^56)G + * 11 | 1 0 1 1 | (2^168 + 2^56 + 1)G + * 12 | 1 1 0 0 | (2^168 + 2^112)G + * 13 | 1 1 0 1 | (2^168 + 2^112 + 1)G + * 14 | 1 1 1 0 | (2^168 + 2^112 + 2^56)G + * 15 | 1 1 1 1 | (2^168 + 2^112 + 2^56 + 1)G + * followed by a copy of this with each element multiplied by 2^28. + * + * The reason for this is so that we can clock bits into four different + * locations when doing simple scalar multiplies against the base point, + * and then another four locations using the second 16 elements. + */ +static const felem gmul[2][16][3] = { {{{0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}}, + {{0x3280d6115c1d21, 0xc1d356c2112234, + 0x7f321390b94a03, 0xb70e0cbd6bb4bf}, + {0xd5819985007e34, 0x75a05a07476444, + 0xfb4c22dfe6cd43, 0xbd376388b5f723}, + {1, 0, 0, 0}}, + {{0xfd9675666ebbe9, 0xbca7664d40ce5e, + 0x2242df8d8a2a43, 0x1f49bbb0f99bc5}, + {0x29e0b892dc9c43, 0xece8608436e662, + 0xdc858f185310d0, 0x9812dd4eb8d321}, + {1, 0, 0, 0}}, + {{0x6d3e678d5d8eb8, 0x559eed1cb362f1, + 0x16e9a3bbce8a3f, 0xeedcccd8c2a748}, + {0xf19f90ed50266d, 0xabf2b4bf65f9df, + 0x313865468fafec, 0x5cb379ba910a17}, + {1, 0, 0, 0}}, + {{0x0641966cab26e3, 0x91fb2991fab0a0, + 0xefec27a4e13a0b, 0x0499aa8a5f8ebe}, + {0x7510407766af5d, 0x84d929610d5450, + 0x81d77aae82f706, 0x6916f6d4338c5b}, + {1, 0, 0, 0}}, + {{0xea95ac3b1f15c6, 0x086000905e82d4, + 0xdd323ae4d1c8b1, 0x932b56be7685a3}, + {0x9ef93dea25dbbf, 0x41665960f390f0, + 0xfdec76dbe2a8a7, 0x523e80f019062a}, + {1, 0, 0, 0}}, + {{0x822fdd26732c73, 0xa01c83531b5d0f, + 0x363f37347c1ba4, 0xc391b45c84725c}, + {0xbbd5e1b2d6ad24, 0xddfbcde19dfaec, + 0xc393da7e222a7f, 0x1efb7890ede244}, + {1, 0, 0, 0}}, + {{0x4c9e90ca217da1, 0xd11beca79159bb, + 0xff8d33c2c98b7c, 0x2610b39409f849}, + {0x44d1352ac64da0, 0xcdbb7b2c46b4fb, + 0x966c079b753c89, 0xfe67e4e820b112}, + {1, 0, 0, 0}}, + {{0xe28cae2df5312d, 0xc71b61d16f5c6e, + 0x79b7619a3e7c4c, 0x05c73240899b47}, + {0x9f7f6382c73e3a, 0x18615165c56bda, + 0x641fab2116fd56, 0x72855882b08394}, + {1, 0, 0, 0}}, + {{0x0469182f161c09, 0x74a98ca8d00fb5, + 0xb89da93489a3e0, 0x41c98768fb0c1d}, + {0xe5ea05fb32da81, 0x3dce9ffbca6855, + 0x1cfe2d3fbf59e6, 0x0e5e03408738a7}, + {1, 0, 0, 0}}, + {{0xdab22b2333e87f, 0x4430137a5dd2f6, + 0xe03ab9f738beb8, 0xcb0c5d0dc34f24}, + {0x764a7df0c8fda5, 0x185ba5c3fa2044, + 0x9281d688bcbe50, 0xc40331df893881}, + {1, 0, 0, 0}}, + {{0xb89530796f0f60, 0xade92bd26909a3, + 0x1a0c83fb4884da, 0x1765bf22a5a984}, + {0x772a9ee75db09e, 0x23bc6c67cec16f, + 0x4c1edba8b14e2f, 0xe2a215d9611369}, + {1, 0, 0, 0}}, + {{0x571e509fb5efb3, 0xade88696410552, + 0xc8ae85fada74fe, 0x6c7e4be83bbde3}, + {0xff9f51160f4652, 0xb47ce2495a6539, + 0xa2946c53b582f4, 0x286d2db3ee9a60}, + {1, 0, 0, 0}}, + {{0x40bbd5081a44af, 0x0995183b13926c, + 0xbcefba6f47f6d0, 0x215619e9cc0057}, + {0x8bc94d3b0df45e, 0xf11c54a3694f6f, + 0x8631b93cdfe8b5, 0xe7e3f4b0982db9}, + {1, 0, 0, 0}}, + {{0xb17048ab3e1c7b, 0xac38f36ff8a1d8, + 0x1c29819435d2c6, 0xc813132f4c07e9}, + {0x2891425503b11f, 0x08781030579fea, + 0xf5426ba5cc9674, 0x1e28ebf18562bc}, + {1, 0, 0, 0}}, + {{0x9f31997cc864eb, 0x06cd91d28b5e4c, + 0xff17036691a973, 0xf1aef351497c58}, + {0xdd1f2d600564ff, 0xdead073b1402db, + 0x74a684435bd693, 0xeea7471f962558}, + {1, 0, 0, 0}}}, +{{{0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}}, + {{0x9665266dddf554, 0x9613d78b60ef2d, 0xce27a34cdba417, 0xd35ab74d6afc31}, + {0x85ccdd22deb15e, 0x2137e5783a6aab, 0xa141cffd8c93c6, 0x355a1830e90f2d}, + {1, 0, 0, 0}}, + {{0x1a494eadaade65, 0xd6da4da77fe53c, 0xe7992996abec86, 0x65c3553c6090e3}, + {0xfa610b1fb09346, 0xf1c6540b8a4aaf, 0xc51a13ccd3cbab, 0x02995b1b18c28a}, + {1, 0, 0, 0}}, + {{0x7874568e7295ef, 0x86b419fbe38d04, 0xdc0690a7550d9a, 0xd3966a44beac33}, + {0x2b7280ec29132f, 0xbeaa3b6a032df3, 0xdc7dd88ae41200, 0xd25e2513e3a100}, + {1, 0, 0, 0}}, + {{0x924857eb2efafd, 0xac2bce41223190, 0x8edaa1445553fc, 0x825800fd3562d5}, + {0x8d79148ea96621, 0x23a01c3dd9ed8d, 0xaf8b219f9416b5, 0xd8db0cc277daea}, + {1, 0, 0, 0}}, + {{0x76a9c3b1a700f0, 0xe9acd29bc7e691, 0x69212d1a6b0327, 0x6322e97fe154be}, + {0x469fc5465d62aa, 0x8d41ed18883b05, 0x1f8eae66c52b88, 0xe4fcbe9325be51}, + {1, 0, 0, 0}}, + {{0x825fdf583cac16, 0x020b857c7b023a, 0x683c17744b0165, 0x14ffd0a2daf2f1}, + {0x323b36184218f9, 0x4944ec4e3b47d4, 0xc15b3080841acf, 0x0bced4b01a28bb}, + {1, 0, 0, 0}}, + {{0x92ac22230df5c4, 0x52f33b4063eda8, 0xcb3f19870c0c93, 0x40064f2ba65233}, + {0xfe16f0924f8992, 0x012da25af5b517, 0x1a57bb24f723a6, 0x06f8bc76760def}, + {1, 0, 0, 0}}, + {{0x4a7084f7817cb9, 0xbcab0738ee9a78, 0x3ec11e11d9c326, 0xdc0fe90e0f1aae}, + {0xcf639ea5f98390, 0x5c350aa22ffb74, 0x9afae98a4047b7, 0x956ec2d617fc45}, + {1, 0, 0, 0}}, + {{0x4306d648c1be6a, 0x9247cd8bc9a462, 0xf5595e377d2f2e, 0xbd1c3caff1a52e}, + {0x045e14472409d0, 0x29f3e17078f773, 0x745a602b2d4f7d, 0x191837685cdfbb}, + {1, 0, 0, 0}}, + {{0x5b6ee254a8cb79, 0x4953433f5e7026, 0xe21faeb1d1def4, 0xc4c225785c09de}, + {0x307ce7bba1e518, 0x31b125b1036db8, 0x47e91868839e8f, 0xc765866e33b9f3}, + {1, 0, 0, 0}}, + {{0x3bfece24f96906, 0x4794da641e5093, 0xde5df64f95db26, 0x297ecd89714b05}, + {0x701bd3ebb2c3aa, 0x7073b4f53cb1d5, 0x13c5665658af16, 0x9895089d66fe58}, + {1, 0, 0, 0}}, + {{0x0fef05f78c4790, 0x2d773633b05d2e, 0x94229c3a951c94, 0xbbbd70df4911bb}, + {0xb2c6963d2c1168, 0x105f47a72b0d73, 0x9fdf6111614080, 0x7b7e94b39e67b0}, + {1, 0, 0, 0}}, + {{0xad1a7d6efbe2b3, 0xf012482c0da69d, 0x6b3bdf12438345, 0x40d7558d7aa4d9}, + {0x8a09fffb5c6d3d, 0x9a356e5d9ffd38, 0x5973f15f4f9b1c, 0xdcd5f59f63c3ea}, + {1, 0, 0, 0}}, + {{0xacf39f4c5ca7ab, 0x4c8071cc5fd737, 0xc64e3602cd1184, 0x0acd4644c9abba}, + {0x6c011a36d8bf6e, 0xfecd87ba24e32a, 0x19f6f56574fad8, 0x050b204ced9405}, + {1, 0, 0, 0}}, + {{0xed4f1cae7d9a96, 0x5ceef7ad94c40a, 0x778e4a3bf3ef9b, 0x7405783dc3b55e}, + {0x32477c61b6e8c6, 0xb46a97570f018b, 0x91176d0a7e95d1, 0x3df90fbc4c7d0e}, + {1, 0, 0, 0}}} +}; + +/* Precomputation for the group generator. */ +typedef struct { + felem g_pre_comp[2][16][3]; + int references; +} NISTP224_PRE_COMP; + +const EC_METHOD *EC_GFp_nistp224_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, + ec_GFp_nistp224_group_init, + ec_GFp_simple_group_finish, + ec_GFp_simple_group_clear_finish, + ec_GFp_nist_group_copy, + ec_GFp_nistp224_group_set_curve, + ec_GFp_simple_group_get_curve, + ec_GFp_simple_group_get_degree, + ec_GFp_simple_group_check_discriminant, + ec_GFp_simple_point_init, + ec_GFp_simple_point_finish, + ec_GFp_simple_point_clear_finish, + ec_GFp_simple_point_copy, + ec_GFp_simple_point_set_to_infinity, + ec_GFp_simple_set_Jprojective_coordinates_GFp, + ec_GFp_simple_get_Jprojective_coordinates_GFp, + ec_GFp_simple_point_set_affine_coordinates, + ec_GFp_nistp224_point_get_affine_coordinates, + 0 /* point_set_compressed_coordinates */ , + 0 /* point2oct */ , + 0 /* oct2point */ , + ec_GFp_simple_add, + ec_GFp_simple_dbl, + ec_GFp_simple_invert, + ec_GFp_simple_is_at_infinity, + ec_GFp_simple_is_on_curve, + ec_GFp_simple_cmp, + ec_GFp_simple_make_affine, + ec_GFp_simple_points_make_affine, + ec_GFp_nistp224_points_mul, + ec_GFp_nistp224_precompute_mult, + ec_GFp_nistp224_have_precompute_mult, + ec_GFp_nist_field_mul, + ec_GFp_nist_field_sqr, + 0 /* field_div */ , + 0 /* field_encode */ , + 0 /* field_decode */ , + 0 /* field_set_to_one */ + }; + + return &ret; +} + +/* + * Helper functions to convert field elements to/from internal representation + */ +static void bin28_to_felem(felem out, const u8 in[28]) +{ + out[0] = *((const uint64_t *)(in)) & 0x00ffffffffffffff; + out[1] = (*((const uint64_t *)(in + 7))) & 0x00ffffffffffffff; + out[2] = (*((const uint64_t *)(in + 14))) & 0x00ffffffffffffff; + out[3] = (*((const uint64_t *)(in+20))) >> 8; +} + +static void felem_to_bin28(u8 out[28], const felem in) +{ + unsigned i; + for (i = 0; i < 7; ++i) { + out[i] = in[0] >> (8 * i); + out[i + 7] = in[1] >> (8 * i); + out[i + 14] = in[2] >> (8 * i); + out[i + 21] = in[3] >> (8 * i); + } +} + +/* To preserve endianness when using BN_bn2bin and BN_bin2bn */ +static void flip_endian(u8 *out, const u8 *in, unsigned len) +{ + unsigned i; + for (i = 0; i < len; ++i) + out[i] = in[len - 1 - i]; +} + +/* From OpenSSL BIGNUM to internal representation */ +static int BN_to_felem(felem out, const BIGNUM *bn) +{ + felem_bytearray b_in; + felem_bytearray b_out; + unsigned num_bytes; + + /* BN_bn2bin eats leading zeroes */ + memset(b_out, 0, sizeof b_out); + num_bytes = BN_num_bytes(bn); + if (num_bytes > sizeof b_out) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + if (BN_is_negative(bn)) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + num_bytes = BN_bn2bin(bn, b_in); + flip_endian(b_out, b_in, num_bytes); + bin28_to_felem(out, b_out); + return 1; +} + +/* From internal representation to OpenSSL BIGNUM */ +static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) +{ + felem_bytearray b_in, b_out; + felem_to_bin28(b_in, in); + flip_endian(b_out, b_in, sizeof b_out); + return BN_bin2bn(b_out, sizeof b_out, out); +} + +/******************************************************************************/ +/*- + * FIELD OPERATIONS + * + * Field operations, using the internal representation of field elements. + * NB! These operations are specific to our point multiplication and cannot be + * expected to be correct in general - e.g., multiplication with a large scalar + * will cause an overflow. + * + */ + +static void felem_one(felem out) +{ + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; +} + +static void felem_assign(felem out, const felem in) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; +} + +/* Sum two field elements: out += in */ +static void felem_sum(felem out, const felem in) +{ + out[0] += in[0]; + out[1] += in[1]; + out[2] += in[2]; + out[3] += in[3]; +} + +/* Get negative value: out = -in */ +/* Assumes in[i] < 2^57 */ +static void felem_neg(felem out, const felem in) +{ + static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2); + static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2); + static const limb two58m42m2 = (((limb) 1) << 58) - + (((limb) 1) << 42) - (((limb) 1) << 2); + + /* Set to 0 mod 2^224-2^96+1 to ensure out > in */ + out[0] = two58p2 - in[0]; + out[1] = two58m42m2 - in[1]; + out[2] = two58m2 - in[2]; + out[3] = two58m2 - in[3]; +} + +/* Subtract field elements: out -= in */ +/* Assumes in[i] < 2^57 */ +static void felem_diff(felem out, const felem in) +{ + static const limb two58p2 = (((limb) 1) << 58) + (((limb) 1) << 2); + static const limb two58m2 = (((limb) 1) << 58) - (((limb) 1) << 2); + static const limb two58m42m2 = (((limb) 1) << 58) - + (((limb) 1) << 42) - (((limb) 1) << 2); + + /* Add 0 mod 2^224-2^96+1 to ensure out > in */ + out[0] += two58p2; + out[1] += two58m42m2; + out[2] += two58m2; + out[3] += two58m2; + + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; +} + +/* Subtract in unreduced 128-bit mode: out -= in */ +/* Assumes in[i] < 2^119 */ +static void widefelem_diff(widefelem out, const widefelem in) +{ + static const widelimb two120 = ((widelimb) 1) << 120; + static const widelimb two120m64 = (((widelimb) 1) << 120) - + (((widelimb) 1) << 64); + static const widelimb two120m104m64 = (((widelimb) 1) << 120) - + (((widelimb) 1) << 104) - (((widelimb) 1) << 64); + + /* Add 0 mod 2^224-2^96+1 to ensure out > in */ + out[0] += two120; + out[1] += two120m64; + out[2] += two120m64; + out[3] += two120; + out[4] += two120m104m64; + out[5] += two120m64; + out[6] += two120m64; + + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; + out[4] -= in[4]; + out[5] -= in[5]; + out[6] -= in[6]; +} + +/* Subtract in mixed mode: out128 -= in64 */ +/* in[i] < 2^63 */ +static void felem_diff_128_64(widefelem out, const felem in) +{ + static const widelimb two64p8 = (((widelimb) 1) << 64) + + (((widelimb) 1) << 8); + static const widelimb two64m8 = (((widelimb) 1) << 64) - + (((widelimb) 1) << 8); + static const widelimb two64m48m8 = (((widelimb) 1) << 64) - + (((widelimb) 1) << 48) - (((widelimb) 1) << 8); + + /* Add 0 mod 2^224-2^96+1 to ensure out > in */ + out[0] += two64p8; + out[1] += two64m48m8; + out[2] += two64m8; + out[3] += two64m8; + + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; +} + +/* + * Multiply a field element by a scalar: out = out * scalar The scalars we + * actually use are small, so results fit without overflow + */ +static void felem_scalar(felem out, const limb scalar) +{ + out[0] *= scalar; + out[1] *= scalar; + out[2] *= scalar; + out[3] *= scalar; +} + +/* + * Multiply an unreduced field element by a scalar: out = out * scalar The + * scalars we actually use are small, so results fit without overflow + */ +static void widefelem_scalar(widefelem out, const widelimb scalar) +{ + out[0] *= scalar; + out[1] *= scalar; + out[2] *= scalar; + out[3] *= scalar; + out[4] *= scalar; + out[5] *= scalar; + out[6] *= scalar; +} + +/* Square a field element: out = in^2 */ +static void felem_square(widefelem out, const felem in) +{ + limb tmp0, tmp1, tmp2; + tmp0 = 2 * in[0]; + tmp1 = 2 * in[1]; + tmp2 = 2 * in[2]; + out[0] = ((widelimb) in[0]) * in[0]; + out[1] = ((widelimb) in[0]) * tmp1; + out[2] = ((widelimb) in[0]) * tmp2 + ((widelimb) in[1]) * in[1]; + out[3] = ((widelimb) in[3]) * tmp0 + ((widelimb) in[1]) * tmp2; + out[4] = ((widelimb) in[3]) * tmp1 + ((widelimb) in[2]) * in[2]; + out[5] = ((widelimb) in[3]) * tmp2; + out[6] = ((widelimb) in[3]) * in[3]; +} + +/* Multiply two field elements: out = in1 * in2 */ +static void felem_mul(widefelem out, const felem in1, const felem in2) +{ + out[0] = ((widelimb) in1[0]) * in2[0]; + out[1] = ((widelimb) in1[0]) * in2[1] + ((widelimb) in1[1]) * in2[0]; + out[2] = ((widelimb) in1[0]) * in2[2] + ((widelimb) in1[1]) * in2[1] + + ((widelimb) in1[2]) * in2[0]; + out[3] = ((widelimb) in1[0]) * in2[3] + ((widelimb) in1[1]) * in2[2] + + ((widelimb) in1[2]) * in2[1] + ((widelimb) in1[3]) * in2[0]; + out[4] = ((widelimb) in1[1]) * in2[3] + ((widelimb) in1[2]) * in2[2] + + ((widelimb) in1[3]) * in2[1]; + out[5] = ((widelimb) in1[2]) * in2[3] + ((widelimb) in1[3]) * in2[2]; + out[6] = ((widelimb) in1[3]) * in2[3]; +} + +/*- + * Reduce seven 128-bit coefficients to four 64-bit coefficients. + * Requires in[i] < 2^126, + * ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 */ +static void felem_reduce(felem out, const widefelem in) +{ + static const widelimb two127p15 = (((widelimb) 1) << 127) + + (((widelimb) 1) << 15); + static const widelimb two127m71 = (((widelimb) 1) << 127) - + (((widelimb) 1) << 71); + static const widelimb two127m71m55 = (((widelimb) 1) << 127) - + (((widelimb) 1) << 71) - (((widelimb) 1) << 55); + widelimb output[5]; + + /* Add 0 mod 2^224-2^96+1 to ensure all differences are positive */ + output[0] = in[0] + two127p15; + output[1] = in[1] + two127m71m55; + output[2] = in[2] + two127m71; + output[3] = in[3]; + output[4] = in[4]; + + /* Eliminate in[4], in[5], in[6] */ + output[4] += in[6] >> 16; + output[3] += (in[6] & 0xffff) << 40; + output[2] -= in[6]; + + output[3] += in[5] >> 16; + output[2] += (in[5] & 0xffff) << 40; + output[1] -= in[5]; + + output[2] += output[4] >> 16; + output[1] += (output[4] & 0xffff) << 40; + output[0] -= output[4]; + + /* Carry 2 -> 3 -> 4 */ + output[3] += output[2] >> 56; + output[2] &= 0x00ffffffffffffff; + + output[4] = output[3] >> 56; + output[3] &= 0x00ffffffffffffff; + + /* Now output[2] < 2^56, output[3] < 2^56, output[4] < 2^72 */ + + /* Eliminate output[4] */ + output[2] += output[4] >> 16; + /* output[2] < 2^56 + 2^56 = 2^57 */ + output[1] += (output[4] & 0xffff) << 40; + output[0] -= output[4]; + + /* Carry 0 -> 1 -> 2 -> 3 */ + output[1] += output[0] >> 56; + out[0] = output[0] & 0x00ffffffffffffff; + + output[2] += output[1] >> 56; + /* output[2] < 2^57 + 2^72 */ + out[1] = output[1] & 0x00ffffffffffffff; + output[3] += output[2] >> 56; + /* output[3] <= 2^56 + 2^16 */ + out[2] = output[2] & 0x00ffffffffffffff; + + /*- + * out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, + * out[3] <= 2^56 + 2^16 (due to final carry), + * so out < 2*p + */ + out[3] = output[3]; +} + +static void felem_square_reduce(felem out, const felem in) +{ + widefelem tmp; + felem_square(tmp, in); + felem_reduce(out, tmp); +} + +static void felem_mul_reduce(felem out, const felem in1, const felem in2) +{ + widefelem tmp; + felem_mul(tmp, in1, in2); + felem_reduce(out, tmp); +} + +/* + * Reduce to unique minimal representation. Requires 0 <= in < 2*p (always + * call felem_reduce first) + */ +static void felem_contract(felem out, const felem in) +{ + static const int64_t two56 = ((limb) 1) << 56; + /* 0 <= in < 2*p, p = 2^224 - 2^96 + 1 */ + /* if in > p , reduce in = in - 2^224 + 2^96 - 1 */ + int64_t tmp[4], a; + tmp[0] = in[0]; + tmp[1] = in[1]; + tmp[2] = in[2]; + tmp[3] = in[3]; + /* Case 1: a = 1 iff in >= 2^224 */ + a = (in[3] >> 56); + tmp[0] -= a; + tmp[1] += a << 40; + tmp[3] &= 0x00ffffffffffffff; + /* + * Case 2: a = 0 iff p <= in < 2^224, i.e., the high 128 bits are all 1 + * and the lower part is non-zero + */ + a = ((in[3] & in[2] & (in[1] | 0x000000ffffffffff)) + 1) | + (((int64_t) (in[0] + (in[1] & 0x000000ffffffffff)) - 1) >> 63); + a &= 0x00ffffffffffffff; + /* turn a into an all-one mask (if a = 0) or an all-zero mask */ + a = (a - 1) >> 63; + /* subtract 2^224 - 2^96 + 1 if a is all-one */ + tmp[3] &= a ^ 0xffffffffffffffff; + tmp[2] &= a ^ 0xffffffffffffffff; + tmp[1] &= (a ^ 0xffffffffffffffff) | 0x000000ffffffffff; + tmp[0] -= 1 & a; + + /* + * eliminate negative coefficients: if tmp[0] is negative, tmp[1] must be + * non-zero, so we only need one step + */ + a = tmp[0] >> 63; + tmp[0] += two56 & a; + tmp[1] -= 1 & a; + + /* carry 1 -> 2 -> 3 */ + tmp[2] += tmp[1] >> 56; + tmp[1] &= 0x00ffffffffffffff; + + tmp[3] += tmp[2] >> 56; + tmp[2] &= 0x00ffffffffffffff; + + /* Now 0 <= out < p */ + out[0] = tmp[0]; + out[1] = tmp[1]; + out[2] = tmp[2]; + out[3] = tmp[3]; +} + +/* + * Zero-check: returns 1 if input is 0, and 0 otherwise. We know that field + * elements are reduced to in < 2^225, so we only need to check three cases: + * 0, 2^224 - 2^96 + 1, and 2^225 - 2^97 + 2 + */ +static limb felem_is_zero(const felem in) +{ + limb zero, two224m96p1, two225m97p2; + + zero = in[0] | in[1] | in[2] | in[3]; + zero = (((int64_t) (zero) - 1) >> 63) & 1; + two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000) + | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x00ffffffffffffff); + two224m96p1 = (((int64_t) (two224m96p1) - 1) >> 63) & 1; + two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000) + | (in[2] ^ 0x00ffffffffffffff) | (in[3] ^ 0x01ffffffffffffff); + two225m97p2 = (((int64_t) (two225m97p2) - 1) >> 63) & 1; + return (zero | two224m96p1 | two225m97p2); +} + +static limb felem_is_zero_int(const felem in) +{ + return (int)(felem_is_zero(in) & ((limb) 1)); +} + +/* Invert a field element */ +/* Computation chain copied from djb's code */ +static void felem_inv(felem out, const felem in) +{ + felem ftmp, ftmp2, ftmp3, ftmp4; + widefelem tmp; + unsigned i; + + felem_square(tmp, in); + felem_reduce(ftmp, tmp); /* 2 */ + felem_mul(tmp, in, ftmp); + felem_reduce(ftmp, tmp); /* 2^2 - 1 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^3 - 2 */ + felem_mul(tmp, in, ftmp); + felem_reduce(ftmp, tmp); /* 2^3 - 1 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp2, tmp); /* 2^4 - 2 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); /* 2^5 - 4 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); /* 2^6 - 8 */ + felem_mul(tmp, ftmp2, ftmp); + felem_reduce(ftmp, tmp); /* 2^6 - 1 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp2, tmp); /* 2^7 - 2 */ + for (i = 0; i < 5; ++i) { /* 2^12 - 2^6 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); + } + felem_mul(tmp, ftmp2, ftmp); + felem_reduce(ftmp2, tmp); /* 2^12 - 1 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^13 - 2 */ + for (i = 0; i < 11; ++i) { /* 2^24 - 2^12 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp2, tmp); /* 2^24 - 1 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^25 - 2 */ + for (i = 0; i < 23; ++i) { /* 2^48 - 2^24 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^48 - 1 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp4, tmp); /* 2^49 - 2 */ + for (i = 0; i < 47; ++i) { /* 2^96 - 2^48 */ + felem_square(tmp, ftmp4); + felem_reduce(ftmp4, tmp); + } + felem_mul(tmp, ftmp3, ftmp4); + felem_reduce(ftmp3, tmp); /* 2^96 - 1 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp4, tmp); /* 2^97 - 2 */ + for (i = 0; i < 23; ++i) { /* 2^120 - 2^24 */ + felem_square(tmp, ftmp4); + felem_reduce(ftmp4, tmp); + } + felem_mul(tmp, ftmp2, ftmp4); + felem_reduce(ftmp2, tmp); /* 2^120 - 1 */ + for (i = 0; i < 6; ++i) { /* 2^126 - 2^6 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); + } + felem_mul(tmp, ftmp2, ftmp); + felem_reduce(ftmp, tmp); /* 2^126 - 1 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^127 - 2 */ + felem_mul(tmp, ftmp, in); + felem_reduce(ftmp, tmp); /* 2^127 - 1 */ + for (i = 0; i < 97; ++i) { /* 2^224 - 2^97 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); + } + felem_mul(tmp, ftmp, ftmp3); + felem_reduce(out, tmp); /* 2^224 - 2^96 - 1 */ +} + +/* + * Copy in constant time: if icopy == 1, copy in to out, if icopy == 0, copy + * out to itself. + */ +static void copy_conditional(felem out, const felem in, limb icopy) +{ + unsigned i; + /* + * icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one + */ + const limb copy = -icopy; + for (i = 0; i < 4; ++i) { + const limb tmp = copy & (in[i] ^ out[i]); + out[i] ^= tmp; + } +} + +/******************************************************************************/ +/*- + * ELLIPTIC CURVE POINT OPERATIONS + * + * Points are represented in Jacobian projective coordinates: + * (X, Y, Z) corresponds to the affine point (X/Z^2, Y/Z^3), + * or to the point at infinity if Z == 0. + * + */ + +/*- + * Double an elliptic curve point: + * (X', Y', Z') = 2 * (X, Y, Z), where + * X' = (3 * (X - Z^2) * (X + Z^2))^2 - 8 * X * Y^2 + * Y' = 3 * (X - Z^2) * (X + Z^2) * (4 * X * Y^2 - X') - 8 * Y^2 + * Z' = (Y + Z)^2 - Y^2 - Z^2 = 2 * Y * Z + * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed, + * while x_out == y_in is not (maybe this works, but it's not tested). + */ +static void +point_double(felem x_out, felem y_out, felem z_out, + const felem x_in, const felem y_in, const felem z_in) +{ + widefelem tmp, tmp2; + felem delta, gamma, beta, alpha, ftmp, ftmp2; + + felem_assign(ftmp, x_in); + felem_assign(ftmp2, x_in); + + /* delta = z^2 */ + felem_square(tmp, z_in); + felem_reduce(delta, tmp); + + /* gamma = y^2 */ + felem_square(tmp, y_in); + felem_reduce(gamma, tmp); + + /* beta = x*gamma */ + felem_mul(tmp, x_in, gamma); + felem_reduce(beta, tmp); + + /* alpha = 3*(x-delta)*(x+delta) */ + felem_diff(ftmp, delta); + /* ftmp[i] < 2^57 + 2^58 + 2 < 2^59 */ + felem_sum(ftmp2, delta); + /* ftmp2[i] < 2^57 + 2^57 = 2^58 */ + felem_scalar(ftmp2, 3); + /* ftmp2[i] < 3 * 2^58 < 2^60 */ + felem_mul(tmp, ftmp, ftmp2); + /* tmp[i] < 2^60 * 2^59 * 4 = 2^121 */ + felem_reduce(alpha, tmp); + + /* x' = alpha^2 - 8*beta */ + felem_square(tmp, alpha); + /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */ + felem_assign(ftmp, beta); + felem_scalar(ftmp, 8); + /* ftmp[i] < 8 * 2^57 = 2^60 */ + felem_diff_128_64(tmp, ftmp); + /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */ + felem_reduce(x_out, tmp); + + /* z' = (y + z)^2 - gamma - delta */ + felem_sum(delta, gamma); + /* delta[i] < 2^57 + 2^57 = 2^58 */ + felem_assign(ftmp, y_in); + felem_sum(ftmp, z_in); + /* ftmp[i] < 2^57 + 2^57 = 2^58 */ + felem_square(tmp, ftmp); + /* tmp[i] < 4 * 2^58 * 2^58 = 2^118 */ + felem_diff_128_64(tmp, delta); + /* tmp[i] < 2^118 + 2^64 + 8 < 2^119 */ + felem_reduce(z_out, tmp); + + /* y' = alpha*(4*beta - x') - 8*gamma^2 */ + felem_scalar(beta, 4); + /* beta[i] < 4 * 2^57 = 2^59 */ + felem_diff(beta, x_out); + /* beta[i] < 2^59 + 2^58 + 2 < 2^60 */ + felem_mul(tmp, alpha, beta); + /* tmp[i] < 4 * 2^57 * 2^60 = 2^119 */ + felem_square(tmp2, gamma); + /* tmp2[i] < 4 * 2^57 * 2^57 = 2^116 */ + widefelem_scalar(tmp2, 8); + /* tmp2[i] < 8 * 2^116 = 2^119 */ + widefelem_diff(tmp, tmp2); + /* tmp[i] < 2^119 + 2^120 < 2^121 */ + felem_reduce(y_out, tmp); +} + +/*- + * Add two elliptic curve points: + * (X_1, Y_1, Z_1) + (X_2, Y_2, Z_2) = (X_3, Y_3, Z_3), where + * X_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1)^2 - (Z_1^2 * X_2 - Z_2^2 * X_1)^3 - + * 2 * Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2 + * Y_3 = (Z_1^3 * Y_2 - Z_2^3 * Y_1) * (Z_2^2 * X_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^2 - X_3) - + * Z_2^3 * Y_1 * (Z_1^2 * X_2 - Z_2^2 * X_1)^3 + * Z_3 = (Z_1^2 * X_2 - Z_2^2 * X_1) * (Z_1 * Z_2) + * + * This runs faster if 'mixed' is set, which requires Z_2 = 1 or Z_2 = 0. + */ + +/* + * This function is not entirely constant-time: it includes a branch for + * checking whether the two input points are equal, (while not equal to the + * point at infinity). This case never happens during single point + * multiplication, so there is no timing leak for ECDH or ECDSA signing. + */ +static void point_add(felem x3, felem y3, felem z3, + const felem x1, const felem y1, const felem z1, + const int mixed, const felem x2, const felem y2, + const felem z2) +{ + felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out; + widefelem tmp, tmp2; + limb z1_is_zero, z2_is_zero, x_equal, y_equal; + + if (!mixed) { + /* ftmp2 = z2^2 */ + felem_square(tmp, z2); + felem_reduce(ftmp2, tmp); + + /* ftmp4 = z2^3 */ + felem_mul(tmp, ftmp2, z2); + felem_reduce(ftmp4, tmp); + + /* ftmp4 = z2^3*y1 */ + felem_mul(tmp2, ftmp4, y1); + felem_reduce(ftmp4, tmp2); + + /* ftmp2 = z2^2*x1 */ + felem_mul(tmp2, ftmp2, x1); + felem_reduce(ftmp2, tmp2); + } else { + /* + * We'll assume z2 = 1 (special case z2 = 0 is handled later) + */ + + /* ftmp4 = z2^3*y1 */ + felem_assign(ftmp4, y1); + + /* ftmp2 = z2^2*x1 */ + felem_assign(ftmp2, x1); + } + + /* ftmp = z1^2 */ + felem_square(tmp, z1); + felem_reduce(ftmp, tmp); + + /* ftmp3 = z1^3 */ + felem_mul(tmp, ftmp, z1); + felem_reduce(ftmp3, tmp); + + /* tmp = z1^3*y2 */ + felem_mul(tmp, ftmp3, y2); + /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */ + + /* ftmp3 = z1^3*y2 - z2^3*y1 */ + felem_diff_128_64(tmp, ftmp4); + /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */ + felem_reduce(ftmp3, tmp); + + /* tmp = z1^2*x2 */ + felem_mul(tmp, ftmp, x2); + /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */ + + /* ftmp = z1^2*x2 - z2^2*x1 */ + felem_diff_128_64(tmp, ftmp2); + /* tmp[i] < 2^116 + 2^64 + 8 < 2^117 */ + felem_reduce(ftmp, tmp); + + /* + * the formulae are incorrect if the points are equal so we check for + * this and do doubling if this happens + */ + x_equal = felem_is_zero(ftmp); + y_equal = felem_is_zero(ftmp3); + z1_is_zero = felem_is_zero(z1); + z2_is_zero = felem_is_zero(z2); + /* In affine coordinates, (X_1, Y_1) == (X_2, Y_2) */ + if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) { + point_double(x3, y3, z3, x1, y1, z1); + return; + } + + /* ftmp5 = z1*z2 */ + if (!mixed) { + felem_mul(tmp, z1, z2); + felem_reduce(ftmp5, tmp); + } else { + /* special case z2 = 0 is handled later */ + felem_assign(ftmp5, z1); + } + + /* z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) */ + felem_mul(tmp, ftmp, ftmp5); + felem_reduce(z_out, tmp); + + /* ftmp = (z1^2*x2 - z2^2*x1)^2 */ + felem_assign(ftmp5, ftmp); + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); + + /* ftmp5 = (z1^2*x2 - z2^2*x1)^3 */ + felem_mul(tmp, ftmp, ftmp5); + felem_reduce(ftmp5, tmp); + + /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */ + felem_mul(tmp, ftmp2, ftmp); + felem_reduce(ftmp2, tmp); + + /* tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 */ + felem_mul(tmp, ftmp4, ftmp5); + /* tmp[i] < 4 * 2^57 * 2^57 = 2^116 */ + + /* tmp2 = (z1^3*y2 - z2^3*y1)^2 */ + felem_square(tmp2, ftmp3); + /* tmp2[i] < 4 * 2^57 * 2^57 < 2^116 */ + + /* tmp2 = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 */ + felem_diff_128_64(tmp2, ftmp5); + /* tmp2[i] < 2^116 + 2^64 + 8 < 2^117 */ + + /* ftmp5 = 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 */ + felem_assign(ftmp5, ftmp2); + felem_scalar(ftmp5, 2); + /* ftmp5[i] < 2 * 2^57 = 2^58 */ + + /*- + * x_out = (z1^3*y2 - z2^3*y1)^2 - (z1^2*x2 - z2^2*x1)^3 - + * 2*z2^2*x1*(z1^2*x2 - z2^2*x1)^2 + */ + felem_diff_128_64(tmp2, ftmp5); + /* tmp2[i] < 2^117 + 2^64 + 8 < 2^118 */ + felem_reduce(x_out, tmp2); + + /* ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out */ + felem_diff(ftmp2, x_out); + /* ftmp2[i] < 2^57 + 2^58 + 2 < 2^59 */ + + /* + * tmp2 = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) + */ + felem_mul(tmp2, ftmp3, ftmp2); + /* tmp2[i] < 4 * 2^57 * 2^59 = 2^118 */ + + /*- + * y_out = (z1^3*y2 - z2^3*y1)*(z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out) - + * z2^3*y1*(z1^2*x2 - z2^2*x1)^3 + */ + widefelem_diff(tmp2, tmp); + /* tmp2[i] < 2^118 + 2^120 < 2^121 */ + felem_reduce(y_out, tmp2); + + /* + * the result (x_out, y_out, z_out) is incorrect if one of the inputs is + * the point at infinity, so we need to check for this separately + */ + + /* + * if point 1 is at infinity, copy point 2 to output, and vice versa + */ + copy_conditional(x_out, x2, z1_is_zero); + copy_conditional(x_out, x1, z2_is_zero); + copy_conditional(y_out, y2, z1_is_zero); + copy_conditional(y_out, y1, z2_is_zero); + copy_conditional(z_out, z2, z1_is_zero); + copy_conditional(z_out, z1, z2_is_zero); + felem_assign(x3, x_out); + felem_assign(y3, y_out); + felem_assign(z3, z_out); +} + +/* + * select_point selects the |idx|th point from a precomputation table and + * copies it to out. + * The pre_comp array argument should be size of |size| argument + */ +static void select_point(const u64 idx, unsigned int size, + const felem pre_comp[][3], felem out[3]) +{ + unsigned i, j; + limb *outlimbs = &out[0][0]; + memset(outlimbs, 0, 3 * sizeof(felem)); + + for (i = 0; i < size; i++) { + const limb *inlimbs = &pre_comp[i][0][0]; + u64 mask = i ^ idx; + mask |= mask >> 4; + mask |= mask >> 2; + mask |= mask >> 1; + mask &= 1; + mask--; + for (j = 0; j < 4 * 3; j++) + outlimbs[j] |= inlimbs[j] & mask; + } +} + +/* get_bit returns the |i|th bit in |in| */ +static char get_bit(const felem_bytearray in, unsigned i) +{ + if (i >= 224) + return 0; + return (in[i >> 3] >> (i & 7)) & 1; +} + +/* + * Interleaved point multiplication using precomputed point multiples: The + * small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[], the scalars + * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the + * generator, using certain (large) precomputed multiples in g_pre_comp. + * Output point (X, Y, Z) is stored in x_out, y_out, z_out + */ +static void batch_mul(felem x_out, felem y_out, felem z_out, + const felem_bytearray scalars[], + const unsigned num_points, const u8 *g_scalar, + const int mixed, const felem pre_comp[][17][3], + const felem g_pre_comp[2][16][3]) +{ + int i, skip; + unsigned num; + unsigned gen_mul = (g_scalar != NULL); + felem nq[3], tmp[4]; + u64 bits; + u8 sign, digit; + + /* set nq to the point at infinity */ + memset(nq, 0, 3 * sizeof(felem)); + + /* + * Loop over all scalars msb-to-lsb, interleaving additions of multiples + * of the generator (two in each of the last 28 rounds) and additions of + * other points multiples (every 5th round). + */ + skip = 1; /* save two point operations in the first + * round */ + for (i = (num_points ? 220 : 27); i >= 0; --i) { + /* double */ + if (!skip) + point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + + /* add multiples of the generator */ + if (gen_mul && (i <= 27)) { + /* first, look 28 bits upwards */ + bits = get_bit(g_scalar, i + 196) << 3; + bits |= get_bit(g_scalar, i + 140) << 2; + bits |= get_bit(g_scalar, i + 84) << 1; + bits |= get_bit(g_scalar, i + 28); + /* select the point to add, in constant time */ + select_point(bits, 16, g_pre_comp[1], tmp); + + if (!skip) { + /* value 1 below is argument for "mixed" */ + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]); + } else { + memcpy(nq, tmp, 3 * sizeof(felem)); + skip = 0; + } + + /* second, look at the current position */ + bits = get_bit(g_scalar, i + 168) << 3; + bits |= get_bit(g_scalar, i + 112) << 2; + bits |= get_bit(g_scalar, i + 56) << 1; + bits |= get_bit(g_scalar, i); + /* select the point to add, in constant time */ + select_point(bits, 16, g_pre_comp[0], tmp); + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], + 1 /* mixed */ , tmp[0], tmp[1], tmp[2]); + } + + /* do other additions every 5 doublings */ + if (num_points && (i % 5 == 0)) { + /* loop over all scalars */ + for (num = 0; num < num_points; ++num) { + bits = get_bit(scalars[num], i + 4) << 5; + bits |= get_bit(scalars[num], i + 3) << 4; + bits |= get_bit(scalars[num], i + 2) << 3; + bits |= get_bit(scalars[num], i + 1) << 2; + bits |= get_bit(scalars[num], i) << 1; + bits |= get_bit(scalars[num], i - 1); + ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + + /* select the point to add or subtract */ + select_point(digit, 17, pre_comp[num], tmp); + felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative + * point */ + copy_conditional(tmp[1], tmp[3], sign); + + if (!skip) { + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], + mixed, tmp[0], tmp[1], tmp[2]); + } else { + memcpy(nq, tmp, 3 * sizeof(felem)); + skip = 0; + } + } + } + } + felem_assign(x_out, nq[0]); + felem_assign(y_out, nq[1]); + felem_assign(z_out, nq[2]); +} + +/******************************************************************************/ +/* + * FUNCTIONS TO MANAGE PRECOMPUTATION + */ + +static NISTP224_PRE_COMP *nistp224_pre_comp_new() +{ + NISTP224_PRE_COMP *ret = NULL; + ret = (NISTP224_PRE_COMP *) OPENSSL_malloc(sizeof *ret); + if (!ret) { + ECerr(EC_F_NISTP224_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + return ret; + } + memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp)); + ret->references = 1; + return ret; +} + +static void *nistp224_pre_comp_dup(void *src_) +{ + NISTP224_PRE_COMP *src = src_; + + /* no need to actually copy, these objects never change! */ + CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); + + return src_; +} + +static void nistp224_pre_comp_free(void *pre_) +{ + int i; + NISTP224_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + OPENSSL_free(pre); +} + +static void nistp224_pre_comp_clear_free(void *pre_) +{ + int i; + NISTP224_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + OPENSSL_cleanse(pre, sizeof *pre); + OPENSSL_free(pre); +} + +/******************************************************************************/ +/* + * OPENSSL EC_METHOD FUNCTIONS + */ + +int ec_GFp_nistp224_group_init(EC_GROUP *group) +{ + int ret; + ret = ec_GFp_simple_group_init(group); + group->a_is_minus3 = 1; + return ret; +} + +int ec_GFp_nistp224_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *curve_p, *curve_a, *curve_b; + + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((curve_p = BN_CTX_get(ctx)) == NULL) || + ((curve_a = BN_CTX_get(ctx)) == NULL) || + ((curve_b = BN_CTX_get(ctx)) == NULL)) + goto err; + BN_bin2bn(nistp224_curve_params[0], sizeof(felem_bytearray), curve_p); + BN_bin2bn(nistp224_curve_params[1], sizeof(felem_bytearray), curve_a); + BN_bin2bn(nistp224_curve_params[2], sizeof(felem_bytearray), curve_b); + if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) { + ECerr(EC_F_EC_GFP_NISTP224_GROUP_SET_CURVE, + EC_R_WRONG_CURVE_PARAMETERS); + goto err; + } + group->field_mod_func = BN_nist_mod_224; + ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +/* + * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = + * (X/Z^2, Y/Z^3) + */ +int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) +{ + felem z1, z2, x_in, y_in, x_out, y_out; + widefelem tmp; + + if (EC_POINT_is_at_infinity(group, point)) { + ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, + EC_R_POINT_AT_INFINITY); + return 0; + } + if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) || + (!BN_to_felem(z1, &point->Z))) + return 0; + felem_inv(z2, z1); + felem_square(tmp, z2); + felem_reduce(z1, tmp); + felem_mul(tmp, x_in, z1); + felem_reduce(x_in, tmp); + felem_contract(x_out, x_in); + if (x != NULL) { + if (!felem_to_BN(x, x_out)) { + ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, + ERR_R_BN_LIB); + return 0; + } + } + felem_mul(tmp, z1, z2); + felem_reduce(z1, tmp); + felem_mul(tmp, y_in, z1); + felem_reduce(y_in, tmp); + felem_contract(y_out, y_in); + if (y != NULL) { + if (!felem_to_BN(y, y_out)) { + ECerr(EC_F_EC_GFP_NISTP224_POINT_GET_AFFINE_COORDINATES, + ERR_R_BN_LIB); + return 0; + } + } + return 1; +} + +static void make_points_affine(size_t num, felem points[ /* num */ ][3], + felem tmp_felems[ /* num+1 */ ]) +{ + /* + * Runs in constant time, unless an input is the point at infinity (which + * normally shouldn't happen). + */ + ec_GFp_nistp_points_make_affine_internal(num, + points, + sizeof(felem), + tmp_felems, + (void (*)(void *))felem_one, + (int (*)(const void *)) + felem_is_zero_int, + (void (*)(void *, const void *)) + felem_assign, + (void (*)(void *, const void *)) + felem_square_reduce, (void (*) + (void *, + const void + *, + const void + *)) + felem_mul_reduce, + (void (*)(void *, const void *)) + felem_inv, + (void (*)(void *, const void *)) + felem_contract); +} + +/* + * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL + * values Result is stored in r (r can equal one of the inputs). + */ +int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx) +{ + int ret = 0; + int j; + unsigned i; + int mixed = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y, *z, *tmp_scalar; + felem_bytearray g_secret; + felem_bytearray *secrets = NULL; + felem(*pre_comp)[17][3] = NULL; + felem *tmp_felems = NULL; + felem_bytearray tmp; + unsigned num_bytes; + int have_pre_comp = 0; + size_t num_points = num; + felem x_in, y_in, z_in, x_out, y_out, z_out; + NISTP224_PRE_COMP *pre = NULL; + const felem(*g_pre_comp)[16][3] = NULL; + EC_POINT *generator = NULL; + const EC_POINT *p = NULL; + const BIGNUM *p_scalar = NULL; + + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((x = BN_CTX_get(ctx)) == NULL) || + ((y = BN_CTX_get(ctx)) == NULL) || + ((z = BN_CTX_get(ctx)) == NULL) || + ((tmp_scalar = BN_CTX_get(ctx)) == NULL)) + goto err; + + if (scalar != NULL) { + pre = EC_EX_DATA_get_data(group->extra_data, + nistp224_pre_comp_dup, + nistp224_pre_comp_free, + nistp224_pre_comp_clear_free); + if (pre) + /* we have precomputation, try to use it */ + g_pre_comp = (const felem(*)[16][3])pre->g_pre_comp; + else + /* try to use the standard precomputation */ + g_pre_comp = &gmul[0]; + generator = EC_POINT_new(group); + if (generator == NULL) + goto err; + /* get the generator from precomputation */ + if (!felem_to_BN(x, g_pre_comp[0][1][0]) || + !felem_to_BN(y, g_pre_comp[0][1][1]) || + !felem_to_BN(z, g_pre_comp[0][1][2])) { + ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + if (!EC_POINT_set_Jprojective_coordinates_GFp(group, + generator, x, y, z, + ctx)) + goto err; + if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) + /* precomputation matches generator */ + have_pre_comp = 1; + else + /* + * we don't have valid precomputation: treat the generator as a + * random point + */ + num_points = num_points + 1; + } + + if (num_points > 0) { + if (num_points >= 3) { + /* + * unless we precompute multiples for just one or two points, + * converting those into affine form is time well spent + */ + mixed = 1; + } + secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray)); + pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem)); + if (mixed) + tmp_felems = + OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem)); + if ((secrets == NULL) || (pre_comp == NULL) + || (mixed && (tmp_felems == NULL))) { + ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * we treat NULL scalars as 0, and NULL points as points at infinity, + * i.e., they contribute nothing to the linear combination + */ + memset(secrets, 0, num_points * sizeof(felem_bytearray)); + memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem)); + for (i = 0; i < num_points; ++i) { + if (i == num) + /* the generator */ + { + p = EC_GROUP_get0_generator(group); + p_scalar = scalar; + } else + /* the i^th point */ + { + p = points[i]; + p_scalar = scalars[i]; + } + if ((p_scalar != NULL) && (p != NULL)) { + /* reduce scalar to 0 <= scalar < 2^224 */ + if ((BN_num_bits(p_scalar) > 224) + || (BN_is_negative(p_scalar))) { + /* + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) { + ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + num_bytes = BN_bn2bin(tmp_scalar, tmp); + } else + num_bytes = BN_bn2bin(p_scalar, tmp); + flip_endian(secrets[i], tmp, num_bytes); + /* precompute multiples */ + if ((!BN_to_felem(x_out, &p->X)) || + (!BN_to_felem(y_out, &p->Y)) || + (!BN_to_felem(z_out, &p->Z))) + goto err; + felem_assign(pre_comp[i][1][0], x_out); + felem_assign(pre_comp[i][1][1], y_out); + felem_assign(pre_comp[i][1][2], z_out); + for (j = 2; j <= 16; ++j) { + if (j & 1) { + point_add(pre_comp[i][j][0], pre_comp[i][j][1], + pre_comp[i][j][2], pre_comp[i][1][0], + pre_comp[i][1][1], pre_comp[i][1][2], 0, + pre_comp[i][j - 1][0], + pre_comp[i][j - 1][1], + pre_comp[i][j - 1][2]); + } else { + point_double(pre_comp[i][j][0], pre_comp[i][j][1], + pre_comp[i][j][2], pre_comp[i][j / 2][0], + pre_comp[i][j / 2][1], + pre_comp[i][j / 2][2]); + } + } + } + } + if (mixed) + make_points_affine(num_points * 17, pre_comp[0], tmp_felems); + } + + /* the scalar for the generator */ + if ((scalar != NULL) && (have_pre_comp)) { + memset(g_secret, 0, sizeof g_secret); + /* reduce scalar to 0 <= scalar < 2^224 */ + if ((BN_num_bits(scalar) > 224) || (BN_is_negative(scalar))) { + /* + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) { + ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + num_bytes = BN_bn2bin(tmp_scalar, tmp); + } else + num_bytes = BN_bn2bin(scalar, tmp); + flip_endian(g_secret, tmp, num_bytes); + /* do the multiplication with generator precomputation */ + batch_mul(x_out, y_out, z_out, + (const felem_bytearray(*))secrets, num_points, + g_secret, + mixed, (const felem(*)[17][3])pre_comp, g_pre_comp); + } else + /* do the multiplication without generator precomputation */ + batch_mul(x_out, y_out, z_out, + (const felem_bytearray(*))secrets, num_points, + NULL, mixed, (const felem(*)[17][3])pre_comp, NULL); + /* reduce the output to its unique minimal representation */ + felem_contract(x_in, x_out); + felem_contract(y_in, y_out); + felem_contract(z_in, z_out); + if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) || + (!felem_to_BN(z, z_in))) { + ECerr(EC_F_EC_GFP_NISTP224_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx); + + err: + BN_CTX_end(ctx); + if (generator != NULL) + EC_POINT_free(generator); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (secrets != NULL) + OPENSSL_free(secrets); + if (pre_comp != NULL) + OPENSSL_free(pre_comp); + if (tmp_felems != NULL) + OPENSSL_free(tmp_felems); + return ret; +} + +int ec_GFp_nistp224_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +{ + int ret = 0; + NISTP224_PRE_COMP *pre = NULL; + int i, j; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y; + EC_POINT *generator = NULL; + felem tmp_felems[32]; + + /* throw away old precomputation */ + EC_EX_DATA_free_data(&group->extra_data, nistp224_pre_comp_dup, + nistp224_pre_comp_free, + nistp224_pre_comp_clear_free); + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL)) + goto err; + /* get the generator */ + if (group->generator == NULL) + goto err; + generator = EC_POINT_new(group); + if (generator == NULL) + goto err; + BN_bin2bn(nistp224_curve_params[3], sizeof(felem_bytearray), x); + BN_bin2bn(nistp224_curve_params[4], sizeof(felem_bytearray), y); + if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx)) + goto err; + if ((pre = nistp224_pre_comp_new()) == NULL) + goto err; + /* + * if the generator is the standard one, use built-in precomputation + */ + if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) { + memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp)); + ret = 1; + goto err; + } + if ((!BN_to_felem(pre->g_pre_comp[0][1][0], &group->generator->X)) || + (!BN_to_felem(pre->g_pre_comp[0][1][1], &group->generator->Y)) || + (!BN_to_felem(pre->g_pre_comp[0][1][2], &group->generator->Z))) + goto err; + /* + * compute 2^56*G, 2^112*G, 2^168*G for the first table, 2^28*G, 2^84*G, + * 2^140*G, 2^196*G for the second one + */ + for (i = 1; i <= 8; i <<= 1) { + point_double(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], + pre->g_pre_comp[1][i][2], pre->g_pre_comp[0][i][0], + pre->g_pre_comp[0][i][1], pre->g_pre_comp[0][i][2]); + for (j = 0; j < 27; ++j) { + point_double(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], + pre->g_pre_comp[1][i][2], pre->g_pre_comp[1][i][0], + pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]); + } + if (i == 8) + break; + point_double(pre->g_pre_comp[0][2 * i][0], + pre->g_pre_comp[0][2 * i][1], + pre->g_pre_comp[0][2 * i][2], pre->g_pre_comp[1][i][0], + pre->g_pre_comp[1][i][1], pre->g_pre_comp[1][i][2]); + for (j = 0; j < 27; ++j) { + point_double(pre->g_pre_comp[0][2 * i][0], + pre->g_pre_comp[0][2 * i][1], + pre->g_pre_comp[0][2 * i][2], + pre->g_pre_comp[0][2 * i][0], + pre->g_pre_comp[0][2 * i][1], + pre->g_pre_comp[0][2 * i][2]); + } + } + for (i = 0; i < 2; i++) { + /* g_pre_comp[i][0] is the point at infinity */ + memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0])); + /* the remaining multiples */ + /* 2^56*G + 2^112*G resp. 2^84*G + 2^140*G */ + point_add(pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1], + pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0], + pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2], + 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], + pre->g_pre_comp[i][2][2]); + /* 2^56*G + 2^168*G resp. 2^84*G + 2^196*G */ + point_add(pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1], + pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0], + pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2], + 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], + pre->g_pre_comp[i][2][2]); + /* 2^112*G + 2^168*G resp. 2^140*G + 2^196*G */ + point_add(pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1], + pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0], + pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2], + 0, pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1], + pre->g_pre_comp[i][4][2]); + /* + * 2^56*G + 2^112*G + 2^168*G resp. 2^84*G + 2^140*G + 2^196*G + */ + point_add(pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1], + pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0], + pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2], + 0, pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], + pre->g_pre_comp[i][2][2]); + for (j = 1; j < 8; ++j) { + /* odd multiples: add G resp. 2^28*G */ + point_add(pre->g_pre_comp[i][2 * j + 1][0], + pre->g_pre_comp[i][2 * j + 1][1], + pre->g_pre_comp[i][2 * j + 1][2], + pre->g_pre_comp[i][2 * j][0], + pre->g_pre_comp[i][2 * j][1], + pre->g_pre_comp[i][2 * j][2], 0, + pre->g_pre_comp[i][1][0], pre->g_pre_comp[i][1][1], + pre->g_pre_comp[i][1][2]); + } + } + make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_felems); + + if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp224_pre_comp_dup, + nistp224_pre_comp_free, + nistp224_pre_comp_clear_free)) + goto err; + ret = 1; + pre = NULL; + err: + BN_CTX_end(ctx); + if (generator != NULL) + EC_POINT_free(generator); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (pre) + nistp224_pre_comp_free(pre); + return ret; +} + +int ec_GFp_nistp224_have_precompute_mult(const EC_GROUP *group) +{ + if (EC_EX_DATA_get_data(group->extra_data, nistp224_pre_comp_dup, + nistp224_pre_comp_free, + nistp224_pre_comp_clear_free) + != NULL) + return 1; + else + return 0; +} + +#else +static void *dummy = &dummy; +#endif diff --git a/libs/openssl/crypto/ec/ecp_nistp256.c b/libs/openssl/crypto/ec/ecp_nistp256.c new file mode 100644 index 00000000..a5887086 --- /dev/null +++ b/libs/openssl/crypto/ec/ecp_nistp256.c @@ -0,0 +1,2369 @@ +/* crypto/ec/ecp_nistp256.c */ +/* + * Written by Adam Langley (Google) for the OpenSSL project + */ +/* Copyright 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * A 64-bit implementation of the NIST P-256 elliptic curve point multiplication + * + * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c. + * Otherwise based on Emilia's P224 work, which was inspired by my curve25519 + * work which got its smarts from Daniel J. Bernstein's work on the same. + */ + +#include +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + +# ifndef OPENSSL_SYS_VMS +# include +# else +# include +# endif + +# include +# include +# include "ec_lcl.h" + +# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) + /* even with gcc, the typedef won't work for 32-bit platforms */ +typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit + * platforms */ +typedef __int128_t int128_t; +# else +# error "Need GCC 3.1 or later to define type uint128_t" +# endif + +typedef uint8_t u8; +typedef uint32_t u32; +typedef uint64_t u64; +typedef int64_t s64; + +/* + * The underlying field. P256 operates over GF(2^256-2^224+2^192+2^96-1). We + * can serialise an element of this field into 32 bytes. We call this an + * felem_bytearray. + */ + +typedef u8 felem_bytearray[32]; + +/* + * These are the parameters of P256, taken from FIPS 186-3, page 86. These + * values are big-endian. + */ +static const felem_bytearray nistp256_curve_params[5] = { + {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* p */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, /* a = -3 */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc}, /* b */ + {0x5a, 0xc6, 0x35, 0xd8, 0xaa, 0x3a, 0x93, 0xe7, + 0xb3, 0xeb, 0xbd, 0x55, 0x76, 0x98, 0x86, 0xbc, + 0x65, 0x1d, 0x06, 0xb0, 0xcc, 0x53, 0xb0, 0xf6, + 0x3b, 0xce, 0x3c, 0x3e, 0x27, 0xd2, 0x60, 0x4b}, + {0x6b, 0x17, 0xd1, 0xf2, 0xe1, 0x2c, 0x42, 0x47, /* x */ + 0xf8, 0xbc, 0xe6, 0xe5, 0x63, 0xa4, 0x40, 0xf2, + 0x77, 0x03, 0x7d, 0x81, 0x2d, 0xeb, 0x33, 0xa0, + 0xf4, 0xa1, 0x39, 0x45, 0xd8, 0x98, 0xc2, 0x96}, + {0x4f, 0xe3, 0x42, 0xe2, 0xfe, 0x1a, 0x7f, 0x9b, /* y */ + 0x8e, 0xe7, 0xeb, 0x4a, 0x7c, 0x0f, 0x9e, 0x16, + 0x2b, 0xce, 0x33, 0x57, 0x6b, 0x31, 0x5e, 0xce, + 0xcb, 0xb6, 0x40, 0x68, 0x37, 0xbf, 0x51, 0xf5} +}; + +/*- + * The representation of field elements. + * ------------------------------------ + * + * We represent field elements with either four 128-bit values, eight 128-bit + * values, or four 64-bit values. The field element represented is: + * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + v[3]*2^192 (mod p) + * or: + * v[0]*2^0 + v[1]*2^64 + v[2]*2^128 + ... + v[8]*2^512 (mod p) + * + * 128-bit values are called 'limbs'. Since the limbs are spaced only 64 bits + * apart, but are 128-bits wide, the most significant bits of each limb overlap + * with the least significant bits of the next. + * + * A field element with four limbs is an 'felem'. One with eight limbs is a + * 'longfelem' + * + * A field element with four, 64-bit values is called a 'smallfelem'. Small + * values are used as intermediate values before multiplication. + */ + +# define NLIMBS 4 + +typedef uint128_t limb; +typedef limb felem[NLIMBS]; +typedef limb longfelem[NLIMBS * 2]; +typedef u64 smallfelem[NLIMBS]; + +/* This is the value of the prime as four 64-bit words, little-endian. */ +static const u64 kPrime[4] = + { 0xfffffffffffffffful, 0xffffffff, 0, 0xffffffff00000001ul }; +static const u64 bottom63bits = 0x7ffffffffffffffful; + +/* + * bin32_to_felem takes a little-endian byte array and converts it into felem + * form. This assumes that the CPU is little-endian. + */ +static void bin32_to_felem(felem out, const u8 in[32]) +{ + out[0] = *((u64 *)&in[0]); + out[1] = *((u64 *)&in[8]); + out[2] = *((u64 *)&in[16]); + out[3] = *((u64 *)&in[24]); +} + +/* + * smallfelem_to_bin32 takes a smallfelem and serialises into a little + * endian, 32 byte array. This assumes that the CPU is little-endian. + */ +static void smallfelem_to_bin32(u8 out[32], const smallfelem in) +{ + *((u64 *)&out[0]) = in[0]; + *((u64 *)&out[8]) = in[1]; + *((u64 *)&out[16]) = in[2]; + *((u64 *)&out[24]) = in[3]; +} + +/* To preserve endianness when using BN_bn2bin and BN_bin2bn */ +static void flip_endian(u8 *out, const u8 *in, unsigned len) +{ + unsigned i; + for (i = 0; i < len; ++i) + out[i] = in[len - 1 - i]; +} + +/* BN_to_felem converts an OpenSSL BIGNUM into an felem */ +static int BN_to_felem(felem out, const BIGNUM *bn) +{ + felem_bytearray b_in; + felem_bytearray b_out; + unsigned num_bytes; + + /* BN_bn2bin eats leading zeroes */ + memset(b_out, 0, sizeof b_out); + num_bytes = BN_num_bytes(bn); + if (num_bytes > sizeof b_out) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + if (BN_is_negative(bn)) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + num_bytes = BN_bn2bin(bn, b_in); + flip_endian(b_out, b_in, num_bytes); + bin32_to_felem(out, b_out); + return 1; +} + +/* felem_to_BN converts an felem into an OpenSSL BIGNUM */ +static BIGNUM *smallfelem_to_BN(BIGNUM *out, const smallfelem in) +{ + felem_bytearray b_in, b_out; + smallfelem_to_bin32(b_in, in); + flip_endian(b_out, b_in, sizeof b_out); + return BN_bin2bn(b_out, sizeof b_out, out); +} + +/*- + * Field operations + * ---------------- + */ + +static void smallfelem_one(smallfelem out) +{ + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; +} + +static void smallfelem_assign(smallfelem out, const smallfelem in) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; +} + +static void felem_assign(felem out, const felem in) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; +} + +/* felem_sum sets out = out + in. */ +static void felem_sum(felem out, const felem in) +{ + out[0] += in[0]; + out[1] += in[1]; + out[2] += in[2]; + out[3] += in[3]; +} + +/* felem_small_sum sets out = out + in. */ +static void felem_small_sum(felem out, const smallfelem in) +{ + out[0] += in[0]; + out[1] += in[1]; + out[2] += in[2]; + out[3] += in[3]; +} + +/* felem_scalar sets out = out * scalar */ +static void felem_scalar(felem out, const u64 scalar) +{ + out[0] *= scalar; + out[1] *= scalar; + out[2] *= scalar; + out[3] *= scalar; +} + +/* longfelem_scalar sets out = out * scalar */ +static void longfelem_scalar(longfelem out, const u64 scalar) +{ + out[0] *= scalar; + out[1] *= scalar; + out[2] *= scalar; + out[3] *= scalar; + out[4] *= scalar; + out[5] *= scalar; + out[6] *= scalar; + out[7] *= scalar; +} + +# define two105m41m9 (((limb)1) << 105) - (((limb)1) << 41) - (((limb)1) << 9) +# define two105 (((limb)1) << 105) +# define two105m41p9 (((limb)1) << 105) - (((limb)1) << 41) + (((limb)1) << 9) + +/* zero105 is 0 mod p */ +static const felem zero105 = + { two105m41m9, two105, two105m41p9, two105m41p9 }; + +/*- + * smallfelem_neg sets |out| to |-small| + * On exit: + * out[i] < out[i] + 2^105 + */ +static void smallfelem_neg(felem out, const smallfelem small) +{ + /* In order to prevent underflow, we subtract from 0 mod p. */ + out[0] = zero105[0] - small[0]; + out[1] = zero105[1] - small[1]; + out[2] = zero105[2] - small[2]; + out[3] = zero105[3] - small[3]; +} + +/*- + * felem_diff subtracts |in| from |out| + * On entry: + * in[i] < 2^104 + * On exit: + * out[i] < out[i] + 2^105 + */ +static void felem_diff(felem out, const felem in) +{ + /* + * In order to prevent underflow, we add 0 mod p before subtracting. + */ + out[0] += zero105[0]; + out[1] += zero105[1]; + out[2] += zero105[2]; + out[3] += zero105[3]; + + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; +} + +# define two107m43m11 (((limb)1) << 107) - (((limb)1) << 43) - (((limb)1) << 11) +# define two107 (((limb)1) << 107) +# define two107m43p11 (((limb)1) << 107) - (((limb)1) << 43) + (((limb)1) << 11) + +/* zero107 is 0 mod p */ +static const felem zero107 = + { two107m43m11, two107, two107m43p11, two107m43p11 }; + +/*- + * An alternative felem_diff for larger inputs |in| + * felem_diff_zero107 subtracts |in| from |out| + * On entry: + * in[i] < 2^106 + * On exit: + * out[i] < out[i] + 2^107 + */ +static void felem_diff_zero107(felem out, const felem in) +{ + /* + * In order to prevent underflow, we add 0 mod p before subtracting. + */ + out[0] += zero107[0]; + out[1] += zero107[1]; + out[2] += zero107[2]; + out[3] += zero107[3]; + + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; +} + +/*- + * longfelem_diff subtracts |in| from |out| + * On entry: + * in[i] < 7*2^67 + * On exit: + * out[i] < out[i] + 2^70 + 2^40 + */ +static void longfelem_diff(longfelem out, const longfelem in) +{ + static const limb two70m8p6 = + (((limb) 1) << 70) - (((limb) 1) << 8) + (((limb) 1) << 6); + static const limb two70p40 = (((limb) 1) << 70) + (((limb) 1) << 40); + static const limb two70 = (((limb) 1) << 70); + static const limb two70m40m38p6 = + (((limb) 1) << 70) - (((limb) 1) << 40) - (((limb) 1) << 38) + + (((limb) 1) << 6); + static const limb two70m6 = (((limb) 1) << 70) - (((limb) 1) << 6); + + /* add 0 mod p to avoid underflow */ + out[0] += two70m8p6; + out[1] += two70p40; + out[2] += two70; + out[3] += two70m40m38p6; + out[4] += two70m6; + out[5] += two70m6; + out[6] += two70m6; + out[7] += two70m6; + + /* in[i] < 7*2^67 < 2^70 - 2^40 - 2^38 + 2^6 */ + out[0] -= in[0]; + out[1] -= in[1]; + out[2] -= in[2]; + out[3] -= in[3]; + out[4] -= in[4]; + out[5] -= in[5]; + out[6] -= in[6]; + out[7] -= in[7]; +} + +# define two64m0 (((limb)1) << 64) - 1 +# define two110p32m0 (((limb)1) << 110) + (((limb)1) << 32) - 1 +# define two64m46 (((limb)1) << 64) - (((limb)1) << 46) +# define two64m32 (((limb)1) << 64) - (((limb)1) << 32) + +/* zero110 is 0 mod p */ +static const felem zero110 = { two64m0, two110p32m0, two64m46, two64m32 }; + +/*- + * felem_shrink converts an felem into a smallfelem. The result isn't quite + * minimal as the value may be greater than p. + * + * On entry: + * in[i] < 2^109 + * On exit: + * out[i] < 2^64 + */ +static void felem_shrink(smallfelem out, const felem in) +{ + felem tmp; + u64 a, b, mask; + s64 high, low; + static const u64 kPrime3Test = 0x7fffffff00000001ul; /* 2^63 - 2^32 + 1 */ + + /* Carry 2->3 */ + tmp[3] = zero110[3] + in[3] + ((u64)(in[2] >> 64)); + /* tmp[3] < 2^110 */ + + tmp[2] = zero110[2] + (u64)in[2]; + tmp[0] = zero110[0] + in[0]; + tmp[1] = zero110[1] + in[1]; + /* tmp[0] < 2**110, tmp[1] < 2^111, tmp[2] < 2**65 */ + + /* + * We perform two partial reductions where we eliminate the high-word of + * tmp[3]. We don't update the other words till the end. + */ + a = tmp[3] >> 64; /* a < 2^46 */ + tmp[3] = (u64)tmp[3]; + tmp[3] -= a; + tmp[3] += ((limb) a) << 32; + /* tmp[3] < 2^79 */ + + b = a; + a = tmp[3] >> 64; /* a < 2^15 */ + b += a; /* b < 2^46 + 2^15 < 2^47 */ + tmp[3] = (u64)tmp[3]; + tmp[3] -= a; + tmp[3] += ((limb) a) << 32; + /* tmp[3] < 2^64 + 2^47 */ + + /* + * This adjusts the other two words to complete the two partial + * reductions. + */ + tmp[0] += b; + tmp[1] -= (((limb) b) << 32); + + /* + * In order to make space in tmp[3] for the carry from 2 -> 3, we + * conditionally subtract kPrime if tmp[3] is large enough. + */ + high = tmp[3] >> 64; + /* As tmp[3] < 2^65, high is either 1 or 0 */ + high <<= 63; + high >>= 63; + /*- + * high is: + * all ones if the high word of tmp[3] is 1 + * all zeros if the high word of tmp[3] if 0 */ + low = tmp[3]; + mask = low >> 63; + /*- + * mask is: + * all ones if the MSB of low is 1 + * all zeros if the MSB of low if 0 */ + low &= bottom63bits; + low -= kPrime3Test; + /* if low was greater than kPrime3Test then the MSB is zero */ + low = ~low; + low >>= 63; + /*- + * low is: + * all ones if low was > kPrime3Test + * all zeros if low was <= kPrime3Test */ + mask = (mask & low) | high; + tmp[0] -= mask & kPrime[0]; + tmp[1] -= mask & kPrime[1]; + /* kPrime[2] is zero, so omitted */ + tmp[3] -= mask & kPrime[3]; + /* tmp[3] < 2**64 - 2**32 + 1 */ + + tmp[1] += ((u64)(tmp[0] >> 64)); + tmp[0] = (u64)tmp[0]; + tmp[2] += ((u64)(tmp[1] >> 64)); + tmp[1] = (u64)tmp[1]; + tmp[3] += ((u64)(tmp[2] >> 64)); + tmp[2] = (u64)tmp[2]; + /* tmp[i] < 2^64 */ + + out[0] = tmp[0]; + out[1] = tmp[1]; + out[2] = tmp[2]; + out[3] = tmp[3]; +} + +/* smallfelem_expand converts a smallfelem to an felem */ +static void smallfelem_expand(felem out, const smallfelem in) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; +} + +/*- + * smallfelem_square sets |out| = |small|^2 + * On entry: + * small[i] < 2^64 + * On exit: + * out[i] < 7 * 2^64 < 2^67 + */ +static void smallfelem_square(longfelem out, const smallfelem small) +{ + limb a; + u64 high, low; + + a = ((uint128_t) small[0]) * small[0]; + low = a; + high = a >> 64; + out[0] = low; + out[1] = high; + + a = ((uint128_t) small[0]) * small[1]; + low = a; + high = a >> 64; + out[1] += low; + out[1] += low; + out[2] = high; + + a = ((uint128_t) small[0]) * small[2]; + low = a; + high = a >> 64; + out[2] += low; + out[2] *= 2; + out[3] = high; + + a = ((uint128_t) small[0]) * small[3]; + low = a; + high = a >> 64; + out[3] += low; + out[4] = high; + + a = ((uint128_t) small[1]) * small[2]; + low = a; + high = a >> 64; + out[3] += low; + out[3] *= 2; + out[4] += high; + + a = ((uint128_t) small[1]) * small[1]; + low = a; + high = a >> 64; + out[2] += low; + out[3] += high; + + a = ((uint128_t) small[1]) * small[3]; + low = a; + high = a >> 64; + out[4] += low; + out[4] *= 2; + out[5] = high; + + a = ((uint128_t) small[2]) * small[3]; + low = a; + high = a >> 64; + out[5] += low; + out[5] *= 2; + out[6] = high; + out[6] += high; + + a = ((uint128_t) small[2]) * small[2]; + low = a; + high = a >> 64; + out[4] += low; + out[5] += high; + + a = ((uint128_t) small[3]) * small[3]; + low = a; + high = a >> 64; + out[6] += low; + out[7] = high; +} + +/*- + * felem_square sets |out| = |in|^2 + * On entry: + * in[i] < 2^109 + * On exit: + * out[i] < 7 * 2^64 < 2^67 + */ +static void felem_square(longfelem out, const felem in) +{ + u64 small[4]; + felem_shrink(small, in); + smallfelem_square(out, small); +} + +/*- + * smallfelem_mul sets |out| = |small1| * |small2| + * On entry: + * small1[i] < 2^64 + * small2[i] < 2^64 + * On exit: + * out[i] < 7 * 2^64 < 2^67 + */ +static void smallfelem_mul(longfelem out, const smallfelem small1, + const smallfelem small2) +{ + limb a; + u64 high, low; + + a = ((uint128_t) small1[0]) * small2[0]; + low = a; + high = a >> 64; + out[0] = low; + out[1] = high; + + a = ((uint128_t) small1[0]) * small2[1]; + low = a; + high = a >> 64; + out[1] += low; + out[2] = high; + + a = ((uint128_t) small1[1]) * small2[0]; + low = a; + high = a >> 64; + out[1] += low; + out[2] += high; + + a = ((uint128_t) small1[0]) * small2[2]; + low = a; + high = a >> 64; + out[2] += low; + out[3] = high; + + a = ((uint128_t) small1[1]) * small2[1]; + low = a; + high = a >> 64; + out[2] += low; + out[3] += high; + + a = ((uint128_t) small1[2]) * small2[0]; + low = a; + high = a >> 64; + out[2] += low; + out[3] += high; + + a = ((uint128_t) small1[0]) * small2[3]; + low = a; + high = a >> 64; + out[3] += low; + out[4] = high; + + a = ((uint128_t) small1[1]) * small2[2]; + low = a; + high = a >> 64; + out[3] += low; + out[4] += high; + + a = ((uint128_t) small1[2]) * small2[1]; + low = a; + high = a >> 64; + out[3] += low; + out[4] += high; + + a = ((uint128_t) small1[3]) * small2[0]; + low = a; + high = a >> 64; + out[3] += low; + out[4] += high; + + a = ((uint128_t) small1[1]) * small2[3]; + low = a; + high = a >> 64; + out[4] += low; + out[5] = high; + + a = ((uint128_t) small1[2]) * small2[2]; + low = a; + high = a >> 64; + out[4] += low; + out[5] += high; + + a = ((uint128_t) small1[3]) * small2[1]; + low = a; + high = a >> 64; + out[4] += low; + out[5] += high; + + a = ((uint128_t) small1[2]) * small2[3]; + low = a; + high = a >> 64; + out[5] += low; + out[6] = high; + + a = ((uint128_t) small1[3]) * small2[2]; + low = a; + high = a >> 64; + out[5] += low; + out[6] += high; + + a = ((uint128_t) small1[3]) * small2[3]; + low = a; + high = a >> 64; + out[6] += low; + out[7] = high; +} + +/*- + * felem_mul sets |out| = |in1| * |in2| + * On entry: + * in1[i] < 2^109 + * in2[i] < 2^109 + * On exit: + * out[i] < 7 * 2^64 < 2^67 + */ +static void felem_mul(longfelem out, const felem in1, const felem in2) +{ + smallfelem small1, small2; + felem_shrink(small1, in1); + felem_shrink(small2, in2); + smallfelem_mul(out, small1, small2); +} + +/*- + * felem_small_mul sets |out| = |small1| * |in2| + * On entry: + * small1[i] < 2^64 + * in2[i] < 2^109 + * On exit: + * out[i] < 7 * 2^64 < 2^67 + */ +static void felem_small_mul(longfelem out, const smallfelem small1, + const felem in2) +{ + smallfelem small2; + felem_shrink(small2, in2); + smallfelem_mul(out, small1, small2); +} + +# define two100m36m4 (((limb)1) << 100) - (((limb)1) << 36) - (((limb)1) << 4) +# define two100 (((limb)1) << 100) +# define two100m36p4 (((limb)1) << 100) - (((limb)1) << 36) + (((limb)1) << 4) +/* zero100 is 0 mod p */ +static const felem zero100 = + { two100m36m4, two100, two100m36p4, two100m36p4 }; + +/*- + * Internal function for the different flavours of felem_reduce. + * felem_reduce_ reduces the higher coefficients in[4]-in[7]. + * On entry: + * out[0] >= in[6] + 2^32*in[6] + in[7] + 2^32*in[7] + * out[1] >= in[7] + 2^32*in[4] + * out[2] >= in[5] + 2^32*in[5] + * out[3] >= in[4] + 2^32*in[5] + 2^32*in[6] + * On exit: + * out[0] <= out[0] + in[4] + 2^32*in[5] + * out[1] <= out[1] + in[5] + 2^33*in[6] + * out[2] <= out[2] + in[7] + 2*in[6] + 2^33*in[7] + * out[3] <= out[3] + 2^32*in[4] + 3*in[7] + */ +static void felem_reduce_(felem out, const longfelem in) +{ + int128_t c; + /* combine common terms from below */ + c = in[4] + (in[5] << 32); + out[0] += c; + out[3] -= c; + + c = in[5] - in[7]; + out[1] += c; + out[2] -= c; + + /* the remaining terms */ + /* 256: [(0,1),(96,-1),(192,-1),(224,1)] */ + out[1] -= (in[4] << 32); + out[3] += (in[4] << 32); + + /* 320: [(32,1),(64,1),(128,-1),(160,-1),(224,-1)] */ + out[2] -= (in[5] << 32); + + /* 384: [(0,-1),(32,-1),(96,2),(128,2),(224,-1)] */ + out[0] -= in[6]; + out[0] -= (in[6] << 32); + out[1] += (in[6] << 33); + out[2] += (in[6] * 2); + out[3] -= (in[6] << 32); + + /* 448: [(0,-1),(32,-1),(64,-1),(128,1),(160,2),(192,3)] */ + out[0] -= in[7]; + out[0] -= (in[7] << 32); + out[2] += (in[7] << 33); + out[3] += (in[7] * 3); +} + +/*- + * felem_reduce converts a longfelem into an felem. + * To be called directly after felem_square or felem_mul. + * On entry: + * in[0] < 2^64, in[1] < 3*2^64, in[2] < 5*2^64, in[3] < 7*2^64 + * in[4] < 7*2^64, in[5] < 5*2^64, in[6] < 3*2^64, in[7] < 2*64 + * On exit: + * out[i] < 2^101 + */ +static void felem_reduce(felem out, const longfelem in) +{ + out[0] = zero100[0] + in[0]; + out[1] = zero100[1] + in[1]; + out[2] = zero100[2] + in[2]; + out[3] = zero100[3] + in[3]; + + felem_reduce_(out, in); + + /*- + * out[0] > 2^100 - 2^36 - 2^4 - 3*2^64 - 3*2^96 - 2^64 - 2^96 > 0 + * out[1] > 2^100 - 2^64 - 7*2^96 > 0 + * out[2] > 2^100 - 2^36 + 2^4 - 5*2^64 - 5*2^96 > 0 + * out[3] > 2^100 - 2^36 + 2^4 - 7*2^64 - 5*2^96 - 3*2^96 > 0 + * + * out[0] < 2^100 + 2^64 + 7*2^64 + 5*2^96 < 2^101 + * out[1] < 2^100 + 3*2^64 + 5*2^64 + 3*2^97 < 2^101 + * out[2] < 2^100 + 5*2^64 + 2^64 + 3*2^65 + 2^97 < 2^101 + * out[3] < 2^100 + 7*2^64 + 7*2^96 + 3*2^64 < 2^101 + */ +} + +/*- + * felem_reduce_zero105 converts a larger longfelem into an felem. + * On entry: + * in[0] < 2^71 + * On exit: + * out[i] < 2^106 + */ +static void felem_reduce_zero105(felem out, const longfelem in) +{ + out[0] = zero105[0] + in[0]; + out[1] = zero105[1] + in[1]; + out[2] = zero105[2] + in[2]; + out[3] = zero105[3] + in[3]; + + felem_reduce_(out, in); + + /*- + * out[0] > 2^105 - 2^41 - 2^9 - 2^71 - 2^103 - 2^71 - 2^103 > 0 + * out[1] > 2^105 - 2^71 - 2^103 > 0 + * out[2] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 > 0 + * out[3] > 2^105 - 2^41 + 2^9 - 2^71 - 2^103 - 2^103 > 0 + * + * out[0] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106 + * out[1] < 2^105 + 2^71 + 2^71 + 2^103 < 2^106 + * out[2] < 2^105 + 2^71 + 2^71 + 2^71 + 2^103 < 2^106 + * out[3] < 2^105 + 2^71 + 2^103 + 2^71 < 2^106 + */ +} + +/* + * subtract_u64 sets *result = *result - v and *carry to one if the + * subtraction underflowed. + */ +static void subtract_u64(u64 *result, u64 *carry, u64 v) +{ + uint128_t r = *result; + r -= v; + *carry = (r >> 64) & 1; + *result = (u64)r; +} + +/* + * felem_contract converts |in| to its unique, minimal representation. On + * entry: in[i] < 2^109 + */ +static void felem_contract(smallfelem out, const felem in) +{ + unsigned i; + u64 all_equal_so_far = 0, result = 0, carry; + + felem_shrink(out, in); + /* small is minimal except that the value might be > p */ + + all_equal_so_far--; + /* + * We are doing a constant time test if out >= kPrime. We need to compare + * each u64, from most-significant to least significant. For each one, if + * all words so far have been equal (m is all ones) then a non-equal + * result is the answer. Otherwise we continue. + */ + for (i = 3; i < 4; i--) { + u64 equal; + uint128_t a = ((uint128_t) kPrime[i]) - out[i]; + /* + * if out[i] > kPrime[i] then a will underflow and the high 64-bits + * will all be set. + */ + result |= all_equal_so_far & ((u64)(a >> 64)); + + /* + * if kPrime[i] == out[i] then |equal| will be all zeros and the + * decrement will make it all ones. + */ + equal = kPrime[i] ^ out[i]; + equal--; + equal &= equal << 32; + equal &= equal << 16; + equal &= equal << 8; + equal &= equal << 4; + equal &= equal << 2; + equal &= equal << 1; + equal = ((s64) equal) >> 63; + + all_equal_so_far &= equal; + } + + /* + * if all_equal_so_far is still all ones then the two values are equal + * and so out >= kPrime is true. + */ + result |= all_equal_so_far; + + /* if out >= kPrime then we subtract kPrime. */ + subtract_u64(&out[0], &carry, result & kPrime[0]); + subtract_u64(&out[1], &carry, carry); + subtract_u64(&out[2], &carry, carry); + subtract_u64(&out[3], &carry, carry); + + subtract_u64(&out[1], &carry, result & kPrime[1]); + subtract_u64(&out[2], &carry, carry); + subtract_u64(&out[3], &carry, carry); + + subtract_u64(&out[2], &carry, result & kPrime[2]); + subtract_u64(&out[3], &carry, carry); + + subtract_u64(&out[3], &carry, result & kPrime[3]); +} + +static void smallfelem_square_contract(smallfelem out, const smallfelem in) +{ + longfelem longtmp; + felem tmp; + + smallfelem_square(longtmp, in); + felem_reduce(tmp, longtmp); + felem_contract(out, tmp); +} + +static void smallfelem_mul_contract(smallfelem out, const smallfelem in1, + const smallfelem in2) +{ + longfelem longtmp; + felem tmp; + + smallfelem_mul(longtmp, in1, in2); + felem_reduce(tmp, longtmp); + felem_contract(out, tmp); +} + +/*- + * felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0 + * otherwise. + * On entry: + * small[i] < 2^64 + */ +static limb smallfelem_is_zero(const smallfelem small) +{ + limb result; + u64 is_p; + + u64 is_zero = small[0] | small[1] | small[2] | small[3]; + is_zero--; + is_zero &= is_zero << 32; + is_zero &= is_zero << 16; + is_zero &= is_zero << 8; + is_zero &= is_zero << 4; + is_zero &= is_zero << 2; + is_zero &= is_zero << 1; + is_zero = ((s64) is_zero) >> 63; + + is_p = (small[0] ^ kPrime[0]) | + (small[1] ^ kPrime[1]) | + (small[2] ^ kPrime[2]) | (small[3] ^ kPrime[3]); + is_p--; + is_p &= is_p << 32; + is_p &= is_p << 16; + is_p &= is_p << 8; + is_p &= is_p << 4; + is_p &= is_p << 2; + is_p &= is_p << 1; + is_p = ((s64) is_p) >> 63; + + is_zero |= is_p; + + result = is_zero; + result |= ((limb) is_zero) << 64; + return result; +} + +static int smallfelem_is_zero_int(const smallfelem small) +{ + return (int)(smallfelem_is_zero(small) & ((limb) 1)); +} + +/*- + * felem_inv calculates |out| = |in|^{-1} + * + * Based on Fermat's Little Theorem: + * a^p = a (mod p) + * a^{p-1} = 1 (mod p) + * a^{p-2} = a^{-1} (mod p) + */ +static void felem_inv(felem out, const felem in) +{ + felem ftmp, ftmp2; + /* each e_I will hold |in|^{2^I - 1} */ + felem e2, e4, e8, e16, e32, e64; + longfelem tmp; + unsigned i; + + felem_square(tmp, in); + felem_reduce(ftmp, tmp); /* 2^1 */ + felem_mul(tmp, in, ftmp); + felem_reduce(ftmp, tmp); /* 2^2 - 2^0 */ + felem_assign(e2, ftmp); + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^3 - 2^1 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^4 - 2^2 */ + felem_mul(tmp, ftmp, e2); + felem_reduce(ftmp, tmp); /* 2^4 - 2^0 */ + felem_assign(e4, ftmp); + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^5 - 2^1 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^6 - 2^2 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^7 - 2^3 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^8 - 2^4 */ + felem_mul(tmp, ftmp, e4); + felem_reduce(ftmp, tmp); /* 2^8 - 2^0 */ + felem_assign(e8, ftmp); + for (i = 0; i < 8; i++) { + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); + } /* 2^16 - 2^8 */ + felem_mul(tmp, ftmp, e8); + felem_reduce(ftmp, tmp); /* 2^16 - 2^0 */ + felem_assign(e16, ftmp); + for (i = 0; i < 16; i++) { + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); + } /* 2^32 - 2^16 */ + felem_mul(tmp, ftmp, e16); + felem_reduce(ftmp, tmp); /* 2^32 - 2^0 */ + felem_assign(e32, ftmp); + for (i = 0; i < 32; i++) { + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); + } /* 2^64 - 2^32 */ + felem_assign(e64, ftmp); + felem_mul(tmp, ftmp, in); + felem_reduce(ftmp, tmp); /* 2^64 - 2^32 + 2^0 */ + for (i = 0; i < 192; i++) { + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); + } /* 2^256 - 2^224 + 2^192 */ + + felem_mul(tmp, e64, e32); + felem_reduce(ftmp2, tmp); /* 2^64 - 2^0 */ + for (i = 0; i < 16; i++) { + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); + } /* 2^80 - 2^16 */ + felem_mul(tmp, ftmp2, e16); + felem_reduce(ftmp2, tmp); /* 2^80 - 2^0 */ + for (i = 0; i < 8; i++) { + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); + } /* 2^88 - 2^8 */ + felem_mul(tmp, ftmp2, e8); + felem_reduce(ftmp2, tmp); /* 2^88 - 2^0 */ + for (i = 0; i < 4; i++) { + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); + } /* 2^92 - 2^4 */ + felem_mul(tmp, ftmp2, e4); + felem_reduce(ftmp2, tmp); /* 2^92 - 2^0 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); /* 2^93 - 2^1 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); /* 2^94 - 2^2 */ + felem_mul(tmp, ftmp2, e2); + felem_reduce(ftmp2, tmp); /* 2^94 - 2^0 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); /* 2^95 - 2^1 */ + felem_square(tmp, ftmp2); + felem_reduce(ftmp2, tmp); /* 2^96 - 2^2 */ + felem_mul(tmp, ftmp2, in); + felem_reduce(ftmp2, tmp); /* 2^96 - 3 */ + + felem_mul(tmp, ftmp2, ftmp); + felem_reduce(out, tmp); /* 2^256 - 2^224 + 2^192 + 2^96 - 3 */ +} + +static void smallfelem_inv_contract(smallfelem out, const smallfelem in) +{ + felem tmp; + + smallfelem_expand(tmp, in); + felem_inv(tmp, tmp); + felem_contract(out, tmp); +} + +/*- + * Group operations + * ---------------- + * + * Building on top of the field operations we have the operations on the + * elliptic curve group itself. Points on the curve are represented in Jacobian + * coordinates + */ + +/*- + * point_double calculates 2*(x_in, y_in, z_in) + * + * The method is taken from: + * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b + * + * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed. + * while x_out == y_in is not (maybe this works, but it's not tested). + */ +static void +point_double(felem x_out, felem y_out, felem z_out, + const felem x_in, const felem y_in, const felem z_in) +{ + longfelem tmp, tmp2; + felem delta, gamma, beta, alpha, ftmp, ftmp2; + smallfelem small1, small2; + + felem_assign(ftmp, x_in); + /* ftmp[i] < 2^106 */ + felem_assign(ftmp2, x_in); + /* ftmp2[i] < 2^106 */ + + /* delta = z^2 */ + felem_square(tmp, z_in); + felem_reduce(delta, tmp); + /* delta[i] < 2^101 */ + + /* gamma = y^2 */ + felem_square(tmp, y_in); + felem_reduce(gamma, tmp); + /* gamma[i] < 2^101 */ + felem_shrink(small1, gamma); + + /* beta = x*gamma */ + felem_small_mul(tmp, small1, x_in); + felem_reduce(beta, tmp); + /* beta[i] < 2^101 */ + + /* alpha = 3*(x-delta)*(x+delta) */ + felem_diff(ftmp, delta); + /* ftmp[i] < 2^105 + 2^106 < 2^107 */ + felem_sum(ftmp2, delta); + /* ftmp2[i] < 2^105 + 2^106 < 2^107 */ + felem_scalar(ftmp2, 3); + /* ftmp2[i] < 3 * 2^107 < 2^109 */ + felem_mul(tmp, ftmp, ftmp2); + felem_reduce(alpha, tmp); + /* alpha[i] < 2^101 */ + felem_shrink(small2, alpha); + + /* x' = alpha^2 - 8*beta */ + smallfelem_square(tmp, small2); + felem_reduce(x_out, tmp); + felem_assign(ftmp, beta); + felem_scalar(ftmp, 8); + /* ftmp[i] < 8 * 2^101 = 2^104 */ + felem_diff(x_out, ftmp); + /* x_out[i] < 2^105 + 2^101 < 2^106 */ + + /* z' = (y + z)^2 - gamma - delta */ + felem_sum(delta, gamma); + /* delta[i] < 2^101 + 2^101 = 2^102 */ + felem_assign(ftmp, y_in); + felem_sum(ftmp, z_in); + /* ftmp[i] < 2^106 + 2^106 = 2^107 */ + felem_square(tmp, ftmp); + felem_reduce(z_out, tmp); + felem_diff(z_out, delta); + /* z_out[i] < 2^105 + 2^101 < 2^106 */ + + /* y' = alpha*(4*beta - x') - 8*gamma^2 */ + felem_scalar(beta, 4); + /* beta[i] < 4 * 2^101 = 2^103 */ + felem_diff_zero107(beta, x_out); + /* beta[i] < 2^107 + 2^103 < 2^108 */ + felem_small_mul(tmp, small2, beta); + /* tmp[i] < 7 * 2^64 < 2^67 */ + smallfelem_square(tmp2, small1); + /* tmp2[i] < 7 * 2^64 */ + longfelem_scalar(tmp2, 8); + /* tmp2[i] < 8 * 7 * 2^64 = 7 * 2^67 */ + longfelem_diff(tmp, tmp2); + /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */ + felem_reduce_zero105(y_out, tmp); + /* y_out[i] < 2^106 */ +} + +/* + * point_double_small is the same as point_double, except that it operates on + * smallfelems + */ +static void +point_double_small(smallfelem x_out, smallfelem y_out, smallfelem z_out, + const smallfelem x_in, const smallfelem y_in, + const smallfelem z_in) +{ + felem felem_x_out, felem_y_out, felem_z_out; + felem felem_x_in, felem_y_in, felem_z_in; + + smallfelem_expand(felem_x_in, x_in); + smallfelem_expand(felem_y_in, y_in); + smallfelem_expand(felem_z_in, z_in); + point_double(felem_x_out, felem_y_out, felem_z_out, + felem_x_in, felem_y_in, felem_z_in); + felem_shrink(x_out, felem_x_out); + felem_shrink(y_out, felem_y_out); + felem_shrink(z_out, felem_z_out); +} + +/* copy_conditional copies in to out iff mask is all ones. */ +static void copy_conditional(felem out, const felem in, limb mask) +{ + unsigned i; + for (i = 0; i < NLIMBS; ++i) { + const limb tmp = mask & (in[i] ^ out[i]); + out[i] ^= tmp; + } +} + +/* copy_small_conditional copies in to out iff mask is all ones. */ +static void copy_small_conditional(felem out, const smallfelem in, limb mask) +{ + unsigned i; + const u64 mask64 = mask; + for (i = 0; i < NLIMBS; ++i) { + out[i] = ((limb) (in[i] & mask64)) | (out[i] & ~mask); + } +} + +/*- + * point_add calcuates (x1, y1, z1) + (x2, y2, z2) + * + * The method is taken from: + * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl, + * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity). + * + * This function includes a branch for checking whether the two input points + * are equal, (while not equal to the point at infinity). This case never + * happens during single point multiplication, so there is no timing leak for + * ECDH or ECDSA signing. + */ +static void point_add(felem x3, felem y3, felem z3, + const felem x1, const felem y1, const felem z1, + const int mixed, const smallfelem x2, + const smallfelem y2, const smallfelem z2) +{ + felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out; + longfelem tmp, tmp2; + smallfelem small1, small2, small3, small4, small5; + limb x_equal, y_equal, z1_is_zero, z2_is_zero; + + felem_shrink(small3, z1); + + z1_is_zero = smallfelem_is_zero(small3); + z2_is_zero = smallfelem_is_zero(z2); + + /* ftmp = z1z1 = z1**2 */ + smallfelem_square(tmp, small3); + felem_reduce(ftmp, tmp); + /* ftmp[i] < 2^101 */ + felem_shrink(small1, ftmp); + + if (!mixed) { + /* ftmp2 = z2z2 = z2**2 */ + smallfelem_square(tmp, z2); + felem_reduce(ftmp2, tmp); + /* ftmp2[i] < 2^101 */ + felem_shrink(small2, ftmp2); + + felem_shrink(small5, x1); + + /* u1 = ftmp3 = x1*z2z2 */ + smallfelem_mul(tmp, small5, small2); + felem_reduce(ftmp3, tmp); + /* ftmp3[i] < 2^101 */ + + /* ftmp5 = z1 + z2 */ + felem_assign(ftmp5, z1); + felem_small_sum(ftmp5, z2); + /* ftmp5[i] < 2^107 */ + + /* ftmp5 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 */ + felem_square(tmp, ftmp5); + felem_reduce(ftmp5, tmp); + /* ftmp2 = z2z2 + z1z1 */ + felem_sum(ftmp2, ftmp); + /* ftmp2[i] < 2^101 + 2^101 = 2^102 */ + felem_diff(ftmp5, ftmp2); + /* ftmp5[i] < 2^105 + 2^101 < 2^106 */ + + /* ftmp2 = z2 * z2z2 */ + smallfelem_mul(tmp, small2, z2); + felem_reduce(ftmp2, tmp); + + /* s1 = ftmp2 = y1 * z2**3 */ + felem_mul(tmp, y1, ftmp2); + felem_reduce(ftmp6, tmp); + /* ftmp6[i] < 2^101 */ + } else { + /* + * We'll assume z2 = 1 (special case z2 = 0 is handled later) + */ + + /* u1 = ftmp3 = x1*z2z2 */ + felem_assign(ftmp3, x1); + /* ftmp3[i] < 2^106 */ + + /* ftmp5 = 2z1z2 */ + felem_assign(ftmp5, z1); + felem_scalar(ftmp5, 2); + /* ftmp5[i] < 2*2^106 = 2^107 */ + + /* s1 = ftmp2 = y1 * z2**3 */ + felem_assign(ftmp6, y1); + /* ftmp6[i] < 2^106 */ + } + + /* u2 = x2*z1z1 */ + smallfelem_mul(tmp, x2, small1); + felem_reduce(ftmp4, tmp); + + /* h = ftmp4 = u2 - u1 */ + felem_diff_zero107(ftmp4, ftmp3); + /* ftmp4[i] < 2^107 + 2^101 < 2^108 */ + felem_shrink(small4, ftmp4); + + x_equal = smallfelem_is_zero(small4); + + /* z_out = ftmp5 * h */ + felem_small_mul(tmp, small4, ftmp5); + felem_reduce(z_out, tmp); + /* z_out[i] < 2^101 */ + + /* ftmp = z1 * z1z1 */ + smallfelem_mul(tmp, small1, small3); + felem_reduce(ftmp, tmp); + + /* s2 = tmp = y2 * z1**3 */ + felem_small_mul(tmp, y2, ftmp); + felem_reduce(ftmp5, tmp); + + /* r = ftmp5 = (s2 - s1)*2 */ + felem_diff_zero107(ftmp5, ftmp6); + /* ftmp5[i] < 2^107 + 2^107 = 2^108 */ + felem_scalar(ftmp5, 2); + /* ftmp5[i] < 2^109 */ + felem_shrink(small1, ftmp5); + y_equal = smallfelem_is_zero(small1); + + if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) { + point_double(x3, y3, z3, x1, y1, z1); + return; + } + + /* I = ftmp = (2h)**2 */ + felem_assign(ftmp, ftmp4); + felem_scalar(ftmp, 2); + /* ftmp[i] < 2*2^108 = 2^109 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); + + /* J = ftmp2 = h * I */ + felem_mul(tmp, ftmp4, ftmp); + felem_reduce(ftmp2, tmp); + + /* V = ftmp4 = U1 * I */ + felem_mul(tmp, ftmp3, ftmp); + felem_reduce(ftmp4, tmp); + + /* x_out = r**2 - J - 2V */ + smallfelem_square(tmp, small1); + felem_reduce(x_out, tmp); + felem_assign(ftmp3, ftmp4); + felem_scalar(ftmp4, 2); + felem_sum(ftmp4, ftmp2); + /* ftmp4[i] < 2*2^101 + 2^101 < 2^103 */ + felem_diff(x_out, ftmp4); + /* x_out[i] < 2^105 + 2^101 */ + + /* y_out = r(V-x_out) - 2 * s1 * J */ + felem_diff_zero107(ftmp3, x_out); + /* ftmp3[i] < 2^107 + 2^101 < 2^108 */ + felem_small_mul(tmp, small1, ftmp3); + felem_mul(tmp2, ftmp6, ftmp2); + longfelem_scalar(tmp2, 2); + /* tmp2[i] < 2*2^67 = 2^68 */ + longfelem_diff(tmp, tmp2); + /* tmp[i] < 2^67 + 2^70 + 2^40 < 2^71 */ + felem_reduce_zero105(y_out, tmp); + /* y_out[i] < 2^106 */ + + copy_small_conditional(x_out, x2, z1_is_zero); + copy_conditional(x_out, x1, z2_is_zero); + copy_small_conditional(y_out, y2, z1_is_zero); + copy_conditional(y_out, y1, z2_is_zero); + copy_small_conditional(z_out, z2, z1_is_zero); + copy_conditional(z_out, z1, z2_is_zero); + felem_assign(x3, x_out); + felem_assign(y3, y_out); + felem_assign(z3, z_out); +} + +/* + * point_add_small is the same as point_add, except that it operates on + * smallfelems + */ +static void point_add_small(smallfelem x3, smallfelem y3, smallfelem z3, + smallfelem x1, smallfelem y1, smallfelem z1, + smallfelem x2, smallfelem y2, smallfelem z2) +{ + felem felem_x3, felem_y3, felem_z3; + felem felem_x1, felem_y1, felem_z1; + smallfelem_expand(felem_x1, x1); + smallfelem_expand(felem_y1, y1); + smallfelem_expand(felem_z1, z1); + point_add(felem_x3, felem_y3, felem_z3, felem_x1, felem_y1, felem_z1, 0, + x2, y2, z2); + felem_shrink(x3, felem_x3); + felem_shrink(y3, felem_y3); + felem_shrink(z3, felem_z3); +} + +/*- + * Base point pre computation + * -------------------------- + * + * Two different sorts of precomputed tables are used in the following code. + * Each contain various points on the curve, where each point is three field + * elements (x, y, z). + * + * For the base point table, z is usually 1 (0 for the point at infinity). + * This table has 2 * 16 elements, starting with the following: + * index | bits | point + * ------+---------+------------------------------ + * 0 | 0 0 0 0 | 0G + * 1 | 0 0 0 1 | 1G + * 2 | 0 0 1 0 | 2^64G + * 3 | 0 0 1 1 | (2^64 + 1)G + * 4 | 0 1 0 0 | 2^128G + * 5 | 0 1 0 1 | (2^128 + 1)G + * 6 | 0 1 1 0 | (2^128 + 2^64)G + * 7 | 0 1 1 1 | (2^128 + 2^64 + 1)G + * 8 | 1 0 0 0 | 2^192G + * 9 | 1 0 0 1 | (2^192 + 1)G + * 10 | 1 0 1 0 | (2^192 + 2^64)G + * 11 | 1 0 1 1 | (2^192 + 2^64 + 1)G + * 12 | 1 1 0 0 | (2^192 + 2^128)G + * 13 | 1 1 0 1 | (2^192 + 2^128 + 1)G + * 14 | 1 1 1 0 | (2^192 + 2^128 + 2^64)G + * 15 | 1 1 1 1 | (2^192 + 2^128 + 2^64 + 1)G + * followed by a copy of this with each element multiplied by 2^32. + * + * The reason for this is so that we can clock bits into four different + * locations when doing simple scalar multiplies against the base point, + * and then another four locations using the second 16 elements. + * + * Tables for other points have table[i] = iG for i in 0 .. 16. */ + +/* gmul is the table of precomputed base points */ +static const smallfelem gmul[2][16][3] = { + {{{0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}}, + {{0xf4a13945d898c296, 0x77037d812deb33a0, 0xf8bce6e563a440f2, + 0x6b17d1f2e12c4247}, + {0xcbb6406837bf51f5, 0x2bce33576b315ece, 0x8ee7eb4a7c0f9e16, + 0x4fe342e2fe1a7f9b}, + {1, 0, 0, 0}}, + {{0x90e75cb48e14db63, 0x29493baaad651f7e, 0x8492592e326e25de, + 0x0fa822bc2811aaa5}, + {0xe41124545f462ee7, 0x34b1a65050fe82f5, 0x6f4ad4bcb3df188b, + 0xbff44ae8f5dba80d}, + {1, 0, 0, 0}}, + {{0x93391ce2097992af, 0xe96c98fd0d35f1fa, 0xb257c0de95e02789, + 0x300a4bbc89d6726f}, + {0xaa54a291c08127a0, 0x5bb1eeada9d806a5, 0x7f1ddb25ff1e3c6f, + 0x72aac7e0d09b4644}, + {1, 0, 0, 0}}, + {{0x57c84fc9d789bd85, 0xfc35ff7dc297eac3, 0xfb982fd588c6766e, + 0x447d739beedb5e67}, + {0x0c7e33c972e25b32, 0x3d349b95a7fae500, 0xe12e9d953a4aaff7, + 0x2d4825ab834131ee}, + {1, 0, 0, 0}}, + {{0x13949c932a1d367f, 0xef7fbd2b1a0a11b7, 0xddc6068bb91dfc60, + 0xef9519328a9c72ff}, + {0x196035a77376d8a8, 0x23183b0895ca1740, 0xc1ee9807022c219c, + 0x611e9fc37dbb2c9b}, + {1, 0, 0, 0}}, + {{0xcae2b1920b57f4bc, 0x2936df5ec6c9bc36, 0x7dea6482e11238bf, + 0x550663797b51f5d8}, + {0x44ffe216348a964c, 0x9fb3d576dbdefbe1, 0x0afa40018d9d50e5, + 0x157164848aecb851}, + {1, 0, 0, 0}}, + {{0xe48ecafffc5cde01, 0x7ccd84e70d715f26, 0xa2e8f483f43e4391, + 0xeb5d7745b21141ea}, + {0xcac917e2731a3479, 0x85f22cfe2844b645, 0x0990e6a158006cee, + 0xeafd72ebdbecc17b}, + {1, 0, 0, 0}}, + {{0x6cf20ffb313728be, 0x96439591a3c6b94a, 0x2736ff8344315fc5, + 0xa6d39677a7849276}, + {0xf2bab833c357f5f4, 0x824a920c2284059b, 0x66b8babd2d27ecdf, + 0x674f84749b0b8816}, + {1, 0, 0, 0}}, + {{0x2df48c04677c8a3e, 0x74e02f080203a56b, 0x31855f7db8c7fedb, + 0x4e769e7672c9ddad}, + {0xa4c36165b824bbb0, 0xfb9ae16f3b9122a5, 0x1ec0057206947281, + 0x42b99082de830663}, + {1, 0, 0, 0}}, + {{0x6ef95150dda868b9, 0xd1f89e799c0ce131, 0x7fdc1ca008a1c478, + 0x78878ef61c6ce04d}, + {0x9c62b9121fe0d976, 0x6ace570ebde08d4f, 0xde53142c12309def, + 0xb6cb3f5d7b72c321}, + {1, 0, 0, 0}}, + {{0x7f991ed2c31a3573, 0x5b82dd5bd54fb496, 0x595c5220812ffcae, + 0x0c88bc4d716b1287}, + {0x3a57bf635f48aca8, 0x7c8181f4df2564f3, 0x18d1b5b39c04e6aa, + 0xdd5ddea3f3901dc6}, + {1, 0, 0, 0}}, + {{0xe96a79fb3e72ad0c, 0x43a0a28c42ba792f, 0xefe0a423083e49f3, + 0x68f344af6b317466}, + {0xcdfe17db3fb24d4a, 0x668bfc2271f5c626, 0x604ed93c24d67ff3, + 0x31b9c405f8540a20}, + {1, 0, 0, 0}}, + {{0xd36b4789a2582e7f, 0x0d1a10144ec39c28, 0x663c62c3edbad7a0, + 0x4052bf4b6f461db9}, + {0x235a27c3188d25eb, 0xe724f33999bfcc5b, 0x862be6bd71d70cc8, + 0xfecf4d5190b0fc61}, + {1, 0, 0, 0}}, + {{0x74346c10a1d4cfac, 0xafdf5cc08526a7a4, 0x123202a8f62bff7a, + 0x1eddbae2c802e41a}, + {0x8fa0af2dd603f844, 0x36e06b7e4c701917, 0x0c45f45273db33a0, + 0x43104d86560ebcfc}, + {1, 0, 0, 0}}, + {{0x9615b5110d1d78e5, 0x66b0de3225c4744b, 0x0a4a46fb6aaf363a, + 0xb48e26b484f7a21c}, + {0x06ebb0f621a01b2d, 0xc004e4048b7b0f98, 0x64131bcdfed6f668, + 0xfac015404d4d3dab}, + {1, 0, 0, 0}}}, + {{{0, 0, 0, 0}, + {0, 0, 0, 0}, + {0, 0, 0, 0}}, + {{0x3a5a9e22185a5943, 0x1ab919365c65dfb6, 0x21656b32262c71da, + 0x7fe36b40af22af89}, + {0xd50d152c699ca101, 0x74b3d5867b8af212, 0x9f09f40407dca6f1, + 0xe697d45825b63624}, + {1, 0, 0, 0}}, + {{0xa84aa9397512218e, 0xe9a521b074ca0141, 0x57880b3a18a2e902, + 0x4a5b506612a677a6}, + {0x0beada7a4c4f3840, 0x626db15419e26d9d, 0xc42604fbe1627d40, + 0xeb13461ceac089f1}, + {1, 0, 0, 0}}, + {{0xf9faed0927a43281, 0x5e52c4144103ecbc, 0xc342967aa815c857, + 0x0781b8291c6a220a}, + {0x5a8343ceeac55f80, 0x88f80eeee54a05e3, 0x97b2a14f12916434, + 0x690cde8df0151593}, + {1, 0, 0, 0}}, + {{0xaee9c75df7f82f2a, 0x9e4c35874afdf43a, 0xf5622df437371326, + 0x8a535f566ec73617}, + {0xc5f9a0ac223094b7, 0xcde533864c8c7669, 0x37e02819085a92bf, + 0x0455c08468b08bd7}, + {1, 0, 0, 0}}, + {{0x0c0a6e2c9477b5d9, 0xf9a4bf62876dc444, 0x5050a949b6cdc279, + 0x06bada7ab77f8276}, + {0xc8b4aed1ea48dac9, 0xdebd8a4b7ea1070f, 0x427d49101366eb70, + 0x5b476dfd0e6cb18a}, + {1, 0, 0, 0}}, + {{0x7c5c3e44278c340a, 0x4d54606812d66f3b, 0x29a751b1ae23c5d8, + 0x3e29864e8a2ec908}, + {0x142d2a6626dbb850, 0xad1744c4765bd780, 0x1f150e68e322d1ed, + 0x239b90ea3dc31e7e}, + {1, 0, 0, 0}}, + {{0x78c416527a53322a, 0x305dde6709776f8e, 0xdbcab759f8862ed4, + 0x820f4dd949f72ff7}, + {0x6cc544a62b5debd4, 0x75be5d937b4e8cc4, 0x1b481b1b215c14d3, + 0x140406ec783a05ec}, + {1, 0, 0, 0}}, + {{0x6a703f10e895df07, 0xfd75f3fa01876bd8, 0xeb5b06e70ce08ffe, + 0x68f6b8542783dfee}, + {0x90c76f8a78712655, 0xcf5293d2f310bf7f, 0xfbc8044dfda45028, + 0xcbe1feba92e40ce6}, + {1, 0, 0, 0}}, + {{0xe998ceea4396e4c1, 0xfc82ef0b6acea274, 0x230f729f2250e927, + 0xd0b2f94d2f420109}, + {0x4305adddb38d4966, 0x10b838f8624c3b45, 0x7db2636658954e7a, + 0x971459828b0719e5}, + {1, 0, 0, 0}}, + {{0x4bd6b72623369fc9, 0x57f2929e53d0b876, 0xc2d5cba4f2340687, + 0x961610004a866aba}, + {0x49997bcd2e407a5e, 0x69ab197d92ddcb24, 0x2cf1f2438fe5131c, + 0x7acb9fadcee75e44}, + {1, 0, 0, 0}}, + {{0x254e839423d2d4c0, 0xf57f0c917aea685b, 0xa60d880f6f75aaea, + 0x24eb9acca333bf5b}, + {0xe3de4ccb1cda5dea, 0xfeef9341c51a6b4f, 0x743125f88bac4c4d, + 0x69f891c5acd079cc}, + {1, 0, 0, 0}}, + {{0xeee44b35702476b5, 0x7ed031a0e45c2258, 0xb422d1e7bd6f8514, + 0xe51f547c5972a107}, + {0xa25bcd6fc9cf343d, 0x8ca922ee097c184e, 0xa62f98b3a9fe9a06, + 0x1c309a2b25bb1387}, + {1, 0, 0, 0}}, + {{0x9295dbeb1967c459, 0xb00148833472c98e, 0xc504977708011828, + 0x20b87b8aa2c4e503}, + {0x3063175de057c277, 0x1bd539338fe582dd, 0x0d11adef5f69a044, + 0xf5c6fa49919776be}, + {1, 0, 0, 0}}, + {{0x8c944e760fd59e11, 0x3876cba1102fad5f, 0xa454c3fad83faa56, + 0x1ed7d1b9332010b9}, + {0xa1011a270024b889, 0x05e4d0dcac0cd344, 0x52b520f0eb6a2a24, + 0x3a2b03f03217257a}, + {1, 0, 0, 0}}, + {{0xf20fc2afdf1d043d, 0xf330240db58d5a62, 0xfc7d229ca0058c3b, + 0x15fee545c78dd9f6}, + {0x501e82885bc98cda, 0x41ef80e5d046ac04, 0x557d9f49461210fb, + 0x4ab5b6b2b8753f81}, + {1, 0, 0, 0}}} +}; + +/* + * select_point selects the |idx|th point from a precomputation table and + * copies it to out. + */ +static void select_point(const u64 idx, unsigned int size, + const smallfelem pre_comp[16][3], smallfelem out[3]) +{ + unsigned i, j; + u64 *outlimbs = &out[0][0]; + memset(outlimbs, 0, 3 * sizeof(smallfelem)); + + for (i = 0; i < size; i++) { + const u64 *inlimbs = (u64 *)&pre_comp[i][0][0]; + u64 mask = i ^ idx; + mask |= mask >> 4; + mask |= mask >> 2; + mask |= mask >> 1; + mask &= 1; + mask--; + for (j = 0; j < NLIMBS * 3; j++) + outlimbs[j] |= inlimbs[j] & mask; + } +} + +/* get_bit returns the |i|th bit in |in| */ +static char get_bit(const felem_bytearray in, int i) +{ + if ((i < 0) || (i >= 256)) + return 0; + return (in[i >> 3] >> (i & 7)) & 1; +} + +/* + * Interleaved point multiplication using precomputed point multiples: The + * small point multiples 0*P, 1*P, ..., 17*P are in pre_comp[], the scalars + * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the + * generator, using certain (large) precomputed multiples in g_pre_comp. + * Output point (X, Y, Z) is stored in x_out, y_out, z_out + */ +static void batch_mul(felem x_out, felem y_out, felem z_out, + const felem_bytearray scalars[], + const unsigned num_points, const u8 *g_scalar, + const int mixed, const smallfelem pre_comp[][17][3], + const smallfelem g_pre_comp[2][16][3]) +{ + int i, skip; + unsigned num, gen_mul = (g_scalar != NULL); + felem nq[3], ftmp; + smallfelem tmp[3]; + u64 bits; + u8 sign, digit; + + /* set nq to the point at infinity */ + memset(nq, 0, 3 * sizeof(felem)); + + /* + * Loop over all scalars msb-to-lsb, interleaving additions of multiples + * of the generator (two in each of the last 32 rounds) and additions of + * other points multiples (every 5th round). + */ + skip = 1; /* save two point operations in the first + * round */ + for (i = (num_points ? 255 : 31); i >= 0; --i) { + /* double */ + if (!skip) + point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + + /* add multiples of the generator */ + if (gen_mul && (i <= 31)) { + /* first, look 32 bits upwards */ + bits = get_bit(g_scalar, i + 224) << 3; + bits |= get_bit(g_scalar, i + 160) << 2; + bits |= get_bit(g_scalar, i + 96) << 1; + bits |= get_bit(g_scalar, i + 32); + /* select the point to add, in constant time */ + select_point(bits, 16, g_pre_comp[1], tmp); + + if (!skip) { + /* Arg 1 below is for "mixed" */ + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]); + } else { + smallfelem_expand(nq[0], tmp[0]); + smallfelem_expand(nq[1], tmp[1]); + smallfelem_expand(nq[2], tmp[2]); + skip = 0; + } + + /* second, look at the current position */ + bits = get_bit(g_scalar, i + 192) << 3; + bits |= get_bit(g_scalar, i + 128) << 2; + bits |= get_bit(g_scalar, i + 64) << 1; + bits |= get_bit(g_scalar, i); + /* select the point to add, in constant time */ + select_point(bits, 16, g_pre_comp[0], tmp); + /* Arg 1 below is for "mixed" */ + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]); + } + + /* do other additions every 5 doublings */ + if (num_points && (i % 5 == 0)) { + /* loop over all scalars */ + for (num = 0; num < num_points; ++num) { + bits = get_bit(scalars[num], i + 4) << 5; + bits |= get_bit(scalars[num], i + 3) << 4; + bits |= get_bit(scalars[num], i + 2) << 3; + bits |= get_bit(scalars[num], i + 1) << 2; + bits |= get_bit(scalars[num], i) << 1; + bits |= get_bit(scalars[num], i - 1); + ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + + /* + * select the point to add or subtract, in constant time + */ + select_point(digit, 17, pre_comp[num], tmp); + smallfelem_neg(ftmp, tmp[1]); /* (X, -Y, Z) is the negative + * point */ + copy_small_conditional(ftmp, tmp[1], (((limb) sign) - 1)); + felem_contract(tmp[1], ftmp); + + if (!skip) { + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], + mixed, tmp[0], tmp[1], tmp[2]); + } else { + smallfelem_expand(nq[0], tmp[0]); + smallfelem_expand(nq[1], tmp[1]); + smallfelem_expand(nq[2], tmp[2]); + skip = 0; + } + } + } + } + felem_assign(x_out, nq[0]); + felem_assign(y_out, nq[1]); + felem_assign(z_out, nq[2]); +} + +/* Precomputation for the group generator. */ +typedef struct { + smallfelem g_pre_comp[2][16][3]; + int references; +} NISTP256_PRE_COMP; + +const EC_METHOD *EC_GFp_nistp256_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, + ec_GFp_nistp256_group_init, + ec_GFp_simple_group_finish, + ec_GFp_simple_group_clear_finish, + ec_GFp_nist_group_copy, + ec_GFp_nistp256_group_set_curve, + ec_GFp_simple_group_get_curve, + ec_GFp_simple_group_get_degree, + ec_GFp_simple_group_check_discriminant, + ec_GFp_simple_point_init, + ec_GFp_simple_point_finish, + ec_GFp_simple_point_clear_finish, + ec_GFp_simple_point_copy, + ec_GFp_simple_point_set_to_infinity, + ec_GFp_simple_set_Jprojective_coordinates_GFp, + ec_GFp_simple_get_Jprojective_coordinates_GFp, + ec_GFp_simple_point_set_affine_coordinates, + ec_GFp_nistp256_point_get_affine_coordinates, + 0 /* point_set_compressed_coordinates */ , + 0 /* point2oct */ , + 0 /* oct2point */ , + ec_GFp_simple_add, + ec_GFp_simple_dbl, + ec_GFp_simple_invert, + ec_GFp_simple_is_at_infinity, + ec_GFp_simple_is_on_curve, + ec_GFp_simple_cmp, + ec_GFp_simple_make_affine, + ec_GFp_simple_points_make_affine, + ec_GFp_nistp256_points_mul, + ec_GFp_nistp256_precompute_mult, + ec_GFp_nistp256_have_precompute_mult, + ec_GFp_nist_field_mul, + ec_GFp_nist_field_sqr, + 0 /* field_div */ , + 0 /* field_encode */ , + 0 /* field_decode */ , + 0 /* field_set_to_one */ + }; + + return &ret; +} + +/******************************************************************************/ +/* + * FUNCTIONS TO MANAGE PRECOMPUTATION + */ + +static NISTP256_PRE_COMP *nistp256_pre_comp_new() +{ + NISTP256_PRE_COMP *ret = NULL; + ret = (NISTP256_PRE_COMP *) OPENSSL_malloc(sizeof *ret); + if (!ret) { + ECerr(EC_F_NISTP256_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + return ret; + } + memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp)); + ret->references = 1; + return ret; +} + +static void *nistp256_pre_comp_dup(void *src_) +{ + NISTP256_PRE_COMP *src = src_; + + /* no need to actually copy, these objects never change! */ + CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); + + return src_; +} + +static void nistp256_pre_comp_free(void *pre_) +{ + int i; + NISTP256_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + OPENSSL_free(pre); +} + +static void nistp256_pre_comp_clear_free(void *pre_) +{ + int i; + NISTP256_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + OPENSSL_cleanse(pre, sizeof *pre); + OPENSSL_free(pre); +} + +/******************************************************************************/ +/* + * OPENSSL EC_METHOD FUNCTIONS + */ + +int ec_GFp_nistp256_group_init(EC_GROUP *group) +{ + int ret; + ret = ec_GFp_simple_group_init(group); + group->a_is_minus3 = 1; + return ret; +} + +int ec_GFp_nistp256_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *curve_p, *curve_a, *curve_b; + + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((curve_p = BN_CTX_get(ctx)) == NULL) || + ((curve_a = BN_CTX_get(ctx)) == NULL) || + ((curve_b = BN_CTX_get(ctx)) == NULL)) + goto err; + BN_bin2bn(nistp256_curve_params[0], sizeof(felem_bytearray), curve_p); + BN_bin2bn(nistp256_curve_params[1], sizeof(felem_bytearray), curve_a); + BN_bin2bn(nistp256_curve_params[2], sizeof(felem_bytearray), curve_b); + if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) { + ECerr(EC_F_EC_GFP_NISTP256_GROUP_SET_CURVE, + EC_R_WRONG_CURVE_PARAMETERS); + goto err; + } + group->field_mod_func = BN_nist_mod_256; + ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +/* + * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = + * (X/Z^2, Y/Z^3) + */ +int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) +{ + felem z1, z2, x_in, y_in; + smallfelem x_out, y_out; + longfelem tmp; + + if (EC_POINT_is_at_infinity(group, point)) { + ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, + EC_R_POINT_AT_INFINITY); + return 0; + } + if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) || + (!BN_to_felem(z1, &point->Z))) + return 0; + felem_inv(z2, z1); + felem_square(tmp, z2); + felem_reduce(z1, tmp); + felem_mul(tmp, x_in, z1); + felem_reduce(x_in, tmp); + felem_contract(x_out, x_in); + if (x != NULL) { + if (!smallfelem_to_BN(x, x_out)) { + ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, + ERR_R_BN_LIB); + return 0; + } + } + felem_mul(tmp, z1, z2); + felem_reduce(z1, tmp); + felem_mul(tmp, y_in, z1); + felem_reduce(y_in, tmp); + felem_contract(y_out, y_in); + if (y != NULL) { + if (!smallfelem_to_BN(y, y_out)) { + ECerr(EC_F_EC_GFP_NISTP256_POINT_GET_AFFINE_COORDINATES, + ERR_R_BN_LIB); + return 0; + } + } + return 1; +} + +/* points below is of size |num|, and tmp_smallfelems is of size |num+1| */ +static void make_points_affine(size_t num, smallfelem points[][3], + smallfelem tmp_smallfelems[]) +{ + /* + * Runs in constant time, unless an input is the point at infinity (which + * normally shouldn't happen). + */ + ec_GFp_nistp_points_make_affine_internal(num, + points, + sizeof(smallfelem), + tmp_smallfelems, + (void (*)(void *))smallfelem_one, + (int (*)(const void *)) + smallfelem_is_zero_int, + (void (*)(void *, const void *)) + smallfelem_assign, + (void (*)(void *, const void *)) + smallfelem_square_contract, + (void (*) + (void *, const void *, + const void *)) + smallfelem_mul_contract, + (void (*)(void *, const void *)) + smallfelem_inv_contract, + /* nothing to contract */ + (void (*)(void *, const void *)) + smallfelem_assign); +} + +/* + * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL + * values Result is stored in r (r can equal one of the inputs). + */ +int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx) +{ + int ret = 0; + int j; + int mixed = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y, *z, *tmp_scalar; + felem_bytearray g_secret; + felem_bytearray *secrets = NULL; + smallfelem(*pre_comp)[17][3] = NULL; + smallfelem *tmp_smallfelems = NULL; + felem_bytearray tmp; + unsigned i, num_bytes; + int have_pre_comp = 0; + size_t num_points = num; + smallfelem x_in, y_in, z_in; + felem x_out, y_out, z_out; + NISTP256_PRE_COMP *pre = NULL; + const smallfelem(*g_pre_comp)[16][3] = NULL; + EC_POINT *generator = NULL; + const EC_POINT *p = NULL; + const BIGNUM *p_scalar = NULL; + + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((x = BN_CTX_get(ctx)) == NULL) || + ((y = BN_CTX_get(ctx)) == NULL) || + ((z = BN_CTX_get(ctx)) == NULL) || + ((tmp_scalar = BN_CTX_get(ctx)) == NULL)) + goto err; + + if (scalar != NULL) { + pre = EC_EX_DATA_get_data(group->extra_data, + nistp256_pre_comp_dup, + nistp256_pre_comp_free, + nistp256_pre_comp_clear_free); + if (pre) + /* we have precomputation, try to use it */ + g_pre_comp = (const smallfelem(*)[16][3])pre->g_pre_comp; + else + /* try to use the standard precomputation */ + g_pre_comp = &gmul[0]; + generator = EC_POINT_new(group); + if (generator == NULL) + goto err; + /* get the generator from precomputation */ + if (!smallfelem_to_BN(x, g_pre_comp[0][1][0]) || + !smallfelem_to_BN(y, g_pre_comp[0][1][1]) || + !smallfelem_to_BN(z, g_pre_comp[0][1][2])) { + ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + if (!EC_POINT_set_Jprojective_coordinates_GFp(group, + generator, x, y, z, + ctx)) + goto err; + if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) + /* precomputation matches generator */ + have_pre_comp = 1; + else + /* + * we don't have valid precomputation: treat the generator as a + * random point + */ + num_points++; + } + if (num_points > 0) { + if (num_points >= 3) { + /* + * unless we precompute multiples for just one or two points, + * converting those into affine form is time well spent + */ + mixed = 1; + } + secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray)); + pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(smallfelem)); + if (mixed) + tmp_smallfelems = + OPENSSL_malloc((num_points * 17 + 1) * sizeof(smallfelem)); + if ((secrets == NULL) || (pre_comp == NULL) + || (mixed && (tmp_smallfelems == NULL))) { + ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * we treat NULL scalars as 0, and NULL points as points at infinity, + * i.e., they contribute nothing to the linear combination + */ + memset(secrets, 0, num_points * sizeof(felem_bytearray)); + memset(pre_comp, 0, num_points * 17 * 3 * sizeof(smallfelem)); + for (i = 0; i < num_points; ++i) { + if (i == num) + /* + * we didn't have a valid precomputation, so we pick the + * generator + */ + { + p = EC_GROUP_get0_generator(group); + p_scalar = scalar; + } else + /* the i^th point */ + { + p = points[i]; + p_scalar = scalars[i]; + } + if ((p_scalar != NULL) && (p != NULL)) { + /* reduce scalar to 0 <= scalar < 2^256 */ + if ((BN_num_bits(p_scalar) > 256) + || (BN_is_negative(p_scalar))) { + /* + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) { + ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + num_bytes = BN_bn2bin(tmp_scalar, tmp); + } else + num_bytes = BN_bn2bin(p_scalar, tmp); + flip_endian(secrets[i], tmp, num_bytes); + /* precompute multiples */ + if ((!BN_to_felem(x_out, &p->X)) || + (!BN_to_felem(y_out, &p->Y)) || + (!BN_to_felem(z_out, &p->Z))) + goto err; + felem_shrink(pre_comp[i][1][0], x_out); + felem_shrink(pre_comp[i][1][1], y_out); + felem_shrink(pre_comp[i][1][2], z_out); + for (j = 2; j <= 16; ++j) { + if (j & 1) { + point_add_small(pre_comp[i][j][0], pre_comp[i][j][1], + pre_comp[i][j][2], pre_comp[i][1][0], + pre_comp[i][1][1], pre_comp[i][1][2], + pre_comp[i][j - 1][0], + pre_comp[i][j - 1][1], + pre_comp[i][j - 1][2]); + } else { + point_double_small(pre_comp[i][j][0], + pre_comp[i][j][1], + pre_comp[i][j][2], + pre_comp[i][j / 2][0], + pre_comp[i][j / 2][1], + pre_comp[i][j / 2][2]); + } + } + } + } + if (mixed) + make_points_affine(num_points * 17, pre_comp[0], tmp_smallfelems); + } + + /* the scalar for the generator */ + if ((scalar != NULL) && (have_pre_comp)) { + memset(g_secret, 0, sizeof(g_secret)); + /* reduce scalar to 0 <= scalar < 2^256 */ + if ((BN_num_bits(scalar) > 256) || (BN_is_negative(scalar))) { + /* + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) { + ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + num_bytes = BN_bn2bin(tmp_scalar, tmp); + } else + num_bytes = BN_bn2bin(scalar, tmp); + flip_endian(g_secret, tmp, num_bytes); + /* do the multiplication with generator precomputation */ + batch_mul(x_out, y_out, z_out, + (const felem_bytearray(*))secrets, num_points, + g_secret, + mixed, (const smallfelem(*)[17][3])pre_comp, g_pre_comp); + } else + /* do the multiplication without generator precomputation */ + batch_mul(x_out, y_out, z_out, + (const felem_bytearray(*))secrets, num_points, + NULL, mixed, (const smallfelem(*)[17][3])pre_comp, NULL); + /* reduce the output to its unique minimal representation */ + felem_contract(x_in, x_out); + felem_contract(y_in, y_out); + felem_contract(z_in, z_out); + if ((!smallfelem_to_BN(x, x_in)) || (!smallfelem_to_BN(y, y_in)) || + (!smallfelem_to_BN(z, z_in))) { + ECerr(EC_F_EC_GFP_NISTP256_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx); + + err: + BN_CTX_end(ctx); + if (generator != NULL) + EC_POINT_free(generator); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (secrets != NULL) + OPENSSL_free(secrets); + if (pre_comp != NULL) + OPENSSL_free(pre_comp); + if (tmp_smallfelems != NULL) + OPENSSL_free(tmp_smallfelems); + return ret; +} + +int ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +{ + int ret = 0; + NISTP256_PRE_COMP *pre = NULL; + int i, j; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y; + EC_POINT *generator = NULL; + smallfelem tmp_smallfelems[32]; + felem x_tmp, y_tmp, z_tmp; + + /* throw away old precomputation */ + EC_EX_DATA_free_data(&group->extra_data, nistp256_pre_comp_dup, + nistp256_pre_comp_free, + nistp256_pre_comp_clear_free); + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL)) + goto err; + /* get the generator */ + if (group->generator == NULL) + goto err; + generator = EC_POINT_new(group); + if (generator == NULL) + goto err; + BN_bin2bn(nistp256_curve_params[3], sizeof(felem_bytearray), x); + BN_bin2bn(nistp256_curve_params[4], sizeof(felem_bytearray), y); + if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx)) + goto err; + if ((pre = nistp256_pre_comp_new()) == NULL) + goto err; + /* + * if the generator is the standard one, use built-in precomputation + */ + if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) { + memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp)); + ret = 1; + goto err; + } + if ((!BN_to_felem(x_tmp, &group->generator->X)) || + (!BN_to_felem(y_tmp, &group->generator->Y)) || + (!BN_to_felem(z_tmp, &group->generator->Z))) + goto err; + felem_shrink(pre->g_pre_comp[0][1][0], x_tmp); + felem_shrink(pre->g_pre_comp[0][1][1], y_tmp); + felem_shrink(pre->g_pre_comp[0][1][2], z_tmp); + /* + * compute 2^64*G, 2^128*G, 2^192*G for the first table, 2^32*G, 2^96*G, + * 2^160*G, 2^224*G for the second one + */ + for (i = 1; i <= 8; i <<= 1) { + point_double_small(pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], + pre->g_pre_comp[1][i][2], pre->g_pre_comp[0][i][0], + pre->g_pre_comp[0][i][1], + pre->g_pre_comp[0][i][2]); + for (j = 0; j < 31; ++j) { + point_double_small(pre->g_pre_comp[1][i][0], + pre->g_pre_comp[1][i][1], + pre->g_pre_comp[1][i][2], + pre->g_pre_comp[1][i][0], + pre->g_pre_comp[1][i][1], + pre->g_pre_comp[1][i][2]); + } + if (i == 8) + break; + point_double_small(pre->g_pre_comp[0][2 * i][0], + pre->g_pre_comp[0][2 * i][1], + pre->g_pre_comp[0][2 * i][2], + pre->g_pre_comp[1][i][0], pre->g_pre_comp[1][i][1], + pre->g_pre_comp[1][i][2]); + for (j = 0; j < 31; ++j) { + point_double_small(pre->g_pre_comp[0][2 * i][0], + pre->g_pre_comp[0][2 * i][1], + pre->g_pre_comp[0][2 * i][2], + pre->g_pre_comp[0][2 * i][0], + pre->g_pre_comp[0][2 * i][1], + pre->g_pre_comp[0][2 * i][2]); + } + } + for (i = 0; i < 2; i++) { + /* g_pre_comp[i][0] is the point at infinity */ + memset(pre->g_pre_comp[i][0], 0, sizeof(pre->g_pre_comp[i][0])); + /* the remaining multiples */ + /* 2^64*G + 2^128*G resp. 2^96*G + 2^160*G */ + point_add_small(pre->g_pre_comp[i][6][0], pre->g_pre_comp[i][6][1], + pre->g_pre_comp[i][6][2], pre->g_pre_comp[i][4][0], + pre->g_pre_comp[i][4][1], pre->g_pre_comp[i][4][2], + pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], + pre->g_pre_comp[i][2][2]); + /* 2^64*G + 2^192*G resp. 2^96*G + 2^224*G */ + point_add_small(pre->g_pre_comp[i][10][0], pre->g_pre_comp[i][10][1], + pre->g_pre_comp[i][10][2], pre->g_pre_comp[i][8][0], + pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2], + pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], + pre->g_pre_comp[i][2][2]); + /* 2^128*G + 2^192*G resp. 2^160*G + 2^224*G */ + point_add_small(pre->g_pre_comp[i][12][0], pre->g_pre_comp[i][12][1], + pre->g_pre_comp[i][12][2], pre->g_pre_comp[i][8][0], + pre->g_pre_comp[i][8][1], pre->g_pre_comp[i][8][2], + pre->g_pre_comp[i][4][0], pre->g_pre_comp[i][4][1], + pre->g_pre_comp[i][4][2]); + /* + * 2^64*G + 2^128*G + 2^192*G resp. 2^96*G + 2^160*G + 2^224*G + */ + point_add_small(pre->g_pre_comp[i][14][0], pre->g_pre_comp[i][14][1], + pre->g_pre_comp[i][14][2], pre->g_pre_comp[i][12][0], + pre->g_pre_comp[i][12][1], pre->g_pre_comp[i][12][2], + pre->g_pre_comp[i][2][0], pre->g_pre_comp[i][2][1], + pre->g_pre_comp[i][2][2]); + for (j = 1; j < 8; ++j) { + /* odd multiples: add G resp. 2^32*G */ + point_add_small(pre->g_pre_comp[i][2 * j + 1][0], + pre->g_pre_comp[i][2 * j + 1][1], + pre->g_pre_comp[i][2 * j + 1][2], + pre->g_pre_comp[i][2 * j][0], + pre->g_pre_comp[i][2 * j][1], + pre->g_pre_comp[i][2 * j][2], + pre->g_pre_comp[i][1][0], + pre->g_pre_comp[i][1][1], + pre->g_pre_comp[i][1][2]); + } + } + make_points_affine(31, &(pre->g_pre_comp[0][1]), tmp_smallfelems); + + if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp256_pre_comp_dup, + nistp256_pre_comp_free, + nistp256_pre_comp_clear_free)) + goto err; + ret = 1; + pre = NULL; + err: + BN_CTX_end(ctx); + if (generator != NULL) + EC_POINT_free(generator); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (pre) + nistp256_pre_comp_free(pre); + return ret; +} + +int ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group) +{ + if (EC_EX_DATA_get_data(group->extra_data, nistp256_pre_comp_dup, + nistp256_pre_comp_free, + nistp256_pre_comp_clear_free) + != NULL) + return 1; + else + return 0; +} +#else +static void *dummy = &dummy; +#endif diff --git a/libs/openssl/crypto/ec/ecp_nistp521.c b/libs/openssl/crypto/ec/ecp_nistp521.c new file mode 100644 index 00000000..cc763451 --- /dev/null +++ b/libs/openssl/crypto/ec/ecp_nistp521.c @@ -0,0 +1,2148 @@ +/* crypto/ec/ecp_nistp521.c */ +/* + * Written by Adam Langley (Google) for the OpenSSL project + */ +/* Copyright 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * A 64-bit implementation of the NIST P-521 elliptic curve point multiplication + * + * OpenSSL integration was taken from Emilia Kasper's work in ecp_nistp224.c. + * Otherwise based on Emilia's P224 work, which was inspired by my curve25519 + * work which got its smarts from Daniel J. Bernstein's work on the same. + */ + +#include +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + +# ifndef OPENSSL_SYS_VMS +# include +# else +# include +# endif + +# include +# include +# include "ec_lcl.h" + +# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) + /* even with gcc, the typedef won't work for 32-bit platforms */ +typedef __uint128_t uint128_t; /* nonstandard; implemented by gcc on 64-bit + * platforms */ +# else +# error "Need GCC 3.1 or later to define type uint128_t" +# endif + +typedef uint8_t u8; +typedef uint64_t u64; +typedef int64_t s64; + +/* + * The underlying field. P521 operates over GF(2^521-1). We can serialise an + * element of this field into 66 bytes where the most significant byte + * contains only a single bit. We call this an felem_bytearray. + */ + +typedef u8 felem_bytearray[66]; + +/* + * These are the parameters of P521, taken from FIPS 186-3, section D.1.2.5. + * These values are big-endian. + */ +static const felem_bytearray nistp521_curve_params[5] = { + {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* p */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff}, + {0x01, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* a = -3 */ + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xfc}, + {0x00, 0x51, 0x95, 0x3e, 0xb9, 0x61, 0x8e, 0x1c, /* b */ + 0x9a, 0x1f, 0x92, 0x9a, 0x21, 0xa0, 0xb6, 0x85, + 0x40, 0xee, 0xa2, 0xda, 0x72, 0x5b, 0x99, 0xb3, + 0x15, 0xf3, 0xb8, 0xb4, 0x89, 0x91, 0x8e, 0xf1, + 0x09, 0xe1, 0x56, 0x19, 0x39, 0x51, 0xec, 0x7e, + 0x93, 0x7b, 0x16, 0x52, 0xc0, 0xbd, 0x3b, 0xb1, + 0xbf, 0x07, 0x35, 0x73, 0xdf, 0x88, 0x3d, 0x2c, + 0x34, 0xf1, 0xef, 0x45, 0x1f, 0xd4, 0x6b, 0x50, + 0x3f, 0x00}, + {0x00, 0xc6, 0x85, 0x8e, 0x06, 0xb7, 0x04, 0x04, /* x */ + 0xe9, 0xcd, 0x9e, 0x3e, 0xcb, 0x66, 0x23, 0x95, + 0xb4, 0x42, 0x9c, 0x64, 0x81, 0x39, 0x05, 0x3f, + 0xb5, 0x21, 0xf8, 0x28, 0xaf, 0x60, 0x6b, 0x4d, + 0x3d, 0xba, 0xa1, 0x4b, 0x5e, 0x77, 0xef, 0xe7, + 0x59, 0x28, 0xfe, 0x1d, 0xc1, 0x27, 0xa2, 0xff, + 0xa8, 0xde, 0x33, 0x48, 0xb3, 0xc1, 0x85, 0x6a, + 0x42, 0x9b, 0xf9, 0x7e, 0x7e, 0x31, 0xc2, 0xe5, + 0xbd, 0x66}, + {0x01, 0x18, 0x39, 0x29, 0x6a, 0x78, 0x9a, 0x3b, /* y */ + 0xc0, 0x04, 0x5c, 0x8a, 0x5f, 0xb4, 0x2c, 0x7d, + 0x1b, 0xd9, 0x98, 0xf5, 0x44, 0x49, 0x57, 0x9b, + 0x44, 0x68, 0x17, 0xaf, 0xbd, 0x17, 0x27, 0x3e, + 0x66, 0x2c, 0x97, 0xee, 0x72, 0x99, 0x5e, 0xf4, + 0x26, 0x40, 0xc5, 0x50, 0xb9, 0x01, 0x3f, 0xad, + 0x07, 0x61, 0x35, 0x3c, 0x70, 0x86, 0xa2, 0x72, + 0xc2, 0x40, 0x88, 0xbe, 0x94, 0x76, 0x9f, 0xd1, + 0x66, 0x50} +}; + +/*- + * The representation of field elements. + * ------------------------------------ + * + * We represent field elements with nine values. These values are either 64 or + * 128 bits and the field element represented is: + * v[0]*2^0 + v[1]*2^58 + v[2]*2^116 + ... + v[8]*2^464 (mod p) + * Each of the nine values is called a 'limb'. Since the limbs are spaced only + * 58 bits apart, but are greater than 58 bits in length, the most significant + * bits of each limb overlap with the least significant bits of the next. + * + * A field element with 64-bit limbs is an 'felem'. One with 128-bit limbs is a + * 'largefelem' */ + +# define NLIMBS 9 + +typedef uint64_t limb; +typedef limb felem[NLIMBS]; +typedef uint128_t largefelem[NLIMBS]; + +static const limb bottom57bits = 0x1ffffffffffffff; +static const limb bottom58bits = 0x3ffffffffffffff; + +/* + * bin66_to_felem takes a little-endian byte array and converts it into felem + * form. This assumes that the CPU is little-endian. + */ +static void bin66_to_felem(felem out, const u8 in[66]) +{ + out[0] = (*((limb *) & in[0])) & bottom58bits; + out[1] = (*((limb *) & in[7]) >> 2) & bottom58bits; + out[2] = (*((limb *) & in[14]) >> 4) & bottom58bits; + out[3] = (*((limb *) & in[21]) >> 6) & bottom58bits; + out[4] = (*((limb *) & in[29])) & bottom58bits; + out[5] = (*((limb *) & in[36]) >> 2) & bottom58bits; + out[6] = (*((limb *) & in[43]) >> 4) & bottom58bits; + out[7] = (*((limb *) & in[50]) >> 6) & bottom58bits; + out[8] = (*((limb *) & in[58])) & bottom57bits; +} + +/* + * felem_to_bin66 takes an felem and serialises into a little endian, 66 byte + * array. This assumes that the CPU is little-endian. + */ +static void felem_to_bin66(u8 out[66], const felem in) +{ + memset(out, 0, 66); + (*((limb *) & out[0])) = in[0]; + (*((limb *) & out[7])) |= in[1] << 2; + (*((limb *) & out[14])) |= in[2] << 4; + (*((limb *) & out[21])) |= in[3] << 6; + (*((limb *) & out[29])) = in[4]; + (*((limb *) & out[36])) |= in[5] << 2; + (*((limb *) & out[43])) |= in[6] << 4; + (*((limb *) & out[50])) |= in[7] << 6; + (*((limb *) & out[58])) = in[8]; +} + +/* To preserve endianness when using BN_bn2bin and BN_bin2bn */ +static void flip_endian(u8 *out, const u8 *in, unsigned len) +{ + unsigned i; + for (i = 0; i < len; ++i) + out[i] = in[len - 1 - i]; +} + +/* BN_to_felem converts an OpenSSL BIGNUM into an felem */ +static int BN_to_felem(felem out, const BIGNUM *bn) +{ + felem_bytearray b_in; + felem_bytearray b_out; + unsigned num_bytes; + + /* BN_bn2bin eats leading zeroes */ + memset(b_out, 0, sizeof b_out); + num_bytes = BN_num_bytes(bn); + if (num_bytes > sizeof b_out) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + if (BN_is_negative(bn)) { + ECerr(EC_F_BN_TO_FELEM, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + num_bytes = BN_bn2bin(bn, b_in); + flip_endian(b_out, b_in, num_bytes); + bin66_to_felem(out, b_out); + return 1; +} + +/* felem_to_BN converts an felem into an OpenSSL BIGNUM */ +static BIGNUM *felem_to_BN(BIGNUM *out, const felem in) +{ + felem_bytearray b_in, b_out; + felem_to_bin66(b_in, in); + flip_endian(b_out, b_in, sizeof b_out); + return BN_bin2bn(b_out, sizeof b_out, out); +} + +/*- + * Field operations + * ---------------- + */ + +static void felem_one(felem out) +{ + out[0] = 1; + out[1] = 0; + out[2] = 0; + out[3] = 0; + out[4] = 0; + out[5] = 0; + out[6] = 0; + out[7] = 0; + out[8] = 0; +} + +static void felem_assign(felem out, const felem in) +{ + out[0] = in[0]; + out[1] = in[1]; + out[2] = in[2]; + out[3] = in[3]; + out[4] = in[4]; + out[5] = in[5]; + out[6] = in[6]; + out[7] = in[7]; + out[8] = in[8]; +} + +/* felem_sum64 sets out = out + in. */ +static void felem_sum64(felem out, const felem in) +{ + out[0] += in[0]; + out[1] += in[1]; + out[2] += in[2]; + out[3] += in[3]; + out[4] += in[4]; + out[5] += in[5]; + out[6] += in[6]; + out[7] += in[7]; + out[8] += in[8]; +} + +/* felem_scalar sets out = in * scalar */ +static void felem_scalar(felem out, const felem in, limb scalar) +{ + out[0] = in[0] * scalar; + out[1] = in[1] * scalar; + out[2] = in[2] * scalar; + out[3] = in[3] * scalar; + out[4] = in[4] * scalar; + out[5] = in[5] * scalar; + out[6] = in[6] * scalar; + out[7] = in[7] * scalar; + out[8] = in[8] * scalar; +} + +/* felem_scalar64 sets out = out * scalar */ +static void felem_scalar64(felem out, limb scalar) +{ + out[0] *= scalar; + out[1] *= scalar; + out[2] *= scalar; + out[3] *= scalar; + out[4] *= scalar; + out[5] *= scalar; + out[6] *= scalar; + out[7] *= scalar; + out[8] *= scalar; +} + +/* felem_scalar128 sets out = out * scalar */ +static void felem_scalar128(largefelem out, limb scalar) +{ + out[0] *= scalar; + out[1] *= scalar; + out[2] *= scalar; + out[3] *= scalar; + out[4] *= scalar; + out[5] *= scalar; + out[6] *= scalar; + out[7] *= scalar; + out[8] *= scalar; +} + +/*- + * felem_neg sets |out| to |-in| + * On entry: + * in[i] < 2^59 + 2^14 + * On exit: + * out[i] < 2^62 + */ +static void felem_neg(felem out, const felem in) +{ + /* In order to prevent underflow, we subtract from 0 mod p. */ + static const limb two62m3 = (((limb) 1) << 62) - (((limb) 1) << 5); + static const limb two62m2 = (((limb) 1) << 62) - (((limb) 1) << 4); + + out[0] = two62m3 - in[0]; + out[1] = two62m2 - in[1]; + out[2] = two62m2 - in[2]; + out[3] = two62m2 - in[3]; + out[4] = two62m2 - in[4]; + out[5] = two62m2 - in[5]; + out[6] = two62m2 - in[6]; + out[7] = two62m2 - in[7]; + out[8] = two62m2 - in[8]; +} + +/*- + * felem_diff64 subtracts |in| from |out| + * On entry: + * in[i] < 2^59 + 2^14 + * On exit: + * out[i] < out[i] + 2^62 + */ +static void felem_diff64(felem out, const felem in) +{ + /* + * In order to prevent underflow, we add 0 mod p before subtracting. + */ + static const limb two62m3 = (((limb) 1) << 62) - (((limb) 1) << 5); + static const limb two62m2 = (((limb) 1) << 62) - (((limb) 1) << 4); + + out[0] += two62m3 - in[0]; + out[1] += two62m2 - in[1]; + out[2] += two62m2 - in[2]; + out[3] += two62m2 - in[3]; + out[4] += two62m2 - in[4]; + out[5] += two62m2 - in[5]; + out[6] += two62m2 - in[6]; + out[7] += two62m2 - in[7]; + out[8] += two62m2 - in[8]; +} + +/*- + * felem_diff_128_64 subtracts |in| from |out| + * On entry: + * in[i] < 2^62 + 2^17 + * On exit: + * out[i] < out[i] + 2^63 + */ +static void felem_diff_128_64(largefelem out, const felem in) +{ + /* + * In order to prevent underflow, we add 0 mod p before subtracting. + */ + static const limb two63m6 = (((limb) 1) << 62) - (((limb) 1) << 5); + static const limb two63m5 = (((limb) 1) << 62) - (((limb) 1) << 4); + + out[0] += two63m6 - in[0]; + out[1] += two63m5 - in[1]; + out[2] += two63m5 - in[2]; + out[3] += two63m5 - in[3]; + out[4] += two63m5 - in[4]; + out[5] += two63m5 - in[5]; + out[6] += two63m5 - in[6]; + out[7] += two63m5 - in[7]; + out[8] += two63m5 - in[8]; +} + +/*- + * felem_diff_128_64 subtracts |in| from |out| + * On entry: + * in[i] < 2^126 + * On exit: + * out[i] < out[i] + 2^127 - 2^69 + */ +static void felem_diff128(largefelem out, const largefelem in) +{ + /* + * In order to prevent underflow, we add 0 mod p before subtracting. + */ + static const uint128_t two127m70 = + (((uint128_t) 1) << 127) - (((uint128_t) 1) << 70); + static const uint128_t two127m69 = + (((uint128_t) 1) << 127) - (((uint128_t) 1) << 69); + + out[0] += (two127m70 - in[0]); + out[1] += (two127m69 - in[1]); + out[2] += (two127m69 - in[2]); + out[3] += (two127m69 - in[3]); + out[4] += (two127m69 - in[4]); + out[5] += (two127m69 - in[5]); + out[6] += (two127m69 - in[6]); + out[7] += (two127m69 - in[7]); + out[8] += (two127m69 - in[8]); +} + +/*- + * felem_square sets |out| = |in|^2 + * On entry: + * in[i] < 2^62 + * On exit: + * out[i] < 17 * max(in[i]) * max(in[i]) + */ +static void felem_square(largefelem out, const felem in) +{ + felem inx2, inx4; + felem_scalar(inx2, in, 2); + felem_scalar(inx4, in, 4); + + /*- + * We have many cases were we want to do + * in[x] * in[y] + + * in[y] * in[x] + * This is obviously just + * 2 * in[x] * in[y] + * However, rather than do the doubling on the 128 bit result, we + * double one of the inputs to the multiplication by reading from + * |inx2| + */ + + out[0] = ((uint128_t) in[0]) * in[0]; + out[1] = ((uint128_t) in[0]) * inx2[1]; + out[2] = ((uint128_t) in[0]) * inx2[2] + ((uint128_t) in[1]) * in[1]; + out[3] = ((uint128_t) in[0]) * inx2[3] + ((uint128_t) in[1]) * inx2[2]; + out[4] = ((uint128_t) in[0]) * inx2[4] + + ((uint128_t) in[1]) * inx2[3] + ((uint128_t) in[2]) * in[2]; + out[5] = ((uint128_t) in[0]) * inx2[5] + + ((uint128_t) in[1]) * inx2[4] + ((uint128_t) in[2]) * inx2[3]; + out[6] = ((uint128_t) in[0]) * inx2[6] + + ((uint128_t) in[1]) * inx2[5] + + ((uint128_t) in[2]) * inx2[4] + ((uint128_t) in[3]) * in[3]; + out[7] = ((uint128_t) in[0]) * inx2[7] + + ((uint128_t) in[1]) * inx2[6] + + ((uint128_t) in[2]) * inx2[5] + ((uint128_t) in[3]) * inx2[4]; + out[8] = ((uint128_t) in[0]) * inx2[8] + + ((uint128_t) in[1]) * inx2[7] + + ((uint128_t) in[2]) * inx2[6] + + ((uint128_t) in[3]) * inx2[5] + ((uint128_t) in[4]) * in[4]; + + /* + * The remaining limbs fall above 2^521, with the first falling at 2^522. + * They correspond to locations one bit up from the limbs produced above + * so we would have to multiply by two to align them. Again, rather than + * operate on the 128-bit result, we double one of the inputs to the + * multiplication. If we want to double for both this reason, and the + * reason above, then we end up multiplying by four. + */ + + /* 9 */ + out[0] += ((uint128_t) in[1]) * inx4[8] + + ((uint128_t) in[2]) * inx4[7] + + ((uint128_t) in[3]) * inx4[6] + ((uint128_t) in[4]) * inx4[5]; + + /* 10 */ + out[1] += ((uint128_t) in[2]) * inx4[8] + + ((uint128_t) in[3]) * inx4[7] + + ((uint128_t) in[4]) * inx4[6] + ((uint128_t) in[5]) * inx2[5]; + + /* 11 */ + out[2] += ((uint128_t) in[3]) * inx4[8] + + ((uint128_t) in[4]) * inx4[7] + ((uint128_t) in[5]) * inx4[6]; + + /* 12 */ + out[3] += ((uint128_t) in[4]) * inx4[8] + + ((uint128_t) in[5]) * inx4[7] + ((uint128_t) in[6]) * inx2[6]; + + /* 13 */ + out[4] += ((uint128_t) in[5]) * inx4[8] + ((uint128_t) in[6]) * inx4[7]; + + /* 14 */ + out[5] += ((uint128_t) in[6]) * inx4[8] + ((uint128_t) in[7]) * inx2[7]; + + /* 15 */ + out[6] += ((uint128_t) in[7]) * inx4[8]; + + /* 16 */ + out[7] += ((uint128_t) in[8]) * inx2[8]; +} + +/*- + * felem_mul sets |out| = |in1| * |in2| + * On entry: + * in1[i] < 2^64 + * in2[i] < 2^63 + * On exit: + * out[i] < 17 * max(in1[i]) * max(in2[i]) + */ +static void felem_mul(largefelem out, const felem in1, const felem in2) +{ + felem in2x2; + felem_scalar(in2x2, in2, 2); + + out[0] = ((uint128_t) in1[0]) * in2[0]; + + out[1] = ((uint128_t) in1[0]) * in2[1] + ((uint128_t) in1[1]) * in2[0]; + + out[2] = ((uint128_t) in1[0]) * in2[2] + + ((uint128_t) in1[1]) * in2[1] + ((uint128_t) in1[2]) * in2[0]; + + out[3] = ((uint128_t) in1[0]) * in2[3] + + ((uint128_t) in1[1]) * in2[2] + + ((uint128_t) in1[2]) * in2[1] + ((uint128_t) in1[3]) * in2[0]; + + out[4] = ((uint128_t) in1[0]) * in2[4] + + ((uint128_t) in1[1]) * in2[3] + + ((uint128_t) in1[2]) * in2[2] + + ((uint128_t) in1[3]) * in2[1] + ((uint128_t) in1[4]) * in2[0]; + + out[5] = ((uint128_t) in1[0]) * in2[5] + + ((uint128_t) in1[1]) * in2[4] + + ((uint128_t) in1[2]) * in2[3] + + ((uint128_t) in1[3]) * in2[2] + + ((uint128_t) in1[4]) * in2[1] + ((uint128_t) in1[5]) * in2[0]; + + out[6] = ((uint128_t) in1[0]) * in2[6] + + ((uint128_t) in1[1]) * in2[5] + + ((uint128_t) in1[2]) * in2[4] + + ((uint128_t) in1[3]) * in2[3] + + ((uint128_t) in1[4]) * in2[2] + + ((uint128_t) in1[5]) * in2[1] + ((uint128_t) in1[6]) * in2[0]; + + out[7] = ((uint128_t) in1[0]) * in2[7] + + ((uint128_t) in1[1]) * in2[6] + + ((uint128_t) in1[2]) * in2[5] + + ((uint128_t) in1[3]) * in2[4] + + ((uint128_t) in1[4]) * in2[3] + + ((uint128_t) in1[5]) * in2[2] + + ((uint128_t) in1[6]) * in2[1] + ((uint128_t) in1[7]) * in2[0]; + + out[8] = ((uint128_t) in1[0]) * in2[8] + + ((uint128_t) in1[1]) * in2[7] + + ((uint128_t) in1[2]) * in2[6] + + ((uint128_t) in1[3]) * in2[5] + + ((uint128_t) in1[4]) * in2[4] + + ((uint128_t) in1[5]) * in2[3] + + ((uint128_t) in1[6]) * in2[2] + + ((uint128_t) in1[7]) * in2[1] + ((uint128_t) in1[8]) * in2[0]; + + /* See comment in felem_square about the use of in2x2 here */ + + out[0] += ((uint128_t) in1[1]) * in2x2[8] + + ((uint128_t) in1[2]) * in2x2[7] + + ((uint128_t) in1[3]) * in2x2[6] + + ((uint128_t) in1[4]) * in2x2[5] + + ((uint128_t) in1[5]) * in2x2[4] + + ((uint128_t) in1[6]) * in2x2[3] + + ((uint128_t) in1[7]) * in2x2[2] + ((uint128_t) in1[8]) * in2x2[1]; + + out[1] += ((uint128_t) in1[2]) * in2x2[8] + + ((uint128_t) in1[3]) * in2x2[7] + + ((uint128_t) in1[4]) * in2x2[6] + + ((uint128_t) in1[5]) * in2x2[5] + + ((uint128_t) in1[6]) * in2x2[4] + + ((uint128_t) in1[7]) * in2x2[3] + ((uint128_t) in1[8]) * in2x2[2]; + + out[2] += ((uint128_t) in1[3]) * in2x2[8] + + ((uint128_t) in1[4]) * in2x2[7] + + ((uint128_t) in1[5]) * in2x2[6] + + ((uint128_t) in1[6]) * in2x2[5] + + ((uint128_t) in1[7]) * in2x2[4] + ((uint128_t) in1[8]) * in2x2[3]; + + out[3] += ((uint128_t) in1[4]) * in2x2[8] + + ((uint128_t) in1[5]) * in2x2[7] + + ((uint128_t) in1[6]) * in2x2[6] + + ((uint128_t) in1[7]) * in2x2[5] + ((uint128_t) in1[8]) * in2x2[4]; + + out[4] += ((uint128_t) in1[5]) * in2x2[8] + + ((uint128_t) in1[6]) * in2x2[7] + + ((uint128_t) in1[7]) * in2x2[6] + ((uint128_t) in1[8]) * in2x2[5]; + + out[5] += ((uint128_t) in1[6]) * in2x2[8] + + ((uint128_t) in1[7]) * in2x2[7] + ((uint128_t) in1[8]) * in2x2[6]; + + out[6] += ((uint128_t) in1[7]) * in2x2[8] + + ((uint128_t) in1[8]) * in2x2[7]; + + out[7] += ((uint128_t) in1[8]) * in2x2[8]; +} + +static const limb bottom52bits = 0xfffffffffffff; + +/*- + * felem_reduce converts a largefelem to an felem. + * On entry: + * in[i] < 2^128 + * On exit: + * out[i] < 2^59 + 2^14 + */ +static void felem_reduce(felem out, const largefelem in) +{ + u64 overflow1, overflow2; + + out[0] = ((limb) in[0]) & bottom58bits; + out[1] = ((limb) in[1]) & bottom58bits; + out[2] = ((limb) in[2]) & bottom58bits; + out[3] = ((limb) in[3]) & bottom58bits; + out[4] = ((limb) in[4]) & bottom58bits; + out[5] = ((limb) in[5]) & bottom58bits; + out[6] = ((limb) in[6]) & bottom58bits; + out[7] = ((limb) in[7]) & bottom58bits; + out[8] = ((limb) in[8]) & bottom58bits; + + /* out[i] < 2^58 */ + + out[1] += ((limb) in[0]) >> 58; + out[1] += (((limb) (in[0] >> 64)) & bottom52bits) << 6; + /*- + * out[1] < 2^58 + 2^6 + 2^58 + * = 2^59 + 2^6 + */ + out[2] += ((limb) (in[0] >> 64)) >> 52; + + out[2] += ((limb) in[1]) >> 58; + out[2] += (((limb) (in[1] >> 64)) & bottom52bits) << 6; + out[3] += ((limb) (in[1] >> 64)) >> 52; + + out[3] += ((limb) in[2]) >> 58; + out[3] += (((limb) (in[2] >> 64)) & bottom52bits) << 6; + out[4] += ((limb) (in[2] >> 64)) >> 52; + + out[4] += ((limb) in[3]) >> 58; + out[4] += (((limb) (in[3] >> 64)) & bottom52bits) << 6; + out[5] += ((limb) (in[3] >> 64)) >> 52; + + out[5] += ((limb) in[4]) >> 58; + out[5] += (((limb) (in[4] >> 64)) & bottom52bits) << 6; + out[6] += ((limb) (in[4] >> 64)) >> 52; + + out[6] += ((limb) in[5]) >> 58; + out[6] += (((limb) (in[5] >> 64)) & bottom52bits) << 6; + out[7] += ((limb) (in[5] >> 64)) >> 52; + + out[7] += ((limb) in[6]) >> 58; + out[7] += (((limb) (in[6] >> 64)) & bottom52bits) << 6; + out[8] += ((limb) (in[6] >> 64)) >> 52; + + out[8] += ((limb) in[7]) >> 58; + out[8] += (((limb) (in[7] >> 64)) & bottom52bits) << 6; + /*- + * out[x > 1] < 2^58 + 2^6 + 2^58 + 2^12 + * < 2^59 + 2^13 + */ + overflow1 = ((limb) (in[7] >> 64)) >> 52; + + overflow1 += ((limb) in[8]) >> 58; + overflow1 += (((limb) (in[8] >> 64)) & bottom52bits) << 6; + overflow2 = ((limb) (in[8] >> 64)) >> 52; + + overflow1 <<= 1; /* overflow1 < 2^13 + 2^7 + 2^59 */ + overflow2 <<= 1; /* overflow2 < 2^13 */ + + out[0] += overflow1; /* out[0] < 2^60 */ + out[1] += overflow2; /* out[1] < 2^59 + 2^6 + 2^13 */ + + out[1] += out[0] >> 58; + out[0] &= bottom58bits; + /*- + * out[0] < 2^58 + * out[1] < 2^59 + 2^6 + 2^13 + 2^2 + * < 2^59 + 2^14 + */ +} + +static void felem_square_reduce(felem out, const felem in) +{ + largefelem tmp; + felem_square(tmp, in); + felem_reduce(out, tmp); +} + +static void felem_mul_reduce(felem out, const felem in1, const felem in2) +{ + largefelem tmp; + felem_mul(tmp, in1, in2); + felem_reduce(out, tmp); +} + +/*- + * felem_inv calculates |out| = |in|^{-1} + * + * Based on Fermat's Little Theorem: + * a^p = a (mod p) + * a^{p-1} = 1 (mod p) + * a^{p-2} = a^{-1} (mod p) + */ +static void felem_inv(felem out, const felem in) +{ + felem ftmp, ftmp2, ftmp3, ftmp4; + largefelem tmp; + unsigned i; + + felem_square(tmp, in); + felem_reduce(ftmp, tmp); /* 2^1 */ + felem_mul(tmp, in, ftmp); + felem_reduce(ftmp, tmp); /* 2^2 - 2^0 */ + felem_assign(ftmp2, ftmp); + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^3 - 2^1 */ + felem_mul(tmp, in, ftmp); + felem_reduce(ftmp, tmp); /* 2^3 - 2^0 */ + felem_square(tmp, ftmp); + felem_reduce(ftmp, tmp); /* 2^4 - 2^1 */ + + felem_square(tmp, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^3 - 2^1 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^4 - 2^2 */ + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^4 - 2^0 */ + + felem_assign(ftmp2, ftmp3); + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^5 - 2^1 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^6 - 2^2 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^7 - 2^3 */ + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^8 - 2^4 */ + felem_assign(ftmp4, ftmp3); + felem_mul(tmp, ftmp3, ftmp); + felem_reduce(ftmp4, tmp); /* 2^8 - 2^1 */ + felem_square(tmp, ftmp4); + felem_reduce(ftmp4, tmp); /* 2^9 - 2^2 */ + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^8 - 2^0 */ + felem_assign(ftmp2, ftmp3); + + for (i = 0; i < 8; i++) { + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^16 - 2^8 */ + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^16 - 2^0 */ + felem_assign(ftmp2, ftmp3); + + for (i = 0; i < 16; i++) { + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^32 - 2^16 */ + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^32 - 2^0 */ + felem_assign(ftmp2, ftmp3); + + for (i = 0; i < 32; i++) { + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^64 - 2^32 */ + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^64 - 2^0 */ + felem_assign(ftmp2, ftmp3); + + for (i = 0; i < 64; i++) { + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^128 - 2^64 */ + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^128 - 2^0 */ + felem_assign(ftmp2, ftmp3); + + for (i = 0; i < 128; i++) { + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^256 - 2^128 */ + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^256 - 2^0 */ + felem_assign(ftmp2, ftmp3); + + for (i = 0; i < 256; i++) { + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^512 - 2^256 */ + } + felem_mul(tmp, ftmp3, ftmp2); + felem_reduce(ftmp3, tmp); /* 2^512 - 2^0 */ + + for (i = 0; i < 9; i++) { + felem_square(tmp, ftmp3); + felem_reduce(ftmp3, tmp); /* 2^521 - 2^9 */ + } + felem_mul(tmp, ftmp3, ftmp4); + felem_reduce(ftmp3, tmp); /* 2^512 - 2^2 */ + felem_mul(tmp, ftmp3, in); + felem_reduce(out, tmp); /* 2^512 - 3 */ +} + +/* This is 2^521-1, expressed as an felem */ +static const felem kPrime = { + 0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff, + 0x03ffffffffffffff, 0x03ffffffffffffff, 0x03ffffffffffffff, + 0x03ffffffffffffff, 0x03ffffffffffffff, 0x01ffffffffffffff +}; + +/*- + * felem_is_zero returns a limb with all bits set if |in| == 0 (mod p) and 0 + * otherwise. + * On entry: + * in[i] < 2^59 + 2^14 + */ +static limb felem_is_zero(const felem in) +{ + felem ftmp; + limb is_zero, is_p; + felem_assign(ftmp, in); + + ftmp[0] += ftmp[8] >> 57; + ftmp[8] &= bottom57bits; + /* ftmp[8] < 2^57 */ + ftmp[1] += ftmp[0] >> 58; + ftmp[0] &= bottom58bits; + ftmp[2] += ftmp[1] >> 58; + ftmp[1] &= bottom58bits; + ftmp[3] += ftmp[2] >> 58; + ftmp[2] &= bottom58bits; + ftmp[4] += ftmp[3] >> 58; + ftmp[3] &= bottom58bits; + ftmp[5] += ftmp[4] >> 58; + ftmp[4] &= bottom58bits; + ftmp[6] += ftmp[5] >> 58; + ftmp[5] &= bottom58bits; + ftmp[7] += ftmp[6] >> 58; + ftmp[6] &= bottom58bits; + ftmp[8] += ftmp[7] >> 58; + ftmp[7] &= bottom58bits; + /* ftmp[8] < 2^57 + 4 */ + + /* + * The ninth limb of 2*(2^521-1) is 0x03ffffffffffffff, which is greater + * than our bound for ftmp[8]. Therefore we only have to check if the + * zero is zero or 2^521-1. + */ + + is_zero = 0; + is_zero |= ftmp[0]; + is_zero |= ftmp[1]; + is_zero |= ftmp[2]; + is_zero |= ftmp[3]; + is_zero |= ftmp[4]; + is_zero |= ftmp[5]; + is_zero |= ftmp[6]; + is_zero |= ftmp[7]; + is_zero |= ftmp[8]; + + is_zero--; + /* + * We know that ftmp[i] < 2^63, therefore the only way that the top bit + * can be set is if is_zero was 0 before the decrement. + */ + is_zero = ((s64) is_zero) >> 63; + + is_p = ftmp[0] ^ kPrime[0]; + is_p |= ftmp[1] ^ kPrime[1]; + is_p |= ftmp[2] ^ kPrime[2]; + is_p |= ftmp[3] ^ kPrime[3]; + is_p |= ftmp[4] ^ kPrime[4]; + is_p |= ftmp[5] ^ kPrime[5]; + is_p |= ftmp[6] ^ kPrime[6]; + is_p |= ftmp[7] ^ kPrime[7]; + is_p |= ftmp[8] ^ kPrime[8]; + + is_p--; + is_p = ((s64) is_p) >> 63; + + is_zero |= is_p; + return is_zero; +} + +static int felem_is_zero_int(const felem in) +{ + return (int)(felem_is_zero(in) & ((limb) 1)); +} + +/*- + * felem_contract converts |in| to its unique, minimal representation. + * On entry: + * in[i] < 2^59 + 2^14 + */ +static void felem_contract(felem out, const felem in) +{ + limb is_p, is_greater, sign; + static const limb two58 = ((limb) 1) << 58; + + felem_assign(out, in); + + out[0] += out[8] >> 57; + out[8] &= bottom57bits; + /* out[8] < 2^57 */ + out[1] += out[0] >> 58; + out[0] &= bottom58bits; + out[2] += out[1] >> 58; + out[1] &= bottom58bits; + out[3] += out[2] >> 58; + out[2] &= bottom58bits; + out[4] += out[3] >> 58; + out[3] &= bottom58bits; + out[5] += out[4] >> 58; + out[4] &= bottom58bits; + out[6] += out[5] >> 58; + out[5] &= bottom58bits; + out[7] += out[6] >> 58; + out[6] &= bottom58bits; + out[8] += out[7] >> 58; + out[7] &= bottom58bits; + /* out[8] < 2^57 + 4 */ + + /* + * If the value is greater than 2^521-1 then we have to subtract 2^521-1 + * out. See the comments in felem_is_zero regarding why we don't test for + * other multiples of the prime. + */ + + /* + * First, if |out| is equal to 2^521-1, we subtract it out to get zero. + */ + + is_p = out[0] ^ kPrime[0]; + is_p |= out[1] ^ kPrime[1]; + is_p |= out[2] ^ kPrime[2]; + is_p |= out[3] ^ kPrime[3]; + is_p |= out[4] ^ kPrime[4]; + is_p |= out[5] ^ kPrime[5]; + is_p |= out[6] ^ kPrime[6]; + is_p |= out[7] ^ kPrime[7]; + is_p |= out[8] ^ kPrime[8]; + + is_p--; + is_p &= is_p << 32; + is_p &= is_p << 16; + is_p &= is_p << 8; + is_p &= is_p << 4; + is_p &= is_p << 2; + is_p &= is_p << 1; + is_p = ((s64) is_p) >> 63; + is_p = ~is_p; + + /* is_p is 0 iff |out| == 2^521-1 and all ones otherwise */ + + out[0] &= is_p; + out[1] &= is_p; + out[2] &= is_p; + out[3] &= is_p; + out[4] &= is_p; + out[5] &= is_p; + out[6] &= is_p; + out[7] &= is_p; + out[8] &= is_p; + + /* + * In order to test that |out| >= 2^521-1 we need only test if out[8] >> + * 57 is greater than zero as (2^521-1) + x >= 2^522 + */ + is_greater = out[8] >> 57; + is_greater |= is_greater << 32; + is_greater |= is_greater << 16; + is_greater |= is_greater << 8; + is_greater |= is_greater << 4; + is_greater |= is_greater << 2; + is_greater |= is_greater << 1; + is_greater = ((s64) is_greater) >> 63; + + out[0] -= kPrime[0] & is_greater; + out[1] -= kPrime[1] & is_greater; + out[2] -= kPrime[2] & is_greater; + out[3] -= kPrime[3] & is_greater; + out[4] -= kPrime[4] & is_greater; + out[5] -= kPrime[5] & is_greater; + out[6] -= kPrime[6] & is_greater; + out[7] -= kPrime[7] & is_greater; + out[8] -= kPrime[8] & is_greater; + + /* Eliminate negative coefficients */ + sign = -(out[0] >> 63); + out[0] += (two58 & sign); + out[1] -= (1 & sign); + sign = -(out[1] >> 63); + out[1] += (two58 & sign); + out[2] -= (1 & sign); + sign = -(out[2] >> 63); + out[2] += (two58 & sign); + out[3] -= (1 & sign); + sign = -(out[3] >> 63); + out[3] += (two58 & sign); + out[4] -= (1 & sign); + sign = -(out[4] >> 63); + out[4] += (two58 & sign); + out[5] -= (1 & sign); + sign = -(out[0] >> 63); + out[5] += (two58 & sign); + out[6] -= (1 & sign); + sign = -(out[6] >> 63); + out[6] += (two58 & sign); + out[7] -= (1 & sign); + sign = -(out[7] >> 63); + out[7] += (two58 & sign); + out[8] -= (1 & sign); + sign = -(out[5] >> 63); + out[5] += (two58 & sign); + out[6] -= (1 & sign); + sign = -(out[6] >> 63); + out[6] += (two58 & sign); + out[7] -= (1 & sign); + sign = -(out[7] >> 63); + out[7] += (two58 & sign); + out[8] -= (1 & sign); +} + +/*- + * Group operations + * ---------------- + * + * Building on top of the field operations we have the operations on the + * elliptic curve group itself. Points on the curve are represented in Jacobian + * coordinates */ + +/*- + * point_double calcuates 2*(x_in, y_in, z_in) + * + * The method is taken from: + * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b + * + * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed. + * while x_out == y_in is not (maybe this works, but it's not tested). */ +static void +point_double(felem x_out, felem y_out, felem z_out, + const felem x_in, const felem y_in, const felem z_in) +{ + largefelem tmp, tmp2; + felem delta, gamma, beta, alpha, ftmp, ftmp2; + + felem_assign(ftmp, x_in); + felem_assign(ftmp2, x_in); + + /* delta = z^2 */ + felem_square(tmp, z_in); + felem_reduce(delta, tmp); /* delta[i] < 2^59 + 2^14 */ + + /* gamma = y^2 */ + felem_square(tmp, y_in); + felem_reduce(gamma, tmp); /* gamma[i] < 2^59 + 2^14 */ + + /* beta = x*gamma */ + felem_mul(tmp, x_in, gamma); + felem_reduce(beta, tmp); /* beta[i] < 2^59 + 2^14 */ + + /* alpha = 3*(x-delta)*(x+delta) */ + felem_diff64(ftmp, delta); + /* ftmp[i] < 2^61 */ + felem_sum64(ftmp2, delta); + /* ftmp2[i] < 2^60 + 2^15 */ + felem_scalar64(ftmp2, 3); + /* ftmp2[i] < 3*2^60 + 3*2^15 */ + felem_mul(tmp, ftmp, ftmp2); + /*- + * tmp[i] < 17(3*2^121 + 3*2^76) + * = 61*2^121 + 61*2^76 + * < 64*2^121 + 64*2^76 + * = 2^127 + 2^82 + * < 2^128 + */ + felem_reduce(alpha, tmp); + + /* x' = alpha^2 - 8*beta */ + felem_square(tmp, alpha); + /* + * tmp[i] < 17*2^120 < 2^125 + */ + felem_assign(ftmp, beta); + felem_scalar64(ftmp, 8); + /* ftmp[i] < 2^62 + 2^17 */ + felem_diff_128_64(tmp, ftmp); + /* tmp[i] < 2^125 + 2^63 + 2^62 + 2^17 */ + felem_reduce(x_out, tmp); + + /* z' = (y + z)^2 - gamma - delta */ + felem_sum64(delta, gamma); + /* delta[i] < 2^60 + 2^15 */ + felem_assign(ftmp, y_in); + felem_sum64(ftmp, z_in); + /* ftmp[i] < 2^60 + 2^15 */ + felem_square(tmp, ftmp); + /* + * tmp[i] < 17(2^122) < 2^127 + */ + felem_diff_128_64(tmp, delta); + /* tmp[i] < 2^127 + 2^63 */ + felem_reduce(z_out, tmp); + + /* y' = alpha*(4*beta - x') - 8*gamma^2 */ + felem_scalar64(beta, 4); + /* beta[i] < 2^61 + 2^16 */ + felem_diff64(beta, x_out); + /* beta[i] < 2^61 + 2^60 + 2^16 */ + felem_mul(tmp, alpha, beta); + /*- + * tmp[i] < 17*((2^59 + 2^14)(2^61 + 2^60 + 2^16)) + * = 17*(2^120 + 2^75 + 2^119 + 2^74 + 2^75 + 2^30) + * = 17*(2^120 + 2^119 + 2^76 + 2^74 + 2^30) + * < 2^128 + */ + felem_square(tmp2, gamma); + /*- + * tmp2[i] < 17*(2^59 + 2^14)^2 + * = 17*(2^118 + 2^74 + 2^28) + */ + felem_scalar128(tmp2, 8); + /*- + * tmp2[i] < 8*17*(2^118 + 2^74 + 2^28) + * = 2^125 + 2^121 + 2^81 + 2^77 + 2^35 + 2^31 + * < 2^126 + */ + felem_diff128(tmp, tmp2); + /*- + * tmp[i] < 2^127 - 2^69 + 17(2^120 + 2^119 + 2^76 + 2^74 + 2^30) + * = 2^127 + 2^124 + 2^122 + 2^120 + 2^118 + 2^80 + 2^78 + 2^76 + + * 2^74 + 2^69 + 2^34 + 2^30 + * < 2^128 + */ + felem_reduce(y_out, tmp); +} + +/* copy_conditional copies in to out iff mask is all ones. */ +static void copy_conditional(felem out, const felem in, limb mask) +{ + unsigned i; + for (i = 0; i < NLIMBS; ++i) { + const limb tmp = mask & (in[i] ^ out[i]); + out[i] ^= tmp; + } +} + +/*- + * point_add calcuates (x1, y1, z1) + (x2, y2, z2) + * + * The method is taken from + * http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl, + * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity). + * + * This function includes a branch for checking whether the two input points + * are equal (while not equal to the point at infinity). This case never + * happens during single point multiplication, so there is no timing leak for + * ECDH or ECDSA signing. */ +static void point_add(felem x3, felem y3, felem z3, + const felem x1, const felem y1, const felem z1, + const int mixed, const felem x2, const felem y2, + const felem z2) +{ + felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out; + largefelem tmp, tmp2; + limb x_equal, y_equal, z1_is_zero, z2_is_zero; + + z1_is_zero = felem_is_zero(z1); + z2_is_zero = felem_is_zero(z2); + + /* ftmp = z1z1 = z1**2 */ + felem_square(tmp, z1); + felem_reduce(ftmp, tmp); + + if (!mixed) { + /* ftmp2 = z2z2 = z2**2 */ + felem_square(tmp, z2); + felem_reduce(ftmp2, tmp); + + /* u1 = ftmp3 = x1*z2z2 */ + felem_mul(tmp, x1, ftmp2); + felem_reduce(ftmp3, tmp); + + /* ftmp5 = z1 + z2 */ + felem_assign(ftmp5, z1); + felem_sum64(ftmp5, z2); + /* ftmp5[i] < 2^61 */ + + /* ftmp5 = (z1 + z2)**2 - z1z1 - z2z2 = 2*z1z2 */ + felem_square(tmp, ftmp5); + /* tmp[i] < 17*2^122 */ + felem_diff_128_64(tmp, ftmp); + /* tmp[i] < 17*2^122 + 2^63 */ + felem_diff_128_64(tmp, ftmp2); + /* tmp[i] < 17*2^122 + 2^64 */ + felem_reduce(ftmp5, tmp); + + /* ftmp2 = z2 * z2z2 */ + felem_mul(tmp, ftmp2, z2); + felem_reduce(ftmp2, tmp); + + /* s1 = ftmp6 = y1 * z2**3 */ + felem_mul(tmp, y1, ftmp2); + felem_reduce(ftmp6, tmp); + } else { + /* + * We'll assume z2 = 1 (special case z2 = 0 is handled later) + */ + + /* u1 = ftmp3 = x1*z2z2 */ + felem_assign(ftmp3, x1); + + /* ftmp5 = 2*z1z2 */ + felem_scalar(ftmp5, z1, 2); + + /* s1 = ftmp6 = y1 * z2**3 */ + felem_assign(ftmp6, y1); + } + + /* u2 = x2*z1z1 */ + felem_mul(tmp, x2, ftmp); + /* tmp[i] < 17*2^120 */ + + /* h = ftmp4 = u2 - u1 */ + felem_diff_128_64(tmp, ftmp3); + /* tmp[i] < 17*2^120 + 2^63 */ + felem_reduce(ftmp4, tmp); + + x_equal = felem_is_zero(ftmp4); + + /* z_out = ftmp5 * h */ + felem_mul(tmp, ftmp5, ftmp4); + felem_reduce(z_out, tmp); + + /* ftmp = z1 * z1z1 */ + felem_mul(tmp, ftmp, z1); + felem_reduce(ftmp, tmp); + + /* s2 = tmp = y2 * z1**3 */ + felem_mul(tmp, y2, ftmp); + /* tmp[i] < 17*2^120 */ + + /* r = ftmp5 = (s2 - s1)*2 */ + felem_diff_128_64(tmp, ftmp6); + /* tmp[i] < 17*2^120 + 2^63 */ + felem_reduce(ftmp5, tmp); + y_equal = felem_is_zero(ftmp5); + felem_scalar64(ftmp5, 2); + /* ftmp5[i] < 2^61 */ + + if (x_equal && y_equal && !z1_is_zero && !z2_is_zero) { + point_double(x3, y3, z3, x1, y1, z1); + return; + } + + /* I = ftmp = (2h)**2 */ + felem_assign(ftmp, ftmp4); + felem_scalar64(ftmp, 2); + /* ftmp[i] < 2^61 */ + felem_square(tmp, ftmp); + /* tmp[i] < 17*2^122 */ + felem_reduce(ftmp, tmp); + + /* J = ftmp2 = h * I */ + felem_mul(tmp, ftmp4, ftmp); + felem_reduce(ftmp2, tmp); + + /* V = ftmp4 = U1 * I */ + felem_mul(tmp, ftmp3, ftmp); + felem_reduce(ftmp4, tmp); + + /* x_out = r**2 - J - 2V */ + felem_square(tmp, ftmp5); + /* tmp[i] < 17*2^122 */ + felem_diff_128_64(tmp, ftmp2); + /* tmp[i] < 17*2^122 + 2^63 */ + felem_assign(ftmp3, ftmp4); + felem_scalar64(ftmp4, 2); + /* ftmp4[i] < 2^61 */ + felem_diff_128_64(tmp, ftmp4); + /* tmp[i] < 17*2^122 + 2^64 */ + felem_reduce(x_out, tmp); + + /* y_out = r(V-x_out) - 2 * s1 * J */ + felem_diff64(ftmp3, x_out); + /* + * ftmp3[i] < 2^60 + 2^60 = 2^61 + */ + felem_mul(tmp, ftmp5, ftmp3); + /* tmp[i] < 17*2^122 */ + felem_mul(tmp2, ftmp6, ftmp2); + /* tmp2[i] < 17*2^120 */ + felem_scalar128(tmp2, 2); + /* tmp2[i] < 17*2^121 */ + felem_diff128(tmp, tmp2); + /*- + * tmp[i] < 2^127 - 2^69 + 17*2^122 + * = 2^126 - 2^122 - 2^6 - 2^2 - 1 + * < 2^127 + */ + felem_reduce(y_out, tmp); + + copy_conditional(x_out, x2, z1_is_zero); + copy_conditional(x_out, x1, z2_is_zero); + copy_conditional(y_out, y2, z1_is_zero); + copy_conditional(y_out, y1, z2_is_zero); + copy_conditional(z_out, z2, z1_is_zero); + copy_conditional(z_out, z1, z2_is_zero); + felem_assign(x3, x_out); + felem_assign(y3, y_out); + felem_assign(z3, z_out); +} + +/*- + * Base point pre computation + * -------------------------- + * + * Two different sorts of precomputed tables are used in the following code. + * Each contain various points on the curve, where each point is three field + * elements (x, y, z). + * + * For the base point table, z is usually 1 (0 for the point at infinity). + * This table has 16 elements: + * index | bits | point + * ------+---------+------------------------------ + * 0 | 0 0 0 0 | 0G + * 1 | 0 0 0 1 | 1G + * 2 | 0 0 1 0 | 2^130G + * 3 | 0 0 1 1 | (2^130 + 1)G + * 4 | 0 1 0 0 | 2^260G + * 5 | 0 1 0 1 | (2^260 + 1)G + * 6 | 0 1 1 0 | (2^260 + 2^130)G + * 7 | 0 1 1 1 | (2^260 + 2^130 + 1)G + * 8 | 1 0 0 0 | 2^390G + * 9 | 1 0 0 1 | (2^390 + 1)G + * 10 | 1 0 1 0 | (2^390 + 2^130)G + * 11 | 1 0 1 1 | (2^390 + 2^130 + 1)G + * 12 | 1 1 0 0 | (2^390 + 2^260)G + * 13 | 1 1 0 1 | (2^390 + 2^260 + 1)G + * 14 | 1 1 1 0 | (2^390 + 2^260 + 2^130)G + * 15 | 1 1 1 1 | (2^390 + 2^260 + 2^130 + 1)G + * + * The reason for this is so that we can clock bits into four different + * locations when doing simple scalar multiplies against the base point. + * + * Tables for other points have table[i] = iG for i in 0 .. 16. */ + +/* gmul is the table of precomputed base points */ +static const felem gmul[16][3] = { {{0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x017e7e31c2e5bd66, 0x022cf0615a90a6fe, 0x00127a2ffa8de334, + 0x01dfbf9d64a3f877, 0x006b4d3dbaa14b5e, 0x014fed487e0a2bd8, + 0x015b4429c6481390, 0x03a73678fb2d988e, 0x00c6858e06b70404}, + {0x00be94769fd16650, 0x031c21a89cb09022, 0x039013fad0761353, + 0x02657bd099031542, 0x03273e662c97ee72, 0x01e6d11a05ebef45, + 0x03d1bd998f544495, 0x03001172297ed0b1, 0x011839296a789a3b}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x0373faacbc875bae, 0x00f325023721c671, 0x00f666fd3dbde5ad, + 0x01a6932363f88ea7, 0x01fc6d9e13f9c47b, 0x03bcbffc2bbf734e, + 0x013ee3c3647f3a92, 0x029409fefe75d07d, 0x00ef9199963d85e5}, + {0x011173743ad5b178, 0x02499c7c21bf7d46, 0x035beaeabb8b1a58, + 0x00f989c4752ea0a3, 0x0101e1de48a9c1a3, 0x01a20076be28ba6c, + 0x02f8052e5eb2de95, 0x01bfe8f82dea117c, 0x0160074d3c36ddb7}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x012f3fc373393b3b, 0x03d3d6172f1419fa, 0x02adc943c0b86873, + 0x00d475584177952b, 0x012a4d1673750ee2, 0x00512517a0f13b0c, + 0x02b184671a7b1734, 0x0315b84236f1a50a, 0x00a4afc472edbdb9}, + {0x00152a7077f385c4, 0x03044007d8d1c2ee, 0x0065829d61d52b52, + 0x00494ff6b6631d0d, 0x00a11d94d5f06bcf, 0x02d2f89474d9282e, + 0x0241c5727c06eeb9, 0x0386928710fbdb9d, 0x01f883f727b0dfbe}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x019b0c3c9185544d, 0x006243a37c9d97db, 0x02ee3cbe030a2ad2, + 0x00cfdd946bb51e0d, 0x0271c00932606b91, 0x03f817d1ec68c561, + 0x03f37009806a369c, 0x03c1f30baf184fd5, 0x01091022d6d2f065}, + {0x0292c583514c45ed, 0x0316fca51f9a286c, 0x00300af507c1489a, + 0x0295f69008298cf1, 0x02c0ed8274943d7b, 0x016509b9b47a431e, + 0x02bc9de9634868ce, 0x005b34929bffcb09, 0x000c1a0121681524}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x0286abc0292fb9f2, 0x02665eee9805b3f7, 0x01ed7455f17f26d6, + 0x0346355b83175d13, 0x006284944cd0a097, 0x0191895bcdec5e51, + 0x02e288370afda7d9, 0x03b22312bfefa67a, 0x01d104d3fc0613fe}, + {0x0092421a12f7e47f, 0x0077a83fa373c501, 0x03bd25c5f696bd0d, + 0x035c41e4d5459761, 0x01ca0d1742b24f53, 0x00aaab27863a509c, + 0x018b6de47df73917, 0x025c0b771705cd01, 0x01fd51d566d760a7}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x01dd92ff6b0d1dbd, 0x039c5e2e8f8afa69, 0x0261ed13242c3b27, + 0x0382c6e67026e6a0, 0x01d60b10be2089f9, 0x03c15f3dce86723f, + 0x03c764a32d2a062d, 0x017307eac0fad056, 0x018207c0b96c5256}, + {0x0196a16d60e13154, 0x03e6ce74c0267030, 0x00ddbf2b4e52a5aa, + 0x012738241bbf31c8, 0x00ebe8dc04685a28, 0x024c2ad6d380d4a2, + 0x035ee062a6e62d0e, 0x0029ed74af7d3a0f, 0x00eef32aec142ebd}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x00c31ec398993b39, 0x03a9f45bcda68253, 0x00ac733c24c70890, + 0x00872b111401ff01, 0x01d178c23195eafb, 0x03bca2c816b87f74, + 0x0261a9af46fbad7a, 0x0324b2a8dd3d28f9, 0x00918121d8f24e23}, + {0x032bc8c1ca983cd7, 0x00d869dfb08fc8c6, 0x01693cb61fce1516, + 0x012a5ea68f4e88a8, 0x010869cab88d7ae3, 0x009081ad277ceee1, + 0x033a77166d064cdc, 0x03955235a1fb3a95, 0x01251a4a9b25b65e}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x00148a3a1b27f40b, 0x0123186df1b31fdc, 0x00026e7beaad34ce, + 0x01db446ac1d3dbba, 0x0299c1a33437eaec, 0x024540610183cbb7, + 0x0173bb0e9ce92e46, 0x02b937e43921214b, 0x01ab0436a9bf01b5}, + {0x0383381640d46948, 0x008dacbf0e7f330f, 0x03602122bcc3f318, + 0x01ee596b200620d6, 0x03bd0585fda430b3, 0x014aed77fd123a83, + 0x005ace749e52f742, 0x0390fe041da2b842, 0x0189a8ceb3299242}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x012a19d6b3282473, 0x00c0915918b423ce, 0x023a954eb94405ae, + 0x00529f692be26158, 0x0289fa1b6fa4b2aa, 0x0198ae4ceea346ef, + 0x0047d8cdfbdedd49, 0x00cc8c8953f0f6b8, 0x001424abbff49203}, + {0x0256732a1115a03a, 0x0351bc38665c6733, 0x03f7b950fb4a6447, + 0x000afffa94c22155, 0x025763d0a4dab540, 0x000511e92d4fc283, + 0x030a7e9eda0ee96c, 0x004c3cd93a28bf0a, 0x017edb3a8719217f}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x011de5675a88e673, 0x031d7d0f5e567fbe, 0x0016b2062c970ae5, + 0x03f4a2be49d90aa7, 0x03cef0bd13822866, 0x03f0923dcf774a6c, + 0x0284bebc4f322f72, 0x016ab2645302bb2c, 0x01793f95dace0e2a}, + {0x010646e13527a28f, 0x01ca1babd59dc5e7, 0x01afedfd9a5595df, + 0x01f15785212ea6b1, 0x0324e5d64f6ae3f4, 0x02d680f526d00645, + 0x0127920fadf627a7, 0x03b383f75df4f684, 0x0089e0057e783b0a}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x00f334b9eb3c26c6, 0x0298fdaa98568dce, 0x01c2d24843a82292, + 0x020bcb24fa1b0711, 0x02cbdb3d2b1875e6, 0x0014907598f89422, + 0x03abe3aa43b26664, 0x02cbf47f720bc168, 0x0133b5e73014b79b}, + {0x034aab5dab05779d, 0x00cdc5d71fee9abb, 0x0399f16bd4bd9d30, + 0x03582fa592d82647, 0x02be1cdfb775b0e9, 0x0034f7cea32e94cb, + 0x0335a7f08f56f286, 0x03b707e9565d1c8b, 0x0015c946ea5b614f}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x024676f6cff72255, 0x00d14625cac96378, 0x00532b6008bc3767, + 0x01fc16721b985322, 0x023355ea1b091668, 0x029de7afdc0317c3, + 0x02fc8a7ca2da037c, 0x02de1217d74a6f30, 0x013f7173175b73bf}, + {0x0344913f441490b5, 0x0200f9e272b61eca, 0x0258a246b1dd55d2, + 0x03753db9ea496f36, 0x025e02937a09c5ef, 0x030cbd3d14012692, + 0x01793a67e70dc72a, 0x03ec1d37048a662e, 0x006550f700c32a8d}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x00d3f48a347eba27, 0x008e636649b61bd8, 0x00d3b93716778fb3, + 0x004d1915757bd209, 0x019d5311a3da44e0, 0x016d1afcbbe6aade, + 0x0241bf5f73265616, 0x0384672e5d50d39b, 0x005009fee522b684}, + {0x029b4fab064435fe, 0x018868ee095bbb07, 0x01ea3d6936cc92b8, + 0x000608b00f78a2f3, 0x02db911073d1c20f, 0x018205938470100a, + 0x01f1e4964cbe6ff2, 0x021a19a29eed4663, 0x01414485f42afa81}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x01612b3a17f63e34, 0x03813992885428e6, 0x022b3c215b5a9608, + 0x029b4057e19f2fcb, 0x0384059a587af7e6, 0x02d6400ace6fe610, + 0x029354d896e8e331, 0x00c047ee6dfba65e, 0x0037720542e9d49d}, + {0x02ce9eed7c5e9278, 0x0374ed703e79643b, 0x01316c54c4072006, + 0x005aaa09054b2ee8, 0x002824000c840d57, 0x03d4eba24771ed86, + 0x0189c50aabc3bdae, 0x0338c01541e15510, 0x00466d56e38eed42}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}}, +{{0x007efd8330ad8bd6, 0x02465ed48047710b, 0x0034c6606b215e0c, + 0x016ae30c53cbf839, 0x01fa17bd37161216, 0x018ead4e61ce8ab9, + 0x005482ed5f5dee46, 0x037543755bba1d7f, 0x005e5ac7e70a9d0f}, + {0x0117e1bb2fdcb2a2, 0x03deea36249f40c4, 0x028d09b4a6246cb7, + 0x03524b8855bcf756, 0x023d7d109d5ceb58, 0x0178e43e3223ef9c, + 0x0154536a0c6e966a, 0x037964d1286ee9fe, 0x0199bcd90e125055}, + {1, 0, 0, 0, 0, 0, 0, 0, 0}} +}; + +/* + * select_point selects the |idx|th point from a precomputation table and + * copies it to out. + */ + /* pre_comp below is of the size provided in |size| */ +static void select_point(const limb idx, unsigned int size, + const felem pre_comp[][3], felem out[3]) +{ + unsigned i, j; + limb *outlimbs = &out[0][0]; + memset(outlimbs, 0, 3 * sizeof(felem)); + + for (i = 0; i < size; i++) { + const limb *inlimbs = &pre_comp[i][0][0]; + limb mask = i ^ idx; + mask |= mask >> 4; + mask |= mask >> 2; + mask |= mask >> 1; + mask &= 1; + mask--; + for (j = 0; j < NLIMBS * 3; j++) + outlimbs[j] |= inlimbs[j] & mask; + } +} + +/* get_bit returns the |i|th bit in |in| */ +static char get_bit(const felem_bytearray in, int i) +{ + if (i < 0) + return 0; + return (in[i >> 3] >> (i & 7)) & 1; +} + +/* + * Interleaved point multiplication using precomputed point multiples: The + * small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[], the scalars + * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the + * generator, using certain (large) precomputed multiples in g_pre_comp. + * Output point (X, Y, Z) is stored in x_out, y_out, z_out + */ +static void batch_mul(felem x_out, felem y_out, felem z_out, + const felem_bytearray scalars[], + const unsigned num_points, const u8 *g_scalar, + const int mixed, const felem pre_comp[][17][3], + const felem g_pre_comp[16][3]) +{ + int i, skip; + unsigned num, gen_mul = (g_scalar != NULL); + felem nq[3], tmp[4]; + limb bits; + u8 sign, digit; + + /* set nq to the point at infinity */ + memset(nq, 0, 3 * sizeof(felem)); + + /* + * Loop over all scalars msb-to-lsb, interleaving additions of multiples + * of the generator (last quarter of rounds) and additions of other + * points multiples (every 5th round). + */ + skip = 1; /* save two point operations in the first + * round */ + for (i = (num_points ? 520 : 130); i >= 0; --i) { + /* double */ + if (!skip) + point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + + /* add multiples of the generator */ + if (gen_mul && (i <= 130)) { + bits = get_bit(g_scalar, i + 390) << 3; + if (i < 130) { + bits |= get_bit(g_scalar, i + 260) << 2; + bits |= get_bit(g_scalar, i + 130) << 1; + bits |= get_bit(g_scalar, i); + } + /* select the point to add, in constant time */ + select_point(bits, 16, g_pre_comp, tmp); + if (!skip) { + /* The 1 argument below is for "mixed" */ + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], 1, tmp[0], tmp[1], tmp[2]); + } else { + memcpy(nq, tmp, 3 * sizeof(felem)); + skip = 0; + } + } + + /* do other additions every 5 doublings */ + if (num_points && (i % 5 == 0)) { + /* loop over all scalars */ + for (num = 0; num < num_points; ++num) { + bits = get_bit(scalars[num], i + 4) << 5; + bits |= get_bit(scalars[num], i + 3) << 4; + bits |= get_bit(scalars[num], i + 2) << 3; + bits |= get_bit(scalars[num], i + 1) << 2; + bits |= get_bit(scalars[num], i) << 1; + bits |= get_bit(scalars[num], i - 1); + ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + + /* + * select the point to add or subtract, in constant time + */ + select_point(digit, 17, pre_comp[num], tmp); + felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative + * point */ + copy_conditional(tmp[1], tmp[3], (-(limb) sign)); + + if (!skip) { + point_add(nq[0], nq[1], nq[2], + nq[0], nq[1], nq[2], + mixed, tmp[0], tmp[1], tmp[2]); + } else { + memcpy(nq, tmp, 3 * sizeof(felem)); + skip = 0; + } + } + } + } + felem_assign(x_out, nq[0]); + felem_assign(y_out, nq[1]); + felem_assign(z_out, nq[2]); +} + +/* Precomputation for the group generator. */ +typedef struct { + felem g_pre_comp[16][3]; + int references; +} NISTP521_PRE_COMP; + +const EC_METHOD *EC_GFp_nistp521_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, + ec_GFp_nistp521_group_init, + ec_GFp_simple_group_finish, + ec_GFp_simple_group_clear_finish, + ec_GFp_nist_group_copy, + ec_GFp_nistp521_group_set_curve, + ec_GFp_simple_group_get_curve, + ec_GFp_simple_group_get_degree, + ec_GFp_simple_group_check_discriminant, + ec_GFp_simple_point_init, + ec_GFp_simple_point_finish, + ec_GFp_simple_point_clear_finish, + ec_GFp_simple_point_copy, + ec_GFp_simple_point_set_to_infinity, + ec_GFp_simple_set_Jprojective_coordinates_GFp, + ec_GFp_simple_get_Jprojective_coordinates_GFp, + ec_GFp_simple_point_set_affine_coordinates, + ec_GFp_nistp521_point_get_affine_coordinates, + 0 /* point_set_compressed_coordinates */ , + 0 /* point2oct */ , + 0 /* oct2point */ , + ec_GFp_simple_add, + ec_GFp_simple_dbl, + ec_GFp_simple_invert, + ec_GFp_simple_is_at_infinity, + ec_GFp_simple_is_on_curve, + ec_GFp_simple_cmp, + ec_GFp_simple_make_affine, + ec_GFp_simple_points_make_affine, + ec_GFp_nistp521_points_mul, + ec_GFp_nistp521_precompute_mult, + ec_GFp_nistp521_have_precompute_mult, + ec_GFp_nist_field_mul, + ec_GFp_nist_field_sqr, + 0 /* field_div */ , + 0 /* field_encode */ , + 0 /* field_decode */ , + 0 /* field_set_to_one */ + }; + + return &ret; +} + +/******************************************************************************/ +/* + * FUNCTIONS TO MANAGE PRECOMPUTATION + */ + +static NISTP521_PRE_COMP *nistp521_pre_comp_new() +{ + NISTP521_PRE_COMP *ret = NULL; + ret = (NISTP521_PRE_COMP *) OPENSSL_malloc(sizeof(NISTP521_PRE_COMP)); + if (!ret) { + ECerr(EC_F_NISTP521_PRE_COMP_NEW, ERR_R_MALLOC_FAILURE); + return ret; + } + memset(ret->g_pre_comp, 0, sizeof(ret->g_pre_comp)); + ret->references = 1; + return ret; +} + +static void *nistp521_pre_comp_dup(void *src_) +{ + NISTP521_PRE_COMP *src = src_; + + /* no need to actually copy, these objects never change! */ + CRYPTO_add(&src->references, 1, CRYPTO_LOCK_EC_PRE_COMP); + + return src_; +} + +static void nistp521_pre_comp_free(void *pre_) +{ + int i; + NISTP521_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + OPENSSL_free(pre); +} + +static void nistp521_pre_comp_clear_free(void *pre_) +{ + int i; + NISTP521_PRE_COMP *pre = pre_; + + if (!pre) + return; + + i = CRYPTO_add(&pre->references, -1, CRYPTO_LOCK_EC_PRE_COMP); + if (i > 0) + return; + + OPENSSL_cleanse(pre, sizeof(*pre)); + OPENSSL_free(pre); +} + +/******************************************************************************/ +/* + * OPENSSL EC_METHOD FUNCTIONS + */ + +int ec_GFp_nistp521_group_init(EC_GROUP *group) +{ + int ret; + ret = ec_GFp_simple_group_init(group); + group->a_is_minus3 = 1; + return ret; +} + +int ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p, + const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *curve_p, *curve_a, *curve_b; + + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((curve_p = BN_CTX_get(ctx)) == NULL) || + ((curve_a = BN_CTX_get(ctx)) == NULL) || + ((curve_b = BN_CTX_get(ctx)) == NULL)) + goto err; + BN_bin2bn(nistp521_curve_params[0], sizeof(felem_bytearray), curve_p); + BN_bin2bn(nistp521_curve_params[1], sizeof(felem_bytearray), curve_a); + BN_bin2bn(nistp521_curve_params[2], sizeof(felem_bytearray), curve_b); + if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) { + ECerr(EC_F_EC_GFP_NISTP521_GROUP_SET_CURVE, + EC_R_WRONG_CURVE_PARAMETERS); + goto err; + } + group->field_mod_func = BN_nist_mod_521; + ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +/* + * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = + * (X/Z^2, Y/Z^3) + */ +int ec_GFp_nistp521_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) +{ + felem z1, z2, x_in, y_in, x_out, y_out; + largefelem tmp; + + if (EC_POINT_is_at_infinity(group, point)) { + ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, + EC_R_POINT_AT_INFINITY); + return 0; + } + if ((!BN_to_felem(x_in, &point->X)) || (!BN_to_felem(y_in, &point->Y)) || + (!BN_to_felem(z1, &point->Z))) + return 0; + felem_inv(z2, z1); + felem_square(tmp, z2); + felem_reduce(z1, tmp); + felem_mul(tmp, x_in, z1); + felem_reduce(x_in, tmp); + felem_contract(x_out, x_in); + if (x != NULL) { + if (!felem_to_BN(x, x_out)) { + ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, + ERR_R_BN_LIB); + return 0; + } + } + felem_mul(tmp, z1, z2); + felem_reduce(z1, tmp); + felem_mul(tmp, y_in, z1); + felem_reduce(y_in, tmp); + felem_contract(y_out, y_in); + if (y != NULL) { + if (!felem_to_BN(y, y_out)) { + ECerr(EC_F_EC_GFP_NISTP521_POINT_GET_AFFINE_COORDINATES, + ERR_R_BN_LIB); + return 0; + } + } + return 1; +} + +/* points below is of size |num|, and tmp_felems is of size |num+1/ */ +static void make_points_affine(size_t num, felem points[][3], + felem tmp_felems[]) +{ + /* + * Runs in constant time, unless an input is the point at infinity (which + * normally shouldn't happen). + */ + ec_GFp_nistp_points_make_affine_internal(num, + points, + sizeof(felem), + tmp_felems, + (void (*)(void *))felem_one, + (int (*)(const void *)) + felem_is_zero_int, + (void (*)(void *, const void *)) + felem_assign, + (void (*)(void *, const void *)) + felem_square_reduce, (void (*) + (void *, + const void + *, + const void + *)) + felem_mul_reduce, + (void (*)(void *, const void *)) + felem_inv, + (void (*)(void *, const void *)) + felem_contract); +} + +/* + * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL + * values Result is stored in r (r can equal one of the inputs). + */ +int ec_GFp_nistp521_points_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *scalar, size_t num, + const EC_POINT *points[], + const BIGNUM *scalars[], BN_CTX *ctx) +{ + int ret = 0; + int j; + int mixed = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y, *z, *tmp_scalar; + felem_bytearray g_secret; + felem_bytearray *secrets = NULL; + felem(*pre_comp)[17][3] = NULL; + felem *tmp_felems = NULL; + felem_bytearray tmp; + unsigned i, num_bytes; + int have_pre_comp = 0; + size_t num_points = num; + felem x_in, y_in, z_in, x_out, y_out, z_out; + NISTP521_PRE_COMP *pre = NULL; + felem(*g_pre_comp)[3] = NULL; + EC_POINT *generator = NULL; + const EC_POINT *p = NULL; + const BIGNUM *p_scalar = NULL; + + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((x = BN_CTX_get(ctx)) == NULL) || + ((y = BN_CTX_get(ctx)) == NULL) || + ((z = BN_CTX_get(ctx)) == NULL) || + ((tmp_scalar = BN_CTX_get(ctx)) == NULL)) + goto err; + + if (scalar != NULL) { + pre = EC_EX_DATA_get_data(group->extra_data, + nistp521_pre_comp_dup, + nistp521_pre_comp_free, + nistp521_pre_comp_clear_free); + if (pre) + /* we have precomputation, try to use it */ + g_pre_comp = &pre->g_pre_comp[0]; + else + /* try to use the standard precomputation */ + g_pre_comp = (felem(*)[3]) gmul; + generator = EC_POINT_new(group); + if (generator == NULL) + goto err; + /* get the generator from precomputation */ + if (!felem_to_BN(x, g_pre_comp[1][0]) || + !felem_to_BN(y, g_pre_comp[1][1]) || + !felem_to_BN(z, g_pre_comp[1][2])) { + ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + if (!EC_POINT_set_Jprojective_coordinates_GFp(group, + generator, x, y, z, + ctx)) + goto err; + if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) + /* precomputation matches generator */ + have_pre_comp = 1; + else + /* + * we don't have valid precomputation: treat the generator as a + * random point + */ + num_points++; + } + + if (num_points > 0) { + if (num_points >= 2) { + /* + * unless we precompute multiples for just one point, converting + * those into affine form is time well spent + */ + mixed = 1; + } + secrets = OPENSSL_malloc(num_points * sizeof(felem_bytearray)); + pre_comp = OPENSSL_malloc(num_points * 17 * 3 * sizeof(felem)); + if (mixed) + tmp_felems = + OPENSSL_malloc((num_points * 17 + 1) * sizeof(felem)); + if ((secrets == NULL) || (pre_comp == NULL) + || (mixed && (tmp_felems == NULL))) { + ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * we treat NULL scalars as 0, and NULL points as points at infinity, + * i.e., they contribute nothing to the linear combination + */ + memset(secrets, 0, num_points * sizeof(felem_bytearray)); + memset(pre_comp, 0, num_points * 17 * 3 * sizeof(felem)); + for (i = 0; i < num_points; ++i) { + if (i == num) + /* + * we didn't have a valid precomputation, so we pick the + * generator + */ + { + p = EC_GROUP_get0_generator(group); + p_scalar = scalar; + } else + /* the i^th point */ + { + p = points[i]; + p_scalar = scalars[i]; + } + if ((p_scalar != NULL) && (p != NULL)) { + /* reduce scalar to 0 <= scalar < 2^521 */ + if ((BN_num_bits(p_scalar) > 521) + || (BN_is_negative(p_scalar))) { + /* + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(tmp_scalar, p_scalar, &group->order, ctx)) { + ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + num_bytes = BN_bn2bin(tmp_scalar, tmp); + } else + num_bytes = BN_bn2bin(p_scalar, tmp); + flip_endian(secrets[i], tmp, num_bytes); + /* precompute multiples */ + if ((!BN_to_felem(x_out, &p->X)) || + (!BN_to_felem(y_out, &p->Y)) || + (!BN_to_felem(z_out, &p->Z))) + goto err; + memcpy(pre_comp[i][1][0], x_out, sizeof(felem)); + memcpy(pre_comp[i][1][1], y_out, sizeof(felem)); + memcpy(pre_comp[i][1][2], z_out, sizeof(felem)); + for (j = 2; j <= 16; ++j) { + if (j & 1) { + point_add(pre_comp[i][j][0], pre_comp[i][j][1], + pre_comp[i][j][2], pre_comp[i][1][0], + pre_comp[i][1][1], pre_comp[i][1][2], 0, + pre_comp[i][j - 1][0], + pre_comp[i][j - 1][1], + pre_comp[i][j - 1][2]); + } else { + point_double(pre_comp[i][j][0], pre_comp[i][j][1], + pre_comp[i][j][2], pre_comp[i][j / 2][0], + pre_comp[i][j / 2][1], + pre_comp[i][j / 2][2]); + } + } + } + } + if (mixed) + make_points_affine(num_points * 17, pre_comp[0], tmp_felems); + } + + /* the scalar for the generator */ + if ((scalar != NULL) && (have_pre_comp)) { + memset(g_secret, 0, sizeof(g_secret)); + /* reduce scalar to 0 <= scalar < 2^521 */ + if ((BN_num_bits(scalar) > 521) || (BN_is_negative(scalar))) { + /* + * this is an unusual input, and we don't guarantee + * constant-timeness + */ + if (!BN_nnmod(tmp_scalar, scalar, &group->order, ctx)) { + ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + num_bytes = BN_bn2bin(tmp_scalar, tmp); + } else + num_bytes = BN_bn2bin(scalar, tmp); + flip_endian(g_secret, tmp, num_bytes); + /* do the multiplication with generator precomputation */ + batch_mul(x_out, y_out, z_out, + (const felem_bytearray(*))secrets, num_points, + g_secret, + mixed, (const felem(*)[17][3])pre_comp, + (const felem(*)[3])g_pre_comp); + } else + /* do the multiplication without generator precomputation */ + batch_mul(x_out, y_out, z_out, + (const felem_bytearray(*))secrets, num_points, + NULL, mixed, (const felem(*)[17][3])pre_comp, NULL); + /* reduce the output to its unique minimal representation */ + felem_contract(x_in, x_out); + felem_contract(y_in, y_out); + felem_contract(z_in, z_out); + if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) || + (!felem_to_BN(z, z_in))) { + ECerr(EC_F_EC_GFP_NISTP521_POINTS_MUL, ERR_R_BN_LIB); + goto err; + } + ret = EC_POINT_set_Jprojective_coordinates_GFp(group, r, x, y, z, ctx); + + err: + BN_CTX_end(ctx); + if (generator != NULL) + EC_POINT_free(generator); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (secrets != NULL) + OPENSSL_free(secrets); + if (pre_comp != NULL) + OPENSSL_free(pre_comp); + if (tmp_felems != NULL) + OPENSSL_free(tmp_felems); + return ret; +} + +int ec_GFp_nistp521_precompute_mult(EC_GROUP *group, BN_CTX *ctx) +{ + int ret = 0; + NISTP521_PRE_COMP *pre = NULL; + int i, j; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y; + EC_POINT *generator = NULL; + felem tmp_felems[16]; + + /* throw away old precomputation */ + EC_EX_DATA_free_data(&group->extra_data, nistp521_pre_comp_dup, + nistp521_pre_comp_free, + nistp521_pre_comp_clear_free); + if (ctx == NULL) + if ((ctx = new_ctx = BN_CTX_new()) == NULL) + return 0; + BN_CTX_start(ctx); + if (((x = BN_CTX_get(ctx)) == NULL) || ((y = BN_CTX_get(ctx)) == NULL)) + goto err; + /* get the generator */ + if (group->generator == NULL) + goto err; + generator = EC_POINT_new(group); + if (generator == NULL) + goto err; + BN_bin2bn(nistp521_curve_params[3], sizeof(felem_bytearray), x); + BN_bin2bn(nistp521_curve_params[4], sizeof(felem_bytearray), y); + if (!EC_POINT_set_affine_coordinates_GFp(group, generator, x, y, ctx)) + goto err; + if ((pre = nistp521_pre_comp_new()) == NULL) + goto err; + /* + * if the generator is the standard one, use built-in precomputation + */ + if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) { + memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp)); + ret = 1; + goto err; + } + if ((!BN_to_felem(pre->g_pre_comp[1][0], &group->generator->X)) || + (!BN_to_felem(pre->g_pre_comp[1][1], &group->generator->Y)) || + (!BN_to_felem(pre->g_pre_comp[1][2], &group->generator->Z))) + goto err; + /* compute 2^130*G, 2^260*G, 2^390*G */ + for (i = 1; i <= 4; i <<= 1) { + point_double(pre->g_pre_comp[2 * i][0], pre->g_pre_comp[2 * i][1], + pre->g_pre_comp[2 * i][2], pre->g_pre_comp[i][0], + pre->g_pre_comp[i][1], pre->g_pre_comp[i][2]); + for (j = 0; j < 129; ++j) { + point_double(pre->g_pre_comp[2 * i][0], + pre->g_pre_comp[2 * i][1], + pre->g_pre_comp[2 * i][2], + pre->g_pre_comp[2 * i][0], + pre->g_pre_comp[2 * i][1], + pre->g_pre_comp[2 * i][2]); + } + } + /* g_pre_comp[0] is the point at infinity */ + memset(pre->g_pre_comp[0], 0, sizeof(pre->g_pre_comp[0])); + /* the remaining multiples */ + /* 2^130*G + 2^260*G */ + point_add(pre->g_pre_comp[6][0], pre->g_pre_comp[6][1], + pre->g_pre_comp[6][2], pre->g_pre_comp[4][0], + pre->g_pre_comp[4][1], pre->g_pre_comp[4][2], + 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1], + pre->g_pre_comp[2][2]); + /* 2^130*G + 2^390*G */ + point_add(pre->g_pre_comp[10][0], pre->g_pre_comp[10][1], + pre->g_pre_comp[10][2], pre->g_pre_comp[8][0], + pre->g_pre_comp[8][1], pre->g_pre_comp[8][2], + 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1], + pre->g_pre_comp[2][2]); + /* 2^260*G + 2^390*G */ + point_add(pre->g_pre_comp[12][0], pre->g_pre_comp[12][1], + pre->g_pre_comp[12][2], pre->g_pre_comp[8][0], + pre->g_pre_comp[8][1], pre->g_pre_comp[8][2], + 0, pre->g_pre_comp[4][0], pre->g_pre_comp[4][1], + pre->g_pre_comp[4][2]); + /* 2^130*G + 2^260*G + 2^390*G */ + point_add(pre->g_pre_comp[14][0], pre->g_pre_comp[14][1], + pre->g_pre_comp[14][2], pre->g_pre_comp[12][0], + pre->g_pre_comp[12][1], pre->g_pre_comp[12][2], + 0, pre->g_pre_comp[2][0], pre->g_pre_comp[2][1], + pre->g_pre_comp[2][2]); + for (i = 1; i < 8; ++i) { + /* odd multiples: add G */ + point_add(pre->g_pre_comp[2 * i + 1][0], + pre->g_pre_comp[2 * i + 1][1], + pre->g_pre_comp[2 * i + 1][2], pre->g_pre_comp[2 * i][0], + pre->g_pre_comp[2 * i][1], pre->g_pre_comp[2 * i][2], 0, + pre->g_pre_comp[1][0], pre->g_pre_comp[1][1], + pre->g_pre_comp[1][2]); + } + make_points_affine(15, &(pre->g_pre_comp[1]), tmp_felems); + + if (!EC_EX_DATA_set_data(&group->extra_data, pre, nistp521_pre_comp_dup, + nistp521_pre_comp_free, + nistp521_pre_comp_clear_free)) + goto err; + ret = 1; + pre = NULL; + err: + BN_CTX_end(ctx); + if (generator != NULL) + EC_POINT_free(generator); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (pre) + nistp521_pre_comp_free(pre); + return ret; +} + +int ec_GFp_nistp521_have_precompute_mult(const EC_GROUP *group) +{ + if (EC_EX_DATA_get_data(group->extra_data, nistp521_pre_comp_dup, + nistp521_pre_comp_free, + nistp521_pre_comp_clear_free) + != NULL) + return 1; + else + return 0; +} + +#else +static void *dummy = &dummy; +#endif diff --git a/libs/openssl/crypto/ec/ecp_nistputil.c b/libs/openssl/crypto/ec/ecp_nistputil.c new file mode 100644 index 00000000..8ba2a25e --- /dev/null +++ b/libs/openssl/crypto/ec/ecp_nistputil.c @@ -0,0 +1,218 @@ +/* crypto/ec/ecp_nistputil.c */ +/* + * Written by Bodo Moeller for the OpenSSL project. + */ +/* Copyright 2011 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + +/* + * Common utility functions for ecp_nistp224.c, ecp_nistp256.c, ecp_nistp521.c. + */ + +# include +# include "ec_lcl.h" + +/* + * Convert an array of points into affine coordinates. (If the point at + * infinity is found (Z = 0), it remains unchanged.) This function is + * essentially an equivalent to EC_POINTs_make_affine(), but works with the + * internal representation of points as used by ecp_nistp###.c rather than + * with (BIGNUM-based) EC_POINT data structures. point_array is the + * input/output buffer ('num' points in projective form, i.e. three + * coordinates each), based on an internal representation of field elements + * of size 'felem_size'. tmp_felems needs to point to a temporary array of + * 'num'+1 field elements for storage of intermediate values. + */ +void ec_GFp_nistp_points_make_affine_internal(size_t num, void *point_array, + size_t felem_size, + void *tmp_felems, + void (*felem_one) (void *out), + int (*felem_is_zero) (const void + *in), + void (*felem_assign) (void *out, + const void + *in), + void (*felem_square) (void *out, + const void + *in), + void (*felem_mul) (void *out, + const void + *in1, + const void + *in2), + void (*felem_inv) (void *out, + const void + *in), + void (*felem_contract) (void + *out, + const + void + *in)) +{ + int i = 0; + +# define tmp_felem(I) (&((char *)tmp_felems)[(I) * felem_size]) +# define X(I) (&((char *)point_array)[3*(I) * felem_size]) +# define Y(I) (&((char *)point_array)[(3*(I) + 1) * felem_size]) +# define Z(I) (&((char *)point_array)[(3*(I) + 2) * felem_size]) + + if (!felem_is_zero(Z(0))) + felem_assign(tmp_felem(0), Z(0)); + else + felem_one(tmp_felem(0)); + for (i = 1; i < (int)num; i++) { + if (!felem_is_zero(Z(i))) + felem_mul(tmp_felem(i), tmp_felem(i - 1), Z(i)); + else + felem_assign(tmp_felem(i), tmp_felem(i - 1)); + } + /* + * Now each tmp_felem(i) is the product of Z(0) .. Z(i), skipping any + * zero-valued factors: if Z(i) = 0, we essentially pretend that Z(i) = 1 + */ + + felem_inv(tmp_felem(num - 1), tmp_felem(num - 1)); + for (i = num - 1; i >= 0; i--) { + if (i > 0) + /* + * tmp_felem(i-1) is the product of Z(0) .. Z(i-1), tmp_felem(i) + * is the inverse of the product of Z(0) .. Z(i) + */ + /* 1/Z(i) */ + felem_mul(tmp_felem(num), tmp_felem(i - 1), tmp_felem(i)); + else + felem_assign(tmp_felem(num), tmp_felem(0)); /* 1/Z(0) */ + + if (!felem_is_zero(Z(i))) { + if (i > 0) + /* + * For next iteration, replace tmp_felem(i-1) by its inverse + */ + felem_mul(tmp_felem(i - 1), tmp_felem(i), Z(i)); + + /* + * Convert point (X, Y, Z) into affine form (X/(Z^2), Y/(Z^3), 1) + */ + felem_square(Z(i), tmp_felem(num)); /* 1/(Z^2) */ + felem_mul(X(i), X(i), Z(i)); /* X/(Z^2) */ + felem_mul(Z(i), Z(i), tmp_felem(num)); /* 1/(Z^3) */ + felem_mul(Y(i), Y(i), Z(i)); /* Y/(Z^3) */ + felem_contract(X(i), X(i)); + felem_contract(Y(i), Y(i)); + felem_one(Z(i)); + } else { + if (i > 0) + /* + * For next iteration, replace tmp_felem(i-1) by its inverse + */ + felem_assign(tmp_felem(i - 1), tmp_felem(i)); + } + } +} + +/*- + * This function looks at 5+1 scalar bits (5 current, 1 adjacent less + * significant bit), and recodes them into a signed digit for use in fast point + * multiplication: the use of signed rather than unsigned digits means that + * fewer points need to be precomputed, given that point inversion is easy + * (a precomputed point dP makes -dP available as well). + * + * BACKGROUND: + * + * Signed digits for multiplication were introduced by Booth ("A signed binary + * multiplication technique", Quart. Journ. Mech. and Applied Math., vol. IV, + * pt. 2 (1951), pp. 236-240), in that case for multiplication of integers. + * Booth's original encoding did not generally improve the density of nonzero + * digits over the binary representation, and was merely meant to simplify the + * handling of signed factors given in two's complement; but it has since been + * shown to be the basis of various signed-digit representations that do have + * further advantages, including the wNAF, using the following general approach: + * + * (1) Given a binary representation + * + * b_k ... b_2 b_1 b_0, + * + * of a nonnegative integer (b_k in {0, 1}), rewrite it in digits 0, 1, -1 + * by using bit-wise subtraction as follows: + * + * b_k b_(k-1) ... b_2 b_1 b_0 + * - b_k ... b_3 b_2 b_1 b_0 + * ------------------------------------- + * s_k b_(k-1) ... s_3 s_2 s_1 s_0 + * + * A left-shift followed by subtraction of the original value yields a new + * representation of the same value, using signed bits s_i = b_(i+1) - b_i. + * This representation from Booth's paper has since appeared in the + * literature under a variety of different names including "reversed binary + * form", "alternating greedy expansion", "mutual opposite form", and + * "sign-alternating {+-1}-representation". + * + * An interesting property is that among the nonzero bits, values 1 and -1 + * strictly alternate. + * + * (2) Various window schemes can be applied to the Booth representation of + * integers: for example, right-to-left sliding windows yield the wNAF + * (a signed-digit encoding independently discovered by various researchers + * in the 1990s), and left-to-right sliding windows yield a left-to-right + * equivalent of the wNAF (independently discovered by various researchers + * around 2004). + * + * To prevent leaking information through side channels in point multiplication, + * we need to recode the given integer into a regular pattern: sliding windows + * as in wNAFs won't do, we need their fixed-window equivalent -- which is a few + * decades older: we'll be using the so-called "modified Booth encoding" due to + * MacSorley ("High-speed arithmetic in binary computers", Proc. IRE, vol. 49 + * (1961), pp. 67-91), in a radix-2^5 setting. That is, we always combine five + * signed bits into a signed digit: + * + * s_(4j + 4) s_(4j + 3) s_(4j + 2) s_(4j + 1) s_(4j) + * + * The sign-alternating property implies that the resulting digit values are + * integers from -16 to 16. + * + * Of course, we don't actually need to compute the signed digits s_i as an + * intermediate step (that's just a nice way to see how this scheme relates + * to the wNAF): a direct computation obtains the recoded digit from the + * six bits b_(4j + 4) ... b_(4j - 1). + * + * This function takes those five bits as an integer (0 .. 63), writing the + * recoded digit to *sign (0 for positive, 1 for negative) and *digit (absolute + * value, in the range 0 .. 8). Note that this integer essentially provides the + * input bits "shifted to the left" by one position: for example, the input to + * compute the least significant recoded digit, given that there's no bit b_-1, + * has to be b_4 b_3 b_2 b_1 b_0 0. + * + */ +void ec_GFp_nistp_recode_scalar_bits(unsigned char *sign, + unsigned char *digit, unsigned char in) +{ + unsigned char s, d; + + s = ~((in >> 5) - 1); /* sets all bits to MSB(in), 'in' seen as + * 6-bit value */ + d = (1 << 6) - in - 1; + d = (d & s) | (in & ~s); + d = (d >> 1) + (d & 1); + + *sign = s & 1; + *digit = d; +} +#else +static void *dummy = &dummy; +#endif diff --git a/libs/openssl/crypto/ec/ecp_oct.c b/libs/openssl/crypto/ec/ecp_oct.c new file mode 100644 index 00000000..1bc3f39a --- /dev/null +++ b/libs/openssl/crypto/ec/ecp_oct.c @@ -0,0 +1,428 @@ +/* crypto/ec/ecp_oct.c */ +/* + * Includes code written by Lenka Fibikova + * for the OpenSSL project. Includes code written by Bodo Moeller for the + * OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions of this software developed by SUN MICROSYSTEMS, INC., + * and contributed to the OpenSSL project. + */ + +#include +#include + +#include "ec_lcl.h" + +int ec_GFp_simple_set_compressed_coordinates(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x_, int y_bit, + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BIGNUM *tmp1, *tmp2, *x, *y; + int ret = 0; + + /* clear error queue */ + ERR_clear_error(); + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + y_bit = (y_bit != 0); + + BN_CTX_start(ctx); + tmp1 = BN_CTX_get(ctx); + tmp2 = BN_CTX_get(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto err; + + /*- + * Recover y. We have a Weierstrass equation + * y^2 = x^3 + a*x + b, + * so y is one of the square roots of x^3 + a*x + b. + */ + + /* tmp1 := x^3 */ + if (!BN_nnmod(x, x_, &group->field, ctx)) + goto err; + if (group->meth->field_decode == 0) { + /* field_{sqr,mul} work on standard representation */ + if (!group->meth->field_sqr(group, tmp2, x_, ctx)) + goto err; + if (!group->meth->field_mul(group, tmp1, tmp2, x_, ctx)) + goto err; + } else { + if (!BN_mod_sqr(tmp2, x_, &group->field, ctx)) + goto err; + if (!BN_mod_mul(tmp1, tmp2, x_, &group->field, ctx)) + goto err; + } + + /* tmp1 := tmp1 + a*x */ + if (group->a_is_minus3) { + if (!BN_mod_lshift1_quick(tmp2, x, &group->field)) + goto err; + if (!BN_mod_add_quick(tmp2, tmp2, x, &group->field)) + goto err; + if (!BN_mod_sub_quick(tmp1, tmp1, tmp2, &group->field)) + goto err; + } else { + if (group->meth->field_decode) { + if (!group->meth->field_decode(group, tmp2, &group->a, ctx)) + goto err; + if (!BN_mod_mul(tmp2, tmp2, x, &group->field, ctx)) + goto err; + } else { + /* field_mul works on standard representation */ + if (!group->meth->field_mul(group, tmp2, &group->a, x, ctx)) + goto err; + } + + if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) + goto err; + } + + /* tmp1 := tmp1 + b */ + if (group->meth->field_decode) { + if (!group->meth->field_decode(group, tmp2, &group->b, ctx)) + goto err; + if (!BN_mod_add_quick(tmp1, tmp1, tmp2, &group->field)) + goto err; + } else { + if (!BN_mod_add_quick(tmp1, tmp1, &group->b, &group->field)) + goto err; + } + + if (!BN_mod_sqrt(y, tmp1, &group->field, ctx)) { + unsigned long err = ERR_peek_last_error(); + + if (ERR_GET_LIB(err) == ERR_LIB_BN + && ERR_GET_REASON(err) == BN_R_NOT_A_SQUARE) { + ERR_clear_error(); + ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, + EC_R_INVALID_COMPRESSED_POINT); + } else + ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, + ERR_R_BN_LIB); + goto err; + } + + if (y_bit != BN_is_odd(y)) { + if (BN_is_zero(y)) { + int kron; + + kron = BN_kronecker(x, &group->field, ctx); + if (kron == -2) + goto err; + + if (kron == 1) + ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, + EC_R_INVALID_COMPRESSION_BIT); + else + /* + * BN_mod_sqrt() should have cought this error (not a square) + */ + ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, + EC_R_INVALID_COMPRESSED_POINT); + goto err; + } + if (!BN_usub(y, &group->field, y)) + goto err; + } + if (y_bit != BN_is_odd(y)) { + ECerr(EC_F_EC_GFP_SIMPLE_SET_COMPRESSED_COORDINATES, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) + goto err; + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +size_t ec_GFp_simple_point2oct(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, + unsigned char *buf, size_t len, BN_CTX *ctx) +{ + size_t ret; + BN_CTX *new_ctx = NULL; + int used_ctx = 0; + BIGNUM *x, *y; + size_t field_len, i, skip; + + if ((form != POINT_CONVERSION_COMPRESSED) + && (form != POINT_CONVERSION_UNCOMPRESSED) + && (form != POINT_CONVERSION_HYBRID)) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_INVALID_FORM); + goto err; + } + + if (EC_POINT_is_at_infinity(group, point)) { + /* encodes to a single 0 octet */ + if (buf != NULL) { + if (len < 1) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); + return 0; + } + buf[0] = 0; + } + return 1; + } + + /* ret := required output buffer length */ + field_len = BN_num_bytes(&group->field); + ret = + (form == + POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; + + /* if 'buf' is NULL, just return required length */ + if (buf != NULL) { + if (len < ret) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, EC_R_BUFFER_TOO_SMALL); + goto err; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + used_ctx = 1; + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto err; + + if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) + goto err; + + if ((form == POINT_CONVERSION_COMPRESSED + || form == POINT_CONVERSION_HYBRID) && BN_is_odd(y)) + buf[0] = form + 1; + else + buf[0] = form; + + i = 1; + + skip = field_len - BN_num_bytes(x); + if (skip > field_len) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + while (skip > 0) { + buf[i++] = 0; + skip--; + } + skip = BN_bn2bin(x, buf + i); + i += skip; + if (i != 1 + field_len) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (form == POINT_CONVERSION_UNCOMPRESSED + || form == POINT_CONVERSION_HYBRID) { + skip = field_len - BN_num_bytes(y); + if (skip > field_len) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + while (skip > 0) { + buf[i++] = 0; + skip--; + } + skip = BN_bn2bin(y, buf + i); + i += skip; + } + + if (i != ret) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT2OCT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (used_ctx) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; + + err: + if (used_ctx) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return 0; +} + +int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, + const unsigned char *buf, size_t len, BN_CTX *ctx) +{ + point_conversion_form_t form; + int y_bit; + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y; + size_t field_len, enc_len; + int ret = 0; + + if (len == 0) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_BUFFER_TOO_SMALL); + return 0; + } + form = buf[0]; + y_bit = form & 1; + form = form & ~1U; + if ((form != 0) && (form != POINT_CONVERSION_COMPRESSED) + && (form != POINT_CONVERSION_UNCOMPRESSED) + && (form != POINT_CONVERSION_HYBRID)) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + if ((form == 0 || form == POINT_CONVERSION_UNCOMPRESSED) && y_bit) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + + if (form == 0) { + if (len != 1) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + + return EC_POINT_set_to_infinity(group, point); + } + + field_len = BN_num_bytes(&group->field); + enc_len = + (form == + POINT_CONVERSION_COMPRESSED) ? 1 + field_len : 1 + 2 * field_len; + + if (len != enc_len) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + return 0; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto err; + + if (!BN_bin2bn(buf + 1, field_len, x)) + goto err; + if (BN_ucmp(x, &group->field) >= 0) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + goto err; + } + + if (form == POINT_CONVERSION_COMPRESSED) { + if (!EC_POINT_set_compressed_coordinates_GFp + (group, point, x, y_bit, ctx)) + goto err; + } else { + if (!BN_bin2bn(buf + 1 + field_len, field_len, y)) + goto err; + if (BN_ucmp(y, &group->field) >= 0) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + goto err; + } + if (form == POINT_CONVERSION_HYBRID) { + if (y_bit != BN_is_odd(y)) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_INVALID_ENCODING); + goto err; + } + } + + if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) + goto err; + } + + /* test required by X9.62 */ + if (EC_POINT_is_on_curve(group, point, ctx) <= 0) { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} diff --git a/libs/openssl/crypto/ec/ecp_smpl.c b/libs/openssl/crypto/ec/ecp_smpl.c new file mode 100644 index 00000000..2b848216 --- /dev/null +++ b/libs/openssl/crypto/ec/ecp_smpl.c @@ -0,0 +1,1418 @@ +/* crypto/ec/ecp_smpl.c */ +/* + * Includes code written by Lenka Fibikova + * for the OpenSSL project. Includes code written by Bodo Moeller for the + * OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * Portions of this software developed by SUN MICROSYSTEMS, INC., + * and contributed to the OpenSSL project. + */ + +#include +#include + +#ifdef OPENSSL_FIPS +# include +#endif + +#include "ec_lcl.h" + +const EC_METHOD *EC_GFp_simple_method(void) +{ + static const EC_METHOD ret = { + EC_FLAGS_DEFAULT_OCT, + NID_X9_62_prime_field, + ec_GFp_simple_group_init, + ec_GFp_simple_group_finish, + ec_GFp_simple_group_clear_finish, + ec_GFp_simple_group_copy, + ec_GFp_simple_group_set_curve, + ec_GFp_simple_group_get_curve, + ec_GFp_simple_group_get_degree, + ec_GFp_simple_group_check_discriminant, + ec_GFp_simple_point_init, + ec_GFp_simple_point_finish, + ec_GFp_simple_point_clear_finish, + ec_GFp_simple_point_copy, + ec_GFp_simple_point_set_to_infinity, + ec_GFp_simple_set_Jprojective_coordinates_GFp, + ec_GFp_simple_get_Jprojective_coordinates_GFp, + ec_GFp_simple_point_set_affine_coordinates, + ec_GFp_simple_point_get_affine_coordinates, + 0, 0, 0, + ec_GFp_simple_add, + ec_GFp_simple_dbl, + ec_GFp_simple_invert, + ec_GFp_simple_is_at_infinity, + ec_GFp_simple_is_on_curve, + ec_GFp_simple_cmp, + ec_GFp_simple_make_affine, + ec_GFp_simple_points_make_affine, + 0 /* mul */ , + 0 /* precompute_mult */ , + 0 /* have_precompute_mult */ , + ec_GFp_simple_field_mul, + ec_GFp_simple_field_sqr, + 0 /* field_div */ , + 0 /* field_encode */ , + 0 /* field_decode */ , + 0 /* field_set_to_one */ + }; + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return fips_ec_gfp_simple_method(); +#endif + + return &ret; +} + +/* + * Most method functions in this file are designed to work with + * non-trivial representations of field elements if necessary + * (see ecp_mont.c): while standard modular addition and subtraction + * are used, the field_mul and field_sqr methods will be used for + * multiplication, and field_encode and field_decode (if defined) + * will be used for converting between representations. + * + * Functions ec_GFp_simple_points_make_affine() and + * ec_GFp_simple_point_get_affine_coordinates() specifically assume + * that if a non-trivial representation is used, it is a Montgomery + * representation (i.e. 'encoding' means multiplying by some factor R). + */ + +int ec_GFp_simple_group_init(EC_GROUP *group) +{ + BN_init(&group->field); + BN_init(&group->a); + BN_init(&group->b); + group->a_is_minus3 = 0; + return 1; +} + +void ec_GFp_simple_group_finish(EC_GROUP *group) +{ + BN_free(&group->field); + BN_free(&group->a); + BN_free(&group->b); +} + +void ec_GFp_simple_group_clear_finish(EC_GROUP *group) +{ + BN_clear_free(&group->field); + BN_clear_free(&group->a); + BN_clear_free(&group->b); +} + +int ec_GFp_simple_group_copy(EC_GROUP *dest, const EC_GROUP *src) +{ + if (!BN_copy(&dest->field, &src->field)) + return 0; + if (!BN_copy(&dest->a, &src->a)) + return 0; + if (!BN_copy(&dest->b, &src->b)) + return 0; + + dest->a_is_minus3 = src->a_is_minus3; + + return 1; +} + +int ec_GFp_simple_group_set_curve(EC_GROUP *group, + const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *new_ctx = NULL; + BIGNUM *tmp_a; + + /* p must be a prime > 3 */ + if (BN_num_bits(p) <= 2 || !BN_is_odd(p)) { + ECerr(EC_F_EC_GFP_SIMPLE_GROUP_SET_CURVE, EC_R_INVALID_FIELD); + return 0; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + tmp_a = BN_CTX_get(ctx); + if (tmp_a == NULL) + goto err; + + /* group->field */ + if (!BN_copy(&group->field, p)) + goto err; + BN_set_negative(&group->field, 0); + + /* group->a */ + if (!BN_nnmod(tmp_a, a, p, ctx)) + goto err; + if (group->meth->field_encode) { + if (!group->meth->field_encode(group, &group->a, tmp_a, ctx)) + goto err; + } else if (!BN_copy(&group->a, tmp_a)) + goto err; + + /* group->b */ + if (!BN_nnmod(&group->b, b, p, ctx)) + goto err; + if (group->meth->field_encode) + if (!group->meth->field_encode(group, &group->b, &group->b, ctx)) + goto err; + + /* group->a_is_minus3 */ + if (!BN_add_word(tmp_a, 3)) + goto err; + group->a_is_minus3 = (0 == BN_cmp(tmp_a, &group->field)); + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_group_get_curve(const EC_GROUP *group, BIGNUM *p, BIGNUM *a, + BIGNUM *b, BN_CTX *ctx) +{ + int ret = 0; + BN_CTX *new_ctx = NULL; + + if (p != NULL) { + if (!BN_copy(p, &group->field)) + return 0; + } + + if (a != NULL || b != NULL) { + if (group->meth->field_decode) { + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + if (a != NULL) { + if (!group->meth->field_decode(group, a, &group->a, ctx)) + goto err; + } + if (b != NULL) { + if (!group->meth->field_decode(group, b, &group->b, ctx)) + goto err; + } + } else { + if (a != NULL) { + if (!BN_copy(a, &group->a)) + goto err; + } + if (b != NULL) { + if (!BN_copy(b, &group->b)) + goto err; + } + } + } + + ret = 1; + + err: + if (new_ctx) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_group_get_degree(const EC_GROUP *group) +{ + return BN_num_bits(&group->field); +} + +int ec_GFp_simple_group_check_discriminant(const EC_GROUP *group, BN_CTX *ctx) +{ + int ret = 0; + BIGNUM *a, *b, *order, *tmp_1, *tmp_2; + const BIGNUM *p = &group->field; + BN_CTX *new_ctx = NULL; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + ECerr(EC_F_EC_GFP_SIMPLE_GROUP_CHECK_DISCRIMINANT, + ERR_R_MALLOC_FAILURE); + goto err; + } + } + BN_CTX_start(ctx); + a = BN_CTX_get(ctx); + b = BN_CTX_get(ctx); + tmp_1 = BN_CTX_get(ctx); + tmp_2 = BN_CTX_get(ctx); + order = BN_CTX_get(ctx); + if (order == NULL) + goto err; + + if (group->meth->field_decode) { + if (!group->meth->field_decode(group, a, &group->a, ctx)) + goto err; + if (!group->meth->field_decode(group, b, &group->b, ctx)) + goto err; + } else { + if (!BN_copy(a, &group->a)) + goto err; + if (!BN_copy(b, &group->b)) + goto err; + } + + /*- + * check the discriminant: + * y^2 = x^3 + a*x + b is an elliptic curve <=> 4*a^3 + 27*b^2 != 0 (mod p) + * 0 =< a, b < p + */ + if (BN_is_zero(a)) { + if (BN_is_zero(b)) + goto err; + } else if (!BN_is_zero(b)) { + if (!BN_mod_sqr(tmp_1, a, p, ctx)) + goto err; + if (!BN_mod_mul(tmp_2, tmp_1, a, p, ctx)) + goto err; + if (!BN_lshift(tmp_1, tmp_2, 2)) + goto err; + /* tmp_1 = 4*a^3 */ + + if (!BN_mod_sqr(tmp_2, b, p, ctx)) + goto err; + if (!BN_mul_word(tmp_2, 27)) + goto err; + /* tmp_2 = 27*b^2 */ + + if (!BN_mod_add(a, tmp_1, tmp_2, p, ctx)) + goto err; + if (BN_is_zero(a)) + goto err; + } + ret = 1; + + err: + if (ctx != NULL) + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_point_init(EC_POINT *point) +{ + BN_init(&point->X); + BN_init(&point->Y); + BN_init(&point->Z); + point->Z_is_one = 0; + + return 1; +} + +void ec_GFp_simple_point_finish(EC_POINT *point) +{ + BN_free(&point->X); + BN_free(&point->Y); + BN_free(&point->Z); +} + +void ec_GFp_simple_point_clear_finish(EC_POINT *point) +{ + BN_clear_free(&point->X); + BN_clear_free(&point->Y); + BN_clear_free(&point->Z); + point->Z_is_one = 0; +} + +int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) +{ + if (!BN_copy(&dest->X, &src->X)) + return 0; + if (!BN_copy(&dest->Y, &src->Y)) + return 0; + if (!BN_copy(&dest->Z, &src->Z)) + return 0; + dest->Z_is_one = src->Z_is_one; + + return 1; +} + +int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, + EC_POINT *point) +{ + point->Z_is_one = 0; + BN_zero(&point->Z); + return 1; +} + +int ec_GFp_simple_set_Jprojective_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x, + const BIGNUM *y, + const BIGNUM *z, + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + int ret = 0; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + if (x != NULL) { + if (!BN_nnmod(&point->X, x, &group->field, ctx)) + goto err; + if (group->meth->field_encode) { + if (!group->meth->field_encode(group, &point->X, &point->X, ctx)) + goto err; + } + } + + if (y != NULL) { + if (!BN_nnmod(&point->Y, y, &group->field, ctx)) + goto err; + if (group->meth->field_encode) { + if (!group->meth->field_encode(group, &point->Y, &point->Y, ctx)) + goto err; + } + } + + if (z != NULL) { + int Z_is_one; + + if (!BN_nnmod(&point->Z, z, &group->field, ctx)) + goto err; + Z_is_one = BN_is_one(&point->Z); + if (group->meth->field_encode) { + if (Z_is_one && (group->meth->field_set_to_one != 0)) { + if (!group->meth->field_set_to_one(group, &point->Z, ctx)) + goto err; + } else { + if (!group-> + meth->field_encode(group, &point->Z, &point->Z, ctx)) + goto err; + } + } + point->Z_is_one = Z_is_one; + } + + ret = 1; + + err: + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_get_Jprojective_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BIGNUM *z, BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + int ret = 0; + + if (group->meth->field_decode != 0) { + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + if (x != NULL) { + if (!group->meth->field_decode(group, x, &point->X, ctx)) + goto err; + } + if (y != NULL) { + if (!group->meth->field_decode(group, y, &point->Y, ctx)) + goto err; + } + if (z != NULL) { + if (!group->meth->field_decode(group, z, &point->Z, ctx)) + goto err; + } + } else { + if (x != NULL) { + if (!BN_copy(x, &point->X)) + goto err; + } + if (y != NULL) { + if (!BN_copy(y, &point->Y)) + goto err; + } + if (z != NULL) { + if (!BN_copy(z, &point->Z)) + goto err; + } + } + + ret = 1; + + err: + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_point_set_affine_coordinates(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) +{ + if (x == NULL || y == NULL) { + /* + * unlike for projective coordinates, we do not tolerate this + */ + ECerr(EC_F_EC_GFP_SIMPLE_POINT_SET_AFFINE_COORDINATES, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return EC_POINT_set_Jprojective_coordinates_GFp(group, point, x, y, + BN_value_one(), ctx); +} + +int ec_GFp_simple_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BIGNUM *Z, *Z_1, *Z_2, *Z_3; + const BIGNUM *Z_; + int ret = 0; + + if (EC_POINT_is_at_infinity(group, point)) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, + EC_R_POINT_AT_INFINITY); + return 0; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + Z = BN_CTX_get(ctx); + Z_1 = BN_CTX_get(ctx); + Z_2 = BN_CTX_get(ctx); + Z_3 = BN_CTX_get(ctx); + if (Z_3 == NULL) + goto err; + + /* transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) */ + + if (group->meth->field_decode) { + if (!group->meth->field_decode(group, Z, &point->Z, ctx)) + goto err; + Z_ = Z; + } else { + Z_ = &point->Z; + } + + if (BN_is_one(Z_)) { + if (group->meth->field_decode) { + if (x != NULL) { + if (!group->meth->field_decode(group, x, &point->X, ctx)) + goto err; + } + if (y != NULL) { + if (!group->meth->field_decode(group, y, &point->Y, ctx)) + goto err; + } + } else { + if (x != NULL) { + if (!BN_copy(x, &point->X)) + goto err; + } + if (y != NULL) { + if (!BN_copy(y, &point->Y)) + goto err; + } + } + } else { + if (!BN_mod_inverse(Z_1, Z_, &group->field, ctx)) { + ECerr(EC_F_EC_GFP_SIMPLE_POINT_GET_AFFINE_COORDINATES, + ERR_R_BN_LIB); + goto err; + } + + if (group->meth->field_encode == 0) { + /* field_sqr works on standard representation */ + if (!group->meth->field_sqr(group, Z_2, Z_1, ctx)) + goto err; + } else { + if (!BN_mod_sqr(Z_2, Z_1, &group->field, ctx)) + goto err; + } + + if (x != NULL) { + /* + * in the Montgomery case, field_mul will cancel out Montgomery + * factor in X: + */ + if (!group->meth->field_mul(group, x, &point->X, Z_2, ctx)) + goto err; + } + + if (y != NULL) { + if (group->meth->field_encode == 0) { + /* + * field_mul works on standard representation + */ + if (!group->meth->field_mul(group, Z_3, Z_2, Z_1, ctx)) + goto err; + } else { + if (!BN_mod_mul(Z_3, Z_2, Z_1, &group->field, ctx)) + goto err; + } + + /* + * in the Montgomery case, field_mul will cancel out Montgomery + * factor in Y: + */ + if (!group->meth->field_mul(group, y, &point->Y, Z_3, ctx)) + goto err; + } + } + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) +{ + int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + const BIGNUM *p; + BN_CTX *new_ctx = NULL; + BIGNUM *n0, *n1, *n2, *n3, *n4, *n5, *n6; + int ret = 0; + + if (a == b) + return EC_POINT_dbl(group, r, a, ctx); + if (EC_POINT_is_at_infinity(group, a)) + return EC_POINT_copy(r, b); + if (EC_POINT_is_at_infinity(group, b)) + return EC_POINT_copy(r, a); + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + p = &group->field; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + n0 = BN_CTX_get(ctx); + n1 = BN_CTX_get(ctx); + n2 = BN_CTX_get(ctx); + n3 = BN_CTX_get(ctx); + n4 = BN_CTX_get(ctx); + n5 = BN_CTX_get(ctx); + n6 = BN_CTX_get(ctx); + if (n6 == NULL) + goto end; + + /* + * Note that in this function we must not read components of 'a' or 'b' + * once we have written the corresponding components of 'r'. ('r' might + * be one of 'a' or 'b'.) + */ + + /* n1, n2 */ + if (b->Z_is_one) { + if (!BN_copy(n1, &a->X)) + goto end; + if (!BN_copy(n2, &a->Y)) + goto end; + /* n1 = X_a */ + /* n2 = Y_a */ + } else { + if (!field_sqr(group, n0, &b->Z, ctx)) + goto end; + if (!field_mul(group, n1, &a->X, n0, ctx)) + goto end; + /* n1 = X_a * Z_b^2 */ + + if (!field_mul(group, n0, n0, &b->Z, ctx)) + goto end; + if (!field_mul(group, n2, &a->Y, n0, ctx)) + goto end; + /* n2 = Y_a * Z_b^3 */ + } + + /* n3, n4 */ + if (a->Z_is_one) { + if (!BN_copy(n3, &b->X)) + goto end; + if (!BN_copy(n4, &b->Y)) + goto end; + /* n3 = X_b */ + /* n4 = Y_b */ + } else { + if (!field_sqr(group, n0, &a->Z, ctx)) + goto end; + if (!field_mul(group, n3, &b->X, n0, ctx)) + goto end; + /* n3 = X_b * Z_a^2 */ + + if (!field_mul(group, n0, n0, &a->Z, ctx)) + goto end; + if (!field_mul(group, n4, &b->Y, n0, ctx)) + goto end; + /* n4 = Y_b * Z_a^3 */ + } + + /* n5, n6 */ + if (!BN_mod_sub_quick(n5, n1, n3, p)) + goto end; + if (!BN_mod_sub_quick(n6, n2, n4, p)) + goto end; + /* n5 = n1 - n3 */ + /* n6 = n2 - n4 */ + + if (BN_is_zero(n5)) { + if (BN_is_zero(n6)) { + /* a is the same point as b */ + BN_CTX_end(ctx); + ret = EC_POINT_dbl(group, r, a, ctx); + ctx = NULL; + goto end; + } else { + /* a is the inverse of b */ + BN_zero(&r->Z); + r->Z_is_one = 0; + ret = 1; + goto end; + } + } + + /* 'n7', 'n8' */ + if (!BN_mod_add_quick(n1, n1, n3, p)) + goto end; + if (!BN_mod_add_quick(n2, n2, n4, p)) + goto end; + /* 'n7' = n1 + n3 */ + /* 'n8' = n2 + n4 */ + + /* Z_r */ + if (a->Z_is_one && b->Z_is_one) { + if (!BN_copy(&r->Z, n5)) + goto end; + } else { + if (a->Z_is_one) { + if (!BN_copy(n0, &b->Z)) + goto end; + } else if (b->Z_is_one) { + if (!BN_copy(n0, &a->Z)) + goto end; + } else { + if (!field_mul(group, n0, &a->Z, &b->Z, ctx)) + goto end; + } + if (!field_mul(group, &r->Z, n0, n5, ctx)) + goto end; + } + r->Z_is_one = 0; + /* Z_r = Z_a * Z_b * n5 */ + + /* X_r */ + if (!field_sqr(group, n0, n6, ctx)) + goto end; + if (!field_sqr(group, n4, n5, ctx)) + goto end; + if (!field_mul(group, n3, n1, n4, ctx)) + goto end; + if (!BN_mod_sub_quick(&r->X, n0, n3, p)) + goto end; + /* X_r = n6^2 - n5^2 * 'n7' */ + + /* 'n9' */ + if (!BN_mod_lshift1_quick(n0, &r->X, p)) + goto end; + if (!BN_mod_sub_quick(n0, n3, n0, p)) + goto end; + /* n9 = n5^2 * 'n7' - 2 * X_r */ + + /* Y_r */ + if (!field_mul(group, n0, n0, n6, ctx)) + goto end; + if (!field_mul(group, n5, n4, n5, ctx)) + goto end; /* now n5 is n5^3 */ + if (!field_mul(group, n1, n2, n5, ctx)) + goto end; + if (!BN_mod_sub_quick(n0, n0, n1, p)) + goto end; + if (BN_is_odd(n0)) + if (!BN_add(n0, n0, p)) + goto end; + /* now 0 <= n0 < 2*p, and n0 is even */ + if (!BN_rshift1(&r->Y, n0)) + goto end; + /* Y_r = (n6 * 'n9' - 'n8' * 'n5^3') / 2 */ + + ret = 1; + + end: + if (ctx) /* otherwise we already called BN_CTX_end */ + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_dbl(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + BN_CTX *ctx) +{ + int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + const BIGNUM *p; + BN_CTX *new_ctx = NULL; + BIGNUM *n0, *n1, *n2, *n3; + int ret = 0; + + if (EC_POINT_is_at_infinity(group, a)) { + BN_zero(&r->Z); + r->Z_is_one = 0; + return 1; + } + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + p = &group->field; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + n0 = BN_CTX_get(ctx); + n1 = BN_CTX_get(ctx); + n2 = BN_CTX_get(ctx); + n3 = BN_CTX_get(ctx); + if (n3 == NULL) + goto err; + + /* + * Note that in this function we must not read components of 'a' once we + * have written the corresponding components of 'r'. ('r' might the same + * as 'a'.) + */ + + /* n1 */ + if (a->Z_is_one) { + if (!field_sqr(group, n0, &a->X, ctx)) + goto err; + if (!BN_mod_lshift1_quick(n1, n0, p)) + goto err; + if (!BN_mod_add_quick(n0, n0, n1, p)) + goto err; + if (!BN_mod_add_quick(n1, n0, &group->a, p)) + goto err; + /* n1 = 3 * X_a^2 + a_curve */ + } else if (group->a_is_minus3) { + if (!field_sqr(group, n1, &a->Z, ctx)) + goto err; + if (!BN_mod_add_quick(n0, &a->X, n1, p)) + goto err; + if (!BN_mod_sub_quick(n2, &a->X, n1, p)) + goto err; + if (!field_mul(group, n1, n0, n2, ctx)) + goto err; + if (!BN_mod_lshift1_quick(n0, n1, p)) + goto err; + if (!BN_mod_add_quick(n1, n0, n1, p)) + goto err; + /*- + * n1 = 3 * (X_a + Z_a^2) * (X_a - Z_a^2) + * = 3 * X_a^2 - 3 * Z_a^4 + */ + } else { + if (!field_sqr(group, n0, &a->X, ctx)) + goto err; + if (!BN_mod_lshift1_quick(n1, n0, p)) + goto err; + if (!BN_mod_add_quick(n0, n0, n1, p)) + goto err; + if (!field_sqr(group, n1, &a->Z, ctx)) + goto err; + if (!field_sqr(group, n1, n1, ctx)) + goto err; + if (!field_mul(group, n1, n1, &group->a, ctx)) + goto err; + if (!BN_mod_add_quick(n1, n1, n0, p)) + goto err; + /* n1 = 3 * X_a^2 + a_curve * Z_a^4 */ + } + + /* Z_r */ + if (a->Z_is_one) { + if (!BN_copy(n0, &a->Y)) + goto err; + } else { + if (!field_mul(group, n0, &a->Y, &a->Z, ctx)) + goto err; + } + if (!BN_mod_lshift1_quick(&r->Z, n0, p)) + goto err; + r->Z_is_one = 0; + /* Z_r = 2 * Y_a * Z_a */ + + /* n2 */ + if (!field_sqr(group, n3, &a->Y, ctx)) + goto err; + if (!field_mul(group, n2, &a->X, n3, ctx)) + goto err; + if (!BN_mod_lshift_quick(n2, n2, 2, p)) + goto err; + /* n2 = 4 * X_a * Y_a^2 */ + + /* X_r */ + if (!BN_mod_lshift1_quick(n0, n2, p)) + goto err; + if (!field_sqr(group, &r->X, n1, ctx)) + goto err; + if (!BN_mod_sub_quick(&r->X, &r->X, n0, p)) + goto err; + /* X_r = n1^2 - 2 * n2 */ + + /* n3 */ + if (!field_sqr(group, n0, n3, ctx)) + goto err; + if (!BN_mod_lshift_quick(n3, n0, 3, p)) + goto err; + /* n3 = 8 * Y_a^4 */ + + /* Y_r */ + if (!BN_mod_sub_quick(n0, n2, &r->X, p)) + goto err; + if (!field_mul(group, n0, n1, n0, ctx)) + goto err; + if (!BN_mod_sub_quick(&r->Y, n0, n3, p)) + goto err; + /* Y_r = n1 * (n2 - X_r) - n3 */ + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_invert(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) +{ + if (EC_POINT_is_at_infinity(group, point) || BN_is_zero(&point->Y)) + /* point is its own inverse */ + return 1; + + return BN_usub(&point->Y, &group->field, &point->Y); +} + +int ec_GFp_simple_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) +{ + return BN_is_zero(&point->Z); +} + +int ec_GFp_simple_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx) +{ + int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + const BIGNUM *p; + BN_CTX *new_ctx = NULL; + BIGNUM *rh, *tmp, *Z4, *Z6; + int ret = -1; + + if (EC_POINT_is_at_infinity(group, point)) + return 1; + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + p = &group->field; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return -1; + } + + BN_CTX_start(ctx); + rh = BN_CTX_get(ctx); + tmp = BN_CTX_get(ctx); + Z4 = BN_CTX_get(ctx); + Z6 = BN_CTX_get(ctx); + if (Z6 == NULL) + goto err; + + /*- + * We have a curve defined by a Weierstrass equation + * y^2 = x^3 + a*x + b. + * The point to consider is given in Jacobian projective coordinates + * where (X, Y, Z) represents (x, y) = (X/Z^2, Y/Z^3). + * Substituting this and multiplying by Z^6 transforms the above equation into + * Y^2 = X^3 + a*X*Z^4 + b*Z^6. + * To test this, we add up the right-hand side in 'rh'. + */ + + /* rh := X^2 */ + if (!field_sqr(group, rh, &point->X, ctx)) + goto err; + + if (!point->Z_is_one) { + if (!field_sqr(group, tmp, &point->Z, ctx)) + goto err; + if (!field_sqr(group, Z4, tmp, ctx)) + goto err; + if (!field_mul(group, Z6, Z4, tmp, ctx)) + goto err; + + /* rh := (rh + a*Z^4)*X */ + if (group->a_is_minus3) { + if (!BN_mod_lshift1_quick(tmp, Z4, p)) + goto err; + if (!BN_mod_add_quick(tmp, tmp, Z4, p)) + goto err; + if (!BN_mod_sub_quick(rh, rh, tmp, p)) + goto err; + if (!field_mul(group, rh, rh, &point->X, ctx)) + goto err; + } else { + if (!field_mul(group, tmp, Z4, &group->a, ctx)) + goto err; + if (!BN_mod_add_quick(rh, rh, tmp, p)) + goto err; + if (!field_mul(group, rh, rh, &point->X, ctx)) + goto err; + } + + /* rh := rh + b*Z^6 */ + if (!field_mul(group, tmp, &group->b, Z6, ctx)) + goto err; + if (!BN_mod_add_quick(rh, rh, tmp, p)) + goto err; + } else { + /* point->Z_is_one */ + + /* rh := (rh + a)*X */ + if (!BN_mod_add_quick(rh, rh, &group->a, p)) + goto err; + if (!field_mul(group, rh, rh, &point->X, ctx)) + goto err; + /* rh := rh + b */ + if (!BN_mod_add_quick(rh, rh, &group->b, p)) + goto err; + } + + /* 'lh' := Y^2 */ + if (!field_sqr(group, tmp, &point->Y, ctx)) + goto err; + + ret = (0 == BN_ucmp(tmp, rh)); + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_cmp(const EC_GROUP *group, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) +{ + /*- + * return values: + * -1 error + * 0 equal (in affine coordinates) + * 1 not equal + */ + + int (*field_mul) (const EC_GROUP *, BIGNUM *, const BIGNUM *, + const BIGNUM *, BN_CTX *); + int (*field_sqr) (const EC_GROUP *, BIGNUM *, const BIGNUM *, BN_CTX *); + BN_CTX *new_ctx = NULL; + BIGNUM *tmp1, *tmp2, *Za23, *Zb23; + const BIGNUM *tmp1_, *tmp2_; + int ret = -1; + + if (EC_POINT_is_at_infinity(group, a)) { + return EC_POINT_is_at_infinity(group, b) ? 0 : 1; + } + + if (EC_POINT_is_at_infinity(group, b)) + return 1; + + if (a->Z_is_one && b->Z_is_one) { + return ((BN_cmp(&a->X, &b->X) == 0) + && BN_cmp(&a->Y, &b->Y) == 0) ? 0 : 1; + } + + field_mul = group->meth->field_mul; + field_sqr = group->meth->field_sqr; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return -1; + } + + BN_CTX_start(ctx); + tmp1 = BN_CTX_get(ctx); + tmp2 = BN_CTX_get(ctx); + Za23 = BN_CTX_get(ctx); + Zb23 = BN_CTX_get(ctx); + if (Zb23 == NULL) + goto end; + + /*- + * We have to decide whether + * (X_a/Z_a^2, Y_a/Z_a^3) = (X_b/Z_b^2, Y_b/Z_b^3), + * or equivalently, whether + * (X_a*Z_b^2, Y_a*Z_b^3) = (X_b*Z_a^2, Y_b*Z_a^3). + */ + + if (!b->Z_is_one) { + if (!field_sqr(group, Zb23, &b->Z, ctx)) + goto end; + if (!field_mul(group, tmp1, &a->X, Zb23, ctx)) + goto end; + tmp1_ = tmp1; + } else + tmp1_ = &a->X; + if (!a->Z_is_one) { + if (!field_sqr(group, Za23, &a->Z, ctx)) + goto end; + if (!field_mul(group, tmp2, &b->X, Za23, ctx)) + goto end; + tmp2_ = tmp2; + } else + tmp2_ = &b->X; + + /* compare X_a*Z_b^2 with X_b*Z_a^2 */ + if (BN_cmp(tmp1_, tmp2_) != 0) { + ret = 1; /* points differ */ + goto end; + } + + if (!b->Z_is_one) { + if (!field_mul(group, Zb23, Zb23, &b->Z, ctx)) + goto end; + if (!field_mul(group, tmp1, &a->Y, Zb23, ctx)) + goto end; + /* tmp1_ = tmp1 */ + } else + tmp1_ = &a->Y; + if (!a->Z_is_one) { + if (!field_mul(group, Za23, Za23, &a->Z, ctx)) + goto end; + if (!field_mul(group, tmp2, &b->Y, Za23, ctx)) + goto end; + /* tmp2_ = tmp2 */ + } else + tmp2_ = &b->Y; + + /* compare Y_a*Z_b^3 with Y_b*Z_a^3 */ + if (BN_cmp(tmp1_, tmp2_) != 0) { + ret = 1; /* points differ */ + goto end; + } + + /* points are equal */ + ret = 0; + + end: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_make_affine(const EC_GROUP *group, EC_POINT *point, + BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BIGNUM *x, *y; + int ret = 0; + + if (point->Z_is_one || EC_POINT_is_at_infinity(group, point)) + return 1; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + if (y == NULL) + goto err; + + if (!EC_POINT_get_affine_coordinates_GFp(group, point, x, y, ctx)) + goto err; + if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) + goto err; + if (!point->Z_is_one) { + ECerr(EC_F_EC_GFP_SIMPLE_MAKE_AFFINE, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + return ret; +} + +int ec_GFp_simple_points_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx) +{ + BN_CTX *new_ctx = NULL; + BIGNUM *tmp, *tmp_Z; + BIGNUM **prod_Z = NULL; + size_t i; + int ret = 0; + + if (num == 0) + return 1; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) + return 0; + } + + BN_CTX_start(ctx); + tmp = BN_CTX_get(ctx); + tmp_Z = BN_CTX_get(ctx); + if (tmp == NULL || tmp_Z == NULL) + goto err; + + prod_Z = OPENSSL_malloc(num * sizeof prod_Z[0]); + if (prod_Z == NULL) + goto err; + for (i = 0; i < num; i++) { + prod_Z[i] = BN_new(); + if (prod_Z[i] == NULL) + goto err; + } + + /* + * Set each prod_Z[i] to the product of points[0]->Z .. points[i]->Z, + * skipping any zero-valued inputs (pretend that they're 1). + */ + + if (!BN_is_zero(&points[0]->Z)) { + if (!BN_copy(prod_Z[0], &points[0]->Z)) + goto err; + } else { + if (group->meth->field_set_to_one != 0) { + if (!group->meth->field_set_to_one(group, prod_Z[0], ctx)) + goto err; + } else { + if (!BN_one(prod_Z[0])) + goto err; + } + } + + for (i = 1; i < num; i++) { + if (!BN_is_zero(&points[i]->Z)) { + if (!group->meth->field_mul(group, prod_Z[i], prod_Z[i - 1], + &points[i]->Z, ctx)) + goto err; + } else { + if (!BN_copy(prod_Z[i], prod_Z[i - 1])) + goto err; + } + } + + /* + * Now use a single explicit inversion to replace every non-zero + * points[i]->Z by its inverse. + */ + + if (!BN_mod_inverse(tmp, prod_Z[num - 1], &group->field, ctx)) { + ECerr(EC_F_EC_GFP_SIMPLE_POINTS_MAKE_AFFINE, ERR_R_BN_LIB); + goto err; + } + if (group->meth->field_encode != 0) { + /* + * In the Montgomery case, we just turned R*H (representing H) into + * 1/(R*H), but we need R*(1/H) (representing 1/H); i.e. we need to + * multiply by the Montgomery factor twice. + */ + if (!group->meth->field_encode(group, tmp, tmp, ctx)) + goto err; + if (!group->meth->field_encode(group, tmp, tmp, ctx)) + goto err; + } + + for (i = num - 1; i > 0; --i) { + /* + * Loop invariant: tmp is the product of the inverses of points[0]->Z + * .. points[i]->Z (zero-valued inputs skipped). + */ + if (!BN_is_zero(&points[i]->Z)) { + /* + * Set tmp_Z to the inverse of points[i]->Z (as product of Z + * inverses 0 .. i, Z values 0 .. i - 1). + */ + if (!group-> + meth->field_mul(group, tmp_Z, prod_Z[i - 1], tmp, ctx)) + goto err; + /* + * Update tmp to satisfy the loop invariant for i - 1. + */ + if (!group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx)) + goto err; + /* Replace points[i]->Z by its inverse. */ + if (!BN_copy(&points[i]->Z, tmp_Z)) + goto err; + } + } + + if (!BN_is_zero(&points[0]->Z)) { + /* Replace points[0]->Z by its inverse. */ + if (!BN_copy(&points[0]->Z, tmp)) + goto err; + } + + /* Finally, fix up the X and Y coordinates for all points. */ + + for (i = 0; i < num; i++) { + EC_POINT *p = points[i]; + + if (!BN_is_zero(&p->Z)) { + /* turn (X, Y, 1/Z) into (X/Z^2, Y/Z^3, 1) */ + + if (!group->meth->field_sqr(group, tmp, &p->Z, ctx)) + goto err; + if (!group->meth->field_mul(group, &p->X, &p->X, tmp, ctx)) + goto err; + + if (!group->meth->field_mul(group, tmp, tmp, &p->Z, ctx)) + goto err; + if (!group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx)) + goto err; + + if (group->meth->field_set_to_one != 0) { + if (!group->meth->field_set_to_one(group, &p->Z, ctx)) + goto err; + } else { + if (!BN_one(&p->Z)) + goto err; + } + p->Z_is_one = 1; + } + } + + ret = 1; + + err: + BN_CTX_end(ctx); + if (new_ctx != NULL) + BN_CTX_free(new_ctx); + if (prod_Z != NULL) { + for (i = 0; i < num; i++) { + if (prod_Z[i] == NULL) + break; + BN_clear_free(prod_Z[i]); + } + OPENSSL_free(prod_Z); + } + return ret; +} + +int ec_GFp_simple_field_mul(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) +{ + return BN_mod_mul(r, a, b, &group->field, ctx); +} + +int ec_GFp_simple_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) +{ + return BN_mod_sqr(r, a, &group->field, ctx); +} diff --git a/libs/openssl/crypto/ec/ectest.c b/libs/openssl/crypto/ec/ectest.c new file mode 100644 index 00000000..efab0b07 --- /dev/null +++ b/libs/openssl/crypto/ec/ectest.c @@ -0,0 +1,1861 @@ +/* crypto/ec/ectest.c */ +/* + * Originally written by Bodo Moeller for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include +#include +#ifdef FLAT_INC +# include "e_os.h" +#else +# include "../e_os.h" +#endif +#include +#include + +#ifdef OPENSSL_NO_EC +int main(int argc, char *argv[]) +{ + puts("Elliptic curves are disabled."); + return 0; +} +#else + +# include +# ifndef OPENSSL_NO_ENGINE +# include +# endif +# include +# include +# include +# include +# include +# include + +# if defined(_MSC_VER) && defined(_MIPS_) && (_MSC_VER/100==12) +/* suppress "too big too optimize" warning */ +# pragma warning(disable:4959) +# endif + +# define ABORT do { \ + fflush(stdout); \ + fprintf(stderr, "%s:%d: ABORT\n", __FILE__, __LINE__); \ + ERR_print_errors_fp(stderr); \ + EXIT(1); \ +} while (0) + +# define TIMING_BASE_PT 0 +# define TIMING_RAND_PT 1 +# define TIMING_SIMUL 2 + +# if 0 +static void timings(EC_GROUP *group, int type, BN_CTX *ctx) +{ + clock_t clck; + int i, j; + BIGNUM *s; + BIGNUM *r[10], *r0[10]; + EC_POINT *P; + + s = BN_new(); + if (s == NULL) + ABORT; + + fprintf(stdout, "Timings for %d-bit field, ", EC_GROUP_get_degree(group)); + if (!EC_GROUP_get_order(group, s, ctx)) + ABORT; + fprintf(stdout, "%d-bit scalars ", (int)BN_num_bits(s)); + fflush(stdout); + + P = EC_POINT_new(group); + if (P == NULL) + ABORT; + EC_POINT_copy(P, EC_GROUP_get0_generator(group)); + + for (i = 0; i < 10; i++) { + if ((r[i] = BN_new()) == NULL) + ABORT; + if (!BN_pseudo_rand(r[i], BN_num_bits(s), 0, 0)) + ABORT; + if (type != TIMING_BASE_PT) { + if ((r0[i] = BN_new()) == NULL) + ABORT; + if (!BN_pseudo_rand(r0[i], BN_num_bits(s), 0, 0)) + ABORT; + } + } + + clck = clock(); + for (i = 0; i < 10; i++) { + for (j = 0; j < 10; j++) { + if (!EC_POINT_mul + (group, P, (type != TIMING_RAND_PT) ? r[i] : NULL, + (type != TIMING_BASE_PT) ? P : NULL, + (type != TIMING_BASE_PT) ? r0[i] : NULL, ctx)) + ABORT; + } + } + clck = clock() - clck; + + fprintf(stdout, "\n"); + +# ifdef CLOCKS_PER_SEC + /* + * "To determine the time in seconds, the value returned by the clock + * function should be divided by the value of the macro CLOCKS_PER_SEC." + * -- ISO/IEC 9899 + */ +# define UNIT "s" +# else + /* + * "`CLOCKS_PER_SEC' undeclared (first use this function)" -- cc on + * NeXTstep/OpenStep + */ +# define UNIT "units" +# define CLOCKS_PER_SEC 1 +# endif + + if (type == TIMING_BASE_PT) { + fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j, + "base point multiplications", (double)clck / CLOCKS_PER_SEC); + } else if (type == TIMING_RAND_PT) { + fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j, + "random point multiplications", + (double)clck / CLOCKS_PER_SEC); + } else if (type == TIMING_SIMUL) { + fprintf(stdout, "%i %s in %.2f " UNIT "\n", i * j, + "s*P+t*Q operations", (double)clck / CLOCKS_PER_SEC); + } + fprintf(stdout, "average: %.4f " UNIT "\n", + (double)clck / (CLOCKS_PER_SEC * i * j)); + + EC_POINT_free(P); + BN_free(s); + for (i = 0; i < 10; i++) { + BN_free(r[i]); + if (type != TIMING_BASE_PT) + BN_free(r0[i]); + } +} +# endif + +/* test multiplication with group order, long and negative scalars */ +static void group_order_tests(EC_GROUP *group) +{ + BIGNUM *n1, *n2, *order; + EC_POINT *P = EC_POINT_new(group); + EC_POINT *Q = EC_POINT_new(group); + BN_CTX *ctx = BN_CTX_new(); + int i; + + n1 = BN_new(); + n2 = BN_new(); + order = BN_new(); + fprintf(stdout, "verify group order ..."); + fflush(stdout); + if (!EC_GROUP_get_order(group, order, ctx)) + ABORT; + if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, Q)) + ABORT; + fprintf(stdout, "."); + fflush(stdout); + if (!EC_GROUP_precompute_mult(group, ctx)) + ABORT; + if (!EC_POINT_mul(group, Q, order, NULL, NULL, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, Q)) + ABORT; + fprintf(stdout, " ok\n"); + fprintf(stdout, "long/negative scalar tests "); + for (i = 1; i <= 2; i++) { + const BIGNUM *scalars[6]; + const EC_POINT *points[6]; + + fprintf(stdout, i == 1 ? + "allowing precomputation ... " : + "without precomputation ... "); + if (!BN_set_word(n1, i)) + ABORT; + /* + * If i == 1, P will be the predefined generator for which + * EC_GROUP_precompute_mult has set up precomputation. + */ + if (!EC_POINT_mul(group, P, n1, NULL, NULL, ctx)) + ABORT; + + if (!BN_one(n1)) + ABORT; + /* n1 = 1 - order */ + if (!BN_sub(n1, n1, order)) + ABORT; + if (!EC_POINT_mul(group, Q, NULL, P, n1, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, Q, P, ctx)) + ABORT; + + /* n2 = 1 + order */ + if (!BN_add(n2, order, BN_value_one())) + ABORT; + if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, Q, P, ctx)) + ABORT; + + /* n2 = (1 - order) * (1 + order) = 1 - order^2 */ + if (!BN_mul(n2, n1, n2, ctx)) + ABORT; + if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, Q, P, ctx)) + ABORT; + + /* n2 = order^2 - 1 */ + BN_set_negative(n2, 0); + if (!EC_POINT_mul(group, Q, NULL, P, n2, ctx)) + ABORT; + /* Add P to verify the result. */ + if (!EC_POINT_add(group, Q, Q, P, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, Q)) + ABORT; + + /* Exercise EC_POINTs_mul, including corner cases. */ + if (EC_POINT_is_at_infinity(group, P)) + ABORT; + scalars[0] = n1; + points[0] = Q; /* => infinity */ + scalars[1] = n2; + points[1] = P; /* => -P */ + scalars[2] = n1; + points[2] = Q; /* => infinity */ + scalars[3] = n2; + points[3] = Q; /* => infinity */ + scalars[4] = n1; + points[4] = P; /* => P */ + scalars[5] = n2; + points[5] = Q; /* => infinity */ + if (!EC_POINTs_mul(group, P, NULL, 6, points, scalars, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + } + fprintf(stdout, "ok\n"); + + EC_POINT_free(P); + EC_POINT_free(Q); + BN_free(n1); + BN_free(n2); + BN_free(order); + BN_CTX_free(ctx); +} + +static void prime_field_tests(void) +{ + BN_CTX *ctx = NULL; + BIGNUM *p, *a, *b; + EC_GROUP *group; + EC_GROUP *P_160 = NULL, *P_192 = NULL, *P_224 = NULL, *P_256 = + NULL, *P_384 = NULL, *P_521 = NULL; + EC_POINT *P, *Q, *R; + BIGNUM *x, *y, *z; + unsigned char buf[100]; + size_t i, len; + int k; + +# if 1 /* optional */ + ctx = BN_CTX_new(); + if (!ctx) + ABORT; +# endif + + p = BN_new(); + a = BN_new(); + b = BN_new(); + if (!p || !a || !b) + ABORT; + + if (!BN_hex2bn(&p, "17")) + ABORT; + if (!BN_hex2bn(&a, "1")) + ABORT; + if (!BN_hex2bn(&b, "1")) + ABORT; + + group = EC_GROUP_new(EC_GFp_mont_method()); /* applications should use + * EC_GROUP_new_curve_GFp so + * that the library gets to + * choose the EC_METHOD */ + if (!group) + ABORT; + + if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) + ABORT; + + { + EC_GROUP *tmp; + tmp = EC_GROUP_new(EC_GROUP_method_of(group)); + if (!tmp) + ABORT; + if (!EC_GROUP_copy(tmp, group)) + ABORT; + EC_GROUP_free(group); + group = tmp; + } + + if (!EC_GROUP_get_curve_GFp(group, p, a, b, ctx)) + ABORT; + + fprintf(stdout, + "Curve defined by Weierstrass equation\n y^2 = x^3 + a*x + b (mod 0x"); + BN_print_fp(stdout, p); + fprintf(stdout, ")\n a = 0x"); + BN_print_fp(stdout, a); + fprintf(stdout, "\n b = 0x"); + BN_print_fp(stdout, b); + fprintf(stdout, "\n"); + + P = EC_POINT_new(group); + Q = EC_POINT_new(group); + R = EC_POINT_new(group); + if (!P || !Q || !R) + ABORT; + + if (!EC_POINT_set_to_infinity(group, P)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + + buf[0] = 0; + if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) + ABORT; + + if (!EC_POINT_add(group, P, P, Q, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + + x = BN_new(); + y = BN_new(); + z = BN_new(); + if (!x || !y || !z) + ABORT; + + if (!BN_hex2bn(&x, "D")) + ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) { + if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) + ABORT; + fprintf(stderr, "Point is not on curve: x = 0x"); + BN_print_fp(stderr, x); + fprintf(stderr, ", y = 0x"); + BN_print_fp(stderr, y); + fprintf(stderr, "\n"); + ABORT; + } + + fprintf(stdout, "A cyclic subgroup:\n"); + k = 100; + do { + if (k-- == 0) + ABORT; + + if (EC_POINT_is_at_infinity(group, P)) + fprintf(stdout, " point at infinity\n"); + else { + if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) + ABORT; + + fprintf(stdout, " x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, ", y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + } + + if (!EC_POINT_copy(R, P)) + ABORT; + if (!EC_POINT_add(group, P, P, Q, ctx)) + ABORT; + +# if 0 /* optional */ + { + EC_POINT *points[3]; + + points[0] = R; + points[1] = Q; + points[2] = P; + if (!EC_POINTs_make_affine(group, 2, points, ctx)) + ABORT; + } +# endif + + } + while (!EC_POINT_is_at_infinity(group, P)); + + if (!EC_POINT_add(group, P, Q, R, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + + len = + EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, + sizeof buf, ctx); + if (len == 0) + ABORT; + if (!EC_POINT_oct2point(group, P, buf, len, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, Q, ctx)) + ABORT; + fprintf(stdout, "Generator as octet string, compressed form:\n "); + for (i = 0; i < len; i++) + fprintf(stdout, "%02X", buf[i]); + + len = + EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, + sizeof buf, ctx); + if (len == 0) + ABORT; + if (!EC_POINT_oct2point(group, P, buf, len, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, Q, ctx)) + ABORT; + fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n "); + for (i = 0; i < len; i++) + fprintf(stdout, "%02X", buf[i]); + + len = + EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, + ctx); + if (len == 0) + ABORT; + if (!EC_POINT_oct2point(group, P, buf, len, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, Q, ctx)) + ABORT; + fprintf(stdout, "\nGenerator as octet string, hybrid form:\n "); + for (i = 0; i < len; i++) + fprintf(stdout, "%02X", buf[i]); + + if (!EC_POINT_get_Jprojective_coordinates_GFp(group, R, x, y, z, ctx)) + ABORT; + fprintf(stdout, + "\nA representation of the inverse of that generator in\nJacobian projective coordinates:\n X = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, ", Y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, ", Z = 0x"); + BN_print_fp(stdout, z); + fprintf(stdout, "\n"); + + if (!EC_POINT_invert(group, P, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, R, ctx)) + ABORT; + + /* + * Curve secp160r1 (Certicom Research SEC 2 Version 1.0, section 2.4.2, + * 2000) -- not a NIST curve, but commonly used + */ + + if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFF")) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF7FFFFFFC")) + ABORT; + if (!BN_hex2bn(&b, "1C97BEFC54BD7A8B65ACF89F81D4D4ADC565FA45")) + ABORT; + if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) + ABORT; + if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) + ABORT; + if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) + ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nSEC2 curve secp160r1 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn(&z, "23a628553168947d59dcc912042351377ac5fb32")) + ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 160) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_160 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_160, group)) + ABORT; + + /* Curve P-192 (FIPS PUB 186-2, App. 6) */ + + if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFF")) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFC")) + ABORT; + if (!BN_hex2bn(&b, "64210519E59C80E70FA7E9AB72243049FEB8DEECC146B9B1")) + ABORT; + if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) + ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) + ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nNIST curve P-192 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn(&z, "07192B95FFC8DA78631011ED6B24CDD573F977A11E794811")) + ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 192) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_192 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_192, group)) + ABORT; + + /* Curve P-224 (FIPS PUB 186-2, App. 6) */ + + if (!BN_hex2bn + (&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001")) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn + (&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE")) + ABORT; + if (!BN_hex2bn + (&b, "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4")) + ABORT; + if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn + (&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) + ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn + (&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) + ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nNIST curve P-224 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn + (&z, "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34")) + ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 224) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_224 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_224, group)) + ABORT; + + /* Curve P-256 (FIPS PUB 186-2, App. 6) */ + + if (!BN_hex2bn + (&p, + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF")) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn + (&a, + "FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC")) + ABORT; + if (!BN_hex2bn + (&b, + "5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B")) + ABORT; + if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn + (&x, + "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) + ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E" + "84F3B9CAC2FC632551")) + ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nNIST curve P-256 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn + (&z, + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5")) + ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 256) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_256 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_256, group)) + ABORT; + + /* Curve P-384 (FIPS PUB 186-2, App. 6) */ + + if (!BN_hex2bn(&p, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFF")) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn(&a, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFEFFFFFFFF0000000000000000FFFFFFFC")) + ABORT; + if (!BN_hex2bn(&b, "B3312FA7E23EE7E4988E056BE3F82D19181D9C6EFE8141" + "120314088F5013875AC656398D8A2ED19D2A85C8EDD3EC2AEF")) + ABORT; + if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B" + "9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) + ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) + ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nNIST curve P-384 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn(&z, "3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A14" + "7CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F")) + ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 384) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_384 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_384, group)) + ABORT; + + /* Curve P-521 (FIPS PUB 186-2, App. 6) */ + + if (!BN_hex2bn(&p, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFF")) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn(&a, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFC")) + ABORT; + if (!BN_hex2bn(&b, "051953EB9618E1C9A1F929A21A0B68540EEA2DA725B99B" + "315F3B8B489918EF109E156193951EC7E937B1652C0BD3BB1BF073573" + "DF883D2C34F1EF451FD46B503F00")) + ABORT; + if (!EC_GROUP_set_curve_GFp(group, p, a, b, ctx)) + ABORT; + + if (!BN_hex2bn(&x, "C6858E06B70404E9CD9E3ECB662395B4429C648139053F" + "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B" + "3C1856A429BF97E7E31C2E5BD66")) + ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5" + "C9B8899C47AEBB6FB71E91386409")) + ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) + ABORT; + + if (!EC_POINT_get_affine_coordinates_GFp(group, P, x, y, ctx)) + ABORT; + fprintf(stdout, "\nNIST curve P-521 -- Generator:\n x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, "\n y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + /* G_y value taken from the standard: */ + if (!BN_hex2bn(&z, "11839296A789A3BC0045C8A5FB42C7D1BD998F54449579" + "B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C" + "7086A272C24088BE94769FD16650")) + ABORT; + if (0 != BN_cmp(y, z)) + ABORT; + + fprintf(stdout, "verify degree ..."); + if (EC_GROUP_get_degree(group) != 521) + ABORT; + fprintf(stdout, " ok\n"); + + group_order_tests(group); + + if (!(P_521 = EC_GROUP_new(EC_GROUP_method_of(group)))) + ABORT; + if (!EC_GROUP_copy(P_521, group)) + ABORT; + + /* more tests using the last curve */ + + if (!EC_POINT_copy(Q, P)) + ABORT; + if (EC_POINT_is_at_infinity(group, Q)) + ABORT; + if (!EC_POINT_dbl(group, P, P, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!EC_POINT_invert(group, Q, ctx)) + ABORT; /* P = -2Q */ + + if (!EC_POINT_add(group, R, P, Q, ctx)) + ABORT; + if (!EC_POINT_add(group, R, R, Q, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, R)) + ABORT; /* R = P + 2Q */ + + { + const EC_POINT *points[4]; + const BIGNUM *scalars[4]; + BIGNUM scalar3; + + if (EC_POINT_is_at_infinity(group, Q)) + ABORT; + points[0] = Q; + points[1] = Q; + points[2] = Q; + points[3] = Q; + + if (!EC_GROUP_get_order(group, z, ctx)) + ABORT; + if (!BN_add(y, z, BN_value_one())) + ABORT; + if (BN_is_odd(y)) + ABORT; + if (!BN_rshift1(y, y)) + ABORT; + scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */ + scalars[1] = y; + + fprintf(stdout, "combined multiplication ..."); + fflush(stdout); + + /* z is still the group order */ + if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) + ABORT; + if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, R, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, R, Q, ctx)) + ABORT; + + fprintf(stdout, "."); + fflush(stdout); + + if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) + ABORT; + if (!BN_add(z, z, y)) + ABORT; + BN_set_negative(z, 1); + scalars[0] = y; + scalars[1] = z; /* z = -(order + y) */ + + if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + + fprintf(stdout, "."); + fflush(stdout); + + if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) + ABORT; + if (!BN_add(z, x, y)) + ABORT; + BN_set_negative(z, 1); + scalars[0] = x; + scalars[1] = y; + scalars[2] = z; /* z = -(x+y) */ + + BN_init(&scalar3); + BN_zero(&scalar3); + scalars[3] = &scalar3; + + if (!EC_POINTs_mul(group, P, NULL, 4, points, scalars, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + + fprintf(stdout, " ok\n\n"); + + BN_free(&scalar3); + } + +# if 0 + timings(P_160, TIMING_BASE_PT, ctx); + timings(P_160, TIMING_RAND_PT, ctx); + timings(P_160, TIMING_SIMUL, ctx); + timings(P_192, TIMING_BASE_PT, ctx); + timings(P_192, TIMING_RAND_PT, ctx); + timings(P_192, TIMING_SIMUL, ctx); + timings(P_224, TIMING_BASE_PT, ctx); + timings(P_224, TIMING_RAND_PT, ctx); + timings(P_224, TIMING_SIMUL, ctx); + timings(P_256, TIMING_BASE_PT, ctx); + timings(P_256, TIMING_RAND_PT, ctx); + timings(P_256, TIMING_SIMUL, ctx); + timings(P_384, TIMING_BASE_PT, ctx); + timings(P_384, TIMING_RAND_PT, ctx); + timings(P_384, TIMING_SIMUL, ctx); + timings(P_521, TIMING_BASE_PT, ctx); + timings(P_521, TIMING_RAND_PT, ctx); + timings(P_521, TIMING_SIMUL, ctx); +# endif + + if (ctx) + BN_CTX_free(ctx); + BN_free(p); + BN_free(a); + BN_free(b); + EC_GROUP_free(group); + EC_POINT_free(P); + EC_POINT_free(Q); + EC_POINT_free(R); + BN_free(x); + BN_free(y); + BN_free(z); + + if (P_160) + EC_GROUP_free(P_160); + if (P_192) + EC_GROUP_free(P_192); + if (P_224) + EC_GROUP_free(P_224); + if (P_256) + EC_GROUP_free(P_256); + if (P_384) + EC_GROUP_free(P_384); + if (P_521) + EC_GROUP_free(P_521); + +} + +/* Change test based on whether binary point compression is enabled or not. */ +# ifdef OPENSSL_EC_BIN_PT_COMP +# define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \ + if (!BN_hex2bn(&x, _x)) ABORT; \ + if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \ + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \ + if (!BN_hex2bn(&z, _order)) ABORT; \ + if (!BN_hex2bn(&cof, _cof)) ABORT; \ + if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \ + if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \ + fprintf(stdout, "\n%s -- Generator:\n x = 0x", _name); \ + BN_print_fp(stdout, x); \ + fprintf(stdout, "\n y = 0x"); \ + BN_print_fp(stdout, y); \ + fprintf(stdout, "\n"); \ + /* G_y value taken from the standard: */ \ + if (!BN_hex2bn(&z, _y)) ABORT; \ + if (0 != BN_cmp(y, z)) ABORT; +# else +# define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \ + if (!BN_hex2bn(&x, _x)) ABORT; \ + if (!BN_hex2bn(&y, _y)) ABORT; \ + if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \ + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \ + if (!BN_hex2bn(&z, _order)) ABORT; \ + if (!BN_hex2bn(&cof, _cof)) ABORT; \ + if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \ + fprintf(stdout, "\n%s -- Generator:\n x = 0x", _name); \ + BN_print_fp(stdout, x); \ + fprintf(stdout, "\n y = 0x"); \ + BN_print_fp(stdout, y); \ + fprintf(stdout, "\n"); +# endif + +# define CHAR2_CURVE_TEST(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \ + if (!BN_hex2bn(&p, _p)) ABORT; \ + if (!BN_hex2bn(&a, _a)) ABORT; \ + if (!BN_hex2bn(&b, _b)) ABORT; \ + if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) ABORT; \ + CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \ + fprintf(stdout, "verify degree ..."); \ + if (EC_GROUP_get_degree(group) != _degree) ABORT; \ + fprintf(stdout, " ok\n"); \ + group_order_tests(group); \ + if (!(_variable = EC_GROUP_new(EC_GROUP_method_of(group)))) ABORT; \ + if (!EC_GROUP_copy(_variable, group)) ABORT; \ + +# ifndef OPENSSL_NO_EC2M + +static void char2_field_tests(void) +{ + BN_CTX *ctx = NULL; + BIGNUM *p, *a, *b; + EC_GROUP *group; + EC_GROUP *C2_K163 = NULL, *C2_K233 = NULL, *C2_K283 = NULL, *C2_K409 = + NULL, *C2_K571 = NULL; + EC_GROUP *C2_B163 = NULL, *C2_B233 = NULL, *C2_B283 = NULL, *C2_B409 = + NULL, *C2_B571 = NULL; + EC_POINT *P, *Q, *R; + BIGNUM *x, *y, *z, *cof; + unsigned char buf[100]; + size_t i, len; + int k; + +# if 1 /* optional */ + ctx = BN_CTX_new(); + if (!ctx) + ABORT; +# endif + + p = BN_new(); + a = BN_new(); + b = BN_new(); + if (!p || !a || !b) + ABORT; + + if (!BN_hex2bn(&p, "13")) + ABORT; + if (!BN_hex2bn(&a, "3")) + ABORT; + if (!BN_hex2bn(&b, "1")) + ABORT; + + group = EC_GROUP_new(EC_GF2m_simple_method()); /* applications should use + * EC_GROUP_new_curve_GF2m + * so that the library gets + * to choose the EC_METHOD */ + if (!group) + ABORT; + if (!EC_GROUP_set_curve_GF2m(group, p, a, b, ctx)) + ABORT; + + { + EC_GROUP *tmp; + tmp = EC_GROUP_new(EC_GROUP_method_of(group)); + if (!tmp) + ABORT; + if (!EC_GROUP_copy(tmp, group)) + ABORT; + EC_GROUP_free(group); + group = tmp; + } + + if (!EC_GROUP_get_curve_GF2m(group, p, a, b, ctx)) + ABORT; + + fprintf(stdout, + "Curve defined by Weierstrass equation\n y^2 + x*y = x^3 + a*x^2 + b (mod 0x"); + BN_print_fp(stdout, p); + fprintf(stdout, ")\n a = 0x"); + BN_print_fp(stdout, a); + fprintf(stdout, "\n b = 0x"); + BN_print_fp(stdout, b); + fprintf(stdout, "\n(0x... means binary polynomial)\n"); + + P = EC_POINT_new(group); + Q = EC_POINT_new(group); + R = EC_POINT_new(group); + if (!P || !Q || !R) + ABORT; + + if (!EC_POINT_set_to_infinity(group, P)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + + buf[0] = 0; + if (!EC_POINT_oct2point(group, Q, buf, 1, ctx)) + ABORT; + + if (!EC_POINT_add(group, P, P, Q, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + + x = BN_new(); + y = BN_new(); + z = BN_new(); + cof = BN_new(); + if (!x || !y || !z || !cof) + ABORT; + + if (!BN_hex2bn(&x, "6")) + ABORT; +/* Change test based on whether binary point compression is enabled or not. */ +# ifdef OPENSSL_EC_BIN_PT_COMP + if (!EC_POINT_set_compressed_coordinates_GF2m(group, Q, x, 1, ctx)) + ABORT; +# else + if (!BN_hex2bn(&y, "8")) + ABORT; + if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) + ABORT; +# endif + if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) { +/* Change test based on whether binary point compression is enabled or not. */ +# ifdef OPENSSL_EC_BIN_PT_COMP + if (!EC_POINT_get_affine_coordinates_GF2m(group, Q, x, y, ctx)) + ABORT; +# endif + fprintf(stderr, "Point is not on curve: x = 0x"); + BN_print_fp(stderr, x); + fprintf(stderr, ", y = 0x"); + BN_print_fp(stderr, y); + fprintf(stderr, "\n"); + ABORT; + } + + fprintf(stdout, "A cyclic subgroup:\n"); + k = 100; + do { + if (k-- == 0) + ABORT; + + if (EC_POINT_is_at_infinity(group, P)) + fprintf(stdout, " point at infinity\n"); + else { + if (!EC_POINT_get_affine_coordinates_GF2m(group, P, x, y, ctx)) + ABORT; + + fprintf(stdout, " x = 0x"); + BN_print_fp(stdout, x); + fprintf(stdout, ", y = 0x"); + BN_print_fp(stdout, y); + fprintf(stdout, "\n"); + } + + if (!EC_POINT_copy(R, P)) + ABORT; + if (!EC_POINT_add(group, P, P, Q, ctx)) + ABORT; + } + while (!EC_POINT_is_at_infinity(group, P)); + + if (!EC_POINT_add(group, P, Q, R, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + +/* Change test based on whether binary point compression is enabled or not. */ +# ifdef OPENSSL_EC_BIN_PT_COMP + len = + EC_POINT_point2oct(group, Q, POINT_CONVERSION_COMPRESSED, buf, + sizeof buf, ctx); + if (len == 0) + ABORT; + if (!EC_POINT_oct2point(group, P, buf, len, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, Q, ctx)) + ABORT; + fprintf(stdout, "Generator as octet string, compressed form:\n "); + for (i = 0; i < len; i++) + fprintf(stdout, "%02X", buf[i]); +# endif + + len = + EC_POINT_point2oct(group, Q, POINT_CONVERSION_UNCOMPRESSED, buf, + sizeof buf, ctx); + if (len == 0) + ABORT; + if (!EC_POINT_oct2point(group, P, buf, len, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, Q, ctx)) + ABORT; + fprintf(stdout, "\nGenerator as octet string, uncompressed form:\n "); + for (i = 0; i < len; i++) + fprintf(stdout, "%02X", buf[i]); + +/* Change test based on whether binary point compression is enabled or not. */ +# ifdef OPENSSL_EC_BIN_PT_COMP + len = + EC_POINT_point2oct(group, Q, POINT_CONVERSION_HYBRID, buf, sizeof buf, + ctx); + if (len == 0) + ABORT; + if (!EC_POINT_oct2point(group, P, buf, len, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, Q, ctx)) + ABORT; + fprintf(stdout, "\nGenerator as octet string, hybrid form:\n "); + for (i = 0; i < len; i++) + fprintf(stdout, "%02X", buf[i]); +# endif + + fprintf(stdout, "\n"); + + if (!EC_POINT_invert(group, P, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, R, ctx)) + ABORT; + + /* Curve K-163 (FIPS PUB 186-2, App. 6) */ + CHAR2_CURVE_TEST + ("NIST curve K-163", + "0800000000000000000000000000000000000000C9", + "1", + "1", + "02FE13C0537BBC11ACAA07D793DE4E6D5E5C94EEE8", + "0289070FB05D38FF58321F2E800536D538CCDAA3D9", + 1, "04000000000000000000020108A2E0CC0D99F8A5EF", "2", 163, C2_K163); + + /* Curve B-163 (FIPS PUB 186-2, App. 6) */ + CHAR2_CURVE_TEST + ("NIST curve B-163", + "0800000000000000000000000000000000000000C9", + "1", + "020A601907B8C953CA1481EB10512F78744A3205FD", + "03F0EBA16286A2D57EA0991168D4994637E8343E36", + "00D51FBC6C71A0094FA2CDD545B11C5C0C797324F1", + 1, "040000000000000000000292FE77E70C12A4234C33", "2", 163, C2_B163); + + /* Curve K-233 (FIPS PUB 186-2, App. 6) */ + CHAR2_CURVE_TEST + ("NIST curve K-233", + "020000000000000000000000000000000000000004000000000000000001", + "0", + "1", + "017232BA853A7E731AF129F22FF4149563A419C26BF50A4C9D6EEFAD6126", + "01DB537DECE819B7F70F555A67C427A8CD9BF18AEB9B56E0C11056FAE6A3", + 0, + "008000000000000000000000000000069D5BB915BCD46EFB1AD5F173ABDF", + "4", 233, C2_K233); + + /* Curve B-233 (FIPS PUB 186-2, App. 6) */ + CHAR2_CURVE_TEST + ("NIST curve B-233", + "020000000000000000000000000000000000000004000000000000000001", + "000000000000000000000000000000000000000000000000000000000001", + "0066647EDE6C332C7F8C0923BB58213B333B20E9CE4281FE115F7D8F90AD", + "00FAC9DFCBAC8313BB2139F1BB755FEF65BC391F8B36F8F8EB7371FD558B", + "01006A08A41903350678E58528BEBF8A0BEFF867A7CA36716F7E01F81052", + 1, + "01000000000000000000000000000013E974E72F8A6922031D2603CFE0D7", + "2", 233, C2_B233); + + /* Curve K-283 (FIPS PUB 186-2, App. 6) */ + CHAR2_CURVE_TEST + ("NIST curve K-283", + "0800000000000000000000000000000000000000000000000000000000000000000010A1", + "0", + "1", + "0503213F78CA44883F1A3B8162F188E553CD265F23C1567A16876913B0C2AC2458492836", + "01CCDA380F1C9E318D90F95D07E5426FE87E45C0E8184698E45962364E34116177DD2259", + 0, + "01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE9AE2ED07577265DFF7F94451E061E163C61", + "4", 283, C2_K283); + + /* Curve B-283 (FIPS PUB 186-2, App. 6) */ + CHAR2_CURVE_TEST + ("NIST curve B-283", + "0800000000000000000000000000000000000000000000000000000000000000000010A1", + "000000000000000000000000000000000000000000000000000000000000000000000001", + "027B680AC8B8596DA5A4AF8A19A0303FCA97FD7645309FA2A581485AF6263E313B79A2F5", + "05F939258DB7DD90E1934F8C70B0DFEC2EED25B8557EAC9C80E2E198F8CDBECD86B12053", + "03676854FE24141CB98FE6D4B20D02B4516FF702350EDDB0826779C813F0DF45BE8112F4", + 1, + "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF90399660FC938A90165B042A7CEFADB307", + "2", 283, C2_B283); + + /* Curve K-409 (FIPS PUB 186-2, App. 6) */ + CHAR2_CURVE_TEST + ("NIST curve K-409", + "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", + "0", + "1", + "0060F05F658F49C1AD3AB1890F7184210EFD0987E307C84C27ACCFB8F9F67CC2C460189EB5AAAA62EE222EB1B35540CFE9023746", + "01E369050B7C4E42ACBA1DACBF04299C3460782F918EA427E6325165E9EA10E3DA5F6C42E9C55215AA9CA27A5863EC48D8E0286B", + 1, + "007FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE5F83B2D4EA20400EC4557D5ED3E3E7CA5B4B5C83B8E01E5FCF", + "4", 409, C2_K409); + + /* Curve B-409 (FIPS PUB 186-2, App. 6) */ + CHAR2_CURVE_TEST + ("NIST curve B-409", + "02000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000001", + "00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + "0021A5C2C8EE9FEB5C4B9A753B7B476B7FD6422EF1F3DD674761FA99D6AC27C8A9A197B272822F6CD57A55AA4F50AE317B13545F", + "015D4860D088DDB3496B0C6064756260441CDE4AF1771D4DB01FFE5B34E59703DC255A868A1180515603AEAB60794E54BB7996A7", + "0061B1CFAB6BE5F32BBFA78324ED106A7636B9C5A7BD198D0158AA4F5488D08F38514F1FDF4B4F40D2181B3681C364BA0273C706", + 1, + "010000000000000000000000000000000000000000000000000001E2AAD6A612F33307BE5FA47C3C9E052F838164CD37D9A21173", + "2", 409, C2_B409); + + /* Curve K-571 (FIPS PUB 186-2, App. 6) */ + CHAR2_CURVE_TEST + ("NIST curve K-571", + "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", + "0", + "1", + "026EB7A859923FBC82189631F8103FE4AC9CA2970012D5D46024804801841CA44370958493B205E647DA304DB4CEB08CBBD1BA39494776FB988B47174DCA88C7E2945283A01C8972", + "0349DC807F4FBF374F4AEADE3BCA95314DD58CEC9F307A54FFC61EFC006D8A2C9D4979C0AC44AEA74FBEBBB9F772AEDCB620B01A7BA7AF1B320430C8591984F601CD4C143EF1C7A3", + 0, + "020000000000000000000000000000000000000000000000000000000000000000000000131850E1F19A63E4B391A8DB917F4138B630D84BE5D639381E91DEB45CFE778F637C1001", + "4", 571, C2_K571); + + /* Curve B-571 (FIPS PUB 186-2, App. 6) */ + CHAR2_CURVE_TEST + ("NIST curve B-571", + "80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000425", + "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001", + "02F40E7E2221F295DE297117B7F3D62F5C6A97FFCB8CEFF1CD6BA8CE4A9A18AD84FFABBD8EFA59332BE7AD6756A66E294AFD185A78FF12AA520E4DE739BACA0C7FFEFF7F2955727A", + "0303001D34B856296C16C0D40D3CD7750A93D1D2955FA80AA5F40FC8DB7B2ABDBDE53950F4C0D293CDD711A35B67FB1499AE60038614F1394ABFA3B4C850D927E1E7769C8EEC2D19", + "037BF27342DA639B6DCCFFFEB73D69D78C6C27A6009CBBCA1980F8533921E8A684423E43BAB08A576291AF8F461BB2A8B3531D2F0485C19B16E2F1516E23DD3C1A4827AF1B8AC15B", + 1, + "03FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE661CE18FF55987308059B186823851EC7DD9CA1161DE93D5174D66E8382E9BB2FE84E47", + "2", 571, C2_B571); + + /* more tests using the last curve */ + + if (!EC_POINT_copy(Q, P)) + ABORT; + if (EC_POINT_is_at_infinity(group, Q)) + ABORT; + if (!EC_POINT_dbl(group, P, P, ctx)) + ABORT; + if (EC_POINT_is_on_curve(group, P, ctx) <= 0) + ABORT; + if (!EC_POINT_invert(group, Q, ctx)) + ABORT; /* P = -2Q */ + + if (!EC_POINT_add(group, R, P, Q, ctx)) + ABORT; + if (!EC_POINT_add(group, R, R, Q, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, R)) + ABORT; /* R = P + 2Q */ + + { + const EC_POINT *points[3]; + const BIGNUM *scalars[3]; + + if (EC_POINT_is_at_infinity(group, Q)) + ABORT; + points[0] = Q; + points[1] = Q; + points[2] = Q; + + if (!BN_add(y, z, BN_value_one())) + ABORT; + if (BN_is_odd(y)) + ABORT; + if (!BN_rshift1(y, y)) + ABORT; + scalars[0] = y; /* (group order + 1)/2, so y*Q + y*Q = Q */ + scalars[1] = y; + + fprintf(stdout, "combined multiplication ..."); + fflush(stdout); + + /* z is still the group order */ + if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) + ABORT; + if (!EC_POINTs_mul(group, R, z, 2, points, scalars, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, P, R, ctx)) + ABORT; + if (0 != EC_POINT_cmp(group, R, Q, ctx)) + ABORT; + + fprintf(stdout, "."); + fflush(stdout); + + if (!BN_pseudo_rand(y, BN_num_bits(y), 0, 0)) + ABORT; + if (!BN_add(z, z, y)) + ABORT; + BN_set_negative(z, 1); + scalars[0] = y; + scalars[1] = z; /* z = -(order + y) */ + + if (!EC_POINTs_mul(group, P, NULL, 2, points, scalars, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + + fprintf(stdout, "."); + fflush(stdout); + + if (!BN_pseudo_rand(x, BN_num_bits(y) - 1, 0, 0)) + ABORT; + if (!BN_add(z, x, y)) + ABORT; + BN_set_negative(z, 1); + scalars[0] = x; + scalars[1] = y; + scalars[2] = z; /* z = -(x+y) */ + + if (!EC_POINTs_mul(group, P, NULL, 3, points, scalars, ctx)) + ABORT; + if (!EC_POINT_is_at_infinity(group, P)) + ABORT; + + fprintf(stdout, " ok\n\n"); + } + +# if 0 + timings(C2_K163, TIMING_BASE_PT, ctx); + timings(C2_K163, TIMING_RAND_PT, ctx); + timings(C2_K163, TIMING_SIMUL, ctx); + timings(C2_B163, TIMING_BASE_PT, ctx); + timings(C2_B163, TIMING_RAND_PT, ctx); + timings(C2_B163, TIMING_SIMUL, ctx); + timings(C2_K233, TIMING_BASE_PT, ctx); + timings(C2_K233, TIMING_RAND_PT, ctx); + timings(C2_K233, TIMING_SIMUL, ctx); + timings(C2_B233, TIMING_BASE_PT, ctx); + timings(C2_B233, TIMING_RAND_PT, ctx); + timings(C2_B233, TIMING_SIMUL, ctx); + timings(C2_K283, TIMING_BASE_PT, ctx); + timings(C2_K283, TIMING_RAND_PT, ctx); + timings(C2_K283, TIMING_SIMUL, ctx); + timings(C2_B283, TIMING_BASE_PT, ctx); + timings(C2_B283, TIMING_RAND_PT, ctx); + timings(C2_B283, TIMING_SIMUL, ctx); + timings(C2_K409, TIMING_BASE_PT, ctx); + timings(C2_K409, TIMING_RAND_PT, ctx); + timings(C2_K409, TIMING_SIMUL, ctx); + timings(C2_B409, TIMING_BASE_PT, ctx); + timings(C2_B409, TIMING_RAND_PT, ctx); + timings(C2_B409, TIMING_SIMUL, ctx); + timings(C2_K571, TIMING_BASE_PT, ctx); + timings(C2_K571, TIMING_RAND_PT, ctx); + timings(C2_K571, TIMING_SIMUL, ctx); + timings(C2_B571, TIMING_BASE_PT, ctx); + timings(C2_B571, TIMING_RAND_PT, ctx); + timings(C2_B571, TIMING_SIMUL, ctx); +# endif + + if (ctx) + BN_CTX_free(ctx); + BN_free(p); + BN_free(a); + BN_free(b); + EC_GROUP_free(group); + EC_POINT_free(P); + EC_POINT_free(Q); + EC_POINT_free(R); + BN_free(x); + BN_free(y); + BN_free(z); + BN_free(cof); + + if (C2_K163) + EC_GROUP_free(C2_K163); + if (C2_B163) + EC_GROUP_free(C2_B163); + if (C2_K233) + EC_GROUP_free(C2_K233); + if (C2_B233) + EC_GROUP_free(C2_B233); + if (C2_K283) + EC_GROUP_free(C2_K283); + if (C2_B283) + EC_GROUP_free(C2_B283); + if (C2_K409) + EC_GROUP_free(C2_K409); + if (C2_B409) + EC_GROUP_free(C2_B409); + if (C2_K571) + EC_GROUP_free(C2_K571); + if (C2_B571) + EC_GROUP_free(C2_B571); + +} +# endif + +static void internal_curve_test(void) +{ + EC_builtin_curve *curves = NULL; + size_t crv_len = 0, n = 0; + int ok = 1; + + crv_len = EC_get_builtin_curves(NULL, 0); + + curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len); + + if (curves == NULL) + return; + + if (!EC_get_builtin_curves(curves, crv_len)) { + OPENSSL_free(curves); + return; + } + + fprintf(stdout, "testing internal curves: "); + + for (n = 0; n < crv_len; n++) { + EC_GROUP *group = NULL; + int nid = curves[n].nid; + if ((group = EC_GROUP_new_by_curve_name(nid)) == NULL) { + ok = 0; + fprintf(stdout, "\nEC_GROUP_new_curve_name() failed with" + " curve %s\n", OBJ_nid2sn(nid)); + /* try next curve */ + continue; + } + if (!EC_GROUP_check(group, NULL)) { + ok = 0; + fprintf(stdout, "\nEC_GROUP_check() failed with" + " curve %s\n", OBJ_nid2sn(nid)); + EC_GROUP_free(group); + /* try the next curve */ + continue; + } + fprintf(stdout, "."); + fflush(stdout); + EC_GROUP_free(group); + } + if (ok) + fprintf(stdout, " ok\n\n"); + else { + fprintf(stdout, " failed\n\n"); + ABORT; + } + OPENSSL_free(curves); + return; +} + +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +/* + * nistp_test_params contains magic numbers for testing our optimized + * implementations of several NIST curves with characteristic > 3. + */ +struct nistp_test_params { + const EC_METHOD *(*meth) (); + int degree; + /* + * Qx, Qy and D are taken from + * http://csrc.nist.gov/groups/ST/toolkit/documents/Examples/ECDSA_Prime.pdf + * Otherwise, values are standard curve parameters from FIPS 180-3 + */ + const char *p, *a, *b, *Qx, *Qy, *Gx, *Gy, *order, *d; +}; + +static const struct nistp_test_params nistp_tests_params[] = { + { + /* P-224 */ + EC_GFp_nistp224_method, + 224, + /* p */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF000000000000000000000001", + /* a */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFE", + /* b */ + "B4050A850C04B3ABF54132565044B0B7D7BFD8BA270B39432355FFB4", + /* Qx */ + "E84FB0B8E7000CB657D7973CF6B42ED78B301674276DF744AF130B3E", + /* Qy */ + "4376675C6FC5612C21A0FF2D2A89D2987DF7A2BC52183B5982298555", + /* Gx */ + "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21", + /* Gy */ + "BD376388B5F723FB4C22DFE6CD4375A05A07476444D5819985007E34", + /* order */ + "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D", + /* d */ + "3F0C488E987C80BE0FEE521F8D90BE6034EC69AE11CA72AA777481E8", + }, + { + /* P-256 */ + EC_GFp_nistp256_method, + 256, + /* p */ + "ffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + /* a */ + "ffffffff00000001000000000000000000000000fffffffffffffffffffffffc", + /* b */ + "5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", + /* Qx */ + "b7e08afdfe94bad3f1dc8c734798ba1c62b3a0ad1e9ea2a38201cd0889bc7a19", + /* Qy */ + "3603f747959dbf7a4bb226e41928729063adc7ae43529e61b563bbc606cc5e09", + /* Gx */ + "6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", + /* Gy */ + "4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + /* order */ + "ffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + /* d */ + "c477f9f65c22cce20657faa5b2d1d8122336f851a508a1ed04e479c34985bf96", + }, + { + /* P-521 */ + EC_GFp_nistp521_method, + 521, + /* p */ + "1ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + /* a */ + "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", + /* b */ + "051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef109e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", + /* Qx */ + "0098e91eef9a68452822309c52fab453f5f117c1da8ed796b255e9ab8f6410cca16e59df403a6bdc6ca467a37056b1e54b3005d8ac030decfeb68df18b171885d5c4", + /* Qy */ + "0164350c321aecfc1cca1ba4364c9b15656150b4b78d6a48d7d28e7f31985ef17be8554376b72900712c4b83ad668327231526e313f5f092999a4632fd50d946bc2e", + /* Gx */ + "c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", + /* Gy */ + "11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", + /* order */ + "1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", + /* d */ + "0100085f47b8e1b8b11b7eb33028c0b2888e304bfc98501955b45bba1478dc184eeedf09b86a5f7c21994406072787205e69a63709fe35aa93ba333514b24f961722", + }, +}; + +static void nistp_single_test(const struct nistp_test_params *test) +{ + BN_CTX *ctx; + BIGNUM *p, *a, *b, *x, *y, *n, *m, *order; + EC_GROUP *NISTP; + EC_POINT *G, *P, *Q, *Q_CHECK; + + fprintf(stdout, "\nNIST curve P-%d (optimised implementation):\n", + test->degree); + ctx = BN_CTX_new(); + p = BN_new(); + a = BN_new(); + b = BN_new(); + x = BN_new(); + y = BN_new(); + m = BN_new(); + n = BN_new(); + order = BN_new(); + + NISTP = EC_GROUP_new(test->meth()); + if (!NISTP) + ABORT; + if (!BN_hex2bn(&p, test->p)) + ABORT; + if (1 != BN_is_prime_ex(p, BN_prime_checks, ctx, NULL)) + ABORT; + if (!BN_hex2bn(&a, test->a)) + ABORT; + if (!BN_hex2bn(&b, test->b)) + ABORT; + if (!EC_GROUP_set_curve_GFp(NISTP, p, a, b, ctx)) + ABORT; + G = EC_POINT_new(NISTP); + P = EC_POINT_new(NISTP); + Q = EC_POINT_new(NISTP); + Q_CHECK = EC_POINT_new(NISTP); + if (!BN_hex2bn(&x, test->Qx)) + ABORT; + if (!BN_hex2bn(&y, test->Qy)) + ABORT; + if (!EC_POINT_set_affine_coordinates_GFp(NISTP, Q_CHECK, x, y, ctx)) + ABORT; + if (!BN_hex2bn(&x, test->Gx)) + ABORT; + if (!BN_hex2bn(&y, test->Gy)) + ABORT; + if (!EC_POINT_set_affine_coordinates_GFp(NISTP, G, x, y, ctx)) + ABORT; + if (!BN_hex2bn(&order, test->order)) + ABORT; + if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) + ABORT; + + fprintf(stdout, "verify degree ... "); + if (EC_GROUP_get_degree(NISTP) != test->degree) + ABORT; + fprintf(stdout, "ok\n"); + + fprintf(stdout, "NIST test vectors ... "); + if (!BN_hex2bn(&n, test->d)) + ABORT; + /* fixed point multiplication */ + EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + /* random point multiplication */ + EC_POINT_mul(NISTP, Q, NULL, G, n, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + + /* set generator to P = 2*G, where G is the standard generator */ + if (!EC_POINT_dbl(NISTP, P, G, ctx)) + ABORT; + if (!EC_GROUP_set_generator(NISTP, P, order, BN_value_one())) + ABORT; + /* set the scalar to m=n/2, where n is the NIST test scalar */ + if (!BN_rshift(m, n, 1)) + ABORT; + + /* test the non-standard generator */ + /* fixed point multiplication */ + EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + /* random point multiplication */ + EC_POINT_mul(NISTP, Q, NULL, P, m, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + + /* now repeat all tests with precomputation */ + if (!EC_GROUP_precompute_mult(NISTP, ctx)) + ABORT; + + /* fixed point multiplication */ + EC_POINT_mul(NISTP, Q, m, NULL, NULL, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + /* random point multiplication */ + EC_POINT_mul(NISTP, Q, NULL, P, m, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + + /* reset generator */ + if (!EC_GROUP_set_generator(NISTP, G, order, BN_value_one())) + ABORT; + /* fixed point multiplication */ + EC_POINT_mul(NISTP, Q, n, NULL, NULL, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + /* random point multiplication */ + EC_POINT_mul(NISTP, Q, NULL, G, n, ctx); + if (0 != EC_POINT_cmp(NISTP, Q, Q_CHECK, ctx)) + ABORT; + + fprintf(stdout, "ok\n"); + group_order_tests(NISTP); +# if 0 + timings(NISTP, TIMING_BASE_PT, ctx); + timings(NISTP, TIMING_RAND_PT, ctx); +# endif + EC_GROUP_free(NISTP); + EC_POINT_free(G); + EC_POINT_free(P); + EC_POINT_free(Q); + EC_POINT_free(Q_CHECK); + BN_free(n); + BN_free(m); + BN_free(p); + BN_free(a); + BN_free(b); + BN_free(x); + BN_free(y); + BN_free(order); + BN_CTX_free(ctx); +} + +static void nistp_tests() +{ + unsigned i; + + for (i = 0; + i < sizeof(nistp_tests_params) / sizeof(struct nistp_test_params); + i++) { + nistp_single_test(&nistp_tests_params[i]); + } +} +# endif + +static const char rnd_seed[] = + "string to make the random number generator think it has entropy"; + +int main(int argc, char *argv[]) +{ + + /* enable memory leak checking unless explicitly disabled */ + if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) + && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) { + CRYPTO_malloc_debug_init(); + CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); + } else { + /* OPENSSL_DEBUG_MEMORY=off */ + CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); + } + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + ERR_load_crypto_strings(); + + RAND_seed(rnd_seed, sizeof rnd_seed); /* or BN_generate_prime may fail */ + + prime_field_tests(); + puts(""); +# ifndef OPENSSL_NO_EC2M + char2_field_tests(); +# endif +# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 + nistp_tests(); +# endif + /* test the internal curves */ + internal_curve_test(); + +# ifndef OPENSSL_NO_ENGINE + ENGINE_cleanup(); +# endif + CRYPTO_cleanup_all_ex_data(); + ERR_free_strings(); + ERR_remove_thread_state(NULL); + CRYPTO_mem_leaks_fp(stderr); + + return 0; +} +#endif diff --git a/libs/openssl/crypto/ecdh/ecdh.h b/libs/openssl/crypto/ecdh/ecdh.h new file mode 100644 index 00000000..a9b811ab --- /dev/null +++ b/libs/openssl/crypto/ecdh/ecdh.h @@ -0,0 +1,127 @@ +/* crypto/ecdh/ecdh.h */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ECDH_H +# define HEADER_ECDH_H + +# include + +# ifdef OPENSSL_NO_ECDH +# error ECDH is disabled. +# endif + +# include +# include +# ifndef OPENSSL_NO_DEPRECATED +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +const ECDH_METHOD *ECDH_OpenSSL(void); + +void ECDH_set_default_method(const ECDH_METHOD *); +const ECDH_METHOD *ECDH_get_default_method(void); +int ECDH_set_method(EC_KEY *, const ECDH_METHOD *); + +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + EC_KEY *ecdh, void *(*KDF) (const void *in, size_t inlen, + void *out, size_t *outlen)); + +int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new + *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg); +void *ECDH_get_ex_data(EC_KEY *d, int idx); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ECDH_strings(void); + +/* Error codes for the ECDH functions. */ + +/* Function codes. */ +# define ECDH_F_ECDH_CHECK 102 +# define ECDH_F_ECDH_COMPUTE_KEY 100 +# define ECDH_F_ECDH_DATA_NEW_METHOD 101 + +/* Reason codes. */ +# define ECDH_R_KDF_FAILED 102 +# define ECDH_R_NON_FIPS_METHOD 103 +# define ECDH_R_NO_PRIVATE_VALUE 100 +# define ECDH_R_POINT_ARITHMETIC_FAILURE 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/ecdh/ecdhtest.c b/libs/openssl/crypto/ecdh/ecdhtest.c new file mode 100644 index 00000000..996321d1 --- /dev/null +++ b/libs/openssl/crypto/ecdh/ecdhtest.c @@ -0,0 +1,410 @@ +/* crypto/ecdh/ecdhtest.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include "../e_os.h" + +#include /* for OPENSSL_NO_ECDH */ +#include +#include +#include +#include +#include +#include +#include + +#ifdef OPENSSL_NO_ECDH +int main(int argc, char *argv[]) +{ + printf("No ECDH support\n"); + return (0); +} +#else +# include +# include + +# ifdef OPENSSL_SYS_WIN16 +# define MS_CALLBACK _far _loadds +# else +# define MS_CALLBACK +# endif + +# if 0 +static void MS_CALLBACK cb(int p, int n, void *arg); +# endif + +static const char rnd_seed[] = + "string to make the random number generator think it has entropy"; + +static const int KDF1_SHA1_len = 20; +static void *KDF1_SHA1(const void *in, size_t inlen, void *out, + size_t *outlen) +{ +# ifndef OPENSSL_NO_SHA + if (*outlen < SHA_DIGEST_LENGTH) + return NULL; + else + *outlen = SHA_DIGEST_LENGTH; + return SHA1(in, inlen, out); +# else + return NULL; +# endif +} + +static int test_ecdh_curve(int nid, const char *text, BN_CTX *ctx, BIO *out) +{ + EC_KEY *a = NULL; + EC_KEY *b = NULL; + BIGNUM *x_a = NULL, *y_a = NULL, *x_b = NULL, *y_b = NULL; + char buf[12]; + unsigned char *abuf = NULL, *bbuf = NULL; + int i, alen, blen, aout, bout, ret = 0; + const EC_GROUP *group; + + a = EC_KEY_new_by_curve_name(nid); + b = EC_KEY_new_by_curve_name(nid); + if (a == NULL || b == NULL) + goto err; + + group = EC_KEY_get0_group(a); + + if ((x_a = BN_new()) == NULL) + goto err; + if ((y_a = BN_new()) == NULL) + goto err; + if ((x_b = BN_new()) == NULL) + goto err; + if ((y_b = BN_new()) == NULL) + goto err; + + BIO_puts(out, "Testing key generation with "); + BIO_puts(out, text); +# ifdef NOISY + BIO_puts(out, "\n"); +# else + (void)BIO_flush(out); +# endif + + if (!EC_KEY_generate_key(a)) + goto err; + + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == + NID_X9_62_prime_field) { + if (!EC_POINT_get_affine_coordinates_GFp + (group, EC_KEY_get0_public_key(a), x_a, y_a, ctx)) + goto err; + } +# ifndef OPENSSL_NO_EC2M + else { + if (!EC_POINT_get_affine_coordinates_GF2m(group, + EC_KEY_get0_public_key(a), + x_a, y_a, ctx)) + goto err; + } +# endif +# ifdef NOISY + BIO_puts(out, " pri 1="); + BN_print(out, a->priv_key); + BIO_puts(out, "\n pub 1="); + BN_print(out, x_a); + BIO_puts(out, ","); + BN_print(out, y_a); + BIO_puts(out, "\n"); +# else + BIO_printf(out, " ."); + (void)BIO_flush(out); +# endif + + if (!EC_KEY_generate_key(b)) + goto err; + + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == + NID_X9_62_prime_field) { + if (!EC_POINT_get_affine_coordinates_GFp + (group, EC_KEY_get0_public_key(b), x_b, y_b, ctx)) + goto err; + } +# ifndef OPENSSL_NO_EC2M + else { + if (!EC_POINT_get_affine_coordinates_GF2m(group, + EC_KEY_get0_public_key(b), + x_b, y_b, ctx)) + goto err; + } +# endif + +# ifdef NOISY + BIO_puts(out, " pri 2="); + BN_print(out, b->priv_key); + BIO_puts(out, "\n pub 2="); + BN_print(out, x_b); + BIO_puts(out, ","); + BN_print(out, y_b); + BIO_puts(out, "\n"); +# else + BIO_printf(out, "."); + (void)BIO_flush(out); +# endif + + alen = KDF1_SHA1_len; + abuf = (unsigned char *)OPENSSL_malloc(alen); + aout = + ECDH_compute_key(abuf, alen, EC_KEY_get0_public_key(b), a, KDF1_SHA1); + +# ifdef NOISY + BIO_puts(out, " key1 ="); + for (i = 0; i < aout; i++) { + sprintf(buf, "%02X", abuf[i]); + BIO_puts(out, buf); + } + BIO_puts(out, "\n"); +# else + BIO_printf(out, "."); + (void)BIO_flush(out); +# endif + + blen = KDF1_SHA1_len; + bbuf = (unsigned char *)OPENSSL_malloc(blen); + bout = + ECDH_compute_key(bbuf, blen, EC_KEY_get0_public_key(a), b, KDF1_SHA1); + +# ifdef NOISY + BIO_puts(out, " key2 ="); + for (i = 0; i < bout; i++) { + sprintf(buf, "%02X", bbuf[i]); + BIO_puts(out, buf); + } + BIO_puts(out, "\n"); +# else + BIO_printf(out, "."); + (void)BIO_flush(out); +# endif + + if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) { +# ifndef NOISY + BIO_printf(out, " failed\n\n"); + BIO_printf(out, "key a:\n"); + BIO_printf(out, "private key: "); + BN_print(out, EC_KEY_get0_private_key(a)); + BIO_printf(out, "\n"); + BIO_printf(out, "public key (x,y): "); + BN_print(out, x_a); + BIO_printf(out, ","); + BN_print(out, y_a); + BIO_printf(out, "\nkey b:\n"); + BIO_printf(out, "private key: "); + BN_print(out, EC_KEY_get0_private_key(b)); + BIO_printf(out, "\n"); + BIO_printf(out, "public key (x,y): "); + BN_print(out, x_b); + BIO_printf(out, ","); + BN_print(out, y_b); + BIO_printf(out, "\n"); + BIO_printf(out, "generated key a: "); + for (i = 0; i < bout; i++) { + sprintf(buf, "%02X", bbuf[i]); + BIO_puts(out, buf); + } + BIO_printf(out, "\n"); + BIO_printf(out, "generated key b: "); + for (i = 0; i < aout; i++) { + sprintf(buf, "%02X", abuf[i]); + BIO_puts(out, buf); + } + BIO_printf(out, "\n"); +# endif + fprintf(stderr, "Error in ECDH routines\n"); + ret = 0; + } else { +# ifndef NOISY + BIO_printf(out, " ok\n"); +# endif + ret = 1; + } + err: + ERR_print_errors_fp(stderr); + + if (abuf != NULL) + OPENSSL_free(abuf); + if (bbuf != NULL) + OPENSSL_free(bbuf); + if (x_a) + BN_free(x_a); + if (y_a) + BN_free(y_a); + if (x_b) + BN_free(x_b); + if (y_b) + BN_free(y_b); + if (b) + EC_KEY_free(b); + if (a) + EC_KEY_free(a); + return (ret); +} + +int main(int argc, char *argv[]) +{ + BN_CTX *ctx = NULL; + int ret = 1; + BIO *out; + + CRYPTO_malloc_debug_init(); + CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + +# ifdef OPENSSL_SYS_WIN32 + CRYPTO_malloc_init(); +# endif + + RAND_seed(rnd_seed, sizeof rnd_seed); + + out = BIO_new(BIO_s_file()); + if (out == NULL) + EXIT(1); + BIO_set_fp(out, stdout, BIO_NOCLOSE); + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + + /* NIST PRIME CURVES TESTS */ + if (!test_ecdh_curve + (NID_X9_62_prime192v1, "NIST Prime-Curve P-192", ctx, out)) + goto err; + if (!test_ecdh_curve(NID_secp224r1, "NIST Prime-Curve P-224", ctx, out)) + goto err; + if (!test_ecdh_curve + (NID_X9_62_prime256v1, "NIST Prime-Curve P-256", ctx, out)) + goto err; + if (!test_ecdh_curve(NID_secp384r1, "NIST Prime-Curve P-384", ctx, out)) + goto err; + if (!test_ecdh_curve(NID_secp521r1, "NIST Prime-Curve P-521", ctx, out)) + goto err; +# ifndef OPENSSL_NO_EC2M + /* NIST BINARY CURVES TESTS */ + if (!test_ecdh_curve(NID_sect163k1, "NIST Binary-Curve K-163", ctx, out)) + goto err; + if (!test_ecdh_curve(NID_sect163r2, "NIST Binary-Curve B-163", ctx, out)) + goto err; + if (!test_ecdh_curve(NID_sect233k1, "NIST Binary-Curve K-233", ctx, out)) + goto err; + if (!test_ecdh_curve(NID_sect233r1, "NIST Binary-Curve B-233", ctx, out)) + goto err; + if (!test_ecdh_curve(NID_sect283k1, "NIST Binary-Curve K-283", ctx, out)) + goto err; + if (!test_ecdh_curve(NID_sect283r1, "NIST Binary-Curve B-283", ctx, out)) + goto err; + if (!test_ecdh_curve(NID_sect409k1, "NIST Binary-Curve K-409", ctx, out)) + goto err; + if (!test_ecdh_curve(NID_sect409r1, "NIST Binary-Curve B-409", ctx, out)) + goto err; + if (!test_ecdh_curve(NID_sect571k1, "NIST Binary-Curve K-571", ctx, out)) + goto err; + if (!test_ecdh_curve(NID_sect571r1, "NIST Binary-Curve B-571", ctx, out)) + goto err; +# endif + + ret = 0; + + err: + ERR_print_errors_fp(stderr); + if (ctx) + BN_CTX_free(ctx); + BIO_free(out); + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + CRYPTO_mem_leaks_fp(stderr); + EXIT(ret); + return (ret); +} + +# if 0 +static void MS_CALLBACK cb(int p, int n, void *arg) +{ + char c = '*'; + + if (p == 0) + c = '.'; + if (p == 1) + c = '+'; + if (p == 2) + c = '*'; + if (p == 3) + c = '\n'; + BIO_write((BIO *)arg, &c, 1); + (void)BIO_flush((BIO *)arg); +# ifdef LINT + p = n; +# endif +} +# endif +#endif diff --git a/libs/openssl/crypto/ecdh/ech_err.c b/libs/openssl/crypto/ecdh/ech_err.c new file mode 100644 index 00000000..af9f625b --- /dev/null +++ b/libs/openssl/crypto/ecdh/ech_err.c @@ -0,0 +1,98 @@ +/* crypto/ecdh/ech_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDH,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDH,0,reason) + +static ERR_STRING_DATA ECDH_str_functs[] = { + {ERR_FUNC(ECDH_F_ECDH_CHECK), "ECDH_CHECK"}, + {ERR_FUNC(ECDH_F_ECDH_COMPUTE_KEY), "ECDH_compute_key"}, + {ERR_FUNC(ECDH_F_ECDH_DATA_NEW_METHOD), "ECDH_DATA_new_method"}, + {0, NULL} +}; + +static ERR_STRING_DATA ECDH_str_reasons[] = { + {ERR_REASON(ECDH_R_KDF_FAILED), "KDF failed"}, + {ERR_REASON(ECDH_R_NON_FIPS_METHOD), "non fips method"}, + {ERR_REASON(ECDH_R_NO_PRIVATE_VALUE), "no private value"}, + {ERR_REASON(ECDH_R_POINT_ARITHMETIC_FAILURE), "point arithmetic failure"}, + {0, NULL} +}; + +#endif + +void ERR_load_ECDH_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(ECDH_str_functs[0].error) == NULL) { + ERR_load_strings(0, ECDH_str_functs); + ERR_load_strings(0, ECDH_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/ecdh/ech_key.c b/libs/openssl/crypto/ecdh/ech_key.c new file mode 100644 index 00000000..4f144989 --- /dev/null +++ b/libs/openssl/crypto/ecdh/ech_key.c @@ -0,0 +1,81 @@ +/* crypto/ecdh/ecdh_key.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ech_locl.h" + +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + EC_KEY *eckey, + void *(*KDF) (const void *in, size_t inlen, void *out, + size_t *outlen)) +{ + ECDH_DATA *ecdh = ecdh_check(eckey); + if (ecdh == NULL) + return 0; + return ecdh->meth->compute_key(out, outlen, pub_key, eckey, KDF); +} diff --git a/libs/openssl/crypto/ecdh/ech_lib.c b/libs/openssl/crypto/ecdh/ech_lib.c new file mode 100644 index 00000000..cbc21d1a --- /dev/null +++ b/libs/openssl/crypto/ecdh/ech_lib.c @@ -0,0 +1,265 @@ +/* crypto/ecdh/ech_lib.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ech_locl.h" +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include +#ifdef OPENSSL_FIPS +# include +#endif + +const char ECDH_version[] = "ECDH" OPENSSL_VERSION_PTEXT; + +static const ECDH_METHOD *default_ECDH_method = NULL; + +static void *ecdh_data_new(void); +static void *ecdh_data_dup(void *); +static void ecdh_data_free(void *); + +void ECDH_set_default_method(const ECDH_METHOD *meth) +{ + default_ECDH_method = meth; +} + +const ECDH_METHOD *ECDH_get_default_method(void) +{ + if (!default_ECDH_method) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_ecdh_openssl(); + else + return ECDH_OpenSSL(); +#else + default_ECDH_method = ECDH_OpenSSL(); +#endif + } + return default_ECDH_method; +} + +int ECDH_set_method(EC_KEY *eckey, const ECDH_METHOD *meth) +{ + ECDH_DATA *ecdh; + + ecdh = ecdh_check(eckey); + + if (ecdh == NULL) + return 0; + +#if 0 + mtmp = ecdh->meth; + if (mtmp->finish) + mtmp->finish(eckey); +#endif +#ifndef OPENSSL_NO_ENGINE + if (ecdh->engine) { + ENGINE_finish(ecdh->engine); + ecdh->engine = NULL; + } +#endif + ecdh->meth = meth; +#if 0 + if (meth->init) + meth->init(eckey); +#endif + return 1; +} + +static ECDH_DATA *ECDH_DATA_new_method(ENGINE *engine) +{ + ECDH_DATA *ret; + + ret = (ECDH_DATA *)OPENSSL_malloc(sizeof(ECDH_DATA)); + if (ret == NULL) { + ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + ret->init = NULL; + + ret->meth = ECDH_get_default_method(); + ret->engine = engine; +#ifndef OPENSSL_NO_ENGINE + if (!ret->engine) + ret->engine = ENGINE_get_default_ECDH(); + if (ret->engine) { + ret->meth = ENGINE_get_ECDH(ret->engine); + if (!ret->meth) { + ECDHerr(ECDH_F_ECDH_DATA_NEW_METHOD, ERR_R_ENGINE_LIB); + ENGINE_finish(ret->engine); + OPENSSL_free(ret); + return NULL; + } + } +#endif + + ret->flags = ret->meth->flags; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data); +#if 0 + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, ret, &ret->ex_data); + OPENSSL_free(ret); + ret = NULL; + } +#endif + return (ret); +} + +static void *ecdh_data_new(void) +{ + return (void *)ECDH_DATA_new_method(NULL); +} + +static void *ecdh_data_dup(void *data) +{ + ECDH_DATA *r = (ECDH_DATA *)data; + + /* XXX: dummy operation */ + if (r == NULL) + return NULL; + + return (void *)ecdh_data_new(); +} + +void ecdh_data_free(void *data) +{ + ECDH_DATA *r = (ECDH_DATA *)data; + +#ifndef OPENSSL_NO_ENGINE + if (r->engine) + ENGINE_finish(r->engine); +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDH, r, &r->ex_data); + + OPENSSL_cleanse((void *)r, sizeof(ECDH_DATA)); + + OPENSSL_free(r); +} + +ECDH_DATA *ecdh_check(EC_KEY *key) +{ + ECDH_DATA *ecdh_data; + + void *data = EC_KEY_get_key_method_data(key, ecdh_data_dup, + ecdh_data_free, ecdh_data_free); + if (data == NULL) { + ecdh_data = (ECDH_DATA *)ecdh_data_new(); + if (ecdh_data == NULL) + return NULL; + data = EC_KEY_insert_key_method_data(key, (void *)ecdh_data, + ecdh_data_dup, ecdh_data_free, + ecdh_data_free); + if (data != NULL) { + /* + * Another thread raced us to install the key_method data and + * won. + */ + ecdh_data_free(ecdh_data); + ecdh_data = (ECDH_DATA *)data; + } + } else + ecdh_data = (ECDH_DATA *)data; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(ecdh_data->flags & ECDH_FLAG_FIPS_METHOD) + && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) { + ECDHerr(ECDH_F_ECDH_CHECK, ECDH_R_NON_FIPS_METHOD); + return NULL; + } +#endif + + return ecdh_data; +} + +int ECDH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDH, argl, argp, + new_func, dup_func, free_func); +} + +int ECDH_set_ex_data(EC_KEY *d, int idx, void *arg) +{ + ECDH_DATA *ecdh; + ecdh = ecdh_check(d); + if (ecdh == NULL) + return 0; + return (CRYPTO_set_ex_data(&ecdh->ex_data, idx, arg)); +} + +void *ECDH_get_ex_data(EC_KEY *d, int idx) +{ + ECDH_DATA *ecdh; + ecdh = ecdh_check(d); + if (ecdh == NULL) + return NULL; + return (CRYPTO_get_ex_data(&ecdh->ex_data, idx)); +} diff --git a/libs/openssl/crypto/ecdh/ech_locl.h b/libs/openssl/crypto/ecdh/ech_locl.h new file mode 100644 index 00000000..4e66024c --- /dev/null +++ b/libs/openssl/crypto/ecdh/ech_locl.h @@ -0,0 +1,104 @@ +/* crypto/ecdh/ech_locl.h */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_ECH_LOCL_H +# define HEADER_ECH_LOCL_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ecdh_method { + const char *name; + int (*compute_key) (void *key, size_t outlen, const EC_POINT *pub_key, + EC_KEY *ecdh, void *(*KDF) (const void *in, + size_t inlen, void *out, + size_t *outlen)); +# if 0 + int (*init) (EC_KEY *eckey); + int (*finish) (EC_KEY *eckey); +# endif + int flags; + char *app_data; +}; + +/* + * If this flag is set the ECDH method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define ECDH_FLAG_FIPS_METHOD 0x1 + +typedef struct ecdh_data_st { + /* EC_KEY_METH_DATA part */ + int (*init) (EC_KEY *); + /* method specific part */ + ENGINE *engine; + int flags; + const ECDH_METHOD *meth; + CRYPTO_EX_DATA ex_data; +} ECDH_DATA; + +ECDH_DATA *ecdh_check(EC_KEY *); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_ECH_LOCL_H */ diff --git a/libs/openssl/crypto/ecdh/ech_ossl.c b/libs/openssl/crypto/ecdh/ech_ossl.c new file mode 100644 index 00000000..d448b19a --- /dev/null +++ b/libs/openssl/crypto/ecdh/ech_ossl.c @@ -0,0 +1,208 @@ +/* crypto/ecdh/ech_ossl.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH software is originally written by Douglas Stebila of + * Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#include "cryptlib.h" + +#include "ech_locl.h" +#include +#include +#include +#include + +static int ecdh_compute_key(void *out, size_t len, const EC_POINT *pub_key, + EC_KEY *ecdh, + void *(*KDF) (const void *in, size_t inlen, + void *out, size_t *outlen)); + +static ECDH_METHOD openssl_ecdh_meth = { + "OpenSSL ECDH method", + ecdh_compute_key, +#if 0 + NULL, /* init */ + NULL, /* finish */ +#endif + 0, /* flags */ + NULL /* app_data */ +}; + +const ECDH_METHOD *ECDH_OpenSSL(void) +{ + return &openssl_ecdh_meth; +} + +/*- + * This implementation is based on the following primitives in the IEEE 1363 standard: + * - ECKAS-DH1 + * - ECSVDP-DH + * Finally an optional KDF is applied. + */ +static int ecdh_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + EC_KEY *ecdh, + void *(*KDF) (const void *in, size_t inlen, + void *out, size_t *outlen)) +{ + BN_CTX *ctx; + EC_POINT *tmp = NULL; + BIGNUM *x = NULL, *y = NULL; + const BIGNUM *priv_key; + const EC_GROUP *group; + int ret = -1; + size_t buflen, len; + unsigned char *buf = NULL; + + if (outlen > INT_MAX) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); /* sort of, + * anyway */ + return -1; + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + x = BN_CTX_get(ctx); + y = BN_CTX_get(ctx); + + priv_key = EC_KEY_get0_private_key(ecdh); + if (priv_key == NULL) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_NO_PRIVATE_VALUE); + goto err; + } + + group = EC_KEY_get0_group(ecdh); + if ((tmp = EC_POINT_new(group)) == NULL) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_POINT_mul(group, tmp, NULL, pub_key, priv_key, ctx)) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE); + goto err; + } + + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == + NID_X9_62_prime_field) { + if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, y, ctx)) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE); + goto err; + } + } +#ifndef OPENSSL_NO_EC2M + else { + if (!EC_POINT_get_affine_coordinates_GF2m(group, tmp, x, y, ctx)) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_POINT_ARITHMETIC_FAILURE); + goto err; + } + } +#endif + + buflen = (EC_GROUP_get_degree(group) + 7) / 8; + len = BN_num_bytes(x); + if (len > buflen) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_INTERNAL_ERROR); + goto err; + } + if ((buf = OPENSSL_malloc(buflen)) == NULL) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + memset(buf, 0, buflen - len); + if (len != (size_t)BN_bn2bin(x, buf + buflen - len)) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ERR_R_BN_LIB); + goto err; + } + + if (KDF != 0) { + if (KDF(buf, buflen, out, &outlen) == NULL) { + ECDHerr(ECDH_F_ECDH_COMPUTE_KEY, ECDH_R_KDF_FAILED); + goto err; + } + ret = outlen; + } else { + /* no KDF, just copy as much as we can */ + if (outlen > buflen) + outlen = buflen; + memcpy(out, buf, outlen); + ret = outlen; + } + + err: + if (tmp) + EC_POINT_free(tmp); + if (ctx) + BN_CTX_end(ctx); + if (ctx) + BN_CTX_free(ctx); + if (buf) + OPENSSL_free(buf); + return (ret); +} diff --git a/libs/openssl/crypto/ecdsa/ecdsa.h b/libs/openssl/crypto/ecdsa/ecdsa.h new file mode 100644 index 00000000..faf76b11 --- /dev/null +++ b/libs/openssl/crypto/ecdsa/ecdsa.h @@ -0,0 +1,260 @@ +/* crypto/ecdsa/ecdsa.h */ +/** + * \file crypto/ecdsa/ecdsa.h Include file for the OpenSSL ECDSA functions + * \author Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_ECDSA_H +# define HEADER_ECDSA_H + +# include + +# ifdef OPENSSL_NO_ECDSA +# error ECDSA is disabled. +# endif + +# include +# include +# ifndef OPENSSL_NO_DEPRECATED +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct ECDSA_SIG_st { + BIGNUM *r; + BIGNUM *s; +} ECDSA_SIG; + +/** Allocates and initialize a ECDSA_SIG structure + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_SIG_new(void); + +/** frees a ECDSA_SIG structure + * \param sig pointer to the ECDSA_SIG structure + */ +void ECDSA_SIG_free(ECDSA_SIG *sig); + +/** DER encode content of ECDSA_SIG object (note: this function modifies *pp + * (*pp += length of the DER encoded signature)). + * \param sig pointer to the ECDSA_SIG object + * \param pp pointer to a unsigned char pointer for the output or NULL + * \return the length of the DER encoded ECDSA_SIG object or 0 + */ +int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp); + +/** Decodes a DER encoded ECDSA signature (note: this function changes *pp + * (*pp += len)). + * \param sig pointer to ECDSA_SIG pointer (may be NULL) + * \param pp memory buffer with the DER encoded signature + * \param len length of the buffer + * \return pointer to the decoded ECDSA_SIG structure (or NULL) + */ +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **sig, const unsigned char **pp, long len); + +/** Computes the ECDSA signature of the given hash value using + * the supplied private key and returns the created signature. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dgst_len, + EC_KEY *eckey); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optioanl), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return pointer to a ECDSA_SIG structure or NULL if an error occurred + */ +ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dgstlen, + const BIGNUM *kinv, const BIGNUM *rp, + EC_KEY *eckey); + +/** Verifies that the supplied signature is a valid ECDSA + * signature of the supplied hash value using the supplied public key. + * \param dgst pointer to the hash value + * \param dgst_len length of the hash value + * \param sig ECDSA_SIG structure + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); + +const ECDSA_METHOD *ECDSA_OpenSSL(void); + +/** Sets the default ECDSA method + * \param meth new default ECDSA_METHOD + */ +void ECDSA_set_default_method(const ECDSA_METHOD *meth); + +/** Returns the default ECDSA method + * \return pointer to ECDSA_METHOD structure containing the default method + */ +const ECDSA_METHOD *ECDSA_get_default_method(void); + +/** Sets method to be used for the ECDSA operations + * \param eckey EC_KEY object + * \param meth new method + * \return 1 on success and 0 otherwise + */ +int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth); + +/** Returns the maximum length of the DER encoded signature + * \param eckey EC_KEY object + * \return numbers of bytes required for the DER encoded signature + */ +int ECDSA_size(const EC_KEY *eckey); + +/** Precompute parts of the signing operation + * \param eckey EC_KEY object containing a private EC key + * \param ctx BN_CTX object (optional) + * \param kinv BIGNUM pointer for the inverse of k + * \param rp BIGNUM pointer for x coordinate of k * generator + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, BIGNUM **rp); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig memory for the DER encoded created signature + * \param siglen pointer to the length of the returned signature + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, EC_KEY *eckey); + +/** Computes ECDSA signature of a given hash value using the supplied + * private key (note: sig must point to ECDSA_size(eckey) bytes of memory). + * \param type this parameter is ignored + * \param dgst pointer to the hash value to sign + * \param dgstlen length of the hash value + * \param sig buffer to hold the DER encoded signature + * \param siglen pointer to the length of the returned signature + * \param kinv BIGNUM with a pre-computed inverse k (optional) + * \param rp BIGNUM with a pre-computed rp value (optioanl), + * see ECDSA_sign_setup + * \param eckey EC_KEY object containing a private EC key + * \return 1 on success and 0 otherwise + */ +int ECDSA_sign_ex(int type, const unsigned char *dgst, int dgstlen, + unsigned char *sig, unsigned int *siglen, + const BIGNUM *kinv, const BIGNUM *rp, EC_KEY *eckey); + +/** Verifies that the given signature is valid ECDSA signature + * of the supplied hash value using the specified public key. + * \param type this parameter is ignored + * \param dgst pointer to the hash value + * \param dgstlen length of the hash value + * \param sig pointer to the DER encoded signature + * \param siglen length of the DER encoded signature + * \param eckey EC_KEY object containing a public EC key + * \return 1 if the signature is valid, 0 if the signature is invalid + * and -1 on error + */ +int ECDSA_verify(int type, const unsigned char *dgst, int dgstlen, + const unsigned char *sig, int siglen, EC_KEY *eckey); + +/* the standard ex_data functions */ +int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new + *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg); +void *ECDSA_get_ex_data(EC_KEY *d, int idx); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ECDSA_strings(void); + +/* Error codes for the ECDSA functions. */ + +/* Function codes. */ +# define ECDSA_F_ECDSA_CHECK 104 +# define ECDSA_F_ECDSA_DATA_NEW_METHOD 100 +# define ECDSA_F_ECDSA_DO_SIGN 101 +# define ECDSA_F_ECDSA_DO_VERIFY 102 +# define ECDSA_F_ECDSA_SIGN_SETUP 103 + +/* Reason codes. */ +# define ECDSA_R_BAD_SIGNATURE 100 +# define ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 101 +# define ECDSA_R_ERR_EC_LIB 102 +# define ECDSA_R_MISSING_PARAMETERS 103 +# define ECDSA_R_NEED_NEW_SETUP_VALUES 106 +# define ECDSA_R_NON_FIPS_METHOD 107 +# define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104 +# define ECDSA_R_SIGNATURE_MALLOC_FAILED 105 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/ecdsa/ecdsatest.c b/libs/openssl/crypto/ecdsa/ecdsatest.c new file mode 100644 index 00000000..0f301f86 --- /dev/null +++ b/libs/openssl/crypto/ecdsa/ecdsatest.c @@ -0,0 +1,556 @@ +/* crypto/ecdsa/ecdsatest.c */ +/* + * Written by Nils Larsch for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * The elliptic curve binary polynomial software is originally written by + * Sheueling Chang Shantz and Douglas Stebila of Sun Microsystems Laboratories. + * + */ + +#include +#include +#include + +#include /* To see if OPENSSL_NO_ECDSA is defined */ + +#ifdef OPENSSL_NO_ECDSA +int main(int argc, char *argv[]) +{ + puts("Elliptic curves are disabled."); + return 0; +} +#else + +# include +# include +# include +# include +# include +# ifndef OPENSSL_NO_ENGINE +# include +# endif +# include +# include + +static const char rnd_seed[] = "string to make the random number generator " + "think it has entropy"; + +/* declaration of the test functions */ +int x9_62_tests(BIO *); +int x9_62_test_internal(BIO *out, int nid, const char *r, const char *s); +int test_builtin(BIO *); + +/* functions to change the RAND_METHOD */ +int change_rand(void); +int restore_rand(void); +int fbytes(unsigned char *buf, int num); + +RAND_METHOD fake_rand; +const RAND_METHOD *old_rand; + +int change_rand(void) +{ + /* save old rand method */ + if ((old_rand = RAND_get_rand_method()) == NULL) + return 0; + + fake_rand.seed = old_rand->seed; + fake_rand.cleanup = old_rand->cleanup; + fake_rand.add = old_rand->add; + fake_rand.status = old_rand->status; + /* use own random function */ + fake_rand.bytes = fbytes; + fake_rand.pseudorand = old_rand->bytes; + /* set new RAND_METHOD */ + if (!RAND_set_rand_method(&fake_rand)) + return 0; + return 1; +} + +int restore_rand(void) +{ + if (!RAND_set_rand_method(old_rand)) + return 0; + else + return 1; +} + +static int fbytes_counter = 0; +static const char *numbers[8] = { + "651056770906015076056810763456358567190100156695615665659", + "6140507067065001063065065565667405560006161556565665656654", + "8763001015071075675010661307616710783570106710677817767166" + "71676178726717", + "7000000175690566466555057817571571075705015757757057795755" + "55657156756655", + "1275552191113212300012030439187146164646146646466749494799", + "1542725565216523985789236956265265265235675811949404040041", + "1456427555219115346513212300075341203043918714616464614664" + "64667494947990", + "1712787255652165239672857892369562652652652356758119494040" + "40041670216363" +}; + +int fbytes(unsigned char *buf, int num) +{ + int ret; + BIGNUM *tmp = NULL; + + if (fbytes_counter >= 8) + return 0; + tmp = BN_new(); + if (!tmp) + return 0; + if (!BN_dec2bn(&tmp, numbers[fbytes_counter])) { + BN_free(tmp); + return 0; + } + fbytes_counter++; + if (num != BN_num_bytes(tmp) || !BN_bn2bin(tmp, buf)) + ret = 0; + else + ret = 1; + if (tmp) + BN_free(tmp); + return ret; +} + +/* some tests from the X9.62 draft */ +int x9_62_test_internal(BIO *out, int nid, const char *r_in, const char *s_in) +{ + int ret = 0; + const char message[] = "abc"; + unsigned char digest[20]; + unsigned int dgst_len = 0; + EVP_MD_CTX md_ctx; + EC_KEY *key = NULL; + ECDSA_SIG *signature = NULL; + BIGNUM *r = NULL, *s = NULL; + + EVP_MD_CTX_init(&md_ctx); + /* get the message digest */ + EVP_DigestInit(&md_ctx, EVP_ecdsa()); + EVP_DigestUpdate(&md_ctx, (const void *)message, 3); + EVP_DigestFinal(&md_ctx, digest, &dgst_len); + + BIO_printf(out, "testing %s: ", OBJ_nid2sn(nid)); + /* create the key */ + if ((key = EC_KEY_new_by_curve_name(nid)) == NULL) + goto x962_int_err; + if (!EC_KEY_generate_key(key)) + goto x962_int_err; + BIO_printf(out, "."); + (void)BIO_flush(out); + /* create the signature */ + signature = ECDSA_do_sign(digest, 20, key); + if (signature == NULL) + goto x962_int_err; + BIO_printf(out, "."); + (void)BIO_flush(out); + /* compare the created signature with the expected signature */ + if ((r = BN_new()) == NULL || (s = BN_new()) == NULL) + goto x962_int_err; + if (!BN_dec2bn(&r, r_in) || !BN_dec2bn(&s, s_in)) + goto x962_int_err; + if (BN_cmp(signature->r, r) || BN_cmp(signature->s, s)) + goto x962_int_err; + BIO_printf(out, "."); + (void)BIO_flush(out); + /* verify the signature */ + if (ECDSA_do_verify(digest, 20, signature, key) != 1) + goto x962_int_err; + BIO_printf(out, "."); + (void)BIO_flush(out); + + BIO_printf(out, " ok\n"); + ret = 1; + x962_int_err: + if (!ret) + BIO_printf(out, " failed\n"); + if (key) + EC_KEY_free(key); + if (signature) + ECDSA_SIG_free(signature); + if (r) + BN_free(r); + if (s) + BN_free(s); + EVP_MD_CTX_cleanup(&md_ctx); + return ret; +} + +int x9_62_tests(BIO *out) +{ + int ret = 0; + + BIO_printf(out, "some tests from X9.62:\n"); + + /* set own rand method */ + if (!change_rand()) + goto x962_err; + + if (!x9_62_test_internal(out, NID_X9_62_prime192v1, + "3342403536405981729393488334694600415596881826869351677613", + "5735822328888155254683894997897571951568553642892029982342")) + goto x962_err; + if (!x9_62_test_internal(out, NID_X9_62_prime239v1, + "3086361431751678114926225473006680188549593787585317781474" + "62058306432176", + "3238135532097973577080787768312505059318910517550078427819" + "78505179448783")) + goto x962_err; +# ifndef OPENSSL_NO_EC2M + if (!x9_62_test_internal(out, NID_X9_62_c2tnb191v1, + "87194383164871543355722284926904419997237591535066528048", + "308992691965804947361541664549085895292153777025772063598")) + goto x962_err; + if (!x9_62_test_internal(out, NID_X9_62_c2tnb239v1, + "2159633321041961198501834003903461262881815148684178964245" + "5876922391552", + "1970303740007316867383349976549972270528498040721988191026" + "49413465737174")) + goto x962_err; +# endif + ret = 1; + x962_err: + if (!restore_rand()) + ret = 0; + return ret; +} + +int test_builtin(BIO *out) +{ + EC_builtin_curve *curves = NULL; + size_t crv_len = 0, n = 0; + EC_KEY *eckey = NULL, *wrong_eckey = NULL; + EC_GROUP *group; + ECDSA_SIG *ecdsa_sig = NULL; + unsigned char digest[20], wrong_digest[20]; + unsigned char *signature = NULL; + const unsigned char *sig_ptr; + unsigned char *sig_ptr2; + unsigned char *raw_buf = NULL; + unsigned int sig_len, degree, r_len, s_len, bn_len, buf_len; + int nid, ret = 0; + + /* fill digest values with some random data */ + if (RAND_pseudo_bytes(digest, 20) <= 0 || + RAND_pseudo_bytes(wrong_digest, 20) <= 0) { + BIO_printf(out, "ERROR: unable to get random data\n"); + goto builtin_err; + } + + /* + * create and verify a ecdsa signature with every availble curve (with ) + */ + BIO_printf(out, "\ntesting ECDSA_sign() and ECDSA_verify() " + "with some internal curves:\n"); + + /* get a list of all internal curves */ + crv_len = EC_get_builtin_curves(NULL, 0); + + curves = OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len); + + if (curves == NULL) { + BIO_printf(out, "malloc error\n"); + goto builtin_err; + } + + if (!EC_get_builtin_curves(curves, crv_len)) { + BIO_printf(out, "unable to get internal curves\n"); + goto builtin_err; + } + + /* now create and verify a signature for every curve */ + for (n = 0; n < crv_len; n++) { + unsigned char dirt, offset; + + nid = curves[n].nid; + if (nid == NID_ipsec4) + continue; + /* create new ecdsa key (== EC_KEY) */ + if ((eckey = EC_KEY_new()) == NULL) + goto builtin_err; + group = EC_GROUP_new_by_curve_name(nid); + if (group == NULL) + goto builtin_err; + if (EC_KEY_set_group(eckey, group) == 0) + goto builtin_err; + EC_GROUP_free(group); + degree = EC_GROUP_get_degree(EC_KEY_get0_group(eckey)); + if (degree < 160) + /* drop the curve */ + { + EC_KEY_free(eckey); + eckey = NULL; + continue; + } + BIO_printf(out, "%s: ", OBJ_nid2sn(nid)); + /* create key */ + if (!EC_KEY_generate_key(eckey)) { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + /* create second key */ + if ((wrong_eckey = EC_KEY_new()) == NULL) + goto builtin_err; + group = EC_GROUP_new_by_curve_name(nid); + if (group == NULL) + goto builtin_err; + if (EC_KEY_set_group(wrong_eckey, group) == 0) + goto builtin_err; + EC_GROUP_free(group); + if (!EC_KEY_generate_key(wrong_eckey)) { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + + BIO_printf(out, "."); + (void)BIO_flush(out); + /* check key */ + if (!EC_KEY_check_key(eckey)) { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + /* create signature */ + sig_len = ECDSA_size(eckey); + if ((signature = OPENSSL_malloc(sig_len)) == NULL) + goto builtin_err; + if (!ECDSA_sign(0, digest, 20, signature, &sig_len, eckey)) { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + /* verify signature */ + if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + /* verify signature with the wrong key */ + if (ECDSA_verify(0, digest, 20, signature, sig_len, wrong_eckey) == 1) { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + /* wrong digest */ + if (ECDSA_verify(0, wrong_digest, 20, signature, sig_len, eckey) == 1) { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + /* wrong length */ + if (ECDSA_verify(0, digest, 20, signature, sig_len - 1, eckey) == 1) { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + + /* + * Modify a single byte of the signature: to ensure we don't garble + * the ASN1 structure, we read the raw signature and modify a byte in + * one of the bignums directly. + */ + sig_ptr = signature; + if ((ecdsa_sig = d2i_ECDSA_SIG(NULL, &sig_ptr, sig_len)) == NULL) { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + + /* Store the two BIGNUMs in raw_buf. */ + r_len = BN_num_bytes(ecdsa_sig->r); + s_len = BN_num_bytes(ecdsa_sig->s); + bn_len = (degree + 7) / 8; + if ((r_len > bn_len) || (s_len > bn_len)) { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + buf_len = 2 * bn_len; + if ((raw_buf = OPENSSL_malloc(buf_len)) == NULL) + goto builtin_err; + /* Pad the bignums with leading zeroes. */ + memset(raw_buf, 0, buf_len); + BN_bn2bin(ecdsa_sig->r, raw_buf + bn_len - r_len); + BN_bn2bin(ecdsa_sig->s, raw_buf + buf_len - s_len); + + /* Modify a single byte in the buffer. */ + offset = raw_buf[10] % buf_len; + dirt = raw_buf[11] ? raw_buf[11] : 1; + raw_buf[offset] ^= dirt; + /* Now read the BIGNUMs back in from raw_buf. */ + if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || + (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) + goto builtin_err; + + sig_ptr2 = signature; + sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); + if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) == 1) { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + /* + * Sanity check: undo the modification and verify signature. + */ + raw_buf[offset] ^= dirt; + if ((BN_bin2bn(raw_buf, bn_len, ecdsa_sig->r) == NULL) || + (BN_bin2bn(raw_buf + bn_len, bn_len, ecdsa_sig->s) == NULL)) + goto builtin_err; + + sig_ptr2 = signature; + sig_len = i2d_ECDSA_SIG(ecdsa_sig, &sig_ptr2); + if (ECDSA_verify(0, digest, 20, signature, sig_len, eckey) != 1) { + BIO_printf(out, " failed\n"); + goto builtin_err; + } + BIO_printf(out, "."); + (void)BIO_flush(out); + + BIO_printf(out, " ok\n"); + /* cleanup */ + /* clean bogus errors */ + ERR_clear_error(); + OPENSSL_free(signature); + signature = NULL; + EC_KEY_free(eckey); + eckey = NULL; + EC_KEY_free(wrong_eckey); + wrong_eckey = NULL; + ECDSA_SIG_free(ecdsa_sig); + ecdsa_sig = NULL; + OPENSSL_free(raw_buf); + raw_buf = NULL; + } + + ret = 1; + builtin_err: + if (eckey) + EC_KEY_free(eckey); + if (wrong_eckey) + EC_KEY_free(wrong_eckey); + if (ecdsa_sig) + ECDSA_SIG_free(ecdsa_sig); + if (signature) + OPENSSL_free(signature); + if (raw_buf) + OPENSSL_free(raw_buf); + if (curves) + OPENSSL_free(curves); + + return ret; +} + +int main(void) +{ + int ret = 1; + BIO *out; + + out = BIO_new_fp(stdout, BIO_NOCLOSE); + + /* enable memory leak checking unless explicitly disabled */ + if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) && + (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) { + CRYPTO_malloc_debug_init(); + CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); + } else { + /* OPENSSL_DEBUG_MEMORY=off */ + CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); + } + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + + ERR_load_crypto_strings(); + + /* initialize the prng */ + RAND_seed(rnd_seed, sizeof(rnd_seed)); + + /* the tests */ + if (!x9_62_tests(out)) + goto err; + if (!test_builtin(out)) + goto err; + + ret = 0; + err: + if (ret) + BIO_printf(out, "\nECDSA test failed\n"); + else + BIO_printf(out, "\nECDSA test passed\n"); + if (ret) + ERR_print_errors(out); + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + ERR_free_strings(); + CRYPTO_mem_leaks(out); + if (out != NULL) + BIO_free(out); + return ret; +} +#endif diff --git a/libs/openssl/crypto/ecdsa/ecs_asn1.c b/libs/openssl/crypto/ecdsa/ecs_asn1.c new file mode 100644 index 00000000..508b079f --- /dev/null +++ b/libs/openssl/crypto/ecdsa/ecs_asn1.c @@ -0,0 +1,67 @@ +/* crypto/ecdsa/ecs_asn1.c */ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ecs_locl.h" +#include +#include + +ASN1_SEQUENCE(ECDSA_SIG) = { + ASN1_SIMPLE(ECDSA_SIG, r, CBIGNUM), + ASN1_SIMPLE(ECDSA_SIG, s, CBIGNUM) +} ASN1_SEQUENCE_END(ECDSA_SIG) + +DECLARE_ASN1_FUNCTIONS_const(ECDSA_SIG) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(ECDSA_SIG, ECDSA_SIG) +IMPLEMENT_ASN1_FUNCTIONS_const(ECDSA_SIG) diff --git a/libs/openssl/crypto/ecdsa/ecs_err.c b/libs/openssl/crypto/ecdsa/ecs_err.c new file mode 100644 index 00000000..6fc64a00 --- /dev/null +++ b/libs/openssl/crypto/ecdsa/ecs_err.c @@ -0,0 +1,106 @@ +/* crypto/ecdsa/ecs_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ECDSA,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ECDSA,0,reason) + +static ERR_STRING_DATA ECDSA_str_functs[] = { + {ERR_FUNC(ECDSA_F_ECDSA_CHECK), "ECDSA_CHECK"}, + {ERR_FUNC(ECDSA_F_ECDSA_DATA_NEW_METHOD), "ECDSA_DATA_NEW_METHOD"}, + {ERR_FUNC(ECDSA_F_ECDSA_DO_SIGN), "ECDSA_do_sign"}, + {ERR_FUNC(ECDSA_F_ECDSA_DO_VERIFY), "ECDSA_do_verify"}, + {ERR_FUNC(ECDSA_F_ECDSA_SIGN_SETUP), "ECDSA_sign_setup"}, + {0, NULL} +}; + +static ERR_STRING_DATA ECDSA_str_reasons[] = { + {ERR_REASON(ECDSA_R_BAD_SIGNATURE), "bad signature"}, + {ERR_REASON(ECDSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), + "data too large for key size"}, + {ERR_REASON(ECDSA_R_ERR_EC_LIB), "err ec lib"}, + {ERR_REASON(ECDSA_R_MISSING_PARAMETERS), "missing parameters"}, + {ERR_REASON(ECDSA_R_NEED_NEW_SETUP_VALUES), "need new setup values"}, + {ERR_REASON(ECDSA_R_NON_FIPS_METHOD), "non fips method"}, + {ERR_REASON(ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED), + "random number generation failed"}, + {ERR_REASON(ECDSA_R_SIGNATURE_MALLOC_FAILED), "signature malloc failed"}, + {0, NULL} +}; + +#endif + +void ERR_load_ECDSA_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(ECDSA_str_functs[0].error) == NULL) { + ERR_load_strings(0, ECDSA_str_functs); + ERR_load_strings(0, ECDSA_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/ecdsa/ecs_lib.c b/libs/openssl/crypto/ecdsa/ecs_lib.c new file mode 100644 index 00000000..0f2d3432 --- /dev/null +++ b/libs/openssl/crypto/ecdsa/ecs_lib.c @@ -0,0 +1,277 @@ +/* crypto/ecdsa/ecs_lib.c */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "ecs_locl.h" +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include +#include +#ifdef OPENSSL_FIPS +# include +#endif + +const char ECDSA_version[] = "ECDSA" OPENSSL_VERSION_PTEXT; + +static const ECDSA_METHOD *default_ECDSA_method = NULL; + +static void *ecdsa_data_new(void); +static void *ecdsa_data_dup(void *); +static void ecdsa_data_free(void *); + +void ECDSA_set_default_method(const ECDSA_METHOD *meth) +{ + default_ECDSA_method = meth; +} + +const ECDSA_METHOD *ECDSA_get_default_method(void) +{ + if (!default_ECDSA_method) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_ecdsa_openssl(); + else + return ECDSA_OpenSSL(); +#else + default_ECDSA_method = ECDSA_OpenSSL(); +#endif + } + return default_ECDSA_method; +} + +int ECDSA_set_method(EC_KEY *eckey, const ECDSA_METHOD *meth) +{ + ECDSA_DATA *ecdsa; + + ecdsa = ecdsa_check(eckey); + + if (ecdsa == NULL) + return 0; + +#ifndef OPENSSL_NO_ENGINE + if (ecdsa->engine) { + ENGINE_finish(ecdsa->engine); + ecdsa->engine = NULL; + } +#endif + ecdsa->meth = meth; + + return 1; +} + +static ECDSA_DATA *ECDSA_DATA_new_method(ENGINE *engine) +{ + ECDSA_DATA *ret; + + ret = (ECDSA_DATA *)OPENSSL_malloc(sizeof(ECDSA_DATA)); + if (ret == NULL) { + ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + ret->init = NULL; + + ret->meth = ECDSA_get_default_method(); + ret->engine = engine; +#ifndef OPENSSL_NO_ENGINE + if (!ret->engine) + ret->engine = ENGINE_get_default_ECDSA(); + if (ret->engine) { + ret->meth = ENGINE_get_ECDSA(ret->engine); + if (!ret->meth) { + ECDSAerr(ECDSA_F_ECDSA_DATA_NEW_METHOD, ERR_R_ENGINE_LIB); + ENGINE_finish(ret->engine); + OPENSSL_free(ret); + return NULL; + } + } +#endif + + ret->flags = ret->meth->flags; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data); +#if 0 + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, ret, &ret->ex_data); + OPENSSL_free(ret); + ret = NULL; + } +#endif + return (ret); +} + +static void *ecdsa_data_new(void) +{ + return (void *)ECDSA_DATA_new_method(NULL); +} + +static void *ecdsa_data_dup(void *data) +{ + ECDSA_DATA *r = (ECDSA_DATA *)data; + + /* XXX: dummy operation */ + if (r == NULL) + return NULL; + + return ecdsa_data_new(); +} + +static void ecdsa_data_free(void *data) +{ + ECDSA_DATA *r = (ECDSA_DATA *)data; + +#ifndef OPENSSL_NO_ENGINE + if (r->engine) + ENGINE_finish(r->engine); +#endif + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ECDSA, r, &r->ex_data); + + OPENSSL_cleanse((void *)r, sizeof(ECDSA_DATA)); + + OPENSSL_free(r); +} + +ECDSA_DATA *ecdsa_check(EC_KEY *key) +{ + ECDSA_DATA *ecdsa_data; + + void *data = EC_KEY_get_key_method_data(key, ecdsa_data_dup, + ecdsa_data_free, ecdsa_data_free); + if (data == NULL) { + ecdsa_data = (ECDSA_DATA *)ecdsa_data_new(); + if (ecdsa_data == NULL) + return NULL; + data = EC_KEY_insert_key_method_data(key, (void *)ecdsa_data, + ecdsa_data_dup, ecdsa_data_free, + ecdsa_data_free); + if (data != NULL) { + /* + * Another thread raced us to install the key_method data and + * won. + */ + ecdsa_data_free(ecdsa_data); + ecdsa_data = (ECDSA_DATA *)data; + } + } else + ecdsa_data = (ECDSA_DATA *)data; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(ecdsa_data->flags & ECDSA_FLAG_FIPS_METHOD) + && !(EC_KEY_get_flags(key) & EC_FLAG_NON_FIPS_ALLOW)) { + ECDSAerr(ECDSA_F_ECDSA_CHECK, ECDSA_R_NON_FIPS_METHOD); + return NULL; + } +#endif + + return ecdsa_data; +} + +int ECDSA_size(const EC_KEY *r) +{ + int ret, i; + ASN1_INTEGER bs; + BIGNUM *order = NULL; + unsigned char buf[4]; + const EC_GROUP *group; + + if (r == NULL) + return 0; + group = EC_KEY_get0_group(r); + if (group == NULL) + return 0; + + if ((order = BN_new()) == NULL) + return 0; + if (!EC_GROUP_get_order(group, order, NULL)) { + BN_clear_free(order); + return 0; + } + i = BN_num_bits(order); + bs.length = (i + 7) / 8; + bs.data = buf; + bs.type = V_ASN1_INTEGER; + /* If the top bit is set the asn1 encoding is 1 larger. */ + buf[0] = 0xff; + + i = i2d_ASN1_INTEGER(&bs, NULL); + i += i; /* r and s */ + ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); + BN_clear_free(order); + return (ret); +} + +int ECDSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ECDSA, argl, argp, + new_func, dup_func, free_func); +} + +int ECDSA_set_ex_data(EC_KEY *d, int idx, void *arg) +{ + ECDSA_DATA *ecdsa; + ecdsa = ecdsa_check(d); + if (ecdsa == NULL) + return 0; + return (CRYPTO_set_ex_data(&ecdsa->ex_data, idx, arg)); +} + +void *ECDSA_get_ex_data(EC_KEY *d, int idx) +{ + ECDSA_DATA *ecdsa; + ecdsa = ecdsa_check(d); + if (ecdsa == NULL) + return NULL; + return (CRYPTO_get_ex_data(&ecdsa->ex_data, idx)); +} diff --git a/libs/openssl/crypto/ecdsa/ecs_locl.h b/libs/openssl/crypto/ecdsa/ecs_locl.h new file mode 100644 index 00000000..76b2caf1 --- /dev/null +++ b/libs/openssl/crypto/ecdsa/ecs_locl.h @@ -0,0 +1,116 @@ +/* crypto/ecdsa/ecs_locl.h */ +/* + * Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_ECS_LOCL_H +# define HEADER_ECS_LOCL_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +struct ecdsa_method { + const char *name; + ECDSA_SIG *(*ecdsa_do_sign) (const unsigned char *dgst, int dgst_len, + const BIGNUM *inv, const BIGNUM *rp, + EC_KEY *eckey); + int (*ecdsa_sign_setup) (EC_KEY *eckey, BN_CTX *ctx, BIGNUM **kinv, + BIGNUM **r); + int (*ecdsa_do_verify) (const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); +# if 0 + int (*init) (EC_KEY *eckey); + int (*finish) (EC_KEY *eckey); +# endif + int flags; + char *app_data; +}; + +/* + * If this flag is set the ECDSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define ECDSA_FLAG_FIPS_METHOD 0x1 + +typedef struct ecdsa_data_st { + /* EC_KEY_METH_DATA part */ + int (*init) (EC_KEY *); + /* method (ECDSA) specific part */ + ENGINE *engine; + int flags; + const ECDSA_METHOD *meth; + CRYPTO_EX_DATA ex_data; +} ECDSA_DATA; + +/** ecdsa_check + * checks whether ECKEY->meth_data is a pointer to a ECDSA_DATA structure + * and if not it removes the old meth_data and creates a ECDSA_DATA structure. + * \param eckey pointer to a EC_KEY object + * \return pointer to a ECDSA_DATA structure + */ +ECDSA_DATA *ecdsa_check(EC_KEY *eckey); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_ECS_LOCL_H */ diff --git a/libs/openssl/crypto/ecdsa/ecs_ossl.c b/libs/openssl/crypto/ecdsa/ecs_ossl.c new file mode 100644 index 00000000..4c5fa6b9 --- /dev/null +++ b/libs/openssl/crypto/ecdsa/ecs_ossl.c @@ -0,0 +1,442 @@ +/* crypto/ecdsa/ecs_ossl.c */ +/* + * Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 1998-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ecs_locl.h" +#include +#include +#include + +static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dlen, + const BIGNUM *, const BIGNUM *, + EC_KEY *eckey); +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp); +static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey); + +static ECDSA_METHOD openssl_ecdsa_meth = { + "OpenSSL ECDSA method", + ecdsa_do_sign, + ecdsa_sign_setup, + ecdsa_do_verify, +#if 0 + NULL, /* init */ + NULL, /* finish */ +#endif + 0, /* flags */ + NULL /* app_data */ +}; + +const ECDSA_METHOD *ECDSA_OpenSSL(void) +{ + return &openssl_ecdsa_meth; +} + +static int ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp) +{ + BN_CTX *ctx = NULL; + BIGNUM *k = NULL, *r = NULL, *order = NULL, *X = NULL; + EC_POINT *tmp_point = NULL; + const EC_GROUP *group; + int ret = 0; + + if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (ctx_in == NULL) { + if ((ctx = BN_CTX_new()) == NULL) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); + return 0; + } + } else + ctx = ctx_in; + + k = BN_new(); /* this value is later returned in *kinvp */ + r = BN_new(); /* this value is later returned in *rp */ + order = BN_new(); + X = BN_new(); + if (!k || !r || !order || !X) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_MALLOC_FAILURE); + goto err; + } + if ((tmp_point = EC_POINT_new(group)) == NULL) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + if (!EC_GROUP_get_order(group, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + + do { + /* get random k */ + do + if (!BN_rand_range(k, order)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, + ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED); + goto err; + } + while (BN_is_zero(k)) ; + + /* + * We do not want timing information to leak the length of k, so we + * compute G*k using an equivalent scalar of fixed bit-length. + */ + + if (!BN_add(k, k, order)) + goto err; + if (BN_num_bits(k) <= BN_num_bits(order)) + if (!BN_add(k, k, order)) + goto err; + + /* compute r the x-coordinate of generator * k */ + if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == + NID_X9_62_prime_field) { + if (!EC_POINT_get_affine_coordinates_GFp + (group, tmp_point, X, NULL, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + } +#ifndef OPENSSL_NO_EC2M + else { /* NID_X9_62_characteristic_two_field */ + + if (!EC_POINT_get_affine_coordinates_GF2m(group, + tmp_point, X, NULL, + ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_EC_LIB); + goto err; + } + } +#endif + if (!BN_nnmod(r, X, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + } + while (BN_is_zero(r)); + + /* compute the inverse of k */ + if (!BN_mod_inverse(k, k, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_SIGN_SETUP, ERR_R_BN_LIB); + goto err; + } + /* clear old values if necessary */ + if (*rp != NULL) + BN_clear_free(*rp); + if (*kinvp != NULL) + BN_clear_free(*kinvp); + /* save the pre-computed values */ + *rp = r; + *kinvp = k; + ret = 1; + err: + if (!ret) { + if (k != NULL) + BN_clear_free(k); + if (r != NULL) + BN_clear_free(r); + } + if (ctx_in == NULL) + BN_CTX_free(ctx); + if (order != NULL) + BN_free(order); + if (tmp_point != NULL) + EC_POINT_free(tmp_point); + if (X) + BN_clear_free(X); + return (ret); +} + +static ECDSA_SIG *ecdsa_do_sign(const unsigned char *dgst, int dgst_len, + const BIGNUM *in_kinv, const BIGNUM *in_r, + EC_KEY *eckey) +{ + int ok = 0, i; + BIGNUM *kinv = NULL, *s, *m = NULL, *tmp = NULL, *order = NULL; + const BIGNUM *ckinv; + BN_CTX *ctx = NULL; + const EC_GROUP *group; + ECDSA_SIG *ret; + ECDSA_DATA *ecdsa; + const BIGNUM *priv_key; + + ecdsa = ecdsa_check(eckey); + group = EC_KEY_get0_group(eckey); + priv_key = EC_KEY_get0_private_key(eckey); + + if (group == NULL || priv_key == NULL || ecdsa == NULL) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + ret = ECDSA_SIG_new(); + if (!ret) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); + return NULL; + } + s = ret->s; + + if ((ctx = BN_CTX_new()) == NULL || (order = BN_new()) == NULL || + (tmp = BN_new()) == NULL || (m = BN_new()) == NULL) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_GROUP_get_order(group, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_EC_LIB); + goto err; + } + i = BN_num_bits(order); + /* + * Need to truncate digest if it is too long: first truncate whole bytes. + */ + if (8 * dgst_len > i) + dgst_len = (i + 7) / 8; + if (!BN_bin2bn(dgst, dgst_len, m)) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + /* If still too long truncate remaining bits with a shift */ + if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + do { + if (in_kinv == NULL || in_r == NULL) { + if (!ECDSA_sign_setup(eckey, ctx, &kinv, &ret->r)) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_ECDSA_LIB); + goto err; + } + ckinv = kinv; + } else { + ckinv = in_kinv; + if (BN_copy(ret->r, in_r) == NULL) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (!BN_mod_mul(tmp, priv_key, ret->r, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + if (!BN_mod_add_quick(s, tmp, m, order)) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + if (!BN_mod_mul(s, s, ckinv, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, ERR_R_BN_LIB); + goto err; + } + if (BN_is_zero(s)) { + /* + * if kinv and r have been supplied by the caller don't to + * generate new kinv and r values + */ + if (in_kinv != NULL && in_r != NULL) { + ECDSAerr(ECDSA_F_ECDSA_DO_SIGN, + ECDSA_R_NEED_NEW_SETUP_VALUES); + goto err; + } + } else + /* s != 0 => we have a valid signature */ + break; + } + while (1); + + ok = 1; + err: + if (!ok) { + ECDSA_SIG_free(ret); + ret = NULL; + } + if (ctx) + BN_CTX_free(ctx); + if (m) + BN_clear_free(m); + if (tmp) + BN_clear_free(tmp); + if (order) + BN_free(order); + if (kinv) + BN_clear_free(kinv); + return ret; +} + +static int ecdsa_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey) +{ + int ret = -1, i; + BN_CTX *ctx; + BIGNUM *order, *u1, *u2, *m, *X; + EC_POINT *point = NULL; + const EC_GROUP *group; + const EC_POINT *pub_key; + + /* check input values */ + if (eckey == NULL || (group = EC_KEY_get0_group(eckey)) == NULL || + (pub_key = EC_KEY_get0_public_key(eckey)) == NULL || sig == NULL) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_MISSING_PARAMETERS); + return -1; + } + + ctx = BN_CTX_new(); + if (!ctx) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); + return -1; + } + BN_CTX_start(ctx); + order = BN_CTX_get(ctx); + u1 = BN_CTX_get(ctx); + u2 = BN_CTX_get(ctx); + m = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + if (!X) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + + if (!EC_GROUP_get_order(group, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + + if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || + BN_ucmp(sig->r, order) >= 0 || BN_is_zero(sig->s) || + BN_is_negative(sig->s) || BN_ucmp(sig->s, order) >= 0) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ECDSA_R_BAD_SIGNATURE); + ret = 0; /* signature is invalid */ + goto err; + } + /* calculate tmp1 = inv(S) mod order */ + if (!BN_mod_inverse(u2, sig->s, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + /* digest -> m */ + i = BN_num_bits(order); + /* + * Need to truncate digest if it is too long: first truncate whole bytes. + */ + if (8 * dgst_len > i) + dgst_len = (i + 7) / 8; + if (!BN_bin2bn(dgst, dgst_len, m)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + /* If still too long truncate remaining bits with a shift */ + if ((8 * dgst_len > i) && !BN_rshift(m, m, 8 - (i & 0x7))) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + /* u1 = m * tmp mod order */ + if (!BN_mod_mul(u1, m, u2, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + /* u2 = r * w mod q */ + if (!BN_mod_mul(u2, sig->r, u2, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + + if ((point = EC_POINT_new(group)) == NULL) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_POINT_mul(group, point, u1, pub_key, u2, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) == + NID_X9_62_prime_field) { + if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + } +#ifndef OPENSSL_NO_EC2M + else { /* NID_X9_62_characteristic_two_field */ + + if (!EC_POINT_get_affine_coordinates_GF2m(group, point, X, NULL, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_EC_LIB); + goto err; + } + } +#endif + if (!BN_nnmod(u1, X, order, ctx)) { + ECDSAerr(ECDSA_F_ECDSA_DO_VERIFY, ERR_R_BN_LIB); + goto err; + } + /* if the signature is correct u1 is equal to sig->r */ + ret = (BN_ucmp(u1, sig->r) == 0); + err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + if (point) + EC_POINT_free(point); + return ret; +} diff --git a/libs/openssl/crypto/ecdsa/ecs_sign.c b/libs/openssl/crypto/ecdsa/ecs_sign.c new file mode 100644 index 00000000..28652d45 --- /dev/null +++ b/libs/openssl/crypto/ecdsa/ecs_sign.c @@ -0,0 +1,106 @@ +/* crypto/ecdsa/ecdsa_sign.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ecs_locl.h" +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include + +ECDSA_SIG *ECDSA_do_sign(const unsigned char *dgst, int dlen, EC_KEY *eckey) +{ + return ECDSA_do_sign_ex(dgst, dlen, NULL, NULL, eckey); +} + +ECDSA_SIG *ECDSA_do_sign_ex(const unsigned char *dgst, int dlen, + const BIGNUM *kinv, const BIGNUM *rp, + EC_KEY *eckey) +{ + ECDSA_DATA *ecdsa = ecdsa_check(eckey); + if (ecdsa == NULL) + return NULL; + return ecdsa->meth->ecdsa_do_sign(dgst, dlen, kinv, rp, eckey); +} + +int ECDSA_sign(int type, const unsigned char *dgst, int dlen, unsigned char + *sig, unsigned int *siglen, EC_KEY *eckey) +{ + return ECDSA_sign_ex(type, dgst, dlen, sig, siglen, NULL, NULL, eckey); +} + +int ECDSA_sign_ex(int type, const unsigned char *dgst, int dlen, unsigned char + *sig, unsigned int *siglen, const BIGNUM *kinv, + const BIGNUM *r, EC_KEY *eckey) +{ + ECDSA_SIG *s; + RAND_seed(dgst, dlen); + s = ECDSA_do_sign_ex(dgst, dlen, kinv, r, eckey); + if (s == NULL) { + *siglen = 0; + return 0; + } + *siglen = i2d_ECDSA_SIG(s, &sig); + ECDSA_SIG_free(s); + return 1; +} + +int ECDSA_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp, + BIGNUM **rp) +{ + ECDSA_DATA *ecdsa = ecdsa_check(eckey); + if (ecdsa == NULL) + return 0; + return ecdsa->meth->ecdsa_sign_setup(eckey, ctx_in, kinvp, rp); +} diff --git a/libs/openssl/crypto/ecdsa/ecs_vrf.c b/libs/openssl/crypto/ecdsa/ecs_vrf.c new file mode 100644 index 00000000..e909aeb4 --- /dev/null +++ b/libs/openssl/crypto/ecdsa/ecs_vrf.c @@ -0,0 +1,112 @@ +/* crypto/ecdsa/ecdsa_vrf.c */ +/* + * Written by Nils Larsch for the OpenSSL project + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ecs_locl.h" +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif + +/*- + * returns + * 1: correct signature + * 0: incorrect signature + * -1: error + */ +int ECDSA_do_verify(const unsigned char *dgst, int dgst_len, + const ECDSA_SIG *sig, EC_KEY *eckey) +{ + ECDSA_DATA *ecdsa = ecdsa_check(eckey); + if (ecdsa == NULL) + return 0; + return ecdsa->meth->ecdsa_do_verify(dgst, dgst_len, sig, eckey); +} + +/*- + * returns + * 1: correct signature + * 0: incorrect signature + * -1: error + */ +int ECDSA_verify(int type, const unsigned char *dgst, int dgst_len, + const unsigned char *sigbuf, int sig_len, EC_KEY *eckey) +{ + ECDSA_SIG *s; + const unsigned char *p = sigbuf; + unsigned char *der = NULL; + int derlen = -1; + int ret = -1; + + s = ECDSA_SIG_new(); + if (s == NULL) + return (ret); + if (d2i_ECDSA_SIG(&s, &p, sig_len) == NULL) + goto err; + /* Ensure signature uses DER and doesn't have trailing garbage */ + derlen = i2d_ECDSA_SIG(s, &der); + if (derlen != sig_len || memcmp(sigbuf, der, derlen)) + goto err; + ret = ECDSA_do_verify(dgst, dgst_len, s, eckey); + err: + if (derlen > 0) { + OPENSSL_cleanse(der, derlen); + OPENSSL_free(der); + } + ECDSA_SIG_free(s); + return (ret); +} diff --git a/libs/openssl/crypto/engine/README b/libs/openssl/crypto/engine/README new file mode 100644 index 00000000..6b69b70f --- /dev/null +++ b/libs/openssl/crypto/engine/README @@ -0,0 +1,211 @@ +Notes: 2001-09-24 +----------------- + +This "description" (if one chooses to call it that) needed some major updating +so here goes. This update addresses a change being made at the same time to +OpenSSL, and it pretty much completely restructures the underlying mechanics of +the "ENGINE" code. So it serves a double purpose of being a "ENGINE internals +for masochists" document *and* a rather extensive commit log message. (I'd get +lynched for sticking all this in CHANGES or the commit mails :-). + +ENGINE_TABLE underlies this restructuring, as described in the internal header +"eng_int.h", implemented in eng_table.c, and used in each of the "class" files; +tb_rsa.c, tb_dsa.c, etc. + +However, "EVP_CIPHER" underlies the motivation and design of ENGINE_TABLE so +I'll mention a bit about that first. EVP_CIPHER (and most of this applies +equally to EVP_MD for digests) is both a "method" and a algorithm/mode +identifier that, in the current API, "lingers". These cipher description + +implementation structures can be defined or obtained directly by applications, +or can be loaded "en masse" into EVP storage so that they can be catalogued and +searched in various ways, ie. two ways of encrypting with the "des_cbc" +algorithm/mode pair are; + +(i) directly; + const EVP_CIPHER *cipher = EVP_des_cbc(); + EVP_EncryptInit(&ctx, cipher, key, iv); + [ ... use EVP_EncryptUpdate() and EVP_EncryptFinal() ...] + +(ii) indirectly; + OpenSSL_add_all_ciphers(); + cipher = EVP_get_cipherbyname("des_cbc"); + EVP_EncryptInit(&ctx, cipher, key, iv); + [ ... etc ... ] + +The latter is more generally used because it also allows ciphers/digests to be +looked up based on other identifiers which can be useful for automatic cipher +selection, eg. in SSL/TLS, or by user-controllable configuration. + +The important point about this is that EVP_CIPHER definitions and structures are +passed around with impunity and there is no safe way, without requiring massive +rewrites of many applications, to assume that EVP_CIPHERs can be reference +counted. One an EVP_CIPHER is exposed to the caller, neither it nor anything it +comes from can "safely" be destroyed. Unless of course the way of getting to +such ciphers is via entirely distinct API calls that didn't exist before. +However existing API usage cannot be made to understand when an EVP_CIPHER +pointer, that has been passed to the caller, is no longer being used. + +The other problem with the existing API w.r.t. to hooking EVP_CIPHER support +into ENGINE is storage - the OBJ_NAME-based storage used by EVP to register +ciphers simultaneously registers cipher *types* and cipher *implementations* - +they are effectively the same thing, an "EVP_CIPHER" pointer. The problem with +hooking in ENGINEs is that multiple ENGINEs may implement the same ciphers. The +solution is necessarily that ENGINE-provided ciphers simply are not registered, +stored, or exposed to the caller in the same manner as existing ciphers. This is +especially necessary considering the fact ENGINE uses reference counts to allow +for cleanup, modularity, and DSO support - yet EVP_CIPHERs, as exposed to +callers in the current API, support no such controls. + +Another sticking point for integrating cipher support into ENGINE is linkage. +Already there is a problem with the way ENGINE supports RSA, DSA, etc whereby +they are available *because* they're part of a giant ENGINE called "openssl". +Ie. all implementations *have* to come from an ENGINE, but we get round that by +having a giant ENGINE with all the software support encapsulated. This creates +linker hassles if nothing else - linking a 1-line application that calls 2 basic +RSA functions (eg. "RSA_free(RSA_new());") will result in large quantities of +ENGINE code being linked in *and* because of that DSA, DH, and RAND also. If we +continue with this approach for EVP_CIPHER support (even if it *was* possible) +we would lose our ability to link selectively by selectively loading certain +implementations of certain functionality. Touching any part of any kind of +crypto would result in massive static linkage of everything else. So the +solution is to change the way ENGINE feeds existing "classes", ie. how the +hooking to ENGINE works from RSA, DSA, DH, RAND, as well as adding new hooking +for EVP_CIPHER, and EVP_MD. + +The way this is now being done is by mostly reverting back to how things used to +work prior to ENGINE :-). Ie. RSA now has a "RSA_METHOD" pointer again - this +was previously replaced by an "ENGINE" pointer and all RSA code that required +the RSA_METHOD would call ENGINE_get_RSA() each time on its ENGINE handle to +temporarily get and use the ENGINE's RSA implementation. Apart from being more +efficient, switching back to each RSA having an RSA_METHOD pointer also allows +us to conceivably operate with *no* ENGINE. As we'll see, this removes any need +for a fallback ENGINE that encapsulates default implementations - we can simply +have our RSA structure pointing its RSA_METHOD pointer to the software +implementation and have its ENGINE pointer set to NULL. + +A look at the EVP_CIPHER hooking is most explanatory, the RSA, DSA (etc) cases +turn out to be degenerate forms of the same thing. The EVP storage of ciphers, +and the existing EVP API functions that return "software" implementations and +descriptions remain untouched. However, the storage takes more meaning in terms +of "cipher description" and less meaning in terms of "implementation". When an +EVP_CIPHER_CTX is actually initialised with an EVP_CIPHER method and is about to +begin en/decryption, the hooking to ENGINE comes into play. What happens is that +cipher-specific ENGINE code is asked for an ENGINE pointer (a functional +reference) for any ENGINE that is registered to perform the algo/mode that the +provided EVP_CIPHER structure represents. Under normal circumstances, that +ENGINE code will return NULL because no ENGINEs will have had any cipher +implementations *registered*. As such, a NULL ENGINE pointer is stored in the +EVP_CIPHER_CTX context, and the EVP_CIPHER structure is left hooked into the +context and so is used as the implementation. Pretty much how things work now +except we'd have a redundant ENGINE pointer set to NULL and doing nothing. + +Conversely, if an ENGINE *has* been registered to perform the algorithm/mode +combination represented by the provided EVP_CIPHER, then a functional reference +to that ENGINE will be returned to the EVP_CIPHER_CTX during initialisation. +That functional reference will be stored in the context (and released on +cleanup) - and having that reference provides a *safe* way to use an EVP_CIPHER +definition that is private to the ENGINE. Ie. the EVP_CIPHER provided by the +application will actually be replaced by an EVP_CIPHER from the registered +ENGINE - it will support the same algorithm/mode as the original but will be a +completely different implementation. Because this EVP_CIPHER isn't stored in the +EVP storage, nor is it returned to applications from traditional API functions, +there is no associated problem with it not having reference counts. And of +course, when one of these "private" cipher implementations is hooked into +EVP_CIPHER_CTX, it is done whilst the EVP_CIPHER_CTX holds a functional +reference to the ENGINE that owns it, thus the use of the ENGINE's EVP_CIPHER is +safe. + +The "cipher-specific ENGINE code" I mentioned is implemented in tb_cipher.c but +in essence it is simply an instantiation of "ENGINE_TABLE" code for use by +EVP_CIPHER code. tb_digest.c is virtually identical but, of course, it is for +use by EVP_MD code. Ditto for tb_rsa.c, tb_dsa.c, etc. These instantiations of +ENGINE_TABLE essentially provide linker-separation of the classes so that even +if ENGINEs implement *all* possible algorithms, an application using only +EVP_CIPHER code will link at most code relating to EVP_CIPHER, tb_cipher.c, core +ENGINE code that is independant of class, and of course the ENGINE +implementation that the application loaded. It will *not* however link any +class-specific ENGINE code for digests, RSA, etc nor will it bleed over into +other APIs, such as the RSA/DSA/etc library code. + +ENGINE_TABLE is a little more complicated than may seem necessary but this is +mostly to avoid a lot of "init()"-thrashing on ENGINEs (that may have to load +DSOs, and other expensive setup that shouldn't be thrashed unnecessarily) *and* +to duplicate "default" behaviour. Basically an ENGINE_TABLE instantiation, for +example tb_cipher.c, implements a hash-table keyed by integer "nid" values. +These nids provide the uniquenness of an algorithm/mode - and each nid will hash +to a potentially NULL "ENGINE_PILE". An ENGINE_PILE is essentially a list of +pointers to ENGINEs that implement that particular 'nid'. Each "pile" uses some +caching tricks such that requests on that 'nid' will be cached and all future +requests will return immediately (well, at least with minimal operation) unless +a change is made to the pile, eg. perhaps an ENGINE was unloaded. The reason is +that an application could have support for 10 ENGINEs statically linked +in, and the machine in question may not have any of the hardware those 10 +ENGINEs support. If each of those ENGINEs has a "des_cbc" implementation, we +want to avoid every EVP_CIPHER_CTX setup from trying (and failing) to initialise +each of those 10 ENGINEs. Instead, the first such request will try to do that +and will either return (and cache) a NULL ENGINE pointer or will return a +functional reference to the first that successfully initialised. In the latter +case it will also cache an extra functional reference to the ENGINE as a +"default" for that 'nid'. The caching is acknowledged by a 'uptodate' variable +that is unset only if un/registration takes place on that pile. Ie. if +implementations of "des_cbc" are added or removed. This behaviour can be +tweaked; the ENGINE_TABLE_FLAG_NOINIT value can be passed to +ENGINE_set_table_flags(), in which case the only ENGINEs that tb_cipher.c will +try to initialise from the "pile" will be those that are already initialised +(ie. it's simply an increment of the functional reference count, and no real +"initialisation" will take place). + +RSA, DSA, DH, and RAND all have their own ENGINE_TABLE code as well, and the +difference is that they all use an implicit 'nid' of 1. Whereas EVP_CIPHERs are +actually qualitatively different depending on 'nid' (the "des_cbc" EVP_CIPHER is +not an interoperable implementation of "aes_256_cbc"), RSA_METHODs are +necessarily interoperable and don't have different flavours, only different +implementations. In other words, the ENGINE_TABLE for RSA will either be empty, +or will have a single ENGING_PILE hashed to by the 'nid' 1 and that pile +represents ENGINEs that implement the single "type" of RSA there is. + +Cleanup - the registration and unregistration may pose questions about how +cleanup works with the ENGINE_PILE doing all this caching nonsense (ie. when the +application or EVP_CIPHER code releases its last reference to an ENGINE, the +ENGINE_PILE code may still have references and thus those ENGINEs will stay +hooked in forever). The way this is handled is via "unregistration". With these +new ENGINE changes, an abstract ENGINE can be loaded and initialised, but that +is an algorithm-agnostic process. Even if initialised, it will not have +registered any of its implementations (to do so would link all class "table" +code despite the fact the application may use only ciphers, for example). This +is deliberately a distinct step. Moreover, registration and unregistration has +nothing to do with whether an ENGINE is *functional* or not (ie. you can even +register an ENGINE and its implementations without it being operational, you may +not even have the drivers to make it operate). What actually happens with +respect to cleanup is managed inside eng_lib.c with the "engine_cleanup_***" +functions. These functions are internal-only and each part of ENGINE code that +could require cleanup will, upon performing its first allocation, register a +callback with the "engine_cleanup" code. The other part of this that makes it +tick is that the ENGINE_TABLE instantiations (tb_***.c) use NULL as their +initialised state. So if RSA code asks for an ENGINE and no ENGINE has +registered an implementation, the code will simply return NULL and the tb_rsa.c +state will be unchanged. Thus, no cleanup is required unless registration takes +place. ENGINE_cleanup() will simply iterate across a list of registered cleanup +callbacks calling each in turn, and will then internally delete its own storage +(a STACK). When a cleanup callback is next registered (eg. if the cleanup() is +part of a gracefull restart and the application wants to cleanup all state then +start again), the internal STACK storage will be freshly allocated. This is much +the same as the situation in the ENGINE_TABLE instantiations ... NULL is the +initialised state, so only modification operations (not queries) will cause that +code to have to register a cleanup. + +What else? The bignum callbacks and associated ENGINE functions have been +removed for two obvious reasons; (i) there was no way to generalise them to the +mechanism now used by RSA/DSA/..., because there's no such thing as a BIGNUM +method, and (ii) because of (i), there was no meaningful way for library or +application code to automatically hook and use ENGINE supplied bignum functions +anyway. Also, ENGINE_cpy() has been removed (although an internal-only version +exists) - the idea of providing an ENGINE_cpy() function probably wasn't a good +one and now certainly doesn't make sense in any generalised way. Some of the +RSA, DSA, DH, and RAND functions that were fiddled during the original ENGINE +changes have now, as a consequence, been reverted back. This is because the +hooking of ENGINE is now automatic (and passive, it can interally use a NULL +ENGINE pointer to simply ignore ENGINE from then on). + +Hell, that should be enough for now ... comments welcome: geoff@openssl.org + diff --git a/libs/openssl/crypto/engine/eng_all.c b/libs/openssl/crypto/engine/eng_all.c new file mode 100644 index 00000000..66c4374d --- /dev/null +++ b/libs/openssl/crypto/engine/eng_all.c @@ -0,0 +1,139 @@ +/* crypto/engine/eng_all.c */ +/* + * Written by Richard Levitte for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include "eng_int.h" + +void ENGINE_load_builtin_engines(void) +{ + /* Some ENGINEs need this */ + OPENSSL_cpuid_setup(); +#if 0 + /* + * There's no longer any need for an "openssl" ENGINE unless, one day, it + * is the *only* way for standard builtin implementations to be be + * accessed (ie. it would be possible to statically link binaries with + * *no* builtin implementations). + */ + ENGINE_load_openssl(); +#endif +#if !defined(OPENSSL_NO_HW) && (defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV)) + ENGINE_load_cryptodev(); +#endif +#ifndef OPENSSL_NO_RSAX + ENGINE_load_rsax(); +#endif +#ifndef OPENSSL_NO_RDRAND + ENGINE_load_rdrand(); +#endif + ENGINE_load_dynamic(); +#ifndef OPENSSL_NO_STATIC_ENGINE +# ifndef OPENSSL_NO_HW +# ifndef OPENSSL_NO_HW_4758_CCA + ENGINE_load_4758cca(); +# endif +# ifndef OPENSSL_NO_HW_AEP + ENGINE_load_aep(); +# endif +# ifndef OPENSSL_NO_HW_ATALLA + ENGINE_load_atalla(); +# endif +# ifndef OPENSSL_NO_HW_CSWIFT + ENGINE_load_cswift(); +# endif +# ifndef OPENSSL_NO_HW_NCIPHER + ENGINE_load_chil(); +# endif +# ifndef OPENSSL_NO_HW_NURON + ENGINE_load_nuron(); +# endif +# ifndef OPENSSL_NO_HW_SUREWARE + ENGINE_load_sureware(); +# endif +# ifndef OPENSSL_NO_HW_UBSEC + ENGINE_load_ubsec(); +# endif +# ifndef OPENSSL_NO_HW_PADLOCK + ENGINE_load_padlock(); +# endif +# endif +# ifndef OPENSSL_NO_GOST + ENGINE_load_gost(); +# endif +# ifndef OPENSSL_NO_GMP + ENGINE_load_gmp(); +# endif +# if defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_NO_CAPIENG) + ENGINE_load_capi(); +# endif +#endif + ENGINE_register_all_complete(); +} + +#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV) +void ENGINE_setup_bsd_cryptodev(void) +{ + static int bsd_cryptodev_default_loaded = 0; + if (!bsd_cryptodev_default_loaded) { + ENGINE_load_cryptodev(); + ENGINE_register_all_complete(); + } + bsd_cryptodev_default_loaded = 1; +} +#endif diff --git a/libs/openssl/crypto/engine/eng_cnf.c b/libs/openssl/crypto/engine/eng_cnf.c new file mode 100644 index 00000000..f09bec4e --- /dev/null +++ b/libs/openssl/crypto/engine/eng_cnf.c @@ -0,0 +1,242 @@ +/* eng_cnf.c */ +/* + * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" +#include + +/* #define ENGINE_CONF_DEBUG */ + +/* ENGINE config module */ + +static char *skip_dot(char *name) +{ + char *p; + p = strchr(name, '.'); + if (p) + return p + 1; + return name; +} + +static STACK_OF(ENGINE) *initialized_engines = NULL; + +static int int_engine_init(ENGINE *e) +{ + if (!ENGINE_init(e)) + return 0; + if (!initialized_engines) + initialized_engines = sk_ENGINE_new_null(); + if (!initialized_engines || !sk_ENGINE_push(initialized_engines, e)) { + ENGINE_finish(e); + return 0; + } + return 1; +} + +static int int_engine_configure(char *name, char *value, const CONF *cnf) +{ + int i; + int ret = 0; + long do_init = -1; + STACK_OF(CONF_VALUE) *ecmds; + CONF_VALUE *ecmd = NULL; + char *ctrlname, *ctrlvalue; + ENGINE *e = NULL; + int soft = 0; + + name = skip_dot(name); +#ifdef ENGINE_CONF_DEBUG + fprintf(stderr, "Configuring engine %s\n", name); +#endif + /* Value is a section containing ENGINE commands */ + ecmds = NCONF_get_section(cnf, value); + + if (!ecmds) { + ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, + ENGINE_R_ENGINE_SECTION_ERROR); + return 0; + } + + for (i = 0; i < sk_CONF_VALUE_num(ecmds); i++) { + ecmd = sk_CONF_VALUE_value(ecmds, i); + ctrlname = skip_dot(ecmd->name); + ctrlvalue = ecmd->value; +#ifdef ENGINE_CONF_DEBUG + fprintf(stderr, "ENGINE conf: doing ctrl(%s,%s)\n", ctrlname, + ctrlvalue); +#endif + + /* First handle some special pseudo ctrls */ + + /* Override engine name to use */ + if (!strcmp(ctrlname, "engine_id")) + name = ctrlvalue; + else if (!strcmp(ctrlname, "soft_load")) + soft = 1; + /* Load a dynamic ENGINE */ + else if (!strcmp(ctrlname, "dynamic_path")) { + e = ENGINE_by_id("dynamic"); + if (!e) + goto err; + if (!ENGINE_ctrl_cmd_string(e, "SO_PATH", ctrlvalue, 0)) + goto err; + if (!ENGINE_ctrl_cmd_string(e, "LIST_ADD", "2", 0)) + goto err; + if (!ENGINE_ctrl_cmd_string(e, "LOAD", NULL, 0)) + goto err; + } + /* ... add other pseudos here ... */ + else { + /* + * At this point we need an ENGINE structural reference if we + * don't already have one. + */ + if (!e) { + e = ENGINE_by_id(name); + if (!e && soft) { + ERR_clear_error(); + return 1; + } + if (!e) + goto err; + } + /* + * Allow "EMPTY" to mean no value: this allows a valid "value" to + * be passed to ctrls of type NO_INPUT + */ + if (!strcmp(ctrlvalue, "EMPTY")) + ctrlvalue = NULL; + if (!strcmp(ctrlname, "init")) { + if (!NCONF_get_number_e(cnf, value, "init", &do_init)) + goto err; + if (do_init == 1) { + if (!int_engine_init(e)) + goto err; + } else if (do_init != 0) { + ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, + ENGINE_R_INVALID_INIT_VALUE); + goto err; + } + } else if (!strcmp(ctrlname, "default_algorithms")) { + if (!ENGINE_set_default_string(e, ctrlvalue)) + goto err; + } else if (!ENGINE_ctrl_cmd_string(e, ctrlname, ctrlvalue, 0)) + goto err; + } + + } + if (e && (do_init == -1) && !int_engine_init(e)) { + ecmd = NULL; + goto err; + } + ret = 1; + err: + if (ret != 1) { + ENGINEerr(ENGINE_F_INT_ENGINE_CONFIGURE, + ENGINE_R_ENGINE_CONFIGURATION_ERROR); + if (ecmd) + ERR_add_error_data(6, "section=", ecmd->section, + ", name=", ecmd->name, + ", value=", ecmd->value); + } + if (e) + ENGINE_free(e); + return ret; +} + +static int int_engine_module_init(CONF_IMODULE *md, const CONF *cnf) +{ + STACK_OF(CONF_VALUE) *elist; + CONF_VALUE *cval; + int i; +#ifdef ENGINE_CONF_DEBUG + fprintf(stderr, "Called engine module: name %s, value %s\n", + CONF_imodule_get_name(md), CONF_imodule_get_value(md)); +#endif + /* Value is a section containing ENGINEs to configure */ + elist = NCONF_get_section(cnf, CONF_imodule_get_value(md)); + + if (!elist) { + ENGINEerr(ENGINE_F_INT_ENGINE_MODULE_INIT, + ENGINE_R_ENGINES_SECTION_ERROR); + return 0; + } + + for (i = 0; i < sk_CONF_VALUE_num(elist); i++) { + cval = sk_CONF_VALUE_value(elist, i); + if (!int_engine_configure(cval->name, cval->value, cnf)) + return 0; + } + + return 1; +} + +static void int_engine_module_finish(CONF_IMODULE *md) +{ + ENGINE *e; + while ((e = sk_ENGINE_pop(initialized_engines))) + ENGINE_finish(e); + sk_ENGINE_free(initialized_engines); + initialized_engines = NULL; +} + +void ENGINE_add_conf_module(void) +{ + CONF_module_add("engines", + int_engine_module_init, int_engine_module_finish); +} diff --git a/libs/openssl/crypto/engine/eng_cryptodev.c b/libs/openssl/crypto/engine/eng_cryptodev.c new file mode 100644 index 00000000..a8a24d05 --- /dev/null +++ b/libs/openssl/crypto/engine/eng_cryptodev.c @@ -0,0 +1,1473 @@ +/* + * Copyright (c) 2002 Bob Beck + * Copyright (c) 2002 Theo de Raadt + * Copyright (c) 2002 Markus Friedl + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include + +#if (defined(__unix__) || defined(unix)) && !defined(USG) && \ + (defined(OpenBSD) || defined(__FreeBSD__)) +# include +# if (OpenBSD >= 200112) || ((__FreeBSD_version >= 470101 && __FreeBSD_version < 500000) || __FreeBSD_version >= 500041) +# define HAVE_CRYPTODEV +# endif +# if (OpenBSD >= 200110) +# define HAVE_SYSLOG_R +# endif +#endif + +#ifndef HAVE_CRYPTODEV + +void ENGINE_load_cryptodev(void) +{ + /* This is a NOP on platforms without /dev/crypto */ + return; +} + +#else + +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +struct dev_crypto_state { + struct session_op d_sess; + int d_fd; +# ifdef USE_CRYPTODEV_DIGESTS + char dummy_mac_key[HASH_MAX_LEN]; + unsigned char digest_res[HASH_MAX_LEN]; + char *mac_data; + int mac_len; +# endif +}; + +static u_int32_t cryptodev_asymfeat = 0; + +static int get_asym_dev_crypto(void); +static int open_dev_crypto(void); +static int get_dev_crypto(void); +static int get_cryptodev_ciphers(const int **cnids); +# ifdef USE_CRYPTODEV_DIGESTS +static int get_cryptodev_digests(const int **cnids); +# endif +static int cryptodev_usable_ciphers(const int **nids); +static int cryptodev_usable_digests(const int **nids); +static int cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); +static int cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx); +static int cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid); +static int cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid); +static int bn2crparam(const BIGNUM *a, struct crparam *crp); +static int crparam2bn(struct crparam *crp, BIGNUM *a); +static void zapparams(struct crypt_kop *kop); +static int cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, + int slen, BIGNUM *s); + +static int cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +static int cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx); +static int cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx); +static int cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx, BN_MONT_CTX *m_ctx); +static int cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, + BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, + BIGNUM *p, BN_CTX *ctx, + BN_MONT_CTX *mont); +static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, + DSA *dsa); +static int cryptodev_dsa_verify(const unsigned char *dgst, int dgst_len, + DSA_SIG *sig, DSA *dsa); +static int cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx); +static int cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, + DH *dh); +static int cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, + void (*f) (void)); +void ENGINE_load_cryptodev(void); + +static const ENGINE_CMD_DEFN cryptodev_defns[] = { + {0, NULL, NULL, 0} +}; + +static struct { + int id; + int nid; + int ivmax; + int keylen; +} ciphers[] = { + { + CRYPTO_ARC4, NID_rc4, 0, 16, + }, + { + CRYPTO_DES_CBC, NID_des_cbc, 8, 8, + }, + { + CRYPTO_3DES_CBC, NID_des_ede3_cbc, 8, 24, + }, + { + CRYPTO_AES_CBC, NID_aes_128_cbc, 16, 16, + }, + { + CRYPTO_AES_CBC, NID_aes_192_cbc, 16, 24, + }, + { + CRYPTO_AES_CBC, NID_aes_256_cbc, 16, 32, + }, + { + CRYPTO_BLF_CBC, NID_bf_cbc, 8, 16, + }, + { + CRYPTO_CAST_CBC, NID_cast5_cbc, 8, 16, + }, + { + CRYPTO_SKIPJACK_CBC, NID_undef, 0, 0, + }, + { + 0, NID_undef, 0, 0, + }, +}; + +# ifdef USE_CRYPTODEV_DIGESTS +static struct { + int id; + int nid; + int keylen; +} digests[] = { + { + CRYPTO_MD5_HMAC, NID_hmacWithMD5, 16 + }, + { + CRYPTO_SHA1_HMAC, NID_hmacWithSHA1, 20 + }, + { + CRYPTO_RIPEMD160_HMAC, NID_ripemd160, 16 + /* ? */ + }, + { + CRYPTO_MD5_KPDK, NID_undef, 0 + }, + { + CRYPTO_SHA1_KPDK, NID_undef, 0 + }, + { + CRYPTO_MD5, NID_md5, 16 + }, + { + CRYPTO_SHA1, NID_sha1, 20 + }, + { + 0, NID_undef, 0 + }, +}; +# endif + +/* + * Return a fd if /dev/crypto seems usable, 0 otherwise. + */ +static int open_dev_crypto(void) +{ + static int fd = -1; + + if (fd == -1) { + if ((fd = open("/dev/crypto", O_RDWR, 0)) == -1) + return (-1); + /* close on exec */ + if (fcntl(fd, F_SETFD, 1) == -1) { + close(fd); + fd = -1; + return (-1); + } + } + return (fd); +} + +static int get_dev_crypto(void) +{ + int fd, retfd; + + if ((fd = open_dev_crypto()) == -1) + return (-1); +# ifndef CRIOGET_NOT_NEEDED + if (ioctl(fd, CRIOGET, &retfd) == -1) + return (-1); + + /* close on exec */ + if (fcntl(retfd, F_SETFD, 1) == -1) { + close(retfd); + return (-1); + } +# else + retfd = fd; +# endif + return (retfd); +} + +static void put_dev_crypto(int fd) +{ +# ifndef CRIOGET_NOT_NEEDED + close(fd); +# endif +} + +/* Caching version for asym operations */ +static int get_asym_dev_crypto(void) +{ + static int fd = -1; + + if (fd == -1) + fd = get_dev_crypto(); + return fd; +} + +/* + * Find out what ciphers /dev/crypto will let us have a session for. + * XXX note, that some of these openssl doesn't deal with yet! + * returning them here is harmless, as long as we return NULL + * when asked for a handler in the cryptodev_engine_ciphers routine + */ +static int get_cryptodev_ciphers(const int **cnids) +{ + static int nids[CRYPTO_ALGORITHM_MAX]; + struct session_op sess; + int fd, i, count = 0; + + if ((fd = get_dev_crypto()) < 0) { + *cnids = NULL; + return (0); + } + memset(&sess, 0, sizeof(sess)); + sess.key = (caddr_t) "123456789abcdefghijklmno"; + + for (i = 0; ciphers[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { + if (ciphers[i].nid == NID_undef) + continue; + sess.cipher = ciphers[i].id; + sess.keylen = ciphers[i].keylen; + sess.mac = 0; + if (ioctl(fd, CIOCGSESSION, &sess) != -1 && + ioctl(fd, CIOCFSESSION, &sess.ses) != -1) + nids[count++] = ciphers[i].nid; + } + put_dev_crypto(fd); + + if (count > 0) + *cnids = nids; + else + *cnids = NULL; + return (count); +} + +# ifdef USE_CRYPTODEV_DIGESTS +/* + * Find out what digests /dev/crypto will let us have a session for. + * XXX note, that some of these openssl doesn't deal with yet! + * returning them here is harmless, as long as we return NULL + * when asked for a handler in the cryptodev_engine_digests routine + */ +static int get_cryptodev_digests(const int **cnids) +{ + static int nids[CRYPTO_ALGORITHM_MAX]; + struct session_op sess; + int fd, i, count = 0; + + if ((fd = get_dev_crypto()) < 0) { + *cnids = NULL; + return (0); + } + memset(&sess, 0, sizeof(sess)); + sess.mackey = (caddr_t) "123456789abcdefghijklmno"; + for (i = 0; digests[i].id && count < CRYPTO_ALGORITHM_MAX; i++) { + if (digests[i].nid == NID_undef) + continue; + sess.mac = digests[i].id; + sess.mackeylen = digests[i].keylen; + sess.cipher = 0; + if (ioctl(fd, CIOCGSESSION, &sess) != -1 && + ioctl(fd, CIOCFSESSION, &sess.ses) != -1) + nids[count++] = digests[i].nid; + } + put_dev_crypto(fd); + + if (count > 0) + *cnids = nids; + else + *cnids = NULL; + return (count); +} +# endif /* 0 */ + +/* + * Find the useable ciphers|digests from dev/crypto - this is the first + * thing called by the engine init crud which determines what it + * can use for ciphers from this engine. We want to return + * only what we can do, anythine else is handled by software. + * + * If we can't initialize the device to do anything useful for + * any reason, we want to return a NULL array, and 0 length, + * which forces everything to be done is software. By putting + * the initalization of the device in here, we ensure we can + * use this engine as the default, and if for whatever reason + * /dev/crypto won't do what we want it will just be done in + * software + * + * This can (should) be greatly expanded to perhaps take into + * account speed of the device, and what we want to do. + * (although the disabling of particular alg's could be controlled + * by the device driver with sysctl's.) - this is where we + * want most of the decisions made about what we actually want + * to use from /dev/crypto. + */ +static int cryptodev_usable_ciphers(const int **nids) +{ + return (get_cryptodev_ciphers(nids)); +} + +static int cryptodev_usable_digests(const int **nids) +{ +# ifdef USE_CRYPTODEV_DIGESTS + return (get_cryptodev_digests(nids)); +# else + /* + * XXXX just disable all digests for now, because it sucks. + * we need a better way to decide this - i.e. I may not + * want digests on slow cards like hifn on fast machines, + * but might want them on slow or loaded machines, etc. + * will also want them when using crypto cards that don't + * suck moose gonads - would be nice to be able to decide something + * as reasonable default without having hackery that's card dependent. + * of course, the default should probably be just do everything, + * with perhaps a sysctl to turn algoritms off (or have them off + * by default) on cards that generally suck like the hifn. + */ + *nids = NULL; + return (0); +# endif +} + +static int +cryptodev_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + struct crypt_op cryp; + struct dev_crypto_state *state = ctx->cipher_data; + struct session_op *sess = &state->d_sess; + const void *iiv; + unsigned char save_iv[EVP_MAX_IV_LENGTH]; + + if (state->d_fd < 0) + return (0); + if (!inl) + return (1); + if ((inl % ctx->cipher->block_size) != 0) + return (0); + + memset(&cryp, 0, sizeof(cryp)); + + cryp.ses = sess->ses; + cryp.flags = 0; + cryp.len = inl; + cryp.src = (caddr_t) in; + cryp.dst = (caddr_t) out; + cryp.mac = 0; + + cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; + + if (ctx->cipher->iv_len) { + cryp.iv = (caddr_t) ctx->iv; + if (!ctx->encrypt) { + iiv = in + inl - ctx->cipher->iv_len; + memcpy(save_iv, iiv, ctx->cipher->iv_len); + } + } else + cryp.iv = NULL; + + if (ioctl(state->d_fd, CIOCCRYPT, &cryp) == -1) { + /* + * XXX need better errror handling this can fail for a number of + * different reasons. + */ + return (0); + } + + if (ctx->cipher->iv_len) { + if (ctx->encrypt) + iiv = out + inl - ctx->cipher->iv_len; + else + iiv = save_iv; + memcpy(ctx->iv, iiv, ctx->cipher->iv_len); + } + return (1); +} + +static int +cryptodev_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + struct dev_crypto_state *state = ctx->cipher_data; + struct session_op *sess = &state->d_sess; + int cipher = -1, i; + + for (i = 0; ciphers[i].id; i++) + if (ctx->cipher->nid == ciphers[i].nid && + ctx->cipher->iv_len <= ciphers[i].ivmax && + ctx->key_len == ciphers[i].keylen) { + cipher = ciphers[i].id; + break; + } + + if (!ciphers[i].id) { + state->d_fd = -1; + return (0); + } + + memset(sess, 0, sizeof(struct session_op)); + + if ((state->d_fd = get_dev_crypto()) < 0) + return (0); + + sess->key = (caddr_t) key; + sess->keylen = ctx->key_len; + sess->cipher = cipher; + + if (ioctl(state->d_fd, CIOCGSESSION, sess) == -1) { + put_dev_crypto(state->d_fd); + state->d_fd = -1; + return (0); + } + return (1); +} + +/* + * free anything we allocated earlier when initting a + * session, and close the session. + */ +static int cryptodev_cleanup(EVP_CIPHER_CTX *ctx) +{ + int ret = 0; + struct dev_crypto_state *state = ctx->cipher_data; + struct session_op *sess = &state->d_sess; + + if (state->d_fd < 0) + return (0); + + /* + * XXX if this ioctl fails, someting's wrong. the invoker may have called + * us with a bogus ctx, or we could have a device that for whatever + * reason just doesn't want to play ball - it's not clear what's right + * here - should this be an error? should it just increase a counter, + * hmm. For right now, we return 0 - I don't believe that to be "right". + * we could call the gorpy openssl lib error handlers that print messages + * to users of the library. hmm.. + */ + + if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) == -1) { + ret = 0; + } else { + ret = 1; + } + put_dev_crypto(state->d_fd); + state->d_fd = -1; + + return (ret); +} + +/* + * libcrypto EVP stuff - this is how we get wired to EVP so the engine + * gets called when libcrypto requests a cipher NID. + */ + +/* RC4 */ +const EVP_CIPHER cryptodev_rc4 = { + NID_rc4, + 1, 16, 0, + EVP_CIPH_VARIABLE_LENGTH, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + NULL, + NULL, + NULL +}; + +/* DES CBC EVP */ +const EVP_CIPHER cryptodev_des_cbc = { + NID_des_cbc, + 8, 8, 8, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +/* 3DES CBC EVP */ +const EVP_CIPHER cryptodev_3des_cbc = { + NID_des_ede3_cbc, + 8, 24, 8, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +const EVP_CIPHER cryptodev_bf_cbc = { + NID_bf_cbc, + 8, 16, 8, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +const EVP_CIPHER cryptodev_cast_cbc = { + NID_cast5_cbc, + 8, 16, 8, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +const EVP_CIPHER cryptodev_aes_cbc = { + NID_aes_128_cbc, + 16, 16, 16, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +const EVP_CIPHER cryptodev_aes_192_cbc = { + NID_aes_192_cbc, + 16, 24, 16, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +const EVP_CIPHER cryptodev_aes_256_cbc = { + NID_aes_256_cbc, + 16, 32, 16, + EVP_CIPH_CBC_MODE, + cryptodev_init_key, + cryptodev_cipher, + cryptodev_cleanup, + sizeof(struct dev_crypto_state), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL +}; + +/* + * Registered by the ENGINE when used to find out how to deal with + * a particular NID in the ENGINE. this says what we'll do at the + * top level - note, that list is restricted by what we answer with + */ +static int +cryptodev_engine_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid) +{ + if (!cipher) + return (cryptodev_usable_ciphers(nids)); + + switch (nid) { + case NID_rc4: + *cipher = &cryptodev_rc4; + break; + case NID_des_ede3_cbc: + *cipher = &cryptodev_3des_cbc; + break; + case NID_des_cbc: + *cipher = &cryptodev_des_cbc; + break; + case NID_bf_cbc: + *cipher = &cryptodev_bf_cbc; + break; + case NID_cast5_cbc: + *cipher = &cryptodev_cast_cbc; + break; + case NID_aes_128_cbc: + *cipher = &cryptodev_aes_cbc; + break; + case NID_aes_192_cbc: + *cipher = &cryptodev_aes_192_cbc; + break; + case NID_aes_256_cbc: + *cipher = &cryptodev_aes_256_cbc; + break; + default: + *cipher = NULL; + break; + } + return (*cipher != NULL); +} + +# ifdef USE_CRYPTODEV_DIGESTS + +/* convert digest type to cryptodev */ +static int digest_nid_to_cryptodev(int nid) +{ + int i; + + for (i = 0; digests[i].id; i++) + if (digests[i].nid == nid) + return (digests[i].id); + return (0); +} + +static int digest_key_length(int nid) +{ + int i; + + for (i = 0; digests[i].id; i++) + if (digests[i].nid == nid) + return digests[i].keylen; + return (0); +} + +static int cryptodev_digest_init(EVP_MD_CTX *ctx) +{ + struct dev_crypto_state *state = ctx->md_data; + struct session_op *sess = &state->d_sess; + int digest; + + if ((digest = digest_nid_to_cryptodev(ctx->digest->type)) == NID_undef) { + printf("cryptodev_digest_init: Can't get digest \n"); + return (0); + } + + memset(state, 0, sizeof(struct dev_crypto_state)); + + if ((state->d_fd = get_dev_crypto()) < 0) { + printf("cryptodev_digest_init: Can't get Dev \n"); + return (0); + } + + sess->mackey = state->dummy_mac_key; + sess->mackeylen = digest_key_length(ctx->digest->type); + sess->mac = digest; + + if (ioctl(state->d_fd, CIOCGSESSION, sess) < 0) { + put_dev_crypto(state->d_fd); + state->d_fd = -1; + printf("cryptodev_digest_init: Open session failed\n"); + return (0); + } + + return (1); +} + +static int cryptodev_digest_update(EVP_MD_CTX *ctx, const void *data, + size_t count) +{ + struct crypt_op cryp; + struct dev_crypto_state *state = ctx->md_data; + struct session_op *sess = &state->d_sess; + + if (!data || state->d_fd < 0) { + printf("cryptodev_digest_update: illegal inputs \n"); + return (0); + } + + if (!count) { + return (0); + } + + if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { + /* if application doesn't support one buffer */ + state->mac_data = + OPENSSL_realloc(state->mac_data, state->mac_len + count); + + if (!state->mac_data) { + printf("cryptodev_digest_update: realloc failed\n"); + return (0); + } + + memcpy(state->mac_data + state->mac_len, data, count); + state->mac_len += count; + + return (1); + } + + memset(&cryp, 0, sizeof(cryp)); + + cryp.ses = sess->ses; + cryp.flags = 0; + cryp.len = count; + cryp.src = (caddr_t) data; + cryp.dst = NULL; + cryp.mac = (caddr_t) state->digest_res; + if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { + printf("cryptodev_digest_update: digest failed\n"); + return (0); + } + return (1); +} + +static int cryptodev_digest_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + struct crypt_op cryp; + struct dev_crypto_state *state = ctx->md_data; + struct session_op *sess = &state->d_sess; + + int ret = 1; + + if (!md || state->d_fd < 0) { + printf("cryptodev_digest_final: illegal input\n"); + return (0); + } + + if (!(ctx->flags & EVP_MD_CTX_FLAG_ONESHOT)) { + /* if application doesn't support one buffer */ + memset(&cryp, 0, sizeof(cryp)); + cryp.ses = sess->ses; + cryp.flags = 0; + cryp.len = state->mac_len; + cryp.src = state->mac_data; + cryp.dst = NULL; + cryp.mac = (caddr_t) md; + if (ioctl(state->d_fd, CIOCCRYPT, &cryp) < 0) { + printf("cryptodev_digest_final: digest failed\n"); + return (0); + } + + return 1; + } + + memcpy(md, state->digest_res, ctx->digest->md_size); + + return (ret); +} + +static int cryptodev_digest_cleanup(EVP_MD_CTX *ctx) +{ + int ret = 1; + struct dev_crypto_state *state = ctx->md_data; + struct session_op *sess = &state->d_sess; + + if (state == NULL) + return 0; + + if (state->d_fd < 0) { + printf("cryptodev_digest_cleanup: illegal input\n"); + return (0); + } + + if (state->mac_data) { + OPENSSL_free(state->mac_data); + state->mac_data = NULL; + state->mac_len = 0; + } + + if (ioctl(state->d_fd, CIOCFSESSION, &sess->ses) < 0) { + printf("cryptodev_digest_cleanup: failed to close session\n"); + ret = 0; + } else { + ret = 1; + } + put_dev_crypto(state->d_fd); + state->d_fd = -1; + + return (ret); +} + +static int cryptodev_digest_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) +{ + struct dev_crypto_state *fstate = from->md_data; + struct dev_crypto_state *dstate = to->md_data; + struct session_op *sess; + int digest; + + if (dstate == NULL || fstate == NULL) + return 1; + + memcpy(dstate, fstate, sizeof(struct dev_crypto_state)); + + sess = &dstate->d_sess; + + digest = digest_nid_to_cryptodev(to->digest->type); + + sess->mackey = dstate->dummy_mac_key; + sess->mackeylen = digest_key_length(to->digest->type); + sess->mac = digest; + + dstate->d_fd = get_dev_crypto(); + + if (ioctl(dstate->d_fd, CIOCGSESSION, sess) < 0) { + put_dev_crypto(dstate->d_fd); + dstate->d_fd = -1; + printf("cryptodev_digest_init: Open session failed\n"); + return (0); + } + + if (fstate->mac_len != 0) { + if (fstate->mac_data != NULL) { + dstate->mac_data = OPENSSL_malloc(fstate->mac_len); + memcpy(dstate->mac_data, fstate->mac_data, fstate->mac_len); + dstate->mac_len = fstate->mac_len; + } + } + + return 1; +} + +const EVP_MD cryptodev_sha1 = { + NID_sha1, + NID_undef, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_ONESHOT, + cryptodev_digest_init, + cryptodev_digest_update, + cryptodev_digest_final, + cryptodev_digest_copy, + cryptodev_digest_cleanup, + EVP_PKEY_NULL_method, + SHA_CBLOCK, + sizeof(struct dev_crypto_state), +}; + +const EVP_MD cryptodev_md5 = { + NID_md5, + NID_undef, + 16 /* MD5_DIGEST_LENGTH */ , + EVP_MD_FLAG_ONESHOT, + cryptodev_digest_init, + cryptodev_digest_update, + cryptodev_digest_final, + cryptodev_digest_copy, + cryptodev_digest_cleanup, + EVP_PKEY_NULL_method, + 64 /* MD5_CBLOCK */ , + sizeof(struct dev_crypto_state), +}; + +# endif /* USE_CRYPTODEV_DIGESTS */ + +static int +cryptodev_engine_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid) +{ + if (!digest) + return (cryptodev_usable_digests(nids)); + + switch (nid) { +# ifdef USE_CRYPTODEV_DIGESTS + case NID_md5: + *digest = &cryptodev_md5; + break; + case NID_sha1: + *digest = &cryptodev_sha1; + break; + default: +# endif /* USE_CRYPTODEV_DIGESTS */ + *digest = NULL; + break; + } + return (*digest != NULL); +} + +/* + * Convert a BIGNUM to the representation that /dev/crypto needs. + * Upon completion of use, the caller is responsible for freeing + * crp->crp_p. + */ +static int bn2crparam(const BIGNUM *a, struct crparam *crp) +{ + int i, j, k; + ssize_t bytes, bits; + u_char *b; + + crp->crp_p = NULL; + crp->crp_nbits = 0; + + bits = BN_num_bits(a); + bytes = (bits + 7) / 8; + + b = malloc(bytes); + if (b == NULL) + return (1); + memset(b, 0, bytes); + + crp->crp_p = (caddr_t) b; + crp->crp_nbits = bits; + + for (i = 0, j = 0; i < a->top; i++) { + for (k = 0; k < BN_BITS2 / 8; k++) { + if ((j + k) >= bytes) + return (0); + b[j + k] = a->d[i] >> (k * 8); + } + j += BN_BITS2 / 8; + } + return (0); +} + +/* Convert a /dev/crypto parameter to a BIGNUM */ +static int crparam2bn(struct crparam *crp, BIGNUM *a) +{ + u_int8_t *pd; + int i, bytes; + + bytes = (crp->crp_nbits + 7) / 8; + + if (bytes == 0) + return (-1); + + if ((pd = (u_int8_t *) malloc(bytes)) == NULL) + return (-1); + + for (i = 0; i < bytes; i++) + pd[i] = crp->crp_p[bytes - i - 1]; + + BN_bin2bn(pd, bytes, a); + free(pd); + + return (0); +} + +static void zapparams(struct crypt_kop *kop) +{ + int i; + + for (i = 0; i < kop->crk_iparams + kop->crk_oparams; i++) { + if (kop->crk_param[i].crp_p) + free(kop->crk_param[i].crp_p); + kop->crk_param[i].crp_p = NULL; + kop->crk_param[i].crp_nbits = 0; + } +} + +static int +cryptodev_asym(struct crypt_kop *kop, int rlen, BIGNUM *r, int slen, + BIGNUM *s) +{ + int fd, ret = -1; + + if ((fd = get_asym_dev_crypto()) < 0) + return (ret); + + if (r) { + kop->crk_param[kop->crk_iparams].crp_p = calloc(rlen, sizeof(char)); + kop->crk_param[kop->crk_iparams].crp_nbits = rlen * 8; + kop->crk_oparams++; + } + if (s) { + kop->crk_param[kop->crk_iparams + 1].crp_p = + calloc(slen, sizeof(char)); + kop->crk_param[kop->crk_iparams + 1].crp_nbits = slen * 8; + kop->crk_oparams++; + } + + if (ioctl(fd, CIOCKEY, kop) == 0) { + if (r) + crparam2bn(&kop->crk_param[kop->crk_iparams], r); + if (s) + crparam2bn(&kop->crk_param[kop->crk_iparams + 1], s); + ret = 0; + } + + return (ret); +} + +static int +cryptodev_bn_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *in_mont) +{ + struct crypt_kop kop; + int ret = 1; + + /* + * Currently, we know we can do mod exp iff we can do any asymmetric + * operations at all. + */ + if (cryptodev_asymfeat == 0) { + ret = BN_mod_exp(r, a, p, m, ctx); + return (ret); + } + + memset(&kop, 0, sizeof kop); + kop.crk_op = CRK_MOD_EXP; + + /* inputs: a^p % m */ + if (bn2crparam(a, &kop.crk_param[0])) + goto err; + if (bn2crparam(p, &kop.crk_param[1])) + goto err; + if (bn2crparam(m, &kop.crk_param[2])) + goto err; + kop.crk_iparams = 3; + + if (cryptodev_asym(&kop, BN_num_bytes(m), r, 0, NULL)) { + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + printf("OCF asym process failed, Running in software\n"); + ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); + + } else if (ECANCELED == kop.crk_status) { + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + printf("OCF hardware operation cancelled. Running in Software\n"); + ret = meth->bn_mod_exp(r, a, p, m, ctx, in_mont); + } + /* else cryptodev operation worked ok ==> ret = 1 */ + + err: + zapparams(&kop); + return (ret); +} + +static int +cryptodev_rsa_nocrt_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx) +{ + int r; + ctx = BN_CTX_new(); + r = cryptodev_bn_mod_exp(r0, I, rsa->d, rsa->n, ctx, NULL); + BN_CTX_free(ctx); + return (r); +} + +static int +cryptodev_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) +{ + struct crypt_kop kop; + int ret = 1; + + if (!rsa->p || !rsa->q || !rsa->dmp1 || !rsa->dmq1 || !rsa->iqmp) { + /* XXX 0 means failure?? */ + return (0); + } + + memset(&kop, 0, sizeof kop); + kop.crk_op = CRK_MOD_EXP_CRT; + /* inputs: rsa->p rsa->q I rsa->dmp1 rsa->dmq1 rsa->iqmp */ + if (bn2crparam(rsa->p, &kop.crk_param[0])) + goto err; + if (bn2crparam(rsa->q, &kop.crk_param[1])) + goto err; + if (bn2crparam(I, &kop.crk_param[2])) + goto err; + if (bn2crparam(rsa->dmp1, &kop.crk_param[3])) + goto err; + if (bn2crparam(rsa->dmq1, &kop.crk_param[4])) + goto err; + if (bn2crparam(rsa->iqmp, &kop.crk_param[5])) + goto err; + kop.crk_iparams = 6; + + if (cryptodev_asym(&kop, BN_num_bytes(rsa->n), r0, 0, NULL)) { + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + printf("OCF asym process failed, running in Software\n"); + ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); + + } else if (ECANCELED == kop.crk_status) { + const RSA_METHOD *meth = RSA_PKCS1_SSLeay(); + printf("OCF hardware operation cancelled. Running in Software\n"); + ret = (*meth->rsa_mod_exp) (r0, I, rsa, ctx); + } + /* else cryptodev operation worked ok ==> ret = 1 */ + + err: + zapparams(&kop); + return (ret); +} + +static RSA_METHOD cryptodev_rsa = { + "cryptodev RSA method", + NULL, /* rsa_pub_enc */ + NULL, /* rsa_pub_dec */ + NULL, /* rsa_priv_enc */ + NULL, /* rsa_priv_dec */ + NULL, + NULL, + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL, /* app_data */ + NULL, /* rsa_sign */ + NULL /* rsa_verify */ +}; + +static int +cryptodev_dsa_bn_mod_exp(DSA *dsa, BIGNUM *r, BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx) +{ + return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); +} + +static int +cryptodev_dsa_dsa_mod_exp(DSA *dsa, BIGNUM *t1, BIGNUM *g, + BIGNUM *u1, BIGNUM *pub_key, BIGNUM *u2, BIGNUM *p, + BN_CTX *ctx, BN_MONT_CTX *mont) +{ + BIGNUM t2; + int ret = 0; + + BN_init(&t2); + + /* v = ( g^u1 * y^u2 mod p ) mod q */ + /* let t1 = g ^ u1 mod p */ + ret = 0; + + if (!dsa->meth->bn_mod_exp(dsa, t1, dsa->g, u1, dsa->p, ctx, mont)) + goto err; + + /* let t2 = y ^ u2 mod p */ + if (!dsa->meth->bn_mod_exp(dsa, &t2, dsa->pub_key, u2, dsa->p, ctx, mont)) + goto err; + /* let u1 = t1 * t2 mod p */ + if (!BN_mod_mul(u1, t1, &t2, dsa->p, ctx)) + goto err; + + BN_copy(t1, u1); + + ret = 1; + err: + BN_free(&t2); + return (ret); +} + +static DSA_SIG *cryptodev_dsa_do_sign(const unsigned char *dgst, int dlen, + DSA *dsa) +{ + struct crypt_kop kop; + BIGNUM *r = NULL, *s = NULL; + DSA_SIG *dsaret = NULL; + + if ((r = BN_new()) == NULL) + goto err; + if ((s = BN_new()) == NULL) { + BN_free(r); + goto err; + } + + memset(&kop, 0, sizeof kop); + kop.crk_op = CRK_DSA_SIGN; + + /* inputs: dgst dsa->p dsa->q dsa->g dsa->priv_key */ + kop.crk_param[0].crp_p = (caddr_t) dgst; + kop.crk_param[0].crp_nbits = dlen * 8; + if (bn2crparam(dsa->p, &kop.crk_param[1])) + goto err; + if (bn2crparam(dsa->q, &kop.crk_param[2])) + goto err; + if (bn2crparam(dsa->g, &kop.crk_param[3])) + goto err; + if (bn2crparam(dsa->priv_key, &kop.crk_param[4])) + goto err; + kop.crk_iparams = 5; + + if (cryptodev_asym(&kop, BN_num_bytes(dsa->q), r, + BN_num_bytes(dsa->q), s) == 0) { + dsaret = DSA_SIG_new(); + if (dsaret == NULL) + goto err; + dsaret->r = r; + dsaret->s = s; + r = s = NULL; + } else { + const DSA_METHOD *meth = DSA_OpenSSL(); + dsaret = (meth->dsa_do_sign) (dgst, dlen, dsa); + } + err: + BN_free(r); + BN_free(s); + kop.crk_param[0].crp_p = NULL; + zapparams(&kop); + return (dsaret); +} + +static int +cryptodev_dsa_verify(const unsigned char *dgst, int dlen, + DSA_SIG *sig, DSA *dsa) +{ + struct crypt_kop kop; + int dsaret = 1; + + memset(&kop, 0, sizeof kop); + kop.crk_op = CRK_DSA_VERIFY; + + /* inputs: dgst dsa->p dsa->q dsa->g dsa->pub_key sig->r sig->s */ + kop.crk_param[0].crp_p = (caddr_t) dgst; + kop.crk_param[0].crp_nbits = dlen * 8; + if (bn2crparam(dsa->p, &kop.crk_param[1])) + goto err; + if (bn2crparam(dsa->q, &kop.crk_param[2])) + goto err; + if (bn2crparam(dsa->g, &kop.crk_param[3])) + goto err; + if (bn2crparam(dsa->pub_key, &kop.crk_param[4])) + goto err; + if (bn2crparam(sig->r, &kop.crk_param[5])) + goto err; + if (bn2crparam(sig->s, &kop.crk_param[6])) + goto err; + kop.crk_iparams = 7; + + if (cryptodev_asym(&kop, 0, NULL, 0, NULL) == 0) { + /* + * OCF success value is 0, if not zero, change dsaret to fail + */ + if (0 != kop.crk_status) + dsaret = 0; + } else { + const DSA_METHOD *meth = DSA_OpenSSL(); + + dsaret = (meth->dsa_do_verify) (dgst, dlen, sig, dsa); + } + err: + kop.crk_param[0].crp_p = NULL; + zapparams(&kop); + return (dsaret); +} + +static DSA_METHOD cryptodev_dsa = { + "cryptodev DSA method", + NULL, + NULL, /* dsa_sign_setup */ + NULL, + NULL, /* dsa_mod_exp */ + NULL, + NULL, /* init */ + NULL, /* finish */ + 0, /* flags */ + NULL /* app_data */ +}; + +static int +cryptodev_mod_exp_dh(const DH *dh, BIGNUM *r, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *m_ctx) +{ + return (cryptodev_bn_mod_exp(r, a, p, m, ctx, m_ctx)); +} + +static int +cryptodev_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh) +{ + struct crypt_kop kop; + int dhret = 1; + int fd, keylen; + + if ((fd = get_asym_dev_crypto()) < 0) { + const DH_METHOD *meth = DH_OpenSSL(); + + return ((meth->compute_key) (key, pub_key, dh)); + } + + keylen = BN_num_bits(dh->p); + + memset(&kop, 0, sizeof kop); + kop.crk_op = CRK_DH_COMPUTE_KEY; + + /* inputs: dh->priv_key pub_key dh->p key */ + if (bn2crparam(dh->priv_key, &kop.crk_param[0])) + goto err; + if (bn2crparam(pub_key, &kop.crk_param[1])) + goto err; + if (bn2crparam(dh->p, &kop.crk_param[2])) + goto err; + kop.crk_iparams = 3; + + kop.crk_param[3].crp_p = (caddr_t) key; + kop.crk_param[3].crp_nbits = keylen * 8; + kop.crk_oparams = 1; + + if (ioctl(fd, CIOCKEY, &kop) == -1) { + const DH_METHOD *meth = DH_OpenSSL(); + + dhret = (meth->compute_key) (key, pub_key, dh); + } + err: + kop.crk_param[3].crp_p = NULL; + zapparams(&kop); + return (dhret); +} + +static DH_METHOD cryptodev_dh = { + "cryptodev DH method", + NULL, /* cryptodev_dh_generate_key */ + NULL, + NULL, + NULL, + NULL, + 0, /* flags */ + NULL /* app_data */ +}; + +/* + * ctrl right now is just a wrapper that doesn't do much + * but I expect we'll want some options soon. + */ +static int +cryptodev_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ +# ifdef HAVE_SYSLOG_R + struct syslog_data sd = SYSLOG_DATA_INIT; +# endif + + switch (cmd) { + default: +# ifdef HAVE_SYSLOG_R + syslog_r(LOG_ERR, &sd, "cryptodev_ctrl: unknown command %d", cmd); +# else + syslog(LOG_ERR, "cryptodev_ctrl: unknown command %d", cmd); +# endif + break; + } + return (1); +} + +void ENGINE_load_cryptodev(void) +{ + ENGINE *engine = ENGINE_new(); + int fd; + + if (engine == NULL) + return; + if ((fd = get_dev_crypto()) < 0) { + ENGINE_free(engine); + return; + } + + /* + * find out what asymmetric crypto algorithms we support + */ + if (ioctl(fd, CIOCASYMFEAT, &cryptodev_asymfeat) == -1) { + put_dev_crypto(fd); + ENGINE_free(engine); + return; + } + put_dev_crypto(fd); + + if (!ENGINE_set_id(engine, "cryptodev") || + !ENGINE_set_name(engine, "BSD cryptodev engine") || + !ENGINE_set_ciphers(engine, cryptodev_engine_ciphers) || + !ENGINE_set_digests(engine, cryptodev_engine_digests) || + !ENGINE_set_ctrl_function(engine, cryptodev_ctrl) || + !ENGINE_set_cmd_defns(engine, cryptodev_defns)) { + ENGINE_free(engine); + return; + } + + if (ENGINE_set_RSA(engine, &cryptodev_rsa)) { + const RSA_METHOD *rsa_meth = RSA_PKCS1_SSLeay(); + + cryptodev_rsa.bn_mod_exp = rsa_meth->bn_mod_exp; + cryptodev_rsa.rsa_mod_exp = rsa_meth->rsa_mod_exp; + cryptodev_rsa.rsa_pub_enc = rsa_meth->rsa_pub_enc; + cryptodev_rsa.rsa_pub_dec = rsa_meth->rsa_pub_dec; + cryptodev_rsa.rsa_priv_enc = rsa_meth->rsa_priv_enc; + cryptodev_rsa.rsa_priv_dec = rsa_meth->rsa_priv_dec; + if (cryptodev_asymfeat & CRF_MOD_EXP) { + cryptodev_rsa.bn_mod_exp = cryptodev_bn_mod_exp; + if (cryptodev_asymfeat & CRF_MOD_EXP_CRT) + cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_mod_exp; + else + cryptodev_rsa.rsa_mod_exp = cryptodev_rsa_nocrt_mod_exp; + } + } + + if (ENGINE_set_DSA(engine, &cryptodev_dsa)) { + const DSA_METHOD *meth = DSA_OpenSSL(); + + memcpy(&cryptodev_dsa, meth, sizeof(DSA_METHOD)); + if (cryptodev_asymfeat & CRF_DSA_SIGN) + cryptodev_dsa.dsa_do_sign = cryptodev_dsa_do_sign; + if (cryptodev_asymfeat & CRF_MOD_EXP) { + cryptodev_dsa.bn_mod_exp = cryptodev_dsa_bn_mod_exp; + cryptodev_dsa.dsa_mod_exp = cryptodev_dsa_dsa_mod_exp; + } + if (cryptodev_asymfeat & CRF_DSA_VERIFY) + cryptodev_dsa.dsa_do_verify = cryptodev_dsa_verify; + } + + if (ENGINE_set_DH(engine, &cryptodev_dh)) { + const DH_METHOD *dh_meth = DH_OpenSSL(); + + cryptodev_dh.generate_key = dh_meth->generate_key; + cryptodev_dh.compute_key = dh_meth->compute_key; + cryptodev_dh.bn_mod_exp = dh_meth->bn_mod_exp; + if (cryptodev_asymfeat & CRF_MOD_EXP) { + cryptodev_dh.bn_mod_exp = cryptodev_mod_exp_dh; + if (cryptodev_asymfeat & CRF_DH_COMPUTE_KEY) + cryptodev_dh.compute_key = cryptodev_dh_compute_key; + } + } + + ENGINE_add(engine); + ENGINE_free(engine); + ERR_clear_error(); +} + +#endif /* HAVE_CRYPTODEV */ diff --git a/libs/openssl/crypto/engine/eng_ctrl.c b/libs/openssl/crypto/engine/eng_ctrl.c new file mode 100644 index 00000000..e6c0dfb0 --- /dev/null +++ b/libs/openssl/crypto/engine/eng_ctrl.c @@ -0,0 +1,385 @@ +/* crypto/engine/eng_ctrl.c */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * When querying a ENGINE-specific control command's 'description', this + * string is used if the ENGINE_CMD_DEFN has cmd_desc set to NULL. + */ +static const char *int_no_description = ""; + +/* + * These internal functions handle 'CMD'-related control commands when the + * ENGINE in question has asked us to take care of it (ie. the ENGINE did not + * set the ENGINE_FLAGS_MANUAL_CMD_CTRL flag. + */ + +static int int_ctrl_cmd_is_null(const ENGINE_CMD_DEFN *defn) +{ + if ((defn->cmd_num == 0) || (defn->cmd_name == NULL)) + return 1; + return 0; +} + +static int int_ctrl_cmd_by_name(const ENGINE_CMD_DEFN *defn, const char *s) +{ + int idx = 0; + while (!int_ctrl_cmd_is_null(defn) && (strcmp(defn->cmd_name, s) != 0)) { + idx++; + defn++; + } + if (int_ctrl_cmd_is_null(defn)) + /* The given name wasn't found */ + return -1; + return idx; +} + +static int int_ctrl_cmd_by_num(const ENGINE_CMD_DEFN *defn, unsigned int num) +{ + int idx = 0; + /* + * NB: It is stipulated that 'cmd_defn' lists are ordered by cmd_num. So + * our searches don't need to take any longer than necessary. + */ + while (!int_ctrl_cmd_is_null(defn) && (defn->cmd_num < num)) { + idx++; + defn++; + } + if (defn->cmd_num == num) + return idx; + /* The given cmd_num wasn't found */ + return -1; +} + +static int int_ctrl_helper(ENGINE *e, int cmd, long i, void *p, + void (*f) (void)) +{ + int idx; + char *s = (char *)p; + /* Take care of the easy one first (eg. it requires no searches) */ + if (cmd == ENGINE_CTRL_GET_FIRST_CMD_TYPE) { + if ((e->cmd_defns == NULL) || int_ctrl_cmd_is_null(e->cmd_defns)) + return 0; + return e->cmd_defns->cmd_num; + } + /* One or two commands require that "p" be a valid string buffer */ + if ((cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) || + (cmd == ENGINE_CTRL_GET_NAME_FROM_CMD) || + (cmd == ENGINE_CTRL_GET_DESC_FROM_CMD)) { + if (s == NULL) { + ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + } + /* Now handle cmd_name -> cmd_num conversion */ + if (cmd == ENGINE_CTRL_GET_CMD_FROM_NAME) { + if ((e->cmd_defns == NULL) + || ((idx = int_ctrl_cmd_by_name(e->cmd_defns, s)) < 0)) { + ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INVALID_CMD_NAME); + return -1; + } + return e->cmd_defns[idx].cmd_num; + } + /* + * For the rest of the commands, the 'long' argument must specify a valie + * command number - so we need to conduct a search. + */ + if ((e->cmd_defns == NULL) || ((idx = int_ctrl_cmd_by_num(e->cmd_defns, + (unsigned int) + i)) < 0)) { + ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INVALID_CMD_NUMBER); + return -1; + } + /* Now the logic splits depending on command type */ + switch (cmd) { + case ENGINE_CTRL_GET_NEXT_CMD_TYPE: + idx++; + if (int_ctrl_cmd_is_null(e->cmd_defns + idx)) + /* end-of-list */ + return 0; + else + return e->cmd_defns[idx].cmd_num; + case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD: + return strlen(e->cmd_defns[idx].cmd_name); + case ENGINE_CTRL_GET_NAME_FROM_CMD: + return BIO_snprintf(s, strlen(e->cmd_defns[idx].cmd_name) + 1, + "%s", e->cmd_defns[idx].cmd_name); + case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD: + if (e->cmd_defns[idx].cmd_desc) + return strlen(e->cmd_defns[idx].cmd_desc); + return strlen(int_no_description); + case ENGINE_CTRL_GET_DESC_FROM_CMD: + if (e->cmd_defns[idx].cmd_desc) + return BIO_snprintf(s, + strlen(e->cmd_defns[idx].cmd_desc) + 1, + "%s", e->cmd_defns[idx].cmd_desc); + return BIO_snprintf(s, strlen(int_no_description) + 1, "%s", + int_no_description); + case ENGINE_CTRL_GET_CMD_FLAGS: + return e->cmd_defns[idx].cmd_flags; + } + /* Shouldn't really be here ... */ + ENGINEerr(ENGINE_F_INT_CTRL_HELPER, ENGINE_R_INTERNAL_LIST_ERROR); + return -1; +} + +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + int ctrl_exists, ref_exists; + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ref_exists = ((e->struct_ref > 0) ? 1 : 0); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + ctrl_exists = ((e->ctrl == NULL) ? 0 : 1); + if (!ref_exists) { + ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_REFERENCE); + return 0; + } + /* + * Intercept any "root-level" commands before trying to hand them on to + * ctrl() handlers. + */ + switch (cmd) { + case ENGINE_CTRL_HAS_CTRL_FUNCTION: + return ctrl_exists; + case ENGINE_CTRL_GET_FIRST_CMD_TYPE: + case ENGINE_CTRL_GET_NEXT_CMD_TYPE: + case ENGINE_CTRL_GET_CMD_FROM_NAME: + case ENGINE_CTRL_GET_NAME_LEN_FROM_CMD: + case ENGINE_CTRL_GET_NAME_FROM_CMD: + case ENGINE_CTRL_GET_DESC_LEN_FROM_CMD: + case ENGINE_CTRL_GET_DESC_FROM_CMD: + case ENGINE_CTRL_GET_CMD_FLAGS: + if (ctrl_exists && !(e->flags & ENGINE_FLAGS_MANUAL_CMD_CTRL)) + return int_ctrl_helper(e, cmd, i, p, f); + if (!ctrl_exists) { + ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_CONTROL_FUNCTION); + /* + * For these cmd-related functions, failure is indicated by a -1 + * return value (because 0 is used as a valid return in some + * places). + */ + return -1; + } + default: + break; + } + /* Anything else requires a ctrl() handler to exist. */ + if (!ctrl_exists) { + ENGINEerr(ENGINE_F_ENGINE_CTRL, ENGINE_R_NO_CONTROL_FUNCTION); + return 0; + } + return e->ctrl(e, cmd, i, p, f); +} + +int ENGINE_cmd_is_executable(ENGINE *e, int cmd) +{ + int flags; + if ((flags = + ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, cmd, NULL, NULL)) < 0) { + ENGINEerr(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE, + ENGINE_R_INVALID_CMD_NUMBER); + return 0; + } + if (!(flags & ENGINE_CMD_FLAG_NO_INPUT) && + !(flags & ENGINE_CMD_FLAG_NUMERIC) && + !(flags & ENGINE_CMD_FLAG_STRING)) + return 0; + return 1; +} + +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f) (void), int cmd_optional) +{ + int num; + + if ((e == NULL) || (cmd_name == NULL)) { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if ((e->ctrl == NULL) || ((num = ENGINE_ctrl(e, + ENGINE_CTRL_GET_CMD_FROM_NAME, + 0, (void *)cmd_name, + NULL)) <= 0)) { + /* + * If the command didn't *have* to be supported, we fake success. + * This allows certain settings to be specified for multiple ENGINEs + * and only require a change of ENGINE id (without having to + * selectively apply settings). Eg. changing from a hardware device + * back to the regular software ENGINE without editing the config + * file, etc. + */ + if (cmd_optional) { + ERR_clear_error(); + return 1; + } + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD, ENGINE_R_INVALID_CMD_NAME); + return 0; + } + /* + * Force the result of the control command to 0 or 1, for the reasons + * mentioned before. + */ + if (ENGINE_ctrl(e, num, i, p, f) > 0) + return 1; + return 0; +} + +int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, + int cmd_optional) +{ + int num, flags; + long l; + char *ptr; + if ((e == NULL) || (cmd_name == NULL)) { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if ((e->ctrl == NULL) || ((num = ENGINE_ctrl(e, + ENGINE_CTRL_GET_CMD_FROM_NAME, + 0, (void *)cmd_name, + NULL)) <= 0)) { + /* + * If the command didn't *have* to be supported, we fake success. + * This allows certain settings to be specified for multiple ENGINEs + * and only require a change of ENGINE id (without having to + * selectively apply settings). Eg. changing from a hardware device + * back to the regular software ENGINE without editing the config + * file, etc. + */ + if (cmd_optional) { + ERR_clear_error(); + return 1; + } + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, ENGINE_R_INVALID_CMD_NAME); + return 0; + } + if (!ENGINE_cmd_is_executable(e, num)) { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_CMD_NOT_EXECUTABLE); + return 0; + } + if ((flags = + ENGINE_ctrl(e, ENGINE_CTRL_GET_CMD_FLAGS, num, NULL, NULL)) < 0) { + /* + * Shouldn't happen, given that ENGINE_cmd_is_executable() returned + * success. + */ + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_INTERNAL_LIST_ERROR); + return 0; + } + /* + * If the command takes no input, there must be no input. And vice versa. + */ + if (flags & ENGINE_CMD_FLAG_NO_INPUT) { + if (arg != NULL) { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_COMMAND_TAKES_NO_INPUT); + return 0; + } + /* + * We deliberately force the result of ENGINE_ctrl() to 0 or 1 rather + * than returning it as "return data". This is to ensure usage of + * these commands is consistent across applications and that certain + * applications don't understand it one way, and others another. + */ + if (ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0) + return 1; + return 0; + } + /* So, we require input */ + if (arg == NULL) { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_COMMAND_TAKES_INPUT); + return 0; + } + /* If it takes string input, that's easy */ + if (flags & ENGINE_CMD_FLAG_STRING) { + /* Same explanation as above */ + if (ENGINE_ctrl(e, num, 0, (void *)arg, NULL) > 0) + return 1; + return 0; + } + /* + * If it doesn't take numeric either, then it is unsupported for use in a + * config-setting situation, which is what this function is for. This + * should never happen though, because ENGINE_cmd_is_executable() was + * used. + */ + if (!(flags & ENGINE_CMD_FLAG_NUMERIC)) { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_INTERNAL_LIST_ERROR); + return 0; + } + l = strtol(arg, &ptr, 10); + if ((arg == ptr) || (*ptr != '\0')) { + ENGINEerr(ENGINE_F_ENGINE_CTRL_CMD_STRING, + ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER); + return 0; + } + /* + * Force the result of the control command to 0 or 1, for the reasons + * mentioned before. + */ + if (ENGINE_ctrl(e, num, l, NULL, NULL) > 0) + return 1; + return 0; +} diff --git a/libs/openssl/crypto/engine/eng_dyn.c b/libs/openssl/crypto/engine/eng_dyn.c new file mode 100644 index 00000000..3169b09a --- /dev/null +++ b/libs/openssl/crypto/engine/eng_dyn.c @@ -0,0 +1,568 @@ +/* crypto/engine/eng_dyn.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" +#include + +/* + * Shared libraries implementing ENGINEs for use by the "dynamic" ENGINE + * loader should implement the hook-up functions with the following + * prototypes. + */ + +/* Our ENGINE handlers */ +static int dynamic_init(ENGINE *e); +static int dynamic_finish(ENGINE *e); +static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, + void (*f) (void)); +/* Predeclare our context type */ +typedef struct st_dynamic_data_ctx dynamic_data_ctx; +/* The implementation for the important control command */ +static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx); + +#define DYNAMIC_CMD_SO_PATH ENGINE_CMD_BASE +#define DYNAMIC_CMD_NO_VCHECK (ENGINE_CMD_BASE + 1) +#define DYNAMIC_CMD_ID (ENGINE_CMD_BASE + 2) +#define DYNAMIC_CMD_LIST_ADD (ENGINE_CMD_BASE + 3) +#define DYNAMIC_CMD_DIR_LOAD (ENGINE_CMD_BASE + 4) +#define DYNAMIC_CMD_DIR_ADD (ENGINE_CMD_BASE + 5) +#define DYNAMIC_CMD_LOAD (ENGINE_CMD_BASE + 6) + +/* The constants used when creating the ENGINE */ +static const char *engine_dynamic_id = "dynamic"; +static const char *engine_dynamic_name = "Dynamic engine loading support"; +static const ENGINE_CMD_DEFN dynamic_cmd_defns[] = { + {DYNAMIC_CMD_SO_PATH, + "SO_PATH", + "Specifies the path to the new ENGINE shared library", + ENGINE_CMD_FLAG_STRING}, + {DYNAMIC_CMD_NO_VCHECK, + "NO_VCHECK", + "Specifies to continue even if version checking fails (boolean)", + ENGINE_CMD_FLAG_NUMERIC}, + {DYNAMIC_CMD_ID, + "ID", + "Specifies an ENGINE id name for loading", + ENGINE_CMD_FLAG_STRING}, + {DYNAMIC_CMD_LIST_ADD, + "LIST_ADD", + "Whether to add a loaded ENGINE to the internal list (0=no,1=yes,2=mandatory)", + ENGINE_CMD_FLAG_NUMERIC}, + {DYNAMIC_CMD_DIR_LOAD, + "DIR_LOAD", + "Specifies whether to load from 'DIR_ADD' directories (0=no,1=yes,2=mandatory)", + ENGINE_CMD_FLAG_NUMERIC}, + {DYNAMIC_CMD_DIR_ADD, + "DIR_ADD", + "Adds a directory from which ENGINEs can be loaded", + ENGINE_CMD_FLAG_STRING}, + {DYNAMIC_CMD_LOAD, + "LOAD", + "Load up the ENGINE specified by other settings", + ENGINE_CMD_FLAG_NO_INPUT}, + {0, NULL, NULL, 0} +}; + +/* + * Loading code stores state inside the ENGINE structure via the "ex_data" + * element. We load all our state into a single structure and use that as a + * single context in the "ex_data" stack. + */ +struct st_dynamic_data_ctx { + /* The DSO object we load that supplies the ENGINE code */ + DSO *dynamic_dso; + /* + * The function pointer to the version checking shared library function + */ + dynamic_v_check_fn v_check; + /* + * The function pointer to the engine-binding shared library function + */ + dynamic_bind_engine bind_engine; + /* The default name/path for loading the shared library */ + const char *DYNAMIC_LIBNAME; + /* Whether to continue loading on a version check failure */ + int no_vcheck; + /* If non-NULL, stipulates the 'id' of the ENGINE to be loaded */ + const char *engine_id; + /* + * If non-zero, a successfully loaded ENGINE should be added to the + * internal ENGINE list. If 2, the add must succeed or the entire load + * should fail. + */ + int list_add_value; + /* The symbol name for the version checking function */ + const char *DYNAMIC_F1; + /* The symbol name for the "initialise ENGINE structure" function */ + const char *DYNAMIC_F2; + /* + * Whether to never use 'dirs', use 'dirs' as a fallback, or only use + * 'dirs' for loading. Default is to use 'dirs' as a fallback. + */ + int dir_load; + /* A stack of directories from which ENGINEs could be loaded */ + STACK_OF(OPENSSL_STRING) *dirs; +}; + +/* + * This is the "ex_data" index we obtain and reserve for use with our context + * structure. + */ +static int dynamic_ex_data_idx = -1; + +static void int_free_str(char *s) +{ + OPENSSL_free(s); +} + +/* + * Because our ex_data element may or may not get allocated depending on + * whether a "first-use" occurs before the ENGINE is freed, we have a memory + * leak problem to solve. We can't declare a "new" handler for the ex_data as + * we don't want a dynamic_data_ctx in *all* ENGINE structures of all types + * (this is a bug in the design of CRYPTO_EX_DATA). As such, we just declare + * a "free" handler and that will get called if an ENGINE is being destroyed + * and there was an ex_data element corresponding to our context type. + */ +static void dynamic_data_ctx_free_func(void *parent, void *ptr, + CRYPTO_EX_DATA *ad, int idx, long argl, + void *argp) +{ + if (ptr) { + dynamic_data_ctx *ctx = (dynamic_data_ctx *)ptr; + if (ctx->dynamic_dso) + DSO_free(ctx->dynamic_dso); + if (ctx->DYNAMIC_LIBNAME) + OPENSSL_free((void *)ctx->DYNAMIC_LIBNAME); + if (ctx->engine_id) + OPENSSL_free((void *)ctx->engine_id); + if (ctx->dirs) + sk_OPENSSL_STRING_pop_free(ctx->dirs, int_free_str); + OPENSSL_free(ctx); + } +} + +/* + * Construct the per-ENGINE context. We create it blindly and then use a lock + * to check for a race - if so, all but one of the threads "racing" will have + * wasted their time. The alternative involves creating everything inside the + * lock which is far worse. + */ +static int dynamic_set_data_ctx(ENGINE *e, dynamic_data_ctx **ctx) +{ + dynamic_data_ctx *c; + c = OPENSSL_malloc(sizeof(dynamic_data_ctx)); + if (!c) { + ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE); + return 0; + } + memset(c, 0, sizeof(dynamic_data_ctx)); + c->dynamic_dso = NULL; + c->v_check = NULL; + c->bind_engine = NULL; + c->DYNAMIC_LIBNAME = NULL; + c->no_vcheck = 0; + c->engine_id = NULL; + c->list_add_value = 0; + c->DYNAMIC_F1 = "v_check"; + c->DYNAMIC_F2 = "bind_engine"; + c->dir_load = 1; + c->dirs = sk_OPENSSL_STRING_new_null(); + if (!c->dirs) { + ENGINEerr(ENGINE_F_DYNAMIC_SET_DATA_CTX, ERR_R_MALLOC_FAILURE); + OPENSSL_free(c); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if ((*ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, + dynamic_ex_data_idx)) + == NULL) { + /* Good, we're the first */ + ENGINE_set_ex_data(e, dynamic_ex_data_idx, c); + *ctx = c; + c = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* + * If we lost the race to set the context, c is non-NULL and *ctx is the + * context of the thread that won. + */ + if (c) + OPENSSL_free(c); + return 1; +} + +/* + * This function retrieves the context structure from an ENGINE's "ex_data", + * or if it doesn't exist yet, sets it up. + */ +static dynamic_data_ctx *dynamic_get_data_ctx(ENGINE *e) +{ + dynamic_data_ctx *ctx; + if (dynamic_ex_data_idx < 0) { + /* + * Create and register the ENGINE ex_data, and associate our "free" + * function with it to ensure any allocated contexts get freed when + * an ENGINE goes underground. + */ + int new_idx = ENGINE_get_ex_new_index(0, NULL, NULL, NULL, + dynamic_data_ctx_free_func); + if (new_idx == -1) { + ENGINEerr(ENGINE_F_DYNAMIC_GET_DATA_CTX, ENGINE_R_NO_INDEX); + return NULL; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + /* Avoid a race by checking again inside this lock */ + if (dynamic_ex_data_idx < 0) { + /* Good, someone didn't beat us to it */ + dynamic_ex_data_idx = new_idx; + new_idx = -1; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* + * In theory we could "give back" the index here if (new_idx>-1), but + * it's not possible and wouldn't gain us much if it were. + */ + } + ctx = (dynamic_data_ctx *)ENGINE_get_ex_data(e, dynamic_ex_data_idx); + /* Check if the context needs to be created */ + if ((ctx == NULL) && !dynamic_set_data_ctx(e, &ctx)) + /* "set_data" will set errors if necessary */ + return NULL; + return ctx; +} + +static ENGINE *engine_dynamic(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!ENGINE_set_id(ret, engine_dynamic_id) || + !ENGINE_set_name(ret, engine_dynamic_name) || + !ENGINE_set_init_function(ret, dynamic_init) || + !ENGINE_set_finish_function(ret, dynamic_finish) || + !ENGINE_set_ctrl_function(ret, dynamic_ctrl) || + !ENGINE_set_flags(ret, ENGINE_FLAGS_BY_ID_COPY) || + !ENGINE_set_cmd_defns(ret, dynamic_cmd_defns)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_dynamic(void) +{ + ENGINE *toadd = engine_dynamic(); + if (!toadd) + return; + ENGINE_add(toadd); + /* + * If the "add" worked, it gets a structural reference. So either way, we + * release our just-created reference. + */ + ENGINE_free(toadd); + /* + * If the "add" didn't work, it was probably a conflict because it was + * already added (eg. someone calling ENGINE_load_blah then calling + * ENGINE_load_builtin_engines() perhaps). + */ + ERR_clear_error(); +} + +static int dynamic_init(ENGINE *e) +{ + /* + * We always return failure - the "dyanamic" engine itself can't be used + * for anything. + */ + return 0; +} + +static int dynamic_finish(ENGINE *e) +{ + /* + * This should never be called on account of "dynamic_init" always + * failing. + */ + return 0; +} + +static int dynamic_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + dynamic_data_ctx *ctx = dynamic_get_data_ctx(e); + int initialised; + + if (!ctx) { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_NOT_LOADED); + return 0; + } + initialised = ((ctx->dynamic_dso == NULL) ? 0 : 1); + /* All our control commands require the ENGINE to be uninitialised */ + if (initialised) { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_ALREADY_LOADED); + return 0; + } + switch (cmd) { + case DYNAMIC_CMD_SO_PATH: + /* a NULL 'p' or a string of zero-length is the same thing */ + if (p && (strlen((const char *)p) < 1)) + p = NULL; + if (ctx->DYNAMIC_LIBNAME) + OPENSSL_free((void *)ctx->DYNAMIC_LIBNAME); + if (p) + ctx->DYNAMIC_LIBNAME = BUF_strdup(p); + else + ctx->DYNAMIC_LIBNAME = NULL; + return (ctx->DYNAMIC_LIBNAME ? 1 : 0); + case DYNAMIC_CMD_NO_VCHECK: + ctx->no_vcheck = ((i == 0) ? 0 : 1); + return 1; + case DYNAMIC_CMD_ID: + /* a NULL 'p' or a string of zero-length is the same thing */ + if (p && (strlen((const char *)p) < 1)) + p = NULL; + if (ctx->engine_id) + OPENSSL_free((void *)ctx->engine_id); + if (p) + ctx->engine_id = BUF_strdup(p); + else + ctx->engine_id = NULL; + return (ctx->engine_id ? 1 : 0); + case DYNAMIC_CMD_LIST_ADD: + if ((i < 0) || (i > 2)) { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT); + return 0; + } + ctx->list_add_value = (int)i; + return 1; + case DYNAMIC_CMD_LOAD: + return dynamic_load(e, ctx); + case DYNAMIC_CMD_DIR_LOAD: + if ((i < 0) || (i > 2)) { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT); + return 0; + } + ctx->dir_load = (int)i; + return 1; + case DYNAMIC_CMD_DIR_ADD: + /* a NULL 'p' or a string of zero-length is the same thing */ + if (!p || (strlen((const char *)p) < 1)) { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_INVALID_ARGUMENT); + return 0; + } + { + char *tmp_str = BUF_strdup(p); + if (!tmp_str) { + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ERR_R_MALLOC_FAILURE); + return 0; + } + sk_OPENSSL_STRING_insert(ctx->dirs, tmp_str, -1); + } + return 1; + default: + break; + } + ENGINEerr(ENGINE_F_DYNAMIC_CTRL, ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED); + return 0; +} + +static int int_load(dynamic_data_ctx *ctx) +{ + int num, loop; + /* Unless told not to, try a direct load */ + if ((ctx->dir_load != 2) && (DSO_load(ctx->dynamic_dso, + ctx->DYNAMIC_LIBNAME, NULL, + 0)) != NULL) + return 1; + /* If we're not allowed to use 'dirs' or we have none, fail */ + if (!ctx->dir_load || (num = sk_OPENSSL_STRING_num(ctx->dirs)) < 1) + return 0; + for (loop = 0; loop < num; loop++) { + const char *s = sk_OPENSSL_STRING_value(ctx->dirs, loop); + char *merge = DSO_merge(ctx->dynamic_dso, ctx->DYNAMIC_LIBNAME, s); + if (!merge) + return 0; + if (DSO_load(ctx->dynamic_dso, merge, NULL, 0)) { + /* Found what we're looking for */ + OPENSSL_free(merge); + return 1; + } + OPENSSL_free(merge); + } + return 0; +} + +static int dynamic_load(ENGINE *e, dynamic_data_ctx *ctx) +{ + ENGINE cpy; + dynamic_fns fns; + + if (!ctx->dynamic_dso) + ctx->dynamic_dso = DSO_new(); + if (!ctx->DYNAMIC_LIBNAME) { + if (!ctx->engine_id) + return 0; + ctx->DYNAMIC_LIBNAME = + DSO_convert_filename(ctx->dynamic_dso, ctx->engine_id); + } + if (!int_load(ctx)) { + ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_NOT_FOUND); + DSO_free(ctx->dynamic_dso); + ctx->dynamic_dso = NULL; + return 0; + } + /* We have to find a bind function otherwise it'll always end badly */ + if (! + (ctx->bind_engine = + (dynamic_bind_engine) DSO_bind_func(ctx->dynamic_dso, + ctx->DYNAMIC_F2))) { + ctx->bind_engine = NULL; + DSO_free(ctx->dynamic_dso); + ctx->dynamic_dso = NULL; + ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_DSO_FAILURE); + return 0; + } + /* Do we perform version checking? */ + if (!ctx->no_vcheck) { + unsigned long vcheck_res = 0; + /* + * Now we try to find a version checking function and decide how to + * cope with failure if/when it fails. + */ + ctx->v_check = + (dynamic_v_check_fn) DSO_bind_func(ctx->dynamic_dso, + ctx->DYNAMIC_F1); + if (ctx->v_check) + vcheck_res = ctx->v_check(OSSL_DYNAMIC_VERSION); + /* + * We fail if the version checker veto'd the load *or* if it is + * deferring to us (by returning its version) and we think it is too + * old. + */ + if (vcheck_res < OSSL_DYNAMIC_OLDEST) { + /* Fail */ + ctx->bind_engine = NULL; + ctx->v_check = NULL; + DSO_free(ctx->dynamic_dso); + ctx->dynamic_dso = NULL; + ENGINEerr(ENGINE_F_DYNAMIC_LOAD, + ENGINE_R_VERSION_INCOMPATIBILITY); + return 0; + } + } + /* + * First binary copy the ENGINE structure so that we can roll back if the + * hand-over fails + */ + memcpy(&cpy, e, sizeof(ENGINE)); + /* + * Provide the ERR, "ex_data", memory, and locking callbacks so the + * loaded library uses our state rather than its own. FIXME: As noted in + * engine.h, much of this would be simplified if each area of code + * provided its own "summary" structure of all related callbacks. It + * would also increase opaqueness. + */ + fns.static_state = ENGINE_get_static_state(); + fns.err_fns = ERR_get_implementation(); + fns.ex_data_fns = CRYPTO_get_ex_data_implementation(); + CRYPTO_get_mem_functions(&fns.mem_fns.malloc_cb, + &fns.mem_fns.realloc_cb, &fns.mem_fns.free_cb); + fns.lock_fns.lock_locking_cb = CRYPTO_get_locking_callback(); + fns.lock_fns.lock_add_lock_cb = CRYPTO_get_add_lock_callback(); + fns.lock_fns.dynlock_create_cb = CRYPTO_get_dynlock_create_callback(); + fns.lock_fns.dynlock_lock_cb = CRYPTO_get_dynlock_lock_callback(); + fns.lock_fns.dynlock_destroy_cb = CRYPTO_get_dynlock_destroy_callback(); + /* + * Now that we've loaded the dynamic engine, make sure no "dynamic" + * ENGINE elements will show through. + */ + engine_set_all_null(e); + + /* Try to bind the ENGINE onto our own ENGINE structure */ + if (!ctx->bind_engine(e, ctx->engine_id, &fns)) { + ctx->bind_engine = NULL; + ctx->v_check = NULL; + DSO_free(ctx->dynamic_dso); + ctx->dynamic_dso = NULL; + ENGINEerr(ENGINE_F_DYNAMIC_LOAD, ENGINE_R_INIT_FAILED); + /* Copy the original ENGINE structure back */ + memcpy(e, &cpy, sizeof(ENGINE)); + return 0; + } + /* Do we try to add this ENGINE to the internal list too? */ + if (ctx->list_add_value > 0) { + if (!ENGINE_add(e)) { + /* Do we tolerate this or fail? */ + if (ctx->list_add_value > 1) { + /* + * Fail - NB: By this time, it's too late to rollback, and + * trying to do so allows the bind_engine() code to have + * created leaks. We just have to fail where we are, after + * the ENGINE has changed. + */ + ENGINEerr(ENGINE_F_DYNAMIC_LOAD, + ENGINE_R_CONFLICTING_ENGINE_ID); + return 0; + } + /* Tolerate */ + ERR_clear_error(); + } + } + return 1; +} diff --git a/libs/openssl/crypto/engine/eng_err.c b/libs/openssl/crypto/engine/eng_err.c new file mode 100644 index 00000000..bcc23485 --- /dev/null +++ b/libs/openssl/crypto/engine/eng_err.c @@ -0,0 +1,181 @@ +/* crypto/engine/eng_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ENGINE,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ENGINE,0,reason) + +static ERR_STRING_DATA ENGINE_str_functs[] = { + {ERR_FUNC(ENGINE_F_DYNAMIC_CTRL), "DYNAMIC_CTRL"}, + {ERR_FUNC(ENGINE_F_DYNAMIC_GET_DATA_CTX), "DYNAMIC_GET_DATA_CTX"}, + {ERR_FUNC(ENGINE_F_DYNAMIC_LOAD), "DYNAMIC_LOAD"}, + {ERR_FUNC(ENGINE_F_DYNAMIC_SET_DATA_CTX), "DYNAMIC_SET_DATA_CTX"}, + {ERR_FUNC(ENGINE_F_ENGINE_ADD), "ENGINE_add"}, + {ERR_FUNC(ENGINE_F_ENGINE_BY_ID), "ENGINE_by_id"}, + {ERR_FUNC(ENGINE_F_ENGINE_CMD_IS_EXECUTABLE), "ENGINE_cmd_is_executable"}, + {ERR_FUNC(ENGINE_F_ENGINE_CTRL), "ENGINE_ctrl"}, + {ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD), "ENGINE_ctrl_cmd"}, + {ERR_FUNC(ENGINE_F_ENGINE_CTRL_CMD_STRING), "ENGINE_ctrl_cmd_string"}, + {ERR_FUNC(ENGINE_F_ENGINE_FINISH), "ENGINE_finish"}, + {ERR_FUNC(ENGINE_F_ENGINE_FREE_UTIL), "ENGINE_FREE_UTIL"}, + {ERR_FUNC(ENGINE_F_ENGINE_GET_CIPHER), "ENGINE_get_cipher"}, + {ERR_FUNC(ENGINE_F_ENGINE_GET_DEFAULT_TYPE), "ENGINE_GET_DEFAULT_TYPE"}, + {ERR_FUNC(ENGINE_F_ENGINE_GET_DIGEST), "ENGINE_get_digest"}, + {ERR_FUNC(ENGINE_F_ENGINE_GET_NEXT), "ENGINE_get_next"}, + {ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH), + "ENGINE_get_pkey_asn1_meth"}, + {ERR_FUNC(ENGINE_F_ENGINE_GET_PKEY_METH), "ENGINE_get_pkey_meth"}, + {ERR_FUNC(ENGINE_F_ENGINE_GET_PREV), "ENGINE_get_prev"}, + {ERR_FUNC(ENGINE_F_ENGINE_INIT), "ENGINE_init"}, + {ERR_FUNC(ENGINE_F_ENGINE_LIST_ADD), "ENGINE_LIST_ADD"}, + {ERR_FUNC(ENGINE_F_ENGINE_LIST_REMOVE), "ENGINE_LIST_REMOVE"}, + {ERR_FUNC(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY), "ENGINE_load_private_key"}, + {ERR_FUNC(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY), "ENGINE_load_public_key"}, + {ERR_FUNC(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT), + "ENGINE_load_ssl_client_cert"}, + {ERR_FUNC(ENGINE_F_ENGINE_NEW), "ENGINE_new"}, + {ERR_FUNC(ENGINE_F_ENGINE_REMOVE), "ENGINE_remove"}, + {ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_STRING), + "ENGINE_set_default_string"}, + {ERR_FUNC(ENGINE_F_ENGINE_SET_DEFAULT_TYPE), "ENGINE_SET_DEFAULT_TYPE"}, + {ERR_FUNC(ENGINE_F_ENGINE_SET_ID), "ENGINE_set_id"}, + {ERR_FUNC(ENGINE_F_ENGINE_SET_NAME), "ENGINE_set_name"}, + {ERR_FUNC(ENGINE_F_ENGINE_TABLE_REGISTER), "ENGINE_TABLE_REGISTER"}, + {ERR_FUNC(ENGINE_F_ENGINE_UNLOAD_KEY), "ENGINE_UNLOAD_KEY"}, + {ERR_FUNC(ENGINE_F_ENGINE_UNLOCKED_FINISH), "ENGINE_UNLOCKED_FINISH"}, + {ERR_FUNC(ENGINE_F_ENGINE_UP_REF), "ENGINE_up_ref"}, + {ERR_FUNC(ENGINE_F_INT_CTRL_HELPER), "INT_CTRL_HELPER"}, + {ERR_FUNC(ENGINE_F_INT_ENGINE_CONFIGURE), "INT_ENGINE_CONFIGURE"}, + {ERR_FUNC(ENGINE_F_INT_ENGINE_MODULE_INIT), "INT_ENGINE_MODULE_INIT"}, + {ERR_FUNC(ENGINE_F_LOG_MESSAGE), "LOG_MESSAGE"}, + {0, NULL} +}; + +static ERR_STRING_DATA ENGINE_str_reasons[] = { + {ERR_REASON(ENGINE_R_ALREADY_LOADED), "already loaded"}, + {ERR_REASON(ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER), + "argument is not a number"}, + {ERR_REASON(ENGINE_R_CMD_NOT_EXECUTABLE), "cmd not executable"}, + {ERR_REASON(ENGINE_R_COMMAND_TAKES_INPUT), "command takes input"}, + {ERR_REASON(ENGINE_R_COMMAND_TAKES_NO_INPUT), "command takes no input"}, + {ERR_REASON(ENGINE_R_CONFLICTING_ENGINE_ID), "conflicting engine id"}, + {ERR_REASON(ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED), + "ctrl command not implemented"}, + {ERR_REASON(ENGINE_R_DH_NOT_IMPLEMENTED), "dh not implemented"}, + {ERR_REASON(ENGINE_R_DSA_NOT_IMPLEMENTED), "dsa not implemented"}, + {ERR_REASON(ENGINE_R_DSO_FAILURE), "DSO failure"}, + {ERR_REASON(ENGINE_R_DSO_NOT_FOUND), "dso not found"}, + {ERR_REASON(ENGINE_R_ENGINES_SECTION_ERROR), "engines section error"}, + {ERR_REASON(ENGINE_R_ENGINE_CONFIGURATION_ERROR), + "engine configuration error"}, + {ERR_REASON(ENGINE_R_ENGINE_IS_NOT_IN_LIST), "engine is not in the list"}, + {ERR_REASON(ENGINE_R_ENGINE_SECTION_ERROR), "engine section error"}, + {ERR_REASON(ENGINE_R_FAILED_LOADING_PRIVATE_KEY), + "failed loading private key"}, + {ERR_REASON(ENGINE_R_FAILED_LOADING_PUBLIC_KEY), + "failed loading public key"}, + {ERR_REASON(ENGINE_R_FINISH_FAILED), "finish failed"}, + {ERR_REASON(ENGINE_R_GET_HANDLE_FAILED), + "could not obtain hardware handle"}, + {ERR_REASON(ENGINE_R_ID_OR_NAME_MISSING), "'id' or 'name' missing"}, + {ERR_REASON(ENGINE_R_INIT_FAILED), "init failed"}, + {ERR_REASON(ENGINE_R_INTERNAL_LIST_ERROR), "internal list error"}, + {ERR_REASON(ENGINE_R_INVALID_ARGUMENT), "invalid argument"}, + {ERR_REASON(ENGINE_R_INVALID_CMD_NAME), "invalid cmd name"}, + {ERR_REASON(ENGINE_R_INVALID_CMD_NUMBER), "invalid cmd number"}, + {ERR_REASON(ENGINE_R_INVALID_INIT_VALUE), "invalid init value"}, + {ERR_REASON(ENGINE_R_INVALID_STRING), "invalid string"}, + {ERR_REASON(ENGINE_R_NOT_INITIALISED), "not initialised"}, + {ERR_REASON(ENGINE_R_NOT_LOADED), "not loaded"}, + {ERR_REASON(ENGINE_R_NO_CONTROL_FUNCTION), "no control function"}, + {ERR_REASON(ENGINE_R_NO_INDEX), "no index"}, + {ERR_REASON(ENGINE_R_NO_LOAD_FUNCTION), "no load function"}, + {ERR_REASON(ENGINE_R_NO_REFERENCE), "no reference"}, + {ERR_REASON(ENGINE_R_NO_SUCH_ENGINE), "no such engine"}, + {ERR_REASON(ENGINE_R_NO_UNLOAD_FUNCTION), "no unload function"}, + {ERR_REASON(ENGINE_R_PROVIDE_PARAMETERS), "provide parameters"}, + {ERR_REASON(ENGINE_R_RSA_NOT_IMPLEMENTED), "rsa not implemented"}, + {ERR_REASON(ENGINE_R_UNIMPLEMENTED_CIPHER), "unimplemented cipher"}, + {ERR_REASON(ENGINE_R_UNIMPLEMENTED_DIGEST), "unimplemented digest"}, + {ERR_REASON(ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD), + "unimplemented public key method"}, + {ERR_REASON(ENGINE_R_VERSION_INCOMPATIBILITY), "version incompatibility"}, + {0, NULL} +}; + +#endif + +void ERR_load_ENGINE_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(ENGINE_str_functs[0].error) == NULL) { + ERR_load_strings(0, ENGINE_str_functs); + ERR_load_strings(0, ENGINE_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/engine/eng_fat.c b/libs/openssl/crypto/engine/eng_fat.c new file mode 100644 index 00000000..4279dd94 --- /dev/null +++ b/libs/openssl/crypto/engine/eng_fat.c @@ -0,0 +1,181 @@ +/* crypto/engine/eng_fat.c */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include "eng_int.h" +#include + +int ENGINE_set_default(ENGINE *e, unsigned int flags) +{ + if ((flags & ENGINE_METHOD_CIPHERS) && !ENGINE_set_default_ciphers(e)) + return 0; + if ((flags & ENGINE_METHOD_DIGESTS) && !ENGINE_set_default_digests(e)) + return 0; +#ifndef OPENSSL_NO_RSA + if ((flags & ENGINE_METHOD_RSA) && !ENGINE_set_default_RSA(e)) + return 0; +#endif +#ifndef OPENSSL_NO_DSA + if ((flags & ENGINE_METHOD_DSA) && !ENGINE_set_default_DSA(e)) + return 0; +#endif +#ifndef OPENSSL_NO_DH + if ((flags & ENGINE_METHOD_DH) && !ENGINE_set_default_DH(e)) + return 0; +#endif +#ifndef OPENSSL_NO_ECDH + if ((flags & ENGINE_METHOD_ECDH) && !ENGINE_set_default_ECDH(e)) + return 0; +#endif +#ifndef OPENSSL_NO_ECDSA + if ((flags & ENGINE_METHOD_ECDSA) && !ENGINE_set_default_ECDSA(e)) + return 0; +#endif + if ((flags & ENGINE_METHOD_RAND) && !ENGINE_set_default_RAND(e)) + return 0; + if ((flags & ENGINE_METHOD_PKEY_METHS) + && !ENGINE_set_default_pkey_meths(e)) + return 0; + if ((flags & ENGINE_METHOD_PKEY_ASN1_METHS) + && !ENGINE_set_default_pkey_asn1_meths(e)) + return 0; + return 1; +} + +/* Set default algorithms using a string */ + +static int int_def_cb(const char *alg, int len, void *arg) +{ + unsigned int *pflags = arg; + if (alg == NULL) + return 0; + if (!strncmp(alg, "ALL", len)) + *pflags |= ENGINE_METHOD_ALL; + else if (!strncmp(alg, "RSA", len)) + *pflags |= ENGINE_METHOD_RSA; + else if (!strncmp(alg, "DSA", len)) + *pflags |= ENGINE_METHOD_DSA; + else if (!strncmp(alg, "ECDH", len)) + *pflags |= ENGINE_METHOD_ECDH; + else if (!strncmp(alg, "ECDSA", len)) + *pflags |= ENGINE_METHOD_ECDSA; + else if (!strncmp(alg, "DH", len)) + *pflags |= ENGINE_METHOD_DH; + else if (!strncmp(alg, "RAND", len)) + *pflags |= ENGINE_METHOD_RAND; + else if (!strncmp(alg, "CIPHERS", len)) + *pflags |= ENGINE_METHOD_CIPHERS; + else if (!strncmp(alg, "DIGESTS", len)) + *pflags |= ENGINE_METHOD_DIGESTS; + else if (!strncmp(alg, "PKEY", len)) + *pflags |= ENGINE_METHOD_PKEY_METHS | ENGINE_METHOD_PKEY_ASN1_METHS; + else if (!strncmp(alg, "PKEY_CRYPTO", len)) + *pflags |= ENGINE_METHOD_PKEY_METHS; + else if (!strncmp(alg, "PKEY_ASN1", len)) + *pflags |= ENGINE_METHOD_PKEY_ASN1_METHS; + else + return 0; + return 1; +} + +int ENGINE_set_default_string(ENGINE *e, const char *def_list) +{ + unsigned int flags = 0; + if (!CONF_parse_list(def_list, ',', 1, int_def_cb, &flags)) { + ENGINEerr(ENGINE_F_ENGINE_SET_DEFAULT_STRING, + ENGINE_R_INVALID_STRING); + ERR_add_error_data(2, "str=", def_list); + return 0; + } + return ENGINE_set_default(e, flags); +} + +int ENGINE_register_complete(ENGINE *e) +{ + ENGINE_register_ciphers(e); + ENGINE_register_digests(e); +#ifndef OPENSSL_NO_RSA + ENGINE_register_RSA(e); +#endif +#ifndef OPENSSL_NO_DSA + ENGINE_register_DSA(e); +#endif +#ifndef OPENSSL_NO_DH + ENGINE_register_DH(e); +#endif +#ifndef OPENSSL_NO_ECDH + ENGINE_register_ECDH(e); +#endif +#ifndef OPENSSL_NO_ECDSA + ENGINE_register_ECDSA(e); +#endif + ENGINE_register_RAND(e); + ENGINE_register_pkey_meths(e); + return 1; +} + +int ENGINE_register_all_complete(void) +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + if (!(e->flags & ENGINE_FLAGS_NO_REGISTER_ALL)) + ENGINE_register_complete(e); + return 1; +} diff --git a/libs/openssl/crypto/engine/eng_init.c b/libs/openssl/crypto/engine/eng_init.c new file mode 100644 index 00000000..4ea7fe63 --- /dev/null +++ b/libs/openssl/crypto/engine/eng_init.c @@ -0,0 +1,157 @@ +/* crypto/engine/eng_init.c */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * Initialise a engine type for use (or up its functional reference count if + * it's already in use). This version is only used internally. + */ +int engine_unlocked_init(ENGINE *e) +{ + int to_return = 1; + + if ((e->funct_ref == 0) && e->init) + /* + * This is the first functional reference and the engine requires + * initialisation so we do it now. + */ + to_return = e->init(e); + if (to_return) { + /* + * OK, we return a functional reference which is also a structural + * reference. + */ + e->struct_ref++; + e->funct_ref++; + engine_ref_debug(e, 0, 1) + engine_ref_debug(e, 1, 1) + } + return to_return; +} + +/* + * Free a functional reference to a engine type. This version is only used + * internally. + */ +int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers) +{ + int to_return = 1; + + /* + * Reduce the functional reference count here so if it's the terminating + * case, we can release the lock safely and call the finish() handler + * without risk of a race. We get a race if we leave the count until + * after and something else is calling "finish" at the same time - + * there's a chance that both threads will together take the count from 2 + * to 0 without either calling finish(). + */ + e->funct_ref--; + engine_ref_debug(e, 1, -1); + if ((e->funct_ref == 0) && e->finish) { + if (unlock_for_handlers) + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + to_return = e->finish(e); + if (unlock_for_handlers) + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (!to_return) + return 0; + } +#ifdef REF_CHECK + if (e->funct_ref < 0) { + fprintf(stderr, "ENGINE_finish, bad functional reference count\n"); + abort(); + } +#endif + /* Release the structural reference too */ + if (!engine_free_util(e, 0)) { + ENGINEerr(ENGINE_F_ENGINE_UNLOCKED_FINISH, ENGINE_R_FINISH_FAILED); + return 0; + } + return to_return; +} + +/* The API (locked) version of "init" */ +int ENGINE_init(ENGINE *e) +{ + int ret; + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_INIT, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ret = engine_unlocked_init(e); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return ret; +} + +/* The API (locked) version of "finish" */ +int ENGINE_finish(ENGINE *e) +{ + int to_return = 1; + + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_FINISH, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + to_return = engine_unlocked_finish(e, 1); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + if (!to_return) { + ENGINEerr(ENGINE_F_ENGINE_FINISH, ENGINE_R_FINISH_FAILED); + return 0; + } + return to_return; +} diff --git a/libs/openssl/crypto/engine/eng_int.h b/libs/openssl/crypto/engine/eng_int.h new file mode 100644 index 00000000..46f163b1 --- /dev/null +++ b/libs/openssl/crypto/engine/eng_int.h @@ -0,0 +1,224 @@ +/* crypto/engine/eng_int.h */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_ENGINE_INT_H +# define HEADER_ENGINE_INT_H + +# include "cryptlib.h" +/* Take public definitions from engine.h */ +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * If we compile with this symbol defined, then both reference counts in the + * ENGINE structure will be monitored with a line of output on stderr for + * each change. This prints the engine's pointer address (truncated to + * unsigned int), "struct" or "funct" to indicate the reference type, the + * before and after reference count, and the file:line-number pair. The + * "engine_ref_debug" statements must come *after* the change. + */ +# ifdef ENGINE_REF_COUNT_DEBUG + +# define engine_ref_debug(e, isfunct, diff) \ + fprintf(stderr, "engine: %08x %s from %d to %d (%s:%d)\n", \ + (unsigned int)(e), (isfunct ? "funct" : "struct"), \ + ((isfunct) ? ((e)->funct_ref - (diff)) : ((e)->struct_ref - (diff))), \ + ((isfunct) ? (e)->funct_ref : (e)->struct_ref), \ + (__FILE__), (__LINE__)); + +# else + +# define engine_ref_debug(e, isfunct, diff) + +# endif + +/* + * Any code that will need cleanup operations should use these functions to + * register callbacks. ENGINE_cleanup() will call all registered callbacks in + * order. NB: both the "add" functions assume CRYPTO_LOCK_ENGINE to already be + * held (in "write" mode). + */ +typedef void (ENGINE_CLEANUP_CB) (void); +typedef struct st_engine_cleanup_item { + ENGINE_CLEANUP_CB *cb; +} ENGINE_CLEANUP_ITEM; +DECLARE_STACK_OF(ENGINE_CLEANUP_ITEM) +void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb); +void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb); + +/* We need stacks of ENGINEs for use in eng_table.c */ +DECLARE_STACK_OF(ENGINE) + +/* + * If this symbol is defined then engine_table_select(), the function that is + * used by RSA, DSA (etc) code to select registered ENGINEs, cache defaults + * and functional references (etc), will display debugging summaries to + * stderr. + */ +/* #define ENGINE_TABLE_DEBUG */ + +/* + * This represents an implementation table. Dependent code should instantiate + * it as a (ENGINE_TABLE *) pointer value set initially to NULL. + */ +typedef struct st_engine_table ENGINE_TABLE; +int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, + ENGINE *e, const int *nids, int num_nids, + int setdefault); +void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e); +void engine_table_cleanup(ENGINE_TABLE **table); +# ifndef ENGINE_TABLE_DEBUG +ENGINE *engine_table_select(ENGINE_TABLE **table, int nid); +# else +ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, + int l); +# define engine_table_select(t,n) engine_table_select_tmp(t,n,__FILE__,__LINE__) +# endif +typedef void (engine_table_doall_cb) (int nid, STACK_OF(ENGINE) *sk, + ENGINE *def, void *arg); +void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, + void *arg); + +/* + * Internal versions of API functions that have control over locking. These + * are used between C files when functionality needs to be shared but the + * caller may already be controlling of the CRYPTO_LOCK_ENGINE lock. + */ +int engine_unlocked_init(ENGINE *e); +int engine_unlocked_finish(ENGINE *e, int unlock_for_handlers); +int engine_free_util(ENGINE *e, int locked); + +/* + * This function will reset all "set"able values in an ENGINE to NULL. This + * won't touch reference counts or ex_data, but is equivalent to calling all + * the ENGINE_set_***() functions with a NULL value. + */ +void engine_set_all_null(ENGINE *e); + +/* + * NB: Bitwise OR-able values for the "flags" variable in ENGINE are now + * exposed in engine.h. + */ + +/* Free up dynamically allocated public key methods associated with ENGINE */ + +void engine_pkey_meths_free(ENGINE *e); +void engine_pkey_asn1_meths_free(ENGINE *e); + +/* + * This is a structure for storing implementations of various crypto + * algorithms and functions. + */ +struct engine_st { + const char *id; + const char *name; + const RSA_METHOD *rsa_meth; + const DSA_METHOD *dsa_meth; + const DH_METHOD *dh_meth; + const ECDH_METHOD *ecdh_meth; + const ECDSA_METHOD *ecdsa_meth; + const RAND_METHOD *rand_meth; + const STORE_METHOD *store_meth; + /* Cipher handling is via this callback */ + ENGINE_CIPHERS_PTR ciphers; + /* Digest handling is via this callback */ + ENGINE_DIGESTS_PTR digests; + /* Public key handling via this callback */ + ENGINE_PKEY_METHS_PTR pkey_meths; + /* ASN1 public key handling via this callback */ + ENGINE_PKEY_ASN1_METHS_PTR pkey_asn1_meths; + ENGINE_GEN_INT_FUNC_PTR destroy; + ENGINE_GEN_INT_FUNC_PTR init; + ENGINE_GEN_INT_FUNC_PTR finish; + ENGINE_CTRL_FUNC_PTR ctrl; + ENGINE_LOAD_KEY_PTR load_privkey; + ENGINE_LOAD_KEY_PTR load_pubkey; + ENGINE_SSL_CLIENT_CERT_PTR load_ssl_client_cert; + const ENGINE_CMD_DEFN *cmd_defns; + int flags; + /* reference count on the structure itself */ + int struct_ref; + /* + * reference count on usability of the engine type. NB: This controls the + * loading and initialisation of any functionlity required by this + * engine, whereas the previous count is simply to cope with + * (de)allocation of this structure. Hence, running_ref <= struct_ref at + * all times. + */ + int funct_ref; + /* A place to store per-ENGINE data */ + CRYPTO_EX_DATA ex_data; + /* Used to maintain the linked-list of engines. */ + struct engine_st *prev; + struct engine_st *next; +}; + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_ENGINE_INT_H */ diff --git a/libs/openssl/crypto/engine/eng_lib.c b/libs/openssl/crypto/engine/eng_lib.c new file mode 100644 index 00000000..dc2abd28 --- /dev/null +++ b/libs/openssl/crypto/engine/eng_lib.c @@ -0,0 +1,347 @@ +/* crypto/engine/eng_lib.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" +#include + +/* The "new"/"free" stuff first */ + +ENGINE *ENGINE_new(void) +{ + ENGINE *ret; + + ret = (ENGINE *)OPENSSL_malloc(sizeof(ENGINE)); + if (ret == NULL) { + ENGINEerr(ENGINE_F_ENGINE_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + memset(ret, 0, sizeof(ENGINE)); + ret->struct_ref = 1; + engine_ref_debug(ret, 0, 1) + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_ENGINE, ret, &ret->ex_data); + return ret; +} + +/* + * Placed here (close proximity to ENGINE_new) so that modifications to the + * elements of the ENGINE structure are more likely to be caught and changed + * here. + */ +void engine_set_all_null(ENGINE *e) +{ + e->id = NULL; + e->name = NULL; + e->rsa_meth = NULL; + e->dsa_meth = NULL; + e->dh_meth = NULL; + e->rand_meth = NULL; + e->store_meth = NULL; + e->ciphers = NULL; + e->digests = NULL; + e->destroy = NULL; + e->init = NULL; + e->finish = NULL; + e->ctrl = NULL; + e->load_privkey = NULL; + e->load_pubkey = NULL; + e->cmd_defns = NULL; + e->flags = 0; +} + +int engine_free_util(ENGINE *e, int locked) +{ + int i; + + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_FREE_UTIL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (locked) + i = CRYPTO_add(&e->struct_ref, -1, CRYPTO_LOCK_ENGINE); + else + i = --e->struct_ref; + engine_ref_debug(e, 0, -1) + if (i > 0) + return 1; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "ENGINE_free, bad structural reference count\n"); + abort(); + } +#endif + /* Free up any dynamically allocated public key methods */ + engine_pkey_meths_free(e); + engine_pkey_asn1_meths_free(e); + /* + * Give the ENGINE a chance to do any structural cleanup corresponding to + * allocation it did in its constructor (eg. unload error strings) + */ + if (e->destroy) + e->destroy(e); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_ENGINE, e, &e->ex_data); + OPENSSL_free(e); + return 1; +} + +int ENGINE_free(ENGINE *e) +{ + return engine_free_util(e, 1); +} + +/* Cleanup stuff */ + +/* + * ENGINE_cleanup() is coded such that anything that does work that will need + * cleanup can register a "cleanup" callback here. That way we don't get + * linker bloat by referring to all *possible* cleanups, but any linker bloat + * into code "X" will cause X's cleanup function to end up here. + */ +static STACK_OF(ENGINE_CLEANUP_ITEM) *cleanup_stack = NULL; +static int int_cleanup_check(int create) +{ + if (cleanup_stack) + return 1; + if (!create) + return 0; + cleanup_stack = sk_ENGINE_CLEANUP_ITEM_new_null(); + return (cleanup_stack ? 1 : 0); +} + +static ENGINE_CLEANUP_ITEM *int_cleanup_item(ENGINE_CLEANUP_CB *cb) +{ + ENGINE_CLEANUP_ITEM *item = OPENSSL_malloc(sizeof(ENGINE_CLEANUP_ITEM)); + if (!item) + return NULL; + item->cb = cb; + return item; +} + +void engine_cleanup_add_first(ENGINE_CLEANUP_CB *cb) +{ + ENGINE_CLEANUP_ITEM *item; + if (!int_cleanup_check(1)) + return; + item = int_cleanup_item(cb); + if (item) + sk_ENGINE_CLEANUP_ITEM_insert(cleanup_stack, item, 0); +} + +void engine_cleanup_add_last(ENGINE_CLEANUP_CB *cb) +{ + ENGINE_CLEANUP_ITEM *item; + if (!int_cleanup_check(1)) + return; + item = int_cleanup_item(cb); + if (item) + sk_ENGINE_CLEANUP_ITEM_push(cleanup_stack, item); +} + +/* The API function that performs all cleanup */ +static void engine_cleanup_cb_free(ENGINE_CLEANUP_ITEM *item) +{ + (*(item->cb)) (); + OPENSSL_free(item); +} + +void ENGINE_cleanup(void) +{ + if (int_cleanup_check(0)) { + sk_ENGINE_CLEANUP_ITEM_pop_free(cleanup_stack, + engine_cleanup_cb_free); + cleanup_stack = NULL; + } + /* + * FIXME: This should be handled (somehow) through RAND, eg. by it + * registering a cleanup callback. + */ + RAND_set_rand_method(NULL); +} + +/* Now the "ex_data" support */ + +int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_ENGINE, argl, argp, + new_func, dup_func, free_func); +} + +int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&e->ex_data, idx, arg)); +} + +void *ENGINE_get_ex_data(const ENGINE *e, int idx) +{ + return (CRYPTO_get_ex_data(&e->ex_data, idx)); +} + +/* + * Functions to get/set an ENGINE's elements - mainly to avoid exposing the + * ENGINE structure itself. + */ + +int ENGINE_set_id(ENGINE *e, const char *id) +{ + if (id == NULL) { + ENGINEerr(ENGINE_F_ENGINE_SET_ID, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + e->id = id; + return 1; +} + +int ENGINE_set_name(ENGINE *e, const char *name) +{ + if (name == NULL) { + ENGINEerr(ENGINE_F_ENGINE_SET_NAME, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + e->name = name; + return 1; +} + +int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f) +{ + e->destroy = destroy_f; + return 1; +} + +int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f) +{ + e->init = init_f; + return 1; +} + +int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f) +{ + e->finish = finish_f; + return 1; +} + +int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f) +{ + e->ctrl = ctrl_f; + return 1; +} + +int ENGINE_set_flags(ENGINE *e, int flags) +{ + e->flags = flags; + return 1; +} + +int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns) +{ + e->cmd_defns = defns; + return 1; +} + +const char *ENGINE_get_id(const ENGINE *e) +{ + return e->id; +} + +const char *ENGINE_get_name(const ENGINE *e) +{ + return e->name; +} + +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e) +{ + return e->destroy; +} + +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e) +{ + return e->init; +} + +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e) +{ + return e->finish; +} + +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e) +{ + return e->ctrl; +} + +int ENGINE_get_flags(const ENGINE *e) +{ + return e->flags; +} + +const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e) +{ + return e->cmd_defns; +} + +/* + * eng_lib.o is pretty much linked into anything that touches ENGINE already, + * so put the "static_state" hack here. + */ + +static int internal_static_hack = 0; + +void *ENGINE_get_static_state(void) +{ + return &internal_static_hack; +} diff --git a/libs/openssl/crypto/engine/eng_list.c b/libs/openssl/crypto/engine/eng_list.c new file mode 100644 index 00000000..83c95d56 --- /dev/null +++ b/libs/openssl/crypto/engine/eng_list.c @@ -0,0 +1,405 @@ +/* crypto/engine/eng_list.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include "eng_int.h" + +/* + * The linked-list of pointers to engine types. engine_list_head incorporates + * an implicit structural reference but engine_list_tail does not - the + * latter is a computational niceity and only points to something that is + * already pointed to by its predecessor in the list (or engine_list_head + * itself). In the same way, the use of the "prev" pointer in each ENGINE is + * to save excessive list iteration, it doesn't correspond to an extra + * structural reference. Hence, engine_list_head, and each non-null "next" + * pointer account for the list itself assuming exactly 1 structural + * reference on each list member. + */ +static ENGINE *engine_list_head = NULL; +static ENGINE *engine_list_tail = NULL; + +/* + * This cleanup function is only needed internally. If it should be called, + * we register it with the "ENGINE_cleanup()" stack to be called during + * cleanup. + */ + +static void engine_list_cleanup(void) +{ + ENGINE *iterator = engine_list_head; + + while (iterator != NULL) { + ENGINE_remove(iterator); + iterator = engine_list_head; + } + return; +} + +/* + * These static functions starting with a lower case "engine_" always take + * place when CRYPTO_LOCK_ENGINE has been locked up. + */ +static int engine_list_add(ENGINE *e) +{ + int conflict = 0; + ENGINE *iterator = NULL; + + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + iterator = engine_list_head; + while (iterator && !conflict) { + conflict = (strcmp(iterator->id, e->id) == 0); + iterator = iterator->next; + } + if (conflict) { + ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_CONFLICTING_ENGINE_ID); + return 0; + } + if (engine_list_head == NULL) { + /* We are adding to an empty list. */ + if (engine_list_tail) { + ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_INTERNAL_LIST_ERROR); + return 0; + } + engine_list_head = e; + e->prev = NULL; + /* + * The first time the list allocates, we should register the cleanup. + */ + engine_cleanup_add_last(engine_list_cleanup); + } else { + /* We are adding to the tail of an existing list. */ + if ((engine_list_tail == NULL) || (engine_list_tail->next != NULL)) { + ENGINEerr(ENGINE_F_ENGINE_LIST_ADD, ENGINE_R_INTERNAL_LIST_ERROR); + return 0; + } + engine_list_tail->next = e; + e->prev = engine_list_tail; + } + /* + * Having the engine in the list assumes a structural reference. + */ + e->struct_ref++; + engine_ref_debug(e, 0, 1) + /* However it came to be, e is the last item in the list. */ + engine_list_tail = e; + e->next = NULL; + return 1; +} + +static int engine_list_remove(ENGINE *e) +{ + ENGINE *iterator; + + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + /* We need to check that e is in our linked list! */ + iterator = engine_list_head; + while (iterator && (iterator != e)) + iterator = iterator->next; + if (iterator == NULL) { + ENGINEerr(ENGINE_F_ENGINE_LIST_REMOVE, + ENGINE_R_ENGINE_IS_NOT_IN_LIST); + return 0; + } + /* un-link e from the chain. */ + if (e->next) + e->next->prev = e->prev; + if (e->prev) + e->prev->next = e->next; + /* Correct our head/tail if necessary. */ + if (engine_list_head == e) + engine_list_head = e->next; + if (engine_list_tail == e) + engine_list_tail = e->prev; + engine_free_util(e, 0); + return 1; +} + +/* Get the first/last "ENGINE" type available. */ +ENGINE *ENGINE_get_first(void) +{ + ENGINE *ret; + + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ret = engine_list_head; + if (ret) { + ret->struct_ref++; + engine_ref_debug(ret, 0, 1) + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return ret; +} + +ENGINE *ENGINE_get_last(void) +{ + ENGINE *ret; + + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ret = engine_list_tail; + if (ret) { + ret->struct_ref++; + engine_ref_debug(ret, 0, 1) + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return ret; +} + +/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ +ENGINE *ENGINE_get_next(ENGINE *e) +{ + ENGINE *ret = NULL; + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_GET_NEXT, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ret = e->next; + if (ret) { + /* Return a valid structural refernce to the next ENGINE */ + ret->struct_ref++; + engine_ref_debug(ret, 0, 1) + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* Release the structural reference to the previous ENGINE */ + ENGINE_free(e); + return ret; +} + +ENGINE *ENGINE_get_prev(ENGINE *e) +{ + ENGINE *ret = NULL; + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_GET_PREV, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + ret = e->prev; + if (ret) { + /* Return a valid structural reference to the next ENGINE */ + ret->struct_ref++; + engine_ref_debug(ret, 0, 1) + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* Release the structural reference to the previous ENGINE */ + ENGINE_free(e); + return ret; +} + +/* Add another "ENGINE" type into the list. */ +int ENGINE_add(ENGINE *e) +{ + int to_return = 1; + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_ADD, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if ((e->id == NULL) || (e->name == NULL)) { + ENGINEerr(ENGINE_F_ENGINE_ADD, ENGINE_R_ID_OR_NAME_MISSING); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (!engine_list_add(e)) { + ENGINEerr(ENGINE_F_ENGINE_ADD, ENGINE_R_INTERNAL_LIST_ERROR); + to_return = 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return to_return; +} + +/* Remove an existing "ENGINE" type from the array. */ +int ENGINE_remove(ENGINE *e) +{ + int to_return = 1; + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_REMOVE, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (!engine_list_remove(e)) { + ENGINEerr(ENGINE_F_ENGINE_REMOVE, ENGINE_R_INTERNAL_LIST_ERROR); + to_return = 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return to_return; +} + +static void engine_cpy(ENGINE *dest, const ENGINE *src) +{ + dest->id = src->id; + dest->name = src->name; +#ifndef OPENSSL_NO_RSA + dest->rsa_meth = src->rsa_meth; +#endif +#ifndef OPENSSL_NO_DSA + dest->dsa_meth = src->dsa_meth; +#endif +#ifndef OPENSSL_NO_DH + dest->dh_meth = src->dh_meth; +#endif +#ifndef OPENSSL_NO_ECDH + dest->ecdh_meth = src->ecdh_meth; +#endif +#ifndef OPENSSL_NO_ECDSA + dest->ecdsa_meth = src->ecdsa_meth; +#endif + dest->rand_meth = src->rand_meth; + dest->store_meth = src->store_meth; + dest->ciphers = src->ciphers; + dest->digests = src->digests; + dest->pkey_meths = src->pkey_meths; + dest->destroy = src->destroy; + dest->init = src->init; + dest->finish = src->finish; + dest->ctrl = src->ctrl; + dest->load_privkey = src->load_privkey; + dest->load_pubkey = src->load_pubkey; + dest->cmd_defns = src->cmd_defns; + dest->flags = src->flags; +} + +ENGINE *ENGINE_by_id(const char *id) +{ + ENGINE *iterator; + char *load_dir = NULL; + if (id == NULL) { + ENGINEerr(ENGINE_F_ENGINE_BY_ID, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + iterator = engine_list_head; + while (iterator && (strcmp(id, iterator->id) != 0)) + iterator = iterator->next; + if (iterator) { + /* + * We need to return a structural reference. If this is an ENGINE + * type that returns copies, make a duplicate - otherwise increment + * the existing ENGINE's reference count. + */ + if (iterator->flags & ENGINE_FLAGS_BY_ID_COPY) { + ENGINE *cp = ENGINE_new(); + if (!cp) + iterator = NULL; + else { + engine_cpy(cp, iterator); + iterator = cp; + } + } else { + iterator->struct_ref++; + engine_ref_debug(iterator, 0, 1) + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); +#if 0 + if (iterator == NULL) { + ENGINEerr(ENGINE_F_ENGINE_BY_ID, ENGINE_R_NO_SUCH_ENGINE); + ERR_add_error_data(2, "id=", id); + } + return iterator; +#else + /* EEK! Experimental code starts */ + if (iterator) + return iterator; + /* + * Prevent infinite recusrion if we're looking for the dynamic engine. + */ + if (strcmp(id, "dynamic")) { +# ifdef OPENSSL_SYS_VMS + if ((load_dir = getenv("OPENSSL_ENGINES")) == 0) + load_dir = "SSLROOT:[ENGINES]"; +# else + if ((load_dir = getenv("OPENSSL_ENGINES")) == 0) + load_dir = ENGINESDIR; +# endif + iterator = ENGINE_by_id("dynamic"); + if (!iterator || !ENGINE_ctrl_cmd_string(iterator, "ID", id, 0) || + !ENGINE_ctrl_cmd_string(iterator, "DIR_LOAD", "2", 0) || + !ENGINE_ctrl_cmd_string(iterator, "DIR_ADD", + load_dir, 0) || + !ENGINE_ctrl_cmd_string(iterator, "LIST_ADD", "1", 0) || + !ENGINE_ctrl_cmd_string(iterator, "LOAD", NULL, 0)) + goto notfound; + return iterator; + } + notfound: + ENGINE_free(iterator); + ENGINEerr(ENGINE_F_ENGINE_BY_ID, ENGINE_R_NO_SUCH_ENGINE); + ERR_add_error_data(2, "id=", id); + return NULL; + /* EEK! Experimental code ends */ +#endif +} + +int ENGINE_up_ref(ENGINE *e) +{ + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_UP_REF, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_add(&e->struct_ref, 1, CRYPTO_LOCK_ENGINE); + return 1; +} diff --git a/libs/openssl/crypto/engine/eng_openssl.c b/libs/openssl/crypto/engine/eng_openssl.c new file mode 100644 index 00000000..34b00295 --- /dev/null +++ b/libs/openssl/crypto/engine/eng_openssl.c @@ -0,0 +1,402 @@ +/* crypto/engine/eng_openssl.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#ifndef OPENSSL_NO_DSA +# include +#endif +#ifndef OPENSSL_NO_DH +# include +#endif + +/* + * This testing gunk is implemented (and explained) lower down. It also + * assumes the application explicitly calls "ENGINE_load_openssl()" because + * this is no longer automatic in ENGINE_load_builtin_engines(). + */ +#define TEST_ENG_OPENSSL_RC4 +#define TEST_ENG_OPENSSL_PKEY +/* #define TEST_ENG_OPENSSL_RC4_OTHERS */ +#define TEST_ENG_OPENSSL_RC4_P_INIT +/* #define TEST_ENG_OPENSSL_RC4_P_CIPHER */ +#define TEST_ENG_OPENSSL_SHA +/* #define TEST_ENG_OPENSSL_SHA_OTHERS */ +/* #define TEST_ENG_OPENSSL_SHA_P_INIT */ +/* #define TEST_ENG_OPENSSL_SHA_P_UPDATE */ +/* #define TEST_ENG_OPENSSL_SHA_P_FINAL */ + +/* Now check what of those algorithms are actually enabled */ +#ifdef OPENSSL_NO_RC4 +# undef TEST_ENG_OPENSSL_RC4 +# undef TEST_ENG_OPENSSL_RC4_OTHERS +# undef TEST_ENG_OPENSSL_RC4_P_INIT +# undef TEST_ENG_OPENSSL_RC4_P_CIPHER +#endif +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0) || defined(OPENSSL_NO_SHA1) +# undef TEST_ENG_OPENSSL_SHA +# undef TEST_ENG_OPENSSL_SHA_OTHERS +# undef TEST_ENG_OPENSSL_SHA_P_INIT +# undef TEST_ENG_OPENSSL_SHA_P_UPDATE +# undef TEST_ENG_OPENSSL_SHA_P_FINAL +#endif + +#ifdef TEST_ENG_OPENSSL_RC4 +static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid); +#endif +#ifdef TEST_ENG_OPENSSL_SHA +static int openssl_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid); +#endif + +#ifdef TEST_ENG_OPENSSL_PKEY +static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, + void *callback_data); +#endif + +/* The constants used when creating the ENGINE */ +static const char *engine_openssl_id = "openssl"; +static const char *engine_openssl_name = "Software engine support"; + +/* + * This internal function is used by ENGINE_openssl() and possibly by the + * "dynamic" ENGINE support too + */ +static int bind_helper(ENGINE *e) +{ + if (!ENGINE_set_id(e, engine_openssl_id) + || !ENGINE_set_name(e, engine_openssl_name) +#ifndef TEST_ENG_OPENSSL_NO_ALGORITHMS +# ifndef OPENSSL_NO_RSA + || !ENGINE_set_RSA(e, RSA_get_default_method()) +# endif +# ifndef OPENSSL_NO_DSA + || !ENGINE_set_DSA(e, DSA_get_default_method()) +# endif +# ifndef OPENSSL_NO_ECDH + || !ENGINE_set_ECDH(e, ECDH_OpenSSL()) +# endif +# ifndef OPENSSL_NO_ECDSA + || !ENGINE_set_ECDSA(e, ECDSA_OpenSSL()) +# endif +# ifndef OPENSSL_NO_DH + || !ENGINE_set_DH(e, DH_get_default_method()) +# endif + || !ENGINE_set_RAND(e, RAND_SSLeay()) +# ifdef TEST_ENG_OPENSSL_RC4 + || !ENGINE_set_ciphers(e, openssl_ciphers) +# endif +# ifdef TEST_ENG_OPENSSL_SHA + || !ENGINE_set_digests(e, openssl_digests) +# endif +#endif +#ifdef TEST_ENG_OPENSSL_PKEY + || !ENGINE_set_load_privkey_function(e, openssl_load_privkey) +#endif + ) + return 0; + /* + * If we add errors to this ENGINE, ensure the error handling is setup + * here + */ + /* openssl_load_error_strings(); */ + return 1; +} + +static ENGINE *engine_openssl(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_helper(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_openssl(void) +{ + ENGINE *toadd = engine_openssl(); + if (!toadd) + return; + ENGINE_add(toadd); + /* + * If the "add" worked, it gets a structural reference. So either way, we + * release our just-created reference. + */ + ENGINE_free(toadd); + ERR_clear_error(); +} + +/* + * This stuff is needed if this ENGINE is being compiled into a + * self-contained shared-library. + */ +#ifdef ENGINE_DYNAMIC_SUPPORT +static int bind_fn(ENGINE *e, const char *id) +{ + if (id && (strcmp(id, engine_openssl_id) != 0)) + return 0; + if (!bind_helper(e)) + return 0; + return 1; +} + +IMPLEMENT_DYNAMIC_CHECK_FN() + IMPLEMENT_DYNAMIC_BIND_FN(bind_fn) +#endif /* ENGINE_DYNAMIC_SUPPORT */ +#ifdef TEST_ENG_OPENSSL_RC4 +/*- + * This section of code compiles an "alternative implementation" of two modes of + * RC4 into this ENGINE. The result is that EVP_CIPHER operation for "rc4" + * should under normal circumstances go via this support rather than the default + * EVP support. There are other symbols to tweak the testing; + * TEST_ENC_OPENSSL_RC4_OTHERS - print a one line message to stderr each time + * we're asked for a cipher we don't support (should not happen). + * TEST_ENG_OPENSSL_RC4_P_INIT - print a one line message to stderr each time + * the "init_key" handler is called. + * TEST_ENG_OPENSSL_RC4_P_CIPHER - ditto for the "cipher" handler. + */ +# include +# define TEST_RC4_KEY_SIZE 16 +static int test_cipher_nids[] = { NID_rc4, NID_rc4_40 }; + +static int test_cipher_nids_number = 2; +typedef struct { + unsigned char key[TEST_RC4_KEY_SIZE]; + RC4_KEY ks; +} TEST_RC4_KEY; +# define test(ctx) ((TEST_RC4_KEY *)(ctx)->cipher_data) +static int test_rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ +# ifdef TEST_ENG_OPENSSL_RC4_P_INIT + fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_init_key() called\n"); +# endif + memcpy(&test(ctx)->key[0], key, EVP_CIPHER_CTX_key_length(ctx)); + RC4_set_key(&test(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), + test(ctx)->key); + return 1; +} + +static int test_rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ +# ifdef TEST_ENG_OPENSSL_RC4_P_CIPHER + fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) test_cipher() called\n"); +# endif + RC4(&test(ctx)->ks, inl, in, out); + return 1; +} + +static const EVP_CIPHER test_r4_cipher = { + NID_rc4, + 1, TEST_RC4_KEY_SIZE, 0, + EVP_CIPH_VARIABLE_LENGTH, + test_rc4_init_key, + test_rc4_cipher, + NULL, + sizeof(TEST_RC4_KEY), + NULL, + NULL, + NULL, + NULL +}; + +static const EVP_CIPHER test_r4_40_cipher = { + NID_rc4_40, + 1, 5 /* 40 bit */ , 0, + EVP_CIPH_VARIABLE_LENGTH, + test_rc4_init_key, + test_rc4_cipher, + NULL, + sizeof(TEST_RC4_KEY), + NULL, + NULL, + NULL, + NULL +}; + +static int openssl_ciphers(ENGINE *e, const EVP_CIPHER **cipher, + const int **nids, int nid) +{ + if (!cipher) { + /* We are returning a list of supported nids */ + *nids = test_cipher_nids; + return test_cipher_nids_number; + } + /* We are being asked for a specific cipher */ + if (nid == NID_rc4) + *cipher = &test_r4_cipher; + else if (nid == NID_rc4_40) + *cipher = &test_r4_40_cipher; + else { +# ifdef TEST_ENG_OPENSSL_RC4_OTHERS + fprintf(stderr, "(TEST_ENG_OPENSSL_RC4) returning NULL for " + "nid %d\n", nid); +# endif + *cipher = NULL; + return 0; + } + return 1; +} +#endif + +#ifdef TEST_ENG_OPENSSL_SHA +/* Much the same sort of comment as for TEST_ENG_OPENSSL_RC4 */ +# include +static int test_digest_nids[] = { NID_sha1 }; + +static int test_digest_nids_number = 1; +static int test_sha1_init(EVP_MD_CTX *ctx) +{ +# ifdef TEST_ENG_OPENSSL_SHA_P_INIT + fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_init() called\n"); +# endif + return SHA1_Init(ctx->md_data); +} + +static int test_sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ +# ifdef TEST_ENG_OPENSSL_SHA_P_UPDATE + fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_update() called\n"); +# endif + return SHA1_Update(ctx->md_data, data, count); +} + +static int test_sha1_final(EVP_MD_CTX *ctx, unsigned char *md) +{ +# ifdef TEST_ENG_OPENSSL_SHA_P_FINAL + fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) test_sha1_final() called\n"); +# endif + return SHA1_Final(md, ctx->md_data); +} + +static const EVP_MD test_sha_md = { + NID_sha1, + NID_sha1WithRSAEncryption, + SHA_DIGEST_LENGTH, + 0, + test_sha1_init, + test_sha1_update, + test_sha1_final, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA_CTX), +}; + +static int openssl_digests(ENGINE *e, const EVP_MD **digest, + const int **nids, int nid) +{ + if (!digest) { + /* We are returning a list of supported nids */ + *nids = test_digest_nids; + return test_digest_nids_number; + } + /* We are being asked for a specific digest */ + if (nid == NID_sha1) + *digest = &test_sha_md; + else { +# ifdef TEST_ENG_OPENSSL_SHA_OTHERS + fprintf(stderr, "(TEST_ENG_OPENSSL_SHA) returning NULL for " + "nid %d\n", nid); +# endif + *digest = NULL; + return 0; + } + return 1; +} +#endif + +#ifdef TEST_ENG_OPENSSL_PKEY +static EVP_PKEY *openssl_load_privkey(ENGINE *eng, const char *key_id, + UI_METHOD *ui_method, + void *callback_data) +{ + BIO *in; + EVP_PKEY *key; + fprintf(stderr, "(TEST_ENG_OPENSSL_PKEY)Loading Private key %s\n", + key_id); + in = BIO_new_file(key_id, "r"); + if (!in) + return NULL; + key = PEM_read_bio_PrivateKey(in, NULL, 0, NULL); + BIO_free(in); + return key; +} +#endif diff --git a/libs/openssl/crypto/engine/eng_pkey.c b/libs/openssl/crypto/engine/eng_pkey.c new file mode 100644 index 00000000..23580d9e --- /dev/null +++ b/libs/openssl/crypto/engine/eng_pkey.c @@ -0,0 +1,186 @@ +/* crypto/engine/eng_pkey.c */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* Basic get/set stuff */ + +int ENGINE_set_load_privkey_function(ENGINE *e, + ENGINE_LOAD_KEY_PTR loadpriv_f) +{ + e->load_privkey = loadpriv_f; + return 1; +} + +int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f) +{ + e->load_pubkey = loadpub_f; + return 1; +} + +int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, + ENGINE_SSL_CLIENT_CERT_PTR + loadssl_f) +{ + e->load_ssl_client_cert = loadssl_f; + return 1; +} + +ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e) +{ + return e->load_privkey; +} + +ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e) +{ + return e->load_pubkey; +} + +ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE + *e) +{ + return e->load_ssl_client_cert; +} + +/* API functions to load public/private keys */ + +EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data) +{ + EVP_PKEY *pkey; + + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (e->funct_ref == 0) { + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, ENGINE_R_NOT_INITIALISED); + return 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + if (!e->load_privkey) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, + ENGINE_R_NO_LOAD_FUNCTION); + return 0; + } + pkey = e->load_privkey(e, key_id, ui_method, callback_data); + if (!pkey) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PRIVATE_KEY, + ENGINE_R_FAILED_LOADING_PRIVATE_KEY); + return 0; + } + return pkey; +} + +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data) +{ + EVP_PKEY *pkey; + + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (e->funct_ref == 0) { + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, ENGINE_R_NOT_INITIALISED); + return 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + if (!e->load_pubkey) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, ENGINE_R_NO_LOAD_FUNCTION); + return 0; + } + pkey = e->load_pubkey(e, key_id, ui_method, callback_data); + if (!pkey) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_PUBLIC_KEY, + ENGINE_R_FAILED_LOADING_PUBLIC_KEY); + return 0; + } + return pkey; +} + +int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, + EVP_PKEY **ppkey, STACK_OF(X509) **pother, + UI_METHOD *ui_method, void *callback_data) +{ + + if (e == NULL) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (e->funct_ref == 0) { + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, + ENGINE_R_NOT_INITIALISED); + return 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + if (!e->load_ssl_client_cert) { + ENGINEerr(ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT, + ENGINE_R_NO_LOAD_FUNCTION); + return 0; + } + return e->load_ssl_client_cert(e, s, ca_dn, pcert, ppkey, pother, + ui_method, callback_data); +} diff --git a/libs/openssl/crypto/engine/eng_rdrand.c b/libs/openssl/crypto/engine/eng_rdrand.c new file mode 100644 index 00000000..9316d6fe --- /dev/null +++ b/libs/openssl/crypto/engine/eng_rdrand.c @@ -0,0 +1,149 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include +#include +#include +#include +#include + +#if (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ) + +size_t OPENSSL_ia32_rdrand(void); + +static int get_random_bytes(unsigned char *buf, int num) +{ + size_t rnd; + + while (num >= (int)sizeof(size_t)) { + if ((rnd = OPENSSL_ia32_rdrand()) == 0) + return 0; + + *((size_t *)buf) = rnd; + buf += sizeof(size_t); + num -= sizeof(size_t); + } + if (num) { + if ((rnd = OPENSSL_ia32_rdrand()) == 0) + return 0; + + memcpy(buf, &rnd, num); + } + + return 1; +} + +static int random_status(void) +{ + return 1; +} + +static RAND_METHOD rdrand_meth = { + NULL, /* seed */ + get_random_bytes, + NULL, /* cleanup */ + NULL, /* add */ + get_random_bytes, + random_status, +}; + +static int rdrand_init(ENGINE *e) +{ + return 1; +} + +static const char *engine_e_rdrand_id = "rdrand"; +static const char *engine_e_rdrand_name = "Intel RDRAND engine"; + +static int bind_helper(ENGINE *e) +{ + if (!ENGINE_set_id(e, engine_e_rdrand_id) || + !ENGINE_set_name(e, engine_e_rdrand_name) || + !ENGINE_set_flags(e, ENGINE_FLAGS_NO_REGISTER_ALL) || + !ENGINE_set_init_function(e, rdrand_init) || + !ENGINE_set_RAND(e, &rdrand_meth)) + return 0; + + return 1; +} + +static ENGINE *ENGINE_rdrand(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_helper(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +void ENGINE_load_rdrand(void) +{ + extern unsigned int OPENSSL_ia32cap_P[]; + + if (OPENSSL_ia32cap_P[1] & (1 << (62 - 32))) { + ENGINE *toadd = ENGINE_rdrand(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); + } +} +#else +void ENGINE_load_rdrand(void) +{ +} +#endif diff --git a/libs/openssl/crypto/engine/eng_rsax.c b/libs/openssl/crypto/engine/eng_rsax.c new file mode 100644 index 00000000..86ee9d89 --- /dev/null +++ b/libs/openssl/crypto/engine/eng_rsax.c @@ -0,0 +1,701 @@ +/* crypto/engine/eng_rsax.c */ +/* Copyright (c) 2010-2010 Intel Corp. + * Author: Vinodh.Gopal@intel.com + * Jim Guilford + * Erdinc.Ozturk@intel.com + * Maxim.Perminov@intel.com + * Ying.Huang@intel.com + * + * More information about algorithm used can be found at: + * http://www.cse.buffalo.edu/srds2009/escs2009_submission_Gopal.pdf + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + */ + +#include + +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#include +#include + +/* RSAX is available **ONLY* on x86_64 CPUs */ +#undef COMPILE_RSAX + +#if (defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined (_M_X64)) && !defined(OPENSSL_NO_ASM) +# define COMPILE_RSAX +static ENGINE *ENGINE_rsax(void); +#endif + +void ENGINE_load_rsax(void) +{ +/* On non-x86 CPUs it just returns. */ +#ifdef COMPILE_RSAX + ENGINE *toadd = ENGINE_rsax(); + if (!toadd) + return; + ENGINE_add(toadd); + ENGINE_free(toadd); + ERR_clear_error(); +#endif +} + +#ifdef COMPILE_RSAX +# define E_RSAX_LIB_NAME "rsax engine" + +static int e_rsax_destroy(ENGINE *e); +static int e_rsax_init(ENGINE *e); +static int e_rsax_finish(ENGINE *e); +static int e_rsax_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); + +# ifndef OPENSSL_NO_RSA +/* RSA stuff */ +static int e_rsax_rsa_mod_exp(BIGNUM *r, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx); +static int e_rsax_rsa_finish(RSA *r); +# endif + +static const ENGINE_CMD_DEFN e_rsax_cmd_defns[] = { + {0, NULL, NULL, 0} +}; + +# ifndef OPENSSL_NO_RSA +/* Our internal RSA_METHOD that we provide pointers to */ +static RSA_METHOD e_rsax_rsa = { + "Intel RSA-X method", + NULL, + NULL, + NULL, + NULL, + e_rsax_rsa_mod_exp, + NULL, + NULL, + e_rsax_rsa_finish, + RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE, + NULL, + NULL, + NULL +}; +# endif + +/* Constants used when creating the ENGINE */ +static const char *engine_e_rsax_id = "rsax"; +static const char *engine_e_rsax_name = "RSAX engine support"; + +/* This internal function is used by ENGINE_rsax() */ +static int bind_helper(ENGINE *e) +{ +# ifndef OPENSSL_NO_RSA + const RSA_METHOD *meth1; +# endif + if (!ENGINE_set_id(e, engine_e_rsax_id) || + !ENGINE_set_name(e, engine_e_rsax_name) || +# ifndef OPENSSL_NO_RSA + !ENGINE_set_RSA(e, &e_rsax_rsa) || +# endif + !ENGINE_set_destroy_function(e, e_rsax_destroy) || + !ENGINE_set_init_function(e, e_rsax_init) || + !ENGINE_set_finish_function(e, e_rsax_finish) || + !ENGINE_set_ctrl_function(e, e_rsax_ctrl) || + !ENGINE_set_cmd_defns(e, e_rsax_cmd_defns)) + return 0; + +# ifndef OPENSSL_NO_RSA + meth1 = RSA_PKCS1_SSLeay(); + e_rsax_rsa.rsa_pub_enc = meth1->rsa_pub_enc; + e_rsax_rsa.rsa_pub_dec = meth1->rsa_pub_dec; + e_rsax_rsa.rsa_priv_enc = meth1->rsa_priv_enc; + e_rsax_rsa.rsa_priv_dec = meth1->rsa_priv_dec; + e_rsax_rsa.bn_mod_exp = meth1->bn_mod_exp; +# endif + return 1; +} + +static ENGINE *ENGINE_rsax(void) +{ + ENGINE *ret = ENGINE_new(); + if (!ret) + return NULL; + if (!bind_helper(ret)) { + ENGINE_free(ret); + return NULL; + } + return ret; +} + +# ifndef OPENSSL_NO_RSA +/* Used to attach our own key-data to an RSA structure */ +static int rsax_ex_data_idx = -1; +# endif + +static int e_rsax_destroy(ENGINE *e) +{ + return 1; +} + +/* (de)initialisation functions. */ +static int e_rsax_init(ENGINE *e) +{ +# ifndef OPENSSL_NO_RSA + if (rsax_ex_data_idx == -1) + rsax_ex_data_idx = RSA_get_ex_new_index(0, NULL, NULL, NULL, NULL); +# endif + if (rsax_ex_data_idx == -1) + return 0; + return 1; +} + +static int e_rsax_finish(ENGINE *e) +{ + return 1; +} + +static int e_rsax_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)) +{ + int to_return = 1; + + switch (cmd) { + /* The command isn't understood by this engine */ + default: + to_return = 0; + break; + } + + return to_return; +} + +# ifndef OPENSSL_NO_RSA + +# ifdef _WIN32 +typedef unsigned __int64 UINT64; +# else +typedef unsigned long long UINT64; +# endif +typedef unsigned short UINT16; + +/* + * Table t is interleaved in the following manner: The order in memory is + * t[0][0], t[0][1], ..., t[0][7], t[1][0], ... A particular 512-bit value is + * stored in t[][index] rather than the more normal t[index][]; i.e. the + * qwords of a particular entry in t are not adjacent in memory + */ + +/* Init BIGNUM b from the interleaved UINT64 array */ +static int interleaved_array_to_bn_512(BIGNUM *b, UINT64 *array); + +/* + * Extract array elements from BIGNUM b To set the whole array from b, call + * with n=8 + */ +static int bn_extract_to_array_512(const BIGNUM *b, unsigned int n, + UINT64 *array); + +struct mod_ctx_512 { + UINT64 t[8][8]; + UINT64 m[8]; + UINT64 m1[8]; /* 2^278 % m */ + UINT64 m2[8]; /* 2^640 % m */ + UINT64 k1[2]; /* (- 1/m) % 2^128 */ +}; + +static int mod_exp_pre_compute_data_512(UINT64 *m, struct mod_ctx_512 *data); + +void mod_exp_512(UINT64 *result, /* 512 bits, 8 qwords */ + UINT64 *g, /* 512 bits, 8 qwords */ + UINT64 *exp, /* 512 bits, 8 qwords */ + struct mod_ctx_512 *data); + +typedef struct st_e_rsax_mod_ctx { + UINT64 type; + union { + struct mod_ctx_512 b512; + } ctx; + +} E_RSAX_MOD_CTX; + +static E_RSAX_MOD_CTX *e_rsax_get_ctx(RSA *rsa, int idx, BIGNUM *m) +{ + E_RSAX_MOD_CTX *hptr; + + if (idx < 0 || idx > 2) + return NULL; + + hptr = RSA_get_ex_data(rsa, rsax_ex_data_idx); + if (!hptr) { + hptr = OPENSSL_malloc(3 * sizeof(E_RSAX_MOD_CTX)); + if (!hptr) + return NULL; + hptr[2].type = hptr[1].type = hptr[0].type = 0; + RSA_set_ex_data(rsa, rsax_ex_data_idx, hptr); + } + + if (hptr[idx].type == (UINT64)BN_num_bits(m)) + return hptr + idx; + + if (BN_num_bits(m) == 512) { + UINT64 _m[8]; + bn_extract_to_array_512(m, 8, _m); + memset(&hptr[idx].ctx.b512, 0, sizeof(struct mod_ctx_512)); + mod_exp_pre_compute_data_512(_m, &hptr[idx].ctx.b512); + } + + hptr[idx].type = BN_num_bits(m); + return hptr + idx; +} + +static int e_rsax_rsa_finish(RSA *rsa) +{ + E_RSAX_MOD_CTX *hptr = RSA_get_ex_data(rsa, rsax_ex_data_idx); + if (hptr) { + OPENSSL_free(hptr); + RSA_set_ex_data(rsa, rsax_ex_data_idx, NULL); + } + if (rsa->_method_mod_n) + BN_MONT_CTX_free(rsa->_method_mod_n); + if (rsa->_method_mod_p) + BN_MONT_CTX_free(rsa->_method_mod_p); + if (rsa->_method_mod_q) + BN_MONT_CTX_free(rsa->_method_mod_q); + return 1; +} + +static int e_rsax_bn_mod_exp(BIGNUM *r, const BIGNUM *g, const BIGNUM *e, + const BIGNUM *m, BN_CTX *ctx, + BN_MONT_CTX *in_mont, + E_RSAX_MOD_CTX *rsax_mod_ctx) +{ + if (rsax_mod_ctx && BN_get_flags(e, BN_FLG_CONSTTIME) != 0) { + if (BN_num_bits(m) == 512) { + UINT64 _r[8]; + UINT64 _g[8]; + UINT64 _e[8]; + + /* Init the arrays from the BIGNUMs */ + bn_extract_to_array_512(g, 8, _g); + bn_extract_to_array_512(e, 8, _e); + + mod_exp_512(_r, _g, _e, &rsax_mod_ctx->ctx.b512); + /* Return the result in the BIGNUM */ + interleaved_array_to_bn_512(r, _r); + return 1; + } + } + + return BN_mod_exp_mont(r, g, e, m, ctx, in_mont); +} + +/* + * Declares for the Intel CIAP 512-bit / CRT / 1024 bit RSA modular + * exponentiation routine precalculations and a structure to hold the + * necessary values. These files are meant to live in crypto/rsa/ in the + * target openssl. + */ + +/* + * Local method: extracts a piece from a BIGNUM, to fit it into + * an array. Call with n=8 to extract an entire 512-bit BIGNUM + */ +static int bn_extract_to_array_512(const BIGNUM *b, unsigned int n, + UINT64 *array) +{ + int i; + UINT64 tmp; + unsigned char bn_buff[64]; + memset(bn_buff, 0, 64); + if (BN_num_bytes(b) > 64) { + printf("Can't support this byte size\n"); + return 0; + } + if (BN_num_bytes(b) != 0) { + if (!BN_bn2bin(b, bn_buff + (64 - BN_num_bytes(b)))) { + printf("Error's in bn2bin\n"); + /* We have to error, here */ + return 0; + } + } + while (n-- > 0) { + array[n] = 0; + for (i = 7; i >= 0; i--) { + tmp = bn_buff[63 - (n * 8 + i)]; + array[n] |= tmp << (8 * i); + } + } + return 1; +} + +/* Init a 512-bit BIGNUM from the UINT64*_ (8 * 64) interleaved array */ +static int interleaved_array_to_bn_512(BIGNUM *b, UINT64 *array) +{ + unsigned char tmp[64]; + int n = 8; + int i; + while (n-- > 0) { + for (i = 7; i >= 0; i--) { + tmp[63 - (n * 8 + i)] = (unsigned char)(array[n] >> (8 * i)); + }} + BN_bin2bn(tmp, 64, b); + return 0; +} + +/* The main 512bit precompute call */ +static int mod_exp_pre_compute_data_512(UINT64 *m, struct mod_ctx_512 *data) +{ + BIGNUM two_768, two_640, two_128, two_512, tmp, _m, tmp2; + + /* We need a BN_CTX for the modulo functions */ + BN_CTX *ctx; + /* Some tmps */ + UINT64 _t[8]; + int i, j, ret = 0; + + /* Init _m with m */ + BN_init(&_m); + interleaved_array_to_bn_512(&_m, m); + memset(_t, 0, 64); + + /* Inits */ + BN_init(&two_768); + BN_init(&two_640); + BN_init(&two_128); + BN_init(&two_512); + BN_init(&tmp); + BN_init(&tmp2); + + /* Create our context */ + if ((ctx = BN_CTX_new()) == NULL) { + goto err; + } + BN_CTX_start(ctx); + + /* + * For production, if you care, these only need to be set once, + * and may be made constants. + */ + BN_lshift(&two_768, BN_value_one(), 768); + BN_lshift(&two_640, BN_value_one(), 640); + BN_lshift(&two_128, BN_value_one(), 128); + BN_lshift(&two_512, BN_value_one(), 512); + + if (0 == (m[7] & 0x8000000000000000)) { + goto err; + } + if (0 == (m[0] & 0x1)) { /* Odd modulus required for Mont */ + goto err; + } + + /* Precompute m1 */ + BN_mod(&tmp, &two_768, &_m, ctx); + if (!bn_extract_to_array_512(&tmp, 8, &data->m1[0])) { + goto err; + } + + /* Precompute m2 */ + BN_mod(&tmp, &two_640, &_m, ctx); + if (!bn_extract_to_array_512(&tmp, 8, &data->m2[0])) { + goto err; + } + + /* + * Precompute k1, a 128b number = ((-1)* m-1 ) mod 2128; k1 should + * be non-negative. + */ + BN_mod_inverse(&tmp, &_m, &two_128, ctx); + if (!BN_is_zero(&tmp)) { + BN_sub(&tmp, &two_128, &tmp); + } + if (!bn_extract_to_array_512(&tmp, 2, &data->k1[0])) { + goto err; + } + + /* Precompute t */ + for (i = 0; i < 8; i++) { + BN_zero(&tmp); + if (i & 1) { + BN_add(&tmp, &two_512, &tmp); + } + if (i & 2) { + BN_add(&tmp, &two_512, &tmp); + } + if (i & 4) { + BN_add(&tmp, &two_640, &tmp); + } + + BN_nnmod(&tmp2, &tmp, &_m, ctx); + if (!bn_extract_to_array_512(&tmp2, 8, _t)) { + goto err; + } + for (j = 0; j < 8; j++) + data->t[j][i] = _t[j]; + } + + /* Precompute m */ + for (i = 0; i < 8; i++) { + data->m[i] = m[i]; + } + + ret = 1; + + err: + /* Cleanup */ + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + BN_free(&two_768); + BN_free(&two_640); + BN_free(&two_128); + BN_free(&two_512); + BN_free(&tmp); + BN_free(&tmp2); + BN_free(&_m); + + return ret; +} + +static int e_rsax_rsa_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, + BN_CTX *ctx) +{ + BIGNUM *r1, *m1, *vrfy; + BIGNUM local_dmp1, local_dmq1, local_c, local_r1; + BIGNUM *dmp1, *dmq1, *c, *pr1; + int ret = 0; + + BN_CTX_start(ctx); + r1 = BN_CTX_get(ctx); + m1 = BN_CTX_get(ctx); + vrfy = BN_CTX_get(ctx); + + { + BIGNUM local_p, local_q; + BIGNUM *p = NULL, *q = NULL; + int error = 0; + + /* + * Make sure BN_mod_inverse in Montgomery intialization uses the + * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) + */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + BN_init(&local_p); + p = &local_p; + BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); + + BN_init(&local_q); + q = &local_q; + BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME); + } else { + p = rsa->p; + q = rsa->q; + } + + if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { + if (!BN_MONT_CTX_set_locked + (&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx)) + error = 1; + if (!BN_MONT_CTX_set_locked + (&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx)) + error = 1; + } + + /* clean up */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + BN_free(&local_p); + BN_free(&local_q); + } + if (error) + goto err; + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked + (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + goto err; + + /* compute I mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + c = &local_c; + BN_with_flags(c, I, BN_FLG_CONSTTIME); + if (!BN_mod(r1, c, rsa->q, ctx)) + goto err; + } else { + if (!BN_mod(r1, I, rsa->q, ctx)) + goto err; + } + + /* compute r1^dmq1 mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + dmq1 = &local_dmq1; + BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); + } else + dmq1 = rsa->dmq1; + + if (!e_rsax_bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, + rsa->_method_mod_q, e_rsax_get_ctx(rsa, 0, + rsa->q))) + goto err; + + /* compute I mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + c = &local_c; + BN_with_flags(c, I, BN_FLG_CONSTTIME); + if (!BN_mod(r1, c, rsa->p, ctx)) + goto err; + } else { + if (!BN_mod(r1, I, rsa->p, ctx)) + goto err; + } + + /* compute r1^dmp1 mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + dmp1 = &local_dmp1; + BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); + } else + dmp1 = rsa->dmp1; + + if (!e_rsax_bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, + rsa->_method_mod_p, e_rsax_get_ctx(rsa, 1, + rsa->p))) + goto err; + + if (!BN_sub(r0, r0, m1)) + goto err; + /* + * This will help stop the size of r0 increasing, which does affect the + * multiply if it optimised for a power of 2 size + */ + if (BN_is_negative(r0)) + if (!BN_add(r0, r0, rsa->p)) + goto err; + + if (!BN_mul(r1, r0, rsa->iqmp, ctx)) + goto err; + + /* Turn BN_FLG_CONSTTIME flag on before division operation */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + pr1 = &local_r1; + BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); + } else + pr1 = r1; + if (!BN_mod(r0, pr1, rsa->p, ctx)) + goto err; + + /* + * If p < q it is occasionally possible for the correction of adding 'p' + * if r0 is negative above to leave the result still negative. This can + * break the private key operations: the following second correction + * should *always* correct this rare occurrence. This will *never* happen + * with OpenSSL generated keys because they ensure p > q [steve] + */ + if (BN_is_negative(r0)) + if (!BN_add(r0, r0, rsa->p)) + goto err; + if (!BN_mul(r1, r0, rsa->q, ctx)) + goto err; + if (!BN_add(r0, r1, m1)) + goto err; + + if (rsa->e && rsa->n) { + if (!e_rsax_bn_mod_exp + (vrfy, r0, rsa->e, rsa->n, ctx, rsa->_method_mod_n, + e_rsax_get_ctx(rsa, 2, rsa->n))) + goto err; + + /* + * If 'I' was greater than (or equal to) rsa->n, the operation will + * be equivalent to using 'I mod n'. However, the result of the + * verify will *always* be less than 'n' so we don't check for + * absolute equality, just congruency. + */ + if (!BN_sub(vrfy, vrfy, I)) + goto err; + if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) + goto err; + if (BN_is_negative(vrfy)) + if (!BN_add(vrfy, vrfy, rsa->n)) + goto err; + if (!BN_is_zero(vrfy)) { + /* + * 'I' and 'vrfy' aren't congruent mod n. Don't leak + * miscalculated CRT output, just do a raw (slower) mod_exp and + * return that instead. + */ + + BIGNUM local_d; + BIGNUM *d = NULL; + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } else + d = rsa->d; + if (!e_rsax_bn_mod_exp(r0, I, d, rsa->n, ctx, + rsa->_method_mod_n, e_rsax_get_ctx(rsa, 2, + rsa->n))) + goto err; + } + } + ret = 1; + + err: + BN_CTX_end(ctx); + + return ret; +} +# endif /* !OPENSSL_NO_RSA */ +#endif /* !COMPILE_RSAX */ diff --git a/libs/openssl/crypto/engine/eng_table.c b/libs/openssl/crypto/engine/eng_table.c new file mode 100644 index 00000000..27d31f70 --- /dev/null +++ b/libs/openssl/crypto/engine/eng_table.c @@ -0,0 +1,358 @@ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include +#include +#include "eng_int.h" + +/* The type of the items in the table */ +typedef struct st_engine_pile { + /* The 'nid' of this algorithm/mode */ + int nid; + /* ENGINEs that implement this algorithm/mode. */ + STACK_OF(ENGINE) *sk; + /* The default ENGINE to perform this algorithm/mode. */ + ENGINE *funct; + /* + * Zero if 'sk' is newer than the cached 'funct', non-zero otherwise + */ + int uptodate; +} ENGINE_PILE; + +DECLARE_LHASH_OF(ENGINE_PILE); + +/* The type exposed in eng_int.h */ +struct st_engine_table { + LHASH_OF(ENGINE_PILE) piles; +}; /* ENGINE_TABLE */ + +typedef struct st_engine_pile_doall { + engine_table_doall_cb *cb; + void *arg; +} ENGINE_PILE_DOALL; + +/* Global flags (ENGINE_TABLE_FLAG_***). */ +static unsigned int table_flags = 0; + +/* API function manipulating 'table_flags' */ +unsigned int ENGINE_get_table_flags(void) +{ + return table_flags; +} + +void ENGINE_set_table_flags(unsigned int flags) +{ + table_flags = flags; +} + +/* Internal functions for the "piles" hash table */ +static unsigned long engine_pile_hash(const ENGINE_PILE *c) +{ + return c->nid; +} + +static int engine_pile_cmp(const ENGINE_PILE *a, const ENGINE_PILE *b) +{ + return a->nid - b->nid; +} + +static IMPLEMENT_LHASH_HASH_FN(engine_pile, ENGINE_PILE) +static IMPLEMENT_LHASH_COMP_FN(engine_pile, ENGINE_PILE) + +static int int_table_check(ENGINE_TABLE **t, int create) +{ + LHASH_OF(ENGINE_PILE) *lh; + + if (*t) + return 1; + if (!create) + return 0; + if ((lh = lh_ENGINE_PILE_new()) == NULL) + return 0; + *t = (ENGINE_TABLE *)lh; + return 1; +} + +/* + * Privately exposed (via eng_int.h) functions for adding and/or removing + * ENGINEs from the implementation table + */ +int engine_table_register(ENGINE_TABLE **table, ENGINE_CLEANUP_CB *cleanup, + ENGINE *e, const int *nids, int num_nids, + int setdefault) +{ + int ret = 0, added = 0; + ENGINE_PILE tmplate, *fnd; + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (!(*table)) + added = 1; + if (!int_table_check(table, 1)) + goto end; + if (added) + /* The cleanup callback needs to be added */ + engine_cleanup_add_first(cleanup); + while (num_nids--) { + tmplate.nid = *nids; + fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); + if (!fnd) { + fnd = OPENSSL_malloc(sizeof(ENGINE_PILE)); + if (!fnd) + goto end; + fnd->uptodate = 1; + fnd->nid = *nids; + fnd->sk = sk_ENGINE_new_null(); + if (!fnd->sk) { + OPENSSL_free(fnd); + goto end; + } + fnd->funct = NULL; + (void)lh_ENGINE_PILE_insert(&(*table)->piles, fnd); + } + /* A registration shouldn't add duplciate entries */ + (void)sk_ENGINE_delete_ptr(fnd->sk, e); + /* + * if 'setdefault', this ENGINE goes to the head of the list + */ + if (!sk_ENGINE_push(fnd->sk, e)) + goto end; + /* "touch" this ENGINE_PILE */ + fnd->uptodate = 0; + if (setdefault) { + if (!engine_unlocked_init(e)) { + ENGINEerr(ENGINE_F_ENGINE_TABLE_REGISTER, + ENGINE_R_INIT_FAILED); + goto end; + } + if (fnd->funct) + engine_unlocked_finish(fnd->funct, 0); + fnd->funct = e; + fnd->uptodate = 1; + } + nids++; + } + ret = 1; + end: + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return ret; +} + +static void int_unregister_cb_doall_arg(ENGINE_PILE *pile, ENGINE *e) +{ + int n; + /* Iterate the 'c->sk' stack removing any occurance of 'e' */ + while ((n = sk_ENGINE_find(pile->sk, e)) >= 0) { + (void)sk_ENGINE_delete(pile->sk, n); + pile->uptodate = 0; + } + if (pile->funct == e) { + engine_unlocked_finish(e, 0); + pile->funct = NULL; + } +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(int_unregister_cb, ENGINE_PILE, ENGINE) + +void engine_table_unregister(ENGINE_TABLE **table, ENGINE *e) +{ + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (int_table_check(table, 0)) + lh_ENGINE_PILE_doall_arg(&(*table)->piles, + LHASH_DOALL_ARG_FN(int_unregister_cb), + ENGINE, e); + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); +} + +static void int_cleanup_cb_doall(ENGINE_PILE *p) +{ + sk_ENGINE_free(p->sk); + if (p->funct) + engine_unlocked_finish(p->funct, 0); + OPENSSL_free(p); +} + +static IMPLEMENT_LHASH_DOALL_FN(int_cleanup_cb, ENGINE_PILE) + +void engine_table_cleanup(ENGINE_TABLE **table) +{ + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + if (*table) { + lh_ENGINE_PILE_doall(&(*table)->piles, + LHASH_DOALL_FN(int_cleanup_cb)); + lh_ENGINE_PILE_free(&(*table)->piles); + *table = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); +} + +/* return a functional reference for a given 'nid' */ +#ifndef ENGINE_TABLE_DEBUG +ENGINE *engine_table_select(ENGINE_TABLE **table, int nid) +#else +ENGINE *engine_table_select_tmp(ENGINE_TABLE **table, int nid, const char *f, + int l) +#endif +{ + ENGINE *ret = NULL; + ENGINE_PILE tmplate, *fnd = NULL; + int initres, loop = 0; + + if (!(*table)) { +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, nothing " + "registered!\n", f, l, nid); +#endif + return NULL; + } + ERR_set_mark(); + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + /* + * Check again inside the lock otherwise we could race against cleanup + * operations. But don't worry about a fprintf(stderr). + */ + if (!int_table_check(table, 0)) + goto end; + tmplate.nid = nid; + fnd = lh_ENGINE_PILE_retrieve(&(*table)->piles, &tmplate); + if (!fnd) + goto end; + if (fnd->funct && engine_unlocked_init(fnd->funct)) { +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " + "ENGINE '%s' cached\n", f, l, nid, fnd->funct->id); +#endif + ret = fnd->funct; + goto end; + } + if (fnd->uptodate) { + ret = fnd->funct; + goto end; + } + trynext: + ret = sk_ENGINE_value(fnd->sk, loop++); + if (!ret) { +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, no " + "registered implementations would initialise\n", f, l, nid); +#endif + goto end; + } + /* Try to initialise the ENGINE? */ + if ((ret->funct_ref > 0) || !(table_flags & ENGINE_TABLE_FLAG_NOINIT)) + initres = engine_unlocked_init(ret); + else + initres = 0; + if (initres) { + /* Update 'funct' */ + if ((fnd->funct != ret) && engine_unlocked_init(ret)) { + /* If there was a previous default we release it. */ + if (fnd->funct) + engine_unlocked_finish(fnd->funct, 0); + fnd->funct = ret; +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, " + "setting default to '%s'\n", f, l, nid, ret->id); +#endif + } +#ifdef ENGINE_TABLE_DEBUG + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, using " + "newly initialised '%s'\n", f, l, nid, ret->id); +#endif + goto end; + } + goto trynext; + end: + /* + * If it failed, it is unlikely to succeed again until some future + * registrations have taken place. In all cases, we cache. + */ + if (fnd) + fnd->uptodate = 1; +#ifdef ENGINE_TABLE_DEBUG + if (ret) + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " + "ENGINE '%s'\n", f, l, nid, ret->id); + else + fprintf(stderr, "engine_table_dbg: %s:%d, nid=%d, caching " + "'no matching ENGINE'\n", f, l, nid); +#endif + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + /* + * Whatever happened, any failed init()s are not failures in this + * context, so clear our error state. + */ + ERR_pop_to_mark(); + return ret; +} + +/* Table enumeration */ + +static void int_cb_doall_arg(ENGINE_PILE *pile, ENGINE_PILE_DOALL *dall) +{ + dall->cb(pile->nid, pile->sk, pile->funct, dall->arg); +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(int_cb, ENGINE_PILE, ENGINE_PILE_DOALL) + +void engine_table_doall(ENGINE_TABLE *table, engine_table_doall_cb *cb, + void *arg) +{ + ENGINE_PILE_DOALL dall; + dall.cb = cb; + dall.arg = arg; + if (table) + lh_ENGINE_PILE_doall_arg(&table->piles, + LHASH_DOALL_ARG_FN(int_cb), + ENGINE_PILE_DOALL, &dall); +} diff --git a/libs/openssl/crypto/engine/engine.h b/libs/openssl/crypto/engine/engine.h new file mode 100644 index 00000000..e81096ae --- /dev/null +++ b/libs/openssl/crypto/engine/engine.h @@ -0,0 +1,961 @@ +/* openssl/engine.h */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_ENGINE_H +# define HEADER_ENGINE_H + +# include + +# ifdef OPENSSL_NO_ENGINE +# error ENGINE is disabled. +# endif + +# ifndef OPENSSL_NO_DEPRECATED +# include +# ifndef OPENSSL_NO_RSA +# include +# endif +# ifndef OPENSSL_NO_DSA +# include +# endif +# ifndef OPENSSL_NO_DH +# include +# endif +# ifndef OPENSSL_NO_ECDH +# include +# endif +# ifndef OPENSSL_NO_ECDSA +# include +# endif +# include +# include +# include +# endif + +# include +# include + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * These flags are used to control combinations of algorithm (methods) by + * bitwise "OR"ing. + */ +# define ENGINE_METHOD_RSA (unsigned int)0x0001 +# define ENGINE_METHOD_DSA (unsigned int)0x0002 +# define ENGINE_METHOD_DH (unsigned int)0x0004 +# define ENGINE_METHOD_RAND (unsigned int)0x0008 +# define ENGINE_METHOD_ECDH (unsigned int)0x0010 +# define ENGINE_METHOD_ECDSA (unsigned int)0x0020 +# define ENGINE_METHOD_CIPHERS (unsigned int)0x0040 +# define ENGINE_METHOD_DIGESTS (unsigned int)0x0080 +# define ENGINE_METHOD_STORE (unsigned int)0x0100 +# define ENGINE_METHOD_PKEY_METHS (unsigned int)0x0200 +# define ENGINE_METHOD_PKEY_ASN1_METHS (unsigned int)0x0400 +/* Obvious all-or-nothing cases. */ +# define ENGINE_METHOD_ALL (unsigned int)0xFFFF +# define ENGINE_METHOD_NONE (unsigned int)0x0000 + +/* + * This(ese) flag(s) controls behaviour of the ENGINE_TABLE mechanism used + * internally to control registration of ENGINE implementations, and can be + * set by ENGINE_set_table_flags(). The "NOINIT" flag prevents attempts to + * initialise registered ENGINEs if they are not already initialised. + */ +# define ENGINE_TABLE_FLAG_NOINIT (unsigned int)0x0001 + +/* ENGINE flags that can be set by ENGINE_set_flags(). */ +/* Not used */ +/* #define ENGINE_FLAGS_MALLOCED 0x0001 */ + +/* + * This flag is for ENGINEs that wish to handle the various 'CMD'-related + * control commands on their own. Without this flag, ENGINE_ctrl() handles + * these control commands on behalf of the ENGINE using their "cmd_defns" + * data. + */ +# define ENGINE_FLAGS_MANUAL_CMD_CTRL (int)0x0002 + +/* + * This flag is for ENGINEs who return new duplicate structures when found + * via "ENGINE_by_id()". When an ENGINE must store state (eg. if + * ENGINE_ctrl() commands are called in sequence as part of some stateful + * process like key-generation setup and execution), it can set this flag - + * then each attempt to obtain the ENGINE will result in it being copied into + * a new structure. Normally, ENGINEs don't declare this flag so + * ENGINE_by_id() just increments the existing ENGINE's structural reference + * count. + */ +# define ENGINE_FLAGS_BY_ID_COPY (int)0x0004 + +/* + * This flag if for an ENGINE that does not want its methods registered as + * part of ENGINE_register_all_complete() for example if the methods are not + * usable as default methods. + */ + +# define ENGINE_FLAGS_NO_REGISTER_ALL (int)0x0008 + +/* + * ENGINEs can support their own command types, and these flags are used in + * ENGINE_CTRL_GET_CMD_FLAGS to indicate to the caller what kind of input + * each command expects. Currently only numeric and string input is + * supported. If a control command supports none of the _NUMERIC, _STRING, or + * _NO_INPUT options, then it is regarded as an "internal" control command - + * and not for use in config setting situations. As such, they're not + * available to the ENGINE_ctrl_cmd_string() function, only raw ENGINE_ctrl() + * access. Changes to this list of 'command types' should be reflected + * carefully in ENGINE_cmd_is_executable() and ENGINE_ctrl_cmd_string(). + */ + +/* accepts a 'long' input value (3rd parameter to ENGINE_ctrl) */ +# define ENGINE_CMD_FLAG_NUMERIC (unsigned int)0x0001 +/* + * accepts string input (cast from 'void*' to 'const char *', 4th parameter + * to ENGINE_ctrl) + */ +# define ENGINE_CMD_FLAG_STRING (unsigned int)0x0002 +/* + * Indicates that the control command takes *no* input. Ie. the control + * command is unparameterised. + */ +# define ENGINE_CMD_FLAG_NO_INPUT (unsigned int)0x0004 +/* + * Indicates that the control command is internal. This control command won't + * be shown in any output, and is only usable through the ENGINE_ctrl_cmd() + * function. + */ +# define ENGINE_CMD_FLAG_INTERNAL (unsigned int)0x0008 + +/* + * NB: These 3 control commands are deprecated and should not be used. + * ENGINEs relying on these commands should compile conditional support for + * compatibility (eg. if these symbols are defined) but should also migrate + * the same functionality to their own ENGINE-specific control functions that + * can be "discovered" by calling applications. The fact these control + * commands wouldn't be "executable" (ie. usable by text-based config) + * doesn't change the fact that application code can find and use them + * without requiring per-ENGINE hacking. + */ + +/* + * These flags are used to tell the ctrl function what should be done. All + * command numbers are shared between all engines, even if some don't make + * sense to some engines. In such a case, they do nothing but return the + * error ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED. + */ +# define ENGINE_CTRL_SET_LOGSTREAM 1 +# define ENGINE_CTRL_SET_PASSWORD_CALLBACK 2 +# define ENGINE_CTRL_HUP 3/* Close and reinitialise + * any handles/connections + * etc. */ +# define ENGINE_CTRL_SET_USER_INTERFACE 4/* Alternative to callback */ +# define ENGINE_CTRL_SET_CALLBACK_DATA 5/* User-specific data, used + * when calling the password + * callback and the user + * interface */ +# define ENGINE_CTRL_LOAD_CONFIGURATION 6/* Load a configuration, + * given a string that + * represents a file name + * or so */ +# define ENGINE_CTRL_LOAD_SECTION 7/* Load data from a given + * section in the already + * loaded configuration */ + +/* + * These control commands allow an application to deal with an arbitrary + * engine in a dynamic way. Warn: Negative return values indicate errors FOR + * THESE COMMANDS because zero is used to indicate 'end-of-list'. Other + * commands, including ENGINE-specific command types, return zero for an + * error. An ENGINE can choose to implement these ctrl functions, and can + * internally manage things however it chooses - it does so by setting the + * ENGINE_FLAGS_MANUAL_CMD_CTRL flag (using ENGINE_set_flags()). Otherwise + * the ENGINE_ctrl() code handles this on the ENGINE's behalf using the + * cmd_defns data (set using ENGINE_set_cmd_defns()). This means an ENGINE's + * ctrl() handler need only implement its own commands - the above "meta" + * commands will be taken care of. + */ + +/* + * Returns non-zero if the supplied ENGINE has a ctrl() handler. If "not", + * then all the remaining control commands will return failure, so it is + * worth checking this first if the caller is trying to "discover" the + * engine's capabilities and doesn't want errors generated unnecessarily. + */ +# define ENGINE_CTRL_HAS_CTRL_FUNCTION 10 +/* + * Returns a positive command number for the first command supported by the + * engine. Returns zero if no ctrl commands are supported. + */ +# define ENGINE_CTRL_GET_FIRST_CMD_TYPE 11 +/* + * The 'long' argument specifies a command implemented by the engine, and the + * return value is the next command supported, or zero if there are no more. + */ +# define ENGINE_CTRL_GET_NEXT_CMD_TYPE 12 +/* + * The 'void*' argument is a command name (cast from 'const char *'), and the + * return value is the command that corresponds to it. + */ +# define ENGINE_CTRL_GET_CMD_FROM_NAME 13 +/* + * The next two allow a command to be converted into its corresponding string + * form. In each case, the 'long' argument supplies the command. In the + * NAME_LEN case, the return value is the length of the command name (not + * counting a trailing EOL). In the NAME case, the 'void*' argument must be a + * string buffer large enough, and it will be populated with the name of the + * command (WITH a trailing EOL). + */ +# define ENGINE_CTRL_GET_NAME_LEN_FROM_CMD 14 +# define ENGINE_CTRL_GET_NAME_FROM_CMD 15 +/* The next two are similar but give a "short description" of a command. */ +# define ENGINE_CTRL_GET_DESC_LEN_FROM_CMD 16 +# define ENGINE_CTRL_GET_DESC_FROM_CMD 17 +/* + * With this command, the return value is the OR'd combination of + * ENGINE_CMD_FLAG_*** values that indicate what kind of input a given + * engine-specific ctrl command expects. + */ +# define ENGINE_CTRL_GET_CMD_FLAGS 18 + +/* + * ENGINE implementations should start the numbering of their own control + * commands from this value. (ie. ENGINE_CMD_BASE, ENGINE_CMD_BASE + 1, etc). + */ +# define ENGINE_CMD_BASE 200 + +/* + * NB: These 2 nCipher "chil" control commands are deprecated, and their + * functionality is now available through ENGINE-specific control commands + * (exposed through the above-mentioned 'CMD'-handling). Code using these 2 + * commands should be migrated to the more general command handling before + * these are removed. + */ + +/* Flags specific to the nCipher "chil" engine */ +# define ENGINE_CTRL_CHIL_SET_FORKCHECK 100 + /* + * Depending on the value of the (long)i argument, this sets or + * unsets the SimpleForkCheck flag in the CHIL API to enable or + * disable checking and workarounds for applications that fork(). + */ +# define ENGINE_CTRL_CHIL_NO_LOCKING 101 + /* + * This prevents the initialisation function from providing mutex + * callbacks to the nCipher library. + */ + +/* + * If an ENGINE supports its own specific control commands and wishes the + * framework to handle the above 'ENGINE_CMD_***'-manipulation commands on + * its behalf, it should supply a null-terminated array of ENGINE_CMD_DEFN + * entries to ENGINE_set_cmd_defns(). It should also implement a ctrl() + * handler that supports the stated commands (ie. the "cmd_num" entries as + * described by the array). NB: The array must be ordered in increasing order + * of cmd_num. "null-terminated" means that the last ENGINE_CMD_DEFN element + * has cmd_num set to zero and/or cmd_name set to NULL. + */ +typedef struct ENGINE_CMD_DEFN_st { + unsigned int cmd_num; /* The command number */ + const char *cmd_name; /* The command name itself */ + const char *cmd_desc; /* A short description of the command */ + unsigned int cmd_flags; /* The input the command expects */ +} ENGINE_CMD_DEFN; + +/* Generic function pointer */ +typedef int (*ENGINE_GEN_FUNC_PTR) (void); +/* Generic function pointer taking no arguments */ +typedef int (*ENGINE_GEN_INT_FUNC_PTR) (ENGINE *); +/* Specific control function pointer */ +typedef int (*ENGINE_CTRL_FUNC_PTR) (ENGINE *, int, long, void *, + void (*f) (void)); +/* Generic load_key function pointer */ +typedef EVP_PKEY *(*ENGINE_LOAD_KEY_PTR)(ENGINE *, const char *, + UI_METHOD *ui_method, + void *callback_data); +typedef int (*ENGINE_SSL_CLIENT_CERT_PTR) (ENGINE *, SSL *ssl, + STACK_OF(X509_NAME) *ca_dn, + X509 **pcert, EVP_PKEY **pkey, + STACK_OF(X509) **pother, + UI_METHOD *ui_method, + void *callback_data); +/*- + * These callback types are for an ENGINE's handler for cipher and digest logic. + * These handlers have these prototypes; + * int foo(ENGINE *e, const EVP_CIPHER **cipher, const int **nids, int nid); + * int foo(ENGINE *e, const EVP_MD **digest, const int **nids, int nid); + * Looking at how to implement these handlers in the case of cipher support, if + * the framework wants the EVP_CIPHER for 'nid', it will call; + * foo(e, &p_evp_cipher, NULL, nid); (return zero for failure) + * If the framework wants a list of supported 'nid's, it will call; + * foo(e, NULL, &p_nids, 0); (returns number of 'nids' or -1 for error) + */ +/* + * Returns to a pointer to the array of supported cipher 'nid's. If the + * second parameter is non-NULL it is set to the size of the returned array. + */ +typedef int (*ENGINE_CIPHERS_PTR) (ENGINE *, const EVP_CIPHER **, + const int **, int); +typedef int (*ENGINE_DIGESTS_PTR) (ENGINE *, const EVP_MD **, const int **, + int); +typedef int (*ENGINE_PKEY_METHS_PTR) (ENGINE *, EVP_PKEY_METHOD **, + const int **, int); +typedef int (*ENGINE_PKEY_ASN1_METHS_PTR) (ENGINE *, EVP_PKEY_ASN1_METHOD **, + const int **, int); +/* + * STRUCTURE functions ... all of these functions deal with pointers to + * ENGINE structures where the pointers have a "structural reference". This + * means that their reference is to allowed access to the structure but it + * does not imply that the structure is functional. To simply increment or + * decrement the structural reference count, use ENGINE_by_id and + * ENGINE_free. NB: This is not required when iterating using ENGINE_get_next + * as it will automatically decrement the structural reference count of the + * "current" ENGINE and increment the structural reference count of the + * ENGINE it returns (unless it is NULL). + */ + +/* Get the first/last "ENGINE" type available. */ +ENGINE *ENGINE_get_first(void); +ENGINE *ENGINE_get_last(void); +/* Iterate to the next/previous "ENGINE" type (NULL = end of the list). */ +ENGINE *ENGINE_get_next(ENGINE *e); +ENGINE *ENGINE_get_prev(ENGINE *e); +/* Add another "ENGINE" type into the array. */ +int ENGINE_add(ENGINE *e); +/* Remove an existing "ENGINE" type from the array. */ +int ENGINE_remove(ENGINE *e); +/* Retrieve an engine from the list by its unique "id" value. */ +ENGINE *ENGINE_by_id(const char *id); +/* Add all the built-in engines. */ +void ENGINE_load_openssl(void); +void ENGINE_load_dynamic(void); +# ifndef OPENSSL_NO_STATIC_ENGINE +void ENGINE_load_4758cca(void); +void ENGINE_load_aep(void); +void ENGINE_load_atalla(void); +void ENGINE_load_chil(void); +void ENGINE_load_cswift(void); +void ENGINE_load_nuron(void); +void ENGINE_load_sureware(void); +void ENGINE_load_ubsec(void); +void ENGINE_load_padlock(void); +void ENGINE_load_capi(void); +# ifndef OPENSSL_NO_GMP +void ENGINE_load_gmp(void); +# endif +# ifndef OPENSSL_NO_GOST +void ENGINE_load_gost(void); +# endif +# endif +void ENGINE_load_cryptodev(void); +void ENGINE_load_rsax(void); +void ENGINE_load_rdrand(void); +void ENGINE_load_builtin_engines(void); + +/* + * Get and set global flags (ENGINE_TABLE_FLAG_***) for the implementation + * "registry" handling. + */ +unsigned int ENGINE_get_table_flags(void); +void ENGINE_set_table_flags(unsigned int flags); + +/*- Manage registration of ENGINEs per "table". For each type, there are 3 + * functions; + * ENGINE_register_***(e) - registers the implementation from 'e' (if it has one) + * ENGINE_unregister_***(e) - unregister the implementation from 'e' + * ENGINE_register_all_***() - call ENGINE_register_***() for each 'e' in the list + * Cleanup is automatically registered from each table when required, so + * ENGINE_cleanup() will reverse any "register" operations. + */ + +int ENGINE_register_RSA(ENGINE *e); +void ENGINE_unregister_RSA(ENGINE *e); +void ENGINE_register_all_RSA(void); + +int ENGINE_register_DSA(ENGINE *e); +void ENGINE_unregister_DSA(ENGINE *e); +void ENGINE_register_all_DSA(void); + +int ENGINE_register_ECDH(ENGINE *e); +void ENGINE_unregister_ECDH(ENGINE *e); +void ENGINE_register_all_ECDH(void); + +int ENGINE_register_ECDSA(ENGINE *e); +void ENGINE_unregister_ECDSA(ENGINE *e); +void ENGINE_register_all_ECDSA(void); + +int ENGINE_register_DH(ENGINE *e); +void ENGINE_unregister_DH(ENGINE *e); +void ENGINE_register_all_DH(void); + +int ENGINE_register_RAND(ENGINE *e); +void ENGINE_unregister_RAND(ENGINE *e); +void ENGINE_register_all_RAND(void); + +int ENGINE_register_STORE(ENGINE *e); +void ENGINE_unregister_STORE(ENGINE *e); +void ENGINE_register_all_STORE(void); + +int ENGINE_register_ciphers(ENGINE *e); +void ENGINE_unregister_ciphers(ENGINE *e); +void ENGINE_register_all_ciphers(void); + +int ENGINE_register_digests(ENGINE *e); +void ENGINE_unregister_digests(ENGINE *e); +void ENGINE_register_all_digests(void); + +int ENGINE_register_pkey_meths(ENGINE *e); +void ENGINE_unregister_pkey_meths(ENGINE *e); +void ENGINE_register_all_pkey_meths(void); + +int ENGINE_register_pkey_asn1_meths(ENGINE *e); +void ENGINE_unregister_pkey_asn1_meths(ENGINE *e); +void ENGINE_register_all_pkey_asn1_meths(void); + +/* + * These functions register all support from the above categories. Note, use + * of these functions can result in static linkage of code your application + * may not need. If you only need a subset of functionality, consider using + * more selective initialisation. + */ +int ENGINE_register_complete(ENGINE *e); +int ENGINE_register_all_complete(void); + +/* + * Send parametrised control commands to the engine. The possibilities to + * send down an integer, a pointer to data or a function pointer are + * provided. Any of the parameters may or may not be NULL, depending on the + * command number. In actuality, this function only requires a structural + * (rather than functional) reference to an engine, but many control commands + * may require the engine be functional. The caller should be aware of trying + * commands that require an operational ENGINE, and only use functional + * references in such situations. + */ +int ENGINE_ctrl(ENGINE *e, int cmd, long i, void *p, void (*f) (void)); + +/* + * This function tests if an ENGINE-specific command is usable as a + * "setting". Eg. in an application's config file that gets processed through + * ENGINE_ctrl_cmd_string(). If this returns zero, it is not available to + * ENGINE_ctrl_cmd_string(), only ENGINE_ctrl(). + */ +int ENGINE_cmd_is_executable(ENGINE *e, int cmd); + +/* + * This function works like ENGINE_ctrl() with the exception of taking a + * command name instead of a command number, and can handle optional + * commands. See the comment on ENGINE_ctrl_cmd_string() for an explanation + * on how to use the cmd_name and cmd_optional. + */ +int ENGINE_ctrl_cmd(ENGINE *e, const char *cmd_name, + long i, void *p, void (*f) (void), int cmd_optional); + +/* + * This function passes a command-name and argument to an ENGINE. The + * cmd_name is converted to a command number and the control command is + * called using 'arg' as an argument (unless the ENGINE doesn't support such + * a command, in which case no control command is called). The command is + * checked for input flags, and if necessary the argument will be converted + * to a numeric value. If cmd_optional is non-zero, then if the ENGINE + * doesn't support the given cmd_name the return value will be success + * anyway. This function is intended for applications to use so that users + * (or config files) can supply engine-specific config data to the ENGINE at + * run-time to control behaviour of specific engines. As such, it shouldn't + * be used for calling ENGINE_ctrl() functions that return data, deal with + * binary data, or that are otherwise supposed to be used directly through + * ENGINE_ctrl() in application code. Any "return" data from an ENGINE_ctrl() + * operation in this function will be lost - the return value is interpreted + * as failure if the return value is zero, success otherwise, and this + * function returns a boolean value as a result. In other words, vendors of + * 'ENGINE'-enabled devices should write ENGINE implementations with + * parameterisations that work in this scheme, so that compliant ENGINE-based + * applications can work consistently with the same configuration for the + * same ENGINE-enabled devices, across applications. + */ +int ENGINE_ctrl_cmd_string(ENGINE *e, const char *cmd_name, const char *arg, + int cmd_optional); + +/* + * These functions are useful for manufacturing new ENGINE structures. They + * don't address reference counting at all - one uses them to populate an + * ENGINE structure with personalised implementations of things prior to + * using it directly or adding it to the builtin ENGINE list in OpenSSL. + * These are also here so that the ENGINE structure doesn't have to be + * exposed and break binary compatibility! + */ +ENGINE *ENGINE_new(void); +int ENGINE_free(ENGINE *e); +int ENGINE_up_ref(ENGINE *e); +int ENGINE_set_id(ENGINE *e, const char *id); +int ENGINE_set_name(ENGINE *e, const char *name); +int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth); +int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth); +int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth); +int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth); +int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth); +int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth); +int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth); +int ENGINE_set_destroy_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR destroy_f); +int ENGINE_set_init_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR init_f); +int ENGINE_set_finish_function(ENGINE *e, ENGINE_GEN_INT_FUNC_PTR finish_f); +int ENGINE_set_ctrl_function(ENGINE *e, ENGINE_CTRL_FUNC_PTR ctrl_f); +int ENGINE_set_load_privkey_function(ENGINE *e, + ENGINE_LOAD_KEY_PTR loadpriv_f); +int ENGINE_set_load_pubkey_function(ENGINE *e, ENGINE_LOAD_KEY_PTR loadpub_f); +int ENGINE_set_load_ssl_client_cert_function(ENGINE *e, + ENGINE_SSL_CLIENT_CERT_PTR + loadssl_f); +int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f); +int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f); +int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f); +int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f); +int ENGINE_set_flags(ENGINE *e, int flags); +int ENGINE_set_cmd_defns(ENGINE *e, const ENGINE_CMD_DEFN *defns); +/* These functions allow control over any per-structure ENGINE data. */ +int ENGINE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +int ENGINE_set_ex_data(ENGINE *e, int idx, void *arg); +void *ENGINE_get_ex_data(const ENGINE *e, int idx); + +/* + * This function cleans up anything that needs it. Eg. the ENGINE_add() + * function automatically ensures the list cleanup function is registered to + * be called from ENGINE_cleanup(). Similarly, all ENGINE_register_*** + * functions ensure ENGINE_cleanup() will clean up after them. + */ +void ENGINE_cleanup(void); + +/* + * These return values from within the ENGINE structure. These can be useful + * with functional references as well as structural references - it depends + * which you obtained. Using the result for functional purposes if you only + * obtained a structural reference may be problematic! + */ +const char *ENGINE_get_id(const ENGINE *e); +const char *ENGINE_get_name(const ENGINE *e); +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e); +const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e); +const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e); +const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e); +const DH_METHOD *ENGINE_get_DH(const ENGINE *e); +const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e); +const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_destroy_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_init_function(const ENGINE *e); +ENGINE_GEN_INT_FUNC_PTR ENGINE_get_finish_function(const ENGINE *e); +ENGINE_CTRL_FUNC_PTR ENGINE_get_ctrl_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_privkey_function(const ENGINE *e); +ENGINE_LOAD_KEY_PTR ENGINE_get_load_pubkey_function(const ENGINE *e); +ENGINE_SSL_CLIENT_CERT_PTR ENGINE_get_ssl_client_cert_function(const ENGINE + *e); +ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e); +ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e); +ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e); +ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e); +const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid); +const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid); +const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid); +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, + const char *str, + int len); +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, + const char *str, + int len); +const ENGINE_CMD_DEFN *ENGINE_get_cmd_defns(const ENGINE *e); +int ENGINE_get_flags(const ENGINE *e); + +/* + * FUNCTIONAL functions. These functions deal with ENGINE structures that + * have (or will) be initialised for use. Broadly speaking, the structural + * functions are useful for iterating the list of available engine types, + * creating new engine types, and other "list" operations. These functions + * actually deal with ENGINEs that are to be used. As such these functions + * can fail (if applicable) when particular engines are unavailable - eg. if + * a hardware accelerator is not attached or not functioning correctly. Each + * ENGINE has 2 reference counts; structural and functional. Every time a + * functional reference is obtained or released, a corresponding structural + * reference is automatically obtained or released too. + */ + +/* + * Initialise a engine type for use (or up its reference count if it's + * already in use). This will fail if the engine is not currently operational + * and cannot initialise. + */ +int ENGINE_init(ENGINE *e); +/* + * Free a functional reference to a engine type. This does not require a + * corresponding call to ENGINE_free as it also releases a structural + * reference. + */ +int ENGINE_finish(ENGINE *e); + +/* + * The following functions handle keys that are stored in some secondary + * location, handled by the engine. The storage may be on a card or + * whatever. + */ +EVP_PKEY *ENGINE_load_private_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +EVP_PKEY *ENGINE_load_public_key(ENGINE *e, const char *key_id, + UI_METHOD *ui_method, void *callback_data); +int ENGINE_load_ssl_client_cert(ENGINE *e, SSL *s, + STACK_OF(X509_NAME) *ca_dn, X509 **pcert, + EVP_PKEY **ppkey, STACK_OF(X509) **pother, + UI_METHOD *ui_method, void *callback_data); + +/* + * This returns a pointer for the current ENGINE structure that is (by + * default) performing any RSA operations. The value returned is an + * incremented reference, so it should be free'd (ENGINE_finish) before it is + * discarded. + */ +ENGINE *ENGINE_get_default_RSA(void); +/* Same for the other "methods" */ +ENGINE *ENGINE_get_default_DSA(void); +ENGINE *ENGINE_get_default_ECDH(void); +ENGINE *ENGINE_get_default_ECDSA(void); +ENGINE *ENGINE_get_default_DH(void); +ENGINE *ENGINE_get_default_RAND(void); +/* + * These functions can be used to get a functional reference to perform + * ciphering or digesting corresponding to "nid". + */ +ENGINE *ENGINE_get_cipher_engine(int nid); +ENGINE *ENGINE_get_digest_engine(int nid); +ENGINE *ENGINE_get_pkey_meth_engine(int nid); +ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid); + +/* + * This sets a new default ENGINE structure for performing RSA operations. If + * the result is non-zero (success) then the ENGINE structure will have had + * its reference count up'd so the caller should still free their own + * reference 'e'. + */ +int ENGINE_set_default_RSA(ENGINE *e); +int ENGINE_set_default_string(ENGINE *e, const char *def_list); +/* Same for the other "methods" */ +int ENGINE_set_default_DSA(ENGINE *e); +int ENGINE_set_default_ECDH(ENGINE *e); +int ENGINE_set_default_ECDSA(ENGINE *e); +int ENGINE_set_default_DH(ENGINE *e); +int ENGINE_set_default_RAND(ENGINE *e); +int ENGINE_set_default_ciphers(ENGINE *e); +int ENGINE_set_default_digests(ENGINE *e); +int ENGINE_set_default_pkey_meths(ENGINE *e); +int ENGINE_set_default_pkey_asn1_meths(ENGINE *e); + +/* + * The combination "set" - the flags are bitwise "OR"d from the + * ENGINE_METHOD_*** defines above. As with the "ENGINE_register_complete()" + * function, this function can result in unnecessary static linkage. If your + * application requires only specific functionality, consider using more + * selective functions. + */ +int ENGINE_set_default(ENGINE *e, unsigned int flags); + +void ENGINE_add_conf_module(void); + +/* Deprecated functions ... */ +/* int ENGINE_clear_defaults(void); */ + +/**************************/ +/* DYNAMIC ENGINE SUPPORT */ +/**************************/ + +/* Binary/behaviour compatibility levels */ +# define OSSL_DYNAMIC_VERSION (unsigned long)0x00020000 +/* + * Binary versions older than this are too old for us (whether we're a loader + * or a loadee) + */ +# define OSSL_DYNAMIC_OLDEST (unsigned long)0x00020000 + +/* + * When compiling an ENGINE entirely as an external shared library, loadable + * by the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' + * structure type provides the calling application's (or library's) error + * functionality and memory management function pointers to the loaded + * library. These should be used/set in the loaded library code so that the + * loading application's 'state' will be used/changed in all operations. The + * 'static_state' pointer allows the loaded library to know if it shares the + * same static data as the calling application (or library), and thus whether + * these callbacks need to be set or not. + */ +typedef void *(*dyn_MEM_malloc_cb) (size_t); +typedef void *(*dyn_MEM_realloc_cb) (void *, size_t); +typedef void (*dyn_MEM_free_cb) (void *); +typedef struct st_dynamic_MEM_fns { + dyn_MEM_malloc_cb malloc_cb; + dyn_MEM_realloc_cb realloc_cb; + dyn_MEM_free_cb free_cb; +} dynamic_MEM_fns; +/* + * FIXME: Perhaps the memory and locking code (crypto.h) should declare and + * use these types so we (and any other dependant code) can simplify a bit?? + */ +typedef void (*dyn_lock_locking_cb) (int, int, const char *, int); +typedef int (*dyn_lock_add_lock_cb) (int *, int, int, const char *, int); +typedef struct CRYPTO_dynlock_value *(*dyn_dynlock_create_cb) (const char *, + int); +typedef void (*dyn_dynlock_lock_cb) (int, struct CRYPTO_dynlock_value *, + const char *, int); +typedef void (*dyn_dynlock_destroy_cb) (struct CRYPTO_dynlock_value *, + const char *, int); +typedef struct st_dynamic_LOCK_fns { + dyn_lock_locking_cb lock_locking_cb; + dyn_lock_add_lock_cb lock_add_lock_cb; + dyn_dynlock_create_cb dynlock_create_cb; + dyn_dynlock_lock_cb dynlock_lock_cb; + dyn_dynlock_destroy_cb dynlock_destroy_cb; +} dynamic_LOCK_fns; +/* The top-level structure */ +typedef struct st_dynamic_fns { + void *static_state; + const ERR_FNS *err_fns; + const CRYPTO_EX_DATA_IMPL *ex_data_fns; + dynamic_MEM_fns mem_fns; + dynamic_LOCK_fns lock_fns; +} dynamic_fns; + +/* + * The version checking function should be of this prototype. NB: The + * ossl_version value passed in is the OSSL_DYNAMIC_VERSION of the loading + * code. If this function returns zero, it indicates a (potential) version + * incompatibility and the loaded library doesn't believe it can proceed. + * Otherwise, the returned value is the (latest) version supported by the + * loading library. The loader may still decide that the loaded code's + * version is unsatisfactory and could veto the load. The function is + * expected to be implemented with the symbol name "v_check", and a default + * implementation can be fully instantiated with + * IMPLEMENT_DYNAMIC_CHECK_FN(). + */ +typedef unsigned long (*dynamic_v_check_fn) (unsigned long ossl_version); +# define IMPLEMENT_DYNAMIC_CHECK_FN() \ + OPENSSL_EXPORT unsigned long v_check(unsigned long v); \ + OPENSSL_EXPORT unsigned long v_check(unsigned long v) { \ + if(v >= OSSL_DYNAMIC_OLDEST) return OSSL_DYNAMIC_VERSION; \ + return 0; } + +/* + * This function is passed the ENGINE structure to initialise with its own + * function and command settings. It should not adjust the structural or + * functional reference counts. If this function returns zero, (a) the load + * will be aborted, (b) the previous ENGINE state will be memcpy'd back onto + * the structure, and (c) the shared library will be unloaded. So + * implementations should do their own internal cleanup in failure + * circumstances otherwise they could leak. The 'id' parameter, if non-NULL, + * represents the ENGINE id that the loader is looking for. If this is NULL, + * the shared library can choose to return failure or to initialise a + * 'default' ENGINE. If non-NULL, the shared library must initialise only an + * ENGINE matching the passed 'id'. The function is expected to be + * implemented with the symbol name "bind_engine". A standard implementation + * can be instantiated with IMPLEMENT_DYNAMIC_BIND_FN(fn) where the parameter + * 'fn' is a callback function that populates the ENGINE structure and + * returns an int value (zero for failure). 'fn' should have prototype; + * [static] int fn(ENGINE *e, const char *id); + */ +typedef int (*dynamic_bind_engine) (ENGINE *e, const char *id, + const dynamic_fns *fns); +# define IMPLEMENT_DYNAMIC_BIND_FN(fn) \ + OPENSSL_EXPORT \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns); \ + OPENSSL_EXPORT \ + int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \ + if(ENGINE_get_static_state() == fns->static_state) goto skip_cbs; \ + if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \ + fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \ + return 0; \ + CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \ + CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \ + CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \ + CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \ + CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \ + if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \ + return 0; \ + if(!ERR_set_implementation(fns->err_fns)) return 0; \ + skip_cbs: \ + if(!fn(e,id)) return 0; \ + return 1; } + +/* + * If the loading application (or library) and the loaded ENGINE library + * share the same static data (eg. they're both dynamically linked to the + * same libcrypto.so) we need a way to avoid trying to set system callbacks - + * this would fail, and for the same reason that it's unnecessary to try. If + * the loaded ENGINE has (or gets from through the loader) its own copy of + * the libcrypto static data, we will need to set the callbacks. The easiest + * way to detect this is to have a function that returns a pointer to some + * static data and let the loading application and loaded ENGINE compare + * their respective values. + */ +void *ENGINE_get_static_state(void); + +# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV) +void ENGINE_setup_bsd_cryptodev(void); +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_ENGINE_strings(void); + +/* Error codes for the ENGINE functions. */ + +/* Function codes. */ +# define ENGINE_F_DYNAMIC_CTRL 180 +# define ENGINE_F_DYNAMIC_GET_DATA_CTX 181 +# define ENGINE_F_DYNAMIC_LOAD 182 +# define ENGINE_F_DYNAMIC_SET_DATA_CTX 183 +# define ENGINE_F_ENGINE_ADD 105 +# define ENGINE_F_ENGINE_BY_ID 106 +# define ENGINE_F_ENGINE_CMD_IS_EXECUTABLE 170 +# define ENGINE_F_ENGINE_CTRL 142 +# define ENGINE_F_ENGINE_CTRL_CMD 178 +# define ENGINE_F_ENGINE_CTRL_CMD_STRING 171 +# define ENGINE_F_ENGINE_FINISH 107 +# define ENGINE_F_ENGINE_FREE_UTIL 108 +# define ENGINE_F_ENGINE_GET_CIPHER 185 +# define ENGINE_F_ENGINE_GET_DEFAULT_TYPE 177 +# define ENGINE_F_ENGINE_GET_DIGEST 186 +# define ENGINE_F_ENGINE_GET_NEXT 115 +# define ENGINE_F_ENGINE_GET_PKEY_ASN1_METH 193 +# define ENGINE_F_ENGINE_GET_PKEY_METH 192 +# define ENGINE_F_ENGINE_GET_PREV 116 +# define ENGINE_F_ENGINE_INIT 119 +# define ENGINE_F_ENGINE_LIST_ADD 120 +# define ENGINE_F_ENGINE_LIST_REMOVE 121 +# define ENGINE_F_ENGINE_LOAD_PRIVATE_KEY 150 +# define ENGINE_F_ENGINE_LOAD_PUBLIC_KEY 151 +# define ENGINE_F_ENGINE_LOAD_SSL_CLIENT_CERT 194 +# define ENGINE_F_ENGINE_NEW 122 +# define ENGINE_F_ENGINE_REMOVE 123 +# define ENGINE_F_ENGINE_SET_DEFAULT_STRING 189 +# define ENGINE_F_ENGINE_SET_DEFAULT_TYPE 126 +# define ENGINE_F_ENGINE_SET_ID 129 +# define ENGINE_F_ENGINE_SET_NAME 130 +# define ENGINE_F_ENGINE_TABLE_REGISTER 184 +# define ENGINE_F_ENGINE_UNLOAD_KEY 152 +# define ENGINE_F_ENGINE_UNLOCKED_FINISH 191 +# define ENGINE_F_ENGINE_UP_REF 190 +# define ENGINE_F_INT_CTRL_HELPER 172 +# define ENGINE_F_INT_ENGINE_CONFIGURE 188 +# define ENGINE_F_INT_ENGINE_MODULE_INIT 187 +# define ENGINE_F_LOG_MESSAGE 141 + +/* Reason codes. */ +# define ENGINE_R_ALREADY_LOADED 100 +# define ENGINE_R_ARGUMENT_IS_NOT_A_NUMBER 133 +# define ENGINE_R_CMD_NOT_EXECUTABLE 134 +# define ENGINE_R_COMMAND_TAKES_INPUT 135 +# define ENGINE_R_COMMAND_TAKES_NO_INPUT 136 +# define ENGINE_R_CONFLICTING_ENGINE_ID 103 +# define ENGINE_R_CTRL_COMMAND_NOT_IMPLEMENTED 119 +# define ENGINE_R_DH_NOT_IMPLEMENTED 139 +# define ENGINE_R_DSA_NOT_IMPLEMENTED 140 +# define ENGINE_R_DSO_FAILURE 104 +# define ENGINE_R_DSO_NOT_FOUND 132 +# define ENGINE_R_ENGINES_SECTION_ERROR 148 +# define ENGINE_R_ENGINE_CONFIGURATION_ERROR 102 +# define ENGINE_R_ENGINE_IS_NOT_IN_LIST 105 +# define ENGINE_R_ENGINE_SECTION_ERROR 149 +# define ENGINE_R_FAILED_LOADING_PRIVATE_KEY 128 +# define ENGINE_R_FAILED_LOADING_PUBLIC_KEY 129 +# define ENGINE_R_FINISH_FAILED 106 +# define ENGINE_R_GET_HANDLE_FAILED 107 +# define ENGINE_R_ID_OR_NAME_MISSING 108 +# define ENGINE_R_INIT_FAILED 109 +# define ENGINE_R_INTERNAL_LIST_ERROR 110 +# define ENGINE_R_INVALID_ARGUMENT 143 +# define ENGINE_R_INVALID_CMD_NAME 137 +# define ENGINE_R_INVALID_CMD_NUMBER 138 +# define ENGINE_R_INVALID_INIT_VALUE 151 +# define ENGINE_R_INVALID_STRING 150 +# define ENGINE_R_NOT_INITIALISED 117 +# define ENGINE_R_NOT_LOADED 112 +# define ENGINE_R_NO_CONTROL_FUNCTION 120 +# define ENGINE_R_NO_INDEX 144 +# define ENGINE_R_NO_LOAD_FUNCTION 125 +# define ENGINE_R_NO_REFERENCE 130 +# define ENGINE_R_NO_SUCH_ENGINE 116 +# define ENGINE_R_NO_UNLOAD_FUNCTION 126 +# define ENGINE_R_PROVIDE_PARAMETERS 113 +# define ENGINE_R_RSA_NOT_IMPLEMENTED 141 +# define ENGINE_R_UNIMPLEMENTED_CIPHER 146 +# define ENGINE_R_UNIMPLEMENTED_DIGEST 147 +# define ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD 101 +# define ENGINE_R_VERSION_INCOMPATIBILITY 145 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/engine/enginetest.c b/libs/openssl/crypto/engine/enginetest.c new file mode 100644 index 00000000..ab7c0c00 --- /dev/null +++ b/libs/openssl/crypto/engine/enginetest.c @@ -0,0 +1,269 @@ +/* crypto/engine/enginetest.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#ifdef OPENSSL_NO_ENGINE +int main(int argc, char *argv[]) +{ + printf("No ENGINE support\n"); + return (0); +} +#else +# include +# include +# include +# include + +static void display_engine_list(void) +{ + ENGINE *h; + int loop; + + h = ENGINE_get_first(); + loop = 0; + printf("listing available engine types\n"); + while (h) { + printf("engine %i, id = \"%s\", name = \"%s\"\n", + loop++, ENGINE_get_id(h), ENGINE_get_name(h)); + h = ENGINE_get_next(h); + } + printf("end of list\n"); + /* + * ENGINE_get_first() increases the struct_ref counter, so we must call + * ENGINE_free() to decrease it again + */ + ENGINE_free(h); +} + +int main(int argc, char *argv[]) +{ + ENGINE *block[512]; + char buf[256]; + const char *id, *name; + ENGINE *ptr; + int loop; + int to_return = 1; + ENGINE *new_h1 = NULL; + ENGINE *new_h2 = NULL; + ENGINE *new_h3 = NULL; + ENGINE *new_h4 = NULL; + + /* enable memory leak checking unless explicitly disabled */ + if (!((getenv("OPENSSL_DEBUG_MEMORY") != NULL) + && (0 == strcmp(getenv("OPENSSL_DEBUG_MEMORY"), "off")))) { + CRYPTO_malloc_debug_init(); + CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); + } else { + /* OPENSSL_DEBUG_MEMORY=off */ + CRYPTO_set_mem_debug_functions(0, 0, 0, 0, 0); + } + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + ERR_load_crypto_strings(); + + memset(block, 0, 512 * sizeof(ENGINE *)); + if (((new_h1 = ENGINE_new()) == NULL) || + !ENGINE_set_id(new_h1, "test_id0") || + !ENGINE_set_name(new_h1, "First test item") || + ((new_h2 = ENGINE_new()) == NULL) || + !ENGINE_set_id(new_h2, "test_id1") || + !ENGINE_set_name(new_h2, "Second test item") || + ((new_h3 = ENGINE_new()) == NULL) || + !ENGINE_set_id(new_h3, "test_id2") || + !ENGINE_set_name(new_h3, "Third test item") || + ((new_h4 = ENGINE_new()) == NULL) || + !ENGINE_set_id(new_h4, "test_id3") || + !ENGINE_set_name(new_h4, "Fourth test item")) { + printf("Couldn't set up test ENGINE structures\n"); + goto end; + } + printf("\nenginetest beginning\n\n"); + display_engine_list(); + if (!ENGINE_add(new_h1)) { + printf("Add failed!\n"); + goto end; + } + display_engine_list(); + ptr = ENGINE_get_first(); + if (!ENGINE_remove(ptr)) { + printf("Remove failed!\n"); + goto end; + } + if (ptr) + ENGINE_free(ptr); + display_engine_list(); + if (!ENGINE_add(new_h3) || !ENGINE_add(new_h2)) { + printf("Add failed!\n"); + goto end; + } + display_engine_list(); + if (!ENGINE_remove(new_h2)) { + printf("Remove failed!\n"); + goto end; + } + display_engine_list(); + if (!ENGINE_add(new_h4)) { + printf("Add failed!\n"); + goto end; + } + display_engine_list(); + if (ENGINE_add(new_h3)) { + printf("Add *should* have failed but didn't!\n"); + goto end; + } else + printf("Add that should fail did.\n"); + ERR_clear_error(); + if (ENGINE_remove(new_h2)) { + printf("Remove *should* have failed but didn't!\n"); + goto end; + } else + printf("Remove that should fail did.\n"); + ERR_clear_error(); + if (!ENGINE_remove(new_h3)) { + printf("Remove failed!\n"); + goto end; + } + display_engine_list(); + if (!ENGINE_remove(new_h4)) { + printf("Remove failed!\n"); + goto end; + } + display_engine_list(); + /* + * Depending on whether there's any hardware support compiled in, this + * remove may be destined to fail. + */ + ptr = ENGINE_get_first(); + if (ptr) + if (!ENGINE_remove(ptr)) + printf("Remove failed!i - probably no hardware " + "support present.\n"); + if (ptr) + ENGINE_free(ptr); + display_engine_list(); + if (!ENGINE_add(new_h1) || !ENGINE_remove(new_h1)) { + printf("Couldn't add and remove to an empty list!\n"); + goto end; + } else + printf("Successfully added and removed to an empty list!\n"); + printf("About to beef up the engine-type list\n"); + for (loop = 0; loop < 512; loop++) { + sprintf(buf, "id%i", loop); + id = BUF_strdup(buf); + sprintf(buf, "Fake engine type %i", loop); + name = BUF_strdup(buf); + if (((block[loop] = ENGINE_new()) == NULL) || + !ENGINE_set_id(block[loop], id) || + !ENGINE_set_name(block[loop], name)) { + printf("Couldn't create block of ENGINE structures.\n" + "I'll probably also core-dump now, damn.\n"); + goto end; + } + } + for (loop = 0; loop < 512; loop++) { + if (!ENGINE_add(block[loop])) { + printf("\nAdding stopped at %i, (%s,%s)\n", + loop, ENGINE_get_id(block[loop]), + ENGINE_get_name(block[loop])); + goto cleanup_loop; + } else + printf("."); + fflush(stdout); + } + cleanup_loop: + printf("\nAbout to empty the engine-type list\n"); + while ((ptr = ENGINE_get_first()) != NULL) { + if (!ENGINE_remove(ptr)) { + printf("\nRemove failed!\n"); + goto end; + } + ENGINE_free(ptr); + printf("."); + fflush(stdout); + } + for (loop = 0; loop < 512; loop++) { + OPENSSL_free((void *)ENGINE_get_id(block[loop])); + OPENSSL_free((void *)ENGINE_get_name(block[loop])); + } + printf("\nTests completed happily\n"); + to_return = 0; + end: + if (to_return) + ERR_print_errors_fp(stderr); + if (new_h1) + ENGINE_free(new_h1); + if (new_h2) + ENGINE_free(new_h2); + if (new_h3) + ENGINE_free(new_h3); + if (new_h4) + ENGINE_free(new_h4); + for (loop = 0; loop < 512; loop++) + if (block[loop]) + ENGINE_free(block[loop]); + ENGINE_cleanup(); + CRYPTO_cleanup_all_ex_data(); + ERR_free_strings(); + ERR_remove_thread_state(NULL); + CRYPTO_mem_leaks_fp(stderr); + return to_return; +} +#endif diff --git a/libs/openssl/crypto/engine/tb_asnmth.c b/libs/openssl/crypto/engine/tb_asnmth.c new file mode 100644 index 00000000..a1a9b88c --- /dev/null +++ b/libs/openssl/crypto/engine/tb_asnmth.c @@ -0,0 +1,246 @@ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" +#include "asn1_locl.h" +#include + +/* + * If this symbol is defined then ENGINE_get_pkey_asn1_meth_engine(), the + * function that is used by EVP to hook in pkey_asn1_meth code and cache + * defaults (etc), will display brief debugging summaries to stderr with the + * 'nid'. + */ +/* #define ENGINE_PKEY_ASN1_METH_DEBUG */ + +static ENGINE_TABLE *pkey_asn1_meth_table = NULL; + +void ENGINE_unregister_pkey_asn1_meths(ENGINE *e) +{ + engine_table_unregister(&pkey_asn1_meth_table, e); +} + +static void engine_unregister_all_pkey_asn1_meths(void) +{ + engine_table_cleanup(&pkey_asn1_meth_table); +} + +int ENGINE_register_pkey_asn1_meths(ENGINE *e) +{ + if (e->pkey_asn1_meths) { + const int *nids; + int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&pkey_asn1_meth_table, + engine_unregister_all_pkey_asn1_meths, + e, nids, num_nids, 0); + } + return 1; +} + +void ENGINE_register_all_pkey_asn1_meths(void) +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_pkey_asn1_meths(e); +} + +int ENGINE_set_default_pkey_asn1_meths(ENGINE *e) +{ + if (e->pkey_asn1_meths) { + const int *nids; + int num_nids = e->pkey_asn1_meths(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&pkey_asn1_meth_table, + engine_unregister_all_pkey_asn1_meths, + e, nids, num_nids, 1); + } + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references) for a given pkey_asn1_meth 'nid' + */ +ENGINE *ENGINE_get_pkey_asn1_meth_engine(int nid) +{ + return engine_table_select(&pkey_asn1_meth_table, nid); +} + +/* + * Obtains a pkey_asn1_meth implementation from an ENGINE functional + * reference + */ +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth(ENGINE *e, int nid) +{ + EVP_PKEY_ASN1_METHOD *ret; + ENGINE_PKEY_ASN1_METHS_PTR fn = ENGINE_get_pkey_asn1_meths(e); + if (!fn || !fn(e, &ret, NULL, nid)) { + ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_ASN1_METH, + ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); + return NULL; + } + return ret; +} + +/* Gets the pkey_asn1_meth callback from an ENGINE structure */ +ENGINE_PKEY_ASN1_METHS_PTR ENGINE_get_pkey_asn1_meths(const ENGINE *e) +{ + return e->pkey_asn1_meths; +} + +/* Sets the pkey_asn1_meth callback in an ENGINE structure */ +int ENGINE_set_pkey_asn1_meths(ENGINE *e, ENGINE_PKEY_ASN1_METHS_PTR f) +{ + e->pkey_asn1_meths = f; + return 1; +} + +/* + * Internal function to free up EVP_PKEY_ASN1_METHOD structures before an + * ENGINE is destroyed + */ + +void engine_pkey_asn1_meths_free(ENGINE *e) +{ + int i; + EVP_PKEY_ASN1_METHOD *pkm; + if (e->pkey_asn1_meths) { + const int *pknids; + int npknids; + npknids = e->pkey_asn1_meths(e, NULL, &pknids, 0); + for (i = 0; i < npknids; i++) { + if (e->pkey_asn1_meths(e, &pkm, NULL, pknids[i])) { + EVP_PKEY_asn1_free(pkm); + } + } + } +} + +/* + * Find a method based on a string. This does a linear search through all + * implemented algorithms. This is OK in practice because only a small number + * of algorithms are likely to be implemented in an engine and it is not used + * for speed critical operations. + */ + +const EVP_PKEY_ASN1_METHOD *ENGINE_get_pkey_asn1_meth_str(ENGINE *e, + const char *str, + int len) +{ + int i, nidcount; + const int *nids; + EVP_PKEY_ASN1_METHOD *ameth; + if (!e->pkey_asn1_meths) + return NULL; + if (len == -1) + len = strlen(str); + nidcount = e->pkey_asn1_meths(e, NULL, &nids, 0); + for (i = 0; i < nidcount; i++) { + e->pkey_asn1_meths(e, &ameth, NULL, nids[i]); + if (((int)strlen(ameth->pem_str) == len) && + !strncasecmp(ameth->pem_str, str, len)) + return ameth; + } + return NULL; +} + +typedef struct { + ENGINE *e; + const EVP_PKEY_ASN1_METHOD *ameth; + const char *str; + int len; +} ENGINE_FIND_STR; + +static void look_str_cb(int nid, STACK_OF(ENGINE) *sk, ENGINE *def, void *arg) +{ + ENGINE_FIND_STR *lk = arg; + int i; + if (lk->ameth) + return; + for (i = 0; i < sk_ENGINE_num(sk); i++) { + ENGINE *e = sk_ENGINE_value(sk, i); + EVP_PKEY_ASN1_METHOD *ameth; + e->pkey_asn1_meths(e, &ameth, NULL, nid); + if (((int)strlen(ameth->pem_str) == lk->len) && + !strncasecmp(ameth->pem_str, lk->str, lk->len)) { + lk->e = e; + lk->ameth = ameth; + return; + } + } +} + +const EVP_PKEY_ASN1_METHOD *ENGINE_pkey_asn1_find_str(ENGINE **pe, + const char *str, + int len) +{ + ENGINE_FIND_STR fstr; + fstr.e = NULL; + fstr.ameth = NULL; + fstr.str = str; + fstr.len = len; + CRYPTO_w_lock(CRYPTO_LOCK_ENGINE); + engine_table_doall(pkey_asn1_meth_table, look_str_cb, &fstr); + /* If found obtain a structural reference to engine */ + if (fstr.e) { + fstr.e->struct_ref++; + engine_ref_debug(fstr.e, 0, 1) + } + *pe = fstr.e; + CRYPTO_w_unlock(CRYPTO_LOCK_ENGINE); + return fstr.ameth; +} diff --git a/libs/openssl/crypto/engine/tb_cipher.c b/libs/openssl/crypto/engine/tb_cipher.c new file mode 100644 index 00000000..fcfb2efd --- /dev/null +++ b/libs/openssl/crypto/engine/tb_cipher.c @@ -0,0 +1,143 @@ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_cipher_engine(), the function + * that is used by EVP to hook in cipher code and cache defaults (etc), will + * display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_CIPHER_DEBUG */ + +static ENGINE_TABLE *cipher_table = NULL; + +void ENGINE_unregister_ciphers(ENGINE *e) +{ + engine_table_unregister(&cipher_table, e); +} + +static void engine_unregister_all_ciphers(void) +{ + engine_table_cleanup(&cipher_table); +} + +int ENGINE_register_ciphers(ENGINE *e) +{ + if (e->ciphers) { + const int *nids; + int num_nids = e->ciphers(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&cipher_table, + engine_unregister_all_ciphers, e, + nids, num_nids, 0); + } + return 1; +} + +void ENGINE_register_all_ciphers() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_ciphers(e); +} + +int ENGINE_set_default_ciphers(ENGINE *e) +{ + if (e->ciphers) { + const int *nids; + int num_nids = e->ciphers(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&cipher_table, + engine_unregister_all_ciphers, e, + nids, num_nids, 1); + } + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references) for a given cipher 'nid' + */ +ENGINE *ENGINE_get_cipher_engine(int nid) +{ + return engine_table_select(&cipher_table, nid); +} + +/* Obtains a cipher implementation from an ENGINE functional reference */ +const EVP_CIPHER *ENGINE_get_cipher(ENGINE *e, int nid) +{ + const EVP_CIPHER *ret; + ENGINE_CIPHERS_PTR fn = ENGINE_get_ciphers(e); + if (!fn || !fn(e, &ret, NULL, nid)) { + ENGINEerr(ENGINE_F_ENGINE_GET_CIPHER, ENGINE_R_UNIMPLEMENTED_CIPHER); + return NULL; + } + return ret; +} + +/* Gets the cipher callback from an ENGINE structure */ +ENGINE_CIPHERS_PTR ENGINE_get_ciphers(const ENGINE *e) +{ + return e->ciphers; +} + +/* Sets the cipher callback in an ENGINE structure */ +int ENGINE_set_ciphers(ENGINE *e, ENGINE_CIPHERS_PTR f) +{ + e->ciphers = f; + return 1; +} diff --git a/libs/openssl/crypto/engine/tb_dh.c b/libs/openssl/crypto/engine/tb_dh.c new file mode 100644 index 00000000..8114afa6 --- /dev/null +++ b/libs/openssl/crypto/engine/tb_dh.c @@ -0,0 +1,124 @@ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_default_DH(), the function that + * is used by DH to hook in implementation code and cache defaults (etc), + * will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_DH_DEBUG */ + +static ENGINE_TABLE *dh_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_DH(ENGINE *e) +{ + engine_table_unregister(&dh_table, e); +} + +static void engine_unregister_all_DH(void) +{ + engine_table_cleanup(&dh_table); +} + +int ENGINE_register_DH(ENGINE *e) +{ + if (e->dh_meth) + return engine_table_register(&dh_table, + engine_unregister_all_DH, e, &dummy_nid, + 1, 0); + return 1; +} + +void ENGINE_register_all_DH() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_DH(e); +} + +int ENGINE_set_default_DH(ENGINE *e) +{ + if (e->dh_meth) + return engine_table_register(&dh_table, + engine_unregister_all_DH, e, &dummy_nid, + 1, 1); + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). + */ +ENGINE *ENGINE_get_default_DH(void) +{ + return engine_table_select(&dh_table, dummy_nid); +} + +/* Obtains an DH implementation from an ENGINE functional reference */ +const DH_METHOD *ENGINE_get_DH(const ENGINE *e) +{ + return e->dh_meth; +} + +/* Sets an DH implementation in an ENGINE structure */ +int ENGINE_set_DH(ENGINE *e, const DH_METHOD *dh_meth) +{ + e->dh_meth = dh_meth; + return 1; +} diff --git a/libs/openssl/crypto/engine/tb_digest.c b/libs/openssl/crypto/engine/tb_digest.c new file mode 100644 index 00000000..de1ad9c0 --- /dev/null +++ b/libs/openssl/crypto/engine/tb_digest.c @@ -0,0 +1,143 @@ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_digest_engine(), the function + * that is used by EVP to hook in digest code and cache defaults (etc), will + * display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_DIGEST_DEBUG */ + +static ENGINE_TABLE *digest_table = NULL; + +void ENGINE_unregister_digests(ENGINE *e) +{ + engine_table_unregister(&digest_table, e); +} + +static void engine_unregister_all_digests(void) +{ + engine_table_cleanup(&digest_table); +} + +int ENGINE_register_digests(ENGINE *e) +{ + if (e->digests) { + const int *nids; + int num_nids = e->digests(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&digest_table, + engine_unregister_all_digests, e, + nids, num_nids, 0); + } + return 1; +} + +void ENGINE_register_all_digests() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_digests(e); +} + +int ENGINE_set_default_digests(ENGINE *e) +{ + if (e->digests) { + const int *nids; + int num_nids = e->digests(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&digest_table, + engine_unregister_all_digests, e, + nids, num_nids, 1); + } + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references) for a given digest 'nid' + */ +ENGINE *ENGINE_get_digest_engine(int nid) +{ + return engine_table_select(&digest_table, nid); +} + +/* Obtains a digest implementation from an ENGINE functional reference */ +const EVP_MD *ENGINE_get_digest(ENGINE *e, int nid) +{ + const EVP_MD *ret; + ENGINE_DIGESTS_PTR fn = ENGINE_get_digests(e); + if (!fn || !fn(e, &ret, NULL, nid)) { + ENGINEerr(ENGINE_F_ENGINE_GET_DIGEST, ENGINE_R_UNIMPLEMENTED_DIGEST); + return NULL; + } + return ret; +} + +/* Gets the digest callback from an ENGINE structure */ +ENGINE_DIGESTS_PTR ENGINE_get_digests(const ENGINE *e) +{ + return e->digests; +} + +/* Sets the digest callback in an ENGINE structure */ +int ENGINE_set_digests(ENGINE *e, ENGINE_DIGESTS_PTR f) +{ + e->digests = f; + return 1; +} diff --git a/libs/openssl/crypto/engine/tb_dsa.c b/libs/openssl/crypto/engine/tb_dsa.c new file mode 100644 index 00000000..c1f57f14 --- /dev/null +++ b/libs/openssl/crypto/engine/tb_dsa.c @@ -0,0 +1,124 @@ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_default_DSA(), the function that + * is used by DSA to hook in implementation code and cache defaults (etc), + * will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_DSA_DEBUG */ + +static ENGINE_TABLE *dsa_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_DSA(ENGINE *e) +{ + engine_table_unregister(&dsa_table, e); +} + +static void engine_unregister_all_DSA(void) +{ + engine_table_cleanup(&dsa_table); +} + +int ENGINE_register_DSA(ENGINE *e) +{ + if (e->dsa_meth) + return engine_table_register(&dsa_table, + engine_unregister_all_DSA, e, &dummy_nid, + 1, 0); + return 1; +} + +void ENGINE_register_all_DSA() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_DSA(e); +} + +int ENGINE_set_default_DSA(ENGINE *e) +{ + if (e->dsa_meth) + return engine_table_register(&dsa_table, + engine_unregister_all_DSA, e, &dummy_nid, + 1, 1); + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). + */ +ENGINE *ENGINE_get_default_DSA(void) +{ + return engine_table_select(&dsa_table, dummy_nid); +} + +/* Obtains an DSA implementation from an ENGINE functional reference */ +const DSA_METHOD *ENGINE_get_DSA(const ENGINE *e) +{ + return e->dsa_meth; +} + +/* Sets an DSA implementation in an ENGINE structure */ +int ENGINE_set_DSA(ENGINE *e, const DSA_METHOD *dsa_meth) +{ + e->dsa_meth = dsa_meth; + return 1; +} diff --git a/libs/openssl/crypto/engine/tb_ecdh.c b/libs/openssl/crypto/engine/tb_ecdh.c new file mode 100644 index 00000000..c51441be --- /dev/null +++ b/libs/openssl/crypto/engine/tb_ecdh.c @@ -0,0 +1,139 @@ +/* crypto/engine/tb_ecdh.c */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * The Elliptic Curve Public-Key Crypto Library (ECC Code) included + * herein is developed by SUN MICROSYSTEMS, INC., and is contributed + * to the OpenSSL project. + * + * The ECC Code is licensed pursuant to the OpenSSL open source + * license provided below. + * + * The ECDH engine software is originally written by Nils Gura and + * Douglas Stebila of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_default_ECDH(), the function + * that is used by ECDH to hook in implementation code and cache defaults + * (etc), will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_ECDH_DEBUG */ + +static ENGINE_TABLE *ecdh_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_ECDH(ENGINE *e) +{ + engine_table_unregister(&ecdh_table, e); +} + +static void engine_unregister_all_ECDH(void) +{ + engine_table_cleanup(&ecdh_table); +} + +int ENGINE_register_ECDH(ENGINE *e) +{ + if (e->ecdh_meth) + return engine_table_register(&ecdh_table, + engine_unregister_all_ECDH, e, + &dummy_nid, 1, 0); + return 1; +} + +void ENGINE_register_all_ECDH() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_ECDH(e); +} + +int ENGINE_set_default_ECDH(ENGINE *e) +{ + if (e->ecdh_meth) + return engine_table_register(&ecdh_table, + engine_unregister_all_ECDH, e, + &dummy_nid, 1, 1); + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). + */ +ENGINE *ENGINE_get_default_ECDH(void) +{ + return engine_table_select(&ecdh_table, dummy_nid); +} + +/* Obtains an ECDH implementation from an ENGINE functional reference */ +const ECDH_METHOD *ENGINE_get_ECDH(const ENGINE *e) +{ + return e->ecdh_meth; +} + +/* Sets an ECDH implementation in an ENGINE structure */ +int ENGINE_set_ECDH(ENGINE *e, const ECDH_METHOD *ecdh_meth) +{ + e->ecdh_meth = ecdh_meth; + return 1; +} diff --git a/libs/openssl/crypto/engine/tb_ecdsa.c b/libs/openssl/crypto/engine/tb_ecdsa.c new file mode 100644 index 00000000..a8b9be60 --- /dev/null +++ b/libs/openssl/crypto/engine/tb_ecdsa.c @@ -0,0 +1,124 @@ +/* ==================================================================== + * Copyright (c) 2000-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_default_ECDSA(), the function + * that is used by ECDSA to hook in implementation code and cache defaults + * (etc), will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_ECDSA_DEBUG */ + +static ENGINE_TABLE *ecdsa_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_ECDSA(ENGINE *e) +{ + engine_table_unregister(&ecdsa_table, e); +} + +static void engine_unregister_all_ECDSA(void) +{ + engine_table_cleanup(&ecdsa_table); +} + +int ENGINE_register_ECDSA(ENGINE *e) +{ + if (e->ecdsa_meth) + return engine_table_register(&ecdsa_table, + engine_unregister_all_ECDSA, e, + &dummy_nid, 1, 0); + return 1; +} + +void ENGINE_register_all_ECDSA() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_ECDSA(e); +} + +int ENGINE_set_default_ECDSA(ENGINE *e) +{ + if (e->ecdsa_meth) + return engine_table_register(&ecdsa_table, + engine_unregister_all_ECDSA, e, + &dummy_nid, 1, 1); + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). + */ +ENGINE *ENGINE_get_default_ECDSA(void) +{ + return engine_table_select(&ecdsa_table, dummy_nid); +} + +/* Obtains an ECDSA implementation from an ENGINE functional reference */ +const ECDSA_METHOD *ENGINE_get_ECDSA(const ENGINE *e) +{ + return e->ecdsa_meth; +} + +/* Sets an ECDSA implementation in an ENGINE structure */ +int ENGINE_set_ECDSA(ENGINE *e, const ECDSA_METHOD *ecdsa_meth) +{ + e->ecdsa_meth = ecdsa_meth; + return 1; +} diff --git a/libs/openssl/crypto/engine/tb_pkmeth.c b/libs/openssl/crypto/engine/tb_pkmeth.c new file mode 100644 index 00000000..29e65be1 --- /dev/null +++ b/libs/openssl/crypto/engine/tb_pkmeth.c @@ -0,0 +1,166 @@ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" +#include + +/* + * If this symbol is defined then ENGINE_get_pkey_meth_engine(), the function + * that is used by EVP to hook in pkey_meth code and cache defaults (etc), + * will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_PKEY_METH_DEBUG */ + +static ENGINE_TABLE *pkey_meth_table = NULL; + +void ENGINE_unregister_pkey_meths(ENGINE *e) +{ + engine_table_unregister(&pkey_meth_table, e); +} + +static void engine_unregister_all_pkey_meths(void) +{ + engine_table_cleanup(&pkey_meth_table); +} + +int ENGINE_register_pkey_meths(ENGINE *e) +{ + if (e->pkey_meths) { + const int *nids; + int num_nids = e->pkey_meths(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&pkey_meth_table, + engine_unregister_all_pkey_meths, e, + nids, num_nids, 0); + } + return 1; +} + +void ENGINE_register_all_pkey_meths() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_pkey_meths(e); +} + +int ENGINE_set_default_pkey_meths(ENGINE *e) +{ + if (e->pkey_meths) { + const int *nids; + int num_nids = e->pkey_meths(e, NULL, &nids, 0); + if (num_nids > 0) + return engine_table_register(&pkey_meth_table, + engine_unregister_all_pkey_meths, e, + nids, num_nids, 1); + } + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references) for a given pkey_meth 'nid' + */ +ENGINE *ENGINE_get_pkey_meth_engine(int nid) +{ + return engine_table_select(&pkey_meth_table, nid); +} + +/* Obtains a pkey_meth implementation from an ENGINE functional reference */ +const EVP_PKEY_METHOD *ENGINE_get_pkey_meth(ENGINE *e, int nid) +{ + EVP_PKEY_METHOD *ret; + ENGINE_PKEY_METHS_PTR fn = ENGINE_get_pkey_meths(e); + if (!fn || !fn(e, &ret, NULL, nid)) { + ENGINEerr(ENGINE_F_ENGINE_GET_PKEY_METH, + ENGINE_R_UNIMPLEMENTED_PUBLIC_KEY_METHOD); + return NULL; + } + return ret; +} + +/* Gets the pkey_meth callback from an ENGINE structure */ +ENGINE_PKEY_METHS_PTR ENGINE_get_pkey_meths(const ENGINE *e) +{ + return e->pkey_meths; +} + +/* Sets the pkey_meth callback in an ENGINE structure */ +int ENGINE_set_pkey_meths(ENGINE *e, ENGINE_PKEY_METHS_PTR f) +{ + e->pkey_meths = f; + return 1; +} + +/* + * Internal function to free up EVP_PKEY_METHOD structures before an ENGINE + * is destroyed + */ + +void engine_pkey_meths_free(ENGINE *e) +{ + int i; + EVP_PKEY_METHOD *pkm; + if (e->pkey_meths) { + const int *pknids; + int npknids; + npknids = e->pkey_meths(e, NULL, &pknids, 0); + for (i = 0; i < npknids; i++) { + if (e->pkey_meths(e, &pkm, NULL, pknids[i])) { + EVP_PKEY_meth_free(pkm); + } + } + } +} diff --git a/libs/openssl/crypto/engine/tb_rand.c b/libs/openssl/crypto/engine/tb_rand.c new file mode 100644 index 00000000..a522264d --- /dev/null +++ b/libs/openssl/crypto/engine/tb_rand.c @@ -0,0 +1,124 @@ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_default_RAND(), the function + * that is used by RAND to hook in implementation code and cache defaults + * (etc), will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_RAND_DEBUG */ + +static ENGINE_TABLE *rand_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_RAND(ENGINE *e) +{ + engine_table_unregister(&rand_table, e); +} + +static void engine_unregister_all_RAND(void) +{ + engine_table_cleanup(&rand_table); +} + +int ENGINE_register_RAND(ENGINE *e) +{ + if (e->rand_meth) + return engine_table_register(&rand_table, + engine_unregister_all_RAND, e, + &dummy_nid, 1, 0); + return 1; +} + +void ENGINE_register_all_RAND() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_RAND(e); +} + +int ENGINE_set_default_RAND(ENGINE *e) +{ + if (e->rand_meth) + return engine_table_register(&rand_table, + engine_unregister_all_RAND, e, + &dummy_nid, 1, 1); + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). + */ +ENGINE *ENGINE_get_default_RAND(void) +{ + return engine_table_select(&rand_table, dummy_nid); +} + +/* Obtains an RAND implementation from an ENGINE functional reference */ +const RAND_METHOD *ENGINE_get_RAND(const ENGINE *e) +{ + return e->rand_meth; +} + +/* Sets an RAND implementation in an ENGINE structure */ +int ENGINE_set_RAND(ENGINE *e, const RAND_METHOD *rand_meth) +{ + e->rand_meth = rand_meth; + return 1; +} diff --git a/libs/openssl/crypto/engine/tb_rsa.c b/libs/openssl/crypto/engine/tb_rsa.c new file mode 100644 index 00000000..2790a821 --- /dev/null +++ b/libs/openssl/crypto/engine/tb_rsa.c @@ -0,0 +1,124 @@ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_default_RSA(), the function that + * is used by RSA to hook in implementation code and cache defaults (etc), + * will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_RSA_DEBUG */ + +static ENGINE_TABLE *rsa_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_RSA(ENGINE *e) +{ + engine_table_unregister(&rsa_table, e); +} + +static void engine_unregister_all_RSA(void) +{ + engine_table_cleanup(&rsa_table); +} + +int ENGINE_register_RSA(ENGINE *e) +{ + if (e->rsa_meth) + return engine_table_register(&rsa_table, + engine_unregister_all_RSA, e, &dummy_nid, + 1, 0); + return 1; +} + +void ENGINE_register_all_RSA() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_RSA(e); +} + +int ENGINE_set_default_RSA(ENGINE *e) +{ + if (e->rsa_meth) + return engine_table_register(&rsa_table, + engine_unregister_all_RSA, e, &dummy_nid, + 1, 1); + return 1; +} + +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). + */ +ENGINE *ENGINE_get_default_RSA(void) +{ + return engine_table_select(&rsa_table, dummy_nid); +} + +/* Obtains an RSA implementation from an ENGINE functional reference */ +const RSA_METHOD *ENGINE_get_RSA(const ENGINE *e) +{ + return e->rsa_meth; +} + +/* Sets an RSA implementation in an ENGINE structure */ +int ENGINE_set_RSA(ENGINE *e, const RSA_METHOD *rsa_meth) +{ + e->rsa_meth = rsa_meth; + return 1; +} diff --git a/libs/openssl/crypto/engine/tb_store.c b/libs/openssl/crypto/engine/tb_store.c new file mode 100644 index 00000000..1eab49d7 --- /dev/null +++ b/libs/openssl/crypto/engine/tb_store.c @@ -0,0 +1,129 @@ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "eng_int.h" + +/* + * If this symbol is defined then ENGINE_get_default_STORE(), the function + * that is used by STORE to hook in implementation code and cache defaults + * (etc), will display brief debugging summaries to stderr with the 'nid'. + */ +/* #define ENGINE_STORE_DEBUG */ + +static ENGINE_TABLE *store_table = NULL; +static const int dummy_nid = 1; + +void ENGINE_unregister_STORE(ENGINE *e) +{ + engine_table_unregister(&store_table, e); +} + +static void engine_unregister_all_STORE(void) +{ + engine_table_cleanup(&store_table); +} + +int ENGINE_register_STORE(ENGINE *e) +{ + if (e->store_meth) + return engine_table_register(&store_table, + engine_unregister_all_STORE, e, + &dummy_nid, 1, 0); + return 1; +} + +void ENGINE_register_all_STORE() +{ + ENGINE *e; + + for (e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) + ENGINE_register_STORE(e); +} + +/* The following two functions are removed because they're useless. */ +#if 0 +int ENGINE_set_default_STORE(ENGINE *e) +{ + if (e->store_meth) + return engine_table_register(&store_table, + engine_unregister_all_STORE, e, + &dummy_nid, 1, 1); + return 1; +} +#endif + +#if 0 +/* + * Exposed API function to get a functional reference from the implementation + * table (ie. try to get a functional reference from the tabled structural + * references). + */ +ENGINE *ENGINE_get_default_STORE(void) +{ + return engine_table_select(&store_table, dummy_nid); +} +#endif + +/* Obtains an STORE implementation from an ENGINE functional reference */ +const STORE_METHOD *ENGINE_get_STORE(const ENGINE *e) +{ + return e->store_meth; +} + +/* Sets an STORE implementation in an ENGINE structure */ +int ENGINE_set_STORE(ENGINE *e, const STORE_METHOD *store_meth) +{ + e->store_meth = store_meth; + return 1; +} diff --git a/libs/openssl/crypto/err/err.c b/libs/openssl/crypto/err/err.c new file mode 100644 index 00000000..e77d963b --- /dev/null +++ b/libs/openssl/crypto/err/err.c @@ -0,0 +1,1145 @@ +/* crypto/err/err.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include + +DECLARE_LHASH_OF(ERR_STRING_DATA); +DECLARE_LHASH_OF(ERR_STATE); + +static void err_load_strings(int lib, ERR_STRING_DATA *str); + +static void ERR_STATE_free(ERR_STATE *s); +#ifndef OPENSSL_NO_ERR +static ERR_STRING_DATA ERR_str_libraries[] = { + {ERR_PACK(ERR_LIB_NONE, 0, 0), "unknown library"}, + {ERR_PACK(ERR_LIB_SYS, 0, 0), "system library"}, + {ERR_PACK(ERR_LIB_BN, 0, 0), "bignum routines"}, + {ERR_PACK(ERR_LIB_RSA, 0, 0), "rsa routines"}, + {ERR_PACK(ERR_LIB_DH, 0, 0), "Diffie-Hellman routines"}, + {ERR_PACK(ERR_LIB_EVP, 0, 0), "digital envelope routines"}, + {ERR_PACK(ERR_LIB_BUF, 0, 0), "memory buffer routines"}, + {ERR_PACK(ERR_LIB_OBJ, 0, 0), "object identifier routines"}, + {ERR_PACK(ERR_LIB_PEM, 0, 0), "PEM routines"}, + {ERR_PACK(ERR_LIB_DSA, 0, 0), "dsa routines"}, + {ERR_PACK(ERR_LIB_X509, 0, 0), "x509 certificate routines"}, + {ERR_PACK(ERR_LIB_ASN1, 0, 0), "asn1 encoding routines"}, + {ERR_PACK(ERR_LIB_CONF, 0, 0), "configuration file routines"}, + {ERR_PACK(ERR_LIB_CRYPTO, 0, 0), "common libcrypto routines"}, + {ERR_PACK(ERR_LIB_EC, 0, 0), "elliptic curve routines"}, + {ERR_PACK(ERR_LIB_SSL, 0, 0), "SSL routines"}, + {ERR_PACK(ERR_LIB_BIO, 0, 0), "BIO routines"}, + {ERR_PACK(ERR_LIB_PKCS7, 0, 0), "PKCS7 routines"}, + {ERR_PACK(ERR_LIB_X509V3, 0, 0), "X509 V3 routines"}, + {ERR_PACK(ERR_LIB_PKCS12, 0, 0), "PKCS12 routines"}, + {ERR_PACK(ERR_LIB_RAND, 0, 0), "random number generator"}, + {ERR_PACK(ERR_LIB_DSO, 0, 0), "DSO support routines"}, + {ERR_PACK(ERR_LIB_TS, 0, 0), "time stamp routines"}, + {ERR_PACK(ERR_LIB_ENGINE, 0, 0), "engine routines"}, + {ERR_PACK(ERR_LIB_OCSP, 0, 0), "OCSP routines"}, + {ERR_PACK(ERR_LIB_FIPS, 0, 0), "FIPS routines"}, + {ERR_PACK(ERR_LIB_CMS, 0, 0), "CMS routines"}, + {ERR_PACK(ERR_LIB_HMAC, 0, 0), "HMAC routines"}, + {0, NULL}, +}; + +static ERR_STRING_DATA ERR_str_functs[] = { + {ERR_PACK(0, SYS_F_FOPEN, 0), "fopen"}, + {ERR_PACK(0, SYS_F_CONNECT, 0), "connect"}, + {ERR_PACK(0, SYS_F_GETSERVBYNAME, 0), "getservbyname"}, + {ERR_PACK(0, SYS_F_SOCKET, 0), "socket"}, + {ERR_PACK(0, SYS_F_IOCTLSOCKET, 0), "ioctlsocket"}, + {ERR_PACK(0, SYS_F_BIND, 0), "bind"}, + {ERR_PACK(0, SYS_F_LISTEN, 0), "listen"}, + {ERR_PACK(0, SYS_F_ACCEPT, 0), "accept"}, +# ifdef OPENSSL_SYS_WINDOWS + {ERR_PACK(0, SYS_F_WSASTARTUP, 0), "WSAstartup"}, +# endif + {ERR_PACK(0, SYS_F_OPENDIR, 0), "opendir"}, + {ERR_PACK(0, SYS_F_FREAD, 0), "fread"}, + {0, NULL}, +}; + +static ERR_STRING_DATA ERR_str_reasons[] = { + {ERR_R_SYS_LIB, "system lib"}, + {ERR_R_BN_LIB, "BN lib"}, + {ERR_R_RSA_LIB, "RSA lib"}, + {ERR_R_DH_LIB, "DH lib"}, + {ERR_R_EVP_LIB, "EVP lib"}, + {ERR_R_BUF_LIB, "BUF lib"}, + {ERR_R_OBJ_LIB, "OBJ lib"}, + {ERR_R_PEM_LIB, "PEM lib"}, + {ERR_R_DSA_LIB, "DSA lib"}, + {ERR_R_X509_LIB, "X509 lib"}, + {ERR_R_ASN1_LIB, "ASN1 lib"}, + {ERR_R_CONF_LIB, "CONF lib"}, + {ERR_R_CRYPTO_LIB, "CRYPTO lib"}, + {ERR_R_EC_LIB, "EC lib"}, + {ERR_R_SSL_LIB, "SSL lib"}, + {ERR_R_BIO_LIB, "BIO lib"}, + {ERR_R_PKCS7_LIB, "PKCS7 lib"}, + {ERR_R_X509V3_LIB, "X509V3 lib"}, + {ERR_R_PKCS12_LIB, "PKCS12 lib"}, + {ERR_R_RAND_LIB, "RAND lib"}, + {ERR_R_DSO_LIB, "DSO lib"}, + {ERR_R_ENGINE_LIB, "ENGINE lib"}, + {ERR_R_OCSP_LIB, "OCSP lib"}, + {ERR_R_TS_LIB, "TS lib"}, + + {ERR_R_NESTED_ASN1_ERROR, "nested asn1 error"}, + {ERR_R_BAD_ASN1_OBJECT_HEADER, "bad asn1 object header"}, + {ERR_R_BAD_GET_ASN1_OBJECT_CALL, "bad get asn1 object call"}, + {ERR_R_EXPECTING_AN_ASN1_SEQUENCE, "expecting an asn1 sequence"}, + {ERR_R_ASN1_LENGTH_MISMATCH, "asn1 length mismatch"}, + {ERR_R_MISSING_ASN1_EOS, "missing asn1 eos"}, + + {ERR_R_FATAL, "fatal"}, + {ERR_R_MALLOC_FAILURE, "malloc failure"}, + {ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED, + "called a function you should not call"}, + {ERR_R_PASSED_NULL_PARAMETER, "passed a null parameter"}, + {ERR_R_INTERNAL_ERROR, "internal error"}, + {ERR_R_DISABLED, "called a function that was disabled at compile-time"}, + + {0, NULL}, +}; +#endif + +/* Define the predeclared (but externally opaque) "ERR_FNS" type */ +struct st_ERR_FNS { + /* Works on the "error_hash" string table */ + LHASH_OF(ERR_STRING_DATA) *(*cb_err_get) (int create); + void (*cb_err_del) (void); + ERR_STRING_DATA *(*cb_err_get_item) (const ERR_STRING_DATA *); + ERR_STRING_DATA *(*cb_err_set_item) (ERR_STRING_DATA *); + ERR_STRING_DATA *(*cb_err_del_item) (ERR_STRING_DATA *); + /* Works on the "thread_hash" error-state table */ + LHASH_OF(ERR_STATE) *(*cb_thread_get) (int create); + void (*cb_thread_release) (LHASH_OF(ERR_STATE) **hash); + ERR_STATE *(*cb_thread_get_item) (const ERR_STATE *); + ERR_STATE *(*cb_thread_set_item) (ERR_STATE *); + void (*cb_thread_del_item) (const ERR_STATE *); + /* Returns the next available error "library" numbers */ + int (*cb_get_next_lib) (void); +}; + +/* Predeclarations of the "err_defaults" functions */ +static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create); +static void int_err_del(void); +static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *); +static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *); +static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *); +static LHASH_OF(ERR_STATE) *int_thread_get(int create); +static void int_thread_release(LHASH_OF(ERR_STATE) **hash); +static ERR_STATE *int_thread_get_item(const ERR_STATE *); +static ERR_STATE *int_thread_set_item(ERR_STATE *); +static void int_thread_del_item(const ERR_STATE *); +static int int_err_get_next_lib(void); +/* The static ERR_FNS table using these defaults functions */ +static const ERR_FNS err_defaults = { + int_err_get, + int_err_del, + int_err_get_item, + int_err_set_item, + int_err_del_item, + int_thread_get, + int_thread_release, + int_thread_get_item, + int_thread_set_item, + int_thread_del_item, + int_err_get_next_lib +}; + +/* The replacable table of ERR_FNS functions we use at run-time */ +static const ERR_FNS *err_fns = NULL; + +/* Eg. rather than using "err_get()", use "ERRFN(err_get)()". */ +#define ERRFN(a) err_fns->cb_##a + +/* + * The internal state used by "err_defaults" - as such, the setting, reading, + * creating, and deleting of this data should only be permitted via the + * "err_defaults" functions. This way, a linked module can completely defer + * all ERR state operation (together with requisite locking) to the + * implementations and state in the loading application. + */ +static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL; +static LHASH_OF(ERR_STATE) *int_thread_hash = NULL; +static int int_thread_hash_references = 0; +static int int_err_library_number = ERR_LIB_USER; + +/* + * Internal function that checks whether "err_fns" is set and if not, sets it + * to the defaults. + */ +static void err_fns_check(void) +{ + if (err_fns) + return; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!err_fns) + err_fns = &err_defaults; + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); +} + +/* API functions to get or set the underlying ERR functions. */ + +const ERR_FNS *ERR_get_implementation(void) +{ + err_fns_check(); + return err_fns; +} + +int ERR_set_implementation(const ERR_FNS *fns) +{ + int ret = 0; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + /* + * It's too late if 'err_fns' is non-NULL. BTW: not much point setting an + * error is there?! + */ + if (!err_fns) { + err_fns = fns; + ret = 1; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + return ret; +} + +/* + * These are the callbacks provided to "lh_new()" when creating the LHASH + * tables internal to the "err_defaults" implementation. + */ + +static unsigned long get_error_values(int inc, int top, const char **file, + int *line, const char **data, + int *flags); + +/* The internal functions used in the "err_defaults" implementation */ + +static unsigned long err_string_data_hash(const ERR_STRING_DATA *a) +{ + unsigned long ret, l; + + l = a->error; + ret = l ^ ERR_GET_LIB(l) ^ ERR_GET_FUNC(l); + return (ret ^ ret % 19 * 13); +} + +static IMPLEMENT_LHASH_HASH_FN(err_string_data, ERR_STRING_DATA) + +static int err_string_data_cmp(const ERR_STRING_DATA *a, + const ERR_STRING_DATA *b) +{ + return (int)(a->error - b->error); +} + +static IMPLEMENT_LHASH_COMP_FN(err_string_data, ERR_STRING_DATA) + +static LHASH_OF(ERR_STRING_DATA) *int_err_get(int create) +{ + LHASH_OF(ERR_STRING_DATA) *ret = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!int_error_hash && create) { + CRYPTO_push_info("int_err_get (err.c)"); + int_error_hash = lh_ERR_STRING_DATA_new(); + CRYPTO_pop_info(); + } + if (int_error_hash) + ret = int_error_hash; + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return ret; +} + +static void int_err_del(void) +{ + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (int_error_hash) { + lh_ERR_STRING_DATA_free(int_error_hash); + int_error_hash = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); +} + +static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) +{ + ERR_STRING_DATA *p; + LHASH_OF(ERR_STRING_DATA) *hash; + + err_fns_check(); + hash = ERRFN(err_get) (0); + if (!hash) + return NULL; + + CRYPTO_r_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STRING_DATA_retrieve(hash, d); + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + + return p; +} + +static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *d) +{ + ERR_STRING_DATA *p; + LHASH_OF(ERR_STRING_DATA) *hash; + + err_fns_check(); + hash = ERRFN(err_get) (1); + if (!hash) + return NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STRING_DATA_insert(hash, d); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return p; +} + +static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d) +{ + ERR_STRING_DATA *p; + LHASH_OF(ERR_STRING_DATA) *hash; + + err_fns_check(); + hash = ERRFN(err_get) (0); + if (!hash) + return NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STRING_DATA_delete(hash, d); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return p; +} + +static unsigned long err_state_hash(const ERR_STATE *a) +{ + return CRYPTO_THREADID_hash(&a->tid) * 13; +} + +static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE) + +static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b) +{ + return CRYPTO_THREADID_cmp(&a->tid, &b->tid); +} + +static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE) + +static LHASH_OF(ERR_STATE) *int_thread_get(int create) +{ + LHASH_OF(ERR_STATE) *ret = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!int_thread_hash && create) { + CRYPTO_push_info("int_thread_get (err.c)"); + int_thread_hash = lh_ERR_STATE_new(); + CRYPTO_pop_info(); + } + if (int_thread_hash) { + int_thread_hash_references++; + ret = int_thread_hash; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + return ret; +} + +static void int_thread_release(LHASH_OF(ERR_STATE) **hash) +{ + int i; + + if (hash == NULL || *hash == NULL) + return; + + i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR); + +#ifdef REF_PRINT + fprintf(stderr, "%4d:%s\n", int_thread_hash_references, "ERR"); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "int_thread_release, bad reference count\n"); + abort(); /* ok */ + } +#endif + *hash = NULL; +} + +static ERR_STATE *int_thread_get_item(const ERR_STATE *d) +{ + ERR_STATE *p; + LHASH_OF(ERR_STATE) *hash; + + err_fns_check(); + hash = ERRFN(thread_get) (0); + if (!hash) + return NULL; + + CRYPTO_r_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STATE_retrieve(hash, d); + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + + ERRFN(thread_release) (&hash); + return p; +} + +static ERR_STATE *int_thread_set_item(ERR_STATE *d) +{ + ERR_STATE *p; + LHASH_OF(ERR_STATE) *hash; + + err_fns_check(); + hash = ERRFN(thread_get) (1); + if (!hash) + return NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STATE_insert(hash, d); + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + ERRFN(thread_release) (&hash); + return p; +} + +static void int_thread_del_item(const ERR_STATE *d) +{ + ERR_STATE *p; + LHASH_OF(ERR_STATE) *hash; + + err_fns_check(); + hash = ERRFN(thread_get) (0); + if (!hash) + return; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + p = lh_ERR_STATE_delete(hash, d); + /* make sure we don't leak memory */ + if (int_thread_hash_references == 1 + && int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0) { + lh_ERR_STATE_free(int_thread_hash); + int_thread_hash = NULL; + } + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + ERRFN(thread_release) (&hash); + if (p) + ERR_STATE_free(p); +} + +static int int_err_get_next_lib(void) +{ + int ret; + + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + ret = int_err_library_number++; + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + + return ret; +} + +#ifndef OPENSSL_NO_ERR +# define NUM_SYS_STR_REASONS 127 +# define LEN_SYS_STR_REASON 32 + +static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1]; +/* + * SYS_str_reasons is filled with copies of strerror() results at + * initialization. 'errno' values up to 127 should cover all usual errors, + * others will be displayed numerically by ERR_error_string. It is crucial + * that we have something for each reason code that occurs in + * ERR_str_reasons, or bogus reason strings will be returned for SYSerr(), + * which always gets an errno value and never one of those 'standard' reason + * codes. + */ + +static void build_SYS_str_reasons(void) +{ + /* OPENSSL_malloc cannot be used here, use static storage instead */ + static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON]; + int i; + static int init = 1; + + CRYPTO_r_lock(CRYPTO_LOCK_ERR); + if (!init) { + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + return; + } + + CRYPTO_r_unlock(CRYPTO_LOCK_ERR); + CRYPTO_w_lock(CRYPTO_LOCK_ERR); + if (!init) { + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); + return; + } + + for (i = 1; i <= NUM_SYS_STR_REASONS; i++) { + ERR_STRING_DATA *str = &SYS_str_reasons[i - 1]; + + str->error = (unsigned long)i; + if (str->string == NULL) { + char (*dest)[LEN_SYS_STR_REASON] = &(strerror_tab[i - 1]); + char *src = strerror(i); + if (src != NULL) { + strncpy(*dest, src, sizeof *dest); + (*dest)[sizeof *dest - 1] = '\0'; + str->string = *dest; + } + } + if (str->string == NULL) + str->string = "unknown"; + } + + /* + * Now we still have SYS_str_reasons[NUM_SYS_STR_REASONS] = {0, NULL}, as + * required by ERR_load_strings. + */ + + init = 0; + + CRYPTO_w_unlock(CRYPTO_LOCK_ERR); +} +#endif + +#define err_clear_data(p,i) \ + do { \ + if (((p)->err_data[i] != NULL) && \ + (p)->err_data_flags[i] & ERR_TXT_MALLOCED) \ + { \ + OPENSSL_free((p)->err_data[i]); \ + (p)->err_data[i]=NULL; \ + } \ + (p)->err_data_flags[i]=0; \ + } while(0) + +#define err_clear(p,i) \ + do { \ + (p)->err_flags[i]=0; \ + (p)->err_buffer[i]=0; \ + err_clear_data(p,i); \ + (p)->err_file[i]=NULL; \ + (p)->err_line[i]= -1; \ + } while(0) + +static void ERR_STATE_free(ERR_STATE *s) +{ + int i; + + if (s == NULL) + return; + + for (i = 0; i < ERR_NUM_ERRORS; i++) { + err_clear_data(s, i); + } + OPENSSL_free(s); +} + +void ERR_load_ERR_strings(void) +{ + err_fns_check(); +#ifndef OPENSSL_NO_ERR + err_load_strings(0, ERR_str_libraries); + err_load_strings(0, ERR_str_reasons); + err_load_strings(ERR_LIB_SYS, ERR_str_functs); + build_SYS_str_reasons(); + err_load_strings(ERR_LIB_SYS, SYS_str_reasons); +#endif +} + +static void err_load_strings(int lib, ERR_STRING_DATA *str) +{ + while (str->error) { + if (lib) + str->error |= ERR_PACK(lib, 0, 0); + ERRFN(err_set_item) (str); + str++; + } +} + +void ERR_load_strings(int lib, ERR_STRING_DATA *str) +{ + ERR_load_ERR_strings(); + err_load_strings(lib, str); +} + +void ERR_unload_strings(int lib, ERR_STRING_DATA *str) +{ + while (str->error) { + if (lib) + str->error |= ERR_PACK(lib, 0, 0); + ERRFN(err_del_item) (str); + str++; + } +} + +void ERR_free_strings(void) +{ + err_fns_check(); + ERRFN(err_del) (); +} + +/********************************************************/ + +void ERR_put_error(int lib, int func, int reason, const char *file, int line) +{ + ERR_STATE *es; + +#ifdef _OSD_POSIX + /* + * In the BS2000-OSD POSIX subsystem, the compiler generates path names + * in the form "*POSIX(/etc/passwd)". This dirty hack strips them to + * something sensible. @@@ We shouldn't modify a const string, though. + */ + if (strncmp(file, "*POSIX(", sizeof("*POSIX(") - 1) == 0) { + char *end; + + /* Skip the "*POSIX(" prefix */ + file += sizeof("*POSIX(") - 1; + end = &file[strlen(file) - 1]; + if (*end == ')') + *end = '\0'; + /* Optional: use the basename of the path only. */ + if ((end = strrchr(file, '/')) != NULL) + file = &end[1]; + } +#endif + es = ERR_get_state(); + + es->top = (es->top + 1) % ERR_NUM_ERRORS; + if (es->top == es->bottom) + es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS; + es->err_flags[es->top] = 0; + es->err_buffer[es->top] = ERR_PACK(lib, func, reason); + es->err_file[es->top] = file; + es->err_line[es->top] = line; + err_clear_data(es, es->top); +} + +void ERR_clear_error(void) +{ + int i; + ERR_STATE *es; + + es = ERR_get_state(); + + for (i = 0; i < ERR_NUM_ERRORS; i++) { + err_clear(es, i); + } + es->top = es->bottom = 0; +} + +unsigned long ERR_get_error(void) +{ + return (get_error_values(1, 0, NULL, NULL, NULL, NULL)); +} + +unsigned long ERR_get_error_line(const char **file, int *line) +{ + return (get_error_values(1, 0, file, line, NULL, NULL)); +} + +unsigned long ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags) +{ + return (get_error_values(1, 0, file, line, data, flags)); +} + +unsigned long ERR_peek_error(void) +{ + return (get_error_values(0, 0, NULL, NULL, NULL, NULL)); +} + +unsigned long ERR_peek_error_line(const char **file, int *line) +{ + return (get_error_values(0, 0, file, line, NULL, NULL)); +} + +unsigned long ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags) +{ + return (get_error_values(0, 0, file, line, data, flags)); +} + +unsigned long ERR_peek_last_error(void) +{ + return (get_error_values(0, 1, NULL, NULL, NULL, NULL)); +} + +unsigned long ERR_peek_last_error_line(const char **file, int *line) +{ + return (get_error_values(0, 1, file, line, NULL, NULL)); +} + +unsigned long ERR_peek_last_error_line_data(const char **file, int *line, + const char **data, int *flags) +{ + return (get_error_values(0, 1, file, line, data, flags)); +} + +static unsigned long get_error_values(int inc, int top, const char **file, + int *line, const char **data, + int *flags) +{ + int i = 0; + ERR_STATE *es; + unsigned long ret; + + es = ERR_get_state(); + + if (inc && top) { + if (file) + *file = ""; + if (line) + *line = 0; + if (data) + *data = ""; + if (flags) + *flags = 0; + + return ERR_R_INTERNAL_ERROR; + } + + if (es->bottom == es->top) + return 0; + if (top) + i = es->top; /* last error */ + else + i = (es->bottom + 1) % ERR_NUM_ERRORS; /* first error */ + + ret = es->err_buffer[i]; + if (inc) { + es->bottom = i; + es->err_buffer[i] = 0; + } + + if ((file != NULL) && (line != NULL)) { + if (es->err_file[i] == NULL) { + *file = "NA"; + if (line != NULL) + *line = 0; + } else { + *file = es->err_file[i]; + if (line != NULL) + *line = es->err_line[i]; + } + } + + if (data == NULL) { + if (inc) { + err_clear_data(es, i); + } + } else { + if (es->err_data[i] == NULL) { + *data = ""; + if (flags != NULL) + *flags = 0; + } else { + *data = es->err_data[i]; + if (flags != NULL) + *flags = es->err_data_flags[i]; + } + } + return ret; +} + +void ERR_error_string_n(unsigned long e, char *buf, size_t len) +{ + char lsbuf[64], fsbuf[64], rsbuf[64]; + const char *ls, *fs, *rs; + unsigned long l, f, r; + + l = ERR_GET_LIB(e); + f = ERR_GET_FUNC(e); + r = ERR_GET_REASON(e); + + ls = ERR_lib_error_string(e); + fs = ERR_func_error_string(e); + rs = ERR_reason_error_string(e); + + if (ls == NULL) + BIO_snprintf(lsbuf, sizeof(lsbuf), "lib(%lu)", l); + if (fs == NULL) + BIO_snprintf(fsbuf, sizeof(fsbuf), "func(%lu)", f); + if (rs == NULL) + BIO_snprintf(rsbuf, sizeof(rsbuf), "reason(%lu)", r); + + BIO_snprintf(buf, len, "error:%08lX:%s:%s:%s", e, ls ? ls : lsbuf, + fs ? fs : fsbuf, rs ? rs : rsbuf); + if (strlen(buf) == len - 1) { + /* + * output may be truncated; make sure we always have 5 + * colon-separated fields, i.e. 4 colons ... + */ +#define NUM_COLONS 4 + if (len > NUM_COLONS) { /* ... if possible */ + int i; + char *s = buf; + + for (i = 0; i < NUM_COLONS; i++) { + char *colon = strchr(s, ':'); + if (colon == NULL || colon > &buf[len - 1] - NUM_COLONS + i) { + /* + * set colon no. i at last possible position (buf[len-1] + * is the terminating 0) + */ + colon = &buf[len - 1] - NUM_COLONS + i; + *colon = ':'; + } + s = colon + 1; + } + } + } +} + +/* BAD for multi-threading: uses a local buffer if ret == NULL */ +/* + * ERR_error_string_n should be used instead for ret != NULL as + * ERR_error_string cannot know how large the buffer is + */ +char *ERR_error_string(unsigned long e, char *ret) +{ + static char buf[256]; + + if (ret == NULL) + ret = buf; + ERR_error_string_n(e, ret, 256); + + return ret; +} + +LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void) +{ + err_fns_check(); + return ERRFN(err_get) (0); +} + +LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void) +{ + err_fns_check(); + return ERRFN(thread_get) (0); +} + +void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash) +{ + err_fns_check(); + ERRFN(thread_release) (hash); +} + +const char *ERR_lib_error_string(unsigned long e) +{ + ERR_STRING_DATA d, *p; + unsigned long l; + + err_fns_check(); + l = ERR_GET_LIB(e); + d.error = ERR_PACK(l, 0, 0); + p = ERRFN(err_get_item) (&d); + return ((p == NULL) ? NULL : p->string); +} + +const char *ERR_func_error_string(unsigned long e) +{ + ERR_STRING_DATA d, *p; + unsigned long l, f; + + err_fns_check(); + l = ERR_GET_LIB(e); + f = ERR_GET_FUNC(e); + d.error = ERR_PACK(l, f, 0); + p = ERRFN(err_get_item) (&d); + return ((p == NULL) ? NULL : p->string); +} + +const char *ERR_reason_error_string(unsigned long e) +{ + ERR_STRING_DATA d, *p = NULL; + unsigned long l, r; + + err_fns_check(); + l = ERR_GET_LIB(e); + r = ERR_GET_REASON(e); + d.error = ERR_PACK(l, 0, r); + p = ERRFN(err_get_item) (&d); + if (!p) { + d.error = ERR_PACK(0, 0, r); + p = ERRFN(err_get_item) (&d); + } + return ((p == NULL) ? NULL : p->string); +} + +void ERR_remove_thread_state(const CRYPTO_THREADID *id) +{ + ERR_STATE tmp; + + if (id) + CRYPTO_THREADID_cpy(&tmp.tid, id); + else + CRYPTO_THREADID_current(&tmp.tid); + err_fns_check(); + /* + * thread_del_item automatically destroys the LHASH if the number of + * items reaches zero. + */ + ERRFN(thread_del_item) (&tmp); +} + +#ifndef OPENSSL_NO_DEPRECATED +void ERR_remove_state(unsigned long pid) +{ + ERR_remove_thread_state(NULL); +} +#endif + +ERR_STATE *ERR_get_state(void) +{ + static ERR_STATE fallback; + ERR_STATE *ret, tmp, *tmpp = NULL; + int i; + CRYPTO_THREADID tid; + + err_fns_check(); + CRYPTO_THREADID_current(&tid); + CRYPTO_THREADID_cpy(&tmp.tid, &tid); + ret = ERRFN(thread_get_item) (&tmp); + + /* ret == the error state, if NULL, make a new one */ + if (ret == NULL) { + ret = (ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE)); + if (ret == NULL) + return (&fallback); + CRYPTO_THREADID_cpy(&ret->tid, &tid); + ret->top = 0; + ret->bottom = 0; + for (i = 0; i < ERR_NUM_ERRORS; i++) { + ret->err_data[i] = NULL; + ret->err_data_flags[i] = 0; + } + tmpp = ERRFN(thread_set_item) (ret); + /* To check if insertion failed, do a get. */ + if (ERRFN(thread_get_item) (ret) != ret) { + ERR_STATE_free(ret); /* could not insert it */ + return (&fallback); + } + /* + * If a race occured in this function and we came second, tmpp is the + * first one that we just replaced. + */ + if (tmpp) + ERR_STATE_free(tmpp); + } + return ret; +} + +int ERR_get_next_error_library(void) +{ + err_fns_check(); + return ERRFN(get_next_lib) (); +} + +void ERR_set_error_data(char *data, int flags) +{ + ERR_STATE *es; + int i; + + es = ERR_get_state(); + + i = es->top; + if (i == 0) + i = ERR_NUM_ERRORS - 1; + + err_clear_data(es, i); + es->err_data[i] = data; + es->err_data_flags[i] = flags; +} + +void ERR_add_error_data(int num, ...) +{ + va_list args; + va_start(args, num); + ERR_add_error_vdata(num, args); + va_end(args); +} + +void ERR_add_error_vdata(int num, va_list args) +{ + int i, n, s; + char *str, *p, *a; + + s = 80; + str = OPENSSL_malloc(s + 1); + if (str == NULL) + return; + str[0] = '\0'; + + n = 0; + for (i = 0; i < num; i++) { + a = va_arg(args, char *); + /* ignore NULLs, thanks to Bob Beck */ + if (a != NULL) { + n += strlen(a); + if (n > s) { + s = n + 20; + p = OPENSSL_realloc(str, s + 1); + if (p == NULL) { + OPENSSL_free(str); + return; + } else + str = p; + } + BUF_strlcat(str, a, (size_t)s + 1); + } + } + ERR_set_error_data(str, ERR_TXT_MALLOCED | ERR_TXT_STRING); +} + +int ERR_set_mark(void) +{ + ERR_STATE *es; + + es = ERR_get_state(); + + if (es->bottom == es->top) + return 0; + es->err_flags[es->top] |= ERR_FLAG_MARK; + return 1; +} + +int ERR_pop_to_mark(void) +{ + ERR_STATE *es; + + es = ERR_get_state(); + + while (es->bottom != es->top + && (es->err_flags[es->top] & ERR_FLAG_MARK) == 0) { + err_clear(es, es->top); + es->top -= 1; + if (es->top == -1) + es->top = ERR_NUM_ERRORS - 1; + } + + if (es->bottom == es->top) + return 0; + es->err_flags[es->top] &= ~ERR_FLAG_MARK; + return 1; +} diff --git a/libs/openssl/crypto/err/err.h b/libs/openssl/crypto/err/err.h new file mode 100644 index 00000000..585aa8ba --- /dev/null +++ b/libs/openssl/crypto/err/err.h @@ -0,0 +1,389 @@ +/* crypto/err/err.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_ERR_H +# define HEADER_ERR_H + +# include + +# ifndef OPENSSL_NO_FP_API +# include +# include +# endif + +# include +# ifndef OPENSSL_NO_BIO +# include +# endif +# ifndef OPENSSL_NO_LHASH +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef OPENSSL_NO_ERR +# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,d,e) +# else +# define ERR_PUT_error(a,b,c,d,e) ERR_put_error(a,b,c,NULL,0) +# endif + +# include + +# define ERR_TXT_MALLOCED 0x01 +# define ERR_TXT_STRING 0x02 + +# define ERR_FLAG_MARK 0x01 + +# define ERR_NUM_ERRORS 16 +typedef struct err_state_st { + CRYPTO_THREADID tid; + int err_flags[ERR_NUM_ERRORS]; + unsigned long err_buffer[ERR_NUM_ERRORS]; + char *err_data[ERR_NUM_ERRORS]; + int err_data_flags[ERR_NUM_ERRORS]; + const char *err_file[ERR_NUM_ERRORS]; + int err_line[ERR_NUM_ERRORS]; + int top, bottom; +} ERR_STATE; + +/* library */ +# define ERR_LIB_NONE 1 +# define ERR_LIB_SYS 2 +# define ERR_LIB_BN 3 +# define ERR_LIB_RSA 4 +# define ERR_LIB_DH 5 +# define ERR_LIB_EVP 6 +# define ERR_LIB_BUF 7 +# define ERR_LIB_OBJ 8 +# define ERR_LIB_PEM 9 +# define ERR_LIB_DSA 10 +# define ERR_LIB_X509 11 +/* #define ERR_LIB_METH 12 */ +# define ERR_LIB_ASN1 13 +# define ERR_LIB_CONF 14 +# define ERR_LIB_CRYPTO 15 +# define ERR_LIB_EC 16 +# define ERR_LIB_SSL 20 +/* #define ERR_LIB_SSL23 21 */ +/* #define ERR_LIB_SSL2 22 */ +/* #define ERR_LIB_SSL3 23 */ +/* #define ERR_LIB_RSAREF 30 */ +/* #define ERR_LIB_PROXY 31 */ +# define ERR_LIB_BIO 32 +# define ERR_LIB_PKCS7 33 +# define ERR_LIB_X509V3 34 +# define ERR_LIB_PKCS12 35 +# define ERR_LIB_RAND 36 +# define ERR_LIB_DSO 37 +# define ERR_LIB_ENGINE 38 +# define ERR_LIB_OCSP 39 +# define ERR_LIB_UI 40 +# define ERR_LIB_COMP 41 +# define ERR_LIB_ECDSA 42 +# define ERR_LIB_ECDH 43 +# define ERR_LIB_STORE 44 +# define ERR_LIB_FIPS 45 +# define ERR_LIB_CMS 46 +# define ERR_LIB_TS 47 +# define ERR_LIB_HMAC 48 +# define ERR_LIB_JPAKE 49 + +# define ERR_LIB_USER 128 + +# define SYSerr(f,r) ERR_PUT_error(ERR_LIB_SYS,(f),(r),__FILE__,__LINE__) +# define BNerr(f,r) ERR_PUT_error(ERR_LIB_BN,(f),(r),__FILE__,__LINE__) +# define RSAerr(f,r) ERR_PUT_error(ERR_LIB_RSA,(f),(r),__FILE__,__LINE__) +# define DHerr(f,r) ERR_PUT_error(ERR_LIB_DH,(f),(r),__FILE__,__LINE__) +# define EVPerr(f,r) ERR_PUT_error(ERR_LIB_EVP,(f),(r),__FILE__,__LINE__) +# define BUFerr(f,r) ERR_PUT_error(ERR_LIB_BUF,(f),(r),__FILE__,__LINE__) +# define OBJerr(f,r) ERR_PUT_error(ERR_LIB_OBJ,(f),(r),__FILE__,__LINE__) +# define PEMerr(f,r) ERR_PUT_error(ERR_LIB_PEM,(f),(r),__FILE__,__LINE__) +# define DSAerr(f,r) ERR_PUT_error(ERR_LIB_DSA,(f),(r),__FILE__,__LINE__) +# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,(f),(r),__FILE__,__LINE__) +# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,(f),(r),__FILE__,__LINE__) +# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,(f),(r),__FILE__,__LINE__) +# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,(f),(r),__FILE__,__LINE__) +# define ECerr(f,r) ERR_PUT_error(ERR_LIB_EC,(f),(r),__FILE__,__LINE__) +# define SSLerr(f,r) ERR_PUT_error(ERR_LIB_SSL,(f),(r),__FILE__,__LINE__) +# define BIOerr(f,r) ERR_PUT_error(ERR_LIB_BIO,(f),(r),__FILE__,__LINE__) +# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,(f),(r),__FILE__,__LINE__) +# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,(f),(r),__FILE__,__LINE__) +# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,(f),(r),__FILE__,__LINE__) +# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,(f),(r),__FILE__,__LINE__) +# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,(f),(r),__FILE__,__LINE__) +# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,(f),(r),__FILE__,__LINE__) +# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,(f),(r),__FILE__,__LINE__) +# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,(f),(r),__FILE__,__LINE__) +# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,(f),(r),__FILE__,__LINE__) +# define ECDSAerr(f,r) ERR_PUT_error(ERR_LIB_ECDSA,(f),(r),__FILE__,__LINE__) +# define ECDHerr(f,r) ERR_PUT_error(ERR_LIB_ECDH,(f),(r),__FILE__,__LINE__) +# define STOREerr(f,r) ERR_PUT_error(ERR_LIB_STORE,(f),(r),__FILE__,__LINE__) +# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,(f),(r),__FILE__,__LINE__) +# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,(f),(r),__FILE__,__LINE__) +# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,(f),(r),__FILE__,__LINE__) +# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,(f),(r),__FILE__,__LINE__) +# define JPAKEerr(f,r) ERR_PUT_error(ERR_LIB_JPAKE,(f),(r),__FILE__,__LINE__) + +/* + * Borland C seems too stupid to be able to shift and do longs in the + * pre-processor :-( + */ +# define ERR_PACK(l,f,r) (((((unsigned long)l)&0xffL)*0x1000000)| \ + ((((unsigned long)f)&0xfffL)*0x1000)| \ + ((((unsigned long)r)&0xfffL))) +# define ERR_GET_LIB(l) (int)((((unsigned long)l)>>24L)&0xffL) +# define ERR_GET_FUNC(l) (int)((((unsigned long)l)>>12L)&0xfffL) +# define ERR_GET_REASON(l) (int)((l)&0xfffL) +# define ERR_FATAL_ERROR(l) (int)((l)&ERR_R_FATAL) + +/* OS functions */ +# define SYS_F_FOPEN 1 +# define SYS_F_CONNECT 2 +# define SYS_F_GETSERVBYNAME 3 +# define SYS_F_SOCKET 4 +# define SYS_F_IOCTLSOCKET 5 +# define SYS_F_BIND 6 +# define SYS_F_LISTEN 7 +# define SYS_F_ACCEPT 8 +# define SYS_F_WSASTARTUP 9/* Winsock stuff */ +# define SYS_F_OPENDIR 10 +# define SYS_F_FREAD 11 + +/* reasons */ +# define ERR_R_SYS_LIB ERR_LIB_SYS/* 2 */ +# define ERR_R_BN_LIB ERR_LIB_BN/* 3 */ +# define ERR_R_RSA_LIB ERR_LIB_RSA/* 4 */ +# define ERR_R_DH_LIB ERR_LIB_DH/* 5 */ +# define ERR_R_EVP_LIB ERR_LIB_EVP/* 6 */ +# define ERR_R_BUF_LIB ERR_LIB_BUF/* 7 */ +# define ERR_R_OBJ_LIB ERR_LIB_OBJ/* 8 */ +# define ERR_R_PEM_LIB ERR_LIB_PEM/* 9 */ +# define ERR_R_DSA_LIB ERR_LIB_DSA/* 10 */ +# define ERR_R_X509_LIB ERR_LIB_X509/* 11 */ +# define ERR_R_ASN1_LIB ERR_LIB_ASN1/* 13 */ +# define ERR_R_CONF_LIB ERR_LIB_CONF/* 14 */ +# define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO/* 15 */ +# define ERR_R_EC_LIB ERR_LIB_EC/* 16 */ +# define ERR_R_SSL_LIB ERR_LIB_SSL/* 20 */ +# define ERR_R_BIO_LIB ERR_LIB_BIO/* 32 */ +# define ERR_R_PKCS7_LIB ERR_LIB_PKCS7/* 33 */ +# define ERR_R_X509V3_LIB ERR_LIB_X509V3/* 34 */ +# define ERR_R_PKCS12_LIB ERR_LIB_PKCS12/* 35 */ +# define ERR_R_RAND_LIB ERR_LIB_RAND/* 36 */ +# define ERR_R_DSO_LIB ERR_LIB_DSO/* 37 */ +# define ERR_R_ENGINE_LIB ERR_LIB_ENGINE/* 38 */ +# define ERR_R_OCSP_LIB ERR_LIB_OCSP/* 39 */ +# define ERR_R_UI_LIB ERR_LIB_UI/* 40 */ +# define ERR_R_COMP_LIB ERR_LIB_COMP/* 41 */ +# define ERR_R_ECDSA_LIB ERR_LIB_ECDSA/* 42 */ +# define ERR_R_ECDH_LIB ERR_LIB_ECDH/* 43 */ +# define ERR_R_STORE_LIB ERR_LIB_STORE/* 44 */ +# define ERR_R_TS_LIB ERR_LIB_TS/* 45 */ + +# define ERR_R_NESTED_ASN1_ERROR 58 +# define ERR_R_BAD_ASN1_OBJECT_HEADER 59 +# define ERR_R_BAD_GET_ASN1_OBJECT_CALL 60 +# define ERR_R_EXPECTING_AN_ASN1_SEQUENCE 61 +# define ERR_R_ASN1_LENGTH_MISMATCH 62 +# define ERR_R_MISSING_ASN1_EOS 63 + +/* fatal error */ +# define ERR_R_FATAL 64 +# define ERR_R_MALLOC_FAILURE (1|ERR_R_FATAL) +# define ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED (2|ERR_R_FATAL) +# define ERR_R_PASSED_NULL_PARAMETER (3|ERR_R_FATAL) +# define ERR_R_INTERNAL_ERROR (4|ERR_R_FATAL) +# define ERR_R_DISABLED (5|ERR_R_FATAL) + +/* + * 99 is the maximum possible ERR_R_... code, higher values are reserved for + * the individual libraries + */ + +typedef struct ERR_string_data_st { + unsigned long error; + const char *string; +} ERR_STRING_DATA; + +void ERR_put_error(int lib, int func, int reason, const char *file, int line); +void ERR_set_error_data(char *data, int flags); + +unsigned long ERR_get_error(void); +unsigned long ERR_get_error_line(const char **file, int *line); +unsigned long ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_error(void); +unsigned long ERR_peek_error_line(const char **file, int *line); +unsigned long ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags); +unsigned long ERR_peek_last_error(void); +unsigned long ERR_peek_last_error_line(const char **file, int *line); +unsigned long ERR_peek_last_error_line_data(const char **file, int *line, + const char **data, int *flags); +void ERR_clear_error(void); +char *ERR_error_string(unsigned long e, char *buf); +void ERR_error_string_n(unsigned long e, char *buf, size_t len); +const char *ERR_lib_error_string(unsigned long e); +const char *ERR_func_error_string(unsigned long e); +const char *ERR_reason_error_string(unsigned long e); +void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), + void *u); +# ifndef OPENSSL_NO_FP_API +void ERR_print_errors_fp(FILE *fp); +# endif +# ifndef OPENSSL_NO_BIO +void ERR_print_errors(BIO *bp); +# endif +void ERR_add_error_data(int num, ...); +void ERR_add_error_vdata(int num, va_list args); +void ERR_load_strings(int lib, ERR_STRING_DATA str[]); +void ERR_unload_strings(int lib, ERR_STRING_DATA str[]); +void ERR_load_ERR_strings(void); +void ERR_load_crypto_strings(void); +void ERR_free_strings(void); + +void ERR_remove_thread_state(const CRYPTO_THREADID *tid); +# ifndef OPENSSL_NO_DEPRECATED +void ERR_remove_state(unsigned long pid); /* if zero we look it up */ +# endif +ERR_STATE *ERR_get_state(void); + +# ifndef OPENSSL_NO_LHASH +LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void); +LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void); +void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash); +# endif + +int ERR_get_next_error_library(void); + +int ERR_set_mark(void); +int ERR_pop_to_mark(void); + +/* Already defined in ossl_typ.h */ +/* typedef struct st_ERR_FNS ERR_FNS; */ +/* + * An application can use this function and provide the return value to + * loaded modules that should use the application's ERR state/functionality + */ +const ERR_FNS *ERR_get_implementation(void); +/* + * A loaded module should call this function prior to any ERR operations + * using the application's "ERR_FNS". + */ +int ERR_set_implementation(const ERR_FNS *fns); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/err/err_all.c b/libs/openssl/crypto/err/err_all.c new file mode 100644 index 00000000..d7575a7e --- /dev/null +++ b/libs/openssl/crypto/err/err_all.c @@ -0,0 +1,168 @@ +/* crypto/err/err_all.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#ifndef OPENSSL_NO_EC +# include +#endif +#include +#include +#ifndef OPENSSL_NO_COMP +# include +#endif +#ifndef OPENSSL_NO_RSA +# include +#endif +#ifndef OPENSSL_NO_DH +# include +#endif +#ifndef OPENSSL_NO_DSA +# include +#endif +#ifndef OPENSSL_NO_ECDSA +# include +#endif +#ifndef OPENSSL_NO_ECDH +# include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include +#include +#include +#ifdef OPENSSL_FIPS +# include +#endif +#include +#ifndef OPENSSL_NO_CMS +# include +#endif +#ifndef OPENSSL_NO_JPAKE +# include +#endif + +void ERR_load_crypto_strings(void) +{ +#ifndef OPENSSL_NO_ERR + ERR_load_ERR_strings(); /* include error strings for SYSerr */ + ERR_load_BN_strings(); +# ifndef OPENSSL_NO_RSA + ERR_load_RSA_strings(); +# endif +# ifndef OPENSSL_NO_DH + ERR_load_DH_strings(); +# endif + ERR_load_EVP_strings(); + ERR_load_BUF_strings(); + ERR_load_OBJ_strings(); + ERR_load_PEM_strings(); +# ifndef OPENSSL_NO_DSA + ERR_load_DSA_strings(); +# endif + ERR_load_X509_strings(); + ERR_load_ASN1_strings(); + ERR_load_CONF_strings(); + ERR_load_CRYPTO_strings(); +# ifndef OPENSSL_NO_COMP + ERR_load_COMP_strings(); +# endif +# ifndef OPENSSL_NO_EC + ERR_load_EC_strings(); +# endif +# ifndef OPENSSL_NO_ECDSA + ERR_load_ECDSA_strings(); +# endif +# ifndef OPENSSL_NO_ECDH + ERR_load_ECDH_strings(); +# endif + /* skip ERR_load_SSL_strings() because it is not in this library */ + ERR_load_BIO_strings(); + ERR_load_PKCS7_strings(); + ERR_load_X509V3_strings(); + ERR_load_PKCS12_strings(); + ERR_load_RAND_strings(); + ERR_load_DSO_strings(); + ERR_load_TS_strings(); +# ifndef OPENSSL_NO_ENGINE + ERR_load_ENGINE_strings(); +# endif + ERR_load_OCSP_strings(); + ERR_load_UI_strings(); +# ifdef OPENSSL_FIPS + ERR_load_FIPS_strings(); +# endif +# ifndef OPENSSL_NO_CMS + ERR_load_CMS_strings(); +# endif +# ifndef OPENSSL_NO_JPAKE + ERR_load_JPAKE_strings(); +# endif +#endif +} diff --git a/libs/openssl/crypto/err/err_prn.c b/libs/openssl/crypto/err/err_prn.c new file mode 100644 index 00000000..6e352eff --- /dev/null +++ b/libs/openssl/crypto/err/err_prn.c @@ -0,0 +1,113 @@ +/* crypto/err/err_prn.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +void ERR_print_errors_cb(int (*cb) (const char *str, size_t len, void *u), + void *u) +{ + unsigned long l; + char buf[256]; + char buf2[4096]; + const char *file, *data; + int line, flags; + unsigned long es; + CRYPTO_THREADID cur; + + CRYPTO_THREADID_current(&cur); + es = CRYPTO_THREADID_hash(&cur); + while ((l = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) { + ERR_error_string_n(l, buf, sizeof buf); + BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", es, buf, + file, line, (flags & ERR_TXT_STRING) ? data : ""); + if (cb(buf2, strlen(buf2), u) <= 0) + break; /* abort outputting the error report */ + } +} + +#ifndef OPENSSL_NO_FP_API +static int print_fp(const char *str, size_t len, void *fp) +{ + BIO bio; + + BIO_set(&bio, BIO_s_file()); + BIO_set_fp(&bio, fp, BIO_NOCLOSE); + + return BIO_printf(&bio, "%s", str); +} + +void ERR_print_errors_fp(FILE *fp) +{ + ERR_print_errors_cb(print_fp, fp); +} +#endif + +static int print_bio(const char *str, size_t len, void *bp) +{ + return BIO_write((BIO *)bp, str, len); +} + +void ERR_print_errors(BIO *bp) +{ + ERR_print_errors_cb(print_bio, bp); +} diff --git a/libs/openssl/crypto/err/openssl.ec b/libs/openssl/crypto/err/openssl.ec new file mode 100644 index 00000000..bafbc35d --- /dev/null +++ b/libs/openssl/crypto/err/openssl.ec @@ -0,0 +1,97 @@ +# crypto/err/openssl.ec + +# configuration file for util/mkerr.pl + +# files that may have to be rewritten by util/mkerr.pl +L ERR NONE NONE +L BN crypto/bn/bn.h crypto/bn/bn_err.c +L RSA crypto/rsa/rsa.h crypto/rsa/rsa_err.c +L DH crypto/dh/dh.h crypto/dh/dh_err.c +L EVP crypto/evp/evp.h crypto/evp/evp_err.c +L BUF crypto/buffer/buffer.h crypto/buffer/buf_err.c +L OBJ crypto/objects/objects.h crypto/objects/obj_err.c +L PEM crypto/pem/pem.h crypto/pem/pem_err.c +L DSA crypto/dsa/dsa.h crypto/dsa/dsa_err.c +L X509 crypto/x509/x509.h crypto/x509/x509_err.c +L ASN1 crypto/asn1/asn1.h crypto/asn1/asn1_err.c +L CONF crypto/conf/conf.h crypto/conf/conf_err.c +L CRYPTO crypto/crypto.h crypto/cpt_err.c +L EC crypto/ec/ec.h crypto/ec/ec_err.c +L SSL ssl/ssl.h ssl/ssl_err.c +L BIO crypto/bio/bio.h crypto/bio/bio_err.c +L PKCS7 crypto/pkcs7/pkcs7.h crypto/pkcs7/pkcs7err.c +L X509V3 crypto/x509v3/x509v3.h crypto/x509v3/v3err.c +L PKCS12 crypto/pkcs12/pkcs12.h crypto/pkcs12/pk12err.c +L RAND crypto/rand/rand.h crypto/rand/rand_err.c +L DSO crypto/dso/dso.h crypto/dso/dso_err.c +L ENGINE crypto/engine/engine.h crypto/engine/eng_err.c +L OCSP crypto/ocsp/ocsp.h crypto/ocsp/ocsp_err.c +L UI crypto/ui/ui.h crypto/ui/ui_err.c +L COMP crypto/comp/comp.h crypto/comp/comp_err.c +L ECDSA crypto/ecdsa/ecdsa.h crypto/ecdsa/ecs_err.c +L ECDH crypto/ecdh/ecdh.h crypto/ecdh/ech_err.c +L STORE crypto/store/store.h crypto/store/str_err.c +L TS crypto/ts/ts.h crypto/ts/ts_err.c +L HMAC crypto/hmac/hmac.h crypto/hmac/hmac_err.c +L CMS crypto/cms/cms.h crypto/cms/cms_err.c +L JPAKE crypto/jpake/jpake.h crypto/jpake/jpake_err.c + +# additional header files to be scanned for function names +L NONE crypto/x509/x509_vfy.h NONE +L NONE crypto/ec/ec_lcl.h NONE +L NONE crypto/asn1/asn_lcl.h NONE +L NONE crypto/cms/cms_lcl.h NONE + + +F RSAREF_F_RSA_BN2BIN +F RSAREF_F_RSA_PRIVATE_DECRYPT +F RSAREF_F_RSA_PRIVATE_ENCRYPT +F RSAREF_F_RSA_PUBLIC_DECRYPT +F RSAREF_F_RSA_PUBLIC_ENCRYPT +#F SSL_F_CLIENT_CERTIFICATE + +R SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 +R SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 +R SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 +R SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 +R SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 +R SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 +R SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 +R SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 +R SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 +R SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 +R SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 +R SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 +R SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 +R SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +R SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 +R SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 +R SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 +R SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 +R SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 +R SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 +R SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +R SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 +R SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +R SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +R SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 +R SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 +R SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 +R SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +R SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 + +R RSAREF_R_CONTENT_ENCODING 0x0400 +R RSAREF_R_DATA 0x0401 +R RSAREF_R_DIGEST_ALGORITHM 0x0402 +R RSAREF_R_ENCODING 0x0403 +R RSAREF_R_KEY 0x0404 +R RSAREF_R_KEY_ENCODING 0x0405 +R RSAREF_R_LEN 0x0406 +R RSAREF_R_MODULUS_LEN 0x0407 +R RSAREF_R_NEED_RANDOM 0x0408 +R RSAREF_R_PRIVATE_KEY 0x0409 +R RSAREF_R_PUBLIC_KEY 0x040a +R RSAREF_R_SIGNATURE 0x040b +R RSAREF_R_SIGNATURE_ENCODING 0x040c +R RSAREF_R_ENCRYPTION_ALGORITHM 0x040d + diff --git a/libs/openssl/crypto/evp/bio_b64.c b/libs/openssl/crypto/evp/bio_b64.c new file mode 100644 index 00000000..538b5202 --- /dev/null +++ b/libs/openssl/crypto/evp/bio_b64.c @@ -0,0 +1,573 @@ +/* crypto/evp/bio_b64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include + +static int b64_write(BIO *h, const char *buf, int num); +static int b64_read(BIO *h, char *buf, int size); +static int b64_puts(BIO *h, const char *str); +/* + * static int b64_gets(BIO *h, char *str, int size); + */ +static long b64_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int b64_new(BIO *h); +static int b64_free(BIO *data); +static long b64_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); +#define B64_BLOCK_SIZE 1024 +#define B64_BLOCK_SIZE2 768 +#define B64_NONE 0 +#define B64_ENCODE 1 +#define B64_DECODE 2 + +typedef struct b64_struct { + /* + * BIO *bio; moved to the BIO structure + */ + int buf_len; + int buf_off; + int tmp_len; /* used to find the start when decoding */ + int tmp_nl; /* If true, scan until '\n' */ + int encode; + int start; /* have we started decoding yet? */ + int cont; /* <= 0 when finished */ + EVP_ENCODE_CTX base64; + char buf[EVP_ENCODE_LENGTH(B64_BLOCK_SIZE) + 10]; + char tmp[B64_BLOCK_SIZE]; +} BIO_B64_CTX; + +static BIO_METHOD methods_b64 = { + BIO_TYPE_BASE64, "base64 encoding", + b64_write, + b64_read, + b64_puts, + NULL, /* b64_gets, */ + b64_ctrl, + b64_new, + b64_free, + b64_callback_ctrl, +}; + +BIO_METHOD *BIO_f_base64(void) +{ + return (&methods_b64); +} + +static int b64_new(BIO *bi) +{ + BIO_B64_CTX *ctx; + + ctx = (BIO_B64_CTX *)OPENSSL_malloc(sizeof(BIO_B64_CTX)); + if (ctx == NULL) + return (0); + + ctx->buf_len = 0; + ctx->tmp_len = 0; + ctx->tmp_nl = 0; + ctx->buf_off = 0; + ctx->cont = 1; + ctx->start = 1; + ctx->encode = 0; + + bi->init = 1; + bi->ptr = (char *)ctx; + bi->flags = 0; + bi->num = 0; + return (1); +} + +static int b64_free(BIO *a) +{ + if (a == NULL) + return (0); + OPENSSL_free(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int b64_read(BIO *b, char *out, int outl) +{ + int ret = 0, i, ii, j, k, x, n, num, ret_code = 0; + BIO_B64_CTX *ctx; + unsigned char *p, *q; + + if (out == NULL) + return (0); + ctx = (BIO_B64_CTX *)b->ptr; + + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + + BIO_clear_retry_flags(b); + + if (ctx->encode != B64_DECODE) { + ctx->encode = B64_DECODE; + ctx->buf_len = 0; + ctx->buf_off = 0; + ctx->tmp_len = 0; + EVP_DecodeInit(&(ctx->base64)); + } + + /* First check if there are bytes decoded/encoded */ + if (ctx->buf_len > 0) { + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + i = ctx->buf_len - ctx->buf_off; + if (i > outl) + i = outl; + OPENSSL_assert(ctx->buf_off + i < (int)sizeof(ctx->buf)); + memcpy(out, &(ctx->buf[ctx->buf_off]), i); + ret = i; + out += i; + outl -= i; + ctx->buf_off += i; + if (ctx->buf_len == ctx->buf_off) { + ctx->buf_len = 0; + ctx->buf_off = 0; + } + } + + /* + * At this point, we have room of outl bytes and an empty buffer, so we + * should read in some more. + */ + + ret_code = 0; + while (outl > 0) { + if (ctx->cont <= 0) + break; + + i = BIO_read(b->next_bio, &(ctx->tmp[ctx->tmp_len]), + B64_BLOCK_SIZE - ctx->tmp_len); + + if (i <= 0) { + ret_code = i; + + /* Should we continue next time we are called? */ + if (!BIO_should_retry(b->next_bio)) { + ctx->cont = i; + /* If buffer empty break */ + if (ctx->tmp_len == 0) + break; + /* Fall through and process what we have */ + else + i = 0; + } + /* else we retry and add more data to buffer */ + else + break; + } + i += ctx->tmp_len; + ctx->tmp_len = i; + + /* + * We need to scan, a line at a time until we have a valid line if we + * are starting. + */ + if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) { + /* ctx->start=1; */ + ctx->tmp_len = 0; + } else if (ctx->start) { + q = p = (unsigned char *)ctx->tmp; + num = 0; + for (j = 0; j < i; j++) { + if (*(q++) != '\n') + continue; + + /* + * due to a previous very long line, we need to keep on + * scanning for a '\n' before we even start looking for + * base64 encoded stuff. + */ + if (ctx->tmp_nl) { + p = q; + ctx->tmp_nl = 0; + continue; + } + + k = EVP_DecodeUpdate(&(ctx->base64), + (unsigned char *)ctx->buf, + &num, p, q - p); + if ((k <= 0) && (num == 0) && (ctx->start)) + EVP_DecodeInit(&ctx->base64); + else { + if (p != (unsigned char *) + &(ctx->tmp[0])) { + i -= (p - (unsigned char *) + &(ctx->tmp[0])); + for (x = 0; x < i; x++) + ctx->tmp[x] = p[x]; + } + EVP_DecodeInit(&ctx->base64); + ctx->start = 0; + break; + } + p = q; + } + + /* we fell off the end without starting */ + if ((j == i) && (num == 0)) { + /* + * Is this is one long chunk?, if so, keep on reading until a + * new line. + */ + if (p == (unsigned char *)&(ctx->tmp[0])) { + /* Check buffer full */ + if (i == B64_BLOCK_SIZE) { + ctx->tmp_nl = 1; + ctx->tmp_len = 0; + } + } else if (p != q) { /* finished on a '\n' */ + n = q - p; + for (ii = 0; ii < n; ii++) + ctx->tmp[ii] = p[ii]; + ctx->tmp_len = n; + } + /* else finished on a '\n' */ + continue; + } else { + ctx->tmp_len = 0; + } + } else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) { + /* + * If buffer isn't full and we can retry then restart to read in + * more data. + */ + continue; + } + + if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { + int z, jj; + +#if 0 + jj = (i >> 2) << 2; +#else + jj = i & ~3; /* process per 4 */ +#endif + z = EVP_DecodeBlock((unsigned char *)ctx->buf, + (unsigned char *)ctx->tmp, jj); + if (jj > 2) { + if (ctx->tmp[jj - 1] == '=') { + z--; + if (ctx->tmp[jj - 2] == '=') + z--; + } + } + /* + * z is now number of output bytes and jj is the number consumed + */ + if (jj != i) { + memmove(ctx->tmp, &ctx->tmp[jj], i - jj); + ctx->tmp_len = i - jj; + } + ctx->buf_len = 0; + if (z > 0) { + ctx->buf_len = z; + } + i = z; + } else { + i = EVP_DecodeUpdate(&(ctx->base64), + (unsigned char *)ctx->buf, &ctx->buf_len, + (unsigned char *)ctx->tmp, i); + ctx->tmp_len = 0; + } + ctx->buf_off = 0; + if (i < 0) { + ret_code = 0; + ctx->buf_len = 0; + break; + } + + if (ctx->buf_len <= outl) + i = ctx->buf_len; + else + i = outl; + + memcpy(out, ctx->buf, i); + ret += i; + ctx->buf_off = i; + if (ctx->buf_off == ctx->buf_len) { + ctx->buf_len = 0; + ctx->buf_off = 0; + } + outl -= i; + out += i; + } + /* BIO_clear_retry_flags(b); */ + BIO_copy_next_retry(b); + return ((ret == 0) ? ret_code : ret); +} + +static int b64_write(BIO *b, const char *in, int inl) +{ + int ret = 0; + int n; + int i; + BIO_B64_CTX *ctx; + + ctx = (BIO_B64_CTX *)b->ptr; + BIO_clear_retry_flags(b); + + if (ctx->encode != B64_ENCODE) { + ctx->encode = B64_ENCODE; + ctx->buf_len = 0; + ctx->buf_off = 0; + ctx->tmp_len = 0; + EVP_EncodeInit(&(ctx->base64)); + } + + OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + n = ctx->buf_len - ctx->buf_off; + while (n > 0) { + i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); + if (i <= 0) { + BIO_copy_next_retry(b); + return (i); + } + OPENSSL_assert(i <= n); + ctx->buf_off += i; + OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + n -= i; + } + /* at this point all pending data has been written */ + ctx->buf_off = 0; + ctx->buf_len = 0; + + if ((in == NULL) || (inl <= 0)) + return (0); + + while (inl > 0) { + n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl; + + if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { + if (ctx->tmp_len > 0) { + OPENSSL_assert(ctx->tmp_len <= 3); + n = 3 - ctx->tmp_len; + /* + * There's a theoretical possibility for this + */ + if (n > inl) + n = inl; + memcpy(&(ctx->tmp[ctx->tmp_len]), in, n); + ctx->tmp_len += n; + ret += n; + if (ctx->tmp_len < 3) + break; + ctx->buf_len = + EVP_EncodeBlock((unsigned char *)ctx->buf, + (unsigned char *)ctx->tmp, ctx->tmp_len); + OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + /* + * Since we're now done using the temporary buffer, the + * length should be 0'd + */ + ctx->tmp_len = 0; + } else { + if (n < 3) { + memcpy(ctx->tmp, in, n); + ctx->tmp_len = n; + ret += n; + break; + } + n -= n % 3; + ctx->buf_len = + EVP_EncodeBlock((unsigned char *)ctx->buf, + (const unsigned char *)in, n); + OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + ret += n; + } + } else { + EVP_EncodeUpdate(&(ctx->base64), + (unsigned char *)ctx->buf, &ctx->buf_len, + (unsigned char *)in, n); + OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + ret += n; + } + inl -= n; + in += n; + + ctx->buf_off = 0; + n = ctx->buf_len; + while (n > 0) { + i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); + if (i <= 0) { + BIO_copy_next_retry(b); + return ((ret == 0) ? i : ret); + } + OPENSSL_assert(i <= n); + n -= i; + ctx->buf_off += i; + OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf)); + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + } + ctx->buf_len = 0; + ctx->buf_off = 0; + } + return (ret); +} + +static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO_B64_CTX *ctx; + long ret = 1; + int i; + + ctx = (BIO_B64_CTX *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->cont = 1; + ctx->start = 1; + ctx->encode = B64_NONE; + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_EOF: /* More to read */ + if (ctx->cont <= 0) + ret = 1; + else + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_WPENDING: /* More to write in buffer */ + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + ret = ctx->buf_len - ctx->buf_off; + if ((ret == 0) && (ctx->encode != B64_NONE) + && (ctx->base64.num != 0)) + ret = 1; + else if (ret <= 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_PENDING: /* More to read in buffer */ + OPENSSL_assert(ctx->buf_len >= ctx->buf_off); + ret = ctx->buf_len - ctx->buf_off; + if (ret <= 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_FLUSH: + /* do a final write */ + again: + while (ctx->buf_len != ctx->buf_off) { + i = b64_write(b, NULL, 0); + if (i < 0) + return i; + } + if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) { + if (ctx->tmp_len != 0) { + ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf, + (unsigned char *)ctx->tmp, + ctx->tmp_len); + ctx->buf_off = 0; + ctx->tmp_len = 0; + goto again; + } + } else if (ctx->encode != B64_NONE && ctx->base64.num != 0) { + ctx->buf_off = 0; + EVP_EncodeFinal(&(ctx->base64), + (unsigned char *)ctx->buf, &(ctx->buf_len)); + /* push out the bytes */ + goto again; + } + /* Finally flush the underlying BIO */ + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + + case BIO_CTRL_DUP: + break; + case BIO_CTRL_INFO: + case BIO_CTRL_GET: + case BIO_CTRL_SET: + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); +} + +static long b64_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static int b64_puts(BIO *b, const char *str) +{ + return b64_write(b, str, strlen(str)); +} diff --git a/libs/openssl/crypto/evp/bio_enc.c b/libs/openssl/crypto/evp/bio_enc.c new file mode 100644 index 00000000..363e0246 --- /dev/null +++ b/libs/openssl/crypto/evp/bio_enc.c @@ -0,0 +1,428 @@ +/* crypto/evp/bio_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include + +static int enc_write(BIO *h, const char *buf, int num); +static int enc_read(BIO *h, char *buf, int size); +/* + * static int enc_puts(BIO *h, const char *str); + */ +/* + * static int enc_gets(BIO *h, char *str, int size); + */ +static long enc_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int enc_new(BIO *h); +static int enc_free(BIO *data); +static long enc_callback_ctrl(BIO *h, int cmd, bio_info_cb *fps); +#define ENC_BLOCK_SIZE (1024*4) +#define BUF_OFFSET (EVP_MAX_BLOCK_LENGTH*2) + +typedef struct enc_struct { + int buf_len; + int buf_off; + int cont; /* <= 0 when finished */ + int finished; + int ok; /* bad decrypt */ + EVP_CIPHER_CTX cipher; + /* + * buf is larger than ENC_BLOCK_SIZE because EVP_DecryptUpdate can return + * up to a block more data than is presented to it + */ + char buf[ENC_BLOCK_SIZE + BUF_OFFSET + 2]; +} BIO_ENC_CTX; + +static BIO_METHOD methods_enc = { + BIO_TYPE_CIPHER, "cipher", + enc_write, + enc_read, + NULL, /* enc_puts, */ + NULL, /* enc_gets, */ + enc_ctrl, + enc_new, + enc_free, + enc_callback_ctrl, +}; + +BIO_METHOD *BIO_f_cipher(void) +{ + return (&methods_enc); +} + +static int enc_new(BIO *bi) +{ + BIO_ENC_CTX *ctx; + + ctx = (BIO_ENC_CTX *)OPENSSL_malloc(sizeof(BIO_ENC_CTX)); + if (ctx == NULL) + return (0); + EVP_CIPHER_CTX_init(&ctx->cipher); + + ctx->buf_len = 0; + ctx->buf_off = 0; + ctx->cont = 1; + ctx->finished = 0; + ctx->ok = 1; + + bi->init = 0; + bi->ptr = (char *)ctx; + bi->flags = 0; + return (1); +} + +static int enc_free(BIO *a) +{ + BIO_ENC_CTX *b; + + if (a == NULL) + return (0); + b = (BIO_ENC_CTX *)a->ptr; + EVP_CIPHER_CTX_cleanup(&(b->cipher)); + OPENSSL_cleanse(a->ptr, sizeof(BIO_ENC_CTX)); + OPENSSL_free(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int enc_read(BIO *b, char *out, int outl) +{ + int ret = 0, i; + BIO_ENC_CTX *ctx; + + if (out == NULL) + return (0); + ctx = (BIO_ENC_CTX *)b->ptr; + + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + + /* First check if there are bytes decoded/encoded */ + if (ctx->buf_len > 0) { + i = ctx->buf_len - ctx->buf_off; + if (i > outl) + i = outl; + memcpy(out, &(ctx->buf[ctx->buf_off]), i); + ret = i; + out += i; + outl -= i; + ctx->buf_off += i; + if (ctx->buf_len == ctx->buf_off) { + ctx->buf_len = 0; + ctx->buf_off = 0; + } + } + + /* + * At this point, we have room of outl bytes and an empty buffer, so we + * should read in some more. + */ + + while (outl > 0) { + if (ctx->cont <= 0) + break; + + /* + * read in at IV offset, read the EVP_Cipher documentation about why + */ + i = BIO_read(b->next_bio, &(ctx->buf[BUF_OFFSET]), ENC_BLOCK_SIZE); + + if (i <= 0) { + /* Should be continue next time we are called? */ + if (!BIO_should_retry(b->next_bio)) { + ctx->cont = i; + i = EVP_CipherFinal_ex(&(ctx->cipher), + (unsigned char *)ctx->buf, + &(ctx->buf_len)); + ctx->ok = i; + ctx->buf_off = 0; + } else { + ret = (ret == 0) ? i : ret; + break; + } + } else { + EVP_CipherUpdate(&(ctx->cipher), + (unsigned char *)ctx->buf, &ctx->buf_len, + (unsigned char *)&(ctx->buf[BUF_OFFSET]), i); + ctx->cont = 1; + /* + * Note: it is possible for EVP_CipherUpdate to decrypt zero + * bytes because this is or looks like the final block: if this + * happens we should retry and either read more data or decrypt + * the final block + */ + if (ctx->buf_len == 0) + continue; + } + + if (ctx->buf_len <= outl) + i = ctx->buf_len; + else + i = outl; + if (i <= 0) + break; + memcpy(out, ctx->buf, i); + ret += i; + ctx->buf_off = i; + outl -= i; + out += i; + } + + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return ((ret == 0) ? ctx->cont : ret); +} + +static int enc_write(BIO *b, const char *in, int inl) +{ + int ret = 0, n, i; + BIO_ENC_CTX *ctx; + + ctx = (BIO_ENC_CTX *)b->ptr; + ret = inl; + + BIO_clear_retry_flags(b); + n = ctx->buf_len - ctx->buf_off; + while (n > 0) { + i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); + if (i <= 0) { + BIO_copy_next_retry(b); + return (i); + } + ctx->buf_off += i; + n -= i; + } + /* at this point all pending data has been written */ + + if ((in == NULL) || (inl <= 0)) + return (0); + + ctx->buf_off = 0; + while (inl > 0) { + n = (inl > ENC_BLOCK_SIZE) ? ENC_BLOCK_SIZE : inl; + EVP_CipherUpdate(&(ctx->cipher), + (unsigned char *)ctx->buf, &ctx->buf_len, + (unsigned char *)in, n); + inl -= n; + in += n; + + ctx->buf_off = 0; + n = ctx->buf_len; + while (n > 0) { + i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); + if (i <= 0) { + BIO_copy_next_retry(b); + return (ret == inl) ? i : ret - inl; + } + n -= i; + ctx->buf_off += i; + } + ctx->buf_len = 0; + ctx->buf_off = 0; + } + BIO_copy_next_retry(b); + return (ret); +} + +static long enc_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO *dbio; + BIO_ENC_CTX *ctx, *dctx; + long ret = 1; + int i; + EVP_CIPHER_CTX **c_ctx; + + ctx = (BIO_ENC_CTX *)b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->ok = 1; + ctx->finished = 0; + EVP_CipherInit_ex(&(ctx->cipher), NULL, NULL, NULL, NULL, + ctx->cipher.encrypt); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_EOF: /* More to read */ + if (ctx->cont <= 0) + ret = 1; + else + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_WPENDING: + ret = ctx->buf_len - ctx->buf_off; + if (ret <= 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_PENDING: /* More to read in buffer */ + ret = ctx->buf_len - ctx->buf_off; + if (ret <= 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_FLUSH: + /* do a final write */ + again: + while (ctx->buf_len != ctx->buf_off) { + i = enc_write(b, NULL, 0); + if (i < 0) + return i; + } + + if (!ctx->finished) { + ctx->finished = 1; + ctx->buf_off = 0; + ret = EVP_CipherFinal_ex(&(ctx->cipher), + (unsigned char *)ctx->buf, + &(ctx->buf_len)); + ctx->ok = (int)ret; + if (ret <= 0) + break; + + /* push out the bytes */ + goto again; + } + + /* Finally flush the underlying BIO */ + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_C_GET_CIPHER_STATUS: + ret = (long)ctx->ok; + break; + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + case BIO_C_GET_CIPHER_CTX: + c_ctx = (EVP_CIPHER_CTX **)ptr; + (*c_ctx) = &(ctx->cipher); + b->init = 1; + break; + case BIO_CTRL_DUP: + dbio = (BIO *)ptr; + dctx = (BIO_ENC_CTX *)dbio->ptr; + EVP_CIPHER_CTX_init(&dctx->cipher); + ret = EVP_CIPHER_CTX_copy(&dctx->cipher, &ctx->cipher); + if (ret) + dbio->init = 1; + break; + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); +} + +static long enc_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +/*- +void BIO_set_cipher_ctx(b,c) +BIO *b; +EVP_CIPHER_ctx *c; + { + if (b == NULL) return; + + if ((b->callback != NULL) && + (b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,0L) <= 0)) + return; + + b->init=1; + ctx=(BIO_ENC_CTX *)b->ptr; + memcpy(ctx->cipher,c,sizeof(EVP_CIPHER_CTX)); + + if (b->callback != NULL) + b->callback(b,BIO_CB_CTRL,(char *)c,BIO_CTRL_SET,e,1L); + } +*/ + +void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, + const unsigned char *i, int e) +{ + BIO_ENC_CTX *ctx; + + if (b == NULL) + return; + + if ((b->callback != NULL) && + (b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 0L) <= + 0)) + return; + + b->init = 1; + ctx = (BIO_ENC_CTX *)b->ptr; + EVP_CipherInit_ex(&(ctx->cipher), c, NULL, k, i, e); + + if (b->callback != NULL) + b->callback(b, BIO_CB_CTRL, (const char *)c, BIO_CTRL_SET, e, 1L); +} diff --git a/libs/openssl/crypto/evp/bio_md.c b/libs/openssl/crypto/evp/bio_md.c new file mode 100644 index 00000000..f0b0c0c0 --- /dev/null +++ b/libs/openssl/crypto/evp/bio_md.c @@ -0,0 +1,272 @@ +/* crypto/evp/bio_md.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include + +/* + * BIO_put and BIO_get both add to the digest, BIO_gets returns the digest + */ + +static int md_write(BIO *h, char const *buf, int num); +static int md_read(BIO *h, char *buf, int size); +/* + * static int md_puts(BIO *h, const char *str); + */ +static int md_gets(BIO *h, char *str, int size); +static long md_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int md_new(BIO *h); +static int md_free(BIO *data); +static long md_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); + +static BIO_METHOD methods_md = { + BIO_TYPE_MD, "message digest", + md_write, + md_read, + NULL, /* md_puts, */ + md_gets, + md_ctrl, + md_new, + md_free, + md_callback_ctrl, +}; + +BIO_METHOD *BIO_f_md(void) +{ + return (&methods_md); +} + +static int md_new(BIO *bi) +{ + EVP_MD_CTX *ctx; + + ctx = EVP_MD_CTX_create(); + if (ctx == NULL) + return (0); + + bi->init = 0; + bi->ptr = (char *)ctx; + bi->flags = 0; + return (1); +} + +static int md_free(BIO *a) +{ + if (a == NULL) + return (0); + EVP_MD_CTX_destroy(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int md_read(BIO *b, char *out, int outl) +{ + int ret = 0; + EVP_MD_CTX *ctx; + + if (out == NULL) + return (0); + ctx = b->ptr; + + if ((ctx == NULL) || (b->next_bio == NULL)) + return (0); + + ret = BIO_read(b->next_bio, out, outl); + if (b->init) { + if (ret > 0) { + if (EVP_DigestUpdate(ctx, (unsigned char *)out, + (unsigned int)ret) <= 0) + return (-1); + } + } + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return (ret); +} + +static int md_write(BIO *b, const char *in, int inl) +{ + int ret = 0; + EVP_MD_CTX *ctx; + + if ((in == NULL) || (inl <= 0)) + return (0); + ctx = b->ptr; + + if ((ctx != NULL) && (b->next_bio != NULL)) + ret = BIO_write(b->next_bio, in, inl); + if (b->init) { + if (ret > 0) { + if (!EVP_DigestUpdate(ctx, (const unsigned char *)in, + (unsigned int)ret)) { + BIO_clear_retry_flags(b); + return 0; + } + } + } + if (b->next_bio != NULL) { + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + } + return (ret); +} + +static long md_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + EVP_MD_CTX *ctx, *dctx, **pctx; + const EVP_MD **ppmd; + EVP_MD *md; + long ret = 1; + BIO *dbio; + + ctx = b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + if (b->init) + ret = EVP_DigestInit_ex(ctx, ctx->digest, NULL); + else + ret = 0; + if (ret > 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_C_GET_MD: + if (b->init) { + ppmd = ptr; + *ppmd = ctx->digest; + } else + ret = 0; + break; + case BIO_C_GET_MD_CTX: + pctx = ptr; + *pctx = ctx; + b->init = 1; + break; + case BIO_C_SET_MD_CTX: + if (b->init) + b->ptr = ptr; + else + ret = 0; + break; + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + + case BIO_C_SET_MD: + md = ptr; + ret = EVP_DigestInit_ex(ctx, md, NULL); + if (ret > 0) + b->init = 1; + break; + case BIO_CTRL_DUP: + dbio = ptr; + dctx = dbio->ptr; + if (!EVP_MD_CTX_copy_ex(dctx, ctx)) + return 0; + b->init = 1; + break; + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); +} + +static long md_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static int md_gets(BIO *bp, char *buf, int size) +{ + EVP_MD_CTX *ctx; + unsigned int ret; + + ctx = bp->ptr; + if (size < ctx->digest->md_size) + return (0); + if (EVP_DigestFinal_ex(ctx, (unsigned char *)buf, &ret) <= 0) + return -1; + + return ((int)ret); +} + +/*- +static int md_puts(bp,str) +BIO *bp; +char *str; + { + return(-1); + } +*/ diff --git a/libs/openssl/crypto/evp/bio_ok.c b/libs/openssl/crypto/evp/bio_ok.c new file mode 100644 index 00000000..5c32e35e --- /dev/null +++ b/libs/openssl/crypto/evp/bio_ok.c @@ -0,0 +1,624 @@ +/* crypto/evp/bio_ok.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/*- + From: Arne Ansper + + Why BIO_f_reliable? + + I wrote function which took BIO* as argument, read data from it + and processed it. Then I wanted to store the input file in + encrypted form. OK I pushed BIO_f_cipher to the BIO stack + and everything was OK. BUT if user types wrong password + BIO_f_cipher outputs only garbage and my function crashes. Yes + I can and I should fix my function, but BIO_f_cipher is + easy way to add encryption support to many existing applications + and it's hard to debug and fix them all. + + So I wanted another BIO which would catch the incorrect passwords and + file damages which cause garbage on BIO_f_cipher's output. + + The easy way is to push the BIO_f_md and save the checksum at + the end of the file. However there are several problems with this + approach: + + 1) you must somehow separate checksum from actual data. + 2) you need lot's of memory when reading the file, because you + must read to the end of the file and verify the checksum before + letting the application to read the data. + + BIO_f_reliable tries to solve both problems, so that you can + read and write arbitrary long streams using only fixed amount + of memory. + + BIO_f_reliable splits data stream into blocks. Each block is prefixed + with it's length and suffixed with it's digest. So you need only + several Kbytes of memory to buffer single block before verifying + it's digest. + + BIO_f_reliable goes further and adds several important capabilities: + + 1) the digest of the block is computed over the whole stream + -- so nobody can rearrange the blocks or remove or replace them. + + 2) to detect invalid passwords right at the start BIO_f_reliable + adds special prefix to the stream. In order to avoid known plain-text + attacks this prefix is generated as follows: + + *) digest is initialized with random seed instead of + standardized one. + *) same seed is written to output + *) well-known text is then hashed and the output + of the digest is also written to output. + + reader can now read the seed from stream, hash the same string + and then compare the digest output. + + Bad things: BIO_f_reliable knows what's going on in EVP_Digest. I + initially wrote and tested this code on x86 machine and wrote the + digests out in machine-dependent order :( There are people using + this code and I cannot change this easily without making existing + data files unreadable. + +*/ + +#include +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include + +static int ok_write(BIO *h, const char *buf, int num); +static int ok_read(BIO *h, char *buf, int size); +static long ok_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int ok_new(BIO *h); +static int ok_free(BIO *data); +static long ok_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); + +static int sig_out(BIO *b); +static int sig_in(BIO *b); +static int block_out(BIO *b); +static int block_in(BIO *b); +#define OK_BLOCK_SIZE (1024*4) +#define OK_BLOCK_BLOCK 4 +#define IOBS (OK_BLOCK_SIZE+ OK_BLOCK_BLOCK+ 3*EVP_MAX_MD_SIZE) +#define WELLKNOWN "The quick brown fox jumped over the lazy dog's back." + +typedef struct ok_struct { + size_t buf_len; + size_t buf_off; + size_t buf_len_save; + size_t buf_off_save; + int cont; /* <= 0 when finished */ + int finished; + EVP_MD_CTX md; + int blockout; /* output block is ready */ + int sigio; /* must process signature */ + unsigned char buf[IOBS]; +} BIO_OK_CTX; + +static BIO_METHOD methods_ok = { + BIO_TYPE_CIPHER, "reliable", + ok_write, + ok_read, + NULL, /* ok_puts, */ + NULL, /* ok_gets, */ + ok_ctrl, + ok_new, + ok_free, + ok_callback_ctrl, +}; + +BIO_METHOD *BIO_f_reliable(void) +{ + return (&methods_ok); +} + +static int ok_new(BIO *bi) +{ + BIO_OK_CTX *ctx; + + ctx = (BIO_OK_CTX *)OPENSSL_malloc(sizeof(BIO_OK_CTX)); + if (ctx == NULL) + return (0); + + ctx->buf_len = 0; + ctx->buf_off = 0; + ctx->buf_len_save = 0; + ctx->buf_off_save = 0; + ctx->cont = 1; + ctx->finished = 0; + ctx->blockout = 0; + ctx->sigio = 1; + + EVP_MD_CTX_init(&ctx->md); + + bi->init = 0; + bi->ptr = (char *)ctx; + bi->flags = 0; + return (1); +} + +static int ok_free(BIO *a) +{ + if (a == NULL) + return (0); + EVP_MD_CTX_cleanup(&((BIO_OK_CTX *)a->ptr)->md); + OPENSSL_cleanse(a->ptr, sizeof(BIO_OK_CTX)); + OPENSSL_free(a->ptr); + a->ptr = NULL; + a->init = 0; + a->flags = 0; + return (1); +} + +static int ok_read(BIO *b, char *out, int outl) +{ + int ret = 0, i, n; + BIO_OK_CTX *ctx; + + if (out == NULL) + return (0); + ctx = (BIO_OK_CTX *)b->ptr; + + if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) + return (0); + + while (outl > 0) { + + /* copy clean bytes to output buffer */ + if (ctx->blockout) { + i = ctx->buf_len - ctx->buf_off; + if (i > outl) + i = outl; + memcpy(out, &(ctx->buf[ctx->buf_off]), i); + ret += i; + out += i; + outl -= i; + ctx->buf_off += i; + + /* all clean bytes are out */ + if (ctx->buf_len == ctx->buf_off) { + ctx->buf_off = 0; + + /* + * copy start of the next block into proper place + */ + if (ctx->buf_len_save - ctx->buf_off_save > 0) { + ctx->buf_len = ctx->buf_len_save - ctx->buf_off_save; + memmove(ctx->buf, &(ctx->buf[ctx->buf_off_save]), + ctx->buf_len); + } else { + ctx->buf_len = 0; + } + ctx->blockout = 0; + } + } + + /* output buffer full -- cancel */ + if (outl == 0) + break; + + /* no clean bytes in buffer -- fill it */ + n = IOBS - ctx->buf_len; + i = BIO_read(b->next_bio, &(ctx->buf[ctx->buf_len]), n); + + if (i <= 0) + break; /* nothing new */ + + ctx->buf_len += i; + + /* no signature yet -- check if we got one */ + if (ctx->sigio == 1) { + if (!sig_in(b)) { + BIO_clear_retry_flags(b); + return 0; + } + } + + /* signature ok -- check if we got block */ + if (ctx->sigio == 0) { + if (!block_in(b)) { + BIO_clear_retry_flags(b); + return 0; + } + } + + /* invalid block -- cancel */ + if (ctx->cont <= 0) + break; + + } + + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return (ret); +} + +static int ok_write(BIO *b, const char *in, int inl) +{ + int ret = 0, n, i; + BIO_OK_CTX *ctx; + + if (inl <= 0) + return inl; + + ctx = (BIO_OK_CTX *)b->ptr; + ret = inl; + + if ((ctx == NULL) || (b->next_bio == NULL) || (b->init == 0)) + return (0); + + if (ctx->sigio && !sig_out(b)) + return 0; + + do { + BIO_clear_retry_flags(b); + n = ctx->buf_len - ctx->buf_off; + while (ctx->blockout && n > 0) { + i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n); + if (i <= 0) { + BIO_copy_next_retry(b); + if (!BIO_should_retry(b)) + ctx->cont = 0; + return (i); + } + ctx->buf_off += i; + n -= i; + } + + /* at this point all pending data has been written */ + ctx->blockout = 0; + if (ctx->buf_len == ctx->buf_off) { + ctx->buf_len = OK_BLOCK_BLOCK; + ctx->buf_off = 0; + } + + if ((in == NULL) || (inl <= 0)) + return (0); + + n = (inl + ctx->buf_len > OK_BLOCK_SIZE + OK_BLOCK_BLOCK) ? + (int)(OK_BLOCK_SIZE + OK_BLOCK_BLOCK - ctx->buf_len) : inl; + + memcpy((unsigned char *)(&(ctx->buf[ctx->buf_len])), + (unsigned char *)in, n); + ctx->buf_len += n; + inl -= n; + in += n; + + if (ctx->buf_len >= OK_BLOCK_SIZE + OK_BLOCK_BLOCK) { + if (!block_out(b)) { + BIO_clear_retry_flags(b); + return 0; + } + } + } while (inl > 0); + + BIO_clear_retry_flags(b); + BIO_copy_next_retry(b); + return (ret); +} + +static long ok_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + BIO_OK_CTX *ctx; + EVP_MD *md; + const EVP_MD **ppmd; + long ret = 1; + int i; + + ctx = b->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ctx->buf_len = 0; + ctx->buf_off = 0; + ctx->buf_len_save = 0; + ctx->buf_off_save = 0; + ctx->cont = 1; + ctx->finished = 0; + ctx->blockout = 0; + ctx->sigio = 1; + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_EOF: /* More to read */ + if (ctx->cont <= 0) + ret = 1; + else + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_PENDING: /* More to read in buffer */ + case BIO_CTRL_WPENDING: /* More to read in buffer */ + ret = ctx->blockout ? ctx->buf_len - ctx->buf_off : 0; + if (ret <= 0) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_CTRL_FLUSH: + /* do a final write */ + if (ctx->blockout == 0) + if (!block_out(b)) + return 0; + + while (ctx->blockout) { + i = ok_write(b, NULL, 0); + if (i < 0) { + ret = i; + break; + } + } + + ctx->finished = 1; + ctx->buf_off = ctx->buf_len = 0; + ctx->cont = (int)ret; + + /* Finally flush the underlying BIO */ + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + case BIO_CTRL_INFO: + ret = (long)ctx->cont; + break; + case BIO_C_SET_MD: + md = ptr; + if (!EVP_DigestInit_ex(&ctx->md, md, NULL)) + return 0; + b->init = 1; + break; + case BIO_C_GET_MD: + if (b->init) { + ppmd = ptr; + *ppmd = ctx->md.digest; + } else + ret = 0; + break; + default: + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + break; + } + return (ret); +} + +static long ok_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + long ret = 1; + + if (b->next_bio == NULL) + return (0); + switch (cmd) { + default: + ret = BIO_callback_ctrl(b->next_bio, cmd, fp); + break; + } + return (ret); +} + +static void longswap(void *_ptr, size_t len) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + + if (is_endian.little) { + size_t i; + unsigned char *p = _ptr, c; + + for (i = 0; i < len; i += 4) { + c = p[0], p[0] = p[3], p[3] = c; + c = p[1], p[1] = p[2], p[2] = c; + } + } +} + +static int sig_out(BIO *b) +{ + BIO_OK_CTX *ctx; + EVP_MD_CTX *md; + + ctx = b->ptr; + md = &ctx->md; + + if (ctx->buf_len + 2 * md->digest->md_size > OK_BLOCK_SIZE) + return 1; + + if (!EVP_DigestInit_ex(md, md->digest, NULL)) + goto berr; + /* + * FIXME: there's absolutely no guarantee this makes any sense at all, + * particularly now EVP_MD_CTX has been restructured. + */ + if (RAND_pseudo_bytes(md->md_data, md->digest->md_size) < 0) + goto berr; + memcpy(&(ctx->buf[ctx->buf_len]), md->md_data, md->digest->md_size); + longswap(&(ctx->buf[ctx->buf_len]), md->digest->md_size); + ctx->buf_len += md->digest->md_size; + + if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN))) + goto berr; + if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL)) + goto berr; + ctx->buf_len += md->digest->md_size; + ctx->blockout = 1; + ctx->sigio = 0; + return 1; + berr: + BIO_clear_retry_flags(b); + return 0; +} + +static int sig_in(BIO *b) +{ + BIO_OK_CTX *ctx; + EVP_MD_CTX *md; + unsigned char tmp[EVP_MAX_MD_SIZE]; + int ret = 0; + + ctx = b->ptr; + md = &ctx->md; + + if ((int)(ctx->buf_len - ctx->buf_off) < 2 * md->digest->md_size) + return 1; + + if (!EVP_DigestInit_ex(md, md->digest, NULL)) + goto berr; + memcpy(md->md_data, &(ctx->buf[ctx->buf_off]), md->digest->md_size); + longswap(md->md_data, md->digest->md_size); + ctx->buf_off += md->digest->md_size; + + if (!EVP_DigestUpdate(md, WELLKNOWN, strlen(WELLKNOWN))) + goto berr; + if (!EVP_DigestFinal_ex(md, tmp, NULL)) + goto berr; + ret = memcmp(&(ctx->buf[ctx->buf_off]), tmp, md->digest->md_size) == 0; + ctx->buf_off += md->digest->md_size; + if (ret == 1) { + ctx->sigio = 0; + if (ctx->buf_len != ctx->buf_off) { + memmove(ctx->buf, &(ctx->buf[ctx->buf_off]), + ctx->buf_len - ctx->buf_off); + } + ctx->buf_len -= ctx->buf_off; + ctx->buf_off = 0; + } else { + ctx->cont = 0; + } + return 1; + berr: + BIO_clear_retry_flags(b); + return 0; +} + +static int block_out(BIO *b) +{ + BIO_OK_CTX *ctx; + EVP_MD_CTX *md; + unsigned long tl; + + ctx = b->ptr; + md = &ctx->md; + + tl = ctx->buf_len - OK_BLOCK_BLOCK; + ctx->buf[0] = (unsigned char)(tl >> 24); + ctx->buf[1] = (unsigned char)(tl >> 16); + ctx->buf[2] = (unsigned char)(tl >> 8); + ctx->buf[3] = (unsigned char)(tl); + if (!EVP_DigestUpdate(md, + (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl)) + goto berr; + if (!EVP_DigestFinal_ex(md, &(ctx->buf[ctx->buf_len]), NULL)) + goto berr; + ctx->buf_len += md->digest->md_size; + ctx->blockout = 1; + return 1; + berr: + BIO_clear_retry_flags(b); + return 0; +} + +static int block_in(BIO *b) +{ + BIO_OK_CTX *ctx; + EVP_MD_CTX *md; + unsigned long tl = 0; + unsigned char tmp[EVP_MAX_MD_SIZE]; + + ctx = b->ptr; + md = &ctx->md; + + assert(sizeof(tl) >= OK_BLOCK_BLOCK); /* always true */ + tl = ctx->buf[0]; + tl <<= 8; + tl |= ctx->buf[1]; + tl <<= 8; + tl |= ctx->buf[2]; + tl <<= 8; + tl |= ctx->buf[3]; + + if (ctx->buf_len < tl + OK_BLOCK_BLOCK + md->digest->md_size) + return 1; + + if (!EVP_DigestUpdate(md, + (unsigned char *)&(ctx->buf[OK_BLOCK_BLOCK]), tl)) + goto berr; + if (!EVP_DigestFinal_ex(md, tmp, NULL)) + goto berr; + if (memcmp(&(ctx->buf[tl + OK_BLOCK_BLOCK]), tmp, md->digest->md_size) == + 0) { + /* there might be parts from next block lurking around ! */ + ctx->buf_off_save = tl + OK_BLOCK_BLOCK + md->digest->md_size; + ctx->buf_len_save = ctx->buf_len; + ctx->buf_off = OK_BLOCK_BLOCK; + ctx->buf_len = tl + OK_BLOCK_BLOCK; + ctx->blockout = 1; + } else { + ctx->cont = 0; + } + return 1; + berr: + BIO_clear_retry_flags(b); + return 0; +} diff --git a/libs/openssl/crypto/evp/c_all.c b/libs/openssl/crypto/evp/c_all.c new file mode 100644 index 00000000..a3ed00d4 --- /dev/null +++ b/libs/openssl/crypto/evp/c_all.c @@ -0,0 +1,90 @@ +/* crypto/evp/c_all.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif + +#if 0 +# undef OpenSSL_add_all_algorithms + +void OpenSSL_add_all_algorithms(void) +{ + OPENSSL_add_all_algorithms_noconf(); +} +#endif + +void OPENSSL_add_all_algorithms_noconf(void) +{ + /* + * For the moment OPENSSL_cpuid_setup does something + * only on IA-32, but we reserve the option for all + * platforms... + */ + OPENSSL_cpuid_setup(); + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); +#ifndef OPENSSL_NO_ENGINE +# if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(HAVE_CRYPTODEV) + ENGINE_setup_bsd_cryptodev(); +# endif +#endif +} diff --git a/libs/openssl/crypto/evp/c_allc.c b/libs/openssl/crypto/evp/c_allc.c new file mode 100644 index 00000000..3097c211 --- /dev/null +++ b/libs/openssl/crypto/evp/c_allc.c @@ -0,0 +1,230 @@ +/* crypto/evp/c_allc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +void OpenSSL_add_all_ciphers(void) +{ + +#ifndef OPENSSL_NO_DES + EVP_add_cipher(EVP_des_cfb()); + EVP_add_cipher(EVP_des_cfb1()); + EVP_add_cipher(EVP_des_cfb8()); + EVP_add_cipher(EVP_des_ede_cfb()); + EVP_add_cipher(EVP_des_ede3_cfb()); + EVP_add_cipher(EVP_des_ede3_cfb1()); + EVP_add_cipher(EVP_des_ede3_cfb8()); + + EVP_add_cipher(EVP_des_ofb()); + EVP_add_cipher(EVP_des_ede_ofb()); + EVP_add_cipher(EVP_des_ede3_ofb()); + + EVP_add_cipher(EVP_desx_cbc()); + EVP_add_cipher_alias(SN_desx_cbc, "DESX"); + EVP_add_cipher_alias(SN_desx_cbc, "desx"); + + EVP_add_cipher(EVP_des_cbc()); + EVP_add_cipher_alias(SN_des_cbc, "DES"); + EVP_add_cipher_alias(SN_des_cbc, "des"); + EVP_add_cipher(EVP_des_ede_cbc()); + EVP_add_cipher(EVP_des_ede3_cbc()); + EVP_add_cipher_alias(SN_des_ede3_cbc, "DES3"); + EVP_add_cipher_alias(SN_des_ede3_cbc, "des3"); + + EVP_add_cipher(EVP_des_ecb()); + EVP_add_cipher(EVP_des_ede()); + EVP_add_cipher(EVP_des_ede3()); +#endif + +#ifndef OPENSSL_NO_RC4 + EVP_add_cipher(EVP_rc4()); + EVP_add_cipher(EVP_rc4_40()); +# ifndef OPENSSL_NO_MD5 + EVP_add_cipher(EVP_rc4_hmac_md5()); +# endif +#endif + +#ifndef OPENSSL_NO_IDEA + EVP_add_cipher(EVP_idea_ecb()); + EVP_add_cipher(EVP_idea_cfb()); + EVP_add_cipher(EVP_idea_ofb()); + EVP_add_cipher(EVP_idea_cbc()); + EVP_add_cipher_alias(SN_idea_cbc, "IDEA"); + EVP_add_cipher_alias(SN_idea_cbc, "idea"); +#endif + +#ifndef OPENSSL_NO_SEED + EVP_add_cipher(EVP_seed_ecb()); + EVP_add_cipher(EVP_seed_cfb()); + EVP_add_cipher(EVP_seed_ofb()); + EVP_add_cipher(EVP_seed_cbc()); + EVP_add_cipher_alias(SN_seed_cbc, "SEED"); + EVP_add_cipher_alias(SN_seed_cbc, "seed"); +#endif + +#ifndef OPENSSL_NO_RC2 + EVP_add_cipher(EVP_rc2_ecb()); + EVP_add_cipher(EVP_rc2_cfb()); + EVP_add_cipher(EVP_rc2_ofb()); + EVP_add_cipher(EVP_rc2_cbc()); + EVP_add_cipher(EVP_rc2_40_cbc()); + EVP_add_cipher(EVP_rc2_64_cbc()); + EVP_add_cipher_alias(SN_rc2_cbc, "RC2"); + EVP_add_cipher_alias(SN_rc2_cbc, "rc2"); +#endif + +#ifndef OPENSSL_NO_BF + EVP_add_cipher(EVP_bf_ecb()); + EVP_add_cipher(EVP_bf_cfb()); + EVP_add_cipher(EVP_bf_ofb()); + EVP_add_cipher(EVP_bf_cbc()); + EVP_add_cipher_alias(SN_bf_cbc, "BF"); + EVP_add_cipher_alias(SN_bf_cbc, "bf"); + EVP_add_cipher_alias(SN_bf_cbc, "blowfish"); +#endif + +#ifndef OPENSSL_NO_CAST + EVP_add_cipher(EVP_cast5_ecb()); + EVP_add_cipher(EVP_cast5_cfb()); + EVP_add_cipher(EVP_cast5_ofb()); + EVP_add_cipher(EVP_cast5_cbc()); + EVP_add_cipher_alias(SN_cast5_cbc, "CAST"); + EVP_add_cipher_alias(SN_cast5_cbc, "cast"); + EVP_add_cipher_alias(SN_cast5_cbc, "CAST-cbc"); + EVP_add_cipher_alias(SN_cast5_cbc, "cast-cbc"); +#endif + +#ifndef OPENSSL_NO_RC5 + EVP_add_cipher(EVP_rc5_32_12_16_ecb()); + EVP_add_cipher(EVP_rc5_32_12_16_cfb()); + EVP_add_cipher(EVP_rc5_32_12_16_ofb()); + EVP_add_cipher(EVP_rc5_32_12_16_cbc()); + EVP_add_cipher_alias(SN_rc5_cbc, "rc5"); + EVP_add_cipher_alias(SN_rc5_cbc, "RC5"); +#endif + +#ifndef OPENSSL_NO_AES + EVP_add_cipher(EVP_aes_128_ecb()); + EVP_add_cipher(EVP_aes_128_cbc()); + EVP_add_cipher(EVP_aes_128_cfb()); + EVP_add_cipher(EVP_aes_128_cfb1()); + EVP_add_cipher(EVP_aes_128_cfb8()); + EVP_add_cipher(EVP_aes_128_ofb()); + EVP_add_cipher(EVP_aes_128_ctr()); + EVP_add_cipher(EVP_aes_128_gcm()); + EVP_add_cipher(EVP_aes_128_xts()); + EVP_add_cipher_alias(SN_aes_128_cbc, "AES128"); + EVP_add_cipher_alias(SN_aes_128_cbc, "aes128"); + EVP_add_cipher(EVP_aes_192_ecb()); + EVP_add_cipher(EVP_aes_192_cbc()); + EVP_add_cipher(EVP_aes_192_cfb()); + EVP_add_cipher(EVP_aes_192_cfb1()); + EVP_add_cipher(EVP_aes_192_cfb8()); + EVP_add_cipher(EVP_aes_192_ofb()); + EVP_add_cipher(EVP_aes_192_ctr()); + EVP_add_cipher(EVP_aes_192_gcm()); + EVP_add_cipher_alias(SN_aes_192_cbc, "AES192"); + EVP_add_cipher_alias(SN_aes_192_cbc, "aes192"); + EVP_add_cipher(EVP_aes_256_ecb()); + EVP_add_cipher(EVP_aes_256_cbc()); + EVP_add_cipher(EVP_aes_256_cfb()); + EVP_add_cipher(EVP_aes_256_cfb1()); + EVP_add_cipher(EVP_aes_256_cfb8()); + EVP_add_cipher(EVP_aes_256_ofb()); + EVP_add_cipher(EVP_aes_256_ctr()); + EVP_add_cipher(EVP_aes_256_gcm()); + EVP_add_cipher(EVP_aes_256_xts()); + EVP_add_cipher_alias(SN_aes_256_cbc, "AES256"); + EVP_add_cipher_alias(SN_aes_256_cbc, "aes256"); +# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) + EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); + EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); +# endif +#endif + +#ifndef OPENSSL_NO_CAMELLIA + EVP_add_cipher(EVP_camellia_128_ecb()); + EVP_add_cipher(EVP_camellia_128_cbc()); + EVP_add_cipher(EVP_camellia_128_cfb()); + EVP_add_cipher(EVP_camellia_128_cfb1()); + EVP_add_cipher(EVP_camellia_128_cfb8()); + EVP_add_cipher(EVP_camellia_128_ofb()); + EVP_add_cipher_alias(SN_camellia_128_cbc, "CAMELLIA128"); + EVP_add_cipher_alias(SN_camellia_128_cbc, "camellia128"); + EVP_add_cipher(EVP_camellia_192_ecb()); + EVP_add_cipher(EVP_camellia_192_cbc()); + EVP_add_cipher(EVP_camellia_192_cfb()); + EVP_add_cipher(EVP_camellia_192_cfb1()); + EVP_add_cipher(EVP_camellia_192_cfb8()); + EVP_add_cipher(EVP_camellia_192_ofb()); + EVP_add_cipher_alias(SN_camellia_192_cbc, "CAMELLIA192"); + EVP_add_cipher_alias(SN_camellia_192_cbc, "camellia192"); + EVP_add_cipher(EVP_camellia_256_ecb()); + EVP_add_cipher(EVP_camellia_256_cbc()); + EVP_add_cipher(EVP_camellia_256_cfb()); + EVP_add_cipher(EVP_camellia_256_cfb1()); + EVP_add_cipher(EVP_camellia_256_cfb8()); + EVP_add_cipher(EVP_camellia_256_ofb()); + EVP_add_cipher_alias(SN_camellia_256_cbc, "CAMELLIA256"); + EVP_add_cipher_alias(SN_camellia_256_cbc, "camellia256"); +#endif +} diff --git a/libs/openssl/crypto/evp/c_alld.c b/libs/openssl/crypto/evp/c_alld.c new file mode 100644 index 00000000..fdbe3ee0 --- /dev/null +++ b/libs/openssl/crypto/evp/c_alld.c @@ -0,0 +1,114 @@ +/* crypto/evp/c_alld.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +void OpenSSL_add_all_digests(void) +{ +#ifndef OPENSSL_NO_MD4 + EVP_add_digest(EVP_md4()); +#endif +#ifndef OPENSSL_NO_MD5 + EVP_add_digest(EVP_md5()); + EVP_add_digest_alias(SN_md5, "ssl2-md5"); + EVP_add_digest_alias(SN_md5, "ssl3-md5"); +#endif +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0) + EVP_add_digest(EVP_sha()); +# ifndef OPENSSL_NO_DSA + EVP_add_digest(EVP_dss()); +# endif +#endif +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) + EVP_add_digest(EVP_sha1()); + EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); + EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); +# ifndef OPENSSL_NO_DSA + EVP_add_digest(EVP_dss1()); + EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2); + EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); + EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); +# endif +# ifndef OPENSSL_NO_ECDSA + EVP_add_digest(EVP_ecdsa()); +# endif +#endif +#if !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES) + EVP_add_digest(EVP_mdc2()); +#endif +#ifndef OPENSSL_NO_RIPEMD + EVP_add_digest(EVP_ripemd160()); + EVP_add_digest_alias(SN_ripemd160, "ripemd"); + EVP_add_digest_alias(SN_ripemd160, "rmd160"); +#endif +#ifndef OPENSSL_NO_SHA256 + EVP_add_digest(EVP_sha224()); + EVP_add_digest(EVP_sha256()); +#endif +#ifndef OPENSSL_NO_SHA512 + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); +#endif +#ifndef OPENSSL_NO_WHIRLPOOL + EVP_add_digest(EVP_whirlpool()); +#endif +} diff --git a/libs/openssl/crypto/evp/digest.c b/libs/openssl/crypto/evp/digest.c new file mode 100644 index 00000000..32167b29 --- /dev/null +++ b/libs/openssl/crypto/evp/digest.c @@ -0,0 +1,396 @@ +/* crypto/evp/digest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif + +#ifdef OPENSSL_FIPS +# include +#endif + +void EVP_MD_CTX_init(EVP_MD_CTX *ctx) +{ + memset(ctx, '\0', sizeof *ctx); +} + +EVP_MD_CTX *EVP_MD_CTX_create(void) +{ + EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof *ctx); + + if (ctx) + EVP_MD_CTX_init(ctx); + + return ctx; +} + +int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type) +{ + EVP_MD_CTX_init(ctx); + return EVP_DigestInit_ex(ctx, type, NULL); +} + +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) +{ + EVP_MD_CTX_clear_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); +#ifndef OPENSSL_NO_ENGINE + /* + * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so + * this context may already have an ENGINE! Try to avoid releasing the + * previous handle, re-querying for an ENGINE, and having a + * reinitialisation, when it may all be unecessary. + */ + if (ctx->engine && ctx->digest && (!type || + (type + && (type->type == + ctx->digest->type)))) + goto skip_to_init; + if (type) { + /* + * Ensure an ENGINE left lying around from last time is cleared (the + * previous check attempted to avoid this if the same ENGINE and + * EVP_MD could be used). + */ + if (ctx->engine) + ENGINE_finish(ctx->engine); + if (impl) { + if (!ENGINE_init(impl)) { + EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR); + return 0; + } + } else + /* Ask if an ENGINE is reserved for this job */ + impl = ENGINE_get_digest_engine(type->type); + if (impl) { + /* There's an ENGINE for this job ... (apparently) */ + const EVP_MD *d = ENGINE_get_digest(impl, type->type); + if (!d) { + /* Same comment from evp_enc.c */ + EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_INITIALIZATION_ERROR); + ENGINE_finish(impl); + return 0; + } + /* We'll use the ENGINE's private digest definition */ + type = d; + /* + * Store the ENGINE functional reference so we know 'type' came + * from an ENGINE and we need to release it when done. + */ + ctx->engine = impl; + } else + ctx->engine = NULL; + } else { + if (!ctx->digest) { + EVPerr(EVP_F_EVP_DIGESTINIT_EX, EVP_R_NO_DIGEST_SET); + return 0; + } + type = ctx->digest; + } +#endif + if (ctx->digest != type) { + if (ctx->digest && ctx->digest->ctx_size) { + OPENSSL_free(ctx->md_data); + ctx->md_data = NULL; + } + ctx->digest = type; + if (!(ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) && type->ctx_size) { + ctx->update = type->update; + ctx->md_data = OPENSSL_malloc(type->ctx_size); + if (ctx->md_data == NULL) { + EVPerr(EVP_F_EVP_DIGESTINIT_EX, ERR_R_MALLOC_FAILURE); + return 0; + } + } + } +#ifndef OPENSSL_NO_ENGINE + skip_to_init: +#endif + if (ctx->pctx) { + int r; + r = EVP_PKEY_CTX_ctrl(ctx->pctx, -1, EVP_PKEY_OP_TYPE_SIG, + EVP_PKEY_CTRL_DIGESTINIT, 0, ctx); + if (r <= 0 && (r != -2)) + return 0; + } + if (ctx->flags & EVP_MD_CTX_FLAG_NO_INIT) + return 1; +#ifdef OPENSSL_FIPS + if (FIPS_mode()) { + if (FIPS_digestinit(ctx, type)) + return 1; + OPENSSL_free(ctx->md_data); + ctx->md_data = NULL; + return 0; + } +#endif + return ctx->digest->init(ctx); +} + +int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t count) +{ +#ifdef OPENSSL_FIPS + return FIPS_digestupdate(ctx, data, count); +#else + return ctx->update(ctx, data, count); +#endif +} + +/* The caller can assume that this removes any secret data from the context */ +int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) +{ + int ret; + ret = EVP_DigestFinal_ex(ctx, md, size); + EVP_MD_CTX_cleanup(ctx); + return ret; +} + +/* The caller can assume that this removes any secret data from the context */ +int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *size) +{ +#ifdef OPENSSL_FIPS + return FIPS_digestfinal(ctx, md, size); +#else + int ret; + + OPENSSL_assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); + ret = ctx->digest->final(ctx, md); + if (size != NULL) + *size = ctx->digest->md_size; + if (ctx->digest->cleanup) { + ctx->digest->cleanup(ctx); + EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_CLEANED); + } + memset(ctx->md_data, 0, ctx->digest->ctx_size); + return ret; +#endif +} + +int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in) +{ + EVP_MD_CTX_init(out); + return EVP_MD_CTX_copy_ex(out, in); +} + +int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) +{ + unsigned char *tmp_buf; + if ((in == NULL) || (in->digest == NULL)) { + EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, EVP_R_INPUT_NOT_INITIALIZED); + return 0; + } +#ifndef OPENSSL_NO_ENGINE + /* Make sure it's safe to copy a digest context using an ENGINE */ + if (in->engine && !ENGINE_init(in->engine)) { + EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_ENGINE_LIB); + return 0; + } +#endif + + if (out->digest == in->digest) { + tmp_buf = out->md_data; + EVP_MD_CTX_set_flags(out, EVP_MD_CTX_FLAG_REUSE); + } else + tmp_buf = NULL; + EVP_MD_CTX_cleanup(out); + memcpy(out, in, sizeof *out); + + if (in->md_data && out->digest->ctx_size) { + if (tmp_buf) + out->md_data = tmp_buf; + else { + out->md_data = OPENSSL_malloc(out->digest->ctx_size); + if (!out->md_data) { + EVPerr(EVP_F_EVP_MD_CTX_COPY_EX, ERR_R_MALLOC_FAILURE); + return 0; + } + } + memcpy(out->md_data, in->md_data, out->digest->ctx_size); + } + + out->update = in->update; + + if (in->pctx) { + out->pctx = EVP_PKEY_CTX_dup(in->pctx); + if (!out->pctx) { + EVP_MD_CTX_cleanup(out); + return 0; + } + } + + if (out->digest->copy) + return out->digest->copy(out, in); + + return 1; +} + +int EVP_Digest(const void *data, size_t count, + unsigned char *md, unsigned int *size, const EVP_MD *type, + ENGINE *impl) +{ + EVP_MD_CTX ctx; + int ret; + + EVP_MD_CTX_init(&ctx); + EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_ONESHOT); + ret = EVP_DigestInit_ex(&ctx, type, impl) + && EVP_DigestUpdate(&ctx, data, count) + && EVP_DigestFinal_ex(&ctx, md, size); + EVP_MD_CTX_cleanup(&ctx); + + return ret; +} + +void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) +{ + if (ctx) { + EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(ctx); + } +} + +/* This call frees resources associated with the context */ +int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) +{ +#ifndef OPENSSL_FIPS + /* + * Don't assume ctx->md_data was cleaned in EVP_Digest_Final, because + * sometimes only copies of the context are ever finalised. + */ + if (ctx->digest && ctx->digest->cleanup + && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_CLEANED)) + ctx->digest->cleanup(ctx); + if (ctx->digest && ctx->digest->ctx_size && ctx->md_data + && !EVP_MD_CTX_test_flags(ctx, EVP_MD_CTX_FLAG_REUSE)) { + OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); + OPENSSL_free(ctx->md_data); + } +#endif + if (ctx->pctx) + EVP_PKEY_CTX_free(ctx->pctx); +#ifndef OPENSSL_NO_ENGINE + if (ctx->engine) + /* + * The EVP_MD we used belongs to an ENGINE, release the functional + * reference we held for this reason. + */ + ENGINE_finish(ctx->engine); +#endif +#ifdef OPENSSL_FIPS + FIPS_md_ctx_cleanup(ctx); +#endif + memset(ctx, '\0', sizeof *ctx); + + return 1; +} diff --git a/libs/openssl/crypto/evp/e_aes.c b/libs/openssl/crypto/evp/e_aes.c new file mode 100644 index 00000000..a4327fcb --- /dev/null +++ b/libs/openssl/crypto/evp/e_aes.c @@ -0,0 +1,1286 @@ +/* ==================================================================== + * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#ifndef OPENSSL_NO_AES +#include +# include +# include +# include +# include +# include +# include "evp_locl.h" +# ifndef OPENSSL_FIPS +# include "modes_lcl.h" +# include + +typedef struct { + AES_KEY ks; + block128_f block; + union { + cbc128_f cbc; + ctr128_f ctr; + } stream; +} EVP_AES_KEY; + +typedef struct { + AES_KEY ks; /* AES key schedule to use */ + int key_set; /* Set if key initialised */ + int iv_set; /* Set if an iv is set */ + GCM128_CONTEXT gcm; + unsigned char *iv; /* Temporary IV store */ + int ivlen; /* IV length */ + int taglen; + int iv_gen; /* It is OK to generate IVs */ + int tls_aad_len; /* TLS AAD length */ + ctr128_f ctr; +} EVP_AES_GCM_CTX; + +typedef struct { + AES_KEY ks1, ks2; /* AES key schedules to use */ + XTS128_CONTEXT xts; + void (*stream) (const unsigned char *in, + unsigned char *out, size_t length, + const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); +} EVP_AES_XTS_CTX; + +typedef struct { + AES_KEY ks; /* AES key schedule to use */ + int key_set; /* Set if key initialised */ + int iv_set; /* Set if an iv is set */ + int tag_set; /* Set if tag is valid */ + int len_set; /* Set if message length set */ + int L, M; /* L and M parameters from RFC3610 */ + CCM128_CONTEXT ccm; + ccm128_f str; +} EVP_AES_CCM_CTX; + +# define MAXBITCHUNK ((size_t)1<<(sizeof(size_t)*8-4)) + +# ifdef VPAES_ASM +int vpaes_set_encrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); +int vpaes_set_decrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); + +void vpaes_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void vpaes_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void vpaes_cbc_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key, unsigned char *ivec, int enc); +# endif +# ifdef BSAES_ASM +void bsaes_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const AES_KEY *key, + unsigned char ivec[16], int enc); +void bsaes_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY *key, + const unsigned char ivec[16]); +void bsaes_xts_encrypt(const unsigned char *inp, unsigned char *out, + size_t len, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char iv[16]); +void bsaes_xts_decrypt(const unsigned char *inp, unsigned char *out, + size_t len, const AES_KEY *key1, + const AES_KEY *key2, const unsigned char iv[16]); +# endif +# ifdef AES_CTR_ASM +void AES_ctr32_encrypt(const unsigned char *in, unsigned char *out, + size_t blocks, const AES_KEY *key, + const unsigned char ivec[AES_BLOCK_SIZE]); +# endif +# ifdef AES_XTS_ASM +void AES_xts_encrypt(const char *inp, char *out, size_t len, + const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); +void AES_xts_decrypt(const char *inp, char *out, size_t len, + const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); +# endif + +# if defined(AES_ASM) && !defined(I386_ONLY) && ( \ + ((defined(__i386) || defined(__i386__) || \ + defined(_M_IX86)) && defined(OPENSSL_IA32_SSE2))|| \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) || \ + defined(__INTEL__) ) + +extern unsigned int OPENSSL_ia32cap_P[2]; + +# ifdef VPAES_ASM +# define VPAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) +# endif +# ifdef BSAES_ASM +# define BSAES_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(41-32))) +# endif +/* + * AES-NI section + */ +# define AESNI_CAPABLE (OPENSSL_ia32cap_P[1]&(1<<(57-32))) + +int aesni_set_encrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); +int aesni_set_decrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); + +void aesni_encrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); +void aesni_decrypt(const unsigned char *in, unsigned char *out, + const AES_KEY *key); + +void aesni_ecb_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, const AES_KEY *key, int enc); +void aesni_cbc_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key, unsigned char *ivec, int enc); + +void aesni_ctr32_encrypt_blocks(const unsigned char *in, + unsigned char *out, + size_t blocks, + const void *key, const unsigned char *ivec); + +void aesni_xts_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); + +void aesni_xts_decrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key1, const AES_KEY *key2, + const unsigned char iv[16]); + +void aesni_ccm64_encrypt_blocks(const unsigned char *in, + unsigned char *out, + size_t blocks, + const void *key, + const unsigned char ivec[16], + unsigned char cmac[16]); + +void aesni_ccm64_decrypt_blocks(const unsigned char *in, + unsigned char *out, + size_t blocks, + const void *key, + const unsigned char ivec[16], + unsigned char cmac[16]); + +static int aesni_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + int ret, mode; + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + mode = ctx->cipher->flags & EVP_CIPH_MODE; + if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) + && !enc) { + ret = aesni_set_decrypt_key(key, ctx->key_len * 8, ctx->cipher_data); + dat->block = (block128_f) aesni_decrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) aesni_cbc_encrypt : NULL; + } else { + ret = aesni_set_encrypt_key(key, ctx->key_len * 8, ctx->cipher_data); + dat->block = (block128_f) aesni_encrypt; + if (mode == EVP_CIPH_CBC_MODE) + dat->stream.cbc = (cbc128_f) aesni_cbc_encrypt; + else if (mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f) aesni_ctr32_encrypt_blocks; + else + dat->stream.cbc = NULL; + } + + if (ret < 0) { + EVPerr(EVP_F_AESNI_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + aesni_cbc_encrypt(in, out, len, ctx->cipher_data, ctx->iv, ctx->encrypt); + + return 1; +} + +static int aesni_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + size_t bl = ctx->cipher->block_size; + + if (len < bl) + return 1; + + aesni_ecb_encrypt(in, out, len, ctx->cipher_data, ctx->encrypt); + + return 1; +} + +# define aesni_ofb_cipher aes_ofb_cipher +static int aesni_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define aesni_cfb_cipher aes_cfb_cipher +static int aesni_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define aesni_cfb8_cipher aes_cfb8_cipher +static int aesni_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define aesni_cfb1_cipher aes_cfb1_cipher +static int aesni_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define aesni_ctr_cipher aes_ctr_cipher +static int aesni_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + if (!iv && !key) + return 1; + if (key) { + aesni_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks); + CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, (block128_f) aesni_encrypt); + gctx->ctr = (ctr128_f) aesni_ctr32_encrypt_blocks; + /* + * If we have an iv can set it directly, otherwise use saved IV. + */ + if (iv == NULL && gctx->iv_set) + iv = gctx->iv; + if (iv) { + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + gctx->iv_set = 1; + } + gctx->key_set = 1; + } else { + /* If key set use IV, otherwise copy */ + if (gctx->key_set) + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + else + memcpy(gctx->iv, iv, gctx->ivlen); + gctx->iv_set = 1; + gctx->iv_gen = 0; + } + return 1; +} + +# define aesni_gcm_cipher aes_gcm_cipher +static int aesni_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +static int aesni_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_XTS_CTX *xctx = ctx->cipher_data; + if (!iv && !key) + return 1; + + if (key) { + /* key_len is two AES keys */ + if (enc) { + aesni_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1); + xctx->xts.block1 = (block128_f) aesni_encrypt; + xctx->stream = aesni_xts_encrypt; + } else { + aesni_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1); + xctx->xts.block1 = (block128_f) aesni_decrypt; + xctx->stream = aesni_xts_decrypt; + } + + aesni_set_encrypt_key(key + ctx->key_len / 2, + ctx->key_len * 4, &xctx->ks2); + xctx->xts.block2 = (block128_f) aesni_encrypt; + + xctx->xts.key1 = &xctx->ks1; + } + + if (iv) { + xctx->xts.key2 = &xctx->ks2; + memcpy(ctx->iv, iv, 16); + } + + return 1; +} + +# define aesni_xts_cipher aes_xts_cipher +static int aesni_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +static int aesni_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_CCM_CTX *cctx = ctx->cipher_data; + if (!iv && !key) + return 1; + if (key) { + aesni_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks); + CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, + &cctx->ks, (block128_f) aesni_encrypt); + cctx->str = enc ? (ccm128_f) aesni_ccm64_encrypt_blocks : + (ccm128_f) aesni_ccm64_decrypt_blocks; + cctx->key_set = 1; + } + if (iv) { + memcpy(ctx->iv, iv, 15 - cctx->L); + cctx->iv_set = 1; + } + return 1; +} + +# define aesni_ccm_cipher aes_ccm_cipher +static int aesni_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len); + +# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ +static const EVP_CIPHER aesni_##keylen##_##mode = { \ + nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aesni_init_key, \ + aesni_##mode##_cipher, \ + NULL, \ + sizeof(EVP_AES_KEY), \ + NULL,NULL,NULL,NULL }; \ +static const EVP_CIPHER aes_##keylen##_##mode = { \ + nid##_##keylen##_##nmode,blocksize, \ + keylen/8,ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aes_init_key, \ + aes_##mode##_cipher, \ + NULL, \ + sizeof(EVP_AES_KEY), \ + NULL,NULL,NULL,NULL }; \ +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ +{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; } + +# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ +static const EVP_CIPHER aesni_##keylen##_##mode = { \ + nid##_##keylen##_##mode,blocksize, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aesni_##mode##_init_key, \ + aesni_##mode##_cipher, \ + aes_##mode##_cleanup, \ + sizeof(EVP_AES_##MODE##_CTX), \ + NULL,NULL,aes_##mode##_ctrl,NULL }; \ +static const EVP_CIPHER aes_##keylen##_##mode = { \ + nid##_##keylen##_##mode,blocksize, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aes_##mode##_init_key, \ + aes_##mode##_cipher, \ + aes_##mode##_cleanup, \ + sizeof(EVP_AES_##MODE##_CTX), \ + NULL,NULL,aes_##mode##_ctrl,NULL }; \ +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ +{ return AESNI_CAPABLE?&aesni_##keylen##_##mode:&aes_##keylen##_##mode; } + +# else + +# define BLOCK_CIPHER_generic(nid,keylen,blocksize,ivlen,nmode,mode,MODE,flags) \ +static const EVP_CIPHER aes_##keylen##_##mode = { \ + nid##_##keylen##_##nmode,blocksize,keylen/8,ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aes_init_key, \ + aes_##mode##_cipher, \ + NULL, \ + sizeof(EVP_AES_KEY), \ + NULL,NULL,NULL,NULL }; \ +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ +{ return &aes_##keylen##_##mode; } + +# define BLOCK_CIPHER_custom(nid,keylen,blocksize,ivlen,mode,MODE,flags) \ +static const EVP_CIPHER aes_##keylen##_##mode = { \ + nid##_##keylen##_##mode,blocksize, \ + (EVP_CIPH_##MODE##_MODE==EVP_CIPH_XTS_MODE?2:1)*keylen/8, ivlen, \ + flags|EVP_CIPH_##MODE##_MODE, \ + aes_##mode##_init_key, \ + aes_##mode##_cipher, \ + aes_##mode##_cleanup, \ + sizeof(EVP_AES_##MODE##_CTX), \ + NULL,NULL,aes_##mode##_ctrl,NULL }; \ +const EVP_CIPHER *EVP_aes_##keylen##_##mode(void) \ +{ return &aes_##keylen##_##mode; } +# endif + +# define BLOCK_CIPHER_generic_pack(nid,keylen,flags) \ + BLOCK_CIPHER_generic(nid,keylen,16,16,cbc,cbc,CBC,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ + BLOCK_CIPHER_generic(nid,keylen,16,0,ecb,ecb,ECB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ + BLOCK_CIPHER_generic(nid,keylen,1,16,ofb128,ofb,OFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ + BLOCK_CIPHER_generic(nid,keylen,1,16,cfb128,cfb,CFB,flags|EVP_CIPH_FLAG_DEFAULT_ASN1) \ + BLOCK_CIPHER_generic(nid,keylen,1,16,cfb1,cfb1,CFB,flags) \ + BLOCK_CIPHER_generic(nid,keylen,1,16,cfb8,cfb8,CFB,flags) \ + BLOCK_CIPHER_generic(nid,keylen,1,16,ctr,ctr,CTR,flags) + +static int aes_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + int ret, mode; + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + mode = ctx->cipher->flags & EVP_CIPH_MODE; + if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) + && !enc) +# ifdef BSAES_CAPABLE + if (BSAES_CAPABLE && mode == EVP_CIPH_CBC_MODE) { + ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks); + dat->block = (block128_f) AES_decrypt; + dat->stream.cbc = (cbc128_f) bsaes_cbc_encrypt; + } else +# endif +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + ret = vpaes_set_decrypt_key(key, ctx->key_len * 8, &dat->ks); + dat->block = (block128_f) vpaes_decrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) vpaes_cbc_encrypt : NULL; + } else +# endif + { + ret = AES_set_decrypt_key(key, ctx->key_len * 8, &dat->ks); + dat->block = (block128_f) AES_decrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) AES_cbc_encrypt : NULL; + } else +# ifdef BSAES_CAPABLE + if (BSAES_CAPABLE && mode == EVP_CIPH_CTR_MODE) { + ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks); + dat->block = (block128_f) AES_encrypt; + dat->stream.ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks; + } else +# endif +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + ret = vpaes_set_encrypt_key(key, ctx->key_len * 8, &dat->ks); + dat->block = (block128_f) vpaes_encrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) vpaes_cbc_encrypt : NULL; + } else +# endif + { + ret = AES_set_encrypt_key(key, ctx->key_len * 8, &dat->ks); + dat->block = (block128_f) AES_encrypt; + dat->stream.cbc = mode == EVP_CIPH_CBC_MODE ? + (cbc128_f) AES_cbc_encrypt : NULL; +# ifdef AES_CTR_ASM + if (mode == EVP_CIPH_CTR_MODE) + dat->stream.ctr = (ctr128_f) AES_ctr32_encrypt; +# endif + } + + if (ret < 0) { + EVPerr(EVP_F_AES_INIT_KEY, EVP_R_AES_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + if (dat->stream.cbc) + (*dat->stream.cbc) (in, out, len, &dat->ks, ctx->iv, ctx->encrypt); + else if (ctx->encrypt) + CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block); + else + CRYPTO_cbc128_encrypt(in, out, len, &dat->ks, ctx->iv, dat->block); + + return 1; +} + +static int aes_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + size_t bl = ctx->cipher->block_size; + size_t i; + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + if (len < bl) + return 1; + + for (i = 0, len -= bl; i <= len; i += bl) + (*dat->block) (in + i, out + i, &dat->ks); + + return 1; +} + +static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + CRYPTO_ofb128_encrypt(in, out, len, &dat->ks, + ctx->iv, &ctx->num, dat->block); + return 1; +} + +static int aes_cfb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + CRYPTO_cfb128_encrypt(in, out, len, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + return 1; +} + +static int aes_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + CRYPTO_cfb128_8_encrypt(in, out, len, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + return 1; +} + +static int aes_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + if (ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) { + CRYPTO_cfb128_1_encrypt(in, out, len, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + return 1; + } + + while (len >= MAXBITCHUNK) { + CRYPTO_cfb128_1_encrypt(in, out, MAXBITCHUNK * 8, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + len -= MAXBITCHUNK; + } + if (len) + CRYPTO_cfb128_1_encrypt(in, out, len * 8, &dat->ks, + ctx->iv, &ctx->num, ctx->encrypt, dat->block); + + return 1; +} + +static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + unsigned int num = ctx->num; + EVP_AES_KEY *dat = (EVP_AES_KEY *) ctx->cipher_data; + + if (dat->stream.ctr) + CRYPTO_ctr128_encrypt_ctr32(in, out, len, &dat->ks, + ctx->iv, ctx->buf, &num, dat->stream.ctr); + else + CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, + ctx->iv, ctx->buf, &num, dat->block); + ctx->num = (size_t)num; + return 1; +} + +BLOCK_CIPHER_generic_pack(NID_aes, 128, EVP_CIPH_FLAG_FIPS) + BLOCK_CIPHER_generic_pack(NID_aes, 192, EVP_CIPH_FLAG_FIPS) + BLOCK_CIPHER_generic_pack(NID_aes, 256, EVP_CIPH_FLAG_FIPS) + +static int aes_gcm_cleanup(EVP_CIPHER_CTX *c) +{ + EVP_AES_GCM_CTX *gctx = c->cipher_data; + OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm)); + if (gctx->iv != c->iv) + OPENSSL_free(gctx->iv); + return 1; +} + +/* increment counter (64-bit int) by 1 */ +static void ctr64_inc(unsigned char *counter) +{ + int n = 8; + unsigned char c; + + do { + --n; + c = counter[n]; + ++c; + counter[n] = c; + if (c) + return; + } while (n); +} + +static int aes_gcm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + EVP_AES_GCM_CTX *gctx = c->cipher_data; + switch (type) { + case EVP_CTRL_INIT: + gctx->key_set = 0; + gctx->iv_set = 0; + gctx->ivlen = c->cipher->iv_len; + gctx->iv = c->iv; + gctx->taglen = -1; + gctx->iv_gen = 0; + gctx->tls_aad_len = -1; + return 1; + + case EVP_CTRL_GCM_SET_IVLEN: + if (arg <= 0) + return 0; +# ifdef OPENSSL_FIPS + if (FIPS_module_mode() && !(c->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) + && arg < 12) + return 0; +# endif + /* Allocate memory for IV if needed */ + if ((arg > EVP_MAX_IV_LENGTH) && (arg > gctx->ivlen)) { + if (gctx->iv != c->iv) + OPENSSL_free(gctx->iv); + gctx->iv = OPENSSL_malloc(arg); + if (!gctx->iv) + return 0; + } + gctx->ivlen = arg; + return 1; + + case EVP_CTRL_GCM_SET_TAG: + if (arg <= 0 || arg > 16 || c->encrypt) + return 0; + memcpy(c->buf, ptr, arg); + gctx->taglen = arg; + return 1; + + case EVP_CTRL_GCM_GET_TAG: + if (arg <= 0 || arg > 16 || !c->encrypt || gctx->taglen < 0) + return 0; + memcpy(ptr, c->buf, arg); + return 1; + + case EVP_CTRL_GCM_SET_IV_FIXED: + /* Special case: -1 length restores whole IV */ + if (arg == -1) { + memcpy(gctx->iv, ptr, gctx->ivlen); + gctx->iv_gen = 1; + return 1; + } + /* + * Fixed field must be at least 4 bytes and invocation field at least + * 8. + */ + if ((arg < 4) || (gctx->ivlen - arg) < 8) + return 0; + if (arg) + memcpy(gctx->iv, ptr, arg); + if (c->encrypt && RAND_bytes(gctx->iv + arg, gctx->ivlen - arg) <= 0) + return 0; + gctx->iv_gen = 1; + return 1; + + case EVP_CTRL_GCM_IV_GEN: + if (gctx->iv_gen == 0 || gctx->key_set == 0) + return 0; + CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); + if (arg <= 0 || arg > gctx->ivlen) + arg = gctx->ivlen; + memcpy(ptr, gctx->iv + gctx->ivlen - arg, arg); + /* + * Invocation field will be at least 8 bytes in size and so no need + * to check wrap around or increment more than last 8 bytes. + */ + ctr64_inc(gctx->iv + gctx->ivlen - 8); + gctx->iv_set = 1; + return 1; + + case EVP_CTRL_GCM_SET_IV_INV: + if (gctx->iv_gen == 0 || gctx->key_set == 0 || c->encrypt) + return 0; + memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); + CRYPTO_gcm128_setiv(&gctx->gcm, gctx->iv, gctx->ivlen); + gctx->iv_set = 1; + return 1; + + case EVP_CTRL_AEAD_TLS1_AAD: + /* Save the AAD for later use */ + if (arg != EVP_AEAD_TLS1_AAD_LEN) + return 0; + memcpy(c->buf, ptr, arg); + gctx->tls_aad_len = arg; + { + unsigned int len = c->buf[arg - 2] << 8 | c->buf[arg - 1]; + /* Correct length for explicit IV */ + len -= EVP_GCM_TLS_EXPLICIT_IV_LEN; + /* If decrypting correct for tag too */ + if (!c->encrypt) + len -= EVP_GCM_TLS_TAG_LEN; + c->buf[arg - 2] = len >> 8; + c->buf[arg - 1] = len & 0xff; + } + /* Extra padding: tag appended to record */ + return EVP_GCM_TLS_TAG_LEN; + + case EVP_CTRL_COPY: + { + EVP_CIPHER_CTX *out = ptr; + EVP_AES_GCM_CTX *gctx_out = out->cipher_data; + if (gctx->gcm.key) { + if (gctx->gcm.key != &gctx->ks) + return 0; + gctx_out->gcm.key = &gctx_out->ks; + } + if (gctx->iv == c->iv) + gctx_out->iv = out->iv; + else { + gctx_out->iv = OPENSSL_malloc(gctx->ivlen); + if (!gctx_out->iv) + return 0; + memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); + } + return 1; + } + + default: + return -1; + + } +} + +static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + if (!iv && !key) + return 1; + if (key) { + do { +# ifdef BSAES_CAPABLE + if (BSAES_CAPABLE) { + AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks); + CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, + (block128_f) AES_encrypt); + gctx->ctr = (ctr128_f) bsaes_ctr32_encrypt_blocks; + break; + } else +# endif +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + vpaes_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks); + CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, + (block128_f) vpaes_encrypt); + gctx->ctr = NULL; + break; + } else +# endif + (void)0; /* terminate potentially open 'else' */ + + AES_set_encrypt_key(key, ctx->key_len * 8, &gctx->ks); + CRYPTO_gcm128_init(&gctx->gcm, &gctx->ks, + (block128_f) AES_encrypt); +# ifdef AES_CTR_ASM + gctx->ctr = (ctr128_f) AES_ctr32_encrypt; +# else + gctx->ctr = NULL; +# endif + } while (0); + + /* + * If we have an iv can set it directly, otherwise use saved IV. + */ + if (iv == NULL && gctx->iv_set) + iv = gctx->iv; + if (iv) { + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + gctx->iv_set = 1; + } + gctx->key_set = 1; + } else { + /* If key set use IV, otherwise copy */ + if (gctx->key_set) + CRYPTO_gcm128_setiv(&gctx->gcm, iv, gctx->ivlen); + else + memcpy(gctx->iv, iv, gctx->ivlen); + gctx->iv_set = 1; + gctx->iv_gen = 0; + } + return 1; +} + +/* + * Handle TLS GCM packet format. This consists of the last portion of the IV + * followed by the payload and finally the tag. On encrypt generate IV, + * encrypt payload and write the tag. On verify retrieve IV, decrypt payload + * and verify tag. + */ + +static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + int rv = -1; + /* Encrypt/decrypt must be performed in place */ + if (out != in + || len < (EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN)) + return -1; + /* + * Set IV from start of buffer or generate IV and write to start of + * buffer. + */ + if (EVP_CIPHER_CTX_ctrl(ctx, ctx->encrypt ? + EVP_CTRL_GCM_IV_GEN : EVP_CTRL_GCM_SET_IV_INV, + EVP_GCM_TLS_EXPLICIT_IV_LEN, out) <= 0) + goto err; + /* Use saved AAD */ + if (CRYPTO_gcm128_aad(&gctx->gcm, ctx->buf, gctx->tls_aad_len)) + goto err; + /* Fix buffer and length to point to payload */ + in += EVP_GCM_TLS_EXPLICIT_IV_LEN; + out += EVP_GCM_TLS_EXPLICIT_IV_LEN; + len -= EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; + if (ctx->encrypt) { + /* Encrypt payload */ + if (gctx->ctr) { + if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, + in, out, len, gctx->ctr)) + goto err; + } else { + if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) + goto err; + } + out += len; + /* Finally write tag */ + CRYPTO_gcm128_tag(&gctx->gcm, out, EVP_GCM_TLS_TAG_LEN); + rv = len + EVP_GCM_TLS_EXPLICIT_IV_LEN + EVP_GCM_TLS_TAG_LEN; + } else { + /* Decrypt */ + if (gctx->ctr) { + if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, + in, out, len, gctx->ctr)) + goto err; + } else { + if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) + goto err; + } + /* Retrieve tag */ + CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, EVP_GCM_TLS_TAG_LEN); + /* If tag mismatch wipe buffer */ + if (CRYPTO_memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) { + OPENSSL_cleanse(out, len); + goto err; + } + rv = len; + } + + err: + gctx->iv_set = 0; + gctx->tls_aad_len = -1; + return rv; +} + +static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + /* If not set up, return error */ + if (!gctx->key_set) + return -1; + + if (gctx->tls_aad_len >= 0) + return aes_gcm_tls_cipher(ctx, out, in, len); + + if (!gctx->iv_set) + return -1; + if (in) { + if (out == NULL) { + if (CRYPTO_gcm128_aad(&gctx->gcm, in, len)) + return -1; + } else if (ctx->encrypt) { + if (gctx->ctr) { + if (CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, + in, out, len, gctx->ctr)) + return -1; + } else { + if (CRYPTO_gcm128_encrypt(&gctx->gcm, in, out, len)) + return -1; + } + } else { + if (gctx->ctr) { + if (CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, + in, out, len, gctx->ctr)) + return -1; + } else { + if (CRYPTO_gcm128_decrypt(&gctx->gcm, in, out, len)) + return -1; + } + } + return len; + } else { + if (!ctx->encrypt) { + if (gctx->taglen < 0) + return -1; + if (CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen) != 0) + return -1; + gctx->iv_set = 0; + return 0; + } + CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, 16); + gctx->taglen = 16; + /* Don't reuse the IV */ + gctx->iv_set = 0; + return 0; + } + +} + +# define CUSTOM_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 \ + | EVP_CIPH_CUSTOM_IV | EVP_CIPH_FLAG_CUSTOM_CIPHER \ + | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ + | EVP_CIPH_CUSTOM_COPY) + +BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, gcm, GCM, + EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | + CUSTOM_FLAGS) + BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, gcm, GCM, + EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | + CUSTOM_FLAGS) + BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, gcm, GCM, + EVP_CIPH_FLAG_FIPS | EVP_CIPH_FLAG_AEAD_CIPHER | + CUSTOM_FLAGS) + +static int aes_xts_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + EVP_AES_XTS_CTX *xctx = c->cipher_data; + if (type == EVP_CTRL_COPY) { + EVP_CIPHER_CTX *out = ptr; + EVP_AES_XTS_CTX *xctx_out = out->cipher_data; + if (xctx->xts.key1) { + if (xctx->xts.key1 != &xctx->ks1) + return 0; + xctx_out->xts.key1 = &xctx_out->ks1; + } + if (xctx->xts.key2) { + if (xctx->xts.key2 != &xctx->ks2) + return 0; + xctx_out->xts.key2 = &xctx_out->ks2; + } + return 1; + } else if (type != EVP_CTRL_INIT) + return -1; + /* key1 and key2 are used as an indicator both key and IV are set */ + xctx->xts.key1 = NULL; + xctx->xts.key2 = NULL; + return 1; +} + +static int aes_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_XTS_CTX *xctx = ctx->cipher_data; + if (!iv && !key) + return 1; + + if (key) + do { +# ifdef AES_XTS_ASM + xctx->stream = enc ? AES_xts_encrypt : AES_xts_decrypt; +# else + xctx->stream = NULL; +# endif + /* key_len is two AES keys */ +# ifdef BSAES_CAPABLE + if (BSAES_CAPABLE) + xctx->stream = enc ? bsaes_xts_encrypt : bsaes_xts_decrypt; + else +# endif +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + if (enc) { + vpaes_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1); + xctx->xts.block1 = (block128_f) vpaes_encrypt; + } else { + vpaes_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1); + xctx->xts.block1 = (block128_f) vpaes_decrypt; + } + + vpaes_set_encrypt_key(key + ctx->key_len / 2, + ctx->key_len * 4, &xctx->ks2); + xctx->xts.block2 = (block128_f) vpaes_encrypt; + + xctx->xts.key1 = &xctx->ks1; + break; + } else +# endif + (void)0; /* terminate potentially open 'else' */ + + if (enc) { + AES_set_encrypt_key(key, ctx->key_len * 4, &xctx->ks1); + xctx->xts.block1 = (block128_f) AES_encrypt; + } else { + AES_set_decrypt_key(key, ctx->key_len * 4, &xctx->ks1); + xctx->xts.block1 = (block128_f) AES_decrypt; + } + + AES_set_encrypt_key(key + ctx->key_len / 2, + ctx->key_len * 4, &xctx->ks2); + xctx->xts.block2 = (block128_f) AES_encrypt; + + xctx->xts.key1 = &xctx->ks1; + } while (0); + + if (iv) { + xctx->xts.key2 = &xctx->ks2; + memcpy(ctx->iv, iv, 16); + } + + return 1; +} + +static int aes_xts_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_XTS_CTX *xctx = ctx->cipher_data; + if (!xctx->xts.key1 || !xctx->xts.key2) + return 0; + if (!out || !in || len < AES_BLOCK_SIZE) + return 0; +# ifdef OPENSSL_FIPS + /* Requirement of SP800-38E */ + if (FIPS_module_mode() && !(ctx->flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW) && + (len > (1UL << 20) * 16)) { + EVPerr(EVP_F_AES_XTS_CIPHER, EVP_R_TOO_LARGE); + return 0; + } +# endif + if (xctx->stream) + (*xctx->stream) (in, out, len, + xctx->xts.key1, xctx->xts.key2, ctx->iv); + else if (CRYPTO_xts128_encrypt(&xctx->xts, ctx->iv, in, out, len, + ctx->encrypt)) + return 0; + return 1; +} + +# define aes_xts_cleanup NULL + +# define XTS_FLAGS (EVP_CIPH_FLAG_DEFAULT_ASN1 | EVP_CIPH_CUSTOM_IV \ + | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CTRL_INIT \ + | EVP_CIPH_CUSTOM_COPY) + +BLOCK_CIPHER_custom(NID_aes, 128, 1, 16, xts, XTS, + EVP_CIPH_FLAG_FIPS | XTS_FLAGS) + BLOCK_CIPHER_custom(NID_aes, 256, 1, 16, xts, XTS, + EVP_CIPH_FLAG_FIPS | XTS_FLAGS) + +static int aes_ccm_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + EVP_AES_CCM_CTX *cctx = c->cipher_data; + switch (type) { + case EVP_CTRL_INIT: + cctx->key_set = 0; + cctx->iv_set = 0; + cctx->L = 8; + cctx->M = 12; + cctx->tag_set = 0; + cctx->len_set = 0; + return 1; + + case EVP_CTRL_CCM_SET_IVLEN: + arg = 15 - arg; + case EVP_CTRL_CCM_SET_L: + if (arg < 2 || arg > 8) + return 0; + cctx->L = arg; + return 1; + + case EVP_CTRL_CCM_SET_TAG: + if ((arg & 1) || arg < 4 || arg > 16) + return 0; + if (c->encrypt && ptr) + return 0; + if (ptr) { + cctx->tag_set = 1; + memcpy(c->buf, ptr, arg); + } + cctx->M = arg; + return 1; + + case EVP_CTRL_CCM_GET_TAG: + if (!c->encrypt || !cctx->tag_set) + return 0; + if (!CRYPTO_ccm128_tag(&cctx->ccm, ptr, (size_t)arg)) + return 0; + cctx->tag_set = 0; + cctx->iv_set = 0; + cctx->len_set = 0; + return 1; + + case EVP_CTRL_COPY: + { + EVP_CIPHER_CTX *out = ptr; + EVP_AES_CCM_CTX *cctx_out = out->cipher_data; + if (cctx->ccm.key) { + if (cctx->ccm.key != &cctx->ks) + return 0; + cctx_out->ccm.key = &cctx_out->ks; + } + return 1; + } + + default: + return -1; + + } +} + +static int aes_ccm_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + EVP_AES_CCM_CTX *cctx = ctx->cipher_data; + if (!iv && !key) + return 1; + if (key) + do { +# ifdef VPAES_CAPABLE + if (VPAES_CAPABLE) { + vpaes_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks); + CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, + &cctx->ks, (block128_f) vpaes_encrypt); + cctx->str = NULL; + cctx->key_set = 1; + break; + } +# endif + AES_set_encrypt_key(key, ctx->key_len * 8, &cctx->ks); + CRYPTO_ccm128_init(&cctx->ccm, cctx->M, cctx->L, + &cctx->ks, (block128_f) AES_encrypt); + cctx->str = NULL; + cctx->key_set = 1; + } while (0); + if (iv) { + memcpy(ctx->iv, iv, 15 - cctx->L); + cctx->iv_set = 1; + } + return 1; +} + +static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_CCM_CTX *cctx = ctx->cipher_data; + CCM128_CONTEXT *ccm = &cctx->ccm; + /* If not set up, return error */ + if (!cctx->iv_set && !cctx->key_set) + return -1; + if (!ctx->encrypt && !cctx->tag_set) + return -1; + if (!out) { + if (!in) { + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) + return -1; + cctx->len_set = 1; + return len; + } + /* If have AAD need message length */ + if (!cctx->len_set && len) + return -1; + CRYPTO_ccm128_aad(ccm, in, len); + return len; + } + /* EVP_*Final() doesn't return any data */ + if (!in) + return 0; + /* If not set length yet do it */ + if (!cctx->len_set) { + if (CRYPTO_ccm128_setiv(ccm, ctx->iv, 15 - cctx->L, len)) + return -1; + cctx->len_set = 1; + } + if (ctx->encrypt) { + if (cctx->str ? CRYPTO_ccm128_encrypt_ccm64(ccm, in, out, len, + cctx->str) : + CRYPTO_ccm128_encrypt(ccm, in, out, len)) + return -1; + cctx->tag_set = 1; + return len; + } else { + int rv = -1; + if (cctx->str ? !CRYPTO_ccm128_decrypt_ccm64(ccm, in, out, len, + cctx->str) : + !CRYPTO_ccm128_decrypt(ccm, in, out, len)) { + unsigned char tag[16]; + if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) { + if (!CRYPTO_memcmp(tag, ctx->buf, cctx->M)) + rv = len; + } + } + if (rv == -1) + OPENSSL_cleanse(out, len); + cctx->iv_set = 0; + cctx->tag_set = 0; + cctx->len_set = 0; + return rv; + } + +} + +# define aes_ccm_cleanup NULL + +BLOCK_CIPHER_custom(NID_aes, 128, 1, 12, ccm, CCM, + EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS) + BLOCK_CIPHER_custom(NID_aes, 192, 1, 12, ccm, CCM, + EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS) + BLOCK_CIPHER_custom(NID_aes, 256, 1, 12, ccm, CCM, + EVP_CIPH_FLAG_FIPS | CUSTOM_FLAGS) +# endif +#endif diff --git a/libs/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c b/libs/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c new file mode 100644 index 00000000..1d598db3 --- /dev/null +++ b/libs/openssl/crypto/evp/e_aes_cbc_hmac_sha1.c @@ -0,0 +1,602 @@ +/* ==================================================================== + * Copyright (c) 2011-2013 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include +#include + +#if !defined(OPENSSL_NO_AES) && !defined(OPENSSL_NO_SHA1) + +# include +# include +# include +# include +# include "evp_locl.h" +# include "constant_time_locl.h" + +# ifndef EVP_CIPH_FLAG_AEAD_CIPHER +# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 +# define EVP_CTRL_AEAD_TLS1_AAD 0x16 +# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 +# endif + +# if !defined(EVP_CIPH_FLAG_DEFAULT_ASN1) +# define EVP_CIPH_FLAG_DEFAULT_ASN1 0 +# endif + +# define TLS1_1_VERSION 0x0302 + +typedef struct { + AES_KEY ks; + SHA_CTX head, tail, md; + size_t payload_length; /* AAD length in decrypt case */ + union { + unsigned int tls_ver; + unsigned char tls_aad[16]; /* 13 used */ + } aux; +} EVP_AES_HMAC_SHA1; + +# define NO_PAYLOAD_LENGTH ((size_t)-1) + +# if defined(AES_ASM) && ( \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) || \ + defined(__INTEL__) ) + +# if defined(__GNUC__) && __GNUC__>=2 && !defined(PEDANTIC) +# define BSWAP(x) ({ unsigned int r=(x); asm ("bswapl %0":"=r"(r):"0"(r)); r; }) +# endif + +extern unsigned int OPENSSL_ia32cap_P[2]; +# define AESNI_CAPABLE (1<<(57-32)) + +int aesni_set_encrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); +int aesni_set_decrypt_key(const unsigned char *userKey, int bits, + AES_KEY *key); + +void aesni_cbc_encrypt(const unsigned char *in, + unsigned char *out, + size_t length, + const AES_KEY *key, unsigned char *ivec, int enc); + +void aesni_cbc_sha1_enc(const void *inp, void *out, size_t blocks, + const AES_KEY *key, unsigned char iv[16], + SHA_CTX *ctx, const void *in0); + +# define data(ctx) ((EVP_AES_HMAC_SHA1 *)(ctx)->cipher_data) + +static int aesni_cbc_hmac_sha1_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *inkey, + const unsigned char *iv, int enc) +{ + EVP_AES_HMAC_SHA1 *key = data(ctx); + int ret; + + if (enc) + ret = aesni_set_encrypt_key(inkey, ctx->key_len * 8, &key->ks); + else + ret = aesni_set_decrypt_key(inkey, ctx->key_len * 8, &key->ks); + + SHA1_Init(&key->head); /* handy when benchmarking */ + key->tail = key->head; + key->md = key->head; + + key->payload_length = NO_PAYLOAD_LENGTH; + + return ret < 0 ? 0 : 1; +} + +# define STITCHED_CALL + +# if !defined(STITCHED_CALL) +# define aes_off 0 +# endif + +void sha1_block_data_order(void *c, const void *p, size_t len); + +static void sha1_update(SHA_CTX *c, const void *data, size_t len) +{ + const unsigned char *ptr = data; + size_t res; + + if ((res = c->num)) { + res = SHA_CBLOCK - res; + if (len < res) + res = len; + SHA1_Update(c, ptr, res); + ptr += res; + len -= res; + } + + res = len % SHA_CBLOCK; + len -= res; + + if (len) { + sha1_block_data_order(c, ptr, len / SHA_CBLOCK); + + ptr += len; + c->Nh += len >> 29; + c->Nl += len <<= 3; + if (c->Nl < (unsigned int)len) + c->Nh++; + } + + if (res) + SHA1_Update(c, ptr, res); +} + +# ifdef SHA1_Update +# undef SHA1_Update +# endif +# define SHA1_Update sha1_update + +static int aesni_cbc_hmac_sha1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_AES_HMAC_SHA1 *key = data(ctx); + unsigned int l; + size_t plen = key->payload_length, iv = 0, /* explicit IV in TLS 1.1 and + * later */ + sha_off = 0; +# if defined(STITCHED_CALL) + size_t aes_off = 0, blocks; + + sha_off = SHA_CBLOCK - key->md.num; +# endif + + key->payload_length = NO_PAYLOAD_LENGTH; + + if (len % AES_BLOCK_SIZE) + return 0; + + if (ctx->encrypt) { + if (plen == NO_PAYLOAD_LENGTH) + plen = len; + else if (len != + ((plen + SHA_DIGEST_LENGTH + + AES_BLOCK_SIZE) & -AES_BLOCK_SIZE)) + return 0; + else if (key->aux.tls_ver >= TLS1_1_VERSION) + iv = AES_BLOCK_SIZE; + +# if defined(STITCHED_CALL) + if (plen > (sha_off + iv) + && (blocks = (plen - (sha_off + iv)) / SHA_CBLOCK)) { + SHA1_Update(&key->md, in + iv, sha_off); + + aesni_cbc_sha1_enc(in, out, blocks, &key->ks, + ctx->iv, &key->md, in + iv + sha_off); + blocks *= SHA_CBLOCK; + aes_off += blocks; + sha_off += blocks; + key->md.Nh += blocks >> 29; + key->md.Nl += blocks <<= 3; + if (key->md.Nl < (unsigned int)blocks) + key->md.Nh++; + } else { + sha_off = 0; + } +# endif + sha_off += iv; + SHA1_Update(&key->md, in + sha_off, plen - sha_off); + + if (plen != len) { /* "TLS" mode of operation */ + if (in != out) + memcpy(out + aes_off, in + aes_off, plen - aes_off); + + /* calculate HMAC and append it to payload */ + SHA1_Final(out + plen, &key->md); + key->md = key->tail; + SHA1_Update(&key->md, out + plen, SHA_DIGEST_LENGTH); + SHA1_Final(out + plen, &key->md); + + /* pad the payload|hmac */ + plen += SHA_DIGEST_LENGTH; + for (l = len - plen - 1; plen < len; plen++) + out[plen] = l; + /* encrypt HMAC|padding at once */ + aesni_cbc_encrypt(out + aes_off, out + aes_off, len - aes_off, + &key->ks, ctx->iv, 1); + } else { + aesni_cbc_encrypt(in + aes_off, out + aes_off, len - aes_off, + &key->ks, ctx->iv, 1); + } + } else { + union { + unsigned int u[SHA_DIGEST_LENGTH / sizeof(unsigned int)]; + unsigned char c[32 + SHA_DIGEST_LENGTH]; + } mac, *pmac; + + /* arrange cache line alignment */ + pmac = (void *)(((size_t)mac.c + 31) & ((size_t)0 - 32)); + + /* decrypt HMAC|padding at once */ + aesni_cbc_encrypt(in, out, len, &key->ks, ctx->iv, 0); + + if (plen) { /* "TLS" mode of operation */ + size_t inp_len, mask, j, i; + unsigned int res, maxpad, pad, bitlen; + int ret = 1; + union { + unsigned int u[SHA_LBLOCK]; + unsigned char c[SHA_CBLOCK]; + } *data = (void *)key->md.data; + + if ((key->aux.tls_aad[plen - 4] << 8 | key->aux.tls_aad[plen - 3]) + >= TLS1_1_VERSION) + iv = AES_BLOCK_SIZE; + + if (len < (iv + SHA_DIGEST_LENGTH + 1)) + return 0; + + /* omit explicit iv */ + out += iv; + len -= iv; + + /* figure out payload length */ + pad = out[len - 1]; + maxpad = len - (SHA_DIGEST_LENGTH + 1); + maxpad |= (255 - maxpad) >> (sizeof(maxpad) * 8 - 8); + maxpad &= 255; + + ret &= constant_time_ge(maxpad, pad); + + inp_len = len - (SHA_DIGEST_LENGTH + pad + 1); + mask = (0 - ((inp_len - len) >> (sizeof(inp_len) * 8 - 1))); + inp_len &= mask; + ret &= (int)mask; + + key->aux.tls_aad[plen - 2] = inp_len >> 8; + key->aux.tls_aad[plen - 1] = inp_len; + + /* calculate HMAC */ + key->md = key->head; + SHA1_Update(&key->md, key->aux.tls_aad, plen); + +# if 1 + len -= SHA_DIGEST_LENGTH; /* amend mac */ + if (len >= (256 + SHA_CBLOCK)) { + j = (len - (256 + SHA_CBLOCK)) & (0 - SHA_CBLOCK); + j += SHA_CBLOCK - key->md.num; + SHA1_Update(&key->md, out, j); + out += j; + len -= j; + inp_len -= j; + } + + /* but pretend as if we hashed padded payload */ + bitlen = key->md.Nl + (inp_len << 3); /* at most 18 bits */ +# ifdef BSWAP + bitlen = BSWAP(bitlen); +# else + mac.c[0] = 0; + mac.c[1] = (unsigned char)(bitlen >> 16); + mac.c[2] = (unsigned char)(bitlen >> 8); + mac.c[3] = (unsigned char)bitlen; + bitlen = mac.u[0]; +# endif + + pmac->u[0] = 0; + pmac->u[1] = 0; + pmac->u[2] = 0; + pmac->u[3] = 0; + pmac->u[4] = 0; + + for (res = key->md.num, j = 0; j < len; j++) { + size_t c = out[j]; + mask = (j - inp_len) >> (sizeof(j) * 8 - 8); + c &= mask; + c |= 0x80 & ~mask & ~((inp_len - j) >> (sizeof(j) * 8 - 8)); + data->c[res++] = (unsigned char)c; + + if (res != SHA_CBLOCK) + continue; + + /* j is not incremented yet */ + mask = 0 - ((inp_len + 7 - j) >> (sizeof(j) * 8 - 1)); + data->u[SHA_LBLOCK - 1] |= bitlen & mask; + sha1_block_data_order(&key->md, data, 1); + mask &= 0 - ((j - inp_len - 72) >> (sizeof(j) * 8 - 1)); + pmac->u[0] |= key->md.h0 & mask; + pmac->u[1] |= key->md.h1 & mask; + pmac->u[2] |= key->md.h2 & mask; + pmac->u[3] |= key->md.h3 & mask; + pmac->u[4] |= key->md.h4 & mask; + res = 0; + } + + for (i = res; i < SHA_CBLOCK; i++, j++) + data->c[i] = 0; + + if (res > SHA_CBLOCK - 8) { + mask = 0 - ((inp_len + 8 - j) >> (sizeof(j) * 8 - 1)); + data->u[SHA_LBLOCK - 1] |= bitlen & mask; + sha1_block_data_order(&key->md, data, 1); + mask &= 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); + pmac->u[0] |= key->md.h0 & mask; + pmac->u[1] |= key->md.h1 & mask; + pmac->u[2] |= key->md.h2 & mask; + pmac->u[3] |= key->md.h3 & mask; + pmac->u[4] |= key->md.h4 & mask; + + memset(data, 0, SHA_CBLOCK); + j += 64; + } + data->u[SHA_LBLOCK - 1] = bitlen; + sha1_block_data_order(&key->md, data, 1); + mask = 0 - ((j - inp_len - 73) >> (sizeof(j) * 8 - 1)); + pmac->u[0] |= key->md.h0 & mask; + pmac->u[1] |= key->md.h1 & mask; + pmac->u[2] |= key->md.h2 & mask; + pmac->u[3] |= key->md.h3 & mask; + pmac->u[4] |= key->md.h4 & mask; + +# ifdef BSWAP + pmac->u[0] = BSWAP(pmac->u[0]); + pmac->u[1] = BSWAP(pmac->u[1]); + pmac->u[2] = BSWAP(pmac->u[2]); + pmac->u[3] = BSWAP(pmac->u[3]); + pmac->u[4] = BSWAP(pmac->u[4]); +# else + for (i = 0; i < 5; i++) { + res = pmac->u[i]; + pmac->c[4 * i + 0] = (unsigned char)(res >> 24); + pmac->c[4 * i + 1] = (unsigned char)(res >> 16); + pmac->c[4 * i + 2] = (unsigned char)(res >> 8); + pmac->c[4 * i + 3] = (unsigned char)res; + } +# endif + len += SHA_DIGEST_LENGTH; +# else + SHA1_Update(&key->md, out, inp_len); + res = key->md.num; + SHA1_Final(pmac->c, &key->md); + + { + unsigned int inp_blocks, pad_blocks; + + /* but pretend as if we hashed padded payload */ + inp_blocks = + 1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1)); + res += (unsigned int)(len - inp_len); + pad_blocks = res / SHA_CBLOCK; + res %= SHA_CBLOCK; + pad_blocks += + 1 + ((SHA_CBLOCK - 9 - res) >> (sizeof(res) * 8 - 1)); + for (; inp_blocks < pad_blocks; inp_blocks++) + sha1_block_data_order(&key->md, data, 1); + } +# endif + key->md = key->tail; + SHA1_Update(&key->md, pmac->c, SHA_DIGEST_LENGTH); + SHA1_Final(pmac->c, &key->md); + + /* verify HMAC */ + out += inp_len; + len -= inp_len; +# if 1 + { + unsigned char *p = out + len - 1 - maxpad - SHA_DIGEST_LENGTH; + size_t off = out - p; + unsigned int c, cmask; + + maxpad += SHA_DIGEST_LENGTH; + for (res = 0, i = 0, j = 0; j < maxpad; j++) { + c = p[j]; + cmask = + ((int)(j - off - SHA_DIGEST_LENGTH)) >> (sizeof(int) * + 8 - 1); + res |= (c ^ pad) & ~cmask; /* ... and padding */ + cmask &= ((int)(off - 1 - j)) >> (sizeof(int) * 8 - 1); + res |= (c ^ pmac->c[i]) & cmask; + i += 1 & cmask; + } + maxpad -= SHA_DIGEST_LENGTH; + + res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); + ret &= (int)~res; + } +# else + for (res = 0, i = 0; i < SHA_DIGEST_LENGTH; i++) + res |= out[i] ^ pmac->c[i]; + res = 0 - ((0 - res) >> (sizeof(res) * 8 - 1)); + ret &= (int)~res; + + /* verify padding */ + pad = (pad & ~res) | (maxpad & res); + out = out + len - 1 - pad; + for (res = 0, i = 0; i < pad; i++) + res |= out[i] ^ pad; + + res = (0 - res) >> (sizeof(res) * 8 - 1); + ret &= (int)~res; +# endif + return ret; + } else { + SHA1_Update(&key->md, out, len); + } + } + + return 1; +} + +static int aesni_cbc_hmac_sha1_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, + void *ptr) +{ + EVP_AES_HMAC_SHA1 *key = data(ctx); + + switch (type) { + case EVP_CTRL_AEAD_SET_MAC_KEY: + { + unsigned int i; + unsigned char hmac_key[64]; + + memset(hmac_key, 0, sizeof(hmac_key)); + + if (arg > (int)sizeof(hmac_key)) { + SHA1_Init(&key->head); + SHA1_Update(&key->head, ptr, arg); + SHA1_Final(hmac_key, &key->head); + } else { + memcpy(hmac_key, ptr, arg); + } + + for (i = 0; i < sizeof(hmac_key); i++) + hmac_key[i] ^= 0x36; /* ipad */ + SHA1_Init(&key->head); + SHA1_Update(&key->head, hmac_key, sizeof(hmac_key)); + + for (i = 0; i < sizeof(hmac_key); i++) + hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */ + SHA1_Init(&key->tail); + SHA1_Update(&key->tail, hmac_key, sizeof(hmac_key)); + + OPENSSL_cleanse(hmac_key, sizeof(hmac_key)); + + return 1; + } + case EVP_CTRL_AEAD_TLS1_AAD: + { + unsigned char *p = ptr; + unsigned int len; + + if (arg != EVP_AEAD_TLS1_AAD_LEN) + return -1; + + len = p[arg - 2] << 8 | p[arg - 1]; + + if (ctx->encrypt) { + key->payload_length = len; + if ((key->aux.tls_ver = + p[arg - 4] << 8 | p[arg - 3]) >= TLS1_1_VERSION) { + len -= AES_BLOCK_SIZE; + p[arg - 2] = len >> 8; + p[arg - 1] = len; + } + key->md = key->head; + SHA1_Update(&key->md, p, arg); + + return (int)(((len + SHA_DIGEST_LENGTH + + AES_BLOCK_SIZE) & -AES_BLOCK_SIZE) + - len); + } else { + memcpy(key->aux.tls_aad, ptr, arg); + key->payload_length = arg; + + return SHA_DIGEST_LENGTH; + } + } + default: + return -1; + } +} + +static EVP_CIPHER aesni_128_cbc_hmac_sha1_cipher = { +# ifdef NID_aes_128_cbc_hmac_sha1 + NID_aes_128_cbc_hmac_sha1, +# else + NID_undef, +# endif + 16, 16, 16, + EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | + EVP_CIPH_FLAG_AEAD_CIPHER, + aesni_cbc_hmac_sha1_init_key, + aesni_cbc_hmac_sha1_cipher, + NULL, + sizeof(EVP_AES_HMAC_SHA1), + EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv, + EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv, + aesni_cbc_hmac_sha1_ctrl, + NULL +}; + +static EVP_CIPHER aesni_256_cbc_hmac_sha1_cipher = { +# ifdef NID_aes_256_cbc_hmac_sha1 + NID_aes_256_cbc_hmac_sha1, +# else + NID_undef, +# endif + 16, 32, 16, + EVP_CIPH_CBC_MODE | EVP_CIPH_FLAG_DEFAULT_ASN1 | + EVP_CIPH_FLAG_AEAD_CIPHER, + aesni_cbc_hmac_sha1_init_key, + aesni_cbc_hmac_sha1_cipher, + NULL, + sizeof(EVP_AES_HMAC_SHA1), + EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_set_asn1_iv, + EVP_CIPH_FLAG_DEFAULT_ASN1 ? NULL : EVP_CIPHER_get_asn1_iv, + aesni_cbc_hmac_sha1_ctrl, + NULL +}; + +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void) +{ + return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ? + &aesni_128_cbc_hmac_sha1_cipher : NULL); +} + +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void) +{ + return (OPENSSL_ia32cap_P[1] & AESNI_CAPABLE ? + &aesni_256_cbc_hmac_sha1_cipher : NULL); +} +# else +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void) +{ + return NULL; +} + +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void) +{ + return NULL; +} +# endif +#endif diff --git a/libs/openssl/crypto/evp/e_bf.c b/libs/openssl/crypto/evp/e_bf.c new file mode 100644 index 00000000..d6a01782 --- /dev/null +++ b/libs/openssl/crypto/evp/e_bf.c @@ -0,0 +1,87 @@ +/* crypto/evp/e_bf.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#ifndef OPENSSL_NO_BF +# include +# include "evp_locl.h" +# include +# include + +static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +typedef struct { + BF_KEY ks; +} EVP_BF_KEY; + +# define data(ctx) EVP_C_DATA(EVP_BF_KEY,ctx) + +IMPLEMENT_BLOCK_CIPHER(bf, ks, BF, EVP_BF_KEY, NID_bf, 8, 16, 8, 64, + EVP_CIPH_VARIABLE_LENGTH, bf_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) + +static int bf_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + BF_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); + return 1; +} + +#endif diff --git a/libs/openssl/crypto/evp/e_camellia.c b/libs/openssl/crypto/evp/e_camellia.c new file mode 100644 index 00000000..f7b135da --- /dev/null +++ b/libs/openssl/crypto/evp/e_camellia.c @@ -0,0 +1,119 @@ +/* crypto/evp/e_camellia.c */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#ifndef OPENSSL_NO_CAMELLIA +# include +# include +# include +# include +# include +# include "evp_locl.h" + +static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +/* Camellia subkey Structure */ +typedef struct { + CAMELLIA_KEY ks; +} EVP_CAMELLIA_KEY; + +/* Attribute operation for Camellia */ +# define data(ctx) EVP_C_DATA(EVP_CAMELLIA_KEY,ctx) + +IMPLEMENT_BLOCK_CIPHER(camellia_128, ks, Camellia, EVP_CAMELLIA_KEY, + NID_camellia_128, 16, 16, 16, 128, + 0, camellia_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) + IMPLEMENT_BLOCK_CIPHER(camellia_192, ks, Camellia, EVP_CAMELLIA_KEY, + NID_camellia_192, 16, 24, 16, 128, + 0, camellia_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) + IMPLEMENT_BLOCK_CIPHER(camellia_256, ks, Camellia, EVP_CAMELLIA_KEY, + NID_camellia_256, 16, 32, 16, 128, + 0, camellia_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) +# define IMPLEMENT_CAMELLIA_CFBR(ksize,cbits) IMPLEMENT_CFBR(camellia,Camellia,EVP_CAMELLIA_KEY,ks,ksize,cbits,16) + IMPLEMENT_CAMELLIA_CFBR(128, 1) + IMPLEMENT_CAMELLIA_CFBR(192, 1) + IMPLEMENT_CAMELLIA_CFBR(256, 1) + + IMPLEMENT_CAMELLIA_CFBR(128, 8) + IMPLEMENT_CAMELLIA_CFBR(192, 8) + IMPLEMENT_CAMELLIA_CFBR(256, 8) + +/* The subkey for Camellia is generated. */ +static int camellia_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + int ret; + + ret = Camellia_set_key(key, ctx->key_len * 8, ctx->cipher_data); + + if (ret < 0) { + EVPerr(EVP_F_CAMELLIA_INIT_KEY, EVP_R_CAMELLIA_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +#else + +# ifdef PEDANTIC +static void *dummy = &dummy; +# endif + +#endif diff --git a/libs/openssl/crypto/evp/e_cast.c b/libs/openssl/crypto/evp/e_cast.c new file mode 100644 index 00000000..3f745485 --- /dev/null +++ b/libs/openssl/crypto/evp/e_cast.c @@ -0,0 +1,89 @@ +/* crypto/evp/e_cast.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_CAST +# include +# include +# include "evp_locl.h" +# include + +static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +typedef struct { + CAST_KEY ks; +} EVP_CAST_KEY; + +# define data(ctx) EVP_C_DATA(EVP_CAST_KEY,ctx) + +IMPLEMENT_BLOCK_CIPHER(cast5, ks, CAST, EVP_CAST_KEY, + NID_cast5, 8, CAST_KEY_LENGTH, 8, 64, + EVP_CIPH_VARIABLE_LENGTH, cast_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) + +static int cast_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + CAST_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); + return 1; +} + +#endif diff --git a/libs/openssl/crypto/evp/e_des.c b/libs/openssl/crypto/evp/e_des.c new file mode 100644 index 00000000..ea1a4c42 --- /dev/null +++ b/libs/openssl/crypto/evp/e_des.c @@ -0,0 +1,223 @@ +/* crypto/evp/e_des.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#ifndef OPENSSL_NO_DES +# include +# include +# include "evp_locl.h" +# include +# include + +static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); + +/* + * Because of various casts and different names can't use + * IMPLEMENT_BLOCK_CIPHER + */ + +static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + BLOCK_CIPHER_ecb_loop() + DES_ecb_encrypt((DES_cblock *)(in + i), (DES_cblock *)(out + i), + ctx->cipher_data, ctx->encrypt); + return 1; +} + +static int des_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_ofb64_encrypt(in, out, (long)inl, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num); + return 1; +} + +static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_ncbc_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_ncbc_encrypt(in, out, (long)inl, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + return 1; +} + +static int des_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_cfb64_encrypt(in, out, (long)inl, ctx->cipher_data, + (DES_cblock *)ctx->iv, &ctx->num, ctx->encrypt); + return 1; +} + +/* + * Although we have a CFB-r implementation for DES, it doesn't pack the right + * way, so wrap it here + */ +static int des_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t n, chunk = EVP_MAXCHUNK / 8; + unsigned char c[1], d[1]; + + if (inl < chunk) + chunk = inl; + + while (inl && inl >= chunk) { + for (n = 0; n < chunk * 8; ++n) { + c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; + DES_cfb_encrypt(c, d, 1, 1, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + out[n / 8] = + (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) | + ((d[0] & 0x80) >> (unsigned int)(n % 8)); + } + inl -= chunk; + in += chunk; + out += chunk; + if (inl < chunk) + chunk = inl; + } + + return 1; +} + +static int des_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_cfb_encrypt(in, out, 8, (long)inl, ctx->cipher_data, + (DES_cblock *)ctx->iv, ctx->encrypt); + return 1; +} + +BLOCK_CIPHER_defs(des, DES_key_schedule, NID_des, 8, 8, 8, 64, + EVP_CIPH_RAND_KEY, des_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) + + +BLOCK_CIPHER_def_cfb(des, DES_key_schedule, NID_des, 8, 8, 1, + EVP_CIPH_RAND_KEY, des_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) + +BLOCK_CIPHER_def_cfb(des, DES_key_schedule, NID_des, 8, 8, 8, + EVP_CIPH_RAND_KEY, des_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des_ctrl) + +static int des_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + DES_cblock *deskey = (DES_cblock *)key; +# ifdef EVP_CHECK_DES_KEY + if (DES_set_key_checked(deskey, ctx->cipher_data) != 0) + return 0; +# else + DES_set_key_unchecked(deskey, ctx->cipher_data); +# endif + return 1; +} + +static int des_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + + switch (type) { + case EVP_CTRL_RAND_KEY: + if (RAND_bytes(ptr, 8) <= 0) + return 0; + DES_set_odd_parity((DES_cblock *)ptr); + return 1; + + default: + return -1; + } +} + +#endif diff --git a/libs/openssl/crypto/evp/e_des3.c b/libs/openssl/crypto/evp/e_des3.c new file mode 100644 index 00000000..12723057 --- /dev/null +++ b/libs/openssl/crypto/evp/e_des3.c @@ -0,0 +1,319 @@ +/* crypto/evp/e_des3.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#ifndef OPENSSL_NO_DES +# include +# include +# include "evp_locl.h" +# include +# include + +# ifndef OPENSSL_FIPS + +static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); + +typedef struct { + DES_key_schedule ks1; /* key schedule */ + DES_key_schedule ks2; /* key schedule (for ede) */ + DES_key_schedule ks3; /* key schedule (for ede3) */ +} DES_EDE_KEY; + +# define data(ctx) ((DES_EDE_KEY *)(ctx)->cipher_data) + +/* + * Because of various casts and different args can't use + * IMPLEMENT_BLOCK_CIPHER + */ + +static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + BLOCK_CIPHER_ecb_loop() + DES_ecb3_encrypt((const_DES_cblock *)(in + i), + (DES_cblock *)(out + i), + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, ctx->encrypt); + return 1; +} + +static int des_ede_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_ede3_ofb64_encrypt(in, out, (long)EVP_MAXCHUNK, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + &ctx->num); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_ede3_ofb64_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + &ctx->num); + + return 1; +} + +static int des_ede_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ +# ifdef KSSL_DEBUG + { + int i; + fprintf(stderr, "des_ede_cbc_cipher(ctx=%p, buflen=%d)\n", ctx, + ctx->buf_len); + fprintf(stderr, "\t iv= "); + for (i = 0; i < 8; i++) + fprintf(stderr, "%02X", ctx->iv[i]); + fprintf(stderr, "\n"); + } +# endif /* KSSL_DEBUG */ + while (inl >= EVP_MAXCHUNK) { + DES_ede3_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_ede3_cbc_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + ctx->encrypt); + return 1; +} + +static int des_ede_cfb64_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_ede3_cfb64_encrypt(in, out, (long)EVP_MAXCHUNK, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + &ctx->num, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_ede3_cfb64_encrypt(in, out, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + &ctx->num, ctx->encrypt); + return 1; +} + +/* + * Although we have a CFB-r implementation for 3-DES, it doesn't pack the + * right way, so wrap it here + */ +static int des_ede3_cfb1_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + size_t n; + unsigned char c[1], d[1]; + + for (n = 0; n < inl; ++n) { + c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; + DES_ede3_cfb_encrypt(c, d, 1, 1, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + ctx->encrypt); + out[n / 8] = (out[n / 8] & ~(0x80 >> (unsigned int)(n % 8))) + | ((d[0] & 0x80) >> (unsigned int)(n % 8)); + } + + return 1; +} + +static int des_ede3_cfb8_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_ede3_cfb_encrypt(in, out, 8, (long)EVP_MAXCHUNK, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_ede3_cfb_encrypt(in, out, 8, (long)inl, + &data(ctx)->ks1, &data(ctx)->ks2, + &data(ctx)->ks3, (DES_cblock *)ctx->iv, + ctx->encrypt); + return 1; +} + +BLOCK_CIPHER_defs(des_ede, DES_EDE_KEY, NID_des_ede, 8, 16, 8, 64, + EVP_CIPH_RAND_KEY, des_ede_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des3_ctrl) +# define des_ede3_cfb64_cipher des_ede_cfb64_cipher +# define des_ede3_ofb_cipher des_ede_ofb_cipher +# define des_ede3_cbc_cipher des_ede_cbc_cipher +# define des_ede3_ecb_cipher des_ede_ecb_cipher + BLOCK_CIPHER_defs(des_ede3, DES_EDE_KEY, NID_des_ede3, 8, 24, 8, 64, + EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, des3_ctrl) + + BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 1, + EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, des3_ctrl) + + BLOCK_CIPHER_def_cfb(des_ede3, DES_EDE_KEY, NID_des_ede3, 24, 8, 8, + EVP_CIPH_RAND_KEY, des_ede3_init_key, NULL, + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, des3_ctrl) + +static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + DES_cblock *deskey = (DES_cblock *)key; +# ifdef EVP_CHECK_DES_KEY + if (DES_set_key_checked(&deskey[0], &data(ctx)->ks1) + || DES_set_key_checked(&deskey[1], &data(ctx)->ks2)) + return 0; +# else + DES_set_key_unchecked(&deskey[0], &data(ctx)->ks1); + DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2); +# endif + memcpy(&data(ctx)->ks3, &data(ctx)->ks1, sizeof(data(ctx)->ks1)); + return 1; +} + +static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + DES_cblock *deskey = (DES_cblock *)key; +# ifdef KSSL_DEBUG + { + int i; + fprintf(stderr, "des_ede3_init_key(ctx=%p)\n", ctx); + fprintf(stderr, "\tKEY= "); + for (i = 0; i < 24; i++) + fprintf(stderr, "%02X", key[i]); + fprintf(stderr, "\n"); + if (iv) { + fprintf(stderr, "\t IV= "); + for (i = 0; i < 8; i++) + fprintf(stderr, "%02X", iv[i]); + fprintf(stderr, "\n"); + } + } +# endif /* KSSL_DEBUG */ + +# ifdef EVP_CHECK_DES_KEY + if (DES_set_key_checked(&deskey[0], &data(ctx)->ks1) + || DES_set_key_checked(&deskey[1], &data(ctx)->ks2) + || DES_set_key_checked(&deskey[2], &data(ctx)->ks3)) + return 0; +# else + DES_set_key_unchecked(&deskey[0], &data(ctx)->ks1); + DES_set_key_unchecked(&deskey[1], &data(ctx)->ks2); + DES_set_key_unchecked(&deskey[2], &data(ctx)->ks3); +# endif + return 1; +} + +static int des3_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + + DES_cblock *deskey = ptr; + + switch (type) { + case EVP_CTRL_RAND_KEY: + if (RAND_bytes(ptr, c->key_len) <= 0) + return 0; + DES_set_odd_parity(deskey); + if (c->key_len >= 16) + DES_set_odd_parity(deskey + 1); + if (c->key_len >= 24) + DES_set_odd_parity(deskey + 2); + return 1; + + default: + return -1; + } +} + +const EVP_CIPHER *EVP_des_ede(void) +{ + return &des_ede_ecb; +} + +const EVP_CIPHER *EVP_des_ede3(void) +{ + return &des_ede3_ecb; +} +# endif +#endif diff --git a/libs/openssl/crypto/evp/e_dsa.c b/libs/openssl/crypto/evp/e_dsa.c new file mode 100644 index 00000000..523993f4 --- /dev/null +++ b/libs/openssl/crypto/evp/e_dsa.c @@ -0,0 +1,69 @@ +/* crypto/evp/e_dsa.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +static EVP_PKEY_METHOD dss_method = { + DSA_sign, + DSA_verify, + {EVP_PKEY_DSA, EVP_PKEY_DSA2, EVP_PKEY_DSA3, NULL}, +}; diff --git a/libs/openssl/crypto/evp/e_idea.c b/libs/openssl/crypto/evp/e_idea.c new file mode 100644 index 00000000..cac72b33 --- /dev/null +++ b/libs/openssl/crypto/evp/e_idea.c @@ -0,0 +1,119 @@ +/* crypto/evp/e_idea.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_IDEA +# include +# include +# include "evp_locl.h" +# include + +static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +/* + * NB idea_ecb_encrypt doesn't take an 'encrypt' argument so we treat it as a + * special case + */ + +static int idea_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + BLOCK_CIPHER_ecb_loop() + idea_ecb_encrypt(in + i, out + i, ctx->cipher_data); + return 1; +} + +/* Can't use IMPLEMENT_BLOCK_CIPHER because idea_ecb_encrypt is different */ + +typedef struct { + IDEA_KEY_SCHEDULE ks; +} EVP_IDEA_KEY; + +BLOCK_CIPHER_func_cbc(idea, idea, EVP_IDEA_KEY, ks) + BLOCK_CIPHER_func_ofb(idea, idea, 64, EVP_IDEA_KEY, ks) + BLOCK_CIPHER_func_cfb(idea, idea, 64, EVP_IDEA_KEY, ks) + + BLOCK_CIPHER_defs(idea, IDEA_KEY_SCHEDULE, NID_idea, 8, 16, 8, 64, + 0, idea_init_key, NULL, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) + +static int idea_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + if (!enc) { + if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_OFB_MODE) + enc = 1; + else if (EVP_CIPHER_CTX_mode(ctx) == EVP_CIPH_CFB_MODE) + enc = 1; + } + if (enc) + idea_set_encrypt_key(key, ctx->cipher_data); + else { + IDEA_KEY_SCHEDULE tmp; + + idea_set_encrypt_key(key, &tmp); + idea_set_decrypt_key(&tmp, ctx->cipher_data); + OPENSSL_cleanse((unsigned char *)&tmp, sizeof(IDEA_KEY_SCHEDULE)); + } + return 1; +} + +#endif diff --git a/libs/openssl/crypto/evp/e_null.c b/libs/openssl/crypto/evp/e_null.c new file mode 100644 index 00000000..af90ce32 --- /dev/null +++ b/libs/openssl/crypto/evp/e_null.c @@ -0,0 +1,103 @@ +/* crypto/evp/e_null.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +#ifndef OPENSSL_FIPS + +static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); +static const EVP_CIPHER n_cipher = { + NID_undef, + 1, 0, 0, + 0, + null_init_key, + null_cipher, + NULL, + 0, + NULL, + NULL, + NULL, + NULL +}; + +const EVP_CIPHER *EVP_enc_null(void) +{ + return (&n_cipher); +} + +static int null_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + /* memset(&(ctx->c),0,sizeof(ctx->c)); */ + return 1; +} + +static int null_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + if (in != out) + memcpy((char *)out, (const char *)in, inl); + return 1; +} +#endif diff --git a/libs/openssl/crypto/evp/e_old.c b/libs/openssl/crypto/evp/e_old.c new file mode 100644 index 00000000..a23d143b --- /dev/null +++ b/libs/openssl/crypto/evp/e_old.c @@ -0,0 +1,164 @@ +/* crypto/evp/e_old.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifdef OPENSSL_NO_DEPRECATED +static void *dummy = &dummy; +#else + +# include + +/* + * Define some deprecated functions, so older programs don't crash and burn + * too quickly. On Windows and VMS, these will never be used, since + * functions and variables in shared libraries are selected by entry point + * location, not by name. + */ + +# ifndef OPENSSL_NO_BF +# undef EVP_bf_cfb +const EVP_CIPHER *EVP_bf_cfb(void); +const EVP_CIPHER *EVP_bf_cfb(void) +{ + return EVP_bf_cfb64(); +} +# endif + +# ifndef OPENSSL_NO_DES +# undef EVP_des_cfb +const EVP_CIPHER *EVP_des_cfb(void); +const EVP_CIPHER *EVP_des_cfb(void) +{ + return EVP_des_cfb64(); +} + +# undef EVP_des_ede3_cfb +const EVP_CIPHER *EVP_des_ede3_cfb(void); +const EVP_CIPHER *EVP_des_ede3_cfb(void) +{ + return EVP_des_ede3_cfb64(); +} + +# undef EVP_des_ede_cfb +const EVP_CIPHER *EVP_des_ede_cfb(void); +const EVP_CIPHER *EVP_des_ede_cfb(void) +{ + return EVP_des_ede_cfb64(); +} +# endif + +# ifndef OPENSSL_NO_IDEA +# undef EVP_idea_cfb +const EVP_CIPHER *EVP_idea_cfb(void); +const EVP_CIPHER *EVP_idea_cfb(void) +{ + return EVP_idea_cfb64(); +} +# endif + +# ifndef OPENSSL_NO_RC2 +# undef EVP_rc2_cfb +const EVP_CIPHER *EVP_rc2_cfb(void); +const EVP_CIPHER *EVP_rc2_cfb(void) +{ + return EVP_rc2_cfb64(); +} +# endif + +# ifndef OPENSSL_NO_CAST +# undef EVP_cast5_cfb +const EVP_CIPHER *EVP_cast5_cfb(void); +const EVP_CIPHER *EVP_cast5_cfb(void) +{ + return EVP_cast5_cfb64(); +} +# endif + +# ifndef OPENSSL_NO_RC5 +# undef EVP_rc5_32_12_16_cfb +const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void); +const EVP_CIPHER *EVP_rc5_32_12_16_cfb(void) +{ + return EVP_rc5_32_12_16_cfb64(); +} +# endif + +# ifndef OPENSSL_NO_AES +# undef EVP_aes_128_cfb +const EVP_CIPHER *EVP_aes_128_cfb(void); +const EVP_CIPHER *EVP_aes_128_cfb(void) +{ + return EVP_aes_128_cfb128(); +} + +# undef EVP_aes_192_cfb +const EVP_CIPHER *EVP_aes_192_cfb(void); +const EVP_CIPHER *EVP_aes_192_cfb(void) +{ + return EVP_aes_192_cfb128(); +} + +# undef EVP_aes_256_cfb +const EVP_CIPHER *EVP_aes_256_cfb(void); +const EVP_CIPHER *EVP_aes_256_cfb(void) +{ + return EVP_aes_256_cfb128(); +} +# endif + +#endif diff --git a/libs/openssl/crypto/evp/e_rc2.c b/libs/openssl/crypto/evp/e_rc2.c new file mode 100644 index 00000000..718cc869 --- /dev/null +++ b/libs/openssl/crypto/evp/e_rc2.c @@ -0,0 +1,235 @@ +/* crypto/evp/e_rc2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_RC2 + +# include +# include +# include "evp_locl.h" +# include + +static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int rc2_meth_to_magic(EVP_CIPHER_CTX *ctx); +static int rc2_magic_to_meth(int i); +static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); + +typedef struct { + int key_bits; /* effective key bits */ + RC2_KEY ks; /* key schedule */ +} EVP_RC2_KEY; + +# define data(ctx) ((EVP_RC2_KEY *)(ctx)->cipher_data) + +IMPLEMENT_BLOCK_CIPHER(rc2, ks, RC2, EVP_RC2_KEY, NID_rc2, + 8, + RC2_KEY_LENGTH, 8, 64, + EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + rc2_init_key, NULL, + rc2_set_asn1_type_and_iv, rc2_get_asn1_type_and_iv, + rc2_ctrl) +# define RC2_40_MAGIC 0xa0 +# define RC2_64_MAGIC 0x78 +# define RC2_128_MAGIC 0x3a +static const EVP_CIPHER r2_64_cbc_cipher = { + NID_rc2_64_cbc, + 8, 8 /* 64 bit */ , 8, + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + rc2_init_key, + rc2_cbc_cipher, + NULL, + sizeof(EVP_RC2_KEY), + rc2_set_asn1_type_and_iv, + rc2_get_asn1_type_and_iv, + rc2_ctrl, + NULL +}; + +static const EVP_CIPHER r2_40_cbc_cipher = { + NID_rc2_40_cbc, + 8, 5 /* 40 bit */ , 8, + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + rc2_init_key, + rc2_cbc_cipher, + NULL, + sizeof(EVP_RC2_KEY), + rc2_set_asn1_type_and_iv, + rc2_get_asn1_type_and_iv, + rc2_ctrl, + NULL +}; + +const EVP_CIPHER *EVP_rc2_64_cbc(void) +{ + return (&r2_64_cbc_cipher); +} + +const EVP_CIPHER *EVP_rc2_40_cbc(void) +{ + return (&r2_40_cbc_cipher); +} + +static int rc2_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + RC2_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), + key, data(ctx)->key_bits); + return 1; +} + +static int rc2_meth_to_magic(EVP_CIPHER_CTX *e) +{ + int i; + + EVP_CIPHER_CTX_ctrl(e, EVP_CTRL_GET_RC2_KEY_BITS, 0, &i); + if (i == 128) + return (RC2_128_MAGIC); + else if (i == 64) + return (RC2_64_MAGIC); + else if (i == 40) + return (RC2_40_MAGIC); + else + return (0); +} + +static int rc2_magic_to_meth(int i) +{ + if (i == RC2_128_MAGIC) + return 128; + else if (i == RC2_64_MAGIC) + return 64; + else if (i == RC2_40_MAGIC) + return 40; + else { + EVPerr(EVP_F_RC2_MAGIC_TO_METH, EVP_R_UNSUPPORTED_KEY_SIZE); + return (0); + } +} + +static int rc2_get_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + long num = 0; + int i = 0; + int key_bits; + unsigned int l; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (type != NULL) { + l = EVP_CIPHER_CTX_iv_length(c); + OPENSSL_assert(l <= sizeof(iv)); + i = ASN1_TYPE_get_int_octetstring(type, &num, iv, l); + if (i != (int)l) + return (-1); + key_bits = rc2_magic_to_meth((int)num); + if (!key_bits) + return (-1); + if (i > 0 && !EVP_CipherInit_ex(c, NULL, NULL, NULL, iv, -1)) + return -1; + EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_RC2_KEY_BITS, key_bits, NULL); + EVP_CIPHER_CTX_set_key_length(c, key_bits / 8); + } + return (i); +} + +static int rc2_set_asn1_type_and_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + long num; + int i = 0, j; + + if (type != NULL) { + num = rc2_meth_to_magic(c); + j = EVP_CIPHER_CTX_iv_length(c); + i = ASN1_TYPE_set_int_octetstring(type, num, c->oiv, j); + } + return (i); +} + +static int rc2_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + switch (type) { + case EVP_CTRL_INIT: + data(c)->key_bits = EVP_CIPHER_CTX_key_length(c) * 8; + return 1; + + case EVP_CTRL_GET_RC2_KEY_BITS: + *(int *)ptr = data(c)->key_bits; + return 1; + + case EVP_CTRL_SET_RC2_KEY_BITS: + if (arg > 0) { + data(c)->key_bits = arg; + return 1; + } + return 0; +# ifdef PBE_PRF_TEST + case EVP_CTRL_PBE_PRF_NID: + *(int *)ptr = NID_hmacWithMD5; + return 1; +# endif + + default: + return -1; + } +} + +#endif diff --git a/libs/openssl/crypto/evp/e_rc4.c b/libs/openssl/crypto/evp/e_rc4.c new file mode 100644 index 00000000..08e48f39 --- /dev/null +++ b/libs/openssl/crypto/evp/e_rc4.c @@ -0,0 +1,133 @@ +/* crypto/evp/e_rc4.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_RC4 + +# include +# include "evp_locl.h" +# include +# include + +/* FIXME: surely this is available elsewhere? */ +# define EVP_RC4_KEY_SIZE 16 + +typedef struct { + RC4_KEY ks; /* working key */ +} EVP_RC4_KEY; + +# define data(ctx) ((EVP_RC4_KEY *)(ctx)->cipher_data) + +static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); +static const EVP_CIPHER r4_cipher = { + NID_rc4, + 1, EVP_RC4_KEY_SIZE, 0, + EVP_CIPH_VARIABLE_LENGTH, + rc4_init_key, + rc4_cipher, + NULL, + sizeof(EVP_RC4_KEY), + NULL, + NULL, + NULL, + NULL +}; + +static const EVP_CIPHER r4_40_cipher = { + NID_rc4_40, + 1, 5 /* 40 bit */ , 0, + EVP_CIPH_VARIABLE_LENGTH, + rc4_init_key, + rc4_cipher, + NULL, + sizeof(EVP_RC4_KEY), + NULL, + NULL, + NULL, + NULL +}; + +const EVP_CIPHER *EVP_rc4(void) +{ + return (&r4_cipher); +} + +const EVP_CIPHER *EVP_rc4_40(void) +{ + return (&r4_40_cipher); +} + +static int rc4_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + RC4_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), key); + return 1; +} + +static int rc4_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + RC4(&data(ctx)->ks, inl, in, out); + return 1; +} +#endif diff --git a/libs/openssl/crypto/evp/e_rc4_hmac_md5.c b/libs/openssl/crypto/evp/e_rc4_hmac_md5.c new file mode 100644 index 00000000..2da11178 --- /dev/null +++ b/libs/openssl/crypto/evp/e_rc4_hmac_md5.c @@ -0,0 +1,308 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#include +#include + +#if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5) + +# include +# include +# include +# include +# include + +# ifndef EVP_CIPH_FLAG_AEAD_CIPHER +# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 +# define EVP_CTRL_AEAD_TLS1_AAD 0x16 +# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 +# endif + +/* FIXME: surely this is available elsewhere? */ +# define EVP_RC4_KEY_SIZE 16 + +typedef struct { + RC4_KEY ks; + MD5_CTX head, tail, md; + size_t payload_length; +} EVP_RC4_HMAC_MD5; + +# define NO_PAYLOAD_LENGTH ((size_t)-1) + +void rc4_md5_enc(RC4_KEY *key, const void *in0, void *out, + MD5_CTX *ctx, const void *inp, size_t blocks); + +# define data(ctx) ((EVP_RC4_HMAC_MD5 *)(ctx)->cipher_data) + +static int rc4_hmac_md5_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *inkey, + const unsigned char *iv, int enc) +{ + EVP_RC4_HMAC_MD5 *key = data(ctx); + + RC4_set_key(&key->ks, EVP_CIPHER_CTX_key_length(ctx), inkey); + + MD5_Init(&key->head); /* handy when benchmarking */ + key->tail = key->head; + key->md = key->head; + + key->payload_length = NO_PAYLOAD_LENGTH; + + return 1; +} + +# if !defined(OPENSSL_NO_ASM) && ( \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_AMD64) || defined(_M_X64) || \ + defined(__INTEL__) ) && \ + !(defined(__APPLE__) && defined(__MACH__)) +# define STITCHED_CALL +# endif + +# if !defined(STITCHED_CALL) +# define rc4_off 0 +# define md5_off 0 +# endif + +static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t len) +{ + EVP_RC4_HMAC_MD5 *key = data(ctx); +# if defined(STITCHED_CALL) + size_t rc4_off = 32 - 1 - (key->ks.x & (32 - 1)), /* 32 is $MOD from + * rc4_md5-x86_64.pl */ + md5_off = MD5_CBLOCK - key->md.num, blocks; + unsigned int l; + extern unsigned int OPENSSL_ia32cap_P[]; +# endif + size_t plen = key->payload_length; + + if (plen != NO_PAYLOAD_LENGTH && len != (plen + MD5_DIGEST_LENGTH)) + return 0; + + if (ctx->encrypt) { + if (plen == NO_PAYLOAD_LENGTH) + plen = len; +# if defined(STITCHED_CALL) + /* cipher has to "fall behind" */ + if (rc4_off > md5_off) + md5_off += MD5_CBLOCK; + + if (plen > md5_off && (blocks = (plen - md5_off) / MD5_CBLOCK) && + (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) { + MD5_Update(&key->md, in, md5_off); + RC4(&key->ks, rc4_off, in, out); + + rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off, + &key->md, in + md5_off, blocks); + blocks *= MD5_CBLOCK; + rc4_off += blocks; + md5_off += blocks; + key->md.Nh += blocks >> 29; + key->md.Nl += blocks <<= 3; + if (key->md.Nl < (unsigned int)blocks) + key->md.Nh++; + } else { + rc4_off = 0; + md5_off = 0; + } +# endif + MD5_Update(&key->md, in + md5_off, plen - md5_off); + + if (plen != len) { /* "TLS" mode of operation */ + if (in != out) + memcpy(out + rc4_off, in + rc4_off, plen - rc4_off); + + /* calculate HMAC and append it to payload */ + MD5_Final(out + plen, &key->md); + key->md = key->tail; + MD5_Update(&key->md, out + plen, MD5_DIGEST_LENGTH); + MD5_Final(out + plen, &key->md); + /* encrypt HMAC at once */ + RC4(&key->ks, len - rc4_off, out + rc4_off, out + rc4_off); + } else { + RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off); + } + } else { + unsigned char mac[MD5_DIGEST_LENGTH]; +# if defined(STITCHED_CALL) + /* digest has to "fall behind" */ + if (md5_off > rc4_off) + rc4_off += 2 * MD5_CBLOCK; + else + rc4_off += MD5_CBLOCK; + + if (len > rc4_off && (blocks = (len - rc4_off) / MD5_CBLOCK) && + (OPENSSL_ia32cap_P[0] & (1 << 20)) == 0) { + RC4(&key->ks, rc4_off, in, out); + MD5_Update(&key->md, out, md5_off); + + rc4_md5_enc(&key->ks, in + rc4_off, out + rc4_off, + &key->md, out + md5_off, blocks); + blocks *= MD5_CBLOCK; + rc4_off += blocks; + md5_off += blocks; + l = (key->md.Nl + (blocks << 3)) & 0xffffffffU; + if (l < key->md.Nl) + key->md.Nh++; + key->md.Nl = l; + key->md.Nh += blocks >> 29; + } else { + md5_off = 0; + rc4_off = 0; + } +# endif + /* decrypt HMAC at once */ + RC4(&key->ks, len - rc4_off, in + rc4_off, out + rc4_off); + if (plen != NO_PAYLOAD_LENGTH) { /* "TLS" mode of operation */ + MD5_Update(&key->md, out + md5_off, plen - md5_off); + + /* calculate HMAC and verify it */ + MD5_Final(mac, &key->md); + key->md = key->tail; + MD5_Update(&key->md, mac, MD5_DIGEST_LENGTH); + MD5_Final(mac, &key->md); + + if (CRYPTO_memcmp(out + plen, mac, MD5_DIGEST_LENGTH)) + return 0; + } else { + MD5_Update(&key->md, out + md5_off, len - md5_off); + } + } + + key->payload_length = NO_PAYLOAD_LENGTH; + + return 1; +} + +static int rc4_hmac_md5_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, + void *ptr) +{ + EVP_RC4_HMAC_MD5 *key = data(ctx); + + switch (type) { + case EVP_CTRL_AEAD_SET_MAC_KEY: + { + unsigned int i; + unsigned char hmac_key[64]; + + memset(hmac_key, 0, sizeof(hmac_key)); + + if (arg > (int)sizeof(hmac_key)) { + MD5_Init(&key->head); + MD5_Update(&key->head, ptr, arg); + MD5_Final(hmac_key, &key->head); + } else { + memcpy(hmac_key, ptr, arg); + } + + for (i = 0; i < sizeof(hmac_key); i++) + hmac_key[i] ^= 0x36; /* ipad */ + MD5_Init(&key->head); + MD5_Update(&key->head, hmac_key, sizeof(hmac_key)); + + for (i = 0; i < sizeof(hmac_key); i++) + hmac_key[i] ^= 0x36 ^ 0x5c; /* opad */ + MD5_Init(&key->tail); + MD5_Update(&key->tail, hmac_key, sizeof(hmac_key)); + + return 1; + } + case EVP_CTRL_AEAD_TLS1_AAD: + { + unsigned char *p = ptr; + unsigned int len; + + if (arg != EVP_AEAD_TLS1_AAD_LEN) + return -1; + + len = p[arg - 2] << 8 | p[arg - 1]; + + if (!ctx->encrypt) { + len -= MD5_DIGEST_LENGTH; + p[arg - 2] = len >> 8; + p[arg - 1] = len; + } + key->payload_length = len; + key->md = key->head; + MD5_Update(&key->md, p, arg); + + return MD5_DIGEST_LENGTH; + } + default: + return -1; + } +} + +static EVP_CIPHER r4_hmac_md5_cipher = { +# ifdef NID_rc4_hmac_md5 + NID_rc4_hmac_md5, +# else + NID_undef, +# endif + 1, EVP_RC4_KEY_SIZE, 0, + EVP_CIPH_STREAM_CIPHER | EVP_CIPH_VARIABLE_LENGTH | + EVP_CIPH_FLAG_AEAD_CIPHER, + rc4_hmac_md5_init_key, + rc4_hmac_md5_cipher, + NULL, + sizeof(EVP_RC4_HMAC_MD5), + NULL, + NULL, + rc4_hmac_md5_ctrl, + NULL +}; + +const EVP_CIPHER *EVP_rc4_hmac_md5(void) +{ + return (&r4_hmac_md5_cipher); +} +#endif diff --git a/libs/openssl/crypto/evp/e_rc5.c b/libs/openssl/crypto/evp/e_rc5.c new file mode 100644 index 00000000..f17e99d0 --- /dev/null +++ b/libs/openssl/crypto/evp/e_rc5.c @@ -0,0 +1,122 @@ +/* crypto/evp/e_rc5.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_RC5 + +# include +# include +# include "evp_locl.h" +# include + +static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr); + +typedef struct { + int rounds; /* number of rounds */ + RC5_32_KEY ks; /* key schedule */ +} EVP_RC5_KEY; + +# define data(ctx) EVP_C_DATA(EVP_RC5_KEY,ctx) + +IMPLEMENT_BLOCK_CIPHER(rc5_32_12_16, ks, RC5_32, EVP_RC5_KEY, NID_rc5, + 8, RC5_32_KEY_LENGTH, 8, 64, + EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + r_32_12_16_init_key, NULL, NULL, NULL, rc5_ctrl) + +static int rc5_ctrl(EVP_CIPHER_CTX *c, int type, int arg, void *ptr) +{ + switch (type) { + case EVP_CTRL_INIT: + data(c)->rounds = RC5_12_ROUNDS; + return 1; + + case EVP_CTRL_GET_RC5_ROUNDS: + *(int *)ptr = data(c)->rounds; + return 1; + + case EVP_CTRL_SET_RC5_ROUNDS: + switch (arg) { + case RC5_8_ROUNDS: + case RC5_12_ROUNDS: + case RC5_16_ROUNDS: + data(c)->rounds = arg; + return 1; + + default: + EVPerr(EVP_F_RC5_CTRL, EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS); + return 0; + } + + default: + return -1; + } +} + +static int r_32_12_16_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + RC5_32_set_key(&data(ctx)->ks, EVP_CIPHER_CTX_key_length(ctx), + key, data(ctx)->rounds); + return 1; +} + +#endif diff --git a/libs/openssl/crypto/evp/e_seed.c b/libs/openssl/crypto/evp/e_seed.c new file mode 100644 index 00000000..7249d1b1 --- /dev/null +++ b/libs/openssl/crypto/evp/e_seed.c @@ -0,0 +1,82 @@ +/* crypto/evp/e_seed.c */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#ifndef OPENSSL_NO_SEED +# include +# include +# include +# include +# include +# include "evp_locl.h" + +static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + +typedef struct { + SEED_KEY_SCHEDULE ks; +} EVP_SEED_KEY; + +IMPLEMENT_BLOCK_CIPHER(seed, ks, SEED, EVP_SEED_KEY, NID_seed, + 16, 16, 16, 128, 0, seed_init_key, 0, 0, 0, 0) + +static int seed_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + SEED_set_key(key, ctx->cipher_data); + return 1; +} + +#endif diff --git a/libs/openssl/crypto/evp/e_xcbc_d.c b/libs/openssl/crypto/evp/e_xcbc_d.c new file mode 100644 index 00000000..3430df9e --- /dev/null +++ b/libs/openssl/crypto/evp/e_xcbc_d.c @@ -0,0 +1,130 @@ +/* crypto/evp/e_xcbc_d.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_DES + +# include +# include +# include "evp_locl.h" +# include + +static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); +static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); + +typedef struct { + DES_key_schedule ks; /* key schedule */ + DES_cblock inw; + DES_cblock outw; +} DESX_CBC_KEY; + +# define data(ctx) ((DESX_CBC_KEY *)(ctx)->cipher_data) + +static const EVP_CIPHER d_xcbc_cipher = { + NID_desx_cbc, + 8, 24, 8, + EVP_CIPH_CBC_MODE, + desx_cbc_init_key, + desx_cbc_cipher, + NULL, + sizeof(DESX_CBC_KEY), + EVP_CIPHER_set_asn1_iv, + EVP_CIPHER_get_asn1_iv, + NULL, + NULL +}; + +const EVP_CIPHER *EVP_desx_cbc(void) +{ + return (&d_xcbc_cipher); +} + +static int desx_cbc_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc) +{ + DES_cblock *deskey = (DES_cblock *)key; + + DES_set_key_unchecked(deskey, &data(ctx)->ks); + memcpy(&data(ctx)->inw[0], &key[8], 8); + memcpy(&data(ctx)->outw[0], &key[16], 8); + + return 1; +} + +static int desx_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl) +{ + while (inl >= EVP_MAXCHUNK) { + DES_xcbc_encrypt(in, out, (long)EVP_MAXCHUNK, &data(ctx)->ks, + (DES_cblock *)&(ctx->iv[0]), + &data(ctx)->inw, &data(ctx)->outw, ctx->encrypt); + inl -= EVP_MAXCHUNK; + in += EVP_MAXCHUNK; + out += EVP_MAXCHUNK; + } + if (inl) + DES_xcbc_encrypt(in, out, (long)inl, &data(ctx)->ks, + (DES_cblock *)&(ctx->iv[0]), + &data(ctx)->inw, &data(ctx)->outw, ctx->encrypt); + return 1; +} +#endif diff --git a/libs/openssl/crypto/evp/encode.c b/libs/openssl/crypto/evp/encode.c new file mode 100644 index 00000000..c6c775e0 --- /dev/null +++ b/libs/openssl/crypto/evp/encode.c @@ -0,0 +1,460 @@ +/* crypto/evp/encode.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include + +static unsigned char conv_ascii2bin(unsigned char a); +#ifndef CHARSET_EBCDIC +# define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f]) +#else +/* + * We assume that PEM encoded files are EBCDIC files (i.e., printable text + * files). Convert them here while decoding. When encoding, output is EBCDIC + * (text) format again. (No need for conversion in the conv_bin2ascii macro, + * as the underlying textstring data_bin2ascii[] is already EBCDIC) + */ +# define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f]) +#endif + +/*- + * 64 char lines + * pad input with 0 + * left over chars are set to = + * 1 byte => xx== + * 2 bytes => xxx= + * 3 bytes => xxxx + */ +#define BIN_PER_LINE (64/4*3) +#define CHUNKS_PER_LINE (64/4) +#define CHAR_PER_LINE (64+1) + +static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\ +abcdefghijklmnopqrstuvwxyz0123456789+/"; + +/*- + * 0xF0 is a EOLN + * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing). + * 0xF2 is EOF + * 0xE0 is ignore at start of line. + * 0xFF is error + */ + +#define B64_EOLN 0xF0 +#define B64_CR 0xF1 +#define B64_EOF 0xF2 +#define B64_WS 0xE0 +#define B64_ERROR 0xFF +#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3) +#define B64_BASE64(a) !B64_NOT_BASE64(a) + +static const unsigned char data_ascii2bin[128] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, + 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, + 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, + 0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, + 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, + 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + +#ifndef CHARSET_EBCDIC +static unsigned char conv_ascii2bin(unsigned char a) +{ + if (a & 0x80) + return B64_ERROR; + return data_ascii2bin[a]; +} +#else +static unsigned char conv_ascii2bin(unsigned char a) +{ + a = os_toascii[a]; + if (a & 0x80) + return B64_ERROR; + return data_ascii2bin[a]; +} +#endif + +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) +{ + ctx->length = 48; + ctx->num = 0; + ctx->line_num = 0; +} + +void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + int i, j; + size_t total = 0; + + *outl = 0; + if (inl <= 0) + return; + OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data)); + if (ctx->length - ctx->num > inl) { + memcpy(&(ctx->enc_data[ctx->num]), in, inl); + ctx->num += inl; + return; + } + if (ctx->num != 0) { + i = ctx->length - ctx->num; + memcpy(&(ctx->enc_data[ctx->num]), in, i); + in += i; + inl -= i; + j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length); + ctx->num = 0; + out += j; + *(out++) = '\n'; + *out = '\0'; + total = j + 1; + } + while (inl >= ctx->length && total <= INT_MAX) { + j = EVP_EncodeBlock(out, in, ctx->length); + in += ctx->length; + inl -= ctx->length; + out += j; + *(out++) = '\n'; + *out = '\0'; + total += j + 1; + } + if (total > INT_MAX) { + /* Too much output data! */ + *outl = 0; + return; + } + if (inl != 0) + memcpy(&(ctx->enc_data[0]), in, inl); + ctx->num = inl; + *outl = total; +} + +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl) +{ + unsigned int ret = 0; + + if (ctx->num != 0) { + ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num); + out[ret++] = '\n'; + out[ret] = '\0'; + ctx->num = 0; + } + *outl = ret; +} + +int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen) +{ + int i, ret = 0; + unsigned long l; + + for (i = dlen; i > 0; i -= 3) { + if (i >= 3) { + l = (((unsigned long)f[0]) << 16L) | + (((unsigned long)f[1]) << 8L) | f[2]; + *(t++) = conv_bin2ascii(l >> 18L); + *(t++) = conv_bin2ascii(l >> 12L); + *(t++) = conv_bin2ascii(l >> 6L); + *(t++) = conv_bin2ascii(l); + } else { + l = ((unsigned long)f[0]) << 16L; + if (i == 2) + l |= ((unsigned long)f[1] << 8L); + + *(t++) = conv_bin2ascii(l >> 18L); + *(t++) = conv_bin2ascii(l >> 12L); + *(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L); + *(t++) = '='; + } + ret += 4; + f += 3; + } + + *t = '\0'; + return (ret); +} + +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) +{ + /* Only ctx->num is used during decoding. */ + ctx->num = 0; + ctx->length = 0; + ctx->line_num = 0; + ctx->expect_nl = 0; +} + +/*- + * -1 for error + * 0 for last line + * 1 for full line + * + * Note: even though EVP_DecodeUpdate attempts to detect and report end of + * content, the context doesn't currently remember it and will accept more data + * in the next call. Therefore, the caller is responsible for checking and + * rejecting a 0 return value in the middle of content. + * + * Note: even though EVP_DecodeUpdate has historically tried to detect end of + * content based on line length, this has never worked properly. Therefore, + * we now return 0 when one of the following is true: + * - Padding or B64_EOF was detected and the last block is complete. + * - Input has zero-length. + * -1 is returned if: + * - Invalid characters are detected. + * - There is extra trailing padding, or data after padding. + * - B64_EOF is detected after an incomplete base64 block. + */ +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + int seof = 0, eof = 0, rv = -1, ret = 0, i, v, tmp, n, decoded_len; + unsigned char *d; + + n = ctx->num; + d = ctx->enc_data; + + if (n > 0 && d[n - 1] == '=') { + eof++; + if (n > 1 && d[n - 2] == '=') + eof++; + } + + /* Legacy behaviour: an empty input chunk signals end of input. */ + if (inl == 0) { + rv = 0; + goto end; + } + + for (i = 0; i < inl; i++) { + tmp = *(in++); + v = conv_ascii2bin(tmp); + if (v == B64_ERROR) { + rv = -1; + goto end; + } + + if (tmp == '=') { + eof++; + } else if (eof > 0 && B64_BASE64(v)) { + /* More data after padding. */ + rv = -1; + goto end; + } + + if (eof > 2) { + rv = -1; + goto end; + } + + if (v == B64_EOF) { + seof = 1; + goto tail; + } + + /* Only save valid base64 characters. */ + if (B64_BASE64(v)) { + if (n >= 64) { + /* + * We increment n once per loop, and empty the buffer as soon as + * we reach 64 characters, so this can only happen if someone's + * manually messed with the ctx. Refuse to write any more data. + */ + rv = -1; + goto end; + } + OPENSSL_assert(n < (int)sizeof(ctx->enc_data)); + d[n++] = tmp; + } + + if (n == 64) { + decoded_len = EVP_DecodeBlock(out, d, n); + n = 0; + if (decoded_len < 0 || eof > decoded_len) { + rv = -1; + goto end; + } + ret += decoded_len - eof; + out += decoded_len - eof; + } + } + + /* + * Legacy behaviour: if the current line is a full base64-block (i.e., has + * 0 mod 4 base64 characters), it is processed immediately. We keep this + * behaviour as applications may not be calling EVP_DecodeFinal properly. + */ +tail: + if (n > 0) { + if ((n & 3) == 0) { + decoded_len = EVP_DecodeBlock(out, d, n); + n = 0; + if (decoded_len < 0 || eof > decoded_len) { + rv = -1; + goto end; + } + ret += (decoded_len - eof); + } else if (seof) { + /* EOF in the middle of a base64 block. */ + rv = -1; + goto end; + } + } + + rv = seof || (n == 0 && eof) ? 0 : 1; +end: + /* Legacy behaviour. This should probably rather be zeroed on error. */ + *outl = ret; + ctx->num = n; + return (rv); +} + +int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n) +{ + int i, ret = 0, a, b, c, d; + unsigned long l; + + /* trim white space from the start of the line. */ + while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) { + f++; + n--; + } + + /* + * strip off stuff at the end of the line ascii2bin values B64_WS, + * B64_EOLN, B64_EOLN and B64_EOF + */ + while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1])))) + n--; + + if (n % 4 != 0) + return (-1); + + for (i = 0; i < n; i += 4) { + a = conv_ascii2bin(*(f++)); + b = conv_ascii2bin(*(f++)); + c = conv_ascii2bin(*(f++)); + d = conv_ascii2bin(*(f++)); + if ((a & 0x80) || (b & 0x80) || (c & 0x80) || (d & 0x80)) + return (-1); + l = ((((unsigned long)a) << 18L) | + (((unsigned long)b) << 12L) | + (((unsigned long)c) << 6L) | (((unsigned long)d))); + *(t++) = (unsigned char)(l >> 16L) & 0xff; + *(t++) = (unsigned char)(l >> 8L) & 0xff; + *(t++) = (unsigned char)(l) & 0xff; + ret += 3; + } + return (ret); +} + +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl) +{ + int i; + + *outl = 0; + if (ctx->num != 0) { + i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num); + if (i < 0) + return (-1); + ctx->num = 0; + *outl = i; + return (1); + } else + return (1); +} + +#ifdef undef +int EVP_DecodeValid(unsigned char *buf, int len) +{ + int i, num = 0, bad = 0; + + if (len == 0) + return (-1); + while (conv_ascii2bin(*buf) == B64_WS) { + buf++; + len--; + if (len == 0) + return (-1); + } + + for (i = len; i >= 4; i -= 4) { + if ((conv_ascii2bin(buf[0]) >= 0x40) || + (conv_ascii2bin(buf[1]) >= 0x40) || + (conv_ascii2bin(buf[2]) >= 0x40) || + (conv_ascii2bin(buf[3]) >= 0x40)) + return (-1); + buf += 4; + num += 1 + (buf[2] != '=') + (buf[3] != '='); + } + if ((i == 1) && (conv_ascii2bin(buf[0]) == B64_EOLN)) + return (num); + if ((i == 2) && (conv_ascii2bin(buf[0]) == B64_EOLN) && + (conv_ascii2bin(buf[0]) == B64_EOLN)) + return (num); + return (1); +} +#endif diff --git a/libs/openssl/crypto/evp/evp.h b/libs/openssl/crypto/evp/evp.h new file mode 100644 index 00000000..6cf98acc --- /dev/null +++ b/libs/openssl/crypto/evp/evp.h @@ -0,0 +1,1480 @@ +/* crypto/evp/evp.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_ENVELOPE_H +# define HEADER_ENVELOPE_H + +# ifdef OPENSSL_ALGORITHM_DEFINES +# include +# else +# define OPENSSL_ALGORITHM_DEFINES +# include +# undef OPENSSL_ALGORITHM_DEFINES +# endif + +# include + +# include + +# ifndef OPENSSL_NO_BIO +# include +# endif + +/*- +#define EVP_RC2_KEY_SIZE 16 +#define EVP_RC4_KEY_SIZE 16 +#define EVP_BLOWFISH_KEY_SIZE 16 +#define EVP_CAST5_KEY_SIZE 16 +#define EVP_RC5_32_12_16_KEY_SIZE 16 +*/ +# define EVP_MAX_MD_SIZE 64/* longest known is SHA512 */ +# define EVP_MAX_KEY_LENGTH 64 +# define EVP_MAX_IV_LENGTH 16 +# define EVP_MAX_BLOCK_LENGTH 32 + +# define PKCS5_SALT_LEN 8 +/* Default PKCS#5 iteration count */ +# define PKCS5_DEFAULT_ITER 2048 + +# include + +# define EVP_PK_RSA 0x0001 +# define EVP_PK_DSA 0x0002 +# define EVP_PK_DH 0x0004 +# define EVP_PK_EC 0x0008 +# define EVP_PKT_SIGN 0x0010 +# define EVP_PKT_ENC 0x0020 +# define EVP_PKT_EXCH 0x0040 +# define EVP_PKS_RSA 0x0100 +# define EVP_PKS_DSA 0x0200 +# define EVP_PKS_EC 0x0400 + +# define EVP_PKEY_NONE NID_undef +# define EVP_PKEY_RSA NID_rsaEncryption +# define EVP_PKEY_RSA2 NID_rsa +# define EVP_PKEY_DSA NID_dsa +# define EVP_PKEY_DSA1 NID_dsa_2 +# define EVP_PKEY_DSA2 NID_dsaWithSHA +# define EVP_PKEY_DSA3 NID_dsaWithSHA1 +# define EVP_PKEY_DSA4 NID_dsaWithSHA1_2 +# define EVP_PKEY_DH NID_dhKeyAgreement +# define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +# define EVP_PKEY_HMAC NID_hmac +# define EVP_PKEY_CMAC NID_cmac + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Type needs to be a bit field Sub-type needs to be for variations on the + * method, as in, can it do arbitrary encryption.... + */ +struct evp_pkey_st { + int type; + int save_type; + int references; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *engine; + union { + char *ptr; +# ifndef OPENSSL_NO_RSA + struct rsa_st *rsa; /* RSA */ +# endif +# ifndef OPENSSL_NO_DSA + struct dsa_st *dsa; /* DSA */ +# endif +# ifndef OPENSSL_NO_DH + struct dh_st *dh; /* DH */ +# endif +# ifndef OPENSSL_NO_EC + struct ec_key_st *ec; /* ECC */ +# endif + } pkey; + int save_parameters; + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ +} /* EVP_PKEY */ ; + +# define EVP_PKEY_MO_SIGN 0x0001 +# define EVP_PKEY_MO_VERIFY 0x0002 +# define EVP_PKEY_MO_ENCRYPT 0x0004 +# define EVP_PKEY_MO_DECRYPT 0x0008 + +# ifndef EVP_MD +struct env_md_st { + int type; + int pkey_type; + int md_size; + unsigned long flags; + int (*init) (EVP_MD_CTX *ctx); + int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); + int (*final) (EVP_MD_CTX *ctx, unsigned char *md); + int (*copy) (EVP_MD_CTX *to, const EVP_MD_CTX *from); + int (*cleanup) (EVP_MD_CTX *ctx); + /* FIXME: prototype these some day */ + int (*sign) (int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, void *key); + int (*verify) (int type, const unsigned char *m, unsigned int m_length, + const unsigned char *sigbuf, unsigned int siglen, + void *key); + int required_pkey_type[5]; /* EVP_PKEY_xxx */ + int block_size; + int ctx_size; /* how big does the ctx->md_data need to be */ + /* control function */ + int (*md_ctrl) (EVP_MD_CTX *ctx, int cmd, int p1, void *p2); +} /* EVP_MD */ ; + +typedef int evp_sign_method(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigret, + unsigned int *siglen, void *key); +typedef int evp_verify_method(int type, const unsigned char *m, + unsigned int m_length, + const unsigned char *sigbuf, + unsigned int siglen, void *key); + +/* digest can only handle a single block */ +# define EVP_MD_FLAG_ONESHOT 0x0001 + +/* + * digest is a "clone" digest used + * which is a copy of an existing + * one for a specific public key type. + * EVP_dss1() etc + */ +# define EVP_MD_FLAG_PKEY_DIGEST 0x0002 + +/* Digest uses EVP_PKEY_METHOD for signing instead of MD specific signing */ + +# define EVP_MD_FLAG_PKEY_METHOD_SIGNATURE 0x0004 + +/* DigestAlgorithmIdentifier flags... */ + +# define EVP_MD_FLAG_DIGALGID_MASK 0x0018 + +/* NULL or absent parameter accepted. Use NULL */ + +# define EVP_MD_FLAG_DIGALGID_NULL 0x0000 + +/* NULL or absent parameter accepted. Use NULL for PKCS#1 otherwise absent */ + +# define EVP_MD_FLAG_DIGALGID_ABSENT 0x0008 + +/* Custom handling via ctrl */ + +# define EVP_MD_FLAG_DIGALGID_CUSTOM 0x0018 + +/* Note if suitable for use in FIPS mode */ +# define EVP_MD_FLAG_FIPS 0x0400 + +/* Digest ctrls */ + +# define EVP_MD_CTRL_DIGALGID 0x1 +# define EVP_MD_CTRL_MICALG 0x2 + +/* Minimum Algorithm specific ctrl value */ + +# define EVP_MD_CTRL_ALG_CTRL 0x1000 + +# define EVP_PKEY_NULL_method NULL,NULL,{0,0,0,0} + +# ifndef OPENSSL_NO_DSA +# define EVP_PKEY_DSA_method (evp_sign_method *)DSA_sign, \ + (evp_verify_method *)DSA_verify, \ + {EVP_PKEY_DSA,EVP_PKEY_DSA2,EVP_PKEY_DSA3, \ + EVP_PKEY_DSA4,0} +# else +# define EVP_PKEY_DSA_method EVP_PKEY_NULL_method +# endif + +# ifndef OPENSSL_NO_ECDSA +# define EVP_PKEY_ECDSA_method (evp_sign_method *)ECDSA_sign, \ + (evp_verify_method *)ECDSA_verify, \ + {EVP_PKEY_EC,0,0,0} +# else +# define EVP_PKEY_ECDSA_method EVP_PKEY_NULL_method +# endif + +# ifndef OPENSSL_NO_RSA +# define EVP_PKEY_RSA_method (evp_sign_method *)RSA_sign, \ + (evp_verify_method *)RSA_verify, \ + {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0} +# define EVP_PKEY_RSA_ASN1_OCTET_STRING_method \ + (evp_sign_method *)RSA_sign_ASN1_OCTET_STRING, \ + (evp_verify_method *)RSA_verify_ASN1_OCTET_STRING, \ + {EVP_PKEY_RSA,EVP_PKEY_RSA2,0,0} +# else +# define EVP_PKEY_RSA_method EVP_PKEY_NULL_method +# define EVP_PKEY_RSA_ASN1_OCTET_STRING_method EVP_PKEY_NULL_method +# endif + +# endif /* !EVP_MD */ + +struct env_md_ctx_st { + const EVP_MD *digest; + ENGINE *engine; /* functional reference if 'digest' is + * ENGINE-provided */ + unsigned long flags; + void *md_data; + /* Public key context for sign/verify */ + EVP_PKEY_CTX *pctx; + /* Update function: usually copied from EVP_MD */ + int (*update) (EVP_MD_CTX *ctx, const void *data, size_t count); +} /* EVP_MD_CTX */ ; + +/* values for EVP_MD_CTX flags */ + +# define EVP_MD_CTX_FLAG_ONESHOT 0x0001/* digest update will be + * called once only */ +# define EVP_MD_CTX_FLAG_CLEANED 0x0002/* context has already been + * cleaned */ +# define EVP_MD_CTX_FLAG_REUSE 0x0004/* Don't free up ctx->md_data + * in EVP_MD_CTX_cleanup */ +/* + * FIPS and pad options are ignored in 1.0.0, definitions are here so we + * don't accidentally reuse the values for other purposes. + */ + +# define EVP_MD_CTX_FLAG_NON_FIPS_ALLOW 0x0008/* Allow use of non FIPS + * digest in FIPS mode */ + +/* + * The following PAD options are also currently ignored in 1.0.0, digest + * parameters are handled through EVP_DigestSign*() and EVP_DigestVerify*() + * instead. + */ +# define EVP_MD_CTX_FLAG_PAD_MASK 0xF0/* RSA mode to use */ +# define EVP_MD_CTX_FLAG_PAD_PKCS1 0x00/* PKCS#1 v1.5 mode */ +# define EVP_MD_CTX_FLAG_PAD_X931 0x10/* X9.31 mode */ +# define EVP_MD_CTX_FLAG_PAD_PSS 0x20/* PSS mode */ + +# define EVP_MD_CTX_FLAG_NO_INIT 0x0100/* Don't initialize md_data */ + +struct evp_cipher_st { + int nid; + int block_size; + /* Default value for variable length ciphers */ + int key_len; + int iv_len; + /* Various flags */ + unsigned long flags; + /* init key */ + int (*init) (EVP_CIPHER_CTX *ctx, const unsigned char *key, + const unsigned char *iv, int enc); + /* encrypt/decrypt data */ + int (*do_cipher) (EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, size_t inl); + /* cleanup ctx */ + int (*cleanup) (EVP_CIPHER_CTX *); + /* how big ctx->cipher_data needs to be */ + int ctx_size; + /* Populate a ASN1_TYPE with parameters */ + int (*set_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); + /* Get parameters from a ASN1_TYPE */ + int (*get_asn1_parameters) (EVP_CIPHER_CTX *, ASN1_TYPE *); + /* Miscellaneous operations */ + int (*ctrl) (EVP_CIPHER_CTX *, int type, int arg, void *ptr); + /* Application data */ + void *app_data; +} /* EVP_CIPHER */ ; + +/* Values for cipher flags */ + +/* Modes for ciphers */ + +# define EVP_CIPH_STREAM_CIPHER 0x0 +# define EVP_CIPH_ECB_MODE 0x1 +# define EVP_CIPH_CBC_MODE 0x2 +# define EVP_CIPH_CFB_MODE 0x3 +# define EVP_CIPH_OFB_MODE 0x4 +# define EVP_CIPH_CTR_MODE 0x5 +# define EVP_CIPH_GCM_MODE 0x6 +# define EVP_CIPH_CCM_MODE 0x7 +# define EVP_CIPH_XTS_MODE 0x10001 +# define EVP_CIPH_MODE 0xF0007 +/* Set if variable length cipher */ +# define EVP_CIPH_VARIABLE_LENGTH 0x8 +/* Set if the iv handling should be done by the cipher itself */ +# define EVP_CIPH_CUSTOM_IV 0x10 +/* Set if the cipher's init() function should be called if key is NULL */ +# define EVP_CIPH_ALWAYS_CALL_INIT 0x20 +/* Call ctrl() to init cipher parameters */ +# define EVP_CIPH_CTRL_INIT 0x40 +/* Don't use standard key length function */ +# define EVP_CIPH_CUSTOM_KEY_LENGTH 0x80 +/* Don't use standard block padding */ +# define EVP_CIPH_NO_PADDING 0x100 +/* cipher handles random key generation */ +# define EVP_CIPH_RAND_KEY 0x200 +/* cipher has its own additional copying logic */ +# define EVP_CIPH_CUSTOM_COPY 0x400 +/* Allow use default ASN1 get/set iv */ +# define EVP_CIPH_FLAG_DEFAULT_ASN1 0x1000 +/* Buffer length in bits not bytes: CFB1 mode only */ +# define EVP_CIPH_FLAG_LENGTH_BITS 0x2000 +/* Note if suitable for use in FIPS mode */ +# define EVP_CIPH_FLAG_FIPS 0x4000 +/* Allow non FIPS cipher in FIPS mode */ +# define EVP_CIPH_FLAG_NON_FIPS_ALLOW 0x8000 +/* + * Cipher handles any and all padding logic as well as finalisation. + */ +# define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x100000 +# define EVP_CIPH_FLAG_AEAD_CIPHER 0x200000 + +/* ctrl() values */ + +# define EVP_CTRL_INIT 0x0 +# define EVP_CTRL_SET_KEY_LENGTH 0x1 +# define EVP_CTRL_GET_RC2_KEY_BITS 0x2 +# define EVP_CTRL_SET_RC2_KEY_BITS 0x3 +# define EVP_CTRL_GET_RC5_ROUNDS 0x4 +# define EVP_CTRL_SET_RC5_ROUNDS 0x5 +# define EVP_CTRL_RAND_KEY 0x6 +# define EVP_CTRL_PBE_PRF_NID 0x7 +# define EVP_CTRL_COPY 0x8 +# define EVP_CTRL_GCM_SET_IVLEN 0x9 +# define EVP_CTRL_GCM_GET_TAG 0x10 +# define EVP_CTRL_GCM_SET_TAG 0x11 +# define EVP_CTRL_GCM_SET_IV_FIXED 0x12 +# define EVP_CTRL_GCM_IV_GEN 0x13 +# define EVP_CTRL_CCM_SET_IVLEN EVP_CTRL_GCM_SET_IVLEN +# define EVP_CTRL_CCM_GET_TAG EVP_CTRL_GCM_GET_TAG +# define EVP_CTRL_CCM_SET_TAG EVP_CTRL_GCM_SET_TAG +# define EVP_CTRL_CCM_SET_L 0x14 +# define EVP_CTRL_CCM_SET_MSGLEN 0x15 +/* + * AEAD cipher deduces payload length and returns number of bytes required to + * store MAC and eventual padding. Subsequent call to EVP_Cipher even + * appends/verifies MAC. + */ +# define EVP_CTRL_AEAD_TLS1_AAD 0x16 +/* Used by composite AEAD ciphers, no-op in GCM, CCM... */ +# define EVP_CTRL_AEAD_SET_MAC_KEY 0x17 +/* Set the GCM invocation field, decrypt only */ +# define EVP_CTRL_GCM_SET_IV_INV 0x18 + +/* RFC 5246 defines additional data to be 13 bytes in length */ +# define EVP_AEAD_TLS1_AAD_LEN 13 + +/* GCM TLS constants */ +/* Length of fixed part of IV derived from PRF */ +# define EVP_GCM_TLS_FIXED_IV_LEN 4 +/* Length of explicit part of IV part of TLS records */ +# define EVP_GCM_TLS_EXPLICIT_IV_LEN 8 +/* Length of tag for TLS */ +# define EVP_GCM_TLS_TAG_LEN 16 + +typedef struct evp_cipher_info_st { + const EVP_CIPHER *cipher; + unsigned char iv[EVP_MAX_IV_LENGTH]; +} EVP_CIPHER_INFO; + +struct evp_cipher_ctx_st { + const EVP_CIPHER *cipher; + ENGINE *engine; /* functional reference if 'cipher' is + * ENGINE-provided */ + int encrypt; /* encrypt or decrypt */ + int buf_len; /* number we have left */ + unsigned char oiv[EVP_MAX_IV_LENGTH]; /* original iv */ + unsigned char iv[EVP_MAX_IV_LENGTH]; /* working iv */ + unsigned char buf[EVP_MAX_BLOCK_LENGTH]; /* saved partial block */ + int num; /* used by cfb/ofb/ctr mode */ + void *app_data; /* application stuff */ + int key_len; /* May change for variable length cipher */ + unsigned long flags; /* Various flags */ + void *cipher_data; /* per EVP data */ + int final_used; + int block_mask; + unsigned char final[EVP_MAX_BLOCK_LENGTH]; /* possible final block */ +} /* EVP_CIPHER_CTX */ ; + +typedef struct evp_Encode_Ctx_st { + /* number saved in a partial encode/decode */ + int num; + /* + * The length is either the output line length (in input bytes) or the + * shortest input line length that is ok. Once decoding begins, the + * length is adjusted up each time a longer line is decoded + */ + int length; + /* data to encode */ + unsigned char enc_data[80]; + /* number read on current line */ + int line_num; + int expect_nl; +} EVP_ENCODE_CTX; + +/* Password based encryption function */ +typedef int (EVP_PBE_KEYGEN) (EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *cipher, const EVP_MD *md, + int en_de); + +# ifndef OPENSSL_NO_RSA +# define EVP_PKEY_assign_RSA(pkey,rsa) EVP_PKEY_assign((pkey),EVP_PKEY_RSA,\ + (char *)(rsa)) +# endif + +# ifndef OPENSSL_NO_DSA +# define EVP_PKEY_assign_DSA(pkey,dsa) EVP_PKEY_assign((pkey),EVP_PKEY_DSA,\ + (char *)(dsa)) +# endif + +# ifndef OPENSSL_NO_DH +# define EVP_PKEY_assign_DH(pkey,dh) EVP_PKEY_assign((pkey),EVP_PKEY_DH,\ + (char *)(dh)) +# endif + +# ifndef OPENSSL_NO_EC +# define EVP_PKEY_assign_EC_KEY(pkey,eckey) EVP_PKEY_assign((pkey),EVP_PKEY_EC,\ + (char *)(eckey)) +# endif + +/* Add some extra combinations */ +# define EVP_get_digestbynid(a) EVP_get_digestbyname(OBJ_nid2sn(a)) +# define EVP_get_digestbyobj(a) EVP_get_digestbynid(OBJ_obj2nid(a)) +# define EVP_get_cipherbynid(a) EVP_get_cipherbyname(OBJ_nid2sn(a)) +# define EVP_get_cipherbyobj(a) EVP_get_cipherbynid(OBJ_obj2nid(a)) + +int EVP_MD_type(const EVP_MD *md); +# define EVP_MD_nid(e) EVP_MD_type(e) +# define EVP_MD_name(e) OBJ_nid2sn(EVP_MD_nid(e)) +int EVP_MD_pkey_type(const EVP_MD *md); +int EVP_MD_size(const EVP_MD *md); +int EVP_MD_block_size(const EVP_MD *md); +unsigned long EVP_MD_flags(const EVP_MD *md); + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); +# define EVP_MD_CTX_size(e) EVP_MD_size(EVP_MD_CTX_md(e)) +# define EVP_MD_CTX_block_size(e) EVP_MD_block_size(EVP_MD_CTX_md(e)) +# define EVP_MD_CTX_type(e) EVP_MD_type(EVP_MD_CTX_md(e)) + +int EVP_CIPHER_nid(const EVP_CIPHER *cipher); +# define EVP_CIPHER_name(e) OBJ_nid2sn(EVP_CIPHER_nid(e)) +int EVP_CIPHER_block_size(const EVP_CIPHER *cipher); +int EVP_CIPHER_key_length(const EVP_CIPHER *cipher); +int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); +unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher); +# define EVP_CIPHER_mode(e) (EVP_CIPHER_flags(e) & EVP_CIPH_MODE) + +const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in); +void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); +void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data); +# define EVP_CIPHER_CTX_type(c) EVP_CIPHER_type(EVP_CIPHER_CTX_cipher(c)) +unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx); +# define EVP_CIPHER_CTX_mode(e) (EVP_CIPHER_CTX_flags(e) & EVP_CIPH_MODE) + +# define EVP_ENCODE_LENGTH(l) (((l+2)/3*4)+(l/48+1)*2+80) +# define EVP_DECODE_LENGTH(l) ((l+3)/4*3+80) + +# define EVP_SignInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +# define EVP_SignInit(a,b) EVP_DigestInit(a,b) +# define EVP_SignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_VerifyInit_ex(a,b,c) EVP_DigestInit_ex(a,b,c) +# define EVP_VerifyInit(a,b) EVP_DigestInit(a,b) +# define EVP_VerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_OpenUpdate(a,b,c,d,e) EVP_DecryptUpdate(a,b,c,d,e) +# define EVP_SealUpdate(a,b,c,d,e) EVP_EncryptUpdate(a,b,c,d,e) +# define EVP_DigestSignUpdate(a,b,c) EVP_DigestUpdate(a,b,c) +# define EVP_DigestVerifyUpdate(a,b,c) EVP_DigestUpdate(a,b,c) + +# ifdef CONST_STRICT +void BIO_set_md(BIO *, const EVP_MD *md); +# else +# define BIO_set_md(b,md) BIO_ctrl(b,BIO_C_SET_MD,0,(char *)md) +# endif +# define BIO_get_md(b,mdp) BIO_ctrl(b,BIO_C_GET_MD,0,(char *)mdp) +# define BIO_get_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_GET_MD_CTX,0,(char *)mdcp) +# define BIO_set_md_ctx(b,mdcp) BIO_ctrl(b,BIO_C_SET_MD_CTX,0,(char *)mdcp) +# define BIO_get_cipher_status(b) BIO_ctrl(b,BIO_C_GET_CIPHER_STATUS,0,NULL) +# define BIO_get_cipher_ctx(b,c_pp) BIO_ctrl(b,BIO_C_GET_CIPHER_CTX,0,(char *)c_pp) + +int EVP_Cipher(EVP_CIPHER_CTX *c, + unsigned char *out, const unsigned char *in, unsigned int inl); + +# define EVP_add_cipher_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS,(n)) +# define EVP_add_digest_alias(n,alias) \ + OBJ_NAME_add((alias),OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS,(n)) +# define EVP_delete_cipher_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_CIPHER_METH|OBJ_NAME_ALIAS); +# define EVP_delete_digest_alias(alias) \ + OBJ_NAME_remove(alias,OBJ_NAME_TYPE_MD_METH|OBJ_NAME_ALIAS); + +void EVP_MD_CTX_init(EVP_MD_CTX *ctx); +int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); +EVP_MD_CTX *EVP_MD_CTX_create(void); +void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); +int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in); +void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags); +void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags); +int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags); +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl); +int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *d, size_t cnt); +int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); +int EVP_Digest(const void *data, size_t count, + unsigned char *md, unsigned int *size, const EVP_MD *type, + ENGINE *impl); + +int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); +int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); +int EVP_DigestFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s); + +int EVP_read_pw_string(char *buf, int length, const char *prompt, int verify); +int EVP_read_pw_string_min(char *buf, int minlen, int maxlen, + const char *prompt, int verify); +void EVP_set_pw_prompt(const char *prompt); +char *EVP_get_pw_prompt(void); + +int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const unsigned char *salt, const unsigned char *data, + int datal, int count, unsigned char *key, + unsigned char *iv); + +void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags); +void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags); +int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags); + +int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv); +int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); +int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv); +int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv); +int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); + +int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, + int enc); +int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv, int enc); +int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); +int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *outm, int *outl); + +int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *md, unsigned int *s, + EVP_PKEY *pkey); + +int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey); + +int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int EVP_DigestSignFinal(EVP_MD_CTX *ctx, + unsigned char *sigret, size_t *siglen); + +int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey); +int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen); + +int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + const unsigned char *ek, int ekl, const unsigned char *iv, + EVP_PKEY *priv); +int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + unsigned char **ek, int *ekl, unsigned char *iv, + EVP_PKEY **pubk, int npubk); +int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl); + +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx); +void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl); +int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx); +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl); +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned + char *out, int *outl); +int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n); + +void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *a); +int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *a); +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *a); +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *x, int keylen); +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *c, int pad); +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr); +int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key); + +# ifndef OPENSSL_NO_BIO +BIO_METHOD *BIO_f_md(void); +BIO_METHOD *BIO_f_base64(void); +BIO_METHOD *BIO_f_cipher(void); +BIO_METHOD *BIO_f_reliable(void); +void BIO_set_cipher(BIO *b, const EVP_CIPHER *c, const unsigned char *k, + const unsigned char *i, int enc); +# endif + +const EVP_MD *EVP_md_null(void); +# ifndef OPENSSL_NO_MD2 +const EVP_MD *EVP_md2(void); +# endif +# ifndef OPENSSL_NO_MD4 +const EVP_MD *EVP_md4(void); +# endif +# ifndef OPENSSL_NO_MD5 +const EVP_MD *EVP_md5(void); +# endif +# ifndef OPENSSL_NO_SHA +const EVP_MD *EVP_sha(void); +const EVP_MD *EVP_sha1(void); +const EVP_MD *EVP_dss(void); +const EVP_MD *EVP_dss1(void); +const EVP_MD *EVP_ecdsa(void); +# endif +# ifndef OPENSSL_NO_SHA256 +const EVP_MD *EVP_sha224(void); +const EVP_MD *EVP_sha256(void); +# endif +# ifndef OPENSSL_NO_SHA512 +const EVP_MD *EVP_sha384(void); +const EVP_MD *EVP_sha512(void); +# endif +# ifndef OPENSSL_NO_MDC2 +const EVP_MD *EVP_mdc2(void); +# endif +# ifndef OPENSSL_NO_RIPEMD +const EVP_MD *EVP_ripemd160(void); +# endif +# ifndef OPENSSL_NO_WHIRLPOOL +const EVP_MD *EVP_whirlpool(void); +# endif +const EVP_CIPHER *EVP_enc_null(void); /* does nothing :-) */ +# ifndef OPENSSL_NO_DES +const EVP_CIPHER *EVP_des_ecb(void); +const EVP_CIPHER *EVP_des_ede(void); +const EVP_CIPHER *EVP_des_ede3(void); +const EVP_CIPHER *EVP_des_ede_ecb(void); +const EVP_CIPHER *EVP_des_ede3_ecb(void); +const EVP_CIPHER *EVP_des_cfb64(void); +# define EVP_des_cfb EVP_des_cfb64 +const EVP_CIPHER *EVP_des_cfb1(void); +const EVP_CIPHER *EVP_des_cfb8(void); +const EVP_CIPHER *EVP_des_ede_cfb64(void); +# define EVP_des_ede_cfb EVP_des_ede_cfb64 +# if 0 +const EVP_CIPHER *EVP_des_ede_cfb1(void); +const EVP_CIPHER *EVP_des_ede_cfb8(void); +# endif +const EVP_CIPHER *EVP_des_ede3_cfb64(void); +# define EVP_des_ede3_cfb EVP_des_ede3_cfb64 +const EVP_CIPHER *EVP_des_ede3_cfb1(void); +const EVP_CIPHER *EVP_des_ede3_cfb8(void); +const EVP_CIPHER *EVP_des_ofb(void); +const EVP_CIPHER *EVP_des_ede_ofb(void); +const EVP_CIPHER *EVP_des_ede3_ofb(void); +const EVP_CIPHER *EVP_des_cbc(void); +const EVP_CIPHER *EVP_des_ede_cbc(void); +const EVP_CIPHER *EVP_des_ede3_cbc(void); +const EVP_CIPHER *EVP_desx_cbc(void); +/* + * This should now be supported through the dev_crypto ENGINE. But also, why + * are rc4 and md5 declarations made here inside a "NO_DES" precompiler + * branch? + */ +# if 0 +# ifdef OPENSSL_OPENBSD_DEV_CRYPTO +const EVP_CIPHER *EVP_dev_crypto_des_ede3_cbc(void); +const EVP_CIPHER *EVP_dev_crypto_rc4(void); +const EVP_MD *EVP_dev_crypto_md5(void); +# endif +# endif +# endif +# ifndef OPENSSL_NO_RC4 +const EVP_CIPHER *EVP_rc4(void); +const EVP_CIPHER *EVP_rc4_40(void); +# ifndef OPENSSL_NO_MD5 +const EVP_CIPHER *EVP_rc4_hmac_md5(void); +# endif +# endif +# ifndef OPENSSL_NO_IDEA +const EVP_CIPHER *EVP_idea_ecb(void); +const EVP_CIPHER *EVP_idea_cfb64(void); +# define EVP_idea_cfb EVP_idea_cfb64 +const EVP_CIPHER *EVP_idea_ofb(void); +const EVP_CIPHER *EVP_idea_cbc(void); +# endif +# ifndef OPENSSL_NO_RC2 +const EVP_CIPHER *EVP_rc2_ecb(void); +const EVP_CIPHER *EVP_rc2_cbc(void); +const EVP_CIPHER *EVP_rc2_40_cbc(void); +const EVP_CIPHER *EVP_rc2_64_cbc(void); +const EVP_CIPHER *EVP_rc2_cfb64(void); +# define EVP_rc2_cfb EVP_rc2_cfb64 +const EVP_CIPHER *EVP_rc2_ofb(void); +# endif +# ifndef OPENSSL_NO_BF +const EVP_CIPHER *EVP_bf_ecb(void); +const EVP_CIPHER *EVP_bf_cbc(void); +const EVP_CIPHER *EVP_bf_cfb64(void); +# define EVP_bf_cfb EVP_bf_cfb64 +const EVP_CIPHER *EVP_bf_ofb(void); +# endif +# ifndef OPENSSL_NO_CAST +const EVP_CIPHER *EVP_cast5_ecb(void); +const EVP_CIPHER *EVP_cast5_cbc(void); +const EVP_CIPHER *EVP_cast5_cfb64(void); +# define EVP_cast5_cfb EVP_cast5_cfb64 +const EVP_CIPHER *EVP_cast5_ofb(void); +# endif +# ifndef OPENSSL_NO_RC5 +const EVP_CIPHER *EVP_rc5_32_12_16_cbc(void); +const EVP_CIPHER *EVP_rc5_32_12_16_ecb(void); +const EVP_CIPHER *EVP_rc5_32_12_16_cfb64(void); +# define EVP_rc5_32_12_16_cfb EVP_rc5_32_12_16_cfb64 +const EVP_CIPHER *EVP_rc5_32_12_16_ofb(void); +# endif +# ifndef OPENSSL_NO_AES +const EVP_CIPHER *EVP_aes_128_ecb(void); +const EVP_CIPHER *EVP_aes_128_cbc(void); +const EVP_CIPHER *EVP_aes_128_cfb1(void); +const EVP_CIPHER *EVP_aes_128_cfb8(void); +const EVP_CIPHER *EVP_aes_128_cfb128(void); +# define EVP_aes_128_cfb EVP_aes_128_cfb128 +const EVP_CIPHER *EVP_aes_128_ofb(void); +const EVP_CIPHER *EVP_aes_128_ctr(void); +const EVP_CIPHER *EVP_aes_128_ccm(void); +const EVP_CIPHER *EVP_aes_128_gcm(void); +const EVP_CIPHER *EVP_aes_128_xts(void); +const EVP_CIPHER *EVP_aes_192_ecb(void); +const EVP_CIPHER *EVP_aes_192_cbc(void); +const EVP_CIPHER *EVP_aes_192_cfb1(void); +const EVP_CIPHER *EVP_aes_192_cfb8(void); +const EVP_CIPHER *EVP_aes_192_cfb128(void); +# define EVP_aes_192_cfb EVP_aes_192_cfb128 +const EVP_CIPHER *EVP_aes_192_ofb(void); +const EVP_CIPHER *EVP_aes_192_ctr(void); +const EVP_CIPHER *EVP_aes_192_ccm(void); +const EVP_CIPHER *EVP_aes_192_gcm(void); +const EVP_CIPHER *EVP_aes_256_ecb(void); +const EVP_CIPHER *EVP_aes_256_cbc(void); +const EVP_CIPHER *EVP_aes_256_cfb1(void); +const EVP_CIPHER *EVP_aes_256_cfb8(void); +const EVP_CIPHER *EVP_aes_256_cfb128(void); +# define EVP_aes_256_cfb EVP_aes_256_cfb128 +const EVP_CIPHER *EVP_aes_256_ofb(void); +const EVP_CIPHER *EVP_aes_256_ctr(void); +const EVP_CIPHER *EVP_aes_256_ccm(void); +const EVP_CIPHER *EVP_aes_256_gcm(void); +const EVP_CIPHER *EVP_aes_256_xts(void); +# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) +const EVP_CIPHER *EVP_aes_128_cbc_hmac_sha1(void); +const EVP_CIPHER *EVP_aes_256_cbc_hmac_sha1(void); +# endif +# endif +# ifndef OPENSSL_NO_CAMELLIA +const EVP_CIPHER *EVP_camellia_128_ecb(void); +const EVP_CIPHER *EVP_camellia_128_cbc(void); +const EVP_CIPHER *EVP_camellia_128_cfb1(void); +const EVP_CIPHER *EVP_camellia_128_cfb8(void); +const EVP_CIPHER *EVP_camellia_128_cfb128(void); +# define EVP_camellia_128_cfb EVP_camellia_128_cfb128 +const EVP_CIPHER *EVP_camellia_128_ofb(void); +const EVP_CIPHER *EVP_camellia_192_ecb(void); +const EVP_CIPHER *EVP_camellia_192_cbc(void); +const EVP_CIPHER *EVP_camellia_192_cfb1(void); +const EVP_CIPHER *EVP_camellia_192_cfb8(void); +const EVP_CIPHER *EVP_camellia_192_cfb128(void); +# define EVP_camellia_192_cfb EVP_camellia_192_cfb128 +const EVP_CIPHER *EVP_camellia_192_ofb(void); +const EVP_CIPHER *EVP_camellia_256_ecb(void); +const EVP_CIPHER *EVP_camellia_256_cbc(void); +const EVP_CIPHER *EVP_camellia_256_cfb1(void); +const EVP_CIPHER *EVP_camellia_256_cfb8(void); +const EVP_CIPHER *EVP_camellia_256_cfb128(void); +# define EVP_camellia_256_cfb EVP_camellia_256_cfb128 +const EVP_CIPHER *EVP_camellia_256_ofb(void); +# endif + +# ifndef OPENSSL_NO_SEED +const EVP_CIPHER *EVP_seed_ecb(void); +const EVP_CIPHER *EVP_seed_cbc(void); +const EVP_CIPHER *EVP_seed_cfb128(void); +# define EVP_seed_cfb EVP_seed_cfb128 +const EVP_CIPHER *EVP_seed_ofb(void); +# endif + +void OPENSSL_add_all_algorithms_noconf(void); +void OPENSSL_add_all_algorithms_conf(void); + +# ifdef OPENSSL_LOAD_CONF +# define OpenSSL_add_all_algorithms() \ + OPENSSL_add_all_algorithms_conf() +# else +# define OpenSSL_add_all_algorithms() \ + OPENSSL_add_all_algorithms_noconf() +# endif + +void OpenSSL_add_all_ciphers(void); +void OpenSSL_add_all_digests(void); +# define SSLeay_add_all_algorithms() OpenSSL_add_all_algorithms() +# define SSLeay_add_all_ciphers() OpenSSL_add_all_ciphers() +# define SSLeay_add_all_digests() OpenSSL_add_all_digests() + +int EVP_add_cipher(const EVP_CIPHER *cipher); +int EVP_add_digest(const EVP_MD *digest); + +const EVP_CIPHER *EVP_get_cipherbyname(const char *name); +const EVP_MD *EVP_get_digestbyname(const char *name); +void EVP_cleanup(void); + +void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), + void *arg); +void EVP_CIPHER_do_all_sorted(void (*fn) + (const EVP_CIPHER *ciph, const char *from, + const char *to, void *x), void *arg); + +void EVP_MD_do_all(void (*fn) (const EVP_MD *ciph, + const char *from, const char *to, void *x), + void *arg); +void EVP_MD_do_all_sorted(void (*fn) + (const EVP_MD *ciph, const char *from, + const char *to, void *x), void *arg); + +int EVP_PKEY_decrypt_old(unsigned char *dec_key, + const unsigned char *enc_key, int enc_key_len, + EVP_PKEY *private_key); +int EVP_PKEY_encrypt_old(unsigned char *enc_key, + const unsigned char *key, int key_len, + EVP_PKEY *pub_key); +int EVP_PKEY_type(int type); +int EVP_PKEY_id(const EVP_PKEY *pkey); +int EVP_PKEY_base_id(const EVP_PKEY *pkey); +int EVP_PKEY_bits(EVP_PKEY *pkey); +int EVP_PKEY_size(EVP_PKEY *pkey); +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len); +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); +void *EVP_PKEY_get0(EVP_PKEY *pkey); + +# ifndef OPENSSL_NO_RSA +struct rsa_st; +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, struct rsa_st *key); +struct rsa_st *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_DSA +struct dsa_st; +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, struct dsa_st *key); +struct dsa_st *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_DH +struct dh_st; +int EVP_PKEY_set1_DH(EVP_PKEY *pkey, struct dh_st *key); +struct dh_st *EVP_PKEY_get1_DH(EVP_PKEY *pkey); +# endif +# ifndef OPENSSL_NO_EC +struct ec_key_st; +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, struct ec_key_st *key); +struct ec_key_st *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); +# endif + +EVP_PKEY *EVP_PKEY_new(void); +void EVP_PKEY_free(EVP_PKEY *pkey); + +EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp); + +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp, + long length); +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp, + long length); +int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp); + +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); +int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); +int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode); +int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid); + +int EVP_CIPHER_type(const EVP_CIPHER *ctx); + +/* calls methods */ +int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* These are used by EVP_CIPHER methods */ +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type); + +/* PKCS5 password based encryption */ +int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de); +int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + int keylen, unsigned char *out); +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, int keylen, unsigned char *out); +int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de); + +void PKCS5_PBE_add(void); + +int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de); + +/* PBE type */ + +/* Can appear as the outermost AlgorithmIdentifier */ +# define EVP_PBE_TYPE_OUTER 0x0 +/* Is an PRF type OID */ +# define EVP_PBE_TYPE_PRF 0x1 + +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, + int md_nid, EVP_PBE_KEYGEN *keygen); +int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, + EVP_PBE_KEYGEN *keygen); +int EVP_PBE_find(int type, int pbe_nid, int *pcnid, int *pmnid, + EVP_PBE_KEYGEN **pkeygen); +void EVP_PBE_cleanup(void); + +# define ASN1_PKEY_ALIAS 0x1 +# define ASN1_PKEY_DYNAMIC 0x2 +# define ASN1_PKEY_SIGPARAM_NULL 0x4 + +# define ASN1_PKEY_CTRL_PKCS7_SIGN 0x1 +# define ASN1_PKEY_CTRL_PKCS7_ENCRYPT 0x2 +# define ASN1_PKEY_CTRL_DEFAULT_MD_NID 0x3 +# define ASN1_PKEY_CTRL_CMS_SIGN 0x5 +# define ASN1_PKEY_CTRL_CMS_ENVELOPE 0x7 + +int EVP_PKEY_asn1_get_count(void); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type); +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe, + const char *str, int len); +int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth); +int EVP_PKEY_asn1_add_alias(int to, int from); +int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *pkey_base_id, + int *ppkey_flags, const char **pinfo, + const char **ppem_str, + const EVP_PKEY_ASN1_METHOD *ameth); + +const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey); +EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags, + const char *pem_str, + const char *info); +void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst, + const EVP_PKEY_ASN1_METHOD *src); +void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth); +void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth, + int (*pub_decode) (EVP_PKEY *pk, + X509_PUBKEY *pub), + int (*pub_encode) (X509_PUBKEY *pub, + const EVP_PKEY *pk), + int (*pub_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*pub_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx), + int (*pkey_size) (const EVP_PKEY *pk), + int (*pkey_bits) (const EVP_PKEY *pk)); +void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth, + int (*priv_decode) (EVP_PKEY *pk, + PKCS8_PRIV_KEY_INFO + *p8inf), + int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, + const EVP_PKEY *pk), + int (*priv_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)); +void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth, + int (*param_decode) (EVP_PKEY *pkey, + const unsigned char **pder, + int derlen), + int (*param_encode) (const EVP_PKEY *pkey, + unsigned char **pder), + int (*param_missing) (const EVP_PKEY *pk), + int (*param_copy) (EVP_PKEY *to, + const EVP_PKEY *from), + int (*param_cmp) (const EVP_PKEY *a, + const EVP_PKEY *b), + int (*param_print) (BIO *out, + const EVP_PKEY *pkey, + int indent, + ASN1_PCTX *pctx)); + +void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth, + void (*pkey_free) (EVP_PKEY *pkey)); +void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth, + int (*pkey_ctrl) (EVP_PKEY *pkey, int op, + long arg1, void *arg2)); + +# define EVP_PKEY_OP_UNDEFINED 0 +# define EVP_PKEY_OP_PARAMGEN (1<<1) +# define EVP_PKEY_OP_KEYGEN (1<<2) +# define EVP_PKEY_OP_SIGN (1<<3) +# define EVP_PKEY_OP_VERIFY (1<<4) +# define EVP_PKEY_OP_VERIFYRECOVER (1<<5) +# define EVP_PKEY_OP_SIGNCTX (1<<6) +# define EVP_PKEY_OP_VERIFYCTX (1<<7) +# define EVP_PKEY_OP_ENCRYPT (1<<8) +# define EVP_PKEY_OP_DECRYPT (1<<9) +# define EVP_PKEY_OP_DERIVE (1<<10) + +# define EVP_PKEY_OP_TYPE_SIG \ + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER \ + | EVP_PKEY_OP_SIGNCTX | EVP_PKEY_OP_VERIFYCTX) + +# define EVP_PKEY_OP_TYPE_CRYPT \ + (EVP_PKEY_OP_ENCRYPT | EVP_PKEY_OP_DECRYPT) + +# define EVP_PKEY_OP_TYPE_NOGEN \ + (EVP_PKEY_OP_SIG | EVP_PKEY_OP_CRYPT | EVP_PKEY_OP_DERIVE) + +# define EVP_PKEY_OP_TYPE_GEN \ + (EVP_PKEY_OP_PARAMGEN | EVP_PKEY_OP_KEYGEN) + +# define EVP_PKEY_CTX_set_signature_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_MD, 0, (void *)md) + +# define EVP_PKEY_CTRL_MD 1 +# define EVP_PKEY_CTRL_PEER_KEY 2 + +# define EVP_PKEY_CTRL_PKCS7_ENCRYPT 3 +# define EVP_PKEY_CTRL_PKCS7_DECRYPT 4 + +# define EVP_PKEY_CTRL_PKCS7_SIGN 5 + +# define EVP_PKEY_CTRL_SET_MAC_KEY 6 + +# define EVP_PKEY_CTRL_DIGESTINIT 7 + +/* Used by GOST key encryption in TLS */ +# define EVP_PKEY_CTRL_SET_IV 8 + +# define EVP_PKEY_CTRL_CMS_ENCRYPT 9 +# define EVP_PKEY_CTRL_CMS_DECRYPT 10 +# define EVP_PKEY_CTRL_CMS_SIGN 11 + +# define EVP_PKEY_CTRL_CIPHER 12 + +# define EVP_PKEY_ALG_CTRL 0x1000 + +# define EVP_PKEY_FLAG_AUTOARGLEN 2 +/* + * Method handles all operations: don't assume any digest related defaults. + */ +# define EVP_PKEY_FLAG_SIGCTX_CUSTOM 4 + +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type); +EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags); +void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, + const EVP_PKEY_METHOD *meth); +void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src); +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth); +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth); + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2); +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, const char *type, + const char *value); + +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx); +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen); + +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, + const unsigned char *key, int keylen); + +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx); +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); + +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx); + +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data); +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + +typedef int EVP_PKEY_gen_cb (EVP_PKEY_CTX *ctx); + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); + +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb); +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx); + +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx); + +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)); + +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup) (EVP_PKEY_CTX *ctx)); + +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init) (EVP_PKEY_CTX *ctx), + int (*paramgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init) (EVP_PKEY_CTX *ctx), + int (*keygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)); + +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + int (*sign_init) (EVP_PKEY_CTX *ctx), + int (*sign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + int (*verify_init) (EVP_PKEY_CTX *ctx), + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init) (EVP_PKEY_CTX + *ctx), + int (*verify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)); + +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + int (*signctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*signctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*verifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)); + +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init) (EVP_PKEY_CTX *ctx), + int (*encryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + int (*decrypt_init) (EVP_PKEY_CTX *ctx), + int (*decrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)); + +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init) (EVP_PKEY_CTX *ctx), + int (*derive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)); + +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (*ctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)); + +void EVP_add_alg_module(void); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_EVP_strings(void); + +/* Error codes for the EVP functions. */ + +/* Function codes. */ +# define EVP_F_AESNI_INIT_KEY 165 +# define EVP_F_AESNI_XTS_CIPHER 176 +# define EVP_F_AES_INIT_KEY 133 +# define EVP_F_AES_XTS 172 +# define EVP_F_AES_XTS_CIPHER 175 +# define EVP_F_ALG_MODULE_INIT 177 +# define EVP_F_CAMELLIA_INIT_KEY 159 +# define EVP_F_CMAC_INIT 173 +# define EVP_F_D2I_PKEY 100 +# define EVP_F_DO_SIGVER_INIT 161 +# define EVP_F_DSAPKEY2PKCS8 134 +# define EVP_F_DSA_PKEY2PKCS8 135 +# define EVP_F_ECDSA_PKEY2PKCS8 129 +# define EVP_F_ECKEY_PKEY2PKCS8 132 +# define EVP_F_EVP_CIPHERINIT_EX 123 +# define EVP_F_EVP_CIPHER_CTX_COPY 163 +# define EVP_F_EVP_CIPHER_CTX_CTRL 124 +# define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122 +# define EVP_F_EVP_DECRYPTFINAL_EX 101 +# define EVP_F_EVP_DIGESTINIT_EX 128 +# define EVP_F_EVP_ENCRYPTFINAL_EX 127 +# define EVP_F_EVP_MD_CTX_COPY_EX 110 +# define EVP_F_EVP_MD_SIZE 162 +# define EVP_F_EVP_OPENINIT 102 +# define EVP_F_EVP_PBE_ALG_ADD 115 +# define EVP_F_EVP_PBE_ALG_ADD_TYPE 160 +# define EVP_F_EVP_PBE_CIPHERINIT 116 +# define EVP_F_EVP_PKCS82PKEY 111 +# define EVP_F_EVP_PKCS82PKEY_BROKEN 136 +# define EVP_F_EVP_PKEY2PKCS8_BROKEN 113 +# define EVP_F_EVP_PKEY_COPY_PARAMETERS 103 +# define EVP_F_EVP_PKEY_CTX_CTRL 137 +# define EVP_F_EVP_PKEY_CTX_CTRL_STR 150 +# define EVP_F_EVP_PKEY_CTX_DUP 156 +# define EVP_F_EVP_PKEY_DECRYPT 104 +# define EVP_F_EVP_PKEY_DECRYPT_INIT 138 +# define EVP_F_EVP_PKEY_DECRYPT_OLD 151 +# define EVP_F_EVP_PKEY_DERIVE 153 +# define EVP_F_EVP_PKEY_DERIVE_INIT 154 +# define EVP_F_EVP_PKEY_DERIVE_SET_PEER 155 +# define EVP_F_EVP_PKEY_ENCRYPT 105 +# define EVP_F_EVP_PKEY_ENCRYPT_INIT 139 +# define EVP_F_EVP_PKEY_ENCRYPT_OLD 152 +# define EVP_F_EVP_PKEY_GET1_DH 119 +# define EVP_F_EVP_PKEY_GET1_DSA 120 +# define EVP_F_EVP_PKEY_GET1_ECDSA 130 +# define EVP_F_EVP_PKEY_GET1_EC_KEY 131 +# define EVP_F_EVP_PKEY_GET1_RSA 121 +# define EVP_F_EVP_PKEY_KEYGEN 146 +# define EVP_F_EVP_PKEY_KEYGEN_INIT 147 +# define EVP_F_EVP_PKEY_NEW 106 +# define EVP_F_EVP_PKEY_PARAMGEN 148 +# define EVP_F_EVP_PKEY_PARAMGEN_INIT 149 +# define EVP_F_EVP_PKEY_SIGN 140 +# define EVP_F_EVP_PKEY_SIGN_INIT 141 +# define EVP_F_EVP_PKEY_VERIFY 142 +# define EVP_F_EVP_PKEY_VERIFY_INIT 143 +# define EVP_F_EVP_PKEY_VERIFY_RECOVER 144 +# define EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT 145 +# define EVP_F_EVP_RIJNDAEL 126 +# define EVP_F_EVP_SIGNFINAL 107 +# define EVP_F_EVP_VERIFYFINAL 108 +# define EVP_F_FIPS_CIPHERINIT 166 +# define EVP_F_FIPS_CIPHER_CTX_COPY 170 +# define EVP_F_FIPS_CIPHER_CTX_CTRL 167 +# define EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH 171 +# define EVP_F_FIPS_DIGESTINIT 168 +# define EVP_F_FIPS_MD_CTX_COPY 169 +# define EVP_F_HMAC_INIT_EX 174 +# define EVP_F_INT_CTX_NEW 157 +# define EVP_F_PKCS5_PBE_KEYIVGEN 117 +# define EVP_F_PKCS5_V2_PBE_KEYIVGEN 118 +# define EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN 164 +# define EVP_F_PKCS8_SET_BROKEN 112 +# define EVP_F_PKEY_SET_TYPE 158 +# define EVP_F_RC2_MAGIC_TO_METH 109 +# define EVP_F_RC5_CTRL 125 + +/* Reason codes. */ +# define EVP_R_AES_IV_SETUP_FAILED 162 +# define EVP_R_AES_KEY_SETUP_FAILED 143 +# define EVP_R_ASN1_LIB 140 +# define EVP_R_BAD_BLOCK_LENGTH 136 +# define EVP_R_BAD_DECRYPT 100 +# define EVP_R_BAD_KEY_LENGTH 137 +# define EVP_R_BN_DECODE_ERROR 112 +# define EVP_R_BN_PUBKEY_ERROR 113 +# define EVP_R_BUFFER_TOO_SMALL 155 +# define EVP_R_CAMELLIA_KEY_SETUP_FAILED 157 +# define EVP_R_CIPHER_PARAMETER_ERROR 122 +# define EVP_R_COMMAND_NOT_SUPPORTED 147 +# define EVP_R_CTRL_NOT_IMPLEMENTED 132 +# define EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED 133 +# define EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 138 +# define EVP_R_DECODE_ERROR 114 +# define EVP_R_DIFFERENT_KEY_TYPES 101 +# define EVP_R_DIFFERENT_PARAMETERS 153 +# define EVP_R_DISABLED_FOR_FIPS 163 +# define EVP_R_ENCODE_ERROR 115 +# define EVP_R_ERROR_LOADING_SECTION 165 +# define EVP_R_ERROR_SETTING_FIPS_MODE 166 +# define EVP_R_EVP_PBE_CIPHERINIT_ERROR 119 +# define EVP_R_EXPECTING_AN_RSA_KEY 127 +# define EVP_R_EXPECTING_A_DH_KEY 128 +# define EVP_R_EXPECTING_A_DSA_KEY 129 +# define EVP_R_EXPECTING_A_ECDSA_KEY 141 +# define EVP_R_EXPECTING_A_EC_KEY 142 +# define EVP_R_FIPS_MODE_NOT_SUPPORTED 167 +# define EVP_R_INITIALIZATION_ERROR 134 +# define EVP_R_INPUT_NOT_INITIALIZED 111 +# define EVP_R_INVALID_DIGEST 152 +# define EVP_R_INVALID_FIPS_MODE 168 +# define EVP_R_INVALID_KEY_LENGTH 130 +# define EVP_R_INVALID_OPERATION 148 +# define EVP_R_IV_TOO_LARGE 102 +# define EVP_R_KEYGEN_FAILURE 120 +# define EVP_R_MESSAGE_DIGEST_IS_NULL 159 +# define EVP_R_METHOD_NOT_SUPPORTED 144 +# define EVP_R_MISSING_PARAMETERS 103 +# define EVP_R_NO_CIPHER_SET 131 +# define EVP_R_NO_DEFAULT_DIGEST 158 +# define EVP_R_NO_DIGEST_SET 139 +# define EVP_R_NO_DSA_PARAMETERS 116 +# define EVP_R_NO_KEY_SET 154 +# define EVP_R_NO_OPERATION_SET 149 +# define EVP_R_NO_SIGN_FUNCTION_CONFIGURED 104 +# define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105 +# define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150 +# define EVP_R_OPERATON_NOT_INITIALIZED 151 +# define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117 +# define EVP_R_PRIVATE_KEY_DECODE_ERROR 145 +# define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146 +# define EVP_R_PUBLIC_KEY_NOT_RSA 106 +# define EVP_R_TOO_LARGE 164 +# define EVP_R_UNKNOWN_CIPHER 160 +# define EVP_R_UNKNOWN_DIGEST 161 +# define EVP_R_UNKNOWN_OPTION 169 +# define EVP_R_UNKNOWN_PBE_ALGORITHM 121 +# define EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS 135 +# define EVP_R_UNSUPPORTED_ALGORITHM 156 +# define EVP_R_UNSUPPORTED_CIPHER 107 +# define EVP_R_UNSUPPORTED_KEYLENGTH 123 +# define EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 124 +# define EVP_R_UNSUPPORTED_KEY_SIZE 108 +# define EVP_R_UNSUPPORTED_PRF 125 +# define EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 118 +# define EVP_R_UNSUPPORTED_SALT_TYPE 126 +# define EVP_R_WRONG_FINAL_BLOCK_LENGTH 109 +# define EVP_R_WRONG_PUBLIC_KEY_TYPE 110 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/evp/evp_acnf.c b/libs/openssl/crypto/evp/evp_acnf.c new file mode 100644 index 00000000..9703116e --- /dev/null +++ b/libs/openssl/crypto/evp/evp_acnf.c @@ -0,0 +1,73 @@ +/* evp_acnf.c */ +/* + * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include +#include + +/* + * Load all algorithms and configure OpenSSL. This function is called + * automatically when OPENSSL_LOAD_CONF is set. + */ + +void OPENSSL_add_all_algorithms_conf(void) +{ + OPENSSL_add_all_algorithms_noconf(); + OPENSSL_config(NULL); +} diff --git a/libs/openssl/crypto/evp/evp_cnf.c b/libs/openssl/crypto/evp/evp_cnf.c new file mode 100644 index 00000000..6fd3a6da --- /dev/null +++ b/libs/openssl/crypto/evp/evp_cnf.c @@ -0,0 +1,118 @@ +/* evp_cnf.c */ +/* + * Written by Stephen Henson (steve@openssl.org) for the OpenSSL project + * 2007. + */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#ifdef OPENSSL_FIPS +# include +#endif + +/* Algorithm configuration module. */ + +static int alg_module_init(CONF_IMODULE *md, const CONF *cnf) +{ + int i; + const char *oid_section; + STACK_OF(CONF_VALUE) *sktmp; + CONF_VALUE *oval; + oid_section = CONF_imodule_get_value(md); + if (!(sktmp = NCONF_get_section(cnf, oid_section))) { + EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_ERROR_LOADING_SECTION); + return 0; + } + for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) { + oval = sk_CONF_VALUE_value(sktmp, i); + if (!strcmp(oval->name, "fips_mode")) { + int m; + if (!X509V3_get_value_bool(oval, &m)) { + EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_INVALID_FIPS_MODE); + return 0; + } + if (m > 0) { +#ifdef OPENSSL_FIPS + if (!FIPS_mode() && !FIPS_mode_set(1)) { + EVPerr(EVP_F_ALG_MODULE_INIT, + EVP_R_ERROR_SETTING_FIPS_MODE); + return 0; + } +#else + EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_FIPS_MODE_NOT_SUPPORTED); + return 0; +#endif + } + } else { + EVPerr(EVP_F_ALG_MODULE_INIT, EVP_R_UNKNOWN_OPTION); + ERR_add_error_data(4, "name=", oval->name, + ", value=", oval->value); + } + + } + return 1; +} + +void EVP_add_alg_module(void) +{ + CONF_module_add("alg_section", alg_module_init, 0); +} diff --git a/libs/openssl/crypto/evp/evp_enc.c b/libs/openssl/crypto/evp/evp_enc.c new file mode 100644 index 00000000..1831572d --- /dev/null +++ b/libs/openssl/crypto/evp/evp_enc.c @@ -0,0 +1,653 @@ +/* crypto/evp/evp_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#ifdef OPENSSL_FIPS +# include +#endif +#include "evp_locl.h" + +#ifdef OPENSSL_FIPS +# define M_do_cipher(ctx, out, in, inl) FIPS_cipher(ctx, out, in, inl) +#else +# define M_do_cipher(ctx, out, in, inl) ctx->cipher->do_cipher(ctx, out, in, inl) +#endif + +const char EVP_version[] = "EVP" OPENSSL_VERSION_PTEXT; + +void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) +{ + memset(ctx, 0, sizeof(EVP_CIPHER_CTX)); + /* ctx->cipher=NULL; */ +} + +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) +{ + EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof *ctx); + if (ctx) + EVP_CIPHER_CTX_init(ctx); + return ctx; +} + +int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv, int enc) +{ + if (cipher) + EVP_CIPHER_CTX_init(ctx); + return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc); +} + +int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv, int enc) +{ + if (enc == -1) + enc = ctx->encrypt; + else { + if (enc) + enc = 1; + ctx->encrypt = enc; + } +#ifndef OPENSSL_NO_ENGINE + /* + * Whether it's nice or not, "Inits" can be used on "Final"'d contexts so + * this context may already have an ENGINE! Try to avoid releasing the + * previous handle, re-querying for an ENGINE, and having a + * reinitialisation, when it may all be unecessary. + */ + if (ctx->engine && ctx->cipher && (!cipher || + (cipher + && (cipher->nid == + ctx->cipher->nid)))) + goto skip_to_init; +#endif + if (cipher) { + /* + * Ensure a context left lying around from last time is cleared (the + * previous check attempted to avoid this if the same ENGINE and + * EVP_CIPHER could be used). + */ + if (ctx->cipher) { + unsigned long flags = ctx->flags; + EVP_CIPHER_CTX_cleanup(ctx); + /* Restore encrypt and flags */ + ctx->encrypt = enc; + ctx->flags = flags; + } +#ifndef OPENSSL_NO_ENGINE + if (impl) { + if (!ENGINE_init(impl)) { + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); + return 0; + } + } else + /* Ask if an ENGINE is reserved for this job */ + impl = ENGINE_get_cipher_engine(cipher->nid); + if (impl) { + /* There's an ENGINE for this job ... (apparently) */ + const EVP_CIPHER *c = ENGINE_get_cipher(impl, cipher->nid); + if (!c) { + /* + * One positive side-effect of US's export control history, + * is that we should at least be able to avoid using US + * mispellings of "initialisation"? + */ + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); + return 0; + } + /* We'll use the ENGINE's private cipher definition */ + cipher = c; + /* + * Store the ENGINE functional reference so we know 'cipher' came + * from an ENGINE and we need to release it when done. + */ + ctx->engine = impl; + } else + ctx->engine = NULL; +#endif + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_cipherinit(ctx, cipher, key, iv, enc); +#endif + ctx->cipher = cipher; + if (ctx->cipher->ctx_size) { + ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size); + if (!ctx->cipher_data) { + EVPerr(EVP_F_EVP_CIPHERINIT_EX, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + ctx->cipher_data = NULL; + } + ctx->key_len = cipher->key_len; + ctx->flags = 0; + if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) { + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_INITIALIZATION_ERROR); + return 0; + } + } + } else if (!ctx->cipher) { + EVPerr(EVP_F_EVP_CIPHERINIT_EX, EVP_R_NO_CIPHER_SET); + return 0; + } +#ifndef OPENSSL_NO_ENGINE + skip_to_init: +#endif +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_cipherinit(ctx, cipher, key, iv, enc); +#endif + /* we assume block size is a power of 2 in *cryptUpdate */ + OPENSSL_assert(ctx->cipher->block_size == 1 + || ctx->cipher->block_size == 8 + || ctx->cipher->block_size == 16); + + if (!(EVP_CIPHER_CTX_flags(ctx) & EVP_CIPH_CUSTOM_IV)) { + switch (EVP_CIPHER_CTX_mode(ctx)) { + + case EVP_CIPH_STREAM_CIPHER: + case EVP_CIPH_ECB_MODE: + break; + + case EVP_CIPH_CFB_MODE: + case EVP_CIPH_OFB_MODE: + + ctx->num = 0; + /* fall-through */ + + case EVP_CIPH_CBC_MODE: + + OPENSSL_assert(EVP_CIPHER_CTX_iv_length(ctx) <= + (int)sizeof(ctx->iv)); + if (iv) + memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + break; + + case EVP_CIPH_CTR_MODE: + ctx->num = 0; + /* Don't reuse IV for CTR mode */ + if (iv) + memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + break; + + default: + return 0; + break; + } + } + + if (key || (ctx->cipher->flags & EVP_CIPH_ALWAYS_CALL_INIT)) { + if (!ctx->cipher->init(ctx, key, iv, enc)) + return 0; + } + ctx->buf_len = 0; + ctx->final_used = 0; + ctx->block_mask = ctx->cipher->block_size - 1; + return 1; +} + +int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + if (ctx->encrypt) + return EVP_EncryptUpdate(ctx, out, outl, in, inl); + else + return EVP_DecryptUpdate(ctx, out, outl, in, inl); +} + +int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + if (ctx->encrypt) + return EVP_EncryptFinal_ex(ctx, out, outl); + else + return EVP_DecryptFinal_ex(ctx, out, outl); +} + +int EVP_CipherFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + if (ctx->encrypt) + return EVP_EncryptFinal(ctx, out, outl); + else + return EVP_DecryptFinal(ctx, out, outl); +} + +int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv) +{ + return EVP_CipherInit(ctx, cipher, key, iv, 1); +} + +int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv) +{ + return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1); +} + +int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const unsigned char *key, const unsigned char *iv) +{ + return EVP_CipherInit(ctx, cipher, key, iv, 0); +} + +int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const unsigned char *key, + const unsigned char *iv) +{ + return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0); +} + +int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + int i, j, bl; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + i = M_do_cipher(ctx, out, in, inl); + if (i < 0) + return 0; + else + *outl = i; + return 1; + } + + if (inl <= 0) { + *outl = 0; + return inl == 0; + } + + if (ctx->buf_len == 0 && (inl & (ctx->block_mask)) == 0) { + if (M_do_cipher(ctx, out, in, inl)) { + *outl = inl; + return 1; + } else { + *outl = 0; + return 0; + } + } + i = ctx->buf_len; + bl = ctx->cipher->block_size; + OPENSSL_assert(bl <= (int)sizeof(ctx->buf)); + if (i != 0) { + if (bl - i > inl) { + memcpy(&(ctx->buf[i]), in, inl); + ctx->buf_len += inl; + *outl = 0; + return 1; + } else { + j = bl - i; + memcpy(&(ctx->buf[i]), in, j); + if (!M_do_cipher(ctx, out, ctx->buf, bl)) + return 0; + inl -= j; + in += j; + out += bl; + *outl = bl; + } + } else + *outl = 0; + i = inl & (bl - 1); + inl -= i; + if (inl > 0) { + if (!M_do_cipher(ctx, out, in, inl)) + return 0; + *outl += inl; + } + + if (i != 0) + memcpy(ctx->buf, &(in[inl]), i); + ctx->buf_len = i; + return 1; +} + +int EVP_EncryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int ret; + ret = EVP_EncryptFinal_ex(ctx, out, outl); + return ret; +} + +int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int n, ret; + unsigned int i, b, bl; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + ret = M_do_cipher(ctx, out, NULL, 0); + if (ret < 0) + return 0; + else + *outl = ret; + return 1; + } + + b = ctx->cipher->block_size; + OPENSSL_assert(b <= sizeof ctx->buf); + if (b == 1) { + *outl = 0; + return 1; + } + bl = ctx->buf_len; + if (ctx->flags & EVP_CIPH_NO_PADDING) { + if (bl) { + EVPerr(EVP_F_EVP_ENCRYPTFINAL_EX, + EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); + return 0; + } + *outl = 0; + return 1; + } + + n = b - bl; + for (i = bl; i < b; i++) + ctx->buf[i] = n; + ret = M_do_cipher(ctx, out, ctx->buf, b); + + if (ret) + *outl = b; + + return ret; +} + +int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) +{ + int fix_len; + unsigned int b; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + fix_len = M_do_cipher(ctx, out, in, inl); + if (fix_len < 0) { + *outl = 0; + return 0; + } else + *outl = fix_len; + return 1; + } + + if (inl <= 0) { + *outl = 0; + return inl == 0; + } + + if (ctx->flags & EVP_CIPH_NO_PADDING) + return EVP_EncryptUpdate(ctx, out, outl, in, inl); + + b = ctx->cipher->block_size; + OPENSSL_assert(b <= sizeof ctx->final); + + if (ctx->final_used) { + memcpy(out, ctx->final, b); + out += b; + fix_len = 1; + } else + fix_len = 0; + + if (!EVP_EncryptUpdate(ctx, out, outl, in, inl)) + return 0; + + /* + * if we have 'decrypted' a multiple of block size, make sure we have a + * copy of this last block + */ + if (b > 1 && !ctx->buf_len) { + *outl -= b; + ctx->final_used = 1; + memcpy(ctx->final, &out[*outl], b); + } else + ctx->final_used = 0; + + if (fix_len) + *outl += b; + + return 1; +} + +int EVP_DecryptFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int ret; + ret = EVP_DecryptFinal_ex(ctx, out, outl); + return ret; +} + +int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int i, n; + unsigned int b; + *outl = 0; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + i = M_do_cipher(ctx, out, NULL, 0); + if (i < 0) + return 0; + else + *outl = i; + return 1; + } + + b = ctx->cipher->block_size; + if (ctx->flags & EVP_CIPH_NO_PADDING) { + if (ctx->buf_len) { + EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, + EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); + return 0; + } + *outl = 0; + return 1; + } + if (b > 1) { + if (ctx->buf_len || !ctx->final_used) { + EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_WRONG_FINAL_BLOCK_LENGTH); + return (0); + } + OPENSSL_assert(b <= sizeof ctx->final); + + /* + * The following assumes that the ciphertext has been authenticated. + * Otherwise it provides a padding oracle. + */ + n = ctx->final[b - 1]; + if (n == 0 || n > (int)b) { + EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); + return (0); + } + for (i = 0; i < n; i++) { + if (ctx->final[--b] != n) { + EVPerr(EVP_F_EVP_DECRYPTFINAL_EX, EVP_R_BAD_DECRYPT); + return (0); + } + } + n = ctx->cipher->block_size - n; + for (i = 0; i < n; i++) + out[i] = ctx->final[i]; + *outl = n; + } else + *outl = 0; + return (1); +} + +void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx) +{ + if (ctx) { + EVP_CIPHER_CTX_cleanup(ctx); + OPENSSL_free(ctx); + } +} + +int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) +{ +#ifndef OPENSSL_FIPS + if (c->cipher != NULL) { + if (c->cipher->cleanup && !c->cipher->cleanup(c)) + return 0; + /* Cleanse cipher context data */ + if (c->cipher_data) + OPENSSL_cleanse(c->cipher_data, c->cipher->ctx_size); + } + if (c->cipher_data) + OPENSSL_free(c->cipher_data); +#endif +#ifndef OPENSSL_NO_ENGINE + if (c->engine) + /* + * The EVP_CIPHER we used belongs to an ENGINE, release the + * functional reference we held for this reason. + */ + ENGINE_finish(c->engine); +#endif +#ifdef OPENSSL_FIPS + FIPS_cipher_ctx_cleanup(c); +#endif + memset(c, 0, sizeof(EVP_CIPHER_CTX)); + return 1; +} + +int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *c, int keylen) +{ + if (c->cipher->flags & EVP_CIPH_CUSTOM_KEY_LENGTH) + return EVP_CIPHER_CTX_ctrl(c, EVP_CTRL_SET_KEY_LENGTH, keylen, NULL); + if (c->key_len == keylen) + return 1; + if ((keylen > 0) && (c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) { + c->key_len = keylen; + return 1; + } + EVPerr(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH, EVP_R_INVALID_KEY_LENGTH); + return 0; +} + +int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad) +{ + if (pad) + ctx->flags &= ~EVP_CIPH_NO_PADDING; + else + ctx->flags |= EVP_CIPH_NO_PADDING; + return 1; +} + +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) +{ + int ret; + if (!ctx->cipher) { + EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_NO_CIPHER_SET); + return 0; + } + + if (!ctx->cipher->ctrl) { + EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, EVP_R_CTRL_NOT_IMPLEMENTED); + return 0; + } + + ret = ctx->cipher->ctrl(ctx, type, arg, ptr); + if (ret == -1) { + EVPerr(EVP_F_EVP_CIPHER_CTX_CTRL, + EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED); + return 0; + } + return ret; +} + +int EVP_CIPHER_CTX_rand_key(EVP_CIPHER_CTX *ctx, unsigned char *key) +{ + if (ctx->cipher->flags & EVP_CIPH_RAND_KEY) + return EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_RAND_KEY, 0, key); + if (RAND_bytes(key, ctx->key_len) <= 0) + return 0; + return 1; +} + +int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) +{ + if ((in == NULL) || (in->cipher == NULL)) { + EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, EVP_R_INPUT_NOT_INITIALIZED); + return 0; + } +#ifndef OPENSSL_NO_ENGINE + /* Make sure it's safe to copy a cipher context using an ENGINE */ + if (in->engine && !ENGINE_init(in->engine)) { + EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_ENGINE_LIB); + return 0; + } +#endif + + EVP_CIPHER_CTX_cleanup(out); + memcpy(out, in, sizeof *out); + + if (in->cipher_data && in->cipher->ctx_size) { + out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); + if (!out->cipher_data) { + EVPerr(EVP_F_EVP_CIPHER_CTX_COPY, ERR_R_MALLOC_FAILURE); + return 0; + } + memcpy(out->cipher_data, in->cipher_data, in->cipher->ctx_size); + } + + if (in->cipher->flags & EVP_CIPH_CUSTOM_COPY) + return in->cipher->ctrl((EVP_CIPHER_CTX *)in, EVP_CTRL_COPY, 0, out); + return 1; +} diff --git a/libs/openssl/crypto/evp/evp_err.c b/libs/openssl/crypto/evp/evp_err.c new file mode 100644 index 00000000..686a6995 --- /dev/null +++ b/libs/openssl/crypto/evp/evp_err.c @@ -0,0 +1,251 @@ +/* crypto/evp/evp_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_EVP,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_EVP,0,reason) + +static ERR_STRING_DATA EVP_str_functs[] = { + {ERR_FUNC(EVP_F_AESNI_INIT_KEY), "AESNI_INIT_KEY"}, + {ERR_FUNC(EVP_F_AESNI_XTS_CIPHER), "AESNI_XTS_CIPHER"}, + {ERR_FUNC(EVP_F_AES_INIT_KEY), "AES_INIT_KEY"}, + {ERR_FUNC(EVP_F_AES_XTS), "AES_XTS"}, + {ERR_FUNC(EVP_F_AES_XTS_CIPHER), "AES_XTS_CIPHER"}, + {ERR_FUNC(EVP_F_ALG_MODULE_INIT), "ALG_MODULE_INIT"}, + {ERR_FUNC(EVP_F_CAMELLIA_INIT_KEY), "CAMELLIA_INIT_KEY"}, + {ERR_FUNC(EVP_F_CMAC_INIT), "CMAC_INIT"}, + {ERR_FUNC(EVP_F_D2I_PKEY), "D2I_PKEY"}, + {ERR_FUNC(EVP_F_DO_SIGVER_INIT), "DO_SIGVER_INIT"}, + {ERR_FUNC(EVP_F_DSAPKEY2PKCS8), "DSAPKEY2PKCS8"}, + {ERR_FUNC(EVP_F_DSA_PKEY2PKCS8), "DSA_PKEY2PKCS8"}, + {ERR_FUNC(EVP_F_ECDSA_PKEY2PKCS8), "ECDSA_PKEY2PKCS8"}, + {ERR_FUNC(EVP_F_ECKEY_PKEY2PKCS8), "ECKEY_PKEY2PKCS8"}, + {ERR_FUNC(EVP_F_EVP_CIPHERINIT_EX), "EVP_CipherInit_ex"}, + {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_COPY), "EVP_CIPHER_CTX_copy"}, + {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_CTRL), "EVP_CIPHER_CTX_ctrl"}, + {ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH), + "EVP_CIPHER_CTX_set_key_length"}, + {ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"}, + {ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"}, + {ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"}, + {ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"}, + {ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_size"}, + {ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"}, + {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD), "EVP_PBE_alg_add"}, + {ERR_FUNC(EVP_F_EVP_PBE_ALG_ADD_TYPE), "EVP_PBE_alg_add_type"}, + {ERR_FUNC(EVP_F_EVP_PBE_CIPHERINIT), "EVP_PBE_CipherInit"}, + {ERR_FUNC(EVP_F_EVP_PKCS82PKEY), "EVP_PKCS82PKEY"}, + {ERR_FUNC(EVP_F_EVP_PKCS82PKEY_BROKEN), "EVP_PKCS82PKEY_BROKEN"}, + {ERR_FUNC(EVP_F_EVP_PKEY2PKCS8_BROKEN), "EVP_PKEY2PKCS8_broken"}, + {ERR_FUNC(EVP_F_EVP_PKEY_COPY_PARAMETERS), "EVP_PKEY_copy_parameters"}, + {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL), "EVP_PKEY_CTX_ctrl"}, + {ERR_FUNC(EVP_F_EVP_PKEY_CTX_CTRL_STR), "EVP_PKEY_CTX_ctrl_str"}, + {ERR_FUNC(EVP_F_EVP_PKEY_CTX_DUP), "EVP_PKEY_CTX_dup"}, + {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT), "EVP_PKEY_decrypt"}, + {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_INIT), "EVP_PKEY_decrypt_init"}, + {ERR_FUNC(EVP_F_EVP_PKEY_DECRYPT_OLD), "EVP_PKEY_decrypt_old"}, + {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE), "EVP_PKEY_derive"}, + {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_INIT), "EVP_PKEY_derive_init"}, + {ERR_FUNC(EVP_F_EVP_PKEY_DERIVE_SET_PEER), "EVP_PKEY_derive_set_peer"}, + {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT), "EVP_PKEY_encrypt"}, + {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_INIT), "EVP_PKEY_encrypt_init"}, + {ERR_FUNC(EVP_F_EVP_PKEY_ENCRYPT_OLD), "EVP_PKEY_encrypt_old"}, + {ERR_FUNC(EVP_F_EVP_PKEY_GET1_DH), "EVP_PKEY_get1_DH"}, + {ERR_FUNC(EVP_F_EVP_PKEY_GET1_DSA), "EVP_PKEY_get1_DSA"}, + {ERR_FUNC(EVP_F_EVP_PKEY_GET1_ECDSA), "EVP_PKEY_GET1_ECDSA"}, + {ERR_FUNC(EVP_F_EVP_PKEY_GET1_EC_KEY), "EVP_PKEY_get1_EC_KEY"}, + {ERR_FUNC(EVP_F_EVP_PKEY_GET1_RSA), "EVP_PKEY_get1_RSA"}, + {ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN), "EVP_PKEY_keygen"}, + {ERR_FUNC(EVP_F_EVP_PKEY_KEYGEN_INIT), "EVP_PKEY_keygen_init"}, + {ERR_FUNC(EVP_F_EVP_PKEY_NEW), "EVP_PKEY_new"}, + {ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN), "EVP_PKEY_paramgen"}, + {ERR_FUNC(EVP_F_EVP_PKEY_PARAMGEN_INIT), "EVP_PKEY_paramgen_init"}, + {ERR_FUNC(EVP_F_EVP_PKEY_SIGN), "EVP_PKEY_sign"}, + {ERR_FUNC(EVP_F_EVP_PKEY_SIGN_INIT), "EVP_PKEY_sign_init"}, + {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY), "EVP_PKEY_verify"}, + {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_INIT), "EVP_PKEY_verify_init"}, + {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER), "EVP_PKEY_verify_recover"}, + {ERR_FUNC(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT), + "EVP_PKEY_verify_recover_init"}, + {ERR_FUNC(EVP_F_EVP_RIJNDAEL), "EVP_RIJNDAEL"}, + {ERR_FUNC(EVP_F_EVP_SIGNFINAL), "EVP_SignFinal"}, + {ERR_FUNC(EVP_F_EVP_VERIFYFINAL), "EVP_VerifyFinal"}, + {ERR_FUNC(EVP_F_FIPS_CIPHERINIT), "FIPS_CIPHERINIT"}, + {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_COPY), "FIPS_CIPHER_CTX_COPY"}, + {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_CTRL), "FIPS_CIPHER_CTX_CTRL"}, + {ERR_FUNC(EVP_F_FIPS_CIPHER_CTX_SET_KEY_LENGTH), + "FIPS_CIPHER_CTX_SET_KEY_LENGTH"}, + {ERR_FUNC(EVP_F_FIPS_DIGESTINIT), "FIPS_DIGESTINIT"}, + {ERR_FUNC(EVP_F_FIPS_MD_CTX_COPY), "FIPS_MD_CTX_COPY"}, + {ERR_FUNC(EVP_F_HMAC_INIT_EX), "HMAC_Init_ex"}, + {ERR_FUNC(EVP_F_INT_CTX_NEW), "INT_CTX_NEW"}, + {ERR_FUNC(EVP_F_PKCS5_PBE_KEYIVGEN), "PKCS5_PBE_keyivgen"}, + {ERR_FUNC(EVP_F_PKCS5_V2_PBE_KEYIVGEN), "PKCS5_v2_PBE_keyivgen"}, + {ERR_FUNC(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN), "PKCS5_V2_PBKDF2_KEYIVGEN"}, + {ERR_FUNC(EVP_F_PKCS8_SET_BROKEN), "PKCS8_set_broken"}, + {ERR_FUNC(EVP_F_PKEY_SET_TYPE), "PKEY_SET_TYPE"}, + {ERR_FUNC(EVP_F_RC2_MAGIC_TO_METH), "RC2_MAGIC_TO_METH"}, + {ERR_FUNC(EVP_F_RC5_CTRL), "RC5_CTRL"}, + {0, NULL} +}; + +static ERR_STRING_DATA EVP_str_reasons[] = { + {ERR_REASON(EVP_R_AES_IV_SETUP_FAILED), "aes iv setup failed"}, + {ERR_REASON(EVP_R_AES_KEY_SETUP_FAILED), "aes key setup failed"}, + {ERR_REASON(EVP_R_ASN1_LIB), "asn1 lib"}, + {ERR_REASON(EVP_R_BAD_BLOCK_LENGTH), "bad block length"}, + {ERR_REASON(EVP_R_BAD_DECRYPT), "bad decrypt"}, + {ERR_REASON(EVP_R_BAD_KEY_LENGTH), "bad key length"}, + {ERR_REASON(EVP_R_BN_DECODE_ERROR), "bn decode error"}, + {ERR_REASON(EVP_R_BN_PUBKEY_ERROR), "bn pubkey error"}, + {ERR_REASON(EVP_R_BUFFER_TOO_SMALL), "buffer too small"}, + {ERR_REASON(EVP_R_CAMELLIA_KEY_SETUP_FAILED), + "camellia key setup failed"}, + {ERR_REASON(EVP_R_CIPHER_PARAMETER_ERROR), "cipher parameter error"}, + {ERR_REASON(EVP_R_COMMAND_NOT_SUPPORTED), "command not supported"}, + {ERR_REASON(EVP_R_CTRL_NOT_IMPLEMENTED), "ctrl not implemented"}, + {ERR_REASON(EVP_R_CTRL_OPERATION_NOT_IMPLEMENTED), + "ctrl operation not implemented"}, + {ERR_REASON(EVP_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH), + "data not multiple of block length"}, + {ERR_REASON(EVP_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(EVP_R_DIFFERENT_KEY_TYPES), "different key types"}, + {ERR_REASON(EVP_R_DIFFERENT_PARAMETERS), "different parameters"}, + {ERR_REASON(EVP_R_DISABLED_FOR_FIPS), "disabled for fips"}, + {ERR_REASON(EVP_R_ENCODE_ERROR), "encode error"}, + {ERR_REASON(EVP_R_ERROR_LOADING_SECTION), "error loading section"}, + {ERR_REASON(EVP_R_ERROR_SETTING_FIPS_MODE), "error setting fips mode"}, + {ERR_REASON(EVP_R_EVP_PBE_CIPHERINIT_ERROR), "evp pbe cipherinit error"}, + {ERR_REASON(EVP_R_EXPECTING_AN_RSA_KEY), "expecting an rsa key"}, + {ERR_REASON(EVP_R_EXPECTING_A_DH_KEY), "expecting a dh key"}, + {ERR_REASON(EVP_R_EXPECTING_A_DSA_KEY), "expecting a dsa key"}, + {ERR_REASON(EVP_R_EXPECTING_A_ECDSA_KEY), "expecting a ecdsa key"}, + {ERR_REASON(EVP_R_EXPECTING_A_EC_KEY), "expecting a ec key"}, + {ERR_REASON(EVP_R_FIPS_MODE_NOT_SUPPORTED), "fips mode not supported"}, + {ERR_REASON(EVP_R_INITIALIZATION_ERROR), "initialization error"}, + {ERR_REASON(EVP_R_INPUT_NOT_INITIALIZED), "input not initialized"}, + {ERR_REASON(EVP_R_INVALID_DIGEST), "invalid digest"}, + {ERR_REASON(EVP_R_INVALID_FIPS_MODE), "invalid fips mode"}, + {ERR_REASON(EVP_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_REASON(EVP_R_INVALID_OPERATION), "invalid operation"}, + {ERR_REASON(EVP_R_IV_TOO_LARGE), "iv too large"}, + {ERR_REASON(EVP_R_KEYGEN_FAILURE), "keygen failure"}, + {ERR_REASON(EVP_R_MESSAGE_DIGEST_IS_NULL), "message digest is null"}, + {ERR_REASON(EVP_R_METHOD_NOT_SUPPORTED), "method not supported"}, + {ERR_REASON(EVP_R_MISSING_PARAMETERS), "missing parameters"}, + {ERR_REASON(EVP_R_NO_CIPHER_SET), "no cipher set"}, + {ERR_REASON(EVP_R_NO_DEFAULT_DIGEST), "no default digest"}, + {ERR_REASON(EVP_R_NO_DIGEST_SET), "no digest set"}, + {ERR_REASON(EVP_R_NO_DSA_PARAMETERS), "no dsa parameters"}, + {ERR_REASON(EVP_R_NO_KEY_SET), "no key set"}, + {ERR_REASON(EVP_R_NO_OPERATION_SET), "no operation set"}, + {ERR_REASON(EVP_R_NO_SIGN_FUNCTION_CONFIGURED), + "no sign function configured"}, + {ERR_REASON(EVP_R_NO_VERIFY_FUNCTION_CONFIGURED), + "no verify function configured"}, + {ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), + "operation not supported for this keytype"}, + {ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"}, + {ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE), + "pkcs8 unknown broken type"}, + {ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"}, + {ERR_REASON(EVP_R_PRIVATE_KEY_ENCODE_ERROR), "private key encode error"}, + {ERR_REASON(EVP_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"}, + {ERR_REASON(EVP_R_TOO_LARGE), "too large"}, + {ERR_REASON(EVP_R_UNKNOWN_CIPHER), "unknown cipher"}, + {ERR_REASON(EVP_R_UNKNOWN_DIGEST), "unknown digest"}, + {ERR_REASON(EVP_R_UNKNOWN_OPTION), "unknown option"}, + {ERR_REASON(EVP_R_UNKNOWN_PBE_ALGORITHM), "unknown pbe algorithm"}, + {ERR_REASON(EVP_R_UNSUPORTED_NUMBER_OF_ROUNDS), + "unsuported number of rounds"}, + {ERR_REASON(EVP_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, + {ERR_REASON(EVP_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, + {ERR_REASON(EVP_R_UNSUPPORTED_KEYLENGTH), "unsupported keylength"}, + {ERR_REASON(EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION), + "unsupported key derivation function"}, + {ERR_REASON(EVP_R_UNSUPPORTED_KEY_SIZE), "unsupported key size"}, + {ERR_REASON(EVP_R_UNSUPPORTED_PRF), "unsupported prf"}, + {ERR_REASON(EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM), + "unsupported private key algorithm"}, + {ERR_REASON(EVP_R_UNSUPPORTED_SALT_TYPE), "unsupported salt type"}, + {ERR_REASON(EVP_R_WRONG_FINAL_BLOCK_LENGTH), "wrong final block length"}, + {ERR_REASON(EVP_R_WRONG_PUBLIC_KEY_TYPE), "wrong public key type"}, + {0, NULL} +}; + +#endif + +void ERR_load_EVP_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(EVP_str_functs[0].error) == NULL) { + ERR_load_strings(0, EVP_str_functs); + ERR_load_strings(0, EVP_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/evp/evp_extra_test.c b/libs/openssl/crypto/evp/evp_extra_test.c new file mode 100644 index 00000000..21688b0c --- /dev/null +++ b/libs/openssl/crypto/evp/evp_extra_test.c @@ -0,0 +1,489 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ +/* ==================================================================== + * Copyright (c) 1998-2015 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * kExampleRSAKeyDER is an RSA private key in ASN.1, DER format. Of course, you + * should never use this key anywhere but in an example. + */ +static const unsigned char kExampleRSAKeyDER[] = { + 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, 0x00, 0xf8, + 0xb8, 0x6c, 0x83, 0xb4, 0xbc, 0xd9, 0xa8, 0x57, 0xc0, 0xa5, 0xb4, 0x59, + 0x76, 0x8c, 0x54, 0x1d, 0x79, 0xeb, 0x22, 0x52, 0x04, 0x7e, 0xd3, 0x37, + 0xeb, 0x41, 0xfd, 0x83, 0xf9, 0xf0, 0xa6, 0x85, 0x15, 0x34, 0x75, 0x71, + 0x5a, 0x84, 0xa8, 0x3c, 0xd2, 0xef, 0x5a, 0x4e, 0xd3, 0xde, 0x97, 0x8a, + 0xdd, 0xff, 0xbb, 0xcf, 0x0a, 0xaa, 0x86, 0x92, 0xbe, 0xb8, 0x50, 0xe4, + 0xcd, 0x6f, 0x80, 0x33, 0x30, 0x76, 0x13, 0x8f, 0xca, 0x7b, 0xdc, 0xec, + 0x5a, 0xca, 0x63, 0xc7, 0x03, 0x25, 0xef, 0xa8, 0x8a, 0x83, 0x58, 0x76, + 0x20, 0xfa, 0x16, 0x77, 0xd7, 0x79, 0x92, 0x63, 0x01, 0x48, 0x1a, 0xd8, + 0x7b, 0x67, 0xf1, 0x52, 0x55, 0x49, 0x4e, 0xd6, 0x6e, 0x4a, 0x5c, 0xd7, + 0x7a, 0x37, 0x36, 0x0c, 0xde, 0xdd, 0x8f, 0x44, 0xe8, 0xc2, 0xa7, 0x2c, + 0x2b, 0xb5, 0xaf, 0x64, 0x4b, 0x61, 0x07, 0x02, 0x03, 0x01, 0x00, 0x01, + 0x02, 0x81, 0x80, 0x74, 0x88, 0x64, 0x3f, 0x69, 0x45, 0x3a, 0x6d, 0xc7, + 0x7f, 0xb9, 0xa3, 0xc0, 0x6e, 0xec, 0xdc, 0xd4, 0x5a, 0xb5, 0x32, 0x85, + 0x5f, 0x19, 0xd4, 0xf8, 0xd4, 0x3f, 0x3c, 0xfa, 0xc2, 0xf6, 0x5f, 0xee, + 0xe6, 0xba, 0x87, 0x74, 0x2e, 0xc7, 0x0c, 0xd4, 0x42, 0xb8, 0x66, 0x85, + 0x9c, 0x7b, 0x24, 0x61, 0xaa, 0x16, 0x11, 0xf6, 0xb5, 0xb6, 0xa4, 0x0a, + 0xc9, 0x55, 0x2e, 0x81, 0xa5, 0x47, 0x61, 0xcb, 0x25, 0x8f, 0xc2, 0x15, + 0x7b, 0x0e, 0x7c, 0x36, 0x9f, 0x3a, 0xda, 0x58, 0x86, 0x1c, 0x5b, 0x83, + 0x79, 0xe6, 0x2b, 0xcc, 0xe6, 0xfa, 0x2c, 0x61, 0xf2, 0x78, 0x80, 0x1b, + 0xe2, 0xf3, 0x9d, 0x39, 0x2b, 0x65, 0x57, 0x91, 0x3d, 0x71, 0x99, 0x73, + 0xa5, 0xc2, 0x79, 0x20, 0x8c, 0x07, 0x4f, 0xe5, 0xb4, 0x60, 0x1f, 0x99, + 0xa2, 0xb1, 0x4f, 0x0c, 0xef, 0xbc, 0x59, 0x53, 0x00, 0x7d, 0xb1, 0x02, + 0x41, 0x00, 0xfc, 0x7e, 0x23, 0x65, 0x70, 0xf8, 0xce, 0xd3, 0x40, 0x41, + 0x80, 0x6a, 0x1d, 0x01, 0xd6, 0x01, 0xff, 0xb6, 0x1b, 0x3d, 0x3d, 0x59, + 0x09, 0x33, 0x79, 0xc0, 0x4f, 0xde, 0x96, 0x27, 0x4b, 0x18, 0xc6, 0xd9, + 0x78, 0xf1, 0xf4, 0x35, 0x46, 0xe9, 0x7c, 0x42, 0x7a, 0x5d, 0x9f, 0xef, + 0x54, 0xb8, 0xf7, 0x9f, 0xc4, 0x33, 0x6c, 0xf3, 0x8c, 0x32, 0x46, 0x87, + 0x67, 0x30, 0x7b, 0xa7, 0xac, 0xe3, 0x02, 0x41, 0x00, 0xfc, 0x2c, 0xdf, + 0x0c, 0x0d, 0x88, 0xf5, 0xb1, 0x92, 0xa8, 0x93, 0x47, 0x63, 0x55, 0xf5, + 0xca, 0x58, 0x43, 0xba, 0x1c, 0xe5, 0x9e, 0xb6, 0x95, 0x05, 0xcd, 0xb5, + 0x82, 0xdf, 0xeb, 0x04, 0x53, 0x9d, 0xbd, 0xc2, 0x38, 0x16, 0xb3, 0x62, + 0xdd, 0xa1, 0x46, 0xdb, 0x6d, 0x97, 0x93, 0x9f, 0x8a, 0xc3, 0x9b, 0x64, + 0x7e, 0x42, 0xe3, 0x32, 0x57, 0x19, 0x1b, 0xd5, 0x6e, 0x85, 0xfa, 0xb8, + 0x8d, 0x02, 0x41, 0x00, 0xbc, 0x3d, 0xde, 0x6d, 0xd6, 0x97, 0xe8, 0xba, + 0x9e, 0x81, 0x37, 0x17, 0xe5, 0xa0, 0x64, 0xc9, 0x00, 0xb7, 0xe7, 0xfe, + 0xf4, 0x29, 0xd9, 0x2e, 0x43, 0x6b, 0x19, 0x20, 0xbd, 0x99, 0x75, 0xe7, + 0x76, 0xf8, 0xd3, 0xae, 0xaf, 0x7e, 0xb8, 0xeb, 0x81, 0xf4, 0x9d, 0xfe, + 0x07, 0x2b, 0x0b, 0x63, 0x0b, 0x5a, 0x55, 0x90, 0x71, 0x7d, 0xf1, 0xdb, + 0xd9, 0xb1, 0x41, 0x41, 0x68, 0x2f, 0x4e, 0x39, 0x02, 0x40, 0x5a, 0x34, + 0x66, 0xd8, 0xf5, 0xe2, 0x7f, 0x18, 0xb5, 0x00, 0x6e, 0x26, 0x84, 0x27, + 0x14, 0x93, 0xfb, 0xfc, 0xc6, 0x0f, 0x5e, 0x27, 0xe6, 0xe1, 0xe9, 0xc0, + 0x8a, 0xe4, 0x34, 0xda, 0xe9, 0xa2, 0x4b, 0x73, 0xbc, 0x8c, 0xb9, 0xba, + 0x13, 0x6c, 0x7a, 0x2b, 0x51, 0x84, 0xa3, 0x4a, 0xe0, 0x30, 0x10, 0x06, + 0x7e, 0xed, 0x17, 0x5a, 0x14, 0x00, 0xc9, 0xef, 0x85, 0xea, 0x52, 0x2c, + 0xbc, 0x65, 0x02, 0x40, 0x51, 0xe3, 0xf2, 0x83, 0x19, 0x9b, 0xc4, 0x1e, + 0x2f, 0x50, 0x3d, 0xdf, 0x5a, 0xa2, 0x18, 0xca, 0x5f, 0x2e, 0x49, 0xaf, + 0x6f, 0xcc, 0xfa, 0x65, 0x77, 0x94, 0xb5, 0xa1, 0x0a, 0xa9, 0xd1, 0x8a, + 0x39, 0x37, 0xf4, 0x0b, 0xa0, 0xd7, 0x82, 0x27, 0x5e, 0xae, 0x17, 0x17, + 0xa1, 0x1e, 0x54, 0x34, 0xbf, 0x6e, 0xc4, 0x8e, 0x99, 0x5d, 0x08, 0xf1, + 0x2d, 0x86, 0x9d, 0xa5, 0x20, 0x1b, 0xe5, 0xdf, +}; + +static const unsigned char kMsg[] = { 1, 2, 3, 4 }; + +static const unsigned char kSignature[] = { + 0xa5, 0xf0, 0x8a, 0x47, 0x5d, 0x3c, 0xb3, 0xcc, 0xa9, 0x79, 0xaf, 0x4d, + 0x8c, 0xae, 0x4c, 0x14, 0xef, 0xc2, 0x0b, 0x34, 0x36, 0xde, 0xf4, 0x3e, + 0x3d, 0xbb, 0x4a, 0x60, 0x5c, 0xc8, 0x91, 0x28, 0xda, 0xfb, 0x7e, 0x04, + 0x96, 0x7e, 0x63, 0x13, 0x90, 0xce, 0xb9, 0xb4, 0x62, 0x7a, 0xfd, 0x09, + 0x3d, 0xc7, 0x67, 0x78, 0x54, 0x04, 0xeb, 0x52, 0x62, 0x6e, 0x24, 0x67, + 0xb4, 0x40, 0xfc, 0x57, 0x62, 0xc6, 0xf1, 0x67, 0xc1, 0x97, 0x8f, 0x6a, + 0xa8, 0xae, 0x44, 0x46, 0x5e, 0xab, 0x67, 0x17, 0x53, 0x19, 0x3a, 0xda, + 0x5a, 0xc8, 0x16, 0x3e, 0x86, 0xd5, 0xc5, 0x71, 0x2f, 0xfc, 0x23, 0x48, + 0xd9, 0x0b, 0x13, 0xdd, 0x7b, 0x5a, 0x25, 0x79, 0xef, 0xa5, 0x7b, 0x04, + 0xed, 0x44, 0xf6, 0x18, 0x55, 0xe4, 0x0a, 0xe9, 0x57, 0x79, 0x5d, 0xd7, + 0x55, 0xa7, 0xab, 0x45, 0x02, 0x97, 0x60, 0x42, +}; + +/* + * kExampleRSAKeyPKCS8 is kExampleRSAKeyDER encoded in a PKCS #8 + * PrivateKeyInfo. + */ +static const unsigned char kExampleRSAKeyPKCS8[] = { + 0x30, 0x82, 0x02, 0x76, 0x02, 0x01, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82, + 0x02, 0x60, 0x30, 0x82, 0x02, 0x5c, 0x02, 0x01, 0x00, 0x02, 0x81, 0x81, + 0x00, 0xf8, 0xb8, 0x6c, 0x83, 0xb4, 0xbc, 0xd9, 0xa8, 0x57, 0xc0, 0xa5, + 0xb4, 0x59, 0x76, 0x8c, 0x54, 0x1d, 0x79, 0xeb, 0x22, 0x52, 0x04, 0x7e, + 0xd3, 0x37, 0xeb, 0x41, 0xfd, 0x83, 0xf9, 0xf0, 0xa6, 0x85, 0x15, 0x34, + 0x75, 0x71, 0x5a, 0x84, 0xa8, 0x3c, 0xd2, 0xef, 0x5a, 0x4e, 0xd3, 0xde, + 0x97, 0x8a, 0xdd, 0xff, 0xbb, 0xcf, 0x0a, 0xaa, 0x86, 0x92, 0xbe, 0xb8, + 0x50, 0xe4, 0xcd, 0x6f, 0x80, 0x33, 0x30, 0x76, 0x13, 0x8f, 0xca, 0x7b, + 0xdc, 0xec, 0x5a, 0xca, 0x63, 0xc7, 0x03, 0x25, 0xef, 0xa8, 0x8a, 0x83, + 0x58, 0x76, 0x20, 0xfa, 0x16, 0x77, 0xd7, 0x79, 0x92, 0x63, 0x01, 0x48, + 0x1a, 0xd8, 0x7b, 0x67, 0xf1, 0x52, 0x55, 0x49, 0x4e, 0xd6, 0x6e, 0x4a, + 0x5c, 0xd7, 0x7a, 0x37, 0x36, 0x0c, 0xde, 0xdd, 0x8f, 0x44, 0xe8, 0xc2, + 0xa7, 0x2c, 0x2b, 0xb5, 0xaf, 0x64, 0x4b, 0x61, 0x07, 0x02, 0x03, 0x01, + 0x00, 0x01, 0x02, 0x81, 0x80, 0x74, 0x88, 0x64, 0x3f, 0x69, 0x45, 0x3a, + 0x6d, 0xc7, 0x7f, 0xb9, 0xa3, 0xc0, 0x6e, 0xec, 0xdc, 0xd4, 0x5a, 0xb5, + 0x32, 0x85, 0x5f, 0x19, 0xd4, 0xf8, 0xd4, 0x3f, 0x3c, 0xfa, 0xc2, 0xf6, + 0x5f, 0xee, 0xe6, 0xba, 0x87, 0x74, 0x2e, 0xc7, 0x0c, 0xd4, 0x42, 0xb8, + 0x66, 0x85, 0x9c, 0x7b, 0x24, 0x61, 0xaa, 0x16, 0x11, 0xf6, 0xb5, 0xb6, + 0xa4, 0x0a, 0xc9, 0x55, 0x2e, 0x81, 0xa5, 0x47, 0x61, 0xcb, 0x25, 0x8f, + 0xc2, 0x15, 0x7b, 0x0e, 0x7c, 0x36, 0x9f, 0x3a, 0xda, 0x58, 0x86, 0x1c, + 0x5b, 0x83, 0x79, 0xe6, 0x2b, 0xcc, 0xe6, 0xfa, 0x2c, 0x61, 0xf2, 0x78, + 0x80, 0x1b, 0xe2, 0xf3, 0x9d, 0x39, 0x2b, 0x65, 0x57, 0x91, 0x3d, 0x71, + 0x99, 0x73, 0xa5, 0xc2, 0x79, 0x20, 0x8c, 0x07, 0x4f, 0xe5, 0xb4, 0x60, + 0x1f, 0x99, 0xa2, 0xb1, 0x4f, 0x0c, 0xef, 0xbc, 0x59, 0x53, 0x00, 0x7d, + 0xb1, 0x02, 0x41, 0x00, 0xfc, 0x7e, 0x23, 0x65, 0x70, 0xf8, 0xce, 0xd3, + 0x40, 0x41, 0x80, 0x6a, 0x1d, 0x01, 0xd6, 0x01, 0xff, 0xb6, 0x1b, 0x3d, + 0x3d, 0x59, 0x09, 0x33, 0x79, 0xc0, 0x4f, 0xde, 0x96, 0x27, 0x4b, 0x18, + 0xc6, 0xd9, 0x78, 0xf1, 0xf4, 0x35, 0x46, 0xe9, 0x7c, 0x42, 0x7a, 0x5d, + 0x9f, 0xef, 0x54, 0xb8, 0xf7, 0x9f, 0xc4, 0x33, 0x6c, 0xf3, 0x8c, 0x32, + 0x46, 0x87, 0x67, 0x30, 0x7b, 0xa7, 0xac, 0xe3, 0x02, 0x41, 0x00, 0xfc, + 0x2c, 0xdf, 0x0c, 0x0d, 0x88, 0xf5, 0xb1, 0x92, 0xa8, 0x93, 0x47, 0x63, + 0x55, 0xf5, 0xca, 0x58, 0x43, 0xba, 0x1c, 0xe5, 0x9e, 0xb6, 0x95, 0x05, + 0xcd, 0xb5, 0x82, 0xdf, 0xeb, 0x04, 0x53, 0x9d, 0xbd, 0xc2, 0x38, 0x16, + 0xb3, 0x62, 0xdd, 0xa1, 0x46, 0xdb, 0x6d, 0x97, 0x93, 0x9f, 0x8a, 0xc3, + 0x9b, 0x64, 0x7e, 0x42, 0xe3, 0x32, 0x57, 0x19, 0x1b, 0xd5, 0x6e, 0x85, + 0xfa, 0xb8, 0x8d, 0x02, 0x41, 0x00, 0xbc, 0x3d, 0xde, 0x6d, 0xd6, 0x97, + 0xe8, 0xba, 0x9e, 0x81, 0x37, 0x17, 0xe5, 0xa0, 0x64, 0xc9, 0x00, 0xb7, + 0xe7, 0xfe, 0xf4, 0x29, 0xd9, 0x2e, 0x43, 0x6b, 0x19, 0x20, 0xbd, 0x99, + 0x75, 0xe7, 0x76, 0xf8, 0xd3, 0xae, 0xaf, 0x7e, 0xb8, 0xeb, 0x81, 0xf4, + 0x9d, 0xfe, 0x07, 0x2b, 0x0b, 0x63, 0x0b, 0x5a, 0x55, 0x90, 0x71, 0x7d, + 0xf1, 0xdb, 0xd9, 0xb1, 0x41, 0x41, 0x68, 0x2f, 0x4e, 0x39, 0x02, 0x40, + 0x5a, 0x34, 0x66, 0xd8, 0xf5, 0xe2, 0x7f, 0x18, 0xb5, 0x00, 0x6e, 0x26, + 0x84, 0x27, 0x14, 0x93, 0xfb, 0xfc, 0xc6, 0x0f, 0x5e, 0x27, 0xe6, 0xe1, + 0xe9, 0xc0, 0x8a, 0xe4, 0x34, 0xda, 0xe9, 0xa2, 0x4b, 0x73, 0xbc, 0x8c, + 0xb9, 0xba, 0x13, 0x6c, 0x7a, 0x2b, 0x51, 0x84, 0xa3, 0x4a, 0xe0, 0x30, + 0x10, 0x06, 0x7e, 0xed, 0x17, 0x5a, 0x14, 0x00, 0xc9, 0xef, 0x85, 0xea, + 0x52, 0x2c, 0xbc, 0x65, 0x02, 0x40, 0x51, 0xe3, 0xf2, 0x83, 0x19, 0x9b, + 0xc4, 0x1e, 0x2f, 0x50, 0x3d, 0xdf, 0x5a, 0xa2, 0x18, 0xca, 0x5f, 0x2e, + 0x49, 0xaf, 0x6f, 0xcc, 0xfa, 0x65, 0x77, 0x94, 0xb5, 0xa1, 0x0a, 0xa9, + 0xd1, 0x8a, 0x39, 0x37, 0xf4, 0x0b, 0xa0, 0xd7, 0x82, 0x27, 0x5e, 0xae, + 0x17, 0x17, 0xa1, 0x1e, 0x54, 0x34, 0xbf, 0x6e, 0xc4, 0x8e, 0x99, 0x5d, + 0x08, 0xf1, 0x2d, 0x86, 0x9d, 0xa5, 0x20, 0x1b, 0xe5, 0xdf, +}; + +#ifndef OPENSSL_NO_EC +/* + * kExampleECKeyDER is a sample EC private key encoded as an ECPrivateKey + * structure. + */ +static const unsigned char kExampleECKeyDER[] = { + 0x30, 0x77, 0x02, 0x01, 0x01, 0x04, 0x20, 0x07, 0x0f, 0x08, 0x72, 0x7a, + 0xd4, 0xa0, 0x4a, 0x9c, 0xdd, 0x59, 0xc9, 0x4d, 0x89, 0x68, 0x77, 0x08, + 0xb5, 0x6f, 0xc9, 0x5d, 0x30, 0x77, 0x0e, 0xe8, 0xd1, 0xc9, 0xce, 0x0a, + 0x8b, 0xb4, 0x6a, 0xa0, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, + 0x03, 0x01, 0x07, 0xa1, 0x44, 0x03, 0x42, 0x00, 0x04, 0xe6, 0x2b, 0x69, + 0xe2, 0xbf, 0x65, 0x9f, 0x97, 0xbe, 0x2f, 0x1e, 0x0d, 0x94, 0x8a, 0x4c, + 0xd5, 0x97, 0x6b, 0xb7, 0xa9, 0x1e, 0x0d, 0x46, 0xfb, 0xdd, 0xa9, 0xa9, + 0x1e, 0x9d, 0xdc, 0xba, 0x5a, 0x01, 0xe7, 0xd6, 0x97, 0xa8, 0x0a, 0x18, + 0xf9, 0xc3, 0xc4, 0xa3, 0x1e, 0x56, 0xe2, 0x7c, 0x83, 0x48, 0xdb, 0x16, + 0x1a, 0x1c, 0xf5, 0x1d, 0x7e, 0xf1, 0x94, 0x2d, 0x4b, 0xcf, 0x72, 0x22, + 0xc1, +}; + +/* + * kExampleBadECKeyDER is a sample EC private key encoded as an ECPrivateKey + * structure. The private key is equal to the order and will fail to import + */ +static const unsigned char kExampleBadECKeyDER[] = { + 0x30, 0x66, 0x02, 0x01, 0x00, 0x30, 0x13, 0x06, 0x07, 0x2A, 0x86, 0x48, + 0xCE, 0x3D, 0x02, 0x01, 0x06, 0x08, 0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, + 0x01, 0x07, 0x04, 0x4C, 0x30, 0x4A, 0x02, 0x01, 0x01, 0x04, 0x20, 0xFF, + 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, 0xF3, + 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51, 0xA1, 0x23, 0x03, 0x21, 0x00, + 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xBC, 0xE6, 0xFA, 0xAD, 0xA7, 0x17, 0x9E, 0x84, + 0xF3, 0xB9, 0xCA, 0xC2, 0xFC, 0x63, 0x25, 0x51 +}; +#endif + +static EVP_PKEY *load_example_rsa_key(void) +{ + EVP_PKEY *ret = NULL; + const unsigned char *derp = kExampleRSAKeyDER; + EVP_PKEY *pkey = NULL; + RSA *rsa = NULL; + + if (!d2i_RSAPrivateKey(&rsa, &derp, sizeof(kExampleRSAKeyDER))) { + return NULL; + } + + pkey = EVP_PKEY_new(); + if (pkey == NULL || !EVP_PKEY_set1_RSA(pkey, rsa)) { + goto out; + } + + ret = pkey; + pkey = NULL; + + out: + if (pkey) { + EVP_PKEY_free(pkey); + } + if (rsa) { + RSA_free(rsa); + } + + return ret; +} + +static int test_EVP_DigestSignInit(void) +{ + int ret = 0; + EVP_PKEY *pkey = NULL; + unsigned char *sig = NULL; + size_t sig_len = 0; + EVP_MD_CTX md_ctx, md_ctx_verify; + + EVP_MD_CTX_init(&md_ctx); + EVP_MD_CTX_init(&md_ctx_verify); + + pkey = load_example_rsa_key(); + if (pkey == NULL || + !EVP_DigestSignInit(&md_ctx, NULL, EVP_sha256(), NULL, pkey) || + !EVP_DigestSignUpdate(&md_ctx, kMsg, sizeof(kMsg))) { + goto out; + } + /* Determine the size of the signature. */ + if (!EVP_DigestSignFinal(&md_ctx, NULL, &sig_len)) { + goto out; + } + /* Sanity check for testing. */ + if (sig_len != (size_t)EVP_PKEY_size(pkey)) { + fprintf(stderr, "sig_len mismatch\n"); + goto out; + } + + sig = OPENSSL_malloc(sig_len); + if (sig == NULL || !EVP_DigestSignFinal(&md_ctx, sig, &sig_len)) { + goto out; + } + + /* Ensure that the signature round-trips. */ + if (!EVP_DigestVerifyInit(&md_ctx_verify, NULL, EVP_sha256(), NULL, pkey) + || !EVP_DigestVerifyUpdate(&md_ctx_verify, kMsg, sizeof(kMsg)) + || !EVP_DigestVerifyFinal(&md_ctx_verify, sig, sig_len)) { + goto out; + } + + ret = 1; + + out: + if (!ret) { + ERR_print_errors_fp(stderr); + } + + EVP_MD_CTX_cleanup(&md_ctx); + EVP_MD_CTX_cleanup(&md_ctx_verify); + if (pkey) { + EVP_PKEY_free(pkey); + } + if (sig) { + OPENSSL_free(sig); + } + + return ret; +} + +static int test_EVP_DigestVerifyInit(void) +{ + int ret = 0; + EVP_PKEY *pkey = NULL; + EVP_MD_CTX md_ctx; + + EVP_MD_CTX_init(&md_ctx); + + pkey = load_example_rsa_key(); + if (pkey == NULL || + !EVP_DigestVerifyInit(&md_ctx, NULL, EVP_sha256(), NULL, pkey) || + !EVP_DigestVerifyUpdate(&md_ctx, kMsg, sizeof(kMsg)) || + !EVP_DigestVerifyFinal(&md_ctx, (unsigned char *)kSignature, sizeof(kSignature))) { + goto out; + } + ret = 1; + + out: + if (!ret) { + ERR_print_errors_fp(stderr); + } + + EVP_MD_CTX_cleanup(&md_ctx); + if (pkey) { + EVP_PKEY_free(pkey); + } + + return ret; +} + +static int test_d2i_AutoPrivateKey(const unsigned char *input, + size_t input_len, int expected_id) +{ + int ret = 0; + const unsigned char *p; + EVP_PKEY *pkey = NULL; + + p = input; + pkey = d2i_AutoPrivateKey(NULL, &p, input_len); + if (pkey == NULL || p != input + input_len) { + fprintf(stderr, "d2i_AutoPrivateKey failed\n"); + goto done; + } + + if (EVP_PKEY_id(pkey) != expected_id) { + fprintf(stderr, "Did not decode expected type\n"); + goto done; + } + + ret = 1; + + done: + if (!ret) { + ERR_print_errors_fp(stderr); + } + + if (pkey != NULL) { + EVP_PKEY_free(pkey); + } + return ret; +} + +#ifndef OPENSSL_NO_EC +/* Tests loading a bad key in PKCS8 format */ +static int test_EVP_PKCS82PKEY(void) +{ + int ret = 0; + const unsigned char *derp = kExampleBadECKeyDER; + PKCS8_PRIV_KEY_INFO *p8inf = NULL; + EVP_PKEY *pkey = NULL; + + p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &derp, sizeof(kExampleBadECKeyDER)); + + if (!p8inf || derp != kExampleBadECKeyDER + sizeof(kExampleBadECKeyDER)) { + fprintf(stderr, "Failed to parse key\n"); + goto done; + } + + pkey = EVP_PKCS82PKEY(p8inf); + if (pkey) { + fprintf(stderr, "Imported invalid EC key\n"); + goto done; + } + + ret = 1; + + done: + if (p8inf != NULL) { + PKCS8_PRIV_KEY_INFO_free(p8inf); + } + + if (pkey != NULL) { + EVP_PKEY_free(pkey); + } + + return ret; +} +#endif + +int main(void) +{ + CRYPTO_malloc_debug_init(); + CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + + ERR_load_crypto_strings(); + /* Load up the software EVP_CIPHER and EVP_MD definitions */ + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); + + if (!test_EVP_DigestSignInit()) { + fprintf(stderr, "EVP_DigestSignInit failed\n"); + return 1; + } + + if (!test_EVP_DigestVerifyInit()) { + fprintf(stderr, "EVP_DigestVerifyInit failed\n"); + return 1; + } + + if (!test_d2i_AutoPrivateKey(kExampleRSAKeyDER, sizeof(kExampleRSAKeyDER), + EVP_PKEY_RSA)) { + fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyDER) failed\n"); + return 1; + } + + if (!test_d2i_AutoPrivateKey + (kExampleRSAKeyPKCS8, sizeof(kExampleRSAKeyPKCS8), EVP_PKEY_RSA)) { + fprintf(stderr, "d2i_AutoPrivateKey(kExampleRSAKeyPKCS8) failed\n"); + return 1; + } + +#ifndef OPENSSL_NO_EC + if (!test_d2i_AutoPrivateKey(kExampleECKeyDER, sizeof(kExampleECKeyDER), + EVP_PKEY_EC)) { + fprintf(stderr, "d2i_AutoPrivateKey(kExampleECKeyDER) failed\n"); + return 1; + } + + if (!test_EVP_PKCS82PKEY()) { + fprintf(stderr, "test_EVP_PKCS82PKEY failed\n"); + return 1; + } +#endif + + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + ERR_free_strings(); + CRYPTO_mem_leaks_fp(stderr); + + printf("PASS\n"); + return 0; +} diff --git a/libs/openssl/crypto/evp/evp_fips.c b/libs/openssl/crypto/evp/evp_fips.c new file mode 100644 index 00000000..71a32fca --- /dev/null +++ b/libs/openssl/crypto/evp/evp_fips.c @@ -0,0 +1,310 @@ +/* crypto/evp/evp_fips.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include + +#ifdef OPENSSL_FIPS +# include + +const EVP_CIPHER *EVP_aes_128_cbc(void) +{ + return FIPS_evp_aes_128_cbc(); +} + +const EVP_CIPHER *EVP_aes_128_ccm(void) +{ + return FIPS_evp_aes_128_ccm(); +} + +const EVP_CIPHER *EVP_aes_128_cfb1(void) +{ + return FIPS_evp_aes_128_cfb1(); +} + +const EVP_CIPHER *EVP_aes_128_cfb128(void) +{ + return FIPS_evp_aes_128_cfb128(); +} + +const EVP_CIPHER *EVP_aes_128_cfb8(void) +{ + return FIPS_evp_aes_128_cfb8(); +} + +const EVP_CIPHER *EVP_aes_128_ctr(void) +{ + return FIPS_evp_aes_128_ctr(); +} + +const EVP_CIPHER *EVP_aes_128_ecb(void) +{ + return FIPS_evp_aes_128_ecb(); +} + +const EVP_CIPHER *EVP_aes_128_gcm(void) +{ + return FIPS_evp_aes_128_gcm(); +} + +const EVP_CIPHER *EVP_aes_128_ofb(void) +{ + return FIPS_evp_aes_128_ofb(); +} + +const EVP_CIPHER *EVP_aes_128_xts(void) +{ + return FIPS_evp_aes_128_xts(); +} + +const EVP_CIPHER *EVP_aes_192_cbc(void) +{ + return FIPS_evp_aes_192_cbc(); +} + +const EVP_CIPHER *EVP_aes_192_ccm(void) +{ + return FIPS_evp_aes_192_ccm(); +} + +const EVP_CIPHER *EVP_aes_192_cfb1(void) +{ + return FIPS_evp_aes_192_cfb1(); +} + +const EVP_CIPHER *EVP_aes_192_cfb128(void) +{ + return FIPS_evp_aes_192_cfb128(); +} + +const EVP_CIPHER *EVP_aes_192_cfb8(void) +{ + return FIPS_evp_aes_192_cfb8(); +} + +const EVP_CIPHER *EVP_aes_192_ctr(void) +{ + return FIPS_evp_aes_192_ctr(); +} + +const EVP_CIPHER *EVP_aes_192_ecb(void) +{ + return FIPS_evp_aes_192_ecb(); +} + +const EVP_CIPHER *EVP_aes_192_gcm(void) +{ + return FIPS_evp_aes_192_gcm(); +} + +const EVP_CIPHER *EVP_aes_192_ofb(void) +{ + return FIPS_evp_aes_192_ofb(); +} + +const EVP_CIPHER *EVP_aes_256_cbc(void) +{ + return FIPS_evp_aes_256_cbc(); +} + +const EVP_CIPHER *EVP_aes_256_ccm(void) +{ + return FIPS_evp_aes_256_ccm(); +} + +const EVP_CIPHER *EVP_aes_256_cfb1(void) +{ + return FIPS_evp_aes_256_cfb1(); +} + +const EVP_CIPHER *EVP_aes_256_cfb128(void) +{ + return FIPS_evp_aes_256_cfb128(); +} + +const EVP_CIPHER *EVP_aes_256_cfb8(void) +{ + return FIPS_evp_aes_256_cfb8(); +} + +const EVP_CIPHER *EVP_aes_256_ctr(void) +{ + return FIPS_evp_aes_256_ctr(); +} + +const EVP_CIPHER *EVP_aes_256_ecb(void) +{ + return FIPS_evp_aes_256_ecb(); +} + +const EVP_CIPHER *EVP_aes_256_gcm(void) +{ + return FIPS_evp_aes_256_gcm(); +} + +const EVP_CIPHER *EVP_aes_256_ofb(void) +{ + return FIPS_evp_aes_256_ofb(); +} + +const EVP_CIPHER *EVP_aes_256_xts(void) +{ + return FIPS_evp_aes_256_xts(); +} + +const EVP_CIPHER *EVP_des_ede(void) +{ + return FIPS_evp_des_ede(); +} + +const EVP_CIPHER *EVP_des_ede3(void) +{ + return FIPS_evp_des_ede3(); +} + +const EVP_CIPHER *EVP_des_ede3_cbc(void) +{ + return FIPS_evp_des_ede3_cbc(); +} + +const EVP_CIPHER *EVP_des_ede3_cfb1(void) +{ + return FIPS_evp_des_ede3_cfb1(); +} + +const EVP_CIPHER *EVP_des_ede3_cfb64(void) +{ + return FIPS_evp_des_ede3_cfb64(); +} + +const EVP_CIPHER *EVP_des_ede3_cfb8(void) +{ + return FIPS_evp_des_ede3_cfb8(); +} + +const EVP_CIPHER *EVP_des_ede3_ecb(void) +{ + return FIPS_evp_des_ede3_ecb(); +} + +const EVP_CIPHER *EVP_des_ede3_ofb(void) +{ + return FIPS_evp_des_ede3_ofb(); +} + +const EVP_CIPHER *EVP_des_ede_cbc(void) +{ + return FIPS_evp_des_ede_cbc(); +} + +const EVP_CIPHER *EVP_des_ede_cfb64(void) +{ + return FIPS_evp_des_ede_cfb64(); +} + +const EVP_CIPHER *EVP_des_ede_ecb(void) +{ + return FIPS_evp_des_ede_ecb(); +} + +const EVP_CIPHER *EVP_des_ede_ofb(void) +{ + return FIPS_evp_des_ede_ofb(); +} + +const EVP_CIPHER *EVP_enc_null(void) +{ + return FIPS_evp_enc_null(); +} + +const EVP_MD *EVP_sha1(void) +{ + return FIPS_evp_sha1(); +} + +const EVP_MD *EVP_sha224(void) +{ + return FIPS_evp_sha224(); +} + +const EVP_MD *EVP_sha256(void) +{ + return FIPS_evp_sha256(); +} + +const EVP_MD *EVP_sha384(void) +{ + return FIPS_evp_sha384(); +} + +const EVP_MD *EVP_sha512(void) +{ + return FIPS_evp_sha512(); +} + +const EVP_MD *EVP_dss(void) +{ + return FIPS_evp_dss(); +} + +const EVP_MD *EVP_dss1(void) +{ + return FIPS_evp_dss1(); +} + +const EVP_MD *EVP_ecdsa(void) +{ + return FIPS_evp_ecdsa(); +} + +#endif diff --git a/libs/openssl/crypto/evp/evp_key.c b/libs/openssl/crypto/evp/evp_key.c new file mode 100644 index 00000000..5be9e336 --- /dev/null +++ b/libs/openssl/crypto/evp/evp_key.c @@ -0,0 +1,195 @@ +/* crypto/evp/evp_key.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +/* should be init to zeros. */ +static char prompt_string[80]; + +void EVP_set_pw_prompt(const char *prompt) +{ + if (prompt == NULL) + prompt_string[0] = '\0'; + else { + strncpy(prompt_string, prompt, 79); + prompt_string[79] = '\0'; + } +} + +char *EVP_get_pw_prompt(void) +{ + if (prompt_string[0] == '\0') + return (NULL); + else + return (prompt_string); +} + +/* + * For historical reasons, the standard function for reading passwords is in + * the DES library -- if someone ever wants to disable DES, this function + * will fail + */ +int EVP_read_pw_string(char *buf, int len, const char *prompt, int verify) +{ + return EVP_read_pw_string_min(buf, 0, len, prompt, verify); +} + +int EVP_read_pw_string_min(char *buf, int min, int len, const char *prompt, + int verify) +{ + int ret; + char buff[BUFSIZ]; + UI *ui; + + if ((prompt == NULL) && (prompt_string[0] != '\0')) + prompt = prompt_string; + ui = UI_new(); + if (ui == NULL) + return -1; + UI_add_input_string(ui, prompt, 0, buf, min, + (len >= BUFSIZ) ? BUFSIZ - 1 : len); + if (verify) + UI_add_verify_string(ui, prompt, 0, + buff, min, (len >= BUFSIZ) ? BUFSIZ - 1 : len, + buf); + ret = UI_process(ui); + UI_free(ui); + OPENSSL_cleanse(buff, BUFSIZ); + return ret; +} + +int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const unsigned char *salt, const unsigned char *data, + int datal, int count, unsigned char *key, + unsigned char *iv) +{ + EVP_MD_CTX c; + unsigned char md_buf[EVP_MAX_MD_SIZE]; + int niv, nkey, addmd = 0; + unsigned int mds = 0, i; + int rv = 0; + nkey = type->key_len; + niv = type->iv_len; + OPENSSL_assert(nkey <= EVP_MAX_KEY_LENGTH); + OPENSSL_assert(niv <= EVP_MAX_IV_LENGTH); + + if (data == NULL) + return (nkey); + + EVP_MD_CTX_init(&c); + for (;;) { + if (!EVP_DigestInit_ex(&c, md, NULL)) + goto err; + if (addmd++) + if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds)) + goto err; + if (!EVP_DigestUpdate(&c, data, datal)) + goto err; + if (salt != NULL) + if (!EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN)) + goto err; + if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds)) + goto err; + + for (i = 1; i < (unsigned int)count; i++) { + if (!EVP_DigestInit_ex(&c, md, NULL)) + goto err; + if (!EVP_DigestUpdate(&c, &(md_buf[0]), mds)) + goto err; + if (!EVP_DigestFinal_ex(&c, &(md_buf[0]), &mds)) + goto err; + } + i = 0; + if (nkey) { + for (;;) { + if (nkey == 0) + break; + if (i == mds) + break; + if (key != NULL) + *(key++) = md_buf[i]; + nkey--; + i++; + } + } + if (niv && (i != mds)) { + for (;;) { + if (niv == 0) + break; + if (i == mds) + break; + if (iv != NULL) + *(iv++) = md_buf[i]; + niv--; + i++; + } + } + if ((nkey == 0) && (niv == 0)) + break; + } + rv = type->key_len; + err: + EVP_MD_CTX_cleanup(&c); + OPENSSL_cleanse(md_buf, sizeof(md_buf)); + return rv; +} diff --git a/libs/openssl/crypto/evp/evp_lib.c b/libs/openssl/crypto/evp/evp_lib.c new file mode 100644 index 00000000..b16d623a --- /dev/null +++ b/libs/openssl/crypto/evp/evp_lib.c @@ -0,0 +1,336 @@ +/* crypto/evp/evp_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +int EVP_CIPHER_param_to_asn1(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int ret; + + if (c->cipher->set_asn1_parameters != NULL) + ret = c->cipher->set_asn1_parameters(c, type); + else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) { + switch (EVP_CIPHER_CTX_mode(c)) { + + case EVP_CIPH_GCM_MODE: + case EVP_CIPH_CCM_MODE: + case EVP_CIPH_XTS_MODE: + ret = -1; + break; + + default: + ret = EVP_CIPHER_set_asn1_iv(c, type); + } + } else + ret = -1; + return (ret); +} + +int EVP_CIPHER_asn1_to_param(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int ret; + + if (c->cipher->get_asn1_parameters != NULL) + ret = c->cipher->get_asn1_parameters(c, type); + else if (c->cipher->flags & EVP_CIPH_FLAG_DEFAULT_ASN1) { + switch (EVP_CIPHER_CTX_mode(c)) { + + case EVP_CIPH_GCM_MODE: + case EVP_CIPH_CCM_MODE: + case EVP_CIPH_XTS_MODE: + ret = -1; + break; + + default: + ret = EVP_CIPHER_get_asn1_iv(c, type); + break; + } + } else + ret = -1; + return (ret); +} + +int EVP_CIPHER_get_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int i = 0; + unsigned int l; + + if (type != NULL) { + l = EVP_CIPHER_CTX_iv_length(c); + OPENSSL_assert(l <= sizeof(c->iv)); + i = ASN1_TYPE_get_octetstring(type, c->oiv, l); + if (i != (int)l) + return (-1); + else if (i > 0) + memcpy(c->iv, c->oiv, l); + } + return (i); +} + +int EVP_CIPHER_set_asn1_iv(EVP_CIPHER_CTX *c, ASN1_TYPE *type) +{ + int i = 0; + unsigned int j; + + if (type != NULL) { + j = EVP_CIPHER_CTX_iv_length(c); + OPENSSL_assert(j <= sizeof(c->iv)); + i = ASN1_TYPE_set_octetstring(type, c->oiv, j); + } + return (i); +} + +/* Convert the various cipher NIDs and dummies to a proper OID NID */ +int EVP_CIPHER_type(const EVP_CIPHER *ctx) +{ + int nid; + ASN1_OBJECT *otmp; + nid = EVP_CIPHER_nid(ctx); + + switch (nid) { + + case NID_rc2_cbc: + case NID_rc2_64_cbc: + case NID_rc2_40_cbc: + + return NID_rc2_cbc; + + case NID_rc4: + case NID_rc4_40: + + return NID_rc4; + + case NID_aes_128_cfb128: + case NID_aes_128_cfb8: + case NID_aes_128_cfb1: + + return NID_aes_128_cfb128; + + case NID_aes_192_cfb128: + case NID_aes_192_cfb8: + case NID_aes_192_cfb1: + + return NID_aes_192_cfb128; + + case NID_aes_256_cfb128: + case NID_aes_256_cfb8: + case NID_aes_256_cfb1: + + return NID_aes_256_cfb128; + + case NID_des_cfb64: + case NID_des_cfb8: + case NID_des_cfb1: + + return NID_des_cfb64; + + case NID_des_ede3_cfb64: + case NID_des_ede3_cfb8: + case NID_des_ede3_cfb1: + + return NID_des_cfb64; + + default: + /* Check it has an OID and it is valid */ + otmp = OBJ_nid2obj(nid); + if (!otmp || !otmp->data) + nid = NID_undef; + ASN1_OBJECT_free(otmp); + return nid; + } +} + +int EVP_CIPHER_block_size(const EVP_CIPHER *e) +{ + return e->block_size; +} + +int EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher->block_size; +} + +int EVP_Cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) +{ + return ctx->cipher->do_cipher(ctx, out, in, inl); +} + +const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher; +} + +unsigned long EVP_CIPHER_flags(const EVP_CIPHER *cipher) +{ + return cipher->flags; +} + +unsigned long EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher->flags; +} + +void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx) +{ + return ctx->app_data; +} + +void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, void *data) +{ + ctx->app_data = data; +} + +int EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) +{ + return cipher->iv_len; +} + +int EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher->iv_len; +} + +int EVP_CIPHER_key_length(const EVP_CIPHER *cipher) +{ + return cipher->key_len; +} + +int EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) +{ + return ctx->key_len; +} + +int EVP_CIPHER_nid(const EVP_CIPHER *cipher) +{ + return cipher->nid; +} + +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) +{ + return ctx->cipher->nid; +} + +int EVP_MD_block_size(const EVP_MD *md) +{ + return md->block_size; +} + +int EVP_MD_type(const EVP_MD *md) +{ + return md->type; +} + +int EVP_MD_pkey_type(const EVP_MD *md) +{ + return md->pkey_type; +} + +int EVP_MD_size(const EVP_MD *md) +{ + if (!md) { + EVPerr(EVP_F_EVP_MD_SIZE, EVP_R_MESSAGE_DIGEST_IS_NULL); + return -1; + } + return md->md_size; +} + +unsigned long EVP_MD_flags(const EVP_MD *md) +{ + return md->flags; +} + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx) +{ + if (!ctx) + return NULL; + return ctx->digest; +} + +void EVP_MD_CTX_set_flags(EVP_MD_CTX *ctx, int flags) +{ + ctx->flags |= flags; +} + +void EVP_MD_CTX_clear_flags(EVP_MD_CTX *ctx, int flags) +{ + ctx->flags &= ~flags; +} + +int EVP_MD_CTX_test_flags(const EVP_MD_CTX *ctx, int flags) +{ + return (ctx->flags & flags); +} + +void EVP_CIPHER_CTX_set_flags(EVP_CIPHER_CTX *ctx, int flags) +{ + ctx->flags |= flags; +} + +void EVP_CIPHER_CTX_clear_flags(EVP_CIPHER_CTX *ctx, int flags) +{ + ctx->flags &= ~flags; +} + +int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags) +{ + return (ctx->flags & flags); +} diff --git a/libs/openssl/crypto/evp/evp_locl.h b/libs/openssl/crypto/evp/evp_locl.h new file mode 100644 index 00000000..980dadab --- /dev/null +++ b/libs/openssl/crypto/evp/evp_locl.h @@ -0,0 +1,370 @@ +/* evp_locl.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Macros to code block cipher wrappers */ + +/* Wrapper functions for each cipher mode */ + +#define BLOCK_CIPHER_ecb_loop() \ + size_t i, bl; \ + bl = ctx->cipher->block_size;\ + if(inl < bl) return 1;\ + inl -= bl; \ + for(i=0; i <= inl; i+=bl) + +#define BLOCK_CIPHER_func_ecb(cname, cprefix, kstruct, ksched) \ +static int cname##_ecb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ +{\ + BLOCK_CIPHER_ecb_loop() \ + cprefix##_ecb_encrypt(in + i, out + i, &((kstruct *)ctx->cipher_data)->ksched, ctx->encrypt);\ + return 1;\ +} + +#define EVP_MAXCHUNK ((size_t)1<<(sizeof(long)*8-2)) + +#define BLOCK_CIPHER_func_ofb(cname, cprefix, cbits, kstruct, ksched) \ +static int cname##_ofb_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ +{\ + while(inl>=EVP_MAXCHUNK)\ + {\ + cprefix##_ofb##cbits##_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\ + inl-=EVP_MAXCHUNK;\ + in +=EVP_MAXCHUNK;\ + out+=EVP_MAXCHUNK;\ + }\ + if (inl)\ + cprefix##_ofb##cbits##_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num);\ + return 1;\ +} + +#define BLOCK_CIPHER_func_cbc(cname, cprefix, kstruct, ksched) \ +static int cname##_cbc_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ +{\ + while(inl>=EVP_MAXCHUNK) \ + {\ + cprefix##_cbc_encrypt(in, out, (long)EVP_MAXCHUNK, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\ + inl-=EVP_MAXCHUNK;\ + in +=EVP_MAXCHUNK;\ + out+=EVP_MAXCHUNK;\ + }\ + if (inl)\ + cprefix##_cbc_encrypt(in, out, (long)inl, &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, ctx->encrypt);\ + return 1;\ +} + +#define BLOCK_CIPHER_func_cfb(cname, cprefix, cbits, kstruct, ksched) \ +static int cname##_cfb##cbits##_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, const unsigned char *in, size_t inl) \ +{\ + size_t chunk=EVP_MAXCHUNK;\ + if (cbits==1) chunk>>=3;\ + if (inl=chunk)\ + {\ + cprefix##_cfb##cbits##_encrypt(in, out, (long)((cbits==1) && !(ctx->flags & EVP_CIPH_FLAG_LENGTH_BITS) ?inl*8:inl), &((kstruct *)ctx->cipher_data)->ksched, ctx->iv, &ctx->num, ctx->encrypt);\ + inl-=chunk;\ + in +=chunk;\ + out+=chunk;\ + if(inlc))+\ + sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ + set_asn1, get_asn1,\ + ctrl, \ + NULL \ +};\ +const EVP_CIPHER *EVP_##cname##_cbc(void) { return &cname##_cbc; }\ +static const EVP_CIPHER cname##_cfb = {\ + nid##_cfb64, 1, key_len, iv_len, \ + flags | EVP_CIPH_CFB_MODE,\ + init_key,\ + cname##_cfb_cipher,\ + cleanup,\ + sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\ + sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ + set_asn1, get_asn1,\ + ctrl,\ + NULL \ +};\ +const EVP_CIPHER *EVP_##cname##_cfb(void) { return &cname##_cfb; }\ +static const EVP_CIPHER cname##_ofb = {\ + nid##_ofb64, 1, key_len, iv_len, \ + flags | EVP_CIPH_OFB_MODE,\ + init_key,\ + cname##_ofb_cipher,\ + cleanup,\ + sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\ + sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ + set_asn1, get_asn1,\ + ctrl,\ + NULL \ +};\ +const EVP_CIPHER *EVP_##cname##_ofb(void) { return &cname##_ofb; }\ +static const EVP_CIPHER cname##_ecb = {\ + nid##_ecb, block_size, key_len, iv_len, \ + flags | EVP_CIPH_ECB_MODE,\ + init_key,\ + cname##_ecb_cipher,\ + cleanup,\ + sizeof(EVP_CIPHER_CTX)-sizeof((((EVP_CIPHER_CTX *)NULL)->c))+\ + sizeof((((EVP_CIPHER_CTX *)NULL)->c.kstruct)),\ + set_asn1, get_asn1,\ + ctrl,\ + NULL \ +};\ +const EVP_CIPHER *EVP_##cname##_ecb(void) { return &cname##_ecb; } +*/ + +#define IMPLEMENT_BLOCK_CIPHER(cname, ksched, cprefix, kstruct, nid, \ + block_size, key_len, iv_len, cbits, \ + flags, init_key, \ + cleanup, set_asn1, get_asn1, ctrl) \ + BLOCK_CIPHER_all_funcs(cname, cprefix, cbits, kstruct, ksched) \ + BLOCK_CIPHER_defs(cname, kstruct, nid, block_size, key_len, iv_len, \ + cbits, flags, init_key, cleanup, set_asn1, \ + get_asn1, ctrl) + +#define EVP_C_DATA(kstruct, ctx) ((kstruct *)(ctx)->cipher_data) + +#define IMPLEMENT_CFBR(cipher,cprefix,kstruct,ksched,keysize,cbits,iv_len) \ + BLOCK_CIPHER_func_cfb(cipher##_##keysize,cprefix,cbits,kstruct,ksched) \ + BLOCK_CIPHER_def_cfb(cipher##_##keysize,kstruct, \ + NID_##cipher##_##keysize, keysize/8, iv_len, cbits, \ + 0, cipher##_init_key, NULL, \ + EVP_CIPHER_set_asn1_iv, \ + EVP_CIPHER_get_asn1_iv, \ + NULL) + +struct evp_pkey_ctx_st { + /* Method associated with this operation */ + const EVP_PKEY_METHOD *pmeth; + /* Engine that implements this method or NULL if builtin */ + ENGINE *engine; + /* Key: may be NULL */ + EVP_PKEY *pkey; + /* Peer key for key agreement, may be NULL */ + EVP_PKEY *peerkey; + /* Actual operation */ + int operation; + /* Algorithm specific data */ + void *data; + /* Application specific data */ + void *app_data; + /* Keygen callback */ + EVP_PKEY_gen_cb *pkey_gencb; + /* implementation specific keygen data */ + int *keygen_info; + int keygen_info_count; +} /* EVP_PKEY_CTX */ ; + +#define EVP_PKEY_FLAG_DYNAMIC 1 + +struct evp_pkey_method_st { + int pkey_id; + int flags; + int (*init) (EVP_PKEY_CTX *ctx); + int (*copy) (EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src); + void (*cleanup) (EVP_PKEY_CTX *ctx); + int (*paramgen_init) (EVP_PKEY_CTX *ctx); + int (*paramgen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + int (*keygen_init) (EVP_PKEY_CTX *ctx); + int (*keygen) (EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + int (*sign_init) (EVP_PKEY_CTX *ctx); + int (*sign) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen); + int (*verify_init) (EVP_PKEY_CTX *ctx); + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen); + int (*verify_recover_init) (EVP_PKEY_CTX *ctx); + int (*verify_recover) (EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen); + int (*signctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + int (*signctx) (EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx); + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx); + int (*verifyctx) (EVP_PKEY_CTX *ctx, const unsigned char *sig, int siglen, + EVP_MD_CTX *mctx); + int (*encrypt_init) (EVP_PKEY_CTX *ctx); + int (*encrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + int (*decrypt_init) (EVP_PKEY_CTX *ctx); + int (*decrypt) (EVP_PKEY_CTX *ctx, unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen); + int (*derive_init) (EVP_PKEY_CTX *ctx); + int (*derive) (EVP_PKEY_CTX *ctx, unsigned char *key, size_t *keylen); + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, void *p2); + int (*ctrl_str) (EVP_PKEY_CTX *ctx, const char *type, const char *value); +} /* EVP_PKEY_METHOD */ ; + +void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx); + +int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *c, const EVP_MD *md, + int en_de); + +#ifdef OPENSSL_FIPS + +# ifdef OPENSSL_DOING_MAKEDEPEND +# undef SHA1_Init +# undef SHA1_Update +# undef SHA224_Init +# undef SHA256_Init +# undef SHA384_Init +# undef SHA512_Init +# undef DES_set_key_unchecked +# endif + +# define RIPEMD160_Init private_RIPEMD160_Init +# define WHIRLPOOL_Init private_WHIRLPOOL_Init +# define MD5_Init private_MD5_Init +# define MD4_Init private_MD4_Init +# define MD2_Init private_MD2_Init +# define MDC2_Init private_MDC2_Init +# define SHA_Init private_SHA_Init +# define SHA1_Init private_SHA1_Init +# define SHA224_Init private_SHA224_Init +# define SHA256_Init private_SHA256_Init +# define SHA384_Init private_SHA384_Init +# define SHA512_Init private_SHA512_Init + +# define BF_set_key private_BF_set_key +# define CAST_set_key private_CAST_set_key +# define idea_set_encrypt_key private_idea_set_encrypt_key +# define SEED_set_key private_SEED_set_key +# define RC2_set_key private_RC2_set_key +# define RC4_set_key private_RC4_set_key +# define DES_set_key_unchecked private_DES_set_key_unchecked +# define Camellia_set_key private_Camellia_set_key + +#endif diff --git a/libs/openssl/crypto/evp/evp_pbe.c b/libs/openssl/crypto/evp/evp_pbe.c new file mode 100644 index 00000000..7934c95f --- /dev/null +++ b/libs/openssl/crypto/evp/evp_pbe.c @@ -0,0 +1,312 @@ +/* evp_pbe.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include "evp_locl.h" + +/* Password based encryption (PBE) functions */ + +DECLARE_STACK_OF(EVP_PBE_CTL) +static STACK_OF(EVP_PBE_CTL) *pbe_algs; + +/* Setup a cipher context from a PBE algorithm */ + +typedef struct { + int pbe_type; + int pbe_nid; + int cipher_nid; + int md_nid; + EVP_PBE_KEYGEN *keygen; +} EVP_PBE_CTL; + +static const EVP_PBE_CTL builtin_pbe[] = { + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndDES_CBC, + NID_des_cbc, NID_md2, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndDES_CBC, + NID_des_cbc, NID_md5, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndRC2_CBC, + NID_rc2_64_cbc, NID_sha1, PKCS5_PBE_keyivgen}, + +#ifndef OPENSSL_NO_HMAC + {EVP_PBE_TYPE_OUTER, NID_id_pbkdf2, -1, -1, PKCS5_v2_PBKDF2_keyivgen}, +#endif + + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC4, + NID_rc4, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC4, + NID_rc4_40, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And3_Key_TripleDES_CBC, + NID_des_ede3_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And2_Key_TripleDES_CBC, + NID_des_ede_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And128BitRC2_CBC, + NID_rc2_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbe_WithSHA1And40BitRC2_CBC, + NID_rc2_40_cbc, NID_sha1, PKCS12_PBE_keyivgen}, + +#ifndef OPENSSL_NO_HMAC + {EVP_PBE_TYPE_OUTER, NID_pbes2, -1, -1, PKCS5_v2_PBE_keyivgen}, +#endif + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD2AndRC2_CBC, + NID_rc2_64_cbc, NID_md2, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithMD5AndRC2_CBC, + NID_rc2_64_cbc, NID_md5, PKCS5_PBE_keyivgen}, + {EVP_PBE_TYPE_OUTER, NID_pbeWithSHA1AndDES_CBC, + NID_des_cbc, NID_sha1, PKCS5_PBE_keyivgen}, + + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA1, -1, NID_sha1, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithMD5, -1, NID_md5, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA224, -1, NID_sha224, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA256, -1, NID_sha256, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA384, -1, NID_sha384, 0}, + {EVP_PBE_TYPE_PRF, NID_hmacWithSHA512, -1, NID_sha512, 0}, + {EVP_PBE_TYPE_PRF, NID_id_HMACGostR3411_94, -1, NID_id_GostR3411_94, 0}, +}; + +#ifdef TEST +int main(int argc, char **argv) +{ + int i, nid_md, nid_cipher; + EVP_PBE_CTL *tpbe, *tpbe2; + /* + * OpenSSL_add_all_algorithms(); + */ + + for (i = 0; i < sizeof(builtin_pbe) / sizeof(EVP_PBE_CTL); i++) { + tpbe = builtin_pbe + i; + fprintf(stderr, "%d %d %s ", tpbe->pbe_type, tpbe->pbe_nid, + OBJ_nid2sn(tpbe->pbe_nid)); + if (EVP_PBE_find(tpbe->pbe_type, tpbe->pbe_nid, + &nid_cipher, &nid_md, 0)) + fprintf(stderr, "Found %s %s\n", + OBJ_nid2sn(nid_cipher), OBJ_nid2sn(nid_md)); + else + fprintf(stderr, "Find ERROR!!\n"); + } + + return 0; +} +#endif + +int EVP_PBE_CipherInit(ASN1_OBJECT *pbe_obj, const char *pass, int passlen, + ASN1_TYPE *param, EVP_CIPHER_CTX *ctx, int en_de) +{ + const EVP_CIPHER *cipher; + const EVP_MD *md; + int cipher_nid, md_nid; + EVP_PBE_KEYGEN *keygen; + + if (!EVP_PBE_find(EVP_PBE_TYPE_OUTER, OBJ_obj2nid(pbe_obj), + &cipher_nid, &md_nid, &keygen)) { + char obj_tmp[80]; + EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_PBE_ALGORITHM); + if (!pbe_obj) + BUF_strlcpy(obj_tmp, "NULL", sizeof obj_tmp); + else + i2t_ASN1_OBJECT(obj_tmp, sizeof obj_tmp, pbe_obj); + ERR_add_error_data(2, "TYPE=", obj_tmp); + return 0; + } + + if (!pass) + passlen = 0; + else if (passlen == -1) + passlen = strlen(pass); + + if (cipher_nid == -1) + cipher = NULL; + else { + cipher = EVP_get_cipherbynid(cipher_nid); + if (!cipher) { + EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_CIPHER); + return 0; + } + } + + if (md_nid == -1) + md = NULL; + else { + md = EVP_get_digestbynid(md_nid); + if (!md) { + EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_UNKNOWN_DIGEST); + return 0; + } + } + + if (!keygen(ctx, pass, passlen, param, cipher, md, en_de)) { + EVPerr(EVP_F_EVP_PBE_CIPHERINIT, EVP_R_KEYGEN_FAILURE); + return 0; + } + return 1; +} + +DECLARE_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); + +static int pbe2_cmp(const EVP_PBE_CTL *pbe1, const EVP_PBE_CTL *pbe2) +{ + int ret = pbe1->pbe_type - pbe2->pbe_type; + if (ret) + return ret; + else + return pbe1->pbe_nid - pbe2->pbe_nid; +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(EVP_PBE_CTL, EVP_PBE_CTL, pbe2); + +static int pbe_cmp(const EVP_PBE_CTL *const *a, const EVP_PBE_CTL *const *b) +{ + int ret = (*a)->pbe_type - (*b)->pbe_type; + if (ret) + return ret; + else + return (*a)->pbe_nid - (*b)->pbe_nid; +} + +/* Add a PBE algorithm */ + +int EVP_PBE_alg_add_type(int pbe_type, int pbe_nid, int cipher_nid, + int md_nid, EVP_PBE_KEYGEN *keygen) +{ + EVP_PBE_CTL *pbe_tmp; + + if (pbe_algs == NULL) { + pbe_algs = sk_EVP_PBE_CTL_new(pbe_cmp); + if (pbe_algs == NULL) + goto err; + } + + if ((pbe_tmp = OPENSSL_malloc(sizeof(*pbe_tmp))) == NULL) + goto err; + + pbe_tmp->pbe_type = pbe_type; + pbe_tmp->pbe_nid = pbe_nid; + pbe_tmp->cipher_nid = cipher_nid; + pbe_tmp->md_nid = md_nid; + pbe_tmp->keygen = keygen; + + sk_EVP_PBE_CTL_push(pbe_algs, pbe_tmp); + return 1; + + err: + EVPerr(EVP_F_EVP_PBE_ALG_ADD_TYPE, ERR_R_MALLOC_FAILURE); + return 0; +} + +int EVP_PBE_alg_add(int nid, const EVP_CIPHER *cipher, const EVP_MD *md, + EVP_PBE_KEYGEN *keygen) +{ + int cipher_nid, md_nid; + if (cipher) + cipher_nid = EVP_CIPHER_nid(cipher); + else + cipher_nid = -1; + if (md) + md_nid = EVP_MD_type(md); + else + md_nid = -1; + + return EVP_PBE_alg_add_type(EVP_PBE_TYPE_OUTER, nid, + cipher_nid, md_nid, keygen); +} + +int EVP_PBE_find(int type, int pbe_nid, + int *pcnid, int *pmnid, EVP_PBE_KEYGEN **pkeygen) +{ + EVP_PBE_CTL *pbetmp = NULL, pbelu; + int i; + if (pbe_nid == NID_undef) + return 0; + + pbelu.pbe_type = type; + pbelu.pbe_nid = pbe_nid; + + if (pbe_algs) { + i = sk_EVP_PBE_CTL_find(pbe_algs, &pbelu); + if (i != -1) + pbetmp = sk_EVP_PBE_CTL_value(pbe_algs, i); + } + if (pbetmp == NULL) { + pbetmp = OBJ_bsearch_pbe2(&pbelu, builtin_pbe, + sizeof(builtin_pbe) / sizeof(EVP_PBE_CTL)); + } + if (pbetmp == NULL) + return 0; + if (pcnid) + *pcnid = pbetmp->cipher_nid; + if (pmnid) + *pmnid = pbetmp->md_nid; + if (pkeygen) + *pkeygen = pbetmp->keygen; + return 1; +} + +static void free_evp_pbe_ctl(EVP_PBE_CTL *pbe) +{ + OPENSSL_freeFunc(pbe); +} + +void EVP_PBE_cleanup(void) +{ + sk_EVP_PBE_CTL_pop_free(pbe_algs, free_evp_pbe_ctl); + pbe_algs = NULL; +} diff --git a/libs/openssl/crypto/evp/evp_pkey.c b/libs/openssl/crypto/evp/evp_pkey.c new file mode 100644 index 00000000..6a456297 --- /dev/null +++ b/libs/openssl/crypto/evp/evp_pkey.c @@ -0,0 +1,229 @@ +/* evp_pkey.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include "asn1_locl.h" + +/* Extract a private key from a PKCS8 structure */ + +EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) +{ + EVP_PKEY *pkey = NULL; + ASN1_OBJECT *algoid; + char obj_tmp[80]; + + if (!PKCS8_pkey_get0(&algoid, NULL, NULL, NULL, p8)) + return NULL; + + if (!(pkey = EVP_PKEY_new())) { + EVPerr(EVP_F_EVP_PKCS82PKEY, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!EVP_PKEY_set_type(pkey, OBJ_obj2nid(algoid))) { + EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); + i2t_ASN1_OBJECT(obj_tmp, 80, algoid); + ERR_add_error_data(2, "TYPE=", obj_tmp); + goto error; + } + + if (pkey->ameth->priv_decode) { + if (!pkey->ameth->priv_decode(pkey, p8)) { + EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_PRIVATE_KEY_DECODE_ERROR); + goto error; + } + } else { + EVPerr(EVP_F_EVP_PKCS82PKEY, EVP_R_METHOD_NOT_SUPPORTED); + goto error; + } + + return pkey; + + error: + EVP_PKEY_free(pkey); + return NULL; +} + +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) +{ + return EVP_PKEY2PKCS8_broken(pkey, PKCS8_OK); +} + +/* Turn a private key into a PKCS8 structure */ + +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken) +{ + PKCS8_PRIV_KEY_INFO *p8; + + if (!(p8 = PKCS8_PRIV_KEY_INFO_new())) { + EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, ERR_R_MALLOC_FAILURE); + return NULL; + } + p8->broken = broken; + + if (pkey->ameth) { + if (pkey->ameth->priv_encode) { + if (!pkey->ameth->priv_encode(p8, pkey)) { + EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, + EVP_R_PRIVATE_KEY_ENCODE_ERROR); + goto error; + } + } else { + EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, EVP_R_METHOD_NOT_SUPPORTED); + goto error; + } + } else { + EVPerr(EVP_F_EVP_PKEY2PKCS8_BROKEN, + EVP_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM); + goto error; + } + RAND_add(p8->pkey->value.octet_string->data, + p8->pkey->value.octet_string->length, 0.0); + return p8; + error: + PKCS8_PRIV_KEY_INFO_free(p8); + return NULL; +} + +PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken) +{ + switch (broken) { + + case PKCS8_OK: + p8->broken = PKCS8_OK; + return p8; + break; + + case PKCS8_NO_OCTET: + p8->broken = PKCS8_NO_OCTET; + p8->pkey->type = V_ASN1_SEQUENCE; + return p8; + break; + + default: + EVPerr(EVP_F_PKCS8_SET_BROKEN, EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE); + return NULL; + } +} + +/* EVP_PKEY attribute functions */ + +int EVP_PKEY_get_attr_count(const EVP_PKEY *key) +{ + return X509at_get_attr_count(key->attributes); +} + +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos) +{ + return X509at_get_attr_by_NID(key->attributes, nid, lastpos); +} + +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(key->attributes, obj, lastpos); +} + +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc) +{ + return X509at_get_attr(key->attributes, loc); +} + +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc) +{ + return X509at_delete_attr(key->attributes, loc); +} + +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr) +{ + if (X509at_add1_attr(&key->attributes, attr)) + return 1; + return 0; +} + +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_OBJ(&key->attributes, obj, type, bytes, len)) + return 1; + return 0; +} + +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, + int nid, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&key->attributes, nid, type, bytes, len)) + return 1; + return 0; +} + +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, + const char *attrname, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&key->attributes, attrname, type, bytes, len)) + return 1; + return 0; +} diff --git a/libs/openssl/crypto/evp/evp_test.c b/libs/openssl/crypto/evp/evp_test.c new file mode 100644 index 00000000..d06b4ee5 --- /dev/null +++ b/libs/openssl/crypto/evp/evp_test.c @@ -0,0 +1,424 @@ +/* Written by Ben Laurie, 2001 */ +/* + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include + +#include "../e_os.h" + +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include +#include + +static void hexdump(FILE *f, const char *title, const unsigned char *s, int l) +{ + int n = 0; + + fprintf(f, "%s", title); + for (; n < l; ++n) { + if ((n % 16) == 0) + fprintf(f, "\n%04x", n); + fprintf(f, " %02x", s[n]); + } + fprintf(f, "\n"); +} + +static int convert(unsigned char *s) +{ + unsigned char *d; + + for (d = s; *s; s += 2, ++d) { + unsigned int n; + + if (!s[1]) { + fprintf(stderr, "Odd number of hex digits!"); + EXIT(4); + } + sscanf((char *)s, "%2x", &n); + *d = (unsigned char)n; + } + return s - d; +} + +static char *sstrsep(char **string, const char *delim) +{ + char isdelim[256]; + char *token = *string; + + if (**string == 0) + return NULL; + + memset(isdelim, 0, 256); + isdelim[0] = 1; + + while (*delim) { + isdelim[(unsigned char)(*delim)] = 1; + delim++; + } + + while (!isdelim[(unsigned char)(**string)]) { + (*string)++; + } + + if (**string) { + **string = 0; + (*string)++; + } + + return token; +} + +static unsigned char *ustrsep(char **p, const char *sep) +{ + return (unsigned char *)sstrsep(p, sep); +} + +static int test1_exit(int ec) +{ + EXIT(ec); + return (0); /* To keep some compilers quiet */ +} + +static void test1(const EVP_CIPHER *c, const unsigned char *key, int kn, + const unsigned char *iv, int in, + const unsigned char *plaintext, int pn, + const unsigned char *ciphertext, int cn, int encdec) +{ + EVP_CIPHER_CTX ctx; + unsigned char out[4096]; + int outl, outl2; + + printf("Testing cipher %s%s\n", EVP_CIPHER_name(c), + (encdec == + 1 ? "(encrypt)" : (encdec == + 0 ? "(decrypt)" : "(encrypt/decrypt)"))); + hexdump(stdout, "Key", key, kn); + if (in) + hexdump(stdout, "IV", iv, in); + hexdump(stdout, "Plaintext", plaintext, pn); + hexdump(stdout, "Ciphertext", ciphertext, cn); + + if (kn != c->key_len) { + fprintf(stderr, "Key length doesn't match, got %d expected %lu\n", kn, + (unsigned long)c->key_len); + test1_exit(5); + } + EVP_CIPHER_CTX_init(&ctx); + if (encdec != 0) { + if (!EVP_EncryptInit_ex(&ctx, c, NULL, key, iv)) { + fprintf(stderr, "EncryptInit failed\n"); + ERR_print_errors_fp(stderr); + test1_exit(10); + } + EVP_CIPHER_CTX_set_padding(&ctx, 0); + + if (!EVP_EncryptUpdate(&ctx, out, &outl, plaintext, pn)) { + fprintf(stderr, "Encrypt failed\n"); + ERR_print_errors_fp(stderr); + test1_exit(6); + } + if (!EVP_EncryptFinal_ex(&ctx, out + outl, &outl2)) { + fprintf(stderr, "EncryptFinal failed\n"); + ERR_print_errors_fp(stderr); + test1_exit(7); + } + + if (outl + outl2 != cn) { + fprintf(stderr, "Ciphertext length mismatch got %d expected %d\n", + outl + outl2, cn); + test1_exit(8); + } + + if (memcmp(out, ciphertext, cn)) { + fprintf(stderr, "Ciphertext mismatch\n"); + hexdump(stderr, "Got", out, cn); + hexdump(stderr, "Expected", ciphertext, cn); + test1_exit(9); + } + } + + if (encdec <= 0) { + if (!EVP_DecryptInit_ex(&ctx, c, NULL, key, iv)) { + fprintf(stderr, "DecryptInit failed\n"); + ERR_print_errors_fp(stderr); + test1_exit(11); + } + EVP_CIPHER_CTX_set_padding(&ctx, 0); + + if (!EVP_DecryptUpdate(&ctx, out, &outl, ciphertext, cn)) { + fprintf(stderr, "Decrypt failed\n"); + ERR_print_errors_fp(stderr); + test1_exit(6); + } + if (!EVP_DecryptFinal_ex(&ctx, out + outl, &outl2)) { + fprintf(stderr, "DecryptFinal failed\n"); + ERR_print_errors_fp(stderr); + test1_exit(7); + } + + if (outl + outl2 != pn) { + fprintf(stderr, "Plaintext length mismatch got %d expected %d\n", + outl + outl2, pn); + test1_exit(8); + } + + if (memcmp(out, plaintext, pn)) { + fprintf(stderr, "Plaintext mismatch\n"); + hexdump(stderr, "Got", out, pn); + hexdump(stderr, "Expected", plaintext, pn); + test1_exit(9); + } + } + + EVP_CIPHER_CTX_cleanup(&ctx); + + printf("\n"); +} + +static int test_cipher(const char *cipher, const unsigned char *key, int kn, + const unsigned char *iv, int in, + const unsigned char *plaintext, int pn, + const unsigned char *ciphertext, int cn, int encdec) +{ + const EVP_CIPHER *c; + + c = EVP_get_cipherbyname(cipher); + if (!c) + return 0; + + test1(c, key, kn, iv, in, plaintext, pn, ciphertext, cn, encdec); + + return 1; +} + +static int test_digest(const char *digest, + const unsigned char *plaintext, int pn, + const unsigned char *ciphertext, unsigned int cn) +{ + const EVP_MD *d; + EVP_MD_CTX ctx; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int mdn; + + d = EVP_get_digestbyname(digest); + if (!d) + return 0; + + printf("Testing digest %s\n", EVP_MD_name(d)); + hexdump(stdout, "Plaintext", plaintext, pn); + hexdump(stdout, "Digest", ciphertext, cn); + + EVP_MD_CTX_init(&ctx); + if (!EVP_DigestInit_ex(&ctx, d, NULL)) { + fprintf(stderr, "DigestInit failed\n"); + ERR_print_errors_fp(stderr); + EXIT(100); + } + if (!EVP_DigestUpdate(&ctx, plaintext, pn)) { + fprintf(stderr, "DigestUpdate failed\n"); + ERR_print_errors_fp(stderr); + EXIT(101); + } + if (!EVP_DigestFinal_ex(&ctx, md, &mdn)) { + fprintf(stderr, "DigestFinal failed\n"); + ERR_print_errors_fp(stderr); + EXIT(101); + } + EVP_MD_CTX_cleanup(&ctx); + + if (mdn != cn) { + fprintf(stderr, "Digest length mismatch, got %d expected %d\n", mdn, + cn); + EXIT(102); + } + + if (memcmp(md, ciphertext, cn)) { + fprintf(stderr, "Digest mismatch\n"); + hexdump(stderr, "Got", md, cn); + hexdump(stderr, "Expected", ciphertext, cn); + EXIT(103); + } + + printf("\n"); + + EVP_MD_CTX_cleanup(&ctx); + + return 1; +} + +int main(int argc, char **argv) +{ + const char *szTestFile; + FILE *f; + + if (argc != 2) { + fprintf(stderr, "%s \n", argv[0]); + EXIT(1); + } + CRYPTO_malloc_debug_init(); + CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + + szTestFile = argv[1]; + + f = fopen(szTestFile, "r"); + if (!f) { + perror(szTestFile); + EXIT(2); + } + + /* Load up the software EVP_CIPHER and EVP_MD definitions */ + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); +#ifndef OPENSSL_NO_ENGINE + /* Load all compiled-in ENGINEs */ + ENGINE_load_builtin_engines(); +#endif +#if 0 + OPENSSL_config(); +#endif +#ifndef OPENSSL_NO_ENGINE + /* + * Register all available ENGINE implementations of ciphers and digests. + * This could perhaps be changed to "ENGINE_register_all_complete()"? + */ + ENGINE_register_all_ciphers(); + ENGINE_register_all_digests(); + /* + * If we add command-line options, this statement should be switchable. + * It'll prevent ENGINEs being ENGINE_init()ialised for cipher/digest use + * if they weren't already initialised. + */ + /* ENGINE_set_cipher_flags(ENGINE_CIPHER_FLAG_NOINIT); */ +#endif + + for (;;) { + char line[4096]; + char *p; + char *cipher; + unsigned char *iv, *key, *plaintext, *ciphertext; + int encdec; + int kn, in, pn, cn; + + if (!fgets((char *)line, sizeof line, f)) + break; + if (line[0] == '#' || line[0] == '\n') + continue; + p = line; + cipher = sstrsep(&p, ":"); + key = ustrsep(&p, ":"); + iv = ustrsep(&p, ":"); + plaintext = ustrsep(&p, ":"); + ciphertext = ustrsep(&p, ":"); + if (p[-1] == '\n') { + p[-1] = '\0'; + encdec = -1; + } else { + encdec = atoi(sstrsep(&p, "\n")); + } + + kn = convert(key); + in = convert(iv); + pn = convert(plaintext); + cn = convert(ciphertext); + + if (!test_cipher + (cipher, key, kn, iv, in, plaintext, pn, ciphertext, cn, encdec) + && !test_digest(cipher, plaintext, pn, ciphertext, cn)) { +#ifdef OPENSSL_NO_AES + if (strstr(cipher, "AES") == cipher) { + fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); + continue; + } +#endif +#ifdef OPENSSL_NO_DES + if (strstr(cipher, "DES") == cipher) { + fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); + continue; + } +#endif +#ifdef OPENSSL_NO_RC4 + if (strstr(cipher, "RC4") == cipher) { + fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); + continue; + } +#endif +#ifdef OPENSSL_NO_CAMELLIA + if (strstr(cipher, "CAMELLIA") == cipher) { + fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); + continue; + } +#endif +#ifdef OPENSSL_NO_SEED + if (strstr(cipher, "SEED") == cipher) { + fprintf(stdout, "Cipher disabled, skipping %s\n", cipher); + continue; + } +#endif + fprintf(stderr, "Can't find %s\n", cipher); + EXIT(3); + } + } + fclose(f); + +#ifndef OPENSSL_NO_ENGINE + ENGINE_cleanup(); +#endif + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + ERR_free_strings(); + CRYPTO_mem_leaks_fp(stderr); + + return 0; +} diff --git a/libs/openssl/crypto/evp/evptests.txt b/libs/openssl/crypto/evp/evptests.txt new file mode 100644 index 00000000..c273707c --- /dev/null +++ b/libs/openssl/crypto/evp/evptests.txt @@ -0,0 +1,334 @@ +#cipher:key:iv:plaintext:ciphertext:0/1(decrypt/encrypt) +#digest:::input:output + +# SHA(1) tests (from shatest.c) +SHA1:::616263:a9993e364706816aba3e25717850c26c9cd0d89d + +# MD5 tests (from md5test.c) +MD5::::d41d8cd98f00b204e9800998ecf8427e +MD5:::61:0cc175b9c0f1b6a831c399e269772661 +MD5:::616263:900150983cd24fb0d6963f7d28e17f72 +MD5:::6d65737361676520646967657374:f96b697d7cb7938d525a2f31aaf161d0 +MD5:::6162636465666768696a6b6c6d6e6f707172737475767778797a:c3fcd3d76192e4007dfb496cca67e13b +MD5:::4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a30313233343536373839:d174ab98d277d9f5a5611c2c9f419d9f +MD5:::3132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930313233343536373839303132333435363738393031323334353637383930:57edf4a22be3c955ac49da2e2107b67a + +# AES 128 ECB tests (from FIPS-197 test vectors, encrypt) + +AES-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:69C4E0D86A7B0430D8CDB78070B4C55A:1 + +# AES 192 ECB tests (from FIPS-197 test vectors, encrypt) + +AES-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:DDA97CA4864CDFE06EAF70A0EC0D7191:1 + +# AES 256 ECB tests (from FIPS-197 test vectors, encrypt) + +AES-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:8EA2B7CA516745BFEAFC49904B496089:1 + +# AES 128 ECB tests (from NIST test vectors, encrypt) + +#AES-128-ECB:00000000000000000000000000000000::00000000000000000000000000000000:C34C052CC0DA8D73451AFE5F03BE297F:1 + +# AES 128 ECB tests (from NIST test vectors, decrypt) + +#AES-128-ECB:00000000000000000000000000000000::44416AC2D1F53C583303917E6BE9EBE0:00000000000000000000000000000000:0 + +# AES 192 ECB tests (from NIST test vectors, decrypt) + +#AES-192-ECB:000000000000000000000000000000000000000000000000::48E31E9E256718F29229319C19F15BA4:00000000000000000000000000000000:0 + +# AES 256 ECB tests (from NIST test vectors, decrypt) + +#AES-256-ECB:0000000000000000000000000000000000000000000000000000000000000000::058CCFFDBBCB382D1F6F56585D8A4ADE:00000000000000000000000000000000:0 + +# AES 128 CBC tests (from NIST test vectors, encrypt) + +#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:8A05FC5E095AF4848A08D328D3688E3D:1 + +# AES 192 CBC tests (from NIST test vectors, encrypt) + +#AES-192-CBC:000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:7BD966D53AD8C1BB85D2ADFAE87BB104:1 + +# AES 256 CBC tests (from NIST test vectors, encrypt) + +#AES-256-CBC:0000000000000000000000000000000000000000000000000000000000000000:00000000000000000000000000000000:00000000000000000000000000000000:FE3C53653E2F45B56FCD88B2CC898FF0:1 + +# AES 128 CBC tests (from NIST test vectors, decrypt) + +#AES-128-CBC:00000000000000000000000000000000:00000000000000000000000000000000:FACA37E0B0C85373DF706E73F7C9AF86:00000000000000000000000000000000:0 + +# AES tests from NIST document SP800-38A +# For all ECB encrypts and decrypts, the transformed sequence is +# AES-bits-ECB:key::plaintext:ciphertext:encdec +# ECB-AES128.Encrypt and ECB-AES128.Decrypt +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:3AD77BB40D7A3660A89ECAF32466EF97 +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:F5D3D58503B9699DE785895A96FDBAAF +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:43B1CD7F598ECE23881B00E3ED030688 +AES-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:7B0C785E27E8AD3F8223207104725DD4 +# ECB-AES192.Encrypt and ECB-AES192.Decrypt +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:BD334F1D6E45F25FF712A214571FA5CC +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:974104846D0AD3AD7734ECB3ECEE4EEF +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:EF7AFD2270E2E60ADCE0BA2FACE6444E +AES-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:9A4B41BA738D6C72FB16691603C18E0E +# ECB-AES256.Encrypt and ECB-AES256.Decrypt +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:F3EED1BDB5D2A03C064B5A7E3DB181F8 +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:591CCB10D410ED26DC5BA74A31362870 +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:B6ED21B99CA6F4F9F153E7B1BEAFED1D +AES-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:23304B7A39F9F3FF067D8D8F9E24ECC7 +# For all CBC encrypts and decrypts, the transformed sequence is +# AES-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec +# CBC-AES128.Encrypt and CBC-AES128.Decrypt +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:7649ABAC8119B246CEE98E9B12E9197D +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:7649ABAC8119B246CEE98E9B12E9197D:AE2D8A571E03AC9C9EB76FAC45AF8E51:5086CB9B507219EE95DB113A917678B2 +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:5086CB9B507219EE95DB113A917678B2:30C81C46A35CE411E5FBC1191A0A52EF:73BED6B8E3C1743B7116E69E22229516 +AES-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:73BED6B8E3C1743B7116E69E22229516:F69F2445DF4F9B17AD2B417BE66C3710:3FF1CAA1681FAC09120ECA307586E1A7 +# CBC-AES192.Encrypt and CBC-AES192.Decrypt +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:4F021DB243BC633D7178183A9FA071E8 +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:4F021DB243BC633D7178183A9FA071E8:AE2D8A571E03AC9C9EB76FAC45AF8E51:B4D9ADA9AD7DEDF4E5E738763F69145A +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:B4D9ADA9AD7DEDF4E5E738763F69145A:30C81C46A35CE411E5FBC1191A0A52EF:571B242012FB7AE07FA9BAAC3DF102E0 +AES-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:571B242012FB7AE07FA9BAAC3DF102E0:F69F2445DF4F9B17AD2B417BE66C3710:08B0E27988598881D920A9E64F5615CD +# CBC-AES256.Encrypt and CBC-AES256.Decrypt +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:F58C4C04D6E5F1BA779EABFB5F7BFBD6 +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:F58C4C04D6E5F1BA779EABFB5F7BFBD6:AE2D8A571E03AC9C9EB76FAC45AF8E51:9CFC4E967EDB808D679F777BC6702C7D +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:9CFC4E967EDB808D679F777BC6702C7D:30C81C46A35CE411E5FBC1191A0A52EF:39F23369A9D9BACFA530E26304231461 +AES-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39F23369A9D9BACFA530E26304231461:F69F2445DF4F9B17AD2B417BE66C3710:B2EB05E2C39BE9FCDA6C19078C6A9D1B +# We don't support CFB{1,8}-AESxxx.{En,De}crypt +# For all CFB128 encrypts and decrypts, the transformed sequence is +# AES-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec +# CFB128-AES128.Encrypt +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:1 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:1 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:1 +# CFB128-AES128.Decrypt +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:3B3FD92EB72DAD20333449F8E83CFB4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:C8A64537A0B3A93FCDE3CDAD9F1CE58B:0 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:C8A64537A0B3A93FCDE3CDAD9F1CE58B:30C81C46A35CE411E5FBC1191A0A52EF:26751F67A3CBB140B1808CF187A4F4DF:0 +AES-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:26751F67A3CBB140B1808CF187A4F4DF:F69F2445DF4F9B17AD2B417BE66C3710:C04B05357C5D1C0EEAC4C66F9FF7F2E6:0 +# CFB128-AES192.Encrypt +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:1 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:1 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:1 +# CFB128-AES192.Decrypt +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:CDC80D6FDDF18CAB34C25909C99A4174:AE2D8A571E03AC9C9EB76FAC45AF8E51:67CE7F7F81173621961A2B70171D3D7A:0 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:67CE7F7F81173621961A2B70171D3D7A:30C81C46A35CE411E5FBC1191A0A52EF:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:0 +AES-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2E1E8A1DD59B88B1C8E60FED1EFAC4C9:F69F2445DF4F9B17AD2B417BE66C3710:C05F9F9CA9834FA042AE8FBA584B09FF:0 +# CFB128-AES256.Encrypt +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:1 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:1 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:1 +# CFB128-AES256.Decrypt +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DC7E84BFDA79164B7ECD8486985D3860:AE2D8A571E03AC9C9EB76FAC45AF8E51:39FFED143B28B1C832113C6331E5407B:0 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:39FFED143B28B1C832113C6331E5407B:30C81C46A35CE411E5FBC1191A0A52EF:DF10132415E54B92A13ED0A8267AE2F9:0 +AES-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:DF10132415E54B92A13ED0A8267AE2F9:F69F2445DF4F9B17AD2B417BE66C3710:75A385741AB9CEF82031623D55B1E471:0 +# For all OFB encrypts and decrypts, the transformed sequence is +# AES-bits-CFB:key:IV/output':plaintext:ciphertext:encdec +# OFB-AES128.Encrypt +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:1 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:1 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:1 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:1 +# OFB-AES128.Decrypt +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:3B3FD92EB72DAD20333449F8E83CFB4A:0 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:7789508D16918F03F53C52DAC54ED825:0 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:9740051E9C5FECF64344F7A82260EDCC:0 +AES-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:304C6528F659C77866A510D9C1D6AE5E:0 +# OFB-AES192.Encrypt +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:1 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:1 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:1 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:1 +# OFB-AES192.Decrypt +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CDC80D6FDDF18CAB34C25909C99A4174:0 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:FCC28B8D4C63837C09E81700C1100401:0 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:8D9A9AEAC0F6596F559C6D4DAF59A5F2:0 +AES-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:6D9F200857CA6C3E9CAC524BD9ACC92A:0 +# OFB-AES256.Encrypt +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:1 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:1 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:1 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:1 +# OFB-AES256.Decrypt +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:DC7E84BFDA79164B7ECD8486985D3860:0 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:4FEBDC6740D20B3AC88F6AD82A4FB08D:0 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:71AB47A086E86EEDF39D1C5BBA97C408:0 +AES-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0126141D67F37BE8538F5A8BE740E484:0 + +# AES Counter test vectors from RFC3686 +aes-128-ctr:AE6852F8121067CC4BF7A5765577F39E:00000030000000000000000000000001:53696E676C6520626C6F636B206D7367:E4095D4FB7A7B3792D6175A3261311B8:1 +aes-128-ctr:7E24067817FAE0D743D6CE1F32539163:006CB6DBC0543B59DA48D90B00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:5104A106168A72D9790D41EE8EDAD388EB2E1EFC46DA57C8FCE630DF9141BE28:1 +aes-128-ctr:7691BE035E5020A8AC6E618529F9A0DC:00E0017B27777F3F4A1786F000000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:C1CF48A89F2FFDD9CF4652E9EFDB72D74540A42BDE6D7836D59A5CEAAEF3105325B2072F:1 + +aes-192-ctr:16AF5B145FC9F579C175F93E3BFB0EED863D06CCFDB78515:0000004836733C147D6D93CB00000001:53696E676C6520626C6F636B206D7367:4B55384FE259C9C84E7935A003CBE928:1 +aes-192-ctr:7C5CB2401B3DC33C19E7340819E0F69C678C3DB8E6F6A91A:0096B03B020C6EADC2CB500D00000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:453243FC609B23327EDFAAFA7131CD9F8490701C5AD4A79CFC1FE0FF42F4FB00:1 +aes-192-ctr:02BF391EE8ECB159B959617B0965279BF59B60A786D3E0FE:0007BDFD5CBD60278DCC091200000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:96893FC55E5C722F540B7DD1DDF7E758D288BC95C69165884536C811662F2188ABEE0935:1 + +aes-256-ctr:776BEFF2851DB06F4C8A0542C8696F6C6A81AF1EEC96B4D37FC1D689E6C1C104:00000060DB5672C97AA8F0B200000001:53696E676C6520626C6F636B206D7367:145AD01DBF824EC7560863DC71E3E0C0:1 +aes-256-ctr:F6D66D6BD52D59BB0796365879EFF886C66DD51A5B6A99744B50590C87A23884:00FAAC24C1585EF15A43D87500000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F:F05E231B3894612C49EE000B804EB2A9B8306B508F839D6A5530831D9344AF1C:1 +aes-256-ctr:FF7A617CE69148E4F1726E2F43581DE2AA62D9F805532EDFF1EED687FB54153D:001CC5B751A51D70A1C1114800000001:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223:EB6C52821D0BBBF7CE7594462ACA4FAAB407DF866569FD07F48CC0B583D6071F1EC0E6B8:1 + +# DES ECB tests (from destest) + +DES-ECB:0000000000000000::0000000000000000:8CA64DE9C1B123A7 +DES-ECB:FFFFFFFFFFFFFFFF::FFFFFFFFFFFFFFFF:7359B2163E4EDC58 +DES-ECB:3000000000000000::1000000000000001:958E6E627A05557B +DES-ECB:1111111111111111::1111111111111111:F40379AB9E0EC533 +DES-ECB:0123456789ABCDEF::1111111111111111:17668DFC7292532D +DES-ECB:1111111111111111::0123456789ABCDEF:8A5AE1F81AB8F2DD +DES-ECB:FEDCBA9876543210::0123456789ABCDEF:ED39D950FA74BCC4 + +# DESX-CBC tests (from destest) +DESX-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:846B2914851E9A2954732F8AA0A611C115CDC2D7951B1053A63C5E03B21AA3C4 + +# DES EDE3 CBC tests (from destest) +DES-EDE3-CBC:0123456789abcdeff1e0d3c2b5a49786fedcba9876543210:fedcba9876543210:37363534333231204E6F77206973207468652074696D6520666F722000000000:3FE301C962AC01D02213763C1CBD4CDC799657C064ECF5D41C673812CFDE9675 + +# RC4 tests (from rc4test) +RC4:0123456789abcdef0123456789abcdef::0123456789abcdef:75b7878099e0c596 +RC4:0123456789abcdef0123456789abcdef::0000000000000000:7494c2e7104b0879 +RC4:00000000000000000000000000000000::0000000000000000:de188941a3375d3a +RC4:ef012345ef012345ef012345ef012345::0000000000000000000000000000000000000000:d6a141a7ec3c38dfbd615a1162e1c7ba36b67858 +RC4:0123456789abcdef0123456789abcdef::123456789ABCDEF0123456789ABCDEF0123456789ABCDEF012345678:66a0949f8af7d6891f7f832ba833c00c892ebe30143ce28740011ecf +RC4:ef012345ef012345ef012345ef012345::00000000000000000000:d6a141a7ec3c38dfbd61 + + +# Camellia tests from RFC3713 +# For all ECB encrypts and decrypts, the transformed sequence is +# CAMELLIA-bits-ECB:key::plaintext:ciphertext:encdec +CAMELLIA-128-ECB:0123456789abcdeffedcba9876543210::0123456789abcdeffedcba9876543210:67673138549669730857065648eabe43 +CAMELLIA-192-ECB:0123456789abcdeffedcba98765432100011223344556677::0123456789abcdeffedcba9876543210:b4993401b3e996f84ee5cee7d79b09b9 +CAMELLIA-256-ECB:0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff::0123456789abcdeffedcba9876543210:9acc237dff16d76c20ef7c919e3a7509 + +# ECB-CAMELLIA128.Encrypt +CAMELLIA-128-ECB:000102030405060708090A0B0C0D0E0F::00112233445566778899AABBCCDDEEFF:77CF412067AF8270613529149919546F:1 +CAMELLIA-192-ECB:000102030405060708090A0B0C0D0E0F1011121314151617::00112233445566778899AABBCCDDEEFF:B22F3C36B72D31329EEE8ADDC2906C68:1 +CAMELLIA-256-ECB:000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F::00112233445566778899AABBCCDDEEFF:2EDF1F3418D53B88841FC8985FB1ECF2:1 + +# ECB-CAMELLIA128.Encrypt and ECB-CAMELLIA128.Decrypt +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::6BC1BEE22E409F96E93D7E117393172A:432FC5DCD628115B7C388D770B270C96 +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::AE2D8A571E03AC9C9EB76FAC45AF8E51:0BE1F14023782A22E8384C5ABB7FAB2B +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::30C81C46A35CE411E5FBC1191A0A52EF:A0A1ABCD1893AB6FE0FE5B65DF5F8636 +CAMELLIA-128-ECB:2B7E151628AED2A6ABF7158809CF4F3C::F69F2445DF4F9B17AD2B417BE66C3710:E61925E0D5DFAA9BB29F815B3076E51A + +# ECB-CAMELLIA192.Encrypt and ECB-CAMELLIA192.Decrypt +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::6BC1BEE22E409F96E93D7E117393172A:CCCC6C4E138B45848514D48D0D3439D3 +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::AE2D8A571E03AC9C9EB76FAC45AF8E51:5713C62C14B2EC0F8393B6AFD6F5785A +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::30C81C46A35CE411E5FBC1191A0A52EF:B40ED2B60EB54D09D030CF511FEEF366 +CAMELLIA-192-ECB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B::F69F2445DF4F9B17AD2B417BE66C3710:909DBD95799096748CB27357E73E1D26 + +# ECB-CAMELLIA256.Encrypt and ECB-CAMELLIA256.Decrypt +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::6BC1BEE22E409F96E93D7E117393172A:BEFD219B112FA00098919CD101C9CCFA +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::AE2D8A571E03AC9C9EB76FAC45AF8E51:C91D3A8F1AEA08A9386CF4B66C0169EA +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::30C81C46A35CE411E5FBC1191A0A52EF:A623D711DC5F25A51BB8A80D56397D28 +CAMELLIA-256-ECB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4::F69F2445DF4F9B17AD2B417BE66C3710:7960109FB6DC42947FCFE59EA3C5EB6B + +# For all CBC encrypts and decrypts, the transformed sequence is +# CAMELLIA-bits-CBC:key:IV/ciphertext':plaintext:ciphertext:encdec +# CBC-CAMELLIA128.Encrypt and CBC-CAMELLIA128.Decrypt +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:1607CF494B36BBF00DAEB0B503C831AB +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:1607CF494B36BBF00DAEB0B503C831AB:AE2D8A571E03AC9C9EB76FAC45AF8E51:A2F2CF671629EF7840C5A5DFB5074887 +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:A2F2CF671629EF7840C5A5DFB5074887:30C81C46A35CE411E5FBC1191A0A52EF:0F06165008CF8B8B5A63586362543E54 +CAMELLIA-128-CBC:2B7E151628AED2A6ABF7158809CF4F3C:36A84CDAFD5F9A85ADA0F0A993D6D577:F69F2445DF4F9B17AD2B417BE66C3710:74C64268CDB8B8FAF5B34E8AF3732980 + +# CBC-CAMELLIA192.Encrypt and CBC-CAMELLIA192.Decrypt +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:2A4830AB5AC4A1A2405955FD2195CF93 +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:2A4830AB5AC4A1A2405955FD2195CF93:AE2D8A571E03AC9C9EB76FAC45AF8E51:5D5A869BD14CE54264F892A6DD2EC3D5 +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:5D5A869BD14CE54264F892A6DD2EC3D5:30C81C46A35CE411E5FBC1191A0A52EF:37D359C3349836D884E310ADDF68C449 +CAMELLIA-192-CBC:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:37D359C3349836D884E310ADDF68C449:F69F2445DF4F9B17AD2B417BE66C3710:01FAAA930B4AB9916E9668E1428C6B08 + +# CBC-CAMELLIA256.Encrypt and CBC-CAMELLIA256.Decrypt +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:E6CFA35FC02B134A4D2C0B6737AC3EDA +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E6CFA35FC02B134A4D2C0B6737AC3EDA:AE2D8A571E03AC9C9EB76FAC45AF8E51:36CBEB73BD504B4070B1B7DE2B21EB50 +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:36CBEB73BD504B4070B1B7DE2B21EB50:30C81C46A35CE411E5FBC1191A0A52EF:E31A6055297D96CA3330CDF1B1860A83 +CAMELLIA-256-CBC:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E31A6055297D96CA3330CDF1B1860A83:F69F2445DF4F9B17AD2B417BE66C3710:5D563F6D1CCCF236051C0C5C1C58F28F + +# We don't support CFB{1,8}-CAMELLIAxxx.{En,De}crypt +# For all CFB128 encrypts and decrypts, the transformed sequence is +# CAMELLIA-bits-CFB:key:IV/ciphertext':plaintext:ciphertext:encdec +# CFB128-CAMELLIA128.Encrypt +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:1 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:1 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:1 + +# CFB128-CAMELLIA128.Decrypt +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:14F7646187817EB586599146B82BD719:AE2D8A571E03AC9C9EB76FAC45AF8E51:A53D28BB82DF741103EA4F921A44880B:0 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:A53D28BB82DF741103EA4F921A44880B:30C81C46A35CE411E5FBC1191A0A52EF:9C2157A664626D1DEF9EA420FDE69B96:0 +CAMELLIA-128-CFB:2B7E151628AED2A6ABF7158809CF4F3C:9C2157A664626D1DEF9EA420FDE69B96:F69F2445DF4F9B17AD2B417BE66C3710:742A25F0542340C7BAEF24CA8482BB09:0 + +# CFB128-CAMELLIA192.Encrypt +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:1 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:1 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:1 + +# CFB128-CAMELLIA192.Decrypt +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:C832BB9780677DAA82D9B6860DCD565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:86F8491627906D780C7A6D46EA331F98:0 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:86F8491627906D780C7A6D46EA331F98:30C81C46A35CE411E5FBC1191A0A52EF:69511CCE594CF710CB98BB63D7221F01:0 +CAMELLIA-192-CFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:69511CCE594CF710CB98BB63D7221F01:F69F2445DF4F9B17AD2B417BE66C3710:D5B5378A3ABED55803F25565D8907B84:0 + +# CFB128-CAMELLIA256.Encrypt +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:1 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:1 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:1 + +# CFB128-CAMELLIA256.Decrypt +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:CF6107BB0CEA7D7FB1BD31F5E7B06C93:AE2D8A571E03AC9C9EB76FAC45AF8E51:89BEDB4CCDD864EA11BA4CBE849B5E2B:0 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:89BEDB4CCDD864EA11BA4CBE849B5E2B:30C81C46A35CE411E5FBC1191A0A52EF:555FC3F34BDD2D54C62D9E3BF338C1C4:0 +CAMELLIA-256-CFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:555FC3F34BDD2D54C62D9E3BF338C1C4:F69F2445DF4F9B17AD2B417BE66C3710:5953ADCE14DB8C7F39F1BD39F359BFFA:0 + +# For all OFB encrypts and decrypts, the transformed sequence is +# CAMELLIA-bits-OFB:key:IV/output':plaintext:ciphertext:encdec +# OFB-CAMELLIA128.Encrypt +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:1 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:1 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:1 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:1 + +# OFB-CAMELLIA128.Decrypt +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:14F7646187817EB586599146B82BD719:0 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:50FE67CC996D32B6DA0937E99BAFEC60:AE2D8A571E03AC9C9EB76FAC45AF8E51:25623DB569CA51E01482649977E28D84:0 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:D9A4DADA0892239F6B8B3D7680E15674:30C81C46A35CE411E5FBC1191A0A52EF:C776634A60729DC657D12B9FCA801E98:0 +CAMELLIA-128-OFB:2B7E151628AED2A6ABF7158809CF4F3C:A78819583F0308E7A6BF36B1386ABF23:F69F2445DF4F9B17AD2B417BE66C3710:D776379BE0E50825E681DA1A4C980E8E:0 + +# OFB-CAMELLIA192.Encrypt +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:1 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:1 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:1 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:1 + +# OFB-CAMELLIA192.Decrypt +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:C832BB9780677DAA82D9B6860DCD565E:0 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:A609B38DF3B1133DDDFF2718BA09565E:AE2D8A571E03AC9C9EB76FAC45AF8E51:8ECEB7D0350D72C7F78562AEBDF99339:0 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:52EF01DA52602FE0975F78AC84BF8A50:30C81C46A35CE411E5FBC1191A0A52EF:BDD62DBBB9700846C53B507F544696F0:0 +CAMELLIA-192-OFB:8E73B0F7DA0E6452C810F32B809079E562F8EAD2522C6B7B:BD5286AC63AABD7EB067AC54B553F71D:F69F2445DF4F9B17AD2B417BE66C3710:E28014E046B802F385C4C2E13EAD4A72:0 + +# OFB-CAMELLIA256.Encrypt +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:1 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:1 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:1 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:1 + +# OFB-CAMELLIA256.Decrypt +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:000102030405060708090A0B0C0D0E0F:6BC1BEE22E409F96E93D7E117393172A:CF6107BB0CEA7D7FB1BD31F5E7B06C93:0 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:B7BF3A5DF43989DD97F0FA97EBCE2F4A:AE2D8A571E03AC9C9EB76FAC45AF8E51:127AD97E8E3994E4820027D7BA109368:0 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:E1C656305ED1A7A6563805746FE03EDC:30C81C46A35CE411E5FBC1191A0A52EF:6BFF6265A6A6B7A535BC65A80B17214E:0 +CAMELLIA-256-OFB:603DEB1015CA71BE2B73AEF0857D77811F352C073B6108D72D9810A30914DFF4:41635BE625B48AFC1666DD42A09D96E7:F69F2445DF4F9B17AD2B417BE66C3710:0A4A0404E26AA78A27CB271E8BF3CF20:0 + +# SEED test vectors from RFC4269 +SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:0 +SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:0 +SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:0 +SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:0 +SEED-ECB:00000000000000000000000000000000::000102030405060708090A0B0C0D0E0F:5EBAC6E0054E166819AFF1CC6D346CDB:1 +SEED-ECB:000102030405060708090A0B0C0D0E0F::00000000000000000000000000000000:C11F22F20140505084483597E4370F43:1 +SEED-ECB:4706480851E61BE85D74BFB3FD956185::83A2F8A288641FB9A4E9A5CC2F131C7D:EE54D13EBCAE706D226BC3142CD40D4A:1 +SEED-ECB:28DBC3BC49FFD87DCFA509B11D422BE7::B41E6BE2EBA84A148E2EED84593C5EC7:9B9B7BFCD1813CB95D0B3618F40F5122:1 diff --git a/libs/openssl/crypto/evp/m_dss.c b/libs/openssl/crypto/evp/m_dss.c new file mode 100644 index 00000000..f22ba522 --- /dev/null +++ b/libs/openssl/crypto/evp/m_dss.c @@ -0,0 +1,106 @@ +/* crypto/evp/m_dss.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#ifndef OPENSSL_NO_DSA +# include +#endif + +#ifndef OPENSSL_NO_SHA +# ifndef OPENSSL_FIPS + +static int init(EVP_MD_CTX *ctx) +{ + return SHA1_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA1_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA1_Final(md, ctx->md_data); +} + +static const EVP_MD dsa_md = { + NID_dsaWithSHA, + NID_dsaWithSHA, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_DIGEST, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_DSA_method, + SHA_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA_CTX), +}; + +const EVP_MD *EVP_dss(void) +{ + return (&dsa_md); +} +# endif +#endif diff --git a/libs/openssl/crypto/evp/m_dss1.c b/libs/openssl/crypto/evp/m_dss1.c new file mode 100644 index 00000000..976148e4 --- /dev/null +++ b/libs/openssl/crypto/evp/m_dss1.c @@ -0,0 +1,108 @@ +/* crypto/evp/m_dss1.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_SHA + +# include +# include +# include +# ifndef OPENSSL_NO_DSA +# include +# endif + +# ifndef OPENSSL_FIPS + +static int init(EVP_MD_CTX *ctx) +{ + return SHA1_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA1_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA1_Final(md, ctx->md_data); +} + +static const EVP_MD dss1_md = { + NID_dsa, + NID_dsaWithSHA1, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_DIGEST, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_DSA_method, + SHA_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA_CTX), +}; + +const EVP_MD *EVP_dss1(void) +{ + return (&dss1_md); +} +# endif +#endif diff --git a/libs/openssl/crypto/evp/m_ecdsa.c b/libs/openssl/crypto/evp/m_ecdsa.c new file mode 100644 index 00000000..d11a13a6 --- /dev/null +++ b/libs/openssl/crypto/evp/m_ecdsa.c @@ -0,0 +1,156 @@ +/* crypto/evp/m_ecdsa.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +#ifndef OPENSSL_NO_SHA +# ifndef OPENSSL_FIPS + +static int init(EVP_MD_CTX *ctx) +{ + return SHA1_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA1_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA1_Final(md, ctx->md_data); +} + +static const EVP_MD ecdsa_md = { + NID_ecdsa_with_SHA1, + NID_ecdsa_with_SHA1, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_DIGEST, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_ECDSA_method, + SHA_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA_CTX), +}; + +const EVP_MD *EVP_ecdsa(void) +{ + return (&ecdsa_md); +} +# endif +#endif diff --git a/libs/openssl/crypto/evp/m_md2.c b/libs/openssl/crypto/evp/m_md2.c new file mode 100644 index 00000000..3c4cd7bf --- /dev/null +++ b/libs/openssl/crypto/evp/m_md2.c @@ -0,0 +1,106 @@ +/* crypto/evp/m_md2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_MD2 + +# include +# include +# include +# include +# ifndef OPENSSL_NO_RSA +# include +# endif + +static int init(EVP_MD_CTX *ctx) +{ + return MD2_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return MD2_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return MD2_Final(md, ctx->md_data); +} + +static const EVP_MD md2_md = { + NID_md2, + NID_md2WithRSAEncryption, + MD2_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_method, + MD2_BLOCK, + sizeof(EVP_MD *) + sizeof(MD2_CTX), +}; + +const EVP_MD *EVP_md2(void) +{ + return (&md2_md); +} +#endif diff --git a/libs/openssl/crypto/evp/m_md4.c b/libs/openssl/crypto/evp/m_md4.c new file mode 100644 index 00000000..851de69f --- /dev/null +++ b/libs/openssl/crypto/evp/m_md4.c @@ -0,0 +1,108 @@ +/* crypto/evp/m_md4.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_MD4 + +# include +# include +# include +# include +# ifndef OPENSSL_NO_RSA +# include +# endif + +# include "evp_locl.h" + +static int init(EVP_MD_CTX *ctx) +{ + return MD4_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return MD4_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return MD4_Final(md, ctx->md_data); +} + +static const EVP_MD md4_md = { + NID_md4, + NID_md4WithRSAEncryption, + MD4_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_method, + MD4_CBLOCK, + sizeof(EVP_MD *) + sizeof(MD4_CTX), +}; + +const EVP_MD *EVP_md4(void) +{ + return (&md4_md); +} +#endif diff --git a/libs/openssl/crypto/evp/m_md5.c b/libs/openssl/crypto/evp/m_md5.c new file mode 100644 index 00000000..e5d5f71b --- /dev/null +++ b/libs/openssl/crypto/evp/m_md5.c @@ -0,0 +1,107 @@ +/* crypto/evp/m_md5.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_MD5 + +# include +# include +# include +# include +# ifndef OPENSSL_NO_RSA +# include +# endif +# include "evp_locl.h" + +static int init(EVP_MD_CTX *ctx) +{ + return MD5_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return MD5_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return MD5_Final(md, ctx->md_data); +} + +static const EVP_MD md5_md = { + NID_md5, + NID_md5WithRSAEncryption, + MD5_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_method, + MD5_CBLOCK, + sizeof(EVP_MD *) + sizeof(MD5_CTX), +}; + +const EVP_MD *EVP_md5(void) +{ + return (&md5_md); +} +#endif diff --git a/libs/openssl/crypto/evp/m_mdc2.c b/libs/openssl/crypto/evp/m_mdc2.c new file mode 100644 index 00000000..94e12a6b --- /dev/null +++ b/libs/openssl/crypto/evp/m_mdc2.c @@ -0,0 +1,108 @@ +/* crypto/evp/m_mdc2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_MDC2 + +# include +# include +# include +# include +# ifndef OPENSSL_NO_RSA +# include +# endif + +# include "evp_locl.h" + +static int init(EVP_MD_CTX *ctx) +{ + return MDC2_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return MDC2_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return MDC2_Final(md, ctx->md_data); +} + +static const EVP_MD mdc2_md = { + NID_mdc2, + NID_mdc2WithRSA, + MDC2_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_ASN1_OCTET_STRING_method, + MDC2_BLOCK, + sizeof(EVP_MD *) + sizeof(MDC2_CTX), +}; + +const EVP_MD *EVP_mdc2(void) +{ + return (&mdc2_md); +} +#endif diff --git a/libs/openssl/crypto/evp/m_null.c b/libs/openssl/crypto/evp/m_null.c new file mode 100644 index 00000000..017e1feb --- /dev/null +++ b/libs/openssl/crypto/evp/m_null.c @@ -0,0 +1,98 @@ +/* crypto/evp/m_null.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +static int init(EVP_MD_CTX *ctx) +{ + return 1; +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return 1; +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return 1; +} + +static const EVP_MD null_md = { + NID_undef, + NID_undef, + 0, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_NULL_method, + 0, + sizeof(EVP_MD *), +}; + +const EVP_MD *EVP_md_null(void) +{ + return (&null_md); +} diff --git a/libs/openssl/crypto/evp/m_ripemd.c b/libs/openssl/crypto/evp/m_ripemd.c new file mode 100644 index 00000000..81de0ef4 --- /dev/null +++ b/libs/openssl/crypto/evp/m_ripemd.c @@ -0,0 +1,107 @@ +/* crypto/evp/m_ripemd.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_RIPEMD + +# include +# include +# include +# include +# ifndef OPENSSL_NO_RSA +# include +# endif +# include "evp_locl.h" + +static int init(EVP_MD_CTX *ctx) +{ + return RIPEMD160_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return RIPEMD160_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return RIPEMD160_Final(md, ctx->md_data); +} + +static const EVP_MD ripemd160_md = { + NID_ripemd160, + NID_ripemd160WithRSA, + RIPEMD160_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_method, + RIPEMD160_CBLOCK, + sizeof(EVP_MD *) + sizeof(RIPEMD160_CTX), +}; + +const EVP_MD *EVP_ripemd160(void) +{ + return (&ripemd160_md); +} +#endif diff --git a/libs/openssl/crypto/evp/m_sha.c b/libs/openssl/crypto/evp/m_sha.c new file mode 100644 index 00000000..e1e22e0c --- /dev/null +++ b/libs/openssl/crypto/evp/m_sha.c @@ -0,0 +1,106 @@ +/* crypto/evp/m_sha.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA0) + +# include +# include +# include +# ifndef OPENSSL_NO_RSA +# include +# endif +# include "evp_locl.h" + +static int init(EVP_MD_CTX *ctx) +{ + return SHA_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA_Final(md, ctx->md_data); +} + +static const EVP_MD sha_md = { + NID_sha, + NID_shaWithRSAEncryption, + SHA_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA_CTX), +}; + +const EVP_MD *EVP_sha(void) +{ + return (&sha_md); +} +#endif diff --git a/libs/openssl/crypto/evp/m_sha1.c b/libs/openssl/crypto/evp/m_sha1.c new file mode 100644 index 00000000..0cc63555 --- /dev/null +++ b/libs/openssl/crypto/evp/m_sha1.c @@ -0,0 +1,239 @@ +/* crypto/evp/m_sha1.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_FIPS + +# ifndef OPENSSL_NO_SHA + +# include +# include +# include +# ifndef OPENSSL_NO_RSA +# include +# endif + +static int init(EVP_MD_CTX *ctx) +{ + return SHA1_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA1_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA1_Final(md, ctx->md_data); +} + +static const EVP_MD sha1_md = { + NID_sha1, + NID_sha1WithRSAEncryption, + SHA_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA_CTX), +}; + +const EVP_MD *EVP_sha1(void) +{ + return (&sha1_md); +} +# endif + +# ifndef OPENSSL_NO_SHA256 +static int init224(EVP_MD_CTX *ctx) +{ + return SHA224_Init(ctx->md_data); +} + +static int init256(EVP_MD_CTX *ctx) +{ + return SHA256_Init(ctx->md_data); +} + +/* + * Even though there're separate SHA224_[Update|Final], we call + * SHA256 functions even in SHA224 context. This is what happens + * there anyway, so we can spare few CPU cycles:-) + */ +static int update256(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA256_Update(ctx->md_data, data, count); +} + +static int final256(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA256_Final(md, ctx->md_data); +} + +static const EVP_MD sha224_md = { + NID_sha224, + NID_sha224WithRSAEncryption, + SHA224_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + init224, + update256, + final256, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA256_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA256_CTX), +}; + +const EVP_MD *EVP_sha224(void) +{ + return (&sha224_md); +} + +static const EVP_MD sha256_md = { + NID_sha256, + NID_sha256WithRSAEncryption, + SHA256_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + init256, + update256, + final256, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA256_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA256_CTX), +}; + +const EVP_MD *EVP_sha256(void) +{ + return (&sha256_md); +} +# endif /* ifndef OPENSSL_NO_SHA256 */ + +# ifndef OPENSSL_NO_SHA512 +static int init384(EVP_MD_CTX *ctx) +{ + return SHA384_Init(ctx->md_data); +} + +static int init512(EVP_MD_CTX *ctx) +{ + return SHA512_Init(ctx->md_data); +} + +/* See comment in SHA224/256 section */ +static int update512(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return SHA512_Update(ctx->md_data, data, count); +} + +static int final512(EVP_MD_CTX *ctx, unsigned char *md) +{ + return SHA512_Final(md, ctx->md_data); +} + +static const EVP_MD sha384_md = { + NID_sha384, + NID_sha384WithRSAEncryption, + SHA384_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + init384, + update512, + final512, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA512_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA512_CTX), +}; + +const EVP_MD *EVP_sha384(void) +{ + return (&sha384_md); +} + +static const EVP_MD sha512_md = { + NID_sha512, + NID_sha512WithRSAEncryption, + SHA512_DIGEST_LENGTH, + EVP_MD_FLAG_PKEY_METHOD_SIGNATURE | EVP_MD_FLAG_DIGALGID_ABSENT, + init512, + update512, + final512, + NULL, + NULL, + EVP_PKEY_RSA_method, + SHA512_CBLOCK, + sizeof(EVP_MD *) + sizeof(SHA512_CTX), +}; + +const EVP_MD *EVP_sha512(void) +{ + return (&sha512_md); +} +# endif /* ifndef OPENSSL_NO_SHA512 */ + +#endif diff --git a/libs/openssl/crypto/evp/m_sigver.c b/libs/openssl/crypto/evp/m_sigver.c new file mode 100644 index 00000000..e153a183 --- /dev/null +++ b/libs/openssl/crypto/evp/m_sigver.c @@ -0,0 +1,187 @@ +/* m_sigver.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006,2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include "evp_locl.h" + +static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey, + int ver) +{ + if (ctx->pctx == NULL) + ctx->pctx = EVP_PKEY_CTX_new(pkey, e); + if (ctx->pctx == NULL) + return 0; + + if (type == NULL) { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) > 0) + type = EVP_get_digestbynid(def_nid); + } + + if (type == NULL) { + EVPerr(EVP_F_DO_SIGVER_INIT, EVP_R_NO_DEFAULT_DIGEST); + return 0; + } + + if (ver) { + if (ctx->pctx->pmeth->verifyctx_init) { + if (ctx->pctx->pmeth->verifyctx_init(ctx->pctx, ctx) <= 0) + return 0; + ctx->pctx->operation = EVP_PKEY_OP_VERIFYCTX; + } else if (EVP_PKEY_verify_init(ctx->pctx) <= 0) + return 0; + } else { + if (ctx->pctx->pmeth->signctx_init) { + if (ctx->pctx->pmeth->signctx_init(ctx->pctx, ctx) <= 0) + return 0; + ctx->pctx->operation = EVP_PKEY_OP_SIGNCTX; + } else if (EVP_PKEY_sign_init(ctx->pctx) <= 0) + return 0; + } + if (EVP_PKEY_CTX_set_signature_md(ctx->pctx, type) <= 0) + return 0; + if (pctx) + *pctx = ctx->pctx; + if (!EVP_DigestInit_ex(ctx, type, e)) + return 0; + return 1; +} + +int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) +{ + return do_sigver_init(ctx, pctx, type, e, pkey, 0); +} + +int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey) +{ + return do_sigver_init(ctx, pctx, type, e, pkey, 1); +} + +int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + size_t *siglen) +{ + int sctx, r = 0; + if (ctx->pctx->pmeth->signctx) + sctx = 1; + else + sctx = 0; + if (sigret) { + EVP_MD_CTX tmp_ctx; + unsigned char md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) + return 0; + if (sctx) + r = tmp_ctx.pctx->pmeth->signctx(tmp_ctx.pctx, + sigret, siglen, &tmp_ctx); + else + r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen); + EVP_MD_CTX_cleanup(&tmp_ctx); + if (sctx || !r) + return r; + if (EVP_PKEY_sign(ctx->pctx, sigret, siglen, md, mdlen) <= 0) + return 0; + } else { + if (sctx) { + if (ctx->pctx->pmeth->signctx(ctx->pctx, sigret, siglen, ctx) <= + 0) + return 0; + } else { + int s = EVP_MD_size(ctx->digest); + if (s < 0 + || EVP_PKEY_sign(ctx->pctx, sigret, siglen, NULL, s) <= 0) + return 0; + } + } + return 1; +} + +int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, unsigned char *sig, size_t siglen) +{ + EVP_MD_CTX tmp_ctx; + unsigned char md[EVP_MAX_MD_SIZE]; + int r; + unsigned int mdlen; + int vctx; + + if (ctx->pctx->pmeth->verifyctx) + vctx = 1; + else + vctx = 0; + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) + return -1; + if (vctx) { + r = tmp_ctx.pctx->pmeth->verifyctx(tmp_ctx.pctx, + sig, siglen, &tmp_ctx); + } else + r = EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen); + EVP_MD_CTX_cleanup(&tmp_ctx); + if (vctx || !r) + return r; + return EVP_PKEY_verify(ctx->pctx, sig, siglen, md, mdlen); +} diff --git a/libs/openssl/crypto/evp/m_wp.c b/libs/openssl/crypto/evp/m_wp.c new file mode 100644 index 00000000..a890939e --- /dev/null +++ b/libs/openssl/crypto/evp/m_wp.c @@ -0,0 +1,48 @@ +/* crypto/evp/m_wp.c */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_WHIRLPOOL + +# include +# include +# include +# include +# include "evp_locl.h" + +static int init(EVP_MD_CTX *ctx) +{ + return WHIRLPOOL_Init(ctx->md_data); +} + +static int update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + return WHIRLPOOL_Update(ctx->md_data, data, count); +} + +static int final(EVP_MD_CTX *ctx, unsigned char *md) +{ + return WHIRLPOOL_Final(md, ctx->md_data); +} + +static const EVP_MD whirlpool_md = { + NID_whirlpool, + 0, + WHIRLPOOL_DIGEST_LENGTH, + 0, + init, + update, + final, + NULL, + NULL, + EVP_PKEY_NULL_method, + WHIRLPOOL_BBLOCK / 8, + sizeof(EVP_MD *) + sizeof(WHIRLPOOL_CTX), +}; + +const EVP_MD *EVP_whirlpool(void) +{ + return (&whirlpool_md); +} +#endif diff --git a/libs/openssl/crypto/evp/names.c b/libs/openssl/crypto/evp/names.c new file mode 100644 index 00000000..ff115a31 --- /dev/null +++ b/libs/openssl/crypto/evp/names.c @@ -0,0 +1,215 @@ +/* crypto/evp/names.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +int EVP_add_cipher(const EVP_CIPHER *c) +{ + int r; + + if (c == NULL) + return 0; + + OPENSSL_init(); + + r = OBJ_NAME_add(OBJ_nid2sn(c->nid), OBJ_NAME_TYPE_CIPHER_METH, + (const char *)c); + if (r == 0) + return (0); + check_defer(c->nid); + r = OBJ_NAME_add(OBJ_nid2ln(c->nid), OBJ_NAME_TYPE_CIPHER_METH, + (const char *)c); + return (r); +} + +int EVP_add_digest(const EVP_MD *md) +{ + int r; + const char *name; + OPENSSL_init(); + + name = OBJ_nid2sn(md->type); + r = OBJ_NAME_add(name, OBJ_NAME_TYPE_MD_METH, (const char *)md); + if (r == 0) + return (0); + check_defer(md->type); + r = OBJ_NAME_add(OBJ_nid2ln(md->type), OBJ_NAME_TYPE_MD_METH, + (const char *)md); + if (r == 0) + return (0); + + if (md->pkey_type && md->type != md->pkey_type) { + r = OBJ_NAME_add(OBJ_nid2sn(md->pkey_type), + OBJ_NAME_TYPE_MD_METH | OBJ_NAME_ALIAS, name); + if (r == 0) + return (0); + check_defer(md->pkey_type); + r = OBJ_NAME_add(OBJ_nid2ln(md->pkey_type), + OBJ_NAME_TYPE_MD_METH | OBJ_NAME_ALIAS, name); + } + return (r); +} + +const EVP_CIPHER *EVP_get_cipherbyname(const char *name) +{ + const EVP_CIPHER *cp; + + cp = (const EVP_CIPHER *)OBJ_NAME_get(name, OBJ_NAME_TYPE_CIPHER_METH); + return (cp); +} + +const EVP_MD *EVP_get_digestbyname(const char *name) +{ + const EVP_MD *cp; + + cp = (const EVP_MD *)OBJ_NAME_get(name, OBJ_NAME_TYPE_MD_METH); + return (cp); +} + +void EVP_cleanup(void) +{ + OBJ_NAME_cleanup(OBJ_NAME_TYPE_CIPHER_METH); + OBJ_NAME_cleanup(OBJ_NAME_TYPE_MD_METH); + /* + * The above calls will only clean out the contents of the name hash + * table, but not the hash table itself. The following line does that + * part. -- Richard Levitte + */ + OBJ_NAME_cleanup(-1); + + EVP_PBE_cleanup(); + if (obj_cleanup_defer == 2) { + obj_cleanup_defer = 0; + OBJ_cleanup(); + } + OBJ_sigid_free(); +} + +struct doall_cipher { + void *arg; + void (*fn) (const EVP_CIPHER *ciph, + const char *from, const char *to, void *arg); +}; + +static void do_all_cipher_fn(const OBJ_NAME *nm, void *arg) +{ + struct doall_cipher *dc = arg; + if (nm->alias) + dc->fn(NULL, nm->name, nm->data, dc->arg); + else + dc->fn((const EVP_CIPHER *)nm->data, nm->name, NULL, dc->arg); +} + +void EVP_CIPHER_do_all(void (*fn) (const EVP_CIPHER *ciph, + const char *from, const char *to, void *x), + void *arg) +{ + struct doall_cipher dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc); +} + +void EVP_CIPHER_do_all_sorted(void (*fn) (const EVP_CIPHER *ciph, + const char *from, const char *to, + void *x), void *arg) +{ + struct doall_cipher dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_CIPHER_METH, do_all_cipher_fn, &dc); +} + +struct doall_md { + void *arg; + void (*fn) (const EVP_MD *ciph, + const char *from, const char *to, void *arg); +}; + +static void do_all_md_fn(const OBJ_NAME *nm, void *arg) +{ + struct doall_md *dc = arg; + if (nm->alias) + dc->fn(NULL, nm->name, nm->data, dc->arg); + else + dc->fn((const EVP_MD *)nm->data, nm->name, NULL, dc->arg); +} + +void EVP_MD_do_all(void (*fn) (const EVP_MD *md, + const char *from, const char *to, void *x), + void *arg) +{ + struct doall_md dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); +} + +void EVP_MD_do_all_sorted(void (*fn) (const EVP_MD *md, + const char *from, const char *to, + void *x), void *arg) +{ + struct doall_md dc; + dc.fn = fn; + dc.arg = arg; + OBJ_NAME_do_all_sorted(OBJ_NAME_TYPE_MD_METH, do_all_md_fn, &dc); +} diff --git a/libs/openssl/crypto/evp/openbsd_hw.c b/libs/openssl/crypto/evp/openbsd_hw.c new file mode 100644 index 00000000..75d12e23 --- /dev/null +++ b/libs/openssl/crypto/evp/openbsd_hw.c @@ -0,0 +1,431 @@ +/* Written by Ben Laurie, 2001 */ +/* + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "evp_locl.h" + +/* + * This stuff should now all be supported through + * crypto/engine/hw_openbsd_dev_crypto.c unless I botched it up + */ +static void *dummy = &dummy; + +#if 0 + +/* check flag after OpenSSL headers to ensure make depend works */ +# ifdef OPENSSL_OPENBSD_DEV_CRYPTO + +# include +# include +# include +# include +# include +# include +# include + +/* longest key supported in hardware */ +# define MAX_HW_KEY 24 +# define MAX_HW_IV 8 + +# define MD5_DIGEST_LENGTH 16 +# define MD5_CBLOCK 64 + +static int fd; +static int dev_failed; + +typedef struct session_op session_op; + +# define CDATA(ctx) EVP_C_DATA(session_op,ctx) + +static void err(const char *str) +{ + fprintf(stderr, "%s: errno %d\n", str, errno); +} + +static int dev_crypto_init(session_op *ses) +{ + if (dev_failed) + return 0; + if (!fd) { + int cryptodev_fd; + + if ((cryptodev_fd = open("/dev/crypto", O_RDWR, 0)) < 0) { + err("/dev/crypto"); + dev_failed = 1; + return 0; + } + if (ioctl(cryptodev_fd, CRIOGET, &fd) == -1) { + err("CRIOGET failed"); + close(cryptodev_fd); + dev_failed = 1; + return 0; + } + close(cryptodev_fd); + } + assert(ses); + memset(ses, '\0', sizeof *ses); + + return 1; +} + +static int dev_crypto_cleanup(EVP_CIPHER_CTX *ctx) +{ + if (ioctl(fd, CIOCFSESSION, &CDATA(ctx)->ses) == -1) + err("CIOCFSESSION failed"); + + OPENSSL_free(CDATA(ctx)->key); + + return 1; +} + +static int dev_crypto_init_key(EVP_CIPHER_CTX *ctx, int cipher, + const unsigned char *key, int klen) +{ + if (!dev_crypto_init(CDATA(ctx))) + return 0; + + CDATA(ctx)->key = OPENSSL_malloc(MAX_HW_KEY); + + assert(ctx->cipher->iv_len <= MAX_HW_IV); + + memcpy(CDATA(ctx)->key, key, klen); + + CDATA(ctx)->cipher = cipher; + CDATA(ctx)->keylen = klen; + + if (ioctl(fd, CIOCGSESSION, CDATA(ctx)) == -1) { + err("CIOCGSESSION failed"); + return 0; + } + return 1; +} + +static int dev_crypto_cipher(EVP_CIPHER_CTX *ctx, unsigned char *out, + const unsigned char *in, unsigned int inl) +{ + struct crypt_op cryp; + unsigned char lb[MAX_HW_IV]; + + if (!inl) + return 1; + + assert(CDATA(ctx)); + assert(!dev_failed); + + memset(&cryp, '\0', sizeof cryp); + cryp.ses = CDATA(ctx)->ses; + cryp.op = ctx->encrypt ? COP_ENCRYPT : COP_DECRYPT; + cryp.flags = 0; + cryp.len = inl; + assert((inl & (ctx->cipher->block_size - 1)) == 0); + cryp.src = (caddr_t) in; + cryp.dst = (caddr_t) out; + cryp.mac = 0; + if (ctx->cipher->iv_len) + cryp.iv = (caddr_t) ctx->iv; + + if (!ctx->encrypt) + memcpy(lb, &in[cryp.len - ctx->cipher->iv_len], ctx->cipher->iv_len); + + if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { + if (errno == EINVAL) { /* buffers are misaligned */ + unsigned int cinl = 0; + char *cin = NULL; + char *cout = NULL; + + /* NB: this can only make cinl != inl with stream ciphers */ + cinl = (inl + 3) / 4 * 4; + + if (((unsigned long)in & 3) || cinl != inl) { + cin = OPENSSL_malloc(cinl); + memcpy(cin, in, inl); + cryp.src = cin; + } + + if (((unsigned long)out & 3) || cinl != inl) { + cout = OPENSSL_malloc(cinl); + cryp.dst = cout; + } + + cryp.len = cinl; + + if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { + err("CIOCCRYPT(2) failed"); + printf("src=%p dst=%p\n", cryp.src, cryp.dst); + abort(); + return 0; + } + + if (cout) { + memcpy(out, cout, inl); + OPENSSL_free(cout); + } + if (cin) + OPENSSL_free(cin); + } else { + err("CIOCCRYPT failed"); + abort(); + return 0; + } + } + + if (ctx->encrypt) + memcpy(ctx->iv, &out[cryp.len - ctx->cipher->iv_len], + ctx->cipher->iv_len); + else + memcpy(ctx->iv, lb, ctx->cipher->iv_len); + + return 1; +} + +static int dev_crypto_des_ede3_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, int enc) +{ + return dev_crypto_init_key(ctx, CRYPTO_3DES_CBC, key, 24); +} + +# define dev_crypto_des_ede3_cbc_cipher dev_crypto_cipher + +BLOCK_CIPHER_def_cbc(dev_crypto_des_ede3, session_op, NID_des_ede3, 8, 24, 8, + 0, dev_crypto_des_ede3_init_key, + dev_crypto_cleanup, + EVP_CIPHER_set_asn1_iv, EVP_CIPHER_get_asn1_iv, NULL) + +static int dev_crypto_rc4_init_key(EVP_CIPHER_CTX *ctx, + const unsigned char *key, + const unsigned char *iv, int enc) +{ + return dev_crypto_init_key(ctx, CRYPTO_ARC4, key, 16); +} + +static const EVP_CIPHER r4_cipher = { + NID_rc4, + 1, 16, 0, /* FIXME: key should be up to 256 bytes */ + EVP_CIPH_VARIABLE_LENGTH, + dev_crypto_rc4_init_key, + dev_crypto_cipher, + dev_crypto_cleanup, + sizeof(session_op), + NULL, + NULL, + NULL +}; + +const EVP_CIPHER *EVP_dev_crypto_rc4(void) +{ + return &r4_cipher; +} + +typedef struct { + session_op sess; + char *data; + int len; + unsigned char md[EVP_MAX_MD_SIZE]; +} MD_DATA; + +static int dev_crypto_init_digest(MD_DATA *md_data, int mac) +{ + if (!dev_crypto_init(&md_data->sess)) + return 0; + + md_data->len = 0; + md_data->data = NULL; + + md_data->sess.mac = mac; + + if (ioctl(fd, CIOCGSESSION, &md_data->sess) == -1) { + err("CIOCGSESSION failed"); + return 0; + } + return 1; +} + +static int dev_crypto_cleanup_digest(MD_DATA *md_data) +{ + if (ioctl(fd, CIOCFSESSION, &md_data->sess.ses) == -1) { + err("CIOCFSESSION failed"); + return 0; + } + + return 1; +} + +/* FIXME: if device can do chained MACs, then don't accumulate */ +/* FIXME: move accumulation to the framework */ +static int dev_crypto_md5_init(EVP_MD_CTX *ctx) +{ + return dev_crypto_init_digest(ctx->md_data, CRYPTO_MD5); +} + +static int do_digest(int ses, unsigned char *md, const void *data, int len) +{ + struct crypt_op cryp; + static unsigned char md5zero[16] = { + 0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04, + 0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e + }; + + /* some cards can't do zero length */ + if (!len) { + memcpy(md, md5zero, 16); + return 1; + } + + memset(&cryp, '\0', sizeof cryp); + cryp.ses = ses; + cryp.op = COP_ENCRYPT; /* required to do the MAC rather than check + * it */ + cryp.len = len; + cryp.src = (caddr_t) data; + cryp.dst = (caddr_t) data; // FIXME!!! + cryp.mac = (caddr_t) md; + + if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { + if (errno == EINVAL) { /* buffer is misaligned */ + char *dcopy; + + dcopy = OPENSSL_malloc(len); + memcpy(dcopy, data, len); + cryp.src = dcopy; + cryp.dst = cryp.src; // FIXME!!! + + if (ioctl(fd, CIOCCRYPT, &cryp) == -1) { + err("CIOCCRYPT(MAC2) failed"); + abort(); + return 0; + } + OPENSSL_free(dcopy); + } else { + err("CIOCCRYPT(MAC) failed"); + abort(); + return 0; + } + } + // printf("done\n"); + + return 1; +} + +static int dev_crypto_md5_update(EVP_MD_CTX *ctx, const void *data, + unsigned long len) +{ + MD_DATA *md_data = ctx->md_data; + + if (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) + return do_digest(md_data->sess.ses, md_data->md, data, len); + + md_data->data = OPENSSL_realloc(md_data->data, md_data->len + len); + memcpy(md_data->data + md_data->len, data, len); + md_data->len += len; + + return 1; +} + +static int dev_crypto_md5_final(EVP_MD_CTX *ctx, unsigned char *md) +{ + int ret; + MD_DATA *md_data = ctx->md_data; + + if (ctx->flags & EVP_MD_CTX_FLAG_ONESHOT) { + memcpy(md, md_data->md, MD5_DIGEST_LENGTH); + ret = 1; + } else { + ret = do_digest(md_data->sess.ses, md, md_data->data, md_data->len); + OPENSSL_free(md_data->data); + md_data->data = NULL; + md_data->len = 0; + } + + return ret; +} + +static int dev_crypto_md5_copy(EVP_MD_CTX *to, const EVP_MD_CTX *from) +{ + const MD_DATA *from_md = from->md_data; + MD_DATA *to_md = to->md_data; + + // How do we copy sessions? + assert(from->digest->flags & EVP_MD_FLAG_ONESHOT); + + to_md->data = OPENSSL_malloc(from_md->len); + memcpy(to_md->data, from_md->data, from_md->len); + + return 1; +} + +static int dev_crypto_md5_cleanup(EVP_MD_CTX *ctx) +{ + return dev_crypto_cleanup_digest(ctx->md_data); +} + +static const EVP_MD md5_md = { + NID_md5, + NID_md5WithRSAEncryption, + MD5_DIGEST_LENGTH, + EVP_MD_FLAG_ONESHOT, // XXX: set according to device info... + dev_crypto_md5_init, + dev_crypto_md5_update, + dev_crypto_md5_final, + dev_crypto_md5_copy, + dev_crypto_md5_cleanup, + EVP_PKEY_RSA_method, + MD5_CBLOCK, + sizeof(MD_DATA), +}; + +const EVP_MD *EVP_dev_crypto_md5(void) +{ + return &md5_md; +} + +# endif +#endif diff --git a/libs/openssl/crypto/evp/p5_crpt.c b/libs/openssl/crypto/evp/p5_crpt.c new file mode 100644 index 00000000..d06ab90a --- /dev/null +++ b/libs/openssl/crypto/evp/p5_crpt.c @@ -0,0 +1,149 @@ +/* p5_crpt.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include +#include + +/* + * Doesn't do anything now: Builtin PBE algorithms in static table. + */ + +void PKCS5_PBE_add(void) +{ +} + +int PKCS5_PBE_keyivgen(EVP_CIPHER_CTX *cctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de) +{ + EVP_MD_CTX ctx; + unsigned char md_tmp[EVP_MAX_MD_SIZE]; + unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; + int i; + PBEPARAM *pbe; + int saltlen, iter; + unsigned char *salt; + const unsigned char *pbuf; + int mdsize; + int rv = 0; + EVP_MD_CTX_init(&ctx); + + /* Extract useful info from parameter */ + if (param == NULL || param->type != V_ASN1_SEQUENCE || + param->value.sequence == NULL) { + EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); + return 0; + } + + pbuf = param->value.sequence->data; + if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) { + EVPerr(EVP_F_PKCS5_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); + return 0; + } + + if (!pbe->iter) + iter = 1; + else + iter = ASN1_INTEGER_get(pbe->iter); + salt = pbe->salt->data; + saltlen = pbe->salt->length; + + if (!pass) + passlen = 0; + else if (passlen == -1) + passlen = strlen(pass); + + if (!EVP_DigestInit_ex(&ctx, md, NULL)) + goto err; + if (!EVP_DigestUpdate(&ctx, pass, passlen)) + goto err; + if (!EVP_DigestUpdate(&ctx, salt, saltlen)) + goto err; + PBEPARAM_free(pbe); + if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL)) + goto err; + mdsize = EVP_MD_size(md); + if (mdsize < 0) + return 0; + for (i = 1; i < iter; i++) { + if (!EVP_DigestInit_ex(&ctx, md, NULL)) + goto err; + if (!EVP_DigestUpdate(&ctx, md_tmp, mdsize)) + goto err; + if (!EVP_DigestFinal_ex(&ctx, md_tmp, NULL)) + goto err; + } + OPENSSL_assert(EVP_CIPHER_key_length(cipher) <= (int)sizeof(md_tmp)); + memcpy(key, md_tmp, EVP_CIPHER_key_length(cipher)); + OPENSSL_assert(EVP_CIPHER_iv_length(cipher) <= 16); + memcpy(iv, md_tmp + (16 - EVP_CIPHER_iv_length(cipher)), + EVP_CIPHER_iv_length(cipher)); + if (!EVP_CipherInit_ex(cctx, cipher, NULL, key, iv, en_de)) + goto err; + OPENSSL_cleanse(md_tmp, EVP_MAX_MD_SIZE); + OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); + OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); + rv = 1; + err: + EVP_MD_CTX_cleanup(&ctx); + return rv; +} diff --git a/libs/openssl/crypto/evp/p5_crpt2.c b/libs/openssl/crypto/evp/p5_crpt2.c new file mode 100644 index 00000000..f2ae1e57 --- /dev/null +++ b/libs/openssl/crypto/evp/p5_crpt2.c @@ -0,0 +1,334 @@ +/* p5_crpt2.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include +#include +#include "cryptlib.h" +#if !defined(OPENSSL_NO_HMAC) && !defined(OPENSSL_NO_SHA) +# include +# include +# include +# include "evp_locl.h" + +/* set this to print out info about the keygen algorithm */ +/* #define DEBUG_PKCS5V2 */ + +# ifdef DEBUG_PKCS5V2 +static void h__dump(const unsigned char *p, int len); +# endif + +/* + * This is an implementation of PKCS#5 v2.0 password based encryption key + * derivation function PBKDF2. SHA1 version verified against test vectors + * posted by Peter Gutmann to the PKCS-TNG + * mailing list. + */ + +int PKCS5_PBKDF2_HMAC(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + const EVP_MD *digest, int keylen, unsigned char *out) +{ + unsigned char digtmp[EVP_MAX_MD_SIZE], *p, itmp[4]; + int cplen, j, k, tkeylen, mdlen; + unsigned long i = 1; + HMAC_CTX hctx_tpl, hctx; + + mdlen = EVP_MD_size(digest); + if (mdlen < 0) + return 0; + + HMAC_CTX_init(&hctx_tpl); + p = out; + tkeylen = keylen; + if (!pass) + passlen = 0; + else if (passlen == -1) + passlen = strlen(pass); + if (!HMAC_Init_ex(&hctx_tpl, pass, passlen, digest, NULL)) { + HMAC_CTX_cleanup(&hctx_tpl); + return 0; + } + while (tkeylen) { + if (tkeylen > mdlen) + cplen = mdlen; + else + cplen = tkeylen; + /* + * We are unlikely to ever use more than 256 blocks (5120 bits!) but + * just in case... + */ + itmp[0] = (unsigned char)((i >> 24) & 0xff); + itmp[1] = (unsigned char)((i >> 16) & 0xff); + itmp[2] = (unsigned char)((i >> 8) & 0xff); + itmp[3] = (unsigned char)(i & 0xff); + if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) { + HMAC_CTX_cleanup(&hctx_tpl); + return 0; + } + if (!HMAC_Update(&hctx, salt, saltlen) + || !HMAC_Update(&hctx, itmp, 4) + || !HMAC_Final(&hctx, digtmp, NULL)) { + HMAC_CTX_cleanup(&hctx_tpl); + HMAC_CTX_cleanup(&hctx); + return 0; + } + HMAC_CTX_cleanup(&hctx); + memcpy(p, digtmp, cplen); + for (j = 1; j < iter; j++) { + if (!HMAC_CTX_copy(&hctx, &hctx_tpl)) { + HMAC_CTX_cleanup(&hctx_tpl); + return 0; + } + if (!HMAC_Update(&hctx, digtmp, mdlen) + || !HMAC_Final(&hctx, digtmp, NULL)) { + HMAC_CTX_cleanup(&hctx_tpl); + HMAC_CTX_cleanup(&hctx); + return 0; + } + HMAC_CTX_cleanup(&hctx); + for (k = 0; k < cplen; k++) + p[k] ^= digtmp[k]; + } + tkeylen -= cplen; + i++; + p += cplen; + } + HMAC_CTX_cleanup(&hctx_tpl); +# ifdef DEBUG_PKCS5V2 + fprintf(stderr, "Password:\n"); + h__dump(pass, passlen); + fprintf(stderr, "Salt:\n"); + h__dump(salt, saltlen); + fprintf(stderr, "Iteration count %d\n", iter); + fprintf(stderr, "Key:\n"); + h__dump(out, keylen); +# endif + return 1; +} + +int PKCS5_PBKDF2_HMAC_SHA1(const char *pass, int passlen, + const unsigned char *salt, int saltlen, int iter, + int keylen, unsigned char *out) +{ + return PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, EVP_sha1(), + keylen, out); +} + +# ifdef DO_TEST +main() +{ + unsigned char out[4]; + unsigned char salt[] = { 0x12, 0x34, 0x56, 0x78 }; + PKCS5_PBKDF2_HMAC_SHA1("password", -1, salt, 4, 5, 4, out); + fprintf(stderr, "Out %02X %02X %02X %02X\n", + out[0], out[1], out[2], out[3]); +} + +# endif + +/* + * Now the key derivation function itself. This is a bit evil because it has + * to check the ASN1 parameters are valid: and there are quite a few of + * them... + */ + +int PKCS5_v2_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *c, + const EVP_MD *md, int en_de) +{ + const unsigned char *pbuf; + int plen; + PBE2PARAM *pbe2 = NULL; + const EVP_CIPHER *cipher; + + int rv = 0; + + if (param == NULL || param->type != V_ASN1_SEQUENCE || + param->value.sequence == NULL) { + EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); + goto err; + } + + pbuf = param->value.sequence->data; + plen = param->value.sequence->length; + if (!(pbe2 = d2i_PBE2PARAM(NULL, &pbuf, plen))) { + EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_DECODE_ERROR); + goto err; + } + + /* See if we recognise the key derivation function */ + + if (OBJ_obj2nid(pbe2->keyfunc->algorithm) != NID_id_pbkdf2) { + EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, + EVP_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); + goto err; + } + + /* + * lets see if we recognise the encryption algorithm. + */ + + cipher = EVP_get_cipherbyobj(pbe2->encryption->algorithm); + + if (!cipher) { + EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_UNSUPPORTED_CIPHER); + goto err; + } + + /* Fixup cipher based on AlgorithmIdentifier */ + if (!EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, en_de)) + goto err; + if (EVP_CIPHER_asn1_to_param(ctx, pbe2->encryption->parameter) < 0) { + EVPerr(EVP_F_PKCS5_V2_PBE_KEYIVGEN, EVP_R_CIPHER_PARAMETER_ERROR); + goto err; + } + rv = PKCS5_v2_PBKDF2_keyivgen(ctx, pass, passlen, + pbe2->keyfunc->parameter, c, md, en_de); + err: + PBE2PARAM_free(pbe2); + return rv; +} + +int PKCS5_v2_PBKDF2_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, + int passlen, ASN1_TYPE *param, + const EVP_CIPHER *c, const EVP_MD *md, int en_de) +{ + unsigned char *salt, key[EVP_MAX_KEY_LENGTH]; + const unsigned char *pbuf; + int saltlen, iter, plen; + int rv = 0; + unsigned int keylen = 0; + int prf_nid, hmac_md_nid; + PBKDF2PARAM *kdf = NULL; + const EVP_MD *prfmd; + + if (EVP_CIPHER_CTX_cipher(ctx) == NULL) { + EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_NO_CIPHER_SET); + goto err; + } + keylen = EVP_CIPHER_CTX_key_length(ctx); + OPENSSL_assert(keylen <= sizeof key); + + /* Decode parameter */ + + if (!param || (param->type != V_ASN1_SEQUENCE)) { + EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR); + goto err; + } + + pbuf = param->value.sequence->data; + plen = param->value.sequence->length; + + if (!(kdf = d2i_PBKDF2PARAM(NULL, &pbuf, plen))) { + EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_DECODE_ERROR); + goto err; + } + + keylen = EVP_CIPHER_CTX_key_length(ctx); + + /* Now check the parameters of the kdf */ + + if (kdf->keylength && (ASN1_INTEGER_get(kdf->keylength) != (int)keylen)) { + EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_KEYLENGTH); + goto err; + } + + if (kdf->prf) + prf_nid = OBJ_obj2nid(kdf->prf->algorithm); + else + prf_nid = NID_hmacWithSHA1; + + if (!EVP_PBE_find(EVP_PBE_TYPE_PRF, prf_nid, NULL, &hmac_md_nid, 0)) { + EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); + goto err; + } + + prfmd = EVP_get_digestbynid(hmac_md_nid); + if (prfmd == NULL) { + EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_PRF); + goto err; + } + + if (kdf->salt->type != V_ASN1_OCTET_STRING) { + EVPerr(EVP_F_PKCS5_V2_PBKDF2_KEYIVGEN, EVP_R_UNSUPPORTED_SALT_TYPE); + goto err; + } + + /* it seems that its all OK */ + salt = kdf->salt->value.octet_string->data; + saltlen = kdf->salt->value.octet_string->length; + iter = ASN1_INTEGER_get(kdf->iter); + if (!PKCS5_PBKDF2_HMAC(pass, passlen, salt, saltlen, iter, prfmd, + keylen, key)) + goto err; + rv = EVP_CipherInit_ex(ctx, NULL, NULL, key, NULL, en_de); + err: + OPENSSL_cleanse(key, keylen); + PBKDF2PARAM_free(kdf); + return rv; +} + +# ifdef DEBUG_PKCS5V2 +static void h__dump(const unsigned char *p, int len) +{ + for (; len--; p++) + fprintf(stderr, "%02X ", *p); + fprintf(stderr, "\n"); +} +# endif +#endif diff --git a/libs/openssl/crypto/evp/p_dec.c b/libs/openssl/crypto/evp/p_dec.c new file mode 100644 index 00000000..225b8b45 --- /dev/null +++ b/libs/openssl/crypto/evp/p_dec.c @@ -0,0 +1,87 @@ +/* crypto/evp/p_dec.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#include +#include +#include + +int EVP_PKEY_decrypt_old(unsigned char *key, const unsigned char *ek, int ekl, + EVP_PKEY *priv) +{ + int ret = -1; + +#ifndef OPENSSL_NO_RSA + if (priv->type != EVP_PKEY_RSA) { +#endif + EVPerr(EVP_F_EVP_PKEY_DECRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA); +#ifndef OPENSSL_NO_RSA + goto err; + } + + ret = + RSA_private_decrypt(ekl, ek, key, priv->pkey.rsa, RSA_PKCS1_PADDING); + err: +#endif + return (ret); +} diff --git a/libs/openssl/crypto/evp/p_enc.c b/libs/openssl/crypto/evp/p_enc.c new file mode 100644 index 00000000..f565f33f --- /dev/null +++ b/libs/openssl/crypto/evp/p_enc.c @@ -0,0 +1,87 @@ +/* crypto/evp/p_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#include +#include +#include + +int EVP_PKEY_encrypt_old(unsigned char *ek, const unsigned char *key, + int key_len, EVP_PKEY *pubk) +{ + int ret = 0; + +#ifndef OPENSSL_NO_RSA + if (pubk->type != EVP_PKEY_RSA) { +#endif + EVPerr(EVP_F_EVP_PKEY_ENCRYPT_OLD, EVP_R_PUBLIC_KEY_NOT_RSA); +#ifndef OPENSSL_NO_RSA + goto err; + } + ret = + RSA_public_encrypt(key_len, key, ek, pubk->pkey.rsa, + RSA_PKCS1_PADDING); + err: +#endif + return (ret); +} diff --git a/libs/openssl/crypto/evp/p_lib.c b/libs/openssl/crypto/evp/p_lib.c new file mode 100644 index 00000000..375f5612 --- /dev/null +++ b/libs/openssl/crypto/evp/p_lib.c @@ -0,0 +1,456 @@ +/* crypto/evp/p_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#ifndef OPENSSL_NO_DSA +# include +#endif +#ifndef OPENSSL_NO_DH +# include +#endif + +#ifndef OPENSSL_NO_ENGINE +# include +#endif + +#include "asn1_locl.h" + +static void EVP_PKEY_free_it(EVP_PKEY *x); + +int EVP_PKEY_bits(EVP_PKEY *pkey) +{ + if (pkey && pkey->ameth && pkey->ameth->pkey_bits) + return pkey->ameth->pkey_bits(pkey); + return 0; +} + +int EVP_PKEY_size(EVP_PKEY *pkey) +{ + if (pkey && pkey->ameth && pkey->ameth->pkey_size) + return pkey->ameth->pkey_size(pkey); + return 0; +} + +int EVP_PKEY_save_parameters(EVP_PKEY *pkey, int mode) +{ +#ifndef OPENSSL_NO_DSA + if (pkey->type == EVP_PKEY_DSA) { + int ret = pkey->save_parameters; + + if (mode >= 0) + pkey->save_parameters = mode; + return (ret); + } +#endif +#ifndef OPENSSL_NO_EC + if (pkey->type == EVP_PKEY_EC) { + int ret = pkey->save_parameters; + + if (mode >= 0) + pkey->save_parameters = mode; + return (ret); + } +#endif + return (0); +} + +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) +{ + if (to->type != from->type) { + EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_DIFFERENT_KEY_TYPES); + goto err; + } + + if (EVP_PKEY_missing_parameters(from)) { + EVPerr(EVP_F_EVP_PKEY_COPY_PARAMETERS, EVP_R_MISSING_PARAMETERS); + goto err; + } + if (from->ameth && from->ameth->param_copy) + return from->ameth->param_copy(to, from); + err: + return 0; +} + +int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey) +{ + if (pkey->ameth && pkey->ameth->param_missing) + return pkey->ameth->param_missing(pkey); + return 0; +} + +int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (a->type != b->type) + return -1; + if (a->ameth && a->ameth->param_cmp) + return a->ameth->param_cmp(a, b); + return -2; +} + +int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (a->type != b->type) + return -1; + + if (a->ameth) { + int ret; + /* Compare parameters if the algorithm has them */ + if (a->ameth->param_cmp) { + ret = a->ameth->param_cmp(a, b); + if (ret <= 0) + return ret; + } + + if (a->ameth->pub_cmp) + return a->ameth->pub_cmp(a, b); + } + + return -2; +} + +EVP_PKEY *EVP_PKEY_new(void) +{ + EVP_PKEY *ret; + + ret = (EVP_PKEY *)OPENSSL_malloc(sizeof(EVP_PKEY)); + if (ret == NULL) { + EVPerr(EVP_F_EVP_PKEY_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + ret->type = EVP_PKEY_NONE; + ret->save_type = EVP_PKEY_NONE; + ret->references = 1; + ret->ameth = NULL; + ret->engine = NULL; + ret->pkey.ptr = NULL; + ret->attributes = NULL; + ret->save_parameters = 1; + return (ret); +} + +/* + * Setup a public key ASN1 method and ENGINE from a NID or a string. If pkey + * is NULL just return 1 or 0 if the algorithm exists. + */ + +static int pkey_set_type(EVP_PKEY *pkey, int type, const char *str, int len) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *e = NULL; + if (pkey) { + if (pkey->pkey.ptr) + EVP_PKEY_free_it(pkey); + /* + * If key type matches and a method exists then this lookup has + * succeeded once so just indicate success. + */ + if ((type == pkey->save_type) && pkey->ameth) + return 1; +#ifndef OPENSSL_NO_ENGINE + /* If we have an ENGINE release it */ + if (pkey->engine) { + ENGINE_finish(pkey->engine); + pkey->engine = NULL; + } +#endif + } + if (str) + ameth = EVP_PKEY_asn1_find_str(&e, str, len); + else + ameth = EVP_PKEY_asn1_find(&e, type); +#ifndef OPENSSL_NO_ENGINE + if (!pkey && e) + ENGINE_finish(e); +#endif + if (!ameth) { + EVPerr(EVP_F_PKEY_SET_TYPE, EVP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + if (pkey) { + pkey->ameth = ameth; + pkey->engine = e; + + pkey->type = pkey->ameth->pkey_id; + pkey->save_type = type; + } + return 1; +} + +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) +{ + return pkey_set_type(pkey, type, NULL, -1); +} + +int EVP_PKEY_set_type_str(EVP_PKEY *pkey, const char *str, int len) +{ + return pkey_set_type(pkey, EVP_PKEY_NONE, str, len); +} + +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) +{ + if (pkey == NULL || !EVP_PKEY_set_type(pkey, type)) + return 0; + pkey->pkey.ptr = key; + return (key != NULL); +} + +void *EVP_PKEY_get0(EVP_PKEY *pkey) +{ + return pkey->pkey.ptr; +} + +#ifndef OPENSSL_NO_RSA +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) +{ + int ret = EVP_PKEY_assign_RSA(pkey, key); + if (ret) + RSA_up_ref(key); + return ret; +} + +RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_RSA) { + EVPerr(EVP_F_EVP_PKEY_GET1_RSA, EVP_R_EXPECTING_AN_RSA_KEY); + return NULL; + } + RSA_up_ref(pkey->pkey.rsa); + return pkey->pkey.rsa; +} +#endif + +#ifndef OPENSSL_NO_DSA +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) +{ + int ret = EVP_PKEY_assign_DSA(pkey, key); + if (ret) + DSA_up_ref(key); + return ret; +} + +DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_DSA) { + EVPerr(EVP_F_EVP_PKEY_GET1_DSA, EVP_R_EXPECTING_A_DSA_KEY); + return NULL; + } + DSA_up_ref(pkey->pkey.dsa); + return pkey->pkey.dsa; +} +#endif + +#ifndef OPENSSL_NO_EC + +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) +{ + int ret = EVP_PKEY_assign_EC_KEY(pkey, key); + if (ret) + EC_KEY_up_ref(key); + return ret; +} + +EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_EC) { + EVPerr(EVP_F_EVP_PKEY_GET1_EC_KEY, EVP_R_EXPECTING_A_EC_KEY); + return NULL; + } + EC_KEY_up_ref(pkey->pkey.ec); + return pkey->pkey.ec; +} +#endif + +#ifndef OPENSSL_NO_DH + +int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *key) +{ + int ret = EVP_PKEY_assign_DH(pkey, key); + if (ret) + DH_up_ref(key); + return ret; +} + +DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey) +{ + if (pkey->type != EVP_PKEY_DH) { + EVPerr(EVP_F_EVP_PKEY_GET1_DH, EVP_R_EXPECTING_A_DH_KEY); + return NULL; + } + DH_up_ref(pkey->pkey.dh); + return pkey->pkey.dh; +} +#endif + +int EVP_PKEY_type(int type) +{ + int ret; + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *e; + ameth = EVP_PKEY_asn1_find(&e, type); + if (ameth) + ret = ameth->pkey_id; + else + ret = NID_undef; +#ifndef OPENSSL_NO_ENGINE + if (e) + ENGINE_finish(e); +#endif + return ret; +} + +int EVP_PKEY_id(const EVP_PKEY *pkey) +{ + return pkey->type; +} + +int EVP_PKEY_base_id(const EVP_PKEY *pkey) +{ + return EVP_PKEY_type(pkey->type); +} + +void EVP_PKEY_free(EVP_PKEY *x) +{ + int i; + + if (x == NULL) + return; + + i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY", x); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "EVP_PKEY_free, bad reference count\n"); + abort(); + } +#endif + EVP_PKEY_free_it(x); + if (x->attributes) + sk_X509_ATTRIBUTE_pop_free(x->attributes, X509_ATTRIBUTE_free); + OPENSSL_free(x); +} + +static void EVP_PKEY_free_it(EVP_PKEY *x) +{ + if (x->ameth && x->ameth->pkey_free) { + x->ameth->pkey_free(x); + x->pkey.ptr = NULL; + } +#ifndef OPENSSL_NO_ENGINE + if (x->engine) { + ENGINE_finish(x->engine); + x->engine = NULL; + } +#endif +} + +static int unsup_alg(BIO *out, const EVP_PKEY *pkey, int indent, + const char *kstr) +{ + BIO_indent(out, indent, 128); + BIO_printf(out, "%s algorithm \"%s\" unsupported\n", + kstr, OBJ_nid2ln(pkey->type)); + return 1; +} + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx) +{ + if (pkey->ameth && pkey->ameth->pub_print) + return pkey->ameth->pub_print(out, pkey, indent, pctx); + + return unsup_alg(out, pkey, indent, "Public Key"); +} + +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx) +{ + if (pkey->ameth && pkey->ameth->priv_print) + return pkey->ameth->priv_print(out, pkey, indent, pctx); + + return unsup_alg(out, pkey, indent, "Private Key"); +} + +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx) +{ + if (pkey->ameth && pkey->ameth->param_print) + return pkey->ameth->param_print(out, pkey, indent, pctx); + return unsup_alg(out, pkey, indent, "Parameters"); +} + +int EVP_PKEY_get_default_digest_nid(EVP_PKEY *pkey, int *pnid) +{ + if (!pkey->ameth || !pkey->ameth->pkey_ctrl) + return -2; + return pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_DEFAULT_MD_NID, + 0, pnid); +} diff --git a/libs/openssl/crypto/evp/p_open.c b/libs/openssl/crypto/evp/p_open.c new file mode 100644 index 00000000..229eb641 --- /dev/null +++ b/libs/openssl/crypto/evp/p_open.c @@ -0,0 +1,129 @@ +/* crypto/evp/p_open.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" + +#ifndef OPENSSL_NO_RSA + +# include +# include +# include +# include + +int EVP_OpenInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + const unsigned char *ek, int ekl, const unsigned char *iv, + EVP_PKEY *priv) +{ + unsigned char *key = NULL; + int i, size = 0, ret = 0; + + if (type) { + EVP_CIPHER_CTX_init(ctx); + if (!EVP_DecryptInit_ex(ctx, type, NULL, NULL, NULL)) + return 0; + } + + if (!priv) + return 1; + + if (priv->type != EVP_PKEY_RSA) { + EVPerr(EVP_F_EVP_OPENINIT, EVP_R_PUBLIC_KEY_NOT_RSA); + goto err; + } + + size = RSA_size(priv->pkey.rsa); + key = (unsigned char *)OPENSSL_malloc(size + 2); + if (key == NULL) { + /* ERROR */ + EVPerr(EVP_F_EVP_OPENINIT, ERR_R_MALLOC_FAILURE); + goto err; + } + + i = EVP_PKEY_decrypt_old(key, ek, ekl, priv); + if ((i <= 0) || !EVP_CIPHER_CTX_set_key_length(ctx, i)) { + /* ERROR */ + goto err; + } + if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) + goto err; + + ret = 1; + err: + if (key != NULL) + OPENSSL_cleanse(key, size); + OPENSSL_free(key); + return (ret); +} + +int EVP_OpenFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int i; + + i = EVP_DecryptFinal_ex(ctx, out, outl); + if (i) + i = EVP_DecryptInit_ex(ctx, NULL, NULL, NULL, NULL); + return (i); +} +#else /* !OPENSSL_NO_RSA */ + +# ifdef PEDANTIC +static void *dummy = &dummy; +# endif + +#endif diff --git a/libs/openssl/crypto/evp/p_seal.c b/libs/openssl/crypto/evp/p_seal.c new file mode 100644 index 00000000..ba9dfff2 --- /dev/null +++ b/libs/openssl/crypto/evp/p_seal.c @@ -0,0 +1,121 @@ +/* crypto/evp/p_seal.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#include +#include +#include + +int EVP_SealInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *type, + unsigned char **ek, int *ekl, unsigned char *iv, + EVP_PKEY **pubk, int npubk) +{ + unsigned char key[EVP_MAX_KEY_LENGTH]; + int i; + + if (type) { + EVP_CIPHER_CTX_init(ctx); + if (!EVP_EncryptInit_ex(ctx, type, NULL, NULL, NULL)) + return 0; + } + if ((npubk <= 0) || !pubk) + return 1; + if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) + return 0; + if (EVP_CIPHER_CTX_iv_length(ctx) + && RAND_bytes(iv, EVP_CIPHER_CTX_iv_length(ctx)) <= 0) + return 0; + + if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) + return 0; + + for (i = 0; i < npubk; i++) { + ekl[i] = + EVP_PKEY_encrypt_old(ek[i], key, EVP_CIPHER_CTX_key_length(ctx), + pubk[i]); + if (ekl[i] <= 0) + return (-1); + } + return (npubk); +} + +/*- MACRO +void EVP_SealUpdate(ctx,out,outl,in,inl) +EVP_CIPHER_CTX *ctx; +unsigned char *out; +int *outl; +unsigned char *in; +int inl; + { + EVP_EncryptUpdate(ctx,out,outl,in,inl); + } +*/ + +int EVP_SealFinal(EVP_CIPHER_CTX *ctx, unsigned char *out, int *outl) +{ + int i; + i = EVP_EncryptFinal_ex(ctx, out, outl); + if (i) + i = EVP_EncryptInit_ex(ctx, NULL, NULL, NULL, NULL); + return i; +} diff --git a/libs/openssl/crypto/evp/p_sign.c b/libs/openssl/crypto/evp/p_sign.c new file mode 100644 index 00000000..1b9ba060 --- /dev/null +++ b/libs/openssl/crypto/evp/p_sign.c @@ -0,0 +1,133 @@ +/* crypto/evp/p_sign.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +#ifdef undef +void EVP_SignInit(EVP_MD_CTX *ctx, EVP_MD *type) +{ + EVP_DigestInit_ex(ctx, type); +} + +void EVP_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count) +{ + EVP_DigestUpdate(ctx, data, count); +} +#endif + +int EVP_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey) +{ + unsigned char m[EVP_MAX_MD_SIZE]; + unsigned int m_len; + int i = 0, ok = 0, v; + EVP_MD_CTX tmp_ctx; + EVP_PKEY_CTX *pkctx = NULL; + + *siglen = 0; + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) + goto err; + if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len)) + goto err; + EVP_MD_CTX_cleanup(&tmp_ctx); + + if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { + size_t sltmp = (size_t)EVP_PKEY_size(pkey); + i = 0; + pkctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pkctx) + goto err; + if (EVP_PKEY_sign_init(pkctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) + goto err; + if (EVP_PKEY_sign(pkctx, sigret, &sltmp, m, m_len) <= 0) + goto err; + *siglen = sltmp; + i = 1; + err: + EVP_PKEY_CTX_free(pkctx); + return i; + } + + for (i = 0; i < 4; i++) { + v = ctx->digest->required_pkey_type[i]; + if (v == 0) + break; + if (pkey->type == v) { + ok = 1; + break; + } + } + if (!ok) { + EVPerr(EVP_F_EVP_SIGNFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE); + return (0); + } + + if (ctx->digest->sign == NULL) { + EVPerr(EVP_F_EVP_SIGNFINAL, EVP_R_NO_SIGN_FUNCTION_CONFIGURED); + return (0); + } + return (ctx->digest->sign(ctx->digest->type, m, m_len, sigret, siglen, + pkey->pkey.ptr)); +} diff --git a/libs/openssl/crypto/evp/p_verify.c b/libs/openssl/crypto/evp/p_verify.c new file mode 100644 index 00000000..65e1e216 --- /dev/null +++ b/libs/openssl/crypto/evp/p_verify.c @@ -0,0 +1,116 @@ +/* crypto/evp/p_verify.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +int EVP_VerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sigbuf, + unsigned int siglen, EVP_PKEY *pkey) +{ + unsigned char m[EVP_MAX_MD_SIZE]; + unsigned int m_len; + int i = 0, ok = 0, v; + EVP_MD_CTX tmp_ctx; + EVP_PKEY_CTX *pkctx = NULL; + + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx)) + goto err; + if (!EVP_DigestFinal_ex(&tmp_ctx, &(m[0]), &m_len)) + goto err; + EVP_MD_CTX_cleanup(&tmp_ctx); + + if (ctx->digest->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) { + i = -1; + pkctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pkctx) + goto err; + if (EVP_PKEY_verify_init(pkctx) <= 0) + goto err; + if (EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) <= 0) + goto err; + i = EVP_PKEY_verify(pkctx, sigbuf, siglen, m, m_len); + err: + EVP_PKEY_CTX_free(pkctx); + return i; + } + + for (i = 0; i < 4; i++) { + v = ctx->digest->required_pkey_type[i]; + if (v == 0) + break; + if (pkey->type == v) { + ok = 1; + break; + } + } + if (!ok) { + EVPerr(EVP_F_EVP_VERIFYFINAL, EVP_R_WRONG_PUBLIC_KEY_TYPE); + return (-1); + } + if (ctx->digest->verify == NULL) { + EVPerr(EVP_F_EVP_VERIFYFINAL, EVP_R_NO_VERIFY_FUNCTION_CONFIGURED); + return (0); + } + + return (ctx->digest->verify(ctx->digest->type, m, m_len, + sigbuf, siglen, pkey->pkey.ptr)); +} diff --git a/libs/openssl/crypto/evp/pmeth_fn.c b/libs/openssl/crypto/evp/pmeth_fn.c new file mode 100644 index 00000000..a8b7f2f6 --- /dev/null +++ b/libs/openssl/crypto/evp/pmeth_fn.c @@ -0,0 +1,346 @@ +/* pmeth_fn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include "evp_locl.h" + +#define M_check_autoarg(ctx, arg, arglen, err) \ + if (ctx->pmeth->flags & EVP_PKEY_FLAG_AUTOARGLEN) \ + { \ + size_t pksize = (size_t)EVP_PKEY_size(ctx->pkey); \ + if (!arg) \ + { \ + *arglen = pksize; \ + return 1; \ + } \ + else if (*arglen < pksize) \ + { \ + EVPerr(err, EVP_R_BUFFER_TOO_SMALL); /*ckerr_ignore*/\ + return 0; \ + } \ + } + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { + EVPerr(EVP_F_EVP_PKEY_SIGN_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_SIGN; + if (!ctx->pmeth->sign_init) + return 1; + ret = ctx->pmeth->sign_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, size_t tbslen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { + EVPerr(EVP_F_EVP_PKEY_SIGN, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_SIGN) { + EVPerr(EVP_F_EVP_PKEY_SIGN, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, sig, siglen, EVP_F_EVP_PKEY_SIGN) + return ctx->pmeth->sign(ctx, sig, siglen, tbs, tbslen); +} + +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { + EVPerr(EVP_F_EVP_PKEY_VERIFY_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_VERIFY; + if (!ctx->pmeth->verify_init) + return 1; + ret = ctx->pmeth->verify_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { + EVPerr(EVP_F_EVP_PKEY_VERIFY, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_VERIFY) { + EVPerr(EVP_F_EVP_PKEY_VERIFY, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + return ctx->pmeth->verify(ctx, sig, siglen, tbs, tbslen); +} + +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { + EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_VERIFYRECOVER; + if (!ctx->pmeth->verify_recover_init) + return 1; + ret = ctx->pmeth->verify_recover_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { + EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) { + EVPerr(EVP_F_EVP_PKEY_VERIFY_RECOVER, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, rout, routlen, EVP_F_EVP_PKEY_VERIFY_RECOVER) + return ctx->pmeth->verify_recover(ctx, rout, routlen, sig, siglen); +} + +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { + EVPerr(EVP_F_EVP_PKEY_ENCRYPT_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_ENCRYPT; + if (!ctx->pmeth->encrypt_init) + return 1; + ret = ctx->pmeth->encrypt_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { + EVPerr(EVP_F_EVP_PKEY_ENCRYPT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { + EVPerr(EVP_F_EVP_PKEY_ENCRYPT, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_ENCRYPT) + return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); +} + +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { + EVPerr(EVP_F_EVP_PKEY_DECRYPT_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_DECRYPT; + if (!ctx->pmeth->decrypt_init) + return 1; + ret = ctx->pmeth->decrypt_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { + EVPerr(EVP_F_EVP_PKEY_DECRYPT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DECRYPT) { + EVPerr(EVP_F_EVP_PKEY_DECRYPT, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, out, outlen, EVP_F_EVP_PKEY_DECRYPT) + return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); +} + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_DERIVE; + if (!ctx->pmeth->derive_init) + return 1; + ret = ctx->pmeth->derive_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer) +{ + int ret; + if (!ctx || !ctx->pmeth + || !(ctx->pmeth->derive || ctx->pmeth->encrypt || ctx->pmeth->decrypt) + || !ctx->pmeth->ctrl) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE + && ctx->operation != EVP_PKEY_OP_ENCRYPT + && ctx->operation != EVP_PKEY_OP_DECRYPT) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, + EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); + + if (ret <= 0) + return ret; + + if (ret == 2) + return 1; + + if (!ctx->pkey) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_NO_KEY_SET); + return -1; + } + + if (ctx->pkey->type != peer->type) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_KEY_TYPES); + return -1; + } + + /* + * ran@cryptocom.ru: For clarity. The error is if parameters in peer are + * present (!missing) but don't match. EVP_PKEY_cmp_parameters may return + * 1 (match), 0 (don't match) and -2 (comparison is not defined). -1 + * (different key types) is impossible here because it is checked earlier. + * -2 is OK for us here, as well as 1, so we can check for 0 only. + */ + if (!EVP_PKEY_missing_parameters(peer) && + !EVP_PKEY_cmp_parameters(ctx->pkey, peer)) { + EVPerr(EVP_F_EVP_PKEY_DERIVE_SET_PEER, EVP_R_DIFFERENT_PARAMETERS); + return -1; + } + + if (ctx->peerkey) + EVP_PKEY_free(ctx->peerkey); + ctx->peerkey = peer; + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer); + + if (ret <= 0) { + ctx->peerkey = NULL; + return ret; + } + + CRYPTO_add(&peer->references, 1, CRYPTO_LOCK_EVP_PKEY); + return 1; +} + +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, unsigned char *key, size_t *pkeylen) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { + EVPerr(EVP_F_EVP_PKEY_DERIVE, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE) { + EVPerr(EVP_F_EVP_PKEY_DERIVE, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + M_check_autoarg(ctx, key, pkeylen, EVP_F_EVP_PKEY_DERIVE) + return ctx->pmeth->derive(ctx, key, pkeylen); +} diff --git a/libs/openssl/crypto/evp/pmeth_gn.c b/libs/openssl/crypto/evp/pmeth_gn.c new file mode 100644 index 00000000..6435f1b6 --- /dev/null +++ b/libs/openssl/crypto/evp/pmeth_gn.c @@ -0,0 +1,220 @@ +/* pmeth_gn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include "evp_locl.h" + +int EVP_PKEY_paramgen_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { + EVPerr(EVP_F_EVP_PKEY_PARAMGEN_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_PARAMGEN; + if (!ctx->pmeth->paramgen_init) + return 1; + ret = ctx->pmeth->paramgen_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->paramgen) { + EVPerr(EVP_F_EVP_PKEY_PARAMGEN, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + + if (ctx->operation != EVP_PKEY_OP_PARAMGEN) { + EVPerr(EVP_F_EVP_PKEY_PARAMGEN, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (ppkey == NULL) + return -1; + + if (*ppkey == NULL) + *ppkey = EVP_PKEY_new(); + + if (*ppkey == NULL) { + EVPerr(EVP_F_EVP_PKEY_PARAMGEN, ERR_R_MALLOC_FAILURE); + return -1; + } + + ret = ctx->pmeth->paramgen(ctx, *ppkey); + if (ret <= 0) { + EVP_PKEY_free(*ppkey); + *ppkey = NULL; + } + return ret; +} + +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { + EVPerr(EVP_F_EVP_PKEY_KEYGEN_INIT, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + ctx->operation = EVP_PKEY_OP_KEYGEN; + if (!ctx->pmeth->keygen_init) + return 1; + ret = ctx->pmeth->keygen_init(ctx); + if (ret <= 0) + ctx->operation = EVP_PKEY_OP_UNDEFINED; + return ret; +} + +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) +{ + int ret; + + if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { + EVPerr(EVP_F_EVP_PKEY_KEYGEN, + EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + } + if (ctx->operation != EVP_PKEY_OP_KEYGEN) { + EVPerr(EVP_F_EVP_PKEY_KEYGEN, EVP_R_OPERATON_NOT_INITIALIZED); + return -1; + } + + if (!ppkey) + return -1; + + if (!*ppkey) + *ppkey = EVP_PKEY_new(); + + ret = ctx->pmeth->keygen(ctx, *ppkey); + if (ret <= 0) { + EVP_PKEY_free(*ppkey); + *ppkey = NULL; + } + return ret; +} + +void EVP_PKEY_CTX_set_cb(EVP_PKEY_CTX *ctx, EVP_PKEY_gen_cb *cb) +{ + ctx->pkey_gencb = cb; +} + +EVP_PKEY_gen_cb *EVP_PKEY_CTX_get_cb(EVP_PKEY_CTX *ctx) +{ + return ctx->pkey_gencb; +} + +/* + * "translation callback" to call EVP_PKEY_CTX callbacks using BN_GENCB style + * callbacks. + */ + +static int trans_cb(int a, int b, BN_GENCB *gcb) +{ + EVP_PKEY_CTX *ctx = gcb->arg; + ctx->keygen_info[0] = a; + ctx->keygen_info[1] = b; + return ctx->pkey_gencb(ctx); +} + +void evp_pkey_set_cb_translate(BN_GENCB *cb, EVP_PKEY_CTX *ctx) +{ + BN_GENCB_set(cb, trans_cb, ctx) +} + +int EVP_PKEY_CTX_get_keygen_info(EVP_PKEY_CTX *ctx, int idx) +{ + if (idx == -1) + return ctx->keygen_info_count; + if (idx < 0 || idx > ctx->keygen_info_count) + return 0; + return ctx->keygen_info[idx]; +} + +EVP_PKEY *EVP_PKEY_new_mac_key(int type, ENGINE *e, + const unsigned char *key, int keylen) +{ + EVP_PKEY_CTX *mac_ctx = NULL; + EVP_PKEY *mac_key = NULL; + mac_ctx = EVP_PKEY_CTX_new_id(type, e); + if (!mac_ctx) + return NULL; + if (EVP_PKEY_keygen_init(mac_ctx) <= 0) + goto merr; + if (EVP_PKEY_CTX_ctrl(mac_ctx, -1, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_SET_MAC_KEY, + keylen, (void *)key) <= 0) + goto merr; + if (EVP_PKEY_keygen(mac_ctx, &mac_key) <= 0) + goto merr; + merr: + if (mac_ctx) + EVP_PKEY_CTX_free(mac_ctx); + return mac_key; +} diff --git a/libs/openssl/crypto/evp/pmeth_lib.c b/libs/openssl/crypto/evp/pmeth_lib.c new file mode 100644 index 00000000..ae8bccb0 --- /dev/null +++ b/libs/openssl/crypto/evp/pmeth_lib.c @@ -0,0 +1,609 @@ +/* pmeth_lib.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include "asn1_locl.h" +#include "evp_locl.h" + +typedef int sk_cmp_fn_type(const char *const *a, const char *const *b); + +DECLARE_STACK_OF(EVP_PKEY_METHOD) +STACK_OF(EVP_PKEY_METHOD) *app_pkey_methods = NULL; + +extern const EVP_PKEY_METHOD rsa_pkey_meth, dh_pkey_meth, dsa_pkey_meth; +extern const EVP_PKEY_METHOD ec_pkey_meth, hmac_pkey_meth, cmac_pkey_meth; + +static const EVP_PKEY_METHOD *standard_methods[] = { +#ifndef OPENSSL_NO_RSA + &rsa_pkey_meth, +#endif +#ifndef OPENSSL_NO_DH + &dh_pkey_meth, +#endif +#ifndef OPENSSL_NO_DSA + &dsa_pkey_meth, +#endif +#ifndef OPENSSL_NO_EC + &ec_pkey_meth, +#endif + &hmac_pkey_meth, + &cmac_pkey_meth +}; + +DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *, + pmeth); + +static int pmeth_cmp(const EVP_PKEY_METHOD *const *a, + const EVP_PKEY_METHOD *const *b) +{ + return ((*a)->pkey_id - (*b)->pkey_id); +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_METHOD *, const EVP_PKEY_METHOD *, + pmeth); + +const EVP_PKEY_METHOD *EVP_PKEY_meth_find(int type) +{ + EVP_PKEY_METHOD tmp; + const EVP_PKEY_METHOD *t = &tmp, **ret; + tmp.pkey_id = type; + if (app_pkey_methods) { + int idx; + idx = sk_EVP_PKEY_METHOD_find(app_pkey_methods, &tmp); + if (idx >= 0) + return sk_EVP_PKEY_METHOD_value(app_pkey_methods, idx); + } + ret = OBJ_bsearch_pmeth(&t, standard_methods, + sizeof(standard_methods) / + sizeof(EVP_PKEY_METHOD *)); + if (!ret || !*ret) + return NULL; + return *ret; +} + +static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id) +{ + EVP_PKEY_CTX *ret; + const EVP_PKEY_METHOD *pmeth; + if (id == -1) { + if (!pkey || !pkey->ameth) + return NULL; + id = pkey->ameth->pkey_id; + } +#ifndef OPENSSL_NO_ENGINE + if (pkey && pkey->engine) + e = pkey->engine; + /* Try to find an ENGINE which implements this method */ + if (e) { + if (!ENGINE_init(e)) { + EVPerr(EVP_F_INT_CTX_NEW, ERR_R_ENGINE_LIB); + return NULL; + } + } else + e = ENGINE_get_pkey_meth_engine(id); + + /* + * If an ENGINE handled this method look it up. Othewise use internal + * tables. + */ + + if (e) + pmeth = ENGINE_get_pkey_meth(e, id); + else +#endif + pmeth = EVP_PKEY_meth_find(id); + + if (pmeth == NULL) { + EVPerr(EVP_F_INT_CTX_NEW, EVP_R_UNSUPPORTED_ALGORITHM); + return NULL; + } + + ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); + if (!ret) { +#ifndef OPENSSL_NO_ENGINE + if (e) + ENGINE_finish(e); +#endif + EVPerr(EVP_F_INT_CTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + ret->engine = e; + ret->pmeth = pmeth; + ret->operation = EVP_PKEY_OP_UNDEFINED; + ret->pkey = pkey; + ret->peerkey = NULL; + ret->pkey_gencb = 0; + if (pkey) + CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + ret->data = NULL; + + if (pmeth->init) { + if (pmeth->init(ret) <= 0) { + EVP_PKEY_CTX_free(ret); + return NULL; + } + } + + return ret; +} + +EVP_PKEY_METHOD *EVP_PKEY_meth_new(int id, int flags) +{ + EVP_PKEY_METHOD *pmeth; + pmeth = OPENSSL_malloc(sizeof(EVP_PKEY_METHOD)); + if (!pmeth) + return NULL; + + memset(pmeth, 0, sizeof(EVP_PKEY_METHOD)); + + pmeth->pkey_id = id; + pmeth->flags = flags | EVP_PKEY_FLAG_DYNAMIC; + + pmeth->init = 0; + pmeth->copy = 0; + pmeth->cleanup = 0; + pmeth->paramgen_init = 0; + pmeth->paramgen = 0; + pmeth->keygen_init = 0; + pmeth->keygen = 0; + pmeth->sign_init = 0; + pmeth->sign = 0; + pmeth->verify_init = 0; + pmeth->verify = 0; + pmeth->verify_recover_init = 0; + pmeth->verify_recover = 0; + pmeth->signctx_init = 0; + pmeth->signctx = 0; + pmeth->verifyctx_init = 0; + pmeth->verifyctx = 0; + pmeth->encrypt_init = 0; + pmeth->encrypt = 0; + pmeth->decrypt_init = 0; + pmeth->decrypt = 0; + pmeth->derive_init = 0; + pmeth->derive = 0; + pmeth->ctrl = 0; + pmeth->ctrl_str = 0; + + return pmeth; +} + +void EVP_PKEY_meth_get0_info(int *ppkey_id, int *pflags, + const EVP_PKEY_METHOD *meth) +{ + if (ppkey_id) + *ppkey_id = meth->pkey_id; + if (pflags) + *pflags = meth->flags; +} + +void EVP_PKEY_meth_copy(EVP_PKEY_METHOD *dst, const EVP_PKEY_METHOD *src) +{ + + dst->init = src->init; + dst->copy = src->copy; + dst->cleanup = src->cleanup; + + dst->paramgen_init = src->paramgen_init; + dst->paramgen = src->paramgen; + + dst->keygen_init = src->keygen_init; + dst->keygen = src->keygen; + + dst->sign_init = src->sign_init; + dst->sign = src->sign; + + dst->verify_init = src->verify_init; + dst->verify = src->verify; + + dst->verify_recover_init = src->verify_recover_init; + dst->verify_recover = src->verify_recover; + + dst->signctx_init = src->signctx_init; + dst->signctx = src->signctx; + + dst->verifyctx_init = src->verifyctx_init; + dst->verifyctx = src->verifyctx; + + dst->encrypt_init = src->encrypt_init; + dst->encrypt = src->encrypt; + + dst->decrypt_init = src->decrypt_init; + dst->decrypt = src->decrypt; + + dst->derive_init = src->derive_init; + dst->derive = src->derive; + + dst->ctrl = src->ctrl; + dst->ctrl_str = src->ctrl_str; +} + +void EVP_PKEY_meth_free(EVP_PKEY_METHOD *pmeth) +{ + if (pmeth && (pmeth->flags & EVP_PKEY_FLAG_DYNAMIC)) + OPENSSL_free(pmeth); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) +{ + return int_ctx_new(pkey, e, -1); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) +{ + return int_ctx_new(NULL, e, id); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx) +{ + EVP_PKEY_CTX *rctx; + if (!pctx->pmeth || !pctx->pmeth->copy) + return NULL; +#ifndef OPENSSL_NO_ENGINE + /* Make sure it's safe to copy a pkey context using an ENGINE */ + if (pctx->engine && !ENGINE_init(pctx->engine)) { + EVPerr(EVP_F_EVP_PKEY_CTX_DUP, ERR_R_ENGINE_LIB); + return 0; + } +#endif + rctx = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); + if (!rctx) + return NULL; + + rctx->pmeth = pctx->pmeth; +#ifndef OPENSSL_NO_ENGINE + rctx->engine = pctx->engine; +#endif + + if (pctx->pkey) + CRYPTO_add(&pctx->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + + rctx->pkey = pctx->pkey; + + if (pctx->peerkey) + CRYPTO_add(&pctx->peerkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + + rctx->peerkey = pctx->peerkey; + + rctx->data = NULL; + rctx->app_data = NULL; + rctx->operation = pctx->operation; + + if (pctx->pmeth->copy(rctx, pctx) > 0) + return rctx; + + EVP_PKEY_CTX_free(rctx); + return NULL; + +} + +int EVP_PKEY_meth_add0(const EVP_PKEY_METHOD *pmeth) +{ + if (app_pkey_methods == NULL) { + app_pkey_methods = sk_EVP_PKEY_METHOD_new(pmeth_cmp); + if (!app_pkey_methods) + return 0; + } + if (!sk_EVP_PKEY_METHOD_push(app_pkey_methods, pmeth)) + return 0; + sk_EVP_PKEY_METHOD_sort(app_pkey_methods); + return 1; +} + +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) +{ + if (ctx == NULL) + return; + if (ctx->pmeth && ctx->pmeth->cleanup) + ctx->pmeth->cleanup(ctx); + if (ctx->pkey) + EVP_PKEY_free(ctx->pkey); + if (ctx->peerkey) + EVP_PKEY_free(ctx->peerkey); +#ifndef OPENSSL_NO_ENGINE + if (ctx->engine) + /* + * The EVP_PKEY_CTX we used belongs to an ENGINE, release the + * functional reference we held for this reason. + */ + ENGINE_finish(ctx->engine); +#endif + OPENSSL_free(ctx); +} + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2) +{ + int ret; + if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if ((keytype != -1) && (ctx->pmeth->pkey_id != keytype)) + return -1; + + if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_NO_OPERATION_SET); + return -1; + } + + if ((optype != -1) && !(ctx->operation & optype)) { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_INVALID_OPERATION); + return -1; + } + + ret = ctx->pmeth->ctrl(ctx, cmd, p1, p2); + + if (ret == -2) + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL, EVP_R_COMMAND_NOT_SUPPORTED); + + return ret; + +} + +int EVP_PKEY_CTX_ctrl_str(EVP_PKEY_CTX *ctx, + const char *name, const char *value) +{ + if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl_str) { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_COMMAND_NOT_SUPPORTED); + return -2; + } + if (!strcmp(name, "digest")) { + const EVP_MD *md; + if (!value || !(md = EVP_get_digestbyname(value))) { + EVPerr(EVP_F_EVP_PKEY_CTX_CTRL_STR, EVP_R_INVALID_DIGEST); + return 0; + } + return EVP_PKEY_CTX_set_signature_md(ctx, md); + } + return ctx->pmeth->ctrl_str(ctx, name, value); +} + +int EVP_PKEY_CTX_get_operation(EVP_PKEY_CTX *ctx) +{ + return ctx->operation; +} + +void EVP_PKEY_CTX_set0_keygen_info(EVP_PKEY_CTX *ctx, int *dat, int datlen) +{ + ctx->keygen_info = dat; + ctx->keygen_info_count = datlen; +} + +void EVP_PKEY_CTX_set_data(EVP_PKEY_CTX *ctx, void *data) +{ + ctx->data = data; +} + +void *EVP_PKEY_CTX_get_data(EVP_PKEY_CTX *ctx) +{ + return ctx->data; +} + +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) +{ + return ctx->pkey; +} + +EVP_PKEY *EVP_PKEY_CTX_get0_peerkey(EVP_PKEY_CTX *ctx) +{ + return ctx->peerkey; +} + +void EVP_PKEY_CTX_set_app_data(EVP_PKEY_CTX *ctx, void *data) +{ + ctx->app_data = data; +} + +void *EVP_PKEY_CTX_get_app_data(EVP_PKEY_CTX *ctx) +{ + return ctx->app_data; +} + +void EVP_PKEY_meth_set_init(EVP_PKEY_METHOD *pmeth, + int (*init) (EVP_PKEY_CTX *ctx)) +{ + pmeth->init = init; +} + +void EVP_PKEY_meth_set_copy(EVP_PKEY_METHOD *pmeth, + int (*copy) (EVP_PKEY_CTX *dst, + EVP_PKEY_CTX *src)) +{ + pmeth->copy = copy; +} + +void EVP_PKEY_meth_set_cleanup(EVP_PKEY_METHOD *pmeth, + void (*cleanup) (EVP_PKEY_CTX *ctx)) +{ + pmeth->cleanup = cleanup; +} + +void EVP_PKEY_meth_set_paramgen(EVP_PKEY_METHOD *pmeth, + int (*paramgen_init) (EVP_PKEY_CTX *ctx), + int (*paramgen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)) +{ + pmeth->paramgen_init = paramgen_init; + pmeth->paramgen = paramgen; +} + +void EVP_PKEY_meth_set_keygen(EVP_PKEY_METHOD *pmeth, + int (*keygen_init) (EVP_PKEY_CTX *ctx), + int (*keygen) (EVP_PKEY_CTX *ctx, + EVP_PKEY *pkey)) +{ + pmeth->keygen_init = keygen_init; + pmeth->keygen = keygen; +} + +void EVP_PKEY_meth_set_sign(EVP_PKEY_METHOD *pmeth, + int (*sign_init) (EVP_PKEY_CTX *ctx), + int (*sign) (EVP_PKEY_CTX *ctx, + unsigned char *sig, size_t *siglen, + const unsigned char *tbs, + size_t tbslen)) +{ + pmeth->sign_init = sign_init; + pmeth->sign = sign; +} + +void EVP_PKEY_meth_set_verify(EVP_PKEY_METHOD *pmeth, + int (*verify_init) (EVP_PKEY_CTX *ctx), + int (*verify) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + size_t siglen, + const unsigned char *tbs, + size_t tbslen)) +{ + pmeth->verify_init = verify_init; + pmeth->verify = verify; +} + +void EVP_PKEY_meth_set_verify_recover(EVP_PKEY_METHOD *pmeth, + int (*verify_recover_init) (EVP_PKEY_CTX + *ctx), + int (*verify_recover) (EVP_PKEY_CTX + *ctx, + unsigned char + *sig, + size_t *siglen, + const unsigned + char *tbs, + size_t tbslen)) +{ + pmeth->verify_recover_init = verify_recover_init; + pmeth->verify_recover = verify_recover; +} + +void EVP_PKEY_meth_set_signctx(EVP_PKEY_METHOD *pmeth, + int (*signctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*signctx) (EVP_PKEY_CTX *ctx, + unsigned char *sig, + size_t *siglen, + EVP_MD_CTX *mctx)) +{ + pmeth->signctx_init = signctx_init; + pmeth->signctx = signctx; +} + +void EVP_PKEY_meth_set_verifyctx(EVP_PKEY_METHOD *pmeth, + int (*verifyctx_init) (EVP_PKEY_CTX *ctx, + EVP_MD_CTX *mctx), + int (*verifyctx) (EVP_PKEY_CTX *ctx, + const unsigned char *sig, + int siglen, + EVP_MD_CTX *mctx)) +{ + pmeth->verifyctx_init = verifyctx_init; + pmeth->verifyctx = verifyctx; +} + +void EVP_PKEY_meth_set_encrypt(EVP_PKEY_METHOD *pmeth, + int (*encrypt_init) (EVP_PKEY_CTX *ctx), + int (*encryptfn) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)) +{ + pmeth->encrypt_init = encrypt_init; + pmeth->encrypt = encryptfn; +} + +void EVP_PKEY_meth_set_decrypt(EVP_PKEY_METHOD *pmeth, + int (*decrypt_init) (EVP_PKEY_CTX *ctx), + int (*decrypt) (EVP_PKEY_CTX *ctx, + unsigned char *out, + size_t *outlen, + const unsigned char *in, + size_t inlen)) +{ + pmeth->decrypt_init = decrypt_init; + pmeth->decrypt = decrypt; +} + +void EVP_PKEY_meth_set_derive(EVP_PKEY_METHOD *pmeth, + int (*derive_init) (EVP_PKEY_CTX *ctx), + int (*derive) (EVP_PKEY_CTX *ctx, + unsigned char *key, + size_t *keylen)) +{ + pmeth->derive_init = derive_init; + pmeth->derive = derive; +} + +void EVP_PKEY_meth_set_ctrl(EVP_PKEY_METHOD *pmeth, + int (*ctrl) (EVP_PKEY_CTX *ctx, int type, int p1, + void *p2), + int (*ctrl_str) (EVP_PKEY_CTX *ctx, + const char *type, + const char *value)) +{ + pmeth->ctrl = ctrl; + pmeth->ctrl_str = ctrl_str; +} diff --git a/libs/openssl/crypto/ex_data.c b/libs/openssl/crypto/ex_data.c new file mode 100644 index 00000000..f96a5178 --- /dev/null +++ b/libs/openssl/crypto/ex_data.c @@ -0,0 +1,646 @@ +/* crypto/ex_data.c */ + +/* + * Overhaul notes; + * + * This code is now *mostly* thread-safe. It is now easier to understand in what + * ways it is safe and in what ways it is not, which is an improvement. Firstly, + * all per-class stacks and index-counters for ex_data are stored in the same + * global LHASH table (keyed by class). This hash table uses locking for all + * access with the exception of CRYPTO_cleanup_all_ex_data(), which must only be + * called when no other threads can possibly race against it (even if it was + * locked, the race would mean it's possible the hash table might have been + * recreated after the cleanup). As classes can only be added to the hash table, + * and within each class, the stack of methods can only be incremented, the + * locking mechanics are simpler than they would otherwise be. For example, the + * new/dup/free ex_data functions will lock the hash table, copy the method + * pointers it needs from the relevant class, then unlock the hash table before + * actually applying those method pointers to the task of the new/dup/free + * operations. As they can't be removed from the method-stack, only + * supplemented, there's no race conditions associated with using them outside + * the lock. The get/set_ex_data functions are not locked because they do not + * involve this global state at all - they operate directly with a previously + * obtained per-class method index and a particular "ex_data" variable. These + * variables are usually instantiated per-context (eg. each RSA structure has + * one) so locking on read/write access to that variable can be locked locally + * if required (eg. using the "RSA" lock to synchronise access to a + * per-RSA-structure ex_data variable if required). + * [Geoff] + */ + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include + +/* What an "implementation of ex_data functionality" looks like */ +struct st_CRYPTO_EX_DATA_IMPL { + /*********************/ + /* GLOBAL OPERATIONS */ + /* Return a new class index */ + int (*cb_new_class) (void); + /* Cleanup all state used by the implementation */ + void (*cb_cleanup) (void); + /************************/ + /* PER-CLASS OPERATIONS */ + /* Get a new method index within a class */ + int (*cb_get_new_index) (int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); + /* Initialise a new CRYPTO_EX_DATA of a given class */ + int (*cb_new_ex_data) (int class_index, void *obj, CRYPTO_EX_DATA *ad); + /* Duplicate a CRYPTO_EX_DATA of a given class onto a copy */ + int (*cb_dup_ex_data) (int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from); + /* Cleanup a CRYPTO_EX_DATA of a given class */ + void (*cb_free_ex_data) (int class_index, void *obj, CRYPTO_EX_DATA *ad); +}; + +/* The implementation we use at run-time */ +static const CRYPTO_EX_DATA_IMPL *impl = NULL; + +/* + * To call "impl" functions, use this macro rather than referring to 'impl' + * directly, eg. EX_IMPL(get_new_index)(...); + */ +#define EX_IMPL(a) impl->cb_##a + +/* Predeclare the "default" ex_data implementation */ +static int int_new_class(void); +static void int_cleanup(void); +static int int_get_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +static int int_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from); +static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad); +static CRYPTO_EX_DATA_IMPL impl_default = { + int_new_class, + int_cleanup, + int_get_new_index, + int_new_ex_data, + int_dup_ex_data, + int_free_ex_data +}; + +/* + * Internal function that checks whether "impl" is set and if not, sets it to + * the default. + */ +static void impl_check(void) +{ + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + if (!impl) + impl = &impl_default; + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); +} + +/* + * A macro wrapper for impl_check that first uses a non-locked test before + * invoking the function (which checks again inside a lock). + */ +#define IMPL_CHECK if(!impl) impl_check(); + +/* API functions to get/set the "ex_data" implementation */ +const CRYPTO_EX_DATA_IMPL *CRYPTO_get_ex_data_implementation(void) +{ + IMPL_CHECK return impl; +} + +int CRYPTO_set_ex_data_implementation(const CRYPTO_EX_DATA_IMPL *i) +{ + int toret = 0; + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + if (!impl) { + impl = i; + toret = 1; + } + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + return toret; +} + +/****************************************************************************/ +/* + * Interal (default) implementation of "ex_data" support. API functions are + * further down. + */ + +/* + * The type that represents what each "class" used to implement locally. A + * STACK of CRYPTO_EX_DATA_FUNCS plus a index-counter. The 'class_index' is + * the global value representing the class that is used to distinguish these + * items. + */ +typedef struct st_ex_class_item { + int class_index; + STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth; + int meth_num; +} EX_CLASS_ITEM; + +/* When assigning new class indexes, this is our counter */ +static int ex_class = CRYPTO_EX_INDEX_USER; + +/* The global hash table of EX_CLASS_ITEM items */ +DECLARE_LHASH_OF(EX_CLASS_ITEM); +static LHASH_OF(EX_CLASS_ITEM) *ex_data = NULL; + +/* The callbacks required in the "ex_data" hash table */ +static unsigned long ex_class_item_hash(const EX_CLASS_ITEM *a) +{ + return a->class_index; +} + +static IMPLEMENT_LHASH_HASH_FN(ex_class_item, EX_CLASS_ITEM) + +static int ex_class_item_cmp(const EX_CLASS_ITEM *a, const EX_CLASS_ITEM *b) +{ + return a->class_index - b->class_index; +} + +static IMPLEMENT_LHASH_COMP_FN(ex_class_item, EX_CLASS_ITEM) + +/* + * Internal functions used by the "impl_default" implementation to access the + * state + */ +static int ex_data_check(void) +{ + int toret = 1; + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + if (!ex_data && (ex_data = lh_EX_CLASS_ITEM_new()) == NULL) + toret = 0; + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + return toret; +} + +/* + * This macros helps reduce the locking from repeated checks because the + * ex_data_check() function checks ex_data again inside a lock. + */ +#define EX_DATA_CHECK(iffail) if(!ex_data && !ex_data_check()) {iffail} + +/* This "inner" callback is used by the callback function that follows it */ +static void def_cleanup_util_cb(CRYPTO_EX_DATA_FUNCS *funcs) +{ + OPENSSL_free(funcs); +} + +/* + * This callback is used in lh_doall to destroy all EX_CLASS_ITEM values from + * "ex_data" prior to the ex_data hash table being itself destroyed. Doesn't + * do any locking. + */ +static void def_cleanup_cb(void *a_void) +{ + EX_CLASS_ITEM *item = (EX_CLASS_ITEM *)a_void; + sk_CRYPTO_EX_DATA_FUNCS_pop_free(item->meth, def_cleanup_util_cb); + OPENSSL_free(item); +} + +/* + * Return the EX_CLASS_ITEM from the "ex_data" hash table that corresponds to + * a given class. Handles locking. + */ +static EX_CLASS_ITEM *def_get_class(int class_index) +{ + EX_CLASS_ITEM d, *p, *gen; + EX_DATA_CHECK(return NULL;) + d.class_index = class_index; + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + p = lh_EX_CLASS_ITEM_retrieve(ex_data, &d); + if (!p) { + gen = OPENSSL_malloc(sizeof(EX_CLASS_ITEM)); + if (gen) { + gen->class_index = class_index; + gen->meth_num = 0; + gen->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null(); + if (!gen->meth) + OPENSSL_free(gen); + else { + /* + * Because we're inside the ex_data lock, the return value + * from the insert will be NULL + */ + (void)lh_EX_CLASS_ITEM_insert(ex_data, gen); + p = gen; + } + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + if (!p) + CRYPTOerr(CRYPTO_F_DEF_GET_CLASS, ERR_R_MALLOC_FAILURE); + return p; +} + +/* + * Add a new method to the given EX_CLASS_ITEM and return the corresponding + * index (or -1 for error). Handles locking. + */ +static int def_add_index(EX_CLASS_ITEM *item, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + int toret = -1; + CRYPTO_EX_DATA_FUNCS *a = + (CRYPTO_EX_DATA_FUNCS *)OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS)); + if (!a) { + CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX, ERR_R_MALLOC_FAILURE); + return -1; + } + a->argl = argl; + a->argp = argp; + a->new_func = new_func; + a->dup_func = dup_func; + a->free_func = free_func; + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + while (sk_CRYPTO_EX_DATA_FUNCS_num(item->meth) <= item->meth_num) { + if (!sk_CRYPTO_EX_DATA_FUNCS_push(item->meth, NULL)) { + CRYPTOerr(CRYPTO_F_DEF_ADD_INDEX, ERR_R_MALLOC_FAILURE); + OPENSSL_free(a); + goto err; + } + } + toret = item->meth_num++; + (void)sk_CRYPTO_EX_DATA_FUNCS_set(item->meth, toret, a); + err: + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + return toret; +} + +/**************************************************************/ +/* The functions in the default CRYPTO_EX_DATA_IMPL structure */ + +static int int_new_class(void) +{ + int toret; + CRYPTO_w_lock(CRYPTO_LOCK_EX_DATA); + toret = ex_class++; + CRYPTO_w_unlock(CRYPTO_LOCK_EX_DATA); + return toret; +} + +static void int_cleanup(void) +{ + EX_DATA_CHECK(return;) + lh_EX_CLASS_ITEM_doall(ex_data, def_cleanup_cb); + lh_EX_CLASS_ITEM_free(ex_data); + ex_data = NULL; + impl = NULL; +} + +static int int_get_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + EX_CLASS_ITEM *item = def_get_class(class_index); + if (!item) + return -1; + return def_add_index(item, argl, argp, new_func, dup_func, free_func); +} + +/* + * Thread-safe by copying a class's array of "CRYPTO_EX_DATA_FUNCS" entries + * in the lock, then using them outside the lock. NB: Thread-safety only + * applies to the global "ex_data" state (ie. class definitions), not + * thread-safe on 'ad' itself. + */ +static int int_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) +{ + int mx, i; + void *ptr; + CRYPTO_EX_DATA_FUNCS **storage = NULL; + EX_CLASS_ITEM *item = def_get_class(class_index); + if (!item) + /* error is already set */ + return 0; + ad->sk = NULL; + CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); + mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); + if (mx > 0) { + storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *)); + if (!storage) + goto skip; + for (i = 0; i < mx; i++) + storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i); + } + skip: + CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); + if ((mx > 0) && !storage) { + CRYPTOerr(CRYPTO_F_INT_NEW_EX_DATA, ERR_R_MALLOC_FAILURE); + return 0; + } + for (i = 0; i < mx; i++) { + if (storage[i] && storage[i]->new_func) { + ptr = CRYPTO_get_ex_data(ad, i); + storage[i]->new_func(obj, ptr, ad, i, + storage[i]->argl, storage[i]->argp); + } + } + if (storage) + OPENSSL_free(storage); + return 1; +} + +/* Same thread-safety notes as for "int_new_ex_data" */ +static int int_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from) +{ + int mx, j, i; + char *ptr; + CRYPTO_EX_DATA_FUNCS **storage = NULL; + EX_CLASS_ITEM *item; + if (!from->sk) + /* 'to' should be "blank" which *is* just like 'from' */ + return 1; + if ((item = def_get_class(class_index)) == NULL) + return 0; + CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); + mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); + j = sk_void_num(from->sk); + if (j < mx) + mx = j; + if (mx > 0) { + storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *)); + if (!storage) + goto skip; + for (i = 0; i < mx; i++) + storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i); + } + skip: + CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); + if ((mx > 0) && !storage) { + CRYPTOerr(CRYPTO_F_INT_DUP_EX_DATA, ERR_R_MALLOC_FAILURE); + return 0; + } + for (i = 0; i < mx; i++) { + ptr = CRYPTO_get_ex_data(from, i); + if (storage[i] && storage[i]->dup_func) + storage[i]->dup_func(to, from, &ptr, i, + storage[i]->argl, storage[i]->argp); + CRYPTO_set_ex_data(to, i, ptr); + } + if (storage) + OPENSSL_free(storage); + return 1; +} + +/* Same thread-safety notes as for "int_new_ex_data" */ +static void int_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) +{ + int mx, i; + EX_CLASS_ITEM *item; + void *ptr; + CRYPTO_EX_DATA_FUNCS **storage = NULL; + if (ex_data == NULL) + return; + if ((item = def_get_class(class_index)) == NULL) + return; + CRYPTO_r_lock(CRYPTO_LOCK_EX_DATA); + mx = sk_CRYPTO_EX_DATA_FUNCS_num(item->meth); + if (mx > 0) { + storage = OPENSSL_malloc(mx * sizeof(CRYPTO_EX_DATA_FUNCS *)); + if (!storage) + goto skip; + for (i = 0; i < mx; i++) + storage[i] = sk_CRYPTO_EX_DATA_FUNCS_value(item->meth, i); + } + skip: + CRYPTO_r_unlock(CRYPTO_LOCK_EX_DATA); + if ((mx > 0) && !storage) { + CRYPTOerr(CRYPTO_F_INT_FREE_EX_DATA, ERR_R_MALLOC_FAILURE); + return; + } + for (i = 0; i < mx; i++) { + if (storage[i] && storage[i]->free_func) { + ptr = CRYPTO_get_ex_data(ad, i); + storage[i]->free_func(obj, ptr, ad, i, + storage[i]->argl, storage[i]->argp); + } + } + if (storage) + OPENSSL_free(storage); + if (ad->sk) { + sk_void_free(ad->sk); + ad->sk = NULL; + } +} + +/********************************************************************/ +/* + * API functions that defer all "state" operations to the "ex_data" + * implementation we have set. + */ + +/* + * Obtain an index for a new class (not the same as getting a new index + * within an existing class - this is actually getting a new *class*) + */ +int CRYPTO_ex_data_new_class(void) +{ + IMPL_CHECK return EX_IMPL(new_class) (); +} + +/* + * Release all "ex_data" state to prevent memory leaks. This can't be made + * thread-safe without overhauling a lot of stuff, and shouldn't really be + * called under potential race-conditions anyway (it's for program shutdown + * after all). + */ +void CRYPTO_cleanup_all_ex_data(void) +{ + IMPL_CHECK EX_IMPL(cleanup) (); +} + +/* Inside an existing class, get/register a new index. */ +int CRYPTO_get_ex_new_index(int class_index, long argl, void *argp, + CRYPTO_EX_new *new_func, CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + int ret = -1; + + IMPL_CHECK + ret = EX_IMPL(get_new_index) (class_index, + argl, argp, new_func, dup_func, + free_func); + return ret; +} + +/* + * Initialise a new CRYPTO_EX_DATA for use in a particular class - including + * calling new() callbacks for each index in the class used by this variable + */ +int CRYPTO_new_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) +{ + IMPL_CHECK return EX_IMPL(new_ex_data) (class_index, obj, ad); +} + +/* + * Duplicate a CRYPTO_EX_DATA variable - including calling dup() callbacks + * for each index in the class used by this variable + */ +int CRYPTO_dup_ex_data(int class_index, CRYPTO_EX_DATA *to, + CRYPTO_EX_DATA *from) +{ + IMPL_CHECK return EX_IMPL(dup_ex_data) (class_index, to, from); +} + +/* + * Cleanup a CRYPTO_EX_DATA variable - including calling free() callbacks for + * each index in the class used by this variable + */ +void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad) +{ + IMPL_CHECK EX_IMPL(free_ex_data) (class_index, obj, ad); +} + +/* + * For a given CRYPTO_EX_DATA variable, set the value corresponding to a + * particular index in the class used by this variable + */ +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int idx, void *val) +{ + int i; + + if (ad->sk == NULL) { + if ((ad->sk = sk_void_new_null()) == NULL) { + CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE); + return (0); + } + } + i = sk_void_num(ad->sk); + + while (i <= idx) { + if (!sk_void_push(ad->sk, NULL)) { + CRYPTOerr(CRYPTO_F_CRYPTO_SET_EX_DATA, ERR_R_MALLOC_FAILURE); + return (0); + } + i++; + } + sk_void_set(ad->sk, idx, val); + return (1); +} + +/* + * For a given CRYPTO_EX_DATA_ variable, get the value corresponding to a + * particular index in the class used by this variable + */ +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx) +{ + if (ad->sk == NULL) + return (0); + else if (idx >= sk_void_num(ad->sk)) + return (0); + else + return (sk_void_value(ad->sk, idx)); +} + +IMPLEMENT_STACK_OF(CRYPTO_EX_DATA_FUNCS) diff --git a/libs/openssl/crypto/fips_err.h b/libs/openssl/crypto/fips_err.h new file mode 100644 index 00000000..0308b63b --- /dev/null +++ b/libs/openssl/crypto/fips_err.h @@ -0,0 +1,223 @@ +/* crypto/fips_err.h */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_FIPS,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_FIPS,0,reason) + +static ERR_STRING_DATA FIPS_str_functs[] = { + {ERR_FUNC(FIPS_F_DH_BUILTIN_GENPARAMS), "DH_BUILTIN_GENPARAMS"}, + {ERR_FUNC(FIPS_F_DH_INIT), "DH_INIT"}, + {ERR_FUNC(FIPS_F_DRBG_RESEED), "DRBG_RESEED"}, + {ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN), "DSA_BUILTIN_PARAMGEN"}, + {ERR_FUNC(FIPS_F_DSA_BUILTIN_PARAMGEN2), "DSA_BUILTIN_PARAMGEN2"}, + {ERR_FUNC(FIPS_F_DSA_DO_SIGN), "DSA_do_sign"}, + {ERR_FUNC(FIPS_F_DSA_DO_VERIFY), "DSA_do_verify"}, + {ERR_FUNC(FIPS_F_FIPS_CHECK_DSA), "FIPS_CHECK_DSA"}, + {ERR_FUNC(FIPS_F_FIPS_CHECK_DSA_PRNG), "fips_check_dsa_prng"}, + {ERR_FUNC(FIPS_F_FIPS_CHECK_EC), "FIPS_CHECK_EC"}, + {ERR_FUNC(FIPS_F_FIPS_CHECK_EC_PRNG), "fips_check_ec_prng"}, + {ERR_FUNC(FIPS_F_FIPS_CHECK_INCORE_FINGERPRINT), + "FIPS_check_incore_fingerprint"}, + {ERR_FUNC(FIPS_F_FIPS_CHECK_RSA), "fips_check_rsa"}, + {ERR_FUNC(FIPS_F_FIPS_CHECK_RSA_PRNG), "fips_check_rsa_prng"}, + {ERR_FUNC(FIPS_F_FIPS_CIPHER), "FIPS_cipher"}, + {ERR_FUNC(FIPS_F_FIPS_CIPHERINIT), "FIPS_cipherinit"}, + {ERR_FUNC(FIPS_F_FIPS_CIPHER_CTX_CTRL), "FIPS_CIPHER_CTX_CTRL"}, + {ERR_FUNC(FIPS_F_FIPS_DIGESTFINAL), "FIPS_digestfinal"}, + {ERR_FUNC(FIPS_F_FIPS_DIGESTINIT), "FIPS_digestinit"}, + {ERR_FUNC(FIPS_F_FIPS_DIGESTUPDATE), "FIPS_digestupdate"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_BYTES), "FIPS_DRBG_BYTES"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_CHECK), "FIPS_DRBG_CHECK"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_CPRNG_TEST), "FIPS_DRBG_CPRNG_TEST"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_ERROR_CHECK), "FIPS_DRBG_ERROR_CHECK"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_GENERATE), "FIPS_drbg_generate"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_INIT), "FIPS_drbg_init"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_INSTANTIATE), "FIPS_drbg_instantiate"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_NEW), "FIPS_drbg_new"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_RESEED), "FIPS_drbg_reseed"}, + {ERR_FUNC(FIPS_F_FIPS_DRBG_SINGLE_KAT), "FIPS_DRBG_SINGLE_KAT"}, + {ERR_FUNC(FIPS_F_FIPS_DSA_SIGN_DIGEST), "FIPS_dsa_sign_digest"}, + {ERR_FUNC(FIPS_F_FIPS_DSA_VERIFY_DIGEST), "FIPS_dsa_verify_digest"}, + {ERR_FUNC(FIPS_F_FIPS_GET_ENTROPY), "FIPS_GET_ENTROPY"}, + {ERR_FUNC(FIPS_F_FIPS_MODULE_MODE_SET), "FIPS_module_mode_set"}, + {ERR_FUNC(FIPS_F_FIPS_PKEY_SIGNATURE_TEST), "fips_pkey_signature_test"}, + {ERR_FUNC(FIPS_F_FIPS_RAND_ADD), "FIPS_rand_add"}, + {ERR_FUNC(FIPS_F_FIPS_RAND_BYTES), "FIPS_rand_bytes"}, + {ERR_FUNC(FIPS_F_FIPS_RAND_PSEUDO_BYTES), "FIPS_rand_pseudo_bytes"}, + {ERR_FUNC(FIPS_F_FIPS_RAND_SEED), "FIPS_rand_seed"}, + {ERR_FUNC(FIPS_F_FIPS_RAND_SET_METHOD), "FIPS_rand_set_method"}, + {ERR_FUNC(FIPS_F_FIPS_RAND_STATUS), "FIPS_rand_status"}, + {ERR_FUNC(FIPS_F_FIPS_RSA_SIGN_DIGEST), "FIPS_rsa_sign_digest"}, + {ERR_FUNC(FIPS_F_FIPS_RSA_VERIFY_DIGEST), "FIPS_rsa_verify_digest"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES), "FIPS_selftest_aes"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_CCM), "FIPS_selftest_aes_ccm"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_GCM), "FIPS_selftest_aes_gcm"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_AES_XTS), "FIPS_selftest_aes_xts"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_CMAC), "FIPS_selftest_cmac"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_DES), "FIPS_selftest_des"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_DSA), "FIPS_selftest_dsa"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_ECDSA), "FIPS_selftest_ecdsa"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_HMAC), "FIPS_selftest_hmac"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_SHA1), "FIPS_selftest_sha1"}, + {ERR_FUNC(FIPS_F_FIPS_SELFTEST_X931), "FIPS_selftest_x931"}, + {ERR_FUNC(FIPS_F_FIPS_SET_PRNG_KEY), "FIPS_SET_PRNG_KEY"}, + {ERR_FUNC(FIPS_F_HASH_FINAL), "HASH_FINAL"}, + {ERR_FUNC(FIPS_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"}, + {ERR_FUNC(FIPS_F_RSA_EAY_INIT), "RSA_EAY_INIT"}, + {ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"}, + {ERR_FUNC(FIPS_F_RSA_EAY_PRIVATE_ENCRYPT), "RSA_EAY_PRIVATE_ENCRYPT"}, + {ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_DECRYPT), "RSA_EAY_PUBLIC_DECRYPT"}, + {ERR_FUNC(FIPS_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"}, + {ERR_FUNC(FIPS_F_RSA_X931_GENERATE_KEY_EX), "RSA_X931_generate_key_ex"}, + {0, NULL} +}; + +static ERR_STRING_DATA FIPS_str_reasons[] = { + {ERR_REASON(FIPS_R_ADDITIONAL_INPUT_ERROR_UNDETECTED), + "additional input error undetected"}, + {ERR_REASON(FIPS_R_ADDITIONAL_INPUT_TOO_LONG), + "additional input too long"}, + {ERR_REASON(FIPS_R_ALREADY_INSTANTIATED), "already instantiated"}, + {ERR_REASON(FIPS_R_AUTHENTICATION_FAILURE), "authentication failure"}, + {ERR_REASON(FIPS_R_CONTRADICTING_EVIDENCE), "contradicting evidence"}, + {ERR_REASON(FIPS_R_DRBG_NOT_INITIALISED), "drbg not initialised"}, + {ERR_REASON(FIPS_R_DRBG_STUCK), "drbg stuck"}, + {ERR_REASON(FIPS_R_ENTROPY_ERROR_UNDETECTED), "entropy error undetected"}, + {ERR_REASON(FIPS_R_ENTROPY_NOT_REQUESTED_FOR_RESEED), + "entropy not requested for reseed"}, + {ERR_REASON(FIPS_R_ENTROPY_SOURCE_STUCK), "entropy source stuck"}, + {ERR_REASON(FIPS_R_ERROR_INITIALISING_DRBG), "error initialising drbg"}, + {ERR_REASON(FIPS_R_ERROR_INSTANTIATING_DRBG), "error instantiating drbg"}, + {ERR_REASON(FIPS_R_ERROR_RETRIEVING_ADDITIONAL_INPUT), + "error retrieving additional input"}, + {ERR_REASON(FIPS_R_ERROR_RETRIEVING_ENTROPY), "error retrieving entropy"}, + {ERR_REASON(FIPS_R_ERROR_RETRIEVING_NONCE), "error retrieving nonce"}, + {ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH), + "fingerprint does not match"}, + {ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_NONPIC_RELOCATED), + "fingerprint does not match nonpic relocated"}, + {ERR_REASON(FIPS_R_FINGERPRINT_DOES_NOT_MATCH_SEGMENT_ALIASING), + "fingerprint does not match segment aliasing"}, + {ERR_REASON(FIPS_R_FIPS_MODE_ALREADY_SET), "fips mode already set"}, + {ERR_REASON(FIPS_R_FIPS_SELFTEST_FAILED), "fips selftest failed"}, + {ERR_REASON(FIPS_R_FUNCTION_ERROR), "function error"}, + {ERR_REASON(FIPS_R_GENERATE_ERROR), "generate error"}, + {ERR_REASON(FIPS_R_GENERATE_ERROR_UNDETECTED), + "generate error undetected"}, + {ERR_REASON(FIPS_R_INSTANTIATE_ERROR), "instantiate error"}, + {ERR_REASON(FIPS_R_INSUFFICIENT_SECURITY_STRENGTH), + "insufficient security strength"}, + {ERR_REASON(FIPS_R_INTERNAL_ERROR), "internal error"}, + {ERR_REASON(FIPS_R_INVALID_KEY_LENGTH), "invalid key length"}, + {ERR_REASON(FIPS_R_INVALID_PARAMETERS), "invalid parameters"}, + {ERR_REASON(FIPS_R_IN_ERROR_STATE), "in error state"}, + {ERR_REASON(FIPS_R_KEY_TOO_SHORT), "key too short"}, + {ERR_REASON(FIPS_R_NONCE_ERROR_UNDETECTED), "nonce error undetected"}, + {ERR_REASON(FIPS_R_NON_FIPS_METHOD), "non fips method"}, + {ERR_REASON(FIPS_R_NOPR_TEST1_FAILURE), "nopr test1 failure"}, + {ERR_REASON(FIPS_R_NOPR_TEST2_FAILURE), "nopr test2 failure"}, + {ERR_REASON(FIPS_R_NOT_INSTANTIATED), "not instantiated"}, + {ERR_REASON(FIPS_R_PAIRWISE_TEST_FAILED), "pairwise test failed"}, + {ERR_REASON(FIPS_R_PERSONALISATION_ERROR_UNDETECTED), + "personalisation error undetected"}, + {ERR_REASON(FIPS_R_PERSONALISATION_STRING_TOO_LONG), + "personalisation string too long"}, + {ERR_REASON(FIPS_R_PRNG_STRENGTH_TOO_LOW), "prng strength too low"}, + {ERR_REASON(FIPS_R_PR_TEST1_FAILURE), "pr test1 failure"}, + {ERR_REASON(FIPS_R_PR_TEST2_FAILURE), "pr test2 failure"}, + {ERR_REASON(FIPS_R_REQUEST_LENGTH_ERROR_UNDETECTED), + "request length error undetected"}, + {ERR_REASON(FIPS_R_REQUEST_TOO_LARGE_FOR_DRBG), + "request too large for drbg"}, + {ERR_REASON(FIPS_R_RESEED_COUNTER_ERROR), "reseed counter error"}, + {ERR_REASON(FIPS_R_RESEED_ERROR), "reseed error"}, + {ERR_REASON(FIPS_R_SELFTEST_FAILED), "selftest failed"}, + {ERR_REASON(FIPS_R_SELFTEST_FAILURE), "selftest failure"}, + {ERR_REASON(FIPS_R_STRENGTH_ERROR_UNDETECTED), + "strength error undetected"}, + {ERR_REASON(FIPS_R_TEST_FAILURE), "test failure"}, + {ERR_REASON(FIPS_R_UNINSTANTIATE_ERROR), "uninstantiate error"}, + {ERR_REASON(FIPS_R_UNINSTANTIATE_ZEROISE_ERROR), + "uninstantiate zeroise error"}, + {ERR_REASON(FIPS_R_UNSUPPORTED_DRBG_TYPE), "unsupported drbg type"}, + {ERR_REASON(FIPS_R_UNSUPPORTED_PLATFORM), "unsupported platform"}, + {0, NULL} +}; + +#endif + +void ERR_load_FIPS_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(FIPS_str_functs[0].error) == NULL) { + ERR_load_strings(0, FIPS_str_functs); + ERR_load_strings(0, FIPS_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/fips_ers.c b/libs/openssl/crypto/fips_ers.c new file mode 100644 index 00000000..1788ed28 --- /dev/null +++ b/libs/openssl/crypto/fips_ers.c @@ -0,0 +1,7 @@ +#include + +#ifdef OPENSSL_FIPS +# include "fips_err.h" +#else +static void *dummy = &dummy; +#endif diff --git a/libs/openssl/crypto/hmac/hm_ameth.c b/libs/openssl/crypto/hmac/hm_ameth.c new file mode 100644 index 00000000..cf147437 --- /dev/null +++ b/libs/openssl/crypto/hmac/hm_ameth.c @@ -0,0 +1,167 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2007. + */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include "asn1_locl.h" + +#define HMAC_TEST_PRIVATE_KEY_FORMAT + +/* + * HMAC "ASN1" method. This is just here to indicate the maximum HMAC output + * length and to free up an HMAC key. + */ + +static int hmac_size(const EVP_PKEY *pkey) +{ + return EVP_MAX_MD_SIZE; +} + +static void hmac_key_free(EVP_PKEY *pkey) +{ + ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; + if (os) { + if (os->data) + OPENSSL_cleanse(os->data, os->length); + ASN1_OCTET_STRING_free(os); + } +} + +static int hmac_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + switch (op) { + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha1; + return 1; + + default: + return -2; + } +} + +#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT +/* + * A bogus private key format for test purposes. This is simply the HMAC key + * with "HMAC PRIVATE KEY" in the headers. When enabled the genpkey utility + * can be used to "generate" HMAC keys. + */ + +static int old_hmac_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + ASN1_OCTET_STRING *os; + os = ASN1_OCTET_STRING_new(); + if (!os || !ASN1_OCTET_STRING_set(os, *pder, derlen)) + goto err; + if (!EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, os)) + goto err; + return 1; + + err: + ASN1_OCTET_STRING_free(os); + return 0; +} + +static int old_hmac_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + int inc; + ASN1_OCTET_STRING *os = (ASN1_OCTET_STRING *)pkey->pkey.ptr; + if (pder) { + if (!*pder) { + *pder = OPENSSL_malloc(os->length); + inc = 0; + } else + inc = 1; + + memcpy(*pder, os->data, os->length); + + if (inc) + *pder += os->length; + } + + return os->length; +} + +#endif + +const EVP_PKEY_ASN1_METHOD hmac_asn1_meth = { + EVP_PKEY_HMAC, + EVP_PKEY_HMAC, + 0, + + "HMAC", + "OpenSSL HMAC method", + + 0, 0, 0, 0, + + 0, 0, 0, + + hmac_size, + 0, + 0, 0, 0, 0, 0, 0, 0, + + hmac_key_free, + hmac_pkey_ctrl, +#ifdef HMAC_TEST_PRIVATE_KEY_FORMAT + old_hmac_decode, + old_hmac_encode +#else + 0, 0 +#endif +}; diff --git a/libs/openssl/crypto/hmac/hm_pmeth.c b/libs/openssl/crypto/hmac/hm_pmeth.c new file mode 100644 index 00000000..0ffff79c --- /dev/null +++ b/libs/openssl/crypto/hmac/hm_pmeth.c @@ -0,0 +1,262 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2007. + */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include "evp_locl.h" + +/* HMAC pkey context structure */ + +typedef struct { + const EVP_MD *md; /* MD for HMAC use */ + ASN1_OCTET_STRING ktmp; /* Temp storage for key */ + HMAC_CTX ctx; +} HMAC_PKEY_CTX; + +static int pkey_hmac_init(EVP_PKEY_CTX *ctx) +{ + HMAC_PKEY_CTX *hctx; + hctx = OPENSSL_malloc(sizeof(HMAC_PKEY_CTX)); + if (!hctx) + return 0; + hctx->md = NULL; + hctx->ktmp.data = NULL; + hctx->ktmp.length = 0; + hctx->ktmp.flags = 0; + hctx->ktmp.type = V_ASN1_OCTET_STRING; + HMAC_CTX_init(&hctx->ctx); + + ctx->data = hctx; + ctx->keygen_info_count = 0; + + return 1; +} + +static int pkey_hmac_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + HMAC_PKEY_CTX *sctx, *dctx; + if (!pkey_hmac_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->md = sctx->md; + HMAC_CTX_init(&dctx->ctx); + if (!HMAC_CTX_copy(&dctx->ctx, &sctx->ctx)) + return 0; + if (sctx->ktmp.data) { + if (!ASN1_OCTET_STRING_set(&dctx->ktmp, + sctx->ktmp.data, sctx->ktmp.length)) + return 0; + } + return 1; +} + +static void pkey_hmac_cleanup(EVP_PKEY_CTX *ctx) +{ + HMAC_PKEY_CTX *hctx = ctx->data; + HMAC_CTX_cleanup(&hctx->ctx); + if (hctx->ktmp.data) { + if (hctx->ktmp.length) + OPENSSL_cleanse(hctx->ktmp.data, hctx->ktmp.length); + OPENSSL_free(hctx->ktmp.data); + hctx->ktmp.data = NULL; + } + OPENSSL_free(hctx); +} + +static int pkey_hmac_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + ASN1_OCTET_STRING *hkey = NULL; + HMAC_PKEY_CTX *hctx = ctx->data; + if (!hctx->ktmp.data) + return 0; + hkey = ASN1_OCTET_STRING_dup(&hctx->ktmp); + if (!hkey) + return 0; + EVP_PKEY_assign(pkey, EVP_PKEY_HMAC, hkey); + + return 1; +} + +static int int_update(EVP_MD_CTX *ctx, const void *data, size_t count) +{ + HMAC_PKEY_CTX *hctx = ctx->pctx->data; + if (!HMAC_Update(&hctx->ctx, data, count)) + return 0; + return 1; +} + +static int hmac_signctx_init(EVP_PKEY_CTX *ctx, EVP_MD_CTX *mctx) +{ + HMAC_PKEY_CTX *hctx = ctx->data; + HMAC_CTX_set_flags(&hctx->ctx, mctx->flags & ~EVP_MD_CTX_FLAG_NO_INIT); + EVP_MD_CTX_set_flags(mctx, EVP_MD_CTX_FLAG_NO_INIT); + mctx->update = int_update; + return 1; +} + +static int hmac_signctx(EVP_PKEY_CTX *ctx, unsigned char *sig, size_t *siglen, + EVP_MD_CTX *mctx) +{ + unsigned int hlen; + HMAC_PKEY_CTX *hctx = ctx->data; + int l = EVP_MD_CTX_size(mctx); + + if (l < 0) + return 0; + *siglen = l; + if (!sig) + return 1; + + if (!HMAC_Final(&hctx->ctx, sig, &hlen)) + return 0; + *siglen = (size_t)hlen; + return 1; +} + +static int pkey_hmac_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + HMAC_PKEY_CTX *hctx = ctx->data; + ASN1_OCTET_STRING *key; + switch (type) { + + case EVP_PKEY_CTRL_SET_MAC_KEY: + if ((!p2 && p1 > 0) || (p1 < -1)) + return 0; + if (!ASN1_OCTET_STRING_set(&hctx->ktmp, p2, p1)) + return 0; + break; + + case EVP_PKEY_CTRL_MD: + hctx->md = p2; + break; + + case EVP_PKEY_CTRL_DIGESTINIT: + key = (ASN1_OCTET_STRING *)ctx->pkey->pkey.ptr; + if (!HMAC_Init_ex(&hctx->ctx, key->data, key->length, hctx->md, + ctx->engine)) + return 0; + break; + + default: + return -2; + + } + return 1; +} + +static int pkey_hmac_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (!value) { + return 0; + } + if (!strcmp(type, "key")) { + void *p = (void *)value; + return pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, -1, p); + } + if (!strcmp(type, "hexkey")) { + unsigned char *key; + int r; + long keylen; + key = string_to_hex(value, &keylen); + if (!key) + return 0; + r = pkey_hmac_ctrl(ctx, EVP_PKEY_CTRL_SET_MAC_KEY, keylen, key); + OPENSSL_free(key); + return r; + } + return -2; +} + +const EVP_PKEY_METHOD hmac_pkey_meth = { + EVP_PKEY_HMAC, + 0, + pkey_hmac_init, + pkey_hmac_copy, + pkey_hmac_cleanup, + + 0, 0, + + 0, + pkey_hmac_keygen, + + 0, 0, + + 0, 0, + + 0, 0, + + hmac_signctx_init, + hmac_signctx, + + 0, 0, + + 0, 0, + + 0, 0, + + 0, 0, + + pkey_hmac_ctrl, + pkey_hmac_ctrl_str +}; diff --git a/libs/openssl/crypto/hmac/hmac.c b/libs/openssl/crypto/hmac/hmac.c new file mode 100644 index 00000000..33d88be1 --- /dev/null +++ b/libs/openssl/crypto/hmac/hmac.c @@ -0,0 +1,258 @@ +/* crypto/hmac/hmac.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +#include +#include +#include +#include "cryptlib.h" +#include + +#ifdef OPENSSL_FIPS +# include +#endif + +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md, ENGINE *impl) +{ + int i, j, reset = 0; + unsigned char pad[HMAC_MAX_MD_CBLOCK]; + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) { + /* If we have an ENGINE need to allow non FIPS */ + if ((impl || ctx->i_ctx.engine) + && !(ctx->i_ctx.flags & EVP_CIPH_FLAG_NON_FIPS_ALLOW)) { + EVPerr(EVP_F_HMAC_INIT_EX, EVP_R_DISABLED_FOR_FIPS); + return 0; + } + /* + * Other algorithm blocking will be done in FIPS_cmac_init, via + * FIPS_hmac_init_ex(). + */ + if (!impl && !ctx->i_ctx.engine) + return FIPS_hmac_init_ex(ctx, key, len, md, NULL); + } +#endif + /* If we are changing MD then we must have a key */ + if (md != NULL && md != ctx->md && (key == NULL || len < 0)) + return 0; + + if (md != NULL) { + reset = 1; + ctx->md = md; + } else if (ctx->md) { + md = ctx->md; + } else { + return 0; + } + + if (key != NULL) { + reset = 1; + j = EVP_MD_block_size(md); + OPENSSL_assert(j <= (int)sizeof(ctx->key)); + if (j < len) { + if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl)) + goto err; + if (!EVP_DigestUpdate(&ctx->md_ctx, key, len)) + goto err; + if (!EVP_DigestFinal_ex(&(ctx->md_ctx), ctx->key, + &ctx->key_length)) + goto err; + } else { + if (len < 0 || len > (int)sizeof(ctx->key)) + return 0; + memcpy(ctx->key, key, len); + ctx->key_length = len; + } + if (ctx->key_length != HMAC_MAX_MD_CBLOCK) + memset(&ctx->key[ctx->key_length], 0, + HMAC_MAX_MD_CBLOCK - ctx->key_length); + } + + if (reset) { + for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) + pad[i] = 0x36 ^ ctx->key[i]; + if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl)) + goto err; + if (!EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md))) + goto err; + + for (i = 0; i < HMAC_MAX_MD_CBLOCK; i++) + pad[i] = 0x5c ^ ctx->key[i]; + if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl)) + goto err; + if (!EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md))) + goto err; + } + if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx)) + goto err; + return 1; + err: + return 0; +} + +int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md) +{ + if (key && md) + HMAC_CTX_init(ctx); + return HMAC_Init_ex(ctx, key, len, md, NULL); +} + +int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !ctx->i_ctx.engine) + return FIPS_hmac_update(ctx, data, len); +#endif + if (!ctx->md) + return 0; + + return EVP_DigestUpdate(&ctx->md_ctx, data, len); +} + +int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len) +{ + unsigned int i; + unsigned char buf[EVP_MAX_MD_SIZE]; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !ctx->i_ctx.engine) + return FIPS_hmac_final(ctx, md, len); +#endif + + if (!ctx->md) + goto err; + + if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i)) + goto err; + if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx)) + goto err; + if (!EVP_DigestUpdate(&ctx->md_ctx, buf, i)) + goto err; + if (!EVP_DigestFinal_ex(&ctx->md_ctx, md, len)) + goto err; + return 1; + err: + return 0; +} + +void HMAC_CTX_init(HMAC_CTX *ctx) +{ + EVP_MD_CTX_init(&ctx->i_ctx); + EVP_MD_CTX_init(&ctx->o_ctx); + EVP_MD_CTX_init(&ctx->md_ctx); + ctx->md = NULL; +} + +int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx) +{ + if (!EVP_MD_CTX_copy(&dctx->i_ctx, &sctx->i_ctx)) + goto err; + if (!EVP_MD_CTX_copy(&dctx->o_ctx, &sctx->o_ctx)) + goto err; + if (!EVP_MD_CTX_copy(&dctx->md_ctx, &sctx->md_ctx)) + goto err; + memcpy(dctx->key, sctx->key, HMAC_MAX_MD_CBLOCK); + dctx->key_length = sctx->key_length; + dctx->md = sctx->md; + return 1; + err: + return 0; +} + +void HMAC_CTX_cleanup(HMAC_CTX *ctx) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !ctx->i_ctx.engine) { + FIPS_hmac_ctx_cleanup(ctx); + return; + } +#endif + EVP_MD_CTX_cleanup(&ctx->i_ctx); + EVP_MD_CTX_cleanup(&ctx->o_ctx); + EVP_MD_CTX_cleanup(&ctx->md_ctx); + memset(ctx, 0, sizeof *ctx); +} + +unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, + const unsigned char *d, size_t n, unsigned char *md, + unsigned int *md_len) +{ + HMAC_CTX c; + static unsigned char m[EVP_MAX_MD_SIZE]; + + if (md == NULL) + md = m; + HMAC_CTX_init(&c); + if (!HMAC_Init(&c, key, key_len, evp_md)) + goto err; + if (!HMAC_Update(&c, d, n)) + goto err; + if (!HMAC_Final(&c, md, md_len)) + goto err; + HMAC_CTX_cleanup(&c); + return md; + err: + HMAC_CTX_cleanup(&c); + return NULL; +} + +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags) +{ + EVP_MD_CTX_set_flags(&ctx->i_ctx, flags); + EVP_MD_CTX_set_flags(&ctx->o_ctx, flags); + EVP_MD_CTX_set_flags(&ctx->md_ctx, flags); +} diff --git a/libs/openssl/crypto/hmac/hmac.h b/libs/openssl/crypto/hmac/hmac.h new file mode 100644 index 00000000..b8b55cda --- /dev/null +++ b/libs/openssl/crypto/hmac/hmac.h @@ -0,0 +1,109 @@ +/* crypto/hmac/hmac.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +#ifndef HEADER_HMAC_H +# define HEADER_HMAC_H + +# include + +# ifdef OPENSSL_NO_HMAC +# error HMAC is disabled. +# endif + +# include + +# define HMAC_MAX_MD_CBLOCK 128/* largest known is SHA512 */ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct hmac_ctx_st { + const EVP_MD *md; + EVP_MD_CTX md_ctx; + EVP_MD_CTX i_ctx; + EVP_MD_CTX o_ctx; + unsigned int key_length; + unsigned char key[HMAC_MAX_MD_CBLOCK]; +} HMAC_CTX; + +# define HMAC_size(e) (EVP_MD_size((e)->md)) + +void HMAC_CTX_init(HMAC_CTX *ctx); +void HMAC_CTX_cleanup(HMAC_CTX *ctx); + +/* deprecated */ +# define HMAC_cleanup(ctx) HMAC_CTX_cleanup(ctx) + +/* deprecated */ +int HMAC_Init(HMAC_CTX *ctx, const void *key, int len, const EVP_MD *md); +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, int len, + const EVP_MD *md, ENGINE *impl); +int HMAC_Update(HMAC_CTX *ctx, const unsigned char *data, size_t len); +int HMAC_Final(HMAC_CTX *ctx, unsigned char *md, unsigned int *len); +unsigned char *HMAC(const EVP_MD *evp_md, const void *key, int key_len, + const unsigned char *d, size_t n, unsigned char *md, + unsigned int *md_len); +int HMAC_CTX_copy(HMAC_CTX *dctx, HMAC_CTX *sctx); + +void HMAC_CTX_set_flags(HMAC_CTX *ctx, unsigned long flags); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/hmac/hmactest.c b/libs/openssl/crypto/hmac/hmactest.c new file mode 100644 index 00000000..271d0ebf --- /dev/null +++ b/libs/openssl/crypto/hmac/hmactest.c @@ -0,0 +1,332 @@ +/* crypto/hmac/hmactest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "../e_os.h" + +#ifdef OPENSSL_NO_HMAC +int main(int argc, char *argv[]) +{ + printf("No HMAC support\n"); + return (0); +} +#else +# include +# ifndef OPENSSL_NO_MD5 +# include +# endif + +# ifdef CHARSET_EBCDIC +# include +# endif + +# ifndef OPENSSL_NO_MD5 +static struct test_st { + unsigned char key[16]; + int key_len; + unsigned char data[64]; + int data_len; + unsigned char *digest; +} test[8] = { + { + "", 0, "More text test vectors to stuff up EBCDIC machines :-)", 54, + (unsigned char *)"e9139d1e6ee064ef8cf514fc7dc83e86", + }, + { + { + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, + }, 16, "Hi There", 8, + (unsigned char *)"9294727a3638bb1c13f48ef8158bfc9d", + }, + { + "Jefe", 4, "what do ya want for nothing?", 28, + (unsigned char *)"750c783e6ab0b503eaa86e310a5db738", + }, + { + { + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, + }, 16, { + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, + 0xdd, 0xdd, 0xdd, 0xdd, 0xdd, 0xdd + }, 50, (unsigned char *)"56be34521d144c88dbb8c733f0e8b3f6", + }, + { + "", 0, "My test data", 12, + (unsigned char *)"61afdecb95429ef494d61fdee15990cabf0826fc" + }, + { + "", 0, "My test data", 12, + (unsigned char *)"2274b195d90ce8e03406f4b526a47e0787a88a65479938f1a5baa3ce0f079776" + }, + { + "123456", 6, "My test data", 12, + (unsigned char *)"bab53058ae861a7f191abe2d0145cbb123776a6369ee3f9d79ce455667e411dd" + }, + { + "12345", 5, "My test data again", 12, + (unsigned char *)"7dbe8c764c068e3bcd6e6b0fbcd5e6fc197b15bb" + } +}; +# endif + +static char *pt(unsigned char *md, unsigned int len); + +int main(int argc, char *argv[]) +{ +# ifndef OPENSSL_NO_MD5 + int i; + char *p; +# endif + int err = 0; + HMAC_CTX ctx, ctx2; + unsigned char buf[EVP_MAX_MD_SIZE]; + unsigned int len; + +# ifdef OPENSSL_NO_MD5 + printf("test skipped: MD5 disabled\n"); +# else + +# ifdef CHARSET_EBCDIC + ebcdic2ascii(test[0].data, test[0].data, test[0].data_len); + ebcdic2ascii(test[1].data, test[1].data, test[1].data_len); + ebcdic2ascii(test[2].key, test[2].key, test[2].key_len); + ebcdic2ascii(test[2].data, test[2].data, test[2].data_len); +# endif + + for (i = 0; i < 4; i++) { + p = pt(HMAC(EVP_md5(), + test[i].key, test[i].key_len, + test[i].data, test[i].data_len, NULL, NULL), + MD5_DIGEST_LENGTH); + + if (strcmp(p, (char *)test[i].digest) != 0) { + printf("Error calculating HMAC on %d entry'\n", i); + printf("got %s instead of %s\n", p, test[i].digest); + err++; + } else + printf("test %d ok\n", i); + } +# endif /* OPENSSL_NO_MD5 */ + +/* test4 */ + HMAC_CTX_init(&ctx); + if (HMAC_Init_ex(&ctx, NULL, 0, NULL, NULL)) { + printf("Should fail to initialise HMAC with empty MD and key (test 4)\n"); + err++; + goto test5; + } + if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) { + printf("Should fail HMAC_Update with ctx not set up (test 4)\n"); + err++; + goto test5; + } + if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha1(), NULL)) { + printf("Should fail to initialise HMAC with empty key (test 4)\n"); + err++; + goto test5; + } + if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) { + printf("Should fail HMAC_Update with ctx not set up (test 4)\n"); + err++; + goto test5; + } + printf("test 4 ok\n"); +test5: + HMAC_CTX_init(&ctx); + if (HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, NULL, NULL)) { + printf("Should fail to initialise HMAC with empty MD (test 5)\n"); + err++; + goto test6; + } + if (HMAC_Update(&ctx, test[4].data, test[4].data_len)) { + printf("Should fail HMAC_Update with ctx not set up (test 5)\n"); + err++; + goto test6; + } + if (HMAC_Init_ex(&ctx, test[4].key, -1, EVP_sha1(), NULL)) { + printf("Should fail to initialise HMAC with invalid key len(test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha1(), NULL)) { + printf("Failed to initialise HMAC (test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Update(&ctx, test[4].data, test[4].data_len)) { + printf("Error updating HMAC with data (test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Final(&ctx, buf, &len)) { + printf("Error finalising data (test 5)\n"); + err++; + goto test6; + } + p = pt(buf, len); + if (strcmp(p, (char *)test[4].digest) != 0) { + printf("Error calculating interim HMAC on test 5\n"); + printf("got %s instead of %s\n", p, test[4].digest); + err++; + goto test6; + } + if (HMAC_Init_ex(&ctx, NULL, 0, EVP_sha256(), NULL)) { + printf("Should disallow changing MD without a new key (test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Init_ex(&ctx, test[4].key, test[4].key_len, EVP_sha256(), NULL)) { + printf("Failed to reinitialise HMAC (test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Update(&ctx, test[5].data, test[5].data_len)) { + printf("Error updating HMAC with data (sha256) (test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Final(&ctx, buf, &len)) { + printf("Error finalising data (sha256) (test 5)\n"); + err++; + goto test6; + } + p = pt(buf, len); + if (strcmp(p, (char *)test[5].digest) != 0) { + printf("Error calculating 2nd interim HMAC on test 5\n"); + printf("got %s instead of %s\n", p, test[5].digest); + err++; + goto test6; + } + if (!HMAC_Init_ex(&ctx, test[6].key, test[6].key_len, NULL, NULL)) { + printf("Failed to reinitialise HMAC with key (test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Update(&ctx, test[6].data, test[6].data_len)) { + printf("Error updating HMAC with data (new key) (test 5)\n"); + err++; + goto test6; + } + if (!HMAC_Final(&ctx, buf, &len)) { + printf("Error finalising data (new key) (test 5)\n"); + err++; + goto test6; + } + p = pt(buf, len); + if (strcmp(p, (char *)test[6].digest) != 0) { + printf("error calculating HMAC on test 5\n"); + printf("got %s instead of %s\n", p, test[6].digest); + err++; + } else { + printf("test 5 ok\n"); + } +test6: + HMAC_CTX_init(&ctx); + if (!HMAC_Init_ex(&ctx, test[7].key, test[7].key_len, EVP_sha1(), NULL)) { + printf("Failed to initialise HMAC (test 6)\n"); + err++; + goto end; + } + if (!HMAC_Update(&ctx, test[7].data, test[7].data_len)) { + printf("Error updating HMAC with data (test 6)\n"); + err++; + goto end; + } + if (!HMAC_CTX_copy(&ctx2, &ctx)) { + printf("Failed to copy HMAC_CTX (test 6)\n"); + err++; + goto end; + } + if (!HMAC_Final(&ctx2, buf, &len)) { + printf("Error finalising data (test 6)\n"); + err++; + goto end; + } + p = pt(buf, len); + if (strcmp(p, (char *)test[7].digest) != 0) { + printf("Error calculating HMAC on test 6\n"); + printf("got %s instead of %s\n", p, test[7].digest); + err++; + } else { + printf("test 6 ok\n"); + } +end: + EXIT(err); + return (0); +} + +# ifndef OPENSSL_NO_MD5 +static char *pt(unsigned char *md, unsigned int len) +{ + unsigned int i; + static char buf[80]; + + for (i = 0; i < len; i++) + sprintf(&(buf[i * 2]), "%02x", md[i]); + return (buf); +} +# endif +#endif diff --git a/libs/openssl/crypto/ia64cpuid.S b/libs/openssl/crypto/ia64cpuid.S new file mode 100644 index 00000000..7832b9b6 --- /dev/null +++ b/libs/openssl/crypto/ia64cpuid.S @@ -0,0 +1,167 @@ +// Works on all IA-64 platforms: Linux, HP-UX, Win64i... +// On Win64i compile with ias.exe. +.text + +.global OPENSSL_cpuid_setup# +.proc OPENSSL_cpuid_setup# +OPENSSL_cpuid_setup: +{ .mib; br.ret.sptk.many b0 };; +.endp OPENSSL_cpuid_setup# + +.global OPENSSL_rdtsc# +.proc OPENSSL_rdtsc# +OPENSSL_rdtsc: +{ .mib; mov r8=ar.itc + br.ret.sptk.many b0 };; +.endp OPENSSL_rdtsc# + +.global OPENSSL_atomic_add# +.proc OPENSSL_atomic_add# +.align 32 +OPENSSL_atomic_add: +{ .mii; ld4 r2=[r32] + nop.i 0 + nop.i 0 };; +.Lspin: +{ .mii; mov ar.ccv=r2 + add r8=r2,r33 + mov r3=r2 };; +{ .mmi; mf;; + cmpxchg4.acq r2=[r32],r8,ar.ccv + nop.i 0 };; +{ .mib; cmp.ne p6,p0=r2,r3 + nop.i 0 +(p6) br.dpnt .Lspin };; +{ .mib; nop.m 0 + sxt4 r8=r8 + br.ret.sptk.many b0 };; +.endp OPENSSL_atomic_add# + +// Returns a structure comprising pointer to the top of stack of +// the caller and pointer beyond backing storage for the current +// register frame. The latter is required, because it might be +// insufficient to wipe backing storage for the current frame +// (as this procedure does), one might have to go further, toward +// higher addresses to reach for whole "retroactively" saved +// context... +.global OPENSSL_wipe_cpu# +.proc OPENSSL_wipe_cpu# +.align 32 +OPENSSL_wipe_cpu: + .prologue + .fframe 0 + .save ar.pfs,r2 + .save ar.lc,r3 +{ .mib; alloc r2=ar.pfs,0,96,0,96 + mov r3=ar.lc + brp.loop.imp .L_wipe_top,.L_wipe_end-16 + };; +{ .mii; mov r9=ar.bsp + mov r8=pr + mov ar.lc=96 };; + .body +{ .mii; add r9=96*8-8,r9 + mov ar.ec=1 };; + +// One can sweep double as fast, but then we can't quarantee +// that backing storage is wiped... +.L_wipe_top: +{ .mfi; st8 [r9]=r0,-8 + mov f127=f0 + mov r127=r0 } +{ .mfb; nop.m 0 + nop.f 0 + br.ctop.sptk .L_wipe_top };; +.L_wipe_end: + +{ .mfi; mov r11=r0 + mov f6=f0 + mov r14=r0 } +{ .mfi; mov r15=r0 + mov f7=f0 + mov r16=r0 } +{ .mfi; mov r17=r0 + mov f8=f0 + mov r18=r0 } +{ .mfi; mov r19=r0 + mov f9=f0 + mov r20=r0 } +{ .mfi; mov r21=r0 + mov f10=f0 + mov r22=r0 } +{ .mfi; mov r23=r0 + mov f11=f0 + mov r24=r0 } +{ .mfi; mov r25=r0 + mov f12=f0 + mov r26=r0 } +{ .mfi; mov r27=r0 + mov f13=f0 + mov r28=r0 } +{ .mfi; mov r29=r0 + mov f14=f0 + mov r30=r0 } +{ .mfi; mov r31=r0 + mov f15=f0 + nop.i 0 } +{ .mfi; mov f16=f0 } +{ .mfi; mov f17=f0 } +{ .mfi; mov f18=f0 } +{ .mfi; mov f19=f0 } +{ .mfi; mov f20=f0 } +{ .mfi; mov f21=f0 } +{ .mfi; mov f22=f0 } +{ .mfi; mov f23=f0 } +{ .mfi; mov f24=f0 } +{ .mfi; mov f25=f0 } +{ .mfi; mov f26=f0 } +{ .mfi; mov f27=f0 } +{ .mfi; mov f28=f0 } +{ .mfi; mov f29=f0 } +{ .mfi; mov f30=f0 } +{ .mfi; add r9=96*8+8,r9 + mov f31=f0 + mov pr=r8,0x1ffff } +{ .mib; mov r8=sp + mov ar.lc=r3 + br.ret.sptk b0 };; +.endp OPENSSL_wipe_cpu# + +.global OPENSSL_cleanse# +.proc OPENSSL_cleanse# +OPENSSL_cleanse: +{ .mib; cmp.eq p6,p0=0,r33 // len==0 +#if defined(_HPUX_SOURCE) && !defined(_LP64) + addp4 r32=0,r32 +#endif +(p6) br.ret.spnt b0 };; +{ .mib; and r2=7,r32 + cmp.leu p6,p0=15,r33 // len>=15 +(p6) br.cond.dptk .Lot };; + +.Little: +{ .mib; st1 [r32]=r0,1 + cmp.ltu p6,p7=1,r33 } // len>1 +{ .mbb; add r33=-1,r33 // len-- +(p6) br.cond.dptk .Little +(p7) br.ret.sptk.many b0 };; + +.Lot: +{ .mib; cmp.eq p6,p0=0,r2 +(p6) br.cond.dptk .Laligned };; +{ .mmi; st1 [r32]=r0,1;; + and r2=7,r32 } +{ .mib; add r33=-1,r33 + br .Lot };; + +.Laligned: +{ .mmi; st8 [r32]=r0,8 + and r2=-8,r33 // len&~7 + add r33=-8,r33 };; // len-=8 +{ .mib; cmp.ltu p6,p0=8,r2 // ((len+8)&~7)>8 +(p6) br.cond.dptk .Laligned };; + +{ .mbb; cmp.eq p6,p7=r0,r33 +(p7) br.cond.dpnt .Little +(p6) br.ret.sptk.many b0 };; +.endp OPENSSL_cleanse# diff --git a/libs/openssl/crypto/idea/i_cbc.c b/libs/openssl/crypto/idea/i_cbc.c new file mode 100644 index 00000000..950df98c --- /dev/null +++ b/libs/openssl/crypto/idea/i_cbc.c @@ -0,0 +1,171 @@ +/* crypto/idea/i_cbc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "idea_lcl.h" + +void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int encrypt) +{ + register unsigned long tin0, tin1; + register unsigned long tout0, tout1, xor0, xor1; + register long l = length; + unsigned long tin[2]; + + if (encrypt) { + n2l(iv, tout0); + n2l(iv, tout1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + n2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + idea_encrypt(tin, ks); + tout0 = tin[0]; + l2n(tout0, out); + tout1 = tin[1]; + l2n(tout1, out); + } + if (l != -8) { + n2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + idea_encrypt(tin, ks); + tout0 = tin[0]; + l2n(tout0, out); + tout1 = tin[1]; + l2n(tout1, out); + } + l2n(tout0, iv); + l2n(tout1, iv); + } else { + n2l(iv, xor0); + n2l(iv, xor1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + n2l(in, tin0); + tin[0] = tin0; + n2l(in, tin1); + tin[1] = tin1; + idea_encrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2n(tout0, out); + l2n(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + n2l(in, tin0); + tin[0] = tin0; + n2l(in, tin1); + tin[1] = tin1; + idea_encrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2nn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2n(xor0, iv); + l2n(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} + +void idea_encrypt(unsigned long *d, IDEA_KEY_SCHEDULE *key) +{ + register IDEA_INT *p; + register unsigned long x1, x2, x3, x4, t0, t1, ul; + + x2 = d[0]; + x1 = (x2 >> 16); + x4 = d[1]; + x3 = (x4 >> 16); + + p = &(key->data[0][0]); + + E_IDEA(0); + E_IDEA(1); + E_IDEA(2); + E_IDEA(3); + E_IDEA(4); + E_IDEA(5); + E_IDEA(6); + E_IDEA(7); + + x1 &= 0xffff; + idea_mul(x1, x1, *p, ul); + p++; + + t0 = x3 + *(p++); + t1 = x2 + *(p++); + + x4 &= 0xffff; + idea_mul(x4, x4, *p, ul); + + d[0] = (t0 & 0xffff) | ((x1 & 0xffff) << 16); + d[1] = (x4 & 0xffff) | ((t1 & 0xffff) << 16); +} diff --git a/libs/openssl/crypto/idea/i_cfb64.c b/libs/openssl/crypto/idea/i_cfb64.c new file mode 100644 index 00000000..a1547ed5 --- /dev/null +++ b/libs/openssl/crypto/idea/i_cfb64.c @@ -0,0 +1,123 @@ +/* crypto/idea/i_cfb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "idea_lcl.h" + +/* + * The input and output encrypted as though 64bit cfb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ + +void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *schedule, + unsigned char *ivec, int *num, int encrypt) +{ + register unsigned long v0, v1, t; + register int n = *num; + register long l = length; + unsigned long ti[2]; + unsigned char *iv, c, cc; + + iv = (unsigned char *)ivec; + if (encrypt) { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + idea_encrypt((unsigned long *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = (unsigned char *)ivec; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + n2l(iv, v0); + ti[0] = v0; + n2l(iv, v1); + ti[1] = v1; + idea_encrypt((unsigned long *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2n(t, iv); + t = ti[1]; + l2n(t, iv); + iv = (unsigned char *)ivec; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; + *num = n; +} diff --git a/libs/openssl/crypto/idea/i_ecb.c b/libs/openssl/crypto/idea/i_ecb.c new file mode 100644 index 00000000..a6b879a9 --- /dev/null +++ b/libs/openssl/crypto/idea/i_ecb.c @@ -0,0 +1,88 @@ +/* crypto/idea/i_ecb.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "idea_lcl.h" +#include + +const char IDEA_version[] = "IDEA" OPENSSL_VERSION_PTEXT; + +const char *idea_options(void) +{ + if (sizeof(short) != sizeof(IDEA_INT)) + return ("idea(int)"); + else + return ("idea(short)"); +} + +void idea_ecb_encrypt(const unsigned char *in, unsigned char *out, + IDEA_KEY_SCHEDULE *ks) +{ + unsigned long l0, l1, d[2]; + + n2l(in, l0); + d[0] = l0; + n2l(in, l1); + d[1] = l1; + idea_encrypt(d, ks); + l0 = d[0]; + l2n(l0, out); + l1 = d[1]; + l2n(l1, out); + l0 = l1 = d[0] = d[1] = 0; +} diff --git a/libs/openssl/crypto/idea/i_ofb64.c b/libs/openssl/crypto/idea/i_ofb64.c new file mode 100644 index 00000000..aa594880 --- /dev/null +++ b/libs/openssl/crypto/idea/i_ofb64.c @@ -0,0 +1,110 @@ +/* crypto/idea/i_ofb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "idea_lcl.h" + +/* + * The input and output encrypted as though 64bit ofb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ +void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *schedule, + unsigned char *ivec, int *num) +{ + register unsigned long v0, v1, t; + register int n = *num; + register long l = length; + unsigned char d[8]; + register char *dp; + unsigned long ti[2]; + unsigned char *iv; + int save = 0; + + iv = (unsigned char *)ivec; + n2l(iv, v0); + n2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2n(v0, dp); + l2n(v1, dp); + while (l--) { + if (n == 0) { + idea_encrypt((unsigned long *)ti, schedule); + dp = (char *)d; + t = ti[0]; + l2n(t, dp); + t = ti[1]; + l2n(t, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = (unsigned char *)ivec; + l2n(v0, iv); + l2n(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} diff --git a/libs/openssl/crypto/idea/i_skey.c b/libs/openssl/crypto/idea/i_skey.c new file mode 100644 index 00000000..53651513 --- /dev/null +++ b/libs/openssl/crypto/idea/i_skey.c @@ -0,0 +1,171 @@ +/* crypto/idea/i_skey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "idea_lcl.h" + +static IDEA_INT inverse(unsigned int xin); +void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks) +#ifdef OPENSSL_FIPS +{ + fips_cipher_abort(IDEA); + private_idea_set_encrypt_key(key, ks); +} + +void private_idea_set_encrypt_key(const unsigned char *key, + IDEA_KEY_SCHEDULE *ks) +#endif +{ + int i; + register IDEA_INT *kt, *kf, r0, r1, r2; + + kt = &(ks->data[0][0]); + n2s(key, kt[0]); + n2s(key, kt[1]); + n2s(key, kt[2]); + n2s(key, kt[3]); + n2s(key, kt[4]); + n2s(key, kt[5]); + n2s(key, kt[6]); + n2s(key, kt[7]); + + kf = kt; + kt += 8; + for (i = 0; i < 6; i++) { + r2 = kf[1]; + r1 = kf[2]; + *(kt++) = ((r2 << 9) | (r1 >> 7)) & 0xffff; + r0 = kf[3]; + *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; + r1 = kf[4]; + *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; + r0 = kf[5]; + *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; + r1 = kf[6]; + *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; + r0 = kf[7]; + *(kt++) = ((r1 << 9) | (r0 >> 7)) & 0xffff; + r1 = kf[0]; + if (i >= 5) + break; + *(kt++) = ((r0 << 9) | (r1 >> 7)) & 0xffff; + *(kt++) = ((r1 << 9) | (r2 >> 7)) & 0xffff; + kf += 8; + } +} + +void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk) +{ + int r; + register IDEA_INT *fp, *tp, t; + + tp = &(dk->data[0][0]); + fp = &(ek->data[8][0]); + for (r = 0; r < 9; r++) { + *(tp++) = inverse(fp[0]); + *(tp++) = ((int)(0x10000L - fp[2]) & 0xffff); + *(tp++) = ((int)(0x10000L - fp[1]) & 0xffff); + *(tp++) = inverse(fp[3]); + if (r == 8) + break; + fp -= 6; + *(tp++) = fp[4]; + *(tp++) = fp[5]; + } + + tp = &(dk->data[0][0]); + t = tp[1]; + tp[1] = tp[2]; + tp[2] = t; + + t = tp[49]; + tp[49] = tp[50]; + tp[50] = t; +} + +/* taken directly from the 'paper' I'll have a look at it later */ +static IDEA_INT inverse(unsigned int xin) +{ + long n1, n2, q, r, b1, b2, t; + + if (xin == 0) + b2 = 0; + else { + n1 = 0x10001; + n2 = xin; + b2 = 1; + b1 = 0; + + do { + r = (n1 % n2); + q = (n1 - r) / n2; + if (r == 0) { + if (b2 < 0) + b2 = 0x10001 + b2; + } else { + n1 = n2; + n2 = r; + t = b2; + b2 = b1 - q * b2; + b1 = t; + } + } while (r != 0); + } + return ((IDEA_INT) b2); +} diff --git a/libs/openssl/crypto/idea/idea.h b/libs/openssl/crypto/idea/idea.h new file mode 100644 index 00000000..60759840 --- /dev/null +++ b/libs/openssl/crypto/idea/idea.h @@ -0,0 +1,105 @@ +/* crypto/idea/idea.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_IDEA_H +# define HEADER_IDEA_H + +# include /* IDEA_INT, OPENSSL_NO_IDEA */ + +# ifdef OPENSSL_NO_IDEA +# error IDEA is disabled. +# endif + +# define IDEA_ENCRYPT 1 +# define IDEA_DECRYPT 0 + +# define IDEA_BLOCK 8 +# define IDEA_KEY_LENGTH 16 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct idea_key_st { + IDEA_INT data[9][6]; +} IDEA_KEY_SCHEDULE; + +const char *idea_options(void); +void idea_ecb_encrypt(const unsigned char *in, unsigned char *out, + IDEA_KEY_SCHEDULE *ks); +# ifdef OPENSSL_FIPS +void private_idea_set_encrypt_key(const unsigned char *key, + IDEA_KEY_SCHEDULE *ks); +# endif +void idea_set_encrypt_key(const unsigned char *key, IDEA_KEY_SCHEDULE *ks); +void idea_set_decrypt_key(IDEA_KEY_SCHEDULE *ek, IDEA_KEY_SCHEDULE *dk); +void idea_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int enc); +void idea_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int *num, int enc); +void idea_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, IDEA_KEY_SCHEDULE *ks, unsigned char *iv, + int *num); +void idea_encrypt(unsigned long *in, IDEA_KEY_SCHEDULE *ks); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/idea/idea_lcl.h b/libs/openssl/crypto/idea/idea_lcl.h new file mode 100644 index 00000000..e4069538 --- /dev/null +++ b/libs/openssl/crypto/idea/idea_lcl.h @@ -0,0 +1,216 @@ +/* crypto/idea/idea_lcl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * The new form of this macro (check if the a*b == 0) was suggested by Colin + * Plumb + */ +/* Removal of the inner if from from Wei Dai 24/4/96 */ +#define idea_mul(r,a,b,ul) \ +ul=(unsigned long)a*b; \ +if (ul != 0) \ + { \ + r=(ul&0xffff)-(ul>>16); \ + r-=((r)>>16); \ + } \ +else \ + r=(-(int)a-b+1); /* assuming a or b is 0 and in range */ + +#ifdef undef +# define idea_mul(r,a,b,ul,sl) \ +if (a == 0) r=(0x10001-b)&0xffff; \ +else if (b == 0) r=(0x10001-a)&0xffff; \ +else { \ + ul=(unsigned long)a*b; \ + sl=(ul&0xffff)-(ul>>16); \ + if (sl <= 0) sl+=0x10001; \ + r=sl; \ + } +#endif + +/* + * 7/12/95 - Many thanks to Rhys Weatherley for + * pointing out that I was assuming little endian byte order for all + * quantities what idea actually used bigendian. No where in the spec does + * it mention this, it is all in terms of 16 bit numbers and even the example + * does not use byte streams for the input example :-(. If you byte swap each + * pair of input, keys and iv, the functions would produce the output as the + * old version :-(. + */ + +/* NOTE - c is not incremented as per n2l */ +#define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + } \ + } + +#undef n2l +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +#undef l2n +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +#undef s2n +#define s2n(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff)) + +#undef n2s +#define n2s(c,l) (l =((IDEA_INT)(*((c)++)))<< 8L, \ + l|=((IDEA_INT)(*((c)++))) ) + +#ifdef undef +/* NOTE - c is not incremented as per c2l */ +# define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +/* NOTE - c is not incremented as per l2c */ +# define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +# undef c2s +# define c2s(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L) + +# undef s2c +# define s2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff)) + +# undef c2l +# define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +# undef l2c +# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) +#endif + +#define E_IDEA(num) \ + x1&=0xffff; \ + idea_mul(x1,x1,*p,ul); p++; \ + x2+= *(p++); \ + x3+= *(p++); \ + x4&=0xffff; \ + idea_mul(x4,x4,*p,ul); p++; \ + t0=(x1^x3)&0xffff; \ + idea_mul(t0,t0,*p,ul); p++; \ + t1=(t0+(x2^x4))&0xffff; \ + idea_mul(t1,t1,*p,ul); p++; \ + t0+=t1; \ + x1^=t1; \ + x4^=t0; \ + ul=x2^t0; /* do the swap to x3 */ \ + x2=x3^t1; \ + x3=ul; diff --git a/libs/openssl/crypto/idea/idea_spd.c b/libs/openssl/crypto/idea/idea_spd.c new file mode 100644 index 00000000..59acc407 --- /dev/null +++ b/libs/openssl/crypto/idea/idea_spd.c @@ -0,0 +1,283 @@ +/* crypto/idea/idea_spd.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */ +/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */ + +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX) +# define TIMES +#endif + +#include + +#include +#include OPENSSL_UNISTD_IO +OPENSSL_DECLARE_EXIT +#ifndef OPENSSL_SYS_NETWARE +# include +#endif +#ifndef _IRIX +# include +#endif +#ifdef TIMES +# include +# include +#endif + /* + * Depending on the VMS version, the tms structure is perhaps defined. + * The __TMS macro will show if it was. If it wasn't defined, we should + * undefine TIMES, since that tells the rest of the program how things + * should be handled. -- Richard Levitte + */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) +# undef TIMES +#endif +#ifndef TIMES +# include +#endif +#if defined(sun) || defined(__ultrix) +# define _POSIX_SOURCE +# include +# include +#endif +#include +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# define HZ 100.0 +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +#endif +#define BUFSIZE ((long)1024) +long run = 0; + +double Time_F(int s); +#ifdef SIGALRM +# if defined(__STDC__) || defined(sgi) || defined(_AIX) +# define SIGRETTYPE void +# else +# define SIGRETTYPE int +# endif + +SIGRETTYPE sig_done(int sig); +SIGRETTYPE sig_done(int sig) +{ + signal(SIGALRM, sig_done); + run = 0; +# ifdef LINT + sig = sig; +# endif +} +#endif + +#define START 0 +#define STOP 1 + +double Time_F(int s) +{ + double ret; +#ifdef TIMES + static struct tms tstart, tend; + + if (s == START) { + times(&tstart); + return (0); + } else { + times(&tend); + ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ; + return ((ret == 0.0) ? 1e-6 : ret); + } +#else /* !times() */ + static struct timeb tstart, tend; + long i; + + if (s == START) { + ftime(&tstart); + return (0); + } else { + ftime(&tend); + i = (long)tend.millitm - (long)tstart.millitm; + ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1e3; + return ((ret == 0.0) ? 1e-6 : ret); + } +#endif +} + +int main(int argc, char **argv) +{ + long count; + static unsigned char buf[BUFSIZE]; + static unsigned char key[] = { + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + IDEA_KEY_SCHEDULE sch; + double a, aa, b, c, d; +#ifndef SIGALRM + long ca, cca, cb, cc; +#endif + +#ifndef TIMES + printf("To get the most accurate results, try to run this\n"); + printf("program when this computer is idle.\n"); +#endif + +#ifndef SIGALRM + printf("First we calculate the approximate speed ...\n"); + idea_set_encrypt_key(key, &sch); + count = 10; + do { + long i; + IDEA_INT data[2]; + + count *= 2; + Time_F(START); + for (i = count; i; i--) + idea_encrypt(data, &sch); + d = Time_F(STOP); + } while (d < 3.0); + ca = count / 4; + cca = count / 200; + cb = count; + cc = count * 8 / BUFSIZE + 1; + printf("idea_set_encrypt_key %ld times\n", ca); +# define COND(d) (count <= (d)) +# define COUNT(d) (d) +#else +# define COND(c) (run) +# define COUNT(d) (count) + signal(SIGALRM, sig_done); + printf("Doing idea_set_encrypt_key for 10 seconds\n"); + alarm(10); +#endif + + Time_F(START); + for (count = 0, run = 1; COND(ca); count += 4) { + idea_set_encrypt_key(key, &sch); + idea_set_encrypt_key(key, &sch); + idea_set_encrypt_key(key, &sch); + idea_set_encrypt_key(key, &sch); + } + d = Time_F(STOP); + printf("%ld idea idea_set_encrypt_key's in %.2f seconds\n", count, d); + a = ((double)COUNT(ca)) / d; + +#ifdef SIGALRM + printf("Doing idea_set_decrypt_key for 10 seconds\n"); + alarm(10); +#else + printf("Doing idea_set_decrypt_key %ld times\n", cca); +#endif + + Time_F(START); + for (count = 0, run = 1; COND(cca); count += 4) { + idea_set_decrypt_key(&sch, &sch); + idea_set_decrypt_key(&sch, &sch); + idea_set_decrypt_key(&sch, &sch); + idea_set_decrypt_key(&sch, &sch); + } + d = Time_F(STOP); + printf("%ld idea idea_set_decrypt_key's in %.2f seconds\n", count, d); + aa = ((double)COUNT(cca)) / d; + +#ifdef SIGALRM + printf("Doing idea_encrypt's for 10 seconds\n"); + alarm(10); +#else + printf("Doing idea_encrypt %ld times\n", cb); +#endif + Time_F(START); + for (count = 0, run = 1; COND(cb); count += 4) { + unsigned long data[2]; + + idea_encrypt(data, &sch); + idea_encrypt(data, &sch); + idea_encrypt(data, &sch); + idea_encrypt(data, &sch); + } + d = Time_F(STOP); + printf("%ld idea_encrypt's in %.2f second\n", count, d); + b = ((double)COUNT(cb) * 8) / d; + +#ifdef SIGALRM + printf("Doing idea_cbc_encrypt on %ld byte blocks for 10 seconds\n", + BUFSIZE); + alarm(10); +#else + printf("Doing idea_cbc_encrypt %ld times on %ld byte blocks\n", cc, + BUFSIZE); +#endif + Time_F(START); + for (count = 0, run = 1; COND(cc); count++) + idea_cbc_encrypt(buf, buf, BUFSIZE, &sch, &(key[0]), IDEA_ENCRYPT); + d = Time_F(STOP); + printf("%ld idea_cbc_encrypt's of %ld byte blocks in %.2f second\n", + count, BUFSIZE, d); + c = ((double)COUNT(cc) * BUFSIZE) / d; + + printf("IDEA set_encrypt_key per sec = %12.2f (%9.3fuS)\n", a, 1.0e6 / a); + printf("IDEA set_decrypt_key per sec = %12.2f (%9.3fuS)\n", aa, + 1.0e6 / aa); + printf("IDEA raw ecb bytes per sec = %12.2f (%9.3fuS)\n", b, 8.0e6 / b); + printf("IDEA cbc bytes per sec = %12.2f (%9.3fuS)\n", c, 8.0e6 / c); + exit(0); +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS) + return (0); +#endif +} diff --git a/libs/openssl/crypto/idea/ideatest.c b/libs/openssl/crypto/idea/ideatest.c new file mode 100644 index 00000000..a967dd58 --- /dev/null +++ b/libs/openssl/crypto/idea/ideatest.c @@ -0,0 +1,232 @@ +/* crypto/idea/ideatest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "../e_os.h" + +#ifdef OPENSSL_NO_IDEA +int main(int argc, char *argv[]) +{ + printf("No IDEA support\n"); + return (0); +} +#else +# include + +unsigned char k[16] = { + 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 +}; + +unsigned char in[8] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03 }; +unsigned char c[8] = { 0x11, 0xFB, 0xED, 0x2B, 0x01, 0x98, 0x6D, 0xE5 }; + +unsigned char out[80]; + +char *text = "Hello to all people out there"; + +static unsigned char cfb_key[16] = { + 0xe1, 0xf0, 0xc3, 0xd2, 0xa5, 0xb4, 0x87, 0x96, + 0x69, 0x78, 0x4b, 0x5a, 0x2d, 0x3c, 0x0f, 0x1e, +}; +static unsigned char cfb_iv[80] = + { 0x34, 0x12, 0x78, 0x56, 0xab, 0x90, 0xef, 0xcd }; +static unsigned char cfb_buf1[40], cfb_buf2[40], cfb_tmp[8]; +# define CFB_TEST_SIZE 24 +static unsigned char plain[CFB_TEST_SIZE] = { + 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, + 0x69, 0x6d, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 +}; + +static unsigned char cfb_cipher64[CFB_TEST_SIZE] = { + 0x59, 0xD8, 0xE2, 0x65, 0x00, 0x58, 0x6C, 0x3F, + 0x2C, 0x17, 0x25, 0xD0, 0x1A, 0x38, 0xB7, 0x2A, + 0x39, 0x61, 0x37, 0xDC, 0x79, 0xFB, 0x9F, 0x45 +/*- 0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38, + 0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9, + 0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/ +}; + +static int cfb64_test(unsigned char *cfb_cipher); +static char *pt(unsigned char *p); +int main(int argc, char *argv[]) +{ + int i, err = 0; + IDEA_KEY_SCHEDULE key, dkey; + unsigned char iv[8]; + + idea_set_encrypt_key(k, &key); + idea_ecb_encrypt(in, out, &key); + if (memcmp(out, c, 8) != 0) { + printf("ecb idea error encrypting\n"); + printf("got :"); + for (i = 0; i < 8; i++) + printf("%02X ", out[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 8; i++) + printf("%02X ", c[i]); + err = 20; + printf("\n"); + } + + idea_set_decrypt_key(&key, &dkey); + idea_ecb_encrypt(c, out, &dkey); + if (memcmp(out, in, 8) != 0) { + printf("ecb idea error decrypting\n"); + printf("got :"); + for (i = 0; i < 8; i++) + printf("%02X ", out[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 8; i++) + printf("%02X ", in[i]); + printf("\n"); + err = 3; + } + + if (err == 0) + printf("ecb idea ok\n"); + + memcpy(iv, k, 8); + idea_cbc_encrypt((unsigned char *)text, out, strlen(text) + 1, &key, iv, + 1); + memcpy(iv, k, 8); + idea_cbc_encrypt(out, out, 8, &dkey, iv, 0); + idea_cbc_encrypt(&(out[8]), &(out[8]), strlen(text) + 1 - 8, &dkey, iv, + 0); + if (memcmp(text, out, strlen(text) + 1) != 0) { + printf("cbc idea bad\n"); + err = 4; + } else + printf("cbc idea ok\n"); + + printf("cfb64 idea "); + if (cfb64_test(cfb_cipher64)) { + printf("bad\n"); + err = 5; + } else + printf("ok\n"); + +# ifdef OPENSSL_SYS_NETWARE + if (err) + printf("ERROR: %d\n", err); +# endif + EXIT(err); + return (err); +} + +static int cfb64_test(unsigned char *cfb_cipher) +{ + IDEA_KEY_SCHEDULE eks, dks; + int err = 0, i, n; + + idea_set_encrypt_key(cfb_key, &eks); + idea_set_decrypt_key(&eks, &dks); + memcpy(cfb_tmp, cfb_iv, 8); + n = 0; + idea_cfb64_encrypt(plain, cfb_buf1, (long)12, &eks, + cfb_tmp, &n, IDEA_ENCRYPT); + idea_cfb64_encrypt(&(plain[12]), &(cfb_buf1[12]), + (long)CFB_TEST_SIZE - 12, &eks, + cfb_tmp, &n, IDEA_ENCRYPT); + if (memcmp(cfb_cipher, cfb_buf1, CFB_TEST_SIZE) != 0) { + err = 1; + printf("idea_cfb64_encrypt encrypt error\n"); + for (i = 0; i < CFB_TEST_SIZE; i += 8) + printf("%s\n", pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp, cfb_iv, 8); + n = 0; + idea_cfb64_encrypt(cfb_buf1, cfb_buf2, (long)13, &eks, + cfb_tmp, &n, IDEA_DECRYPT); + idea_cfb64_encrypt(&(cfb_buf1[13]), &(cfb_buf2[13]), + (long)CFB_TEST_SIZE - 13, &eks, + cfb_tmp, &n, IDEA_DECRYPT); + if (memcmp(plain, cfb_buf2, CFB_TEST_SIZE) != 0) { + err = 1; + printf("idea_cfb_encrypt decrypt error\n"); + for (i = 0; i < 24; i += 8) + printf("%s\n", pt(&(cfb_buf2[i]))); + } + return (err); +} + +static char *pt(unsigned char *p) +{ + static char bufs[10][20]; + static int bnum = 0; + char *ret; + int i; + static char *f = "0123456789ABCDEF"; + + ret = &(bufs[bnum++][0]); + bnum %= 10; + for (i = 0; i < 8; i++) { + ret[i * 2] = f[(p[i] >> 4) & 0xf]; + ret[i * 2 + 1] = f[p[i] & 0xf]; + } + ret[16] = '\0'; + return (ret); +} +#endif diff --git a/libs/openssl/crypto/idea/version b/libs/openssl/crypto/idea/version new file mode 100644 index 00000000..3f222937 --- /dev/null +++ b/libs/openssl/crypto/idea/version @@ -0,0 +1,12 @@ +1.1 07/12/95 - eay + Many thanks to Rhys Weatherley + for pointing out that I was assuming little endian byte + order for all quantities what idea actually used + bigendian. No where in the spec does it mention + this, it is all in terms of 16 bit numbers and even the example + does not use byte streams for the input example :-(. + If you byte swap each pair of input, keys and iv, the functions + would produce the output as the old version :-(. + +1.0 ??/??/95 - eay + First version. diff --git a/libs/openssl/crypto/install-crypto.com b/libs/openssl/crypto/install-crypto.com new file mode 100755 index 00000000..d19081d4 --- /dev/null +++ b/libs/openssl/crypto/install-crypto.com @@ -0,0 +1,199 @@ +$! INSTALL.COM -- Installs the files in a given directory tree +$! +$! Author: Richard Levitte +$! Time of creation: 22-MAY-1998 10:13 +$! +$! Changes by Zoltan Arpadffy +$! +$! P1 root of the directory tree +$! P2 "64" for 64-bit pointers. +$! +$! +$! Announce/identify. +$! +$ proc = f$environment( "procedure") +$ write sys$output "@@@ "+ - + f$parse( proc, , , "name")+ f$parse( proc, , , "type") +$! +$ on error then goto tidy +$ on control_c then goto tidy +$! +$ if (p1 .eqs. "") +$ then +$ write sys$output "First argument missing." +$ write sys$output - + "It should be the directory where you want things installed." +$ exit +$ endif +$! +$ if (f$getsyi( "cpu") .lt. 128) +$ then +$ arch = "VAX" +$ else +$ arch = f$edit( f$getsyi( "arch_name"), "upcase") +$ if (arch .eqs. "") then arch = "UNK" +$ endif +$! +$ archd = arch +$ lib32 = "32" +$ shr = "_SHR32" +$! +$ if (p2 .nes. "") +$ then +$ if (p2 .eqs. "64") +$ then +$ archd = arch+ "_64" +$ lib32 = "" +$ shr = "_SHR" +$ else +$ if (p2 .nes. "32") +$ then +$ write sys$output "Second argument invalid." +$ write sys$output "It should be "32", "64", or nothing." +$ exit +$ endif +$ endif +$ endif +$! +$ root = f$parse( p1, "[]A.;0", , , "syntax_only, no_conceal") - "A.;0" +$ root_dev = f$parse( root, , , "device", "syntax_only") +$ root_dir = f$parse( root, , , "directory", "syntax_only") - - + "[000000." - "][" - "[" - "]" +$ root = root_dev + "[" + root_dir +$! +$ define /nolog wrk_sslroot 'root'.] /trans=conc +$ define /nolog wrk_sslinclude wrk_sslroot:[include] +$ define /nolog wrk_sslxlib wrk_sslroot:['arch'_lib] +$! +$ if f$parse("wrk_sslroot:[000000]") .eqs. "" then - + create /directory /log wrk_sslroot:[000000] +$ if f$parse("wrk_sslinclude:") .eqs. "" then - + create /directory /log wrk_sslinclude: +$ if f$parse("wrk_sslxlib:") .eqs. "" then - + create /directory /log wrk_sslxlib: +$! +$ sdirs := , - + 'archd', - + objects, - + md4, md5, sha, mdc2, hmac, ripemd, whrlpool, - + des, aes, rc2, rc4, idea, bf, cast, camellia, seed, - + bn, ec, rsa, dsa, ecdsa, dh, ecdh, dso, engine, - + buffer, bio, stack, lhash, rand, err, - + evp, asn1, pem, x509, x509v3, conf, txt_db, pkcs7, pkcs12, comp, ocsp, - + ui, krb5, - + cms, pqueue, ts, jpake, srp, store, cmac +$! +$ exheader_ := crypto.h, opensslv.h, ebcdic.h, symhacks.h, ossl_typ.h +$ exheader_'archd' := opensslconf.h +$ exheader_objects := objects.h, obj_mac.h +$ exheader_md2 := md2.h +$ exheader_md4 := md4.h +$ exheader_md5 := md5.h +$ exheader_sha := sha.h +$ exheader_mdc2 := mdc2.h +$ exheader_hmac := hmac.h +$ exheader_ripemd := ripemd.h +$ exheader_whrlpool := whrlpool.h +$ exheader_des := des.h, des_old.h +$ exheader_aes := aes.h +$ exheader_rc2 := rc2.h +$ exheader_rc4 := rc4.h +$ exheader_rc5 := rc5.h +$ exheader_idea := idea.h +$ exheader_bf := blowfish.h +$ exheader_cast := cast.h +$ exheader_camellia := camellia.h +$ exheader_seed := seed.h +$ exheader_modes := modes.h +$ exheader_bn := bn.h +$ exheader_ec := ec.h +$ exheader_rsa := rsa.h +$ exheader_dsa := dsa.h +$ exheader_ecdsa := ecdsa.h +$ exheader_dh := dh.h +$ exheader_ecdh := ecdh.h +$ exheader_dso := dso.h +$ exheader_engine := engine.h +$ exheader_buffer := buffer.h +$ exheader_bio := bio.h +$ exheader_stack := stack.h, safestack.h +$ exheader_lhash := lhash.h +$ exheader_rand := rand.h +$ exheader_err := err.h +$ exheader_evp := evp.h +$ exheader_asn1 := asn1.h, asn1_mac.h, asn1t.h +$ exheader_pem := pem.h, pem2.h +$ exheader_x509 := x509.h, x509_vfy.h +$ exheader_x509v3 := x509v3.h +$ exheader_conf := conf.h, conf_api.h +$ exheader_txt_db := txt_db.h +$ exheader_pkcs7 := pkcs7.h +$ exheader_pkcs12 := pkcs12.h +$ exheader_comp := comp.h +$ exheader_ocsp := ocsp.h +$ exheader_ui := ui.h, ui_compat.h +$ exheader_krb5 := krb5_asn.h +$! exheader_store := store.h, str_compat.h +$ exheader_store := store.h +$ exheader_cms := cms.h +$ exheader_pqueue := pqueue.h +$ exheader_ts := ts.h +$ exheader_jpake := jpake.h +$ exheader_srp := srp.h +$ exheader_store := store.h +$ exheader_cmac := cmac.h +$ libs := ssl_libcrypto +$! +$ exe_dir := [-.'archd'.exe.crypto] +$! +$! Header files. +$! +$ i = 0 +$ loop_sdirs: +$ d = f$edit( f$element( i, ",", sdirs), "trim") +$ i = i + 1 +$ if d .eqs. "," then goto loop_sdirs_end +$ tmp = exheader_'d' +$ if (d .nes. "") then d = "."+ d +$ copy /protection = w:re ['d']'tmp' wrk_sslinclude: /log +$ goto loop_sdirs +$ loop_sdirs_end: +$! +$! Object libraries, shareable images. +$! +$ i = 0 +$ loop_lib: +$ e = f$edit( f$element( i, ",", libs), "trim") +$ i = i + 1 +$ if e .eqs. "," then goto loop_lib_end +$ set noon +$ file = exe_dir+ e+ lib32+ ".olb" +$ if f$search( file) .nes. "" +$ then +$ copy /protection = w:re 'file' wrk_sslxlib: /log +$ endif +$! +$ file = exe_dir+ e+ shr+ ".exe" +$ if f$search( file) .nes. "" +$ then +$ copy /protection = w:re 'file' wrk_sslxlib: /log +$ endif +$ set on +$ goto loop_lib +$ loop_lib_end: +$! +$ tidy: +$! +$ call deass wrk_sslroot +$ call deass wrk_sslinclude +$ call deass wrk_sslxlib +$! +$ exit +$! +$ deass: subroutine +$ if (f$trnlnm( p1, "LNM$PROCESS") .nes. "") +$ then +$ deassign /process 'p1' +$ endif +$ endsubroutine +$! diff --git a/libs/openssl/crypto/jpake/jpake.c b/libs/openssl/crypto/jpake/jpake.c new file mode 100644 index 00000000..ac853d49 --- /dev/null +++ b/libs/openssl/crypto/jpake/jpake.c @@ -0,0 +1,511 @@ +#include "jpake.h" + +#include +#include +#include +#include + +/* + * In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or + * Bob's (x3, x4, x1, x2). If you see what I mean. + */ + +typedef struct { + char *name; /* Must be unique */ + char *peer_name; + BIGNUM *p; + BIGNUM *g; + BIGNUM *q; + BIGNUM *gxc; /* Alice's g^{x3} or Bob's g^{x1} */ + BIGNUM *gxd; /* Alice's g^{x4} or Bob's g^{x2} */ +} JPAKE_CTX_PUBLIC; + +struct JPAKE_CTX { + JPAKE_CTX_PUBLIC p; + BIGNUM *secret; /* The shared secret */ + BN_CTX *ctx; + BIGNUM *xa; /* Alice's x1 or Bob's x3 */ + BIGNUM *xb; /* Alice's x2 or Bob's x4 */ + BIGNUM *key; /* The calculated (shared) key */ +}; + +static void JPAKE_ZKP_init(JPAKE_ZKP *zkp) +{ + zkp->gr = BN_new(); + zkp->b = BN_new(); +} + +static void JPAKE_ZKP_release(JPAKE_ZKP *zkp) +{ + BN_free(zkp->b); + BN_free(zkp->gr); +} + +/* Two birds with one stone - make the global name as expected */ +#define JPAKE_STEP_PART_init JPAKE_STEP2_init +#define JPAKE_STEP_PART_release JPAKE_STEP2_release + +void JPAKE_STEP_PART_init(JPAKE_STEP_PART *p) +{ + p->gx = BN_new(); + JPAKE_ZKP_init(&p->zkpx); +} + +void JPAKE_STEP_PART_release(JPAKE_STEP_PART *p) +{ + JPAKE_ZKP_release(&p->zkpx); + BN_free(p->gx); +} + +void JPAKE_STEP1_init(JPAKE_STEP1 *s1) +{ + JPAKE_STEP_PART_init(&s1->p1); + JPAKE_STEP_PART_init(&s1->p2); +} + +void JPAKE_STEP1_release(JPAKE_STEP1 *s1) +{ + JPAKE_STEP_PART_release(&s1->p2); + JPAKE_STEP_PART_release(&s1->p1); +} + +static void JPAKE_CTX_init(JPAKE_CTX *ctx, const char *name, + const char *peer_name, const BIGNUM *p, + const BIGNUM *g, const BIGNUM *q, + const BIGNUM *secret) +{ + ctx->p.name = OPENSSL_strdup(name); + ctx->p.peer_name = OPENSSL_strdup(peer_name); + ctx->p.p = BN_dup(p); + ctx->p.g = BN_dup(g); + ctx->p.q = BN_dup(q); + ctx->secret = BN_dup(secret); + + ctx->p.gxc = BN_new(); + ctx->p.gxd = BN_new(); + + ctx->xa = BN_new(); + ctx->xb = BN_new(); + ctx->key = BN_new(); + ctx->ctx = BN_CTX_new(); +} + +static void JPAKE_CTX_release(JPAKE_CTX *ctx) +{ + BN_CTX_free(ctx->ctx); + BN_clear_free(ctx->key); + BN_clear_free(ctx->xb); + BN_clear_free(ctx->xa); + + BN_free(ctx->p.gxd); + BN_free(ctx->p.gxc); + + BN_clear_free(ctx->secret); + BN_free(ctx->p.q); + BN_free(ctx->p.g); + BN_free(ctx->p.p); + OPENSSL_free(ctx->p.peer_name); + OPENSSL_free(ctx->p.name); + + memset(ctx, '\0', sizeof *ctx); +} + +JPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name, + const BIGNUM *p, const BIGNUM *g, const BIGNUM *q, + const BIGNUM *secret) +{ + JPAKE_CTX *ctx = OPENSSL_malloc(sizeof *ctx); + + JPAKE_CTX_init(ctx, name, peer_name, p, g, q, secret); + + return ctx; +} + +void JPAKE_CTX_free(JPAKE_CTX *ctx) +{ + JPAKE_CTX_release(ctx); + OPENSSL_free(ctx); +} + +static void hashlength(SHA_CTX *sha, size_t l) +{ + unsigned char b[2]; + + OPENSSL_assert(l <= 0xffff); + b[0] = l >> 8; + b[1] = l & 0xff; + SHA1_Update(sha, b, 2); +} + +static void hashstring(SHA_CTX *sha, const char *string) +{ + size_t l = strlen(string); + + hashlength(sha, l); + SHA1_Update(sha, string, l); +} + +static void hashbn(SHA_CTX *sha, const BIGNUM *bn) +{ + size_t l = BN_num_bytes(bn); + unsigned char *bin = OPENSSL_malloc(l); + + hashlength(sha, l); + BN_bn2bin(bn, bin); + SHA1_Update(sha, bin, l); + OPENSSL_free(bin); +} + +/* h=hash(g, g^r, g^x, name) */ +static void zkp_hash(BIGNUM *h, const BIGNUM *zkpg, const JPAKE_STEP_PART *p, + const char *proof_name) +{ + unsigned char md[SHA_DIGEST_LENGTH]; + SHA_CTX sha; + + /* + * XXX: hash should not allow moving of the boundaries - Java code + * is flawed in this respect. Length encoding seems simplest. + */ + SHA1_Init(&sha); + hashbn(&sha, zkpg); + OPENSSL_assert(!BN_is_zero(p->zkpx.gr)); + hashbn(&sha, p->zkpx.gr); + hashbn(&sha, p->gx); + hashstring(&sha, proof_name); + SHA1_Final(md, &sha); + BN_bin2bn(md, SHA_DIGEST_LENGTH, h); +} + +/* + * Prove knowledge of x + * Note that p->gx has already been calculated + */ +static void generate_zkp(JPAKE_STEP_PART *p, const BIGNUM *x, + const BIGNUM *zkpg, JPAKE_CTX *ctx) +{ + BIGNUM *r = BN_new(); + BIGNUM *h = BN_new(); + BIGNUM *t = BN_new(); + + /*- + * r in [0,q) + * XXX: Java chooses r in [0, 2^160) - i.e. distribution not uniform + */ + BN_rand_range(r, ctx->p.q); + /* g^r */ + BN_mod_exp(p->zkpx.gr, zkpg, r, ctx->p.p, ctx->ctx); + + /* h=hash... */ + zkp_hash(h, zkpg, p, ctx->p.name); + + /* b = r - x*h */ + BN_mod_mul(t, x, h, ctx->p.q, ctx->ctx); + BN_mod_sub(p->zkpx.b, r, t, ctx->p.q, ctx->ctx); + + /* cleanup */ + BN_free(t); + BN_free(h); + BN_free(r); +} + +static int verify_zkp(const JPAKE_STEP_PART *p, const BIGNUM *zkpg, + JPAKE_CTX *ctx) +{ + BIGNUM *h = BN_new(); + BIGNUM *t1 = BN_new(); + BIGNUM *t2 = BN_new(); + BIGNUM *t3 = BN_new(); + int ret = 0; + + if (h == NULL || t1 == NULL || t2 == NULL || t3 == NULL) + goto end; + + zkp_hash(h, zkpg, p, ctx->p.peer_name); + + /* t1 = g^b */ + BN_mod_exp(t1, zkpg, p->zkpx.b, ctx->p.p, ctx->ctx); + /* t2 = (g^x)^h = g^{hx} */ + BN_mod_exp(t2, p->gx, h, ctx->p.p, ctx->ctx); + /* t3 = t1 * t2 = g^{hx} * g^b = g^{hx+b} = g^r (allegedly) */ + BN_mod_mul(t3, t1, t2, ctx->p.p, ctx->ctx); + + /* verify t3 == g^r */ + if (BN_cmp(t3, p->zkpx.gr) == 0) + ret = 1; + else + JPAKEerr(JPAKE_F_VERIFY_ZKP, JPAKE_R_ZKP_VERIFY_FAILED); + +end: + /* cleanup */ + BN_free(t3); + BN_free(t2); + BN_free(t1); + BN_free(h); + + return ret; +} + +static void generate_step_part(JPAKE_STEP_PART *p, const BIGNUM *x, + const BIGNUM *g, JPAKE_CTX *ctx) +{ + BN_mod_exp(p->gx, g, x, ctx->p.p, ctx->ctx); + generate_zkp(p, x, g, ctx); +} + +/* Generate each party's random numbers. xa is in [0, q), xb is in [1, q). */ +static void genrand(JPAKE_CTX *ctx) +{ + BIGNUM *qm1; + + /* xa in [0, q) */ + BN_rand_range(ctx->xa, ctx->p.q); + + /* q-1 */ + qm1 = BN_new(); + BN_copy(qm1, ctx->p.q); + BN_sub_word(qm1, 1); + + /* ... and xb in [0, q-1) */ + BN_rand_range(ctx->xb, qm1); + /* [1, q) */ + BN_add_word(ctx->xb, 1); + + /* cleanup */ + BN_free(qm1); +} + +int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx) +{ + genrand(ctx); + generate_step_part(&send->p1, ctx->xa, ctx->p.g, ctx); + generate_step_part(&send->p2, ctx->xb, ctx->p.g, ctx); + + return 1; +} + +/* g^x is a legal value */ +static int is_legal(const BIGNUM *gx, const JPAKE_CTX *ctx) +{ + BIGNUM *t; + int res; + + if (BN_is_negative(gx) || BN_is_zero(gx) || BN_cmp(gx, ctx->p.p) >= 0) + return 0; + + t = BN_new(); + BN_mod_exp(t, gx, ctx->p.q, ctx->p.p, ctx->ctx); + res = BN_is_one(t); + BN_free(t); + + return res; +} + +int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received) +{ + if (!is_legal(received->p1.gx, ctx)) { + JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, + JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL); + return 0; + } + + if (!is_legal(received->p2.gx, ctx)) { + JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, + JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL); + return 0; + } + + /* verify their ZKP(xc) */ + if (!verify_zkp(&received->p1, ctx->p.g, ctx)) { + JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X3_FAILED); + return 0; + } + + /* verify their ZKP(xd) */ + if (!verify_zkp(&received->p2, ctx->p.g, ctx)) { + JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_VERIFY_X4_FAILED); + return 0; + } + + /* g^xd != 1 */ + if (BN_is_one(received->p2.gx)) { + JPAKEerr(JPAKE_F_JPAKE_STEP1_PROCESS, JPAKE_R_G_TO_THE_X4_IS_ONE); + return 0; + } + + /* Save the bits we need for later */ + BN_copy(ctx->p.gxc, received->p1.gx); + BN_copy(ctx->p.gxd, received->p2.gx); + + return 1; +} + +int JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx) +{ + BIGNUM *t1 = BN_new(); + BIGNUM *t2 = BN_new(); + + /*- + * X = g^{(xa + xc + xd) * xb * s} + * t1 = g^xa + */ + BN_mod_exp(t1, ctx->p.g, ctx->xa, ctx->p.p, ctx->ctx); + /* t2 = t1 * g^{xc} = g^{xa} * g^{xc} = g^{xa + xc} */ + BN_mod_mul(t2, t1, ctx->p.gxc, ctx->p.p, ctx->ctx); + /* t1 = t2 * g^{xd} = g^{xa + xc + xd} */ + BN_mod_mul(t1, t2, ctx->p.gxd, ctx->p.p, ctx->ctx); + /* t2 = xb * s */ + BN_mod_mul(t2, ctx->xb, ctx->secret, ctx->p.q, ctx->ctx); + + /*- + * ZKP(xb * s) + * XXX: this is kinda funky, because we're using + * + * g' = g^{xa + xc + xd} + * + * as the generator, which means X is g'^{xb * s} + * X = t1^{t2} = t1^{xb * s} = g^{(xa + xc + xd) * xb * s} + */ + generate_step_part(send, t2, t1, ctx); + + /* cleanup */ + BN_free(t1); + BN_free(t2); + + return 1; +} + +/* gx = g^{xc + xa + xb} * xd * s */ +static int compute_key(JPAKE_CTX *ctx, const BIGNUM *gx) +{ + BIGNUM *t1 = BN_new(); + BIGNUM *t2 = BN_new(); + BIGNUM *t3 = BN_new(); + + /*- + * K = (gx/g^{xb * xd * s})^{xb} + * = (g^{(xc + xa + xb) * xd * s - xb * xd *s})^{xb} + * = (g^{(xa + xc) * xd * s})^{xb} + * = g^{(xa + xc) * xb * xd * s} + * [which is the same regardless of who calculates it] + */ + + /* t1 = (g^{xd})^{xb} = g^{xb * xd} */ + BN_mod_exp(t1, ctx->p.gxd, ctx->xb, ctx->p.p, ctx->ctx); + /* t2 = -s = q-s */ + BN_sub(t2, ctx->p.q, ctx->secret); + /* t3 = t1^t2 = g^{-xb * xd * s} */ + BN_mod_exp(t3, t1, t2, ctx->p.p, ctx->ctx); + /* t1 = gx * t3 = X/g^{xb * xd * s} */ + BN_mod_mul(t1, gx, t3, ctx->p.p, ctx->ctx); + /* K = t1^{xb} */ + BN_mod_exp(ctx->key, t1, ctx->xb, ctx->p.p, ctx->ctx); + + /* cleanup */ + BN_free(t3); + BN_free(t2); + BN_free(t1); + + return 1; +} + +int JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received) +{ + BIGNUM *t1 = BN_new(); + BIGNUM *t2 = BN_new(); + int ret = 0; + + /*- + * g' = g^{xc + xa + xb} [from our POV] + * t1 = xa + xb + */ + BN_mod_add(t1, ctx->xa, ctx->xb, ctx->p.q, ctx->ctx); + /* t2 = g^{t1} = g^{xa+xb} */ + BN_mod_exp(t2, ctx->p.g, t1, ctx->p.p, ctx->ctx); + /* t1 = g^{xc} * t2 = g^{xc + xa + xb} */ + BN_mod_mul(t1, ctx->p.gxc, t2, ctx->p.p, ctx->ctx); + + if (verify_zkp(received, t1, ctx)) + ret = 1; + else + JPAKEerr(JPAKE_F_JPAKE_STEP2_PROCESS, JPAKE_R_VERIFY_B_FAILED); + + compute_key(ctx, received->gx); + + /* cleanup */ + BN_free(t2); + BN_free(t1); + + return ret; +} + +static void quickhashbn(unsigned char *md, const BIGNUM *bn) +{ + SHA_CTX sha; + + SHA1_Init(&sha); + hashbn(&sha, bn); + SHA1_Final(md, &sha); +} + +void JPAKE_STEP3A_init(JPAKE_STEP3A *s3a) +{ +} + +int JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx) +{ + quickhashbn(send->hhk, ctx->key); + SHA1(send->hhk, sizeof send->hhk, send->hhk); + + return 1; +} + +int JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received) +{ + unsigned char hhk[SHA_DIGEST_LENGTH]; + + quickhashbn(hhk, ctx->key); + SHA1(hhk, sizeof hhk, hhk); + if (memcmp(hhk, received->hhk, sizeof hhk)) { + JPAKEerr(JPAKE_F_JPAKE_STEP3A_PROCESS, + JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH); + return 0; + } + return 1; +} + +void JPAKE_STEP3A_release(JPAKE_STEP3A *s3a) +{ +} + +void JPAKE_STEP3B_init(JPAKE_STEP3B *s3b) +{ +} + +int JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx) +{ + quickhashbn(send->hk, ctx->key); + + return 1; +} + +int JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received) +{ + unsigned char hk[SHA_DIGEST_LENGTH]; + + quickhashbn(hk, ctx->key); + if (memcmp(hk, received->hk, sizeof hk)) { + JPAKEerr(JPAKE_F_JPAKE_STEP3B_PROCESS, JPAKE_R_HASH_OF_KEY_MISMATCH); + return 0; + } + return 1; +} + +void JPAKE_STEP3B_release(JPAKE_STEP3B *s3b) +{ +} + +const BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx) +{ + return ctx->key; +} diff --git a/libs/openssl/crypto/jpake/jpake.h b/libs/openssl/crypto/jpake/jpake.h new file mode 100644 index 00000000..371eed67 --- /dev/null +++ b/libs/openssl/crypto/jpake/jpake.h @@ -0,0 +1,128 @@ +/* + * Implement J-PAKE, as described in + * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf + * + * With hints from http://www.cl.cam.ac.uk/~fh240/software/JPAKE2.java. + */ + +#ifndef HEADER_JPAKE_H +# define HEADER_JPAKE_H + +# include + +# ifdef OPENSSL_NO_JPAKE +# error JPAKE is disabled. +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# include +# include + +typedef struct JPAKE_CTX JPAKE_CTX; + +/* Note that "g" in the ZKPs is not necessarily the J-PAKE g. */ +typedef struct { + BIGNUM *gr; /* g^r (r random) */ + BIGNUM *b; /* b = r - x*h, h=hash(g, g^r, g^x, name) */ +} JPAKE_ZKP; + +typedef struct { + BIGNUM *gx; /* g^x in step 1, g^(xa + xc + xd) * xb * s + * in step 2 */ + JPAKE_ZKP zkpx; /* ZKP(x) or ZKP(xb * s) */ +} JPAKE_STEP_PART; + +typedef struct { + JPAKE_STEP_PART p1; /* g^x3, ZKP(x3) or g^x1, ZKP(x1) */ + JPAKE_STEP_PART p2; /* g^x4, ZKP(x4) or g^x2, ZKP(x2) */ +} JPAKE_STEP1; + +typedef JPAKE_STEP_PART JPAKE_STEP2; + +typedef struct { + unsigned char hhk[SHA_DIGEST_LENGTH]; +} JPAKE_STEP3A; + +typedef struct { + unsigned char hk[SHA_DIGEST_LENGTH]; +} JPAKE_STEP3B; + +/* Parameters are copied */ +JPAKE_CTX *JPAKE_CTX_new(const char *name, const char *peer_name, + const BIGNUM *p, const BIGNUM *g, const BIGNUM *q, + const BIGNUM *secret); +void JPAKE_CTX_free(JPAKE_CTX *ctx); + +/* + * Note that JPAKE_STEP1 can be used multiple times before release + * without another init. + */ +void JPAKE_STEP1_init(JPAKE_STEP1 *s1); +int JPAKE_STEP1_generate(JPAKE_STEP1 *send, JPAKE_CTX *ctx); +int JPAKE_STEP1_process(JPAKE_CTX *ctx, const JPAKE_STEP1 *received); +void JPAKE_STEP1_release(JPAKE_STEP1 *s1); + +/* + * Note that JPAKE_STEP2 can be used multiple times before release + * without another init. + */ +void JPAKE_STEP2_init(JPAKE_STEP2 *s2); +int JPAKE_STEP2_generate(JPAKE_STEP2 *send, JPAKE_CTX *ctx); +int JPAKE_STEP2_process(JPAKE_CTX *ctx, const JPAKE_STEP2 *received); +void JPAKE_STEP2_release(JPAKE_STEP2 *s2); + +/* + * Optionally verify the shared key. If the shared secrets do not + * match, the two ends will disagree about the shared key, but + * otherwise the protocol will succeed. + */ +void JPAKE_STEP3A_init(JPAKE_STEP3A *s3a); +int JPAKE_STEP3A_generate(JPAKE_STEP3A *send, JPAKE_CTX *ctx); +int JPAKE_STEP3A_process(JPAKE_CTX *ctx, const JPAKE_STEP3A *received); +void JPAKE_STEP3A_release(JPAKE_STEP3A *s3a); + +void JPAKE_STEP3B_init(JPAKE_STEP3B *s3b); +int JPAKE_STEP3B_generate(JPAKE_STEP3B *send, JPAKE_CTX *ctx); +int JPAKE_STEP3B_process(JPAKE_CTX *ctx, const JPAKE_STEP3B *received); +void JPAKE_STEP3B_release(JPAKE_STEP3B *s3b); + +/* + * the return value belongs to the library and will be released when + * ctx is released, and will change when a new handshake is performed. + */ +const BIGNUM *JPAKE_get_shared_key(JPAKE_CTX *ctx); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_JPAKE_strings(void); + +/* Error codes for the JPAKE functions. */ + +/* Function codes. */ +# define JPAKE_F_JPAKE_STEP1_PROCESS 101 +# define JPAKE_F_JPAKE_STEP2_PROCESS 102 +# define JPAKE_F_JPAKE_STEP3A_PROCESS 103 +# define JPAKE_F_JPAKE_STEP3B_PROCESS 104 +# define JPAKE_F_VERIFY_ZKP 100 + +/* Reason codes. */ +# define JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL 108 +# define JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL 109 +# define JPAKE_R_G_TO_THE_X4_IS_ONE 105 +# define JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH 106 +# define JPAKE_R_HASH_OF_KEY_MISMATCH 107 +# define JPAKE_R_VERIFY_B_FAILED 102 +# define JPAKE_R_VERIFY_X3_FAILED 103 +# define JPAKE_R_VERIFY_X4_FAILED 104 +# define JPAKE_R_ZKP_VERIFY_FAILED 100 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/jpake/jpake_err.c b/libs/openssl/crypto/jpake/jpake_err.c new file mode 100644 index 00000000..be236d9e --- /dev/null +++ b/libs/openssl/crypto/jpake/jpake_err.c @@ -0,0 +1,108 @@ +/* crypto/jpake/jpake_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_JPAKE,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_JPAKE,0,reason) + +static ERR_STRING_DATA JPAKE_str_functs[] = { + {ERR_FUNC(JPAKE_F_JPAKE_STEP1_PROCESS), "JPAKE_STEP1_process"}, + {ERR_FUNC(JPAKE_F_JPAKE_STEP2_PROCESS), "JPAKE_STEP2_process"}, + {ERR_FUNC(JPAKE_F_JPAKE_STEP3A_PROCESS), "JPAKE_STEP3A_process"}, + {ERR_FUNC(JPAKE_F_JPAKE_STEP3B_PROCESS), "JPAKE_STEP3B_process"}, + {ERR_FUNC(JPAKE_F_VERIFY_ZKP), "VERIFY_ZKP"}, + {0, NULL} +}; + +static ERR_STRING_DATA JPAKE_str_reasons[] = { + {ERR_REASON(JPAKE_R_G_TO_THE_X3_IS_NOT_LEGAL), + "g to the x3 is not legal"}, + {ERR_REASON(JPAKE_R_G_TO_THE_X4_IS_NOT_LEGAL), + "g to the x4 is not legal"}, + {ERR_REASON(JPAKE_R_G_TO_THE_X4_IS_ONE), "g to the x4 is one"}, + {ERR_REASON(JPAKE_R_HASH_OF_HASH_OF_KEY_MISMATCH), + "hash of hash of key mismatch"}, + {ERR_REASON(JPAKE_R_HASH_OF_KEY_MISMATCH), "hash of key mismatch"}, + {ERR_REASON(JPAKE_R_VERIFY_B_FAILED), "verify b failed"}, + {ERR_REASON(JPAKE_R_VERIFY_X3_FAILED), "verify x3 failed"}, + {ERR_REASON(JPAKE_R_VERIFY_X4_FAILED), "verify x4 failed"}, + {ERR_REASON(JPAKE_R_ZKP_VERIFY_FAILED), "zkp verify failed"}, + {0, NULL} +}; + +#endif + +void ERR_load_JPAKE_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(JPAKE_str_functs[0].error) == NULL) { + ERR_load_strings(0, JPAKE_str_functs); + ERR_load_strings(0, JPAKE_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/jpake/jpaketest.c b/libs/openssl/crypto/jpake/jpaketest.c new file mode 100644 index 00000000..ef9e54bd --- /dev/null +++ b/libs/openssl/crypto/jpake/jpaketest.c @@ -0,0 +1,185 @@ +#include + +#ifdef OPENSSL_NO_JPAKE + +# include + +int main(int argc, char *argv[]) +{ + printf("No J-PAKE support\n"); + return (0); +} + +#else + +# include +# include + +static void showbn(const char *name, const BIGNUM *bn) +{ + fputs(name, stdout); + fputs(" = ", stdout); + BN_print_fp(stdout, bn); + putc('\n', stdout); +} + +static int run_jpake(JPAKE_CTX *alice, JPAKE_CTX *bob) +{ + JPAKE_STEP1 alice_s1; + JPAKE_STEP1 bob_s1; + JPAKE_STEP2 alice_s2; + JPAKE_STEP2 bob_s2; + JPAKE_STEP3A alice_s3a; + JPAKE_STEP3B bob_s3b; + + /* Alice -> Bob: step 1 */ + puts("A->B s1"); + JPAKE_STEP1_init(&alice_s1); + JPAKE_STEP1_generate(&alice_s1, alice); + if (!JPAKE_STEP1_process(bob, &alice_s1)) { + printf("Bob fails to process Alice's step 1\n"); + ERR_print_errors_fp(stdout); + return 1; + } + JPAKE_STEP1_release(&alice_s1); + + /* Bob -> Alice: step 1 */ + puts("B->A s1"); + JPAKE_STEP1_init(&bob_s1); + JPAKE_STEP1_generate(&bob_s1, bob); + if (!JPAKE_STEP1_process(alice, &bob_s1)) { + printf("Alice fails to process Bob's step 1\n"); + ERR_print_errors_fp(stdout); + return 2; + } + JPAKE_STEP1_release(&bob_s1); + + /* Alice -> Bob: step 2 */ + puts("A->B s2"); + JPAKE_STEP2_init(&alice_s2); + JPAKE_STEP2_generate(&alice_s2, alice); + if (!JPAKE_STEP2_process(bob, &alice_s2)) { + printf("Bob fails to process Alice's step 2\n"); + ERR_print_errors_fp(stdout); + return 3; + } + JPAKE_STEP2_release(&alice_s2); + + /* Bob -> Alice: step 2 */ + puts("B->A s2"); + JPAKE_STEP2_init(&bob_s2); + JPAKE_STEP2_generate(&bob_s2, bob); + if (!JPAKE_STEP2_process(alice, &bob_s2)) { + printf("Alice fails to process Bob's step 2\n"); + ERR_print_errors_fp(stdout); + return 4; + } + JPAKE_STEP2_release(&bob_s2); + + showbn("Alice's key", JPAKE_get_shared_key(alice)); + showbn("Bob's key ", JPAKE_get_shared_key(bob)); + + /* Alice -> Bob: step 3a */ + puts("A->B s3a"); + JPAKE_STEP3A_init(&alice_s3a); + JPAKE_STEP3A_generate(&alice_s3a, alice); + if (!JPAKE_STEP3A_process(bob, &alice_s3a)) { + printf("Bob fails to process Alice's step 3a\n"); + ERR_print_errors_fp(stdout); + return 5; + } + JPAKE_STEP3A_release(&alice_s3a); + + /* Bob -> Alice: step 3b */ + puts("B->A s3b"); + JPAKE_STEP3B_init(&bob_s3b); + JPAKE_STEP3B_generate(&bob_s3b, bob); + if (!JPAKE_STEP3B_process(alice, &bob_s3b)) { + printf("Alice fails to process Bob's step 3b\n"); + ERR_print_errors_fp(stdout); + return 6; + } + JPAKE_STEP3B_release(&bob_s3b); + + return 0; +} + +int main(int argc, char **argv) +{ + JPAKE_CTX *alice; + JPAKE_CTX *bob; + BIGNUM *p = NULL; + BIGNUM *g = NULL; + BIGNUM *q = NULL; + BIGNUM *secret = BN_new(); + BIO *bio_err; + + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + + CRYPTO_malloc_debug_init(); + CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + + ERR_load_crypto_strings(); + + /*- + BN_hex2bn(&p, "fd7f53811d75122952df4a9c2eece4e7f611b7523cef4400c31e3f80b6512669455d402251fb593d8d58fabfc5f5ba30f6cb9b556cd7813b801d346ff26660b76b9950a5a49f9fe8047b1022c24fbba9d7feb7c61bf83b57e7c6a8a6150f04fb83f6d3c51ec3023554135a169132f675f3ae2b61d72aeff22203199dd14801c7"); + BN_hex2bn(&g, "f7e1a085d69b3ddecbbcab5c36b857b97994afbbfa3aea82f9574c0b3d0782675159578ebad4594fe67107108180b449167123e84c281613b7cf09328cc8a6e13c167a8b547c8d28e0a3ae1e2bb3a675916ea37f0bfa213562f1fb627a01243bcca4f1bea8519089a883dfe15ae59f06928b665e807b552564014c3bfecf492a"); + BN_hex2bn(&q, "9760508f15230bccb292b982a2eb840bf0581cf5"); + */ + /*- + p = BN_new(); + BN_generate_prime(p, 1024, 1, NULL, NULL, NULL, NULL); + */ + /* Use a safe prime for p (that we found earlier) */ + BN_hex2bn(&p, + "F9E5B365665EA7A05A9C534502780FEE6F1AB5BD4F49947FD036DBD7E905269AF46EF28B0FC07487EE4F5D20FB3C0AF8E700F3A2FA3414970CBED44FEDFF80CE78D800F184BB82435D137AADA2C6C16523247930A63B85661D1FC817A51ACD96168E95898A1F83A79FFB529368AA7833ABD1B0C3AEDDB14D2E1A2F71D99F763F"); + showbn("p", p); + g = BN_new(); + BN_set_word(g, 2); + showbn("g", g); + q = BN_new(); + BN_rshift1(q, p); + showbn("q", q); + + BN_rand(secret, 32, -1, 0); + + /* A normal run, expect this to work... */ + alice = JPAKE_CTX_new("Alice", "Bob", p, g, q, secret); + bob = JPAKE_CTX_new("Bob", "Alice", p, g, q, secret); + + if (run_jpake(alice, bob) != 0) { + fprintf(stderr, "Plain JPAKE run failed\n"); + return 1; + } + + JPAKE_CTX_free(bob); + JPAKE_CTX_free(alice); + + /* Now give Alice and Bob different secrets */ + alice = JPAKE_CTX_new("Alice", "Bob", p, g, q, secret); + BN_add_word(secret, 1); + bob = JPAKE_CTX_new("Bob", "Alice", p, g, q, secret); + + if (run_jpake(alice, bob) != 5) { + fprintf(stderr, "Mismatched secret JPAKE run failed\n"); + return 1; + } + + JPAKE_CTX_free(bob); + JPAKE_CTX_free(alice); + + BN_free(secret); + BN_free(q); + BN_free(g); + BN_free(p); + + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + ERR_free_strings(); + CRYPTO_mem_leaks(bio_err); + + return 0; +} + +#endif diff --git a/libs/openssl/crypto/krb5/krb5_asn.c b/libs/openssl/crypto/krb5/krb5_asn.c new file mode 100644 index 00000000..d9851e97 --- /dev/null +++ b/libs/openssl/crypto/krb5/krb5_asn.c @@ -0,0 +1,162 @@ +/* krb5_asn.c */ +/* + * Written by Vern Staats for the OpenSSL project, ** + * using ocsp/{*.h,*asn*.c} as a starting point + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include +#include +#include + + +ASN1_SEQUENCE(KRB5_ENCDATA) = { + ASN1_EXP(KRB5_ENCDATA, etype, ASN1_INTEGER, 0), + ASN1_EXP_OPT(KRB5_ENCDATA, kvno, ASN1_INTEGER, 1), + ASN1_EXP(KRB5_ENCDATA, cipher, ASN1_OCTET_STRING,2) +} ASN1_SEQUENCE_END(KRB5_ENCDATA) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCDATA) + + +ASN1_SEQUENCE(KRB5_PRINCNAME) = { + ASN1_EXP(KRB5_PRINCNAME, nametype, ASN1_INTEGER, 0), + ASN1_EXP_SEQUENCE_OF(KRB5_PRINCNAME, namestring, ASN1_GENERALSTRING, 1) +} ASN1_SEQUENCE_END(KRB5_PRINCNAME) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_PRINCNAME) + +/* [APPLICATION 1] = 0x61 */ +ASN1_SEQUENCE(KRB5_TKTBODY) = { + ASN1_EXP(KRB5_TKTBODY, tktvno, ASN1_INTEGER, 0), + ASN1_EXP(KRB5_TKTBODY, realm, ASN1_GENERALSTRING, 1), + ASN1_EXP(KRB5_TKTBODY, sname, KRB5_PRINCNAME, 2), + ASN1_EXP(KRB5_TKTBODY, encdata, KRB5_ENCDATA, 3) +} ASN1_SEQUENCE_END(KRB5_TKTBODY) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_TKTBODY) + + +ASN1_ITEM_TEMPLATE(KRB5_TICKET) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 1, + KRB5_TICKET, KRB5_TKTBODY) +ASN1_ITEM_TEMPLATE_END(KRB5_TICKET) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_TICKET) + +/* [APPLICATION 14] = 0x6e */ +ASN1_SEQUENCE(KRB5_APREQBODY) = { + ASN1_EXP(KRB5_APREQBODY, pvno, ASN1_INTEGER, 0), + ASN1_EXP(KRB5_APREQBODY, msgtype, ASN1_INTEGER, 1), + ASN1_EXP(KRB5_APREQBODY, apoptions, ASN1_BIT_STRING, 2), + ASN1_EXP(KRB5_APREQBODY, ticket, KRB5_TICKET, 3), + ASN1_EXP(KRB5_APREQBODY, authenticator, KRB5_ENCDATA, 4), +} ASN1_SEQUENCE_END(KRB5_APREQBODY) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQBODY) + +ASN1_ITEM_TEMPLATE(KRB5_APREQ) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 14, + KRB5_APREQ, KRB5_APREQBODY) +ASN1_ITEM_TEMPLATE_END(KRB5_APREQ) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_APREQ) + +/* Authenticator stuff */ + +ASN1_SEQUENCE(KRB5_CHECKSUM) = { + ASN1_EXP(KRB5_CHECKSUM, ctype, ASN1_INTEGER, 0), + ASN1_EXP(KRB5_CHECKSUM, checksum, ASN1_OCTET_STRING,1) +} ASN1_SEQUENCE_END(KRB5_CHECKSUM) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_CHECKSUM) + + +ASN1_SEQUENCE(KRB5_ENCKEY) = { + ASN1_EXP(KRB5_ENCKEY, ktype, ASN1_INTEGER, 0), + ASN1_EXP(KRB5_ENCKEY, keyvalue, ASN1_OCTET_STRING,1) +} ASN1_SEQUENCE_END(KRB5_ENCKEY) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_ENCKEY) + +/* SEQ OF SEQ; see ASN1_EXP_SEQUENCE_OF_OPT() below */ +ASN1_SEQUENCE(KRB5_AUTHDATA) = { + ASN1_EXP(KRB5_AUTHDATA, adtype, ASN1_INTEGER, 0), + ASN1_EXP(KRB5_AUTHDATA, addata, ASN1_OCTET_STRING,1) +} ASN1_SEQUENCE_END(KRB5_AUTHDATA) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHDATA) + +/* [APPLICATION 2] = 0x62 */ +ASN1_SEQUENCE(KRB5_AUTHENTBODY) = { + ASN1_EXP(KRB5_AUTHENTBODY, avno, ASN1_INTEGER, 0), + ASN1_EXP(KRB5_AUTHENTBODY, crealm, ASN1_GENERALSTRING, 1), + ASN1_EXP(KRB5_AUTHENTBODY, cname, KRB5_PRINCNAME, 2), + ASN1_EXP_OPT(KRB5_AUTHENTBODY, cksum, KRB5_CHECKSUM, 3), + ASN1_EXP(KRB5_AUTHENTBODY, cusec, ASN1_INTEGER, 4), + ASN1_EXP(KRB5_AUTHENTBODY, ctime, ASN1_GENERALIZEDTIME, 5), + ASN1_EXP_OPT(KRB5_AUTHENTBODY, subkey, KRB5_ENCKEY, 6), + ASN1_EXP_OPT(KRB5_AUTHENTBODY, seqnum, ASN1_INTEGER, 7), + ASN1_EXP_SEQUENCE_OF_OPT + (KRB5_AUTHENTBODY, authorization, KRB5_AUTHDATA, 8), +} ASN1_SEQUENCE_END(KRB5_AUTHENTBODY) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENTBODY) + +ASN1_ITEM_TEMPLATE(KRB5_AUTHENT) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_EXPTAG|ASN1_TFLG_APPLICATION, 2, + KRB5_AUTHENT, KRB5_AUTHENTBODY) +ASN1_ITEM_TEMPLATE_END(KRB5_AUTHENT) + +IMPLEMENT_ASN1_FUNCTIONS(KRB5_AUTHENT) diff --git a/libs/openssl/crypto/krb5/krb5_asn.h b/libs/openssl/crypto/krb5/krb5_asn.h new file mode 100644 index 00000000..9cf5a26d --- /dev/null +++ b/libs/openssl/crypto/krb5/krb5_asn.h @@ -0,0 +1,240 @@ +/* krb5_asn.h */ +/* + * Written by Vern Staats for the OpenSSL project, ** + * using ocsp/{*.h,*asn*.c} as a starting point + */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_KRB5_ASN_H +# define HEADER_KRB5_ASN_H + +/* + * #include + */ +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * ASN.1 from Kerberos RFC 1510 + */ + +/*- EncryptedData ::= SEQUENCE { + * etype[0] INTEGER, -- EncryptionType + * kvno[1] INTEGER OPTIONAL, + * cipher[2] OCTET STRING -- ciphertext + * } + */ +typedef struct krb5_encdata_st { + ASN1_INTEGER *etype; + ASN1_INTEGER *kvno; + ASN1_OCTET_STRING *cipher; +} KRB5_ENCDATA; + +DECLARE_STACK_OF(KRB5_ENCDATA) + +/*- PrincipalName ::= SEQUENCE { + * name-type[0] INTEGER, + * name-string[1] SEQUENCE OF GeneralString + * } + */ +typedef struct krb5_princname_st { + ASN1_INTEGER *nametype; + STACK_OF(ASN1_GENERALSTRING) *namestring; +} KRB5_PRINCNAME; + +DECLARE_STACK_OF(KRB5_PRINCNAME) + +/*- Ticket ::= [APPLICATION 1] SEQUENCE { + * tkt-vno[0] INTEGER, + * realm[1] Realm, + * sname[2] PrincipalName, + * enc-part[3] EncryptedData + * } + */ +typedef struct krb5_tktbody_st { + ASN1_INTEGER *tktvno; + ASN1_GENERALSTRING *realm; + KRB5_PRINCNAME *sname; + KRB5_ENCDATA *encdata; +} KRB5_TKTBODY; + +typedef STACK_OF(KRB5_TKTBODY) KRB5_TICKET; +DECLARE_STACK_OF(KRB5_TKTBODY) + +/*- AP-REQ ::= [APPLICATION 14] SEQUENCE { + * pvno[0] INTEGER, + * msg-type[1] INTEGER, + * ap-options[2] APOptions, + * ticket[3] Ticket, + * authenticator[4] EncryptedData + * } + * + * APOptions ::= BIT STRING { + * reserved(0), use-session-key(1), mutual-required(2) } + */ +typedef struct krb5_ap_req_st { + ASN1_INTEGER *pvno; + ASN1_INTEGER *msgtype; + ASN1_BIT_STRING *apoptions; + KRB5_TICKET *ticket; + KRB5_ENCDATA *authenticator; +} KRB5_APREQBODY; + +typedef STACK_OF(KRB5_APREQBODY) KRB5_APREQ; +DECLARE_STACK_OF(KRB5_APREQBODY) + +/* Authenticator Stuff */ + +/*- Checksum ::= SEQUENCE { + * cksumtype[0] INTEGER, + * checksum[1] OCTET STRING + * } + */ +typedef struct krb5_checksum_st { + ASN1_INTEGER *ctype; + ASN1_OCTET_STRING *checksum; +} KRB5_CHECKSUM; + +DECLARE_STACK_OF(KRB5_CHECKSUM) + +/*- EncryptionKey ::= SEQUENCE { + * keytype[0] INTEGER, + * keyvalue[1] OCTET STRING + * } + */ +typedef struct krb5_encryptionkey_st { + ASN1_INTEGER *ktype; + ASN1_OCTET_STRING *keyvalue; +} KRB5_ENCKEY; + +DECLARE_STACK_OF(KRB5_ENCKEY) + +/*- AuthorizationData ::= SEQUENCE OF SEQUENCE { + * ad-type[0] INTEGER, + * ad-data[1] OCTET STRING + * } + */ +typedef struct krb5_authorization_st { + ASN1_INTEGER *adtype; + ASN1_OCTET_STRING *addata; +} KRB5_AUTHDATA; + +DECLARE_STACK_OF(KRB5_AUTHDATA) + +/*- -- Unencrypted authenticator + * Authenticator ::= [APPLICATION 2] SEQUENCE { + * authenticator-vno[0] INTEGER, + * crealm[1] Realm, + * cname[2] PrincipalName, + * cksum[3] Checksum OPTIONAL, + * cusec[4] INTEGER, + * ctime[5] KerberosTime, + * subkey[6] EncryptionKey OPTIONAL, + * seq-number[7] INTEGER OPTIONAL, + * authorization-data[8] AuthorizationData OPTIONAL + * } + */ +typedef struct krb5_authenticator_st { + ASN1_INTEGER *avno; + ASN1_GENERALSTRING *crealm; + KRB5_PRINCNAME *cname; + KRB5_CHECKSUM *cksum; + ASN1_INTEGER *cusec; + ASN1_GENERALIZEDTIME *ctime; + KRB5_ENCKEY *subkey; + ASN1_INTEGER *seqnum; + KRB5_AUTHDATA *authorization; +} KRB5_AUTHENTBODY; + +typedef STACK_OF(KRB5_AUTHENTBODY) KRB5_AUTHENT; +DECLARE_STACK_OF(KRB5_AUTHENTBODY) + +/*- DECLARE_ASN1_FUNCTIONS(type) = DECLARE_ASN1_FUNCTIONS_name(type, type) = + * type *name##_new(void); + * void name##_free(type *a); + * DECLARE_ASN1_ENCODE_FUNCTIONS(type, name, name) = + * DECLARE_ASN1_ENCODE_FUNCTIONS(type, itname, name) = + * type *d2i_##name(type **a, const unsigned char **in, long len); + * int i2d_##name(type *a, unsigned char **out); + * DECLARE_ASN1_ITEM(itname) = OPENSSL_EXTERN const ASN1_ITEM itname##_it + */ + +DECLARE_ASN1_FUNCTIONS(KRB5_ENCDATA) +DECLARE_ASN1_FUNCTIONS(KRB5_PRINCNAME) +DECLARE_ASN1_FUNCTIONS(KRB5_TKTBODY) +DECLARE_ASN1_FUNCTIONS(KRB5_APREQBODY) +DECLARE_ASN1_FUNCTIONS(KRB5_TICKET) +DECLARE_ASN1_FUNCTIONS(KRB5_APREQ) + +DECLARE_ASN1_FUNCTIONS(KRB5_CHECKSUM) +DECLARE_ASN1_FUNCTIONS(KRB5_ENCKEY) +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHDATA) +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENTBODY) +DECLARE_ASN1_FUNCTIONS(KRB5_AUTHENT) + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/lhash/lh_stats.c b/libs/openssl/crypto/lhash/lh_stats.c new file mode 100644 index 00000000..0bfec232 --- /dev/null +++ b/libs/openssl/crypto/lhash/lh_stats.c @@ -0,0 +1,246 @@ +/* crypto/lhash/lh_stats.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +/* + * If you wish to build this outside of SSLeay, remove the following lines + * and things should work as expected + */ +#include "cryptlib.h" + +#ifndef OPENSSL_NO_BIO +# include +#endif +#include + +#ifdef OPENSSL_NO_BIO + +void lh_stats(LHASH *lh, FILE *out) +{ + fprintf(out, "num_items = %lu\n", lh->num_items); + fprintf(out, "num_nodes = %u\n", lh->num_nodes); + fprintf(out, "num_alloc_nodes = %u\n", lh->num_alloc_nodes); + fprintf(out, "num_expands = %lu\n", lh->num_expands); + fprintf(out, "num_expand_reallocs = %lu\n", lh->num_expand_reallocs); + fprintf(out, "num_contracts = %lu\n", lh->num_contracts); + fprintf(out, "num_contract_reallocs = %lu\n", lh->num_contract_reallocs); + fprintf(out, "num_hash_calls = %lu\n", lh->num_hash_calls); + fprintf(out, "num_comp_calls = %lu\n", lh->num_comp_calls); + fprintf(out, "num_insert = %lu\n", lh->num_insert); + fprintf(out, "num_replace = %lu\n", lh->num_replace); + fprintf(out, "num_delete = %lu\n", lh->num_delete); + fprintf(out, "num_no_delete = %lu\n", lh->num_no_delete); + fprintf(out, "num_retrieve = %lu\n", lh->num_retrieve); + fprintf(out, "num_retrieve_miss = %lu\n", lh->num_retrieve_miss); + fprintf(out, "num_hash_comps = %lu\n", lh->num_hash_comps); +# if 0 + fprintf(out, "p = %u\n", lh->p); + fprintf(out, "pmax = %u\n", lh->pmax); + fprintf(out, "up_load = %lu\n", lh->up_load); + fprintf(out, "down_load = %lu\n", lh->down_load); +# endif +} + +void lh_node_stats(LHASH *lh, FILE *out) +{ + LHASH_NODE *n; + unsigned int i, num; + + for (i = 0; i < lh->num_nodes; i++) { + for (n = lh->b[i], num = 0; n != NULL; n = n->next) + num++; + fprintf(out, "node %6u -> %3u\n", i, num); + } +} + +void lh_node_usage_stats(LHASH *lh, FILE *out) +{ + LHASH_NODE *n; + unsigned long num; + unsigned int i; + unsigned long total = 0, n_used = 0; + + for (i = 0; i < lh->num_nodes; i++) { + for (n = lh->b[i], num = 0; n != NULL; n = n->next) + num++; + if (num != 0) { + n_used++; + total += num; + } + } + fprintf(out, "%lu nodes used out of %u\n", n_used, lh->num_nodes); + fprintf(out, "%lu items\n", total); + if (n_used == 0) + return; + fprintf(out, "load %d.%02d actual load %d.%02d\n", + (int)(total / lh->num_nodes), + (int)((total % lh->num_nodes) * 100 / lh->num_nodes), + (int)(total / n_used), (int)((total % n_used) * 100 / n_used)); +} + +#else + +# ifndef OPENSSL_NO_FP_API +void lh_stats(const _LHASH *lh, FILE *fp) +{ + BIO *bp; + + bp = BIO_new(BIO_s_file()); + if (bp == NULL) + goto end; + BIO_set_fp(bp, fp, BIO_NOCLOSE); + lh_stats_bio(lh, bp); + BIO_free(bp); + end:; +} + +void lh_node_stats(const _LHASH *lh, FILE *fp) +{ + BIO *bp; + + bp = BIO_new(BIO_s_file()); + if (bp == NULL) + goto end; + BIO_set_fp(bp, fp, BIO_NOCLOSE); + lh_node_stats_bio(lh, bp); + BIO_free(bp); + end:; +} + +void lh_node_usage_stats(const _LHASH *lh, FILE *fp) +{ + BIO *bp; + + bp = BIO_new(BIO_s_file()); + if (bp == NULL) + goto end; + BIO_set_fp(bp, fp, BIO_NOCLOSE); + lh_node_usage_stats_bio(lh, bp); + BIO_free(bp); + end:; +} + +# endif + +void lh_stats_bio(const _LHASH *lh, BIO *out) +{ + BIO_printf(out, "num_items = %lu\n", lh->num_items); + BIO_printf(out, "num_nodes = %u\n", lh->num_nodes); + BIO_printf(out, "num_alloc_nodes = %u\n", lh->num_alloc_nodes); + BIO_printf(out, "num_expands = %lu\n", lh->num_expands); + BIO_printf(out, "num_expand_reallocs = %lu\n", lh->num_expand_reallocs); + BIO_printf(out, "num_contracts = %lu\n", lh->num_contracts); + BIO_printf(out, "num_contract_reallocs = %lu\n", + lh->num_contract_reallocs); + BIO_printf(out, "num_hash_calls = %lu\n", lh->num_hash_calls); + BIO_printf(out, "num_comp_calls = %lu\n", lh->num_comp_calls); + BIO_printf(out, "num_insert = %lu\n", lh->num_insert); + BIO_printf(out, "num_replace = %lu\n", lh->num_replace); + BIO_printf(out, "num_delete = %lu\n", lh->num_delete); + BIO_printf(out, "num_no_delete = %lu\n", lh->num_no_delete); + BIO_printf(out, "num_retrieve = %lu\n", lh->num_retrieve); + BIO_printf(out, "num_retrieve_miss = %lu\n", lh->num_retrieve_miss); + BIO_printf(out, "num_hash_comps = %lu\n", lh->num_hash_comps); +# if 0 + BIO_printf(out, "p = %u\n", lh->p); + BIO_printf(out, "pmax = %u\n", lh->pmax); + BIO_printf(out, "up_load = %lu\n", lh->up_load); + BIO_printf(out, "down_load = %lu\n", lh->down_load); +# endif +} + +void lh_node_stats_bio(const _LHASH *lh, BIO *out) +{ + LHASH_NODE *n; + unsigned int i, num; + + for (i = 0; i < lh->num_nodes; i++) { + for (n = lh->b[i], num = 0; n != NULL; n = n->next) + num++; + BIO_printf(out, "node %6u -> %3u\n", i, num); + } +} + +void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out) +{ + LHASH_NODE *n; + unsigned long num; + unsigned int i; + unsigned long total = 0, n_used = 0; + + for (i = 0; i < lh->num_nodes; i++) { + for (n = lh->b[i], num = 0; n != NULL; n = n->next) + num++; + if (num != 0) { + n_used++; + total += num; + } + } + BIO_printf(out, "%lu nodes used out of %u\n", n_used, lh->num_nodes); + BIO_printf(out, "%lu items\n", total); + if (n_used == 0) + return; + BIO_printf(out, "load %d.%02d actual load %d.%02d\n", + (int)(total / lh->num_nodes), + (int)((total % lh->num_nodes) * 100 / lh->num_nodes), + (int)(total / n_used), (int)((total % n_used) * 100 / n_used)); +} + +#endif diff --git a/libs/openssl/crypto/lhash/lh_test.c b/libs/openssl/crypto/lhash/lh_test.c new file mode 100644 index 00000000..d9db83f7 --- /dev/null +++ b/libs/openssl/crypto/lhash/lh_test.c @@ -0,0 +1,88 @@ +/* crypto/lhash/lh_test.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +main() +{ + LHASH *conf; + char buf[256]; + int i; + + conf = lh_new(lh_strhash, strcmp); + for (;;) { + char *p; + + buf[0] = '\0'; + fgets(buf, 256, stdin); + if (buf[0] == '\0') + break; + i = strlen(buf); + p = OPENSSL_malloc(i + 1); + memcpy(p, buf, i + 1); + lh_insert(conf, p); + } + + lh_node_stats(conf, stdout); + lh_stats(conf, stdout); + lh_node_usage_stats(conf, stdout); + exit(0); +} diff --git a/libs/openssl/crypto/lhash/lhash.c b/libs/openssl/crypto/lhash/lhash.c new file mode 100644 index 00000000..53c5c138 --- /dev/null +++ b/libs/openssl/crypto/lhash/lhash.c @@ -0,0 +1,458 @@ +/* crypto/lhash/lhash.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/*- + * Code for dynamic hash table routines + * Author - Eric Young v 2.0 + * + * 2.2 eay - added #include "crypto.h" so the memory leak checking code is + * present. eay 18-Jun-98 + * + * 2.1 eay - Added an 'error in last operation' flag. eay 6-May-98 + * + * 2.0 eay - Fixed a bug that occurred when using lh_delete + * from inside lh_doall(). As entries were deleted, + * the 'table' was 'contract()ed', making some entries + * jump from the end of the table to the start, there by + * skipping the lh_doall() processing. eay - 4/12/95 + * + * 1.9 eay - Fixed a memory leak in lh_free, the LHASH_NODEs + * were not being free()ed. 21/11/95 + * + * 1.8 eay - Put the stats routines into a separate file, lh_stats.c + * 19/09/95 + * + * 1.7 eay - Removed the fputs() for realloc failures - the code + * should silently tolerate them. I have also fixed things + * lint complained about 04/05/95 + * + * 1.6 eay - Fixed an invalid pointers in contract/expand 27/07/92 + * + * 1.5 eay - Fixed a misuse of realloc in expand 02/03/1992 + * + * 1.4 eay - Fixed lh_doall so the function can call lh_delete 28/05/91 + * + * 1.3 eay - Fixed a few lint problems 19/3/1991 + * + * 1.2 eay - Fixed lh_doall problem 13/3/1991 + * + * 1.1 eay - Added lh_doall + * + * 1.0 eay - First version + */ +#include +#include +#include +#include +#include + +const char lh_version[] = "lhash" OPENSSL_VERSION_PTEXT; + +#undef MIN_NODES +#define MIN_NODES 16 +#define UP_LOAD (2*LH_LOAD_MULT) /* load times 256 (default 2) */ +#define DOWN_LOAD (LH_LOAD_MULT) /* load times 256 (default 1) */ + +static void expand(_LHASH *lh); +static void contract(_LHASH *lh); +static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash); + +_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c) +{ + _LHASH *ret; + int i; + + if ((ret = OPENSSL_malloc(sizeof(_LHASH))) == NULL) + goto err0; + if ((ret->b = OPENSSL_malloc(sizeof(LHASH_NODE *) * MIN_NODES)) == NULL) + goto err1; + for (i = 0; i < MIN_NODES; i++) + ret->b[i] = NULL; + ret->comp = ((c == NULL) ? (LHASH_COMP_FN_TYPE)strcmp : c); + ret->hash = ((h == NULL) ? (LHASH_HASH_FN_TYPE)lh_strhash : h); + ret->num_nodes = MIN_NODES / 2; + ret->num_alloc_nodes = MIN_NODES; + ret->p = 0; + ret->pmax = MIN_NODES / 2; + ret->up_load = UP_LOAD; + ret->down_load = DOWN_LOAD; + ret->num_items = 0; + + ret->num_expands = 0; + ret->num_expand_reallocs = 0; + ret->num_contracts = 0; + ret->num_contract_reallocs = 0; + ret->num_hash_calls = 0; + ret->num_comp_calls = 0; + ret->num_insert = 0; + ret->num_replace = 0; + ret->num_delete = 0; + ret->num_no_delete = 0; + ret->num_retrieve = 0; + ret->num_retrieve_miss = 0; + ret->num_hash_comps = 0; + + ret->error = 0; + return (ret); + err1: + OPENSSL_free(ret); + err0: + return (NULL); +} + +void lh_free(_LHASH *lh) +{ + unsigned int i; + LHASH_NODE *n, *nn; + + if (lh == NULL) + return; + + for (i = 0; i < lh->num_nodes; i++) { + n = lh->b[i]; + while (n != NULL) { + nn = n->next; + OPENSSL_free(n); + n = nn; + } + } + OPENSSL_free(lh->b); + OPENSSL_free(lh); +} + +void *lh_insert(_LHASH *lh, void *data) +{ + unsigned long hash; + LHASH_NODE *nn, **rn; + void *ret; + + lh->error = 0; + if (lh->up_load <= (lh->num_items * LH_LOAD_MULT / lh->num_nodes)) + expand(lh); + + rn = getrn(lh, data, &hash); + + if (*rn == NULL) { + if ((nn = (LHASH_NODE *)OPENSSL_malloc(sizeof(LHASH_NODE))) == NULL) { + lh->error++; + return (NULL); + } + nn->data = data; + nn->next = NULL; +#ifndef OPENSSL_NO_HASH_COMP + nn->hash = hash; +#endif + *rn = nn; + ret = NULL; + lh->num_insert++; + lh->num_items++; + } else { /* replace same key */ + + ret = (*rn)->data; + (*rn)->data = data; + lh->num_replace++; + } + return (ret); +} + +void *lh_delete(_LHASH *lh, const void *data) +{ + unsigned long hash; + LHASH_NODE *nn, **rn; + void *ret; + + lh->error = 0; + rn = getrn(lh, data, &hash); + + if (*rn == NULL) { + lh->num_no_delete++; + return (NULL); + } else { + nn = *rn; + *rn = nn->next; + ret = nn->data; + OPENSSL_free(nn); + lh->num_delete++; + } + + lh->num_items--; + if ((lh->num_nodes > MIN_NODES) && + (lh->down_load >= (lh->num_items * LH_LOAD_MULT / lh->num_nodes))) + contract(lh); + + return (ret); +} + +void *lh_retrieve(_LHASH *lh, const void *data) +{ + unsigned long hash; + LHASH_NODE **rn; + void *ret; + + lh->error = 0; + rn = getrn(lh, data, &hash); + + if (*rn == NULL) { + lh->num_retrieve_miss++; + return (NULL); + } else { + ret = (*rn)->data; + lh->num_retrieve++; + } + return (ret); +} + +static void doall_util_fn(_LHASH *lh, int use_arg, LHASH_DOALL_FN_TYPE func, + LHASH_DOALL_ARG_FN_TYPE func_arg, void *arg) +{ + int i; + LHASH_NODE *a, *n; + + if (lh == NULL) + return; + + /* + * reverse the order so we search from 'top to bottom' We were having + * memory leaks otherwise + */ + for (i = lh->num_nodes - 1; i >= 0; i--) { + a = lh->b[i]; + while (a != NULL) { + /* + * 28/05/91 - eay - n added so items can be deleted via lh_doall + */ + /* + * 22/05/08 - ben - eh? since a is not passed, this should not be + * needed + */ + n = a->next; + if (use_arg) + func_arg(a->data, arg); + else + func(a->data); + a = n; + } + } +} + +void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func) +{ + doall_util_fn(lh, 0, func, (LHASH_DOALL_ARG_FN_TYPE)0, NULL); +} + +void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg) +{ + doall_util_fn(lh, 1, (LHASH_DOALL_FN_TYPE)0, func, arg); +} + +static void expand(_LHASH *lh) +{ + LHASH_NODE **n, **n1, **n2, *np; + unsigned int p, i, j; + unsigned long hash, nni; + + lh->num_nodes++; + lh->num_expands++; + p = (int)lh->p++; + n1 = &(lh->b[p]); + n2 = &(lh->b[p + (int)lh->pmax]); + *n2 = NULL; /* 27/07/92 - eay - undefined pointer bug */ + nni = lh->num_alloc_nodes; + + for (np = *n1; np != NULL;) { +#ifndef OPENSSL_NO_HASH_COMP + hash = np->hash; +#else + hash = lh->hash(np->data); + lh->num_hash_calls++; +#endif + if ((hash % nni) != p) { /* move it */ + *n1 = (*n1)->next; + np->next = *n2; + *n2 = np; + } else + n1 = &((*n1)->next); + np = *n1; + } + + if ((lh->p) >= lh->pmax) { + j = (int)lh->num_alloc_nodes * 2; + n = (LHASH_NODE **)OPENSSL_realloc(lh->b, + (int)(sizeof(LHASH_NODE *) * j)); + if (n == NULL) { +/* fputs("realloc error in lhash",stderr); */ + lh->error++; + lh->p = 0; + return; + } + /* else */ + for (i = (int)lh->num_alloc_nodes; i < j; i++) /* 26/02/92 eay */ + n[i] = NULL; /* 02/03/92 eay */ + lh->pmax = lh->num_alloc_nodes; + lh->num_alloc_nodes = j; + lh->num_expand_reallocs++; + lh->p = 0; + lh->b = n; + } +} + +static void contract(_LHASH *lh) +{ + LHASH_NODE **n, *n1, *np; + + np = lh->b[lh->p + lh->pmax - 1]; + lh->b[lh->p + lh->pmax - 1] = NULL; /* 24/07-92 - eay - weird but :-( */ + if (lh->p == 0) { + n = (LHASH_NODE **)OPENSSL_realloc(lh->b, + (unsigned int)(sizeof(LHASH_NODE *) + * lh->pmax)); + if (n == NULL) { +/* fputs("realloc error in lhash",stderr); */ + lh->error++; + return; + } + lh->num_contract_reallocs++; + lh->num_alloc_nodes /= 2; + lh->pmax /= 2; + lh->p = lh->pmax - 1; + lh->b = n; + } else + lh->p--; + + lh->num_nodes--; + lh->num_contracts++; + + n1 = lh->b[(int)lh->p]; + if (n1 == NULL) + lh->b[(int)lh->p] = np; + else { + while (n1->next != NULL) + n1 = n1->next; + n1->next = np; + } +} + +static LHASH_NODE **getrn(_LHASH *lh, const void *data, unsigned long *rhash) +{ + LHASH_NODE **ret, *n1; + unsigned long hash, nn; + LHASH_COMP_FN_TYPE cf; + + hash = (*(lh->hash)) (data); + lh->num_hash_calls++; + *rhash = hash; + + nn = hash % lh->pmax; + if (nn < lh->p) + nn = hash % lh->num_alloc_nodes; + + cf = lh->comp; + ret = &(lh->b[(int)nn]); + for (n1 = *ret; n1 != NULL; n1 = n1->next) { +#ifndef OPENSSL_NO_HASH_COMP + lh->num_hash_comps++; + if (n1->hash != hash) { + ret = &(n1->next); + continue; + } +#endif + lh->num_comp_calls++; + if (cf(n1->data, data) == 0) + break; + ret = &(n1->next); + } + return (ret); +} + +/* + * The following hash seems to work very well on normal text strings no + * collisions on /usr/dict/words and it distributes on %2^n quite well, not + * as good as MD5, but still good. + */ +unsigned long lh_strhash(const char *c) +{ + unsigned long ret = 0; + long n; + unsigned long v; + int r; + + if ((c == NULL) || (*c == '\0')) + return (ret); +/*- + unsigned char b[16]; + MD5(c,strlen(c),b); + return(b[0]|(b[1]<<8)|(b[2]<<16)|(b[3]<<24)); +*/ + + n = 0x100; + while (*c) { + v = n | (*c); + n += 0x100; + r = (int)((v >> 2) ^ v) & 0x0f; + ret = (ret << r) | (ret >> (32 - r)); + ret &= 0xFFFFFFFFL; + ret ^= v * v; + c++; + } + return ((ret >> 16) ^ ret); +} + +unsigned long lh_num_items(const _LHASH *lh) +{ + return lh ? lh->num_items : 0; +} diff --git a/libs/openssl/crypto/lhash/lhash.h b/libs/openssl/crypto/lhash/lhash.h new file mode 100644 index 00000000..b6c328bf --- /dev/null +++ b/libs/openssl/crypto/lhash/lhash.h @@ -0,0 +1,240 @@ +/* crypto/lhash/lhash.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * Header for dynamic hash table routines Author - Eric Young + */ + +#ifndef HEADER_LHASH_H +# define HEADER_LHASH_H + +# include +# ifndef OPENSSL_NO_FP_API +# include +# endif + +# ifndef OPENSSL_NO_BIO +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct lhash_node_st { + void *data; + struct lhash_node_st *next; +# ifndef OPENSSL_NO_HASH_COMP + unsigned long hash; +# endif +} LHASH_NODE; + +typedef int (*LHASH_COMP_FN_TYPE) (const void *, const void *); +typedef unsigned long (*LHASH_HASH_FN_TYPE) (const void *); +typedef void (*LHASH_DOALL_FN_TYPE) (void *); +typedef void (*LHASH_DOALL_ARG_FN_TYPE) (void *, void *); + +/* + * Macros for declaring and implementing type-safe wrappers for LHASH + * callbacks. This way, callbacks can be provided to LHASH structures without + * function pointer casting and the macro-defined callbacks provide + * per-variable casting before deferring to the underlying type-specific + * callbacks. NB: It is possible to place a "static" in front of both the + * DECLARE and IMPLEMENT macros if the functions are strictly internal. + */ + +/* First: "hash" functions */ +# define DECLARE_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *); +# define IMPLEMENT_LHASH_HASH_FN(name, o_type) \ + unsigned long name##_LHASH_HASH(const void *arg) { \ + const o_type *a = arg; \ + return name##_hash(a); } +# define LHASH_HASH_FN(name) name##_LHASH_HASH + +/* Second: "compare" functions */ +# define DECLARE_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *, const void *); +# define IMPLEMENT_LHASH_COMP_FN(name, o_type) \ + int name##_LHASH_COMP(const void *arg1, const void *arg2) { \ + const o_type *a = arg1; \ + const o_type *b = arg2; \ + return name##_cmp(a,b); } +# define LHASH_COMP_FN(name) name##_LHASH_COMP + +/* Third: "doall" functions */ +# define DECLARE_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *); +# define IMPLEMENT_LHASH_DOALL_FN(name, o_type) \ + void name##_LHASH_DOALL(void *arg) { \ + o_type *a = arg; \ + name##_doall(a); } +# define LHASH_DOALL_FN(name) name##_LHASH_DOALL + +/* Fourth: "doall_arg" functions */ +# define DECLARE_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *, void *); +# define IMPLEMENT_LHASH_DOALL_ARG_FN(name, o_type, a_type) \ + void name##_LHASH_DOALL_ARG(void *arg1, void *arg2) { \ + o_type *a = arg1; \ + a_type *b = arg2; \ + name##_doall_arg(a, b); } +# define LHASH_DOALL_ARG_FN(name) name##_LHASH_DOALL_ARG + +typedef struct lhash_st { + LHASH_NODE **b; + LHASH_COMP_FN_TYPE comp; + LHASH_HASH_FN_TYPE hash; + unsigned int num_nodes; + unsigned int num_alloc_nodes; + unsigned int p; + unsigned int pmax; + unsigned long up_load; /* load times 256 */ + unsigned long down_load; /* load times 256 */ + unsigned long num_items; + unsigned long num_expands; + unsigned long num_expand_reallocs; + unsigned long num_contracts; + unsigned long num_contract_reallocs; + unsigned long num_hash_calls; + unsigned long num_comp_calls; + unsigned long num_insert; + unsigned long num_replace; + unsigned long num_delete; + unsigned long num_no_delete; + unsigned long num_retrieve; + unsigned long num_retrieve_miss; + unsigned long num_hash_comps; + int error; +} _LHASH; /* Do not use _LHASH directly, use LHASH_OF + * and friends */ + +# define LH_LOAD_MULT 256 + +/* + * Indicates a malloc() error in the last call, this is only bad in + * lh_insert(). + */ +# define lh_error(lh) ((lh)->error) + +_LHASH *lh_new(LHASH_HASH_FN_TYPE h, LHASH_COMP_FN_TYPE c); +void lh_free(_LHASH *lh); +void *lh_insert(_LHASH *lh, void *data); +void *lh_delete(_LHASH *lh, const void *data); +void *lh_retrieve(_LHASH *lh, const void *data); +void lh_doall(_LHASH *lh, LHASH_DOALL_FN_TYPE func); +void lh_doall_arg(_LHASH *lh, LHASH_DOALL_ARG_FN_TYPE func, void *arg); +unsigned long lh_strhash(const char *c); +unsigned long lh_num_items(const _LHASH *lh); + +# ifndef OPENSSL_NO_FP_API +void lh_stats(const _LHASH *lh, FILE *out); +void lh_node_stats(const _LHASH *lh, FILE *out); +void lh_node_usage_stats(const _LHASH *lh, FILE *out); +# endif + +# ifndef OPENSSL_NO_BIO +void lh_stats_bio(const _LHASH *lh, BIO *out); +void lh_node_stats_bio(const _LHASH *lh, BIO *out); +void lh_node_usage_stats_bio(const _LHASH *lh, BIO *out); +# endif + +/* Type checking... */ + +# define LHASH_OF(type) struct lhash_st_##type + +# define DECLARE_LHASH_OF(type) LHASH_OF(type) { int dummy; } + +# define CHECKED_LHASH_OF(type,lh) \ + ((_LHASH *)CHECKED_PTR_OF(LHASH_OF(type),lh)) + +/* Define wrapper functions. */ +# define LHM_lh_new(type, name) \ + ((LHASH_OF(type) *)lh_new(LHASH_HASH_FN(name), LHASH_COMP_FN(name))) +# define LHM_lh_error(type, lh) \ + lh_error(CHECKED_LHASH_OF(type,lh)) +# define LHM_lh_insert(type, lh, inst) \ + ((type *)lh_insert(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +# define LHM_lh_retrieve(type, lh, inst) \ + ((type *)lh_retrieve(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +# define LHM_lh_delete(type, lh, inst) \ + ((type *)lh_delete(CHECKED_LHASH_OF(type, lh), \ + CHECKED_PTR_OF(type, inst))) +# define LHM_lh_doall(type, lh,fn) lh_doall(CHECKED_LHASH_OF(type, lh), fn) +# define LHM_lh_doall_arg(type, lh, fn, arg_type, arg) \ + lh_doall_arg(CHECKED_LHASH_OF(type, lh), fn, CHECKED_PTR_OF(arg_type, arg)) +# define LHM_lh_num_items(type, lh) lh_num_items(CHECKED_LHASH_OF(type, lh)) +# define LHM_lh_down_load(type, lh) (CHECKED_LHASH_OF(type, lh)->down_load) +# define LHM_lh_node_stats_bio(type, lh, out) \ + lh_node_stats_bio(CHECKED_LHASH_OF(type, lh), out) +# define LHM_lh_node_usage_stats_bio(type, lh, out) \ + lh_node_usage_stats_bio(CHECKED_LHASH_OF(type, lh), out) +# define LHM_lh_stats_bio(type, lh, out) \ + lh_stats_bio(CHECKED_LHASH_OF(type, lh), out) +# define LHM_lh_free(type, lh) lh_free(CHECKED_LHASH_OF(type, lh)) + +DECLARE_LHASH_OF(OPENSSL_STRING); +DECLARE_LHASH_OF(OPENSSL_CSTRING); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/lhash/num.pl b/libs/openssl/crypto/lhash/num.pl new file mode 100644 index 00000000..30fedf9c --- /dev/null +++ b/libs/openssl/crypto/lhash/num.pl @@ -0,0 +1,17 @@ +#!/usr/local/bin/perl + +#node 10 -> 4 + +while (<>) + { + next unless /^node/; + chop; + @a=split; + $num{$a[3]}++; + } + +@a=sort {$a <=> $b } keys %num; +foreach (0 .. $a[$#a]) + { + printf "%4d:%4d\n",$_,$num{$_}; + } diff --git a/libs/openssl/crypto/md2/md2.c b/libs/openssl/crypto/md2/md2.c new file mode 100644 index 00000000..584e34a6 --- /dev/null +++ b/libs/openssl/crypto/md2/md2.c @@ -0,0 +1,119 @@ +/* crypto/md2/md2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#define BUFSIZE 1024*16 + +void do_fp(FILE *f); +void pt(unsigned char *md); +int read(int, void *, unsigned int); +void exit(int); +int main(int argc, char *argv[]) +{ + int i, err = 0; + FILE *IN; + + if (argc == 1) { + do_fp(stdin); + } else { + for (i = 1; i < argc; i++) { + IN = fopen(argv[i], "r"); + if (IN == NULL) { + perror(argv[i]); + err++; + continue; + } + printf("MD2(%s)= ", argv[i]); + do_fp(IN); + fclose(IN); + } + } + exit(err); + return (err); +} + +void do_fp(FILE *f) +{ + MD2_CTX c; + unsigned char md[MD2_DIGEST_LENGTH]; + int fd, i; + static unsigned char buf[BUFSIZE]; + + fd = fileno(f); + MD2_Init(&c); + for (;;) { + i = read(fd, buf, BUFSIZE); + if (i <= 0) + break; + MD2_Update(&c, buf, (unsigned long)i); + } + MD2_Final(&(md[0]), &c); + pt(md); +} + +void pt(unsigned char *md) +{ + int i; + + for (i = 0; i < MD2_DIGEST_LENGTH; i++) + printf("%02x", md[i]); + printf("\n"); +} diff --git a/libs/openssl/crypto/md2/md2.h b/libs/openssl/crypto/md2/md2.h new file mode 100644 index 00000000..b568d3f9 --- /dev/null +++ b/libs/openssl/crypto/md2/md2.h @@ -0,0 +1,94 @@ +/* crypto/md/md2.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_MD2_H +# define HEADER_MD2_H + +# include /* OPENSSL_NO_MD2, MD2_INT */ +# ifdef OPENSSL_NO_MD2 +# error MD2 is disabled. +# endif +# include + +# define MD2_DIGEST_LENGTH 16 +# define MD2_BLOCK 16 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct MD2state_st { + unsigned int num; + unsigned char data[MD2_BLOCK]; + MD2_INT cksm[MD2_BLOCK]; + MD2_INT state[MD2_BLOCK]; +} MD2_CTX; + +const char *MD2_options(void); +# ifdef OPENSSL_FIPS +int private_MD2_Init(MD2_CTX *c); +# endif +int MD2_Init(MD2_CTX *c); +int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len); +int MD2_Final(unsigned char *md, MD2_CTX *c); +unsigned char *MD2(const unsigned char *d, size_t n, unsigned char *md); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/md2/md2_dgst.c b/libs/openssl/crypto/md2/md2_dgst.c new file mode 100644 index 00000000..9cd79f8d --- /dev/null +++ b/libs/openssl/crypto/md2/md2_dgst.c @@ -0,0 +1,224 @@ +/* crypto/md2/md2_dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include +#include + +const char MD2_version[] = "MD2" OPENSSL_VERSION_PTEXT; + +/* + * Implemented from RFC1319 The MD2 Message-Digest Algorithm + */ + +#define UCHAR unsigned char + +static void md2_block(MD2_CTX *c, const unsigned char *d); +/* + * The magic S table - I have converted it to hex since it is basically just + * a random byte string. + */ +static const MD2_INT S[256] = { + 0x29, 0x2E, 0x43, 0xC9, 0xA2, 0xD8, 0x7C, 0x01, + 0x3D, 0x36, 0x54, 0xA1, 0xEC, 0xF0, 0x06, 0x13, + 0x62, 0xA7, 0x05, 0xF3, 0xC0, 0xC7, 0x73, 0x8C, + 0x98, 0x93, 0x2B, 0xD9, 0xBC, 0x4C, 0x82, 0xCA, + 0x1E, 0x9B, 0x57, 0x3C, 0xFD, 0xD4, 0xE0, 0x16, + 0x67, 0x42, 0x6F, 0x18, 0x8A, 0x17, 0xE5, 0x12, + 0xBE, 0x4E, 0xC4, 0xD6, 0xDA, 0x9E, 0xDE, 0x49, + 0xA0, 0xFB, 0xF5, 0x8E, 0xBB, 0x2F, 0xEE, 0x7A, + 0xA9, 0x68, 0x79, 0x91, 0x15, 0xB2, 0x07, 0x3F, + 0x94, 0xC2, 0x10, 0x89, 0x0B, 0x22, 0x5F, 0x21, + 0x80, 0x7F, 0x5D, 0x9A, 0x5A, 0x90, 0x32, 0x27, + 0x35, 0x3E, 0xCC, 0xE7, 0xBF, 0xF7, 0x97, 0x03, + 0xFF, 0x19, 0x30, 0xB3, 0x48, 0xA5, 0xB5, 0xD1, + 0xD7, 0x5E, 0x92, 0x2A, 0xAC, 0x56, 0xAA, 0xC6, + 0x4F, 0xB8, 0x38, 0xD2, 0x96, 0xA4, 0x7D, 0xB6, + 0x76, 0xFC, 0x6B, 0xE2, 0x9C, 0x74, 0x04, 0xF1, + 0x45, 0x9D, 0x70, 0x59, 0x64, 0x71, 0x87, 0x20, + 0x86, 0x5B, 0xCF, 0x65, 0xE6, 0x2D, 0xA8, 0x02, + 0x1B, 0x60, 0x25, 0xAD, 0xAE, 0xB0, 0xB9, 0xF6, + 0x1C, 0x46, 0x61, 0x69, 0x34, 0x40, 0x7E, 0x0F, + 0x55, 0x47, 0xA3, 0x23, 0xDD, 0x51, 0xAF, 0x3A, + 0xC3, 0x5C, 0xF9, 0xCE, 0xBA, 0xC5, 0xEA, 0x26, + 0x2C, 0x53, 0x0D, 0x6E, 0x85, 0x28, 0x84, 0x09, + 0xD3, 0xDF, 0xCD, 0xF4, 0x41, 0x81, 0x4D, 0x52, + 0x6A, 0xDC, 0x37, 0xC8, 0x6C, 0xC1, 0xAB, 0xFA, + 0x24, 0xE1, 0x7B, 0x08, 0x0C, 0xBD, 0xB1, 0x4A, + 0x78, 0x88, 0x95, 0x8B, 0xE3, 0x63, 0xE8, 0x6D, + 0xE9, 0xCB, 0xD5, 0xFE, 0x3B, 0x00, 0x1D, 0x39, + 0xF2, 0xEF, 0xB7, 0x0E, 0x66, 0x58, 0xD0, 0xE4, + 0xA6, 0x77, 0x72, 0xF8, 0xEB, 0x75, 0x4B, 0x0A, + 0x31, 0x44, 0x50, 0xB4, 0x8F, 0xED, 0x1F, 0x1A, + 0xDB, 0x99, 0x8D, 0x33, 0x9F, 0x11, 0x83, 0x14, +}; + +const char *MD2_options(void) +{ + if (sizeof(MD2_INT) == 1) + return ("md2(char)"); + else + return ("md2(int)"); +} + +fips_md_init(MD2) +{ + c->num = 0; + memset(c->state, 0, sizeof c->state); + memset(c->cksm, 0, sizeof c->cksm); + memset(c->data, 0, sizeof c->data); + return 1; +} + +int MD2_Update(MD2_CTX *c, const unsigned char *data, size_t len) +{ + register UCHAR *p; + + if (len == 0) + return 1; + + p = c->data; + if (c->num != 0) { + if ((c->num + len) >= MD2_BLOCK) { + memcpy(&(p[c->num]), data, MD2_BLOCK - c->num); + md2_block(c, c->data); + data += (MD2_BLOCK - c->num); + len -= (MD2_BLOCK - c->num); + c->num = 0; + /* drop through and do the rest */ + } else { + memcpy(&(p[c->num]), data, len); + /* data+=len; */ + c->num += (int)len; + return 1; + } + } + /* + * we now can process the input data in blocks of MD2_BLOCK chars and + * save the leftovers to c->data. + */ + while (len >= MD2_BLOCK) { + md2_block(c, data); + data += MD2_BLOCK; + len -= MD2_BLOCK; + } + memcpy(p, data, len); + c->num = (int)len; + return 1; +} + +static void md2_block(MD2_CTX *c, const unsigned char *d) +{ + register MD2_INT t, *sp1, *sp2; + register int i, j; + MD2_INT state[48]; + + sp1 = c->state; + sp2 = c->cksm; + j = sp2[MD2_BLOCK - 1]; + for (i = 0; i < 16; i++) { + state[i] = sp1[i]; + state[i + 16] = t = d[i]; + state[i + 32] = (t ^ sp1[i]); + j = sp2[i] ^= S[t ^ j]; + } + t = 0; + for (i = 0; i < 18; i++) { + for (j = 0; j < 48; j += 8) { + t = state[j + 0] ^= S[t]; + t = state[j + 1] ^= S[t]; + t = state[j + 2] ^= S[t]; + t = state[j + 3] ^= S[t]; + t = state[j + 4] ^= S[t]; + t = state[j + 5] ^= S[t]; + t = state[j + 6] ^= S[t]; + t = state[j + 7] ^= S[t]; + } + t = (t + i) & 0xff; + } + memcpy(sp1, state, 16 * sizeof(MD2_INT)); + OPENSSL_cleanse(state, 48 * sizeof(MD2_INT)); +} + +int MD2_Final(unsigned char *md, MD2_CTX *c) +{ + int i, v; + register UCHAR *cp; + register MD2_INT *p1, *p2; + + cp = c->data; + p1 = c->state; + p2 = c->cksm; + v = MD2_BLOCK - c->num; + for (i = c->num; i < MD2_BLOCK; i++) + cp[i] = (UCHAR) v; + + md2_block(c, cp); + + for (i = 0; i < MD2_BLOCK; i++) + cp[i] = (UCHAR) p2[i]; + md2_block(c, cp); + + for (i = 0; i < 16; i++) + md[i] = (UCHAR) (p1[i] & 0xff); + memset((char *)&c, 0, sizeof(c)); + return 1; +} diff --git a/libs/openssl/crypto/md2/md2_one.c b/libs/openssl/crypto/md2/md2_one.c new file mode 100644 index 00000000..cd2631b2 --- /dev/null +++ b/libs/openssl/crypto/md2/md2_one.c @@ -0,0 +1,96 @@ +/* crypto/md2/md2_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include + +/* + * This is a separate file so that #defines in cryptlib.h can map my MD + * functions to different names + */ + +unsigned char *MD2(const unsigned char *d, size_t n, unsigned char *md) +{ + MD2_CTX c; + static unsigned char m[MD2_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!MD2_Init(&c)) + return NULL; +#ifndef CHARSET_EBCDIC + MD2_Update(&c, d, n); +#else + { + char temp[1024]; + unsigned long chunk; + + while (n > 0) { + chunk = (n > sizeof(temp)) ? sizeof(temp) : n; + ebcdic2ascii(temp, d, chunk); + MD2_Update(&c, temp, chunk); + n -= chunk; + d += chunk; + } + } +#endif + MD2_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); /* Security consideration */ + return (md); +} diff --git a/libs/openssl/crypto/md2/md2test.c b/libs/openssl/crypto/md2/md2test.c new file mode 100644 index 00000000..49a8a9bc --- /dev/null +++ b/libs/openssl/crypto/md2/md2test.c @@ -0,0 +1,142 @@ +/* crypto/md2/md2test.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "../e_os.h" + +#ifdef OPENSSL_NO_MD2 +int main(int argc, char *argv[]) +{ + printf("No MD2 support\n"); + return (0); +} +#else +# include +# include + +# ifdef CHARSET_EBCDIC +# include +# endif + +static char *test[] = { + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + NULL, +}; + +static char *ret[] = { + "8350e5a3e24c153df2275c9f80692773", + "32ec01ec4a6dac72c0ab96fb34c0b5d1", + "da853b0d3f88d99b30283a69e6ded6bb", + "ab4f496bfb2a530b219ff33031fe06b0", + "4e8ddff3650292ab5a4108c3aa47940b", + "da33def2a42df13975352846c30338cd", + "d5976f79d83d3a0dc9806c3c66f3efd8", +}; + +static char *pt(unsigned char *md); +int main(int argc, char *argv[]) +{ + int i, err = 0; + char **P, **R; + char *p; + unsigned char md[MD2_DIGEST_LENGTH]; + + P = test; + R = ret; + i = 1; + while (*P != NULL) { + EVP_Digest((unsigned char *)*P, strlen(*P), md, NULL, EVP_md2(), + NULL); + p = pt(md); + if (strcmp(p, *R) != 0) { + printf("error calculating MD2 on '%s'\n", *P); + printf("got %s instead of %s\n", p, *R); + err++; + } else + printf("test %d ok\n", i); + i++; + R++; + P++; + } +# ifdef OPENSSL_SYS_NETWARE + if (err) + printf("ERROR: %d\n", err); +# endif + EXIT(err); + return err; +} + +static char *pt(unsigned char *md) +{ + int i; + static char buf[80]; + + for (i = 0; i < MD2_DIGEST_LENGTH; i++) + sprintf(&(buf[i * 2]), "%02x", md[i]); + return (buf); +} +#endif diff --git a/libs/openssl/crypto/md32_common.h b/libs/openssl/crypto/md32_common.h new file mode 100644 index 00000000..18238334 --- /dev/null +++ b/libs/openssl/crypto/md32_common.h @@ -0,0 +1,410 @@ +/* crypto/md32_common.h */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +/*- + * This is a generic 32 bit "collector" for message digest algorithms. + * Whenever needed it collects input character stream into chunks of + * 32 bit values and invokes a block function that performs actual hash + * calculations. + * + * Porting guide. + * + * Obligatory macros: + * + * DATA_ORDER_IS_BIG_ENDIAN or DATA_ORDER_IS_LITTLE_ENDIAN + * this macro defines byte order of input stream. + * HASH_CBLOCK + * size of a unit chunk HASH_BLOCK operates on. + * HASH_LONG + * has to be at lest 32 bit wide, if it's wider, then + * HASH_LONG_LOG2 *has to* be defined along + * HASH_CTX + * context structure that at least contains following + * members: + * typedef struct { + * ... + * HASH_LONG Nl,Nh; + * either { + * HASH_LONG data[HASH_LBLOCK]; + * unsigned char data[HASH_CBLOCK]; + * }; + * unsigned int num; + * ... + * } HASH_CTX; + * data[] vector is expected to be zeroed upon first call to + * HASH_UPDATE. + * HASH_UPDATE + * name of "Update" function, implemented here. + * HASH_TRANSFORM + * name of "Transform" function, implemented here. + * HASH_FINAL + * name of "Final" function, implemented here. + * HASH_BLOCK_DATA_ORDER + * name of "block" function capable of treating *unaligned* input + * message in original (data) byte order, implemented externally. + * HASH_MAKE_STRING + * macro convering context variables to an ASCII hash string. + * + * MD5 example: + * + * #define DATA_ORDER_IS_LITTLE_ENDIAN + * + * #define HASH_LONG MD5_LONG + * #define HASH_LONG_LOG2 MD5_LONG_LOG2 + * #define HASH_CTX MD5_CTX + * #define HASH_CBLOCK MD5_CBLOCK + * #define HASH_UPDATE MD5_Update + * #define HASH_TRANSFORM MD5_Transform + * #define HASH_FINAL MD5_Final + * #define HASH_BLOCK_DATA_ORDER md5_block_data_order + * + * + */ + +#if !defined(DATA_ORDER_IS_BIG_ENDIAN) && !defined(DATA_ORDER_IS_LITTLE_ENDIAN) +# error "DATA_ORDER must be defined!" +#endif + +#ifndef HASH_CBLOCK +# error "HASH_CBLOCK must be defined!" +#endif +#ifndef HASH_LONG +# error "HASH_LONG must be defined!" +#endif +#ifndef HASH_CTX +# error "HASH_CTX must be defined!" +#endif + +#ifndef HASH_UPDATE +# error "HASH_UPDATE must be defined!" +#endif +#ifndef HASH_TRANSFORM +# error "HASH_TRANSFORM must be defined!" +#endif +#ifndef HASH_FINAL +# error "HASH_FINAL must be defined!" +#endif + +#ifndef HASH_BLOCK_DATA_ORDER +# error "HASH_BLOCK_DATA_ORDER must be defined!" +#endif + +/* + * Engage compiler specific rotate intrinsic function if available. + */ +#undef ROTATE +#ifndef PEDANTIC +# if defined(_MSC_VER) +# define ROTATE(a,n) _lrotl(a,n) +# elif defined(__ICC) +# define ROTATE(a,n) _rotl(a,n) +# elif defined(__MWERKS__) +# if defined(__POWERPC__) +# define ROTATE(a,n) __rlwinm(a,n,0,31) +# elif defined(__MC68K__) + /* Motorola specific tweak. */ +# define ROTATE(a,n) ( n<24 ? __rol(a,n) : __ror(a,32-n) ) +# else +# define ROTATE(a,n) __rol(a,n) +# endif +# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) + /* + * Some GNU C inline assembler templates. Note that these are + * rotates by *constant* number of bits! But that's exactly + * what we need here... + * + */ +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ( \ + "roll %1,%0" \ + : "=r"(ret) \ + : "I"(n), "0"((unsigned int)(a)) \ + : "cc"); \ + ret; \ + }) +# elif defined(_ARCH_PPC) || defined(_ARCH_PPC64) || \ + defined(__powerpc) || defined(__ppc__) || defined(__powerpc64__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ( \ + "rlwinm %0,%1,%2,0,31" \ + : "=r"(ret) \ + : "r"(a), "I"(n)); \ + ret; \ + }) +# elif defined(__s390x__) +# define ROTATE(a,n) ({ register unsigned int ret; \ + asm ("rll %0,%1,%2" \ + : "=r"(ret) \ + : "r"(a), "I"(n)); \ + ret; \ + }) +# endif +# endif +#endif /* PEDANTIC */ + +#ifndef ROTATE +# define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) +#endif + +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + +# ifndef PEDANTIC +# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if ((defined(__i386) || defined(__i386__)) && !defined(I386_ONLY)) || \ + (defined(__x86_64) || defined(__x86_64__)) +# if !defined(B_ENDIAN) + /* + * This gives ~30-40% performance improvement in SHA-256 compiled + * with gcc [on P4]. Well, first macro to be frank. We can pull + * this trick on x86* platforms only, because these CPUs can fetch + * unaligned data without raising an exception. + */ +# define HOST_c2l(c,l) ({ unsigned int r=*((const unsigned int *)(c)); \ + asm ("bswapl %0":"=r"(r):"0"(r)); \ + (c)+=4; (l)=r; }) +# define HOST_l2c(l,c) ({ unsigned int r=(l); \ + asm ("bswapl %0":"=r"(r):"0"(r)); \ + *((unsigned int *)(c))=r; (c)+=4; r; }) +# endif +# endif +# endif +# endif +# if defined(__s390__) || defined(__s390x__) +# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, (l)) +# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, (l)) +# endif + +# ifndef HOST_c2l +# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++)))<<24), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++))) ) ) +# endif +# ifndef HOST_l2c +# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff), \ + l) +# endif + +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + +# ifndef PEDANTIC +# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(__s390x__) +# define HOST_c2l(c,l) ({ asm ("lrv %0,%1" \ + :"=d"(l) :"m"(*(const unsigned int *)(c)));\ + (c)+=4; (l); }) +# define HOST_l2c(l,c) ({ asm ("strv %1,%0" \ + :"=m"(*(unsigned int *)(c)) :"d"(l));\ + (c)+=4; (l); }) +# endif +# endif +# endif +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# ifndef B_ENDIAN + /* See comment in DATA_ORDER_IS_BIG_ENDIAN section. */ +# define HOST_c2l(c,l) ((l)=*((const unsigned int *)(c)), (c)+=4, l) +# define HOST_l2c(l,c) (*((unsigned int *)(c))=(l), (c)+=4, l) +# endif +# endif + +# ifndef HOST_c2l +# define HOST_c2l(c,l) (l =(((unsigned long)(*((c)++))) ), \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<<24) ) +# endif +# ifndef HOST_l2c +# define HOST_l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + l) +# endif + +#endif + +/* + * Time for some action:-) + */ + +int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) +{ + const unsigned char *data = data_; + unsigned char *p; + HASH_LONG l; + size_t n; + + if (len == 0) + return 1; + + l = (c->Nl + (((HASH_LONG) len) << 3)) & 0xffffffffUL; + /* + * 95-05-24 eay Fixed a bug with the overflow handling, thanks to Wei Dai + * for pointing it out. + */ + if (l < c->Nl) /* overflow */ + c->Nh++; + c->Nh += (HASH_LONG) (len >> 29); /* might cause compiler warning on + * 16-bit */ + c->Nl = l; + + n = c->num; + if (n != 0) { + p = (unsigned char *)c->data; + + if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) { + memcpy(p + n, data, HASH_CBLOCK - n); + HASH_BLOCK_DATA_ORDER(c, p, 1); + n = HASH_CBLOCK - n; + data += n; + len -= n; + c->num = 0; + memset(p, 0, HASH_CBLOCK); /* keep it zeroed */ + } else { + memcpy(p + n, data, len); + c->num += (unsigned int)len; + return 1; + } + } + + n = len / HASH_CBLOCK; + if (n > 0) { + HASH_BLOCK_DATA_ORDER(c, data, n); + n *= HASH_CBLOCK; + data += n; + len -= n; + } + + if (len != 0) { + p = (unsigned char *)c->data; + c->num = (unsigned int)len; + memcpy(p, data, len); + } + return 1; +} + +void HASH_TRANSFORM(HASH_CTX *c, const unsigned char *data) +{ + HASH_BLOCK_DATA_ORDER(c, data, 1); +} + +int HASH_FINAL(unsigned char *md, HASH_CTX *c) +{ + unsigned char *p = (unsigned char *)c->data; + size_t n = c->num; + + p[n] = 0x80; /* there is always room for one */ + n++; + + if (n > (HASH_CBLOCK - 8)) { + memset(p + n, 0, HASH_CBLOCK - n); + n = 0; + HASH_BLOCK_DATA_ORDER(c, p, 1); + } + memset(p + n, 0, HASH_CBLOCK - 8 - n); + + p += HASH_CBLOCK - 8; +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + (void)HOST_l2c(c->Nh, p); + (void)HOST_l2c(c->Nl, p); +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + (void)HOST_l2c(c->Nl, p); + (void)HOST_l2c(c->Nh, p); +#endif + p -= HASH_CBLOCK; + HASH_BLOCK_DATA_ORDER(c, p, 1); + c->num = 0; + memset(p, 0, HASH_CBLOCK); + +#ifndef HASH_MAKE_STRING +# error "HASH_MAKE_STRING must be defined!" +#else + HASH_MAKE_STRING(c, md); +#endif + + return 1; +} + +#ifndef MD32_REG_T +# if defined(__alpha) || defined(__sparcv9) || defined(__mips) +# define MD32_REG_T long +/* + * This comment was originaly written for MD5, which is why it + * discusses A-D. But it basically applies to all 32-bit digests, + * which is why it was moved to common header file. + * + * In case you wonder why A-D are declared as long and not + * as MD5_LONG. Doing so results in slight performance + * boost on LP64 architectures. The catch is we don't + * really care if 32 MSBs of a 64-bit register get polluted + * with eventual overflows as we *save* only 32 LSBs in + * *either* case. Now declaring 'em long excuses the compiler + * from keeping 32 MSBs zeroed resulting in 13% performance + * improvement under SPARC Solaris7/64 and 5% under AlphaLinux. + * Well, to be honest it should say that this *prevents* + * performance degradation. + * + */ +# else +/* + * Above is not absolute and there are LP64 compilers that + * generate better code if MD32_REG_T is defined int. The above + * pre-processor condition reflects the circumstances under which + * the conclusion was made and is subject to further extension. + * + */ +# define MD32_REG_T int +# endif +#endif diff --git a/libs/openssl/crypto/md4/md4.c b/libs/openssl/crypto/md4/md4.c new file mode 100644 index 00000000..c9fab666 --- /dev/null +++ b/libs/openssl/crypto/md4/md4.c @@ -0,0 +1,121 @@ +/* crypto/md4/md4.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#define BUFSIZE 1024*16 + +void do_fp(FILE *f); +void pt(unsigned char *md); +#if !defined(_OSD_POSIX) && !defined(__DJGPP__) +int read(int, void *, unsigned int); +#endif + +int main(int argc, char **argv) +{ + int i, err = 0; + FILE *IN; + + if (argc == 1) { + do_fp(stdin); + } else { + for (i = 1; i < argc; i++) { + IN = fopen(argv[i], "r"); + if (IN == NULL) { + perror(argv[i]); + err++; + continue; + } + printf("MD4(%s)= ", argv[i]); + do_fp(IN); + fclose(IN); + } + } + exit(err); +} + +void do_fp(FILE *f) +{ + MD4_CTX c; + unsigned char md[MD4_DIGEST_LENGTH]; + int fd; + int i; + static unsigned char buf[BUFSIZE]; + + fd = fileno(f); + MD4_Init(&c); + for (;;) { + i = read(fd, buf, sizeof buf); + if (i <= 0) + break; + MD4_Update(&c, buf, (unsigned long)i); + } + MD4_Final(&(md[0]), &c); + pt(md); +} + +void pt(unsigned char *md) +{ + int i; + + for (i = 0; i < MD4_DIGEST_LENGTH; i++) + printf("%02x", md[i]); + printf("\n"); +} diff --git a/libs/openssl/crypto/md4/md4.h b/libs/openssl/crypto/md4/md4.h new file mode 100644 index 00000000..11fd7129 --- /dev/null +++ b/libs/openssl/crypto/md4/md4.h @@ -0,0 +1,119 @@ +/* crypto/md4/md4.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_MD4_H +# define HEADER_MD4_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_MD4 +# error MD4 is disabled. +# endif + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD4_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! MD4_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +# if defined(__LP32__) +# define MD4_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define MD4_LONG unsigned long +# define MD4_LONG_LOG2 3 +/* + * _CRAY note. I could declare short, but I have no idea what impact + * does it have on performance on none-T3E machines. I could declare + * int, but at least on C90 sizeof(int) can be chosen at compile time. + * So I've chosen long... + * + */ +# else +# define MD4_LONG unsigned int +# endif + +# define MD4_CBLOCK 64 +# define MD4_LBLOCK (MD4_CBLOCK/4) +# define MD4_DIGEST_LENGTH 16 + +typedef struct MD4state_st { + MD4_LONG A, B, C, D; + MD4_LONG Nl, Nh; + MD4_LONG data[MD4_LBLOCK]; + unsigned int num; +} MD4_CTX; + +# ifdef OPENSSL_FIPS +int private_MD4_Init(MD4_CTX *c); +# endif +int MD4_Init(MD4_CTX *c); +int MD4_Update(MD4_CTX *c, const void *data, size_t len); +int MD4_Final(unsigned char *md, MD4_CTX *c); +unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md); +void MD4_Transform(MD4_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/md4/md4_dgst.c b/libs/openssl/crypto/md4/md4_dgst.c new file mode 100644 index 00000000..614fca00 --- /dev/null +++ b/libs/openssl/crypto/md4/md4_dgst.c @@ -0,0 +1,199 @@ +/* crypto/md4/md4_dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include "md4_locl.h" + +const char MD4_version[] = "MD4" OPENSSL_VERSION_PTEXT; + +/* + * Implemented from RFC1186 The MD4 Message-Digest Algorithm + */ + +#define INIT_DATA_A (unsigned long)0x67452301L +#define INIT_DATA_B (unsigned long)0xefcdab89L +#define INIT_DATA_C (unsigned long)0x98badcfeL +#define INIT_DATA_D (unsigned long)0x10325476L + +fips_md_init(MD4) +{ + memset(c, 0, sizeof(*c)); + c->A = INIT_DATA_A; + c->B = INIT_DATA_B; + c->C = INIT_DATA_C; + c->D = INIT_DATA_D; + return 1; +} + +#ifndef md4_block_data_order +# ifdef X +# undef X +# endif +void md4_block_data_order(MD4_CTX *c, const void *data_, size_t num) +{ + const unsigned char *data = data_; + register unsigned MD32_REG_T A, B, C, D, l; +# ifndef MD32_XARRAY + /* See comment in crypto/sha/sha_locl.h for details. */ + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; +# define X(i) XX##i +# else + MD4_LONG XX[MD4_LBLOCK]; +# define X(i) XX[i] +# endif + + A = c->A; + B = c->B; + C = c->C; + D = c->D; + + for (; num--;) { + (void)HOST_c2l(data, l); + X(0) = l; + (void)HOST_c2l(data, l); + X(1) = l; + /* Round 0 */ + R0(A, B, C, D, X(0), 3, 0); + (void)HOST_c2l(data, l); + X(2) = l; + R0(D, A, B, C, X(1), 7, 0); + (void)HOST_c2l(data, l); + X(3) = l; + R0(C, D, A, B, X(2), 11, 0); + (void)HOST_c2l(data, l); + X(4) = l; + R0(B, C, D, A, X(3), 19, 0); + (void)HOST_c2l(data, l); + X(5) = l; + R0(A, B, C, D, X(4), 3, 0); + (void)HOST_c2l(data, l); + X(6) = l; + R0(D, A, B, C, X(5), 7, 0); + (void)HOST_c2l(data, l); + X(7) = l; + R0(C, D, A, B, X(6), 11, 0); + (void)HOST_c2l(data, l); + X(8) = l; + R0(B, C, D, A, X(7), 19, 0); + (void)HOST_c2l(data, l); + X(9) = l; + R0(A, B, C, D, X(8), 3, 0); + (void)HOST_c2l(data, l); + X(10) = l; + R0(D, A, B, C, X(9), 7, 0); + (void)HOST_c2l(data, l); + X(11) = l; + R0(C, D, A, B, X(10), 11, 0); + (void)HOST_c2l(data, l); + X(12) = l; + R0(B, C, D, A, X(11), 19, 0); + (void)HOST_c2l(data, l); + X(13) = l; + R0(A, B, C, D, X(12), 3, 0); + (void)HOST_c2l(data, l); + X(14) = l; + R0(D, A, B, C, X(13), 7, 0); + (void)HOST_c2l(data, l); + X(15) = l; + R0(C, D, A, B, X(14), 11, 0); + R0(B, C, D, A, X(15), 19, 0); + /* Round 1 */ + R1(A, B, C, D, X(0), 3, 0x5A827999L); + R1(D, A, B, C, X(4), 5, 0x5A827999L); + R1(C, D, A, B, X(8), 9, 0x5A827999L); + R1(B, C, D, A, X(12), 13, 0x5A827999L); + R1(A, B, C, D, X(1), 3, 0x5A827999L); + R1(D, A, B, C, X(5), 5, 0x5A827999L); + R1(C, D, A, B, X(9), 9, 0x5A827999L); + R1(B, C, D, A, X(13), 13, 0x5A827999L); + R1(A, B, C, D, X(2), 3, 0x5A827999L); + R1(D, A, B, C, X(6), 5, 0x5A827999L); + R1(C, D, A, B, X(10), 9, 0x5A827999L); + R1(B, C, D, A, X(14), 13, 0x5A827999L); + R1(A, B, C, D, X(3), 3, 0x5A827999L); + R1(D, A, B, C, X(7), 5, 0x5A827999L); + R1(C, D, A, B, X(11), 9, 0x5A827999L); + R1(B, C, D, A, X(15), 13, 0x5A827999L); + /* Round 2 */ + R2(A, B, C, D, X(0), 3, 0x6ED9EBA1L); + R2(D, A, B, C, X(8), 9, 0x6ED9EBA1L); + R2(C, D, A, B, X(4), 11, 0x6ED9EBA1L); + R2(B, C, D, A, X(12), 15, 0x6ED9EBA1L); + R2(A, B, C, D, X(2), 3, 0x6ED9EBA1L); + R2(D, A, B, C, X(10), 9, 0x6ED9EBA1L); + R2(C, D, A, B, X(6), 11, 0x6ED9EBA1L); + R2(B, C, D, A, X(14), 15, 0x6ED9EBA1L); + R2(A, B, C, D, X(1), 3, 0x6ED9EBA1L); + R2(D, A, B, C, X(9), 9, 0x6ED9EBA1L); + R2(C, D, A, B, X(5), 11, 0x6ED9EBA1L); + R2(B, C, D, A, X(13), 15, 0x6ED9EBA1L); + R2(A, B, C, D, X(3), 3, 0x6ED9EBA1L); + R2(D, A, B, C, X(11), 9, 0x6ED9EBA1L); + R2(C, D, A, B, X(7), 11, 0x6ED9EBA1L); + R2(B, C, D, A, X(15), 15, 0x6ED9EBA1L); + + A = c->A += A; + B = c->B += B; + C = c->C += C; + D = c->D += D; + } +} +#endif diff --git a/libs/openssl/crypto/md4/md4_locl.h b/libs/openssl/crypto/md4/md4_locl.h new file mode 100644 index 00000000..dc86a86c --- /dev/null +++ b/libs/openssl/crypto/md4/md4_locl.h @@ -0,0 +1,113 @@ +/* crypto/md4/md4_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#ifndef MD4_LONG_LOG2 +# define MD4_LONG_LOG2 2 /* default to 32 bits */ +#endif + +void md4_block_data_order(MD4_CTX *c, const void *p, size_t num); + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_LONG MD4_LONG +#define HASH_CTX MD4_CTX +#define HASH_CBLOCK MD4_CBLOCK +#define HASH_UPDATE MD4_Update +#define HASH_TRANSFORM MD4_Transform +#define HASH_FINAL MD4_Final +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->A; (void)HOST_l2c(ll,(s)); \ + ll=(c)->B; (void)HOST_l2c(ll,(s)); \ + ll=(c)->C; (void)HOST_l2c(ll,(s)); \ + ll=(c)->D; (void)HOST_l2c(ll,(s)); \ + } while (0) +#define HASH_BLOCK_DATA_ORDER md4_block_data_order + +#include "md32_common.h" + +/*- +#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) +#define G(x,y,z) (((x) & (y)) | ((x) & ((z))) | ((y) & ((z)))) +*/ + +/* + * As pointed out by Wei Dai , the above can be simplified + * to the code below. Wei attributes these optimizations to Peter Gutmann's + * SHS code, and he attributes it to Rich Schroeppel. + */ +#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define G(b,c,d) (((b) & (c)) | ((b) & (d)) | ((c) & (d))) +#define H(b,c,d) ((b) ^ (c) ^ (d)) + +#define R0(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+F((b),(c),(d))); \ + a=ROTATE(a,s); }; + +#define R1(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+G((b),(c),(d))); \ + a=ROTATE(a,s); };\ + +#define R2(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+H((b),(c),(d))); \ + a=ROTATE(a,s); }; diff --git a/libs/openssl/crypto/md4/md4_one.c b/libs/openssl/crypto/md4/md4_one.c new file mode 100644 index 00000000..32ebd5fa --- /dev/null +++ b/libs/openssl/crypto/md4/md4_one.c @@ -0,0 +1,96 @@ +/* crypto/md4/md4_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#ifdef CHARSET_EBCDIC +# include +#endif + +unsigned char *MD4(const unsigned char *d, size_t n, unsigned char *md) +{ + MD4_CTX c; + static unsigned char m[MD4_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!MD4_Init(&c)) + return NULL; +#ifndef CHARSET_EBCDIC + MD4_Update(&c, d, n); +#else + { + char temp[1024]; + unsigned long chunk; + + while (n > 0) { + chunk = (n > sizeof(temp)) ? sizeof(temp) : n; + ebcdic2ascii(temp, d, chunk); + MD4_Update(&c, temp, chunk); + n -= chunk; + d += chunk; + } + } +#endif + MD4_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */ + return (md); +} diff --git a/libs/openssl/crypto/md4/md4s.cpp b/libs/openssl/crypto/md4/md4s.cpp new file mode 100644 index 00000000..c0ec97fc --- /dev/null +++ b/libs/openssl/crypto/md4/md4s.cpp @@ -0,0 +1,78 @@ +// +// gettsc.inl +// +// gives access to the Pentium's (secret) cycle counter +// +// This software was written by Leonard Janke (janke@unixg.ubc.ca) +// in 1996-7 and is entered, by him, into the public domain. + +#if defined(__WATCOMC__) +void GetTSC(unsigned long&); +#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax]; +#elif defined(__GNUC__) +inline +void GetTSC(unsigned long& tsc) +{ + asm volatile(".byte 15, 49\n\t" + : "=eax" (tsc) + : + : "%edx", "%eax"); +} +#elif defined(_MSC_VER) +inline +void GetTSC(unsigned long& tsc) +{ + unsigned long a; + __asm _emit 0fh + __asm _emit 31h + __asm mov a, eax; + tsc=a; +} +#endif + +#include +#include +#include + +extern "C" { +void md4_block_x86(MD4_CTX *ctx, unsigned char *buffer,int num); +} + +void main(int argc,char *argv[]) + { + unsigned char buffer[64*256]; + MD4_CTX ctx; + unsigned long s1,s2,e1,e2; + unsigned char k[16]; + unsigned long data[2]; + unsigned char iv[8]; + int i,num=0,numm; + int j=0; + + if (argc >= 2) + num=atoi(argv[1]); + + if (num == 0) num=16; + if (num > 250) num=16; + numm=num+2; + num*=64; + numm*=64; + + for (j=0; j<6; j++) + { + for (i=0; i<10; i++) /**/ + { + md4_block_x86(&ctx,buffer,numm); + GetTSC(s1); + md4_block_x86(&ctx,buffer,numm); + GetTSC(e1); + GetTSC(s2); + md4_block_x86(&ctx,buffer,num); + GetTSC(e2); + md4_block_x86(&ctx,buffer,num); + } + printf("md4 (%d bytes) %d %d (%.2f)\n",num, + e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2); + } + } + diff --git a/libs/openssl/crypto/md4/md4test.c b/libs/openssl/crypto/md4/md4test.c new file mode 100644 index 00000000..59f23bb5 --- /dev/null +++ b/libs/openssl/crypto/md4/md4test.c @@ -0,0 +1,133 @@ +/* crypto/md4/md4test.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "../e_os.h" + +#ifdef OPENSSL_NO_MD4 +int main(int argc, char *argv[]) +{ + printf("No MD4 support\n"); + return (0); +} +#else +# include +# include + +static char *test[] = { + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + NULL, +}; + +static char *ret[] = { + "31d6cfe0d16ae931b73c59d7e0c089c0", + "bde52cb31de33e46245e05fbdbd6fb24", + "a448017aaf21d8525fc10ae87aa6729d", + "d9130a8164549fe818874806e1c7014b", + "d79e1c308aa5bbcdeea8ed63df412da9", + "043f8582f241db351ce627e153e7f0e4", + "e33b4ddc9c38f2199c3e7b164fcc0536", +}; + +static char *pt(unsigned char *md); +int main(int argc, char *argv[]) +{ + int i, err = 0; + char **P, **R; + char *p; + unsigned char md[MD4_DIGEST_LENGTH]; + + P = test; + R = ret; + i = 1; + while (*P != NULL) { + EVP_Digest(&(P[0][0]), strlen((char *)*P), md, NULL, EVP_md4(), NULL); + p = pt(md); + if (strcmp(p, (char *)*R) != 0) { + printf("error calculating MD4 on '%s'\n", *P); + printf("got %s instead of %s\n", p, *R); + err++; + } else + printf("test %d ok\n", i); + i++; + R++; + P++; + } + EXIT(err); + return (0); +} + +static char *pt(unsigned char *md) +{ + int i; + static char buf[80]; + + for (i = 0; i < MD4_DIGEST_LENGTH; i++) + sprintf(&(buf[i * 2]), "%02x", md[i]); + return (buf); +} +#endif diff --git a/libs/openssl/crypto/md5/asm/md5-586.pl b/libs/openssl/crypto/md5/asm/md5-586.pl new file mode 100644 index 00000000..6cb66bb4 --- /dev/null +++ b/libs/openssl/crypto/md5/asm/md5-586.pl @@ -0,0 +1,307 @@ +#!/usr/local/bin/perl + +# Normal is the +# md5_block_x86(MD5_CTX *c, ULONG *X); +# version, non-normal is the +# md5_block_x86(MD5_CTX *c, ULONG *X,int blocks); + +$normal=0; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],$0); + +$A="eax"; +$B="ebx"; +$C="ecx"; +$D="edx"; +$tmp1="edi"; +$tmp2="ebp"; +$X="esi"; + +# What we need to load into $tmp for the next round +%Ltmp1=("R0",&Np($C), "R1",&Np($C), "R2",&Np($C), "R3",&Np($D)); +@xo=( + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, # R0 + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, # R1 + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, # R2 + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, # R3 + ); + +&md5_block("md5_block_asm_data_order"); +&asm_finish(); + +sub Np + { + local($p)=@_; + local(%n)=($A,$D,$B,$A,$C,$B,$D,$C); + return($n{$p}); + } + +sub R0 + { + local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_; + + &mov($tmp1,$C) if $pos < 0; + &mov($tmp2,&DWP($xo[$ki]*4,$K,"",0)) if $pos < 0; # very first one + + # body proper + + &comment("R0 $ki"); + &xor($tmp1,$d); # F function - part 2 + + &and($tmp1,$b); # F function - part 3 + &lea($a,&DWP($t,$a,$tmp2,1)); + + &xor($tmp1,$d); # F function - part 4 + + &add($a,$tmp1); + &mov($tmp1,&Np($c)) if $pos < 1; # next tmp1 for R0 + &mov($tmp1,&Np($c)) if $pos == 1; # next tmp1 for R1 + + &rotl($a,$s); + + &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2); + + &add($a,$b); + } + +sub R1 + { + local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_; + + &comment("R1 $ki"); + + &lea($a,&DWP($t,$a,$tmp2,1)); + + &xor($tmp1,$b); # G function - part 2 + &and($tmp1,$d); # G function - part 3 + + &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2); + &xor($tmp1,$c); # G function - part 4 + + &add($a,$tmp1); + &mov($tmp1,&Np($c)) if $pos < 1; # G function - part 1 + &mov($tmp1,&Np($c)) if $pos == 1; # G function - part 1 + + &rotl($a,$s); + + &add($a,$b); + } + +sub R2 + { + local($n,$pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_; + # This one is different, only 3 logical operations + +if (($n & 1) == 0) + { + &comment("R2 $ki"); + # make sure to do 'D' first, not 'B', else we clash with + # the last add from the previous round. + + &xor($tmp1,$d); # H function - part 2 + + &xor($tmp1,$b); # H function - part 3 + &lea($a,&DWP($t,$a,$tmp2,1)); + + &add($a,$tmp1); + + &rotl($a,$s); + + &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)); + &mov($tmp1,&Np($c)); + } +else + { + &comment("R2 $ki"); + # make sure to do 'D' first, not 'B', else we clash with + # the last add from the previous round. + + &lea($a,&DWP($t,$a,$tmp2,1)); + + &add($b,$c); # MOVED FORWARD + &xor($tmp1,$d); # H function - part 2 + + &xor($tmp1,$b); # H function - part 3 + &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if ($pos != 2); + + &add($a,$tmp1); + &mov($tmp1,&Np($c)) if $pos < 1; # H function - part 1 + &mov($tmp1,-1) if $pos == 1; # I function - part 1 + + &rotl($a,$s); + + &add($a,$b); + } + } + +sub R3 + { + local($pos,$a,$b,$c,$d,$K,$ki,$s,$t)=@_; + + &comment("R3 $ki"); + + # ¬($tmp1) + &xor($tmp1,$d) if $pos < 0; # I function - part 2 + + &or($tmp1,$b); # I function - part 3 + &lea($a,&DWP($t,$a,$tmp2,1)); + + &xor($tmp1,$c); # I function - part 4 + &mov($tmp2,&DWP($xo[$ki+1]*4,$K,"",0)) if $pos != 2; # load X/k value + &mov($tmp2,&wparam(0)) if $pos == 2; + + &add($a,$tmp1); + &mov($tmp1,-1) if $pos < 1; # H function - part 1 + &add($K,64) if $pos >=1 && !$normal; + + &rotl($a,$s); + + &xor($tmp1,&Np($d)) if $pos <= 0; # I function - part = first time + &mov($tmp1,&DWP( 0,$tmp2,"",0)) if $pos > 0; + &add($a,$b); + } + + +sub md5_block + { + local($name)=@_; + + &function_begin_B($name,"",3); + + # parameter 1 is the MD5_CTX structure. + # A 0 + # B 4 + # C 8 + # D 12 + + &push("esi"); + &push("edi"); + &mov($tmp1, &wparam(0)); # edi + &mov($X, &wparam(1)); # esi + &mov($C, &wparam(2)); + &push("ebp"); + &shl($C, 6); + &push("ebx"); + &add($C, $X); # offset we end at + &sub($C, 64); + &mov($A, &DWP( 0,$tmp1,"",0)); + &push($C); # Put on the TOS + &mov($B, &DWP( 4,$tmp1,"",0)); + &mov($C, &DWP( 8,$tmp1,"",0)); + &mov($D, &DWP(12,$tmp1,"",0)); + + &set_label("start") unless $normal; + &comment(""); + &comment("R0 section"); + + &R0(-2,$A,$B,$C,$D,$X, 0, 7,0xd76aa478); + &R0( 0,$D,$A,$B,$C,$X, 1,12,0xe8c7b756); + &R0( 0,$C,$D,$A,$B,$X, 2,17,0x242070db); + &R0( 0,$B,$C,$D,$A,$X, 3,22,0xc1bdceee); + &R0( 0,$A,$B,$C,$D,$X, 4, 7,0xf57c0faf); + &R0( 0,$D,$A,$B,$C,$X, 5,12,0x4787c62a); + &R0( 0,$C,$D,$A,$B,$X, 6,17,0xa8304613); + &R0( 0,$B,$C,$D,$A,$X, 7,22,0xfd469501); + &R0( 0,$A,$B,$C,$D,$X, 8, 7,0x698098d8); + &R0( 0,$D,$A,$B,$C,$X, 9,12,0x8b44f7af); + &R0( 0,$C,$D,$A,$B,$X,10,17,0xffff5bb1); + &R0( 0,$B,$C,$D,$A,$X,11,22,0x895cd7be); + &R0( 0,$A,$B,$C,$D,$X,12, 7,0x6b901122); + &R0( 0,$D,$A,$B,$C,$X,13,12,0xfd987193); + &R0( 0,$C,$D,$A,$B,$X,14,17,0xa679438e); + &R0( 1,$B,$C,$D,$A,$X,15,22,0x49b40821); + + &comment(""); + &comment("R1 section"); + &R1(-1,$A,$B,$C,$D,$X,16, 5,0xf61e2562); + &R1( 0,$D,$A,$B,$C,$X,17, 9,0xc040b340); + &R1( 0,$C,$D,$A,$B,$X,18,14,0x265e5a51); + &R1( 0,$B,$C,$D,$A,$X,19,20,0xe9b6c7aa); + &R1( 0,$A,$B,$C,$D,$X,20, 5,0xd62f105d); + &R1( 0,$D,$A,$B,$C,$X,21, 9,0x02441453); + &R1( 0,$C,$D,$A,$B,$X,22,14,0xd8a1e681); + &R1( 0,$B,$C,$D,$A,$X,23,20,0xe7d3fbc8); + &R1( 0,$A,$B,$C,$D,$X,24, 5,0x21e1cde6); + &R1( 0,$D,$A,$B,$C,$X,25, 9,0xc33707d6); + &R1( 0,$C,$D,$A,$B,$X,26,14,0xf4d50d87); + &R1( 0,$B,$C,$D,$A,$X,27,20,0x455a14ed); + &R1( 0,$A,$B,$C,$D,$X,28, 5,0xa9e3e905); + &R1( 0,$D,$A,$B,$C,$X,29, 9,0xfcefa3f8); + &R1( 0,$C,$D,$A,$B,$X,30,14,0x676f02d9); + &R1( 1,$B,$C,$D,$A,$X,31,20,0x8d2a4c8a); + + &comment(""); + &comment("R2 section"); + &R2( 0,-1,$A,$B,$C,$D,$X,32, 4,0xfffa3942); + &R2( 1, 0,$D,$A,$B,$C,$X,33,11,0x8771f681); + &R2( 2, 0,$C,$D,$A,$B,$X,34,16,0x6d9d6122); + &R2( 3, 0,$B,$C,$D,$A,$X,35,23,0xfde5380c); + &R2( 4, 0,$A,$B,$C,$D,$X,36, 4,0xa4beea44); + &R2( 5, 0,$D,$A,$B,$C,$X,37,11,0x4bdecfa9); + &R2( 6, 0,$C,$D,$A,$B,$X,38,16,0xf6bb4b60); + &R2( 7, 0,$B,$C,$D,$A,$X,39,23,0xbebfbc70); + &R2( 8, 0,$A,$B,$C,$D,$X,40, 4,0x289b7ec6); + &R2( 9, 0,$D,$A,$B,$C,$X,41,11,0xeaa127fa); + &R2(10, 0,$C,$D,$A,$B,$X,42,16,0xd4ef3085); + &R2(11, 0,$B,$C,$D,$A,$X,43,23,0x04881d05); + &R2(12, 0,$A,$B,$C,$D,$X,44, 4,0xd9d4d039); + &R2(13, 0,$D,$A,$B,$C,$X,45,11,0xe6db99e5); + &R2(14, 0,$C,$D,$A,$B,$X,46,16,0x1fa27cf8); + &R2(15, 1,$B,$C,$D,$A,$X,47,23,0xc4ac5665); + + &comment(""); + &comment("R3 section"); + &R3(-1,$A,$B,$C,$D,$X,48, 6,0xf4292244); + &R3( 0,$D,$A,$B,$C,$X,49,10,0x432aff97); + &R3( 0,$C,$D,$A,$B,$X,50,15,0xab9423a7); + &R3( 0,$B,$C,$D,$A,$X,51,21,0xfc93a039); + &R3( 0,$A,$B,$C,$D,$X,52, 6,0x655b59c3); + &R3( 0,$D,$A,$B,$C,$X,53,10,0x8f0ccc92); + &R3( 0,$C,$D,$A,$B,$X,54,15,0xffeff47d); + &R3( 0,$B,$C,$D,$A,$X,55,21,0x85845dd1); + &R3( 0,$A,$B,$C,$D,$X,56, 6,0x6fa87e4f); + &R3( 0,$D,$A,$B,$C,$X,57,10,0xfe2ce6e0); + &R3( 0,$C,$D,$A,$B,$X,58,15,0xa3014314); + &R3( 0,$B,$C,$D,$A,$X,59,21,0x4e0811a1); + &R3( 0,$A,$B,$C,$D,$X,60, 6,0xf7537e82); + &R3( 0,$D,$A,$B,$C,$X,61,10,0xbd3af235); + &R3( 0,$C,$D,$A,$B,$X,62,15,0x2ad7d2bb); + &R3( 2,$B,$C,$D,$A,$X,63,21,0xeb86d391); + + # &mov($tmp2,&wparam(0)); # done in the last R3 + # &mov($tmp1, &DWP( 0,$tmp2,"",0)); # done is the last R3 + + &add($A,$tmp1); + &mov($tmp1, &DWP( 4,$tmp2,"",0)); + + &add($B,$tmp1); + &mov($tmp1, &DWP( 8,$tmp2,"",0)); + + &add($C,$tmp1); + &mov($tmp1, &DWP(12,$tmp2,"",0)); + + &add($D,$tmp1); + &mov(&DWP( 0,$tmp2,"",0),$A); + + &mov(&DWP( 4,$tmp2,"",0),$B); + &mov($tmp1,&swtmp(0)) unless $normal; + + &mov(&DWP( 8,$tmp2,"",0),$C); + &mov(&DWP(12,$tmp2,"",0),$D); + + &cmp($tmp1,$X) unless $normal; # check count + &jae(&label("start")) unless $normal; + + &pop("eax"); # pop the temp variable off the stack + &pop("ebx"); + &pop("ebp"); + &pop("edi"); + &pop("esi"); + &ret(); + &function_end_B($name); + } + diff --git a/libs/openssl/crypto/md5/asm/md5-ia64.S b/libs/openssl/crypto/md5/asm/md5-ia64.S new file mode 100644 index 00000000..e7de08d4 --- /dev/null +++ b/libs/openssl/crypto/md5/asm/md5-ia64.S @@ -0,0 +1,992 @@ +/* Copyright (c) 2005 Hewlett-Packard Development Company, L.P. + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + +// Common registers are assigned as follows: +// +// COMMON +// +// t0 Const Tbl Ptr TPtr +// t1 Round Constant TRound +// t4 Block residual LenResid +// t5 Residual Data DTmp +// +// {in,out}0 Block 0 Cycle RotateM0 +// {in,out}1 Block Value 12 M12 +// {in,out}2 Block Value 8 M8 +// {in,out}3 Block Value 4 M4 +// {in,out}4 Block Value 0 M0 +// {in,out}5 Block 1 Cycle RotateM1 +// {in,out}6 Block Value 13 M13 +// {in,out}7 Block Value 9 M9 +// {in,out}8 Block Value 5 M5 +// {in,out}9 Block Value 1 M1 +// {in,out}10 Block 2 Cycle RotateM2 +// {in,out}11 Block Value 14 M14 +// {in,out}12 Block Value 10 M10 +// {in,out}13 Block Value 6 M6 +// {in,out}14 Block Value 2 M2 +// {in,out}15 Block 3 Cycle RotateM3 +// {in,out}16 Block Value 15 M15 +// {in,out}17 Block Value 11 M11 +// {in,out}18 Block Value 7 M7 +// {in,out}19 Block Value 3 M3 +// {in,out}20 Scratch Z +// {in,out}21 Scratch Y +// {in,out}22 Scratch X +// {in,out}23 Scratch W +// {in,out}24 Digest A A +// {in,out}25 Digest B B +// {in,out}26 Digest C C +// {in,out}27 Digest D D +// {in,out}28 Active Data Ptr DPtr +// in28 Dummy Value - +// out28 Dummy Value - +// bt0 Coroutine Link QUICK_RTN +// +/// These predicates are used for computing the padding block(s) and +/// are shared between the driver and digest co-routines +// +// pt0 Extra Pad Block pExtra +// pt1 Load next word pLoad +// pt2 Skip next word pSkip +// pt3 Search for Pad pNoPad +// pt4 Pad Word 0 pPad0 +// pt5 Pad Word 1 pPad1 +// pt6 Pad Word 2 pPad2 +// pt7 Pad Word 3 pPad3 + +#define DTmp r19 +#define LenResid r18 +#define QUICK_RTN b6 +#define TPtr r14 +#define TRound r15 +#define pExtra p6 +#define pLoad p7 +#define pNoPad p9 +#define pPad0 p10 +#define pPad1 p11 +#define pPad2 p12 +#define pPad3 p13 +#define pSkip p8 + +#define A_ out24 +#define B_ out25 +#define C_ out26 +#define D_ out27 +#define DPtr_ out28 +#define M0_ out4 +#define M1_ out9 +#define M10_ out12 +#define M11_ out17 +#define M12_ out1 +#define M13_ out6 +#define M14_ out11 +#define M15_ out16 +#define M2_ out14 +#define M3_ out19 +#define M4_ out3 +#define M5_ out8 +#define M6_ out13 +#define M7_ out18 +#define M8_ out2 +#define M9_ out7 +#define RotateM0_ out0 +#define RotateM1_ out5 +#define RotateM2_ out10 +#define RotateM3_ out15 +#define W_ out23 +#define X_ out22 +#define Y_ out21 +#define Z_ out20 + +#define A in24 +#define B in25 +#define C in26 +#define D in27 +#define DPtr in28 +#define M0 in4 +#define M1 in9 +#define M10 in12 +#define M11 in17 +#define M12 in1 +#define M13 in6 +#define M14 in11 +#define M15 in16 +#define M2 in14 +#define M3 in19 +#define M4 in3 +#define M5 in8 +#define M6 in13 +#define M7 in18 +#define M8 in2 +#define M9 in7 +#define RotateM0 in0 +#define RotateM1 in5 +#define RotateM2 in10 +#define RotateM3 in15 +#define W in23 +#define X in22 +#define Y in21 +#define Z in20 + +/* register stack configuration for md5_block_asm_data_order(): */ +#define MD5_NINP 3 +#define MD5_NLOC 0 +#define MD5_NOUT 29 +#define MD5_NROT 0 + +/* register stack configuration for helpers: */ +#define _NINPUTS MD5_NOUT +#define _NLOCALS 0 +#define _NOUTPUT 0 +#define _NROTATE 24 /* this must be <= _NINPUTS */ + +#if defined(_HPUX_SOURCE) && !defined(_LP64) +#define ADDP addp4 +#else +#define ADDP add +#endif + +#if defined(_HPUX_SOURCE) || defined(B_ENDIAN) +#define HOST_IS_BIG_ENDIAN +#endif + +// Macros for getting the left and right portions of little-endian words + +#define GETLW(dst, src, align) dep.z dst = src, 32 - 8 * align, 8 * align +#define GETRW(dst, src, align) extr.u dst = src, 8 * align, 32 - 8 * align + +// MD5 driver +// +// Reads an input block, then calls the digest block +// subroutine and adds the results to the accumulated +// digest. It allocates 32 outs which the subroutine +// uses as it's inputs and rotating +// registers. Initializes the round constant pointer and +// takes care of saving/restoring ar.lc +// +/// INPUT +// +// in0 Context Ptr CtxPtr0 +// in1 Input Data Ptr DPtrIn +// in2 Integral Blocks BlockCount +// rp Return Address - +// +/// CODE +// +// v2 Input Align InAlign +// t0 Shared w/digest - +// t1 Shared w/digest - +// t2 Shared w/digest - +// t3 Shared w/digest - +// t4 Shared w/digest - +// t5 Shared w/digest - +// t6 PFS Save PFSSave +// t7 ar.lc Save LCSave +// t8 Saved PR PRSave +// t9 2nd CtxPtr CtxPtr1 +// t10 Table Base CTable +// t11 Table[0] CTable0 +// t13 Accumulator A AccumA +// t14 Accumulator B AccumB +// t15 Accumulator C AccumC +// t16 Accumulator D AccumD +// pt0 Shared w/digest - +// pt1 Shared w/digest - +// pt2 Shared w/digest - +// pt3 Shared w/digest - +// pt4 Shared w/digest - +// pt5 Shared w/digest - +// pt6 Shared w/digest - +// pt7 Shared w/digest - +// pt8 Not Aligned pOff +// pt8 Blocks Left pAgain + +#define AccumA r27 +#define AccumB r28 +#define AccumC r29 +#define AccumD r30 +#define CTable r24 +#define CTable0 r25 +#define CtxPtr0 in0 +#define CtxPtr1 r23 +#define DPtrIn in1 +#define BlockCount in2 +#define InAlign r10 +#define LCSave r21 +#define PFSSave r20 +#define PRSave r22 +#define pAgain p63 +#define pOff p63 + + .text + +/* md5_block_asm_data_order(MD5_CTX *c, const void *data, size_t num) + + where: + c: a pointer to a structure of this type: + + typedef struct MD5state_st + { + MD5_LONG A,B,C,D; + MD5_LONG Nl,Nh; + MD5_LONG data[MD5_LBLOCK]; + unsigned int num; + } + MD5_CTX; + + data: a pointer to the input data (may be misaligned) + num: the number of 16-byte blocks to hash (i.e., the length + of DATA is 16*NUM. + + */ + + .type md5_block_asm_data_order, @function + .global md5_block_asm_data_order + .align 32 + .proc md5_block_asm_data_order +md5_block_asm_data_order: +.md5_block: + .prologue +{ .mmi + .save ar.pfs, PFSSave + alloc PFSSave = ar.pfs, MD5_NINP, MD5_NLOC, MD5_NOUT, MD5_NROT + ADDP CtxPtr1 = 8, CtxPtr0 + mov CTable = ip +} +{ .mmi + ADDP DPtrIn = 0, DPtrIn + ADDP CtxPtr0 = 0, CtxPtr0 + .save ar.lc, LCSave + mov LCSave = ar.lc +} +;; +{ .mmi + add CTable = .md5_tbl_data_order#-.md5_block#, CTable + and InAlign = 0x3, DPtrIn +} + +{ .mmi + ld4 AccumA = [CtxPtr0], 4 + ld4 AccumC = [CtxPtr1], 4 + .save pr, PRSave + mov PRSave = pr + .body +} +;; +{ .mmi + ld4 AccumB = [CtxPtr0] + ld4 AccumD = [CtxPtr1] + dep DPtr_ = 0, DPtrIn, 0, 2 +} ;; +#ifdef HOST_IS_BIG_ENDIAN + rum psr.be;; // switch to little-endian +#endif +{ .mmb + ld4 CTable0 = [CTable], 4 + cmp.ne pOff, p0 = 0, InAlign +(pOff) br.cond.spnt.many .md5_unaligned +} ;; + +// The FF load/compute loop rotates values three times, so that +// loading into M12 here produces the M0 value, M13 -> M1, etc. + +.md5_block_loop0: +{ .mmi + ld4 M12_ = [DPtr_], 4 + mov TPtr = CTable + mov TRound = CTable0 +} ;; +{ .mmi + ld4 M13_ = [DPtr_], 4 + mov A_ = AccumA + mov B_ = AccumB +} ;; +{ .mmi + ld4 M14_ = [DPtr_], 4 + mov C_ = AccumC + mov D_ = AccumD +} ;; +{ .mmb + ld4 M15_ = [DPtr_], 4 + add BlockCount = -1, BlockCount + br.call.sptk.many QUICK_RTN = md5_digest_block0 +} ;; + +// Now, we add the new digest values and do some clean-up +// before checking if there's another full block to process + +{ .mmi + add AccumA = AccumA, A_ + add AccumB = AccumB, B_ + cmp.ne pAgain, p0 = 0, BlockCount +} +{ .mib + add AccumC = AccumC, C_ + add AccumD = AccumD, D_ +(pAgain) br.cond.dptk.many .md5_block_loop0 +} ;; + +.md5_exit: +#ifdef HOST_IS_BIG_ENDIAN + sum psr.be;; // switch back to big-endian mode +#endif +{ .mmi + st4 [CtxPtr0] = AccumB, -4 + st4 [CtxPtr1] = AccumD, -4 + mov pr = PRSave, 0x1ffff ;; +} +{ .mmi + st4 [CtxPtr0] = AccumA + st4 [CtxPtr1] = AccumC + mov ar.lc = LCSave +} ;; +{ .mib + mov ar.pfs = PFSSave + br.ret.sptk.few rp +} ;; + +#define MD5UNALIGNED(offset) \ +.md5_process##offset: \ +{ .mib ; \ + nop 0x0 ; \ + GETRW(DTmp, DTmp, offset) ; \ +} ;; \ +.md5_block_loop##offset: \ +{ .mmi ; \ + ld4 Y_ = [DPtr_], 4 ; \ + mov TPtr = CTable ; \ + mov TRound = CTable0 ; \ +} ;; \ +{ .mmi ; \ + ld4 M13_ = [DPtr_], 4 ; \ + mov A_ = AccumA ; \ + mov B_ = AccumB ; \ +} ;; \ +{ .mii ; \ + ld4 M14_ = [DPtr_], 4 ; \ + GETLW(W_, Y_, offset) ; \ + mov C_ = AccumC ; \ +} \ +{ .mmi ; \ + mov D_ = AccumD ;; \ + or M12_ = W_, DTmp ; \ + GETRW(DTmp, Y_, offset) ; \ +} \ +{ .mib ; \ + ld4 M15_ = [DPtr_], 4 ; \ + add BlockCount = -1, BlockCount ; \ + br.call.sptk.many QUICK_RTN = md5_digest_block##offset; \ +} ;; \ +{ .mmi ; \ + add AccumA = AccumA, A_ ; \ + add AccumB = AccumB, B_ ; \ + cmp.ne pAgain, p0 = 0, BlockCount ; \ +} \ +{ .mib ; \ + add AccumC = AccumC, C_ ; \ + add AccumD = AccumD, D_ ; \ +(pAgain) br.cond.dptk.many .md5_block_loop##offset ; \ +} ;; \ +{ .mib ; \ + nop 0x0 ; \ + nop 0x0 ; \ + br.cond.sptk.many .md5_exit ; \ +} ;; + + .align 32 +.md5_unaligned: +// +// Because variable shifts are expensive, we special case each of +// the four alignements. In practice, this won't hurt too much +// since only one working set of code will be loaded. +// +{ .mib + ld4 DTmp = [DPtr_], 4 + cmp.eq pOff, p0 = 1, InAlign +(pOff) br.cond.dpnt.many .md5_process1 +} ;; +{ .mib + cmp.eq pOff, p0 = 2, InAlign + nop 0x0 +(pOff) br.cond.dpnt.many .md5_process2 +} ;; + MD5UNALIGNED(3) + MD5UNALIGNED(1) + MD5UNALIGNED(2) + + .endp md5_block_asm_data_order + + +// MD5 Perform the F function and load +// +// Passed the first 4 words (M0 - M3) and initial (A, B, C, D) values, +// computes the FF() round of functions, then branches to the common +// digest code to finish up with GG(), HH, and II(). +// +// INPUT +// +// rp Return Address - +// +// CODE +// +// v0 PFS bit bucket PFS +// v1 Loop Trip Count LTrip +// pt0 Load next word pMore + +/* For F round: */ +#define LTrip r9 +#define PFS r8 +#define pMore p6 + +/* For GHI rounds: */ +#define T r9 +#define U r10 +#define V r11 + +#define COMPUTE(a, b, s, M, R) \ +{ \ + .mii ; \ + ld4 TRound = [TPtr], 4 ; \ + dep.z Y = Z, 32, 32 ;; \ + shrp Z = Z, Y, 64 - s ; \ +} ;; \ +{ \ + .mmi ; \ + add a = Z, b ; \ + mov R = M ; \ + nop 0x0 ; \ +} ;; + +#define LOOP(a, b, s, M, R, label) \ +{ .mii ; \ + ld4 TRound = [TPtr], 4 ; \ + dep.z Y = Z, 32, 32 ;; \ + shrp Z = Z, Y, 64 - s ; \ +} ;; \ +{ .mib ; \ + add a = Z, b ; \ + mov R = M ; \ + br.ctop.sptk.many label ; \ +} ;; + +// G(B, C, D) = (B & D) | (C & ~D) + +#define G(a, b, c, d, M) \ +{ .mmi ; \ + add Z = M, TRound ; \ + and Y = b, d ; \ + andcm X = c, d ; \ +} ;; \ +{ .mii ; \ + add Z = Z, a ; \ + or Y = Y, X ;; \ + add Z = Z, Y ; \ +} ;; + +// H(B, C, D) = B ^ C ^ D + +#define H(a, b, c, d, M) \ +{ .mmi ; \ + add Z = M, TRound ; \ + xor Y = b, c ; \ + nop 0x0 ; \ +} ;; \ +{ .mii ; \ + add Z = Z, a ; \ + xor Y = Y, d ;; \ + add Z = Z, Y ; \ +} ;; + +// I(B, C, D) = C ^ (B | ~D) +// +// However, since we have an andcm operator, we use the fact that +// +// Y ^ Z == ~Y ^ ~Z +// +// to rewrite the expression as +// +// I(B, C, D) = ~C ^ (~B & D) + +#define I(a, b, c, d, M) \ +{ .mmi ; \ + add Z = M, TRound ; \ + andcm Y = d, b ; \ + andcm X = -1, c ; \ +} ;; \ +{ .mii ; \ + add Z = Z, a ; \ + xor Y = Y, X ;; \ + add Z = Z, Y ; \ +} ;; + +#define GG4(label) \ + G(A, B, C, D, M0) \ + COMPUTE(A, B, 5, M0, RotateM0) \ + G(D, A, B, C, M1) \ + COMPUTE(D, A, 9, M1, RotateM1) \ + G(C, D, A, B, M2) \ + COMPUTE(C, D, 14, M2, RotateM2) \ + G(B, C, D, A, M3) \ + LOOP(B, C, 20, M3, RotateM3, label) + +#define HH4(label) \ + H(A, B, C, D, M0) \ + COMPUTE(A, B, 4, M0, RotateM0) \ + H(D, A, B, C, M1) \ + COMPUTE(D, A, 11, M1, RotateM1) \ + H(C, D, A, B, M2) \ + COMPUTE(C, D, 16, M2, RotateM2) \ + H(B, C, D, A, M3) \ + LOOP(B, C, 23, M3, RotateM3, label) + +#define II4(label) \ + I(A, B, C, D, M0) \ + COMPUTE(A, B, 6, M0, RotateM0) \ + I(D, A, B, C, M1) \ + COMPUTE(D, A, 10, M1, RotateM1) \ + I(C, D, A, B, M2) \ + COMPUTE(C, D, 15, M2, RotateM2) \ + I(B, C, D, A, M3) \ + LOOP(B, C, 21, M3, RotateM3, label) + +#define FFLOAD(a, b, c, d, M, N, s) \ +{ .mii ; \ +(pMore) ld4 N = [DPtr], 4 ; \ + add Z = M, TRound ; \ + and Y = c, b ; \ +} \ +{ .mmi ; \ + andcm X = d, b ;; \ + add Z = Z, a ; \ + or Y = Y, X ; \ +} ;; \ +{ .mii ; \ + ld4 TRound = [TPtr], 4 ; \ + add Z = Z, Y ;; \ + dep.z Y = Z, 32, 32 ; \ +} ;; \ +{ .mii ; \ + nop 0x0 ; \ + shrp Z = Z, Y, 64 - s ;; \ + add a = Z, b ; \ +} ;; + +#define FFLOOP(a, b, c, d, M, N, s, dest) \ +{ .mii ; \ +(pMore) ld4 N = [DPtr], 4 ; \ + add Z = M, TRound ; \ + and Y = c, b ; \ +} \ +{ .mmi ; \ + andcm X = d, b ;; \ + add Z = Z, a ; \ + or Y = Y, X ; \ +} ;; \ +{ .mii ; \ + ld4 TRound = [TPtr], 4 ; \ + add Z = Z, Y ;; \ + dep.z Y = Z, 32, 32 ; \ +} ;; \ +{ .mii ; \ + nop 0x0 ; \ + shrp Z = Z, Y, 64 - s ;; \ + add a = Z, b ; \ +} \ +{ .mib ; \ + cmp.ne pMore, p0 = 0, LTrip ; \ + add LTrip = -1, LTrip ; \ + br.ctop.dptk.many dest ; \ +} ;; + + .type md5_digest_block0, @function + .align 32 + + .proc md5_digest_block0 + .prologue +md5_digest_block0: + .altrp QUICK_RTN + .body +{ .mmi + alloc PFS = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE + mov LTrip = 2 + mov ar.lc = 3 +} ;; +{ .mii + cmp.eq pMore, p0 = r0, r0 + mov ar.ec = 0 + nop 0x0 +} ;; + +.md5_FF_round0: + FFLOAD(A, B, C, D, M12, RotateM0, 7) + FFLOAD(D, A, B, C, M13, RotateM1, 12) + FFLOAD(C, D, A, B, M14, RotateM2, 17) + FFLOOP(B, C, D, A, M15, RotateM3, 22, .md5_FF_round0) + // + // !!! Fall through to md5_digest_GHI + // + .endp md5_digest_block0 + + .type md5_digest_GHI, @function + .align 32 + + .proc md5_digest_GHI + .prologue + .regstk _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE +md5_digest_GHI: + .altrp QUICK_RTN + .body +// +// The following sequence shuffles the block counstants round for the +// next round: +// +// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 +// 1 6 11 0 5 10 14 4 9 14 3 8 13 2 7 12 +// +{ .mmi + mov Z = M0 + mov Y = M15 + mov ar.lc = 3 +} +{ .mmi + mov X = M2 + mov W = M9 + mov V = M4 +} ;; + +{ .mmi + mov M0 = M1 + mov M15 = M12 + mov ar.ec = 1 +} +{ .mmi + mov M2 = M11 + mov M9 = M14 + mov M4 = M5 +} ;; + +{ .mmi + mov M1 = M6 + mov M12 = M13 + mov U = M3 +} +{ .mmi + mov M11 = M8 + mov M14 = M7 + mov M5 = M10 +} ;; + +{ .mmi + mov M6 = Y + mov M13 = X + mov M3 = Z +} +{ .mmi + mov M8 = W + mov M7 = V + mov M10 = U +} ;; + +.md5_GG_round: + GG4(.md5_GG_round) + +// The following sequence shuffles the block constants round for the +// next round: +// +// 1 6 11 0 5 10 14 4 9 14 3 8 13 2 7 12 +// 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2 + +{ .mmi + mov Z = M0 + mov Y = M1 + mov ar.lc = 3 +} +{ .mmi + mov X = M3 + mov W = M5 + mov V = M6 +} ;; + +{ .mmi + mov M0 = M4 + mov M1 = M11 + mov ar.ec = 1 +} +{ .mmi + mov M3 = M9 + mov U = M8 + mov T = M13 +} ;; + +{ .mmi + mov M4 = Z + mov M11 = Y + mov M5 = M7 +} +{ .mmi + mov M6 = M14 + mov M8 = M12 + mov M13 = M15 +} ;; + +{ .mmi + mov M7 = W + mov M14 = V + nop 0x0 +} +{ .mmi + mov M9 = X + mov M12 = U + mov M15 = T +} ;; + +.md5_HH_round: + HH4(.md5_HH_round) + +// The following sequence shuffles the block constants round for the +// next round: +// +// 5 8 11 14 1 4 7 10 13 0 3 6 9 12 15 2 +// 0 7 14 5 12 3 10 1 8 15 6 13 4 11 2 9 + +{ .mmi + mov Z = M0 + mov Y = M15 + mov ar.lc = 3 +} +{ .mmi + mov X = M10 + mov W = M1 + mov V = M4 +} ;; + +{ .mmi + mov M0 = M9 + mov M15 = M12 + mov ar.ec = 1 +} +{ .mmi + mov M10 = M11 + mov M1 = M6 + mov M4 = M13 +} ;; + +{ .mmi + mov M9 = M14 + mov M12 = M5 + mov U = M3 +} +{ .mmi + mov M11 = M8 + mov M6 = M7 + mov M13 = M2 +} ;; + +{ .mmi + mov M14 = Y + mov M5 = X + mov M3 = Z +} +{ .mmi + mov M8 = W + mov M7 = V + mov M2 = U +} ;; + +.md5_II_round: + II4(.md5_II_round) + +{ .mib + nop 0x0 + nop 0x0 + br.ret.sptk.many QUICK_RTN +} ;; + + .endp md5_digest_GHI + +#define FFLOADU(a, b, c, d, M, P, N, s, offset) \ +{ .mii ; \ +(pMore) ld4 N = [DPtr], 4 ; \ + add Z = M, TRound ; \ + and Y = c, b ; \ +} \ +{ .mmi ; \ + andcm X = d, b ;; \ + add Z = Z, a ; \ + or Y = Y, X ; \ +} ;; \ +{ .mii ; \ + ld4 TRound = [TPtr], 4 ; \ + GETLW(W, P, offset) ; \ + add Z = Z, Y ; \ +} ;; \ +{ .mii ; \ + or W = W, DTmp ; \ + dep.z Y = Z, 32, 32 ;; \ + shrp Z = Z, Y, 64 - s ; \ +} ;; \ +{ .mii ; \ + add a = Z, b ; \ + GETRW(DTmp, P, offset) ; \ + mov P = W ; \ +} ;; + +#define FFLOOPU(a, b, c, d, M, P, N, s, offset) \ +{ .mii ; \ +(pMore) ld4 N = [DPtr], 4 ; \ + add Z = M, TRound ; \ + and Y = c, b ; \ +} \ +{ .mmi ; \ + andcm X = d, b ;; \ + add Z = Z, a ; \ + or Y = Y, X ; \ +} ;; \ +{ .mii ; \ + ld4 TRound = [TPtr], 4 ; \ +(pMore) GETLW(W, P, offset) ; \ + add Z = Z, Y ; \ +} ;; \ +{ .mii ; \ +(pMore) or W = W, DTmp ; \ + dep.z Y = Z, 32, 32 ;; \ + shrp Z = Z, Y, 64 - s ; \ +} ;; \ +{ .mii ; \ + add a = Z, b ; \ +(pMore) GETRW(DTmp, P, offset) ; \ +(pMore) mov P = W ; \ +} \ +{ .mib ; \ + cmp.ne pMore, p0 = 0, LTrip ; \ + add LTrip = -1, LTrip ; \ + br.ctop.sptk.many .md5_FF_round##offset ; \ +} ;; + +#define MD5FBLOCK(offset) \ + .type md5_digest_block##offset, @function ; \ + \ + .align 32 ; \ + .proc md5_digest_block##offset ; \ + .prologue ; \ + .altrp QUICK_RTN ; \ + .body ; \ +md5_digest_block##offset: \ +{ .mmi ; \ + alloc PFS = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE ; \ + mov LTrip = 2 ; \ + mov ar.lc = 3 ; \ +} ;; \ +{ .mii ; \ + cmp.eq pMore, p0 = r0, r0 ; \ + mov ar.ec = 0 ; \ + nop 0x0 ; \ +} ;; \ + \ + .pred.rel "mutex", pLoad, pSkip ; \ +.md5_FF_round##offset: \ + FFLOADU(A, B, C, D, M12, M13, RotateM0, 7, offset) \ + FFLOADU(D, A, B, C, M13, M14, RotateM1, 12, offset) \ + FFLOADU(C, D, A, B, M14, M15, RotateM2, 17, offset) \ + FFLOOPU(B, C, D, A, M15, RotateM0, RotateM3, 22, offset) \ + \ +{ .mib ; \ + nop 0x0 ; \ + nop 0x0 ; \ + br.cond.sptk.many md5_digest_GHI ; \ +} ;; \ + .endp md5_digest_block##offset + +MD5FBLOCK(1) +MD5FBLOCK(2) +MD5FBLOCK(3) + + .align 64 + .type md5_constants, @object +md5_constants: +.md5_tbl_data_order: // To ensure little-endian data + // order, code as bytes. + data1 0x78, 0xa4, 0x6a, 0xd7 // 0 + data1 0x56, 0xb7, 0xc7, 0xe8 // 1 + data1 0xdb, 0x70, 0x20, 0x24 // 2 + data1 0xee, 0xce, 0xbd, 0xc1 // 3 + data1 0xaf, 0x0f, 0x7c, 0xf5 // 4 + data1 0x2a, 0xc6, 0x87, 0x47 // 5 + data1 0x13, 0x46, 0x30, 0xa8 // 6 + data1 0x01, 0x95, 0x46, 0xfd // 7 + data1 0xd8, 0x98, 0x80, 0x69 // 8 + data1 0xaf, 0xf7, 0x44, 0x8b // 9 + data1 0xb1, 0x5b, 0xff, 0xff // 10 + data1 0xbe, 0xd7, 0x5c, 0x89 // 11 + data1 0x22, 0x11, 0x90, 0x6b // 12 + data1 0x93, 0x71, 0x98, 0xfd // 13 + data1 0x8e, 0x43, 0x79, 0xa6 // 14 + data1 0x21, 0x08, 0xb4, 0x49 // 15 + data1 0x62, 0x25, 0x1e, 0xf6 // 16 + data1 0x40, 0xb3, 0x40, 0xc0 // 17 + data1 0x51, 0x5a, 0x5e, 0x26 // 18 + data1 0xaa, 0xc7, 0xb6, 0xe9 // 19 + data1 0x5d, 0x10, 0x2f, 0xd6 // 20 + data1 0x53, 0x14, 0x44, 0x02 // 21 + data1 0x81, 0xe6, 0xa1, 0xd8 // 22 + data1 0xc8, 0xfb, 0xd3, 0xe7 // 23 + data1 0xe6, 0xcd, 0xe1, 0x21 // 24 + data1 0xd6, 0x07, 0x37, 0xc3 // 25 + data1 0x87, 0x0d, 0xd5, 0xf4 // 26 + data1 0xed, 0x14, 0x5a, 0x45 // 27 + data1 0x05, 0xe9, 0xe3, 0xa9 // 28 + data1 0xf8, 0xa3, 0xef, 0xfc // 29 + data1 0xd9, 0x02, 0x6f, 0x67 // 30 + data1 0x8a, 0x4c, 0x2a, 0x8d // 31 + data1 0x42, 0x39, 0xfa, 0xff // 32 + data1 0x81, 0xf6, 0x71, 0x87 // 33 + data1 0x22, 0x61, 0x9d, 0x6d // 34 + data1 0x0c, 0x38, 0xe5, 0xfd // 35 + data1 0x44, 0xea, 0xbe, 0xa4 // 36 + data1 0xa9, 0xcf, 0xde, 0x4b // 37 + data1 0x60, 0x4b, 0xbb, 0xf6 // 38 + data1 0x70, 0xbc, 0xbf, 0xbe // 39 + data1 0xc6, 0x7e, 0x9b, 0x28 // 40 + data1 0xfa, 0x27, 0xa1, 0xea // 41 + data1 0x85, 0x30, 0xef, 0xd4 // 42 + data1 0x05, 0x1d, 0x88, 0x04 // 43 + data1 0x39, 0xd0, 0xd4, 0xd9 // 44 + data1 0xe5, 0x99, 0xdb, 0xe6 // 45 + data1 0xf8, 0x7c, 0xa2, 0x1f // 46 + data1 0x65, 0x56, 0xac, 0xc4 // 47 + data1 0x44, 0x22, 0x29, 0xf4 // 48 + data1 0x97, 0xff, 0x2a, 0x43 // 49 + data1 0xa7, 0x23, 0x94, 0xab // 50 + data1 0x39, 0xa0, 0x93, 0xfc // 51 + data1 0xc3, 0x59, 0x5b, 0x65 // 52 + data1 0x92, 0xcc, 0x0c, 0x8f // 53 + data1 0x7d, 0xf4, 0xef, 0xff // 54 + data1 0xd1, 0x5d, 0x84, 0x85 // 55 + data1 0x4f, 0x7e, 0xa8, 0x6f // 56 + data1 0xe0, 0xe6, 0x2c, 0xfe // 57 + data1 0x14, 0x43, 0x01, 0xa3 // 58 + data1 0xa1, 0x11, 0x08, 0x4e // 59 + data1 0x82, 0x7e, 0x53, 0xf7 // 60 + data1 0x35, 0xf2, 0x3a, 0xbd // 61 + data1 0xbb, 0xd2, 0xd7, 0x2a // 62 + data1 0x91, 0xd3, 0x86, 0xeb // 63 +.size md5_constants#,64*4 diff --git a/libs/openssl/crypto/md5/asm/md5-x86_64.pl b/libs/openssl/crypto/md5/asm/md5-x86_64.pl new file mode 100755 index 00000000..381bf77e --- /dev/null +++ b/libs/openssl/crypto/md5/asm/md5-x86_64.pl @@ -0,0 +1,370 @@ +#!/usr/bin/perl -w +# +# MD5 optimized for AMD64. +# +# Author: Marc Bevand +# Licence: I hereby disclaim the copyright on this code and place it +# in the public domain. +# + +use strict; + +my $code; + +# round1_step() does: +# dst = x + ((dst + F(x,y,z) + X[k] + T_i) <<< s) +# %r10d = X[k_next] +# %r11d = z' (copy of z for the next step) +# Each round1_step() takes about 5.3 clocks (9 instructions, 1.7 IPC) +sub round1_step +{ + my ($pos, $dst, $x, $y, $z, $k_next, $T_i, $s) = @_; + $code .= " mov 0*4(%rsi), %r10d /* (NEXT STEP) X[0] */\n" if ($pos == -1); + $code .= " mov %edx, %r11d /* (NEXT STEP) z' = %edx */\n" if ($pos == -1); + $code .= <A + mov 1*4(%rbp), %ebx # ebx = ctx->B + mov 2*4(%rbp), %ecx # ecx = ctx->C + mov 3*4(%rbp), %edx # edx = ctx->D + # end is 'rdi' + # ptr is 'rsi' + # A is 'eax' + # B is 'ebx' + # C is 'ecx' + # D is 'edx' + + cmp %rdi, %rsi # cmp end with ptr + je .Lend # jmp if ptr == end + + # BEGIN of loop over 16-word blocks +.Lloop: # save old values of A, B, C, D + mov %eax, %r8d + mov %ebx, %r9d + mov %ecx, %r14d + mov %edx, %r15d +EOF +round1_step(-1,'%eax','%ebx','%ecx','%edx', '1','0xd76aa478', '7'); +round1_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xe8c7b756','12'); +round1_step( 0,'%ecx','%edx','%eax','%ebx', '3','0x242070db','17'); +round1_step( 0,'%ebx','%ecx','%edx','%eax', '4','0xc1bdceee','22'); +round1_step( 0,'%eax','%ebx','%ecx','%edx', '5','0xf57c0faf', '7'); +round1_step( 0,'%edx','%eax','%ebx','%ecx', '6','0x4787c62a','12'); +round1_step( 0,'%ecx','%edx','%eax','%ebx', '7','0xa8304613','17'); +round1_step( 0,'%ebx','%ecx','%edx','%eax', '8','0xfd469501','22'); +round1_step( 0,'%eax','%ebx','%ecx','%edx', '9','0x698098d8', '7'); +round1_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8b44f7af','12'); +round1_step( 0,'%ecx','%edx','%eax','%ebx','11','0xffff5bb1','17'); +round1_step( 0,'%ebx','%ecx','%edx','%eax','12','0x895cd7be','22'); +round1_step( 0,'%eax','%ebx','%ecx','%edx','13','0x6b901122', '7'); +round1_step( 0,'%edx','%eax','%ebx','%ecx','14','0xfd987193','12'); +round1_step( 0,'%ecx','%edx','%eax','%ebx','15','0xa679438e','17'); +round1_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x49b40821','22'); + +round2_step(-1,'%eax','%ebx','%ecx','%edx', '6','0xf61e2562', '5'); +round2_step( 0,'%edx','%eax','%ebx','%ecx','11','0xc040b340', '9'); +round2_step( 0,'%ecx','%edx','%eax','%ebx', '0','0x265e5a51','14'); +round2_step( 0,'%ebx','%ecx','%edx','%eax', '5','0xe9b6c7aa','20'); +round2_step( 0,'%eax','%ebx','%ecx','%edx','10','0xd62f105d', '5'); +round2_step( 0,'%edx','%eax','%ebx','%ecx','15', '0x2441453', '9'); +round2_step( 0,'%ecx','%edx','%eax','%ebx', '4','0xd8a1e681','14'); +round2_step( 0,'%ebx','%ecx','%edx','%eax', '9','0xe7d3fbc8','20'); +round2_step( 0,'%eax','%ebx','%ecx','%edx','14','0x21e1cde6', '5'); +round2_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xc33707d6', '9'); +round2_step( 0,'%ecx','%edx','%eax','%ebx', '8','0xf4d50d87','14'); +round2_step( 0,'%ebx','%ecx','%edx','%eax','13','0x455a14ed','20'); +round2_step( 0,'%eax','%ebx','%ecx','%edx', '2','0xa9e3e905', '5'); +round2_step( 0,'%edx','%eax','%ebx','%ecx', '7','0xfcefa3f8', '9'); +round2_step( 0,'%ecx','%edx','%eax','%ebx','12','0x676f02d9','14'); +round2_step( 1,'%ebx','%ecx','%edx','%eax', '0','0x8d2a4c8a','20'); + +round3_step(-1,'%eax','%ebx','%ecx','%edx', '8','0xfffa3942', '4'); +round3_step( 0,'%edx','%eax','%ebx','%ecx','11','0x8771f681','11'); +round3_step( 0,'%ecx','%edx','%eax','%ebx','14','0x6d9d6122','16'); +round3_step( 0,'%ebx','%ecx','%edx','%eax', '1','0xfde5380c','23'); +round3_step( 0,'%eax','%ebx','%ecx','%edx', '4','0xa4beea44', '4'); +round3_step( 0,'%edx','%eax','%ebx','%ecx', '7','0x4bdecfa9','11'); +round3_step( 0,'%ecx','%edx','%eax','%ebx','10','0xf6bb4b60','16'); +round3_step( 0,'%ebx','%ecx','%edx','%eax','13','0xbebfbc70','23'); +round3_step( 0,'%eax','%ebx','%ecx','%edx', '0','0x289b7ec6', '4'); +round3_step( 0,'%edx','%eax','%ebx','%ecx', '3','0xeaa127fa','11'); +round3_step( 0,'%ecx','%edx','%eax','%ebx', '6','0xd4ef3085','16'); +round3_step( 0,'%ebx','%ecx','%edx','%eax', '9', '0x4881d05','23'); +round3_step( 0,'%eax','%ebx','%ecx','%edx','12','0xd9d4d039', '4'); +round3_step( 0,'%edx','%eax','%ebx','%ecx','15','0xe6db99e5','11'); +round3_step( 0,'%ecx','%edx','%eax','%ebx', '2','0x1fa27cf8','16'); +round3_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xc4ac5665','23'); + +round4_step(-1,'%eax','%ebx','%ecx','%edx', '7','0xf4292244', '6'); +round4_step( 0,'%edx','%eax','%ebx','%ecx','14','0x432aff97','10'); +round4_step( 0,'%ecx','%edx','%eax','%ebx', '5','0xab9423a7','15'); +round4_step( 0,'%ebx','%ecx','%edx','%eax','12','0xfc93a039','21'); +round4_step( 0,'%eax','%ebx','%ecx','%edx', '3','0x655b59c3', '6'); +round4_step( 0,'%edx','%eax','%ebx','%ecx','10','0x8f0ccc92','10'); +round4_step( 0,'%ecx','%edx','%eax','%ebx', '1','0xffeff47d','15'); +round4_step( 0,'%ebx','%ecx','%edx','%eax', '8','0x85845dd1','21'); +round4_step( 0,'%eax','%ebx','%ecx','%edx','15','0x6fa87e4f', '6'); +round4_step( 0,'%edx','%eax','%ebx','%ecx', '6','0xfe2ce6e0','10'); +round4_step( 0,'%ecx','%edx','%eax','%ebx','13','0xa3014314','15'); +round4_step( 0,'%ebx','%ecx','%edx','%eax', '4','0x4e0811a1','21'); +round4_step( 0,'%eax','%ebx','%ecx','%edx','11','0xf7537e82', '6'); +round4_step( 0,'%edx','%eax','%ebx','%ecx', '2','0xbd3af235','10'); +round4_step( 0,'%ecx','%edx','%eax','%ebx', '9','0x2ad7d2bb','15'); +round4_step( 1,'%ebx','%ecx','%edx','%eax', '0','0xeb86d391','21'); +$code .= <A = A + mov %ebx, 1*4(%rbp) # ctx->B = B + mov %ecx, 2*4(%rbp) # ctx->C = C + mov %edx, 3*4(%rbp) # ctx->D = D + + mov (%rsp),%r15 + mov 8(%rsp),%r14 + mov 16(%rsp),%r12 + mov 24(%rsp),%rbx + mov 32(%rsp),%rbp + add \$40,%rsp +.Lepilogue: + ret +.size md5_block_asm_data_order,.-md5_block_asm_data_order +EOF + +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +my $rec="%rcx"; +my $frame="%rdx"; +my $context="%r8"; +my $disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type se_handler,\@abi-omnipotent +.align 16 +se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + lea .Lprologue(%rip),%r10 + cmp %r10,%rbx # context->Rip<.Lprologue + jb .Lin_prologue + + mov 152($context),%rax # pull context->Rsp + + lea .Lepilogue(%rip),%r10 + cmp %r10,%rbx # context->Rip>=.Lepilogue + jae .Lin_prologue + + lea 40(%rax),%rax + + mov -8(%rax),%rbp + mov -16(%rax),%rbx + mov -24(%rax),%r12 + mov -32(%rax),%r14 + mov -40(%rax),%r15 + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + +.Lin_prologue: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$154,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size se_handler,.-se_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_md5_block_asm_data_order + .rva .LSEH_end_md5_block_asm_data_order + .rva .LSEH_info_md5_block_asm_data_order + +.section .xdata +.align 8 +.LSEH_info_md5_block_asm_data_order: + .byte 9,0,0,0 + .rva se_handler +___ +} + +print $code; + +close STDOUT; diff --git a/libs/openssl/crypto/md5/md5.c b/libs/openssl/crypto/md5/md5.c new file mode 100644 index 00000000..f0282c50 --- /dev/null +++ b/libs/openssl/crypto/md5/md5.c @@ -0,0 +1,121 @@ +/* crypto/md5/md5.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#define BUFSIZE 1024*16 + +void do_fp(FILE *f); +void pt(unsigned char *md); +#if !defined(_OSD_POSIX) && !defined(__DJGPP__) +int read(int, void *, unsigned int); +#endif + +int main(int argc, char **argv) +{ + int i, err = 0; + FILE *IN; + + if (argc == 1) { + do_fp(stdin); + } else { + for (i = 1; i < argc; i++) { + IN = fopen(argv[i], "r"); + if (IN == NULL) { + perror(argv[i]); + err++; + continue; + } + printf("MD5(%s)= ", argv[i]); + do_fp(IN); + fclose(IN); + } + } + exit(err); +} + +void do_fp(FILE *f) +{ + MD5_CTX c; + unsigned char md[MD5_DIGEST_LENGTH]; + int fd; + int i; + static unsigned char buf[BUFSIZE]; + + fd = fileno(f); + MD5_Init(&c); + for (;;) { + i = read(fd, buf, BUFSIZE); + if (i <= 0) + break; + MD5_Update(&c, buf, (unsigned long)i); + } + MD5_Final(&(md[0]), &c); + pt(md); +} + +void pt(unsigned char *md) +{ + int i; + + for (i = 0; i < MD5_DIGEST_LENGTH; i++) + printf("%02x", md[i]); + printf("\n"); +} diff --git a/libs/openssl/crypto/md5/md5.h b/libs/openssl/crypto/md5/md5.h new file mode 100644 index 00000000..2659038a --- /dev/null +++ b/libs/openssl/crypto/md5/md5.h @@ -0,0 +1,119 @@ +/* crypto/md5/md5.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_MD5_H +# define HEADER_MD5_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_MD5 +# error MD5 is disabled. +# endif + +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! MD5_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! MD5_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +# if defined(__LP32__) +# define MD5_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define MD5_LONG unsigned long +# define MD5_LONG_LOG2 3 +/* + * _CRAY note. I could declare short, but I have no idea what impact + * does it have on performance on none-T3E machines. I could declare + * int, but at least on C90 sizeof(int) can be chosen at compile time. + * So I've chosen long... + * + */ +# else +# define MD5_LONG unsigned int +# endif + +# define MD5_CBLOCK 64 +# define MD5_LBLOCK (MD5_CBLOCK/4) +# define MD5_DIGEST_LENGTH 16 + +typedef struct MD5state_st { + MD5_LONG A, B, C, D; + MD5_LONG Nl, Nh; + MD5_LONG data[MD5_LBLOCK]; + unsigned int num; +} MD5_CTX; + +# ifdef OPENSSL_FIPS +int private_MD5_Init(MD5_CTX *c); +# endif +int MD5_Init(MD5_CTX *c); +int MD5_Update(MD5_CTX *c, const void *data, size_t len); +int MD5_Final(unsigned char *md, MD5_CTX *c); +unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md); +void MD5_Transform(MD5_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/md5/md5_dgst.c b/libs/openssl/crypto/md5/md5_dgst.c new file mode 100644 index 00000000..2b519467 --- /dev/null +++ b/libs/openssl/crypto/md5/md5_dgst.c @@ -0,0 +1,216 @@ +/* crypto/md5/md5_dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "md5_locl.h" +#include +#include + +const char MD5_version[] = "MD5" OPENSSL_VERSION_PTEXT; + +/* + * Implemented from RFC1321 The MD5 Message-Digest Algorithm + */ + +#define INIT_DATA_A (unsigned long)0x67452301L +#define INIT_DATA_B (unsigned long)0xefcdab89L +#define INIT_DATA_C (unsigned long)0x98badcfeL +#define INIT_DATA_D (unsigned long)0x10325476L + +fips_md_init(MD5) +{ + memset(c, 0, sizeof(*c)); + c->A = INIT_DATA_A; + c->B = INIT_DATA_B; + c->C = INIT_DATA_C; + c->D = INIT_DATA_D; + return 1; +} + +#ifndef md5_block_data_order +# ifdef X +# undef X +# endif +void md5_block_data_order(MD5_CTX *c, const void *data_, size_t num) +{ + const unsigned char *data = data_; + register unsigned MD32_REG_T A, B, C, D, l; +# ifndef MD32_XARRAY + /* See comment in crypto/sha/sha_locl.h for details. */ + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; +# define X(i) XX##i +# else + MD5_LONG XX[MD5_LBLOCK]; +# define X(i) XX[i] +# endif + + A = c->A; + B = c->B; + C = c->C; + D = c->D; + + for (; num--;) { + HOST_c2l(data, l); + X(0) = l; + HOST_c2l(data, l); + X(1) = l; + /* Round 0 */ + R0(A, B, C, D, X(0), 7, 0xd76aa478L); + HOST_c2l(data, l); + X(2) = l; + R0(D, A, B, C, X(1), 12, 0xe8c7b756L); + HOST_c2l(data, l); + X(3) = l; + R0(C, D, A, B, X(2), 17, 0x242070dbL); + HOST_c2l(data, l); + X(4) = l; + R0(B, C, D, A, X(3), 22, 0xc1bdceeeL); + HOST_c2l(data, l); + X(5) = l; + R0(A, B, C, D, X(4), 7, 0xf57c0fafL); + HOST_c2l(data, l); + X(6) = l; + R0(D, A, B, C, X(5), 12, 0x4787c62aL); + HOST_c2l(data, l); + X(7) = l; + R0(C, D, A, B, X(6), 17, 0xa8304613L); + HOST_c2l(data, l); + X(8) = l; + R0(B, C, D, A, X(7), 22, 0xfd469501L); + HOST_c2l(data, l); + X(9) = l; + R0(A, B, C, D, X(8), 7, 0x698098d8L); + HOST_c2l(data, l); + X(10) = l; + R0(D, A, B, C, X(9), 12, 0x8b44f7afL); + HOST_c2l(data, l); + X(11) = l; + R0(C, D, A, B, X(10), 17, 0xffff5bb1L); + HOST_c2l(data, l); + X(12) = l; + R0(B, C, D, A, X(11), 22, 0x895cd7beL); + HOST_c2l(data, l); + X(13) = l; + R0(A, B, C, D, X(12), 7, 0x6b901122L); + HOST_c2l(data, l); + X(14) = l; + R0(D, A, B, C, X(13), 12, 0xfd987193L); + HOST_c2l(data, l); + X(15) = l; + R0(C, D, A, B, X(14), 17, 0xa679438eL); + R0(B, C, D, A, X(15), 22, 0x49b40821L); + /* Round 1 */ + R1(A, B, C, D, X(1), 5, 0xf61e2562L); + R1(D, A, B, C, X(6), 9, 0xc040b340L); + R1(C, D, A, B, X(11), 14, 0x265e5a51L); + R1(B, C, D, A, X(0), 20, 0xe9b6c7aaL); + R1(A, B, C, D, X(5), 5, 0xd62f105dL); + R1(D, A, B, C, X(10), 9, 0x02441453L); + R1(C, D, A, B, X(15), 14, 0xd8a1e681L); + R1(B, C, D, A, X(4), 20, 0xe7d3fbc8L); + R1(A, B, C, D, X(9), 5, 0x21e1cde6L); + R1(D, A, B, C, X(14), 9, 0xc33707d6L); + R1(C, D, A, B, X(3), 14, 0xf4d50d87L); + R1(B, C, D, A, X(8), 20, 0x455a14edL); + R1(A, B, C, D, X(13), 5, 0xa9e3e905L); + R1(D, A, B, C, X(2), 9, 0xfcefa3f8L); + R1(C, D, A, B, X(7), 14, 0x676f02d9L); + R1(B, C, D, A, X(12), 20, 0x8d2a4c8aL); + /* Round 2 */ + R2(A, B, C, D, X(5), 4, 0xfffa3942L); + R2(D, A, B, C, X(8), 11, 0x8771f681L); + R2(C, D, A, B, X(11), 16, 0x6d9d6122L); + R2(B, C, D, A, X(14), 23, 0xfde5380cL); + R2(A, B, C, D, X(1), 4, 0xa4beea44L); + R2(D, A, B, C, X(4), 11, 0x4bdecfa9L); + R2(C, D, A, B, X(7), 16, 0xf6bb4b60L); + R2(B, C, D, A, X(10), 23, 0xbebfbc70L); + R2(A, B, C, D, X(13), 4, 0x289b7ec6L); + R2(D, A, B, C, X(0), 11, 0xeaa127faL); + R2(C, D, A, B, X(3), 16, 0xd4ef3085L); + R2(B, C, D, A, X(6), 23, 0x04881d05L); + R2(A, B, C, D, X(9), 4, 0xd9d4d039L); + R2(D, A, B, C, X(12), 11, 0xe6db99e5L); + R2(C, D, A, B, X(15), 16, 0x1fa27cf8L); + R2(B, C, D, A, X(2), 23, 0xc4ac5665L); + /* Round 3 */ + R3(A, B, C, D, X(0), 6, 0xf4292244L); + R3(D, A, B, C, X(7), 10, 0x432aff97L); + R3(C, D, A, B, X(14), 15, 0xab9423a7L); + R3(B, C, D, A, X(5), 21, 0xfc93a039L); + R3(A, B, C, D, X(12), 6, 0x655b59c3L); + R3(D, A, B, C, X(3), 10, 0x8f0ccc92L); + R3(C, D, A, B, X(10), 15, 0xffeff47dL); + R3(B, C, D, A, X(1), 21, 0x85845dd1L); + R3(A, B, C, D, X(8), 6, 0x6fa87e4fL); + R3(D, A, B, C, X(15), 10, 0xfe2ce6e0L); + R3(C, D, A, B, X(6), 15, 0xa3014314L); + R3(B, C, D, A, X(13), 21, 0x4e0811a1L); + R3(A, B, C, D, X(4), 6, 0xf7537e82L); + R3(D, A, B, C, X(11), 10, 0xbd3af235L); + R3(C, D, A, B, X(2), 15, 0x2ad7d2bbL); + R3(B, C, D, A, X(9), 21, 0xeb86d391L); + + A = c->A += A; + B = c->B += B; + C = c->C += C; + D = c->D += D; + } +} +#endif diff --git a/libs/openssl/crypto/md5/md5_locl.h b/libs/openssl/crypto/md5/md5_locl.h new file mode 100644 index 00000000..5f6f2fde --- /dev/null +++ b/libs/openssl/crypto/md5/md5_locl.h @@ -0,0 +1,131 @@ +/* crypto/md5/md5_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#ifndef MD5_LONG_LOG2 +# define MD5_LONG_LOG2 2 /* default to 32 bits */ +#endif + +#ifdef MD5_ASM +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_AMD64) || defined(_M_X64) +# define md5_block_data_order md5_block_asm_data_order +# elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64) +# define md5_block_data_order md5_block_asm_data_order +# endif +#endif + +void md5_block_data_order(MD5_CTX *c, const void *p, size_t num); + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_LONG MD5_LONG +#define HASH_CTX MD5_CTX +#define HASH_CBLOCK MD5_CBLOCK +#define HASH_UPDATE MD5_Update +#define HASH_TRANSFORM MD5_Transform +#define HASH_FINAL MD5_Final +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->A; (void)HOST_l2c(ll,(s)); \ + ll=(c)->B; (void)HOST_l2c(ll,(s)); \ + ll=(c)->C; (void)HOST_l2c(ll,(s)); \ + ll=(c)->D; (void)HOST_l2c(ll,(s)); \ + } while (0) +#define HASH_BLOCK_DATA_ORDER md5_block_data_order + +#include "md32_common.h" + +/*- +#define F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) +#define G(x,y,z) (((x) & (z)) | ((y) & (~(z)))) +*/ + +/* + * As pointed out by Wei Dai , the above can be simplified + * to the code below. Wei attributes these optimizations to Peter Gutmann's + * SHS code, and he attributes it to Rich Schroeppel. + */ +#define F(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define G(b,c,d) ((((b) ^ (c)) & (d)) ^ (c)) +#define H(b,c,d) ((b) ^ (c) ^ (d)) +#define I(b,c,d) (((~(d)) | (b)) ^ (c)) + +#define R0(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+F((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; };\ + +#define R1(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+G((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + +#define R2(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+H((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; + +#define R3(a,b,c,d,k,s,t) { \ + a+=((k)+(t)+I((b),(c),(d))); \ + a=ROTATE(a,s); \ + a+=b; }; diff --git a/libs/openssl/crypto/md5/md5_one.c b/libs/openssl/crypto/md5/md5_one.c new file mode 100644 index 00000000..4ac882e7 --- /dev/null +++ b/libs/openssl/crypto/md5/md5_one.c @@ -0,0 +1,96 @@ +/* crypto/md5/md5_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#ifdef CHARSET_EBCDIC +# include +#endif + +unsigned char *MD5(const unsigned char *d, size_t n, unsigned char *md) +{ + MD5_CTX c; + static unsigned char m[MD5_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!MD5_Init(&c)) + return NULL; +#ifndef CHARSET_EBCDIC + MD5_Update(&c, d, n); +#else + { + char temp[1024]; + unsigned long chunk; + + while (n > 0) { + chunk = (n > sizeof(temp)) ? sizeof(temp) : n; + ebcdic2ascii(temp, d, chunk); + MD5_Update(&c, temp, chunk); + n -= chunk; + d += chunk; + } + } +#endif + MD5_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */ + return (md); +} diff --git a/libs/openssl/crypto/md5/md5s.cpp b/libs/openssl/crypto/md5/md5s.cpp new file mode 100644 index 00000000..dd343fd4 --- /dev/null +++ b/libs/openssl/crypto/md5/md5s.cpp @@ -0,0 +1,78 @@ +// +// gettsc.inl +// +// gives access to the Pentium's (secret) cycle counter +// +// This software was written by Leonard Janke (janke@unixg.ubc.ca) +// in 1996-7 and is entered, by him, into the public domain. + +#if defined(__WATCOMC__) +void GetTSC(unsigned long&); +#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax]; +#elif defined(__GNUC__) +inline +void GetTSC(unsigned long& tsc) +{ + asm volatile(".byte 15, 49\n\t" + : "=eax" (tsc) + : + : "%edx", "%eax"); +} +#elif defined(_MSC_VER) +inline +void GetTSC(unsigned long& tsc) +{ + unsigned long a; + __asm _emit 0fh + __asm _emit 31h + __asm mov a, eax; + tsc=a; +} +#endif + +#include +#include +#include + +extern "C" { +void md5_block_x86(MD5_CTX *ctx, unsigned char *buffer,int num); +} + +void main(int argc,char *argv[]) + { + unsigned char buffer[64*256]; + MD5_CTX ctx; + unsigned long s1,s2,e1,e2; + unsigned char k[16]; + unsigned long data[2]; + unsigned char iv[8]; + int i,num=0,numm; + int j=0; + + if (argc >= 2) + num=atoi(argv[1]); + + if (num == 0) num=16; + if (num > 250) num=16; + numm=num+2; + num*=64; + numm*=64; + + for (j=0; j<6; j++) + { + for (i=0; i<10; i++) /**/ + { + md5_block_x86(&ctx,buffer,numm); + GetTSC(s1); + md5_block_x86(&ctx,buffer,numm); + GetTSC(e1); + GetTSC(s2); + md5_block_x86(&ctx,buffer,num); + GetTSC(e2); + md5_block_x86(&ctx,buffer,num); + } + printf("md5 (%d bytes) %d %d (%.2f)\n",num, + e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2); + } + } + diff --git a/libs/openssl/crypto/md5/md5test.c b/libs/openssl/crypto/md5/md5test.c new file mode 100644 index 00000000..0d0ab2d7 --- /dev/null +++ b/libs/openssl/crypto/md5/md5test.c @@ -0,0 +1,138 @@ +/* crypto/md5/md5test.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "../e_os.h" + +#ifdef OPENSSL_NO_MD5 +int main(int argc, char *argv[]) +{ + printf("No MD5 support\n"); + return (0); +} +#else +# include +# include + +static char *test[] = { + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + NULL, +}; + +static char *ret[] = { + "d41d8cd98f00b204e9800998ecf8427e", + "0cc175b9c0f1b6a831c399e269772661", + "900150983cd24fb0d6963f7d28e17f72", + "f96b697d7cb7938d525a2f31aaf161d0", + "c3fcd3d76192e4007dfb496cca67e13b", + "d174ab98d277d9f5a5611c2c9f419d9f", + "57edf4a22be3c955ac49da2e2107b67a", +}; + +static char *pt(unsigned char *md); +int main(int argc, char *argv[]) +{ + int i, err = 0; + char **P, **R; + char *p; + unsigned char md[MD5_DIGEST_LENGTH]; + + P = test; + R = ret; + i = 1; + while (*P != NULL) { + EVP_Digest(&(P[0][0]), strlen((char *)*P), md, NULL, EVP_md5(), NULL); + p = pt(md); + if (strcmp(p, (char *)*R) != 0) { + printf("error calculating MD5 on '%s'\n", *P); + printf("got %s instead of %s\n", p, *R); + err++; + } else + printf("test %d ok\n", i); + i++; + R++; + P++; + } + +# ifdef OPENSSL_SYS_NETWARE + if (err) + printf("ERROR: %d\n", err); +# endif + EXIT(err); + return (0); +} + +static char *pt(unsigned char *md) +{ + int i; + static char buf[80]; + + for (i = 0; i < MD5_DIGEST_LENGTH; i++) + sprintf(&(buf[i * 2]), "%02x", md[i]); + return (buf); +} +#endif diff --git a/libs/openssl/crypto/mdc2/mdc2.h b/libs/openssl/crypto/mdc2/mdc2.h new file mode 100644 index 00000000..7efe53bc --- /dev/null +++ b/libs/openssl/crypto/mdc2/mdc2.h @@ -0,0 +1,94 @@ +/* crypto/mdc2/mdc2.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_MDC2_H +# define HEADER_MDC2_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_MDC2 +# error MDC2 is disabled. +# endif + +# define MDC2_BLOCK 8 +# define MDC2_DIGEST_LENGTH 16 + +typedef struct mdc2_ctx_st { + unsigned int num; + unsigned char data[MDC2_BLOCK]; + DES_cblock h, hh; + int pad_type; /* either 1 or 2, default 1 */ +} MDC2_CTX; + +# ifdef OPENSSL_FIPS +int private_MDC2_Init(MDC2_CTX *c); +# endif +int MDC2_Init(MDC2_CTX *c); +int MDC2_Update(MDC2_CTX *c, const unsigned char *data, size_t len); +int MDC2_Final(unsigned char *md, MDC2_CTX *c); +unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/mdc2/mdc2_one.c b/libs/openssl/crypto/mdc2/mdc2_one.c new file mode 100644 index 00000000..790775c6 --- /dev/null +++ b/libs/openssl/crypto/mdc2/mdc2_one.c @@ -0,0 +1,76 @@ +/* crypto/mdc2/mdc2_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include + +unsigned char *MDC2(const unsigned char *d, size_t n, unsigned char *md) +{ + MDC2_CTX c; + static unsigned char m[MDC2_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!MDC2_Init(&c)) + return NULL; + MDC2_Update(&c, d, n); + MDC2_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */ + return (md); +} diff --git a/libs/openssl/crypto/mdc2/mdc2dgst.c b/libs/openssl/crypto/mdc2/mdc2dgst.c new file mode 100644 index 00000000..6615cf84 --- /dev/null +++ b/libs/openssl/crypto/mdc2/mdc2dgst.c @@ -0,0 +1,196 @@ +/* crypto/mdc2/mdc2dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include +#include + +#undef c2l +#define c2l(c,l) (l =((DES_LONG)(*((c)++))) , \ + l|=((DES_LONG)(*((c)++)))<< 8L, \ + l|=((DES_LONG)(*((c)++)))<<16L, \ + l|=((DES_LONG)(*((c)++)))<<24L) + +#undef l2c +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len); +fips_md_init(MDC2) +{ + c->num = 0; + c->pad_type = 1; + memset(&(c->h[0]), 0x52, MDC2_BLOCK); + memset(&(c->hh[0]), 0x25, MDC2_BLOCK); + return 1; +} + +int MDC2_Update(MDC2_CTX *c, const unsigned char *in, size_t len) +{ + size_t i, j; + + i = c->num; + if (i != 0) { + if (i + len < MDC2_BLOCK) { + /* partial block */ + memcpy(&(c->data[i]), in, len); + c->num += (int)len; + return 1; + } else { + /* filled one */ + j = MDC2_BLOCK - i; + memcpy(&(c->data[i]), in, j); + len -= j; + in += j; + c->num = 0; + mdc2_body(c, &(c->data[0]), MDC2_BLOCK); + } + } + i = len & ~((size_t)MDC2_BLOCK - 1); + if (i > 0) + mdc2_body(c, in, i); + j = len - i; + if (j > 0) { + memcpy(&(c->data[0]), &(in[i]), j); + c->num = (int)j; + } + return 1; +} + +static void mdc2_body(MDC2_CTX *c, const unsigned char *in, size_t len) +{ + register DES_LONG tin0, tin1; + register DES_LONG ttin0, ttin1; + DES_LONG d[2], dd[2]; + DES_key_schedule k; + unsigned char *p; + size_t i; + + for (i = 0; i < len; i += 8) { + c2l(in, tin0); + d[0] = dd[0] = tin0; + c2l(in, tin1); + d[1] = dd[1] = tin1; + c->h[0] = (c->h[0] & 0x9f) | 0x40; + c->hh[0] = (c->hh[0] & 0x9f) | 0x20; + + DES_set_odd_parity(&c->h); + DES_set_key_unchecked(&c->h, &k); + DES_encrypt1(d, &k, 1); + + DES_set_odd_parity(&c->hh); + DES_set_key_unchecked(&c->hh, &k); + DES_encrypt1(dd, &k, 1); + + ttin0 = tin0 ^ dd[0]; + ttin1 = tin1 ^ dd[1]; + tin0 ^= d[0]; + tin1 ^= d[1]; + + p = c->h; + l2c(tin0, p); + l2c(ttin1, p); + p = c->hh; + l2c(ttin0, p); + l2c(tin1, p); + } +} + +int MDC2_Final(unsigned char *md, MDC2_CTX *c) +{ + unsigned int i; + int j; + + i = c->num; + j = c->pad_type; + if ((i > 0) || (j == 2)) { + if (j == 2) + c->data[i++] = 0x80; + memset(&(c->data[i]), 0, MDC2_BLOCK - i); + mdc2_body(c, c->data, MDC2_BLOCK); + } + memcpy(md, (char *)c->h, MDC2_BLOCK); + memcpy(&(md[MDC2_BLOCK]), (char *)c->hh, MDC2_BLOCK); + return 1; +} + +#undef TEST + +#ifdef TEST +main() +{ + unsigned char md[MDC2_DIGEST_LENGTH]; + int i; + MDC2_CTX c; + static char *text = "Now is the time for all "; + + MDC2_Init(&c); + MDC2_Update(&c, text, strlen(text)); + MDC2_Final(&(md[0]), &c); + + for (i = 0; i < MDC2_DIGEST_LENGTH; i++) + printf("%02X", md[i]); + printf("\n"); +} + +#endif diff --git a/libs/openssl/crypto/mdc2/mdc2test.c b/libs/openssl/crypto/mdc2/mdc2test.c new file mode 100644 index 00000000..8416252f --- /dev/null +++ b/libs/openssl/crypto/mdc2/mdc2test.c @@ -0,0 +1,146 @@ +/* crypto/mdc2/mdc2test.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "../e_os.h" + +#if defined(OPENSSL_NO_DES) && !defined(OPENSSL_NO_MDC2) +# define OPENSSL_NO_MDC2 +#endif + +#ifdef OPENSSL_NO_MDC2 +int main(int argc, char *argv[]) +{ + printf("No MDC2 support\n"); + return (0); +} +#else +# include +# include + +# ifdef CHARSET_EBCDIC +# include +# endif + +static unsigned char pad1[16] = { + 0x42, 0xE5, 0x0C, 0xD2, 0x24, 0xBA, 0xCE, 0xBA, + 0x76, 0x0B, 0xDD, 0x2B, 0xD4, 0x09, 0x28, 0x1A +}; + +static unsigned char pad2[16] = { + 0x2E, 0x46, 0x79, 0xB5, 0xAD, 0xD9, 0xCA, 0x75, + 0x35, 0xD8, 0x7A, 0xFE, 0xAB, 0x33, 0xBE, 0xE2 +}; + +int main(int argc, char *argv[]) +{ + int ret = 0; + unsigned char md[MDC2_DIGEST_LENGTH]; + int i; + EVP_MD_CTX c; + static char *text = "Now is the time for all "; + +# ifdef CHARSET_EBCDIC + ebcdic2ascii(text, text, strlen(text)); +# endif + + EVP_MD_CTX_init(&c); + EVP_DigestInit_ex(&c, EVP_mdc2(), NULL); + EVP_DigestUpdate(&c, (unsigned char *)text, strlen(text)); + EVP_DigestFinal_ex(&c, &(md[0]), NULL); + + if (memcmp(md, pad1, MDC2_DIGEST_LENGTH) != 0) { + for (i = 0; i < MDC2_DIGEST_LENGTH; i++) + printf("%02X", md[i]); + printf(" <- generated\n"); + for (i = 0; i < MDC2_DIGEST_LENGTH; i++) + printf("%02X", pad1[i]); + printf(" <- correct\n"); + ret = 1; + } else + printf("pad1 - ok\n"); + + EVP_DigestInit_ex(&c, EVP_mdc2(), NULL); + /* FIXME: use a ctl function? */ + ((MDC2_CTX *)c.md_data)->pad_type = 2; + EVP_DigestUpdate(&c, (unsigned char *)text, strlen(text)); + EVP_DigestFinal_ex(&c, &(md[0]), NULL); + + if (memcmp(md, pad2, MDC2_DIGEST_LENGTH) != 0) { + for (i = 0; i < MDC2_DIGEST_LENGTH; i++) + printf("%02X", md[i]); + printf(" <- generated\n"); + for (i = 0; i < MDC2_DIGEST_LENGTH; i++) + printf("%02X", pad2[i]); + printf(" <- correct\n"); + ret = 1; + } else + printf("pad2 - ok\n"); + + EVP_MD_CTX_cleanup(&c); +# ifdef OPENSSL_SYS_NETWARE + if (ret) + printf("ERROR: %d\n", ret); +# endif + EXIT(ret); + return (ret); +} +#endif diff --git a/libs/openssl/crypto/mem.c b/libs/openssl/crypto/mem.c new file mode 100644 index 00000000..fdad49b7 --- /dev/null +++ b/libs/openssl/crypto/mem.c @@ -0,0 +1,466 @@ +/* crypto/mem.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include "cryptlib.h" + +static int allow_customize = 1; /* we provide flexible functions for */ +static int allow_customize_debug = 1; /* exchanging memory-related functions + * at run-time, but this must be done + * before any blocks are actually + * allocated; or we'll run into huge + * problems when malloc/free pairs + * don't match etc. */ + +/* + * the following pointers may be changed as long as 'allow_customize' is set + */ + +static void *(*malloc_func) (size_t) = malloc; +static void *default_malloc_ex(size_t num, const char *file, int line) +{ + return malloc_func(num); +} + +static void *(*malloc_ex_func) (size_t, const char *file, int line) + = default_malloc_ex; + +static void *(*realloc_func) (void *, size_t) = realloc; +static void *default_realloc_ex(void *str, size_t num, + const char *file, int line) +{ + return realloc_func(str, num); +} + +static void *(*realloc_ex_func) (void *, size_t, const char *file, int line) + = default_realloc_ex; + +static void (*free_func) (void *) = free; + +static void *(*malloc_locked_func) (size_t) = malloc; +static void *default_malloc_locked_ex(size_t num, const char *file, int line) +{ + return malloc_locked_func(num); +} + +static void *(*malloc_locked_ex_func) (size_t, const char *file, int line) + = default_malloc_locked_ex; + +static void (*free_locked_func) (void *) = free; + +/* may be changed as long as 'allow_customize_debug' is set */ +/* XXX use correct function pointer types */ +#ifdef CRYPTO_MDEBUG +/* use default functions from mem_dbg.c */ +static void (*malloc_debug_func) (void *, int, const char *, int, int) + = CRYPTO_dbg_malloc; +static void (*realloc_debug_func) (void *, void *, int, const char *, int, + int) + = CRYPTO_dbg_realloc; +static void (*free_debug_func) (void *, int) = CRYPTO_dbg_free; +static void (*set_debug_options_func) (long) = CRYPTO_dbg_set_options; +static long (*get_debug_options_func) (void) = CRYPTO_dbg_get_options; +#else +/* + * applications can use CRYPTO_malloc_debug_init() to select above case at + * run-time + */ +static void (*malloc_debug_func) (void *, int, const char *, int, int) = NULL; +static void (*realloc_debug_func) (void *, void *, int, const char *, int, + int) + = NULL; +static void (*free_debug_func) (void *, int) = NULL; +static void (*set_debug_options_func) (long) = NULL; +static long (*get_debug_options_func) (void) = NULL; +#endif + +int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t), + void (*f) (void *)) +{ + /* Dummy call just to ensure OPENSSL_init() gets linked in */ + OPENSSL_init(); + if (!allow_customize) + return 0; + if ((m == 0) || (r == 0) || (f == 0)) + return 0; + malloc_func = m; + malloc_ex_func = default_malloc_ex; + realloc_func = r; + realloc_ex_func = default_realloc_ex; + free_func = f; + malloc_locked_func = m; + malloc_locked_ex_func = default_malloc_locked_ex; + free_locked_func = f; + return 1; +} + +int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int), + void *(*r) (void *, size_t, const char *, + int), void (*f) (void *)) +{ + if (!allow_customize) + return 0; + if ((m == 0) || (r == 0) || (f == 0)) + return 0; + malloc_func = 0; + malloc_ex_func = m; + realloc_func = 0; + realloc_ex_func = r; + free_func = f; + malloc_locked_func = 0; + malloc_locked_ex_func = m; + free_locked_func = f; + return 1; +} + +int CRYPTO_set_locked_mem_functions(void *(*m) (size_t), void (*f) (void *)) +{ + if (!allow_customize) + return 0; + if ((m == NULL) || (f == NULL)) + return 0; + malloc_locked_func = m; + malloc_locked_ex_func = default_malloc_locked_ex; + free_locked_func = f; + return 1; +} + +int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int), + void (*f) (void *)) +{ + if (!allow_customize) + return 0; + if ((m == NULL) || (f == NULL)) + return 0; + malloc_locked_func = 0; + malloc_locked_ex_func = m; + free_func = f; + return 1; +} + +int CRYPTO_set_mem_debug_functions(void (*m) + (void *, int, const char *, int, int), + void (*r) (void *, void *, int, + const char *, int, int), + void (*f) (void *, int), void (*so) (long), + long (*go) (void)) +{ + if (!allow_customize_debug) + return 0; + OPENSSL_init(); + malloc_debug_func = m; + realloc_debug_func = r; + free_debug_func = f; + set_debug_options_func = so; + get_debug_options_func = go; + return 1; +} + +void CRYPTO_get_mem_functions(void *(**m) (size_t), + void *(**r) (void *, size_t), + void (**f) (void *)) +{ + if (m != NULL) + *m = (malloc_ex_func == default_malloc_ex) ? malloc_func : 0; + if (r != NULL) + *r = (realloc_ex_func == default_realloc_ex) ? realloc_func : 0; + if (f != NULL) + *f = free_func; +} + +void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int), + void *(**r) (void *, size_t, const char *, + int), void (**f) (void *)) +{ + if (m != NULL) + *m = (malloc_ex_func != default_malloc_ex) ? malloc_ex_func : 0; + if (r != NULL) + *r = (realloc_ex_func != default_realloc_ex) ? realloc_ex_func : 0; + if (f != NULL) + *f = free_func; +} + +void CRYPTO_get_locked_mem_functions(void *(**m) (size_t), + void (**f) (void *)) +{ + if (m != NULL) + *m = (malloc_locked_ex_func == default_malloc_locked_ex) ? + malloc_locked_func : 0; + if (f != NULL) + *f = free_locked_func; +} + +void CRYPTO_get_locked_mem_ex_functions(void + *(**m) (size_t, const char *, int), + void (**f) (void *)) +{ + if (m != NULL) + *m = (malloc_locked_ex_func != default_malloc_locked_ex) ? + malloc_locked_ex_func : 0; + if (f != NULL) + *f = free_locked_func; +} + +void CRYPTO_get_mem_debug_functions(void (**m) + (void *, int, const char *, int, int), + void (**r) (void *, void *, int, + const char *, int, int), + void (**f) (void *, int), + void (**so) (long), long (**go) (void)) +{ + if (m != NULL) + *m = malloc_debug_func; + if (r != NULL) + *r = realloc_debug_func; + if (f != NULL) + *f = free_debug_func; + if (so != NULL) + *so = set_debug_options_func; + if (go != NULL) + *go = get_debug_options_func; +} + +void *CRYPTO_malloc_locked(int num, const char *file, int line) +{ + void *ret = NULL; + + if (num <= 0) + return NULL; + + if (allow_customize) + allow_customize = 0; + if (malloc_debug_func != NULL) { + if (allow_customize_debug) + allow_customize_debug = 0; + malloc_debug_func(NULL, num, file, line, 0); + } + ret = malloc_locked_ex_func(num, file, line); +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num); +#endif + if (malloc_debug_func != NULL) + malloc_debug_func(ret, num, file, line, 1); + +#ifndef OPENSSL_CPUID_OBJ + /* + * Create a dependency on the value of 'cleanse_ctr' so our memory + * sanitisation function can't be optimised out. NB: We only do this for + * >2Kb so the overhead doesn't bother us. + */ + if (ret && (num > 2048)) { + extern unsigned char cleanse_ctr; + ((unsigned char *)ret)[0] = cleanse_ctr; + } +#endif + + return ret; +} + +void CRYPTO_free_locked(void *str) +{ + if (free_debug_func != NULL) + free_debug_func(str, 0); +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str); +#endif + free_locked_func(str); + if (free_debug_func != NULL) + free_debug_func(NULL, 1); +} + +void *CRYPTO_malloc(int num, const char *file, int line) +{ + void *ret = NULL; + + if (num <= 0) + return NULL; + + if (allow_customize) + allow_customize = 0; + if (malloc_debug_func != NULL) { + if (allow_customize_debug) + allow_customize_debug = 0; + malloc_debug_func(NULL, num, file, line, 0); + } + ret = malloc_ex_func(num, file, line); +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num); +#endif + if (malloc_debug_func != NULL) + malloc_debug_func(ret, num, file, line, 1); + +#ifndef OPENSSL_CPUID_OBJ + /* + * Create a dependency on the value of 'cleanse_ctr' so our memory + * sanitisation function can't be optimised out. NB: We only do this for + * >2Kb so the overhead doesn't bother us. + */ + if (ret && (num > 2048)) { + extern unsigned char cleanse_ctr; + ((unsigned char *)ret)[0] = cleanse_ctr; + } +#endif + + return ret; +} + +char *CRYPTO_strdup(const char *str, const char *file, int line) +{ + char *ret = CRYPTO_malloc(strlen(str) + 1, file, line); + + if (ret == NULL) + return NULL; + + strcpy(ret, str); + return ret; +} + +void *CRYPTO_realloc(void *str, int num, const char *file, int line) +{ + void *ret = NULL; + + if (str == NULL) + return CRYPTO_malloc(num, file, line); + + if (num <= 0) + return NULL; + + if (realloc_debug_func != NULL) + realloc_debug_func(str, NULL, num, file, line, 0); + ret = realloc_ex_func(str, num, file, line); +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", str, + ret, num); +#endif + if (realloc_debug_func != NULL) + realloc_debug_func(str, ret, num, file, line, 1); + + return ret; +} + +void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file, + int line) +{ + void *ret = NULL; + + if (str == NULL) + return CRYPTO_malloc(num, file, line); + + if (num <= 0) + return NULL; + + /* + * We don't support shrinking the buffer. Note the memcpy that copies + * |old_len| bytes to the new buffer, below. + */ + if (num < old_len) + return NULL; + + if (realloc_debug_func != NULL) + realloc_debug_func(str, NULL, num, file, line, 0); + ret = malloc_ex_func(num, file, line); + if (ret) { + memcpy(ret, str, old_len); + OPENSSL_cleanse(str, old_len); + free_func(str); + } +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, + "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", + str, ret, num); +#endif + if (realloc_debug_func != NULL) + realloc_debug_func(str, ret, num, file, line, 1); + + return ret; +} + +void CRYPTO_free(void *str) +{ + if (free_debug_func != NULL) + free_debug_func(str, 0); +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str); +#endif + free_func(str); + if (free_debug_func != NULL) + free_debug_func(NULL, 1); +} + +void *CRYPTO_remalloc(void *a, int num, const char *file, int line) +{ + if (a != NULL) + OPENSSL_free(a); + a = (char *)OPENSSL_malloc(num); + return (a); +} + +void CRYPTO_set_mem_debug_options(long bits) +{ + if (set_debug_options_func != NULL) + set_debug_options_func(bits); +} + +long CRYPTO_get_mem_debug_options(void) +{ + if (get_debug_options_func != NULL) + return get_debug_options_func(); + return 0; +} diff --git a/libs/openssl/crypto/mem_clr.c b/libs/openssl/crypto/mem_clr.c new file mode 100644 index 00000000..ab85344e --- /dev/null +++ b/libs/openssl/crypto/mem_clr.c @@ -0,0 +1,81 @@ +/* crypto/mem_clr.c */ +/* + * Written by Geoff Thorpe (geoff@geoffthorpe.net) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +unsigned char cleanse_ctr = 0; + +void OPENSSL_cleanse(void *ptr, size_t len) +{ + unsigned char *p = ptr; + size_t loop = len, ctr = cleanse_ctr; + + if (ptr == NULL) + return; + + while (loop--) { + *(p++) = (unsigned char)ctr; + ctr += (17 + ((size_t)p & 0xF)); + } + p = memchr(ptr, (unsigned char)ctr, len); + if (p) + ctr += (63 + (size_t)p); + cleanse_ctr = (unsigned char)ctr; +} diff --git a/libs/openssl/crypto/mem_dbg.c b/libs/openssl/crypto/mem_dbg.c new file mode 100644 index 00000000..8525ded7 --- /dev/null +++ b/libs/openssl/crypto/mem_dbg.c @@ -0,0 +1,830 @@ +/* crypto/mem_dbg.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include + +static int mh_mode = CRYPTO_MEM_CHECK_OFF; +/* + * The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE when + * the application asks for it (usually after library initialisation for + * which no book-keeping is desired). State CRYPTO_MEM_CHECK_ON exists only + * temporarily when the library thinks that certain allocations should not be + * checked (e.g. the data structures used for memory checking). It is not + * suitable as an initial state: the library will unexpectedly enable memory + * checking when it executes one of those sections that want to disable + * checking temporarily. State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes + * no sense whatsoever. + */ + +static unsigned long order = 0; /* number of memory requests */ + +DECLARE_LHASH_OF(MEM); +static LHASH_OF(MEM) *mh = NULL; /* hash-table of memory requests (address as + * key); access requires MALLOC2 lock */ + +typedef struct app_mem_info_st +/*- + * For application-defined information (static C-string `info') + * to be displayed in memory leak list. + * Each thread has its own stack. For applications, there is + * CRYPTO_push_info("...") to push an entry, + * CRYPTO_pop_info() to pop an entry, + * CRYPTO_remove_all_info() to pop all entries. + */ +{ + CRYPTO_THREADID threadid; + const char *file; + int line; + const char *info; + struct app_mem_info_st *next; /* tail of thread's stack */ + int references; +} APP_INFO; + +static void app_info_free(APP_INFO *); + +DECLARE_LHASH_OF(APP_INFO); +static LHASH_OF(APP_INFO) *amih = NULL; /* hash-table with those + * app_mem_info_st's that are at the + * top of their thread's stack (with + * `thread' as key); access requires + * MALLOC2 lock */ + +typedef struct mem_st +/* memory-block description */ +{ + void *addr; + int num; + const char *file; + int line; + CRYPTO_THREADID threadid; + unsigned long order; + time_t time; + APP_INFO *app_info; +} MEM; + +static long options = /* extra information to be recorded */ +#if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL) + V_CRYPTO_MDEBUG_TIME | +#endif +#if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL) + V_CRYPTO_MDEBUG_THREAD | +#endif + 0; + +static unsigned int num_disable = 0; /* num_disable > 0 iff mh_mode == + * CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */ + +/* + * Valid iff num_disable > 0. CRYPTO_LOCK_MALLOC2 is locked exactly in this + * case (by the thread named in disabling_thread). + */ +static CRYPTO_THREADID disabling_threadid; + +static void app_info_free(APP_INFO *inf) +{ + if (--(inf->references) <= 0) { + if (inf->next != NULL) { + app_info_free(inf->next); + } + OPENSSL_free(inf); + } +} + +int CRYPTO_mem_ctrl(int mode) +{ + int ret = mh_mode; + + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); + switch (mode) { + /* + * for applications (not to be called while multiple threads use the + * library): + */ + case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */ + mh_mode = CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE; + num_disable = 0; + break; + case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */ + mh_mode = 0; + num_disable = 0; /* should be true *before* MemCheck_stop is + * used, or there'll be a lot of confusion */ + break; + + /* switch off temporarily (for library-internal use): */ + case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */ + if (mh_mode & CRYPTO_MEM_CHECK_ON) { + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); + /* see if we don't have the MALLOC2 lock already */ + if (!num_disable + || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) { + /* + * Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed + * while we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock + * if somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot + * release it because we block entry to this function). Give + * them a chance, first, and then claim the locks in + * appropriate order (long-time lock first). + */ + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); + /* + * Note that after we have waited for CRYPTO_LOCK_MALLOC2 and + * CRYPTO_LOCK_MALLOC, we'll still be in the right "case" and + * "if" branch because MemCheck_start and MemCheck_stop may + * never be used while there are multiple OpenSSL threads. + */ + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); + mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE; + CRYPTO_THREADID_cpy(&disabling_threadid, &cur); + } + num_disable++; + } + break; + case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */ + if (mh_mode & CRYPTO_MEM_CHECK_ON) { + if (num_disable) { /* always true, or something is going wrong */ + num_disable--; + if (num_disable == 0) { + mh_mode |= CRYPTO_MEM_CHECK_ENABLE; + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); + } + } + } + break; + + default: + break; + } + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); + return (ret); +} + +int CRYPTO_is_mem_check_on(void) +{ + int ret = 0; + + if (mh_mode & CRYPTO_MEM_CHECK_ON) { + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); + CRYPTO_r_lock(CRYPTO_LOCK_MALLOC); + + ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) + || CRYPTO_THREADID_cmp(&disabling_threadid, &cur); + + CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC); + } + return (ret); +} + +void CRYPTO_dbg_set_options(long bits) +{ + options = bits; +} + +long CRYPTO_dbg_get_options(void) +{ + return options; +} + +static int mem_cmp(const MEM *a, const MEM *b) +{ +#ifdef _WIN64 + const char *ap = (const char *)a->addr, *bp = (const char *)b->addr; + if (ap == bp) + return 0; + else if (ap > bp) + return 1; + else + return -1; +#else + return (const char *)a->addr - (const char *)b->addr; +#endif +} + +static IMPLEMENT_LHASH_COMP_FN(mem, MEM) + +static unsigned long mem_hash(const MEM *a) +{ + unsigned long ret; + + ret = (unsigned long)a->addr; + + ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251; + return (ret); +} + +static IMPLEMENT_LHASH_HASH_FN(mem, MEM) + +/* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */ +static int app_info_cmp(const void *a_void, const void *b_void) +{ + return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid, + &((const APP_INFO *)b_void)->threadid); +} + +static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO) + +static unsigned long app_info_hash(const APP_INFO *a) +{ + unsigned long ret; + + ret = CRYPTO_THREADID_hash(&a->threadid); + /* This is left in as a "who am I to question legacy?" measure */ + ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251; + return (ret); +} + +static IMPLEMENT_LHASH_HASH_FN(app_info, APP_INFO) + +static APP_INFO *pop_info(void) +{ + APP_INFO tmp; + APP_INFO *ret = NULL; + + if (amih != NULL) { + CRYPTO_THREADID_current(&tmp.threadid); + if ((ret = lh_APP_INFO_delete(amih, &tmp)) != NULL) { + APP_INFO *next = ret->next; + + if (next != NULL) { + next->references++; + (void)lh_APP_INFO_insert(amih, next); + } +#ifdef LEVITTE_DEBUG_MEM + if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid)) { + fprintf(stderr, + "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n", + CRYPTO_THREADID_hash(&ret->threadid), + CRYPTO_THREADID_hash(&tmp.threadid)); + abort(); + } +#endif + if (--(ret->references) <= 0) { + ret->next = NULL; + if (next != NULL) + next->references--; + OPENSSL_free(ret); + } + } + } + return (ret); +} + +int CRYPTO_push_info_(const char *info, const char *file, int line) +{ + APP_INFO *ami, *amim; + int ret = 0; + + if (is_MemCheck_on()) { + MemCheck_off(); /* obtain MALLOC2 lock */ + + if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL) { + ret = 0; + goto err; + } + if (amih == NULL) { + if ((amih = lh_APP_INFO_new()) == NULL) { + OPENSSL_free(ami); + ret = 0; + goto err; + } + } + + CRYPTO_THREADID_current(&ami->threadid); + ami->file = file; + ami->line = line; + ami->info = info; + ami->references = 1; + ami->next = NULL; + + if ((amim = lh_APP_INFO_insert(amih, ami)) != NULL) { +#ifdef LEVITTE_DEBUG_MEM + if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid)) { + fprintf(stderr, + "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n", + CRYPTO_THREADID_hash(&amim->threadid), + CRYPTO_THREADID_hash(&ami->threadid)); + abort(); + } +#endif + ami->next = amim; + } + err: + MemCheck_on(); /* release MALLOC2 lock */ + } + + return (ret); +} + +int CRYPTO_pop_info(void) +{ + int ret = 0; + + if (is_MemCheck_on()) { /* _must_ be true, or something went severely + * wrong */ + MemCheck_off(); /* obtain MALLOC2 lock */ + + ret = (pop_info() != NULL); + + MemCheck_on(); /* release MALLOC2 lock */ + } + return (ret); +} + +int CRYPTO_remove_all_info(void) +{ + int ret = 0; + + if (is_MemCheck_on()) { /* _must_ be true */ + MemCheck_off(); /* obtain MALLOC2 lock */ + + while (pop_info() != NULL) + ret++; + + MemCheck_on(); /* release MALLOC2 lock */ + } + return (ret); +} + +static unsigned long break_order_num = 0; +void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, + int before_p) +{ + MEM *m, *mm; + APP_INFO tmp, *amim; + + switch (before_p & 127) { + case 0: + break; + case 1: + if (addr == NULL) + break; + + if (is_MemCheck_on()) { + MemCheck_off(); /* make sure we hold MALLOC2 lock */ + if ((m = (MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL) { + OPENSSL_free(addr); + MemCheck_on(); /* release MALLOC2 lock if num_disabled drops + * to 0 */ + return; + } + if (mh == NULL) { + if ((mh = lh_MEM_new()) == NULL) { + OPENSSL_free(addr); + OPENSSL_free(m); + addr = NULL; + goto err; + } + } + + m->addr = addr; + m->file = file; + m->line = line; + m->num = num; + if (options & V_CRYPTO_MDEBUG_THREAD) + CRYPTO_THREADID_current(&m->threadid); + else + memset(&m->threadid, 0, sizeof(m->threadid)); + + if (order == break_order_num) { + /* BREAK HERE */ + m->order = order; + } + m->order = order++; +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n", + m->order, (before_p & 128) ? '*' : '+', m->addr, m->num); +#endif + if (options & V_CRYPTO_MDEBUG_TIME) + m->time = time(NULL); + else + m->time = 0; + + CRYPTO_THREADID_current(&tmp.threadid); + m->app_info = NULL; + if (amih != NULL + && (amim = lh_APP_INFO_retrieve(amih, &tmp)) != NULL) { + m->app_info = amim; + amim->references++; + } + + if ((mm = lh_MEM_insert(mh, m)) != NULL) { + /* Not good, but don't sweat it */ + if (mm->app_info != NULL) { + mm->app_info->references--; + } + OPENSSL_free(mm); + } + err: + MemCheck_on(); /* release MALLOC2 lock if num_disabled drops + * to 0 */ + } + break; + } + return; +} + +void CRYPTO_dbg_free(void *addr, int before_p) +{ + MEM m, *mp; + + switch (before_p) { + case 0: + if (addr == NULL) + break; + + if (is_MemCheck_on() && (mh != NULL)) { + MemCheck_off(); /* make sure we hold MALLOC2 lock */ + + m.addr = addr; + mp = lh_MEM_delete(mh, &m); + if (mp != NULL) { +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n", + mp->order, mp->addr, mp->num); +#endif + if (mp->app_info != NULL) + app_info_free(mp->app_info); + OPENSSL_free(mp); + } + + MemCheck_on(); /* release MALLOC2 lock if num_disabled drops + * to 0 */ + } + break; + case 1: + break; + } +} + +void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, + const char *file, int line, int before_p) +{ + MEM m, *mp; + +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, + "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n", + addr1, addr2, num, file, line, before_p); +#endif + + switch (before_p) { + case 0: + break; + case 1: + if (addr2 == NULL) + break; + + if (addr1 == NULL) { + CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p); + break; + } + + if (is_MemCheck_on()) { + MemCheck_off(); /* make sure we hold MALLOC2 lock */ + + m.addr = addr1; + mp = lh_MEM_delete(mh, &m); + if (mp != NULL) { +#ifdef LEVITTE_DEBUG_MEM + fprintf(stderr, + "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n", + mp->order, mp->addr, mp->num, addr2, num); +#endif + mp->addr = addr2; + mp->num = num; + (void)lh_MEM_insert(mh, mp); + } + + MemCheck_on(); /* release MALLOC2 lock if num_disabled drops + * to 0 */ + } + break; + } + return; +} + +typedef struct mem_leak_st { + BIO *bio; + int chunks; + long bytes; +} MEM_LEAK; + +static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l) +{ + char buf[1024]; + char *bufp = buf; + APP_INFO *amip; + int ami_cnt; + struct tm *lcl = NULL; + CRYPTO_THREADID ti; + +#define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf)) + + if (m->addr == (char *)l->bio) + return; + + if (options & V_CRYPTO_MDEBUG_TIME) { + lcl = localtime(&m->time); + + BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ", + lcl->tm_hour, lcl->tm_min, lcl->tm_sec); + bufp += strlen(bufp); + } + + BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ", + m->order, m->file, m->line); + bufp += strlen(bufp); + + if (options & V_CRYPTO_MDEBUG_THREAD) { + BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", + CRYPTO_THREADID_hash(&m->threadid)); + bufp += strlen(bufp); + } + + BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n", + m->num, (unsigned long)m->addr); + bufp += strlen(bufp); + + BIO_puts(l->bio, buf); + + l->chunks++; + l->bytes += m->num; + + amip = m->app_info; + ami_cnt = 0; + if (!amip) + return; + CRYPTO_THREADID_cpy(&ti, &amip->threadid); + + do { + int buf_len; + int info_len; + + ami_cnt++; + memset(buf, '>', ami_cnt); + BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt, + " thread=%lu, file=%s, line=%d, info=\"", + CRYPTO_THREADID_hash(&amip->threadid), amip->file, + amip->line); + buf_len = strlen(buf); + info_len = strlen(amip->info); + if (128 - buf_len - 3 < info_len) { + memcpy(buf + buf_len, amip->info, 128 - buf_len - 3); + buf_len = 128 - 3; + } else { + BUF_strlcpy(buf + buf_len, amip->info, sizeof buf - buf_len); + buf_len = strlen(buf); + } + BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n"); + + BIO_puts(l->bio, buf); + + amip = amip->next; + } + while (amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti)); + +#ifdef LEVITTE_DEBUG_MEM + if (amip) { + fprintf(stderr, "Thread switch detected in backtrace!!!!\n"); + abort(); + } +#endif +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK) + +void CRYPTO_mem_leaks(BIO *b) +{ + MEM_LEAK ml; + + if (mh == NULL && amih == NULL) + return; + + MemCheck_off(); /* obtain MALLOC2 lock */ + + ml.bio = b; + ml.bytes = 0; + ml.chunks = 0; + if (mh != NULL) + lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), MEM_LEAK, &ml); + if (ml.chunks != 0) { + BIO_printf(b, "%ld bytes leaked in %d chunks\n", ml.bytes, ml.chunks); +#ifdef CRYPTO_MDEBUG_ABORT + abort(); +#endif + } else { + /* + * Make sure that, if we found no leaks, memory-leak debugging itself + * does not introduce memory leaks (which might irritate external + * debugging tools). (When someone enables leak checking, but does not + * call this function, we declare it to be their fault.) XXX This + * should be in CRYPTO_mem_leaks_cb, and CRYPTO_mem_leaks should be + * implemented by using CRYPTO_mem_leaks_cb. (Also there should be a + * variant of lh_doall_arg that takes a function pointer instead of a + * void *; this would obviate the ugly and illegal void_fn_to_char + * kludge in CRYPTO_mem_leaks_cb. Otherwise the code police will come + * and get us.) + */ + int old_mh_mode; + + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); + + /* + * avoid deadlock when lh_free() uses CRYPTO_dbg_free(), which uses + * CRYPTO_is_mem_check_on + */ + old_mh_mode = mh_mode; + mh_mode = CRYPTO_MEM_CHECK_OFF; + + if (mh != NULL) { + lh_MEM_free(mh); + mh = NULL; + } + if (amih != NULL) { + if (lh_APP_INFO_num_items(amih) == 0) { + lh_APP_INFO_free(amih); + amih = NULL; + } + } + + mh_mode = old_mh_mode; + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); + } + MemCheck_on(); /* release MALLOC2 lock */ +} + +#ifndef OPENSSL_NO_FP_API +void CRYPTO_mem_leaks_fp(FILE *fp) +{ + BIO *b; + + if (mh == NULL) + return; + /* + * Need to turn off memory checking when allocated BIOs ... especially as + * we're creating them at a time when we're trying to check we've not + * left anything un-free()'d!! + */ + MemCheck_off(); + b = BIO_new(BIO_s_file()); + MemCheck_on(); + if (!b) + return; + BIO_set_fp(b, fp, BIO_NOCLOSE); + CRYPTO_mem_leaks(b); + BIO_free(b); +} +#endif + +/* + * FIXME: We really don't allow much to the callback. For example, it has no + * chance of reaching the info stack for the item it processes. Should it + * really be this way? -- Richard Levitte + */ +/* + * NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside + * crypto.h If this code is restructured, remove the callback type if it is + * no longer needed. -- Geoff Thorpe + */ + +/* + * Can't pass CRYPTO_MEM_LEAK_CB directly to lh_MEM_doall_arg because it is a + * function pointer and conversion to void * is prohibited. Instead pass its + * address + */ + +typedef CRYPTO_MEM_LEAK_CB *PCRYPTO_MEM_LEAK_CB; + +static void cb_leak_doall_arg(const MEM *m, PCRYPTO_MEM_LEAK_CB *cb) +{ + (*cb) (m->order, m->file, m->line, m->num, m->addr); +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM, PCRYPTO_MEM_LEAK_CB) + +void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb) +{ + if (mh == NULL) + return; + CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); + lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), PCRYPTO_MEM_LEAK_CB, + &cb); + CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); +} diff --git a/libs/openssl/crypto/modes/asm/ghash-alpha.pl b/libs/openssl/crypto/modes/asm/ghash-alpha.pl new file mode 100644 index 00000000..aa360293 --- /dev/null +++ b/libs/openssl/crypto/modes/asm/ghash-alpha.pl @@ -0,0 +1,460 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# March 2010 +# +# The module implements "4-bit" GCM GHASH function and underlying +# single multiplication operation in GF(2^128). "4-bit" means that it +# uses 256 bytes per-key table [+128 bytes shared table]. Even though +# loops are aggressively modulo-scheduled in respect to references to +# Htbl and Z.hi updates for 8 cycles per byte, measured performance is +# ~12 cycles per processed byte on 21264 CPU. It seems to be a dynamic +# scheduling "glitch," because uprofile(1) indicates uniform sample +# distribution, as if all instruction bundles execute in 1.5 cycles. +# Meaning that it could have been even faster, yet 12 cycles is ~60% +# better than gcc-generated code and ~80% than code generated by vendor +# compiler. + +$cnt="v0"; # $0 +$t0="t0"; +$t1="t1"; +$t2="t2"; +$Thi0="t3"; # $4 +$Tlo0="t4"; +$Thi1="t5"; +$Tlo1="t6"; +$rem="t7"; # $8 +################# +$Xi="a0"; # $16, input argument block +$Htbl="a1"; +$inp="a2"; +$len="a3"; +$nlo="a4"; # $20 +$nhi="a5"; +$Zhi="t8"; +$Zlo="t9"; +$Xhi="t10"; # $24 +$Xlo="t11"; +$remp="t12"; +$rem_4bit="AT"; # $28 + +{ my $N; + sub loop() { + + $N++; +$code.=<<___; +.align 4 + extbl $Xlo,7,$nlo + and $nlo,0xf0,$nhi + sll $nlo,4,$nlo + and $nlo,0xf0,$nlo + + addq $nlo,$Htbl,$nlo + ldq $Zlo,8($nlo) + addq $nhi,$Htbl,$nhi + ldq $Zhi,0($nlo) + + and $Zlo,0x0f,$remp + sll $Zhi,60,$t0 + lda $cnt,6(zero) + extbl $Xlo,6,$nlo + + ldq $Tlo1,8($nhi) + s8addq $remp,$rem_4bit,$remp + ldq $Thi1,0($nhi) + srl $Zlo,4,$Zlo + + ldq $rem,0($remp) + srl $Zhi,4,$Zhi + xor $t0,$Zlo,$Zlo + and $nlo,0xf0,$nhi + + xor $Tlo1,$Zlo,$Zlo + sll $nlo,4,$nlo + xor $Thi1,$Zhi,$Zhi + and $nlo,0xf0,$nlo + + addq $nlo,$Htbl,$nlo + ldq $Tlo0,8($nlo) + addq $nhi,$Htbl,$nhi + ldq $Thi0,0($nlo) + +.Looplo$N: + and $Zlo,0x0f,$remp + sll $Zhi,60,$t0 + subq $cnt,1,$cnt + srl $Zlo,4,$Zlo + + ldq $Tlo1,8($nhi) + xor $rem,$Zhi,$Zhi + ldq $Thi1,0($nhi) + s8addq $remp,$rem_4bit,$remp + + ldq $rem,0($remp) + srl $Zhi,4,$Zhi + xor $t0,$Zlo,$Zlo + extbl $Xlo,$cnt,$nlo + + and $nlo,0xf0,$nhi + xor $Thi0,$Zhi,$Zhi + xor $Tlo0,$Zlo,$Zlo + sll $nlo,4,$nlo + + + and $Zlo,0x0f,$remp + sll $Zhi,60,$t0 + and $nlo,0xf0,$nlo + srl $Zlo,4,$Zlo + + s8addq $remp,$rem_4bit,$remp + xor $rem,$Zhi,$Zhi + addq $nlo,$Htbl,$nlo + addq $nhi,$Htbl,$nhi + + ldq $rem,0($remp) + srl $Zhi,4,$Zhi + ldq $Tlo0,8($nlo) + xor $t0,$Zlo,$Zlo + + xor $Tlo1,$Zlo,$Zlo + xor $Thi1,$Zhi,$Zhi + ldq $Thi0,0($nlo) + bne $cnt,.Looplo$N + + + and $Zlo,0x0f,$remp + sll $Zhi,60,$t0 + lda $cnt,7(zero) + srl $Zlo,4,$Zlo + + ldq $Tlo1,8($nhi) + xor $rem,$Zhi,$Zhi + ldq $Thi1,0($nhi) + s8addq $remp,$rem_4bit,$remp + + ldq $rem,0($remp) + srl $Zhi,4,$Zhi + xor $t0,$Zlo,$Zlo + extbl $Xhi,$cnt,$nlo + + and $nlo,0xf0,$nhi + xor $Thi0,$Zhi,$Zhi + xor $Tlo0,$Zlo,$Zlo + sll $nlo,4,$nlo + + and $Zlo,0x0f,$remp + sll $Zhi,60,$t0 + and $nlo,0xf0,$nlo + srl $Zlo,4,$Zlo + + s8addq $remp,$rem_4bit,$remp + xor $rem,$Zhi,$Zhi + addq $nlo,$Htbl,$nlo + addq $nhi,$Htbl,$nhi + + ldq $rem,0($remp) + srl $Zhi,4,$Zhi + ldq $Tlo0,8($nlo) + xor $t0,$Zlo,$Zlo + + xor $Tlo1,$Zlo,$Zlo + xor $Thi1,$Zhi,$Zhi + ldq $Thi0,0($nlo) + unop + + +.Loophi$N: + and $Zlo,0x0f,$remp + sll $Zhi,60,$t0 + subq $cnt,1,$cnt + srl $Zlo,4,$Zlo + + ldq $Tlo1,8($nhi) + xor $rem,$Zhi,$Zhi + ldq $Thi1,0($nhi) + s8addq $remp,$rem_4bit,$remp + + ldq $rem,0($remp) + srl $Zhi,4,$Zhi + xor $t0,$Zlo,$Zlo + extbl $Xhi,$cnt,$nlo + + and $nlo,0xf0,$nhi + xor $Thi0,$Zhi,$Zhi + xor $Tlo0,$Zlo,$Zlo + sll $nlo,4,$nlo + + + and $Zlo,0x0f,$remp + sll $Zhi,60,$t0 + and $nlo,0xf0,$nlo + srl $Zlo,4,$Zlo + + s8addq $remp,$rem_4bit,$remp + xor $rem,$Zhi,$Zhi + addq $nlo,$Htbl,$nlo + addq $nhi,$Htbl,$nhi + + ldq $rem,0($remp) + srl $Zhi,4,$Zhi + ldq $Tlo0,8($nlo) + xor $t0,$Zlo,$Zlo + + xor $Tlo1,$Zlo,$Zlo + xor $Thi1,$Zhi,$Zhi + ldq $Thi0,0($nlo) + bne $cnt,.Loophi$N + + + and $Zlo,0x0f,$remp + sll $Zhi,60,$t0 + srl $Zlo,4,$Zlo + + ldq $Tlo1,8($nhi) + xor $rem,$Zhi,$Zhi + ldq $Thi1,0($nhi) + s8addq $remp,$rem_4bit,$remp + + ldq $rem,0($remp) + srl $Zhi,4,$Zhi + xor $t0,$Zlo,$Zlo + + xor $Tlo0,$Zlo,$Zlo + xor $Thi0,$Zhi,$Zhi + + and $Zlo,0x0f,$remp + sll $Zhi,60,$t0 + srl $Zlo,4,$Zlo + + s8addq $remp,$rem_4bit,$remp + xor $rem,$Zhi,$Zhi + + ldq $rem,0($remp) + srl $Zhi,4,$Zhi + xor $Tlo1,$Zlo,$Zlo + xor $Thi1,$Zhi,$Zhi + xor $t0,$Zlo,$Zlo + xor $rem,$Zhi,$Zhi +___ +}} + +$code=<<___; +#ifdef __linux__ +#include +#else +#include +#include +#endif + +.text + +.set noat +.set noreorder +.globl gcm_gmult_4bit +.align 4 +.ent gcm_gmult_4bit +gcm_gmult_4bit: + .frame sp,0,ra + .prologue 0 + + ldq $Xlo,8($Xi) + ldq $Xhi,0($Xi) + + bsr $t0,picmeup + nop +___ + + &loop(); + +$code.=<<___; + srl $Zlo,24,$t0 # byte swap + srl $Zlo,8,$t1 + + sll $Zlo,8,$t2 + sll $Zlo,24,$Zlo + zapnot $t0,0x11,$t0 + zapnot $t1,0x22,$t1 + + zapnot $Zlo,0x88,$Zlo + or $t0,$t1,$t0 + zapnot $t2,0x44,$t2 + + or $Zlo,$t0,$Zlo + srl $Zhi,24,$t0 + srl $Zhi,8,$t1 + + or $Zlo,$t2,$Zlo + sll $Zhi,8,$t2 + sll $Zhi,24,$Zhi + + srl $Zlo,32,$Xlo + sll $Zlo,32,$Zlo + + zapnot $t0,0x11,$t0 + zapnot $t1,0x22,$t1 + or $Zlo,$Xlo,$Xlo + + zapnot $Zhi,0x88,$Zhi + or $t0,$t1,$t0 + zapnot $t2,0x44,$t2 + + or $Zhi,$t0,$Zhi + or $Zhi,$t2,$Zhi + + srl $Zhi,32,$Xhi + sll $Zhi,32,$Zhi + + or $Zhi,$Xhi,$Xhi + stq $Xlo,8($Xi) + stq $Xhi,0($Xi) + + ret (ra) +.end gcm_gmult_4bit +___ + +$inhi="s0"; +$inlo="s1"; + +$code.=<<___; +.globl gcm_ghash_4bit +.align 4 +.ent gcm_ghash_4bit +gcm_ghash_4bit: + lda sp,-32(sp) + stq ra,0(sp) + stq s0,8(sp) + stq s1,16(sp) + .mask 0x04000600,-32 + .frame sp,32,ra + .prologue 0 + + ldq_u $inhi,0($inp) + ldq_u $Thi0,7($inp) + ldq_u $inlo,8($inp) + ldq_u $Tlo0,15($inp) + ldq $Xhi,0($Xi) + ldq $Xlo,8($Xi) + + bsr $t0,picmeup + nop + +.Louter: + extql $inhi,$inp,$inhi + extqh $Thi0,$inp,$Thi0 + or $inhi,$Thi0,$inhi + lda $inp,16($inp) + + extql $inlo,$inp,$inlo + extqh $Tlo0,$inp,$Tlo0 + or $inlo,$Tlo0,$inlo + subq $len,16,$len + + xor $Xlo,$inlo,$Xlo + xor $Xhi,$inhi,$Xhi +___ + + &loop(); + +$code.=<<___; + srl $Zlo,24,$t0 # byte swap + srl $Zlo,8,$t1 + + sll $Zlo,8,$t2 + sll $Zlo,24,$Zlo + zapnot $t0,0x11,$t0 + zapnot $t1,0x22,$t1 + + zapnot $Zlo,0x88,$Zlo + or $t0,$t1,$t0 + zapnot $t2,0x44,$t2 + + or $Zlo,$t0,$Zlo + srl $Zhi,24,$t0 + srl $Zhi,8,$t1 + + or $Zlo,$t2,$Zlo + sll $Zhi,8,$t2 + sll $Zhi,24,$Zhi + + srl $Zlo,32,$Xlo + sll $Zlo,32,$Zlo + beq $len,.Ldone + + zapnot $t0,0x11,$t0 + zapnot $t1,0x22,$t1 + or $Zlo,$Xlo,$Xlo + ldq_u $inhi,0($inp) + + zapnot $Zhi,0x88,$Zhi + or $t0,$t1,$t0 + zapnot $t2,0x44,$t2 + ldq_u $Thi0,7($inp) + + or $Zhi,$t0,$Zhi + or $Zhi,$t2,$Zhi + ldq_u $inlo,8($inp) + ldq_u $Tlo0,15($inp) + + srl $Zhi,32,$Xhi + sll $Zhi,32,$Zhi + + or $Zhi,$Xhi,$Xhi + br zero,.Louter + +.Ldone: + zapnot $t0,0x11,$t0 + zapnot $t1,0x22,$t1 + or $Zlo,$Xlo,$Xlo + + zapnot $Zhi,0x88,$Zhi + or $t0,$t1,$t0 + zapnot $t2,0x44,$t2 + + or $Zhi,$t0,$Zhi + or $Zhi,$t2,$Zhi + + srl $Zhi,32,$Xhi + sll $Zhi,32,$Zhi + + or $Zhi,$Xhi,$Xhi + + stq $Xlo,8($Xi) + stq $Xhi,0($Xi) + + .set noreorder + /*ldq ra,0(sp)*/ + ldq s0,8(sp) + ldq s1,16(sp) + lda sp,32(sp) + ret (ra) +.end gcm_ghash_4bit + +.align 4 +.ent picmeup +picmeup: + .frame sp,0,$t0 + .prologue 0 + br $rem_4bit,.Lpic +.Lpic: lda $rem_4bit,12($rem_4bit) + ret ($t0) +.end picmeup + nop +rem_4bit: + .long 0,0x0000<<16, 0,0x1C20<<16, 0,0x3840<<16, 0,0x2460<<16 + .long 0,0x7080<<16, 0,0x6CA0<<16, 0,0x48C0<<16, 0,0x54E0<<16 + .long 0,0xE100<<16, 0,0xFD20<<16, 0,0xD940<<16, 0,0xC560<<16 + .long 0,0x9180<<16, 0,0x8DA0<<16, 0,0xA9C0<<16, 0,0xB5E0<<16 +.ascii "GHASH for Alpha, CRYPTOGAMS by " +.align 4 + +___ +$output=shift and open STDOUT,">$output"; +print $code; +close STDOUT; + diff --git a/libs/openssl/crypto/modes/asm/ghash-armv4.pl b/libs/openssl/crypto/modes/asm/ghash-armv4.pl new file mode 100644 index 00000000..e46f8e34 --- /dev/null +++ b/libs/openssl/crypto/modes/asm/ghash-armv4.pl @@ -0,0 +1,429 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# April 2010 +# +# The module implements "4-bit" GCM GHASH function and underlying +# single multiplication operation in GF(2^128). "4-bit" means that it +# uses 256 bytes per-key table [+32 bytes shared table]. There is no +# experimental performance data available yet. The only approximation +# that can be made at this point is based on code size. Inner loop is +# 32 instructions long and on single-issue core should execute in <40 +# cycles. Having verified that gcc 3.4 didn't unroll corresponding +# loop, this assembler loop body was found to be ~3x smaller than +# compiler-generated one... +# +# July 2010 +# +# Rescheduling for dual-issue pipeline resulted in 8.5% improvement on +# Cortex A8 core and ~25 cycles per processed byte (which was observed +# to be ~3 times faster than gcc-generated code:-) +# +# February 2011 +# +# Profiler-assisted and platform-specific optimization resulted in 7% +# improvement on Cortex A8 core and ~23.5 cycles per byte. +# +# March 2011 +# +# Add NEON implementation featuring polynomial multiplication, i.e. no +# lookup tables involved. On Cortex A8 it was measured to process one +# byte in 15 cycles or 55% faster than integer-only code. + +# ==================================================================== +# Note about "528B" variant. In ARM case it makes lesser sense to +# implement it for following reasons: +# +# - performance improvement won't be anywhere near 50%, because 128- +# bit shift operation is neatly fused with 128-bit xor here, and +# "538B" variant would eliminate only 4-5 instructions out of 32 +# in the inner loop (meaning that estimated improvement is ~15%); +# - ARM-based systems are often embedded ones and extra memory +# consumption might be unappreciated (for so little improvement); +# +# Byte order [in]dependence. ========================================= +# +# Caller is expected to maintain specific *dword* order in Htable, +# namely with *least* significant dword of 128-bit value at *lower* +# address. This differs completely from C code and has everything to +# do with ldm instruction and order in which dwords are "consumed" by +# algorithm. *Byte* order within these dwords in turn is whatever +# *native* byte order on current platform. See gcm128.c for working +# example... + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +$Xi="r0"; # argument block +$Htbl="r1"; +$inp="r2"; +$len="r3"; + +$Zll="r4"; # variables +$Zlh="r5"; +$Zhl="r6"; +$Zhh="r7"; +$Tll="r8"; +$Tlh="r9"; +$Thl="r10"; +$Thh="r11"; +$nlo="r12"; +################# r13 is stack pointer +$nhi="r14"; +################# r15 is program counter + +$rem_4bit=$inp; # used in gcm_gmult_4bit +$cnt=$len; + +sub Zsmash() { + my $i=12; + my @args=@_; + for ($Zll,$Zlh,$Zhl,$Zhh) { + $code.=<<___; +#if __ARM_ARCH__>=7 && defined(__ARMEL__) + rev $_,$_ + str $_,[$Xi,#$i] +#elif defined(__ARMEB__) + str $_,[$Xi,#$i] +#else + mov $Tlh,$_,lsr#8 + strb $_,[$Xi,#$i+3] + mov $Thl,$_,lsr#16 + strb $Tlh,[$Xi,#$i+2] + mov $Thh,$_,lsr#24 + strb $Thl,[$Xi,#$i+1] + strb $Thh,[$Xi,#$i] +#endif +___ + $code.="\t".shift(@args)."\n"; + $i-=4; + } +} + +$code=<<___; +#include "arm_arch.h" + +.text +.code 32 + +.type rem_4bit,%object +.align 5 +rem_4bit: +.short 0x0000,0x1C20,0x3840,0x2460 +.short 0x7080,0x6CA0,0x48C0,0x54E0 +.short 0xE100,0xFD20,0xD940,0xC560 +.short 0x9180,0x8DA0,0xA9C0,0xB5E0 +.size rem_4bit,.-rem_4bit + +.type rem_4bit_get,%function +rem_4bit_get: + sub $rem_4bit,pc,#8 + sub $rem_4bit,$rem_4bit,#32 @ &rem_4bit + b .Lrem_4bit_got + nop +.size rem_4bit_get,.-rem_4bit_get + +.global gcm_ghash_4bit +.type gcm_ghash_4bit,%function +gcm_ghash_4bit: + sub r12,pc,#8 + add $len,$inp,$len @ $len to point at the end + stmdb sp!,{r3-r11,lr} @ save $len/end too + sub r12,r12,#48 @ &rem_4bit + + ldmia r12,{r4-r11} @ copy rem_4bit ... + stmdb sp!,{r4-r11} @ ... to stack + + ldrb $nlo,[$inp,#15] + ldrb $nhi,[$Xi,#15] +.Louter: + eor $nlo,$nlo,$nhi + and $nhi,$nlo,#0xf0 + and $nlo,$nlo,#0x0f + mov $cnt,#14 + + add $Zhh,$Htbl,$nlo,lsl#4 + ldmia $Zhh,{$Zll-$Zhh} @ load Htbl[nlo] + add $Thh,$Htbl,$nhi + ldrb $nlo,[$inp,#14] + + and $nhi,$Zll,#0xf @ rem + ldmia $Thh,{$Tll-$Thh} @ load Htbl[nhi] + add $nhi,$nhi,$nhi + eor $Zll,$Tll,$Zll,lsr#4 + ldrh $Tll,[sp,$nhi] @ rem_4bit[rem] + eor $Zll,$Zll,$Zlh,lsl#28 + ldrb $nhi,[$Xi,#14] + eor $Zlh,$Tlh,$Zlh,lsr#4 + eor $Zlh,$Zlh,$Zhl,lsl#28 + eor $Zhl,$Thl,$Zhl,lsr#4 + eor $Zhl,$Zhl,$Zhh,lsl#28 + eor $Zhh,$Thh,$Zhh,lsr#4 + eor $nlo,$nlo,$nhi + and $nhi,$nlo,#0xf0 + and $nlo,$nlo,#0x0f + eor $Zhh,$Zhh,$Tll,lsl#16 + +.Linner: + add $Thh,$Htbl,$nlo,lsl#4 + and $nlo,$Zll,#0xf @ rem + subs $cnt,$cnt,#1 + add $nlo,$nlo,$nlo + ldmia $Thh,{$Tll-$Thh} @ load Htbl[nlo] + eor $Zll,$Tll,$Zll,lsr#4 + eor $Zll,$Zll,$Zlh,lsl#28 + eor $Zlh,$Tlh,$Zlh,lsr#4 + eor $Zlh,$Zlh,$Zhl,lsl#28 + ldrh $Tll,[sp,$nlo] @ rem_4bit[rem] + eor $Zhl,$Thl,$Zhl,lsr#4 + ldrplb $nlo,[$inp,$cnt] + eor $Zhl,$Zhl,$Zhh,lsl#28 + eor $Zhh,$Thh,$Zhh,lsr#4 + + add $Thh,$Htbl,$nhi + and $nhi,$Zll,#0xf @ rem + eor $Zhh,$Zhh,$Tll,lsl#16 @ ^= rem_4bit[rem] + add $nhi,$nhi,$nhi + ldmia $Thh,{$Tll-$Thh} @ load Htbl[nhi] + eor $Zll,$Tll,$Zll,lsr#4 + ldrplb $Tll,[$Xi,$cnt] + eor $Zll,$Zll,$Zlh,lsl#28 + eor $Zlh,$Tlh,$Zlh,lsr#4 + ldrh $Tlh,[sp,$nhi] + eor $Zlh,$Zlh,$Zhl,lsl#28 + eor $Zhl,$Thl,$Zhl,lsr#4 + eor $Zhl,$Zhl,$Zhh,lsl#28 + eorpl $nlo,$nlo,$Tll + eor $Zhh,$Thh,$Zhh,lsr#4 + andpl $nhi,$nlo,#0xf0 + andpl $nlo,$nlo,#0x0f + eor $Zhh,$Zhh,$Tlh,lsl#16 @ ^= rem_4bit[rem] + bpl .Linner + + ldr $len,[sp,#32] @ re-load $len/end + add $inp,$inp,#16 + mov $nhi,$Zll +___ + &Zsmash("cmp\t$inp,$len","ldrneb\t$nlo,[$inp,#15]"); +$code.=<<___; + bne .Louter + + add sp,sp,#36 +#if __ARM_ARCH__>=5 + ldmia sp!,{r4-r11,pc} +#else + ldmia sp!,{r4-r11,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif +.size gcm_ghash_4bit,.-gcm_ghash_4bit + +.global gcm_gmult_4bit +.type gcm_gmult_4bit,%function +gcm_gmult_4bit: + stmdb sp!,{r4-r11,lr} + ldrb $nlo,[$Xi,#15] + b rem_4bit_get +.Lrem_4bit_got: + and $nhi,$nlo,#0xf0 + and $nlo,$nlo,#0x0f + mov $cnt,#14 + + add $Zhh,$Htbl,$nlo,lsl#4 + ldmia $Zhh,{$Zll-$Zhh} @ load Htbl[nlo] + ldrb $nlo,[$Xi,#14] + + add $Thh,$Htbl,$nhi + and $nhi,$Zll,#0xf @ rem + ldmia $Thh,{$Tll-$Thh} @ load Htbl[nhi] + add $nhi,$nhi,$nhi + eor $Zll,$Tll,$Zll,lsr#4 + ldrh $Tll,[$rem_4bit,$nhi] @ rem_4bit[rem] + eor $Zll,$Zll,$Zlh,lsl#28 + eor $Zlh,$Tlh,$Zlh,lsr#4 + eor $Zlh,$Zlh,$Zhl,lsl#28 + eor $Zhl,$Thl,$Zhl,lsr#4 + eor $Zhl,$Zhl,$Zhh,lsl#28 + eor $Zhh,$Thh,$Zhh,lsr#4 + and $nhi,$nlo,#0xf0 + eor $Zhh,$Zhh,$Tll,lsl#16 + and $nlo,$nlo,#0x0f + +.Loop: + add $Thh,$Htbl,$nlo,lsl#4 + and $nlo,$Zll,#0xf @ rem + subs $cnt,$cnt,#1 + add $nlo,$nlo,$nlo + ldmia $Thh,{$Tll-$Thh} @ load Htbl[nlo] + eor $Zll,$Tll,$Zll,lsr#4 + eor $Zll,$Zll,$Zlh,lsl#28 + eor $Zlh,$Tlh,$Zlh,lsr#4 + eor $Zlh,$Zlh,$Zhl,lsl#28 + ldrh $Tll,[$rem_4bit,$nlo] @ rem_4bit[rem] + eor $Zhl,$Thl,$Zhl,lsr#4 + ldrplb $nlo,[$Xi,$cnt] + eor $Zhl,$Zhl,$Zhh,lsl#28 + eor $Zhh,$Thh,$Zhh,lsr#4 + + add $Thh,$Htbl,$nhi + and $nhi,$Zll,#0xf @ rem + eor $Zhh,$Zhh,$Tll,lsl#16 @ ^= rem_4bit[rem] + add $nhi,$nhi,$nhi + ldmia $Thh,{$Tll-$Thh} @ load Htbl[nhi] + eor $Zll,$Tll,$Zll,lsr#4 + eor $Zll,$Zll,$Zlh,lsl#28 + eor $Zlh,$Tlh,$Zlh,lsr#4 + ldrh $Tll,[$rem_4bit,$nhi] @ rem_4bit[rem] + eor $Zlh,$Zlh,$Zhl,lsl#28 + eor $Zhl,$Thl,$Zhl,lsr#4 + eor $Zhl,$Zhl,$Zhh,lsl#28 + eor $Zhh,$Thh,$Zhh,lsr#4 + andpl $nhi,$nlo,#0xf0 + andpl $nlo,$nlo,#0x0f + eor $Zhh,$Zhh,$Tll,lsl#16 @ ^= rem_4bit[rem] + bpl .Loop +___ + &Zsmash(); +$code.=<<___; +#if __ARM_ARCH__>=5 + ldmia sp!,{r4-r11,pc} +#else + ldmia sp!,{r4-r11,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif +.size gcm_gmult_4bit,.-gcm_gmult_4bit +___ +{ +my $cnt=$Htbl; # $Htbl is used once in the very beginning + +my ($Hhi, $Hlo, $Zo, $T, $xi, $mod) = map("d$_",(0..7)); +my ($Qhi, $Qlo, $Z, $R, $zero, $Qpost, $IN) = map("q$_",(8..15)); + +# Z:Zo keeps 128-bit result shifted by 1 to the right, with bottom bit +# in Zo. Or should I say "top bit", because GHASH is specified in +# reverse bit order? Otherwise straightforward 128-bt H by one input +# byte multiplication and modulo-reduction, times 16. + +sub Dlo() { shift=~m|q([1]?[0-9])|?"d".($1*2):""; } +sub Dhi() { shift=~m|q([1]?[0-9])|?"d".($1*2+1):""; } +sub Q() { shift=~m|d([1-3]?[02468])|?"q".($1/2):""; } + +$code.=<<___; +#if __ARM_ARCH__>=7 +.fpu neon + +.global gcm_gmult_neon +.type gcm_gmult_neon,%function +.align 4 +gcm_gmult_neon: + sub $Htbl,#16 @ point at H in GCM128_CTX + vld1.64 `&Dhi("$IN")`,[$Xi,:64]!@ load Xi + vmov.i32 $mod,#0xe1 @ our irreducible polynomial + vld1.64 `&Dlo("$IN")`,[$Xi,:64]! + vshr.u64 $mod,#32 + vldmia $Htbl,{$Hhi-$Hlo} @ load H + veor $zero,$zero +#ifdef __ARMEL__ + vrev64.8 $IN,$IN +#endif + veor $Qpost,$Qpost + veor $R,$R + mov $cnt,#16 + veor $Z,$Z + mov $len,#16 + veor $Zo,$Zo + vdup.8 $xi,`&Dlo("$IN")`[0] @ broadcast lowest byte + b .Linner_neon +.size gcm_gmult_neon,.-gcm_gmult_neon + +.global gcm_ghash_neon +.type gcm_ghash_neon,%function +.align 4 +gcm_ghash_neon: + vld1.64 `&Dhi("$Z")`,[$Xi,:64]! @ load Xi + vmov.i32 $mod,#0xe1 @ our irreducible polynomial + vld1.64 `&Dlo("$Z")`,[$Xi,:64]! + vshr.u64 $mod,#32 + vldmia $Xi,{$Hhi-$Hlo} @ load H + veor $zero,$zero + nop +#ifdef __ARMEL__ + vrev64.8 $Z,$Z +#endif +.Louter_neon: + vld1.64 `&Dhi($IN)`,[$inp]! @ load inp + veor $Qpost,$Qpost + vld1.64 `&Dlo($IN)`,[$inp]! + veor $R,$R + mov $cnt,#16 +#ifdef __ARMEL__ + vrev64.8 $IN,$IN +#endif + veor $Zo,$Zo + veor $IN,$Z @ inp^=Xi + veor $Z,$Z + vdup.8 $xi,`&Dlo("$IN")`[0] @ broadcast lowest byte +.Linner_neon: + subs $cnt,$cnt,#1 + vmull.p8 $Qlo,$Hlo,$xi @ H.lo·Xi[i] + vmull.p8 $Qhi,$Hhi,$xi @ H.hi·Xi[i] + vext.8 $IN,$zero,#1 @ IN>>=8 + + veor $Z,$Qpost @ modulo-scheduled part + vshl.i64 `&Dlo("$R")`,#48 + vdup.8 $xi,`&Dlo("$IN")`[0] @ broadcast lowest byte + veor $T,`&Dlo("$Qlo")`,`&Dlo("$Z")` + + veor `&Dhi("$Z")`,`&Dlo("$R")` + vuzp.8 $Qlo,$Qhi + vsli.8 $Zo,$T,#1 @ compose the "carry" byte + vext.8 $Z,$zero,#1 @ Z>>=8 + + vmull.p8 $R,$Zo,$mod @ "carry"·0xe1 + vshr.u8 $Zo,$T,#7 @ save Z's bottom bit + vext.8 $Qpost,$Qlo,$zero,#1 @ Qlo>>=8 + veor $Z,$Qhi + bne .Linner_neon + + veor $Z,$Qpost @ modulo-scheduled artefact + vshl.i64 `&Dlo("$R")`,#48 + veor `&Dhi("$Z")`,`&Dlo("$R")` + + @ finalization, normalize Z:Zo + vand $Zo,$mod @ suffices to mask the bit + vshr.u64 `&Dhi(&Q("$Zo"))`,`&Dlo("$Z")`,#63 + vshl.i64 $Z,#1 + subs $len,#16 + vorr $Z,`&Q("$Zo")` @ Z=Z:Zo<<1 + bne .Louter_neon + +#ifdef __ARMEL__ + vrev64.8 $Z,$Z +#endif + sub $Xi,#16 + vst1.64 `&Dhi("$Z")`,[$Xi,:64]! @ write out Xi + vst1.64 `&Dlo("$Z")`,[$Xi,:64] + + bx lr +.size gcm_ghash_neon,.-gcm_ghash_neon +#endif +___ +} +$code.=<<___; +.asciz "GHASH for ARMv4/NEON, CRYPTOGAMS by " +.align 2 +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 +print $code; +close STDOUT; # enforce flush diff --git a/libs/openssl/crypto/modes/asm/ghash-ia64.pl b/libs/openssl/crypto/modes/asm/ghash-ia64.pl new file mode 100755 index 00000000..0354c954 --- /dev/null +++ b/libs/openssl/crypto/modes/asm/ghash-ia64.pl @@ -0,0 +1,463 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# March 2010 +# +# The module implements "4-bit" GCM GHASH function and underlying +# single multiplication operation in GF(2^128). "4-bit" means that it +# uses 256 bytes per-key table [+128 bytes shared table]. Streamed +# GHASH performance was measured to be 6.67 cycles per processed byte +# on Itanium 2, which is >90% better than Microsoft compiler generated +# code. To anchor to something else sha1-ia64.pl module processes one +# byte in 5.7 cycles. On Itanium GHASH should run at ~8.5 cycles per +# byte. + +# September 2010 +# +# It was originally thought that it makes lesser sense to implement +# "528B" variant on Itanium 2 for following reason. Because number of +# functional units is naturally limited, it appeared impossible to +# implement "528B" loop in 4 cycles, only in 5. This would mean that +# theoretically performance improvement couldn't be more than 20%. +# But occasionally you prove yourself wrong:-) I figured out a way to +# fold couple of instructions and having freed yet another instruction +# slot by unrolling the loop... Resulting performance is 4.45 cycles +# per processed byte and 50% better than "256B" version. On original +# Itanium performance should remain the same as the "256B" version, +# i.e. ~8.5 cycles. + +$output=shift and (open STDOUT,">$output" or die "can't open $output: $!"); + +if ($^O eq "hpux") { + $ADDP="addp4"; + for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); } +} else { $ADDP="add"; } +for (@ARGV) { $big_endian=1 if (/\-DB_ENDIAN/); + $big_endian=0 if (/\-DL_ENDIAN/); } +if (!defined($big_endian)) + { $big_endian=(unpack('L',pack('N',1))==1); } + +sub loop() { +my $label=shift; +my ($p16,$p17)=(shift)?("p63","p63"):("p16","p17"); # mask references to inp + +# Loop is scheduled for 6 ticks on Itanium 2 and 8 on Itanium, i.e. +# in scalable manner;-) Naturally assuming data in L1 cache... +# Special note about 'dep' instruction, which is used to construct +# &rem_4bit[Zlo&0xf]. It works, because rem_4bit is aligned at 128 +# bytes boundary and lower 7 bits of its address are guaranteed to +# be zero. +$code.=<<___; +$label: +{ .mfi; (p18) ld8 Hlo=[Hi[1]],-8 + (p19) dep rem=Zlo,rem_4bitp,3,4 } +{ .mfi; (p19) xor Zhi=Zhi,Hhi + ($p17) xor xi[1]=xi[1],in[1] };; +{ .mfi; (p18) ld8 Hhi=[Hi[1]] + (p19) shrp Zlo=Zhi,Zlo,4 } +{ .mfi; (p19) ld8 rem=[rem] + (p18) and Hi[1]=mask0xf0,xi[2] };; +{ .mmi; ($p16) ld1 in[0]=[inp],-1 + (p18) xor Zlo=Zlo,Hlo + (p19) shr.u Zhi=Zhi,4 } +{ .mib; (p19) xor Hhi=Hhi,rem + (p18) add Hi[1]=Htbl,Hi[1] };; + +{ .mfi; (p18) ld8 Hlo=[Hi[1]],-8 + (p18) dep rem=Zlo,rem_4bitp,3,4 } +{ .mfi; (p17) shladd Hi[0]=xi[1],4,r0 + (p18) xor Zhi=Zhi,Hhi };; +{ .mfi; (p18) ld8 Hhi=[Hi[1]] + (p18) shrp Zlo=Zhi,Zlo,4 } +{ .mfi; (p18) ld8 rem=[rem] + (p17) and Hi[0]=mask0xf0,Hi[0] };; +{ .mmi; (p16) ld1 xi[0]=[Xi],-1 + (p18) xor Zlo=Zlo,Hlo + (p18) shr.u Zhi=Zhi,4 } +{ .mib; (p18) xor Hhi=Hhi,rem + (p17) add Hi[0]=Htbl,Hi[0] + br.ctop.sptk $label };; +___ +} + +$code=<<___; +.explicit +.text + +prevfs=r2; prevlc=r3; prevpr=r8; +mask0xf0=r21; +rem=r22; rem_4bitp=r23; +Xi=r24; Htbl=r25; +inp=r26; end=r27; +Hhi=r28; Hlo=r29; +Zhi=r30; Zlo=r31; + +.align 128 +.skip 16 // aligns loop body +.global gcm_gmult_4bit# +.proc gcm_gmult_4bit# +gcm_gmult_4bit: + .prologue +{ .mmi; .save ar.pfs,prevfs + alloc prevfs=ar.pfs,2,6,0,8 + $ADDP Xi=15,in0 // &Xi[15] + mov rem_4bitp=ip } +{ .mii; $ADDP Htbl=8,in1 // &Htbl[0].lo + .save ar.lc,prevlc + mov prevlc=ar.lc + .save pr,prevpr + mov prevpr=pr };; + + .body + .rotr in[3],xi[3],Hi[2] + +{ .mib; ld1 xi[2]=[Xi],-1 // Xi[15] + mov mask0xf0=0xf0 + brp.loop.imp .Loop1,.Lend1-16};; +{ .mmi; ld1 xi[1]=[Xi],-1 // Xi[14] + };; +{ .mii; shladd Hi[1]=xi[2],4,r0 + mov pr.rot=0x7<<16 + mov ar.lc=13 };; +{ .mii; and Hi[1]=mask0xf0,Hi[1] + mov ar.ec=3 + xor Zlo=Zlo,Zlo };; +{ .mii; add Hi[1]=Htbl,Hi[1] // &Htbl[nlo].lo + add rem_4bitp=rem_4bit#-gcm_gmult_4bit#,rem_4bitp + xor Zhi=Zhi,Zhi };; +___ + &loop (".Loop1",1); +$code.=<<___; +.Lend1: +{ .mib; xor Zhi=Zhi,Hhi };; // modulo-scheduling artefact +{ .mib; mux1 Zlo=Zlo,\@rev };; +{ .mib; mux1 Zhi=Zhi,\@rev };; +{ .mmi; add Hlo=9,Xi;; // ;; is here to prevent + add Hhi=1,Xi };; // pipeline flush on Itanium +{ .mib; st8 [Hlo]=Zlo + mov pr=prevpr,0x1ffff };; +{ .mib; st8 [Hhi]=Zhi + mov ar.lc=prevlc + br.ret.sptk.many b0 };; +.endp gcm_gmult_4bit# +___ + +###################################################################### +# "528B" (well, "512B" actualy) streamed GHASH +# +$Xip="in0"; +$Htbl="in1"; +$inp="in2"; +$len="in3"; +$rem_8bit="loc0"; +$mask0xff="loc1"; +($sum,$rum) = $big_endian ? ("nop.m","nop.m") : ("sum","rum"); + +sub load_htable() { + for (my $i=0;$i<8;$i++) { + $code.=<<___; +{ .mmi; ld8 r`16+2*$i+1`=[r8],16 // Htable[$i].hi + ld8 r`16+2*$i`=[r9],16 } // Htable[$i].lo +{ .mmi; ldf8 f`32+2*$i+1`=[r10],16 // Htable[`8+$i`].hi + ldf8 f`32+2*$i`=[r11],16 // Htable[`8+$i`].lo +___ + $code.=shift if (($i+$#_)==7); + $code.="\t};;\n" + } +} + +$code.=<<___; +prevsp=r3; + +.align 32 +.skip 16 // aligns loop body +.global gcm_ghash_4bit# +.proc gcm_ghash_4bit# +gcm_ghash_4bit: + .prologue +{ .mmi; .save ar.pfs,prevfs + alloc prevfs=ar.pfs,4,2,0,0 + .vframe prevsp + mov prevsp=sp + mov $rem_8bit=ip };; + .body +{ .mfi; $ADDP r8=0+0,$Htbl + $ADDP r9=0+8,$Htbl } +{ .mfi; $ADDP r10=128+0,$Htbl + $ADDP r11=128+8,$Htbl };; +___ + &load_htable( + " $ADDP $Xip=15,$Xip", # &Xi[15] + " $ADDP $len=$len,$inp", # &inp[len] + " $ADDP $inp=15,$inp", # &inp[15] + " mov $mask0xff=0xff", + " add sp=-512,sp", + " andcm sp=sp,$mask0xff", # align stack frame + " add r14=0,sp", + " add r15=8,sp"); +$code.=<<___; +{ .mmi; $sum 1<<1 // go big-endian + add r8=256+0,sp + add r9=256+8,sp } +{ .mmi; add r10=256+128+0,sp + add r11=256+128+8,sp + add $len=-17,$len };; +___ +for($i=0;$i<8;$i++) { # generate first half of Hshr4[] +my ($rlo,$rhi)=("r".eval(16+2*$i),"r".eval(16+2*$i+1)); +$code.=<<___; +{ .mmi; st8 [r8]=$rlo,16 // Htable[$i].lo + st8 [r9]=$rhi,16 // Htable[$i].hi + shrp $rlo=$rhi,$rlo,4 }//;; +{ .mmi; stf8 [r10]=f`32+2*$i`,16 // Htable[`8+$i`].lo + stf8 [r11]=f`32+2*$i+1`,16 // Htable[`8+$i`].hi + shr.u $rhi=$rhi,4 };; +{ .mmi; st8 [r14]=$rlo,16 // Htable[$i].lo>>4 + st8 [r15]=$rhi,16 }//;; // Htable[$i].hi>>4 +___ +} +$code.=<<___; +{ .mmi; ld8 r16=[r8],16 // Htable[8].lo + ld8 r17=[r9],16 };; // Htable[8].hi +{ .mmi; ld8 r18=[r8],16 // Htable[9].lo + ld8 r19=[r9],16 } // Htable[9].hi +{ .mmi; rum 1<<5 // clear um.mfh + shrp r16=r17,r16,4 };; +___ +for($i=0;$i<6;$i++) { # generate second half of Hshr4[] +$code.=<<___; +{ .mmi; ld8 r`20+2*$i`=[r8],16 // Htable[`10+$i`].lo + ld8 r`20+2*$i+1`=[r9],16 // Htable[`10+$i`].hi + shr.u r`16+2*$i+1`=r`16+2*$i+1`,4 };; +{ .mmi; st8 [r14]=r`16+2*$i`,16 // Htable[`8+$i`].lo>>4 + st8 [r15]=r`16+2*$i+1`,16 // Htable[`8+$i`].hi>>4 + shrp r`18+2*$i`=r`18+2*$i+1`,r`18+2*$i`,4 } +___ +} +$code.=<<___; +{ .mmi; shr.u r`16+2*$i+1`=r`16+2*$i+1`,4 };; +{ .mmi; st8 [r14]=r`16+2*$i`,16 // Htable[`8+$i`].lo>>4 + st8 [r15]=r`16+2*$i+1`,16 // Htable[`8+$i`].hi>>4 + shrp r`18+2*$i`=r`18+2*$i+1`,r`18+2*$i`,4 } +{ .mmi; add $Htbl=256,sp // &Htable[0] + add $rem_8bit=rem_8bit#-gcm_ghash_4bit#,$rem_8bit + shr.u r`18+2*$i+1`=r`18+2*$i+1`,4 };; +{ .mmi; st8 [r14]=r`18+2*$i` // Htable[`8+$i`].lo>>4 + st8 [r15]=r`18+2*$i+1` } // Htable[`8+$i`].hi>>4 +___ + +$in="r15"; +@xi=("r16","r17"); +@rem=("r18","r19"); +($Alo,$Ahi,$Blo,$Bhi,$Zlo,$Zhi)=("r20","r21","r22","r23","r24","r25"); +($Atbl,$Btbl)=("r26","r27"); + +$code.=<<___; # (p16) +{ .mmi; ld1 $in=[$inp],-1 //(p16) *inp-- + ld1 $xi[0]=[$Xip],-1 //(p16) *Xi-- + cmp.eq p0,p6=r0,r0 };; // clear p6 +___ +push (@xi,shift(@xi)); push (@rem,shift(@rem)); # "rotate" registers + +$code.=<<___; # (p16),(p17) +{ .mmi; ld1 $xi[0]=[$Xip],-1 //(p16) *Xi-- + xor $xi[1]=$xi[1],$in };; //(p17) xi=$xi[i]^inp[i] +{ .mii; ld1 $in=[$inp],-1 //(p16) *inp-- + dep $Atbl=$xi[1],$Htbl,4,4 //(p17) &Htable[nlo].lo + and $xi[1]=-16,$xi[1] };; //(p17) nhi=xi&0xf0 +.align 32 +.LOOP: +{ .mmi; +(p6) st8 [$Xip]=$Zhi,13 + xor $Zlo=$Zlo,$Zlo + add $Btbl=$xi[1],$Htbl };; //(p17) &Htable[nhi].lo +___ +push (@xi,shift(@xi)); push (@rem,shift(@rem)); # "rotate" registers + +$code.=<<___; # (p16),(p17),(p18) +{ .mmi; ld8 $Alo=[$Atbl],8 //(p18) Htable[nlo].lo,&Htable[nlo].hi + ld8 $rem[0]=[$Btbl],-256 //(p18) Htable[nhi].lo,&Hshr4[nhi].lo + xor $xi[1]=$xi[1],$in };; //(p17) xi=$xi[i]^inp[i] +{ .mfi; ld8 $Ahi=[$Atbl] //(p18) Htable[nlo].hi + dep $Atbl=$xi[1],$Htbl,4,4 } //(p17) &Htable[nlo].lo +{ .mfi; shladd $rem[0]=$rem[0],4,r0 //(p18) Htable[nhi].lo<<4 + xor $Zlo=$Zlo,$Alo };; //(p18) Z.lo^=Htable[nlo].lo +{ .mmi; ld8 $Blo=[$Btbl],8 //(p18) Hshr4[nhi].lo,&Hshr4[nhi].hi + ld1 $in=[$inp],-1 } //(p16) *inp-- +{ .mmi; xor $rem[0]=$rem[0],$Zlo //(p18) Z.lo^(Htable[nhi].lo<<4) + mov $Zhi=$Ahi //(p18) Z.hi^=Htable[nlo].hi + and $xi[1]=-16,$xi[1] };; //(p17) nhi=xi&0xf0 +{ .mmi; ld8 $Bhi=[$Btbl] //(p18) Hshr4[nhi].hi + ld1 $xi[0]=[$Xip],-1 //(p16) *Xi-- + shrp $Zlo=$Zhi,$Zlo,8 } //(p18) Z.lo=(Z.hi<<56)|(Z.lo>>8) +{ .mmi; and $rem[0]=$rem[0],$mask0xff //(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff + add $Btbl=$xi[1],$Htbl };; //(p17) &Htable[nhi] +___ +push (@xi,shift(@xi)); push (@rem,shift(@rem)); # "rotate" registers + +for ($i=1;$i<14;$i++) { +# Above and below fragments are derived from this one by removing +# unsuitable (p??) instructions. +$code.=<<___; # (p16),(p17),(p18),(p19) +{ .mmi; ld8 $Alo=[$Atbl],8 //(p18) Htable[nlo].lo,&Htable[nlo].hi + ld8 $rem[0]=[$Btbl],-256 //(p18) Htable[nhi].lo,&Hshr4[nhi].lo + shr.u $Zhi=$Zhi,8 } //(p19) Z.hi>>=8 +{ .mmi; shladd $rem[1]=$rem[1],1,$rem_8bit //(p19) &rem_8bit[rem] + xor $Zlo=$Zlo,$Blo //(p19) Z.lo^=Hshr4[nhi].lo + xor $xi[1]=$xi[1],$in };; //(p17) xi=$xi[i]^inp[i] +{ .mmi; ld8 $Ahi=[$Atbl] //(p18) Htable[nlo].hi + ld2 $rem[1]=[$rem[1]] //(p19) rem_8bit[rem] + dep $Atbl=$xi[1],$Htbl,4,4 } //(p17) &Htable[nlo].lo +{ .mmi; shladd $rem[0]=$rem[0],4,r0 //(p18) Htable[nhi].lo<<4 + xor $Zlo=$Zlo,$Alo //(p18) Z.lo^=Htable[nlo].lo + xor $Zhi=$Zhi,$Bhi };; //(p19) Z.hi^=Hshr4[nhi].hi +{ .mmi; ld8 $Blo=[$Btbl],8 //(p18) Hshr4[nhi].lo,&Hshr4[nhi].hi + ld1 $in=[$inp],-1 //(p16) *inp-- + shl $rem[1]=$rem[1],48 } //(p19) rem_8bit[rem]<<48 +{ .mmi; xor $rem[0]=$rem[0],$Zlo //(p18) Z.lo^(Htable[nhi].lo<<4) + xor $Zhi=$Zhi,$Ahi //(p18) Z.hi^=Htable[nlo].hi + and $xi[1]=-16,$xi[1] };; //(p17) nhi=xi&0xf0 +{ .mmi; ld8 $Bhi=[$Btbl] //(p18) Hshr4[nhi].hi + ld1 $xi[0]=[$Xip],-1 //(p16) *Xi-- + shrp $Zlo=$Zhi,$Zlo,8 } //(p18) Z.lo=(Z.hi<<56)|(Z.lo>>8) +{ .mmi; and $rem[0]=$rem[0],$mask0xff //(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff + xor $Zhi=$Zhi,$rem[1] //(p19) Z.hi^=rem_8bit[rem]<<48 + add $Btbl=$xi[1],$Htbl };; //(p17) &Htable[nhi] +___ +push (@xi,shift(@xi)); push (@rem,shift(@rem)); # "rotate" registers +} + +$code.=<<___; # (p17),(p18),(p19) +{ .mmi; ld8 $Alo=[$Atbl],8 //(p18) Htable[nlo].lo,&Htable[nlo].hi + ld8 $rem[0]=[$Btbl],-256 //(p18) Htable[nhi].lo,&Hshr4[nhi].lo + shr.u $Zhi=$Zhi,8 } //(p19) Z.hi>>=8 +{ .mmi; shladd $rem[1]=$rem[1],1,$rem_8bit //(p19) &rem_8bit[rem] + xor $Zlo=$Zlo,$Blo //(p19) Z.lo^=Hshr4[nhi].lo + xor $xi[1]=$xi[1],$in };; //(p17) xi=$xi[i]^inp[i] +{ .mmi; ld8 $Ahi=[$Atbl] //(p18) Htable[nlo].hi + ld2 $rem[1]=[$rem[1]] //(p19) rem_8bit[rem] + dep $Atbl=$xi[1],$Htbl,4,4 };; //(p17) &Htable[nlo].lo +{ .mmi; shladd $rem[0]=$rem[0],4,r0 //(p18) Htable[nhi].lo<<4 + xor $Zlo=$Zlo,$Alo //(p18) Z.lo^=Htable[nlo].lo + xor $Zhi=$Zhi,$Bhi };; //(p19) Z.hi^=Hshr4[nhi].hi +{ .mmi; ld8 $Blo=[$Btbl],8 //(p18) Hshr4[nhi].lo,&Hshr4[nhi].hi + shl $rem[1]=$rem[1],48 } //(p19) rem_8bit[rem]<<48 +{ .mmi; xor $rem[0]=$rem[0],$Zlo //(p18) Z.lo^(Htable[nhi].lo<<4) + xor $Zhi=$Zhi,$Ahi //(p18) Z.hi^=Htable[nlo].hi + and $xi[1]=-16,$xi[1] };; //(p17) nhi=xi&0xf0 +{ .mmi; ld8 $Bhi=[$Btbl] //(p18) Hshr4[nhi].hi + shrp $Zlo=$Zhi,$Zlo,8 } //(p18) Z.lo=(Z.hi<<56)|(Z.lo>>8) +{ .mmi; and $rem[0]=$rem[0],$mask0xff //(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff + xor $Zhi=$Zhi,$rem[1] //(p19) Z.hi^=rem_8bit[rem]<<48 + add $Btbl=$xi[1],$Htbl };; //(p17) &Htable[nhi] +___ +push (@xi,shift(@xi)); push (@rem,shift(@rem)); # "rotate" registers + +$code.=<<___; # (p18),(p19) +{ .mfi; ld8 $Alo=[$Atbl],8 //(p18) Htable[nlo].lo,&Htable[nlo].hi + shr.u $Zhi=$Zhi,8 } //(p19) Z.hi>>=8 +{ .mfi; shladd $rem[1]=$rem[1],1,$rem_8bit //(p19) &rem_8bit[rem] + xor $Zlo=$Zlo,$Blo };; //(p19) Z.lo^=Hshr4[nhi].lo +{ .mfi; ld8 $Ahi=[$Atbl] //(p18) Htable[nlo].hi + xor $Zlo=$Zlo,$Alo } //(p18) Z.lo^=Htable[nlo].lo +{ .mfi; ld2 $rem[1]=[$rem[1]] //(p19) rem_8bit[rem] + xor $Zhi=$Zhi,$Bhi };; //(p19) Z.hi^=Hshr4[nhi].hi +{ .mfi; ld8 $Blo=[$Btbl],8 //(p18) Htable[nhi].lo,&Htable[nhi].hi + shl $rem[1]=$rem[1],48 } //(p19) rem_8bit[rem]<<48 +{ .mfi; shladd $rem[0]=$Zlo,4,r0 //(p18) Z.lo<<4 + xor $Zhi=$Zhi,$Ahi };; //(p18) Z.hi^=Htable[nlo].hi +{ .mfi; ld8 $Bhi=[$Btbl] //(p18) Htable[nhi].hi + shrp $Zlo=$Zhi,$Zlo,4 } //(p18) Z.lo=(Z.hi<<60)|(Z.lo>>4) +{ .mfi; and $rem[0]=$rem[0],$mask0xff //(p18) rem=($Zlo^(Htable[nhi].lo<<4))&0xff + xor $Zhi=$Zhi,$rem[1] };; //(p19) Z.hi^=rem_8bit[rem]<<48 +___ +push (@xi,shift(@xi)); push (@rem,shift(@rem)); # "rotate" registers + +$code.=<<___; # (p19) +{ .mmi; cmp.ltu p6,p0=$inp,$len + add $inp=32,$inp + shr.u $Zhi=$Zhi,4 } //(p19) Z.hi>>=4 +{ .mmi; shladd $rem[1]=$rem[1],1,$rem_8bit //(p19) &rem_8bit[rem] + xor $Zlo=$Zlo,$Blo //(p19) Z.lo^=Hshr4[nhi].lo + add $Xip=9,$Xip };; // &Xi.lo +{ .mmi; ld2 $rem[1]=[$rem[1]] //(p19) rem_8bit[rem] +(p6) ld1 $in=[$inp],-1 //[p16] *inp-- +(p6) extr.u $xi[1]=$Zlo,8,8 } //[p17] Xi[14] +{ .mmi; xor $Zhi=$Zhi,$Bhi //(p19) Z.hi^=Hshr4[nhi].hi +(p6) and $xi[0]=$Zlo,$mask0xff };; //[p16] Xi[15] +{ .mmi; st8 [$Xip]=$Zlo,-8 +(p6) xor $xi[0]=$xi[0],$in //[p17] xi=$xi[i]^inp[i] + shl $rem[1]=$rem[1],48 };; //(p19) rem_8bit[rem]<<48 +{ .mmi; +(p6) ld1 $in=[$inp],-1 //[p16] *inp-- + xor $Zhi=$Zhi,$rem[1] //(p19) Z.hi^=rem_8bit[rem]<<48 +(p6) dep $Atbl=$xi[0],$Htbl,4,4 } //[p17] &Htable[nlo].lo +{ .mib; +(p6) and $xi[0]=-16,$xi[0] //[p17] nhi=xi&0xf0 +(p6) br.cond.dptk.many .LOOP };; + +{ .mib; st8 [$Xip]=$Zhi };; +{ .mib; $rum 1<<1 // return to little-endian + .restore sp + mov sp=prevsp + br.ret.sptk.many b0 };; +.endp gcm_ghash_4bit# +___ +$code.=<<___; +.align 128 +.type rem_4bit#,\@object +rem_4bit: + data8 0x0000<<48, 0x1C20<<48, 0x3840<<48, 0x2460<<48 + data8 0x7080<<48, 0x6CA0<<48, 0x48C0<<48, 0x54E0<<48 + data8 0xE100<<48, 0xFD20<<48, 0xD940<<48, 0xC560<<48 + data8 0x9180<<48, 0x8DA0<<48, 0xA9C0<<48, 0xB5E0<<48 +.size rem_4bit#,128 +.type rem_8bit#,\@object +rem_8bit: + data1 0x00,0x00, 0x01,0xC2, 0x03,0x84, 0x02,0x46, 0x07,0x08, 0x06,0xCA, 0x04,0x8C, 0x05,0x4E + data1 0x0E,0x10, 0x0F,0xD2, 0x0D,0x94, 0x0C,0x56, 0x09,0x18, 0x08,0xDA, 0x0A,0x9C, 0x0B,0x5E + data1 0x1C,0x20, 0x1D,0xE2, 0x1F,0xA4, 0x1E,0x66, 0x1B,0x28, 0x1A,0xEA, 0x18,0xAC, 0x19,0x6E + data1 0x12,0x30, 0x13,0xF2, 0x11,0xB4, 0x10,0x76, 0x15,0x38, 0x14,0xFA, 0x16,0xBC, 0x17,0x7E + data1 0x38,0x40, 0x39,0x82, 0x3B,0xC4, 0x3A,0x06, 0x3F,0x48, 0x3E,0x8A, 0x3C,0xCC, 0x3D,0x0E + data1 0x36,0x50, 0x37,0x92, 0x35,0xD4, 0x34,0x16, 0x31,0x58, 0x30,0x9A, 0x32,0xDC, 0x33,0x1E + data1 0x24,0x60, 0x25,0xA2, 0x27,0xE4, 0x26,0x26, 0x23,0x68, 0x22,0xAA, 0x20,0xEC, 0x21,0x2E + data1 0x2A,0x70, 0x2B,0xB2, 0x29,0xF4, 0x28,0x36, 0x2D,0x78, 0x2C,0xBA, 0x2E,0xFC, 0x2F,0x3E + data1 0x70,0x80, 0x71,0x42, 0x73,0x04, 0x72,0xC6, 0x77,0x88, 0x76,0x4A, 0x74,0x0C, 0x75,0xCE + data1 0x7E,0x90, 0x7F,0x52, 0x7D,0x14, 0x7C,0xD6, 0x79,0x98, 0x78,0x5A, 0x7A,0x1C, 0x7B,0xDE + data1 0x6C,0xA0, 0x6D,0x62, 0x6F,0x24, 0x6E,0xE6, 0x6B,0xA8, 0x6A,0x6A, 0x68,0x2C, 0x69,0xEE + data1 0x62,0xB0, 0x63,0x72, 0x61,0x34, 0x60,0xF6, 0x65,0xB8, 0x64,0x7A, 0x66,0x3C, 0x67,0xFE + data1 0x48,0xC0, 0x49,0x02, 0x4B,0x44, 0x4A,0x86, 0x4F,0xC8, 0x4E,0x0A, 0x4C,0x4C, 0x4D,0x8E + data1 0x46,0xD0, 0x47,0x12, 0x45,0x54, 0x44,0x96, 0x41,0xD8, 0x40,0x1A, 0x42,0x5C, 0x43,0x9E + data1 0x54,0xE0, 0x55,0x22, 0x57,0x64, 0x56,0xA6, 0x53,0xE8, 0x52,0x2A, 0x50,0x6C, 0x51,0xAE + data1 0x5A,0xF0, 0x5B,0x32, 0x59,0x74, 0x58,0xB6, 0x5D,0xF8, 0x5C,0x3A, 0x5E,0x7C, 0x5F,0xBE + data1 0xE1,0x00, 0xE0,0xC2, 0xE2,0x84, 0xE3,0x46, 0xE6,0x08, 0xE7,0xCA, 0xE5,0x8C, 0xE4,0x4E + data1 0xEF,0x10, 0xEE,0xD2, 0xEC,0x94, 0xED,0x56, 0xE8,0x18, 0xE9,0xDA, 0xEB,0x9C, 0xEA,0x5E + data1 0xFD,0x20, 0xFC,0xE2, 0xFE,0xA4, 0xFF,0x66, 0xFA,0x28, 0xFB,0xEA, 0xF9,0xAC, 0xF8,0x6E + data1 0xF3,0x30, 0xF2,0xF2, 0xF0,0xB4, 0xF1,0x76, 0xF4,0x38, 0xF5,0xFA, 0xF7,0xBC, 0xF6,0x7E + data1 0xD9,0x40, 0xD8,0x82, 0xDA,0xC4, 0xDB,0x06, 0xDE,0x48, 0xDF,0x8A, 0xDD,0xCC, 0xDC,0x0E + data1 0xD7,0x50, 0xD6,0x92, 0xD4,0xD4, 0xD5,0x16, 0xD0,0x58, 0xD1,0x9A, 0xD3,0xDC, 0xD2,0x1E + data1 0xC5,0x60, 0xC4,0xA2, 0xC6,0xE4, 0xC7,0x26, 0xC2,0x68, 0xC3,0xAA, 0xC1,0xEC, 0xC0,0x2E + data1 0xCB,0x70, 0xCA,0xB2, 0xC8,0xF4, 0xC9,0x36, 0xCC,0x78, 0xCD,0xBA, 0xCF,0xFC, 0xCE,0x3E + data1 0x91,0x80, 0x90,0x42, 0x92,0x04, 0x93,0xC6, 0x96,0x88, 0x97,0x4A, 0x95,0x0C, 0x94,0xCE + data1 0x9F,0x90, 0x9E,0x52, 0x9C,0x14, 0x9D,0xD6, 0x98,0x98, 0x99,0x5A, 0x9B,0x1C, 0x9A,0xDE + data1 0x8D,0xA0, 0x8C,0x62, 0x8E,0x24, 0x8F,0xE6, 0x8A,0xA8, 0x8B,0x6A, 0x89,0x2C, 0x88,0xEE + data1 0x83,0xB0, 0x82,0x72, 0x80,0x34, 0x81,0xF6, 0x84,0xB8, 0x85,0x7A, 0x87,0x3C, 0x86,0xFE + data1 0xA9,0xC0, 0xA8,0x02, 0xAA,0x44, 0xAB,0x86, 0xAE,0xC8, 0xAF,0x0A, 0xAD,0x4C, 0xAC,0x8E + data1 0xA7,0xD0, 0xA6,0x12, 0xA4,0x54, 0xA5,0x96, 0xA0,0xD8, 0xA1,0x1A, 0xA3,0x5C, 0xA2,0x9E + data1 0xB5,0xE0, 0xB4,0x22, 0xB6,0x64, 0xB7,0xA6, 0xB2,0xE8, 0xB3,0x2A, 0xB1,0x6C, 0xB0,0xAE + data1 0xBB,0xF0, 0xBA,0x32, 0xB8,0x74, 0xB9,0xB6, 0xBC,0xF8, 0xBD,0x3A, 0xBF,0x7C, 0xBE,0xBE +.size rem_8bit#,512 +stringz "GHASH for IA64, CRYPTOGAMS by " +___ + +$code =~ s/mux1(\s+)\S+\@rev/nop.i$1 0x0/gm if ($big_endian); +$code =~ s/\`([^\`]*)\`/eval $1/gem; + +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/modes/asm/ghash-parisc.pl b/libs/openssl/crypto/modes/asm/ghash-parisc.pl new file mode 100644 index 00000000..d5ad96b4 --- /dev/null +++ b/libs/openssl/crypto/modes/asm/ghash-parisc.pl @@ -0,0 +1,731 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# April 2010 +# +# The module implements "4-bit" GCM GHASH function and underlying +# single multiplication operation in GF(2^128). "4-bit" means that it +# uses 256 bytes per-key table [+128 bytes shared table]. On PA-7100LC +# it processes one byte in 19.6 cycles, which is more than twice as +# fast as code generated by gcc 3.2. PA-RISC 2.0 loop is scheduled for +# 8 cycles, but measured performance on PA-8600 system is ~9 cycles per +# processed byte. This is ~2.2x faster than 64-bit code generated by +# vendor compiler (which used to be very hard to beat:-). +# +# Special thanks to polarhome.com for providing HP-UX account. + +$flavour = shift; +$output = shift; +open STDOUT,">$output"; + +if ($flavour =~ /64/) { + $LEVEL ="2.0W"; + $SIZE_T =8; + $FRAME_MARKER =80; + $SAVED_RP =16; + $PUSH ="std"; + $PUSHMA ="std,ma"; + $POP ="ldd"; + $POPMB ="ldd,mb"; + $NREGS =6; +} else { + $LEVEL ="1.0"; #"\n\t.ALLOW\t2.0"; + $SIZE_T =4; + $FRAME_MARKER =48; + $SAVED_RP =20; + $PUSH ="stw"; + $PUSHMA ="stwm"; + $POP ="ldw"; + $POPMB ="ldwm"; + $NREGS =11; +} + +$FRAME=10*$SIZE_T+$FRAME_MARKER;# NREGS saved regs + frame marker + # [+ argument transfer] + +################# volatile registers +$Xi="%r26"; # argument block +$Htbl="%r25"; +$inp="%r24"; +$len="%r23"; +$Hhh=$Htbl; # variables +$Hll="%r22"; +$Zhh="%r21"; +$Zll="%r20"; +$cnt="%r19"; +$rem_4bit="%r28"; +$rem="%r29"; +$mask0xf0="%r31"; + +################# preserved registers +$Thh="%r1"; +$Tll="%r2"; +$nlo="%r3"; +$nhi="%r4"; +$byte="%r5"; +if ($SIZE_T==4) { + $Zhl="%r6"; + $Zlh="%r7"; + $Hhl="%r8"; + $Hlh="%r9"; + $Thl="%r10"; + $Tlh="%r11"; +} +$rem2="%r6"; # used in PA-RISC 2.0 code + +$code.=<<___; + .LEVEL $LEVEL + .SPACE \$TEXT\$ + .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY + + .EXPORT gcm_gmult_4bit,ENTRY,ARGW0=GR,ARGW1=GR + .ALIGN 64 +gcm_gmult_4bit + .PROC + .CALLINFO FRAME=`$FRAME-10*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=$NREGS + .ENTRY + $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue + $PUSHMA %r3,$FRAME(%sp) + $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp) + $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp) + $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp) +___ +$code.=<<___ if ($SIZE_T==4); + $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp) + $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp) + $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp) + $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp) + $PUSH %r11,`-$FRAME+8*$SIZE_T`(%sp) +___ +$code.=<<___; + blr %r0,$rem_4bit + ldi 3,$rem +L\$pic_gmult + andcm $rem_4bit,$rem,$rem_4bit + addl $inp,$len,$len + ldo L\$rem_4bit-L\$pic_gmult($rem_4bit),$rem_4bit + ldi 0xf0,$mask0xf0 +___ +$code.=<<___ if ($SIZE_T==4); + ldi 31,$rem + mtctl $rem,%cr11 + extrd,u,*= $rem,%sar,1,$rem ; executes on PA-RISC 1.0 + b L\$parisc1_gmult + nop +___ + +$code.=<<___; + ldb 15($Xi),$nlo + ldo 8($Htbl),$Hll + + and $mask0xf0,$nlo,$nhi + depd,z $nlo,59,4,$nlo + + ldd $nlo($Hll),$Zll + ldd $nlo($Hhh),$Zhh + + depd,z $Zll,60,4,$rem + shrpd $Zhh,$Zll,4,$Zll + extrd,u $Zhh,59,60,$Zhh + ldb 14($Xi),$nlo + + ldd $nhi($Hll),$Tll + ldd $nhi($Hhh),$Thh + and $mask0xf0,$nlo,$nhi + depd,z $nlo,59,4,$nlo + + xor $Tll,$Zll,$Zll + xor $Thh,$Zhh,$Zhh + ldd $rem($rem_4bit),$rem + b L\$oop_gmult_pa2 + ldi 13,$cnt + + .ALIGN 8 +L\$oop_gmult_pa2 + xor $rem,$Zhh,$Zhh ; moved here to work around gas bug + depd,z $Zll,60,4,$rem + + shrpd $Zhh,$Zll,4,$Zll + extrd,u $Zhh,59,60,$Zhh + ldd $nlo($Hll),$Tll + ldd $nlo($Hhh),$Thh + + xor $Tll,$Zll,$Zll + xor $Thh,$Zhh,$Zhh + ldd $rem($rem_4bit),$rem + + xor $rem,$Zhh,$Zhh + depd,z $Zll,60,4,$rem + ldbx $cnt($Xi),$nlo + + shrpd $Zhh,$Zll,4,$Zll + extrd,u $Zhh,59,60,$Zhh + ldd $nhi($Hll),$Tll + ldd $nhi($Hhh),$Thh + + and $mask0xf0,$nlo,$nhi + depd,z $nlo,59,4,$nlo + ldd $rem($rem_4bit),$rem + + xor $Tll,$Zll,$Zll + addib,uv -1,$cnt,L\$oop_gmult_pa2 + xor $Thh,$Zhh,$Zhh + + xor $rem,$Zhh,$Zhh + depd,z $Zll,60,4,$rem + + shrpd $Zhh,$Zll,4,$Zll + extrd,u $Zhh,59,60,$Zhh + ldd $nlo($Hll),$Tll + ldd $nlo($Hhh),$Thh + + xor $Tll,$Zll,$Zll + xor $Thh,$Zhh,$Zhh + ldd $rem($rem_4bit),$rem + + xor $rem,$Zhh,$Zhh + depd,z $Zll,60,4,$rem + + shrpd $Zhh,$Zll,4,$Zll + extrd,u $Zhh,59,60,$Zhh + ldd $nhi($Hll),$Tll + ldd $nhi($Hhh),$Thh + + xor $Tll,$Zll,$Zll + xor $Thh,$Zhh,$Zhh + ldd $rem($rem_4bit),$rem + + xor $rem,$Zhh,$Zhh + std $Zll,8($Xi) + std $Zhh,0($Xi) +___ + +$code.=<<___ if ($SIZE_T==4); + b L\$done_gmult + nop + +L\$parisc1_gmult + ldb 15($Xi),$nlo + ldo 12($Htbl),$Hll + ldo 8($Htbl),$Hlh + ldo 4($Htbl),$Hhl + + and $mask0xf0,$nlo,$nhi + zdep $nlo,27,4,$nlo + + ldwx $nlo($Hll),$Zll + ldwx $nlo($Hlh),$Zlh + ldwx $nlo($Hhl),$Zhl + ldwx $nlo($Hhh),$Zhh + zdep $Zll,28,4,$rem + ldb 14($Xi),$nlo + ldwx $rem($rem_4bit),$rem + shrpw $Zlh,$Zll,4,$Zll + ldwx $nhi($Hll),$Tll + shrpw $Zhl,$Zlh,4,$Zlh + ldwx $nhi($Hlh),$Tlh + shrpw $Zhh,$Zhl,4,$Zhl + ldwx $nhi($Hhl),$Thl + extru $Zhh,27,28,$Zhh + ldwx $nhi($Hhh),$Thh + xor $rem,$Zhh,$Zhh + and $mask0xf0,$nlo,$nhi + zdep $nlo,27,4,$nlo + + xor $Tll,$Zll,$Zll + ldwx $nlo($Hll),$Tll + xor $Tlh,$Zlh,$Zlh + ldwx $nlo($Hlh),$Tlh + xor $Thl,$Zhl,$Zhl + b L\$oop_gmult_pa1 + ldi 13,$cnt + + .ALIGN 8 +L\$oop_gmult_pa1 + zdep $Zll,28,4,$rem + ldwx $nlo($Hhl),$Thl + xor $Thh,$Zhh,$Zhh + ldwx $rem($rem_4bit),$rem + shrpw $Zlh,$Zll,4,$Zll + ldwx $nlo($Hhh),$Thh + shrpw $Zhl,$Zlh,4,$Zlh + ldbx $cnt($Xi),$nlo + xor $Tll,$Zll,$Zll + ldwx $nhi($Hll),$Tll + shrpw $Zhh,$Zhl,4,$Zhl + xor $Tlh,$Zlh,$Zlh + ldwx $nhi($Hlh),$Tlh + extru $Zhh,27,28,$Zhh + xor $Thl,$Zhl,$Zhl + ldwx $nhi($Hhl),$Thl + xor $rem,$Zhh,$Zhh + zdep $Zll,28,4,$rem + xor $Thh,$Zhh,$Zhh + ldwx $nhi($Hhh),$Thh + shrpw $Zlh,$Zll,4,$Zll + ldwx $rem($rem_4bit),$rem + shrpw $Zhl,$Zlh,4,$Zlh + shrpw $Zhh,$Zhl,4,$Zhl + and $mask0xf0,$nlo,$nhi + extru $Zhh,27,28,$Zhh + zdep $nlo,27,4,$nlo + xor $Tll,$Zll,$Zll + ldwx $nlo($Hll),$Tll + xor $Tlh,$Zlh,$Zlh + ldwx $nlo($Hlh),$Tlh + xor $rem,$Zhh,$Zhh + addib,uv -1,$cnt,L\$oop_gmult_pa1 + xor $Thl,$Zhl,$Zhl + + zdep $Zll,28,4,$rem + ldwx $nlo($Hhl),$Thl + xor $Thh,$Zhh,$Zhh + ldwx $rem($rem_4bit),$rem + shrpw $Zlh,$Zll,4,$Zll + ldwx $nlo($Hhh),$Thh + shrpw $Zhl,$Zlh,4,$Zlh + xor $Tll,$Zll,$Zll + ldwx $nhi($Hll),$Tll + shrpw $Zhh,$Zhl,4,$Zhl + xor $Tlh,$Zlh,$Zlh + ldwx $nhi($Hlh),$Tlh + extru $Zhh,27,28,$Zhh + xor $rem,$Zhh,$Zhh + xor $Thl,$Zhl,$Zhl + ldwx $nhi($Hhl),$Thl + xor $Thh,$Zhh,$Zhh + ldwx $nhi($Hhh),$Thh + zdep $Zll,28,4,$rem + ldwx $rem($rem_4bit),$rem + shrpw $Zlh,$Zll,4,$Zll + shrpw $Zhl,$Zlh,4,$Zlh + shrpw $Zhh,$Zhl,4,$Zhl + extru $Zhh,27,28,$Zhh + xor $Tll,$Zll,$Zll + xor $Tlh,$Zlh,$Zlh + xor $rem,$Zhh,$Zhh + stw $Zll,12($Xi) + xor $Thl,$Zhl,$Zhl + stw $Zlh,8($Xi) + xor $Thh,$Zhh,$Zhh + stw $Zhl,4($Xi) + stw $Zhh,0($Xi) +___ +$code.=<<___; +L\$done_gmult + $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue + $POP `-$FRAME+1*$SIZE_T`(%sp),%r4 + $POP `-$FRAME+2*$SIZE_T`(%sp),%r5 + $POP `-$FRAME+3*$SIZE_T`(%sp),%r6 +___ +$code.=<<___ if ($SIZE_T==4); + $POP `-$FRAME+4*$SIZE_T`(%sp),%r7 + $POP `-$FRAME+5*$SIZE_T`(%sp),%r8 + $POP `-$FRAME+6*$SIZE_T`(%sp),%r9 + $POP `-$FRAME+7*$SIZE_T`(%sp),%r10 + $POP `-$FRAME+8*$SIZE_T`(%sp),%r11 +___ +$code.=<<___; + bv (%r2) + .EXIT + $POPMB -$FRAME(%sp),%r3 + .PROCEND + + .EXPORT gcm_ghash_4bit,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR + .ALIGN 64 +gcm_ghash_4bit + .PROC + .CALLINFO FRAME=`$FRAME-10*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=11 + .ENTRY + $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue + $PUSHMA %r3,$FRAME(%sp) + $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp) + $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp) + $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp) +___ +$code.=<<___ if ($SIZE_T==4); + $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp) + $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp) + $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp) + $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp) + $PUSH %r11,`-$FRAME+8*$SIZE_T`(%sp) +___ +$code.=<<___; + blr %r0,$rem_4bit + ldi 3,$rem +L\$pic_ghash + andcm $rem_4bit,$rem,$rem_4bit + addl $inp,$len,$len + ldo L\$rem_4bit-L\$pic_ghash($rem_4bit),$rem_4bit + ldi 0xf0,$mask0xf0 +___ +$code.=<<___ if ($SIZE_T==4); + ldi 31,$rem + mtctl $rem,%cr11 + extrd,u,*= $rem,%sar,1,$rem ; executes on PA-RISC 1.0 + b L\$parisc1_ghash + nop +___ + +$code.=<<___; + ldb 15($Xi),$nlo + ldo 8($Htbl),$Hll + +L\$outer_ghash_pa2 + ldb 15($inp),$nhi + xor $nhi,$nlo,$nlo + and $mask0xf0,$nlo,$nhi + depd,z $nlo,59,4,$nlo + + ldd $nlo($Hll),$Zll + ldd $nlo($Hhh),$Zhh + + depd,z $Zll,60,4,$rem + shrpd $Zhh,$Zll,4,$Zll + extrd,u $Zhh,59,60,$Zhh + ldb 14($Xi),$nlo + ldb 14($inp),$byte + + ldd $nhi($Hll),$Tll + ldd $nhi($Hhh),$Thh + xor $byte,$nlo,$nlo + and $mask0xf0,$nlo,$nhi + depd,z $nlo,59,4,$nlo + + xor $Tll,$Zll,$Zll + xor $Thh,$Zhh,$Zhh + ldd $rem($rem_4bit),$rem + b L\$oop_ghash_pa2 + ldi 13,$cnt + + .ALIGN 8 +L\$oop_ghash_pa2 + xor $rem,$Zhh,$Zhh ; moved here to work around gas bug + depd,z $Zll,60,4,$rem2 + + shrpd $Zhh,$Zll,4,$Zll + extrd,u $Zhh,59,60,$Zhh + ldd $nlo($Hll),$Tll + ldd $nlo($Hhh),$Thh + + xor $Tll,$Zll,$Zll + xor $Thh,$Zhh,$Zhh + ldbx $cnt($Xi),$nlo + ldbx $cnt($inp),$byte + + depd,z $Zll,60,4,$rem + shrpd $Zhh,$Zll,4,$Zll + ldd $rem2($rem_4bit),$rem2 + + xor $rem2,$Zhh,$Zhh + xor $byte,$nlo,$nlo + ldd $nhi($Hll),$Tll + ldd $nhi($Hhh),$Thh + + and $mask0xf0,$nlo,$nhi + depd,z $nlo,59,4,$nlo + + extrd,u $Zhh,59,60,$Zhh + xor $Tll,$Zll,$Zll + + ldd $rem($rem_4bit),$rem + addib,uv -1,$cnt,L\$oop_ghash_pa2 + xor $Thh,$Zhh,$Zhh + + xor $rem,$Zhh,$Zhh + depd,z $Zll,60,4,$rem2 + + shrpd $Zhh,$Zll,4,$Zll + extrd,u $Zhh,59,60,$Zhh + ldd $nlo($Hll),$Tll + ldd $nlo($Hhh),$Thh + + xor $Tll,$Zll,$Zll + xor $Thh,$Zhh,$Zhh + + depd,z $Zll,60,4,$rem + shrpd $Zhh,$Zll,4,$Zll + ldd $rem2($rem_4bit),$rem2 + + xor $rem2,$Zhh,$Zhh + ldd $nhi($Hll),$Tll + ldd $nhi($Hhh),$Thh + + extrd,u $Zhh,59,60,$Zhh + xor $Tll,$Zll,$Zll + xor $Thh,$Zhh,$Zhh + ldd $rem($rem_4bit),$rem + + xor $rem,$Zhh,$Zhh + std $Zll,8($Xi) + ldo 16($inp),$inp + std $Zhh,0($Xi) + cmpb,*<> $inp,$len,L\$outer_ghash_pa2 + copy $Zll,$nlo +___ + +$code.=<<___ if ($SIZE_T==4); + b L\$done_ghash + nop + +L\$parisc1_ghash + ldb 15($Xi),$nlo + ldo 12($Htbl),$Hll + ldo 8($Htbl),$Hlh + ldo 4($Htbl),$Hhl + +L\$outer_ghash_pa1 + ldb 15($inp),$byte + xor $byte,$nlo,$nlo + and $mask0xf0,$nlo,$nhi + zdep $nlo,27,4,$nlo + + ldwx $nlo($Hll),$Zll + ldwx $nlo($Hlh),$Zlh + ldwx $nlo($Hhl),$Zhl + ldwx $nlo($Hhh),$Zhh + zdep $Zll,28,4,$rem + ldb 14($Xi),$nlo + ldb 14($inp),$byte + ldwx $rem($rem_4bit),$rem + shrpw $Zlh,$Zll,4,$Zll + ldwx $nhi($Hll),$Tll + shrpw $Zhl,$Zlh,4,$Zlh + ldwx $nhi($Hlh),$Tlh + shrpw $Zhh,$Zhl,4,$Zhl + ldwx $nhi($Hhl),$Thl + extru $Zhh,27,28,$Zhh + ldwx $nhi($Hhh),$Thh + xor $byte,$nlo,$nlo + xor $rem,$Zhh,$Zhh + and $mask0xf0,$nlo,$nhi + zdep $nlo,27,4,$nlo + + xor $Tll,$Zll,$Zll + ldwx $nlo($Hll),$Tll + xor $Tlh,$Zlh,$Zlh + ldwx $nlo($Hlh),$Tlh + xor $Thl,$Zhl,$Zhl + b L\$oop_ghash_pa1 + ldi 13,$cnt + + .ALIGN 8 +L\$oop_ghash_pa1 + zdep $Zll,28,4,$rem + ldwx $nlo($Hhl),$Thl + xor $Thh,$Zhh,$Zhh + ldwx $rem($rem_4bit),$rem + shrpw $Zlh,$Zll,4,$Zll + ldwx $nlo($Hhh),$Thh + shrpw $Zhl,$Zlh,4,$Zlh + ldbx $cnt($Xi),$nlo + xor $Tll,$Zll,$Zll + ldwx $nhi($Hll),$Tll + shrpw $Zhh,$Zhl,4,$Zhl + ldbx $cnt($inp),$byte + xor $Tlh,$Zlh,$Zlh + ldwx $nhi($Hlh),$Tlh + extru $Zhh,27,28,$Zhh + xor $Thl,$Zhl,$Zhl + ldwx $nhi($Hhl),$Thl + xor $rem,$Zhh,$Zhh + zdep $Zll,28,4,$rem + xor $Thh,$Zhh,$Zhh + ldwx $nhi($Hhh),$Thh + shrpw $Zlh,$Zll,4,$Zll + ldwx $rem($rem_4bit),$rem + shrpw $Zhl,$Zlh,4,$Zlh + xor $byte,$nlo,$nlo + shrpw $Zhh,$Zhl,4,$Zhl + and $mask0xf0,$nlo,$nhi + extru $Zhh,27,28,$Zhh + zdep $nlo,27,4,$nlo + xor $Tll,$Zll,$Zll + ldwx $nlo($Hll),$Tll + xor $Tlh,$Zlh,$Zlh + ldwx $nlo($Hlh),$Tlh + xor $rem,$Zhh,$Zhh + addib,uv -1,$cnt,L\$oop_ghash_pa1 + xor $Thl,$Zhl,$Zhl + + zdep $Zll,28,4,$rem + ldwx $nlo($Hhl),$Thl + xor $Thh,$Zhh,$Zhh + ldwx $rem($rem_4bit),$rem + shrpw $Zlh,$Zll,4,$Zll + ldwx $nlo($Hhh),$Thh + shrpw $Zhl,$Zlh,4,$Zlh + xor $Tll,$Zll,$Zll + ldwx $nhi($Hll),$Tll + shrpw $Zhh,$Zhl,4,$Zhl + xor $Tlh,$Zlh,$Zlh + ldwx $nhi($Hlh),$Tlh + extru $Zhh,27,28,$Zhh + xor $rem,$Zhh,$Zhh + xor $Thl,$Zhl,$Zhl + ldwx $nhi($Hhl),$Thl + xor $Thh,$Zhh,$Zhh + ldwx $nhi($Hhh),$Thh + zdep $Zll,28,4,$rem + ldwx $rem($rem_4bit),$rem + shrpw $Zlh,$Zll,4,$Zll + shrpw $Zhl,$Zlh,4,$Zlh + shrpw $Zhh,$Zhl,4,$Zhl + extru $Zhh,27,28,$Zhh + xor $Tll,$Zll,$Zll + xor $Tlh,$Zlh,$Zlh + xor $rem,$Zhh,$Zhh + stw $Zll,12($Xi) + xor $Thl,$Zhl,$Zhl + stw $Zlh,8($Xi) + xor $Thh,$Zhh,$Zhh + stw $Zhl,4($Xi) + ldo 16($inp),$inp + stw $Zhh,0($Xi) + comb,<> $inp,$len,L\$outer_ghash_pa1 + copy $Zll,$nlo +___ +$code.=<<___; +L\$done_ghash + $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue + $POP `-$FRAME+1*$SIZE_T`(%sp),%r4 + $POP `-$FRAME+2*$SIZE_T`(%sp),%r5 + $POP `-$FRAME+3*$SIZE_T`(%sp),%r6 +___ +$code.=<<___ if ($SIZE_T==4); + $POP `-$FRAME+4*$SIZE_T`(%sp),%r7 + $POP `-$FRAME+5*$SIZE_T`(%sp),%r8 + $POP `-$FRAME+6*$SIZE_T`(%sp),%r9 + $POP `-$FRAME+7*$SIZE_T`(%sp),%r10 + $POP `-$FRAME+8*$SIZE_T`(%sp),%r11 +___ +$code.=<<___; + bv (%r2) + .EXIT + $POPMB -$FRAME(%sp),%r3 + .PROCEND + + .ALIGN 64 +L\$rem_4bit + .WORD `0x0000<<16`,0,`0x1C20<<16`,0,`0x3840<<16`,0,`0x2460<<16`,0 + .WORD `0x7080<<16`,0,`0x6CA0<<16`,0,`0x48C0<<16`,0,`0x54E0<<16`,0 + .WORD `0xE100<<16`,0,`0xFD20<<16`,0,`0xD940<<16`,0,`0xC560<<16`,0 + .WORD `0x9180<<16`,0,`0x8DA0<<16`,0,`0xA9C0<<16`,0,`0xB5E0<<16`,0 + .STRINGZ "GHASH for PA-RISC, GRYPTOGAMS by " + .ALIGN 64 +___ + +# Explicitly encode PA-RISC 2.0 instructions used in this module, so +# that it can be compiled with .LEVEL 1.0. It should be noted that I +# wouldn't have to do this, if GNU assembler understood .ALLOW 2.0 +# directive... + +my $ldd = sub { + my ($mod,$args) = @_; + my $orig = "ldd$mod\t$args"; + + if ($args =~ /%r([0-9]+)\(%r([0-9]+)\),%r([0-9]+)/) # format 4 + { my $opcode=(0x03<<26)|($2<<21)|($1<<16)|(3<<6)|$3; + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + elsif ($args =~ /(\-?[0-9]+)\(%r([0-9]+)\),%r([0-9]+)/) # format 5 + { my $opcode=(0x03<<26)|($2<<21)|(1<<12)|(3<<6)|$3; + $opcode|=(($1&0xF)<<17)|(($1&0x10)<<12); # encode offset + $opcode|=(1<<5) if ($mod =~ /^,m/); + $opcode|=(1<<13) if ($mod =~ /^,mb/); + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + else { "\t".$orig; } +}; + +my $std = sub { + my ($mod,$args) = @_; + my $orig = "std$mod\t$args"; + + if ($args =~ /%r([0-9]+),(\-?[0-9]+)\(%r([0-9]+)\)/) # format 3 suffices + { my $opcode=(0x1c<<26)|($3<<21)|($1<<16)|(($2&0x1FF8)<<1)|(($2>>13)&1); + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + else { "\t".$orig; } +}; + +my $extrd = sub { + my ($mod,$args) = @_; + my $orig = "extrd$mod\t$args"; + + # I only have ",u" completer, it's implicitly encoded... + if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/) # format 15 + { my $opcode=(0x36<<26)|($1<<21)|($4<<16); + my $len=32-$3; + $opcode |= (($2&0x20)<<6)|(($2&0x1f)<<5); # encode pos + $opcode |= (($len&0x20)<<7)|($len&0x1f); # encode len + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + elsif ($args =~ /%r([0-9]+),%sar,([0-9]+),%r([0-9]+)/) # format 12 + { my $opcode=(0x34<<26)|($1<<21)|($3<<16)|(2<<11)|(1<<9); + my $len=32-$2; + $opcode |= (($len&0x20)<<3)|($len&0x1f); # encode len + $opcode |= (1<<13) if ($mod =~ /,\**=/); + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + else { "\t".$orig; } +}; + +my $shrpd = sub { + my ($mod,$args) = @_; + my $orig = "shrpd$mod\t$args"; + + if ($args =~ /%r([0-9]+),%r([0-9]+),([0-9]+),%r([0-9]+)/) # format 14 + { my $opcode=(0x34<<26)|($2<<21)|($1<<16)|(1<<10)|$4; + my $cpos=63-$3; + $opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5); # encode sa + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + elsif ($args =~ /%r([0-9]+),%r([0-9]+),%sar,%r([0-9]+)/) # format 11 + { sprintf "\t.WORD\t0x%08x\t; %s", + (0x34<<26)|($2<<21)|($1<<16)|(1<<9)|$3,$orig; + } + else { "\t".$orig; } +}; + +my $depd = sub { + my ($mod,$args) = @_; + my $orig = "depd$mod\t$args"; + + # I only have ",z" completer, it's impicitly encoded... + if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/) # format 16 + { my $opcode=(0x3c<<26)|($4<<21)|($1<<16); + my $cpos=63-$2; + my $len=32-$3; + $opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5); # encode pos + $opcode |= (($len&0x20)<<7)|($len&0x1f); # encode len + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + else { "\t".$orig; } +}; + +sub assemble { + my ($mnemonic,$mod,$args)=@_; + my $opcode = eval("\$$mnemonic"); + + ref($opcode) eq 'CODE' ? &$opcode($mod,$args) : "\t$mnemonic$mod\t$args"; +} + +foreach (split("\n",$code)) { + s/\`([^\`]*)\`/eval $1/ge; + if ($SIZE_T==4) { + s/^\s+([a-z]+)([\S]*)\s+([\S]*)/&assemble($1,$2,$3)/e; + s/cmpb,\*/comb,/; + s/,\*/,/; + } + s/\bbv\b/bve/ if ($SIZE_T==8); + print $_,"\n"; +} + +close STDOUT; diff --git a/libs/openssl/crypto/modes/asm/ghash-s390x.pl b/libs/openssl/crypto/modes/asm/ghash-s390x.pl new file mode 100644 index 00000000..6a40d5d8 --- /dev/null +++ b/libs/openssl/crypto/modes/asm/ghash-s390x.pl @@ -0,0 +1,262 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# September 2010. +# +# The module implements "4-bit" GCM GHASH function and underlying +# single multiplication operation in GF(2^128). "4-bit" means that it +# uses 256 bytes per-key table [+128 bytes shared table]. Performance +# was measured to be ~18 cycles per processed byte on z10, which is +# almost 40% better than gcc-generated code. It should be noted that +# 18 cycles is worse result than expected: loop is scheduled for 12 +# and the result should be close to 12. In the lack of instruction- +# level profiling data it's impossible to tell why... + +# November 2010. +# +# Adapt for -m31 build. If kernel supports what's called "highgprs" +# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit +# instructions and achieve "64-bit" performance even in 31-bit legacy +# application context. The feature is not specific to any particular +# processor, as long as it's "z-CPU". Latter implies that the code +# remains z/Architecture specific. On z990 it was measured to perform +# 2.8x better than 32-bit code generated by gcc 4.3. + +# March 2011. +# +# Support for hardware KIMD-GHASH is verified to produce correct +# result and therefore is engaged. On z196 it was measured to process +# 8KB buffer ~7 faster than software implementation. It's not as +# impressive for smaller buffer sizes and for smallest 16-bytes buffer +# it's actually almost 2 times slower. Which is the reason why +# KIMD-GHASH is not used in gcm_gmult_4bit. + +$flavour = shift; + +if ($flavour =~ /3[12]/) { + $SIZE_T=4; + $g=""; +} else { + $SIZE_T=8; + $g="g"; +} + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +$softonly=0; + +$Zhi="%r0"; +$Zlo="%r1"; + +$Xi="%r2"; # argument block +$Htbl="%r3"; +$inp="%r4"; +$len="%r5"; + +$rem0="%r6"; # variables +$rem1="%r7"; +$nlo="%r8"; +$nhi="%r9"; +$xi="%r10"; +$cnt="%r11"; +$tmp="%r12"; +$x78="%r13"; +$rem_4bit="%r14"; + +$sp="%r15"; + +$code.=<<___; +.text + +.globl gcm_gmult_4bit +.align 32 +gcm_gmult_4bit: +___ +$code.=<<___ if(!$softonly && 0); # hardware is slow for single block... + larl %r1,OPENSSL_s390xcap_P + lg %r0,0(%r1) + tmhl %r0,0x4000 # check for message-security-assist + jz .Lsoft_gmult + lghi %r0,0 + la %r1,16($sp) + .long 0xb93e0004 # kimd %r0,%r4 + lg %r1,24($sp) + tmhh %r1,0x4000 # check for function 65 + jz .Lsoft_gmult + stg %r0,16($sp) # arrange 16 bytes of zero input + stg %r0,24($sp) + lghi %r0,65 # function 65 + la %r1,0($Xi) # H lies right after Xi in gcm128_context + la $inp,16($sp) + lghi $len,16 + .long 0xb93e0004 # kimd %r0,$inp + brc 1,.-4 # pay attention to "partial completion" + br %r14 +.align 32 +.Lsoft_gmult: +___ +$code.=<<___; + stm${g} %r6,%r14,6*$SIZE_T($sp) + + aghi $Xi,-1 + lghi $len,1 + lghi $x78,`0xf<<3` + larl $rem_4bit,rem_4bit + + lg $Zlo,8+1($Xi) # Xi + j .Lgmult_shortcut +.type gcm_gmult_4bit,\@function +.size gcm_gmult_4bit,(.-gcm_gmult_4bit) + +.globl gcm_ghash_4bit +.align 32 +gcm_ghash_4bit: +___ +$code.=<<___ if(!$softonly); + larl %r1,OPENSSL_s390xcap_P + lg %r0,0(%r1) + tmhl %r0,0x4000 # check for message-security-assist + jz .Lsoft_ghash + lghi %r0,0 + la %r1,16($sp) + .long 0xb93e0004 # kimd %r0,%r4 + lg %r1,24($sp) + tmhh %r1,0x4000 # check for function 65 + jz .Lsoft_ghash + lghi %r0,65 # function 65 + la %r1,0($Xi) # H lies right after Xi in gcm128_context + .long 0xb93e0004 # kimd %r0,$inp + brc 1,.-4 # pay attention to "partial completion" + br %r14 +.align 32 +.Lsoft_ghash: +___ +$code.=<<___ if ($flavour =~ /3[12]/); + llgfr $len,$len +___ +$code.=<<___; + stm${g} %r6,%r14,6*$SIZE_T($sp) + + aghi $Xi,-1 + srlg $len,$len,4 + lghi $x78,`0xf<<3` + larl $rem_4bit,rem_4bit + + lg $Zlo,8+1($Xi) # Xi + lg $Zhi,0+1($Xi) + lghi $tmp,0 +.Louter: + xg $Zhi,0($inp) # Xi ^= inp + xg $Zlo,8($inp) + xgr $Zhi,$tmp + stg $Zlo,8+1($Xi) + stg $Zhi,0+1($Xi) + +.Lgmult_shortcut: + lghi $tmp,0xf0 + sllg $nlo,$Zlo,4 + srlg $xi,$Zlo,8 # extract second byte + ngr $nlo,$tmp + lgr $nhi,$Zlo + lghi $cnt,14 + ngr $nhi,$tmp + + lg $Zlo,8($nlo,$Htbl) + lg $Zhi,0($nlo,$Htbl) + + sllg $nlo,$xi,4 + sllg $rem0,$Zlo,3 + ngr $nlo,$tmp + ngr $rem0,$x78 + ngr $xi,$tmp + + sllg $tmp,$Zhi,60 + srlg $Zlo,$Zlo,4 + srlg $Zhi,$Zhi,4 + xg $Zlo,8($nhi,$Htbl) + xg $Zhi,0($nhi,$Htbl) + lgr $nhi,$xi + sllg $rem1,$Zlo,3 + xgr $Zlo,$tmp + ngr $rem1,$x78 + j .Lghash_inner +.align 16 +.Lghash_inner: + srlg $Zlo,$Zlo,4 + sllg $tmp,$Zhi,60 + xg $Zlo,8($nlo,$Htbl) + srlg $Zhi,$Zhi,4 + llgc $xi,0($cnt,$Xi) + xg $Zhi,0($nlo,$Htbl) + sllg $nlo,$xi,4 + xg $Zhi,0($rem0,$rem_4bit) + nill $nlo,0xf0 + sllg $rem0,$Zlo,3 + xgr $Zlo,$tmp + ngr $rem0,$x78 + nill $xi,0xf0 + + sllg $tmp,$Zhi,60 + srlg $Zlo,$Zlo,4 + srlg $Zhi,$Zhi,4 + xg $Zlo,8($nhi,$Htbl) + xg $Zhi,0($nhi,$Htbl) + lgr $nhi,$xi + xg $Zhi,0($rem1,$rem_4bit) + sllg $rem1,$Zlo,3 + xgr $Zlo,$tmp + ngr $rem1,$x78 + brct $cnt,.Lghash_inner + + sllg $tmp,$Zhi,60 + srlg $Zlo,$Zlo,4 + srlg $Zhi,$Zhi,4 + xg $Zlo,8($nlo,$Htbl) + xg $Zhi,0($nlo,$Htbl) + sllg $xi,$Zlo,3 + xg $Zhi,0($rem0,$rem_4bit) + xgr $Zlo,$tmp + ngr $xi,$x78 + + sllg $tmp,$Zhi,60 + srlg $Zlo,$Zlo,4 + srlg $Zhi,$Zhi,4 + xg $Zlo,8($nhi,$Htbl) + xg $Zhi,0($nhi,$Htbl) + xgr $Zlo,$tmp + xg $Zhi,0($rem1,$rem_4bit) + + lg $tmp,0($xi,$rem_4bit) + la $inp,16($inp) + sllg $tmp,$tmp,4 # correct last rem_4bit[rem] + brctg $len,.Louter + + xgr $Zhi,$tmp + stg $Zlo,8+1($Xi) + stg $Zhi,0+1($Xi) + lm${g} %r6,%r14,6*$SIZE_T($sp) + br %r14 +.type gcm_ghash_4bit,\@function +.size gcm_ghash_4bit,(.-gcm_ghash_4bit) + +.align 64 +rem_4bit: + .long `0x0000<<12`,0,`0x1C20<<12`,0,`0x3840<<12`,0,`0x2460<<12`,0 + .long `0x7080<<12`,0,`0x6CA0<<12`,0,`0x48C0<<12`,0,`0x54E0<<12`,0 + .long `0xE100<<12`,0,`0xFD20<<12`,0,`0xD940<<12`,0,`0xC560<<12`,0 + .long `0x9180<<12`,0,`0x8DA0<<12`,0,`0xA9C0<<12`,0,`0xB5E0<<12`,0 +.type rem_4bit,\@object +.size rem_4bit,(.-rem_4bit) +.string "GHASH for s390x, CRYPTOGAMS by " +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/modes/asm/ghash-sparcv9.pl b/libs/openssl/crypto/modes/asm/ghash-sparcv9.pl new file mode 100644 index 00000000..70e7b044 --- /dev/null +++ b/libs/openssl/crypto/modes/asm/ghash-sparcv9.pl @@ -0,0 +1,330 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# March 2010 +# +# The module implements "4-bit" GCM GHASH function and underlying +# single multiplication operation in GF(2^128). "4-bit" means that it +# uses 256 bytes per-key table [+128 bytes shared table]. Performance +# results are for streamed GHASH subroutine on UltraSPARC pre-Tx CPU +# and are expressed in cycles per processed byte, less is better: +# +# gcc 3.3.x cc 5.2 this assembler +# +# 32-bit build 81.4 43.3 12.6 (+546%/+244%) +# 64-bit build 20.2 21.2 12.6 (+60%/+68%) +# +# Here is data collected on UltraSPARC T1 system running Linux: +# +# gcc 4.4.1 this assembler +# +# 32-bit build 566 50 (+1000%) +# 64-bit build 56 50 (+12%) +# +# I don't quite understand why difference between 32-bit and 64-bit +# compiler-generated code is so big. Compilers *were* instructed to +# generate code for UltraSPARC and should have used 64-bit registers +# for Z vector (see C code) even in 32-bit build... Oh well, it only +# means more impressive improvement coefficients for this assembler +# module;-) Loops are aggressively modulo-scheduled in respect to +# references to input data and Z.hi updates to achieve 12 cycles +# timing. To anchor to something else, sha1-sparcv9.pl spends 11.6 +# cycles to process one byte on UltraSPARC pre-Tx CPU and ~24 on T1. + +$bits=32; +for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); } +if ($bits==64) { $bias=2047; $frame=192; } +else { $bias=0; $frame=112; } + +$output=shift; +open STDOUT,">$output"; + +$Zhi="%o0"; # 64-bit values +$Zlo="%o1"; +$Thi="%o2"; +$Tlo="%o3"; +$rem="%o4"; +$tmp="%o5"; + +$nhi="%l0"; # small values and pointers +$nlo="%l1"; +$xi0="%l2"; +$xi1="%l3"; +$rem_4bit="%l4"; +$remi="%l5"; +$Htblo="%l6"; +$cnt="%l7"; + +$Xi="%i0"; # input argument block +$Htbl="%i1"; +$inp="%i2"; +$len="%i3"; + +$code.=<<___; +.section ".text",#alloc,#execinstr + +.align 64 +rem_4bit: + .long `0x0000<<16`,0,`0x1C20<<16`,0,`0x3840<<16`,0,`0x2460<<16`,0 + .long `0x7080<<16`,0,`0x6CA0<<16`,0,`0x48C0<<16`,0,`0x54E0<<16`,0 + .long `0xE100<<16`,0,`0xFD20<<16`,0,`0xD940<<16`,0,`0xC560<<16`,0 + .long `0x9180<<16`,0,`0x8DA0<<16`,0,`0xA9C0<<16`,0,`0xB5E0<<16`,0 +.type rem_4bit,#object +.size rem_4bit,(.-rem_4bit) + +.globl gcm_ghash_4bit +.align 32 +gcm_ghash_4bit: + save %sp,-$frame,%sp + ldub [$inp+15],$nlo + ldub [$Xi+15],$xi0 + ldub [$Xi+14],$xi1 + add $len,$inp,$len + add $Htbl,8,$Htblo + +1: call .+8 + add %o7,rem_4bit-1b,$rem_4bit + +.Louter: + xor $xi0,$nlo,$nlo + and $nlo,0xf0,$nhi + and $nlo,0x0f,$nlo + sll $nlo,4,$nlo + ldx [$Htblo+$nlo],$Zlo + ldx [$Htbl+$nlo],$Zhi + + ldub [$inp+14],$nlo + + ldx [$Htblo+$nhi],$Tlo + and $Zlo,0xf,$remi + ldx [$Htbl+$nhi],$Thi + sll $remi,3,$remi + ldx [$rem_4bit+$remi],$rem + srlx $Zlo,4,$Zlo + mov 13,$cnt + sllx $Zhi,60,$tmp + xor $Tlo,$Zlo,$Zlo + srlx $Zhi,4,$Zhi + xor $Zlo,$tmp,$Zlo + + xor $xi1,$nlo,$nlo + and $Zlo,0xf,$remi + and $nlo,0xf0,$nhi + and $nlo,0x0f,$nlo + ba .Lghash_inner + sll $nlo,4,$nlo +.align 32 +.Lghash_inner: + ldx [$Htblo+$nlo],$Tlo + sll $remi,3,$remi + xor $Thi,$Zhi,$Zhi + ldx [$Htbl+$nlo],$Thi + srlx $Zlo,4,$Zlo + xor $rem,$Zhi,$Zhi + ldx [$rem_4bit+$remi],$rem + sllx $Zhi,60,$tmp + xor $Tlo,$Zlo,$Zlo + ldub [$inp+$cnt],$nlo + srlx $Zhi,4,$Zhi + xor $Zlo,$tmp,$Zlo + ldub [$Xi+$cnt],$xi1 + xor $Thi,$Zhi,$Zhi + and $Zlo,0xf,$remi + + ldx [$Htblo+$nhi],$Tlo + sll $remi,3,$remi + xor $rem,$Zhi,$Zhi + ldx [$Htbl+$nhi],$Thi + srlx $Zlo,4,$Zlo + ldx [$rem_4bit+$remi],$rem + sllx $Zhi,60,$tmp + xor $xi1,$nlo,$nlo + srlx $Zhi,4,$Zhi + and $nlo,0xf0,$nhi + addcc $cnt,-1,$cnt + xor $Zlo,$tmp,$Zlo + and $nlo,0x0f,$nlo + xor $Tlo,$Zlo,$Zlo + sll $nlo,4,$nlo + blu .Lghash_inner + and $Zlo,0xf,$remi + + ldx [$Htblo+$nlo],$Tlo + sll $remi,3,$remi + xor $Thi,$Zhi,$Zhi + ldx [$Htbl+$nlo],$Thi + srlx $Zlo,4,$Zlo + xor $rem,$Zhi,$Zhi + ldx [$rem_4bit+$remi],$rem + sllx $Zhi,60,$tmp + xor $Tlo,$Zlo,$Zlo + srlx $Zhi,4,$Zhi + xor $Zlo,$tmp,$Zlo + xor $Thi,$Zhi,$Zhi + + add $inp,16,$inp + cmp $inp,$len + be,pn `$bits==64?"%xcc":"%icc"`,.Ldone + and $Zlo,0xf,$remi + + ldx [$Htblo+$nhi],$Tlo + sll $remi,3,$remi + xor $rem,$Zhi,$Zhi + ldx [$Htbl+$nhi],$Thi + srlx $Zlo,4,$Zlo + ldx [$rem_4bit+$remi],$rem + sllx $Zhi,60,$tmp + xor $Tlo,$Zlo,$Zlo + ldub [$inp+15],$nlo + srlx $Zhi,4,$Zhi + xor $Zlo,$tmp,$Zlo + xor $Thi,$Zhi,$Zhi + stx $Zlo,[$Xi+8] + xor $rem,$Zhi,$Zhi + stx $Zhi,[$Xi] + srl $Zlo,8,$xi1 + and $Zlo,0xff,$xi0 + ba .Louter + and $xi1,0xff,$xi1 +.align 32 +.Ldone: + ldx [$Htblo+$nhi],$Tlo + sll $remi,3,$remi + xor $rem,$Zhi,$Zhi + ldx [$Htbl+$nhi],$Thi + srlx $Zlo,4,$Zlo + ldx [$rem_4bit+$remi],$rem + sllx $Zhi,60,$tmp + xor $Tlo,$Zlo,$Zlo + srlx $Zhi,4,$Zhi + xor $Zlo,$tmp,$Zlo + xor $Thi,$Zhi,$Zhi + stx $Zlo,[$Xi+8] + xor $rem,$Zhi,$Zhi + stx $Zhi,[$Xi] + + ret + restore +.type gcm_ghash_4bit,#function +.size gcm_ghash_4bit,(.-gcm_ghash_4bit) +___ + +undef $inp; +undef $len; + +$code.=<<___; +.globl gcm_gmult_4bit +.align 32 +gcm_gmult_4bit: + save %sp,-$frame,%sp + ldub [$Xi+15],$nlo + add $Htbl,8,$Htblo + +1: call .+8 + add %o7,rem_4bit-1b,$rem_4bit + + and $nlo,0xf0,$nhi + and $nlo,0x0f,$nlo + sll $nlo,4,$nlo + ldx [$Htblo+$nlo],$Zlo + ldx [$Htbl+$nlo],$Zhi + + ldub [$Xi+14],$nlo + + ldx [$Htblo+$nhi],$Tlo + and $Zlo,0xf,$remi + ldx [$Htbl+$nhi],$Thi + sll $remi,3,$remi + ldx [$rem_4bit+$remi],$rem + srlx $Zlo,4,$Zlo + mov 13,$cnt + sllx $Zhi,60,$tmp + xor $Tlo,$Zlo,$Zlo + srlx $Zhi,4,$Zhi + xor $Zlo,$tmp,$Zlo + + and $Zlo,0xf,$remi + and $nlo,0xf0,$nhi + and $nlo,0x0f,$nlo + ba .Lgmult_inner + sll $nlo,4,$nlo +.align 32 +.Lgmult_inner: + ldx [$Htblo+$nlo],$Tlo + sll $remi,3,$remi + xor $Thi,$Zhi,$Zhi + ldx [$Htbl+$nlo],$Thi + srlx $Zlo,4,$Zlo + xor $rem,$Zhi,$Zhi + ldx [$rem_4bit+$remi],$rem + sllx $Zhi,60,$tmp + xor $Tlo,$Zlo,$Zlo + ldub [$Xi+$cnt],$nlo + srlx $Zhi,4,$Zhi + xor $Zlo,$tmp,$Zlo + xor $Thi,$Zhi,$Zhi + and $Zlo,0xf,$remi + + ldx [$Htblo+$nhi],$Tlo + sll $remi,3,$remi + xor $rem,$Zhi,$Zhi + ldx [$Htbl+$nhi],$Thi + srlx $Zlo,4,$Zlo + ldx [$rem_4bit+$remi],$rem + sllx $Zhi,60,$tmp + srlx $Zhi,4,$Zhi + and $nlo,0xf0,$nhi + addcc $cnt,-1,$cnt + xor $Zlo,$tmp,$Zlo + and $nlo,0x0f,$nlo + xor $Tlo,$Zlo,$Zlo + sll $nlo,4,$nlo + blu .Lgmult_inner + and $Zlo,0xf,$remi + + ldx [$Htblo+$nlo],$Tlo + sll $remi,3,$remi + xor $Thi,$Zhi,$Zhi + ldx [$Htbl+$nlo],$Thi + srlx $Zlo,4,$Zlo + xor $rem,$Zhi,$Zhi + ldx [$rem_4bit+$remi],$rem + sllx $Zhi,60,$tmp + xor $Tlo,$Zlo,$Zlo + srlx $Zhi,4,$Zhi + xor $Zlo,$tmp,$Zlo + xor $Thi,$Zhi,$Zhi + and $Zlo,0xf,$remi + + ldx [$Htblo+$nhi],$Tlo + sll $remi,3,$remi + xor $rem,$Zhi,$Zhi + ldx [$Htbl+$nhi],$Thi + srlx $Zlo,4,$Zlo + ldx [$rem_4bit+$remi],$rem + sllx $Zhi,60,$tmp + xor $Tlo,$Zlo,$Zlo + srlx $Zhi,4,$Zhi + xor $Zlo,$tmp,$Zlo + xor $Thi,$Zhi,$Zhi + stx $Zlo,[$Xi+8] + xor $rem,$Zhi,$Zhi + stx $Zhi,[$Xi] + + ret + restore +.type gcm_gmult_4bit,#function +.size gcm_gmult_4bit,(.-gcm_gmult_4bit) +.asciz "GHASH for SPARCv9, CRYPTOGAMS by " +.align 4 +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/modes/asm/ghash-x86.pl b/libs/openssl/crypto/modes/asm/ghash-x86.pl new file mode 100644 index 00000000..2426cd0c --- /dev/null +++ b/libs/openssl/crypto/modes/asm/ghash-x86.pl @@ -0,0 +1,1342 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# March, May, June 2010 +# +# The module implements "4-bit" GCM GHASH function and underlying +# single multiplication operation in GF(2^128). "4-bit" means that it +# uses 256 bytes per-key table [+64/128 bytes fixed table]. It has two +# code paths: vanilla x86 and vanilla MMX. Former will be executed on +# 486 and Pentium, latter on all others. MMX GHASH features so called +# "528B" variant of "4-bit" method utilizing additional 256+16 bytes +# of per-key storage [+512 bytes shared table]. Performance results +# are for streamed GHASH subroutine and are expressed in cycles per +# processed byte, less is better: +# +# gcc 2.95.3(*) MMX assembler x86 assembler +# +# Pentium 105/111(**) - 50 +# PIII 68 /75 12.2 24 +# P4 125/125 17.8 84(***) +# Opteron 66 /70 10.1 30 +# Core2 54 /67 8.4 18 +# +# (*) gcc 3.4.x was observed to generate few percent slower code, +# which is one of reasons why 2.95.3 results were chosen, +# another reason is lack of 3.4.x results for older CPUs; +# comparison with MMX results is not completely fair, because C +# results are for vanilla "256B" implementation, while +# assembler results are for "528B";-) +# (**) second number is result for code compiled with -fPIC flag, +# which is actually more relevant, because assembler code is +# position-independent; +# (***) see comment in non-MMX routine for further details; +# +# To summarize, it's >2-5 times faster than gcc-generated code. To +# anchor it to something else SHA1 assembler processes one byte in +# 11-13 cycles on contemporary x86 cores. As for choice of MMX in +# particular, see comment at the end of the file... + +# May 2010 +# +# Add PCLMULQDQ version performing at 2.10 cycles per processed byte. +# The question is how close is it to theoretical limit? The pclmulqdq +# instruction latency appears to be 14 cycles and there can't be more +# than 2 of them executing at any given time. This means that single +# Karatsuba multiplication would take 28 cycles *plus* few cycles for +# pre- and post-processing. Then multiplication has to be followed by +# modulo-reduction. Given that aggregated reduction method [see +# "Carry-less Multiplication and Its Usage for Computing the GCM Mode" +# white paper by Intel] allows you to perform reduction only once in +# a while we can assume that asymptotic performance can be estimated +# as (28+Tmod/Naggr)/16, where Tmod is time to perform reduction +# and Naggr is the aggregation factor. +# +# Before we proceed to this implementation let's have closer look at +# the best-performing code suggested by Intel in their white paper. +# By tracing inter-register dependencies Tmod is estimated as ~19 +# cycles and Naggr chosen by Intel is 4, resulting in 2.05 cycles per +# processed byte. As implied, this is quite optimistic estimate, +# because it does not account for Karatsuba pre- and post-processing, +# which for a single multiplication is ~5 cycles. Unfortunately Intel +# does not provide performance data for GHASH alone. But benchmarking +# AES_GCM_encrypt ripped out of Fig. 15 of the white paper with aadt +# alone resulted in 2.46 cycles per byte of out 16KB buffer. Note that +# the result accounts even for pre-computing of degrees of the hash +# key H, but its portion is negligible at 16KB buffer size. +# +# Moving on to the implementation in question. Tmod is estimated as +# ~13 cycles and Naggr is 2, giving asymptotic performance of ... +# 2.16. How is it possible that measured performance is better than +# optimistic theoretical estimate? There is one thing Intel failed +# to recognize. By serializing GHASH with CTR in same subroutine +# former's performance is really limited to above (Tmul + Tmod/Naggr) +# equation. But if GHASH procedure is detached, the modulo-reduction +# can be interleaved with Naggr-1 multiplications at instruction level +# and under ideal conditions even disappear from the equation. So that +# optimistic theoretical estimate for this implementation is ... +# 28/16=1.75, and not 2.16. Well, it's probably way too optimistic, +# at least for such small Naggr. I'd argue that (28+Tproc/Naggr), +# where Tproc is time required for Karatsuba pre- and post-processing, +# is more realistic estimate. In this case it gives ... 1.91 cycles. +# Or in other words, depending on how well we can interleave reduction +# and one of the two multiplications the performance should be betwen +# 1.91 and 2.16. As already mentioned, this implementation processes +# one byte out of 8KB buffer in 2.10 cycles, while x86_64 counterpart +# - in 2.02. x86_64 performance is better, because larger register +# bank allows to interleave reduction and multiplication better. +# +# Does it make sense to increase Naggr? To start with it's virtually +# impossible in 32-bit mode, because of limited register bank +# capacity. Otherwise improvement has to be weighed agiainst slower +# setup, as well as code size and complexity increase. As even +# optimistic estimate doesn't promise 30% performance improvement, +# there are currently no plans to increase Naggr. +# +# Special thanks to David Woodhouse for +# providing access to a Westmere-based system on behalf of Intel +# Open Source Technology Centre. + +# January 2010 +# +# Tweaked to optimize transitions between integer and FP operations +# on same XMM register, PCLMULQDQ subroutine was measured to process +# one byte in 2.07 cycles on Sandy Bridge, and in 2.12 - on Westmere. +# The minor regression on Westmere is outweighed by ~15% improvement +# on Sandy Bridge. Strangely enough attempt to modify 64-bit code in +# similar manner resulted in almost 20% degradation on Sandy Bridge, +# where original 64-bit code processes one byte in 1.95 cycles. + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"ghash-x86.pl",$x86only = $ARGV[$#ARGV] eq "386"); + +$sse2=0; +for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } + +($Zhh,$Zhl,$Zlh,$Zll) = ("ebp","edx","ecx","ebx"); +$inp = "edi"; +$Htbl = "esi"; + +$unroll = 0; # Affects x86 loop. Folded loop performs ~7% worse + # than unrolled, which has to be weighted against + # 2.5x x86-specific code size reduction. + +sub x86_loop { + my $off = shift; + my $rem = "eax"; + + &mov ($Zhh,&DWP(4,$Htbl,$Zll)); + &mov ($Zhl,&DWP(0,$Htbl,$Zll)); + &mov ($Zlh,&DWP(12,$Htbl,$Zll)); + &mov ($Zll,&DWP(8,$Htbl,$Zll)); + &xor ($rem,$rem); # avoid partial register stalls on PIII + + # shrd practically kills P4, 2.5x deterioration, but P4 has + # MMX code-path to execute. shrd runs tad faster [than twice + # the shifts, move's and or's] on pre-MMX Pentium (as well as + # PIII and Core2), *but* minimizes code size, spares register + # and thus allows to fold the loop... + if (!$unroll) { + my $cnt = $inp; + &mov ($cnt,15); + &jmp (&label("x86_loop")); + &set_label("x86_loop",16); + for($i=1;$i<=2;$i++) { + &mov (&LB($rem),&LB($Zll)); + &shrd ($Zll,$Zlh,4); + &and (&LB($rem),0xf); + &shrd ($Zlh,$Zhl,4); + &shrd ($Zhl,$Zhh,4); + &shr ($Zhh,4); + &xor ($Zhh,&DWP($off+16,"esp",$rem,4)); + + &mov (&LB($rem),&BP($off,"esp",$cnt)); + if ($i&1) { + &and (&LB($rem),0xf0); + } else { + &shl (&LB($rem),4); + } + + &xor ($Zll,&DWP(8,$Htbl,$rem)); + &xor ($Zlh,&DWP(12,$Htbl,$rem)); + &xor ($Zhl,&DWP(0,$Htbl,$rem)); + &xor ($Zhh,&DWP(4,$Htbl,$rem)); + + if ($i&1) { + &dec ($cnt); + &js (&label("x86_break")); + } else { + &jmp (&label("x86_loop")); + } + } + &set_label("x86_break",16); + } else { + for($i=1;$i<32;$i++) { + &comment($i); + &mov (&LB($rem),&LB($Zll)); + &shrd ($Zll,$Zlh,4); + &and (&LB($rem),0xf); + &shrd ($Zlh,$Zhl,4); + &shrd ($Zhl,$Zhh,4); + &shr ($Zhh,4); + &xor ($Zhh,&DWP($off+16,"esp",$rem,4)); + + if ($i&1) { + &mov (&LB($rem),&BP($off+15-($i>>1),"esp")); + &and (&LB($rem),0xf0); + } else { + &mov (&LB($rem),&BP($off+15-($i>>1),"esp")); + &shl (&LB($rem),4); + } + + &xor ($Zll,&DWP(8,$Htbl,$rem)); + &xor ($Zlh,&DWP(12,$Htbl,$rem)); + &xor ($Zhl,&DWP(0,$Htbl,$rem)); + &xor ($Zhh,&DWP(4,$Htbl,$rem)); + } + } + &bswap ($Zll); + &bswap ($Zlh); + &bswap ($Zhl); + if (!$x86only) { + &bswap ($Zhh); + } else { + &mov ("eax",$Zhh); + &bswap ("eax"); + &mov ($Zhh,"eax"); + } +} + +if ($unroll) { + &function_begin_B("_x86_gmult_4bit_inner"); + &x86_loop(4); + &ret (); + &function_end_B("_x86_gmult_4bit_inner"); +} + +sub deposit_rem_4bit { + my $bias = shift; + + &mov (&DWP($bias+0, "esp"),0x0000<<16); + &mov (&DWP($bias+4, "esp"),0x1C20<<16); + &mov (&DWP($bias+8, "esp"),0x3840<<16); + &mov (&DWP($bias+12,"esp"),0x2460<<16); + &mov (&DWP($bias+16,"esp"),0x7080<<16); + &mov (&DWP($bias+20,"esp"),0x6CA0<<16); + &mov (&DWP($bias+24,"esp"),0x48C0<<16); + &mov (&DWP($bias+28,"esp"),0x54E0<<16); + &mov (&DWP($bias+32,"esp"),0xE100<<16); + &mov (&DWP($bias+36,"esp"),0xFD20<<16); + &mov (&DWP($bias+40,"esp"),0xD940<<16); + &mov (&DWP($bias+44,"esp"),0xC560<<16); + &mov (&DWP($bias+48,"esp"),0x9180<<16); + &mov (&DWP($bias+52,"esp"),0x8DA0<<16); + &mov (&DWP($bias+56,"esp"),0xA9C0<<16); + &mov (&DWP($bias+60,"esp"),0xB5E0<<16); +} + +$suffix = $x86only ? "" : "_x86"; + +&function_begin("gcm_gmult_4bit".$suffix); + &stack_push(16+4+1); # +1 for stack alignment + &mov ($inp,&wparam(0)); # load Xi + &mov ($Htbl,&wparam(1)); # load Htable + + &mov ($Zhh,&DWP(0,$inp)); # load Xi[16] + &mov ($Zhl,&DWP(4,$inp)); + &mov ($Zlh,&DWP(8,$inp)); + &mov ($Zll,&DWP(12,$inp)); + + &deposit_rem_4bit(16); + + &mov (&DWP(0,"esp"),$Zhh); # copy Xi[16] on stack + &mov (&DWP(4,"esp"),$Zhl); + &mov (&DWP(8,"esp"),$Zlh); + &mov (&DWP(12,"esp"),$Zll); + &shr ($Zll,20); + &and ($Zll,0xf0); + + if ($unroll) { + &call ("_x86_gmult_4bit_inner"); + } else { + &x86_loop(0); + &mov ($inp,&wparam(0)); + } + + &mov (&DWP(12,$inp),$Zll); + &mov (&DWP(8,$inp),$Zlh); + &mov (&DWP(4,$inp),$Zhl); + &mov (&DWP(0,$inp),$Zhh); + &stack_pop(16+4+1); +&function_end("gcm_gmult_4bit".$suffix); + +&function_begin("gcm_ghash_4bit".$suffix); + &stack_push(16+4+1); # +1 for 64-bit alignment + &mov ($Zll,&wparam(0)); # load Xi + &mov ($Htbl,&wparam(1)); # load Htable + &mov ($inp,&wparam(2)); # load in + &mov ("ecx",&wparam(3)); # load len + &add ("ecx",$inp); + &mov (&wparam(3),"ecx"); + + &mov ($Zhh,&DWP(0,$Zll)); # load Xi[16] + &mov ($Zhl,&DWP(4,$Zll)); + &mov ($Zlh,&DWP(8,$Zll)); + &mov ($Zll,&DWP(12,$Zll)); + + &deposit_rem_4bit(16); + + &set_label("x86_outer_loop",16); + &xor ($Zll,&DWP(12,$inp)); # xor with input + &xor ($Zlh,&DWP(8,$inp)); + &xor ($Zhl,&DWP(4,$inp)); + &xor ($Zhh,&DWP(0,$inp)); + &mov (&DWP(12,"esp"),$Zll); # dump it on stack + &mov (&DWP(8,"esp"),$Zlh); + &mov (&DWP(4,"esp"),$Zhl); + &mov (&DWP(0,"esp"),$Zhh); + + &shr ($Zll,20); + &and ($Zll,0xf0); + + if ($unroll) { + &call ("_x86_gmult_4bit_inner"); + } else { + &x86_loop(0); + &mov ($inp,&wparam(2)); + } + &lea ($inp,&DWP(16,$inp)); + &cmp ($inp,&wparam(3)); + &mov (&wparam(2),$inp) if (!$unroll); + &jb (&label("x86_outer_loop")); + + &mov ($inp,&wparam(0)); # load Xi + &mov (&DWP(12,$inp),$Zll); + &mov (&DWP(8,$inp),$Zlh); + &mov (&DWP(4,$inp),$Zhl); + &mov (&DWP(0,$inp),$Zhh); + &stack_pop(16+4+1); +&function_end("gcm_ghash_4bit".$suffix); + +if (!$x86only) {{{ + +&static_label("rem_4bit"); + +if (!$sse2) {{ # pure-MMX "May" version... + +$S=12; # shift factor for rem_4bit + +&function_begin_B("_mmx_gmult_4bit_inner"); +# MMX version performs 3.5 times better on P4 (see comment in non-MMX +# routine for further details), 100% better on Opteron, ~70% better +# on Core2 and PIII... In other words effort is considered to be well +# spent... Since initial release the loop was unrolled in order to +# "liberate" register previously used as loop counter. Instead it's +# used to optimize critical path in 'Z.hi ^= rem_4bit[Z.lo&0xf]'. +# The path involves move of Z.lo from MMX to integer register, +# effective address calculation and finally merge of value to Z.hi. +# Reference to rem_4bit is scheduled so late that I had to >>4 +# rem_4bit elements. This resulted in 20-45% procent improvement +# on contemporary µ-archs. +{ + my $cnt; + my $rem_4bit = "eax"; + my @rem = ($Zhh,$Zll); + my $nhi = $Zhl; + my $nlo = $Zlh; + + my ($Zlo,$Zhi) = ("mm0","mm1"); + my $tmp = "mm2"; + + &xor ($nlo,$nlo); # avoid partial register stalls on PIII + &mov ($nhi,$Zll); + &mov (&LB($nlo),&LB($nhi)); + &shl (&LB($nlo),4); + &and ($nhi,0xf0); + &movq ($Zlo,&QWP(8,$Htbl,$nlo)); + &movq ($Zhi,&QWP(0,$Htbl,$nlo)); + &movd ($rem[0],$Zlo); + + for ($cnt=28;$cnt>=-2;$cnt--) { + my $odd = $cnt&1; + my $nix = $odd ? $nlo : $nhi; + + &shl (&LB($nlo),4) if ($odd); + &psrlq ($Zlo,4); + &movq ($tmp,$Zhi); + &psrlq ($Zhi,4); + &pxor ($Zlo,&QWP(8,$Htbl,$nix)); + &mov (&LB($nlo),&BP($cnt/2,$inp)) if (!$odd && $cnt>=0); + &psllq ($tmp,60); + &and ($nhi,0xf0) if ($odd); + &pxor ($Zhi,&QWP(0,$rem_4bit,$rem[1],8)) if ($cnt<28); + &and ($rem[0],0xf); + &pxor ($Zhi,&QWP(0,$Htbl,$nix)); + &mov ($nhi,$nlo) if (!$odd && $cnt>=0); + &movd ($rem[1],$Zlo); + &pxor ($Zlo,$tmp); + + push (@rem,shift(@rem)); # "rotate" registers + } + + &mov ($inp,&DWP(4,$rem_4bit,$rem[1],8)); # last rem_4bit[rem] + + &psrlq ($Zlo,32); # lower part of Zlo is already there + &movd ($Zhl,$Zhi); + &psrlq ($Zhi,32); + &movd ($Zlh,$Zlo); + &movd ($Zhh,$Zhi); + &shl ($inp,4); # compensate for rem_4bit[i] being >>4 + + &bswap ($Zll); + &bswap ($Zhl); + &bswap ($Zlh); + &xor ($Zhh,$inp); + &bswap ($Zhh); + + &ret (); +} +&function_end_B("_mmx_gmult_4bit_inner"); + +&function_begin("gcm_gmult_4bit_mmx"); + &mov ($inp,&wparam(0)); # load Xi + &mov ($Htbl,&wparam(1)); # load Htable + + &call (&label("pic_point")); + &set_label("pic_point"); + &blindpop("eax"); + &lea ("eax",&DWP(&label("rem_4bit")."-".&label("pic_point"),"eax")); + + &movz ($Zll,&BP(15,$inp)); + + &call ("_mmx_gmult_4bit_inner"); + + &mov ($inp,&wparam(0)); # load Xi + &emms (); + &mov (&DWP(12,$inp),$Zll); + &mov (&DWP(4,$inp),$Zhl); + &mov (&DWP(8,$inp),$Zlh); + &mov (&DWP(0,$inp),$Zhh); +&function_end("gcm_gmult_4bit_mmx"); + +# Streamed version performs 20% better on P4, 7% on Opteron, +# 10% on Core2 and PIII... +&function_begin("gcm_ghash_4bit_mmx"); + &mov ($Zhh,&wparam(0)); # load Xi + &mov ($Htbl,&wparam(1)); # load Htable + &mov ($inp,&wparam(2)); # load in + &mov ($Zlh,&wparam(3)); # load len + + &call (&label("pic_point")); + &set_label("pic_point"); + &blindpop("eax"); + &lea ("eax",&DWP(&label("rem_4bit")."-".&label("pic_point"),"eax")); + + &add ($Zlh,$inp); + &mov (&wparam(3),$Zlh); # len to point at the end of input + &stack_push(4+1); # +1 for stack alignment + + &mov ($Zll,&DWP(12,$Zhh)); # load Xi[16] + &mov ($Zhl,&DWP(4,$Zhh)); + &mov ($Zlh,&DWP(8,$Zhh)); + &mov ($Zhh,&DWP(0,$Zhh)); + &jmp (&label("mmx_outer_loop")); + + &set_label("mmx_outer_loop",16); + &xor ($Zll,&DWP(12,$inp)); + &xor ($Zhl,&DWP(4,$inp)); + &xor ($Zlh,&DWP(8,$inp)); + &xor ($Zhh,&DWP(0,$inp)); + &mov (&wparam(2),$inp); + &mov (&DWP(12,"esp"),$Zll); + &mov (&DWP(4,"esp"),$Zhl); + &mov (&DWP(8,"esp"),$Zlh); + &mov (&DWP(0,"esp"),$Zhh); + + &mov ($inp,"esp"); + &shr ($Zll,24); + + &call ("_mmx_gmult_4bit_inner"); + + &mov ($inp,&wparam(2)); + &lea ($inp,&DWP(16,$inp)); + &cmp ($inp,&wparam(3)); + &jb (&label("mmx_outer_loop")); + + &mov ($inp,&wparam(0)); # load Xi + &emms (); + &mov (&DWP(12,$inp),$Zll); + &mov (&DWP(4,$inp),$Zhl); + &mov (&DWP(8,$inp),$Zlh); + &mov (&DWP(0,$inp),$Zhh); + + &stack_pop(4+1); +&function_end("gcm_ghash_4bit_mmx"); + +}} else {{ # "June" MMX version... + # ... has slower "April" gcm_gmult_4bit_mmx with folded + # loop. This is done to conserve code size... +$S=16; # shift factor for rem_4bit + +sub mmx_loop() { +# MMX version performs 2.8 times better on P4 (see comment in non-MMX +# routine for further details), 40% better on Opteron and Core2, 50% +# better on PIII... In other words effort is considered to be well +# spent... + my $inp = shift; + my $rem_4bit = shift; + my $cnt = $Zhh; + my $nhi = $Zhl; + my $nlo = $Zlh; + my $rem = $Zll; + + my ($Zlo,$Zhi) = ("mm0","mm1"); + my $tmp = "mm2"; + + &xor ($nlo,$nlo); # avoid partial register stalls on PIII + &mov ($nhi,$Zll); + &mov (&LB($nlo),&LB($nhi)); + &mov ($cnt,14); + &shl (&LB($nlo),4); + &and ($nhi,0xf0); + &movq ($Zlo,&QWP(8,$Htbl,$nlo)); + &movq ($Zhi,&QWP(0,$Htbl,$nlo)); + &movd ($rem,$Zlo); + &jmp (&label("mmx_loop")); + + &set_label("mmx_loop",16); + &psrlq ($Zlo,4); + &and ($rem,0xf); + &movq ($tmp,$Zhi); + &psrlq ($Zhi,4); + &pxor ($Zlo,&QWP(8,$Htbl,$nhi)); + &mov (&LB($nlo),&BP(0,$inp,$cnt)); + &psllq ($tmp,60); + &pxor ($Zhi,&QWP(0,$rem_4bit,$rem,8)); + &dec ($cnt); + &movd ($rem,$Zlo); + &pxor ($Zhi,&QWP(0,$Htbl,$nhi)); + &mov ($nhi,$nlo); + &pxor ($Zlo,$tmp); + &js (&label("mmx_break")); + + &shl (&LB($nlo),4); + &and ($rem,0xf); + &psrlq ($Zlo,4); + &and ($nhi,0xf0); + &movq ($tmp,$Zhi); + &psrlq ($Zhi,4); + &pxor ($Zlo,&QWP(8,$Htbl,$nlo)); + &psllq ($tmp,60); + &pxor ($Zhi,&QWP(0,$rem_4bit,$rem,8)); + &movd ($rem,$Zlo); + &pxor ($Zhi,&QWP(0,$Htbl,$nlo)); + &pxor ($Zlo,$tmp); + &jmp (&label("mmx_loop")); + + &set_label("mmx_break",16); + &shl (&LB($nlo),4); + &and ($rem,0xf); + &psrlq ($Zlo,4); + &and ($nhi,0xf0); + &movq ($tmp,$Zhi); + &psrlq ($Zhi,4); + &pxor ($Zlo,&QWP(8,$Htbl,$nlo)); + &psllq ($tmp,60); + &pxor ($Zhi,&QWP(0,$rem_4bit,$rem,8)); + &movd ($rem,$Zlo); + &pxor ($Zhi,&QWP(0,$Htbl,$nlo)); + &pxor ($Zlo,$tmp); + + &psrlq ($Zlo,4); + &and ($rem,0xf); + &movq ($tmp,$Zhi); + &psrlq ($Zhi,4); + &pxor ($Zlo,&QWP(8,$Htbl,$nhi)); + &psllq ($tmp,60); + &pxor ($Zhi,&QWP(0,$rem_4bit,$rem,8)); + &movd ($rem,$Zlo); + &pxor ($Zhi,&QWP(0,$Htbl,$nhi)); + &pxor ($Zlo,$tmp); + + &psrlq ($Zlo,32); # lower part of Zlo is already there + &movd ($Zhl,$Zhi); + &psrlq ($Zhi,32); + &movd ($Zlh,$Zlo); + &movd ($Zhh,$Zhi); + + &bswap ($Zll); + &bswap ($Zhl); + &bswap ($Zlh); + &bswap ($Zhh); +} + +&function_begin("gcm_gmult_4bit_mmx"); + &mov ($inp,&wparam(0)); # load Xi + &mov ($Htbl,&wparam(1)); # load Htable + + &call (&label("pic_point")); + &set_label("pic_point"); + &blindpop("eax"); + &lea ("eax",&DWP(&label("rem_4bit")."-".&label("pic_point"),"eax")); + + &movz ($Zll,&BP(15,$inp)); + + &mmx_loop($inp,"eax"); + + &emms (); + &mov (&DWP(12,$inp),$Zll); + &mov (&DWP(4,$inp),$Zhl); + &mov (&DWP(8,$inp),$Zlh); + &mov (&DWP(0,$inp),$Zhh); +&function_end("gcm_gmult_4bit_mmx"); + +###################################################################### +# Below subroutine is "528B" variant of "4-bit" GCM GHASH function +# (see gcm128.c for details). It provides further 20-40% performance +# improvement over above mentioned "May" version. + +&static_label("rem_8bit"); + +&function_begin("gcm_ghash_4bit_mmx"); +{ my ($Zlo,$Zhi) = ("mm7","mm6"); + my $rem_8bit = "esi"; + my $Htbl = "ebx"; + + # parameter block + &mov ("eax",&wparam(0)); # Xi + &mov ("ebx",&wparam(1)); # Htable + &mov ("ecx",&wparam(2)); # inp + &mov ("edx",&wparam(3)); # len + &mov ("ebp","esp"); # original %esp + &call (&label("pic_point")); + &set_label ("pic_point"); + &blindpop ($rem_8bit); + &lea ($rem_8bit,&DWP(&label("rem_8bit")."-".&label("pic_point"),$rem_8bit)); + + &sub ("esp",512+16+16); # allocate stack frame... + &and ("esp",-64); # ...and align it + &sub ("esp",16); # place for (u8)(H[]<<4) + + &add ("edx","ecx"); # pointer to the end of input + &mov (&DWP(528+16+0,"esp"),"eax"); # save Xi + &mov (&DWP(528+16+8,"esp"),"edx"); # save inp+len + &mov (&DWP(528+16+12,"esp"),"ebp"); # save original %esp + + { my @lo = ("mm0","mm1","mm2"); + my @hi = ("mm3","mm4","mm5"); + my @tmp = ("mm6","mm7"); + my ($off1,$off2,$i) = (0,0,); + + &add ($Htbl,128); # optimize for size + &lea ("edi",&DWP(16+128,"esp")); + &lea ("ebp",&DWP(16+256+128,"esp")); + + # decompose Htable (low and high parts are kept separately), + # generate Htable[]>>4, (u8)(Htable[]<<4), save to stack... + for ($i=0;$i<18;$i++) { + + &mov ("edx",&DWP(16*$i+8-128,$Htbl)) if ($i<16); + &movq ($lo[0],&QWP(16*$i+8-128,$Htbl)) if ($i<16); + &psllq ($tmp[1],60) if ($i>1); + &movq ($hi[0],&QWP(16*$i+0-128,$Htbl)) if ($i<16); + &por ($lo[2],$tmp[1]) if ($i>1); + &movq (&QWP($off1-128,"edi"),$lo[1]) if ($i>0 && $i<17); + &psrlq ($lo[1],4) if ($i>0 && $i<17); + &movq (&QWP($off1,"edi"),$hi[1]) if ($i>0 && $i<17); + &movq ($tmp[0],$hi[1]) if ($i>0 && $i<17); + &movq (&QWP($off2-128,"ebp"),$lo[2]) if ($i>1); + &psrlq ($hi[1],4) if ($i>0 && $i<17); + &movq (&QWP($off2,"ebp"),$hi[2]) if ($i>1); + &shl ("edx",4) if ($i<16); + &mov (&BP($i,"esp"),&LB("edx")) if ($i<16); + + unshift (@lo,pop(@lo)); # "rotate" registers + unshift (@hi,pop(@hi)); + unshift (@tmp,pop(@tmp)); + $off1 += 8 if ($i>0); + $off2 += 8 if ($i>1); + } + } + + &movq ($Zhi,&QWP(0,"eax")); + &mov ("ebx",&DWP(8,"eax")); + &mov ("edx",&DWP(12,"eax")); # load Xi + +&set_label("outer",16); + { my $nlo = "eax"; + my $dat = "edx"; + my @nhi = ("edi","ebp"); + my @rem = ("ebx","ecx"); + my @red = ("mm0","mm1","mm2"); + my $tmp = "mm3"; + + &xor ($dat,&DWP(12,"ecx")); # merge input data + &xor ("ebx",&DWP(8,"ecx")); + &pxor ($Zhi,&QWP(0,"ecx")); + &lea ("ecx",&DWP(16,"ecx")); # inp+=16 + #&mov (&DWP(528+12,"esp"),$dat); # save inp^Xi + &mov (&DWP(528+8,"esp"),"ebx"); + &movq (&QWP(528+0,"esp"),$Zhi); + &mov (&DWP(528+16+4,"esp"),"ecx"); # save inp + + &xor ($nlo,$nlo); + &rol ($dat,8); + &mov (&LB($nlo),&LB($dat)); + &mov ($nhi[1],$nlo); + &and (&LB($nlo),0x0f); + &shr ($nhi[1],4); + &pxor ($red[0],$red[0]); + &rol ($dat,8); # next byte + &pxor ($red[1],$red[1]); + &pxor ($red[2],$red[2]); + + # Just like in "May" verson modulo-schedule for critical path in + # 'Z.hi ^= rem_8bit[Z.lo&0xff^((u8)H[nhi]<<4)]<<48'. Final 'pxor' + # is scheduled so late that rem_8bit[] has to be shifted *right* + # by 16, which is why last argument to pinsrw is 2, which + # corresponds to <<32=<<48>>16... + for ($j=11,$i=0;$i<15;$i++) { + + if ($i>0) { + &pxor ($Zlo,&QWP(16,"esp",$nlo,8)); # Z^=H[nlo] + &rol ($dat,8); # next byte + &pxor ($Zhi,&QWP(16+128,"esp",$nlo,8)); + + &pxor ($Zlo,$tmp); + &pxor ($Zhi,&QWP(16+256+128,"esp",$nhi[0],8)); + &xor (&LB($rem[1]),&BP(0,"esp",$nhi[0])); # rem^(H[nhi]<<4) + } else { + &movq ($Zlo,&QWP(16,"esp",$nlo,8)); + &movq ($Zhi,&QWP(16+128,"esp",$nlo,8)); + } + + &mov (&LB($nlo),&LB($dat)); + &mov ($dat,&DWP(528+$j,"esp")) if (--$j%4==0); + + &movd ($rem[0],$Zlo); + &movz ($rem[1],&LB($rem[1])) if ($i>0); + &psrlq ($Zlo,8); # Z>>=8 + + &movq ($tmp,$Zhi); + &mov ($nhi[0],$nlo); + &psrlq ($Zhi,8); + + &pxor ($Zlo,&QWP(16+256+0,"esp",$nhi[1],8)); # Z^=H[nhi]>>4 + &and (&LB($nlo),0x0f); + &psllq ($tmp,56); + + &pxor ($Zhi,$red[1]) if ($i>1); + &shr ($nhi[0],4); + &pinsrw ($red[0],&WP(0,$rem_8bit,$rem[1],2),2) if ($i>0); + + unshift (@red,pop(@red)); # "rotate" registers + unshift (@rem,pop(@rem)); + unshift (@nhi,pop(@nhi)); + } + + &pxor ($Zlo,&QWP(16,"esp",$nlo,8)); # Z^=H[nlo] + &pxor ($Zhi,&QWP(16+128,"esp",$nlo,8)); + &xor (&LB($rem[1]),&BP(0,"esp",$nhi[0])); # rem^(H[nhi]<<4) + + &pxor ($Zlo,$tmp); + &pxor ($Zhi,&QWP(16+256+128,"esp",$nhi[0],8)); + &movz ($rem[1],&LB($rem[1])); + + &pxor ($red[2],$red[2]); # clear 2nd word + &psllq ($red[1],4); + + &movd ($rem[0],$Zlo); + &psrlq ($Zlo,4); # Z>>=4 + + &movq ($tmp,$Zhi); + &psrlq ($Zhi,4); + &shl ($rem[0],4); # rem<<4 + + &pxor ($Zlo,&QWP(16,"esp",$nhi[1],8)); # Z^=H[nhi] + &psllq ($tmp,60); + &movz ($rem[0],&LB($rem[0])); + + &pxor ($Zlo,$tmp); + &pxor ($Zhi,&QWP(16+128,"esp",$nhi[1],8)); + + &pinsrw ($red[0],&WP(0,$rem_8bit,$rem[1],2),2); + &pxor ($Zhi,$red[1]); + + &movd ($dat,$Zlo); + &pinsrw ($red[2],&WP(0,$rem_8bit,$rem[0],2),3); # last is <<48 + + &psllq ($red[0],12); # correct by <<16>>4 + &pxor ($Zhi,$red[0]); + &psrlq ($Zlo,32); + &pxor ($Zhi,$red[2]); + + &mov ("ecx",&DWP(528+16+4,"esp")); # restore inp + &movd ("ebx",$Zlo); + &movq ($tmp,$Zhi); # 01234567 + &psllw ($Zhi,8); # 1.3.5.7. + &psrlw ($tmp,8); # .0.2.4.6 + &por ($Zhi,$tmp); # 10325476 + &bswap ($dat); + &pshufw ($Zhi,$Zhi,0b00011011); # 76543210 + &bswap ("ebx"); + + &cmp ("ecx",&DWP(528+16+8,"esp")); # are we done? + &jne (&label("outer")); + } + + &mov ("eax",&DWP(528+16+0,"esp")); # restore Xi + &mov (&DWP(12,"eax"),"edx"); + &mov (&DWP(8,"eax"),"ebx"); + &movq (&QWP(0,"eax"),$Zhi); + + &mov ("esp",&DWP(528+16+12,"esp")); # restore original %esp + &emms (); +} +&function_end("gcm_ghash_4bit_mmx"); +}} + +if ($sse2) {{ +###################################################################### +# PCLMULQDQ version. + +$Xip="eax"; +$Htbl="edx"; +$const="ecx"; +$inp="esi"; +$len="ebx"; + +($Xi,$Xhi)=("xmm0","xmm1"); $Hkey="xmm2"; +($T1,$T2,$T3)=("xmm3","xmm4","xmm5"); +($Xn,$Xhn)=("xmm6","xmm7"); + +&static_label("bswap"); + +sub clmul64x64_T2 { # minimal "register" pressure +my ($Xhi,$Xi,$Hkey)=@_; + + &movdqa ($Xhi,$Xi); # + &pshufd ($T1,$Xi,0b01001110); + &pshufd ($T2,$Hkey,0b01001110); + &pxor ($T1,$Xi); # + &pxor ($T2,$Hkey); + + &pclmulqdq ($Xi,$Hkey,0x00); ####### + &pclmulqdq ($Xhi,$Hkey,0x11); ####### + &pclmulqdq ($T1,$T2,0x00); ####### + &xorps ($T1,$Xi); # + &xorps ($T1,$Xhi); # + + &movdqa ($T2,$T1); # + &psrldq ($T1,8); + &pslldq ($T2,8); # + &pxor ($Xhi,$T1); + &pxor ($Xi,$T2); # +} + +sub clmul64x64_T3 { +# Even though this subroutine offers visually better ILP, it +# was empirically found to be a tad slower than above version. +# At least in gcm_ghash_clmul context. But it's just as well, +# because loop modulo-scheduling is possible only thanks to +# minimized "register" pressure... +my ($Xhi,$Xi,$Hkey)=@_; + + &movdqa ($T1,$Xi); # + &movdqa ($Xhi,$Xi); + &pclmulqdq ($Xi,$Hkey,0x00); ####### + &pclmulqdq ($Xhi,$Hkey,0x11); ####### + &pshufd ($T2,$T1,0b01001110); # + &pshufd ($T3,$Hkey,0b01001110); + &pxor ($T2,$T1); # + &pxor ($T3,$Hkey); + &pclmulqdq ($T2,$T3,0x00); ####### + &pxor ($T2,$Xi); # + &pxor ($T2,$Xhi); # + + &movdqa ($T3,$T2); # + &psrldq ($T2,8); + &pslldq ($T3,8); # + &pxor ($Xhi,$T2); + &pxor ($Xi,$T3); # +} + +if (1) { # Algorithm 9 with <<1 twist. + # Reduction is shorter and uses only two + # temporary registers, which makes it better + # candidate for interleaving with 64x64 + # multiplication. Pre-modulo-scheduled loop + # was found to be ~20% faster than Algorithm 5 + # below. Algorithm 9 was therefore chosen for + # further optimization... + +sub reduction_alg9 { # 17/13 times faster than Intel version +my ($Xhi,$Xi) = @_; + + # 1st phase + &movdqa ($T1,$Xi); # + &psllq ($Xi,1); + &pxor ($Xi,$T1); # + &psllq ($Xi,5); # + &pxor ($Xi,$T1); # + &psllq ($Xi,57); # + &movdqa ($T2,$Xi); # + &pslldq ($Xi,8); + &psrldq ($T2,8); # + &pxor ($Xi,$T1); + &pxor ($Xhi,$T2); # + + # 2nd phase + &movdqa ($T2,$Xi); + &psrlq ($Xi,5); + &pxor ($Xi,$T2); # + &psrlq ($Xi,1); # + &pxor ($Xi,$T2); # + &pxor ($T2,$Xhi); + &psrlq ($Xi,1); # + &pxor ($Xi,$T2); # +} + +&function_begin_B("gcm_init_clmul"); + &mov ($Htbl,&wparam(0)); + &mov ($Xip,&wparam(1)); + + &call (&label("pic")); +&set_label("pic"); + &blindpop ($const); + &lea ($const,&DWP(&label("bswap")."-".&label("pic"),$const)); + + &movdqu ($Hkey,&QWP(0,$Xip)); + &pshufd ($Hkey,$Hkey,0b01001110);# dword swap + + # <<1 twist + &pshufd ($T2,$Hkey,0b11111111); # broadcast uppermost dword + &movdqa ($T1,$Hkey); + &psllq ($Hkey,1); + &pxor ($T3,$T3); # + &psrlq ($T1,63); + &pcmpgtd ($T3,$T2); # broadcast carry bit + &pslldq ($T1,8); + &por ($Hkey,$T1); # H<<=1 + + # magic reduction + &pand ($T3,&QWP(16,$const)); # 0x1c2_polynomial + &pxor ($Hkey,$T3); # if(carry) H^=0x1c2_polynomial + + # calculate H^2 + &movdqa ($Xi,$Hkey); + &clmul64x64_T2 ($Xhi,$Xi,$Hkey); + &reduction_alg9 ($Xhi,$Xi); + + &movdqu (&QWP(0,$Htbl),$Hkey); # save H + &movdqu (&QWP(16,$Htbl),$Xi); # save H^2 + + &ret (); +&function_end_B("gcm_init_clmul"); + +&function_begin_B("gcm_gmult_clmul"); + &mov ($Xip,&wparam(0)); + &mov ($Htbl,&wparam(1)); + + &call (&label("pic")); +&set_label("pic"); + &blindpop ($const); + &lea ($const,&DWP(&label("bswap")."-".&label("pic"),$const)); + + &movdqu ($Xi,&QWP(0,$Xip)); + &movdqa ($T3,&QWP(0,$const)); + &movups ($Hkey,&QWP(0,$Htbl)); + &pshufb ($Xi,$T3); + + &clmul64x64_T2 ($Xhi,$Xi,$Hkey); + &reduction_alg9 ($Xhi,$Xi); + + &pshufb ($Xi,$T3); + &movdqu (&QWP(0,$Xip),$Xi); + + &ret (); +&function_end_B("gcm_gmult_clmul"); + +&function_begin("gcm_ghash_clmul"); + &mov ($Xip,&wparam(0)); + &mov ($Htbl,&wparam(1)); + &mov ($inp,&wparam(2)); + &mov ($len,&wparam(3)); + + &call (&label("pic")); +&set_label("pic"); + &blindpop ($const); + &lea ($const,&DWP(&label("bswap")."-".&label("pic"),$const)); + + &movdqu ($Xi,&QWP(0,$Xip)); + &movdqa ($T3,&QWP(0,$const)); + &movdqu ($Hkey,&QWP(0,$Htbl)); + &pshufb ($Xi,$T3); + + &sub ($len,0x10); + &jz (&label("odd_tail")); + + ####### + # Xi+2 =[H*(Ii+1 + Xi+1)] mod P = + # [(H*Ii+1) + (H*Xi+1)] mod P = + # [(H*Ii+1) + H^2*(Ii+Xi)] mod P + # + &movdqu ($T1,&QWP(0,$inp)); # Ii + &movdqu ($Xn,&QWP(16,$inp)); # Ii+1 + &pshufb ($T1,$T3); + &pshufb ($Xn,$T3); + &pxor ($Xi,$T1); # Ii+Xi + + &clmul64x64_T2 ($Xhn,$Xn,$Hkey); # H*Ii+1 + &movups ($Hkey,&QWP(16,$Htbl)); # load H^2 + + &lea ($inp,&DWP(32,$inp)); # i+=2 + &sub ($len,0x20); + &jbe (&label("even_tail")); + +&set_label("mod_loop"); + &clmul64x64_T2 ($Xhi,$Xi,$Hkey); # H^2*(Ii+Xi) + &movdqu ($T1,&QWP(0,$inp)); # Ii + &movups ($Hkey,&QWP(0,$Htbl)); # load H + + &pxor ($Xi,$Xn); # (H*Ii+1) + H^2*(Ii+Xi) + &pxor ($Xhi,$Xhn); + + &movdqu ($Xn,&QWP(16,$inp)); # Ii+1 + &pshufb ($T1,$T3); + &pshufb ($Xn,$T3); + + &movdqa ($T3,$Xn); #&clmul64x64_TX ($Xhn,$Xn,$Hkey); H*Ii+1 + &movdqa ($Xhn,$Xn); + &pxor ($Xhi,$T1); # "Ii+Xi", consume early + + &movdqa ($T1,$Xi); #&reduction_alg9($Xhi,$Xi); 1st phase + &psllq ($Xi,1); + &pxor ($Xi,$T1); # + &psllq ($Xi,5); # + &pxor ($Xi,$T1); # + &pclmulqdq ($Xn,$Hkey,0x00); ####### + &psllq ($Xi,57); # + &movdqa ($T2,$Xi); # + &pslldq ($Xi,8); + &psrldq ($T2,8); # + &pxor ($Xi,$T1); + &pshufd ($T1,$T3,0b01001110); + &pxor ($Xhi,$T2); # + &pxor ($T1,$T3); + &pshufd ($T3,$Hkey,0b01001110); + &pxor ($T3,$Hkey); # + + &pclmulqdq ($Xhn,$Hkey,0x11); ####### + &movdqa ($T2,$Xi); # 2nd phase + &psrlq ($Xi,5); + &pxor ($Xi,$T2); # + &psrlq ($Xi,1); # + &pxor ($Xi,$T2); # + &pxor ($T2,$Xhi); + &psrlq ($Xi,1); # + &pxor ($Xi,$T2); # + + &pclmulqdq ($T1,$T3,0x00); ####### + &movups ($Hkey,&QWP(16,$Htbl)); # load H^2 + &xorps ($T1,$Xn); # + &xorps ($T1,$Xhn); # + + &movdqa ($T3,$T1); # + &psrldq ($T1,8); + &pslldq ($T3,8); # + &pxor ($Xhn,$T1); + &pxor ($Xn,$T3); # + &movdqa ($T3,&QWP(0,$const)); + + &lea ($inp,&DWP(32,$inp)); + &sub ($len,0x20); + &ja (&label("mod_loop")); + +&set_label("even_tail"); + &clmul64x64_T2 ($Xhi,$Xi,$Hkey); # H^2*(Ii+Xi) + + &pxor ($Xi,$Xn); # (H*Ii+1) + H^2*(Ii+Xi) + &pxor ($Xhi,$Xhn); + + &reduction_alg9 ($Xhi,$Xi); + + &test ($len,$len); + &jnz (&label("done")); + + &movups ($Hkey,&QWP(0,$Htbl)); # load H +&set_label("odd_tail"); + &movdqu ($T1,&QWP(0,$inp)); # Ii + &pshufb ($T1,$T3); + &pxor ($Xi,$T1); # Ii+Xi + + &clmul64x64_T2 ($Xhi,$Xi,$Hkey); # H*(Ii+Xi) + &reduction_alg9 ($Xhi,$Xi); + +&set_label("done"); + &pshufb ($Xi,$T3); + &movdqu (&QWP(0,$Xip),$Xi); +&function_end("gcm_ghash_clmul"); + +} else { # Algorith 5. Kept for reference purposes. + +sub reduction_alg5 { # 19/16 times faster than Intel version +my ($Xhi,$Xi)=@_; + + # <<1 + &movdqa ($T1,$Xi); # + &movdqa ($T2,$Xhi); + &pslld ($Xi,1); + &pslld ($Xhi,1); # + &psrld ($T1,31); + &psrld ($T2,31); # + &movdqa ($T3,$T1); + &pslldq ($T1,4); + &psrldq ($T3,12); # + &pslldq ($T2,4); + &por ($Xhi,$T3); # + &por ($Xi,$T1); + &por ($Xhi,$T2); # + + # 1st phase + &movdqa ($T1,$Xi); + &movdqa ($T2,$Xi); + &movdqa ($T3,$Xi); # + &pslld ($T1,31); + &pslld ($T2,30); + &pslld ($Xi,25); # + &pxor ($T1,$T2); + &pxor ($T1,$Xi); # + &movdqa ($T2,$T1); # + &pslldq ($T1,12); + &psrldq ($T2,4); # + &pxor ($T3,$T1); + + # 2nd phase + &pxor ($Xhi,$T3); # + &movdqa ($Xi,$T3); + &movdqa ($T1,$T3); + &psrld ($Xi,1); # + &psrld ($T1,2); + &psrld ($T3,7); # + &pxor ($Xi,$T1); + &pxor ($Xhi,$T2); + &pxor ($Xi,$T3); # + &pxor ($Xi,$Xhi); # +} + +&function_begin_B("gcm_init_clmul"); + &mov ($Htbl,&wparam(0)); + &mov ($Xip,&wparam(1)); + + &call (&label("pic")); +&set_label("pic"); + &blindpop ($const); + &lea ($const,&DWP(&label("bswap")."-".&label("pic"),$const)); + + &movdqu ($Hkey,&QWP(0,$Xip)); + &pshufd ($Hkey,$Hkey,0b01001110);# dword swap + + # calculate H^2 + &movdqa ($Xi,$Hkey); + &clmul64x64_T3 ($Xhi,$Xi,$Hkey); + &reduction_alg5 ($Xhi,$Xi); + + &movdqu (&QWP(0,$Htbl),$Hkey); # save H + &movdqu (&QWP(16,$Htbl),$Xi); # save H^2 + + &ret (); +&function_end_B("gcm_init_clmul"); + +&function_begin_B("gcm_gmult_clmul"); + &mov ($Xip,&wparam(0)); + &mov ($Htbl,&wparam(1)); + + &call (&label("pic")); +&set_label("pic"); + &blindpop ($const); + &lea ($const,&DWP(&label("bswap")."-".&label("pic"),$const)); + + &movdqu ($Xi,&QWP(0,$Xip)); + &movdqa ($Xn,&QWP(0,$const)); + &movdqu ($Hkey,&QWP(0,$Htbl)); + &pshufb ($Xi,$Xn); + + &clmul64x64_T3 ($Xhi,$Xi,$Hkey); + &reduction_alg5 ($Xhi,$Xi); + + &pshufb ($Xi,$Xn); + &movdqu (&QWP(0,$Xip),$Xi); + + &ret (); +&function_end_B("gcm_gmult_clmul"); + +&function_begin("gcm_ghash_clmul"); + &mov ($Xip,&wparam(0)); + &mov ($Htbl,&wparam(1)); + &mov ($inp,&wparam(2)); + &mov ($len,&wparam(3)); + + &call (&label("pic")); +&set_label("pic"); + &blindpop ($const); + &lea ($const,&DWP(&label("bswap")."-".&label("pic"),$const)); + + &movdqu ($Xi,&QWP(0,$Xip)); + &movdqa ($T3,&QWP(0,$const)); + &movdqu ($Hkey,&QWP(0,$Htbl)); + &pshufb ($Xi,$T3); + + &sub ($len,0x10); + &jz (&label("odd_tail")); + + ####### + # Xi+2 =[H*(Ii+1 + Xi+1)] mod P = + # [(H*Ii+1) + (H*Xi+1)] mod P = + # [(H*Ii+1) + H^2*(Ii+Xi)] mod P + # + &movdqu ($T1,&QWP(0,$inp)); # Ii + &movdqu ($Xn,&QWP(16,$inp)); # Ii+1 + &pshufb ($T1,$T3); + &pshufb ($Xn,$T3); + &pxor ($Xi,$T1); # Ii+Xi + + &clmul64x64_T3 ($Xhn,$Xn,$Hkey); # H*Ii+1 + &movdqu ($Hkey,&QWP(16,$Htbl)); # load H^2 + + &sub ($len,0x20); + &lea ($inp,&DWP(32,$inp)); # i+=2 + &jbe (&label("even_tail")); + +&set_label("mod_loop"); + &clmul64x64_T3 ($Xhi,$Xi,$Hkey); # H^2*(Ii+Xi) + &movdqu ($Hkey,&QWP(0,$Htbl)); # load H + + &pxor ($Xi,$Xn); # (H*Ii+1) + H^2*(Ii+Xi) + &pxor ($Xhi,$Xhn); + + &reduction_alg5 ($Xhi,$Xi); + + ####### + &movdqa ($T3,&QWP(0,$const)); + &movdqu ($T1,&QWP(0,$inp)); # Ii + &movdqu ($Xn,&QWP(16,$inp)); # Ii+1 + &pshufb ($T1,$T3); + &pshufb ($Xn,$T3); + &pxor ($Xi,$T1); # Ii+Xi + + &clmul64x64_T3 ($Xhn,$Xn,$Hkey); # H*Ii+1 + &movdqu ($Hkey,&QWP(16,$Htbl)); # load H^2 + + &sub ($len,0x20); + &lea ($inp,&DWP(32,$inp)); + &ja (&label("mod_loop")); + +&set_label("even_tail"); + &clmul64x64_T3 ($Xhi,$Xi,$Hkey); # H^2*(Ii+Xi) + + &pxor ($Xi,$Xn); # (H*Ii+1) + H^2*(Ii+Xi) + &pxor ($Xhi,$Xhn); + + &reduction_alg5 ($Xhi,$Xi); + + &movdqa ($T3,&QWP(0,$const)); + &test ($len,$len); + &jnz (&label("done")); + + &movdqu ($Hkey,&QWP(0,$Htbl)); # load H +&set_label("odd_tail"); + &movdqu ($T1,&QWP(0,$inp)); # Ii + &pshufb ($T1,$T3); + &pxor ($Xi,$T1); # Ii+Xi + + &clmul64x64_T3 ($Xhi,$Xi,$Hkey); # H*(Ii+Xi) + &reduction_alg5 ($Xhi,$Xi); + + &movdqa ($T3,&QWP(0,$const)); +&set_label("done"); + &pshufb ($Xi,$T3); + &movdqu (&QWP(0,$Xip),$Xi); +&function_end("gcm_ghash_clmul"); + +} + +&set_label("bswap",64); + &data_byte(15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0); + &data_byte(1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2); # 0x1c2_polynomial +}} # $sse2 + +&set_label("rem_4bit",64); + &data_word(0,0x0000<<$S,0,0x1C20<<$S,0,0x3840<<$S,0,0x2460<<$S); + &data_word(0,0x7080<<$S,0,0x6CA0<<$S,0,0x48C0<<$S,0,0x54E0<<$S); + &data_word(0,0xE100<<$S,0,0xFD20<<$S,0,0xD940<<$S,0,0xC560<<$S); + &data_word(0,0x9180<<$S,0,0x8DA0<<$S,0,0xA9C0<<$S,0,0xB5E0<<$S); +&set_label("rem_8bit",64); + &data_short(0x0000,0x01C2,0x0384,0x0246,0x0708,0x06CA,0x048C,0x054E); + &data_short(0x0E10,0x0FD2,0x0D94,0x0C56,0x0918,0x08DA,0x0A9C,0x0B5E); + &data_short(0x1C20,0x1DE2,0x1FA4,0x1E66,0x1B28,0x1AEA,0x18AC,0x196E); + &data_short(0x1230,0x13F2,0x11B4,0x1076,0x1538,0x14FA,0x16BC,0x177E); + &data_short(0x3840,0x3982,0x3BC4,0x3A06,0x3F48,0x3E8A,0x3CCC,0x3D0E); + &data_short(0x3650,0x3792,0x35D4,0x3416,0x3158,0x309A,0x32DC,0x331E); + &data_short(0x2460,0x25A2,0x27E4,0x2626,0x2368,0x22AA,0x20EC,0x212E); + &data_short(0x2A70,0x2BB2,0x29F4,0x2836,0x2D78,0x2CBA,0x2EFC,0x2F3E); + &data_short(0x7080,0x7142,0x7304,0x72C6,0x7788,0x764A,0x740C,0x75CE); + &data_short(0x7E90,0x7F52,0x7D14,0x7CD6,0x7998,0x785A,0x7A1C,0x7BDE); + &data_short(0x6CA0,0x6D62,0x6F24,0x6EE6,0x6BA8,0x6A6A,0x682C,0x69EE); + &data_short(0x62B0,0x6372,0x6134,0x60F6,0x65B8,0x647A,0x663C,0x67FE); + &data_short(0x48C0,0x4902,0x4B44,0x4A86,0x4FC8,0x4E0A,0x4C4C,0x4D8E); + &data_short(0x46D0,0x4712,0x4554,0x4496,0x41D8,0x401A,0x425C,0x439E); + &data_short(0x54E0,0x5522,0x5764,0x56A6,0x53E8,0x522A,0x506C,0x51AE); + &data_short(0x5AF0,0x5B32,0x5974,0x58B6,0x5DF8,0x5C3A,0x5E7C,0x5FBE); + &data_short(0xE100,0xE0C2,0xE284,0xE346,0xE608,0xE7CA,0xE58C,0xE44E); + &data_short(0xEF10,0xEED2,0xEC94,0xED56,0xE818,0xE9DA,0xEB9C,0xEA5E); + &data_short(0xFD20,0xFCE2,0xFEA4,0xFF66,0xFA28,0xFBEA,0xF9AC,0xF86E); + &data_short(0xF330,0xF2F2,0xF0B4,0xF176,0xF438,0xF5FA,0xF7BC,0xF67E); + &data_short(0xD940,0xD882,0xDAC4,0xDB06,0xDE48,0xDF8A,0xDDCC,0xDC0E); + &data_short(0xD750,0xD692,0xD4D4,0xD516,0xD058,0xD19A,0xD3DC,0xD21E); + &data_short(0xC560,0xC4A2,0xC6E4,0xC726,0xC268,0xC3AA,0xC1EC,0xC02E); + &data_short(0xCB70,0xCAB2,0xC8F4,0xC936,0xCC78,0xCDBA,0xCFFC,0xCE3E); + &data_short(0x9180,0x9042,0x9204,0x93C6,0x9688,0x974A,0x950C,0x94CE); + &data_short(0x9F90,0x9E52,0x9C14,0x9DD6,0x9898,0x995A,0x9B1C,0x9ADE); + &data_short(0x8DA0,0x8C62,0x8E24,0x8FE6,0x8AA8,0x8B6A,0x892C,0x88EE); + &data_short(0x83B0,0x8272,0x8034,0x81F6,0x84B8,0x857A,0x873C,0x86FE); + &data_short(0xA9C0,0xA802,0xAA44,0xAB86,0xAEC8,0xAF0A,0xAD4C,0xAC8E); + &data_short(0xA7D0,0xA612,0xA454,0xA596,0xA0D8,0xA11A,0xA35C,0xA29E); + &data_short(0xB5E0,0xB422,0xB664,0xB7A6,0xB2E8,0xB32A,0xB16C,0xB0AE); + &data_short(0xBBF0,0xBA32,0xB874,0xB9B6,0xBCF8,0xBD3A,0xBF7C,0xBEBE); +}}} # !$x86only + +&asciz("GHASH for x86, CRYPTOGAMS by "); +&asm_finish(); + +# A question was risen about choice of vanilla MMX. Or rather why wasn't +# SSE2 chosen instead? In addition to the fact that MMX runs on legacy +# CPUs such as PIII, "4-bit" MMX version was observed to provide better +# performance than *corresponding* SSE2 one even on contemporary CPUs. +# SSE2 results were provided by Peter-Michael Hager. He maintains SSE2 +# implementation featuring full range of lookup-table sizes, but with +# per-invocation lookup table setup. Latter means that table size is +# chosen depending on how much data is to be hashed in every given call, +# more data - larger table. Best reported result for Core2 is ~4 cycles +# per processed byte out of 64KB block. This number accounts even for +# 64KB table setup overhead. As discussed in gcm128.c we choose to be +# more conservative in respect to lookup table sizes, but how do the +# results compare? Minimalistic "256B" MMX version delivers ~11 cycles +# on same platform. As also discussed in gcm128.c, next in line "8-bit +# Shoup's" or "4KB" method should deliver twice the performance of +# "256B" one, in other words not worse than ~6 cycles per byte. It +# should be also be noted that in SSE2 case improvement can be "super- +# linear," i.e. more than twice, mostly because >>8 maps to single +# instruction on SSE2 register. This is unlike "4-bit" case when >>4 +# maps to same amount of instructions in both MMX and SSE2 cases. +# Bottom line is that switch to SSE2 is considered to be justifiable +# only in case we choose to implement "8-bit" method... diff --git a/libs/openssl/crypto/modes/asm/ghash-x86_64.pl b/libs/openssl/crypto/modes/asm/ghash-x86_64.pl new file mode 100644 index 00000000..38d779ed --- /dev/null +++ b/libs/openssl/crypto/modes/asm/ghash-x86_64.pl @@ -0,0 +1,806 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# March, June 2010 +# +# The module implements "4-bit" GCM GHASH function and underlying +# single multiplication operation in GF(2^128). "4-bit" means that +# it uses 256 bytes per-key table [+128 bytes shared table]. GHASH +# function features so called "528B" variant utilizing additional +# 256+16 bytes of per-key storage [+512 bytes shared table]. +# Performance results are for this streamed GHASH subroutine and are +# expressed in cycles per processed byte, less is better: +# +# gcc 3.4.x(*) assembler +# +# P4 28.6 14.0 +100% +# Opteron 19.3 7.7 +150% +# Core2 17.8 8.1(**) +120% +# +# (*) comparison is not completely fair, because C results are +# for vanilla "256B" implementation, while assembler results +# are for "528B";-) +# (**) it's mystery [to me] why Core2 result is not same as for +# Opteron; + +# May 2010 +# +# Add PCLMULQDQ version performing at 2.02 cycles per processed byte. +# See ghash-x86.pl for background information and details about coding +# techniques. +# +# Special thanks to David Woodhouse for +# providing access to a Westmere-based system on behalf of Intel +# Open Source Technology Centre. + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +# common register layout +$nlo="%rax"; +$nhi="%rbx"; +$Zlo="%r8"; +$Zhi="%r9"; +$tmp="%r10"; +$rem_4bit = "%r11"; + +$Xi="%rdi"; +$Htbl="%rsi"; + +# per-function register layout +$cnt="%rcx"; +$rem="%rdx"; + +sub LB() { my $r=shift; $r =~ s/%[er]([a-d])x/%\1l/ or + $r =~ s/%[er]([sd]i)/%\1l/ or + $r =~ s/%[er](bp)/%\1l/ or + $r =~ s/%(r[0-9]+)[d]?/%\1b/; $r; } + +sub AUTOLOAD() # thunk [simplified] 32-bit style perlasm +{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; + my $arg = pop; + $arg = "\$$arg" if ($arg*1 eq $arg); + $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n"; +} + +{ my $N; + sub loop() { + my $inp = shift; + + $N++; +$code.=<<___; + xor $nlo,$nlo + xor $nhi,$nhi + mov `&LB("$Zlo")`,`&LB("$nlo")` + mov `&LB("$Zlo")`,`&LB("$nhi")` + shl \$4,`&LB("$nlo")` + mov \$14,$cnt + mov 8($Htbl,$nlo),$Zlo + mov ($Htbl,$nlo),$Zhi + and \$0xf0,`&LB("$nhi")` + mov $Zlo,$rem + jmp .Loop$N + +.align 16 +.Loop$N: + shr \$4,$Zlo + and \$0xf,$rem + mov $Zhi,$tmp + mov ($inp,$cnt),`&LB("$nlo")` + shr \$4,$Zhi + xor 8($Htbl,$nhi),$Zlo + shl \$60,$tmp + xor ($Htbl,$nhi),$Zhi + mov `&LB("$nlo")`,`&LB("$nhi")` + xor ($rem_4bit,$rem,8),$Zhi + mov $Zlo,$rem + shl \$4,`&LB("$nlo")` + xor $tmp,$Zlo + dec $cnt + js .Lbreak$N + + shr \$4,$Zlo + and \$0xf,$rem + mov $Zhi,$tmp + shr \$4,$Zhi + xor 8($Htbl,$nlo),$Zlo + shl \$60,$tmp + xor ($Htbl,$nlo),$Zhi + and \$0xf0,`&LB("$nhi")` + xor ($rem_4bit,$rem,8),$Zhi + mov $Zlo,$rem + xor $tmp,$Zlo + jmp .Loop$N + +.align 16 +.Lbreak$N: + shr \$4,$Zlo + and \$0xf,$rem + mov $Zhi,$tmp + shr \$4,$Zhi + xor 8($Htbl,$nlo),$Zlo + shl \$60,$tmp + xor ($Htbl,$nlo),$Zhi + and \$0xf0,`&LB("$nhi")` + xor ($rem_4bit,$rem,8),$Zhi + mov $Zlo,$rem + xor $tmp,$Zlo + + shr \$4,$Zlo + and \$0xf,$rem + mov $Zhi,$tmp + shr \$4,$Zhi + xor 8($Htbl,$nhi),$Zlo + shl \$60,$tmp + xor ($Htbl,$nhi),$Zhi + xor $tmp,$Zlo + xor ($rem_4bit,$rem,8),$Zhi + + bswap $Zlo + bswap $Zhi +___ +}} + +$code=<<___; +.text + +.globl gcm_gmult_4bit +.type gcm_gmult_4bit,\@function,2 +.align 16 +gcm_gmult_4bit: + push %rbx + push %rbp # %rbp and %r12 are pushed exclusively in + push %r12 # order to reuse Win64 exception handler... +.Lgmult_prologue: + + movzb 15($Xi),$Zlo + lea .Lrem_4bit(%rip),$rem_4bit +___ + &loop ($Xi); +$code.=<<___; + mov $Zlo,8($Xi) + mov $Zhi,($Xi) + + mov 16(%rsp),%rbx + lea 24(%rsp),%rsp +.Lgmult_epilogue: + ret +.size gcm_gmult_4bit,.-gcm_gmult_4bit +___ + +# per-function register layout +$inp="%rdx"; +$len="%rcx"; +$rem_8bit=$rem_4bit; + +$code.=<<___; +.globl gcm_ghash_4bit +.type gcm_ghash_4bit,\@function,4 +.align 16 +gcm_ghash_4bit: + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + sub \$280,%rsp +.Lghash_prologue: + mov $inp,%r14 # reassign couple of args + mov $len,%r15 +___ +{ my $inp="%r14"; + my $dat="%edx"; + my $len="%r15"; + my @nhi=("%ebx","%ecx"); + my @rem=("%r12","%r13"); + my $Hshr4="%rbp"; + + &sub ($Htbl,-128); # size optimization + &lea ($Hshr4,"16+128(%rsp)"); + { my @lo =($nlo,$nhi); + my @hi =($Zlo,$Zhi); + + &xor ($dat,$dat); + for ($i=0,$j=-2;$i<18;$i++,$j++) { + &mov ("$j(%rsp)",&LB($dat)) if ($i>1); + &or ($lo[0],$tmp) if ($i>1); + &mov (&LB($dat),&LB($lo[1])) if ($i>0 && $i<17); + &shr ($lo[1],4) if ($i>0 && $i<17); + &mov ($tmp,$hi[1]) if ($i>0 && $i<17); + &shr ($hi[1],4) if ($i>0 && $i<17); + &mov ("8*$j($Hshr4)",$hi[0]) if ($i>1); + &mov ($hi[0],"16*$i+0-128($Htbl)") if ($i<16); + &shl (&LB($dat),4) if ($i>0 && $i<17); + &mov ("8*$j-128($Hshr4)",$lo[0]) if ($i>1); + &mov ($lo[0],"16*$i+8-128($Htbl)") if ($i<16); + &shl ($tmp,60) if ($i>0 && $i<17); + + push (@lo,shift(@lo)); + push (@hi,shift(@hi)); + } + } + &add ($Htbl,-128); + &mov ($Zlo,"8($Xi)"); + &mov ($Zhi,"0($Xi)"); + &add ($len,$inp); # pointer to the end of data + &lea ($rem_8bit,".Lrem_8bit(%rip)"); + &jmp (".Louter_loop"); + +$code.=".align 16\n.Louter_loop:\n"; + &xor ($Zhi,"($inp)"); + &mov ("%rdx","8($inp)"); + &lea ($inp,"16($inp)"); + &xor ("%rdx",$Zlo); + &mov ("($Xi)",$Zhi); + &mov ("8($Xi)","%rdx"); + &shr ("%rdx",32); + + &xor ($nlo,$nlo); + &rol ($dat,8); + &mov (&LB($nlo),&LB($dat)); + &movz ($nhi[0],&LB($dat)); + &shl (&LB($nlo),4); + &shr ($nhi[0],4); + + for ($j=11,$i=0;$i<15;$i++) { + &rol ($dat,8); + &xor ($Zlo,"8($Htbl,$nlo)") if ($i>0); + &xor ($Zhi,"($Htbl,$nlo)") if ($i>0); + &mov ($Zlo,"8($Htbl,$nlo)") if ($i==0); + &mov ($Zhi,"($Htbl,$nlo)") if ($i==0); + + &mov (&LB($nlo),&LB($dat)); + &xor ($Zlo,$tmp) if ($i>0); + &movzw ($rem[1],"($rem_8bit,$rem[1],2)") if ($i>0); + + &movz ($nhi[1],&LB($dat)); + &shl (&LB($nlo),4); + &movzb ($rem[0],"(%rsp,$nhi[0])"); + + &shr ($nhi[1],4) if ($i<14); + &and ($nhi[1],0xf0) if ($i==14); + &shl ($rem[1],48) if ($i>0); + &xor ($rem[0],$Zlo); + + &mov ($tmp,$Zhi); + &xor ($Zhi,$rem[1]) if ($i>0); + &shr ($Zlo,8); + + &movz ($rem[0],&LB($rem[0])); + &mov ($dat,"$j($Xi)") if (--$j%4==0); + &shr ($Zhi,8); + + &xor ($Zlo,"-128($Hshr4,$nhi[0],8)"); + &shl ($tmp,56); + &xor ($Zhi,"($Hshr4,$nhi[0],8)"); + + unshift (@nhi,pop(@nhi)); # "rotate" registers + unshift (@rem,pop(@rem)); + } + &movzw ($rem[1],"($rem_8bit,$rem[1],2)"); + &xor ($Zlo,"8($Htbl,$nlo)"); + &xor ($Zhi,"($Htbl,$nlo)"); + + &shl ($rem[1],48); + &xor ($Zlo,$tmp); + + &xor ($Zhi,$rem[1]); + &movz ($rem[0],&LB($Zlo)); + &shr ($Zlo,4); + + &mov ($tmp,$Zhi); + &shl (&LB($rem[0]),4); + &shr ($Zhi,4); + + &xor ($Zlo,"8($Htbl,$nhi[0])"); + &movzw ($rem[0],"($rem_8bit,$rem[0],2)"); + &shl ($tmp,60); + + &xor ($Zhi,"($Htbl,$nhi[0])"); + &xor ($Zlo,$tmp); + &shl ($rem[0],48); + + &bswap ($Zlo); + &xor ($Zhi,$rem[0]); + + &bswap ($Zhi); + &cmp ($inp,$len); + &jb (".Louter_loop"); +} +$code.=<<___; + mov $Zlo,8($Xi) + mov $Zhi,($Xi) + + lea 280(%rsp),%rsi + mov 0(%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 + mov 24(%rsi),%r12 + mov 32(%rsi),%rbp + mov 40(%rsi),%rbx + lea 48(%rsi),%rsp +.Lghash_epilogue: + ret +.size gcm_ghash_4bit,.-gcm_ghash_4bit +___ + +###################################################################### +# PCLMULQDQ version. + +@_4args=$win64? ("%rcx","%rdx","%r8", "%r9") : # Win64 order + ("%rdi","%rsi","%rdx","%rcx"); # Unix order + +($Xi,$Xhi)=("%xmm0","%xmm1"); $Hkey="%xmm2"; +($T1,$T2,$T3)=("%xmm3","%xmm4","%xmm5"); + +sub clmul64x64_T2 { # minimal register pressure +my ($Xhi,$Xi,$Hkey,$modulo)=@_; + +$code.=<<___ if (!defined($modulo)); + movdqa $Xi,$Xhi # + pshufd \$0b01001110,$Xi,$T1 + pshufd \$0b01001110,$Hkey,$T2 + pxor $Xi,$T1 # + pxor $Hkey,$T2 +___ +$code.=<<___; + pclmulqdq \$0x00,$Hkey,$Xi ####### + pclmulqdq \$0x11,$Hkey,$Xhi ####### + pclmulqdq \$0x00,$T2,$T1 ####### + pxor $Xi,$T1 # + pxor $Xhi,$T1 # + + movdqa $T1,$T2 # + psrldq \$8,$T1 + pslldq \$8,$T2 # + pxor $T1,$Xhi + pxor $T2,$Xi # +___ +} + +sub reduction_alg9 { # 17/13 times faster than Intel version +my ($Xhi,$Xi) = @_; + +$code.=<<___; + # 1st phase + movdqa $Xi,$T1 # + psllq \$1,$Xi + pxor $T1,$Xi # + psllq \$5,$Xi # + pxor $T1,$Xi # + psllq \$57,$Xi # + movdqa $Xi,$T2 # + pslldq \$8,$Xi + psrldq \$8,$T2 # + pxor $T1,$Xi + pxor $T2,$Xhi # + + # 2nd phase + movdqa $Xi,$T2 + psrlq \$5,$Xi + pxor $T2,$Xi # + psrlq \$1,$Xi # + pxor $T2,$Xi # + pxor $Xhi,$T2 + psrlq \$1,$Xi # + pxor $T2,$Xi # +___ +} + +{ my ($Htbl,$Xip)=@_4args; + +$code.=<<___; +.globl gcm_init_clmul +.type gcm_init_clmul,\@abi-omnipotent +.align 16 +gcm_init_clmul: + movdqu ($Xip),$Hkey + pshufd \$0b01001110,$Hkey,$Hkey # dword swap + + # <<1 twist + pshufd \$0b11111111,$Hkey,$T2 # broadcast uppermost dword + movdqa $Hkey,$T1 + psllq \$1,$Hkey + pxor $T3,$T3 # + psrlq \$63,$T1 + pcmpgtd $T2,$T3 # broadcast carry bit + pslldq \$8,$T1 + por $T1,$Hkey # H<<=1 + + # magic reduction + pand .L0x1c2_polynomial(%rip),$T3 + pxor $T3,$Hkey # if(carry) H^=0x1c2_polynomial + + # calculate H^2 + movdqa $Hkey,$Xi +___ + &clmul64x64_T2 ($Xhi,$Xi,$Hkey); + &reduction_alg9 ($Xhi,$Xi); +$code.=<<___; + movdqu $Hkey,($Htbl) # save H + movdqu $Xi,16($Htbl) # save H^2 + ret +.size gcm_init_clmul,.-gcm_init_clmul +___ +} + +{ my ($Xip,$Htbl)=@_4args; + +$code.=<<___; +.globl gcm_gmult_clmul +.type gcm_gmult_clmul,\@abi-omnipotent +.align 16 +gcm_gmult_clmul: + movdqu ($Xip),$Xi + movdqa .Lbswap_mask(%rip),$T3 + movdqu ($Htbl),$Hkey + pshufb $T3,$Xi +___ + &clmul64x64_T2 ($Xhi,$Xi,$Hkey); + &reduction_alg9 ($Xhi,$Xi); +$code.=<<___; + pshufb $T3,$Xi + movdqu $Xi,($Xip) + ret +.size gcm_gmult_clmul,.-gcm_gmult_clmul +___ +} + +{ my ($Xip,$Htbl,$inp,$len)=@_4args; + my $Xn="%xmm6"; + my $Xhn="%xmm7"; + my $Hkey2="%xmm8"; + my $T1n="%xmm9"; + my $T2n="%xmm10"; + +$code.=<<___; +.globl gcm_ghash_clmul +.type gcm_ghash_clmul,\@abi-omnipotent +.align 16 +gcm_ghash_clmul: +___ +$code.=<<___ if ($win64); +.LSEH_begin_gcm_ghash_clmul: + # I can't trust assembler to use specific encoding:-( + .byte 0x48,0x83,0xec,0x58 #sub \$0x58,%rsp + .byte 0x0f,0x29,0x34,0x24 #movaps %xmm6,(%rsp) + .byte 0x0f,0x29,0x7c,0x24,0x10 #movdqa %xmm7,0x10(%rsp) + .byte 0x44,0x0f,0x29,0x44,0x24,0x20 #movaps %xmm8,0x20(%rsp) + .byte 0x44,0x0f,0x29,0x4c,0x24,0x30 #movaps %xmm9,0x30(%rsp) + .byte 0x44,0x0f,0x29,0x54,0x24,0x40 #movaps %xmm10,0x40(%rsp) +___ +$code.=<<___; + movdqa .Lbswap_mask(%rip),$T3 + + movdqu ($Xip),$Xi + movdqu ($Htbl),$Hkey + pshufb $T3,$Xi + + sub \$0x10,$len + jz .Lodd_tail + + movdqu 16($Htbl),$Hkey2 + ####### + # Xi+2 =[H*(Ii+1 + Xi+1)] mod P = + # [(H*Ii+1) + (H*Xi+1)] mod P = + # [(H*Ii+1) + H^2*(Ii+Xi)] mod P + # + movdqu ($inp),$T1 # Ii + movdqu 16($inp),$Xn # Ii+1 + pshufb $T3,$T1 + pshufb $T3,$Xn + pxor $T1,$Xi # Ii+Xi +___ + &clmul64x64_T2 ($Xhn,$Xn,$Hkey); # H*Ii+1 +$code.=<<___; + movdqa $Xi,$Xhi # + pshufd \$0b01001110,$Xi,$T1 + pshufd \$0b01001110,$Hkey2,$T2 + pxor $Xi,$T1 # + pxor $Hkey2,$T2 + + lea 32($inp),$inp # i+=2 + sub \$0x20,$len + jbe .Leven_tail + +.Lmod_loop: +___ + &clmul64x64_T2 ($Xhi,$Xi,$Hkey2,1); # H^2*(Ii+Xi) +$code.=<<___; + movdqu ($inp),$T1 # Ii + pxor $Xn,$Xi # (H*Ii+1) + H^2*(Ii+Xi) + pxor $Xhn,$Xhi + + movdqu 16($inp),$Xn # Ii+1 + pshufb $T3,$T1 + pshufb $T3,$Xn + + movdqa $Xn,$Xhn # + pshufd \$0b01001110,$Xn,$T1n + pshufd \$0b01001110,$Hkey,$T2n + pxor $Xn,$T1n # + pxor $Hkey,$T2n + pxor $T1,$Xhi # "Ii+Xi", consume early + + movdqa $Xi,$T1 # 1st phase + psllq \$1,$Xi + pxor $T1,$Xi # + psllq \$5,$Xi # + pxor $T1,$Xi # + pclmulqdq \$0x00,$Hkey,$Xn ####### + psllq \$57,$Xi # + movdqa $Xi,$T2 # + pslldq \$8,$Xi + psrldq \$8,$T2 # + pxor $T1,$Xi + pxor $T2,$Xhi # + + pclmulqdq \$0x11,$Hkey,$Xhn ####### + movdqa $Xi,$T2 # 2nd phase + psrlq \$5,$Xi + pxor $T2,$Xi # + psrlq \$1,$Xi # + pxor $T2,$Xi # + pxor $Xhi,$T2 + psrlq \$1,$Xi # + pxor $T2,$Xi # + + pclmulqdq \$0x00,$T2n,$T1n ####### + movdqa $Xi,$Xhi # + pshufd \$0b01001110,$Xi,$T1 + pshufd \$0b01001110,$Hkey2,$T2 + pxor $Xi,$T1 # + pxor $Hkey2,$T2 + + pxor $Xn,$T1n # + pxor $Xhn,$T1n # + movdqa $T1n,$T2n # + psrldq \$8,$T1n + pslldq \$8,$T2n # + pxor $T1n,$Xhn + pxor $T2n,$Xn # + + lea 32($inp),$inp + sub \$0x20,$len + ja .Lmod_loop + +.Leven_tail: +___ + &clmul64x64_T2 ($Xhi,$Xi,$Hkey2,1); # H^2*(Ii+Xi) +$code.=<<___; + pxor $Xn,$Xi # (H*Ii+1) + H^2*(Ii+Xi) + pxor $Xhn,$Xhi +___ + &reduction_alg9 ($Xhi,$Xi); +$code.=<<___; + test $len,$len + jnz .Ldone + +.Lodd_tail: + movdqu ($inp),$T1 # Ii + pshufb $T3,$T1 + pxor $T1,$Xi # Ii+Xi +___ + &clmul64x64_T2 ($Xhi,$Xi,$Hkey); # H*(Ii+Xi) + &reduction_alg9 ($Xhi,$Xi); +$code.=<<___; +.Ldone: + pshufb $T3,$Xi + movdqu $Xi,($Xip) +___ +$code.=<<___ if ($win64); + movaps (%rsp),%xmm6 + movaps 0x10(%rsp),%xmm7 + movaps 0x20(%rsp),%xmm8 + movaps 0x30(%rsp),%xmm9 + movaps 0x40(%rsp),%xmm10 + add \$0x58,%rsp +___ +$code.=<<___; + ret +.LSEH_end_gcm_ghash_clmul: +.size gcm_ghash_clmul,.-gcm_ghash_clmul +___ +} + +$code.=<<___; +.align 64 +.Lbswap_mask: + .byte 15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0 +.L0x1c2_polynomial: + .byte 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0xc2 +.align 64 +.type .Lrem_4bit,\@object +.Lrem_4bit: + .long 0,`0x0000<<16`,0,`0x1C20<<16`,0,`0x3840<<16`,0,`0x2460<<16` + .long 0,`0x7080<<16`,0,`0x6CA0<<16`,0,`0x48C0<<16`,0,`0x54E0<<16` + .long 0,`0xE100<<16`,0,`0xFD20<<16`,0,`0xD940<<16`,0,`0xC560<<16` + .long 0,`0x9180<<16`,0,`0x8DA0<<16`,0,`0xA9C0<<16`,0,`0xB5E0<<16` +.type .Lrem_8bit,\@object +.Lrem_8bit: + .value 0x0000,0x01C2,0x0384,0x0246,0x0708,0x06CA,0x048C,0x054E + .value 0x0E10,0x0FD2,0x0D94,0x0C56,0x0918,0x08DA,0x0A9C,0x0B5E + .value 0x1C20,0x1DE2,0x1FA4,0x1E66,0x1B28,0x1AEA,0x18AC,0x196E + .value 0x1230,0x13F2,0x11B4,0x1076,0x1538,0x14FA,0x16BC,0x177E + .value 0x3840,0x3982,0x3BC4,0x3A06,0x3F48,0x3E8A,0x3CCC,0x3D0E + .value 0x3650,0x3792,0x35D4,0x3416,0x3158,0x309A,0x32DC,0x331E + .value 0x2460,0x25A2,0x27E4,0x2626,0x2368,0x22AA,0x20EC,0x212E + .value 0x2A70,0x2BB2,0x29F4,0x2836,0x2D78,0x2CBA,0x2EFC,0x2F3E + .value 0x7080,0x7142,0x7304,0x72C6,0x7788,0x764A,0x740C,0x75CE + .value 0x7E90,0x7F52,0x7D14,0x7CD6,0x7998,0x785A,0x7A1C,0x7BDE + .value 0x6CA0,0x6D62,0x6F24,0x6EE6,0x6BA8,0x6A6A,0x682C,0x69EE + .value 0x62B0,0x6372,0x6134,0x60F6,0x65B8,0x647A,0x663C,0x67FE + .value 0x48C0,0x4902,0x4B44,0x4A86,0x4FC8,0x4E0A,0x4C4C,0x4D8E + .value 0x46D0,0x4712,0x4554,0x4496,0x41D8,0x401A,0x425C,0x439E + .value 0x54E0,0x5522,0x5764,0x56A6,0x53E8,0x522A,0x506C,0x51AE + .value 0x5AF0,0x5B32,0x5974,0x58B6,0x5DF8,0x5C3A,0x5E7C,0x5FBE + .value 0xE100,0xE0C2,0xE284,0xE346,0xE608,0xE7CA,0xE58C,0xE44E + .value 0xEF10,0xEED2,0xEC94,0xED56,0xE818,0xE9DA,0xEB9C,0xEA5E + .value 0xFD20,0xFCE2,0xFEA4,0xFF66,0xFA28,0xFBEA,0xF9AC,0xF86E + .value 0xF330,0xF2F2,0xF0B4,0xF176,0xF438,0xF5FA,0xF7BC,0xF67E + .value 0xD940,0xD882,0xDAC4,0xDB06,0xDE48,0xDF8A,0xDDCC,0xDC0E + .value 0xD750,0xD692,0xD4D4,0xD516,0xD058,0xD19A,0xD3DC,0xD21E + .value 0xC560,0xC4A2,0xC6E4,0xC726,0xC268,0xC3AA,0xC1EC,0xC02E + .value 0xCB70,0xCAB2,0xC8F4,0xC936,0xCC78,0xCDBA,0xCFFC,0xCE3E + .value 0x9180,0x9042,0x9204,0x93C6,0x9688,0x974A,0x950C,0x94CE + .value 0x9F90,0x9E52,0x9C14,0x9DD6,0x9898,0x995A,0x9B1C,0x9ADE + .value 0x8DA0,0x8C62,0x8E24,0x8FE6,0x8AA8,0x8B6A,0x892C,0x88EE + .value 0x83B0,0x8272,0x8034,0x81F6,0x84B8,0x857A,0x873C,0x86FE + .value 0xA9C0,0xA802,0xAA44,0xAB86,0xAEC8,0xAF0A,0xAD4C,0xAC8E + .value 0xA7D0,0xA612,0xA454,0xA596,0xA0D8,0xA11A,0xA35C,0xA29E + .value 0xB5E0,0xB422,0xB664,0xB7A6,0xB2E8,0xB32A,0xB16C,0xB0AE + .value 0xBBF0,0xBA32,0xB874,0xB9B6,0xBCF8,0xBD3A,0xBF7C,0xBEBE + +.asciz "GHASH for x86_64, CRYPTOGAMS by " +.align 64 +___ + +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type se_handler,\@abi-omnipotent +.align 16 +se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + mov 8($disp),%rsi # disp->ImageBase + mov 56($disp),%r11 # disp->HandlerData + + mov 0(%r11),%r10d # HandlerData[0] + lea (%rsi,%r10),%r10 # prologue label + cmp %r10,%rbx # context->RipRsp + + mov 4(%r11),%r10d # HandlerData[1] + lea (%rsi,%r10),%r10 # epilogue label + cmp %r10,%rbx # context->Rip>=epilogue label + jae .Lin_prologue + + lea 24(%rax),%rax # adjust "rsp" + + mov -8(%rax),%rbx + mov -16(%rax),%rbp + mov -24(%rax),%r12 + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + +.Lin_prologue: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$`1232/8`,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size se_handler,.-se_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_gcm_gmult_4bit + .rva .LSEH_end_gcm_gmult_4bit + .rva .LSEH_info_gcm_gmult_4bit + + .rva .LSEH_begin_gcm_ghash_4bit + .rva .LSEH_end_gcm_ghash_4bit + .rva .LSEH_info_gcm_ghash_4bit + + .rva .LSEH_begin_gcm_ghash_clmul + .rva .LSEH_end_gcm_ghash_clmul + .rva .LSEH_info_gcm_ghash_clmul + +.section .xdata +.align 8 +.LSEH_info_gcm_gmult_4bit: + .byte 9,0,0,0 + .rva se_handler + .rva .Lgmult_prologue,.Lgmult_epilogue # HandlerData +.LSEH_info_gcm_ghash_4bit: + .byte 9,0,0,0 + .rva se_handler + .rva .Lghash_prologue,.Lghash_epilogue # HandlerData +.LSEH_info_gcm_ghash_clmul: + .byte 0x01,0x1f,0x0b,0x00 + .byte 0x1f,0xa8,0x04,0x00 #movaps 0x40(rsp),xmm10 + .byte 0x19,0x98,0x03,0x00 #movaps 0x30(rsp),xmm9 + .byte 0x13,0x88,0x02,0x00 #movaps 0x20(rsp),xmm8 + .byte 0x0d,0x78,0x01,0x00 #movaps 0x10(rsp),xmm7 + .byte 0x08,0x68,0x00,0x00 #movaps (rsp),xmm6 + .byte 0x04,0xa2,0x00,0x00 #sub rsp,0x58 +___ +} + +$code =~ s/\`([^\`]*)\`/eval($1)/gem; + +print $code; + +close STDOUT; diff --git a/libs/openssl/crypto/modes/cbc128.c b/libs/openssl/crypto/modes/cbc128.c new file mode 100644 index 00000000..1ed79672 --- /dev/null +++ b/libs/openssl/crypto/modes/cbc128.c @@ -0,0 +1,207 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +#ifndef STRICT_ALIGNMENT +# define STRICT_ALIGNMENT 0 +#endif + +void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block) +{ + size_t n; + const unsigned char *iv = ivec; + + assert(in && out && key && ivec); + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (STRICT_ALIGNMENT && + ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { + while (len >= 16) { + for (n = 0; n < 16; ++n) + out[n] = in[n] ^ iv[n]; + (*block) (out, out, key); + iv = out; + len -= 16; + in += 16; + out += 16; + } + } else { + while (len >= 16) { + for (n = 0; n < 16; n += sizeof(size_t)) + *(size_t *)(out + n) = + *(size_t *)(in + n) ^ *(size_t *)(iv + n); + (*block) (out, out, key); + iv = out; + len -= 16; + in += 16; + out += 16; + } + } +#endif + while (len) { + for (n = 0; n < 16 && n < len; ++n) + out[n] = in[n] ^ iv[n]; + for (; n < 16; ++n) + out[n] = iv[n]; + (*block) (out, out, key); + iv = out; + if (len <= 16) + break; + len -= 16; + in += 16; + out += 16; + } + memcpy(ivec, iv, 16); +} + +void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block) +{ + size_t n; + union { + size_t t[16 / sizeof(size_t)]; + unsigned char c[16]; + } tmp; + + assert(in && out && key && ivec); + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (in != out) { + const unsigned char *iv = ivec; + + if (STRICT_ALIGNMENT && + ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { + while (len >= 16) { + (*block) (in, out, key); + for (n = 0; n < 16; ++n) + out[n] ^= iv[n]; + iv = in; + len -= 16; + in += 16; + out += 16; + } + } else if (16 % sizeof(size_t) == 0) { /* always true */ + while (len >= 16) { + size_t *out_t = (size_t *)out, *iv_t = (size_t *)iv; + + (*block) (in, out, key); + for (n = 0; n < 16 / sizeof(size_t); n++) + out_t[n] ^= iv_t[n]; + iv = in; + len -= 16; + in += 16; + out += 16; + } + } + memcpy(ivec, iv, 16); + } else { + if (STRICT_ALIGNMENT && + ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != 0) { + unsigned char c; + while (len >= 16) { + (*block) (in, tmp.c, key); + for (n = 0; n < 16; ++n) { + c = in[n]; + out[n] = tmp.c[n] ^ ivec[n]; + ivec[n] = c; + } + len -= 16; + in += 16; + out += 16; + } + } else if (16 % sizeof(size_t) == 0) { /* always true */ + while (len >= 16) { + size_t c, *out_t = (size_t *)out, *ivec_t = (size_t *)ivec; + const size_t *in_t = (const size_t *)in; + + (*block) (in, tmp.c, key); + for (n = 0; n < 16 / sizeof(size_t); n++) { + c = in_t[n]; + out_t[n] = tmp.t[n] ^ ivec_t[n]; + ivec_t[n] = c; + } + len -= 16; + in += 16; + out += 16; + } + } + } +#endif + while (len) { + unsigned char c; + (*block) (in, tmp.c, key); + for (n = 0; n < 16 && n < len; ++n) { + c = in[n]; + out[n] = tmp.c[n] ^ ivec[n]; + ivec[n] = c; + } + if (len <= 16) { + for (; n < 16; ++n) + ivec[n] = in[n]; + break; + } + len -= 16; + in += 16; + out += 16; + } +} diff --git a/libs/openssl/crypto/modes/ccm128.c b/libs/openssl/crypto/modes/ccm128.c new file mode 100644 index 00000000..c1ded0f9 --- /dev/null +++ b/libs/openssl/crypto/modes/ccm128.c @@ -0,0 +1,479 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +/* + * First you setup M and L parameters and pass the key schedule. This is + * called once per session setup... + */ +void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, + unsigned int M, unsigned int L, void *key, + block128_f block) +{ + memset(ctx->nonce.c, 0, sizeof(ctx->nonce.c)); + ctx->nonce.c[0] = ((u8)(L - 1) & 7) | (u8)(((M - 2) / 2) & 7) << 3; + ctx->blocks = 0; + ctx->block = block; + ctx->key = key; +} + +/* !!! Following interfaces are to be called *once* per packet !!! */ + +/* Then you setup per-message nonce and pass the length of the message */ +int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, + const unsigned char *nonce, size_t nlen, size_t mlen) +{ + unsigned int L = ctx->nonce.c[0] & 7; /* the L parameter */ + + if (nlen < (14 - L)) + return -1; /* nonce is too short */ + + if (sizeof(mlen) == 8 && L >= 3) { + ctx->nonce.c[8] = (u8)(mlen >> (56 % (sizeof(mlen) * 8))); + ctx->nonce.c[9] = (u8)(mlen >> (48 % (sizeof(mlen) * 8))); + ctx->nonce.c[10] = (u8)(mlen >> (40 % (sizeof(mlen) * 8))); + ctx->nonce.c[11] = (u8)(mlen >> (32 % (sizeof(mlen) * 8))); + } else + ctx->nonce.u[1] = 0; + + ctx->nonce.c[12] = (u8)(mlen >> 24); + ctx->nonce.c[13] = (u8)(mlen >> 16); + ctx->nonce.c[14] = (u8)(mlen >> 8); + ctx->nonce.c[15] = (u8)mlen; + + ctx->nonce.c[0] &= ~0x40; /* clear Adata flag */ + memcpy(&ctx->nonce.c[1], nonce, 14 - L); + + return 0; +} + +/* Then you pass additional authentication data, this is optional */ +void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, + const unsigned char *aad, size_t alen) +{ + unsigned int i; + block128_f block = ctx->block; + + if (alen == 0) + return; + + ctx->nonce.c[0] |= 0x40; /* set Adata flag */ + (*block) (ctx->nonce.c, ctx->cmac.c, ctx->key), ctx->blocks++; + + if (alen < (0x10000 - 0x100)) { + ctx->cmac.c[0] ^= (u8)(alen >> 8); + ctx->cmac.c[1] ^= (u8)alen; + i = 2; + } else if (sizeof(alen) == 8 + && alen >= (size_t)1 << (32 % (sizeof(alen) * 8))) { + ctx->cmac.c[0] ^= 0xFF; + ctx->cmac.c[1] ^= 0xFF; + ctx->cmac.c[2] ^= (u8)(alen >> (56 % (sizeof(alen) * 8))); + ctx->cmac.c[3] ^= (u8)(alen >> (48 % (sizeof(alen) * 8))); + ctx->cmac.c[4] ^= (u8)(alen >> (40 % (sizeof(alen) * 8))); + ctx->cmac.c[5] ^= (u8)(alen >> (32 % (sizeof(alen) * 8))); + ctx->cmac.c[6] ^= (u8)(alen >> 24); + ctx->cmac.c[7] ^= (u8)(alen >> 16); + ctx->cmac.c[8] ^= (u8)(alen >> 8); + ctx->cmac.c[9] ^= (u8)alen; + i = 10; + } else { + ctx->cmac.c[0] ^= 0xFF; + ctx->cmac.c[1] ^= 0xFE; + ctx->cmac.c[2] ^= (u8)(alen >> 24); + ctx->cmac.c[3] ^= (u8)(alen >> 16); + ctx->cmac.c[4] ^= (u8)(alen >> 8); + ctx->cmac.c[5] ^= (u8)alen; + i = 6; + } + + do { + for (; i < 16 && alen; ++i, ++aad, --alen) + ctx->cmac.c[i] ^= *aad; + (*block) (ctx->cmac.c, ctx->cmac.c, ctx->key), ctx->blocks++; + i = 0; + } while (alen); +} + +/* Finally you encrypt or decrypt the message */ + +/* + * counter part of nonce may not be larger than L*8 bits, L is not larger + * than 8, therefore 64-bit counter... + */ +static void ctr64_inc(unsigned char *counter) +{ + unsigned int n = 8; + u8 c; + + counter += 8; + do { + --n; + c = counter[n]; + ++c; + counter[n] = c; + if (c) + return; + } while (n); +} + +int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, + size_t len) +{ + size_t n; + unsigned int i, L; + unsigned char flags0 = ctx->nonce.c[0]; + block128_f block = ctx->block; + void *key = ctx->key; + union { + u64 u[2]; + u8 c[16]; + } scratch; + + if (!(flags0 & 0x40)) + (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++; + + ctx->nonce.c[0] = L = flags0 & 7; + for (n = 0, i = 15 - L; i < 15; ++i) { + n |= ctx->nonce.c[i]; + ctx->nonce.c[i] = 0; + n <<= 8; + } + n |= ctx->nonce.c[15]; /* reconstructed length */ + ctx->nonce.c[15] = 1; + + if (n != len) + return -1; /* length mismatch */ + + ctx->blocks += ((len + 15) >> 3) | 1; + if (ctx->blocks > (U64(1) << 61)) + return -2; /* too much data */ + + while (len >= 16) { +#if defined(STRICT_ALIGNMENT) + union { + u64 u[2]; + u8 c[16]; + } temp; + + memcpy(temp.c, inp, 16); + ctx->cmac.u[0] ^= temp.u[0]; + ctx->cmac.u[1] ^= temp.u[1]; +#else + ctx->cmac.u[0] ^= ((u64 *)inp)[0]; + ctx->cmac.u[1] ^= ((u64 *)inp)[1]; +#endif + (*block) (ctx->cmac.c, ctx->cmac.c, key); + (*block) (ctx->nonce.c, scratch.c, key); + ctr64_inc(ctx->nonce.c); +#if defined(STRICT_ALIGNMENT) + temp.u[0] ^= scratch.u[0]; + temp.u[1] ^= scratch.u[1]; + memcpy(out, temp.c, 16); +#else + ((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]; + ((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]; +#endif + inp += 16; + out += 16; + len -= 16; + } + + if (len) { + for (i = 0; i < len; ++i) + ctx->cmac.c[i] ^= inp[i]; + (*block) (ctx->cmac.c, ctx->cmac.c, key); + (*block) (ctx->nonce.c, scratch.c, key); + for (i = 0; i < len; ++i) + out[i] = scratch.c[i] ^ inp[i]; + } + + for (i = 15 - L; i < 16; ++i) + ctx->nonce.c[i] = 0; + + (*block) (ctx->nonce.c, scratch.c, key); + ctx->cmac.u[0] ^= scratch.u[0]; + ctx->cmac.u[1] ^= scratch.u[1]; + + ctx->nonce.c[0] = flags0; + + return 0; +} + +int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, + size_t len) +{ + size_t n; + unsigned int i, L; + unsigned char flags0 = ctx->nonce.c[0]; + block128_f block = ctx->block; + void *key = ctx->key; + union { + u64 u[2]; + u8 c[16]; + } scratch; + + if (!(flags0 & 0x40)) + (*block) (ctx->nonce.c, ctx->cmac.c, key); + + ctx->nonce.c[0] = L = flags0 & 7; + for (n = 0, i = 15 - L; i < 15; ++i) { + n |= ctx->nonce.c[i]; + ctx->nonce.c[i] = 0; + n <<= 8; + } + n |= ctx->nonce.c[15]; /* reconstructed length */ + ctx->nonce.c[15] = 1; + + if (n != len) + return -1; + + while (len >= 16) { +#if defined(STRICT_ALIGNMENT) + union { + u64 u[2]; + u8 c[16]; + } temp; +#endif + (*block) (ctx->nonce.c, scratch.c, key); + ctr64_inc(ctx->nonce.c); +#if defined(STRICT_ALIGNMENT) + memcpy(temp.c, inp, 16); + ctx->cmac.u[0] ^= (scratch.u[0] ^= temp.u[0]); + ctx->cmac.u[1] ^= (scratch.u[1] ^= temp.u[1]); + memcpy(out, scratch.c, 16); +#else + ctx->cmac.u[0] ^= (((u64 *)out)[0] = scratch.u[0] ^ ((u64 *)inp)[0]); + ctx->cmac.u[1] ^= (((u64 *)out)[1] = scratch.u[1] ^ ((u64 *)inp)[1]); +#endif + (*block) (ctx->cmac.c, ctx->cmac.c, key); + + inp += 16; + out += 16; + len -= 16; + } + + if (len) { + (*block) (ctx->nonce.c, scratch.c, key); + for (i = 0; i < len; ++i) + ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]); + (*block) (ctx->cmac.c, ctx->cmac.c, key); + } + + for (i = 15 - L; i < 16; ++i) + ctx->nonce.c[i] = 0; + + (*block) (ctx->nonce.c, scratch.c, key); + ctx->cmac.u[0] ^= scratch.u[0]; + ctx->cmac.u[1] ^= scratch.u[1]; + + ctx->nonce.c[0] = flags0; + + return 0; +} + +static void ctr64_add(unsigned char *counter, size_t inc) +{ + size_t n = 8, val = 0; + + counter += 8; + do { + --n; + val += counter[n] + (inc & 0xff); + counter[n] = (unsigned char)val; + val >>= 8; /* carry bit */ + inc >>= 8; + } while (n && (inc || val)); +} + +int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, + size_t len, ccm128_f stream) +{ + size_t n; + unsigned int i, L; + unsigned char flags0 = ctx->nonce.c[0]; + block128_f block = ctx->block; + void *key = ctx->key; + union { + u64 u[2]; + u8 c[16]; + } scratch; + + if (!(flags0 & 0x40)) + (*block) (ctx->nonce.c, ctx->cmac.c, key), ctx->blocks++; + + ctx->nonce.c[0] = L = flags0 & 7; + for (n = 0, i = 15 - L; i < 15; ++i) { + n |= ctx->nonce.c[i]; + ctx->nonce.c[i] = 0; + n <<= 8; + } + n |= ctx->nonce.c[15]; /* reconstructed length */ + ctx->nonce.c[15] = 1; + + if (n != len) + return -1; /* length mismatch */ + + ctx->blocks += ((len + 15) >> 3) | 1; + if (ctx->blocks > (U64(1) << 61)) + return -2; /* too much data */ + + if ((n = len / 16)) { + (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c); + n *= 16; + inp += n; + out += n; + len -= n; + if (len) + ctr64_add(ctx->nonce.c, n / 16); + } + + if (len) { + for (i = 0; i < len; ++i) + ctx->cmac.c[i] ^= inp[i]; + (*block) (ctx->cmac.c, ctx->cmac.c, key); + (*block) (ctx->nonce.c, scratch.c, key); + for (i = 0; i < len; ++i) + out[i] = scratch.c[i] ^ inp[i]; + } + + for (i = 15 - L; i < 16; ++i) + ctx->nonce.c[i] = 0; + + (*block) (ctx->nonce.c, scratch.c, key); + ctx->cmac.u[0] ^= scratch.u[0]; + ctx->cmac.u[1] ^= scratch.u[1]; + + ctx->nonce.c[0] = flags0; + + return 0; +} + +int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, + const unsigned char *inp, unsigned char *out, + size_t len, ccm128_f stream) +{ + size_t n; + unsigned int i, L; + unsigned char flags0 = ctx->nonce.c[0]; + block128_f block = ctx->block; + void *key = ctx->key; + union { + u64 u[2]; + u8 c[16]; + } scratch; + + if (!(flags0 & 0x40)) + (*block) (ctx->nonce.c, ctx->cmac.c, key); + + ctx->nonce.c[0] = L = flags0 & 7; + for (n = 0, i = 15 - L; i < 15; ++i) { + n |= ctx->nonce.c[i]; + ctx->nonce.c[i] = 0; + n <<= 8; + } + n |= ctx->nonce.c[15]; /* reconstructed length */ + ctx->nonce.c[15] = 1; + + if (n != len) + return -1; + + if ((n = len / 16)) { + (*stream) (inp, out, n, key, ctx->nonce.c, ctx->cmac.c); + n *= 16; + inp += n; + out += n; + len -= n; + if (len) + ctr64_add(ctx->nonce.c, n / 16); + } + + if (len) { + (*block) (ctx->nonce.c, scratch.c, key); + for (i = 0; i < len; ++i) + ctx->cmac.c[i] ^= (out[i] = scratch.c[i] ^ inp[i]); + (*block) (ctx->cmac.c, ctx->cmac.c, key); + } + + for (i = 15 - L; i < 16; ++i) + ctx->nonce.c[i] = 0; + + (*block) (ctx->nonce.c, scratch.c, key); + ctx->cmac.u[0] ^= scratch.u[0]; + ctx->cmac.u[1] ^= scratch.u[1]; + + ctx->nonce.c[0] = flags0; + + return 0; +} + +size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len) +{ + unsigned int M = (ctx->nonce.c[0] >> 3) & 7; /* the M parameter */ + + M *= 2; + M += 2; + if (len < M) + return 0; + memcpy(tag, ctx->cmac.c, M); + return M; +} diff --git a/libs/openssl/crypto/modes/cfb128.c b/libs/openssl/crypto/modes/cfb128.c new file mode 100644 index 00000000..d4ecbd08 --- /dev/null +++ b/libs/openssl/crypto/modes/cfb128.c @@ -0,0 +1,254 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +/* + * The input and output encrypted as though 128bit cfb mode is being used. + * The extra state information to record how much of the 128bit block we have + * used is contained in *num; + */ +void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block) +{ + unsigned int n; + size_t l = 0; + + assert(in && out && key && ivec && num); + + n = *num; + + if (enc) { +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) { /* always true actually */ + do { + while (n && len) { + *(out++) = ivec[n] ^= *(in++); + --len; + n = (n + 1) % 16; + } +# if defined(STRICT_ALIGNMENT) + if (((size_t)in | (size_t)out | (size_t)ivec) % + sizeof(size_t) != 0) + break; +# endif + while (len >= 16) { + (*block) (ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) { + *(size_t *)(out + n) = + *(size_t *)(ivec + n) ^= *(size_t *)(in + n); + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block) (ivec, ivec, key); + while (len--) { + out[n] = ivec[n] ^= in[n]; + ++n; + } + } + *num = n; + return; + } while (0); + } + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l < len) { + if (n == 0) { + (*block) (ivec, ivec, key); + } + out[l] = ivec[n] ^= in[l]; + ++l; + n = (n + 1) % 16; + } + *num = n; + } else { +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) { /* always true actually */ + do { + while (n && len) { + unsigned char c; + *(out++) = ivec[n] ^ (c = *(in++)); + ivec[n] = c; + --len; + n = (n + 1) % 16; + } +# if defined(STRICT_ALIGNMENT) + if (((size_t)in | (size_t)out | (size_t)ivec) % + sizeof(size_t) != 0) + break; +# endif + while (len >= 16) { + (*block) (ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) { + size_t t = *(size_t *)(in + n); + *(size_t *)(out + n) = *(size_t *)(ivec + n) ^ t; + *(size_t *)(ivec + n) = t; + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block) (ivec, ivec, key); + while (len--) { + unsigned char c; + out[n] = ivec[n] ^ (c = in[n]); + ivec[n] = c; + ++n; + } + } + *num = n; + return; + } while (0); + } + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l < len) { + unsigned char c; + if (n == 0) { + (*block) (ivec, ivec, key); + } + out[l] = ivec[n] ^ (c = in[l]); + ivec[n] = c; + ++l; + n = (n + 1) % 16; + } + *num = n; + } +} + +/* + * This expects a single block of size nbits for both in and out. Note that + * it corrupts any extra bits in the last byte of out + */ +static void cfbr_encrypt_block(const unsigned char *in, unsigned char *out, + int nbits, const void *key, + unsigned char ivec[16], int enc, + block128_f block) +{ + int n, rem, num; + unsigned char ovec[16 * 2 + 1]; /* +1 because we dererefence (but don't + * use) one byte off the end */ + + if (nbits <= 0 || nbits > 128) + return; + + /* fill in the first half of the new IV with the current IV */ + memcpy(ovec, ivec, 16); + /* construct the new IV */ + (*block) (ivec, ivec, key); + num = (nbits + 7) / 8; + if (enc) /* encrypt the input */ + for (n = 0; n < num; ++n) + out[n] = (ovec[16 + n] = in[n] ^ ivec[n]); + else /* decrypt the input */ + for (n = 0; n < num; ++n) + out[n] = (ovec[16 + n] = in[n]) ^ ivec[n]; + /* shift ovec left... */ + rem = nbits % 8; + num = nbits / 8; + if (rem == 0) + memcpy(ivec, ovec + num, 16); + else + for (n = 0; n < 16; ++n) + ivec[n] = ovec[n + num] << rem | ovec[n + num + 1] >> (8 - rem); + + /* it is not necessary to cleanse ovec, since the IV is not secret */ +} + +/* N.B. This expects the input to be packed, MS bit first */ +void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, + size_t bits, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block) +{ + size_t n; + unsigned char c[1], d[1]; + + assert(in && out && key && ivec && num); + assert(*num == 0); + + for (n = 0; n < bits; ++n) { + c[0] = (in[n / 8] & (1 << (7 - n % 8))) ? 0x80 : 0; + cfbr_encrypt_block(c, d, 1, key, ivec, enc, block); + out[n / 8] = (out[n / 8] & ~(1 << (unsigned int)(7 - n % 8))) | + ((d[0] & 0x80) >> (unsigned int)(n % 8)); + } +} + +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block) +{ + size_t n; + + assert(in && out && key && ivec && num); + assert(*num == 0); + + for (n = 0; n < length; ++n) + cfbr_encrypt_block(&in[n], &out[n], 8, key, ivec, enc, block); +} diff --git a/libs/openssl/crypto/modes/ctr128.c b/libs/openssl/crypto/modes/ctr128.c new file mode 100644 index 00000000..bcafd6b6 --- /dev/null +++ b/libs/openssl/crypto/modes/ctr128.c @@ -0,0 +1,263 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +/* + * NOTE: the IV/counter CTR mode is big-endian. The code itself is + * endian-neutral. + */ + +/* increment counter (128-bit int) by 1 */ +static void ctr128_inc(unsigned char *counter) +{ + u32 n = 16, c = 1; + + do { + --n; + c += counter[n]; + counter[n] = (u8)c; + c >>= 8; + } while (n); +} + +#if !defined(OPENSSL_SMALL_FOOTPRINT) +static void ctr128_inc_aligned(unsigned char *counter) +{ + size_t *data, c, d, n; + const union { + long one; + char little; + } is_endian = { + 1 + }; + + if (is_endian.little || ((size_t)counter % sizeof(size_t)) != 0) { + ctr128_inc(counter); + return; + } + + data = (size_t *)counter; + c = 1; + n = 16 / sizeof(size_t); + do { + --n; + d = data[n] += c; + /* did addition carry? */ + c = ((d - c) ^ d) >> (sizeof(size_t) * 8 - 1); + } while (n); +} +#endif + +/* + * The input encrypted as though 128bit counter mode is being used. The + * extra state information to record how much of the 128bit block we have + * used is contained in *num, and the encrypted counter is kept in + * ecount_buf. Both *num and ecount_buf must be initialised with zeros + * before the first call to CRYPTO_ctr128_encrypt(). This algorithm assumes + * that the counter is in the x lower bits of the IV (ivec), and that the + * application has full control over overflow and the rest of the IV. This + * implementation takes NO responsability for checking that the counter + * doesn't overflow into the rest of the IV when incremented. + */ +void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], unsigned int *num, + block128_f block) +{ + unsigned int n; + size_t l = 0; + + assert(in && out && key && ecount_buf && num); + assert(*num < 16); + + n = *num; + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) { /* always true actually */ + do { + while (n && len) { + *(out++) = *(in++) ^ ecount_buf[n]; + --len; + n = (n + 1) % 16; + } + +# if defined(STRICT_ALIGNMENT) + if (((size_t)in | (size_t)out | (size_t)ecount_buf) + % sizeof(size_t) != 0) + break; +# endif + while (len >= 16) { + (*block) (ivec, ecount_buf, key); + ctr128_inc_aligned(ivec); + for (n = 0; n < 16; n += sizeof(size_t)) + *(size_t *)(out + n) = + *(size_t *)(in + n) ^ *(size_t *)(ecount_buf + n); + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block) (ivec, ecount_buf, key); + ctr128_inc_aligned(ivec); + while (len--) { + out[n] = in[n] ^ ecount_buf[n]; + ++n; + } + } + *num = n; + return; + } while (0); + } + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l < len) { + if (n == 0) { + (*block) (ivec, ecount_buf, key); + ctr128_inc(ivec); + } + out[l] = in[l] ^ ecount_buf[n]; + ++l; + n = (n + 1) % 16; + } + + *num = n; +} + +/* increment upper 96 bits of 128-bit counter by 1 */ +static void ctr96_inc(unsigned char *counter) +{ + u32 n = 12, c = 1; + + do { + --n; + c += counter[n]; + counter[n] = (u8)c; + c >>= 8; + } while (n); +} + +void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], + unsigned int *num, ctr128_f func) +{ + unsigned int n, ctr32; + + assert(in && out && key && ecount_buf && num); + assert(*num < 16); + + n = *num; + + while (n && len) { + *(out++) = *(in++) ^ ecount_buf[n]; + --len; + n = (n + 1) % 16; + } + + ctr32 = GETU32(ivec + 12); + while (len >= 16) { + size_t blocks = len / 16; + /* + * 1<<28 is just a not-so-small yet not-so-large number... + * Below condition is practically never met, but it has to + * be checked for code correctness. + */ + if (sizeof(size_t) > sizeof(unsigned int) && blocks > (1U << 28)) + blocks = (1U << 28); + /* + * As (*func) operates on 32-bit counter, caller + * has to handle overflow. 'if' below detects the + * overflow, which is then handled by limiting the + * amount of blocks to the exact overflow point... + */ + ctr32 += (u32)blocks; + if (ctr32 < blocks) { + blocks -= ctr32; + ctr32 = 0; + } + (*func) (in, out, blocks, key, ivec); + /* (*ctr) does not update ivec, caller does: */ + PUTU32(ivec + 12, ctr32); + /* ... overflow was detected, propogate carry. */ + if (ctr32 == 0) + ctr96_inc(ivec); + blocks *= 16; + len -= blocks; + out += blocks; + in += blocks; + } + if (len) { + memset(ecount_buf, 0, 16); + (*func) (ecount_buf, ecount_buf, 1, key, ivec); + ++ctr32; + PUTU32(ivec + 12, ctr32); + if (ctr32 == 0) + ctr96_inc(ivec); + while (len--) { + out[n] = in[n] ^ ecount_buf[n]; + ++n; + } + } + + *num = n; +} diff --git a/libs/openssl/crypto/modes/cts128.c b/libs/openssl/crypto/modes/cts128.c new file mode 100644 index 00000000..137be595 --- /dev/null +++ b/libs/openssl/crypto/modes/cts128.c @@ -0,0 +1,544 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Rights for redistribution and usage in source and binary + * forms are granted according to the OpenSSL license. + */ + +#include +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +/* + * Trouble with Ciphertext Stealing, CTS, mode is that there is no + * common official specification, but couple of cipher/application + * specific ones: RFC2040 and RFC3962. Then there is 'Proposal to + * Extend CBC Mode By "Ciphertext Stealing"' at NIST site, which + * deviates from mentioned RFCs. Most notably it allows input to be + * of block length and it doesn't flip the order of the last two + * blocks. CTS is being discussed even in ECB context, but it's not + * adopted for any known application. This implementation provides + * two interfaces: one compliant with above mentioned RFCs and one + * compliant with the NIST proposal, both extending CBC mode. + */ + +size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], + block128_f block) +{ + size_t residue, n; + + assert(in && out && key && ivec); + + if (len <= 16) + return 0; + + if ((residue = len % 16) == 0) + residue = 16; + + len -= residue; + + CRYPTO_cbc128_encrypt(in, out, len, key, ivec, block); + + in += len; + out += len; + + for (n = 0; n < residue; ++n) + ivec[n] ^= in[n]; + (*block) (ivec, ivec, key); + memcpy(out, out - 16, residue); + memcpy(out - 16, ivec, 16); + + return len + residue; +} + +size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, + unsigned char ivec[16], + block128_f block) +{ + size_t residue, n; + + assert(in && out && key && ivec); + + if (len < 16) + return 0; + + residue = len % 16; + + len -= residue; + + CRYPTO_cbc128_encrypt(in, out, len, key, ivec, block); + + if (residue == 0) + return len; + + in += len; + out += len; + + for (n = 0; n < residue; ++n) + ivec[n] ^= in[n]; + (*block) (ivec, ivec, key); + memcpy(out - 16 + residue, ivec, 16); + + return len + residue; +} + +size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc) +{ + size_t residue; + union { + size_t align; + unsigned char c[16]; + } tmp; + + assert(in && out && key && ivec); + + if (len <= 16) + return 0; + + if ((residue = len % 16) == 0) + residue = 16; + + len -= residue; + + (*cbc) (in, out, len, key, ivec, 1); + + in += len; + out += len; + +#if defined(CBC_HANDLES_TRUNCATED_IO) + memcpy(tmp.c, out - 16, 16); + (*cbc) (in, out - 16, residue, key, ivec, 1); + memcpy(out, tmp.c, residue); +#else + memset(tmp.c, 0, sizeof(tmp)); + memcpy(tmp.c, in, residue); + memcpy(out, out - 16, residue); + (*cbc) (tmp.c, out - 16, 16, key, ivec, 1); +#endif + return len + residue; +} + +size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc) +{ + size_t residue; + union { + size_t align; + unsigned char c[16]; + } tmp; + + assert(in && out && key && ivec); + + if (len < 16) + return 0; + + residue = len % 16; + + len -= residue; + + (*cbc) (in, out, len, key, ivec, 1); + + if (residue == 0) + return len; + + in += len; + out += len; + +#if defined(CBC_HANDLES_TRUNCATED_IO) + (*cbc) (in, out - 16 + residue, residue, key, ivec, 1); +#else + memset(tmp.c, 0, sizeof(tmp)); + memcpy(tmp.c, in, residue); + (*cbc) (tmp.c, out - 16 + residue, 16, key, ivec, 1); +#endif + return len + residue; +} + +size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], + block128_f block) +{ + size_t residue, n; + union { + size_t align; + unsigned char c[32]; + } tmp; + + assert(in && out && key && ivec); + + if (len <= 16) + return 0; + + if ((residue = len % 16) == 0) + residue = 16; + + len -= 16 + residue; + + if (len) { + CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block); + in += len; + out += len; + } + + (*block) (in, tmp.c + 16, key); + + memcpy(tmp.c, tmp.c + 16, 16); + memcpy(tmp.c, in + 16, residue); + (*block) (tmp.c, tmp.c, key); + + for (n = 0; n < 16; ++n) { + unsigned char c = in[n]; + out[n] = tmp.c[n] ^ ivec[n]; + ivec[n] = c; + } + for (residue += 16; n < residue; ++n) + out[n] = tmp.c[n] ^ in[n]; + + return 16 + len + residue; +} + +size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, + unsigned char ivec[16], + block128_f block) +{ + size_t residue, n; + union { + size_t align; + unsigned char c[32]; + } tmp; + + assert(in && out && key && ivec); + + if (len < 16) + return 0; + + residue = len % 16; + + if (residue == 0) { + CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block); + return len; + } + + len -= 16 + residue; + + if (len) { + CRYPTO_cbc128_decrypt(in, out, len, key, ivec, block); + in += len; + out += len; + } + + (*block) (in + residue, tmp.c + 16, key); + + memcpy(tmp.c, tmp.c + 16, 16); + memcpy(tmp.c, in, residue); + (*block) (tmp.c, tmp.c, key); + + for (n = 0; n < 16; ++n) { + unsigned char c = in[n]; + out[n] = tmp.c[n] ^ ivec[n]; + ivec[n] = in[n + residue]; + tmp.c[n] = c; + } + for (residue += 16; n < residue; ++n) + out[n] = tmp.c[n] ^ tmp.c[n - 16]; + + return 16 + len + residue; +} + +size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc) +{ + size_t residue; + union { + size_t align; + unsigned char c[32]; + } tmp; + + assert(in && out && key && ivec); + + if (len <= 16) + return 0; + + if ((residue = len % 16) == 0) + residue = 16; + + len -= 16 + residue; + + if (len) { + (*cbc) (in, out, len, key, ivec, 0); + in += len; + out += len; + } + + memset(tmp.c, 0, sizeof(tmp)); + /* + * this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] + */ + (*cbc) (in, tmp.c, 16, key, tmp.c + 16, 0); + + memcpy(tmp.c, in + 16, residue); +#if defined(CBC_HANDLES_TRUNCATED_IO) + (*cbc) (tmp.c, out, 16 + residue, key, ivec, 0); +#else + (*cbc) (tmp.c, tmp.c, 32, key, ivec, 0); + memcpy(out, tmp.c, 16 + residue); +#endif + return 16 + len + residue; +} + +size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc) +{ + size_t residue; + union { + size_t align; + unsigned char c[32]; + } tmp; + + assert(in && out && key && ivec); + + if (len < 16) + return 0; + + residue = len % 16; + + if (residue == 0) { + (*cbc) (in, out, len, key, ivec, 0); + return len; + } + + len -= 16 + residue; + + if (len) { + (*cbc) (in, out, len, key, ivec, 0); + in += len; + out += len; + } + + memset(tmp.c, 0, sizeof(tmp)); + /* + * this places in[16] at &tmp.c[16] and decrypted block at &tmp.c[0] + */ + (*cbc) (in + residue, tmp.c, 16, key, tmp.c + 16, 0); + + memcpy(tmp.c, in, residue); +#if defined(CBC_HANDLES_TRUNCATED_IO) + (*cbc) (tmp.c, out, 16 + residue, key, ivec, 0); +#else + (*cbc) (tmp.c, tmp.c, 32, key, ivec, 0); + memcpy(out, tmp.c, 16 + residue); +#endif + return 16 + len + residue; +} + +#if defined(SELFTEST) +# include +# include + +/* test vectors from RFC 3962 */ +static const unsigned char test_key[16] = "chicken teriyaki"; +static const unsigned char test_input[64] = + "I would like the" " General Gau's C" + "hicken, please, " "and wonton soup."; +static const unsigned char test_iv[16] = + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + +static const unsigned char vector_17[17] = { + 0xc6, 0x35, 0x35, 0x68, 0xf2, 0xbf, 0x8c, 0xb4, + 0xd8, 0xa5, 0x80, 0x36, 0x2d, 0xa7, 0xff, 0x7f, + 0x97 +}; + +static const unsigned char vector_31[31] = { + 0xfc, 0x00, 0x78, 0x3e, 0x0e, 0xfd, 0xb2, 0xc1, + 0xd4, 0x45, 0xd4, 0xc8, 0xef, 0xf7, 0xed, 0x22, + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5 +}; + +static const unsigned char vector_32[32] = { + 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, + 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8, + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84 +}; + +static const unsigned char vector_47[47] = { + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84, + 0xb3, 0xff, 0xfd, 0x94, 0x0c, 0x16, 0xa1, 0x8c, + 0x1b, 0x55, 0x49, 0xd2, 0xf8, 0x38, 0x02, 0x9e, + 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, + 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5 +}; + +static const unsigned char vector_48[48] = { + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84, + 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0, + 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8, + 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, + 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8 +}; + +static const unsigned char vector_64[64] = { + 0x97, 0x68, 0x72, 0x68, 0xd6, 0xec, 0xcc, 0xc0, + 0xc0, 0x7b, 0x25, 0xe2, 0x5e, 0xcf, 0xe5, 0x84, + 0x39, 0x31, 0x25, 0x23, 0xa7, 0x86, 0x62, 0xd5, + 0xbe, 0x7f, 0xcb, 0xcc, 0x98, 0xeb, 0xf5, 0xa8, + 0x48, 0x07, 0xef, 0xe8, 0x36, 0xee, 0x89, 0xa5, + 0x26, 0x73, 0x0d, 0xbc, 0x2f, 0x7b, 0xc8, 0x40, + 0x9d, 0xad, 0x8b, 0xbb, 0x96, 0xc4, 0xcd, 0xc0, + 0x3b, 0xc1, 0x03, 0xe1, 0xa1, 0x94, 0xbb, 0xd8 +}; + +static AES_KEY encks, decks; + +void test_vector(const unsigned char *vector, size_t len) +{ + unsigned char iv[sizeof(test_iv)]; + unsigned char cleartext[64], ciphertext[64]; + size_t tail; + + printf("vector_%d\n", len); + fflush(stdout); + + if ((tail = len % 16) == 0) + tail = 16; + tail += 16; + + /* test block-based encryption */ + memcpy(iv, test_iv, sizeof(test_iv)); + CRYPTO_cts128_encrypt_block(test_input, ciphertext, len, &encks, iv, + (block128_f) AES_encrypt); + if (memcmp(ciphertext, vector, len)) + fprintf(stderr, "output_%d mismatch\n", len), exit(1); + if (memcmp(iv, vector + len - tail, sizeof(iv))) + fprintf(stderr, "iv_%d mismatch\n", len), exit(1); + + /* test block-based decryption */ + memcpy(iv, test_iv, sizeof(test_iv)); + CRYPTO_cts128_decrypt_block(ciphertext, cleartext, len, &decks, iv, + (block128_f) AES_decrypt); + if (memcmp(cleartext, test_input, len)) + fprintf(stderr, "input_%d mismatch\n", len), exit(2); + if (memcmp(iv, vector + len - tail, sizeof(iv))) + fprintf(stderr, "iv_%d mismatch\n", len), exit(2); + + /* test streamed encryption */ + memcpy(iv, test_iv, sizeof(test_iv)); + CRYPTO_cts128_encrypt(test_input, ciphertext, len, &encks, iv, + (cbc128_f) AES_cbc_encrypt); + if (memcmp(ciphertext, vector, len)) + fprintf(stderr, "output_%d mismatch\n", len), exit(3); + if (memcmp(iv, vector + len - tail, sizeof(iv))) + fprintf(stderr, "iv_%d mismatch\n", len), exit(3); + + /* test streamed decryption */ + memcpy(iv, test_iv, sizeof(test_iv)); + CRYPTO_cts128_decrypt(ciphertext, cleartext, len, &decks, iv, + (cbc128_f) AES_cbc_encrypt); + if (memcmp(cleartext, test_input, len)) + fprintf(stderr, "input_%d mismatch\n", len), exit(4); + if (memcmp(iv, vector + len - tail, sizeof(iv))) + fprintf(stderr, "iv_%d mismatch\n", len), exit(4); +} + +void test_nistvector(const unsigned char *vector, size_t len) +{ + unsigned char iv[sizeof(test_iv)]; + unsigned char cleartext[64], ciphertext[64], nistvector[64]; + size_t tail; + + printf("nistvector_%d\n", len); + fflush(stdout); + + if ((tail = len % 16) == 0) + tail = 16; + + len -= 16 + tail; + memcpy(nistvector, vector, len); + /* flip two last blocks */ + memcpy(nistvector + len, vector + len + 16, tail); + memcpy(nistvector + len + tail, vector + len, 16); + len += 16 + tail; + tail = 16; + + /* test block-based encryption */ + memcpy(iv, test_iv, sizeof(test_iv)); + CRYPTO_nistcts128_encrypt_block(test_input, ciphertext, len, &encks, iv, + (block128_f) AES_encrypt); + if (memcmp(ciphertext, nistvector, len)) + fprintf(stderr, "output_%d mismatch\n", len), exit(1); + if (memcmp(iv, nistvector + len - tail, sizeof(iv))) + fprintf(stderr, "iv_%d mismatch\n", len), exit(1); + + /* test block-based decryption */ + memcpy(iv, test_iv, sizeof(test_iv)); + CRYPTO_nistcts128_decrypt_block(ciphertext, cleartext, len, &decks, iv, + (block128_f) AES_decrypt); + if (memcmp(cleartext, test_input, len)) + fprintf(stderr, "input_%d mismatch\n", len), exit(2); + if (memcmp(iv, nistvector + len - tail, sizeof(iv))) + fprintf(stderr, "iv_%d mismatch\n", len), exit(2); + + /* test streamed encryption */ + memcpy(iv, test_iv, sizeof(test_iv)); + CRYPTO_nistcts128_encrypt(test_input, ciphertext, len, &encks, iv, + (cbc128_f) AES_cbc_encrypt); + if (memcmp(ciphertext, nistvector, len)) + fprintf(stderr, "output_%d mismatch\n", len), exit(3); + if (memcmp(iv, nistvector + len - tail, sizeof(iv))) + fprintf(stderr, "iv_%d mismatch\n", len), exit(3); + + /* test streamed decryption */ + memcpy(iv, test_iv, sizeof(test_iv)); + CRYPTO_nistcts128_decrypt(ciphertext, cleartext, len, &decks, iv, + (cbc128_f) AES_cbc_encrypt); + if (memcmp(cleartext, test_input, len)) + fprintf(stderr, "input_%d mismatch\n", len), exit(4); + if (memcmp(iv, nistvector + len - tail, sizeof(iv))) + fprintf(stderr, "iv_%d mismatch\n", len), exit(4); +} + +int main() +{ + AES_set_encrypt_key(test_key, 128, &encks); + AES_set_decrypt_key(test_key, 128, &decks); + + test_vector(vector_17, sizeof(vector_17)); + test_vector(vector_31, sizeof(vector_31)); + test_vector(vector_32, sizeof(vector_32)); + test_vector(vector_47, sizeof(vector_47)); + test_vector(vector_48, sizeof(vector_48)); + test_vector(vector_64, sizeof(vector_64)); + + test_nistvector(vector_17, sizeof(vector_17)); + test_nistvector(vector_31, sizeof(vector_31)); + test_nistvector(vector_32, sizeof(vector_32)); + test_nistvector(vector_47, sizeof(vector_47)); + test_nistvector(vector_48, sizeof(vector_48)); + test_nistvector(vector_64, sizeof(vector_64)); + + return 0; +} +#endif diff --git a/libs/openssl/crypto/modes/gcm128.c b/libs/openssl/crypto/modes/gcm128.c new file mode 100644 index 00000000..0ee569fb --- /dev/null +++ b/libs/openssl/crypto/modes/gcm128.c @@ -0,0 +1,2289 @@ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#define OPENSSL_FIPSAPI + +#include +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +#if defined(BSWAP4) && defined(STRICT_ALIGNMENT) +/* redefine, because alignment is ensured */ +# undef GETU32 +# define GETU32(p) BSWAP4(*(const u32 *)(p)) +# undef PUTU32 +# define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) +#endif + +#define PACK(s) ((size_t)(s)<<(sizeof(size_t)*8-16)) +#define REDUCE1BIT(V) do { \ + if (sizeof(size_t)==8) { \ + u64 T = U64(0xe100000000000000) & (0-(V.lo&1)); \ + V.lo = (V.hi<<63)|(V.lo>>1); \ + V.hi = (V.hi>>1 )^T; \ + } \ + else { \ + u32 T = 0xe1000000U & (0-(u32)(V.lo&1)); \ + V.lo = (V.hi<<63)|(V.lo>>1); \ + V.hi = (V.hi>>1 )^((u64)T<<32); \ + } \ +} while(0) + +/*- + * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should + * never be set to 8. 8 is effectively reserved for testing purposes. + * TABLE_BITS>1 are lookup-table-driven implementations referred to as + * "Shoup's" in GCM specification. In other words OpenSSL does not cover + * whole spectrum of possible table driven implementations. Why? In + * non-"Shoup's" case memory access pattern is segmented in such manner, + * that it's trivial to see that cache timing information can reveal + * fair portion of intermediate hash value. Given that ciphertext is + * always available to attacker, it's possible for him to attempt to + * deduce secret parameter H and if successful, tamper with messages + * [which is nothing but trivial in CTR mode]. In "Shoup's" case it's + * not as trivial, but there is no reason to believe that it's resistant + * to cache-timing attack. And the thing about "8-bit" implementation is + * that it consumes 16 (sixteen) times more memory, 4KB per individual + * key + 1KB shared. Well, on pros side it should be twice as fast as + * "4-bit" version. And for gcc-generated x86[_64] code, "8-bit" version + * was observed to run ~75% faster, closer to 100% for commercial + * compilers... Yet "4-bit" procedure is preferred, because it's + * believed to provide better security-performance balance and adequate + * all-round performance. "All-round" refers to things like: + * + * - shorter setup time effectively improves overall timing for + * handling short messages; + * - larger table allocation can become unbearable because of VM + * subsystem penalties (for example on Windows large enough free + * results in VM working set trimming, meaning that consequent + * malloc would immediately incur working set expansion); + * - larger table has larger cache footprint, which can affect + * performance of other code paths (not necessarily even from same + * thread in Hyper-Threading world); + * + * Value of 1 is not appropriate for performance reasons. + */ +#if TABLE_BITS==8 + +static void gcm_init_8bit(u128 Htable[256], u64 H[2]) +{ + int i, j; + u128 V; + + Htable[0].hi = 0; + Htable[0].lo = 0; + V.hi = H[0]; + V.lo = H[1]; + + for (Htable[128] = V, i = 64; i > 0; i >>= 1) { + REDUCE1BIT(V); + Htable[i] = V; + } + + for (i = 2; i < 256; i <<= 1) { + u128 *Hi = Htable + i, H0 = *Hi; + for (j = 1; j < i; ++j) { + Hi[j].hi = H0.hi ^ Htable[j].hi; + Hi[j].lo = H0.lo ^ Htable[j].lo; + } + } +} + +static void gcm_gmult_8bit(u64 Xi[2], const u128 Htable[256]) +{ + u128 Z = { 0, 0 }; + const u8 *xi = (const u8 *)Xi + 15; + size_t rem, n = *xi; + const union { + long one; + char little; + } is_endian = { + 1 + }; + static const size_t rem_8bit[256] = { + PACK(0x0000), PACK(0x01C2), PACK(0x0384), PACK(0x0246), + PACK(0x0708), PACK(0x06CA), PACK(0x048C), PACK(0x054E), + PACK(0x0E10), PACK(0x0FD2), PACK(0x0D94), PACK(0x0C56), + PACK(0x0918), PACK(0x08DA), PACK(0x0A9C), PACK(0x0B5E), + PACK(0x1C20), PACK(0x1DE2), PACK(0x1FA4), PACK(0x1E66), + PACK(0x1B28), PACK(0x1AEA), PACK(0x18AC), PACK(0x196E), + PACK(0x1230), PACK(0x13F2), PACK(0x11B4), PACK(0x1076), + PACK(0x1538), PACK(0x14FA), PACK(0x16BC), PACK(0x177E), + PACK(0x3840), PACK(0x3982), PACK(0x3BC4), PACK(0x3A06), + PACK(0x3F48), PACK(0x3E8A), PACK(0x3CCC), PACK(0x3D0E), + PACK(0x3650), PACK(0x3792), PACK(0x35D4), PACK(0x3416), + PACK(0x3158), PACK(0x309A), PACK(0x32DC), PACK(0x331E), + PACK(0x2460), PACK(0x25A2), PACK(0x27E4), PACK(0x2626), + PACK(0x2368), PACK(0x22AA), PACK(0x20EC), PACK(0x212E), + PACK(0x2A70), PACK(0x2BB2), PACK(0x29F4), PACK(0x2836), + PACK(0x2D78), PACK(0x2CBA), PACK(0x2EFC), PACK(0x2F3E), + PACK(0x7080), PACK(0x7142), PACK(0x7304), PACK(0x72C6), + PACK(0x7788), PACK(0x764A), PACK(0x740C), PACK(0x75CE), + PACK(0x7E90), PACK(0x7F52), PACK(0x7D14), PACK(0x7CD6), + PACK(0x7998), PACK(0x785A), PACK(0x7A1C), PACK(0x7BDE), + PACK(0x6CA0), PACK(0x6D62), PACK(0x6F24), PACK(0x6EE6), + PACK(0x6BA8), PACK(0x6A6A), PACK(0x682C), PACK(0x69EE), + PACK(0x62B0), PACK(0x6372), PACK(0x6134), PACK(0x60F6), + PACK(0x65B8), PACK(0x647A), PACK(0x663C), PACK(0x67FE), + PACK(0x48C0), PACK(0x4902), PACK(0x4B44), PACK(0x4A86), + PACK(0x4FC8), PACK(0x4E0A), PACK(0x4C4C), PACK(0x4D8E), + PACK(0x46D0), PACK(0x4712), PACK(0x4554), PACK(0x4496), + PACK(0x41D8), PACK(0x401A), PACK(0x425C), PACK(0x439E), + PACK(0x54E0), PACK(0x5522), PACK(0x5764), PACK(0x56A6), + PACK(0x53E8), PACK(0x522A), PACK(0x506C), PACK(0x51AE), + PACK(0x5AF0), PACK(0x5B32), PACK(0x5974), PACK(0x58B6), + PACK(0x5DF8), PACK(0x5C3A), PACK(0x5E7C), PACK(0x5FBE), + PACK(0xE100), PACK(0xE0C2), PACK(0xE284), PACK(0xE346), + PACK(0xE608), PACK(0xE7CA), PACK(0xE58C), PACK(0xE44E), + PACK(0xEF10), PACK(0xEED2), PACK(0xEC94), PACK(0xED56), + PACK(0xE818), PACK(0xE9DA), PACK(0xEB9C), PACK(0xEA5E), + PACK(0xFD20), PACK(0xFCE2), PACK(0xFEA4), PACK(0xFF66), + PACK(0xFA28), PACK(0xFBEA), PACK(0xF9AC), PACK(0xF86E), + PACK(0xF330), PACK(0xF2F2), PACK(0xF0B4), PACK(0xF176), + PACK(0xF438), PACK(0xF5FA), PACK(0xF7BC), PACK(0xF67E), + PACK(0xD940), PACK(0xD882), PACK(0xDAC4), PACK(0xDB06), + PACK(0xDE48), PACK(0xDF8A), PACK(0xDDCC), PACK(0xDC0E), + PACK(0xD750), PACK(0xD692), PACK(0xD4D4), PACK(0xD516), + PACK(0xD058), PACK(0xD19A), PACK(0xD3DC), PACK(0xD21E), + PACK(0xC560), PACK(0xC4A2), PACK(0xC6E4), PACK(0xC726), + PACK(0xC268), PACK(0xC3AA), PACK(0xC1EC), PACK(0xC02E), + PACK(0xCB70), PACK(0xCAB2), PACK(0xC8F4), PACK(0xC936), + PACK(0xCC78), PACK(0xCDBA), PACK(0xCFFC), PACK(0xCE3E), + PACK(0x9180), PACK(0x9042), PACK(0x9204), PACK(0x93C6), + PACK(0x9688), PACK(0x974A), PACK(0x950C), PACK(0x94CE), + PACK(0x9F90), PACK(0x9E52), PACK(0x9C14), PACK(0x9DD6), + PACK(0x9898), PACK(0x995A), PACK(0x9B1C), PACK(0x9ADE), + PACK(0x8DA0), PACK(0x8C62), PACK(0x8E24), PACK(0x8FE6), + PACK(0x8AA8), PACK(0x8B6A), PACK(0x892C), PACK(0x88EE), + PACK(0x83B0), PACK(0x8272), PACK(0x8034), PACK(0x81F6), + PACK(0x84B8), PACK(0x857A), PACK(0x873C), PACK(0x86FE), + PACK(0xA9C0), PACK(0xA802), PACK(0xAA44), PACK(0xAB86), + PACK(0xAEC8), PACK(0xAF0A), PACK(0xAD4C), PACK(0xAC8E), + PACK(0xA7D0), PACK(0xA612), PACK(0xA454), PACK(0xA596), + PACK(0xA0D8), PACK(0xA11A), PACK(0xA35C), PACK(0xA29E), + PACK(0xB5E0), PACK(0xB422), PACK(0xB664), PACK(0xB7A6), + PACK(0xB2E8), PACK(0xB32A), PACK(0xB16C), PACK(0xB0AE), + PACK(0xBBF0), PACK(0xBA32), PACK(0xB874), PACK(0xB9B6), + PACK(0xBCF8), PACK(0xBD3A), PACK(0xBF7C), PACK(0xBEBE) + }; + + while (1) { + Z.hi ^= Htable[n].hi; + Z.lo ^= Htable[n].lo; + + if ((u8 *)Xi == xi) + break; + + n = *(--xi); + + rem = (size_t)Z.lo & 0xff; + Z.lo = (Z.hi << 56) | (Z.lo >> 8); + Z.hi = (Z.hi >> 8); + if (sizeof(size_t) == 8) + Z.hi ^= rem_8bit[rem]; + else + Z.hi ^= (u64)rem_8bit[rem] << 32; + } + + if (is_endian.little) { +# ifdef BSWAP8 + Xi[0] = BSWAP8(Z.hi); + Xi[1] = BSWAP8(Z.lo); +# else + u8 *p = (u8 *)Xi; + u32 v; + v = (u32)(Z.hi >> 32); + PUTU32(p, v); + v = (u32)(Z.hi); + PUTU32(p + 4, v); + v = (u32)(Z.lo >> 32); + PUTU32(p + 8, v); + v = (u32)(Z.lo); + PUTU32(p + 12, v); +# endif + } else { + Xi[0] = Z.hi; + Xi[1] = Z.lo; + } +} + +# define GCM_MUL(ctx,Xi) gcm_gmult_8bit(ctx->Xi.u,ctx->Htable) + +#elif TABLE_BITS==4 + +static void gcm_init_4bit(u128 Htable[16], u64 H[2]) +{ + u128 V; +# if defined(OPENSSL_SMALL_FOOTPRINT) + int i; +# endif + + Htable[0].hi = 0; + Htable[0].lo = 0; + V.hi = H[0]; + V.lo = H[1]; + +# if defined(OPENSSL_SMALL_FOOTPRINT) + for (Htable[8] = V, i = 4; i > 0; i >>= 1) { + REDUCE1BIT(V); + Htable[i] = V; + } + + for (i = 2; i < 16; i <<= 1) { + u128 *Hi = Htable + i; + int j; + for (V = *Hi, j = 1; j < i; ++j) { + Hi[j].hi = V.hi ^ Htable[j].hi; + Hi[j].lo = V.lo ^ Htable[j].lo; + } + } +# else + Htable[8] = V; + REDUCE1BIT(V); + Htable[4] = V; + REDUCE1BIT(V); + Htable[2] = V; + REDUCE1BIT(V); + Htable[1] = V; + Htable[3].hi = V.hi ^ Htable[2].hi, Htable[3].lo = V.lo ^ Htable[2].lo; + V = Htable[4]; + Htable[5].hi = V.hi ^ Htable[1].hi, Htable[5].lo = V.lo ^ Htable[1].lo; + Htable[6].hi = V.hi ^ Htable[2].hi, Htable[6].lo = V.lo ^ Htable[2].lo; + Htable[7].hi = V.hi ^ Htable[3].hi, Htable[7].lo = V.lo ^ Htable[3].lo; + V = Htable[8]; + Htable[9].hi = V.hi ^ Htable[1].hi, Htable[9].lo = V.lo ^ Htable[1].lo; + Htable[10].hi = V.hi ^ Htable[2].hi, Htable[10].lo = V.lo ^ Htable[2].lo; + Htable[11].hi = V.hi ^ Htable[3].hi, Htable[11].lo = V.lo ^ Htable[3].lo; + Htable[12].hi = V.hi ^ Htable[4].hi, Htable[12].lo = V.lo ^ Htable[4].lo; + Htable[13].hi = V.hi ^ Htable[5].hi, Htable[13].lo = V.lo ^ Htable[5].lo; + Htable[14].hi = V.hi ^ Htable[6].hi, Htable[14].lo = V.lo ^ Htable[6].lo; + Htable[15].hi = V.hi ^ Htable[7].hi, Htable[15].lo = V.lo ^ Htable[7].lo; +# endif +# if defined(GHASH_ASM) && (defined(__arm__) || defined(__arm)) + /* + * ARM assembler expects specific dword order in Htable. + */ + { + int j; + const union { + long one; + char little; + } is_endian = { + 1 + }; + + if (is_endian.little) + for (j = 0; j < 16; ++j) { + V = Htable[j]; + Htable[j].hi = V.lo; + Htable[j].lo = V.hi; + } else + for (j = 0; j < 16; ++j) { + V = Htable[j]; + Htable[j].hi = V.lo << 32 | V.lo >> 32; + Htable[j].lo = V.hi << 32 | V.hi >> 32; + } + } +# endif +} + +# ifndef GHASH_ASM +static const size_t rem_4bit[16] = { + PACK(0x0000), PACK(0x1C20), PACK(0x3840), PACK(0x2460), + PACK(0x7080), PACK(0x6CA0), PACK(0x48C0), PACK(0x54E0), + PACK(0xE100), PACK(0xFD20), PACK(0xD940), PACK(0xC560), + PACK(0x9180), PACK(0x8DA0), PACK(0xA9C0), PACK(0xB5E0) +}; + +static void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]) +{ + u128 Z; + int cnt = 15; + size_t rem, nlo, nhi; + const union { + long one; + char little; + } is_endian = { + 1 + }; + + nlo = ((const u8 *)Xi)[15]; + nhi = nlo >> 4; + nlo &= 0xf; + + Z.hi = Htable[nlo].hi; + Z.lo = Htable[nlo].lo; + + while (1) { + rem = (size_t)Z.lo & 0xf; + Z.lo = (Z.hi << 60) | (Z.lo >> 4); + Z.hi = (Z.hi >> 4); + if (sizeof(size_t) == 8) + Z.hi ^= rem_4bit[rem]; + else + Z.hi ^= (u64)rem_4bit[rem] << 32; + + Z.hi ^= Htable[nhi].hi; + Z.lo ^= Htable[nhi].lo; + + if (--cnt < 0) + break; + + nlo = ((const u8 *)Xi)[cnt]; + nhi = nlo >> 4; + nlo &= 0xf; + + rem = (size_t)Z.lo & 0xf; + Z.lo = (Z.hi << 60) | (Z.lo >> 4); + Z.hi = (Z.hi >> 4); + if (sizeof(size_t) == 8) + Z.hi ^= rem_4bit[rem]; + else + Z.hi ^= (u64)rem_4bit[rem] << 32; + + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + } + + if (is_endian.little) { +# ifdef BSWAP8 + Xi[0] = BSWAP8(Z.hi); + Xi[1] = BSWAP8(Z.lo); +# else + u8 *p = (u8 *)Xi; + u32 v; + v = (u32)(Z.hi >> 32); + PUTU32(p, v); + v = (u32)(Z.hi); + PUTU32(p + 4, v); + v = (u32)(Z.lo >> 32); + PUTU32(p + 8, v); + v = (u32)(Z.lo); + PUTU32(p + 12, v); +# endif + } else { + Xi[0] = Z.hi; + Xi[1] = Z.lo; + } +} + +# if !defined(OPENSSL_SMALL_FOOTPRINT) +/* + * Streamed gcm_mult_4bit, see CRYPTO_gcm128_[en|de]crypt for + * details... Compiler-generated code doesn't seem to give any + * performance improvement, at least not on x86[_64]. It's here + * mostly as reference and a placeholder for possible future + * non-trivial optimization[s]... + */ +static void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) +{ + u128 Z; + int cnt; + size_t rem, nlo, nhi; + const union { + long one; + char little; + } is_endian = { + 1 + }; + +# if 1 + do { + cnt = 15; + nlo = ((const u8 *)Xi)[15]; + nlo ^= inp[15]; + nhi = nlo >> 4; + nlo &= 0xf; + + Z.hi = Htable[nlo].hi; + Z.lo = Htable[nlo].lo; + + while (1) { + rem = (size_t)Z.lo & 0xf; + Z.lo = (Z.hi << 60) | (Z.lo >> 4); + Z.hi = (Z.hi >> 4); + if (sizeof(size_t) == 8) + Z.hi ^= rem_4bit[rem]; + else + Z.hi ^= (u64)rem_4bit[rem] << 32; + + Z.hi ^= Htable[nhi].hi; + Z.lo ^= Htable[nhi].lo; + + if (--cnt < 0) + break; + + nlo = ((const u8 *)Xi)[cnt]; + nlo ^= inp[cnt]; + nhi = nlo >> 4; + nlo &= 0xf; + + rem = (size_t)Z.lo & 0xf; + Z.lo = (Z.hi << 60) | (Z.lo >> 4); + Z.hi = (Z.hi >> 4); + if (sizeof(size_t) == 8) + Z.hi ^= rem_4bit[rem]; + else + Z.hi ^= (u64)rem_4bit[rem] << 32; + + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + } +# else + /* + * Extra 256+16 bytes per-key plus 512 bytes shared tables + * [should] give ~50% improvement... One could have PACK()-ed + * the rem_8bit even here, but the priority is to minimize + * cache footprint... + */ + u128 Hshr4[16]; /* Htable shifted right by 4 bits */ + u8 Hshl4[16]; /* Htable shifted left by 4 bits */ + static const unsigned short rem_8bit[256] = { + 0x0000, 0x01C2, 0x0384, 0x0246, 0x0708, 0x06CA, 0x048C, 0x054E, + 0x0E10, 0x0FD2, 0x0D94, 0x0C56, 0x0918, 0x08DA, 0x0A9C, 0x0B5E, + 0x1C20, 0x1DE2, 0x1FA4, 0x1E66, 0x1B28, 0x1AEA, 0x18AC, 0x196E, + 0x1230, 0x13F2, 0x11B4, 0x1076, 0x1538, 0x14FA, 0x16BC, 0x177E, + 0x3840, 0x3982, 0x3BC4, 0x3A06, 0x3F48, 0x3E8A, 0x3CCC, 0x3D0E, + 0x3650, 0x3792, 0x35D4, 0x3416, 0x3158, 0x309A, 0x32DC, 0x331E, + 0x2460, 0x25A2, 0x27E4, 0x2626, 0x2368, 0x22AA, 0x20EC, 0x212E, + 0x2A70, 0x2BB2, 0x29F4, 0x2836, 0x2D78, 0x2CBA, 0x2EFC, 0x2F3E, + 0x7080, 0x7142, 0x7304, 0x72C6, 0x7788, 0x764A, 0x740C, 0x75CE, + 0x7E90, 0x7F52, 0x7D14, 0x7CD6, 0x7998, 0x785A, 0x7A1C, 0x7BDE, + 0x6CA0, 0x6D62, 0x6F24, 0x6EE6, 0x6BA8, 0x6A6A, 0x682C, 0x69EE, + 0x62B0, 0x6372, 0x6134, 0x60F6, 0x65B8, 0x647A, 0x663C, 0x67FE, + 0x48C0, 0x4902, 0x4B44, 0x4A86, 0x4FC8, 0x4E0A, 0x4C4C, 0x4D8E, + 0x46D0, 0x4712, 0x4554, 0x4496, 0x41D8, 0x401A, 0x425C, 0x439E, + 0x54E0, 0x5522, 0x5764, 0x56A6, 0x53E8, 0x522A, 0x506C, 0x51AE, + 0x5AF0, 0x5B32, 0x5974, 0x58B6, 0x5DF8, 0x5C3A, 0x5E7C, 0x5FBE, + 0xE100, 0xE0C2, 0xE284, 0xE346, 0xE608, 0xE7CA, 0xE58C, 0xE44E, + 0xEF10, 0xEED2, 0xEC94, 0xED56, 0xE818, 0xE9DA, 0xEB9C, 0xEA5E, + 0xFD20, 0xFCE2, 0xFEA4, 0xFF66, 0xFA28, 0xFBEA, 0xF9AC, 0xF86E, + 0xF330, 0xF2F2, 0xF0B4, 0xF176, 0xF438, 0xF5FA, 0xF7BC, 0xF67E, + 0xD940, 0xD882, 0xDAC4, 0xDB06, 0xDE48, 0xDF8A, 0xDDCC, 0xDC0E, + 0xD750, 0xD692, 0xD4D4, 0xD516, 0xD058, 0xD19A, 0xD3DC, 0xD21E, + 0xC560, 0xC4A2, 0xC6E4, 0xC726, 0xC268, 0xC3AA, 0xC1EC, 0xC02E, + 0xCB70, 0xCAB2, 0xC8F4, 0xC936, 0xCC78, 0xCDBA, 0xCFFC, 0xCE3E, + 0x9180, 0x9042, 0x9204, 0x93C6, 0x9688, 0x974A, 0x950C, 0x94CE, + 0x9F90, 0x9E52, 0x9C14, 0x9DD6, 0x9898, 0x995A, 0x9B1C, 0x9ADE, + 0x8DA0, 0x8C62, 0x8E24, 0x8FE6, 0x8AA8, 0x8B6A, 0x892C, 0x88EE, + 0x83B0, 0x8272, 0x8034, 0x81F6, 0x84B8, 0x857A, 0x873C, 0x86FE, + 0xA9C0, 0xA802, 0xAA44, 0xAB86, 0xAEC8, 0xAF0A, 0xAD4C, 0xAC8E, + 0xA7D0, 0xA612, 0xA454, 0xA596, 0xA0D8, 0xA11A, 0xA35C, 0xA29E, + 0xB5E0, 0xB422, 0xB664, 0xB7A6, 0xB2E8, 0xB32A, 0xB16C, 0xB0AE, + 0xBBF0, 0xBA32, 0xB874, 0xB9B6, 0xBCF8, 0xBD3A, 0xBF7C, 0xBEBE + }; + /* + * This pre-processing phase slows down procedure by approximately + * same time as it makes each loop spin faster. In other words + * single block performance is approximately same as straightforward + * "4-bit" implementation, and then it goes only faster... + */ + for (cnt = 0; cnt < 16; ++cnt) { + Z.hi = Htable[cnt].hi; + Z.lo = Htable[cnt].lo; + Hshr4[cnt].lo = (Z.hi << 60) | (Z.lo >> 4); + Hshr4[cnt].hi = (Z.hi >> 4); + Hshl4[cnt] = (u8)(Z.lo << 4); + } + + do { + for (Z.lo = 0, Z.hi = 0, cnt = 15; cnt; --cnt) { + nlo = ((const u8 *)Xi)[cnt]; + nlo ^= inp[cnt]; + nhi = nlo >> 4; + nlo &= 0xf; + + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + + rem = (size_t)Z.lo & 0xff; + + Z.lo = (Z.hi << 56) | (Z.lo >> 8); + Z.hi = (Z.hi >> 8); + + Z.hi ^= Hshr4[nhi].hi; + Z.lo ^= Hshr4[nhi].lo; + Z.hi ^= (u64)rem_8bit[rem ^ Hshl4[nhi]] << 48; + } + + nlo = ((const u8 *)Xi)[0]; + nlo ^= inp[0]; + nhi = nlo >> 4; + nlo &= 0xf; + + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + + rem = (size_t)Z.lo & 0xf; + + Z.lo = (Z.hi << 60) | (Z.lo >> 4); + Z.hi = (Z.hi >> 4); + + Z.hi ^= Htable[nhi].hi; + Z.lo ^= Htable[nhi].lo; + Z.hi ^= ((u64)rem_8bit[rem << 4]) << 48; +# endif + + if (is_endian.little) { +# ifdef BSWAP8 + Xi[0] = BSWAP8(Z.hi); + Xi[1] = BSWAP8(Z.lo); +# else + u8 *p = (u8 *)Xi; + u32 v; + v = (u32)(Z.hi >> 32); + PUTU32(p, v); + v = (u32)(Z.hi); + PUTU32(p + 4, v); + v = (u32)(Z.lo >> 32); + PUTU32(p + 8, v); + v = (u32)(Z.lo); + PUTU32(p + 12, v); +# endif + } else { + Xi[0] = Z.hi; + Xi[1] = Z.lo; + } + } while (inp += 16, len -= 16); +} +# endif +# else +void gcm_gmult_4bit(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_4bit(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +# endif + +# define GCM_MUL(ctx,Xi) gcm_gmult_4bit(ctx->Xi.u,ctx->Htable) +# if defined(GHASH_ASM) || !defined(OPENSSL_SMALL_FOOTPRINT) +# define GHASH(ctx,in,len) gcm_ghash_4bit((ctx)->Xi.u,(ctx)->Htable,in,len) +/* + * GHASH_CHUNK is "stride parameter" missioned to mitigate cache trashing + * effect. In other words idea is to hash data while it's still in L1 cache + * after encryption pass... + */ +# define GHASH_CHUNK (3*1024) +# endif + +#else /* TABLE_BITS */ + +static void gcm_gmult_1bit(u64 Xi[2], const u64 H[2]) +{ + u128 V, Z = { 0, 0 }; + long X; + int i, j; + const long *xi = (const long *)Xi; + const union { + long one; + char little; + } is_endian = { + 1 + }; + + V.hi = H[0]; /* H is in host byte order, no byte swapping */ + V.lo = H[1]; + + for (j = 0; j < 16 / sizeof(long); ++j) { + if (is_endian.little) { + if (sizeof(long) == 8) { +# ifdef BSWAP8 + X = (long)(BSWAP8(xi[j])); +# else + const u8 *p = (const u8 *)(xi + j); + X = (long)((u64)GETU32(p) << 32 | GETU32(p + 4)); +# endif + } else { + const u8 *p = (const u8 *)(xi + j); + X = (long)GETU32(p); + } + } else + X = xi[j]; + + for (i = 0; i < 8 * sizeof(long); ++i, X <<= 1) { + u64 M = (u64)(X >> (8 * sizeof(long) - 1)); + Z.hi ^= V.hi & M; + Z.lo ^= V.lo & M; + + REDUCE1BIT(V); + } + } + + if (is_endian.little) { +# ifdef BSWAP8 + Xi[0] = BSWAP8(Z.hi); + Xi[1] = BSWAP8(Z.lo); +# else + u8 *p = (u8 *)Xi; + u32 v; + v = (u32)(Z.hi >> 32); + PUTU32(p, v); + v = (u32)(Z.hi); + PUTU32(p + 4, v); + v = (u32)(Z.lo >> 32); + PUTU32(p + 8, v); + v = (u32)(Z.lo); + PUTU32(p + 12, v); +# endif + } else { + Xi[0] = Z.hi; + Xi[1] = Z.lo; + } +} + +# define GCM_MUL(ctx,Xi) gcm_gmult_1bit(ctx->Xi.u,ctx->H.u) + +#endif + +#if TABLE_BITS==4 && defined(GHASH_ASM) +# if !defined(I386_ONLY) && \ + (defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64)) +# define GHASH_ASM_X86_OR_64 +# define GCM_FUNCREF_4BIT +extern unsigned int OPENSSL_ia32cap_P[2]; + +void gcm_init_clmul(u128 Htable[16], const u64 Xi[2]); +void gcm_gmult_clmul(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_clmul(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); + +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) +# define GHASH_ASM_X86 +void gcm_gmult_4bit_mmx(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_4bit_mmx(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); + +void gcm_gmult_4bit_x86(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_4bit_x86(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +# endif +# elif defined(__arm__) || defined(__arm) +# include "arm_arch.h" +# if __ARM_ARCH__>=7 +# define GHASH_ASM_ARM +# define GCM_FUNCREF_4BIT +void gcm_gmult_neon(u64 Xi[2], const u128 Htable[16]); +void gcm_ghash_neon(u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +# endif +# endif +#endif + +#ifdef GCM_FUNCREF_4BIT +# undef GCM_MUL +# define GCM_MUL(ctx,Xi) (*gcm_gmult_p)(ctx->Xi.u,ctx->Htable) +# ifdef GHASH +# undef GHASH +# define GHASH(ctx,in,len) (*gcm_ghash_p)(ctx->Xi.u,ctx->Htable,in,len) +# endif +#endif + +void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + + memset(ctx, 0, sizeof(*ctx)); + ctx->block = block; + ctx->key = key; + + (*block) (ctx->H.c, ctx->H.c, key); + + if (is_endian.little) { + /* H is stored in host byte order */ +#ifdef BSWAP8 + ctx->H.u[0] = BSWAP8(ctx->H.u[0]); + ctx->H.u[1] = BSWAP8(ctx->H.u[1]); +#else + u8 *p = ctx->H.c; + u64 hi, lo; + hi = (u64)GETU32(p) << 32 | GETU32(p + 4); + lo = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); + ctx->H.u[0] = hi; + ctx->H.u[1] = lo; +#endif + } +#if TABLE_BITS==8 + gcm_init_8bit(ctx->Htable, ctx->H.u); +#elif TABLE_BITS==4 +# if defined(GHASH_ASM_X86_OR_64) +# if !defined(GHASH_ASM_X86) || defined(OPENSSL_IA32_SSE2) + if (OPENSSL_ia32cap_P[0] & (1 << 24) && /* check FXSR bit */ + OPENSSL_ia32cap_P[1] & (1 << 1)) { /* check PCLMULQDQ bit */ + gcm_init_clmul(ctx->Htable, ctx->H.u); + ctx->gmult = gcm_gmult_clmul; + ctx->ghash = gcm_ghash_clmul; + return; + } +# endif + gcm_init_4bit(ctx->Htable, ctx->H.u); +# if defined(GHASH_ASM_X86) /* x86 only */ +# if defined(OPENSSL_IA32_SSE2) + if (OPENSSL_ia32cap_P[0] & (1 << 25)) { /* check SSE bit */ +# else + if (OPENSSL_ia32cap_P[0] & (1 << 23)) { /* check MMX bit */ +# endif + ctx->gmult = gcm_gmult_4bit_mmx; + ctx->ghash = gcm_ghash_4bit_mmx; + } else { + ctx->gmult = gcm_gmult_4bit_x86; + ctx->ghash = gcm_ghash_4bit_x86; + } +# else + ctx->gmult = gcm_gmult_4bit; + ctx->ghash = gcm_ghash_4bit; +# endif +# elif defined(GHASH_ASM_ARM) + if (OPENSSL_armcap_P & ARMV7_NEON) { + ctx->gmult = gcm_gmult_neon; + ctx->ghash = gcm_ghash_neon; + } else { + gcm_init_4bit(ctx->Htable, ctx->H.u); + ctx->gmult = gcm_gmult_4bit; + ctx->ghash = gcm_ghash_4bit; + } +# else + gcm_init_4bit(ctx->Htable, ctx->H.u); +# endif +#endif +} + +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, + size_t len) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + unsigned int ctr; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +#endif + + ctx->Yi.u[0] = 0; + ctx->Yi.u[1] = 0; + ctx->Xi.u[0] = 0; + ctx->Xi.u[1] = 0; + ctx->len.u[0] = 0; /* AAD length */ + ctx->len.u[1] = 0; /* message length */ + ctx->ares = 0; + ctx->mres = 0; + + if (len == 12) { + memcpy(ctx->Yi.c, iv, 12); + ctx->Yi.c[15] = 1; + ctr = 1; + } else { + size_t i; + u64 len0 = len; + + while (len >= 16) { + for (i = 0; i < 16; ++i) + ctx->Yi.c[i] ^= iv[i]; + GCM_MUL(ctx, Yi); + iv += 16; + len -= 16; + } + if (len) { + for (i = 0; i < len; ++i) + ctx->Yi.c[i] ^= iv[i]; + GCM_MUL(ctx, Yi); + } + len0 <<= 3; + if (is_endian.little) { +#ifdef BSWAP8 + ctx->Yi.u[1] ^= BSWAP8(len0); +#else + ctx->Yi.c[8] ^= (u8)(len0 >> 56); + ctx->Yi.c[9] ^= (u8)(len0 >> 48); + ctx->Yi.c[10] ^= (u8)(len0 >> 40); + ctx->Yi.c[11] ^= (u8)(len0 >> 32); + ctx->Yi.c[12] ^= (u8)(len0 >> 24); + ctx->Yi.c[13] ^= (u8)(len0 >> 16); + ctx->Yi.c[14] ^= (u8)(len0 >> 8); + ctx->Yi.c[15] ^= (u8)(len0); +#endif + } else + ctx->Yi.u[1] ^= len0; + + GCM_MUL(ctx, Yi); + + if (is_endian.little) +#ifdef BSWAP4 + ctr = BSWAP4(ctx->Yi.d[3]); +#else + ctr = GETU32(ctx->Yi.c + 12); +#endif + else + ctr = ctx->Yi.d[3]; + } + + (*ctx->block) (ctx->Yi.c, ctx->EK0.c, ctx->key); + ++ctr; + if (is_endian.little) +#ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +#else + PUTU32(ctx->Yi.c + 12, ctr); +#endif + else + ctx->Yi.d[3] = ctr; +} + +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, + size_t len) +{ + size_t i; + unsigned int n; + u64 alen = ctx->len.u[0]; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + + if (ctx->len.u[1]) + return -2; + + alen += len; + if (alen > (U64(1) << 61) || (sizeof(len) == 8 && alen < len)) + return -1; + ctx->len.u[0] = alen; + + n = ctx->ares; + if (n) { + while (n && len) { + ctx->Xi.c[n] ^= *(aad++); + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->ares = n; + return 0; + } + } +#ifdef GHASH + if ((i = (len & (size_t)-16))) { + GHASH(ctx, aad, i); + aad += i; + len -= i; + } +#else + while (len >= 16) { + for (i = 0; i < 16; ++i) + ctx->Xi.c[i] ^= aad[i]; + GCM_MUL(ctx, Xi); + aad += 16; + len -= 16; + } +#endif + if (len) { + n = (unsigned int)len; + for (i = 0; i < len; ++i) + ctx->Xi.c[i] ^= aad[i]; + } + + ctx->ares = n; + return 0; +} + +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + unsigned int n, ctr; + size_t i; + u64 mlen = ctx->len.u[1]; + block128_f block = ctx->block; + void *key = ctx->key; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + +#if 0 + n = (unsigned int)mlen % 16; /* alternative to ctx->mres */ +#endif + mlen += len; + if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) + return -1; + ctx->len.u[1] = mlen; + + if (ctx->ares) { + /* First call to encrypt finalizes GHASH(AAD) */ + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + if (is_endian.little) +#ifdef BSWAP4 + ctr = BSWAP4(ctx->Yi.d[3]); +#else + ctr = GETU32(ctx->Yi.c + 12); +#endif + else + ctr = ctx->Yi.d[3]; + + n = ctx->mres; +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) { /* always true actually */ + do { + if (n) { + while (n && len) { + ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n]; + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->mres = n; + return 0; + } + } +# if defined(STRICT_ALIGNMENT) + if (((size_t)in | (size_t)out) % sizeof(size_t) != 0) + break; +# endif +# if defined(GHASH) && defined(GHASH_CHUNK) + while (len >= GHASH_CHUNK) { + size_t j = GHASH_CHUNK; + + while (j) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + for (i = 0; i < 16 / sizeof(size_t); ++i) + out_t[i] = in_t[i] ^ ctx->EKi.t[i]; + out += 16; + in += 16; + j -= 16; + } + GHASH(ctx, out - GHASH_CHUNK, GHASH_CHUNK); + len -= GHASH_CHUNK; + } + if ((i = (len & (size_t)-16))) { + size_t j = i; + + while (len >= 16) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + for (i = 0; i < 16 / sizeof(size_t); ++i) + out_t[i] = in_t[i] ^ ctx->EKi.t[i]; + out += 16; + in += 16; + len -= 16; + } + GHASH(ctx, out - j, j); + } +# else + while (len >= 16) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + for (i = 0; i < 16 / sizeof(size_t); ++i) + ctx->Xi.t[i] ^= out_t[i] = in_t[i] ^ ctx->EKi.t[i]; + GCM_MUL(ctx, Xi); + out += 16; + in += 16; + len -= 16; + } +# endif + if (len) { + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + while (len--) { + ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 0; + } while (0); + } +#endif + for (i = 0; i < len; ++i) { + if (n == 0) { + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +#ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +#else + PUTU32(ctx->Yi.c + 12, ctr); +#endif + else + ctx->Yi.d[3] = ctr; + } + ctx->Xi.c[n] ^= out[i] = in[i] ^ ctx->EKi.c[n]; + n = (n + 1) % 16; + if (n == 0) + GCM_MUL(ctx, Xi); + } + + ctx->mres = n; + return 0; +} + +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + unsigned int n, ctr; + size_t i; + u64 mlen = ctx->len.u[1]; + block128_f block = ctx->block; + void *key = ctx->key; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + + mlen += len; + if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) + return -1; + ctx->len.u[1] = mlen; + + if (ctx->ares) { + /* First call to decrypt finalizes GHASH(AAD) */ + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + if (is_endian.little) +#ifdef BSWAP4 + ctr = BSWAP4(ctx->Yi.d[3]); +#else + ctr = GETU32(ctx->Yi.c + 12); +#endif + else + ctr = ctx->Yi.d[3]; + + n = ctx->mres; +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) { /* always true actually */ + do { + if (n) { + while (n && len) { + u8 c = *(in++); + *(out++) = c ^ ctx->EKi.c[n]; + ctx->Xi.c[n] ^= c; + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->mres = n; + return 0; + } + } +# if defined(STRICT_ALIGNMENT) + if (((size_t)in | (size_t)out) % sizeof(size_t) != 0) + break; +# endif +# if defined(GHASH) && defined(GHASH_CHUNK) + while (len >= GHASH_CHUNK) { + size_t j = GHASH_CHUNK; + + GHASH(ctx, in, GHASH_CHUNK); + while (j) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + for (i = 0; i < 16 / sizeof(size_t); ++i) + out_t[i] = in_t[i] ^ ctx->EKi.t[i]; + out += 16; + in += 16; + j -= 16; + } + len -= GHASH_CHUNK; + } + if ((i = (len & (size_t)-16))) { + GHASH(ctx, in, i); + while (len >= 16) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + for (i = 0; i < 16 / sizeof(size_t); ++i) + out_t[i] = in_t[i] ^ ctx->EKi.t[i]; + out += 16; + in += 16; + len -= 16; + } + } +# else + while (len >= 16) { + size_t *out_t = (size_t *)out; + const size_t *in_t = (const size_t *)in; + + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + for (i = 0; i < 16 / sizeof(size_t); ++i) { + size_t c = in[i]; + out[i] = c ^ ctx->EKi.t[i]; + ctx->Xi.t[i] ^= c; + } + GCM_MUL(ctx, Xi); + out += 16; + in += 16; + len -= 16; + } +# endif + if (len) { + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + while (len--) { + u8 c = in[n]; + ctx->Xi.c[n] ^= c; + out[n] = c ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 0; + } while (0); + } +#endif + for (i = 0; i < len; ++i) { + u8 c; + if (n == 0) { + (*block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +#ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +#else + PUTU32(ctx->Yi.c + 12, ctr); +#endif + else + ctx->Yi.d[3] = ctr; + } + c = in[i]; + out[i] = c ^ ctx->EKi.c[n]; + ctx->Xi.c[n] ^= c; + n = (n + 1) % 16; + if (n == 0) + GCM_MUL(ctx, Xi); + } + + ctx->mres = n; + return 0; +} + +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + unsigned int n, ctr; + size_t i; + u64 mlen = ctx->len.u[1]; + void *key = ctx->key; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + + mlen += len; + if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) + return -1; + ctx->len.u[1] = mlen; + + if (ctx->ares) { + /* First call to encrypt finalizes GHASH(AAD) */ + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + if (is_endian.little) +#ifdef BSWAP4 + ctr = BSWAP4(ctx->Yi.d[3]); +#else + ctr = GETU32(ctx->Yi.c + 12); +#endif + else + ctr = ctx->Yi.d[3]; + + n = ctx->mres; + if (n) { + while (n && len) { + ctx->Xi.c[n] ^= *(out++) = *(in++) ^ ctx->EKi.c[n]; + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->mres = n; + return 0; + } + } +#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT) + while (len >= GHASH_CHUNK) { + (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); + ctr += GHASH_CHUNK / 16; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + GHASH(ctx, out, GHASH_CHUNK); + out += GHASH_CHUNK; + in += GHASH_CHUNK; + len -= GHASH_CHUNK; + } +#endif + if ((i = (len & (size_t)-16))) { + size_t j = i / 16; + + (*stream) (in, out, j, key, ctx->Yi.c); + ctr += (unsigned int)j; + if (is_endian.little) +#ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +#else + PUTU32(ctx->Yi.c + 12, ctr); +#endif + else + ctx->Yi.d[3] = ctr; + in += i; + len -= i; +#if defined(GHASH) + GHASH(ctx, out, i); + out += i; +#else + while (j--) { + for (i = 0; i < 16; ++i) + ctx->Xi.c[i] ^= out[i]; + GCM_MUL(ctx, Xi); + out += 16; + } +#endif + } + if (len) { + (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +#ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +#else + PUTU32(ctx->Yi.c + 12, ctr); +#endif + else + ctx->Yi.d[3] = ctr; + while (len--) { + ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 0; +} + +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + unsigned int n, ctr; + size_t i; + u64 mlen = ctx->len.u[1]; + void *key = ctx->key; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +# ifdef GHASH + void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx->ghash; +# endif +#endif + + mlen += len; + if (mlen > ((U64(1) << 36) - 32) || (sizeof(len) == 8 && mlen < len)) + return -1; + ctx->len.u[1] = mlen; + + if (ctx->ares) { + /* First call to decrypt finalizes GHASH(AAD) */ + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + if (is_endian.little) +#ifdef BSWAP4 + ctr = BSWAP4(ctx->Yi.d[3]); +#else + ctr = GETU32(ctx->Yi.c + 12); +#endif + else + ctr = ctx->Yi.d[3]; + + n = ctx->mres; + if (n) { + while (n && len) { + u8 c = *(in++); + *(out++) = c ^ ctx->EKi.c[n]; + ctx->Xi.c[n] ^= c; + --len; + n = (n + 1) % 16; + } + if (n == 0) + GCM_MUL(ctx, Xi); + else { + ctx->mres = n; + return 0; + } + } +#if defined(GHASH) && !defined(OPENSSL_SMALL_FOOTPRINT) + while (len >= GHASH_CHUNK) { + GHASH(ctx, in, GHASH_CHUNK); + (*stream) (in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); + ctr += GHASH_CHUNK / 16; + if (is_endian.little) +# ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +# else + PUTU32(ctx->Yi.c + 12, ctr); +# endif + else + ctx->Yi.d[3] = ctr; + out += GHASH_CHUNK; + in += GHASH_CHUNK; + len -= GHASH_CHUNK; + } +#endif + if ((i = (len & (size_t)-16))) { + size_t j = i / 16; + +#if defined(GHASH) + GHASH(ctx, in, i); +#else + while (j--) { + size_t k; + for (k = 0; k < 16; ++k) + ctx->Xi.c[k] ^= in[k]; + GCM_MUL(ctx, Xi); + in += 16; + } + j = i / 16; + in -= i; +#endif + (*stream) (in, out, j, key, ctx->Yi.c); + ctr += (unsigned int)j; + if (is_endian.little) +#ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +#else + PUTU32(ctx->Yi.c + 12, ctr); +#endif + else + ctx->Yi.d[3] = ctr; + out += i; + in += i; + len -= i; + } + if (len) { + (*ctx->block) (ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + if (is_endian.little) +#ifdef BSWAP4 + ctx->Yi.d[3] = BSWAP4(ctr); +#else + PUTU32(ctx->Yi.c + 12, ctr); +#endif + else + ctx->Yi.d[3] = ctr; + while (len--) { + u8 c = in[n]; + ctx->Xi.c[n] ^= c; + out[n] = c ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 0; +} + +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, + size_t len) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + u64 alen = ctx->len.u[0] << 3; + u64 clen = ctx->len.u[1] << 3; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p) (u64 Xi[2], const u128 Htable[16]) = ctx->gmult; +#endif + + if (ctx->mres || ctx->ares) + GCM_MUL(ctx, Xi); + + if (is_endian.little) { +#ifdef BSWAP8 + alen = BSWAP8(alen); + clen = BSWAP8(clen); +#else + u8 *p = ctx->len.c; + + ctx->len.u[0] = alen; + ctx->len.u[1] = clen; + + alen = (u64)GETU32(p) << 32 | GETU32(p + 4); + clen = (u64)GETU32(p + 8) << 32 | GETU32(p + 12); +#endif + } + + ctx->Xi.u[0] ^= alen; + ctx->Xi.u[1] ^= clen; + GCM_MUL(ctx, Xi); + + ctx->Xi.u[0] ^= ctx->EK0.u[0]; + ctx->Xi.u[1] ^= ctx->EK0.u[1]; + + if (tag && len <= sizeof(ctx->Xi)) + return CRYPTO_memcmp(ctx->Xi.c, tag, len); + else + return -1; +} + +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len) +{ + CRYPTO_gcm128_finish(ctx, NULL, 0); + memcpy(tag, ctx->Xi.c, + len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c)); +} + +GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block) +{ + GCM128_CONTEXT *ret; + + if ((ret = (GCM128_CONTEXT *)OPENSSL_malloc(sizeof(GCM128_CONTEXT)))) + CRYPTO_gcm128_init(ret, key, block); + + return ret; +} + +void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx) +{ + if (ctx) { + OPENSSL_cleanse(ctx, sizeof(*ctx)); + OPENSSL_free(ctx); + } +} + +#if defined(SELFTEST) +# include +# include + +/* Test Case 1 */ +static const u8 K1[16], *P1 = NULL, *A1 = NULL, IV1[12], *C1 = NULL; +static const u8 T1[] = { + 0x58, 0xe2, 0xfc, 0xce, 0xfa, 0x7e, 0x30, 0x61, + 0x36, 0x7f, 0x1d, 0x57, 0xa4, 0xe7, 0x45, 0x5a +}; + +/* Test Case 2 */ +# define K2 K1 +# define A2 A1 +# define IV2 IV1 +static const u8 P2[16]; +static const u8 C2[] = { + 0x03, 0x88, 0xda, 0xce, 0x60, 0xb6, 0xa3, 0x92, + 0xf3, 0x28, 0xc2, 0xb9, 0x71, 0xb2, 0xfe, 0x78 +}; + +static const u8 T2[] = { + 0xab, 0x6e, 0x47, 0xd4, 0x2c, 0xec, 0x13, 0xbd, + 0xf5, 0x3a, 0x67, 0xb2, 0x12, 0x57, 0xbd, 0xdf +}; + +/* Test Case 3 */ +# define A3 A2 +static const u8 K3[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 +}; + +static const u8 P3[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 +}; + +static const u8 IV3[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 +}; + +static const u8 C3[] = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91, 0x47, 0x3f, 0x59, 0x85 +}; + +static const u8 T3[] = { + 0x4d, 0x5c, 0x2a, 0xf3, 0x27, 0xcd, 0x64, 0xa6, + 0x2c, 0xf3, 0x5a, 0xbd, 0x2b, 0xa6, 0xfa, 0xb4 +}; + +/* Test Case 4 */ +# define K4 K3 +# define IV4 IV3 +static const u8 P4[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 +}; + +static const u8 A4[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 +}; + +static const u8 C4[] = { + 0x42, 0x83, 0x1e, 0xc2, 0x21, 0x77, 0x74, 0x24, + 0x4b, 0x72, 0x21, 0xb7, 0x84, 0xd0, 0xd4, 0x9c, + 0xe3, 0xaa, 0x21, 0x2f, 0x2c, 0x02, 0xa4, 0xe0, + 0x35, 0xc1, 0x7e, 0x23, 0x29, 0xac, 0xa1, 0x2e, + 0x21, 0xd5, 0x14, 0xb2, 0x54, 0x66, 0x93, 0x1c, + 0x7d, 0x8f, 0x6a, 0x5a, 0xac, 0x84, 0xaa, 0x05, + 0x1b, 0xa3, 0x0b, 0x39, 0x6a, 0x0a, 0xac, 0x97, + 0x3d, 0x58, 0xe0, 0x91 +}; + +static const u8 T4[] = { + 0x5b, 0xc9, 0x4f, 0xbc, 0x32, 0x21, 0xa5, 0xdb, + 0x94, 0xfa, 0xe9, 0x5a, 0xe7, 0x12, 0x1a, 0x47 +}; + +/* Test Case 5 */ +# define K5 K4 +# define P5 P4 +# define A5 A4 +static const u8 IV5[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad +}; + +static const u8 C5[] = { + 0x61, 0x35, 0x3b, 0x4c, 0x28, 0x06, 0x93, 0x4a, + 0x77, 0x7f, 0xf5, 0x1f, 0xa2, 0x2a, 0x47, 0x55, + 0x69, 0x9b, 0x2a, 0x71, 0x4f, 0xcd, 0xc6, 0xf8, + 0x37, 0x66, 0xe5, 0xf9, 0x7b, 0x6c, 0x74, 0x23, + 0x73, 0x80, 0x69, 0x00, 0xe4, 0x9f, 0x24, 0xb2, + 0x2b, 0x09, 0x75, 0x44, 0xd4, 0x89, 0x6b, 0x42, + 0x49, 0x89, 0xb5, 0xe1, 0xeb, 0xac, 0x0f, 0x07, + 0xc2, 0x3f, 0x45, 0x98 +}; + +static const u8 T5[] = { + 0x36, 0x12, 0xd2, 0xe7, 0x9e, 0x3b, 0x07, 0x85, + 0x56, 0x1b, 0xe1, 0x4a, 0xac, 0xa2, 0xfc, 0xcb +}; + +/* Test Case 6 */ +# define K6 K5 +# define P6 P5 +# define A6 A5 +static const u8 IV6[] = { + 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b +}; + +static const u8 C6[] = { + 0x8c, 0xe2, 0x49, 0x98, 0x62, 0x56, 0x15, 0xb6, + 0x03, 0xa0, 0x33, 0xac, 0xa1, 0x3f, 0xb8, 0x94, + 0xbe, 0x91, 0x12, 0xa5, 0xc3, 0xa2, 0x11, 0xa8, + 0xba, 0x26, 0x2a, 0x3c, 0xca, 0x7e, 0x2c, 0xa7, + 0x01, 0xe4, 0xa9, 0xa4, 0xfb, 0xa4, 0x3c, 0x90, + 0xcc, 0xdc, 0xb2, 0x81, 0xd4, 0x8c, 0x7c, 0x6f, + 0xd6, 0x28, 0x75, 0xd2, 0xac, 0xa4, 0x17, 0x03, + 0x4c, 0x34, 0xae, 0xe5 +}; + +static const u8 T6[] = { + 0x61, 0x9c, 0xc5, 0xae, 0xff, 0xfe, 0x0b, 0xfa, + 0x46, 0x2a, 0xf4, 0x3c, 0x16, 0x99, 0xd0, 0x50 +}; + +/* Test Case 7 */ +static const u8 K7[24], *P7 = NULL, *A7 = NULL, IV7[12], *C7 = NULL; +static const u8 T7[] = { + 0xcd, 0x33, 0xb2, 0x8a, 0xc7, 0x73, 0xf7, 0x4b, + 0xa0, 0x0e, 0xd1, 0xf3, 0x12, 0x57, 0x24, 0x35 +}; + +/* Test Case 8 */ +# define K8 K7 +# define IV8 IV7 +# define A8 A7 +static const u8 P8[16]; +static const u8 C8[] = { + 0x98, 0xe7, 0x24, 0x7c, 0x07, 0xf0, 0xfe, 0x41, + 0x1c, 0x26, 0x7e, 0x43, 0x84, 0xb0, 0xf6, 0x00 +}; + +static const u8 T8[] = { + 0x2f, 0xf5, 0x8d, 0x80, 0x03, 0x39, 0x27, 0xab, + 0x8e, 0xf4, 0xd4, 0x58, 0x75, 0x14, 0xf0, 0xfb +}; + +/* Test Case 9 */ +# define A9 A8 +static const u8 K9[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c +}; + +static const u8 P9[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 +}; + +static const u8 IV9[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 +}; + +static const u8 C9[] = { + 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10, 0xac, 0xad, 0xe2, 0x56 +}; + +static const u8 T9[] = { + 0x99, 0x24, 0xa7, 0xc8, 0x58, 0x73, 0x36, 0xbf, + 0xb1, 0x18, 0x02, 0x4d, 0xb8, 0x67, 0x4a, 0x14 +}; + +/* Test Case 10 */ +# define K10 K9 +# define IV10 IV9 +static const u8 P10[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 +}; + +static const u8 A10[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 +}; + +static const u8 C10[] = { + 0x39, 0x80, 0xca, 0x0b, 0x3c, 0x00, 0xe8, 0x41, + 0xeb, 0x06, 0xfa, 0xc4, 0x87, 0x2a, 0x27, 0x57, + 0x85, 0x9e, 0x1c, 0xea, 0xa6, 0xef, 0xd9, 0x84, + 0x62, 0x85, 0x93, 0xb4, 0x0c, 0xa1, 0xe1, 0x9c, + 0x7d, 0x77, 0x3d, 0x00, 0xc1, 0x44, 0xc5, 0x25, + 0xac, 0x61, 0x9d, 0x18, 0xc8, 0x4a, 0x3f, 0x47, + 0x18, 0xe2, 0x44, 0x8b, 0x2f, 0xe3, 0x24, 0xd9, + 0xcc, 0xda, 0x27, 0x10 +}; + +static const u8 T10[] = { + 0x25, 0x19, 0x49, 0x8e, 0x80, 0xf1, 0x47, 0x8f, + 0x37, 0xba, 0x55, 0xbd, 0x6d, 0x27, 0x61, 0x8c +}; + +/* Test Case 11 */ +# define K11 K10 +# define P11 P10 +# define A11 A10 +static const u8 IV11[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad }; + +static const u8 C11[] = { + 0x0f, 0x10, 0xf5, 0x99, 0xae, 0x14, 0xa1, 0x54, + 0xed, 0x24, 0xb3, 0x6e, 0x25, 0x32, 0x4d, 0xb8, + 0xc5, 0x66, 0x63, 0x2e, 0xf2, 0xbb, 0xb3, 0x4f, + 0x83, 0x47, 0x28, 0x0f, 0xc4, 0x50, 0x70, 0x57, + 0xfd, 0xdc, 0x29, 0xdf, 0x9a, 0x47, 0x1f, 0x75, + 0xc6, 0x65, 0x41, 0xd4, 0xd4, 0xda, 0xd1, 0xc9, + 0xe9, 0x3a, 0x19, 0xa5, 0x8e, 0x8b, 0x47, 0x3f, + 0xa0, 0xf0, 0x62, 0xf7 +}; + +static const u8 T11[] = { + 0x65, 0xdc, 0xc5, 0x7f, 0xcf, 0x62, 0x3a, 0x24, + 0x09, 0x4f, 0xcc, 0xa4, 0x0d, 0x35, 0x33, 0xf8 +}; + +/* Test Case 12 */ +# define K12 K11 +# define P12 P11 +# define A12 A11 +static const u8 IV12[] = { + 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b +}; + +static const u8 C12[] = { + 0xd2, 0x7e, 0x88, 0x68, 0x1c, 0xe3, 0x24, 0x3c, + 0x48, 0x30, 0x16, 0x5a, 0x8f, 0xdc, 0xf9, 0xff, + 0x1d, 0xe9, 0xa1, 0xd8, 0xe6, 0xb4, 0x47, 0xef, + 0x6e, 0xf7, 0xb7, 0x98, 0x28, 0x66, 0x6e, 0x45, + 0x81, 0xe7, 0x90, 0x12, 0xaf, 0x34, 0xdd, 0xd9, + 0xe2, 0xf0, 0x37, 0x58, 0x9b, 0x29, 0x2d, 0xb3, + 0xe6, 0x7c, 0x03, 0x67, 0x45, 0xfa, 0x22, 0xe7, + 0xe9, 0xb7, 0x37, 0x3b +}; + +static const u8 T12[] = { + 0xdc, 0xf5, 0x66, 0xff, 0x29, 0x1c, 0x25, 0xbb, + 0xb8, 0x56, 0x8f, 0xc3, 0xd3, 0x76, 0xa6, 0xd9 +}; + +/* Test Case 13 */ +static const u8 K13[32], *P13 = NULL, *A13 = NULL, IV13[12], *C13 = NULL; +static const u8 T13[] = { + 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, + 0xa9, 0x63, 0xb4, 0xf1, 0xc4, 0xcb, 0x73, 0x8b +}; + +/* Test Case 14 */ +# define K14 K13 +# define A14 A13 +static const u8 P14[16], IV14[12]; +static const u8 C14[] = { + 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, + 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18 +}; + +static const u8 T14[] = { + 0xd0, 0xd1, 0xc8, 0xa7, 0x99, 0x99, 0x6b, 0xf0, + 0x26, 0x5b, 0x98, 0xb5, 0xd4, 0x8a, 0xb9, 0x19 +}; + +/* Test Case 15 */ +# define A15 A14 +static const u8 K15[] = { + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08, + 0xfe, 0xff, 0xe9, 0x92, 0x86, 0x65, 0x73, 0x1c, + 0x6d, 0x6a, 0x8f, 0x94, 0x67, 0x30, 0x83, 0x08 +}; + +static const u8 P15[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55 +}; + +static const u8 IV15[] = { + 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad, + 0xde, 0xca, 0xf8, 0x88 +}; + +static const u8 C15[] = { + 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad +}; + +static const u8 T15[] = { + 0xb0, 0x94, 0xda, 0xc5, 0xd9, 0x34, 0x71, 0xbd, + 0xec, 0x1a, 0x50, 0x22, 0x70, 0xe3, 0xcc, 0x6c +}; + +/* Test Case 16 */ +# define K16 K15 +# define IV16 IV15 +static const u8 P16[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39 +}; + +static const u8 A16[] = { + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef, + 0xab, 0xad, 0xda, 0xd2 +}; + +static const u8 C16[] = { + 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62 +}; + +static const u8 T16[] = { + 0x76, 0xfc, 0x6e, 0xce, 0x0f, 0x4e, 0x17, 0x68, + 0xcd, 0xdf, 0x88, 0x53, 0xbb, 0x2d, 0x55, 0x1b +}; + +/* Test Case 17 */ +# define K17 K16 +# define P17 P16 +# define A17 A16 +static const u8 IV17[] = { 0xca, 0xfe, 0xba, 0xbe, 0xfa, 0xce, 0xdb, 0xad }; + +static const u8 C17[] = { + 0xc3, 0x76, 0x2d, 0xf1, 0xca, 0x78, 0x7d, 0x32, + 0xae, 0x47, 0xc1, 0x3b, 0xf1, 0x98, 0x44, 0xcb, + 0xaf, 0x1a, 0xe1, 0x4d, 0x0b, 0x97, 0x6a, 0xfa, + 0xc5, 0x2f, 0xf7, 0xd7, 0x9b, 0xba, 0x9d, 0xe0, + 0xfe, 0xb5, 0x82, 0xd3, 0x39, 0x34, 0xa4, 0xf0, + 0x95, 0x4c, 0xc2, 0x36, 0x3b, 0xc7, 0x3f, 0x78, + 0x62, 0xac, 0x43, 0x0e, 0x64, 0xab, 0xe4, 0x99, + 0xf4, 0x7c, 0x9b, 0x1f +}; + +static const u8 T17[] = { + 0x3a, 0x33, 0x7d, 0xbf, 0x46, 0xa7, 0x92, 0xc4, + 0x5e, 0x45, 0x49, 0x13, 0xfe, 0x2e, 0xa8, 0xf2 +}; + +/* Test Case 18 */ +# define K18 K17 +# define P18 P17 +# define A18 A17 +static const u8 IV18[] = { + 0x93, 0x13, 0x22, 0x5d, 0xf8, 0x84, 0x06, 0xe5, + 0x55, 0x90, 0x9c, 0x5a, 0xff, 0x52, 0x69, 0xaa, + 0x6a, 0x7a, 0x95, 0x38, 0x53, 0x4f, 0x7d, 0xa1, + 0xe4, 0xc3, 0x03, 0xd2, 0xa3, 0x18, 0xa7, 0x28, + 0xc3, 0xc0, 0xc9, 0x51, 0x56, 0x80, 0x95, 0x39, + 0xfc, 0xf0, 0xe2, 0x42, 0x9a, 0x6b, 0x52, 0x54, + 0x16, 0xae, 0xdb, 0xf5, 0xa0, 0xde, 0x6a, 0x57, + 0xa6, 0x37, 0xb3, 0x9b +}; + +static const u8 C18[] = { + 0x5a, 0x8d, 0xef, 0x2f, 0x0c, 0x9e, 0x53, 0xf1, + 0xf7, 0x5d, 0x78, 0x53, 0x65, 0x9e, 0x2a, 0x20, + 0xee, 0xb2, 0xb2, 0x2a, 0xaf, 0xde, 0x64, 0x19, + 0xa0, 0x58, 0xab, 0x4f, 0x6f, 0x74, 0x6b, 0xf4, + 0x0f, 0xc0, 0xc3, 0xb7, 0x80, 0xf2, 0x44, 0x45, + 0x2d, 0xa3, 0xeb, 0xf1, 0xc5, 0xd8, 0x2c, 0xde, + 0xa2, 0x41, 0x89, 0x97, 0x20, 0x0e, 0xf8, 0x2e, + 0x44, 0xae, 0x7e, 0x3f +}; + +static const u8 T18[] = { + 0xa4, 0x4a, 0x82, 0x66, 0xee, 0x1c, 0x8e, 0xb0, + 0xc8, 0xb5, 0xd4, 0xcf, 0x5a, 0xe9, 0xf1, 0x9a +}; + +/* Test Case 19 */ +# define K19 K1 +# define P19 P1 +# define IV19 IV1 +# define C19 C1 +static const u8 A19[] = { + 0xd9, 0x31, 0x32, 0x25, 0xf8, 0x84, 0x06, 0xe5, + 0xa5, 0x59, 0x09, 0xc5, 0xaf, 0xf5, 0x26, 0x9a, + 0x86, 0xa7, 0xa9, 0x53, 0x15, 0x34, 0xf7, 0xda, + 0x2e, 0x4c, 0x30, 0x3d, 0x8a, 0x31, 0x8a, 0x72, + 0x1c, 0x3c, 0x0c, 0x95, 0x95, 0x68, 0x09, 0x53, + 0x2f, 0xcf, 0x0e, 0x24, 0x49, 0xa6, 0xb5, 0x25, + 0xb1, 0x6a, 0xed, 0xf5, 0xaa, 0x0d, 0xe6, 0x57, + 0xba, 0x63, 0x7b, 0x39, 0x1a, 0xaf, 0xd2, 0x55, + 0x52, 0x2d, 0xc1, 0xf0, 0x99, 0x56, 0x7d, 0x07, + 0xf4, 0x7f, 0x37, 0xa3, 0x2a, 0x84, 0x42, 0x7d, + 0x64, 0x3a, 0x8c, 0xdc, 0xbf, 0xe5, 0xc0, 0xc9, + 0x75, 0x98, 0xa2, 0xbd, 0x25, 0x55, 0xd1, 0xaa, + 0x8c, 0xb0, 0x8e, 0x48, 0x59, 0x0d, 0xbb, 0x3d, + 0xa7, 0xb0, 0x8b, 0x10, 0x56, 0x82, 0x88, 0x38, + 0xc5, 0xf6, 0x1e, 0x63, 0x93, 0xba, 0x7a, 0x0a, + 0xbc, 0xc9, 0xf6, 0x62, 0x89, 0x80, 0x15, 0xad +}; + +static const u8 T19[] = { + 0x5f, 0xea, 0x79, 0x3a, 0x2d, 0x6f, 0x97, 0x4d, + 0x37, 0xe6, 0x8e, 0x0c, 0xb8, 0xff, 0x94, 0x92 +}; + +/* Test Case 20 */ +# define K20 K1 +# define A20 A1 +/* this results in 0xff in counter LSB */ +static const u8 IV20[64] = { 0xff, 0xff, 0xff, 0xff }; + +static const u8 P20[288]; +static const u8 C20[] = { + 0x56, 0xb3, 0x37, 0x3c, 0xa9, 0xef, 0x6e, 0x4a, + 0x2b, 0x64, 0xfe, 0x1e, 0x9a, 0x17, 0xb6, 0x14, + 0x25, 0xf1, 0x0d, 0x47, 0xa7, 0x5a, 0x5f, 0xce, + 0x13, 0xef, 0xc6, 0xbc, 0x78, 0x4a, 0xf2, 0x4f, + 0x41, 0x41, 0xbd, 0xd4, 0x8c, 0xf7, 0xc7, 0x70, + 0x88, 0x7a, 0xfd, 0x57, 0x3c, 0xca, 0x54, 0x18, + 0xa9, 0xae, 0xff, 0xcd, 0x7c, 0x5c, 0xed, 0xdf, + 0xc6, 0xa7, 0x83, 0x97, 0xb9, 0xa8, 0x5b, 0x49, + 0x9d, 0xa5, 0x58, 0x25, 0x72, 0x67, 0xca, 0xab, + 0x2a, 0xd0, 0xb2, 0x3c, 0xa4, 0x76, 0xa5, 0x3c, + 0xb1, 0x7f, 0xb4, 0x1c, 0x4b, 0x8b, 0x47, 0x5c, + 0xb4, 0xf3, 0xf7, 0x16, 0x50, 0x94, 0xc2, 0x29, + 0xc9, 0xe8, 0xc4, 0xdc, 0x0a, 0x2a, 0x5f, 0xf1, + 0x90, 0x3e, 0x50, 0x15, 0x11, 0x22, 0x13, 0x76, + 0xa1, 0xcd, 0xb8, 0x36, 0x4c, 0x50, 0x61, 0xa2, + 0x0c, 0xae, 0x74, 0xbc, 0x4a, 0xcd, 0x76, 0xce, + 0xb0, 0xab, 0xc9, 0xfd, 0x32, 0x17, 0xef, 0x9f, + 0x8c, 0x90, 0xbe, 0x40, 0x2d, 0xdf, 0x6d, 0x86, + 0x97, 0xf4, 0xf8, 0x80, 0xdf, 0xf1, 0x5b, 0xfb, + 0x7a, 0x6b, 0x28, 0x24, 0x1e, 0xc8, 0xfe, 0x18, + 0x3c, 0x2d, 0x59, 0xe3, 0xf9, 0xdf, 0xff, 0x65, + 0x3c, 0x71, 0x26, 0xf0, 0xac, 0xb9, 0xe6, 0x42, + 0x11, 0xf4, 0x2b, 0xae, 0x12, 0xaf, 0x46, 0x2b, + 0x10, 0x70, 0xbe, 0xf1, 0xab, 0x5e, 0x36, 0x06, + 0x87, 0x2c, 0xa1, 0x0d, 0xee, 0x15, 0xb3, 0x24, + 0x9b, 0x1a, 0x1b, 0x95, 0x8f, 0x23, 0x13, 0x4c, + 0x4b, 0xcc, 0xb7, 0xd0, 0x32, 0x00, 0xbc, 0xe4, + 0x20, 0xa2, 0xf8, 0xeb, 0x66, 0xdc, 0xf3, 0x64, + 0x4d, 0x14, 0x23, 0xc1, 0xb5, 0x69, 0x90, 0x03, + 0xc1, 0x3e, 0xce, 0xf4, 0xbf, 0x38, 0xa3, 0xb6, + 0x0e, 0xed, 0xc3, 0x40, 0x33, 0xba, 0xc1, 0x90, + 0x27, 0x83, 0xdc, 0x6d, 0x89, 0xe2, 0xe7, 0x74, + 0x18, 0x8a, 0x43, 0x9c, 0x7e, 0xbc, 0xc0, 0x67, + 0x2d, 0xbd, 0xa4, 0xdd, 0xcf, 0xb2, 0x79, 0x46, + 0x13, 0xb0, 0xbe, 0x41, 0x31, 0x5e, 0xf7, 0x78, + 0x70, 0x8a, 0x70, 0xee, 0x7d, 0x75, 0x16, 0x5c +}; + +static const u8 T20[] = { + 0x8b, 0x30, 0x7f, 0x6b, 0x33, 0x28, 0x6d, 0x0a, + 0xb0, 0x26, 0xa9, 0xed, 0x3f, 0xe1, 0xe8, 0x5f +}; + +# define TEST_CASE(n) do { \ + u8 out[sizeof(P##n)]; \ + AES_set_encrypt_key(K##n,sizeof(K##n)*8,&key); \ + CRYPTO_gcm128_init(&ctx,&key,(block128_f)AES_encrypt); \ + CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n)); \ + memset(out,0,sizeof(out)); \ + if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n)); \ + if (P##n) CRYPTO_gcm128_encrypt(&ctx,P##n,out,sizeof(out)); \ + if (CRYPTO_gcm128_finish(&ctx,T##n,16) || \ + (C##n && memcmp(out,C##n,sizeof(out)))) \ + ret++, printf ("encrypt test#%d failed.\n",n); \ + CRYPTO_gcm128_setiv(&ctx,IV##n,sizeof(IV##n)); \ + memset(out,0,sizeof(out)); \ + if (A##n) CRYPTO_gcm128_aad(&ctx,A##n,sizeof(A##n)); \ + if (C##n) CRYPTO_gcm128_decrypt(&ctx,C##n,out,sizeof(out)); \ + if (CRYPTO_gcm128_finish(&ctx,T##n,16) || \ + (P##n && memcmp(out,P##n,sizeof(out)))) \ + ret++, printf ("decrypt test#%d failed.\n",n); \ + } while(0) + +int main() +{ + GCM128_CONTEXT ctx; + AES_KEY key; + int ret = 0; + + TEST_CASE(1); + TEST_CASE(2); + TEST_CASE(3); + TEST_CASE(4); + TEST_CASE(5); + TEST_CASE(6); + TEST_CASE(7); + TEST_CASE(8); + TEST_CASE(9); + TEST_CASE(10); + TEST_CASE(11); + TEST_CASE(12); + TEST_CASE(13); + TEST_CASE(14); + TEST_CASE(15); + TEST_CASE(16); + TEST_CASE(17); + TEST_CASE(18); + TEST_CASE(19); + TEST_CASE(20); + +# ifdef OPENSSL_CPUID_OBJ + { + size_t start, stop, gcm_t, ctr_t, OPENSSL_rdtsc(); + union { + u64 u; + u8 c[1024]; + } buf; + int i; + + AES_set_encrypt_key(K1, sizeof(K1) * 8, &key); + CRYPTO_gcm128_init(&ctx, &key, (block128_f) AES_encrypt); + CRYPTO_gcm128_setiv(&ctx, IV1, sizeof(IV1)); + + CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf)); + start = OPENSSL_rdtsc(); + CRYPTO_gcm128_encrypt(&ctx, buf.c, buf.c, sizeof(buf)); + gcm_t = OPENSSL_rdtsc() - start; + + CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf), + &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres, + (block128_f) AES_encrypt); + start = OPENSSL_rdtsc(); + CRYPTO_ctr128_encrypt(buf.c, buf.c, sizeof(buf), + &key, ctx.Yi.c, ctx.EKi.c, &ctx.mres, + (block128_f) AES_encrypt); + ctr_t = OPENSSL_rdtsc() - start; + + printf("%.2f-%.2f=%.2f\n", + gcm_t / (double)sizeof(buf), + ctr_t / (double)sizeof(buf), + (gcm_t - ctr_t) / (double)sizeof(buf)); +# ifdef GHASH + { + void (*gcm_ghash_p) (u64 Xi[2], const u128 Htable[16], + const u8 *inp, size_t len) = ctx.ghash; + + GHASH((&ctx), buf.c, sizeof(buf)); + start = OPENSSL_rdtsc(); + for (i = 0; i < 100; ++i) + GHASH((&ctx), buf.c, sizeof(buf)); + gcm_t = OPENSSL_rdtsc() - start; + printf("%.2f\n", gcm_t / (double)sizeof(buf) / (double)i); + } +# endif + } +# endif + + return ret; +} +#endif diff --git a/libs/openssl/crypto/modes/modes.h b/libs/openssl/crypto/modes/modes.h new file mode 100644 index 00000000..880f020d --- /dev/null +++ b/libs/openssl/crypto/modes/modes.h @@ -0,0 +1,153 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Rights for redistribution and usage in source and binary + * forms are granted according to the OpenSSL license. + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif +typedef void (*block128_f) (const unsigned char in[16], + unsigned char out[16], const void *key); + +typedef void (*cbc128_f) (const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int enc); + +typedef void (*ctr128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16]); + +typedef void (*ccm128_f) (const unsigned char *in, unsigned char *out, + size_t blocks, const void *key, + const unsigned char ivec[16], + unsigned char cmac[16]); + +void CRYPTO_cbc128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); +void CRYPTO_cbc128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], block128_f block); + +void CRYPTO_ctr128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], unsigned int *num, + block128_f block); + +void CRYPTO_ctr128_encrypt_ctr32(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], + unsigned char ecount_buf[16], + unsigned int *num, ctr128_f ctr); + +void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + block128_f block); + +void CRYPTO_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_8_encrypt(const unsigned char *in, unsigned char *out, + size_t length, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); +void CRYPTO_cfb128_1_encrypt(const unsigned char *in, unsigned char *out, + size_t bits, const void *key, + unsigned char ivec[16], int *num, + int enc, block128_f block); + +size_t CRYPTO_cts128_encrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], + block128_f block); +size_t CRYPTO_cts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_cts128_decrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], + block128_f block); +size_t CRYPTO_cts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); + +size_t CRYPTO_nistcts128_encrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, + unsigned char ivec[16], + block128_f block); +size_t CRYPTO_nistcts128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); +size_t CRYPTO_nistcts128_decrypt_block(const unsigned char *in, + unsigned char *out, size_t len, + const void *key, + unsigned char ivec[16], + block128_f block); +size_t CRYPTO_nistcts128_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], cbc128_f cbc); + +typedef struct gcm128_context GCM128_CONTEXT; + +GCM128_CONTEXT *CRYPTO_gcm128_new(void *key, block128_f block); +void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, void *key, block128_f block); +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const unsigned char *iv, + size_t len); +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const unsigned char *aad, + size_t len); +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len); +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, + const unsigned char *in, unsigned char *out, + size_t len, ctr128_f stream); +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const unsigned char *tag, + size_t len); +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len); +void CRYPTO_gcm128_release(GCM128_CONTEXT *ctx); + +typedef struct ccm128_context CCM128_CONTEXT; + +void CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, + unsigned int M, unsigned int L, void *key, + block128_f block); +int CRYPTO_ccm128_setiv(CCM128_CONTEXT *ctx, const unsigned char *nonce, + size_t nlen, size_t mlen); +void CRYPTO_ccm128_aad(CCM128_CONTEXT *ctx, const unsigned char *aad, + size_t alen); +int CRYPTO_ccm128_encrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len); +int CRYPTO_ccm128_decrypt(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len); +int CRYPTO_ccm128_encrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len, + ccm128_f stream); +int CRYPTO_ccm128_decrypt_ccm64(CCM128_CONTEXT *ctx, const unsigned char *inp, + unsigned char *out, size_t len, + ccm128_f stream); +size_t CRYPTO_ccm128_tag(CCM128_CONTEXT *ctx, unsigned char *tag, size_t len); + +typedef struct xts128_context XTS128_CONTEXT; + +int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, + const unsigned char iv[16], + const unsigned char *inp, unsigned char *out, + size_t len, int enc); + +#ifdef __cplusplus +} +#endif diff --git a/libs/openssl/crypto/modes/modes_lcl.h b/libs/openssl/crypto/modes/modes_lcl.h new file mode 100644 index 00000000..296849b8 --- /dev/null +++ b/libs/openssl/crypto/modes/modes_lcl.h @@ -0,0 +1,133 @@ +/* ==================================================================== + * Copyright (c) 2010 The OpenSSL Project. All rights reserved. + * + * Redistribution and use is governed by OpenSSL license. + * ==================================================================== + */ + +#include + +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +typedef __int64 i64; +typedef unsigned __int64 u64; +# define U64(C) C##UI64 +#elif defined(__arch64__) +typedef long i64; +typedef unsigned long u64; +# define U64(C) C##UL +#else +typedef long long i64; +typedef unsigned long long u64; +# define U64(C) C##ULL +#endif + +typedef unsigned int u32; +typedef unsigned char u8; + +#define STRICT_ALIGNMENT 1 +#if defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) || \ + defined(__s390__) || defined(__s390x__) +# undef STRICT_ALIGNMENT +#endif + +#if !defined(PEDANTIC) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(__GNUC__) && __GNUC__>=2 +# if defined(__x86_64) || defined(__x86_64__) +# define BSWAP8(x) ({ u64 ret=(x); \ + asm ("bswapq %0" \ + : "+r"(ret)); ret; }) +# define BSWAP4(x) ({ u32 ret=(x); \ + asm ("bswapl %0" \ + : "+r"(ret)); ret; }) +# elif (defined(__i386) || defined(__i386__)) && !defined(I386_ONLY) +# define BSWAP8(x) ({ u32 lo=(u64)(x)>>32,hi=(x); \ + asm ("bswapl %0; bswapl %1" \ + : "+r"(hi),"+r"(lo)); \ + (u64)hi<<32|lo; }) +# define BSWAP4(x) ({ u32 ret=(x); \ + asm ("bswapl %0" \ + : "+r"(ret)); ret; }) +# elif (defined(__arm__) || defined(__arm)) && !defined(STRICT_ALIGNMENT) +# define BSWAP8(x) ({ u32 lo=(u64)(x)>>32,hi=(x); \ + asm ("rev %0,%0; rev %1,%1" \ + : "+r"(hi),"+r"(lo)); \ + (u64)hi<<32|lo; }) +# define BSWAP4(x) ({ u32 ret; \ + asm ("rev %0,%1" \ + : "=r"(ret) : "r"((u32)(x))); \ + ret; }) +# endif +# elif defined(_MSC_VER) +# if _MSC_VER>=1300 +# pragma intrinsic(_byteswap_uint64,_byteswap_ulong) +# define BSWAP8(x) _byteswap_uint64((u64)(x)) +# define BSWAP4(x) _byteswap_ulong((u32)(x)) +# elif defined(_M_IX86) +__inline u32 _bswap4(u32 val) +{ +_asm mov eax, val _asm bswap eax} +# define BSWAP4(x) _bswap4(x) +# endif +# endif +#endif +#if defined(BSWAP4) && !defined(STRICT_ALIGNMENT) +# define GETU32(p) BSWAP4(*(const u32 *)(p)) +# define PUTU32(p,v) *(u32 *)(p) = BSWAP4(v) +#else +# define GETU32(p) ((u32)(p)[0]<<24|(u32)(p)[1]<<16|(u32)(p)[2]<<8|(u32)(p)[3]) +# define PUTU32(p,v) ((p)[0]=(u8)((v)>>24),(p)[1]=(u8)((v)>>16),(p)[2]=(u8)((v)>>8),(p)[3]=(u8)(v)) +#endif +/*- GCM definitions */ typedef struct { + u64 hi, lo; +} u128; + +#ifdef TABLE_BITS +# undef TABLE_BITS +#endif +/* + * Even though permitted values for TABLE_BITS are 8, 4 and 1, it should + * never be set to 8 [or 1]. For further information see gcm128.c. + */ +#define TABLE_BITS 4 + +struct gcm128_context { + /* Following 6 names follow names in GCM specification */ + union { + u64 u[2]; + u32 d[4]; + u8 c[16]; + size_t t[16 / sizeof(size_t)]; + } Yi, EKi, EK0, len, Xi, H; + /* + * Relative position of Xi, H and pre-computed Htable is used in some + * assembler modules, i.e. don't change the order! + */ +#if TABLE_BITS==8 + u128 Htable[256]; +#else + u128 Htable[16]; + void (*gmult) (u64 Xi[2], const u128 Htable[16]); + void (*ghash) (u64 Xi[2], const u128 Htable[16], const u8 *inp, + size_t len); +#endif + unsigned int mres, ares; + block128_f block; + void *key; +}; + +struct xts128_context { + void *key1, *key2; + block128_f block1, block2; +}; + +struct ccm128_context { + union { + u64 u[2]; + u8 c[16]; + } nonce, cmac; + u64 blocks; + block128_f block; + void *key; +}; diff --git a/libs/openssl/crypto/modes/ofb128.c b/libs/openssl/crypto/modes/ofb128.c new file mode 100644 index 00000000..4dbaccd7 --- /dev/null +++ b/libs/openssl/crypto/modes/ofb128.c @@ -0,0 +1,124 @@ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +/* + * The input and output encrypted as though 128bit ofb mode is being used. + * The extra state information to record how much of the 128bit block we have + * used is contained in *num; + */ +void CRYPTO_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], int *num, block128_f block) +{ + unsigned int n; + size_t l = 0; + + assert(in && out && key && ivec && num); + + n = *num; + +#if !defined(OPENSSL_SMALL_FOOTPRINT) + if (16 % sizeof(size_t) == 0) { /* always true actually */ + do { + while (n && len) { + *(out++) = *(in++) ^ ivec[n]; + --len; + n = (n + 1) % 16; + } +# if defined(STRICT_ALIGNMENT) + if (((size_t)in | (size_t)out | (size_t)ivec) % sizeof(size_t) != + 0) + break; +# endif + while (len >= 16) { + (*block) (ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) + *(size_t *)(out + n) = + *(size_t *)(in + n) ^ *(size_t *)(ivec + n); + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block) (ivec, ivec, key); + while (len--) { + out[n] = in[n] ^ ivec[n]; + ++n; + } + } + *num = n; + return; + } while (0); + } + /* the rest would be commonly eliminated by x86* compiler */ +#endif + while (l < len) { + if (n == 0) { + (*block) (ivec, ivec, key); + } + out[l] = in[l] ^ ivec[n]; + ++l; + n = (n + 1) % 16; + } + + *num = n; +} diff --git a/libs/openssl/crypto/modes/xts128.c b/libs/openssl/crypto/modes/xts128.c new file mode 100644 index 00000000..8f2af588 --- /dev/null +++ b/libs/openssl/crypto/modes/xts128.c @@ -0,0 +1,204 @@ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include "modes_lcl.h" +#include + +#ifndef MODES_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif +#include + +int CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, + const unsigned char iv[16], + const unsigned char *inp, unsigned char *out, + size_t len, int enc) +{ + const union { + long one; + char little; + } is_endian = { + 1 + }; + union { + u64 u[2]; + u32 d[4]; + u8 c[16]; + } tweak, scratch; + unsigned int i; + + if (len < 16) + return -1; + + memcpy(tweak.c, iv, 16); + + (*ctx->block2) (tweak.c, tweak.c, ctx->key2); + + if (!enc && (len % 16)) + len -= 16; + + while (len >= 16) { +#if defined(STRICT_ALIGNMENT) + memcpy(scratch.c, inp, 16); + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; +#else + scratch.u[0] = ((u64 *)inp)[0] ^ tweak.u[0]; + scratch.u[1] = ((u64 *)inp)[1] ^ tweak.u[1]; +#endif + (*ctx->block1) (scratch.c, scratch.c, ctx->key1); +#if defined(STRICT_ALIGNMENT) + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + memcpy(out, scratch.c, 16); +#else + ((u64 *)out)[0] = scratch.u[0] ^= tweak.u[0]; + ((u64 *)out)[1] = scratch.u[1] ^= tweak.u[1]; +#endif + inp += 16; + out += 16; + len -= 16; + + if (len == 0) + return 0; + + if (is_endian.little) { + unsigned int carry, res; + + res = 0x87 & (((int)tweak.d[3]) >> 31); + carry = (unsigned int)(tweak.u[0] >> 63); + tweak.u[0] = (tweak.u[0] << 1) ^ res; + tweak.u[1] = (tweak.u[1] << 1) | carry; + } else { + size_t c; + + for (c = 0, i = 0; i < 16; ++i) { + /* + * + substitutes for |, because c is 1 bit + */ + c += ((size_t)tweak.c[i]) << 1; + tweak.c[i] = (u8)c; + c = c >> 8; + } + tweak.c[0] ^= (u8)(0x87 & (0 - c)); + } + } + if (enc) { + for (i = 0; i < len; ++i) { + u8 c = inp[i]; + out[i] = scratch.c[i]; + scratch.c[i] = c; + } + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + (*ctx->block1) (scratch.c, scratch.c, ctx->key1); + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + memcpy(out - 16, scratch.c, 16); + } else { + union { + u64 u[2]; + u8 c[16]; + } tweak1; + + if (is_endian.little) { + unsigned int carry, res; + + res = 0x87 & (((int)tweak.d[3]) >> 31); + carry = (unsigned int)(tweak.u[0] >> 63); + tweak1.u[0] = (tweak.u[0] << 1) ^ res; + tweak1.u[1] = (tweak.u[1] << 1) | carry; + } else { + size_t c; + + for (c = 0, i = 0; i < 16; ++i) { + /* + * + substitutes for |, because c is 1 bit + */ + c += ((size_t)tweak.c[i]) << 1; + tweak1.c[i] = (u8)c; + c = c >> 8; + } + tweak1.c[0] ^= (u8)(0x87 & (0 - c)); + } +#if defined(STRICT_ALIGNMENT) + memcpy(scratch.c, inp, 16); + scratch.u[0] ^= tweak1.u[0]; + scratch.u[1] ^= tweak1.u[1]; +#else + scratch.u[0] = ((u64 *)inp)[0] ^ tweak1.u[0]; + scratch.u[1] = ((u64 *)inp)[1] ^ tweak1.u[1]; +#endif + (*ctx->block1) (scratch.c, scratch.c, ctx->key1); + scratch.u[0] ^= tweak1.u[0]; + scratch.u[1] ^= tweak1.u[1]; + + for (i = 0; i < len; ++i) { + u8 c = inp[16 + i]; + out[16 + i] = scratch.c[i]; + scratch.c[i] = c; + } + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + (*ctx->block1) (scratch.c, scratch.c, ctx->key1); +#if defined(STRICT_ALIGNMENT) + scratch.u[0] ^= tweak.u[0]; + scratch.u[1] ^= tweak.u[1]; + memcpy(out, scratch.c, 16); +#else + ((u64 *)out)[0] = scratch.u[0] ^ tweak.u[0]; + ((u64 *)out)[1] = scratch.u[1] ^ tweak.u[1]; +#endif + } + + return 0; +} diff --git a/libs/openssl/crypto/o_dir.c b/libs/openssl/crypto/o_dir.c new file mode 100644 index 00000000..f9dbed87 --- /dev/null +++ b/libs/openssl/crypto/o_dir.c @@ -0,0 +1,86 @@ +/* crypto/o_dir.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +/* + * The routines really come from the Levitte Programming, so to make life + * simple, let's just use the raw files and hack the symbols to fit our + * namespace. + */ +#define LP_DIR_CTX OPENSSL_DIR_CTX +#define LP_dir_context_st OPENSSL_dir_context_st +#define LP_find_file OPENSSL_DIR_read +#define LP_find_file_end OPENSSL_DIR_end + +#include "o_dir.h" + +#define LPDIR_H +#if defined OPENSSL_SYS_UNIX || defined DJGPP +# include "LPdir_unix.c" +#elif defined OPENSSL_SYS_VMS +# include "LPdir_vms.c" +#elif defined OPENSSL_SYS_WIN32 +# include "LPdir_win32.c" +#elif defined OPENSSL_SYS_WINCE +# include "LPdir_wince.c" +#else +# include "LPdir_nyi.c" +#endif diff --git a/libs/openssl/crypto/o_dir.h b/libs/openssl/crypto/o_dir.h new file mode 100644 index 00000000..bf45a14d --- /dev/null +++ b/libs/openssl/crypto/o_dir.h @@ -0,0 +1,55 @@ +/* crypto/o_dir.h */ +/* + * Copied from Richard Levitte's (richard@levitte.org) LP library. All + * symbol names have been changed, with permission from the author. + */ + +/* $LP: LPlib/source/LPdir.h,v 1.1 2004/06/14 08:56:04 _cvs_levitte Exp $ */ +/* + * Copyright (c) 2004, Richard Levitte + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef O_DIR_H +# define O_DIR_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct OPENSSL_dir_context_st OPENSSL_DIR_CTX; + + /* + * returns NULL on error or end-of-directory. If it is end-of-directory, + * errno will be zero + */ +const char *OPENSSL_DIR_read(OPENSSL_DIR_CTX **ctx, const char *directory); + /* returns 1 on success, 0 on error */ +int OPENSSL_DIR_end(OPENSSL_DIR_CTX **ctx); + +#ifdef __cplusplus +} +#endif + +#endif /* LPDIR_H */ diff --git a/libs/openssl/crypto/o_dir_test.c b/libs/openssl/crypto/o_dir_test.c new file mode 100644 index 00000000..60436b72 --- /dev/null +++ b/libs/openssl/crypto/o_dir_test.c @@ -0,0 +1,68 @@ +/* crypto/o_dir.h */ +/* + * Copied from Richard Levitte's (richard@levitte.org) LP library. All + * symbol names have been changed, with permission from the author. + */ + +/* $LP: LPlib/test/test_dir.c,v 1.1 2004/06/16 22:59:47 _cvs_levitte Exp $ */ +/* + * Copyright (c) 2004, Richard Levitte + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include "e_os2.h" +#include "o_dir.h" + +#if defined OPENSSL_SYS_UNIX || defined OPENSSL_SYS_WIN32 || defined OPENSSL_SYS_WINCE +# define CURRDIR "." +#elif defined OPENSSL_SYS_VMS +# define CURRDIR "SYS$DISK:[]" +#else +# error "No supported platform defined!" +#endif + +int main() +{ + OPENSSL_DIR_CTX *ctx = NULL; + const char *result; + + while ((result = OPENSSL_DIR_read(&ctx, CURRDIR)) != NULL) { + printf("%s\n", result); + } + + if (errno) { + perror("test_dir"); + exit(1); + } + + if (!OPENSSL_DIR_end(&ctx)) { + perror("test_dir"); + exit(2); + } + exit(0); +} diff --git a/libs/openssl/crypto/o_fips.c b/libs/openssl/crypto/o_fips.c new file mode 100644 index 00000000..f56d5bb7 --- /dev/null +++ b/libs/openssl/crypto/o_fips.c @@ -0,0 +1,96 @@ +/* + * Written by Stephen henson (steve@openssl.org) for the OpenSSL project + * 2011. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#ifdef OPENSSL_FIPS +# include +# include +# include +#endif + +int FIPS_mode(void) +{ + OPENSSL_init(); +#ifdef OPENSSL_FIPS + return FIPS_module_mode(); +#else + return 0; +#endif +} + +int FIPS_mode_set(int r) +{ + OPENSSL_init(); +#ifdef OPENSSL_FIPS +# ifndef FIPS_AUTH_USER_PASS +# define FIPS_AUTH_USER_PASS "Default FIPS Crypto User Password" +# endif + if (!FIPS_module_mode_set(r, FIPS_AUTH_USER_PASS)) + return 0; + if (r) + RAND_set_rand_method(FIPS_rand_get_method()); + else + RAND_set_rand_method(NULL); + return 1; +#else + if (r == 0) + return 1; + CRYPTOerr(CRYPTO_F_FIPS_MODE_SET, CRYPTO_R_FIPS_MODE_NOT_SUPPORTED); + return 0; +#endif +} diff --git a/libs/openssl/crypto/o_init.c b/libs/openssl/crypto/o_init.c new file mode 100644 index 00000000..20883881 --- /dev/null +++ b/libs/openssl/crypto/o_init.c @@ -0,0 +1,83 @@ +/* o_init.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#ifdef OPENSSL_FIPS +# include +# include +#endif + +/* + * Perform any essential OpenSSL initialization operations. Currently only + * sets FIPS callbacks + */ + +void OPENSSL_init(void) +{ + static int done = 0; + if (done) + return; + done = 1; +#ifdef OPENSSL_FIPS + FIPS_set_locking_callbacks(CRYPTO_lock, CRYPTO_add_lock); + FIPS_set_error_callbacks(ERR_put_error, ERR_add_error_vdata); + FIPS_set_malloc_callbacks(CRYPTO_malloc, CRYPTO_free); + RAND_init_fips(); +#endif +#if 0 + fprintf(stderr, "Called OPENSSL_init\n"); +#endif +} diff --git a/libs/openssl/crypto/o_str.c b/libs/openssl/crypto/o_str.c new file mode 100644 index 00000000..fd4087ff --- /dev/null +++ b/libs/openssl/crypto/o_str.c @@ -0,0 +1,116 @@ +/* crypto/o_str.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2003. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "o_str.h" + +#if !defined(OPENSSL_IMPLEMENTS_strncasecmp) && \ + !defined(OPENSSL_SYSNAME_WIN32) && \ + !defined(NETWARE_CLIB) +# include +#endif + +int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n) +{ +#if defined(OPENSSL_IMPLEMENTS_strncasecmp) + while (*str1 && *str2 && n) { + int res = toupper(*str1) - toupper(*str2); + if (res) + return res < 0 ? -1 : 1; + str1++; + str2++; + n--; + } + if (n == 0) + return 0; + if (*str1) + return 1; + if (*str2) + return -1; + return 0; +#else + /* + * Recursion hazard warning! Whenever strncasecmp is #defined as + * OPENSSL_strncasecmp, OPENSSL_IMPLEMENTS_strncasecmp must be defined as + * well. + */ + return strncasecmp(str1, str2, n); +#endif +} + +int OPENSSL_strcasecmp(const char *str1, const char *str2) +{ +#if defined(OPENSSL_IMPLEMENTS_strncasecmp) + return OPENSSL_strncasecmp(str1, str2, (size_t)-1); +#else + return strcasecmp(str1, str2); +#endif +} + +int OPENSSL_memcmp(const void *v1, const void *v2, size_t n) +{ + const unsigned char *c1 = v1, *c2 = v2; + int ret = 0; + + while (n && (ret = *c1 - *c2) == 0) + n--, c1++, c2++; + + return ret; +} diff --git a/libs/openssl/crypto/o_str.h b/libs/openssl/crypto/o_str.h new file mode 100644 index 00000000..fa512eb3 --- /dev/null +++ b/libs/openssl/crypto/o_str.h @@ -0,0 +1,69 @@ +/* crypto/o_str.h */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2003. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_O_STR_H +# define HEADER_O_STR_H + +# include /* to get size_t */ + +int OPENSSL_strcasecmp(const char *str1, const char *str2); +int OPENSSL_strncasecmp(const char *str1, const char *str2, size_t n); +int OPENSSL_memcmp(const void *p1, const void *p2, size_t n); + +#endif diff --git a/libs/openssl/crypto/o_time.c b/libs/openssl/crypto/o_time.c new file mode 100644 index 00000000..297bfafa --- /dev/null +++ b/libs/openssl/crypto/o_time.c @@ -0,0 +1,380 @@ +/* crypto/o_time.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2008. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "o_time.h" + +#ifdef OPENSSL_SYS_VMS +# if __CRTL_VER >= 70000000 && \ + (defined _POSIX_C_SOURCE || !defined _ANSI_C_SOURCE) +# define VMS_GMTIME_OK +# endif +# ifndef VMS_GMTIME_OK +# include +# include +# include +# include +# include +# include +# endif /* ndef VMS_GMTIME_OK */ +#endif + +struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result) +{ + struct tm *ts = NULL; + +#if defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_OS2) && (!defined(OPENSSL_SYS_VMS) || defined(gmtime_r)) && !defined(OPENSSL_SYS_MACOSX) && !defined(OPENSSL_SYS_SUNOS) + /* + * should return &data, but doesn't on some systems, so we don't even + * look at the return value + */ + gmtime_r(timer, result); + ts = result; +#elif !defined(OPENSSL_SYS_VMS) || defined(VMS_GMTIME_OK) + ts = gmtime(timer); + if (ts == NULL) + return NULL; + + memcpy(result, ts, sizeof(struct tm)); + ts = result; +#endif +#if defined( OPENSSL_SYS_VMS) && !defined( VMS_GMTIME_OK) + if (ts == NULL) { + static $DESCRIPTOR(tabnam, "LNM$DCL_LOGICAL"); + static $DESCRIPTOR(lognam, "SYS$TIMEZONE_DIFFERENTIAL"); + char logvalue[256]; + unsigned int reslen = 0; + struct { + short buflen; + short code; + void *bufaddr; + unsigned int *reslen; + } itemlist[] = { + { + 0, LNM$_STRING, 0, 0 + }, + { + 0, 0, 0, 0 + }, + }; + int status; + time_t t; + + /* Get the value for SYS$TIMEZONE_DIFFERENTIAL */ + itemlist[0].buflen = sizeof(logvalue); + itemlist[0].bufaddr = logvalue; + itemlist[0].reslen = &reslen; + status = sys$trnlnm(0, &tabnam, &lognam, 0, itemlist); + if (!(status & 1)) + return NULL; + logvalue[reslen] = '\0'; + + t = *timer; + +/* The following is extracted from the DEC C header time.h */ + /* + ** Beginning in OpenVMS Version 7.0 mktime, time, ctime, strftime + ** have two implementations. One implementation is provided + ** for compatibility and deals with time in terms of local time, + ** the other __utc_* deals with time in terms of UTC. + */ + /* + * We use the same conditions as in said time.h to check if we should + * assume that t contains local time (and should therefore be + * adjusted) or UTC (and should therefore be left untouched). + */ +# if __CRTL_VER < 70000000 || defined _VMS_V6_SOURCE + /* Get the numerical value of the equivalence string */ + status = atoi(logvalue); + + /* and use it to move time to GMT */ + t -= status; +# endif + + /* then convert the result to the time structure */ + + /* + * Since there was no gmtime_r() to do this stuff for us, we have to + * do it the hard way. + */ + { + /*- + * The VMS epoch is the astronomical Smithsonian date, + if I remember correctly, which is November 17, 1858. + Furthermore, time is measure in thenths of microseconds + and stored in quadwords (64 bit integers). unix_epoch + below is January 1st 1970 expressed as a VMS time. The + following code was used to get this number: + + #include + #include + #include + #include + + main() + { + unsigned long systime[2]; + unsigned short epoch_values[7] = + { 1970, 1, 1, 0, 0, 0, 0 }; + + lib$cvt_vectim(epoch_values, systime); + + printf("%u %u", systime[0], systime[1]); + } + */ + unsigned long unix_epoch[2] = { 1273708544, 8164711 }; + unsigned long deltatime[2]; + unsigned long systime[2]; + struct vms_vectime { + short year, month, day, hour, minute, second, centi_second; + } time_values; + long operation; + + /* + * Turn the number of seconds since January 1st 1970 to an + * internal delta time. Note that lib$cvt_to_internal_time() will + * assume that t is signed, and will therefore break on 32-bit + * systems some time in 2038. + */ + operation = LIB$K_DELTA_SECONDS; + status = lib$cvt_to_internal_time(&operation, &t, deltatime); + + /* + * Add the delta time with the Unix epoch and we have the current + * UTC time in internal format + */ + status = lib$add_times(unix_epoch, deltatime, systime); + + /* Turn the internal time into a time vector */ + status = sys$numtim(&time_values, systime); + + /* Fill in the struct tm with the result */ + result->tm_sec = time_values.second; + result->tm_min = time_values.minute; + result->tm_hour = time_values.hour; + result->tm_mday = time_values.day; + result->tm_mon = time_values.month - 1; + result->tm_year = time_values.year - 1900; + + operation = LIB$K_DAY_OF_WEEK; + status = lib$cvt_from_internal_time(&operation, + &result->tm_wday, systime); + result->tm_wday %= 7; + + operation = LIB$K_DAY_OF_YEAR; + status = lib$cvt_from_internal_time(&operation, + &result->tm_yday, systime); + result->tm_yday--; + + result->tm_isdst = 0; /* There's no way to know... */ + + ts = result; + } + } +#endif + return ts; +} + +/* + * Take a tm structure and add an offset to it. This avoids any OS issues + * with restricted date types and overflows which cause the year 2038 + * problem. + */ + +#define SECS_PER_DAY (24 * 60 * 60) + +static long date_to_julian(int y, int m, int d); +static void julian_to_date(long jd, int *y, int *m, int *d); + +int OPENSSL_gmtime_adj(struct tm *tm, int off_day, long offset_sec) +{ + int offset_hms, offset_day; + long time_jd; + int time_year, time_month, time_day; + /* split offset into days and day seconds */ + offset_day = offset_sec / SECS_PER_DAY; + /* Avoid sign issues with % operator */ + offset_hms = offset_sec - (offset_day * SECS_PER_DAY); + offset_day += off_day; + /* Add current time seconds to offset */ + offset_hms += tm->tm_hour * 3600 + tm->tm_min * 60 + tm->tm_sec; + /* Adjust day seconds if overflow */ + if (offset_hms >= SECS_PER_DAY) { + offset_day++; + offset_hms -= SECS_PER_DAY; + } else if (offset_hms < 0) { + offset_day--; + offset_hms += SECS_PER_DAY; + } + + /* + * Convert date of time structure into a Julian day number. + */ + + time_year = tm->tm_year + 1900; + time_month = tm->tm_mon + 1; + time_day = tm->tm_mday; + + time_jd = date_to_julian(time_year, time_month, time_day); + + /* Work out Julian day of new date */ + time_jd += offset_day; + + if (time_jd < 0) + return 0; + + /* Convert Julian day back to date */ + + julian_to_date(time_jd, &time_year, &time_month, &time_day); + + if (time_year < 1900 || time_year > 9999) + return 0; + + /* Update tm structure */ + + tm->tm_year = time_year - 1900; + tm->tm_mon = time_month - 1; + tm->tm_mday = time_day; + + tm->tm_hour = offset_hms / 3600; + tm->tm_min = (offset_hms / 60) % 60; + tm->tm_sec = offset_hms % 60; + + return 1; + +} + +/* + * Convert date to and from julian day Uses Fliegel & Van Flandern algorithm + */ +static long date_to_julian(int y, int m, int d) +{ + return (1461 * (y + 4800 + (m - 14) / 12)) / 4 + + (367 * (m - 2 - 12 * ((m - 14) / 12))) / 12 - + (3 * ((y + 4900 + (m - 14) / 12) / 100)) / 4 + d - 32075; +} + +static void julian_to_date(long jd, int *y, int *m, int *d) +{ + long L = jd + 68569; + long n = (4 * L) / 146097; + long i, j; + + L = L - (146097 * n + 3) / 4; + i = (4000 * (L + 1)) / 1461001; + L = L - (1461 * i) / 4 + 31; + j = (80 * L) / 2447; + *d = L - (2447 * j) / 80; + L = j / 11; + *m = j + 2 - (12 * L); + *y = 100 * (n - 49) + i + L; +} + +#ifdef OPENSSL_TIME_TEST + +# include + +/* + * Time checking test code. Check times are identical for a wide range of + * offsets. This should be run on a machine with 64 bit time_t or it will + * trigger the very errors the routines fix. + */ + +int main(int argc, char **argv) +{ + long offset; + for (offset = 0; offset < 1000000; offset++) { + check_time(offset); + check_time(-offset); + check_time(offset * 1000); + check_time(-offset * 1000); + } +} + +int check_time(long offset) +{ + struct tm tm1, tm2; + time_t t1, t2; + time(&t1); + t2 = t1 + offset; + OPENSSL_gmtime(&t2, &tm2); + OPENSSL_gmtime(&t1, &tm1); + OPENSSL_gmtime_adj(&tm1, 0, offset); + if ((tm1.tm_year == tm2.tm_year) && + (tm1.tm_mon == tm2.tm_mon) && + (tm1.tm_mday == tm2.tm_mday) && + (tm1.tm_hour == tm2.tm_hour) && + (tm1.tm_min == tm2.tm_min) && (tm1.tm_sec == tm2.tm_sec)) + return 1; + fprintf(stderr, "TIME ERROR!!\n"); + fprintf(stderr, "Time1: %d/%d/%d, %d:%02d:%02d\n", + tm2.tm_mday, tm2.tm_mon + 1, tm2.tm_year + 1900, + tm2.tm_hour, tm2.tm_min, tm2.tm_sec); + fprintf(stderr, "Time2: %d/%d/%d, %d:%02d:%02d\n", + tm1.tm_mday, tm1.tm_mon + 1, tm1.tm_year + 1900, + tm1.tm_hour, tm1.tm_min, tm1.tm_sec); + return 0; +} + +#endif diff --git a/libs/openssl/crypto/o_time.h b/libs/openssl/crypto/o_time.h new file mode 100644 index 00000000..8e49e66b --- /dev/null +++ b/libs/openssl/crypto/o_time.h @@ -0,0 +1,68 @@ +/* crypto/o_time.h */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_O_TIME_H +# define HEADER_O_TIME_H + +# include + +struct tm *OPENSSL_gmtime(const time_t *timer, struct tm *result); +int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec); + +#endif diff --git a/libs/openssl/crypto/objects/o_names.c b/libs/openssl/crypto/objects/o_names.c new file mode 100644 index 00000000..24859926 --- /dev/null +++ b/libs/openssl/crypto/objects/o_names.c @@ -0,0 +1,366 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +/* + * Later versions of DEC C has started to add lnkage information to certain + * functions, which makes it tricky to use them as values to regular function + * pointers. One way is to define a macro that takes care of casting them + * correctly. + */ +#ifdef OPENSSL_SYS_VMS_DECC +# define OPENSSL_strcmp (int (*)(const char *,const char *))strcmp +#else +# define OPENSSL_strcmp strcmp +#endif + +/* + * I use the ex_data stuff to manage the identifiers for the obj_name_types + * that applications may define. I only really use the free function field. + */ +DECLARE_LHASH_OF(OBJ_NAME); +static LHASH_OF(OBJ_NAME) *names_lh = NULL; +static int names_type_num = OBJ_NAME_TYPE_NUM; + +typedef struct name_funcs_st { + unsigned long (*hash_func) (const char *name); + int (*cmp_func) (const char *a, const char *b); + void (*free_func) (const char *, int, const char *); +} NAME_FUNCS; + +DECLARE_STACK_OF(NAME_FUNCS) +IMPLEMENT_STACK_OF(NAME_FUNCS) + +static STACK_OF(NAME_FUNCS) *name_funcs_stack; + +/* + * The LHASH callbacks now use the raw "void *" prototypes and do + * per-variable casting in the functions. This prevents function pointer + * casting without the need for macro-generated wrapper functions. + */ + +/* static unsigned long obj_name_hash(OBJ_NAME *a); */ +static unsigned long obj_name_hash(const void *a_void); +/* static int obj_name_cmp(OBJ_NAME *a,OBJ_NAME *b); */ +static int obj_name_cmp(const void *a_void, const void *b_void); + +static IMPLEMENT_LHASH_HASH_FN(obj_name, OBJ_NAME) +static IMPLEMENT_LHASH_COMP_FN(obj_name, OBJ_NAME) + +int OBJ_NAME_init(void) +{ + if (names_lh != NULL) + return (1); + MemCheck_off(); + names_lh = lh_OBJ_NAME_new(); + MemCheck_on(); + return (names_lh != NULL); +} + +int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), + int (*cmp_func) (const char *, const char *), + void (*free_func) (const char *, int, const char *)) +{ + int ret; + int i; + NAME_FUNCS *name_funcs; + + if (name_funcs_stack == NULL) { + MemCheck_off(); + name_funcs_stack = sk_NAME_FUNCS_new_null(); + MemCheck_on(); + } + if (name_funcs_stack == NULL) { + /* ERROR */ + return (0); + } + ret = names_type_num; + names_type_num++; + for (i = sk_NAME_FUNCS_num(name_funcs_stack); i < names_type_num; i++) { + MemCheck_off(); + name_funcs = OPENSSL_malloc(sizeof(NAME_FUNCS)); + MemCheck_on(); + if (!name_funcs) { + OBJerr(OBJ_F_OBJ_NAME_NEW_INDEX, ERR_R_MALLOC_FAILURE); + return (0); + } + name_funcs->hash_func = lh_strhash; + name_funcs->cmp_func = OPENSSL_strcmp; + name_funcs->free_func = 0; /* NULL is often declared to * ((void + * *)0), which according * to Compaq C is + * not really * compatible with a function + * * pointer. -- Richard Levitte */ + MemCheck_off(); + sk_NAME_FUNCS_push(name_funcs_stack, name_funcs); + MemCheck_on(); + } + name_funcs = sk_NAME_FUNCS_value(name_funcs_stack, ret); + if (hash_func != NULL) + name_funcs->hash_func = hash_func; + if (cmp_func != NULL) + name_funcs->cmp_func = cmp_func; + if (free_func != NULL) + name_funcs->free_func = free_func; + return (ret); +} + +/* static int obj_name_cmp(OBJ_NAME *a, OBJ_NAME *b) */ +static int obj_name_cmp(const void *a_void, const void *b_void) +{ + int ret; + const OBJ_NAME *a = (const OBJ_NAME *)a_void; + const OBJ_NAME *b = (const OBJ_NAME *)b_void; + + ret = a->type - b->type; + if (ret == 0) { + if ((name_funcs_stack != NULL) + && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) { + ret = sk_NAME_FUNCS_value(name_funcs_stack, + a->type)->cmp_func(a->name, b->name); + } else + ret = strcmp(a->name, b->name); + } + return (ret); +} + +/* static unsigned long obj_name_hash(OBJ_NAME *a) */ +static unsigned long obj_name_hash(const void *a_void) +{ + unsigned long ret; + const OBJ_NAME *a = (const OBJ_NAME *)a_void; + + if ((name_funcs_stack != NULL) + && (sk_NAME_FUNCS_num(name_funcs_stack) > a->type)) { + ret = + sk_NAME_FUNCS_value(name_funcs_stack, + a->type)->hash_func(a->name); + } else { + ret = lh_strhash(a->name); + } + ret ^= a->type; + return (ret); +} + +const char *OBJ_NAME_get(const char *name, int type) +{ + OBJ_NAME on, *ret; + int num = 0, alias; + + if (name == NULL) + return (NULL); + if ((names_lh == NULL) && !OBJ_NAME_init()) + return (NULL); + + alias = type & OBJ_NAME_ALIAS; + type &= ~OBJ_NAME_ALIAS; + + on.name = name; + on.type = type; + + for (;;) { + ret = lh_OBJ_NAME_retrieve(names_lh, &on); + if (ret == NULL) + return (NULL); + if ((ret->alias) && !alias) { + if (++num > 10) + return (NULL); + on.name = ret->data; + } else { + return (ret->data); + } + } +} + +int OBJ_NAME_add(const char *name, int type, const char *data) +{ + OBJ_NAME *onp, *ret; + int alias; + + if ((names_lh == NULL) && !OBJ_NAME_init()) + return (0); + + alias = type & OBJ_NAME_ALIAS; + type &= ~OBJ_NAME_ALIAS; + + onp = (OBJ_NAME *)OPENSSL_malloc(sizeof(OBJ_NAME)); + if (onp == NULL) { + /* ERROR */ + return (0); + } + + onp->name = name; + onp->alias = alias; + onp->type = type; + onp->data = data; + + ret = lh_OBJ_NAME_insert(names_lh, onp); + if (ret != NULL) { + /* free things */ + if ((name_funcs_stack != NULL) + && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) { + /* + * XXX: I'm not sure I understand why the free function should + * get three arguments... -- Richard Levitte + */ + sk_NAME_FUNCS_value(name_funcs_stack, + ret->type)->free_func(ret->name, ret->type, + ret->data); + } + OPENSSL_free(ret); + } else { + if (lh_OBJ_NAME_error(names_lh)) { + /* ERROR */ + return (0); + } + } + return (1); +} + +int OBJ_NAME_remove(const char *name, int type) +{ + OBJ_NAME on, *ret; + + if (names_lh == NULL) + return (0); + + type &= ~OBJ_NAME_ALIAS; + on.name = name; + on.type = type; + ret = lh_OBJ_NAME_delete(names_lh, &on); + if (ret != NULL) { + /* free things */ + if ((name_funcs_stack != NULL) + && (sk_NAME_FUNCS_num(name_funcs_stack) > ret->type)) { + /* + * XXX: I'm not sure I understand why the free function should + * get three arguments... -- Richard Levitte + */ + sk_NAME_FUNCS_value(name_funcs_stack, + ret->type)->free_func(ret->name, ret->type, + ret->data); + } + OPENSSL_free(ret); + return (1); + } else + return (0); +} + +struct doall { + int type; + void (*fn) (const OBJ_NAME *, void *arg); + void *arg; +}; + +static void do_all_fn_doall_arg(const OBJ_NAME *name, struct doall *d) +{ + if (name->type == d->type) + d->fn(name, d->arg); +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(do_all_fn, const OBJ_NAME, struct doall) + +void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg), + void *arg) +{ + struct doall d; + + d.type = type; + d.fn = fn; + d.arg = arg; + + lh_OBJ_NAME_doall_arg(names_lh, LHASH_DOALL_ARG_FN(do_all_fn), + struct doall, &d); +} + +struct doall_sorted { + int type; + int n; + const OBJ_NAME **names; +}; + +static void do_all_sorted_fn(const OBJ_NAME *name, void *d_) +{ + struct doall_sorted *d = d_; + + if (name->type != d->type) + return; + + d->names[d->n++] = name; +} + +static int do_all_sorted_cmp(const void *n1_, const void *n2_) +{ + const OBJ_NAME *const *n1 = n1_; + const OBJ_NAME *const *n2 = n2_; + + return strcmp((*n1)->name, (*n2)->name); +} + +void OBJ_NAME_do_all_sorted(int type, + void (*fn) (const OBJ_NAME *, void *arg), + void *arg) +{ + struct doall_sorted d; + int n; + + d.type = type; + d.names = + OPENSSL_malloc(lh_OBJ_NAME_num_items(names_lh) * sizeof *d.names); + /* Really should return an error if !d.names...but its a void function! */ + if (d.names) { + d.n = 0; + OBJ_NAME_do_all(type, do_all_sorted_fn, &d); + + qsort((void *)d.names, d.n, sizeof *d.names, do_all_sorted_cmp); + + for (n = 0; n < d.n; ++n) + fn(d.names[n], arg); + + OPENSSL_free((void *)d.names); + } +} + +static int free_type; + +static void names_lh_free_doall(OBJ_NAME *onp) +{ + if (onp == NULL) + return; + + if (free_type < 0 || free_type == onp->type) + OBJ_NAME_remove(onp->name, onp->type); +} + +static IMPLEMENT_LHASH_DOALL_FN(names_lh_free, OBJ_NAME) + +static void name_funcs_free(NAME_FUNCS *ptr) +{ + OPENSSL_free(ptr); +} + +void OBJ_NAME_cleanup(int type) +{ + unsigned long down_load; + + if (names_lh == NULL) + return; + + free_type = type; + down_load = lh_OBJ_NAME_down_load(names_lh); + lh_OBJ_NAME_down_load(names_lh) = 0; + + lh_OBJ_NAME_doall(names_lh, LHASH_DOALL_FN(names_lh_free)); + if (type < 0) { + lh_OBJ_NAME_free(names_lh); + sk_NAME_FUNCS_pop_free(name_funcs_stack, name_funcs_free); + names_lh = NULL; + name_funcs_stack = NULL; + } else + lh_OBJ_NAME_down_load(names_lh) = down_load; +} diff --git a/libs/openssl/crypto/objects/obj_dat.c b/libs/openssl/crypto/objects/obj_dat.c new file mode 100644 index 00000000..aca382a6 --- /dev/null +++ b/libs/openssl/crypto/objects/obj_dat.c @@ -0,0 +1,801 @@ +/* crypto/objects/obj_dat.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include + +/* obj_dat.h is generated from objects.h by obj_dat.pl */ +#ifndef OPENSSL_NO_OBJECT +# include "obj_dat.h" +#else +/* You will have to load all the objects needed manually in the application */ +# define NUM_NID 0 +# define NUM_SN 0 +# define NUM_LN 0 +# define NUM_OBJ 0 +static const unsigned char lvalues[1]; +static const ASN1_OBJECT nid_objs[1]; +static const unsigned int sn_objs[1]; +static const unsigned int ln_objs[1]; +static const unsigned int obj_objs[1]; +#endif + +DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn); +DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln); +DECLARE_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); + +#define ADDED_DATA 0 +#define ADDED_SNAME 1 +#define ADDED_LNAME 2 +#define ADDED_NID 3 + +typedef struct added_obj_st { + int type; + ASN1_OBJECT *obj; +} ADDED_OBJ; +DECLARE_LHASH_OF(ADDED_OBJ); + +static int new_nid = NUM_NID; +static LHASH_OF(ADDED_OBJ) *added = NULL; + +static int sn_cmp(const ASN1_OBJECT *const *a, const unsigned int *b) +{ + return (strcmp((*a)->sn, nid_objs[*b].sn)); +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, sn); + +static int ln_cmp(const ASN1_OBJECT *const *a, const unsigned int *b) +{ + return (strcmp((*a)->ln, nid_objs[*b].ln)); +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, ln); + +static unsigned long added_obj_hash(const ADDED_OBJ *ca) +{ + const ASN1_OBJECT *a; + int i; + unsigned long ret = 0; + unsigned char *p; + + a = ca->obj; + switch (ca->type) { + case ADDED_DATA: + ret = a->length << 20L; + p = (unsigned char *)a->data; + for (i = 0; i < a->length; i++) + ret ^= p[i] << ((i * 3) % 24); + break; + case ADDED_SNAME: + ret = lh_strhash(a->sn); + break; + case ADDED_LNAME: + ret = lh_strhash(a->ln); + break; + case ADDED_NID: + ret = a->nid; + break; + default: + /* abort(); */ + return 0; + } + ret &= 0x3fffffffL; + ret |= ((unsigned long)ca->type) << 30L; + return (ret); +} + +static IMPLEMENT_LHASH_HASH_FN(added_obj, ADDED_OBJ) + +static int added_obj_cmp(const ADDED_OBJ *ca, const ADDED_OBJ *cb) +{ + ASN1_OBJECT *a, *b; + int i; + + i = ca->type - cb->type; + if (i) + return (i); + a = ca->obj; + b = cb->obj; + switch (ca->type) { + case ADDED_DATA: + i = (a->length - b->length); + if (i) + return (i); + return (memcmp(a->data, b->data, (size_t)a->length)); + case ADDED_SNAME: + if (a->sn == NULL) + return (-1); + else if (b->sn == NULL) + return (1); + else + return (strcmp(a->sn, b->sn)); + case ADDED_LNAME: + if (a->ln == NULL) + return (-1); + else if (b->ln == NULL) + return (1); + else + return (strcmp(a->ln, b->ln)); + case ADDED_NID: + return (a->nid - b->nid); + default: + /* abort(); */ + return 0; + } +} + +static IMPLEMENT_LHASH_COMP_FN(added_obj, ADDED_OBJ) + +static int init_added(void) +{ + if (added != NULL) + return (1); + added = lh_ADDED_OBJ_new(); + return (added != NULL); +} + +static void cleanup1_doall(ADDED_OBJ *a) +{ + a->obj->nid = 0; + a->obj->flags |= ASN1_OBJECT_FLAG_DYNAMIC | + ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | ASN1_OBJECT_FLAG_DYNAMIC_DATA; +} + +static void cleanup2_doall(ADDED_OBJ *a) +{ + a->obj->nid++; +} + +static void cleanup3_doall(ADDED_OBJ *a) +{ + if (--a->obj->nid == 0) + ASN1_OBJECT_free(a->obj); + OPENSSL_free(a); +} + +static IMPLEMENT_LHASH_DOALL_FN(cleanup1, ADDED_OBJ) +static IMPLEMENT_LHASH_DOALL_FN(cleanup2, ADDED_OBJ) +static IMPLEMENT_LHASH_DOALL_FN(cleanup3, ADDED_OBJ) + +/* + * The purpose of obj_cleanup_defer is to avoid EVP_cleanup() attempting to + * use freed up OIDs. If neccessary the actual freeing up of OIDs is delayed. + */ +int obj_cleanup_defer = 0; + +void check_defer(int nid) +{ + if (!obj_cleanup_defer && nid >= NUM_NID) + obj_cleanup_defer = 1; +} + +void OBJ_cleanup(void) +{ + if (obj_cleanup_defer) { + obj_cleanup_defer = 2; + return; + } + if (added == NULL) + return; + lh_ADDED_OBJ_down_load(added) = 0; + lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup1)); /* zero counters */ + lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup2)); /* set counters */ + lh_ADDED_OBJ_doall(added, LHASH_DOALL_FN(cleanup3)); /* free objects */ + lh_ADDED_OBJ_free(added); + added = NULL; +} + +int OBJ_new_nid(int num) +{ + int i; + + i = new_nid; + new_nid += num; + return (i); +} + +int OBJ_add_object(const ASN1_OBJECT *obj) +{ + ASN1_OBJECT *o; + ADDED_OBJ *ao[4] = { NULL, NULL, NULL, NULL }, *aop; + int i; + + if (added == NULL) + if (!init_added()) + return (0); + if ((o = OBJ_dup(obj)) == NULL) + goto err; + if (!(ao[ADDED_NID] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) + goto err2; + if ((o->length != 0) && (obj->data != NULL)) + if (! + (ao[ADDED_DATA] = (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) + goto err2; + if (o->sn != NULL) + if (! + (ao[ADDED_SNAME] = + (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) + goto err2; + if (o->ln != NULL) + if (! + (ao[ADDED_LNAME] = + (ADDED_OBJ *)OPENSSL_malloc(sizeof(ADDED_OBJ)))) + goto err2; + + for (i = ADDED_DATA; i <= ADDED_NID; i++) { + if (ao[i] != NULL) { + ao[i]->type = i; + ao[i]->obj = o; + aop = lh_ADDED_OBJ_insert(added, ao[i]); + /* memory leak, buit should not normally matter */ + if (aop != NULL) + OPENSSL_free(aop); + } + } + o->flags &= + ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA); + + return (o->nid); + err2: + OBJerr(OBJ_F_OBJ_ADD_OBJECT, ERR_R_MALLOC_FAILURE); + err: + for (i = ADDED_DATA; i <= ADDED_NID; i++) + if (ao[i] != NULL) + OPENSSL_free(ao[i]); + if (o != NULL) + OPENSSL_free(o); + return (NID_undef); +} + +ASN1_OBJECT *OBJ_nid2obj(int n) +{ + ADDED_OBJ ad, *adp; + ASN1_OBJECT ob; + + if ((n >= 0) && (n < NUM_NID)) { + if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { + OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); + return (NULL); + } + return ((ASN1_OBJECT *)&(nid_objs[n])); + } else if (added == NULL) + return (NULL); + else { + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj); + else { + OBJerr(OBJ_F_OBJ_NID2OBJ, OBJ_R_UNKNOWN_NID); + return (NULL); + } + } +} + +const char *OBJ_nid2sn(int n) +{ + ADDED_OBJ ad, *adp; + ASN1_OBJECT ob; + + if ((n >= 0) && (n < NUM_NID)) { + if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { + OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); + return (NULL); + } + return (nid_objs[n].sn); + } else if (added == NULL) + return (NULL); + else { + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->sn); + else { + OBJerr(OBJ_F_OBJ_NID2SN, OBJ_R_UNKNOWN_NID); + return (NULL); + } + } +} + +const char *OBJ_nid2ln(int n) +{ + ADDED_OBJ ad, *adp; + ASN1_OBJECT ob; + + if ((n >= 0) && (n < NUM_NID)) { + if ((n != NID_undef) && (nid_objs[n].nid == NID_undef)) { + OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); + return (NULL); + } + return (nid_objs[n].ln); + } else if (added == NULL) + return (NULL); + else { + ad.type = ADDED_NID; + ad.obj = &ob; + ob.nid = n; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->ln); + else { + OBJerr(OBJ_F_OBJ_NID2LN, OBJ_R_UNKNOWN_NID); + return (NULL); + } + } +} + +static int obj_cmp(const ASN1_OBJECT *const *ap, const unsigned int *bp) +{ + int j; + const ASN1_OBJECT *a = *ap; + const ASN1_OBJECT *b = &nid_objs[*bp]; + + j = (a->length - b->length); + if (j) + return (j); + if (a->length == 0) + return 0; + return (memcmp(a->data, b->data, a->length)); +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const ASN1_OBJECT *, unsigned int, obj); + +int OBJ_obj2nid(const ASN1_OBJECT *a) +{ + const unsigned int *op; + ADDED_OBJ ad, *adp; + + if (a == NULL) + return (NID_undef); + if (a->nid != 0) + return (a->nid); + + if (a->length == 0) + return NID_undef; + + if (added != NULL) { + ad.type = ADDED_DATA; + ad.obj = (ASN1_OBJECT *)a; /* XXX: ugly but harmless */ + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->nid); + } + op = OBJ_bsearch_obj(&a, obj_objs, NUM_OBJ); + if (op == NULL) + return (NID_undef); + return (nid_objs[*op].nid); +} + +/* + * Convert an object name into an ASN1_OBJECT if "noname" is not set then + * search for short and long names first. This will convert the "dotted" form + * into an object: unlike OBJ_txt2nid it can be used with any objects, not + * just registered ones. + */ + +ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name) +{ + int nid = NID_undef; + ASN1_OBJECT *op = NULL; + unsigned char *buf; + unsigned char *p; + const unsigned char *cp; + int i, j; + + if (!no_name) { + if (((nid = OBJ_sn2nid(s)) != NID_undef) || + ((nid = OBJ_ln2nid(s)) != NID_undef)) + return OBJ_nid2obj(nid); + } + + /* Work out size of content octets */ + i = a2d_ASN1_OBJECT(NULL, 0, s, -1); + if (i <= 0) { + /* Don't clear the error */ + /* + * ERR_clear_error(); + */ + return NULL; + } + /* Work out total size */ + j = ASN1_object_size(0, i, V_ASN1_OBJECT); + + if ((buf = (unsigned char *)OPENSSL_malloc(j)) == NULL) + return NULL; + + p = buf; + /* Write out tag+length */ + ASN1_put_object(&p, 0, i, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); + /* Write out contents */ + a2d_ASN1_OBJECT(p, i, s, -1); + + cp = buf; + op = d2i_ASN1_OBJECT(NULL, &cp, j); + OPENSSL_free(buf); + return op; +} + +int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name) +{ + int i, n = 0, len, nid, first, use_bn; + BIGNUM *bl; + unsigned long l; + const unsigned char *p; + char tbuf[DECIMAL_SIZE(i) + DECIMAL_SIZE(l) + 2]; + + /* Ensure that, at every state, |buf| is NUL-terminated. */ + if (buf && buf_len > 0) + buf[0] = '\0'; + + if ((a == NULL) || (a->data == NULL)) + return (0); + + if (!no_name && (nid = OBJ_obj2nid(a)) != NID_undef) { + const char *s; + s = OBJ_nid2ln(nid); + if (s == NULL) + s = OBJ_nid2sn(nid); + if (s) { + if (buf) + BUF_strlcpy(buf, s, buf_len); + n = strlen(s); + return n; + } + } + + len = a->length; + p = a->data; + + first = 1; + bl = NULL; + + while (len > 0) { + l = 0; + use_bn = 0; + for (;;) { + unsigned char c = *p++; + len--; + if ((len == 0) && (c & 0x80)) + goto err; + if (use_bn) { + if (!BN_add_word(bl, c & 0x7f)) + goto err; + } else + l |= c & 0x7f; + if (!(c & 0x80)) + break; + if (!use_bn && (l > (ULONG_MAX >> 7L))) { + if (!bl && !(bl = BN_new())) + goto err; + if (!BN_set_word(bl, l)) + goto err; + use_bn = 1; + } + if (use_bn) { + if (!BN_lshift(bl, bl, 7)) + goto err; + } else + l <<= 7L; + } + + if (first) { + first = 0; + if (l >= 80) { + i = 2; + if (use_bn) { + if (!BN_sub_word(bl, 80)) + goto err; + } else + l -= 80; + } else { + i = (int)(l / 40); + l -= (long)(i * 40); + } + if (buf && (buf_len > 1)) { + *buf++ = i + '0'; + *buf = '\0'; + buf_len--; + } + n++; + } + + if (use_bn) { + char *bndec; + bndec = BN_bn2dec(bl); + if (!bndec) + goto err; + i = strlen(bndec); + if (buf) { + if (buf_len > 1) { + *buf++ = '.'; + *buf = '\0'; + buf_len--; + } + BUF_strlcpy(buf, bndec, buf_len); + if (i > buf_len) { + buf += buf_len; + buf_len = 0; + } else { + buf += i; + buf_len -= i; + } + } + n++; + n += i; + OPENSSL_free(bndec); + } else { + BIO_snprintf(tbuf, sizeof tbuf, ".%lu", l); + i = strlen(tbuf); + if (buf && (buf_len > 0)) { + BUF_strlcpy(buf, tbuf, buf_len); + if (i > buf_len) { + buf += buf_len; + buf_len = 0; + } else { + buf += i; + buf_len -= i; + } + } + n += i; + l = 0; + } + } + + if (bl) + BN_free(bl); + return n; + + err: + if (bl) + BN_free(bl); + return -1; +} + +int OBJ_txt2nid(const char *s) +{ + ASN1_OBJECT *obj; + int nid; + obj = OBJ_txt2obj(s, 0); + nid = OBJ_obj2nid(obj); + ASN1_OBJECT_free(obj); + return nid; +} + +int OBJ_ln2nid(const char *s) +{ + ASN1_OBJECT o; + const ASN1_OBJECT *oo = &o; + ADDED_OBJ ad, *adp; + const unsigned int *op; + + o.ln = s; + if (added != NULL) { + ad.type = ADDED_LNAME; + ad.obj = &o; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->nid); + } + op = OBJ_bsearch_ln(&oo, ln_objs, NUM_LN); + if (op == NULL) + return (NID_undef); + return (nid_objs[*op].nid); +} + +int OBJ_sn2nid(const char *s) +{ + ASN1_OBJECT o; + const ASN1_OBJECT *oo = &o; + ADDED_OBJ ad, *adp; + const unsigned int *op; + + o.sn = s; + if (added != NULL) { + ad.type = ADDED_SNAME; + ad.obj = &o; + adp = lh_ADDED_OBJ_retrieve(added, &ad); + if (adp != NULL) + return (adp->obj->nid); + } + op = OBJ_bsearch_sn(&oo, sn_objs, NUM_SN); + if (op == NULL) + return (NID_undef); + return (nid_objs[*op].nid); +} + +const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, + int (*cmp) (const void *, const void *)) +{ + return OBJ_bsearch_ex_(key, base, num, size, cmp, 0); +} + +const void *OBJ_bsearch_ex_(const void *key, const void *base_, int num, + int size, + int (*cmp) (const void *, const void *), + int flags) +{ + const char *base = base_; + int l, h, i = 0, c = 0; + const char *p = NULL; + + if (num == 0) + return (NULL); + l = 0; + h = num; + while (l < h) { + i = (l + h) / 2; + p = &(base[i * size]); + c = (*cmp) (key, p); + if (c < 0) + h = i; + else if (c > 0) + l = i + 1; + else + break; + } +#ifdef CHARSET_EBCDIC + /* + * THIS IS A KLUDGE - Because the *_obj is sorted in ASCII order, and I + * don't have perl (yet), we revert to a *LINEAR* search when the object + * wasn't found in the binary search. + */ + if (c != 0) { + for (i = 0; i < num; ++i) { + p = &(base[i * size]); + c = (*cmp) (key, p); + if (c == 0 || (c < 0 && (flags & OBJ_BSEARCH_VALUE_ON_NOMATCH))) + return p; + } + } +#endif + if (c != 0 && !(flags & OBJ_BSEARCH_VALUE_ON_NOMATCH)) + p = NULL; + else if (c == 0 && (flags & OBJ_BSEARCH_FIRST_VALUE_ON_MATCH)) { + while (i > 0 && (*cmp) (key, &(base[(i - 1) * size])) == 0) + i--; + p = &(base[i * size]); + } + return (p); +} + +int OBJ_create_objects(BIO *in) +{ + MS_STATIC char buf[512]; + int i, num = 0; + char *o, *s, *l = NULL; + + for (;;) { + s = o = NULL; + i = BIO_gets(in, buf, 512); + if (i <= 0) + return (num); + buf[i - 1] = '\0'; + if (!isalnum((unsigned char)buf[0])) + return (num); + o = s = buf; + while (isdigit((unsigned char)*s) || (*s == '.')) + s++; + if (*s != '\0') { + *(s++) = '\0'; + while (isspace((unsigned char)*s)) + s++; + if (*s == '\0') + s = NULL; + else { + l = s; + while ((*l != '\0') && !isspace((unsigned char)*l)) + l++; + if (*l != '\0') { + *(l++) = '\0'; + while (isspace((unsigned char)*l)) + l++; + if (*l == '\0') + l = NULL; + } else + l = NULL; + } + } else + s = NULL; + if ((o == NULL) || (*o == '\0')) + return (num); + if (!OBJ_create(o, s, l)) + return (num); + num++; + } + /* return(num); */ +} + +int OBJ_create(const char *oid, const char *sn, const char *ln) +{ + int ok = 0; + ASN1_OBJECT *op = NULL; + unsigned char *buf; + int i; + + i = a2d_ASN1_OBJECT(NULL, 0, oid, -1); + if (i <= 0) + return (0); + + if ((buf = (unsigned char *)OPENSSL_malloc(i)) == NULL) { + OBJerr(OBJ_F_OBJ_CREATE, ERR_R_MALLOC_FAILURE); + return (0); + } + i = a2d_ASN1_OBJECT(buf, i, oid, -1); + if (i == 0) + goto err; + op = (ASN1_OBJECT *)ASN1_OBJECT_create(OBJ_new_nid(1), buf, i, sn, ln); + if (op == NULL) + goto err; + ok = OBJ_add_object(op); + err: + ASN1_OBJECT_free(op); + OPENSSL_free(buf); + return (ok); +} diff --git a/libs/openssl/crypto/objects/obj_dat.h b/libs/openssl/crypto/objects/obj_dat.h new file mode 100644 index 00000000..bc69665b --- /dev/null +++ b/libs/openssl/crypto/objects/obj_dat.h @@ -0,0 +1,5095 @@ +/* crypto/objects/obj_dat.h */ + +/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the + * following command: + * perl obj_dat.pl obj_mac.h obj_dat.h + */ + +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#define NUM_NID 920 +#define NUM_SN 913 +#define NUM_LN 913 +#define NUM_OBJ 857 + +static const unsigned char lvalues[5974]={ +0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x05, /* [ 21] OBJ_md5 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x04, /* [ 29] OBJ_rc4 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x01,/* [ 37] OBJ_rsaEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x02,/* [ 46] OBJ_md2WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x04,/* [ 55] OBJ_md5WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x01,/* [ 64] OBJ_pbeWithMD2AndDES_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x03,/* [ 73] OBJ_pbeWithMD5AndDES_CBC */ +0x55, /* [ 82] OBJ_X500 */ +0x55,0x04, /* [ 83] OBJ_X509 */ +0x55,0x04,0x03, /* [ 85] OBJ_commonName */ +0x55,0x04,0x06, /* [ 88] OBJ_countryName */ +0x55,0x04,0x07, /* [ 91] OBJ_localityName */ +0x55,0x04,0x08, /* [ 94] OBJ_stateOrProvinceName */ +0x55,0x04,0x0A, /* [ 97] OBJ_organizationName */ +0x55,0x04,0x0B, /* [100] OBJ_organizationalUnitName */ +0x55,0x08,0x01,0x01, /* [103] OBJ_rsa */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07, /* [107] OBJ_pkcs7 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x01,/* [115] OBJ_pkcs7_data */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x02,/* [124] OBJ_pkcs7_signed */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x03,/* [133] OBJ_pkcs7_enveloped */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x04,/* [142] OBJ_pkcs7_signedAndEnveloped */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x05,/* [151] OBJ_pkcs7_digest */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x07,0x06,/* [160] OBJ_pkcs7_encrypted */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03, /* [169] OBJ_pkcs3 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x03,0x01,/* [177] OBJ_dhKeyAgreement */ +0x2B,0x0E,0x03,0x02,0x06, /* [186] OBJ_des_ecb */ +0x2B,0x0E,0x03,0x02,0x09, /* [191] OBJ_des_cfb64 */ +0x2B,0x0E,0x03,0x02,0x07, /* [196] OBJ_des_cbc */ +0x2B,0x0E,0x03,0x02,0x11, /* [201] OBJ_des_ede_ecb */ +0x2B,0x06,0x01,0x04,0x01,0x81,0x3C,0x07,0x01,0x01,0x02,/* [206] OBJ_idea_cbc */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x02, /* [217] OBJ_rc2_cbc */ +0x2B,0x0E,0x03,0x02,0x12, /* [225] OBJ_sha */ +0x2B,0x0E,0x03,0x02,0x0F, /* [230] OBJ_shaWithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x07, /* [235] OBJ_des_ede3_cbc */ +0x2B,0x0E,0x03,0x02,0x08, /* [243] OBJ_des_ofb64 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09, /* [248] OBJ_pkcs9 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x01,/* [256] OBJ_pkcs9_emailAddress */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x02,/* [265] OBJ_pkcs9_unstructuredName */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x03,/* [274] OBJ_pkcs9_contentType */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x04,/* [283] OBJ_pkcs9_messageDigest */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x05,/* [292] OBJ_pkcs9_signingTime */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x06,/* [301] OBJ_pkcs9_countersignature */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x07,/* [310] OBJ_pkcs9_challengePassword */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x08,/* [319] OBJ_pkcs9_unstructuredAddress */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x09,/* [328] OBJ_pkcs9_extCertAttributes */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42, /* [337] OBJ_netscape */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01, /* [344] OBJ_netscape_cert_extension */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02, /* [352] OBJ_netscape_data_type */ +0x2B,0x0E,0x03,0x02,0x1A, /* [360] OBJ_sha1 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x05,/* [365] OBJ_sha1WithRSAEncryption */ +0x2B,0x0E,0x03,0x02,0x0D, /* [374] OBJ_dsaWithSHA */ +0x2B,0x0E,0x03,0x02,0x0C, /* [379] OBJ_dsa_2 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0B,/* [384] OBJ_pbeWithSHA1AndRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0C,/* [393] OBJ_id_pbkdf2 */ +0x2B,0x0E,0x03,0x02,0x1B, /* [402] OBJ_dsaWithSHA1_2 */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x01,/* [407] OBJ_netscape_cert_type */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x02,/* [416] OBJ_netscape_base_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x03,/* [425] OBJ_netscape_revocation_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x04,/* [434] OBJ_netscape_ca_revocation_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x07,/* [443] OBJ_netscape_renewal_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x08,/* [452] OBJ_netscape_ca_policy_url */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0C,/* [461] OBJ_netscape_ssl_server_name */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x01,0x0D,/* [470] OBJ_netscape_comment */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x02,0x05,/* [479] OBJ_netscape_cert_sequence */ +0x55,0x1D, /* [488] OBJ_id_ce */ +0x55,0x1D,0x0E, /* [490] OBJ_subject_key_identifier */ +0x55,0x1D,0x0F, /* [493] OBJ_key_usage */ +0x55,0x1D,0x10, /* [496] OBJ_private_key_usage_period */ +0x55,0x1D,0x11, /* [499] OBJ_subject_alt_name */ +0x55,0x1D,0x12, /* [502] OBJ_issuer_alt_name */ +0x55,0x1D,0x13, /* [505] OBJ_basic_constraints */ +0x55,0x1D,0x14, /* [508] OBJ_crl_number */ +0x55,0x1D,0x20, /* [511] OBJ_certificate_policies */ +0x55,0x1D,0x23, /* [514] OBJ_authority_key_identifier */ +0x2B,0x06,0x01,0x04,0x01,0x97,0x55,0x01,0x02,/* [517] OBJ_bf_cbc */ +0x55,0x08,0x03,0x65, /* [526] OBJ_mdc2 */ +0x55,0x08,0x03,0x64, /* [530] OBJ_mdc2WithRSA */ +0x55,0x04,0x2A, /* [534] OBJ_givenName */ +0x55,0x04,0x04, /* [537] OBJ_surname */ +0x55,0x04,0x2B, /* [540] OBJ_initials */ +0x55,0x1D,0x1F, /* [543] OBJ_crl_distribution_points */ +0x2B,0x0E,0x03,0x02,0x03, /* [546] OBJ_md5WithRSA */ +0x55,0x04,0x05, /* [551] OBJ_serialNumber */ +0x55,0x04,0x0C, /* [554] OBJ_title */ +0x55,0x04,0x0D, /* [557] OBJ_description */ +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0A,/* [560] OBJ_cast5_cbc */ +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0C,/* [569] OBJ_pbeWithMD5AndCast5_CBC */ +0x2A,0x86,0x48,0xCE,0x38,0x04,0x03, /* [578] OBJ_dsaWithSHA1 */ +0x2B,0x0E,0x03,0x02,0x1D, /* [585] OBJ_sha1WithRSA */ +0x2A,0x86,0x48,0xCE,0x38,0x04,0x01, /* [590] OBJ_dsa */ +0x2B,0x24,0x03,0x02,0x01, /* [597] OBJ_ripemd160 */ +0x2B,0x24,0x03,0x03,0x01,0x02, /* [602] OBJ_ripemd160WithRSA */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x08, /* [608] OBJ_rc5_cbc */ +0x29,0x01,0x01,0x85,0x1A,0x01, /* [616] OBJ_rle_compression */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x08,/* [622] OBJ_zlib_compression */ +0x55,0x1D,0x25, /* [633] OBJ_ext_key_usage */ +0x2B,0x06,0x01,0x05,0x05,0x07, /* [636] OBJ_id_pkix */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03, /* [642] OBJ_id_kp */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x01, /* [649] OBJ_server_auth */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x02, /* [657] OBJ_client_auth */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x03, /* [665] OBJ_code_sign */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x04, /* [673] OBJ_email_protect */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x08, /* [681] OBJ_time_stamp */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x15,/* [689] OBJ_ms_code_ind */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x16,/* [699] OBJ_ms_code_com */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x01,/* [709] OBJ_ms_ctl_sign */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x03,/* [719] OBJ_ms_sgc */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x0A,0x03,0x04,/* [729] OBJ_ms_efs */ +0x60,0x86,0x48,0x01,0x86,0xF8,0x42,0x04,0x01,/* [739] OBJ_ns_sgc */ +0x55,0x1D,0x1B, /* [748] OBJ_delta_crl */ +0x55,0x1D,0x15, /* [751] OBJ_crl_reason */ +0x55,0x1D,0x18, /* [754] OBJ_invalidity_date */ +0x2B,0x65,0x01,0x04,0x01, /* [757] OBJ_sxnet */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x01,/* [762] OBJ_pbe_WithSHA1And128BitRC4 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x02,/* [772] OBJ_pbe_WithSHA1And40BitRC4 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x03,/* [782] OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x04,/* [792] OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x05,/* [802] OBJ_pbe_WithSHA1And128BitRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x01,0x06,/* [812] OBJ_pbe_WithSHA1And40BitRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x01,/* [822] OBJ_keyBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x02,/* [833] OBJ_pkcs8ShroudedKeyBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x03,/* [844] OBJ_certBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x04,/* [855] OBJ_crlBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x05,/* [866] OBJ_secretBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x0C,0x0A,0x01,0x06,/* [877] OBJ_safeContentsBag */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x14,/* [888] OBJ_friendlyName */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x15,/* [897] OBJ_localKeyID */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x01,/* [906] OBJ_x509Certificate */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x16,0x02,/* [916] OBJ_sdsiCertificate */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x17,0x01,/* [926] OBJ_x509Crl */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0D,/* [936] OBJ_pbes2 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0E,/* [945] OBJ_pbmac1 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x07, /* [954] OBJ_hmacWithSHA1 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x01, /* [962] OBJ_id_qt_cps */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x02, /* [970] OBJ_id_qt_unotice */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0F,/* [978] OBJ_SMIMECapabilities */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x04,/* [987] OBJ_pbeWithMD2AndRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x06,/* [996] OBJ_pbeWithMD5AndRC2_CBC */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05,0x0A,/* [1005] OBJ_pbeWithSHA1AndDES_CBC */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x02,0x01,0x0E,/* [1014] OBJ_ms_ext_req */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x0E,/* [1024] OBJ_ext_req */ +0x55,0x04,0x29, /* [1033] OBJ_name */ +0x55,0x04,0x2E, /* [1036] OBJ_dnQualifier */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01, /* [1039] OBJ_id_pe */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30, /* [1046] OBJ_id_ad */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x01, /* [1053] OBJ_info_access */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01, /* [1061] OBJ_ad_OCSP */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x02, /* [1069] OBJ_ad_ca_issuers */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x09, /* [1077] OBJ_OCSP_sign */ +0x2A, /* [1085] OBJ_member_body */ +0x2A,0x86,0x48, /* [1086] OBJ_ISO_US */ +0x2A,0x86,0x48,0xCE,0x38, /* [1089] OBJ_X9_57 */ +0x2A,0x86,0x48,0xCE,0x38,0x04, /* [1094] OBJ_X9cm */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01, /* [1100] OBJ_pkcs1 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x05, /* [1108] OBJ_pkcs5 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,/* [1116] OBJ_SMIME */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,/* [1125] OBJ_id_smime_mod */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,/* [1135] OBJ_id_smime_ct */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,/* [1145] OBJ_id_smime_aa */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,/* [1155] OBJ_id_smime_alg */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,/* [1165] OBJ_id_smime_cd */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,/* [1175] OBJ_id_smime_spq */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,/* [1185] OBJ_id_smime_cti */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x01,/* [1195] OBJ_id_smime_mod_cms */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x02,/* [1206] OBJ_id_smime_mod_ess */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x03,/* [1217] OBJ_id_smime_mod_oid */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x04,/* [1228] OBJ_id_smime_mod_msg_v3 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x05,/* [1239] OBJ_id_smime_mod_ets_eSignature_88 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x06,/* [1250] OBJ_id_smime_mod_ets_eSignature_97 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x07,/* [1261] OBJ_id_smime_mod_ets_eSigPolicy_88 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x00,0x08,/* [1272] OBJ_id_smime_mod_ets_eSigPolicy_97 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x01,/* [1283] OBJ_id_smime_ct_receipt */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x02,/* [1294] OBJ_id_smime_ct_authData */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x03,/* [1305] OBJ_id_smime_ct_publishCert */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x04,/* [1316] OBJ_id_smime_ct_TSTInfo */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x05,/* [1327] OBJ_id_smime_ct_TDTInfo */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x06,/* [1338] OBJ_id_smime_ct_contentInfo */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x07,/* [1349] OBJ_id_smime_ct_DVCSRequestData */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x08,/* [1360] OBJ_id_smime_ct_DVCSResponseData */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x01,/* [1371] OBJ_id_smime_aa_receiptRequest */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x02,/* [1382] OBJ_id_smime_aa_securityLabel */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x03,/* [1393] OBJ_id_smime_aa_mlExpandHistory */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x04,/* [1404] OBJ_id_smime_aa_contentHint */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x05,/* [1415] OBJ_id_smime_aa_msgSigDigest */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x06,/* [1426] OBJ_id_smime_aa_encapContentType */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x07,/* [1437] OBJ_id_smime_aa_contentIdentifier */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x08,/* [1448] OBJ_id_smime_aa_macValue */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x09,/* [1459] OBJ_id_smime_aa_equivalentLabels */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0A,/* [1470] OBJ_id_smime_aa_contentReference */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0B,/* [1481] OBJ_id_smime_aa_encrypKeyPref */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0C,/* [1492] OBJ_id_smime_aa_signingCertificate */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0D,/* [1503] OBJ_id_smime_aa_smimeEncryptCerts */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0E,/* [1514] OBJ_id_smime_aa_timeStampToken */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x0F,/* [1525] OBJ_id_smime_aa_ets_sigPolicyId */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x10,/* [1536] OBJ_id_smime_aa_ets_commitmentType */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x11,/* [1547] OBJ_id_smime_aa_ets_signerLocation */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x12,/* [1558] OBJ_id_smime_aa_ets_signerAttr */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x13,/* [1569] OBJ_id_smime_aa_ets_otherSigCert */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x14,/* [1580] OBJ_id_smime_aa_ets_contentTimestamp */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x15,/* [1591] OBJ_id_smime_aa_ets_CertificateRefs */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x16,/* [1602] OBJ_id_smime_aa_ets_RevocationRefs */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x17,/* [1613] OBJ_id_smime_aa_ets_certValues */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x18,/* [1624] OBJ_id_smime_aa_ets_revocationValues */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x19,/* [1635] OBJ_id_smime_aa_ets_escTimeStamp */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1A,/* [1646] OBJ_id_smime_aa_ets_certCRLTimestamp */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1B,/* [1657] OBJ_id_smime_aa_ets_archiveTimeStamp */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1C,/* [1668] OBJ_id_smime_aa_signatureType */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x02,0x1D,/* [1679] OBJ_id_smime_aa_dvcs_dvc */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x01,/* [1690] OBJ_id_smime_alg_ESDHwith3DES */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x02,/* [1701] OBJ_id_smime_alg_ESDHwithRC2 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x03,/* [1712] OBJ_id_smime_alg_3DESwrap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x04,/* [1723] OBJ_id_smime_alg_RC2wrap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x05,/* [1734] OBJ_id_smime_alg_ESDH */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x06,/* [1745] OBJ_id_smime_alg_CMS3DESwrap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x07,/* [1756] OBJ_id_smime_alg_CMSRC2wrap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x04,0x01,/* [1767] OBJ_id_smime_cd_ldap */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x01,/* [1778] OBJ_id_smime_spq_ets_sqt_uri */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x05,0x02,/* [1789] OBJ_id_smime_spq_ets_sqt_unotice */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x01,/* [1800] OBJ_id_smime_cti_ets_proofOfOrigin */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x02,/* [1811] OBJ_id_smime_cti_ets_proofOfReceipt */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x03,/* [1822] OBJ_id_smime_cti_ets_proofOfDelivery */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x04,/* [1833] OBJ_id_smime_cti_ets_proofOfSender */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x05,/* [1844] OBJ_id_smime_cti_ets_proofOfApproval */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x06,0x06,/* [1855] OBJ_id_smime_cti_ets_proofOfCreation */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x04, /* [1866] OBJ_md4 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00, /* [1874] OBJ_id_pkix_mod */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x02, /* [1881] OBJ_id_qt */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04, /* [1888] OBJ_id_it */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05, /* [1895] OBJ_id_pkip */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06, /* [1902] OBJ_id_alg */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07, /* [1909] OBJ_id_cmc */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x08, /* [1916] OBJ_id_on */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09, /* [1923] OBJ_id_pda */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A, /* [1930] OBJ_id_aca */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0B, /* [1937] OBJ_id_qcs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C, /* [1944] OBJ_id_cct */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x01, /* [1951] OBJ_id_pkix1_explicit_88 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x02, /* [1959] OBJ_id_pkix1_implicit_88 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x03, /* [1967] OBJ_id_pkix1_explicit_93 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x04, /* [1975] OBJ_id_pkix1_implicit_93 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x05, /* [1983] OBJ_id_mod_crmf */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x06, /* [1991] OBJ_id_mod_cmc */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x07, /* [1999] OBJ_id_mod_kea_profile_88 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x08, /* [2007] OBJ_id_mod_kea_profile_93 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x09, /* [2015] OBJ_id_mod_cmp */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0A, /* [2023] OBJ_id_mod_qualified_cert_88 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0B, /* [2031] OBJ_id_mod_qualified_cert_93 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0C, /* [2039] OBJ_id_mod_attribute_cert */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0D, /* [2047] OBJ_id_mod_timestamp_protocol */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0E, /* [2055] OBJ_id_mod_ocsp */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x0F, /* [2063] OBJ_id_mod_dvcs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x00,0x10, /* [2071] OBJ_id_mod_cmp2000 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x02, /* [2079] OBJ_biometricInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x03, /* [2087] OBJ_qcStatements */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x04, /* [2095] OBJ_ac_auditEntity */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x05, /* [2103] OBJ_ac_targeting */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x06, /* [2111] OBJ_aaControls */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x07, /* [2119] OBJ_sbgp_ipAddrBlock */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x08, /* [2127] OBJ_sbgp_autonomousSysNum */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x09, /* [2135] OBJ_sbgp_routerIdentifier */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x02,0x03, /* [2143] OBJ_textNotice */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x05, /* [2151] OBJ_ipsecEndSystem */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x06, /* [2159] OBJ_ipsecTunnel */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x07, /* [2167] OBJ_ipsecUser */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x03,0x0A, /* [2175] OBJ_dvcs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x01, /* [2183] OBJ_id_it_caProtEncCert */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x02, /* [2191] OBJ_id_it_signKeyPairTypes */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x03, /* [2199] OBJ_id_it_encKeyPairTypes */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x04, /* [2207] OBJ_id_it_preferredSymmAlg */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x05, /* [2215] OBJ_id_it_caKeyUpdateInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x06, /* [2223] OBJ_id_it_currentCRL */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x07, /* [2231] OBJ_id_it_unsupportedOIDs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x08, /* [2239] OBJ_id_it_subscriptionRequest */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x09, /* [2247] OBJ_id_it_subscriptionResponse */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0A, /* [2255] OBJ_id_it_keyPairParamReq */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0B, /* [2263] OBJ_id_it_keyPairParamRep */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0C, /* [2271] OBJ_id_it_revPassphrase */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0D, /* [2279] OBJ_id_it_implicitConfirm */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0E, /* [2287] OBJ_id_it_confirmWaitTime */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x0F, /* [2295] OBJ_id_it_origPKIMessage */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01, /* [2303] OBJ_id_regCtrl */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02, /* [2311] OBJ_id_regInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x01,/* [2319] OBJ_id_regCtrl_regToken */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x02,/* [2328] OBJ_id_regCtrl_authenticator */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x03,/* [2337] OBJ_id_regCtrl_pkiPublicationInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x04,/* [2346] OBJ_id_regCtrl_pkiArchiveOptions */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x05,/* [2355] OBJ_id_regCtrl_oldCertID */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x01,0x06,/* [2364] OBJ_id_regCtrl_protocolEncrKey */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x01,/* [2373] OBJ_id_regInfo_utf8Pairs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x05,0x02,0x02,/* [2382] OBJ_id_regInfo_certReq */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x01, /* [2391] OBJ_id_alg_des40 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x02, /* [2399] OBJ_id_alg_noSignature */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x03, /* [2407] OBJ_id_alg_dh_sig_hmac_sha1 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x06,0x04, /* [2415] OBJ_id_alg_dh_pop */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x01, /* [2423] OBJ_id_cmc_statusInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x02, /* [2431] OBJ_id_cmc_identification */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x03, /* [2439] OBJ_id_cmc_identityProof */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x04, /* [2447] OBJ_id_cmc_dataReturn */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x05, /* [2455] OBJ_id_cmc_transactionId */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x06, /* [2463] OBJ_id_cmc_senderNonce */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x07, /* [2471] OBJ_id_cmc_recipientNonce */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x08, /* [2479] OBJ_id_cmc_addExtensions */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x09, /* [2487] OBJ_id_cmc_encryptedPOP */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0A, /* [2495] OBJ_id_cmc_decryptedPOP */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0B, /* [2503] OBJ_id_cmc_lraPOPWitness */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x0F, /* [2511] OBJ_id_cmc_getCert */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x10, /* [2519] OBJ_id_cmc_getCRL */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x11, /* [2527] OBJ_id_cmc_revokeRequest */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x12, /* [2535] OBJ_id_cmc_regInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x13, /* [2543] OBJ_id_cmc_responseInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x15, /* [2551] OBJ_id_cmc_queryPending */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x16, /* [2559] OBJ_id_cmc_popLinkRandom */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x17, /* [2567] OBJ_id_cmc_popLinkWitness */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x07,0x18, /* [2575] OBJ_id_cmc_confirmCertAcceptance */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x01, /* [2583] OBJ_id_on_personalData */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x01, /* [2591] OBJ_id_pda_dateOfBirth */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x02, /* [2599] OBJ_id_pda_placeOfBirth */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x03, /* [2607] OBJ_id_pda_gender */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x04, /* [2615] OBJ_id_pda_countryOfCitizenship */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x09,0x05, /* [2623] OBJ_id_pda_countryOfResidence */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x01, /* [2631] OBJ_id_aca_authenticationInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x02, /* [2639] OBJ_id_aca_accessIdentity */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x03, /* [2647] OBJ_id_aca_chargingIdentity */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x04, /* [2655] OBJ_id_aca_group */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x05, /* [2663] OBJ_id_aca_role */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0B,0x01, /* [2671] OBJ_id_qcs_pkixQCSyntax_v1 */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x01, /* [2679] OBJ_id_cct_crs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x02, /* [2687] OBJ_id_cct_PKIData */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0C,0x03, /* [2695] OBJ_id_cct_PKIResponse */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x03, /* [2703] OBJ_ad_timeStamping */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x04, /* [2711] OBJ_ad_dvcs */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x01,/* [2719] OBJ_id_pkix_OCSP_basic */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x02,/* [2728] OBJ_id_pkix_OCSP_Nonce */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x03,/* [2737] OBJ_id_pkix_OCSP_CrlID */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x04,/* [2746] OBJ_id_pkix_OCSP_acceptableResponses */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x05,/* [2755] OBJ_id_pkix_OCSP_noCheck */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x06,/* [2764] OBJ_id_pkix_OCSP_archiveCutoff */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x07,/* [2773] OBJ_id_pkix_OCSP_serviceLocator */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x08,/* [2782] OBJ_id_pkix_OCSP_extendedStatus */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x09,/* [2791] OBJ_id_pkix_OCSP_valid */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0A,/* [2800] OBJ_id_pkix_OCSP_path */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x01,0x0B,/* [2809] OBJ_id_pkix_OCSP_trustRoot */ +0x2B,0x0E,0x03,0x02, /* [2818] OBJ_algorithm */ +0x2B,0x0E,0x03,0x02,0x0B, /* [2822] OBJ_rsaSignature */ +0x55,0x08, /* [2827] OBJ_X500algorithms */ +0x2B, /* [2829] OBJ_org */ +0x2B,0x06, /* [2830] OBJ_dod */ +0x2B,0x06,0x01, /* [2832] OBJ_iana */ +0x2B,0x06,0x01,0x01, /* [2835] OBJ_Directory */ +0x2B,0x06,0x01,0x02, /* [2839] OBJ_Management */ +0x2B,0x06,0x01,0x03, /* [2843] OBJ_Experimental */ +0x2B,0x06,0x01,0x04, /* [2847] OBJ_Private */ +0x2B,0x06,0x01,0x05, /* [2851] OBJ_Security */ +0x2B,0x06,0x01,0x06, /* [2855] OBJ_SNMPv2 */ +0x2B,0x06,0x01,0x07, /* [2859] OBJ_Mail */ +0x2B,0x06,0x01,0x04,0x01, /* [2863] OBJ_Enterprises */ +0x2B,0x06,0x01,0x04,0x01,0x8B,0x3A,0x82,0x58,/* [2868] OBJ_dcObject */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x19,/* [2877] OBJ_domainComponent */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0D,/* [2887] OBJ_Domain */ +0x55,0x01,0x05, /* [2897] OBJ_selected_attribute_types */ +0x55,0x01,0x05,0x37, /* [2900] OBJ_clearance */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x03,/* [2904] OBJ_md4WithRSAEncryption */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0A, /* [2913] OBJ_ac_proxying */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0B, /* [2921] OBJ_sinfo_access */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x0A,0x06, /* [2929] OBJ_id_aca_encAttrs */ +0x55,0x04,0x48, /* [2937] OBJ_role */ +0x55,0x1D,0x24, /* [2940] OBJ_policy_constraints */ +0x55,0x1D,0x37, /* [2943] OBJ_target_information */ +0x55,0x1D,0x38, /* [2946] OBJ_no_rev_avail */ +0x2A,0x86,0x48,0xCE,0x3D, /* [2949] OBJ_ansi_X9_62 */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x01, /* [2954] OBJ_X9_62_prime_field */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02, /* [2961] OBJ_X9_62_characteristic_two_field */ +0x2A,0x86,0x48,0xCE,0x3D,0x02,0x01, /* [2968] OBJ_X9_62_id_ecPublicKey */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x01, /* [2975] OBJ_X9_62_prime192v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x02, /* [2983] OBJ_X9_62_prime192v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x03, /* [2991] OBJ_X9_62_prime192v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x04, /* [2999] OBJ_X9_62_prime239v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x05, /* [3007] OBJ_X9_62_prime239v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x06, /* [3015] OBJ_X9_62_prime239v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x01,0x07, /* [3023] OBJ_X9_62_prime256v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x01, /* [3031] OBJ_ecdsa_with_SHA1 */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x01,/* [3038] OBJ_ms_csp_name */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x01,/* [3047] OBJ_aes_128_ecb */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x02,/* [3056] OBJ_aes_128_cbc */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x03,/* [3065] OBJ_aes_128_ofb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x04,/* [3074] OBJ_aes_128_cfb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x15,/* [3083] OBJ_aes_192_ecb */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x16,/* [3092] OBJ_aes_192_cbc */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x17,/* [3101] OBJ_aes_192_ofb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x18,/* [3110] OBJ_aes_192_cfb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x29,/* [3119] OBJ_aes_256_ecb */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2A,/* [3128] OBJ_aes_256_cbc */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2B,/* [3137] OBJ_aes_256_ofb128 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2C,/* [3146] OBJ_aes_256_cfb128 */ +0x55,0x1D,0x17, /* [3155] OBJ_hold_instruction_code */ +0x2A,0x86,0x48,0xCE,0x38,0x02,0x01, /* [3158] OBJ_hold_instruction_none */ +0x2A,0x86,0x48,0xCE,0x38,0x02,0x02, /* [3165] OBJ_hold_instruction_call_issuer */ +0x2A,0x86,0x48,0xCE,0x38,0x02,0x03, /* [3172] OBJ_hold_instruction_reject */ +0x09, /* [3179] OBJ_data */ +0x09,0x92,0x26, /* [3180] OBJ_pss */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C, /* [3183] OBJ_ucl */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64, /* [3190] OBJ_pilot */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,/* [3198] OBJ_pilotAttributeType */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,/* [3207] OBJ_pilotAttributeSyntax */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,/* [3216] OBJ_pilotObjectClass */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x0A,/* [3225] OBJ_pilotGroups */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x04,/* [3234] OBJ_iA5StringSyntax */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x03,0x05,/* [3244] OBJ_caseIgnoreIA5StringSyntax */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x03,/* [3254] OBJ_pilotObject */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x04,/* [3264] OBJ_pilotPerson */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x05,/* [3274] OBJ_account */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x06,/* [3284] OBJ_document */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x07,/* [3294] OBJ_room */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x09,/* [3304] OBJ_documentSeries */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0E,/* [3314] OBJ_rFC822localPart */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x0F,/* [3324] OBJ_dNSDomain */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x11,/* [3334] OBJ_domainRelatedObject */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x12,/* [3344] OBJ_friendlyCountry */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x13,/* [3354] OBJ_simpleSecurityObject */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x14,/* [3364] OBJ_pilotOrganization */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x15,/* [3374] OBJ_pilotDSA */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x04,0x16,/* [3384] OBJ_qualityLabelledData */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01,/* [3394] OBJ_userId */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x02,/* [3404] OBJ_textEncodedORAddress */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x03,/* [3414] OBJ_rfc822Mailbox */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x04,/* [3424] OBJ_info */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x05,/* [3434] OBJ_favouriteDrink */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x06,/* [3444] OBJ_roomNumber */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x07,/* [3454] OBJ_photo */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x08,/* [3464] OBJ_userClass */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x09,/* [3474] OBJ_host */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0A,/* [3484] OBJ_manager */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0B,/* [3494] OBJ_documentIdentifier */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0C,/* [3504] OBJ_documentTitle */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0D,/* [3514] OBJ_documentVersion */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0E,/* [3524] OBJ_documentAuthor */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x0F,/* [3534] OBJ_documentLocation */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x14,/* [3544] OBJ_homeTelephoneNumber */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x15,/* [3554] OBJ_secretary */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x16,/* [3564] OBJ_otherMailbox */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x17,/* [3574] OBJ_lastModifiedTime */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x18,/* [3584] OBJ_lastModifiedBy */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1A,/* [3594] OBJ_aRecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1B,/* [3604] OBJ_pilotAttributeType27 */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1C,/* [3614] OBJ_mXRecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1D,/* [3624] OBJ_nSRecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1E,/* [3634] OBJ_sOARecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x1F,/* [3644] OBJ_cNAMERecord */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x25,/* [3654] OBJ_associatedDomain */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x26,/* [3664] OBJ_associatedName */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x27,/* [3674] OBJ_homePostalAddress */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x28,/* [3684] OBJ_personalTitle */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x29,/* [3694] OBJ_mobileTelephoneNumber */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2A,/* [3704] OBJ_pagerTelephoneNumber */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2B,/* [3714] OBJ_friendlyCountryName */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2D,/* [3724] OBJ_organizationalStatus */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2E,/* [3734] OBJ_janetMailbox */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x2F,/* [3744] OBJ_mailPreferenceOption */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x30,/* [3754] OBJ_buildingName */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x31,/* [3764] OBJ_dSAQuality */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x32,/* [3774] OBJ_singleLevelQuality */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x33,/* [3784] OBJ_subtreeMinimumQuality */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x34,/* [3794] OBJ_subtreeMaximumQuality */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x35,/* [3804] OBJ_personalSignature */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x36,/* [3814] OBJ_dITRedirect */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x37,/* [3824] OBJ_audio */ +0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x38,/* [3834] OBJ_documentPublisher */ +0x55,0x04,0x2D, /* [3844] OBJ_x500UniqueIdentifier */ +0x2B,0x06,0x01,0x07,0x01, /* [3847] OBJ_mime_mhs */ +0x2B,0x06,0x01,0x07,0x01,0x01, /* [3852] OBJ_mime_mhs_headings */ +0x2B,0x06,0x01,0x07,0x01,0x02, /* [3858] OBJ_mime_mhs_bodies */ +0x2B,0x06,0x01,0x07,0x01,0x01,0x01, /* [3864] OBJ_id_hex_partial_message */ +0x2B,0x06,0x01,0x07,0x01,0x01,0x02, /* [3871] OBJ_id_hex_multipart_message */ +0x55,0x04,0x2C, /* [3878] OBJ_generationQualifier */ +0x55,0x04,0x41, /* [3881] OBJ_pseudonym */ +0x67,0x2A, /* [3884] OBJ_id_set */ +0x67,0x2A,0x00, /* [3886] OBJ_set_ctype */ +0x67,0x2A,0x01, /* [3889] OBJ_set_msgExt */ +0x67,0x2A,0x03, /* [3892] OBJ_set_attr */ +0x67,0x2A,0x05, /* [3895] OBJ_set_policy */ +0x67,0x2A,0x07, /* [3898] OBJ_set_certExt */ +0x67,0x2A,0x08, /* [3901] OBJ_set_brand */ +0x67,0x2A,0x00,0x00, /* [3904] OBJ_setct_PANData */ +0x67,0x2A,0x00,0x01, /* [3908] OBJ_setct_PANToken */ +0x67,0x2A,0x00,0x02, /* [3912] OBJ_setct_PANOnly */ +0x67,0x2A,0x00,0x03, /* [3916] OBJ_setct_OIData */ +0x67,0x2A,0x00,0x04, /* [3920] OBJ_setct_PI */ +0x67,0x2A,0x00,0x05, /* [3924] OBJ_setct_PIData */ +0x67,0x2A,0x00,0x06, /* [3928] OBJ_setct_PIDataUnsigned */ +0x67,0x2A,0x00,0x07, /* [3932] OBJ_setct_HODInput */ +0x67,0x2A,0x00,0x08, /* [3936] OBJ_setct_AuthResBaggage */ +0x67,0x2A,0x00,0x09, /* [3940] OBJ_setct_AuthRevReqBaggage */ +0x67,0x2A,0x00,0x0A, /* [3944] OBJ_setct_AuthRevResBaggage */ +0x67,0x2A,0x00,0x0B, /* [3948] OBJ_setct_CapTokenSeq */ +0x67,0x2A,0x00,0x0C, /* [3952] OBJ_setct_PInitResData */ +0x67,0x2A,0x00,0x0D, /* [3956] OBJ_setct_PI_TBS */ +0x67,0x2A,0x00,0x0E, /* [3960] OBJ_setct_PResData */ +0x67,0x2A,0x00,0x10, /* [3964] OBJ_setct_AuthReqTBS */ +0x67,0x2A,0x00,0x11, /* [3968] OBJ_setct_AuthResTBS */ +0x67,0x2A,0x00,0x12, /* [3972] OBJ_setct_AuthResTBSX */ +0x67,0x2A,0x00,0x13, /* [3976] OBJ_setct_AuthTokenTBS */ +0x67,0x2A,0x00,0x14, /* [3980] OBJ_setct_CapTokenData */ +0x67,0x2A,0x00,0x15, /* [3984] OBJ_setct_CapTokenTBS */ +0x67,0x2A,0x00,0x16, /* [3988] OBJ_setct_AcqCardCodeMsg */ +0x67,0x2A,0x00,0x17, /* [3992] OBJ_setct_AuthRevReqTBS */ +0x67,0x2A,0x00,0x18, /* [3996] OBJ_setct_AuthRevResData */ +0x67,0x2A,0x00,0x19, /* [4000] OBJ_setct_AuthRevResTBS */ +0x67,0x2A,0x00,0x1A, /* [4004] OBJ_setct_CapReqTBS */ +0x67,0x2A,0x00,0x1B, /* [4008] OBJ_setct_CapReqTBSX */ +0x67,0x2A,0x00,0x1C, /* [4012] OBJ_setct_CapResData */ +0x67,0x2A,0x00,0x1D, /* [4016] OBJ_setct_CapRevReqTBS */ +0x67,0x2A,0x00,0x1E, /* [4020] OBJ_setct_CapRevReqTBSX */ +0x67,0x2A,0x00,0x1F, /* [4024] OBJ_setct_CapRevResData */ +0x67,0x2A,0x00,0x20, /* [4028] OBJ_setct_CredReqTBS */ +0x67,0x2A,0x00,0x21, /* [4032] OBJ_setct_CredReqTBSX */ +0x67,0x2A,0x00,0x22, /* [4036] OBJ_setct_CredResData */ +0x67,0x2A,0x00,0x23, /* [4040] OBJ_setct_CredRevReqTBS */ +0x67,0x2A,0x00,0x24, /* [4044] OBJ_setct_CredRevReqTBSX */ +0x67,0x2A,0x00,0x25, /* [4048] OBJ_setct_CredRevResData */ +0x67,0x2A,0x00,0x26, /* [4052] OBJ_setct_PCertReqData */ +0x67,0x2A,0x00,0x27, /* [4056] OBJ_setct_PCertResTBS */ +0x67,0x2A,0x00,0x28, /* [4060] OBJ_setct_BatchAdminReqData */ +0x67,0x2A,0x00,0x29, /* [4064] OBJ_setct_BatchAdminResData */ +0x67,0x2A,0x00,0x2A, /* [4068] OBJ_setct_CardCInitResTBS */ +0x67,0x2A,0x00,0x2B, /* [4072] OBJ_setct_MeAqCInitResTBS */ +0x67,0x2A,0x00,0x2C, /* [4076] OBJ_setct_RegFormResTBS */ +0x67,0x2A,0x00,0x2D, /* [4080] OBJ_setct_CertReqData */ +0x67,0x2A,0x00,0x2E, /* [4084] OBJ_setct_CertReqTBS */ +0x67,0x2A,0x00,0x2F, /* [4088] OBJ_setct_CertResData */ +0x67,0x2A,0x00,0x30, /* [4092] OBJ_setct_CertInqReqTBS */ +0x67,0x2A,0x00,0x31, /* [4096] OBJ_setct_ErrorTBS */ +0x67,0x2A,0x00,0x32, /* [4100] OBJ_setct_PIDualSignedTBE */ +0x67,0x2A,0x00,0x33, /* [4104] OBJ_setct_PIUnsignedTBE */ +0x67,0x2A,0x00,0x34, /* [4108] OBJ_setct_AuthReqTBE */ +0x67,0x2A,0x00,0x35, /* [4112] OBJ_setct_AuthResTBE */ +0x67,0x2A,0x00,0x36, /* [4116] OBJ_setct_AuthResTBEX */ +0x67,0x2A,0x00,0x37, /* [4120] OBJ_setct_AuthTokenTBE */ +0x67,0x2A,0x00,0x38, /* [4124] OBJ_setct_CapTokenTBE */ +0x67,0x2A,0x00,0x39, /* [4128] OBJ_setct_CapTokenTBEX */ +0x67,0x2A,0x00,0x3A, /* [4132] OBJ_setct_AcqCardCodeMsgTBE */ +0x67,0x2A,0x00,0x3B, /* [4136] OBJ_setct_AuthRevReqTBE */ +0x67,0x2A,0x00,0x3C, /* [4140] OBJ_setct_AuthRevResTBE */ +0x67,0x2A,0x00,0x3D, /* [4144] OBJ_setct_AuthRevResTBEB */ +0x67,0x2A,0x00,0x3E, /* [4148] OBJ_setct_CapReqTBE */ +0x67,0x2A,0x00,0x3F, /* [4152] OBJ_setct_CapReqTBEX */ +0x67,0x2A,0x00,0x40, /* [4156] OBJ_setct_CapResTBE */ +0x67,0x2A,0x00,0x41, /* [4160] OBJ_setct_CapRevReqTBE */ +0x67,0x2A,0x00,0x42, /* [4164] OBJ_setct_CapRevReqTBEX */ +0x67,0x2A,0x00,0x43, /* [4168] OBJ_setct_CapRevResTBE */ +0x67,0x2A,0x00,0x44, /* [4172] OBJ_setct_CredReqTBE */ +0x67,0x2A,0x00,0x45, /* [4176] OBJ_setct_CredReqTBEX */ +0x67,0x2A,0x00,0x46, /* [4180] OBJ_setct_CredResTBE */ +0x67,0x2A,0x00,0x47, /* [4184] OBJ_setct_CredRevReqTBE */ +0x67,0x2A,0x00,0x48, /* [4188] OBJ_setct_CredRevReqTBEX */ +0x67,0x2A,0x00,0x49, /* [4192] OBJ_setct_CredRevResTBE */ +0x67,0x2A,0x00,0x4A, /* [4196] OBJ_setct_BatchAdminReqTBE */ +0x67,0x2A,0x00,0x4B, /* [4200] OBJ_setct_BatchAdminResTBE */ +0x67,0x2A,0x00,0x4C, /* [4204] OBJ_setct_RegFormReqTBE */ +0x67,0x2A,0x00,0x4D, /* [4208] OBJ_setct_CertReqTBE */ +0x67,0x2A,0x00,0x4E, /* [4212] OBJ_setct_CertReqTBEX */ +0x67,0x2A,0x00,0x4F, /* [4216] OBJ_setct_CertResTBE */ +0x67,0x2A,0x00,0x50, /* [4220] OBJ_setct_CRLNotificationTBS */ +0x67,0x2A,0x00,0x51, /* [4224] OBJ_setct_CRLNotificationResTBS */ +0x67,0x2A,0x00,0x52, /* [4228] OBJ_setct_BCIDistributionTBS */ +0x67,0x2A,0x01,0x01, /* [4232] OBJ_setext_genCrypt */ +0x67,0x2A,0x01,0x03, /* [4236] OBJ_setext_miAuth */ +0x67,0x2A,0x01,0x04, /* [4240] OBJ_setext_pinSecure */ +0x67,0x2A,0x01,0x05, /* [4244] OBJ_setext_pinAny */ +0x67,0x2A,0x01,0x07, /* [4248] OBJ_setext_track2 */ +0x67,0x2A,0x01,0x08, /* [4252] OBJ_setext_cv */ +0x67,0x2A,0x05,0x00, /* [4256] OBJ_set_policy_root */ +0x67,0x2A,0x07,0x00, /* [4260] OBJ_setCext_hashedRoot */ +0x67,0x2A,0x07,0x01, /* [4264] OBJ_setCext_certType */ +0x67,0x2A,0x07,0x02, /* [4268] OBJ_setCext_merchData */ +0x67,0x2A,0x07,0x03, /* [4272] OBJ_setCext_cCertRequired */ +0x67,0x2A,0x07,0x04, /* [4276] OBJ_setCext_tunneling */ +0x67,0x2A,0x07,0x05, /* [4280] OBJ_setCext_setExt */ +0x67,0x2A,0x07,0x06, /* [4284] OBJ_setCext_setQualf */ +0x67,0x2A,0x07,0x07, /* [4288] OBJ_setCext_PGWYcapabilities */ +0x67,0x2A,0x07,0x08, /* [4292] OBJ_setCext_TokenIdentifier */ +0x67,0x2A,0x07,0x09, /* [4296] OBJ_setCext_Track2Data */ +0x67,0x2A,0x07,0x0A, /* [4300] OBJ_setCext_TokenType */ +0x67,0x2A,0x07,0x0B, /* [4304] OBJ_setCext_IssuerCapabilities */ +0x67,0x2A,0x03,0x00, /* [4308] OBJ_setAttr_Cert */ +0x67,0x2A,0x03,0x01, /* [4312] OBJ_setAttr_PGWYcap */ +0x67,0x2A,0x03,0x02, /* [4316] OBJ_setAttr_TokenType */ +0x67,0x2A,0x03,0x03, /* [4320] OBJ_setAttr_IssCap */ +0x67,0x2A,0x03,0x00,0x00, /* [4324] OBJ_set_rootKeyThumb */ +0x67,0x2A,0x03,0x00,0x01, /* [4329] OBJ_set_addPolicy */ +0x67,0x2A,0x03,0x02,0x01, /* [4334] OBJ_setAttr_Token_EMV */ +0x67,0x2A,0x03,0x02,0x02, /* [4339] OBJ_setAttr_Token_B0Prime */ +0x67,0x2A,0x03,0x03,0x03, /* [4344] OBJ_setAttr_IssCap_CVM */ +0x67,0x2A,0x03,0x03,0x04, /* [4349] OBJ_setAttr_IssCap_T2 */ +0x67,0x2A,0x03,0x03,0x05, /* [4354] OBJ_setAttr_IssCap_Sig */ +0x67,0x2A,0x03,0x03,0x03,0x01, /* [4359] OBJ_setAttr_GenCryptgrm */ +0x67,0x2A,0x03,0x03,0x04,0x01, /* [4365] OBJ_setAttr_T2Enc */ +0x67,0x2A,0x03,0x03,0x04,0x02, /* [4371] OBJ_setAttr_T2cleartxt */ +0x67,0x2A,0x03,0x03,0x05,0x01, /* [4377] OBJ_setAttr_TokICCsig */ +0x67,0x2A,0x03,0x03,0x05,0x02, /* [4383] OBJ_setAttr_SecDevSig */ +0x67,0x2A,0x08,0x01, /* [4389] OBJ_set_brand_IATA_ATA */ +0x67,0x2A,0x08,0x1E, /* [4393] OBJ_set_brand_Diners */ +0x67,0x2A,0x08,0x22, /* [4397] OBJ_set_brand_AmericanExpress */ +0x67,0x2A,0x08,0x23, /* [4401] OBJ_set_brand_JCB */ +0x67,0x2A,0x08,0x04, /* [4405] OBJ_set_brand_Visa */ +0x67,0x2A,0x08,0x05, /* [4409] OBJ_set_brand_MasterCard */ +0x67,0x2A,0x08,0xAE,0x7B, /* [4413] OBJ_set_brand_Novus */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x03,0x0A, /* [4418] OBJ_des_cdmf */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x06,/* [4426] OBJ_rsaOAEPEncryptionSET */ +0x67, /* [4435] OBJ_international_organizations */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x02,/* [4436] OBJ_ms_smartcard_login */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x14,0x02,0x03,/* [4446] OBJ_ms_upn */ +0x55,0x04,0x09, /* [4456] OBJ_streetAddress */ +0x55,0x04,0x11, /* [4459] OBJ_postalCode */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x15, /* [4462] OBJ_id_ppl */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x0E, /* [4469] OBJ_proxyCertInfo */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x00, /* [4477] OBJ_id_ppl_anyLanguage */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x01, /* [4485] OBJ_id_ppl_inheritAll */ +0x55,0x1D,0x1E, /* [4493] OBJ_name_constraints */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x15,0x02, /* [4496] OBJ_Independent */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0B,/* [4504] OBJ_sha256WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0C,/* [4513] OBJ_sha384WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0D,/* [4522] OBJ_sha512WithRSAEncryption */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0E,/* [4531] OBJ_sha224WithRSAEncryption */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x01,/* [4540] OBJ_sha256 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x02,/* [4549] OBJ_sha384 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x03,/* [4558] OBJ_sha512 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x02,0x04,/* [4567] OBJ_sha224 */ +0x2B, /* [4576] OBJ_identified_organization */ +0x2B,0x81,0x04, /* [4577] OBJ_certicom_arc */ +0x67,0x2B, /* [4580] OBJ_wap */ +0x67,0x2B,0x01, /* [4582] OBJ_wap_wsg */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03, /* [4585] OBJ_X9_62_id_characteristic_two_basis */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x01,/* [4593] OBJ_X9_62_onBasis */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x02,/* [4602] OBJ_X9_62_tpBasis */ +0x2A,0x86,0x48,0xCE,0x3D,0x01,0x02,0x03,0x03,/* [4611] OBJ_X9_62_ppBasis */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x01, /* [4620] OBJ_X9_62_c2pnb163v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x02, /* [4628] OBJ_X9_62_c2pnb163v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x03, /* [4636] OBJ_X9_62_c2pnb163v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x04, /* [4644] OBJ_X9_62_c2pnb176v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x05, /* [4652] OBJ_X9_62_c2tnb191v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x06, /* [4660] OBJ_X9_62_c2tnb191v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x07, /* [4668] OBJ_X9_62_c2tnb191v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x08, /* [4676] OBJ_X9_62_c2onb191v4 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x09, /* [4684] OBJ_X9_62_c2onb191v5 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0A, /* [4692] OBJ_X9_62_c2pnb208w1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0B, /* [4700] OBJ_X9_62_c2tnb239v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0C, /* [4708] OBJ_X9_62_c2tnb239v2 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0D, /* [4716] OBJ_X9_62_c2tnb239v3 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0E, /* [4724] OBJ_X9_62_c2onb239v4 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x0F, /* [4732] OBJ_X9_62_c2onb239v5 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x10, /* [4740] OBJ_X9_62_c2pnb272w1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x11, /* [4748] OBJ_X9_62_c2pnb304w1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x12, /* [4756] OBJ_X9_62_c2tnb359v1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x13, /* [4764] OBJ_X9_62_c2pnb368w1 */ +0x2A,0x86,0x48,0xCE,0x3D,0x03,0x00,0x14, /* [4772] OBJ_X9_62_c2tnb431r1 */ +0x2B,0x81,0x04,0x00,0x06, /* [4780] OBJ_secp112r1 */ +0x2B,0x81,0x04,0x00,0x07, /* [4785] OBJ_secp112r2 */ +0x2B,0x81,0x04,0x00,0x1C, /* [4790] OBJ_secp128r1 */ +0x2B,0x81,0x04,0x00,0x1D, /* [4795] OBJ_secp128r2 */ +0x2B,0x81,0x04,0x00,0x09, /* [4800] OBJ_secp160k1 */ +0x2B,0x81,0x04,0x00,0x08, /* [4805] OBJ_secp160r1 */ +0x2B,0x81,0x04,0x00,0x1E, /* [4810] OBJ_secp160r2 */ +0x2B,0x81,0x04,0x00,0x1F, /* [4815] OBJ_secp192k1 */ +0x2B,0x81,0x04,0x00,0x20, /* [4820] OBJ_secp224k1 */ +0x2B,0x81,0x04,0x00,0x21, /* [4825] OBJ_secp224r1 */ +0x2B,0x81,0x04,0x00,0x0A, /* [4830] OBJ_secp256k1 */ +0x2B,0x81,0x04,0x00,0x22, /* [4835] OBJ_secp384r1 */ +0x2B,0x81,0x04,0x00,0x23, /* [4840] OBJ_secp521r1 */ +0x2B,0x81,0x04,0x00,0x04, /* [4845] OBJ_sect113r1 */ +0x2B,0x81,0x04,0x00,0x05, /* [4850] OBJ_sect113r2 */ +0x2B,0x81,0x04,0x00,0x16, /* [4855] OBJ_sect131r1 */ +0x2B,0x81,0x04,0x00,0x17, /* [4860] OBJ_sect131r2 */ +0x2B,0x81,0x04,0x00,0x01, /* [4865] OBJ_sect163k1 */ +0x2B,0x81,0x04,0x00,0x02, /* [4870] OBJ_sect163r1 */ +0x2B,0x81,0x04,0x00,0x0F, /* [4875] OBJ_sect163r2 */ +0x2B,0x81,0x04,0x00,0x18, /* [4880] OBJ_sect193r1 */ +0x2B,0x81,0x04,0x00,0x19, /* [4885] OBJ_sect193r2 */ +0x2B,0x81,0x04,0x00,0x1A, /* [4890] OBJ_sect233k1 */ +0x2B,0x81,0x04,0x00,0x1B, /* [4895] OBJ_sect233r1 */ +0x2B,0x81,0x04,0x00,0x03, /* [4900] OBJ_sect239k1 */ +0x2B,0x81,0x04,0x00,0x10, /* [4905] OBJ_sect283k1 */ +0x2B,0x81,0x04,0x00,0x11, /* [4910] OBJ_sect283r1 */ +0x2B,0x81,0x04,0x00,0x24, /* [4915] OBJ_sect409k1 */ +0x2B,0x81,0x04,0x00,0x25, /* [4920] OBJ_sect409r1 */ +0x2B,0x81,0x04,0x00,0x26, /* [4925] OBJ_sect571k1 */ +0x2B,0x81,0x04,0x00,0x27, /* [4930] OBJ_sect571r1 */ +0x67,0x2B,0x01,0x04,0x01, /* [4935] OBJ_wap_wsg_idm_ecid_wtls1 */ +0x67,0x2B,0x01,0x04,0x03, /* [4940] OBJ_wap_wsg_idm_ecid_wtls3 */ +0x67,0x2B,0x01,0x04,0x04, /* [4945] OBJ_wap_wsg_idm_ecid_wtls4 */ +0x67,0x2B,0x01,0x04,0x05, /* [4950] OBJ_wap_wsg_idm_ecid_wtls5 */ +0x67,0x2B,0x01,0x04,0x06, /* [4955] OBJ_wap_wsg_idm_ecid_wtls6 */ +0x67,0x2B,0x01,0x04,0x07, /* [4960] OBJ_wap_wsg_idm_ecid_wtls7 */ +0x67,0x2B,0x01,0x04,0x08, /* [4965] OBJ_wap_wsg_idm_ecid_wtls8 */ +0x67,0x2B,0x01,0x04,0x09, /* [4970] OBJ_wap_wsg_idm_ecid_wtls9 */ +0x67,0x2B,0x01,0x04,0x0A, /* [4975] OBJ_wap_wsg_idm_ecid_wtls10 */ +0x67,0x2B,0x01,0x04,0x0B, /* [4980] OBJ_wap_wsg_idm_ecid_wtls11 */ +0x67,0x2B,0x01,0x04,0x0C, /* [4985] OBJ_wap_wsg_idm_ecid_wtls12 */ +0x55,0x1D,0x20,0x00, /* [4990] OBJ_any_policy */ +0x55,0x1D,0x21, /* [4994] OBJ_policy_mappings */ +0x55,0x1D,0x36, /* [4997] OBJ_inhibit_any_policy */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x02,/* [5000] OBJ_camellia_128_cbc */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x03,/* [5011] OBJ_camellia_192_cbc */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x01,0x04,/* [5022] OBJ_camellia_256_cbc */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x01, /* [5033] OBJ_camellia_128_ecb */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x15, /* [5041] OBJ_camellia_192_ecb */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x29, /* [5049] OBJ_camellia_256_ecb */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x04, /* [5057] OBJ_camellia_128_cfb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x18, /* [5065] OBJ_camellia_192_cfb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2C, /* [5073] OBJ_camellia_256_cfb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x03, /* [5081] OBJ_camellia_128_ofb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x17, /* [5089] OBJ_camellia_192_ofb128 */ +0x03,0xA2,0x31,0x05,0x03,0x01,0x09,0x2B, /* [5097] OBJ_camellia_256_ofb128 */ +0x55,0x1D,0x09, /* [5105] OBJ_subject_directory_attributes */ +0x55,0x1D,0x1C, /* [5108] OBJ_issuing_distribution_point */ +0x55,0x1D,0x1D, /* [5111] OBJ_certificate_issuer */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44, /* [5114] OBJ_kisa */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x03, /* [5120] OBJ_seed_ecb */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x04, /* [5128] OBJ_seed_cbc */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x06, /* [5136] OBJ_seed_ofb128 */ +0x2A,0x83,0x1A,0x8C,0x9A,0x44,0x01,0x05, /* [5144] OBJ_seed_cfb128 */ +0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x01, /* [5152] OBJ_hmac_md5 */ +0x2B,0x06,0x01,0x05,0x05,0x08,0x01,0x02, /* [5160] OBJ_hmac_sha1 */ +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x0D,/* [5168] OBJ_id_PasswordBasedMAC */ +0x2A,0x86,0x48,0x86,0xF6,0x7D,0x07,0x42,0x1E,/* [5177] OBJ_id_DHBasedMac */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x04,0x10, /* [5186] OBJ_id_it_suppLangTags */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x30,0x05, /* [5194] OBJ_caRepository */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x09,/* [5202] OBJ_id_smime_ct_compressedData */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x01,0x1B,/* [5213] OBJ_id_ct_asciiTextWithCRLF */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x05,/* [5224] OBJ_id_aes128_wrap */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x19,/* [5233] OBJ_id_aes192_wrap */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2D,/* [5242] OBJ_id_aes256_wrap */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x02, /* [5251] OBJ_ecdsa_with_Recommended */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03, /* [5258] OBJ_ecdsa_with_Specified */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x01, /* [5265] OBJ_ecdsa_with_SHA224 */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x02, /* [5273] OBJ_ecdsa_with_SHA256 */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x03, /* [5281] OBJ_ecdsa_with_SHA384 */ +0x2A,0x86,0x48,0xCE,0x3D,0x04,0x03,0x04, /* [5289] OBJ_ecdsa_with_SHA512 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x06, /* [5297] OBJ_hmacWithMD5 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x08, /* [5305] OBJ_hmacWithSHA224 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x09, /* [5313] OBJ_hmacWithSHA256 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0A, /* [5321] OBJ_hmacWithSHA384 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0B, /* [5329] OBJ_hmacWithSHA512 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x01,/* [5337] OBJ_dsa_with_SHA224 */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x03,0x02,/* [5346] OBJ_dsa_with_SHA256 */ +0x28,0xCF,0x06,0x03,0x00,0x37, /* [5355] OBJ_whirlpool */ +0x2A,0x85,0x03,0x02,0x02, /* [5361] OBJ_cryptopro */ +0x2A,0x85,0x03,0x02,0x09, /* [5366] OBJ_cryptocom */ +0x2A,0x85,0x03,0x02,0x02,0x03, /* [5371] OBJ_id_GostR3411_94_with_GostR3410_2001 */ +0x2A,0x85,0x03,0x02,0x02,0x04, /* [5377] OBJ_id_GostR3411_94_with_GostR3410_94 */ +0x2A,0x85,0x03,0x02,0x02,0x09, /* [5383] OBJ_id_GostR3411_94 */ +0x2A,0x85,0x03,0x02,0x02,0x0A, /* [5389] OBJ_id_HMACGostR3411_94 */ +0x2A,0x85,0x03,0x02,0x02,0x13, /* [5395] OBJ_id_GostR3410_2001 */ +0x2A,0x85,0x03,0x02,0x02,0x14, /* [5401] OBJ_id_GostR3410_94 */ +0x2A,0x85,0x03,0x02,0x02,0x15, /* [5407] OBJ_id_Gost28147_89 */ +0x2A,0x85,0x03,0x02,0x02,0x16, /* [5413] OBJ_id_Gost28147_89_MAC */ +0x2A,0x85,0x03,0x02,0x02,0x17, /* [5419] OBJ_id_GostR3411_94_prf */ +0x2A,0x85,0x03,0x02,0x02,0x62, /* [5425] OBJ_id_GostR3410_2001DH */ +0x2A,0x85,0x03,0x02,0x02,0x63, /* [5431] OBJ_id_GostR3410_94DH */ +0x2A,0x85,0x03,0x02,0x02,0x0E,0x01, /* [5437] OBJ_id_Gost28147_89_CryptoPro_KeyMeshing */ +0x2A,0x85,0x03,0x02,0x02,0x0E,0x00, /* [5444] OBJ_id_Gost28147_89_None_KeyMeshing */ +0x2A,0x85,0x03,0x02,0x02,0x1E,0x00, /* [5451] OBJ_id_GostR3411_94_TestParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1E,0x01, /* [5458] OBJ_id_GostR3411_94_CryptoProParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x00, /* [5465] OBJ_id_Gost28147_89_TestParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x01, /* [5472] OBJ_id_Gost28147_89_CryptoPro_A_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x02, /* [5479] OBJ_id_Gost28147_89_CryptoPro_B_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x03, /* [5486] OBJ_id_Gost28147_89_CryptoPro_C_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x04, /* [5493] OBJ_id_Gost28147_89_CryptoPro_D_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x05, /* [5500] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x06, /* [5507] OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x1F,0x07, /* [5514] OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x00, /* [5521] OBJ_id_GostR3410_94_TestParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x02, /* [5528] OBJ_id_GostR3410_94_CryptoPro_A_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x03, /* [5535] OBJ_id_GostR3410_94_CryptoPro_B_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x04, /* [5542] OBJ_id_GostR3410_94_CryptoPro_C_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x20,0x05, /* [5549] OBJ_id_GostR3410_94_CryptoPro_D_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x21,0x01, /* [5556] OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x21,0x02, /* [5563] OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x21,0x03, /* [5570] OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x23,0x00, /* [5577] OBJ_id_GostR3410_2001_TestParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x23,0x01, /* [5584] OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x23,0x02, /* [5591] OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x23,0x03, /* [5598] OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x24,0x00, /* [5605] OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x24,0x01, /* [5612] OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet */ +0x2A,0x85,0x03,0x02,0x02,0x14,0x01, /* [5619] OBJ_id_GostR3410_94_a */ +0x2A,0x85,0x03,0x02,0x02,0x14,0x02, /* [5626] OBJ_id_GostR3410_94_aBis */ +0x2A,0x85,0x03,0x02,0x02,0x14,0x03, /* [5633] OBJ_id_GostR3410_94_b */ +0x2A,0x85,0x03,0x02,0x02,0x14,0x04, /* [5640] OBJ_id_GostR3410_94_bBis */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x06,0x01, /* [5647] OBJ_id_Gost28147_89_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x03, /* [5655] OBJ_id_GostR3410_94_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x05,0x04, /* [5663] OBJ_id_GostR3410_2001_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x03, /* [5671] OBJ_id_GostR3411_94_with_GostR3410_94_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x03,0x04, /* [5679] OBJ_id_GostR3411_94_with_GostR3410_2001_cc */ +0x2A,0x85,0x03,0x02,0x09,0x01,0x08,0x01, /* [5687] OBJ_id_GostR3410_2001_ParamSet_cc */ +0x2B,0x06,0x01,0x04,0x01,0x82,0x37,0x11,0x02,/* [5695] OBJ_LocalKeySet */ +0x55,0x1D,0x2E, /* [5704] OBJ_freshest_crl */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x08,0x03, /* [5707] OBJ_id_on_permanentIdentifier */ +0x55,0x04,0x0E, /* [5715] OBJ_searchGuide */ +0x55,0x04,0x0F, /* [5718] OBJ_businessCategory */ +0x55,0x04,0x10, /* [5721] OBJ_postalAddress */ +0x55,0x04,0x12, /* [5724] OBJ_postOfficeBox */ +0x55,0x04,0x13, /* [5727] OBJ_physicalDeliveryOfficeName */ +0x55,0x04,0x14, /* [5730] OBJ_telephoneNumber */ +0x55,0x04,0x15, /* [5733] OBJ_telexNumber */ +0x55,0x04,0x16, /* [5736] OBJ_teletexTerminalIdentifier */ +0x55,0x04,0x17, /* [5739] OBJ_facsimileTelephoneNumber */ +0x55,0x04,0x18, /* [5742] OBJ_x121Address */ +0x55,0x04,0x19, /* [5745] OBJ_internationaliSDNNumber */ +0x55,0x04,0x1A, /* [5748] OBJ_registeredAddress */ +0x55,0x04,0x1B, /* [5751] OBJ_destinationIndicator */ +0x55,0x04,0x1C, /* [5754] OBJ_preferredDeliveryMethod */ +0x55,0x04,0x1D, /* [5757] OBJ_presentationAddress */ +0x55,0x04,0x1E, /* [5760] OBJ_supportedApplicationContext */ +0x55,0x04,0x1F, /* [5763] OBJ_member */ +0x55,0x04,0x20, /* [5766] OBJ_owner */ +0x55,0x04,0x21, /* [5769] OBJ_roleOccupant */ +0x55,0x04,0x22, /* [5772] OBJ_seeAlso */ +0x55,0x04,0x23, /* [5775] OBJ_userPassword */ +0x55,0x04,0x24, /* [5778] OBJ_userCertificate */ +0x55,0x04,0x25, /* [5781] OBJ_cACertificate */ +0x55,0x04,0x26, /* [5784] OBJ_authorityRevocationList */ +0x55,0x04,0x27, /* [5787] OBJ_certificateRevocationList */ +0x55,0x04,0x28, /* [5790] OBJ_crossCertificatePair */ +0x55,0x04,0x2F, /* [5793] OBJ_enhancedSearchGuide */ +0x55,0x04,0x30, /* [5796] OBJ_protocolInformation */ +0x55,0x04,0x31, /* [5799] OBJ_distinguishedName */ +0x55,0x04,0x32, /* [5802] OBJ_uniqueMember */ +0x55,0x04,0x33, /* [5805] OBJ_houseIdentifier */ +0x55,0x04,0x34, /* [5808] OBJ_supportedAlgorithms */ +0x55,0x04,0x35, /* [5811] OBJ_deltaRevocationList */ +0x55,0x04,0x36, /* [5814] OBJ_dmdName */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x09,0x10,0x03,0x09,/* [5817] OBJ_id_alg_PWRI_KEK */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x06,/* [5828] OBJ_aes_128_gcm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x07,/* [5837] OBJ_aes_128_ccm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x08,/* [5846] OBJ_id_aes128_wrap_pad */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1A,/* [5855] OBJ_aes_192_gcm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1B,/* [5864] OBJ_aes_192_ccm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x1C,/* [5873] OBJ_id_aes192_wrap_pad */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2E,/* [5882] OBJ_aes_256_gcm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x2F,/* [5891] OBJ_aes_256_ccm */ +0x60,0x86,0x48,0x01,0x65,0x03,0x04,0x01,0x30,/* [5900] OBJ_id_aes256_wrap_pad */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x02,/* [5909] OBJ_id_camellia128_wrap */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x03,/* [5920] OBJ_id_camellia192_wrap */ +0x2A,0x83,0x08,0x8C,0x9A,0x4B,0x3D,0x01,0x01,0x03,0x04,/* [5931] OBJ_id_camellia256_wrap */ +0x55,0x1D,0x25,0x00, /* [5942] OBJ_anyExtendedKeyUsage */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x08,/* [5946] OBJ_mgf1 */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x0A,/* [5955] OBJ_rsassaPss */ +0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01,0x01,0x07,/* [5964] OBJ_rsaesOaep */ +}; + +static const ASN1_OBJECT nid_objs[NUM_NID]={ +{"UNDEF","undefined",NID_undef,0,NULL,0}, +{"rsadsi","RSA Data Security, Inc.",NID_rsadsi,6,&(lvalues[0]),0}, +{"pkcs","RSA Data Security, Inc. PKCS",NID_pkcs,7,&(lvalues[6]),0}, +{"MD2","md2",NID_md2,8,&(lvalues[13]),0}, +{"MD5","md5",NID_md5,8,&(lvalues[21]),0}, +{"RC4","rc4",NID_rc4,8,&(lvalues[29]),0}, +{"rsaEncryption","rsaEncryption",NID_rsaEncryption,9,&(lvalues[37]),0}, +{"RSA-MD2","md2WithRSAEncryption",NID_md2WithRSAEncryption,9, + &(lvalues[46]),0}, +{"RSA-MD5","md5WithRSAEncryption",NID_md5WithRSAEncryption,9, + &(lvalues[55]),0}, +{"PBE-MD2-DES","pbeWithMD2AndDES-CBC",NID_pbeWithMD2AndDES_CBC,9, + &(lvalues[64]),0}, +{"PBE-MD5-DES","pbeWithMD5AndDES-CBC",NID_pbeWithMD5AndDES_CBC,9, + &(lvalues[73]),0}, +{"X500","directory services (X.500)",NID_X500,1,&(lvalues[82]),0}, +{"X509","X509",NID_X509,2,&(lvalues[83]),0}, +{"CN","commonName",NID_commonName,3,&(lvalues[85]),0}, +{"C","countryName",NID_countryName,3,&(lvalues[88]),0}, +{"L","localityName",NID_localityName,3,&(lvalues[91]),0}, +{"ST","stateOrProvinceName",NID_stateOrProvinceName,3,&(lvalues[94]),0}, +{"O","organizationName",NID_organizationName,3,&(lvalues[97]),0}, +{"OU","organizationalUnitName",NID_organizationalUnitName,3, + &(lvalues[100]),0}, +{"RSA","rsa",NID_rsa,4,&(lvalues[103]),0}, +{"pkcs7","pkcs7",NID_pkcs7,8,&(lvalues[107]),0}, +{"pkcs7-data","pkcs7-data",NID_pkcs7_data,9,&(lvalues[115]),0}, +{"pkcs7-signedData","pkcs7-signedData",NID_pkcs7_signed,9, + &(lvalues[124]),0}, +{"pkcs7-envelopedData","pkcs7-envelopedData",NID_pkcs7_enveloped,9, + &(lvalues[133]),0}, +{"pkcs7-signedAndEnvelopedData","pkcs7-signedAndEnvelopedData", + NID_pkcs7_signedAndEnveloped,9,&(lvalues[142]),0}, +{"pkcs7-digestData","pkcs7-digestData",NID_pkcs7_digest,9, + &(lvalues[151]),0}, +{"pkcs7-encryptedData","pkcs7-encryptedData",NID_pkcs7_encrypted,9, + &(lvalues[160]),0}, +{"pkcs3","pkcs3",NID_pkcs3,8,&(lvalues[169]),0}, +{"dhKeyAgreement","dhKeyAgreement",NID_dhKeyAgreement,9, + &(lvalues[177]),0}, +{"DES-ECB","des-ecb",NID_des_ecb,5,&(lvalues[186]),0}, +{"DES-CFB","des-cfb",NID_des_cfb64,5,&(lvalues[191]),0}, +{"DES-CBC","des-cbc",NID_des_cbc,5,&(lvalues[196]),0}, +{"DES-EDE","des-ede",NID_des_ede_ecb,5,&(lvalues[201]),0}, +{"DES-EDE3","des-ede3",NID_des_ede3_ecb,0,NULL,0}, +{"IDEA-CBC","idea-cbc",NID_idea_cbc,11,&(lvalues[206]),0}, +{"IDEA-CFB","idea-cfb",NID_idea_cfb64,0,NULL,0}, +{"IDEA-ECB","idea-ecb",NID_idea_ecb,0,NULL,0}, +{"RC2-CBC","rc2-cbc",NID_rc2_cbc,8,&(lvalues[217]),0}, +{"RC2-ECB","rc2-ecb",NID_rc2_ecb,0,NULL,0}, +{"RC2-CFB","rc2-cfb",NID_rc2_cfb64,0,NULL,0}, +{"RC2-OFB","rc2-ofb",NID_rc2_ofb64,0,NULL,0}, +{"SHA","sha",NID_sha,5,&(lvalues[225]),0}, +{"RSA-SHA","shaWithRSAEncryption",NID_shaWithRSAEncryption,5, + &(lvalues[230]),0}, +{"DES-EDE-CBC","des-ede-cbc",NID_des_ede_cbc,0,NULL,0}, +{"DES-EDE3-CBC","des-ede3-cbc",NID_des_ede3_cbc,8,&(lvalues[235]),0}, +{"DES-OFB","des-ofb",NID_des_ofb64,5,&(lvalues[243]),0}, +{"IDEA-OFB","idea-ofb",NID_idea_ofb64,0,NULL,0}, +{"pkcs9","pkcs9",NID_pkcs9,8,&(lvalues[248]),0}, +{"emailAddress","emailAddress",NID_pkcs9_emailAddress,9, + &(lvalues[256]),0}, +{"unstructuredName","unstructuredName",NID_pkcs9_unstructuredName,9, + &(lvalues[265]),0}, +{"contentType","contentType",NID_pkcs9_contentType,9,&(lvalues[274]),0}, +{"messageDigest","messageDigest",NID_pkcs9_messageDigest,9, + &(lvalues[283]),0}, +{"signingTime","signingTime",NID_pkcs9_signingTime,9,&(lvalues[292]),0}, +{"countersignature","countersignature",NID_pkcs9_countersignature,9, + &(lvalues[301]),0}, +{"challengePassword","challengePassword",NID_pkcs9_challengePassword, + 9,&(lvalues[310]),0}, +{"unstructuredAddress","unstructuredAddress", + NID_pkcs9_unstructuredAddress,9,&(lvalues[319]),0}, +{"extendedCertificateAttributes","extendedCertificateAttributes", + NID_pkcs9_extCertAttributes,9,&(lvalues[328]),0}, +{"Netscape","Netscape Communications Corp.",NID_netscape,7, + &(lvalues[337]),0}, +{"nsCertExt","Netscape Certificate Extension", + NID_netscape_cert_extension,8,&(lvalues[344]),0}, +{"nsDataType","Netscape Data Type",NID_netscape_data_type,8, + &(lvalues[352]),0}, +{"DES-EDE-CFB","des-ede-cfb",NID_des_ede_cfb64,0,NULL,0}, +{"DES-EDE3-CFB","des-ede3-cfb",NID_des_ede3_cfb64,0,NULL,0}, +{"DES-EDE-OFB","des-ede-ofb",NID_des_ede_ofb64,0,NULL,0}, +{"DES-EDE3-OFB","des-ede3-ofb",NID_des_ede3_ofb64,0,NULL,0}, +{"SHA1","sha1",NID_sha1,5,&(lvalues[360]),0}, +{"RSA-SHA1","sha1WithRSAEncryption",NID_sha1WithRSAEncryption,9, + &(lvalues[365]),0}, +{"DSA-SHA","dsaWithSHA",NID_dsaWithSHA,5,&(lvalues[374]),0}, +{"DSA-old","dsaEncryption-old",NID_dsa_2,5,&(lvalues[379]),0}, +{"PBE-SHA1-RC2-64","pbeWithSHA1AndRC2-CBC",NID_pbeWithSHA1AndRC2_CBC, + 9,&(lvalues[384]),0}, +{"PBKDF2","PBKDF2",NID_id_pbkdf2,9,&(lvalues[393]),0}, +{"DSA-SHA1-old","dsaWithSHA1-old",NID_dsaWithSHA1_2,5,&(lvalues[402]),0}, +{"nsCertType","Netscape Cert Type",NID_netscape_cert_type,9, + &(lvalues[407]),0}, +{"nsBaseUrl","Netscape Base Url",NID_netscape_base_url,9, + &(lvalues[416]),0}, +{"nsRevocationUrl","Netscape Revocation Url", + NID_netscape_revocation_url,9,&(lvalues[425]),0}, +{"nsCaRevocationUrl","Netscape CA Revocation Url", + NID_netscape_ca_revocation_url,9,&(lvalues[434]),0}, +{"nsRenewalUrl","Netscape Renewal Url",NID_netscape_renewal_url,9, + &(lvalues[443]),0}, +{"nsCaPolicyUrl","Netscape CA Policy Url",NID_netscape_ca_policy_url, + 9,&(lvalues[452]),0}, +{"nsSslServerName","Netscape SSL Server Name", + NID_netscape_ssl_server_name,9,&(lvalues[461]),0}, +{"nsComment","Netscape Comment",NID_netscape_comment,9,&(lvalues[470]),0}, +{"nsCertSequence","Netscape Certificate Sequence", + NID_netscape_cert_sequence,9,&(lvalues[479]),0}, +{"DESX-CBC","desx-cbc",NID_desx_cbc,0,NULL,0}, +{"id-ce","id-ce",NID_id_ce,2,&(lvalues[488]),0}, +{"subjectKeyIdentifier","X509v3 Subject Key Identifier", + NID_subject_key_identifier,3,&(lvalues[490]),0}, +{"keyUsage","X509v3 Key Usage",NID_key_usage,3,&(lvalues[493]),0}, +{"privateKeyUsagePeriod","X509v3 Private Key Usage Period", + NID_private_key_usage_period,3,&(lvalues[496]),0}, +{"subjectAltName","X509v3 Subject Alternative Name", + NID_subject_alt_name,3,&(lvalues[499]),0}, +{"issuerAltName","X509v3 Issuer Alternative Name",NID_issuer_alt_name, + 3,&(lvalues[502]),0}, +{"basicConstraints","X509v3 Basic Constraints",NID_basic_constraints, + 3,&(lvalues[505]),0}, +{"crlNumber","X509v3 CRL Number",NID_crl_number,3,&(lvalues[508]),0}, +{"certificatePolicies","X509v3 Certificate Policies", + NID_certificate_policies,3,&(lvalues[511]),0}, +{"authorityKeyIdentifier","X509v3 Authority Key Identifier", + NID_authority_key_identifier,3,&(lvalues[514]),0}, +{"BF-CBC","bf-cbc",NID_bf_cbc,9,&(lvalues[517]),0}, +{"BF-ECB","bf-ecb",NID_bf_ecb,0,NULL,0}, +{"BF-CFB","bf-cfb",NID_bf_cfb64,0,NULL,0}, +{"BF-OFB","bf-ofb",NID_bf_ofb64,0,NULL,0}, +{"MDC2","mdc2",NID_mdc2,4,&(lvalues[526]),0}, +{"RSA-MDC2","mdc2WithRSA",NID_mdc2WithRSA,4,&(lvalues[530]),0}, +{"RC4-40","rc4-40",NID_rc4_40,0,NULL,0}, +{"RC2-40-CBC","rc2-40-cbc",NID_rc2_40_cbc,0,NULL,0}, +{"GN","givenName",NID_givenName,3,&(lvalues[534]),0}, +{"SN","surname",NID_surname,3,&(lvalues[537]),0}, +{"initials","initials",NID_initials,3,&(lvalues[540]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"crlDistributionPoints","X509v3 CRL Distribution Points", + NID_crl_distribution_points,3,&(lvalues[543]),0}, +{"RSA-NP-MD5","md5WithRSA",NID_md5WithRSA,5,&(lvalues[546]),0}, +{"serialNumber","serialNumber",NID_serialNumber,3,&(lvalues[551]),0}, +{"title","title",NID_title,3,&(lvalues[554]),0}, +{"description","description",NID_description,3,&(lvalues[557]),0}, +{"CAST5-CBC","cast5-cbc",NID_cast5_cbc,9,&(lvalues[560]),0}, +{"CAST5-ECB","cast5-ecb",NID_cast5_ecb,0,NULL,0}, +{"CAST5-CFB","cast5-cfb",NID_cast5_cfb64,0,NULL,0}, +{"CAST5-OFB","cast5-ofb",NID_cast5_ofb64,0,NULL,0}, +{"pbeWithMD5AndCast5CBC","pbeWithMD5AndCast5CBC", + NID_pbeWithMD5AndCast5_CBC,9,&(lvalues[569]),0}, +{"DSA-SHA1","dsaWithSHA1",NID_dsaWithSHA1,7,&(lvalues[578]),0}, +{"MD5-SHA1","md5-sha1",NID_md5_sha1,0,NULL,0}, +{"RSA-SHA1-2","sha1WithRSA",NID_sha1WithRSA,5,&(lvalues[585]),0}, +{"DSA","dsaEncryption",NID_dsa,7,&(lvalues[590]),0}, +{"RIPEMD160","ripemd160",NID_ripemd160,5,&(lvalues[597]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"RSA-RIPEMD160","ripemd160WithRSA",NID_ripemd160WithRSA,6, + &(lvalues[602]),0}, +{"RC5-CBC","rc5-cbc",NID_rc5_cbc,8,&(lvalues[608]),0}, +{"RC5-ECB","rc5-ecb",NID_rc5_ecb,0,NULL,0}, +{"RC5-CFB","rc5-cfb",NID_rc5_cfb64,0,NULL,0}, +{"RC5-OFB","rc5-ofb",NID_rc5_ofb64,0,NULL,0}, +{"RLE","run length compression",NID_rle_compression,6,&(lvalues[616]),0}, +{"ZLIB","zlib compression",NID_zlib_compression,11,&(lvalues[622]),0}, +{"extendedKeyUsage","X509v3 Extended Key Usage",NID_ext_key_usage,3, + &(lvalues[633]),0}, +{"PKIX","PKIX",NID_id_pkix,6,&(lvalues[636]),0}, +{"id-kp","id-kp",NID_id_kp,7,&(lvalues[642]),0}, +{"serverAuth","TLS Web Server Authentication",NID_server_auth,8, + &(lvalues[649]),0}, +{"clientAuth","TLS Web Client Authentication",NID_client_auth,8, + &(lvalues[657]),0}, +{"codeSigning","Code Signing",NID_code_sign,8,&(lvalues[665]),0}, +{"emailProtection","E-mail Protection",NID_email_protect,8, + &(lvalues[673]),0}, +{"timeStamping","Time Stamping",NID_time_stamp,8,&(lvalues[681]),0}, +{"msCodeInd","Microsoft Individual Code Signing",NID_ms_code_ind,10, + &(lvalues[689]),0}, +{"msCodeCom","Microsoft Commercial Code Signing",NID_ms_code_com,10, + &(lvalues[699]),0}, +{"msCTLSign","Microsoft Trust List Signing",NID_ms_ctl_sign,10, + &(lvalues[709]),0}, +{"msSGC","Microsoft Server Gated Crypto",NID_ms_sgc,10,&(lvalues[719]),0}, +{"msEFS","Microsoft Encrypted File System",NID_ms_efs,10, + &(lvalues[729]),0}, +{"nsSGC","Netscape Server Gated Crypto",NID_ns_sgc,9,&(lvalues[739]),0}, +{"deltaCRL","X509v3 Delta CRL Indicator",NID_delta_crl,3, + &(lvalues[748]),0}, +{"CRLReason","X509v3 CRL Reason Code",NID_crl_reason,3,&(lvalues[751]),0}, +{"invalidityDate","Invalidity Date",NID_invalidity_date,3, + &(lvalues[754]),0}, +{"SXNetID","Strong Extranet ID",NID_sxnet,5,&(lvalues[757]),0}, +{"PBE-SHA1-RC4-128","pbeWithSHA1And128BitRC4", + NID_pbe_WithSHA1And128BitRC4,10,&(lvalues[762]),0}, +{"PBE-SHA1-RC4-40","pbeWithSHA1And40BitRC4", + NID_pbe_WithSHA1And40BitRC4,10,&(lvalues[772]),0}, +{"PBE-SHA1-3DES","pbeWithSHA1And3-KeyTripleDES-CBC", + NID_pbe_WithSHA1And3_Key_TripleDES_CBC,10,&(lvalues[782]),0}, +{"PBE-SHA1-2DES","pbeWithSHA1And2-KeyTripleDES-CBC", + NID_pbe_WithSHA1And2_Key_TripleDES_CBC,10,&(lvalues[792]),0}, +{"PBE-SHA1-RC2-128","pbeWithSHA1And128BitRC2-CBC", + NID_pbe_WithSHA1And128BitRC2_CBC,10,&(lvalues[802]),0}, +{"PBE-SHA1-RC2-40","pbeWithSHA1And40BitRC2-CBC", + NID_pbe_WithSHA1And40BitRC2_CBC,10,&(lvalues[812]),0}, +{"keyBag","keyBag",NID_keyBag,11,&(lvalues[822]),0}, +{"pkcs8ShroudedKeyBag","pkcs8ShroudedKeyBag",NID_pkcs8ShroudedKeyBag, + 11,&(lvalues[833]),0}, +{"certBag","certBag",NID_certBag,11,&(lvalues[844]),0}, +{"crlBag","crlBag",NID_crlBag,11,&(lvalues[855]),0}, +{"secretBag","secretBag",NID_secretBag,11,&(lvalues[866]),0}, +{"safeContentsBag","safeContentsBag",NID_safeContentsBag,11, + &(lvalues[877]),0}, +{"friendlyName","friendlyName",NID_friendlyName,9,&(lvalues[888]),0}, +{"localKeyID","localKeyID",NID_localKeyID,9,&(lvalues[897]),0}, +{"x509Certificate","x509Certificate",NID_x509Certificate,10, + &(lvalues[906]),0}, +{"sdsiCertificate","sdsiCertificate",NID_sdsiCertificate,10, + &(lvalues[916]),0}, +{"x509Crl","x509Crl",NID_x509Crl,10,&(lvalues[926]),0}, +{"PBES2","PBES2",NID_pbes2,9,&(lvalues[936]),0}, +{"PBMAC1","PBMAC1",NID_pbmac1,9,&(lvalues[945]),0}, +{"hmacWithSHA1","hmacWithSHA1",NID_hmacWithSHA1,8,&(lvalues[954]),0}, +{"id-qt-cps","Policy Qualifier CPS",NID_id_qt_cps,8,&(lvalues[962]),0}, +{"id-qt-unotice","Policy Qualifier User Notice",NID_id_qt_unotice,8, + &(lvalues[970]),0}, +{"RC2-64-CBC","rc2-64-cbc",NID_rc2_64_cbc,0,NULL,0}, +{"SMIME-CAPS","S/MIME Capabilities",NID_SMIMECapabilities,9, + &(lvalues[978]),0}, +{"PBE-MD2-RC2-64","pbeWithMD2AndRC2-CBC",NID_pbeWithMD2AndRC2_CBC,9, + &(lvalues[987]),0}, +{"PBE-MD5-RC2-64","pbeWithMD5AndRC2-CBC",NID_pbeWithMD5AndRC2_CBC,9, + &(lvalues[996]),0}, +{"PBE-SHA1-DES","pbeWithSHA1AndDES-CBC",NID_pbeWithSHA1AndDES_CBC,9, + &(lvalues[1005]),0}, +{"msExtReq","Microsoft Extension Request",NID_ms_ext_req,10, + &(lvalues[1014]),0}, +{"extReq","Extension Request",NID_ext_req,9,&(lvalues[1024]),0}, +{"name","name",NID_name,3,&(lvalues[1033]),0}, +{"dnQualifier","dnQualifier",NID_dnQualifier,3,&(lvalues[1036]),0}, +{"id-pe","id-pe",NID_id_pe,7,&(lvalues[1039]),0}, +{"id-ad","id-ad",NID_id_ad,7,&(lvalues[1046]),0}, +{"authorityInfoAccess","Authority Information Access",NID_info_access, + 8,&(lvalues[1053]),0}, +{"OCSP","OCSP",NID_ad_OCSP,8,&(lvalues[1061]),0}, +{"caIssuers","CA Issuers",NID_ad_ca_issuers,8,&(lvalues[1069]),0}, +{"OCSPSigning","OCSP Signing",NID_OCSP_sign,8,&(lvalues[1077]),0}, +{"ISO","iso",NID_iso,0,NULL,0}, +{"member-body","ISO Member Body",NID_member_body,1,&(lvalues[1085]),0}, +{"ISO-US","ISO US Member Body",NID_ISO_US,3,&(lvalues[1086]),0}, +{"X9-57","X9.57",NID_X9_57,5,&(lvalues[1089]),0}, +{"X9cm","X9.57 CM ?",NID_X9cm,6,&(lvalues[1094]),0}, +{"pkcs1","pkcs1",NID_pkcs1,8,&(lvalues[1100]),0}, +{"pkcs5","pkcs5",NID_pkcs5,8,&(lvalues[1108]),0}, +{"SMIME","S/MIME",NID_SMIME,9,&(lvalues[1116]),0}, +{"id-smime-mod","id-smime-mod",NID_id_smime_mod,10,&(lvalues[1125]),0}, +{"id-smime-ct","id-smime-ct",NID_id_smime_ct,10,&(lvalues[1135]),0}, +{"id-smime-aa","id-smime-aa",NID_id_smime_aa,10,&(lvalues[1145]),0}, +{"id-smime-alg","id-smime-alg",NID_id_smime_alg,10,&(lvalues[1155]),0}, +{"id-smime-cd","id-smime-cd",NID_id_smime_cd,10,&(lvalues[1165]),0}, +{"id-smime-spq","id-smime-spq",NID_id_smime_spq,10,&(lvalues[1175]),0}, +{"id-smime-cti","id-smime-cti",NID_id_smime_cti,10,&(lvalues[1185]),0}, +{"id-smime-mod-cms","id-smime-mod-cms",NID_id_smime_mod_cms,11, + &(lvalues[1195]),0}, +{"id-smime-mod-ess","id-smime-mod-ess",NID_id_smime_mod_ess,11, + &(lvalues[1206]),0}, +{"id-smime-mod-oid","id-smime-mod-oid",NID_id_smime_mod_oid,11, + &(lvalues[1217]),0}, +{"id-smime-mod-msg-v3","id-smime-mod-msg-v3",NID_id_smime_mod_msg_v3, + 11,&(lvalues[1228]),0}, +{"id-smime-mod-ets-eSignature-88","id-smime-mod-ets-eSignature-88", + NID_id_smime_mod_ets_eSignature_88,11,&(lvalues[1239]),0}, +{"id-smime-mod-ets-eSignature-97","id-smime-mod-ets-eSignature-97", + NID_id_smime_mod_ets_eSignature_97,11,&(lvalues[1250]),0}, +{"id-smime-mod-ets-eSigPolicy-88","id-smime-mod-ets-eSigPolicy-88", + NID_id_smime_mod_ets_eSigPolicy_88,11,&(lvalues[1261]),0}, +{"id-smime-mod-ets-eSigPolicy-97","id-smime-mod-ets-eSigPolicy-97", + NID_id_smime_mod_ets_eSigPolicy_97,11,&(lvalues[1272]),0}, +{"id-smime-ct-receipt","id-smime-ct-receipt",NID_id_smime_ct_receipt, + 11,&(lvalues[1283]),0}, +{"id-smime-ct-authData","id-smime-ct-authData", + NID_id_smime_ct_authData,11,&(lvalues[1294]),0}, +{"id-smime-ct-publishCert","id-smime-ct-publishCert", + NID_id_smime_ct_publishCert,11,&(lvalues[1305]),0}, +{"id-smime-ct-TSTInfo","id-smime-ct-TSTInfo",NID_id_smime_ct_TSTInfo, + 11,&(lvalues[1316]),0}, +{"id-smime-ct-TDTInfo","id-smime-ct-TDTInfo",NID_id_smime_ct_TDTInfo, + 11,&(lvalues[1327]),0}, +{"id-smime-ct-contentInfo","id-smime-ct-contentInfo", + NID_id_smime_ct_contentInfo,11,&(lvalues[1338]),0}, +{"id-smime-ct-DVCSRequestData","id-smime-ct-DVCSRequestData", + NID_id_smime_ct_DVCSRequestData,11,&(lvalues[1349]),0}, +{"id-smime-ct-DVCSResponseData","id-smime-ct-DVCSResponseData", + NID_id_smime_ct_DVCSResponseData,11,&(lvalues[1360]),0}, +{"id-smime-aa-receiptRequest","id-smime-aa-receiptRequest", + NID_id_smime_aa_receiptRequest,11,&(lvalues[1371]),0}, +{"id-smime-aa-securityLabel","id-smime-aa-securityLabel", + NID_id_smime_aa_securityLabel,11,&(lvalues[1382]),0}, +{"id-smime-aa-mlExpandHistory","id-smime-aa-mlExpandHistory", + NID_id_smime_aa_mlExpandHistory,11,&(lvalues[1393]),0}, +{"id-smime-aa-contentHint","id-smime-aa-contentHint", + NID_id_smime_aa_contentHint,11,&(lvalues[1404]),0}, +{"id-smime-aa-msgSigDigest","id-smime-aa-msgSigDigest", + NID_id_smime_aa_msgSigDigest,11,&(lvalues[1415]),0}, +{"id-smime-aa-encapContentType","id-smime-aa-encapContentType", + NID_id_smime_aa_encapContentType,11,&(lvalues[1426]),0}, +{"id-smime-aa-contentIdentifier","id-smime-aa-contentIdentifier", + NID_id_smime_aa_contentIdentifier,11,&(lvalues[1437]),0}, +{"id-smime-aa-macValue","id-smime-aa-macValue", + NID_id_smime_aa_macValue,11,&(lvalues[1448]),0}, +{"id-smime-aa-equivalentLabels","id-smime-aa-equivalentLabels", + NID_id_smime_aa_equivalentLabels,11,&(lvalues[1459]),0}, +{"id-smime-aa-contentReference","id-smime-aa-contentReference", + NID_id_smime_aa_contentReference,11,&(lvalues[1470]),0}, +{"id-smime-aa-encrypKeyPref","id-smime-aa-encrypKeyPref", + NID_id_smime_aa_encrypKeyPref,11,&(lvalues[1481]),0}, +{"id-smime-aa-signingCertificate","id-smime-aa-signingCertificate", + NID_id_smime_aa_signingCertificate,11,&(lvalues[1492]),0}, +{"id-smime-aa-smimeEncryptCerts","id-smime-aa-smimeEncryptCerts", + NID_id_smime_aa_smimeEncryptCerts,11,&(lvalues[1503]),0}, +{"id-smime-aa-timeStampToken","id-smime-aa-timeStampToken", + NID_id_smime_aa_timeStampToken,11,&(lvalues[1514]),0}, +{"id-smime-aa-ets-sigPolicyId","id-smime-aa-ets-sigPolicyId", + NID_id_smime_aa_ets_sigPolicyId,11,&(lvalues[1525]),0}, +{"id-smime-aa-ets-commitmentType","id-smime-aa-ets-commitmentType", + NID_id_smime_aa_ets_commitmentType,11,&(lvalues[1536]),0}, +{"id-smime-aa-ets-signerLocation","id-smime-aa-ets-signerLocation", + NID_id_smime_aa_ets_signerLocation,11,&(lvalues[1547]),0}, +{"id-smime-aa-ets-signerAttr","id-smime-aa-ets-signerAttr", + NID_id_smime_aa_ets_signerAttr,11,&(lvalues[1558]),0}, +{"id-smime-aa-ets-otherSigCert","id-smime-aa-ets-otherSigCert", + NID_id_smime_aa_ets_otherSigCert,11,&(lvalues[1569]),0}, +{"id-smime-aa-ets-contentTimestamp", + "id-smime-aa-ets-contentTimestamp", + NID_id_smime_aa_ets_contentTimestamp,11,&(lvalues[1580]),0}, +{"id-smime-aa-ets-CertificateRefs","id-smime-aa-ets-CertificateRefs", + NID_id_smime_aa_ets_CertificateRefs,11,&(lvalues[1591]),0}, +{"id-smime-aa-ets-RevocationRefs","id-smime-aa-ets-RevocationRefs", + NID_id_smime_aa_ets_RevocationRefs,11,&(lvalues[1602]),0}, +{"id-smime-aa-ets-certValues","id-smime-aa-ets-certValues", + NID_id_smime_aa_ets_certValues,11,&(lvalues[1613]),0}, +{"id-smime-aa-ets-revocationValues", + "id-smime-aa-ets-revocationValues", + NID_id_smime_aa_ets_revocationValues,11,&(lvalues[1624]),0}, +{"id-smime-aa-ets-escTimeStamp","id-smime-aa-ets-escTimeStamp", + NID_id_smime_aa_ets_escTimeStamp,11,&(lvalues[1635]),0}, +{"id-smime-aa-ets-certCRLTimestamp", + "id-smime-aa-ets-certCRLTimestamp", + NID_id_smime_aa_ets_certCRLTimestamp,11,&(lvalues[1646]),0}, +{"id-smime-aa-ets-archiveTimeStamp", + "id-smime-aa-ets-archiveTimeStamp", + NID_id_smime_aa_ets_archiveTimeStamp,11,&(lvalues[1657]),0}, +{"id-smime-aa-signatureType","id-smime-aa-signatureType", + NID_id_smime_aa_signatureType,11,&(lvalues[1668]),0}, +{"id-smime-aa-dvcs-dvc","id-smime-aa-dvcs-dvc", + NID_id_smime_aa_dvcs_dvc,11,&(lvalues[1679]),0}, +{"id-smime-alg-ESDHwith3DES","id-smime-alg-ESDHwith3DES", + NID_id_smime_alg_ESDHwith3DES,11,&(lvalues[1690]),0}, +{"id-smime-alg-ESDHwithRC2","id-smime-alg-ESDHwithRC2", + NID_id_smime_alg_ESDHwithRC2,11,&(lvalues[1701]),0}, +{"id-smime-alg-3DESwrap","id-smime-alg-3DESwrap", + NID_id_smime_alg_3DESwrap,11,&(lvalues[1712]),0}, +{"id-smime-alg-RC2wrap","id-smime-alg-RC2wrap", + NID_id_smime_alg_RC2wrap,11,&(lvalues[1723]),0}, +{"id-smime-alg-ESDH","id-smime-alg-ESDH",NID_id_smime_alg_ESDH,11, + &(lvalues[1734]),0}, +{"id-smime-alg-CMS3DESwrap","id-smime-alg-CMS3DESwrap", + NID_id_smime_alg_CMS3DESwrap,11,&(lvalues[1745]),0}, +{"id-smime-alg-CMSRC2wrap","id-smime-alg-CMSRC2wrap", + NID_id_smime_alg_CMSRC2wrap,11,&(lvalues[1756]),0}, +{"id-smime-cd-ldap","id-smime-cd-ldap",NID_id_smime_cd_ldap,11, + &(lvalues[1767]),0}, +{"id-smime-spq-ets-sqt-uri","id-smime-spq-ets-sqt-uri", + NID_id_smime_spq_ets_sqt_uri,11,&(lvalues[1778]),0}, +{"id-smime-spq-ets-sqt-unotice","id-smime-spq-ets-sqt-unotice", + NID_id_smime_spq_ets_sqt_unotice,11,&(lvalues[1789]),0}, +{"id-smime-cti-ets-proofOfOrigin","id-smime-cti-ets-proofOfOrigin", + NID_id_smime_cti_ets_proofOfOrigin,11,&(lvalues[1800]),0}, +{"id-smime-cti-ets-proofOfReceipt","id-smime-cti-ets-proofOfReceipt", + NID_id_smime_cti_ets_proofOfReceipt,11,&(lvalues[1811]),0}, +{"id-smime-cti-ets-proofOfDelivery", + "id-smime-cti-ets-proofOfDelivery", + NID_id_smime_cti_ets_proofOfDelivery,11,&(lvalues[1822]),0}, +{"id-smime-cti-ets-proofOfSender","id-smime-cti-ets-proofOfSender", + NID_id_smime_cti_ets_proofOfSender,11,&(lvalues[1833]),0}, +{"id-smime-cti-ets-proofOfApproval", + "id-smime-cti-ets-proofOfApproval", + NID_id_smime_cti_ets_proofOfApproval,11,&(lvalues[1844]),0}, +{"id-smime-cti-ets-proofOfCreation", + "id-smime-cti-ets-proofOfCreation", + NID_id_smime_cti_ets_proofOfCreation,11,&(lvalues[1855]),0}, +{"MD4","md4",NID_md4,8,&(lvalues[1866]),0}, +{"id-pkix-mod","id-pkix-mod",NID_id_pkix_mod,7,&(lvalues[1874]),0}, +{"id-qt","id-qt",NID_id_qt,7,&(lvalues[1881]),0}, +{"id-it","id-it",NID_id_it,7,&(lvalues[1888]),0}, +{"id-pkip","id-pkip",NID_id_pkip,7,&(lvalues[1895]),0}, +{"id-alg","id-alg",NID_id_alg,7,&(lvalues[1902]),0}, +{"id-cmc","id-cmc",NID_id_cmc,7,&(lvalues[1909]),0}, +{"id-on","id-on",NID_id_on,7,&(lvalues[1916]),0}, +{"id-pda","id-pda",NID_id_pda,7,&(lvalues[1923]),0}, +{"id-aca","id-aca",NID_id_aca,7,&(lvalues[1930]),0}, +{"id-qcs","id-qcs",NID_id_qcs,7,&(lvalues[1937]),0}, +{"id-cct","id-cct",NID_id_cct,7,&(lvalues[1944]),0}, +{"id-pkix1-explicit-88","id-pkix1-explicit-88", + NID_id_pkix1_explicit_88,8,&(lvalues[1951]),0}, +{"id-pkix1-implicit-88","id-pkix1-implicit-88", + NID_id_pkix1_implicit_88,8,&(lvalues[1959]),0}, +{"id-pkix1-explicit-93","id-pkix1-explicit-93", + NID_id_pkix1_explicit_93,8,&(lvalues[1967]),0}, +{"id-pkix1-implicit-93","id-pkix1-implicit-93", + NID_id_pkix1_implicit_93,8,&(lvalues[1975]),0}, +{"id-mod-crmf","id-mod-crmf",NID_id_mod_crmf,8,&(lvalues[1983]),0}, +{"id-mod-cmc","id-mod-cmc",NID_id_mod_cmc,8,&(lvalues[1991]),0}, +{"id-mod-kea-profile-88","id-mod-kea-profile-88", + NID_id_mod_kea_profile_88,8,&(lvalues[1999]),0}, +{"id-mod-kea-profile-93","id-mod-kea-profile-93", + NID_id_mod_kea_profile_93,8,&(lvalues[2007]),0}, +{"id-mod-cmp","id-mod-cmp",NID_id_mod_cmp,8,&(lvalues[2015]),0}, +{"id-mod-qualified-cert-88","id-mod-qualified-cert-88", + NID_id_mod_qualified_cert_88,8,&(lvalues[2023]),0}, +{"id-mod-qualified-cert-93","id-mod-qualified-cert-93", + NID_id_mod_qualified_cert_93,8,&(lvalues[2031]),0}, +{"id-mod-attribute-cert","id-mod-attribute-cert", + NID_id_mod_attribute_cert,8,&(lvalues[2039]),0}, +{"id-mod-timestamp-protocol","id-mod-timestamp-protocol", + NID_id_mod_timestamp_protocol,8,&(lvalues[2047]),0}, +{"id-mod-ocsp","id-mod-ocsp",NID_id_mod_ocsp,8,&(lvalues[2055]),0}, +{"id-mod-dvcs","id-mod-dvcs",NID_id_mod_dvcs,8,&(lvalues[2063]),0}, +{"id-mod-cmp2000","id-mod-cmp2000",NID_id_mod_cmp2000,8, + &(lvalues[2071]),0}, +{"biometricInfo","Biometric Info",NID_biometricInfo,8,&(lvalues[2079]),0}, +{"qcStatements","qcStatements",NID_qcStatements,8,&(lvalues[2087]),0}, +{"ac-auditEntity","ac-auditEntity",NID_ac_auditEntity,8, + &(lvalues[2095]),0}, +{"ac-targeting","ac-targeting",NID_ac_targeting,8,&(lvalues[2103]),0}, +{"aaControls","aaControls",NID_aaControls,8,&(lvalues[2111]),0}, +{"sbgp-ipAddrBlock","sbgp-ipAddrBlock",NID_sbgp_ipAddrBlock,8, + &(lvalues[2119]),0}, +{"sbgp-autonomousSysNum","sbgp-autonomousSysNum", + NID_sbgp_autonomousSysNum,8,&(lvalues[2127]),0}, +{"sbgp-routerIdentifier","sbgp-routerIdentifier", + NID_sbgp_routerIdentifier,8,&(lvalues[2135]),0}, +{"textNotice","textNotice",NID_textNotice,8,&(lvalues[2143]),0}, +{"ipsecEndSystem","IPSec End System",NID_ipsecEndSystem,8, + &(lvalues[2151]),0}, +{"ipsecTunnel","IPSec Tunnel",NID_ipsecTunnel,8,&(lvalues[2159]),0}, +{"ipsecUser","IPSec User",NID_ipsecUser,8,&(lvalues[2167]),0}, +{"DVCS","dvcs",NID_dvcs,8,&(lvalues[2175]),0}, +{"id-it-caProtEncCert","id-it-caProtEncCert",NID_id_it_caProtEncCert, + 8,&(lvalues[2183]),0}, +{"id-it-signKeyPairTypes","id-it-signKeyPairTypes", + NID_id_it_signKeyPairTypes,8,&(lvalues[2191]),0}, +{"id-it-encKeyPairTypes","id-it-encKeyPairTypes", + NID_id_it_encKeyPairTypes,8,&(lvalues[2199]),0}, +{"id-it-preferredSymmAlg","id-it-preferredSymmAlg", + NID_id_it_preferredSymmAlg,8,&(lvalues[2207]),0}, +{"id-it-caKeyUpdateInfo","id-it-caKeyUpdateInfo", + NID_id_it_caKeyUpdateInfo,8,&(lvalues[2215]),0}, +{"id-it-currentCRL","id-it-currentCRL",NID_id_it_currentCRL,8, + &(lvalues[2223]),0}, +{"id-it-unsupportedOIDs","id-it-unsupportedOIDs", + NID_id_it_unsupportedOIDs,8,&(lvalues[2231]),0}, +{"id-it-subscriptionRequest","id-it-subscriptionRequest", + NID_id_it_subscriptionRequest,8,&(lvalues[2239]),0}, +{"id-it-subscriptionResponse","id-it-subscriptionResponse", + NID_id_it_subscriptionResponse,8,&(lvalues[2247]),0}, +{"id-it-keyPairParamReq","id-it-keyPairParamReq", + NID_id_it_keyPairParamReq,8,&(lvalues[2255]),0}, +{"id-it-keyPairParamRep","id-it-keyPairParamRep", + NID_id_it_keyPairParamRep,8,&(lvalues[2263]),0}, +{"id-it-revPassphrase","id-it-revPassphrase",NID_id_it_revPassphrase, + 8,&(lvalues[2271]),0}, +{"id-it-implicitConfirm","id-it-implicitConfirm", + NID_id_it_implicitConfirm,8,&(lvalues[2279]),0}, +{"id-it-confirmWaitTime","id-it-confirmWaitTime", + NID_id_it_confirmWaitTime,8,&(lvalues[2287]),0}, +{"id-it-origPKIMessage","id-it-origPKIMessage", + NID_id_it_origPKIMessage,8,&(lvalues[2295]),0}, +{"id-regCtrl","id-regCtrl",NID_id_regCtrl,8,&(lvalues[2303]),0}, +{"id-regInfo","id-regInfo",NID_id_regInfo,8,&(lvalues[2311]),0}, +{"id-regCtrl-regToken","id-regCtrl-regToken",NID_id_regCtrl_regToken, + 9,&(lvalues[2319]),0}, +{"id-regCtrl-authenticator","id-regCtrl-authenticator", + NID_id_regCtrl_authenticator,9,&(lvalues[2328]),0}, +{"id-regCtrl-pkiPublicationInfo","id-regCtrl-pkiPublicationInfo", + NID_id_regCtrl_pkiPublicationInfo,9,&(lvalues[2337]),0}, +{"id-regCtrl-pkiArchiveOptions","id-regCtrl-pkiArchiveOptions", + NID_id_regCtrl_pkiArchiveOptions,9,&(lvalues[2346]),0}, +{"id-regCtrl-oldCertID","id-regCtrl-oldCertID", + NID_id_regCtrl_oldCertID,9,&(lvalues[2355]),0}, +{"id-regCtrl-protocolEncrKey","id-regCtrl-protocolEncrKey", + NID_id_regCtrl_protocolEncrKey,9,&(lvalues[2364]),0}, +{"id-regInfo-utf8Pairs","id-regInfo-utf8Pairs", + NID_id_regInfo_utf8Pairs,9,&(lvalues[2373]),0}, +{"id-regInfo-certReq","id-regInfo-certReq",NID_id_regInfo_certReq,9, + &(lvalues[2382]),0}, +{"id-alg-des40","id-alg-des40",NID_id_alg_des40,8,&(lvalues[2391]),0}, +{"id-alg-noSignature","id-alg-noSignature",NID_id_alg_noSignature,8, + &(lvalues[2399]),0}, +{"id-alg-dh-sig-hmac-sha1","id-alg-dh-sig-hmac-sha1", + NID_id_alg_dh_sig_hmac_sha1,8,&(lvalues[2407]),0}, +{"id-alg-dh-pop","id-alg-dh-pop",NID_id_alg_dh_pop,8,&(lvalues[2415]),0}, +{"id-cmc-statusInfo","id-cmc-statusInfo",NID_id_cmc_statusInfo,8, + &(lvalues[2423]),0}, +{"id-cmc-identification","id-cmc-identification", + NID_id_cmc_identification,8,&(lvalues[2431]),0}, +{"id-cmc-identityProof","id-cmc-identityProof", + NID_id_cmc_identityProof,8,&(lvalues[2439]),0}, +{"id-cmc-dataReturn","id-cmc-dataReturn",NID_id_cmc_dataReturn,8, + &(lvalues[2447]),0}, +{"id-cmc-transactionId","id-cmc-transactionId", + NID_id_cmc_transactionId,8,&(lvalues[2455]),0}, +{"id-cmc-senderNonce","id-cmc-senderNonce",NID_id_cmc_senderNonce,8, + &(lvalues[2463]),0}, +{"id-cmc-recipientNonce","id-cmc-recipientNonce", + NID_id_cmc_recipientNonce,8,&(lvalues[2471]),0}, +{"id-cmc-addExtensions","id-cmc-addExtensions", + NID_id_cmc_addExtensions,8,&(lvalues[2479]),0}, +{"id-cmc-encryptedPOP","id-cmc-encryptedPOP",NID_id_cmc_encryptedPOP, + 8,&(lvalues[2487]),0}, +{"id-cmc-decryptedPOP","id-cmc-decryptedPOP",NID_id_cmc_decryptedPOP, + 8,&(lvalues[2495]),0}, +{"id-cmc-lraPOPWitness","id-cmc-lraPOPWitness", + NID_id_cmc_lraPOPWitness,8,&(lvalues[2503]),0}, +{"id-cmc-getCert","id-cmc-getCert",NID_id_cmc_getCert,8, + &(lvalues[2511]),0}, +{"id-cmc-getCRL","id-cmc-getCRL",NID_id_cmc_getCRL,8,&(lvalues[2519]),0}, +{"id-cmc-revokeRequest","id-cmc-revokeRequest", + NID_id_cmc_revokeRequest,8,&(lvalues[2527]),0}, +{"id-cmc-regInfo","id-cmc-regInfo",NID_id_cmc_regInfo,8, + &(lvalues[2535]),0}, +{"id-cmc-responseInfo","id-cmc-responseInfo",NID_id_cmc_responseInfo, + 8,&(lvalues[2543]),0}, +{"id-cmc-queryPending","id-cmc-queryPending",NID_id_cmc_queryPending, + 8,&(lvalues[2551]),0}, +{"id-cmc-popLinkRandom","id-cmc-popLinkRandom", + NID_id_cmc_popLinkRandom,8,&(lvalues[2559]),0}, +{"id-cmc-popLinkWitness","id-cmc-popLinkWitness", + NID_id_cmc_popLinkWitness,8,&(lvalues[2567]),0}, +{"id-cmc-confirmCertAcceptance","id-cmc-confirmCertAcceptance", + NID_id_cmc_confirmCertAcceptance,8,&(lvalues[2575]),0}, +{"id-on-personalData","id-on-personalData",NID_id_on_personalData,8, + &(lvalues[2583]),0}, +{"id-pda-dateOfBirth","id-pda-dateOfBirth",NID_id_pda_dateOfBirth,8, + &(lvalues[2591]),0}, +{"id-pda-placeOfBirth","id-pda-placeOfBirth",NID_id_pda_placeOfBirth, + 8,&(lvalues[2599]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"id-pda-gender","id-pda-gender",NID_id_pda_gender,8,&(lvalues[2607]),0}, +{"id-pda-countryOfCitizenship","id-pda-countryOfCitizenship", + NID_id_pda_countryOfCitizenship,8,&(lvalues[2615]),0}, +{"id-pda-countryOfResidence","id-pda-countryOfResidence", + NID_id_pda_countryOfResidence,8,&(lvalues[2623]),0}, +{"id-aca-authenticationInfo","id-aca-authenticationInfo", + NID_id_aca_authenticationInfo,8,&(lvalues[2631]),0}, +{"id-aca-accessIdentity","id-aca-accessIdentity", + NID_id_aca_accessIdentity,8,&(lvalues[2639]),0}, +{"id-aca-chargingIdentity","id-aca-chargingIdentity", + NID_id_aca_chargingIdentity,8,&(lvalues[2647]),0}, +{"id-aca-group","id-aca-group",NID_id_aca_group,8,&(lvalues[2655]),0}, +{"id-aca-role","id-aca-role",NID_id_aca_role,8,&(lvalues[2663]),0}, +{"id-qcs-pkixQCSyntax-v1","id-qcs-pkixQCSyntax-v1", + NID_id_qcs_pkixQCSyntax_v1,8,&(lvalues[2671]),0}, +{"id-cct-crs","id-cct-crs",NID_id_cct_crs,8,&(lvalues[2679]),0}, +{"id-cct-PKIData","id-cct-PKIData",NID_id_cct_PKIData,8, + &(lvalues[2687]),0}, +{"id-cct-PKIResponse","id-cct-PKIResponse",NID_id_cct_PKIResponse,8, + &(lvalues[2695]),0}, +{"ad_timestamping","AD Time Stamping",NID_ad_timeStamping,8, + &(lvalues[2703]),0}, +{"AD_DVCS","ad dvcs",NID_ad_dvcs,8,&(lvalues[2711]),0}, +{"basicOCSPResponse","Basic OCSP Response",NID_id_pkix_OCSP_basic,9, + &(lvalues[2719]),0}, +{"Nonce","OCSP Nonce",NID_id_pkix_OCSP_Nonce,9,&(lvalues[2728]),0}, +{"CrlID","OCSP CRL ID",NID_id_pkix_OCSP_CrlID,9,&(lvalues[2737]),0}, +{"acceptableResponses","Acceptable OCSP Responses", + NID_id_pkix_OCSP_acceptableResponses,9,&(lvalues[2746]),0}, +{"noCheck","OCSP No Check",NID_id_pkix_OCSP_noCheck,9,&(lvalues[2755]),0}, +{"archiveCutoff","OCSP Archive Cutoff",NID_id_pkix_OCSP_archiveCutoff, + 9,&(lvalues[2764]),0}, +{"serviceLocator","OCSP Service Locator", + NID_id_pkix_OCSP_serviceLocator,9,&(lvalues[2773]),0}, +{"extendedStatus","Extended OCSP Status", + NID_id_pkix_OCSP_extendedStatus,9,&(lvalues[2782]),0}, +{"valid","valid",NID_id_pkix_OCSP_valid,9,&(lvalues[2791]),0}, +{"path","path",NID_id_pkix_OCSP_path,9,&(lvalues[2800]),0}, +{"trustRoot","Trust Root",NID_id_pkix_OCSP_trustRoot,9, + &(lvalues[2809]),0}, +{"algorithm","algorithm",NID_algorithm,4,&(lvalues[2818]),0}, +{"rsaSignature","rsaSignature",NID_rsaSignature,5,&(lvalues[2822]),0}, +{"X500algorithms","directory services - algorithms", + NID_X500algorithms,2,&(lvalues[2827]),0}, +{"ORG","org",NID_org,1,&(lvalues[2829]),0}, +{"DOD","dod",NID_dod,2,&(lvalues[2830]),0}, +{"IANA","iana",NID_iana,3,&(lvalues[2832]),0}, +{"directory","Directory",NID_Directory,4,&(lvalues[2835]),0}, +{"mgmt","Management",NID_Management,4,&(lvalues[2839]),0}, +{"experimental","Experimental",NID_Experimental,4,&(lvalues[2843]),0}, +{"private","Private",NID_Private,4,&(lvalues[2847]),0}, +{"security","Security",NID_Security,4,&(lvalues[2851]),0}, +{"snmpv2","SNMPv2",NID_SNMPv2,4,&(lvalues[2855]),0}, +{"Mail","Mail",NID_Mail,4,&(lvalues[2859]),0}, +{"enterprises","Enterprises",NID_Enterprises,5,&(lvalues[2863]),0}, +{"dcobject","dcObject",NID_dcObject,9,&(lvalues[2868]),0}, +{"DC","domainComponent",NID_domainComponent,10,&(lvalues[2877]),0}, +{"domain","Domain",NID_Domain,10,&(lvalues[2887]),0}, +{"NULL","NULL",NID_joint_iso_ccitt,0,NULL,0}, +{"selected-attribute-types","Selected Attribute Types", + NID_selected_attribute_types,3,&(lvalues[2897]),0}, +{"clearance","clearance",NID_clearance,4,&(lvalues[2900]),0}, +{"RSA-MD4","md4WithRSAEncryption",NID_md4WithRSAEncryption,9, + &(lvalues[2904]),0}, +{"ac-proxying","ac-proxying",NID_ac_proxying,8,&(lvalues[2913]),0}, +{"subjectInfoAccess","Subject Information Access",NID_sinfo_access,8, + &(lvalues[2921]),0}, +{"id-aca-encAttrs","id-aca-encAttrs",NID_id_aca_encAttrs,8, + &(lvalues[2929]),0}, +{"role","role",NID_role,3,&(lvalues[2937]),0}, +{"policyConstraints","X509v3 Policy Constraints", + NID_policy_constraints,3,&(lvalues[2940]),0}, +{"targetInformation","X509v3 AC Targeting",NID_target_information,3, + &(lvalues[2943]),0}, +{"noRevAvail","X509v3 No Revocation Available",NID_no_rev_avail,3, + &(lvalues[2946]),0}, +{"NULL","NULL",NID_ccitt,0,NULL,0}, +{"ansi-X9-62","ANSI X9.62",NID_ansi_X9_62,5,&(lvalues[2949]),0}, +{"prime-field","prime-field",NID_X9_62_prime_field,7,&(lvalues[2954]),0}, +{"characteristic-two-field","characteristic-two-field", + NID_X9_62_characteristic_two_field,7,&(lvalues[2961]),0}, +{"id-ecPublicKey","id-ecPublicKey",NID_X9_62_id_ecPublicKey,7, + &(lvalues[2968]),0}, +{"prime192v1","prime192v1",NID_X9_62_prime192v1,8,&(lvalues[2975]),0}, +{"prime192v2","prime192v2",NID_X9_62_prime192v2,8,&(lvalues[2983]),0}, +{"prime192v3","prime192v3",NID_X9_62_prime192v3,8,&(lvalues[2991]),0}, +{"prime239v1","prime239v1",NID_X9_62_prime239v1,8,&(lvalues[2999]),0}, +{"prime239v2","prime239v2",NID_X9_62_prime239v2,8,&(lvalues[3007]),0}, +{"prime239v3","prime239v3",NID_X9_62_prime239v3,8,&(lvalues[3015]),0}, +{"prime256v1","prime256v1",NID_X9_62_prime256v1,8,&(lvalues[3023]),0}, +{"ecdsa-with-SHA1","ecdsa-with-SHA1",NID_ecdsa_with_SHA1,7, + &(lvalues[3031]),0}, +{"CSPName","Microsoft CSP Name",NID_ms_csp_name,9,&(lvalues[3038]),0}, +{"AES-128-ECB","aes-128-ecb",NID_aes_128_ecb,9,&(lvalues[3047]),0}, +{"AES-128-CBC","aes-128-cbc",NID_aes_128_cbc,9,&(lvalues[3056]),0}, +{"AES-128-OFB","aes-128-ofb",NID_aes_128_ofb128,9,&(lvalues[3065]),0}, +{"AES-128-CFB","aes-128-cfb",NID_aes_128_cfb128,9,&(lvalues[3074]),0}, +{"AES-192-ECB","aes-192-ecb",NID_aes_192_ecb,9,&(lvalues[3083]),0}, +{"AES-192-CBC","aes-192-cbc",NID_aes_192_cbc,9,&(lvalues[3092]),0}, +{"AES-192-OFB","aes-192-ofb",NID_aes_192_ofb128,9,&(lvalues[3101]),0}, +{"AES-192-CFB","aes-192-cfb",NID_aes_192_cfb128,9,&(lvalues[3110]),0}, +{"AES-256-ECB","aes-256-ecb",NID_aes_256_ecb,9,&(lvalues[3119]),0}, +{"AES-256-CBC","aes-256-cbc",NID_aes_256_cbc,9,&(lvalues[3128]),0}, +{"AES-256-OFB","aes-256-ofb",NID_aes_256_ofb128,9,&(lvalues[3137]),0}, +{"AES-256-CFB","aes-256-cfb",NID_aes_256_cfb128,9,&(lvalues[3146]),0}, +{"holdInstructionCode","Hold Instruction Code", + NID_hold_instruction_code,3,&(lvalues[3155]),0}, +{"holdInstructionNone","Hold Instruction None", + NID_hold_instruction_none,7,&(lvalues[3158]),0}, +{"holdInstructionCallIssuer","Hold Instruction Call Issuer", + NID_hold_instruction_call_issuer,7,&(lvalues[3165]),0}, +{"holdInstructionReject","Hold Instruction Reject", + NID_hold_instruction_reject,7,&(lvalues[3172]),0}, +{"data","data",NID_data,1,&(lvalues[3179]),0}, +{"pss","pss",NID_pss,3,&(lvalues[3180]),0}, +{"ucl","ucl",NID_ucl,7,&(lvalues[3183]),0}, +{"pilot","pilot",NID_pilot,8,&(lvalues[3190]),0}, +{"pilotAttributeType","pilotAttributeType",NID_pilotAttributeType,9, + &(lvalues[3198]),0}, +{"pilotAttributeSyntax","pilotAttributeSyntax", + NID_pilotAttributeSyntax,9,&(lvalues[3207]),0}, +{"pilotObjectClass","pilotObjectClass",NID_pilotObjectClass,9, + &(lvalues[3216]),0}, +{"pilotGroups","pilotGroups",NID_pilotGroups,9,&(lvalues[3225]),0}, +{"iA5StringSyntax","iA5StringSyntax",NID_iA5StringSyntax,10, + &(lvalues[3234]),0}, +{"caseIgnoreIA5StringSyntax","caseIgnoreIA5StringSyntax", + NID_caseIgnoreIA5StringSyntax,10,&(lvalues[3244]),0}, +{"pilotObject","pilotObject",NID_pilotObject,10,&(lvalues[3254]),0}, +{"pilotPerson","pilotPerson",NID_pilotPerson,10,&(lvalues[3264]),0}, +{"account","account",NID_account,10,&(lvalues[3274]),0}, +{"document","document",NID_document,10,&(lvalues[3284]),0}, +{"room","room",NID_room,10,&(lvalues[3294]),0}, +{"documentSeries","documentSeries",NID_documentSeries,10, + &(lvalues[3304]),0}, +{"rFC822localPart","rFC822localPart",NID_rFC822localPart,10, + &(lvalues[3314]),0}, +{"dNSDomain","dNSDomain",NID_dNSDomain,10,&(lvalues[3324]),0}, +{"domainRelatedObject","domainRelatedObject",NID_domainRelatedObject, + 10,&(lvalues[3334]),0}, +{"friendlyCountry","friendlyCountry",NID_friendlyCountry,10, + &(lvalues[3344]),0}, +{"simpleSecurityObject","simpleSecurityObject", + NID_simpleSecurityObject,10,&(lvalues[3354]),0}, +{"pilotOrganization","pilotOrganization",NID_pilotOrganization,10, + &(lvalues[3364]),0}, +{"pilotDSA","pilotDSA",NID_pilotDSA,10,&(lvalues[3374]),0}, +{"qualityLabelledData","qualityLabelledData",NID_qualityLabelledData, + 10,&(lvalues[3384]),0}, +{"UID","userId",NID_userId,10,&(lvalues[3394]),0}, +{"textEncodedORAddress","textEncodedORAddress", + NID_textEncodedORAddress,10,&(lvalues[3404]),0}, +{"mail","rfc822Mailbox",NID_rfc822Mailbox,10,&(lvalues[3414]),0}, +{"info","info",NID_info,10,&(lvalues[3424]),0}, +{"favouriteDrink","favouriteDrink",NID_favouriteDrink,10, + &(lvalues[3434]),0}, +{"roomNumber","roomNumber",NID_roomNumber,10,&(lvalues[3444]),0}, +{"photo","photo",NID_photo,10,&(lvalues[3454]),0}, +{"userClass","userClass",NID_userClass,10,&(lvalues[3464]),0}, +{"host","host",NID_host,10,&(lvalues[3474]),0}, +{"manager","manager",NID_manager,10,&(lvalues[3484]),0}, +{"documentIdentifier","documentIdentifier",NID_documentIdentifier,10, + &(lvalues[3494]),0}, +{"documentTitle","documentTitle",NID_documentTitle,10,&(lvalues[3504]),0}, +{"documentVersion","documentVersion",NID_documentVersion,10, + &(lvalues[3514]),0}, +{"documentAuthor","documentAuthor",NID_documentAuthor,10, + &(lvalues[3524]),0}, +{"documentLocation","documentLocation",NID_documentLocation,10, + &(lvalues[3534]),0}, +{"homeTelephoneNumber","homeTelephoneNumber",NID_homeTelephoneNumber, + 10,&(lvalues[3544]),0}, +{"secretary","secretary",NID_secretary,10,&(lvalues[3554]),0}, +{"otherMailbox","otherMailbox",NID_otherMailbox,10,&(lvalues[3564]),0}, +{"lastModifiedTime","lastModifiedTime",NID_lastModifiedTime,10, + &(lvalues[3574]),0}, +{"lastModifiedBy","lastModifiedBy",NID_lastModifiedBy,10, + &(lvalues[3584]),0}, +{"aRecord","aRecord",NID_aRecord,10,&(lvalues[3594]),0}, +{"pilotAttributeType27","pilotAttributeType27", + NID_pilotAttributeType27,10,&(lvalues[3604]),0}, +{"mXRecord","mXRecord",NID_mXRecord,10,&(lvalues[3614]),0}, +{"nSRecord","nSRecord",NID_nSRecord,10,&(lvalues[3624]),0}, +{"sOARecord","sOARecord",NID_sOARecord,10,&(lvalues[3634]),0}, +{"cNAMERecord","cNAMERecord",NID_cNAMERecord,10,&(lvalues[3644]),0}, +{"associatedDomain","associatedDomain",NID_associatedDomain,10, + &(lvalues[3654]),0}, +{"associatedName","associatedName",NID_associatedName,10, + &(lvalues[3664]),0}, +{"homePostalAddress","homePostalAddress",NID_homePostalAddress,10, + &(lvalues[3674]),0}, +{"personalTitle","personalTitle",NID_personalTitle,10,&(lvalues[3684]),0}, +{"mobileTelephoneNumber","mobileTelephoneNumber", + NID_mobileTelephoneNumber,10,&(lvalues[3694]),0}, +{"pagerTelephoneNumber","pagerTelephoneNumber", + NID_pagerTelephoneNumber,10,&(lvalues[3704]),0}, +{"friendlyCountryName","friendlyCountryName",NID_friendlyCountryName, + 10,&(lvalues[3714]),0}, +{"organizationalStatus","organizationalStatus", + NID_organizationalStatus,10,&(lvalues[3724]),0}, +{"janetMailbox","janetMailbox",NID_janetMailbox,10,&(lvalues[3734]),0}, +{"mailPreferenceOption","mailPreferenceOption", + NID_mailPreferenceOption,10,&(lvalues[3744]),0}, +{"buildingName","buildingName",NID_buildingName,10,&(lvalues[3754]),0}, +{"dSAQuality","dSAQuality",NID_dSAQuality,10,&(lvalues[3764]),0}, +{"singleLevelQuality","singleLevelQuality",NID_singleLevelQuality,10, + &(lvalues[3774]),0}, +{"subtreeMinimumQuality","subtreeMinimumQuality", + NID_subtreeMinimumQuality,10,&(lvalues[3784]),0}, +{"subtreeMaximumQuality","subtreeMaximumQuality", + NID_subtreeMaximumQuality,10,&(lvalues[3794]),0}, +{"personalSignature","personalSignature",NID_personalSignature,10, + &(lvalues[3804]),0}, +{"dITRedirect","dITRedirect",NID_dITRedirect,10,&(lvalues[3814]),0}, +{"audio","audio",NID_audio,10,&(lvalues[3824]),0}, +{"documentPublisher","documentPublisher",NID_documentPublisher,10, + &(lvalues[3834]),0}, +{"x500UniqueIdentifier","x500UniqueIdentifier", + NID_x500UniqueIdentifier,3,&(lvalues[3844]),0}, +{"mime-mhs","MIME MHS",NID_mime_mhs,5,&(lvalues[3847]),0}, +{"mime-mhs-headings","mime-mhs-headings",NID_mime_mhs_headings,6, + &(lvalues[3852]),0}, +{"mime-mhs-bodies","mime-mhs-bodies",NID_mime_mhs_bodies,6, + &(lvalues[3858]),0}, +{"id-hex-partial-message","id-hex-partial-message", + NID_id_hex_partial_message,7,&(lvalues[3864]),0}, +{"id-hex-multipart-message","id-hex-multipart-message", + NID_id_hex_multipart_message,7,&(lvalues[3871]),0}, +{"generationQualifier","generationQualifier",NID_generationQualifier, + 3,&(lvalues[3878]),0}, +{"pseudonym","pseudonym",NID_pseudonym,3,&(lvalues[3881]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"id-set","Secure Electronic Transactions",NID_id_set,2, + &(lvalues[3884]),0}, +{"set-ctype","content types",NID_set_ctype,3,&(lvalues[3886]),0}, +{"set-msgExt","message extensions",NID_set_msgExt,3,&(lvalues[3889]),0}, +{"set-attr","set-attr",NID_set_attr,3,&(lvalues[3892]),0}, +{"set-policy","set-policy",NID_set_policy,3,&(lvalues[3895]),0}, +{"set-certExt","certificate extensions",NID_set_certExt,3, + &(lvalues[3898]),0}, +{"set-brand","set-brand",NID_set_brand,3,&(lvalues[3901]),0}, +{"setct-PANData","setct-PANData",NID_setct_PANData,4,&(lvalues[3904]),0}, +{"setct-PANToken","setct-PANToken",NID_setct_PANToken,4, + &(lvalues[3908]),0}, +{"setct-PANOnly","setct-PANOnly",NID_setct_PANOnly,4,&(lvalues[3912]),0}, +{"setct-OIData","setct-OIData",NID_setct_OIData,4,&(lvalues[3916]),0}, +{"setct-PI","setct-PI",NID_setct_PI,4,&(lvalues[3920]),0}, +{"setct-PIData","setct-PIData",NID_setct_PIData,4,&(lvalues[3924]),0}, +{"setct-PIDataUnsigned","setct-PIDataUnsigned", + NID_setct_PIDataUnsigned,4,&(lvalues[3928]),0}, +{"setct-HODInput","setct-HODInput",NID_setct_HODInput,4, + &(lvalues[3932]),0}, +{"setct-AuthResBaggage","setct-AuthResBaggage", + NID_setct_AuthResBaggage,4,&(lvalues[3936]),0}, +{"setct-AuthRevReqBaggage","setct-AuthRevReqBaggage", + NID_setct_AuthRevReqBaggage,4,&(lvalues[3940]),0}, +{"setct-AuthRevResBaggage","setct-AuthRevResBaggage", + NID_setct_AuthRevResBaggage,4,&(lvalues[3944]),0}, +{"setct-CapTokenSeq","setct-CapTokenSeq",NID_setct_CapTokenSeq,4, + &(lvalues[3948]),0}, +{"setct-PInitResData","setct-PInitResData",NID_setct_PInitResData,4, + &(lvalues[3952]),0}, +{"setct-PI-TBS","setct-PI-TBS",NID_setct_PI_TBS,4,&(lvalues[3956]),0}, +{"setct-PResData","setct-PResData",NID_setct_PResData,4, + &(lvalues[3960]),0}, +{"setct-AuthReqTBS","setct-AuthReqTBS",NID_setct_AuthReqTBS,4, + &(lvalues[3964]),0}, +{"setct-AuthResTBS","setct-AuthResTBS",NID_setct_AuthResTBS,4, + &(lvalues[3968]),0}, +{"setct-AuthResTBSX","setct-AuthResTBSX",NID_setct_AuthResTBSX,4, + &(lvalues[3972]),0}, +{"setct-AuthTokenTBS","setct-AuthTokenTBS",NID_setct_AuthTokenTBS,4, + &(lvalues[3976]),0}, +{"setct-CapTokenData","setct-CapTokenData",NID_setct_CapTokenData,4, + &(lvalues[3980]),0}, +{"setct-CapTokenTBS","setct-CapTokenTBS",NID_setct_CapTokenTBS,4, + &(lvalues[3984]),0}, +{"setct-AcqCardCodeMsg","setct-AcqCardCodeMsg", + NID_setct_AcqCardCodeMsg,4,&(lvalues[3988]),0}, +{"setct-AuthRevReqTBS","setct-AuthRevReqTBS",NID_setct_AuthRevReqTBS, + 4,&(lvalues[3992]),0}, +{"setct-AuthRevResData","setct-AuthRevResData", + NID_setct_AuthRevResData,4,&(lvalues[3996]),0}, +{"setct-AuthRevResTBS","setct-AuthRevResTBS",NID_setct_AuthRevResTBS, + 4,&(lvalues[4000]),0}, +{"setct-CapReqTBS","setct-CapReqTBS",NID_setct_CapReqTBS,4, + &(lvalues[4004]),0}, +{"setct-CapReqTBSX","setct-CapReqTBSX",NID_setct_CapReqTBSX,4, + &(lvalues[4008]),0}, +{"setct-CapResData","setct-CapResData",NID_setct_CapResData,4, + &(lvalues[4012]),0}, +{"setct-CapRevReqTBS","setct-CapRevReqTBS",NID_setct_CapRevReqTBS,4, + &(lvalues[4016]),0}, +{"setct-CapRevReqTBSX","setct-CapRevReqTBSX",NID_setct_CapRevReqTBSX, + 4,&(lvalues[4020]),0}, +{"setct-CapRevResData","setct-CapRevResData",NID_setct_CapRevResData, + 4,&(lvalues[4024]),0}, +{"setct-CredReqTBS","setct-CredReqTBS",NID_setct_CredReqTBS,4, + &(lvalues[4028]),0}, +{"setct-CredReqTBSX","setct-CredReqTBSX",NID_setct_CredReqTBSX,4, + &(lvalues[4032]),0}, +{"setct-CredResData","setct-CredResData",NID_setct_CredResData,4, + &(lvalues[4036]),0}, +{"setct-CredRevReqTBS","setct-CredRevReqTBS",NID_setct_CredRevReqTBS, + 4,&(lvalues[4040]),0}, +{"setct-CredRevReqTBSX","setct-CredRevReqTBSX", + NID_setct_CredRevReqTBSX,4,&(lvalues[4044]),0}, +{"setct-CredRevResData","setct-CredRevResData", + NID_setct_CredRevResData,4,&(lvalues[4048]),0}, +{"setct-PCertReqData","setct-PCertReqData",NID_setct_PCertReqData,4, + &(lvalues[4052]),0}, +{"setct-PCertResTBS","setct-PCertResTBS",NID_setct_PCertResTBS,4, + &(lvalues[4056]),0}, +{"setct-BatchAdminReqData","setct-BatchAdminReqData", + NID_setct_BatchAdminReqData,4,&(lvalues[4060]),0}, +{"setct-BatchAdminResData","setct-BatchAdminResData", + NID_setct_BatchAdminResData,4,&(lvalues[4064]),0}, +{"setct-CardCInitResTBS","setct-CardCInitResTBS", + NID_setct_CardCInitResTBS,4,&(lvalues[4068]),0}, +{"setct-MeAqCInitResTBS","setct-MeAqCInitResTBS", + NID_setct_MeAqCInitResTBS,4,&(lvalues[4072]),0}, +{"setct-RegFormResTBS","setct-RegFormResTBS",NID_setct_RegFormResTBS, + 4,&(lvalues[4076]),0}, +{"setct-CertReqData","setct-CertReqData",NID_setct_CertReqData,4, + &(lvalues[4080]),0}, +{"setct-CertReqTBS","setct-CertReqTBS",NID_setct_CertReqTBS,4, + &(lvalues[4084]),0}, +{"setct-CertResData","setct-CertResData",NID_setct_CertResData,4, + &(lvalues[4088]),0}, +{"setct-CertInqReqTBS","setct-CertInqReqTBS",NID_setct_CertInqReqTBS, + 4,&(lvalues[4092]),0}, +{"setct-ErrorTBS","setct-ErrorTBS",NID_setct_ErrorTBS,4, + &(lvalues[4096]),0}, +{"setct-PIDualSignedTBE","setct-PIDualSignedTBE", + NID_setct_PIDualSignedTBE,4,&(lvalues[4100]),0}, +{"setct-PIUnsignedTBE","setct-PIUnsignedTBE",NID_setct_PIUnsignedTBE, + 4,&(lvalues[4104]),0}, +{"setct-AuthReqTBE","setct-AuthReqTBE",NID_setct_AuthReqTBE,4, + &(lvalues[4108]),0}, +{"setct-AuthResTBE","setct-AuthResTBE",NID_setct_AuthResTBE,4, + &(lvalues[4112]),0}, +{"setct-AuthResTBEX","setct-AuthResTBEX",NID_setct_AuthResTBEX,4, + &(lvalues[4116]),0}, +{"setct-AuthTokenTBE","setct-AuthTokenTBE",NID_setct_AuthTokenTBE,4, + &(lvalues[4120]),0}, +{"setct-CapTokenTBE","setct-CapTokenTBE",NID_setct_CapTokenTBE,4, + &(lvalues[4124]),0}, +{"setct-CapTokenTBEX","setct-CapTokenTBEX",NID_setct_CapTokenTBEX,4, + &(lvalues[4128]),0}, +{"setct-AcqCardCodeMsgTBE","setct-AcqCardCodeMsgTBE", + NID_setct_AcqCardCodeMsgTBE,4,&(lvalues[4132]),0}, +{"setct-AuthRevReqTBE","setct-AuthRevReqTBE",NID_setct_AuthRevReqTBE, + 4,&(lvalues[4136]),0}, +{"setct-AuthRevResTBE","setct-AuthRevResTBE",NID_setct_AuthRevResTBE, + 4,&(lvalues[4140]),0}, +{"setct-AuthRevResTBEB","setct-AuthRevResTBEB", + NID_setct_AuthRevResTBEB,4,&(lvalues[4144]),0}, +{"setct-CapReqTBE","setct-CapReqTBE",NID_setct_CapReqTBE,4, + &(lvalues[4148]),0}, +{"setct-CapReqTBEX","setct-CapReqTBEX",NID_setct_CapReqTBEX,4, + &(lvalues[4152]),0}, +{"setct-CapResTBE","setct-CapResTBE",NID_setct_CapResTBE,4, + &(lvalues[4156]),0}, +{"setct-CapRevReqTBE","setct-CapRevReqTBE",NID_setct_CapRevReqTBE,4, + &(lvalues[4160]),0}, +{"setct-CapRevReqTBEX","setct-CapRevReqTBEX",NID_setct_CapRevReqTBEX, + 4,&(lvalues[4164]),0}, +{"setct-CapRevResTBE","setct-CapRevResTBE",NID_setct_CapRevResTBE,4, + &(lvalues[4168]),0}, +{"setct-CredReqTBE","setct-CredReqTBE",NID_setct_CredReqTBE,4, + &(lvalues[4172]),0}, +{"setct-CredReqTBEX","setct-CredReqTBEX",NID_setct_CredReqTBEX,4, + &(lvalues[4176]),0}, +{"setct-CredResTBE","setct-CredResTBE",NID_setct_CredResTBE,4, + &(lvalues[4180]),0}, +{"setct-CredRevReqTBE","setct-CredRevReqTBE",NID_setct_CredRevReqTBE, + 4,&(lvalues[4184]),0}, +{"setct-CredRevReqTBEX","setct-CredRevReqTBEX", + NID_setct_CredRevReqTBEX,4,&(lvalues[4188]),0}, +{"setct-CredRevResTBE","setct-CredRevResTBE",NID_setct_CredRevResTBE, + 4,&(lvalues[4192]),0}, +{"setct-BatchAdminReqTBE","setct-BatchAdminReqTBE", + NID_setct_BatchAdminReqTBE,4,&(lvalues[4196]),0}, +{"setct-BatchAdminResTBE","setct-BatchAdminResTBE", + NID_setct_BatchAdminResTBE,4,&(lvalues[4200]),0}, +{"setct-RegFormReqTBE","setct-RegFormReqTBE",NID_setct_RegFormReqTBE, + 4,&(lvalues[4204]),0}, +{"setct-CertReqTBE","setct-CertReqTBE",NID_setct_CertReqTBE,4, + &(lvalues[4208]),0}, +{"setct-CertReqTBEX","setct-CertReqTBEX",NID_setct_CertReqTBEX,4, + &(lvalues[4212]),0}, +{"setct-CertResTBE","setct-CertResTBE",NID_setct_CertResTBE,4, + &(lvalues[4216]),0}, +{"setct-CRLNotificationTBS","setct-CRLNotificationTBS", + NID_setct_CRLNotificationTBS,4,&(lvalues[4220]),0}, +{"setct-CRLNotificationResTBS","setct-CRLNotificationResTBS", + NID_setct_CRLNotificationResTBS,4,&(lvalues[4224]),0}, +{"setct-BCIDistributionTBS","setct-BCIDistributionTBS", + NID_setct_BCIDistributionTBS,4,&(lvalues[4228]),0}, +{"setext-genCrypt","generic cryptogram",NID_setext_genCrypt,4, + &(lvalues[4232]),0}, +{"setext-miAuth","merchant initiated auth",NID_setext_miAuth,4, + &(lvalues[4236]),0}, +{"setext-pinSecure","setext-pinSecure",NID_setext_pinSecure,4, + &(lvalues[4240]),0}, +{"setext-pinAny","setext-pinAny",NID_setext_pinAny,4,&(lvalues[4244]),0}, +{"setext-track2","setext-track2",NID_setext_track2,4,&(lvalues[4248]),0}, +{"setext-cv","additional verification",NID_setext_cv,4, + &(lvalues[4252]),0}, +{"set-policy-root","set-policy-root",NID_set_policy_root,4, + &(lvalues[4256]),0}, +{"setCext-hashedRoot","setCext-hashedRoot",NID_setCext_hashedRoot,4, + &(lvalues[4260]),0}, +{"setCext-certType","setCext-certType",NID_setCext_certType,4, + &(lvalues[4264]),0}, +{"setCext-merchData","setCext-merchData",NID_setCext_merchData,4, + &(lvalues[4268]),0}, +{"setCext-cCertRequired","setCext-cCertRequired", + NID_setCext_cCertRequired,4,&(lvalues[4272]),0}, +{"setCext-tunneling","setCext-tunneling",NID_setCext_tunneling,4, + &(lvalues[4276]),0}, +{"setCext-setExt","setCext-setExt",NID_setCext_setExt,4, + &(lvalues[4280]),0}, +{"setCext-setQualf","setCext-setQualf",NID_setCext_setQualf,4, + &(lvalues[4284]),0}, +{"setCext-PGWYcapabilities","setCext-PGWYcapabilities", + NID_setCext_PGWYcapabilities,4,&(lvalues[4288]),0}, +{"setCext-TokenIdentifier","setCext-TokenIdentifier", + NID_setCext_TokenIdentifier,4,&(lvalues[4292]),0}, +{"setCext-Track2Data","setCext-Track2Data",NID_setCext_Track2Data,4, + &(lvalues[4296]),0}, +{"setCext-TokenType","setCext-TokenType",NID_setCext_TokenType,4, + &(lvalues[4300]),0}, +{"setCext-IssuerCapabilities","setCext-IssuerCapabilities", + NID_setCext_IssuerCapabilities,4,&(lvalues[4304]),0}, +{"setAttr-Cert","setAttr-Cert",NID_setAttr_Cert,4,&(lvalues[4308]),0}, +{"setAttr-PGWYcap","payment gateway capabilities",NID_setAttr_PGWYcap, + 4,&(lvalues[4312]),0}, +{"setAttr-TokenType","setAttr-TokenType",NID_setAttr_TokenType,4, + &(lvalues[4316]),0}, +{"setAttr-IssCap","issuer capabilities",NID_setAttr_IssCap,4, + &(lvalues[4320]),0}, +{"set-rootKeyThumb","set-rootKeyThumb",NID_set_rootKeyThumb,5, + &(lvalues[4324]),0}, +{"set-addPolicy","set-addPolicy",NID_set_addPolicy,5,&(lvalues[4329]),0}, +{"setAttr-Token-EMV","setAttr-Token-EMV",NID_setAttr_Token_EMV,5, + &(lvalues[4334]),0}, +{"setAttr-Token-B0Prime","setAttr-Token-B0Prime", + NID_setAttr_Token_B0Prime,5,&(lvalues[4339]),0}, +{"setAttr-IssCap-CVM","setAttr-IssCap-CVM",NID_setAttr_IssCap_CVM,5, + &(lvalues[4344]),0}, +{"setAttr-IssCap-T2","setAttr-IssCap-T2",NID_setAttr_IssCap_T2,5, + &(lvalues[4349]),0}, +{"setAttr-IssCap-Sig","setAttr-IssCap-Sig",NID_setAttr_IssCap_Sig,5, + &(lvalues[4354]),0}, +{"setAttr-GenCryptgrm","generate cryptogram",NID_setAttr_GenCryptgrm, + 6,&(lvalues[4359]),0}, +{"setAttr-T2Enc","encrypted track 2",NID_setAttr_T2Enc,6, + &(lvalues[4365]),0}, +{"setAttr-T2cleartxt","cleartext track 2",NID_setAttr_T2cleartxt,6, + &(lvalues[4371]),0}, +{"setAttr-TokICCsig","ICC or token signature",NID_setAttr_TokICCsig,6, + &(lvalues[4377]),0}, +{"setAttr-SecDevSig","secure device signature",NID_setAttr_SecDevSig, + 6,&(lvalues[4383]),0}, +{"set-brand-IATA-ATA","set-brand-IATA-ATA",NID_set_brand_IATA_ATA,4, + &(lvalues[4389]),0}, +{"set-brand-Diners","set-brand-Diners",NID_set_brand_Diners,4, + &(lvalues[4393]),0}, +{"set-brand-AmericanExpress","set-brand-AmericanExpress", + NID_set_brand_AmericanExpress,4,&(lvalues[4397]),0}, +{"set-brand-JCB","set-brand-JCB",NID_set_brand_JCB,4,&(lvalues[4401]),0}, +{"set-brand-Visa","set-brand-Visa",NID_set_brand_Visa,4, + &(lvalues[4405]),0}, +{"set-brand-MasterCard","set-brand-MasterCard", + NID_set_brand_MasterCard,4,&(lvalues[4409]),0}, +{"set-brand-Novus","set-brand-Novus",NID_set_brand_Novus,5, + &(lvalues[4413]),0}, +{"DES-CDMF","des-cdmf",NID_des_cdmf,8,&(lvalues[4418]),0}, +{"rsaOAEPEncryptionSET","rsaOAEPEncryptionSET", + NID_rsaOAEPEncryptionSET,9,&(lvalues[4426]),0}, +{"ITU-T","itu-t",NID_itu_t,0,NULL,0}, +{"JOINT-ISO-ITU-T","joint-iso-itu-t",NID_joint_iso_itu_t,0,NULL,0}, +{"international-organizations","International Organizations", + NID_international_organizations,1,&(lvalues[4435]),0}, +{"msSmartcardLogin","Microsoft Smartcardlogin",NID_ms_smartcard_login, + 10,&(lvalues[4436]),0}, +{"msUPN","Microsoft Universal Principal Name",NID_ms_upn,10, + &(lvalues[4446]),0}, +{"AES-128-CFB1","aes-128-cfb1",NID_aes_128_cfb1,0,NULL,0}, +{"AES-192-CFB1","aes-192-cfb1",NID_aes_192_cfb1,0,NULL,0}, +{"AES-256-CFB1","aes-256-cfb1",NID_aes_256_cfb1,0,NULL,0}, +{"AES-128-CFB8","aes-128-cfb8",NID_aes_128_cfb8,0,NULL,0}, +{"AES-192-CFB8","aes-192-cfb8",NID_aes_192_cfb8,0,NULL,0}, +{"AES-256-CFB8","aes-256-cfb8",NID_aes_256_cfb8,0,NULL,0}, +{"DES-CFB1","des-cfb1",NID_des_cfb1,0,NULL,0}, +{"DES-CFB8","des-cfb8",NID_des_cfb8,0,NULL,0}, +{"DES-EDE3-CFB1","des-ede3-cfb1",NID_des_ede3_cfb1,0,NULL,0}, +{"DES-EDE3-CFB8","des-ede3-cfb8",NID_des_ede3_cfb8,0,NULL,0}, +{"street","streetAddress",NID_streetAddress,3,&(lvalues[4456]),0}, +{"postalCode","postalCode",NID_postalCode,3,&(lvalues[4459]),0}, +{"id-ppl","id-ppl",NID_id_ppl,7,&(lvalues[4462]),0}, +{"proxyCertInfo","Proxy Certificate Information",NID_proxyCertInfo,8, + &(lvalues[4469]),0}, +{"id-ppl-anyLanguage","Any language",NID_id_ppl_anyLanguage,8, + &(lvalues[4477]),0}, +{"id-ppl-inheritAll","Inherit all",NID_id_ppl_inheritAll,8, + &(lvalues[4485]),0}, +{"nameConstraints","X509v3 Name Constraints",NID_name_constraints,3, + &(lvalues[4493]),0}, +{"id-ppl-independent","Independent",NID_Independent,8,&(lvalues[4496]),0}, +{"RSA-SHA256","sha256WithRSAEncryption",NID_sha256WithRSAEncryption,9, + &(lvalues[4504]),0}, +{"RSA-SHA384","sha384WithRSAEncryption",NID_sha384WithRSAEncryption,9, + &(lvalues[4513]),0}, +{"RSA-SHA512","sha512WithRSAEncryption",NID_sha512WithRSAEncryption,9, + &(lvalues[4522]),0}, +{"RSA-SHA224","sha224WithRSAEncryption",NID_sha224WithRSAEncryption,9, + &(lvalues[4531]),0}, +{"SHA256","sha256",NID_sha256,9,&(lvalues[4540]),0}, +{"SHA384","sha384",NID_sha384,9,&(lvalues[4549]),0}, +{"SHA512","sha512",NID_sha512,9,&(lvalues[4558]),0}, +{"SHA224","sha224",NID_sha224,9,&(lvalues[4567]),0}, +{"identified-organization","identified-organization", + NID_identified_organization,1,&(lvalues[4576]),0}, +{"certicom-arc","certicom-arc",NID_certicom_arc,3,&(lvalues[4577]),0}, +{"wap","wap",NID_wap,2,&(lvalues[4580]),0}, +{"wap-wsg","wap-wsg",NID_wap_wsg,3,&(lvalues[4582]),0}, +{"id-characteristic-two-basis","id-characteristic-two-basis", + NID_X9_62_id_characteristic_two_basis,8,&(lvalues[4585]),0}, +{"onBasis","onBasis",NID_X9_62_onBasis,9,&(lvalues[4593]),0}, +{"tpBasis","tpBasis",NID_X9_62_tpBasis,9,&(lvalues[4602]),0}, +{"ppBasis","ppBasis",NID_X9_62_ppBasis,9,&(lvalues[4611]),0}, +{"c2pnb163v1","c2pnb163v1",NID_X9_62_c2pnb163v1,8,&(lvalues[4620]),0}, +{"c2pnb163v2","c2pnb163v2",NID_X9_62_c2pnb163v2,8,&(lvalues[4628]),0}, +{"c2pnb163v3","c2pnb163v3",NID_X9_62_c2pnb163v3,8,&(lvalues[4636]),0}, +{"c2pnb176v1","c2pnb176v1",NID_X9_62_c2pnb176v1,8,&(lvalues[4644]),0}, +{"c2tnb191v1","c2tnb191v1",NID_X9_62_c2tnb191v1,8,&(lvalues[4652]),0}, +{"c2tnb191v2","c2tnb191v2",NID_X9_62_c2tnb191v2,8,&(lvalues[4660]),0}, +{"c2tnb191v3","c2tnb191v3",NID_X9_62_c2tnb191v3,8,&(lvalues[4668]),0}, +{"c2onb191v4","c2onb191v4",NID_X9_62_c2onb191v4,8,&(lvalues[4676]),0}, +{"c2onb191v5","c2onb191v5",NID_X9_62_c2onb191v5,8,&(lvalues[4684]),0}, +{"c2pnb208w1","c2pnb208w1",NID_X9_62_c2pnb208w1,8,&(lvalues[4692]),0}, +{"c2tnb239v1","c2tnb239v1",NID_X9_62_c2tnb239v1,8,&(lvalues[4700]),0}, +{"c2tnb239v2","c2tnb239v2",NID_X9_62_c2tnb239v2,8,&(lvalues[4708]),0}, +{"c2tnb239v3","c2tnb239v3",NID_X9_62_c2tnb239v3,8,&(lvalues[4716]),0}, +{"c2onb239v4","c2onb239v4",NID_X9_62_c2onb239v4,8,&(lvalues[4724]),0}, +{"c2onb239v5","c2onb239v5",NID_X9_62_c2onb239v5,8,&(lvalues[4732]),0}, +{"c2pnb272w1","c2pnb272w1",NID_X9_62_c2pnb272w1,8,&(lvalues[4740]),0}, +{"c2pnb304w1","c2pnb304w1",NID_X9_62_c2pnb304w1,8,&(lvalues[4748]),0}, +{"c2tnb359v1","c2tnb359v1",NID_X9_62_c2tnb359v1,8,&(lvalues[4756]),0}, +{"c2pnb368w1","c2pnb368w1",NID_X9_62_c2pnb368w1,8,&(lvalues[4764]),0}, +{"c2tnb431r1","c2tnb431r1",NID_X9_62_c2tnb431r1,8,&(lvalues[4772]),0}, +{"secp112r1","secp112r1",NID_secp112r1,5,&(lvalues[4780]),0}, +{"secp112r2","secp112r2",NID_secp112r2,5,&(lvalues[4785]),0}, +{"secp128r1","secp128r1",NID_secp128r1,5,&(lvalues[4790]),0}, +{"secp128r2","secp128r2",NID_secp128r2,5,&(lvalues[4795]),0}, +{"secp160k1","secp160k1",NID_secp160k1,5,&(lvalues[4800]),0}, +{"secp160r1","secp160r1",NID_secp160r1,5,&(lvalues[4805]),0}, +{"secp160r2","secp160r2",NID_secp160r2,5,&(lvalues[4810]),0}, +{"secp192k1","secp192k1",NID_secp192k1,5,&(lvalues[4815]),0}, +{"secp224k1","secp224k1",NID_secp224k1,5,&(lvalues[4820]),0}, +{"secp224r1","secp224r1",NID_secp224r1,5,&(lvalues[4825]),0}, +{"secp256k1","secp256k1",NID_secp256k1,5,&(lvalues[4830]),0}, +{"secp384r1","secp384r1",NID_secp384r1,5,&(lvalues[4835]),0}, +{"secp521r1","secp521r1",NID_secp521r1,5,&(lvalues[4840]),0}, +{"sect113r1","sect113r1",NID_sect113r1,5,&(lvalues[4845]),0}, +{"sect113r2","sect113r2",NID_sect113r2,5,&(lvalues[4850]),0}, +{"sect131r1","sect131r1",NID_sect131r1,5,&(lvalues[4855]),0}, +{"sect131r2","sect131r2",NID_sect131r2,5,&(lvalues[4860]),0}, +{"sect163k1","sect163k1",NID_sect163k1,5,&(lvalues[4865]),0}, +{"sect163r1","sect163r1",NID_sect163r1,5,&(lvalues[4870]),0}, +{"sect163r2","sect163r2",NID_sect163r2,5,&(lvalues[4875]),0}, +{"sect193r1","sect193r1",NID_sect193r1,5,&(lvalues[4880]),0}, +{"sect193r2","sect193r2",NID_sect193r2,5,&(lvalues[4885]),0}, +{"sect233k1","sect233k1",NID_sect233k1,5,&(lvalues[4890]),0}, +{"sect233r1","sect233r1",NID_sect233r1,5,&(lvalues[4895]),0}, +{"sect239k1","sect239k1",NID_sect239k1,5,&(lvalues[4900]),0}, +{"sect283k1","sect283k1",NID_sect283k1,5,&(lvalues[4905]),0}, +{"sect283r1","sect283r1",NID_sect283r1,5,&(lvalues[4910]),0}, +{"sect409k1","sect409k1",NID_sect409k1,5,&(lvalues[4915]),0}, +{"sect409r1","sect409r1",NID_sect409r1,5,&(lvalues[4920]),0}, +{"sect571k1","sect571k1",NID_sect571k1,5,&(lvalues[4925]),0}, +{"sect571r1","sect571r1",NID_sect571r1,5,&(lvalues[4930]),0}, +{"wap-wsg-idm-ecid-wtls1","wap-wsg-idm-ecid-wtls1", + NID_wap_wsg_idm_ecid_wtls1,5,&(lvalues[4935]),0}, +{"wap-wsg-idm-ecid-wtls3","wap-wsg-idm-ecid-wtls3", + NID_wap_wsg_idm_ecid_wtls3,5,&(lvalues[4940]),0}, +{"wap-wsg-idm-ecid-wtls4","wap-wsg-idm-ecid-wtls4", + NID_wap_wsg_idm_ecid_wtls4,5,&(lvalues[4945]),0}, +{"wap-wsg-idm-ecid-wtls5","wap-wsg-idm-ecid-wtls5", + NID_wap_wsg_idm_ecid_wtls5,5,&(lvalues[4950]),0}, +{"wap-wsg-idm-ecid-wtls6","wap-wsg-idm-ecid-wtls6", + NID_wap_wsg_idm_ecid_wtls6,5,&(lvalues[4955]),0}, +{"wap-wsg-idm-ecid-wtls7","wap-wsg-idm-ecid-wtls7", + NID_wap_wsg_idm_ecid_wtls7,5,&(lvalues[4960]),0}, +{"wap-wsg-idm-ecid-wtls8","wap-wsg-idm-ecid-wtls8", + NID_wap_wsg_idm_ecid_wtls8,5,&(lvalues[4965]),0}, +{"wap-wsg-idm-ecid-wtls9","wap-wsg-idm-ecid-wtls9", + NID_wap_wsg_idm_ecid_wtls9,5,&(lvalues[4970]),0}, +{"wap-wsg-idm-ecid-wtls10","wap-wsg-idm-ecid-wtls10", + NID_wap_wsg_idm_ecid_wtls10,5,&(lvalues[4975]),0}, +{"wap-wsg-idm-ecid-wtls11","wap-wsg-idm-ecid-wtls11", + NID_wap_wsg_idm_ecid_wtls11,5,&(lvalues[4980]),0}, +{"wap-wsg-idm-ecid-wtls12","wap-wsg-idm-ecid-wtls12", + NID_wap_wsg_idm_ecid_wtls12,5,&(lvalues[4985]),0}, +{"anyPolicy","X509v3 Any Policy",NID_any_policy,4,&(lvalues[4990]),0}, +{"policyMappings","X509v3 Policy Mappings",NID_policy_mappings,3, + &(lvalues[4994]),0}, +{"inhibitAnyPolicy","X509v3 Inhibit Any Policy", + NID_inhibit_any_policy,3,&(lvalues[4997]),0}, +{"Oakley-EC2N-3","ipsec3",NID_ipsec3,0,NULL,0}, +{"Oakley-EC2N-4","ipsec4",NID_ipsec4,0,NULL,0}, +{"CAMELLIA-128-CBC","camellia-128-cbc",NID_camellia_128_cbc,11, + &(lvalues[5000]),0}, +{"CAMELLIA-192-CBC","camellia-192-cbc",NID_camellia_192_cbc,11, + &(lvalues[5011]),0}, +{"CAMELLIA-256-CBC","camellia-256-cbc",NID_camellia_256_cbc,11, + &(lvalues[5022]),0}, +{"CAMELLIA-128-ECB","camellia-128-ecb",NID_camellia_128_ecb,8, + &(lvalues[5033]),0}, +{"CAMELLIA-192-ECB","camellia-192-ecb",NID_camellia_192_ecb,8, + &(lvalues[5041]),0}, +{"CAMELLIA-256-ECB","camellia-256-ecb",NID_camellia_256_ecb,8, + &(lvalues[5049]),0}, +{"CAMELLIA-128-CFB","camellia-128-cfb",NID_camellia_128_cfb128,8, + &(lvalues[5057]),0}, +{"CAMELLIA-192-CFB","camellia-192-cfb",NID_camellia_192_cfb128,8, + &(lvalues[5065]),0}, +{"CAMELLIA-256-CFB","camellia-256-cfb",NID_camellia_256_cfb128,8, + &(lvalues[5073]),0}, +{"CAMELLIA-128-CFB1","camellia-128-cfb1",NID_camellia_128_cfb1,0,NULL,0}, +{"CAMELLIA-192-CFB1","camellia-192-cfb1",NID_camellia_192_cfb1,0,NULL,0}, +{"CAMELLIA-256-CFB1","camellia-256-cfb1",NID_camellia_256_cfb1,0,NULL,0}, +{"CAMELLIA-128-CFB8","camellia-128-cfb8",NID_camellia_128_cfb8,0,NULL,0}, +{"CAMELLIA-192-CFB8","camellia-192-cfb8",NID_camellia_192_cfb8,0,NULL,0}, +{"CAMELLIA-256-CFB8","camellia-256-cfb8",NID_camellia_256_cfb8,0,NULL,0}, +{"CAMELLIA-128-OFB","camellia-128-ofb",NID_camellia_128_ofb128,8, + &(lvalues[5081]),0}, +{"CAMELLIA-192-OFB","camellia-192-ofb",NID_camellia_192_ofb128,8, + &(lvalues[5089]),0}, +{"CAMELLIA-256-OFB","camellia-256-ofb",NID_camellia_256_ofb128,8, + &(lvalues[5097]),0}, +{"subjectDirectoryAttributes","X509v3 Subject Directory Attributes", + NID_subject_directory_attributes,3,&(lvalues[5105]),0}, +{"issuingDistributionPoint","X509v3 Issuing Distrubution Point", + NID_issuing_distribution_point,3,&(lvalues[5108]),0}, +{"certificateIssuer","X509v3 Certificate Issuer", + NID_certificate_issuer,3,&(lvalues[5111]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"KISA","kisa",NID_kisa,6,&(lvalues[5114]),0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{NULL,NULL,NID_undef,0,NULL,0}, +{"SEED-ECB","seed-ecb",NID_seed_ecb,8,&(lvalues[5120]),0}, +{"SEED-CBC","seed-cbc",NID_seed_cbc,8,&(lvalues[5128]),0}, +{"SEED-OFB","seed-ofb",NID_seed_ofb128,8,&(lvalues[5136]),0}, +{"SEED-CFB","seed-cfb",NID_seed_cfb128,8,&(lvalues[5144]),0}, +{"HMAC-MD5","hmac-md5",NID_hmac_md5,8,&(lvalues[5152]),0}, +{"HMAC-SHA1","hmac-sha1",NID_hmac_sha1,8,&(lvalues[5160]),0}, +{"id-PasswordBasedMAC","password based MAC",NID_id_PasswordBasedMAC,9, + &(lvalues[5168]),0}, +{"id-DHBasedMac","Diffie-Hellman based MAC",NID_id_DHBasedMac,9, + &(lvalues[5177]),0}, +{"id-it-suppLangTags","id-it-suppLangTags",NID_id_it_suppLangTags,8, + &(lvalues[5186]),0}, +{"caRepository","CA Repository",NID_caRepository,8,&(lvalues[5194]),0}, +{"id-smime-ct-compressedData","id-smime-ct-compressedData", + NID_id_smime_ct_compressedData,11,&(lvalues[5202]),0}, +{"id-ct-asciiTextWithCRLF","id-ct-asciiTextWithCRLF", + NID_id_ct_asciiTextWithCRLF,11,&(lvalues[5213]),0}, +{"id-aes128-wrap","id-aes128-wrap",NID_id_aes128_wrap,9, + &(lvalues[5224]),0}, +{"id-aes192-wrap","id-aes192-wrap",NID_id_aes192_wrap,9, + &(lvalues[5233]),0}, +{"id-aes256-wrap","id-aes256-wrap",NID_id_aes256_wrap,9, + &(lvalues[5242]),0}, +{"ecdsa-with-Recommended","ecdsa-with-Recommended", + NID_ecdsa_with_Recommended,7,&(lvalues[5251]),0}, +{"ecdsa-with-Specified","ecdsa-with-Specified", + NID_ecdsa_with_Specified,7,&(lvalues[5258]),0}, +{"ecdsa-with-SHA224","ecdsa-with-SHA224",NID_ecdsa_with_SHA224,8, + &(lvalues[5265]),0}, +{"ecdsa-with-SHA256","ecdsa-with-SHA256",NID_ecdsa_with_SHA256,8, + &(lvalues[5273]),0}, +{"ecdsa-with-SHA384","ecdsa-with-SHA384",NID_ecdsa_with_SHA384,8, + &(lvalues[5281]),0}, +{"ecdsa-with-SHA512","ecdsa-with-SHA512",NID_ecdsa_with_SHA512,8, + &(lvalues[5289]),0}, +{"hmacWithMD5","hmacWithMD5",NID_hmacWithMD5,8,&(lvalues[5297]),0}, +{"hmacWithSHA224","hmacWithSHA224",NID_hmacWithSHA224,8, + &(lvalues[5305]),0}, +{"hmacWithSHA256","hmacWithSHA256",NID_hmacWithSHA256,8, + &(lvalues[5313]),0}, +{"hmacWithSHA384","hmacWithSHA384",NID_hmacWithSHA384,8, + &(lvalues[5321]),0}, +{"hmacWithSHA512","hmacWithSHA512",NID_hmacWithSHA512,8, + &(lvalues[5329]),0}, +{"dsa_with_SHA224","dsa_with_SHA224",NID_dsa_with_SHA224,9, + &(lvalues[5337]),0}, +{"dsa_with_SHA256","dsa_with_SHA256",NID_dsa_with_SHA256,9, + &(lvalues[5346]),0}, +{"whirlpool","whirlpool",NID_whirlpool,6,&(lvalues[5355]),0}, +{"cryptopro","cryptopro",NID_cryptopro,5,&(lvalues[5361]),0}, +{"cryptocom","cryptocom",NID_cryptocom,5,&(lvalues[5366]),0}, +{"id-GostR3411-94-with-GostR3410-2001", + "GOST R 34.11-94 with GOST R 34.10-2001", + NID_id_GostR3411_94_with_GostR3410_2001,6,&(lvalues[5371]),0}, +{"id-GostR3411-94-with-GostR3410-94", + "GOST R 34.11-94 with GOST R 34.10-94", + NID_id_GostR3411_94_with_GostR3410_94,6,&(lvalues[5377]),0}, +{"md_gost94","GOST R 34.11-94",NID_id_GostR3411_94,6,&(lvalues[5383]),0}, +{"id-HMACGostR3411-94","HMAC GOST 34.11-94",NID_id_HMACGostR3411_94,6, + &(lvalues[5389]),0}, +{"gost2001","GOST R 34.10-2001",NID_id_GostR3410_2001,6, + &(lvalues[5395]),0}, +{"gost94","GOST R 34.10-94",NID_id_GostR3410_94,6,&(lvalues[5401]),0}, +{"gost89","GOST 28147-89",NID_id_Gost28147_89,6,&(lvalues[5407]),0}, +{"gost89-cnt","gost89-cnt",NID_gost89_cnt,0,NULL,0}, +{"gost-mac","GOST 28147-89 MAC",NID_id_Gost28147_89_MAC,6, + &(lvalues[5413]),0}, +{"prf-gostr3411-94","GOST R 34.11-94 PRF",NID_id_GostR3411_94_prf,6, + &(lvalues[5419]),0}, +{"id-GostR3410-2001DH","GOST R 34.10-2001 DH",NID_id_GostR3410_2001DH, + 6,&(lvalues[5425]),0}, +{"id-GostR3410-94DH","GOST R 34.10-94 DH",NID_id_GostR3410_94DH,6, + &(lvalues[5431]),0}, +{"id-Gost28147-89-CryptoPro-KeyMeshing", + "id-Gost28147-89-CryptoPro-KeyMeshing", + NID_id_Gost28147_89_CryptoPro_KeyMeshing,7,&(lvalues[5437]),0}, +{"id-Gost28147-89-None-KeyMeshing","id-Gost28147-89-None-KeyMeshing", + NID_id_Gost28147_89_None_KeyMeshing,7,&(lvalues[5444]),0}, +{"id-GostR3411-94-TestParamSet","id-GostR3411-94-TestParamSet", + NID_id_GostR3411_94_TestParamSet,7,&(lvalues[5451]),0}, +{"id-GostR3411-94-CryptoProParamSet", + "id-GostR3411-94-CryptoProParamSet", + NID_id_GostR3411_94_CryptoProParamSet,7,&(lvalues[5458]),0}, +{"id-Gost28147-89-TestParamSet","id-Gost28147-89-TestParamSet", + NID_id_Gost28147_89_TestParamSet,7,&(lvalues[5465]),0}, +{"id-Gost28147-89-CryptoPro-A-ParamSet", + "id-Gost28147-89-CryptoPro-A-ParamSet", + NID_id_Gost28147_89_CryptoPro_A_ParamSet,7,&(lvalues[5472]),0}, +{"id-Gost28147-89-CryptoPro-B-ParamSet", + "id-Gost28147-89-CryptoPro-B-ParamSet", + NID_id_Gost28147_89_CryptoPro_B_ParamSet,7,&(lvalues[5479]),0}, +{"id-Gost28147-89-CryptoPro-C-ParamSet", + "id-Gost28147-89-CryptoPro-C-ParamSet", + NID_id_Gost28147_89_CryptoPro_C_ParamSet,7,&(lvalues[5486]),0}, +{"id-Gost28147-89-CryptoPro-D-ParamSet", + "id-Gost28147-89-CryptoPro-D-ParamSet", + NID_id_Gost28147_89_CryptoPro_D_ParamSet,7,&(lvalues[5493]),0}, +{"id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", + "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet", + NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet,7,&(lvalues[5500]), + 0}, +{"id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", + "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet", + NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet,7,&(lvalues[5507]), + 0}, +{"id-Gost28147-89-CryptoPro-RIC-1-ParamSet", + "id-Gost28147-89-CryptoPro-RIC-1-ParamSet", + NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet,7,&(lvalues[5514]),0}, +{"id-GostR3410-94-TestParamSet","id-GostR3410-94-TestParamSet", + NID_id_GostR3410_94_TestParamSet,7,&(lvalues[5521]),0}, +{"id-GostR3410-94-CryptoPro-A-ParamSet", + "id-GostR3410-94-CryptoPro-A-ParamSet", + NID_id_GostR3410_94_CryptoPro_A_ParamSet,7,&(lvalues[5528]),0}, +{"id-GostR3410-94-CryptoPro-B-ParamSet", + "id-GostR3410-94-CryptoPro-B-ParamSet", + NID_id_GostR3410_94_CryptoPro_B_ParamSet,7,&(lvalues[5535]),0}, +{"id-GostR3410-94-CryptoPro-C-ParamSet", + "id-GostR3410-94-CryptoPro-C-ParamSet", + NID_id_GostR3410_94_CryptoPro_C_ParamSet,7,&(lvalues[5542]),0}, +{"id-GostR3410-94-CryptoPro-D-ParamSet", + "id-GostR3410-94-CryptoPro-D-ParamSet", + NID_id_GostR3410_94_CryptoPro_D_ParamSet,7,&(lvalues[5549]),0}, +{"id-GostR3410-94-CryptoPro-XchA-ParamSet", + "id-GostR3410-94-CryptoPro-XchA-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchA_ParamSet,7,&(lvalues[5556]),0}, +{"id-GostR3410-94-CryptoPro-XchB-ParamSet", + "id-GostR3410-94-CryptoPro-XchB-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchB_ParamSet,7,&(lvalues[5563]),0}, +{"id-GostR3410-94-CryptoPro-XchC-ParamSet", + "id-GostR3410-94-CryptoPro-XchC-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchC_ParamSet,7,&(lvalues[5570]),0}, +{"id-GostR3410-2001-TestParamSet","id-GostR3410-2001-TestParamSet", + NID_id_GostR3410_2001_TestParamSet,7,&(lvalues[5577]),0}, +{"id-GostR3410-2001-CryptoPro-A-ParamSet", + "id-GostR3410-2001-CryptoPro-A-ParamSet", + NID_id_GostR3410_2001_CryptoPro_A_ParamSet,7,&(lvalues[5584]),0}, +{"id-GostR3410-2001-CryptoPro-B-ParamSet", + "id-GostR3410-2001-CryptoPro-B-ParamSet", + NID_id_GostR3410_2001_CryptoPro_B_ParamSet,7,&(lvalues[5591]),0}, +{"id-GostR3410-2001-CryptoPro-C-ParamSet", + "id-GostR3410-2001-CryptoPro-C-ParamSet", + NID_id_GostR3410_2001_CryptoPro_C_ParamSet,7,&(lvalues[5598]),0}, +{"id-GostR3410-2001-CryptoPro-XchA-ParamSet", + "id-GostR3410-2001-CryptoPro-XchA-ParamSet", + NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet,7,&(lvalues[5605]),0}, + +{"id-GostR3410-2001-CryptoPro-XchB-ParamSet", + "id-GostR3410-2001-CryptoPro-XchB-ParamSet", + NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet,7,&(lvalues[5612]),0}, + +{"id-GostR3410-94-a","id-GostR3410-94-a",NID_id_GostR3410_94_a,7, + &(lvalues[5619]),0}, +{"id-GostR3410-94-aBis","id-GostR3410-94-aBis", + NID_id_GostR3410_94_aBis,7,&(lvalues[5626]),0}, +{"id-GostR3410-94-b","id-GostR3410-94-b",NID_id_GostR3410_94_b,7, + &(lvalues[5633]),0}, +{"id-GostR3410-94-bBis","id-GostR3410-94-bBis", + NID_id_GostR3410_94_bBis,7,&(lvalues[5640]),0}, +{"id-Gost28147-89-cc","GOST 28147-89 Cryptocom ParamSet", + NID_id_Gost28147_89_cc,8,&(lvalues[5647]),0}, +{"gost94cc","GOST 34.10-94 Cryptocom",NID_id_GostR3410_94_cc,8, + &(lvalues[5655]),0}, +{"gost2001cc","GOST 34.10-2001 Cryptocom",NID_id_GostR3410_2001_cc,8, + &(lvalues[5663]),0}, +{"id-GostR3411-94-with-GostR3410-94-cc", + "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom", + NID_id_GostR3411_94_with_GostR3410_94_cc,8,&(lvalues[5671]),0}, +{"id-GostR3411-94-with-GostR3410-2001-cc", + "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom", + NID_id_GostR3411_94_with_GostR3410_2001_cc,8,&(lvalues[5679]),0}, +{"id-GostR3410-2001-ParamSet-cc", + "GOST R 3410-2001 Parameter Set Cryptocom", + NID_id_GostR3410_2001_ParamSet_cc,8,&(lvalues[5687]),0}, +{"HMAC","hmac",NID_hmac,0,NULL,0}, +{"LocalKeySet","Microsoft Local Key set",NID_LocalKeySet,9, + &(lvalues[5695]),0}, +{"freshestCRL","X509v3 Freshest CRL",NID_freshest_crl,3, + &(lvalues[5704]),0}, +{"id-on-permanentIdentifier","Permanent Identifier", + NID_id_on_permanentIdentifier,8,&(lvalues[5707]),0}, +{"searchGuide","searchGuide",NID_searchGuide,3,&(lvalues[5715]),0}, +{"businessCategory","businessCategory",NID_businessCategory,3, + &(lvalues[5718]),0}, +{"postalAddress","postalAddress",NID_postalAddress,3,&(lvalues[5721]),0}, +{"postOfficeBox","postOfficeBox",NID_postOfficeBox,3,&(lvalues[5724]),0}, +{"physicalDeliveryOfficeName","physicalDeliveryOfficeName", + NID_physicalDeliveryOfficeName,3,&(lvalues[5727]),0}, +{"telephoneNumber","telephoneNumber",NID_telephoneNumber,3, + &(lvalues[5730]),0}, +{"telexNumber","telexNumber",NID_telexNumber,3,&(lvalues[5733]),0}, +{"teletexTerminalIdentifier","teletexTerminalIdentifier", + NID_teletexTerminalIdentifier,3,&(lvalues[5736]),0}, +{"facsimileTelephoneNumber","facsimileTelephoneNumber", + NID_facsimileTelephoneNumber,3,&(lvalues[5739]),0}, +{"x121Address","x121Address",NID_x121Address,3,&(lvalues[5742]),0}, +{"internationaliSDNNumber","internationaliSDNNumber", + NID_internationaliSDNNumber,3,&(lvalues[5745]),0}, +{"registeredAddress","registeredAddress",NID_registeredAddress,3, + &(lvalues[5748]),0}, +{"destinationIndicator","destinationIndicator", + NID_destinationIndicator,3,&(lvalues[5751]),0}, +{"preferredDeliveryMethod","preferredDeliveryMethod", + NID_preferredDeliveryMethod,3,&(lvalues[5754]),0}, +{"presentationAddress","presentationAddress",NID_presentationAddress, + 3,&(lvalues[5757]),0}, +{"supportedApplicationContext","supportedApplicationContext", + NID_supportedApplicationContext,3,&(lvalues[5760]),0}, +{"member","member",NID_member,3,&(lvalues[5763]),0}, +{"owner","owner",NID_owner,3,&(lvalues[5766]),0}, +{"roleOccupant","roleOccupant",NID_roleOccupant,3,&(lvalues[5769]),0}, +{"seeAlso","seeAlso",NID_seeAlso,3,&(lvalues[5772]),0}, +{"userPassword","userPassword",NID_userPassword,3,&(lvalues[5775]),0}, +{"userCertificate","userCertificate",NID_userCertificate,3, + &(lvalues[5778]),0}, +{"cACertificate","cACertificate",NID_cACertificate,3,&(lvalues[5781]),0}, +{"authorityRevocationList","authorityRevocationList", + NID_authorityRevocationList,3,&(lvalues[5784]),0}, +{"certificateRevocationList","certificateRevocationList", + NID_certificateRevocationList,3,&(lvalues[5787]),0}, +{"crossCertificatePair","crossCertificatePair", + NID_crossCertificatePair,3,&(lvalues[5790]),0}, +{"enhancedSearchGuide","enhancedSearchGuide",NID_enhancedSearchGuide, + 3,&(lvalues[5793]),0}, +{"protocolInformation","protocolInformation",NID_protocolInformation, + 3,&(lvalues[5796]),0}, +{"distinguishedName","distinguishedName",NID_distinguishedName,3, + &(lvalues[5799]),0}, +{"uniqueMember","uniqueMember",NID_uniqueMember,3,&(lvalues[5802]),0}, +{"houseIdentifier","houseIdentifier",NID_houseIdentifier,3, + &(lvalues[5805]),0}, +{"supportedAlgorithms","supportedAlgorithms",NID_supportedAlgorithms, + 3,&(lvalues[5808]),0}, +{"deltaRevocationList","deltaRevocationList",NID_deltaRevocationList, + 3,&(lvalues[5811]),0}, +{"dmdName","dmdName",NID_dmdName,3,&(lvalues[5814]),0}, +{"id-alg-PWRI-KEK","id-alg-PWRI-KEK",NID_id_alg_PWRI_KEK,11, + &(lvalues[5817]),0}, +{"CMAC","cmac",NID_cmac,0,NULL,0}, +{"id-aes128-GCM","aes-128-gcm",NID_aes_128_gcm,9,&(lvalues[5828]),0}, +{"id-aes128-CCM","aes-128-ccm",NID_aes_128_ccm,9,&(lvalues[5837]),0}, +{"id-aes128-wrap-pad","id-aes128-wrap-pad",NID_id_aes128_wrap_pad,9, + &(lvalues[5846]),0}, +{"id-aes192-GCM","aes-192-gcm",NID_aes_192_gcm,9,&(lvalues[5855]),0}, +{"id-aes192-CCM","aes-192-ccm",NID_aes_192_ccm,9,&(lvalues[5864]),0}, +{"id-aes192-wrap-pad","id-aes192-wrap-pad",NID_id_aes192_wrap_pad,9, + &(lvalues[5873]),0}, +{"id-aes256-GCM","aes-256-gcm",NID_aes_256_gcm,9,&(lvalues[5882]),0}, +{"id-aes256-CCM","aes-256-ccm",NID_aes_256_ccm,9,&(lvalues[5891]),0}, +{"id-aes256-wrap-pad","id-aes256-wrap-pad",NID_id_aes256_wrap_pad,9, + &(lvalues[5900]),0}, +{"AES-128-CTR","aes-128-ctr",NID_aes_128_ctr,0,NULL,0}, +{"AES-192-CTR","aes-192-ctr",NID_aes_192_ctr,0,NULL,0}, +{"AES-256-CTR","aes-256-ctr",NID_aes_256_ctr,0,NULL,0}, +{"id-camellia128-wrap","id-camellia128-wrap",NID_id_camellia128_wrap, + 11,&(lvalues[5909]),0}, +{"id-camellia192-wrap","id-camellia192-wrap",NID_id_camellia192_wrap, + 11,&(lvalues[5920]),0}, +{"id-camellia256-wrap","id-camellia256-wrap",NID_id_camellia256_wrap, + 11,&(lvalues[5931]),0}, +{"anyExtendedKeyUsage","Any Extended Key Usage", + NID_anyExtendedKeyUsage,4,&(lvalues[5942]),0}, +{"MGF1","mgf1",NID_mgf1,9,&(lvalues[5946]),0}, +{"RSASSA-PSS","rsassaPss",NID_rsassaPss,9,&(lvalues[5955]),0}, +{"AES-128-XTS","aes-128-xts",NID_aes_128_xts,0,NULL,0}, +{"AES-256-XTS","aes-256-xts",NID_aes_256_xts,0,NULL,0}, +{"RC4-HMAC-MD5","rc4-hmac-md5",NID_rc4_hmac_md5,0,NULL,0}, +{"AES-128-CBC-HMAC-SHA1","aes-128-cbc-hmac-sha1", + NID_aes_128_cbc_hmac_sha1,0,NULL,0}, +{"AES-192-CBC-HMAC-SHA1","aes-192-cbc-hmac-sha1", + NID_aes_192_cbc_hmac_sha1,0,NULL,0}, +{"AES-256-CBC-HMAC-SHA1","aes-256-cbc-hmac-sha1", + NID_aes_256_cbc_hmac_sha1,0,NULL,0}, +{"RSAES-OAEP","rsaesOaep",NID_rsaesOaep,9,&(lvalues[5964]),0}, +}; + +static const unsigned int sn_objs[NUM_SN]={ +364, /* "AD_DVCS" */ +419, /* "AES-128-CBC" */ +916, /* "AES-128-CBC-HMAC-SHA1" */ +421, /* "AES-128-CFB" */ +650, /* "AES-128-CFB1" */ +653, /* "AES-128-CFB8" */ +904, /* "AES-128-CTR" */ +418, /* "AES-128-ECB" */ +420, /* "AES-128-OFB" */ +913, /* "AES-128-XTS" */ +423, /* "AES-192-CBC" */ +917, /* "AES-192-CBC-HMAC-SHA1" */ +425, /* "AES-192-CFB" */ +651, /* "AES-192-CFB1" */ +654, /* "AES-192-CFB8" */ +905, /* "AES-192-CTR" */ +422, /* "AES-192-ECB" */ +424, /* "AES-192-OFB" */ +427, /* "AES-256-CBC" */ +918, /* "AES-256-CBC-HMAC-SHA1" */ +429, /* "AES-256-CFB" */ +652, /* "AES-256-CFB1" */ +655, /* "AES-256-CFB8" */ +906, /* "AES-256-CTR" */ +426, /* "AES-256-ECB" */ +428, /* "AES-256-OFB" */ +914, /* "AES-256-XTS" */ +91, /* "BF-CBC" */ +93, /* "BF-CFB" */ +92, /* "BF-ECB" */ +94, /* "BF-OFB" */ +14, /* "C" */ +751, /* "CAMELLIA-128-CBC" */ +757, /* "CAMELLIA-128-CFB" */ +760, /* "CAMELLIA-128-CFB1" */ +763, /* "CAMELLIA-128-CFB8" */ +754, /* "CAMELLIA-128-ECB" */ +766, /* "CAMELLIA-128-OFB" */ +752, /* "CAMELLIA-192-CBC" */ +758, /* "CAMELLIA-192-CFB" */ +761, /* "CAMELLIA-192-CFB1" */ +764, /* "CAMELLIA-192-CFB8" */ +755, /* "CAMELLIA-192-ECB" */ +767, /* "CAMELLIA-192-OFB" */ +753, /* "CAMELLIA-256-CBC" */ +759, /* "CAMELLIA-256-CFB" */ +762, /* "CAMELLIA-256-CFB1" */ +765, /* "CAMELLIA-256-CFB8" */ +756, /* "CAMELLIA-256-ECB" */ +768, /* "CAMELLIA-256-OFB" */ +108, /* "CAST5-CBC" */ +110, /* "CAST5-CFB" */ +109, /* "CAST5-ECB" */ +111, /* "CAST5-OFB" */ +894, /* "CMAC" */ +13, /* "CN" */ +141, /* "CRLReason" */ +417, /* "CSPName" */ +367, /* "CrlID" */ +391, /* "DC" */ +31, /* "DES-CBC" */ +643, /* "DES-CDMF" */ +30, /* "DES-CFB" */ +656, /* "DES-CFB1" */ +657, /* "DES-CFB8" */ +29, /* "DES-ECB" */ +32, /* "DES-EDE" */ +43, /* "DES-EDE-CBC" */ +60, /* "DES-EDE-CFB" */ +62, /* "DES-EDE-OFB" */ +33, /* "DES-EDE3" */ +44, /* "DES-EDE3-CBC" */ +61, /* "DES-EDE3-CFB" */ +658, /* "DES-EDE3-CFB1" */ +659, /* "DES-EDE3-CFB8" */ +63, /* "DES-EDE3-OFB" */ +45, /* "DES-OFB" */ +80, /* "DESX-CBC" */ +380, /* "DOD" */ +116, /* "DSA" */ +66, /* "DSA-SHA" */ +113, /* "DSA-SHA1" */ +70, /* "DSA-SHA1-old" */ +67, /* "DSA-old" */ +297, /* "DVCS" */ +99, /* "GN" */ +855, /* "HMAC" */ +780, /* "HMAC-MD5" */ +781, /* "HMAC-SHA1" */ +381, /* "IANA" */ +34, /* "IDEA-CBC" */ +35, /* "IDEA-CFB" */ +36, /* "IDEA-ECB" */ +46, /* "IDEA-OFB" */ +181, /* "ISO" */ +183, /* "ISO-US" */ +645, /* "ITU-T" */ +646, /* "JOINT-ISO-ITU-T" */ +773, /* "KISA" */ +15, /* "L" */ +856, /* "LocalKeySet" */ + 3, /* "MD2" */ +257, /* "MD4" */ + 4, /* "MD5" */ +114, /* "MD5-SHA1" */ +95, /* "MDC2" */ +911, /* "MGF1" */ +388, /* "Mail" */ +393, /* "NULL" */ +404, /* "NULL" */ +57, /* "Netscape" */ +366, /* "Nonce" */ +17, /* "O" */ +178, /* "OCSP" */ +180, /* "OCSPSigning" */ +379, /* "ORG" */ +18, /* "OU" */ +749, /* "Oakley-EC2N-3" */ +750, /* "Oakley-EC2N-4" */ + 9, /* "PBE-MD2-DES" */ +168, /* "PBE-MD2-RC2-64" */ +10, /* "PBE-MD5-DES" */ +169, /* "PBE-MD5-RC2-64" */ +147, /* "PBE-SHA1-2DES" */ +146, /* "PBE-SHA1-3DES" */ +170, /* "PBE-SHA1-DES" */ +148, /* "PBE-SHA1-RC2-128" */ +149, /* "PBE-SHA1-RC2-40" */ +68, /* "PBE-SHA1-RC2-64" */ +144, /* "PBE-SHA1-RC4-128" */ +145, /* "PBE-SHA1-RC4-40" */ +161, /* "PBES2" */ +69, /* "PBKDF2" */ +162, /* "PBMAC1" */ +127, /* "PKIX" */ +98, /* "RC2-40-CBC" */ +166, /* "RC2-64-CBC" */ +37, /* "RC2-CBC" */ +39, /* "RC2-CFB" */ +38, /* "RC2-ECB" */ +40, /* "RC2-OFB" */ + 5, /* "RC4" */ +97, /* "RC4-40" */ +915, /* "RC4-HMAC-MD5" */ +120, /* "RC5-CBC" */ +122, /* "RC5-CFB" */ +121, /* "RC5-ECB" */ +123, /* "RC5-OFB" */ +117, /* "RIPEMD160" */ +124, /* "RLE" */ +19, /* "RSA" */ + 7, /* "RSA-MD2" */ +396, /* "RSA-MD4" */ + 8, /* "RSA-MD5" */ +96, /* "RSA-MDC2" */ +104, /* "RSA-NP-MD5" */ +119, /* "RSA-RIPEMD160" */ +42, /* "RSA-SHA" */ +65, /* "RSA-SHA1" */ +115, /* "RSA-SHA1-2" */ +671, /* "RSA-SHA224" */ +668, /* "RSA-SHA256" */ +669, /* "RSA-SHA384" */ +670, /* "RSA-SHA512" */ +919, /* "RSAES-OAEP" */ +912, /* "RSASSA-PSS" */ +777, /* "SEED-CBC" */ +779, /* "SEED-CFB" */ +776, /* "SEED-ECB" */ +778, /* "SEED-OFB" */ +41, /* "SHA" */ +64, /* "SHA1" */ +675, /* "SHA224" */ +672, /* "SHA256" */ +673, /* "SHA384" */ +674, /* "SHA512" */ +188, /* "SMIME" */ +167, /* "SMIME-CAPS" */ +100, /* "SN" */ +16, /* "ST" */ +143, /* "SXNetID" */ +458, /* "UID" */ + 0, /* "UNDEF" */ +11, /* "X500" */ +378, /* "X500algorithms" */ +12, /* "X509" */ +184, /* "X9-57" */ +185, /* "X9cm" */ +125, /* "ZLIB" */ +478, /* "aRecord" */ +289, /* "aaControls" */ +287, /* "ac-auditEntity" */ +397, /* "ac-proxying" */ +288, /* "ac-targeting" */ +368, /* "acceptableResponses" */ +446, /* "account" */ +363, /* "ad_timestamping" */ +376, /* "algorithm" */ +405, /* "ansi-X9-62" */ +910, /* "anyExtendedKeyUsage" */ +746, /* "anyPolicy" */ +370, /* "archiveCutoff" */ +484, /* "associatedDomain" */ +485, /* "associatedName" */ +501, /* "audio" */ +177, /* "authorityInfoAccess" */ +90, /* "authorityKeyIdentifier" */ +882, /* "authorityRevocationList" */ +87, /* "basicConstraints" */ +365, /* "basicOCSPResponse" */ +285, /* "biometricInfo" */ +494, /* "buildingName" */ +860, /* "businessCategory" */ +691, /* "c2onb191v4" */ +692, /* "c2onb191v5" */ +697, /* "c2onb239v4" */ +698, /* "c2onb239v5" */ +684, /* "c2pnb163v1" */ +685, /* "c2pnb163v2" */ +686, /* "c2pnb163v3" */ +687, /* "c2pnb176v1" */ +693, /* "c2pnb208w1" */ +699, /* "c2pnb272w1" */ +700, /* "c2pnb304w1" */ +702, /* "c2pnb368w1" */ +688, /* "c2tnb191v1" */ +689, /* "c2tnb191v2" */ +690, /* "c2tnb191v3" */ +694, /* "c2tnb239v1" */ +695, /* "c2tnb239v2" */ +696, /* "c2tnb239v3" */ +701, /* "c2tnb359v1" */ +703, /* "c2tnb431r1" */ +881, /* "cACertificate" */ +483, /* "cNAMERecord" */ +179, /* "caIssuers" */ +785, /* "caRepository" */ +443, /* "caseIgnoreIA5StringSyntax" */ +152, /* "certBag" */ +677, /* "certicom-arc" */ +771, /* "certificateIssuer" */ +89, /* "certificatePolicies" */ +883, /* "certificateRevocationList" */ +54, /* "challengePassword" */ +407, /* "characteristic-two-field" */ +395, /* "clearance" */ +130, /* "clientAuth" */ +131, /* "codeSigning" */ +50, /* "contentType" */ +53, /* "countersignature" */ +153, /* "crlBag" */ +103, /* "crlDistributionPoints" */ +88, /* "crlNumber" */ +884, /* "crossCertificatePair" */ +806, /* "cryptocom" */ +805, /* "cryptopro" */ +500, /* "dITRedirect" */ +451, /* "dNSDomain" */ +495, /* "dSAQuality" */ +434, /* "data" */ +390, /* "dcobject" */ +140, /* "deltaCRL" */ +891, /* "deltaRevocationList" */ +107, /* "description" */ +871, /* "destinationIndicator" */ +28, /* "dhKeyAgreement" */ +382, /* "directory" */ +887, /* "distinguishedName" */ +892, /* "dmdName" */ +174, /* "dnQualifier" */ +447, /* "document" */ +471, /* "documentAuthor" */ +468, /* "documentIdentifier" */ +472, /* "documentLocation" */ +502, /* "documentPublisher" */ +449, /* "documentSeries" */ +469, /* "documentTitle" */ +470, /* "documentVersion" */ +392, /* "domain" */ +452, /* "domainRelatedObject" */ +802, /* "dsa_with_SHA224" */ +803, /* "dsa_with_SHA256" */ +791, /* "ecdsa-with-Recommended" */ +416, /* "ecdsa-with-SHA1" */ +793, /* "ecdsa-with-SHA224" */ +794, /* "ecdsa-with-SHA256" */ +795, /* "ecdsa-with-SHA384" */ +796, /* "ecdsa-with-SHA512" */ +792, /* "ecdsa-with-Specified" */ +48, /* "emailAddress" */ +132, /* "emailProtection" */ +885, /* "enhancedSearchGuide" */ +389, /* "enterprises" */ +384, /* "experimental" */ +172, /* "extReq" */ +56, /* "extendedCertificateAttributes" */ +126, /* "extendedKeyUsage" */ +372, /* "extendedStatus" */ +867, /* "facsimileTelephoneNumber" */ +462, /* "favouriteDrink" */ +857, /* "freshestCRL" */ +453, /* "friendlyCountry" */ +490, /* "friendlyCountryName" */ +156, /* "friendlyName" */ +509, /* "generationQualifier" */ +815, /* "gost-mac" */ +811, /* "gost2001" */ +851, /* "gost2001cc" */ +813, /* "gost89" */ +814, /* "gost89-cnt" */ +812, /* "gost94" */ +850, /* "gost94cc" */ +797, /* "hmacWithMD5" */ +163, /* "hmacWithSHA1" */ +798, /* "hmacWithSHA224" */ +799, /* "hmacWithSHA256" */ +800, /* "hmacWithSHA384" */ +801, /* "hmacWithSHA512" */ +432, /* "holdInstructionCallIssuer" */ +430, /* "holdInstructionCode" */ +431, /* "holdInstructionNone" */ +433, /* "holdInstructionReject" */ +486, /* "homePostalAddress" */ +473, /* "homeTelephoneNumber" */ +466, /* "host" */ +889, /* "houseIdentifier" */ +442, /* "iA5StringSyntax" */ +783, /* "id-DHBasedMac" */ +824, /* "id-Gost28147-89-CryptoPro-A-ParamSet" */ +825, /* "id-Gost28147-89-CryptoPro-B-ParamSet" */ +826, /* "id-Gost28147-89-CryptoPro-C-ParamSet" */ +827, /* "id-Gost28147-89-CryptoPro-D-ParamSet" */ +819, /* "id-Gost28147-89-CryptoPro-KeyMeshing" */ +829, /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */ +828, /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */ +830, /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */ +820, /* "id-Gost28147-89-None-KeyMeshing" */ +823, /* "id-Gost28147-89-TestParamSet" */ +849, /* "id-Gost28147-89-cc" */ +840, /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */ +841, /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */ +842, /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */ +843, /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */ +844, /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */ +854, /* "id-GostR3410-2001-ParamSet-cc" */ +839, /* "id-GostR3410-2001-TestParamSet" */ +817, /* "id-GostR3410-2001DH" */ +832, /* "id-GostR3410-94-CryptoPro-A-ParamSet" */ +833, /* "id-GostR3410-94-CryptoPro-B-ParamSet" */ +834, /* "id-GostR3410-94-CryptoPro-C-ParamSet" */ +835, /* "id-GostR3410-94-CryptoPro-D-ParamSet" */ +836, /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */ +837, /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */ +838, /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */ +831, /* "id-GostR3410-94-TestParamSet" */ +845, /* "id-GostR3410-94-a" */ +846, /* "id-GostR3410-94-aBis" */ +847, /* "id-GostR3410-94-b" */ +848, /* "id-GostR3410-94-bBis" */ +818, /* "id-GostR3410-94DH" */ +822, /* "id-GostR3411-94-CryptoProParamSet" */ +821, /* "id-GostR3411-94-TestParamSet" */ +807, /* "id-GostR3411-94-with-GostR3410-2001" */ +853, /* "id-GostR3411-94-with-GostR3410-2001-cc" */ +808, /* "id-GostR3411-94-with-GostR3410-94" */ +852, /* "id-GostR3411-94-with-GostR3410-94-cc" */ +810, /* "id-HMACGostR3411-94" */ +782, /* "id-PasswordBasedMAC" */ +266, /* "id-aca" */ +355, /* "id-aca-accessIdentity" */ +354, /* "id-aca-authenticationInfo" */ +356, /* "id-aca-chargingIdentity" */ +399, /* "id-aca-encAttrs" */ +357, /* "id-aca-group" */ +358, /* "id-aca-role" */ +176, /* "id-ad" */ +896, /* "id-aes128-CCM" */ +895, /* "id-aes128-GCM" */ +788, /* "id-aes128-wrap" */ +897, /* "id-aes128-wrap-pad" */ +899, /* "id-aes192-CCM" */ +898, /* "id-aes192-GCM" */ +789, /* "id-aes192-wrap" */ +900, /* "id-aes192-wrap-pad" */ +902, /* "id-aes256-CCM" */ +901, /* "id-aes256-GCM" */ +790, /* "id-aes256-wrap" */ +903, /* "id-aes256-wrap-pad" */ +262, /* "id-alg" */ +893, /* "id-alg-PWRI-KEK" */ +323, /* "id-alg-des40" */ +326, /* "id-alg-dh-pop" */ +325, /* "id-alg-dh-sig-hmac-sha1" */ +324, /* "id-alg-noSignature" */ +907, /* "id-camellia128-wrap" */ +908, /* "id-camellia192-wrap" */ +909, /* "id-camellia256-wrap" */ +268, /* "id-cct" */ +361, /* "id-cct-PKIData" */ +362, /* "id-cct-PKIResponse" */ +360, /* "id-cct-crs" */ +81, /* "id-ce" */ +680, /* "id-characteristic-two-basis" */ +263, /* "id-cmc" */ +334, /* "id-cmc-addExtensions" */ +346, /* "id-cmc-confirmCertAcceptance" */ +330, /* "id-cmc-dataReturn" */ +336, /* "id-cmc-decryptedPOP" */ +335, /* "id-cmc-encryptedPOP" */ +339, /* "id-cmc-getCRL" */ +338, /* "id-cmc-getCert" */ +328, /* "id-cmc-identification" */ +329, /* "id-cmc-identityProof" */ +337, /* "id-cmc-lraPOPWitness" */ +344, /* "id-cmc-popLinkRandom" */ +345, /* "id-cmc-popLinkWitness" */ +343, /* "id-cmc-queryPending" */ +333, /* "id-cmc-recipientNonce" */ +341, /* "id-cmc-regInfo" */ +342, /* "id-cmc-responseInfo" */ +340, /* "id-cmc-revokeRequest" */ +332, /* "id-cmc-senderNonce" */ +327, /* "id-cmc-statusInfo" */ +331, /* "id-cmc-transactionId" */ +787, /* "id-ct-asciiTextWithCRLF" */ +408, /* "id-ecPublicKey" */ +508, /* "id-hex-multipart-message" */ +507, /* "id-hex-partial-message" */ +260, /* "id-it" */ +302, /* "id-it-caKeyUpdateInfo" */ +298, /* "id-it-caProtEncCert" */ +311, /* "id-it-confirmWaitTime" */ +303, /* "id-it-currentCRL" */ +300, /* "id-it-encKeyPairTypes" */ +310, /* "id-it-implicitConfirm" */ +308, /* "id-it-keyPairParamRep" */ +307, /* "id-it-keyPairParamReq" */ +312, /* "id-it-origPKIMessage" */ +301, /* "id-it-preferredSymmAlg" */ +309, /* "id-it-revPassphrase" */ +299, /* "id-it-signKeyPairTypes" */ +305, /* "id-it-subscriptionRequest" */ +306, /* "id-it-subscriptionResponse" */ +784, /* "id-it-suppLangTags" */ +304, /* "id-it-unsupportedOIDs" */ +128, /* "id-kp" */ +280, /* "id-mod-attribute-cert" */ +274, /* "id-mod-cmc" */ +277, /* "id-mod-cmp" */ +284, /* "id-mod-cmp2000" */ +273, /* "id-mod-crmf" */ +283, /* "id-mod-dvcs" */ +275, /* "id-mod-kea-profile-88" */ +276, /* "id-mod-kea-profile-93" */ +282, /* "id-mod-ocsp" */ +278, /* "id-mod-qualified-cert-88" */ +279, /* "id-mod-qualified-cert-93" */ +281, /* "id-mod-timestamp-protocol" */ +264, /* "id-on" */ +858, /* "id-on-permanentIdentifier" */ +347, /* "id-on-personalData" */ +265, /* "id-pda" */ +352, /* "id-pda-countryOfCitizenship" */ +353, /* "id-pda-countryOfResidence" */ +348, /* "id-pda-dateOfBirth" */ +351, /* "id-pda-gender" */ +349, /* "id-pda-placeOfBirth" */ +175, /* "id-pe" */ +261, /* "id-pkip" */ +258, /* "id-pkix-mod" */ +269, /* "id-pkix1-explicit-88" */ +271, /* "id-pkix1-explicit-93" */ +270, /* "id-pkix1-implicit-88" */ +272, /* "id-pkix1-implicit-93" */ +662, /* "id-ppl" */ +664, /* "id-ppl-anyLanguage" */ +667, /* "id-ppl-independent" */ +665, /* "id-ppl-inheritAll" */ +267, /* "id-qcs" */ +359, /* "id-qcs-pkixQCSyntax-v1" */ +259, /* "id-qt" */ +164, /* "id-qt-cps" */ +165, /* "id-qt-unotice" */ +313, /* "id-regCtrl" */ +316, /* "id-regCtrl-authenticator" */ +319, /* "id-regCtrl-oldCertID" */ +318, /* "id-regCtrl-pkiArchiveOptions" */ +317, /* "id-regCtrl-pkiPublicationInfo" */ +320, /* "id-regCtrl-protocolEncrKey" */ +315, /* "id-regCtrl-regToken" */ +314, /* "id-regInfo" */ +322, /* "id-regInfo-certReq" */ +321, /* "id-regInfo-utf8Pairs" */ +512, /* "id-set" */ +191, /* "id-smime-aa" */ +215, /* "id-smime-aa-contentHint" */ +218, /* "id-smime-aa-contentIdentifier" */ +221, /* "id-smime-aa-contentReference" */ +240, /* "id-smime-aa-dvcs-dvc" */ +217, /* "id-smime-aa-encapContentType" */ +222, /* "id-smime-aa-encrypKeyPref" */ +220, /* "id-smime-aa-equivalentLabels" */ +232, /* "id-smime-aa-ets-CertificateRefs" */ +233, /* "id-smime-aa-ets-RevocationRefs" */ +238, /* "id-smime-aa-ets-archiveTimeStamp" */ +237, /* "id-smime-aa-ets-certCRLTimestamp" */ +234, /* "id-smime-aa-ets-certValues" */ +227, /* "id-smime-aa-ets-commitmentType" */ +231, /* "id-smime-aa-ets-contentTimestamp" */ +236, /* "id-smime-aa-ets-escTimeStamp" */ +230, /* "id-smime-aa-ets-otherSigCert" */ +235, /* "id-smime-aa-ets-revocationValues" */ +226, /* "id-smime-aa-ets-sigPolicyId" */ +229, /* "id-smime-aa-ets-signerAttr" */ +228, /* "id-smime-aa-ets-signerLocation" */ +219, /* "id-smime-aa-macValue" */ +214, /* "id-smime-aa-mlExpandHistory" */ +216, /* "id-smime-aa-msgSigDigest" */ +212, /* "id-smime-aa-receiptRequest" */ +213, /* "id-smime-aa-securityLabel" */ +239, /* "id-smime-aa-signatureType" */ +223, /* "id-smime-aa-signingCertificate" */ +224, /* "id-smime-aa-smimeEncryptCerts" */ +225, /* "id-smime-aa-timeStampToken" */ +192, /* "id-smime-alg" */ +243, /* "id-smime-alg-3DESwrap" */ +246, /* "id-smime-alg-CMS3DESwrap" */ +247, /* "id-smime-alg-CMSRC2wrap" */ +245, /* "id-smime-alg-ESDH" */ +241, /* "id-smime-alg-ESDHwith3DES" */ +242, /* "id-smime-alg-ESDHwithRC2" */ +244, /* "id-smime-alg-RC2wrap" */ +193, /* "id-smime-cd" */ +248, /* "id-smime-cd-ldap" */ +190, /* "id-smime-ct" */ +210, /* "id-smime-ct-DVCSRequestData" */ +211, /* "id-smime-ct-DVCSResponseData" */ +208, /* "id-smime-ct-TDTInfo" */ +207, /* "id-smime-ct-TSTInfo" */ +205, /* "id-smime-ct-authData" */ +786, /* "id-smime-ct-compressedData" */ +209, /* "id-smime-ct-contentInfo" */ +206, /* "id-smime-ct-publishCert" */ +204, /* "id-smime-ct-receipt" */ +195, /* "id-smime-cti" */ +255, /* "id-smime-cti-ets-proofOfApproval" */ +256, /* "id-smime-cti-ets-proofOfCreation" */ +253, /* "id-smime-cti-ets-proofOfDelivery" */ +251, /* "id-smime-cti-ets-proofOfOrigin" */ +252, /* "id-smime-cti-ets-proofOfReceipt" */ +254, /* "id-smime-cti-ets-proofOfSender" */ +189, /* "id-smime-mod" */ +196, /* "id-smime-mod-cms" */ +197, /* "id-smime-mod-ess" */ +202, /* "id-smime-mod-ets-eSigPolicy-88" */ +203, /* "id-smime-mod-ets-eSigPolicy-97" */ +200, /* "id-smime-mod-ets-eSignature-88" */ +201, /* "id-smime-mod-ets-eSignature-97" */ +199, /* "id-smime-mod-msg-v3" */ +198, /* "id-smime-mod-oid" */ +194, /* "id-smime-spq" */ +250, /* "id-smime-spq-ets-sqt-unotice" */ +249, /* "id-smime-spq-ets-sqt-uri" */ +676, /* "identified-organization" */ +461, /* "info" */ +748, /* "inhibitAnyPolicy" */ +101, /* "initials" */ +647, /* "international-organizations" */ +869, /* "internationaliSDNNumber" */ +142, /* "invalidityDate" */ +294, /* "ipsecEndSystem" */ +295, /* "ipsecTunnel" */ +296, /* "ipsecUser" */ +86, /* "issuerAltName" */ +770, /* "issuingDistributionPoint" */ +492, /* "janetMailbox" */ +150, /* "keyBag" */ +83, /* "keyUsage" */ +477, /* "lastModifiedBy" */ +476, /* "lastModifiedTime" */ +157, /* "localKeyID" */ +480, /* "mXRecord" */ +460, /* "mail" */ +493, /* "mailPreferenceOption" */ +467, /* "manager" */ +809, /* "md_gost94" */ +875, /* "member" */ +182, /* "member-body" */ +51, /* "messageDigest" */ +383, /* "mgmt" */ +504, /* "mime-mhs" */ +506, /* "mime-mhs-bodies" */ +505, /* "mime-mhs-headings" */ +488, /* "mobileTelephoneNumber" */ +136, /* "msCTLSign" */ +135, /* "msCodeCom" */ +134, /* "msCodeInd" */ +138, /* "msEFS" */ +171, /* "msExtReq" */ +137, /* "msSGC" */ +648, /* "msSmartcardLogin" */ +649, /* "msUPN" */ +481, /* "nSRecord" */ +173, /* "name" */ +666, /* "nameConstraints" */ +369, /* "noCheck" */ +403, /* "noRevAvail" */ +72, /* "nsBaseUrl" */ +76, /* "nsCaPolicyUrl" */ +74, /* "nsCaRevocationUrl" */ +58, /* "nsCertExt" */ +79, /* "nsCertSequence" */ +71, /* "nsCertType" */ +78, /* "nsComment" */ +59, /* "nsDataType" */ +75, /* "nsRenewalUrl" */ +73, /* "nsRevocationUrl" */ +139, /* "nsSGC" */ +77, /* "nsSslServerName" */ +681, /* "onBasis" */ +491, /* "organizationalStatus" */ +475, /* "otherMailbox" */ +876, /* "owner" */ +489, /* "pagerTelephoneNumber" */ +374, /* "path" */ +112, /* "pbeWithMD5AndCast5CBC" */ +499, /* "personalSignature" */ +487, /* "personalTitle" */ +464, /* "photo" */ +863, /* "physicalDeliveryOfficeName" */ +437, /* "pilot" */ +439, /* "pilotAttributeSyntax" */ +438, /* "pilotAttributeType" */ +479, /* "pilotAttributeType27" */ +456, /* "pilotDSA" */ +441, /* "pilotGroups" */ +444, /* "pilotObject" */ +440, /* "pilotObjectClass" */ +455, /* "pilotOrganization" */ +445, /* "pilotPerson" */ + 2, /* "pkcs" */ +186, /* "pkcs1" */ +27, /* "pkcs3" */ +187, /* "pkcs5" */ +20, /* "pkcs7" */ +21, /* "pkcs7-data" */ +25, /* "pkcs7-digestData" */ +26, /* "pkcs7-encryptedData" */ +23, /* "pkcs7-envelopedData" */ +24, /* "pkcs7-signedAndEnvelopedData" */ +22, /* "pkcs7-signedData" */ +151, /* "pkcs8ShroudedKeyBag" */ +47, /* "pkcs9" */ +401, /* "policyConstraints" */ +747, /* "policyMappings" */ +862, /* "postOfficeBox" */ +861, /* "postalAddress" */ +661, /* "postalCode" */ +683, /* "ppBasis" */ +872, /* "preferredDeliveryMethod" */ +873, /* "presentationAddress" */ +816, /* "prf-gostr3411-94" */ +406, /* "prime-field" */ +409, /* "prime192v1" */ +410, /* "prime192v2" */ +411, /* "prime192v3" */ +412, /* "prime239v1" */ +413, /* "prime239v2" */ +414, /* "prime239v3" */ +415, /* "prime256v1" */ +385, /* "private" */ +84, /* "privateKeyUsagePeriod" */ +886, /* "protocolInformation" */ +663, /* "proxyCertInfo" */ +510, /* "pseudonym" */ +435, /* "pss" */ +286, /* "qcStatements" */ +457, /* "qualityLabelledData" */ +450, /* "rFC822localPart" */ +870, /* "registeredAddress" */ +400, /* "role" */ +877, /* "roleOccupant" */ +448, /* "room" */ +463, /* "roomNumber" */ + 6, /* "rsaEncryption" */ +644, /* "rsaOAEPEncryptionSET" */ +377, /* "rsaSignature" */ + 1, /* "rsadsi" */ +482, /* "sOARecord" */ +155, /* "safeContentsBag" */ +291, /* "sbgp-autonomousSysNum" */ +290, /* "sbgp-ipAddrBlock" */ +292, /* "sbgp-routerIdentifier" */ +159, /* "sdsiCertificate" */ +859, /* "searchGuide" */ +704, /* "secp112r1" */ +705, /* "secp112r2" */ +706, /* "secp128r1" */ +707, /* "secp128r2" */ +708, /* "secp160k1" */ +709, /* "secp160r1" */ +710, /* "secp160r2" */ +711, /* "secp192k1" */ +712, /* "secp224k1" */ +713, /* "secp224r1" */ +714, /* "secp256k1" */ +715, /* "secp384r1" */ +716, /* "secp521r1" */ +154, /* "secretBag" */ +474, /* "secretary" */ +717, /* "sect113r1" */ +718, /* "sect113r2" */ +719, /* "sect131r1" */ +720, /* "sect131r2" */ +721, /* "sect163k1" */ +722, /* "sect163r1" */ +723, /* "sect163r2" */ +724, /* "sect193r1" */ +725, /* "sect193r2" */ +726, /* "sect233k1" */ +727, /* "sect233r1" */ +728, /* "sect239k1" */ +729, /* "sect283k1" */ +730, /* "sect283r1" */ +731, /* "sect409k1" */ +732, /* "sect409r1" */ +733, /* "sect571k1" */ +734, /* "sect571r1" */ +386, /* "security" */ +878, /* "seeAlso" */ +394, /* "selected-attribute-types" */ +105, /* "serialNumber" */ +129, /* "serverAuth" */ +371, /* "serviceLocator" */ +625, /* "set-addPolicy" */ +515, /* "set-attr" */ +518, /* "set-brand" */ +638, /* "set-brand-AmericanExpress" */ +637, /* "set-brand-Diners" */ +636, /* "set-brand-IATA-ATA" */ +639, /* "set-brand-JCB" */ +641, /* "set-brand-MasterCard" */ +642, /* "set-brand-Novus" */ +640, /* "set-brand-Visa" */ +517, /* "set-certExt" */ +513, /* "set-ctype" */ +514, /* "set-msgExt" */ +516, /* "set-policy" */ +607, /* "set-policy-root" */ +624, /* "set-rootKeyThumb" */ +620, /* "setAttr-Cert" */ +631, /* "setAttr-GenCryptgrm" */ +623, /* "setAttr-IssCap" */ +628, /* "setAttr-IssCap-CVM" */ +630, /* "setAttr-IssCap-Sig" */ +629, /* "setAttr-IssCap-T2" */ +621, /* "setAttr-PGWYcap" */ +635, /* "setAttr-SecDevSig" */ +632, /* "setAttr-T2Enc" */ +633, /* "setAttr-T2cleartxt" */ +634, /* "setAttr-TokICCsig" */ +627, /* "setAttr-Token-B0Prime" */ +626, /* "setAttr-Token-EMV" */ +622, /* "setAttr-TokenType" */ +619, /* "setCext-IssuerCapabilities" */ +615, /* "setCext-PGWYcapabilities" */ +616, /* "setCext-TokenIdentifier" */ +618, /* "setCext-TokenType" */ +617, /* "setCext-Track2Data" */ +611, /* "setCext-cCertRequired" */ +609, /* "setCext-certType" */ +608, /* "setCext-hashedRoot" */ +610, /* "setCext-merchData" */ +613, /* "setCext-setExt" */ +614, /* "setCext-setQualf" */ +612, /* "setCext-tunneling" */ +540, /* "setct-AcqCardCodeMsg" */ +576, /* "setct-AcqCardCodeMsgTBE" */ +570, /* "setct-AuthReqTBE" */ +534, /* "setct-AuthReqTBS" */ +527, /* "setct-AuthResBaggage" */ +571, /* "setct-AuthResTBE" */ +572, /* "setct-AuthResTBEX" */ +535, /* "setct-AuthResTBS" */ +536, /* "setct-AuthResTBSX" */ +528, /* "setct-AuthRevReqBaggage" */ +577, /* "setct-AuthRevReqTBE" */ +541, /* "setct-AuthRevReqTBS" */ +529, /* "setct-AuthRevResBaggage" */ +542, /* "setct-AuthRevResData" */ +578, /* "setct-AuthRevResTBE" */ +579, /* "setct-AuthRevResTBEB" */ +543, /* "setct-AuthRevResTBS" */ +573, /* "setct-AuthTokenTBE" */ +537, /* "setct-AuthTokenTBS" */ +600, /* "setct-BCIDistributionTBS" */ +558, /* "setct-BatchAdminReqData" */ +592, /* "setct-BatchAdminReqTBE" */ +559, /* "setct-BatchAdminResData" */ +593, /* "setct-BatchAdminResTBE" */ +599, /* "setct-CRLNotificationResTBS" */ +598, /* "setct-CRLNotificationTBS" */ +580, /* "setct-CapReqTBE" */ +581, /* "setct-CapReqTBEX" */ +544, /* "setct-CapReqTBS" */ +545, /* "setct-CapReqTBSX" */ +546, /* "setct-CapResData" */ +582, /* "setct-CapResTBE" */ +583, /* "setct-CapRevReqTBE" */ +584, /* "setct-CapRevReqTBEX" */ +547, /* "setct-CapRevReqTBS" */ +548, /* "setct-CapRevReqTBSX" */ +549, /* "setct-CapRevResData" */ +585, /* "setct-CapRevResTBE" */ +538, /* "setct-CapTokenData" */ +530, /* "setct-CapTokenSeq" */ +574, /* "setct-CapTokenTBE" */ +575, /* "setct-CapTokenTBEX" */ +539, /* "setct-CapTokenTBS" */ +560, /* "setct-CardCInitResTBS" */ +566, /* "setct-CertInqReqTBS" */ +563, /* "setct-CertReqData" */ +595, /* "setct-CertReqTBE" */ +596, /* "setct-CertReqTBEX" */ +564, /* "setct-CertReqTBS" */ +565, /* "setct-CertResData" */ +597, /* "setct-CertResTBE" */ +586, /* "setct-CredReqTBE" */ +587, /* "setct-CredReqTBEX" */ +550, /* "setct-CredReqTBS" */ +551, /* "setct-CredReqTBSX" */ +552, /* "setct-CredResData" */ +588, /* "setct-CredResTBE" */ +589, /* "setct-CredRevReqTBE" */ +590, /* "setct-CredRevReqTBEX" */ +553, /* "setct-CredRevReqTBS" */ +554, /* "setct-CredRevReqTBSX" */ +555, /* "setct-CredRevResData" */ +591, /* "setct-CredRevResTBE" */ +567, /* "setct-ErrorTBS" */ +526, /* "setct-HODInput" */ +561, /* "setct-MeAqCInitResTBS" */ +522, /* "setct-OIData" */ +519, /* "setct-PANData" */ +521, /* "setct-PANOnly" */ +520, /* "setct-PANToken" */ +556, /* "setct-PCertReqData" */ +557, /* "setct-PCertResTBS" */ +523, /* "setct-PI" */ +532, /* "setct-PI-TBS" */ +524, /* "setct-PIData" */ +525, /* "setct-PIDataUnsigned" */ +568, /* "setct-PIDualSignedTBE" */ +569, /* "setct-PIUnsignedTBE" */ +531, /* "setct-PInitResData" */ +533, /* "setct-PResData" */ +594, /* "setct-RegFormReqTBE" */ +562, /* "setct-RegFormResTBS" */ +606, /* "setext-cv" */ +601, /* "setext-genCrypt" */ +602, /* "setext-miAuth" */ +604, /* "setext-pinAny" */ +603, /* "setext-pinSecure" */ +605, /* "setext-track2" */ +52, /* "signingTime" */ +454, /* "simpleSecurityObject" */ +496, /* "singleLevelQuality" */ +387, /* "snmpv2" */ +660, /* "street" */ +85, /* "subjectAltName" */ +769, /* "subjectDirectoryAttributes" */ +398, /* "subjectInfoAccess" */ +82, /* "subjectKeyIdentifier" */ +498, /* "subtreeMaximumQuality" */ +497, /* "subtreeMinimumQuality" */ +890, /* "supportedAlgorithms" */ +874, /* "supportedApplicationContext" */ +402, /* "targetInformation" */ +864, /* "telephoneNumber" */ +866, /* "teletexTerminalIdentifier" */ +865, /* "telexNumber" */ +459, /* "textEncodedORAddress" */ +293, /* "textNotice" */ +133, /* "timeStamping" */ +106, /* "title" */ +682, /* "tpBasis" */ +375, /* "trustRoot" */ +436, /* "ucl" */ +888, /* "uniqueMember" */ +55, /* "unstructuredAddress" */ +49, /* "unstructuredName" */ +880, /* "userCertificate" */ +465, /* "userClass" */ +879, /* "userPassword" */ +373, /* "valid" */ +678, /* "wap" */ +679, /* "wap-wsg" */ +735, /* "wap-wsg-idm-ecid-wtls1" */ +743, /* "wap-wsg-idm-ecid-wtls10" */ +744, /* "wap-wsg-idm-ecid-wtls11" */ +745, /* "wap-wsg-idm-ecid-wtls12" */ +736, /* "wap-wsg-idm-ecid-wtls3" */ +737, /* "wap-wsg-idm-ecid-wtls4" */ +738, /* "wap-wsg-idm-ecid-wtls5" */ +739, /* "wap-wsg-idm-ecid-wtls6" */ +740, /* "wap-wsg-idm-ecid-wtls7" */ +741, /* "wap-wsg-idm-ecid-wtls8" */ +742, /* "wap-wsg-idm-ecid-wtls9" */ +804, /* "whirlpool" */ +868, /* "x121Address" */ +503, /* "x500UniqueIdentifier" */ +158, /* "x509Certificate" */ +160, /* "x509Crl" */ +}; + +static const unsigned int ln_objs[NUM_LN]={ +363, /* "AD Time Stamping" */ +405, /* "ANSI X9.62" */ +368, /* "Acceptable OCSP Responses" */ +910, /* "Any Extended Key Usage" */ +664, /* "Any language" */ +177, /* "Authority Information Access" */ +365, /* "Basic OCSP Response" */ +285, /* "Biometric Info" */ +179, /* "CA Issuers" */ +785, /* "CA Repository" */ +131, /* "Code Signing" */ +783, /* "Diffie-Hellman based MAC" */ +382, /* "Directory" */ +392, /* "Domain" */ +132, /* "E-mail Protection" */ +389, /* "Enterprises" */ +384, /* "Experimental" */ +372, /* "Extended OCSP Status" */ +172, /* "Extension Request" */ +813, /* "GOST 28147-89" */ +849, /* "GOST 28147-89 Cryptocom ParamSet" */ +815, /* "GOST 28147-89 MAC" */ +851, /* "GOST 34.10-2001 Cryptocom" */ +850, /* "GOST 34.10-94 Cryptocom" */ +811, /* "GOST R 34.10-2001" */ +817, /* "GOST R 34.10-2001 DH" */ +812, /* "GOST R 34.10-94" */ +818, /* "GOST R 34.10-94 DH" */ +809, /* "GOST R 34.11-94" */ +816, /* "GOST R 34.11-94 PRF" */ +807, /* "GOST R 34.11-94 with GOST R 34.10-2001" */ +853, /* "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" */ +808, /* "GOST R 34.11-94 with GOST R 34.10-94" */ +852, /* "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" */ +854, /* "GOST R 3410-2001 Parameter Set Cryptocom" */ +810, /* "HMAC GOST 34.11-94" */ +432, /* "Hold Instruction Call Issuer" */ +430, /* "Hold Instruction Code" */ +431, /* "Hold Instruction None" */ +433, /* "Hold Instruction Reject" */ +634, /* "ICC or token signature" */ +294, /* "IPSec End System" */ +295, /* "IPSec Tunnel" */ +296, /* "IPSec User" */ +182, /* "ISO Member Body" */ +183, /* "ISO US Member Body" */ +667, /* "Independent" */ +665, /* "Inherit all" */ +647, /* "International Organizations" */ +142, /* "Invalidity Date" */ +504, /* "MIME MHS" */ +388, /* "Mail" */ +383, /* "Management" */ +417, /* "Microsoft CSP Name" */ +135, /* "Microsoft Commercial Code Signing" */ +138, /* "Microsoft Encrypted File System" */ +171, /* "Microsoft Extension Request" */ +134, /* "Microsoft Individual Code Signing" */ +856, /* "Microsoft Local Key set" */ +137, /* "Microsoft Server Gated Crypto" */ +648, /* "Microsoft Smartcardlogin" */ +136, /* "Microsoft Trust List Signing" */ +649, /* "Microsoft Universal Principal Name" */ +393, /* "NULL" */ +404, /* "NULL" */ +72, /* "Netscape Base Url" */ +76, /* "Netscape CA Policy Url" */ +74, /* "Netscape CA Revocation Url" */ +71, /* "Netscape Cert Type" */ +58, /* "Netscape Certificate Extension" */ +79, /* "Netscape Certificate Sequence" */ +78, /* "Netscape Comment" */ +57, /* "Netscape Communications Corp." */ +59, /* "Netscape Data Type" */ +75, /* "Netscape Renewal Url" */ +73, /* "Netscape Revocation Url" */ +77, /* "Netscape SSL Server Name" */ +139, /* "Netscape Server Gated Crypto" */ +178, /* "OCSP" */ +370, /* "OCSP Archive Cutoff" */ +367, /* "OCSP CRL ID" */ +369, /* "OCSP No Check" */ +366, /* "OCSP Nonce" */ +371, /* "OCSP Service Locator" */ +180, /* "OCSP Signing" */ +161, /* "PBES2" */ +69, /* "PBKDF2" */ +162, /* "PBMAC1" */ +127, /* "PKIX" */ +858, /* "Permanent Identifier" */ +164, /* "Policy Qualifier CPS" */ +165, /* "Policy Qualifier User Notice" */ +385, /* "Private" */ +663, /* "Proxy Certificate Information" */ + 1, /* "RSA Data Security, Inc." */ + 2, /* "RSA Data Security, Inc. PKCS" */ +188, /* "S/MIME" */ +167, /* "S/MIME Capabilities" */ +387, /* "SNMPv2" */ +512, /* "Secure Electronic Transactions" */ +386, /* "Security" */ +394, /* "Selected Attribute Types" */ +143, /* "Strong Extranet ID" */ +398, /* "Subject Information Access" */ +130, /* "TLS Web Client Authentication" */ +129, /* "TLS Web Server Authentication" */ +133, /* "Time Stamping" */ +375, /* "Trust Root" */ +12, /* "X509" */ +402, /* "X509v3 AC Targeting" */ +746, /* "X509v3 Any Policy" */ +90, /* "X509v3 Authority Key Identifier" */ +87, /* "X509v3 Basic Constraints" */ +103, /* "X509v3 CRL Distribution Points" */ +88, /* "X509v3 CRL Number" */ +141, /* "X509v3 CRL Reason Code" */ +771, /* "X509v3 Certificate Issuer" */ +89, /* "X509v3 Certificate Policies" */ +140, /* "X509v3 Delta CRL Indicator" */ +126, /* "X509v3 Extended Key Usage" */ +857, /* "X509v3 Freshest CRL" */ +748, /* "X509v3 Inhibit Any Policy" */ +86, /* "X509v3 Issuer Alternative Name" */ +770, /* "X509v3 Issuing Distrubution Point" */ +83, /* "X509v3 Key Usage" */ +666, /* "X509v3 Name Constraints" */ +403, /* "X509v3 No Revocation Available" */ +401, /* "X509v3 Policy Constraints" */ +747, /* "X509v3 Policy Mappings" */ +84, /* "X509v3 Private Key Usage Period" */ +85, /* "X509v3 Subject Alternative Name" */ +769, /* "X509v3 Subject Directory Attributes" */ +82, /* "X509v3 Subject Key Identifier" */ +184, /* "X9.57" */ +185, /* "X9.57 CM ?" */ +478, /* "aRecord" */ +289, /* "aaControls" */ +287, /* "ac-auditEntity" */ +397, /* "ac-proxying" */ +288, /* "ac-targeting" */ +446, /* "account" */ +364, /* "ad dvcs" */ +606, /* "additional verification" */ +419, /* "aes-128-cbc" */ +916, /* "aes-128-cbc-hmac-sha1" */ +896, /* "aes-128-ccm" */ +421, /* "aes-128-cfb" */ +650, /* "aes-128-cfb1" */ +653, /* "aes-128-cfb8" */ +904, /* "aes-128-ctr" */ +418, /* "aes-128-ecb" */ +895, /* "aes-128-gcm" */ +420, /* "aes-128-ofb" */ +913, /* "aes-128-xts" */ +423, /* "aes-192-cbc" */ +917, /* "aes-192-cbc-hmac-sha1" */ +899, /* "aes-192-ccm" */ +425, /* "aes-192-cfb" */ +651, /* "aes-192-cfb1" */ +654, /* "aes-192-cfb8" */ +905, /* "aes-192-ctr" */ +422, /* "aes-192-ecb" */ +898, /* "aes-192-gcm" */ +424, /* "aes-192-ofb" */ +427, /* "aes-256-cbc" */ +918, /* "aes-256-cbc-hmac-sha1" */ +902, /* "aes-256-ccm" */ +429, /* "aes-256-cfb" */ +652, /* "aes-256-cfb1" */ +655, /* "aes-256-cfb8" */ +906, /* "aes-256-ctr" */ +426, /* "aes-256-ecb" */ +901, /* "aes-256-gcm" */ +428, /* "aes-256-ofb" */ +914, /* "aes-256-xts" */ +376, /* "algorithm" */ +484, /* "associatedDomain" */ +485, /* "associatedName" */ +501, /* "audio" */ +882, /* "authorityRevocationList" */ +91, /* "bf-cbc" */ +93, /* "bf-cfb" */ +92, /* "bf-ecb" */ +94, /* "bf-ofb" */ +494, /* "buildingName" */ +860, /* "businessCategory" */ +691, /* "c2onb191v4" */ +692, /* "c2onb191v5" */ +697, /* "c2onb239v4" */ +698, /* "c2onb239v5" */ +684, /* "c2pnb163v1" */ +685, /* "c2pnb163v2" */ +686, /* "c2pnb163v3" */ +687, /* "c2pnb176v1" */ +693, /* "c2pnb208w1" */ +699, /* "c2pnb272w1" */ +700, /* "c2pnb304w1" */ +702, /* "c2pnb368w1" */ +688, /* "c2tnb191v1" */ +689, /* "c2tnb191v2" */ +690, /* "c2tnb191v3" */ +694, /* "c2tnb239v1" */ +695, /* "c2tnb239v2" */ +696, /* "c2tnb239v3" */ +701, /* "c2tnb359v1" */ +703, /* "c2tnb431r1" */ +881, /* "cACertificate" */ +483, /* "cNAMERecord" */ +751, /* "camellia-128-cbc" */ +757, /* "camellia-128-cfb" */ +760, /* "camellia-128-cfb1" */ +763, /* "camellia-128-cfb8" */ +754, /* "camellia-128-ecb" */ +766, /* "camellia-128-ofb" */ +752, /* "camellia-192-cbc" */ +758, /* "camellia-192-cfb" */ +761, /* "camellia-192-cfb1" */ +764, /* "camellia-192-cfb8" */ +755, /* "camellia-192-ecb" */ +767, /* "camellia-192-ofb" */ +753, /* "camellia-256-cbc" */ +759, /* "camellia-256-cfb" */ +762, /* "camellia-256-cfb1" */ +765, /* "camellia-256-cfb8" */ +756, /* "camellia-256-ecb" */ +768, /* "camellia-256-ofb" */ +443, /* "caseIgnoreIA5StringSyntax" */ +108, /* "cast5-cbc" */ +110, /* "cast5-cfb" */ +109, /* "cast5-ecb" */ +111, /* "cast5-ofb" */ +152, /* "certBag" */ +677, /* "certicom-arc" */ +517, /* "certificate extensions" */ +883, /* "certificateRevocationList" */ +54, /* "challengePassword" */ +407, /* "characteristic-two-field" */ +395, /* "clearance" */ +633, /* "cleartext track 2" */ +894, /* "cmac" */ +13, /* "commonName" */ +513, /* "content types" */ +50, /* "contentType" */ +53, /* "countersignature" */ +14, /* "countryName" */ +153, /* "crlBag" */ +884, /* "crossCertificatePair" */ +806, /* "cryptocom" */ +805, /* "cryptopro" */ +500, /* "dITRedirect" */ +451, /* "dNSDomain" */ +495, /* "dSAQuality" */ +434, /* "data" */ +390, /* "dcObject" */ +891, /* "deltaRevocationList" */ +31, /* "des-cbc" */ +643, /* "des-cdmf" */ +30, /* "des-cfb" */ +656, /* "des-cfb1" */ +657, /* "des-cfb8" */ +29, /* "des-ecb" */ +32, /* "des-ede" */ +43, /* "des-ede-cbc" */ +60, /* "des-ede-cfb" */ +62, /* "des-ede-ofb" */ +33, /* "des-ede3" */ +44, /* "des-ede3-cbc" */ +61, /* "des-ede3-cfb" */ +658, /* "des-ede3-cfb1" */ +659, /* "des-ede3-cfb8" */ +63, /* "des-ede3-ofb" */ +45, /* "des-ofb" */ +107, /* "description" */ +871, /* "destinationIndicator" */ +80, /* "desx-cbc" */ +28, /* "dhKeyAgreement" */ +11, /* "directory services (X.500)" */ +378, /* "directory services - algorithms" */ +887, /* "distinguishedName" */ +892, /* "dmdName" */ +174, /* "dnQualifier" */ +447, /* "document" */ +471, /* "documentAuthor" */ +468, /* "documentIdentifier" */ +472, /* "documentLocation" */ +502, /* "documentPublisher" */ +449, /* "documentSeries" */ +469, /* "documentTitle" */ +470, /* "documentVersion" */ +380, /* "dod" */ +391, /* "domainComponent" */ +452, /* "domainRelatedObject" */ +116, /* "dsaEncryption" */ +67, /* "dsaEncryption-old" */ +66, /* "dsaWithSHA" */ +113, /* "dsaWithSHA1" */ +70, /* "dsaWithSHA1-old" */ +802, /* "dsa_with_SHA224" */ +803, /* "dsa_with_SHA256" */ +297, /* "dvcs" */ +791, /* "ecdsa-with-Recommended" */ +416, /* "ecdsa-with-SHA1" */ +793, /* "ecdsa-with-SHA224" */ +794, /* "ecdsa-with-SHA256" */ +795, /* "ecdsa-with-SHA384" */ +796, /* "ecdsa-with-SHA512" */ +792, /* "ecdsa-with-Specified" */ +48, /* "emailAddress" */ +632, /* "encrypted track 2" */ +885, /* "enhancedSearchGuide" */ +56, /* "extendedCertificateAttributes" */ +867, /* "facsimileTelephoneNumber" */ +462, /* "favouriteDrink" */ +453, /* "friendlyCountry" */ +490, /* "friendlyCountryName" */ +156, /* "friendlyName" */ +631, /* "generate cryptogram" */ +509, /* "generationQualifier" */ +601, /* "generic cryptogram" */ +99, /* "givenName" */ +814, /* "gost89-cnt" */ +855, /* "hmac" */ +780, /* "hmac-md5" */ +781, /* "hmac-sha1" */ +797, /* "hmacWithMD5" */ +163, /* "hmacWithSHA1" */ +798, /* "hmacWithSHA224" */ +799, /* "hmacWithSHA256" */ +800, /* "hmacWithSHA384" */ +801, /* "hmacWithSHA512" */ +486, /* "homePostalAddress" */ +473, /* "homeTelephoneNumber" */ +466, /* "host" */ +889, /* "houseIdentifier" */ +442, /* "iA5StringSyntax" */ +381, /* "iana" */ +824, /* "id-Gost28147-89-CryptoPro-A-ParamSet" */ +825, /* "id-Gost28147-89-CryptoPro-B-ParamSet" */ +826, /* "id-Gost28147-89-CryptoPro-C-ParamSet" */ +827, /* "id-Gost28147-89-CryptoPro-D-ParamSet" */ +819, /* "id-Gost28147-89-CryptoPro-KeyMeshing" */ +829, /* "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" */ +828, /* "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" */ +830, /* "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" */ +820, /* "id-Gost28147-89-None-KeyMeshing" */ +823, /* "id-Gost28147-89-TestParamSet" */ +840, /* "id-GostR3410-2001-CryptoPro-A-ParamSet" */ +841, /* "id-GostR3410-2001-CryptoPro-B-ParamSet" */ +842, /* "id-GostR3410-2001-CryptoPro-C-ParamSet" */ +843, /* "id-GostR3410-2001-CryptoPro-XchA-ParamSet" */ +844, /* "id-GostR3410-2001-CryptoPro-XchB-ParamSet" */ +839, /* "id-GostR3410-2001-TestParamSet" */ +832, /* "id-GostR3410-94-CryptoPro-A-ParamSet" */ +833, /* "id-GostR3410-94-CryptoPro-B-ParamSet" */ +834, /* "id-GostR3410-94-CryptoPro-C-ParamSet" */ +835, /* "id-GostR3410-94-CryptoPro-D-ParamSet" */ +836, /* "id-GostR3410-94-CryptoPro-XchA-ParamSet" */ +837, /* "id-GostR3410-94-CryptoPro-XchB-ParamSet" */ +838, /* "id-GostR3410-94-CryptoPro-XchC-ParamSet" */ +831, /* "id-GostR3410-94-TestParamSet" */ +845, /* "id-GostR3410-94-a" */ +846, /* "id-GostR3410-94-aBis" */ +847, /* "id-GostR3410-94-b" */ +848, /* "id-GostR3410-94-bBis" */ +822, /* "id-GostR3411-94-CryptoProParamSet" */ +821, /* "id-GostR3411-94-TestParamSet" */ +266, /* "id-aca" */ +355, /* "id-aca-accessIdentity" */ +354, /* "id-aca-authenticationInfo" */ +356, /* "id-aca-chargingIdentity" */ +399, /* "id-aca-encAttrs" */ +357, /* "id-aca-group" */ +358, /* "id-aca-role" */ +176, /* "id-ad" */ +788, /* "id-aes128-wrap" */ +897, /* "id-aes128-wrap-pad" */ +789, /* "id-aes192-wrap" */ +900, /* "id-aes192-wrap-pad" */ +790, /* "id-aes256-wrap" */ +903, /* "id-aes256-wrap-pad" */ +262, /* "id-alg" */ +893, /* "id-alg-PWRI-KEK" */ +323, /* "id-alg-des40" */ +326, /* "id-alg-dh-pop" */ +325, /* "id-alg-dh-sig-hmac-sha1" */ +324, /* "id-alg-noSignature" */ +907, /* "id-camellia128-wrap" */ +908, /* "id-camellia192-wrap" */ +909, /* "id-camellia256-wrap" */ +268, /* "id-cct" */ +361, /* "id-cct-PKIData" */ +362, /* "id-cct-PKIResponse" */ +360, /* "id-cct-crs" */ +81, /* "id-ce" */ +680, /* "id-characteristic-two-basis" */ +263, /* "id-cmc" */ +334, /* "id-cmc-addExtensions" */ +346, /* "id-cmc-confirmCertAcceptance" */ +330, /* "id-cmc-dataReturn" */ +336, /* "id-cmc-decryptedPOP" */ +335, /* "id-cmc-encryptedPOP" */ +339, /* "id-cmc-getCRL" */ +338, /* "id-cmc-getCert" */ +328, /* "id-cmc-identification" */ +329, /* "id-cmc-identityProof" */ +337, /* "id-cmc-lraPOPWitness" */ +344, /* "id-cmc-popLinkRandom" */ +345, /* "id-cmc-popLinkWitness" */ +343, /* "id-cmc-queryPending" */ +333, /* "id-cmc-recipientNonce" */ +341, /* "id-cmc-regInfo" */ +342, /* "id-cmc-responseInfo" */ +340, /* "id-cmc-revokeRequest" */ +332, /* "id-cmc-senderNonce" */ +327, /* "id-cmc-statusInfo" */ +331, /* "id-cmc-transactionId" */ +787, /* "id-ct-asciiTextWithCRLF" */ +408, /* "id-ecPublicKey" */ +508, /* "id-hex-multipart-message" */ +507, /* "id-hex-partial-message" */ +260, /* "id-it" */ +302, /* "id-it-caKeyUpdateInfo" */ +298, /* "id-it-caProtEncCert" */ +311, /* "id-it-confirmWaitTime" */ +303, /* "id-it-currentCRL" */ +300, /* "id-it-encKeyPairTypes" */ +310, /* "id-it-implicitConfirm" */ +308, /* "id-it-keyPairParamRep" */ +307, /* "id-it-keyPairParamReq" */ +312, /* "id-it-origPKIMessage" */ +301, /* "id-it-preferredSymmAlg" */ +309, /* "id-it-revPassphrase" */ +299, /* "id-it-signKeyPairTypes" */ +305, /* "id-it-subscriptionRequest" */ +306, /* "id-it-subscriptionResponse" */ +784, /* "id-it-suppLangTags" */ +304, /* "id-it-unsupportedOIDs" */ +128, /* "id-kp" */ +280, /* "id-mod-attribute-cert" */ +274, /* "id-mod-cmc" */ +277, /* "id-mod-cmp" */ +284, /* "id-mod-cmp2000" */ +273, /* "id-mod-crmf" */ +283, /* "id-mod-dvcs" */ +275, /* "id-mod-kea-profile-88" */ +276, /* "id-mod-kea-profile-93" */ +282, /* "id-mod-ocsp" */ +278, /* "id-mod-qualified-cert-88" */ +279, /* "id-mod-qualified-cert-93" */ +281, /* "id-mod-timestamp-protocol" */ +264, /* "id-on" */ +347, /* "id-on-personalData" */ +265, /* "id-pda" */ +352, /* "id-pda-countryOfCitizenship" */ +353, /* "id-pda-countryOfResidence" */ +348, /* "id-pda-dateOfBirth" */ +351, /* "id-pda-gender" */ +349, /* "id-pda-placeOfBirth" */ +175, /* "id-pe" */ +261, /* "id-pkip" */ +258, /* "id-pkix-mod" */ +269, /* "id-pkix1-explicit-88" */ +271, /* "id-pkix1-explicit-93" */ +270, /* "id-pkix1-implicit-88" */ +272, /* "id-pkix1-implicit-93" */ +662, /* "id-ppl" */ +267, /* "id-qcs" */ +359, /* "id-qcs-pkixQCSyntax-v1" */ +259, /* "id-qt" */ +313, /* "id-regCtrl" */ +316, /* "id-regCtrl-authenticator" */ +319, /* "id-regCtrl-oldCertID" */ +318, /* "id-regCtrl-pkiArchiveOptions" */ +317, /* "id-regCtrl-pkiPublicationInfo" */ +320, /* "id-regCtrl-protocolEncrKey" */ +315, /* "id-regCtrl-regToken" */ +314, /* "id-regInfo" */ +322, /* "id-regInfo-certReq" */ +321, /* "id-regInfo-utf8Pairs" */ +191, /* "id-smime-aa" */ +215, /* "id-smime-aa-contentHint" */ +218, /* "id-smime-aa-contentIdentifier" */ +221, /* "id-smime-aa-contentReference" */ +240, /* "id-smime-aa-dvcs-dvc" */ +217, /* "id-smime-aa-encapContentType" */ +222, /* "id-smime-aa-encrypKeyPref" */ +220, /* "id-smime-aa-equivalentLabels" */ +232, /* "id-smime-aa-ets-CertificateRefs" */ +233, /* "id-smime-aa-ets-RevocationRefs" */ +238, /* "id-smime-aa-ets-archiveTimeStamp" */ +237, /* "id-smime-aa-ets-certCRLTimestamp" */ +234, /* "id-smime-aa-ets-certValues" */ +227, /* "id-smime-aa-ets-commitmentType" */ +231, /* "id-smime-aa-ets-contentTimestamp" */ +236, /* "id-smime-aa-ets-escTimeStamp" */ +230, /* "id-smime-aa-ets-otherSigCert" */ +235, /* "id-smime-aa-ets-revocationValues" */ +226, /* "id-smime-aa-ets-sigPolicyId" */ +229, /* "id-smime-aa-ets-signerAttr" */ +228, /* "id-smime-aa-ets-signerLocation" */ +219, /* "id-smime-aa-macValue" */ +214, /* "id-smime-aa-mlExpandHistory" */ +216, /* "id-smime-aa-msgSigDigest" */ +212, /* "id-smime-aa-receiptRequest" */ +213, /* "id-smime-aa-securityLabel" */ +239, /* "id-smime-aa-signatureType" */ +223, /* "id-smime-aa-signingCertificate" */ +224, /* "id-smime-aa-smimeEncryptCerts" */ +225, /* "id-smime-aa-timeStampToken" */ +192, /* "id-smime-alg" */ +243, /* "id-smime-alg-3DESwrap" */ +246, /* "id-smime-alg-CMS3DESwrap" */ +247, /* "id-smime-alg-CMSRC2wrap" */ +245, /* "id-smime-alg-ESDH" */ +241, /* "id-smime-alg-ESDHwith3DES" */ +242, /* "id-smime-alg-ESDHwithRC2" */ +244, /* "id-smime-alg-RC2wrap" */ +193, /* "id-smime-cd" */ +248, /* "id-smime-cd-ldap" */ +190, /* "id-smime-ct" */ +210, /* "id-smime-ct-DVCSRequestData" */ +211, /* "id-smime-ct-DVCSResponseData" */ +208, /* "id-smime-ct-TDTInfo" */ +207, /* "id-smime-ct-TSTInfo" */ +205, /* "id-smime-ct-authData" */ +786, /* "id-smime-ct-compressedData" */ +209, /* "id-smime-ct-contentInfo" */ +206, /* "id-smime-ct-publishCert" */ +204, /* "id-smime-ct-receipt" */ +195, /* "id-smime-cti" */ +255, /* "id-smime-cti-ets-proofOfApproval" */ +256, /* "id-smime-cti-ets-proofOfCreation" */ +253, /* "id-smime-cti-ets-proofOfDelivery" */ +251, /* "id-smime-cti-ets-proofOfOrigin" */ +252, /* "id-smime-cti-ets-proofOfReceipt" */ +254, /* "id-smime-cti-ets-proofOfSender" */ +189, /* "id-smime-mod" */ +196, /* "id-smime-mod-cms" */ +197, /* "id-smime-mod-ess" */ +202, /* "id-smime-mod-ets-eSigPolicy-88" */ +203, /* "id-smime-mod-ets-eSigPolicy-97" */ +200, /* "id-smime-mod-ets-eSignature-88" */ +201, /* "id-smime-mod-ets-eSignature-97" */ +199, /* "id-smime-mod-msg-v3" */ +198, /* "id-smime-mod-oid" */ +194, /* "id-smime-spq" */ +250, /* "id-smime-spq-ets-sqt-unotice" */ +249, /* "id-smime-spq-ets-sqt-uri" */ +34, /* "idea-cbc" */ +35, /* "idea-cfb" */ +36, /* "idea-ecb" */ +46, /* "idea-ofb" */ +676, /* "identified-organization" */ +461, /* "info" */ +101, /* "initials" */ +869, /* "internationaliSDNNumber" */ +749, /* "ipsec3" */ +750, /* "ipsec4" */ +181, /* "iso" */ +623, /* "issuer capabilities" */ +645, /* "itu-t" */ +492, /* "janetMailbox" */ +646, /* "joint-iso-itu-t" */ +150, /* "keyBag" */ +773, /* "kisa" */ +477, /* "lastModifiedBy" */ +476, /* "lastModifiedTime" */ +157, /* "localKeyID" */ +15, /* "localityName" */ +480, /* "mXRecord" */ +493, /* "mailPreferenceOption" */ +467, /* "manager" */ + 3, /* "md2" */ + 7, /* "md2WithRSAEncryption" */ +257, /* "md4" */ +396, /* "md4WithRSAEncryption" */ + 4, /* "md5" */ +114, /* "md5-sha1" */ +104, /* "md5WithRSA" */ + 8, /* "md5WithRSAEncryption" */ +95, /* "mdc2" */ +96, /* "mdc2WithRSA" */ +875, /* "member" */ +602, /* "merchant initiated auth" */ +514, /* "message extensions" */ +51, /* "messageDigest" */ +911, /* "mgf1" */ +506, /* "mime-mhs-bodies" */ +505, /* "mime-mhs-headings" */ +488, /* "mobileTelephoneNumber" */ +481, /* "nSRecord" */ +173, /* "name" */ +681, /* "onBasis" */ +379, /* "org" */ +17, /* "organizationName" */ +491, /* "organizationalStatus" */ +18, /* "organizationalUnitName" */ +475, /* "otherMailbox" */ +876, /* "owner" */ +489, /* "pagerTelephoneNumber" */ +782, /* "password based MAC" */ +374, /* "path" */ +621, /* "payment gateway capabilities" */ + 9, /* "pbeWithMD2AndDES-CBC" */ +168, /* "pbeWithMD2AndRC2-CBC" */ +112, /* "pbeWithMD5AndCast5CBC" */ +10, /* "pbeWithMD5AndDES-CBC" */ +169, /* "pbeWithMD5AndRC2-CBC" */ +148, /* "pbeWithSHA1And128BitRC2-CBC" */ +144, /* "pbeWithSHA1And128BitRC4" */ +147, /* "pbeWithSHA1And2-KeyTripleDES-CBC" */ +146, /* "pbeWithSHA1And3-KeyTripleDES-CBC" */ +149, /* "pbeWithSHA1And40BitRC2-CBC" */ +145, /* "pbeWithSHA1And40BitRC4" */ +170, /* "pbeWithSHA1AndDES-CBC" */ +68, /* "pbeWithSHA1AndRC2-CBC" */ +499, /* "personalSignature" */ +487, /* "personalTitle" */ +464, /* "photo" */ +863, /* "physicalDeliveryOfficeName" */ +437, /* "pilot" */ +439, /* "pilotAttributeSyntax" */ +438, /* "pilotAttributeType" */ +479, /* "pilotAttributeType27" */ +456, /* "pilotDSA" */ +441, /* "pilotGroups" */ +444, /* "pilotObject" */ +440, /* "pilotObjectClass" */ +455, /* "pilotOrganization" */ +445, /* "pilotPerson" */ +186, /* "pkcs1" */ +27, /* "pkcs3" */ +187, /* "pkcs5" */ +20, /* "pkcs7" */ +21, /* "pkcs7-data" */ +25, /* "pkcs7-digestData" */ +26, /* "pkcs7-encryptedData" */ +23, /* "pkcs7-envelopedData" */ +24, /* "pkcs7-signedAndEnvelopedData" */ +22, /* "pkcs7-signedData" */ +151, /* "pkcs8ShroudedKeyBag" */ +47, /* "pkcs9" */ +862, /* "postOfficeBox" */ +861, /* "postalAddress" */ +661, /* "postalCode" */ +683, /* "ppBasis" */ +872, /* "preferredDeliveryMethod" */ +873, /* "presentationAddress" */ +406, /* "prime-field" */ +409, /* "prime192v1" */ +410, /* "prime192v2" */ +411, /* "prime192v3" */ +412, /* "prime239v1" */ +413, /* "prime239v2" */ +414, /* "prime239v3" */ +415, /* "prime256v1" */ +886, /* "protocolInformation" */ +510, /* "pseudonym" */ +435, /* "pss" */ +286, /* "qcStatements" */ +457, /* "qualityLabelledData" */ +450, /* "rFC822localPart" */ +98, /* "rc2-40-cbc" */ +166, /* "rc2-64-cbc" */ +37, /* "rc2-cbc" */ +39, /* "rc2-cfb" */ +38, /* "rc2-ecb" */ +40, /* "rc2-ofb" */ + 5, /* "rc4" */ +97, /* "rc4-40" */ +915, /* "rc4-hmac-md5" */ +120, /* "rc5-cbc" */ +122, /* "rc5-cfb" */ +121, /* "rc5-ecb" */ +123, /* "rc5-ofb" */ +870, /* "registeredAddress" */ +460, /* "rfc822Mailbox" */ +117, /* "ripemd160" */ +119, /* "ripemd160WithRSA" */ +400, /* "role" */ +877, /* "roleOccupant" */ +448, /* "room" */ +463, /* "roomNumber" */ +19, /* "rsa" */ + 6, /* "rsaEncryption" */ +644, /* "rsaOAEPEncryptionSET" */ +377, /* "rsaSignature" */ +919, /* "rsaesOaep" */ +912, /* "rsassaPss" */ +124, /* "run length compression" */ +482, /* "sOARecord" */ +155, /* "safeContentsBag" */ +291, /* "sbgp-autonomousSysNum" */ +290, /* "sbgp-ipAddrBlock" */ +292, /* "sbgp-routerIdentifier" */ +159, /* "sdsiCertificate" */ +859, /* "searchGuide" */ +704, /* "secp112r1" */ +705, /* "secp112r2" */ +706, /* "secp128r1" */ +707, /* "secp128r2" */ +708, /* "secp160k1" */ +709, /* "secp160r1" */ +710, /* "secp160r2" */ +711, /* "secp192k1" */ +712, /* "secp224k1" */ +713, /* "secp224r1" */ +714, /* "secp256k1" */ +715, /* "secp384r1" */ +716, /* "secp521r1" */ +154, /* "secretBag" */ +474, /* "secretary" */ +717, /* "sect113r1" */ +718, /* "sect113r2" */ +719, /* "sect131r1" */ +720, /* "sect131r2" */ +721, /* "sect163k1" */ +722, /* "sect163r1" */ +723, /* "sect163r2" */ +724, /* "sect193r1" */ +725, /* "sect193r2" */ +726, /* "sect233k1" */ +727, /* "sect233r1" */ +728, /* "sect239k1" */ +729, /* "sect283k1" */ +730, /* "sect283r1" */ +731, /* "sect409k1" */ +732, /* "sect409r1" */ +733, /* "sect571k1" */ +734, /* "sect571r1" */ +635, /* "secure device signature" */ +878, /* "seeAlso" */ +777, /* "seed-cbc" */ +779, /* "seed-cfb" */ +776, /* "seed-ecb" */ +778, /* "seed-ofb" */ +105, /* "serialNumber" */ +625, /* "set-addPolicy" */ +515, /* "set-attr" */ +518, /* "set-brand" */ +638, /* "set-brand-AmericanExpress" */ +637, /* "set-brand-Diners" */ +636, /* "set-brand-IATA-ATA" */ +639, /* "set-brand-JCB" */ +641, /* "set-brand-MasterCard" */ +642, /* "set-brand-Novus" */ +640, /* "set-brand-Visa" */ +516, /* "set-policy" */ +607, /* "set-policy-root" */ +624, /* "set-rootKeyThumb" */ +620, /* "setAttr-Cert" */ +628, /* "setAttr-IssCap-CVM" */ +630, /* "setAttr-IssCap-Sig" */ +629, /* "setAttr-IssCap-T2" */ +627, /* "setAttr-Token-B0Prime" */ +626, /* "setAttr-Token-EMV" */ +622, /* "setAttr-TokenType" */ +619, /* "setCext-IssuerCapabilities" */ +615, /* "setCext-PGWYcapabilities" */ +616, /* "setCext-TokenIdentifier" */ +618, /* "setCext-TokenType" */ +617, /* "setCext-Track2Data" */ +611, /* "setCext-cCertRequired" */ +609, /* "setCext-certType" */ +608, /* "setCext-hashedRoot" */ +610, /* "setCext-merchData" */ +613, /* "setCext-setExt" */ +614, /* "setCext-setQualf" */ +612, /* "setCext-tunneling" */ +540, /* "setct-AcqCardCodeMsg" */ +576, /* "setct-AcqCardCodeMsgTBE" */ +570, /* "setct-AuthReqTBE" */ +534, /* "setct-AuthReqTBS" */ +527, /* "setct-AuthResBaggage" */ +571, /* "setct-AuthResTBE" */ +572, /* "setct-AuthResTBEX" */ +535, /* "setct-AuthResTBS" */ +536, /* "setct-AuthResTBSX" */ +528, /* "setct-AuthRevReqBaggage" */ +577, /* "setct-AuthRevReqTBE" */ +541, /* "setct-AuthRevReqTBS" */ +529, /* "setct-AuthRevResBaggage" */ +542, /* "setct-AuthRevResData" */ +578, /* "setct-AuthRevResTBE" */ +579, /* "setct-AuthRevResTBEB" */ +543, /* "setct-AuthRevResTBS" */ +573, /* "setct-AuthTokenTBE" */ +537, /* "setct-AuthTokenTBS" */ +600, /* "setct-BCIDistributionTBS" */ +558, /* "setct-BatchAdminReqData" */ +592, /* "setct-BatchAdminReqTBE" */ +559, /* "setct-BatchAdminResData" */ +593, /* "setct-BatchAdminResTBE" */ +599, /* "setct-CRLNotificationResTBS" */ +598, /* "setct-CRLNotificationTBS" */ +580, /* "setct-CapReqTBE" */ +581, /* "setct-CapReqTBEX" */ +544, /* "setct-CapReqTBS" */ +545, /* "setct-CapReqTBSX" */ +546, /* "setct-CapResData" */ +582, /* "setct-CapResTBE" */ +583, /* "setct-CapRevReqTBE" */ +584, /* "setct-CapRevReqTBEX" */ +547, /* "setct-CapRevReqTBS" */ +548, /* "setct-CapRevReqTBSX" */ +549, /* "setct-CapRevResData" */ +585, /* "setct-CapRevResTBE" */ +538, /* "setct-CapTokenData" */ +530, /* "setct-CapTokenSeq" */ +574, /* "setct-CapTokenTBE" */ +575, /* "setct-CapTokenTBEX" */ +539, /* "setct-CapTokenTBS" */ +560, /* "setct-CardCInitResTBS" */ +566, /* "setct-CertInqReqTBS" */ +563, /* "setct-CertReqData" */ +595, /* "setct-CertReqTBE" */ +596, /* "setct-CertReqTBEX" */ +564, /* "setct-CertReqTBS" */ +565, /* "setct-CertResData" */ +597, /* "setct-CertResTBE" */ +586, /* "setct-CredReqTBE" */ +587, /* "setct-CredReqTBEX" */ +550, /* "setct-CredReqTBS" */ +551, /* "setct-CredReqTBSX" */ +552, /* "setct-CredResData" */ +588, /* "setct-CredResTBE" */ +589, /* "setct-CredRevReqTBE" */ +590, /* "setct-CredRevReqTBEX" */ +553, /* "setct-CredRevReqTBS" */ +554, /* "setct-CredRevReqTBSX" */ +555, /* "setct-CredRevResData" */ +591, /* "setct-CredRevResTBE" */ +567, /* "setct-ErrorTBS" */ +526, /* "setct-HODInput" */ +561, /* "setct-MeAqCInitResTBS" */ +522, /* "setct-OIData" */ +519, /* "setct-PANData" */ +521, /* "setct-PANOnly" */ +520, /* "setct-PANToken" */ +556, /* "setct-PCertReqData" */ +557, /* "setct-PCertResTBS" */ +523, /* "setct-PI" */ +532, /* "setct-PI-TBS" */ +524, /* "setct-PIData" */ +525, /* "setct-PIDataUnsigned" */ +568, /* "setct-PIDualSignedTBE" */ +569, /* "setct-PIUnsignedTBE" */ +531, /* "setct-PInitResData" */ +533, /* "setct-PResData" */ +594, /* "setct-RegFormReqTBE" */ +562, /* "setct-RegFormResTBS" */ +604, /* "setext-pinAny" */ +603, /* "setext-pinSecure" */ +605, /* "setext-track2" */ +41, /* "sha" */ +64, /* "sha1" */ +115, /* "sha1WithRSA" */ +65, /* "sha1WithRSAEncryption" */ +675, /* "sha224" */ +671, /* "sha224WithRSAEncryption" */ +672, /* "sha256" */ +668, /* "sha256WithRSAEncryption" */ +673, /* "sha384" */ +669, /* "sha384WithRSAEncryption" */ +674, /* "sha512" */ +670, /* "sha512WithRSAEncryption" */ +42, /* "shaWithRSAEncryption" */ +52, /* "signingTime" */ +454, /* "simpleSecurityObject" */ +496, /* "singleLevelQuality" */ +16, /* "stateOrProvinceName" */ +660, /* "streetAddress" */ +498, /* "subtreeMaximumQuality" */ +497, /* "subtreeMinimumQuality" */ +890, /* "supportedAlgorithms" */ +874, /* "supportedApplicationContext" */ +100, /* "surname" */ +864, /* "telephoneNumber" */ +866, /* "teletexTerminalIdentifier" */ +865, /* "telexNumber" */ +459, /* "textEncodedORAddress" */ +293, /* "textNotice" */ +106, /* "title" */ +682, /* "tpBasis" */ +436, /* "ucl" */ + 0, /* "undefined" */ +888, /* "uniqueMember" */ +55, /* "unstructuredAddress" */ +49, /* "unstructuredName" */ +880, /* "userCertificate" */ +465, /* "userClass" */ +458, /* "userId" */ +879, /* "userPassword" */ +373, /* "valid" */ +678, /* "wap" */ +679, /* "wap-wsg" */ +735, /* "wap-wsg-idm-ecid-wtls1" */ +743, /* "wap-wsg-idm-ecid-wtls10" */ +744, /* "wap-wsg-idm-ecid-wtls11" */ +745, /* "wap-wsg-idm-ecid-wtls12" */ +736, /* "wap-wsg-idm-ecid-wtls3" */ +737, /* "wap-wsg-idm-ecid-wtls4" */ +738, /* "wap-wsg-idm-ecid-wtls5" */ +739, /* "wap-wsg-idm-ecid-wtls6" */ +740, /* "wap-wsg-idm-ecid-wtls7" */ +741, /* "wap-wsg-idm-ecid-wtls8" */ +742, /* "wap-wsg-idm-ecid-wtls9" */ +804, /* "whirlpool" */ +868, /* "x121Address" */ +503, /* "x500UniqueIdentifier" */ +158, /* "x509Certificate" */ +160, /* "x509Crl" */ +125, /* "zlib compression" */ +}; + +static const unsigned int obj_objs[NUM_OBJ]={ + 0, /* OBJ_undef 0 */ +181, /* OBJ_iso 1 */ +393, /* OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t */ +404, /* OBJ_ccitt OBJ_itu_t */ +645, /* OBJ_itu_t 0 */ +646, /* OBJ_joint_iso_itu_t 2 */ +434, /* OBJ_data 0 9 */ +182, /* OBJ_member_body 1 2 */ +379, /* OBJ_org 1 3 */ +676, /* OBJ_identified_organization 1 3 */ +11, /* OBJ_X500 2 5 */ +647, /* OBJ_international_organizations 2 23 */ +380, /* OBJ_dod 1 3 6 */ +12, /* OBJ_X509 2 5 4 */ +378, /* OBJ_X500algorithms 2 5 8 */ +81, /* OBJ_id_ce 2 5 29 */ +512, /* OBJ_id_set 2 23 42 */ +678, /* OBJ_wap 2 23 43 */ +435, /* OBJ_pss 0 9 2342 */ +183, /* OBJ_ISO_US 1 2 840 */ +381, /* OBJ_iana 1 3 6 1 */ +677, /* OBJ_certicom_arc 1 3 132 */ +394, /* OBJ_selected_attribute_types 2 5 1 5 */ +13, /* OBJ_commonName 2 5 4 3 */ +100, /* OBJ_surname 2 5 4 4 */ +105, /* OBJ_serialNumber 2 5 4 5 */ +14, /* OBJ_countryName 2 5 4 6 */ +15, /* OBJ_localityName 2 5 4 7 */ +16, /* OBJ_stateOrProvinceName 2 5 4 8 */ +660, /* OBJ_streetAddress 2 5 4 9 */ +17, /* OBJ_organizationName 2 5 4 10 */ +18, /* OBJ_organizationalUnitName 2 5 4 11 */ +106, /* OBJ_title 2 5 4 12 */ +107, /* OBJ_description 2 5 4 13 */ +859, /* OBJ_searchGuide 2 5 4 14 */ +860, /* OBJ_businessCategory 2 5 4 15 */ +861, /* OBJ_postalAddress 2 5 4 16 */ +661, /* OBJ_postalCode 2 5 4 17 */ +862, /* OBJ_postOfficeBox 2 5 4 18 */ +863, /* OBJ_physicalDeliveryOfficeName 2 5 4 19 */ +864, /* OBJ_telephoneNumber 2 5 4 20 */ +865, /* OBJ_telexNumber 2 5 4 21 */ +866, /* OBJ_teletexTerminalIdentifier 2 5 4 22 */ +867, /* OBJ_facsimileTelephoneNumber 2 5 4 23 */ +868, /* OBJ_x121Address 2 5 4 24 */ +869, /* OBJ_internationaliSDNNumber 2 5 4 25 */ +870, /* OBJ_registeredAddress 2 5 4 26 */ +871, /* OBJ_destinationIndicator 2 5 4 27 */ +872, /* OBJ_preferredDeliveryMethod 2 5 4 28 */ +873, /* OBJ_presentationAddress 2 5 4 29 */ +874, /* OBJ_supportedApplicationContext 2 5 4 30 */ +875, /* OBJ_member 2 5 4 31 */ +876, /* OBJ_owner 2 5 4 32 */ +877, /* OBJ_roleOccupant 2 5 4 33 */ +878, /* OBJ_seeAlso 2 5 4 34 */ +879, /* OBJ_userPassword 2 5 4 35 */ +880, /* OBJ_userCertificate 2 5 4 36 */ +881, /* OBJ_cACertificate 2 5 4 37 */ +882, /* OBJ_authorityRevocationList 2 5 4 38 */ +883, /* OBJ_certificateRevocationList 2 5 4 39 */ +884, /* OBJ_crossCertificatePair 2 5 4 40 */ +173, /* OBJ_name 2 5 4 41 */ +99, /* OBJ_givenName 2 5 4 42 */ +101, /* OBJ_initials 2 5 4 43 */ +509, /* OBJ_generationQualifier 2 5 4 44 */ +503, /* OBJ_x500UniqueIdentifier 2 5 4 45 */ +174, /* OBJ_dnQualifier 2 5 4 46 */ +885, /* OBJ_enhancedSearchGuide 2 5 4 47 */ +886, /* OBJ_protocolInformation 2 5 4 48 */ +887, /* OBJ_distinguishedName 2 5 4 49 */ +888, /* OBJ_uniqueMember 2 5 4 50 */ +889, /* OBJ_houseIdentifier 2 5 4 51 */ +890, /* OBJ_supportedAlgorithms 2 5 4 52 */ +891, /* OBJ_deltaRevocationList 2 5 4 53 */ +892, /* OBJ_dmdName 2 5 4 54 */ +510, /* OBJ_pseudonym 2 5 4 65 */ +400, /* OBJ_role 2 5 4 72 */ +769, /* OBJ_subject_directory_attributes 2 5 29 9 */ +82, /* OBJ_subject_key_identifier 2 5 29 14 */ +83, /* OBJ_key_usage 2 5 29 15 */ +84, /* OBJ_private_key_usage_period 2 5 29 16 */ +85, /* OBJ_subject_alt_name 2 5 29 17 */ +86, /* OBJ_issuer_alt_name 2 5 29 18 */ +87, /* OBJ_basic_constraints 2 5 29 19 */ +88, /* OBJ_crl_number 2 5 29 20 */ +141, /* OBJ_crl_reason 2 5 29 21 */ +430, /* OBJ_hold_instruction_code 2 5 29 23 */ +142, /* OBJ_invalidity_date 2 5 29 24 */ +140, /* OBJ_delta_crl 2 5 29 27 */ +770, /* OBJ_issuing_distribution_point 2 5 29 28 */ +771, /* OBJ_certificate_issuer 2 5 29 29 */ +666, /* OBJ_name_constraints 2 5 29 30 */ +103, /* OBJ_crl_distribution_points 2 5 29 31 */ +89, /* OBJ_certificate_policies 2 5 29 32 */ +747, /* OBJ_policy_mappings 2 5 29 33 */ +90, /* OBJ_authority_key_identifier 2 5 29 35 */ +401, /* OBJ_policy_constraints 2 5 29 36 */ +126, /* OBJ_ext_key_usage 2 5 29 37 */ +857, /* OBJ_freshest_crl 2 5 29 46 */ +748, /* OBJ_inhibit_any_policy 2 5 29 54 */ +402, /* OBJ_target_information 2 5 29 55 */ +403, /* OBJ_no_rev_avail 2 5 29 56 */ +513, /* OBJ_set_ctype 2 23 42 0 */ +514, /* OBJ_set_msgExt 2 23 42 1 */ +515, /* OBJ_set_attr 2 23 42 3 */ +516, /* OBJ_set_policy 2 23 42 5 */ +517, /* OBJ_set_certExt 2 23 42 7 */ +518, /* OBJ_set_brand 2 23 42 8 */ +679, /* OBJ_wap_wsg 2 23 43 1 */ +382, /* OBJ_Directory 1 3 6 1 1 */ +383, /* OBJ_Management 1 3 6 1 2 */ +384, /* OBJ_Experimental 1 3 6 1 3 */ +385, /* OBJ_Private 1 3 6 1 4 */ +386, /* OBJ_Security 1 3 6 1 5 */ +387, /* OBJ_SNMPv2 1 3 6 1 6 */ +388, /* OBJ_Mail 1 3 6 1 7 */ +376, /* OBJ_algorithm 1 3 14 3 2 */ +395, /* OBJ_clearance 2 5 1 5 55 */ +19, /* OBJ_rsa 2 5 8 1 1 */ +96, /* OBJ_mdc2WithRSA 2 5 8 3 100 */ +95, /* OBJ_mdc2 2 5 8 3 101 */ +746, /* OBJ_any_policy 2 5 29 32 0 */ +910, /* OBJ_anyExtendedKeyUsage 2 5 29 37 0 */ +519, /* OBJ_setct_PANData 2 23 42 0 0 */ +520, /* OBJ_setct_PANToken 2 23 42 0 1 */ +521, /* OBJ_setct_PANOnly 2 23 42 0 2 */ +522, /* OBJ_setct_OIData 2 23 42 0 3 */ +523, /* OBJ_setct_PI 2 23 42 0 4 */ +524, /* OBJ_setct_PIData 2 23 42 0 5 */ +525, /* OBJ_setct_PIDataUnsigned 2 23 42 0 6 */ +526, /* OBJ_setct_HODInput 2 23 42 0 7 */ +527, /* OBJ_setct_AuthResBaggage 2 23 42 0 8 */ +528, /* OBJ_setct_AuthRevReqBaggage 2 23 42 0 9 */ +529, /* OBJ_setct_AuthRevResBaggage 2 23 42 0 10 */ +530, /* OBJ_setct_CapTokenSeq 2 23 42 0 11 */ +531, /* OBJ_setct_PInitResData 2 23 42 0 12 */ +532, /* OBJ_setct_PI_TBS 2 23 42 0 13 */ +533, /* OBJ_setct_PResData 2 23 42 0 14 */ +534, /* OBJ_setct_AuthReqTBS 2 23 42 0 16 */ +535, /* OBJ_setct_AuthResTBS 2 23 42 0 17 */ +536, /* OBJ_setct_AuthResTBSX 2 23 42 0 18 */ +537, /* OBJ_setct_AuthTokenTBS 2 23 42 0 19 */ +538, /* OBJ_setct_CapTokenData 2 23 42 0 20 */ +539, /* OBJ_setct_CapTokenTBS 2 23 42 0 21 */ +540, /* OBJ_setct_AcqCardCodeMsg 2 23 42 0 22 */ +541, /* OBJ_setct_AuthRevReqTBS 2 23 42 0 23 */ +542, /* OBJ_setct_AuthRevResData 2 23 42 0 24 */ +543, /* OBJ_setct_AuthRevResTBS 2 23 42 0 25 */ +544, /* OBJ_setct_CapReqTBS 2 23 42 0 26 */ +545, /* OBJ_setct_CapReqTBSX 2 23 42 0 27 */ +546, /* OBJ_setct_CapResData 2 23 42 0 28 */ +547, /* OBJ_setct_CapRevReqTBS 2 23 42 0 29 */ +548, /* OBJ_setct_CapRevReqTBSX 2 23 42 0 30 */ +549, /* OBJ_setct_CapRevResData 2 23 42 0 31 */ +550, /* OBJ_setct_CredReqTBS 2 23 42 0 32 */ +551, /* OBJ_setct_CredReqTBSX 2 23 42 0 33 */ +552, /* OBJ_setct_CredResData 2 23 42 0 34 */ +553, /* OBJ_setct_CredRevReqTBS 2 23 42 0 35 */ +554, /* OBJ_setct_CredRevReqTBSX 2 23 42 0 36 */ +555, /* OBJ_setct_CredRevResData 2 23 42 0 37 */ +556, /* OBJ_setct_PCertReqData 2 23 42 0 38 */ +557, /* OBJ_setct_PCertResTBS 2 23 42 0 39 */ +558, /* OBJ_setct_BatchAdminReqData 2 23 42 0 40 */ +559, /* OBJ_setct_BatchAdminResData 2 23 42 0 41 */ +560, /* OBJ_setct_CardCInitResTBS 2 23 42 0 42 */ +561, /* OBJ_setct_MeAqCInitResTBS 2 23 42 0 43 */ +562, /* OBJ_setct_RegFormResTBS 2 23 42 0 44 */ +563, /* OBJ_setct_CertReqData 2 23 42 0 45 */ +564, /* OBJ_setct_CertReqTBS 2 23 42 0 46 */ +565, /* OBJ_setct_CertResData 2 23 42 0 47 */ +566, /* OBJ_setct_CertInqReqTBS 2 23 42 0 48 */ +567, /* OBJ_setct_ErrorTBS 2 23 42 0 49 */ +568, /* OBJ_setct_PIDualSignedTBE 2 23 42 0 50 */ +569, /* OBJ_setct_PIUnsignedTBE 2 23 42 0 51 */ +570, /* OBJ_setct_AuthReqTBE 2 23 42 0 52 */ +571, /* OBJ_setct_AuthResTBE 2 23 42 0 53 */ +572, /* OBJ_setct_AuthResTBEX 2 23 42 0 54 */ +573, /* OBJ_setct_AuthTokenTBE 2 23 42 0 55 */ +574, /* OBJ_setct_CapTokenTBE 2 23 42 0 56 */ +575, /* OBJ_setct_CapTokenTBEX 2 23 42 0 57 */ +576, /* OBJ_setct_AcqCardCodeMsgTBE 2 23 42 0 58 */ +577, /* OBJ_setct_AuthRevReqTBE 2 23 42 0 59 */ +578, /* OBJ_setct_AuthRevResTBE 2 23 42 0 60 */ +579, /* OBJ_setct_AuthRevResTBEB 2 23 42 0 61 */ +580, /* OBJ_setct_CapReqTBE 2 23 42 0 62 */ +581, /* OBJ_setct_CapReqTBEX 2 23 42 0 63 */ +582, /* OBJ_setct_CapResTBE 2 23 42 0 64 */ +583, /* OBJ_setct_CapRevReqTBE 2 23 42 0 65 */ +584, /* OBJ_setct_CapRevReqTBEX 2 23 42 0 66 */ +585, /* OBJ_setct_CapRevResTBE 2 23 42 0 67 */ +586, /* OBJ_setct_CredReqTBE 2 23 42 0 68 */ +587, /* OBJ_setct_CredReqTBEX 2 23 42 0 69 */ +588, /* OBJ_setct_CredResTBE 2 23 42 0 70 */ +589, /* OBJ_setct_CredRevReqTBE 2 23 42 0 71 */ +590, /* OBJ_setct_CredRevReqTBEX 2 23 42 0 72 */ +591, /* OBJ_setct_CredRevResTBE 2 23 42 0 73 */ +592, /* OBJ_setct_BatchAdminReqTBE 2 23 42 0 74 */ +593, /* OBJ_setct_BatchAdminResTBE 2 23 42 0 75 */ +594, /* OBJ_setct_RegFormReqTBE 2 23 42 0 76 */ +595, /* OBJ_setct_CertReqTBE 2 23 42 0 77 */ +596, /* OBJ_setct_CertReqTBEX 2 23 42 0 78 */ +597, /* OBJ_setct_CertResTBE 2 23 42 0 79 */ +598, /* OBJ_setct_CRLNotificationTBS 2 23 42 0 80 */ +599, /* OBJ_setct_CRLNotificationResTBS 2 23 42 0 81 */ +600, /* OBJ_setct_BCIDistributionTBS 2 23 42 0 82 */ +601, /* OBJ_setext_genCrypt 2 23 42 1 1 */ +602, /* OBJ_setext_miAuth 2 23 42 1 3 */ +603, /* OBJ_setext_pinSecure 2 23 42 1 4 */ +604, /* OBJ_setext_pinAny 2 23 42 1 5 */ +605, /* OBJ_setext_track2 2 23 42 1 7 */ +606, /* OBJ_setext_cv 2 23 42 1 8 */ +620, /* OBJ_setAttr_Cert 2 23 42 3 0 */ +621, /* OBJ_setAttr_PGWYcap 2 23 42 3 1 */ +622, /* OBJ_setAttr_TokenType 2 23 42 3 2 */ +623, /* OBJ_setAttr_IssCap 2 23 42 3 3 */ +607, /* OBJ_set_policy_root 2 23 42 5 0 */ +608, /* OBJ_setCext_hashedRoot 2 23 42 7 0 */ +609, /* OBJ_setCext_certType 2 23 42 7 1 */ +610, /* OBJ_setCext_merchData 2 23 42 7 2 */ +611, /* OBJ_setCext_cCertRequired 2 23 42 7 3 */ +612, /* OBJ_setCext_tunneling 2 23 42 7 4 */ +613, /* OBJ_setCext_setExt 2 23 42 7 5 */ +614, /* OBJ_setCext_setQualf 2 23 42 7 6 */ +615, /* OBJ_setCext_PGWYcapabilities 2 23 42 7 7 */ +616, /* OBJ_setCext_TokenIdentifier 2 23 42 7 8 */ +617, /* OBJ_setCext_Track2Data 2 23 42 7 9 */ +618, /* OBJ_setCext_TokenType 2 23 42 7 10 */ +619, /* OBJ_setCext_IssuerCapabilities 2 23 42 7 11 */ +636, /* OBJ_set_brand_IATA_ATA 2 23 42 8 1 */ +640, /* OBJ_set_brand_Visa 2 23 42 8 4 */ +641, /* OBJ_set_brand_MasterCard 2 23 42 8 5 */ +637, /* OBJ_set_brand_Diners 2 23 42 8 30 */ +638, /* OBJ_set_brand_AmericanExpress 2 23 42 8 34 */ +639, /* OBJ_set_brand_JCB 2 23 42 8 35 */ +805, /* OBJ_cryptopro 1 2 643 2 2 */ +806, /* OBJ_cryptocom 1 2 643 2 9 */ +184, /* OBJ_X9_57 1 2 840 10040 */ +405, /* OBJ_ansi_X9_62 1 2 840 10045 */ +389, /* OBJ_Enterprises 1 3 6 1 4 1 */ +504, /* OBJ_mime_mhs 1 3 6 1 7 1 */ +104, /* OBJ_md5WithRSA 1 3 14 3 2 3 */ +29, /* OBJ_des_ecb 1 3 14 3 2 6 */ +31, /* OBJ_des_cbc 1 3 14 3 2 7 */ +45, /* OBJ_des_ofb64 1 3 14 3 2 8 */ +30, /* OBJ_des_cfb64 1 3 14 3 2 9 */ +377, /* OBJ_rsaSignature 1 3 14 3 2 11 */ +67, /* OBJ_dsa_2 1 3 14 3 2 12 */ +66, /* OBJ_dsaWithSHA 1 3 14 3 2 13 */ +42, /* OBJ_shaWithRSAEncryption 1 3 14 3 2 15 */ +32, /* OBJ_des_ede_ecb 1 3 14 3 2 17 */ +41, /* OBJ_sha 1 3 14 3 2 18 */ +64, /* OBJ_sha1 1 3 14 3 2 26 */ +70, /* OBJ_dsaWithSHA1_2 1 3 14 3 2 27 */ +115, /* OBJ_sha1WithRSA 1 3 14 3 2 29 */ +117, /* OBJ_ripemd160 1 3 36 3 2 1 */ +143, /* OBJ_sxnet 1 3 101 1 4 1 */ +721, /* OBJ_sect163k1 1 3 132 0 1 */ +722, /* OBJ_sect163r1 1 3 132 0 2 */ +728, /* OBJ_sect239k1 1 3 132 0 3 */ +717, /* OBJ_sect113r1 1 3 132 0 4 */ +718, /* OBJ_sect113r2 1 3 132 0 5 */ +704, /* OBJ_secp112r1 1 3 132 0 6 */ +705, /* OBJ_secp112r2 1 3 132 0 7 */ +709, /* OBJ_secp160r1 1 3 132 0 8 */ +708, /* OBJ_secp160k1 1 3 132 0 9 */ +714, /* OBJ_secp256k1 1 3 132 0 10 */ +723, /* OBJ_sect163r2 1 3 132 0 15 */ +729, /* OBJ_sect283k1 1 3 132 0 16 */ +730, /* OBJ_sect283r1 1 3 132 0 17 */ +719, /* OBJ_sect131r1 1 3 132 0 22 */ +720, /* OBJ_sect131r2 1 3 132 0 23 */ +724, /* OBJ_sect193r1 1 3 132 0 24 */ +725, /* OBJ_sect193r2 1 3 132 0 25 */ +726, /* OBJ_sect233k1 1 3 132 0 26 */ +727, /* OBJ_sect233r1 1 3 132 0 27 */ +706, /* OBJ_secp128r1 1 3 132 0 28 */ +707, /* OBJ_secp128r2 1 3 132 0 29 */ +710, /* OBJ_secp160r2 1 3 132 0 30 */ +711, /* OBJ_secp192k1 1 3 132 0 31 */ +712, /* OBJ_secp224k1 1 3 132 0 32 */ +713, /* OBJ_secp224r1 1 3 132 0 33 */ +715, /* OBJ_secp384r1 1 3 132 0 34 */ +716, /* OBJ_secp521r1 1 3 132 0 35 */ +731, /* OBJ_sect409k1 1 3 132 0 36 */ +732, /* OBJ_sect409r1 1 3 132 0 37 */ +733, /* OBJ_sect571k1 1 3 132 0 38 */ +734, /* OBJ_sect571r1 1 3 132 0 39 */ +624, /* OBJ_set_rootKeyThumb 2 23 42 3 0 0 */ +625, /* OBJ_set_addPolicy 2 23 42 3 0 1 */ +626, /* OBJ_setAttr_Token_EMV 2 23 42 3 2 1 */ +627, /* OBJ_setAttr_Token_B0Prime 2 23 42 3 2 2 */ +628, /* OBJ_setAttr_IssCap_CVM 2 23 42 3 3 3 */ +629, /* OBJ_setAttr_IssCap_T2 2 23 42 3 3 4 */ +630, /* OBJ_setAttr_IssCap_Sig 2 23 42 3 3 5 */ +642, /* OBJ_set_brand_Novus 2 23 42 8 6011 */ +735, /* OBJ_wap_wsg_idm_ecid_wtls1 2 23 43 1 4 1 */ +736, /* OBJ_wap_wsg_idm_ecid_wtls3 2 23 43 1 4 3 */ +737, /* OBJ_wap_wsg_idm_ecid_wtls4 2 23 43 1 4 4 */ +738, /* OBJ_wap_wsg_idm_ecid_wtls5 2 23 43 1 4 5 */ +739, /* OBJ_wap_wsg_idm_ecid_wtls6 2 23 43 1 4 6 */ +740, /* OBJ_wap_wsg_idm_ecid_wtls7 2 23 43 1 4 7 */ +741, /* OBJ_wap_wsg_idm_ecid_wtls8 2 23 43 1 4 8 */ +742, /* OBJ_wap_wsg_idm_ecid_wtls9 2 23 43 1 4 9 */ +743, /* OBJ_wap_wsg_idm_ecid_wtls10 2 23 43 1 4 10 */ +744, /* OBJ_wap_wsg_idm_ecid_wtls11 2 23 43 1 4 11 */ +745, /* OBJ_wap_wsg_idm_ecid_wtls12 2 23 43 1 4 12 */ +804, /* OBJ_whirlpool 1 0 10118 3 0 55 */ +124, /* OBJ_rle_compression 1 1 1 1 666 1 */ +773, /* OBJ_kisa 1 2 410 200004 */ +807, /* OBJ_id_GostR3411_94_with_GostR3410_2001 1 2 643 2 2 3 */ +808, /* OBJ_id_GostR3411_94_with_GostR3410_94 1 2 643 2 2 4 */ +809, /* OBJ_id_GostR3411_94 1 2 643 2 2 9 */ +810, /* OBJ_id_HMACGostR3411_94 1 2 643 2 2 10 */ +811, /* OBJ_id_GostR3410_2001 1 2 643 2 2 19 */ +812, /* OBJ_id_GostR3410_94 1 2 643 2 2 20 */ +813, /* OBJ_id_Gost28147_89 1 2 643 2 2 21 */ +815, /* OBJ_id_Gost28147_89_MAC 1 2 643 2 2 22 */ +816, /* OBJ_id_GostR3411_94_prf 1 2 643 2 2 23 */ +817, /* OBJ_id_GostR3410_2001DH 1 2 643 2 2 98 */ +818, /* OBJ_id_GostR3410_94DH 1 2 643 2 2 99 */ + 1, /* OBJ_rsadsi 1 2 840 113549 */ +185, /* OBJ_X9cm 1 2 840 10040 4 */ +127, /* OBJ_id_pkix 1 3 6 1 5 5 7 */ +505, /* OBJ_mime_mhs_headings 1 3 6 1 7 1 1 */ +506, /* OBJ_mime_mhs_bodies 1 3 6 1 7 1 2 */ +119, /* OBJ_ripemd160WithRSA 1 3 36 3 3 1 2 */ +631, /* OBJ_setAttr_GenCryptgrm 2 23 42 3 3 3 1 */ +632, /* OBJ_setAttr_T2Enc 2 23 42 3 3 4 1 */ +633, /* OBJ_setAttr_T2cleartxt 2 23 42 3 3 4 2 */ +634, /* OBJ_setAttr_TokICCsig 2 23 42 3 3 5 1 */ +635, /* OBJ_setAttr_SecDevSig 2 23 42 3 3 5 2 */ +436, /* OBJ_ucl 0 9 2342 19200300 */ +820, /* OBJ_id_Gost28147_89_None_KeyMeshing 1 2 643 2 2 14 0 */ +819, /* OBJ_id_Gost28147_89_CryptoPro_KeyMeshing 1 2 643 2 2 14 1 */ +845, /* OBJ_id_GostR3410_94_a 1 2 643 2 2 20 1 */ +846, /* OBJ_id_GostR3410_94_aBis 1 2 643 2 2 20 2 */ +847, /* OBJ_id_GostR3410_94_b 1 2 643 2 2 20 3 */ +848, /* OBJ_id_GostR3410_94_bBis 1 2 643 2 2 20 4 */ +821, /* OBJ_id_GostR3411_94_TestParamSet 1 2 643 2 2 30 0 */ +822, /* OBJ_id_GostR3411_94_CryptoProParamSet 1 2 643 2 2 30 1 */ +823, /* OBJ_id_Gost28147_89_TestParamSet 1 2 643 2 2 31 0 */ +824, /* OBJ_id_Gost28147_89_CryptoPro_A_ParamSet 1 2 643 2 2 31 1 */ +825, /* OBJ_id_Gost28147_89_CryptoPro_B_ParamSet 1 2 643 2 2 31 2 */ +826, /* OBJ_id_Gost28147_89_CryptoPro_C_ParamSet 1 2 643 2 2 31 3 */ +827, /* OBJ_id_Gost28147_89_CryptoPro_D_ParamSet 1 2 643 2 2 31 4 */ +828, /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 1 2 643 2 2 31 5 */ +829, /* OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 1 2 643 2 2 31 6 */ +830, /* OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 1 2 643 2 2 31 7 */ +831, /* OBJ_id_GostR3410_94_TestParamSet 1 2 643 2 2 32 0 */ +832, /* OBJ_id_GostR3410_94_CryptoPro_A_ParamSet 1 2 643 2 2 32 2 */ +833, /* OBJ_id_GostR3410_94_CryptoPro_B_ParamSet 1 2 643 2 2 32 3 */ +834, /* OBJ_id_GostR3410_94_CryptoPro_C_ParamSet 1 2 643 2 2 32 4 */ +835, /* OBJ_id_GostR3410_94_CryptoPro_D_ParamSet 1 2 643 2 2 32 5 */ +836, /* OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet 1 2 643 2 2 33 1 */ +837, /* OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet 1 2 643 2 2 33 2 */ +838, /* OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet 1 2 643 2 2 33 3 */ +839, /* OBJ_id_GostR3410_2001_TestParamSet 1 2 643 2 2 35 0 */ +840, /* OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet 1 2 643 2 2 35 1 */ +841, /* OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet 1 2 643 2 2 35 2 */ +842, /* OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet 1 2 643 2 2 35 3 */ +843, /* OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet 1 2 643 2 2 36 0 */ +844, /* OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet 1 2 643 2 2 36 1 */ + 2, /* OBJ_pkcs 1 2 840 113549 1 */ +431, /* OBJ_hold_instruction_none 1 2 840 10040 2 1 */ +432, /* OBJ_hold_instruction_call_issuer 1 2 840 10040 2 2 */ +433, /* OBJ_hold_instruction_reject 1 2 840 10040 2 3 */ +116, /* OBJ_dsa 1 2 840 10040 4 1 */ +113, /* OBJ_dsaWithSHA1 1 2 840 10040 4 3 */ +406, /* OBJ_X9_62_prime_field 1 2 840 10045 1 1 */ +407, /* OBJ_X9_62_characteristic_two_field 1 2 840 10045 1 2 */ +408, /* OBJ_X9_62_id_ecPublicKey 1 2 840 10045 2 1 */ +416, /* OBJ_ecdsa_with_SHA1 1 2 840 10045 4 1 */ +791, /* OBJ_ecdsa_with_Recommended 1 2 840 10045 4 2 */ +792, /* OBJ_ecdsa_with_Specified 1 2 840 10045 4 3 */ +258, /* OBJ_id_pkix_mod 1 3 6 1 5 5 7 0 */ +175, /* OBJ_id_pe 1 3 6 1 5 5 7 1 */ +259, /* OBJ_id_qt 1 3 6 1 5 5 7 2 */ +128, /* OBJ_id_kp 1 3 6 1 5 5 7 3 */ +260, /* OBJ_id_it 1 3 6 1 5 5 7 4 */ +261, /* OBJ_id_pkip 1 3 6 1 5 5 7 5 */ +262, /* OBJ_id_alg 1 3 6 1 5 5 7 6 */ +263, /* OBJ_id_cmc 1 3 6 1 5 5 7 7 */ +264, /* OBJ_id_on 1 3 6 1 5 5 7 8 */ +265, /* OBJ_id_pda 1 3 6 1 5 5 7 9 */ +266, /* OBJ_id_aca 1 3 6 1 5 5 7 10 */ +267, /* OBJ_id_qcs 1 3 6 1 5 5 7 11 */ +268, /* OBJ_id_cct 1 3 6 1 5 5 7 12 */ +662, /* OBJ_id_ppl 1 3 6 1 5 5 7 21 */ +176, /* OBJ_id_ad 1 3 6 1 5 5 7 48 */ +507, /* OBJ_id_hex_partial_message 1 3 6 1 7 1 1 1 */ +508, /* OBJ_id_hex_multipart_message 1 3 6 1 7 1 1 2 */ +57, /* OBJ_netscape 2 16 840 1 113730 */ +754, /* OBJ_camellia_128_ecb 0 3 4401 5 3 1 9 1 */ +766, /* OBJ_camellia_128_ofb128 0 3 4401 5 3 1 9 3 */ +757, /* OBJ_camellia_128_cfb128 0 3 4401 5 3 1 9 4 */ +755, /* OBJ_camellia_192_ecb 0 3 4401 5 3 1 9 21 */ +767, /* OBJ_camellia_192_ofb128 0 3 4401 5 3 1 9 23 */ +758, /* OBJ_camellia_192_cfb128 0 3 4401 5 3 1 9 24 */ +756, /* OBJ_camellia_256_ecb 0 3 4401 5 3 1 9 41 */ +768, /* OBJ_camellia_256_ofb128 0 3 4401 5 3 1 9 43 */ +759, /* OBJ_camellia_256_cfb128 0 3 4401 5 3 1 9 44 */ +437, /* OBJ_pilot 0 9 2342 19200300 100 */ +776, /* OBJ_seed_ecb 1 2 410 200004 1 3 */ +777, /* OBJ_seed_cbc 1 2 410 200004 1 4 */ +779, /* OBJ_seed_cfb128 1 2 410 200004 1 5 */ +778, /* OBJ_seed_ofb128 1 2 410 200004 1 6 */ +852, /* OBJ_id_GostR3411_94_with_GostR3410_94_cc 1 2 643 2 9 1 3 3 */ +853, /* OBJ_id_GostR3411_94_with_GostR3410_2001_cc 1 2 643 2 9 1 3 4 */ +850, /* OBJ_id_GostR3410_94_cc 1 2 643 2 9 1 5 3 */ +851, /* OBJ_id_GostR3410_2001_cc 1 2 643 2 9 1 5 4 */ +849, /* OBJ_id_Gost28147_89_cc 1 2 643 2 9 1 6 1 */ +854, /* OBJ_id_GostR3410_2001_ParamSet_cc 1 2 643 2 9 1 8 1 */ +186, /* OBJ_pkcs1 1 2 840 113549 1 1 */ +27, /* OBJ_pkcs3 1 2 840 113549 1 3 */ +187, /* OBJ_pkcs5 1 2 840 113549 1 5 */ +20, /* OBJ_pkcs7 1 2 840 113549 1 7 */ +47, /* OBJ_pkcs9 1 2 840 113549 1 9 */ + 3, /* OBJ_md2 1 2 840 113549 2 2 */ +257, /* OBJ_md4 1 2 840 113549 2 4 */ + 4, /* OBJ_md5 1 2 840 113549 2 5 */ +797, /* OBJ_hmacWithMD5 1 2 840 113549 2 6 */ +163, /* OBJ_hmacWithSHA1 1 2 840 113549 2 7 */ +798, /* OBJ_hmacWithSHA224 1 2 840 113549 2 8 */ +799, /* OBJ_hmacWithSHA256 1 2 840 113549 2 9 */ +800, /* OBJ_hmacWithSHA384 1 2 840 113549 2 10 */ +801, /* OBJ_hmacWithSHA512 1 2 840 113549 2 11 */ +37, /* OBJ_rc2_cbc 1 2 840 113549 3 2 */ + 5, /* OBJ_rc4 1 2 840 113549 3 4 */ +44, /* OBJ_des_ede3_cbc 1 2 840 113549 3 7 */ +120, /* OBJ_rc5_cbc 1 2 840 113549 3 8 */ +643, /* OBJ_des_cdmf 1 2 840 113549 3 10 */ +680, /* OBJ_X9_62_id_characteristic_two_basis 1 2 840 10045 1 2 3 */ +684, /* OBJ_X9_62_c2pnb163v1 1 2 840 10045 3 0 1 */ +685, /* OBJ_X9_62_c2pnb163v2 1 2 840 10045 3 0 2 */ +686, /* OBJ_X9_62_c2pnb163v3 1 2 840 10045 3 0 3 */ +687, /* OBJ_X9_62_c2pnb176v1 1 2 840 10045 3 0 4 */ +688, /* OBJ_X9_62_c2tnb191v1 1 2 840 10045 3 0 5 */ +689, /* OBJ_X9_62_c2tnb191v2 1 2 840 10045 3 0 6 */ +690, /* OBJ_X9_62_c2tnb191v3 1 2 840 10045 3 0 7 */ +691, /* OBJ_X9_62_c2onb191v4 1 2 840 10045 3 0 8 */ +692, /* OBJ_X9_62_c2onb191v5 1 2 840 10045 3 0 9 */ +693, /* OBJ_X9_62_c2pnb208w1 1 2 840 10045 3 0 10 */ +694, /* OBJ_X9_62_c2tnb239v1 1 2 840 10045 3 0 11 */ +695, /* OBJ_X9_62_c2tnb239v2 1 2 840 10045 3 0 12 */ +696, /* OBJ_X9_62_c2tnb239v3 1 2 840 10045 3 0 13 */ +697, /* OBJ_X9_62_c2onb239v4 1 2 840 10045 3 0 14 */ +698, /* OBJ_X9_62_c2onb239v5 1 2 840 10045 3 0 15 */ +699, /* OBJ_X9_62_c2pnb272w1 1 2 840 10045 3 0 16 */ +700, /* OBJ_X9_62_c2pnb304w1 1 2 840 10045 3 0 17 */ +701, /* OBJ_X9_62_c2tnb359v1 1 2 840 10045 3 0 18 */ +702, /* OBJ_X9_62_c2pnb368w1 1 2 840 10045 3 0 19 */ +703, /* OBJ_X9_62_c2tnb431r1 1 2 840 10045 3 0 20 */ +409, /* OBJ_X9_62_prime192v1 1 2 840 10045 3 1 1 */ +410, /* OBJ_X9_62_prime192v2 1 2 840 10045 3 1 2 */ +411, /* OBJ_X9_62_prime192v3 1 2 840 10045 3 1 3 */ +412, /* OBJ_X9_62_prime239v1 1 2 840 10045 3 1 4 */ +413, /* OBJ_X9_62_prime239v2 1 2 840 10045 3 1 5 */ +414, /* OBJ_X9_62_prime239v3 1 2 840 10045 3 1 6 */ +415, /* OBJ_X9_62_prime256v1 1 2 840 10045 3 1 7 */ +793, /* OBJ_ecdsa_with_SHA224 1 2 840 10045 4 3 1 */ +794, /* OBJ_ecdsa_with_SHA256 1 2 840 10045 4 3 2 */ +795, /* OBJ_ecdsa_with_SHA384 1 2 840 10045 4 3 3 */ +796, /* OBJ_ecdsa_with_SHA512 1 2 840 10045 4 3 4 */ +269, /* OBJ_id_pkix1_explicit_88 1 3 6 1 5 5 7 0 1 */ +270, /* OBJ_id_pkix1_implicit_88 1 3 6 1 5 5 7 0 2 */ +271, /* OBJ_id_pkix1_explicit_93 1 3 6 1 5 5 7 0 3 */ +272, /* OBJ_id_pkix1_implicit_93 1 3 6 1 5 5 7 0 4 */ +273, /* OBJ_id_mod_crmf 1 3 6 1 5 5 7 0 5 */ +274, /* OBJ_id_mod_cmc 1 3 6 1 5 5 7 0 6 */ +275, /* OBJ_id_mod_kea_profile_88 1 3 6 1 5 5 7 0 7 */ +276, /* OBJ_id_mod_kea_profile_93 1 3 6 1 5 5 7 0 8 */ +277, /* OBJ_id_mod_cmp 1 3 6 1 5 5 7 0 9 */ +278, /* OBJ_id_mod_qualified_cert_88 1 3 6 1 5 5 7 0 10 */ +279, /* OBJ_id_mod_qualified_cert_93 1 3 6 1 5 5 7 0 11 */ +280, /* OBJ_id_mod_attribute_cert 1 3 6 1 5 5 7 0 12 */ +281, /* OBJ_id_mod_timestamp_protocol 1 3 6 1 5 5 7 0 13 */ +282, /* OBJ_id_mod_ocsp 1 3 6 1 5 5 7 0 14 */ +283, /* OBJ_id_mod_dvcs 1 3 6 1 5 5 7 0 15 */ +284, /* OBJ_id_mod_cmp2000 1 3 6 1 5 5 7 0 16 */ +177, /* OBJ_info_access 1 3 6 1 5 5 7 1 1 */ +285, /* OBJ_biometricInfo 1 3 6 1 5 5 7 1 2 */ +286, /* OBJ_qcStatements 1 3 6 1 5 5 7 1 3 */ +287, /* OBJ_ac_auditEntity 1 3 6 1 5 5 7 1 4 */ +288, /* OBJ_ac_targeting 1 3 6 1 5 5 7 1 5 */ +289, /* OBJ_aaControls 1 3 6 1 5 5 7 1 6 */ +290, /* OBJ_sbgp_ipAddrBlock 1 3 6 1 5 5 7 1 7 */ +291, /* OBJ_sbgp_autonomousSysNum 1 3 6 1 5 5 7 1 8 */ +292, /* OBJ_sbgp_routerIdentifier 1 3 6 1 5 5 7 1 9 */ +397, /* OBJ_ac_proxying 1 3 6 1 5 5 7 1 10 */ +398, /* OBJ_sinfo_access 1 3 6 1 5 5 7 1 11 */ +663, /* OBJ_proxyCertInfo 1 3 6 1 5 5 7 1 14 */ +164, /* OBJ_id_qt_cps 1 3 6 1 5 5 7 2 1 */ +165, /* OBJ_id_qt_unotice 1 3 6 1 5 5 7 2 2 */ +293, /* OBJ_textNotice 1 3 6 1 5 5 7 2 3 */ +129, /* OBJ_server_auth 1 3 6 1 5 5 7 3 1 */ +130, /* OBJ_client_auth 1 3 6 1 5 5 7 3 2 */ +131, /* OBJ_code_sign 1 3 6 1 5 5 7 3 3 */ +132, /* OBJ_email_protect 1 3 6 1 5 5 7 3 4 */ +294, /* OBJ_ipsecEndSystem 1 3 6 1 5 5 7 3 5 */ +295, /* OBJ_ipsecTunnel 1 3 6 1 5 5 7 3 6 */ +296, /* OBJ_ipsecUser 1 3 6 1 5 5 7 3 7 */ +133, /* OBJ_time_stamp 1 3 6 1 5 5 7 3 8 */ +180, /* OBJ_OCSP_sign 1 3 6 1 5 5 7 3 9 */ +297, /* OBJ_dvcs 1 3 6 1 5 5 7 3 10 */ +298, /* OBJ_id_it_caProtEncCert 1 3 6 1 5 5 7 4 1 */ +299, /* OBJ_id_it_signKeyPairTypes 1 3 6 1 5 5 7 4 2 */ +300, /* OBJ_id_it_encKeyPairTypes 1 3 6 1 5 5 7 4 3 */ +301, /* OBJ_id_it_preferredSymmAlg 1 3 6 1 5 5 7 4 4 */ +302, /* OBJ_id_it_caKeyUpdateInfo 1 3 6 1 5 5 7 4 5 */ +303, /* OBJ_id_it_currentCRL 1 3 6 1 5 5 7 4 6 */ +304, /* OBJ_id_it_unsupportedOIDs 1 3 6 1 5 5 7 4 7 */ +305, /* OBJ_id_it_subscriptionRequest 1 3 6 1 5 5 7 4 8 */ +306, /* OBJ_id_it_subscriptionResponse 1 3 6 1 5 5 7 4 9 */ +307, /* OBJ_id_it_keyPairParamReq 1 3 6 1 5 5 7 4 10 */ +308, /* OBJ_id_it_keyPairParamRep 1 3 6 1 5 5 7 4 11 */ +309, /* OBJ_id_it_revPassphrase 1 3 6 1 5 5 7 4 12 */ +310, /* OBJ_id_it_implicitConfirm 1 3 6 1 5 5 7 4 13 */ +311, /* OBJ_id_it_confirmWaitTime 1 3 6 1 5 5 7 4 14 */ +312, /* OBJ_id_it_origPKIMessage 1 3 6 1 5 5 7 4 15 */ +784, /* OBJ_id_it_suppLangTags 1 3 6 1 5 5 7 4 16 */ +313, /* OBJ_id_regCtrl 1 3 6 1 5 5 7 5 1 */ +314, /* OBJ_id_regInfo 1 3 6 1 5 5 7 5 2 */ +323, /* OBJ_id_alg_des40 1 3 6 1 5 5 7 6 1 */ +324, /* OBJ_id_alg_noSignature 1 3 6 1 5 5 7 6 2 */ +325, /* OBJ_id_alg_dh_sig_hmac_sha1 1 3 6 1 5 5 7 6 3 */ +326, /* OBJ_id_alg_dh_pop 1 3 6 1 5 5 7 6 4 */ +327, /* OBJ_id_cmc_statusInfo 1 3 6 1 5 5 7 7 1 */ +328, /* OBJ_id_cmc_identification 1 3 6 1 5 5 7 7 2 */ +329, /* OBJ_id_cmc_identityProof 1 3 6 1 5 5 7 7 3 */ +330, /* OBJ_id_cmc_dataReturn 1 3 6 1 5 5 7 7 4 */ +331, /* OBJ_id_cmc_transactionId 1 3 6 1 5 5 7 7 5 */ +332, /* OBJ_id_cmc_senderNonce 1 3 6 1 5 5 7 7 6 */ +333, /* OBJ_id_cmc_recipientNonce 1 3 6 1 5 5 7 7 7 */ +334, /* OBJ_id_cmc_addExtensions 1 3 6 1 5 5 7 7 8 */ +335, /* OBJ_id_cmc_encryptedPOP 1 3 6 1 5 5 7 7 9 */ +336, /* OBJ_id_cmc_decryptedPOP 1 3 6 1 5 5 7 7 10 */ +337, /* OBJ_id_cmc_lraPOPWitness 1 3 6 1 5 5 7 7 11 */ +338, /* OBJ_id_cmc_getCert 1 3 6 1 5 5 7 7 15 */ +339, /* OBJ_id_cmc_getCRL 1 3 6 1 5 5 7 7 16 */ +340, /* OBJ_id_cmc_revokeRequest 1 3 6 1 5 5 7 7 17 */ +341, /* OBJ_id_cmc_regInfo 1 3 6 1 5 5 7 7 18 */ +342, /* OBJ_id_cmc_responseInfo 1 3 6 1 5 5 7 7 19 */ +343, /* OBJ_id_cmc_queryPending 1 3 6 1 5 5 7 7 21 */ +344, /* OBJ_id_cmc_popLinkRandom 1 3 6 1 5 5 7 7 22 */ +345, /* OBJ_id_cmc_popLinkWitness 1 3 6 1 5 5 7 7 23 */ +346, /* OBJ_id_cmc_confirmCertAcceptance 1 3 6 1 5 5 7 7 24 */ +347, /* OBJ_id_on_personalData 1 3 6 1 5 5 7 8 1 */ +858, /* OBJ_id_on_permanentIdentifier 1 3 6 1 5 5 7 8 3 */ +348, /* OBJ_id_pda_dateOfBirth 1 3 6 1 5 5 7 9 1 */ +349, /* OBJ_id_pda_placeOfBirth 1 3 6 1 5 5 7 9 2 */ +351, /* OBJ_id_pda_gender 1 3 6 1 5 5 7 9 3 */ +352, /* OBJ_id_pda_countryOfCitizenship 1 3 6 1 5 5 7 9 4 */ +353, /* OBJ_id_pda_countryOfResidence 1 3 6 1 5 5 7 9 5 */ +354, /* OBJ_id_aca_authenticationInfo 1 3 6 1 5 5 7 10 1 */ +355, /* OBJ_id_aca_accessIdentity 1 3 6 1 5 5 7 10 2 */ +356, /* OBJ_id_aca_chargingIdentity 1 3 6 1 5 5 7 10 3 */ +357, /* OBJ_id_aca_group 1 3 6 1 5 5 7 10 4 */ +358, /* OBJ_id_aca_role 1 3 6 1 5 5 7 10 5 */ +399, /* OBJ_id_aca_encAttrs 1 3 6 1 5 5 7 10 6 */ +359, /* OBJ_id_qcs_pkixQCSyntax_v1 1 3 6 1 5 5 7 11 1 */ +360, /* OBJ_id_cct_crs 1 3 6 1 5 5 7 12 1 */ +361, /* OBJ_id_cct_PKIData 1 3 6 1 5 5 7 12 2 */ +362, /* OBJ_id_cct_PKIResponse 1 3 6 1 5 5 7 12 3 */ +664, /* OBJ_id_ppl_anyLanguage 1 3 6 1 5 5 7 21 0 */ +665, /* OBJ_id_ppl_inheritAll 1 3 6 1 5 5 7 21 1 */ +667, /* OBJ_Independent 1 3 6 1 5 5 7 21 2 */ +178, /* OBJ_ad_OCSP 1 3 6 1 5 5 7 48 1 */ +179, /* OBJ_ad_ca_issuers 1 3 6 1 5 5 7 48 2 */ +363, /* OBJ_ad_timeStamping 1 3 6 1 5 5 7 48 3 */ +364, /* OBJ_ad_dvcs 1 3 6 1 5 5 7 48 4 */ +785, /* OBJ_caRepository 1 3 6 1 5 5 7 48 5 */ +780, /* OBJ_hmac_md5 1 3 6 1 5 5 8 1 1 */ +781, /* OBJ_hmac_sha1 1 3 6 1 5 5 8 1 2 */ +58, /* OBJ_netscape_cert_extension 2 16 840 1 113730 1 */ +59, /* OBJ_netscape_data_type 2 16 840 1 113730 2 */ +438, /* OBJ_pilotAttributeType 0 9 2342 19200300 100 1 */ +439, /* OBJ_pilotAttributeSyntax 0 9 2342 19200300 100 3 */ +440, /* OBJ_pilotObjectClass 0 9 2342 19200300 100 4 */ +441, /* OBJ_pilotGroups 0 9 2342 19200300 100 10 */ +108, /* OBJ_cast5_cbc 1 2 840 113533 7 66 10 */ +112, /* OBJ_pbeWithMD5AndCast5_CBC 1 2 840 113533 7 66 12 */ +782, /* OBJ_id_PasswordBasedMAC 1 2 840 113533 7 66 13 */ +783, /* OBJ_id_DHBasedMac 1 2 840 113533 7 66 30 */ + 6, /* OBJ_rsaEncryption 1 2 840 113549 1 1 1 */ + 7, /* OBJ_md2WithRSAEncryption 1 2 840 113549 1 1 2 */ +396, /* OBJ_md4WithRSAEncryption 1 2 840 113549 1 1 3 */ + 8, /* OBJ_md5WithRSAEncryption 1 2 840 113549 1 1 4 */ +65, /* OBJ_sha1WithRSAEncryption 1 2 840 113549 1 1 5 */ +644, /* OBJ_rsaOAEPEncryptionSET 1 2 840 113549 1 1 6 */ +919, /* OBJ_rsaesOaep 1 2 840 113549 1 1 7 */ +911, /* OBJ_mgf1 1 2 840 113549 1 1 8 */ +912, /* OBJ_rsassaPss 1 2 840 113549 1 1 10 */ +668, /* OBJ_sha256WithRSAEncryption 1 2 840 113549 1 1 11 */ +669, /* OBJ_sha384WithRSAEncryption 1 2 840 113549 1 1 12 */ +670, /* OBJ_sha512WithRSAEncryption 1 2 840 113549 1 1 13 */ +671, /* OBJ_sha224WithRSAEncryption 1 2 840 113549 1 1 14 */ +28, /* OBJ_dhKeyAgreement 1 2 840 113549 1 3 1 */ + 9, /* OBJ_pbeWithMD2AndDES_CBC 1 2 840 113549 1 5 1 */ +10, /* OBJ_pbeWithMD5AndDES_CBC 1 2 840 113549 1 5 3 */ +168, /* OBJ_pbeWithMD2AndRC2_CBC 1 2 840 113549 1 5 4 */ +169, /* OBJ_pbeWithMD5AndRC2_CBC 1 2 840 113549 1 5 6 */ +170, /* OBJ_pbeWithSHA1AndDES_CBC 1 2 840 113549 1 5 10 */ +68, /* OBJ_pbeWithSHA1AndRC2_CBC 1 2 840 113549 1 5 11 */ +69, /* OBJ_id_pbkdf2 1 2 840 113549 1 5 12 */ +161, /* OBJ_pbes2 1 2 840 113549 1 5 13 */ +162, /* OBJ_pbmac1 1 2 840 113549 1 5 14 */ +21, /* OBJ_pkcs7_data 1 2 840 113549 1 7 1 */ +22, /* OBJ_pkcs7_signed 1 2 840 113549 1 7 2 */ +23, /* OBJ_pkcs7_enveloped 1 2 840 113549 1 7 3 */ +24, /* OBJ_pkcs7_signedAndEnveloped 1 2 840 113549 1 7 4 */ +25, /* OBJ_pkcs7_digest 1 2 840 113549 1 7 5 */ +26, /* OBJ_pkcs7_encrypted 1 2 840 113549 1 7 6 */ +48, /* OBJ_pkcs9_emailAddress 1 2 840 113549 1 9 1 */ +49, /* OBJ_pkcs9_unstructuredName 1 2 840 113549 1 9 2 */ +50, /* OBJ_pkcs9_contentType 1 2 840 113549 1 9 3 */ +51, /* OBJ_pkcs9_messageDigest 1 2 840 113549 1 9 4 */ +52, /* OBJ_pkcs9_signingTime 1 2 840 113549 1 9 5 */ +53, /* OBJ_pkcs9_countersignature 1 2 840 113549 1 9 6 */ +54, /* OBJ_pkcs9_challengePassword 1 2 840 113549 1 9 7 */ +55, /* OBJ_pkcs9_unstructuredAddress 1 2 840 113549 1 9 8 */ +56, /* OBJ_pkcs9_extCertAttributes 1 2 840 113549 1 9 9 */ +172, /* OBJ_ext_req 1 2 840 113549 1 9 14 */ +167, /* OBJ_SMIMECapabilities 1 2 840 113549 1 9 15 */ +188, /* OBJ_SMIME 1 2 840 113549 1 9 16 */ +156, /* OBJ_friendlyName 1 2 840 113549 1 9 20 */ +157, /* OBJ_localKeyID 1 2 840 113549 1 9 21 */ +681, /* OBJ_X9_62_onBasis 1 2 840 10045 1 2 3 1 */ +682, /* OBJ_X9_62_tpBasis 1 2 840 10045 1 2 3 2 */ +683, /* OBJ_X9_62_ppBasis 1 2 840 10045 1 2 3 3 */ +417, /* OBJ_ms_csp_name 1 3 6 1 4 1 311 17 1 */ +856, /* OBJ_LocalKeySet 1 3 6 1 4 1 311 17 2 */ +390, /* OBJ_dcObject 1 3 6 1 4 1 1466 344 */ +91, /* OBJ_bf_cbc 1 3 6 1 4 1 3029 1 2 */ +315, /* OBJ_id_regCtrl_regToken 1 3 6 1 5 5 7 5 1 1 */ +316, /* OBJ_id_regCtrl_authenticator 1 3 6 1 5 5 7 5 1 2 */ +317, /* OBJ_id_regCtrl_pkiPublicationInfo 1 3 6 1 5 5 7 5 1 3 */ +318, /* OBJ_id_regCtrl_pkiArchiveOptions 1 3 6 1 5 5 7 5 1 4 */ +319, /* OBJ_id_regCtrl_oldCertID 1 3 6 1 5 5 7 5 1 5 */ +320, /* OBJ_id_regCtrl_protocolEncrKey 1 3 6 1 5 5 7 5 1 6 */ +321, /* OBJ_id_regInfo_utf8Pairs 1 3 6 1 5 5 7 5 2 1 */ +322, /* OBJ_id_regInfo_certReq 1 3 6 1 5 5 7 5 2 2 */ +365, /* OBJ_id_pkix_OCSP_basic 1 3 6 1 5 5 7 48 1 1 */ +366, /* OBJ_id_pkix_OCSP_Nonce 1 3 6 1 5 5 7 48 1 2 */ +367, /* OBJ_id_pkix_OCSP_CrlID 1 3 6 1 5 5 7 48 1 3 */ +368, /* OBJ_id_pkix_OCSP_acceptableResponses 1 3 6 1 5 5 7 48 1 4 */ +369, /* OBJ_id_pkix_OCSP_noCheck 1 3 6 1 5 5 7 48 1 5 */ +370, /* OBJ_id_pkix_OCSP_archiveCutoff 1 3 6 1 5 5 7 48 1 6 */ +371, /* OBJ_id_pkix_OCSP_serviceLocator 1 3 6 1 5 5 7 48 1 7 */ +372, /* OBJ_id_pkix_OCSP_extendedStatus 1 3 6 1 5 5 7 48 1 8 */ +373, /* OBJ_id_pkix_OCSP_valid 1 3 6 1 5 5 7 48 1 9 */ +374, /* OBJ_id_pkix_OCSP_path 1 3 6 1 5 5 7 48 1 10 */ +375, /* OBJ_id_pkix_OCSP_trustRoot 1 3 6 1 5 5 7 48 1 11 */ +418, /* OBJ_aes_128_ecb 2 16 840 1 101 3 4 1 1 */ +419, /* OBJ_aes_128_cbc 2 16 840 1 101 3 4 1 2 */ +420, /* OBJ_aes_128_ofb128 2 16 840 1 101 3 4 1 3 */ +421, /* OBJ_aes_128_cfb128 2 16 840 1 101 3 4 1 4 */ +788, /* OBJ_id_aes128_wrap 2 16 840 1 101 3 4 1 5 */ +895, /* OBJ_aes_128_gcm 2 16 840 1 101 3 4 1 6 */ +896, /* OBJ_aes_128_ccm 2 16 840 1 101 3 4 1 7 */ +897, /* OBJ_id_aes128_wrap_pad 2 16 840 1 101 3 4 1 8 */ +422, /* OBJ_aes_192_ecb 2 16 840 1 101 3 4 1 21 */ +423, /* OBJ_aes_192_cbc 2 16 840 1 101 3 4 1 22 */ +424, /* OBJ_aes_192_ofb128 2 16 840 1 101 3 4 1 23 */ +425, /* OBJ_aes_192_cfb128 2 16 840 1 101 3 4 1 24 */ +789, /* OBJ_id_aes192_wrap 2 16 840 1 101 3 4 1 25 */ +898, /* OBJ_aes_192_gcm 2 16 840 1 101 3 4 1 26 */ +899, /* OBJ_aes_192_ccm 2 16 840 1 101 3 4 1 27 */ +900, /* OBJ_id_aes192_wrap_pad 2 16 840 1 101 3 4 1 28 */ +426, /* OBJ_aes_256_ecb 2 16 840 1 101 3 4 1 41 */ +427, /* OBJ_aes_256_cbc 2 16 840 1 101 3 4 1 42 */ +428, /* OBJ_aes_256_ofb128 2 16 840 1 101 3 4 1 43 */ +429, /* OBJ_aes_256_cfb128 2 16 840 1 101 3 4 1 44 */ +790, /* OBJ_id_aes256_wrap 2 16 840 1 101 3 4 1 45 */ +901, /* OBJ_aes_256_gcm 2 16 840 1 101 3 4 1 46 */ +902, /* OBJ_aes_256_ccm 2 16 840 1 101 3 4 1 47 */ +903, /* OBJ_id_aes256_wrap_pad 2 16 840 1 101 3 4 1 48 */ +672, /* OBJ_sha256 2 16 840 1 101 3 4 2 1 */ +673, /* OBJ_sha384 2 16 840 1 101 3 4 2 2 */ +674, /* OBJ_sha512 2 16 840 1 101 3 4 2 3 */ +675, /* OBJ_sha224 2 16 840 1 101 3 4 2 4 */ +802, /* OBJ_dsa_with_SHA224 2 16 840 1 101 3 4 3 1 */ +803, /* OBJ_dsa_with_SHA256 2 16 840 1 101 3 4 3 2 */ +71, /* OBJ_netscape_cert_type 2 16 840 1 113730 1 1 */ +72, /* OBJ_netscape_base_url 2 16 840 1 113730 1 2 */ +73, /* OBJ_netscape_revocation_url 2 16 840 1 113730 1 3 */ +74, /* OBJ_netscape_ca_revocation_url 2 16 840 1 113730 1 4 */ +75, /* OBJ_netscape_renewal_url 2 16 840 1 113730 1 7 */ +76, /* OBJ_netscape_ca_policy_url 2 16 840 1 113730 1 8 */ +77, /* OBJ_netscape_ssl_server_name 2 16 840 1 113730 1 12 */ +78, /* OBJ_netscape_comment 2 16 840 1 113730 1 13 */ +79, /* OBJ_netscape_cert_sequence 2 16 840 1 113730 2 5 */ +139, /* OBJ_ns_sgc 2 16 840 1 113730 4 1 */ +458, /* OBJ_userId 0 9 2342 19200300 100 1 1 */ +459, /* OBJ_textEncodedORAddress 0 9 2342 19200300 100 1 2 */ +460, /* OBJ_rfc822Mailbox 0 9 2342 19200300 100 1 3 */ +461, /* OBJ_info 0 9 2342 19200300 100 1 4 */ +462, /* OBJ_favouriteDrink 0 9 2342 19200300 100 1 5 */ +463, /* OBJ_roomNumber 0 9 2342 19200300 100 1 6 */ +464, /* OBJ_photo 0 9 2342 19200300 100 1 7 */ +465, /* OBJ_userClass 0 9 2342 19200300 100 1 8 */ +466, /* OBJ_host 0 9 2342 19200300 100 1 9 */ +467, /* OBJ_manager 0 9 2342 19200300 100 1 10 */ +468, /* OBJ_documentIdentifier 0 9 2342 19200300 100 1 11 */ +469, /* OBJ_documentTitle 0 9 2342 19200300 100 1 12 */ +470, /* OBJ_documentVersion 0 9 2342 19200300 100 1 13 */ +471, /* OBJ_documentAuthor 0 9 2342 19200300 100 1 14 */ +472, /* OBJ_documentLocation 0 9 2342 19200300 100 1 15 */ +473, /* OBJ_homeTelephoneNumber 0 9 2342 19200300 100 1 20 */ +474, /* OBJ_secretary 0 9 2342 19200300 100 1 21 */ +475, /* OBJ_otherMailbox 0 9 2342 19200300 100 1 22 */ +476, /* OBJ_lastModifiedTime 0 9 2342 19200300 100 1 23 */ +477, /* OBJ_lastModifiedBy 0 9 2342 19200300 100 1 24 */ +391, /* OBJ_domainComponent 0 9 2342 19200300 100 1 25 */ +478, /* OBJ_aRecord 0 9 2342 19200300 100 1 26 */ +479, /* OBJ_pilotAttributeType27 0 9 2342 19200300 100 1 27 */ +480, /* OBJ_mXRecord 0 9 2342 19200300 100 1 28 */ +481, /* OBJ_nSRecord 0 9 2342 19200300 100 1 29 */ +482, /* OBJ_sOARecord 0 9 2342 19200300 100 1 30 */ +483, /* OBJ_cNAMERecord 0 9 2342 19200300 100 1 31 */ +484, /* OBJ_associatedDomain 0 9 2342 19200300 100 1 37 */ +485, /* OBJ_associatedName 0 9 2342 19200300 100 1 38 */ +486, /* OBJ_homePostalAddress 0 9 2342 19200300 100 1 39 */ +487, /* OBJ_personalTitle 0 9 2342 19200300 100 1 40 */ +488, /* OBJ_mobileTelephoneNumber 0 9 2342 19200300 100 1 41 */ +489, /* OBJ_pagerTelephoneNumber 0 9 2342 19200300 100 1 42 */ +490, /* OBJ_friendlyCountryName 0 9 2342 19200300 100 1 43 */ +491, /* OBJ_organizationalStatus 0 9 2342 19200300 100 1 45 */ +492, /* OBJ_janetMailbox 0 9 2342 19200300 100 1 46 */ +493, /* OBJ_mailPreferenceOption 0 9 2342 19200300 100 1 47 */ +494, /* OBJ_buildingName 0 9 2342 19200300 100 1 48 */ +495, /* OBJ_dSAQuality 0 9 2342 19200300 100 1 49 */ +496, /* OBJ_singleLevelQuality 0 9 2342 19200300 100 1 50 */ +497, /* OBJ_subtreeMinimumQuality 0 9 2342 19200300 100 1 51 */ +498, /* OBJ_subtreeMaximumQuality 0 9 2342 19200300 100 1 52 */ +499, /* OBJ_personalSignature 0 9 2342 19200300 100 1 53 */ +500, /* OBJ_dITRedirect 0 9 2342 19200300 100 1 54 */ +501, /* OBJ_audio 0 9 2342 19200300 100 1 55 */ +502, /* OBJ_documentPublisher 0 9 2342 19200300 100 1 56 */ +442, /* OBJ_iA5StringSyntax 0 9 2342 19200300 100 3 4 */ +443, /* OBJ_caseIgnoreIA5StringSyntax 0 9 2342 19200300 100 3 5 */ +444, /* OBJ_pilotObject 0 9 2342 19200300 100 4 3 */ +445, /* OBJ_pilotPerson 0 9 2342 19200300 100 4 4 */ +446, /* OBJ_account 0 9 2342 19200300 100 4 5 */ +447, /* OBJ_document 0 9 2342 19200300 100 4 6 */ +448, /* OBJ_room 0 9 2342 19200300 100 4 7 */ +449, /* OBJ_documentSeries 0 9 2342 19200300 100 4 9 */ +392, /* OBJ_Domain 0 9 2342 19200300 100 4 13 */ +450, /* OBJ_rFC822localPart 0 9 2342 19200300 100 4 14 */ +451, /* OBJ_dNSDomain 0 9 2342 19200300 100 4 15 */ +452, /* OBJ_domainRelatedObject 0 9 2342 19200300 100 4 17 */ +453, /* OBJ_friendlyCountry 0 9 2342 19200300 100 4 18 */ +454, /* OBJ_simpleSecurityObject 0 9 2342 19200300 100 4 19 */ +455, /* OBJ_pilotOrganization 0 9 2342 19200300 100 4 20 */ +456, /* OBJ_pilotDSA 0 9 2342 19200300 100 4 21 */ +457, /* OBJ_qualityLabelledData 0 9 2342 19200300 100 4 22 */ +189, /* OBJ_id_smime_mod 1 2 840 113549 1 9 16 0 */ +190, /* OBJ_id_smime_ct 1 2 840 113549 1 9 16 1 */ +191, /* OBJ_id_smime_aa 1 2 840 113549 1 9 16 2 */ +192, /* OBJ_id_smime_alg 1 2 840 113549 1 9 16 3 */ +193, /* OBJ_id_smime_cd 1 2 840 113549 1 9 16 4 */ +194, /* OBJ_id_smime_spq 1 2 840 113549 1 9 16 5 */ +195, /* OBJ_id_smime_cti 1 2 840 113549 1 9 16 6 */ +158, /* OBJ_x509Certificate 1 2 840 113549 1 9 22 1 */ +159, /* OBJ_sdsiCertificate 1 2 840 113549 1 9 22 2 */ +160, /* OBJ_x509Crl 1 2 840 113549 1 9 23 1 */ +144, /* OBJ_pbe_WithSHA1And128BitRC4 1 2 840 113549 1 12 1 1 */ +145, /* OBJ_pbe_WithSHA1And40BitRC4 1 2 840 113549 1 12 1 2 */ +146, /* OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC 1 2 840 113549 1 12 1 3 */ +147, /* OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC 1 2 840 113549 1 12 1 4 */ +148, /* OBJ_pbe_WithSHA1And128BitRC2_CBC 1 2 840 113549 1 12 1 5 */ +149, /* OBJ_pbe_WithSHA1And40BitRC2_CBC 1 2 840 113549 1 12 1 6 */ +171, /* OBJ_ms_ext_req 1 3 6 1 4 1 311 2 1 14 */ +134, /* OBJ_ms_code_ind 1 3 6 1 4 1 311 2 1 21 */ +135, /* OBJ_ms_code_com 1 3 6 1 4 1 311 2 1 22 */ +136, /* OBJ_ms_ctl_sign 1 3 6 1 4 1 311 10 3 1 */ +137, /* OBJ_ms_sgc 1 3 6 1 4 1 311 10 3 3 */ +138, /* OBJ_ms_efs 1 3 6 1 4 1 311 10 3 4 */ +648, /* OBJ_ms_smartcard_login 1 3 6 1 4 1 311 20 2 2 */ +649, /* OBJ_ms_upn 1 3 6 1 4 1 311 20 2 3 */ +751, /* OBJ_camellia_128_cbc 1 2 392 200011 61 1 1 1 2 */ +752, /* OBJ_camellia_192_cbc 1 2 392 200011 61 1 1 1 3 */ +753, /* OBJ_camellia_256_cbc 1 2 392 200011 61 1 1 1 4 */ +907, /* OBJ_id_camellia128_wrap 1 2 392 200011 61 1 1 3 2 */ +908, /* OBJ_id_camellia192_wrap 1 2 392 200011 61 1 1 3 3 */ +909, /* OBJ_id_camellia256_wrap 1 2 392 200011 61 1 1 3 4 */ +196, /* OBJ_id_smime_mod_cms 1 2 840 113549 1 9 16 0 1 */ +197, /* OBJ_id_smime_mod_ess 1 2 840 113549 1 9 16 0 2 */ +198, /* OBJ_id_smime_mod_oid 1 2 840 113549 1 9 16 0 3 */ +199, /* OBJ_id_smime_mod_msg_v3 1 2 840 113549 1 9 16 0 4 */ +200, /* OBJ_id_smime_mod_ets_eSignature_88 1 2 840 113549 1 9 16 0 5 */ +201, /* OBJ_id_smime_mod_ets_eSignature_97 1 2 840 113549 1 9 16 0 6 */ +202, /* OBJ_id_smime_mod_ets_eSigPolicy_88 1 2 840 113549 1 9 16 0 7 */ +203, /* OBJ_id_smime_mod_ets_eSigPolicy_97 1 2 840 113549 1 9 16 0 8 */ +204, /* OBJ_id_smime_ct_receipt 1 2 840 113549 1 9 16 1 1 */ +205, /* OBJ_id_smime_ct_authData 1 2 840 113549 1 9 16 1 2 */ +206, /* OBJ_id_smime_ct_publishCert 1 2 840 113549 1 9 16 1 3 */ +207, /* OBJ_id_smime_ct_TSTInfo 1 2 840 113549 1 9 16 1 4 */ +208, /* OBJ_id_smime_ct_TDTInfo 1 2 840 113549 1 9 16 1 5 */ +209, /* OBJ_id_smime_ct_contentInfo 1 2 840 113549 1 9 16 1 6 */ +210, /* OBJ_id_smime_ct_DVCSRequestData 1 2 840 113549 1 9 16 1 7 */ +211, /* OBJ_id_smime_ct_DVCSResponseData 1 2 840 113549 1 9 16 1 8 */ +786, /* OBJ_id_smime_ct_compressedData 1 2 840 113549 1 9 16 1 9 */ +787, /* OBJ_id_ct_asciiTextWithCRLF 1 2 840 113549 1 9 16 1 27 */ +212, /* OBJ_id_smime_aa_receiptRequest 1 2 840 113549 1 9 16 2 1 */ +213, /* OBJ_id_smime_aa_securityLabel 1 2 840 113549 1 9 16 2 2 */ +214, /* OBJ_id_smime_aa_mlExpandHistory 1 2 840 113549 1 9 16 2 3 */ +215, /* OBJ_id_smime_aa_contentHint 1 2 840 113549 1 9 16 2 4 */ +216, /* OBJ_id_smime_aa_msgSigDigest 1 2 840 113549 1 9 16 2 5 */ +217, /* OBJ_id_smime_aa_encapContentType 1 2 840 113549 1 9 16 2 6 */ +218, /* OBJ_id_smime_aa_contentIdentifier 1 2 840 113549 1 9 16 2 7 */ +219, /* OBJ_id_smime_aa_macValue 1 2 840 113549 1 9 16 2 8 */ +220, /* OBJ_id_smime_aa_equivalentLabels 1 2 840 113549 1 9 16 2 9 */ +221, /* OBJ_id_smime_aa_contentReference 1 2 840 113549 1 9 16 2 10 */ +222, /* OBJ_id_smime_aa_encrypKeyPref 1 2 840 113549 1 9 16 2 11 */ +223, /* OBJ_id_smime_aa_signingCertificate 1 2 840 113549 1 9 16 2 12 */ +224, /* OBJ_id_smime_aa_smimeEncryptCerts 1 2 840 113549 1 9 16 2 13 */ +225, /* OBJ_id_smime_aa_timeStampToken 1 2 840 113549 1 9 16 2 14 */ +226, /* OBJ_id_smime_aa_ets_sigPolicyId 1 2 840 113549 1 9 16 2 15 */ +227, /* OBJ_id_smime_aa_ets_commitmentType 1 2 840 113549 1 9 16 2 16 */ +228, /* OBJ_id_smime_aa_ets_signerLocation 1 2 840 113549 1 9 16 2 17 */ +229, /* OBJ_id_smime_aa_ets_signerAttr 1 2 840 113549 1 9 16 2 18 */ +230, /* OBJ_id_smime_aa_ets_otherSigCert 1 2 840 113549 1 9 16 2 19 */ +231, /* OBJ_id_smime_aa_ets_contentTimestamp 1 2 840 113549 1 9 16 2 20 */ +232, /* OBJ_id_smime_aa_ets_CertificateRefs 1 2 840 113549 1 9 16 2 21 */ +233, /* OBJ_id_smime_aa_ets_RevocationRefs 1 2 840 113549 1 9 16 2 22 */ +234, /* OBJ_id_smime_aa_ets_certValues 1 2 840 113549 1 9 16 2 23 */ +235, /* OBJ_id_smime_aa_ets_revocationValues 1 2 840 113549 1 9 16 2 24 */ +236, /* OBJ_id_smime_aa_ets_escTimeStamp 1 2 840 113549 1 9 16 2 25 */ +237, /* OBJ_id_smime_aa_ets_certCRLTimestamp 1 2 840 113549 1 9 16 2 26 */ +238, /* OBJ_id_smime_aa_ets_archiveTimeStamp 1 2 840 113549 1 9 16 2 27 */ +239, /* OBJ_id_smime_aa_signatureType 1 2 840 113549 1 9 16 2 28 */ +240, /* OBJ_id_smime_aa_dvcs_dvc 1 2 840 113549 1 9 16 2 29 */ +241, /* OBJ_id_smime_alg_ESDHwith3DES 1 2 840 113549 1 9 16 3 1 */ +242, /* OBJ_id_smime_alg_ESDHwithRC2 1 2 840 113549 1 9 16 3 2 */ +243, /* OBJ_id_smime_alg_3DESwrap 1 2 840 113549 1 9 16 3 3 */ +244, /* OBJ_id_smime_alg_RC2wrap 1 2 840 113549 1 9 16 3 4 */ +245, /* OBJ_id_smime_alg_ESDH 1 2 840 113549 1 9 16 3 5 */ +246, /* OBJ_id_smime_alg_CMS3DESwrap 1 2 840 113549 1 9 16 3 6 */ +247, /* OBJ_id_smime_alg_CMSRC2wrap 1 2 840 113549 1 9 16 3 7 */ +125, /* OBJ_zlib_compression 1 2 840 113549 1 9 16 3 8 */ +893, /* OBJ_id_alg_PWRI_KEK 1 2 840 113549 1 9 16 3 9 */ +248, /* OBJ_id_smime_cd_ldap 1 2 840 113549 1 9 16 4 1 */ +249, /* OBJ_id_smime_spq_ets_sqt_uri 1 2 840 113549 1 9 16 5 1 */ +250, /* OBJ_id_smime_spq_ets_sqt_unotice 1 2 840 113549 1 9 16 5 2 */ +251, /* OBJ_id_smime_cti_ets_proofOfOrigin 1 2 840 113549 1 9 16 6 1 */ +252, /* OBJ_id_smime_cti_ets_proofOfReceipt 1 2 840 113549 1 9 16 6 2 */ +253, /* OBJ_id_smime_cti_ets_proofOfDelivery 1 2 840 113549 1 9 16 6 3 */ +254, /* OBJ_id_smime_cti_ets_proofOfSender 1 2 840 113549 1 9 16 6 4 */ +255, /* OBJ_id_smime_cti_ets_proofOfApproval 1 2 840 113549 1 9 16 6 5 */ +256, /* OBJ_id_smime_cti_ets_proofOfCreation 1 2 840 113549 1 9 16 6 6 */ +150, /* OBJ_keyBag 1 2 840 113549 1 12 10 1 1 */ +151, /* OBJ_pkcs8ShroudedKeyBag 1 2 840 113549 1 12 10 1 2 */ +152, /* OBJ_certBag 1 2 840 113549 1 12 10 1 3 */ +153, /* OBJ_crlBag 1 2 840 113549 1 12 10 1 4 */ +154, /* OBJ_secretBag 1 2 840 113549 1 12 10 1 5 */ +155, /* OBJ_safeContentsBag 1 2 840 113549 1 12 10 1 6 */ +34, /* OBJ_idea_cbc 1 3 6 1 4 1 188 7 1 1 2 */ +}; + diff --git a/libs/openssl/crypto/objects/obj_dat.pl b/libs/openssl/crypto/objects/obj_dat.pl new file mode 100644 index 00000000..86bcefb9 --- /dev/null +++ b/libs/openssl/crypto/objects/obj_dat.pl @@ -0,0 +1,307 @@ +#!/usr/local/bin/perl + +# fixes bug in floating point emulation on sparc64 when +# this script produces off-by-one output on sparc64 +use integer; + +sub obj_cmp + { + local(@a,@b,$_,$r); + + $A=$obj_len{$obj{$nid{$a}}}; + $B=$obj_len{$obj{$nid{$b}}}; + + $r=($A-$B); + return($r) if $r != 0; + + $A=$obj_der{$obj{$nid{$a}}}; + $B=$obj_der{$obj{$nid{$b}}}; + + return($A cmp $B); + } + +sub expand_obj + { + local(*v)=@_; + local($k,$d); + local($i); + + do { + $i=0; + foreach $k (keys %v) + { + if (($v{$k} =~ s/(OBJ_[^,]+),/$v{$1},/)) + { $i++; } + } + } while($i); + foreach $k (keys %v) + { + @a=split(/,/,$v{$k}); + $objn{$k}=$#a+1; + } + return(%objn); + } + +open (IN,"$ARGV[0]") || die "Can't open input file $ARGV[0]"; +open (OUT,">$ARGV[1]") || die "Can't open output file $ARGV[1]"; + +while () + { + next unless /^\#define\s+(\S+)\s+(.*)$/; + $v=$1; + $d=$2; + $d =~ s/^\"//; + $d =~ s/\"$//; + if ($v =~ /^SN_(.*)$/) + { + if(defined $snames{$d}) + { + print "WARNING: Duplicate short name \"$d\"\n"; + } + else + { $snames{$d} = "X"; } + $sn{$1}=$d; + } + elsif ($v =~ /^LN_(.*)$/) + { + if(defined $lnames{$d}) + { + print "WARNING: Duplicate long name \"$d\"\n"; + } + else + { $lnames{$d} = "X"; } + $ln{$1}=$d; + } + elsif ($v =~ /^NID_(.*)$/) + { $nid{$d}=$1; } + elsif ($v =~ /^OBJ_(.*)$/) + { + $obj{$1}=$v; + $objd{$v}=$d; + } + } +close IN; + +%ob=&expand_obj(*objd); + +@a=sort { $a <=> $b } keys %nid; +$n=$a[$#a]+1; + +@lvalues=(); +$lvalues=0; + +for ($i=0; $i<$n; $i++) + { + if (!defined($nid{$i})) + { + push(@out,"{NULL,NULL,NID_undef,0,NULL,0},\n"); + } + else + { + $sn=defined($sn{$nid{$i}})?"$sn{$nid{$i}}":"NULL"; + $ln=defined($ln{$nid{$i}})?"$ln{$nid{$i}}":"NULL"; + + if ($sn eq "NULL") { + $sn=$ln; + $sn{$nid{$i}} = $ln; + } + + if ($ln eq "NULL") { + $ln=$sn; + $ln{$nid{$i}} = $sn; + } + + $out ="{"; + $out.="\"$sn\""; + $out.=","."\"$ln\""; + $out.=",NID_$nid{$i},"; + if (defined($obj{$nid{$i}}) && $objd{$obj{$nid{$i}}} =~ /,/) + { + $v=$objd{$obj{$nid{$i}}}; + $v =~ s/L//g; + $v =~ s/,/ /g; + $r=&der_it($v); + $z=""; + $length=0; + foreach (unpack("C*",$r)) + { + $z.=sprintf("0x%02X,",$_); + $length++; + } + $obj_der{$obj{$nid{$i}}}=$z; + $obj_len{$obj{$nid{$i}}}=$length; + + push(@lvalues,sprintf("%-45s/* [%3d] %s */\n", + $z,$lvalues,$obj{$nid{$i}})); + $out.="$length,&(lvalues[$lvalues]),0"; + $lvalues+=$length; + } + else + { + $out.="0,NULL,0"; + } + $out.="},\n"; + push(@out,$out); + } + } + +@a=grep(defined($sn{$nid{$_}}),0 .. $n); +foreach (sort { $sn{$nid{$a}} cmp $sn{$nid{$b}} } @a) + { + push(@sn,sprintf("%2d,\t/* \"$sn{$nid{$_}}\" */\n",$_)); + } + +@a=grep(defined($ln{$nid{$_}}),0 .. $n); +foreach (sort { $ln{$nid{$a}} cmp $ln{$nid{$b}} } @a) + { + push(@ln,sprintf("%2d,\t/* \"$ln{$nid{$_}}\" */\n",$_)); + } + +@a=grep(defined($obj{$nid{$_}}),0 .. $n); +foreach (sort obj_cmp @a) + { + $m=$obj{$nid{$_}}; + $v=$objd{$m}; + $v =~ s/L//g; + $v =~ s/,/ /g; + push(@ob,sprintf("%2d,\t/* %-32s %s */\n",$_,$m,$v)); + } + +print OUT <<'EOF'; +/* crypto/objects/obj_dat.h */ + +/* THIS FILE IS GENERATED FROM objects.h by obj_dat.pl via the + * following command: + * perl obj_dat.pl obj_mac.h obj_dat.h + */ + +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +EOF + +printf OUT "#define NUM_NID %d\n",$n; +printf OUT "#define NUM_SN %d\n",$#sn+1; +printf OUT "#define NUM_LN %d\n",$#ln+1; +printf OUT "#define NUM_OBJ %d\n\n",$#ob+1; + +printf OUT "static const unsigned char lvalues[%d]={\n",$lvalues+1; +print OUT @lvalues; +print OUT "};\n\n"; + +printf OUT "static const ASN1_OBJECT nid_objs[NUM_NID]={\n"; +foreach (@out) + { + if (length($_) > 75) + { + $out=""; + foreach (split(/,/)) + { + $t=$out.$_.","; + if (length($t) > 70) + { + print OUT "$out\n"; + $t="\t$_,"; + } + $out=$t; + } + chop $out; + print OUT "$out"; + } + else + { print OUT $_; } + } +print OUT "};\n\n"; + +printf OUT "static const unsigned int sn_objs[NUM_SN]={\n"; +print OUT @sn; +print OUT "};\n\n"; + +printf OUT "static const unsigned int ln_objs[NUM_LN]={\n"; +print OUT @ln; +print OUT "};\n\n"; + +printf OUT "static const unsigned int obj_objs[NUM_OBJ]={\n"; +print OUT @ob; +print OUT "};\n\n"; + +close OUT; + +sub der_it + { + local($v)=@_; + local(@a,$i,$ret,@r); + + @a=split(/\s+/,$v); + $ret.=pack("C*",$a[0]*40+$a[1]); + shift @a; + shift @a; + foreach (@a) + { + @r=(); + $t=0; + while ($_ >= 128) + { + $x=$_%128; + $_/=128; + push(@r,((($t++)?0x80:0)|$x)); + } + push(@r,((($t++)?0x80:0)|$_)); + $ret.=pack("C*",reverse(@r)); + } + return($ret); + } diff --git a/libs/openssl/crypto/objects/obj_err.c b/libs/openssl/crypto/objects/obj_err.c new file mode 100644 index 00000000..238aaa59 --- /dev/null +++ b/libs/openssl/crypto/objects/obj_err.c @@ -0,0 +1,100 @@ +/* crypto/objects/obj_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_OBJ,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_OBJ,0,reason) + +static ERR_STRING_DATA OBJ_str_functs[] = { + {ERR_FUNC(OBJ_F_OBJ_ADD_OBJECT), "OBJ_add_object"}, + {ERR_FUNC(OBJ_F_OBJ_CREATE), "OBJ_create"}, + {ERR_FUNC(OBJ_F_OBJ_DUP), "OBJ_dup"}, + {ERR_FUNC(OBJ_F_OBJ_NAME_NEW_INDEX), "OBJ_NAME_new_index"}, + {ERR_FUNC(OBJ_F_OBJ_NID2LN), "OBJ_nid2ln"}, + {ERR_FUNC(OBJ_F_OBJ_NID2OBJ), "OBJ_nid2obj"}, + {ERR_FUNC(OBJ_F_OBJ_NID2SN), "OBJ_nid2sn"}, + {0, NULL} +}; + +static ERR_STRING_DATA OBJ_str_reasons[] = { + {ERR_REASON(OBJ_R_MALLOC_FAILURE), "malloc failure"}, + {ERR_REASON(OBJ_R_UNKNOWN_NID), "unknown nid"}, + {0, NULL} +}; + +#endif + +void ERR_load_OBJ_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(OBJ_str_functs[0].error) == NULL) { + ERR_load_strings(0, OBJ_str_functs); + ERR_load_strings(0, OBJ_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/objects/obj_lib.c b/libs/openssl/crypto/objects/obj_lib.c new file mode 100644 index 00000000..8851baff --- /dev/null +++ b/libs/openssl/crypto/objects/obj_lib.c @@ -0,0 +1,135 @@ +/* crypto/objects/obj_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) +{ + ASN1_OBJECT *r; + int i; + char *ln = NULL, *sn = NULL; + unsigned char *data = NULL; + + if (o == NULL) + return (NULL); + if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) + return ((ASN1_OBJECT *)o); /* XXX: ugh! Why? What kind of duplication + * is this??? */ + + r = ASN1_OBJECT_new(); + if (r == NULL) { + OBJerr(OBJ_F_OBJ_DUP, ERR_R_ASN1_LIB); + return (NULL); + } + data = OPENSSL_malloc(o->length); + if (data == NULL) + goto err; + if (o->data != NULL) + memcpy(data, o->data, o->length); + /* once data attached to object it remains const */ + r->data = data; + r->length = o->length; + r->nid = o->nid; + r->ln = r->sn = NULL; + if (o->ln != NULL) { + i = strlen(o->ln) + 1; + ln = OPENSSL_malloc(i); + if (ln == NULL) + goto err; + memcpy(ln, o->ln, i); + r->ln = ln; + } + + if (o->sn != NULL) { + i = strlen(o->sn) + 1; + sn = OPENSSL_malloc(i); + if (sn == NULL) + goto err; + memcpy(sn, o->sn, i); + r->sn = sn; + } + r->flags = o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | + ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA); + return (r); + err: + OBJerr(OBJ_F_OBJ_DUP, ERR_R_MALLOC_FAILURE); + if (ln != NULL) + OPENSSL_free(ln); + if (sn != NULL) + OPENSSL_free(sn); + if (data != NULL) + OPENSSL_free(data); + if (r != NULL) + OPENSSL_free(r); + return (NULL); +} + +int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b) +{ + int ret; + + ret = (a->length - b->length); + if (ret) + return (ret); + return (memcmp(a->data, b->data, a->length)); +} diff --git a/libs/openssl/crypto/objects/obj_mac.h b/libs/openssl/crypto/objects/obj_mac.h new file mode 100644 index 00000000..f752aeff --- /dev/null +++ b/libs/openssl/crypto/objects/obj_mac.h @@ -0,0 +1,4031 @@ +/* crypto/objects/obj_mac.h */ + +/* + * THIS FILE IS GENERATED FROM objects.txt by objects.pl via the following + * command: perl objects.pl objects.txt obj_mac.num obj_mac.h + */ + +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +#define SN_itu_t "ITU-T" +#define LN_itu_t "itu-t" +#define NID_itu_t 645 +#define OBJ_itu_t 0L + +#define NID_ccitt 404 +#define OBJ_ccitt OBJ_itu_t + +#define SN_iso "ISO" +#define LN_iso "iso" +#define NID_iso 181 +#define OBJ_iso 1L + +#define SN_joint_iso_itu_t "JOINT-ISO-ITU-T" +#define LN_joint_iso_itu_t "joint-iso-itu-t" +#define NID_joint_iso_itu_t 646 +#define OBJ_joint_iso_itu_t 2L + +#define NID_joint_iso_ccitt 393 +#define OBJ_joint_iso_ccitt OBJ_joint_iso_itu_t + +#define SN_member_body "member-body" +#define LN_member_body "ISO Member Body" +#define NID_member_body 182 +#define OBJ_member_body OBJ_iso,2L + +#define SN_identified_organization "identified-organization" +#define NID_identified_organization 676 +#define OBJ_identified_organization OBJ_iso,3L + +#define SN_hmac_md5 "HMAC-MD5" +#define LN_hmac_md5 "hmac-md5" +#define NID_hmac_md5 780 +#define OBJ_hmac_md5 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,1L + +#define SN_hmac_sha1 "HMAC-SHA1" +#define LN_hmac_sha1 "hmac-sha1" +#define NID_hmac_sha1 781 +#define OBJ_hmac_sha1 OBJ_identified_organization,6L,1L,5L,5L,8L,1L,2L + +#define SN_certicom_arc "certicom-arc" +#define NID_certicom_arc 677 +#define OBJ_certicom_arc OBJ_identified_organization,132L + +#define SN_international_organizations "international-organizations" +#define LN_international_organizations "International Organizations" +#define NID_international_organizations 647 +#define OBJ_international_organizations OBJ_joint_iso_itu_t,23L + +#define SN_wap "wap" +#define NID_wap 678 +#define OBJ_wap OBJ_international_organizations,43L + +#define SN_wap_wsg "wap-wsg" +#define NID_wap_wsg 679 +#define OBJ_wap_wsg OBJ_wap,1L + +#define SN_selected_attribute_types "selected-attribute-types" +#define LN_selected_attribute_types "Selected Attribute Types" +#define NID_selected_attribute_types 394 +#define OBJ_selected_attribute_types OBJ_joint_iso_itu_t,5L,1L,5L + +#define SN_clearance "clearance" +#define NID_clearance 395 +#define OBJ_clearance OBJ_selected_attribute_types,55L + +#define SN_ISO_US "ISO-US" +#define LN_ISO_US "ISO US Member Body" +#define NID_ISO_US 183 +#define OBJ_ISO_US OBJ_member_body,840L + +#define SN_X9_57 "X9-57" +#define LN_X9_57 "X9.57" +#define NID_X9_57 184 +#define OBJ_X9_57 OBJ_ISO_US,10040L + +#define SN_X9cm "X9cm" +#define LN_X9cm "X9.57 CM ?" +#define NID_X9cm 185 +#define OBJ_X9cm OBJ_X9_57,4L + +#define SN_dsa "DSA" +#define LN_dsa "dsaEncryption" +#define NID_dsa 116 +#define OBJ_dsa OBJ_X9cm,1L + +#define SN_dsaWithSHA1 "DSA-SHA1" +#define LN_dsaWithSHA1 "dsaWithSHA1" +#define NID_dsaWithSHA1 113 +#define OBJ_dsaWithSHA1 OBJ_X9cm,3L + +#define SN_ansi_X9_62 "ansi-X9-62" +#define LN_ansi_X9_62 "ANSI X9.62" +#define NID_ansi_X9_62 405 +#define OBJ_ansi_X9_62 OBJ_ISO_US,10045L + +#define OBJ_X9_62_id_fieldType OBJ_ansi_X9_62,1L + +#define SN_X9_62_prime_field "prime-field" +#define NID_X9_62_prime_field 406 +#define OBJ_X9_62_prime_field OBJ_X9_62_id_fieldType,1L + +#define SN_X9_62_characteristic_two_field "characteristic-two-field" +#define NID_X9_62_characteristic_two_field 407 +#define OBJ_X9_62_characteristic_two_field OBJ_X9_62_id_fieldType,2L + +#define SN_X9_62_id_characteristic_two_basis "id-characteristic-two-basis" +#define NID_X9_62_id_characteristic_two_basis 680 +#define OBJ_X9_62_id_characteristic_two_basis OBJ_X9_62_characteristic_two_field,3L + +#define SN_X9_62_onBasis "onBasis" +#define NID_X9_62_onBasis 681 +#define OBJ_X9_62_onBasis OBJ_X9_62_id_characteristic_two_basis,1L + +#define SN_X9_62_tpBasis "tpBasis" +#define NID_X9_62_tpBasis 682 +#define OBJ_X9_62_tpBasis OBJ_X9_62_id_characteristic_two_basis,2L + +#define SN_X9_62_ppBasis "ppBasis" +#define NID_X9_62_ppBasis 683 +#define OBJ_X9_62_ppBasis OBJ_X9_62_id_characteristic_two_basis,3L + +#define OBJ_X9_62_id_publicKeyType OBJ_ansi_X9_62,2L + +#define SN_X9_62_id_ecPublicKey "id-ecPublicKey" +#define NID_X9_62_id_ecPublicKey 408 +#define OBJ_X9_62_id_ecPublicKey OBJ_X9_62_id_publicKeyType,1L + +#define OBJ_X9_62_ellipticCurve OBJ_ansi_X9_62,3L + +#define OBJ_X9_62_c_TwoCurve OBJ_X9_62_ellipticCurve,0L + +#define SN_X9_62_c2pnb163v1 "c2pnb163v1" +#define NID_X9_62_c2pnb163v1 684 +#define OBJ_X9_62_c2pnb163v1 OBJ_X9_62_c_TwoCurve,1L + +#define SN_X9_62_c2pnb163v2 "c2pnb163v2" +#define NID_X9_62_c2pnb163v2 685 +#define OBJ_X9_62_c2pnb163v2 OBJ_X9_62_c_TwoCurve,2L + +#define SN_X9_62_c2pnb163v3 "c2pnb163v3" +#define NID_X9_62_c2pnb163v3 686 +#define OBJ_X9_62_c2pnb163v3 OBJ_X9_62_c_TwoCurve,3L + +#define SN_X9_62_c2pnb176v1 "c2pnb176v1" +#define NID_X9_62_c2pnb176v1 687 +#define OBJ_X9_62_c2pnb176v1 OBJ_X9_62_c_TwoCurve,4L + +#define SN_X9_62_c2tnb191v1 "c2tnb191v1" +#define NID_X9_62_c2tnb191v1 688 +#define OBJ_X9_62_c2tnb191v1 OBJ_X9_62_c_TwoCurve,5L + +#define SN_X9_62_c2tnb191v2 "c2tnb191v2" +#define NID_X9_62_c2tnb191v2 689 +#define OBJ_X9_62_c2tnb191v2 OBJ_X9_62_c_TwoCurve,6L + +#define SN_X9_62_c2tnb191v3 "c2tnb191v3" +#define NID_X9_62_c2tnb191v3 690 +#define OBJ_X9_62_c2tnb191v3 OBJ_X9_62_c_TwoCurve,7L + +#define SN_X9_62_c2onb191v4 "c2onb191v4" +#define NID_X9_62_c2onb191v4 691 +#define OBJ_X9_62_c2onb191v4 OBJ_X9_62_c_TwoCurve,8L + +#define SN_X9_62_c2onb191v5 "c2onb191v5" +#define NID_X9_62_c2onb191v5 692 +#define OBJ_X9_62_c2onb191v5 OBJ_X9_62_c_TwoCurve,9L + +#define SN_X9_62_c2pnb208w1 "c2pnb208w1" +#define NID_X9_62_c2pnb208w1 693 +#define OBJ_X9_62_c2pnb208w1 OBJ_X9_62_c_TwoCurve,10L + +#define SN_X9_62_c2tnb239v1 "c2tnb239v1" +#define NID_X9_62_c2tnb239v1 694 +#define OBJ_X9_62_c2tnb239v1 OBJ_X9_62_c_TwoCurve,11L + +#define SN_X9_62_c2tnb239v2 "c2tnb239v2" +#define NID_X9_62_c2tnb239v2 695 +#define OBJ_X9_62_c2tnb239v2 OBJ_X9_62_c_TwoCurve,12L + +#define SN_X9_62_c2tnb239v3 "c2tnb239v3" +#define NID_X9_62_c2tnb239v3 696 +#define OBJ_X9_62_c2tnb239v3 OBJ_X9_62_c_TwoCurve,13L + +#define SN_X9_62_c2onb239v4 "c2onb239v4" +#define NID_X9_62_c2onb239v4 697 +#define OBJ_X9_62_c2onb239v4 OBJ_X9_62_c_TwoCurve,14L + +#define SN_X9_62_c2onb239v5 "c2onb239v5" +#define NID_X9_62_c2onb239v5 698 +#define OBJ_X9_62_c2onb239v5 OBJ_X9_62_c_TwoCurve,15L + +#define SN_X9_62_c2pnb272w1 "c2pnb272w1" +#define NID_X9_62_c2pnb272w1 699 +#define OBJ_X9_62_c2pnb272w1 OBJ_X9_62_c_TwoCurve,16L + +#define SN_X9_62_c2pnb304w1 "c2pnb304w1" +#define NID_X9_62_c2pnb304w1 700 +#define OBJ_X9_62_c2pnb304w1 OBJ_X9_62_c_TwoCurve,17L + +#define SN_X9_62_c2tnb359v1 "c2tnb359v1" +#define NID_X9_62_c2tnb359v1 701 +#define OBJ_X9_62_c2tnb359v1 OBJ_X9_62_c_TwoCurve,18L + +#define SN_X9_62_c2pnb368w1 "c2pnb368w1" +#define NID_X9_62_c2pnb368w1 702 +#define OBJ_X9_62_c2pnb368w1 OBJ_X9_62_c_TwoCurve,19L + +#define SN_X9_62_c2tnb431r1 "c2tnb431r1" +#define NID_X9_62_c2tnb431r1 703 +#define OBJ_X9_62_c2tnb431r1 OBJ_X9_62_c_TwoCurve,20L + +#define OBJ_X9_62_primeCurve OBJ_X9_62_ellipticCurve,1L + +#define SN_X9_62_prime192v1 "prime192v1" +#define NID_X9_62_prime192v1 409 +#define OBJ_X9_62_prime192v1 OBJ_X9_62_primeCurve,1L + +#define SN_X9_62_prime192v2 "prime192v2" +#define NID_X9_62_prime192v2 410 +#define OBJ_X9_62_prime192v2 OBJ_X9_62_primeCurve,2L + +#define SN_X9_62_prime192v3 "prime192v3" +#define NID_X9_62_prime192v3 411 +#define OBJ_X9_62_prime192v3 OBJ_X9_62_primeCurve,3L + +#define SN_X9_62_prime239v1 "prime239v1" +#define NID_X9_62_prime239v1 412 +#define OBJ_X9_62_prime239v1 OBJ_X9_62_primeCurve,4L + +#define SN_X9_62_prime239v2 "prime239v2" +#define NID_X9_62_prime239v2 413 +#define OBJ_X9_62_prime239v2 OBJ_X9_62_primeCurve,5L + +#define SN_X9_62_prime239v3 "prime239v3" +#define NID_X9_62_prime239v3 414 +#define OBJ_X9_62_prime239v3 OBJ_X9_62_primeCurve,6L + +#define SN_X9_62_prime256v1 "prime256v1" +#define NID_X9_62_prime256v1 415 +#define OBJ_X9_62_prime256v1 OBJ_X9_62_primeCurve,7L + +#define OBJ_X9_62_id_ecSigType OBJ_ansi_X9_62,4L + +#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1" +#define NID_ecdsa_with_SHA1 416 +#define OBJ_ecdsa_with_SHA1 OBJ_X9_62_id_ecSigType,1L + +#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended" +#define NID_ecdsa_with_Recommended 791 +#define OBJ_ecdsa_with_Recommended OBJ_X9_62_id_ecSigType,2L + +#define SN_ecdsa_with_Specified "ecdsa-with-Specified" +#define NID_ecdsa_with_Specified 792 +#define OBJ_ecdsa_with_Specified OBJ_X9_62_id_ecSigType,3L + +#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224" +#define NID_ecdsa_with_SHA224 793 +#define OBJ_ecdsa_with_SHA224 OBJ_ecdsa_with_Specified,1L + +#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256" +#define NID_ecdsa_with_SHA256 794 +#define OBJ_ecdsa_with_SHA256 OBJ_ecdsa_with_Specified,2L + +#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384" +#define NID_ecdsa_with_SHA384 795 +#define OBJ_ecdsa_with_SHA384 OBJ_ecdsa_with_Specified,3L + +#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512" +#define NID_ecdsa_with_SHA512 796 +#define OBJ_ecdsa_with_SHA512 OBJ_ecdsa_with_Specified,4L + +#define OBJ_secg_ellipticCurve OBJ_certicom_arc,0L + +#define SN_secp112r1 "secp112r1" +#define NID_secp112r1 704 +#define OBJ_secp112r1 OBJ_secg_ellipticCurve,6L + +#define SN_secp112r2 "secp112r2" +#define NID_secp112r2 705 +#define OBJ_secp112r2 OBJ_secg_ellipticCurve,7L + +#define SN_secp128r1 "secp128r1" +#define NID_secp128r1 706 +#define OBJ_secp128r1 OBJ_secg_ellipticCurve,28L + +#define SN_secp128r2 "secp128r2" +#define NID_secp128r2 707 +#define OBJ_secp128r2 OBJ_secg_ellipticCurve,29L + +#define SN_secp160k1 "secp160k1" +#define NID_secp160k1 708 +#define OBJ_secp160k1 OBJ_secg_ellipticCurve,9L + +#define SN_secp160r1 "secp160r1" +#define NID_secp160r1 709 +#define OBJ_secp160r1 OBJ_secg_ellipticCurve,8L + +#define SN_secp160r2 "secp160r2" +#define NID_secp160r2 710 +#define OBJ_secp160r2 OBJ_secg_ellipticCurve,30L + +#define SN_secp192k1 "secp192k1" +#define NID_secp192k1 711 +#define OBJ_secp192k1 OBJ_secg_ellipticCurve,31L + +#define SN_secp224k1 "secp224k1" +#define NID_secp224k1 712 +#define OBJ_secp224k1 OBJ_secg_ellipticCurve,32L + +#define SN_secp224r1 "secp224r1" +#define NID_secp224r1 713 +#define OBJ_secp224r1 OBJ_secg_ellipticCurve,33L + +#define SN_secp256k1 "secp256k1" +#define NID_secp256k1 714 +#define OBJ_secp256k1 OBJ_secg_ellipticCurve,10L + +#define SN_secp384r1 "secp384r1" +#define NID_secp384r1 715 +#define OBJ_secp384r1 OBJ_secg_ellipticCurve,34L + +#define SN_secp521r1 "secp521r1" +#define NID_secp521r1 716 +#define OBJ_secp521r1 OBJ_secg_ellipticCurve,35L + +#define SN_sect113r1 "sect113r1" +#define NID_sect113r1 717 +#define OBJ_sect113r1 OBJ_secg_ellipticCurve,4L + +#define SN_sect113r2 "sect113r2" +#define NID_sect113r2 718 +#define OBJ_sect113r2 OBJ_secg_ellipticCurve,5L + +#define SN_sect131r1 "sect131r1" +#define NID_sect131r1 719 +#define OBJ_sect131r1 OBJ_secg_ellipticCurve,22L + +#define SN_sect131r2 "sect131r2" +#define NID_sect131r2 720 +#define OBJ_sect131r2 OBJ_secg_ellipticCurve,23L + +#define SN_sect163k1 "sect163k1" +#define NID_sect163k1 721 +#define OBJ_sect163k1 OBJ_secg_ellipticCurve,1L + +#define SN_sect163r1 "sect163r1" +#define NID_sect163r1 722 +#define OBJ_sect163r1 OBJ_secg_ellipticCurve,2L + +#define SN_sect163r2 "sect163r2" +#define NID_sect163r2 723 +#define OBJ_sect163r2 OBJ_secg_ellipticCurve,15L + +#define SN_sect193r1 "sect193r1" +#define NID_sect193r1 724 +#define OBJ_sect193r1 OBJ_secg_ellipticCurve,24L + +#define SN_sect193r2 "sect193r2" +#define NID_sect193r2 725 +#define OBJ_sect193r2 OBJ_secg_ellipticCurve,25L + +#define SN_sect233k1 "sect233k1" +#define NID_sect233k1 726 +#define OBJ_sect233k1 OBJ_secg_ellipticCurve,26L + +#define SN_sect233r1 "sect233r1" +#define NID_sect233r1 727 +#define OBJ_sect233r1 OBJ_secg_ellipticCurve,27L + +#define SN_sect239k1 "sect239k1" +#define NID_sect239k1 728 +#define OBJ_sect239k1 OBJ_secg_ellipticCurve,3L + +#define SN_sect283k1 "sect283k1" +#define NID_sect283k1 729 +#define OBJ_sect283k1 OBJ_secg_ellipticCurve,16L + +#define SN_sect283r1 "sect283r1" +#define NID_sect283r1 730 +#define OBJ_sect283r1 OBJ_secg_ellipticCurve,17L + +#define SN_sect409k1 "sect409k1" +#define NID_sect409k1 731 +#define OBJ_sect409k1 OBJ_secg_ellipticCurve,36L + +#define SN_sect409r1 "sect409r1" +#define NID_sect409r1 732 +#define OBJ_sect409r1 OBJ_secg_ellipticCurve,37L + +#define SN_sect571k1 "sect571k1" +#define NID_sect571k1 733 +#define OBJ_sect571k1 OBJ_secg_ellipticCurve,38L + +#define SN_sect571r1 "sect571r1" +#define NID_sect571r1 734 +#define OBJ_sect571r1 OBJ_secg_ellipticCurve,39L + +#define OBJ_wap_wsg_idm_ecid OBJ_wap_wsg,4L + +#define SN_wap_wsg_idm_ecid_wtls1 "wap-wsg-idm-ecid-wtls1" +#define NID_wap_wsg_idm_ecid_wtls1 735 +#define OBJ_wap_wsg_idm_ecid_wtls1 OBJ_wap_wsg_idm_ecid,1L + +#define SN_wap_wsg_idm_ecid_wtls3 "wap-wsg-idm-ecid-wtls3" +#define NID_wap_wsg_idm_ecid_wtls3 736 +#define OBJ_wap_wsg_idm_ecid_wtls3 OBJ_wap_wsg_idm_ecid,3L + +#define SN_wap_wsg_idm_ecid_wtls4 "wap-wsg-idm-ecid-wtls4" +#define NID_wap_wsg_idm_ecid_wtls4 737 +#define OBJ_wap_wsg_idm_ecid_wtls4 OBJ_wap_wsg_idm_ecid,4L + +#define SN_wap_wsg_idm_ecid_wtls5 "wap-wsg-idm-ecid-wtls5" +#define NID_wap_wsg_idm_ecid_wtls5 738 +#define OBJ_wap_wsg_idm_ecid_wtls5 OBJ_wap_wsg_idm_ecid,5L + +#define SN_wap_wsg_idm_ecid_wtls6 "wap-wsg-idm-ecid-wtls6" +#define NID_wap_wsg_idm_ecid_wtls6 739 +#define OBJ_wap_wsg_idm_ecid_wtls6 OBJ_wap_wsg_idm_ecid,6L + +#define SN_wap_wsg_idm_ecid_wtls7 "wap-wsg-idm-ecid-wtls7" +#define NID_wap_wsg_idm_ecid_wtls7 740 +#define OBJ_wap_wsg_idm_ecid_wtls7 OBJ_wap_wsg_idm_ecid,7L + +#define SN_wap_wsg_idm_ecid_wtls8 "wap-wsg-idm-ecid-wtls8" +#define NID_wap_wsg_idm_ecid_wtls8 741 +#define OBJ_wap_wsg_idm_ecid_wtls8 OBJ_wap_wsg_idm_ecid,8L + +#define SN_wap_wsg_idm_ecid_wtls9 "wap-wsg-idm-ecid-wtls9" +#define NID_wap_wsg_idm_ecid_wtls9 742 +#define OBJ_wap_wsg_idm_ecid_wtls9 OBJ_wap_wsg_idm_ecid,9L + +#define SN_wap_wsg_idm_ecid_wtls10 "wap-wsg-idm-ecid-wtls10" +#define NID_wap_wsg_idm_ecid_wtls10 743 +#define OBJ_wap_wsg_idm_ecid_wtls10 OBJ_wap_wsg_idm_ecid,10L + +#define SN_wap_wsg_idm_ecid_wtls11 "wap-wsg-idm-ecid-wtls11" +#define NID_wap_wsg_idm_ecid_wtls11 744 +#define OBJ_wap_wsg_idm_ecid_wtls11 OBJ_wap_wsg_idm_ecid,11L + +#define SN_wap_wsg_idm_ecid_wtls12 "wap-wsg-idm-ecid-wtls12" +#define NID_wap_wsg_idm_ecid_wtls12 745 +#define OBJ_wap_wsg_idm_ecid_wtls12 OBJ_wap_wsg_idm_ecid,12L + +#define SN_cast5_cbc "CAST5-CBC" +#define LN_cast5_cbc "cast5-cbc" +#define NID_cast5_cbc 108 +#define OBJ_cast5_cbc OBJ_ISO_US,113533L,7L,66L,10L + +#define SN_cast5_ecb "CAST5-ECB" +#define LN_cast5_ecb "cast5-ecb" +#define NID_cast5_ecb 109 + +#define SN_cast5_cfb64 "CAST5-CFB" +#define LN_cast5_cfb64 "cast5-cfb" +#define NID_cast5_cfb64 110 + +#define SN_cast5_ofb64 "CAST5-OFB" +#define LN_cast5_ofb64 "cast5-ofb" +#define NID_cast5_ofb64 111 + +#define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +#define NID_pbeWithMD5AndCast5_CBC 112 +#define OBJ_pbeWithMD5AndCast5_CBC OBJ_ISO_US,113533L,7L,66L,12L + +#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC" +#define LN_id_PasswordBasedMAC "password based MAC" +#define NID_id_PasswordBasedMAC 782 +#define OBJ_id_PasswordBasedMAC OBJ_ISO_US,113533L,7L,66L,13L + +#define SN_id_DHBasedMac "id-DHBasedMac" +#define LN_id_DHBasedMac "Diffie-Hellman based MAC" +#define NID_id_DHBasedMac 783 +#define OBJ_id_DHBasedMac OBJ_ISO_US,113533L,7L,66L,30L + +#define SN_rsadsi "rsadsi" +#define LN_rsadsi "RSA Data Security, Inc." +#define NID_rsadsi 1 +#define OBJ_rsadsi OBJ_ISO_US,113549L + +#define SN_pkcs "pkcs" +#define LN_pkcs "RSA Data Security, Inc. PKCS" +#define NID_pkcs 2 +#define OBJ_pkcs OBJ_rsadsi,1L + +#define SN_pkcs1 "pkcs1" +#define NID_pkcs1 186 +#define OBJ_pkcs1 OBJ_pkcs,1L + +#define LN_rsaEncryption "rsaEncryption" +#define NID_rsaEncryption 6 +#define OBJ_rsaEncryption OBJ_pkcs1,1L + +#define SN_md2WithRSAEncryption "RSA-MD2" +#define LN_md2WithRSAEncryption "md2WithRSAEncryption" +#define NID_md2WithRSAEncryption 7 +#define OBJ_md2WithRSAEncryption OBJ_pkcs1,2L + +#define SN_md4WithRSAEncryption "RSA-MD4" +#define LN_md4WithRSAEncryption "md4WithRSAEncryption" +#define NID_md4WithRSAEncryption 396 +#define OBJ_md4WithRSAEncryption OBJ_pkcs1,3L + +#define SN_md5WithRSAEncryption "RSA-MD5" +#define LN_md5WithRSAEncryption "md5WithRSAEncryption" +#define NID_md5WithRSAEncryption 8 +#define OBJ_md5WithRSAEncryption OBJ_pkcs1,4L + +#define SN_sha1WithRSAEncryption "RSA-SHA1" +#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +#define NID_sha1WithRSAEncryption 65 +#define OBJ_sha1WithRSAEncryption OBJ_pkcs1,5L + +#define SN_rsaesOaep "RSAES-OAEP" +#define LN_rsaesOaep "rsaesOaep" +#define NID_rsaesOaep 919 +#define OBJ_rsaesOaep OBJ_pkcs1,7L + +#define SN_mgf1 "MGF1" +#define LN_mgf1 "mgf1" +#define NID_mgf1 911 +#define OBJ_mgf1 OBJ_pkcs1,8L + +#define SN_rsassaPss "RSASSA-PSS" +#define LN_rsassaPss "rsassaPss" +#define NID_rsassaPss 912 +#define OBJ_rsassaPss OBJ_pkcs1,10L + +#define SN_sha256WithRSAEncryption "RSA-SHA256" +#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption" +#define NID_sha256WithRSAEncryption 668 +#define OBJ_sha256WithRSAEncryption OBJ_pkcs1,11L + +#define SN_sha384WithRSAEncryption "RSA-SHA384" +#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption" +#define NID_sha384WithRSAEncryption 669 +#define OBJ_sha384WithRSAEncryption OBJ_pkcs1,12L + +#define SN_sha512WithRSAEncryption "RSA-SHA512" +#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption" +#define NID_sha512WithRSAEncryption 670 +#define OBJ_sha512WithRSAEncryption OBJ_pkcs1,13L + +#define SN_sha224WithRSAEncryption "RSA-SHA224" +#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption" +#define NID_sha224WithRSAEncryption 671 +#define OBJ_sha224WithRSAEncryption OBJ_pkcs1,14L + +#define SN_pkcs3 "pkcs3" +#define NID_pkcs3 27 +#define OBJ_pkcs3 OBJ_pkcs,3L + +#define LN_dhKeyAgreement "dhKeyAgreement" +#define NID_dhKeyAgreement 28 +#define OBJ_dhKeyAgreement OBJ_pkcs3,1L + +#define SN_pkcs5 "pkcs5" +#define NID_pkcs5 187 +#define OBJ_pkcs5 OBJ_pkcs,5L + +#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +#define NID_pbeWithMD2AndDES_CBC 9 +#define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs5,1L + +#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +#define NID_pbeWithMD5AndDES_CBC 10 +#define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs5,3L + +#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +#define NID_pbeWithMD2AndRC2_CBC 168 +#define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs5,4L + +#define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +#define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +#define NID_pbeWithMD5AndRC2_CBC 169 +#define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs5,6L + +#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +#define NID_pbeWithSHA1AndDES_CBC 170 +#define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs5,10L + +#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +#define NID_pbeWithSHA1AndRC2_CBC 68 +#define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs5,11L + +#define LN_id_pbkdf2 "PBKDF2" +#define NID_id_pbkdf2 69 +#define OBJ_id_pbkdf2 OBJ_pkcs5,12L + +#define LN_pbes2 "PBES2" +#define NID_pbes2 161 +#define OBJ_pbes2 OBJ_pkcs5,13L + +#define LN_pbmac1 "PBMAC1" +#define NID_pbmac1 162 +#define OBJ_pbmac1 OBJ_pkcs5,14L + +#define SN_pkcs7 "pkcs7" +#define NID_pkcs7 20 +#define OBJ_pkcs7 OBJ_pkcs,7L + +#define LN_pkcs7_data "pkcs7-data" +#define NID_pkcs7_data 21 +#define OBJ_pkcs7_data OBJ_pkcs7,1L + +#define LN_pkcs7_signed "pkcs7-signedData" +#define NID_pkcs7_signed 22 +#define OBJ_pkcs7_signed OBJ_pkcs7,2L + +#define LN_pkcs7_enveloped "pkcs7-envelopedData" +#define NID_pkcs7_enveloped 23 +#define OBJ_pkcs7_enveloped OBJ_pkcs7,3L + +#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +#define NID_pkcs7_signedAndEnveloped 24 +#define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L + +#define LN_pkcs7_digest "pkcs7-digestData" +#define NID_pkcs7_digest 25 +#define OBJ_pkcs7_digest OBJ_pkcs7,5L + +#define LN_pkcs7_encrypted "pkcs7-encryptedData" +#define NID_pkcs7_encrypted 26 +#define OBJ_pkcs7_encrypted OBJ_pkcs7,6L + +#define SN_pkcs9 "pkcs9" +#define NID_pkcs9 47 +#define OBJ_pkcs9 OBJ_pkcs,9L + +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L + +#define LN_pkcs9_unstructuredName "unstructuredName" +#define NID_pkcs9_unstructuredName 49 +#define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L + +#define LN_pkcs9_contentType "contentType" +#define NID_pkcs9_contentType 50 +#define OBJ_pkcs9_contentType OBJ_pkcs9,3L + +#define LN_pkcs9_messageDigest "messageDigest" +#define NID_pkcs9_messageDigest 51 +#define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L + +#define LN_pkcs9_signingTime "signingTime" +#define NID_pkcs9_signingTime 52 +#define OBJ_pkcs9_signingTime OBJ_pkcs9,5L + +#define LN_pkcs9_countersignature "countersignature" +#define NID_pkcs9_countersignature 53 +#define OBJ_pkcs9_countersignature OBJ_pkcs9,6L + +#define LN_pkcs9_challengePassword "challengePassword" +#define NID_pkcs9_challengePassword 54 +#define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L + +#define LN_pkcs9_unstructuredAddress "unstructuredAddress" +#define NID_pkcs9_unstructuredAddress 55 +#define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L + +#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +#define NID_pkcs9_extCertAttributes 56 +#define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L + +#define SN_ext_req "extReq" +#define LN_ext_req "Extension Request" +#define NID_ext_req 172 +#define OBJ_ext_req OBJ_pkcs9,14L + +#define SN_SMIMECapabilities "SMIME-CAPS" +#define LN_SMIMECapabilities "S/MIME Capabilities" +#define NID_SMIMECapabilities 167 +#define OBJ_SMIMECapabilities OBJ_pkcs9,15L + +#define SN_SMIME "SMIME" +#define LN_SMIME "S/MIME" +#define NID_SMIME 188 +#define OBJ_SMIME OBJ_pkcs9,16L + +#define SN_id_smime_mod "id-smime-mod" +#define NID_id_smime_mod 189 +#define OBJ_id_smime_mod OBJ_SMIME,0L + +#define SN_id_smime_ct "id-smime-ct" +#define NID_id_smime_ct 190 +#define OBJ_id_smime_ct OBJ_SMIME,1L + +#define SN_id_smime_aa "id-smime-aa" +#define NID_id_smime_aa 191 +#define OBJ_id_smime_aa OBJ_SMIME,2L + +#define SN_id_smime_alg "id-smime-alg" +#define NID_id_smime_alg 192 +#define OBJ_id_smime_alg OBJ_SMIME,3L + +#define SN_id_smime_cd "id-smime-cd" +#define NID_id_smime_cd 193 +#define OBJ_id_smime_cd OBJ_SMIME,4L + +#define SN_id_smime_spq "id-smime-spq" +#define NID_id_smime_spq 194 +#define OBJ_id_smime_spq OBJ_SMIME,5L + +#define SN_id_smime_cti "id-smime-cti" +#define NID_id_smime_cti 195 +#define OBJ_id_smime_cti OBJ_SMIME,6L + +#define SN_id_smime_mod_cms "id-smime-mod-cms" +#define NID_id_smime_mod_cms 196 +#define OBJ_id_smime_mod_cms OBJ_id_smime_mod,1L + +#define SN_id_smime_mod_ess "id-smime-mod-ess" +#define NID_id_smime_mod_ess 197 +#define OBJ_id_smime_mod_ess OBJ_id_smime_mod,2L + +#define SN_id_smime_mod_oid "id-smime-mod-oid" +#define NID_id_smime_mod_oid 198 +#define OBJ_id_smime_mod_oid OBJ_id_smime_mod,3L + +#define SN_id_smime_mod_msg_v3 "id-smime-mod-msg-v3" +#define NID_id_smime_mod_msg_v3 199 +#define OBJ_id_smime_mod_msg_v3 OBJ_id_smime_mod,4L + +#define SN_id_smime_mod_ets_eSignature_88 "id-smime-mod-ets-eSignature-88" +#define NID_id_smime_mod_ets_eSignature_88 200 +#define OBJ_id_smime_mod_ets_eSignature_88 OBJ_id_smime_mod,5L + +#define SN_id_smime_mod_ets_eSignature_97 "id-smime-mod-ets-eSignature-97" +#define NID_id_smime_mod_ets_eSignature_97 201 +#define OBJ_id_smime_mod_ets_eSignature_97 OBJ_id_smime_mod,6L + +#define SN_id_smime_mod_ets_eSigPolicy_88 "id-smime-mod-ets-eSigPolicy-88" +#define NID_id_smime_mod_ets_eSigPolicy_88 202 +#define OBJ_id_smime_mod_ets_eSigPolicy_88 OBJ_id_smime_mod,7L + +#define SN_id_smime_mod_ets_eSigPolicy_97 "id-smime-mod-ets-eSigPolicy-97" +#define NID_id_smime_mod_ets_eSigPolicy_97 203 +#define OBJ_id_smime_mod_ets_eSigPolicy_97 OBJ_id_smime_mod,8L + +#define SN_id_smime_ct_receipt "id-smime-ct-receipt" +#define NID_id_smime_ct_receipt 204 +#define OBJ_id_smime_ct_receipt OBJ_id_smime_ct,1L + +#define SN_id_smime_ct_authData "id-smime-ct-authData" +#define NID_id_smime_ct_authData 205 +#define OBJ_id_smime_ct_authData OBJ_id_smime_ct,2L + +#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert" +#define NID_id_smime_ct_publishCert 206 +#define OBJ_id_smime_ct_publishCert OBJ_id_smime_ct,3L + +#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo" +#define NID_id_smime_ct_TSTInfo 207 +#define OBJ_id_smime_ct_TSTInfo OBJ_id_smime_ct,4L + +#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo" +#define NID_id_smime_ct_TDTInfo 208 +#define OBJ_id_smime_ct_TDTInfo OBJ_id_smime_ct,5L + +#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo" +#define NID_id_smime_ct_contentInfo 209 +#define OBJ_id_smime_ct_contentInfo OBJ_id_smime_ct,6L + +#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData" +#define NID_id_smime_ct_DVCSRequestData 210 +#define OBJ_id_smime_ct_DVCSRequestData OBJ_id_smime_ct,7L + +#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData" +#define NID_id_smime_ct_DVCSResponseData 211 +#define OBJ_id_smime_ct_DVCSResponseData OBJ_id_smime_ct,8L + +#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData" +#define NID_id_smime_ct_compressedData 786 +#define OBJ_id_smime_ct_compressedData OBJ_id_smime_ct,9L + +#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF" +#define NID_id_ct_asciiTextWithCRLF 787 +#define OBJ_id_ct_asciiTextWithCRLF OBJ_id_smime_ct,27L + +#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" +#define NID_id_smime_aa_receiptRequest 212 +#define OBJ_id_smime_aa_receiptRequest OBJ_id_smime_aa,1L + +#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel" +#define NID_id_smime_aa_securityLabel 213 +#define OBJ_id_smime_aa_securityLabel OBJ_id_smime_aa,2L + +#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory" +#define NID_id_smime_aa_mlExpandHistory 214 +#define OBJ_id_smime_aa_mlExpandHistory OBJ_id_smime_aa,3L + +#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint" +#define NID_id_smime_aa_contentHint 215 +#define OBJ_id_smime_aa_contentHint OBJ_id_smime_aa,4L + +#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest" +#define NID_id_smime_aa_msgSigDigest 216 +#define OBJ_id_smime_aa_msgSigDigest OBJ_id_smime_aa,5L + +#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType" +#define NID_id_smime_aa_encapContentType 217 +#define OBJ_id_smime_aa_encapContentType OBJ_id_smime_aa,6L + +#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier" +#define NID_id_smime_aa_contentIdentifier 218 +#define OBJ_id_smime_aa_contentIdentifier OBJ_id_smime_aa,7L + +#define SN_id_smime_aa_macValue "id-smime-aa-macValue" +#define NID_id_smime_aa_macValue 219 +#define OBJ_id_smime_aa_macValue OBJ_id_smime_aa,8L + +#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels" +#define NID_id_smime_aa_equivalentLabels 220 +#define OBJ_id_smime_aa_equivalentLabels OBJ_id_smime_aa,9L + +#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference" +#define NID_id_smime_aa_contentReference 221 +#define OBJ_id_smime_aa_contentReference OBJ_id_smime_aa,10L + +#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref" +#define NID_id_smime_aa_encrypKeyPref 222 +#define OBJ_id_smime_aa_encrypKeyPref OBJ_id_smime_aa,11L + +#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate" +#define NID_id_smime_aa_signingCertificate 223 +#define OBJ_id_smime_aa_signingCertificate OBJ_id_smime_aa,12L + +#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts" +#define NID_id_smime_aa_smimeEncryptCerts 224 +#define OBJ_id_smime_aa_smimeEncryptCerts OBJ_id_smime_aa,13L + +#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken" +#define NID_id_smime_aa_timeStampToken 225 +#define OBJ_id_smime_aa_timeStampToken OBJ_id_smime_aa,14L + +#define SN_id_smime_aa_ets_sigPolicyId "id-smime-aa-ets-sigPolicyId" +#define NID_id_smime_aa_ets_sigPolicyId 226 +#define OBJ_id_smime_aa_ets_sigPolicyId OBJ_id_smime_aa,15L + +#define SN_id_smime_aa_ets_commitmentType "id-smime-aa-ets-commitmentType" +#define NID_id_smime_aa_ets_commitmentType 227 +#define OBJ_id_smime_aa_ets_commitmentType OBJ_id_smime_aa,16L + +#define SN_id_smime_aa_ets_signerLocation "id-smime-aa-ets-signerLocation" +#define NID_id_smime_aa_ets_signerLocation 228 +#define OBJ_id_smime_aa_ets_signerLocation OBJ_id_smime_aa,17L + +#define SN_id_smime_aa_ets_signerAttr "id-smime-aa-ets-signerAttr" +#define NID_id_smime_aa_ets_signerAttr 229 +#define OBJ_id_smime_aa_ets_signerAttr OBJ_id_smime_aa,18L + +#define SN_id_smime_aa_ets_otherSigCert "id-smime-aa-ets-otherSigCert" +#define NID_id_smime_aa_ets_otherSigCert 230 +#define OBJ_id_smime_aa_ets_otherSigCert OBJ_id_smime_aa,19L + +#define SN_id_smime_aa_ets_contentTimestamp "id-smime-aa-ets-contentTimestamp" +#define NID_id_smime_aa_ets_contentTimestamp 231 +#define OBJ_id_smime_aa_ets_contentTimestamp OBJ_id_smime_aa,20L + +#define SN_id_smime_aa_ets_CertificateRefs "id-smime-aa-ets-CertificateRefs" +#define NID_id_smime_aa_ets_CertificateRefs 232 +#define OBJ_id_smime_aa_ets_CertificateRefs OBJ_id_smime_aa,21L + +#define SN_id_smime_aa_ets_RevocationRefs "id-smime-aa-ets-RevocationRefs" +#define NID_id_smime_aa_ets_RevocationRefs 233 +#define OBJ_id_smime_aa_ets_RevocationRefs OBJ_id_smime_aa,22L + +#define SN_id_smime_aa_ets_certValues "id-smime-aa-ets-certValues" +#define NID_id_smime_aa_ets_certValues 234 +#define OBJ_id_smime_aa_ets_certValues OBJ_id_smime_aa,23L + +#define SN_id_smime_aa_ets_revocationValues "id-smime-aa-ets-revocationValues" +#define NID_id_smime_aa_ets_revocationValues 235 +#define OBJ_id_smime_aa_ets_revocationValues OBJ_id_smime_aa,24L + +#define SN_id_smime_aa_ets_escTimeStamp "id-smime-aa-ets-escTimeStamp" +#define NID_id_smime_aa_ets_escTimeStamp 236 +#define OBJ_id_smime_aa_ets_escTimeStamp OBJ_id_smime_aa,25L + +#define SN_id_smime_aa_ets_certCRLTimestamp "id-smime-aa-ets-certCRLTimestamp" +#define NID_id_smime_aa_ets_certCRLTimestamp 237 +#define OBJ_id_smime_aa_ets_certCRLTimestamp OBJ_id_smime_aa,26L + +#define SN_id_smime_aa_ets_archiveTimeStamp "id-smime-aa-ets-archiveTimeStamp" +#define NID_id_smime_aa_ets_archiveTimeStamp 238 +#define OBJ_id_smime_aa_ets_archiveTimeStamp OBJ_id_smime_aa,27L + +#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType" +#define NID_id_smime_aa_signatureType 239 +#define OBJ_id_smime_aa_signatureType OBJ_id_smime_aa,28L + +#define SN_id_smime_aa_dvcs_dvc "id-smime-aa-dvcs-dvc" +#define NID_id_smime_aa_dvcs_dvc 240 +#define OBJ_id_smime_aa_dvcs_dvc OBJ_id_smime_aa,29L + +#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" +#define NID_id_smime_alg_ESDHwith3DES 241 +#define OBJ_id_smime_alg_ESDHwith3DES OBJ_id_smime_alg,1L + +#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2" +#define NID_id_smime_alg_ESDHwithRC2 242 +#define OBJ_id_smime_alg_ESDHwithRC2 OBJ_id_smime_alg,2L + +#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap" +#define NID_id_smime_alg_3DESwrap 243 +#define OBJ_id_smime_alg_3DESwrap OBJ_id_smime_alg,3L + +#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap" +#define NID_id_smime_alg_RC2wrap 244 +#define OBJ_id_smime_alg_RC2wrap OBJ_id_smime_alg,4L + +#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH" +#define NID_id_smime_alg_ESDH 245 +#define OBJ_id_smime_alg_ESDH OBJ_id_smime_alg,5L + +#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap" +#define NID_id_smime_alg_CMS3DESwrap 246 +#define OBJ_id_smime_alg_CMS3DESwrap OBJ_id_smime_alg,6L + +#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap" +#define NID_id_smime_alg_CMSRC2wrap 247 +#define OBJ_id_smime_alg_CMSRC2wrap OBJ_id_smime_alg,7L + +#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK" +#define NID_id_alg_PWRI_KEK 893 +#define OBJ_id_alg_PWRI_KEK OBJ_id_smime_alg,9L + +#define SN_id_smime_cd_ldap "id-smime-cd-ldap" +#define NID_id_smime_cd_ldap 248 +#define OBJ_id_smime_cd_ldap OBJ_id_smime_cd,1L + +#define SN_id_smime_spq_ets_sqt_uri "id-smime-spq-ets-sqt-uri" +#define NID_id_smime_spq_ets_sqt_uri 249 +#define OBJ_id_smime_spq_ets_sqt_uri OBJ_id_smime_spq,1L + +#define SN_id_smime_spq_ets_sqt_unotice "id-smime-spq-ets-sqt-unotice" +#define NID_id_smime_spq_ets_sqt_unotice 250 +#define OBJ_id_smime_spq_ets_sqt_unotice OBJ_id_smime_spq,2L + +#define SN_id_smime_cti_ets_proofOfOrigin "id-smime-cti-ets-proofOfOrigin" +#define NID_id_smime_cti_ets_proofOfOrigin 251 +#define OBJ_id_smime_cti_ets_proofOfOrigin OBJ_id_smime_cti,1L + +#define SN_id_smime_cti_ets_proofOfReceipt "id-smime-cti-ets-proofOfReceipt" +#define NID_id_smime_cti_ets_proofOfReceipt 252 +#define OBJ_id_smime_cti_ets_proofOfReceipt OBJ_id_smime_cti,2L + +#define SN_id_smime_cti_ets_proofOfDelivery "id-smime-cti-ets-proofOfDelivery" +#define NID_id_smime_cti_ets_proofOfDelivery 253 +#define OBJ_id_smime_cti_ets_proofOfDelivery OBJ_id_smime_cti,3L + +#define SN_id_smime_cti_ets_proofOfSender "id-smime-cti-ets-proofOfSender" +#define NID_id_smime_cti_ets_proofOfSender 254 +#define OBJ_id_smime_cti_ets_proofOfSender OBJ_id_smime_cti,4L + +#define SN_id_smime_cti_ets_proofOfApproval "id-smime-cti-ets-proofOfApproval" +#define NID_id_smime_cti_ets_proofOfApproval 255 +#define OBJ_id_smime_cti_ets_proofOfApproval OBJ_id_smime_cti,5L + +#define SN_id_smime_cti_ets_proofOfCreation "id-smime-cti-ets-proofOfCreation" +#define NID_id_smime_cti_ets_proofOfCreation 256 +#define OBJ_id_smime_cti_ets_proofOfCreation OBJ_id_smime_cti,6L + +#define LN_friendlyName "friendlyName" +#define NID_friendlyName 156 +#define OBJ_friendlyName OBJ_pkcs9,20L + +#define LN_localKeyID "localKeyID" +#define NID_localKeyID 157 +#define OBJ_localKeyID OBJ_pkcs9,21L + +#define SN_ms_csp_name "CSPName" +#define LN_ms_csp_name "Microsoft CSP Name" +#define NID_ms_csp_name 417 +#define OBJ_ms_csp_name 1L,3L,6L,1L,4L,1L,311L,17L,1L + +#define SN_LocalKeySet "LocalKeySet" +#define LN_LocalKeySet "Microsoft Local Key set" +#define NID_LocalKeySet 856 +#define OBJ_LocalKeySet 1L,3L,6L,1L,4L,1L,311L,17L,2L + +#define OBJ_certTypes OBJ_pkcs9,22L + +#define LN_x509Certificate "x509Certificate" +#define NID_x509Certificate 158 +#define OBJ_x509Certificate OBJ_certTypes,1L + +#define LN_sdsiCertificate "sdsiCertificate" +#define NID_sdsiCertificate 159 +#define OBJ_sdsiCertificate OBJ_certTypes,2L + +#define OBJ_crlTypes OBJ_pkcs9,23L + +#define LN_x509Crl "x509Crl" +#define NID_x509Crl 160 +#define OBJ_x509Crl OBJ_crlTypes,1L + +#define OBJ_pkcs12 OBJ_pkcs,12L + +#define OBJ_pkcs12_pbeids OBJ_pkcs12,1L + +#define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +#define NID_pbe_WithSHA1And128BitRC4 144 +#define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids,1L + +#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +#define NID_pbe_WithSHA1And40BitRC4 145 +#define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids,2L + +#define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +#define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +#define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids,3L + +#define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +#define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +#define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +#define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids,4L + +#define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +#define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +#define NID_pbe_WithSHA1And128BitRC2_CBC 148 +#define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids,5L + +#define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +#define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +#define NID_pbe_WithSHA1And40BitRC2_CBC 149 +#define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids,6L + +#define OBJ_pkcs12_Version1 OBJ_pkcs12,10L + +#define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1,1L + +#define LN_keyBag "keyBag" +#define NID_keyBag 150 +#define OBJ_keyBag OBJ_pkcs12_BagIds,1L + +#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +#define NID_pkcs8ShroudedKeyBag 151 +#define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds,2L + +#define LN_certBag "certBag" +#define NID_certBag 152 +#define OBJ_certBag OBJ_pkcs12_BagIds,3L + +#define LN_crlBag "crlBag" +#define NID_crlBag 153 +#define OBJ_crlBag OBJ_pkcs12_BagIds,4L + +#define LN_secretBag "secretBag" +#define NID_secretBag 154 +#define OBJ_secretBag OBJ_pkcs12_BagIds,5L + +#define LN_safeContentsBag "safeContentsBag" +#define NID_safeContentsBag 155 +#define OBJ_safeContentsBag OBJ_pkcs12_BagIds,6L + +#define SN_md2 "MD2" +#define LN_md2 "md2" +#define NID_md2 3 +#define OBJ_md2 OBJ_rsadsi,2L,2L + +#define SN_md4 "MD4" +#define LN_md4 "md4" +#define NID_md4 257 +#define OBJ_md4 OBJ_rsadsi,2L,4L + +#define SN_md5 "MD5" +#define LN_md5 "md5" +#define NID_md5 4 +#define OBJ_md5 OBJ_rsadsi,2L,5L + +#define SN_md5_sha1 "MD5-SHA1" +#define LN_md5_sha1 "md5-sha1" +#define NID_md5_sha1 114 + +#define LN_hmacWithMD5 "hmacWithMD5" +#define NID_hmacWithMD5 797 +#define OBJ_hmacWithMD5 OBJ_rsadsi,2L,6L + +#define LN_hmacWithSHA1 "hmacWithSHA1" +#define NID_hmacWithSHA1 163 +#define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L + +#define LN_hmacWithSHA224 "hmacWithSHA224" +#define NID_hmacWithSHA224 798 +#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L + +#define LN_hmacWithSHA256 "hmacWithSHA256" +#define NID_hmacWithSHA256 799 +#define OBJ_hmacWithSHA256 OBJ_rsadsi,2L,9L + +#define LN_hmacWithSHA384 "hmacWithSHA384" +#define NID_hmacWithSHA384 800 +#define OBJ_hmacWithSHA384 OBJ_rsadsi,2L,10L + +#define LN_hmacWithSHA512 "hmacWithSHA512" +#define NID_hmacWithSHA512 801 +#define OBJ_hmacWithSHA512 OBJ_rsadsi,2L,11L + +#define SN_rc2_cbc "RC2-CBC" +#define LN_rc2_cbc "rc2-cbc" +#define NID_rc2_cbc 37 +#define OBJ_rc2_cbc OBJ_rsadsi,3L,2L + +#define SN_rc2_ecb "RC2-ECB" +#define LN_rc2_ecb "rc2-ecb" +#define NID_rc2_ecb 38 + +#define SN_rc2_cfb64 "RC2-CFB" +#define LN_rc2_cfb64 "rc2-cfb" +#define NID_rc2_cfb64 39 + +#define SN_rc2_ofb64 "RC2-OFB" +#define LN_rc2_ofb64 "rc2-ofb" +#define NID_rc2_ofb64 40 + +#define SN_rc2_40_cbc "RC2-40-CBC" +#define LN_rc2_40_cbc "rc2-40-cbc" +#define NID_rc2_40_cbc 98 + +#define SN_rc2_64_cbc "RC2-64-CBC" +#define LN_rc2_64_cbc "rc2-64-cbc" +#define NID_rc2_64_cbc 166 + +#define SN_rc4 "RC4" +#define LN_rc4 "rc4" +#define NID_rc4 5 +#define OBJ_rc4 OBJ_rsadsi,3L,4L + +#define SN_rc4_40 "RC4-40" +#define LN_rc4_40 "rc4-40" +#define NID_rc4_40 97 + +#define SN_des_ede3_cbc "DES-EDE3-CBC" +#define LN_des_ede3_cbc "des-ede3-cbc" +#define NID_des_ede3_cbc 44 +#define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L + +#define SN_rc5_cbc "RC5-CBC" +#define LN_rc5_cbc "rc5-cbc" +#define NID_rc5_cbc 120 +#define OBJ_rc5_cbc OBJ_rsadsi,3L,8L + +#define SN_rc5_ecb "RC5-ECB" +#define LN_rc5_ecb "rc5-ecb" +#define NID_rc5_ecb 121 + +#define SN_rc5_cfb64 "RC5-CFB" +#define LN_rc5_cfb64 "rc5-cfb" +#define NID_rc5_cfb64 122 + +#define SN_rc5_ofb64 "RC5-OFB" +#define LN_rc5_ofb64 "rc5-ofb" +#define NID_rc5_ofb64 123 + +#define SN_ms_ext_req "msExtReq" +#define LN_ms_ext_req "Microsoft Extension Request" +#define NID_ms_ext_req 171 +#define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L + +#define SN_ms_code_ind "msCodeInd" +#define LN_ms_code_ind "Microsoft Individual Code Signing" +#define NID_ms_code_ind 134 +#define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L + +#define SN_ms_code_com "msCodeCom" +#define LN_ms_code_com "Microsoft Commercial Code Signing" +#define NID_ms_code_com 135 +#define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L + +#define SN_ms_ctl_sign "msCTLSign" +#define LN_ms_ctl_sign "Microsoft Trust List Signing" +#define NID_ms_ctl_sign 136 +#define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L + +#define SN_ms_sgc "msSGC" +#define LN_ms_sgc "Microsoft Server Gated Crypto" +#define NID_ms_sgc 137 +#define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L + +#define SN_ms_efs "msEFS" +#define LN_ms_efs "Microsoft Encrypted File System" +#define NID_ms_efs 138 +#define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L + +#define SN_ms_smartcard_login "msSmartcardLogin" +#define LN_ms_smartcard_login "Microsoft Smartcardlogin" +#define NID_ms_smartcard_login 648 +#define OBJ_ms_smartcard_login 1L,3L,6L,1L,4L,1L,311L,20L,2L,2L + +#define SN_ms_upn "msUPN" +#define LN_ms_upn "Microsoft Universal Principal Name" +#define NID_ms_upn 649 +#define OBJ_ms_upn 1L,3L,6L,1L,4L,1L,311L,20L,2L,3L + +#define SN_idea_cbc "IDEA-CBC" +#define LN_idea_cbc "idea-cbc" +#define NID_idea_cbc 34 +#define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L + +#define SN_idea_ecb "IDEA-ECB" +#define LN_idea_ecb "idea-ecb" +#define NID_idea_ecb 36 + +#define SN_idea_cfb64 "IDEA-CFB" +#define LN_idea_cfb64 "idea-cfb" +#define NID_idea_cfb64 35 + +#define SN_idea_ofb64 "IDEA-OFB" +#define LN_idea_ofb64 "idea-ofb" +#define NID_idea_ofb64 46 + +#define SN_bf_cbc "BF-CBC" +#define LN_bf_cbc "bf-cbc" +#define NID_bf_cbc 91 +#define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L + +#define SN_bf_ecb "BF-ECB" +#define LN_bf_ecb "bf-ecb" +#define NID_bf_ecb 92 + +#define SN_bf_cfb64 "BF-CFB" +#define LN_bf_cfb64 "bf-cfb" +#define NID_bf_cfb64 93 + +#define SN_bf_ofb64 "BF-OFB" +#define LN_bf_ofb64 "bf-ofb" +#define NID_bf_ofb64 94 + +#define SN_id_pkix "PKIX" +#define NID_id_pkix 127 +#define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L + +#define SN_id_pkix_mod "id-pkix-mod" +#define NID_id_pkix_mod 258 +#define OBJ_id_pkix_mod OBJ_id_pkix,0L + +#define SN_id_pe "id-pe" +#define NID_id_pe 175 +#define OBJ_id_pe OBJ_id_pkix,1L + +#define SN_id_qt "id-qt" +#define NID_id_qt 259 +#define OBJ_id_qt OBJ_id_pkix,2L + +#define SN_id_kp "id-kp" +#define NID_id_kp 128 +#define OBJ_id_kp OBJ_id_pkix,3L + +#define SN_id_it "id-it" +#define NID_id_it 260 +#define OBJ_id_it OBJ_id_pkix,4L + +#define SN_id_pkip "id-pkip" +#define NID_id_pkip 261 +#define OBJ_id_pkip OBJ_id_pkix,5L + +#define SN_id_alg "id-alg" +#define NID_id_alg 262 +#define OBJ_id_alg OBJ_id_pkix,6L + +#define SN_id_cmc "id-cmc" +#define NID_id_cmc 263 +#define OBJ_id_cmc OBJ_id_pkix,7L + +#define SN_id_on "id-on" +#define NID_id_on 264 +#define OBJ_id_on OBJ_id_pkix,8L + +#define SN_id_pda "id-pda" +#define NID_id_pda 265 +#define OBJ_id_pda OBJ_id_pkix,9L + +#define SN_id_aca "id-aca" +#define NID_id_aca 266 +#define OBJ_id_aca OBJ_id_pkix,10L + +#define SN_id_qcs "id-qcs" +#define NID_id_qcs 267 +#define OBJ_id_qcs OBJ_id_pkix,11L + +#define SN_id_cct "id-cct" +#define NID_id_cct 268 +#define OBJ_id_cct OBJ_id_pkix,12L + +#define SN_id_ppl "id-ppl" +#define NID_id_ppl 662 +#define OBJ_id_ppl OBJ_id_pkix,21L + +#define SN_id_ad "id-ad" +#define NID_id_ad 176 +#define OBJ_id_ad OBJ_id_pkix,48L + +#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88" +#define NID_id_pkix1_explicit_88 269 +#define OBJ_id_pkix1_explicit_88 OBJ_id_pkix_mod,1L + +#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88" +#define NID_id_pkix1_implicit_88 270 +#define OBJ_id_pkix1_implicit_88 OBJ_id_pkix_mod,2L + +#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93" +#define NID_id_pkix1_explicit_93 271 +#define OBJ_id_pkix1_explicit_93 OBJ_id_pkix_mod,3L + +#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93" +#define NID_id_pkix1_implicit_93 272 +#define OBJ_id_pkix1_implicit_93 OBJ_id_pkix_mod,4L + +#define SN_id_mod_crmf "id-mod-crmf" +#define NID_id_mod_crmf 273 +#define OBJ_id_mod_crmf OBJ_id_pkix_mod,5L + +#define SN_id_mod_cmc "id-mod-cmc" +#define NID_id_mod_cmc 274 +#define OBJ_id_mod_cmc OBJ_id_pkix_mod,6L + +#define SN_id_mod_kea_profile_88 "id-mod-kea-profile-88" +#define NID_id_mod_kea_profile_88 275 +#define OBJ_id_mod_kea_profile_88 OBJ_id_pkix_mod,7L + +#define SN_id_mod_kea_profile_93 "id-mod-kea-profile-93" +#define NID_id_mod_kea_profile_93 276 +#define OBJ_id_mod_kea_profile_93 OBJ_id_pkix_mod,8L + +#define SN_id_mod_cmp "id-mod-cmp" +#define NID_id_mod_cmp 277 +#define OBJ_id_mod_cmp OBJ_id_pkix_mod,9L + +#define SN_id_mod_qualified_cert_88 "id-mod-qualified-cert-88" +#define NID_id_mod_qualified_cert_88 278 +#define OBJ_id_mod_qualified_cert_88 OBJ_id_pkix_mod,10L + +#define SN_id_mod_qualified_cert_93 "id-mod-qualified-cert-93" +#define NID_id_mod_qualified_cert_93 279 +#define OBJ_id_mod_qualified_cert_93 OBJ_id_pkix_mod,11L + +#define SN_id_mod_attribute_cert "id-mod-attribute-cert" +#define NID_id_mod_attribute_cert 280 +#define OBJ_id_mod_attribute_cert OBJ_id_pkix_mod,12L + +#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol" +#define NID_id_mod_timestamp_protocol 281 +#define OBJ_id_mod_timestamp_protocol OBJ_id_pkix_mod,13L + +#define SN_id_mod_ocsp "id-mod-ocsp" +#define NID_id_mod_ocsp 282 +#define OBJ_id_mod_ocsp OBJ_id_pkix_mod,14L + +#define SN_id_mod_dvcs "id-mod-dvcs" +#define NID_id_mod_dvcs 283 +#define OBJ_id_mod_dvcs OBJ_id_pkix_mod,15L + +#define SN_id_mod_cmp2000 "id-mod-cmp2000" +#define NID_id_mod_cmp2000 284 +#define OBJ_id_mod_cmp2000 OBJ_id_pkix_mod,16L + +#define SN_info_access "authorityInfoAccess" +#define LN_info_access "Authority Information Access" +#define NID_info_access 177 +#define OBJ_info_access OBJ_id_pe,1L + +#define SN_biometricInfo "biometricInfo" +#define LN_biometricInfo "Biometric Info" +#define NID_biometricInfo 285 +#define OBJ_biometricInfo OBJ_id_pe,2L + +#define SN_qcStatements "qcStatements" +#define NID_qcStatements 286 +#define OBJ_qcStatements OBJ_id_pe,3L + +#define SN_ac_auditEntity "ac-auditEntity" +#define NID_ac_auditEntity 287 +#define OBJ_ac_auditEntity OBJ_id_pe,4L + +#define SN_ac_targeting "ac-targeting" +#define NID_ac_targeting 288 +#define OBJ_ac_targeting OBJ_id_pe,5L + +#define SN_aaControls "aaControls" +#define NID_aaControls 289 +#define OBJ_aaControls OBJ_id_pe,6L + +#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock" +#define NID_sbgp_ipAddrBlock 290 +#define OBJ_sbgp_ipAddrBlock OBJ_id_pe,7L + +#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum" +#define NID_sbgp_autonomousSysNum 291 +#define OBJ_sbgp_autonomousSysNum OBJ_id_pe,8L + +#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier" +#define NID_sbgp_routerIdentifier 292 +#define OBJ_sbgp_routerIdentifier OBJ_id_pe,9L + +#define SN_ac_proxying "ac-proxying" +#define NID_ac_proxying 397 +#define OBJ_ac_proxying OBJ_id_pe,10L + +#define SN_sinfo_access "subjectInfoAccess" +#define LN_sinfo_access "Subject Information Access" +#define NID_sinfo_access 398 +#define OBJ_sinfo_access OBJ_id_pe,11L + +#define SN_proxyCertInfo "proxyCertInfo" +#define LN_proxyCertInfo "Proxy Certificate Information" +#define NID_proxyCertInfo 663 +#define OBJ_proxyCertInfo OBJ_id_pe,14L + +#define SN_id_qt_cps "id-qt-cps" +#define LN_id_qt_cps "Policy Qualifier CPS" +#define NID_id_qt_cps 164 +#define OBJ_id_qt_cps OBJ_id_qt,1L + +#define SN_id_qt_unotice "id-qt-unotice" +#define LN_id_qt_unotice "Policy Qualifier User Notice" +#define NID_id_qt_unotice 165 +#define OBJ_id_qt_unotice OBJ_id_qt,2L + +#define SN_textNotice "textNotice" +#define NID_textNotice 293 +#define OBJ_textNotice OBJ_id_qt,3L + +#define SN_server_auth "serverAuth" +#define LN_server_auth "TLS Web Server Authentication" +#define NID_server_auth 129 +#define OBJ_server_auth OBJ_id_kp,1L + +#define SN_client_auth "clientAuth" +#define LN_client_auth "TLS Web Client Authentication" +#define NID_client_auth 130 +#define OBJ_client_auth OBJ_id_kp,2L + +#define SN_code_sign "codeSigning" +#define LN_code_sign "Code Signing" +#define NID_code_sign 131 +#define OBJ_code_sign OBJ_id_kp,3L + +#define SN_email_protect "emailProtection" +#define LN_email_protect "E-mail Protection" +#define NID_email_protect 132 +#define OBJ_email_protect OBJ_id_kp,4L + +#define SN_ipsecEndSystem "ipsecEndSystem" +#define LN_ipsecEndSystem "IPSec End System" +#define NID_ipsecEndSystem 294 +#define OBJ_ipsecEndSystem OBJ_id_kp,5L + +#define SN_ipsecTunnel "ipsecTunnel" +#define LN_ipsecTunnel "IPSec Tunnel" +#define NID_ipsecTunnel 295 +#define OBJ_ipsecTunnel OBJ_id_kp,6L + +#define SN_ipsecUser "ipsecUser" +#define LN_ipsecUser "IPSec User" +#define NID_ipsecUser 296 +#define OBJ_ipsecUser OBJ_id_kp,7L + +#define SN_time_stamp "timeStamping" +#define LN_time_stamp "Time Stamping" +#define NID_time_stamp 133 +#define OBJ_time_stamp OBJ_id_kp,8L + +#define SN_OCSP_sign "OCSPSigning" +#define LN_OCSP_sign "OCSP Signing" +#define NID_OCSP_sign 180 +#define OBJ_OCSP_sign OBJ_id_kp,9L + +#define SN_dvcs "DVCS" +#define LN_dvcs "dvcs" +#define NID_dvcs 297 +#define OBJ_dvcs OBJ_id_kp,10L + +#define SN_id_it_caProtEncCert "id-it-caProtEncCert" +#define NID_id_it_caProtEncCert 298 +#define OBJ_id_it_caProtEncCert OBJ_id_it,1L + +#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes" +#define NID_id_it_signKeyPairTypes 299 +#define OBJ_id_it_signKeyPairTypes OBJ_id_it,2L + +#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes" +#define NID_id_it_encKeyPairTypes 300 +#define OBJ_id_it_encKeyPairTypes OBJ_id_it,3L + +#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg" +#define NID_id_it_preferredSymmAlg 301 +#define OBJ_id_it_preferredSymmAlg OBJ_id_it,4L + +#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo" +#define NID_id_it_caKeyUpdateInfo 302 +#define OBJ_id_it_caKeyUpdateInfo OBJ_id_it,5L + +#define SN_id_it_currentCRL "id-it-currentCRL" +#define NID_id_it_currentCRL 303 +#define OBJ_id_it_currentCRL OBJ_id_it,6L + +#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs" +#define NID_id_it_unsupportedOIDs 304 +#define OBJ_id_it_unsupportedOIDs OBJ_id_it,7L + +#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest" +#define NID_id_it_subscriptionRequest 305 +#define OBJ_id_it_subscriptionRequest OBJ_id_it,8L + +#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse" +#define NID_id_it_subscriptionResponse 306 +#define OBJ_id_it_subscriptionResponse OBJ_id_it,9L + +#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq" +#define NID_id_it_keyPairParamReq 307 +#define OBJ_id_it_keyPairParamReq OBJ_id_it,10L + +#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep" +#define NID_id_it_keyPairParamRep 308 +#define OBJ_id_it_keyPairParamRep OBJ_id_it,11L + +#define SN_id_it_revPassphrase "id-it-revPassphrase" +#define NID_id_it_revPassphrase 309 +#define OBJ_id_it_revPassphrase OBJ_id_it,12L + +#define SN_id_it_implicitConfirm "id-it-implicitConfirm" +#define NID_id_it_implicitConfirm 310 +#define OBJ_id_it_implicitConfirm OBJ_id_it,13L + +#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime" +#define NID_id_it_confirmWaitTime 311 +#define OBJ_id_it_confirmWaitTime OBJ_id_it,14L + +#define SN_id_it_origPKIMessage "id-it-origPKIMessage" +#define NID_id_it_origPKIMessage 312 +#define OBJ_id_it_origPKIMessage OBJ_id_it,15L + +#define SN_id_it_suppLangTags "id-it-suppLangTags" +#define NID_id_it_suppLangTags 784 +#define OBJ_id_it_suppLangTags OBJ_id_it,16L + +#define SN_id_regCtrl "id-regCtrl" +#define NID_id_regCtrl 313 +#define OBJ_id_regCtrl OBJ_id_pkip,1L + +#define SN_id_regInfo "id-regInfo" +#define NID_id_regInfo 314 +#define OBJ_id_regInfo OBJ_id_pkip,2L + +#define SN_id_regCtrl_regToken "id-regCtrl-regToken" +#define NID_id_regCtrl_regToken 315 +#define OBJ_id_regCtrl_regToken OBJ_id_regCtrl,1L + +#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator" +#define NID_id_regCtrl_authenticator 316 +#define OBJ_id_regCtrl_authenticator OBJ_id_regCtrl,2L + +#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo" +#define NID_id_regCtrl_pkiPublicationInfo 317 +#define OBJ_id_regCtrl_pkiPublicationInfo OBJ_id_regCtrl,3L + +#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions" +#define NID_id_regCtrl_pkiArchiveOptions 318 +#define OBJ_id_regCtrl_pkiArchiveOptions OBJ_id_regCtrl,4L + +#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID" +#define NID_id_regCtrl_oldCertID 319 +#define OBJ_id_regCtrl_oldCertID OBJ_id_regCtrl,5L + +#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey" +#define NID_id_regCtrl_protocolEncrKey 320 +#define OBJ_id_regCtrl_protocolEncrKey OBJ_id_regCtrl,6L + +#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" +#define NID_id_regInfo_utf8Pairs 321 +#define OBJ_id_regInfo_utf8Pairs OBJ_id_regInfo,1L + +#define SN_id_regInfo_certReq "id-regInfo-certReq" +#define NID_id_regInfo_certReq 322 +#define OBJ_id_regInfo_certReq OBJ_id_regInfo,2L + +#define SN_id_alg_des40 "id-alg-des40" +#define NID_id_alg_des40 323 +#define OBJ_id_alg_des40 OBJ_id_alg,1L + +#define SN_id_alg_noSignature "id-alg-noSignature" +#define NID_id_alg_noSignature 324 +#define OBJ_id_alg_noSignature OBJ_id_alg,2L + +#define SN_id_alg_dh_sig_hmac_sha1 "id-alg-dh-sig-hmac-sha1" +#define NID_id_alg_dh_sig_hmac_sha1 325 +#define OBJ_id_alg_dh_sig_hmac_sha1 OBJ_id_alg,3L + +#define SN_id_alg_dh_pop "id-alg-dh-pop" +#define NID_id_alg_dh_pop 326 +#define OBJ_id_alg_dh_pop OBJ_id_alg,4L + +#define SN_id_cmc_statusInfo "id-cmc-statusInfo" +#define NID_id_cmc_statusInfo 327 +#define OBJ_id_cmc_statusInfo OBJ_id_cmc,1L + +#define SN_id_cmc_identification "id-cmc-identification" +#define NID_id_cmc_identification 328 +#define OBJ_id_cmc_identification OBJ_id_cmc,2L + +#define SN_id_cmc_identityProof "id-cmc-identityProof" +#define NID_id_cmc_identityProof 329 +#define OBJ_id_cmc_identityProof OBJ_id_cmc,3L + +#define SN_id_cmc_dataReturn "id-cmc-dataReturn" +#define NID_id_cmc_dataReturn 330 +#define OBJ_id_cmc_dataReturn OBJ_id_cmc,4L + +#define SN_id_cmc_transactionId "id-cmc-transactionId" +#define NID_id_cmc_transactionId 331 +#define OBJ_id_cmc_transactionId OBJ_id_cmc,5L + +#define SN_id_cmc_senderNonce "id-cmc-senderNonce" +#define NID_id_cmc_senderNonce 332 +#define OBJ_id_cmc_senderNonce OBJ_id_cmc,6L + +#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce" +#define NID_id_cmc_recipientNonce 333 +#define OBJ_id_cmc_recipientNonce OBJ_id_cmc,7L + +#define SN_id_cmc_addExtensions "id-cmc-addExtensions" +#define NID_id_cmc_addExtensions 334 +#define OBJ_id_cmc_addExtensions OBJ_id_cmc,8L + +#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP" +#define NID_id_cmc_encryptedPOP 335 +#define OBJ_id_cmc_encryptedPOP OBJ_id_cmc,9L + +#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP" +#define NID_id_cmc_decryptedPOP 336 +#define OBJ_id_cmc_decryptedPOP OBJ_id_cmc,10L + +#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness" +#define NID_id_cmc_lraPOPWitness 337 +#define OBJ_id_cmc_lraPOPWitness OBJ_id_cmc,11L + +#define SN_id_cmc_getCert "id-cmc-getCert" +#define NID_id_cmc_getCert 338 +#define OBJ_id_cmc_getCert OBJ_id_cmc,15L + +#define SN_id_cmc_getCRL "id-cmc-getCRL" +#define NID_id_cmc_getCRL 339 +#define OBJ_id_cmc_getCRL OBJ_id_cmc,16L + +#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest" +#define NID_id_cmc_revokeRequest 340 +#define OBJ_id_cmc_revokeRequest OBJ_id_cmc,17L + +#define SN_id_cmc_regInfo "id-cmc-regInfo" +#define NID_id_cmc_regInfo 341 +#define OBJ_id_cmc_regInfo OBJ_id_cmc,18L + +#define SN_id_cmc_responseInfo "id-cmc-responseInfo" +#define NID_id_cmc_responseInfo 342 +#define OBJ_id_cmc_responseInfo OBJ_id_cmc,19L + +#define SN_id_cmc_queryPending "id-cmc-queryPending" +#define NID_id_cmc_queryPending 343 +#define OBJ_id_cmc_queryPending OBJ_id_cmc,21L + +#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom" +#define NID_id_cmc_popLinkRandom 344 +#define OBJ_id_cmc_popLinkRandom OBJ_id_cmc,22L + +#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness" +#define NID_id_cmc_popLinkWitness 345 +#define OBJ_id_cmc_popLinkWitness OBJ_id_cmc,23L + +#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance" +#define NID_id_cmc_confirmCertAcceptance 346 +#define OBJ_id_cmc_confirmCertAcceptance OBJ_id_cmc,24L + +#define SN_id_on_personalData "id-on-personalData" +#define NID_id_on_personalData 347 +#define OBJ_id_on_personalData OBJ_id_on,1L + +#define SN_id_on_permanentIdentifier "id-on-permanentIdentifier" +#define LN_id_on_permanentIdentifier "Permanent Identifier" +#define NID_id_on_permanentIdentifier 858 +#define OBJ_id_on_permanentIdentifier OBJ_id_on,3L + +#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth" +#define NID_id_pda_dateOfBirth 348 +#define OBJ_id_pda_dateOfBirth OBJ_id_pda,1L + +#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth" +#define NID_id_pda_placeOfBirth 349 +#define OBJ_id_pda_placeOfBirth OBJ_id_pda,2L + +#define SN_id_pda_gender "id-pda-gender" +#define NID_id_pda_gender 351 +#define OBJ_id_pda_gender OBJ_id_pda,3L + +#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship" +#define NID_id_pda_countryOfCitizenship 352 +#define OBJ_id_pda_countryOfCitizenship OBJ_id_pda,4L + +#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence" +#define NID_id_pda_countryOfResidence 353 +#define OBJ_id_pda_countryOfResidence OBJ_id_pda,5L + +#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo" +#define NID_id_aca_authenticationInfo 354 +#define OBJ_id_aca_authenticationInfo OBJ_id_aca,1L + +#define SN_id_aca_accessIdentity "id-aca-accessIdentity" +#define NID_id_aca_accessIdentity 355 +#define OBJ_id_aca_accessIdentity OBJ_id_aca,2L + +#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity" +#define NID_id_aca_chargingIdentity 356 +#define OBJ_id_aca_chargingIdentity OBJ_id_aca,3L + +#define SN_id_aca_group "id-aca-group" +#define NID_id_aca_group 357 +#define OBJ_id_aca_group OBJ_id_aca,4L + +#define SN_id_aca_role "id-aca-role" +#define NID_id_aca_role 358 +#define OBJ_id_aca_role OBJ_id_aca,5L + +#define SN_id_aca_encAttrs "id-aca-encAttrs" +#define NID_id_aca_encAttrs 399 +#define OBJ_id_aca_encAttrs OBJ_id_aca,6L + +#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1" +#define NID_id_qcs_pkixQCSyntax_v1 359 +#define OBJ_id_qcs_pkixQCSyntax_v1 OBJ_id_qcs,1L + +#define SN_id_cct_crs "id-cct-crs" +#define NID_id_cct_crs 360 +#define OBJ_id_cct_crs OBJ_id_cct,1L + +#define SN_id_cct_PKIData "id-cct-PKIData" +#define NID_id_cct_PKIData 361 +#define OBJ_id_cct_PKIData OBJ_id_cct,2L + +#define SN_id_cct_PKIResponse "id-cct-PKIResponse" +#define NID_id_cct_PKIResponse 362 +#define OBJ_id_cct_PKIResponse OBJ_id_cct,3L + +#define SN_id_ppl_anyLanguage "id-ppl-anyLanguage" +#define LN_id_ppl_anyLanguage "Any language" +#define NID_id_ppl_anyLanguage 664 +#define OBJ_id_ppl_anyLanguage OBJ_id_ppl,0L + +#define SN_id_ppl_inheritAll "id-ppl-inheritAll" +#define LN_id_ppl_inheritAll "Inherit all" +#define NID_id_ppl_inheritAll 665 +#define OBJ_id_ppl_inheritAll OBJ_id_ppl,1L + +#define SN_Independent "id-ppl-independent" +#define LN_Independent "Independent" +#define NID_Independent 667 +#define OBJ_Independent OBJ_id_ppl,2L + +#define SN_ad_OCSP "OCSP" +#define LN_ad_OCSP "OCSP" +#define NID_ad_OCSP 178 +#define OBJ_ad_OCSP OBJ_id_ad,1L + +#define SN_ad_ca_issuers "caIssuers" +#define LN_ad_ca_issuers "CA Issuers" +#define NID_ad_ca_issuers 179 +#define OBJ_ad_ca_issuers OBJ_id_ad,2L + +#define SN_ad_timeStamping "ad_timestamping" +#define LN_ad_timeStamping "AD Time Stamping" +#define NID_ad_timeStamping 363 +#define OBJ_ad_timeStamping OBJ_id_ad,3L + +#define SN_ad_dvcs "AD_DVCS" +#define LN_ad_dvcs "ad dvcs" +#define NID_ad_dvcs 364 +#define OBJ_ad_dvcs OBJ_id_ad,4L + +#define SN_caRepository "caRepository" +#define LN_caRepository "CA Repository" +#define NID_caRepository 785 +#define OBJ_caRepository OBJ_id_ad,5L + +#define OBJ_id_pkix_OCSP OBJ_ad_OCSP + +#define SN_id_pkix_OCSP_basic "basicOCSPResponse" +#define LN_id_pkix_OCSP_basic "Basic OCSP Response" +#define NID_id_pkix_OCSP_basic 365 +#define OBJ_id_pkix_OCSP_basic OBJ_id_pkix_OCSP,1L + +#define SN_id_pkix_OCSP_Nonce "Nonce" +#define LN_id_pkix_OCSP_Nonce "OCSP Nonce" +#define NID_id_pkix_OCSP_Nonce 366 +#define OBJ_id_pkix_OCSP_Nonce OBJ_id_pkix_OCSP,2L + +#define SN_id_pkix_OCSP_CrlID "CrlID" +#define LN_id_pkix_OCSP_CrlID "OCSP CRL ID" +#define NID_id_pkix_OCSP_CrlID 367 +#define OBJ_id_pkix_OCSP_CrlID OBJ_id_pkix_OCSP,3L + +#define SN_id_pkix_OCSP_acceptableResponses "acceptableResponses" +#define LN_id_pkix_OCSP_acceptableResponses "Acceptable OCSP Responses" +#define NID_id_pkix_OCSP_acceptableResponses 368 +#define OBJ_id_pkix_OCSP_acceptableResponses OBJ_id_pkix_OCSP,4L + +#define SN_id_pkix_OCSP_noCheck "noCheck" +#define LN_id_pkix_OCSP_noCheck "OCSP No Check" +#define NID_id_pkix_OCSP_noCheck 369 +#define OBJ_id_pkix_OCSP_noCheck OBJ_id_pkix_OCSP,5L + +#define SN_id_pkix_OCSP_archiveCutoff "archiveCutoff" +#define LN_id_pkix_OCSP_archiveCutoff "OCSP Archive Cutoff" +#define NID_id_pkix_OCSP_archiveCutoff 370 +#define OBJ_id_pkix_OCSP_archiveCutoff OBJ_id_pkix_OCSP,6L + +#define SN_id_pkix_OCSP_serviceLocator "serviceLocator" +#define LN_id_pkix_OCSP_serviceLocator "OCSP Service Locator" +#define NID_id_pkix_OCSP_serviceLocator 371 +#define OBJ_id_pkix_OCSP_serviceLocator OBJ_id_pkix_OCSP,7L + +#define SN_id_pkix_OCSP_extendedStatus "extendedStatus" +#define LN_id_pkix_OCSP_extendedStatus "Extended OCSP Status" +#define NID_id_pkix_OCSP_extendedStatus 372 +#define OBJ_id_pkix_OCSP_extendedStatus OBJ_id_pkix_OCSP,8L + +#define SN_id_pkix_OCSP_valid "valid" +#define NID_id_pkix_OCSP_valid 373 +#define OBJ_id_pkix_OCSP_valid OBJ_id_pkix_OCSP,9L + +#define SN_id_pkix_OCSP_path "path" +#define NID_id_pkix_OCSP_path 374 +#define OBJ_id_pkix_OCSP_path OBJ_id_pkix_OCSP,10L + +#define SN_id_pkix_OCSP_trustRoot "trustRoot" +#define LN_id_pkix_OCSP_trustRoot "Trust Root" +#define NID_id_pkix_OCSP_trustRoot 375 +#define OBJ_id_pkix_OCSP_trustRoot OBJ_id_pkix_OCSP,11L + +#define SN_algorithm "algorithm" +#define LN_algorithm "algorithm" +#define NID_algorithm 376 +#define OBJ_algorithm 1L,3L,14L,3L,2L + +#define SN_md5WithRSA "RSA-NP-MD5" +#define LN_md5WithRSA "md5WithRSA" +#define NID_md5WithRSA 104 +#define OBJ_md5WithRSA OBJ_algorithm,3L + +#define SN_des_ecb "DES-ECB" +#define LN_des_ecb "des-ecb" +#define NID_des_ecb 29 +#define OBJ_des_ecb OBJ_algorithm,6L + +#define SN_des_cbc "DES-CBC" +#define LN_des_cbc "des-cbc" +#define NID_des_cbc 31 +#define OBJ_des_cbc OBJ_algorithm,7L + +#define SN_des_ofb64 "DES-OFB" +#define LN_des_ofb64 "des-ofb" +#define NID_des_ofb64 45 +#define OBJ_des_ofb64 OBJ_algorithm,8L + +#define SN_des_cfb64 "DES-CFB" +#define LN_des_cfb64 "des-cfb" +#define NID_des_cfb64 30 +#define OBJ_des_cfb64 OBJ_algorithm,9L + +#define SN_rsaSignature "rsaSignature" +#define NID_rsaSignature 377 +#define OBJ_rsaSignature OBJ_algorithm,11L + +#define SN_dsa_2 "DSA-old" +#define LN_dsa_2 "dsaEncryption-old" +#define NID_dsa_2 67 +#define OBJ_dsa_2 OBJ_algorithm,12L + +#define SN_dsaWithSHA "DSA-SHA" +#define LN_dsaWithSHA "dsaWithSHA" +#define NID_dsaWithSHA 66 +#define OBJ_dsaWithSHA OBJ_algorithm,13L + +#define SN_shaWithRSAEncryption "RSA-SHA" +#define LN_shaWithRSAEncryption "shaWithRSAEncryption" +#define NID_shaWithRSAEncryption 42 +#define OBJ_shaWithRSAEncryption OBJ_algorithm,15L + +#define SN_des_ede_ecb "DES-EDE" +#define LN_des_ede_ecb "des-ede" +#define NID_des_ede_ecb 32 +#define OBJ_des_ede_ecb OBJ_algorithm,17L + +#define SN_des_ede3_ecb "DES-EDE3" +#define LN_des_ede3_ecb "des-ede3" +#define NID_des_ede3_ecb 33 + +#define SN_des_ede_cbc "DES-EDE-CBC" +#define LN_des_ede_cbc "des-ede-cbc" +#define NID_des_ede_cbc 43 + +#define SN_des_ede_cfb64 "DES-EDE-CFB" +#define LN_des_ede_cfb64 "des-ede-cfb" +#define NID_des_ede_cfb64 60 + +#define SN_des_ede3_cfb64 "DES-EDE3-CFB" +#define LN_des_ede3_cfb64 "des-ede3-cfb" +#define NID_des_ede3_cfb64 61 + +#define SN_des_ede_ofb64 "DES-EDE-OFB" +#define LN_des_ede_ofb64 "des-ede-ofb" +#define NID_des_ede_ofb64 62 + +#define SN_des_ede3_ofb64 "DES-EDE3-OFB" +#define LN_des_ede3_ofb64 "des-ede3-ofb" +#define NID_des_ede3_ofb64 63 + +#define SN_desx_cbc "DESX-CBC" +#define LN_desx_cbc "desx-cbc" +#define NID_desx_cbc 80 + +#define SN_sha "SHA" +#define LN_sha "sha" +#define NID_sha 41 +#define OBJ_sha OBJ_algorithm,18L + +#define SN_sha1 "SHA1" +#define LN_sha1 "sha1" +#define NID_sha1 64 +#define OBJ_sha1 OBJ_algorithm,26L + +#define SN_dsaWithSHA1_2 "DSA-SHA1-old" +#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +#define NID_dsaWithSHA1_2 70 +#define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L + +#define SN_sha1WithRSA "RSA-SHA1-2" +#define LN_sha1WithRSA "sha1WithRSA" +#define NID_sha1WithRSA 115 +#define OBJ_sha1WithRSA OBJ_algorithm,29L + +#define SN_ripemd160 "RIPEMD160" +#define LN_ripemd160 "ripemd160" +#define NID_ripemd160 117 +#define OBJ_ripemd160 1L,3L,36L,3L,2L,1L + +#define SN_ripemd160WithRSA "RSA-RIPEMD160" +#define LN_ripemd160WithRSA "ripemd160WithRSA" +#define NID_ripemd160WithRSA 119 +#define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L + +#define SN_sxnet "SXNetID" +#define LN_sxnet "Strong Extranet ID" +#define NID_sxnet 143 +#define OBJ_sxnet 1L,3L,101L,1L,4L,1L + +#define SN_X500 "X500" +#define LN_X500 "directory services (X.500)" +#define NID_X500 11 +#define OBJ_X500 2L,5L + +#define SN_X509 "X509" +#define NID_X509 12 +#define OBJ_X509 OBJ_X500,4L + +#define SN_commonName "CN" +#define LN_commonName "commonName" +#define NID_commonName 13 +#define OBJ_commonName OBJ_X509,3L + +#define SN_surname "SN" +#define LN_surname "surname" +#define NID_surname 100 +#define OBJ_surname OBJ_X509,4L + +#define LN_serialNumber "serialNumber" +#define NID_serialNumber 105 +#define OBJ_serialNumber OBJ_X509,5L + +#define SN_countryName "C" +#define LN_countryName "countryName" +#define NID_countryName 14 +#define OBJ_countryName OBJ_X509,6L + +#define SN_localityName "L" +#define LN_localityName "localityName" +#define NID_localityName 15 +#define OBJ_localityName OBJ_X509,7L + +#define SN_stateOrProvinceName "ST" +#define LN_stateOrProvinceName "stateOrProvinceName" +#define NID_stateOrProvinceName 16 +#define OBJ_stateOrProvinceName OBJ_X509,8L + +#define SN_streetAddress "street" +#define LN_streetAddress "streetAddress" +#define NID_streetAddress 660 +#define OBJ_streetAddress OBJ_X509,9L + +#define SN_organizationName "O" +#define LN_organizationName "organizationName" +#define NID_organizationName 17 +#define OBJ_organizationName OBJ_X509,10L + +#define SN_organizationalUnitName "OU" +#define LN_organizationalUnitName "organizationalUnitName" +#define NID_organizationalUnitName 18 +#define OBJ_organizationalUnitName OBJ_X509,11L + +#define SN_title "title" +#define LN_title "title" +#define NID_title 106 +#define OBJ_title OBJ_X509,12L + +#define LN_description "description" +#define NID_description 107 +#define OBJ_description OBJ_X509,13L + +#define LN_searchGuide "searchGuide" +#define NID_searchGuide 859 +#define OBJ_searchGuide OBJ_X509,14L + +#define LN_businessCategory "businessCategory" +#define NID_businessCategory 860 +#define OBJ_businessCategory OBJ_X509,15L + +#define LN_postalAddress "postalAddress" +#define NID_postalAddress 861 +#define OBJ_postalAddress OBJ_X509,16L + +#define LN_postalCode "postalCode" +#define NID_postalCode 661 +#define OBJ_postalCode OBJ_X509,17L + +#define LN_postOfficeBox "postOfficeBox" +#define NID_postOfficeBox 862 +#define OBJ_postOfficeBox OBJ_X509,18L + +#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName" +#define NID_physicalDeliveryOfficeName 863 +#define OBJ_physicalDeliveryOfficeName OBJ_X509,19L + +#define LN_telephoneNumber "telephoneNumber" +#define NID_telephoneNumber 864 +#define OBJ_telephoneNumber OBJ_X509,20L + +#define LN_telexNumber "telexNumber" +#define NID_telexNumber 865 +#define OBJ_telexNumber OBJ_X509,21L + +#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier" +#define NID_teletexTerminalIdentifier 866 +#define OBJ_teletexTerminalIdentifier OBJ_X509,22L + +#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber" +#define NID_facsimileTelephoneNumber 867 +#define OBJ_facsimileTelephoneNumber OBJ_X509,23L + +#define LN_x121Address "x121Address" +#define NID_x121Address 868 +#define OBJ_x121Address OBJ_X509,24L + +#define LN_internationaliSDNNumber "internationaliSDNNumber" +#define NID_internationaliSDNNumber 869 +#define OBJ_internationaliSDNNumber OBJ_X509,25L + +#define LN_registeredAddress "registeredAddress" +#define NID_registeredAddress 870 +#define OBJ_registeredAddress OBJ_X509,26L + +#define LN_destinationIndicator "destinationIndicator" +#define NID_destinationIndicator 871 +#define OBJ_destinationIndicator OBJ_X509,27L + +#define LN_preferredDeliveryMethod "preferredDeliveryMethod" +#define NID_preferredDeliveryMethod 872 +#define OBJ_preferredDeliveryMethod OBJ_X509,28L + +#define LN_presentationAddress "presentationAddress" +#define NID_presentationAddress 873 +#define OBJ_presentationAddress OBJ_X509,29L + +#define LN_supportedApplicationContext "supportedApplicationContext" +#define NID_supportedApplicationContext 874 +#define OBJ_supportedApplicationContext OBJ_X509,30L + +#define SN_member "member" +#define NID_member 875 +#define OBJ_member OBJ_X509,31L + +#define SN_owner "owner" +#define NID_owner 876 +#define OBJ_owner OBJ_X509,32L + +#define LN_roleOccupant "roleOccupant" +#define NID_roleOccupant 877 +#define OBJ_roleOccupant OBJ_X509,33L + +#define SN_seeAlso "seeAlso" +#define NID_seeAlso 878 +#define OBJ_seeAlso OBJ_X509,34L + +#define LN_userPassword "userPassword" +#define NID_userPassword 879 +#define OBJ_userPassword OBJ_X509,35L + +#define LN_userCertificate "userCertificate" +#define NID_userCertificate 880 +#define OBJ_userCertificate OBJ_X509,36L + +#define LN_cACertificate "cACertificate" +#define NID_cACertificate 881 +#define OBJ_cACertificate OBJ_X509,37L + +#define LN_authorityRevocationList "authorityRevocationList" +#define NID_authorityRevocationList 882 +#define OBJ_authorityRevocationList OBJ_X509,38L + +#define LN_certificateRevocationList "certificateRevocationList" +#define NID_certificateRevocationList 883 +#define OBJ_certificateRevocationList OBJ_X509,39L + +#define LN_crossCertificatePair "crossCertificatePair" +#define NID_crossCertificatePair 884 +#define OBJ_crossCertificatePair OBJ_X509,40L + +#define SN_name "name" +#define LN_name "name" +#define NID_name 173 +#define OBJ_name OBJ_X509,41L + +#define SN_givenName "GN" +#define LN_givenName "givenName" +#define NID_givenName 99 +#define OBJ_givenName OBJ_X509,42L + +#define SN_initials "initials" +#define LN_initials "initials" +#define NID_initials 101 +#define OBJ_initials OBJ_X509,43L + +#define LN_generationQualifier "generationQualifier" +#define NID_generationQualifier 509 +#define OBJ_generationQualifier OBJ_X509,44L + +#define LN_x500UniqueIdentifier "x500UniqueIdentifier" +#define NID_x500UniqueIdentifier 503 +#define OBJ_x500UniqueIdentifier OBJ_X509,45L + +#define SN_dnQualifier "dnQualifier" +#define LN_dnQualifier "dnQualifier" +#define NID_dnQualifier 174 +#define OBJ_dnQualifier OBJ_X509,46L + +#define LN_enhancedSearchGuide "enhancedSearchGuide" +#define NID_enhancedSearchGuide 885 +#define OBJ_enhancedSearchGuide OBJ_X509,47L + +#define LN_protocolInformation "protocolInformation" +#define NID_protocolInformation 886 +#define OBJ_protocolInformation OBJ_X509,48L + +#define LN_distinguishedName "distinguishedName" +#define NID_distinguishedName 887 +#define OBJ_distinguishedName OBJ_X509,49L + +#define LN_uniqueMember "uniqueMember" +#define NID_uniqueMember 888 +#define OBJ_uniqueMember OBJ_X509,50L + +#define LN_houseIdentifier "houseIdentifier" +#define NID_houseIdentifier 889 +#define OBJ_houseIdentifier OBJ_X509,51L + +#define LN_supportedAlgorithms "supportedAlgorithms" +#define NID_supportedAlgorithms 890 +#define OBJ_supportedAlgorithms OBJ_X509,52L + +#define LN_deltaRevocationList "deltaRevocationList" +#define NID_deltaRevocationList 891 +#define OBJ_deltaRevocationList OBJ_X509,53L + +#define SN_dmdName "dmdName" +#define NID_dmdName 892 +#define OBJ_dmdName OBJ_X509,54L + +#define LN_pseudonym "pseudonym" +#define NID_pseudonym 510 +#define OBJ_pseudonym OBJ_X509,65L + +#define SN_role "role" +#define LN_role "role" +#define NID_role 400 +#define OBJ_role OBJ_X509,72L + +#define SN_X500algorithms "X500algorithms" +#define LN_X500algorithms "directory services - algorithms" +#define NID_X500algorithms 378 +#define OBJ_X500algorithms OBJ_X500,8L + +#define SN_rsa "RSA" +#define LN_rsa "rsa" +#define NID_rsa 19 +#define OBJ_rsa OBJ_X500algorithms,1L,1L + +#define SN_mdc2WithRSA "RSA-MDC2" +#define LN_mdc2WithRSA "mdc2WithRSA" +#define NID_mdc2WithRSA 96 +#define OBJ_mdc2WithRSA OBJ_X500algorithms,3L,100L + +#define SN_mdc2 "MDC2" +#define LN_mdc2 "mdc2" +#define NID_mdc2 95 +#define OBJ_mdc2 OBJ_X500algorithms,3L,101L + +#define SN_id_ce "id-ce" +#define NID_id_ce 81 +#define OBJ_id_ce OBJ_X500,29L + +#define SN_subject_directory_attributes "subjectDirectoryAttributes" +#define LN_subject_directory_attributes "X509v3 Subject Directory Attributes" +#define NID_subject_directory_attributes 769 +#define OBJ_subject_directory_attributes OBJ_id_ce,9L + +#define SN_subject_key_identifier "subjectKeyIdentifier" +#define LN_subject_key_identifier "X509v3 Subject Key Identifier" +#define NID_subject_key_identifier 82 +#define OBJ_subject_key_identifier OBJ_id_ce,14L + +#define SN_key_usage "keyUsage" +#define LN_key_usage "X509v3 Key Usage" +#define NID_key_usage 83 +#define OBJ_key_usage OBJ_id_ce,15L + +#define SN_private_key_usage_period "privateKeyUsagePeriod" +#define LN_private_key_usage_period "X509v3 Private Key Usage Period" +#define NID_private_key_usage_period 84 +#define OBJ_private_key_usage_period OBJ_id_ce,16L + +#define SN_subject_alt_name "subjectAltName" +#define LN_subject_alt_name "X509v3 Subject Alternative Name" +#define NID_subject_alt_name 85 +#define OBJ_subject_alt_name OBJ_id_ce,17L + +#define SN_issuer_alt_name "issuerAltName" +#define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +#define NID_issuer_alt_name 86 +#define OBJ_issuer_alt_name OBJ_id_ce,18L + +#define SN_basic_constraints "basicConstraints" +#define LN_basic_constraints "X509v3 Basic Constraints" +#define NID_basic_constraints 87 +#define OBJ_basic_constraints OBJ_id_ce,19L + +#define SN_crl_number "crlNumber" +#define LN_crl_number "X509v3 CRL Number" +#define NID_crl_number 88 +#define OBJ_crl_number OBJ_id_ce,20L + +#define SN_crl_reason "CRLReason" +#define LN_crl_reason "X509v3 CRL Reason Code" +#define NID_crl_reason 141 +#define OBJ_crl_reason OBJ_id_ce,21L + +#define SN_invalidity_date "invalidityDate" +#define LN_invalidity_date "Invalidity Date" +#define NID_invalidity_date 142 +#define OBJ_invalidity_date OBJ_id_ce,24L + +#define SN_delta_crl "deltaCRL" +#define LN_delta_crl "X509v3 Delta CRL Indicator" +#define NID_delta_crl 140 +#define OBJ_delta_crl OBJ_id_ce,27L + +#define SN_issuing_distribution_point "issuingDistributionPoint" +#define LN_issuing_distribution_point "X509v3 Issuing Distrubution Point" +#define NID_issuing_distribution_point 770 +#define OBJ_issuing_distribution_point OBJ_id_ce,28L + +#define SN_certificate_issuer "certificateIssuer" +#define LN_certificate_issuer "X509v3 Certificate Issuer" +#define NID_certificate_issuer 771 +#define OBJ_certificate_issuer OBJ_id_ce,29L + +#define SN_name_constraints "nameConstraints" +#define LN_name_constraints "X509v3 Name Constraints" +#define NID_name_constraints 666 +#define OBJ_name_constraints OBJ_id_ce,30L + +#define SN_crl_distribution_points "crlDistributionPoints" +#define LN_crl_distribution_points "X509v3 CRL Distribution Points" +#define NID_crl_distribution_points 103 +#define OBJ_crl_distribution_points OBJ_id_ce,31L + +#define SN_certificate_policies "certificatePolicies" +#define LN_certificate_policies "X509v3 Certificate Policies" +#define NID_certificate_policies 89 +#define OBJ_certificate_policies OBJ_id_ce,32L + +#define SN_any_policy "anyPolicy" +#define LN_any_policy "X509v3 Any Policy" +#define NID_any_policy 746 +#define OBJ_any_policy OBJ_certificate_policies,0L + +#define SN_policy_mappings "policyMappings" +#define LN_policy_mappings "X509v3 Policy Mappings" +#define NID_policy_mappings 747 +#define OBJ_policy_mappings OBJ_id_ce,33L + +#define SN_authority_key_identifier "authorityKeyIdentifier" +#define LN_authority_key_identifier "X509v3 Authority Key Identifier" +#define NID_authority_key_identifier 90 +#define OBJ_authority_key_identifier OBJ_id_ce,35L + +#define SN_policy_constraints "policyConstraints" +#define LN_policy_constraints "X509v3 Policy Constraints" +#define NID_policy_constraints 401 +#define OBJ_policy_constraints OBJ_id_ce,36L + +#define SN_ext_key_usage "extendedKeyUsage" +#define LN_ext_key_usage "X509v3 Extended Key Usage" +#define NID_ext_key_usage 126 +#define OBJ_ext_key_usage OBJ_id_ce,37L + +#define SN_freshest_crl "freshestCRL" +#define LN_freshest_crl "X509v3 Freshest CRL" +#define NID_freshest_crl 857 +#define OBJ_freshest_crl OBJ_id_ce,46L + +#define SN_inhibit_any_policy "inhibitAnyPolicy" +#define LN_inhibit_any_policy "X509v3 Inhibit Any Policy" +#define NID_inhibit_any_policy 748 +#define OBJ_inhibit_any_policy OBJ_id_ce,54L + +#define SN_target_information "targetInformation" +#define LN_target_information "X509v3 AC Targeting" +#define NID_target_information 402 +#define OBJ_target_information OBJ_id_ce,55L + +#define SN_no_rev_avail "noRevAvail" +#define LN_no_rev_avail "X509v3 No Revocation Available" +#define NID_no_rev_avail 403 +#define OBJ_no_rev_avail OBJ_id_ce,56L + +#define SN_anyExtendedKeyUsage "anyExtendedKeyUsage" +#define LN_anyExtendedKeyUsage "Any Extended Key Usage" +#define NID_anyExtendedKeyUsage 910 +#define OBJ_anyExtendedKeyUsage OBJ_ext_key_usage,0L + +#define SN_netscape "Netscape" +#define LN_netscape "Netscape Communications Corp." +#define NID_netscape 57 +#define OBJ_netscape 2L,16L,840L,1L,113730L + +#define SN_netscape_cert_extension "nsCertExt" +#define LN_netscape_cert_extension "Netscape Certificate Extension" +#define NID_netscape_cert_extension 58 +#define OBJ_netscape_cert_extension OBJ_netscape,1L + +#define SN_netscape_data_type "nsDataType" +#define LN_netscape_data_type "Netscape Data Type" +#define NID_netscape_data_type 59 +#define OBJ_netscape_data_type OBJ_netscape,2L + +#define SN_netscape_cert_type "nsCertType" +#define LN_netscape_cert_type "Netscape Cert Type" +#define NID_netscape_cert_type 71 +#define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L + +#define SN_netscape_base_url "nsBaseUrl" +#define LN_netscape_base_url "Netscape Base Url" +#define NID_netscape_base_url 72 +#define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L + +#define SN_netscape_revocation_url "nsRevocationUrl" +#define LN_netscape_revocation_url "Netscape Revocation Url" +#define NID_netscape_revocation_url 73 +#define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L + +#define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +#define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +#define NID_netscape_ca_revocation_url 74 +#define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L + +#define SN_netscape_renewal_url "nsRenewalUrl" +#define LN_netscape_renewal_url "Netscape Renewal Url" +#define NID_netscape_renewal_url 75 +#define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L + +#define SN_netscape_ca_policy_url "nsCaPolicyUrl" +#define LN_netscape_ca_policy_url "Netscape CA Policy Url" +#define NID_netscape_ca_policy_url 76 +#define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L + +#define SN_netscape_ssl_server_name "nsSslServerName" +#define LN_netscape_ssl_server_name "Netscape SSL Server Name" +#define NID_netscape_ssl_server_name 77 +#define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L + +#define SN_netscape_comment "nsComment" +#define LN_netscape_comment "Netscape Comment" +#define NID_netscape_comment 78 +#define OBJ_netscape_comment OBJ_netscape_cert_extension,13L + +#define SN_netscape_cert_sequence "nsCertSequence" +#define LN_netscape_cert_sequence "Netscape Certificate Sequence" +#define NID_netscape_cert_sequence 79 +#define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L + +#define SN_ns_sgc "nsSGC" +#define LN_ns_sgc "Netscape Server Gated Crypto" +#define NID_ns_sgc 139 +#define OBJ_ns_sgc OBJ_netscape,4L,1L + +#define SN_org "ORG" +#define LN_org "org" +#define NID_org 379 +#define OBJ_org OBJ_iso,3L + +#define SN_dod "DOD" +#define LN_dod "dod" +#define NID_dod 380 +#define OBJ_dod OBJ_org,6L + +#define SN_iana "IANA" +#define LN_iana "iana" +#define NID_iana 381 +#define OBJ_iana OBJ_dod,1L + +#define OBJ_internet OBJ_iana + +#define SN_Directory "directory" +#define LN_Directory "Directory" +#define NID_Directory 382 +#define OBJ_Directory OBJ_internet,1L + +#define SN_Management "mgmt" +#define LN_Management "Management" +#define NID_Management 383 +#define OBJ_Management OBJ_internet,2L + +#define SN_Experimental "experimental" +#define LN_Experimental "Experimental" +#define NID_Experimental 384 +#define OBJ_Experimental OBJ_internet,3L + +#define SN_Private "private" +#define LN_Private "Private" +#define NID_Private 385 +#define OBJ_Private OBJ_internet,4L + +#define SN_Security "security" +#define LN_Security "Security" +#define NID_Security 386 +#define OBJ_Security OBJ_internet,5L + +#define SN_SNMPv2 "snmpv2" +#define LN_SNMPv2 "SNMPv2" +#define NID_SNMPv2 387 +#define OBJ_SNMPv2 OBJ_internet,6L + +#define LN_Mail "Mail" +#define NID_Mail 388 +#define OBJ_Mail OBJ_internet,7L + +#define SN_Enterprises "enterprises" +#define LN_Enterprises "Enterprises" +#define NID_Enterprises 389 +#define OBJ_Enterprises OBJ_Private,1L + +#define SN_dcObject "dcobject" +#define LN_dcObject "dcObject" +#define NID_dcObject 390 +#define OBJ_dcObject OBJ_Enterprises,1466L,344L + +#define SN_mime_mhs "mime-mhs" +#define LN_mime_mhs "MIME MHS" +#define NID_mime_mhs 504 +#define OBJ_mime_mhs OBJ_Mail,1L + +#define SN_mime_mhs_headings "mime-mhs-headings" +#define LN_mime_mhs_headings "mime-mhs-headings" +#define NID_mime_mhs_headings 505 +#define OBJ_mime_mhs_headings OBJ_mime_mhs,1L + +#define SN_mime_mhs_bodies "mime-mhs-bodies" +#define LN_mime_mhs_bodies "mime-mhs-bodies" +#define NID_mime_mhs_bodies 506 +#define OBJ_mime_mhs_bodies OBJ_mime_mhs,2L + +#define SN_id_hex_partial_message "id-hex-partial-message" +#define LN_id_hex_partial_message "id-hex-partial-message" +#define NID_id_hex_partial_message 507 +#define OBJ_id_hex_partial_message OBJ_mime_mhs_headings,1L + +#define SN_id_hex_multipart_message "id-hex-multipart-message" +#define LN_id_hex_multipart_message "id-hex-multipart-message" +#define NID_id_hex_multipart_message 508 +#define OBJ_id_hex_multipart_message OBJ_mime_mhs_headings,2L + +#define SN_rle_compression "RLE" +#define LN_rle_compression "run length compression" +#define NID_rle_compression 124 +#define OBJ_rle_compression 1L,1L,1L,1L,666L,1L + +#define SN_zlib_compression "ZLIB" +#define LN_zlib_compression "zlib compression" +#define NID_zlib_compression 125 +#define OBJ_zlib_compression OBJ_id_smime_alg,8L + +#define OBJ_csor 2L,16L,840L,1L,101L,3L + +#define OBJ_nistAlgorithms OBJ_csor,4L + +#define OBJ_aes OBJ_nistAlgorithms,1L + +#define SN_aes_128_ecb "AES-128-ECB" +#define LN_aes_128_ecb "aes-128-ecb" +#define NID_aes_128_ecb 418 +#define OBJ_aes_128_ecb OBJ_aes,1L + +#define SN_aes_128_cbc "AES-128-CBC" +#define LN_aes_128_cbc "aes-128-cbc" +#define NID_aes_128_cbc 419 +#define OBJ_aes_128_cbc OBJ_aes,2L + +#define SN_aes_128_ofb128 "AES-128-OFB" +#define LN_aes_128_ofb128 "aes-128-ofb" +#define NID_aes_128_ofb128 420 +#define OBJ_aes_128_ofb128 OBJ_aes,3L + +#define SN_aes_128_cfb128 "AES-128-CFB" +#define LN_aes_128_cfb128 "aes-128-cfb" +#define NID_aes_128_cfb128 421 +#define OBJ_aes_128_cfb128 OBJ_aes,4L + +#define SN_id_aes128_wrap "id-aes128-wrap" +#define NID_id_aes128_wrap 788 +#define OBJ_id_aes128_wrap OBJ_aes,5L + +#define SN_aes_128_gcm "id-aes128-GCM" +#define LN_aes_128_gcm "aes-128-gcm" +#define NID_aes_128_gcm 895 +#define OBJ_aes_128_gcm OBJ_aes,6L + +#define SN_aes_128_ccm "id-aes128-CCM" +#define LN_aes_128_ccm "aes-128-ccm" +#define NID_aes_128_ccm 896 +#define OBJ_aes_128_ccm OBJ_aes,7L + +#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad" +#define NID_id_aes128_wrap_pad 897 +#define OBJ_id_aes128_wrap_pad OBJ_aes,8L + +#define SN_aes_192_ecb "AES-192-ECB" +#define LN_aes_192_ecb "aes-192-ecb" +#define NID_aes_192_ecb 422 +#define OBJ_aes_192_ecb OBJ_aes,21L + +#define SN_aes_192_cbc "AES-192-CBC" +#define LN_aes_192_cbc "aes-192-cbc" +#define NID_aes_192_cbc 423 +#define OBJ_aes_192_cbc OBJ_aes,22L + +#define SN_aes_192_ofb128 "AES-192-OFB" +#define LN_aes_192_ofb128 "aes-192-ofb" +#define NID_aes_192_ofb128 424 +#define OBJ_aes_192_ofb128 OBJ_aes,23L + +#define SN_aes_192_cfb128 "AES-192-CFB" +#define LN_aes_192_cfb128 "aes-192-cfb" +#define NID_aes_192_cfb128 425 +#define OBJ_aes_192_cfb128 OBJ_aes,24L + +#define SN_id_aes192_wrap "id-aes192-wrap" +#define NID_id_aes192_wrap 789 +#define OBJ_id_aes192_wrap OBJ_aes,25L + +#define SN_aes_192_gcm "id-aes192-GCM" +#define LN_aes_192_gcm "aes-192-gcm" +#define NID_aes_192_gcm 898 +#define OBJ_aes_192_gcm OBJ_aes,26L + +#define SN_aes_192_ccm "id-aes192-CCM" +#define LN_aes_192_ccm "aes-192-ccm" +#define NID_aes_192_ccm 899 +#define OBJ_aes_192_ccm OBJ_aes,27L + +#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad" +#define NID_id_aes192_wrap_pad 900 +#define OBJ_id_aes192_wrap_pad OBJ_aes,28L + +#define SN_aes_256_ecb "AES-256-ECB" +#define LN_aes_256_ecb "aes-256-ecb" +#define NID_aes_256_ecb 426 +#define OBJ_aes_256_ecb OBJ_aes,41L + +#define SN_aes_256_cbc "AES-256-CBC" +#define LN_aes_256_cbc "aes-256-cbc" +#define NID_aes_256_cbc 427 +#define OBJ_aes_256_cbc OBJ_aes,42L + +#define SN_aes_256_ofb128 "AES-256-OFB" +#define LN_aes_256_ofb128 "aes-256-ofb" +#define NID_aes_256_ofb128 428 +#define OBJ_aes_256_ofb128 OBJ_aes,43L + +#define SN_aes_256_cfb128 "AES-256-CFB" +#define LN_aes_256_cfb128 "aes-256-cfb" +#define NID_aes_256_cfb128 429 +#define OBJ_aes_256_cfb128 OBJ_aes,44L + +#define SN_id_aes256_wrap "id-aes256-wrap" +#define NID_id_aes256_wrap 790 +#define OBJ_id_aes256_wrap OBJ_aes,45L + +#define SN_aes_256_gcm "id-aes256-GCM" +#define LN_aes_256_gcm "aes-256-gcm" +#define NID_aes_256_gcm 901 +#define OBJ_aes_256_gcm OBJ_aes,46L + +#define SN_aes_256_ccm "id-aes256-CCM" +#define LN_aes_256_ccm "aes-256-ccm" +#define NID_aes_256_ccm 902 +#define OBJ_aes_256_ccm OBJ_aes,47L + +#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad" +#define NID_id_aes256_wrap_pad 903 +#define OBJ_id_aes256_wrap_pad OBJ_aes,48L + +#define SN_aes_128_cfb1 "AES-128-CFB1" +#define LN_aes_128_cfb1 "aes-128-cfb1" +#define NID_aes_128_cfb1 650 + +#define SN_aes_192_cfb1 "AES-192-CFB1" +#define LN_aes_192_cfb1 "aes-192-cfb1" +#define NID_aes_192_cfb1 651 + +#define SN_aes_256_cfb1 "AES-256-CFB1" +#define LN_aes_256_cfb1 "aes-256-cfb1" +#define NID_aes_256_cfb1 652 + +#define SN_aes_128_cfb8 "AES-128-CFB8" +#define LN_aes_128_cfb8 "aes-128-cfb8" +#define NID_aes_128_cfb8 653 + +#define SN_aes_192_cfb8 "AES-192-CFB8" +#define LN_aes_192_cfb8 "aes-192-cfb8" +#define NID_aes_192_cfb8 654 + +#define SN_aes_256_cfb8 "AES-256-CFB8" +#define LN_aes_256_cfb8 "aes-256-cfb8" +#define NID_aes_256_cfb8 655 + +#define SN_aes_128_ctr "AES-128-CTR" +#define LN_aes_128_ctr "aes-128-ctr" +#define NID_aes_128_ctr 904 + +#define SN_aes_192_ctr "AES-192-CTR" +#define LN_aes_192_ctr "aes-192-ctr" +#define NID_aes_192_ctr 905 + +#define SN_aes_256_ctr "AES-256-CTR" +#define LN_aes_256_ctr "aes-256-ctr" +#define NID_aes_256_ctr 906 + +#define SN_aes_128_xts "AES-128-XTS" +#define LN_aes_128_xts "aes-128-xts" +#define NID_aes_128_xts 913 + +#define SN_aes_256_xts "AES-256-XTS" +#define LN_aes_256_xts "aes-256-xts" +#define NID_aes_256_xts 914 + +#define SN_des_cfb1 "DES-CFB1" +#define LN_des_cfb1 "des-cfb1" +#define NID_des_cfb1 656 + +#define SN_des_cfb8 "DES-CFB8" +#define LN_des_cfb8 "des-cfb8" +#define NID_des_cfb8 657 + +#define SN_des_ede3_cfb1 "DES-EDE3-CFB1" +#define LN_des_ede3_cfb1 "des-ede3-cfb1" +#define NID_des_ede3_cfb1 658 + +#define SN_des_ede3_cfb8 "DES-EDE3-CFB8" +#define LN_des_ede3_cfb8 "des-ede3-cfb8" +#define NID_des_ede3_cfb8 659 + +#define OBJ_nist_hashalgs OBJ_nistAlgorithms,2L + +#define SN_sha256 "SHA256" +#define LN_sha256 "sha256" +#define NID_sha256 672 +#define OBJ_sha256 OBJ_nist_hashalgs,1L + +#define SN_sha384 "SHA384" +#define LN_sha384 "sha384" +#define NID_sha384 673 +#define OBJ_sha384 OBJ_nist_hashalgs,2L + +#define SN_sha512 "SHA512" +#define LN_sha512 "sha512" +#define NID_sha512 674 +#define OBJ_sha512 OBJ_nist_hashalgs,3L + +#define SN_sha224 "SHA224" +#define LN_sha224 "sha224" +#define NID_sha224 675 +#define OBJ_sha224 OBJ_nist_hashalgs,4L + +#define OBJ_dsa_with_sha2 OBJ_nistAlgorithms,3L + +#define SN_dsa_with_SHA224 "dsa_with_SHA224" +#define NID_dsa_with_SHA224 802 +#define OBJ_dsa_with_SHA224 OBJ_dsa_with_sha2,1L + +#define SN_dsa_with_SHA256 "dsa_with_SHA256" +#define NID_dsa_with_SHA256 803 +#define OBJ_dsa_with_SHA256 OBJ_dsa_with_sha2,2L + +#define SN_hold_instruction_code "holdInstructionCode" +#define LN_hold_instruction_code "Hold Instruction Code" +#define NID_hold_instruction_code 430 +#define OBJ_hold_instruction_code OBJ_id_ce,23L + +#define OBJ_holdInstruction OBJ_X9_57,2L + +#define SN_hold_instruction_none "holdInstructionNone" +#define LN_hold_instruction_none "Hold Instruction None" +#define NID_hold_instruction_none 431 +#define OBJ_hold_instruction_none OBJ_holdInstruction,1L + +#define SN_hold_instruction_call_issuer "holdInstructionCallIssuer" +#define LN_hold_instruction_call_issuer "Hold Instruction Call Issuer" +#define NID_hold_instruction_call_issuer 432 +#define OBJ_hold_instruction_call_issuer OBJ_holdInstruction,2L + +#define SN_hold_instruction_reject "holdInstructionReject" +#define LN_hold_instruction_reject "Hold Instruction Reject" +#define NID_hold_instruction_reject 433 +#define OBJ_hold_instruction_reject OBJ_holdInstruction,3L + +#define SN_data "data" +#define NID_data 434 +#define OBJ_data OBJ_itu_t,9L + +#define SN_pss "pss" +#define NID_pss 435 +#define OBJ_pss OBJ_data,2342L + +#define SN_ucl "ucl" +#define NID_ucl 436 +#define OBJ_ucl OBJ_pss,19200300L + +#define SN_pilot "pilot" +#define NID_pilot 437 +#define OBJ_pilot OBJ_ucl,100L + +#define LN_pilotAttributeType "pilotAttributeType" +#define NID_pilotAttributeType 438 +#define OBJ_pilotAttributeType OBJ_pilot,1L + +#define LN_pilotAttributeSyntax "pilotAttributeSyntax" +#define NID_pilotAttributeSyntax 439 +#define OBJ_pilotAttributeSyntax OBJ_pilot,3L + +#define LN_pilotObjectClass "pilotObjectClass" +#define NID_pilotObjectClass 440 +#define OBJ_pilotObjectClass OBJ_pilot,4L + +#define LN_pilotGroups "pilotGroups" +#define NID_pilotGroups 441 +#define OBJ_pilotGroups OBJ_pilot,10L + +#define LN_iA5StringSyntax "iA5StringSyntax" +#define NID_iA5StringSyntax 442 +#define OBJ_iA5StringSyntax OBJ_pilotAttributeSyntax,4L + +#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax" +#define NID_caseIgnoreIA5StringSyntax 443 +#define OBJ_caseIgnoreIA5StringSyntax OBJ_pilotAttributeSyntax,5L + +#define LN_pilotObject "pilotObject" +#define NID_pilotObject 444 +#define OBJ_pilotObject OBJ_pilotObjectClass,3L + +#define LN_pilotPerson "pilotPerson" +#define NID_pilotPerson 445 +#define OBJ_pilotPerson OBJ_pilotObjectClass,4L + +#define SN_account "account" +#define NID_account 446 +#define OBJ_account OBJ_pilotObjectClass,5L + +#define SN_document "document" +#define NID_document 447 +#define OBJ_document OBJ_pilotObjectClass,6L + +#define SN_room "room" +#define NID_room 448 +#define OBJ_room OBJ_pilotObjectClass,7L + +#define LN_documentSeries "documentSeries" +#define NID_documentSeries 449 +#define OBJ_documentSeries OBJ_pilotObjectClass,9L + +#define SN_Domain "domain" +#define LN_Domain "Domain" +#define NID_Domain 392 +#define OBJ_Domain OBJ_pilotObjectClass,13L + +#define LN_rFC822localPart "rFC822localPart" +#define NID_rFC822localPart 450 +#define OBJ_rFC822localPart OBJ_pilotObjectClass,14L + +#define LN_dNSDomain "dNSDomain" +#define NID_dNSDomain 451 +#define OBJ_dNSDomain OBJ_pilotObjectClass,15L + +#define LN_domainRelatedObject "domainRelatedObject" +#define NID_domainRelatedObject 452 +#define OBJ_domainRelatedObject OBJ_pilotObjectClass,17L + +#define LN_friendlyCountry "friendlyCountry" +#define NID_friendlyCountry 453 +#define OBJ_friendlyCountry OBJ_pilotObjectClass,18L + +#define LN_simpleSecurityObject "simpleSecurityObject" +#define NID_simpleSecurityObject 454 +#define OBJ_simpleSecurityObject OBJ_pilotObjectClass,19L + +#define LN_pilotOrganization "pilotOrganization" +#define NID_pilotOrganization 455 +#define OBJ_pilotOrganization OBJ_pilotObjectClass,20L + +#define LN_pilotDSA "pilotDSA" +#define NID_pilotDSA 456 +#define OBJ_pilotDSA OBJ_pilotObjectClass,21L + +#define LN_qualityLabelledData "qualityLabelledData" +#define NID_qualityLabelledData 457 +#define OBJ_qualityLabelledData OBJ_pilotObjectClass,22L + +#define SN_userId "UID" +#define LN_userId "userId" +#define NID_userId 458 +#define OBJ_userId OBJ_pilotAttributeType,1L + +#define LN_textEncodedORAddress "textEncodedORAddress" +#define NID_textEncodedORAddress 459 +#define OBJ_textEncodedORAddress OBJ_pilotAttributeType,2L + +#define SN_rfc822Mailbox "mail" +#define LN_rfc822Mailbox "rfc822Mailbox" +#define NID_rfc822Mailbox 460 +#define OBJ_rfc822Mailbox OBJ_pilotAttributeType,3L + +#define SN_info "info" +#define NID_info 461 +#define OBJ_info OBJ_pilotAttributeType,4L + +#define LN_favouriteDrink "favouriteDrink" +#define NID_favouriteDrink 462 +#define OBJ_favouriteDrink OBJ_pilotAttributeType,5L + +#define LN_roomNumber "roomNumber" +#define NID_roomNumber 463 +#define OBJ_roomNumber OBJ_pilotAttributeType,6L + +#define SN_photo "photo" +#define NID_photo 464 +#define OBJ_photo OBJ_pilotAttributeType,7L + +#define LN_userClass "userClass" +#define NID_userClass 465 +#define OBJ_userClass OBJ_pilotAttributeType,8L + +#define SN_host "host" +#define NID_host 466 +#define OBJ_host OBJ_pilotAttributeType,9L + +#define SN_manager "manager" +#define NID_manager 467 +#define OBJ_manager OBJ_pilotAttributeType,10L + +#define LN_documentIdentifier "documentIdentifier" +#define NID_documentIdentifier 468 +#define OBJ_documentIdentifier OBJ_pilotAttributeType,11L + +#define LN_documentTitle "documentTitle" +#define NID_documentTitle 469 +#define OBJ_documentTitle OBJ_pilotAttributeType,12L + +#define LN_documentVersion "documentVersion" +#define NID_documentVersion 470 +#define OBJ_documentVersion OBJ_pilotAttributeType,13L + +#define LN_documentAuthor "documentAuthor" +#define NID_documentAuthor 471 +#define OBJ_documentAuthor OBJ_pilotAttributeType,14L + +#define LN_documentLocation "documentLocation" +#define NID_documentLocation 472 +#define OBJ_documentLocation OBJ_pilotAttributeType,15L + +#define LN_homeTelephoneNumber "homeTelephoneNumber" +#define NID_homeTelephoneNumber 473 +#define OBJ_homeTelephoneNumber OBJ_pilotAttributeType,20L + +#define SN_secretary "secretary" +#define NID_secretary 474 +#define OBJ_secretary OBJ_pilotAttributeType,21L + +#define LN_otherMailbox "otherMailbox" +#define NID_otherMailbox 475 +#define OBJ_otherMailbox OBJ_pilotAttributeType,22L + +#define LN_lastModifiedTime "lastModifiedTime" +#define NID_lastModifiedTime 476 +#define OBJ_lastModifiedTime OBJ_pilotAttributeType,23L + +#define LN_lastModifiedBy "lastModifiedBy" +#define NID_lastModifiedBy 477 +#define OBJ_lastModifiedBy OBJ_pilotAttributeType,24L + +#define SN_domainComponent "DC" +#define LN_domainComponent "domainComponent" +#define NID_domainComponent 391 +#define OBJ_domainComponent OBJ_pilotAttributeType,25L + +#define LN_aRecord "aRecord" +#define NID_aRecord 478 +#define OBJ_aRecord OBJ_pilotAttributeType,26L + +#define LN_pilotAttributeType27 "pilotAttributeType27" +#define NID_pilotAttributeType27 479 +#define OBJ_pilotAttributeType27 OBJ_pilotAttributeType,27L + +#define LN_mXRecord "mXRecord" +#define NID_mXRecord 480 +#define OBJ_mXRecord OBJ_pilotAttributeType,28L + +#define LN_nSRecord "nSRecord" +#define NID_nSRecord 481 +#define OBJ_nSRecord OBJ_pilotAttributeType,29L + +#define LN_sOARecord "sOARecord" +#define NID_sOARecord 482 +#define OBJ_sOARecord OBJ_pilotAttributeType,30L + +#define LN_cNAMERecord "cNAMERecord" +#define NID_cNAMERecord 483 +#define OBJ_cNAMERecord OBJ_pilotAttributeType,31L + +#define LN_associatedDomain "associatedDomain" +#define NID_associatedDomain 484 +#define OBJ_associatedDomain OBJ_pilotAttributeType,37L + +#define LN_associatedName "associatedName" +#define NID_associatedName 485 +#define OBJ_associatedName OBJ_pilotAttributeType,38L + +#define LN_homePostalAddress "homePostalAddress" +#define NID_homePostalAddress 486 +#define OBJ_homePostalAddress OBJ_pilotAttributeType,39L + +#define LN_personalTitle "personalTitle" +#define NID_personalTitle 487 +#define OBJ_personalTitle OBJ_pilotAttributeType,40L + +#define LN_mobileTelephoneNumber "mobileTelephoneNumber" +#define NID_mobileTelephoneNumber 488 +#define OBJ_mobileTelephoneNumber OBJ_pilotAttributeType,41L + +#define LN_pagerTelephoneNumber "pagerTelephoneNumber" +#define NID_pagerTelephoneNumber 489 +#define OBJ_pagerTelephoneNumber OBJ_pilotAttributeType,42L + +#define LN_friendlyCountryName "friendlyCountryName" +#define NID_friendlyCountryName 490 +#define OBJ_friendlyCountryName OBJ_pilotAttributeType,43L + +#define LN_organizationalStatus "organizationalStatus" +#define NID_organizationalStatus 491 +#define OBJ_organizationalStatus OBJ_pilotAttributeType,45L + +#define LN_janetMailbox "janetMailbox" +#define NID_janetMailbox 492 +#define OBJ_janetMailbox OBJ_pilotAttributeType,46L + +#define LN_mailPreferenceOption "mailPreferenceOption" +#define NID_mailPreferenceOption 493 +#define OBJ_mailPreferenceOption OBJ_pilotAttributeType,47L + +#define LN_buildingName "buildingName" +#define NID_buildingName 494 +#define OBJ_buildingName OBJ_pilotAttributeType,48L + +#define LN_dSAQuality "dSAQuality" +#define NID_dSAQuality 495 +#define OBJ_dSAQuality OBJ_pilotAttributeType,49L + +#define LN_singleLevelQuality "singleLevelQuality" +#define NID_singleLevelQuality 496 +#define OBJ_singleLevelQuality OBJ_pilotAttributeType,50L + +#define LN_subtreeMinimumQuality "subtreeMinimumQuality" +#define NID_subtreeMinimumQuality 497 +#define OBJ_subtreeMinimumQuality OBJ_pilotAttributeType,51L + +#define LN_subtreeMaximumQuality "subtreeMaximumQuality" +#define NID_subtreeMaximumQuality 498 +#define OBJ_subtreeMaximumQuality OBJ_pilotAttributeType,52L + +#define LN_personalSignature "personalSignature" +#define NID_personalSignature 499 +#define OBJ_personalSignature OBJ_pilotAttributeType,53L + +#define LN_dITRedirect "dITRedirect" +#define NID_dITRedirect 500 +#define OBJ_dITRedirect OBJ_pilotAttributeType,54L + +#define SN_audio "audio" +#define NID_audio 501 +#define OBJ_audio OBJ_pilotAttributeType,55L + +#define LN_documentPublisher "documentPublisher" +#define NID_documentPublisher 502 +#define OBJ_documentPublisher OBJ_pilotAttributeType,56L + +#define SN_id_set "id-set" +#define LN_id_set "Secure Electronic Transactions" +#define NID_id_set 512 +#define OBJ_id_set OBJ_international_organizations,42L + +#define SN_set_ctype "set-ctype" +#define LN_set_ctype "content types" +#define NID_set_ctype 513 +#define OBJ_set_ctype OBJ_id_set,0L + +#define SN_set_msgExt "set-msgExt" +#define LN_set_msgExt "message extensions" +#define NID_set_msgExt 514 +#define OBJ_set_msgExt OBJ_id_set,1L + +#define SN_set_attr "set-attr" +#define NID_set_attr 515 +#define OBJ_set_attr OBJ_id_set,3L + +#define SN_set_policy "set-policy" +#define NID_set_policy 516 +#define OBJ_set_policy OBJ_id_set,5L + +#define SN_set_certExt "set-certExt" +#define LN_set_certExt "certificate extensions" +#define NID_set_certExt 517 +#define OBJ_set_certExt OBJ_id_set,7L + +#define SN_set_brand "set-brand" +#define NID_set_brand 518 +#define OBJ_set_brand OBJ_id_set,8L + +#define SN_setct_PANData "setct-PANData" +#define NID_setct_PANData 519 +#define OBJ_setct_PANData OBJ_set_ctype,0L + +#define SN_setct_PANToken "setct-PANToken" +#define NID_setct_PANToken 520 +#define OBJ_setct_PANToken OBJ_set_ctype,1L + +#define SN_setct_PANOnly "setct-PANOnly" +#define NID_setct_PANOnly 521 +#define OBJ_setct_PANOnly OBJ_set_ctype,2L + +#define SN_setct_OIData "setct-OIData" +#define NID_setct_OIData 522 +#define OBJ_setct_OIData OBJ_set_ctype,3L + +#define SN_setct_PI "setct-PI" +#define NID_setct_PI 523 +#define OBJ_setct_PI OBJ_set_ctype,4L + +#define SN_setct_PIData "setct-PIData" +#define NID_setct_PIData 524 +#define OBJ_setct_PIData OBJ_set_ctype,5L + +#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned" +#define NID_setct_PIDataUnsigned 525 +#define OBJ_setct_PIDataUnsigned OBJ_set_ctype,6L + +#define SN_setct_HODInput "setct-HODInput" +#define NID_setct_HODInput 526 +#define OBJ_setct_HODInput OBJ_set_ctype,7L + +#define SN_setct_AuthResBaggage "setct-AuthResBaggage" +#define NID_setct_AuthResBaggage 527 +#define OBJ_setct_AuthResBaggage OBJ_set_ctype,8L + +#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage" +#define NID_setct_AuthRevReqBaggage 528 +#define OBJ_setct_AuthRevReqBaggage OBJ_set_ctype,9L + +#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage" +#define NID_setct_AuthRevResBaggage 529 +#define OBJ_setct_AuthRevResBaggage OBJ_set_ctype,10L + +#define SN_setct_CapTokenSeq "setct-CapTokenSeq" +#define NID_setct_CapTokenSeq 530 +#define OBJ_setct_CapTokenSeq OBJ_set_ctype,11L + +#define SN_setct_PInitResData "setct-PInitResData" +#define NID_setct_PInitResData 531 +#define OBJ_setct_PInitResData OBJ_set_ctype,12L + +#define SN_setct_PI_TBS "setct-PI-TBS" +#define NID_setct_PI_TBS 532 +#define OBJ_setct_PI_TBS OBJ_set_ctype,13L + +#define SN_setct_PResData "setct-PResData" +#define NID_setct_PResData 533 +#define OBJ_setct_PResData OBJ_set_ctype,14L + +#define SN_setct_AuthReqTBS "setct-AuthReqTBS" +#define NID_setct_AuthReqTBS 534 +#define OBJ_setct_AuthReqTBS OBJ_set_ctype,16L + +#define SN_setct_AuthResTBS "setct-AuthResTBS" +#define NID_setct_AuthResTBS 535 +#define OBJ_setct_AuthResTBS OBJ_set_ctype,17L + +#define SN_setct_AuthResTBSX "setct-AuthResTBSX" +#define NID_setct_AuthResTBSX 536 +#define OBJ_setct_AuthResTBSX OBJ_set_ctype,18L + +#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS" +#define NID_setct_AuthTokenTBS 537 +#define OBJ_setct_AuthTokenTBS OBJ_set_ctype,19L + +#define SN_setct_CapTokenData "setct-CapTokenData" +#define NID_setct_CapTokenData 538 +#define OBJ_setct_CapTokenData OBJ_set_ctype,20L + +#define SN_setct_CapTokenTBS "setct-CapTokenTBS" +#define NID_setct_CapTokenTBS 539 +#define OBJ_setct_CapTokenTBS OBJ_set_ctype,21L + +#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg" +#define NID_setct_AcqCardCodeMsg 540 +#define OBJ_setct_AcqCardCodeMsg OBJ_set_ctype,22L + +#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS" +#define NID_setct_AuthRevReqTBS 541 +#define OBJ_setct_AuthRevReqTBS OBJ_set_ctype,23L + +#define SN_setct_AuthRevResData "setct-AuthRevResData" +#define NID_setct_AuthRevResData 542 +#define OBJ_setct_AuthRevResData OBJ_set_ctype,24L + +#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS" +#define NID_setct_AuthRevResTBS 543 +#define OBJ_setct_AuthRevResTBS OBJ_set_ctype,25L + +#define SN_setct_CapReqTBS "setct-CapReqTBS" +#define NID_setct_CapReqTBS 544 +#define OBJ_setct_CapReqTBS OBJ_set_ctype,26L + +#define SN_setct_CapReqTBSX "setct-CapReqTBSX" +#define NID_setct_CapReqTBSX 545 +#define OBJ_setct_CapReqTBSX OBJ_set_ctype,27L + +#define SN_setct_CapResData "setct-CapResData" +#define NID_setct_CapResData 546 +#define OBJ_setct_CapResData OBJ_set_ctype,28L + +#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS" +#define NID_setct_CapRevReqTBS 547 +#define OBJ_setct_CapRevReqTBS OBJ_set_ctype,29L + +#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX" +#define NID_setct_CapRevReqTBSX 548 +#define OBJ_setct_CapRevReqTBSX OBJ_set_ctype,30L + +#define SN_setct_CapRevResData "setct-CapRevResData" +#define NID_setct_CapRevResData 549 +#define OBJ_setct_CapRevResData OBJ_set_ctype,31L + +#define SN_setct_CredReqTBS "setct-CredReqTBS" +#define NID_setct_CredReqTBS 550 +#define OBJ_setct_CredReqTBS OBJ_set_ctype,32L + +#define SN_setct_CredReqTBSX "setct-CredReqTBSX" +#define NID_setct_CredReqTBSX 551 +#define OBJ_setct_CredReqTBSX OBJ_set_ctype,33L + +#define SN_setct_CredResData "setct-CredResData" +#define NID_setct_CredResData 552 +#define OBJ_setct_CredResData OBJ_set_ctype,34L + +#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS" +#define NID_setct_CredRevReqTBS 553 +#define OBJ_setct_CredRevReqTBS OBJ_set_ctype,35L + +#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX" +#define NID_setct_CredRevReqTBSX 554 +#define OBJ_setct_CredRevReqTBSX OBJ_set_ctype,36L + +#define SN_setct_CredRevResData "setct-CredRevResData" +#define NID_setct_CredRevResData 555 +#define OBJ_setct_CredRevResData OBJ_set_ctype,37L + +#define SN_setct_PCertReqData "setct-PCertReqData" +#define NID_setct_PCertReqData 556 +#define OBJ_setct_PCertReqData OBJ_set_ctype,38L + +#define SN_setct_PCertResTBS "setct-PCertResTBS" +#define NID_setct_PCertResTBS 557 +#define OBJ_setct_PCertResTBS OBJ_set_ctype,39L + +#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData" +#define NID_setct_BatchAdminReqData 558 +#define OBJ_setct_BatchAdminReqData OBJ_set_ctype,40L + +#define SN_setct_BatchAdminResData "setct-BatchAdminResData" +#define NID_setct_BatchAdminResData 559 +#define OBJ_setct_BatchAdminResData OBJ_set_ctype,41L + +#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS" +#define NID_setct_CardCInitResTBS 560 +#define OBJ_setct_CardCInitResTBS OBJ_set_ctype,42L + +#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS" +#define NID_setct_MeAqCInitResTBS 561 +#define OBJ_setct_MeAqCInitResTBS OBJ_set_ctype,43L + +#define SN_setct_RegFormResTBS "setct-RegFormResTBS" +#define NID_setct_RegFormResTBS 562 +#define OBJ_setct_RegFormResTBS OBJ_set_ctype,44L + +#define SN_setct_CertReqData "setct-CertReqData" +#define NID_setct_CertReqData 563 +#define OBJ_setct_CertReqData OBJ_set_ctype,45L + +#define SN_setct_CertReqTBS "setct-CertReqTBS" +#define NID_setct_CertReqTBS 564 +#define OBJ_setct_CertReqTBS OBJ_set_ctype,46L + +#define SN_setct_CertResData "setct-CertResData" +#define NID_setct_CertResData 565 +#define OBJ_setct_CertResData OBJ_set_ctype,47L + +#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS" +#define NID_setct_CertInqReqTBS 566 +#define OBJ_setct_CertInqReqTBS OBJ_set_ctype,48L + +#define SN_setct_ErrorTBS "setct-ErrorTBS" +#define NID_setct_ErrorTBS 567 +#define OBJ_setct_ErrorTBS OBJ_set_ctype,49L + +#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE" +#define NID_setct_PIDualSignedTBE 568 +#define OBJ_setct_PIDualSignedTBE OBJ_set_ctype,50L + +#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE" +#define NID_setct_PIUnsignedTBE 569 +#define OBJ_setct_PIUnsignedTBE OBJ_set_ctype,51L + +#define SN_setct_AuthReqTBE "setct-AuthReqTBE" +#define NID_setct_AuthReqTBE 570 +#define OBJ_setct_AuthReqTBE OBJ_set_ctype,52L + +#define SN_setct_AuthResTBE "setct-AuthResTBE" +#define NID_setct_AuthResTBE 571 +#define OBJ_setct_AuthResTBE OBJ_set_ctype,53L + +#define SN_setct_AuthResTBEX "setct-AuthResTBEX" +#define NID_setct_AuthResTBEX 572 +#define OBJ_setct_AuthResTBEX OBJ_set_ctype,54L + +#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE" +#define NID_setct_AuthTokenTBE 573 +#define OBJ_setct_AuthTokenTBE OBJ_set_ctype,55L + +#define SN_setct_CapTokenTBE "setct-CapTokenTBE" +#define NID_setct_CapTokenTBE 574 +#define OBJ_setct_CapTokenTBE OBJ_set_ctype,56L + +#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX" +#define NID_setct_CapTokenTBEX 575 +#define OBJ_setct_CapTokenTBEX OBJ_set_ctype,57L + +#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE" +#define NID_setct_AcqCardCodeMsgTBE 576 +#define OBJ_setct_AcqCardCodeMsgTBE OBJ_set_ctype,58L + +#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE" +#define NID_setct_AuthRevReqTBE 577 +#define OBJ_setct_AuthRevReqTBE OBJ_set_ctype,59L + +#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE" +#define NID_setct_AuthRevResTBE 578 +#define OBJ_setct_AuthRevResTBE OBJ_set_ctype,60L + +#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB" +#define NID_setct_AuthRevResTBEB 579 +#define OBJ_setct_AuthRevResTBEB OBJ_set_ctype,61L + +#define SN_setct_CapReqTBE "setct-CapReqTBE" +#define NID_setct_CapReqTBE 580 +#define OBJ_setct_CapReqTBE OBJ_set_ctype,62L + +#define SN_setct_CapReqTBEX "setct-CapReqTBEX" +#define NID_setct_CapReqTBEX 581 +#define OBJ_setct_CapReqTBEX OBJ_set_ctype,63L + +#define SN_setct_CapResTBE "setct-CapResTBE" +#define NID_setct_CapResTBE 582 +#define OBJ_setct_CapResTBE OBJ_set_ctype,64L + +#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE" +#define NID_setct_CapRevReqTBE 583 +#define OBJ_setct_CapRevReqTBE OBJ_set_ctype,65L + +#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX" +#define NID_setct_CapRevReqTBEX 584 +#define OBJ_setct_CapRevReqTBEX OBJ_set_ctype,66L + +#define SN_setct_CapRevResTBE "setct-CapRevResTBE" +#define NID_setct_CapRevResTBE 585 +#define OBJ_setct_CapRevResTBE OBJ_set_ctype,67L + +#define SN_setct_CredReqTBE "setct-CredReqTBE" +#define NID_setct_CredReqTBE 586 +#define OBJ_setct_CredReqTBE OBJ_set_ctype,68L + +#define SN_setct_CredReqTBEX "setct-CredReqTBEX" +#define NID_setct_CredReqTBEX 587 +#define OBJ_setct_CredReqTBEX OBJ_set_ctype,69L + +#define SN_setct_CredResTBE "setct-CredResTBE" +#define NID_setct_CredResTBE 588 +#define OBJ_setct_CredResTBE OBJ_set_ctype,70L + +#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE" +#define NID_setct_CredRevReqTBE 589 +#define OBJ_setct_CredRevReqTBE OBJ_set_ctype,71L + +#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX" +#define NID_setct_CredRevReqTBEX 590 +#define OBJ_setct_CredRevReqTBEX OBJ_set_ctype,72L + +#define SN_setct_CredRevResTBE "setct-CredRevResTBE" +#define NID_setct_CredRevResTBE 591 +#define OBJ_setct_CredRevResTBE OBJ_set_ctype,73L + +#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE" +#define NID_setct_BatchAdminReqTBE 592 +#define OBJ_setct_BatchAdminReqTBE OBJ_set_ctype,74L + +#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE" +#define NID_setct_BatchAdminResTBE 593 +#define OBJ_setct_BatchAdminResTBE OBJ_set_ctype,75L + +#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE" +#define NID_setct_RegFormReqTBE 594 +#define OBJ_setct_RegFormReqTBE OBJ_set_ctype,76L + +#define SN_setct_CertReqTBE "setct-CertReqTBE" +#define NID_setct_CertReqTBE 595 +#define OBJ_setct_CertReqTBE OBJ_set_ctype,77L + +#define SN_setct_CertReqTBEX "setct-CertReqTBEX" +#define NID_setct_CertReqTBEX 596 +#define OBJ_setct_CertReqTBEX OBJ_set_ctype,78L + +#define SN_setct_CertResTBE "setct-CertResTBE" +#define NID_setct_CertResTBE 597 +#define OBJ_setct_CertResTBE OBJ_set_ctype,79L + +#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS" +#define NID_setct_CRLNotificationTBS 598 +#define OBJ_setct_CRLNotificationTBS OBJ_set_ctype,80L + +#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS" +#define NID_setct_CRLNotificationResTBS 599 +#define OBJ_setct_CRLNotificationResTBS OBJ_set_ctype,81L + +#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS" +#define NID_setct_BCIDistributionTBS 600 +#define OBJ_setct_BCIDistributionTBS OBJ_set_ctype,82L + +#define SN_setext_genCrypt "setext-genCrypt" +#define LN_setext_genCrypt "generic cryptogram" +#define NID_setext_genCrypt 601 +#define OBJ_setext_genCrypt OBJ_set_msgExt,1L + +#define SN_setext_miAuth "setext-miAuth" +#define LN_setext_miAuth "merchant initiated auth" +#define NID_setext_miAuth 602 +#define OBJ_setext_miAuth OBJ_set_msgExt,3L + +#define SN_setext_pinSecure "setext-pinSecure" +#define NID_setext_pinSecure 603 +#define OBJ_setext_pinSecure OBJ_set_msgExt,4L + +#define SN_setext_pinAny "setext-pinAny" +#define NID_setext_pinAny 604 +#define OBJ_setext_pinAny OBJ_set_msgExt,5L + +#define SN_setext_track2 "setext-track2" +#define NID_setext_track2 605 +#define OBJ_setext_track2 OBJ_set_msgExt,7L + +#define SN_setext_cv "setext-cv" +#define LN_setext_cv "additional verification" +#define NID_setext_cv 606 +#define OBJ_setext_cv OBJ_set_msgExt,8L + +#define SN_set_policy_root "set-policy-root" +#define NID_set_policy_root 607 +#define OBJ_set_policy_root OBJ_set_policy,0L + +#define SN_setCext_hashedRoot "setCext-hashedRoot" +#define NID_setCext_hashedRoot 608 +#define OBJ_setCext_hashedRoot OBJ_set_certExt,0L + +#define SN_setCext_certType "setCext-certType" +#define NID_setCext_certType 609 +#define OBJ_setCext_certType OBJ_set_certExt,1L + +#define SN_setCext_merchData "setCext-merchData" +#define NID_setCext_merchData 610 +#define OBJ_setCext_merchData OBJ_set_certExt,2L + +#define SN_setCext_cCertRequired "setCext-cCertRequired" +#define NID_setCext_cCertRequired 611 +#define OBJ_setCext_cCertRequired OBJ_set_certExt,3L + +#define SN_setCext_tunneling "setCext-tunneling" +#define NID_setCext_tunneling 612 +#define OBJ_setCext_tunneling OBJ_set_certExt,4L + +#define SN_setCext_setExt "setCext-setExt" +#define NID_setCext_setExt 613 +#define OBJ_setCext_setExt OBJ_set_certExt,5L + +#define SN_setCext_setQualf "setCext-setQualf" +#define NID_setCext_setQualf 614 +#define OBJ_setCext_setQualf OBJ_set_certExt,6L + +#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities" +#define NID_setCext_PGWYcapabilities 615 +#define OBJ_setCext_PGWYcapabilities OBJ_set_certExt,7L + +#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier" +#define NID_setCext_TokenIdentifier 616 +#define OBJ_setCext_TokenIdentifier OBJ_set_certExt,8L + +#define SN_setCext_Track2Data "setCext-Track2Data" +#define NID_setCext_Track2Data 617 +#define OBJ_setCext_Track2Data OBJ_set_certExt,9L + +#define SN_setCext_TokenType "setCext-TokenType" +#define NID_setCext_TokenType 618 +#define OBJ_setCext_TokenType OBJ_set_certExt,10L + +#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities" +#define NID_setCext_IssuerCapabilities 619 +#define OBJ_setCext_IssuerCapabilities OBJ_set_certExt,11L + +#define SN_setAttr_Cert "setAttr-Cert" +#define NID_setAttr_Cert 620 +#define OBJ_setAttr_Cert OBJ_set_attr,0L + +#define SN_setAttr_PGWYcap "setAttr-PGWYcap" +#define LN_setAttr_PGWYcap "payment gateway capabilities" +#define NID_setAttr_PGWYcap 621 +#define OBJ_setAttr_PGWYcap OBJ_set_attr,1L + +#define SN_setAttr_TokenType "setAttr-TokenType" +#define NID_setAttr_TokenType 622 +#define OBJ_setAttr_TokenType OBJ_set_attr,2L + +#define SN_setAttr_IssCap "setAttr-IssCap" +#define LN_setAttr_IssCap "issuer capabilities" +#define NID_setAttr_IssCap 623 +#define OBJ_setAttr_IssCap OBJ_set_attr,3L + +#define SN_set_rootKeyThumb "set-rootKeyThumb" +#define NID_set_rootKeyThumb 624 +#define OBJ_set_rootKeyThumb OBJ_setAttr_Cert,0L + +#define SN_set_addPolicy "set-addPolicy" +#define NID_set_addPolicy 625 +#define OBJ_set_addPolicy OBJ_setAttr_Cert,1L + +#define SN_setAttr_Token_EMV "setAttr-Token-EMV" +#define NID_setAttr_Token_EMV 626 +#define OBJ_setAttr_Token_EMV OBJ_setAttr_TokenType,1L + +#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime" +#define NID_setAttr_Token_B0Prime 627 +#define OBJ_setAttr_Token_B0Prime OBJ_setAttr_TokenType,2L + +#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM" +#define NID_setAttr_IssCap_CVM 628 +#define OBJ_setAttr_IssCap_CVM OBJ_setAttr_IssCap,3L + +#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2" +#define NID_setAttr_IssCap_T2 629 +#define OBJ_setAttr_IssCap_T2 OBJ_setAttr_IssCap,4L + +#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig" +#define NID_setAttr_IssCap_Sig 630 +#define OBJ_setAttr_IssCap_Sig OBJ_setAttr_IssCap,5L + +#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm" +#define LN_setAttr_GenCryptgrm "generate cryptogram" +#define NID_setAttr_GenCryptgrm 631 +#define OBJ_setAttr_GenCryptgrm OBJ_setAttr_IssCap_CVM,1L + +#define SN_setAttr_T2Enc "setAttr-T2Enc" +#define LN_setAttr_T2Enc "encrypted track 2" +#define NID_setAttr_T2Enc 632 +#define OBJ_setAttr_T2Enc OBJ_setAttr_IssCap_T2,1L + +#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt" +#define LN_setAttr_T2cleartxt "cleartext track 2" +#define NID_setAttr_T2cleartxt 633 +#define OBJ_setAttr_T2cleartxt OBJ_setAttr_IssCap_T2,2L + +#define SN_setAttr_TokICCsig "setAttr-TokICCsig" +#define LN_setAttr_TokICCsig "ICC or token signature" +#define NID_setAttr_TokICCsig 634 +#define OBJ_setAttr_TokICCsig OBJ_setAttr_IssCap_Sig,1L + +#define SN_setAttr_SecDevSig "setAttr-SecDevSig" +#define LN_setAttr_SecDevSig "secure device signature" +#define NID_setAttr_SecDevSig 635 +#define OBJ_setAttr_SecDevSig OBJ_setAttr_IssCap_Sig,2L + +#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA" +#define NID_set_brand_IATA_ATA 636 +#define OBJ_set_brand_IATA_ATA OBJ_set_brand,1L + +#define SN_set_brand_Diners "set-brand-Diners" +#define NID_set_brand_Diners 637 +#define OBJ_set_brand_Diners OBJ_set_brand,30L + +#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress" +#define NID_set_brand_AmericanExpress 638 +#define OBJ_set_brand_AmericanExpress OBJ_set_brand,34L + +#define SN_set_brand_JCB "set-brand-JCB" +#define NID_set_brand_JCB 639 +#define OBJ_set_brand_JCB OBJ_set_brand,35L + +#define SN_set_brand_Visa "set-brand-Visa" +#define NID_set_brand_Visa 640 +#define OBJ_set_brand_Visa OBJ_set_brand,4L + +#define SN_set_brand_MasterCard "set-brand-MasterCard" +#define NID_set_brand_MasterCard 641 +#define OBJ_set_brand_MasterCard OBJ_set_brand,5L + +#define SN_set_brand_Novus "set-brand-Novus" +#define NID_set_brand_Novus 642 +#define OBJ_set_brand_Novus OBJ_set_brand,6011L + +#define SN_des_cdmf "DES-CDMF" +#define LN_des_cdmf "des-cdmf" +#define NID_des_cdmf 643 +#define OBJ_des_cdmf OBJ_rsadsi,3L,10L + +#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET" +#define NID_rsaOAEPEncryptionSET 644 +#define OBJ_rsaOAEPEncryptionSET OBJ_rsadsi,1L,1L,6L + +#define SN_ipsec3 "Oakley-EC2N-3" +#define LN_ipsec3 "ipsec3" +#define NID_ipsec3 749 + +#define SN_ipsec4 "Oakley-EC2N-4" +#define LN_ipsec4 "ipsec4" +#define NID_ipsec4 750 + +#define SN_whirlpool "whirlpool" +#define NID_whirlpool 804 +#define OBJ_whirlpool OBJ_iso,0L,10118L,3L,0L,55L + +#define SN_cryptopro "cryptopro" +#define NID_cryptopro 805 +#define OBJ_cryptopro OBJ_member_body,643L,2L,2L + +#define SN_cryptocom "cryptocom" +#define NID_cryptocom 806 +#define OBJ_cryptocom OBJ_member_body,643L,2L,9L + +#define SN_id_GostR3411_94_with_GostR3410_2001 "id-GostR3411-94-with-GostR3410-2001" +#define LN_id_GostR3411_94_with_GostR3410_2001 "GOST R 34.11-94 with GOST R 34.10-2001" +#define NID_id_GostR3411_94_with_GostR3410_2001 807 +#define OBJ_id_GostR3411_94_with_GostR3410_2001 OBJ_cryptopro,3L + +#define SN_id_GostR3411_94_with_GostR3410_94 "id-GostR3411-94-with-GostR3410-94" +#define LN_id_GostR3411_94_with_GostR3410_94 "GOST R 34.11-94 with GOST R 34.10-94" +#define NID_id_GostR3411_94_with_GostR3410_94 808 +#define OBJ_id_GostR3411_94_with_GostR3410_94 OBJ_cryptopro,4L + +#define SN_id_GostR3411_94 "md_gost94" +#define LN_id_GostR3411_94 "GOST R 34.11-94" +#define NID_id_GostR3411_94 809 +#define OBJ_id_GostR3411_94 OBJ_cryptopro,9L + +#define SN_id_HMACGostR3411_94 "id-HMACGostR3411-94" +#define LN_id_HMACGostR3411_94 "HMAC GOST 34.11-94" +#define NID_id_HMACGostR3411_94 810 +#define OBJ_id_HMACGostR3411_94 OBJ_cryptopro,10L + +#define SN_id_GostR3410_2001 "gost2001" +#define LN_id_GostR3410_2001 "GOST R 34.10-2001" +#define NID_id_GostR3410_2001 811 +#define OBJ_id_GostR3410_2001 OBJ_cryptopro,19L + +#define SN_id_GostR3410_94 "gost94" +#define LN_id_GostR3410_94 "GOST R 34.10-94" +#define NID_id_GostR3410_94 812 +#define OBJ_id_GostR3410_94 OBJ_cryptopro,20L + +#define SN_id_Gost28147_89 "gost89" +#define LN_id_Gost28147_89 "GOST 28147-89" +#define NID_id_Gost28147_89 813 +#define OBJ_id_Gost28147_89 OBJ_cryptopro,21L + +#define SN_gost89_cnt "gost89-cnt" +#define NID_gost89_cnt 814 + +#define SN_id_Gost28147_89_MAC "gost-mac" +#define LN_id_Gost28147_89_MAC "GOST 28147-89 MAC" +#define NID_id_Gost28147_89_MAC 815 +#define OBJ_id_Gost28147_89_MAC OBJ_cryptopro,22L + +#define SN_id_GostR3411_94_prf "prf-gostr3411-94" +#define LN_id_GostR3411_94_prf "GOST R 34.11-94 PRF" +#define NID_id_GostR3411_94_prf 816 +#define OBJ_id_GostR3411_94_prf OBJ_cryptopro,23L + +#define SN_id_GostR3410_2001DH "id-GostR3410-2001DH" +#define LN_id_GostR3410_2001DH "GOST R 34.10-2001 DH" +#define NID_id_GostR3410_2001DH 817 +#define OBJ_id_GostR3410_2001DH OBJ_cryptopro,98L + +#define SN_id_GostR3410_94DH "id-GostR3410-94DH" +#define LN_id_GostR3410_94DH "GOST R 34.10-94 DH" +#define NID_id_GostR3410_94DH 818 +#define OBJ_id_GostR3410_94DH OBJ_cryptopro,99L + +#define SN_id_Gost28147_89_CryptoPro_KeyMeshing "id-Gost28147-89-CryptoPro-KeyMeshing" +#define NID_id_Gost28147_89_CryptoPro_KeyMeshing 819 +#define OBJ_id_Gost28147_89_CryptoPro_KeyMeshing OBJ_cryptopro,14L,1L + +#define SN_id_Gost28147_89_None_KeyMeshing "id-Gost28147-89-None-KeyMeshing" +#define NID_id_Gost28147_89_None_KeyMeshing 820 +#define OBJ_id_Gost28147_89_None_KeyMeshing OBJ_cryptopro,14L,0L + +#define SN_id_GostR3411_94_TestParamSet "id-GostR3411-94-TestParamSet" +#define NID_id_GostR3411_94_TestParamSet 821 +#define OBJ_id_GostR3411_94_TestParamSet OBJ_cryptopro,30L,0L + +#define SN_id_GostR3411_94_CryptoProParamSet "id-GostR3411-94-CryptoProParamSet" +#define NID_id_GostR3411_94_CryptoProParamSet 822 +#define OBJ_id_GostR3411_94_CryptoProParamSet OBJ_cryptopro,30L,1L + +#define SN_id_Gost28147_89_TestParamSet "id-Gost28147-89-TestParamSet" +#define NID_id_Gost28147_89_TestParamSet 823 +#define OBJ_id_Gost28147_89_TestParamSet OBJ_cryptopro,31L,0L + +#define SN_id_Gost28147_89_CryptoPro_A_ParamSet "id-Gost28147-89-CryptoPro-A-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_A_ParamSet 824 +#define OBJ_id_Gost28147_89_CryptoPro_A_ParamSet OBJ_cryptopro,31L,1L + +#define SN_id_Gost28147_89_CryptoPro_B_ParamSet "id-Gost28147-89-CryptoPro-B-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_B_ParamSet 825 +#define OBJ_id_Gost28147_89_CryptoPro_B_ParamSet OBJ_cryptopro,31L,2L + +#define SN_id_Gost28147_89_CryptoPro_C_ParamSet "id-Gost28147-89-CryptoPro-C-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_C_ParamSet 826 +#define OBJ_id_Gost28147_89_CryptoPro_C_ParamSet OBJ_cryptopro,31L,3L + +#define SN_id_Gost28147_89_CryptoPro_D_ParamSet "id-Gost28147-89-CryptoPro-D-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_D_ParamSet 827 +#define OBJ_id_Gost28147_89_CryptoPro_D_ParamSet OBJ_cryptopro,31L,4L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet OBJ_cryptopro,31L,5L + +#define SN_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet "id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829 +#define OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet OBJ_cryptopro,31L,6L + +#define SN_id_Gost28147_89_CryptoPro_RIC_1_ParamSet "id-Gost28147-89-CryptoPro-RIC-1-ParamSet" +#define NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830 +#define OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet OBJ_cryptopro,31L,7L + +#define SN_id_GostR3410_94_TestParamSet "id-GostR3410-94-TestParamSet" +#define NID_id_GostR3410_94_TestParamSet 831 +#define OBJ_id_GostR3410_94_TestParamSet OBJ_cryptopro,32L,0L + +#define SN_id_GostR3410_94_CryptoPro_A_ParamSet "id-GostR3410-94-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_A_ParamSet 832 +#define OBJ_id_GostR3410_94_CryptoPro_A_ParamSet OBJ_cryptopro,32L,2L + +#define SN_id_GostR3410_94_CryptoPro_B_ParamSet "id-GostR3410-94-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_B_ParamSet 833 +#define OBJ_id_GostR3410_94_CryptoPro_B_ParamSet OBJ_cryptopro,32L,3L + +#define SN_id_GostR3410_94_CryptoPro_C_ParamSet "id-GostR3410-94-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_C_ParamSet 834 +#define OBJ_id_GostR3410_94_CryptoPro_C_ParamSet OBJ_cryptopro,32L,4L + +#define SN_id_GostR3410_94_CryptoPro_D_ParamSet "id-GostR3410-94-CryptoPro-D-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_D_ParamSet 835 +#define OBJ_id_GostR3410_94_CryptoPro_D_ParamSet OBJ_cryptopro,32L,5L + +#define SN_id_GostR3410_94_CryptoPro_XchA_ParamSet "id-GostR3410-94-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchA_ParamSet 836 +#define OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet OBJ_cryptopro,33L,1L + +#define SN_id_GostR3410_94_CryptoPro_XchB_ParamSet "id-GostR3410-94-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchB_ParamSet 837 +#define OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet OBJ_cryptopro,33L,2L + +#define SN_id_GostR3410_94_CryptoPro_XchC_ParamSet "id-GostR3410-94-CryptoPro-XchC-ParamSet" +#define NID_id_GostR3410_94_CryptoPro_XchC_ParamSet 838 +#define OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet OBJ_cryptopro,33L,3L + +#define SN_id_GostR3410_2001_TestParamSet "id-GostR3410-2001-TestParamSet" +#define NID_id_GostR3410_2001_TestParamSet 839 +#define OBJ_id_GostR3410_2001_TestParamSet OBJ_cryptopro,35L,0L + +#define SN_id_GostR3410_2001_CryptoPro_A_ParamSet "id-GostR3410-2001-CryptoPro-A-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_A_ParamSet 840 +#define OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet OBJ_cryptopro,35L,1L + +#define SN_id_GostR3410_2001_CryptoPro_B_ParamSet "id-GostR3410-2001-CryptoPro-B-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_B_ParamSet 841 +#define OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet OBJ_cryptopro,35L,2L + +#define SN_id_GostR3410_2001_CryptoPro_C_ParamSet "id-GostR3410-2001-CryptoPro-C-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_C_ParamSet 842 +#define OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet OBJ_cryptopro,35L,3L + +#define SN_id_GostR3410_2001_CryptoPro_XchA_ParamSet "id-GostR3410-2001-CryptoPro-XchA-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet 843 +#define OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet OBJ_cryptopro,36L,0L + +#define SN_id_GostR3410_2001_CryptoPro_XchB_ParamSet "id-GostR3410-2001-CryptoPro-XchB-ParamSet" +#define NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet 844 +#define OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet OBJ_cryptopro,36L,1L + +#define SN_id_GostR3410_94_a "id-GostR3410-94-a" +#define NID_id_GostR3410_94_a 845 +#define OBJ_id_GostR3410_94_a OBJ_id_GostR3410_94,1L + +#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis" +#define NID_id_GostR3410_94_aBis 846 +#define OBJ_id_GostR3410_94_aBis OBJ_id_GostR3410_94,2L + +#define SN_id_GostR3410_94_b "id-GostR3410-94-b" +#define NID_id_GostR3410_94_b 847 +#define OBJ_id_GostR3410_94_b OBJ_id_GostR3410_94,3L + +#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis" +#define NID_id_GostR3410_94_bBis 848 +#define OBJ_id_GostR3410_94_bBis OBJ_id_GostR3410_94,4L + +#define SN_id_Gost28147_89_cc "id-Gost28147-89-cc" +#define LN_id_Gost28147_89_cc "GOST 28147-89 Cryptocom ParamSet" +#define NID_id_Gost28147_89_cc 849 +#define OBJ_id_Gost28147_89_cc OBJ_cryptocom,1L,6L,1L + +#define SN_id_GostR3410_94_cc "gost94cc" +#define LN_id_GostR3410_94_cc "GOST 34.10-94 Cryptocom" +#define NID_id_GostR3410_94_cc 850 +#define OBJ_id_GostR3410_94_cc OBJ_cryptocom,1L,5L,3L + +#define SN_id_GostR3410_2001_cc "gost2001cc" +#define LN_id_GostR3410_2001_cc "GOST 34.10-2001 Cryptocom" +#define NID_id_GostR3410_2001_cc 851 +#define OBJ_id_GostR3410_2001_cc OBJ_cryptocom,1L,5L,4L + +#define SN_id_GostR3411_94_with_GostR3410_94_cc "id-GostR3411-94-with-GostR3410-94-cc" +#define LN_id_GostR3411_94_with_GostR3410_94_cc "GOST R 34.11-94 with GOST R 34.10-94 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_94_cc 852 +#define OBJ_id_GostR3411_94_with_GostR3410_94_cc OBJ_cryptocom,1L,3L,3L + +#define SN_id_GostR3411_94_with_GostR3410_2001_cc "id-GostR3411-94-with-GostR3410-2001-cc" +#define LN_id_GostR3411_94_with_GostR3410_2001_cc "GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom" +#define NID_id_GostR3411_94_with_GostR3410_2001_cc 853 +#define OBJ_id_GostR3411_94_with_GostR3410_2001_cc OBJ_cryptocom,1L,3L,4L + +#define SN_id_GostR3410_2001_ParamSet_cc "id-GostR3410-2001-ParamSet-cc" +#define LN_id_GostR3410_2001_ParamSet_cc "GOST R 3410-2001 Parameter Set Cryptocom" +#define NID_id_GostR3410_2001_ParamSet_cc 854 +#define OBJ_id_GostR3410_2001_ParamSet_cc OBJ_cryptocom,1L,8L,1L + +#define SN_camellia_128_cbc "CAMELLIA-128-CBC" +#define LN_camellia_128_cbc "camellia-128-cbc" +#define NID_camellia_128_cbc 751 +#define OBJ_camellia_128_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,2L + +#define SN_camellia_192_cbc "CAMELLIA-192-CBC" +#define LN_camellia_192_cbc "camellia-192-cbc" +#define NID_camellia_192_cbc 752 +#define OBJ_camellia_192_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,3L + +#define SN_camellia_256_cbc "CAMELLIA-256-CBC" +#define LN_camellia_256_cbc "camellia-256-cbc" +#define NID_camellia_256_cbc 753 +#define OBJ_camellia_256_cbc 1L,2L,392L,200011L,61L,1L,1L,1L,4L + +#define SN_id_camellia128_wrap "id-camellia128-wrap" +#define NID_id_camellia128_wrap 907 +#define OBJ_id_camellia128_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,2L + +#define SN_id_camellia192_wrap "id-camellia192-wrap" +#define NID_id_camellia192_wrap 908 +#define OBJ_id_camellia192_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,3L + +#define SN_id_camellia256_wrap "id-camellia256-wrap" +#define NID_id_camellia256_wrap 909 +#define OBJ_id_camellia256_wrap 1L,2L,392L,200011L,61L,1L,1L,3L,4L + +#define OBJ_ntt_ds 0L,3L,4401L,5L + +#define OBJ_camellia OBJ_ntt_ds,3L,1L,9L + +#define SN_camellia_128_ecb "CAMELLIA-128-ECB" +#define LN_camellia_128_ecb "camellia-128-ecb" +#define NID_camellia_128_ecb 754 +#define OBJ_camellia_128_ecb OBJ_camellia,1L + +#define SN_camellia_128_ofb128 "CAMELLIA-128-OFB" +#define LN_camellia_128_ofb128 "camellia-128-ofb" +#define NID_camellia_128_ofb128 766 +#define OBJ_camellia_128_ofb128 OBJ_camellia,3L + +#define SN_camellia_128_cfb128 "CAMELLIA-128-CFB" +#define LN_camellia_128_cfb128 "camellia-128-cfb" +#define NID_camellia_128_cfb128 757 +#define OBJ_camellia_128_cfb128 OBJ_camellia,4L + +#define SN_camellia_192_ecb "CAMELLIA-192-ECB" +#define LN_camellia_192_ecb "camellia-192-ecb" +#define NID_camellia_192_ecb 755 +#define OBJ_camellia_192_ecb OBJ_camellia,21L + +#define SN_camellia_192_ofb128 "CAMELLIA-192-OFB" +#define LN_camellia_192_ofb128 "camellia-192-ofb" +#define NID_camellia_192_ofb128 767 +#define OBJ_camellia_192_ofb128 OBJ_camellia,23L + +#define SN_camellia_192_cfb128 "CAMELLIA-192-CFB" +#define LN_camellia_192_cfb128 "camellia-192-cfb" +#define NID_camellia_192_cfb128 758 +#define OBJ_camellia_192_cfb128 OBJ_camellia,24L + +#define SN_camellia_256_ecb "CAMELLIA-256-ECB" +#define LN_camellia_256_ecb "camellia-256-ecb" +#define NID_camellia_256_ecb 756 +#define OBJ_camellia_256_ecb OBJ_camellia,41L + +#define SN_camellia_256_ofb128 "CAMELLIA-256-OFB" +#define LN_camellia_256_ofb128 "camellia-256-ofb" +#define NID_camellia_256_ofb128 768 +#define OBJ_camellia_256_ofb128 OBJ_camellia,43L + +#define SN_camellia_256_cfb128 "CAMELLIA-256-CFB" +#define LN_camellia_256_cfb128 "camellia-256-cfb" +#define NID_camellia_256_cfb128 759 +#define OBJ_camellia_256_cfb128 OBJ_camellia,44L + +#define SN_camellia_128_cfb1 "CAMELLIA-128-CFB1" +#define LN_camellia_128_cfb1 "camellia-128-cfb1" +#define NID_camellia_128_cfb1 760 + +#define SN_camellia_192_cfb1 "CAMELLIA-192-CFB1" +#define LN_camellia_192_cfb1 "camellia-192-cfb1" +#define NID_camellia_192_cfb1 761 + +#define SN_camellia_256_cfb1 "CAMELLIA-256-CFB1" +#define LN_camellia_256_cfb1 "camellia-256-cfb1" +#define NID_camellia_256_cfb1 762 + +#define SN_camellia_128_cfb8 "CAMELLIA-128-CFB8" +#define LN_camellia_128_cfb8 "camellia-128-cfb8" +#define NID_camellia_128_cfb8 763 + +#define SN_camellia_192_cfb8 "CAMELLIA-192-CFB8" +#define LN_camellia_192_cfb8 "camellia-192-cfb8" +#define NID_camellia_192_cfb8 764 + +#define SN_camellia_256_cfb8 "CAMELLIA-256-CFB8" +#define LN_camellia_256_cfb8 "camellia-256-cfb8" +#define NID_camellia_256_cfb8 765 + +#define SN_kisa "KISA" +#define LN_kisa "kisa" +#define NID_kisa 773 +#define OBJ_kisa OBJ_member_body,410L,200004L + +#define SN_seed_ecb "SEED-ECB" +#define LN_seed_ecb "seed-ecb" +#define NID_seed_ecb 776 +#define OBJ_seed_ecb OBJ_kisa,1L,3L + +#define SN_seed_cbc "SEED-CBC" +#define LN_seed_cbc "seed-cbc" +#define NID_seed_cbc 777 +#define OBJ_seed_cbc OBJ_kisa,1L,4L + +#define SN_seed_cfb128 "SEED-CFB" +#define LN_seed_cfb128 "seed-cfb" +#define NID_seed_cfb128 779 +#define OBJ_seed_cfb128 OBJ_kisa,1L,5L + +#define SN_seed_ofb128 "SEED-OFB" +#define LN_seed_ofb128 "seed-ofb" +#define NID_seed_ofb128 778 +#define OBJ_seed_ofb128 OBJ_kisa,1L,6L + +#define SN_hmac "HMAC" +#define LN_hmac "hmac" +#define NID_hmac 855 + +#define SN_cmac "CMAC" +#define LN_cmac "cmac" +#define NID_cmac 894 + +#define SN_rc4_hmac_md5 "RC4-HMAC-MD5" +#define LN_rc4_hmac_md5 "rc4-hmac-md5" +#define NID_rc4_hmac_md5 915 + +#define SN_aes_128_cbc_hmac_sha1 "AES-128-CBC-HMAC-SHA1" +#define LN_aes_128_cbc_hmac_sha1 "aes-128-cbc-hmac-sha1" +#define NID_aes_128_cbc_hmac_sha1 916 + +#define SN_aes_192_cbc_hmac_sha1 "AES-192-CBC-HMAC-SHA1" +#define LN_aes_192_cbc_hmac_sha1 "aes-192-cbc-hmac-sha1" +#define NID_aes_192_cbc_hmac_sha1 917 + +#define SN_aes_256_cbc_hmac_sha1 "AES-256-CBC-HMAC-SHA1" +#define LN_aes_256_cbc_hmac_sha1 "aes-256-cbc-hmac-sha1" +#define NID_aes_256_cbc_hmac_sha1 918 diff --git a/libs/openssl/crypto/objects/obj_mac.num b/libs/openssl/crypto/objects/obj_mac.num new file mode 100644 index 00000000..1d0a7c80 --- /dev/null +++ b/libs/openssl/crypto/objects/obj_mac.num @@ -0,0 +1,919 @@ +undef 0 +rsadsi 1 +pkcs 2 +md2 3 +md5 4 +rc4 5 +rsaEncryption 6 +md2WithRSAEncryption 7 +md5WithRSAEncryption 8 +pbeWithMD2AndDES_CBC 9 +pbeWithMD5AndDES_CBC 10 +X500 11 +X509 12 +commonName 13 +countryName 14 +localityName 15 +stateOrProvinceName 16 +organizationName 17 +organizationalUnitName 18 +rsa 19 +pkcs7 20 +pkcs7_data 21 +pkcs7_signed 22 +pkcs7_enveloped 23 +pkcs7_signedAndEnveloped 24 +pkcs7_digest 25 +pkcs7_encrypted 26 +pkcs3 27 +dhKeyAgreement 28 +des_ecb 29 +des_cfb64 30 +des_cbc 31 +des_ede_ecb 32 +des_ede3_ecb 33 +idea_cbc 34 +idea_cfb64 35 +idea_ecb 36 +rc2_cbc 37 +rc2_ecb 38 +rc2_cfb64 39 +rc2_ofb64 40 +sha 41 +shaWithRSAEncryption 42 +des_ede_cbc 43 +des_ede3_cbc 44 +des_ofb64 45 +idea_ofb64 46 +pkcs9 47 +pkcs9_emailAddress 48 +pkcs9_unstructuredName 49 +pkcs9_contentType 50 +pkcs9_messageDigest 51 +pkcs9_signingTime 52 +pkcs9_countersignature 53 +pkcs9_challengePassword 54 +pkcs9_unstructuredAddress 55 +pkcs9_extCertAttributes 56 +netscape 57 +netscape_cert_extension 58 +netscape_data_type 59 +des_ede_cfb64 60 +des_ede3_cfb64 61 +des_ede_ofb64 62 +des_ede3_ofb64 63 +sha1 64 +sha1WithRSAEncryption 65 +dsaWithSHA 66 +dsa_2 67 +pbeWithSHA1AndRC2_CBC 68 +id_pbkdf2 69 +dsaWithSHA1_2 70 +netscape_cert_type 71 +netscape_base_url 72 +netscape_revocation_url 73 +netscape_ca_revocation_url 74 +netscape_renewal_url 75 +netscape_ca_policy_url 76 +netscape_ssl_server_name 77 +netscape_comment 78 +netscape_cert_sequence 79 +desx_cbc 80 +id_ce 81 +subject_key_identifier 82 +key_usage 83 +private_key_usage_period 84 +subject_alt_name 85 +issuer_alt_name 86 +basic_constraints 87 +crl_number 88 +certificate_policies 89 +authority_key_identifier 90 +bf_cbc 91 +bf_ecb 92 +bf_cfb64 93 +bf_ofb64 94 +mdc2 95 +mdc2WithRSA 96 +rc4_40 97 +rc2_40_cbc 98 +givenName 99 +surname 100 +initials 101 +uniqueIdentifier 102 +crl_distribution_points 103 +md5WithRSA 104 +serialNumber 105 +title 106 +description 107 +cast5_cbc 108 +cast5_ecb 109 +cast5_cfb64 110 +cast5_ofb64 111 +pbeWithMD5AndCast5_CBC 112 +dsaWithSHA1 113 +md5_sha1 114 +sha1WithRSA 115 +dsa 116 +ripemd160 117 +ripemd160WithRSA 119 +rc5_cbc 120 +rc5_ecb 121 +rc5_cfb64 122 +rc5_ofb64 123 +rle_compression 124 +zlib_compression 125 +ext_key_usage 126 +id_pkix 127 +id_kp 128 +server_auth 129 +client_auth 130 +code_sign 131 +email_protect 132 +time_stamp 133 +ms_code_ind 134 +ms_code_com 135 +ms_ctl_sign 136 +ms_sgc 137 +ms_efs 138 +ns_sgc 139 +delta_crl 140 +crl_reason 141 +invalidity_date 142 +sxnet 143 +pbe_WithSHA1And128BitRC4 144 +pbe_WithSHA1And40BitRC4 145 +pbe_WithSHA1And3_Key_TripleDES_CBC 146 +pbe_WithSHA1And2_Key_TripleDES_CBC 147 +pbe_WithSHA1And128BitRC2_CBC 148 +pbe_WithSHA1And40BitRC2_CBC 149 +keyBag 150 +pkcs8ShroudedKeyBag 151 +certBag 152 +crlBag 153 +secretBag 154 +safeContentsBag 155 +friendlyName 156 +localKeyID 157 +x509Certificate 158 +sdsiCertificate 159 +x509Crl 160 +pbes2 161 +pbmac1 162 +hmacWithSHA1 163 +id_qt_cps 164 +id_qt_unotice 165 +rc2_64_cbc 166 +SMIMECapabilities 167 +pbeWithMD2AndRC2_CBC 168 +pbeWithMD5AndRC2_CBC 169 +pbeWithSHA1AndDES_CBC 170 +ms_ext_req 171 +ext_req 172 +name 173 +dnQualifier 174 +id_pe 175 +id_ad 176 +info_access 177 +ad_OCSP 178 +ad_ca_issuers 179 +OCSP_sign 180 +iso 181 +member_body 182 +ISO_US 183 +X9_57 184 +X9cm 185 +pkcs1 186 +pkcs5 187 +SMIME 188 +id_smime_mod 189 +id_smime_ct 190 +id_smime_aa 191 +id_smime_alg 192 +id_smime_cd 193 +id_smime_spq 194 +id_smime_cti 195 +id_smime_mod_cms 196 +id_smime_mod_ess 197 +id_smime_mod_oid 198 +id_smime_mod_msg_v3 199 +id_smime_mod_ets_eSignature_88 200 +id_smime_mod_ets_eSignature_97 201 +id_smime_mod_ets_eSigPolicy_88 202 +id_smime_mod_ets_eSigPolicy_97 203 +id_smime_ct_receipt 204 +id_smime_ct_authData 205 +id_smime_ct_publishCert 206 +id_smime_ct_TSTInfo 207 +id_smime_ct_TDTInfo 208 +id_smime_ct_contentInfo 209 +id_smime_ct_DVCSRequestData 210 +id_smime_ct_DVCSResponseData 211 +id_smime_aa_receiptRequest 212 +id_smime_aa_securityLabel 213 +id_smime_aa_mlExpandHistory 214 +id_smime_aa_contentHint 215 +id_smime_aa_msgSigDigest 216 +id_smime_aa_encapContentType 217 +id_smime_aa_contentIdentifier 218 +id_smime_aa_macValue 219 +id_smime_aa_equivalentLabels 220 +id_smime_aa_contentReference 221 +id_smime_aa_encrypKeyPref 222 +id_smime_aa_signingCertificate 223 +id_smime_aa_smimeEncryptCerts 224 +id_smime_aa_timeStampToken 225 +id_smime_aa_ets_sigPolicyId 226 +id_smime_aa_ets_commitmentType 227 +id_smime_aa_ets_signerLocation 228 +id_smime_aa_ets_signerAttr 229 +id_smime_aa_ets_otherSigCert 230 +id_smime_aa_ets_contentTimestamp 231 +id_smime_aa_ets_CertificateRefs 232 +id_smime_aa_ets_RevocationRefs 233 +id_smime_aa_ets_certValues 234 +id_smime_aa_ets_revocationValues 235 +id_smime_aa_ets_escTimeStamp 236 +id_smime_aa_ets_certCRLTimestamp 237 +id_smime_aa_ets_archiveTimeStamp 238 +id_smime_aa_signatureType 239 +id_smime_aa_dvcs_dvc 240 +id_smime_alg_ESDHwith3DES 241 +id_smime_alg_ESDHwithRC2 242 +id_smime_alg_3DESwrap 243 +id_smime_alg_RC2wrap 244 +id_smime_alg_ESDH 245 +id_smime_alg_CMS3DESwrap 246 +id_smime_alg_CMSRC2wrap 247 +id_smime_cd_ldap 248 +id_smime_spq_ets_sqt_uri 249 +id_smime_spq_ets_sqt_unotice 250 +id_smime_cti_ets_proofOfOrigin 251 +id_smime_cti_ets_proofOfReceipt 252 +id_smime_cti_ets_proofOfDelivery 253 +id_smime_cti_ets_proofOfSender 254 +id_smime_cti_ets_proofOfApproval 255 +id_smime_cti_ets_proofOfCreation 256 +md4 257 +id_pkix_mod 258 +id_qt 259 +id_it 260 +id_pkip 261 +id_alg 262 +id_cmc 263 +id_on 264 +id_pda 265 +id_aca 266 +id_qcs 267 +id_cct 268 +id_pkix1_explicit_88 269 +id_pkix1_implicit_88 270 +id_pkix1_explicit_93 271 +id_pkix1_implicit_93 272 +id_mod_crmf 273 +id_mod_cmc 274 +id_mod_kea_profile_88 275 +id_mod_kea_profile_93 276 +id_mod_cmp 277 +id_mod_qualified_cert_88 278 +id_mod_qualified_cert_93 279 +id_mod_attribute_cert 280 +id_mod_timestamp_protocol 281 +id_mod_ocsp 282 +id_mod_dvcs 283 +id_mod_cmp2000 284 +biometricInfo 285 +qcStatements 286 +ac_auditEntity 287 +ac_targeting 288 +aaControls 289 +sbgp_ipAddrBlock 290 +sbgp_autonomousSysNum 291 +sbgp_routerIdentifier 292 +textNotice 293 +ipsecEndSystem 294 +ipsecTunnel 295 +ipsecUser 296 +dvcs 297 +id_it_caProtEncCert 298 +id_it_signKeyPairTypes 299 +id_it_encKeyPairTypes 300 +id_it_preferredSymmAlg 301 +id_it_caKeyUpdateInfo 302 +id_it_currentCRL 303 +id_it_unsupportedOIDs 304 +id_it_subscriptionRequest 305 +id_it_subscriptionResponse 306 +id_it_keyPairParamReq 307 +id_it_keyPairParamRep 308 +id_it_revPassphrase 309 +id_it_implicitConfirm 310 +id_it_confirmWaitTime 311 +id_it_origPKIMessage 312 +id_regCtrl 313 +id_regInfo 314 +id_regCtrl_regToken 315 +id_regCtrl_authenticator 316 +id_regCtrl_pkiPublicationInfo 317 +id_regCtrl_pkiArchiveOptions 318 +id_regCtrl_oldCertID 319 +id_regCtrl_protocolEncrKey 320 +id_regInfo_utf8Pairs 321 +id_regInfo_certReq 322 +id_alg_des40 323 +id_alg_noSignature 324 +id_alg_dh_sig_hmac_sha1 325 +id_alg_dh_pop 326 +id_cmc_statusInfo 327 +id_cmc_identification 328 +id_cmc_identityProof 329 +id_cmc_dataReturn 330 +id_cmc_transactionId 331 +id_cmc_senderNonce 332 +id_cmc_recipientNonce 333 +id_cmc_addExtensions 334 +id_cmc_encryptedPOP 335 +id_cmc_decryptedPOP 336 +id_cmc_lraPOPWitness 337 +id_cmc_getCert 338 +id_cmc_getCRL 339 +id_cmc_revokeRequest 340 +id_cmc_regInfo 341 +id_cmc_responseInfo 342 +id_cmc_queryPending 343 +id_cmc_popLinkRandom 344 +id_cmc_popLinkWitness 345 +id_cmc_confirmCertAcceptance 346 +id_on_personalData 347 +id_pda_dateOfBirth 348 +id_pda_placeOfBirth 349 +id_pda_pseudonym 350 +id_pda_gender 351 +id_pda_countryOfCitizenship 352 +id_pda_countryOfResidence 353 +id_aca_authenticationInfo 354 +id_aca_accessIdentity 355 +id_aca_chargingIdentity 356 +id_aca_group 357 +id_aca_role 358 +id_qcs_pkixQCSyntax_v1 359 +id_cct_crs 360 +id_cct_PKIData 361 +id_cct_PKIResponse 362 +ad_timeStamping 363 +ad_dvcs 364 +id_pkix_OCSP_basic 365 +id_pkix_OCSP_Nonce 366 +id_pkix_OCSP_CrlID 367 +id_pkix_OCSP_acceptableResponses 368 +id_pkix_OCSP_noCheck 369 +id_pkix_OCSP_archiveCutoff 370 +id_pkix_OCSP_serviceLocator 371 +id_pkix_OCSP_extendedStatus 372 +id_pkix_OCSP_valid 373 +id_pkix_OCSP_path 374 +id_pkix_OCSP_trustRoot 375 +algorithm 376 +rsaSignature 377 +X500algorithms 378 +org 379 +dod 380 +iana 381 +Directory 382 +Management 383 +Experimental 384 +Private 385 +Security 386 +SNMPv2 387 +Mail 388 +Enterprises 389 +dcObject 390 +domainComponent 391 +Domain 392 +joint_iso_ccitt 393 +selected_attribute_types 394 +clearance 395 +md4WithRSAEncryption 396 +ac_proxying 397 +sinfo_access 398 +id_aca_encAttrs 399 +role 400 +policy_constraints 401 +target_information 402 +no_rev_avail 403 +ccitt 404 +ansi_X9_62 405 +X9_62_prime_field 406 +X9_62_characteristic_two_field 407 +X9_62_id_ecPublicKey 408 +X9_62_prime192v1 409 +X9_62_prime192v2 410 +X9_62_prime192v3 411 +X9_62_prime239v1 412 +X9_62_prime239v2 413 +X9_62_prime239v3 414 +X9_62_prime256v1 415 +ecdsa_with_SHA1 416 +ms_csp_name 417 +aes_128_ecb 418 +aes_128_cbc 419 +aes_128_ofb128 420 +aes_128_cfb128 421 +aes_192_ecb 422 +aes_192_cbc 423 +aes_192_ofb128 424 +aes_192_cfb128 425 +aes_256_ecb 426 +aes_256_cbc 427 +aes_256_ofb128 428 +aes_256_cfb128 429 +hold_instruction_code 430 +hold_instruction_none 431 +hold_instruction_call_issuer 432 +hold_instruction_reject 433 +data 434 +pss 435 +ucl 436 +pilot 437 +pilotAttributeType 438 +pilotAttributeSyntax 439 +pilotObjectClass 440 +pilotGroups 441 +iA5StringSyntax 442 +caseIgnoreIA5StringSyntax 443 +pilotObject 444 +pilotPerson 445 +account 446 +document 447 +room 448 +documentSeries 449 +rFC822localPart 450 +dNSDomain 451 +domainRelatedObject 452 +friendlyCountry 453 +simpleSecurityObject 454 +pilotOrganization 455 +pilotDSA 456 +qualityLabelledData 457 +userId 458 +textEncodedORAddress 459 +rfc822Mailbox 460 +info 461 +favouriteDrink 462 +roomNumber 463 +photo 464 +userClass 465 +host 466 +manager 467 +documentIdentifier 468 +documentTitle 469 +documentVersion 470 +documentAuthor 471 +documentLocation 472 +homeTelephoneNumber 473 +secretary 474 +otherMailbox 475 +lastModifiedTime 476 +lastModifiedBy 477 +aRecord 478 +pilotAttributeType27 479 +mXRecord 480 +nSRecord 481 +sOARecord 482 +cNAMERecord 483 +associatedDomain 484 +associatedName 485 +homePostalAddress 486 +personalTitle 487 +mobileTelephoneNumber 488 +pagerTelephoneNumber 489 +friendlyCountryName 490 +organizationalStatus 491 +janetMailbox 492 +mailPreferenceOption 493 +buildingName 494 +dSAQuality 495 +singleLevelQuality 496 +subtreeMinimumQuality 497 +subtreeMaximumQuality 498 +personalSignature 499 +dITRedirect 500 +audio 501 +documentPublisher 502 +x500UniqueIdentifier 503 +mime_mhs 504 +mime_mhs_headings 505 +mime_mhs_bodies 506 +id_hex_partial_message 507 +id_hex_multipart_message 508 +generationQualifier 509 +pseudonym 510 +InternationalRA 511 +id_set 512 +set_ctype 513 +set_msgExt 514 +set_attr 515 +set_policy 516 +set_certExt 517 +set_brand 518 +setct_PANData 519 +setct_PANToken 520 +setct_PANOnly 521 +setct_OIData 522 +setct_PI 523 +setct_PIData 524 +setct_PIDataUnsigned 525 +setct_HODInput 526 +setct_AuthResBaggage 527 +setct_AuthRevReqBaggage 528 +setct_AuthRevResBaggage 529 +setct_CapTokenSeq 530 +setct_PInitResData 531 +setct_PI_TBS 532 +setct_PResData 533 +setct_AuthReqTBS 534 +setct_AuthResTBS 535 +setct_AuthResTBSX 536 +setct_AuthTokenTBS 537 +setct_CapTokenData 538 +setct_CapTokenTBS 539 +setct_AcqCardCodeMsg 540 +setct_AuthRevReqTBS 541 +setct_AuthRevResData 542 +setct_AuthRevResTBS 543 +setct_CapReqTBS 544 +setct_CapReqTBSX 545 +setct_CapResData 546 +setct_CapRevReqTBS 547 +setct_CapRevReqTBSX 548 +setct_CapRevResData 549 +setct_CredReqTBS 550 +setct_CredReqTBSX 551 +setct_CredResData 552 +setct_CredRevReqTBS 553 +setct_CredRevReqTBSX 554 +setct_CredRevResData 555 +setct_PCertReqData 556 +setct_PCertResTBS 557 +setct_BatchAdminReqData 558 +setct_BatchAdminResData 559 +setct_CardCInitResTBS 560 +setct_MeAqCInitResTBS 561 +setct_RegFormResTBS 562 +setct_CertReqData 563 +setct_CertReqTBS 564 +setct_CertResData 565 +setct_CertInqReqTBS 566 +setct_ErrorTBS 567 +setct_PIDualSignedTBE 568 +setct_PIUnsignedTBE 569 +setct_AuthReqTBE 570 +setct_AuthResTBE 571 +setct_AuthResTBEX 572 +setct_AuthTokenTBE 573 +setct_CapTokenTBE 574 +setct_CapTokenTBEX 575 +setct_AcqCardCodeMsgTBE 576 +setct_AuthRevReqTBE 577 +setct_AuthRevResTBE 578 +setct_AuthRevResTBEB 579 +setct_CapReqTBE 580 +setct_CapReqTBEX 581 +setct_CapResTBE 582 +setct_CapRevReqTBE 583 +setct_CapRevReqTBEX 584 +setct_CapRevResTBE 585 +setct_CredReqTBE 586 +setct_CredReqTBEX 587 +setct_CredResTBE 588 +setct_CredRevReqTBE 589 +setct_CredRevReqTBEX 590 +setct_CredRevResTBE 591 +setct_BatchAdminReqTBE 592 +setct_BatchAdminResTBE 593 +setct_RegFormReqTBE 594 +setct_CertReqTBE 595 +setct_CertReqTBEX 596 +setct_CertResTBE 597 +setct_CRLNotificationTBS 598 +setct_CRLNotificationResTBS 599 +setct_BCIDistributionTBS 600 +setext_genCrypt 601 +setext_miAuth 602 +setext_pinSecure 603 +setext_pinAny 604 +setext_track2 605 +setext_cv 606 +set_policy_root 607 +setCext_hashedRoot 608 +setCext_certType 609 +setCext_merchData 610 +setCext_cCertRequired 611 +setCext_tunneling 612 +setCext_setExt 613 +setCext_setQualf 614 +setCext_PGWYcapabilities 615 +setCext_TokenIdentifier 616 +setCext_Track2Data 617 +setCext_TokenType 618 +setCext_IssuerCapabilities 619 +setAttr_Cert 620 +setAttr_PGWYcap 621 +setAttr_TokenType 622 +setAttr_IssCap 623 +set_rootKeyThumb 624 +set_addPolicy 625 +setAttr_Token_EMV 626 +setAttr_Token_B0Prime 627 +setAttr_IssCap_CVM 628 +setAttr_IssCap_T2 629 +setAttr_IssCap_Sig 630 +setAttr_GenCryptgrm 631 +setAttr_T2Enc 632 +setAttr_T2cleartxt 633 +setAttr_TokICCsig 634 +setAttr_SecDevSig 635 +set_brand_IATA_ATA 636 +set_brand_Diners 637 +set_brand_AmericanExpress 638 +set_brand_JCB 639 +set_brand_Visa 640 +set_brand_MasterCard 641 +set_brand_Novus 642 +des_cdmf 643 +rsaOAEPEncryptionSET 644 +itu_t 645 +joint_iso_itu_t 646 +international_organizations 647 +ms_smartcard_login 648 +ms_upn 649 +aes_128_cfb1 650 +aes_192_cfb1 651 +aes_256_cfb1 652 +aes_128_cfb8 653 +aes_192_cfb8 654 +aes_256_cfb8 655 +des_cfb1 656 +des_cfb8 657 +des_ede3_cfb1 658 +des_ede3_cfb8 659 +streetAddress 660 +postalCode 661 +id_ppl 662 +proxyCertInfo 663 +id_ppl_anyLanguage 664 +id_ppl_inheritAll 665 +name_constraints 666 +Independent 667 +sha256WithRSAEncryption 668 +sha384WithRSAEncryption 669 +sha512WithRSAEncryption 670 +sha224WithRSAEncryption 671 +sha256 672 +sha384 673 +sha512 674 +sha224 675 +identified_organization 676 +certicom_arc 677 +wap 678 +wap_wsg 679 +X9_62_id_characteristic_two_basis 680 +X9_62_onBasis 681 +X9_62_tpBasis 682 +X9_62_ppBasis 683 +X9_62_c2pnb163v1 684 +X9_62_c2pnb163v2 685 +X9_62_c2pnb163v3 686 +X9_62_c2pnb176v1 687 +X9_62_c2tnb191v1 688 +X9_62_c2tnb191v2 689 +X9_62_c2tnb191v3 690 +X9_62_c2onb191v4 691 +X9_62_c2onb191v5 692 +X9_62_c2pnb208w1 693 +X9_62_c2tnb239v1 694 +X9_62_c2tnb239v2 695 +X9_62_c2tnb239v3 696 +X9_62_c2onb239v4 697 +X9_62_c2onb239v5 698 +X9_62_c2pnb272w1 699 +X9_62_c2pnb304w1 700 +X9_62_c2tnb359v1 701 +X9_62_c2pnb368w1 702 +X9_62_c2tnb431r1 703 +secp112r1 704 +secp112r2 705 +secp128r1 706 +secp128r2 707 +secp160k1 708 +secp160r1 709 +secp160r2 710 +secp192k1 711 +secp224k1 712 +secp224r1 713 +secp256k1 714 +secp384r1 715 +secp521r1 716 +sect113r1 717 +sect113r2 718 +sect131r1 719 +sect131r2 720 +sect163k1 721 +sect163r1 722 +sect163r2 723 +sect193r1 724 +sect193r2 725 +sect233k1 726 +sect233r1 727 +sect239k1 728 +sect283k1 729 +sect283r1 730 +sect409k1 731 +sect409r1 732 +sect571k1 733 +sect571r1 734 +wap_wsg_idm_ecid_wtls1 735 +wap_wsg_idm_ecid_wtls3 736 +wap_wsg_idm_ecid_wtls4 737 +wap_wsg_idm_ecid_wtls5 738 +wap_wsg_idm_ecid_wtls6 739 +wap_wsg_idm_ecid_wtls7 740 +wap_wsg_idm_ecid_wtls8 741 +wap_wsg_idm_ecid_wtls9 742 +wap_wsg_idm_ecid_wtls10 743 +wap_wsg_idm_ecid_wtls11 744 +wap_wsg_idm_ecid_wtls12 745 +any_policy 746 +policy_mappings 747 +inhibit_any_policy 748 +ipsec3 749 +ipsec4 750 +camellia_128_cbc 751 +camellia_192_cbc 752 +camellia_256_cbc 753 +camellia_128_ecb 754 +camellia_192_ecb 755 +camellia_256_ecb 756 +camellia_128_cfb128 757 +camellia_192_cfb128 758 +camellia_256_cfb128 759 +camellia_128_cfb1 760 +camellia_192_cfb1 761 +camellia_256_cfb1 762 +camellia_128_cfb8 763 +camellia_192_cfb8 764 +camellia_256_cfb8 765 +camellia_128_ofb128 766 +camellia_192_ofb128 767 +camellia_256_ofb128 768 +subject_directory_attributes 769 +issuing_distribution_point 770 +certificate_issuer 771 +korea 772 +kisa 773 +kftc 774 +npki_alg 775 +seed_ecb 776 +seed_cbc 777 +seed_ofb128 778 +seed_cfb128 779 +hmac_md5 780 +hmac_sha1 781 +id_PasswordBasedMAC 782 +id_DHBasedMac 783 +id_it_suppLangTags 784 +caRepository 785 +id_smime_ct_compressedData 786 +id_ct_asciiTextWithCRLF 787 +id_aes128_wrap 788 +id_aes192_wrap 789 +id_aes256_wrap 790 +ecdsa_with_Recommended 791 +ecdsa_with_Specified 792 +ecdsa_with_SHA224 793 +ecdsa_with_SHA256 794 +ecdsa_with_SHA384 795 +ecdsa_with_SHA512 796 +hmacWithMD5 797 +hmacWithSHA224 798 +hmacWithSHA256 799 +hmacWithSHA384 800 +hmacWithSHA512 801 +dsa_with_SHA224 802 +dsa_with_SHA256 803 +whirlpool 804 +cryptopro 805 +cryptocom 806 +id_GostR3411_94_with_GostR3410_2001 807 +id_GostR3411_94_with_GostR3410_94 808 +id_GostR3411_94 809 +id_HMACGostR3411_94 810 +id_GostR3410_2001 811 +id_GostR3410_94 812 +id_Gost28147_89 813 +gost89_cnt 814 +id_Gost28147_89_MAC 815 +id_GostR3411_94_prf 816 +id_GostR3410_2001DH 817 +id_GostR3410_94DH 818 +id_Gost28147_89_CryptoPro_KeyMeshing 819 +id_Gost28147_89_None_KeyMeshing 820 +id_GostR3411_94_TestParamSet 821 +id_GostR3411_94_CryptoProParamSet 822 +id_Gost28147_89_TestParamSet 823 +id_Gost28147_89_CryptoPro_A_ParamSet 824 +id_Gost28147_89_CryptoPro_B_ParamSet 825 +id_Gost28147_89_CryptoPro_C_ParamSet 826 +id_Gost28147_89_CryptoPro_D_ParamSet 827 +id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet 828 +id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet 829 +id_Gost28147_89_CryptoPro_RIC_1_ParamSet 830 +id_GostR3410_94_TestParamSet 831 +id_GostR3410_94_CryptoPro_A_ParamSet 832 +id_GostR3410_94_CryptoPro_B_ParamSet 833 +id_GostR3410_94_CryptoPro_C_ParamSet 834 +id_GostR3410_94_CryptoPro_D_ParamSet 835 +id_GostR3410_94_CryptoPro_XchA_ParamSet 836 +id_GostR3410_94_CryptoPro_XchB_ParamSet 837 +id_GostR3410_94_CryptoPro_XchC_ParamSet 838 +id_GostR3410_2001_TestParamSet 839 +id_GostR3410_2001_CryptoPro_A_ParamSet 840 +id_GostR3410_2001_CryptoPro_B_ParamSet 841 +id_GostR3410_2001_CryptoPro_C_ParamSet 842 +id_GostR3410_2001_CryptoPro_XchA_ParamSet 843 +id_GostR3410_2001_CryptoPro_XchB_ParamSet 844 +id_GostR3410_94_a 845 +id_GostR3410_94_aBis 846 +id_GostR3410_94_b 847 +id_GostR3410_94_bBis 848 +id_Gost28147_89_cc 849 +id_GostR3410_94_cc 850 +id_GostR3410_2001_cc 851 +id_GostR3411_94_with_GostR3410_94_cc 852 +id_GostR3411_94_with_GostR3410_2001_cc 853 +id_GostR3410_2001_ParamSet_cc 854 +hmac 855 +LocalKeySet 856 +freshest_crl 857 +id_on_permanentIdentifier 858 +searchGuide 859 +businessCategory 860 +postalAddress 861 +postOfficeBox 862 +physicalDeliveryOfficeName 863 +telephoneNumber 864 +telexNumber 865 +teletexTerminalIdentifier 866 +facsimileTelephoneNumber 867 +x121Address 868 +internationaliSDNNumber 869 +registeredAddress 870 +destinationIndicator 871 +preferredDeliveryMethod 872 +presentationAddress 873 +supportedApplicationContext 874 +member 875 +owner 876 +roleOccupant 877 +seeAlso 878 +userPassword 879 +userCertificate 880 +cACertificate 881 +authorityRevocationList 882 +certificateRevocationList 883 +crossCertificatePair 884 +enhancedSearchGuide 885 +protocolInformation 886 +distinguishedName 887 +uniqueMember 888 +houseIdentifier 889 +supportedAlgorithms 890 +deltaRevocationList 891 +dmdName 892 +id_alg_PWRI_KEK 893 +cmac 894 +aes_128_gcm 895 +aes_128_ccm 896 +id_aes128_wrap_pad 897 +aes_192_gcm 898 +aes_192_ccm 899 +id_aes192_wrap_pad 900 +aes_256_gcm 901 +aes_256_ccm 902 +id_aes256_wrap_pad 903 +aes_128_ctr 904 +aes_192_ctr 905 +aes_256_ctr 906 +id_camellia128_wrap 907 +id_camellia192_wrap 908 +id_camellia256_wrap 909 +anyExtendedKeyUsage 910 +mgf1 911 +rsassaPss 912 +aes_128_xts 913 +aes_256_xts 914 +rc4_hmac_md5 915 +aes_128_cbc_hmac_sha1 916 +aes_192_cbc_hmac_sha1 917 +aes_256_cbc_hmac_sha1 918 +rsaesOaep 919 diff --git a/libs/openssl/crypto/objects/obj_xref.c b/libs/openssl/crypto/objects/obj_xref.c new file mode 100644 index 00000000..97b305d2 --- /dev/null +++ b/libs/openssl/crypto/objects/obj_xref.c @@ -0,0 +1,222 @@ +/* crypto/objects/obj_xref.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "obj_xref.h" + +DECLARE_STACK_OF(nid_triple) +STACK_OF(nid_triple) *sig_app, *sigx_app; + +static int sig_cmp(const nid_triple *a, const nid_triple *b) +{ + return a->sign_id - b->sign_id; +} + +DECLARE_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(nid_triple, nid_triple, sig); + +static int sig_sk_cmp(const nid_triple *const *a, const nid_triple *const *b) +{ + return (*a)->sign_id - (*b)->sign_id; +} + +DECLARE_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx); + +static int sigx_cmp(const nid_triple *const *a, const nid_triple *const *b) +{ + int ret; + ret = (*a)->hash_id - (*b)->hash_id; + if (ret) + return ret; + return (*a)->pkey_id - (*b)->pkey_id; +} + +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const nid_triple *, const nid_triple *, sigx); + +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid) +{ + nid_triple tmp; + const nid_triple *rv = NULL; + tmp.sign_id = signid; + + if (sig_app) { + int idx = sk_nid_triple_find(sig_app, &tmp); + if (idx >= 0) + rv = sk_nid_triple_value(sig_app, idx); + } +#ifndef OBJ_XREF_TEST2 + if (rv == NULL) { + rv = OBJ_bsearch_sig(&tmp, sigoid_srt, + sizeof(sigoid_srt) / sizeof(nid_triple)); + } +#endif + if (rv == NULL) + return 0; + if (pdig_nid) + *pdig_nid = rv->hash_id; + if (ppkey_nid) + *ppkey_nid = rv->pkey_id; + return 1; +} + +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid) +{ + nid_triple tmp; + const nid_triple *t = &tmp; + const nid_triple **rv = NULL; + + tmp.hash_id = dig_nid; + tmp.pkey_id = pkey_nid; + + if (sigx_app) { + int idx = sk_nid_triple_find(sigx_app, &tmp); + if (idx >= 0) { + t = sk_nid_triple_value(sigx_app, idx); + rv = &t; + } + } +#ifndef OBJ_XREF_TEST2 + if (rv == NULL) { + rv = OBJ_bsearch_sigx(&t, sigoid_srt_xref, + sizeof(sigoid_srt_xref) / sizeof(nid_triple *) + ); + } +#endif + if (rv == NULL) + return 0; + if (psignid) + *psignid = (*rv)->sign_id; + return 1; +} + +int OBJ_add_sigid(int signid, int dig_id, int pkey_id) +{ + nid_triple *ntr; + if (!sig_app) + sig_app = sk_nid_triple_new(sig_sk_cmp); + if (!sig_app) + return 0; + if (!sigx_app) + sigx_app = sk_nid_triple_new(sigx_cmp); + if (!sigx_app) + return 0; + ntr = OPENSSL_malloc(sizeof(int) * 3); + if (!ntr) + return 0; + ntr->sign_id = signid; + ntr->hash_id = dig_id; + ntr->pkey_id = pkey_id; + + if (!sk_nid_triple_push(sig_app, ntr)) { + OPENSSL_free(ntr); + return 0; + } + + if (!sk_nid_triple_push(sigx_app, ntr)) + return 0; + + sk_nid_triple_sort(sig_app); + sk_nid_triple_sort(sigx_app); + + return 1; +} + +static void sid_free(nid_triple *tt) +{ + OPENSSL_free(tt); +} + +void OBJ_sigid_free(void) +{ + if (sig_app) { + sk_nid_triple_pop_free(sig_app, sid_free); + sig_app = NULL; + } + if (sigx_app) { + sk_nid_triple_free(sigx_app); + sigx_app = NULL; + } +} + +#ifdef OBJ_XREF_TEST + +main() +{ + int n1, n2, n3; + + int i, rv; +# ifdef OBJ_XREF_TEST2 + for (i = 0; i < sizeof(sigoid_srt) / sizeof(nid_triple); i++) { + OBJ_add_sigid(sigoid_srt[i][0], sigoid_srt[i][1], sigoid_srt[i][2]); + } +# endif + + for (i = 0; i < sizeof(sigoid_srt) / sizeof(nid_triple); i++) { + n1 = sigoid_srt[i][0]; + rv = OBJ_find_sigid_algs(n1, &n2, &n3); + printf("Forward: %d, %s %s %s\n", rv, + OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3)); + n1 = 0; + rv = OBJ_find_sigid_by_algs(&n1, n2, n3); + printf("Reverse: %d, %s %s %s\n", rv, + OBJ_nid2ln(n1), OBJ_nid2ln(n2), OBJ_nid2ln(n3)); + } +} + +#endif diff --git a/libs/openssl/crypto/objects/obj_xref.h b/libs/openssl/crypto/objects/obj_xref.h new file mode 100644 index 00000000..b8f7d341 --- /dev/null +++ b/libs/openssl/crypto/objects/obj_xref.h @@ -0,0 +1,74 @@ +/* AUTOGENERATED BY objxref.pl, DO NOT EDIT */ + +typedef struct { + int sign_id; + int hash_id; + int pkey_id; +} nid_triple; + +static const nid_triple sigoid_srt[] = { + {NID_md2WithRSAEncryption, NID_md2, NID_rsaEncryption}, + {NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption}, + {NID_shaWithRSAEncryption, NID_sha, NID_rsaEncryption}, + {NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption}, + {NID_dsaWithSHA, NID_sha, NID_dsa}, + {NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2}, + {NID_mdc2WithRSA, NID_mdc2, NID_rsaEncryption}, + {NID_md5WithRSA, NID_md5, NID_rsa}, + {NID_dsaWithSHA1, NID_sha1, NID_dsa}, + {NID_sha1WithRSA, NID_sha1, NID_rsa}, + {NID_ripemd160WithRSA, NID_ripemd160, NID_rsaEncryption}, + {NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption}, + {NID_ecdsa_with_SHA1, NID_sha1, NID_X9_62_id_ecPublicKey}, + {NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption}, + {NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption}, + {NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption}, + {NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption}, + {NID_ecdsa_with_Recommended, NID_undef, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_Specified, NID_undef, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA224, NID_sha224, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA256, NID_sha256, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA384, NID_sha384, NID_X9_62_id_ecPublicKey}, + {NID_ecdsa_with_SHA512, NID_sha512, NID_X9_62_id_ecPublicKey}, + {NID_dsa_with_SHA224, NID_sha224, NID_dsa}, + {NID_dsa_with_SHA256, NID_sha256, NID_dsa}, + {NID_id_GostR3411_94_with_GostR3410_2001, NID_id_GostR3411_94, + NID_id_GostR3410_2001}, + {NID_id_GostR3411_94_with_GostR3410_94, NID_id_GostR3411_94, + NID_id_GostR3410_94}, + {NID_id_GostR3411_94_with_GostR3410_94_cc, NID_id_GostR3411_94, + NID_id_GostR3410_94_cc}, + {NID_id_GostR3411_94_with_GostR3410_2001_cc, NID_id_GostR3411_94, + NID_id_GostR3410_2001_cc}, + {NID_rsassaPss, NID_undef, NID_rsaEncryption}, +}; + +static const nid_triple *const sigoid_srt_xref[] = { + &sigoid_srt[0], + &sigoid_srt[1], + &sigoid_srt[7], + &sigoid_srt[2], + &sigoid_srt[4], + &sigoid_srt[3], + &sigoid_srt[9], + &sigoid_srt[5], + &sigoid_srt[8], + &sigoid_srt[12], + &sigoid_srt[6], + &sigoid_srt[10], + &sigoid_srt[11], + &sigoid_srt[13], + &sigoid_srt[24], + &sigoid_srt[20], + &sigoid_srt[14], + &sigoid_srt[21], + &sigoid_srt[15], + &sigoid_srt[22], + &sigoid_srt[16], + &sigoid_srt[23], + &sigoid_srt[19], + &sigoid_srt[25], + &sigoid_srt[26], + &sigoid_srt[27], + &sigoid_srt[28], +}; diff --git a/libs/openssl/crypto/objects/obj_xref.txt b/libs/openssl/crypto/objects/obj_xref.txt new file mode 100644 index 00000000..cb917182 --- /dev/null +++ b/libs/openssl/crypto/objects/obj_xref.txt @@ -0,0 +1,46 @@ +# OID cross reference table. +# Links signatures OIDs to their corresponding public key algorithms +# and digests. + +md2WithRSAEncryption md2 rsaEncryption +md5WithRSAEncryption md5 rsaEncryption +shaWithRSAEncryption sha rsaEncryption +sha1WithRSAEncryption sha1 rsaEncryption +md4WithRSAEncryption md4 rsaEncryption +sha256WithRSAEncryption sha256 rsaEncryption +sha384WithRSAEncryption sha384 rsaEncryption +sha512WithRSAEncryption sha512 rsaEncryption +sha224WithRSAEncryption sha224 rsaEncryption +mdc2WithRSA mdc2 rsaEncryption +ripemd160WithRSA ripemd160 rsaEncryption +# For PSS the digest algorithm can vary and depends on the included +# AlgorithmIdentifier. The digest "undef" indicates the public key +# method should handle this explicitly. +rsassaPss undef rsaEncryption + +# Alternative deprecated OIDs. By using the older "rsa" OID this +# type will be recognized by not normally used. + +md5WithRSA md5 rsa +sha1WithRSA sha1 rsa + +dsaWithSHA sha dsa +dsaWithSHA1 sha1 dsa + +dsaWithSHA1_2 sha1 dsa_2 + +ecdsa_with_SHA1 sha1 X9_62_id_ecPublicKey +ecdsa_with_SHA224 sha224 X9_62_id_ecPublicKey +ecdsa_with_SHA256 sha256 X9_62_id_ecPublicKey +ecdsa_with_SHA384 sha384 X9_62_id_ecPublicKey +ecdsa_with_SHA512 sha512 X9_62_id_ecPublicKey +ecdsa_with_Recommended undef X9_62_id_ecPublicKey +ecdsa_with_Specified undef X9_62_id_ecPublicKey + +dsa_with_SHA224 sha224 dsa +dsa_with_SHA256 sha256 dsa + +id_GostR3411_94_with_GostR3410_2001 id_GostR3411_94 id_GostR3410_2001 +id_GostR3411_94_with_GostR3410_94 id_GostR3411_94 id_GostR3410_94 +id_GostR3411_94_with_GostR3410_94_cc id_GostR3411_94 id_GostR3410_94_cc +id_GostR3411_94_with_GostR3410_2001_cc id_GostR3411_94 id_GostR3410_2001_cc diff --git a/libs/openssl/crypto/objects/objects.README b/libs/openssl/crypto/objects/objects.README new file mode 100644 index 00000000..cb1d216c --- /dev/null +++ b/libs/openssl/crypto/objects/objects.README @@ -0,0 +1,44 @@ +objects.txt syntax +------------------ + +To cover all the naming hacks that were previously in objects.h needed some +kind of hacks in objects.txt. + +The basic syntax for adding an object is as follows: + + 1 2 3 4 : shortName : Long Name + + If Long Name contains only word characters and hyphen-minus + (0x2D) or full stop (0x2E) then Long Name is used as basis + for the base name in C. Otherwise, the shortName is used. + + The base name (let's call it 'base') will then be used to + create the C macros SN_base, LN_base, NID_base and OBJ_base. + + Note that if the base name contains spaces, dashes or periods, + those will be converte to underscore. + +Then there are some extra commands: + + !Alias foo 1 2 3 4 + + This just makes a name foo for an OID. The C macro + OBJ_foo will be created as a result. + + !Cname foo + + This makes sure that the name foo will be used as base name + in C. + + !module foo + 1 2 3 4 : shortName : Long Name + !global + + The !module command was meant to define a kind of modularity. + What it does is to make sure the module name is prepended + to the base name. !global turns this off. This construction + is not recursive. + +Lines starting with # are treated as comments, as well as any line starting +with ! and not matching the commands above. + diff --git a/libs/openssl/crypto/objects/objects.h b/libs/openssl/crypto/objects/objects.h new file mode 100644 index 00000000..b8dafa89 --- /dev/null +++ b/libs/openssl/crypto/objects/objects.h @@ -0,0 +1,1143 @@ +/* crypto/objects/objects.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_OBJECTS_H +# define HEADER_OBJECTS_H + +# define USE_OBJ_MAC + +# ifdef USE_OBJ_MAC +# include +# else +# define SN_undef "UNDEF" +# define LN_undef "undefined" +# define NID_undef 0 +# define OBJ_undef 0L + +# define SN_Algorithm "Algorithm" +# define LN_algorithm "algorithm" +# define NID_algorithm 38 +# define OBJ_algorithm 1L,3L,14L,3L,2L + +# define LN_rsadsi "rsadsi" +# define NID_rsadsi 1 +# define OBJ_rsadsi 1L,2L,840L,113549L + +# define LN_pkcs "pkcs" +# define NID_pkcs 2 +# define OBJ_pkcs OBJ_rsadsi,1L + +# define SN_md2 "MD2" +# define LN_md2 "md2" +# define NID_md2 3 +# define OBJ_md2 OBJ_rsadsi,2L,2L + +# define SN_md5 "MD5" +# define LN_md5 "md5" +# define NID_md5 4 +# define OBJ_md5 OBJ_rsadsi,2L,5L + +# define SN_rc4 "RC4" +# define LN_rc4 "rc4" +# define NID_rc4 5 +# define OBJ_rc4 OBJ_rsadsi,3L,4L + +# define LN_rsaEncryption "rsaEncryption" +# define NID_rsaEncryption 6 +# define OBJ_rsaEncryption OBJ_pkcs,1L,1L + +# define SN_md2WithRSAEncryption "RSA-MD2" +# define LN_md2WithRSAEncryption "md2WithRSAEncryption" +# define NID_md2WithRSAEncryption 7 +# define OBJ_md2WithRSAEncryption OBJ_pkcs,1L,2L + +# define SN_md5WithRSAEncryption "RSA-MD5" +# define LN_md5WithRSAEncryption "md5WithRSAEncryption" +# define NID_md5WithRSAEncryption 8 +# define OBJ_md5WithRSAEncryption OBJ_pkcs,1L,4L + +# define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +# define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +# define NID_pbeWithMD2AndDES_CBC 9 +# define OBJ_pbeWithMD2AndDES_CBC OBJ_pkcs,5L,1L + +# define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +# define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +# define NID_pbeWithMD5AndDES_CBC 10 +# define OBJ_pbeWithMD5AndDES_CBC OBJ_pkcs,5L,3L + +# define LN_X500 "X500" +# define NID_X500 11 +# define OBJ_X500 2L,5L + +# define LN_X509 "X509" +# define NID_X509 12 +# define OBJ_X509 OBJ_X500,4L + +# define SN_commonName "CN" +# define LN_commonName "commonName" +# define NID_commonName 13 +# define OBJ_commonName OBJ_X509,3L + +# define SN_countryName "C" +# define LN_countryName "countryName" +# define NID_countryName 14 +# define OBJ_countryName OBJ_X509,6L + +# define SN_localityName "L" +# define LN_localityName "localityName" +# define NID_localityName 15 +# define OBJ_localityName OBJ_X509,7L + +/* Postal Address? PA */ + +/* should be "ST" (rfc1327) but MS uses 'S' */ +# define SN_stateOrProvinceName "ST" +# define LN_stateOrProvinceName "stateOrProvinceName" +# define NID_stateOrProvinceName 16 +# define OBJ_stateOrProvinceName OBJ_X509,8L + +# define SN_organizationName "O" +# define LN_organizationName "organizationName" +# define NID_organizationName 17 +# define OBJ_organizationName OBJ_X509,10L + +# define SN_organizationalUnitName "OU" +# define LN_organizationalUnitName "organizationalUnitName" +# define NID_organizationalUnitName 18 +# define OBJ_organizationalUnitName OBJ_X509,11L + +# define SN_rsa "RSA" +# define LN_rsa "rsa" +# define NID_rsa 19 +# define OBJ_rsa OBJ_X500,8L,1L,1L + +# define LN_pkcs7 "pkcs7" +# define NID_pkcs7 20 +# define OBJ_pkcs7 OBJ_pkcs,7L + +# define LN_pkcs7_data "pkcs7-data" +# define NID_pkcs7_data 21 +# define OBJ_pkcs7_data OBJ_pkcs7,1L + +# define LN_pkcs7_signed "pkcs7-signedData" +# define NID_pkcs7_signed 22 +# define OBJ_pkcs7_signed OBJ_pkcs7,2L + +# define LN_pkcs7_enveloped "pkcs7-envelopedData" +# define NID_pkcs7_enveloped 23 +# define OBJ_pkcs7_enveloped OBJ_pkcs7,3L + +# define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +# define NID_pkcs7_signedAndEnveloped 24 +# define OBJ_pkcs7_signedAndEnveloped OBJ_pkcs7,4L + +# define LN_pkcs7_digest "pkcs7-digestData" +# define NID_pkcs7_digest 25 +# define OBJ_pkcs7_digest OBJ_pkcs7,5L + +# define LN_pkcs7_encrypted "pkcs7-encryptedData" +# define NID_pkcs7_encrypted 26 +# define OBJ_pkcs7_encrypted OBJ_pkcs7,6L + +# define LN_pkcs3 "pkcs3" +# define NID_pkcs3 27 +# define OBJ_pkcs3 OBJ_pkcs,3L + +# define LN_dhKeyAgreement "dhKeyAgreement" +# define NID_dhKeyAgreement 28 +# define OBJ_dhKeyAgreement OBJ_pkcs3,1L + +# define SN_des_ecb "DES-ECB" +# define LN_des_ecb "des-ecb" +# define NID_des_ecb 29 +# define OBJ_des_ecb OBJ_algorithm,6L + +# define SN_des_cfb64 "DES-CFB" +# define LN_des_cfb64 "des-cfb" +# define NID_des_cfb64 30 +/* IV + num */ +# define OBJ_des_cfb64 OBJ_algorithm,9L + +# define SN_des_cbc "DES-CBC" +# define LN_des_cbc "des-cbc" +# define NID_des_cbc 31 +/* IV */ +# define OBJ_des_cbc OBJ_algorithm,7L + +# define SN_des_ede "DES-EDE" +# define LN_des_ede "des-ede" +# define NID_des_ede 32 +/* ?? */ +# define OBJ_des_ede OBJ_algorithm,17L + +# define SN_des_ede3 "DES-EDE3" +# define LN_des_ede3 "des-ede3" +# define NID_des_ede3 33 + +# define SN_idea_cbc "IDEA-CBC" +# define LN_idea_cbc "idea-cbc" +# define NID_idea_cbc 34 +# define OBJ_idea_cbc 1L,3L,6L,1L,4L,1L,188L,7L,1L,1L,2L + +# define SN_idea_cfb64 "IDEA-CFB" +# define LN_idea_cfb64 "idea-cfb" +# define NID_idea_cfb64 35 + +# define SN_idea_ecb "IDEA-ECB" +# define LN_idea_ecb "idea-ecb" +# define NID_idea_ecb 36 + +# define SN_rc2_cbc "RC2-CBC" +# define LN_rc2_cbc "rc2-cbc" +# define NID_rc2_cbc 37 +# define OBJ_rc2_cbc OBJ_rsadsi,3L,2L + +# define SN_rc2_ecb "RC2-ECB" +# define LN_rc2_ecb "rc2-ecb" +# define NID_rc2_ecb 38 + +# define SN_rc2_cfb64 "RC2-CFB" +# define LN_rc2_cfb64 "rc2-cfb" +# define NID_rc2_cfb64 39 + +# define SN_rc2_ofb64 "RC2-OFB" +# define LN_rc2_ofb64 "rc2-ofb" +# define NID_rc2_ofb64 40 + +# define SN_sha "SHA" +# define LN_sha "sha" +# define NID_sha 41 +# define OBJ_sha OBJ_algorithm,18L + +# define SN_shaWithRSAEncryption "RSA-SHA" +# define LN_shaWithRSAEncryption "shaWithRSAEncryption" +# define NID_shaWithRSAEncryption 42 +# define OBJ_shaWithRSAEncryption OBJ_algorithm,15L + +# define SN_des_ede_cbc "DES-EDE-CBC" +# define LN_des_ede_cbc "des-ede-cbc" +# define NID_des_ede_cbc 43 + +# define SN_des_ede3_cbc "DES-EDE3-CBC" +# define LN_des_ede3_cbc "des-ede3-cbc" +# define NID_des_ede3_cbc 44 +# define OBJ_des_ede3_cbc OBJ_rsadsi,3L,7L + +# define SN_des_ofb64 "DES-OFB" +# define LN_des_ofb64 "des-ofb" +# define NID_des_ofb64 45 +# define OBJ_des_ofb64 OBJ_algorithm,8L + +# define SN_idea_ofb64 "IDEA-OFB" +# define LN_idea_ofb64 "idea-ofb" +# define NID_idea_ofb64 46 + +# define LN_pkcs9 "pkcs9" +# define NID_pkcs9 47 +# define OBJ_pkcs9 OBJ_pkcs,9L + +# define SN_pkcs9_emailAddress "Email" +# define LN_pkcs9_emailAddress "emailAddress" +# define NID_pkcs9_emailAddress 48 +# define OBJ_pkcs9_emailAddress OBJ_pkcs9,1L + +# define LN_pkcs9_unstructuredName "unstructuredName" +# define NID_pkcs9_unstructuredName 49 +# define OBJ_pkcs9_unstructuredName OBJ_pkcs9,2L + +# define LN_pkcs9_contentType "contentType" +# define NID_pkcs9_contentType 50 +# define OBJ_pkcs9_contentType OBJ_pkcs9,3L + +# define LN_pkcs9_messageDigest "messageDigest" +# define NID_pkcs9_messageDigest 51 +# define OBJ_pkcs9_messageDigest OBJ_pkcs9,4L + +# define LN_pkcs9_signingTime "signingTime" +# define NID_pkcs9_signingTime 52 +# define OBJ_pkcs9_signingTime OBJ_pkcs9,5L + +# define LN_pkcs9_countersignature "countersignature" +# define NID_pkcs9_countersignature 53 +# define OBJ_pkcs9_countersignature OBJ_pkcs9,6L + +# define LN_pkcs9_challengePassword "challengePassword" +# define NID_pkcs9_challengePassword 54 +# define OBJ_pkcs9_challengePassword OBJ_pkcs9,7L + +# define LN_pkcs9_unstructuredAddress "unstructuredAddress" +# define NID_pkcs9_unstructuredAddress 55 +# define OBJ_pkcs9_unstructuredAddress OBJ_pkcs9,8L + +# define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +# define NID_pkcs9_extCertAttributes 56 +# define OBJ_pkcs9_extCertAttributes OBJ_pkcs9,9L + +# define SN_netscape "Netscape" +# define LN_netscape "Netscape Communications Corp." +# define NID_netscape 57 +# define OBJ_netscape 2L,16L,840L,1L,113730L + +# define SN_netscape_cert_extension "nsCertExt" +# define LN_netscape_cert_extension "Netscape Certificate Extension" +# define NID_netscape_cert_extension 58 +# define OBJ_netscape_cert_extension OBJ_netscape,1L + +# define SN_netscape_data_type "nsDataType" +# define LN_netscape_data_type "Netscape Data Type" +# define NID_netscape_data_type 59 +# define OBJ_netscape_data_type OBJ_netscape,2L + +# define SN_des_ede_cfb64 "DES-EDE-CFB" +# define LN_des_ede_cfb64 "des-ede-cfb" +# define NID_des_ede_cfb64 60 + +# define SN_des_ede3_cfb64 "DES-EDE3-CFB" +# define LN_des_ede3_cfb64 "des-ede3-cfb" +# define NID_des_ede3_cfb64 61 + +# define SN_des_ede_ofb64 "DES-EDE-OFB" +# define LN_des_ede_ofb64 "des-ede-ofb" +# define NID_des_ede_ofb64 62 + +# define SN_des_ede3_ofb64 "DES-EDE3-OFB" +# define LN_des_ede3_ofb64 "des-ede3-ofb" +# define NID_des_ede3_ofb64 63 + +/* I'm not sure about the object ID */ +# define SN_sha1 "SHA1" +# define LN_sha1 "sha1" +# define NID_sha1 64 +# define OBJ_sha1 OBJ_algorithm,26L +/* 28 Jun 1996 - eay */ +/* #define OBJ_sha1 1L,3L,14L,2L,26L,05L <- wrong */ + +# define SN_sha1WithRSAEncryption "RSA-SHA1" +# define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +# define NID_sha1WithRSAEncryption 65 +# define OBJ_sha1WithRSAEncryption OBJ_pkcs,1L,5L + +# define SN_dsaWithSHA "DSA-SHA" +# define LN_dsaWithSHA "dsaWithSHA" +# define NID_dsaWithSHA 66 +# define OBJ_dsaWithSHA OBJ_algorithm,13L + +# define SN_dsa_2 "DSA-old" +# define LN_dsa_2 "dsaEncryption-old" +# define NID_dsa_2 67 +# define OBJ_dsa_2 OBJ_algorithm,12L + +/* proposed by microsoft to RSA */ +# define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +# define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +# define NID_pbeWithSHA1AndRC2_CBC 68 +# define OBJ_pbeWithSHA1AndRC2_CBC OBJ_pkcs,5L,11L + +/* + * proposed by microsoft to RSA as pbeWithSHA1AndRC4: it is now defined + * explicitly in PKCS#5 v2.0 as id-PBKDF2 which is something completely + * different. + */ +# define LN_id_pbkdf2 "PBKDF2" +# define NID_id_pbkdf2 69 +# define OBJ_id_pbkdf2 OBJ_pkcs,5L,12L + +# define SN_dsaWithSHA1_2 "DSA-SHA1-old" +# define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +# define NID_dsaWithSHA1_2 70 +/* Got this one from 'sdn706r20.pdf' which is actually an NSA document :-) */ +# define OBJ_dsaWithSHA1_2 OBJ_algorithm,27L + +# define SN_netscape_cert_type "nsCertType" +# define LN_netscape_cert_type "Netscape Cert Type" +# define NID_netscape_cert_type 71 +# define OBJ_netscape_cert_type OBJ_netscape_cert_extension,1L + +# define SN_netscape_base_url "nsBaseUrl" +# define LN_netscape_base_url "Netscape Base Url" +# define NID_netscape_base_url 72 +# define OBJ_netscape_base_url OBJ_netscape_cert_extension,2L + +# define SN_netscape_revocation_url "nsRevocationUrl" +# define LN_netscape_revocation_url "Netscape Revocation Url" +# define NID_netscape_revocation_url 73 +# define OBJ_netscape_revocation_url OBJ_netscape_cert_extension,3L + +# define SN_netscape_ca_revocation_url "nsCaRevocationUrl" +# define LN_netscape_ca_revocation_url "Netscape CA Revocation Url" +# define NID_netscape_ca_revocation_url 74 +# define OBJ_netscape_ca_revocation_url OBJ_netscape_cert_extension,4L + +# define SN_netscape_renewal_url "nsRenewalUrl" +# define LN_netscape_renewal_url "Netscape Renewal Url" +# define NID_netscape_renewal_url 75 +# define OBJ_netscape_renewal_url OBJ_netscape_cert_extension,7L + +# define SN_netscape_ca_policy_url "nsCaPolicyUrl" +# define LN_netscape_ca_policy_url "Netscape CA Policy Url" +# define NID_netscape_ca_policy_url 76 +# define OBJ_netscape_ca_policy_url OBJ_netscape_cert_extension,8L + +# define SN_netscape_ssl_server_name "nsSslServerName" +# define LN_netscape_ssl_server_name "Netscape SSL Server Name" +# define NID_netscape_ssl_server_name 77 +# define OBJ_netscape_ssl_server_name OBJ_netscape_cert_extension,12L + +# define SN_netscape_comment "nsComment" +# define LN_netscape_comment "Netscape Comment" +# define NID_netscape_comment 78 +# define OBJ_netscape_comment OBJ_netscape_cert_extension,13L + +# define SN_netscape_cert_sequence "nsCertSequence" +# define LN_netscape_cert_sequence "Netscape Certificate Sequence" +# define NID_netscape_cert_sequence 79 +# define OBJ_netscape_cert_sequence OBJ_netscape_data_type,5L + +# define SN_desx_cbc "DESX-CBC" +# define LN_desx_cbc "desx-cbc" +# define NID_desx_cbc 80 + +# define SN_id_ce "id-ce" +# define NID_id_ce 81 +# define OBJ_id_ce 2L,5L,29L + +# define SN_subject_key_identifier "subjectKeyIdentifier" +# define LN_subject_key_identifier "X509v3 Subject Key Identifier" +# define NID_subject_key_identifier 82 +# define OBJ_subject_key_identifier OBJ_id_ce,14L + +# define SN_key_usage "keyUsage" +# define LN_key_usage "X509v3 Key Usage" +# define NID_key_usage 83 +# define OBJ_key_usage OBJ_id_ce,15L + +# define SN_private_key_usage_period "privateKeyUsagePeriod" +# define LN_private_key_usage_period "X509v3 Private Key Usage Period" +# define NID_private_key_usage_period 84 +# define OBJ_private_key_usage_period OBJ_id_ce,16L + +# define SN_subject_alt_name "subjectAltName" +# define LN_subject_alt_name "X509v3 Subject Alternative Name" +# define NID_subject_alt_name 85 +# define OBJ_subject_alt_name OBJ_id_ce,17L + +# define SN_issuer_alt_name "issuerAltName" +# define LN_issuer_alt_name "X509v3 Issuer Alternative Name" +# define NID_issuer_alt_name 86 +# define OBJ_issuer_alt_name OBJ_id_ce,18L + +# define SN_basic_constraints "basicConstraints" +# define LN_basic_constraints "X509v3 Basic Constraints" +# define NID_basic_constraints 87 +# define OBJ_basic_constraints OBJ_id_ce,19L + +# define SN_crl_number "crlNumber" +# define LN_crl_number "X509v3 CRL Number" +# define NID_crl_number 88 +# define OBJ_crl_number OBJ_id_ce,20L + +# define SN_certificate_policies "certificatePolicies" +# define LN_certificate_policies "X509v3 Certificate Policies" +# define NID_certificate_policies 89 +# define OBJ_certificate_policies OBJ_id_ce,32L + +# define SN_authority_key_identifier "authorityKeyIdentifier" +# define LN_authority_key_identifier "X509v3 Authority Key Identifier" +# define NID_authority_key_identifier 90 +# define OBJ_authority_key_identifier OBJ_id_ce,35L + +# define SN_bf_cbc "BF-CBC" +# define LN_bf_cbc "bf-cbc" +# define NID_bf_cbc 91 +# define OBJ_bf_cbc 1L,3L,6L,1L,4L,1L,3029L,1L,2L + +# define SN_bf_ecb "BF-ECB" +# define LN_bf_ecb "bf-ecb" +# define NID_bf_ecb 92 + +# define SN_bf_cfb64 "BF-CFB" +# define LN_bf_cfb64 "bf-cfb" +# define NID_bf_cfb64 93 + +# define SN_bf_ofb64 "BF-OFB" +# define LN_bf_ofb64 "bf-ofb" +# define NID_bf_ofb64 94 + +# define SN_mdc2 "MDC2" +# define LN_mdc2 "mdc2" +# define NID_mdc2 95 +# define OBJ_mdc2 2L,5L,8L,3L,101L +/* An alternative? 1L,3L,14L,3L,2L,19L */ + +# define SN_mdc2WithRSA "RSA-MDC2" +# define LN_mdc2WithRSA "mdc2withRSA" +# define NID_mdc2WithRSA 96 +# define OBJ_mdc2WithRSA 2L,5L,8L,3L,100L + +# define SN_rc4_40 "RC4-40" +# define LN_rc4_40 "rc4-40" +# define NID_rc4_40 97 + +# define SN_rc2_40_cbc "RC2-40-CBC" +# define LN_rc2_40_cbc "rc2-40-cbc" +# define NID_rc2_40_cbc 98 + +# define SN_givenName "G" +# define LN_givenName "givenName" +# define NID_givenName 99 +# define OBJ_givenName OBJ_X509,42L + +# define SN_surname "S" +# define LN_surname "surname" +# define NID_surname 100 +# define OBJ_surname OBJ_X509,4L + +# define SN_initials "I" +# define LN_initials "initials" +# define NID_initials 101 +# define OBJ_initials OBJ_X509,43L + +# define SN_uniqueIdentifier "UID" +# define LN_uniqueIdentifier "uniqueIdentifier" +# define NID_uniqueIdentifier 102 +# define OBJ_uniqueIdentifier OBJ_X509,45L + +# define SN_crl_distribution_points "crlDistributionPoints" +# define LN_crl_distribution_points "X509v3 CRL Distribution Points" +# define NID_crl_distribution_points 103 +# define OBJ_crl_distribution_points OBJ_id_ce,31L + +# define SN_md5WithRSA "RSA-NP-MD5" +# define LN_md5WithRSA "md5WithRSA" +# define NID_md5WithRSA 104 +# define OBJ_md5WithRSA OBJ_algorithm,3L + +# define SN_serialNumber "SN" +# define LN_serialNumber "serialNumber" +# define NID_serialNumber 105 +# define OBJ_serialNumber OBJ_X509,5L + +# define SN_title "T" +# define LN_title "title" +# define NID_title 106 +# define OBJ_title OBJ_X509,12L + +# define SN_description "D" +# define LN_description "description" +# define NID_description 107 +# define OBJ_description OBJ_X509,13L + +/* CAST5 is CAST-128, I'm just sticking with the documentation */ +# define SN_cast5_cbc "CAST5-CBC" +# define LN_cast5_cbc "cast5-cbc" +# define NID_cast5_cbc 108 +# define OBJ_cast5_cbc 1L,2L,840L,113533L,7L,66L,10L + +# define SN_cast5_ecb "CAST5-ECB" +# define LN_cast5_ecb "cast5-ecb" +# define NID_cast5_ecb 109 + +# define SN_cast5_cfb64 "CAST5-CFB" +# define LN_cast5_cfb64 "cast5-cfb" +# define NID_cast5_cfb64 110 + +# define SN_cast5_ofb64 "CAST5-OFB" +# define LN_cast5_ofb64 "cast5-ofb" +# define NID_cast5_ofb64 111 + +# define LN_pbeWithMD5AndCast5_CBC "pbeWithMD5AndCast5CBC" +# define NID_pbeWithMD5AndCast5_CBC 112 +# define OBJ_pbeWithMD5AndCast5_CBC 1L,2L,840L,113533L,7L,66L,12L + +/*- + * This is one sun will soon be using :-( + * id-dsa-with-sha1 ID ::= { + * iso(1) member-body(2) us(840) x9-57 (10040) x9cm(4) 3 } + */ +# define SN_dsaWithSHA1 "DSA-SHA1" +# define LN_dsaWithSHA1 "dsaWithSHA1" +# define NID_dsaWithSHA1 113 +# define OBJ_dsaWithSHA1 1L,2L,840L,10040L,4L,3L + +# define NID_md5_sha1 114 +# define SN_md5_sha1 "MD5-SHA1" +# define LN_md5_sha1 "md5-sha1" + +# define SN_sha1WithRSA "RSA-SHA1-2" +# define LN_sha1WithRSA "sha1WithRSA" +# define NID_sha1WithRSA 115 +# define OBJ_sha1WithRSA OBJ_algorithm,29L + +# define SN_dsa "DSA" +# define LN_dsa "dsaEncryption" +# define NID_dsa 116 +# define OBJ_dsa 1L,2L,840L,10040L,4L,1L + +# define SN_ripemd160 "RIPEMD160" +# define LN_ripemd160 "ripemd160" +# define NID_ripemd160 117 +# define OBJ_ripemd160 1L,3L,36L,3L,2L,1L + +/* + * The name should actually be rsaSignatureWithripemd160, but I'm going to + * continue using the convention I'm using with the other ciphers + */ +# define SN_ripemd160WithRSA "RSA-RIPEMD160" +# define LN_ripemd160WithRSA "ripemd160WithRSA" +# define NID_ripemd160WithRSA 119 +# define OBJ_ripemd160WithRSA 1L,3L,36L,3L,3L,1L,2L + +/*- + * Taken from rfc2040 + * RC5_CBC_Parameters ::= SEQUENCE { + * version INTEGER (v1_0(16)), + * rounds INTEGER (8..127), + * blockSizeInBits INTEGER (64, 128), + * iv OCTET STRING OPTIONAL + * } + */ +# define SN_rc5_cbc "RC5-CBC" +# define LN_rc5_cbc "rc5-cbc" +# define NID_rc5_cbc 120 +# define OBJ_rc5_cbc OBJ_rsadsi,3L,8L + +# define SN_rc5_ecb "RC5-ECB" +# define LN_rc5_ecb "rc5-ecb" +# define NID_rc5_ecb 121 + +# define SN_rc5_cfb64 "RC5-CFB" +# define LN_rc5_cfb64 "rc5-cfb" +# define NID_rc5_cfb64 122 + +# define SN_rc5_ofb64 "RC5-OFB" +# define LN_rc5_ofb64 "rc5-ofb" +# define NID_rc5_ofb64 123 + +# define SN_rle_compression "RLE" +# define LN_rle_compression "run length compression" +# define NID_rle_compression 124 +# define OBJ_rle_compression 1L,1L,1L,1L,666L,1L + +# define SN_zlib_compression "ZLIB" +# define LN_zlib_compression "zlib compression" +# define NID_zlib_compression 125 +# define OBJ_zlib_compression 1L,1L,1L,1L,666L,2L + +# define SN_ext_key_usage "extendedKeyUsage" +# define LN_ext_key_usage "X509v3 Extended Key Usage" +# define NID_ext_key_usage 126 +# define OBJ_ext_key_usage OBJ_id_ce,37 + +# define SN_id_pkix "PKIX" +# define NID_id_pkix 127 +# define OBJ_id_pkix 1L,3L,6L,1L,5L,5L,7L + +# define SN_id_kp "id-kp" +# define NID_id_kp 128 +# define OBJ_id_kp OBJ_id_pkix,3L + +/* PKIX extended key usage OIDs */ + +# define SN_server_auth "serverAuth" +# define LN_server_auth "TLS Web Server Authentication" +# define NID_server_auth 129 +# define OBJ_server_auth OBJ_id_kp,1L + +# define SN_client_auth "clientAuth" +# define LN_client_auth "TLS Web Client Authentication" +# define NID_client_auth 130 +# define OBJ_client_auth OBJ_id_kp,2L + +# define SN_code_sign "codeSigning" +# define LN_code_sign "Code Signing" +# define NID_code_sign 131 +# define OBJ_code_sign OBJ_id_kp,3L + +# define SN_email_protect "emailProtection" +# define LN_email_protect "E-mail Protection" +# define NID_email_protect 132 +# define OBJ_email_protect OBJ_id_kp,4L + +# define SN_time_stamp "timeStamping" +# define LN_time_stamp "Time Stamping" +# define NID_time_stamp 133 +# define OBJ_time_stamp OBJ_id_kp,8L + +/* Additional extended key usage OIDs: Microsoft */ + +# define SN_ms_code_ind "msCodeInd" +# define LN_ms_code_ind "Microsoft Individual Code Signing" +# define NID_ms_code_ind 134 +# define OBJ_ms_code_ind 1L,3L,6L,1L,4L,1L,311L,2L,1L,21L + +# define SN_ms_code_com "msCodeCom" +# define LN_ms_code_com "Microsoft Commercial Code Signing" +# define NID_ms_code_com 135 +# define OBJ_ms_code_com 1L,3L,6L,1L,4L,1L,311L,2L,1L,22L + +# define SN_ms_ctl_sign "msCTLSign" +# define LN_ms_ctl_sign "Microsoft Trust List Signing" +# define NID_ms_ctl_sign 136 +# define OBJ_ms_ctl_sign 1L,3L,6L,1L,4L,1L,311L,10L,3L,1L + +# define SN_ms_sgc "msSGC" +# define LN_ms_sgc "Microsoft Server Gated Crypto" +# define NID_ms_sgc 137 +# define OBJ_ms_sgc 1L,3L,6L,1L,4L,1L,311L,10L,3L,3L + +# define SN_ms_efs "msEFS" +# define LN_ms_efs "Microsoft Encrypted File System" +# define NID_ms_efs 138 +# define OBJ_ms_efs 1L,3L,6L,1L,4L,1L,311L,10L,3L,4L + +/* Additional usage: Netscape */ + +# define SN_ns_sgc "nsSGC" +# define LN_ns_sgc "Netscape Server Gated Crypto" +# define NID_ns_sgc 139 +# define OBJ_ns_sgc OBJ_netscape,4L,1L + +# define SN_delta_crl "deltaCRL" +# define LN_delta_crl "X509v3 Delta CRL Indicator" +# define NID_delta_crl 140 +# define OBJ_delta_crl OBJ_id_ce,27L + +# define SN_crl_reason "CRLReason" +# define LN_crl_reason "CRL Reason Code" +# define NID_crl_reason 141 +# define OBJ_crl_reason OBJ_id_ce,21L + +# define SN_invalidity_date "invalidityDate" +# define LN_invalidity_date "Invalidity Date" +# define NID_invalidity_date 142 +# define OBJ_invalidity_date OBJ_id_ce,24L + +# define SN_sxnet "SXNetID" +# define LN_sxnet "Strong Extranet ID" +# define NID_sxnet 143 +# define OBJ_sxnet 1L,3L,101L,1L,4L,1L + +/* PKCS12 and related OBJECT IDENTIFIERS */ + +# define OBJ_pkcs12 OBJ_pkcs,12L +# define OBJ_pkcs12_pbeids OBJ_pkcs12, 1 + +# define SN_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +# define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +# define NID_pbe_WithSHA1And128BitRC4 144 +# define OBJ_pbe_WithSHA1And128BitRC4 OBJ_pkcs12_pbeids, 1L + +# define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +# define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +# define NID_pbe_WithSHA1And40BitRC4 145 +# define OBJ_pbe_WithSHA1And40BitRC4 OBJ_pkcs12_pbeids, 2L + +# define SN_pbe_WithSHA1And3_Key_TripleDES_CBC "PBE-SHA1-3DES" +# define LN_pbe_WithSHA1And3_Key_TripleDES_CBC "pbeWithSHA1And3-KeyTripleDES-CBC" +# define NID_pbe_WithSHA1And3_Key_TripleDES_CBC 146 +# define OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 3L + +# define SN_pbe_WithSHA1And2_Key_TripleDES_CBC "PBE-SHA1-2DES" +# define LN_pbe_WithSHA1And2_Key_TripleDES_CBC "pbeWithSHA1And2-KeyTripleDES-CBC" +# define NID_pbe_WithSHA1And2_Key_TripleDES_CBC 147 +# define OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC OBJ_pkcs12_pbeids, 4L + +# define SN_pbe_WithSHA1And128BitRC2_CBC "PBE-SHA1-RC2-128" +# define LN_pbe_WithSHA1And128BitRC2_CBC "pbeWithSHA1And128BitRC2-CBC" +# define NID_pbe_WithSHA1And128BitRC2_CBC 148 +# define OBJ_pbe_WithSHA1And128BitRC2_CBC OBJ_pkcs12_pbeids, 5L + +# define SN_pbe_WithSHA1And40BitRC2_CBC "PBE-SHA1-RC2-40" +# define LN_pbe_WithSHA1And40BitRC2_CBC "pbeWithSHA1And40BitRC2-CBC" +# define NID_pbe_WithSHA1And40BitRC2_CBC 149 +# define OBJ_pbe_WithSHA1And40BitRC2_CBC OBJ_pkcs12_pbeids, 6L + +# define OBJ_pkcs12_Version1 OBJ_pkcs12, 10L + +# define OBJ_pkcs12_BagIds OBJ_pkcs12_Version1, 1L + +# define LN_keyBag "keyBag" +# define NID_keyBag 150 +# define OBJ_keyBag OBJ_pkcs12_BagIds, 1L + +# define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +# define NID_pkcs8ShroudedKeyBag 151 +# define OBJ_pkcs8ShroudedKeyBag OBJ_pkcs12_BagIds, 2L + +# define LN_certBag "certBag" +# define NID_certBag 152 +# define OBJ_certBag OBJ_pkcs12_BagIds, 3L + +# define LN_crlBag "crlBag" +# define NID_crlBag 153 +# define OBJ_crlBag OBJ_pkcs12_BagIds, 4L + +# define LN_secretBag "secretBag" +# define NID_secretBag 154 +# define OBJ_secretBag OBJ_pkcs12_BagIds, 5L + +# define LN_safeContentsBag "safeContentsBag" +# define NID_safeContentsBag 155 +# define OBJ_safeContentsBag OBJ_pkcs12_BagIds, 6L + +# define LN_friendlyName "friendlyName" +# define NID_friendlyName 156 +# define OBJ_friendlyName OBJ_pkcs9, 20L + +# define LN_localKeyID "localKeyID" +# define NID_localKeyID 157 +# define OBJ_localKeyID OBJ_pkcs9, 21L + +# define OBJ_certTypes OBJ_pkcs9, 22L + +# define LN_x509Certificate "x509Certificate" +# define NID_x509Certificate 158 +# define OBJ_x509Certificate OBJ_certTypes, 1L + +# define LN_sdsiCertificate "sdsiCertificate" +# define NID_sdsiCertificate 159 +# define OBJ_sdsiCertificate OBJ_certTypes, 2L + +# define OBJ_crlTypes OBJ_pkcs9, 23L + +# define LN_x509Crl "x509Crl" +# define NID_x509Crl 160 +# define OBJ_x509Crl OBJ_crlTypes, 1L + +/* PKCS#5 v2 OIDs */ + +# define LN_pbes2 "PBES2" +# define NID_pbes2 161 +# define OBJ_pbes2 OBJ_pkcs,5L,13L + +# define LN_pbmac1 "PBMAC1" +# define NID_pbmac1 162 +# define OBJ_pbmac1 OBJ_pkcs,5L,14L + +# define LN_hmacWithSHA1 "hmacWithSHA1" +# define NID_hmacWithSHA1 163 +# define OBJ_hmacWithSHA1 OBJ_rsadsi,2L,7L + +/* Policy Qualifier Ids */ + +# define LN_id_qt_cps "Policy Qualifier CPS" +# define SN_id_qt_cps "id-qt-cps" +# define NID_id_qt_cps 164 +# define OBJ_id_qt_cps OBJ_id_pkix,2L,1L + +# define LN_id_qt_unotice "Policy Qualifier User Notice" +# define SN_id_qt_unotice "id-qt-unotice" +# define NID_id_qt_unotice 165 +# define OBJ_id_qt_unotice OBJ_id_pkix,2L,2L + +# define SN_rc2_64_cbc "RC2-64-CBC" +# define LN_rc2_64_cbc "rc2-64-cbc" +# define NID_rc2_64_cbc 166 + +# define SN_SMIMECapabilities "SMIME-CAPS" +# define LN_SMIMECapabilities "S/MIME Capabilities" +# define NID_SMIMECapabilities 167 +# define OBJ_SMIMECapabilities OBJ_pkcs9,15L + +# define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +# define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +# define NID_pbeWithMD2AndRC2_CBC 168 +# define OBJ_pbeWithMD2AndRC2_CBC OBJ_pkcs,5L,4L + +# define SN_pbeWithMD5AndRC2_CBC "PBE-MD5-RC2-64" +# define LN_pbeWithMD5AndRC2_CBC "pbeWithMD5AndRC2-CBC" +# define NID_pbeWithMD5AndRC2_CBC 169 +# define OBJ_pbeWithMD5AndRC2_CBC OBJ_pkcs,5L,6L + +# define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +# define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +# define NID_pbeWithSHA1AndDES_CBC 170 +# define OBJ_pbeWithSHA1AndDES_CBC OBJ_pkcs,5L,10L + +/* Extension request OIDs */ + +# define LN_ms_ext_req "Microsoft Extension Request" +# define SN_ms_ext_req "msExtReq" +# define NID_ms_ext_req 171 +# define OBJ_ms_ext_req 1L,3L,6L,1L,4L,1L,311L,2L,1L,14L + +# define LN_ext_req "Extension Request" +# define SN_ext_req "extReq" +# define NID_ext_req 172 +# define OBJ_ext_req OBJ_pkcs9,14L + +# define SN_name "name" +# define LN_name "name" +# define NID_name 173 +# define OBJ_name OBJ_X509,41L + +# define SN_dnQualifier "dnQualifier" +# define LN_dnQualifier "dnQualifier" +# define NID_dnQualifier 174 +# define OBJ_dnQualifier OBJ_X509,46L + +# define SN_id_pe "id-pe" +# define NID_id_pe 175 +# define OBJ_id_pe OBJ_id_pkix,1L + +# define SN_id_ad "id-ad" +# define NID_id_ad 176 +# define OBJ_id_ad OBJ_id_pkix,48L + +# define SN_info_access "authorityInfoAccess" +# define LN_info_access "Authority Information Access" +# define NID_info_access 177 +# define OBJ_info_access OBJ_id_pe,1L + +# define SN_ad_OCSP "OCSP" +# define LN_ad_OCSP "OCSP" +# define NID_ad_OCSP 178 +# define OBJ_ad_OCSP OBJ_id_ad,1L + +# define SN_ad_ca_issuers "caIssuers" +# define LN_ad_ca_issuers "CA Issuers" +# define NID_ad_ca_issuers 179 +# define OBJ_ad_ca_issuers OBJ_id_ad,2L + +# define SN_OCSP_sign "OCSPSigning" +# define LN_OCSP_sign "OCSP Signing" +# define NID_OCSP_sign 180 +# define OBJ_OCSP_sign OBJ_id_kp,9L +# endif /* USE_OBJ_MAC */ + +# include +# include + +# define OBJ_NAME_TYPE_UNDEF 0x00 +# define OBJ_NAME_TYPE_MD_METH 0x01 +# define OBJ_NAME_TYPE_CIPHER_METH 0x02 +# define OBJ_NAME_TYPE_PKEY_METH 0x03 +# define OBJ_NAME_TYPE_COMP_METH 0x04 +# define OBJ_NAME_TYPE_NUM 0x05 + +# define OBJ_NAME_ALIAS 0x8000 + +# define OBJ_BSEARCH_VALUE_ON_NOMATCH 0x01 +# define OBJ_BSEARCH_FIRST_VALUE_ON_MATCH 0x02 + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct obj_name_st { + int type; + int alias; + const char *name; + const char *data; +} OBJ_NAME; + +# define OBJ_create_and_add_object(a,b,c) OBJ_create(a,b,c) + +int OBJ_NAME_init(void); +int OBJ_NAME_new_index(unsigned long (*hash_func) (const char *), + int (*cmp_func) (const char *, const char *), + void (*free_func) (const char *, int, const char *)); +const char *OBJ_NAME_get(const char *name, int type); +int OBJ_NAME_add(const char *name, int type, const char *data); +int OBJ_NAME_remove(const char *name, int type); +void OBJ_NAME_cleanup(int type); /* -1 for everything */ +void OBJ_NAME_do_all(int type, void (*fn) (const OBJ_NAME *, void *arg), + void *arg); +void OBJ_NAME_do_all_sorted(int type, + void (*fn) (const OBJ_NAME *, void *arg), + void *arg); + +ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o); +ASN1_OBJECT *OBJ_nid2obj(int n); +const char *OBJ_nid2ln(int n); +const char *OBJ_nid2sn(int n); +int OBJ_obj2nid(const ASN1_OBJECT *o); +ASN1_OBJECT *OBJ_txt2obj(const char *s, int no_name); +int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name); +int OBJ_txt2nid(const char *s); +int OBJ_ln2nid(const char *s); +int OBJ_sn2nid(const char *s); +int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b); +const void *OBJ_bsearch_(const void *key, const void *base, int num, int size, + int (*cmp) (const void *, const void *)); +const void *OBJ_bsearch_ex_(const void *key, const void *base, int num, + int size, + int (*cmp) (const void *, const void *), + int flags); + +# define _DECLARE_OBJ_BSEARCH_CMP_FN(scope, type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *, const void *); \ + static int nm##_cmp(type1 const *, type2 const *); \ + scope type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +# define DECLARE_OBJ_BSEARCH_CMP_FN(type1, type2, cmp) \ + _DECLARE_OBJ_BSEARCH_CMP_FN(static, type1, type2, cmp) +# define DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + type2 * OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) + +/*- + * Unsolved problem: if a type is actually a pointer type, like + * nid_triple is, then its impossible to get a const where you need + * it. Consider: + * + * typedef int nid_triple[3]; + * const void *a_; + * const nid_triple const *a = a_; + * + * The assignement discards a const because what you really want is: + * + * const int const * const *a = a_; + * + * But if you do that, you lose the fact that a is an array of 3 ints, + * which breaks comparison functions. + * + * Thus we end up having to cast, sadly, or unpack the + * declarations. Or, as I finally did in this case, delcare nid_triple + * to be a struct, which it should have been in the first place. + * + * Ben, August 2008. + * + * Also, strictly speaking not all types need be const, but handling + * the non-constness means a lot of complication, and in practice + * comparison routines do always not touch their arguments. + */ + +# define IMPLEMENT_OBJ_BSEARCH_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + static type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +# define IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(type1, type2, nm) \ + static int nm##_cmp_BSEARCH_CMP_FN(const void *a_, const void *b_) \ + { \ + type1 const *a = a_; \ + type2 const *b = b_; \ + return nm##_cmp(a,b); \ + } \ + type2 *OBJ_bsearch_##nm(type1 *key, type2 const *base, int num) \ + { \ + return (type2 *)OBJ_bsearch_(key, base, num, sizeof(type2), \ + nm##_cmp_BSEARCH_CMP_FN); \ + } \ + extern void dummy_prototype(void) + +# define OBJ_bsearch(type1,key,type2,base,num,cmp) \ + ((type2 *)OBJ_bsearch_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN))) + +# define OBJ_bsearch_ex(type1,key,type2,base,num,cmp,flags) \ + ((type2 *)OBJ_bsearch_ex_(CHECKED_PTR_OF(type1,key),CHECKED_PTR_OF(type2,base), \ + num,sizeof(type2), \ + ((void)CHECKED_PTR_OF(type1,cmp##_type_1), \ + (void)type_2=CHECKED_PTR_OF(type2,cmp##_type_2), \ + cmp##_BSEARCH_CMP_FN)),flags) + +int OBJ_new_nid(int num); +int OBJ_add_object(const ASN1_OBJECT *obj); +int OBJ_create(const char *oid, const char *sn, const char *ln); +void OBJ_cleanup(void); +int OBJ_create_objects(BIO *in); + +int OBJ_find_sigid_algs(int signid, int *pdig_nid, int *ppkey_nid); +int OBJ_find_sigid_by_algs(int *psignid, int dig_nid, int pkey_nid); +int OBJ_add_sigid(int signid, int dig_id, int pkey_id); +void OBJ_sigid_free(void); + +extern int obj_cleanup_defer; +void check_defer(int nid); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_OBJ_strings(void); + +/* Error codes for the OBJ functions. */ + +/* Function codes. */ +# define OBJ_F_OBJ_ADD_OBJECT 105 +# define OBJ_F_OBJ_CREATE 100 +# define OBJ_F_OBJ_DUP 101 +# define OBJ_F_OBJ_NAME_NEW_INDEX 106 +# define OBJ_F_OBJ_NID2LN 102 +# define OBJ_F_OBJ_NID2OBJ 103 +# define OBJ_F_OBJ_NID2SN 104 + +/* Reason codes. */ +# define OBJ_R_MALLOC_FAILURE 100 +# define OBJ_R_UNKNOWN_NID 101 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/objects/objects.pl b/libs/openssl/crypto/objects/objects.pl new file mode 100644 index 00000000..389dc348 --- /dev/null +++ b/libs/openssl/crypto/objects/objects.pl @@ -0,0 +1,240 @@ +#!/usr/local/bin/perl + +open (NUMIN,"$ARGV[1]") || die "Can't open number file $ARGV[1]"; +$max_nid=0; +$o=0; +while() + { + chop; + $o++; + s/#.*$//; + next if /^\s*$/; + $_ = 'X'.$_; + ($Cname,$mynum) = split; + $Cname =~ s/^X//; + if (defined($nidn{$mynum})) + { die "$ARGV[1]:$o:There's already an object with NID ",$mynum," on line ",$order{$mynum},"\n"; } + if (defined($nid{$Cname})) + { die "$ARGV[1]:$o:There's already an object with name ",$Cname," on line ",$order{$nid{$Cname}},"\n"; } + $nid{$Cname} = $mynum; + $nidn{$mynum} = $Cname; + $order{$mynum} = $o; + $max_nid = $mynum if $mynum > $max_nid; + } +close NUMIN; + +open (IN,"$ARGV[0]") || die "Can't open input file $ARGV[0]"; +$Cname=""; +$o=0; +while () + { + chop; + $o++; + if (/^!module\s+(.*)$/) + { + $module = $1."-"; + $module =~ s/\./_/g; + $module =~ s/-/_/g; + } + if (/^!global$/) + { $module = ""; } + if (/^!Cname\s+(.*)$/) + { $Cname = $1; } + if (/^!Alias\s+(.+?)\s+(.*)$/) + { + $Cname = $module.$1; + $myoid = $2; + $myoid = &process_oid($myoid); + $Cname =~ s/-/_/g; + $ordern{$o} = $Cname; + $order{$Cname} = $o; + $obj{$Cname} = $myoid; + $_ = ""; + $Cname = ""; + } + s/!.*$//; + s/#.*$//; + next if /^\s*$/; + ($myoid,$mysn,$myln) = split ':'; + $mysn =~ s/^\s*//; + $mysn =~ s/\s*$//; + $myln =~ s/^\s*//; + $myln =~ s/\s*$//; + $myoid =~ s/^\s*//; + $myoid =~ s/\s*$//; + if ($myoid ne "") + { + $myoid = &process_oid($myoid); + } + + if ($Cname eq "" && ($myln =~ /^[_A-Za-z][\w.-]*$/ )) + { + $Cname = $myln; + $Cname =~ s/\./_/g; + $Cname =~ s/-/_/g; + if ($Cname ne "" && defined($ln{$module.$Cname})) + { die "objects.txt:$o:There's already an object with long name ",$ln{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; } + } + if ($Cname eq "") + { + $Cname = $mysn; + $Cname =~ s/-/_/g; + if ($Cname ne "" && defined($sn{$module.$Cname})) + { die "objects.txt:$o:There's already an object with short name ",$sn{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; } + } + if ($Cname eq "") + { + $Cname = $myln; + $Cname =~ s/-/_/g; + $Cname =~ s/\./_/g; + $Cname =~ s/ /_/g; + if ($Cname ne "" && defined($ln{$module.$Cname})) + { die "objects.txt:$o:There's already an object with long name ",$ln{$module.$Cname}," on line ",$order{$module.$Cname},"\n"; } + } + $Cname =~ s/\./_/g; + $Cname =~ s/-/_/g; + $Cname = $module.$Cname; + $ordern{$o} = $Cname; + $order{$Cname} = $o; + $sn{$Cname} = $mysn; + $ln{$Cname} = $myln; + $obj{$Cname} = $myoid; + if (!defined($nid{$Cname})) + { + $max_nid++; + $nid{$Cname} = $max_nid; + $nidn{$max_nid} = $Cname; +print STDERR "Added OID $Cname\n"; + } + $Cname=""; + } +close IN; + +open (NUMOUT,">$ARGV[1]") || die "Can't open output file $ARGV[1]"; +foreach (sort { $a <=> $b } keys %nidn) + { + print NUMOUT $nidn{$_},"\t\t",$_,"\n"; + } +close NUMOUT; + +open (OUT,">$ARGV[2]") || die "Can't open output file $ARGV[2]"; +print OUT <<'EOF'; +/* crypto/objects/obj_mac.h */ + +/* + * THIS FILE IS GENERATED FROM objects.txt by objects.pl via the following + * command: perl objects.pl objects.txt obj_mac.num obj_mac.h + */ + +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L +EOF + +sub expand + { + my $string = shift; + + 1 while $string =~ s/\t+/' ' x (length($&) * 8 - length($`) % 8)/e; + + return $string; + } + +foreach (sort { $a <=> $b } keys %ordern) + { + $Cname=$ordern{$_}; + print OUT "\n"; + print OUT expand("#define SN_$Cname\t\t\"$sn{$Cname}\"\n") if $sn{$Cname} ne ""; + print OUT expand("#define LN_$Cname\t\t\"$ln{$Cname}\"\n") if $ln{$Cname} ne ""; + print OUT expand("#define NID_$Cname\t\t$nid{$Cname}\n") if $nid{$Cname} ne ""; + print OUT expand("#define OBJ_$Cname\t\t$obj{$Cname}\n") if $obj{$Cname} ne ""; + } + +close OUT; + +sub process_oid + { + local($oid)=@_; + local(@a,$oid_pref); + + @a = split(/\s+/,$myoid); + $pref_oid = ""; + $pref_sep = ""; + if (!($a[0] =~ /^[0-9]+$/)) + { + $a[0] =~ s/-/_/g; + if (!defined($obj{$a[0]})) + { die "$ARGV[0]:$o:Undefined identifier ",$a[0],"\n"; } + $pref_oid = "OBJ_" . $a[0]; + $pref_sep = ","; + shift @a; + } + $oids = join('L,',@a) . "L"; + if ($oids ne "L") + { + $oids = $pref_oid . $pref_sep . $oids; + } + else + { + $oids = $pref_oid; + } + return($oids); + } diff --git a/libs/openssl/crypto/objects/objects.txt b/libs/openssl/crypto/objects/objects.txt new file mode 100644 index 00000000..d3bfad72 --- /dev/null +++ b/libs/openssl/crypto/objects/objects.txt @@ -0,0 +1,1292 @@ +# CCITT was renamed to ITU-T quite some time ago +0 : ITU-T : itu-t +!Alias ccitt itu-t + +1 : ISO : iso + +2 : JOINT-ISO-ITU-T : joint-iso-itu-t +!Alias joint-iso-ccitt joint-iso-itu-t + +iso 2 : member-body : ISO Member Body + +iso 3 : identified-organization + +# HMAC OIDs +identified-organization 6 1 5 5 8 1 1 : HMAC-MD5 : hmac-md5 +identified-organization 6 1 5 5 8 1 2 : HMAC-SHA1 : hmac-sha1 + +identified-organization 132 : certicom-arc + +joint-iso-itu-t 23 : international-organizations : International Organizations + +international-organizations 43 : wap +wap 1 : wap-wsg + +joint-iso-itu-t 5 1 5 : selected-attribute-types : Selected Attribute Types + +selected-attribute-types 55 : clearance + +member-body 840 : ISO-US : ISO US Member Body +ISO-US 10040 : X9-57 : X9.57 +X9-57 4 : X9cm : X9.57 CM ? + +!Cname dsa +X9cm 1 : DSA : dsaEncryption +X9cm 3 : DSA-SHA1 : dsaWithSHA1 + + +ISO-US 10045 : ansi-X9-62 : ANSI X9.62 +!module X9-62 +!Alias id-fieldType ansi-X9-62 1 +X9-62_id-fieldType 1 : prime-field +X9-62_id-fieldType 2 : characteristic-two-field +X9-62_characteristic-two-field 3 : id-characteristic-two-basis +X9-62_id-characteristic-two-basis 1 : onBasis +X9-62_id-characteristic-two-basis 2 : tpBasis +X9-62_id-characteristic-two-basis 3 : ppBasis +!Alias id-publicKeyType ansi-X9-62 2 +X9-62_id-publicKeyType 1 : id-ecPublicKey +!Alias ellipticCurve ansi-X9-62 3 +!Alias c-TwoCurve X9-62_ellipticCurve 0 +X9-62_c-TwoCurve 1 : c2pnb163v1 +X9-62_c-TwoCurve 2 : c2pnb163v2 +X9-62_c-TwoCurve 3 : c2pnb163v3 +X9-62_c-TwoCurve 4 : c2pnb176v1 +X9-62_c-TwoCurve 5 : c2tnb191v1 +X9-62_c-TwoCurve 6 : c2tnb191v2 +X9-62_c-TwoCurve 7 : c2tnb191v3 +X9-62_c-TwoCurve 8 : c2onb191v4 +X9-62_c-TwoCurve 9 : c2onb191v5 +X9-62_c-TwoCurve 10 : c2pnb208w1 +X9-62_c-TwoCurve 11 : c2tnb239v1 +X9-62_c-TwoCurve 12 : c2tnb239v2 +X9-62_c-TwoCurve 13 : c2tnb239v3 +X9-62_c-TwoCurve 14 : c2onb239v4 +X9-62_c-TwoCurve 15 : c2onb239v5 +X9-62_c-TwoCurve 16 : c2pnb272w1 +X9-62_c-TwoCurve 17 : c2pnb304w1 +X9-62_c-TwoCurve 18 : c2tnb359v1 +X9-62_c-TwoCurve 19 : c2pnb368w1 +X9-62_c-TwoCurve 20 : c2tnb431r1 +!Alias primeCurve X9-62_ellipticCurve 1 +X9-62_primeCurve 1 : prime192v1 +X9-62_primeCurve 2 : prime192v2 +X9-62_primeCurve 3 : prime192v3 +X9-62_primeCurve 4 : prime239v1 +X9-62_primeCurve 5 : prime239v2 +X9-62_primeCurve 6 : prime239v3 +X9-62_primeCurve 7 : prime256v1 +!Alias id-ecSigType ansi-X9-62 4 +!global +X9-62_id-ecSigType 1 : ecdsa-with-SHA1 +X9-62_id-ecSigType 2 : ecdsa-with-Recommended +X9-62_id-ecSigType 3 : ecdsa-with-Specified +ecdsa-with-Specified 1 : ecdsa-with-SHA224 +ecdsa-with-Specified 2 : ecdsa-with-SHA256 +ecdsa-with-Specified 3 : ecdsa-with-SHA384 +ecdsa-with-Specified 4 : ecdsa-with-SHA512 + +# SECG curve OIDs from "SEC 2: Recommended Elliptic Curve Domain Parameters" +# (http://www.secg.org/) +!Alias secg_ellipticCurve certicom-arc 0 +# SECG prime curves OIDs +secg-ellipticCurve 6 : secp112r1 +secg-ellipticCurve 7 : secp112r2 +secg-ellipticCurve 28 : secp128r1 +secg-ellipticCurve 29 : secp128r2 +secg-ellipticCurve 9 : secp160k1 +secg-ellipticCurve 8 : secp160r1 +secg-ellipticCurve 30 : secp160r2 +secg-ellipticCurve 31 : secp192k1 +# NOTE: the curve secp192r1 is the same as prime192v1 defined above +# and is therefore omitted +secg-ellipticCurve 32 : secp224k1 +secg-ellipticCurve 33 : secp224r1 +secg-ellipticCurve 10 : secp256k1 +# NOTE: the curve secp256r1 is the same as prime256v1 defined above +# and is therefore omitted +secg-ellipticCurve 34 : secp384r1 +secg-ellipticCurve 35 : secp521r1 +# SECG characteristic two curves OIDs +secg-ellipticCurve 4 : sect113r1 +secg-ellipticCurve 5 : sect113r2 +secg-ellipticCurve 22 : sect131r1 +secg-ellipticCurve 23 : sect131r2 +secg-ellipticCurve 1 : sect163k1 +secg-ellipticCurve 2 : sect163r1 +secg-ellipticCurve 15 : sect163r2 +secg-ellipticCurve 24 : sect193r1 +secg-ellipticCurve 25 : sect193r2 +secg-ellipticCurve 26 : sect233k1 +secg-ellipticCurve 27 : sect233r1 +secg-ellipticCurve 3 : sect239k1 +secg-ellipticCurve 16 : sect283k1 +secg-ellipticCurve 17 : sect283r1 +secg-ellipticCurve 36 : sect409k1 +secg-ellipticCurve 37 : sect409r1 +secg-ellipticCurve 38 : sect571k1 +secg-ellipticCurve 39 : sect571r1 + +# WAP/TLS curve OIDs (http://www.wapforum.org/) +!Alias wap-wsg-idm-ecid wap-wsg 4 +wap-wsg-idm-ecid 1 : wap-wsg-idm-ecid-wtls1 +wap-wsg-idm-ecid 3 : wap-wsg-idm-ecid-wtls3 +wap-wsg-idm-ecid 4 : wap-wsg-idm-ecid-wtls4 +wap-wsg-idm-ecid 5 : wap-wsg-idm-ecid-wtls5 +wap-wsg-idm-ecid 6 : wap-wsg-idm-ecid-wtls6 +wap-wsg-idm-ecid 7 : wap-wsg-idm-ecid-wtls7 +wap-wsg-idm-ecid 8 : wap-wsg-idm-ecid-wtls8 +wap-wsg-idm-ecid 9 : wap-wsg-idm-ecid-wtls9 +wap-wsg-idm-ecid 10 : wap-wsg-idm-ecid-wtls10 +wap-wsg-idm-ecid 11 : wap-wsg-idm-ecid-wtls11 +wap-wsg-idm-ecid 12 : wap-wsg-idm-ecid-wtls12 + + +ISO-US 113533 7 66 10 : CAST5-CBC : cast5-cbc + : CAST5-ECB : cast5-ecb +!Cname cast5-cfb64 + : CAST5-CFB : cast5-cfb +!Cname cast5-ofb64 + : CAST5-OFB : cast5-ofb +!Cname pbeWithMD5AndCast5-CBC +ISO-US 113533 7 66 12 : : pbeWithMD5AndCast5CBC + +# Macs for CMP and CRMF +ISO-US 113533 7 66 13 : id-PasswordBasedMAC : password based MAC +ISO-US 113533 7 66 30 : id-DHBasedMac : Diffie-Hellman based MAC + +ISO-US 113549 : rsadsi : RSA Data Security, Inc. + +rsadsi 1 : pkcs : RSA Data Security, Inc. PKCS + +pkcs 1 : pkcs1 +pkcs1 1 : : rsaEncryption +pkcs1 2 : RSA-MD2 : md2WithRSAEncryption +pkcs1 3 : RSA-MD4 : md4WithRSAEncryption +pkcs1 4 : RSA-MD5 : md5WithRSAEncryption +pkcs1 5 : RSA-SHA1 : sha1WithRSAEncryption +# According to PKCS #1 version 2.1 +pkcs1 7 : RSAES-OAEP : rsaesOaep +pkcs1 8 : MGF1 : mgf1 +pkcs1 10 : RSASSA-PSS : rsassaPss + +pkcs1 11 : RSA-SHA256 : sha256WithRSAEncryption +pkcs1 12 : RSA-SHA384 : sha384WithRSAEncryption +pkcs1 13 : RSA-SHA512 : sha512WithRSAEncryption +pkcs1 14 : RSA-SHA224 : sha224WithRSAEncryption + +pkcs 3 : pkcs3 +pkcs3 1 : : dhKeyAgreement + +pkcs 5 : pkcs5 +pkcs5 1 : PBE-MD2-DES : pbeWithMD2AndDES-CBC +pkcs5 3 : PBE-MD5-DES : pbeWithMD5AndDES-CBC +pkcs5 4 : PBE-MD2-RC2-64 : pbeWithMD2AndRC2-CBC +pkcs5 6 : PBE-MD5-RC2-64 : pbeWithMD5AndRC2-CBC +pkcs5 10 : PBE-SHA1-DES : pbeWithSHA1AndDES-CBC +pkcs5 11 : PBE-SHA1-RC2-64 : pbeWithSHA1AndRC2-CBC +!Cname id_pbkdf2 +pkcs5 12 : : PBKDF2 +!Cname pbes2 +pkcs5 13 : : PBES2 +!Cname pbmac1 +pkcs5 14 : : PBMAC1 + +pkcs 7 : pkcs7 +pkcs7 1 : : pkcs7-data +!Cname pkcs7-signed +pkcs7 2 : : pkcs7-signedData +!Cname pkcs7-enveloped +pkcs7 3 : : pkcs7-envelopedData +!Cname pkcs7-signedAndEnveloped +pkcs7 4 : : pkcs7-signedAndEnvelopedData +!Cname pkcs7-digest +pkcs7 5 : : pkcs7-digestData +!Cname pkcs7-encrypted +pkcs7 6 : : pkcs7-encryptedData + +pkcs 9 : pkcs9 +!module pkcs9 +pkcs9 1 : : emailAddress +pkcs9 2 : : unstructuredName +pkcs9 3 : : contentType +pkcs9 4 : : messageDigest +pkcs9 5 : : signingTime +pkcs9 6 : : countersignature +pkcs9 7 : : challengePassword +pkcs9 8 : : unstructuredAddress +!Cname extCertAttributes +pkcs9 9 : : extendedCertificateAttributes +!global + +!Cname ext-req +pkcs9 14 : extReq : Extension Request + +!Cname SMIMECapabilities +pkcs9 15 : SMIME-CAPS : S/MIME Capabilities + +# S/MIME +!Cname SMIME +pkcs9 16 : SMIME : S/MIME +SMIME 0 : id-smime-mod +SMIME 1 : id-smime-ct +SMIME 2 : id-smime-aa +SMIME 3 : id-smime-alg +SMIME 4 : id-smime-cd +SMIME 5 : id-smime-spq +SMIME 6 : id-smime-cti + +# S/MIME Modules +id-smime-mod 1 : id-smime-mod-cms +id-smime-mod 2 : id-smime-mod-ess +id-smime-mod 3 : id-smime-mod-oid +id-smime-mod 4 : id-smime-mod-msg-v3 +id-smime-mod 5 : id-smime-mod-ets-eSignature-88 +id-smime-mod 6 : id-smime-mod-ets-eSignature-97 +id-smime-mod 7 : id-smime-mod-ets-eSigPolicy-88 +id-smime-mod 8 : id-smime-mod-ets-eSigPolicy-97 + +# S/MIME Content Types +id-smime-ct 1 : id-smime-ct-receipt +id-smime-ct 2 : id-smime-ct-authData +id-smime-ct 3 : id-smime-ct-publishCert +id-smime-ct 4 : id-smime-ct-TSTInfo +id-smime-ct 5 : id-smime-ct-TDTInfo +id-smime-ct 6 : id-smime-ct-contentInfo +id-smime-ct 7 : id-smime-ct-DVCSRequestData +id-smime-ct 8 : id-smime-ct-DVCSResponseData +id-smime-ct 9 : id-smime-ct-compressedData +id-smime-ct 27 : id-ct-asciiTextWithCRLF + +# S/MIME Attributes +id-smime-aa 1 : id-smime-aa-receiptRequest +id-smime-aa 2 : id-smime-aa-securityLabel +id-smime-aa 3 : id-smime-aa-mlExpandHistory +id-smime-aa 4 : id-smime-aa-contentHint +id-smime-aa 5 : id-smime-aa-msgSigDigest +# obsolete +id-smime-aa 6 : id-smime-aa-encapContentType +id-smime-aa 7 : id-smime-aa-contentIdentifier +# obsolete +id-smime-aa 8 : id-smime-aa-macValue +id-smime-aa 9 : id-smime-aa-equivalentLabels +id-smime-aa 10 : id-smime-aa-contentReference +id-smime-aa 11 : id-smime-aa-encrypKeyPref +id-smime-aa 12 : id-smime-aa-signingCertificate +id-smime-aa 13 : id-smime-aa-smimeEncryptCerts +id-smime-aa 14 : id-smime-aa-timeStampToken +id-smime-aa 15 : id-smime-aa-ets-sigPolicyId +id-smime-aa 16 : id-smime-aa-ets-commitmentType +id-smime-aa 17 : id-smime-aa-ets-signerLocation +id-smime-aa 18 : id-smime-aa-ets-signerAttr +id-smime-aa 19 : id-smime-aa-ets-otherSigCert +id-smime-aa 20 : id-smime-aa-ets-contentTimestamp +id-smime-aa 21 : id-smime-aa-ets-CertificateRefs +id-smime-aa 22 : id-smime-aa-ets-RevocationRefs +id-smime-aa 23 : id-smime-aa-ets-certValues +id-smime-aa 24 : id-smime-aa-ets-revocationValues +id-smime-aa 25 : id-smime-aa-ets-escTimeStamp +id-smime-aa 26 : id-smime-aa-ets-certCRLTimestamp +id-smime-aa 27 : id-smime-aa-ets-archiveTimeStamp +id-smime-aa 28 : id-smime-aa-signatureType +id-smime-aa 29 : id-smime-aa-dvcs-dvc + +# S/MIME Algorithm Identifiers +# obsolete +id-smime-alg 1 : id-smime-alg-ESDHwith3DES +# obsolete +id-smime-alg 2 : id-smime-alg-ESDHwithRC2 +# obsolete +id-smime-alg 3 : id-smime-alg-3DESwrap +# obsolete +id-smime-alg 4 : id-smime-alg-RC2wrap +id-smime-alg 5 : id-smime-alg-ESDH +id-smime-alg 6 : id-smime-alg-CMS3DESwrap +id-smime-alg 7 : id-smime-alg-CMSRC2wrap +id-smime-alg 9 : id-alg-PWRI-KEK + +# S/MIME Certificate Distribution +id-smime-cd 1 : id-smime-cd-ldap + +# S/MIME Signature Policy Qualifier +id-smime-spq 1 : id-smime-spq-ets-sqt-uri +id-smime-spq 2 : id-smime-spq-ets-sqt-unotice + +# S/MIME Commitment Type Identifier +id-smime-cti 1 : id-smime-cti-ets-proofOfOrigin +id-smime-cti 2 : id-smime-cti-ets-proofOfReceipt +id-smime-cti 3 : id-smime-cti-ets-proofOfDelivery +id-smime-cti 4 : id-smime-cti-ets-proofOfSender +id-smime-cti 5 : id-smime-cti-ets-proofOfApproval +id-smime-cti 6 : id-smime-cti-ets-proofOfCreation + +pkcs9 20 : : friendlyName +pkcs9 21 : : localKeyID +!Cname ms-csp-name +1 3 6 1 4 1 311 17 1 : CSPName : Microsoft CSP Name +1 3 6 1 4 1 311 17 2 : LocalKeySet : Microsoft Local Key set +!Alias certTypes pkcs9 22 +certTypes 1 : : x509Certificate +certTypes 2 : : sdsiCertificate +!Alias crlTypes pkcs9 23 +crlTypes 1 : : x509Crl + +!Alias pkcs12 pkcs 12 +!Alias pkcs12-pbeids pkcs12 1 + +!Cname pbe-WithSHA1And128BitRC4 +pkcs12-pbeids 1 : PBE-SHA1-RC4-128 : pbeWithSHA1And128BitRC4 +!Cname pbe-WithSHA1And40BitRC4 +pkcs12-pbeids 2 : PBE-SHA1-RC4-40 : pbeWithSHA1And40BitRC4 +!Cname pbe-WithSHA1And3_Key_TripleDES-CBC +pkcs12-pbeids 3 : PBE-SHA1-3DES : pbeWithSHA1And3-KeyTripleDES-CBC +!Cname pbe-WithSHA1And2_Key_TripleDES-CBC +pkcs12-pbeids 4 : PBE-SHA1-2DES : pbeWithSHA1And2-KeyTripleDES-CBC +!Cname pbe-WithSHA1And128BitRC2-CBC +pkcs12-pbeids 5 : PBE-SHA1-RC2-128 : pbeWithSHA1And128BitRC2-CBC +!Cname pbe-WithSHA1And40BitRC2-CBC +pkcs12-pbeids 6 : PBE-SHA1-RC2-40 : pbeWithSHA1And40BitRC2-CBC + +!Alias pkcs12-Version1 pkcs12 10 +!Alias pkcs12-BagIds pkcs12-Version1 1 +pkcs12-BagIds 1 : : keyBag +pkcs12-BagIds 2 : : pkcs8ShroudedKeyBag +pkcs12-BagIds 3 : : certBag +pkcs12-BagIds 4 : : crlBag +pkcs12-BagIds 5 : : secretBag +pkcs12-BagIds 6 : : safeContentsBag + +rsadsi 2 2 : MD2 : md2 +rsadsi 2 4 : MD4 : md4 +rsadsi 2 5 : MD5 : md5 + : MD5-SHA1 : md5-sha1 +rsadsi 2 6 : : hmacWithMD5 +rsadsi 2 7 : : hmacWithSHA1 + +# From RFC4231 +rsadsi 2 8 : : hmacWithSHA224 +rsadsi 2 9 : : hmacWithSHA256 +rsadsi 2 10 : : hmacWithSHA384 +rsadsi 2 11 : : hmacWithSHA512 + +rsadsi 3 2 : RC2-CBC : rc2-cbc + : RC2-ECB : rc2-ecb +!Cname rc2-cfb64 + : RC2-CFB : rc2-cfb +!Cname rc2-ofb64 + : RC2-OFB : rc2-ofb + : RC2-40-CBC : rc2-40-cbc + : RC2-64-CBC : rc2-64-cbc +rsadsi 3 4 : RC4 : rc4 + : RC4-40 : rc4-40 +rsadsi 3 7 : DES-EDE3-CBC : des-ede3-cbc +rsadsi 3 8 : RC5-CBC : rc5-cbc + : RC5-ECB : rc5-ecb +!Cname rc5-cfb64 + : RC5-CFB : rc5-cfb +!Cname rc5-ofb64 + : RC5-OFB : rc5-ofb + +!Cname ms-ext-req +1 3 6 1 4 1 311 2 1 14 : msExtReq : Microsoft Extension Request +!Cname ms-code-ind +1 3 6 1 4 1 311 2 1 21 : msCodeInd : Microsoft Individual Code Signing +!Cname ms-code-com +1 3 6 1 4 1 311 2 1 22 : msCodeCom : Microsoft Commercial Code Signing +!Cname ms-ctl-sign +1 3 6 1 4 1 311 10 3 1 : msCTLSign : Microsoft Trust List Signing +!Cname ms-sgc +1 3 6 1 4 1 311 10 3 3 : msSGC : Microsoft Server Gated Crypto +!Cname ms-efs +1 3 6 1 4 1 311 10 3 4 : msEFS : Microsoft Encrypted File System +!Cname ms-smartcard-login +1 3 6 1 4 1 311 20 2 2 : msSmartcardLogin : Microsoft Smartcardlogin +!Cname ms-upn +1 3 6 1 4 1 311 20 2 3 : msUPN : Microsoft Universal Principal Name + +1 3 6 1 4 1 188 7 1 1 2 : IDEA-CBC : idea-cbc + : IDEA-ECB : idea-ecb +!Cname idea-cfb64 + : IDEA-CFB : idea-cfb +!Cname idea-ofb64 + : IDEA-OFB : idea-ofb + +1 3 6 1 4 1 3029 1 2 : BF-CBC : bf-cbc + : BF-ECB : bf-ecb +!Cname bf-cfb64 + : BF-CFB : bf-cfb +!Cname bf-ofb64 + : BF-OFB : bf-ofb + +!Cname id-pkix +1 3 6 1 5 5 7 : PKIX + +# PKIX Arcs +id-pkix 0 : id-pkix-mod +id-pkix 1 : id-pe +id-pkix 2 : id-qt +id-pkix 3 : id-kp +id-pkix 4 : id-it +id-pkix 5 : id-pkip +id-pkix 6 : id-alg +id-pkix 7 : id-cmc +id-pkix 8 : id-on +id-pkix 9 : id-pda +id-pkix 10 : id-aca +id-pkix 11 : id-qcs +id-pkix 12 : id-cct +id-pkix 21 : id-ppl +id-pkix 48 : id-ad + +# PKIX Modules +id-pkix-mod 1 : id-pkix1-explicit-88 +id-pkix-mod 2 : id-pkix1-implicit-88 +id-pkix-mod 3 : id-pkix1-explicit-93 +id-pkix-mod 4 : id-pkix1-implicit-93 +id-pkix-mod 5 : id-mod-crmf +id-pkix-mod 6 : id-mod-cmc +id-pkix-mod 7 : id-mod-kea-profile-88 +id-pkix-mod 8 : id-mod-kea-profile-93 +id-pkix-mod 9 : id-mod-cmp +id-pkix-mod 10 : id-mod-qualified-cert-88 +id-pkix-mod 11 : id-mod-qualified-cert-93 +id-pkix-mod 12 : id-mod-attribute-cert +id-pkix-mod 13 : id-mod-timestamp-protocol +id-pkix-mod 14 : id-mod-ocsp +id-pkix-mod 15 : id-mod-dvcs +id-pkix-mod 16 : id-mod-cmp2000 + +# PKIX Private Extensions +!Cname info-access +id-pe 1 : authorityInfoAccess : Authority Information Access +id-pe 2 : biometricInfo : Biometric Info +id-pe 3 : qcStatements +id-pe 4 : ac-auditEntity +id-pe 5 : ac-targeting +id-pe 6 : aaControls +id-pe 7 : sbgp-ipAddrBlock +id-pe 8 : sbgp-autonomousSysNum +id-pe 9 : sbgp-routerIdentifier +id-pe 10 : ac-proxying +!Cname sinfo-access +id-pe 11 : subjectInfoAccess : Subject Information Access +id-pe 14 : proxyCertInfo : Proxy Certificate Information + +# PKIX policyQualifiers for Internet policy qualifiers +id-qt 1 : id-qt-cps : Policy Qualifier CPS +id-qt 2 : id-qt-unotice : Policy Qualifier User Notice +id-qt 3 : textNotice + +# PKIX key purpose identifiers +!Cname server-auth +id-kp 1 : serverAuth : TLS Web Server Authentication +!Cname client-auth +id-kp 2 : clientAuth : TLS Web Client Authentication +!Cname code-sign +id-kp 3 : codeSigning : Code Signing +!Cname email-protect +id-kp 4 : emailProtection : E-mail Protection +id-kp 5 : ipsecEndSystem : IPSec End System +id-kp 6 : ipsecTunnel : IPSec Tunnel +id-kp 7 : ipsecUser : IPSec User +!Cname time-stamp +id-kp 8 : timeStamping : Time Stamping +# From OCSP spec RFC2560 +!Cname OCSP-sign +id-kp 9 : OCSPSigning : OCSP Signing +id-kp 10 : DVCS : dvcs + +# CMP information types +id-it 1 : id-it-caProtEncCert +id-it 2 : id-it-signKeyPairTypes +id-it 3 : id-it-encKeyPairTypes +id-it 4 : id-it-preferredSymmAlg +id-it 5 : id-it-caKeyUpdateInfo +id-it 6 : id-it-currentCRL +id-it 7 : id-it-unsupportedOIDs +# obsolete +id-it 8 : id-it-subscriptionRequest +# obsolete +id-it 9 : id-it-subscriptionResponse +id-it 10 : id-it-keyPairParamReq +id-it 11 : id-it-keyPairParamRep +id-it 12 : id-it-revPassphrase +id-it 13 : id-it-implicitConfirm +id-it 14 : id-it-confirmWaitTime +id-it 15 : id-it-origPKIMessage +id-it 16 : id-it-suppLangTags + +# CRMF registration +id-pkip 1 : id-regCtrl +id-pkip 2 : id-regInfo + +# CRMF registration controls +id-regCtrl 1 : id-regCtrl-regToken +id-regCtrl 2 : id-regCtrl-authenticator +id-regCtrl 3 : id-regCtrl-pkiPublicationInfo +id-regCtrl 4 : id-regCtrl-pkiArchiveOptions +id-regCtrl 5 : id-regCtrl-oldCertID +id-regCtrl 6 : id-regCtrl-protocolEncrKey + +# CRMF registration information +id-regInfo 1 : id-regInfo-utf8Pairs +id-regInfo 2 : id-regInfo-certReq + +# algorithms +id-alg 1 : id-alg-des40 +id-alg 2 : id-alg-noSignature +id-alg 3 : id-alg-dh-sig-hmac-sha1 +id-alg 4 : id-alg-dh-pop + +# CMC controls +id-cmc 1 : id-cmc-statusInfo +id-cmc 2 : id-cmc-identification +id-cmc 3 : id-cmc-identityProof +id-cmc 4 : id-cmc-dataReturn +id-cmc 5 : id-cmc-transactionId +id-cmc 6 : id-cmc-senderNonce +id-cmc 7 : id-cmc-recipientNonce +id-cmc 8 : id-cmc-addExtensions +id-cmc 9 : id-cmc-encryptedPOP +id-cmc 10 : id-cmc-decryptedPOP +id-cmc 11 : id-cmc-lraPOPWitness +id-cmc 15 : id-cmc-getCert +id-cmc 16 : id-cmc-getCRL +id-cmc 17 : id-cmc-revokeRequest +id-cmc 18 : id-cmc-regInfo +id-cmc 19 : id-cmc-responseInfo +id-cmc 21 : id-cmc-queryPending +id-cmc 22 : id-cmc-popLinkRandom +id-cmc 23 : id-cmc-popLinkWitness +id-cmc 24 : id-cmc-confirmCertAcceptance + +# other names +id-on 1 : id-on-personalData +id-on 3 : id-on-permanentIdentifier : Permanent Identifier + +# personal data attributes +id-pda 1 : id-pda-dateOfBirth +id-pda 2 : id-pda-placeOfBirth +id-pda 3 : id-pda-gender +id-pda 4 : id-pda-countryOfCitizenship +id-pda 5 : id-pda-countryOfResidence + +# attribute certificate attributes +id-aca 1 : id-aca-authenticationInfo +id-aca 2 : id-aca-accessIdentity +id-aca 3 : id-aca-chargingIdentity +id-aca 4 : id-aca-group +# attention : the following seems to be obsolete, replace by 'role' +id-aca 5 : id-aca-role +id-aca 6 : id-aca-encAttrs + +# qualified certificate statements +id-qcs 1 : id-qcs-pkixQCSyntax-v1 + +# CMC content types +id-cct 1 : id-cct-crs +id-cct 2 : id-cct-PKIData +id-cct 3 : id-cct-PKIResponse + +# Predefined Proxy Certificate policy languages +id-ppl 0 : id-ppl-anyLanguage : Any language +id-ppl 1 : id-ppl-inheritAll : Inherit all +id-ppl 2 : id-ppl-independent : Independent + +# access descriptors for authority info access extension +!Cname ad-OCSP +id-ad 1 : OCSP : OCSP +!Cname ad-ca-issuers +id-ad 2 : caIssuers : CA Issuers +!Cname ad-timeStamping +id-ad 3 : ad_timestamping : AD Time Stamping +!Cname ad-dvcs +id-ad 4 : AD_DVCS : ad dvcs +id-ad 5 : caRepository : CA Repository + + +!Alias id-pkix-OCSP ad-OCSP +!module id-pkix-OCSP +!Cname basic +id-pkix-OCSP 1 : basicOCSPResponse : Basic OCSP Response +id-pkix-OCSP 2 : Nonce : OCSP Nonce +id-pkix-OCSP 3 : CrlID : OCSP CRL ID +id-pkix-OCSP 4 : acceptableResponses : Acceptable OCSP Responses +id-pkix-OCSP 5 : noCheck : OCSP No Check +id-pkix-OCSP 6 : archiveCutoff : OCSP Archive Cutoff +id-pkix-OCSP 7 : serviceLocator : OCSP Service Locator +id-pkix-OCSP 8 : extendedStatus : Extended OCSP Status +id-pkix-OCSP 9 : valid +id-pkix-OCSP 10 : path +id-pkix-OCSP 11 : trustRoot : Trust Root +!global + +1 3 14 3 2 : algorithm : algorithm +algorithm 3 : RSA-NP-MD5 : md5WithRSA +algorithm 6 : DES-ECB : des-ecb +algorithm 7 : DES-CBC : des-cbc +!Cname des-ofb64 +algorithm 8 : DES-OFB : des-ofb +!Cname des-cfb64 +algorithm 9 : DES-CFB : des-cfb +algorithm 11 : rsaSignature +!Cname dsa-2 +algorithm 12 : DSA-old : dsaEncryption-old +algorithm 13 : DSA-SHA : dsaWithSHA +algorithm 15 : RSA-SHA : shaWithRSAEncryption +!Cname des-ede-ecb +algorithm 17 : DES-EDE : des-ede +!Cname des-ede3-ecb + : DES-EDE3 : des-ede3 + : DES-EDE-CBC : des-ede-cbc +!Cname des-ede-cfb64 + : DES-EDE-CFB : des-ede-cfb +!Cname des-ede3-cfb64 + : DES-EDE3-CFB : des-ede3-cfb +!Cname des-ede-ofb64 + : DES-EDE-OFB : des-ede-ofb +!Cname des-ede3-ofb64 + : DES-EDE3-OFB : des-ede3-ofb + : DESX-CBC : desx-cbc +algorithm 18 : SHA : sha +algorithm 26 : SHA1 : sha1 +!Cname dsaWithSHA1-2 +algorithm 27 : DSA-SHA1-old : dsaWithSHA1-old +algorithm 29 : RSA-SHA1-2 : sha1WithRSA + +1 3 36 3 2 1 : RIPEMD160 : ripemd160 +1 3 36 3 3 1 2 : RSA-RIPEMD160 : ripemd160WithRSA + +!Cname sxnet +1 3 101 1 4 1 : SXNetID : Strong Extranet ID + +2 5 : X500 : directory services (X.500) + +X500 4 : X509 +X509 3 : CN : commonName +X509 4 : SN : surname +X509 5 : : serialNumber +X509 6 : C : countryName +X509 7 : L : localityName +X509 8 : ST : stateOrProvinceName +X509 9 : street : streetAddress +X509 10 : O : organizationName +X509 11 : OU : organizationalUnitName +X509 12 : title : title +X509 13 : : description +X509 14 : : searchGuide +X509 15 : : businessCategory +X509 16 : : postalAddress +X509 17 : : postalCode +X509 18 : : postOfficeBox +X509 19 : : physicalDeliveryOfficeName +X509 20 : : telephoneNumber +X509 21 : : telexNumber +X509 22 : : teletexTerminalIdentifier +X509 23 : : facsimileTelephoneNumber +X509 24 : : x121Address +X509 25 : : internationaliSDNNumber +X509 26 : : registeredAddress +X509 27 : : destinationIndicator +X509 28 : : preferredDeliveryMethod +X509 29 : : presentationAddress +X509 30 : : supportedApplicationContext +X509 31 : member : +X509 32 : owner : +X509 33 : : roleOccupant +X509 34 : seeAlso : +X509 35 : : userPassword +X509 36 : : userCertificate +X509 37 : : cACertificate +X509 38 : : authorityRevocationList +X509 39 : : certificateRevocationList +X509 40 : : crossCertificatePair +X509 41 : name : name +X509 42 : GN : givenName +X509 43 : initials : initials +X509 44 : : generationQualifier +X509 45 : : x500UniqueIdentifier +X509 46 : dnQualifier : dnQualifier +X509 47 : : enhancedSearchGuide +X509 48 : : protocolInformation +X509 49 : : distinguishedName +X509 50 : : uniqueMember +X509 51 : : houseIdentifier +X509 52 : : supportedAlgorithms +X509 53 : : deltaRevocationList +X509 54 : dmdName : +X509 65 : : pseudonym +X509 72 : role : role + +X500 8 : X500algorithms : directory services - algorithms +X500algorithms 1 1 : RSA : rsa +X500algorithms 3 100 : RSA-MDC2 : mdc2WithRSA +X500algorithms 3 101 : MDC2 : mdc2 + +X500 29 : id-ce +!Cname subject-directory-attributes +id-ce 9 : subjectDirectoryAttributes : X509v3 Subject Directory Attributes +!Cname subject-key-identifier +id-ce 14 : subjectKeyIdentifier : X509v3 Subject Key Identifier +!Cname key-usage +id-ce 15 : keyUsage : X509v3 Key Usage +!Cname private-key-usage-period +id-ce 16 : privateKeyUsagePeriod : X509v3 Private Key Usage Period +!Cname subject-alt-name +id-ce 17 : subjectAltName : X509v3 Subject Alternative Name +!Cname issuer-alt-name +id-ce 18 : issuerAltName : X509v3 Issuer Alternative Name +!Cname basic-constraints +id-ce 19 : basicConstraints : X509v3 Basic Constraints +!Cname crl-number +id-ce 20 : crlNumber : X509v3 CRL Number +!Cname crl-reason +id-ce 21 : CRLReason : X509v3 CRL Reason Code +!Cname invalidity-date +id-ce 24 : invalidityDate : Invalidity Date +!Cname delta-crl +id-ce 27 : deltaCRL : X509v3 Delta CRL Indicator +!Cname issuing-distribution-point +id-ce 28 : issuingDistributionPoint : X509v3 Issuing Distrubution Point +!Cname certificate-issuer +id-ce 29 : certificateIssuer : X509v3 Certificate Issuer +!Cname name-constraints +id-ce 30 : nameConstraints : X509v3 Name Constraints +!Cname crl-distribution-points +id-ce 31 : crlDistributionPoints : X509v3 CRL Distribution Points +!Cname certificate-policies +id-ce 32 : certificatePolicies : X509v3 Certificate Policies +!Cname any-policy +certificate-policies 0 : anyPolicy : X509v3 Any Policy +!Cname policy-mappings +id-ce 33 : policyMappings : X509v3 Policy Mappings +!Cname authority-key-identifier +id-ce 35 : authorityKeyIdentifier : X509v3 Authority Key Identifier +!Cname policy-constraints +id-ce 36 : policyConstraints : X509v3 Policy Constraints +!Cname ext-key-usage +id-ce 37 : extendedKeyUsage : X509v3 Extended Key Usage +!Cname freshest-crl +id-ce 46 : freshestCRL : X509v3 Freshest CRL +!Cname inhibit-any-policy +id-ce 54 : inhibitAnyPolicy : X509v3 Inhibit Any Policy +!Cname target-information +id-ce 55 : targetInformation : X509v3 AC Targeting +!Cname no-rev-avail +id-ce 56 : noRevAvail : X509v3 No Revocation Available + +# From RFC5280 +ext-key-usage 0 : anyExtendedKeyUsage : Any Extended Key Usage + + +!Cname netscape +2 16 840 1 113730 : Netscape : Netscape Communications Corp. +!Cname netscape-cert-extension +netscape 1 : nsCertExt : Netscape Certificate Extension +!Cname netscape-data-type +netscape 2 : nsDataType : Netscape Data Type +!Cname netscape-cert-type +netscape-cert-extension 1 : nsCertType : Netscape Cert Type +!Cname netscape-base-url +netscape-cert-extension 2 : nsBaseUrl : Netscape Base Url +!Cname netscape-revocation-url +netscape-cert-extension 3 : nsRevocationUrl : Netscape Revocation Url +!Cname netscape-ca-revocation-url +netscape-cert-extension 4 : nsCaRevocationUrl : Netscape CA Revocation Url +!Cname netscape-renewal-url +netscape-cert-extension 7 : nsRenewalUrl : Netscape Renewal Url +!Cname netscape-ca-policy-url +netscape-cert-extension 8 : nsCaPolicyUrl : Netscape CA Policy Url +!Cname netscape-ssl-server-name +netscape-cert-extension 12 : nsSslServerName : Netscape SSL Server Name +!Cname netscape-comment +netscape-cert-extension 13 : nsComment : Netscape Comment +!Cname netscape-cert-sequence +netscape-data-type 5 : nsCertSequence : Netscape Certificate Sequence +!Cname ns-sgc +netscape 4 1 : nsSGC : Netscape Server Gated Crypto + +# iso(1) +iso 3 : ORG : org +org 6 : DOD : dod +dod 1 : IANA : iana +!Alias internet iana + +internet 1 : directory : Directory +internet 2 : mgmt : Management +internet 3 : experimental : Experimental +internet 4 : private : Private +internet 5 : security : Security +internet 6 : snmpv2 : SNMPv2 +# Documents refer to "internet 7" as "mail". This however leads to ambiguities +# with RFC2798, Section 9.1.3, where "mail" is defined as the short name for +# rfc822Mailbox. The short name is therefore here left out for a reason. +# Subclasses of "mail", e.g. "MIME MHS" don't consitute a problem, as +# references are realized via long name "Mail" (with capital M). +internet 7 : : Mail + +Private 1 : enterprises : Enterprises + +# RFC 2247 +Enterprises 1466 344 : dcobject : dcObject + +# RFC 1495 +Mail 1 : mime-mhs : MIME MHS +mime-mhs 1 : mime-mhs-headings : mime-mhs-headings +mime-mhs 2 : mime-mhs-bodies : mime-mhs-bodies +mime-mhs-headings 1 : id-hex-partial-message : id-hex-partial-message +mime-mhs-headings 2 : id-hex-multipart-message : id-hex-multipart-message + +# What the hell are these OIDs, really? +!Cname rle-compression +1 1 1 1 666 1 : RLE : run length compression +!Cname zlib-compression +id-smime-alg 8 : ZLIB : zlib compression + +# AES aka Rijndael + +!Alias csor 2 16 840 1 101 3 +!Alias nistAlgorithms csor 4 +!Alias aes nistAlgorithms 1 + +aes 1 : AES-128-ECB : aes-128-ecb +aes 2 : AES-128-CBC : aes-128-cbc +!Cname aes-128-ofb128 +aes 3 : AES-128-OFB : aes-128-ofb +!Cname aes-128-cfb128 +aes 4 : AES-128-CFB : aes-128-cfb +aes 5 : id-aes128-wrap +aes 6 : id-aes128-GCM : aes-128-gcm +aes 7 : id-aes128-CCM : aes-128-ccm +aes 8 : id-aes128-wrap-pad + +aes 21 : AES-192-ECB : aes-192-ecb +aes 22 : AES-192-CBC : aes-192-cbc +!Cname aes-192-ofb128 +aes 23 : AES-192-OFB : aes-192-ofb +!Cname aes-192-cfb128 +aes 24 : AES-192-CFB : aes-192-cfb +aes 25 : id-aes192-wrap +aes 26 : id-aes192-GCM : aes-192-gcm +aes 27 : id-aes192-CCM : aes-192-ccm +aes 28 : id-aes192-wrap-pad + +aes 41 : AES-256-ECB : aes-256-ecb +aes 42 : AES-256-CBC : aes-256-cbc +!Cname aes-256-ofb128 +aes 43 : AES-256-OFB : aes-256-ofb +!Cname aes-256-cfb128 +aes 44 : AES-256-CFB : aes-256-cfb +aes 45 : id-aes256-wrap +aes 46 : id-aes256-GCM : aes-256-gcm +aes 47 : id-aes256-CCM : aes-256-ccm +aes 48 : id-aes256-wrap-pad + +# There are no OIDs for these modes... + + : AES-128-CFB1 : aes-128-cfb1 + : AES-192-CFB1 : aes-192-cfb1 + : AES-256-CFB1 : aes-256-cfb1 + : AES-128-CFB8 : aes-128-cfb8 + : AES-192-CFB8 : aes-192-cfb8 + : AES-256-CFB8 : aes-256-cfb8 + : AES-128-CTR : aes-128-ctr + : AES-192-CTR : aes-192-ctr + : AES-256-CTR : aes-256-ctr + : AES-128-XTS : aes-128-xts + : AES-256-XTS : aes-256-xts + : DES-CFB1 : des-cfb1 + : DES-CFB8 : des-cfb8 + : DES-EDE3-CFB1 : des-ede3-cfb1 + : DES-EDE3-CFB8 : des-ede3-cfb8 + +# OIDs for SHA224, SHA256, SHA385 and SHA512, according to x9.84. +!Alias nist_hashalgs nistAlgorithms 2 +nist_hashalgs 1 : SHA256 : sha256 +nist_hashalgs 2 : SHA384 : sha384 +nist_hashalgs 3 : SHA512 : sha512 +nist_hashalgs 4 : SHA224 : sha224 + +# OIDs for dsa-with-sha224 and dsa-with-sha256 +!Alias dsa_with_sha2 nistAlgorithms 3 +dsa_with_sha2 1 : dsa_with_SHA224 +dsa_with_sha2 2 : dsa_with_SHA256 + +# Hold instruction CRL entry extension +!Cname hold-instruction-code +id-ce 23 : holdInstructionCode : Hold Instruction Code +!Alias holdInstruction X9-57 2 +!Cname hold-instruction-none +holdInstruction 1 : holdInstructionNone : Hold Instruction None +!Cname hold-instruction-call-issuer +holdInstruction 2 : holdInstructionCallIssuer : Hold Instruction Call Issuer +!Cname hold-instruction-reject +holdInstruction 3 : holdInstructionReject : Hold Instruction Reject + +# OID's from ITU-T. Most of this is defined in RFC 1274. A couple of +# them are also mentioned in RFC 2247 +itu-t 9 : data +data 2342 : pss +pss 19200300 : ucl +ucl 100 : pilot +pilot 1 : : pilotAttributeType +pilot 3 : : pilotAttributeSyntax +pilot 4 : : pilotObjectClass +pilot 10 : : pilotGroups +pilotAttributeSyntax 4 : : iA5StringSyntax +pilotAttributeSyntax 5 : : caseIgnoreIA5StringSyntax +pilotObjectClass 3 : : pilotObject +pilotObjectClass 4 : : pilotPerson +pilotObjectClass 5 : account +pilotObjectClass 6 : document +pilotObjectClass 7 : room +pilotObjectClass 9 : : documentSeries +pilotObjectClass 13 : domain : Domain +pilotObjectClass 14 : : rFC822localPart +pilotObjectClass 15 : : dNSDomain +pilotObjectClass 17 : : domainRelatedObject +pilotObjectClass 18 : : friendlyCountry +pilotObjectClass 19 : : simpleSecurityObject +pilotObjectClass 20 : : pilotOrganization +pilotObjectClass 21 : : pilotDSA +pilotObjectClass 22 : : qualityLabelledData +pilotAttributeType 1 : UID : userId +pilotAttributeType 2 : : textEncodedORAddress +pilotAttributeType 3 : mail : rfc822Mailbox +pilotAttributeType 4 : info +pilotAttributeType 5 : : favouriteDrink +pilotAttributeType 6 : : roomNumber +pilotAttributeType 7 : photo +pilotAttributeType 8 : : userClass +pilotAttributeType 9 : host +pilotAttributeType 10 : manager +pilotAttributeType 11 : : documentIdentifier +pilotAttributeType 12 : : documentTitle +pilotAttributeType 13 : : documentVersion +pilotAttributeType 14 : : documentAuthor +pilotAttributeType 15 : : documentLocation +pilotAttributeType 20 : : homeTelephoneNumber +pilotAttributeType 21 : secretary +pilotAttributeType 22 : : otherMailbox +pilotAttributeType 23 : : lastModifiedTime +pilotAttributeType 24 : : lastModifiedBy +pilotAttributeType 25 : DC : domainComponent +pilotAttributeType 26 : : aRecord +pilotAttributeType 27 : : pilotAttributeType27 +pilotAttributeType 28 : : mXRecord +pilotAttributeType 29 : : nSRecord +pilotAttributeType 30 : : sOARecord +pilotAttributeType 31 : : cNAMERecord +pilotAttributeType 37 : : associatedDomain +pilotAttributeType 38 : : associatedName +pilotAttributeType 39 : : homePostalAddress +pilotAttributeType 40 : : personalTitle +pilotAttributeType 41 : : mobileTelephoneNumber +pilotAttributeType 42 : : pagerTelephoneNumber +pilotAttributeType 43 : : friendlyCountryName +# The following clashes with 2.5.4.45, so commented away +#pilotAttributeType 44 : uid : uniqueIdentifier +pilotAttributeType 45 : : organizationalStatus +pilotAttributeType 46 : : janetMailbox +pilotAttributeType 47 : : mailPreferenceOption +pilotAttributeType 48 : : buildingName +pilotAttributeType 49 : : dSAQuality +pilotAttributeType 50 : : singleLevelQuality +pilotAttributeType 51 : : subtreeMinimumQuality +pilotAttributeType 52 : : subtreeMaximumQuality +pilotAttributeType 53 : : personalSignature +pilotAttributeType 54 : : dITRedirect +pilotAttributeType 55 : audio +pilotAttributeType 56 : : documentPublisher + +international-organizations 42 : id-set : Secure Electronic Transactions + +id-set 0 : set-ctype : content types +id-set 1 : set-msgExt : message extensions +id-set 3 : set-attr +id-set 5 : set-policy +id-set 7 : set-certExt : certificate extensions +id-set 8 : set-brand + +set-ctype 0 : setct-PANData +set-ctype 1 : setct-PANToken +set-ctype 2 : setct-PANOnly +set-ctype 3 : setct-OIData +set-ctype 4 : setct-PI +set-ctype 5 : setct-PIData +set-ctype 6 : setct-PIDataUnsigned +set-ctype 7 : setct-HODInput +set-ctype 8 : setct-AuthResBaggage +set-ctype 9 : setct-AuthRevReqBaggage +set-ctype 10 : setct-AuthRevResBaggage +set-ctype 11 : setct-CapTokenSeq +set-ctype 12 : setct-PInitResData +set-ctype 13 : setct-PI-TBS +set-ctype 14 : setct-PResData +set-ctype 16 : setct-AuthReqTBS +set-ctype 17 : setct-AuthResTBS +set-ctype 18 : setct-AuthResTBSX +set-ctype 19 : setct-AuthTokenTBS +set-ctype 20 : setct-CapTokenData +set-ctype 21 : setct-CapTokenTBS +set-ctype 22 : setct-AcqCardCodeMsg +set-ctype 23 : setct-AuthRevReqTBS +set-ctype 24 : setct-AuthRevResData +set-ctype 25 : setct-AuthRevResTBS +set-ctype 26 : setct-CapReqTBS +set-ctype 27 : setct-CapReqTBSX +set-ctype 28 : setct-CapResData +set-ctype 29 : setct-CapRevReqTBS +set-ctype 30 : setct-CapRevReqTBSX +set-ctype 31 : setct-CapRevResData +set-ctype 32 : setct-CredReqTBS +set-ctype 33 : setct-CredReqTBSX +set-ctype 34 : setct-CredResData +set-ctype 35 : setct-CredRevReqTBS +set-ctype 36 : setct-CredRevReqTBSX +set-ctype 37 : setct-CredRevResData +set-ctype 38 : setct-PCertReqData +set-ctype 39 : setct-PCertResTBS +set-ctype 40 : setct-BatchAdminReqData +set-ctype 41 : setct-BatchAdminResData +set-ctype 42 : setct-CardCInitResTBS +set-ctype 43 : setct-MeAqCInitResTBS +set-ctype 44 : setct-RegFormResTBS +set-ctype 45 : setct-CertReqData +set-ctype 46 : setct-CertReqTBS +set-ctype 47 : setct-CertResData +set-ctype 48 : setct-CertInqReqTBS +set-ctype 49 : setct-ErrorTBS +set-ctype 50 : setct-PIDualSignedTBE +set-ctype 51 : setct-PIUnsignedTBE +set-ctype 52 : setct-AuthReqTBE +set-ctype 53 : setct-AuthResTBE +set-ctype 54 : setct-AuthResTBEX +set-ctype 55 : setct-AuthTokenTBE +set-ctype 56 : setct-CapTokenTBE +set-ctype 57 : setct-CapTokenTBEX +set-ctype 58 : setct-AcqCardCodeMsgTBE +set-ctype 59 : setct-AuthRevReqTBE +set-ctype 60 : setct-AuthRevResTBE +set-ctype 61 : setct-AuthRevResTBEB +set-ctype 62 : setct-CapReqTBE +set-ctype 63 : setct-CapReqTBEX +set-ctype 64 : setct-CapResTBE +set-ctype 65 : setct-CapRevReqTBE +set-ctype 66 : setct-CapRevReqTBEX +set-ctype 67 : setct-CapRevResTBE +set-ctype 68 : setct-CredReqTBE +set-ctype 69 : setct-CredReqTBEX +set-ctype 70 : setct-CredResTBE +set-ctype 71 : setct-CredRevReqTBE +set-ctype 72 : setct-CredRevReqTBEX +set-ctype 73 : setct-CredRevResTBE +set-ctype 74 : setct-BatchAdminReqTBE +set-ctype 75 : setct-BatchAdminResTBE +set-ctype 76 : setct-RegFormReqTBE +set-ctype 77 : setct-CertReqTBE +set-ctype 78 : setct-CertReqTBEX +set-ctype 79 : setct-CertResTBE +set-ctype 80 : setct-CRLNotificationTBS +set-ctype 81 : setct-CRLNotificationResTBS +set-ctype 82 : setct-BCIDistributionTBS + +set-msgExt 1 : setext-genCrypt : generic cryptogram +set-msgExt 3 : setext-miAuth : merchant initiated auth +set-msgExt 4 : setext-pinSecure +set-msgExt 5 : setext-pinAny +set-msgExt 7 : setext-track2 +set-msgExt 8 : setext-cv : additional verification + +set-policy 0 : set-policy-root + +set-certExt 0 : setCext-hashedRoot +set-certExt 1 : setCext-certType +set-certExt 2 : setCext-merchData +set-certExt 3 : setCext-cCertRequired +set-certExt 4 : setCext-tunneling +set-certExt 5 : setCext-setExt +set-certExt 6 : setCext-setQualf +set-certExt 7 : setCext-PGWYcapabilities +set-certExt 8 : setCext-TokenIdentifier +set-certExt 9 : setCext-Track2Data +set-certExt 10 : setCext-TokenType +set-certExt 11 : setCext-IssuerCapabilities + +set-attr 0 : setAttr-Cert +set-attr 1 : setAttr-PGWYcap : payment gateway capabilities +set-attr 2 : setAttr-TokenType +set-attr 3 : setAttr-IssCap : issuer capabilities + +setAttr-Cert 0 : set-rootKeyThumb +setAttr-Cert 1 : set-addPolicy + +setAttr-TokenType 1 : setAttr-Token-EMV +setAttr-TokenType 2 : setAttr-Token-B0Prime + +setAttr-IssCap 3 : setAttr-IssCap-CVM +setAttr-IssCap 4 : setAttr-IssCap-T2 +setAttr-IssCap 5 : setAttr-IssCap-Sig + +setAttr-IssCap-CVM 1 : setAttr-GenCryptgrm : generate cryptogram +setAttr-IssCap-T2 1 : setAttr-T2Enc : encrypted track 2 +setAttr-IssCap-T2 2 : setAttr-T2cleartxt : cleartext track 2 + +setAttr-IssCap-Sig 1 : setAttr-TokICCsig : ICC or token signature +setAttr-IssCap-Sig 2 : setAttr-SecDevSig : secure device signature + +set-brand 1 : set-brand-IATA-ATA +set-brand 30 : set-brand-Diners +set-brand 34 : set-brand-AmericanExpress +set-brand 35 : set-brand-JCB +set-brand 4 : set-brand-Visa +set-brand 5 : set-brand-MasterCard +set-brand 6011 : set-brand-Novus + +rsadsi 3 10 : DES-CDMF : des-cdmf +rsadsi 1 1 6 : rsaOAEPEncryptionSET + + : Oakley-EC2N-3 : ipsec3 + : Oakley-EC2N-4 : ipsec4 + +iso 0 10118 3 0 55 : whirlpool + +# GOST OIDs + +member-body 643 2 2 : cryptopro +member-body 643 2 9 : cryptocom + +cryptopro 3 : id-GostR3411-94-with-GostR3410-2001 : GOST R 34.11-94 with GOST R 34.10-2001 +cryptopro 4 : id-GostR3411-94-with-GostR3410-94 : GOST R 34.11-94 with GOST R 34.10-94 +!Cname id-GostR3411-94 +cryptopro 9 : md_gost94 : GOST R 34.11-94 +cryptopro 10 : id-HMACGostR3411-94 : HMAC GOST 34.11-94 +!Cname id-GostR3410-2001 +cryptopro 19 : gost2001 : GOST R 34.10-2001 +!Cname id-GostR3410-94 +cryptopro 20 : gost94 : GOST R 34.10-94 +!Cname id-Gost28147-89 +cryptopro 21 : gost89 : GOST 28147-89 + : gost89-cnt +!Cname id-Gost28147-89-MAC +cryptopro 22 : gost-mac : GOST 28147-89 MAC +!Cname id-GostR3411-94-prf +cryptopro 23 : prf-gostr3411-94 : GOST R 34.11-94 PRF +cryptopro 98 : id-GostR3410-2001DH : GOST R 34.10-2001 DH +cryptopro 99 : id-GostR3410-94DH : GOST R 34.10-94 DH + +cryptopro 14 1 : id-Gost28147-89-CryptoPro-KeyMeshing +cryptopro 14 0 : id-Gost28147-89-None-KeyMeshing + +# GOST parameter set OIDs + +cryptopro 30 0 : id-GostR3411-94-TestParamSet +cryptopro 30 1 : id-GostR3411-94-CryptoProParamSet + +cryptopro 31 0 : id-Gost28147-89-TestParamSet +cryptopro 31 1 : id-Gost28147-89-CryptoPro-A-ParamSet +cryptopro 31 2 : id-Gost28147-89-CryptoPro-B-ParamSet +cryptopro 31 3 : id-Gost28147-89-CryptoPro-C-ParamSet +cryptopro 31 4 : id-Gost28147-89-CryptoPro-D-ParamSet +cryptopro 31 5 : id-Gost28147-89-CryptoPro-Oscar-1-1-ParamSet +cryptopro 31 6 : id-Gost28147-89-CryptoPro-Oscar-1-0-ParamSet +cryptopro 31 7 : id-Gost28147-89-CryptoPro-RIC-1-ParamSet + +cryptopro 32 0 : id-GostR3410-94-TestParamSet +cryptopro 32 2 : id-GostR3410-94-CryptoPro-A-ParamSet +cryptopro 32 3 : id-GostR3410-94-CryptoPro-B-ParamSet +cryptopro 32 4 : id-GostR3410-94-CryptoPro-C-ParamSet +cryptopro 32 5 : id-GostR3410-94-CryptoPro-D-ParamSet + +cryptopro 33 1 : id-GostR3410-94-CryptoPro-XchA-ParamSet +cryptopro 33 2 : id-GostR3410-94-CryptoPro-XchB-ParamSet +cryptopro 33 3 : id-GostR3410-94-CryptoPro-XchC-ParamSet + +cryptopro 35 0 : id-GostR3410-2001-TestParamSet +cryptopro 35 1 : id-GostR3410-2001-CryptoPro-A-ParamSet +cryptopro 35 2 : id-GostR3410-2001-CryptoPro-B-ParamSet +cryptopro 35 3 : id-GostR3410-2001-CryptoPro-C-ParamSet + +cryptopro 36 0 : id-GostR3410-2001-CryptoPro-XchA-ParamSet +cryptopro 36 1 : id-GostR3410-2001-CryptoPro-XchB-ParamSet + +id-GostR3410-94 1 : id-GostR3410-94-a +id-GostR3410-94 2 : id-GostR3410-94-aBis +id-GostR3410-94 3 : id-GostR3410-94-b +id-GostR3410-94 4 : id-GostR3410-94-bBis + +# Cryptocom LTD GOST OIDs + +cryptocom 1 6 1 : id-Gost28147-89-cc : GOST 28147-89 Cryptocom ParamSet +!Cname id-GostR3410-94-cc +cryptocom 1 5 3 : gost94cc : GOST 34.10-94 Cryptocom +!Cname id-GostR3410-2001-cc +cryptocom 1 5 4 : gost2001cc : GOST 34.10-2001 Cryptocom + +cryptocom 1 3 3 : id-GostR3411-94-with-GostR3410-94-cc : GOST R 34.11-94 with GOST R 34.10-94 Cryptocom +cryptocom 1 3 4 : id-GostR3411-94-with-GostR3410-2001-cc : GOST R 34.11-94 with GOST R 34.10-2001 Cryptocom + +cryptocom 1 8 1 : id-GostR3410-2001-ParamSet-cc : GOST R 3410-2001 Parameter Set Cryptocom + +# Definitions for Camellia cipher - CBC MODE + +1 2 392 200011 61 1 1 1 2 : CAMELLIA-128-CBC : camellia-128-cbc +1 2 392 200011 61 1 1 1 3 : CAMELLIA-192-CBC : camellia-192-cbc +1 2 392 200011 61 1 1 1 4 : CAMELLIA-256-CBC : camellia-256-cbc +1 2 392 200011 61 1 1 3 2 : id-camellia128-wrap +1 2 392 200011 61 1 1 3 3 : id-camellia192-wrap +1 2 392 200011 61 1 1 3 4 : id-camellia256-wrap + +# Definitions for Camellia cipher - ECB, CFB, OFB MODE + +!Alias ntt-ds 0 3 4401 5 +!Alias camellia ntt-ds 3 1 9 + +camellia 1 : CAMELLIA-128-ECB : camellia-128-ecb +!Cname camellia-128-ofb128 +camellia 3 : CAMELLIA-128-OFB : camellia-128-ofb +!Cname camellia-128-cfb128 +camellia 4 : CAMELLIA-128-CFB : camellia-128-cfb + +camellia 21 : CAMELLIA-192-ECB : camellia-192-ecb +!Cname camellia-192-ofb128 +camellia 23 : CAMELLIA-192-OFB : camellia-192-ofb +!Cname camellia-192-cfb128 +camellia 24 : CAMELLIA-192-CFB : camellia-192-cfb + +camellia 41 : CAMELLIA-256-ECB : camellia-256-ecb +!Cname camellia-256-ofb128 +camellia 43 : CAMELLIA-256-OFB : camellia-256-ofb +!Cname camellia-256-cfb128 +camellia 44 : CAMELLIA-256-CFB : camellia-256-cfb + +# There are no OIDs for these modes... + + : CAMELLIA-128-CFB1 : camellia-128-cfb1 + : CAMELLIA-192-CFB1 : camellia-192-cfb1 + : CAMELLIA-256-CFB1 : camellia-256-cfb1 + : CAMELLIA-128-CFB8 : camellia-128-cfb8 + : CAMELLIA-192-CFB8 : camellia-192-cfb8 + : CAMELLIA-256-CFB8 : camellia-256-cfb8 + +# Definitions for SEED cipher - ECB, CBC, OFB mode + +member-body 410 200004 : KISA : kisa +kisa 1 3 : SEED-ECB : seed-ecb +kisa 1 4 : SEED-CBC : seed-cbc +!Cname seed-cfb128 +kisa 1 5 : SEED-CFB : seed-cfb +!Cname seed-ofb128 +kisa 1 6 : SEED-OFB : seed-ofb + +# There is no OID that just denotes "HMAC" oddly enough... + + : HMAC : hmac +# Nor CMAC either + : CMAC : cmac + +# Synthetic composite ciphersuites + : RC4-HMAC-MD5 : rc4-hmac-md5 + : AES-128-CBC-HMAC-SHA1 : aes-128-cbc-hmac-sha1 + : AES-192-CBC-HMAC-SHA1 : aes-192-cbc-hmac-sha1 + : AES-256-CBC-HMAC-SHA1 : aes-256-cbc-hmac-sha1 diff --git a/libs/openssl/crypto/objects/objxref.pl b/libs/openssl/crypto/objects/objxref.pl new file mode 100644 index 00000000..35c06514 --- /dev/null +++ b/libs/openssl/crypto/objects/objxref.pl @@ -0,0 +1,115 @@ +#!/usr/local/bin/perl + +use strict; + +my %xref_tbl; +my %oid_tbl; + +my ($mac_file, $xref_file) = @ARGV; + +open(IN, $mac_file) || die "Can't open $mac_file"; + +# Read in OID nid values for a lookup table. + +while () + { + chomp; + my ($name, $num) = /^(\S+)\s+(\S+)$/; + $oid_tbl{$name} = $num; + } +close IN; + +open(IN, $xref_file) || die "Can't open $xref_file"; + +my $ln = 1; + +while () + { + chomp; + s/#.*$//; + next if (/^\S*$/); + my ($xr, $p1, $p2) = /^(\S+)\s+(\S+)\s+(\S+)/; + check_oid($xr); + check_oid($p1); + check_oid($p2); + $xref_tbl{$xr} = [$p1, $p2, $ln]; + } + +my @xrkeys = keys %xref_tbl; + +my @srt1 = sort { $oid_tbl{$a} <=> $oid_tbl{$b}} @xrkeys; + +for(my $i = 0; $i <= $#srt1; $i++) + { + $xref_tbl{$srt1[$i]}[2] = $i; + } + +my @srt2 = sort + { + my$ap1 = $oid_tbl{$xref_tbl{$a}[0]}; + my$bp1 = $oid_tbl{$xref_tbl{$b}[0]}; + return $ap1 - $bp1 if ($ap1 != $bp1); + my$ap2 = $oid_tbl{$xref_tbl{$a}[1]}; + my$bp2 = $oid_tbl{$xref_tbl{$b}[1]}; + + return $ap2 - $bp2; + } @xrkeys; + +my $pname = $0; + +$pname =~ s|^.[^/]/||; + +print < for the OpenSSL + * project. + */ + +/* + * History: This file was transfered to Richard Levitte from CertCo by Kathy + * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a + * patch kit. + */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_OCSP_H +# define HEADER_OCSP_H + +# include +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Various flags and values */ + +# define OCSP_DEFAULT_NONCE_LENGTH 16 + +# define OCSP_NOCERTS 0x1 +# define OCSP_NOINTERN 0x2 +# define OCSP_NOSIGS 0x4 +# define OCSP_NOCHAIN 0x8 +# define OCSP_NOVERIFY 0x10 +# define OCSP_NOEXPLICIT 0x20 +# define OCSP_NOCASIGN 0x40 +# define OCSP_NODELEGATED 0x80 +# define OCSP_NOCHECKS 0x100 +# define OCSP_TRUSTOTHER 0x200 +# define OCSP_RESPID_KEY 0x400 +# define OCSP_NOTIME 0x800 + +/*- CertID ::= SEQUENCE { + * hashAlgorithm AlgorithmIdentifier, + * issuerNameHash OCTET STRING, -- Hash of Issuer's DN + * issuerKeyHash OCTET STRING, -- Hash of Issuers public key (excluding the tag & length fields) + * serialNumber CertificateSerialNumber } + */ +typedef struct ocsp_cert_id_st { + X509_ALGOR *hashAlgorithm; + ASN1_OCTET_STRING *issuerNameHash; + ASN1_OCTET_STRING *issuerKeyHash; + ASN1_INTEGER *serialNumber; +} OCSP_CERTID; + +DECLARE_STACK_OF(OCSP_CERTID) + +/*- Request ::= SEQUENCE { + * reqCert CertID, + * singleRequestExtensions [0] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_one_request_st { + OCSP_CERTID *reqCert; + STACK_OF(X509_EXTENSION) *singleRequestExtensions; +} OCSP_ONEREQ; + +DECLARE_STACK_OF(OCSP_ONEREQ) +DECLARE_ASN1_SET_OF(OCSP_ONEREQ) + +/*- TBSRequest ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * requestorName [1] EXPLICIT GeneralName OPTIONAL, + * requestList SEQUENCE OF Request, + * requestExtensions [2] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_req_info_st { + ASN1_INTEGER *version; + GENERAL_NAME *requestorName; + STACK_OF(OCSP_ONEREQ) *requestList; + STACK_OF(X509_EXTENSION) *requestExtensions; +} OCSP_REQINFO; + +/*- Signature ::= SEQUENCE { + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } + */ +typedef struct ocsp_signature_st { + X509_ALGOR *signatureAlgorithm; + ASN1_BIT_STRING *signature; + STACK_OF(X509) *certs; +} OCSP_SIGNATURE; + +/*- OCSPRequest ::= SEQUENCE { + * tbsRequest TBSRequest, + * optionalSignature [0] EXPLICIT Signature OPTIONAL } + */ +typedef struct ocsp_request_st { + OCSP_REQINFO *tbsRequest; + OCSP_SIGNATURE *optionalSignature; /* OPTIONAL */ +} OCSP_REQUEST; + +/*- OCSPResponseStatus ::= ENUMERATED { + * successful (0), --Response has valid confirmations + * malformedRequest (1), --Illegal confirmation request + * internalError (2), --Internal error in issuer + * tryLater (3), --Try again later + * --(4) is not used + * sigRequired (5), --Must sign the request + * unauthorized (6) --Request unauthorized + * } + */ +# define OCSP_RESPONSE_STATUS_SUCCESSFUL 0 +# define OCSP_RESPONSE_STATUS_MALFORMEDREQUEST 1 +# define OCSP_RESPONSE_STATUS_INTERNALERROR 2 +# define OCSP_RESPONSE_STATUS_TRYLATER 3 +# define OCSP_RESPONSE_STATUS_SIGREQUIRED 5 +# define OCSP_RESPONSE_STATUS_UNAUTHORIZED 6 + +/*- ResponseBytes ::= SEQUENCE { + * responseType OBJECT IDENTIFIER, + * response OCTET STRING } + */ +typedef struct ocsp_resp_bytes_st { + ASN1_OBJECT *responseType; + ASN1_OCTET_STRING *response; +} OCSP_RESPBYTES; + +/*- OCSPResponse ::= SEQUENCE { + * responseStatus OCSPResponseStatus, + * responseBytes [0] EXPLICIT ResponseBytes OPTIONAL } + */ +struct ocsp_response_st { + ASN1_ENUMERATED *responseStatus; + OCSP_RESPBYTES *responseBytes; +}; + +/*- ResponderID ::= CHOICE { + * byName [1] Name, + * byKey [2] KeyHash } + */ +# define V_OCSP_RESPID_NAME 0 +# define V_OCSP_RESPID_KEY 1 +struct ocsp_responder_id_st { + int type; + union { + X509_NAME *byName; + ASN1_OCTET_STRING *byKey; + } value; +}; + +DECLARE_STACK_OF(OCSP_RESPID) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) + +/*- KeyHash ::= OCTET STRING --SHA-1 hash of responder's public key + * --(excluding the tag and length fields) + */ + +/*- RevokedInfo ::= SEQUENCE { + * revocationTime GeneralizedTime, + * revocationReason [0] EXPLICIT CRLReason OPTIONAL } + */ +typedef struct ocsp_revoked_info_st { + ASN1_GENERALIZEDTIME *revocationTime; + ASN1_ENUMERATED *revocationReason; +} OCSP_REVOKEDINFO; + +/*- CertStatus ::= CHOICE { + * good [0] IMPLICIT NULL, + * revoked [1] IMPLICIT RevokedInfo, + * unknown [2] IMPLICIT UnknownInfo } + */ +# define V_OCSP_CERTSTATUS_GOOD 0 +# define V_OCSP_CERTSTATUS_REVOKED 1 +# define V_OCSP_CERTSTATUS_UNKNOWN 2 +typedef struct ocsp_cert_status_st { + int type; + union { + ASN1_NULL *good; + OCSP_REVOKEDINFO *revoked; + ASN1_NULL *unknown; + } value; +} OCSP_CERTSTATUS; + +/*- SingleResponse ::= SEQUENCE { + * certID CertID, + * certStatus CertStatus, + * thisUpdate GeneralizedTime, + * nextUpdate [0] EXPLICIT GeneralizedTime OPTIONAL, + * singleExtensions [1] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_single_response_st { + OCSP_CERTID *certId; + OCSP_CERTSTATUS *certStatus; + ASN1_GENERALIZEDTIME *thisUpdate; + ASN1_GENERALIZEDTIME *nextUpdate; + STACK_OF(X509_EXTENSION) *singleExtensions; +} OCSP_SINGLERESP; + +DECLARE_STACK_OF(OCSP_SINGLERESP) +DECLARE_ASN1_SET_OF(OCSP_SINGLERESP) + +/*- ResponseData ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * responderID ResponderID, + * producedAt GeneralizedTime, + * responses SEQUENCE OF SingleResponse, + * responseExtensions [1] EXPLICIT Extensions OPTIONAL } + */ +typedef struct ocsp_response_data_st { + ASN1_INTEGER *version; + OCSP_RESPID *responderId; + ASN1_GENERALIZEDTIME *producedAt; + STACK_OF(OCSP_SINGLERESP) *responses; + STACK_OF(X509_EXTENSION) *responseExtensions; +} OCSP_RESPDATA; + +/*- BasicOCSPResponse ::= SEQUENCE { + * tbsResponseData ResponseData, + * signatureAlgorithm AlgorithmIdentifier, + * signature BIT STRING, + * certs [0] EXPLICIT SEQUENCE OF Certificate OPTIONAL } + */ + /* + * Note 1: The value for "signature" is specified in the OCSP rfc2560 as + * follows: "The value for the signature SHALL be computed on the hash of + * the DER encoding ResponseData." This means that you must hash the + * DER-encoded tbsResponseData, and then run it through a crypto-signing + * function, which will (at least w/RSA) do a hash-'n'-private-encrypt + * operation. This seems a bit odd, but that's the spec. Also note that + * the data structures do not leave anywhere to independently specify the + * algorithm used for the initial hash. So, we look at the + * signature-specification algorithm, and try to do something intelligent. + * -- Kathy Weinhold, CertCo + */ + /* + * Note 2: It seems that the mentioned passage from RFC 2560 (section + * 4.2.1) is open for interpretation. I've done tests against another + * responder, and found that it doesn't do the double hashing that the RFC + * seems to say one should. Therefore, all relevant functions take a flag + * saying which variant should be used. -- Richard Levitte, OpenSSL team + * and CeloCom + */ +typedef struct ocsp_basic_response_st { + OCSP_RESPDATA *tbsResponseData; + X509_ALGOR *signatureAlgorithm; + ASN1_BIT_STRING *signature; + STACK_OF(X509) *certs; +} OCSP_BASICRESP; + +/*- + * CRLReason ::= ENUMERATED { + * unspecified (0), + * keyCompromise (1), + * cACompromise (2), + * affiliationChanged (3), + * superseded (4), + * cessationOfOperation (5), + * certificateHold (6), + * removeFromCRL (8) } + */ +# define OCSP_REVOKED_STATUS_NOSTATUS -1 +# define OCSP_REVOKED_STATUS_UNSPECIFIED 0 +# define OCSP_REVOKED_STATUS_KEYCOMPROMISE 1 +# define OCSP_REVOKED_STATUS_CACOMPROMISE 2 +# define OCSP_REVOKED_STATUS_AFFILIATIONCHANGED 3 +# define OCSP_REVOKED_STATUS_SUPERSEDED 4 +# define OCSP_REVOKED_STATUS_CESSATIONOFOPERATION 5 +# define OCSP_REVOKED_STATUS_CERTIFICATEHOLD 6 +# define OCSP_REVOKED_STATUS_REMOVEFROMCRL 8 + +/*- + * CrlID ::= SEQUENCE { + * crlUrl [0] EXPLICIT IA5String OPTIONAL, + * crlNum [1] EXPLICIT INTEGER OPTIONAL, + * crlTime [2] EXPLICIT GeneralizedTime OPTIONAL } + */ +typedef struct ocsp_crl_id_st { + ASN1_IA5STRING *crlUrl; + ASN1_INTEGER *crlNum; + ASN1_GENERALIZEDTIME *crlTime; +} OCSP_CRLID; + +/*- + * ServiceLocator ::= SEQUENCE { + * issuer Name, + * locator AuthorityInfoAccessSyntax OPTIONAL } + */ +typedef struct ocsp_service_locator_st { + X509_NAME *issuer; + STACK_OF(ACCESS_DESCRIPTION) *locator; +} OCSP_SERVICELOC; + +# define PEM_STRING_OCSP_REQUEST "OCSP REQUEST" +# define PEM_STRING_OCSP_RESPONSE "OCSP RESPONSE" + +# define d2i_OCSP_REQUEST_bio(bp,p) ASN1_d2i_bio_of(OCSP_REQUEST,OCSP_REQUEST_new,d2i_OCSP_REQUEST,bp,p) + +# define d2i_OCSP_RESPONSE_bio(bp,p) ASN1_d2i_bio_of(OCSP_RESPONSE,OCSP_RESPONSE_new,d2i_OCSP_RESPONSE,bp,p) + +# define PEM_read_bio_OCSP_REQUEST(bp,x,cb) (OCSP_REQUEST *)PEM_ASN1_read_bio( \ + (char *(*)())d2i_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,bp,(char **)x,cb,NULL) + +# define PEM_read_bio_OCSP_RESPONSE(bp,x,cb)(OCSP_RESPONSE *)PEM_ASN1_read_bio(\ + (char *(*)())d2i_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,bp,(char **)x,cb,NULL) + +# define PEM_write_bio_OCSP_REQUEST(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_REQUEST,PEM_STRING_OCSP_REQUEST,\ + bp,(char *)o, NULL,NULL,0,NULL,NULL) + +# define PEM_write_bio_OCSP_RESPONSE(bp,o) \ + PEM_ASN1_write_bio((int (*)())i2d_OCSP_RESPONSE,PEM_STRING_OCSP_RESPONSE,\ + bp,(char *)o, NULL,NULL,0,NULL,NULL) + +# define i2d_OCSP_RESPONSE_bio(bp,o) ASN1_i2d_bio_of(OCSP_RESPONSE,i2d_OCSP_RESPONSE,bp,o) + +# define i2d_OCSP_REQUEST_bio(bp,o) ASN1_i2d_bio_of(OCSP_REQUEST,i2d_OCSP_REQUEST,bp,o) + +# define OCSP_REQUEST_sign(o,pkey,md) \ + ASN1_item_sign(ASN1_ITEM_rptr(OCSP_REQINFO),\ + o->optionalSignature->signatureAlgorithm,NULL,\ + o->optionalSignature->signature,o->tbsRequest,pkey,md) + +# define OCSP_BASICRESP_sign(o,pkey,md,d) \ + ASN1_item_sign(ASN1_ITEM_rptr(OCSP_RESPDATA),o->signatureAlgorithm,NULL,\ + o->signature,o->tbsResponseData,pkey,md) + +# define OCSP_REQUEST_verify(a,r) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_REQINFO),\ + a->optionalSignature->signatureAlgorithm,\ + a->optionalSignature->signature,a->tbsRequest,r) + +# define OCSP_BASICRESP_verify(a,r,d) ASN1_item_verify(ASN1_ITEM_rptr(OCSP_RESPDATA),\ + a->signatureAlgorithm,a->signature,a->tbsResponseData,r) + +# define ASN1_BIT_STRING_digest(data,type,md,len) \ + ASN1_item_digest(ASN1_ITEM_rptr(ASN1_BIT_STRING),type,data,md,len) + +# define OCSP_CERTSTATUS_dup(cs)\ + (OCSP_CERTSTATUS*)ASN1_dup((int(*)())i2d_OCSP_CERTSTATUS,\ + (char *(*)())d2i_OCSP_CERTSTATUS,(char *)(cs)) + +OCSP_CERTID *OCSP_CERTID_dup(OCSP_CERTID *id); + +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req); +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req, + int maxline); +int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx); +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx); +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req); +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, + const char *name, const char *value); + +OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer); + +OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, + X509_NAME *issuerName, + ASN1_BIT_STRING *issuerKey, + ASN1_INTEGER *serialNumber); + +OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid); + +int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len); +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len); +int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs); +int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req); + +int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm); +int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert); + +int OCSP_request_sign(OCSP_REQUEST *req, + X509 *signer, + EVP_PKEY *key, + const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); + +int OCSP_response_status(OCSP_RESPONSE *resp); +OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp); + +int OCSP_resp_count(OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx); +int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last); +int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, + int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd); +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, + ASN1_GENERALIZEDTIME *nextupd, long sec, long maxsec); + +int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, + X509_STORE *store, unsigned long flags); + +int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, + int *pssl); + +int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b); +int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b); + +int OCSP_request_onereq_count(OCSP_REQUEST *req); +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i); +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one); +int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, + ASN1_OCTET_STRING **pikeyHash, + ASN1_INTEGER **pserial, OCSP_CERTID *cid); +int OCSP_request_is_signed(OCSP_REQUEST *req); +OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs); +OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, + OCSP_CERTID *cid, + int status, int reason, + ASN1_TIME *revtime, + ASN1_TIME *thisupd, + ASN1_TIME *nextupd); +int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert); +int OCSP_basic_sign(OCSP_BASICRESP *brsp, + X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags); + +X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim); + +X509_EXTENSION *OCSP_accept_responses_new(char **oids); + +X509_EXTENSION *OCSP_archive_cutoff_new(char *tim); + +X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, char **urls); + +int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x); +int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos); +int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, + int lastpos); +int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos); +X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc); +X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc); +void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, + int *idx); +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc); + +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x); +int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos); +int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos); +int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos); +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc); +X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc); +void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx); +int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, + unsigned long flags); +int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc); + +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x); +int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos); +int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, + int lastpos); +int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc); +X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc); +void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, + int *idx); +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc); + +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x); +int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos); +int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, + int lastpos); +int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, + int lastpos); +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc); +X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc); +void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, + int *idx); +int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, + int crit, unsigned long flags); +int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc); + +DECLARE_ASN1_FUNCTIONS(OCSP_SINGLERESP) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTSTATUS) +DECLARE_ASN1_FUNCTIONS(OCSP_REVOKEDINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_BASICRESP) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPDATA) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPID) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPONSE) +DECLARE_ASN1_FUNCTIONS(OCSP_RESPBYTES) +DECLARE_ASN1_FUNCTIONS(OCSP_ONEREQ) +DECLARE_ASN1_FUNCTIONS(OCSP_CERTID) +DECLARE_ASN1_FUNCTIONS(OCSP_REQUEST) +DECLARE_ASN1_FUNCTIONS(OCSP_SIGNATURE) +DECLARE_ASN1_FUNCTIONS(OCSP_REQINFO) +DECLARE_ASN1_FUNCTIONS(OCSP_CRLID) +DECLARE_ASN1_FUNCTIONS(OCSP_SERVICELOC) + +const char *OCSP_response_status_str(long s); +const char *OCSP_cert_status_str(long s); +const char *OCSP_crl_reason_str(long s); + +int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *a, unsigned long flags); +int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags); + +int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_OCSP_strings(void); + +/* Error codes for the OCSP functions. */ + +/* Function codes. */ +# define OCSP_F_ASN1_STRING_ENCODE 100 +# define OCSP_F_D2I_OCSP_NONCE 102 +# define OCSP_F_OCSP_BASIC_ADD1_STATUS 103 +# define OCSP_F_OCSP_BASIC_SIGN 104 +# define OCSP_F_OCSP_BASIC_VERIFY 105 +# define OCSP_F_OCSP_CERT_ID_NEW 101 +# define OCSP_F_OCSP_CHECK_DELEGATED 106 +# define OCSP_F_OCSP_CHECK_IDS 107 +# define OCSP_F_OCSP_CHECK_ISSUER 108 +# define OCSP_F_OCSP_CHECK_VALIDITY 115 +# define OCSP_F_OCSP_MATCH_ISSUERID 109 +# define OCSP_F_OCSP_PARSE_URL 114 +# define OCSP_F_OCSP_REQUEST_SIGN 110 +# define OCSP_F_OCSP_REQUEST_VERIFY 116 +# define OCSP_F_OCSP_RESPONSE_GET1_BASIC 111 +# define OCSP_F_OCSP_SENDREQ_BIO 112 +# define OCSP_F_OCSP_SENDREQ_NBIO 117 +# define OCSP_F_PARSE_HTTP_LINE1 118 +# define OCSP_F_REQUEST_VERIFY 113 + +/* Reason codes. */ +# define OCSP_R_BAD_DATA 100 +# define OCSP_R_CERTIFICATE_VERIFY_ERROR 101 +# define OCSP_R_DIGEST_ERR 102 +# define OCSP_R_ERROR_IN_NEXTUPDATE_FIELD 122 +# define OCSP_R_ERROR_IN_THISUPDATE_FIELD 123 +# define OCSP_R_ERROR_PARSING_URL 121 +# define OCSP_R_MISSING_OCSPSIGNING_USAGE 103 +# define OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE 124 +# define OCSP_R_NOT_BASIC_RESPONSE 104 +# define OCSP_R_NO_CERTIFICATES_IN_CHAIN 105 +# define OCSP_R_NO_CONTENT 106 +# define OCSP_R_NO_PUBLIC_KEY 107 +# define OCSP_R_NO_RESPONSE_DATA 108 +# define OCSP_R_NO_REVOKED_TIME 109 +# define OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 110 +# define OCSP_R_REQUEST_NOT_SIGNED 128 +# define OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA 111 +# define OCSP_R_ROOT_CA_NOT_TRUSTED 112 +# define OCSP_R_SERVER_READ_ERROR 113 +# define OCSP_R_SERVER_RESPONSE_ERROR 114 +# define OCSP_R_SERVER_RESPONSE_PARSE_ERROR 115 +# define OCSP_R_SERVER_WRITE_ERROR 116 +# define OCSP_R_SIGNATURE_FAILURE 117 +# define OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND 118 +# define OCSP_R_STATUS_EXPIRED 125 +# define OCSP_R_STATUS_NOT_YET_VALID 126 +# define OCSP_R_STATUS_TOO_OLD 127 +# define OCSP_R_UNKNOWN_MESSAGE_DIGEST 119 +# define OCSP_R_UNKNOWN_NID 120 +# define OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE 129 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/ocsp/ocsp_asn.c b/libs/openssl/crypto/ocsp/ocsp_asn.c new file mode 100644 index 00000000..e2e52e77 --- /dev/null +++ b/libs/openssl/crypto/ocsp/ocsp_asn.c @@ -0,0 +1,183 @@ +/* ocsp_asn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include +#include +#include + +ASN1_SEQUENCE(OCSP_SIGNATURE) = { + ASN1_SIMPLE(OCSP_SIGNATURE, signatureAlgorithm, X509_ALGOR), + ASN1_SIMPLE(OCSP_SIGNATURE, signature, ASN1_BIT_STRING), + ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SIGNATURE, certs, X509, 0) +} ASN1_SEQUENCE_END(OCSP_SIGNATURE) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_SIGNATURE) + +ASN1_SEQUENCE(OCSP_CERTID) = { + ASN1_SIMPLE(OCSP_CERTID, hashAlgorithm, X509_ALGOR), + ASN1_SIMPLE(OCSP_CERTID, issuerNameHash, ASN1_OCTET_STRING), + ASN1_SIMPLE(OCSP_CERTID, issuerKeyHash, ASN1_OCTET_STRING), + ASN1_SIMPLE(OCSP_CERTID, serialNumber, ASN1_INTEGER) +} ASN1_SEQUENCE_END(OCSP_CERTID) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTID) + +ASN1_SEQUENCE(OCSP_ONEREQ) = { + ASN1_SIMPLE(OCSP_ONEREQ, reqCert, OCSP_CERTID), + ASN1_EXP_SEQUENCE_OF_OPT(OCSP_ONEREQ, singleRequestExtensions, X509_EXTENSION, 0) +} ASN1_SEQUENCE_END(OCSP_ONEREQ) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_ONEREQ) + +ASN1_SEQUENCE(OCSP_REQINFO) = { + ASN1_EXP_OPT(OCSP_REQINFO, version, ASN1_INTEGER, 0), + ASN1_EXP_OPT(OCSP_REQINFO, requestorName, GENERAL_NAME, 1), + ASN1_SEQUENCE_OF(OCSP_REQINFO, requestList, OCSP_ONEREQ), + ASN1_EXP_SEQUENCE_OF_OPT(OCSP_REQINFO, requestExtensions, X509_EXTENSION, 2) +} ASN1_SEQUENCE_END(OCSP_REQINFO) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQINFO) + +ASN1_SEQUENCE(OCSP_REQUEST) = { + ASN1_SIMPLE(OCSP_REQUEST, tbsRequest, OCSP_REQINFO), + ASN1_EXP_OPT(OCSP_REQUEST, optionalSignature, OCSP_SIGNATURE, 0) +} ASN1_SEQUENCE_END(OCSP_REQUEST) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_REQUEST) + +/* OCSP_RESPONSE templates */ + +ASN1_SEQUENCE(OCSP_RESPBYTES) = { + ASN1_SIMPLE(OCSP_RESPBYTES, responseType, ASN1_OBJECT), + ASN1_SIMPLE(OCSP_RESPBYTES, response, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(OCSP_RESPBYTES) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPBYTES) + +ASN1_SEQUENCE(OCSP_RESPONSE) = { + ASN1_SIMPLE(OCSP_RESPONSE, responseStatus, ASN1_ENUMERATED), + ASN1_EXP_OPT(OCSP_RESPONSE, responseBytes, OCSP_RESPBYTES, 0) +} ASN1_SEQUENCE_END(OCSP_RESPONSE) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPONSE) + +ASN1_CHOICE(OCSP_RESPID) = { + ASN1_EXP(OCSP_RESPID, value.byName, X509_NAME, 1), + ASN1_EXP(OCSP_RESPID, value.byKey, ASN1_OCTET_STRING, 2) +} ASN1_CHOICE_END(OCSP_RESPID) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPID) + +ASN1_SEQUENCE(OCSP_REVOKEDINFO) = { + ASN1_SIMPLE(OCSP_REVOKEDINFO, revocationTime, ASN1_GENERALIZEDTIME), + ASN1_EXP_OPT(OCSP_REVOKEDINFO, revocationReason, ASN1_ENUMERATED, 0) +} ASN1_SEQUENCE_END(OCSP_REVOKEDINFO) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_REVOKEDINFO) + +ASN1_CHOICE(OCSP_CERTSTATUS) = { + ASN1_IMP(OCSP_CERTSTATUS, value.good, ASN1_NULL, 0), + ASN1_IMP(OCSP_CERTSTATUS, value.revoked, OCSP_REVOKEDINFO, 1), + ASN1_IMP(OCSP_CERTSTATUS, value.unknown, ASN1_NULL, 2) +} ASN1_CHOICE_END(OCSP_CERTSTATUS) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_CERTSTATUS) + +ASN1_SEQUENCE(OCSP_SINGLERESP) = { + ASN1_SIMPLE(OCSP_SINGLERESP, certId, OCSP_CERTID), + ASN1_SIMPLE(OCSP_SINGLERESP, certStatus, OCSP_CERTSTATUS), + ASN1_SIMPLE(OCSP_SINGLERESP, thisUpdate, ASN1_GENERALIZEDTIME), + ASN1_EXP_OPT(OCSP_SINGLERESP, nextUpdate, ASN1_GENERALIZEDTIME, 0), + ASN1_EXP_SEQUENCE_OF_OPT(OCSP_SINGLERESP, singleExtensions, X509_EXTENSION, 1) +} ASN1_SEQUENCE_END(OCSP_SINGLERESP) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_SINGLERESP) + +ASN1_SEQUENCE(OCSP_RESPDATA) = { + ASN1_EXP_OPT(OCSP_RESPDATA, version, ASN1_INTEGER, 0), + ASN1_SIMPLE(OCSP_RESPDATA, responderId, OCSP_RESPID), + ASN1_SIMPLE(OCSP_RESPDATA, producedAt, ASN1_GENERALIZEDTIME), + ASN1_SEQUENCE_OF(OCSP_RESPDATA, responses, OCSP_SINGLERESP), + ASN1_EXP_SEQUENCE_OF_OPT(OCSP_RESPDATA, responseExtensions, X509_EXTENSION, 1) +} ASN1_SEQUENCE_END(OCSP_RESPDATA) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_RESPDATA) + +ASN1_SEQUENCE(OCSP_BASICRESP) = { + ASN1_SIMPLE(OCSP_BASICRESP, tbsResponseData, OCSP_RESPDATA), + ASN1_SIMPLE(OCSP_BASICRESP, signatureAlgorithm, X509_ALGOR), + ASN1_SIMPLE(OCSP_BASICRESP, signature, ASN1_BIT_STRING), + ASN1_EXP_SEQUENCE_OF_OPT(OCSP_BASICRESP, certs, X509, 0) +} ASN1_SEQUENCE_END(OCSP_BASICRESP) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_BASICRESP) + +ASN1_SEQUENCE(OCSP_CRLID) = { + ASN1_EXP_OPT(OCSP_CRLID, crlUrl, ASN1_IA5STRING, 0), + ASN1_EXP_OPT(OCSP_CRLID, crlNum, ASN1_INTEGER, 1), + ASN1_EXP_OPT(OCSP_CRLID, crlTime, ASN1_GENERALIZEDTIME, 2) +} ASN1_SEQUENCE_END(OCSP_CRLID) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_CRLID) + +ASN1_SEQUENCE(OCSP_SERVICELOC) = { + ASN1_SIMPLE(OCSP_SERVICELOC, issuer, X509_NAME), + ASN1_SEQUENCE_OF_OPT(OCSP_SERVICELOC, locator, ACCESS_DESCRIPTION) +} ASN1_SEQUENCE_END(OCSP_SERVICELOC) + +IMPLEMENT_ASN1_FUNCTIONS(OCSP_SERVICELOC) diff --git a/libs/openssl/crypto/ocsp/ocsp_cl.c b/libs/openssl/crypto/ocsp/ocsp_cl.c new file mode 100644 index 00000000..b3612c8d --- /dev/null +++ b/libs/openssl/crypto/ocsp/ocsp_cl.c @@ -0,0 +1,383 @@ +/* ocsp_cl.c */ +/* + * Written by Tom Titchener for the OpenSSL + * project. + */ + +/* + * History: This file was transfered to Richard Levitte from CertCo by Kathy + * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a + * patch kit. + */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Utility functions related to sending OCSP requests and extracting relevant + * information from the response. + */ + +/* + * Add an OCSP_CERTID to an OCSP request. Return new OCSP_ONEREQ pointer: + * useful if we want to add extensions. + */ + +OCSP_ONEREQ *OCSP_request_add0_id(OCSP_REQUEST *req, OCSP_CERTID *cid) +{ + OCSP_ONEREQ *one = NULL; + + if (!(one = OCSP_ONEREQ_new())) + goto err; + if (one->reqCert) + OCSP_CERTID_free(one->reqCert); + one->reqCert = cid; + if (req && !sk_OCSP_ONEREQ_push(req->tbsRequest->requestList, one)) + goto err; + return one; + err: + OCSP_ONEREQ_free(one); + return NULL; +} + +/* Set requestorName from an X509_NAME structure */ + +int OCSP_request_set1_name(OCSP_REQUEST *req, X509_NAME *nm) +{ + GENERAL_NAME *gen; + gen = GENERAL_NAME_new(); + if (gen == NULL) + return 0; + if (!X509_NAME_set(&gen->d.directoryName, nm)) { + GENERAL_NAME_free(gen); + return 0; + } + gen->type = GEN_DIRNAME; + if (req->tbsRequest->requestorName) + GENERAL_NAME_free(req->tbsRequest->requestorName); + req->tbsRequest->requestorName = gen; + return 1; +} + +/* Add a certificate to an OCSP request */ + +int OCSP_request_add1_cert(OCSP_REQUEST *req, X509 *cert) +{ + OCSP_SIGNATURE *sig; + if (!req->optionalSignature) + req->optionalSignature = OCSP_SIGNATURE_new(); + sig = req->optionalSignature; + if (!sig) + return 0; + if (!cert) + return 1; + if (!sig->certs && !(sig->certs = sk_X509_new_null())) + return 0; + + if (!sk_X509_push(sig->certs, cert)) + return 0; + CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); + return 1; +} + +/* + * Sign an OCSP request set the requestorName to the subjec name of an + * optional signers certificate and include one or more optional certificates + * in the request. Behaves like PKCS7_sign(). + */ + +int OCSP_request_sign(OCSP_REQUEST *req, + X509 *signer, + EVP_PKEY *key, + const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags) +{ + int i; + OCSP_SIGNATURE *sig; + X509 *x; + + if (!OCSP_request_set1_name(req, X509_get_subject_name(signer))) + goto err; + + if (!(req->optionalSignature = sig = OCSP_SIGNATURE_new())) + goto err; + if (key) { + if (!X509_check_private_key(signer, key)) { + OCSPerr(OCSP_F_OCSP_REQUEST_SIGN, + OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + goto err; + } + if (!OCSP_REQUEST_sign(req, key, dgst)) + goto err; + } + + if (!(flags & OCSP_NOCERTS)) { + if (!OCSP_request_add1_cert(req, signer)) + goto err; + for (i = 0; i < sk_X509_num(certs); i++) { + x = sk_X509_value(certs, i); + if (!OCSP_request_add1_cert(req, x)) + goto err; + } + } + + return 1; + err: + OCSP_SIGNATURE_free(req->optionalSignature); + req->optionalSignature = NULL; + return 0; +} + +/* Get response status */ + +int OCSP_response_status(OCSP_RESPONSE *resp) +{ + return ASN1_ENUMERATED_get(resp->responseStatus); +} + +/* + * Extract basic response from OCSP_RESPONSE or NULL if no basic response + * present. + */ + +OCSP_BASICRESP *OCSP_response_get1_basic(OCSP_RESPONSE *resp) +{ + OCSP_RESPBYTES *rb; + rb = resp->responseBytes; + if (!rb) { + OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NO_RESPONSE_DATA); + return NULL; + } + if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { + OCSPerr(OCSP_F_OCSP_RESPONSE_GET1_BASIC, OCSP_R_NOT_BASIC_RESPONSE); + return NULL; + } + + return ASN1_item_unpack(rb->response, ASN1_ITEM_rptr(OCSP_BASICRESP)); +} + +/* + * Return number of OCSP_SINGLERESP reponses present in a basic response. + */ + +int OCSP_resp_count(OCSP_BASICRESP *bs) +{ + if (!bs) + return -1; + return sk_OCSP_SINGLERESP_num(bs->tbsResponseData->responses); +} + +/* Extract an OCSP_SINGLERESP response with a given index */ + +OCSP_SINGLERESP *OCSP_resp_get0(OCSP_BASICRESP *bs, int idx) +{ + if (!bs) + return NULL; + return sk_OCSP_SINGLERESP_value(bs->tbsResponseData->responses, idx); +} + +/* Look single response matching a given certificate ID */ + +int OCSP_resp_find(OCSP_BASICRESP *bs, OCSP_CERTID *id, int last) +{ + int i; + STACK_OF(OCSP_SINGLERESP) *sresp; + OCSP_SINGLERESP *single; + if (!bs) + return -1; + if (last < 0) + last = 0; + else + last++; + sresp = bs->tbsResponseData->responses; + for (i = last; i < sk_OCSP_SINGLERESP_num(sresp); i++) { + single = sk_OCSP_SINGLERESP_value(sresp, i); + if (!OCSP_id_cmp(id, single->certId)) + return i; + } + return -1; +} + +/* + * Extract status information from an OCSP_SINGLERESP structure. Note: the + * revtime and reason values are only set if the certificate status is + * revoked. Returns numerical value of status. + */ + +int OCSP_single_get0_status(OCSP_SINGLERESP *single, int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd) +{ + int ret; + OCSP_CERTSTATUS *cst; + if (!single) + return -1; + cst = single->certStatus; + ret = cst->type; + if (ret == V_OCSP_CERTSTATUS_REVOKED) { + OCSP_REVOKEDINFO *rev = cst->value.revoked; + if (revtime) + *revtime = rev->revocationTime; + if (reason) { + if (rev->revocationReason) + *reason = ASN1_ENUMERATED_get(rev->revocationReason); + else + *reason = -1; + } + } + if (thisupd) + *thisupd = single->thisUpdate; + if (nextupd) + *nextupd = single->nextUpdate; + return ret; +} + +/* + * This function combines the previous ones: look up a certificate ID and if + * found extract status information. Return 0 is successful. + */ + +int OCSP_resp_find_status(OCSP_BASICRESP *bs, OCSP_CERTID *id, int *status, + int *reason, + ASN1_GENERALIZEDTIME **revtime, + ASN1_GENERALIZEDTIME **thisupd, + ASN1_GENERALIZEDTIME **nextupd) +{ + int i; + OCSP_SINGLERESP *single; + i = OCSP_resp_find(bs, id, -1); + /* Maybe check for multiple responses and give an error? */ + if (i < 0) + return 0; + single = OCSP_resp_get0(bs, i); + i = OCSP_single_get0_status(single, reason, revtime, thisupd, nextupd); + if (status) + *status = i; + return 1; +} + +/* + * Check validity of thisUpdate and nextUpdate fields. It is possible that + * the request will take a few seconds to process and/or the time wont be + * totally accurate. Therefore to avoid rejecting otherwise valid time we + * allow the times to be within 'nsec' of the current time. Also to avoid + * accepting very old responses without a nextUpdate field an optional maxage + * parameter specifies the maximum age the thisUpdate field can be. + */ + +int OCSP_check_validity(ASN1_GENERALIZEDTIME *thisupd, + ASN1_GENERALIZEDTIME *nextupd, long nsec, long maxsec) +{ + int ret = 1; + time_t t_now, t_tmp; + time(&t_now); + /* Check thisUpdate is valid and not more than nsec in the future */ + if (!ASN1_GENERALIZEDTIME_check(thisupd)) { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_THISUPDATE_FIELD); + ret = 0; + } else { + t_tmp = t_now + nsec; + if (X509_cmp_time(thisupd, &t_tmp) > 0) { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_NOT_YET_VALID); + ret = 0; + } + + /* + * If maxsec specified check thisUpdate is not more than maxsec in + * the past + */ + if (maxsec >= 0) { + t_tmp = t_now - maxsec; + if (X509_cmp_time(thisupd, &t_tmp) < 0) { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_TOO_OLD); + ret = 0; + } + } + } + + if (!nextupd) + return ret; + + /* Check nextUpdate is valid and not more than nsec in the past */ + if (!ASN1_GENERALIZEDTIME_check(nextupd)) { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_ERROR_IN_NEXTUPDATE_FIELD); + ret = 0; + } else { + t_tmp = t_now - nsec; + if (X509_cmp_time(nextupd, &t_tmp) < 0) { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, OCSP_R_STATUS_EXPIRED); + ret = 0; + } + } + + /* Also don't allow nextUpdate to precede thisUpdate */ + if (ASN1_STRING_cmp(nextupd, thisupd) < 0) { + OCSPerr(OCSP_F_OCSP_CHECK_VALIDITY, + OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE); + ret = 0; + } + + return ret; +} diff --git a/libs/openssl/crypto/ocsp/ocsp_err.c b/libs/openssl/crypto/ocsp/ocsp_err.c new file mode 100644 index 00000000..722043c0 --- /dev/null +++ b/libs/openssl/crypto/ocsp/ocsp_err.c @@ -0,0 +1,149 @@ +/* crypto/ocsp/ocsp_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_OCSP,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_OCSP,0,reason) + +static ERR_STRING_DATA OCSP_str_functs[] = { + {ERR_FUNC(OCSP_F_ASN1_STRING_ENCODE), "ASN1_STRING_encode"}, + {ERR_FUNC(OCSP_F_D2I_OCSP_NONCE), "D2I_OCSP_NONCE"}, + {ERR_FUNC(OCSP_F_OCSP_BASIC_ADD1_STATUS), "OCSP_basic_add1_status"}, + {ERR_FUNC(OCSP_F_OCSP_BASIC_SIGN), "OCSP_basic_sign"}, + {ERR_FUNC(OCSP_F_OCSP_BASIC_VERIFY), "OCSP_basic_verify"}, + {ERR_FUNC(OCSP_F_OCSP_CERT_ID_NEW), "OCSP_cert_id_new"}, + {ERR_FUNC(OCSP_F_OCSP_CHECK_DELEGATED), "OCSP_CHECK_DELEGATED"}, + {ERR_FUNC(OCSP_F_OCSP_CHECK_IDS), "OCSP_CHECK_IDS"}, + {ERR_FUNC(OCSP_F_OCSP_CHECK_ISSUER), "OCSP_CHECK_ISSUER"}, + {ERR_FUNC(OCSP_F_OCSP_CHECK_VALIDITY), "OCSP_check_validity"}, + {ERR_FUNC(OCSP_F_OCSP_MATCH_ISSUERID), "OCSP_MATCH_ISSUERID"}, + {ERR_FUNC(OCSP_F_OCSP_PARSE_URL), "OCSP_parse_url"}, + {ERR_FUNC(OCSP_F_OCSP_REQUEST_SIGN), "OCSP_request_sign"}, + {ERR_FUNC(OCSP_F_OCSP_REQUEST_VERIFY), "OCSP_request_verify"}, + {ERR_FUNC(OCSP_F_OCSP_RESPONSE_GET1_BASIC), "OCSP_response_get1_basic"}, + {ERR_FUNC(OCSP_F_OCSP_SENDREQ_BIO), "OCSP_sendreq_bio"}, + {ERR_FUNC(OCSP_F_OCSP_SENDREQ_NBIO), "OCSP_sendreq_nbio"}, + {ERR_FUNC(OCSP_F_PARSE_HTTP_LINE1), "PARSE_HTTP_LINE1"}, + {ERR_FUNC(OCSP_F_REQUEST_VERIFY), "REQUEST_VERIFY"}, + {0, NULL} +}; + +static ERR_STRING_DATA OCSP_str_reasons[] = { + {ERR_REASON(OCSP_R_BAD_DATA), "bad data"}, + {ERR_REASON(OCSP_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, + {ERR_REASON(OCSP_R_DIGEST_ERR), "digest err"}, + {ERR_REASON(OCSP_R_ERROR_IN_NEXTUPDATE_FIELD), + "error in nextupdate field"}, + {ERR_REASON(OCSP_R_ERROR_IN_THISUPDATE_FIELD), + "error in thisupdate field"}, + {ERR_REASON(OCSP_R_ERROR_PARSING_URL), "error parsing url"}, + {ERR_REASON(OCSP_R_MISSING_OCSPSIGNING_USAGE), + "missing ocspsigning usage"}, + {ERR_REASON(OCSP_R_NEXTUPDATE_BEFORE_THISUPDATE), + "nextupdate before thisupdate"}, + {ERR_REASON(OCSP_R_NOT_BASIC_RESPONSE), "not basic response"}, + {ERR_REASON(OCSP_R_NO_CERTIFICATES_IN_CHAIN), "no certificates in chain"}, + {ERR_REASON(OCSP_R_NO_CONTENT), "no content"}, + {ERR_REASON(OCSP_R_NO_PUBLIC_KEY), "no public key"}, + {ERR_REASON(OCSP_R_NO_RESPONSE_DATA), "no response data"}, + {ERR_REASON(OCSP_R_NO_REVOKED_TIME), "no revoked time"}, + {ERR_REASON(OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), + "private key does not match certificate"}, + {ERR_REASON(OCSP_R_REQUEST_NOT_SIGNED), "request not signed"}, + {ERR_REASON(OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA), + "response contains no revocation data"}, + {ERR_REASON(OCSP_R_ROOT_CA_NOT_TRUSTED), "root ca not trusted"}, + {ERR_REASON(OCSP_R_SERVER_READ_ERROR), "server read error"}, + {ERR_REASON(OCSP_R_SERVER_RESPONSE_ERROR), "server response error"}, + {ERR_REASON(OCSP_R_SERVER_RESPONSE_PARSE_ERROR), + "server response parse error"}, + {ERR_REASON(OCSP_R_SERVER_WRITE_ERROR), "server write error"}, + {ERR_REASON(OCSP_R_SIGNATURE_FAILURE), "signature failure"}, + {ERR_REASON(OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND), + "signer certificate not found"}, + {ERR_REASON(OCSP_R_STATUS_EXPIRED), "status expired"}, + {ERR_REASON(OCSP_R_STATUS_NOT_YET_VALID), "status not yet valid"}, + {ERR_REASON(OCSP_R_STATUS_TOO_OLD), "status too old"}, + {ERR_REASON(OCSP_R_UNKNOWN_MESSAGE_DIGEST), "unknown message digest"}, + {ERR_REASON(OCSP_R_UNKNOWN_NID), "unknown nid"}, + {ERR_REASON(OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE), + "unsupported requestorname type"}, + {0, NULL} +}; + +#endif + +void ERR_load_OCSP_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(OCSP_str_functs[0].error) == NULL) { + ERR_load_strings(0, OCSP_str_functs); + ERR_load_strings(0, OCSP_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/ocsp/ocsp_ext.c b/libs/openssl/crypto/ocsp/ocsp_ext.c new file mode 100644 index 00000000..c19648c7 --- /dev/null +++ b/libs/openssl/crypto/ocsp/ocsp_ext.c @@ -0,0 +1,566 @@ +/* ocsp_ext.c */ +/* + * Written by Tom Titchener for the OpenSSL + * project. + */ + +/* + * History: This file was transfered to Richard Levitte from CertCo by Kathy + * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a + * patch kit. + */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Standard wrapper functions for extensions */ + +/* OCSP request extensions */ + +int OCSP_REQUEST_get_ext_count(OCSP_REQUEST *x) +{ + return (X509v3_get_ext_count(x->tbsRequest->requestExtensions)); +} + +int OCSP_REQUEST_get_ext_by_NID(OCSP_REQUEST *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID + (x->tbsRequest->requestExtensions, nid, lastpos)); +} + +int OCSP_REQUEST_get_ext_by_OBJ(OCSP_REQUEST *x, ASN1_OBJECT *obj, + int lastpos) +{ + return (X509v3_get_ext_by_OBJ + (x->tbsRequest->requestExtensions, obj, lastpos)); +} + +int OCSP_REQUEST_get_ext_by_critical(OCSP_REQUEST *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical + (x->tbsRequest->requestExtensions, crit, lastpos)); +} + +X509_EXTENSION *OCSP_REQUEST_get_ext(OCSP_REQUEST *x, int loc) +{ + return (X509v3_get_ext(x->tbsRequest->requestExtensions, loc)); +} + +X509_EXTENSION *OCSP_REQUEST_delete_ext(OCSP_REQUEST *x, int loc) +{ + return (X509v3_delete_ext(x->tbsRequest->requestExtensions, loc)); +} + +void *OCSP_REQUEST_get1_ext_d2i(OCSP_REQUEST *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->tbsRequest->requestExtensions, nid, crit, idx); +} + +int OCSP_REQUEST_add1_ext_i2d(OCSP_REQUEST *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->tbsRequest->requestExtensions, nid, value, + crit, flags); +} + +int OCSP_REQUEST_add_ext(OCSP_REQUEST *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->tbsRequest->requestExtensions), ex, loc) != + NULL); +} + +/* Single extensions */ + +int OCSP_ONEREQ_get_ext_count(OCSP_ONEREQ *x) +{ + return (X509v3_get_ext_count(x->singleRequestExtensions)); +} + +int OCSP_ONEREQ_get_ext_by_NID(OCSP_ONEREQ *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->singleRequestExtensions, nid, lastpos)); +} + +int OCSP_ONEREQ_get_ext_by_OBJ(OCSP_ONEREQ *x, ASN1_OBJECT *obj, int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->singleRequestExtensions, obj, lastpos)); +} + +int OCSP_ONEREQ_get_ext_by_critical(OCSP_ONEREQ *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical + (x->singleRequestExtensions, crit, lastpos)); +} + +X509_EXTENSION *OCSP_ONEREQ_get_ext(OCSP_ONEREQ *x, int loc) +{ + return (X509v3_get_ext(x->singleRequestExtensions, loc)); +} + +X509_EXTENSION *OCSP_ONEREQ_delete_ext(OCSP_ONEREQ *x, int loc) +{ + return (X509v3_delete_ext(x->singleRequestExtensions, loc)); +} + +void *OCSP_ONEREQ_get1_ext_d2i(OCSP_ONEREQ *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->singleRequestExtensions, nid, crit, idx); +} + +int OCSP_ONEREQ_add1_ext_i2d(OCSP_ONEREQ *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->singleRequestExtensions, nid, value, crit, + flags); +} + +int OCSP_ONEREQ_add_ext(OCSP_ONEREQ *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->singleRequestExtensions), ex, loc) != NULL); +} + +/* OCSP Basic response */ + +int OCSP_BASICRESP_get_ext_count(OCSP_BASICRESP *x) +{ + return (X509v3_get_ext_count(x->tbsResponseData->responseExtensions)); +} + +int OCSP_BASICRESP_get_ext_by_NID(OCSP_BASICRESP *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID + (x->tbsResponseData->responseExtensions, nid, lastpos)); +} + +int OCSP_BASICRESP_get_ext_by_OBJ(OCSP_BASICRESP *x, ASN1_OBJECT *obj, + int lastpos) +{ + return (X509v3_get_ext_by_OBJ + (x->tbsResponseData->responseExtensions, obj, lastpos)); +} + +int OCSP_BASICRESP_get_ext_by_critical(OCSP_BASICRESP *x, int crit, + int lastpos) +{ + return (X509v3_get_ext_by_critical + (x->tbsResponseData->responseExtensions, crit, lastpos)); +} + +X509_EXTENSION *OCSP_BASICRESP_get_ext(OCSP_BASICRESP *x, int loc) +{ + return (X509v3_get_ext(x->tbsResponseData->responseExtensions, loc)); +} + +X509_EXTENSION *OCSP_BASICRESP_delete_ext(OCSP_BASICRESP *x, int loc) +{ + return (X509v3_delete_ext(x->tbsResponseData->responseExtensions, loc)); +} + +void *OCSP_BASICRESP_get1_ext_d2i(OCSP_BASICRESP *x, int nid, int *crit, + int *idx) +{ + return X509V3_get_d2i(x->tbsResponseData->responseExtensions, nid, crit, + idx); +} + +int OCSP_BASICRESP_add1_ext_i2d(OCSP_BASICRESP *x, int nid, void *value, + int crit, unsigned long flags) +{ + return X509V3_add1_i2d(&x->tbsResponseData->responseExtensions, nid, + value, crit, flags); +} + +int OCSP_BASICRESP_add_ext(OCSP_BASICRESP *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->tbsResponseData->responseExtensions), ex, loc) + != NULL); +} + +/* OCSP single response extensions */ + +int OCSP_SINGLERESP_get_ext_count(OCSP_SINGLERESP *x) +{ + return (X509v3_get_ext_count(x->singleExtensions)); +} + +int OCSP_SINGLERESP_get_ext_by_NID(OCSP_SINGLERESP *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->singleExtensions, nid, lastpos)); +} + +int OCSP_SINGLERESP_get_ext_by_OBJ(OCSP_SINGLERESP *x, ASN1_OBJECT *obj, + int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->singleExtensions, obj, lastpos)); +} + +int OCSP_SINGLERESP_get_ext_by_critical(OCSP_SINGLERESP *x, int crit, + int lastpos) +{ + return (X509v3_get_ext_by_critical(x->singleExtensions, crit, lastpos)); +} + +X509_EXTENSION *OCSP_SINGLERESP_get_ext(OCSP_SINGLERESP *x, int loc) +{ + return (X509v3_get_ext(x->singleExtensions, loc)); +} + +X509_EXTENSION *OCSP_SINGLERESP_delete_ext(OCSP_SINGLERESP *x, int loc) +{ + return (X509v3_delete_ext(x->singleExtensions, loc)); +} + +void *OCSP_SINGLERESP_get1_ext_d2i(OCSP_SINGLERESP *x, int nid, int *crit, + int *idx) +{ + return X509V3_get_d2i(x->singleExtensions, nid, crit, idx); +} + +int OCSP_SINGLERESP_add1_ext_i2d(OCSP_SINGLERESP *x, int nid, void *value, + int crit, unsigned long flags) +{ + return X509V3_add1_i2d(&x->singleExtensions, nid, value, crit, flags); +} + +int OCSP_SINGLERESP_add_ext(OCSP_SINGLERESP *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->singleExtensions), ex, loc) != NULL); +} + +/* also CRL Entry Extensions */ +#if 0 +ASN1_STRING *ASN1_STRING_encode(ASN1_STRING *s, i2d_of_void *i2d, + void *data, STACK_OF(ASN1_OBJECT) *sk) +{ + int i; + unsigned char *p, *b = NULL; + + if (data) { + if ((i = i2d(data, NULL)) <= 0) + goto err; + if (!(b = p = OPENSSL_malloc((unsigned int)i))) + goto err; + if (i2d(data, &p) <= 0) + goto err; + } else if (sk) { + if ((i = i2d_ASN1_SET_OF_ASN1_OBJECT(sk, NULL, + (I2D_OF(ASN1_OBJECT)) i2d, + V_ASN1_SEQUENCE, + V_ASN1_UNIVERSAL, + IS_SEQUENCE)) <= 0) + goto err; + if (!(b = p = OPENSSL_malloc((unsigned int)i))) + goto err; + if (i2d_ASN1_SET_OF_ASN1_OBJECT(sk, &p, (I2D_OF(ASN1_OBJECT)) i2d, + V_ASN1_SEQUENCE, + V_ASN1_UNIVERSAL, IS_SEQUENCE) <= 0) + goto err; + } else { + OCSPerr(OCSP_F_ASN1_STRING_ENCODE, OCSP_R_BAD_DATA); + goto err; + } + if (!s && !(s = ASN1_STRING_new())) + goto err; + if (!(ASN1_STRING_set(s, b, i))) + goto err; + OPENSSL_free(b); + return s; + err: + if (b) + OPENSSL_free(b); + return NULL; +} +#endif + +/* Nonce handling functions */ + +/* + * Add a nonce to an extension stack. A nonce can be specificed or if NULL a + * random nonce will be generated. Note: OpenSSL 0.9.7d and later create an + * OCTET STRING containing the nonce, previous versions used the raw nonce. + */ + +static int ocsp_add1_nonce(STACK_OF(X509_EXTENSION) **exts, + unsigned char *val, int len) +{ + unsigned char *tmpval; + ASN1_OCTET_STRING os; + int ret = 0; + if (len <= 0) + len = OCSP_DEFAULT_NONCE_LENGTH; + /* + * Create the OCTET STRING manually by writing out the header and + * appending the content octets. This avoids an extra memory allocation + * operation in some cases. Applications should *NOT* do this because it + * relies on library internals. + */ + os.length = ASN1_object_size(0, len, V_ASN1_OCTET_STRING); + os.data = OPENSSL_malloc(os.length); + if (os.data == NULL) + goto err; + tmpval = os.data; + ASN1_put_object(&tmpval, 0, len, V_ASN1_OCTET_STRING, V_ASN1_UNIVERSAL); + if (val) + memcpy(tmpval, val, len); + else if (RAND_pseudo_bytes(tmpval, len) < 0) + goto err; + if (!X509V3_add1_i2d(exts, NID_id_pkix_OCSP_Nonce, + &os, 0, X509V3_ADD_REPLACE)) + goto err; + ret = 1; + err: + if (os.data) + OPENSSL_free(os.data); + return ret; +} + +/* Add nonce to an OCSP request */ + +int OCSP_request_add1_nonce(OCSP_REQUEST *req, unsigned char *val, int len) +{ + return ocsp_add1_nonce(&req->tbsRequest->requestExtensions, val, len); +} + +/* Same as above but for a response */ + +int OCSP_basic_add1_nonce(OCSP_BASICRESP *resp, unsigned char *val, int len) +{ + return ocsp_add1_nonce(&resp->tbsResponseData->responseExtensions, val, + len); +} + +/*- + * Check nonce validity in a request and response. + * Return value reflects result: + * 1: nonces present and equal. + * 2: nonces both absent. + * 3: nonce present in response only. + * 0: nonces both present and not equal. + * -1: nonce in request only. + * + * For most responders clients can check return > 0. + * If responder doesn't handle nonces return != 0 may be + * necessary. return == 0 is always an error. + */ + +int OCSP_check_nonce(OCSP_REQUEST *req, OCSP_BASICRESP *bs) +{ + /* + * Since we are only interested in the presence or absence of + * the nonce and comparing its value there is no need to use + * the X509V3 routines: this way we can avoid them allocating an + * ASN1_OCTET_STRING structure for the value which would be + * freed immediately anyway. + */ + + int req_idx, resp_idx; + X509_EXTENSION *req_ext, *resp_ext; + req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); + resp_idx = OCSP_BASICRESP_get_ext_by_NID(bs, NID_id_pkix_OCSP_Nonce, -1); + /* Check both absent */ + if ((req_idx < 0) && (resp_idx < 0)) + return 2; + /* Check in request only */ + if ((req_idx >= 0) && (resp_idx < 0)) + return -1; + /* Check in response but not request */ + if ((req_idx < 0) && (resp_idx >= 0)) + return 3; + /* + * Otherwise nonce in request and response so retrieve the extensions + */ + req_ext = OCSP_REQUEST_get_ext(req, req_idx); + resp_ext = OCSP_BASICRESP_get_ext(bs, resp_idx); + if (ASN1_OCTET_STRING_cmp(req_ext->value, resp_ext->value)) + return 0; + return 1; +} + +/* + * Copy the nonce value (if any) from an OCSP request to a response. + */ + +int OCSP_copy_nonce(OCSP_BASICRESP *resp, OCSP_REQUEST *req) +{ + X509_EXTENSION *req_ext; + int req_idx; + /* Check for nonce in request */ + req_idx = OCSP_REQUEST_get_ext_by_NID(req, NID_id_pkix_OCSP_Nonce, -1); + /* If no nonce that's OK */ + if (req_idx < 0) + return 2; + req_ext = OCSP_REQUEST_get_ext(req, req_idx); + return OCSP_BASICRESP_add_ext(resp, req_ext, -1); +} + +X509_EXTENSION *OCSP_crlID_new(char *url, long *n, char *tim) +{ + X509_EXTENSION *x = NULL; + OCSP_CRLID *cid = NULL; + + if (!(cid = OCSP_CRLID_new())) + goto err; + if (url) { + if (!(cid->crlUrl = ASN1_IA5STRING_new())) + goto err; + if (!(ASN1_STRING_set(cid->crlUrl, url, -1))) + goto err; + } + if (n) { + if (!(cid->crlNum = ASN1_INTEGER_new())) + goto err; + if (!(ASN1_INTEGER_set(cid->crlNum, *n))) + goto err; + } + if (tim) { + if (!(cid->crlTime = ASN1_GENERALIZEDTIME_new())) + goto err; + if (!(ASN1_GENERALIZEDTIME_set_string(cid->crlTime, tim))) + goto err; + } + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_CrlID, 0, cid); + err: + if (cid) + OCSP_CRLID_free(cid); + return x; +} + +/* AcceptableResponses ::= SEQUENCE OF OBJECT IDENTIFIER */ +X509_EXTENSION *OCSP_accept_responses_new(char **oids) +{ + int nid; + STACK_OF(ASN1_OBJECT) *sk = NULL; + ASN1_OBJECT *o = NULL; + X509_EXTENSION *x = NULL; + + if (!(sk = sk_ASN1_OBJECT_new_null())) + goto err; + while (oids && *oids) { + if ((nid = OBJ_txt2nid(*oids)) != NID_undef && (o = OBJ_nid2obj(nid))) + sk_ASN1_OBJECT_push(sk, o); + oids++; + } + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_acceptableResponses, 0, sk); + err: + if (sk) + sk_ASN1_OBJECT_pop_free(sk, ASN1_OBJECT_free); + return x; +} + +/* ArchiveCutoff ::= GeneralizedTime */ +X509_EXTENSION *OCSP_archive_cutoff_new(char *tim) +{ + X509_EXTENSION *x = NULL; + ASN1_GENERALIZEDTIME *gt = NULL; + + if (!(gt = ASN1_GENERALIZEDTIME_new())) + goto err; + if (!(ASN1_GENERALIZEDTIME_set_string(gt, tim))) + goto err; + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_archiveCutoff, 0, gt); + err: + if (gt) + ASN1_GENERALIZEDTIME_free(gt); + return x; +} + +/* + * per ACCESS_DESCRIPTION parameter are oids, of which there are currently + * two--NID_ad_ocsp, NID_id_ad_caIssuers--and GeneralName value. This method + * forces NID_ad_ocsp and uniformResourceLocator [6] IA5String. + */ +X509_EXTENSION *OCSP_url_svcloc_new(X509_NAME *issuer, char **urls) +{ + X509_EXTENSION *x = NULL; + ASN1_IA5STRING *ia5 = NULL; + OCSP_SERVICELOC *sloc = NULL; + ACCESS_DESCRIPTION *ad = NULL; + + if (!(sloc = OCSP_SERVICELOC_new())) + goto err; + if (!(sloc->issuer = X509_NAME_dup(issuer))) + goto err; + if (urls && *urls && !(sloc->locator = sk_ACCESS_DESCRIPTION_new_null())) + goto err; + while (urls && *urls) { + if (!(ad = ACCESS_DESCRIPTION_new())) + goto err; + if (!(ad->method = OBJ_nid2obj(NID_ad_OCSP))) + goto err; + if (!(ad->location = GENERAL_NAME_new())) + goto err; + if (!(ia5 = ASN1_IA5STRING_new())) + goto err; + if (!ASN1_STRING_set((ASN1_STRING *)ia5, *urls, -1)) + goto err; + ad->location->type = GEN_URI; + ad->location->d.ia5 = ia5; + if (!sk_ACCESS_DESCRIPTION_push(sloc->locator, ad)) + goto err; + urls++; + } + x = X509V3_EXT_i2d(NID_id_pkix_OCSP_serviceLocator, 0, sloc); + err: + if (sloc) + OCSP_SERVICELOC_free(sloc); + return x; +} diff --git a/libs/openssl/crypto/ocsp/ocsp_ht.c b/libs/openssl/crypto/ocsp/ocsp_ht.c new file mode 100644 index 00000000..970fea4a --- /dev/null +++ b/libs/openssl/crypto/ocsp/ocsp_ht.c @@ -0,0 +1,476 @@ +/* ocsp_ht.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include "e_os.h" +#include +#include +#include +#include +#ifdef OPENSSL_SYS_SUNOS +# define strtoul (unsigned long)strtol +#endif /* OPENSSL_SYS_SUNOS */ + +/* Stateful OCSP request code, supporting non-blocking I/O */ + +/* Opaque OCSP request status structure */ + +struct ocsp_req_ctx_st { + int state; /* Current I/O state */ + unsigned char *iobuf; /* Line buffer */ + int iobuflen; /* Line buffer length */ + BIO *io; /* BIO to perform I/O with */ + BIO *mem; /* Memory BIO response is built into */ + unsigned long asn1_len; /* ASN1 length of response */ +}; + +#define OCSP_MAX_REQUEST_LENGTH (100 * 1024) +#define OCSP_MAX_LINE_LEN 4096; + +/* OCSP states */ + +/* If set no reading should be performed */ +#define OHS_NOREAD 0x1000 +/* Error condition */ +#define OHS_ERROR (0 | OHS_NOREAD) +/* First line being read */ +#define OHS_FIRSTLINE 1 +/* MIME headers being read */ +#define OHS_HEADERS 2 +/* OCSP initial header (tag + length) being read */ +#define OHS_ASN1_HEADER 3 +/* OCSP content octets being read */ +#define OHS_ASN1_CONTENT 4 +/* Request being sent */ +#define OHS_ASN1_WRITE (6 | OHS_NOREAD) +/* Request being flushed */ +#define OHS_ASN1_FLUSH (7 | OHS_NOREAD) +/* Completed */ +#define OHS_DONE (8 | OHS_NOREAD) + +static int parse_http_line1(char *line); + +void OCSP_REQ_CTX_free(OCSP_REQ_CTX *rctx) +{ + if (rctx->mem) + BIO_free(rctx->mem); + if (rctx->iobuf) + OPENSSL_free(rctx->iobuf); + OPENSSL_free(rctx); +} + +int OCSP_REQ_CTX_set1_req(OCSP_REQ_CTX *rctx, OCSP_REQUEST *req) +{ + static const char req_hdr[] = + "Content-Type: application/ocsp-request\r\n" + "Content-Length: %d\r\n\r\n"; + if (BIO_printf(rctx->mem, req_hdr, i2d_OCSP_REQUEST(req, NULL)) <= 0) + return 0; + if (i2d_OCSP_REQUEST_bio(rctx->mem, req) <= 0) + return 0; + rctx->state = OHS_ASN1_WRITE; + rctx->asn1_len = BIO_get_mem_data(rctx->mem, NULL); + return 1; +} + +int OCSP_REQ_CTX_add1_header(OCSP_REQ_CTX *rctx, + const char *name, const char *value) +{ + if (!name) + return 0; + if (BIO_puts(rctx->mem, name) <= 0) + return 0; + if (value) { + if (BIO_write(rctx->mem, ": ", 2) != 2) + return 0; + if (BIO_puts(rctx->mem, value) <= 0) + return 0; + } + if (BIO_write(rctx->mem, "\r\n", 2) != 2) + return 0; + return 1; +} + +OCSP_REQ_CTX *OCSP_sendreq_new(BIO *io, char *path, OCSP_REQUEST *req, + int maxline) +{ + static const char post_hdr[] = "POST %s HTTP/1.0\r\n"; + + OCSP_REQ_CTX *rctx; + rctx = OPENSSL_malloc(sizeof(OCSP_REQ_CTX)); + if (!rctx) + return NULL; + rctx->state = OHS_ERROR; + rctx->mem = BIO_new(BIO_s_mem()); + rctx->io = io; + rctx->asn1_len = 0; + if (maxline > 0) + rctx->iobuflen = maxline; + else + rctx->iobuflen = OCSP_MAX_LINE_LEN; + rctx->iobuf = OPENSSL_malloc(rctx->iobuflen); + if (!rctx->mem || !rctx->iobuf) + goto err; + if (!path) + path = "/"; + + if (BIO_printf(rctx->mem, post_hdr, path) <= 0) + goto err; + + if (req && !OCSP_REQ_CTX_set1_req(rctx, req)) + goto err; + + return rctx; + err: + OCSP_REQ_CTX_free(rctx); + return NULL; +} + +/* + * Parse the HTTP response. This will look like this: "HTTP/1.0 200 OK". We + * need to obtain the numeric code and (optional) informational message. + */ + +static int parse_http_line1(char *line) +{ + int retcode; + char *p, *q, *r; + /* Skip to first white space (passed protocol info) */ + + for (p = line; *p && !isspace((unsigned char)*p); p++) + continue; + if (!*p) { + OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); + return 0; + } + + /* Skip past white space to start of response code */ + while (*p && isspace((unsigned char)*p)) + p++; + + if (!*p) { + OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); + return 0; + } + + /* Find end of response code: first whitespace after start of code */ + for (q = p; *q && !isspace((unsigned char)*q); q++) + continue; + + if (!*q) { + OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_PARSE_ERROR); + return 0; + } + + /* Set end of response code and start of message */ + *q++ = 0; + + /* Attempt to parse numeric code */ + retcode = strtoul(p, &r, 10); + + if (*r) + return 0; + + /* Skip over any leading white space in message */ + while (*q && isspace((unsigned char)*q)) + q++; + + if (*q) { + /* + * Finally zap any trailing white space in message (include CRLF) + */ + + /* We know q has a non white space character so this is OK */ + for (r = q + strlen(q) - 1; isspace((unsigned char)*r); r--) + *r = 0; + } + if (retcode != 200) { + OCSPerr(OCSP_F_PARSE_HTTP_LINE1, OCSP_R_SERVER_RESPONSE_ERROR); + if (!*q) + ERR_add_error_data(2, "Code=", p); + else + ERR_add_error_data(4, "Code=", p, ",Reason=", q); + return 0; + } + + return 1; + +} + +int OCSP_sendreq_nbio(OCSP_RESPONSE **presp, OCSP_REQ_CTX *rctx) +{ + int i, n; + const unsigned char *p; + next_io: + if (!(rctx->state & OHS_NOREAD)) { + n = BIO_read(rctx->io, rctx->iobuf, rctx->iobuflen); + + if (n <= 0) { + if (BIO_should_retry(rctx->io)) + return -1; + return 0; + } + + /* Write data to memory BIO */ + + if (BIO_write(rctx->mem, rctx->iobuf, n) != n) + return 0; + } + + switch (rctx->state) { + + case OHS_ASN1_WRITE: + n = BIO_get_mem_data(rctx->mem, &p); + + i = BIO_write(rctx->io, p + (n - rctx->asn1_len), rctx->asn1_len); + + if (i <= 0) { + if (BIO_should_retry(rctx->io)) + return -1; + rctx->state = OHS_ERROR; + return 0; + } + + rctx->asn1_len -= i; + + if (rctx->asn1_len > 0) + goto next_io; + + rctx->state = OHS_ASN1_FLUSH; + + (void)BIO_reset(rctx->mem); + + case OHS_ASN1_FLUSH: + + i = BIO_flush(rctx->io); + + if (i > 0) { + rctx->state = OHS_FIRSTLINE; + goto next_io; + } + + if (BIO_should_retry(rctx->io)) + return -1; + + rctx->state = OHS_ERROR; + return 0; + + case OHS_ERROR: + return 0; + + case OHS_FIRSTLINE: + case OHS_HEADERS: + + /* Attempt to read a line in */ + + next_line: + /* + * Due to &%^*$" memory BIO behaviour with BIO_gets we have to check + * there's a complete line in there before calling BIO_gets or we'll + * just get a partial read. + */ + n = BIO_get_mem_data(rctx->mem, &p); + if ((n <= 0) || !memchr(p, '\n', n)) { + if (n >= rctx->iobuflen) { + rctx->state = OHS_ERROR; + return 0; + } + goto next_io; + } + n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen); + + if (n <= 0) { + if (BIO_should_retry(rctx->mem)) + goto next_io; + rctx->state = OHS_ERROR; + return 0; + } + + /* Don't allow excessive lines */ + if (n == rctx->iobuflen) { + rctx->state = OHS_ERROR; + return 0; + } + + /* First line */ + if (rctx->state == OHS_FIRSTLINE) { + if (parse_http_line1((char *)rctx->iobuf)) { + rctx->state = OHS_HEADERS; + goto next_line; + } else { + rctx->state = OHS_ERROR; + return 0; + } + } else { + /* Look for blank line: end of headers */ + for (p = rctx->iobuf; *p; p++) { + if ((*p != '\r') && (*p != '\n')) + break; + } + if (*p) + goto next_line; + + rctx->state = OHS_ASN1_HEADER; + + } + + /* Fall thru */ + + case OHS_ASN1_HEADER: + /* + * Now reading ASN1 header: can read at least 2 bytes which is enough + * for ASN1 SEQUENCE header and either length field or at least the + * length of the length field. + */ + n = BIO_get_mem_data(rctx->mem, &p); + if (n < 2) + goto next_io; + + /* Check it is an ASN1 SEQUENCE */ + if (*p++ != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) { + rctx->state = OHS_ERROR; + return 0; + } + + /* Check out length field */ + if (*p & 0x80) { + /* + * If MSB set on initial length octet we can now always read 6 + * octets: make sure we have them. + */ + if (n < 6) + goto next_io; + n = *p & 0x7F; + /* Not NDEF or excessive length */ + if (!n || (n > 4)) { + rctx->state = OHS_ERROR; + return 0; + } + p++; + rctx->asn1_len = 0; + for (i = 0; i < n; i++) { + rctx->asn1_len <<= 8; + rctx->asn1_len |= *p++; + } + + if (rctx->asn1_len > OCSP_MAX_REQUEST_LENGTH) { + rctx->state = OHS_ERROR; + return 0; + } + + rctx->asn1_len += n + 2; + } else + rctx->asn1_len = *p + 2; + + rctx->state = OHS_ASN1_CONTENT; + + /* Fall thru */ + + case OHS_ASN1_CONTENT: + n = BIO_get_mem_data(rctx->mem, &p); + if (n < (int)rctx->asn1_len) + goto next_io; + + *presp = d2i_OCSP_RESPONSE(NULL, &p, rctx->asn1_len); + if (*presp) { + rctx->state = OHS_DONE; + return 1; + } + + rctx->state = OHS_ERROR; + return 0; + + break; + + case OHS_DONE: + return 1; + + } + + return 0; + +} + +/* Blocking OCSP request handler: now a special case of non-blocking I/O */ + +OCSP_RESPONSE *OCSP_sendreq_bio(BIO *b, char *path, OCSP_REQUEST *req) +{ + OCSP_RESPONSE *resp = NULL; + OCSP_REQ_CTX *ctx; + int rv; + + ctx = OCSP_sendreq_new(b, path, req, -1); + + if (!ctx) + return NULL; + + do { + rv = OCSP_sendreq_nbio(&resp, ctx); + } while ((rv == -1) && BIO_should_retry(b)); + + OCSP_REQ_CTX_free(ctx); + + if (rv) + return resp; + + return NULL; +} diff --git a/libs/openssl/crypto/ocsp/ocsp_lib.c b/libs/openssl/crypto/ocsp/ocsp_lib.c new file mode 100644 index 00000000..8db62ba7 --- /dev/null +++ b/libs/openssl/crypto/ocsp/ocsp_lib.c @@ -0,0 +1,284 @@ +/* ocsp_lib.c */ +/* + * Written by Tom Titchener for the OpenSSL + * project. + */ + +/* + * History: This file was transfered to Richard Levitte from CertCo by Kathy + * Weinhold in mid-spring 2000 to be included in OpenSSL or released as a + * patch kit. + */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Convert a certificate and its issuer to an OCSP_CERTID */ + +OCSP_CERTID *OCSP_cert_to_id(const EVP_MD *dgst, X509 *subject, X509 *issuer) +{ + X509_NAME *iname; + ASN1_INTEGER *serial; + ASN1_BIT_STRING *ikey; +#ifndef OPENSSL_NO_SHA1 + if (!dgst) + dgst = EVP_sha1(); +#endif + if (subject) { + iname = X509_get_issuer_name(subject); + serial = X509_get_serialNumber(subject); + } else { + iname = X509_get_subject_name(issuer); + serial = NULL; + } + ikey = X509_get0_pubkey_bitstr(issuer); + return OCSP_cert_id_new(dgst, iname, ikey, serial); +} + +OCSP_CERTID *OCSP_cert_id_new(const EVP_MD *dgst, + X509_NAME *issuerName, + ASN1_BIT_STRING *issuerKey, + ASN1_INTEGER *serialNumber) +{ + int nid; + unsigned int i; + X509_ALGOR *alg; + OCSP_CERTID *cid = NULL; + unsigned char md[EVP_MAX_MD_SIZE]; + + if (!(cid = OCSP_CERTID_new())) + goto err; + + alg = cid->hashAlgorithm; + if (alg->algorithm != NULL) + ASN1_OBJECT_free(alg->algorithm); + if ((nid = EVP_MD_type(dgst)) == NID_undef) { + OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_UNKNOWN_NID); + goto err; + } + if (!(alg->algorithm = OBJ_nid2obj(nid))) + goto err; + if ((alg->parameter = ASN1_TYPE_new()) == NULL) + goto err; + alg->parameter->type = V_ASN1_NULL; + + if (!X509_NAME_digest(issuerName, dgst, md, &i)) + goto digerr; + if (!(ASN1_OCTET_STRING_set(cid->issuerNameHash, md, i))) + goto err; + + /* Calculate the issuerKey hash, excluding tag and length */ + if (!EVP_Digest(issuerKey->data, issuerKey->length, md, &i, dgst, NULL)) + goto err; + + if (!(ASN1_OCTET_STRING_set(cid->issuerKeyHash, md, i))) + goto err; + + if (serialNumber) { + ASN1_INTEGER_free(cid->serialNumber); + if (!(cid->serialNumber = ASN1_INTEGER_dup(serialNumber))) + goto err; + } + return cid; + digerr: + OCSPerr(OCSP_F_OCSP_CERT_ID_NEW, OCSP_R_DIGEST_ERR); + err: + if (cid) + OCSP_CERTID_free(cid); + return NULL; +} + +int OCSP_id_issuer_cmp(OCSP_CERTID *a, OCSP_CERTID *b) +{ + int ret; + ret = OBJ_cmp(a->hashAlgorithm->algorithm, b->hashAlgorithm->algorithm); + if (ret) + return ret; + ret = ASN1_OCTET_STRING_cmp(a->issuerNameHash, b->issuerNameHash); + if (ret) + return ret; + return ASN1_OCTET_STRING_cmp(a->issuerKeyHash, b->issuerKeyHash); +} + +int OCSP_id_cmp(OCSP_CERTID *a, OCSP_CERTID *b) +{ + int ret; + ret = OCSP_id_issuer_cmp(a, b); + if (ret) + return ret; + return ASN1_INTEGER_cmp(a->serialNumber, b->serialNumber); +} + +/* + * Parse a URL and split it up into host, port and path components and + * whether it is SSL. + */ + +int OCSP_parse_url(char *url, char **phost, char **pport, char **ppath, + int *pssl) +{ + char *p, *buf; + + char *host, *port; + + *phost = NULL; + *pport = NULL; + *ppath = NULL; + + /* dup the buffer since we are going to mess with it */ + buf = BUF_strdup(url); + if (!buf) + goto mem_err; + + /* Check for initial colon */ + p = strchr(buf, ':'); + + if (!p) + goto parse_err; + + *(p++) = '\0'; + + if (!strcmp(buf, "http")) { + *pssl = 0; + port = "80"; + } else if (!strcmp(buf, "https")) { + *pssl = 1; + port = "443"; + } else + goto parse_err; + + /* Check for double slash */ + if ((p[0] != '/') || (p[1] != '/')) + goto parse_err; + + p += 2; + + host = p; + + /* Check for trailing part of path */ + + p = strchr(p, '/'); + + if (!p) + *ppath = BUF_strdup("/"); + else { + *ppath = BUF_strdup(p); + /* Set start of path to 0 so hostname is valid */ + *p = '\0'; + } + + if (!*ppath) + goto mem_err; + + p = host; + if (host[0] == '[') { + /* ipv6 literal */ + host++; + p = strchr(host, ']'); + if (!p) + goto parse_err; + *p = '\0'; + p++; + } + + /* Look for optional ':' for port number */ + if ((p = strchr(p, ':'))) { + *p = 0; + port = p + 1; + } + + *pport = BUF_strdup(port); + if (!*pport) + goto mem_err; + + *phost = BUF_strdup(host); + + if (!*phost) + goto mem_err; + + OPENSSL_free(buf); + + return 1; + + mem_err: + OCSPerr(OCSP_F_OCSP_PARSE_URL, ERR_R_MALLOC_FAILURE); + goto err; + + parse_err: + OCSPerr(OCSP_F_OCSP_PARSE_URL, OCSP_R_ERROR_PARSING_URL); + + err: + if (buf) + OPENSSL_free(buf); + if (*ppath) + OPENSSL_free(*ppath); + if (*pport) + OPENSSL_free(*pport); + if (*phost) + OPENSSL_free(*phost); + return 0; + +} + +IMPLEMENT_ASN1_DUP_FUNCTION(OCSP_CERTID) diff --git a/libs/openssl/crypto/ocsp/ocsp_prn.c b/libs/openssl/crypto/ocsp/ocsp_prn.c new file mode 100644 index 00000000..47d5f83e --- /dev/null +++ b/libs/openssl/crypto/ocsp/ocsp_prn.c @@ -0,0 +1,299 @@ +/* ocsp_prn.c */ +/* + * Written by Tom Titchener for the OpenSSL + * project. + */ + +/* + * History: This file was originally part of ocsp.c and was transfered to + * Richard Levitte from CertCo by Kathy Weinhold in mid-spring 2000 to be + * included in OpenSSL or released as a patch kit. + */ + +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include + +static int ocsp_certid_print(BIO *bp, OCSP_CERTID *a, int indent) +{ + BIO_printf(bp, "%*sCertificate ID:\n", indent, ""); + indent += 2; + BIO_printf(bp, "%*sHash Algorithm: ", indent, ""); + i2a_ASN1_OBJECT(bp, a->hashAlgorithm->algorithm); + BIO_printf(bp, "\n%*sIssuer Name Hash: ", indent, ""); + i2a_ASN1_STRING(bp, a->issuerNameHash, V_ASN1_OCTET_STRING); + BIO_printf(bp, "\n%*sIssuer Key Hash: ", indent, ""); + i2a_ASN1_STRING(bp, a->issuerKeyHash, V_ASN1_OCTET_STRING); + BIO_printf(bp, "\n%*sSerial Number: ", indent, ""); + i2a_ASN1_INTEGER(bp, a->serialNumber); + BIO_printf(bp, "\n"); + return 1; +} + +typedef struct { + long t; + const char *m; +} OCSP_TBLSTR; + +static const char *table2string(long s, const OCSP_TBLSTR *ts, int len) +{ + const OCSP_TBLSTR *p; + for (p = ts; p < ts + len; p++) + if (p->t == s) + return p->m; + return "(UNKNOWN)"; +} + +const char *OCSP_response_status_str(long s) +{ + static const OCSP_TBLSTR rstat_tbl[] = { + {OCSP_RESPONSE_STATUS_SUCCESSFUL, "successful"}, + {OCSP_RESPONSE_STATUS_MALFORMEDREQUEST, "malformedrequest"}, + {OCSP_RESPONSE_STATUS_INTERNALERROR, "internalerror"}, + {OCSP_RESPONSE_STATUS_TRYLATER, "trylater"}, + {OCSP_RESPONSE_STATUS_SIGREQUIRED, "sigrequired"}, + {OCSP_RESPONSE_STATUS_UNAUTHORIZED, "unauthorized"} + }; + return table2string(s, rstat_tbl, 6); +} + +const char *OCSP_cert_status_str(long s) +{ + static const OCSP_TBLSTR cstat_tbl[] = { + {V_OCSP_CERTSTATUS_GOOD, "good"}, + {V_OCSP_CERTSTATUS_REVOKED, "revoked"}, + {V_OCSP_CERTSTATUS_UNKNOWN, "unknown"} + }; + return table2string(s, cstat_tbl, 3); +} + +const char *OCSP_crl_reason_str(long s) +{ + static const OCSP_TBLSTR reason_tbl[] = { + {OCSP_REVOKED_STATUS_UNSPECIFIED, "unspecified"}, + {OCSP_REVOKED_STATUS_KEYCOMPROMISE, "keyCompromise"}, + {OCSP_REVOKED_STATUS_CACOMPROMISE, "cACompromise"}, + {OCSP_REVOKED_STATUS_AFFILIATIONCHANGED, "affiliationChanged"}, + {OCSP_REVOKED_STATUS_SUPERSEDED, "superseded"}, + {OCSP_REVOKED_STATUS_CESSATIONOFOPERATION, "cessationOfOperation"}, + {OCSP_REVOKED_STATUS_CERTIFICATEHOLD, "certificateHold"}, + {OCSP_REVOKED_STATUS_REMOVEFROMCRL, "removeFromCRL"} + }; + return table2string(s, reason_tbl, 8); +} + +int OCSP_REQUEST_print(BIO *bp, OCSP_REQUEST *o, unsigned long flags) +{ + int i; + long l; + OCSP_CERTID *cid = NULL; + OCSP_ONEREQ *one = NULL; + OCSP_REQINFO *inf = o->tbsRequest; + OCSP_SIGNATURE *sig = o->optionalSignature; + + if (BIO_write(bp, "OCSP Request Data:\n", 19) <= 0) + goto err; + l = ASN1_INTEGER_get(inf->version); + if (BIO_printf(bp, " Version: %lu (0x%lx)", l + 1, l) <= 0) + goto err; + if (inf->requestorName != NULL) { + if (BIO_write(bp, "\n Requestor Name: ", 21) <= 0) + goto err; + GENERAL_NAME_print(bp, inf->requestorName); + } + if (BIO_write(bp, "\n Requestor List:\n", 21) <= 0) + goto err; + for (i = 0; i < sk_OCSP_ONEREQ_num(inf->requestList); i++) { + one = sk_OCSP_ONEREQ_value(inf->requestList, i); + cid = one->reqCert; + ocsp_certid_print(bp, cid, 8); + if (!X509V3_extensions_print(bp, + "Request Single Extensions", + one->singleRequestExtensions, flags, 8)) + goto err; + } + if (!X509V3_extensions_print(bp, "Request Extensions", + inf->requestExtensions, flags, 4)) + goto err; + if (sig) { + X509_signature_print(bp, sig->signatureAlgorithm, sig->signature); + for (i = 0; i < sk_X509_num(sig->certs); i++) { + X509_print(bp, sk_X509_value(sig->certs, i)); + PEM_write_bio_X509(bp, sk_X509_value(sig->certs, i)); + } + } + return 1; + err: + return 0; +} + +int OCSP_RESPONSE_print(BIO *bp, OCSP_RESPONSE *o, unsigned long flags) +{ + int i, ret = 0; + long l; + OCSP_CERTID *cid = NULL; + OCSP_BASICRESP *br = NULL; + OCSP_RESPID *rid = NULL; + OCSP_RESPDATA *rd = NULL; + OCSP_CERTSTATUS *cst = NULL; + OCSP_REVOKEDINFO *rev = NULL; + OCSP_SINGLERESP *single = NULL; + OCSP_RESPBYTES *rb = o->responseBytes; + + if (BIO_puts(bp, "OCSP Response Data:\n") <= 0) + goto err; + l = ASN1_ENUMERATED_get(o->responseStatus); + if (BIO_printf(bp, " OCSP Response Status: %s (0x%lx)\n", + OCSP_response_status_str(l), l) <= 0) + goto err; + if (rb == NULL) + return 1; + if (BIO_puts(bp, " Response Type: ") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, rb->responseType) <= 0) + goto err; + if (OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) { + BIO_puts(bp, " (unknown response type)\n"); + return 1; + } + + if ((br = OCSP_response_get1_basic(o)) == NULL) + goto err; + rd = br->tbsResponseData; + l = ASN1_INTEGER_get(rd->version); + if (BIO_printf(bp, "\n Version: %lu (0x%lx)\n", l + 1, l) <= 0) + goto err; + if (BIO_puts(bp, " Responder Id: ") <= 0) + goto err; + + rid = rd->responderId; + switch (rid->type) { + case V_OCSP_RESPID_NAME: + X509_NAME_print_ex(bp, rid->value.byName, 0, XN_FLAG_ONELINE); + break; + case V_OCSP_RESPID_KEY: + i2a_ASN1_STRING(bp, rid->value.byKey, V_ASN1_OCTET_STRING); + break; + } + + if (BIO_printf(bp, "\n Produced At: ") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, rd->producedAt)) + goto err; + if (BIO_printf(bp, "\n Responses:\n") <= 0) + goto err; + for (i = 0; i < sk_OCSP_SINGLERESP_num(rd->responses); i++) { + if (!sk_OCSP_SINGLERESP_value(rd->responses, i)) + continue; + single = sk_OCSP_SINGLERESP_value(rd->responses, i); + cid = single->certId; + if (ocsp_certid_print(bp, cid, 4) <= 0) + goto err; + cst = single->certStatus; + if (BIO_printf(bp, " Cert Status: %s", + OCSP_cert_status_str(cst->type)) <= 0) + goto err; + if (cst->type == V_OCSP_CERTSTATUS_REVOKED) { + rev = cst->value.revoked; + if (BIO_printf(bp, "\n Revocation Time: ") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, rev->revocationTime)) + goto err; + if (rev->revocationReason) { + l = ASN1_ENUMERATED_get(rev->revocationReason); + if (BIO_printf(bp, + "\n Revocation Reason: %s (0x%lx)", + OCSP_crl_reason_str(l), l) <= 0) + goto err; + } + } + if (BIO_printf(bp, "\n This Update: ") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, single->thisUpdate)) + goto err; + if (single->nextUpdate) { + if (BIO_printf(bp, "\n Next Update: ") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, single->nextUpdate)) + goto err; + } + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + if (!X509V3_extensions_print(bp, + "Response Single Extensions", + single->singleExtensions, flags, 8)) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (!X509V3_extensions_print(bp, "Response Extensions", + rd->responseExtensions, flags, 4)) + goto err; + if (X509_signature_print(bp, br->signatureAlgorithm, br->signature) <= 0) + goto err; + + for (i = 0; i < sk_X509_num(br->certs); i++) { + X509_print(bp, sk_X509_value(br->certs, i)); + PEM_write_bio_X509(bp, sk_X509_value(br->certs, i)); + } + + ret = 1; + err: + OCSP_BASICRESP_free(br); + return ret; +} diff --git a/libs/openssl/crypto/ocsp/ocsp_srv.c b/libs/openssl/crypto/ocsp/ocsp_srv.c new file mode 100644 index 00000000..2ec2c636 --- /dev/null +++ b/libs/openssl/crypto/ocsp/ocsp_srv.c @@ -0,0 +1,271 @@ +/* ocsp_srv.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Utility functions related to sending OCSP responses and extracting + * relevant information from the request. + */ + +int OCSP_request_onereq_count(OCSP_REQUEST *req) +{ + return sk_OCSP_ONEREQ_num(req->tbsRequest->requestList); +} + +OCSP_ONEREQ *OCSP_request_onereq_get0(OCSP_REQUEST *req, int i) +{ + return sk_OCSP_ONEREQ_value(req->tbsRequest->requestList, i); +} + +OCSP_CERTID *OCSP_onereq_get0_id(OCSP_ONEREQ *one) +{ + return one->reqCert; +} + +int OCSP_id_get0_info(ASN1_OCTET_STRING **piNameHash, ASN1_OBJECT **pmd, + ASN1_OCTET_STRING **pikeyHash, + ASN1_INTEGER **pserial, OCSP_CERTID *cid) +{ + if (!cid) + return 0; + if (pmd) + *pmd = cid->hashAlgorithm->algorithm; + if (piNameHash) + *piNameHash = cid->issuerNameHash; + if (pikeyHash) + *pikeyHash = cid->issuerKeyHash; + if (pserial) + *pserial = cid->serialNumber; + return 1; +} + +int OCSP_request_is_signed(OCSP_REQUEST *req) +{ + if (req->optionalSignature) + return 1; + return 0; +} + +/* Create an OCSP response and encode an optional basic response */ +OCSP_RESPONSE *OCSP_response_create(int status, OCSP_BASICRESP *bs) +{ + OCSP_RESPONSE *rsp = NULL; + + if (!(rsp = OCSP_RESPONSE_new())) + goto err; + if (!(ASN1_ENUMERATED_set(rsp->responseStatus, status))) + goto err; + if (!bs) + return rsp; + if (!(rsp->responseBytes = OCSP_RESPBYTES_new())) + goto err; + rsp->responseBytes->responseType = OBJ_nid2obj(NID_id_pkix_OCSP_basic); + if (!ASN1_item_pack + (bs, ASN1_ITEM_rptr(OCSP_BASICRESP), &rsp->responseBytes->response)) + goto err; + return rsp; + err: + if (rsp) + OCSP_RESPONSE_free(rsp); + return NULL; +} + +OCSP_SINGLERESP *OCSP_basic_add1_status(OCSP_BASICRESP *rsp, + OCSP_CERTID *cid, + int status, int reason, + ASN1_TIME *revtime, + ASN1_TIME *thisupd, + ASN1_TIME *nextupd) +{ + OCSP_SINGLERESP *single = NULL; + OCSP_CERTSTATUS *cs; + OCSP_REVOKEDINFO *ri; + + if (!rsp->tbsResponseData->responses && + !(rsp->tbsResponseData->responses = sk_OCSP_SINGLERESP_new_null())) + goto err; + + if (!(single = OCSP_SINGLERESP_new())) + goto err; + + if (!ASN1_TIME_to_generalizedtime(thisupd, &single->thisUpdate)) + goto err; + if (nextupd && + !ASN1_TIME_to_generalizedtime(nextupd, &single->nextUpdate)) + goto err; + + OCSP_CERTID_free(single->certId); + + if (!(single->certId = OCSP_CERTID_dup(cid))) + goto err; + + cs = single->certStatus; + switch (cs->type = status) { + case V_OCSP_CERTSTATUS_REVOKED: + if (!revtime) { + OCSPerr(OCSP_F_OCSP_BASIC_ADD1_STATUS, OCSP_R_NO_REVOKED_TIME); + goto err; + } + if (!(cs->value.revoked = ri = OCSP_REVOKEDINFO_new())) + goto err; + if (!ASN1_TIME_to_generalizedtime(revtime, &ri->revocationTime)) + goto err; + if (reason != OCSP_REVOKED_STATUS_NOSTATUS) { + if (!(ri->revocationReason = ASN1_ENUMERATED_new())) + goto err; + if (!(ASN1_ENUMERATED_set(ri->revocationReason, reason))) + goto err; + } + break; + + case V_OCSP_CERTSTATUS_GOOD: + cs->value.good = ASN1_NULL_new(); + break; + + case V_OCSP_CERTSTATUS_UNKNOWN: + cs->value.unknown = ASN1_NULL_new(); + break; + + default: + goto err; + + } + if (!(sk_OCSP_SINGLERESP_push(rsp->tbsResponseData->responses, single))) + goto err; + return single; + err: + OCSP_SINGLERESP_free(single); + return NULL; +} + +/* Add a certificate to an OCSP request */ + +int OCSP_basic_add1_cert(OCSP_BASICRESP *resp, X509 *cert) +{ + if (!resp->certs && !(resp->certs = sk_X509_new_null())) + return 0; + + if (!sk_X509_push(resp->certs, cert)) + return 0; + CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); + return 1; +} + +int OCSP_basic_sign(OCSP_BASICRESP *brsp, + X509 *signer, EVP_PKEY *key, const EVP_MD *dgst, + STACK_OF(X509) *certs, unsigned long flags) +{ + int i; + OCSP_RESPID *rid; + + if (!X509_check_private_key(signer, key)) { + OCSPerr(OCSP_F_OCSP_BASIC_SIGN, + OCSP_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + goto err; + } + + if (!(flags & OCSP_NOCERTS)) { + if (!OCSP_basic_add1_cert(brsp, signer)) + goto err; + for (i = 0; i < sk_X509_num(certs); i++) { + X509 *tmpcert = sk_X509_value(certs, i); + if (!OCSP_basic_add1_cert(brsp, tmpcert)) + goto err; + } + } + + rid = brsp->tbsResponseData->responderId; + if (flags & OCSP_RESPID_KEY) { + unsigned char md[SHA_DIGEST_LENGTH]; + X509_pubkey_digest(signer, EVP_sha1(), md, NULL); + if (!(rid->value.byKey = ASN1_OCTET_STRING_new())) + goto err; + if (!(ASN1_OCTET_STRING_set(rid->value.byKey, md, SHA_DIGEST_LENGTH))) + goto err; + rid->type = V_OCSP_RESPID_KEY; + } else { + if (!X509_NAME_set(&rid->value.byName, X509_get_subject_name(signer))) + goto err; + rid->type = V_OCSP_RESPID_NAME; + } + + if (!(flags & OCSP_NOTIME) && + !X509_gmtime_adj(brsp->tbsResponseData->producedAt, 0)) + goto err; + + /* + * Right now, I think that not doing double hashing is the right thing. + * -- Richard Levitte + */ + + if (!OCSP_BASICRESP_sign(brsp, key, dgst, 0)) + goto err; + + return 1; + err: + return 0; +} diff --git a/libs/openssl/crypto/ocsp/ocsp_vfy.c b/libs/openssl/crypto/ocsp/ocsp_vfy.c new file mode 100644 index 00000000..d4a257c3 --- /dev/null +++ b/libs/openssl/crypto/ocsp/ocsp_vfy.c @@ -0,0 +1,454 @@ +/* ocsp_vfy.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, + STACK_OF(X509) *certs, X509_STORE *st, + unsigned long flags); +static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id); +static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, + unsigned long flags); +static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, + OCSP_CERTID **ret); +static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, + STACK_OF(OCSP_SINGLERESP) *sresp); +static int ocsp_check_delegated(X509 *x, int flags); +static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, + X509_NAME *nm, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags); + +/* Verify a basic response message */ + +int OCSP_basic_verify(OCSP_BASICRESP *bs, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags) +{ + X509 *signer, *x; + STACK_OF(X509) *chain = NULL; + STACK_OF(X509) *untrusted = NULL; + X509_STORE_CTX ctx; + int i, ret = 0; + ret = ocsp_find_signer(&signer, bs, certs, st, flags); + if (!ret) { + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, + OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); + goto end; + } + if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) + flags |= OCSP_NOVERIFY; + if (!(flags & OCSP_NOSIGS)) { + EVP_PKEY *skey; + skey = X509_get_pubkey(signer); + if (skey) { + ret = OCSP_BASICRESP_verify(bs, skey, 0); + EVP_PKEY_free(skey); + } + if (!skey || ret <= 0) { + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_SIGNATURE_FAILURE); + goto end; + } + } + if (!(flags & OCSP_NOVERIFY)) { + int init_res; + if (flags & OCSP_NOCHAIN) { + untrusted = NULL; + } else if (bs->certs && certs) { + untrusted = sk_X509_dup(bs->certs); + for (i = 0; i < sk_X509_num(certs); i++) { + if (!sk_X509_push(untrusted, sk_X509_value(certs, i))) { + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_MALLOC_FAILURE); + goto end; + } + } + } else { + untrusted = bs->certs; + } + init_res = X509_STORE_CTX_init(&ctx, st, signer, untrusted); + if (!init_res) { + ret = -1; + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, ERR_R_X509_LIB); + goto end; + } + + X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); + ret = X509_verify_cert(&ctx); + chain = X509_STORE_CTX_get1_chain(&ctx); + X509_STORE_CTX_cleanup(&ctx); + if (ret <= 0) { + i = X509_STORE_CTX_get_error(&ctx); + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, + OCSP_R_CERTIFICATE_VERIFY_ERROR); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(i)); + goto end; + } + if (flags & OCSP_NOCHECKS) { + ret = 1; + goto end; + } + /* + * At this point we have a valid certificate chain need to verify it + * against the OCSP issuer criteria. + */ + ret = ocsp_check_issuer(bs, chain, flags); + + /* If fatal error or valid match then finish */ + if (ret != 0) + goto end; + + /* + * Easy case: explicitly trusted. Get root CA and check for explicit + * trust + */ + if (flags & OCSP_NOEXPLICIT) + goto end; + + x = sk_X509_value(chain, sk_X509_num(chain) - 1); + if (X509_check_trust(x, NID_OCSP_sign, 0) != X509_TRUST_TRUSTED) { + OCSPerr(OCSP_F_OCSP_BASIC_VERIFY, OCSP_R_ROOT_CA_NOT_TRUSTED); + goto end; + } + ret = 1; + } + + end: + if (chain) + sk_X509_pop_free(chain, X509_free); + if (bs->certs && certs) + sk_X509_free(untrusted); + return ret; +} + +static int ocsp_find_signer(X509 **psigner, OCSP_BASICRESP *bs, + STACK_OF(X509) *certs, X509_STORE *st, + unsigned long flags) +{ + X509 *signer; + OCSP_RESPID *rid = bs->tbsResponseData->responderId; + if ((signer = ocsp_find_signer_sk(certs, rid))) { + *psigner = signer; + return 2; + } + if (!(flags & OCSP_NOINTERN) && + (signer = ocsp_find_signer_sk(bs->certs, rid))) { + *psigner = signer; + return 1; + } + /* Maybe lookup from store if by subject name */ + + *psigner = NULL; + return 0; +} + +static X509 *ocsp_find_signer_sk(STACK_OF(X509) *certs, OCSP_RESPID *id) +{ + int i; + unsigned char tmphash[SHA_DIGEST_LENGTH], *keyhash; + X509 *x; + + /* Easy if lookup by name */ + if (id->type == V_OCSP_RESPID_NAME) + return X509_find_by_subject(certs, id->value.byName); + + /* Lookup by key hash */ + + /* If key hash isn't SHA1 length then forget it */ + if (id->value.byKey->length != SHA_DIGEST_LENGTH) + return NULL; + keyhash = id->value.byKey->data; + /* Calculate hash of each key and compare */ + for (i = 0; i < sk_X509_num(certs); i++) { + x = sk_X509_value(certs, i); + X509_pubkey_digest(x, EVP_sha1(), tmphash, NULL); + if (!memcmp(keyhash, tmphash, SHA_DIGEST_LENGTH)) + return x; + } + return NULL; +} + +static int ocsp_check_issuer(OCSP_BASICRESP *bs, STACK_OF(X509) *chain, + unsigned long flags) +{ + STACK_OF(OCSP_SINGLERESP) *sresp; + X509 *signer, *sca; + OCSP_CERTID *caid = NULL; + int i; + sresp = bs->tbsResponseData->responses; + + if (sk_X509_num(chain) <= 0) { + OCSPerr(OCSP_F_OCSP_CHECK_ISSUER, OCSP_R_NO_CERTIFICATES_IN_CHAIN); + return -1; + } + + /* See if the issuer IDs match. */ + i = ocsp_check_ids(sresp, &caid); + + /* If ID mismatch or other error then return */ + if (i <= 0) + return i; + + signer = sk_X509_value(chain, 0); + /* Check to see if OCSP responder CA matches request CA */ + if (sk_X509_num(chain) > 1) { + sca = sk_X509_value(chain, 1); + i = ocsp_match_issuerid(sca, caid, sresp); + if (i < 0) + return i; + if (i) { + /* We have a match, if extensions OK then success */ + if (ocsp_check_delegated(signer, flags)) + return 1; + return 0; + } + } + + /* Otherwise check if OCSP request signed directly by request CA */ + return ocsp_match_issuerid(signer, caid, sresp); +} + +/* + * Check the issuer certificate IDs for equality. If there is a mismatch with + * the same algorithm then there's no point trying to match any certificates + * against the issuer. If the issuer IDs all match then we just need to check + * equality against one of them. + */ + +static int ocsp_check_ids(STACK_OF(OCSP_SINGLERESP) *sresp, OCSP_CERTID **ret) +{ + OCSP_CERTID *tmpid, *cid; + int i, idcount; + + idcount = sk_OCSP_SINGLERESP_num(sresp); + if (idcount <= 0) { + OCSPerr(OCSP_F_OCSP_CHECK_IDS, + OCSP_R_RESPONSE_CONTAINS_NO_REVOCATION_DATA); + return -1; + } + + cid = sk_OCSP_SINGLERESP_value(sresp, 0)->certId; + + *ret = NULL; + + for (i = 1; i < idcount; i++) { + tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; + /* Check to see if IDs match */ + if (OCSP_id_issuer_cmp(cid, tmpid)) { + /* If algoritm mismatch let caller deal with it */ + if (OBJ_cmp(tmpid->hashAlgorithm->algorithm, + cid->hashAlgorithm->algorithm)) + return 2; + /* Else mismatch */ + return 0; + } + } + + /* All IDs match: only need to check one ID */ + *ret = cid; + return 1; +} + +static int ocsp_match_issuerid(X509 *cert, OCSP_CERTID *cid, + STACK_OF(OCSP_SINGLERESP) *sresp) +{ + /* If only one ID to match then do it */ + if (cid) { + const EVP_MD *dgst; + X509_NAME *iname; + int mdlen; + unsigned char md[EVP_MAX_MD_SIZE]; + if (!(dgst = EVP_get_digestbyobj(cid->hashAlgorithm->algorithm))) { + OCSPerr(OCSP_F_OCSP_MATCH_ISSUERID, + OCSP_R_UNKNOWN_MESSAGE_DIGEST); + return -1; + } + + mdlen = EVP_MD_size(dgst); + if (mdlen < 0) + return -1; + if ((cid->issuerNameHash->length != mdlen) || + (cid->issuerKeyHash->length != mdlen)) + return 0; + iname = X509_get_subject_name(cert); + if (!X509_NAME_digest(iname, dgst, md, NULL)) + return -1; + if (memcmp(md, cid->issuerNameHash->data, mdlen)) + return 0; + X509_pubkey_digest(cert, dgst, md, NULL); + if (memcmp(md, cid->issuerKeyHash->data, mdlen)) + return 0; + + return 1; + + } else { + /* We have to match the whole lot */ + int i, ret; + OCSP_CERTID *tmpid; + for (i = 0; i < sk_OCSP_SINGLERESP_num(sresp); i++) { + tmpid = sk_OCSP_SINGLERESP_value(sresp, i)->certId; + ret = ocsp_match_issuerid(cert, tmpid, NULL); + if (ret <= 0) + return ret; + } + return 1; + } + +} + +static int ocsp_check_delegated(X509 *x, int flags) +{ + X509_check_purpose(x, -1, 0); + if ((x->ex_flags & EXFLAG_XKUSAGE) && (x->ex_xkusage & XKU_OCSP_SIGN)) + return 1; + OCSPerr(OCSP_F_OCSP_CHECK_DELEGATED, OCSP_R_MISSING_OCSPSIGNING_USAGE); + return 0; +} + +/* + * Verify an OCSP request. This is fortunately much easier than OCSP response + * verify. Just find the signers certificate and verify it against a given + * trust value. + */ + +int OCSP_request_verify(OCSP_REQUEST *req, STACK_OF(X509) *certs, + X509_STORE *store, unsigned long flags) +{ + X509 *signer; + X509_NAME *nm; + GENERAL_NAME *gen; + int ret; + X509_STORE_CTX ctx; + if (!req->optionalSignature) { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_REQUEST_NOT_SIGNED); + return 0; + } + gen = req->tbsRequest->requestorName; + if (!gen || gen->type != GEN_DIRNAME) { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, + OCSP_R_UNSUPPORTED_REQUESTORNAME_TYPE); + return 0; + } + nm = gen->d.directoryName; + ret = ocsp_req_find_signer(&signer, req, nm, certs, store, flags); + if (ret <= 0) { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, + OCSP_R_SIGNER_CERTIFICATE_NOT_FOUND); + return 0; + } + if ((ret == 2) && (flags & OCSP_TRUSTOTHER)) + flags |= OCSP_NOVERIFY; + if (!(flags & OCSP_NOSIGS)) { + EVP_PKEY *skey; + skey = X509_get_pubkey(signer); + ret = OCSP_REQUEST_verify(req, skey); + EVP_PKEY_free(skey); + if (ret <= 0) { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, OCSP_R_SIGNATURE_FAILURE); + return 0; + } + } + if (!(flags & OCSP_NOVERIFY)) { + int init_res; + if (flags & OCSP_NOCHAIN) + init_res = X509_STORE_CTX_init(&ctx, store, signer, NULL); + else + init_res = X509_STORE_CTX_init(&ctx, store, signer, + req->optionalSignature->certs); + if (!init_res) { + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, ERR_R_X509_LIB); + return 0; + } + + X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER); + X509_STORE_CTX_set_trust(&ctx, X509_TRUST_OCSP_REQUEST); + ret = X509_verify_cert(&ctx); + X509_STORE_CTX_cleanup(&ctx); + if (ret <= 0) { + ret = X509_STORE_CTX_get_error(&ctx); + OCSPerr(OCSP_F_OCSP_REQUEST_VERIFY, + OCSP_R_CERTIFICATE_VERIFY_ERROR); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(ret)); + return 0; + } + } + return 1; +} + +static int ocsp_req_find_signer(X509 **psigner, OCSP_REQUEST *req, + X509_NAME *nm, STACK_OF(X509) *certs, + X509_STORE *st, unsigned long flags) +{ + X509 *signer; + if (!(flags & OCSP_NOINTERN)) { + signer = X509_find_by_subject(req->optionalSignature->certs, nm); + if (signer) { + *psigner = signer; + return 1; + } + } + + signer = X509_find_by_subject(certs, nm); + if (signer) { + *psigner = signer; + return 2; + } + return 0; +} diff --git a/libs/openssl/crypto/opensslconf.h b/libs/openssl/crypto/opensslconf.h new file mode 100644 index 00000000..b78b3df9 --- /dev/null +++ b/libs/openssl/crypto/opensslconf.h @@ -0,0 +1,253 @@ +/* opensslconf.h */ +/* WARNING: Generated automatically from opensslconf.h.in by Configure. */ + +#ifdef __cplusplus +extern "C" { +#endif +/* OpenSSL was configured with the following options: */ +#ifndef OPENSSL_DOING_MAKEDEPEND + + +#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128 +# define OPENSSL_NO_EC_NISTP_64_GCC_128 +#endif +#ifndef OPENSSL_NO_GMP +# define OPENSSL_NO_GMP +#endif +#ifndef OPENSSL_NO_JPAKE +# define OPENSSL_NO_JPAKE +#endif +#ifndef OPENSSL_NO_KRB5 +# define OPENSSL_NO_KRB5 +#endif +#ifndef OPENSSL_NO_MD2 +# define OPENSSL_NO_MD2 +#endif +#ifndef OPENSSL_NO_RC5 +# define OPENSSL_NO_RC5 +#endif +#ifndef OPENSSL_NO_RFC3779 +# define OPENSSL_NO_RFC3779 +#endif +#ifndef OPENSSL_NO_SCTP +# define OPENSSL_NO_SCTP +#endif +#ifndef OPENSSL_NO_SSL2 +# define OPENSSL_NO_SSL2 +#endif +#ifndef OPENSSL_NO_STORE +# define OPENSSL_NO_STORE +#endif +#ifndef OPENSSL_NO_UNIT_TEST +# define OPENSSL_NO_UNIT_TEST +#endif +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS +# define OPENSSL_NO_WEAK_SSL_CIPHERS +#endif + +#endif /* OPENSSL_DOING_MAKEDEPEND */ + +#ifndef OPENSSL_NO_DYNAMIC_ENGINE +# define OPENSSL_NO_DYNAMIC_ENGINE +#endif + +/* The OPENSSL_NO_* macros are also defined as NO_* if the application + asks for it. This is a transient feature that is provided for those + who haven't had the time to do the appropriate changes in their + applications. */ +#ifdef OPENSSL_ALGORITHM_DEFINES +# if defined(OPENSSL_NO_EC_NISTP_64_GCC_128) && !defined(NO_EC_NISTP_64_GCC_128) +# define NO_EC_NISTP_64_GCC_128 +# endif +# if defined(OPENSSL_NO_GMP) && !defined(NO_GMP) +# define NO_GMP +# endif +# if defined(OPENSSL_NO_JPAKE) && !defined(NO_JPAKE) +# define NO_JPAKE +# endif +# if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5) +# define NO_KRB5 +# endif +# if defined(OPENSSL_NO_MD2) && !defined(NO_MD2) +# define NO_MD2 +# endif +# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5) +# define NO_RC5 +# endif +# if defined(OPENSSL_NO_RFC3779) && !defined(NO_RFC3779) +# define NO_RFC3779 +# endif +# if defined(OPENSSL_NO_SCTP) && !defined(NO_SCTP) +# define NO_SCTP +# endif +# if defined(OPENSSL_NO_SSL2) && !defined(NO_SSL2) +# define NO_SSL2 +# endif +# if defined(OPENSSL_NO_STORE) && !defined(NO_STORE) +# define NO_STORE +# endif +# if defined(OPENSSL_NO_UNIT_TEST) && !defined(NO_UNIT_TEST) +# define NO_UNIT_TEST +# endif +# if defined(OPENSSL_NO_WEAK_SSL_CIPHERS) && !defined(NO_WEAK_SSL_CIPHERS) +# define NO_WEAK_SSL_CIPHERS +# endif +#endif + +/* crypto/opensslconf.h.in */ + +/* Generate 80386 code? */ +#undef I386_ONLY + +#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */ +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define ENGINESDIR "/usr/local/ssl/lib/engines" +#define OPENSSLDIR "/usr/local/ssl" +#endif +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#undef RC4_CHUNK +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned long +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#undef BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependancies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +#error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very mucy CPU dependant */ +#ifndef DES_UNROLL +#undef DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ +#ifdef __cplusplus +} +#endif diff --git a/libs/openssl/crypto/opensslconf.h.in b/libs/openssl/crypto/opensslconf.h.in new file mode 100644 index 00000000..7a1c85d6 --- /dev/null +++ b/libs/openssl/crypto/opensslconf.h.in @@ -0,0 +1,154 @@ +/* crypto/opensslconf.h.in */ + +/* Generate 80386 code? */ +#undef I386_ONLY + +#if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */ +#if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +#define ENGINESDIR "/usr/local/lib/engines" +#define OPENSSLDIR "/usr/local/ssl" +#endif +#endif + +#undef OPENSSL_UNISTD +#define OPENSSL_UNISTD + +#undef OPENSSL_EXPORT_VAR_AS_FUNCTION + +#if defined(HEADER_IDEA_H) && !defined(IDEA_INT) +#define IDEA_INT unsigned int +#endif + +#if defined(HEADER_MD2_H) && !defined(MD2_INT) +#define MD2_INT unsigned int +#endif + +#if defined(HEADER_RC2_H) && !defined(RC2_INT) +/* I need to put in a mod for the alpha - eay */ +#define RC2_INT unsigned int +#endif + +#if defined(HEADER_RC4_H) +#if !defined(RC4_INT) +/* using int types make the structure larger but make the code faster + * on most boxes I have tested - up to %20 faster. */ +/* + * I don't know what does "most" mean, but declaring "int" is a must on: + * - Intel P6 because partial register stalls are very expensive; + * - elder Alpha because it lacks byte load/store instructions; + */ +#define RC4_INT unsigned int +#endif +#if !defined(RC4_CHUNK) +/* + * This enables code handling data aligned at natural CPU word + * boundary. See crypto/rc4/rc4_enc.c for further details. + */ +#undef RC4_CHUNK +#endif +#endif + +#if (defined(HEADER_NEW_DES_H) || defined(HEADER_DES_H)) && !defined(DES_LONG) +/* If this is set to 'unsigned int' on a DEC Alpha, this gives about a + * %20 speed up (longs are 8 bytes, int's are 4). */ +#ifndef DES_LONG +#define DES_LONG unsigned long +#endif +#endif + +#if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) +#define CONFIG_HEADER_BN_H +#undef BN_LLONG + +/* Should we define BN_DIV2W here? */ + +/* Only one for the following should be defined */ +#undef SIXTY_FOUR_BIT_LONG +#undef SIXTY_FOUR_BIT +#define THIRTY_TWO_BIT +#endif + +#if defined(HEADER_RC4_LOCL_H) && !defined(CONFIG_HEADER_RC4_LOCL_H) +#define CONFIG_HEADER_RC4_LOCL_H +/* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +#undef RC4_INDEX +#endif + +#if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +#define CONFIG_HEADER_BF_LOCL_H +#undef BF_PTR +#endif /* HEADER_BF_LOCL_H */ + +#if defined(HEADER_DES_LOCL_H) && !defined(CONFIG_HEADER_DES_LOCL_H) +#define CONFIG_HEADER_DES_LOCL_H +#ifndef DES_DEFAULT_OPTIONS +/* the following is tweaked from a config script, that is why it is a + * protected undef/define */ +#ifndef DES_PTR +#undef DES_PTR +#endif + +/* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependancies at the expense of 2 more + * registers */ +#ifndef DES_RISC1 +#undef DES_RISC1 +#endif + +#ifndef DES_RISC2 +#undef DES_RISC2 +#endif + +#if defined(DES_RISC1) && defined(DES_RISC2) +#error YOU SHOULD NOT HAVE BOTH DES_RISC1 AND DES_RISC2 DEFINED!!!!! +#endif + +/* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very mucy CPU dependant */ +#ifndef DES_UNROLL +#undef DES_UNROLL +#endif + +/* These default values were supplied by + * Peter Gutman + * They are only used if nothing else has been defined */ +#if !defined(DES_PTR) && !defined(DES_RISC1) && !defined(DES_RISC2) && !defined(DES_UNROLL) +/* Special defines which change the way the code is built depending on the + CPU and OS. For SGI machines you can use _MIPS_SZLONG (32 or 64) to find + even newer MIPS CPU's, but at the moment one size fits all for + optimization options. Older Sparc's work better with only UNROLL, but + there's no way to tell at compile time what it is you're running on */ + +#if defined( __sun ) || defined ( sun ) /* Newer Sparc's */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#elif defined( __ultrix ) /* Older MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined( __osf1__ ) /* Alpha */ +# define DES_PTR +# define DES_RISC2 +#elif defined ( _AIX ) /* RS6000 */ + /* Unknown */ +#elif defined( __hpux ) /* HP-PA */ + /* Unknown */ +#elif defined( __aux ) /* 68K */ + /* Unknown */ +#elif defined( __dgux ) /* 88K (but P6 in latest boxes) */ +# define DES_UNROLL +#elif defined( __sgi ) /* Newer MIPS */ +# define DES_PTR +# define DES_RISC2 +# define DES_UNROLL +#elif defined(i386) || defined(__i386__) /* x86 boxes, should be gcc */ +# define DES_PTR +# define DES_RISC1 +# define DES_UNROLL +#endif /* Systems-specific speed defines */ +#endif + +#endif /* DES_DEFAULT_OPTIONS */ +#endif /* HEADER_DES_LOCL_H */ diff --git a/libs/openssl/crypto/opensslv.h b/libs/openssl/crypto/opensslv.h new file mode 100644 index 00000000..2f293232 --- /dev/null +++ b/libs/openssl/crypto/opensslv.h @@ -0,0 +1,97 @@ +#ifndef HEADER_OPENSSLV_H +# define HEADER_OPENSSLV_H + +#ifdef __cplusplus +extern "C" { +#endif + +/*- + * Numeric release version identifier: + * MNNFFPPS: major minor fix patch status + * The status nibble has one of the values 0 for development, 1 to e for betas + * 1 to 14, and f for release. The patch level is exactly that. + * For example: + * 0.9.3-dev 0x00903000 + * 0.9.3-beta1 0x00903001 + * 0.9.3-beta2-dev 0x00903002 + * 0.9.3-beta2 0x00903002 (same as ...beta2-dev) + * 0.9.3 0x0090300f + * 0.9.3a 0x0090301f + * 0.9.4 0x0090400f + * 1.2.3z 0x102031af + * + * For continuity reasons (because 0.9.5 is already out, and is coded + * 0x00905100), between 0.9.5 and 0.9.6 the coding of the patch level + * part is slightly different, by setting the highest bit. This means + * that 0.9.5a looks like this: 0x0090581f. At 0.9.6, we can start + * with 0x0090600S... + * + * (Prior to 0.9.3-dev a different scheme was used: 0.9.2b is 0x0922.) + * (Prior to 0.9.5a beta1, a different scheme was used: MMNNFFRBB for + * major minor fix final patch/beta) + */ +# define OPENSSL_VERSION_NUMBER 0x1000114fL +# ifdef OPENSSL_FIPS +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1t-fips 3 May 2016" +# else +# define OPENSSL_VERSION_TEXT "OpenSSL 1.0.1t 3 May 2016" +# endif +# define OPENSSL_VERSION_PTEXT " part of " OPENSSL_VERSION_TEXT + +/*- + * The macros below are to be used for shared library (.so, .dll, ...) + * versioning. That kind of versioning works a bit differently between + * operating systems. The most usual scheme is to set a major and a minor + * number, and have the runtime loader check that the major number is equal + * to what it was at application link time, while the minor number has to + * be greater or equal to what it was at application link time. With this + * scheme, the version number is usually part of the file name, like this: + * + * libcrypto.so.0.9 + * + * Some unixen also make a softlink with the major verson number only: + * + * libcrypto.so.0 + * + * On Tru64 and IRIX 6.x it works a little bit differently. There, the + * shared library version is stored in the file, and is actually a series + * of versions, separated by colons. The rightmost version present in the + * library when linking an application is stored in the application to be + * matched at run time. When the application is run, a check is done to + * see if the library version stored in the application matches any of the + * versions in the version string of the library itself. + * This version string can be constructed in any way, depending on what + * kind of matching is desired. However, to implement the same scheme as + * the one used in the other unixen, all compatible versions, from lowest + * to highest, should be part of the string. Consecutive builds would + * give the following versions strings: + * + * 3.0 + * 3.0:3.1 + * 3.0:3.1:3.2 + * 4.0 + * 4.0:4.1 + * + * Notice how version 4 is completely incompatible with version, and + * therefore give the breach you can see. + * + * There may be other schemes as well that I haven't yet discovered. + * + * So, here's the way it works here: first of all, the library version + * number doesn't need at all to match the overall OpenSSL version. + * However, it's nice and more understandable if it actually does. + * The current library version is stored in the macro SHLIB_VERSION_NUMBER, + * which is just a piece of text in the format "M.m.e" (Major, minor, edit). + * For the sake of Tru64, IRIX, and any other OS that behaves in similar ways, + * we need to keep a history of version numbers, which is done in the + * macro SHLIB_VERSION_HISTORY. The numbers are separated by colons and + * should only keep the versions that are binary compatible with the current. + */ +# define SHLIB_VERSION_HISTORY "" +# define SHLIB_VERSION_NUMBER "1.0.0" + + +#ifdef __cplusplus +} +#endif +#endif /* HEADER_OPENSSLV_H */ diff --git a/libs/openssl/crypto/ossl_typ.h b/libs/openssl/crypto/ossl_typ.h new file mode 100644 index 00000000..0fcb0cea --- /dev/null +++ b/libs/openssl/crypto/ossl_typ.h @@ -0,0 +1,209 @@ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_OPENSSL_TYPES_H +# define HEADER_OPENSSL_TYPES_H + +#ifdef __cplusplus +extern "C" { +#endif + +# include + +# ifdef NO_ASN1_TYPEDEFS +# define ASN1_INTEGER ASN1_STRING +# define ASN1_ENUMERATED ASN1_STRING +# define ASN1_BIT_STRING ASN1_STRING +# define ASN1_OCTET_STRING ASN1_STRING +# define ASN1_PRINTABLESTRING ASN1_STRING +# define ASN1_T61STRING ASN1_STRING +# define ASN1_IA5STRING ASN1_STRING +# define ASN1_UTCTIME ASN1_STRING +# define ASN1_GENERALIZEDTIME ASN1_STRING +# define ASN1_TIME ASN1_STRING +# define ASN1_GENERALSTRING ASN1_STRING +# define ASN1_UNIVERSALSTRING ASN1_STRING +# define ASN1_BMPSTRING ASN1_STRING +# define ASN1_VISIBLESTRING ASN1_STRING +# define ASN1_UTF8STRING ASN1_STRING +# define ASN1_BOOLEAN int +# define ASN1_NULL int +# else +typedef struct asn1_string_st ASN1_INTEGER; +typedef struct asn1_string_st ASN1_ENUMERATED; +typedef struct asn1_string_st ASN1_BIT_STRING; +typedef struct asn1_string_st ASN1_OCTET_STRING; +typedef struct asn1_string_st ASN1_PRINTABLESTRING; +typedef struct asn1_string_st ASN1_T61STRING; +typedef struct asn1_string_st ASN1_IA5STRING; +typedef struct asn1_string_st ASN1_GENERALSTRING; +typedef struct asn1_string_st ASN1_UNIVERSALSTRING; +typedef struct asn1_string_st ASN1_BMPSTRING; +typedef struct asn1_string_st ASN1_UTCTIME; +typedef struct asn1_string_st ASN1_TIME; +typedef struct asn1_string_st ASN1_GENERALIZEDTIME; +typedef struct asn1_string_st ASN1_VISIBLESTRING; +typedef struct asn1_string_st ASN1_UTF8STRING; +typedef struct asn1_string_st ASN1_STRING; +typedef int ASN1_BOOLEAN; +typedef int ASN1_NULL; +# endif + +typedef struct ASN1_ITEM_st ASN1_ITEM; +typedef struct asn1_pctx_st ASN1_PCTX; + +# ifdef OPENSSL_SYS_WIN32 +# undef X509_NAME +# undef X509_EXTENSIONS +# undef X509_CERT_PAIR +# undef PKCS7_ISSUER_AND_SERIAL +# undef OCSP_REQUEST +# undef OCSP_RESPONSE +# endif + +# ifdef BIGNUM +# undef BIGNUM +# endif +typedef struct bignum_st BIGNUM; +typedef struct bignum_ctx BN_CTX; +typedef struct bn_blinding_st BN_BLINDING; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct bn_recp_ctx_st BN_RECP_CTX; +typedef struct bn_gencb_st BN_GENCB; + +typedef struct buf_mem_st BUF_MEM; + +typedef struct evp_cipher_st EVP_CIPHER; +typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; +typedef struct env_md_st EVP_MD; +typedef struct env_md_ctx_st EVP_MD_CTX; +typedef struct evp_pkey_st EVP_PKEY; + +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; + +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; + +typedef struct dh_st DH; +typedef struct dh_method DH_METHOD; + +typedef struct dsa_st DSA; +typedef struct dsa_method DSA_METHOD; + +typedef struct rsa_st RSA; +typedef struct rsa_meth_st RSA_METHOD; + +typedef struct rand_meth_st RAND_METHOD; + +typedef struct ecdh_method ECDH_METHOD; +typedef struct ecdsa_method ECDSA_METHOD; + +typedef struct x509_st X509; +typedef struct X509_algor_st X509_ALGOR; +typedef struct X509_crl_st X509_CRL; +typedef struct x509_crl_method_st X509_CRL_METHOD; +typedef struct x509_revoked_st X509_REVOKED; +typedef struct X509_name_st X509_NAME; +typedef struct X509_pubkey_st X509_PUBKEY; +typedef struct x509_store_st X509_STORE; +typedef struct x509_store_ctx_st X509_STORE_CTX; + +typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; + +typedef struct v3_ext_ctx X509V3_CTX; +typedef struct conf_st CONF; + +typedef struct store_st STORE; +typedef struct store_method_st STORE_METHOD; + +typedef struct ui_st UI; +typedef struct ui_method_st UI_METHOD; + +typedef struct st_ERR_FNS ERR_FNS; + +typedef struct engine_st ENGINE; +typedef struct ssl_st SSL; +typedef struct ssl_ctx_st SSL_CTX; + +typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; +typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; +typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; +typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; + +typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID; +typedef struct DIST_POINT_st DIST_POINT; +typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT; +typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; + + /* If placed in pkcs12.h, we end up with a circular depency with pkcs7.h */ +# define DECLARE_PKCS12_STACK_OF(type)/* Nothing */ +# define IMPLEMENT_PKCS12_STACK_OF(type)/* Nothing */ + +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; +/* Callback types for crypto.h */ +typedef int CRYPTO_EX_new (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef void CRYPTO_EX_free (void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int idx, long argl, void *argp); +typedef int CRYPTO_EX_dup (CRYPTO_EX_DATA *to, CRYPTO_EX_DATA *from, + void *from_d, int idx, long argl, void *argp); + +typedef struct ocsp_req_ctx_st OCSP_REQ_CTX; +typedef struct ocsp_response_st OCSP_RESPONSE; +typedef struct ocsp_responder_id_st OCSP_RESPID; + +#ifdef __cplusplus +} +#endif +#endif /* def HEADER_OPENSSL_TYPES_H */ diff --git a/libs/openssl/crypto/pariscid.pl b/libs/openssl/crypto/pariscid.pl new file mode 100644 index 00000000..bfc56fdc --- /dev/null +++ b/libs/openssl/crypto/pariscid.pl @@ -0,0 +1,225 @@ +#!/usr/bin/env perl + +$flavour = shift; +$output = shift; +open STDOUT,">$output"; + +if ($flavour =~ /64/) { + $LEVEL ="2.0W"; + $SIZE_T =8; + $ST ="std"; +} else { + $LEVEL ="1.1"; + $SIZE_T =4; + $ST ="stw"; +} + +$rp="%r2"; +$sp="%r30"; +$rv="%r28"; + +$code=<<___; + .LEVEL $LEVEL + .SPACE \$TEXT\$ + .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY + + .EXPORT OPENSSL_cpuid_setup,ENTRY + .ALIGN 8 +OPENSSL_cpuid_setup + .PROC + .CALLINFO NO_CALLS + .ENTRY + bv ($rp) + .EXIT + nop + .PROCEND + + .EXPORT OPENSSL_rdtsc,ENTRY + .ALIGN 8 +OPENSSL_rdtsc + .PROC + .CALLINFO NO_CALLS + .ENTRY + mfctl %cr16,$rv + bv ($rp) + .EXIT + nop + .PROCEND + + .EXPORT OPENSSL_wipe_cpu,ENTRY + .ALIGN 8 +OPENSSL_wipe_cpu + .PROC + .CALLINFO NO_CALLS + .ENTRY + xor %r0,%r0,%r1 + fcpy,dbl %fr0,%fr4 + xor %r0,%r0,%r19 + fcpy,dbl %fr0,%fr5 + xor %r0,%r0,%r20 + fcpy,dbl %fr0,%fr6 + xor %r0,%r0,%r21 + fcpy,dbl %fr0,%fr7 + xor %r0,%r0,%r22 + fcpy,dbl %fr0,%fr8 + xor %r0,%r0,%r23 + fcpy,dbl %fr0,%fr9 + xor %r0,%r0,%r24 + fcpy,dbl %fr0,%fr10 + xor %r0,%r0,%r25 + fcpy,dbl %fr0,%fr11 + xor %r0,%r0,%r26 + fcpy,dbl %fr0,%fr22 + xor %r0,%r0,%r29 + fcpy,dbl %fr0,%fr23 + xor %r0,%r0,%r31 + fcpy,dbl %fr0,%fr24 + fcpy,dbl %fr0,%fr25 + fcpy,dbl %fr0,%fr26 + fcpy,dbl %fr0,%fr27 + fcpy,dbl %fr0,%fr28 + fcpy,dbl %fr0,%fr29 + fcpy,dbl %fr0,%fr30 + fcpy,dbl %fr0,%fr31 + bv ($rp) + .EXIT + ldo 0($sp),$rv + .PROCEND +___ +{ +my $inp="%r26"; +my $len="%r25"; + +$code.=<<___; + .EXPORT OPENSSL_cleanse,ENTRY,ARGW0=GR,ARGW1=GR + .ALIGN 8 +OPENSSL_cleanse + .PROC + .CALLINFO NO_CALLS + .ENTRY + cmpib,*= 0,$len,L\$done + nop + cmpib,*>>= 15,$len,L\$ittle + ldi $SIZE_T-1,%r1 + +L\$align + and,*<> $inp,%r1,%r28 + b,n L\$aligned + stb %r0,0($inp) + ldo -1($len),$len + b L\$align + ldo 1($inp),$inp + +L\$aligned + andcm $len,%r1,%r28 +L\$ot + $ST %r0,0($inp) + addib,*<> -$SIZE_T,%r28,L\$ot + ldo $SIZE_T($inp),$inp + + and,*<> $len,%r1,$len + b,n L\$done +L\$ittle + stb %r0,0($inp) + addib,*<> -1,$len,L\$ittle + ldo 1($inp),$inp +L\$done + bv ($rp) + .EXIT + nop + .PROCEND +___ +} +{ +my ($out,$cnt,$max)=("%r26","%r25","%r24"); +my ($tick,$lasttick)=("%r23","%r22"); +my ($diff,$lastdiff)=("%r21","%r20"); + +$code.=<<___; + .EXPORT OPENSSL_instrument_bus,ENTRY,ARGW0=GR,ARGW1=GR + .ALIGN 8 +OPENSSL_instrument_bus + .PROC + .CALLINFO NO_CALLS + .ENTRY + copy $cnt,$rv + mfctl %cr16,$tick + copy $tick,$lasttick + ldi 0,$diff + + fdc 0($out) + ldw 0($out),$tick + add $diff,$tick,$tick + stw $tick,0($out) +L\$oop + mfctl %cr16,$tick + sub $tick,$lasttick,$diff + copy $tick,$lasttick + + fdc 0($out) + ldw 0($out),$tick + add $diff,$tick,$tick + stw $tick,0($out) + + addib,<> -1,$cnt,L\$oop + addi 4,$out,$out + + bv ($rp) + .EXIT + sub $rv,$cnt,$rv + .PROCEND + + .EXPORT OPENSSL_instrument_bus2,ENTRY,ARGW0=GR,ARGW1=GR + .ALIGN 8 +OPENSSL_instrument_bus2 + .PROC + .CALLINFO NO_CALLS + .ENTRY + copy $cnt,$rv + sub %r0,$cnt,$cnt + + mfctl %cr16,$tick + copy $tick,$lasttick + ldi 0,$diff + + fdc 0($out) + ldw 0($out),$tick + add $diff,$tick,$tick + stw $tick,0($out) + + mfctl %cr16,$tick + sub $tick,$lasttick,$diff + copy $tick,$lasttick +L\$oop2 + copy $diff,$lastdiff + fdc 0($out) + ldw 0($out),$tick + add $diff,$tick,$tick + stw $tick,0($out) + + addib,= -1,$max,L\$done2 + nop + + mfctl %cr16,$tick + sub $tick,$lasttick,$diff + copy $tick,$lasttick + cmpclr,<> $lastdiff,$diff,$tick + ldi 1,$tick + + ldi 1,%r1 + xor %r1,$tick,$tick + addb,<> $tick,$cnt,L\$oop2 + shladd,l $tick,2,$out,$out +L\$done2 + bv ($rp) + .EXIT + add $rv,$cnt,$rv + .PROCEND +___ +} +$code =~ s/cmpib,\*/comib,/gm if ($SIZE_T==4); +$code =~ s/,\*/,/gm if ($SIZE_T==4); +$code =~ s/\bbv\b/bve/gm if ($SIZE_T==8); +print $code; +close STDOUT; + diff --git a/libs/openssl/crypto/pem/message b/libs/openssl/crypto/pem/message new file mode 100644 index 00000000..e8bf9d75 --- /dev/null +++ b/libs/openssl/crypto/pem/message @@ -0,0 +1,16 @@ +-----BEGIN PRIVACY-ENHANCED MESSAGE----- +Proc-Type: 4,ENCRYPTED +Proc-Type: 4,MIC-ONLY +Proc-Type: 4,MIC-CLEAR +Content-Domain: RFC822 +DEK-Info: DES-CBC,0123456789abcdef +Originator-Certificate + xxxx +Issuer-Certificate + xxxx +MIC-Info: RSA-MD5,RSA, + xxxx + + +-----END PRIVACY-ENHANCED MESSAGE----- + diff --git a/libs/openssl/crypto/pem/pem.h b/libs/openssl/crypto/pem/pem.h new file mode 100644 index 00000000..2cdad8ac --- /dev/null +++ b/libs/openssl/crypto/pem/pem.h @@ -0,0 +1,611 @@ +/* crypto/pem/pem.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_PEM_H +# define HEADER_PEM_H + +# include +# ifndef OPENSSL_NO_BIO +# include +# endif +# ifndef OPENSSL_NO_STACK +# include +# endif +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define PEM_BUFSIZE 1024 + +# define PEM_OBJ_UNDEF 0 +# define PEM_OBJ_X509 1 +# define PEM_OBJ_X509_REQ 2 +# define PEM_OBJ_CRL 3 +# define PEM_OBJ_SSL_SESSION 4 +# define PEM_OBJ_PRIV_KEY 10 +# define PEM_OBJ_PRIV_RSA 11 +# define PEM_OBJ_PRIV_DSA 12 +# define PEM_OBJ_PRIV_DH 13 +# define PEM_OBJ_PUB_RSA 14 +# define PEM_OBJ_PUB_DSA 15 +# define PEM_OBJ_PUB_DH 16 +# define PEM_OBJ_DHPARAMS 17 +# define PEM_OBJ_DSAPARAMS 18 +# define PEM_OBJ_PRIV_RSA_PUBLIC 19 +# define PEM_OBJ_PRIV_ECDSA 20 +# define PEM_OBJ_PUB_ECDSA 21 +# define PEM_OBJ_ECPARAMETERS 22 + +# define PEM_ERROR 30 +# define PEM_DEK_DES_CBC 40 +# define PEM_DEK_IDEA_CBC 45 +# define PEM_DEK_DES_EDE 50 +# define PEM_DEK_DES_ECB 60 +# define PEM_DEK_RSA 70 +# define PEM_DEK_RSA_MD2 80 +# define PEM_DEK_RSA_MD5 90 + +# define PEM_MD_MD2 NID_md2 +# define PEM_MD_MD5 NID_md5 +# define PEM_MD_SHA NID_sha +# define PEM_MD_MD2_RSA NID_md2WithRSAEncryption +# define PEM_MD_MD5_RSA NID_md5WithRSAEncryption +# define PEM_MD_SHA_RSA NID_sha1WithRSAEncryption + +# define PEM_STRING_X509_OLD "X509 CERTIFICATE" +# define PEM_STRING_X509 "CERTIFICATE" +# define PEM_STRING_X509_PAIR "CERTIFICATE PAIR" +# define PEM_STRING_X509_TRUSTED "TRUSTED CERTIFICATE" +# define PEM_STRING_X509_REQ_OLD "NEW CERTIFICATE REQUEST" +# define PEM_STRING_X509_REQ "CERTIFICATE REQUEST" +# define PEM_STRING_X509_CRL "X509 CRL" +# define PEM_STRING_EVP_PKEY "ANY PRIVATE KEY" +# define PEM_STRING_PUBLIC "PUBLIC KEY" +# define PEM_STRING_RSA "RSA PRIVATE KEY" +# define PEM_STRING_RSA_PUBLIC "RSA PUBLIC KEY" +# define PEM_STRING_DSA "DSA PRIVATE KEY" +# define PEM_STRING_DSA_PUBLIC "DSA PUBLIC KEY" +# define PEM_STRING_PKCS7 "PKCS7" +# define PEM_STRING_PKCS7_SIGNED "PKCS #7 SIGNED DATA" +# define PEM_STRING_PKCS8 "ENCRYPTED PRIVATE KEY" +# define PEM_STRING_PKCS8INF "PRIVATE KEY" +# define PEM_STRING_DHPARAMS "DH PARAMETERS" +# define PEM_STRING_SSL_SESSION "SSL SESSION PARAMETERS" +# define PEM_STRING_DSAPARAMS "DSA PARAMETERS" +# define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" +# define PEM_STRING_ECPARAMETERS "EC PARAMETERS" +# define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" +# define PEM_STRING_PARAMETERS "PARAMETERS" +# define PEM_STRING_CMS "CMS" + + /* + * Note that this structure is initialised by PEM_SealInit and cleaned up + * by PEM_SealFinal (at least for now) + */ +typedef struct PEM_Encode_Seal_st { + EVP_ENCODE_CTX encode; + EVP_MD_CTX md; + EVP_CIPHER_CTX cipher; +} PEM_ENCODE_SEAL_CTX; + +/* enc_type is one off */ +# define PEM_TYPE_ENCRYPTED 10 +# define PEM_TYPE_MIC_ONLY 20 +# define PEM_TYPE_MIC_CLEAR 30 +# define PEM_TYPE_CLEAR 40 + +typedef struct pem_recip_st { + char *name; + X509_NAME *dn; + int cipher; + int key_enc; + /* char iv[8]; unused and wrong size */ +} PEM_USER; + +typedef struct pem_ctx_st { + int type; /* what type of object */ + struct { + int version; + int mode; + } proc_type; + + char *domain; + + struct { + int cipher; + /*- + unused, and wrong size + unsigned char iv[8]; */ + } DEK_info; + + PEM_USER *originator; + + int num_recipient; + PEM_USER **recipient; + +/*- + XXX(ben): don#t think this is used! + STACK *x509_chain; / * certificate chain */ + EVP_MD *md; /* signature type */ + + int md_enc; /* is the md encrypted or not? */ + int md_len; /* length of md_data */ + char *md_data; /* message digest, could be pkey encrypted */ + + EVP_CIPHER *dec; /* date encryption cipher */ + int key_len; /* key length */ + unsigned char *key; /* key */ + /*- + unused, and wrong size + unsigned char iv[8]; */ + + int data_enc; /* is the data encrypted */ + int data_len; + unsigned char *data; +} PEM_CTX; + +/* + * These macros make the PEM_read/PEM_write functions easier to maintain and + * write. Now they are all implemented with either: IMPLEMENT_PEM_rw(...) or + * IMPLEMENT_PEM_rw_cb(...) + */ + +# ifdef OPENSSL_NO_FP_API + +# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) /**/ +# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) /**/ +# else + +# define IMPLEMENT_PEM_read_fp(name, type, str, asn1) \ +type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \ +} + +# define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, const type *x) \ +{ \ +return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) \ +int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, \ + void *u) \ + { \ + return PEM_ASN1_write((i2d_of_void *)i2d_##asn1,str,fp,x,enc,kstr,klen,cb,u); \ + } + +# endif + +# define IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ +type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \ +} + +# define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, const type *x) \ +{ \ +return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,NULL,NULL,0,NULL,NULL); \ +} + +# define IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ +int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u) \ + { \ + return PEM_ASN1_write_bio((i2d_of_void *)i2d_##asn1,str,bp,(void *)x,enc,kstr,klen,cb,u); \ + } + +# define IMPLEMENT_PEM_write(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_fp_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_write_cb_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_bio_const(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb_fp_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_read_bio(name, type, str, asn1) \ + IMPLEMENT_PEM_read_fp(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw_const(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_const(name, type, str, asn1) + +# define IMPLEMENT_PEM_rw_cb(name, type, str, asn1) \ + IMPLEMENT_PEM_read(name, type, str, asn1) \ + IMPLEMENT_PEM_write_cb(name, type, str, asn1) + +/* These are the same except they are for the declarations */ + +# if defined(OPENSSL_NO_FP_API) + +# define DECLARE_PEM_read_fp(name, type) /**/ +# define DECLARE_PEM_write_fp(name, type) /**/ +# define DECLARE_PEM_write_cb_fp(name, type) /**/ +# else + +# define DECLARE_PEM_read_fp(name, type) \ + type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x); + +# define DECLARE_PEM_write_fp_const(name, type) \ + int PEM_write_##name(FILE *fp, const type *x); + +# define DECLARE_PEM_write_cb_fp(name, type) \ + int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +# endif + +# ifndef OPENSSL_NO_BIO +# define DECLARE_PEM_read_bio(name, type) \ + type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u); + +# define DECLARE_PEM_write_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x); + +# define DECLARE_PEM_write_bio_const(name, type) \ + int PEM_write_bio_##name(BIO *bp, const type *x); + +# define DECLARE_PEM_write_cb_bio(name, type) \ + int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +# else + +# define DECLARE_PEM_read_bio(name, type) /**/ +# define DECLARE_PEM_write_bio(name, type) /**/ +# define DECLARE_PEM_write_bio_const(name, type) /**/ +# define DECLARE_PEM_write_cb_bio(name, type) /**/ +# endif +# define DECLARE_PEM_write(name, type) \ + DECLARE_PEM_write_bio(name, type) \ + DECLARE_PEM_write_fp(name, type) +# define DECLARE_PEM_write_const(name, type) \ + DECLARE_PEM_write_bio_const(name, type) \ + DECLARE_PEM_write_fp_const(name, type) +# define DECLARE_PEM_write_cb(name, type) \ + DECLARE_PEM_write_cb_bio(name, type) \ + DECLARE_PEM_write_cb_fp(name, type) +# define DECLARE_PEM_read(name, type) \ + DECLARE_PEM_read_bio(name, type) \ + DECLARE_PEM_read_fp(name, type) +# define DECLARE_PEM_rw(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write(name, type) +# define DECLARE_PEM_rw_const(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_const(name, type) +# define DECLARE_PEM_rw_cb(name, type) \ + DECLARE_PEM_read(name, type) \ + DECLARE_PEM_write_cb(name, type) +# if 1 +/* "userdata": new with OpenSSL 0.9.4 */ +typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata); +# else +/* OpenSSL 0.9.3, 0.9.3a */ +typedef int pem_password_cb (char *buf, int size, int rwflag); +# endif + +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); +int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *len, + pem_password_cb *callback, void *u); + +# ifndef OPENSSL_NO_BIO +int PEM_read_bio(BIO *bp, char **name, char **header, + unsigned char **data, long *len); +int PEM_write_bio(BIO *bp, const char *name, char *hdr, unsigned char *data, + long len); +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, + void *u); +void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, void *x, + const EVP_CIPHER *enc, unsigned char *kstr, int klen, + pem_password_cb *cb, void *u); + +STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); +int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cd, void *u); +# endif + +int PEM_read(FILE *fp, char **name, char **header, + unsigned char **data, long *len); +int PEM_write(FILE *fp, char *name, char *hdr, unsigned char *data, long len); +void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, + pem_password_cb *cb, void *u); +int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *callback, void *u); +STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u); + +int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, + EVP_MD *md_type, unsigned char **ek, int *ekl, + unsigned char *iv, EVP_PKEY **pubk, int npubk); +void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl, + unsigned char *in, int inl); +int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl, + unsigned char *out, int *outl, EVP_PKEY *priv); + +void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type); +void PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *d, unsigned int cnt); +int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey); + +int PEM_def_callback(char *buf, int num, int w, void *key); +void PEM_proc_type(char *buf, int type); +void PEM_dek_info(char *buf, const char *type, int len, char *str); + +# include + +DECLARE_PEM_rw(X509, X509) +DECLARE_PEM_rw(X509_AUX, X509) +DECLARE_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR) +DECLARE_PEM_rw(X509_REQ, X509_REQ) +DECLARE_PEM_write(X509_REQ_NEW, X509_REQ) +DECLARE_PEM_rw(X509_CRL, X509_CRL) +DECLARE_PEM_rw(PKCS7, PKCS7) +DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE) +DECLARE_PEM_rw(PKCS8, X509_SIG) +DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) +# ifndef OPENSSL_NO_RSA +DECLARE_PEM_rw_cb(RSAPrivateKey, RSA) +DECLARE_PEM_rw_const(RSAPublicKey, RSA) +DECLARE_PEM_rw(RSA_PUBKEY, RSA) +# endif +# ifndef OPENSSL_NO_DSA +DECLARE_PEM_rw_cb(DSAPrivateKey, DSA) +DECLARE_PEM_rw(DSA_PUBKEY, DSA) +DECLARE_PEM_rw_const(DSAparams, DSA) +# endif +# ifndef OPENSSL_NO_EC +DECLARE_PEM_rw_const(ECPKParameters, EC_GROUP) +DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) +DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) +# endif +# ifndef OPENSSL_NO_DH +DECLARE_PEM_rw_const(DHparams, DH) +# endif +DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) +DECLARE_PEM_rw(PUBKEY, EVP_PKEY) + +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, + char *, int, pem_password_cb *, void *); +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u); + +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u); + +int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cd, + void *u); + +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x); +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x); + +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length); +EVP_PKEY *b2i_PrivateKey_bio(BIO *in); +EVP_PKEY *b2i_PublicKey_bio(BIO *in); +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk); +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk); +# ifndef OPENSSL_NO_RC4 +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u); +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u); +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_PEM_strings(void); + +/* Error codes for the PEM functions. */ + +/* Function codes. */ +# define PEM_F_B2I_DSS 127 +# define PEM_F_B2I_PVK_BIO 128 +# define PEM_F_B2I_RSA 129 +# define PEM_F_CHECK_BITLEN_DSA 130 +# define PEM_F_CHECK_BITLEN_RSA 131 +# define PEM_F_D2I_PKCS8PRIVATEKEY_BIO 120 +# define PEM_F_D2I_PKCS8PRIVATEKEY_FP 121 +# define PEM_F_DO_B2I 132 +# define PEM_F_DO_B2I_BIO 133 +# define PEM_F_DO_BLOB_HEADER 134 +# define PEM_F_DO_PK8PKEY 126 +# define PEM_F_DO_PK8PKEY_FP 125 +# define PEM_F_DO_PVK_BODY 135 +# define PEM_F_DO_PVK_HEADER 136 +# define PEM_F_I2B_PVK 137 +# define PEM_F_I2B_PVK_BIO 138 +# define PEM_F_LOAD_IV 101 +# define PEM_F_PEM_ASN1_READ 102 +# define PEM_F_PEM_ASN1_READ_BIO 103 +# define PEM_F_PEM_ASN1_WRITE 104 +# define PEM_F_PEM_ASN1_WRITE_BIO 105 +# define PEM_F_PEM_DEF_CALLBACK 100 +# define PEM_F_PEM_DO_HEADER 106 +# define PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY 118 +# define PEM_F_PEM_GET_EVP_CIPHER_INFO 107 +# define PEM_F_PEM_PK8PKEY 119 +# define PEM_F_PEM_READ 108 +# define PEM_F_PEM_READ_BIO 109 +# define PEM_F_PEM_READ_BIO_PARAMETERS 140 +# define PEM_F_PEM_READ_BIO_PRIVATEKEY 123 +# define PEM_F_PEM_READ_PRIVATEKEY 124 +# define PEM_F_PEM_SEALFINAL 110 +# define PEM_F_PEM_SEALINIT 111 +# define PEM_F_PEM_SIGNFINAL 112 +# define PEM_F_PEM_WRITE 113 +# define PEM_F_PEM_WRITE_BIO 114 +# define PEM_F_PEM_WRITE_PRIVATEKEY 139 +# define PEM_F_PEM_X509_INFO_READ 115 +# define PEM_F_PEM_X509_INFO_READ_BIO 116 +# define PEM_F_PEM_X509_INFO_WRITE_BIO 117 + +/* Reason codes. */ +# define PEM_R_BAD_BASE64_DECODE 100 +# define PEM_R_BAD_DECRYPT 101 +# define PEM_R_BAD_END_LINE 102 +# define PEM_R_BAD_IV_CHARS 103 +# define PEM_R_BAD_MAGIC_NUMBER 116 +# define PEM_R_BAD_PASSWORD_READ 104 +# define PEM_R_BAD_VERSION_NUMBER 117 +# define PEM_R_BIO_WRITE_FAILURE 118 +# define PEM_R_CIPHER_IS_NULL 127 +# define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 115 +# define PEM_R_EXPECTING_PRIVATE_KEY_BLOB 119 +# define PEM_R_EXPECTING_PUBLIC_KEY_BLOB 120 +# define PEM_R_INCONSISTENT_HEADER 121 +# define PEM_R_KEYBLOB_HEADER_PARSE_ERROR 122 +# define PEM_R_KEYBLOB_TOO_SHORT 123 +# define PEM_R_NOT_DEK_INFO 105 +# define PEM_R_NOT_ENCRYPTED 106 +# define PEM_R_NOT_PROC_TYPE 107 +# define PEM_R_NO_START_LINE 108 +# define PEM_R_PROBLEMS_GETTING_PASSWORD 109 +# define PEM_R_PUBLIC_KEY_NO_RSA 110 +# define PEM_R_PVK_DATA_TOO_SHORT 124 +# define PEM_R_PVK_TOO_SHORT 125 +# define PEM_R_READ_KEY 111 +# define PEM_R_SHORT_HEADER 112 +# define PEM_R_UNSUPPORTED_CIPHER 113 +# define PEM_R_UNSUPPORTED_ENCRYPTION 114 +# define PEM_R_UNSUPPORTED_KEY_COMPONENTS 126 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/pem/pem2.h b/libs/openssl/crypto/pem/pem2.h new file mode 100644 index 00000000..84897d5e --- /dev/null +++ b/libs/openssl/crypto/pem/pem2.h @@ -0,0 +1,70 @@ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * This header only exists to break a circular dependency between pem and err + * Ben 30 Jan 1999. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef HEADER_PEM_H +void ERR_load_PEM_strings(void); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/libs/openssl/crypto/pem/pem_all.c b/libs/openssl/crypto/pem/pem_all.c new file mode 100644 index 00000000..64b8ba7c --- /dev/null +++ b/libs/openssl/crypto/pem/pem_all.c @@ -0,0 +1,426 @@ +/* crypto/pem/pem_all.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#ifndef OPENSSL_NO_DSA +# include +#endif +#ifndef OPENSSL_NO_DH +# include +#endif + +#ifndef OPENSSL_NO_RSA +static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa); +#endif +#ifndef OPENSSL_NO_DSA +static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa); +#endif + +#ifndef OPENSSL_NO_EC +static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey); +#endif + +IMPLEMENT_PEM_rw(X509_REQ, X509_REQ, PEM_STRING_X509_REQ, X509_REQ) + +IMPLEMENT_PEM_write(X509_REQ_NEW, X509_REQ, PEM_STRING_X509_REQ_OLD, X509_REQ) +IMPLEMENT_PEM_rw(X509_CRL, X509_CRL, PEM_STRING_X509_CRL, X509_CRL) +IMPLEMENT_PEM_rw(PKCS7, PKCS7, PEM_STRING_PKCS7, PKCS7) + +IMPLEMENT_PEM_rw(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE, + PEM_STRING_X509, NETSCAPE_CERT_SEQUENCE) +#ifndef OPENSSL_NO_RSA +/* + * We treat RSA or DSA private keys as a special case. For private keys we + * read in an EVP_PKEY structure with PEM_read_bio_PrivateKey() and extract + * the relevant private key: this means can handle "traditional" and PKCS#8 + * formats transparently. + */ +static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa) +{ + RSA *rtmp; + if (!key) + return NULL; + rtmp = EVP_PKEY_get1_RSA(key); + EVP_PKEY_free(key); + if (!rtmp) + return NULL; + if (rsa) { + RSA_free(*rsa); + *rsa = rtmp; + } + return rtmp; +} + +RSA *PEM_read_bio_RSAPrivateKey(BIO *bp, RSA **rsa, pem_password_cb *cb, + void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_rsa(pktmp, rsa); +} + +# ifndef OPENSSL_NO_FP_API + +RSA *PEM_read_RSAPrivateKey(FILE *fp, RSA **rsa, pem_password_cb *cb, void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_rsa(pktmp, rsa); +} + +# endif + +# ifdef OPENSSL_FIPS + +int PEM_write_bio_RSAPrivateKey(BIO *bp, RSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + if (FIPS_mode()) { + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_RSA(k, x); + + ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; + } else + return PEM_ASN1_write_bio((i2d_of_void *)i2d_RSAPrivateKey, + PEM_STRING_RSA, bp, x, enc, kstr, klen, cb, + u); +} + +# ifndef OPENSSL_NO_FP_API +int PEM_write_RSAPrivateKey(FILE *fp, RSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + if (FIPS_mode()) { + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + + EVP_PKEY_set1_RSA(k, x); + + ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; + } else + return PEM_ASN1_write((i2d_of_void *)i2d_RSAPrivateKey, + PEM_STRING_RSA, fp, x, enc, kstr, klen, cb, u); +} +# endif + +# else + +IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, + RSAPrivateKey) +# endif +IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, + RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, + PEM_STRING_PUBLIC, + RSA_PUBKEY) +#endif +#ifndef OPENSSL_NO_DSA +static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa) +{ + DSA *dtmp; + if (!key) + return NULL; + dtmp = EVP_PKEY_get1_DSA(key); + EVP_PKEY_free(key); + if (!dtmp) + return NULL; + if (dsa) { + DSA_free(*dsa); + *dsa = dtmp; + } + return dtmp; +} + +DSA *PEM_read_bio_DSAPrivateKey(BIO *bp, DSA **dsa, pem_password_cb *cb, + void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ +} + +# ifdef OPENSSL_FIPS + +int PEM_write_bio_DSAPrivateKey(BIO *bp, DSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + if (FIPS_mode()) { + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_DSA(k, x); + + ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; + } else + return PEM_ASN1_write_bio((i2d_of_void *)i2d_DSAPrivateKey, + PEM_STRING_DSA, bp, x, enc, kstr, klen, cb, + u); +} + +# ifndef OPENSSL_NO_FP_API +int PEM_write_DSAPrivateKey(FILE *fp, DSA *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + if (FIPS_mode()) { + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_DSA(k, x); + ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; + } else + return PEM_ASN1_write((i2d_of_void *)i2d_DSAPrivateKey, + PEM_STRING_DSA, fp, x, enc, kstr, klen, cb, u); +} +# endif + +# else + +IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, + DSAPrivateKey) +# endif + IMPLEMENT_PEM_rw(DSA_PUBKEY, DSA, PEM_STRING_PUBLIC, DSA_PUBKEY) +# ifndef OPENSSL_NO_FP_API +DSA *PEM_read_DSAPrivateKey(FILE *fp, DSA **dsa, pem_password_cb *cb, void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_dsa(pktmp, dsa); /* will free pktmp */ +} + +# endif + +IMPLEMENT_PEM_rw_const(DSAparams, DSA, PEM_STRING_DSAPARAMS, DSAparams) +#endif +#ifndef OPENSSL_NO_EC +static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey) +{ + EC_KEY *dtmp; + if (!key) + return NULL; + dtmp = EVP_PKEY_get1_EC_KEY(key); + EVP_PKEY_free(key); + if (!dtmp) + return NULL; + if (eckey) { + EC_KEY_free(*eckey); + *eckey = dtmp; + } + return dtmp; +} + +EC_KEY *PEM_read_bio_ECPrivateKey(BIO *bp, EC_KEY **key, pem_password_cb *cb, + void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_bio_PrivateKey(bp, NULL, cb, u); + return pkey_get_eckey(pktmp, key); /* will free pktmp */ +} + +IMPLEMENT_PEM_rw_const(ECPKParameters, EC_GROUP, PEM_STRING_ECPARAMETERS, + ECPKParameters) +# ifdef OPENSSL_FIPS +int PEM_write_bio_ECPrivateKey(BIO *bp, EC_KEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + if (FIPS_mode()) { + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_EC_KEY(k, x); + + ret = PEM_write_bio_PrivateKey(bp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; + } else + return PEM_ASN1_write_bio((i2d_of_void *)i2d_ECPrivateKey, + PEM_STRING_ECPRIVATEKEY, + bp, x, enc, kstr, klen, cb, u); +} + +# ifndef OPENSSL_NO_FP_API +int PEM_write_ECPrivateKey(FILE *fp, EC_KEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + if (FIPS_mode()) { + EVP_PKEY *k; + int ret; + k = EVP_PKEY_new(); + if (!k) + return 0; + EVP_PKEY_set1_EC_KEY(k, x); + ret = PEM_write_PrivateKey(fp, k, enc, kstr, klen, cb, u); + EVP_PKEY_free(k); + return ret; + } else + return PEM_ASN1_write((i2d_of_void *)i2d_ECPrivateKey, + PEM_STRING_ECPRIVATEKEY, + fp, x, enc, kstr, klen, cb, u); +} +# endif + +# else + IMPLEMENT_PEM_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, + ECPrivateKey) +# endif +IMPLEMENT_PEM_rw(EC_PUBKEY, EC_KEY, PEM_STRING_PUBLIC, EC_PUBKEY) +# ifndef OPENSSL_NO_FP_API +EC_KEY *PEM_read_ECPrivateKey(FILE *fp, EC_KEY **eckey, pem_password_cb *cb, + void *u) +{ + EVP_PKEY *pktmp; + pktmp = PEM_read_PrivateKey(fp, NULL, cb, u); + return pkey_get_eckey(pktmp, eckey); /* will free pktmp */ +} + +# endif + +#endif + +#ifndef OPENSSL_NO_DH + +IMPLEMENT_PEM_rw_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) +#endif + IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) diff --git a/libs/openssl/crypto/pem/pem_err.c b/libs/openssl/crypto/pem/pem_err.c new file mode 100644 index 00000000..702c5ade --- /dev/null +++ b/libs/openssl/crypto/pem/pem_err.c @@ -0,0 +1,166 @@ +/* crypto/pem/pem_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PEM,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PEM,0,reason) + +static ERR_STRING_DATA PEM_str_functs[] = { + {ERR_FUNC(PEM_F_B2I_DSS), "B2I_DSS"}, + {ERR_FUNC(PEM_F_B2I_PVK_BIO), "b2i_PVK_bio"}, + {ERR_FUNC(PEM_F_B2I_RSA), "B2I_RSA"}, + {ERR_FUNC(PEM_F_CHECK_BITLEN_DSA), "CHECK_BITLEN_DSA"}, + {ERR_FUNC(PEM_F_CHECK_BITLEN_RSA), "CHECK_BITLEN_RSA"}, + {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_BIO), "d2i_PKCS8PrivateKey_bio"}, + {ERR_FUNC(PEM_F_D2I_PKCS8PRIVATEKEY_FP), "d2i_PKCS8PrivateKey_fp"}, + {ERR_FUNC(PEM_F_DO_B2I), "DO_B2I"}, + {ERR_FUNC(PEM_F_DO_B2I_BIO), "DO_B2I_BIO"}, + {ERR_FUNC(PEM_F_DO_BLOB_HEADER), "DO_BLOB_HEADER"}, + {ERR_FUNC(PEM_F_DO_PK8PKEY), "DO_PK8PKEY"}, + {ERR_FUNC(PEM_F_DO_PK8PKEY_FP), "DO_PK8PKEY_FP"}, + {ERR_FUNC(PEM_F_DO_PVK_BODY), "DO_PVK_BODY"}, + {ERR_FUNC(PEM_F_DO_PVK_HEADER), "DO_PVK_HEADER"}, + {ERR_FUNC(PEM_F_I2B_PVK), "I2B_PVK"}, + {ERR_FUNC(PEM_F_I2B_PVK_BIO), "i2b_PVK_bio"}, + {ERR_FUNC(PEM_F_LOAD_IV), "LOAD_IV"}, + {ERR_FUNC(PEM_F_PEM_ASN1_READ), "PEM_ASN1_read"}, + {ERR_FUNC(PEM_F_PEM_ASN1_READ_BIO), "PEM_ASN1_read_bio"}, + {ERR_FUNC(PEM_F_PEM_ASN1_WRITE), "PEM_ASN1_write"}, + {ERR_FUNC(PEM_F_PEM_ASN1_WRITE_BIO), "PEM_ASN1_write_bio"}, + {ERR_FUNC(PEM_F_PEM_DEF_CALLBACK), "PEM_def_callback"}, + {ERR_FUNC(PEM_F_PEM_DO_HEADER), "PEM_do_header"}, + {ERR_FUNC(PEM_F_PEM_F_PEM_WRITE_PKCS8PRIVATEKEY), + "PEM_F_PEM_WRITE_PKCS8PRIVATEKEY"}, + {ERR_FUNC(PEM_F_PEM_GET_EVP_CIPHER_INFO), "PEM_get_EVP_CIPHER_INFO"}, + {ERR_FUNC(PEM_F_PEM_PK8PKEY), "PEM_PK8PKEY"}, + {ERR_FUNC(PEM_F_PEM_READ), "PEM_read"}, + {ERR_FUNC(PEM_F_PEM_READ_BIO), "PEM_read_bio"}, + {ERR_FUNC(PEM_F_PEM_READ_BIO_PARAMETERS), "PEM_read_bio_Parameters"}, + {ERR_FUNC(PEM_F_PEM_READ_BIO_PRIVATEKEY), "PEM_READ_BIO_PRIVATEKEY"}, + {ERR_FUNC(PEM_F_PEM_READ_PRIVATEKEY), "PEM_READ_PRIVATEKEY"}, + {ERR_FUNC(PEM_F_PEM_SEALFINAL), "PEM_SealFinal"}, + {ERR_FUNC(PEM_F_PEM_SEALINIT), "PEM_SealInit"}, + {ERR_FUNC(PEM_F_PEM_SIGNFINAL), "PEM_SignFinal"}, + {ERR_FUNC(PEM_F_PEM_WRITE), "PEM_write"}, + {ERR_FUNC(PEM_F_PEM_WRITE_BIO), "PEM_write_bio"}, + {ERR_FUNC(PEM_F_PEM_WRITE_PRIVATEKEY), "PEM_WRITE_PRIVATEKEY"}, + {ERR_FUNC(PEM_F_PEM_X509_INFO_READ), "PEM_X509_INFO_read"}, + {ERR_FUNC(PEM_F_PEM_X509_INFO_READ_BIO), "PEM_X509_INFO_read_bio"}, + {ERR_FUNC(PEM_F_PEM_X509_INFO_WRITE_BIO), "PEM_X509_INFO_write_bio"}, + {0, NULL} +}; + +static ERR_STRING_DATA PEM_str_reasons[] = { + {ERR_REASON(PEM_R_BAD_BASE64_DECODE), "bad base64 decode"}, + {ERR_REASON(PEM_R_BAD_DECRYPT), "bad decrypt"}, + {ERR_REASON(PEM_R_BAD_END_LINE), "bad end line"}, + {ERR_REASON(PEM_R_BAD_IV_CHARS), "bad iv chars"}, + {ERR_REASON(PEM_R_BAD_MAGIC_NUMBER), "bad magic number"}, + {ERR_REASON(PEM_R_BAD_PASSWORD_READ), "bad password read"}, + {ERR_REASON(PEM_R_BAD_VERSION_NUMBER), "bad version number"}, + {ERR_REASON(PEM_R_BIO_WRITE_FAILURE), "bio write failure"}, + {ERR_REASON(PEM_R_CIPHER_IS_NULL), "cipher is null"}, + {ERR_REASON(PEM_R_ERROR_CONVERTING_PRIVATE_KEY), + "error converting private key"}, + {ERR_REASON(PEM_R_EXPECTING_PRIVATE_KEY_BLOB), + "expecting private key blob"}, + {ERR_REASON(PEM_R_EXPECTING_PUBLIC_KEY_BLOB), + "expecting public key blob"}, + {ERR_REASON(PEM_R_INCONSISTENT_HEADER), "inconsistent header"}, + {ERR_REASON(PEM_R_KEYBLOB_HEADER_PARSE_ERROR), + "keyblob header parse error"}, + {ERR_REASON(PEM_R_KEYBLOB_TOO_SHORT), "keyblob too short"}, + {ERR_REASON(PEM_R_NOT_DEK_INFO), "not dek info"}, + {ERR_REASON(PEM_R_NOT_ENCRYPTED), "not encrypted"}, + {ERR_REASON(PEM_R_NOT_PROC_TYPE), "not proc type"}, + {ERR_REASON(PEM_R_NO_START_LINE), "no start line"}, + {ERR_REASON(PEM_R_PROBLEMS_GETTING_PASSWORD), + "problems getting password"}, + {ERR_REASON(PEM_R_PUBLIC_KEY_NO_RSA), "public key no rsa"}, + {ERR_REASON(PEM_R_PVK_DATA_TOO_SHORT), "pvk data too short"}, + {ERR_REASON(PEM_R_PVK_TOO_SHORT), "pvk too short"}, + {ERR_REASON(PEM_R_READ_KEY), "read key"}, + {ERR_REASON(PEM_R_SHORT_HEADER), "short header"}, + {ERR_REASON(PEM_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, + {ERR_REASON(PEM_R_UNSUPPORTED_ENCRYPTION), "unsupported encryption"}, + {ERR_REASON(PEM_R_UNSUPPORTED_KEY_COMPONENTS), + "unsupported key components"}, + {0, NULL} +}; + +#endif + +void ERR_load_PEM_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(PEM_str_functs[0].error) == NULL) { + ERR_load_strings(0, PEM_str_functs); + ERR_load_strings(0, PEM_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/pem/pem_info.c b/libs/openssl/crypto/pem/pem_info.c new file mode 100644 index 00000000..4d736a1d --- /dev/null +++ b/libs/openssl/crypto/pem/pem_info.c @@ -0,0 +1,394 @@ +/* crypto/pem/pem_info.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#ifndef OPENSSL_NO_DSA +# include +#endif + +#ifndef OPENSSL_NO_FP_API +STACK_OF(X509_INFO) *PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u) +{ + BIO *b; + STACK_OF(X509_INFO) *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerr(PEM_F_PEM_X509_INFO_READ, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_X509_INFO_read_bio(b, sk, cb, u); + BIO_free(b); + return (ret); +} +#endif + +STACK_OF(X509_INFO) *PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, + pem_password_cb *cb, void *u) +{ + X509_INFO *xi = NULL; + char *name = NULL, *header = NULL; + void *pp; + unsigned char *data = NULL; + const unsigned char *p; + long len, error = 0; + int ok = 0; + STACK_OF(X509_INFO) *ret = NULL; + unsigned int i, raw, ptype; + d2i_of_void *d2i = 0; + + if (sk == NULL) { + if ((ret = sk_X509_INFO_new_null()) == NULL) { + PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + } else + ret = sk; + + if ((xi = X509_INFO_new()) == NULL) + goto err; + for (;;) { + raw = 0; + ptype = 0; + i = PEM_read_bio(bp, &name, &header, &data, &len); + if (i == 0) { + error = ERR_GET_REASON(ERR_peek_last_error()); + if (error == PEM_R_NO_START_LINE) { + ERR_clear_error(); + break; + } + goto err; + } + start: + if ((strcmp(name, PEM_STRING_X509) == 0) || + (strcmp(name, PEM_STRING_X509_OLD) == 0)) { + d2i = (D2I_OF(void)) d2i_X509; + if (xi->x509 != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + goto start; + } + pp = &(xi->x509); + } else if ((strcmp(name, PEM_STRING_X509_TRUSTED) == 0)) { + d2i = (D2I_OF(void)) d2i_X509_AUX; + if (xi->x509 != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + goto start; + } + pp = &(xi->x509); + } else if (strcmp(name, PEM_STRING_X509_CRL) == 0) { + d2i = (D2I_OF(void)) d2i_X509_CRL; + if (xi->crl != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + goto start; + } + pp = &(xi->crl); + } else +#ifndef OPENSSL_NO_RSA + if (strcmp(name, PEM_STRING_RSA) == 0) { + d2i = (D2I_OF(void)) d2i_RSAPrivateKey; + if (xi->x_pkey != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + goto start; + } + + xi->enc_data = NULL; + xi->enc_len = 0; + + xi->x_pkey = X509_PKEY_new(); + if (xi->x_pkey == NULL) + goto err; + ptype = EVP_PKEY_RSA; + pp = &xi->x_pkey->dec_pkey; + if ((int)strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else +#endif +#ifndef OPENSSL_NO_DSA + if (strcmp(name, PEM_STRING_DSA) == 0) { + d2i = (D2I_OF(void)) d2i_DSAPrivateKey; + if (xi->x_pkey != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + goto start; + } + + xi->enc_data = NULL; + xi->enc_len = 0; + + xi->x_pkey = X509_PKEY_new(); + if (xi->x_pkey == NULL) + goto err; + ptype = EVP_PKEY_DSA; + pp = &xi->x_pkey->dec_pkey; + if ((int)strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else +#endif +#ifndef OPENSSL_NO_EC + if (strcmp(name, PEM_STRING_ECPRIVATEKEY) == 0) { + d2i = (D2I_OF(void)) d2i_ECPrivateKey; + if (xi->x_pkey != NULL) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + if ((xi = X509_INFO_new()) == NULL) + goto err; + goto start; + } + + xi->enc_data = NULL; + xi->enc_len = 0; + + xi->x_pkey = X509_PKEY_new(); + if (xi->x_pkey == NULL) + goto err; + ptype = EVP_PKEY_EC; + pp = &xi->x_pkey->dec_pkey; + if ((int)strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else +#endif + { + d2i = NULL; + pp = NULL; + } + + if (d2i != NULL) { + if (!raw) { + EVP_CIPHER_INFO cipher; + + if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) + goto err; + if (!PEM_do_header(&cipher, data, &len, cb, u)) + goto err; + p = data; + if (ptype) { + if (!d2i_PrivateKey(ptype, pp, &p, len)) { + PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB); + goto err; + } + } else if (d2i(pp, &p, len) == NULL) { + PEMerr(PEM_F_PEM_X509_INFO_READ_BIO, ERR_R_ASN1_LIB); + goto err; + } + } else { /* encrypted RSA data */ + if (!PEM_get_EVP_CIPHER_INFO(header, &xi->enc_cipher)) + goto err; + xi->enc_data = (char *)data; + xi->enc_len = (int)len; + data = NULL; + } + } else { + /* unknown */ + } + if (name != NULL) + OPENSSL_free(name); + if (header != NULL) + OPENSSL_free(header); + if (data != NULL) + OPENSSL_free(data); + name = NULL; + header = NULL; + data = NULL; + } + + /* + * if the last one hasn't been pushed yet and there is anything in it + * then add it to the stack ... + */ + if ((xi->x509 != NULL) || (xi->crl != NULL) || + (xi->x_pkey != NULL) || (xi->enc_data != NULL)) { + if (!sk_X509_INFO_push(ret, xi)) + goto err; + xi = NULL; + } + ok = 1; + err: + if (xi != NULL) + X509_INFO_free(xi); + if (!ok) { + for (i = 0; ((int)i) < sk_X509_INFO_num(ret); i++) { + xi = sk_X509_INFO_value(ret, i); + X509_INFO_free(xi); + } + if (ret != sk) + sk_X509_INFO_free(ret); + ret = NULL; + } + + if (name != NULL) + OPENSSL_free(name); + if (header != NULL) + OPENSSL_free(header); + if (data != NULL) + OPENSSL_free(data); + return (ret); +} + +/* A TJH addition */ +int PEM_X509_INFO_write_bio(BIO *bp, X509_INFO *xi, EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + EVP_CIPHER_CTX ctx; + int i, ret = 0; + unsigned char *data = NULL; + const char *objstr = NULL; + char buf[PEM_BUFSIZE]; + unsigned char *iv = NULL; + + if (enc != NULL) { + objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); + if (objstr == NULL) { + PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + } + + /* + * now for the fun part ... if we have a private key then we have to be + * able to handle a not-yet-decrypted key being written out correctly ... + * if it is decrypted or it is non-encrypted then we use the base code + */ + if (xi->x_pkey != NULL) { + if ((xi->enc_data != NULL) && (xi->enc_len > 0)) { + if (enc == NULL) { + PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, PEM_R_CIPHER_IS_NULL); + goto err; + } + + /* copy from weirdo names into more normal things */ + iv = xi->enc_cipher.iv; + data = (unsigned char *)xi->enc_data; + i = xi->enc_len; + + /* + * we take the encryption data from the internal stuff rather + * than what the user has passed us ... as we have to match + * exactly for some strange reason + */ + objstr = OBJ_nid2sn(EVP_CIPHER_nid(xi->enc_cipher.cipher)); + if (objstr == NULL) { + PEMerr(PEM_F_PEM_X509_INFO_WRITE_BIO, + PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + + /* create the right magic header stuff */ + OPENSSL_assert(strlen(objstr) + 23 + 2 * enc->iv_len + 13 <= + sizeof buf); + buf[0] = '\0'; + PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); + PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv); + + /* use the normal code to write things out */ + i = PEM_write_bio(bp, PEM_STRING_RSA, buf, data, i); + if (i <= 0) + goto err; + } else { + /* Add DSA/DH */ +#ifndef OPENSSL_NO_RSA + /* normal optionally encrypted stuff */ + if (PEM_write_bio_RSAPrivateKey(bp, + xi->x_pkey->dec_pkey->pkey.rsa, + enc, kstr, klen, cb, u) <= 0) + goto err; +#endif + } + } + + /* if we have a certificate then write it out now */ + if ((xi->x509 != NULL) && (PEM_write_bio_X509(bp, xi->x509) <= 0)) + goto err; + + /* + * we are ignoring anything else that is loaded into the X509_INFO + * structure for the moment ... as I don't need it so I'm not coding it + * here and Eric can do it when this makes it into the base library --tjh + */ + + ret = 1; + + err: + OPENSSL_cleanse((char *)&ctx, sizeof(ctx)); + OPENSSL_cleanse(buf, PEM_BUFSIZE); + return (ret); +} diff --git a/libs/openssl/crypto/pem/pem_lib.c b/libs/openssl/crypto/pem/pem_lib.c new file mode 100644 index 00000000..ab45a84f --- /dev/null +++ b/libs/openssl/crypto/pem/pem_lib.c @@ -0,0 +1,860 @@ +/* crypto/pem/pem_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include +#include "asn1_locl.h" +#ifndef OPENSSL_NO_DES +# include +#endif +#ifndef OPENSSL_NO_ENGINE +# include +#endif + +const char PEM_version[] = "PEM" OPENSSL_VERSION_PTEXT; + +#define MIN_LENGTH 4 + +static int load_iv(char **fromp, unsigned char *to, int num); +static int check_pem(const char *nm, const char *name); +int pem_check_suffix(const char *pem_str, const char *suffix); + +int PEM_def_callback(char *buf, int num, int w, void *key) +{ +#ifdef OPENSSL_NO_FP_API + /* + * We should not ever call the default callback routine from windows. + */ + PEMerr(PEM_F_PEM_DEF_CALLBACK, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (-1); +#else + int i, j; + const char *prompt; + if (key) { + i = strlen(key); + i = (i > num) ? num : i; + memcpy(buf, key, i); + return (i); + } + + prompt = EVP_get_pw_prompt(); + if (prompt == NULL) + prompt = "Enter PEM pass phrase:"; + + for (;;) { + i = EVP_read_pw_string_min(buf, MIN_LENGTH, num, prompt, w); + if (i != 0) { + PEMerr(PEM_F_PEM_DEF_CALLBACK, PEM_R_PROBLEMS_GETTING_PASSWORD); + memset(buf, 0, (unsigned int)num); + return (-1); + } + j = strlen(buf); + if (j < MIN_LENGTH) { + fprintf(stderr, + "phrase is too short, needs to be at least %d chars\n", + MIN_LENGTH); + } else + break; + } + return (j); +#endif +} + +void PEM_proc_type(char *buf, int type) +{ + const char *str; + + if (type == PEM_TYPE_ENCRYPTED) + str = "ENCRYPTED"; + else if (type == PEM_TYPE_MIC_CLEAR) + str = "MIC-CLEAR"; + else if (type == PEM_TYPE_MIC_ONLY) + str = "MIC-ONLY"; + else + str = "BAD-TYPE"; + + BUF_strlcat(buf, "Proc-Type: 4,", PEM_BUFSIZE); + BUF_strlcat(buf, str, PEM_BUFSIZE); + BUF_strlcat(buf, "\n", PEM_BUFSIZE); +} + +void PEM_dek_info(char *buf, const char *type, int len, char *str) +{ + static const unsigned char map[17] = "0123456789ABCDEF"; + long i; + int j; + + BUF_strlcat(buf, "DEK-Info: ", PEM_BUFSIZE); + BUF_strlcat(buf, type, PEM_BUFSIZE); + BUF_strlcat(buf, ",", PEM_BUFSIZE); + j = strlen(buf); + if (j + (len * 2) + 1 > PEM_BUFSIZE) + return; + for (i = 0; i < len; i++) { + buf[j + i * 2] = map[(str[i] >> 4) & 0x0f]; + buf[j + i * 2 + 1] = map[(str[i]) & 0x0f]; + } + buf[j + i * 2] = '\n'; + buf[j + i * 2 + 1] = '\0'; +} + +#ifndef OPENSSL_NO_FP_API +void *PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, + pem_password_cb *cb, void *u) +{ + BIO *b; + void *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerr(PEM_F_PEM_ASN1_READ, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_ASN1_read_bio(d2i, name, b, x, cb, u); + BIO_free(b); + return (ret); +} +#endif + +static int check_pem(const char *nm, const char *name) +{ + /* Normal matching nm and name */ + if (!strcmp(nm, name)) + return 1; + + /* Make PEM_STRING_EVP_PKEY match any private key */ + + if (!strcmp(name, PEM_STRING_EVP_PKEY)) { + int slen; + const EVP_PKEY_ASN1_METHOD *ameth; + if (!strcmp(nm, PEM_STRING_PKCS8)) + return 1; + if (!strcmp(nm, PEM_STRING_PKCS8INF)) + return 1; + slen = pem_check_suffix(nm, "PRIVATE KEY"); + if (slen > 0) { + /* + * NB: ENGINE implementations wont contain a deprecated old + * private key decode function so don't look for them. + */ + ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); + if (ameth && ameth->old_priv_decode) + return 1; + } + return 0; + } + + if (!strcmp(name, PEM_STRING_PARAMETERS)) { + int slen; + const EVP_PKEY_ASN1_METHOD *ameth; + slen = pem_check_suffix(nm, "PARAMETERS"); + if (slen > 0) { + ENGINE *e; + ameth = EVP_PKEY_asn1_find_str(&e, nm, slen); + if (ameth) { + int r; + if (ameth->param_decode) + r = 1; + else + r = 0; +#ifndef OPENSSL_NO_ENGINE + if (e) + ENGINE_finish(e); +#endif + return r; + } + } + return 0; + } + + /* Permit older strings */ + + if (!strcmp(nm, PEM_STRING_X509_OLD) && !strcmp(name, PEM_STRING_X509)) + return 1; + + if (!strcmp(nm, PEM_STRING_X509_REQ_OLD) && + !strcmp(name, PEM_STRING_X509_REQ)) + return 1; + + /* Allow normal certs to be read as trusted certs */ + if (!strcmp(nm, PEM_STRING_X509) && + !strcmp(name, PEM_STRING_X509_TRUSTED)) + return 1; + + if (!strcmp(nm, PEM_STRING_X509_OLD) && + !strcmp(name, PEM_STRING_X509_TRUSTED)) + return 1; + + /* Some CAs use PKCS#7 with CERTIFICATE headers */ + if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_PKCS7)) + return 1; + + if (!strcmp(nm, PEM_STRING_PKCS7_SIGNED) && + !strcmp(name, PEM_STRING_PKCS7)) + return 1; + +#ifndef OPENSSL_NO_CMS + if (!strcmp(nm, PEM_STRING_X509) && !strcmp(name, PEM_STRING_CMS)) + return 1; + /* Allow CMS to be read from PKCS#7 headers */ + if (!strcmp(nm, PEM_STRING_PKCS7) && !strcmp(name, PEM_STRING_CMS)) + return 1; +#endif + + return 0; +} + +int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, + const char *name, BIO *bp, pem_password_cb *cb, + void *u) +{ + EVP_CIPHER_INFO cipher; + char *nm = NULL, *header = NULL; + unsigned char *data = NULL; + long len; + int ret = 0; + + for (;;) { + if (!PEM_read_bio(bp, &nm, &header, &data, &len)) { + if (ERR_GET_REASON(ERR_peek_error()) == PEM_R_NO_START_LINE) + ERR_add_error_data(2, "Expecting: ", name); + return 0; + } + if (check_pem(nm, name)) + break; + OPENSSL_free(nm); + OPENSSL_free(header); + OPENSSL_free(data); + } + if (!PEM_get_EVP_CIPHER_INFO(header, &cipher)) + goto err; + if (!PEM_do_header(&cipher, data, &len, cb, u)) + goto err; + + *pdata = data; + *plen = len; + + if (pnm) + *pnm = nm; + + ret = 1; + + err: + if (!ret || !pnm) + OPENSSL_free(nm); + OPENSSL_free(header); + if (!ret) + OPENSSL_free(data); + return ret; +} + +#ifndef OPENSSL_NO_FP_API +int PEM_ASN1_write(i2d_of_void *i2d, const char *name, FILE *fp, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *callback, void *u) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerr(PEM_F_PEM_ASN1_WRITE, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_ASN1_write_bio(i2d, name, b, x, enc, kstr, klen, callback, u); + BIO_free(b); + return (ret); +} +#endif + +int PEM_ASN1_write_bio(i2d_of_void *i2d, const char *name, BIO *bp, + void *x, const EVP_CIPHER *enc, unsigned char *kstr, + int klen, pem_password_cb *callback, void *u) +{ + EVP_CIPHER_CTX ctx; + int dsize = 0, i, j, ret = 0; + unsigned char *p, *data = NULL; + const char *objstr = NULL; + char buf[PEM_BUFSIZE]; + unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char iv[EVP_MAX_IV_LENGTH]; + + if (enc != NULL) { + objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); + if (objstr == NULL || EVP_CIPHER_iv_length(enc) == 0) { + PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + } + + if ((dsize = i2d(x, NULL)) < 0) { + PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_ASN1_LIB); + dsize = 0; + goto err; + } + /* dzise + 8 bytes are needed */ + /* actually it needs the cipher block size extra... */ + data = (unsigned char *)OPENSSL_malloc((unsigned int)dsize + 20); + if (data == NULL) { + PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + p = data; + i = i2d(x, &p); + + if (enc != NULL) { + if (kstr == NULL) { + if (callback == NULL) + klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); + else + klen = (*callback) (buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + PEMerr(PEM_F_PEM_ASN1_WRITE_BIO, PEM_R_READ_KEY); + goto err; + } +#ifdef CHARSET_EBCDIC + /* Convert the pass phrase from EBCDIC */ + ebcdic2ascii(buf, buf, klen); +#endif + kstr = (unsigned char *)buf; + } + RAND_add(data, i, 0); /* put in the RSA key. */ + OPENSSL_assert(enc->iv_len <= (int)sizeof(iv)); + if (RAND_pseudo_bytes(iv, enc->iv_len) < 0) /* Generate a salt */ + goto err; + /* + * The 'iv' is used as the iv and as a salt. It is NOT taken from + * the BytesToKey function + */ + if (!EVP_BytesToKey(enc, EVP_md5(), iv, kstr, klen, 1, key, NULL)) + goto err; + + if (kstr == (unsigned char *)buf) + OPENSSL_cleanse(buf, PEM_BUFSIZE); + + OPENSSL_assert(strlen(objstr) + 23 + 2 * enc->iv_len + 13 <= + sizeof buf); + + buf[0] = '\0'; + PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); + PEM_dek_info(buf, objstr, enc->iv_len, (char *)iv); + /* k=strlen(buf); */ + + EVP_CIPHER_CTX_init(&ctx); + ret = 1; + if (!EVP_EncryptInit_ex(&ctx, enc, NULL, key, iv) + || !EVP_EncryptUpdate(&ctx, data, &j, data, i) + || !EVP_EncryptFinal_ex(&ctx, &(data[j]), &i)) + ret = 0; + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + goto err; + i += j; + } else { + ret = 1; + buf[0] = '\0'; + } + i = PEM_write_bio(bp, name, buf, data, i); + if (i <= 0) + ret = 0; + err: + OPENSSL_cleanse(key, sizeof(key)); + OPENSSL_cleanse(iv, sizeof(iv)); + OPENSSL_cleanse((char *)&ctx, sizeof(ctx)); + OPENSSL_cleanse(buf, PEM_BUFSIZE); + if (data != NULL) { + OPENSSL_cleanse(data, (unsigned int)dsize); + OPENSSL_free(data); + } + return (ret); +} + +int PEM_do_header(EVP_CIPHER_INFO *cipher, unsigned char *data, long *plen, + pem_password_cb *callback, void *u) +{ + int i = 0, j, o, klen; + long len; + EVP_CIPHER_CTX ctx; + unsigned char key[EVP_MAX_KEY_LENGTH]; + char buf[PEM_BUFSIZE]; + + len = *plen; + + if (cipher->cipher == NULL) + return (1); + if (callback == NULL) + klen = PEM_def_callback(buf, PEM_BUFSIZE, 0, u); + else + klen = callback(buf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_PASSWORD_READ); + return (0); + } +#ifdef CHARSET_EBCDIC + /* Convert the pass phrase from EBCDIC */ + ebcdic2ascii(buf, buf, klen); +#endif + + if (!EVP_BytesToKey(cipher->cipher, EVP_md5(), &(cipher->iv[0]), + (unsigned char *)buf, klen, 1, key, NULL)) + return 0; + + j = (int)len; + EVP_CIPHER_CTX_init(&ctx); + o = EVP_DecryptInit_ex(&ctx, cipher->cipher, NULL, key, &(cipher->iv[0])); + if (o) + o = EVP_DecryptUpdate(&ctx, data, &i, data, j); + if (o) + o = EVP_DecryptFinal_ex(&ctx, &(data[i]), &j); + EVP_CIPHER_CTX_cleanup(&ctx); + OPENSSL_cleanse((char *)buf, sizeof(buf)); + OPENSSL_cleanse((char *)key, sizeof(key)); + j += i; + if (!o) { + PEMerr(PEM_F_PEM_DO_HEADER, PEM_R_BAD_DECRYPT); + return (0); + } + *plen = j; + return (1); +} + +int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher) +{ + const EVP_CIPHER *enc = NULL; + char *p, c; + char **header_pp = &header; + + cipher->cipher = NULL; + if ((header == NULL) || (*header == '\0') || (*header == '\n')) + return (1); + if (strncmp(header, "Proc-Type: ", 11) != 0) { + PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_PROC_TYPE); + return (0); + } + header += 11; + if (*header != '4') + return (0); + header++; + if (*header != ',') + return (0); + header++; + if (strncmp(header, "ENCRYPTED", 9) != 0) { + PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_ENCRYPTED); + return (0); + } + for (; (*header != '\n') && (*header != '\0'); header++) ; + if (*header == '\0') { + PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_SHORT_HEADER); + return (0); + } + header++; + if (strncmp(header, "DEK-Info: ", 10) != 0) { + PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_NOT_DEK_INFO); + return (0); + } + header += 10; + + p = header; + for (;;) { + c = *header; +#ifndef CHARSET_EBCDIC + if (!(((c >= 'A') && (c <= 'Z')) || (c == '-') || + ((c >= '0') && (c <= '9')))) + break; +#else + if (!(isupper(c) || (c == '-') || isdigit(c))) + break; +#endif + header++; + } + *header = '\0'; + cipher->cipher = enc = EVP_get_cipherbyname(p); + *header = c; + header++; + + if (enc == NULL) { + PEMerr(PEM_F_PEM_GET_EVP_CIPHER_INFO, PEM_R_UNSUPPORTED_ENCRYPTION); + return (0); + } + if (!load_iv(header_pp, &(cipher->iv[0]), enc->iv_len)) + return (0); + + return (1); +} + +static int load_iv(char **fromp, unsigned char *to, int num) +{ + int v, i; + char *from; + + from = *fromp; + for (i = 0; i < num; i++) + to[i] = 0; + num *= 2; + for (i = 0; i < num; i++) { + if ((*from >= '0') && (*from <= '9')) + v = *from - '0'; + else if ((*from >= 'A') && (*from <= 'F')) + v = *from - 'A' + 10; + else if ((*from >= 'a') && (*from <= 'f')) + v = *from - 'a' + 10; + else { + PEMerr(PEM_F_LOAD_IV, PEM_R_BAD_IV_CHARS); + return (0); + } + from++; + to[i / 2] |= v << (long)((!(i & 1)) * 4); + } + + *fromp = from; + return (1); +} + +#ifndef OPENSSL_NO_FP_API +int PEM_write(FILE *fp, char *name, char *header, unsigned char *data, + long len) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerr(PEM_F_PEM_WRITE, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_write_bio(b, name, header, data, len); + BIO_free(b); + return (ret); +} +#endif + +int PEM_write_bio(BIO *bp, const char *name, char *header, + unsigned char *data, long len) +{ + int nlen, n, i, j, outl; + unsigned char *buf = NULL; + EVP_ENCODE_CTX ctx; + int reason = ERR_R_BUF_LIB; + + EVP_EncodeInit(&ctx); + nlen = strlen(name); + + if ((BIO_write(bp, "-----BEGIN ", 11) != 11) || + (BIO_write(bp, name, nlen) != nlen) || + (BIO_write(bp, "-----\n", 6) != 6)) + goto err; + + i = strlen(header); + if (i > 0) { + if ((BIO_write(bp, header, i) != i) || (BIO_write(bp, "\n", 1) != 1)) + goto err; + } + + buf = OPENSSL_malloc(PEM_BUFSIZE * 8); + if (buf == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + + i = j = 0; + while (len > 0) { + n = (int)((len > (PEM_BUFSIZE * 5)) ? (PEM_BUFSIZE * 5) : len); + EVP_EncodeUpdate(&ctx, buf, &outl, &(data[j]), n); + if ((outl) && (BIO_write(bp, (char *)buf, outl) != outl)) + goto err; + i += outl; + len -= n; + j += n; + } + EVP_EncodeFinal(&ctx, buf, &outl); + if ((outl > 0) && (BIO_write(bp, (char *)buf, outl) != outl)) + goto err; + OPENSSL_cleanse(buf, PEM_BUFSIZE * 8); + OPENSSL_free(buf); + buf = NULL; + if ((BIO_write(bp, "-----END ", 9) != 9) || + (BIO_write(bp, name, nlen) != nlen) || + (BIO_write(bp, "-----\n", 6) != 6)) + goto err; + return (i + outl); + err: + if (buf) { + OPENSSL_cleanse(buf, PEM_BUFSIZE * 8); + OPENSSL_free(buf); + } + PEMerr(PEM_F_PEM_WRITE_BIO, reason); + return (0); +} + +#ifndef OPENSSL_NO_FP_API +int PEM_read(FILE *fp, char **name, char **header, unsigned char **data, + long *len) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerr(PEM_F_PEM_READ, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_read_bio(b, name, header, data, len); + BIO_free(b); + return (ret); +} +#endif + +int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data, + long *len) +{ + EVP_ENCODE_CTX ctx; + int end = 0, i, k, bl = 0, hl = 0, nohead = 0; + char buf[256]; + BUF_MEM *nameB; + BUF_MEM *headerB; + BUF_MEM *dataB, *tmpB; + + nameB = BUF_MEM_new(); + headerB = BUF_MEM_new(); + dataB = BUF_MEM_new(); + if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL)) { + BUF_MEM_free(nameB); + BUF_MEM_free(headerB); + BUF_MEM_free(dataB); + PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); + return (0); + } + + buf[254] = '\0'; + for (;;) { + i = BIO_gets(bp, buf, 254); + + if (i <= 0) { + PEMerr(PEM_F_PEM_READ_BIO, PEM_R_NO_START_LINE); + goto err; + } + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (strncmp(buf, "-----BEGIN ", 11) == 0) { + i = strlen(&(buf[11])); + + if (strncmp(&(buf[11 + i - 6]), "-----\n", 6) != 0) + continue; + if (!BUF_MEM_grow(nameB, i + 9)) { + PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + memcpy(nameB->data, &(buf[11]), i - 6); + nameB->data[i - 6] = '\0'; + break; + } + } + hl = 0; + if (!BUF_MEM_grow(headerB, 256)) { + PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + headerB->data[0] = '\0'; + for (;;) { + i = BIO_gets(bp, buf, 254); + if (i <= 0) + break; + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (buf[0] == '\n') + break; + if (!BUF_MEM_grow(headerB, hl + i + 9)) { + PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + if (strncmp(buf, "-----END ", 9) == 0) { + nohead = 1; + break; + } + memcpy(&(headerB->data[hl]), buf, i); + headerB->data[hl + i] = '\0'; + hl += i; + } + + bl = 0; + if (!BUF_MEM_grow(dataB, 1024)) { + PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + dataB->data[0] = '\0'; + if (!nohead) { + for (;;) { + i = BIO_gets(bp, buf, 254); + if (i <= 0) + break; + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + if (i != 65) + end = 1; + if (strncmp(buf, "-----END ", 9) == 0) + break; + if (i > 65) + break; + if (!BUF_MEM_grow_clean(dataB, i + bl + 9)) { + PEMerr(PEM_F_PEM_READ_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + memcpy(&(dataB->data[bl]), buf, i); + dataB->data[bl + i] = '\0'; + bl += i; + if (end) { + buf[0] = '\0'; + i = BIO_gets(bp, buf, 254); + if (i <= 0) + break; + + while ((i >= 0) && (buf[i] <= ' ')) + i--; + buf[++i] = '\n'; + buf[++i] = '\0'; + + break; + } + } + } else { + tmpB = headerB; + headerB = dataB; + dataB = tmpB; + bl = hl; + } + i = strlen(nameB->data); + if ((strncmp(buf, "-----END ", 9) != 0) || + (strncmp(nameB->data, &(buf[9]), i) != 0) || + (strncmp(&(buf[9 + i]), "-----\n", 6) != 0)) { + PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_END_LINE); + goto err; + } + + EVP_DecodeInit(&ctx); + i = EVP_DecodeUpdate(&ctx, + (unsigned char *)dataB->data, &bl, + (unsigned char *)dataB->data, bl); + if (i < 0) { + PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE); + goto err; + } + i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k); + if (i < 0) { + PEMerr(PEM_F_PEM_READ_BIO, PEM_R_BAD_BASE64_DECODE); + goto err; + } + bl += k; + + if (bl == 0) + goto err; + *name = nameB->data; + *header = headerB->data; + *data = (unsigned char *)dataB->data; + *len = bl; + OPENSSL_free(nameB); + OPENSSL_free(headerB); + OPENSSL_free(dataB); + return (1); + err: + BUF_MEM_free(nameB); + BUF_MEM_free(headerB); + BUF_MEM_free(dataB); + return (0); +} + +/* + * Check pem string and return prefix length. If for example the pem_str == + * "RSA PRIVATE KEY" and suffix = "PRIVATE KEY" the return value is 3 for the + * string "RSA". + */ + +int pem_check_suffix(const char *pem_str, const char *suffix) +{ + int pem_len = strlen(pem_str); + int suffix_len = strlen(suffix); + const char *p; + if (suffix_len + 1 >= pem_len) + return 0; + p = pem_str + pem_len - suffix_len; + if (strcmp(p, suffix)) + return 0; + p--; + if (*p != ' ') + return 0; + return p - pem_str; +} diff --git a/libs/openssl/crypto/pem/pem_oth.c b/libs/openssl/crypto/pem/pem_oth.c new file mode 100644 index 00000000..1dd3bd7a --- /dev/null +++ b/libs/openssl/crypto/pem/pem_oth.c @@ -0,0 +1,86 @@ +/* crypto/pem/pem_oth.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include + +/* Handle 'other' PEMs: not private keys */ + +void *PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, + pem_password_cb *cb, void *u) +{ + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + char *ret = NULL; + + if (!PEM_bytes_read_bio(&data, &len, NULL, name, bp, cb, u)) + return NULL; + p = data; + ret = d2i(x, &p, len); + if (ret == NULL) + PEMerr(PEM_F_PEM_ASN1_READ_BIO, ERR_R_ASN1_LIB); + OPENSSL_free(data); + return (ret); +} diff --git a/libs/openssl/crypto/pem/pem_pk8.c b/libs/openssl/crypto/pem/pem_pk8.c new file mode 100644 index 00000000..5747c736 --- /dev/null +++ b/libs/openssl/crypto/pem/pem_pk8.c @@ -0,0 +1,259 @@ +/* crypto/pem/pem_pkey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include + +static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, + int nid, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u); +static int do_pk8pkey_fp(FILE *bp, EVP_PKEY *x, int isder, + int nid, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u); + +/* + * These functions write a private key in PKCS#8 format: it is a "drop in" + * replacement for PEM_write_bio_PrivateKey() and friends. As usual if 'enc' + * is NULL then it uses the unencrypted private key form. The 'nid' versions + * uses PKCS#5 v1.5 PBE algorithms whereas the others use PKCS#5 v2.0. + */ + +int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 0, nid, NULL, kstr, klen, cb, u); +} + +int PEM_write_bio_PKCS8PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 0, -1, enc, kstr, klen, cb, u); +} + +int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 1, -1, enc, kstr, klen, cb, u); +} + +int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey(bp, x, 1, nid, NULL, kstr, klen, cb, u); +} + +static int do_pk8pkey(BIO *bp, EVP_PKEY *x, int isder, int nid, + const EVP_CIPHER *enc, char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + X509_SIG *p8; + PKCS8_PRIV_KEY_INFO *p8inf; + char buf[PEM_BUFSIZE]; + int ret; + if (!(p8inf = EVP_PKEY2PKCS8(x))) { + PEMerr(PEM_F_DO_PK8PKEY, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); + return 0; + } + if (enc || (nid != -1)) { + if (!kstr) { + if (!cb) + klen = PEM_def_callback(buf, PEM_BUFSIZE, 1, u); + else + klen = cb(buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + PEMerr(PEM_F_DO_PK8PKEY, PEM_R_READ_KEY); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return 0; + } + + kstr = buf; + } + p8 = PKCS8_encrypt(nid, enc, kstr, klen, NULL, 0, 0, p8inf); + if (kstr == buf) + OPENSSL_cleanse(buf, klen); + PKCS8_PRIV_KEY_INFO_free(p8inf); + if (p8 == NULL) + return 0; + if (isder) + ret = i2d_PKCS8_bio(bp, p8); + else + ret = PEM_write_bio_PKCS8(bp, p8); + X509_SIG_free(p8); + return ret; + } else { + if (isder) + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + else + ret = PEM_write_bio_PKCS8_PRIV_KEY_INFO(bp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; + } +} + +EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + PKCS8_PRIV_KEY_INFO *p8inf = NULL; + X509_SIG *p8 = NULL; + int klen; + EVP_PKEY *ret; + char psbuf[PEM_BUFSIZE]; + p8 = d2i_PKCS8_bio(bp, NULL); + if (!p8) + return NULL; + if (cb) + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + else + klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_BIO, PEM_R_BAD_PASSWORD_READ); + X509_SIG_free(p8); + return NULL; + } + p8inf = PKCS8_decrypt(p8, psbuf, klen); + X509_SIG_free(p8); + if (!p8inf) + return NULL; + ret = EVP_PKCS82PKEY(p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + if (!ret) + return NULL; + if (x) { + if (*x) + EVP_PKEY_free(*x); + *x = ret; + } + return ret; +} + +#ifndef OPENSSL_NO_FP_API + +int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 1, -1, enc, kstr, klen, cb, u); +} + +int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 1, nid, NULL, kstr, klen, cb, u); +} + +int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, + char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + return do_pk8pkey_fp(fp, x, 0, nid, NULL, kstr, klen, cb, u); +} + +int PEM_write_PKCS8PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + char *kstr, int klen, pem_password_cb *cb, + void *u) +{ + return do_pk8pkey_fp(fp, x, 0, -1, enc, kstr, klen, cb, u); +} + +static int do_pk8pkey_fp(FILE *fp, EVP_PKEY *x, int isder, int nid, + const EVP_CIPHER *enc, char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + BIO *bp; + int ret; + if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { + PEMerr(PEM_F_DO_PK8PKEY_FP, ERR_R_BUF_LIB); + return (0); + } + ret = do_pk8pkey(bp, x, isder, nid, enc, kstr, klen, cb, u); + BIO_free(bp); + return ret; +} + +EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + BIO *bp; + EVP_PKEY *ret; + if (!(bp = BIO_new_fp(fp, BIO_NOCLOSE))) { + PEMerr(PEM_F_D2I_PKCS8PRIVATEKEY_FP, ERR_R_BUF_LIB); + return NULL; + } + ret = d2i_PKCS8PrivateKey_bio(bp, x, cb, u); + BIO_free(bp); + return ret; +} + +#endif + +IMPLEMENT_PEM_rw(PKCS8, X509_SIG, PEM_STRING_PKCS8, X509_SIG) + + +IMPLEMENT_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO, PEM_STRING_PKCS8INF, + PKCS8_PRIV_KEY_INFO) diff --git a/libs/openssl/crypto/pem/pem_pkey.c b/libs/openssl/crypto/pem/pem_pkey.c new file mode 100644 index 00000000..0b05e63f --- /dev/null +++ b/libs/openssl/crypto/pem/pem_pkey.c @@ -0,0 +1,243 @@ +/* crypto/pem/pem_pkey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include "asn1_locl.h" + +int pem_check_suffix(const char *pem_str, const char *suffix); + +EVP_PKEY *PEM_read_bio_PrivateKey(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + char *nm = NULL; + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + int slen; + EVP_PKEY *ret = NULL; + + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_EVP_PKEY, bp, cb, u)) + return NULL; + p = data; + + if (strcmp(nm, PEM_STRING_PKCS8INF) == 0) { + PKCS8_PRIV_KEY_INFO *p8inf; + p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, len); + if (!p8inf) + goto p8err; + ret = EVP_PKCS82PKEY(p8inf); + if (x) { + if (*x) + EVP_PKEY_free((EVP_PKEY *)*x); + *x = ret; + } + PKCS8_PRIV_KEY_INFO_free(p8inf); + } else if (strcmp(nm, PEM_STRING_PKCS8) == 0) { + PKCS8_PRIV_KEY_INFO *p8inf; + X509_SIG *p8; + int klen; + char psbuf[PEM_BUFSIZE]; + p8 = d2i_X509_SIG(NULL, &p, len); + if (!p8) + goto p8err; + if (cb) + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + else + klen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, PEM_R_BAD_PASSWORD_READ); + X509_SIG_free(p8); + goto err; + } + p8inf = PKCS8_decrypt(p8, psbuf, klen); + X509_SIG_free(p8); + if (!p8inf) + goto p8err; + ret = EVP_PKCS82PKEY(p8inf); + if (x) { + if (*x) + EVP_PKEY_free((EVP_PKEY *)*x); + *x = ret; + } + PKCS8_PRIV_KEY_INFO_free(p8inf); + } else if ((slen = pem_check_suffix(nm, "PRIVATE KEY")) > 0) { + const EVP_PKEY_ASN1_METHOD *ameth; + ameth = EVP_PKEY_asn1_find_str(NULL, nm, slen); + if (!ameth || !ameth->old_priv_decode) + goto p8err; + ret = d2i_PrivateKey(ameth->pkey_id, x, &p, len); + } + p8err: + if (ret == NULL) + PEMerr(PEM_F_PEM_READ_BIO_PRIVATEKEY, ERR_R_ASN1_LIB); + err: + OPENSSL_free(nm); + OPENSSL_cleanse(data, len); + OPENSSL_free(data); + return (ret); +} + +int PEM_write_bio_PrivateKey(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + char pem_str[80]; + if (!x->ameth || x->ameth->priv_encode) + return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, + (char *)kstr, klen, cb, u); + + BIO_snprintf(pem_str, 80, "%s PRIVATE KEY", x->ameth->pem_str); + return PEM_ASN1_write_bio((i2d_of_void *)i2d_PrivateKey, + pem_str, bp, x, enc, kstr, klen, cb, u); +} + +EVP_PKEY *PEM_read_bio_Parameters(BIO *bp, EVP_PKEY **x) +{ + char *nm = NULL; + const unsigned char *p = NULL; + unsigned char *data = NULL; + long len; + int slen; + EVP_PKEY *ret = NULL; + + if (!PEM_bytes_read_bio(&data, &len, &nm, PEM_STRING_PARAMETERS, + bp, 0, NULL)) + return NULL; + p = data; + + if ((slen = pem_check_suffix(nm, "PARAMETERS")) > 0) { + ret = EVP_PKEY_new(); + if (!ret) + goto err; + if (!EVP_PKEY_set_type_str(ret, nm, slen) + || !ret->ameth->param_decode + || !ret->ameth->param_decode(ret, &p, len)) { + EVP_PKEY_free(ret); + ret = NULL; + goto err; + } + if (x) { + if (*x) + EVP_PKEY_free((EVP_PKEY *)*x); + *x = ret; + } + } + err: + if (ret == NULL) + PEMerr(PEM_F_PEM_READ_BIO_PARAMETERS, ERR_R_ASN1_LIB); + OPENSSL_free(nm); + OPENSSL_free(data); + return (ret); +} + +int PEM_write_bio_Parameters(BIO *bp, EVP_PKEY *x) +{ + char pem_str[80]; + if (!x->ameth || !x->ameth->param_encode) + return 0; + + BIO_snprintf(pem_str, 80, "%s PARAMETERS", x->ameth->pem_str); + return PEM_ASN1_write_bio((i2d_of_void *)x->ameth->param_encode, + pem_str, bp, x, NULL, NULL, 0, 0, NULL); +} + +#ifndef OPENSSL_NO_FP_API +EVP_PKEY *PEM_read_PrivateKey(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, + void *u) +{ + BIO *b; + EVP_PKEY *ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + PEMerr(PEM_F_PEM_READ_PRIVATEKEY, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = PEM_read_bio_PrivateKey(b, x, cb, u); + BIO_free(b); + return (ret); +} + +int PEM_write_PrivateKey(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, + unsigned char *kstr, int klen, + pem_password_cb *cb, void *u) +{ + BIO *b; + int ret; + + if ((b = BIO_new_fp(fp, BIO_NOCLOSE)) == NULL) { + PEMerr(PEM_F_PEM_WRITE_PRIVATEKEY, ERR_R_BUF_LIB); + return 0; + } + ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u); + BIO_free(b); + return ret; +} + +#endif diff --git a/libs/openssl/crypto/pem/pem_seal.c b/libs/openssl/crypto/pem/pem_seal.c new file mode 100644 index 00000000..a5c18125 --- /dev/null +++ b/libs/openssl/crypto/pem/pem_seal.c @@ -0,0 +1,191 @@ +/* crypto/pem/pem_seal.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include /* for OPENSSL_NO_RSA */ +#ifndef OPENSSL_NO_RSA +# include +# include "cryptlib.h" +# include +# include +# include +# include +# include +# include + +int PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type, + unsigned char **ek, int *ekl, unsigned char *iv, + EVP_PKEY **pubk, int npubk) +{ + unsigned char key[EVP_MAX_KEY_LENGTH]; + int ret = -1; + int i, j, max = 0; + char *s = NULL; + + for (i = 0; i < npubk; i++) { + if (pubk[i]->type != EVP_PKEY_RSA) { + PEMerr(PEM_F_PEM_SEALINIT, PEM_R_PUBLIC_KEY_NO_RSA); + goto err; + } + j = RSA_size(pubk[i]->pkey.rsa); + if (j > max) + max = j; + } + s = (char *)OPENSSL_malloc(max * 2); + if (s == NULL) { + PEMerr(PEM_F_PEM_SEALINIT, ERR_R_MALLOC_FAILURE); + goto err; + } + + EVP_EncodeInit(&ctx->encode); + + EVP_MD_CTX_init(&ctx->md); + if (!EVP_SignInit(&ctx->md, md_type)) + goto err; + + EVP_CIPHER_CTX_init(&ctx->cipher); + ret = EVP_SealInit(&ctx->cipher, type, ek, ekl, iv, pubk, npubk); + if (ret <= 0) + goto err; + + /* base64 encode the keys */ + for (i = 0; i < npubk; i++) { + j = EVP_EncodeBlock((unsigned char *)s, ek[i], + RSA_size(pubk[i]->pkey.rsa)); + ekl[i] = j; + memcpy(ek[i], s, j + 1); + } + + ret = npubk; + err: + if (s != NULL) + OPENSSL_free(s); + OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); + return (ret); +} + +void PEM_SealUpdate(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *out, int *outl, + unsigned char *in, int inl) +{ + unsigned char buffer[1600]; + int i, j; + + *outl = 0; + EVP_SignUpdate(&ctx->md, in, inl); + for (;;) { + if (inl <= 0) + break; + if (inl > 1200) + i = 1200; + else + i = inl; + EVP_EncryptUpdate(&ctx->cipher, buffer, &j, in, i); + EVP_EncodeUpdate(&ctx->encode, out, &j, buffer, j); + *outl += j; + out += j; + in += i; + inl -= i; + } +} + +int PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl, + unsigned char *out, int *outl, EVP_PKEY *priv) +{ + unsigned char *s = NULL; + int ret = 0, j; + unsigned int i; + + if (priv->type != EVP_PKEY_RSA) { + PEMerr(PEM_F_PEM_SEALFINAL, PEM_R_PUBLIC_KEY_NO_RSA); + goto err; + } + i = RSA_size(priv->pkey.rsa); + if (i < 100) + i = 100; + s = (unsigned char *)OPENSSL_malloc(i * 2); + if (s == NULL) { + PEMerr(PEM_F_PEM_SEALFINAL, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_EncryptFinal_ex(&ctx->cipher, s, (int *)&i)) + goto err; + EVP_EncodeUpdate(&ctx->encode, out, &j, s, i); + *outl = j; + out += j; + EVP_EncodeFinal(&ctx->encode, out, &j); + *outl += j; + + if (!EVP_SignFinal(&ctx->md, s, &i, priv)) + goto err; + *sigl = EVP_EncodeBlock(sig, s, i); + + ret = 1; + err: + EVP_MD_CTX_cleanup(&ctx->md); + EVP_CIPHER_CTX_cleanup(&ctx->cipher); + if (s != NULL) + OPENSSL_free(s); + return (ret); +} +#else /* !OPENSSL_NO_RSA */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif diff --git a/libs/openssl/crypto/pem/pem_sign.c b/libs/openssl/crypto/pem/pem_sign.c new file mode 100644 index 00000000..b5e5c29b --- /dev/null +++ b/libs/openssl/crypto/pem/pem_sign.c @@ -0,0 +1,101 @@ +/* crypto/pem/pem_sign.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include + +void PEM_SignInit(EVP_MD_CTX *ctx, EVP_MD *type) +{ + EVP_DigestInit_ex(ctx, type, NULL); +} + +void PEM_SignUpdate(EVP_MD_CTX *ctx, unsigned char *data, unsigned int count) +{ + EVP_DigestUpdate(ctx, data, count); +} + +int PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, + unsigned int *siglen, EVP_PKEY *pkey) +{ + unsigned char *m; + int i, ret = 0; + unsigned int m_len; + + m = (unsigned char *)OPENSSL_malloc(EVP_PKEY_size(pkey) + 2); + if (m == NULL) { + PEMerr(PEM_F_PEM_SIGNFINAL, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_SignFinal(ctx, m, &m_len, pkey) <= 0) + goto err; + + i = EVP_EncodeBlock(sigret, m, m_len); + *siglen = i; + ret = 1; + err: + /* ctx has been zeroed by EVP_SignFinal() */ + if (m != NULL) + OPENSSL_free(m); + return (ret); +} diff --git a/libs/openssl/crypto/pem/pem_x509.c b/libs/openssl/crypto/pem/pem_x509.c new file mode 100644 index 00000000..3c20ff28 --- /dev/null +++ b/libs/openssl/crypto/pem/pem_x509.c @@ -0,0 +1,68 @@ +/* pem_x509.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include + +IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509) diff --git a/libs/openssl/crypto/pem/pem_xaux.c b/libs/openssl/crypto/pem/pem_xaux.c new file mode 100644 index 00000000..c5234301 --- /dev/null +++ b/libs/openssl/crypto/pem/pem_xaux.c @@ -0,0 +1,70 @@ +/* pem_xaux.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include + +IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX) +IMPLEMENT_PEM_rw(X509_CERT_PAIR, X509_CERT_PAIR, PEM_STRING_X509_PAIR, + X509_CERT_PAIR) diff --git a/libs/openssl/crypto/pem/pkcs7.lis b/libs/openssl/crypto/pem/pkcs7.lis new file mode 100644 index 00000000..be90c5d8 --- /dev/null +++ b/libs/openssl/crypto/pem/pkcs7.lis @@ -0,0 +1,22 @@ +21 0:d=0 hl=2 l= 0 cons: univ: SEQUENCE + 00 2:d=0 hl=2 l= 9 prim: univ: OBJECT_IDENTIFIER :pkcs-7-signedData + 21 13:d=0 hl=2 l= 0 cons: cont: 00 # explicit tag + 21 15:d=0 hl=2 l= 0 cons: univ: SEQUENCE + 00 17:d=0 hl=2 l= 1 prim: univ: INTEGER # version + 20 20:d=0 hl=2 l= 0 cons: univ: SET + 21 22:d=0 hl=2 l= 0 cons: univ: SEQUENCE + 00 24:d=0 hl=2 l= 9 prim: univ: OBJECT_IDENTIFIER :pkcs-7-data + 00 35:d=0 hl=2 l= 0 prim: univ: EOC + 21 37:d=0 hl=2 l= 0 cons: cont: 00 # cert tag + 20 39:d=0 hl=4 l=545 cons: univ: SEQUENCE + 20 588:d=0 hl=4 l=524 cons: univ: SEQUENCE + 00 1116:d=0 hl=2 l= 0 prim: univ: EOC + 21 1118:d=0 hl=2 l= 0 cons: cont: 01 # crl tag + 20 1120:d=0 hl=4 l=653 cons: univ: SEQUENCE + 20 1777:d=0 hl=4 l=285 cons: univ: SEQUENCE + 00 2066:d=0 hl=2 l= 0 prim: univ: EOC + 21 2068:d=0 hl=2 l= 0 cons: univ: SET # signers + 00 2070:d=0 hl=2 l= 0 prim: univ: EOC + 00 2072:d=0 hl=2 l= 0 prim: univ: EOC + 00 2074:d=0 hl=2 l= 0 prim: univ: EOC +00 2076:d=0 hl=2 l= 0 prim: univ: EOC diff --git a/libs/openssl/crypto/pem/pvkfmt.c b/libs/openssl/crypto/pem/pvkfmt.c new file mode 100644 index 00000000..61864468 --- /dev/null +++ b/libs/openssl/crypto/pem/pvkfmt.c @@ -0,0 +1,888 @@ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Support for PVK format keys and related structures (such a PUBLICKEYBLOB + * and PRIVATEKEYBLOB). + */ + +#include "cryptlib.h" +#include +#include +#include +#if !defined(OPENSSL_NO_RSA) && !defined(OPENSSL_NO_DSA) +# include +# include + +/* + * Utility function: read a DWORD (4 byte unsigned integer) in little endian + * format + */ + +static unsigned int read_ledword(const unsigned char **in) +{ + const unsigned char *p = *in; + unsigned int ret; + ret = *p++; + ret |= (*p++ << 8); + ret |= (*p++ << 16); + ret |= (*p++ << 24); + *in = p; + return ret; +} + +/* + * Read a BIGNUM in little endian format. The docs say that this should take + * up bitlen/8 bytes. + */ + +static int read_lebn(const unsigned char **in, unsigned int nbyte, BIGNUM **r) +{ + const unsigned char *p; + unsigned char *tmpbuf, *q; + unsigned int i; + p = *in + nbyte - 1; + tmpbuf = OPENSSL_malloc(nbyte); + if (!tmpbuf) + return 0; + q = tmpbuf; + for (i = 0; i < nbyte; i++) + *q++ = *p--; + *r = BN_bin2bn(tmpbuf, nbyte, NULL); + OPENSSL_free(tmpbuf); + if (*r) { + *in += nbyte; + return 1; + } else + return 0; +} + +/* Convert private key blob to EVP_PKEY: RSA and DSA keys supported */ + +# define MS_PUBLICKEYBLOB 0x6 +# define MS_PRIVATEKEYBLOB 0x7 +# define MS_RSA1MAGIC 0x31415352L +# define MS_RSA2MAGIC 0x32415352L +# define MS_DSS1MAGIC 0x31535344L +# define MS_DSS2MAGIC 0x32535344L + +# define MS_KEYALG_RSA_KEYX 0xa400 +# define MS_KEYALG_DSS_SIGN 0x2200 + +# define MS_KEYTYPE_KEYX 0x1 +# define MS_KEYTYPE_SIGN 0x2 + +/* The PVK file magic number: seems to spell out "bobsfile", who is Bob? */ +# define MS_PVKMAGIC 0xb0b5f11eL +/* Salt length for PVK files */ +# define PVK_SALTLEN 0x10 +/* Maximum length in PVK header */ +# define PVK_MAX_KEYLEN 102400 +/* Maximum salt length */ +# define PVK_MAX_SALTLEN 10240 + +static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length, + unsigned int bitlen, int ispub); +static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length, + unsigned int bitlen, int ispub); + +static int do_blob_header(const unsigned char **in, unsigned int length, + unsigned int *pmagic, unsigned int *pbitlen, + int *pisdss, int *pispub) +{ + const unsigned char *p = *in; + if (length < 16) + return 0; + /* bType */ + if (*p == MS_PUBLICKEYBLOB) { + if (*pispub == 0) { + PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB); + return 0; + } + *pispub = 1; + } else if (*p == MS_PRIVATEKEYBLOB) { + if (*pispub == 1) { + PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB); + return 0; + } + *pispub = 0; + } else + return 0; + p++; + /* Version */ + if (*p++ != 0x2) { + PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_VERSION_NUMBER); + return 0; + } + /* Ignore reserved, aiKeyAlg */ + p += 6; + *pmagic = read_ledword(&p); + *pbitlen = read_ledword(&p); + *pisdss = 0; + switch (*pmagic) { + + case MS_DSS1MAGIC: + *pisdss = 1; + case MS_RSA1MAGIC: + if (*pispub == 0) { + PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PRIVATE_KEY_BLOB); + return 0; + } + break; + + case MS_DSS2MAGIC: + *pisdss = 1; + case MS_RSA2MAGIC: + if (*pispub == 1) { + PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_EXPECTING_PUBLIC_KEY_BLOB); + return 0; + } + break; + + default: + PEMerr(PEM_F_DO_BLOB_HEADER, PEM_R_BAD_MAGIC_NUMBER); + return -1; + } + *in = p; + return 1; +} + +static unsigned int blob_length(unsigned bitlen, int isdss, int ispub) +{ + unsigned int nbyte, hnbyte; + nbyte = (bitlen + 7) >> 3; + hnbyte = (bitlen + 15) >> 4; + if (isdss) { + + /* + * Expected length: 20 for q + 3 components bitlen each + 24 for seed + * structure. + */ + if (ispub) + return 44 + 3 * nbyte; + /* + * Expected length: 20 for q, priv, 2 bitlen components + 24 for seed + * structure. + */ + else + return 64 + 2 * nbyte; + } else { + /* Expected length: 4 for 'e' + 'n' */ + if (ispub) + return 4 + nbyte; + else + /* + * Expected length: 4 for 'e' and 7 other components. 2 + * components are bitlen size, 5 are bitlen/2 + */ + return 4 + 2 * nbyte + 5 * hnbyte; + } + +} + +static EVP_PKEY *do_b2i(const unsigned char **in, unsigned int length, + int ispub) +{ + const unsigned char *p = *in; + unsigned int bitlen, magic; + int isdss; + if (do_blob_header(&p, length, &magic, &bitlen, &isdss, &ispub) <= 0) { + PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_HEADER_PARSE_ERROR); + return NULL; + } + length -= 16; + if (length < blob_length(bitlen, isdss, ispub)) { + PEMerr(PEM_F_DO_B2I, PEM_R_KEYBLOB_TOO_SHORT); + return NULL; + } + if (isdss) + return b2i_dss(&p, length, bitlen, ispub); + else + return b2i_rsa(&p, length, bitlen, ispub); +} + +static EVP_PKEY *do_b2i_bio(BIO *in, int ispub) +{ + const unsigned char *p; + unsigned char hdr_buf[16], *buf = NULL; + unsigned int bitlen, magic, length; + int isdss; + EVP_PKEY *ret = NULL; + if (BIO_read(in, hdr_buf, 16) != 16) { + PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT); + return NULL; + } + p = hdr_buf; + if (do_blob_header(&p, 16, &magic, &bitlen, &isdss, &ispub) <= 0) + return NULL; + + length = blob_length(bitlen, isdss, ispub); + buf = OPENSSL_malloc(length); + if (!buf) { + PEMerr(PEM_F_DO_B2I_BIO, ERR_R_MALLOC_FAILURE); + goto err; + } + p = buf; + if (BIO_read(in, buf, length) != (int)length) { + PEMerr(PEM_F_DO_B2I_BIO, PEM_R_KEYBLOB_TOO_SHORT); + goto err; + } + + if (isdss) + ret = b2i_dss(&p, length, bitlen, ispub); + else + ret = b2i_rsa(&p, length, bitlen, ispub); + + err: + if (buf) + OPENSSL_free(buf); + return ret; +} + +static EVP_PKEY *b2i_dss(const unsigned char **in, unsigned int length, + unsigned int bitlen, int ispub) +{ + const unsigned char *p = *in; + EVP_PKEY *ret = NULL; + DSA *dsa = NULL; + BN_CTX *ctx = NULL; + unsigned int nbyte; + nbyte = (bitlen + 7) >> 3; + + dsa = DSA_new(); + ret = EVP_PKEY_new(); + if (!dsa || !ret) + goto memerr; + if (!read_lebn(&p, nbyte, &dsa->p)) + goto memerr; + if (!read_lebn(&p, 20, &dsa->q)) + goto memerr; + if (!read_lebn(&p, nbyte, &dsa->g)) + goto memerr; + if (ispub) { + if (!read_lebn(&p, nbyte, &dsa->pub_key)) + goto memerr; + } else { + if (!read_lebn(&p, 20, &dsa->priv_key)) + goto memerr; + /* Calculate public key */ + if (!(dsa->pub_key = BN_new())) + goto memerr; + if (!(ctx = BN_CTX_new())) + goto memerr; + + if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) + + goto memerr; + BN_CTX_free(ctx); + } + + EVP_PKEY_set1_DSA(ret, dsa); + DSA_free(dsa); + *in = p; + return ret; + + memerr: + PEMerr(PEM_F_B2I_DSS, ERR_R_MALLOC_FAILURE); + if (dsa) + DSA_free(dsa); + if (ret) + EVP_PKEY_free(ret); + if (ctx) + BN_CTX_free(ctx); + return NULL; +} + +static EVP_PKEY *b2i_rsa(const unsigned char **in, unsigned int length, + unsigned int bitlen, int ispub) +{ + const unsigned char *p = *in; + EVP_PKEY *ret = NULL; + RSA *rsa = NULL; + unsigned int nbyte, hnbyte; + nbyte = (bitlen + 7) >> 3; + hnbyte = (bitlen + 15) >> 4; + rsa = RSA_new(); + ret = EVP_PKEY_new(); + if (!rsa || !ret) + goto memerr; + rsa->e = BN_new(); + if (!rsa->e) + goto memerr; + if (!BN_set_word(rsa->e, read_ledword(&p))) + goto memerr; + if (!read_lebn(&p, nbyte, &rsa->n)) + goto memerr; + if (!ispub) { + if (!read_lebn(&p, hnbyte, &rsa->p)) + goto memerr; + if (!read_lebn(&p, hnbyte, &rsa->q)) + goto memerr; + if (!read_lebn(&p, hnbyte, &rsa->dmp1)) + goto memerr; + if (!read_lebn(&p, hnbyte, &rsa->dmq1)) + goto memerr; + if (!read_lebn(&p, hnbyte, &rsa->iqmp)) + goto memerr; + if (!read_lebn(&p, nbyte, &rsa->d)) + goto memerr; + } + + EVP_PKEY_set1_RSA(ret, rsa); + RSA_free(rsa); + *in = p; + return ret; + memerr: + PEMerr(PEM_F_B2I_RSA, ERR_R_MALLOC_FAILURE); + if (rsa) + RSA_free(rsa); + if (ret) + EVP_PKEY_free(ret); + return NULL; +} + +EVP_PKEY *b2i_PrivateKey(const unsigned char **in, long length) +{ + return do_b2i(in, length, 0); +} + +EVP_PKEY *b2i_PublicKey(const unsigned char **in, long length) +{ + return do_b2i(in, length, 1); +} + +EVP_PKEY *b2i_PrivateKey_bio(BIO *in) +{ + return do_b2i_bio(in, 0); +} + +EVP_PKEY *b2i_PublicKey_bio(BIO *in) +{ + return do_b2i_bio(in, 1); +} + +static void write_ledword(unsigned char **out, unsigned int dw) +{ + unsigned char *p = *out; + *p++ = dw & 0xff; + *p++ = (dw >> 8) & 0xff; + *p++ = (dw >> 16) & 0xff; + *p++ = (dw >> 24) & 0xff; + *out = p; +} + +static void write_lebn(unsigned char **out, const BIGNUM *bn, int len) +{ + int nb, i; + unsigned char *p = *out, *q, c; + nb = BN_num_bytes(bn); + BN_bn2bin(bn, p); + q = p + nb - 1; + /* In place byte order reversal */ + for (i = 0; i < nb / 2; i++) { + c = *p; + *p++ = *q; + *q-- = c; + } + *out += nb; + /* Pad with zeroes if we have to */ + if (len > 0) { + len -= nb; + if (len > 0) { + memset(*out, 0, len); + *out += len; + } + } +} + +static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *magic); +static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *magic); + +static void write_rsa(unsigned char **out, RSA *rsa, int ispub); +static void write_dsa(unsigned char **out, DSA *dsa, int ispub); + +static int do_i2b(unsigned char **out, EVP_PKEY *pk, int ispub) +{ + unsigned char *p; + unsigned int bitlen, magic = 0, keyalg; + int outlen, noinc = 0; + if (pk->type == EVP_PKEY_DSA) { + bitlen = check_bitlen_dsa(pk->pkey.dsa, ispub, &magic); + keyalg = MS_KEYALG_DSS_SIGN; + } else if (pk->type == EVP_PKEY_RSA) { + bitlen = check_bitlen_rsa(pk->pkey.rsa, ispub, &magic); + keyalg = MS_KEYALG_RSA_KEYX; + } else + return -1; + if (bitlen == 0) + return -1; + outlen = 16 + blob_length(bitlen, + keyalg == MS_KEYALG_DSS_SIGN ? 1 : 0, ispub); + if (out == NULL) + return outlen; + if (*out) + p = *out; + else { + p = OPENSSL_malloc(outlen); + if (!p) + return -1; + *out = p; + noinc = 1; + } + if (ispub) + *p++ = MS_PUBLICKEYBLOB; + else + *p++ = MS_PRIVATEKEYBLOB; + *p++ = 0x2; + *p++ = 0; + *p++ = 0; + write_ledword(&p, keyalg); + write_ledword(&p, magic); + write_ledword(&p, bitlen); + if (keyalg == MS_KEYALG_DSS_SIGN) + write_dsa(&p, pk->pkey.dsa, ispub); + else + write_rsa(&p, pk->pkey.rsa, ispub); + if (!noinc) + *out += outlen; + return outlen; +} + +static int do_i2b_bio(BIO *out, EVP_PKEY *pk, int ispub) +{ + unsigned char *tmp = NULL; + int outlen, wrlen; + outlen = do_i2b(&tmp, pk, ispub); + if (outlen < 0) + return -1; + wrlen = BIO_write(out, tmp, outlen); + OPENSSL_free(tmp); + if (wrlen == outlen) + return outlen; + return -1; +} + +static int check_bitlen_dsa(DSA *dsa, int ispub, unsigned int *pmagic) +{ + int bitlen; + bitlen = BN_num_bits(dsa->p); + if ((bitlen & 7) || (BN_num_bits(dsa->q) != 160) + || (BN_num_bits(dsa->g) > bitlen)) + goto badkey; + if (ispub) { + if (BN_num_bits(dsa->pub_key) > bitlen) + goto badkey; + *pmagic = MS_DSS1MAGIC; + } else { + if (BN_num_bits(dsa->priv_key) > 160) + goto badkey; + *pmagic = MS_DSS2MAGIC; + } + + return bitlen; + badkey: + PEMerr(PEM_F_CHECK_BITLEN_DSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS); + return 0; +} + +static int check_bitlen_rsa(RSA *rsa, int ispub, unsigned int *pmagic) +{ + int nbyte, hnbyte, bitlen; + if (BN_num_bits(rsa->e) > 32) + goto badkey; + bitlen = BN_num_bits(rsa->n); + nbyte = BN_num_bytes(rsa->n); + hnbyte = (BN_num_bits(rsa->n) + 15) >> 4; + if (ispub) { + *pmagic = MS_RSA1MAGIC; + return bitlen; + } else { + *pmagic = MS_RSA2MAGIC; + /* + * For private key each component must fit within nbyte or hnbyte. + */ + if (BN_num_bytes(rsa->d) > nbyte) + goto badkey; + if ((BN_num_bytes(rsa->iqmp) > hnbyte) + || (BN_num_bytes(rsa->p) > hnbyte) + || (BN_num_bytes(rsa->q) > hnbyte) + || (BN_num_bytes(rsa->dmp1) > hnbyte) + || (BN_num_bytes(rsa->dmq1) > hnbyte)) + goto badkey; + } + return bitlen; + badkey: + PEMerr(PEM_F_CHECK_BITLEN_RSA, PEM_R_UNSUPPORTED_KEY_COMPONENTS); + return 0; +} + +static void write_rsa(unsigned char **out, RSA *rsa, int ispub) +{ + int nbyte, hnbyte; + nbyte = BN_num_bytes(rsa->n); + hnbyte = (BN_num_bits(rsa->n) + 15) >> 4; + write_lebn(out, rsa->e, 4); + write_lebn(out, rsa->n, -1); + if (ispub) + return; + write_lebn(out, rsa->p, hnbyte); + write_lebn(out, rsa->q, hnbyte); + write_lebn(out, rsa->dmp1, hnbyte); + write_lebn(out, rsa->dmq1, hnbyte); + write_lebn(out, rsa->iqmp, hnbyte); + write_lebn(out, rsa->d, nbyte); +} + +static void write_dsa(unsigned char **out, DSA *dsa, int ispub) +{ + int nbyte; + nbyte = BN_num_bytes(dsa->p); + write_lebn(out, dsa->p, nbyte); + write_lebn(out, dsa->q, 20); + write_lebn(out, dsa->g, nbyte); + if (ispub) + write_lebn(out, dsa->pub_key, nbyte); + else + write_lebn(out, dsa->priv_key, 20); + /* Set "invalid" for seed structure values */ + memset(*out, 0xff, 24); + *out += 24; + return; +} + +int i2b_PrivateKey_bio(BIO *out, EVP_PKEY *pk) +{ + return do_i2b_bio(out, pk, 0); +} + +int i2b_PublicKey_bio(BIO *out, EVP_PKEY *pk) +{ + return do_i2b_bio(out, pk, 1); +} + +# ifndef OPENSSL_NO_RC4 + +static int do_PVK_header(const unsigned char **in, unsigned int length, + int skip_magic, + unsigned int *psaltlen, unsigned int *pkeylen) +{ + const unsigned char *p = *in; + unsigned int pvk_magic, is_encrypted; + if (skip_magic) { + if (length < 20) { + PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT); + return 0; + } + } else { + if (length < 24) { + PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_PVK_TOO_SHORT); + return 0; + } + pvk_magic = read_ledword(&p); + if (pvk_magic != MS_PVKMAGIC) { + PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_BAD_MAGIC_NUMBER); + return 0; + } + } + /* Skip reserved */ + p += 4; + /* + * keytype = + */ read_ledword(&p); + is_encrypted = read_ledword(&p); + *psaltlen = read_ledword(&p); + *pkeylen = read_ledword(&p); + + if (*pkeylen > PVK_MAX_KEYLEN || *psaltlen > PVK_MAX_SALTLEN) + return 0; + + if (is_encrypted && !*psaltlen) { + PEMerr(PEM_F_DO_PVK_HEADER, PEM_R_INCONSISTENT_HEADER); + return 0; + } + + *in = p; + return 1; +} + +static int derive_pvk_key(unsigned char *key, + const unsigned char *salt, unsigned int saltlen, + const unsigned char *pass, int passlen) +{ + EVP_MD_CTX mctx; + int rv = 1; + EVP_MD_CTX_init(&mctx); + if (!EVP_DigestInit_ex(&mctx, EVP_sha1(), NULL) + || !EVP_DigestUpdate(&mctx, salt, saltlen) + || !EVP_DigestUpdate(&mctx, pass, passlen) + || !EVP_DigestFinal_ex(&mctx, key, NULL)) + rv = 0; + + EVP_MD_CTX_cleanup(&mctx); + return rv; +} + +static EVP_PKEY *do_PVK_body(const unsigned char **in, + unsigned int saltlen, unsigned int keylen, + pem_password_cb *cb, void *u) +{ + EVP_PKEY *ret = NULL; + const unsigned char *p = *in; + unsigned int magic; + unsigned char *enctmp = NULL, *q; + EVP_CIPHER_CTX cctx; + EVP_CIPHER_CTX_init(&cctx); + if (saltlen) { + char psbuf[PEM_BUFSIZE]; + unsigned char keybuf[20]; + int enctmplen, inlen; + if (cb) + inlen = cb(psbuf, PEM_BUFSIZE, 0, u); + else + inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 0, u); + if (inlen <= 0) { + PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_PASSWORD_READ); + goto err; + } + enctmp = OPENSSL_malloc(keylen + 8); + if (!enctmp) { + PEMerr(PEM_F_DO_PVK_BODY, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!derive_pvk_key(keybuf, p, saltlen, + (unsigned char *)psbuf, inlen)) + goto err; + p += saltlen; + /* Copy BLOBHEADER across, decrypt rest */ + memcpy(enctmp, p, 8); + p += 8; + if (keylen < 8) { + PEMerr(PEM_F_DO_PVK_BODY, PEM_R_PVK_TOO_SHORT); + goto err; + } + inlen = keylen - 8; + q = enctmp + 8; + if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL)) + goto err; + if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen)) + goto err; + if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen)) + goto err; + magic = read_ledword((const unsigned char **)&q); + if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) { + q = enctmp + 8; + memset(keybuf + 5, 0, 11); + if (!EVP_DecryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL)) + goto err; + OPENSSL_cleanse(keybuf, 20); + if (!EVP_DecryptUpdate(&cctx, q, &enctmplen, p, inlen)) + goto err; + if (!EVP_DecryptFinal_ex(&cctx, q + enctmplen, &enctmplen)) + goto err; + magic = read_ledword((const unsigned char **)&q); + if (magic != MS_RSA2MAGIC && magic != MS_DSS2MAGIC) { + PEMerr(PEM_F_DO_PVK_BODY, PEM_R_BAD_DECRYPT); + goto err; + } + } else + OPENSSL_cleanse(keybuf, 20); + p = enctmp; + } + + ret = b2i_PrivateKey(&p, keylen); + err: + EVP_CIPHER_CTX_cleanup(&cctx); + if (enctmp && saltlen) + OPENSSL_free(enctmp); + return ret; +} + +EVP_PKEY *b2i_PVK_bio(BIO *in, pem_password_cb *cb, void *u) +{ + unsigned char pvk_hdr[24], *buf = NULL; + const unsigned char *p; + int buflen; + EVP_PKEY *ret = NULL; + unsigned int saltlen, keylen; + if (BIO_read(in, pvk_hdr, 24) != 24) { + PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT); + return NULL; + } + p = pvk_hdr; + + if (!do_PVK_header(&p, 24, 0, &saltlen, &keylen)) + return 0; + buflen = (int)keylen + saltlen; + buf = OPENSSL_malloc(buflen); + if (!buf) { + PEMerr(PEM_F_B2I_PVK_BIO, ERR_R_MALLOC_FAILURE); + return 0; + } + p = buf; + if (BIO_read(in, buf, buflen) != buflen) { + PEMerr(PEM_F_B2I_PVK_BIO, PEM_R_PVK_DATA_TOO_SHORT); + goto err; + } + ret = do_PVK_body(&p, saltlen, keylen, cb, u); + + err: + if (buf) { + OPENSSL_cleanse(buf, buflen); + OPENSSL_free(buf); + } + return ret; +} + +static int i2b_PVK(unsigned char **out, EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u) +{ + int outlen = 24, pklen; + unsigned char *p, *salt = NULL; + EVP_CIPHER_CTX cctx; + EVP_CIPHER_CTX_init(&cctx); + if (enclevel) + outlen += PVK_SALTLEN; + pklen = do_i2b(NULL, pk, 0); + if (pklen < 0) + return -1; + outlen += pklen; + if (!out) + return outlen; + if (*out) + p = *out; + else { + p = OPENSSL_malloc(outlen); + if (!p) { + PEMerr(PEM_F_I2B_PVK, ERR_R_MALLOC_FAILURE); + return -1; + } + *out = p; + } + + write_ledword(&p, MS_PVKMAGIC); + write_ledword(&p, 0); + if (pk->type == EVP_PKEY_DSA) + write_ledword(&p, MS_KEYTYPE_SIGN); + else + write_ledword(&p, MS_KEYTYPE_KEYX); + write_ledword(&p, enclevel ? 1 : 0); + write_ledword(&p, enclevel ? PVK_SALTLEN : 0); + write_ledword(&p, pklen); + if (enclevel) { + if (RAND_bytes(p, PVK_SALTLEN) <= 0) + goto error; + salt = p; + p += PVK_SALTLEN; + } + do_i2b(&p, pk, 0); + if (enclevel == 0) + return outlen; + else { + char psbuf[PEM_BUFSIZE]; + unsigned char keybuf[20]; + int enctmplen, inlen; + if (cb) + inlen = cb(psbuf, PEM_BUFSIZE, 1, u); + else + inlen = PEM_def_callback(psbuf, PEM_BUFSIZE, 1, u); + if (inlen <= 0) { + PEMerr(PEM_F_I2B_PVK, PEM_R_BAD_PASSWORD_READ); + goto error; + } + if (!derive_pvk_key(keybuf, salt, PVK_SALTLEN, + (unsigned char *)psbuf, inlen)) + goto error; + if (enclevel == 1) + memset(keybuf + 5, 0, 11); + p = salt + PVK_SALTLEN + 8; + if (!EVP_EncryptInit_ex(&cctx, EVP_rc4(), NULL, keybuf, NULL)) + goto error; + OPENSSL_cleanse(keybuf, 20); + if (!EVP_DecryptUpdate(&cctx, p, &enctmplen, p, pklen - 8)) + goto error; + if (!EVP_DecryptFinal_ex(&cctx, p + enctmplen, &enctmplen)) + goto error; + } + EVP_CIPHER_CTX_cleanup(&cctx); + return outlen; + + error: + EVP_CIPHER_CTX_cleanup(&cctx); + return -1; +} + +int i2b_PVK_bio(BIO *out, EVP_PKEY *pk, int enclevel, + pem_password_cb *cb, void *u) +{ + unsigned char *tmp = NULL; + int outlen, wrlen; + outlen = i2b_PVK(&tmp, pk, enclevel, cb, u); + if (outlen < 0) + return -1; + wrlen = BIO_write(out, tmp, outlen); + OPENSSL_free(tmp); + if (wrlen == outlen) { + PEMerr(PEM_F_I2B_PVK_BIO, PEM_R_BIO_WRITE_FAILURE); + return outlen; + } + return -1; +} + +# endif + +#endif diff --git a/libs/openssl/crypto/perlasm/cbc.pl b/libs/openssl/crypto/perlasm/cbc.pl new file mode 100644 index 00000000..24561e75 --- /dev/null +++ b/libs/openssl/crypto/perlasm/cbc.pl @@ -0,0 +1,349 @@ +#!/usr/local/bin/perl + +# void des_ncbc_encrypt(input, output, length, schedule, ivec, enc) +# des_cblock (*input); +# des_cblock (*output); +# long length; +# des_key_schedule schedule; +# des_cblock (*ivec); +# int enc; +# +# calls +# des_encrypt((DES_LONG *)tin,schedule,DES_ENCRYPT); +# + +#&cbc("des_ncbc_encrypt","des_encrypt",0); +#&cbc("BF_cbc_encrypt","BF_encrypt","BF_encrypt", +# 1,4,5,3,5,-1); +#&cbc("des_ncbc_encrypt","des_encrypt","des_encrypt", +# 0,4,5,3,5,-1); +#&cbc("des_ede3_cbc_encrypt","des_encrypt3","des_decrypt3", +# 0,6,7,3,4,5); +# +# When doing a cipher that needs bigendian order, +# for encrypt, the iv is kept in bigendian form, +# while for decrypt, it is kept in little endian. +sub cbc + { + local($name,$enc_func,$dec_func,$swap,$iv_off,$enc_off,$p1,$p2,$p3)=@_; + # name is the function name + # enc_func and dec_func and the functions to call for encrypt/decrypt + # swap is true if byte order needs to be reversed + # iv_off is parameter number for the iv + # enc_off is parameter number for the encrypt/decrypt flag + # p1,p2,p3 are the offsets for parameters to be passed to the + # underlying calls. + + &function_begin_B($name,""); + &comment(""); + + $in="esi"; + $out="edi"; + $count="ebp"; + + &push("ebp"); + &push("ebx"); + &push("esi"); + &push("edi"); + + $data_off=4; + $data_off+=4 if ($p1 > 0); + $data_off+=4 if ($p2 > 0); + $data_off+=4 if ($p3 > 0); + + &mov($count, &wparam(2)); # length + + &comment("getting iv ptr from parameter $iv_off"); + &mov("ebx", &wparam($iv_off)); # Get iv ptr + + &mov($in, &DWP(0,"ebx","",0));# iv[0] + &mov($out, &DWP(4,"ebx","",0));# iv[1] + + &push($out); + &push($in); + &push($out); # used in decrypt for iv[1] + &push($in); # used in decrypt for iv[0] + + &mov("ebx", "esp"); # This is the address of tin[2] + + &mov($in, &wparam(0)); # in + &mov($out, &wparam(1)); # out + + # We have loaded them all, how lets push things + &comment("getting encrypt flag from parameter $enc_off"); + &mov("ecx", &wparam($enc_off)); # Get enc flag + if ($p3 > 0) + { + &comment("get and push parameter $p3"); + if ($enc_off != $p3) + { &mov("eax", &wparam($p3)); &push("eax"); } + else { &push("ecx"); } + } + if ($p2 > 0) + { + &comment("get and push parameter $p2"); + if ($enc_off != $p2) + { &mov("eax", &wparam($p2)); &push("eax"); } + else { &push("ecx"); } + } + if ($p1 > 0) + { + &comment("get and push parameter $p1"); + if ($enc_off != $p1) + { &mov("eax", &wparam($p1)); &push("eax"); } + else { &push("ecx"); } + } + &push("ebx"); # push data/iv + + &cmp("ecx",0); + &jz(&label("decrypt")); + + &and($count,0xfffffff8); + &mov("eax", &DWP($data_off,"esp","",0)); # load iv[0] + &mov("ebx", &DWP($data_off+4,"esp","",0)); # load iv[1] + + &jz(&label("encrypt_finish")); + + ############################################################# + + &set_label("encrypt_loop"); + # encrypt start + # "eax" and "ebx" hold iv (or the last cipher text) + + &mov("ecx", &DWP(0,$in,"",0)); # load first 4 bytes + &mov("edx", &DWP(4,$in,"",0)); # second 4 bytes + + &xor("eax", "ecx"); + &xor("ebx", "edx"); + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call + &mov(&DWP($data_off+4,"esp","",0), "ebx"); # + + &call($enc_func); + + &mov("eax", &DWP($data_off,"esp","",0)); + &mov("ebx", &DWP($data_off+4,"esp","",0)); + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP(0,$out,"",0),"eax"); + &mov(&DWP(4,$out,"",0),"ebx"); + + # eax and ebx are the next iv. + + &add($in, 8); + &add($out, 8); + + &sub($count, 8); + &jnz(&label("encrypt_loop")); + +###################################################################3 + &set_label("encrypt_finish"); + &mov($count, &wparam(2)); # length + &and($count, 7); + &jz(&label("finish")); + &call(&label("PIC_point")); +&set_label("PIC_point"); + &blindpop("edx"); + &lea("ecx",&DWP(&label("cbc_enc_jmp_table")."-".&label("PIC_point"),"edx")); + &mov($count,&DWP(0,"ecx",$count,4)); + &add($count,"edx"); + &xor("ecx","ecx"); + &xor("edx","edx"); + #&mov($count,&DWP(&label("cbc_enc_jmp_table"),"",$count,4)); + &jmp_ptr($count); + +&set_label("ej7"); + &movb(&HB("edx"), &BP(6,$in,"",0)); + &shl("edx",8); +&set_label("ej6"); + &movb(&HB("edx"), &BP(5,$in,"",0)); +&set_label("ej5"); + &movb(&LB("edx"), &BP(4,$in,"",0)); +&set_label("ej4"); + &mov("ecx", &DWP(0,$in,"",0)); + &jmp(&label("ejend")); +&set_label("ej3"); + &movb(&HB("ecx"), &BP(2,$in,"",0)); + &shl("ecx",8); +&set_label("ej2"); + &movb(&HB("ecx"), &BP(1,$in,"",0)); +&set_label("ej1"); + &movb(&LB("ecx"), &BP(0,$in,"",0)); +&set_label("ejend"); + + &xor("eax", "ecx"); + &xor("ebx", "edx"); + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP($data_off,"esp","",0), "eax"); # put in array for call + &mov(&DWP($data_off+4,"esp","",0), "ebx"); # + + &call($enc_func); + + &mov("eax", &DWP($data_off,"esp","",0)); + &mov("ebx", &DWP($data_off+4,"esp","",0)); + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP(0,$out,"",0),"eax"); + &mov(&DWP(4,$out,"",0),"ebx"); + + &jmp(&label("finish")); + + ############################################################# + ############################################################# + &set_label("decrypt",1); + # decrypt start + &and($count,0xfffffff8); + # The next 2 instructions are only for if the jz is taken + &mov("eax", &DWP($data_off+8,"esp","",0)); # get iv[0] + &mov("ebx", &DWP($data_off+12,"esp","",0)); # get iv[1] + &jz(&label("decrypt_finish")); + + &set_label("decrypt_loop"); + &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes + &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP($data_off,"esp","",0), "eax"); # put back + &mov(&DWP($data_off+4,"esp","",0), "ebx"); # + + &call($dec_func); + + &mov("eax", &DWP($data_off,"esp","",0)); # get return + &mov("ebx", &DWP($data_off+4,"esp","",0)); # + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0] + &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1] + + &xor("ecx", "eax"); + &xor("edx", "ebx"); + + &mov("eax", &DWP(0,$in,"",0)); # get old cipher text, + &mov("ebx", &DWP(4,$in,"",0)); # next iv actually + + &mov(&DWP(0,$out,"",0),"ecx"); + &mov(&DWP(4,$out,"",0),"edx"); + + &mov(&DWP($data_off+8,"esp","",0), "eax"); # save iv + &mov(&DWP($data_off+12,"esp","",0), "ebx"); # + + &add($in, 8); + &add($out, 8); + + &sub($count, 8); + &jnz(&label("decrypt_loop")); +############################ ENDIT #######################3 + &set_label("decrypt_finish"); + &mov($count, &wparam(2)); # length + &and($count, 7); + &jz(&label("finish")); + + &mov("eax", &DWP(0,$in,"",0)); # load first 4 bytes + &mov("ebx", &DWP(4,$in,"",0)); # second 4 bytes + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov(&DWP($data_off,"esp","",0), "eax"); # put back + &mov(&DWP($data_off+4,"esp","",0), "ebx"); # + + &call($dec_func); + + &mov("eax", &DWP($data_off,"esp","",0)); # get return + &mov("ebx", &DWP($data_off+4,"esp","",0)); # + + &bswap("eax") if $swap; + &bswap("ebx") if $swap; + + &mov("ecx", &DWP($data_off+8,"esp","",0)); # get iv[0] + &mov("edx", &DWP($data_off+12,"esp","",0)); # get iv[1] + + &xor("ecx", "eax"); + &xor("edx", "ebx"); + + # this is for when we exit + &mov("eax", &DWP(0,$in,"",0)); # get old cipher text, + &mov("ebx", &DWP(4,$in,"",0)); # next iv actually + +&set_label("dj7"); + &rotr("edx", 16); + &movb(&BP(6,$out,"",0), &LB("edx")); + &shr("edx",16); +&set_label("dj6"); + &movb(&BP(5,$out,"",0), &HB("edx")); +&set_label("dj5"); + &movb(&BP(4,$out,"",0), &LB("edx")); +&set_label("dj4"); + &mov(&DWP(0,$out,"",0), "ecx"); + &jmp(&label("djend")); +&set_label("dj3"); + &rotr("ecx", 16); + &movb(&BP(2,$out,"",0), &LB("ecx")); + &shl("ecx",16); +&set_label("dj2"); + &movb(&BP(1,$in,"",0), &HB("ecx")); +&set_label("dj1"); + &movb(&BP(0,$in,"",0), &LB("ecx")); +&set_label("djend"); + + # final iv is still in eax:ebx + &jmp(&label("finish")); + + +############################ FINISH #######################3 + &set_label("finish",1); + &mov("ecx", &wparam($iv_off)); # Get iv ptr + + ################################################# + $total=16+4; + $total+=4 if ($p1 > 0); + $total+=4 if ($p2 > 0); + $total+=4 if ($p3 > 0); + &add("esp",$total); + + &mov(&DWP(0,"ecx","",0), "eax"); # save iv + &mov(&DWP(4,"ecx","",0), "ebx"); # save iv + + &function_end_A($name); + + &align(64); + &set_label("cbc_enc_jmp_table"); + &data_word("0"); + &data_word(&label("ej1")."-".&label("PIC_point")); + &data_word(&label("ej2")."-".&label("PIC_point")); + &data_word(&label("ej3")."-".&label("PIC_point")); + &data_word(&label("ej4")."-".&label("PIC_point")); + &data_word(&label("ej5")."-".&label("PIC_point")); + &data_word(&label("ej6")."-".&label("PIC_point")); + &data_word(&label("ej7")."-".&label("PIC_point")); + # not used + #&set_label("cbc_dec_jmp_table",1); + #&data_word("0"); + #&data_word(&label("dj1")."-".&label("PIC_point")); + #&data_word(&label("dj2")."-".&label("PIC_point")); + #&data_word(&label("dj3")."-".&label("PIC_point")); + #&data_word(&label("dj4")."-".&label("PIC_point")); + #&data_word(&label("dj5")."-".&label("PIC_point")); + #&data_word(&label("dj6")."-".&label("PIC_point")); + #&data_word(&label("dj7")."-".&label("PIC_point")); + &align(64); + + &function_end_B($name); + + } + +1; diff --git a/libs/openssl/crypto/perlasm/ppc-xlate.pl b/libs/openssl/crypto/perlasm/ppc-xlate.pl new file mode 100755 index 00000000..a3edd982 --- /dev/null +++ b/libs/openssl/crypto/perlasm/ppc-xlate.pl @@ -0,0 +1,159 @@ +#!/usr/bin/env perl + +# PowerPC assembler distiller by . + +my $flavour = shift; +my $output = shift; +open STDOUT,">$output" || die "can't open $output: $!"; + +my %GLOBALS; +my $dotinlocallabels=($flavour=~/linux/)?1:0; + +################################################################ +# directives which need special treatment on different platforms +################################################################ +my $globl = sub { + my $junk = shift; + my $name = shift; + my $global = \$GLOBALS{$name}; + my $ret; + + $name =~ s|^[\.\_]||; + + SWITCH: for ($flavour) { + /aix/ && do { $name = ".$name"; + last; + }; + /osx/ && do { $name = "_$name"; + last; + }; + /linux.*32/ && do { $ret .= ".globl $name\n"; + $ret .= ".type $name,\@function"; + last; + }; + /linux.*64/ && do { $ret .= ".globl $name\n"; + $ret .= ".type $name,\@function\n"; + $ret .= ".section \".opd\",\"aw\"\n"; + $ret .= ".align 3\n"; + $ret .= "$name:\n"; + $ret .= ".quad .$name,.TOC.\@tocbase,0\n"; + $ret .= ".size $name,24\n"; + $ret .= ".previous\n"; + + $name = ".$name"; + last; + }; + } + + $ret = ".globl $name" if (!$ret); + $$global = $name; + $ret; +}; +my $text = sub { + ($flavour =~ /aix/) ? ".csect" : ".text"; +}; +my $machine = sub { + my $junk = shift; + my $arch = shift; + if ($flavour =~ /osx/) + { $arch =~ s/\"//g; + $arch = ($flavour=~/64/) ? "ppc970-64" : "ppc970" if ($arch eq "any"); + } + ".machine $arch"; +}; +my $size = sub { + if ($flavour =~ /linux.*32/) + { shift; + ".size " . join(",",@_); + } + else + { ""; } +}; +my $asciz = sub { + shift; + my $line = join(",",@_); + if ($line =~ /^"(.*)"$/) + { ".byte " . join(",",unpack("C*",$1),0) . "\n.align 2"; } + else + { ""; } +}; + +################################################################ +# simplified mnemonics not handled by at least one assembler +################################################################ +my $cmplw = sub { + my $f = shift; + my $cr = 0; $cr = shift if ($#_>1); + # Some out-of-date 32-bit GNU assembler just can't handle cmplw... + ($flavour =~ /linux.*32/) ? + " .long ".sprintf "0x%x",31<<26|$cr<<23|$_[0]<<16|$_[1]<<11|64 : + " cmplw ".join(',',$cr,@_); +}; +my $bdnz = sub { + my $f = shift; + my $bo = $f=~/[\+\-]/ ? 16+9 : 16; # optional "to be taken" hint + " bc $bo,0,".shift; +} if ($flavour!~/linux/); +my $bltlr = sub { + my $f = shift; + my $bo = $f=~/\-/ ? 12+2 : 12; # optional "not to be taken" hint + ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints + " .long ".sprintf "0x%x",19<<26|$bo<<21|16<<1 : + " bclr $bo,0"; +}; +my $bnelr = sub { + my $f = shift; + my $bo = $f=~/\-/ ? 4+2 : 4; # optional "not to be taken" hint + ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints + " .long ".sprintf "0x%x",19<<26|$bo<<21|2<<16|16<<1 : + " bclr $bo,2"; +}; +my $beqlr = sub { + my $f = shift; + my $bo = $f=~/-/ ? 12+2 : 12; # optional "not to be taken" hint + ($flavour =~ /linux/) ? # GNU as doesn't allow most recent hints + " .long ".sprintf "0x%X",19<<26|$bo<<21|2<<16|16<<1 : + " bclr $bo,2"; +}; +# GNU assembler can't handle extrdi rA,rS,16,48, or when sum of last two +# arguments is 64, with "operand out of range" error. +my $extrdi = sub { + my ($f,$ra,$rs,$n,$b) = @_; + $b = ($b+$n)&63; $n = 64-$n; + " rldicl $ra,$rs,$b,$n"; +}; + +while($line=<>) { + + $line =~ s|[#!;].*$||; # get rid of asm-style comments... + $line =~ s|/\*.*\*/||; # ... and C-style comments... + $line =~ s|^\s+||; # ... and skip white spaces in beginning... + $line =~ s|\s+$||; # ... and at the end + + { + $line =~ s|\b\.L(\w+)|L$1|g; # common denominator for Locallabel + $line =~ s|\bL(\w+)|\.L$1|g if ($dotinlocallabels); + } + + { + $line =~ s|(^[\.\w]+)\:\s*||; + my $label = $1; + printf "%s:",($GLOBALS{$label} or $label) if ($label); + } + + { + $line =~ s|^\s*(\.?)(\w+)([\.\+\-]?)\s*||; + my $c = $1; $c = "\t" if ($c eq ""); + my $mnemonic = $2; + my $f = $3; + my $opcode = eval("\$$mnemonic"); + $line =~ s|\bc?[rf]([0-9]+)\b|$1|g if ($c ne "." and $flavour !~ /osx/); + if (ref($opcode) eq 'CODE') { $line = &$opcode($f,split(',',$line)); } + elsif ($mnemonic) { $line = $c.$mnemonic.$f."\t".$line; } + } + + print $line if ($line); + print "\n"; +} + +close STDOUT; diff --git a/libs/openssl/crypto/perlasm/readme b/libs/openssl/crypto/perlasm/readme new file mode 100644 index 00000000..f02bbee7 --- /dev/null +++ b/libs/openssl/crypto/perlasm/readme @@ -0,0 +1,124 @@ +The perl scripts in this directory are my 'hack' to generate +multiple different assembler formats via the one origional script. + +The way to use this library is to start with adding the path to this directory +and then include it. + +push(@INC,"perlasm","../../perlasm"); +require "x86asm.pl"; + +The first thing we do is setup the file and type of assember + +&asm_init($ARGV[0],$0); + +The first argument is the 'type'. Currently +'cpp', 'sol', 'a.out', 'elf' or 'win32'. +Argument 2 is the file name. + +The reciprocal function is +&asm_finish() which should be called at the end. + +There are 2 main 'packages'. x86ms.pl, which is the microsoft assembler, +and x86unix.pl which is the unix (gas) version. + +Functions of interest are: +&external_label("des_SPtrans"); declare and external variable +&LB(reg); Low byte for a register +&HB(reg); High byte for a register +&BP(off,base,index,scale) Byte pointer addressing +&DWP(off,base,index,scale) Word pointer addressing +&stack_push(num) Basically a 'sub esp, num*4' with extra +&stack_pop(num) inverse of stack_push +&function_begin(name,extra) Start a function with pushing of + edi, esi, ebx and ebp. extra is extra win32 + external info that may be required. +&function_begin_B(name,extra) Same as norma function_begin but no pushing. +&function_end(name) Call at end of function. +&function_end_A(name) Standard pop and ret, for use inside functions +&function_end_B(name) Call at end but with poping or 'ret'. +&swtmp(num) Address on stack temp word. +&wparam(num) Parameter number num, that was push + in C convention. This all works over pushes + and pops. +&comment("hello there") Put in a comment. +&label("loop") Refer to a label, normally a jmp target. +&set_label("loop") Set a label at this point. +&data_word(word) Put in a word of data. + +So how does this all hold together? Given + +int calc(int len, int *data) + { + int i,j=0; + + for (i=0; i. +# +# Why AT&T to MASM and not vice versa? Several reasons. Because AT&T +# format is way easier to parse. Because it's simpler to "gear" from +# Unix ABI to Windows one [see cross-reference "card" at the end of +# file]. Because Linux targets were available first... +# +# In addition the script also "distills" code suitable for GNU +# assembler, so that it can be compiled with more rigid assemblers, +# such as Solaris /usr/ccs/bin/as. +# +# This translator is not designed to convert *arbitrary* assembler +# code from AT&T format to MASM one. It's designed to convert just +# enough to provide for dual-ABI OpenSSL modules development... +# There *are* limitations and you might have to modify your assembler +# code or this script to achieve the desired result... +# +# Currently recognized limitations: +# +# - can't use multiple ops per line; +# +# Dual-ABI styling rules. +# +# 1. Adhere to Unix register and stack layout [see cross-reference +# ABI "card" at the end for explanation]. +# 2. Forget about "red zone," stick to more traditional blended +# stack frame allocation. If volatile storage is actually required +# that is. If not, just leave the stack as is. +# 3. Functions tagged with ".type name,@function" get crafted with +# unified Win64 prologue and epilogue automatically. If you want +# to take care of ABI differences yourself, tag functions as +# ".type name,@abi-omnipotent" instead. +# 4. To optimize the Win64 prologue you can specify number of input +# arguments as ".type name,@function,N." Keep in mind that if N is +# larger than 6, then you *have to* write "abi-omnipotent" code, +# because >6 cases can't be addressed with unified prologue. +# 5. Name local labels as .L*, do *not* use dynamic labels such as 1: +# (sorry about latter). +# 6. Don't use [or hand-code with .byte] "rep ret." "ret" mnemonic is +# required to identify the spots, where to inject Win64 epilogue! +# But on the pros, it's then prefixed with rep automatically:-) +# 7. Stick to explicit ip-relative addressing. If you have to use +# GOTPCREL addressing, stick to mov symbol@GOTPCREL(%rip),%r??. +# Both are recognized and translated to proper Win64 addressing +# modes. To support legacy code a synthetic directive, .picmeup, +# is implemented. It puts address of the *next* instruction into +# target register, e.g.: +# +# .picmeup %rax +# lea .Label-.(%rax),%rax +# +# 8. In order to provide for structured exception handling unified +# Win64 prologue copies %rsp value to %rax. For further details +# see SEH paragraph at the end. +# 9. .init segment is allowed to contain calls to functions only. +# a. If function accepts more than 4 arguments *and* >4th argument +# is declared as non 64-bit value, do clear its upper part. + +my $flavour = shift; +my $output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +open STDOUT,">$output" || die "can't open $output: $!" + if (defined($output)); + +my $gas=1; $gas=0 if ($output =~ /\.asm$/); +my $elf=1; $elf=0 if (!$gas); +my $win64=0; +my $prefix=""; +my $decor=".L"; + +my $masmref=8 + 50727*2**-32; # 8.00.50727 shipped with VS2005 +my $masm=0; +my $PTR=" PTR"; + +my $nasmref=2.03; +my $nasm=0; + +if ($flavour eq "mingw64") { $gas=1; $elf=0; $win64=1; + $prefix=`echo __USER_LABEL_PREFIX__ | $ENV{CC} -E -P -`; + chomp($prefix); + } +elsif ($flavour eq "macosx") { $gas=1; $elf=0; $prefix="_"; $decor="L\$"; } +elsif ($flavour eq "masm") { $gas=0; $elf=0; $masm=$masmref; $win64=1; $decor="\$L\$"; } +elsif ($flavour eq "nasm") { $gas=0; $elf=0; $nasm=$nasmref; $win64=1; $decor="\$L\$"; $PTR=""; } +elsif (!$gas) +{ if ($ENV{ASM} =~ m/nasm/ && `nasm -v` =~ m/version ([0-9]+)\.([0-9]+)/i) + { $nasm = $1 + $2*0.01; $PTR=""; } + elsif (`ml64 2>&1` =~ m/Version ([0-9]+)\.([0-9]+)(\.([0-9]+))?/) + { $masm = $1 + $2*2**-16 + $4*2**-32; } + die "no assembler found on %PATH" if (!($nasm || $masm)); + $win64=1; + $elf=0; + $decor="\$L\$"; +} + +my $current_segment; +my $current_function; +my %globals; + +{ package opcode; # pick up opcodes + sub re { + my $self = shift; # single instance in enough... + local *line = shift; + undef $ret; + + if ($line =~ /^([a-z][a-z0-9]*)/i) { + $self->{op} = $1; + $ret = $self; + $line = substr($line,@+[0]); $line =~ s/^\s+//; + + undef $self->{sz}; + if ($self->{op} =~ /^(movz)x?([bw]).*/) { # movz is pain... + $self->{op} = $1; + $self->{sz} = $2; + } elsif ($self->{op} =~ /call|jmp/) { + $self->{sz} = ""; + } elsif ($self->{op} =~ /^p/ && $' !~ /^(ush|op|insrw)/) { # SSEn + $self->{sz} = ""; + } elsif ($self->{op} =~ /^v/) { # VEX + $self->{sz} = ""; + } elsif ($self->{op} =~ /mov[dq]/ && $line =~ /%xmm/) { + $self->{sz} = ""; + } elsif ($self->{op} =~ /([a-z]{3,})([qlwb])$/) { + $self->{op} = $1; + $self->{sz} = $2; + } + } + $ret; + } + sub size { + my $self = shift; + my $sz = shift; + $self->{sz} = $sz if (defined($sz) && !defined($self->{sz})); + $self->{sz}; + } + sub out { + my $self = shift; + if ($gas) { + if ($self->{op} eq "movz") { # movz is pain... + sprintf "%s%s%s",$self->{op},$self->{sz},shift; + } elsif ($self->{op} =~ /^set/) { + "$self->{op}"; + } elsif ($self->{op} eq "ret") { + my $epilogue = ""; + if ($win64 && $current_function->{abi} eq "svr4") { + $epilogue = "movq 8(%rsp),%rdi\n\t" . + "movq 16(%rsp),%rsi\n\t"; + } + $epilogue . ".byte 0xf3,0xc3"; + } elsif ($self->{op} eq "call" && !$elf && $current_segment eq ".init") { + ".p2align\t3\n\t.quad"; + } else { + "$self->{op}$self->{sz}"; + } + } else { + $self->{op} =~ s/^movz/movzx/; + if ($self->{op} eq "ret") { + $self->{op} = ""; + if ($win64 && $current_function->{abi} eq "svr4") { + $self->{op} = "mov rdi,QWORD${PTR}[8+rsp]\t;WIN64 epilogue\n\t". + "mov rsi,QWORD${PTR}[16+rsp]\n\t"; + } + $self->{op} .= "DB\t0F3h,0C3h\t\t;repret"; + } elsif ($self->{op} =~ /^(pop|push)f/) { + $self->{op} .= $self->{sz}; + } elsif ($self->{op} eq "call" && $current_segment eq ".CRT\$XCU") { + $self->{op} = "\tDQ"; + } + $self->{op}; + } + } + sub mnemonic { + my $self=shift; + my $op=shift; + $self->{op}=$op if (defined($op)); + $self->{op}; + } +} +{ package const; # pick up constants, which start with $ + sub re { + my $self = shift; # single instance in enough... + local *line = shift; + undef $ret; + + if ($line =~ /^\$([^,]+)/) { + $self->{value} = $1; + $ret = $self; + $line = substr($line,@+[0]); $line =~ s/^\s+//; + } + $ret; + } + sub out { + my $self = shift; + + if ($gas) { + # Solaris /usr/ccs/bin/as can't handle multiplications + # in $self->{value} + $self->{value} =~ s/(?{value} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg; + sprintf "\$%s",$self->{value}; + } else { + $self->{value} =~ s/(0b[0-1]+)/oct($1)/eig; + $self->{value} =~ s/0x([0-9a-f]+)/0$1h/ig if ($masm); + sprintf "%s",$self->{value}; + } + } +} +{ package ea; # pick up effective addresses: expr(%reg,%reg,scale) + sub re { + my $self = shift; # single instance in enough... + local *line = shift; + undef $ret; + + # optional * ---vvv--- appears in indirect jmp/call + if ($line =~ /^(\*?)([^\(,]*)\(([%\w,]+)\)/) { + $self->{asterisk} = $1; + $self->{label} = $2; + ($self->{base},$self->{index},$self->{scale})=split(/,/,$3); + $self->{scale} = 1 if (!defined($self->{scale})); + $ret = $self; + $line = substr($line,@+[0]); $line =~ s/^\s+//; + + if ($win64 && $self->{label} =~ s/\@GOTPCREL//) { + die if (opcode->mnemonic() ne "mov"); + opcode->mnemonic("lea"); + } + $self->{base} =~ s/^%//; + $self->{index} =~ s/^%// if (defined($self->{index})); + } + $ret; + } + sub size {} + sub out { + my $self = shift; + my $sz = shift; + + $self->{label} =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei; + $self->{label} =~ s/\.L/$decor/g; + + # Silently convert all EAs to 64-bit. This is required for + # elder GNU assembler and results in more compact code, + # *but* most importantly AES module depends on this feature! + $self->{index} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/; + $self->{base} =~ s/^[er](.?[0-9xpi])[d]?$/r\1/; + + # Solaris /usr/ccs/bin/as can't handle multiplications + # in $self->{label}, new gas requires sign extension... + use integer; + $self->{label} =~ s/(?{label} =~ s/([0-9]+\s*[\*\/\%]\s*[0-9]+)/eval($1)/eg; + $self->{label} =~ s/([0-9]+)/$1<<32>>32/eg; + + if ($gas) { + $self->{label} =~ s/^___imp_/__imp__/ if ($flavour eq "mingw64"); + + if (defined($self->{index})) { + sprintf "%s%s(%s,%%%s,%d)",$self->{asterisk}, + $self->{label}, + $self->{base}?"%$self->{base}":"", + $self->{index},$self->{scale}; + } else { + sprintf "%s%s(%%%s)", $self->{asterisk},$self->{label},$self->{base}; + } + } else { + %szmap = ( b=>"BYTE$PTR", w=>"WORD$PTR", l=>"DWORD$PTR", + q=>"QWORD$PTR",o=>"OWORD$PTR",x=>"XMMWORD$PTR" ); + + $self->{label} =~ s/\./\$/g; + $self->{label} =~ s/(?{label} = "($self->{label})" if ($self->{label} =~ /[\*\+\-\/]/); + $sz="q" if ($self->{asterisk} || opcode->mnemonic() eq "movq"); + $sz="l" if (opcode->mnemonic() eq "movd"); + + if (defined($self->{index})) { + sprintf "%s[%s%s*%d%s]",$szmap{$sz}, + $self->{label}?"$self->{label}+":"", + $self->{index},$self->{scale}, + $self->{base}?"+$self->{base}":""; + } elsif ($self->{base} eq "rip") { + sprintf "%s[%s]",$szmap{$sz},$self->{label}; + } else { + sprintf "%s[%s%s]",$szmap{$sz}, + $self->{label}?"$self->{label}+":"", + $self->{base}; + } + } + } +} +{ package register; # pick up registers, which start with %. + sub re { + my $class = shift; # muliple instances... + my $self = {}; + local *line = shift; + undef $ret; + + # optional * ---vvv--- appears in indirect jmp/call + if ($line =~ /^(\*?)%(\w+)/) { + bless $self,$class; + $self->{asterisk} = $1; + $self->{value} = $2; + $ret = $self; + $line = substr($line,@+[0]); $line =~ s/^\s+//; + } + $ret; + } + sub size { + my $self = shift; + undef $ret; + + if ($self->{value} =~ /^r[\d]+b$/i) { $ret="b"; } + elsif ($self->{value} =~ /^r[\d]+w$/i) { $ret="w"; } + elsif ($self->{value} =~ /^r[\d]+d$/i) { $ret="l"; } + elsif ($self->{value} =~ /^r[\w]+$/i) { $ret="q"; } + elsif ($self->{value} =~ /^[a-d][hl]$/i){ $ret="b"; } + elsif ($self->{value} =~ /^[\w]{2}l$/i) { $ret="b"; } + elsif ($self->{value} =~ /^[\w]{2}$/i) { $ret="w"; } + elsif ($self->{value} =~ /^e[a-z]{2}$/i){ $ret="l"; } + + $ret; + } + sub out { + my $self = shift; + if ($gas) { sprintf "%s%%%s",$self->{asterisk},$self->{value}; } + else { $self->{value}; } + } +} +{ package label; # pick up labels, which end with : + sub re { + my $self = shift; # single instance is enough... + local *line = shift; + undef $ret; + + if ($line =~ /(^[\.\w]+)\:/) { + $self->{value} = $1; + $ret = $self; + $line = substr($line,@+[0]); $line =~ s/^\s+//; + + $self->{value} =~ s/^\.L/$decor/; + } + $ret; + } + sub out { + my $self = shift; + + if ($gas) { + my $func = ($globals{$self->{value}} or $self->{value}) . ":"; + if ($win64 && + $current_function->{name} eq $self->{value} && + $current_function->{abi} eq "svr4") { + $func .= "\n"; + $func .= " movq %rdi,8(%rsp)\n"; + $func .= " movq %rsi,16(%rsp)\n"; + $func .= " movq %rsp,%rax\n"; + $func .= "${decor}SEH_begin_$current_function->{name}:\n"; + my $narg = $current_function->{narg}; + $narg=6 if (!defined($narg)); + $func .= " movq %rcx,%rdi\n" if ($narg>0); + $func .= " movq %rdx,%rsi\n" if ($narg>1); + $func .= " movq %r8,%rdx\n" if ($narg>2); + $func .= " movq %r9,%rcx\n" if ($narg>3); + $func .= " movq 40(%rsp),%r8\n" if ($narg>4); + $func .= " movq 48(%rsp),%r9\n" if ($narg>5); + } + $func; + } elsif ($self->{value} ne "$current_function->{name}") { + $self->{value} .= ":" if ($masm && $ret!~m/^\$/); + $self->{value} . ":"; + } elsif ($win64 && $current_function->{abi} eq "svr4") { + my $func = "$current_function->{name}" . + ($nasm ? ":" : "\tPROC $current_function->{scope}") . + "\n"; + $func .= " mov QWORD${PTR}[8+rsp],rdi\t;WIN64 prologue\n"; + $func .= " mov QWORD${PTR}[16+rsp],rsi\n"; + $func .= " mov rax,rsp\n"; + $func .= "${decor}SEH_begin_$current_function->{name}:"; + $func .= ":" if ($masm); + $func .= "\n"; + my $narg = $current_function->{narg}; + $narg=6 if (!defined($narg)); + $func .= " mov rdi,rcx\n" if ($narg>0); + $func .= " mov rsi,rdx\n" if ($narg>1); + $func .= " mov rdx,r8\n" if ($narg>2); + $func .= " mov rcx,r9\n" if ($narg>3); + $func .= " mov r8,QWORD${PTR}[40+rsp]\n" if ($narg>4); + $func .= " mov r9,QWORD${PTR}[48+rsp]\n" if ($narg>5); + $func .= "\n"; + } else { + "$current_function->{name}". + ($nasm ? ":" : "\tPROC $current_function->{scope}"); + } + } +} +{ package expr; # pick up expressioins + sub re { + my $self = shift; # single instance is enough... + local *line = shift; + undef $ret; + + if ($line =~ /(^[^,]+)/) { + $self->{value} = $1; + $ret = $self; + $line = substr($line,@+[0]); $line =~ s/^\s+//; + + $self->{value} =~ s/\@PLT// if (!$elf); + $self->{value} =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei; + $self->{value} =~ s/\.L/$decor/g; + } + $ret; + } + sub out { + my $self = shift; + if ($nasm && opcode->mnemonic()=~m/^j/) { + "NEAR ".$self->{value}; + } else { + $self->{value}; + } + } +} +{ package directive; # pick up directives, which start with . + sub re { + my $self = shift; # single instance is enough... + local *line = shift; + undef $ret; + my $dir; + my %opcode = # lea 2f-1f(%rip),%dst; 1: nop; 2: + ( "%rax"=>0x01058d48, "%rcx"=>0x010d8d48, + "%rdx"=>0x01158d48, "%rbx"=>0x011d8d48, + "%rsp"=>0x01258d48, "%rbp"=>0x012d8d48, + "%rsi"=>0x01358d48, "%rdi"=>0x013d8d48, + "%r8" =>0x01058d4c, "%r9" =>0x010d8d4c, + "%r10"=>0x01158d4c, "%r11"=>0x011d8d4c, + "%r12"=>0x01258d4c, "%r13"=>0x012d8d4c, + "%r14"=>0x01358d4c, "%r15"=>0x013d8d4c ); + + if ($line =~ /^\s*(\.\w+)/) { + $dir = $1; + $ret = $self; + undef $self->{value}; + $line = substr($line,@+[0]); $line =~ s/^\s+//; + + SWITCH: for ($dir) { + /\.picmeup/ && do { if ($line =~ /(%r[\w]+)/i) { + $dir="\t.long"; + $line=sprintf "0x%x,0x90000000",$opcode{$1}; + } + last; + }; + /\.global|\.globl|\.extern/ + && do { $globals{$line} = $prefix . $line; + $line = $globals{$line} if ($prefix); + last; + }; + /\.type/ && do { ($sym,$type,$narg) = split(',',$line); + if ($type eq "\@function") { + undef $current_function; + $current_function->{name} = $sym; + $current_function->{abi} = "svr4"; + $current_function->{narg} = $narg; + $current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE"; + } elsif ($type eq "\@abi-omnipotent") { + undef $current_function; + $current_function->{name} = $sym; + $current_function->{scope} = defined($globals{$sym})?"PUBLIC":"PRIVATE"; + } + $line =~ s/\@abi\-omnipotent/\@function/; + $line =~ s/\@function.*/\@function/; + last; + }; + /\.asciz/ && do { if ($line =~ /^"(.*)"$/) { + $dir = ".byte"; + $line = join(",",unpack("C*",$1),0); + } + last; + }; + /\.rva|\.long|\.quad/ + && do { $line =~ s/([_a-z][_a-z0-9]*)/$globals{$1} or $1/gei; + $line =~ s/\.L/$decor/g; + last; + }; + } + + if ($gas) { + $self->{value} = $dir . "\t" . $line; + + if ($dir =~ /\.extern/) { + $self->{value} = ""; # swallow extern + } elsif (!$elf && $dir =~ /\.type/) { + $self->{value} = ""; + $self->{value} = ".def\t" . ($globals{$1} or $1) . ";\t" . + (defined($globals{$1})?".scl 2;":".scl 3;") . + "\t.type 32;\t.endef" + if ($win64 && $line =~ /([^,]+),\@function/); + } elsif (!$elf && $dir =~ /\.size/) { + $self->{value} = ""; + if (defined($current_function)) { + $self->{value} .= "${decor}SEH_end_$current_function->{name}:" + if ($win64 && $current_function->{abi} eq "svr4"); + undef $current_function; + } + } elsif (!$elf && $dir =~ /\.align/) { + $self->{value} = ".p2align\t" . (log($line)/log(2)); + } elsif ($dir eq ".section") { + $current_segment=$line; + if (!$elf && $current_segment eq ".init") { + if ($flavour eq "macosx") { $self->{value} = ".mod_init_func"; } + elsif ($flavour eq "mingw64") { $self->{value} = ".section\t.ctors"; } + } + } elsif ($dir =~ /\.(text|data)/) { + $current_segment=".$1"; + } elsif ($dir =~ /\.hidden/) { + if ($flavour eq "macosx") { $self->{value} = ".private_extern\t$prefix$line"; } + elsif ($flavour eq "mingw64") { $self->{value} = ""; } + } elsif ($dir =~ /\.comm/) { + $self->{value} = "$dir\t$prefix$line"; + $self->{value} =~ s|,([0-9]+),([0-9]+)$|",$1,".log($2)/log(2)|e if ($flavour eq "macosx"); + } + $line = ""; + return $self; + } + + # non-gas case or nasm/masm + SWITCH: for ($dir) { + /\.text/ && do { my $v=undef; + if ($nasm) { + $v="section .text code align=64\n"; + } else { + $v="$current_segment\tENDS\n" if ($current_segment); + $current_segment = ".text\$"; + $v.="$current_segment\tSEGMENT "; + $v.=$masm>=$masmref ? "ALIGN(64)" : "PAGE"; + $v.=" 'CODE'"; + } + $self->{value} = $v; + last; + }; + /\.data/ && do { my $v=undef; + if ($nasm) { + $v="section .data data align=8\n"; + } else { + $v="$current_segment\tENDS\n" if ($current_segment); + $current_segment = "_DATA"; + $v.="$current_segment\tSEGMENT"; + } + $self->{value} = $v; + last; + }; + /\.section/ && do { my $v=undef; + $line =~ s/([^,]*).*/$1/; + $line = ".CRT\$XCU" if ($line eq ".init"); + if ($nasm) { + $v="section $line"; + if ($line=~/\.([px])data/) { + $v.=" rdata align="; + $v.=$1 eq "p"? 4 : 8; + } elsif ($line=~/\.CRT\$/i) { + $v.=" rdata align=8"; + } + } else { + $v="$current_segment\tENDS\n" if ($current_segment); + $v.="$line\tSEGMENT"; + if ($line=~/\.([px])data/) { + $v.=" READONLY"; + $v.=" ALIGN(".($1 eq "p" ? 4 : 8).")" if ($masm>=$masmref); + } elsif ($line=~/\.CRT\$/i) { + $v.=" READONLY "; + $v.=$masm>=$masmref ? "ALIGN(8)" : "DWORD"; + } + } + $current_segment = $line; + $self->{value} = $v; + last; + }; + /\.extern/ && do { $self->{value} = "EXTERN\t".$line; + $self->{value} .= ":NEAR" if ($masm); + last; + }; + /\.globl|.global/ + && do { $self->{value} = $masm?"PUBLIC":"global"; + $self->{value} .= "\t".$line; + last; + }; + /\.size/ && do { if (defined($current_function)) { + undef $self->{value}; + if ($current_function->{abi} eq "svr4") { + $self->{value}="${decor}SEH_end_$current_function->{name}:"; + $self->{value}.=":\n" if($masm); + } + $self->{value}.="$current_function->{name}\tENDP" if($masm && $current_function->{name}); + undef $current_function; + } + last; + }; + /\.align/ && do { $self->{value} = "ALIGN\t".$line; last; }; + /\.(value|long|rva|quad)/ + && do { my $sz = substr($1,0,1); + my @arr = split(/,\s*/,$line); + my $last = pop(@arr); + my $conv = sub { my $var=shift; + $var=~s/^(0b[0-1]+)/oct($1)/eig; + $var=~s/^0x([0-9a-f]+)/0$1h/ig if ($masm); + if ($sz eq "D" && ($current_segment=~/.[px]data/ || $dir eq ".rva")) + { $var=~s/([_a-z\$\@][_a-z0-9\$\@]*)/$nasm?"$1 wrt ..imagebase":"imagerel $1"/egi; } + $var; + }; + + $sz =~ tr/bvlrq/BWDDQ/; + $self->{value} = "\tD$sz\t"; + for (@arr) { $self->{value} .= &$conv($_).","; } + $self->{value} .= &$conv($last); + last; + }; + /\.byte/ && do { my @str=split(/,\s*/,$line); + map(s/(0b[0-1]+)/oct($1)/eig,@str); + map(s/0x([0-9a-f]+)/0$1h/ig,@str) if ($masm); + while ($#str>15) { + $self->{value}.="DB\t" + .join(",",@str[0..15])."\n"; + foreach (0..15) { shift @str; } + } + $self->{value}.="DB\t" + .join(",",@str) if (@str); + last; + }; + /\.comm/ && do { my @str=split(/,\s*/,$line); + my $v=undef; + if ($nasm) { + $v.="common $prefix@str[0] @str[1]"; + } else { + $v="$current_segment\tENDS\n" if ($current_segment); + $current_segment = "_DATA"; + $v.="$current_segment\tSEGMENT\n"; + $v.="COMM @str[0]:DWORD:".@str[1]/4; + } + $self->{value} = $v; + last; + }; + } + $line = ""; + } + + $ret; + } + sub out { + my $self = shift; + $self->{value}; + } +} + +sub rex { + local *opcode=shift; + my ($dst,$src,$rex)=@_; + + $rex|=0x04 if($dst>=8); + $rex|=0x01 if($src>=8); + push @opcode,($rex|0x40) if ($rex); +} + +# older gas and ml64 don't handle SSE>2 instructions +my %regrm = ( "%eax"=>0, "%ecx"=>1, "%edx"=>2, "%ebx"=>3, + "%esp"=>4, "%ebp"=>5, "%esi"=>6, "%edi"=>7 ); + +my $movq = sub { # elderly gas can't handle inter-register movq + my $arg = shift; + my @opcode=(0x66); + if ($arg =~ /%xmm([0-9]+),\s*%r(\w+)/) { + my ($src,$dst)=($1,$2); + if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; } + rex(\@opcode,$src,$dst,0x8); + push @opcode,0x0f,0x7e; + push @opcode,0xc0|(($src&7)<<3)|($dst&7); # ModR/M + @opcode; + } elsif ($arg =~ /%r(\w+),\s*%xmm([0-9]+)/) { + my ($src,$dst)=($2,$1); + if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; } + rex(\@opcode,$src,$dst,0x8); + push @opcode,0x0f,0x6e; + push @opcode,0xc0|(($src&7)<<3)|($dst&7); # ModR/M + @opcode; + } else { + (); + } +}; + +my $pextrd = sub { + if (shift =~ /\$([0-9]+),\s*%xmm([0-9]+),\s*(%\w+)/) { + my @opcode=(0x66); + $imm=$1; + $src=$2; + $dst=$3; + if ($dst =~ /%r([0-9]+)d/) { $dst = $1; } + elsif ($dst =~ /%e/) { $dst = $regrm{$dst}; } + rex(\@opcode,$src,$dst); + push @opcode,0x0f,0x3a,0x16; + push @opcode,0xc0|(($src&7)<<3)|($dst&7); # ModR/M + push @opcode,$imm; + @opcode; + } else { + (); + } +}; + +my $pinsrd = sub { + if (shift =~ /\$([0-9]+),\s*(%\w+),\s*%xmm([0-9]+)/) { + my @opcode=(0x66); + $imm=$1; + $src=$2; + $dst=$3; + if ($src =~ /%r([0-9]+)/) { $src = $1; } + elsif ($src =~ /%e/) { $src = $regrm{$src}; } + rex(\@opcode,$dst,$src); + push @opcode,0x0f,0x3a,0x22; + push @opcode,0xc0|(($dst&7)<<3)|($src&7); # ModR/M + push @opcode,$imm; + @opcode; + } else { + (); + } +}; + +my $pshufb = sub { + if (shift =~ /%xmm([0-9]+),\s*%xmm([0-9]+)/) { + my @opcode=(0x66); + rex(\@opcode,$2,$1); + push @opcode,0x0f,0x38,0x00; + push @opcode,0xc0|($1&7)|(($2&7)<<3); # ModR/M + @opcode; + } else { + (); + } +}; + +my $palignr = sub { + if (shift =~ /\$([0-9]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) { + my @opcode=(0x66); + rex(\@opcode,$3,$2); + push @opcode,0x0f,0x3a,0x0f; + push @opcode,0xc0|($2&7)|(($3&7)<<3); # ModR/M + push @opcode,$1; + @opcode; + } else { + (); + } +}; + +my $pclmulqdq = sub { + if (shift =~ /\$([x0-9a-f]+),\s*%xmm([0-9]+),\s*%xmm([0-9]+)/) { + my @opcode=(0x66); + rex(\@opcode,$3,$2); + push @opcode,0x0f,0x3a,0x44; + push @opcode,0xc0|($2&7)|(($3&7)<<3); # ModR/M + my $c=$1; + push @opcode,$c=~/^0/?oct($c):$c; + @opcode; + } else { + (); + } +}; + +my $rdrand = sub { + if (shift =~ /%[er](\w+)/) { + my @opcode=(); + my $dst=$1; + if ($dst !~ /[0-9]+/) { $dst = $regrm{"%e$dst"}; } + rex(\@opcode,0,$1,8); + push @opcode,0x0f,0xc7,0xf0|($dst&7); + @opcode; + } else { + (); + } +}; + +if ($nasm) { + print <<___; +default rel +%define XMMWORD +___ +} elsif ($masm) { + print <<___; +OPTION DOTNAME +___ +} +while($line=<>) { + + chomp($line); + + $line =~ s|[#!].*$||; # get rid of asm-style comments... + $line =~ s|/\*.*\*/||; # ... and C-style comments... + $line =~ s|^\s+||; # ... and skip white spaces in beginning + + undef $label; + undef $opcode; + undef @args; + + if ($label=label->re(\$line)) { print $label->out(); } + + if (directive->re(\$line)) { + printf "%s",directive->out(); + } elsif ($opcode=opcode->re(\$line)) { + my $asm = eval("\$".$opcode->mnemonic()); + undef @bytes; + + if ((ref($asm) eq 'CODE') && scalar(@bytes=&$asm($line))) { + print $gas?".byte\t":"DB\t",join(',',@bytes),"\n"; + next; + } + + ARGUMENT: while (1) { + my $arg; + + if ($arg=register->re(\$line)) { opcode->size($arg->size()); } + elsif ($arg=const->re(\$line)) { } + elsif ($arg=ea->re(\$line)) { } + elsif ($arg=expr->re(\$line)) { } + else { last ARGUMENT; } + + push @args,$arg; + + last ARGUMENT if ($line !~ /^,/); + + $line =~ s/^,\s*//; + } # ARGUMENT: + + if ($#args>=0) { + my $insn; + my $sz=opcode->size(); + + if ($gas) { + $insn = $opcode->out($#args>=1?$args[$#args]->size():$sz); + @args = map($_->out($sz),@args); + printf "\t%s\t%s",$insn,join(",",@args); + } else { + $insn = $opcode->out(); + foreach (@args) { + my $arg = $_->out(); + # $insn.=$sz compensates for movq, pinsrw, ... + if ($arg =~ /^xmm[0-9]+$/) { $insn.=$sz; $sz="x" if(!$sz); last; } + if ($arg =~ /^mm[0-9]+$/) { $insn.=$sz; $sz="q" if(!$sz); last; } + } + @args = reverse(@args); + undef $sz if ($nasm && $opcode->mnemonic() eq "lea"); + printf "\t%s\t%s",$insn,join(",",map($_->out($sz),@args)); + } + } else { + printf "\t%s",$opcode->out(); + } + } + + print $line,"\n"; +} + +print "\n$current_segment\tENDS\n" if ($current_segment && $masm); +print "END\n" if ($masm); + +close STDOUT; + + ################################################# +# Cross-reference x86_64 ABI "card" +# +# Unix Win64 +# %rax * * +# %rbx - - +# %rcx #4 #1 +# %rdx #3 #2 +# %rsi #2 - +# %rdi #1 - +# %rbp - - +# %rsp - - +# %r8 #5 #3 +# %r9 #6 #4 +# %r10 * * +# %r11 * * +# %r12 - - +# %r13 - - +# %r14 - - +# %r15 - - +# +# (*) volatile register +# (-) preserved by callee +# (#) Nth argument, volatile +# +# In Unix terms top of stack is argument transfer area for arguments +# which could not be accomodated in registers. Or in other words 7th +# [integer] argument resides at 8(%rsp) upon function entry point. +# 128 bytes above %rsp constitute a "red zone" which is not touched +# by signal handlers and can be used as temporal storage without +# allocating a frame. +# +# In Win64 terms N*8 bytes on top of stack is argument transfer area, +# which belongs to/can be overwritten by callee. N is the number of +# arguments passed to callee, *but* not less than 4! This means that +# upon function entry point 5th argument resides at 40(%rsp), as well +# as that 32 bytes from 8(%rsp) can always be used as temporal +# storage [without allocating a frame]. One can actually argue that +# one can assume a "red zone" above stack pointer under Win64 as well. +# Point is that at apparently no occasion Windows kernel would alter +# the area above user stack pointer in true asynchronous manner... +# +# All the above means that if assembler programmer adheres to Unix +# register and stack layout, but disregards the "red zone" existense, +# it's possible to use following prologue and epilogue to "gear" from +# Unix to Win64 ABI in leaf functions with not more than 6 arguments. +# +# omnipotent_function: +# ifdef WIN64 +# movq %rdi,8(%rsp) +# movq %rsi,16(%rsp) +# movq %rcx,%rdi ; if 1st argument is actually present +# movq %rdx,%rsi ; if 2nd argument is actually ... +# movq %r8,%rdx ; if 3rd argument is ... +# movq %r9,%rcx ; if 4th argument ... +# movq 40(%rsp),%r8 ; if 5th ... +# movq 48(%rsp),%r9 ; if 6th ... +# endif +# ... +# ifdef WIN64 +# movq 8(%rsp),%rdi +# movq 16(%rsp),%rsi +# endif +# ret +# + ################################################# +# Win64 SEH, Structured Exception Handling. +# +# Unlike on Unix systems(*) lack of Win64 stack unwinding information +# has undesired side-effect at run-time: if an exception is raised in +# assembler subroutine such as those in question (basically we're +# referring to segmentation violations caused by malformed input +# parameters), the application is briskly terminated without invoking +# any exception handlers, most notably without generating memory dump +# or any user notification whatsoever. This poses a problem. It's +# possible to address it by registering custom language-specific +# handler that would restore processor context to the state at +# subroutine entry point and return "exception is not handled, keep +# unwinding" code. Writing such handler can be a challenge... But it's +# doable, though requires certain coding convention. Consider following +# snippet: +# +# .type function,@function +# function: +# movq %rsp,%rax # copy rsp to volatile register +# pushq %r15 # save non-volatile registers +# pushq %rbx +# pushq %rbp +# movq %rsp,%r11 +# subq %rdi,%r11 # prepare [variable] stack frame +# andq $-64,%r11 +# movq %rax,0(%r11) # check for exceptions +# movq %r11,%rsp # allocate [variable] stack frame +# movq %rax,0(%rsp) # save original rsp value +# magic_point: +# ... +# movq 0(%rsp),%rcx # pull original rsp value +# movq -24(%rcx),%rbp # restore non-volatile registers +# movq -16(%rcx),%rbx +# movq -8(%rcx),%r15 +# movq %rcx,%rsp # restore original rsp +# ret +# .size function,.-function +# +# The key is that up to magic_point copy of original rsp value remains +# in chosen volatile register and no non-volatile register, except for +# rsp, is modified. While past magic_point rsp remains constant till +# the very end of the function. In this case custom language-specific +# exception handler would look like this: +# +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +# { ULONG64 *rsp = (ULONG64 *)context->Rax; +# if (context->Rip >= magic_point) +# { rsp = ((ULONG64 **)context->Rsp)[0]; +# context->Rbp = rsp[-3]; +# context->Rbx = rsp[-2]; +# context->R15 = rsp[-1]; +# } +# context->Rsp = (ULONG64)rsp; +# context->Rdi = rsp[1]; +# context->Rsi = rsp[2]; +# +# memcpy (disp->ContextRecord,context,sizeof(CONTEXT)); +# RtlVirtualUnwind(UNW_FLAG_NHANDLER,disp->ImageBase, +# dips->ControlPc,disp->FunctionEntry,disp->ContextRecord, +# &disp->HandlerData,&disp->EstablisherFrame,NULL); +# return ExceptionContinueSearch; +# } +# +# It's appropriate to implement this handler in assembler, directly in +# function's module. In order to do that one has to know members' +# offsets in CONTEXT and DISPATCHER_CONTEXT structures and some constant +# values. Here they are: +# +# CONTEXT.Rax 120 +# CONTEXT.Rcx 128 +# CONTEXT.Rdx 136 +# CONTEXT.Rbx 144 +# CONTEXT.Rsp 152 +# CONTEXT.Rbp 160 +# CONTEXT.Rsi 168 +# CONTEXT.Rdi 176 +# CONTEXT.R8 184 +# CONTEXT.R9 192 +# CONTEXT.R10 200 +# CONTEXT.R11 208 +# CONTEXT.R12 216 +# CONTEXT.R13 224 +# CONTEXT.R14 232 +# CONTEXT.R15 240 +# CONTEXT.Rip 248 +# CONTEXT.Xmm6 512 +# sizeof(CONTEXT) 1232 +# DISPATCHER_CONTEXT.ControlPc 0 +# DISPATCHER_CONTEXT.ImageBase 8 +# DISPATCHER_CONTEXT.FunctionEntry 16 +# DISPATCHER_CONTEXT.EstablisherFrame 24 +# DISPATCHER_CONTEXT.TargetIp 32 +# DISPATCHER_CONTEXT.ContextRecord 40 +# DISPATCHER_CONTEXT.LanguageHandler 48 +# DISPATCHER_CONTEXT.HandlerData 56 +# UNW_FLAG_NHANDLER 0 +# ExceptionContinueSearch 1 +# +# In order to tie the handler to the function one has to compose +# couple of structures: one for .xdata segment and one for .pdata. +# +# UNWIND_INFO structure for .xdata segment would be +# +# function_unwind_info: +# .byte 9,0,0,0 +# .rva handler +# +# This structure designates exception handler for a function with +# zero-length prologue, no stack frame or frame register. +# +# To facilitate composing of .pdata structures, auto-generated "gear" +# prologue copies rsp value to rax and denotes next instruction with +# .LSEH_begin_{function_name} label. This essentially defines the SEH +# styling rule mentioned in the beginning. Position of this label is +# chosen in such manner that possible exceptions raised in the "gear" +# prologue would be accounted to caller and unwound from latter's frame. +# End of function is marked with respective .LSEH_end_{function_name} +# label. To summarize, .pdata segment would contain +# +# .rva .LSEH_begin_function +# .rva .LSEH_end_function +# .rva function_unwind_info +# +# Reference to functon_unwind_info from .xdata segment is the anchor. +# In case you wonder why references are 32-bit .rvas and not 64-bit +# .quads. References put into these two segments are required to be +# *relative* to the base address of the current binary module, a.k.a. +# image base. No Win64 module, be it .exe or .dll, can be larger than +# 2GB and thus such relative references can be and are accommodated in +# 32 bits. +# +# Having reviewed the example function code, one can argue that "movq +# %rsp,%rax" above is redundant. It is not! Keep in mind that on Unix +# rax would contain an undefined value. If this "offends" you, use +# another register and refrain from modifying rax till magic_point is +# reached, i.e. as if it was a non-volatile register. If more registers +# are required prior [variable] frame setup is completed, note that +# nobody says that you can have only one "magic point." You can +# "liberate" non-volatile registers by denoting last stack off-load +# instruction and reflecting it in finer grade unwind logic in handler. +# After all, isn't it why it's called *language-specific* handler... +# +# Attentive reader can notice that exceptions would be mishandled in +# auto-generated "gear" epilogue. Well, exception effectively can't +# occur there, because if memory area used by it was subject to +# segmentation violation, then it would be raised upon call to the +# function (and as already mentioned be accounted to caller, which is +# not a problem). If you're still not comfortable, then define tail +# "magic point" just prior ret instruction and have handler treat it... +# +# (*) Note that we're talking about run-time, not debug-time. Lack of +# unwind information makes debugging hard on both Windows and +# Unix. "Unlike" referes to the fact that on Unix signal handler +# will always be invoked, core dumped and appropriate exit code +# returned to parent (for user notification). diff --git a/libs/openssl/crypto/perlasm/x86asm.pl b/libs/openssl/crypto/perlasm/x86asm.pl new file mode 100644 index 00000000..eb543db2 --- /dev/null +++ b/libs/openssl/crypto/perlasm/x86asm.pl @@ -0,0 +1,260 @@ +#!/usr/bin/env perl + +# require 'x86asm.pl'; +# &asm_init(,"des-586.pl"[,$i386only]); +# &function_begin("foo"); +# ... +# &function_end("foo"); +# &asm_finish + +$out=(); +$i386=0; + +# AUTOLOAD is this context has quite unpleasant side effect, namely +# that typos in function calls effectively go to assembler output, +# but on the pros side we don't have to implement one subroutine per +# each opcode... +sub ::AUTOLOAD +{ my $opcode = $AUTOLOAD; + + die "more than 4 arguments passed to $opcode" if ($#_>3); + + $opcode =~ s/.*:://; + if ($opcode =~ /^push/) { $stack+=4; } + elsif ($opcode =~ /^pop/) { $stack-=4; } + + &generic($opcode,@_) or die "undefined subroutine \&$AUTOLOAD"; +} + +sub ::emit +{ my $opcode=shift; + + if ($#_==-1) { push(@out,"\t$opcode\n"); } + else { push(@out,"\t$opcode\t".join(',',@_)."\n"); } +} + +sub ::LB +{ $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'low byte'"; + $1."l"; +} +sub ::HB +{ $_[0] =~ m/^e?([a-d])x$/o or die "$_[0] does not have a 'high byte'"; + $1."h"; +} +sub ::stack_push{ my $num=$_[0]*4; $stack+=$num; &sub("esp",$num); } +sub ::stack_pop { my $num=$_[0]*4; $stack-=$num; &add("esp",$num); } +sub ::blindpop { &pop($_[0]); $stack+=4; } +sub ::wparam { &DWP($stack+4*$_[0],"esp"); } +sub ::swtmp { &DWP(4*$_[0],"esp"); } + +sub ::bswap +{ if ($i386) # emulate bswap for i386 + { &comment("bswap @_"); + &xchg(&HB(@_),&LB(@_)); + &ror (@_,16); + &xchg(&HB(@_),&LB(@_)); + } + else + { &generic("bswap",@_); } +} +# These are made-up opcodes introduced over the years essentially +# by ignorance, just alias them to real ones... +sub ::movb { &mov(@_); } +sub ::xorb { &xor(@_); } +sub ::rotl { &rol(@_); } +sub ::rotr { &ror(@_); } +sub ::exch { &xchg(@_); } +sub ::halt { &hlt; } +sub ::movz { &movzx(@_); } +sub ::pushf { &pushfd; } +sub ::popf { &popfd; } + +# 3 argument instructions +sub ::movq +{ my($p1,$p2,$optimize)=@_; + + if ($optimize && $p1=~/^mm[0-7]$/ && $p2=~/^mm[0-7]$/) + # movq between mmx registers can sink Intel CPUs + { &::pshufw($p1,$p2,0xe4); } + else + { &::generic("movq",@_); } +} + +# SSE>2 instructions +my %regrm = ( "eax"=>0, "ecx"=>1, "edx"=>2, "ebx"=>3, + "esp"=>4, "ebp"=>5, "esi"=>6, "edi"=>7 ); +sub ::pextrd +{ my($dst,$src,$imm)=@_; + if ("$dst:$src" =~ /(e[a-dsd][ixp]):xmm([0-7])/) + { &::data_byte(0x66,0x0f,0x3a,0x16,0xc0|($2<<3)|$regrm{$1},$imm); } + else + { &::generic("pextrd",@_); } +} + +sub ::pinsrd +{ my($dst,$src,$imm)=@_; + if ("$dst:$src" =~ /xmm([0-7]):(e[a-dsd][ixp])/) + { &::data_byte(0x66,0x0f,0x3a,0x22,0xc0|($1<<3)|$regrm{$2},$imm); } + else + { &::generic("pinsrd",@_); } +} + +sub ::pshufb +{ my($dst,$src)=@_; + if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/) + { &data_byte(0x66,0x0f,0x38,0x00,0xc0|($1<<3)|$2); } + else + { &::generic("pshufb",@_); } +} + +sub ::palignr +{ my($dst,$src,$imm)=@_; + if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/) + { &::data_byte(0x66,0x0f,0x3a,0x0f,0xc0|($1<<3)|$2,$imm); } + else + { &::generic("palignr",@_); } +} + +sub ::pclmulqdq +{ my($dst,$src,$imm)=@_; + if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/) + { &::data_byte(0x66,0x0f,0x3a,0x44,0xc0|($1<<3)|$2,$imm); } + else + { &::generic("pclmulqdq",@_); } +} + +sub ::rdrand +{ my ($dst)=@_; + if ($dst =~ /(e[a-dsd][ixp])/) + { &::data_byte(0x0f,0xc7,0xf0|$regrm{$dst}); } + else + { &::generic("rdrand",@_); } +} + +# label management +$lbdecor="L"; # local label decoration, set by package +$label="000"; + +sub ::islabel # see is argument is a known label +{ my $i; + foreach $i (values %label) { return $i if ($i eq $_[0]); } + $label{$_[0]}; # can be undef +} + +sub ::label # instantiate a function-scope label +{ if (!defined($label{$_[0]})) + { $label{$_[0]}="${lbdecor}${label}${_[0]}"; $label++; } + $label{$_[0]}; +} + +sub ::LABEL # instantiate a file-scope label +{ $label{$_[0]}=$_[1] if (!defined($label{$_[0]})); + $label{$_[0]}; +} + +sub ::static_label { &::LABEL($_[0],$lbdecor.$_[0]); } + +sub ::set_label_B { push(@out,"@_:\n"); } +sub ::set_label +{ my $label=&::label($_[0]); + &::align($_[1]) if ($_[1]>1); + &::set_label_B($label); + $label; +} + +sub ::wipe_labels # wipes function-scope labels +{ foreach $i (keys %label) + { delete $label{$i} if ($label{$i} =~ /^\Q${lbdecor}\E[0-9]{3}/); } +} + +# subroutine management +sub ::function_begin +{ &function_begin_B(@_); + $stack=4; + &push("ebp"); + &push("ebx"); + &push("esi"); + &push("edi"); +} + +sub ::function_end +{ &pop("edi"); + &pop("esi"); + &pop("ebx"); + &pop("ebp"); + &ret(); + &function_end_B(@_); + $stack=0; + &wipe_labels(); +} + +sub ::function_end_A +{ &pop("edi"); + &pop("esi"); + &pop("ebx"); + &pop("ebp"); + &ret(); + $stack+=16; # readjust esp as if we didn't pop anything +} + +sub ::asciz +{ my @str=unpack("C*",shift); + push @str,0; + while ($#str>15) { + &data_byte(@str[0..15]); + foreach (0..15) { shift @str; } + } + &data_byte(@str) if (@str); +} + +sub ::asm_finish +{ &file_end(); + print @out; +} + +sub ::asm_init +{ my ($type,$fn,$cpu)=@_; + + $filename=$fn; + $i386=$cpu; + + $elf=$cpp=$coff=$aout=$macosx=$win32=$netware=$mwerks=$android=0; + if (($type eq "elf")) + { $elf=1; require "x86gas.pl"; } + elsif (($type eq "a\.out")) + { $aout=1; require "x86gas.pl"; } + elsif (($type eq "coff" or $type eq "gaswin")) + { $coff=1; require "x86gas.pl"; } + elsif (($type eq "win32n")) + { $win32=1; require "x86nasm.pl"; } + elsif (($type eq "nw-nasm")) + { $netware=1; require "x86nasm.pl"; } + #elsif (($type eq "nw-mwasm")) + #{ $netware=1; $mwerks=1; require "x86nasm.pl"; } + elsif (($type eq "win32")) + { $win32=1; require "x86masm.pl"; } + elsif (($type eq "macosx")) + { $aout=1; $macosx=1; require "x86gas.pl"; } + elsif (($type eq "android")) + { $elf=1; $android=1; require "x86gas.pl"; } + else + { print STDERR <<"EOF"; +Pick one target type from + elf - Linux, FreeBSD, Solaris x86, etc. + a.out - DJGPP, elder OpenBSD, etc. + coff - GAS/COFF such as Win32 targets + win32n - Windows 95/Windows NT NASM format + nw-nasm - NetWare NASM format + macosx - Mac OS X +EOF + exit(1); + } + + $pic=0; + for (@ARGV) { $pic=1 if (/\-[fK]PIC/i); } + + $filename =~ s/\.pl$//; + &file($filename); +} + +1; diff --git a/libs/openssl/crypto/perlasm/x86gas.pl b/libs/openssl/crypto/perlasm/x86gas.pl new file mode 100644 index 00000000..682a3a31 --- /dev/null +++ b/libs/openssl/crypto/perlasm/x86gas.pl @@ -0,0 +1,253 @@ +#!/usr/bin/env perl + +package x86gas; + +*out=\@::out; + +$::lbdecor=$::aout?"L":".L"; # local label decoration +$nmdecor=($::aout or $::coff)?"_":""; # external name decoration + +$initseg=""; + +$align=16; +$align=log($align)/log(2) if ($::aout); +$com_start="#" if ($::aout or $::coff); + +sub opsize() +{ my $reg=shift; + if ($reg =~ m/^%e/o) { "l"; } + elsif ($reg =~ m/^%[a-d][hl]$/o) { "b"; } + elsif ($reg =~ m/^%[xm]/o) { undef; } + else { "w"; } +} + +# swap arguments; +# expand opcode with size suffix; +# prefix numeric constants with $; +sub ::generic +{ my($opcode,@arg)=@_; + my($suffix,$dst,$src); + + @arg=reverse(@arg); + + for (@arg) + { s/^(\*?)(e?[a-dsixphl]{2})$/$1%$2/o; # gp registers + s/^([xy]?mm[0-7])$/%$1/o; # xmm/mmx registers + s/^(\-?[0-9]+)$/\$$1/o; # constants + s/^(\-?0x[0-9a-f]+)$/\$$1/o; # constants + } + + $dst = $arg[$#arg] if ($#arg>=0); + $src = $arg[$#arg-1] if ($#arg>=1); + if ($dst =~ m/^%/o) { $suffix=&opsize($dst); } + elsif ($src =~ m/^%/o) { $suffix=&opsize($src); } + else { $suffix="l"; } + undef $suffix if ($dst =~ m/^%[xm]/o || $src =~ m/^%[xm]/o); + + if ($#_==0) { &::emit($opcode); } + elsif ($#_==1 && $opcode =~ m/^(call|clflush|j|loop|set)/o) + { &::emit($opcode,@arg); } + else { &::emit($opcode.$suffix,@arg);} + + 1; +} +# +# opcodes not covered by ::generic above, mostly inconsistent namings... +# +sub ::movzx { &::movzb(@_); } +sub ::pushfd { &::pushfl; } +sub ::popfd { &::popfl; } +sub ::cpuid { &::emit(".byte\t0x0f,0xa2"); } +sub ::rdtsc { &::emit(".byte\t0x0f,0x31"); } + +sub ::call { &::emit("call",(&::islabel($_[0]) or "$nmdecor$_[0]")); } +sub ::call_ptr { &::generic("call","*$_[0]"); } +sub ::jmp_ptr { &::generic("jmp","*$_[0]"); } + +*::bswap = sub { &::emit("bswap","%$_[0]"); } if (!$::i386); + +sub ::DWP +{ my($addr,$reg1,$reg2,$idx)=@_; + my $ret=""; + + $addr =~ s/^\s+//; + # prepend global references with optional underscore + $addr =~ s/^([^\+\-0-9][^\+\-]*)/&::islabel($1) or "$nmdecor$1"/ige; + + $reg1 = "%$reg1" if ($reg1); + $reg2 = "%$reg2" if ($reg2); + + $ret .= $addr if (($addr ne "") && ($addr ne 0)); + + if ($reg2) + { $idx!= 0 or $idx=1; + $ret .= "($reg1,$reg2,$idx)"; + } + elsif ($reg1) + { $ret .= "($reg1)"; } + + $ret; +} +sub ::QWP { &::DWP(@_); } +sub ::BP { &::DWP(@_); } +sub ::WP { &::DWP(@_); } +sub ::BC { @_; } +sub ::DWC { @_; } + +sub ::file +{ push(@out,".file\t\"$_[0].s\"\n.text\n"); } + +sub ::function_begin_B +{ my $func=shift; + my $global=($func !~ /^_/); + my $begin="${::lbdecor}_${func}_begin"; + + &::LABEL($func,$global?"$begin":"$nmdecor$func"); + $func=$nmdecor.$func; + + push(@out,".globl\t$func\n") if ($global); + if ($::coff) + { push(@out,".def\t$func;\t.scl\t".(3-$global).";\t.type\t32;\t.endef\n"); } + elsif (($::aout and !$::pic) or $::macosx) + { } + else + { push(@out,".type $func,\@function\n"); } + push(@out,".align\t$align\n"); + push(@out,"$func:\n"); + push(@out,"$begin:\n") if ($global); + $::stack=4; +} + +sub ::function_end_B +{ my $func=shift; + push(@out,".size\t$nmdecor$func,.-".&::LABEL($func)."\n") if ($::elf); + $::stack=0; + &::wipe_labels(); +} + +sub ::comment + { + if (!defined($com_start) or $::elf) + { # Regarding $::elf above... + # GNU and SVR4 as'es use different comment delimiters, + push(@out,"\n"); # so we just skip ELF comments... + return; + } + foreach (@_) + { + if (/^\s*$/) + { push(@out,"\n"); } + else + { push(@out,"\t$com_start $_ $com_end\n"); } + } + } + +sub ::external_label +{ foreach(@_) { &::LABEL($_,$nmdecor.$_); } } + +sub ::public_label +{ push(@out,".globl\t".&::LABEL($_[0],$nmdecor.$_[0])."\n"); } + +sub ::file_end +{ if ($::macosx) + { if (%non_lazy_ptr) + { push(@out,".section __IMPORT,__pointers,non_lazy_symbol_pointers\n"); + foreach $i (keys %non_lazy_ptr) + { push(@out,"$non_lazy_ptr{$i}:\n.indirect_symbol\t$i\n.long\t0\n"); } + } + } + if (grep {/\b${nmdecor}OPENSSL_ia32cap_P\b/i} @out) { + my $tmp=".comm\t${nmdecor}OPENSSL_ia32cap_P,8"; + if ($::macosx) { push (@out,"$tmp,2\n"); } + elsif ($::elf) { push (@out,"$tmp,4\n"); } + else { push (@out,"$tmp\n"); } + } + push(@out,$initseg) if ($initseg); +} + +sub ::data_byte { push(@out,".byte\t".join(',',@_)."\n"); } +sub ::data_short{ push(@out,".value\t".join(',',@_)."\n"); } +sub ::data_word { push(@out,".long\t".join(',',@_)."\n"); } + +sub ::align +{ my $val=$_[0],$p2,$i; + if ($::aout) + { for ($p2=0;$val!=0;$val>>=1) { $p2++; } + $val=$p2-1; + $val.=",0x90"; + } + push(@out,".align\t$val\n"); +} + +sub ::picmeup +{ my($dst,$sym,$base,$reflabel)=@_; + + if (($::pic && ($::elf || $::aout)) || $::macosx) + { if (!defined($base)) + { &::call(&::label("PIC_me_up")); + &::set_label("PIC_me_up"); + &::blindpop($dst); + $base=$dst; + $reflabel=&::label("PIC_me_up"); + } + if ($::macosx) + { my $indirect=&::static_label("$nmdecor$sym\$non_lazy_ptr"); + &::mov($dst,&::DWP("$indirect-$reflabel",$base)); + $non_lazy_ptr{"$nmdecor$sym"}=$indirect; + } + else + { &::lea($dst,&::DWP("_GLOBAL_OFFSET_TABLE_+[.-$reflabel]", + $base)); + &::mov($dst,&::DWP("$sym\@GOT",$dst)); + } + } + else + { &::lea($dst,&::DWP($sym)); } +} + +sub ::initseg +{ my $f=$nmdecor.shift; + + if ($::android) + { $initseg.=<<___; +.section .init_array +.align 4 +.long $f +___ + } + elsif ($::elf) + { $initseg.=<<___; +.section .init + call $f +___ + } + elsif ($::coff) + { $initseg.=<<___; # applies to both Cygwin and Mingw +.section .ctors +.long $f +___ + } + elsif ($::macosx) + { $initseg.=<<___; +.mod_init_func +.align 2 +.long $f +___ + } + elsif ($::aout) + { my $ctor="${nmdecor}_GLOBAL_\$I\$$f"; + $initseg.=".text\n"; + $initseg.=".type $ctor,\@function\n" if ($::pic); + $initseg.=<<___; # OpenBSD way... +.globl $ctor +.align 2 +$ctor: + jmp $f +___ + } +} + +sub ::dataseg +{ push(@out,".data\n"); } + +1; diff --git a/libs/openssl/crypto/perlasm/x86masm.pl b/libs/openssl/crypto/perlasm/x86masm.pl new file mode 100644 index 00000000..f937d07c --- /dev/null +++ b/libs/openssl/crypto/perlasm/x86masm.pl @@ -0,0 +1,198 @@ +#!/usr/bin/env perl + +package x86masm; + +*out=\@::out; + +$::lbdecor="\$L"; # local label decoration +$nmdecor="_"; # external name decoration + +$initseg=""; +$segment=""; + +sub ::generic +{ my ($opcode,@arg)=@_; + + # fix hexadecimal constants + for (@arg) { s/(?= 0x02030000\n"); + push(@out,"safeseh ".&::LABEL($nm,$nmdecor.$nm)."\n"); + push(@out,"%endif\n"); +} + +1; diff --git a/libs/openssl/crypto/pkcs12/p12_add.c b/libs/openssl/crypto/pkcs12/p12_add.c new file mode 100644 index 00000000..d9f03a39 --- /dev/null +++ b/libs/openssl/crypto/pkcs12/p12_add.c @@ -0,0 +1,258 @@ +/* p12_add.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +/* Pack an object into an OCTET STRING and turn into a safebag */ + +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, + int nid1, int nid2) +{ + PKCS12_BAGS *bag; + PKCS12_SAFEBAG *safebag; + if (!(bag = PKCS12_BAGS_new())) { + PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); + return NULL; + } + bag->type = OBJ_nid2obj(nid1); + if (!ASN1_item_pack(obj, it, &bag->value.octet)) { + PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!(safebag = PKCS12_SAFEBAG_new())) { + PKCS12err(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG, ERR_R_MALLOC_FAILURE); + goto err; + } + safebag->value.bag = bag; + safebag->type = OBJ_nid2obj(nid2); + return safebag; + + err: + PKCS12_BAGS_free(bag); + return NULL; +} + +/* Turn PKCS8 object into a keybag */ + +PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8) +{ + PKCS12_SAFEBAG *bag; + if (!(bag = PKCS12_SAFEBAG_new())) { + PKCS12err(PKCS12_F_PKCS12_MAKE_KEYBAG, ERR_R_MALLOC_FAILURE); + return NULL; + } + bag->type = OBJ_nid2obj(NID_keyBag); + bag->value.keybag = p8; + return bag; +} + +/* Turn PKCS8 object into a shrouded keybag */ + +PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, + int passlen, unsigned char *salt, + int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8) +{ + PKCS12_SAFEBAG *bag; + const EVP_CIPHER *pbe_ciph; + + /* Set up the safe bag */ + if (!(bag = PKCS12_SAFEBAG_new())) { + PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); + return NULL; + } + + bag->type = OBJ_nid2obj(NID_pkcs8ShroudedKeyBag); + + pbe_ciph = EVP_get_cipherbynid(pbe_nid); + + if (pbe_ciph) + pbe_nid = -1; + + if (!(bag->value.shkeybag = + PKCS8_encrypt(pbe_nid, pbe_ciph, pass, passlen, salt, saltlen, iter, + p8))) { + PKCS12err(PKCS12_F_PKCS12_MAKE_SHKEYBAG, ERR_R_MALLOC_FAILURE); + PKCS12_SAFEBAG_free(bag); + return NULL; + } + + return bag; +} + +/* Turn a stack of SAFEBAGS into a PKCS#7 data Contentinfo */ +PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk) +{ + PKCS7 *p7; + if (!(p7 = PKCS7_new())) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE); + return NULL; + } + p7->type = OBJ_nid2obj(NID_pkcs7_data); + if (!(p7->d.data = M_ASN1_OCTET_STRING_new())) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!ASN1_item_pack(sk, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), &p7->d.data)) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7DATA, PKCS12_R_CANT_PACK_STRUCTURE); + goto err; + } + return p7; + + err: + PKCS7_free(p7); + return NULL; +} + +/* Unpack SAFEBAGS from PKCS#7 data ContentInfo */ +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7) +{ + if (!PKCS7_type_is_data(p7)) { + PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA, + PKCS12_R_CONTENT_TYPE_NOT_DATA); + return NULL; + } + return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS)); +} + +/* Turn a stack of SAFEBAGS into a PKCS#7 encrypted data ContentInfo */ + +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + STACK_OF(PKCS12_SAFEBAG) *bags) +{ + PKCS7 *p7; + X509_ALGOR *pbe; + const EVP_CIPHER *pbe_ciph; + if (!(p7 = PKCS7_new())) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!PKCS7_set_type(p7, NID_pkcs7_encrypted)) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, + PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE); + goto err; + } + + pbe_ciph = EVP_get_cipherbynid(pbe_nid); + + if (pbe_ciph) + pbe = PKCS5_pbe2_set(pbe_ciph, iter, salt, saltlen); + else + pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); + + if (!pbe) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, ERR_R_MALLOC_FAILURE); + goto err; + } + X509_ALGOR_free(p7->d.encrypted->enc_data->algorithm); + p7->d.encrypted->enc_data->algorithm = pbe; + M_ASN1_OCTET_STRING_free(p7->d.encrypted->enc_data->enc_data); + if (!(p7->d.encrypted->enc_data->enc_data = + PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS12_SAFEBAGS), pass, + passlen, bags, 1))) { + PKCS12err(PKCS12_F_PKCS12_PACK_P7ENCDATA, PKCS12_R_ENCRYPT_ERROR); + goto err; + } + + return p7; + + err: + PKCS7_free(p7); + return NULL; +} + +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, + int passlen) +{ + if (!PKCS7_type_is_encrypted(p7)) + return NULL; + return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm, + ASN1_ITEM_rptr(PKCS12_SAFEBAGS), + pass, passlen, + p7->d.encrypted->enc_data->enc_data, 1); +} + +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, + const char *pass, int passlen) +{ + return PKCS8_decrypt(bag->value.shkeybag, pass, passlen); +} + +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes) +{ + if (ASN1_item_pack(safes, ASN1_ITEM_rptr(PKCS12_AUTHSAFES), + &p12->authsafes->d.data)) + return 1; + return 0; +} + +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12) +{ + if (!PKCS7_type_is_data(p12->authsafes)) { + PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES, + PKCS12_R_CONTENT_TYPE_NOT_DATA); + return NULL; + } + return ASN1_item_unpack(p12->authsafes->d.data, + ASN1_ITEM_rptr(PKCS12_AUTHSAFES)); +} diff --git a/libs/openssl/crypto/pkcs12/p12_asn.c b/libs/openssl/crypto/pkcs12/p12_asn.c new file mode 100644 index 00000000..370ddbd6 --- /dev/null +++ b/libs/openssl/crypto/pkcs12/p12_asn.c @@ -0,0 +1,125 @@ +/* p12_asn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include + +/* PKCS#12 ASN1 module */ + +ASN1_SEQUENCE(PKCS12) = { + ASN1_SIMPLE(PKCS12, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS12, authsafes, PKCS7), + ASN1_OPT(PKCS12, mac, PKCS12_MAC_DATA) +} ASN1_SEQUENCE_END(PKCS12) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS12) + +ASN1_SEQUENCE(PKCS12_MAC_DATA) = { + ASN1_SIMPLE(PKCS12_MAC_DATA, dinfo, X509_SIG), + ASN1_SIMPLE(PKCS12_MAC_DATA, salt, ASN1_OCTET_STRING), + ASN1_OPT(PKCS12_MAC_DATA, iter, ASN1_INTEGER) +} ASN1_SEQUENCE_END(PKCS12_MAC_DATA) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS12_MAC_DATA) + +ASN1_ADB_TEMPLATE(bag_default) = ASN1_EXP(PKCS12_BAGS, value.other, ASN1_ANY, 0); + +ASN1_ADB(PKCS12_BAGS) = { + ADB_ENTRY(NID_x509Certificate, ASN1_EXP(PKCS12_BAGS, value.x509cert, ASN1_OCTET_STRING, 0)), + ADB_ENTRY(NID_x509Crl, ASN1_EXP(PKCS12_BAGS, value.x509crl, ASN1_OCTET_STRING, 0)), + ADB_ENTRY(NID_sdsiCertificate, ASN1_EXP(PKCS12_BAGS, value.sdsicert, ASN1_IA5STRING, 0)), +} ASN1_ADB_END(PKCS12_BAGS, 0, type, 0, &bag_default_tt, NULL); + +ASN1_SEQUENCE(PKCS12_BAGS) = { + ASN1_SIMPLE(PKCS12_BAGS, type, ASN1_OBJECT), + ASN1_ADB_OBJECT(PKCS12_BAGS), +} ASN1_SEQUENCE_END(PKCS12_BAGS) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS12_BAGS) + +ASN1_ADB_TEMPLATE(safebag_default) = ASN1_EXP(PKCS12_SAFEBAG, value.other, ASN1_ANY, 0); + +ASN1_ADB(PKCS12_SAFEBAG) = { + ADB_ENTRY(NID_keyBag, ASN1_EXP(PKCS12_SAFEBAG, value.keybag, PKCS8_PRIV_KEY_INFO, 0)), + ADB_ENTRY(NID_pkcs8ShroudedKeyBag, ASN1_EXP(PKCS12_SAFEBAG, value.shkeybag, X509_SIG, 0)), + ADB_ENTRY(NID_safeContentsBag, ASN1_EXP_SET_OF(PKCS12_SAFEBAG, value.safes, PKCS12_SAFEBAG, 0)), + ADB_ENTRY(NID_certBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)), + ADB_ENTRY(NID_crlBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)), + ADB_ENTRY(NID_secretBag, ASN1_EXP(PKCS12_SAFEBAG, value.bag, PKCS12_BAGS, 0)) +} ASN1_ADB_END(PKCS12_SAFEBAG, 0, type, 0, &safebag_default_tt, NULL); + +ASN1_SEQUENCE(PKCS12_SAFEBAG) = { + ASN1_SIMPLE(PKCS12_SAFEBAG, type, ASN1_OBJECT), + ASN1_ADB_OBJECT(PKCS12_SAFEBAG), + ASN1_SET_OF_OPT(PKCS12_SAFEBAG, attrib, X509_ATTRIBUTE) +} ASN1_SEQUENCE_END(PKCS12_SAFEBAG) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS12_SAFEBAG) + +/* SEQUENCE OF SafeBag */ +ASN1_ITEM_TEMPLATE(PKCS12_SAFEBAGS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_SAFEBAGS, PKCS12_SAFEBAG) +ASN1_ITEM_TEMPLATE_END(PKCS12_SAFEBAGS) + +/* Authsafes: SEQUENCE OF PKCS7 */ +ASN1_ITEM_TEMPLATE(PKCS12_AUTHSAFES) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, PKCS12_AUTHSAFES, PKCS7) +ASN1_ITEM_TEMPLATE_END(PKCS12_AUTHSAFES) diff --git a/libs/openssl/crypto/pkcs12/p12_attr.c b/libs/openssl/crypto/pkcs12/p12_attr.c new file mode 100644 index 00000000..fff3ba1e --- /dev/null +++ b/libs/openssl/crypto/pkcs12/p12_attr.c @@ -0,0 +1,147 @@ +/* p12_attr.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +/* Add a local keyid to a safebag */ + +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, + int namelen) +{ + if (X509at_add1_attr_by_NID(&bag->attrib, NID_localKeyID, + V_ASN1_OCTET_STRING, name, namelen)) + return 1; + else + return 0; +} + +/* Add key usage to PKCS#8 structure */ + +int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage) +{ + unsigned char us_val; + us_val = (unsigned char)usage; + if (X509at_add1_attr_by_NID(&p8->attributes, NID_key_usage, + V_ASN1_BIT_STRING, &us_val, 1)) + return 1; + else + return 0; +} + +/* Add a friendlyname to a safebag */ + +int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen) +{ + if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, + MBSTRING_ASC, (unsigned char *)name, namelen)) + return 1; + else + return 0; +} + +int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, + const unsigned char *name, int namelen) +{ + if (X509at_add1_attr_by_NID(&bag->attrib, NID_friendlyName, + MBSTRING_BMP, name, namelen)) + return 1; + else + return 0; +} + +int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, int namelen) +{ + if (X509at_add1_attr_by_NID(&bag->attrib, NID_ms_csp_name, + MBSTRING_ASC, (unsigned char *)name, namelen)) + return 1; + else + return 0; +} + +ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid) +{ + X509_ATTRIBUTE *attrib; + int i; + if (!attrs) + return NULL; + for (i = 0; i < sk_X509_ATTRIBUTE_num(attrs); i++) { + attrib = sk_X509_ATTRIBUTE_value(attrs, i); + if (OBJ_obj2nid(attrib->object) == attr_nid) { + if (sk_ASN1_TYPE_num(attrib->value.set)) + return sk_ASN1_TYPE_value(attrib->value.set, 0); + else + return NULL; + } + } + return NULL; +} + +char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag) +{ + ASN1_TYPE *atype; + if (!(atype = PKCS12_get_attr(bag, NID_friendlyName))) + return NULL; + if (atype->type != V_ASN1_BMPSTRING) + return NULL; + return OPENSSL_uni2asc(atype->value.bmpstring->data, + atype->value.bmpstring->length); +} diff --git a/libs/openssl/crypto/pkcs12/p12_crpt.c b/libs/openssl/crypto/pkcs12/p12_crpt.c new file mode 100644 index 00000000..9c2dcab0 --- /dev/null +++ b/libs/openssl/crypto/pkcs12/p12_crpt.c @@ -0,0 +1,119 @@ +/* p12_crpt.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +/* PKCS#12 PBE algorithms now in static table */ + +void PKCS12_PBE_add(void) +{ +} + +int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md, int en_de) +{ + PBEPARAM *pbe; + int saltlen, iter, ret; + unsigned char *salt; + const unsigned char *pbuf; + unsigned char key[EVP_MAX_KEY_LENGTH], iv[EVP_MAX_IV_LENGTH]; + + if (cipher == NULL) + return 0; + + /* Extract useful info from parameter */ + if (param == NULL || param->type != V_ASN1_SEQUENCE || + param->value.sequence == NULL) { + PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR); + return 0; + } + + pbuf = param->value.sequence->data; + if (!(pbe = d2i_PBEPARAM(NULL, &pbuf, param->value.sequence->length))) { + PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_DECODE_ERROR); + return 0; + } + + if (!pbe->iter) + iter = 1; + else + iter = ASN1_INTEGER_get(pbe->iter); + salt = pbe->salt->data; + saltlen = pbe->salt->length; + if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_KEY_ID, + iter, EVP_CIPHER_key_length(cipher), key, md)) { + PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_KEY_GEN_ERROR); + PBEPARAM_free(pbe); + return 0; + } + if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_IV_ID, + iter, EVP_CIPHER_iv_length(cipher), iv, md)) { + PKCS12err(PKCS12_F_PKCS12_PBE_KEYIVGEN, PKCS12_R_IV_GEN_ERROR); + PBEPARAM_free(pbe); + return 0; + } + PBEPARAM_free(pbe); + ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, en_de); + OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); + OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); + return ret; +} diff --git a/libs/openssl/crypto/pkcs12/p12_crt.c b/libs/openssl/crypto/pkcs12/p12_crt.c new file mode 100644 index 00000000..7d2aeefa --- /dev/null +++ b/libs/openssl/crypto/pkcs12/p12_crt.c @@ -0,0 +1,358 @@ +/* p12_crt.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, + PKCS12_SAFEBAG *bag); + +static int copy_bag_attr(PKCS12_SAFEBAG *bag, EVP_PKEY *pkey, int nid) +{ + int idx; + X509_ATTRIBUTE *attr; + idx = EVP_PKEY_get_attr_by_NID(pkey, nid, -1); + if (idx < 0) + return 1; + attr = EVP_PKEY_get_attr(pkey, idx); + if (!X509at_add1_attr(&bag->attrib, attr)) + return 0; + return 1; +} + +PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, + STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, + int mac_iter, int keytype) +{ + PKCS12 *p12 = NULL; + STACK_OF(PKCS7) *safes = NULL; + STACK_OF(PKCS12_SAFEBAG) *bags = NULL; + PKCS12_SAFEBAG *bag = NULL; + int i; + unsigned char keyid[EVP_MAX_MD_SIZE]; + unsigned int keyidlen = 0; + + /* Set defaults */ + if (!nid_cert) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + else +#endif +#ifdef OPENSSL_NO_RC2 + nid_cert = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; +#else + nid_cert = NID_pbe_WithSHA1And40BitRC2_CBC; +#endif + } + if (!nid_key) + nid_key = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; + if (!iter) + iter = PKCS12_DEFAULT_ITER; + if (!mac_iter) + mac_iter = 1; + + if (!pkey && !cert && !ca) { + PKCS12err(PKCS12_F_PKCS12_CREATE, PKCS12_R_INVALID_NULL_ARGUMENT); + return NULL; + } + + if (pkey && cert) { + if (!X509_check_private_key(cert, pkey)) + return NULL; + X509_digest(cert, EVP_sha1(), keyid, &keyidlen); + } + + if (cert) { + bag = PKCS12_add_cert(&bags, cert); + if (name && !PKCS12_add_friendlyname(bag, name, -1)) + goto err; + if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) + goto err; + } + + /* Add all other certificates */ + for (i = 0; i < sk_X509_num(ca); i++) { + if (!PKCS12_add_cert(&bags, sk_X509_value(ca, i))) + goto err; + } + + if (bags && !PKCS12_add_safe(&safes, bags, nid_cert, iter, pass)) + goto err; + + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + bags = NULL; + + if (pkey) { + bag = PKCS12_add_key(&bags, pkey, keytype, iter, nid_key, pass); + + if (!bag) + goto err; + + if (!copy_bag_attr(bag, pkey, NID_ms_csp_name)) + goto err; + if (!copy_bag_attr(bag, pkey, NID_LocalKeySet)) + goto err; + + if (name && !PKCS12_add_friendlyname(bag, name, -1)) + goto err; + if (keyidlen && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) + goto err; + } + + if (bags && !PKCS12_add_safe(&safes, bags, -1, 0, NULL)) + goto err; + + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + bags = NULL; + + p12 = PKCS12_add_safes(safes, 0); + + if (!p12) + goto err; + + sk_PKCS7_pop_free(safes, PKCS7_free); + + safes = NULL; + + if ((mac_iter != -1) && + !PKCS12_set_mac(p12, pass, -1, NULL, 0, mac_iter, NULL)) + goto err; + + return p12; + + err: + + if (p12) + PKCS12_free(p12); + if (safes) + sk_PKCS7_pop_free(safes, PKCS7_free); + if (bags) + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + return NULL; + +} + +PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert) +{ + PKCS12_SAFEBAG *bag = NULL; + char *name; + int namelen = -1; + unsigned char *keyid; + int keyidlen = -1; + + /* Add user certificate */ + if (!(bag = PKCS12_x5092certbag(cert))) + goto err; + + /* + * Use friendlyName and localKeyID in certificate. (if present) + */ + + name = (char *)X509_alias_get0(cert, &namelen); + + if (name && !PKCS12_add_friendlyname(bag, name, namelen)) + goto err; + + keyid = X509_keyid_get0(cert, &keyidlen); + + if (keyid && !PKCS12_add_localkeyid(bag, keyid, keyidlen)) + goto err; + + if (!pkcs12_add_bag(pbags, bag)) + goto err; + + return bag; + + err: + + if (bag) + PKCS12_SAFEBAG_free(bag); + + return NULL; + +} + +PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, + EVP_PKEY *key, int key_usage, int iter, + int nid_key, char *pass) +{ + + PKCS12_SAFEBAG *bag = NULL; + PKCS8_PRIV_KEY_INFO *p8 = NULL; + + /* Make a PKCS#8 structure */ + if (!(p8 = EVP_PKEY2PKCS8(key))) + goto err; + if (key_usage && !PKCS8_add_keyusage(p8, key_usage)) + goto err; + if (nid_key != -1) { + bag = PKCS12_MAKE_SHKEYBAG(nid_key, pass, -1, NULL, 0, iter, p8); + PKCS8_PRIV_KEY_INFO_free(p8); + } else + bag = PKCS12_MAKE_KEYBAG(p8); + + if (!bag) + goto err; + + if (!pkcs12_add_bag(pbags, bag)) + goto err; + + return bag; + + err: + + if (bag) + PKCS12_SAFEBAG_free(bag); + + return NULL; + +} + +int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, + int nid_safe, int iter, char *pass) +{ + PKCS7 *p7 = NULL; + int free_safes = 0; + + if (!*psafes) { + *psafes = sk_PKCS7_new_null(); + if (!*psafes) + return 0; + free_safes = 1; + } else + free_safes = 0; + + if (nid_safe == 0) +#ifdef OPENSSL_NO_RC2 + nid_safe = NID_pbe_WithSHA1And3_Key_TripleDES_CBC; +#else + nid_safe = NID_pbe_WithSHA1And40BitRC2_CBC; +#endif + + if (nid_safe == -1) + p7 = PKCS12_pack_p7data(bags); + else + p7 = PKCS12_pack_p7encdata(nid_safe, pass, -1, NULL, 0, iter, bags); + if (!p7) + goto err; + + if (!sk_PKCS7_push(*psafes, p7)) + goto err; + + return 1; + + err: + if (free_safes) { + sk_PKCS7_free(*psafes); + *psafes = NULL; + } + + if (p7) + PKCS7_free(p7); + + return 0; + +} + +static int pkcs12_add_bag(STACK_OF(PKCS12_SAFEBAG) **pbags, + PKCS12_SAFEBAG *bag) +{ + int free_bags; + if (!pbags) + return 1; + if (!*pbags) { + *pbags = sk_PKCS12_SAFEBAG_new_null(); + if (!*pbags) + return 0; + free_bags = 1; + } else + free_bags = 0; + + if (!sk_PKCS12_SAFEBAG_push(*pbags, bag)) { + if (free_bags) { + sk_PKCS12_SAFEBAG_free(*pbags); + *pbags = NULL; + } + return 0; + } + + return 1; + +} + +PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int nid_p7) +{ + PKCS12 *p12; + if (nid_p7 <= 0) + nid_p7 = NID_pkcs7_data; + p12 = PKCS12_init(nid_p7); + + if (!p12) + return NULL; + + if (!PKCS12_pack_authsafes(p12, safes)) { + PKCS12_free(p12); + return NULL; + } + + return p12; + +} diff --git a/libs/openssl/crypto/pkcs12/p12_decr.c b/libs/openssl/crypto/pkcs12/p12_decr.c new file mode 100644 index 00000000..d46eae3c --- /dev/null +++ b/libs/openssl/crypto/pkcs12/p12_decr.c @@ -0,0 +1,198 @@ +/* p12_decr.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +/* Define this to dump decrypted output to files called DERnnn */ +/* + * #define DEBUG_DECRYPT + */ + +/* + * Encrypt/Decrypt a buffer based on password and algor, result in a + * OPENSSL_malloc'ed buffer + */ + +unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass, + int passlen, unsigned char *in, int inlen, + unsigned char **data, int *datalen, int en_de) +{ + unsigned char *out; + int outlen, i; + EVP_CIPHER_CTX ctx; + + EVP_CIPHER_CTX_init(&ctx); + /* Decrypt data */ + if (!EVP_PBE_CipherInit(algor->algorithm, pass, passlen, + algor->parameter, &ctx, en_de)) { + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, + PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR); + return NULL; + } + + if (!(out = OPENSSL_malloc(inlen + EVP_CIPHER_CTX_block_size(&ctx)))) { + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_CipherUpdate(&ctx, out, &i, in, inlen)) { + OPENSSL_free(out); + out = NULL; + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, ERR_R_EVP_LIB); + goto err; + } + + outlen = i; + if (!EVP_CipherFinal_ex(&ctx, out + i, &i)) { + OPENSSL_free(out); + out = NULL; + PKCS12err(PKCS12_F_PKCS12_PBE_CRYPT, + PKCS12_R_PKCS12_CIPHERFINAL_ERROR); + goto err; + } + outlen += i; + if (datalen) + *datalen = outlen; + if (data) + *data = out; + err: + EVP_CIPHER_CTX_cleanup(&ctx); + return out; + +} + +/* + * Decrypt an OCTET STRING and decode ASN1 structure if zbuf set zero buffer + * after use. + */ + +void *PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, + ASN1_OCTET_STRING *oct, int zbuf) +{ + unsigned char *out; + const unsigned char *p; + void *ret; + int outlen; + + if (!PKCS12_pbe_crypt(algor, pass, passlen, oct->data, oct->length, + &out, &outlen, 0)) { + PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, + PKCS12_R_PKCS12_PBE_CRYPT_ERROR); + return NULL; + } + p = out; +#ifdef DEBUG_DECRYPT + { + FILE *op; + + char fname[30]; + static int fnm = 1; + sprintf(fname, "DER%d", fnm++); + op = fopen(fname, "wb"); + fwrite(p, 1, outlen, op); + fclose(op); + } +#endif + ret = ASN1_item_d2i(NULL, &p, outlen, it); + if (zbuf) + OPENSSL_cleanse(out, outlen); + if (!ret) + PKCS12err(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I, PKCS12_R_DECODE_ERROR); + OPENSSL_free(out); + return ret; +} + +/* + * Encode ASN1 structure and encrypt, return OCTET STRING if zbuf set zero + * encoding. + */ + +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, + const ASN1_ITEM *it, + const char *pass, int passlen, + void *obj, int zbuf) +{ + ASN1_OCTET_STRING *oct; + unsigned char *in = NULL; + int inlen; + if (!(oct = M_ASN1_OCTET_STRING_new())) { + PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, ERR_R_MALLOC_FAILURE); + return NULL; + } + inlen = ASN1_item_i2d(obj, &in, it); + if (!in) { + PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCODE_ERROR); + return NULL; + } + if (!PKCS12_pbe_crypt(algor, pass, passlen, in, inlen, &oct->data, + &oct->length, 1)) { + PKCS12err(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT, PKCS12_R_ENCRYPT_ERROR); + OPENSSL_free(in); + return NULL; + } + if (zbuf) + OPENSSL_cleanse(in, inlen); + OPENSSL_free(in); + return oct; +} + +IMPLEMENT_PKCS12_STACK_OF(PKCS7) diff --git a/libs/openssl/crypto/pkcs12/p12_init.c b/libs/openssl/crypto/pkcs12/p12_init.c new file mode 100644 index 00000000..0322df94 --- /dev/null +++ b/libs/openssl/crypto/pkcs12/p12_init.c @@ -0,0 +1,92 @@ +/* p12_init.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +/* Initialise a PKCS12 structure to take data */ + +PKCS12 *PKCS12_init(int mode) +{ + PKCS12 *pkcs12; + if (!(pkcs12 = PKCS12_new())) { + PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE); + return NULL; + } + ASN1_INTEGER_set(pkcs12->version, 3); + pkcs12->authsafes->type = OBJ_nid2obj(mode); + switch (mode) { + case NID_pkcs7_data: + if (!(pkcs12->authsafes->d.data = M_ASN1_OCTET_STRING_new())) { + PKCS12err(PKCS12_F_PKCS12_INIT, ERR_R_MALLOC_FAILURE); + goto err; + } + break; + default: + PKCS12err(PKCS12_F_PKCS12_INIT, PKCS12_R_UNSUPPORTED_PKCS12_MODE); + goto err; + } + + return pkcs12; + err: + if (pkcs12 != NULL) + PKCS12_free(pkcs12); + return NULL; +} diff --git a/libs/openssl/crypto/pkcs12/p12_key.c b/libs/openssl/crypto/pkcs12/p12_key.c new file mode 100644 index 00000000..99b8260c --- /dev/null +++ b/libs/openssl/crypto/pkcs12/p12_key.c @@ -0,0 +1,238 @@ +/* p12_key.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include + +/* Uncomment out this line to get debugging info about key generation */ +/* + * #define DEBUG_KEYGEN + */ +#ifdef DEBUG_KEYGEN +# include +extern BIO *bio_err; +void h__dump(unsigned char *p, int len); +#endif + +/* PKCS12 compatible key/IV generation */ +#ifndef min +# define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + +int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type) +{ + int ret; + unsigned char *unipass; + int uniplen; + + if (!pass) { + unipass = NULL; + uniplen = 0; + } else if (!OPENSSL_asc2uni(pass, passlen, &unipass, &uniplen)) { + PKCS12err(PKCS12_F_PKCS12_KEY_GEN_ASC, ERR_R_MALLOC_FAILURE); + return 0; + } + ret = PKCS12_key_gen_uni(unipass, uniplen, salt, saltlen, + id, iter, n, out, md_type); + if (ret <= 0) + return 0; + if (unipass) { + OPENSSL_cleanse(unipass, uniplen); /* Clear password from memory */ + OPENSSL_free(unipass); + } + return ret; +} + +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type) +{ + unsigned char *B, *D, *I, *p, *Ai; + int Slen, Plen, Ilen, Ijlen; + int i, j, u, v; + int ret = 0; + BIGNUM *Ij, *Bpl1; /* These hold Ij and B + 1 */ + EVP_MD_CTX ctx; +#ifdef DEBUG_KEYGEN + unsigned char *tmpout = out; + int tmpn = n; +#endif + +#if 0 + if (!pass) { + PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } +#endif + + EVP_MD_CTX_init(&ctx); +#ifdef DEBUG_KEYGEN + fprintf(stderr, "KEYGEN DEBUG\n"); + fprintf(stderr, "ID %d, ITER %d\n", id, iter); + fprintf(stderr, "Password (length %d):\n", passlen); + h__dump(pass, passlen); + fprintf(stderr, "Salt (length %d):\n", saltlen); + h__dump(salt, saltlen); +#endif + v = EVP_MD_block_size(md_type); + u = EVP_MD_size(md_type); + if (u < 0) + return 0; + D = OPENSSL_malloc(v); + Ai = OPENSSL_malloc(u); + B = OPENSSL_malloc(v + 1); + Slen = v * ((saltlen + v - 1) / v); + if (passlen) + Plen = v * ((passlen + v - 1) / v); + else + Plen = 0; + Ilen = Slen + Plen; + I = OPENSSL_malloc(Ilen); + Ij = BN_new(); + Bpl1 = BN_new(); + if (!D || !Ai || !B || !I || !Ij || !Bpl1) + goto err; + for (i = 0; i < v; i++) + D[i] = id; + p = I; + for (i = 0; i < Slen; i++) + *p++ = salt[i % saltlen]; + for (i = 0; i < Plen; i++) + *p++ = pass[i % passlen]; + for (;;) { + if (!EVP_DigestInit_ex(&ctx, md_type, NULL) + || !EVP_DigestUpdate(&ctx, D, v) + || !EVP_DigestUpdate(&ctx, I, Ilen) + || !EVP_DigestFinal_ex(&ctx, Ai, NULL)) + goto err; + for (j = 1; j < iter; j++) { + if (!EVP_DigestInit_ex(&ctx, md_type, NULL) + || !EVP_DigestUpdate(&ctx, Ai, u) + || !EVP_DigestFinal_ex(&ctx, Ai, NULL)) + goto err; + } + memcpy(out, Ai, min(n, u)); + if (u >= n) { +#ifdef DEBUG_KEYGEN + fprintf(stderr, "Output KEY (length %d)\n", tmpn); + h__dump(tmpout, tmpn); +#endif + ret = 1; + goto end; + } + n -= u; + out += u; + for (j = 0; j < v; j++) + B[j] = Ai[j % u]; + /* Work out B + 1 first then can use B as tmp space */ + if (!BN_bin2bn(B, v, Bpl1)) + goto err; + if (!BN_add_word(Bpl1, 1)) + goto err; + for (j = 0; j < Ilen; j += v) { + if (!BN_bin2bn(I + j, v, Ij)) + goto err; + if (!BN_add(Ij, Ij, Bpl1)) + goto err; + if (!BN_bn2bin(Ij, B)) + goto err; + Ijlen = BN_num_bytes(Ij); + /* If more than 2^(v*8) - 1 cut off MSB */ + if (Ijlen > v) { + if (!BN_bn2bin(Ij, B)) + goto err; + memcpy(I + j, B + 1, v); +#ifndef PKCS12_BROKEN_KEYGEN + /* If less than v bytes pad with zeroes */ + } else if (Ijlen < v) { + memset(I + j, 0, v - Ijlen); + if (!BN_bn2bin(Ij, I + j + v - Ijlen)) + goto err; +#endif + } else if (!BN_bn2bin(Ij, I + j)) + goto err; + } + } + + err: + PKCS12err(PKCS12_F_PKCS12_KEY_GEN_UNI, ERR_R_MALLOC_FAILURE); + + end: + OPENSSL_free(Ai); + OPENSSL_free(B); + OPENSSL_free(D); + OPENSSL_free(I); + BN_free(Ij); + BN_free(Bpl1); + EVP_MD_CTX_cleanup(&ctx); + return ret; +} + +#ifdef DEBUG_KEYGEN +void h__dump(unsigned char *p, int len) +{ + for (; len--; p++) + fprintf(stderr, "%02X", *p); + fprintf(stderr, "\n"); +} +#endif diff --git a/libs/openssl/crypto/pkcs12/p12_kiss.c b/libs/openssl/crypto/pkcs12/p12_kiss.c new file mode 100644 index 00000000..9aa3c90c --- /dev/null +++ b/libs/openssl/crypto/pkcs12/p12_kiss.c @@ -0,0 +1,299 @@ +/* p12_kiss.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +/* Simplified PKCS#12 routines */ + +static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, + EVP_PKEY **pkey, STACK_OF(X509) *ocerts); + +static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, + int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts); + +static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, + EVP_PKEY **pkey, STACK_OF(X509) *ocerts); + +/* + * Parse and decrypt a PKCS#12 structure returning user key, user cert and + * other (CA) certs. Note either ca should be NULL, *ca should be NULL, or it + * should point to a valid STACK structure. pkey and cert can be passed + * unitialised. + */ + +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + STACK_OF(X509) **ca) +{ + STACK_OF(X509) *ocerts = NULL; + X509 *x = NULL; + /* Check for NULL PKCS12 structure */ + + if (!p12) { + PKCS12err(PKCS12_F_PKCS12_PARSE, + PKCS12_R_INVALID_NULL_PKCS12_POINTER); + return 0; + } + + if (pkey) + *pkey = NULL; + if (cert) + *cert = NULL; + + /* Check the mac */ + + /* + * If password is zero length or NULL then try verifying both cases to + * determine which password is correct. The reason for this is that under + * PKCS#12 password based encryption no password and a zero length + * password are two different things... + */ + + if (!pass || !*pass) { + if (PKCS12_verify_mac(p12, NULL, 0)) + pass = NULL; + else if (PKCS12_verify_mac(p12, "", 0)) + pass = ""; + else { + PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); + goto err; + } + } else if (!PKCS12_verify_mac(p12, pass, -1)) { + PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_MAC_VERIFY_FAILURE); + goto err; + } + + /* Allocate stack for other certificates */ + ocerts = sk_X509_new_null(); + + if (!ocerts) { + PKCS12err(PKCS12_F_PKCS12_PARSE, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!parse_pk12(p12, pass, -1, pkey, ocerts)) { + PKCS12err(PKCS12_F_PKCS12_PARSE, PKCS12_R_PARSE_ERROR); + goto err; + } + + while ((x = sk_X509_pop(ocerts))) { + if (pkey && *pkey && cert && !*cert) { + ERR_set_mark(); + if (X509_check_private_key(x, *pkey)) { + *cert = x; + x = NULL; + } + ERR_pop_to_mark(); + } + + if (ca && x) { + if (!*ca) + *ca = sk_X509_new_null(); + if (!*ca) + goto err; + if (!sk_X509_push(*ca, x)) + goto err; + x = NULL; + } + if (x) + X509_free(x); + } + + if (ocerts) + sk_X509_pop_free(ocerts, X509_free); + + return 1; + + err: + + if (pkey && *pkey) + EVP_PKEY_free(*pkey); + if (cert && *cert) + X509_free(*cert); + if (x) + X509_free(x); + if (ocerts) + sk_X509_pop_free(ocerts, X509_free); + return 0; + +} + +/* Parse the outer PKCS#12 structure */ + +static int parse_pk12(PKCS12 *p12, const char *pass, int passlen, + EVP_PKEY **pkey, STACK_OF(X509) *ocerts) +{ + STACK_OF(PKCS7) *asafes; + STACK_OF(PKCS12_SAFEBAG) *bags; + int i, bagnid; + PKCS7 *p7; + + if (!(asafes = PKCS12_unpack_authsafes(p12))) + return 0; + for (i = 0; i < sk_PKCS7_num(asafes); i++) { + p7 = sk_PKCS7_value(asafes, i); + bagnid = OBJ_obj2nid(p7->type); + if (bagnid == NID_pkcs7_data) { + bags = PKCS12_unpack_p7data(p7); + } else if (bagnid == NID_pkcs7_encrypted) { + bags = PKCS12_unpack_p7encdata(p7, pass, passlen); + } else + continue; + if (!bags) { + sk_PKCS7_pop_free(asafes, PKCS7_free); + return 0; + } + if (!parse_bags(bags, pass, passlen, pkey, ocerts)) { + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + sk_PKCS7_pop_free(asafes, PKCS7_free); + return 0; + } + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + } + sk_PKCS7_pop_free(asafes, PKCS7_free); + return 1; +} + +static int parse_bags(STACK_OF(PKCS12_SAFEBAG) *bags, const char *pass, + int passlen, EVP_PKEY **pkey, STACK_OF(X509) *ocerts) +{ + int i; + for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { + if (!parse_bag(sk_PKCS12_SAFEBAG_value(bags, i), + pass, passlen, pkey, ocerts)) + return 0; + } + return 1; +} + +static int parse_bag(PKCS12_SAFEBAG *bag, const char *pass, int passlen, + EVP_PKEY **pkey, STACK_OF(X509) *ocerts) +{ + PKCS8_PRIV_KEY_INFO *p8; + X509 *x509; + ASN1_TYPE *attrib; + ASN1_BMPSTRING *fname = NULL; + ASN1_OCTET_STRING *lkid = NULL; + + if ((attrib = PKCS12_get_attr(bag, NID_friendlyName))) + fname = attrib->value.bmpstring; + + if ((attrib = PKCS12_get_attr(bag, NID_localKeyID))) + lkid = attrib->value.octet_string; + + switch (M_PKCS12_bag_type(bag)) { + case NID_keyBag: + if (!pkey || *pkey) + return 1; + if (!(*pkey = EVP_PKCS82PKEY(bag->value.keybag))) + return 0; + break; + + case NID_pkcs8ShroudedKeyBag: + if (!pkey || *pkey) + return 1; + if (!(p8 = PKCS12_decrypt_skey(bag, pass, passlen))) + return 0; + *pkey = EVP_PKCS82PKEY(p8); + PKCS8_PRIV_KEY_INFO_free(p8); + if (!(*pkey)) + return 0; + break; + + case NID_certBag: + if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) + return 1; + if (!(x509 = PKCS12_certbag2x509(bag))) + return 0; + if (lkid && !X509_keyid_set1(x509, lkid->data, lkid->length)) { + X509_free(x509); + return 0; + } + if (fname) { + int len, r; + unsigned char *data; + len = ASN1_STRING_to_UTF8(&data, fname); + if (len >= 0) { + r = X509_alias_set1(x509, data, len); + OPENSSL_free(data); + if (!r) { + X509_free(x509); + return 0; + } + } + } + + if (!sk_X509_push(ocerts, x509)) { + X509_free(x509); + return 0; + } + + break; + + case NID_safeContentsBag: + return parse_bags(bag->value.safes, pass, passlen, pkey, ocerts); + break; + + default: + return 1; + break; + } + return 1; +} diff --git a/libs/openssl/crypto/pkcs12/p12_mutl.c b/libs/openssl/crypto/pkcs12/p12_mutl.c new file mode 100644 index 00000000..a9277827 --- /dev/null +++ b/libs/openssl/crypto/pkcs12/p12_mutl.c @@ -0,0 +1,195 @@ +/* p12_mutl.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef OPENSSL_NO_HMAC +# include +# include "cryptlib.h" +# include +# include +# include +# include + +/* Generate a MAC */ +int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *mac, unsigned int *maclen) +{ + const EVP_MD *md_type; + HMAC_CTX hmac; + unsigned char key[EVP_MAX_MD_SIZE], *salt; + int saltlen, iter; + int md_size; + + if (!PKCS7_type_is_data(p12->authsafes)) { + PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_CONTENT_TYPE_NOT_DATA); + return 0; + } + + salt = p12->mac->salt->data; + saltlen = p12->mac->salt->length; + if (!p12->mac->iter) + iter = 1; + else + iter = ASN1_INTEGER_get(p12->mac->iter); + if (!(md_type = EVP_get_digestbyobj(p12->mac->dinfo->algor->algorithm))) { + PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_UNKNOWN_DIGEST_ALGORITHM); + return 0; + } + md_size = EVP_MD_size(md_type); + if (md_size < 0) + return 0; + if (!PKCS12_key_gen(pass, passlen, salt, saltlen, PKCS12_MAC_ID, iter, + md_size, key, md_type)) { + PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_KEY_GEN_ERROR); + return 0; + } + HMAC_CTX_init(&hmac); + if (!HMAC_Init_ex(&hmac, key, md_size, md_type, NULL) + || !HMAC_Update(&hmac, p12->authsafes->d.data->data, + p12->authsafes->d.data->length) + || !HMAC_Final(&hmac, mac, maclen)) { + HMAC_CTX_cleanup(&hmac); + return 0; + } + HMAC_CTX_cleanup(&hmac); + return 1; +} + +/* Verify the mac */ +int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen) +{ + unsigned char mac[EVP_MAX_MD_SIZE]; + unsigned int maclen; + if (p12->mac == NULL) { + PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_ABSENT); + return 0; + } + if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) { + PKCS12err(PKCS12_F_PKCS12_VERIFY_MAC, PKCS12_R_MAC_GENERATION_ERROR); + return 0; + } + if ((maclen != (unsigned int)p12->mac->dinfo->digest->length) + || CRYPTO_memcmp(mac, p12->mac->dinfo->digest->data, maclen)) + return 0; + return 1; +} + +/* Set a mac */ + +int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + const EVP_MD *md_type) +{ + unsigned char mac[EVP_MAX_MD_SIZE]; + unsigned int maclen; + + if (!md_type) + md_type = EVP_sha1(); + if (PKCS12_setup_mac(p12, iter, salt, saltlen, md_type) == PKCS12_ERROR) { + PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_SETUP_ERROR); + return 0; + } + if (!PKCS12_gen_mac(p12, pass, passlen, mac, &maclen)) { + PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_GENERATION_ERROR); + return 0; + } + if (!(M_ASN1_OCTET_STRING_set(p12->mac->dinfo->digest, mac, maclen))) { + PKCS12err(PKCS12_F_PKCS12_SET_MAC, PKCS12_R_MAC_STRING_SET_ERROR); + return 0; + } + return 1; +} + +/* Set up a mac structure */ +int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, int saltlen, + const EVP_MD *md_type) +{ + if (!(p12->mac = PKCS12_MAC_DATA_new())) + return PKCS12_ERROR; + if (iter > 1) { + if (!(p12->mac->iter = M_ASN1_INTEGER_new())) { + PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!ASN1_INTEGER_set(p12->mac->iter, iter)) { + PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + return 0; + } + } + if (!saltlen) + saltlen = PKCS12_SALT_LEN; + if ((p12->mac->salt->data = OPENSSL_malloc(saltlen)) == NULL) { + PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + return 0; + } + p12->mac->salt->length = saltlen; + if (!salt) { + if (RAND_pseudo_bytes(p12->mac->salt->data, saltlen) < 0) + return 0; + } else + memcpy(p12->mac->salt->data, salt, saltlen); + p12->mac->dinfo->algor->algorithm = OBJ_nid2obj(EVP_MD_type(md_type)); + if (!(p12->mac->dinfo->algor->parameter = ASN1_TYPE_new())) { + PKCS12err(PKCS12_F_PKCS12_SETUP_MAC, ERR_R_MALLOC_FAILURE); + return 0; + } + p12->mac->dinfo->algor->parameter->type = V_ASN1_NULL; + + return 1; +} +#endif diff --git a/libs/openssl/crypto/pkcs12/p12_npas.c b/libs/openssl/crypto/pkcs12/p12_npas.c new file mode 100644 index 00000000..a89b61ab --- /dev/null +++ b/libs/openssl/crypto/pkcs12/p12_npas.c @@ -0,0 +1,235 @@ +/* p12_npas.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include + +/* PKCS#12 password change routine */ + +static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass); +static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass, + char *newpass); +static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass); +static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen); + +/* + * Change the password on a PKCS#12 structure. + */ + +int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass) +{ + /* Check for NULL PKCS12 structure */ + + if (!p12) { + PKCS12err(PKCS12_F_PKCS12_NEWPASS, + PKCS12_R_INVALID_NULL_PKCS12_POINTER); + return 0; + } + + /* Check the mac */ + + if (!PKCS12_verify_mac(p12, oldpass, -1)) { + PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_MAC_VERIFY_FAILURE); + return 0; + } + + if (!newpass_p12(p12, oldpass, newpass)) { + PKCS12err(PKCS12_F_PKCS12_NEWPASS, PKCS12_R_PARSE_ERROR); + return 0; + } + + return 1; +} + +/* Parse the outer PKCS#12 structure */ + +static int newpass_p12(PKCS12 *p12, char *oldpass, char *newpass) +{ + STACK_OF(PKCS7) *asafes, *newsafes; + STACK_OF(PKCS12_SAFEBAG) *bags; + int i, bagnid, pbe_nid = 0, pbe_iter = 0, pbe_saltlen = 0; + PKCS7 *p7, *p7new; + ASN1_OCTET_STRING *p12_data_tmp = NULL, *macnew = NULL; + unsigned char mac[EVP_MAX_MD_SIZE]; + unsigned int maclen; + + if (!(asafes = PKCS12_unpack_authsafes(p12))) + return 0; + if (!(newsafes = sk_PKCS7_new_null())) + return 0; + for (i = 0; i < sk_PKCS7_num(asafes); i++) { + p7 = sk_PKCS7_value(asafes, i); + bagnid = OBJ_obj2nid(p7->type); + if (bagnid == NID_pkcs7_data) { + bags = PKCS12_unpack_p7data(p7); + } else if (bagnid == NID_pkcs7_encrypted) { + bags = PKCS12_unpack_p7encdata(p7, oldpass, -1); + if (!alg_get(p7->d.encrypted->enc_data->algorithm, + &pbe_nid, &pbe_iter, &pbe_saltlen)) { + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + bags = NULL; + } + } else + continue; + if (!bags) { + sk_PKCS7_pop_free(asafes, PKCS7_free); + return 0; + } + if (!newpass_bags(bags, oldpass, newpass)) { + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + sk_PKCS7_pop_free(asafes, PKCS7_free); + return 0; + } + /* Repack bag in same form with new password */ + if (bagnid == NID_pkcs7_data) + p7new = PKCS12_pack_p7data(bags); + else + p7new = PKCS12_pack_p7encdata(pbe_nid, newpass, -1, NULL, + pbe_saltlen, pbe_iter, bags); + sk_PKCS12_SAFEBAG_pop_free(bags, PKCS12_SAFEBAG_free); + if (!p7new) { + sk_PKCS7_pop_free(asafes, PKCS7_free); + return 0; + } + sk_PKCS7_push(newsafes, p7new); + } + sk_PKCS7_pop_free(asafes, PKCS7_free); + + /* Repack safe: save old safe in case of error */ + + p12_data_tmp = p12->authsafes->d.data; + if (!(p12->authsafes->d.data = ASN1_OCTET_STRING_new())) + goto saferr; + if (!PKCS12_pack_authsafes(p12, newsafes)) + goto saferr; + + if (!PKCS12_gen_mac(p12, newpass, -1, mac, &maclen)) + goto saferr; + if (!(macnew = ASN1_OCTET_STRING_new())) + goto saferr; + if (!ASN1_OCTET_STRING_set(macnew, mac, maclen)) + goto saferr; + ASN1_OCTET_STRING_free(p12->mac->dinfo->digest); + p12->mac->dinfo->digest = macnew; + ASN1_OCTET_STRING_free(p12_data_tmp); + + return 1; + + saferr: + /* Restore old safe */ + ASN1_OCTET_STRING_free(p12->authsafes->d.data); + ASN1_OCTET_STRING_free(macnew); + p12->authsafes->d.data = p12_data_tmp; + return 0; + +} + +static int newpass_bags(STACK_OF(PKCS12_SAFEBAG) *bags, char *oldpass, + char *newpass) +{ + int i; + for (i = 0; i < sk_PKCS12_SAFEBAG_num(bags); i++) { + if (!newpass_bag(sk_PKCS12_SAFEBAG_value(bags, i), oldpass, newpass)) + return 0; + } + return 1; +} + +/* Change password of safebag: only needs handle shrouded keybags */ + +static int newpass_bag(PKCS12_SAFEBAG *bag, char *oldpass, char *newpass) +{ + PKCS8_PRIV_KEY_INFO *p8; + X509_SIG *p8new; + int p8_nid, p8_saltlen, p8_iter; + + if (M_PKCS12_bag_type(bag) != NID_pkcs8ShroudedKeyBag) + return 1; + + if (!(p8 = PKCS8_decrypt(bag->value.shkeybag, oldpass, -1))) + return 0; + if (!alg_get(bag->value.shkeybag->algor, &p8_nid, &p8_iter, &p8_saltlen)) + return 0; + if (!(p8new = PKCS8_encrypt(p8_nid, NULL, newpass, -1, NULL, p8_saltlen, + p8_iter, p8))) + return 0; + X509_SIG_free(bag->value.shkeybag); + bag->value.shkeybag = p8new; + return 1; +} + +static int alg_get(X509_ALGOR *alg, int *pnid, int *piter, int *psaltlen) +{ + PBEPARAM *pbe; + const unsigned char *p; + + p = alg->parameter->value.sequence->data; + pbe = d2i_PBEPARAM(NULL, &p, alg->parameter->value.sequence->length); + if (!pbe) + return 0; + *pnid = OBJ_obj2nid(alg->algorithm); + *piter = ASN1_INTEGER_get(pbe->iter); + *psaltlen = pbe->salt->length; + PBEPARAM_free(pbe); + return 1; +} diff --git a/libs/openssl/crypto/pkcs12/p12_p8d.c b/libs/openssl/crypto/pkcs12/p12_p8d.c new file mode 100644 index 00000000..3cc7a9f4 --- /dev/null +++ b/libs/openssl/crypto/pkcs12/p12_p8d.c @@ -0,0 +1,70 @@ +/* p12_p8d.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, + int passlen) +{ + return PKCS12_item_decrypt_d2i(p8->algor, + ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), pass, + passlen, p8->digest, 1); +} diff --git a/libs/openssl/crypto/pkcs12/p12_p8e.c b/libs/openssl/crypto/pkcs12/p12_p8e.c new file mode 100644 index 00000000..d970f054 --- /dev/null +++ b/libs/openssl/crypto/pkcs12/p12_p8e.c @@ -0,0 +1,101 @@ +/* p12_p8e.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8inf) +{ + X509_SIG *p8 = NULL; + X509_ALGOR *pbe; + + if (!(p8 = X509_SIG_new())) { + PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (pbe_nid == -1) + pbe = PKCS5_pbe2_set(cipher, iter, salt, saltlen); + else + pbe = PKCS5_pbe_set(pbe_nid, iter, salt, saltlen); + if (!pbe) { + PKCS12err(PKCS12_F_PKCS8_ENCRYPT, ERR_R_ASN1_LIB); + goto err; + } + X509_ALGOR_free(p8->algor); + p8->algor = pbe; + M_ASN1_OCTET_STRING_free(p8->digest); + p8->digest = + PKCS12_item_i2d_encrypt(pbe, ASN1_ITEM_rptr(PKCS8_PRIV_KEY_INFO), + pass, passlen, p8inf, 1); + if (!p8->digest) { + PKCS12err(PKCS12_F_PKCS8_ENCRYPT, PKCS12_R_ENCRYPT_ERROR); + goto err; + } + + return p8; + + err: + X509_SIG_free(p8); + return NULL; +} diff --git a/libs/openssl/crypto/pkcs12/p12_utl.c b/libs/openssl/crypto/pkcs12/p12_utl.c new file mode 100644 index 00000000..a0b992ea --- /dev/null +++ b/libs/openssl/crypto/pkcs12/p12_utl.c @@ -0,0 +1,161 @@ +/* p12_utl.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +/* Cheap and nasty Unicode stuff */ + +unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, + unsigned char **uni, int *unilen) +{ + int ulen, i; + unsigned char *unitmp; + if (asclen == -1) + asclen = strlen(asc); + ulen = asclen * 2 + 2; + if (!(unitmp = OPENSSL_malloc(ulen))) + return NULL; + for (i = 0; i < ulen - 2; i += 2) { + unitmp[i] = 0; + unitmp[i + 1] = asc[i >> 1]; + } + /* Make result double null terminated */ + unitmp[ulen - 2] = 0; + unitmp[ulen - 1] = 0; + if (unilen) + *unilen = ulen; + if (uni) + *uni = unitmp; + return unitmp; +} + +char *OPENSSL_uni2asc(unsigned char *uni, int unilen) +{ + int asclen, i; + char *asctmp; + asclen = unilen / 2; + /* If no terminating zero allow for one */ + if (!unilen || uni[unilen - 1]) + asclen++; + uni++; + if (!(asctmp = OPENSSL_malloc(asclen))) + return NULL; + for (i = 0; i < unilen; i += 2) + asctmp[i >> 1] = uni[i]; + asctmp[asclen - 1] = 0; + return asctmp; +} + +int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS12), bp, p12); +} + +#ifndef OPENSSL_NO_FP_API +int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS12), fp, p12); +} +#endif + +PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS12), bp, p12); +} + +#ifndef OPENSSL_NO_FP_API +PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS12), fp, p12); +} +#endif + +PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509) +{ + return PKCS12_item_pack_safebag(x509, ASN1_ITEM_rptr(X509), + NID_x509Certificate, NID_certBag); +} + +PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl) +{ + return PKCS12_item_pack_safebag(crl, ASN1_ITEM_rptr(X509_CRL), + NID_x509Crl, NID_crlBag); +} + +X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag) +{ + if (M_PKCS12_bag_type(bag) != NID_certBag) + return NULL; + if (M_PKCS12_cert_bag_type(bag) != NID_x509Certificate) + return NULL; + return ASN1_item_unpack(bag->value.bag->value.octet, + ASN1_ITEM_rptr(X509)); +} + +X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag) +{ + if (M_PKCS12_bag_type(bag) != NID_crlBag) + return NULL; + if (M_PKCS12_cert_bag_type(bag) != NID_x509Crl) + return NULL; + return ASN1_item_unpack(bag->value.bag->value.octet, + ASN1_ITEM_rptr(X509_CRL)); +} diff --git a/libs/openssl/crypto/pkcs12/pk12err.c b/libs/openssl/crypto/pkcs12/pk12err.c new file mode 100644 index 00000000..e58710b2 --- /dev/null +++ b/libs/openssl/crypto/pkcs12/pk12err.c @@ -0,0 +1,149 @@ +/* crypto/pkcs12/pk12err.c */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS12,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS12,0,reason) + +static ERR_STRING_DATA PKCS12_str_functs[] = { + {ERR_FUNC(PKCS12_F_PARSE_BAG), "PARSE_BAG"}, + {ERR_FUNC(PKCS12_F_PARSE_BAGS), "PARSE_BAGS"}, + {ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME), "PKCS12_ADD_FRIENDLYNAME"}, + {ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC), + "PKCS12_add_friendlyname_asc"}, + {ERR_FUNC(PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI), + "PKCS12_add_friendlyname_uni"}, + {ERR_FUNC(PKCS12_F_PKCS12_ADD_LOCALKEYID), "PKCS12_add_localkeyid"}, + {ERR_FUNC(PKCS12_F_PKCS12_CREATE), "PKCS12_create"}, + {ERR_FUNC(PKCS12_F_PKCS12_GEN_MAC), "PKCS12_gen_mac"}, + {ERR_FUNC(PKCS12_F_PKCS12_INIT), "PKCS12_init"}, + {ERR_FUNC(PKCS12_F_PKCS12_ITEM_DECRYPT_D2I), "PKCS12_item_decrypt_d2i"}, + {ERR_FUNC(PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT), "PKCS12_item_i2d_encrypt"}, + {ERR_FUNC(PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG), "PKCS12_item_pack_safebag"}, + {ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_ASC), "PKCS12_key_gen_asc"}, + {ERR_FUNC(PKCS12_F_PKCS12_KEY_GEN_UNI), "PKCS12_key_gen_uni"}, + {ERR_FUNC(PKCS12_F_PKCS12_MAKE_KEYBAG), "PKCS12_MAKE_KEYBAG"}, + {ERR_FUNC(PKCS12_F_PKCS12_MAKE_SHKEYBAG), "PKCS12_MAKE_SHKEYBAG"}, + {ERR_FUNC(PKCS12_F_PKCS12_NEWPASS), "PKCS12_newpass"}, + {ERR_FUNC(PKCS12_F_PKCS12_PACK_P7DATA), "PKCS12_pack_p7data"}, + {ERR_FUNC(PKCS12_F_PKCS12_PACK_P7ENCDATA), "PKCS12_pack_p7encdata"}, + {ERR_FUNC(PKCS12_F_PKCS12_PARSE), "PKCS12_parse"}, + {ERR_FUNC(PKCS12_F_PKCS12_PBE_CRYPT), "PKCS12_pbe_crypt"}, + {ERR_FUNC(PKCS12_F_PKCS12_PBE_KEYIVGEN), "PKCS12_PBE_keyivgen"}, + {ERR_FUNC(PKCS12_F_PKCS12_SETUP_MAC), "PKCS12_setup_mac"}, + {ERR_FUNC(PKCS12_F_PKCS12_SET_MAC), "PKCS12_set_mac"}, + {ERR_FUNC(PKCS12_F_PKCS12_UNPACK_AUTHSAFES), "PKCS12_unpack_authsafes"}, + {ERR_FUNC(PKCS12_F_PKCS12_UNPACK_P7DATA), "PKCS12_unpack_p7data"}, + {ERR_FUNC(PKCS12_F_PKCS12_VERIFY_MAC), "PKCS12_verify_mac"}, + {ERR_FUNC(PKCS12_F_PKCS8_ADD_KEYUSAGE), "PKCS8_add_keyusage"}, + {ERR_FUNC(PKCS12_F_PKCS8_ENCRYPT), "PKCS8_encrypt"}, + {0, NULL} +}; + +static ERR_STRING_DATA PKCS12_str_reasons[] = { + {ERR_REASON(PKCS12_R_CANT_PACK_STRUCTURE), "cant pack structure"}, + {ERR_REASON(PKCS12_R_CONTENT_TYPE_NOT_DATA), "content type not data"}, + {ERR_REASON(PKCS12_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(PKCS12_R_ENCODE_ERROR), "encode error"}, + {ERR_REASON(PKCS12_R_ENCRYPT_ERROR), "encrypt error"}, + {ERR_REASON(PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE), + "error setting encrypted data type"}, + {ERR_REASON(PKCS12_R_INVALID_NULL_ARGUMENT), "invalid null argument"}, + {ERR_REASON(PKCS12_R_INVALID_NULL_PKCS12_POINTER), + "invalid null pkcs12 pointer"}, + {ERR_REASON(PKCS12_R_IV_GEN_ERROR), "iv gen error"}, + {ERR_REASON(PKCS12_R_KEY_GEN_ERROR), "key gen error"}, + {ERR_REASON(PKCS12_R_MAC_ABSENT), "mac absent"}, + {ERR_REASON(PKCS12_R_MAC_GENERATION_ERROR), "mac generation error"}, + {ERR_REASON(PKCS12_R_MAC_SETUP_ERROR), "mac setup error"}, + {ERR_REASON(PKCS12_R_MAC_STRING_SET_ERROR), "mac string set error"}, + {ERR_REASON(PKCS12_R_MAC_VERIFY_ERROR), "mac verify error"}, + {ERR_REASON(PKCS12_R_MAC_VERIFY_FAILURE), "mac verify failure"}, + {ERR_REASON(PKCS12_R_PARSE_ERROR), "parse error"}, + {ERR_REASON(PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR), + "pkcs12 algor cipherinit error"}, + {ERR_REASON(PKCS12_R_PKCS12_CIPHERFINAL_ERROR), + "pkcs12 cipherfinal error"}, + {ERR_REASON(PKCS12_R_PKCS12_PBE_CRYPT_ERROR), "pkcs12 pbe crypt error"}, + {ERR_REASON(PKCS12_R_UNKNOWN_DIGEST_ALGORITHM), + "unknown digest algorithm"}, + {ERR_REASON(PKCS12_R_UNSUPPORTED_PKCS12_MODE), "unsupported pkcs12 mode"}, + {0, NULL} +}; + +#endif + +void ERR_load_PKCS12_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(PKCS12_str_functs[0].error) == NULL) { + ERR_load_strings(0, PKCS12_str_functs); + ERR_load_strings(0, PKCS12_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/pkcs12/pkcs12.h b/libs/openssl/crypto/pkcs12/pkcs12.h new file mode 100644 index 00000000..a39adf5e --- /dev/null +++ b/libs/openssl/crypto/pkcs12/pkcs12.h @@ -0,0 +1,342 @@ +/* pkcs12.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_PKCS12_H +# define HEADER_PKCS12_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define PKCS12_KEY_ID 1 +# define PKCS12_IV_ID 2 +# define PKCS12_MAC_ID 3 + +/* Default iteration count */ +# ifndef PKCS12_DEFAULT_ITER +# define PKCS12_DEFAULT_ITER PKCS5_DEFAULT_ITER +# endif + +# define PKCS12_MAC_KEY_LENGTH 20 + +# define PKCS12_SALT_LEN 8 + +/* Uncomment out next line for unicode password and names, otherwise ASCII */ + +/* + * #define PBE_UNICODE + */ + +# ifdef PBE_UNICODE +# define PKCS12_key_gen PKCS12_key_gen_uni +# define PKCS12_add_friendlyname PKCS12_add_friendlyname_uni +# else +# define PKCS12_key_gen PKCS12_key_gen_asc +# define PKCS12_add_friendlyname PKCS12_add_friendlyname_asc +# endif + +/* MS key usage constants */ + +# define KEY_EX 0x10 +# define KEY_SIG 0x80 + +typedef struct { + X509_SIG *dinfo; + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *iter; /* defaults to 1 */ +} PKCS12_MAC_DATA; + +typedef struct { + ASN1_INTEGER *version; + PKCS12_MAC_DATA *mac; + PKCS7 *authsafes; +} PKCS12; + +typedef struct { + ASN1_OBJECT *type; + union { + struct pkcs12_bag_st *bag; /* secret, crl and certbag */ + struct pkcs8_priv_key_info_st *keybag; /* keybag */ + X509_SIG *shkeybag; /* shrouded key bag */ + STACK_OF(PKCS12_SAFEBAG) *safes; + ASN1_TYPE *other; + } value; + STACK_OF(X509_ATTRIBUTE) *attrib; +} PKCS12_SAFEBAG; + +DECLARE_STACK_OF(PKCS12_SAFEBAG) +DECLARE_ASN1_SET_OF(PKCS12_SAFEBAG) +DECLARE_PKCS12_STACK_OF(PKCS12_SAFEBAG) + +typedef struct pkcs12_bag_st { + ASN1_OBJECT *type; + union { + ASN1_OCTET_STRING *x509cert; + ASN1_OCTET_STRING *x509crl; + ASN1_OCTET_STRING *octet; + ASN1_IA5STRING *sdsicert; + ASN1_TYPE *other; /* Secret or other bag */ + } value; +} PKCS12_BAGS; + +# define PKCS12_ERROR 0 +# define PKCS12_OK 1 + +/* Compatibility macros */ + +# define M_PKCS12_x5092certbag PKCS12_x5092certbag +# define M_PKCS12_x509crl2certbag PKCS12_x509crl2certbag + +# define M_PKCS12_certbag2x509 PKCS12_certbag2x509 +# define M_PKCS12_certbag2x509crl PKCS12_certbag2x509crl + +# define M_PKCS12_unpack_p7data PKCS12_unpack_p7data +# define M_PKCS12_pack_authsafes PKCS12_pack_authsafes +# define M_PKCS12_unpack_authsafes PKCS12_unpack_authsafes +# define M_PKCS12_unpack_p7encdata PKCS12_unpack_p7encdata + +# define M_PKCS12_decrypt_skey PKCS12_decrypt_skey +# define M_PKCS8_decrypt PKCS8_decrypt + +# define M_PKCS12_bag_type(bg) OBJ_obj2nid((bg)->type) +# define M_PKCS12_cert_bag_type(bg) OBJ_obj2nid((bg)->value.bag->type) +# define M_PKCS12_crl_bag_type M_PKCS12_cert_bag_type + +# define PKCS12_get_attr(bag, attr_nid) \ + PKCS12_get_attr_gen(bag->attrib, attr_nid) + +# define PKCS8_get_attr(p8, attr_nid) \ + PKCS12_get_attr_gen(p8->attributes, attr_nid) + +# define PKCS12_mac_present(p12) ((p12)->mac ? 1 : 0) + +PKCS12_SAFEBAG *PKCS12_x5092certbag(X509 *x509); +PKCS12_SAFEBAG *PKCS12_x509crl2certbag(X509_CRL *crl); +X509 *PKCS12_certbag2x509(PKCS12_SAFEBAG *bag); +X509_CRL *PKCS12_certbag2x509crl(PKCS12_SAFEBAG *bag); + +PKCS12_SAFEBAG *PKCS12_item_pack_safebag(void *obj, const ASN1_ITEM *it, + int nid1, int nid2); +PKCS12_SAFEBAG *PKCS12_MAKE_KEYBAG(PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *p8, const char *pass, + int passlen); +PKCS8_PRIV_KEY_INFO *PKCS12_decrypt_skey(PKCS12_SAFEBAG *bag, + const char *pass, int passlen); +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int passlen, unsigned char *salt, + int saltlen, int iter, PKCS8_PRIV_KEY_INFO *p8); +PKCS12_SAFEBAG *PKCS12_MAKE_SHKEYBAG(int pbe_nid, const char *pass, + int passlen, unsigned char *salt, + int saltlen, int iter, + PKCS8_PRIV_KEY_INFO *p8); +PKCS7 *PKCS12_pack_p7data(STACK_OF(PKCS12_SAFEBAG) *sk); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7); +PKCS7 *PKCS12_pack_p7encdata(int pbe_nid, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + STACK_OF(PKCS12_SAFEBAG) *bags); +STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass, + int passlen); + +int PKCS12_pack_authsafes(PKCS12 *p12, STACK_OF(PKCS7) *safes); +STACK_OF(PKCS7) *PKCS12_unpack_authsafes(PKCS12 *p12); + +int PKCS12_add_localkeyid(PKCS12_SAFEBAG *bag, unsigned char *name, + int namelen); +int PKCS12_add_friendlyname_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_CSPName_asc(PKCS12_SAFEBAG *bag, const char *name, + int namelen); +int PKCS12_add_friendlyname_uni(PKCS12_SAFEBAG *bag, + const unsigned char *name, int namelen); +int PKCS8_add_keyusage(PKCS8_PRIV_KEY_INFO *p8, int usage); +ASN1_TYPE *PKCS12_get_attr_gen(STACK_OF(X509_ATTRIBUTE) *attrs, int attr_nid); +char *PKCS12_get_friendlyname(PKCS12_SAFEBAG *bag); +unsigned char *PKCS12_pbe_crypt(X509_ALGOR *algor, const char *pass, + int passlen, unsigned char *in, int inlen, + unsigned char **data, int *datalen, + int en_de); +void *PKCS12_item_decrypt_d2i(X509_ALGOR *algor, const ASN1_ITEM *it, + const char *pass, int passlen, + ASN1_OCTET_STRING *oct, int zbuf); +ASN1_OCTET_STRING *PKCS12_item_i2d_encrypt(X509_ALGOR *algor, + const ASN1_ITEM *it, + const char *pass, int passlen, + void *obj, int zbuf); +PKCS12 *PKCS12_init(int mode); +int PKCS12_key_gen_asc(const char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_key_gen_uni(unsigned char *pass, int passlen, unsigned char *salt, + int saltlen, int id, int iter, int n, + unsigned char *out, const EVP_MD *md_type); +int PKCS12_PBE_keyivgen(EVP_CIPHER_CTX *ctx, const char *pass, int passlen, + ASN1_TYPE *param, const EVP_CIPHER *cipher, + const EVP_MD *md_type, int en_de); +int PKCS12_gen_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *mac, unsigned int *maclen); +int PKCS12_verify_mac(PKCS12 *p12, const char *pass, int passlen); +int PKCS12_set_mac(PKCS12 *p12, const char *pass, int passlen, + unsigned char *salt, int saltlen, int iter, + const EVP_MD *md_type); +int PKCS12_setup_mac(PKCS12 *p12, int iter, unsigned char *salt, + int saltlen, const EVP_MD *md_type); +unsigned char *OPENSSL_asc2uni(const char *asc, int asclen, + unsigned char **uni, int *unilen); +char *OPENSSL_uni2asc(unsigned char *uni, int unilen); + +DECLARE_ASN1_FUNCTIONS(PKCS12) +DECLARE_ASN1_FUNCTIONS(PKCS12_MAC_DATA) +DECLARE_ASN1_FUNCTIONS(PKCS12_SAFEBAG) +DECLARE_ASN1_FUNCTIONS(PKCS12_BAGS) + +DECLARE_ASN1_ITEM(PKCS12_SAFEBAGS) +DECLARE_ASN1_ITEM(PKCS12_AUTHSAFES) + +void PKCS12_PBE_add(void); +int PKCS12_parse(PKCS12 *p12, const char *pass, EVP_PKEY **pkey, X509 **cert, + STACK_OF(X509) **ca); +PKCS12 *PKCS12_create(char *pass, char *name, EVP_PKEY *pkey, X509 *cert, + STACK_OF(X509) *ca, int nid_key, int nid_cert, int iter, + int mac_iter, int keytype); + +PKCS12_SAFEBAG *PKCS12_add_cert(STACK_OF(PKCS12_SAFEBAG) **pbags, X509 *cert); +PKCS12_SAFEBAG *PKCS12_add_key(STACK_OF(PKCS12_SAFEBAG) **pbags, + EVP_PKEY *key, int key_usage, int iter, + int key_nid, char *pass); +int PKCS12_add_safe(STACK_OF(PKCS7) **psafes, STACK_OF(PKCS12_SAFEBAG) *bags, + int safe_nid, int iter, char *pass); +PKCS12 *PKCS12_add_safes(STACK_OF(PKCS7) *safes, int p7_nid); + +int i2d_PKCS12_bio(BIO *bp, PKCS12 *p12); +int i2d_PKCS12_fp(FILE *fp, PKCS12 *p12); +PKCS12 *d2i_PKCS12_bio(BIO *bp, PKCS12 **p12); +PKCS12 *d2i_PKCS12_fp(FILE *fp, PKCS12 **p12); +int PKCS12_newpass(PKCS12 *p12, char *oldpass, char *newpass); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_PKCS12_strings(void); + +/* Error codes for the PKCS12 functions. */ + +/* Function codes. */ +# define PKCS12_F_PARSE_BAG 129 +# define PKCS12_F_PARSE_BAGS 103 +# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME 100 +# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_ASC 127 +# define PKCS12_F_PKCS12_ADD_FRIENDLYNAME_UNI 102 +# define PKCS12_F_PKCS12_ADD_LOCALKEYID 104 +# define PKCS12_F_PKCS12_CREATE 105 +# define PKCS12_F_PKCS12_GEN_MAC 107 +# define PKCS12_F_PKCS12_INIT 109 +# define PKCS12_F_PKCS12_ITEM_DECRYPT_D2I 106 +# define PKCS12_F_PKCS12_ITEM_I2D_ENCRYPT 108 +# define PKCS12_F_PKCS12_ITEM_PACK_SAFEBAG 117 +# define PKCS12_F_PKCS12_KEY_GEN_ASC 110 +# define PKCS12_F_PKCS12_KEY_GEN_UNI 111 +# define PKCS12_F_PKCS12_MAKE_KEYBAG 112 +# define PKCS12_F_PKCS12_MAKE_SHKEYBAG 113 +# define PKCS12_F_PKCS12_NEWPASS 128 +# define PKCS12_F_PKCS12_PACK_P7DATA 114 +# define PKCS12_F_PKCS12_PACK_P7ENCDATA 115 +# define PKCS12_F_PKCS12_PARSE 118 +# define PKCS12_F_PKCS12_PBE_CRYPT 119 +# define PKCS12_F_PKCS12_PBE_KEYIVGEN 120 +# define PKCS12_F_PKCS12_SETUP_MAC 122 +# define PKCS12_F_PKCS12_SET_MAC 123 +# define PKCS12_F_PKCS12_UNPACK_AUTHSAFES 130 +# define PKCS12_F_PKCS12_UNPACK_P7DATA 131 +# define PKCS12_F_PKCS12_VERIFY_MAC 126 +# define PKCS12_F_PKCS8_ADD_KEYUSAGE 124 +# define PKCS12_F_PKCS8_ENCRYPT 125 + +/* Reason codes. */ +# define PKCS12_R_CANT_PACK_STRUCTURE 100 +# define PKCS12_R_CONTENT_TYPE_NOT_DATA 121 +# define PKCS12_R_DECODE_ERROR 101 +# define PKCS12_R_ENCODE_ERROR 102 +# define PKCS12_R_ENCRYPT_ERROR 103 +# define PKCS12_R_ERROR_SETTING_ENCRYPTED_DATA_TYPE 120 +# define PKCS12_R_INVALID_NULL_ARGUMENT 104 +# define PKCS12_R_INVALID_NULL_PKCS12_POINTER 105 +# define PKCS12_R_IV_GEN_ERROR 106 +# define PKCS12_R_KEY_GEN_ERROR 107 +# define PKCS12_R_MAC_ABSENT 108 +# define PKCS12_R_MAC_GENERATION_ERROR 109 +# define PKCS12_R_MAC_SETUP_ERROR 110 +# define PKCS12_R_MAC_STRING_SET_ERROR 111 +# define PKCS12_R_MAC_VERIFY_ERROR 112 +# define PKCS12_R_MAC_VERIFY_FAILURE 113 +# define PKCS12_R_PARSE_ERROR 114 +# define PKCS12_R_PKCS12_ALGOR_CIPHERINIT_ERROR 115 +# define PKCS12_R_PKCS12_CIPHERFINAL_ERROR 116 +# define PKCS12_R_PKCS12_PBE_CRYPT_ERROR 117 +# define PKCS12_R_UNKNOWN_DIGEST_ALGORITHM 118 +# define PKCS12_R_UNSUPPORTED_PKCS12_MODE 119 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/pkcs7/bio_pk7.c b/libs/openssl/crypto/pkcs7/bio_pk7.c new file mode 100644 index 00000000..fae1c564 --- /dev/null +++ b/libs/openssl/crypto/pkcs7/bio_pk7.c @@ -0,0 +1,70 @@ +/* bio_pk7.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include + +#if !defined(OPENSSL_SYSNAME_NETWARE) && !defined(OPENSSL_SYSNAME_VXWORKS) +# include +#endif +#include + +/* Streaming encode support for PKCS#7 */ + +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7) +{ + return BIO_new_NDEF(out, (ASN1_VALUE *)p7, ASN1_ITEM_rptr(PKCS7)); +} diff --git a/libs/openssl/crypto/pkcs7/pk7_asn1.c b/libs/openssl/crypto/pkcs7/pk7_asn1.c new file mode 100644 index 00000000..9c0a4398 --- /dev/null +++ b/libs/openssl/crypto/pkcs7/pk7_asn1.c @@ -0,0 +1,251 @@ +/* pk7_asn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +/* PKCS#7 ASN1 module */ + +/* This is the ANY DEFINED BY table for the top level PKCS#7 structure */ + +ASN1_ADB_TEMPLATE(p7default) = ASN1_EXP_OPT(PKCS7, d.other, ASN1_ANY, 0); + +ASN1_ADB(PKCS7) = { + ADB_ENTRY(NID_pkcs7_data, ASN1_NDEF_EXP_OPT(PKCS7, d.data, ASN1_OCTET_STRING_NDEF, 0)), + ADB_ENTRY(NID_pkcs7_signed, ASN1_NDEF_EXP_OPT(PKCS7, d.sign, PKCS7_SIGNED, 0)), + ADB_ENTRY(NID_pkcs7_enveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.enveloped, PKCS7_ENVELOPE, 0)), + ADB_ENTRY(NID_pkcs7_signedAndEnveloped, ASN1_NDEF_EXP_OPT(PKCS7, d.signed_and_enveloped, PKCS7_SIGN_ENVELOPE, 0)), + ADB_ENTRY(NID_pkcs7_digest, ASN1_NDEF_EXP_OPT(PKCS7, d.digest, PKCS7_DIGEST, 0)), + ADB_ENTRY(NID_pkcs7_encrypted, ASN1_NDEF_EXP_OPT(PKCS7, d.encrypted, PKCS7_ENCRYPT, 0)) +} ASN1_ADB_END(PKCS7, 0, type, 0, &p7default_tt, NULL); + +/* PKCS#7 streaming support */ +static int pk7_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + ASN1_STREAM_ARG *sarg = exarg; + PKCS7 **pp7 = (PKCS7 **)pval; + + switch (operation) { + + case ASN1_OP_STREAM_PRE: + if (PKCS7_stream(&sarg->boundary, *pp7) <= 0) + return 0; + case ASN1_OP_DETACHED_PRE: + sarg->ndef_bio = PKCS7_dataInit(*pp7, sarg->out); + if (!sarg->ndef_bio) + return 0; + break; + + case ASN1_OP_STREAM_POST: + case ASN1_OP_DETACHED_POST: + if (PKCS7_dataFinal(*pp7, sarg->ndef_bio) <= 0) + return 0; + break; + + } + return 1; +} + +ASN1_NDEF_SEQUENCE_cb(PKCS7, pk7_cb) = { + ASN1_SIMPLE(PKCS7, type, ASN1_OBJECT), + ASN1_ADB_OBJECT(PKCS7) +}ASN1_NDEF_SEQUENCE_END_cb(PKCS7, PKCS7) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7) + +IMPLEMENT_ASN1_NDEF_FUNCTION(PKCS7) + +IMPLEMENT_ASN1_DUP_FUNCTION(PKCS7) + +ASN1_NDEF_SEQUENCE(PKCS7_SIGNED) = { + ASN1_SIMPLE(PKCS7_SIGNED, version, ASN1_INTEGER), + ASN1_SET_OF(PKCS7_SIGNED, md_algs, X509_ALGOR), + ASN1_SIMPLE(PKCS7_SIGNED, contents, PKCS7), + ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNED, cert, X509, 0), + ASN1_IMP_SET_OF_OPT(PKCS7_SIGNED, crl, X509_CRL, 1), + ASN1_SET_OF(PKCS7_SIGNED, signer_info, PKCS7_SIGNER_INFO) +} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGNED) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNED) + +/* Minor tweak to operation: free up EVP_PKEY */ +static int si_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_FREE_POST) { + PKCS7_SIGNER_INFO *si = (PKCS7_SIGNER_INFO *)*pval; + EVP_PKEY_free(si->pkey); + } + return 1; +} + +ASN1_SEQUENCE_cb(PKCS7_SIGNER_INFO, si_cb) = { + ASN1_SIMPLE(PKCS7_SIGNER_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS7_SIGNER_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL), + ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_alg, X509_ALGOR), + /* NB this should be a SET OF but we use a SEQUENCE OF so the + * original order * is retained when the structure is reencoded. + * Since the attributes are implicitly tagged this will not affect + * the encoding. + */ + ASN1_IMP_SEQUENCE_OF_OPT(PKCS7_SIGNER_INFO, auth_attr, X509_ATTRIBUTE, 0), + ASN1_SIMPLE(PKCS7_SIGNER_INFO, digest_enc_alg, X509_ALGOR), + ASN1_SIMPLE(PKCS7_SIGNER_INFO, enc_digest, ASN1_OCTET_STRING), + ASN1_IMP_SET_OF_OPT(PKCS7_SIGNER_INFO, unauth_attr, X509_ATTRIBUTE, 1) +} ASN1_SEQUENCE_END_cb(PKCS7_SIGNER_INFO, PKCS7_SIGNER_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) + +ASN1_SEQUENCE(PKCS7_ISSUER_AND_SERIAL) = { + ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, issuer, X509_NAME), + ASN1_SIMPLE(PKCS7_ISSUER_AND_SERIAL, serial, ASN1_INTEGER) +} ASN1_SEQUENCE_END(PKCS7_ISSUER_AND_SERIAL) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) + +ASN1_NDEF_SEQUENCE(PKCS7_ENVELOPE) = { + ASN1_SIMPLE(PKCS7_ENVELOPE, version, ASN1_INTEGER), + ASN1_SET_OF(PKCS7_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO), + ASN1_SIMPLE(PKCS7_ENVELOPE, enc_data, PKCS7_ENC_CONTENT) +} ASN1_NDEF_SEQUENCE_END(PKCS7_ENVELOPE) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENVELOPE) + +/* Minor tweak to operation: free up X509 */ +static int ri_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_FREE_POST) { + PKCS7_RECIP_INFO *ri = (PKCS7_RECIP_INFO *)*pval; + X509_free(ri->cert); + } + return 1; +} + +ASN1_SEQUENCE_cb(PKCS7_RECIP_INFO, ri_cb) = { + ASN1_SIMPLE(PKCS7_RECIP_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS7_RECIP_INFO, issuer_and_serial, PKCS7_ISSUER_AND_SERIAL), + ASN1_SIMPLE(PKCS7_RECIP_INFO, key_enc_algor, X509_ALGOR), + ASN1_SIMPLE(PKCS7_RECIP_INFO, enc_key, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END_cb(PKCS7_RECIP_INFO, PKCS7_RECIP_INFO) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) + +ASN1_NDEF_SEQUENCE(PKCS7_ENC_CONTENT) = { + ASN1_SIMPLE(PKCS7_ENC_CONTENT, content_type, ASN1_OBJECT), + ASN1_SIMPLE(PKCS7_ENC_CONTENT, algorithm, X509_ALGOR), + ASN1_IMP_OPT(PKCS7_ENC_CONTENT, enc_data, ASN1_OCTET_STRING_NDEF, 0) +} ASN1_NDEF_SEQUENCE_END(PKCS7_ENC_CONTENT) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) + +ASN1_NDEF_SEQUENCE(PKCS7_SIGN_ENVELOPE) = { + ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, version, ASN1_INTEGER), + ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, recipientinfo, PKCS7_RECIP_INFO), + ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, md_algs, X509_ALGOR), + ASN1_SIMPLE(PKCS7_SIGN_ENVELOPE, enc_data, PKCS7_ENC_CONTENT), + ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, cert, X509, 0), + ASN1_IMP_SET_OF_OPT(PKCS7_SIGN_ENVELOPE, crl, X509_CRL, 1), + ASN1_SET_OF(PKCS7_SIGN_ENVELOPE, signer_info, PKCS7_SIGNER_INFO) +} ASN1_NDEF_SEQUENCE_END(PKCS7_SIGN_ENVELOPE) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) + +ASN1_NDEF_SEQUENCE(PKCS7_ENCRYPT) = { + ASN1_SIMPLE(PKCS7_ENCRYPT, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS7_ENCRYPT, enc_data, PKCS7_ENC_CONTENT) +} ASN1_NDEF_SEQUENCE_END(PKCS7_ENCRYPT) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_ENCRYPT) + +ASN1_NDEF_SEQUENCE(PKCS7_DIGEST) = { + ASN1_SIMPLE(PKCS7_DIGEST, version, ASN1_INTEGER), + ASN1_SIMPLE(PKCS7_DIGEST, md, X509_ALGOR), + ASN1_SIMPLE(PKCS7_DIGEST, contents, PKCS7), + ASN1_SIMPLE(PKCS7_DIGEST, digest, ASN1_OCTET_STRING) +} ASN1_NDEF_SEQUENCE_END(PKCS7_DIGEST) + +IMPLEMENT_ASN1_FUNCTIONS(PKCS7_DIGEST) + +/* Specials for authenticated attributes */ + +/* + * When signing attributes we want to reorder them to match the sorted + * encoding. + */ + +ASN1_ITEM_TEMPLATE(PKCS7_ATTR_SIGN) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_ORDER, 0, PKCS7_ATTRIBUTES, X509_ATTRIBUTE) +ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_SIGN) + +/* + * When verifying attributes we need to use the received order. So we use + * SEQUENCE OF and tag it to SET OF + */ + +ASN1_ITEM_TEMPLATE(PKCS7_ATTR_VERIFY) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF | ASN1_TFLG_IMPTAG | ASN1_TFLG_UNIVERSAL, + V_ASN1_SET, PKCS7_ATTRIBUTES, X509_ATTRIBUTE) +ASN1_ITEM_TEMPLATE_END(PKCS7_ATTR_VERIFY) + +IMPLEMENT_ASN1_PRINT_FUNCTION(PKCS7) diff --git a/libs/openssl/crypto/pkcs7/pk7_attr.c b/libs/openssl/crypto/pkcs7/pk7_attr.c new file mode 100644 index 00000000..88922efe --- /dev/null +++ b/libs/openssl/crypto/pkcs7/pk7_attr.c @@ -0,0 +1,165 @@ +/* pk7_attr.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, + STACK_OF(X509_ALGOR) *cap) +{ + ASN1_STRING *seq; + if (!(seq = ASN1_STRING_new())) { + PKCS7err(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP, ERR_R_MALLOC_FAILURE); + return 0; + } + seq->length = ASN1_item_i2d((ASN1_VALUE *)cap, &seq->data, + ASN1_ITEM_rptr(X509_ALGORS)); + return PKCS7_add_signed_attribute(si, NID_SMIMECapabilities, + V_ASN1_SEQUENCE, seq); +} + +STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si) +{ + ASN1_TYPE *cap; + const unsigned char *p; + + cap = PKCS7_get_signed_attribute(si, NID_SMIMECapabilities); + if (!cap || (cap->type != V_ASN1_SEQUENCE)) + return NULL; + p = cap->value.sequence->data; + return (STACK_OF(X509_ALGOR) *) + ASN1_item_d2i(NULL, &p, cap->value.sequence->length, + ASN1_ITEM_rptr(X509_ALGORS)); +} + +/* Basic smime-capabilities OID and optional integer arg */ +int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) +{ + X509_ALGOR *alg; + + if (!(alg = X509_ALGOR_new())) { + PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_OBJECT_free(alg->algorithm); + alg->algorithm = OBJ_nid2obj(nid); + if (arg > 0) { + ASN1_INTEGER *nbit; + if (!(alg->parameter = ASN1_TYPE_new())) { + PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!(nbit = ASN1_INTEGER_new())) { + PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!ASN1_INTEGER_set(nbit, arg)) { + PKCS7err(PKCS7_F_PKCS7_SIMPLE_SMIMECAP, ERR_R_MALLOC_FAILURE); + return 0; + } + alg->parameter->value.integer = nbit; + alg->parameter->type = V_ASN1_INTEGER; + } + sk_X509_ALGOR_push(sk, alg); + return 1; +} + +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid) +{ + if (PKCS7_get_signed_attribute(si, NID_pkcs9_contentType)) + return 0; + if (!coid) + coid = OBJ_nid2obj(NID_pkcs7_data); + return PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, + V_ASN1_OBJECT, coid); +} + +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t) +{ + if (!t && !(t = X509_gmtime_adj(NULL, 0))) { + PKCS7err(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME, + ERR_R_MALLOC_FAILURE); + return 0; + } + return PKCS7_add_signed_attribute(si, NID_pkcs9_signingTime, + V_ASN1_UTCTIME, t); +} + +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, + const unsigned char *md, int mdlen) +{ + ASN1_OCTET_STRING *os; + os = ASN1_OCTET_STRING_new(); + if (!os) + return 0; + if (!ASN1_STRING_set(os, md, mdlen) + || !PKCS7_add_signed_attribute(si, NID_pkcs9_messageDigest, + V_ASN1_OCTET_STRING, os)) { + ASN1_OCTET_STRING_free(os); + return 0; + } + return 1; +} diff --git a/libs/openssl/crypto/pkcs7/pk7_dgst.c b/libs/openssl/crypto/pkcs7/pk7_dgst.c new file mode 100644 index 00000000..6b57f97a --- /dev/null +++ b/libs/openssl/crypto/pkcs7/pk7_dgst.c @@ -0,0 +1,65 @@ +/* crypto/pkcs7/pk7_dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include diff --git a/libs/openssl/crypto/pkcs7/pk7_doit.c b/libs/openssl/crypto/pkcs7/pk7_doit.c new file mode 100644 index 00000000..946aaa65 --- /dev/null +++ b/libs/openssl/crypto/pkcs7/pk7_doit.c @@ -0,0 +1,1295 @@ +/* crypto/pkcs7/pk7_doit.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include + +static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, + void *value); +static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid); + +static int PKCS7_type_is_other(PKCS7 *p7) +{ + int isOther = 1; + + int nid = OBJ_obj2nid(p7->type); + + switch (nid) { + case NID_pkcs7_data: + case NID_pkcs7_signed: + case NID_pkcs7_enveloped: + case NID_pkcs7_signedAndEnveloped: + case NID_pkcs7_digest: + case NID_pkcs7_encrypted: + isOther = 0; + break; + default: + isOther = 1; + } + + return isOther; + +} + +static ASN1_OCTET_STRING *PKCS7_get_octet_string(PKCS7 *p7) +{ + if (PKCS7_type_is_data(p7)) + return p7->d.data; + if (PKCS7_type_is_other(p7) && p7->d.other + && (p7->d.other->type == V_ASN1_OCTET_STRING)) + return p7->d.other->value.octet_string; + return NULL; +} + +static int PKCS7_bio_add_digest(BIO **pbio, X509_ALGOR *alg) +{ + BIO *btmp; + const EVP_MD *md; + if ((btmp = BIO_new(BIO_f_md())) == NULL) { + PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); + goto err; + } + + md = EVP_get_digestbyobj(alg->algorithm); + if (md == NULL) { + PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, PKCS7_R_UNKNOWN_DIGEST_TYPE); + goto err; + } + + BIO_set_md(btmp, md); + if (*pbio == NULL) + *pbio = btmp; + else if (!BIO_push(*pbio, btmp)) { + PKCS7err(PKCS7_F_PKCS7_BIO_ADD_DIGEST, ERR_R_BIO_LIB); + goto err; + } + btmp = NULL; + + return 1; + + err: + if (btmp) + BIO_free(btmp); + return 0; + +} + +static int pkcs7_encode_rinfo(PKCS7_RECIP_INFO *ri, + unsigned char *key, int keylen) +{ + EVP_PKEY_CTX *pctx = NULL; + EVP_PKEY *pkey = NULL; + unsigned char *ek = NULL; + int ret = 0; + size_t eklen; + + pkey = X509_get_pubkey(ri->cert); + + if (!pkey) + return 0; + + pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pctx) + return 0; + + if (EVP_PKEY_encrypt_init(pctx) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_ENCRYPT, + EVP_PKEY_CTRL_PKCS7_ENCRYPT, 0, ri) <= 0) { + PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, PKCS7_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, NULL, &eklen, key, keylen) <= 0) + goto err; + + ek = OPENSSL_malloc(eklen); + + if (ek == NULL) { + PKCS7err(PKCS7_F_PKCS7_ENCODE_RINFO, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_encrypt(pctx, ek, &eklen, key, keylen) <= 0) + goto err; + + ASN1_STRING_set0(ri->enc_key, ek, eklen); + ek = NULL; + + ret = 1; + + err: + if (pkey) + EVP_PKEY_free(pkey); + if (pctx) + EVP_PKEY_CTX_free(pctx); + if (ek) + OPENSSL_free(ek); + return ret; + +} + +static int pkcs7_decrypt_rinfo(unsigned char **pek, int *peklen, + PKCS7_RECIP_INFO *ri, EVP_PKEY *pkey) +{ + EVP_PKEY_CTX *pctx = NULL; + unsigned char *ek = NULL; + size_t eklen; + + int ret = -1; + + pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pctx) + return -1; + + if (EVP_PKEY_decrypt_init(pctx) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_DECRYPT, + EVP_PKEY_CTRL_PKCS7_DECRYPT, 0, ri) <= 0) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, PKCS7_R_CTRL_ERROR); + goto err; + } + + if (EVP_PKEY_decrypt(pctx, NULL, &eklen, + ri->enc_key->data, ri->enc_key->length) <= 0) + goto err; + + ek = OPENSSL_malloc(eklen); + + if (ek == NULL) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (EVP_PKEY_decrypt(pctx, ek, &eklen, + ri->enc_key->data, ri->enc_key->length) <= 0) { + ret = 0; + PKCS7err(PKCS7_F_PKCS7_DECRYPT_RINFO, ERR_R_EVP_LIB); + goto err; + } + + ret = 1; + + if (*pek) { + OPENSSL_cleanse(*pek, *peklen); + OPENSSL_free(*pek); + } + + *pek = ek; + *peklen = eklen; + + err: + if (pctx) + EVP_PKEY_CTX_free(pctx); + if (!ret && ek) + OPENSSL_free(ek); + + return ret; +} + +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio) +{ + int i; + BIO *out = NULL, *btmp = NULL; + X509_ALGOR *xa = NULL; + const EVP_CIPHER *evp_cipher = NULL; + STACK_OF(X509_ALGOR) *md_sk = NULL; + STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; + X509_ALGOR *xalg = NULL; + PKCS7_RECIP_INFO *ri = NULL; + ASN1_OCTET_STRING *os = NULL; + + if (p7 == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_INVALID_NULL_POINTER); + return NULL; + } + /* + * The content field in the PKCS7 ContentInfo is optional, but that really + * only applies to inner content (precisely, detached signatures). + * + * When reading content, missing outer content is therefore treated as an + * error. + * + * When creating content, PKCS7_content_new() must be called before + * calling this method, so a NULL p7->d is always an error. + */ + if (p7->d.ptr == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_NO_CONTENT); + return NULL; + } + + i = OBJ_obj2nid(p7->type); + p7->state = PKCS7_S_HEADER; + + switch (i) { + case NID_pkcs7_signed: + md_sk = p7->d.sign->md_algs; + os = PKCS7_get_octet_string(p7->d.sign->contents); + break; + case NID_pkcs7_signedAndEnveloped: + rsk = p7->d.signed_and_enveloped->recipientinfo; + md_sk = p7->d.signed_and_enveloped->md_algs; + xalg = p7->d.signed_and_enveloped->enc_data->algorithm; + evp_cipher = p7->d.signed_and_enveloped->enc_data->cipher; + if (evp_cipher == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); + goto err; + } + break; + case NID_pkcs7_enveloped: + rsk = p7->d.enveloped->recipientinfo; + xalg = p7->d.enveloped->enc_data->algorithm; + evp_cipher = p7->d.enveloped->enc_data->cipher; + if (evp_cipher == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_CIPHER_NOT_INITIALIZED); + goto err; + } + break; + case NID_pkcs7_digest: + xa = p7->d.digest->md; + os = PKCS7_get_octet_string(p7->d.digest->contents); + break; + case NID_pkcs7_data: + break; + default: + PKCS7err(PKCS7_F_PKCS7_DATAINIT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + + for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) + if (!PKCS7_bio_add_digest(&out, sk_X509_ALGOR_value(md_sk, i))) + goto err; + + if (xa && !PKCS7_bio_add_digest(&out, xa)) + goto err; + + if (evp_cipher != NULL) { + unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char iv[EVP_MAX_IV_LENGTH]; + int keylen, ivlen; + EVP_CIPHER_CTX *ctx; + + if ((btmp = BIO_new(BIO_f_cipher())) == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAINIT, ERR_R_BIO_LIB); + goto err; + } + BIO_get_cipher_ctx(btmp, &ctx); + keylen = EVP_CIPHER_key_length(evp_cipher); + ivlen = EVP_CIPHER_iv_length(evp_cipher); + xalg->algorithm = OBJ_nid2obj(EVP_CIPHER_type(evp_cipher)); + if (ivlen > 0) + if (RAND_pseudo_bytes(iv, ivlen) <= 0) + goto err; + if (EVP_CipherInit_ex(ctx, evp_cipher, NULL, NULL, NULL, 1) <= 0) + goto err; + if (EVP_CIPHER_CTX_rand_key(ctx, key) <= 0) + goto err; + if (EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, 1) <= 0) + goto err; + + if (ivlen > 0) { + if (xalg->parameter == NULL) { + xalg->parameter = ASN1_TYPE_new(); + if (xalg->parameter == NULL) + goto err; + } + if (EVP_CIPHER_param_to_asn1(ctx, xalg->parameter) < 0) + goto err; + } + + /* Lets do the pub key stuff :-) */ + for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { + ri = sk_PKCS7_RECIP_INFO_value(rsk, i); + if (pkcs7_encode_rinfo(ri, key, keylen) <= 0) + goto err; + } + OPENSSL_cleanse(key, keylen); + + if (out == NULL) + out = btmp; + else + BIO_push(out, btmp); + btmp = NULL; + } + + if (bio == NULL) { + if (PKCS7_is_detached(p7)) + bio = BIO_new(BIO_s_null()); + else if (os && os->length > 0) + bio = BIO_new_mem_buf(os->data, os->length); + if (bio == NULL) { + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) + goto err; + BIO_set_mem_eof_return(bio, 0); + } + } + if (out) + BIO_push(out, bio); + else + out = bio; + bio = NULL; + if (0) { + err: + if (out != NULL) + BIO_free_all(out); + if (btmp != NULL) + BIO_free_all(btmp); + out = NULL; + } + return (out); +} + +static int pkcs7_cmp_ri(PKCS7_RECIP_INFO *ri, X509 *pcert) +{ + int ret; + ret = X509_NAME_cmp(ri->issuer_and_serial->issuer, + pcert->cert_info->issuer); + if (ret) + return ret; + return M_ASN1_INTEGER_cmp(pcert->cert_info->serialNumber, + ri->issuer_and_serial->serial); +} + +/* int */ +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert) +{ + int i, j; + BIO *out = NULL, *btmp = NULL, *etmp = NULL, *bio = NULL; + X509_ALGOR *xa; + ASN1_OCTET_STRING *data_body = NULL; + const EVP_MD *evp_md; + const EVP_CIPHER *evp_cipher = NULL; + EVP_CIPHER_CTX *evp_ctx = NULL; + X509_ALGOR *enc_alg = NULL; + STACK_OF(X509_ALGOR) *md_sk = NULL; + STACK_OF(PKCS7_RECIP_INFO) *rsk = NULL; + PKCS7_RECIP_INFO *ri = NULL; + unsigned char *ek = NULL, *tkey = NULL; + int eklen = 0, tkeylen = 0; + + if (p7 == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_INVALID_NULL_POINTER); + return NULL; + } + + if (p7->d.ptr == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); + return NULL; + } + + i = OBJ_obj2nid(p7->type); + p7->state = PKCS7_S_HEADER; + + switch (i) { + case NID_pkcs7_signed: + /* + * p7->d.sign->contents is a PKCS7 structure consisting of a contentType + * field and optional content. + * data_body is NULL if that structure has no (=detached) content + * or if the contentType is wrong (i.e., not "data"). + */ + data_body = PKCS7_get_octet_string(p7->d.sign->contents); + if (!PKCS7_is_detached(p7) && data_body == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, + PKCS7_R_INVALID_SIGNED_DATA_TYPE); + goto err; + } + md_sk = p7->d.sign->md_algs; + break; + case NID_pkcs7_signedAndEnveloped: + rsk = p7->d.signed_and_enveloped->recipientinfo; + md_sk = p7->d.signed_and_enveloped->md_algs; + /* data_body is NULL if the optional EncryptedContent is missing. */ + data_body = p7->d.signed_and_enveloped->enc_data->enc_data; + enc_alg = p7->d.signed_and_enveloped->enc_data->algorithm; + evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); + if (evp_cipher == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, + PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + goto err; + } + break; + case NID_pkcs7_enveloped: + rsk = p7->d.enveloped->recipientinfo; + enc_alg = p7->d.enveloped->enc_data->algorithm; + /* data_body is NULL if the optional EncryptedContent is missing. */ + data_body = p7->d.enveloped->enc_data->enc_data; + evp_cipher = EVP_get_cipherbyobj(enc_alg->algorithm); + if (evp_cipher == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, + PKCS7_R_UNSUPPORTED_CIPHER_TYPE); + goto err; + } + break; + default: + PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + + /* Detached content must be supplied via in_bio instead. */ + if (data_body == NULL && in_bio == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); + goto err; + } + + /* We will be checking the signature */ + if (md_sk != NULL) { + for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { + xa = sk_X509_ALGOR_value(md_sk, i); + if ((btmp = BIO_new(BIO_f_md())) == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); + goto err; + } + + j = OBJ_obj2nid(xa->algorithm); + evp_md = EVP_get_digestbynid(j); + if (evp_md == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, + PKCS7_R_UNKNOWN_DIGEST_TYPE); + goto err; + } + + BIO_set_md(btmp, evp_md); + if (out == NULL) + out = btmp; + else + BIO_push(out, btmp); + btmp = NULL; + } + } + + if (evp_cipher != NULL) { +#if 0 + unsigned char key[EVP_MAX_KEY_LENGTH]; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char *p; + int keylen, ivlen; + int max; + X509_OBJECT ret; +#endif + + if ((etmp = BIO_new(BIO_f_cipher())) == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, ERR_R_BIO_LIB); + goto err; + } + + /* + * It was encrypted, we need to decrypt the secret key with the + * private key + */ + + /* + * Find the recipientInfo which matches the passed certificate (if + * any) + */ + + if (pcert) { + for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { + ri = sk_PKCS7_RECIP_INFO_value(rsk, i); + if (!pkcs7_cmp_ri(ri, pcert)) + break; + ri = NULL; + } + if (ri == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATADECODE, + PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE); + goto err; + } + } + + /* If we haven't got a certificate try each ri in turn */ + if (pcert == NULL) { + /* + * Always attempt to decrypt all rinfo even after sucess as a + * defence against MMA timing attacks. + */ + for (i = 0; i < sk_PKCS7_RECIP_INFO_num(rsk); i++) { + ri = sk_PKCS7_RECIP_INFO_value(rsk, i); + + if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) + goto err; + ERR_clear_error(); + } + } else { + /* Only exit on fatal errors, not decrypt failure */ + if (pkcs7_decrypt_rinfo(&ek, &eklen, ri, pkey) < 0) + goto err; + ERR_clear_error(); + } + + evp_ctx = NULL; + BIO_get_cipher_ctx(etmp, &evp_ctx); + if (EVP_CipherInit_ex(evp_ctx, evp_cipher, NULL, NULL, NULL, 0) <= 0) + goto err; + if (EVP_CIPHER_asn1_to_param(evp_ctx, enc_alg->parameter) < 0) + goto err; + /* Generate random key as MMA defence */ + tkeylen = EVP_CIPHER_CTX_key_length(evp_ctx); + tkey = OPENSSL_malloc(tkeylen); + if (!tkey) + goto err; + if (EVP_CIPHER_CTX_rand_key(evp_ctx, tkey) <= 0) + goto err; + if (ek == NULL) { + ek = tkey; + eklen = tkeylen; + tkey = NULL; + } + + if (eklen != EVP_CIPHER_CTX_key_length(evp_ctx)) { + /* + * Some S/MIME clients don't use the same key and effective key + * length. The key length is determined by the size of the + * decrypted RSA key. + */ + if (!EVP_CIPHER_CTX_set_key_length(evp_ctx, eklen)) { + /* Use random key as MMA defence */ + OPENSSL_cleanse(ek, eklen); + OPENSSL_free(ek); + ek = tkey; + eklen = tkeylen; + tkey = NULL; + } + } + /* Clear errors so we don't leak information useful in MMA */ + ERR_clear_error(); + if (EVP_CipherInit_ex(evp_ctx, NULL, NULL, ek, NULL, 0) <= 0) + goto err; + + if (ek) { + OPENSSL_cleanse(ek, eklen); + OPENSSL_free(ek); + ek = NULL; + } + if (tkey) { + OPENSSL_cleanse(tkey, tkeylen); + OPENSSL_free(tkey); + tkey = NULL; + } + + if (out == NULL) + out = etmp; + else + BIO_push(out, etmp); + etmp = NULL; + } +#if 1 + if (in_bio != NULL) { + bio = in_bio; + } else { +# if 0 + bio = BIO_new(BIO_s_mem()); + /* + * We need to set this so that when we have read all the data, the + * encrypt BIO, if present, will read EOF and encode the last few + * bytes + */ + BIO_set_mem_eof_return(bio, 0); + + if (data_body->length > 0) + BIO_write(bio, (char *)data_body->data, data_body->length); +# else + if (data_body->length > 0) + bio = BIO_new_mem_buf(data_body->data, data_body->length); + else { + bio = BIO_new(BIO_s_mem()); + if (bio == NULL) + goto err; + BIO_set_mem_eof_return(bio, 0); + } + if (bio == NULL) + goto err; +# endif + } + BIO_push(out, bio); + bio = NULL; +#endif + if (0) { + err: + if (ek) { + OPENSSL_cleanse(ek, eklen); + OPENSSL_free(ek); + } + if (tkey) { + OPENSSL_cleanse(tkey, tkeylen); + OPENSSL_free(tkey); + } + if (out != NULL) + BIO_free_all(out); + if (btmp != NULL) + BIO_free_all(btmp); + if (etmp != NULL) + BIO_free_all(etmp); + if (bio != NULL) + BIO_free_all(bio); + out = NULL; + } + return (out); +} + +static BIO *PKCS7_find_digest(EVP_MD_CTX **pmd, BIO *bio, int nid) +{ + for (;;) { + bio = BIO_find_type(bio, BIO_TYPE_MD); + if (bio == NULL) { + PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, + PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + return NULL; + } + BIO_get_md_ctx(bio, pmd); + if (*pmd == NULL) { + PKCS7err(PKCS7_F_PKCS7_FIND_DIGEST, ERR_R_INTERNAL_ERROR); + return NULL; + } + if (EVP_MD_CTX_type(*pmd) == nid) + return bio; + bio = BIO_next(bio); + } + return NULL; +} + +static int do_pkcs7_signed_attrib(PKCS7_SIGNER_INFO *si, EVP_MD_CTX *mctx) +{ + unsigned char md_data[EVP_MAX_MD_SIZE]; + unsigned int md_len; + + /* Add signing time if not already present */ + if (!PKCS7_get_signed_attribute(si, NID_pkcs9_signingTime)) { + if (!PKCS7_add0_attrib_signing_time(si, NULL)) { + PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + /* Add digest */ + if (!EVP_DigestFinal_ex(mctx, md_data, &md_len)) { + PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_EVP_LIB); + return 0; + } + if (!PKCS7_add1_attrib_digest(si, md_data, md_len)) { + PKCS7err(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB, ERR_R_MALLOC_FAILURE); + return 0; + } + + /* Now sign the attributes */ + if (!PKCS7_SIGNER_INFO_sign(si)) + return 0; + + return 1; +} + +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio) +{ + int ret = 0; + int i, j; + BIO *btmp; + PKCS7_SIGNER_INFO *si; + EVP_MD_CTX *mdc, ctx_tmp; + STACK_OF(X509_ATTRIBUTE) *sk; + STACK_OF(PKCS7_SIGNER_INFO) *si_sk = NULL; + ASN1_OCTET_STRING *os = NULL; + + if (p7 == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + + if (p7->d.ptr == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_NO_CONTENT); + return 0; + } + + EVP_MD_CTX_init(&ctx_tmp); + i = OBJ_obj2nid(p7->type); + p7->state = PKCS7_S_HEADER; + + switch (i) { + case NID_pkcs7_data: + os = p7->d.data; + break; + case NID_pkcs7_signedAndEnveloped: + /* XXXXXXXXXXXXXXXX */ + si_sk = p7->d.signed_and_enveloped->signer_info; + os = p7->d.signed_and_enveloped->enc_data->enc_data; + if (!os) { + os = M_ASN1_OCTET_STRING_new(); + if (!os) { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); + goto err; + } + p7->d.signed_and_enveloped->enc_data->enc_data = os; + } + break; + case NID_pkcs7_enveloped: + /* XXXXXXXXXXXXXXXX */ + os = p7->d.enveloped->enc_data->enc_data; + if (!os) { + os = M_ASN1_OCTET_STRING_new(); + if (!os) { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_MALLOC_FAILURE); + goto err; + } + p7->d.enveloped->enc_data->enc_data = os; + } + break; + case NID_pkcs7_signed: + si_sk = p7->d.sign->signer_info; + os = PKCS7_get_octet_string(p7->d.sign->contents); + /* If detached data then the content is excluded */ + if (PKCS7_type_is_data(p7->d.sign->contents) && p7->detached) { + M_ASN1_OCTET_STRING_free(os); + os = NULL; + p7->d.sign->contents->d.data = NULL; + } + break; + + case NID_pkcs7_digest: + os = PKCS7_get_octet_string(p7->d.digest->contents); + /* If detached data then the content is excluded */ + if (PKCS7_type_is_data(p7->d.digest->contents) && p7->detached) { + M_ASN1_OCTET_STRING_free(os); + os = NULL; + p7->d.digest->contents->d.data = NULL; + } + break; + + default: + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + + if (si_sk != NULL) { + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(si_sk); i++) { + si = sk_PKCS7_SIGNER_INFO_value(si_sk, i); + if (si->pkey == NULL) + continue; + + j = OBJ_obj2nid(si->digest_alg->algorithm); + + btmp = bio; + + btmp = PKCS7_find_digest(&mdc, btmp, j); + + if (btmp == NULL) + goto err; + + /* + * We now have the EVP_MD_CTX, lets do the signing. + */ + if (!EVP_MD_CTX_copy_ex(&ctx_tmp, mdc)) + goto err; + + sk = si->auth_attr; + + /* + * If there are attributes, we add the digest attribute and only + * sign the attributes + */ + if (sk_X509_ATTRIBUTE_num(sk) > 0) { + if (!do_pkcs7_signed_attrib(si, &ctx_tmp)) + goto err; + } else { + unsigned char *abuf = NULL; + unsigned int abuflen; + abuflen = EVP_PKEY_size(si->pkey); + abuf = OPENSSL_malloc(abuflen); + if (!abuf) + goto err; + + if (!EVP_SignFinal(&ctx_tmp, abuf, &abuflen, si->pkey)) { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, ERR_R_EVP_LIB); + goto err; + } + ASN1_STRING_set0(si->enc_digest, abuf, abuflen); + } + } + } else if (i == NID_pkcs7_digest) { + unsigned char md_data[EVP_MAX_MD_SIZE]; + unsigned int md_len; + if (!PKCS7_find_digest(&mdc, bio, + OBJ_obj2nid(p7->d.digest->md->algorithm))) + goto err; + if (!EVP_DigestFinal_ex(mdc, md_data, &md_len)) + goto err; + M_ASN1_OCTET_STRING_set(p7->d.digest->digest, md_data, md_len); + } + + if (!PKCS7_is_detached(p7)) { + /* + * NOTE(emilia): I think we only reach os == NULL here because detached + * digested data support is broken. + */ + if (os == NULL) + goto err; + if (!(os->flags & ASN1_STRING_FLAG_NDEF)) { + char *cont; + long contlen; + btmp = BIO_find_type(bio, BIO_TYPE_MEM); + if (btmp == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAFINAL, PKCS7_R_UNABLE_TO_FIND_MEM_BIO); + goto err; + } + contlen = BIO_get_mem_data(btmp, &cont); + /* + * Mark the BIO read only then we can use its copy of the data + * instead of making an extra copy. + */ + BIO_set_flags(btmp, BIO_FLAGS_MEM_RDONLY); + BIO_set_mem_eof_return(btmp, 0); + ASN1_STRING_set0(os, (unsigned char *)cont, contlen); + } + } + ret = 1; + err: + EVP_MD_CTX_cleanup(&ctx_tmp); + return (ret); +} + +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) +{ + EVP_MD_CTX mctx; + EVP_PKEY_CTX *pctx; + unsigned char *abuf = NULL; + int alen; + size_t siglen; + const EVP_MD *md = NULL; + + md = EVP_get_digestbyobj(si->digest_alg->algorithm); + if (md == NULL) + return 0; + + EVP_MD_CTX_init(&mctx); + if (EVP_DigestSignInit(&mctx, &pctx, md, NULL, si->pkey) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_PKCS7_SIGN, 0, si) <= 0) { + PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); + goto err; + } + + alen = ASN1_item_i2d((ASN1_VALUE *)si->auth_attr, &abuf, + ASN1_ITEM_rptr(PKCS7_ATTR_SIGN)); + if (!abuf) + goto err; + if (EVP_DigestSignUpdate(&mctx, abuf, alen) <= 0) + goto err; + OPENSSL_free(abuf); + abuf = NULL; + if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) + goto err; + abuf = OPENSSL_malloc(siglen); + if (!abuf) + goto err; + if (EVP_DigestSignFinal(&mctx, abuf, &siglen) <= 0) + goto err; + + if (EVP_PKEY_CTX_ctrl(pctx, -1, EVP_PKEY_OP_SIGN, + EVP_PKEY_CTRL_PKCS7_SIGN, 1, si) <= 0) { + PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SIGN, PKCS7_R_CTRL_ERROR); + goto err; + } + + EVP_MD_CTX_cleanup(&mctx); + + ASN1_STRING_set0(si->enc_digest, abuf, siglen); + + return 1; + + err: + if (abuf) + OPENSSL_free(abuf); + EVP_MD_CTX_cleanup(&mctx); + return 0; + +} + +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, BIO *bio, + PKCS7 *p7, PKCS7_SIGNER_INFO *si) +{ + PKCS7_ISSUER_AND_SERIAL *ias; + int ret = 0, i; + STACK_OF(X509) *cert; + X509 *x509; + + if (p7 == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + + if (p7->d.ptr == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_NO_CONTENT); + return 0; + } + + if (PKCS7_type_is_signed(p7)) { + cert = p7->d.sign->cert; + } else if (PKCS7_type_is_signedAndEnveloped(p7)) { + cert = p7->d.signed_and_enveloped->cert; + } else { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); + goto err; + } + /* XXXXXXXXXXXXXXXXXXXXXXX */ + ias = si->issuer_and_serial; + + x509 = X509_find_by_issuer_and_serial(cert, ias->issuer, ias->serial); + + /* were we able to find the cert in passed to us */ + if (x509 == NULL) { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, + PKCS7_R_UNABLE_TO_FIND_CERTIFICATE); + goto err; + } + + /* Lets verify */ + if (!X509_STORE_CTX_init(ctx, cert_store, x509, cert)) { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); + goto err; + } + X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_SMIME_SIGN); + i = X509_verify_cert(ctx); + if (i <= 0) { + PKCS7err(PKCS7_F_PKCS7_DATAVERIFY, ERR_R_X509_LIB); + X509_STORE_CTX_cleanup(ctx); + goto err; + } + X509_STORE_CTX_cleanup(ctx); + + return PKCS7_signatureVerify(bio, p7, si, x509); + err: + return ret; +} + +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + X509 *x509) +{ + ASN1_OCTET_STRING *os; + EVP_MD_CTX mdc_tmp, *mdc; + int ret = 0, i; + int md_type; + STACK_OF(X509_ATTRIBUTE) *sk; + BIO *btmp; + EVP_PKEY *pkey; + + EVP_MD_CTX_init(&mdc_tmp); + + if (!PKCS7_type_is_signed(p7) && !PKCS7_type_is_signedAndEnveloped(p7)) { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_WRONG_PKCS7_TYPE); + goto err; + } + + md_type = OBJ_obj2nid(si->digest_alg->algorithm); + + btmp = bio; + for (;;) { + if ((btmp == NULL) || + ((btmp = BIO_find_type(btmp, BIO_TYPE_MD)) == NULL)) { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, + PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + goto err; + } + BIO_get_md_ctx(btmp, &mdc); + if (mdc == NULL) { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + if (EVP_MD_CTX_type(mdc) == md_type) + break; + /* + * Workaround for some broken clients that put the signature OID + * instead of the digest OID in digest_alg->algorithm + */ + if (EVP_MD_pkey_type(EVP_MD_CTX_md(mdc)) == md_type) + break; + btmp = BIO_next(btmp); + } + + /* + * mdc is the digest ctx that we want, unless there are attributes, in + * which case the digest is the signed attributes + */ + if (!EVP_MD_CTX_copy_ex(&mdc_tmp, mdc)) + goto err; + + sk = si->auth_attr; + if ((sk != NULL) && (sk_X509_ATTRIBUTE_num(sk) != 0)) { + unsigned char md_dat[EVP_MAX_MD_SIZE], *abuf = NULL; + unsigned int md_len; + int alen; + ASN1_OCTET_STRING *message_digest; + + if (!EVP_DigestFinal_ex(&mdc_tmp, md_dat, &md_len)) + goto err; + message_digest = PKCS7_digest_from_attributes(sk); + if (!message_digest) { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, + PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST); + goto err; + } + if ((message_digest->length != (int)md_len) || + (memcmp(message_digest->data, md_dat, md_len))) { +#if 0 + { + int ii; + for (ii = 0; ii < message_digest->length; ii++) + printf("%02X", message_digest->data[ii]); + printf(" sent\n"); + for (ii = 0; ii < md_len; ii++) + printf("%02X", md_dat[ii]); + printf(" calc\n"); + } +#endif + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_DIGEST_FAILURE); + ret = -1; + goto err; + } + + if (!EVP_VerifyInit_ex(&mdc_tmp, EVP_get_digestbynid(md_type), NULL)) + goto err; + + alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf, + ASN1_ITEM_rptr(PKCS7_ATTR_VERIFY)); + if (alen <= 0) { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, ERR_R_ASN1_LIB); + ret = -1; + goto err; + } + if (!EVP_VerifyUpdate(&mdc_tmp, abuf, alen)) + goto err; + + OPENSSL_free(abuf); + } + + os = si->enc_digest; + pkey = X509_get_pubkey(x509); + if (!pkey) { + ret = -1; + goto err; + } + + i = EVP_VerifyFinal(&mdc_tmp, os->data, os->length, pkey); + EVP_PKEY_free(pkey); + if (i <= 0) { + PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE); + ret = -1; + goto err; + } else + ret = 1; + err: + EVP_MD_CTX_cleanup(&mdc_tmp); + return (ret); +} + +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx) +{ + STACK_OF(PKCS7_RECIP_INFO) *rsk; + PKCS7_RECIP_INFO *ri; + int i; + + i = OBJ_obj2nid(p7->type); + if (i != NID_pkcs7_signedAndEnveloped) + return NULL; + if (p7->d.signed_and_enveloped == NULL) + return NULL; + rsk = p7->d.signed_and_enveloped->recipientinfo; + if (rsk == NULL) + return NULL; + if (sk_PKCS7_RECIP_INFO_num(rsk) <= idx) + return (NULL); + ri = sk_PKCS7_RECIP_INFO_value(rsk, idx); + return (ri->issuer_and_serial); +} + +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid) +{ + return (get_attribute(si->auth_attr, nid)); +} + +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid) +{ + return (get_attribute(si->unauth_attr, nid)); +} + +static ASN1_TYPE *get_attribute(STACK_OF(X509_ATTRIBUTE) *sk, int nid) +{ + int i; + X509_ATTRIBUTE *xa; + ASN1_OBJECT *o; + + o = OBJ_nid2obj(nid); + if (!o || !sk) + return (NULL); + for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { + xa = sk_X509_ATTRIBUTE_value(sk, i); + if (OBJ_cmp(xa->object, o) == 0) { + if (!xa->single && sk_ASN1_TYPE_num(xa->value.set)) + return (sk_ASN1_TYPE_value(xa->value.set, 0)); + else + return (NULL); + } + } + return (NULL); +} + +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk) +{ + ASN1_TYPE *astype; + if (!(astype = get_attribute(sk, NID_pkcs9_messageDigest))) + return NULL; + return astype->value.octet_string; +} + +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk) +{ + int i; + + if (p7si->auth_attr != NULL) + sk_X509_ATTRIBUTE_pop_free(p7si->auth_attr, X509_ATTRIBUTE_free); + p7si->auth_attr = sk_X509_ATTRIBUTE_dup(sk); + if (p7si->auth_attr == NULL) + return 0; + for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { + if ((sk_X509_ATTRIBUTE_set(p7si->auth_attr, i, + X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value + (sk, i)))) + == NULL) + return (0); + } + return (1); +} + +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk) +{ + int i; + + if (p7si->unauth_attr != NULL) + sk_X509_ATTRIBUTE_pop_free(p7si->unauth_attr, X509_ATTRIBUTE_free); + p7si->unauth_attr = sk_X509_ATTRIBUTE_dup(sk); + if (p7si->unauth_attr == NULL) + return 0; + for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { + if ((sk_X509_ATTRIBUTE_set(p7si->unauth_attr, i, + X509_ATTRIBUTE_dup(sk_X509_ATTRIBUTE_value + (sk, i)))) + == NULL) + return (0); + } + return (1); +} + +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value) +{ + return (add_attribute(&(p7si->auth_attr), nid, atrtype, value)); +} + +int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value) +{ + return (add_attribute(&(p7si->unauth_attr), nid, atrtype, value)); +} + +static int add_attribute(STACK_OF(X509_ATTRIBUTE) **sk, int nid, int atrtype, + void *value) +{ + X509_ATTRIBUTE *attr = NULL; + + if (*sk == NULL) { + *sk = sk_X509_ATTRIBUTE_new_null(); + if (*sk == NULL) + return 0; + new_attrib: + if (!(attr = X509_ATTRIBUTE_create(nid, atrtype, value))) + return 0; + if (!sk_X509_ATTRIBUTE_push(*sk, attr)) { + X509_ATTRIBUTE_free(attr); + return 0; + } + } else { + int i; + + for (i = 0; i < sk_X509_ATTRIBUTE_num(*sk); i++) { + attr = sk_X509_ATTRIBUTE_value(*sk, i); + if (OBJ_obj2nid(attr->object) == nid) { + X509_ATTRIBUTE_free(attr); + attr = X509_ATTRIBUTE_create(nid, atrtype, value); + if (attr == NULL) + return 0; + if (!sk_X509_ATTRIBUTE_set(*sk, i, attr)) { + X509_ATTRIBUTE_free(attr); + return 0; + } + goto end; + } + } + goto new_attrib; + } + end: + return (1); +} diff --git a/libs/openssl/crypto/pkcs7/pk7_enc.c b/libs/openssl/crypto/pkcs7/pk7_enc.c new file mode 100644 index 00000000..6983e014 --- /dev/null +++ b/libs/openssl/crypto/pkcs7/pk7_enc.c @@ -0,0 +1,75 @@ +/* crypto/pkcs7/pk7_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include + +PKCS7_in_bio(PKCS7 *p7, BIO *in); +PKCS7_out_bio(PKCS7 *p7, BIO *out); + +PKCS7_add_signer(PKCS7 *p7, X509 *cert, EVP_PKEY *key); +PKCS7_cipher(PKCS7 *p7, EVP_CIPHER *cipher); + +PKCS7_Init(PKCS7 *p7); +PKCS7_Update(PKCS7 *p7); +PKCS7_Finish(PKCS7 *p7); diff --git a/libs/openssl/crypto/pkcs7/pk7_lib.c b/libs/openssl/crypto/pkcs7/pk7_lib.c new file mode 100644 index 00000000..0c5fcaa6 --- /dev/null +++ b/libs/openssl/crypto/pkcs7/pk7_lib.c @@ -0,0 +1,646 @@ +/* crypto/pkcs7/pk7_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include "asn1_locl.h" + +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg) +{ + int nid; + long ret; + + nid = OBJ_obj2nid(p7->type); + + switch (cmd) { + /* NOTE(emilia): does not support detached digested data. */ + case PKCS7_OP_SET_DETACHED_SIGNATURE: + if (nid == NID_pkcs7_signed) { + ret = p7->detached = (int)larg; + if (ret && PKCS7_type_is_data(p7->d.sign->contents)) { + ASN1_OCTET_STRING *os; + os = p7->d.sign->contents->d.data; + ASN1_OCTET_STRING_free(os); + p7->d.sign->contents->d.data = NULL; + } + } else { + PKCS7err(PKCS7_F_PKCS7_CTRL, + PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); + ret = 0; + } + break; + case PKCS7_OP_GET_DETACHED_SIGNATURE: + if (nid == NID_pkcs7_signed) { + if (!p7->d.sign || !p7->d.sign->contents->d.ptr) + ret = 1; + else + ret = 0; + + p7->detached = ret; + } else { + PKCS7err(PKCS7_F_PKCS7_CTRL, + PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE); + ret = 0; + } + + break; + default: + PKCS7err(PKCS7_F_PKCS7_CTRL, PKCS7_R_UNKNOWN_OPERATION); + ret = 0; + } + return (ret); +} + +int PKCS7_content_new(PKCS7 *p7, int type) +{ + PKCS7 *ret = NULL; + + if ((ret = PKCS7_new()) == NULL) + goto err; + if (!PKCS7_set_type(ret, type)) + goto err; + if (!PKCS7_set_content(p7, ret)) + goto err; + + return (1); + err: + if (ret != NULL) + PKCS7_free(ret); + return (0); +} + +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data) +{ + int i; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signed: + if (p7->d.sign->contents != NULL) + PKCS7_free(p7->d.sign->contents); + p7->d.sign->contents = p7_data; + break; + case NID_pkcs7_digest: + if (p7->d.digest->contents != NULL) + PKCS7_free(p7->d.digest->contents); + p7->d.digest->contents = p7_data; + break; + case NID_pkcs7_data: + case NID_pkcs7_enveloped: + case NID_pkcs7_signedAndEnveloped: + case NID_pkcs7_encrypted: + default: + PKCS7err(PKCS7_F_PKCS7_SET_CONTENT, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + return (1); + err: + return (0); +} + +int PKCS7_set_type(PKCS7 *p7, int type) +{ + ASN1_OBJECT *obj; + + /* + * PKCS7_content_free(p7); + */ + obj = OBJ_nid2obj(type); /* will not fail */ + + switch (type) { + case NID_pkcs7_signed: + p7->type = obj; + if ((p7->d.sign = PKCS7_SIGNED_new()) == NULL) + goto err; + if (!ASN1_INTEGER_set(p7->d.sign->version, 1)) { + PKCS7_SIGNED_free(p7->d.sign); + p7->d.sign = NULL; + goto err; + } + break; + case NID_pkcs7_data: + p7->type = obj; + if ((p7->d.data = M_ASN1_OCTET_STRING_new()) == NULL) + goto err; + break; + case NID_pkcs7_signedAndEnveloped: + p7->type = obj; + if ((p7->d.signed_and_enveloped = PKCS7_SIGN_ENVELOPE_new()) + == NULL) + goto err; + ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1); + if (!ASN1_INTEGER_set(p7->d.signed_and_enveloped->version, 1)) + goto err; + p7->d.signed_and_enveloped->enc_data->content_type + = OBJ_nid2obj(NID_pkcs7_data); + break; + case NID_pkcs7_enveloped: + p7->type = obj; + if ((p7->d.enveloped = PKCS7_ENVELOPE_new()) + == NULL) + goto err; + if (!ASN1_INTEGER_set(p7->d.enveloped->version, 0)) + goto err; + p7->d.enveloped->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data); + break; + case NID_pkcs7_encrypted: + p7->type = obj; + if ((p7->d.encrypted = PKCS7_ENCRYPT_new()) + == NULL) + goto err; + if (!ASN1_INTEGER_set(p7->d.encrypted->version, 0)) + goto err; + p7->d.encrypted->enc_data->content_type = OBJ_nid2obj(NID_pkcs7_data); + break; + + case NID_pkcs7_digest: + p7->type = obj; + if ((p7->d.digest = PKCS7_DIGEST_new()) + == NULL) + goto err; + if (!ASN1_INTEGER_set(p7->d.digest->version, 0)) + goto err; + break; + default: + PKCS7err(PKCS7_F_PKCS7_SET_TYPE, PKCS7_R_UNSUPPORTED_CONTENT_TYPE); + goto err; + } + return (1); + err: + return (0); +} + +int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other) +{ + p7->type = OBJ_nid2obj(type); + p7->d.other = other; + return 1; +} + +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *psi) +{ + int i, j, nid; + X509_ALGOR *alg; + STACK_OF(PKCS7_SIGNER_INFO) *signer_sk; + STACK_OF(X509_ALGOR) *md_sk; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signed: + signer_sk = p7->d.sign->signer_info; + md_sk = p7->d.sign->md_algs; + break; + case NID_pkcs7_signedAndEnveloped: + signer_sk = p7->d.signed_and_enveloped->signer_info; + md_sk = p7->d.signed_and_enveloped->md_algs; + break; + default: + PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + nid = OBJ_obj2nid(psi->digest_alg->algorithm); + + /* If the digest is not currently listed, add it */ + j = 0; + for (i = 0; i < sk_X509_ALGOR_num(md_sk); i++) { + alg = sk_X509_ALGOR_value(md_sk, i); + if (OBJ_obj2nid(alg->algorithm) == nid) { + j = 1; + break; + } + } + if (!j) { /* we need to add another algorithm */ + if (!(alg = X509_ALGOR_new()) + || !(alg->parameter = ASN1_TYPE_new())) { + X509_ALGOR_free(alg); + PKCS7err(PKCS7_F_PKCS7_ADD_SIGNER, ERR_R_MALLOC_FAILURE); + return (0); + } + alg->algorithm = OBJ_nid2obj(nid); + alg->parameter->type = V_ASN1_NULL; + if (!sk_X509_ALGOR_push(md_sk, alg)) { + X509_ALGOR_free(alg); + return 0; + } + } + + if (!sk_PKCS7_SIGNER_INFO_push(signer_sk, psi)) + return 0; + return (1); +} + +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509) +{ + int i; + STACK_OF(X509) **sk; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signed: + sk = &(p7->d.sign->cert); + break; + case NID_pkcs7_signedAndEnveloped: + sk = &(p7->d.signed_and_enveloped->cert); + break; + default: + PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + if (*sk == NULL) + *sk = sk_X509_new_null(); + if (*sk == NULL) { + PKCS7err(PKCS7_F_PKCS7_ADD_CERTIFICATE, ERR_R_MALLOC_FAILURE); + return 0; + } + CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); + if (!sk_X509_push(*sk, x509)) { + X509_free(x509); + return 0; + } + return (1); +} + +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl) +{ + int i; + STACK_OF(X509_CRL) **sk; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signed: + sk = &(p7->d.sign->crl); + break; + case NID_pkcs7_signedAndEnveloped: + sk = &(p7->d.signed_and_enveloped->crl); + break; + default: + PKCS7err(PKCS7_F_PKCS7_ADD_CRL, PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + if (*sk == NULL) + *sk = sk_X509_CRL_new_null(); + if (*sk == NULL) { + PKCS7err(PKCS7_F_PKCS7_ADD_CRL, ERR_R_MALLOC_FAILURE); + return 0; + } + + CRYPTO_add(&crl->references, 1, CRYPTO_LOCK_X509_CRL); + if (!sk_X509_CRL_push(*sk, crl)) { + X509_CRL_free(crl); + return 0; + } + return (1); +} + +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst) +{ + int ret; + + /* We now need to add another PKCS7_SIGNER_INFO entry */ + if (!ASN1_INTEGER_set(p7i->version, 1)) + goto err; + if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, + X509_get_issuer_name(x509))) + goto err; + + /* + * because ASN1_INTEGER_set is used to set a 'long' we will do things the + * ugly way. + */ + M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial); + if (!(p7i->issuer_and_serial->serial = + M_ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) + goto err; + + /* lets keep the pkey around for a while */ + CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + p7i->pkey = pkey; + + /* Set the algorithms */ + + X509_ALGOR_set0(p7i->digest_alg, OBJ_nid2obj(EVP_MD_type(dgst)), + V_ASN1_NULL, NULL); + + if (pkey->ameth && pkey->ameth->pkey_ctrl) { + ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_SIGN, 0, p7i); + if (ret > 0) + return 1; + if (ret != -2) { + PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, + PKCS7_R_SIGNING_CTRL_FAILURE); + return 0; + } + } + PKCS7err(PKCS7_F_PKCS7_SIGNER_INFO_SET, + PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + err: + return 0; +} + +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst) +{ + PKCS7_SIGNER_INFO *si = NULL; + + if (dgst == NULL) { + int def_nid; + if (EVP_PKEY_get_default_digest_nid(pkey, &def_nid) <= 0) + goto err; + dgst = EVP_get_digestbynid(def_nid); + if (dgst == NULL) { + PKCS7err(PKCS7_F_PKCS7_ADD_SIGNATURE, PKCS7_R_NO_DEFAULT_DIGEST); + goto err; + } + } + + if ((si = PKCS7_SIGNER_INFO_new()) == NULL) + goto err; + if (!PKCS7_SIGNER_INFO_set(si, x509, pkey, dgst)) + goto err; + if (!PKCS7_add_signer(p7, si)) + goto err; + return (si); + err: + if (si) + PKCS7_SIGNER_INFO_free(si); + return (NULL); +} + +int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md) +{ + if (PKCS7_type_is_digest(p7)) { + if (!(p7->d.digest->md->parameter = ASN1_TYPE_new())) { + PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + p7->d.digest->md->parameter->type = V_ASN1_NULL; + p7->d.digest->md->algorithm = OBJ_nid2obj(EVP_MD_nid(md)); + return 1; + } + + PKCS7err(PKCS7_F_PKCS7_SET_DIGEST, PKCS7_R_WRONG_CONTENT_TYPE); + return 1; +} + +STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7) +{ + if (p7 == NULL || p7->d.ptr == NULL) + return NULL; + if (PKCS7_type_is_signed(p7)) { + return (p7->d.sign->signer_info); + } else if (PKCS7_type_is_signedAndEnveloped(p7)) { + return (p7->d.signed_and_enveloped->signer_info); + } else + return (NULL); +} + +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig) +{ + if (pk) + *pk = si->pkey; + if (pdig) + *pdig = si->digest_alg; + if (psig) + *psig = si->digest_enc_alg; +} + +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc) +{ + if (penc) + *penc = ri->key_enc_algor; +} + +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509) +{ + PKCS7_RECIP_INFO *ri; + + if ((ri = PKCS7_RECIP_INFO_new()) == NULL) + goto err; + if (!PKCS7_RECIP_INFO_set(ri, x509)) + goto err; + if (!PKCS7_add_recipient_info(p7, ri)) + goto err; + return ri; + err: + if (ri) + PKCS7_RECIP_INFO_free(ri); + return NULL; +} + +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri) +{ + int i; + STACK_OF(PKCS7_RECIP_INFO) *sk; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signedAndEnveloped: + sk = p7->d.signed_and_enveloped->recipientinfo; + break; + case NID_pkcs7_enveloped: + sk = p7->d.enveloped->recipientinfo; + break; + default: + PKCS7err(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO, + PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + if (!sk_PKCS7_RECIP_INFO_push(sk, ri)) + return 0; + return (1); +} + +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509) +{ + int ret; + EVP_PKEY *pkey = NULL; + if (!ASN1_INTEGER_set(p7i->version, 0)) + return 0; + if (!X509_NAME_set(&p7i->issuer_and_serial->issuer, + X509_get_issuer_name(x509))) + return 0; + + M_ASN1_INTEGER_free(p7i->issuer_and_serial->serial); + if (!(p7i->issuer_and_serial->serial = + M_ASN1_INTEGER_dup(X509_get_serialNumber(x509)))) + return 0; + + pkey = X509_get_pubkey(x509); + + if (!pkey || !pkey->ameth || !pkey->ameth->pkey_ctrl) { + PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, + PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; + } + + ret = pkey->ameth->pkey_ctrl(pkey, ASN1_PKEY_CTRL_PKCS7_ENCRYPT, 0, p7i); + if (ret == -2) { + PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, + PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE); + goto err; + } + if (ret <= 0) { + PKCS7err(PKCS7_F_PKCS7_RECIP_INFO_SET, + PKCS7_R_ENCRYPTION_CTRL_FAILURE); + goto err; + } + + EVP_PKEY_free(pkey); + + CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); + p7i->cert = x509; + + return 1; + + err: + if (pkey) + EVP_PKEY_free(pkey); + return 0; +} + +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si) +{ + if (PKCS7_type_is_signed(p7)) + return (X509_find_by_issuer_and_serial(p7->d.sign->cert, + si->issuer_and_serial->issuer, + si-> + issuer_and_serial->serial)); + else + return (NULL); +} + +int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher) +{ + int i; + PKCS7_ENC_CONTENT *ec; + + i = OBJ_obj2nid(p7->type); + switch (i) { + case NID_pkcs7_signedAndEnveloped: + ec = p7->d.signed_and_enveloped->enc_data; + break; + case NID_pkcs7_enveloped: + ec = p7->d.enveloped->enc_data; + break; + default: + PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, PKCS7_R_WRONG_CONTENT_TYPE); + return (0); + } + + /* Check cipher OID exists and has data in it */ + i = EVP_CIPHER_type(cipher); + if (i == NID_undef) { + PKCS7err(PKCS7_F_PKCS7_SET_CIPHER, + PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); + return (0); + } + + ec->cipher = cipher; + return 1; +} + +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7) +{ + ASN1_OCTET_STRING *os = NULL; + + switch (OBJ_obj2nid(p7->type)) { + case NID_pkcs7_data: + os = p7->d.data; + break; + + case NID_pkcs7_signedAndEnveloped: + os = p7->d.signed_and_enveloped->enc_data->enc_data; + if (os == NULL) { + os = M_ASN1_OCTET_STRING_new(); + p7->d.signed_and_enveloped->enc_data->enc_data = os; + } + break; + + case NID_pkcs7_enveloped: + os = p7->d.enveloped->enc_data->enc_data; + if (os == NULL) { + os = M_ASN1_OCTET_STRING_new(); + p7->d.enveloped->enc_data->enc_data = os; + } + break; + + case NID_pkcs7_signed: + os = p7->d.sign->contents->d.data; + break; + + default: + os = NULL; + break; + } + + if (os == NULL) + return 0; + + os->flags |= ASN1_STRING_FLAG_NDEF; + *boundary = &os->data; + + return 1; +} diff --git a/libs/openssl/crypto/pkcs7/pk7_mime.c b/libs/openssl/crypto/pkcs7/pk7_mime.c new file mode 100644 index 00000000..62fb2997 --- /dev/null +++ b/libs/openssl/crypto/pkcs7/pk7_mime.c @@ -0,0 +1,96 @@ +/* pk7_mime.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include + +/* PKCS#7 wrappers round generalised stream and MIME routines */ + +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags) +{ + return i2d_ASN1_bio_stream(out, (ASN1_VALUE *)p7, in, flags, + ASN1_ITEM_rptr(PKCS7)); +} + +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags) +{ + return PEM_write_bio_ASN1_stream(out, (ASN1_VALUE *)p7, in, flags, + "PKCS7", ASN1_ITEM_rptr(PKCS7)); +} + +int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags) +{ + STACK_OF(X509_ALGOR) *mdalgs; + int ctype_nid = OBJ_obj2nid(p7->type); + if (ctype_nid == NID_pkcs7_signed) + mdalgs = p7->d.sign->md_algs; + else + mdalgs = NULL; + + flags ^= SMIME_OLDMIME; + + return SMIME_write_ASN1(bio, (ASN1_VALUE *)p7, data, flags, + ctype_nid, NID_undef, mdalgs, + ASN1_ITEM_rptr(PKCS7)); +} + +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont) +{ + return (PKCS7 *)SMIME_read_ASN1(bio, bcont, ASN1_ITEM_rptr(PKCS7)); +} diff --git a/libs/openssl/crypto/pkcs7/pk7_smime.c b/libs/openssl/crypto/pkcs7/pk7_smime.c new file mode 100644 index 00000000..dbd4100c --- /dev/null +++ b/libs/openssl/crypto/pkcs7/pk7_smime.c @@ -0,0 +1,586 @@ +/* pk7_smime.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* Simple PKCS#7 processing functions */ + +#include +#include "cryptlib.h" +#include +#include + +static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si); + +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags) +{ + PKCS7 *p7; + int i; + + if (!(p7 = PKCS7_new())) { + PKCS7err(PKCS7_F_PKCS7_SIGN, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!PKCS7_set_type(p7, NID_pkcs7_signed)) + goto err; + + if (!PKCS7_content_new(p7, NID_pkcs7_data)) + goto err; + + if (pkey && !PKCS7_sign_add_signer(p7, signcert, pkey, NULL, flags)) { + PKCS7err(PKCS7_F_PKCS7_SIGN, PKCS7_R_PKCS7_ADD_SIGNER_ERROR); + goto err; + } + + if (!(flags & PKCS7_NOCERTS)) { + for (i = 0; i < sk_X509_num(certs); i++) { + if (!PKCS7_add_certificate(p7, sk_X509_value(certs, i))) + goto err; + } + } + + if (flags & PKCS7_DETACHED) + PKCS7_set_detached(p7, 1); + + if (flags & (PKCS7_STREAM | PKCS7_PARTIAL)) + return p7; + + if (PKCS7_final(p7, data, flags)) + return p7; + + err: + PKCS7_free(p7); + return NULL; +} + +int PKCS7_final(PKCS7 *p7, BIO *data, int flags) +{ + BIO *p7bio; + int ret = 0; + if (!(p7bio = PKCS7_dataInit(p7, NULL))) { + PKCS7err(PKCS7_F_PKCS7_FINAL, ERR_R_MALLOC_FAILURE); + return 0; + } + + SMIME_crlf_copy(data, p7bio, flags); + + (void)BIO_flush(p7bio); + + if (!PKCS7_dataFinal(p7, p7bio)) { + PKCS7err(PKCS7_F_PKCS7_FINAL, PKCS7_R_PKCS7_DATASIGN); + goto err; + } + + ret = 1; + + err: + BIO_free_all(p7bio); + + return ret; + +} + +/* Check to see if a cipher exists and if so add S/MIME capabilities */ + +static int add_cipher_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) +{ + if (EVP_get_cipherbynid(nid)) + return PKCS7_simple_smimecap(sk, nid, arg); + return 1; +} + +static int add_digest_smcap(STACK_OF(X509_ALGOR) *sk, int nid, int arg) +{ + if (EVP_get_digestbynid(nid)) + return PKCS7_simple_smimecap(sk, nid, arg); + return 1; +} + +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, X509 *signcert, + EVP_PKEY *pkey, const EVP_MD *md, + int flags) +{ + PKCS7_SIGNER_INFO *si = NULL; + STACK_OF(X509_ALGOR) *smcap = NULL; + if (!X509_check_private_key(signcert, pkey)) { + PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, + PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + return NULL; + } + + if (!(si = PKCS7_add_signature(p7, signcert, pkey, md))) { + PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, + PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR); + return NULL; + } + + if (!(flags & PKCS7_NOCERTS)) { + if (!PKCS7_add_certificate(p7, signcert)) + goto err; + } + + if (!(flags & PKCS7_NOATTR)) { + if (!PKCS7_add_attrib_content_type(si, NULL)) + goto err; + /* Add SMIMECapabilities */ + if (!(flags & PKCS7_NOSMIMECAP)) { + if (!(smcap = sk_X509_ALGOR_new_null())) { + PKCS7err(PKCS7_F_PKCS7_SIGN_ADD_SIGNER, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!add_cipher_smcap(smcap, NID_aes_256_cbc, -1) + || !add_digest_smcap(smcap, NID_id_GostR3411_94, -1) + || !add_cipher_smcap(smcap, NID_id_Gost28147_89, -1) + || !add_cipher_smcap(smcap, NID_aes_192_cbc, -1) + || !add_cipher_smcap(smcap, NID_aes_128_cbc, -1) + || !add_cipher_smcap(smcap, NID_des_ede3_cbc, -1) + || !add_cipher_smcap(smcap, NID_rc2_cbc, 128) + || !add_cipher_smcap(smcap, NID_rc2_cbc, 64) + || !add_cipher_smcap(smcap, NID_des_cbc, -1) + || !add_cipher_smcap(smcap, NID_rc2_cbc, 40) + || !PKCS7_add_attrib_smimecap(si, smcap)) + goto err; + sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); + smcap = NULL; + } + if (flags & PKCS7_REUSE_DIGEST) { + if (!pkcs7_copy_existing_digest(p7, si)) + goto err; + if (!(flags & PKCS7_PARTIAL) && !PKCS7_SIGNER_INFO_sign(si)) + goto err; + } + } + return si; + err: + if (smcap) + sk_X509_ALGOR_pop_free(smcap, X509_ALGOR_free); + return NULL; +} + +/* + * Search for a digest matching SignerInfo digest type and if found copy + * across. + */ + +static int pkcs7_copy_existing_digest(PKCS7 *p7, PKCS7_SIGNER_INFO *si) +{ + int i; + STACK_OF(PKCS7_SIGNER_INFO) *sinfos; + PKCS7_SIGNER_INFO *sitmp; + ASN1_OCTET_STRING *osdig = NULL; + sinfos = PKCS7_get_signer_info(p7); + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { + sitmp = sk_PKCS7_SIGNER_INFO_value(sinfos, i); + if (si == sitmp) + break; + if (sk_X509_ATTRIBUTE_num(sitmp->auth_attr) <= 0) + continue; + if (!OBJ_cmp(si->digest_alg->algorithm, sitmp->digest_alg->algorithm)) { + osdig = PKCS7_digest_from_attributes(sitmp->auth_attr); + break; + } + + } + + if (osdig) + return PKCS7_add1_attrib_digest(si, osdig->data, osdig->length); + + PKCS7err(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST, + PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND); + return 0; +} + +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, + BIO *indata, BIO *out, int flags) +{ + STACK_OF(X509) *signers; + X509 *signer; + STACK_OF(PKCS7_SIGNER_INFO) *sinfos; + PKCS7_SIGNER_INFO *si; + X509_STORE_CTX cert_ctx; + char buf[4096]; + int i, j = 0, k, ret = 0; + BIO *p7bio; + BIO *tmpin, *tmpout; + + if (!p7) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + + if (!PKCS7_type_is_signed(p7)) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_WRONG_CONTENT_TYPE); + return 0; + } + + /* Check for no data and no content: no data to verify signature */ + if (PKCS7_get_detached(p7) && !indata) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_CONTENT); + return 0; + } +#if 0 + /* + * NB: this test commented out because some versions of Netscape + * illegally include zero length content when signing data. + */ + + /* Check for data and content: two sets of data */ + if (!PKCS7_get_detached(p7) && indata) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_CONTENT_AND_DATA_PRESENT); + return 0; + } +#endif + + sinfos = PKCS7_get_signer_info(p7); + + if (!sinfos || !sk_PKCS7_SIGNER_INFO_num(sinfos)) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_NO_SIGNATURES_ON_DATA); + return 0; + } + + signers = PKCS7_get0_signers(p7, certs, flags); + + if (!signers) + return 0; + + /* Now verify the certificates */ + + if (!(flags & PKCS7_NOVERIFY)) + for (k = 0; k < sk_X509_num(signers); k++) { + signer = sk_X509_value(signers, k); + if (!(flags & PKCS7_NOCHAIN)) { + if (!X509_STORE_CTX_init(&cert_ctx, store, signer, + p7->d.sign->cert)) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); + sk_X509_free(signers); + return 0; + } + X509_STORE_CTX_set_default(&cert_ctx, "smime_sign"); + } else if (!X509_STORE_CTX_init(&cert_ctx, store, signer, NULL)) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_X509_LIB); + sk_X509_free(signers); + return 0; + } + if (!(flags & PKCS7_NOCRL)) + X509_STORE_CTX_set0_crls(&cert_ctx, p7->d.sign->crl); + i = X509_verify_cert(&cert_ctx); + if (i <= 0) + j = X509_STORE_CTX_get_error(&cert_ctx); + X509_STORE_CTX_cleanup(&cert_ctx); + if (i <= 0) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, + PKCS7_R_CERTIFICATE_VERIFY_ERROR); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(j)); + sk_X509_free(signers); + return 0; + } + /* Check for revocation status here */ + } + + /* + * Performance optimization: if the content is a memory BIO then store + * its contents in a temporary read only memory BIO. This avoids + * potentially large numbers of slow copies of data which will occur when + * reading from a read write memory BIO when signatures are calculated. + */ + + if (indata && (BIO_method_type(indata) == BIO_TYPE_MEM)) { + char *ptr; + long len; + len = BIO_get_mem_data(indata, &ptr); + tmpin = BIO_new_mem_buf(ptr, len); + if (tmpin == NULL) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); + return 0; + } + } else + tmpin = indata; + + if (!(p7bio = PKCS7_dataInit(p7, tmpin))) + goto err; + + if (flags & PKCS7_TEXT) { + if (!(tmpout = BIO_new(BIO_s_mem()))) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + BIO_set_mem_eof_return(tmpout, 0); + } else + tmpout = out; + + /* We now have to 'read' from p7bio to calculate digests etc. */ + for (;;) { + i = BIO_read(p7bio, buf, sizeof(buf)); + if (i <= 0) + break; + if (tmpout) + BIO_write(tmpout, buf, i); + } + + if (flags & PKCS7_TEXT) { + if (!SMIME_text(tmpout, out)) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SMIME_TEXT_ERROR); + BIO_free(tmpout); + goto err; + } + BIO_free(tmpout); + } + + /* Now Verify All Signatures */ + if (!(flags & PKCS7_NOSIGS)) + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { + si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); + signer = sk_X509_value(signers, i); + j = PKCS7_signatureVerify(p7bio, p7, si, signer); + if (j <= 0) { + PKCS7err(PKCS7_F_PKCS7_VERIFY, PKCS7_R_SIGNATURE_FAILURE); + goto err; + } + } + + ret = 1; + + err: + + if (tmpin == indata) { + if (indata) + BIO_pop(p7bio); + } + BIO_free_all(p7bio); + + sk_X509_free(signers); + + return ret; +} + +STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, + int flags) +{ + STACK_OF(X509) *signers; + STACK_OF(PKCS7_SIGNER_INFO) *sinfos; + PKCS7_SIGNER_INFO *si; + PKCS7_ISSUER_AND_SERIAL *ias; + X509 *signer; + int i; + + if (!p7) { + PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_INVALID_NULL_POINTER); + return NULL; + } + + if (!PKCS7_type_is_signed(p7)) { + PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_WRONG_CONTENT_TYPE); + return NULL; + } + + /* Collect all the signers together */ + + sinfos = PKCS7_get_signer_info(p7); + + if (sk_PKCS7_SIGNER_INFO_num(sinfos) <= 0) { + PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, PKCS7_R_NO_SIGNERS); + return 0; + } + + if (!(signers = sk_X509_new_null())) { + PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_PKCS7_SIGNER_INFO_num(sinfos); i++) { + si = sk_PKCS7_SIGNER_INFO_value(sinfos, i); + ias = si->issuer_and_serial; + signer = NULL; + /* If any certificates passed they take priority */ + if (certs) + signer = X509_find_by_issuer_and_serial(certs, + ias->issuer, ias->serial); + if (!signer && !(flags & PKCS7_NOINTERN) + && p7->d.sign->cert) + signer = + X509_find_by_issuer_and_serial(p7->d.sign->cert, + ias->issuer, ias->serial); + if (!signer) { + PKCS7err(PKCS7_F_PKCS7_GET0_SIGNERS, + PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND); + sk_X509_free(signers); + return 0; + } + + if (!sk_X509_push(signers, signer)) { + sk_X509_free(signers); + return NULL; + } + } + return signers; +} + +/* Build a complete PKCS#7 enveloped data */ + +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags) +{ + PKCS7 *p7; + BIO *p7bio = NULL; + int i; + X509 *x509; + if (!(p7 = PKCS7_new())) { + PKCS7err(PKCS7_F_PKCS7_ENCRYPT, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!PKCS7_set_type(p7, NID_pkcs7_enveloped)) + goto err; + if (!PKCS7_set_cipher(p7, cipher)) { + PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_SETTING_CIPHER); + goto err; + } + + for (i = 0; i < sk_X509_num(certs); i++) { + x509 = sk_X509_value(certs, i); + if (!PKCS7_add_recipient(p7, x509)) { + PKCS7err(PKCS7_F_PKCS7_ENCRYPT, PKCS7_R_ERROR_ADDING_RECIPIENT); + goto err; + } + } + + if (flags & PKCS7_STREAM) + return p7; + + if (PKCS7_final(p7, in, flags)) + return p7; + + err: + + BIO_free_all(p7bio); + PKCS7_free(p7); + return NULL; + +} + +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, int flags) +{ + BIO *tmpmem; + int ret, i; + char buf[4096]; + + if (!p7) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_INVALID_NULL_POINTER); + return 0; + } + + if (!PKCS7_type_is_enveloped(p7)) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_WRONG_CONTENT_TYPE); + return 0; + } + + if (cert && !X509_check_private_key(cert, pkey)) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT, + PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + return 0; + } + + if (!(tmpmem = PKCS7_dataDecode(p7, pkey, NULL, cert))) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT, PKCS7_R_DECRYPT_ERROR); + return 0; + } + + if (flags & PKCS7_TEXT) { + BIO *tmpbuf, *bread; + /* Encrypt BIOs can't do BIO_gets() so add a buffer BIO */ + if (!(tmpbuf = BIO_new(BIO_f_buffer()))) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); + BIO_free_all(tmpmem); + return 0; + } + if (!(bread = BIO_push(tmpbuf, tmpmem))) { + PKCS7err(PKCS7_F_PKCS7_DECRYPT, ERR_R_MALLOC_FAILURE); + BIO_free_all(tmpbuf); + BIO_free_all(tmpmem); + return 0; + } + ret = SMIME_text(bread, data); + if (ret > 0 && BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) { + if (!BIO_get_cipher_status(tmpmem)) + ret = 0; + } + BIO_free_all(bread); + return ret; + } else { + for (;;) { + i = BIO_read(tmpmem, buf, sizeof(buf)); + if (i <= 0) { + ret = 1; + if (BIO_method_type(tmpmem) == BIO_TYPE_CIPHER) { + if (!BIO_get_cipher_status(tmpmem)) + ret = 0; + } + + break; + } + if (BIO_write(data, buf, i) != i) { + ret = 0; + break; + } + } + BIO_free_all(tmpmem); + return ret; + } +} diff --git a/libs/openssl/crypto/pkcs7/pkcs7.h b/libs/openssl/crypto/pkcs7/pkcs7.h new file mode 100644 index 00000000..b51b3863 --- /dev/null +++ b/libs/openssl/crypto/pkcs7/pkcs7.h @@ -0,0 +1,481 @@ +/* crypto/pkcs7/pkcs7.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_PKCS7_H +# define HEADER_PKCS7_H + +# include +# include +# include + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_SYS_WIN32 +/* Under Win32 thes are defined in wincrypt.h */ +# undef PKCS7_ISSUER_AND_SERIAL +# undef PKCS7_SIGNER_INFO +# endif + +/*- +Encryption_ID DES-CBC +Digest_ID MD5 +Digest_Encryption_ID rsaEncryption +Key_Encryption_ID rsaEncryption +*/ + +typedef struct pkcs7_issuer_and_serial_st { + X509_NAME *issuer; + ASN1_INTEGER *serial; +} PKCS7_ISSUER_AND_SERIAL; + +typedef struct pkcs7_signer_info_st { + ASN1_INTEGER *version; /* version 1 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *digest_alg; + STACK_OF(X509_ATTRIBUTE) *auth_attr; /* [ 0 ] */ + X509_ALGOR *digest_enc_alg; + ASN1_OCTET_STRING *enc_digest; + STACK_OF(X509_ATTRIBUTE) *unauth_attr; /* [ 1 ] */ + /* The private key to sign with */ + EVP_PKEY *pkey; +} PKCS7_SIGNER_INFO; + +DECLARE_STACK_OF(PKCS7_SIGNER_INFO) +DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) + +typedef struct pkcs7_recip_info_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ISSUER_AND_SERIAL *issuer_and_serial; + X509_ALGOR *key_enc_algor; + ASN1_OCTET_STRING *enc_key; + X509 *cert; /* get the pub-key from this */ +} PKCS7_RECIP_INFO; + +DECLARE_STACK_OF(PKCS7_RECIP_INFO) +DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) + +typedef struct pkcs7_signed_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + struct pkcs7_st *contents; +} PKCS7_SIGNED; +/* + * The above structure is very very similar to PKCS7_SIGN_ENVELOPE. How about + * merging the two + */ + +typedef struct pkcs7_enc_content_st { + ASN1_OBJECT *content_type; + X509_ALGOR *algorithm; + ASN1_OCTET_STRING *enc_data; /* [ 0 ] */ + const EVP_CIPHER *cipher; +} PKCS7_ENC_CONTENT; + +typedef struct pkcs7_enveloped_st { + ASN1_INTEGER *version; /* version 0 */ + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENVELOPE; + +typedef struct pkcs7_signedandenveloped_st { + ASN1_INTEGER *version; /* version 1 */ + STACK_OF(X509_ALGOR) *md_algs; /* md used */ + STACK_OF(X509) *cert; /* [ 0 ] */ + STACK_OF(X509_CRL) *crl; /* [ 1 ] */ + STACK_OF(PKCS7_SIGNER_INFO) *signer_info; + PKCS7_ENC_CONTENT *enc_data; + STACK_OF(PKCS7_RECIP_INFO) *recipientinfo; +} PKCS7_SIGN_ENVELOPE; + +typedef struct pkcs7_digest_st { + ASN1_INTEGER *version; /* version 0 */ + X509_ALGOR *md; /* md used */ + struct pkcs7_st *contents; + ASN1_OCTET_STRING *digest; +} PKCS7_DIGEST; + +typedef struct pkcs7_encrypted_st { + ASN1_INTEGER *version; /* version 0 */ + PKCS7_ENC_CONTENT *enc_data; +} PKCS7_ENCRYPT; + +typedef struct pkcs7_st { + /* + * The following is non NULL if it contains ASN1 encoding of this + * structure + */ + unsigned char *asn1; + long length; +# define PKCS7_S_HEADER 0 +# define PKCS7_S_BODY 1 +# define PKCS7_S_TAIL 2 + int state; /* used during processing */ + int detached; + ASN1_OBJECT *type; + /* content as defined by the type */ + /* + * all encryption/message digests are applied to the 'contents', leaving + * out the 'type' field. + */ + union { + char *ptr; + /* NID_pkcs7_data */ + ASN1_OCTET_STRING *data; + /* NID_pkcs7_signed */ + PKCS7_SIGNED *sign; + /* NID_pkcs7_enveloped */ + PKCS7_ENVELOPE *enveloped; + /* NID_pkcs7_signedAndEnveloped */ + PKCS7_SIGN_ENVELOPE *signed_and_enveloped; + /* NID_pkcs7_digest */ + PKCS7_DIGEST *digest; + /* NID_pkcs7_encrypted */ + PKCS7_ENCRYPT *encrypted; + /* Anything else */ + ASN1_TYPE *other; + } d; +} PKCS7; + +DECLARE_STACK_OF(PKCS7) +DECLARE_ASN1_SET_OF(PKCS7) +DECLARE_PKCS12_STACK_OF(PKCS7) + +# define PKCS7_OP_SET_DETACHED_SIGNATURE 1 +# define PKCS7_OP_GET_DETACHED_SIGNATURE 2 + +# define PKCS7_get_signed_attributes(si) ((si)->auth_attr) +# define PKCS7_get_attributes(si) ((si)->unauth_attr) + +# define PKCS7_type_is_signed(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_signed) +# define PKCS7_type_is_encrypted(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_encrypted) +# define PKCS7_type_is_enveloped(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_enveloped) +# define PKCS7_type_is_signedAndEnveloped(a) \ + (OBJ_obj2nid((a)->type) == NID_pkcs7_signedAndEnveloped) +# define PKCS7_type_is_data(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_data) +# define PKCS7_type_is_digest(a) (OBJ_obj2nid((a)->type) == NID_pkcs7_digest) + +# define PKCS7_set_detached(p,v) \ + PKCS7_ctrl(p,PKCS7_OP_SET_DETACHED_SIGNATURE,v,NULL) +# define PKCS7_get_detached(p) \ + PKCS7_ctrl(p,PKCS7_OP_GET_DETACHED_SIGNATURE,0,NULL) + +# define PKCS7_is_detached(p7) (PKCS7_type_is_signed(p7) && PKCS7_get_detached(p7)) + +/* S/MIME related flags */ + +# define PKCS7_TEXT 0x1 +# define PKCS7_NOCERTS 0x2 +# define PKCS7_NOSIGS 0x4 +# define PKCS7_NOCHAIN 0x8 +# define PKCS7_NOINTERN 0x10 +# define PKCS7_NOVERIFY 0x20 +# define PKCS7_DETACHED 0x40 +# define PKCS7_BINARY 0x80 +# define PKCS7_NOATTR 0x100 +# define PKCS7_NOSMIMECAP 0x200 +# define PKCS7_NOOLDMIMETYPE 0x400 +# define PKCS7_CRLFEOL 0x800 +# define PKCS7_STREAM 0x1000 +# define PKCS7_NOCRL 0x2000 +# define PKCS7_PARTIAL 0x4000 +# define PKCS7_REUSE_DIGEST 0x8000 + +/* Flags: for compatibility with older code */ + +# define SMIME_TEXT PKCS7_TEXT +# define SMIME_NOCERTS PKCS7_NOCERTS +# define SMIME_NOSIGS PKCS7_NOSIGS +# define SMIME_NOCHAIN PKCS7_NOCHAIN +# define SMIME_NOINTERN PKCS7_NOINTERN +# define SMIME_NOVERIFY PKCS7_NOVERIFY +# define SMIME_DETACHED PKCS7_DETACHED +# define SMIME_BINARY PKCS7_BINARY +# define SMIME_NOATTR PKCS7_NOATTR + +DECLARE_ASN1_FUNCTIONS(PKCS7_ISSUER_AND_SERIAL) + +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, + const EVP_MD *type, unsigned char *md, + unsigned int *len); +# ifndef OPENSSL_NO_FP_API +PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7); +int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7); +# endif +PKCS7 *PKCS7_dup(PKCS7 *p7); +PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7); +int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7); +int i2d_PKCS7_bio_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); +int PEM_write_bio_PKCS7_stream(BIO *out, PKCS7 *p7, BIO *in, int flags); + +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNER_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_RECIP_INFO) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGNED) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENC_CONTENT) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_SIGN_ENVELOPE) +DECLARE_ASN1_FUNCTIONS(PKCS7_DIGEST) +DECLARE_ASN1_FUNCTIONS(PKCS7_ENCRYPT) +DECLARE_ASN1_FUNCTIONS(PKCS7) + +DECLARE_ASN1_ITEM(PKCS7_ATTR_SIGN) +DECLARE_ASN1_ITEM(PKCS7_ATTR_VERIFY) + +DECLARE_ASN1_NDEF_FUNCTION(PKCS7) +DECLARE_ASN1_PRINT_FUNCTION(PKCS7) + +long PKCS7_ctrl(PKCS7 *p7, int cmd, long larg, char *parg); + +int PKCS7_set_type(PKCS7 *p7, int type); +int PKCS7_set0_type_other(PKCS7 *p7, int type, ASN1_TYPE *other); +int PKCS7_set_content(PKCS7 *p7, PKCS7 *p7_data); +int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey, + const EVP_MD *dgst); +int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si); +int PKCS7_add_signer(PKCS7 *p7, PKCS7_SIGNER_INFO *p7i); +int PKCS7_add_certificate(PKCS7 *p7, X509 *x509); +int PKCS7_add_crl(PKCS7 *p7, X509_CRL *x509); +int PKCS7_content_new(PKCS7 *p7, int nid); +int PKCS7_dataVerify(X509_STORE *cert_store, X509_STORE_CTX *ctx, + BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si, + X509 *x509); + +BIO *PKCS7_dataInit(PKCS7 *p7, BIO *bio); +int PKCS7_dataFinal(PKCS7 *p7, BIO *bio); +BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, BIO *in_bio, X509 *pcert); + +PKCS7_SIGNER_INFO *PKCS7_add_signature(PKCS7 *p7, X509 *x509, + EVP_PKEY *pkey, const EVP_MD *dgst); +X509 *PKCS7_cert_from_signer_info(PKCS7 *p7, PKCS7_SIGNER_INFO *si); +int PKCS7_set_digest(PKCS7 *p7, const EVP_MD *md); +STACK_OF(PKCS7_SIGNER_INFO) *PKCS7_get_signer_info(PKCS7 *p7); + +PKCS7_RECIP_INFO *PKCS7_add_recipient(PKCS7 *p7, X509 *x509); +void PKCS7_SIGNER_INFO_get0_algs(PKCS7_SIGNER_INFO *si, EVP_PKEY **pk, + X509_ALGOR **pdig, X509_ALGOR **psig); +void PKCS7_RECIP_INFO_get0_alg(PKCS7_RECIP_INFO *ri, X509_ALGOR **penc); +int PKCS7_add_recipient_info(PKCS7 *p7, PKCS7_RECIP_INFO *ri); +int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509); +int PKCS7_set_cipher(PKCS7 *p7, const EVP_CIPHER *cipher); +int PKCS7_stream(unsigned char ***boundary, PKCS7 *p7); + +PKCS7_ISSUER_AND_SERIAL *PKCS7_get_issuer_and_serial(PKCS7 *p7, int idx); +ASN1_OCTET_STRING *PKCS7_digest_from_attributes(STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_add_signed_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int type, + void *data); +int PKCS7_add_attribute(PKCS7_SIGNER_INFO *p7si, int nid, int atrtype, + void *value); +ASN1_TYPE *PKCS7_get_attribute(PKCS7_SIGNER_INFO *si, int nid); +ASN1_TYPE *PKCS7_get_signed_attribute(PKCS7_SIGNER_INFO *si, int nid); +int PKCS7_set_signed_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); +int PKCS7_set_attributes(PKCS7_SIGNER_INFO *p7si, + STACK_OF(X509_ATTRIBUTE) *sk); + +PKCS7 *PKCS7_sign(X509 *signcert, EVP_PKEY *pkey, STACK_OF(X509) *certs, + BIO *data, int flags); + +PKCS7_SIGNER_INFO *PKCS7_sign_add_signer(PKCS7 *p7, + X509 *signcert, EVP_PKEY *pkey, + const EVP_MD *md, int flags); + +int PKCS7_final(PKCS7 *p7, BIO *data, int flags); +int PKCS7_verify(PKCS7 *p7, STACK_OF(X509) *certs, X509_STORE *store, + BIO *indata, BIO *out, int flags); +STACK_OF(X509) *PKCS7_get0_signers(PKCS7 *p7, STACK_OF(X509) *certs, + int flags); +PKCS7 *PKCS7_encrypt(STACK_OF(X509) *certs, BIO *in, const EVP_CIPHER *cipher, + int flags); +int PKCS7_decrypt(PKCS7 *p7, EVP_PKEY *pkey, X509 *cert, BIO *data, + int flags); + +int PKCS7_add_attrib_smimecap(PKCS7_SIGNER_INFO *si, + STACK_OF(X509_ALGOR) *cap); +STACK_OF(X509_ALGOR) *PKCS7_get_smimecap(PKCS7_SIGNER_INFO *si); +int PKCS7_simple_smimecap(STACK_OF(X509_ALGOR) *sk, int nid, int arg); + +int PKCS7_add_attrib_content_type(PKCS7_SIGNER_INFO *si, ASN1_OBJECT *coid); +int PKCS7_add0_attrib_signing_time(PKCS7_SIGNER_INFO *si, ASN1_TIME *t); +int PKCS7_add1_attrib_digest(PKCS7_SIGNER_INFO *si, + const unsigned char *md, int mdlen); + +int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags); +PKCS7 *SMIME_read_PKCS7(BIO *bio, BIO **bcont); + +BIO *BIO_new_PKCS7(BIO *out, PKCS7 *p7); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_PKCS7_strings(void); + +/* Error codes for the PKCS7 functions. */ + +/* Function codes. */ +# define PKCS7_F_B64_READ_PKCS7 120 +# define PKCS7_F_B64_WRITE_PKCS7 121 +# define PKCS7_F_DO_PKCS7_SIGNED_ATTRIB 136 +# define PKCS7_F_I2D_PKCS7_BIO_STREAM 140 +# define PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME 135 +# define PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP 118 +# define PKCS7_F_PKCS7_ADD_CERTIFICATE 100 +# define PKCS7_F_PKCS7_ADD_CRL 101 +# define PKCS7_F_PKCS7_ADD_RECIPIENT_INFO 102 +# define PKCS7_F_PKCS7_ADD_SIGNATURE 131 +# define PKCS7_F_PKCS7_ADD_SIGNER 103 +# define PKCS7_F_PKCS7_BIO_ADD_DIGEST 125 +# define PKCS7_F_PKCS7_COPY_EXISTING_DIGEST 138 +# define PKCS7_F_PKCS7_CTRL 104 +# define PKCS7_F_PKCS7_DATADECODE 112 +# define PKCS7_F_PKCS7_DATAFINAL 128 +# define PKCS7_F_PKCS7_DATAINIT 105 +# define PKCS7_F_PKCS7_DATASIGN 106 +# define PKCS7_F_PKCS7_DATAVERIFY 107 +# define PKCS7_F_PKCS7_DECRYPT 114 +# define PKCS7_F_PKCS7_DECRYPT_RINFO 133 +# define PKCS7_F_PKCS7_ENCODE_RINFO 132 +# define PKCS7_F_PKCS7_ENCRYPT 115 +# define PKCS7_F_PKCS7_FINAL 134 +# define PKCS7_F_PKCS7_FIND_DIGEST 127 +# define PKCS7_F_PKCS7_GET0_SIGNERS 124 +# define PKCS7_F_PKCS7_RECIP_INFO_SET 130 +# define PKCS7_F_PKCS7_SET_CIPHER 108 +# define PKCS7_F_PKCS7_SET_CONTENT 109 +# define PKCS7_F_PKCS7_SET_DIGEST 126 +# define PKCS7_F_PKCS7_SET_TYPE 110 +# define PKCS7_F_PKCS7_SIGN 116 +# define PKCS7_F_PKCS7_SIGNATUREVERIFY 113 +# define PKCS7_F_PKCS7_SIGNER_INFO_SET 129 +# define PKCS7_F_PKCS7_SIGNER_INFO_SIGN 139 +# define PKCS7_F_PKCS7_SIGN_ADD_SIGNER 137 +# define PKCS7_F_PKCS7_SIMPLE_SMIMECAP 119 +# define PKCS7_F_PKCS7_VERIFY 117 +# define PKCS7_F_SMIME_READ_PKCS7 122 +# define PKCS7_F_SMIME_TEXT 123 + +/* Reason codes. */ +# define PKCS7_R_CERTIFICATE_VERIFY_ERROR 117 +# define PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 144 +# define PKCS7_R_CIPHER_NOT_INITIALIZED 116 +# define PKCS7_R_CONTENT_AND_DATA_PRESENT 118 +# define PKCS7_R_CTRL_ERROR 152 +# define PKCS7_R_DECODE_ERROR 130 +# define PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH 100 +# define PKCS7_R_DECRYPT_ERROR 119 +# define PKCS7_R_DIGEST_FAILURE 101 +# define PKCS7_R_ENCRYPTION_CTRL_FAILURE 149 +# define PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 150 +# define PKCS7_R_ERROR_ADDING_RECIPIENT 120 +# define PKCS7_R_ERROR_SETTING_CIPHER 121 +# define PKCS7_R_INVALID_MIME_TYPE 131 +# define PKCS7_R_INVALID_NULL_POINTER 143 +# define PKCS7_R_INVALID_SIGNED_DATA_TYPE 155 +# define PKCS7_R_MIME_NO_CONTENT_TYPE 132 +# define PKCS7_R_MIME_PARSE_ERROR 133 +# define PKCS7_R_MIME_SIG_PARSE_ERROR 134 +# define PKCS7_R_MISSING_CERIPEND_INFO 103 +# define PKCS7_R_NO_CONTENT 122 +# define PKCS7_R_NO_CONTENT_TYPE 135 +# define PKCS7_R_NO_DEFAULT_DIGEST 151 +# define PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND 154 +# define PKCS7_R_NO_MULTIPART_BODY_FAILURE 136 +# define PKCS7_R_NO_MULTIPART_BOUNDARY 137 +# define PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE 115 +# define PKCS7_R_NO_RECIPIENT_MATCHES_KEY 146 +# define PKCS7_R_NO_SIGNATURES_ON_DATA 123 +# define PKCS7_R_NO_SIGNERS 142 +# define PKCS7_R_NO_SIG_CONTENT_TYPE 138 +# define PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE 104 +# define PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR 124 +# define PKCS7_R_PKCS7_ADD_SIGNER_ERROR 153 +# define PKCS7_R_PKCS7_DATAFINAL 126 +# define PKCS7_R_PKCS7_DATAFINAL_ERROR 125 +# define PKCS7_R_PKCS7_DATASIGN 145 +# define PKCS7_R_PKCS7_PARSE_ERROR 139 +# define PKCS7_R_PKCS7_SIG_PARSE_ERROR 140 +# define PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 127 +# define PKCS7_R_SIGNATURE_FAILURE 105 +# define PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND 128 +# define PKCS7_R_SIGNING_CTRL_FAILURE 147 +# define PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE 148 +# define PKCS7_R_SIG_INVALID_MIME_TYPE 141 +# define PKCS7_R_SMIME_TEXT_ERROR 129 +# define PKCS7_R_UNABLE_TO_FIND_CERTIFICATE 106 +# define PKCS7_R_UNABLE_TO_FIND_MEM_BIO 107 +# define PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST 108 +# define PKCS7_R_UNKNOWN_DIGEST_TYPE 109 +# define PKCS7_R_UNKNOWN_OPERATION 110 +# define PKCS7_R_UNSUPPORTED_CIPHER_TYPE 111 +# define PKCS7_R_UNSUPPORTED_CONTENT_TYPE 112 +# define PKCS7_R_WRONG_CONTENT_TYPE 113 +# define PKCS7_R_WRONG_PKCS7_TYPE 114 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/pkcs7/pkcs7err.c b/libs/openssl/crypto/pkcs7/pkcs7err.c new file mode 100644 index 00000000..323513fe --- /dev/null +++ b/libs/openssl/crypto/pkcs7/pkcs7err.c @@ -0,0 +1,207 @@ +/* crypto/pkcs7/pkcs7err.c */ +/* ==================================================================== + * Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_PKCS7,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_PKCS7,0,reason) + +static ERR_STRING_DATA PKCS7_str_functs[] = { + {ERR_FUNC(PKCS7_F_B64_READ_PKCS7), "B64_READ_PKCS7"}, + {ERR_FUNC(PKCS7_F_B64_WRITE_PKCS7), "B64_WRITE_PKCS7"}, + {ERR_FUNC(PKCS7_F_DO_PKCS7_SIGNED_ATTRIB), "DO_PKCS7_SIGNED_ATTRIB"}, + {ERR_FUNC(PKCS7_F_I2D_PKCS7_BIO_STREAM), "i2d_PKCS7_bio_stream"}, + {ERR_FUNC(PKCS7_F_PKCS7_ADD0_ATTRIB_SIGNING_TIME), + "PKCS7_add0_attrib_signing_time"}, + {ERR_FUNC(PKCS7_F_PKCS7_ADD_ATTRIB_SMIMECAP), + "PKCS7_add_attrib_smimecap"}, + {ERR_FUNC(PKCS7_F_PKCS7_ADD_CERTIFICATE), "PKCS7_add_certificate"}, + {ERR_FUNC(PKCS7_F_PKCS7_ADD_CRL), "PKCS7_add_crl"}, + {ERR_FUNC(PKCS7_F_PKCS7_ADD_RECIPIENT_INFO), "PKCS7_add_recipient_info"}, + {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNATURE), "PKCS7_add_signature"}, + {ERR_FUNC(PKCS7_F_PKCS7_ADD_SIGNER), "PKCS7_add_signer"}, + {ERR_FUNC(PKCS7_F_PKCS7_BIO_ADD_DIGEST), "PKCS7_BIO_ADD_DIGEST"}, + {ERR_FUNC(PKCS7_F_PKCS7_COPY_EXISTING_DIGEST), + "PKCS7_COPY_EXISTING_DIGEST"}, + {ERR_FUNC(PKCS7_F_PKCS7_CTRL), "PKCS7_ctrl"}, + {ERR_FUNC(PKCS7_F_PKCS7_DATADECODE), "PKCS7_dataDecode"}, + {ERR_FUNC(PKCS7_F_PKCS7_DATAFINAL), "PKCS7_dataFinal"}, + {ERR_FUNC(PKCS7_F_PKCS7_DATAINIT), "PKCS7_dataInit"}, + {ERR_FUNC(PKCS7_F_PKCS7_DATASIGN), "PKCS7_DATASIGN"}, + {ERR_FUNC(PKCS7_F_PKCS7_DATAVERIFY), "PKCS7_dataVerify"}, + {ERR_FUNC(PKCS7_F_PKCS7_DECRYPT), "PKCS7_decrypt"}, + {ERR_FUNC(PKCS7_F_PKCS7_DECRYPT_RINFO), "PKCS7_DECRYPT_RINFO"}, + {ERR_FUNC(PKCS7_F_PKCS7_ENCODE_RINFO), "PKCS7_ENCODE_RINFO"}, + {ERR_FUNC(PKCS7_F_PKCS7_ENCRYPT), "PKCS7_encrypt"}, + {ERR_FUNC(PKCS7_F_PKCS7_FINAL), "PKCS7_final"}, + {ERR_FUNC(PKCS7_F_PKCS7_FIND_DIGEST), "PKCS7_FIND_DIGEST"}, + {ERR_FUNC(PKCS7_F_PKCS7_GET0_SIGNERS), "PKCS7_get0_signers"}, + {ERR_FUNC(PKCS7_F_PKCS7_RECIP_INFO_SET), "PKCS7_RECIP_INFO_set"}, + {ERR_FUNC(PKCS7_F_PKCS7_SET_CIPHER), "PKCS7_set_cipher"}, + {ERR_FUNC(PKCS7_F_PKCS7_SET_CONTENT), "PKCS7_set_content"}, + {ERR_FUNC(PKCS7_F_PKCS7_SET_DIGEST), "PKCS7_set_digest"}, + {ERR_FUNC(PKCS7_F_PKCS7_SET_TYPE), "PKCS7_set_type"}, + {ERR_FUNC(PKCS7_F_PKCS7_SIGN), "PKCS7_sign"}, + {ERR_FUNC(PKCS7_F_PKCS7_SIGNATUREVERIFY), "PKCS7_signatureVerify"}, + {ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SET), "PKCS7_SIGNER_INFO_set"}, + {ERR_FUNC(PKCS7_F_PKCS7_SIGNER_INFO_SIGN), "PKCS7_SIGNER_INFO_sign"}, + {ERR_FUNC(PKCS7_F_PKCS7_SIGN_ADD_SIGNER), "PKCS7_sign_add_signer"}, + {ERR_FUNC(PKCS7_F_PKCS7_SIMPLE_SMIMECAP), "PKCS7_simple_smimecap"}, + {ERR_FUNC(PKCS7_F_PKCS7_VERIFY), "PKCS7_verify"}, + {ERR_FUNC(PKCS7_F_SMIME_READ_PKCS7), "SMIME_read_PKCS7"}, + {ERR_FUNC(PKCS7_F_SMIME_TEXT), "SMIME_text"}, + {0, NULL} +}; + +static ERR_STRING_DATA PKCS7_str_reasons[] = { + {ERR_REASON(PKCS7_R_CERTIFICATE_VERIFY_ERROR), + "certificate verify error"}, + {ERR_REASON(PKCS7_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER), + "cipher has no object identifier"}, + {ERR_REASON(PKCS7_R_CIPHER_NOT_INITIALIZED), "cipher not initialized"}, + {ERR_REASON(PKCS7_R_CONTENT_AND_DATA_PRESENT), + "content and data present"}, + {ERR_REASON(PKCS7_R_CTRL_ERROR), "ctrl error"}, + {ERR_REASON(PKCS7_R_DECODE_ERROR), "decode error"}, + {ERR_REASON(PKCS7_R_DECRYPTED_KEY_IS_WRONG_LENGTH), + "decrypted key is wrong length"}, + {ERR_REASON(PKCS7_R_DECRYPT_ERROR), "decrypt error"}, + {ERR_REASON(PKCS7_R_DIGEST_FAILURE), "digest failure"}, + {ERR_REASON(PKCS7_R_ENCRYPTION_CTRL_FAILURE), "encryption ctrl failure"}, + {ERR_REASON(PKCS7_R_ENCRYPTION_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), + "encryption not supported for this key type"}, + {ERR_REASON(PKCS7_R_ERROR_ADDING_RECIPIENT), "error adding recipient"}, + {ERR_REASON(PKCS7_R_ERROR_SETTING_CIPHER), "error setting cipher"}, + {ERR_REASON(PKCS7_R_INVALID_MIME_TYPE), "invalid mime type"}, + {ERR_REASON(PKCS7_R_INVALID_NULL_POINTER), "invalid null pointer"}, + {ERR_REASON(PKCS7_R_INVALID_SIGNED_DATA_TYPE), + "invalid signed data type"}, + {ERR_REASON(PKCS7_R_MIME_NO_CONTENT_TYPE), "mime no content type"}, + {ERR_REASON(PKCS7_R_MIME_PARSE_ERROR), "mime parse error"}, + {ERR_REASON(PKCS7_R_MIME_SIG_PARSE_ERROR), "mime sig parse error"}, + {ERR_REASON(PKCS7_R_MISSING_CERIPEND_INFO), "missing ceripend info"}, + {ERR_REASON(PKCS7_R_NO_CONTENT), "no content"}, + {ERR_REASON(PKCS7_R_NO_CONTENT_TYPE), "no content type"}, + {ERR_REASON(PKCS7_R_NO_DEFAULT_DIGEST), "no default digest"}, + {ERR_REASON(PKCS7_R_NO_MATCHING_DIGEST_TYPE_FOUND), + "no matching digest type found"}, + {ERR_REASON(PKCS7_R_NO_MULTIPART_BODY_FAILURE), + "no multipart body failure"}, + {ERR_REASON(PKCS7_R_NO_MULTIPART_BOUNDARY), "no multipart boundary"}, + {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_CERTIFICATE), + "no recipient matches certificate"}, + {ERR_REASON(PKCS7_R_NO_RECIPIENT_MATCHES_KEY), + "no recipient matches key"}, + {ERR_REASON(PKCS7_R_NO_SIGNATURES_ON_DATA), "no signatures on data"}, + {ERR_REASON(PKCS7_R_NO_SIGNERS), "no signers"}, + {ERR_REASON(PKCS7_R_NO_SIG_CONTENT_TYPE), "no sig content type"}, + {ERR_REASON(PKCS7_R_OPERATION_NOT_SUPPORTED_ON_THIS_TYPE), + "operation not supported on this type"}, + {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNATURE_ERROR), + "pkcs7 add signature error"}, + {ERR_REASON(PKCS7_R_PKCS7_ADD_SIGNER_ERROR), "pkcs7 add signer error"}, + {ERR_REASON(PKCS7_R_PKCS7_DATAFINAL), "pkcs7 datafinal"}, + {ERR_REASON(PKCS7_R_PKCS7_DATAFINAL_ERROR), "pkcs7 datafinal error"}, + {ERR_REASON(PKCS7_R_PKCS7_DATASIGN), "pkcs7 datasign"}, + {ERR_REASON(PKCS7_R_PKCS7_PARSE_ERROR), "pkcs7 parse error"}, + {ERR_REASON(PKCS7_R_PKCS7_SIG_PARSE_ERROR), "pkcs7 sig parse error"}, + {ERR_REASON(PKCS7_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), + "private key does not match certificate"}, + {ERR_REASON(PKCS7_R_SIGNATURE_FAILURE), "signature failure"}, + {ERR_REASON(PKCS7_R_SIGNER_CERTIFICATE_NOT_FOUND), + "signer certificate not found"}, + {ERR_REASON(PKCS7_R_SIGNING_CTRL_FAILURE), "signing ctrl failure"}, + {ERR_REASON(PKCS7_R_SIGNING_NOT_SUPPORTED_FOR_THIS_KEY_TYPE), + "signing not supported for this key type"}, + {ERR_REASON(PKCS7_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"}, + {ERR_REASON(PKCS7_R_SMIME_TEXT_ERROR), "smime text error"}, + {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_CERTIFICATE), + "unable to find certificate"}, + {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MEM_BIO), "unable to find mem bio"}, + {ERR_REASON(PKCS7_R_UNABLE_TO_FIND_MESSAGE_DIGEST), + "unable to find message digest"}, + {ERR_REASON(PKCS7_R_UNKNOWN_DIGEST_TYPE), "unknown digest type"}, + {ERR_REASON(PKCS7_R_UNKNOWN_OPERATION), "unknown operation"}, + {ERR_REASON(PKCS7_R_UNSUPPORTED_CIPHER_TYPE), "unsupported cipher type"}, + {ERR_REASON(PKCS7_R_UNSUPPORTED_CONTENT_TYPE), + "unsupported content type"}, + {ERR_REASON(PKCS7_R_WRONG_CONTENT_TYPE), "wrong content type"}, + {ERR_REASON(PKCS7_R_WRONG_PKCS7_TYPE), "wrong pkcs7 type"}, + {0, NULL} +}; + +#endif + +void ERR_load_PKCS7_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(PKCS7_str_functs[0].error) == NULL) { + ERR_load_strings(0, PKCS7_str_functs); + ERR_load_strings(0, PKCS7_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/ppccap.c b/libs/openssl/crypto/ppccap.c new file mode 100644 index 00000000..52422943 --- /dev/null +++ b/libs/openssl/crypto/ppccap.c @@ -0,0 +1,129 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#define PPC_FPU64 (1<<0) +#define PPC_ALTIVEC (1<<1) + +static int OPENSSL_ppccap_P = 0; + +static sigset_t all_masked; + +#ifdef OPENSSL_BN_ASM_MONT +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num) +{ + int bn_mul_mont_fpu64(BN_ULONG *rp, const BN_ULONG *ap, + const BN_ULONG *bp, const BN_ULONG *np, + const BN_ULONG *n0, int num); + int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num); + + if (sizeof(size_t) == 4) { +# if (defined(__APPLE__) && defined(__MACH__)) + if (num >= 8 && (num & 3) == 0 && (OPENSSL_ppccap_P & PPC_FPU64)) + return bn_mul_mont_fpu64(rp, ap, bp, np, n0, num); +# else + /* + * boundary of 32 was experimentally determined on Linux 2.6.22, + * might have to be adjusted on AIX... + */ + if (num >= 32 && (num & 3) == 0 && (OPENSSL_ppccap_P & PPC_FPU64)) { + sigset_t oset; + int ret; + + sigprocmask(SIG_SETMASK, &all_masked, &oset); + ret = bn_mul_mont_fpu64(rp, ap, bp, np, n0, num); + sigprocmask(SIG_SETMASK, &oset, NULL); + + return ret; + } +# endif + } else if ((OPENSSL_ppccap_P & PPC_FPU64)) + /* + * this is a "must" on POWER6, but run-time detection is not + * implemented yet... + */ + return bn_mul_mont_fpu64(rp, ap, bp, np, n0, num); + + return bn_mul_mont_int(rp, ap, bp, np, n0, num); +} +#endif + +static sigjmp_buf ill_jmp; +static void ill_handler(int sig) +{ + siglongjmp(ill_jmp, sig); +} + +void OPENSSL_ppc64_probe(void); +void OPENSSL_altivec_probe(void); + +void OPENSSL_cpuid_setup(void) +{ + char *e; + struct sigaction ill_oact, ill_act; + sigset_t oset; + static int trigger = 0; + + if (trigger) + return; + trigger = 1; + + sigfillset(&all_masked); + sigdelset(&all_masked, SIGILL); + sigdelset(&all_masked, SIGTRAP); +#ifdef SIGEMT + sigdelset(&all_masked, SIGEMT); +#endif + sigdelset(&all_masked, SIGFPE); + sigdelset(&all_masked, SIGBUS); + sigdelset(&all_masked, SIGSEGV); + + if ((e = getenv("OPENSSL_ppccap"))) { + OPENSSL_ppccap_P = strtoul(e, NULL, 0); + return; + } + + OPENSSL_ppccap_P = 0; + +#if defined(_AIX) + if (sizeof(size_t) == 4 +# if defined(_SC_AIX_KERNEL_BITMODE) + && sysconf(_SC_AIX_KERNEL_BITMODE) != 64 +# endif + ) + return; +#endif + + memset(&ill_act, 0, sizeof(ill_act)); + ill_act.sa_handler = ill_handler; + ill_act.sa_mask = all_masked; + + sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); + sigaction(SIGILL, &ill_act, &ill_oact); + + if (sizeof(size_t) == 4) { + if (sigsetjmp(ill_jmp, 1) == 0) { + OPENSSL_ppc64_probe(); + OPENSSL_ppccap_P |= PPC_FPU64; + } + } else { + /* + * Wanted code detecting POWER6 CPU and setting PPC_FPU64 + */ + } + + if (sigsetjmp(ill_jmp, 1) == 0) { + OPENSSL_altivec_probe(); + OPENSSL_ppccap_P |= PPC_ALTIVEC; + } + + sigaction(SIGILL, &ill_oact, NULL); + sigprocmask(SIG_SETMASK, &oset, NULL); +} diff --git a/libs/openssl/crypto/ppccpuid.pl b/libs/openssl/crypto/ppccpuid.pl new file mode 100755 index 00000000..4ba736a1 --- /dev/null +++ b/libs/openssl/crypto/ppccpuid.pl @@ -0,0 +1,132 @@ +#!/usr/bin/env perl + +$flavour = shift; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or +( $xlate="${dir}perlasm/ppc-xlate.pl" and -f $xlate) or +die "can't locate ppc-xlate.pl"; + +open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; + +if ($flavour=~/64/) { + $CMPLI="cmpldi"; + $SHRLI="srdi"; + $SIGNX="extsw"; +} else { + $CMPLI="cmplwi"; + $SHRLI="srwi"; + $SIGNX="mr"; +} + +$code=<<___; +.machine "any" +.text + +.globl .OPENSSL_ppc64_probe +.align 4 +.OPENSSL_ppc64_probe: + fcfid f1,f1 + extrdi r0,r0,32,0 + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 + +.globl .OPENSSL_altivec_probe +.align 4 +.OPENSSL_altivec_probe: + .long 0x10000484 # vor v0,v0,v0 + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 + +.globl .OPENSSL_wipe_cpu +.align 4 +.OPENSSL_wipe_cpu: + xor r0,r0,r0 + fmr f0,f31 + fmr f1,f31 + fmr f2,f31 + mr r3,r1 + fmr f3,f31 + xor r4,r4,r4 + fmr f4,f31 + xor r5,r5,r5 + fmr f5,f31 + xor r6,r6,r6 + fmr f6,f31 + xor r7,r7,r7 + fmr f7,f31 + xor r8,r8,r8 + fmr f8,f31 + xor r9,r9,r9 + fmr f9,f31 + xor r10,r10,r10 + fmr f10,f31 + xor r11,r11,r11 + fmr f11,f31 + xor r12,r12,r12 + fmr f12,f31 + fmr f13,f31 + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 + +.globl .OPENSSL_atomic_add +.align 4 +.OPENSSL_atomic_add: +Ladd: lwarx r5,0,r3 + add r0,r4,r5 + stwcx. r0,0,r3 + bne- Ladd + $SIGNX r3,r0 + blr + .long 0 + .byte 0,12,0x14,0,0,0,2,0 + .long 0 + +.globl .OPENSSL_rdtsc +.align 4 +.OPENSSL_rdtsc: + mftb r3 + mftbu r4 + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 + +.globl .OPENSSL_cleanse +.align 4 +.OPENSSL_cleanse: + $CMPLI r4,7 + li r0,0 + bge Lot + $CMPLI r4,0 + beqlr- +Little: mtctr r4 + stb r0,0(r3) + addi r3,r3,1 + bdnz \$-8 + blr +Lot: andi. r5,r3,3 + beq Laligned + stb r0,0(r3) + subi r4,r4,1 + addi r3,r3,1 + b Lot +Laligned: + $SHRLI r5,r4,2 + mtctr r5 + stw r0,0(r3) + addi r3,r3,4 + bdnz \$-8 + andi. r4,r4,3 + bne Little + blr + .long 0 + .byte 0,12,0x14,0,0,0,2,0 + .long 0 +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/pqueue/pq_test.c b/libs/openssl/crypto/pqueue/pq_test.c new file mode 100644 index 00000000..479ab224 --- /dev/null +++ b/libs/openssl/crypto/pqueue/pq_test.c @@ -0,0 +1,94 @@ +/* crypto/pqueue/pq_test.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "pqueue.h" + +int main(void) +{ + pitem *item; + pqueue pq; + + pq = pqueue_new(); + + item = pitem_new(3, NULL); + pqueue_insert(pq, item); + + item = pitem_new(1, NULL); + pqueue_insert(pq, item); + + item = pitem_new(2, NULL); + pqueue_insert(pq, item); + + item = pqueue_find(pq, 1); + fprintf(stderr, "found %ld\n", item->priority); + + item = pqueue_find(pq, 2); + fprintf(stderr, "found %ld\n", item->priority); + + item = pqueue_find(pq, 3); + fprintf(stderr, "found %ld\n", item ? item->priority : 0); + + pqueue_print(pq); + + for (item = pqueue_pop(pq); item != NULL; item = pqueue_pop(pq)) + pitem_free(item); + + pqueue_free(pq); + return 0; +} diff --git a/libs/openssl/crypto/pqueue/pqueue.c b/libs/openssl/crypto/pqueue/pqueue.c new file mode 100644 index 00000000..75f97349 --- /dev/null +++ b/libs/openssl/crypto/pqueue/pqueue.c @@ -0,0 +1,235 @@ +/* crypto/pqueue/pqueue.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include +#include "pqueue.h" + +typedef struct _pqueue { + pitem *items; + int count; +} pqueue_s; + +pitem *pitem_new(unsigned char *prio64be, void *data) +{ + pitem *item = (pitem *)OPENSSL_malloc(sizeof(pitem)); + if (item == NULL) + return NULL; + + memcpy(item->priority, prio64be, sizeof(item->priority)); + + item->data = data; + item->next = NULL; + + return item; +} + +void pitem_free(pitem *item) +{ + if (item == NULL) + return; + + OPENSSL_free(item); +} + +pqueue_s *pqueue_new() +{ + pqueue_s *pq = (pqueue_s *)OPENSSL_malloc(sizeof(pqueue_s)); + if (pq == NULL) + return NULL; + + memset(pq, 0x00, sizeof(pqueue_s)); + return pq; +} + +void pqueue_free(pqueue_s *pq) +{ + if (pq == NULL) + return; + + OPENSSL_free(pq); +} + +pitem *pqueue_insert(pqueue_s *pq, pitem *item) +{ + pitem *curr, *next; + + if (pq->items == NULL) { + pq->items = item; + return item; + } + + for (curr = NULL, next = pq->items; + next != NULL; curr = next, next = next->next) { + /* + * we can compare 64-bit value in big-endian encoding with memcmp:-) + */ + int cmp = memcmp(next->priority, item->priority, 8); + if (cmp > 0) { /* next > item */ + item->next = next; + + if (curr == NULL) + pq->items = item; + else + curr->next = item; + + return item; + } + + else if (cmp == 0) /* duplicates not allowed */ + return NULL; + } + + item->next = NULL; + curr->next = item; + + return item; +} + +pitem *pqueue_peek(pqueue_s *pq) +{ + return pq->items; +} + +pitem *pqueue_pop(pqueue_s *pq) +{ + pitem *item = pq->items; + + if (pq->items != NULL) + pq->items = pq->items->next; + + return item; +} + +pitem *pqueue_find(pqueue_s *pq, unsigned char *prio64be) +{ + pitem *next; + pitem *found = NULL; + + if (pq->items == NULL) + return NULL; + + for (next = pq->items; next->next != NULL; next = next->next) { + if (memcmp(next->priority, prio64be, 8) == 0) { + found = next; + break; + } + } + + /* check the one last node */ + if (memcmp(next->priority, prio64be, 8) == 0) + found = next; + + if (!found) + return NULL; + +#if 0 /* find works in peek mode */ + if (prev == NULL) + pq->items = next->next; + else + prev->next = next->next; +#endif + + return found; +} + +void pqueue_print(pqueue_s *pq) +{ + pitem *item = pq->items; + + while (item != NULL) { + printf("item\t%02x%02x%02x%02x%02x%02x%02x%02x\n", + item->priority[0], item->priority[1], + item->priority[2], item->priority[3], + item->priority[4], item->priority[5], + item->priority[6], item->priority[7]); + item = item->next; + } +} + +pitem *pqueue_iterator(pqueue_s *pq) +{ + return pqueue_peek(pq); +} + +pitem *pqueue_next(pitem **item) +{ + pitem *ret; + + if (item == NULL || *item == NULL) + return NULL; + + /* *item != NULL */ + ret = *item; + *item = (*item)->next; + + return ret; +} + +int pqueue_size(pqueue_s *pq) +{ + pitem *item = pq->items; + int count = 0; + + while (item != NULL) { + count++; + item = item->next; + } + return count; +} diff --git a/libs/openssl/crypto/pqueue/pqueue.h b/libs/openssl/crypto/pqueue/pqueue.h new file mode 100644 index 00000000..d40d9c7d --- /dev/null +++ b/libs/openssl/crypto/pqueue/pqueue.h @@ -0,0 +1,99 @@ +/* crypto/pqueue/pqueue.h */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_PQUEUE_H +# define HEADER_PQUEUE_H + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif +typedef struct _pqueue *pqueue; + +typedef struct _pitem { + unsigned char priority[8]; /* 64-bit value in big-endian encoding */ + void *data; + struct _pitem *next; +} pitem; + +typedef struct _pitem *piterator; + +pitem *pitem_new(unsigned char *prio64be, void *data); +void pitem_free(pitem *item); + +pqueue pqueue_new(void); +void pqueue_free(pqueue pq); + +pitem *pqueue_insert(pqueue pq, pitem *item); +pitem *pqueue_peek(pqueue pq); +pitem *pqueue_pop(pqueue pq); +pitem *pqueue_find(pqueue pq, unsigned char *prio64be); +pitem *pqueue_iterator(pqueue pq); +pitem *pqueue_next(piterator *iter); + +void pqueue_print(pqueue pq); +int pqueue_size(pqueue pq); + +#ifdef __cplusplus +} +#endif +#endif /* ! HEADER_PQUEUE_H */ diff --git a/libs/openssl/crypto/rand/md_rand.c b/libs/openssl/crypto/rand/md_rand.c new file mode 100644 index 00000000..5c13d577 --- /dev/null +++ b/libs/openssl/crypto/rand/md_rand.c @@ -0,0 +1,592 @@ +/* crypto/rand/md_rand.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#define OPENSSL_FIPSEVP + +#ifdef MD_RAND_DEBUG +# ifndef NDEBUG +# define NDEBUG +# endif +#endif + +#include +#include +#include + +#include "e_os.h" + +#include +#include +#include "rand_lcl.h" + +#include + +#ifdef BN_DEBUG +# define PREDICT +#endif + +/* #define PREDICT 1 */ + +#define STATE_SIZE 1023 +static int state_num = 0, state_index = 0; +static unsigned char state[STATE_SIZE + MD_DIGEST_LENGTH]; +static unsigned char md[MD_DIGEST_LENGTH]; +static long md_count[2] = { 0, 0 }; + +static double entropy = 0; +static int initialized = 0; + +static unsigned int crypto_lock_rand = 0; /* may be set only when a thread + * holds CRYPTO_LOCK_RAND (to + * prevent double locking) */ +/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */ +/* valid iff crypto_lock_rand is set */ +static CRYPTO_THREADID locking_threadid; + +#ifdef PREDICT +int rand_predictable = 0; +#endif + +const char RAND_version[] = "RAND" OPENSSL_VERSION_PTEXT; + +static void ssleay_rand_cleanup(void); +static void ssleay_rand_seed(const void *buf, int num); +static void ssleay_rand_add(const void *buf, int num, double add_entropy); +static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num); +static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num); +static int ssleay_rand_status(void); + +RAND_METHOD rand_ssleay_meth = { + ssleay_rand_seed, + ssleay_rand_nopseudo_bytes, + ssleay_rand_cleanup, + ssleay_rand_add, + ssleay_rand_pseudo_bytes, + ssleay_rand_status +}; + +RAND_METHOD *RAND_SSLeay(void) +{ + return (&rand_ssleay_meth); +} + +static void ssleay_rand_cleanup(void) +{ + OPENSSL_cleanse(state, sizeof(state)); + state_num = 0; + state_index = 0; + OPENSSL_cleanse(md, MD_DIGEST_LENGTH); + md_count[0] = 0; + md_count[1] = 0; + entropy = 0; + initialized = 0; +} + +static void ssleay_rand_add(const void *buf, int num, double add) +{ + int i, j, k, st_idx; + long md_c[2]; + unsigned char local_md[MD_DIGEST_LENGTH]; + EVP_MD_CTX m; + int do_not_lock; + + if (!num) + return; + + /* + * (Based on the rand(3) manpage) + * + * The input is chopped up into units of 20 bytes (or less for + * the last block). Each of these blocks is run through the hash + * function as follows: The data passed to the hash function + * is the current 'md', the same number of bytes from the 'state' + * (the location determined by in incremented looping index) as + * the current 'block', the new key data 'block', and 'count' + * (which is incremented after each use). + * The result of this is kept in 'md' and also xored into the + * 'state' at the same locations that were used as input into the + * hash function. + */ + + /* check if we already have the lock */ + if (crypto_lock_rand) { + CRYPTO_THREADID cur; + CRYPTO_THREADID_current(&cur); + CRYPTO_r_lock(CRYPTO_LOCK_RAND2); + do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); + CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); + } else + do_not_lock = 0; + + if (!do_not_lock) + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + st_idx = state_index; + + /* + * use our own copies of the counters so that even if a concurrent thread + * seeds with exactly the same data and uses the same subarray there's + * _some_ difference + */ + md_c[0] = md_count[0]; + md_c[1] = md_count[1]; + + memcpy(local_md, md, sizeof md); + + /* state_index <= state_num <= STATE_SIZE */ + state_index += num; + if (state_index >= STATE_SIZE) { + state_index %= STATE_SIZE; + state_num = STATE_SIZE; + } else if (state_num < STATE_SIZE) { + if (state_index > state_num) + state_num = state_index; + } + /* state_index <= state_num <= STATE_SIZE */ + + /* + * state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE] are what we + * will use now, but other threads may use them as well + */ + + md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0); + + if (!do_not_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + + EVP_MD_CTX_init(&m); + for (i = 0; i < num; i += MD_DIGEST_LENGTH) { + j = (num - i); + j = (j > MD_DIGEST_LENGTH) ? MD_DIGEST_LENGTH : j; + + MD_Init(&m); + MD_Update(&m, local_md, MD_DIGEST_LENGTH); + k = (st_idx + j) - STATE_SIZE; + if (k > 0) { + MD_Update(&m, &(state[st_idx]), j - k); + MD_Update(&m, &(state[0]), k); + } else + MD_Update(&m, &(state[st_idx]), j); + + /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */ + MD_Update(&m, buf, j); + /* + * We know that line may cause programs such as purify and valgrind + * to complain about use of uninitialized data. The problem is not, + * it's with the caller. Removing that line will make sure you get + * really bad randomness and thereby other problems such as very + * insecure keys. + */ + + MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)); + MD_Final(&m, local_md); + md_c[1]++; + + buf = (const char *)buf + j; + + for (k = 0; k < j; k++) { + /* + * Parallel threads may interfere with this, but always each byte + * of the new state is the XOR of some previous value of its and + * local_md (itermediate values may be lost). Alway using locking + * could hurt performance more than necessary given that + * conflicts occur only when the total seeding is longer than the + * random state. + */ + state[st_idx++] ^= local_md[k]; + if (st_idx >= STATE_SIZE) + st_idx = 0; + } + } + EVP_MD_CTX_cleanup(&m); + + if (!do_not_lock) + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + /* + * Don't just copy back local_md into md -- this could mean that other + * thread's seeding remains without effect (except for the incremented + * counter). By XORing it we keep at least as much entropy as fits into + * md. + */ + for (k = 0; k < (int)sizeof(md); k++) { + md[k] ^= local_md[k]; + } + if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */ + entropy += add; + if (!do_not_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + +#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) + assert(md_c[1] == md_count[1]); +#endif +} + +static void ssleay_rand_seed(const void *buf, int num) +{ + ssleay_rand_add(buf, num, (double)num); +} + +int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock) +{ + static volatile int stirred_pool = 0; + int i, j, k, st_num, st_idx; + int num_ceil; + int ok; + long md_c[2]; + unsigned char local_md[MD_DIGEST_LENGTH]; + EVP_MD_CTX m; +#ifndef GETPID_IS_MEANINGLESS + pid_t curr_pid = getpid(); +#endif + int do_stir_pool = 0; + +#ifdef PREDICT + if (rand_predictable) { + static unsigned char val = 0; + + for (i = 0; i < num; i++) + buf[i] = val++; + return (1); + } +#endif + + if (num <= 0) + return 1; + + EVP_MD_CTX_init(&m); + /* round upwards to multiple of MD_DIGEST_LENGTH/2 */ + num_ceil = + (1 + (num - 1) / (MD_DIGEST_LENGTH / 2)) * (MD_DIGEST_LENGTH / 2); + + /* + * (Based on the rand(3) manpage:) + * + * For each group of 10 bytes (or less), we do the following: + * + * Input into the hash function the local 'md' (which is initialized from + * the global 'md' before any bytes are generated), the bytes that are to + * be overwritten by the random bytes, and bytes from the 'state' + * (incrementing looping index). From this digest output (which is kept + * in 'md'), the top (up to) 10 bytes are returned to the caller and the + * bottom 10 bytes are xored into the 'state'. + * + * Finally, after we have finished 'num' random bytes for the + * caller, 'count' (which is incremented) and the local and global 'md' + * are fed into the hash function and the results are kept in the + * global 'md'. + */ + if (lock) + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + + /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ + CRYPTO_w_lock(CRYPTO_LOCK_RAND2); + CRYPTO_THREADID_current(&locking_threadid); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); + crypto_lock_rand = 1; + + if (!initialized) { + RAND_poll(); + initialized = 1; + } + + if (!stirred_pool) + do_stir_pool = 1; + + ok = (entropy >= ENTROPY_NEEDED); + if (!ok) { + /* + * If the PRNG state is not yet unpredictable, then seeing the PRNG + * output may help attackers to determine the new state; thus we have + * to decrease the entropy estimate. Once we've had enough initial + * seeding we don't bother to adjust the entropy count, though, + * because we're not ambitious to provide *information-theoretic* + * randomness. NOTE: This approach fails if the program forks before + * we have enough entropy. Entropy should be collected in a separate + * input pool and be transferred to the output pool only when the + * entropy limit has been reached. + */ + entropy -= num; + if (entropy < 0) + entropy = 0; + } + + if (do_stir_pool) { + /* + * In the output function only half of 'md' remains secret, so we + * better make sure that the required entropy gets 'evenly + * distributed' through 'state', our randomness pool. The input + * function (ssleay_rand_add) chains all of 'md', which makes it more + * suitable for this purpose. + */ + + int n = STATE_SIZE; /* so that the complete pool gets accessed */ + while (n > 0) { +#if MD_DIGEST_LENGTH > 20 +# error "Please adjust DUMMY_SEED." +#endif +#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */ + /* + * Note that the seed does not matter, it's just that + * ssleay_rand_add expects to have something to hash. + */ + ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0); + n -= MD_DIGEST_LENGTH; + } + if (ok) + stirred_pool = 1; + } + + st_idx = state_index; + st_num = state_num; + md_c[0] = md_count[0]; + md_c[1] = md_count[1]; + memcpy(local_md, md, sizeof md); + + state_index += num_ceil; + if (state_index > state_num) + state_index %= state_num; + + /* + * state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num] are now + * ours (but other threads may use them too) + */ + + md_count[0] += 1; + + /* before unlocking, we must clear 'crypto_lock_rand' */ + crypto_lock_rand = 0; + if (lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + + while (num > 0) { + /* num_ceil -= MD_DIGEST_LENGTH/2 */ + j = (num >= MD_DIGEST_LENGTH / 2) ? MD_DIGEST_LENGTH / 2 : num; + num -= j; + MD_Init(&m); +#ifndef GETPID_IS_MEANINGLESS + if (curr_pid) { /* just in the first iteration to save time */ + MD_Update(&m, (unsigned char *)&curr_pid, sizeof curr_pid); + curr_pid = 0; + } +#endif + MD_Update(&m, local_md, MD_DIGEST_LENGTH); + MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)); + +#ifndef PURIFY /* purify complains */ + /* + * The following line uses the supplied buffer as a small source of + * entropy: since this buffer is often uninitialised it may cause + * programs such as purify or valgrind to complain. So for those + * builds it is not used: the removal of such a small source of + * entropy has negligible impact on security. + */ + MD_Update(&m, buf, j); +#endif + + k = (st_idx + MD_DIGEST_LENGTH / 2) - st_num; + if (k > 0) { + MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k); + MD_Update(&m, &(state[0]), k); + } else + MD_Update(&m, &(state[st_idx]), MD_DIGEST_LENGTH / 2); + MD_Final(&m, local_md); + + for (i = 0; i < MD_DIGEST_LENGTH / 2; i++) { + /* may compete with other threads */ + state[st_idx++] ^= local_md[i]; + if (st_idx >= st_num) + st_idx = 0; + if (i < j) + *(buf++) = local_md[i + MD_DIGEST_LENGTH / 2]; + } + } + + MD_Init(&m); + MD_Update(&m, (unsigned char *)&(md_c[0]), sizeof(md_c)); + MD_Update(&m, local_md, MD_DIGEST_LENGTH); + if (lock) + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + MD_Update(&m, md, MD_DIGEST_LENGTH); + MD_Final(&m, md); + if (lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + + EVP_MD_CTX_cleanup(&m); + if (ok) + return (1); + else if (pseudo) + return 0; + else { + RANDerr(RAND_F_SSLEAY_RAND_BYTES, RAND_R_PRNG_NOT_SEEDED); + ERR_add_error_data(1, "You need to read the OpenSSL FAQ, " + "http://www.openssl.org/support/faq.html"); + return (0); + } +} + +static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num) +{ + return ssleay_rand_bytes(buf, num, 0, 1); +} + +/* + * pseudo-random bytes that are guaranteed to be unique but not unpredictable + */ +static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num) +{ + return ssleay_rand_bytes(buf, num, 1, 1); +} + +static int ssleay_rand_status(void) +{ + CRYPTO_THREADID cur; + int ret; + int do_not_lock; + + CRYPTO_THREADID_current(&cur); + /* + * check if we already have the lock (could happen if a RAND_poll() + * implementation calls RAND_status()) + */ + if (crypto_lock_rand) { + CRYPTO_r_lock(CRYPTO_LOCK_RAND2); + do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); + CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); + } else + do_not_lock = 0; + + if (!do_not_lock) { + CRYPTO_w_lock(CRYPTO_LOCK_RAND); + + /* + * prevent ssleay_rand_bytes() from trying to obtain the lock again + */ + CRYPTO_w_lock(CRYPTO_LOCK_RAND2); + CRYPTO_THREADID_cpy(&locking_threadid, &cur); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); + crypto_lock_rand = 1; + } + + if (!initialized) { + RAND_poll(); + initialized = 1; + } + + ret = entropy >= ENTROPY_NEEDED; + + if (!do_not_lock) { + /* before unlocking, we must clear 'crypto_lock_rand' */ + crypto_lock_rand = 0; + + CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + } + + return ret; +} diff --git a/libs/openssl/crypto/rand/rand.h b/libs/openssl/crypto/rand/rand.h new file mode 100644 index 00000000..2553afda --- /dev/null +++ b/libs/openssl/crypto/rand/rand.h @@ -0,0 +1,150 @@ +/* crypto/rand/rand.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RAND_H +# define HEADER_RAND_H + +# include +# include +# include + +# if defined(OPENSSL_SYS_WINDOWS) +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# if defined(OPENSSL_FIPS) +# define FIPS_RAND_SIZE_T size_t +# endif + +/* Already defined in ossl_typ.h */ +/* typedef struct rand_meth_st RAND_METHOD; */ + +struct rand_meth_st { + void (*seed) (const void *buf, int num); + int (*bytes) (unsigned char *buf, int num); + void (*cleanup) (void); + void (*add) (const void *buf, int num, double entropy); + int (*pseudorand) (unsigned char *buf, int num); + int (*status) (void); +}; + +# ifdef BN_DEBUG +extern int rand_predictable; +# endif + +int RAND_set_rand_method(const RAND_METHOD *meth); +const RAND_METHOD *RAND_get_rand_method(void); +# ifndef OPENSSL_NO_ENGINE +int RAND_set_rand_engine(ENGINE *engine); +# endif +RAND_METHOD *RAND_SSLeay(void); +void RAND_cleanup(void); +int RAND_bytes(unsigned char *buf, int num); +int RAND_pseudo_bytes(unsigned char *buf, int num); +void RAND_seed(const void *buf, int num); +void RAND_add(const void *buf, int num, double entropy); +int RAND_load_file(const char *file, long max_bytes); +int RAND_write_file(const char *file); +const char *RAND_file_name(char *file, size_t num); +int RAND_status(void); +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes); +int RAND_egd(const char *path); +int RAND_egd_bytes(const char *path, int bytes); +int RAND_poll(void); + +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) + +void RAND_screen(void); +int RAND_event(UINT, WPARAM, LPARAM); + +# endif + +# ifdef OPENSSL_FIPS +void RAND_set_fips_drbg_type(int type, int flags); +int RAND_init_fips(void); +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_RAND_strings(void); + +/* Error codes for the RAND functions. */ + +/* Function codes. */ +# define RAND_F_RAND_GET_RAND_METHOD 101 +# define RAND_F_RAND_INIT_FIPS 102 +# define RAND_F_SSLEAY_RAND_BYTES 100 + +/* Reason codes. */ +# define RAND_R_DUAL_EC_DRBG_DISABLED 104 +# define RAND_R_ERROR_INITIALISING_DRBG 102 +# define RAND_R_ERROR_INSTANTIATING_DRBG 103 +# define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101 +# define RAND_R_PRNG_NOT_SEEDED 100 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/rand/rand_egd.c b/libs/openssl/crypto/rand/rand_egd.c new file mode 100644 index 00000000..737aebfa --- /dev/null +++ b/libs/openssl/crypto/rand/rand_egd.c @@ -0,0 +1,292 @@ +/* crypto/rand/rand_egd.c */ +/* Written by Ulf Moeller and Lutz Jaenicke for the OpenSSL project. */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +/*- + * Query the EGD . + * + * This module supplies three routines: + * + * RAND_query_egd_bytes(path, buf, bytes) + * will actually query "bytes" bytes of entropy form the egd-socket located + * at path and will write them to buf (if supplied) or will directly feed + * it to RAND_seed() if buf==NULL. + * The number of bytes is not limited by the maximum chunk size of EGD, + * which is 255 bytes. If more than 255 bytes are wanted, several chunks + * of entropy bytes are requested. The connection is left open until the + * query is competed. + * RAND_query_egd_bytes() returns with + * -1 if an error occured during connection or communication. + * num the number of bytes read from the EGD socket. This number is either + * the number of bytes requested or smaller, if the EGD pool is + * drained and the daemon signals that the pool is empty. + * This routine does not touch any RAND_status(). This is necessary, since + * PRNG functions may call it during initialization. + * + * RAND_egd_bytes(path, bytes) will query "bytes" bytes and have them + * used to seed the PRNG. + * RAND_egd_bytes() is a wrapper for RAND_query_egd_bytes() with buf=NULL. + * Unlike RAND_query_egd_bytes(), RAND_status() is used to test the + * seed status so that the return value can reflect the seed state: + * -1 if an error occured during connection or communication _or_ + * if the PRNG has still not received the required seeding. + * num the number of bytes read from the EGD socket. This number is either + * the number of bytes requested or smaller, if the EGD pool is + * drained and the daemon signals that the pool is empty. + * + * RAND_egd(path) will query 255 bytes and use the bytes retreived to seed + * the PRNG. + * RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255. + */ + +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS) +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) +{ + return (-1); +} + +int RAND_egd(const char *path) +{ + return (-1); +} + +int RAND_egd_bytes(const char *path, int bytes) +{ + return (-1); +} +#else +# include +# include OPENSSL_UNISTD +# include +# include +# include +# ifndef NO_SYS_UN_H +# ifdef OPENSSL_SYS_VXWORKS +# include +# else +# include +# endif +# else +struct sockaddr_un { + short sun_family; /* AF_UNIX */ + char sun_path[108]; /* path name (gag) */ +}; +# endif /* NO_SYS_UN_H */ +# include +# include + +# ifndef offsetof +# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) +# endif + +int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) +{ + int ret = 0; + struct sockaddr_un addr; + int len, num, numbytes; + int fd = -1; + int success; + unsigned char egdbuf[2], tempbuf[255], *retrievebuf; + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + if (strlen(path) >= sizeof(addr.sun_path)) + return (-1); + BUF_strlcpy(addr.sun_path, path, sizeof addr.sun_path); + len = offsetof(struct sockaddr_un, sun_path) + strlen(path); + fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd == -1) + return (-1); + success = 0; + while (!success) { + if (connect(fd, (struct sockaddr *)&addr, len) == 0) + success = 1; + else { + switch (errno) { +# ifdef EINTR + case EINTR: +# endif +# ifdef EAGAIN + case EAGAIN: +# endif +# ifdef EINPROGRESS + case EINPROGRESS: +# endif +# ifdef EALREADY + case EALREADY: +# endif + /* No error, try again */ + break; +# ifdef EISCONN + case EISCONN: + success = 1; + break; +# endif + default: + goto err; /* failure */ + } + } + } + + while (bytes > 0) { + egdbuf[0] = 1; + egdbuf[1] = bytes < 255 ? bytes : 255; + numbytes = 0; + while (numbytes != 2) { + num = write(fd, egdbuf + numbytes, 2 - numbytes); + if (num >= 0) + numbytes += num; + else { + switch (errno) { +# ifdef EINTR + case EINTR: +# endif +# ifdef EAGAIN + case EAGAIN: +# endif + /* No error, try again */ + break; + default: + ret = -1; + goto err; /* failure */ + } + } + } + numbytes = 0; + while (numbytes != 1) { + num = read(fd, egdbuf, 1); + if (num == 0) + goto err; /* descriptor closed */ + else if (num > 0) + numbytes += num; + else { + switch (errno) { +# ifdef EINTR + case EINTR: +# endif +# ifdef EAGAIN + case EAGAIN: +# endif + /* No error, try again */ + break; + default: + ret = -1; + goto err; /* failure */ + } + } + } + if (egdbuf[0] == 0) + goto err; + if (buf) + retrievebuf = buf + ret; + else + retrievebuf = tempbuf; + numbytes = 0; + while (numbytes != egdbuf[0]) { + num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes); + if (num == 0) + goto err; /* descriptor closed */ + else if (num > 0) + numbytes += num; + else { + switch (errno) { +# ifdef EINTR + case EINTR: +# endif +# ifdef EAGAIN + case EAGAIN: +# endif + /* No error, try again */ + break; + default: + ret = -1; + goto err; /* failure */ + } + } + } + ret += egdbuf[0]; + bytes -= egdbuf[0]; + if (!buf) + RAND_seed(tempbuf, egdbuf[0]); + } + err: + if (fd != -1) + close(fd); + return (ret); +} + +int RAND_egd_bytes(const char *path, int bytes) +{ + int num, ret = 0; + + num = RAND_query_egd_bytes(path, NULL, bytes); + if (num < 1) + goto err; + if (RAND_status() == 1) + ret = num; + err: + return (ret); +} + +int RAND_egd(const char *path) +{ + return (RAND_egd_bytes(path, 255)); +} + +#endif diff --git a/libs/openssl/crypto/rand/rand_err.c b/libs/openssl/crypto/rand/rand_err.c new file mode 100644 index 00000000..55d86ea8 --- /dev/null +++ b/libs/openssl/crypto/rand/rand_err.c @@ -0,0 +1,100 @@ +/* crypto/rand/rand_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_RAND,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_RAND,0,reason) + +static ERR_STRING_DATA RAND_str_functs[] = { + {ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"}, + {ERR_FUNC(RAND_F_RAND_INIT_FIPS), "RAND_init_fips"}, + {ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"}, + {0, NULL} +}; + +static ERR_STRING_DATA RAND_str_reasons[] = { + {ERR_REASON(RAND_R_DUAL_EC_DRBG_DISABLED), "dual ec drbg disabled"}, + {ERR_REASON(RAND_R_ERROR_INITIALISING_DRBG), "error initialising drbg"}, + {ERR_REASON(RAND_R_ERROR_INSTANTIATING_DRBG), "error instantiating drbg"}, + {ERR_REASON(RAND_R_NO_FIPS_RANDOM_METHOD_SET), + "no fips random method set"}, + {ERR_REASON(RAND_R_PRNG_NOT_SEEDED), "PRNG not seeded"}, + {0, NULL} +}; + +#endif + +void ERR_load_RAND_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(RAND_str_functs[0].error) == NULL) { + ERR_load_strings(0, RAND_str_functs); + ERR_load_strings(0, RAND_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/rand/rand_lcl.h b/libs/openssl/crypto/rand/rand_lcl.h new file mode 100644 index 00000000..f9fda3eb --- /dev/null +++ b/libs/openssl/crypto/rand/rand_lcl.h @@ -0,0 +1,158 @@ +/* crypto/rand/rand_lcl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_RAND_LCL_H +# define HEADER_RAND_LCL_H + +# define ENTROPY_NEEDED 32 /* require 256 bits = 32 bytes of randomness */ + +# if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND) +# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) +# define USE_SHA1_RAND +# elif !defined(OPENSSL_NO_MD5) +# define USE_MD5_RAND +# elif !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES) +# define USE_MDC2_RAND +# elif !defined(OPENSSL_NO_MD2) +# define USE_MD2_RAND +# else +# error No message digest algorithm available +# endif +# endif + +# include +# define MD_Update(a,b,c) EVP_DigestUpdate(a,b,c) +# define MD_Final(a,b) EVP_DigestFinal_ex(a,b,NULL) +# if defined(USE_MD5_RAND) +# include +# define MD_DIGEST_LENGTH MD5_DIGEST_LENGTH +# define MD_Init(a) EVP_DigestInit_ex(a,EVP_md5(), NULL) +# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md5(), NULL) +# elif defined(USE_SHA1_RAND) +# include +# define MD_DIGEST_LENGTH SHA_DIGEST_LENGTH +# define MD_Init(a) EVP_DigestInit_ex(a,EVP_sha1(), NULL) +# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_sha1(), NULL) +# elif defined(USE_MDC2_RAND) +# include +# define MD_DIGEST_LENGTH MDC2_DIGEST_LENGTH +# define MD_Init(a) EVP_DigestInit_ex(a,EVP_mdc2(), NULL) +# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_mdc2(), NULL) +# elif defined(USE_MD2_RAND) +# include +# define MD_DIGEST_LENGTH MD2_DIGEST_LENGTH +# define MD_Init(a) EVP_DigestInit_ex(a,EVP_md2(), NULL) +# define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md2(), NULL) +# endif + +int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo, int lock); + +#endif diff --git a/libs/openssl/crypto/rand/rand_lib.c b/libs/openssl/crypto/rand/rand_lib.c new file mode 100644 index 00000000..88a78d35 --- /dev/null +++ b/libs/openssl/crypto/rand/rand_lib.c @@ -0,0 +1,300 @@ +/* crypto/rand/rand_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include + +#ifndef OPENSSL_NO_ENGINE +# include +#endif + +#ifdef OPENSSL_FIPS +# include +# include +# include "rand_lcl.h" +#endif + +#ifndef OPENSSL_NO_ENGINE +/* non-NULL if default_RAND_meth is ENGINE-provided */ +static ENGINE *funct_ref = NULL; +#endif +static const RAND_METHOD *default_RAND_meth = NULL; + +int RAND_set_rand_method(const RAND_METHOD *meth) +{ +#ifndef OPENSSL_NO_ENGINE + if (funct_ref) { + ENGINE_finish(funct_ref); + funct_ref = NULL; + } +#endif + default_RAND_meth = meth; + return 1; +} + +const RAND_METHOD *RAND_get_rand_method(void) +{ + if (!default_RAND_meth) { +#ifndef OPENSSL_NO_ENGINE + ENGINE *e = ENGINE_get_default_RAND(); + if (e) { + default_RAND_meth = ENGINE_get_RAND(e); + if (!default_RAND_meth) { + ENGINE_finish(e); + e = NULL; + } + } + if (e) + funct_ref = e; + else +#endif + default_RAND_meth = RAND_SSLeay(); + } + return default_RAND_meth; +} + +#ifndef OPENSSL_NO_ENGINE +int RAND_set_rand_engine(ENGINE *engine) +{ + const RAND_METHOD *tmp_meth = NULL; + if (engine) { + if (!ENGINE_init(engine)) + return 0; + tmp_meth = ENGINE_get_RAND(engine); + if (!tmp_meth) { + ENGINE_finish(engine); + return 0; + } + } + /* This function releases any prior ENGINE so call it first */ + RAND_set_rand_method(tmp_meth); + funct_ref = engine; + return 1; +} +#endif + +void RAND_cleanup(void) +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->cleanup) + meth->cleanup(); + RAND_set_rand_method(NULL); +} + +void RAND_seed(const void *buf, int num) +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->seed) + meth->seed(buf, num); +} + +void RAND_add(const void *buf, int num, double entropy) +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->add) + meth->add(buf, num, entropy); +} + +int RAND_bytes(unsigned char *buf, int num) +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->bytes) + return meth->bytes(buf, num); + return (-1); +} + +int RAND_pseudo_bytes(unsigned char *buf, int num) +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->pseudorand) + return meth->pseudorand(buf, num); + return (-1); +} + +int RAND_status(void) +{ + const RAND_METHOD *meth = RAND_get_rand_method(); + if (meth && meth->status) + return meth->status(); + return 0; +} + +#ifdef OPENSSL_FIPS + +/* + * FIPS DRBG initialisation code. This sets up the DRBG for use by the rest + * of OpenSSL. + */ + +/* + * Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather + * entropy internally through RAND_poll(). + */ + +static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout, + int entropy, size_t min_len, size_t max_len) +{ + /* Round up request to multiple of block size */ + min_len = ((min_len + 19) / 20) * 20; + *pout = OPENSSL_malloc(min_len); + if (!*pout) + return 0; + if (ssleay_rand_bytes(*pout, min_len, 0, 0) <= 0) { + OPENSSL_free(*pout); + *pout = NULL; + return 0; + } + return min_len; +} + +static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen) +{ + if (out) { + OPENSSL_cleanse(out, olen); + OPENSSL_free(out); + } +} + +/* + * Set "additional input" when generating random data. This uses the current + * PID, a time value and a counter. + */ + +static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout) +{ + /* Use of static variables is OK as this happens under a lock */ + static unsigned char buf[16]; + static unsigned long counter; + FIPS_get_timevec(buf, &counter); + *pout = buf; + return sizeof(buf); +} + +/* + * RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is + * correctly seeded by RAND_poll(). + */ + +static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen, + double entropy) +{ + RAND_SSLeay()->add(in, inlen, entropy); + return 1; +} + +static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen) +{ + RAND_SSLeay()->seed(in, inlen); + return 1; +} + +# ifndef OPENSSL_DRBG_DEFAULT_TYPE +# define OPENSSL_DRBG_DEFAULT_TYPE NID_aes_256_ctr +# endif +# ifndef OPENSSL_DRBG_DEFAULT_FLAGS +# define OPENSSL_DRBG_DEFAULT_FLAGS DRBG_FLAG_CTR_USE_DF +# endif + +static int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE; +static int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS; + +void RAND_set_fips_drbg_type(int type, int flags) +{ + fips_drbg_type = type; + fips_drbg_flags = flags; +} + +int RAND_init_fips(void) +{ + DRBG_CTX *dctx; + size_t plen; + unsigned char pers[32], *p; +# ifndef OPENSSL_ALLOW_DUAL_EC_DRBG + if (fips_drbg_type >> 16) { + RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_DUAL_EC_DRBG_DISABLED); + return 0; + } +# endif + + dctx = FIPS_get_default_drbg(); + if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0) { + RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG); + return 0; + } + + FIPS_drbg_set_callbacks(dctx, + drbg_get_entropy, drbg_free_entropy, 20, + drbg_get_entropy, drbg_free_entropy); + FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0, + drbg_rand_seed, drbg_rand_add); + /* Personalisation string: a string followed by date time vector */ + strcpy((char *)pers, "OpenSSL DRBG2.0"); + plen = drbg_get_adin(dctx, &p); + memcpy(pers + 16, p, plen); + + if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0) { + RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG); + return 0; + } + FIPS_rand_set_method(FIPS_drbg_method()); + return 1; +} + +#endif diff --git a/libs/openssl/crypto/rand/rand_nw.c b/libs/openssl/crypto/rand/rand_nw.c new file mode 100644 index 00000000..55ffe9ad --- /dev/null +++ b/libs/openssl/crypto/rand/rand_nw.c @@ -0,0 +1,179 @@ +/* crypto/rand/rand_nw.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include +#include "rand_lcl.h" + +#if defined (OPENSSL_SYS_NETWARE) + +# if defined(NETWARE_LIBC) +# include +# else +# include +# endif + +extern int GetProcessSwitchCount(void); +# if !defined(NETWARE_LIBC) || (CURRENT_NDK_THRESHOLD < 509220000) +extern void *RunningProcess; /* declare here same as found in newer NDKs */ +extern unsigned long GetSuperHighResolutionTimer(void); +# endif + + /* + * the FAQ indicates we need to provide at least 20 bytes (160 bits) of + * seed + */ +int RAND_poll(void) +{ + unsigned long l; + unsigned long tsc; + int i; + + /* + * There are several options to gather miscellaneous data but for now we + * will loop checking the time stamp counter (rdtsc) and the + * SuperHighResolutionTimer. Each iteration will collect 8 bytes of data + * but it is treated as only 1 byte of entropy. The call to + * ThreadSwitchWithDelay() will introduce additional variability into the + * data returned by rdtsc. Applications can agument the seed material by + * adding additional stuff with RAND_add() and should probably do so. + */ + l = GetProcessSwitchCount(); + RAND_add(&l, sizeof(l), 1); + + /* need to cast the void* to unsigned long here */ + l = (unsigned long)RunningProcess; + RAND_add(&l, sizeof(l), 1); + + for (i = 2; i < ENTROPY_NEEDED; i++) { +# ifdef __MWERKS__ + asm { + rdtsc mov tsc, eax} +# elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) + asm volatile ("rdtsc":"=a" (tsc)::"edx"); +# endif + + RAND_add(&tsc, sizeof(tsc), 1); + + l = GetSuperHighResolutionTimer(); + RAND_add(&l, sizeof(l), 0); + +# if defined(NETWARE_LIBC) + NXThreadYield(); +# else /* NETWARE_CLIB */ + ThreadSwitchWithDelay(); +# endif + } + + return 1; +} + +#endif diff --git a/libs/openssl/crypto/rand/rand_os2.c b/libs/openssl/crypto/rand/rand_os2.c new file mode 100644 index 00000000..706ab1e8 --- /dev/null +++ b/libs/openssl/crypto/rand/rand_os2.c @@ -0,0 +1,170 @@ +/* crypto/rand/rand_os2.c */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include +#include "rand_lcl.h" + +#ifdef OPENSSL_SYS_OS2 + +# define INCL_DOSPROCESS +# define INCL_DOSPROFILE +# define INCL_DOSMISC +# define INCL_DOSMODULEMGR +# include + +# define CMD_KI_RDCNT (0x63) + +typedef struct _CPUUTIL { + ULONG ulTimeLow; /* Low 32 bits of time stamp */ + ULONG ulTimeHigh; /* High 32 bits of time stamp */ + ULONG ulIdleLow; /* Low 32 bits of idle time */ + ULONG ulIdleHigh; /* High 32 bits of idle time */ + ULONG ulBusyLow; /* Low 32 bits of busy time */ + ULONG ulBusyHigh; /* High 32 bits of busy time */ + ULONG ulIntrLow; /* Low 32 bits of interrupt time */ + ULONG ulIntrHigh; /* High 32 bits of interrupt time */ +} CPUUTIL; + +# ifndef __KLIBC__ +APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1, + ULONG ulParm2, ULONG ulParm3) = NULL; +APIRET APIENTRY(*DosQuerySysState) (ULONG func, ULONG arg1, ULONG pid, + ULONG _res_, PVOID buf, ULONG bufsz) = + NULL; +# endif +HMODULE hDoscalls = 0; + +int RAND_poll(void) +{ + char failed_module[20]; + QWORD qwTime; + ULONG SysVars[QSV_FOREGROUND_PROCESS]; + + if (hDoscalls == 0) { + ULONG rc = + DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS", + &hDoscalls); + +# ifndef __KLIBC__ + if (rc == 0) { + rc = DosQueryProcAddr(hDoscalls, 976, NULL, + (PFN *) & DosPerfSysCall); + + if (rc) + DosPerfSysCall = NULL; + + rc = DosQueryProcAddr(hDoscalls, 368, NULL, + (PFN *) & DosQuerySysState); + + if (rc) + DosQuerySysState = NULL; + } +# endif + } + + /* Sample the hi-res timer, runs at around 1.1 MHz */ + DosTmrQueryTime(&qwTime); + RAND_add(&qwTime, sizeof(qwTime), 2); + + /* + * Sample a bunch of system variables, includes various process & memory + * statistics + */ + DosQuerySysInfo(1, QSV_FOREGROUND_PROCESS, SysVars, sizeof(SysVars)); + RAND_add(SysVars, sizeof(SysVars), 4); + + /* + * If available, sample CPU registers that count at CPU MHz Only fairly + * new CPUs (PPro & K6 onwards) & OS/2 versions support this + */ + if (DosPerfSysCall) { + CPUUTIL util; + + if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG) & util, 0, 0) == 0) { + RAND_add(&util, sizeof(util), 10); + } else { +# ifndef __KLIBC__ + DosPerfSysCall = NULL; +# endif + } + } + + /* + * DosQuerySysState() gives us a huge quantity of process, thread, memory + * & handle stats + */ + if (DosQuerySysState) { + char *buffer = OPENSSL_malloc(256 * 1024); + + if (!buffer) + return 0; + + if (DosQuerySysState(0x1F, 0, 0, 0, buffer, 256 * 1024) == 0) { + /* + * First 4 bytes in buffer is a pointer to the thread count there + * should be at least 1 byte of entropy per thread + */ + RAND_add(buffer, 256 * 1024, **(ULONG **) buffer); + } + + OPENSSL_free(buffer); + return 1; + } + + return 0; +} + +#endif /* OPENSSL_SYS_OS2 */ diff --git a/libs/openssl/crypto/rand/rand_unix.c b/libs/openssl/crypto/rand/rand_unix.c new file mode 100644 index 00000000..266111ed --- /dev/null +++ b/libs/openssl/crypto/rand/rand_unix.c @@ -0,0 +1,447 @@ +/* crypto/rand/rand_unix.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include + +#define USE_SOCKETS +#include "e_os.h" +#include "cryptlib.h" +#include +#include "rand_lcl.h" + +#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) + +# include +# include +# include +# include +# include +# include +# include +# if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually + * everywhere */ +# include +# endif +# include +# ifndef FD_SETSIZE +# define FD_SETSIZE (8*sizeof(fd_set)) +# endif + +# if defined(OPENSSL_SYS_VOS) + +/* + * The following algorithm repeatedly samples the real-time clock (RTC) to + * generate a sequence of unpredictable data. The algorithm relies upon the + * uneven execution speed of the code (due to factors such as cache misses, + * interrupts, bus activity, and scheduling) and upon the rather large + * relative difference between the speed of the clock and the rate at which + * it can be read. + * + * If this code is ported to an environment where execution speed is more + * constant or where the RTC ticks at a much slower rate, or the clock can be + * read with fewer instructions, it is likely that the results would be far + * more predictable. + * + * As a precaution, we generate 4 times the minimum required amount of seed + * data. + */ + +int RAND_poll(void) +{ + short int code; + gid_t curr_gid; + pid_t curr_pid; + uid_t curr_uid; + int i, k; + struct timespec ts; + unsigned char v; + +# ifdef OPENSSL_SYS_VOS_HPPA + long duration; + extern void s$sleep(long *_duration, short int *_code); +# else +# ifdef OPENSSL_SYS_VOS_IA32 + long long duration; + extern void s$sleep2(long long *_duration, short int *_code); +# else +# error "Unsupported Platform." +# endif /* OPENSSL_SYS_VOS_IA32 */ +# endif /* OPENSSL_SYS_VOS_HPPA */ + + /* + * Seed with the gid, pid, and uid, to ensure *some* variation between + * different processes. + */ + + curr_gid = getgid(); + RAND_add(&curr_gid, sizeof curr_gid, 1); + curr_gid = 0; + + curr_pid = getpid(); + RAND_add(&curr_pid, sizeof curr_pid, 1); + curr_pid = 0; + + curr_uid = getuid(); + RAND_add(&curr_uid, sizeof curr_uid, 1); + curr_uid = 0; + + for (i = 0; i < (ENTROPY_NEEDED * 4); i++) { + /* + * burn some cpu; hope for interrupts, cache collisions, bus + * interference, etc. + */ + for (k = 0; k < 99; k++) + ts.tv_nsec = random(); + +# ifdef OPENSSL_SYS_VOS_HPPA + /* sleep for 1/1024 of a second (976 us). */ + duration = 1; + s$sleep(&duration, &code); +# else +# ifdef OPENSSL_SYS_VOS_IA32 + /* sleep for 1/65536 of a second (15 us). */ + duration = 1; + s$sleep2(&duration, &code); +# endif /* OPENSSL_SYS_VOS_IA32 */ +# endif /* OPENSSL_SYS_VOS_HPPA */ + + /* get wall clock time. */ + clock_gettime(CLOCK_REALTIME, &ts); + + /* take 8 bits */ + v = (unsigned char)(ts.tv_nsec % 256); + RAND_add(&v, sizeof v, 1); + v = 0; + } + return 1; +} +# elif defined __OpenBSD__ +int RAND_poll(void) +{ + u_int32_t rnd = 0, i; + unsigned char buf[ENTROPY_NEEDED]; + + for (i = 0; i < sizeof(buf); i++) { + if (i % 4 == 0) + rnd = arc4random(); + buf[i] = rnd; + rnd >>= 8; + } + RAND_add(buf, sizeof(buf), ENTROPY_NEEDED); + memset(buf, 0, sizeof(buf)); + + return 1; +} +# else /* !defined(__OpenBSD__) */ +int RAND_poll(void) +{ + unsigned long l; + pid_t curr_pid = getpid(); +# if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) + unsigned char tmpbuf[ENTROPY_NEEDED]; + int n = 0; +# endif +# ifdef DEVRANDOM + static const char *randomfiles[] = { DEVRANDOM }; + struct stat randomstats[sizeof(randomfiles) / sizeof(randomfiles[0])]; + int fd; + unsigned int i; +# endif +# ifdef DEVRANDOM_EGD + static const char *egdsockets[] = { DEVRANDOM_EGD, NULL }; + const char **egdsocket = NULL; +# endif + +# ifdef DEVRANDOM + memset(randomstats, 0, sizeof(randomstats)); + /* + * Use a random entropy pool device. Linux, FreeBSD and OpenBSD have + * this. Use /dev/urandom if you can as /dev/random may block if it runs + * out of random entries. + */ + + for (i = 0; (i < sizeof(randomfiles) / sizeof(randomfiles[0])) && + (n < ENTROPY_NEEDED); i++) { + if ((fd = open(randomfiles[i], O_RDONLY +# ifdef O_NONBLOCK + | O_NONBLOCK +# endif +# ifdef O_BINARY + | O_BINARY +# endif +# ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do + * not make it our controlling tty */ + | O_NOCTTY +# endif + )) >= 0) { + int usec = 10 * 1000; /* spend 10ms on each file */ + int r; + unsigned int j; + struct stat *st = &randomstats[i]; + + /* + * Avoid using same input... Used to be O_NOFOLLOW above, but + * it's not universally appropriate... + */ + if (fstat(fd, st) != 0) { + close(fd); + continue; + } + for (j = 0; j < i; j++) { + if (randomstats[j].st_ino == st->st_ino && + randomstats[j].st_dev == st->st_dev) + break; + } + if (j < i) { + close(fd); + continue; + } + + do { + int try_read = 0; + +# if defined(OPENSSL_SYS_BEOS_R5) + /* + * select() is broken in BeOS R5, so we simply try to read + * something and snooze if we couldn't + */ + try_read = 1; + +# elif defined(OPENSSL_SYS_LINUX) + /* use poll() */ + struct pollfd pset; + + pset.fd = fd; + pset.events = POLLIN; + pset.revents = 0; + + if (poll(&pset, 1, usec / 1000) < 0) + usec = 0; + else + try_read = (pset.revents & POLLIN) != 0; + +# else + /* use select() */ + fd_set fset; + struct timeval t; + + t.tv_sec = 0; + t.tv_usec = usec; + + if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE) { + /* + * can't use select, so just try to read once anyway + */ + try_read = 1; + } else { + FD_ZERO(&fset); + FD_SET(fd, &fset); + + if (select(fd + 1, &fset, NULL, NULL, &t) >= 0) { + usec = t.tv_usec; + if (FD_ISSET(fd, &fset)) + try_read = 1; + } else + usec = 0; + } +# endif + + if (try_read) { + r = read(fd, (unsigned char *)tmpbuf + n, + ENTROPY_NEEDED - n); + if (r > 0) + n += r; +# if defined(OPENSSL_SYS_BEOS_R5) + if (r == 0) + snooze(t.tv_usec); +# endif + } else + r = -1; + + /* + * Some Unixen will update t in select(), some won't. For + * those who won't, or if we didn't use select() in the first + * place, give up here, otherwise, we will do this once again + * for the remaining time. + */ + if (usec == 10 * 1000) + usec = 0; + } + while ((r > 0 || + (errno == EINTR || errno == EAGAIN)) && usec != 0 + && n < ENTROPY_NEEDED); + + close(fd); + } + } +# endif /* defined(DEVRANDOM) */ + +# ifdef DEVRANDOM_EGD + /* + * Use an EGD socket to read entropy from an EGD or PRNGD entropy + * collecting daemon. + */ + + for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED; + egdsocket++) { + int r; + + r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf + n, + ENTROPY_NEEDED - n); + if (r > 0) + n += r; + } +# endif /* defined(DEVRANDOM_EGD) */ + +# if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) + if (n > 0) { + RAND_add(tmpbuf, sizeof tmpbuf, (double)n); + OPENSSL_cleanse(tmpbuf, n); + } +# endif + + /* put in some default random data, we need more than just this */ + l = curr_pid; + RAND_add(&l, sizeof(l), 0.0); + l = getuid(); + RAND_add(&l, sizeof(l), 0.0); + + l = time(NULL); + RAND_add(&l, sizeof(l), 0.0); + +# if defined(OPENSSL_SYS_BEOS) + { + system_info sysInfo; + get_system_info(&sysInfo); + RAND_add(&sysInfo, sizeof(sysInfo), 0); + } +# endif + +# if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) + return 1; +# else + return 0; +# endif +} + +# endif /* defined(__OpenBSD__) */ +#endif /* !(defined(OPENSSL_SYS_WINDOWS) || + * defined(OPENSSL_SYS_WIN32) || + * defined(OPENSSL_SYS_VMS) || + * defined(OPENSSL_SYS_OS2) || + * defined(OPENSSL_SYS_VXWORKS) || + * defined(OPENSSL_SYS_NETWARE)) */ + +#if defined(OPENSSL_SYS_VXWORKS) +int RAND_poll(void) +{ + return 0; +} +#endif diff --git a/libs/openssl/crypto/rand/rand_vms.c b/libs/openssl/crypto/rand/rand_vms.c new file mode 100644 index 00000000..0e10c363 --- /dev/null +++ b/libs/openssl/crypto/rand/rand_vms.c @@ -0,0 +1,159 @@ +/* crypto/rand/rand_vms.c */ +/* + * Written by Richard Levitte for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "rand_lcl.h" + +#if defined(OPENSSL_SYS_VMS) + +# include +# include +# include +# include +# ifdef __DECC +# pragma message disable DOLLARID +# endif + +/* + * Use 32-bit pointers almost everywhere. Define the type to which to cast a + * pointer passed to an external function. + */ +# if __INITIAL_POINTER_SIZE == 64 +# define PTR_T __void_ptr64 +# pragma pointer_size save +# pragma pointer_size 32 +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define PTR_T void * +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + +static struct items_data_st { + short length, code; /* length is amount of bytes */ +} items_data[] = { + { + 4, JPI$_BUFIO + }, + { + 4, JPI$_CPUTIM + }, + { + 4, JPI$_DIRIO + }, + { + 8, JPI$_LOGINTIM + }, + { + 4, JPI$_PAGEFLTS + }, + { + 4, JPI$_PID + }, + { + 4, JPI$_WSSIZE + }, + { + 0, 0 + } +}; + +int RAND_poll(void) +{ + long pid, iosb[2]; + int status = 0; + struct { + short length, code; + long *buffer; + int *retlen; + } item[32], *pitem; + unsigned char data_buffer[256]; + short total_length = 0; + struct items_data_st *pitems_data; + + pitems_data = items_data; + pitem = item; + + /* Setup */ + while (pitems_data->length && (total_length + pitems_data->length <= 256)) { + pitem->length = pitems_data->length; + pitem->code = pitems_data->code; + pitem->buffer = (long *)&data_buffer[total_length]; + pitem->retlen = 0; + total_length += pitems_data->length; + pitems_data++; + pitem ++; + } + pitem->length = pitem->code = 0; + + /* + * Scan through all the processes in the system and add entropy with + * results from the processes that were possible to look at. + * However, view the information as only half trustable. + */ + pid = -1; /* search context */ + while ((status = sys$getjpiw(0, &pid, 0, item, iosb, 0, 0)) + != SS$_NOMOREPROC) { + if (status == SS$_NORMAL) { + RAND_add((PTR_T) data_buffer, total_length, total_length / 2); + } + } + sys$gettim(iosb); + RAND_add((PTR_T) iosb, sizeof(iosb), sizeof(iosb) / 2); + return 1; +} + +#endif diff --git a/libs/openssl/crypto/rand/rand_win.c b/libs/openssl/crypto/rand/rand_win.c new file mode 100644 index 00000000..0c616c4c --- /dev/null +++ b/libs/openssl/crypto/rand/rand_win.c @@ -0,0 +1,751 @@ +/* crypto/rand/rand_win.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include +#include "rand_lcl.h" + +#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +# include +# ifndef _WIN32_WINNT +# define _WIN32_WINNT 0x0400 +# endif +# include +# include + +/* + * Limit the time spent walking through the heap, processes, threads and + * modules to a maximum of 1000 miliseconds each, unless CryptoGenRandom + * failed + */ +# define MAXDELAY 1000 + +/* + * Intel hardware RNG CSP -- available from + * http://developer.intel.com/design/security/rng/redist_license.htm + */ +# define PROV_INTEL_SEC 22 +# define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider" + +static void readtimer(void); +static void readscreen(void); + +/* + * It appears like CURSORINFO, PCURSORINFO and LPCURSORINFO are only defined + * when WINVER is 0x0500 and up, which currently only happens on Win2000. + * Unfortunately, those are typedefs, so they're a little bit difficult to + * detect properly. On the other hand, the macro CURSOR_SHOWING is defined + * within the same conditional, so it can be use to detect the absence of + * said typedefs. + */ + +# ifndef CURSOR_SHOWING +/* + * Information about the global cursor. + */ +typedef struct tagCURSORINFO { + DWORD cbSize; + DWORD flags; + HCURSOR hCursor; + POINT ptScreenPos; +} CURSORINFO, *PCURSORINFO, *LPCURSORINFO; + +# define CURSOR_SHOWING 0x00000001 +# endif /* CURSOR_SHOWING */ + +# if !defined(OPENSSL_SYS_WINCE) +typedef BOOL(WINAPI *CRYPTACQUIRECONTEXTW) (HCRYPTPROV *, LPCWSTR, LPCWSTR, + DWORD, DWORD); +typedef BOOL(WINAPI *CRYPTGENRANDOM) (HCRYPTPROV, DWORD, BYTE *); +typedef BOOL(WINAPI *CRYPTRELEASECONTEXT) (HCRYPTPROV, DWORD); + +typedef HWND(WINAPI *GETFOREGROUNDWINDOW) (VOID); +typedef BOOL(WINAPI *GETCURSORINFO) (PCURSORINFO); +typedef DWORD(WINAPI *GETQUEUESTATUS) (UINT); + +typedef HANDLE(WINAPI *CREATETOOLHELP32SNAPSHOT) (DWORD, DWORD); +typedef BOOL(WINAPI *CLOSETOOLHELP32SNAPSHOT) (HANDLE); +typedef BOOL(WINAPI *HEAP32FIRST) (LPHEAPENTRY32, DWORD, size_t); +typedef BOOL(WINAPI *HEAP32NEXT) (LPHEAPENTRY32); +typedef BOOL(WINAPI *HEAP32LIST) (HANDLE, LPHEAPLIST32); +typedef BOOL(WINAPI *PROCESS32) (HANDLE, LPPROCESSENTRY32); +typedef BOOL(WINAPI *THREAD32) (HANDLE, LPTHREADENTRY32); +typedef BOOL(WINAPI *MODULE32) (HANDLE, LPMODULEENTRY32); + +# include +# include +# if 1 +/* + * The NET API is Unicode only. It requires the use of the UNICODE macro. + * When UNICODE is defined LPTSTR becomes LPWSTR. LMSTR was was added to the + * Platform SDK to allow the NET API to be used in non-Unicode applications + * provided that Unicode strings were still used for input. LMSTR is defined + * as LPWSTR. + */ +typedef NET_API_STATUS(NET_API_FUNCTION *NETSTATGET) + (LPWSTR, LPWSTR, DWORD, DWORD, LPBYTE *); +typedef NET_API_STATUS(NET_API_FUNCTION *NETFREE) (LPBYTE); +# endif /* 1 */ +# endif /* !OPENSSL_SYS_WINCE */ + +int RAND_poll(void) +{ + MEMORYSTATUS m; + HCRYPTPROV hProvider = 0; + DWORD w; + int good = 0; + +# if defined(OPENSSL_SYS_WINCE) +# if defined(_WIN32_WCE) && _WIN32_WCE>=300 + /* + * Even though MSDN says _WIN32_WCE>=210, it doesn't seem to be available + * in commonly available implementations prior 300... + */ + { + BYTE buf[64]; + /* poll the CryptoAPI PRNG */ + /* The CryptoAPI returns sizeof(buf) bytes of randomness */ + if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) { + if (CryptGenRandom(hProvider, sizeof(buf), buf)) + RAND_add(buf, sizeof(buf), sizeof(buf)); + CryptReleaseContext(hProvider, 0); + } + } +# endif +# else /* OPENSSL_SYS_WINCE */ + /* + * None of below libraries are present on Windows CE, which is + * why we #ifndef the whole section. This also excuses us from + * handling the GetProcAddress issue. The trouble is that in + * real Win32 API GetProcAddress is available in ANSI flavor + * only. In WinCE on the other hand GetProcAddress is a macro + * most commonly defined as GetProcAddressW, which accepts + * Unicode argument. If we were to call GetProcAddress under + * WinCE, I'd recommend to either redefine GetProcAddress as + * GetProcAddressA (there seem to be one in common CE spec) or + * implement own shim routine, which would accept ANSI argument + * and expand it to Unicode. + */ + { + /* load functions dynamically - not available on all systems */ + HMODULE advapi = LoadLibrary(TEXT("ADVAPI32.DLL")); + HMODULE kernel = LoadLibrary(TEXT("KERNEL32.DLL")); + HMODULE user = NULL; + HMODULE netapi = LoadLibrary(TEXT("NETAPI32.DLL")); + CRYPTACQUIRECONTEXTW acquire = NULL; + CRYPTGENRANDOM gen = NULL; + CRYPTRELEASECONTEXT release = NULL; + NETSTATGET netstatget = NULL; + NETFREE netfree = NULL; + BYTE buf[64]; + + if (netapi) { + netstatget = + (NETSTATGET) GetProcAddress(netapi, "NetStatisticsGet"); + netfree = (NETFREE) GetProcAddress(netapi, "NetApiBufferFree"); + } + + if (netstatget && netfree) { + LPBYTE outbuf; + /* + * NetStatisticsGet() is a Unicode only function + * STAT_WORKSTATION_0 contains 45 fields and STAT_SERVER_0 + * contains 17 fields. We treat each field as a source of one + * byte of entropy. + */ + + if (netstatget(NULL, L"LanmanWorkstation", 0, 0, &outbuf) == 0) { + RAND_add(outbuf, sizeof(STAT_WORKSTATION_0), 45); + netfree(outbuf); + } + if (netstatget(NULL, L"LanmanServer", 0, 0, &outbuf) == 0) { + RAND_add(outbuf, sizeof(STAT_SERVER_0), 17); + netfree(outbuf); + } + } + + if (netapi) + FreeLibrary(netapi); + + /* + * It appears like this can cause an exception deep within + * ADVAPI32.DLL at random times on Windows 2000. Reported by Jeffrey + * Altman. Only use it on NT. + */ + + if (advapi) { + /* + * If it's available, then it's available in both ANSI + * and UNICODE flavors even in Win9x, documentation says. + * We favor Unicode... + */ + acquire = (CRYPTACQUIRECONTEXTW) GetProcAddress(advapi, + "CryptAcquireContextW"); + gen = (CRYPTGENRANDOM) GetProcAddress(advapi, "CryptGenRandom"); + release = (CRYPTRELEASECONTEXT) GetProcAddress(advapi, + "CryptReleaseContext"); + } + + if (acquire && gen && release) { + /* poll the CryptoAPI PRNG */ + /* The CryptoAPI returns sizeof(buf) bytes of randomness */ + if (acquire(&hProvider, NULL, NULL, PROV_RSA_FULL, + CRYPT_VERIFYCONTEXT)) { + if (gen(hProvider, sizeof(buf), buf) != 0) { + RAND_add(buf, sizeof(buf), 0); + good = 1; +# if 0 + printf("randomness from PROV_RSA_FULL\n"); +# endif + } + release(hProvider, 0); + } + + /* poll the Pentium PRG with CryptoAPI */ + if (acquire(&hProvider, 0, INTEL_DEF_PROV, PROV_INTEL_SEC, 0)) { + if (gen(hProvider, sizeof(buf), buf) != 0) { + RAND_add(buf, sizeof(buf), sizeof(buf)); + good = 1; +# if 0 + printf("randomness from PROV_INTEL_SEC\n"); +# endif + } + release(hProvider, 0); + } + } + + if (advapi) + FreeLibrary(advapi); + + if ((!check_winnt() || + !OPENSSL_isservice()) && + (user = LoadLibrary(TEXT("USER32.DLL")))) { + GETCURSORINFO cursor; + GETFOREGROUNDWINDOW win; + GETQUEUESTATUS queue; + + win = + (GETFOREGROUNDWINDOW) GetProcAddress(user, + "GetForegroundWindow"); + cursor = (GETCURSORINFO) GetProcAddress(user, "GetCursorInfo"); + queue = (GETQUEUESTATUS) GetProcAddress(user, "GetQueueStatus"); + + if (win) { + /* window handle */ + HWND h = win(); + RAND_add(&h, sizeof(h), 0); + } + if (cursor) { + /* + * unfortunately, its not safe to call GetCursorInfo() on NT4 + * even though it exists in SP3 (or SP6) and higher. + */ + if (check_winnt() && !check_win_minplat(5)) + cursor = 0; + } + if (cursor) { + /* cursor position */ + /* assume 2 bytes of entropy */ + CURSORINFO ci; + ci.cbSize = sizeof(CURSORINFO); + if (cursor(&ci)) + RAND_add(&ci, ci.cbSize, 2); + } + + if (queue) { + /* message queue status */ + /* assume 1 byte of entropy */ + w = queue(QS_ALLEVENTS); + RAND_add(&w, sizeof(w), 1); + } + + FreeLibrary(user); + } + + /*- + * Toolhelp32 snapshot: enumerate processes, threads, modules and heap + * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm + * (Win 9x and 2000 only, not available on NT) + * + * This seeding method was proposed in Peter Gutmann, Software + * Generation of Practically Strong Random Numbers, + * http://www.usenix.org/publications/library/proceedings/sec98/gutmann.html + * revised version at http://www.cryptoengines.com/~peter/06_random.pdf + * (The assignment of entropy estimates below is arbitrary, but based + * on Peter's analysis the full poll appears to be safe. Additional + * interactive seeding is encouraged.) + */ + + if (kernel) { + CREATETOOLHELP32SNAPSHOT snap; + CLOSETOOLHELP32SNAPSHOT close_snap; + HANDLE handle; + + HEAP32FIRST heap_first; + HEAP32NEXT heap_next; + HEAP32LIST heaplist_first, heaplist_next; + PROCESS32 process_first, process_next; + THREAD32 thread_first, thread_next; + MODULE32 module_first, module_next; + + HEAPLIST32 hlist; + HEAPENTRY32 hentry; + PROCESSENTRY32 p; + THREADENTRY32 t; + MODULEENTRY32 m; + DWORD starttime = 0; + + snap = (CREATETOOLHELP32SNAPSHOT) + GetProcAddress(kernel, "CreateToolhelp32Snapshot"); + close_snap = (CLOSETOOLHELP32SNAPSHOT) + GetProcAddress(kernel, "CloseToolhelp32Snapshot"); + heap_first = (HEAP32FIRST) GetProcAddress(kernel, "Heap32First"); + heap_next = (HEAP32NEXT) GetProcAddress(kernel, "Heap32Next"); + heaplist_first = + (HEAP32LIST) GetProcAddress(kernel, "Heap32ListFirst"); + heaplist_next = + (HEAP32LIST) GetProcAddress(kernel, "Heap32ListNext"); + process_first = + (PROCESS32) GetProcAddress(kernel, "Process32First"); + process_next = + (PROCESS32) GetProcAddress(kernel, "Process32Next"); + thread_first = (THREAD32) GetProcAddress(kernel, "Thread32First"); + thread_next = (THREAD32) GetProcAddress(kernel, "Thread32Next"); + module_first = (MODULE32) GetProcAddress(kernel, "Module32First"); + module_next = (MODULE32) GetProcAddress(kernel, "Module32Next"); + + if (snap && heap_first && heap_next && heaplist_first && + heaplist_next && process_first && process_next && + thread_first && thread_next && module_first && + module_next && (handle = snap(TH32CS_SNAPALL, 0)) + != INVALID_HANDLE_VALUE) { + /* heap list and heap walking */ + /* + * HEAPLIST32 contains 3 fields that will change with each + * entry. Consider each field a source of 1 byte of entropy. + * HEAPENTRY32 contains 5 fields that will change with each + * entry. Consider each field a source of 1 byte of entropy. + */ + ZeroMemory(&hlist, sizeof(HEAPLIST32)); + hlist.dwSize = sizeof(HEAPLIST32); + if (good) + starttime = GetTickCount(); +# ifdef _MSC_VER + if (heaplist_first(handle, &hlist)) { + /* + * following discussion on dev ML, exception on WinCE (or + * other Win platform) is theoretically of unknown + * origin; prevent infinite loop here when this + * theoretical case occurs; otherwise cope with the + * expected (MSDN documented) exception-throwing + * behaviour of Heap32Next() on WinCE. + * + * based on patch in original message by Tanguy Fautré + * (2009/03/02) Subject: RAND_poll() and + * CreateToolhelp32Snapshot() stability + */ + int ex_cnt_limit = 42; + do { + RAND_add(&hlist, hlist.dwSize, 3); + __try { + ZeroMemory(&hentry, sizeof(HEAPENTRY32)); + hentry.dwSize = sizeof(HEAPENTRY32); + if (heap_first(&hentry, + hlist.th32ProcessID, + hlist.th32HeapID)) { + int entrycnt = 80; + do + RAND_add(&hentry, hentry.dwSize, 5); + while (heap_next(&hentry) + && (!good + || (GetTickCount() - starttime) < + MAXDELAY) + && --entrycnt > 0); + } + } + __except(EXCEPTION_EXECUTE_HANDLER) { + /* + * ignore access violations when walking the heap + * list + */ + ex_cnt_limit--; + } + } while (heaplist_next(handle, &hlist) + && (!good + || (GetTickCount() - starttime) < MAXDELAY) + && ex_cnt_limit > 0); + } +# else + if (heaplist_first(handle, &hlist)) { + do { + RAND_add(&hlist, hlist.dwSize, 3); + hentry.dwSize = sizeof(HEAPENTRY32); + if (heap_first(&hentry, + hlist.th32ProcessID, + hlist.th32HeapID)) { + int entrycnt = 80; + do + RAND_add(&hentry, hentry.dwSize, 5); + while (heap_next(&hentry) + && --entrycnt > 0); + } + } while (heaplist_next(handle, &hlist) + && (!good + || (GetTickCount() - starttime) < MAXDELAY)); + } +# endif + + /* process walking */ + /* + * PROCESSENTRY32 contains 9 fields that will change with + * each entry. Consider each field a source of 1 byte of + * entropy. + */ + p.dwSize = sizeof(PROCESSENTRY32); + + if (good) + starttime = GetTickCount(); + if (process_first(handle, &p)) + do + RAND_add(&p, p.dwSize, 9); + while (process_next(handle, &p) + && (!good + || (GetTickCount() - starttime) < MAXDELAY)); + + /* thread walking */ + /* + * THREADENTRY32 contains 6 fields that will change with each + * entry. Consider each field a source of 1 byte of entropy. + */ + t.dwSize = sizeof(THREADENTRY32); + if (good) + starttime = GetTickCount(); + if (thread_first(handle, &t)) + do + RAND_add(&t, t.dwSize, 6); + while (thread_next(handle, &t) + && (!good + || (GetTickCount() - starttime) < MAXDELAY)); + + /* module walking */ + /* + * MODULEENTRY32 contains 9 fields that will change with each + * entry. Consider each field a source of 1 byte of entropy. + */ + m.dwSize = sizeof(MODULEENTRY32); + if (good) + starttime = GetTickCount(); + if (module_first(handle, &m)) + do + RAND_add(&m, m.dwSize, 9); + while (module_next(handle, &m) + && (!good + || (GetTickCount() - starttime) < MAXDELAY)); + if (close_snap) + close_snap(handle); + else + CloseHandle(handle); + + } + + FreeLibrary(kernel); + } + } +# endif /* !OPENSSL_SYS_WINCE */ + + /* timer data */ + readtimer(); + + /* memory usage statistics */ + GlobalMemoryStatus(&m); + RAND_add(&m, sizeof(m), 1); + + /* process ID */ + w = GetCurrentProcessId(); + RAND_add(&w, sizeof(w), 1); + +# if 0 + printf("Exiting RAND_poll\n"); +# endif + + return (1); +} + +int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam) +{ + double add_entropy = 0; + + switch (iMsg) { + case WM_KEYDOWN: + { + static WPARAM key; + if (key != wParam) + add_entropy = 0.05; + key = wParam; + } + break; + case WM_MOUSEMOVE: + { + static int lastx, lasty, lastdx, lastdy; + int x, y, dx, dy; + + x = LOWORD(lParam); + y = HIWORD(lParam); + dx = lastx - x; + dy = lasty - y; + if (dx != 0 && dy != 0 && dx - lastdx != 0 && dy - lastdy != 0) + add_entropy = .2; + lastx = x, lasty = y; + lastdx = dx, lastdy = dy; + } + break; + } + + readtimer(); + RAND_add(&iMsg, sizeof(iMsg), add_entropy); + RAND_add(&wParam, sizeof(wParam), 0); + RAND_add(&lParam, sizeof(lParam), 0); + + return (RAND_status()); +} + +void RAND_screen(void) +{ /* function available for backward + * compatibility */ + RAND_poll(); + readscreen(); +} + +/* feed timing information to the PRNG */ +static void readtimer(void) +{ + DWORD w; + LARGE_INTEGER l; + static int have_perfc = 1; +# if defined(_MSC_VER) && defined(_M_X86) + static int have_tsc = 1; + DWORD cyclecount; + + if (have_tsc) { + __try { + __asm { + _emit 0x0f _emit 0x31 mov cyclecount, eax} + RAND_add(&cyclecount, sizeof(cyclecount), 1); + } + __except(EXCEPTION_EXECUTE_HANDLER) { + have_tsc = 0; + } + } +# else +# define have_tsc 0 +# endif + + if (have_perfc) { + if (QueryPerformanceCounter(&l) == 0) + have_perfc = 0; + else + RAND_add(&l, sizeof(l), 0); + } + + if (!have_tsc && !have_perfc) { + w = GetTickCount(); + RAND_add(&w, sizeof(w), 0); + } +} + +/* feed screen contents to PRNG */ +/***************************************************************************** + * + * Created 960901 by Gertjan van Oosten, gertjan@West.NL, West Consulting B.V. + * + * Code adapted from + * ; + * the original copyright message is: + * + * (C) Copyright Microsoft Corp. 1993. All rights reserved. + * + * You have a royalty-free right to use, modify, reproduce and + * distribute the Sample Files (and/or any modified version) in + * any way you find useful, provided that you agree that + * Microsoft has no warranty obligations or liability for any + * Sample Application Files which are modified. + */ + +static void readscreen(void) +{ +# if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN) + HDC hScrDC; /* screen DC */ + HDC hMemDC; /* memory DC */ + HBITMAP hBitmap; /* handle for our bitmap */ + HBITMAP hOldBitmap; /* handle for previous bitmap */ + BITMAP bm; /* bitmap properties */ + unsigned int size; /* size of bitmap */ + char *bmbits; /* contents of bitmap */ + int w; /* screen width */ + int h; /* screen height */ + int y; /* y-coordinate of screen lines to grab */ + int n = 16; /* number of screen lines to grab at a time */ + + if (check_winnt() && OPENSSL_isservice() > 0) + return; + + /* Create a screen DC and a memory DC compatible to screen DC */ + hScrDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL); + hMemDC = CreateCompatibleDC(hScrDC); + + /* Get screen resolution */ + w = GetDeviceCaps(hScrDC, HORZRES); + h = GetDeviceCaps(hScrDC, VERTRES); + + /* Create a bitmap compatible with the screen DC */ + hBitmap = CreateCompatibleBitmap(hScrDC, w, n); + + /* Select new bitmap into memory DC */ + hOldBitmap = SelectObject(hMemDC, hBitmap); + + /* Get bitmap properties */ + GetObject(hBitmap, sizeof(BITMAP), (LPSTR) & bm); + size = (unsigned int)bm.bmWidthBytes * bm.bmHeight * bm.bmPlanes; + + bmbits = OPENSSL_malloc(size); + if (bmbits) { + /* Now go through the whole screen, repeatedly grabbing n lines */ + for (y = 0; y < h - n; y += n) { + unsigned char md[MD_DIGEST_LENGTH]; + + /* Bitblt screen DC to memory DC */ + BitBlt(hMemDC, 0, 0, w, n, hScrDC, 0, y, SRCCOPY); + + /* Copy bitmap bits from memory DC to bmbits */ + GetBitmapBits(hBitmap, size, bmbits); + + /* Get the hash of the bitmap */ + MD(bmbits, size, md); + + /* Seed the random generator with the hash value */ + RAND_add(md, MD_DIGEST_LENGTH, 0); + } + + OPENSSL_free(bmbits); + } + + /* Select old bitmap back into memory DC */ + hBitmap = SelectObject(hMemDC, hOldBitmap); + + /* Clean up */ + DeleteObject(hBitmap); + DeleteDC(hMemDC); + DeleteDC(hScrDC); +# endif /* !OPENSSL_SYS_WINCE */ +} + +#endif diff --git a/libs/openssl/crypto/rand/randfile.c b/libs/openssl/crypto/rand/randfile.c new file mode 100644 index 00000000..9537c56a --- /dev/null +++ b/libs/openssl/crypto/rand/randfile.c @@ -0,0 +1,337 @@ +/* crypto/rand/randfile.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* We need to define this to get macros like S_IFBLK and S_IFCHR */ +#if !defined(OPENSSL_SYS_VXWORKS) +# define _XOPEN_SOURCE 500 +#endif + +#include +#include +#include +#include + +#include "e_os.h" +#include +#include +#include + +#ifdef OPENSSL_SYS_VMS +# include +#endif +#ifndef NO_SYS_TYPES_H +# include +#endif +#ifndef OPENSSL_NO_POSIX_IO +# include +# include +#endif + +#ifdef _WIN32 +# define stat _stat +# define chmod _chmod +# define open _open +# define fdopen _fdopen +#endif + +#undef BUFSIZE +#define BUFSIZE 1024 +#define RAND_DATA 1024 + +#ifdef OPENSSL_SYS_VMS +/* + * This declaration is a nasty hack to get around vms' extension to fopen for + * passing in sharing options being disabled by our /STANDARD=ANSI89 + */ +static FILE *(*const vms_fopen)(const char *, const char *, ...) = + (FILE *(*)(const char *, const char *, ...))fopen; +# define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0" +#endif + +/* #define RFILE ".rnd" - defined in ../../e_os.h */ + +/* + * Note that these functions are intended for seed files only. Entropy + * devices and EGD sockets are handled in rand_unix.c + */ + +int RAND_load_file(const char *file, long bytes) +{ + /*- + * If bytes >= 0, read up to 'bytes' bytes. + * if bytes == -1, read complete file. + */ + + MS_STATIC unsigned char buf[BUFSIZE]; +#ifndef OPENSSL_NO_POSIX_IO + struct stat sb; +#endif + int i, ret = 0, n; + FILE *in; + + if (file == NULL) + return (0); + +#ifndef OPENSSL_NO_POSIX_IO +# ifdef PURIFY + /* + * struct stat can have padding and unused fields that may not be + * initialized in the call to stat(). We need to clear the entire + * structure before calling RAND_add() to avoid complaints from + * applications such as Valgrind. + */ + memset(&sb, 0, sizeof(sb)); +# endif + if (stat(file, &sb) < 0) + return (0); + RAND_add(&sb, sizeof(sb), 0.0); +#endif + if (bytes == 0) + return (ret); + +#ifdef OPENSSL_SYS_VMS + in = vms_fopen(file, "rb", VMS_OPEN_ATTRS); +#else + in = fopen(file, "rb"); +#endif + if (in == NULL) + goto err; +#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_NO_POSIX_IO) + if (sb.st_mode & (S_IFBLK | S_IFCHR)) { + /* + * this file is a device. we don't want read an infinite number of + * bytes from a random device, nor do we want to use buffered I/O + * because we will waste system entropy. + */ + bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */ +# ifndef OPENSSL_NO_SETVBUF_IONBF + setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */ +# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */ + } +#endif + for (;;) { + if (bytes > 0) + n = (bytes < BUFSIZE) ? (int)bytes : BUFSIZE; + else + n = BUFSIZE; + i = fread(buf, 1, n, in); + if (i <= 0) + break; +#ifdef PURIFY + RAND_add(buf, i, (double)i); +#else + /* even if n != i, use the full array */ + RAND_add(buf, n, (double)i); +#endif + ret += i; + if (bytes > 0) { + bytes -= n; + if (bytes <= 0) + break; + } + } + fclose(in); + OPENSSL_cleanse(buf, BUFSIZE); + err: + return (ret); +} + +int RAND_write_file(const char *file) +{ + unsigned char buf[BUFSIZE]; + int i, ret = 0, rand_err = 0; + FILE *out = NULL; + int n; +#ifndef OPENSSL_NO_POSIX_IO + struct stat sb; + + i = stat(file, &sb); + if (i != -1) { +# if defined(S_ISBLK) && defined(S_ISCHR) + if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { + /* + * this file is a device. we don't write back to it. we + * "succeed" on the assumption this is some sort of random + * device. Otherwise attempting to write to and chmod the device + * causes problems. + */ + return (1); + } +# endif + } +#endif + +#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS) + { +# ifndef O_BINARY +# define O_BINARY 0 +# endif + /* + * chmod(..., 0600) is too late to protect the file, permissions + * should be restrictive from the start + */ + int fd = open(file, O_WRONLY | O_CREAT | O_BINARY, 0600); + if (fd != -1) + out = fdopen(fd, "wb"); + } +#endif + +#ifdef OPENSSL_SYS_VMS + /* + * VMS NOTE: Prior versions of this routine created a _new_ version of + * the rand file for each call into this routine, then deleted all + * existing versions named ;-1, and finally renamed the current version + * as ';1'. Under concurrent usage, this resulted in an RMS race + * condition in rename() which could orphan files (see vms message help + * for RMS$_REENT). With the fopen() calls below, openssl/VMS now shares + * the top-level version of the rand file. Note that there may still be + * conditions where the top-level rand file is locked. If so, this code + * will then create a new version of the rand file. Without the delete + * and rename code, this can result in ascending file versions that stop + * at version 32767, and this routine will then return an error. The + * remedy for this is to recode the calling application to avoid + * concurrent use of the rand file, or synchronize usage at the + * application level. Also consider whether or not you NEED a persistent + * rand file in a concurrent use situation. + */ + + out = vms_fopen(file, "rb+", VMS_OPEN_ATTRS); + if (out == NULL) + out = vms_fopen(file, "wb", VMS_OPEN_ATTRS); +#else + if (out == NULL) + out = fopen(file, "wb"); +#endif + if (out == NULL) + goto err; + +#ifndef NO_CHMOD + chmod(file, 0600); +#endif + n = RAND_DATA; + for (;;) { + i = (n > BUFSIZE) ? BUFSIZE : n; + n -= BUFSIZE; + if (RAND_bytes(buf, i) <= 0) + rand_err = 1; + i = fwrite(buf, 1, i, out); + if (i <= 0) { + ret = 0; + break; + } + ret += i; + if (n <= 0) + break; + } + + fclose(out); + OPENSSL_cleanse(buf, BUFSIZE); + err: + return (rand_err ? -1 : ret); +} + +const char *RAND_file_name(char *buf, size_t size) +{ + char *s = NULL; +#ifdef __OpenBSD__ + struct stat sb; +#endif + + if (OPENSSL_issetugid() == 0) + s = getenv("RANDFILE"); + if (s != NULL && *s && strlen(s) + 1 < size) { + if (BUF_strlcpy(buf, s, size) >= size) + return NULL; + } else { + if (OPENSSL_issetugid() == 0) + s = getenv("HOME"); +#ifdef DEFAULT_HOME + if (s == NULL) { + s = DEFAULT_HOME; + } +#endif + if (s && *s && strlen(s) + strlen(RFILE) + 2 < size) { + BUF_strlcpy(buf, s, size); +#ifndef OPENSSL_SYS_VMS + BUF_strlcat(buf, "/", size); +#endif + BUF_strlcat(buf, RFILE, size); + } else + buf[0] = '\0'; /* no file name */ + } + +#ifdef __OpenBSD__ + /* + * given that all random loads just fail if the file can't be seen on a + * stat, we stat the file we're returning, if it fails, use /dev/arandom + * instead. this allows the user to use their own source for good random + * data, but defaults to something hopefully decent if that isn't + * available. + */ + + if (!buf[0]) + if (BUF_strlcpy(buf, "/dev/arandom", size) >= size) { + return (NULL); + } + if (stat(buf, &sb) == -1) + if (BUF_strlcpy(buf, "/dev/arandom", size) >= size) { + return (NULL); + } +#endif + return (buf); +} diff --git a/libs/openssl/crypto/rand/randtest.c b/libs/openssl/crypto/rand/randtest.c new file mode 100644 index 00000000..91bcac99 --- /dev/null +++ b/libs/openssl/crypto/rand/randtest.c @@ -0,0 +1,209 @@ +/* crypto/rand/randtest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "../e_os.h" + +/* some FIPS 140-1 random number test */ +/* some simple tests */ + +int main(int argc, char **argv) +{ + unsigned char buf[2500]; + int i, j, k, s, sign, nsign, err = 0; + unsigned long n1; + unsigned long n2[16]; + unsigned long runs[2][34]; + /* + * double d; + */ + long d; + + i = RAND_pseudo_bytes(buf, 2500); + if (i < 0) { + printf("init failed, the rand method is not properly installed\n"); + err++; + goto err; + } + + n1 = 0; + for (i = 0; i < 16; i++) + n2[i] = 0; + for (i = 0; i < 34; i++) + runs[0][i] = runs[1][i] = 0; + + /* test 1 and 2 */ + sign = 0; + nsign = 0; + for (i = 0; i < 2500; i++) { + j = buf[i]; + + n2[j & 0x0f]++; + n2[(j >> 4) & 0x0f]++; + + for (k = 0; k < 8; k++) { + s = (j & 0x01); + if (s == sign) + nsign++; + else { + if (nsign > 34) + nsign = 34; + if (nsign != 0) { + runs[sign][nsign - 1]++; + if (nsign > 6) + runs[sign][5]++; + } + sign = s; + nsign = 1; + } + + if (s) + n1++; + j >>= 1; + } + } + if (nsign > 34) + nsign = 34; + if (nsign != 0) + runs[sign][nsign - 1]++; + + /* test 1 */ + if (!((9654 < n1) && (n1 < 10346))) { + printf("test 1 failed, X=%lu\n", n1); + err++; + } + printf("test 1 done\n"); + + /* test 2 */ +#ifdef undef + d = 0; + for (i = 0; i < 16; i++) + d += n2[i] * n2[i]; + d = d * 16.0 / 5000.0 - 5000.0; + if (!((1.03 < d) && (d < 57.4))) { + printf("test 2 failed, X=%.2f\n", d); + err++; + } +#endif + d = 0; + for (i = 0; i < 16; i++) + d += n2[i] * n2[i]; + d = (d * 8) / 25 - 500000; + if (!((103 < d) && (d < 5740))) { + printf("test 2 failed, X=%ld.%02ld\n", d / 100L, d % 100L); + err++; + } + printf("test 2 done\n"); + + /* test 3 */ + for (i = 0; i < 2; i++) { + if (!((2267 < runs[i][0]) && (runs[i][0] < 2733))) { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i, 1, runs[i][0]); + err++; + } + if (!((1079 < runs[i][1]) && (runs[i][1] < 1421))) { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i, 2, runs[i][1]); + err++; + } + if (!((502 < runs[i][2]) && (runs[i][2] < 748))) { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i, 3, runs[i][2]); + err++; + } + if (!((223 < runs[i][3]) && (runs[i][3] < 402))) { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i, 4, runs[i][3]); + err++; + } + if (!((90 < runs[i][4]) && (runs[i][4] < 223))) { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i, 5, runs[i][4]); + err++; + } + if (!((90 < runs[i][5]) && (runs[i][5] < 223))) { + printf("test 3 failed, bit=%d run=%d num=%lu\n", + i, 6, runs[i][5]); + err++; + } + } + printf("test 3 done\n"); + + /* test 4 */ + if (runs[0][33] != 0) { + printf("test 4 failed, bit=%d run=%d num=%lu\n", 0, 34, runs[0][33]); + err++; + } + if (runs[1][33] != 0) { + printf("test 4 failed, bit=%d run=%d num=%lu\n", 1, 34, runs[1][33]); + err++; + } + printf("test 4 done\n"); + err: + err = ((err) ? 1 : 0); +#ifdef OPENSSL_SYS_NETWARE + if (err) + printf("ERROR: %d\n", err); +#endif + EXIT(err); + return (err); +} diff --git a/libs/openssl/crypto/rc2/rc2.h b/libs/openssl/crypto/rc2/rc2.h new file mode 100644 index 00000000..29d02d73 --- /dev/null +++ b/libs/openssl/crypto/rc2/rc2.h @@ -0,0 +1,103 @@ +/* crypto/rc2/rc2.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RC2_H +# define HEADER_RC2_H + +# include /* OPENSSL_NO_RC2, RC2_INT */ +# ifdef OPENSSL_NO_RC2 +# error RC2 is disabled. +# endif + +# define RC2_ENCRYPT 1 +# define RC2_DECRYPT 0 + +# define RC2_BLOCK 8 +# define RC2_KEY_LENGTH 16 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc2_key_st { + RC2_INT data[64]; +} RC2_KEY; + +# ifdef OPENSSL_FIPS +void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, + int bits); +# endif +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits); +void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, + RC2_KEY *key, int enc); +void RC2_encrypt(unsigned long *data, RC2_KEY *key); +void RC2_decrypt(unsigned long *data, RC2_KEY *key); +void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + RC2_KEY *ks, unsigned char *iv, int enc); +void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num, int enc); +void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/rc2/rc2_cbc.c b/libs/openssl/crypto/rc2/rc2_cbc.c new file mode 100644 index 00000000..5eaf01d2 --- /dev/null +++ b/libs/openssl/crypto/rc2/rc2_cbc.c @@ -0,0 +1,228 @@ +/* crypto/rc2/rc2_cbc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rc2_locl.h" + +void RC2_cbc_encrypt(const unsigned char *in, unsigned char *out, long length, + RC2_KEY *ks, unsigned char *iv, int encrypt) +{ + register unsigned long tin0, tin1; + register unsigned long tout0, tout1, xor0, xor1; + register long l = length; + unsigned long tin[2]; + + if (encrypt) { + c2l(iv, tout0); + c2l(iv, tout1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + RC2_encrypt(tin, ks); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + RC2_encrypt(tin, ks); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + l2c(tout0, iv); + l2c(tout1, iv); + } else { + c2l(iv, xor0); + c2l(iv, xor1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + RC2_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + RC2_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2cn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2c(xor0, iv); + l2c(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} + +void RC2_encrypt(unsigned long *d, RC2_KEY *key) +{ + int i, n; + register RC2_INT *p0, *p1; + register RC2_INT x0, x1, x2, x3, t; + unsigned long l; + + l = d[0]; + x0 = (RC2_INT) l & 0xffff; + x1 = (RC2_INT) (l >> 16L); + l = d[1]; + x2 = (RC2_INT) l & 0xffff; + x3 = (RC2_INT) (l >> 16L); + + n = 3; + i = 5; + + p0 = p1 = &(key->data[0]); + for (;;) { + t = (x0 + (x1 & ~x3) + (x2 & x3) + *(p0++)) & 0xffff; + x0 = (t << 1) | (t >> 15); + t = (x1 + (x2 & ~x0) + (x3 & x0) + *(p0++)) & 0xffff; + x1 = (t << 2) | (t >> 14); + t = (x2 + (x3 & ~x1) + (x0 & x1) + *(p0++)) & 0xffff; + x2 = (t << 3) | (t >> 13); + t = (x3 + (x0 & ~x2) + (x1 & x2) + *(p0++)) & 0xffff; + x3 = (t << 5) | (t >> 11); + + if (--i == 0) { + if (--n == 0) + break; + i = (n == 2) ? 6 : 5; + + x0 += p1[x3 & 0x3f]; + x1 += p1[x0 & 0x3f]; + x2 += p1[x1 & 0x3f]; + x3 += p1[x2 & 0x3f]; + } + } + + d[0] = + (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L); + d[1] = + (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L); +} + +void RC2_decrypt(unsigned long *d, RC2_KEY *key) +{ + int i, n; + register RC2_INT *p0, *p1; + register RC2_INT x0, x1, x2, x3, t; + unsigned long l; + + l = d[0]; + x0 = (RC2_INT) l & 0xffff; + x1 = (RC2_INT) (l >> 16L); + l = d[1]; + x2 = (RC2_INT) l & 0xffff; + x3 = (RC2_INT) (l >> 16L); + + n = 3; + i = 5; + + p0 = &(key->data[63]); + p1 = &(key->data[0]); + for (;;) { + t = ((x3 << 11) | (x3 >> 5)) & 0xffff; + x3 = (t - (x0 & ~x2) - (x1 & x2) - *(p0--)) & 0xffff; + t = ((x2 << 13) | (x2 >> 3)) & 0xffff; + x2 = (t - (x3 & ~x1) - (x0 & x1) - *(p0--)) & 0xffff; + t = ((x1 << 14) | (x1 >> 2)) & 0xffff; + x1 = (t - (x2 & ~x0) - (x3 & x0) - *(p0--)) & 0xffff; + t = ((x0 << 15) | (x0 >> 1)) & 0xffff; + x0 = (t - (x1 & ~x3) - (x2 & x3) - *(p0--)) & 0xffff; + + if (--i == 0) { + if (--n == 0) + break; + i = (n == 2) ? 6 : 5; + + x3 = (x3 - p1[x2 & 0x3f]) & 0xffff; + x2 = (x2 - p1[x1 & 0x3f]) & 0xffff; + x1 = (x1 - p1[x0 & 0x3f]) & 0xffff; + x0 = (x0 - p1[x3 & 0x3f]) & 0xffff; + } + } + + d[0] = + (unsigned long)(x0 & 0xffff) | ((unsigned long)(x1 & 0xffff) << 16L); + d[1] = + (unsigned long)(x2 & 0xffff) | ((unsigned long)(x3 & 0xffff) << 16L); +} diff --git a/libs/openssl/crypto/rc2/rc2_ecb.c b/libs/openssl/crypto/rc2/rc2_ecb.c new file mode 100644 index 00000000..48442a3f --- /dev/null +++ b/libs/openssl/crypto/rc2/rc2_ecb.c @@ -0,0 +1,92 @@ +/* crypto/rc2/rc2_ecb.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rc2_locl.h" +#include + +const char RC2_version[] = "RC2" OPENSSL_VERSION_PTEXT; + +/*- + * RC2 as implemented frm a posting from + * Newsgroups: sci.crypt + * Sender: pgut01@cs.auckland.ac.nz (Peter Gutmann) + * Subject: Specification for Ron Rivests Cipher No.2 + * Message-ID: <4fk39f$f70@net.auckland.ac.nz> + * Date: 11 Feb 1996 06:45:03 GMT + */ + +void RC2_ecb_encrypt(const unsigned char *in, unsigned char *out, RC2_KEY *ks, + int encrypt) +{ + unsigned long l, d[2]; + + c2l(in, l); + d[0] = l; + c2l(in, l); + d[1] = l; + if (encrypt) + RC2_encrypt(d, ks); + else + RC2_decrypt(d, ks); + l = d[0]; + l2c(l, out); + l = d[1]; + l2c(l, out); + l = d[0] = d[1] = 0; +} diff --git a/libs/openssl/crypto/rc2/rc2_locl.h b/libs/openssl/crypto/rc2/rc2_locl.h new file mode 100644 index 00000000..e72a20c0 --- /dev/null +++ b/libs/openssl/crypto/rc2/rc2_locl.h @@ -0,0 +1,155 @@ +/* crypto/rc2/rc2_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#undef c2l +#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +#undef c2ln +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +#undef l2c +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#undef l2cn +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +/* NOTE - c is not incremented as per n2l */ +#define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + } \ + } + +#undef n2l +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +#undef l2n +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +#define C_RC2(n) \ + t=(x0+(x1& ~x3)+(x2&x3)+ *(p0++))&0xffff; \ + x0=(t<<1)|(t>>15); \ + t=(x1+(x2& ~x0)+(x3&x0)+ *(p0++))&0xffff; \ + x1=(t<<2)|(t>>14); \ + t=(x2+(x3& ~x1)+(x0&x1)+ *(p0++))&0xffff; \ + x2=(t<<3)|(t>>13); \ + t=(x3+(x0& ~x2)+(x1&x2)+ *(p0++))&0xffff; \ + x3=(t<<5)|(t>>11); diff --git a/libs/openssl/crypto/rc2/rc2_skey.c b/libs/openssl/crypto/rc2/rc2_skey.c new file mode 100644 index 00000000..bcec0a85 --- /dev/null +++ b/libs/openssl/crypto/rc2/rc2_skey.c @@ -0,0 +1,157 @@ +/* crypto/rc2/rc2_skey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "rc2_locl.h" + +static const unsigned char key_table[256] = { + 0xd9, 0x78, 0xf9, 0xc4, 0x19, 0xdd, 0xb5, 0xed, 0x28, 0xe9, 0xfd, 0x79, + 0x4a, 0xa0, 0xd8, 0x9d, 0xc6, 0x7e, 0x37, 0x83, 0x2b, 0x76, 0x53, 0x8e, + 0x62, 0x4c, 0x64, 0x88, 0x44, 0x8b, 0xfb, 0xa2, 0x17, 0x9a, 0x59, 0xf5, + 0x87, 0xb3, 0x4f, 0x13, 0x61, 0x45, 0x6d, 0x8d, 0x09, 0x81, 0x7d, 0x32, + 0xbd, 0x8f, 0x40, 0xeb, 0x86, 0xb7, 0x7b, 0x0b, 0xf0, 0x95, 0x21, 0x22, + 0x5c, 0x6b, 0x4e, 0x82, 0x54, 0xd6, 0x65, 0x93, 0xce, 0x60, 0xb2, 0x1c, + 0x73, 0x56, 0xc0, 0x14, 0xa7, 0x8c, 0xf1, 0xdc, 0x12, 0x75, 0xca, 0x1f, + 0x3b, 0xbe, 0xe4, 0xd1, 0x42, 0x3d, 0xd4, 0x30, 0xa3, 0x3c, 0xb6, 0x26, + 0x6f, 0xbf, 0x0e, 0xda, 0x46, 0x69, 0x07, 0x57, 0x27, 0xf2, 0x1d, 0x9b, + 0xbc, 0x94, 0x43, 0x03, 0xf8, 0x11, 0xc7, 0xf6, 0x90, 0xef, 0x3e, 0xe7, + 0x06, 0xc3, 0xd5, 0x2f, 0xc8, 0x66, 0x1e, 0xd7, 0x08, 0xe8, 0xea, 0xde, + 0x80, 0x52, 0xee, 0xf7, 0x84, 0xaa, 0x72, 0xac, 0x35, 0x4d, 0x6a, 0x2a, + 0x96, 0x1a, 0xd2, 0x71, 0x5a, 0x15, 0x49, 0x74, 0x4b, 0x9f, 0xd0, 0x5e, + 0x04, 0x18, 0xa4, 0xec, 0xc2, 0xe0, 0x41, 0x6e, 0x0f, 0x51, 0xcb, 0xcc, + 0x24, 0x91, 0xaf, 0x50, 0xa1, 0xf4, 0x70, 0x39, 0x99, 0x7c, 0x3a, 0x85, + 0x23, 0xb8, 0xb4, 0x7a, 0xfc, 0x02, 0x36, 0x5b, 0x25, 0x55, 0x97, 0x31, + 0x2d, 0x5d, 0xfa, 0x98, 0xe3, 0x8a, 0x92, 0xae, 0x05, 0xdf, 0x29, 0x10, + 0x67, 0x6c, 0xba, 0xc9, 0xd3, 0x00, 0xe6, 0xcf, 0xe1, 0x9e, 0xa8, 0x2c, + 0x63, 0x16, 0x01, 0x3f, 0x58, 0xe2, 0x89, 0xa9, 0x0d, 0x38, 0x34, 0x1b, + 0xab, 0x33, 0xff, 0xb0, 0xbb, 0x48, 0x0c, 0x5f, 0xb9, 0xb1, 0xcd, 0x2e, + 0xc5, 0xf3, 0xdb, 0x47, 0xe5, 0xa5, 0x9c, 0x77, 0x0a, 0xa6, 0x20, 0x68, + 0xfe, 0x7f, 0xc1, 0xad, +}; + +#if defined(_MSC_VER) && defined(_ARM_) +# pragma optimize("g",off) +#endif + +/* + * It has come to my attention that there are 2 versions of the RC2 key + * schedule. One which is normal, and anther which has a hook to use a + * reduced key length. BSAFE uses the 'retarded' version. What I previously + * shipped is the same as specifying 1024 for the 'bits' parameter. Bsafe + * uses a version where the bits parameter is the same as len*8 + */ +void RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, int bits) +#ifdef OPENSSL_FIPS +{ + fips_cipher_abort(RC2); + private_RC2_set_key(key, len, data, bits); +} + +void private_RC2_set_key(RC2_KEY *key, int len, const unsigned char *data, + int bits) +#endif +{ + int i, j; + unsigned char *k; + RC2_INT *ki; + unsigned int c, d; + + k = (unsigned char *)&(key->data[0]); + *k = 0; /* for if there is a zero length key */ + + if (len > 128) + len = 128; + if (bits <= 0) + bits = 1024; + if (bits > 1024) + bits = 1024; + + for (i = 0; i < len; i++) + k[i] = data[i]; + + /* expand table */ + d = k[len - 1]; + j = 0; + for (i = len; i < 128; i++, j++) { + d = key_table[(k[j] + d) & 0xff]; + k[i] = d; + } + + /* hmm.... key reduction to 'bits' bits */ + + j = (bits + 7) >> 3; + i = 128 - j; + c = (0xff >> (-bits & 0x07)); + + d = key_table[k[i] & c]; + k[i] = d; + while (i--) { + d = key_table[k[i + j] ^ d]; + k[i] = d; + } + + /* copy from bytes into RC2_INT's */ + ki = &(key->data[63]); + for (i = 127; i >= 0; i -= 2) + *(ki--) = ((k[i] << 8) | k[i - 1]) & 0xffff; +} + +#if defined(_MSC_VER) +# pragma optimize("",on) +#endif diff --git a/libs/openssl/crypto/rc2/rc2cfb64.c b/libs/openssl/crypto/rc2/rc2cfb64.c new file mode 100644 index 00000000..8b5929fd --- /dev/null +++ b/libs/openssl/crypto/rc2/rc2cfb64.c @@ -0,0 +1,123 @@ +/* crypto/rc2/rc2cfb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rc2_locl.h" + +/* + * The input and output encrypted as though 64bit cfb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ + +void RC2_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num, int encrypt) +{ + register unsigned long v0, v1, t; + register int n = *num; + register long l = length; + unsigned long ti[2]; + unsigned char *iv, c, cc; + + iv = (unsigned char *)ivec; + if (encrypt) { + while (l--) { + if (n == 0) { + c2l(iv, v0); + ti[0] = v0; + c2l(iv, v1); + ti[1] = v1; + RC2_encrypt((unsigned long *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2c(t, iv); + t = ti[1]; + l2c(t, iv); + iv = (unsigned char *)ivec; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + c2l(iv, v0); + ti[0] = v0; + c2l(iv, v1); + ti[1] = v1; + RC2_encrypt((unsigned long *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2c(t, iv); + t = ti[1]; + l2c(t, iv); + iv = (unsigned char *)ivec; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; + *num = n; +} diff --git a/libs/openssl/crypto/rc2/rc2ofb64.c b/libs/openssl/crypto/rc2/rc2ofb64.c new file mode 100644 index 00000000..b9f4d8c3 --- /dev/null +++ b/libs/openssl/crypto/rc2/rc2ofb64.c @@ -0,0 +1,110 @@ +/* crypto/rc2/rc2ofb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rc2_locl.h" + +/* + * The input and output encrypted as though 64bit ofb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ +void RC2_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC2_KEY *schedule, unsigned char *ivec, + int *num) +{ + register unsigned long v0, v1, t; + register int n = *num; + register long l = length; + unsigned char d[8]; + register char *dp; + unsigned long ti[2]; + unsigned char *iv; + int save = 0; + + iv = (unsigned char *)ivec; + c2l(iv, v0); + c2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2c(v0, dp); + l2c(v1, dp); + while (l--) { + if (n == 0) { + RC2_encrypt((unsigned long *)ti, schedule); + dp = (char *)d; + t = ti[0]; + l2c(t, dp); + t = ti[1]; + l2c(t, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = (unsigned char *)ivec; + l2c(v0, iv); + l2c(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} diff --git a/libs/openssl/crypto/rc2/rc2speed.c b/libs/openssl/crypto/rc2/rc2speed.c new file mode 100644 index 00000000..3e45eb08 --- /dev/null +++ b/libs/openssl/crypto/rc2/rc2speed.c @@ -0,0 +1,262 @@ +/* crypto/rc2/rc2speed.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */ +/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */ + +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX) +# define TIMES +#endif + +#include + +#include +#include OPENSSL_UNISTD_IO +OPENSSL_DECLARE_EXIT +#ifndef OPENSSL_SYS_NETWARE +# include +#endif +#ifndef _IRIX +# include +#endif +#ifdef TIMES +# include +# include +#endif + /* + * Depending on the VMS version, the tms structure is perhaps defined. + * The __TMS macro will show if it was. If it wasn't defined, we should + * undefine TIMES, since that tells the rest of the program how things + * should be handled. -- Richard Levitte + */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) +# undef TIMES +#endif +#ifndef TIMES +# include +#endif +#if defined(sun) || defined(__ultrix) +# define _POSIX_SOURCE +# include +# include +#endif +#include +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# define HZ 100.0 +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif /* CLK_TCK */ +#endif /* HZ */ +#define BUFSIZE ((long)1024) +long run = 0; + +double Time_F(int s); +#ifdef SIGALRM +# if defined(__STDC__) || defined(sgi) || defined(_AIX) +# define SIGRETTYPE void +# else +# define SIGRETTYPE int +# endif + +SIGRETTYPE sig_done(int sig); +SIGRETTYPE sig_done(int sig) +{ + signal(SIGALRM, sig_done); + run = 0; +# ifdef LINT + sig = sig; +# endif +} +#endif + +#define START 0 +#define STOP 1 + +double Time_F(int s) +{ + double ret; +#ifdef TIMES + static struct tms tstart, tend; + + if (s == START) { + times(&tstart); + return (0); + } else { + times(&tend); + ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ; + return ((ret == 0.0) ? 1e-6 : ret); + } +#else /* !times() */ + static struct timeb tstart, tend; + long i; + + if (s == START) { + ftime(&tstart); + return (0); + } else { + ftime(&tend); + i = (long)tend.millitm - (long)tstart.millitm; + ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1e3; + return ((ret == 0.0) ? 1e-6 : ret); + } +#endif +} + +int main(int argc, char **argv) +{ + long count; + static unsigned char buf[BUFSIZE]; + static unsigned char key[] = { + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + RC2_KEY sch; + double a, b, c, d; +#ifndef SIGALRM + long ca, cb, cc; +#endif + +#ifndef TIMES + printf("To get the most accurate results, try to run this\n"); + printf("program when this computer is idle.\n"); +#endif + +#ifndef SIGALRM + printf("First we calculate the approximate speed ...\n"); + RC2_set_key(&sch, 16, key, 128); + count = 10; + do { + long i; + unsigned long data[2]; + + count *= 2; + Time_F(START); + for (i = count; i; i--) + RC2_encrypt(data, &sch); + d = Time_F(STOP); + } while (d < 3.0); + ca = count / 512; + cb = count; + cc = count * 8 / BUFSIZE + 1; + printf("Doing RC2_set_key %ld times\n", ca); +# define COND(d) (count != (d)) +# define COUNT(d) (d) +#else +# define COND(c) (run) +# define COUNT(d) (count) + signal(SIGALRM, sig_done); + printf("Doing RC2_set_key for 10 seconds\n"); + alarm(10); +#endif + + Time_F(START); + for (count = 0, run = 1; COND(ca); count += 4) { + RC2_set_key(&sch, 16, key, 128); + RC2_set_key(&sch, 16, key, 128); + RC2_set_key(&sch, 16, key, 128); + RC2_set_key(&sch, 16, key, 128); + } + d = Time_F(STOP); + printf("%ld RC2_set_key's in %.2f seconds\n", count, d); + a = ((double)COUNT(ca)) / d; + +#ifdef SIGALRM + printf("Doing RC2_encrypt's for 10 seconds\n"); + alarm(10); +#else + printf("Doing RC2_encrypt %ld times\n", cb); +#endif + Time_F(START); + for (count = 0, run = 1; COND(cb); count += 4) { + unsigned long data[2]; + + RC2_encrypt(data, &sch); + RC2_encrypt(data, &sch); + RC2_encrypt(data, &sch); + RC2_encrypt(data, &sch); + } + d = Time_F(STOP); + printf("%ld RC2_encrypt's in %.2f second\n", count, d); + b = ((double)COUNT(cb) * 8) / d; + +#ifdef SIGALRM + printf("Doing RC2_cbc_encrypt on %ld byte blocks for 10 seconds\n", + BUFSIZE); + alarm(10); +#else + printf("Doing RC2_cbc_encrypt %ld times on %ld byte blocks\n", cc, + BUFSIZE); +#endif + Time_F(START); + for (count = 0, run = 1; COND(cc); count++) + RC2_cbc_encrypt(buf, buf, BUFSIZE, &sch, &(key[0]), RC2_ENCRYPT); + d = Time_F(STOP); + printf("%ld RC2_cbc_encrypt's of %ld byte blocks in %.2f second\n", + count, BUFSIZE, d); + c = ((double)COUNT(cc) * BUFSIZE) / d; + + printf("RC2 set_key per sec = %12.2f (%9.3fuS)\n", a, 1.0e6 / a); + printf("RC2 raw ecb bytes per sec = %12.2f (%9.3fuS)\n", b, 8.0e6 / b); + printf("RC2 cbc bytes per sec = %12.2f (%9.3fuS)\n", c, 8.0e6 / c); + exit(0); +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS) + return (0); +#endif +} diff --git a/libs/openssl/crypto/rc2/rc2test.c b/libs/openssl/crypto/rc2/rc2test.c new file mode 100644 index 00000000..e61df342 --- /dev/null +++ b/libs/openssl/crypto/rc2/rc2test.c @@ -0,0 +1,274 @@ +/* crypto/rc2/rc2test.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * This has been a quickly hacked 'ideatest.c'. When I add tests for other + * RC2 modes, more of the code will be uncommented. + */ + +#include +#include +#include + +#include "../e_os.h" + +#ifdef OPENSSL_NO_RC2 +int main(int argc, char *argv[]) +{ + printf("No RC2 support\n"); + return (0); +} +#else +# include + +static unsigned char RC2key[4][16] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F}, +}; + +static unsigned char RC2plain[4][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, +}; + +static unsigned char RC2cipher[4][8] = { + {0x1C, 0x19, 0x8A, 0x83, 0x8D, 0xF0, 0x28, 0xB7}, + {0x21, 0x82, 0x9C, 0x78, 0xA9, 0xF9, 0xC0, 0x74}, + {0x13, 0xDB, 0x35, 0x17, 0xD3, 0x21, 0x86, 0x9E}, + {0x50, 0xDC, 0x01, 0x62, 0xBD, 0x75, 0x7F, 0x31}, +}; + +/************/ +# ifdef undef +unsigned char k[16] = { + 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, + 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 +}; + +unsigned char in[8] = { 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03 }; +unsigned char c[8] = { 0x11, 0xFB, 0xED, 0x2B, 0x01, 0x98, 0x6D, 0xE5 }; + +unsigned char out[80]; + +char *text = "Hello to all people out there"; + +static unsigned char cfb_key[16] = { + 0xe1, 0xf0, 0xc3, 0xd2, 0xa5, 0xb4, 0x87, 0x96, + 0x69, 0x78, 0x4b, 0x5a, 0x2d, 0x3c, 0x0f, 0x1e, +}; +static unsigned char cfb_iv[80] = + { 0x34, 0x12, 0x78, 0x56, 0xab, 0x90, 0xef, 0xcd }; +static unsigned char cfb_buf1[40], cfb_buf2[40], cfb_tmp[8]; +# define CFB_TEST_SIZE 24 +static unsigned char plain[CFB_TEST_SIZE] = { + 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, + 0x20, 0x74, 0x68, 0x65, 0x20, 0x74, + 0x69, 0x6d, 0x65, 0x20, 0x66, 0x6f, + 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20 +}; + +static unsigned char cfb_cipher64[CFB_TEST_SIZE] = { + 0x59, 0xD8, 0xE2, 0x65, 0x00, 0x58, 0x6C, 0x3F, + 0x2C, 0x17, 0x25, 0xD0, 0x1A, 0x38, 0xB7, 0x2A, + 0x39, 0x61, 0x37, 0xDC, 0x79, 0xFB, 0x9F, 0x45 +/*- 0xF9,0x78,0x32,0xB5,0x42,0x1A,0x6B,0x38, + 0x9A,0x44,0xD6,0x04,0x19,0x43,0xC4,0xD9, + 0x3D,0x1E,0xAE,0x47,0xFC,0xCF,0x29,0x0B,*/ +}; + +/* + * static int cfb64_test(unsigned char *cfb_cipher); + */ +static char *pt(unsigned char *p); +# endif + +int main(int argc, char *argv[]) +{ + int i, n, err = 0; + RC2_KEY key; + unsigned char buf[8], buf2[8]; + + for (n = 0; n < 4; n++) { + RC2_set_key(&key, 16, &(RC2key[n][0]), 0 /* or 1024 */ ); + + RC2_ecb_encrypt(&(RC2plain[n][0]), buf, &key, RC2_ENCRYPT); + if (memcmp(&(RC2cipher[n][0]), buf, 8) != 0) { + printf("ecb rc2 error encrypting\n"); + printf("got :"); + for (i = 0; i < 8; i++) + printf("%02X ", buf[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 8; i++) + printf("%02X ", RC2cipher[n][i]); + err = 20; + printf("\n"); + } + + RC2_ecb_encrypt(buf, buf2, &key, RC2_DECRYPT); + if (memcmp(&(RC2plain[n][0]), buf2, 8) != 0) { + printf("ecb RC2 error decrypting\n"); + printf("got :"); + for (i = 0; i < 8; i++) + printf("%02X ", buf[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 8; i++) + printf("%02X ", RC2plain[n][i]); + printf("\n"); + err = 3; + } + } + + if (err == 0) + printf("ecb RC2 ok\n"); +# ifdef undef + memcpy(iv, k, 8); + idea_cbc_encrypt((unsigned char *)text, out, strlen(text) + 1, &key, iv, + 1); + memcpy(iv, k, 8); + idea_cbc_encrypt(out, out, 8, &dkey, iv, 0); + idea_cbc_encrypt(&(out[8]), &(out[8]), strlen(text) + 1 - 8, &dkey, iv, + 0); + if (memcmp(text, out, strlen(text) + 1) != 0) { + printf("cbc idea bad\n"); + err = 4; + } else + printf("cbc idea ok\n"); + + printf("cfb64 idea "); + if (cfb64_test(cfb_cipher64)) { + printf("bad\n"); + err = 5; + } else + printf("ok\n"); +# endif + +# ifdef OPENSSL_SYS_NETWARE + if (err) + printf("ERROR: %d\n", err); +# endif + EXIT(err); + return (err); +} + +# ifdef undef +static int cfb64_test(unsigned char *cfb_cipher) +{ + IDEA_KEY_SCHEDULE eks, dks; + int err = 0, i, n; + + idea_set_encrypt_key(cfb_key, &eks); + idea_set_decrypt_key(&eks, &dks); + memcpy(cfb_tmp, cfb_iv, 8); + n = 0; + idea_cfb64_encrypt(plain, cfb_buf1, (long)12, &eks, + cfb_tmp, &n, IDEA_ENCRYPT); + idea_cfb64_encrypt(&(plain[12]), &(cfb_buf1[12]), + (long)CFB_TEST_SIZE - 12, &eks, + cfb_tmp, &n, IDEA_ENCRYPT); + if (memcmp(cfb_cipher, cfb_buf1, CFB_TEST_SIZE) != 0) { + err = 1; + printf("idea_cfb64_encrypt encrypt error\n"); + for (i = 0; i < CFB_TEST_SIZE; i += 8) + printf("%s\n", pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp, cfb_iv, 8); + n = 0; + idea_cfb64_encrypt(cfb_buf1, cfb_buf2, (long)17, &eks, + cfb_tmp, &n, IDEA_DECRYPT); + idea_cfb64_encrypt(&(cfb_buf1[17]), &(cfb_buf2[17]), + (long)CFB_TEST_SIZE - 17, &dks, + cfb_tmp, &n, IDEA_DECRYPT); + if (memcmp(plain, cfb_buf2, CFB_TEST_SIZE) != 0) { + err = 1; + printf("idea_cfb_encrypt decrypt error\n"); + for (i = 0; i < 24; i += 8) + printf("%s\n", pt(&(cfb_buf2[i]))); + } + return (err); +} + +static char *pt(unsigned char *p) +{ + static char bufs[10][20]; + static int bnum = 0; + char *ret; + int i; + static char *f = "0123456789ABCDEF"; + + ret = &(bufs[bnum++][0]); + bnum %= 10; + for (i = 0; i < 8; i++) { + ret[i * 2] = f[(p[i] >> 4) & 0xf]; + ret[i * 2 + 1] = f[p[i] & 0xf]; + } + ret[16] = '\0'; + return (ret); +} + +# endif +#endif diff --git a/libs/openssl/crypto/rc2/rrc2.doc b/libs/openssl/crypto/rc2/rrc2.doc new file mode 100644 index 00000000..f93ee003 --- /dev/null +++ b/libs/openssl/crypto/rc2/rrc2.doc @@ -0,0 +1,219 @@ +>From cygnus.mincom.oz.au!minbne.mincom.oz.au!bunyip.cc.uq.oz.au!munnari.OZ.AU!comp.vuw.ac.nz!waikato!auckland.ac.nz!news Mon Feb 12 18:48:17 EST 1996 +Article 23601 of sci.crypt: +Path: cygnus.mincom.oz.au!minbne.mincom.oz.au!bunyip.cc.uq.oz.au!munnari.OZ.AU!comp.vuw.ac.nz!waikato!auckland.ac.nz!news +>From: pgut01@cs.auckland.ac.nz (Peter Gutmann) +Newsgroups: sci.crypt +Subject: Specification for Ron Rivests Cipher No.2 +Date: 11 Feb 1996 06:45:03 GMT +Organization: University of Auckland +Lines: 203 +Sender: pgut01@cs.auckland.ac.nz (Peter Gutmann) +Message-ID: <4fk39f$f70@net.auckland.ac.nz> +NNTP-Posting-Host: cs26.cs.auckland.ac.nz +X-Newsreader: NN version 6.5.0 #3 (NOV) + + + + + Ron Rivest's Cipher No.2 + ------------------------ + +Ron Rivest's Cipher No.2 (hereafter referred to as RRC.2, other people may +refer to it by other names) is word oriented, operating on a block of 64 bits +divided into four 16-bit words, with a key table of 64 words. All data units +are little-endian. This functional description of the algorithm is based in +the paper "The RC5 Encryption Algorithm" (RC5 is a trademark of RSADSI), using +the same general layout, terminology, and pseudocode style. + + +Notation and RRC.2 Primitive Operations + +RRC.2 uses the following primitive operations: + +1. Two's-complement addition of words, denoted by "+". The inverse operation, + subtraction, is denoted by "-". +2. Bitwise exclusive OR, denoted by "^". +3. Bitwise AND, denoted by "&". +4. Bitwise NOT, denoted by "~". +5. A left-rotation of words; the rotation of word x left by y is denoted + x <<< y. The inverse operation, right-rotation, is denoted x >>> y. + +These operations are directly and efficiently supported by most processors. + + +The RRC.2 Algorithm + +RRC.2 consists of three components, a *key expansion* algorithm, an +*encryption* algorithm, and a *decryption* algorithm. + + +Key Expansion + +The purpose of the key-expansion routine is to expand the user's key K to fill +the expanded key array S, so S resembles an array of random binary words +determined by the user's secret key K. + +Initialising the S-box + +RRC.2 uses a single 256-byte S-box derived from the ciphertext contents of +Beale Cipher No.1 XOR'd with a one-time pad. The Beale Ciphers predate modern +cryptography by enough time that there should be no concerns about trapdoors +hidden in the data. They have been published widely, and the S-box can be +easily recreated from the one-time pad values and the Beale Cipher data taken +from a standard source. To initialise the S-box: + + for i = 0 to 255 do + sBox[ i ] = ( beale[ i ] mod 256 ) ^ pad[ i ] + +The contents of Beale Cipher No.1 and the necessary one-time pad are given as +an appendix at the end of this document. For efficiency, implementors may wish +to skip the Beale Cipher expansion and store the sBox table directly. + +Expanding the Secret Key to 128 Bytes + +The secret key is first expanded to fill 128 bytes (64 words). The expansion +consists of taking the sum of the first and last bytes in the user key, looking +up the sum (modulo 256) in the S-box, and appending the result to the key. The +operation is repeated with the second byte and new last byte of the key until +all 128 bytes have been generated. Note that the following pseudocode treats +the S array as an array of 128 bytes rather than 64 words. + + for j = 0 to length-1 do + S[ j ] = K[ j ] + for j = length to 127 do + s[ j ] = sBox[ ( S[ j-length ] + S[ j-1 ] ) mod 256 ]; + +At this point it is possible to perform a truncation of the effective key +length to ease the creation of espionage-enabled software products. However +since the author cannot conceive why anyone would want to do this, it will not +be considered further. + +The final phase of the key expansion involves replacing the first byte of S +with the entry selected from the S-box: + + S[ 0 ] = sBox[ S[ 0 ] ] + + +Encryption + +The cipher has 16 full rounds, each divided into 4 subrounds. Two of the full +rounds perform an additional transformation on the data. Note that the +following pseudocode treats the S array as an array of 64 words rather than 128 +bytes. + + for i = 0 to 15 do + j = i * 4; + word0 = ( word0 + ( word1 & ~word3 ) + ( word2 & word3 ) + S[ j+0 ] ) <<< 1 + word1 = ( word1 + ( word2 & ~word0 ) + ( word3 & word0 ) + S[ j+1 ] ) <<< 2 + word2 = ( word2 + ( word3 & ~word1 ) + ( word0 & word1 ) + S[ j+2 ] ) <<< 3 + word3 = ( word3 + ( word0 & ~word2 ) + ( word1 & word2 ) + S[ j+3 ] ) <<< 5 + +In addition the fifth and eleventh rounds add the contents of the S-box indexed +by one of the data words to another of the data words following the four +subrounds as follows: + + word0 = word0 + S[ word3 & 63 ]; + word1 = word1 + S[ word0 & 63 ]; + word2 = word2 + S[ word1 & 63 ]; + word3 = word3 + S[ word2 & 63 ]; + + +Decryption + +The decryption operation is simply the inverse of the encryption operation. +Note that the following pseudocode treats the S array as an array of 64 words +rather than 128 bytes. + + for i = 15 downto 0 do + j = i * 4; + word3 = ( word3 >>> 5 ) - ( word0 & ~word2 ) - ( word1 & word2 ) - S[ j+3 ] + word2 = ( word2 >>> 3 ) - ( word3 & ~word1 ) - ( word0 & word1 ) - S[ j+2 ] + word1 = ( word1 >>> 2 ) - ( word2 & ~word0 ) - ( word3 & word0 ) - S[ j+1 ] + word0 = ( word0 >>> 1 ) - ( word1 & ~word3 ) - ( word2 & word3 ) - S[ j+0 ] + +In addition the fifth and eleventh rounds subtract the contents of the S-box +indexed by one of the data words from another one of the data words following +the four subrounds as follows: + + word3 = word3 - S[ word2 & 63 ] + word2 = word2 - S[ word1 & 63 ] + word1 = word1 - S[ word0 & 63 ] + word0 = word0 - S[ word3 & 63 ] + + +Test Vectors + +The following test vectors may be used to test the correctness of an RRC.2 +implementation: + + Key: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + Plain: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + Cipher: 0x1C, 0x19, 0x8A, 0x83, 0x8D, 0xF0, 0x28, 0xB7 + + Key: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 + Plain: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + Cipher: 0x21, 0x82, 0x9C, 0x78, 0xA9, 0xF9, 0xC0, 0x74 + + Key: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + Plain: 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + Cipher: 0x13, 0xDB, 0x35, 0x17, 0xD3, 0x21, 0x86, 0x9E + + Key: 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F + Plain: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 + Cipher: 0x50, 0xDC, 0x01, 0x62, 0xBD, 0x75, 0x7F, 0x31 + + +Appendix: Beale Cipher No.1, "The Locality of the Vault", and One-time Pad for + Creating the S-Box + +Beale Cipher No.1. + + 71, 194, 38,1701, 89, 76, 11, 83,1629, 48, 94, 63, 132, 16, 111, 95, + 84, 341, 975, 14, 40, 64, 27, 81, 139, 213, 63, 90,1120, 8, 15, 3, + 126,2018, 40, 74, 758, 485, 604, 230, 436, 664, 582, 150, 251, 284, 308, 231, + 124, 211, 486, 225, 401, 370, 11, 101, 305, 139, 189, 17, 33, 88, 208, 193, + 145, 1, 94, 73, 416, 918, 263, 28, 500, 538, 356, 117, 136, 219, 27, 176, + 130, 10, 460, 25, 485, 18, 436, 65, 84, 200, 283, 118, 320, 138, 36, 416, + 280, 15, 71, 224, 961, 44, 16, 401, 39, 88, 61, 304, 12, 21, 24, 283, + 134, 92, 63, 246, 486, 682, 7, 219, 184, 360, 780, 18, 64, 463, 474, 131, + 160, 79, 73, 440, 95, 18, 64, 581, 34, 69, 128, 367, 460, 17, 81, 12, + 103, 820, 62, 110, 97, 103, 862, 70, 60,1317, 471, 540, 208, 121, 890, 346, + 36, 150, 59, 568, 614, 13, 120, 63, 219, 812,2160,1780, 99, 35, 18, 21, + 136, 872, 15, 28, 170, 88, 4, 30, 44, 112, 18, 147, 436, 195, 320, 37, + 122, 113, 6, 140, 8, 120, 305, 42, 58, 461, 44, 106, 301, 13, 408, 680, + 93, 86, 116, 530, 82, 568, 9, 102, 38, 416, 89, 71, 216, 728, 965, 818, + 2, 38, 121, 195, 14, 326, 148, 234, 18, 55, 131, 234, 361, 824, 5, 81, + 623, 48, 961, 19, 26, 33, 10,1101, 365, 92, 88, 181, 275, 346, 201, 206 + +One-time Pad. + + 158, 186, 223, 97, 64, 145, 190, 190, 117, 217, 163, 70, 206, 176, 183, 194, + 146, 43, 248, 141, 3, 54, 72, 223, 233, 153, 91, 210, 36, 131, 244, 161, + 105, 120, 113, 191, 113, 86, 19, 245, 213, 221, 43, 27, 242, 157, 73, 213, + 193, 92, 166, 10, 23, 197, 112, 110, 193, 30, 156, 51, 125, 51, 158, 67, + 197, 215, 59, 218, 110, 246, 181, 0, 135, 76, 164, 97, 47, 87, 234, 108, + 144, 127, 6, 6, 222, 172, 80, 144, 22, 245, 207, 70, 227, 182, 146, 134, + 119, 176, 73, 58, 135, 69, 23, 198, 0, 170, 32, 171, 176, 129, 91, 24, + 126, 77, 248, 0, 118, 69, 57, 60, 190, 171, 217, 61, 136, 169, 196, 84, + 168, 167, 163, 102, 223, 64, 174, 178, 166, 239, 242, 195, 249, 92, 59, 38, + 241, 46, 236, 31, 59, 114, 23, 50, 119, 186, 7, 66, 212, 97, 222, 182, + 230, 118, 122, 86, 105, 92, 179, 243, 255, 189, 223, 164, 194, 215, 98, 44, + 17, 20, 53, 153, 137, 224, 176, 100, 208, 114, 36, 200, 145, 150, 215, 20, + 87, 44, 252, 20, 235, 242, 163, 132, 63, 18, 5, 122, 74, 97, 34, 97, + 142, 86, 146, 221, 179, 166, 161, 74, 69, 182, 88, 120, 128, 58, 76, 155, + 15, 30, 77, 216, 165, 117, 107, 90, 169, 127, 143, 181, 208, 137, 200, 127, + 170, 195, 26, 84, 255, 132, 150, 58, 103, 250, 120, 221, 237, 37, 8, 99 + + +Implementation + +A non-US based programmer who has never seen any encryption code before will +shortly be implementing RRC.2 based solely on this specification and not on +knowledge of any other encryption algorithms. Stand by. + + + diff --git a/libs/openssl/crypto/rc2/tab.c b/libs/openssl/crypto/rc2/tab.c new file mode 100644 index 00000000..0534e375 --- /dev/null +++ b/libs/openssl/crypto/rc2/tab.c @@ -0,0 +1,84 @@ +#include + +unsigned char ebits_to_num[256] = { + 0xbd, 0x56, 0xea, 0xf2, 0xa2, 0xf1, 0xac, 0x2a, + 0xb0, 0x93, 0xd1, 0x9c, 0x1b, 0x33, 0xfd, 0xd0, + 0x30, 0x04, 0xb6, 0xdc, 0x7d, 0xdf, 0x32, 0x4b, + 0xf7, 0xcb, 0x45, 0x9b, 0x31, 0xbb, 0x21, 0x5a, + 0x41, 0x9f, 0xe1, 0xd9, 0x4a, 0x4d, 0x9e, 0xda, + 0xa0, 0x68, 0x2c, 0xc3, 0x27, 0x5f, 0x80, 0x36, + 0x3e, 0xee, 0xfb, 0x95, 0x1a, 0xfe, 0xce, 0xa8, + 0x34, 0xa9, 0x13, 0xf0, 0xa6, 0x3f, 0xd8, 0x0c, + 0x78, 0x24, 0xaf, 0x23, 0x52, 0xc1, 0x67, 0x17, + 0xf5, 0x66, 0x90, 0xe7, 0xe8, 0x07, 0xb8, 0x60, + 0x48, 0xe6, 0x1e, 0x53, 0xf3, 0x92, 0xa4, 0x72, + 0x8c, 0x08, 0x15, 0x6e, 0x86, 0x00, 0x84, 0xfa, + 0xf4, 0x7f, 0x8a, 0x42, 0x19, 0xf6, 0xdb, 0xcd, + 0x14, 0x8d, 0x50, 0x12, 0xba, 0x3c, 0x06, 0x4e, + 0xec, 0xb3, 0x35, 0x11, 0xa1, 0x88, 0x8e, 0x2b, + 0x94, 0x99, 0xb7, 0x71, 0x74, 0xd3, 0xe4, 0xbf, + 0x3a, 0xde, 0x96, 0x0e, 0xbc, 0x0a, 0xed, 0x77, + 0xfc, 0x37, 0x6b, 0x03, 0x79, 0x89, 0x62, 0xc6, + 0xd7, 0xc0, 0xd2, 0x7c, 0x6a, 0x8b, 0x22, 0xa3, + 0x5b, 0x05, 0x5d, 0x02, 0x75, 0xd5, 0x61, 0xe3, + 0x18, 0x8f, 0x55, 0x51, 0xad, 0x1f, 0x0b, 0x5e, + 0x85, 0xe5, 0xc2, 0x57, 0x63, 0xca, 0x3d, 0x6c, + 0xb4, 0xc5, 0xcc, 0x70, 0xb2, 0x91, 0x59, 0x0d, + 0x47, 0x20, 0xc8, 0x4f, 0x58, 0xe0, 0x01, 0xe2, + 0x16, 0x38, 0xc4, 0x6f, 0x3b, 0x0f, 0x65, 0x46, + 0xbe, 0x7e, 0x2d, 0x7b, 0x82, 0xf9, 0x40, 0xb5, + 0x1d, 0x73, 0xf8, 0xeb, 0x26, 0xc7, 0x87, 0x97, + 0x25, 0x54, 0xb1, 0x28, 0xaa, 0x98, 0x9d, 0xa5, + 0x64, 0x6d, 0x7a, 0xd4, 0x10, 0x81, 0x44, 0xef, + 0x49, 0xd6, 0xae, 0x2e, 0xdd, 0x76, 0x5c, 0x2f, + 0xa7, 0x1c, 0xc9, 0x09, 0x69, 0x9a, 0x83, 0xcf, + 0x29, 0x39, 0xb9, 0xe9, 0x4c, 0xff, 0x43, 0xab, +}; + +unsigned char num_to_ebits[256] = { + 0x5d, 0xbe, 0x9b, 0x8b, 0x11, 0x99, 0x6e, 0x4d, + 0x59, 0xf3, 0x85, 0xa6, 0x3f, 0xb7, 0x83, 0xc5, + 0xe4, 0x73, 0x6b, 0x3a, 0x68, 0x5a, 0xc0, 0x47, + 0xa0, 0x64, 0x34, 0x0c, 0xf1, 0xd0, 0x52, 0xa5, + 0xb9, 0x1e, 0x96, 0x43, 0x41, 0xd8, 0xd4, 0x2c, + 0xdb, 0xf8, 0x07, 0x77, 0x2a, 0xca, 0xeb, 0xef, + 0x10, 0x1c, 0x16, 0x0d, 0x38, 0x72, 0x2f, 0x89, + 0xc1, 0xf9, 0x80, 0xc4, 0x6d, 0xae, 0x30, 0x3d, + 0xce, 0x20, 0x63, 0xfe, 0xe6, 0x1a, 0xc7, 0xb8, + 0x50, 0xe8, 0x24, 0x17, 0xfc, 0x25, 0x6f, 0xbb, + 0x6a, 0xa3, 0x44, 0x53, 0xd9, 0xa2, 0x01, 0xab, + 0xbc, 0xb6, 0x1f, 0x98, 0xee, 0x9a, 0xa7, 0x2d, + 0x4f, 0x9e, 0x8e, 0xac, 0xe0, 0xc6, 0x49, 0x46, + 0x29, 0xf4, 0x94, 0x8a, 0xaf, 0xe1, 0x5b, 0xc3, + 0xb3, 0x7b, 0x57, 0xd1, 0x7c, 0x9c, 0xed, 0x87, + 0x40, 0x8c, 0xe2, 0xcb, 0x93, 0x14, 0xc9, 0x61, + 0x2e, 0xe5, 0xcc, 0xf6, 0x5e, 0xa8, 0x5c, 0xd6, + 0x75, 0x8d, 0x62, 0x95, 0x58, 0x69, 0x76, 0xa1, + 0x4a, 0xb5, 0x55, 0x09, 0x78, 0x33, 0x82, 0xd7, + 0xdd, 0x79, 0xf5, 0x1b, 0x0b, 0xde, 0x26, 0x21, + 0x28, 0x74, 0x04, 0x97, 0x56, 0xdf, 0x3c, 0xf0, + 0x37, 0x39, 0xdc, 0xff, 0x06, 0xa4, 0xea, 0x42, + 0x08, 0xda, 0xb4, 0x71, 0xb0, 0xcf, 0x12, 0x7a, + 0x4e, 0xfa, 0x6c, 0x1d, 0x84, 0x00, 0xc8, 0x7f, + 0x91, 0x45, 0xaa, 0x2b, 0xc2, 0xb1, 0x8f, 0xd5, + 0xba, 0xf2, 0xad, 0x19, 0xb2, 0x67, 0x36, 0xf7, + 0x0f, 0x0a, 0x92, 0x7d, 0xe3, 0x9d, 0xe9, 0x90, + 0x3e, 0x23, 0x27, 0x66, 0x13, 0xec, 0x81, 0x15, + 0xbd, 0x22, 0xbf, 0x9f, 0x7e, 0xa9, 0x51, 0x4b, + 0x4c, 0xfb, 0x02, 0xd3, 0x70, 0x86, 0x31, 0xe7, + 0x3b, 0x05, 0x03, 0x54, 0x60, 0x48, 0x65, 0x18, + 0xd2, 0xcd, 0x5f, 0x32, 0x88, 0x0e, 0x35, 0xfd, +}; + +main() +{ + int i, j; + + for (i = 0; i < 256; i++) { + for (j = 0; j < 256; j++) + if (ebits_to_num[j] == i) { + printf("0x%02x,", j); + break; + } + } +} diff --git a/libs/openssl/crypto/rc2/version b/libs/openssl/crypto/rc2/version new file mode 100644 index 00000000..6f89d595 --- /dev/null +++ b/libs/openssl/crypto/rc2/version @@ -0,0 +1,22 @@ +1.1 23/08/96 - eay + Changed RC2_set_key() so it now takes another argument. Many + thanks to Peter Gutmann for the + clarification and origional specification of RC2. BSAFE uses + this last parameter, 'bits'. It the key is 128 bits, BSAFE + also sets this parameter to 128. The old behaviour can be + duplicated by setting this parameter to 1024. + +1.0 08/04/96 - eay + First version of SSLeay with rc2. This has been written from the spec + posted sci.crypt. It is in this directory under rrc2.doc + I have no test values for any mode other than ecb, my wrappers for the + other modes should be ok since they are basically the same as + the ones taken from idea and des :-). I have implemented them as + little-endian operators. + While rc2 is included because it is used with SSL, I don't know how + far I trust it. It is about the same speed as IDEA and DES. + So if you are paranoid, used Tripple DES, else IDEA. If RC2 + does get used more, perhaps more people will look for weaknesses in + it. + + diff --git a/libs/openssl/crypto/rc4/asm/rc4-586.pl b/libs/openssl/crypto/rc4/asm/rc4-586.pl new file mode 100644 index 00000000..5c9ac6ad --- /dev/null +++ b/libs/openssl/crypto/rc4/asm/rc4-586.pl @@ -0,0 +1,410 @@ +#!/usr/bin/env perl + +# ==================================================================== +# [Re]written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# At some point it became apparent that the original SSLeay RC4 +# assembler implementation performs suboptimally on latest IA-32 +# microarchitectures. After re-tuning performance has changed as +# following: +# +# Pentium -10% +# Pentium III +12% +# AMD +50%(*) +# P4 +250%(**) +# +# (*) This number is actually a trade-off:-) It's possible to +# achieve +72%, but at the cost of -48% off PIII performance. +# In other words code performing further 13% faster on AMD +# would perform almost 2 times slower on Intel PIII... +# For reference! This code delivers ~80% of rc4-amd64.pl +# performance on the same Opteron machine. +# (**) This number requires compressed key schedule set up by +# RC4_set_key [see commentary below for further details]. +# +# + +# May 2011 +# +# Optimize for Core2 and Westmere [and incidentally Opteron]. Current +# performance in cycles per processed byte (less is better) and +# improvement relative to previous version of this module is: +# +# Pentium 10.2 # original numbers +# Pentium III 7.8(*) +# Intel P4 7.5 +# +# Opteron 6.1/+20% # new MMX numbers +# Core2 5.3/+67%(**) +# Westmere 5.1/+94%(**) +# Sandy Bridge 5.0/+8% +# Atom 12.6/+6% +# +# (*) PIII can actually deliver 6.6 cycles per byte with MMX code, +# but this specific code performs poorly on Core2. And vice +# versa, below MMX/SSE code delivering 5.8/7.1 on Core2 performs +# poorly on PIII, at 8.0/14.5:-( As PIII is not a "hot" CPU +# [anymore], I chose to discard PIII-specific code path and opt +# for original IALU-only code, which is why MMX/SSE code path +# is guarded by SSE2 bit (see below), not MMX/SSE. +# (**) Performance vs. block size on Core2 and Westmere had a maximum +# at ... 64 bytes block size. And it was quite a maximum, 40-60% +# in comparison to largest 8KB block size. Above improvement +# coefficients are for the largest block size. + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"rc4-586.pl"); + +$xx="eax"; +$yy="ebx"; +$tx="ecx"; +$ty="edx"; +$inp="esi"; +$out="ebp"; +$dat="edi"; + +sub RC4_loop { + my $i=shift; + my $func = ($i==0)?*mov:*or; + + &add (&LB($yy),&LB($tx)); + &mov ($ty,&DWP(0,$dat,$yy,4)); + &mov (&DWP(0,$dat,$yy,4),$tx); + &mov (&DWP(0,$dat,$xx,4),$ty); + &add ($ty,$tx); + &inc (&LB($xx)); + &and ($ty,0xff); + &ror ($out,8) if ($i!=0); + if ($i<3) { + &mov ($tx,&DWP(0,$dat,$xx,4)); + } else { + &mov ($tx,&wparam(3)); # reload [re-biased] out + } + &$func ($out,&DWP(0,$dat,$ty,4)); +} + +if ($alt=0) { + # >20% faster on Atom and Sandy Bridge[!], 8% faster on Opteron, + # but ~40% slower on Core2 and Westmere... Attempt to add movz + # brings down Opteron by 25%, Atom and Sandy Bridge by 15%, yet + # on Core2 with movz it's almost 20% slower than below alternative + # code... Yes, it's a total mess... + my @XX=($xx,$out); + $RC4_loop_mmx = sub { # SSE actually... + my $i=shift; + my $j=$i<=0?0:$i>>1; + my $mm=$i<=0?"mm0":"mm".($i&1); + + &add (&LB($yy),&LB($tx)); + &lea (@XX[1],&DWP(1,@XX[0])); + &pxor ("mm2","mm0") if ($i==0); + &psllq ("mm1",8) if ($i==0); + &and (@XX[1],0xff); + &pxor ("mm0","mm0") if ($i<=0); + &mov ($ty,&DWP(0,$dat,$yy,4)); + &mov (&DWP(0,$dat,$yy,4),$tx); + &pxor ("mm1","mm2") if ($i==0); + &mov (&DWP(0,$dat,$XX[0],4),$ty); + &add (&LB($ty),&LB($tx)); + &movd (@XX[0],"mm7") if ($i==0); + &mov ($tx,&DWP(0,$dat,@XX[1],4)); + &pxor ("mm1","mm1") if ($i==1); + &movq ("mm2",&QWP(0,$inp)) if ($i==1); + &movq (&QWP(-8,(@XX[0],$inp)),"mm1") if ($i==0); + &pinsrw ($mm,&DWP(0,$dat,$ty,4),$j); + + push (@XX,shift(@XX)) if ($i>=0); + } +} else { + # Using pinsrw here improves performane on Intel CPUs by 2-3%, but + # brings down AMD by 7%... + $RC4_loop_mmx = sub { + my $i=shift; + + &add (&LB($yy),&LB($tx)); + &psllq ("mm1",8*(($i-1)&7)) if (abs($i)!=1); + &mov ($ty,&DWP(0,$dat,$yy,4)); + &mov (&DWP(0,$dat,$yy,4),$tx); + &mov (&DWP(0,$dat,$xx,4),$ty); + &inc ($xx); + &add ($ty,$tx); + &movz ($xx,&LB($xx)); # (*) + &movz ($ty,&LB($ty)); # (*) + &pxor ("mm2",$i==1?"mm0":"mm1") if ($i>=0); + &movq ("mm0",&QWP(0,$inp)) if ($i<=0); + &movq (&QWP(-8,($out,$inp)),"mm2") if ($i==0); + &mov ($tx,&DWP(0,$dat,$xx,4)); + &movd ($i>0?"mm1":"mm2",&DWP(0,$dat,$ty,4)); + + # (*) This is the key to Core2 and Westmere performance. + # Whithout movz out-of-order execution logic confuses + # itself and fails to reorder loads and stores. Problem + # appears to be fixed in Sandy Bridge... + } +} + +&external_label("OPENSSL_ia32cap_P"); + +# void RC4(RC4_KEY *key,size_t len,const unsigned char *inp,unsigned char *out); +&function_begin("RC4"); + &mov ($dat,&wparam(0)); # load key schedule pointer + &mov ($ty, &wparam(1)); # load len + &mov ($inp,&wparam(2)); # load inp + &mov ($out,&wparam(3)); # load out + + &xor ($xx,$xx); # avoid partial register stalls + &xor ($yy,$yy); + + &cmp ($ty,0); # safety net + &je (&label("abort")); + + &mov (&LB($xx),&BP(0,$dat)); # load key->x + &mov (&LB($yy),&BP(4,$dat)); # load key->y + &add ($dat,8); + + &lea ($tx,&DWP(0,$inp,$ty)); + &sub ($out,$inp); # re-bias out + &mov (&wparam(1),$tx); # save input+len + + &inc (&LB($xx)); + + # detect compressed key schedule... + &cmp (&DWP(256,$dat),-1); + &je (&label("RC4_CHAR")); + + &mov ($tx,&DWP(0,$dat,$xx,4)); + + &and ($ty,-4); # how many 4-byte chunks? + &jz (&label("loop1")); + + &test ($ty,-8); + &mov (&wparam(3),$out); # $out as accumulator in these loops + &jz (&label("go4loop4")); + + &picmeup($out,"OPENSSL_ia32cap_P"); + &bt (&DWP(0,$out),26); # check SSE2 bit [could have been MMX] + &jnc (&label("go4loop4")); + + &mov ($out,&wparam(3)) if (!$alt); + &movd ("mm7",&wparam(3)) if ($alt); + &and ($ty,-8); + &lea ($ty,&DWP(-8,$inp,$ty)); + &mov (&DWP(-4,$dat),$ty); # save input+(len/8)*8-8 + + &$RC4_loop_mmx(-1); + &jmp(&label("loop_mmx_enter")); + + &set_label("loop_mmx",16); + &$RC4_loop_mmx(0); + &set_label("loop_mmx_enter"); + for ($i=1;$i<8;$i++) { &$RC4_loop_mmx($i); } + &mov ($ty,$yy); + &xor ($yy,$yy); # this is second key to Core2 + &mov (&LB($yy),&LB($ty)); # and Westmere performance... + &cmp ($inp,&DWP(-4,$dat)); + &lea ($inp,&DWP(8,$inp)); + &jb (&label("loop_mmx")); + + if ($alt) { + &movd ($out,"mm7"); + &pxor ("mm2","mm0"); + &psllq ("mm1",8); + &pxor ("mm1","mm2"); + &movq (&QWP(-8,$out,$inp),"mm1"); + } else { + &psllq ("mm1",56); + &pxor ("mm2","mm1"); + &movq (&QWP(-8,$out,$inp),"mm2"); + } + &emms (); + + &cmp ($inp,&wparam(1)); # compare to input+len + &je (&label("done")); + &jmp (&label("loop1")); + +&set_label("go4loop4",16); + &lea ($ty,&DWP(-4,$inp,$ty)); + &mov (&wparam(2),$ty); # save input+(len/4)*4-4 + + &set_label("loop4"); + for ($i=0;$i<4;$i++) { RC4_loop($i); } + &ror ($out,8); + &xor ($out,&DWP(0,$inp)); + &cmp ($inp,&wparam(2)); # compare to input+(len/4)*4-4 + &mov (&DWP(0,$tx,$inp),$out);# $tx holds re-biased out here + &lea ($inp,&DWP(4,$inp)); + &mov ($tx,&DWP(0,$dat,$xx,4)); + &jb (&label("loop4")); + + &cmp ($inp,&wparam(1)); # compare to input+len + &je (&label("done")); + &mov ($out,&wparam(3)); # restore $out + + &set_label("loop1",16); + &add (&LB($yy),&LB($tx)); + &mov ($ty,&DWP(0,$dat,$yy,4)); + &mov (&DWP(0,$dat,$yy,4),$tx); + &mov (&DWP(0,$dat,$xx,4),$ty); + &add ($ty,$tx); + &inc (&LB($xx)); + &and ($ty,0xff); + &mov ($ty,&DWP(0,$dat,$ty,4)); + &xor (&LB($ty),&BP(0,$inp)); + &lea ($inp,&DWP(1,$inp)); + &mov ($tx,&DWP(0,$dat,$xx,4)); + &cmp ($inp,&wparam(1)); # compare to input+len + &mov (&BP(-1,$out,$inp),&LB($ty)); + &jb (&label("loop1")); + + &jmp (&label("done")); + +# this is essentially Intel P4 specific codepath... +&set_label("RC4_CHAR",16); + &movz ($tx,&BP(0,$dat,$xx)); + # strangely enough unrolled loop performs over 20% slower... + &set_label("cloop1"); + &add (&LB($yy),&LB($tx)); + &movz ($ty,&BP(0,$dat,$yy)); + &mov (&BP(0,$dat,$yy),&LB($tx)); + &mov (&BP(0,$dat,$xx),&LB($ty)); + &add (&LB($ty),&LB($tx)); + &movz ($ty,&BP(0,$dat,$ty)); + &add (&LB($xx),1); + &xor (&LB($ty),&BP(0,$inp)); + &lea ($inp,&DWP(1,$inp)); + &movz ($tx,&BP(0,$dat,$xx)); + &cmp ($inp,&wparam(1)); + &mov (&BP(-1,$out,$inp),&LB($ty)); + &jb (&label("cloop1")); + +&set_label("done"); + &dec (&LB($xx)); + &mov (&DWP(-4,$dat),$yy); # save key->y + &mov (&BP(-8,$dat),&LB($xx)); # save key->x +&set_label("abort"); +&function_end("RC4"); + +######################################################################## + +$inp="esi"; +$out="edi"; +$idi="ebp"; +$ido="ecx"; +$idx="edx"; + +# void RC4_set_key(RC4_KEY *key,int len,const unsigned char *data); +&function_begin("private_RC4_set_key"); + &mov ($out,&wparam(0)); # load key + &mov ($idi,&wparam(1)); # load len + &mov ($inp,&wparam(2)); # load data + &picmeup($idx,"OPENSSL_ia32cap_P"); + + &lea ($out,&DWP(2*4,$out)); # &key->data + &lea ($inp,&DWP(0,$inp,$idi)); # $inp to point at the end + &neg ($idi); + &xor ("eax","eax"); + &mov (&DWP(-4,$out),$idi); # borrow key->y + + &bt (&DWP(0,$idx),20); # check for bit#20 + &jc (&label("c1stloop")); + +&set_label("w1stloop",16); + &mov (&DWP(0,$out,"eax",4),"eax"); # key->data[i]=i; + &add (&LB("eax"),1); # i++; + &jnc (&label("w1stloop")); + + &xor ($ido,$ido); + &xor ($idx,$idx); + +&set_label("w2ndloop",16); + &mov ("eax",&DWP(0,$out,$ido,4)); + &add (&LB($idx),&BP(0,$inp,$idi)); + &add (&LB($idx),&LB("eax")); + &add ($idi,1); + &mov ("ebx",&DWP(0,$out,$idx,4)); + &jnz (&label("wnowrap")); + &mov ($idi,&DWP(-4,$out)); + &set_label("wnowrap"); + &mov (&DWP(0,$out,$idx,4),"eax"); + &mov (&DWP(0,$out,$ido,4),"ebx"); + &add (&LB($ido),1); + &jnc (&label("w2ndloop")); +&jmp (&label("exit")); + +# Unlike all other x86 [and x86_64] implementations, Intel P4 core +# [including EM64T] was found to perform poorly with above "32-bit" key +# schedule, a.k.a. RC4_INT. Performance improvement for IA-32 hand-coded +# assembler turned out to be 3.5x if re-coded for compressed 8-bit one, +# a.k.a. RC4_CHAR! It's however inappropriate to just switch to 8-bit +# schedule for x86[_64], because non-P4 implementations suffer from +# significant performance losses then, e.g. PIII exhibits >2x +# deterioration, and so does Opteron. In order to assure optimal +# all-round performance, we detect P4 at run-time and set up compressed +# key schedule, which is recognized by RC4 procedure. + +&set_label("c1stloop",16); + &mov (&BP(0,$out,"eax"),&LB("eax")); # key->data[i]=i; + &add (&LB("eax"),1); # i++; + &jnc (&label("c1stloop")); + + &xor ($ido,$ido); + &xor ($idx,$idx); + &xor ("ebx","ebx"); + +&set_label("c2ndloop",16); + &mov (&LB("eax"),&BP(0,$out,$ido)); + &add (&LB($idx),&BP(0,$inp,$idi)); + &add (&LB($idx),&LB("eax")); + &add ($idi,1); + &mov (&LB("ebx"),&BP(0,$out,$idx)); + &jnz (&label("cnowrap")); + &mov ($idi,&DWP(-4,$out)); + &set_label("cnowrap"); + &mov (&BP(0,$out,$idx),&LB("eax")); + &mov (&BP(0,$out,$ido),&LB("ebx")); + &add (&LB($ido),1); + &jnc (&label("c2ndloop")); + + &mov (&DWP(256,$out),-1); # mark schedule as compressed + +&set_label("exit"); + &xor ("eax","eax"); + &mov (&DWP(-8,$out),"eax"); # key->x=0; + &mov (&DWP(-4,$out),"eax"); # key->y=0; +&function_end("private_RC4_set_key"); + +# const char *RC4_options(void); +&function_begin_B("RC4_options"); + &call (&label("pic_point")); +&set_label("pic_point"); + &blindpop("eax"); + &lea ("eax",&DWP(&label("opts")."-".&label("pic_point"),"eax")); + &picmeup("edx","OPENSSL_ia32cap_P"); + &mov ("edx",&DWP(0,"edx")); + &bt ("edx",20); + &jc (&label("1xchar")); + &bt ("edx",26); + &jnc (&label("ret")); + &add ("eax",25); + &ret (); +&set_label("1xchar"); + &add ("eax",12); +&set_label("ret"); + &ret (); +&set_label("opts",64); +&asciz ("rc4(4x,int)"); +&asciz ("rc4(1x,char)"); +&asciz ("rc4(8x,mmx)"); +&asciz ("RC4 for x86, CRYPTOGAMS by "); +&align (64); +&function_end_B("RC4_options"); + +&asm_finish(); + diff --git a/libs/openssl/crypto/rc4/asm/rc4-ia64.pl b/libs/openssl/crypto/rc4/asm/rc4-ia64.pl new file mode 100644 index 00000000..49cd5b5e --- /dev/null +++ b/libs/openssl/crypto/rc4/asm/rc4-ia64.pl @@ -0,0 +1,755 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by David Mosberger based on the +# Itanium optimized Crypto code which was released by HP Labs at +# http://www.hpl.hp.com/research/linux/crypto/. +# +# Copyright (c) 2005 Hewlett-Packard Development Company, L.P. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ + + + +# This is a little helper program which generates a software-pipelined +# for RC4 encryption. The basic algorithm looks like this: +# +# for (counter = 0; counter < len; ++counter) +# { +# in = inp[counter]; +# SI = S[I]; +# J = (SI + J) & 0xff; +# SJ = S[J]; +# T = (SI + SJ) & 0xff; +# S[I] = SJ, S[J] = SI; +# ST = S[T]; +# outp[counter] = in ^ ST; +# I = (I + 1) & 0xff; +# } +# +# Pipelining this loop isn't easy, because the stores to the S[] array +# need to be observed in the right order. The loop generated by the +# code below has the following pipeline diagram: +# +# cycle +# | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |10 |11 |12 |13 |14 |15 |16 |17 | +# iter +# 1: xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx +# 2: xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx +# 3: xxx LDI xxx xxx xxx LDJ xxx SWP xxx LDT xxx xxx +# +# where: +# LDI = load of S[I] +# LDJ = load of S[J] +# SWP = swap of S[I] and S[J] +# LDT = load of S[T] +# +# Note that in the above diagram, the major trouble-spot is that LDI +# of the 2nd iteration is performed BEFORE the SWP of the first +# iteration. Fortunately, this is easy to detect (I of the 1st +# iteration will be equal to J of the 2nd iteration) and when this +# happens, we simply forward the proper value from the 1st iteration +# to the 2nd one. The proper value in this case is simply the value +# of S[I] from the first iteration (thanks to the fact that SWP +# simply swaps the contents of S[I] and S[J]). +# +# Another potential trouble-spot is in cycle 7, where SWP of the 1st +# iteration issues at the same time as the LDI of the 3rd iteration. +# However, thanks to IA-64 execution semantics, this can be taken +# care of simply by placing LDI later in the instruction-group than +# SWP. IA-64 CPUs will automatically forward the value if they +# detect that the SWP and LDI are accessing the same memory-location. + +# The core-loop that can be pipelined then looks like this (annotated +# with McKinley/Madison issue port & latency numbers, assuming L1 +# cache hits for the most part): + +# operation: instruction: issue-ports: latency +# ------------------ ----------------------------- ------------- ------- + +# Data = *inp++ ld1 data = [inp], 1 M0-M1 1 cyc c0 +# shladd Iptr = I, KeyTable, 3 M0-M3, I0, I1 1 cyc +# I = (I + 1) & 0xff padd1 nextI = I, one M0-M3, I0, I1 3 cyc +# ;; +# SI = S[I] ld8 SI = [Iptr] M0-M1 1 cyc c1 * after SWAP! +# ;; +# cmp.eq.unc pBypass = I, J * after J is valid! +# J = SI + J add J = J, SI M0-M3, I0, I1 1 cyc c2 +# (pBypass) br.cond.spnt Bypass +# ;; +# --------------------------------------------------------------------------------------- +# J = J & 0xff zxt1 J = J I0, I1, 1 cyc c3 +# ;; +# shladd Jptr = J, KeyTable, 3 M0-M3, I0, I1 1 cyc c4 +# ;; +# SJ = S[J] ld8 SJ = [Jptr] M0-M1 1 cyc c5 +# ;; +# --------------------------------------------------------------------------------------- +# T = (SI + SJ) add T = SI, SJ M0-M3, I0, I1 1 cyc c6 +# ;; +# T = T & 0xff zxt1 T = T I0, I1 1 cyc +# S[I] = SJ st8 [Iptr] = SJ M2-M3 c7 +# S[J] = SI st8 [Jptr] = SI M2-M3 +# ;; +# shladd Tptr = T, KeyTable, 3 M0-M3, I0, I1 1 cyc c8 +# ;; +# --------------------------------------------------------------------------------------- +# T = S[T] ld8 T = [Tptr] M0-M1 1 cyc c9 +# ;; +# data ^= T xor data = data, T M0-M3, I0, I1 1 cyc c10 +# ;; +# *out++ = Data ^ T dep word = word, data, 8, POS I0, I1 1 cyc c11 +# ;; +# --------------------------------------------------------------------------------------- + +# There are several points worth making here: + +# - Note that due to the bypass/forwarding-path, the first two +# phases of the loop are strangly mingled together. In +# particular, note that the first stage of the pipeline is +# using the value of "J", as calculated by the second stage. +# - Each bundle-pair will have exactly 6 instructions. +# - Pipelined, the loop can execute in 3 cycles/iteration and +# 4 stages. However, McKinley/Madison can issue "st1" to +# the same bank at a rate of at most one per 4 cycles. Thus, +# instead of storing each byte, we accumulate them in a word +# and then write them back at once with a single "st8" (this +# implies that the setup code needs to ensure that the output +# buffer is properly aligned, if need be, by encoding the +# first few bytes separately). +# - There is no space for a "br.ctop" instruction. For this +# reason we can't use module-loop support in IA-64 and have +# to do a traditional, purely software-pipelined loop. +# - We can't replace any of the remaining "add/zxt1" pairs with +# "padd1" because the latency for that instruction is too high +# and would push the loop to the point where more bypasses +# would be needed, which we don't have space for. +# - The above loop runs at around 3.26 cycles/byte, or roughly +# 440 MByte/sec on a 1.5GHz Madison. This is well below the +# system bus bandwidth and hence with judicious use of +# "lfetch" this loop can run at (almost) peak speed even when +# the input and output data reside in memory. The +# max. latency that can be tolerated is (PREFETCH_DISTANCE * +# L2_LINE_SIZE * 3 cyc), or about 384 cycles assuming (at +# least) 1-ahead prefetching of 128 byte cache-lines. Note +# that we do NOT prefetch into L1, since that would only +# interfere with the S[] table values stored there. This is +# acceptable because there is a 10 cycle latency between +# load and first use of the input data. +# - We use a branch to out-of-line bypass-code of cycle-pressure: +# we calculate the next J, check for the need to activate the +# bypass path, and activate the bypass path ALL IN THE SAME +# CYCLE. If we didn't have these constraints, we could do +# the bypass with a simple conditional move instruction. +# Fortunately, the bypass paths get activated relatively +# infrequently, so the extra branches don't cost all that much +# (about 0.04 cycles/byte, measured on a 16396 byte file with +# random input data). +# + +$phases = 4; # number of stages/phases in the pipelined-loop +$unroll_count = 6; # number of times we unrolled it +$pComI = (1 << 0); +$pComJ = (1 << 1); +$pComT = (1 << 2); +$pOut = (1 << 3); + +$NData = 4; +$NIP = 3; +$NJP = 2; +$NI = 2; +$NSI = 3; +$NSJ = 2; +$NT = 2; +$NOutWord = 2; + +# +# $threshold is the minimum length before we attempt to use the +# big software-pipelined loop. It MUST be greater-or-equal +# to: +# PHASES * (UNROLL_COUNT + 1) + 7 +# +# The "+ 7" comes from the fact we may have to encode up to +# 7 bytes separately before the output pointer is aligned. +# +$threshold = (3 * ($phases * ($unroll_count + 1)) + 7); + +sub I { + local *code = shift; + local $format = shift; + $code .= sprintf ("\t\t".$format."\n", @_); +} + +sub P { + local *code = shift; + local $format = shift; + $code .= sprintf ($format."\n", @_); +} + +sub STOP { + local *code = shift; + $code .=<<___; + ;; +___ +} + +sub emit_body { + local *c = shift; + local *bypass = shift; + local ($iteration, $p) = @_; + + local $i0 = $iteration; + local $i1 = $iteration - 1; + local $i2 = $iteration - 2; + local $i3 = $iteration - 3; + local $iw0 = ($iteration - 3) / 8; + local $iw1 = ($iteration > 3) ? ($iteration - 4) / 8 : 1; + local $byte_num = ($iteration - 3) % 8; + local $label = $iteration + 1; + local $pAny = ($p & 0xf) == 0xf; + local $pByp = (($p & $pComI) && ($iteration > 0)); + + $c.=<<___; +////////////////////////////////////////////////// +___ + + if (($p & 0xf) == 0) { + $c.="#ifdef HOST_IS_BIG_ENDIAN\n"; + &I(\$c,"shr.u OutWord[%u] = OutWord[%u], 32;;", + $iw1 % $NOutWord, $iw1 % $NOutWord); + $c.="#endif\n"; + &I(\$c, "st4 [OutPtr] = OutWord[%u], 4", $iw1 % $NOutWord); + return; + } + + # Cycle 0 + &I(\$c, "{ .mmi") if ($pAny); + &I(\$c, "ld1 Data[%u] = [InPtr], 1", $i0 % $NData) if ($p & $pComI); + &I(\$c, "padd1 I[%u] = One, I[%u]", $i0 % $NI, $i1 % $NI)if ($p & $pComI); + &I(\$c, "zxt1 J = J") if ($p & $pComJ); + &I(\$c, "}") if ($pAny); + &I(\$c, "{ .mmi") if ($pAny); + &I(\$c, "LKEY T[%u] = [T[%u]]", $i1 % $NT, $i1 % $NT) if ($p & $pOut); + &I(\$c, "add T[%u] = SI[%u], SJ[%u]", + $i0 % $NT, $i2 % $NSI, $i1 % $NSJ) if ($p & $pComT); + &I(\$c, "KEYADDR(IPr[%u], I[%u])", $i0 % $NIP, $i1 % $NI) if ($p & $pComI); + &I(\$c, "}") if ($pAny); + &STOP(\$c); + + # Cycle 1 + &I(\$c, "{ .mmi") if ($pAny); + &I(\$c, "SKEY [IPr[%u]] = SJ[%u]", $i2 % $NIP, $i1%$NSJ)if ($p & $pComT); + &I(\$c, "SKEY [JP[%u]] = SI[%u]", $i1 % $NJP, $i2%$NSI) if ($p & $pComT); + &I(\$c, "zxt1 T[%u] = T[%u]", $i0 % $NT, $i0 % $NT) if ($p & $pComT); + &I(\$c, "}") if ($pAny); + &I(\$c, "{ .mmi") if ($pAny); + &I(\$c, "LKEY SI[%u] = [IPr[%u]]", $i0 % $NSI, $i0%$NIP)if ($p & $pComI); + &I(\$c, "KEYADDR(JP[%u], J)", $i0 % $NJP) if ($p & $pComJ); + &I(\$c, "xor Data[%u] = Data[%u], T[%u]", + $i3 % $NData, $i3 % $NData, $i1 % $NT) if ($p & $pOut); + &I(\$c, "}") if ($pAny); + &STOP(\$c); + + # Cycle 2 + &I(\$c, "{ .mmi") if ($pAny); + &I(\$c, "LKEY SJ[%u] = [JP[%u]]", $i0 % $NSJ, $i0%$NJP) if ($p & $pComJ); + &I(\$c, "cmp.eq pBypass, p0 = I[%u], J", $i1 % $NI) if ($pByp); + &I(\$c, "dep OutWord[%u] = Data[%u], OutWord[%u], BYTE_POS(%u), 8", + $iw0%$NOutWord, $i3%$NData, $iw1%$NOutWord, $byte_num) if ($p & $pOut); + &I(\$c, "}") if ($pAny); + &I(\$c, "{ .mmb") if ($pAny); + &I(\$c, "add J = J, SI[%u]", $i0 % $NSI) if ($p & $pComI); + &I(\$c, "KEYADDR(T[%u], T[%u])", $i0 % $NT, $i0 % $NT) if ($p & $pComT); + &P(\$c, "(pBypass)\tbr.cond.spnt.many .rc4Bypass%u",$label)if ($pByp); + &I(\$c, "}") if ($pAny); + &STOP(\$c); + + &P(\$c, ".rc4Resume%u:", $label) if ($pByp); + if ($byte_num == 0 && $iteration >= $phases) { + &I(\$c, "st8 [OutPtr] = OutWord[%u], 8", + $iw1 % $NOutWord) if ($p & $pOut); + if ($iteration == (1 + $unroll_count) * $phases - 1) { + if ($unroll_count == 6) { + &I(\$c, "mov OutWord[%u] = OutWord[%u]", + $iw1 % $NOutWord, $iw0 % $NOutWord); + } + &I(\$c, "lfetch.nt1 [InPrefetch], %u", + $unroll_count * $phases); + &I(\$c, "lfetch.excl.nt1 [OutPrefetch], %u", + $unroll_count * $phases); + &I(\$c, "br.cloop.sptk.few .rc4Loop"); + } + } + + if ($pByp) { + &P(\$bypass, ".rc4Bypass%u:", $label); + &I(\$bypass, "sub J = J, SI[%u]", $i0 % $NSI); + &I(\$bypass, "nop 0"); + &I(\$bypass, "nop 0"); + &I(\$bypass, ";;"); + &I(\$bypass, "add J = J, SI[%u]", $i1 % $NSI); + &I(\$bypass, "mov SI[%u] = SI[%u]", $i0 % $NSI, $i1 % $NSI); + &I(\$bypass, "br.sptk.many .rc4Resume%u\n", $label); + &I(\$bypass, ";;"); + } +} + +$code=<<___; +.ident \"rc4-ia64.s, version 3.0\" +.ident \"Copyright (c) 2005 Hewlett-Packard Development Company, L.P.\" + +#define LCSave r8 +#define PRSave r9 + +/* Inputs become invalid once rotation begins! */ + +#define StateTable in0 +#define DataLen in1 +#define InputBuffer in2 +#define OutputBuffer in3 + +#define KTable r14 +#define J r15 +#define InPtr r16 +#define OutPtr r17 +#define InPrefetch r18 +#define OutPrefetch r19 +#define One r20 +#define LoopCount r21 +#define Remainder r22 +#define IFinal r23 +#define EndPtr r24 + +#define tmp0 r25 +#define tmp1 r26 + +#define pBypass p6 +#define pDone p7 +#define pSmall p8 +#define pAligned p9 +#define pUnaligned p10 + +#define pComputeI pPhase[0] +#define pComputeJ pPhase[1] +#define pComputeT pPhase[2] +#define pOutput pPhase[3] + +#define RetVal r8 +#define L_OK p7 +#define L_NOK p8 + +#define _NINPUTS 4 +#define _NOUTPUT 0 + +#define _NROTATE 24 +#define _NLOCALS (_NROTATE - _NINPUTS - _NOUTPUT) + +#ifndef SZ +# define SZ 4 // this must be set to sizeof(RC4_INT) +#endif + +#if SZ == 1 +# define LKEY ld1 +# define SKEY st1 +# define KEYADDR(dst, i) add dst = i, KTable +#elif SZ == 2 +# define LKEY ld2 +# define SKEY st2 +# define KEYADDR(dst, i) shladd dst = i, 1, KTable +#elif SZ == 4 +# define LKEY ld4 +# define SKEY st4 +# define KEYADDR(dst, i) shladd dst = i, 2, KTable +#else +# define LKEY ld8 +# define SKEY st8 +# define KEYADDR(dst, i) shladd dst = i, 3, KTable +#endif + +#if defined(_HPUX_SOURCE) && !defined(_LP64) +# define ADDP addp4 +#else +# define ADDP add +#endif + +/* Define a macro for the bit number of the n-th byte: */ + +#if defined(_HPUX_SOURCE) || defined(B_ENDIAN) +# define HOST_IS_BIG_ENDIAN +# define BYTE_POS(n) (56 - (8 * (n))) +#else +# define BYTE_POS(n) (8 * (n)) +#endif + +/* + We must perform the first phase of the pipeline explicitly since + we will always load from the stable the first time. The br.cexit + will never be taken since regardless of the number of bytes because + the epilogue count is 4. +*/ +/* MODSCHED_RC4 macro was split to _PROLOGUE and _LOOP, because HP-UX + assembler failed on original macro with syntax error. */ +#define MODSCHED_RC4_PROLOGUE \\ + { \\ + ld1 Data[0] = [InPtr], 1; \\ + add IFinal = 1, I[1]; \\ + KEYADDR(IPr[0], I[1]); \\ + } ;; \\ + { \\ + LKEY SI[0] = [IPr[0]]; \\ + mov pr.rot = 0x10000; \\ + mov ar.ec = 4; \\ + } ;; \\ + { \\ + add J = J, SI[0]; \\ + zxt1 I[0] = IFinal; \\ + br.cexit.spnt.few .+16; /* never taken */ \\ + } ;; +#define MODSCHED_RC4_LOOP(label) \\ +label: \\ + { .mmi; \\ + (pComputeI) ld1 Data[0] = [InPtr], 1; \\ + (pComputeI) add IFinal = 1, I[1]; \\ + (pComputeJ) zxt1 J = J; \\ + }{ .mmi; \\ + (pOutput) LKEY T[1] = [T[1]]; \\ + (pComputeT) add T[0] = SI[2], SJ[1]; \\ + (pComputeI) KEYADDR(IPr[0], I[1]); \\ + } ;; \\ + { .mmi; \\ + (pComputeT) SKEY [IPr[2]] = SJ[1]; \\ + (pComputeT) SKEY [JP[1]] = SI[2]; \\ + (pComputeT) zxt1 T[0] = T[0]; \\ + }{ .mmi; \\ + (pComputeI) LKEY SI[0] = [IPr[0]]; \\ + (pComputeJ) KEYADDR(JP[0], J); \\ + (pComputeI) cmp.eq.unc pBypass, p0 = I[1], J; \\ + } ;; \\ + { .mmi; \\ + (pComputeJ) LKEY SJ[0] = [JP[0]]; \\ + (pOutput) xor Data[3] = Data[3], T[1]; \\ + nop 0x0; \\ + }{ .mmi; \\ + (pComputeT) KEYADDR(T[0], T[0]); \\ + (pBypass) mov SI[0] = SI[1]; \\ + (pComputeI) zxt1 I[0] = IFinal; \\ + } ;; \\ + { .mmb; \\ + (pOutput) st1 [OutPtr] = Data[3], 1; \\ + (pComputeI) add J = J, SI[0]; \\ + br.ctop.sptk.few label; \\ + } ;; + + .text + + .align 32 + + .type RC4, \@function + .global RC4 + + .proc RC4 + .prologue + +RC4: + { + .mmi + alloc r2 = ar.pfs, _NINPUTS, _NLOCALS, _NOUTPUT, _NROTATE + + .rotr Data[4], I[2], IPr[3], SI[3], JP[2], SJ[2], T[2], \\ + OutWord[2] + .rotp pPhase[4] + + ADDP InPrefetch = 0, InputBuffer + ADDP KTable = 0, StateTable + } + { + .mmi + ADDP InPtr = 0, InputBuffer + ADDP OutPtr = 0, OutputBuffer + mov RetVal = r0 + } + ;; + { + .mmi + lfetch.nt1 [InPrefetch], 0x80 + ADDP OutPrefetch = 0, OutputBuffer + } + { // Return 0 if the input length is nonsensical + .mib + ADDP StateTable = 0, StateTable + cmp.ge.unc L_NOK, L_OK = r0, DataLen + (L_NOK) br.ret.sptk.few rp + } + ;; + { + .mib + cmp.eq.or L_NOK, L_OK = r0, InPtr + cmp.eq.or L_NOK, L_OK = r0, OutPtr + nop 0x0 + } + { + .mib + cmp.eq.or L_NOK, L_OK = r0, StateTable + nop 0x0 + (L_NOK) br.ret.sptk.few rp + } + ;; + LKEY I[1] = [KTable], SZ +/* Prefetch the state-table. It contains 256 elements of size SZ */ + +#if SZ == 1 + ADDP tmp0 = 1*128, StateTable +#elif SZ == 2 + ADDP tmp0 = 3*128, StateTable + ADDP tmp1 = 2*128, StateTable +#elif SZ == 4 + ADDP tmp0 = 7*128, StateTable + ADDP tmp1 = 6*128, StateTable +#elif SZ == 8 + ADDP tmp0 = 15*128, StateTable + ADDP tmp1 = 14*128, StateTable +#endif + ;; +#if SZ >= 8 + lfetch.fault.nt1 [tmp0], -256 // 15 + lfetch.fault.nt1 [tmp1], -256;; + lfetch.fault.nt1 [tmp0], -256 // 13 + lfetch.fault.nt1 [tmp1], -256;; + lfetch.fault.nt1 [tmp0], -256 // 11 + lfetch.fault.nt1 [tmp1], -256;; + lfetch.fault.nt1 [tmp0], -256 // 9 + lfetch.fault.nt1 [tmp1], -256;; +#endif +#if SZ >= 4 + lfetch.fault.nt1 [tmp0], -256 // 7 + lfetch.fault.nt1 [tmp1], -256;; + lfetch.fault.nt1 [tmp0], -256 // 5 + lfetch.fault.nt1 [tmp1], -256;; +#endif +#if SZ >= 2 + lfetch.fault.nt1 [tmp0], -256 // 3 + lfetch.fault.nt1 [tmp1], -256;; +#endif + { + .mii + lfetch.fault.nt1 [tmp0] // 1 + add I[1]=1,I[1];; + zxt1 I[1]=I[1] + } + { + .mmi + lfetch.nt1 [InPrefetch], 0x80 + lfetch.excl.nt1 [OutPrefetch], 0x80 + .save pr, PRSave + mov PRSave = pr + } ;; + { + .mmi + lfetch.excl.nt1 [OutPrefetch], 0x80 + LKEY J = [KTable], SZ + ADDP EndPtr = DataLen, InPtr + } ;; + { + .mmi + ADDP EndPtr = -1, EndPtr // Make it point to + // last data byte. + mov One = 1 + .save ar.lc, LCSave + mov LCSave = ar.lc + .body + } ;; + { + .mmb + sub Remainder = 0, OutPtr + cmp.gtu pSmall, p0 = $threshold, DataLen +(pSmall) br.cond.dpnt .rc4Remainder // Data too small for + // big loop. + } ;; + { + .mmi + and Remainder = 0x7, Remainder + ;; + cmp.eq pAligned, pUnaligned = Remainder, r0 + nop 0x0 + } ;; + { + .mmb +.pred.rel "mutex",pUnaligned,pAligned +(pUnaligned) add Remainder = -1, Remainder +(pAligned) sub Remainder = EndPtr, InPtr +(pAligned) br.cond.dptk.many .rc4Aligned + } ;; + { + .mmi + nop 0x0 + nop 0x0 + mov.i ar.lc = Remainder + } + +/* Do the initial few bytes via the compact, modulo-scheduled loop + until the output pointer is 8-byte-aligned. */ + + MODSCHED_RC4_PROLOGUE + MODSCHED_RC4_LOOP(.RC4AlignLoop) + + { + .mib + sub Remainder = EndPtr, InPtr + zxt1 IFinal = IFinal + clrrrb // Clear CFM.rrb.pr so + ;; // next "mov pr.rot = N" + // does the right thing. + } + { + .mmi + mov I[1] = IFinal + nop 0x0 + nop 0x0 + } ;; + + +.rc4Aligned: + +/* + Unrolled loop count = (Remainder - ($unroll_count+1)*$phases)/($unroll_count*$phases) + */ + + { + .mlx + add LoopCount = 1 - ($unroll_count + 1)*$phases, Remainder + movl Remainder = 0xaaaaaaaaaaaaaaab + } ;; + { + .mmi + setf.sig f6 = LoopCount // M2, M3 6 cyc + setf.sig f7 = Remainder // M2, M3 6 cyc + nop 0x0 + } ;; + { + .mfb + nop 0x0 + xmpy.hu f6 = f6, f7 + nop 0x0 + } ;; + { + .mmi + getf.sig LoopCount = f6;; // M2 5 cyc + nop 0x0 + shr.u LoopCount = LoopCount, 4 + } ;; + { + .mmi + nop 0x0 + nop 0x0 + mov.i ar.lc = LoopCount + } ;; + +/* Now comes the unrolled loop: */ + +.rc4Prologue: +___ + +$iteration = 0; + +# Generate the prologue: +$predicates = 1; +for ($i = 0; $i < $phases; ++$i) { + &emit_body (\$code, \$bypass, $iteration++, $predicates); + $predicates = ($predicates << 1) | 1; +} + +$code.=<<___; +.rc4Loop: +___ + +# Generate the body: +for ($i = 0; $i < $unroll_count*$phases; ++$i) { + &emit_body (\$code, \$bypass, $iteration++, $predicates); +} + +$code.=<<___; +.rc4Epilogue: +___ + +# Generate the epilogue: +for ($i = 0; $i < $phases; ++$i) { + $predicates <<= 1; + &emit_body (\$code, \$bypass, $iteration++, $predicates); +} + +$code.=<<___; + { + .mmi + lfetch.nt1 [EndPtr] // fetch line with last byte + mov IFinal = I[1] + nop 0x0 + } + +.rc4Remainder: + { + .mmi + sub Remainder = EndPtr, InPtr // Calculate + // # of bytes + // left - 1 + nop 0x0 + nop 0x0 + } ;; + { + .mib + cmp.eq pDone, p0 = -1, Remainder // done already? + mov.i ar.lc = Remainder +(pDone) br.cond.dptk.few .rc4Complete + } + +/* Do the remaining bytes via the compact, modulo-scheduled loop */ + + MODSCHED_RC4_PROLOGUE + MODSCHED_RC4_LOOP(.RC4RestLoop) + +.rc4Complete: + { + .mmi + add KTable = -SZ, KTable + add IFinal = -1, IFinal + mov ar.lc = LCSave + } ;; + { + .mii + SKEY [KTable] = J,-SZ + zxt1 IFinal = IFinal + mov pr = PRSave, 0x1FFFF + } ;; + { + .mib + SKEY [KTable] = IFinal + add RetVal = 1, r0 + br.ret.sptk.few rp + } ;; +___ + +# Last but not least, emit the code for the bypass-code of the unrolled loop: + +$code.=$bypass; + +$code.=<<___; + .endp RC4 +___ + +print $code; diff --git a/libs/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl b/libs/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl new file mode 100644 index 00000000..272fa91e --- /dev/null +++ b/libs/openssl/crypto/rc4/asm/rc4-md5-x86_64.pl @@ -0,0 +1,632 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# June 2011 +# +# This is RC4+MD5 "stitch" implementation. The idea, as spelled in +# http://download.intel.com/design/intarch/papers/323686.pdf, is that +# since both algorithms exhibit instruction-level parallelism, ILP, +# below theoretical maximum, interleaving them would allow to utilize +# processor resources better and achieve better performance. RC4 +# instruction sequence is virtually identical to rc4-x86_64.pl, which +# is heavily based on submission by Maxim Perminov, Maxim Locktyukhin +# and Jim Guilford of Intel. MD5 is fresh implementation aiming to +# minimize register usage, which was used as "main thread" with RC4 +# weaved into it, one RC4 round per one MD5 round. In addition to the +# stiched subroutine the script can generate standalone replacement +# md5_block_asm_data_order and RC4. Below are performance numbers in +# cycles per processed byte, less is better, for these the standalone +# subroutines, sum of them, and stitched one: +# +# RC4 MD5 RC4+MD5 stitch gain +# Opteron 6.5(*) 5.4 11.9 7.0 +70%(*) +# Core2 6.5 5.8 12.3 7.7 +60% +# Westmere 4.3 5.2 9.5 7.0 +36% +# Sandy Bridge 4.2 5.5 9.7 6.8 +43% +# Atom 9.3 6.5 15.8 11.1 +42% +# +# (*) rc4-x86_64.pl delivers 5.3 on Opteron, so real improvement +# is +53%... + +my ($rc4,$md5)=(1,1); # what to generate? +my $D="#" if (!$md5); # if set to "#", MD5 is stitched into RC4(), + # but its result is discarded. Idea here is + # to be able to use 'openssl speed rc4' for + # benchmarking the stitched subroutine... + +my $flavour = shift; +my $output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +my $win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +my ($dat,$in0,$out,$ctx,$inp,$len, $func,$nargs); + +if ($rc4 && !$md5) { + ($dat,$len,$in0,$out) = ("%rdi","%rsi","%rdx","%rcx"); + $func="RC4"; $nargs=4; +} elsif ($md5 && !$rc4) { + ($ctx,$inp,$len) = ("%rdi","%rsi","%rdx"); + $func="md5_block_asm_data_order"; $nargs=3; +} else { + ($dat,$in0,$out,$ctx,$inp,$len) = ("%rdi","%rsi","%rdx","%rcx","%r8","%r9"); + $func="rc4_md5_enc"; $nargs=6; + # void rc4_md5_enc( + # RC4_KEY *key, # + # const void *in0, # RC4 input + # void *out, # RC4 output + # MD5_CTX *ctx, # + # const void *inp, # MD5 input + # size_t len); # number of 64-byte blocks +} + +my @K=( 0xd76aa478,0xe8c7b756,0x242070db,0xc1bdceee, + 0xf57c0faf,0x4787c62a,0xa8304613,0xfd469501, + 0x698098d8,0x8b44f7af,0xffff5bb1,0x895cd7be, + 0x6b901122,0xfd987193,0xa679438e,0x49b40821, + + 0xf61e2562,0xc040b340,0x265e5a51,0xe9b6c7aa, + 0xd62f105d,0x02441453,0xd8a1e681,0xe7d3fbc8, + 0x21e1cde6,0xc33707d6,0xf4d50d87,0x455a14ed, + 0xa9e3e905,0xfcefa3f8,0x676f02d9,0x8d2a4c8a, + + 0xfffa3942,0x8771f681,0x6d9d6122,0xfde5380c, + 0xa4beea44,0x4bdecfa9,0xf6bb4b60,0xbebfbc70, + 0x289b7ec6,0xeaa127fa,0xd4ef3085,0x04881d05, + 0xd9d4d039,0xe6db99e5,0x1fa27cf8,0xc4ac5665, + + 0xf4292244,0x432aff97,0xab9423a7,0xfc93a039, + 0x655b59c3,0x8f0ccc92,0xffeff47d,0x85845dd1, + 0x6fa87e4f,0xfe2ce6e0,0xa3014314,0x4e0811a1, + 0xf7537e82,0xbd3af235,0x2ad7d2bb,0xeb86d391 ); + +my @V=("%r8d","%r9d","%r10d","%r11d"); # MD5 registers +my $tmp="%r12d"; + +my @XX=("%rbp","%rsi"); # RC4 registers +my @TX=("%rax","%rbx"); +my $YY="%rcx"; +my $TY="%rdx"; + +my $MOD=32; # 16, 32 or 64 + +$code.=<<___; +.text +.align 16 + +.globl $func +.type $func,\@function,$nargs +$func: + cmp \$0,$len + je .Labort + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + sub \$40,%rsp +.Lbody: +___ +if ($rc4) { +$code.=<<___; +$D#md5# mov $ctx,%r11 # reassign arguments + mov $len,%r12 + mov $in0,%r13 + mov $out,%r14 +$D#md5# mov $inp,%r15 +___ + $ctx="%r11" if ($md5); # reassign arguments + $len="%r12"; + $in0="%r13"; + $out="%r14"; + $inp="%r15" if ($md5); + $inp=$in0 if (!$md5); +$code.=<<___; + xor $XX[0],$XX[0] + xor $YY,$YY + + lea 8($dat),$dat + mov -8($dat),$XX[0]#b + mov -4($dat),$YY#b + + inc $XX[0]#b + sub $in0,$out + movl ($dat,$XX[0],4),$TX[0]#d +___ +$code.=<<___ if (!$md5); + xor $TX[1],$TX[1] + test \$-128,$len + jz .Loop1 + sub $XX[0],$TX[1] + and \$`$MOD-1`,$TX[1] + jz .Loop${MOD}_is_hot + sub $TX[1],$len +.Loop${MOD}_warmup: + add $TX[0]#b,$YY#b + movl ($dat,$YY,4),$TY#d + movl $TX[0]#d,($dat,$YY,4) + movl $TY#d,($dat,$XX[0],4) + add $TY#b,$TX[0]#b + inc $XX[0]#b + movl ($dat,$TX[0],4),$TY#d + movl ($dat,$XX[0],4),$TX[0]#d + xorb ($in0),$TY#b + movb $TY#b,($out,$in0) + lea 1($in0),$in0 + dec $TX[1] + jnz .Loop${MOD}_warmup + + mov $YY,$TX[1] + xor $YY,$YY + mov $TX[1]#b,$YY#b + +.Loop${MOD}_is_hot: + mov $len,32(%rsp) # save original $len + shr \$6,$len # number of 64-byte blocks +___ + if ($D && !$md5) { # stitch in dummy MD5 + $md5=1; + $ctx="%r11"; + $inp="%r15"; + $code.=<<___; + mov %rsp,$ctx + mov $in0,$inp +___ + } +} +$code.=<<___; +#rc4# add $TX[0]#b,$YY#b +#rc4# lea ($dat,$XX[0],4),$XX[1] + shl \$6,$len + add $inp,$len # pointer to the end of input + mov $len,16(%rsp) + +#md5# mov $ctx,24(%rsp) # save pointer to MD5_CTX +#md5# mov 0*4($ctx),$V[0] # load current hash value from MD5_CTX +#md5# mov 1*4($ctx),$V[1] +#md5# mov 2*4($ctx),$V[2] +#md5# mov 3*4($ctx),$V[3] + jmp .Loop + +.align 16 +.Loop: +#md5# mov $V[0],0*4(%rsp) # put aside current hash value +#md5# mov $V[1],1*4(%rsp) +#md5# mov $V[2],2*4(%rsp) +#md5# mov $V[3],$tmp # forward reference +#md5# mov $V[3],3*4(%rsp) +___ + +sub R0 { + my ($i,$a,$b,$c,$d)=@_; + my @rot0=(7,12,17,22); + my $j=$i%16; + my $k=$i%$MOD; + my $xmm="%xmm".($j&1); + $code.=" movdqu ($in0),%xmm2\n" if ($rc4 && $j==15); + $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1); + $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1); + $code.=<<___; +#rc4# movl ($dat,$YY,4),$TY#d +#md5# xor $c,$tmp +#rc4# movl $TX[0]#d,($dat,$YY,4) +#md5# and $b,$tmp +#md5# add 4*`$j`($inp),$a +#rc4# add $TY#b,$TX[0]#b +#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d +#md5# add \$$K[$i],$a +#md5# xor $d,$tmp +#rc4# movz $TX[0]#b,$TX[0]#d +#rc4# movl $TY#d,4*$k($XX[1]) +#md5# add $tmp,$a +#rc4# add $TX[1]#b,$YY#b +#md5# rol \$$rot0[$j%4],$a +#md5# mov `$j==15?"$b":"$c"`,$tmp # forward reference +#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n +#md5# add $b,$a +___ + $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1); + mov $YY,$XX[1] + xor $YY,$YY # keyword to partial register + mov $XX[1]#b,$YY#b + lea ($dat,$XX[0],4),$XX[1] +___ + $code.=<<___ if ($rc4 && $j==15); + psllq \$8,%xmm1 + pxor %xmm0,%xmm2 + pxor %xmm1,%xmm2 +___ +} +sub R1 { + my ($i,$a,$b,$c,$d)=@_; + my @rot1=(5,9,14,20); + my $j=$i%16; + my $k=$i%$MOD; + my $xmm="%xmm".($j&1); + $code.=" movdqu 16($in0),%xmm3\n" if ($rc4 && $j==15); + $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1); + $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1); + $code.=<<___; +#rc4# movl ($dat,$YY,4),$TY#d +#md5# xor $b,$tmp +#rc4# movl $TX[0]#d,($dat,$YY,4) +#md5# and $d,$tmp +#md5# add 4*`((1+5*$j)%16)`($inp),$a +#rc4# add $TY#b,$TX[0]#b +#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d +#md5# add \$$K[$i],$a +#md5# xor $c,$tmp +#rc4# movz $TX[0]#b,$TX[0]#d +#rc4# movl $TY#d,4*$k($XX[1]) +#md5# add $tmp,$a +#rc4# add $TX[1]#b,$YY#b +#md5# rol \$$rot1[$j%4],$a +#md5# mov `$j==15?"$c":"$b"`,$tmp # forward reference +#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n +#md5# add $b,$a +___ + $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1); + mov $YY,$XX[1] + xor $YY,$YY # keyword to partial register + mov $XX[1]#b,$YY#b + lea ($dat,$XX[0],4),$XX[1] +___ + $code.=<<___ if ($rc4 && $j==15); + psllq \$8,%xmm1 + pxor %xmm0,%xmm3 + pxor %xmm1,%xmm3 +___ +} +sub R2 { + my ($i,$a,$b,$c,$d)=@_; + my @rot2=(4,11,16,23); + my $j=$i%16; + my $k=$i%$MOD; + my $xmm="%xmm".($j&1); + $code.=" movdqu 32($in0),%xmm4\n" if ($rc4 && $j==15); + $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1); + $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1); + $code.=<<___; +#rc4# movl ($dat,$YY,4),$TY#d +#md5# xor $c,$tmp +#rc4# movl $TX[0]#d,($dat,$YY,4) +#md5# xor $b,$tmp +#md5# add 4*`((5+3*$j)%16)`($inp),$a +#rc4# add $TY#b,$TX[0]#b +#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d +#md5# add \$$K[$i],$a +#rc4# movz $TX[0]#b,$TX[0]#d +#md5# add $tmp,$a +#rc4# movl $TY#d,4*$k($XX[1]) +#rc4# add $TX[1]#b,$YY#b +#md5# rol \$$rot2[$j%4],$a +#md5# mov `$j==15?"\\\$-1":"$c"`,$tmp # forward reference +#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n +#md5# add $b,$a +___ + $code.=<<___ if ($rc4 && $j==15 && $k==$MOD-1); + mov $YY,$XX[1] + xor $YY,$YY # keyword to partial register + mov $XX[1]#b,$YY#b + lea ($dat,$XX[0],4),$XX[1] +___ + $code.=<<___ if ($rc4 && $j==15); + psllq \$8,%xmm1 + pxor %xmm0,%xmm4 + pxor %xmm1,%xmm4 +___ +} +sub R3 { + my ($i,$a,$b,$c,$d)=@_; + my @rot3=(6,10,15,21); + my $j=$i%16; + my $k=$i%$MOD; + my $xmm="%xmm".($j&1); + $code.=" movdqu 48($in0),%xmm5\n" if ($rc4 && $j==15); + $code.=" add \$$MOD,$XX[0]#b\n" if ($rc4 && $j==15 && $k==$MOD-1); + $code.=" pxor $xmm,$xmm\n" if ($rc4 && $j<=1); + $code.=<<___; +#rc4# movl ($dat,$YY,4),$TY#d +#md5# xor $d,$tmp +#rc4# movl $TX[0]#d,($dat,$YY,4) +#md5# or $b,$tmp +#md5# add 4*`((7*$j)%16)`($inp),$a +#rc4# add $TY#b,$TX[0]#b +#rc4# movl `4*(($k+1)%$MOD)`(`$k==$MOD-1?"$dat,$XX[0],4":"$XX[1]"`),$TX[1]#d +#md5# add \$$K[$i],$a +#rc4# movz $TX[0]#b,$TX[0]#d +#md5# xor $c,$tmp +#rc4# movl $TY#d,4*$k($XX[1]) +#md5# add $tmp,$a +#rc4# add $TX[1]#b,$YY#b +#md5# rol \$$rot3[$j%4],$a +#md5# mov \$-1,$tmp # forward reference +#rc4# pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n +#md5# add $b,$a +___ + $code.=<<___ if ($rc4 && $j==15); + mov $XX[0],$XX[1] + xor $XX[0],$XX[0] # keyword to partial register + mov $XX[1]#b,$XX[0]#b + mov $YY,$XX[1] + xor $YY,$YY # keyword to partial register + mov $XX[1]#b,$YY#b + lea ($dat,$XX[0],4),$XX[1] + psllq \$8,%xmm1 + pxor %xmm0,%xmm5 + pxor %xmm1,%xmm5 +___ +} + +my $i=0; +for(;$i<16;$i++) { R0($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); } +for(;$i<32;$i++) { R1($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); } +for(;$i<48;$i++) { R2($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); } +for(;$i<64;$i++) { R3($i,@V); unshift(@V,pop(@V)); push(@TX,shift(@TX)); } + +$code.=<<___; +#md5# add 0*4(%rsp),$V[0] # accumulate hash value +#md5# add 1*4(%rsp),$V[1] +#md5# add 2*4(%rsp),$V[2] +#md5# add 3*4(%rsp),$V[3] + +#rc4# movdqu %xmm2,($out,$in0) # write RC4 output +#rc4# movdqu %xmm3,16($out,$in0) +#rc4# movdqu %xmm4,32($out,$in0) +#rc4# movdqu %xmm5,48($out,$in0) +#md5# lea 64($inp),$inp +#rc4# lea 64($in0),$in0 + cmp 16(%rsp),$inp # are we done? + jb .Loop + +#md5# mov 24(%rsp),$len # restore pointer to MD5_CTX +#rc4# sub $TX[0]#b,$YY#b # correct $YY +#md5# mov $V[0],0*4($len) # write MD5_CTX +#md5# mov $V[1],1*4($len) +#md5# mov $V[2],2*4($len) +#md5# mov $V[3],3*4($len) +___ +$code.=<<___ if ($rc4 && (!$md5 || $D)); + mov 32(%rsp),$len # restore original $len + and \$63,$len # remaining bytes + jnz .Loop1 + jmp .Ldone + +.align 16 +.Loop1: + add $TX[0]#b,$YY#b + movl ($dat,$YY,4),$TY#d + movl $TX[0]#d,($dat,$YY,4) + movl $TY#d,($dat,$XX[0],4) + add $TY#b,$TX[0]#b + inc $XX[0]#b + movl ($dat,$TX[0],4),$TY#d + movl ($dat,$XX[0],4),$TX[0]#d + xorb ($in0),$TY#b + movb $TY#b,($out,$in0) + lea 1($in0),$in0 + dec $len + jnz .Loop1 + +.Ldone: +___ +$code.=<<___; +#rc4# sub \$1,$XX[0]#b +#rc4# movl $XX[0]#d,-8($dat) +#rc4# movl $YY#d,-4($dat) + + mov 40(%rsp),%r15 + mov 48(%rsp),%r14 + mov 56(%rsp),%r13 + mov 64(%rsp),%r12 + mov 72(%rsp),%rbp + mov 80(%rsp),%rbx + lea 88(%rsp),%rsp +.Lepilogue: +.Labort: + ret +.size $func,.-$func +___ + +if ($rc4 && $D) { # sole purpose of this section is to provide + # option to use the generated module as drop-in + # replacement for rc4-x86_64.pl for debugging + # and testing purposes... +my ($idx,$ido)=("%r8","%r9"); +my ($dat,$len,$inp)=("%rdi","%rsi","%rdx"); + +$code.=<<___; +.globl RC4_set_key +.type RC4_set_key,\@function,3 +.align 16 +RC4_set_key: + lea 8($dat),$dat + lea ($inp,$len),$inp + neg $len + mov $len,%rcx + xor %eax,%eax + xor $ido,$ido + xor %r10,%r10 + xor %r11,%r11 + jmp .Lw1stloop + +.align 16 +.Lw1stloop: + mov %eax,($dat,%rax,4) + add \$1,%al + jnc .Lw1stloop + + xor $ido,$ido + xor $idx,$idx +.align 16 +.Lw2ndloop: + mov ($dat,$ido,4),%r10d + add ($inp,$len,1),$idx#b + add %r10b,$idx#b + add \$1,$len + mov ($dat,$idx,4),%r11d + cmovz %rcx,$len + mov %r10d,($dat,$idx,4) + mov %r11d,($dat,$ido,4) + add \$1,$ido#b + jnc .Lw2ndloop + + xor %eax,%eax + mov %eax,-8($dat) + mov %eax,-4($dat) + ret +.size RC4_set_key,.-RC4_set_key + +.globl RC4_options +.type RC4_options,\@abi-omnipotent +.align 16 +RC4_options: + lea .Lopts(%rip),%rax + ret +.align 64 +.Lopts: +.asciz "rc4(64x,int)" +.align 64 +.size RC4_options,.-RC4_options +___ +} +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +my $rec="%rcx"; +my $frame="%rdx"; +my $context="%r8"; +my $disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type se_handler,\@abi-omnipotent +.align 16 +se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + lea .Lbody(%rip),%r10 + cmp %r10,%rbx # context->Rip<.Lbody + jb .Lin_prologue + + mov 152($context),%rax # pull context->Rsp + + lea .Lepilogue(%rip),%r10 + cmp %r10,%rbx # context->Rip>=.Lepilogue + jae .Lin_prologue + + mov 40(%rax),%r15 + mov 48(%rax),%r14 + mov 56(%rax),%r13 + mov 64(%rax),%r12 + mov 72(%rax),%rbp + mov 80(%rax),%rbx + lea 88(%rax),%rax + + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R12 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + +.Lin_prologue: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$154,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size se_handler,.-se_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_$func + .rva .LSEH_end_$func + .rva .LSEH_info_$func + +.section .xdata +.align 8 +.LSEH_info_$func: + .byte 9,0,0,0 + .rva se_handler +___ +} + +sub reg_part { +my ($reg,$conv)=@_; + if ($reg =~ /%r[0-9]+/) { $reg .= $conv; } + elsif ($conv eq "b") { $reg =~ s/%[er]([^x]+)x?/%$1l/; } + elsif ($conv eq "w") { $reg =~ s/%[er](.+)/%$1/; } + elsif ($conv eq "d") { $reg =~ s/%[er](.+)/%e$1/; } + return $reg; +} + +$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem; +$code =~ s/\`([^\`]*)\`/eval $1/gem; +$code =~ s/pinsrw\s+\$0,/movd /gm; + +$code =~ s/#md5#//gm if ($md5); +$code =~ s/#rc4#//gm if ($rc4); + +print $code; + +close STDOUT; diff --git a/libs/openssl/crypto/rc4/asm/rc4-parisc.pl b/libs/openssl/crypto/rc4/asm/rc4-parisc.pl new file mode 100644 index 00000000..ad7e6565 --- /dev/null +++ b/libs/openssl/crypto/rc4/asm/rc4-parisc.pl @@ -0,0 +1,314 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# RC4 for PA-RISC. + +# June 2009. +# +# Performance is 33% better than gcc 3.2 generated code on PA-7100LC. +# For reference, [4x] unrolled loop is >40% faster than folded one. +# It's possible to unroll loop 8 times on PA-RISC 2.0, but improvement +# is believed to be not sufficient to justify the effort... +# +# Special thanks to polarhome.com for providing HP-UX account. + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; + +$flavour = shift; +$output = shift; +open STDOUT,">$output"; + +if ($flavour =~ /64/) { + $LEVEL ="2.0W"; + $SIZE_T =8; + $FRAME_MARKER =80; + $SAVED_RP =16; + $PUSH ="std"; + $PUSHMA ="std,ma"; + $POP ="ldd"; + $POPMB ="ldd,mb"; +} else { + $LEVEL ="1.0"; + $SIZE_T =4; + $FRAME_MARKER =48; + $SAVED_RP =20; + $PUSH ="stw"; + $PUSHMA ="stwm"; + $POP ="ldw"; + $POPMB ="ldwm"; +} + +$FRAME=4*$SIZE_T+$FRAME_MARKER; # 4 saved regs + frame marker + # [+ argument transfer] +$SZ=1; # defaults to RC4_CHAR +if (open CONF,"<${dir}../../opensslconf.h") { + while() { + if (m/#\s*define\s+RC4_INT\s+(.*)/) { + $SZ = ($1=~/char$/) ? 1 : 4; + last; + } + } + close CONF; +} + +if ($SZ==1) { # RC4_CHAR + $LD="ldb"; + $LDX="ldbx"; + $MKX="addl"; + $ST="stb"; +} else { # RC4_INT (~5% faster than RC4_CHAR on PA-7100LC) + $LD="ldw"; + $LDX="ldwx,s"; + $MKX="sh2addl"; + $ST="stw"; +} + +$key="%r26"; +$len="%r25"; +$inp="%r24"; +$out="%r23"; + +@XX=("%r19","%r20"); +@TX=("%r21","%r22"); +$YY="%r28"; +$TY="%r29"; + +$acc="%r1"; +$ix="%r2"; +$iy="%r3"; +$dat0="%r4"; +$dat1="%r5"; +$rem="%r6"; +$mask="%r31"; + +sub unrolledloopbody { +for ($i=0;$i<4;$i++) { +$code.=<<___; + ldo 1($XX[0]),$XX[1] + `sprintf("$LDX %$TY(%$key),%$dat1") if ($i>0)` + and $mask,$XX[1],$XX[1] + $LDX $YY($key),$TY + $MKX $YY,$key,$ix + $LDX $XX[1]($key),$TX[1] + $MKX $XX[0],$key,$iy + $ST $TX[0],0($ix) + comclr,<> $XX[1],$YY,%r0 ; conditional + copy $TX[0],$TX[1] ; move + `sprintf("%sdep %$dat1,%d,8,%$acc",$i==1?"z":"",8*($i-1)+7) if ($i>0)` + $ST $TY,0($iy) + addl $TX[0],$TY,$TY + addl $TX[1],$YY,$YY + and $mask,$TY,$TY + and $mask,$YY,$YY +___ +push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers +} } + +sub foldedloop { +my ($label,$count)=@_; +$code.=<<___; +$label + $MKX $YY,$key,$iy + $LDX $YY($key),$TY + $MKX $XX[0],$key,$ix + $ST $TX[0],0($iy) + ldo 1($XX[0]),$XX[0] + $ST $TY,0($ix) + addl $TX[0],$TY,$TY + ldbx $inp($out),$dat1 + and $mask,$TY,$TY + and $mask,$XX[0],$XX[0] + $LDX $TY($key),$acc + $LDX $XX[0]($key),$TX[0] + ldo 1($out),$out + xor $dat1,$acc,$acc + addl $TX[0],$YY,$YY + stb $acc,-1($out) + addib,<> -1,$count,$label ; $count is always small + and $mask,$YY,$YY +___ +} + +$code=<<___; + .LEVEL $LEVEL + .SPACE \$TEXT\$ + .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY + + .EXPORT RC4,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR +RC4 + .PROC + .CALLINFO FRAME=`$FRAME-4*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=6 + .ENTRY + $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue + $PUSHMA %r3,$FRAME(%sp) + $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp) + $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp) + $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp) + + cmpib,*= 0,$len,L\$abort + sub $inp,$out,$inp ; distance between $inp and $out + + $LD `0*$SZ`($key),$XX[0] + $LD `1*$SZ`($key),$YY + ldo `2*$SZ`($key),$key + + ldi 0xff,$mask + ldi 3,$dat0 + + ldo 1($XX[0]),$XX[0] ; warm up loop + and $mask,$XX[0],$XX[0] + $LDX $XX[0]($key),$TX[0] + addl $TX[0],$YY,$YY + cmpib,*>>= 6,$len,L\$oop1 ; is $len large enough to bother? + and $mask,$YY,$YY + + and,<> $out,$dat0,$rem ; is $out aligned? + b L\$alignedout + subi 4,$rem,$rem + sub $len,$rem,$len +___ +&foldedloop("L\$alignout",$rem); # process till $out is aligned + +$code.=<<___; +L\$alignedout ; $len is at least 4 here + and,<> $inp,$dat0,$acc ; is $inp aligned? + b L\$oop4 + sub $inp,$acc,$rem ; align $inp + + sh3addl $acc,%r0,$acc + subi 32,$acc,$acc + mtctl $acc,%cr11 ; load %sar with vshd align factor + ldwx $rem($out),$dat0 + ldo 4($rem),$rem +L\$oop4misalignedinp +___ +&unrolledloopbody(); +$code.=<<___; + $LDX $TY($key),$ix + ldwx $rem($out),$dat1 + ldo -4($len),$len + or $ix,$acc,$acc ; last piece, no need to dep + vshd $dat0,$dat1,$iy ; align data + copy $dat1,$dat0 + xor $iy,$acc,$acc + stw $acc,0($out) + cmpib,*<< 3,$len,L\$oop4misalignedinp + ldo 4($out),$out + cmpib,*= 0,$len,L\$done + nop + b L\$oop1 + nop + + .ALIGN 8 +L\$oop4 +___ +&unrolledloopbody(); +$code.=<<___; + $LDX $TY($key),$ix + ldwx $inp($out),$dat0 + ldo -4($len),$len + or $ix,$acc,$acc ; last piece, no need to dep + xor $dat0,$acc,$acc + stw $acc,0($out) + cmpib,*<< 3,$len,L\$oop4 + ldo 4($out),$out + cmpib,*= 0,$len,L\$done + nop +___ +&foldedloop("L\$oop1",$len); +$code.=<<___; +L\$done + $POP `-$FRAME-$SAVED_RP`(%sp),%r2 + ldo -1($XX[0]),$XX[0] ; chill out loop + sub $YY,$TX[0],$YY + and $mask,$XX[0],$XX[0] + and $mask,$YY,$YY + $ST $XX[0],`-2*$SZ`($key) + $ST $YY,`-1*$SZ`($key) + $POP `-$FRAME+1*$SIZE_T`(%sp),%r4 + $POP `-$FRAME+2*$SIZE_T`(%sp),%r5 + $POP `-$FRAME+3*$SIZE_T`(%sp),%r6 +L\$abort + bv (%r2) + .EXIT + $POPMB -$FRAME(%sp),%r3 + .PROCEND +___ + +$code.=<<___; + + .EXPORT private_RC4_set_key,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR + .ALIGN 8 +private_RC4_set_key + .PROC + .CALLINFO NO_CALLS + .ENTRY + $ST %r0,`0*$SZ`($key) + $ST %r0,`1*$SZ`($key) + ldo `2*$SZ`($key),$key + copy %r0,@XX[0] +L\$1st + $ST @XX[0],0($key) + ldo 1(@XX[0]),@XX[0] + bb,>= @XX[0],`31-8`,L\$1st ; @XX[0]<256 + ldo $SZ($key),$key + + ldo `-256*$SZ`($key),$key ; rewind $key + addl $len,$inp,$inp ; $inp to point at the end + sub %r0,$len,%r23 ; inverse index + copy %r0,@XX[0] + copy %r0,@XX[1] + ldi 0xff,$mask + +L\$2nd + $LDX @XX[0]($key),@TX[0] + ldbx %r23($inp),@TX[1] + addi,nuv 1,%r23,%r23 ; increment and conditional + sub %r0,$len,%r23 ; inverse index + addl @TX[0],@XX[1],@XX[1] + addl @TX[1],@XX[1],@XX[1] + and $mask,@XX[1],@XX[1] + $MKX @XX[0],$key,$TY + $LDX @XX[1]($key),@TX[1] + $MKX @XX[1],$key,$YY + ldo 1(@XX[0]),@XX[0] + $ST @TX[0],0($YY) + bb,>= @XX[0],`31-8`,L\$2nd ; @XX[0]<256 + $ST @TX[1],0($TY) + + bv,n (%r2) + .EXIT + nop + .PROCEND + + .EXPORT RC4_options,ENTRY + .ALIGN 8 +RC4_options + .PROC + .CALLINFO NO_CALLS + .ENTRY + blr %r0,%r28 + ldi 3,%r1 +L\$pic + andcm %r28,%r1,%r28 + bv (%r2) + .EXIT + ldo L\$opts-L\$pic(%r28),%r28 + .PROCEND + .ALIGN 8 +L\$opts + .STRINGZ "rc4(4x,`$SZ==1?"char":"int"`)" + .STRINGZ "RC4 for PA-RISC, CRYPTOGAMS by " +___ +$code =~ s/\`([^\`]*)\`/eval $1/gem; +$code =~ s/cmpib,\*/comib,/gm if ($SIZE_T==4); +$code =~ s/\bbv\b/bve/gm if ($SIZE_T==8); + +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/rc4/asm/rc4-s390x.pl b/libs/openssl/crypto/rc4/asm/rc4-s390x.pl new file mode 100644 index 00000000..7528ece1 --- /dev/null +++ b/libs/openssl/crypto/rc4/asm/rc4-s390x.pl @@ -0,0 +1,234 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# February 2009 +# +# Performance is 2x of gcc 3.4.6 on z10. Coding "secret" is to +# "cluster" Address Generation Interlocks, so that one pipeline stall +# resolves several dependencies. + +# November 2010. +# +# Adapt for -m31 build. If kernel supports what's called "highgprs" +# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit +# instructions and achieve "64-bit" performance even in 31-bit legacy +# application context. The feature is not specific to any particular +# processor, as long as it's "z-CPU". Latter implies that the code +# remains z/Architecture specific. On z990 it was measured to perform +# 50% better than code generated by gcc 4.3. + +$flavour = shift; + +if ($flavour =~ /3[12]/) { + $SIZE_T=4; + $g=""; +} else { + $SIZE_T=8; + $g="g"; +} + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +$rp="%r14"; +$sp="%r15"; +$code=<<___; +.text + +___ + +# void RC4(RC4_KEY *key,size_t len,const void *inp,void *out) +{ +$acc="%r0"; +$cnt="%r1"; +$key="%r2"; +$len="%r3"; +$inp="%r4"; +$out="%r5"; + +@XX=("%r6","%r7"); +@TX=("%r8","%r9"); +$YY="%r10"; +$TY="%r11"; + +$code.=<<___; +.globl RC4 +.type RC4,\@function +.align 64 +RC4: + stm${g} %r6,%r11,6*$SIZE_T($sp) +___ +$code.=<<___ if ($flavour =~ /3[12]/); + llgfr $len,$len +___ +$code.=<<___; + llgc $XX[0],0($key) + llgc $YY,1($key) + la $XX[0],1($XX[0]) + nill $XX[0],0xff + srlg $cnt,$len,3 + ltgr $cnt,$cnt + llgc $TX[0],2($XX[0],$key) + jz .Lshort + j .Loop8 + +.align 64 +.Loop8: +___ +for ($i=0;$i<8;$i++) { +$code.=<<___; + la $YY,0($YY,$TX[0]) # $i + nill $YY,255 + la $XX[1],1($XX[0]) + nill $XX[1],255 +___ +$code.=<<___ if ($i==1); + llgc $acc,2($TY,$key) +___ +$code.=<<___ if ($i>1); + sllg $acc,$acc,8 + ic $acc,2($TY,$key) +___ +$code.=<<___; + llgc $TY,2($YY,$key) + stc $TX[0],2($YY,$key) + llgc $TX[1],2($XX[1],$key) + stc $TY,2($XX[0],$key) + cr $XX[1],$YY + jne .Lcmov$i + la $TX[1],0($TX[0]) +.Lcmov$i: + la $TY,0($TY,$TX[0]) + nill $TY,255 +___ +push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers +} + +$code.=<<___; + lg $TX[1],0($inp) + sllg $acc,$acc,8 + la $inp,8($inp) + ic $acc,2($TY,$key) + xgr $acc,$TX[1] + stg $acc,0($out) + la $out,8($out) + brctg $cnt,.Loop8 + +.Lshort: + lghi $acc,7 + ngr $len,$acc + jz .Lexit + j .Loop1 + +.align 16 +.Loop1: + la $YY,0($YY,$TX[0]) + nill $YY,255 + llgc $TY,2($YY,$key) + stc $TX[0],2($YY,$key) + stc $TY,2($XX[0],$key) + ar $TY,$TX[0] + ahi $XX[0],1 + nill $TY,255 + nill $XX[0],255 + llgc $acc,0($inp) + la $inp,1($inp) + llgc $TY,2($TY,$key) + llgc $TX[0],2($XX[0],$key) + xr $acc,$TY + stc $acc,0($out) + la $out,1($out) + brct $len,.Loop1 + +.Lexit: + ahi $XX[0],-1 + stc $XX[0],0($key) + stc $YY,1($key) + lm${g} %r6,%r11,6*$SIZE_T($sp) + br $rp +.size RC4,.-RC4 +.string "RC4 for s390x, CRYPTOGAMS by " + +___ +} + +# void RC4_set_key(RC4_KEY *key,unsigned int len,const void *inp) +{ +$cnt="%r0"; +$idx="%r1"; +$key="%r2"; +$len="%r3"; +$inp="%r4"; +$acc="%r5"; +$dat="%r6"; +$ikey="%r7"; +$iinp="%r8"; + +$code.=<<___; +.globl private_RC4_set_key +.type private_RC4_set_key,\@function +.align 64 +private_RC4_set_key: + stm${g} %r6,%r8,6*$SIZE_T($sp) + lhi $cnt,256 + la $idx,0(%r0) + sth $idx,0($key) +.align 4 +.L1stloop: + stc $idx,2($idx,$key) + la $idx,1($idx) + brct $cnt,.L1stloop + + lghi $ikey,-256 + lr $cnt,$len + la $iinp,0(%r0) + la $idx,0(%r0) +.align 16 +.L2ndloop: + llgc $acc,2+256($ikey,$key) + llgc $dat,0($iinp,$inp) + la $idx,0($idx,$acc) + la $ikey,1($ikey) + la $idx,0($idx,$dat) + nill $idx,255 + la $iinp,1($iinp) + tml $ikey,255 + llgc $dat,2($idx,$key) + stc $dat,2+256-1($ikey,$key) + stc $acc,2($idx,$key) + jz .Ldone + brct $cnt,.L2ndloop + lr $cnt,$len + la $iinp,0(%r0) + j .L2ndloop +.Ldone: + lm${g} %r6,%r8,6*$SIZE_T($sp) + br $rp +.size private_RC4_set_key,.-private_RC4_set_key + +___ +} + +# const char *RC4_options() +$code.=<<___; +.globl RC4_options +.type RC4_options,\@function +.align 16 +RC4_options: + larl %r2,.Loptions + br %r14 +.size RC4_options,.-RC4_options +.section .rodata +.Loptions: +.align 8 +.string "rc4(8x,char)" +___ + +print $code; +close STDOUT; # force flush diff --git a/libs/openssl/crypto/rc4/asm/rc4-x86_64.pl b/libs/openssl/crypto/rc4/asm/rc4-x86_64.pl new file mode 100755 index 00000000..20722d3e --- /dev/null +++ b/libs/openssl/crypto/rc4/asm/rc4-x86_64.pl @@ -0,0 +1,677 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# July 2004 +# +# 2.22x RC4 tune-up:-) It should be noted though that my hand [as in +# "hand-coded assembler"] doesn't stand for the whole improvement +# coefficient. It turned out that eliminating RC4_CHAR from config +# line results in ~40% improvement (yes, even for C implementation). +# Presumably it has everything to do with AMD cache architecture and +# RAW or whatever penalties. Once again! The module *requires* config +# line *without* RC4_CHAR! As for coding "secret," I bet on partial +# register arithmetics. For example instead of 'inc %r8; and $255,%r8' +# I simply 'inc %r8b'. Even though optimization manual discourages +# to operate on partial registers, it turned out to be the best bet. +# At least for AMD... How IA32E would perform remains to be seen... + +# November 2004 +# +# As was shown by Marc Bevand reordering of couple of load operations +# results in even higher performance gain of 3.3x:-) At least on +# Opteron... For reference, 1x in this case is RC4_CHAR C-code +# compiled with gcc 3.3.2, which performs at ~54MBps per 1GHz clock. +# Latter means that if you want to *estimate* what to expect from +# *your* Opteron, then multiply 54 by 3.3 and clock frequency in GHz. + +# November 2004 +# +# Intel P4 EM64T core was found to run the AMD64 code really slow... +# The only way to achieve comparable performance on P4 was to keep +# RC4_CHAR. Kind of ironic, huh? As it's apparently impossible to +# compose blended code, which would perform even within 30% marginal +# on either AMD and Intel platforms, I implement both cases. See +# rc4_skey.c for further details... + +# April 2005 +# +# P4 EM64T core appears to be "allergic" to 64-bit inc/dec. Replacing +# those with add/sub results in 50% performance improvement of folded +# loop... + +# May 2005 +# +# As was shown by Zou Nanhai loop unrolling can improve Intel EM64T +# performance by >30% [unlike P4 32-bit case that is]. But this is +# provided that loads are reordered even more aggressively! Both code +# pathes, AMD64 and EM64T, reorder loads in essentially same manner +# as my IA-64 implementation. On Opteron this resulted in modest 5% +# improvement [I had to test it], while final Intel P4 performance +# achieves respectful 432MBps on 2.8GHz processor now. For reference. +# If executed on Xeon, current RC4_CHAR code-path is 2.7x faster than +# RC4_INT code-path. While if executed on Opteron, it's only 25% +# slower than the RC4_INT one [meaning that if CPU µ-arch detection +# is not implemented, then this final RC4_CHAR code-path should be +# preferred, as it provides better *all-round* performance]. + +# March 2007 +# +# Intel Core2 was observed to perform poorly on both code paths:-( It +# apparently suffers from some kind of partial register stall, which +# occurs in 64-bit mode only [as virtually identical 32-bit loop was +# observed to outperform 64-bit one by almost 50%]. Adding two movzb to +# cloop1 boosts its performance by 80%! This loop appears to be optimal +# fit for Core2 and therefore the code was modified to skip cloop8 on +# this CPU. + +# May 2010 +# +# Intel Westmere was observed to perform suboptimally. Adding yet +# another movzb to cloop1 improved performance by almost 50%! Core2 +# performance is improved too, but nominally... + +# May 2011 +# +# The only code path that was not modified is P4-specific one. Non-P4 +# Intel code path optimization is heavily based on submission by Maxim +# Perminov, Maxim Locktyukhin and Jim Guilford of Intel. I've used +# some of the ideas even in attempt to optmize the original RC4_INT +# code path... Current performance in cycles per processed byte (less +# is better) and improvement coefficients relative to previous +# version of this module are: +# +# Opteron 5.3/+0%(*) +# P4 6.5 +# Core2 6.2/+15%(**) +# Westmere 4.2/+60% +# Sandy Bridge 4.2/+120% +# Atom 9.3/+80% +# +# (*) But corresponding loop has less instructions, which should have +# positive effect on upcoming Bulldozer, which has one less ALU. +# For reference, Intel code runs at 6.8 cpb rate on Opteron. +# (**) Note that Core2 result is ~15% lower than corresponding result +# for 32-bit code, meaning that it's possible to improve it, +# but more than likely at the cost of the others (see rc4-586.pl +# to get the idea)... + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +$dat="%rdi"; # arg1 +$len="%rsi"; # arg2 +$inp="%rdx"; # arg3 +$out="%rcx"; # arg4 + +{ +$code=<<___; +.text +.extern OPENSSL_ia32cap_P + +.globl RC4 +.type RC4,\@function,4 +.align 16 +RC4: or $len,$len + jne .Lentry + ret +.Lentry: + push %rbx + push %r12 + push %r13 +.Lprologue: + mov $len,%r11 + mov $inp,%r12 + mov $out,%r13 +___ +my $len="%r11"; # reassign input arguments +my $inp="%r12"; +my $out="%r13"; + +my @XX=("%r10","%rsi"); +my @TX=("%rax","%rbx"); +my $YY="%rcx"; +my $TY="%rdx"; + +$code.=<<___; + xor $XX[0],$XX[0] + xor $YY,$YY + + lea 8($dat),$dat + mov -8($dat),$XX[0]#b + mov -4($dat),$YY#b + cmpl \$-1,256($dat) + je .LRC4_CHAR + mov OPENSSL_ia32cap_P(%rip),%r8d + xor $TX[1],$TX[1] + inc $XX[0]#b + sub $XX[0],$TX[1] + sub $inp,$out + movl ($dat,$XX[0],4),$TX[0]#d + test \$-16,$len + jz .Lloop1 + bt \$30,%r8d # Intel CPU? + jc .Lintel + and \$7,$TX[1] + lea 1($XX[0]),$XX[1] + jz .Loop8 + sub $TX[1],$len +.Loop8_warmup: + add $TX[0]#b,$YY#b + movl ($dat,$YY,4),$TY#d + movl $TX[0]#d,($dat,$YY,4) + movl $TY#d,($dat,$XX[0],4) + add $TY#b,$TX[0]#b + inc $XX[0]#b + movl ($dat,$TX[0],4),$TY#d + movl ($dat,$XX[0],4),$TX[0]#d + xorb ($inp),$TY#b + movb $TY#b,($out,$inp) + lea 1($inp),$inp + dec $TX[1] + jnz .Loop8_warmup + + lea 1($XX[0]),$XX[1] + jmp .Loop8 +.align 16 +.Loop8: +___ +for ($i=0;$i<8;$i++) { +$code.=<<___ if ($i==7); + add \$8,$XX[1]#b +___ +$code.=<<___; + add $TX[0]#b,$YY#b + movl ($dat,$YY,4),$TY#d + movl $TX[0]#d,($dat,$YY,4) + movl `4*($i==7?-1:$i)`($dat,$XX[1],4),$TX[1]#d + ror \$8,%r8 # ror is redundant when $i=0 + movl $TY#d,4*$i($dat,$XX[0],4) + add $TX[0]#b,$TY#b + movb ($dat,$TY,4),%r8b +___ +push(@TX,shift(@TX)); #push(@XX,shift(@XX)); # "rotate" registers +} +$code.=<<___; + add \$8,$XX[0]#b + ror \$8,%r8 + sub \$8,$len + + xor ($inp),%r8 + mov %r8,($out,$inp) + lea 8($inp),$inp + + test \$-8,$len + jnz .Loop8 + cmp \$0,$len + jne .Lloop1 + jmp .Lexit + +.align 16 +.Lintel: + test \$-32,$len + jz .Lloop1 + and \$15,$TX[1] + jz .Loop16_is_hot + sub $TX[1],$len +.Loop16_warmup: + add $TX[0]#b,$YY#b + movl ($dat,$YY,4),$TY#d + movl $TX[0]#d,($dat,$YY,4) + movl $TY#d,($dat,$XX[0],4) + add $TY#b,$TX[0]#b + inc $XX[0]#b + movl ($dat,$TX[0],4),$TY#d + movl ($dat,$XX[0],4),$TX[0]#d + xorb ($inp),$TY#b + movb $TY#b,($out,$inp) + lea 1($inp),$inp + dec $TX[1] + jnz .Loop16_warmup + + mov $YY,$TX[1] + xor $YY,$YY + mov $TX[1]#b,$YY#b + +.Loop16_is_hot: + lea ($dat,$XX[0],4),$XX[1] +___ +sub RC4_loop { + my $i=shift; + my $j=$i<0?0:$i; + my $xmm="%xmm".($j&1); + + $code.=" add \$16,$XX[0]#b\n" if ($i==15); + $code.=" movdqu ($inp),%xmm2\n" if ($i==15); + $code.=" add $TX[0]#b,$YY#b\n" if ($i<=0); + $code.=" movl ($dat,$YY,4),$TY#d\n"; + $code.=" pxor %xmm0,%xmm2\n" if ($i==0); + $code.=" psllq \$8,%xmm1\n" if ($i==0); + $code.=" pxor $xmm,$xmm\n" if ($i<=1); + $code.=" movl $TX[0]#d,($dat,$YY,4)\n"; + $code.=" add $TY#b,$TX[0]#b\n"; + $code.=" movl `4*($j+1)`($XX[1]),$TX[1]#d\n" if ($i<15); + $code.=" movz $TX[0]#b,$TX[0]#d\n"; + $code.=" movl $TY#d,4*$j($XX[1])\n"; + $code.=" pxor %xmm1,%xmm2\n" if ($i==0); + $code.=" lea ($dat,$XX[0],4),$XX[1]\n" if ($i==15); + $code.=" add $TX[1]#b,$YY#b\n" if ($i<15); + $code.=" pinsrw \$`($j>>1)&7`,($dat,$TX[0],4),$xmm\n"; + $code.=" movdqu %xmm2,($out,$inp)\n" if ($i==0); + $code.=" lea 16($inp),$inp\n" if ($i==0); + $code.=" movl ($XX[1]),$TX[1]#d\n" if ($i==15); +} + RC4_loop(-1); +$code.=<<___; + jmp .Loop16_enter +.align 16 +.Loop16: +___ + +for ($i=0;$i<16;$i++) { + $code.=".Loop16_enter:\n" if ($i==1); + RC4_loop($i); + push(@TX,shift(@TX)); # "rotate" registers +} +$code.=<<___; + mov $YY,$TX[1] + xor $YY,$YY # keyword to partial register + sub \$16,$len + mov $TX[1]#b,$YY#b + test \$-16,$len + jnz .Loop16 + + psllq \$8,%xmm1 + pxor %xmm0,%xmm2 + pxor %xmm1,%xmm2 + movdqu %xmm2,($out,$inp) + lea 16($inp),$inp + + cmp \$0,$len + jne .Lloop1 + jmp .Lexit + +.align 16 +.Lloop1: + add $TX[0]#b,$YY#b + movl ($dat,$YY,4),$TY#d + movl $TX[0]#d,($dat,$YY,4) + movl $TY#d,($dat,$XX[0],4) + add $TY#b,$TX[0]#b + inc $XX[0]#b + movl ($dat,$TX[0],4),$TY#d + movl ($dat,$XX[0],4),$TX[0]#d + xorb ($inp),$TY#b + movb $TY#b,($out,$inp) + lea 1($inp),$inp + dec $len + jnz .Lloop1 + jmp .Lexit + +.align 16 +.LRC4_CHAR: + add \$1,$XX[0]#b + movzb ($dat,$XX[0]),$TX[0]#d + test \$-8,$len + jz .Lcloop1 + jmp .Lcloop8 +.align 16 +.Lcloop8: + mov ($inp),%r8d + mov 4($inp),%r9d +___ +# unroll 2x4-wise, because 64-bit rotates kill Intel P4... +for ($i=0;$i<4;$i++) { +$code.=<<___; + add $TX[0]#b,$YY#b + lea 1($XX[0]),$XX[1] + movzb ($dat,$YY),$TY#d + movzb $XX[1]#b,$XX[1]#d + movzb ($dat,$XX[1]),$TX[1]#d + movb $TX[0]#b,($dat,$YY) + cmp $XX[1],$YY + movb $TY#b,($dat,$XX[0]) + jne .Lcmov$i # Intel cmov is sloooow... + mov $TX[0],$TX[1] +.Lcmov$i: + add $TX[0]#b,$TY#b + xor ($dat,$TY),%r8b + ror \$8,%r8d +___ +push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers +} +for ($i=4;$i<8;$i++) { +$code.=<<___; + add $TX[0]#b,$YY#b + lea 1($XX[0]),$XX[1] + movzb ($dat,$YY),$TY#d + movzb $XX[1]#b,$XX[1]#d + movzb ($dat,$XX[1]),$TX[1]#d + movb $TX[0]#b,($dat,$YY) + cmp $XX[1],$YY + movb $TY#b,($dat,$XX[0]) + jne .Lcmov$i # Intel cmov is sloooow... + mov $TX[0],$TX[1] +.Lcmov$i: + add $TX[0]#b,$TY#b + xor ($dat,$TY),%r9b + ror \$8,%r9d +___ +push(@TX,shift(@TX)); push(@XX,shift(@XX)); # "rotate" registers +} +$code.=<<___; + lea -8($len),$len + mov %r8d,($out) + lea 8($inp),$inp + mov %r9d,4($out) + lea 8($out),$out + + test \$-8,$len + jnz .Lcloop8 + cmp \$0,$len + jne .Lcloop1 + jmp .Lexit +___ +$code.=<<___; +.align 16 +.Lcloop1: + add $TX[0]#b,$YY#b + movzb $YY#b,$YY#d + movzb ($dat,$YY),$TY#d + movb $TX[0]#b,($dat,$YY) + movb $TY#b,($dat,$XX[0]) + add $TX[0]#b,$TY#b + add \$1,$XX[0]#b + movzb $TY#b,$TY#d + movzb $XX[0]#b,$XX[0]#d + movzb ($dat,$TY),$TY#d + movzb ($dat,$XX[0]),$TX[0]#d + xorb ($inp),$TY#b + lea 1($inp),$inp + movb $TY#b,($out) + lea 1($out),$out + sub \$1,$len + jnz .Lcloop1 + jmp .Lexit + +.align 16 +.Lexit: + sub \$1,$XX[0]#b + movl $XX[0]#d,-8($dat) + movl $YY#d,-4($dat) + + mov (%rsp),%r13 + mov 8(%rsp),%r12 + mov 16(%rsp),%rbx + add \$24,%rsp +.Lepilogue: + ret +.size RC4,.-RC4 +___ +} + +$idx="%r8"; +$ido="%r9"; + +$code.=<<___; +.globl private_RC4_set_key +.type private_RC4_set_key,\@function,3 +.align 16 +private_RC4_set_key: + lea 8($dat),$dat + lea ($inp,$len),$inp + neg $len + mov $len,%rcx + xor %eax,%eax + xor $ido,$ido + xor %r10,%r10 + xor %r11,%r11 + + mov OPENSSL_ia32cap_P(%rip),$idx#d + bt \$20,$idx#d # RC4_CHAR? + jc .Lc1stloop + jmp .Lw1stloop + +.align 16 +.Lw1stloop: + mov %eax,($dat,%rax,4) + add \$1,%al + jnc .Lw1stloop + + xor $ido,$ido + xor $idx,$idx +.align 16 +.Lw2ndloop: + mov ($dat,$ido,4),%r10d + add ($inp,$len,1),$idx#b + add %r10b,$idx#b + add \$1,$len + mov ($dat,$idx,4),%r11d + cmovz %rcx,$len + mov %r10d,($dat,$idx,4) + mov %r11d,($dat,$ido,4) + add \$1,$ido#b + jnc .Lw2ndloop + jmp .Lexit_key + +.align 16 +.Lc1stloop: + mov %al,($dat,%rax) + add \$1,%al + jnc .Lc1stloop + + xor $ido,$ido + xor $idx,$idx +.align 16 +.Lc2ndloop: + mov ($dat,$ido),%r10b + add ($inp,$len),$idx#b + add %r10b,$idx#b + add \$1,$len + mov ($dat,$idx),%r11b + jnz .Lcnowrap + mov %rcx,$len +.Lcnowrap: + mov %r10b,($dat,$idx) + mov %r11b,($dat,$ido) + add \$1,$ido#b + jnc .Lc2ndloop + movl \$-1,256($dat) + +.align 16 +.Lexit_key: + xor %eax,%eax + mov %eax,-8($dat) + mov %eax,-4($dat) + ret +.size private_RC4_set_key,.-private_RC4_set_key + +.globl RC4_options +.type RC4_options,\@abi-omnipotent +.align 16 +RC4_options: + lea .Lopts(%rip),%rax + mov OPENSSL_ia32cap_P(%rip),%edx + bt \$20,%edx + jc .L8xchar + bt \$30,%edx + jnc .Ldone + add \$25,%rax + ret +.L8xchar: + add \$12,%rax +.Ldone: + ret +.align 64 +.Lopts: +.asciz "rc4(8x,int)" +.asciz "rc4(8x,char)" +.asciz "rc4(16x,int)" +.asciz "RC4 for x86_64, CRYPTOGAMS by " +.align 64 +.size RC4_options,.-RC4_options +___ + +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type stream_se_handler,\@abi-omnipotent +.align 16 +stream_se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + lea .Lprologue(%rip),%r10 + cmp %r10,%rbx # context->RipRsp + + lea .Lepilogue(%rip),%r10 + cmp %r10,%rbx # context->Rip>=epilogue label + jae .Lin_prologue + + lea 24(%rax),%rax + + mov -8(%rax),%rbx + mov -16(%rax),%r12 + mov -24(%rax),%r13 + mov %rbx,144($context) # restore context->Rbx + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + +.Lin_prologue: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + jmp .Lcommon_seh_exit +.size stream_se_handler,.-stream_se_handler + +.type key_se_handler,\@abi-omnipotent +.align 16 +key_se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 152($context),%rax # pull context->Rsp + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + +.Lcommon_seh_exit: + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$154,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size key_se_handler,.-key_se_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_RC4 + .rva .LSEH_end_RC4 + .rva .LSEH_info_RC4 + + .rva .LSEH_begin_private_RC4_set_key + .rva .LSEH_end_private_RC4_set_key + .rva .LSEH_info_private_RC4_set_key + +.section .xdata +.align 8 +.LSEH_info_RC4: + .byte 9,0,0,0 + .rva stream_se_handler +.LSEH_info_private_RC4_set_key: + .byte 9,0,0,0 + .rva key_se_handler +___ +} + +sub reg_part { +my ($reg,$conv)=@_; + if ($reg =~ /%r[0-9]+/) { $reg .= $conv; } + elsif ($conv eq "b") { $reg =~ s/%[er]([^x]+)x?/%$1l/; } + elsif ($conv eq "w") { $reg =~ s/%[er](.+)/%$1/; } + elsif ($conv eq "d") { $reg =~ s/%[er](.+)/%e$1/; } + return $reg; +} + +$code =~ s/(%[a-z0-9]+)#([bwd])/reg_part($1,$2)/gem; +$code =~ s/\`([^\`]*)\`/eval $1/gem; + +print $code; + +close STDOUT; diff --git a/libs/openssl/crypto/rc4/rc4.c b/libs/openssl/crypto/rc4/rc4.c new file mode 100644 index 00000000..99082e89 --- /dev/null +++ b/libs/openssl/crypto/rc4/rc4.c @@ -0,0 +1,179 @@ +/* crypto/rc4/rc4.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include + +char *usage[] = { + "usage: rc4 args\n", + "\n", + " -in arg - input file - default stdin\n", + " -out arg - output file - default stdout\n", + " -key key - password\n", + NULL +}; + +int main(int argc, char *argv[]) +{ + FILE *in = NULL, *out = NULL; + char *infile = NULL, *outfile = NULL, *keystr = NULL; + RC4_KEY key; + char buf[BUFSIZ]; + int badops = 0, i; + char **pp; + unsigned char md[MD5_DIGEST_LENGTH]; + + argc--; + argv++; + while (argc >= 1) { + if (strcmp(*argv, "-in") == 0) { + if (--argc < 1) + goto bad; + infile = *(++argv); + } else if (strcmp(*argv, "-out") == 0) { + if (--argc < 1) + goto bad; + outfile = *(++argv); + } else if (strcmp(*argv, "-key") == 0) { + if (--argc < 1) + goto bad; + keystr = *(++argv); + } else { + fprintf(stderr, "unknown option %s\n", *argv); + badops = 1; + break; + } + argc--; + argv++; + } + + if (badops) { + bad: + for (pp = usage; (*pp != NULL); pp++) + fprintf(stderr, "%s", *pp); + exit(1); + } + + if (infile == NULL) + in = stdin; + else { + in = fopen(infile, "r"); + if (in == NULL) { + perror("open"); + exit(1); + } + + } + if (outfile == NULL) + out = stdout; + else { + out = fopen(outfile, "w"); + if (out == NULL) { + perror("open"); + exit(1); + } + } + +#ifdef OPENSSL_SYS_MSDOS + /* This should set the file to binary mode. */ + { +# include + setmode(fileno(in), O_BINARY); + setmode(fileno(out), O_BINARY); + } +#endif + + if (keystr == NULL) { /* get key */ + i = EVP_read_pw_string(buf, BUFSIZ, "Enter RC4 password:", 0); + if (i != 0) { + OPENSSL_cleanse(buf, BUFSIZ); + fprintf(stderr, "bad password read\n"); + exit(1); + } + keystr = buf; + } + + EVP_Digest((unsigned char *)keystr, strlen(keystr), md, NULL, EVP_md5(), + NULL); + OPENSSL_cleanse(keystr, strlen(keystr)); + RC4_set_key(&key, MD5_DIGEST_LENGTH, md); + + for (;;) { + i = fread(buf, 1, BUFSIZ, in); + if (i == 0) + break; + if (i < 0) { + perror("read"); + exit(1); + } + RC4(&key, (unsigned int)i, (unsigned char *)buf, + (unsigned char *)buf); + i = fwrite(buf, (unsigned int)i, 1, out); + if (i != 1) { + perror("write"); + exit(1); + } + } + fclose(out); + fclose(in); + exit(0); + return (1); +} diff --git a/libs/openssl/crypto/rc4/rc4.h b/libs/openssl/crypto/rc4/rc4.h new file mode 100644 index 00000000..39162b16 --- /dev/null +++ b/libs/openssl/crypto/rc4/rc4.h @@ -0,0 +1,88 @@ +/* crypto/rc4/rc4.h */ +/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RC4_H +# define HEADER_RC4_H + +# include /* OPENSSL_NO_RC4, RC4_INT */ +# ifdef OPENSSL_NO_RC4 +# error RC4 is disabled. +# endif + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct rc4_key_st { + RC4_INT x, y; + RC4_INT data[256]; +} RC4_KEY; + +const char *RC4_options(void); +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data); +void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, + unsigned char *outdata); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/rc4/rc4_enc.c b/libs/openssl/crypto/rc4/rc4_enc.c new file mode 100644 index 00000000..6ebd54d4 --- /dev/null +++ b/libs/openssl/crypto/rc4/rc4_enc.c @@ -0,0 +1,334 @@ +/* crypto/rc4/rc4_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rc4_locl.h" + +/*- + * RC4 as implemented from a posting from + * Newsgroups: sci.crypt + * From: sterndark@netcom.com (David Sterndark) + * Subject: RC4 Algorithm revealed. + * Message-ID: + * Date: Wed, 14 Sep 1994 06:35:31 GMT + */ + +void RC4(RC4_KEY *key, size_t len, const unsigned char *indata, + unsigned char *outdata) +{ + register RC4_INT *d; + register RC4_INT x, y, tx, ty; + size_t i; + + x = key->x; + y = key->y; + d = key->data; + +#if defined(RC4_CHUNK) + /*- + * The original reason for implementing this(*) was the fact that + * pre-21164a Alpha CPUs don't have byte load/store instructions + * and e.g. a byte store has to be done with 64-bit load, shift, + * and, or and finally 64-bit store. Peaking data and operating + * at natural word size made it possible to reduce amount of + * instructions as well as to perform early read-ahead without + * suffering from RAW (read-after-write) hazard. This resulted + * in ~40%(**) performance improvement on 21064 box with gcc. + * But it's not only Alpha users who win here:-) Thanks to the + * early-n-wide read-ahead this implementation also exhibits + * >40% speed-up on SPARC and 20-30% on 64-bit MIPS (depending + * on sizeof(RC4_INT)). + * + * (*) "this" means code which recognizes the case when input + * and output pointers appear to be aligned at natural CPU + * word boundary + * (**) i.e. according to 'apps/openssl speed rc4' benchmark, + * crypto/rc4/rc4speed.c exhibits almost 70% speed-up... + * + * Cavets. + * + * - RC4_CHUNK="unsigned long long" should be a #1 choice for + * UltraSPARC. Unfortunately gcc generates very slow code + * (2.5-3 times slower than one generated by Sun's WorkShop + * C) and therefore gcc (at least 2.95 and earlier) should + * always be told that RC4_CHUNK="unsigned long". + * + * + */ + +# define RC4_STEP ( \ + x=(x+1) &0xff, \ + tx=d[x], \ + y=(tx+y)&0xff, \ + ty=d[y], \ + d[y]=tx, \ + d[x]=ty, \ + (RC4_CHUNK)d[(tx+ty)&0xff]\ + ) + + if ((((size_t)indata & (sizeof(RC4_CHUNK) - 1)) | + ((size_t)outdata & (sizeof(RC4_CHUNK) - 1))) == 0) { + RC4_CHUNK ichunk, otp; + const union { + long one; + char little; + } is_endian = { + 1 + }; + + /*- + * I reckon we can afford to implement both endian + * cases and to decide which way to take at run-time + * because the machine code appears to be very compact + * and redundant 1-2KB is perfectly tolerable (i.e. + * in case the compiler fails to eliminate it:-). By + * suggestion from Terrel Larson + * who also stands for the is_endian union:-) + * + * Special notes. + * + * - is_endian is declared automatic as doing otherwise + * (declaring static) prevents gcc from eliminating + * the redundant code; + * - compilers (those I've tried) don't seem to have + * problems eliminating either the operators guarded + * by "if (sizeof(RC4_CHUNK)==8)" or the condition + * expressions themselves so I've got 'em to replace + * corresponding #ifdefs from the previous version; + * - I chose to let the redundant switch cases when + * sizeof(RC4_CHUNK)!=8 be (were also #ifdefed + * before); + * - in case you wonder "&(sizeof(RC4_CHUNK)*8-1)" in + * [LB]ESHFT guards against "shift is out of range" + * warnings when sizeof(RC4_CHUNK)!=8 + * + * + */ + if (!is_endian.little) { /* BIG-ENDIAN CASE */ +# define BESHFT(c) (((sizeof(RC4_CHUNK)-(c)-1)*8)&(sizeof(RC4_CHUNK)*8-1)) + for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) { + ichunk = *(RC4_CHUNK *) indata; + otp = RC4_STEP << BESHFT(0); + otp |= RC4_STEP << BESHFT(1); + otp |= RC4_STEP << BESHFT(2); + otp |= RC4_STEP << BESHFT(3); + if (sizeof(RC4_CHUNK) == 8) { + otp |= RC4_STEP << BESHFT(4); + otp |= RC4_STEP << BESHFT(5); + otp |= RC4_STEP << BESHFT(6); + otp |= RC4_STEP << BESHFT(7); + } + *(RC4_CHUNK *) outdata = otp ^ ichunk; + indata += sizeof(RC4_CHUNK); + outdata += sizeof(RC4_CHUNK); + } + if (len) { + RC4_CHUNK mask = (RC4_CHUNK) - 1, ochunk; + + ichunk = *(RC4_CHUNK *) indata; + ochunk = *(RC4_CHUNK *) outdata; + otp = 0; + i = BESHFT(0); + mask <<= (sizeof(RC4_CHUNK) - len) << 3; + switch (len & (sizeof(RC4_CHUNK) - 1)) { + case 7: + otp = RC4_STEP << i, i -= 8; + case 6: + otp |= RC4_STEP << i, i -= 8; + case 5: + otp |= RC4_STEP << i, i -= 8; + case 4: + otp |= RC4_STEP << i, i -= 8; + case 3: + otp |= RC4_STEP << i, i -= 8; + case 2: + otp |= RC4_STEP << i, i -= 8; + case 1: + otp |= RC4_STEP << i, i -= 8; + case 0:; /* + * it's never the case, + * but it has to be here + * for ultrix? + */ + } + ochunk &= ~mask; + ochunk |= (otp ^ ichunk) & mask; + *(RC4_CHUNK *) outdata = ochunk; + } + key->x = x; + key->y = y; + return; + } else { /* LITTLE-ENDIAN CASE */ +# define LESHFT(c) (((c)*8)&(sizeof(RC4_CHUNK)*8-1)) + for (; len & (0 - sizeof(RC4_CHUNK)); len -= sizeof(RC4_CHUNK)) { + ichunk = *(RC4_CHUNK *) indata; + otp = RC4_STEP; + otp |= RC4_STEP << 8; + otp |= RC4_STEP << 16; + otp |= RC4_STEP << 24; + if (sizeof(RC4_CHUNK) == 8) { + otp |= RC4_STEP << LESHFT(4); + otp |= RC4_STEP << LESHFT(5); + otp |= RC4_STEP << LESHFT(6); + otp |= RC4_STEP << LESHFT(7); + } + *(RC4_CHUNK *) outdata = otp ^ ichunk; + indata += sizeof(RC4_CHUNK); + outdata += sizeof(RC4_CHUNK); + } + if (len) { + RC4_CHUNK mask = (RC4_CHUNK) - 1, ochunk; + + ichunk = *(RC4_CHUNK *) indata; + ochunk = *(RC4_CHUNK *) outdata; + otp = 0; + i = 0; + mask >>= (sizeof(RC4_CHUNK) - len) << 3; + switch (len & (sizeof(RC4_CHUNK) - 1)) { + case 7: + otp = RC4_STEP, i += 8; + case 6: + otp |= RC4_STEP << i, i += 8; + case 5: + otp |= RC4_STEP << i, i += 8; + case 4: + otp |= RC4_STEP << i, i += 8; + case 3: + otp |= RC4_STEP << i, i += 8; + case 2: + otp |= RC4_STEP << i, i += 8; + case 1: + otp |= RC4_STEP << i, i += 8; + case 0:; /* + * it's never the case, + * but it has to be here + * for ultrix? + */ + } + ochunk &= ~mask; + ochunk |= (otp ^ ichunk) & mask; + *(RC4_CHUNK *) outdata = ochunk; + } + key->x = x; + key->y = y; + return; + } + } +#endif +#define LOOP(in,out) \ + x=((x+1)&0xff); \ + tx=d[x]; \ + y=(tx+y)&0xff; \ + d[x]=ty=d[y]; \ + d[y]=tx; \ + (out) = d[(tx+ty)&0xff]^ (in); + +#ifndef RC4_INDEX +# define RC4_LOOP(a,b,i) LOOP(*((a)++),*((b)++)) +#else +# define RC4_LOOP(a,b,i) LOOP(a[i],b[i]) +#endif + + i = len >> 3; + if (i) { + for (;;) { + RC4_LOOP(indata, outdata, 0); + RC4_LOOP(indata, outdata, 1); + RC4_LOOP(indata, outdata, 2); + RC4_LOOP(indata, outdata, 3); + RC4_LOOP(indata, outdata, 4); + RC4_LOOP(indata, outdata, 5); + RC4_LOOP(indata, outdata, 6); + RC4_LOOP(indata, outdata, 7); +#ifdef RC4_INDEX + indata += 8; + outdata += 8; +#endif + if (--i == 0) + break; + } + } + i = len & 0x07; + if (i) { + for (;;) { + RC4_LOOP(indata, outdata, 0); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 1); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 2); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 3); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 4); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 5); + if (--i == 0) + break; + RC4_LOOP(indata, outdata, 6); + if (--i == 0) + break; + } + } + key->x = x; + key->y = y; +} diff --git a/libs/openssl/crypto/rc4/rc4_locl.h b/libs/openssl/crypto/rc4/rc4_locl.h new file mode 100644 index 00000000..faf8742f --- /dev/null +++ b/libs/openssl/crypto/rc4/rc4_locl.h @@ -0,0 +1,5 @@ +#ifndef HEADER_RC4_LOCL_H +# define HEADER_RC4_LOCL_H +# include +# include +#endif diff --git a/libs/openssl/crypto/rc4/rc4_skey.c b/libs/openssl/crypto/rc4/rc4_skey.c new file mode 100644 index 00000000..06890d16 --- /dev/null +++ b/libs/openssl/crypto/rc4/rc4_skey.c @@ -0,0 +1,116 @@ +/* crypto/rc4/rc4_skey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rc4_locl.h" +#include + +const char RC4_version[] = "RC4" OPENSSL_VERSION_PTEXT; + +const char *RC4_options(void) +{ +#ifdef RC4_INDEX + if (sizeof(RC4_INT) == 1) + return ("rc4(idx,char)"); + else + return ("rc4(idx,int)"); +#else + if (sizeof(RC4_INT) == 1) + return ("rc4(ptr,char)"); + else + return ("rc4(ptr,int)"); +#endif +} + +/*- + * RC4 as implemented from a posting from + * Newsgroups: sci.crypt + * From: sterndark@netcom.com (David Sterndark) + * Subject: RC4 Algorithm revealed. + * Message-ID: + * Date: Wed, 14 Sep 1994 06:35:31 GMT + */ + +void private_RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) +{ + register RC4_INT tmp; + register int id1, id2; + register RC4_INT *d; + unsigned int i; + + d = &(key->data[0]); + key->x = 0; + key->y = 0; + id1 = id2 = 0; + +#define SK_LOOP(d,n) { \ + tmp=d[(n)]; \ + id2 = (data[id1] + tmp + id2) & 0xff; \ + if (++id1 == len) id1=0; \ + d[(n)]=d[id2]; \ + d[id2]=tmp; } + + for (i = 0; i < 256; i++) + d[i] = i; + for (i = 0; i < 256; i += 4) { + SK_LOOP(d, i + 0); + SK_LOOP(d, i + 1); + SK_LOOP(d, i + 2); + SK_LOOP(d, i + 3); + } +} diff --git a/libs/openssl/crypto/rc4/rc4_utl.c b/libs/openssl/crypto/rc4/rc4_utl.c new file mode 100644 index 00000000..cbd4a24e --- /dev/null +++ b/libs/openssl/crypto/rc4/rc4_utl.c @@ -0,0 +1,62 @@ +/* crypto/rc4/rc4_utl.c */ +/* ==================================================================== + * Copyright (c) 2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include +#include + +void RC4_set_key(RC4_KEY *key, int len, const unsigned char *data) +{ +#ifdef OPENSSL_FIPS + fips_cipher_abort(RC4); +#endif + private_RC4_set_key(key, len, data); +} diff --git a/libs/openssl/crypto/rc4/rc4s.cpp b/libs/openssl/crypto/rc4/rc4s.cpp new file mode 100644 index 00000000..3814fde9 --- /dev/null +++ b/libs/openssl/crypto/rc4/rc4s.cpp @@ -0,0 +1,73 @@ +// +// gettsc.inl +// +// gives access to the Pentium's (secret) cycle counter +// +// This software was written by Leonard Janke (janke@unixg.ubc.ca) +// in 1996-7 and is entered, by him, into the public domain. + +#if defined(__WATCOMC__) +void GetTSC(unsigned long&); +#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax]; +#elif defined(__GNUC__) +inline +void GetTSC(unsigned long& tsc) +{ + asm volatile(".byte 15, 49\n\t" + : "=eax" (tsc) + : + : "%edx", "%eax"); +} +#elif defined(_MSC_VER) +inline +void GetTSC(unsigned long& tsc) +{ + unsigned long a; + __asm _emit 0fh + __asm _emit 31h + __asm mov a, eax; + tsc=a; +} +#endif + +#include +#include +#include + +void main(int argc,char *argv[]) + { + unsigned char buffer[1024]; + RC4_KEY ctx; + unsigned long s1,s2,e1,e2; + unsigned char k[16]; + unsigned long data[2]; + unsigned char iv[8]; + int i,num=64,numm; + int j=0; + + if (argc >= 2) + num=atoi(argv[1]); + + if (num == 0) num=256; + if (num > 1024-16) num=1024-16; + numm=num+8; + + for (j=0; j<6; j++) + { + for (i=0; i<10; i++) /**/ + { + RC4(&ctx,numm,buffer,buffer); + GetTSC(s1); + RC4(&ctx,numm,buffer,buffer); + GetTSC(e1); + GetTSC(s2); + RC4(&ctx,num,buffer,buffer); + GetTSC(e2); + RC4(&ctx,num,buffer,buffer); + } + + printf("RC4 (%d bytes) %d %d (%d) - 8 bytes\n",num, + e1-s1,e2-s2,(e1-s1)-(e2-s2)); + } + } + diff --git a/libs/openssl/crypto/rc4/rc4speed.c b/libs/openssl/crypto/rc4/rc4speed.c new file mode 100644 index 00000000..3f13a2b2 --- /dev/null +++ b/libs/openssl/crypto/rc4/rc4speed.c @@ -0,0 +1,239 @@ +/* crypto/rc4/rc4speed.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */ +/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */ + +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX) +# define TIMES +#endif + +#include + +#include +#include OPENSSL_UNISTD_IO +OPENSSL_DECLARE_EXIT +#ifndef OPENSSL_SYS_NETWARE +# include +#endif +#ifndef _IRIX +# include +#endif +#ifdef TIMES +# include +# include +#endif + /* + * Depending on the VMS version, the tms structure is perhaps defined. + * The __TMS macro will show if it was. If it wasn't defined, we should + * undefine TIMES, since that tells the rest of the program how things + * should be handled. -- Richard Levitte + */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) +# undef TIMES +#endif +#ifndef TIMES +# include +#endif +#if defined(sun) || defined(__ultrix) +# define _POSIX_SOURCE +# include +# include +#endif +#include +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# define HZ 100.0 +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +#endif +#define BUFSIZE ((long)1024) +long run = 0; + +double Time_F(int s); +#ifdef SIGALRM +# if defined(__STDC__) || defined(sgi) || defined(_AIX) +# define SIGRETTYPE void +# else +# define SIGRETTYPE int +# endif + +SIGRETTYPE sig_done(int sig); +SIGRETTYPE sig_done(int sig) +{ + signal(SIGALRM, sig_done); + run = 0; +# ifdef LINT + sig = sig; +# endif +} +#endif + +#define START 0 +#define STOP 1 + +double Time_F(int s) +{ + double ret; +#ifdef TIMES + static struct tms tstart, tend; + + if (s == START) { + times(&tstart); + return (0); + } else { + times(&tend); + ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ; + return ((ret == 0.0) ? 1e-6 : ret); + } +#else /* !times() */ + static struct timeb tstart, tend; + long i; + + if (s == START) { + ftime(&tstart); + return (0); + } else { + ftime(&tend); + i = (long)tend.millitm - (long)tstart.millitm; + ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1e3; + return ((ret == 0.0) ? 1e-6 : ret); + } +#endif +} + +int main(int argc, char **argv) +{ + long count; + static unsigned char buf[BUFSIZE]; + static unsigned char key[] = { + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + RC4_KEY sch; + double a, b, c, d; +#ifndef SIGALRM + long ca, cb, cc; +#endif + +#ifndef TIMES + printf("To get the most accurate results, try to run this\n"); + printf("program when this computer is idle.\n"); +#endif + +#ifndef SIGALRM + printf("First we calculate the approximate speed ...\n"); + RC4_set_key(&sch, 16, key); + count = 10; + do { + long i; + unsigned long data[2]; + + count *= 2; + Time_F(START); + for (i = count; i; i--) + RC4(&sch, 8, buf, buf); + d = Time_F(STOP); + } while (d < 3.0); + ca = count / 512; + cc = count * 8 / BUFSIZE + 1; + printf("Doing RC4_set_key %ld times\n", ca); +# define COND(d) (count != (d)) +# define COUNT(d) (d) +#else +# define COND(c) (run) +# define COUNT(d) (count) + signal(SIGALRM, sig_done); + printf("Doing RC4_set_key for 10 seconds\n"); + alarm(10); +#endif + + Time_F(START); + for (count = 0, run = 1; COND(ca); count += 4) { + RC4_set_key(&sch, 16, key); + RC4_set_key(&sch, 16, key); + RC4_set_key(&sch, 16, key); + RC4_set_key(&sch, 16, key); + } + d = Time_F(STOP); + printf("%ld RC4_set_key's in %.2f seconds\n", count, d); + a = ((double)COUNT(ca)) / d; + +#ifdef SIGALRM + printf("Doing RC4 on %ld byte blocks for 10 seconds\n", BUFSIZE); + alarm(10); +#else + printf("Doing RC4 %ld times on %ld byte blocks\n", cc, BUFSIZE); +#endif + Time_F(START); + for (count = 0, run = 1; COND(cc); count++) + RC4(&sch, BUFSIZE, buf, buf); + d = Time_F(STOP); + printf("%ld RC4's of %ld byte blocks in %.2f second\n", + count, BUFSIZE, d); + c = ((double)COUNT(cc) * BUFSIZE) / d; + + printf("RC4 set_key per sec = %12.2f (%9.3fuS)\n", a, 1.0e6 / a); + printf("RC4 bytes per sec = %12.2f (%9.3fuS)\n", c, 8.0e6 / c); + exit(0); +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS) + return (0); +#endif +} diff --git a/libs/openssl/crypto/rc4/rc4test.c b/libs/openssl/crypto/rc4/rc4test.c new file mode 100644 index 00000000..e2bfbfa1 --- /dev/null +++ b/libs/openssl/crypto/rc4/rc4test.c @@ -0,0 +1,235 @@ +/* crypto/rc4/rc4test.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "../e_os.h" + +#ifdef OPENSSL_NO_RC4 +int main(int argc, char *argv[]) +{ + printf("No RC4 support\n"); + return (0); +} +#else +# include +# include + +static unsigned char keys[7][30] = { + {8, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + {8, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + {8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {4, 0xef, 0x01, 0x23, 0x45}, + {8, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef}, + {4, 0xef, 0x01, 0x23, 0x45}, +}; + +static unsigned char data_len[7] = { 8, 8, 8, 20, 28, 10 }; + +static unsigned char data[7][30] = { + {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xff}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xff}, + {0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, + 0x12, 0x34, 0x56, 0x78, 0xff}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff}, + {0}, +}; + +static unsigned char output[7][30] = { + {0x75, 0xb7, 0x87, 0x80, 0x99, 0xe0, 0xc5, 0x96, 0x00}, + {0x74, 0x94, 0xc2, 0xe7, 0x10, 0x4b, 0x08, 0x79, 0x00}, + {0xde, 0x18, 0x89, 0x41, 0xa3, 0x37, 0x5d, 0x3a, 0x00}, + {0xd6, 0xa1, 0x41, 0xa7, 0xec, 0x3c, 0x38, 0xdf, + 0xbd, 0x61, 0x5a, 0x11, 0x62, 0xe1, 0xc7, 0xba, + 0x36, 0xb6, 0x78, 0x58, 0x00}, + {0x66, 0xa0, 0x94, 0x9f, 0x8a, 0xf7, 0xd6, 0x89, + 0x1f, 0x7f, 0x83, 0x2b, 0xa8, 0x33, 0xc0, 0x0c, + 0x89, 0x2e, 0xbe, 0x30, 0x14, 0x3c, 0xe2, 0x87, + 0x40, 0x01, 0x1e, 0xcf, 0x00}, + {0xd6, 0xa1, 0x41, 0xa7, 0xec, 0x3c, 0x38, 0xdf, 0xbd, 0x61, 0x00}, + {0}, +}; + +int main(int argc, char *argv[]) +{ + int i, err = 0; + int j; + unsigned char *p; + RC4_KEY key; + unsigned char obuf[512]; + +# if !defined(OPENSSL_PIC) + void OPENSSL_cpuid_setup(void); + + OPENSSL_cpuid_setup(); +# endif + + for (i = 0; i < 6; i++) { + RC4_set_key(&key, keys[i][0], &(keys[i][1])); + memset(obuf, 0x00, sizeof(obuf)); + RC4(&key, data_len[i], &(data[i][0]), obuf); + if (memcmp(obuf, output[i], data_len[i] + 1) != 0) { + printf("error calculating RC4\n"); + printf("output:"); + for (j = 0; j < data_len[i] + 1; j++) + printf(" %02x", obuf[j]); + printf("\n"); + printf("expect:"); + p = &(output[i][0]); + for (j = 0; j < data_len[i] + 1; j++) + printf(" %02x", *(p++)); + printf("\n"); + err++; + } else + printf("test %d ok\n", i); + } + printf("test end processing "); + for (i = 0; i < data_len[3]; i++) { + RC4_set_key(&key, keys[3][0], &(keys[3][1])); + memset(obuf, 0x00, sizeof(obuf)); + RC4(&key, i, &(data[3][0]), obuf); + if ((memcmp(obuf, output[3], i) != 0) || (obuf[i] != 0)) { + printf("error in RC4 length processing\n"); + printf("output:"); + for (j = 0; j < i + 1; j++) + printf(" %02x", obuf[j]); + printf("\n"); + printf("expect:"); + p = &(output[3][0]); + for (j = 0; j < i; j++) + printf(" %02x", *(p++)); + printf(" 00\n"); + err++; + } else { + printf("."); + fflush(stdout); + } + } + printf("done\n"); + printf("test multi-call "); + for (i = 0; i < data_len[3]; i++) { + RC4_set_key(&key, keys[3][0], &(keys[3][1])); + memset(obuf, 0x00, sizeof(obuf)); + RC4(&key, i, &(data[3][0]), obuf); + RC4(&key, data_len[3] - i, &(data[3][i]), &(obuf[i])); + if (memcmp(obuf, output[3], data_len[3] + 1) != 0) { + printf("error in RC4 multi-call processing\n"); + printf("output:"); + for (j = 0; j < data_len[3] + 1; j++) + printf(" %02x", obuf[j]); + printf("\n"); + printf("expect:"); + p = &(output[3][0]); + for (j = 0; j < data_len[3] + 1; j++) + printf(" %02x", *(p++)); + err++; + } else { + printf("."); + fflush(stdout); + } + } + printf("done\n"); + printf("bulk test "); + { + unsigned char buf[513]; + SHA_CTX c; + unsigned char md[SHA_DIGEST_LENGTH]; + static unsigned char expected[] = { + 0xa4, 0x7b, 0xcc, 0x00, 0x3d, 0xd0, 0xbd, 0xe1, 0xac, 0x5f, + 0x12, 0x1e, 0x45, 0xbc, 0xfb, 0x1a, 0xa1, 0xf2, 0x7f, 0xc5 + }; + + RC4_set_key(&key, keys[0][0], &(keys[3][1])); + memset(buf, '\0', sizeof(buf)); + SHA1_Init(&c); + for (i = 0; i < 2571; i++) { + RC4(&key, sizeof(buf), buf, buf); + SHA1_Update(&c, buf, sizeof(buf)); + } + SHA1_Final(md, &c); + + if (memcmp(md, expected, sizeof(md))) { + printf("error in RC4 bulk test\n"); + printf("output:"); + for (j = 0; j < (int)sizeof(md); j++) + printf(" %02x", md[j]); + printf("\n"); + printf("expect:"); + for (j = 0; j < (int)sizeof(md); j++) + printf(" %02x", expected[j]); + printf("\n"); + err++; + } else + printf("ok\n"); + } +# ifdef OPENSSL_SYS_NETWARE + if (err) + printf("ERROR: %d\n", err); +# endif + EXIT(err); + return (0); +} +#endif diff --git a/libs/openssl/crypto/rc4/rrc4.doc b/libs/openssl/crypto/rc4/rrc4.doc new file mode 100644 index 00000000..2f9a953c --- /dev/null +++ b/libs/openssl/crypto/rc4/rrc4.doc @@ -0,0 +1,278 @@ +Newsgroups: sci.crypt,alt.security,comp.security.misc,alt.privacy +Path: ghost.dsi.unimi.it!univ-lyon1.fr!jussieu.fr!zaphod.crihan.fr!warwick!clyde.open.ac.uk!strath-cs!bnr.co.uk!bt!pipex!howland.reston.ans.net!europa.eng.gtefsd.com!MathWorks.Com!yeshua.marcam.com!charnel.ecst.csuchico.edu!csusac!csus.edu!netcom.com!sterndark +From: sterndark@netcom.com (David Sterndark) +Subject: RC4 Algorithm revealed. +Message-ID: +Sender: sterndark@netcom.com +Organization: NETCOM On-line Communication Services (408 261-4700 guest) +X-Newsreader: TIN [version 1.2 PL1] +Date: Wed, 14 Sep 1994 06:35:31 GMT +Lines: 263 +Xref: ghost.dsi.unimi.it sci.crypt:27332 alt.security:14732 comp.security.misc:11701 alt.privacy:16026 + +I am shocked, shocked, I tell you, shocked, to discover +that the cypherpunks have illegaly and criminally revealed +a crucial RSA trade secret and harmed the security of +America by reverse engineering the RC4 algorithm and +publishing it to the world. + +On Saturday morning an anonymous cypherpunk wrote: + + + SUBJECT: RC4 Source Code + + + I've tested this. It is compatible with the RC4 object module + that comes in the various RSA toolkits. + + /* rc4.h */ + typedef struct rc4_key + { + unsigned char state[256]; + unsigned char x; + unsigned char y; + } rc4_key; + void prepare_key(unsigned char *key_data_ptr,int key_data_len, + rc4_key *key); + void rc4(unsigned char *buffer_ptr,int buffer_len,rc4_key * key); + + + /*rc4.c */ + #include "rc4.h" + static void swap_byte(unsigned char *a, unsigned char *b); + void prepare_key(unsigned char *key_data_ptr, int key_data_len, + rc4_key *key) + { + unsigned char swapByte; + unsigned char index1; + unsigned char index2; + unsigned char* state; + short counter; + + state = &key->state[0]; + for(counter = 0; counter < 256; counter++) + state[counter] = counter; + key->x = 0; + key->y = 0; + index1 = 0; + index2 = 0; + for(counter = 0; counter < 256; counter++) + { + index2 = (key_data_ptr[index1] + state[counter] + + index2) % 256; + swap_byte(&state[counter], &state[index2]); + + index1 = (index1 + 1) % key_data_len; + } + } + + void rc4(unsigned char *buffer_ptr, int buffer_len, rc4_key *key) + { + unsigned char x; + unsigned char y; + unsigned char* state; + unsigned char xorIndex; + short counter; + + x = key->x; + y = key->y; + + state = &key->state[0]; + for(counter = 0; counter < buffer_len; counter ++) + { + x = (x + 1) % 256; + y = (state[x] + y) % 256; + swap_byte(&state[x], &state[y]); + + xorIndex = (state[x] + state[y]) % 256; + + buffer_ptr[counter] ^= state[xorIndex]; + } + key->x = x; + key->y = y; + } + + static void swap_byte(unsigned char *a, unsigned char *b) + { + unsigned char swapByte; + + swapByte = *a; + *a = *b; + *b = swapByte; + } + + + +Another cypherpunk, this one not anonymous, tested the +output from this algorithm against the output from +official RC4 object code + + + Date: Tue, 13 Sep 94 18:37:56 PDT + From: ekr@eit.COM (Eric Rescorla) + Message-Id: <9409140137.AA17743@eitech.eit.com> + Subject: RC4 compatibility testing + Cc: cypherpunks@toad.com + + One data point: + + I can't say anything about the internals of RC4 versus the + algorithm that Bill Sommerfeld is rightly calling 'Alleged RC4', + since I don't know anything about RC4's internals. + + However, I do have a (legitimately acquired) copy of BSAFE2 and + so I'm able to compare the output of this algorithm to the output + of genuine RC4 as found in BSAFE. I chose a set of test vectors + and ran them through both algorithms. The algorithms appear to + give identical results, at least with these key/plaintext pairs. + + I note that this is the algorithm _without_ Hal Finney's + proposed modification + + (see <199409130605.XAA24133@jobe.shell.portal.com>). + + The vectors I used (together with the ciphertext they produce) + follow at the end of this message. + + -Ekr + + Disclaimer: This posting does not reflect the opinions of EIT. + + --------------------results follow-------------- + Test vector 0 + Key: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef + Input: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef + 0 Output: 0x75 0xb7 0x87 0x80 0x99 0xe0 0xc5 0x96 + + Test vector 1 + Key: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef + Input: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0 Output: 0x74 0x94 0xc2 0xe7 0x10 0x4b 0x08 0x79 + + Test vector 2 + Key: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + Input: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0 Output: 0xde 0x18 0x89 0x41 0xa3 0x37 0x5d 0x3a + + Test vector 3 + Key: 0xef 0x01 0x23 0x45 + Input: 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 + 0 Output: 0xd6 0xa1 0x41 0xa7 0xec 0x3c 0x38 0xdf 0xbd 0x61 + + Test vector 4 + Key: 0x01 0x23 0x45 0x67 0x89 0xab 0xcd 0xef + Input: 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 0x01 + 0x01 + 0 Output: 0x75 0x95 0xc3 0xe6 0x11 0x4a 0x09 0x78 0x0c 0x4a 0xd4 + 0x52 0x33 0x8e 0x1f 0xfd 0x9a 0x1b 0xe9 0x49 0x8f + 0x81 0x3d 0x76 0x53 0x34 0x49 0xb6 0x77 0x8d 0xca + 0xd8 0xc7 0x8a 0x8d 0x2b 0xa9 0xac 0x66 0x08 0x5d + 0x0e 0x53 0xd5 0x9c 0x26 0xc2 0xd1 0xc4 0x90 0xc1 + 0xeb 0xbe 0x0c 0xe6 0x6d 0x1b 0x6b 0x1b 0x13 0xb6 + 0xb9 0x19 0xb8 0x47 0xc2 0x5a 0x91 0x44 0x7a 0x95 + 0xe7 0x5e 0x4e 0xf1 0x67 0x79 0xcd 0xe8 0xbf 0x0a + 0x95 0x85 0x0e 0x32 0xaf 0x96 0x89 0x44 0x4f 0xd3 + 0x77 0x10 0x8f 0x98 0xfd 0xcb 0xd4 0xe7 0x26 0x56 + 0x75 0x00 0x99 0x0b 0xcc 0x7e 0x0c 0xa3 0xc4 0xaa + 0xa3 0x04 0xa3 0x87 0xd2 0x0f 0x3b 0x8f 0xbb 0xcd + 0x42 0xa1 0xbd 0x31 0x1d 0x7a 0x43 0x03 0xdd 0xa5 + 0xab 0x07 0x88 0x96 0xae 0x80 0xc1 0x8b 0x0a 0xf6 + 0x6d 0xff 0x31 0x96 0x16 0xeb 0x78 0x4e 0x49 0x5a + 0xd2 0xce 0x90 0xd7 0xf7 0x72 0xa8 0x17 0x47 0xb6 + 0x5f 0x62 0x09 0x3b 0x1e 0x0d 0xb9 0xe5 0xba 0x53 + 0x2f 0xaf 0xec 0x47 0x50 0x83 0x23 0xe6 0x71 0x32 + 0x7d 0xf9 0x44 0x44 0x32 0xcb 0x73 0x67 0xce 0xc8 + 0x2f 0x5d 0x44 0xc0 0xd0 0x0b 0x67 0xd6 0x50 0xa0 + 0x75 0xcd 0x4b 0x70 0xde 0xdd 0x77 0xeb 0x9b 0x10 + 0x23 0x1b 0x6b 0x5b 0x74 0x13 0x47 0x39 0x6d 0x62 + 0x89 0x74 0x21 0xd4 0x3d 0xf9 0xb4 0x2e 0x44 0x6e + 0x35 0x8e 0x9c 0x11 0xa9 0xb2 0x18 0x4e 0xcb 0xef + 0x0c 0xd8 0xe7 0xa8 0x77 0xef 0x96 0x8f 0x13 0x90 + 0xec 0x9b 0x3d 0x35 0xa5 0x58 0x5c 0xb0 0x09 0x29 + 0x0e 0x2f 0xcd 0xe7 0xb5 0xec 0x66 0xd9 0x08 0x4b + 0xe4 0x40 0x55 0xa6 0x19 0xd9 0xdd 0x7f 0xc3 0x16 + 0x6f 0x94 0x87 0xf7 0xcb 0x27 0x29 0x12 0x42 0x64 + 0x45 0x99 0x85 0x14 0xc1 0x5d 0x53 0xa1 0x8c 0x86 + 0x4c 0xe3 0xa2 0xb7 0x55 0x57 0x93 0x98 0x81 0x26 + 0x52 0x0e 0xac 0xf2 0xe3 0x06 0x6e 0x23 0x0c 0x91 + 0xbe 0xe4 0xdd 0x53 0x04 0xf5 0xfd 0x04 0x05 0xb3 + 0x5b 0xd9 0x9c 0x73 0x13 0x5d 0x3d 0x9b 0xc3 0x35 + 0xee 0x04 0x9e 0xf6 0x9b 0x38 0x67 0xbf 0x2d 0x7b + 0xd1 0xea 0xa5 0x95 0xd8 0xbf 0xc0 0x06 0x6f 0xf8 + 0xd3 0x15 0x09 0xeb 0x0c 0x6c 0xaa 0x00 0x6c 0x80 + 0x7a 0x62 0x3e 0xf8 0x4c 0x3d 0x33 0xc1 0x95 0xd2 + 0x3e 0xe3 0x20 0xc4 0x0d 0xe0 0x55 0x81 0x57 0xc8 + 0x22 0xd4 0xb8 0xc5 0x69 0xd8 0x49 0xae 0xd5 0x9d + 0x4e 0x0f 0xd7 0xf3 0x79 0x58 0x6b 0x4b 0x7f 0xf6 + 0x84 0xed 0x6a 0x18 0x9f 0x74 0x86 0xd4 0x9b 0x9c + 0x4b 0xad 0x9b 0xa2 0x4b 0x96 0xab 0xf9 0x24 0x37 + 0x2c 0x8a 0x8f 0xff 0xb1 0x0d 0x55 0x35 0x49 0x00 + 0xa7 0x7a 0x3d 0xb5 0xf2 0x05 0xe1 0xb9 0x9f 0xcd + 0x86 0x60 0x86 0x3a 0x15 0x9a 0xd4 0xab 0xe4 0x0f + 0xa4 0x89 0x34 0x16 0x3d 0xdd 0xe5 0x42 0xa6 0x58 + 0x55 0x40 0xfd 0x68 0x3c 0xbf 0xd8 0xc0 0x0f 0x12 + 0x12 0x9a 0x28 0x4d 0xea 0xcc 0x4c 0xde 0xfe 0x58 + 0xbe 0x71 0x37 0x54 0x1c 0x04 0x71 0x26 0xc8 0xd4 + 0x9e 0x27 0x55 0xab 0x18 0x1a 0xb7 0xe9 0x40 0xb0 + 0xc0 + + + +-- + --------------------------------------------------------------------- +We have the right to defend ourselves and our +property, because of the kind of animals that we James A. Donald +are. True law derives from this right, not from +the arbitrary power of the omnipotent state. jamesd@netcom.com + + diff --git a/libs/openssl/crypto/rc5/asm/rc5-586.pl b/libs/openssl/crypto/rc5/asm/rc5-586.pl new file mode 100644 index 00000000..61ac6eff --- /dev/null +++ b/libs/openssl/crypto/rc5/asm/rc5-586.pl @@ -0,0 +1,110 @@ +#!/usr/local/bin/perl + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; +require "cbc.pl"; + +&asm_init($ARGV[0],"rc5-586.pl"); + +$RC5_MAX_ROUNDS=16; +$RC5_32_OFF=($RC5_MAX_ROUNDS+2)*4; +$A="edi"; +$B="esi"; +$S="ebp"; +$tmp1="eax"; +$r="ebx"; +$tmpc="ecx"; +$tmp4="edx"; + +&RC5_32_encrypt("RC5_32_encrypt",1); +&RC5_32_encrypt("RC5_32_decrypt",0); +&cbc("RC5_32_cbc_encrypt","RC5_32_encrypt","RC5_32_decrypt",0,4,5,3,-1,-1); +&asm_finish(); + +sub RC5_32_encrypt + { + local($name,$enc)=@_; + + &function_begin_B($name,""); + + &comment(""); + + &push("ebp"); + &push("esi"); + &push("edi"); + &mov($tmp4,&wparam(0)); + &mov($S,&wparam(1)); + + &comment("Load the 2 words"); + &mov($A,&DWP(0,$tmp4,"",0)); + &mov($B,&DWP(4,$tmp4,"",0)); + + &push($r); + &mov($r, &DWP(0,$S,"",0)); + + # encrypting part + + if ($enc) + { + &add($A, &DWP(4+0,$S,"",0)); + &add($B, &DWP(4+4,$S,"",0)); + + for ($i=0; $i<$RC5_MAX_ROUNDS; $i++) + { + &xor($A, $B); + &mov($tmp1, &DWP(12+$i*8,$S,"",0)); + &mov($tmpc, $B); + &rotl($A, &LB("ecx")); + &add($A, $tmp1); + + &xor($B, $A); + &mov($tmp1, &DWP(16+$i*8,$S,"",0)); + &mov($tmpc, $A); + &rotl($B, &LB("ecx")); + &add($B, $tmp1); + if (($i == 7) || ($i == 11)) + { + &cmp($r, $i+1); + &je(&label("rc5_exit")); + } + } + } + else + { + &cmp($r, 12); + &je(&label("rc5_dec_12")); + &cmp($r, 8); + &je(&label("rc5_dec_8")); + for ($i=$RC5_MAX_ROUNDS; $i > 0; $i--) + { + &set_label("rc5_dec_$i") if ($i == 12) || ($i == 8); + &mov($tmp1, &DWP($i*8+8,$S,"",0)); + &sub($B, $tmp1); + &mov($tmpc, $A); + &rotr($B, &LB("ecx")); + &xor($B, $A); + + &mov($tmp1, &DWP($i*8+4,$S,"",0)); + &sub($A, $tmp1); + &mov($tmpc, $B); + &rotr($A, &LB("ecx")); + &xor($A, $B); + } + &sub($B, &DWP(4+4,$S,"",0)); + &sub($A, &DWP(4+0,$S,"",0)); + } + + &set_label("rc5_exit"); + &mov(&DWP(0,$tmp4,"",0),$A); + &mov(&DWP(4,$tmp4,"",0),$B); + + &pop("ebx"); + &pop("edi"); + &pop("esi"); + &pop("ebp"); + &ret(); + &function_end_B($name); + } + + diff --git a/libs/openssl/crypto/rc5/rc5.h b/libs/openssl/crypto/rc5/rc5.h new file mode 100644 index 00000000..fba61371 --- /dev/null +++ b/libs/openssl/crypto/rc5/rc5.h @@ -0,0 +1,115 @@ +/* crypto/rc5/rc5.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RC5_H +# define HEADER_RC5_H + +# include /* OPENSSL_NO_RC5 */ + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_RC5 +# error RC5 is disabled. +# endif + +# define RC5_ENCRYPT 1 +# define RC5_DECRYPT 0 + +/* 32 bit. For Alpha, things may get weird */ +# define RC5_32_INT unsigned long + +# define RC5_32_BLOCK 8 +# define RC5_32_KEY_LENGTH 16/* This is a default, max is 255 */ + +/* + * This are the only values supported. Tweak the code if you want more The + * most supported modes will be RC5-32/12/16 RC5-32/16/8 + */ +# define RC5_8_ROUNDS 8 +# define RC5_12_ROUNDS 12 +# define RC5_16_ROUNDS 16 + +typedef struct rc5_key_st { + /* Number of rounds */ + int rounds; + RC5_32_INT data[2 * (RC5_16_ROUNDS + 1)]; +} RC5_32_KEY; + +void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, + int rounds); +void RC5_32_ecb_encrypt(const unsigned char *in, unsigned char *out, + RC5_32_KEY *key, int enc); +void RC5_32_encrypt(unsigned long *data, RC5_32_KEY *key); +void RC5_32_decrypt(unsigned long *data, RC5_32_KEY *key); +void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *ks, unsigned char *iv, + int enc); +void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *schedule, + unsigned char *ivec, int *num, int enc); +void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *schedule, + unsigned char *ivec, int *num); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/rc5/rc5_ecb.c b/libs/openssl/crypto/rc5/rc5_ecb.c new file mode 100644 index 00000000..e657a93b --- /dev/null +++ b/libs/openssl/crypto/rc5/rc5_ecb.c @@ -0,0 +1,83 @@ +/* crypto/rc5/rc5_ecb.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rc5_locl.h" +#include + +const char RC5_version[] = "RC5" OPENSSL_VERSION_PTEXT; + +void RC5_32_ecb_encrypt(const unsigned char *in, unsigned char *out, + RC5_32_KEY *ks, int encrypt) +{ + unsigned long l, d[2]; + + c2l(in, l); + d[0] = l; + c2l(in, l); + d[1] = l; + if (encrypt) + RC5_32_encrypt(d, ks); + else + RC5_32_decrypt(d, ks); + l = d[0]; + l2c(l, out); + l = d[1]; + l2c(l, out); + l = d[0] = d[1] = 0; +} diff --git a/libs/openssl/crypto/rc5/rc5_enc.c b/libs/openssl/crypto/rc5/rc5_enc.c new file mode 100644 index 00000000..06b89d83 --- /dev/null +++ b/libs/openssl/crypto/rc5/rc5_enc.c @@ -0,0 +1,209 @@ +/* crypto/rc5/rc5_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "rc5_locl.h" + +void RC5_32_cbc_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *ks, unsigned char *iv, + int encrypt) +{ + register unsigned long tin0, tin1; + register unsigned long tout0, tout1, xor0, xor1; + register long l = length; + unsigned long tin[2]; + + if (encrypt) { + c2l(iv, tout0); + c2l(iv, tout1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + RC5_32_encrypt(tin, ks); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + if (l != -8) { + c2ln(in, tin0, tin1, l + 8); + tin0 ^= tout0; + tin1 ^= tout1; + tin[0] = tin0; + tin[1] = tin1; + RC5_32_encrypt(tin, ks); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + l2c(tout0, iv); + l2c(tout1, iv); + } else { + c2l(iv, xor0); + c2l(iv, xor1); + iv -= 8; + for (l -= 8; l >= 0; l -= 8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + RC5_32_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (l != -8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + RC5_32_decrypt(tin, ks); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2cn(tout0, tout1, out, l + 8); + xor0 = tin0; + xor1 = tin1; + } + l2c(xor0, iv); + l2c(xor1, iv); + } + tin0 = tin1 = tout0 = tout1 = xor0 = xor1 = 0; + tin[0] = tin[1] = 0; +} + +void RC5_32_encrypt(unsigned long *d, RC5_32_KEY *key) +{ + RC5_32_INT a, b, *s; + + s = key->data; + + a = d[0] + s[0]; + b = d[1] + s[1]; + E_RC5_32(a, b, s, 2); + E_RC5_32(a, b, s, 4); + E_RC5_32(a, b, s, 6); + E_RC5_32(a, b, s, 8); + E_RC5_32(a, b, s, 10); + E_RC5_32(a, b, s, 12); + E_RC5_32(a, b, s, 14); + E_RC5_32(a, b, s, 16); + if (key->rounds == 12) { + E_RC5_32(a, b, s, 18); + E_RC5_32(a, b, s, 20); + E_RC5_32(a, b, s, 22); + E_RC5_32(a, b, s, 24); + } else if (key->rounds == 16) { + /* Do a full expansion to avoid a jump */ + E_RC5_32(a, b, s, 18); + E_RC5_32(a, b, s, 20); + E_RC5_32(a, b, s, 22); + E_RC5_32(a, b, s, 24); + E_RC5_32(a, b, s, 26); + E_RC5_32(a, b, s, 28); + E_RC5_32(a, b, s, 30); + E_RC5_32(a, b, s, 32); + } + d[0] = a; + d[1] = b; +} + +void RC5_32_decrypt(unsigned long *d, RC5_32_KEY *key) +{ + RC5_32_INT a, b, *s; + + s = key->data; + + a = d[0]; + b = d[1]; + if (key->rounds == 16) { + D_RC5_32(a, b, s, 32); + D_RC5_32(a, b, s, 30); + D_RC5_32(a, b, s, 28); + D_RC5_32(a, b, s, 26); + /* Do a full expansion to avoid a jump */ + D_RC5_32(a, b, s, 24); + D_RC5_32(a, b, s, 22); + D_RC5_32(a, b, s, 20); + D_RC5_32(a, b, s, 18); + } else if (key->rounds == 12) { + D_RC5_32(a, b, s, 24); + D_RC5_32(a, b, s, 22); + D_RC5_32(a, b, s, 20); + D_RC5_32(a, b, s, 18); + } + D_RC5_32(a, b, s, 16); + D_RC5_32(a, b, s, 14); + D_RC5_32(a, b, s, 12); + D_RC5_32(a, b, s, 10); + D_RC5_32(a, b, s, 8); + D_RC5_32(a, b, s, 6); + D_RC5_32(a, b, s, 4); + D_RC5_32(a, b, s, 2); + d[0] = a - s[0]; + d[1] = b - s[1]; +} diff --git a/libs/openssl/crypto/rc5/rc5_locl.h b/libs/openssl/crypto/rc5/rc5_locl.h new file mode 100644 index 00000000..1e83f19f --- /dev/null +++ b/libs/openssl/crypto/rc5/rc5_locl.h @@ -0,0 +1,204 @@ +/* crypto/rc5/rc5_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +#undef c2l +#define c2l(c,l) (l =((unsigned long)(*((c)++))) , \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<<24L) + +/* NOTE - c is not incremented as per c2l */ +#undef c2ln +#define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24L; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16L; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8L; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24L; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16L; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8L; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +#undef l2c +#define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24L)&0xff)) + +/* NOTE - c is not incremented as per l2c */ +#undef l2cn +#define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24L)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16L)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8L)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24L)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16L)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8L)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +/* NOTE - c is not incremented as per n2l */ +#define n2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c)))) ; \ + case 7: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 6: l2|=((unsigned long)(*(--(c))))<<16; \ + case 5: l2|=((unsigned long)(*(--(c))))<<24; \ + case 4: l1 =((unsigned long)(*(--(c)))) ; \ + case 3: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 2: l1|=((unsigned long)(*(--(c))))<<16; \ + case 1: l1|=((unsigned long)(*(--(c))))<<24; \ + } \ + } + +/* NOTE - c is not incremented as per l2n */ +#define l2nn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1) )&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + } \ + } + +#undef n2l +#define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24L, \ + l|=((unsigned long)(*((c)++)))<<16L, \ + l|=((unsigned long)(*((c)++)))<< 8L, \ + l|=((unsigned long)(*((c)++)))) + +#undef l2n +#define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24L)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16L)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8L)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +#if (defined(OPENSSL_SYS_WIN32) && defined(_MSC_VER)) || defined(__ICC) +# define ROTATE_l32(a,n) _lrotl(a,n) +# define ROTATE_r32(a,n) _lrotr(a,n) +#elif defined(__GNUC__) && __GNUC__>=2 && !defined(__STRICT_ANSI__) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) && !defined(PEDANTIC) +# if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__) +# define ROTATE_l32(a,n) ({ register unsigned int ret; \ + asm ("roll %%cl,%0" \ + : "=r"(ret) \ + : "c"(n),"0"((unsigned int)(a)) \ + : "cc"); \ + ret; \ + }) +# define ROTATE_r32(a,n) ({ register unsigned int ret; \ + asm ("rorl %%cl,%0" \ + : "=r"(ret) \ + : "c"(n),"0"((unsigned int)(a)) \ + : "cc"); \ + ret; \ + }) +# endif +#endif +#ifndef ROTATE_l32 +# define ROTATE_l32(a,n) (((a)<<(n&0x1f))|(((a)&0xffffffff)>>(32-(n&0x1f)))) +#endif +#ifndef ROTATE_r32 +# define ROTATE_r32(a,n) (((a)<<(32-(n&0x1f)))|(((a)&0xffffffff)>>(n&0x1f))) +#endif + +#define RC5_32_MASK 0xffffffffL + +#define RC5_16_P 0xB7E1 +#define RC5_16_Q 0x9E37 +#define RC5_32_P 0xB7E15163L +#define RC5_32_Q 0x9E3779B9L +#define RC5_64_P 0xB7E151628AED2A6BLL +#define RC5_64_Q 0x9E3779B97F4A7C15LL + +#define E_RC5_32(a,b,s,n) \ + a^=b; \ + a=ROTATE_l32(a,b); \ + a+=s[n]; \ + a&=RC5_32_MASK; \ + b^=a; \ + b=ROTATE_l32(b,a); \ + b+=s[n+1]; \ + b&=RC5_32_MASK; + +#define D_RC5_32(a,b,s,n) \ + b-=s[n+1]; \ + b&=RC5_32_MASK; \ + b=ROTATE_r32(b,a); \ + b^=a; \ + a-=s[n]; \ + a&=RC5_32_MASK; \ + a=ROTATE_r32(a,b); \ + a^=b; diff --git a/libs/openssl/crypto/rc5/rc5_skey.c b/libs/openssl/crypto/rc5/rc5_skey.c new file mode 100644 index 00000000..5dd4a527 --- /dev/null +++ b/libs/openssl/crypto/rc5/rc5_skey.c @@ -0,0 +1,110 @@ +/* crypto/rc5/rc5_skey.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rc5_locl.h" + +void RC5_32_set_key(RC5_32_KEY *key, int len, const unsigned char *data, + int rounds) +{ + RC5_32_INT L[64], l, ll, A, B, *S, k; + int i, j, m, c, t, ii, jj; + + if ((rounds != RC5_16_ROUNDS) && + (rounds != RC5_12_ROUNDS) && (rounds != RC5_8_ROUNDS)) + rounds = RC5_16_ROUNDS; + + key->rounds = rounds; + S = &(key->data[0]); + j = 0; + for (i = 0; i <= (len - 8); i += 8) { + c2l(data, l); + L[j++] = l; + c2l(data, l); + L[j++] = l; + } + ii = len - i; + if (ii) { + k = len & 0x07; + c2ln(data, l, ll, k); + L[j + 0] = l; + L[j + 1] = ll; + } + + c = (len + 3) / 4; + t = (rounds + 1) * 2; + S[0] = RC5_32_P; + for (i = 1; i < t; i++) + S[i] = (S[i - 1] + RC5_32_Q) & RC5_32_MASK; + + j = (t > c) ? t : c; + j *= 3; + ii = jj = 0; + A = B = 0; + for (i = 0; i < j; i++) { + k = (S[ii] + A + B) & RC5_32_MASK; + A = S[ii] = ROTATE_l32(k, 3); + m = (int)(A + B); + k = (L[jj] + A + B) & RC5_32_MASK; + B = L[jj] = ROTATE_l32(k, m); + if (++ii >= t) + ii = 0; + if (++jj >= c) + jj = 0; + } +} diff --git a/libs/openssl/crypto/rc5/rc5cfb64.c b/libs/openssl/crypto/rc5/rc5cfb64.c new file mode 100644 index 00000000..a3813e03 --- /dev/null +++ b/libs/openssl/crypto/rc5/rc5cfb64.c @@ -0,0 +1,123 @@ +/* crypto/rc5/rc5cfb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rc5_locl.h" + +/* + * The input and output encrypted as though 64bit cfb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ + +void RC5_32_cfb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *schedule, + unsigned char *ivec, int *num, int encrypt) +{ + register unsigned long v0, v1, t; + register int n = *num; + register long l = length; + unsigned long ti[2]; + unsigned char *iv, c, cc; + + iv = (unsigned char *)ivec; + if (encrypt) { + while (l--) { + if (n == 0) { + c2l(iv, v0); + ti[0] = v0; + c2l(iv, v1); + ti[1] = v1; + RC5_32_encrypt((unsigned long *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2c(t, iv); + t = ti[1]; + l2c(t, iv); + iv = (unsigned char *)ivec; + } + c = *(in++) ^ iv[n]; + *(out++) = c; + iv[n] = c; + n = (n + 1) & 0x07; + } + } else { + while (l--) { + if (n == 0) { + c2l(iv, v0); + ti[0] = v0; + c2l(iv, v1); + ti[1] = v1; + RC5_32_encrypt((unsigned long *)ti, schedule); + iv = (unsigned char *)ivec; + t = ti[0]; + l2c(t, iv); + t = ti[1]; + l2c(t, iv); + iv = (unsigned char *)ivec; + } + cc = *(in++); + c = iv[n]; + iv[n] = cc; + *(out++) = c ^ cc; + n = (n + 1) & 0x07; + } + } + v0 = v1 = ti[0] = ti[1] = t = c = cc = 0; + *num = n; +} diff --git a/libs/openssl/crypto/rc5/rc5ofb64.c b/libs/openssl/crypto/rc5/rc5ofb64.c new file mode 100644 index 00000000..d3c63067 --- /dev/null +++ b/libs/openssl/crypto/rc5/rc5ofb64.c @@ -0,0 +1,110 @@ +/* crypto/rc5/rc5ofb64.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rc5_locl.h" + +/* + * The input and output encrypted as though 64bit ofb mode is being used. + * The extra state information to record how much of the 64bit block we have + * used is contained in *num; + */ +void RC5_32_ofb64_encrypt(const unsigned char *in, unsigned char *out, + long length, RC5_32_KEY *schedule, + unsigned char *ivec, int *num) +{ + register unsigned long v0, v1, t; + register int n = *num; + register long l = length; + unsigned char d[8]; + register char *dp; + unsigned long ti[2]; + unsigned char *iv; + int save = 0; + + iv = (unsigned char *)ivec; + c2l(iv, v0); + c2l(iv, v1); + ti[0] = v0; + ti[1] = v1; + dp = (char *)d; + l2c(v0, dp); + l2c(v1, dp); + while (l--) { + if (n == 0) { + RC5_32_encrypt((unsigned long *)ti, schedule); + dp = (char *)d; + t = ti[0]; + l2c(t, dp); + t = ti[1]; + l2c(t, dp); + save++; + } + *(out++) = *(in++) ^ d[n]; + n = (n + 1) & 0x07; + } + if (save) { + v0 = ti[0]; + v1 = ti[1]; + iv = (unsigned char *)ivec; + l2c(v0, iv); + l2c(v1, iv); + } + t = v0 = v1 = ti[0] = ti[1] = 0; + *num = n; +} diff --git a/libs/openssl/crypto/rc5/rc5s.cpp b/libs/openssl/crypto/rc5/rc5s.cpp new file mode 100644 index 00000000..1c5518bc --- /dev/null +++ b/libs/openssl/crypto/rc5/rc5s.cpp @@ -0,0 +1,70 @@ +// +// gettsc.inl +// +// gives access to the Pentium's (secret) cycle counter +// +// This software was written by Leonard Janke (janke@unixg.ubc.ca) +// in 1996-7 and is entered, by him, into the public domain. + +#if defined(__WATCOMC__) +void GetTSC(unsigned long&); +#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax]; +#elif defined(__GNUC__) +inline +void GetTSC(unsigned long& tsc) +{ + asm volatile(".byte 15, 49\n\t" + : "=eax" (tsc) + : + : "%edx", "%eax"); +} +#elif defined(_MSC_VER) +inline +void GetTSC(unsigned long& tsc) +{ + unsigned long a; + __asm _emit 0fh + __asm _emit 31h + __asm mov a, eax; + tsc=a; +} +#endif + +#include +#include +#include + +void main(int argc,char *argv[]) + { + RC5_32_KEY key; + unsigned long s1,s2,e1,e2; + unsigned long data[2]; + int i,j; + static unsigned char d[16]={0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF}; + + RC5_32_set_key(&key, 16,d,12); + + for (j=0; j<6; j++) + { + for (i=0; i<1000; i++) /**/ + { + RC5_32_encrypt(&data[0],&key); + GetTSC(s1); + RC5_32_encrypt(&data[0],&key); + RC5_32_encrypt(&data[0],&key); + RC5_32_encrypt(&data[0],&key); + GetTSC(e1); + GetTSC(s2); + RC5_32_encrypt(&data[0],&key); + RC5_32_encrypt(&data[0],&key); + RC5_32_encrypt(&data[0],&key); + RC5_32_encrypt(&data[0],&key); + GetTSC(e2); + RC5_32_encrypt(&data[0],&key); + } + + printf("cast %d %d (%d)\n", + e1-s1,e2-s2,((e2-s2)-(e1-s1))); + } + } + diff --git a/libs/openssl/crypto/rc5/rc5speed.c b/libs/openssl/crypto/rc5/rc5speed.c new file mode 100644 index 00000000..3f595704 --- /dev/null +++ b/libs/openssl/crypto/rc5/rc5speed.c @@ -0,0 +1,265 @@ +/* crypto/rc5/rc5speed.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* 11-Sep-92 Andrew Daviel Support for Silicon Graphics IRIX added */ +/* 06-Apr-92 Luke Brennan Support for VMS and add extra signal calls */ + +#if !defined(OPENSSL_SYS_MSDOS) && (!defined(OPENSSL_SYS_VMS) || defined(__DECC)) && !defined(OPENSSL_SYS_MACOSX) +# define TIMES +#endif + +#include + +#include +#include OPENSSL_UNISTD_IO +OPENSSL_DECLARE_EXIT +#ifndef OPENSSL_SYS_NETWARE +# include +#endif +#ifndef _IRIX +# include +#endif +#ifdef TIMES +# include +# include +#endif + /* + * Depending on the VMS version, the tms structure is perhaps defined. + * The __TMS macro will show if it was. If it wasn't defined, we should + * undefine TIMES, since that tells the rest of the program how things + * should be handled. -- Richard Levitte + */ +#if defined(OPENSSL_SYS_VMS_DECC) && !defined(__TMS) +# undef TIMES +#endif +#ifndef TIMES +# include +#endif +#if defined(sun) || defined(__ultrix) +# define _POSIX_SOURCE +# include +# include +#endif +#include +/* The following if from times(3) man page. It may need to be changed */ +#ifndef HZ +# ifndef CLK_TCK +# define HZ 100.0 +# else /* CLK_TCK */ +# define HZ ((double)CLK_TCK) +# endif +#endif +#define BUFSIZE ((long)1024) +long run = 0; + +double Time_F(int s); +#ifdef SIGALRM +# if defined(__STDC__) || defined(sgi) || defined(_AIX) +# define SIGRETTYPE void +# else +# define SIGRETTYPE int +# endif + +SIGRETTYPE sig_done(int sig); +SIGRETTYPE sig_done(int sig) +{ + signal(SIGALRM, sig_done); + run = 0; +# ifdef LINT + sig = sig; +# endif +} +#endif + +#define START 0 +#define STOP 1 + +double Time_F(int s) +{ + double ret; +#ifdef TIMES + static struct tms tstart, tend; + + if (s == START) { + times(&tstart); + return (0); + } else { + times(&tend); + ret = ((double)(tend.tms_utime - tstart.tms_utime)) / HZ; + return ((ret == 0.0) ? 1e-6 : ret); + } +#else /* !times() */ + static struct timeb tstart, tend; + long i; + + if (s == START) { + ftime(&tstart); + return (0); + } else { + ftime(&tend); + i = (long)tend.millitm - (long)tstart.millitm; + ret = ((double)(tend.time - tstart.time)) + ((double)i) / 1e3; + return ((ret == 0.0) ? 1e-6 : ret); + } +#endif +} + +int main(int argc, char **argv) +{ + long count; + static unsigned char buf[BUFSIZE]; + static unsigned char key[] = { + 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0, + 0xfe, 0xdc, 0xba, 0x98, 0x76, 0x54, 0x32, 0x10, + }; + RC5_32_KEY sch; + double a, b, c, d; +#ifndef SIGALRM + long ca, cb, cc; +#endif + +#ifndef TIMES + printf("To get the most accurate results, try to run this\n"); + printf("program when this computer is idle.\n"); +#endif + +#ifndef SIGALRM + printf("First we calculate the approximate speed ...\n"); + RC5_32_set_key(&sch, 16, key, 12); + count = 10; + do { + long i; + unsigned long data[2]; + + count *= 2; + Time_F(START); + for (i = count; i; i--) + RC5_32_encrypt(data, &sch); + d = Time_F(STOP); + } while (d < 3.0); + ca = count / 512; + cb = count; + cc = count * 8 / BUFSIZE + 1; + printf("Doing RC5_32_set_key %ld times\n", ca); +# define COND(d) (count != (d)) +# define COUNT(d) (d) +#else +# define COND(c) (run) +# define COUNT(d) (count) + signal(SIGALRM, sig_done); + printf("Doing RC5_32_set_key for 10 seconds\n"); + alarm(10); +#endif + + Time_F(START); + for (count = 0, run = 1; COND(ca); count += 4) { + RC5_32_set_key(&sch, 16, key, 12); + RC5_32_set_key(&sch, 16, key, 12); + RC5_32_set_key(&sch, 16, key, 12); + RC5_32_set_key(&sch, 16, key, 12); + } + d = Time_F(STOP); + printf("%ld RC5_32_set_key's in %.2f seconds\n", count, d); + a = ((double)COUNT(ca)) / d; + +#ifdef SIGALRM + printf("Doing RC5_32_encrypt's for 10 seconds\n"); + alarm(10); +#else + printf("Doing RC5_32_encrypt %ld times\n", cb); +#endif + Time_F(START); + for (count = 0, run = 1; COND(cb); count += 4) { + unsigned long data[2]; + + RC5_32_encrypt(data, &sch); + RC5_32_encrypt(data, &sch); + RC5_32_encrypt(data, &sch); + RC5_32_encrypt(data, &sch); + } + d = Time_F(STOP); + printf("%ld RC5_32_encrypt's in %.2f second\n", count, d); + b = ((double)COUNT(cb) * 8) / d; + +#ifdef SIGALRM + printf("Doing RC5_32_cbc_encrypt on %ld byte blocks for 10 seconds\n", + BUFSIZE); + alarm(10); +#else + printf("Doing RC5_32_cbc_encrypt %ld times on %ld byte blocks\n", cc, + BUFSIZE); +#endif + Time_F(START); + for (count = 0, run = 1; COND(cc); count++) + RC5_32_cbc_encrypt(buf, buf, BUFSIZE, &sch, &(key[0]), RC5_ENCRYPT); + d = Time_F(STOP); + printf("%ld RC5_32_cbc_encrypt's of %ld byte blocks in %.2f second\n", + count, BUFSIZE, d); + c = ((double)COUNT(cc) * BUFSIZE) / d; + + printf("RC5_32/12/16 set_key per sec = %12.2f (%9.3fuS)\n", a, + 1.0e6 / a); + printf("RC5_32/12/16 raw ecb bytes per sec = %12.2f (%9.3fuS)\n", b, + 8.0e6 / b); + printf("RC5_32/12/16 cbc bytes per sec = %12.2f (%9.3fuS)\n", c, + 8.0e6 / c); + exit(0); +#if defined(LINT) || defined(OPENSSL_SYS_MSDOS) + return (0); +#endif +} diff --git a/libs/openssl/crypto/rc5/rc5test.c b/libs/openssl/crypto/rc5/rc5test.c new file mode 100644 index 00000000..b29a436c --- /dev/null +++ b/libs/openssl/crypto/rc5/rc5test.c @@ -0,0 +1,381 @@ +/* crypto/rc5/rc5test.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * This has been a quickly hacked 'ideatest.c'. When I add tests for other + * RC5 modes, more of the code will be uncommented. + */ + +#include +#include +#include + +#include "../e_os.h" + +#ifdef OPENSSL_NO_RC5 +int main(int argc, char *argv[]) +{ + printf("No RC5 support\n"); + return (0); +} +#else +# include + +static unsigned char RC5key[5][16] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x91, 0x5f, 0x46, 0x19, 0xbe, 0x41, 0xb2, 0x51, + 0x63, 0x55, 0xa5, 0x01, 0x10, 0xa9, 0xce, 0x91}, + {0x78, 0x33, 0x48, 0xe7, 0x5a, 0xeb, 0x0f, 0x2f, + 0xd7, 0xb1, 0x69, 0xbb, 0x8d, 0xc1, 0x67, 0x87}, + {0xdc, 0x49, 0xdb, 0x13, 0x75, 0xa5, 0x58, 0x4f, + 0x64, 0x85, 0xb4, 0x13, 0xb5, 0xf1, 0x2b, 0xaf}, + {0x52, 0x69, 0xf1, 0x49, 0xd4, 0x1b, 0xa0, 0x15, + 0x24, 0x97, 0x57, 0x4d, 0x7f, 0x15, 0x31, 0x25}, +}; + +static unsigned char RC5plain[5][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x21, 0xA5, 0xDB, 0xEE, 0x15, 0x4B, 0x8F, 0x6D}, + {0xF7, 0xC0, 0x13, 0xAC, 0x5B, 0x2B, 0x89, 0x52}, + {0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92}, + {0x65, 0xC1, 0x78, 0xB2, 0x84, 0xD1, 0x97, 0xCC}, +}; + +static unsigned char RC5cipher[5][8] = { + {0x21, 0xA5, 0xDB, 0xEE, 0x15, 0x4B, 0x8F, 0x6D}, + {0xF7, 0xC0, 0x13, 0xAC, 0x5B, 0x2B, 0x89, 0x52}, + {0x2F, 0x42, 0xB3, 0xB7, 0x03, 0x69, 0xFC, 0x92}, + {0x65, 0xC1, 0x78, 0xB2, 0x84, 0xD1, 0x97, 0xCC}, + {0xEB, 0x44, 0xE4, 0x15, 0xDA, 0x31, 0x98, 0x24}, +}; + +# define RC5_CBC_NUM 27 +static unsigned char rc5_cbc_cipher[RC5_CBC_NUM][8] = { + {0x7a, 0x7b, 0xba, 0x4d, 0x79, 0x11, 0x1d, 0x1e}, + {0x79, 0x7b, 0xba, 0x4d, 0x78, 0x11, 0x1d, 0x1e}, + {0x7a, 0x7b, 0xba, 0x4d, 0x79, 0x11, 0x1d, 0x1f}, + {0x7a, 0x7b, 0xba, 0x4d, 0x79, 0x11, 0x1d, 0x1f}, + {0x8b, 0x9d, 0xed, 0x91, 0xce, 0x77, 0x94, 0xa6}, + {0x2f, 0x75, 0x9f, 0xe7, 0xad, 0x86, 0xa3, 0x78}, + {0xdc, 0xa2, 0x69, 0x4b, 0xf4, 0x0e, 0x07, 0x88}, + {0xdc, 0xa2, 0x69, 0x4b, 0xf4, 0x0e, 0x07, 0x88}, + {0xdc, 0xfe, 0x09, 0x85, 0x77, 0xec, 0xa5, 0xff}, + {0x96, 0x46, 0xfb, 0x77, 0x63, 0x8f, 0x9c, 0xa8}, + {0xb2, 0xb3, 0x20, 0x9d, 0xb6, 0x59, 0x4d, 0xa4}, + {0x54, 0x5f, 0x7f, 0x32, 0xa5, 0xfc, 0x38, 0x36}, + {0x82, 0x85, 0xe7, 0xc1, 0xb5, 0xbc, 0x74, 0x02}, + {0xfc, 0x58, 0x6f, 0x92, 0xf7, 0x08, 0x09, 0x34}, + {0xcf, 0x27, 0x0e, 0xf9, 0x71, 0x7f, 0xf7, 0xc4}, + {0xe4, 0x93, 0xf1, 0xc1, 0xbb, 0x4d, 0x6e, 0x8c}, + {0x5c, 0x4c, 0x04, 0x1e, 0x0f, 0x21, 0x7a, 0xc3}, + {0x92, 0x1f, 0x12, 0x48, 0x53, 0x73, 0xb4, 0xf7}, + {0x5b, 0xa0, 0xca, 0x6b, 0xbe, 0x7f, 0x5f, 0xad}, + {0xc5, 0x33, 0x77, 0x1c, 0xd0, 0x11, 0x0e, 0x63}, + {0x29, 0x4d, 0xdb, 0x46, 0xb3, 0x27, 0x8d, 0x60}, + {0xda, 0xd6, 0xbd, 0xa9, 0xdf, 0xe8, 0xf7, 0xe8}, + {0x97, 0xe0, 0x78, 0x78, 0x37, 0xed, 0x31, 0x7f}, + {0x78, 0x75, 0xdb, 0xf6, 0x73, 0x8c, 0x64, 0x78}, + {0x8f, 0x34, 0xc3, 0xc6, 0x81, 0xc9, 0x96, 0x95}, + {0x7c, 0xb3, 0xf1, 0xdf, 0x34, 0xf9, 0x48, 0x11}, + {0x7f, 0xd1, 0xa0, 0x23, 0xa5, 0xbb, 0xa2, 0x17}, +}; + +static unsigned char rc5_cbc_key[RC5_CBC_NUM][17] = { + {1, 0x00}, + {1, 0x00}, + {1, 0x00}, + {1, 0x00}, + {1, 0x00}, + {1, 0x11}, + {1, 0x00}, + {4, 0x00, 0x00, 0x00, 0x00}, + {1, 0x00}, + {1, 0x00}, + {1, 0x00}, + {1, 0x00}, + {4, 0x01, 0x02, 0x03, 0x04}, + {4, 0x01, 0x02, 0x03, 0x04}, + {4, 0x01, 0x02, 0x03, 0x04}, + {8, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + {8, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + {8, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + {8, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + {16, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}, + {16, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}, + {16, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, + 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}, + {5, 0x01, 0x02, 0x03, 0x04, 0x05}, + {5, 0x01, 0x02, 0x03, 0x04, 0x05}, + {5, 0x01, 0x02, 0x03, 0x04, 0x05}, + {5, 0x01, 0x02, 0x03, 0x04, 0x05}, + {5, 0x01, 0x02, 0x03, 0x04, 0x05}, +}; + +static unsigned char rc5_cbc_plain[RC5_CBC_NUM][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}, + {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}, + {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}, + {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}, + {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}, + {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}, + {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}, + {0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x80}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, + {0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x01}, +}; + +static int rc5_cbc_rounds[RC5_CBC_NUM] = { + 0, 0, 0, 0, 0, 1, 2, 2, + 8, 8, 12, 16, 8, 12, 16, 12, + 8, 12, 16, 8, 12, 16, 12, 8, + 8, 8, 8, +}; + +static unsigned char rc5_cbc_iv[RC5_CBC_NUM][8] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x78, 0x75, 0xdb, 0xf6, 0x73, 0x8c, 0x64, 0x78}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x7c, 0xb3, 0xf1, 0xdf, 0x34, 0xf9, 0x48, 0x11}, +}; + +int main(int argc, char *argv[]) +{ + int i, n, err = 0; + RC5_32_KEY key; + unsigned char buf[8], buf2[8], ivb[8]; + + for (n = 0; n < 5; n++) { + RC5_32_set_key(&key, 16, &(RC5key[n][0]), 12); + + RC5_32_ecb_encrypt(&(RC5plain[n][0]), buf, &key, RC5_ENCRYPT); + if (memcmp(&(RC5cipher[n][0]), buf, 8) != 0) { + printf("ecb RC5 error encrypting (%d)\n", n + 1); + printf("got :"); + for (i = 0; i < 8; i++) + printf("%02X ", buf[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 8; i++) + printf("%02X ", RC5cipher[n][i]); + err = 20; + printf("\n"); + } + + RC5_32_ecb_encrypt(buf, buf2, &key, RC5_DECRYPT); + if (memcmp(&(RC5plain[n][0]), buf2, 8) != 0) { + printf("ecb RC5 error decrypting (%d)\n", n + 1); + printf("got :"); + for (i = 0; i < 8; i++) + printf("%02X ", buf2[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 8; i++) + printf("%02X ", RC5plain[n][i]); + printf("\n"); + err = 3; + } + } + if (err == 0) + printf("ecb RC5 ok\n"); + + for (n = 0; n < RC5_CBC_NUM; n++) { + i = rc5_cbc_rounds[n]; + if (i < 8) + continue; + + RC5_32_set_key(&key, rc5_cbc_key[n][0], &(rc5_cbc_key[n][1]), i); + + memcpy(ivb, &(rc5_cbc_iv[n][0]), 8); + RC5_32_cbc_encrypt(&(rc5_cbc_plain[n][0]), buf, 8, + &key, &(ivb[0]), RC5_ENCRYPT); + + if (memcmp(&(rc5_cbc_cipher[n][0]), buf, 8) != 0) { + printf("cbc RC5 error encrypting (%d)\n", n + 1); + printf("got :"); + for (i = 0; i < 8; i++) + printf("%02X ", buf[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 8; i++) + printf("%02X ", rc5_cbc_cipher[n][i]); + err = 30; + printf("\n"); + } + + memcpy(ivb, &(rc5_cbc_iv[n][0]), 8); + RC5_32_cbc_encrypt(buf, buf2, 8, &key, &(ivb[0]), RC5_DECRYPT); + if (memcmp(&(rc5_cbc_plain[n][0]), buf2, 8) != 0) { + printf("cbc RC5 error decrypting (%d)\n", n + 1); + printf("got :"); + for (i = 0; i < 8; i++) + printf("%02X ", buf2[i]); + printf("\n"); + printf("expected:"); + for (i = 0; i < 8; i++) + printf("%02X ", rc5_cbc_plain[n][i]); + printf("\n"); + err = 3; + } + } + if (err == 0) + printf("cbc RC5 ok\n"); + + EXIT(err); + return (err); +} + +# ifdef undef +static int cfb64_test(unsigned char *cfb_cipher) +{ + IDEA_KEY_SCHEDULE eks, dks; + int err = 0, i, n; + + idea_set_encrypt_key(cfb_key, &eks); + idea_set_decrypt_key(&eks, &dks); + memcpy(cfb_tmp, cfb_iv, 8); + n = 0; + idea_cfb64_encrypt(plain, cfb_buf1, (long)12, &eks, + cfb_tmp, &n, IDEA_ENCRYPT); + idea_cfb64_encrypt(&(plain[12]), &(cfb_buf1[12]), + (long)CFB_TEST_SIZE - 12, &eks, + cfb_tmp, &n, IDEA_ENCRYPT); + if (memcmp(cfb_cipher, cfb_buf1, CFB_TEST_SIZE) != 0) { + err = 1; + printf("idea_cfb64_encrypt encrypt error\n"); + for (i = 0; i < CFB_TEST_SIZE; i += 8) + printf("%s\n", pt(&(cfb_buf1[i]))); + } + memcpy(cfb_tmp, cfb_iv, 8); + n = 0; + idea_cfb64_encrypt(cfb_buf1, cfb_buf2, (long)17, &eks, + cfb_tmp, &n, IDEA_DECRYPT); + idea_cfb64_encrypt(&(cfb_buf1[17]), &(cfb_buf2[17]), + (long)CFB_TEST_SIZE - 17, &dks, + cfb_tmp, &n, IDEA_DECRYPT); + if (memcmp(plain, cfb_buf2, CFB_TEST_SIZE) != 0) { + err = 1; + printf("idea_cfb_encrypt decrypt error\n"); + for (i = 0; i < 24; i += 8) + printf("%s\n", pt(&(cfb_buf2[i]))); + } + return (err); +} + +static char *pt(unsigned char *p) +{ + static char bufs[10][20]; + static int bnum = 0; + char *ret; + int i; + static char *f = "0123456789ABCDEF"; + + ret = &(bufs[bnum++][0]); + bnum %= 10; + for (i = 0; i < 8; i++) { + ret[i * 2] = f[(p[i] >> 4) & 0xf]; + ret[i * 2 + 1] = f[p[i] & 0xf]; + } + ret[16] = '\0'; + return (ret); +} + +# endif +#endif diff --git a/libs/openssl/crypto/ripemd/README b/libs/openssl/crypto/ripemd/README new file mode 100644 index 00000000..f1ffc8b1 --- /dev/null +++ b/libs/openssl/crypto/ripemd/README @@ -0,0 +1,15 @@ +RIPEMD-160 +http://www.esat.kuleuven.ac.be/~bosselae/ripemd160.html + +This is my implementation of RIPEMD-160. The pentium assember is a little +off the pace since I only get 1050 cycles, while the best is 1013. +I have a few ideas for how to get another 20 or so cycles, but at +this point I will not bother right now. I believe the trick will be +to remove my 'copy X array onto stack' until inside the RIP1() finctions the +first time round. To do this I need another register and will only have one +temporary one. A bit tricky.... I can also cleanup the saving of the 5 words +after the first half of the calculation. I should read the origional +value, add then write. Currently I just save the new and read the origioal. +I then read both at the end. Bad. + +eric (20-Jan-1998) diff --git a/libs/openssl/crypto/ripemd/asm/rips.cpp b/libs/openssl/crypto/ripemd/asm/rips.cpp new file mode 100644 index 00000000..f7a13677 --- /dev/null +++ b/libs/openssl/crypto/ripemd/asm/rips.cpp @@ -0,0 +1,82 @@ +// +// gettsc.inl +// +// gives access to the Pentium's (secret) cycle counter +// +// This software was written by Leonard Janke (janke@unixg.ubc.ca) +// in 1996-7 and is entered, by him, into the public domain. + +#if defined(__WATCOMC__) +void GetTSC(unsigned long&); +#pragma aux GetTSC = 0x0f 0x31 "mov [edi], eax" parm [edi] modify [edx eax]; +#elif defined(__GNUC__) +inline +void GetTSC(unsigned long& tsc) +{ + asm volatile(".byte 15, 49\n\t" + : "=eax" (tsc) + : + : "%edx", "%eax"); +} +#elif defined(_MSC_VER) +inline +void GetTSC(unsigned long& tsc) +{ + unsigned long a; + __asm _emit 0fh + __asm _emit 31h + __asm mov a, eax; + tsc=a; +} +#endif + +#include +#include +#include + +#define ripemd160_block_x86 ripemd160_block_asm_host_order + +extern "C" { +void ripemd160_block_x86(RIPEMD160_CTX *ctx, unsigned char *buffer,int num); +} + +void main(int argc,char *argv[]) + { + unsigned char buffer[64*256]; + RIPEMD160_CTX ctx; + unsigned long s1,s2,e1,e2; + unsigned char k[16]; + unsigned long data[2]; + unsigned char iv[8]; + int i,num=0,numm; + int j=0; + + if (argc >= 2) + num=atoi(argv[1]); + + if (num == 0) num=16; + if (num > 250) num=16; + numm=num+2; +#if 0 + num*=64; + numm*=64; +#endif + + for (j=0; j<6; j++) + { + for (i=0; i<10; i++) /**/ + { + ripemd160_block_x86(&ctx,buffer,numm); + GetTSC(s1); + ripemd160_block_x86(&ctx,buffer,numm); + GetTSC(e1); + GetTSC(s2); + ripemd160_block_x86(&ctx,buffer,num); + GetTSC(e2); + ripemd160_block_x86(&ctx,buffer,num); + } + printf("ripemd160 (%d bytes) %d %d (%.2f)\n",num*64, + e1-s1,e2-s2,(double)((e1-s1)-(e2-s2))/2); + } + } + diff --git a/libs/openssl/crypto/ripemd/asm/rmd-586.pl b/libs/openssl/crypto/ripemd/asm/rmd-586.pl new file mode 100644 index 00000000..e8b2bc2d --- /dev/null +++ b/libs/openssl/crypto/ripemd/asm/rmd-586.pl @@ -0,0 +1,591 @@ +#!/usr/local/bin/perl + +# Normal is the +# ripemd160_block_asm_data_order(RIPEMD160_CTX *c, ULONG *X,int blocks); + +$normal=0; + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],$0); + +$A="ecx"; +$B="esi"; +$C="edi"; +$D="ebx"; +$E="ebp"; +$tmp1="eax"; +$tmp2="edx"; + +$KL1=0x5A827999; +$KL2=0x6ED9EBA1; +$KL3=0x8F1BBCDC; +$KL4=0xA953FD4E; +$KR0=0x50A28BE6; +$KR1=0x5C4DD124; +$KR2=0x6D703EF3; +$KR3=0x7A6D76E9; + + +@wl=( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, + 7, 4,13, 1,10, 6,15, 3,12, 0, 9, 5, 2,14,11, 8, + 3,10,14, 4, 9,15, 8, 1, 2, 7, 0, 6,13,11, 5,12, + 1, 9,11,10, 0, 8,12, 4,13, 3, 7,15,14, 5, 6, 2, + 4, 0, 5, 9, 7,12, 2,10,14, 1, 3, 8,11, 6,15,13, + ); + +@wr=( 5,14, 7, 0, 9, 2,11, 4,13, 6,15, 8, 1,10, 3,12, + 6,11, 3, 7, 0,13, 5,10,14,15, 8,12, 4, 9, 1, 2, + 15, 5, 1, 3, 7,14, 6, 9,11, 8,12, 2,10, 0, 4,13, + 8, 6, 4, 1, 3,11,15, 0, 5,12, 2,13, 9, 7,10,14, + 12,15,10, 4, 1, 5, 8, 7, 6, 2,13,14, 0, 3, 9,11, + ); + +@sl=( 11,14,15,12, 5, 8, 7, 9,11,13,14,15, 6, 7, 9, 8, + 7, 6, 8,13,11, 9, 7,15, 7,12,15, 9,11, 7,13,12, + 11,13, 6, 7,14, 9,13,15,14, 8,13, 6, 5,12, 7, 5, + 11,12,14,15,14,15, 9, 8, 9,14, 5, 6, 8, 6, 5,12, + 9,15, 5,11, 6, 8,13,12, 5,12,13,14,11, 8, 5, 6, + ); + +@sr=( 8, 9, 9,11,13,15,15, 5, 7, 7, 8,11,14,14,12, 6, + 9,13,15, 7,12, 8, 9,11, 7, 7,12, 7, 6,15,13,11, + 9, 7,15,11, 8, 6, 6,14,12,13, 5,14,13,13, 7, 5, + 15, 5, 8,11,14,14, 6,14, 6, 9,12, 9,12, 5,15, 8, + 8, 5,12, 9,12, 5,14, 6, 8,13, 6, 5,15,13,11,11, + ); + +&ripemd160_block("ripemd160_block_asm_data_order"); +&asm_finish(); + +sub Xv + { + local($n)=@_; + return(&swtmp($n)); + # tmp on stack + } + +sub Np + { + local($p)=@_; + local(%n)=($A,$E,$B,$A,$C,$B,$D,$C,$E,$D); + return($n{$p}); + } + +sub RIP1 + { + local($a,$b,$c,$d,$e,$pos,$s,$o,$pos2)=@_; + + &comment($p++); + if ($p & 1) + { + #&mov($tmp1, $c) if $o == -1; + &xor($tmp1, $d) if $o == -1; + &mov($tmp2, &Xv($pos)); + &xor($tmp1, $b); + &add($a, $tmp2); + &rotl($c, 10); + &add($a, $tmp1); + &mov($tmp1, &Np($c)); # NEXT + # XXX + &rotl($a, $s); + &add($a, $e); + } + else + { + &xor($tmp1, $d); + &mov($tmp2, &Xv($pos)); + &xor($tmp1, $b); + &add($a, $tmp1); + &mov($tmp1, &Np($c)) if $o <= 0; + &mov($tmp1, -1) if $o == 1; + # XXX if $o == 2; + &rotl($c, 10); + &add($a, $tmp2); + &xor($tmp1, &Np($d)) if $o <= 0; + &mov($tmp2, &Xv($pos2)) if $o == 1; + &mov($tmp2, &wparam(0)) if $o == 2; + &rotl($a, $s); + &add($a, $e); + } + } + +sub RIP2 + { + local($a,$b,$c,$d,$e,$pos,$pos2,$s,$K,$o)=@_; + +# XXXXXX + &comment($p++); + if ($p & 1) + { +# &mov($tmp2, &Xv($pos)) if $o < -1; +# &mov($tmp1, -1) if $o < -1; + + &add($a, $tmp2); + &mov($tmp2, $c); + &sub($tmp1, $b); + &and($tmp2, $b); + &and($tmp1, $d); + &or($tmp2, $tmp1); + &mov($tmp1, &Xv($pos2)) if $o <= 0; # XXXXXXXXXXXXXX + # XXX + &rotl($c, 10); + &lea($a, &DWP($K,$a,$tmp2,1)); + &mov($tmp2, -1) if $o <= 0; + # XXX + &rotl($a, $s); + &add($a, $e); + } + else + { + # XXX + &add($a, $tmp1); + &mov($tmp1, $c); + &sub($tmp2, $b); + &and($tmp1, $b); + &and($tmp2, $d); + if ($o != 2) + { + &or($tmp1, $tmp2); + &mov($tmp2, &Xv($pos2)) if $o <= 0; + &mov($tmp2, -1) if $o == 1; + &rotl($c, 10); + &lea($a, &DWP($K,$a,$tmp1,1)); + &mov($tmp1, -1) if $o <= 0; + &sub($tmp2, &Np($c)) if $o == 1; + } else { + &or($tmp2, $tmp1); + &mov($tmp1, &Np($c)); + &rotl($c, 10); + &lea($a, &DWP($K,$a,$tmp2,1)); + &xor($tmp1, &Np($d)); + } + &rotl($a, $s); + &add($a, $e); + } + } + +sub RIP3 + { + local($a,$b,$c,$d,$e,$pos,$s,$K,$o,$pos2)=@_; + + &comment($p++); + if ($p & 1) + { +# &mov($tmp2, -1) if $o < -1; +# &sub($tmp2, $c) if $o < -1; + &mov($tmp1, &Xv($pos)); + &or($tmp2, $b); + &add($a, $tmp1); + &xor($tmp2, $d); + &mov($tmp1, -1) if $o <= 0; # NEXT + # XXX + &rotl($c, 10); + &lea($a, &DWP($K,$a,$tmp2,1)); + &sub($tmp1, &Np($c)) if $o <= 0; # NEXT + # XXX + &rotl($a, $s); + &add($a, $e); + } + else + { + &mov($tmp2, &Xv($pos)); + &or($tmp1, $b); + &add($a, $tmp2); + &xor($tmp1, $d); + &mov($tmp2, -1) if $o <= 0; # NEXT + &mov($tmp2, -1) if $o == 1; + &mov($tmp2, &Xv($pos2)) if $o == 2; + &rotl($c, 10); + &lea($a, &DWP($K,$a,$tmp1,1)); + &sub($tmp2, &Np($c)) if $o <= 0; # NEXT + &mov($tmp1, &Np($d)) if $o == 1; + &mov($tmp1, -1) if $o == 2; + &rotl($a, $s); + &add($a, $e); + } + } + +sub RIP4 + { + local($a,$b,$c,$d,$e,$pos,$s,$K,$o)=@_; + + &comment($p++); + if ($p & 1) + { +# &mov($tmp2, -1) if $o == -2; +# &mov($tmp1, $d) if $o == -2; + &sub($tmp2, $d); + &and($tmp1, $b); + &and($tmp2, $c); + &or($tmp2, $tmp1); + &mov($tmp1, &Xv($pos)); + &rotl($c, 10); + &lea($a, &DWP($K,$a,$tmp2)); + &mov($tmp2, -1) unless $o > 0; # NEXT + # XXX + &add($a, $tmp1); + &mov($tmp1, &Np($d)) unless $o > 0; # NEXT + # XXX + &rotl($a, $s); + &add($a, $e); + } + else + { + &sub($tmp2, $d); + &and($tmp1, $b); + &and($tmp2, $c); + &or($tmp2, $tmp1); + &mov($tmp1, &Xv($pos)); + &rotl($c, 10); + &lea($a, &DWP($K,$a,$tmp2)); + &mov($tmp2, -1) if $o == 0; # NEXT + &mov($tmp2, -1) if $o == 1; + &mov($tmp2, -1) if $o == 2; + # XXX + &add($a, $tmp1); + &mov($tmp1, &Np($d)) if $o == 0; # NEXT + &sub($tmp2, &Np($d)) if $o == 1; + &sub($tmp2, &Np($c)) if $o == 2; + # XXX + &rotl($a, $s); + &add($a, $e); + } + } + +sub RIP5 + { + local($a,$b,$c,$d,$e,$pos,$s,$K,$o)=@_; + + &comment($p++); + if ($p & 1) + { + &mov($tmp2, -1) if $o == -2; + &sub($tmp2, $d) if $o == -2; + &mov($tmp1, &Xv($pos)); + &or($tmp2, $c); + &add($a, $tmp1); + &xor($tmp2, $b); + &mov($tmp1, -1) if $o <= 0; + # XXX + &rotl($c, 10); + &lea($a, &DWP($K,$a,$tmp2,1)); + &sub($tmp1, &Np($d)) if $o <= 0; + # XXX + &rotl($a, $s); + &add($a, $e); + } + else + { + &mov($tmp2, &Xv($pos)); + &or($tmp1, $c); + &add($a, $tmp2); + &xor($tmp1, $b); + &mov($tmp2, -1) if $o <= 0; + &mov($tmp2, &wparam(0)) if $o == 1; # Middle code + &mov($tmp2, -1) if $o == 2; + &rotl($c, 10); + &lea($a, &DWP($K,$a,$tmp1,1)); + &sub($tmp2, &Np($d)) if $o <= 0; + &mov(&swtmp(16), $A) if $o == 1; + &mov($tmp1, &Np($d)) if $o == 2; + &rotl($a, $s); + &add($a, $e); + } + } + +sub ripemd160_block + { + local($name)=@_; + + &function_begin_B($name,"",3); + + # parameter 1 is the RIPEMD160_CTX structure. + # A 0 + # B 4 + # C 8 + # D 12 + # E 16 + + &mov($tmp2, &wparam(0)); + &mov($tmp1, &wparam(1)); + &push("esi"); + &mov($A, &DWP( 0,$tmp2,"",0)); + &push("edi"); + &mov($B, &DWP( 4,$tmp2,"",0)); + &push("ebp"); + &mov($C, &DWP( 8,$tmp2,"",0)); + &push("ebx"); + &stack_push(16+5+6); + # Special comment about the figure of 6. + # Idea is to pad the current frame so + # that the top of the stack gets fairly + # aligned. Well, as you realize it would + # always depend on how the frame below is + # aligned. The good news are that gcc-2.95 + # and later does keep first argument at + # least double-wise aligned. + # + + &set_label("start") unless $normal; + &comment(""); + + # &mov($tmp1, &wparam(1)); # Done at end of loop + # &mov($tmp2, &wparam(0)); # Done at end of loop + + for ($z=0; $z<16; $z+=2) + { + &mov($D, &DWP( $z*4,$tmp1,"",0)); + &mov($E, &DWP( ($z+1)*4,$tmp1,"",0)); + &mov(&swtmp($z), $D); + &mov(&swtmp($z+1), $E); + } + &mov($tmp1, $C); + &mov($D, &DWP(12,$tmp2,"",0)); + &mov($E, &DWP(16,$tmp2,"",0)); + + &RIP1($A,$B,$C,$D,$E,$wl[ 0],$sl[ 0],-1); + &RIP1($E,$A,$B,$C,$D,$wl[ 1],$sl[ 1],0); + &RIP1($D,$E,$A,$B,$C,$wl[ 2],$sl[ 2],0); + &RIP1($C,$D,$E,$A,$B,$wl[ 3],$sl[ 3],0); + &RIP1($B,$C,$D,$E,$A,$wl[ 4],$sl[ 4],0); + &RIP1($A,$B,$C,$D,$E,$wl[ 5],$sl[ 5],0); + &RIP1($E,$A,$B,$C,$D,$wl[ 6],$sl[ 6],0); + &RIP1($D,$E,$A,$B,$C,$wl[ 7],$sl[ 7],0); + &RIP1($C,$D,$E,$A,$B,$wl[ 8],$sl[ 8],0); + &RIP1($B,$C,$D,$E,$A,$wl[ 9],$sl[ 9],0); + &RIP1($A,$B,$C,$D,$E,$wl[10],$sl[10],0); + &RIP1($E,$A,$B,$C,$D,$wl[11],$sl[11],0); + &RIP1($D,$E,$A,$B,$C,$wl[12],$sl[12],0); + &RIP1($C,$D,$E,$A,$B,$wl[13],$sl[13],0); + &RIP1($B,$C,$D,$E,$A,$wl[14],$sl[14],0); + &RIP1($A,$B,$C,$D,$E,$wl[15],$sl[15],1,$wl[16]); + + &RIP2($E,$A,$B,$C,$D,$wl[16],$wl[17],$sl[16],$KL1,-1); + &RIP2($D,$E,$A,$B,$C,$wl[17],$wl[18],$sl[17],$KL1,0); + &RIP2($C,$D,$E,$A,$B,$wl[18],$wl[19],$sl[18],$KL1,0); + &RIP2($B,$C,$D,$E,$A,$wl[19],$wl[20],$sl[19],$KL1,0); + &RIP2($A,$B,$C,$D,$E,$wl[20],$wl[21],$sl[20],$KL1,0); + &RIP2($E,$A,$B,$C,$D,$wl[21],$wl[22],$sl[21],$KL1,0); + &RIP2($D,$E,$A,$B,$C,$wl[22],$wl[23],$sl[22],$KL1,0); + &RIP2($C,$D,$E,$A,$B,$wl[23],$wl[24],$sl[23],$KL1,0); + &RIP2($B,$C,$D,$E,$A,$wl[24],$wl[25],$sl[24],$KL1,0); + &RIP2($A,$B,$C,$D,$E,$wl[25],$wl[26],$sl[25],$KL1,0); + &RIP2($E,$A,$B,$C,$D,$wl[26],$wl[27],$sl[26],$KL1,0); + &RIP2($D,$E,$A,$B,$C,$wl[27],$wl[28],$sl[27],$KL1,0); + &RIP2($C,$D,$E,$A,$B,$wl[28],$wl[29],$sl[28],$KL1,0); + &RIP2($B,$C,$D,$E,$A,$wl[29],$wl[30],$sl[29],$KL1,0); + &RIP2($A,$B,$C,$D,$E,$wl[30],$wl[31],$sl[30],$KL1,0); + &RIP2($E,$A,$B,$C,$D,$wl[31],$wl[32],$sl[31],$KL1,1); + + &RIP3($D,$E,$A,$B,$C,$wl[32],$sl[32],$KL2,-1); + &RIP3($C,$D,$E,$A,$B,$wl[33],$sl[33],$KL2,0); + &RIP3($B,$C,$D,$E,$A,$wl[34],$sl[34],$KL2,0); + &RIP3($A,$B,$C,$D,$E,$wl[35],$sl[35],$KL2,0); + &RIP3($E,$A,$B,$C,$D,$wl[36],$sl[36],$KL2,0); + &RIP3($D,$E,$A,$B,$C,$wl[37],$sl[37],$KL2,0); + &RIP3($C,$D,$E,$A,$B,$wl[38],$sl[38],$KL2,0); + &RIP3($B,$C,$D,$E,$A,$wl[39],$sl[39],$KL2,0); + &RIP3($A,$B,$C,$D,$E,$wl[40],$sl[40],$KL2,0); + &RIP3($E,$A,$B,$C,$D,$wl[41],$sl[41],$KL2,0); + &RIP3($D,$E,$A,$B,$C,$wl[42],$sl[42],$KL2,0); + &RIP3($C,$D,$E,$A,$B,$wl[43],$sl[43],$KL2,0); + &RIP3($B,$C,$D,$E,$A,$wl[44],$sl[44],$KL2,0); + &RIP3($A,$B,$C,$D,$E,$wl[45],$sl[45],$KL2,0); + &RIP3($E,$A,$B,$C,$D,$wl[46],$sl[46],$KL2,0); + &RIP3($D,$E,$A,$B,$C,$wl[47],$sl[47],$KL2,1); + + &RIP4($C,$D,$E,$A,$B,$wl[48],$sl[48],$KL3,-1); + &RIP4($B,$C,$D,$E,$A,$wl[49],$sl[49],$KL3,0); + &RIP4($A,$B,$C,$D,$E,$wl[50],$sl[50],$KL3,0); + &RIP4($E,$A,$B,$C,$D,$wl[51],$sl[51],$KL3,0); + &RIP4($D,$E,$A,$B,$C,$wl[52],$sl[52],$KL3,0); + &RIP4($C,$D,$E,$A,$B,$wl[53],$sl[53],$KL3,0); + &RIP4($B,$C,$D,$E,$A,$wl[54],$sl[54],$KL3,0); + &RIP4($A,$B,$C,$D,$E,$wl[55],$sl[55],$KL3,0); + &RIP4($E,$A,$B,$C,$D,$wl[56],$sl[56],$KL3,0); + &RIP4($D,$E,$A,$B,$C,$wl[57],$sl[57],$KL3,0); + &RIP4($C,$D,$E,$A,$B,$wl[58],$sl[58],$KL3,0); + &RIP4($B,$C,$D,$E,$A,$wl[59],$sl[59],$KL3,0); + &RIP4($A,$B,$C,$D,$E,$wl[60],$sl[60],$KL3,0); + &RIP4($E,$A,$B,$C,$D,$wl[61],$sl[61],$KL3,0); + &RIP4($D,$E,$A,$B,$C,$wl[62],$sl[62],$KL3,0); + &RIP4($C,$D,$E,$A,$B,$wl[63],$sl[63],$KL3,1); + + &RIP5($B,$C,$D,$E,$A,$wl[64],$sl[64],$KL4,-1); + &RIP5($A,$B,$C,$D,$E,$wl[65],$sl[65],$KL4,0); + &RIP5($E,$A,$B,$C,$D,$wl[66],$sl[66],$KL4,0); + &RIP5($D,$E,$A,$B,$C,$wl[67],$sl[67],$KL4,0); + &RIP5($C,$D,$E,$A,$B,$wl[68],$sl[68],$KL4,0); + &RIP5($B,$C,$D,$E,$A,$wl[69],$sl[69],$KL4,0); + &RIP5($A,$B,$C,$D,$E,$wl[70],$sl[70],$KL4,0); + &RIP5($E,$A,$B,$C,$D,$wl[71],$sl[71],$KL4,0); + &RIP5($D,$E,$A,$B,$C,$wl[72],$sl[72],$KL4,0); + &RIP5($C,$D,$E,$A,$B,$wl[73],$sl[73],$KL4,0); + &RIP5($B,$C,$D,$E,$A,$wl[74],$sl[74],$KL4,0); + &RIP5($A,$B,$C,$D,$E,$wl[75],$sl[75],$KL4,0); + &RIP5($E,$A,$B,$C,$D,$wl[76],$sl[76],$KL4,0); + &RIP5($D,$E,$A,$B,$C,$wl[77],$sl[77],$KL4,0); + &RIP5($C,$D,$E,$A,$B,$wl[78],$sl[78],$KL4,0); + &RIP5($B,$C,$D,$E,$A,$wl[79],$sl[79],$KL4,1); + + # &mov($tmp2, &wparam(0)); # moved into last RIP5 + # &mov(&swtmp(16), $A); + &mov($A, &DWP( 0,$tmp2,"",0)); + &mov(&swtmp(16+1), $B); + &mov(&swtmp(16+2), $C); + &mov($B, &DWP( 4,$tmp2,"",0)); + &mov(&swtmp(16+3), $D); + &mov($C, &DWP( 8,$tmp2,"",0)); + &mov(&swtmp(16+4), $E); + &mov($D, &DWP(12,$tmp2,"",0)); + &mov($E, &DWP(16,$tmp2,"",0)); + + &RIP5($A,$B,$C,$D,$E,$wr[ 0],$sr[ 0],$KR0,-2); + &RIP5($E,$A,$B,$C,$D,$wr[ 1],$sr[ 1],$KR0,0); + &RIP5($D,$E,$A,$B,$C,$wr[ 2],$sr[ 2],$KR0,0); + &RIP5($C,$D,$E,$A,$B,$wr[ 3],$sr[ 3],$KR0,0); + &RIP5($B,$C,$D,$E,$A,$wr[ 4],$sr[ 4],$KR0,0); + &RIP5($A,$B,$C,$D,$E,$wr[ 5],$sr[ 5],$KR0,0); + &RIP5($E,$A,$B,$C,$D,$wr[ 6],$sr[ 6],$KR0,0); + &RIP5($D,$E,$A,$B,$C,$wr[ 7],$sr[ 7],$KR0,0); + &RIP5($C,$D,$E,$A,$B,$wr[ 8],$sr[ 8],$KR0,0); + &RIP5($B,$C,$D,$E,$A,$wr[ 9],$sr[ 9],$KR0,0); + &RIP5($A,$B,$C,$D,$E,$wr[10],$sr[10],$KR0,0); + &RIP5($E,$A,$B,$C,$D,$wr[11],$sr[11],$KR0,0); + &RIP5($D,$E,$A,$B,$C,$wr[12],$sr[12],$KR0,0); + &RIP5($C,$D,$E,$A,$B,$wr[13],$sr[13],$KR0,0); + &RIP5($B,$C,$D,$E,$A,$wr[14],$sr[14],$KR0,0); + &RIP5($A,$B,$C,$D,$E,$wr[15],$sr[15],$KR0,2); + + &RIP4($E,$A,$B,$C,$D,$wr[16],$sr[16],$KR1,-2); + &RIP4($D,$E,$A,$B,$C,$wr[17],$sr[17],$KR1,0); + &RIP4($C,$D,$E,$A,$B,$wr[18],$sr[18],$KR1,0); + &RIP4($B,$C,$D,$E,$A,$wr[19],$sr[19],$KR1,0); + &RIP4($A,$B,$C,$D,$E,$wr[20],$sr[20],$KR1,0); + &RIP4($E,$A,$B,$C,$D,$wr[21],$sr[21],$KR1,0); + &RIP4($D,$E,$A,$B,$C,$wr[22],$sr[22],$KR1,0); + &RIP4($C,$D,$E,$A,$B,$wr[23],$sr[23],$KR1,0); + &RIP4($B,$C,$D,$E,$A,$wr[24],$sr[24],$KR1,0); + &RIP4($A,$B,$C,$D,$E,$wr[25],$sr[25],$KR1,0); + &RIP4($E,$A,$B,$C,$D,$wr[26],$sr[26],$KR1,0); + &RIP4($D,$E,$A,$B,$C,$wr[27],$sr[27],$KR1,0); + &RIP4($C,$D,$E,$A,$B,$wr[28],$sr[28],$KR1,0); + &RIP4($B,$C,$D,$E,$A,$wr[29],$sr[29],$KR1,0); + &RIP4($A,$B,$C,$D,$E,$wr[30],$sr[30],$KR1,0); + &RIP4($E,$A,$B,$C,$D,$wr[31],$sr[31],$KR1,2); + + &RIP3($D,$E,$A,$B,$C,$wr[32],$sr[32],$KR2,-2); + &RIP3($C,$D,$E,$A,$B,$wr[33],$sr[33],$KR2,0); + &RIP3($B,$C,$D,$E,$A,$wr[34],$sr[34],$KR2,0); + &RIP3($A,$B,$C,$D,$E,$wr[35],$sr[35],$KR2,0); + &RIP3($E,$A,$B,$C,$D,$wr[36],$sr[36],$KR2,0); + &RIP3($D,$E,$A,$B,$C,$wr[37],$sr[37],$KR2,0); + &RIP3($C,$D,$E,$A,$B,$wr[38],$sr[38],$KR2,0); + &RIP3($B,$C,$D,$E,$A,$wr[39],$sr[39],$KR2,0); + &RIP3($A,$B,$C,$D,$E,$wr[40],$sr[40],$KR2,0); + &RIP3($E,$A,$B,$C,$D,$wr[41],$sr[41],$KR2,0); + &RIP3($D,$E,$A,$B,$C,$wr[42],$sr[42],$KR2,0); + &RIP3($C,$D,$E,$A,$B,$wr[43],$sr[43],$KR2,0); + &RIP3($B,$C,$D,$E,$A,$wr[44],$sr[44],$KR2,0); + &RIP3($A,$B,$C,$D,$E,$wr[45],$sr[45],$KR2,0); + &RIP3($E,$A,$B,$C,$D,$wr[46],$sr[46],$KR2,0); + &RIP3($D,$E,$A,$B,$C,$wr[47],$sr[47],$KR2,2,$wr[48]); + + &RIP2($C,$D,$E,$A,$B,$wr[48],$wr[49],$sr[48],$KR3,-2); + &RIP2($B,$C,$D,$E,$A,$wr[49],$wr[50],$sr[49],$KR3,0); + &RIP2($A,$B,$C,$D,$E,$wr[50],$wr[51],$sr[50],$KR3,0); + &RIP2($E,$A,$B,$C,$D,$wr[51],$wr[52],$sr[51],$KR3,0); + &RIP2($D,$E,$A,$B,$C,$wr[52],$wr[53],$sr[52],$KR3,0); + &RIP2($C,$D,$E,$A,$B,$wr[53],$wr[54],$sr[53],$KR3,0); + &RIP2($B,$C,$D,$E,$A,$wr[54],$wr[55],$sr[54],$KR3,0); + &RIP2($A,$B,$C,$D,$E,$wr[55],$wr[56],$sr[55],$KR3,0); + &RIP2($E,$A,$B,$C,$D,$wr[56],$wr[57],$sr[56],$KR3,0); + &RIP2($D,$E,$A,$B,$C,$wr[57],$wr[58],$sr[57],$KR3,0); + &RIP2($C,$D,$E,$A,$B,$wr[58],$wr[59],$sr[58],$KR3,0); + &RIP2($B,$C,$D,$E,$A,$wr[59],$wr[60],$sr[59],$KR3,0); + &RIP2($A,$B,$C,$D,$E,$wr[60],$wr[61],$sr[60],$KR3,0); + &RIP2($E,$A,$B,$C,$D,$wr[61],$wr[62],$sr[61],$KR3,0); + &RIP2($D,$E,$A,$B,$C,$wr[62],$wr[63],$sr[62],$KR3,0); + &RIP2($C,$D,$E,$A,$B,$wr[63],$wr[64],$sr[63],$KR3,2); + + &RIP1($B,$C,$D,$E,$A,$wr[64],$sr[64],-2); + &RIP1($A,$B,$C,$D,$E,$wr[65],$sr[65],0); + &RIP1($E,$A,$B,$C,$D,$wr[66],$sr[66],0); + &RIP1($D,$E,$A,$B,$C,$wr[67],$sr[67],0); + &RIP1($C,$D,$E,$A,$B,$wr[68],$sr[68],0); + &RIP1($B,$C,$D,$E,$A,$wr[69],$sr[69],0); + &RIP1($A,$B,$C,$D,$E,$wr[70],$sr[70],0); + &RIP1($E,$A,$B,$C,$D,$wr[71],$sr[71],0); + &RIP1($D,$E,$A,$B,$C,$wr[72],$sr[72],0); + &RIP1($C,$D,$E,$A,$B,$wr[73],$sr[73],0); + &RIP1($B,$C,$D,$E,$A,$wr[74],$sr[74],0); + &RIP1($A,$B,$C,$D,$E,$wr[75],$sr[75],0); + &RIP1($E,$A,$B,$C,$D,$wr[76],$sr[76],0); + &RIP1($D,$E,$A,$B,$C,$wr[77],$sr[77],0); + &RIP1($C,$D,$E,$A,$B,$wr[78],$sr[78],0); + &RIP1($B,$C,$D,$E,$A,$wr[79],$sr[79],2); + + # &mov($tmp2, &wparam(0)); # Moved into last round + + &mov($tmp1, &DWP( 4,$tmp2,"",0)); # ctx->B + &add($D, $tmp1); + &mov($tmp1, &swtmp(16+2)); # $c + &add($D, $tmp1); + + &mov($tmp1, &DWP( 8,$tmp2,"",0)); # ctx->C + &add($E, $tmp1); + &mov($tmp1, &swtmp(16+3)); # $d + &add($E, $tmp1); + + &mov($tmp1, &DWP(12,$tmp2,"",0)); # ctx->D + &add($A, $tmp1); + &mov($tmp1, &swtmp(16+4)); # $e + &add($A, $tmp1); + + + &mov($tmp1, &DWP(16,$tmp2,"",0)); # ctx->E + &add($B, $tmp1); + &mov($tmp1, &swtmp(16+0)); # $a + &add($B, $tmp1); + + &mov($tmp1, &DWP( 0,$tmp2,"",0)); # ctx->A + &add($C, $tmp1); + &mov($tmp1, &swtmp(16+1)); # $b + &add($C, $tmp1); + + &mov($tmp1, &wparam(2)); + + &mov(&DWP( 0,$tmp2,"",0), $D); + &mov(&DWP( 4,$tmp2,"",0), $E); + &mov(&DWP( 8,$tmp2,"",0), $A); + &sub($tmp1,1); + &mov(&DWP(12,$tmp2,"",0), $B); + &mov(&DWP(16,$tmp2,"",0), $C); + + &jle(&label("get_out")); + + &mov(&wparam(2),$tmp1); + &mov($C, $A); + &mov($tmp1, &wparam(1)); + &mov($A, $D); + &add($tmp1, 64); + &mov($B, $E); + &mov(&wparam(1),$tmp1); + + &jmp(&label("start")); + + &set_label("get_out"); + + &stack_pop(16+5+6); + + &pop("ebx"); + &pop("ebp"); + &pop("edi"); + &pop("esi"); + &ret(); + &function_end_B($name); + } + diff --git a/libs/openssl/crypto/ripemd/ripemd.h b/libs/openssl/crypto/ripemd/ripemd.h new file mode 100644 index 00000000..b88ef25e --- /dev/null +++ b/libs/openssl/crypto/ripemd/ripemd.h @@ -0,0 +1,105 @@ +/* crypto/ripemd/ripemd.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RIPEMD_H +# define HEADER_RIPEMD_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_NO_RIPEMD +# error RIPEMD is disabled. +# endif + +# if defined(__LP32__) +# define RIPEMD160_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define RIPEMD160_LONG unsigned long +# define RIPEMD160_LONG_LOG2 3 +# else +# define RIPEMD160_LONG unsigned int +# endif + +# define RIPEMD160_CBLOCK 64 +# define RIPEMD160_LBLOCK (RIPEMD160_CBLOCK/4) +# define RIPEMD160_DIGEST_LENGTH 20 + +typedef struct RIPEMD160state_st { + RIPEMD160_LONG A, B, C, D, E; + RIPEMD160_LONG Nl, Nh; + RIPEMD160_LONG data[RIPEMD160_LBLOCK]; + unsigned int num; +} RIPEMD160_CTX; + +# ifdef OPENSSL_FIPS +int private_RIPEMD160_Init(RIPEMD160_CTX *c); +# endif +int RIPEMD160_Init(RIPEMD160_CTX *c); +int RIPEMD160_Update(RIPEMD160_CTX *c, const void *data, size_t len); +int RIPEMD160_Final(unsigned char *md, RIPEMD160_CTX *c); +unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md); +void RIPEMD160_Transform(RIPEMD160_CTX *c, const unsigned char *b); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/ripemd/rmd160.c b/libs/openssl/crypto/ripemd/rmd160.c new file mode 100644 index 00000000..a4f80070 --- /dev/null +++ b/libs/openssl/crypto/ripemd/rmd160.c @@ -0,0 +1,121 @@ +/* crypto/ripemd/rmd160.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#define BUFSIZE 1024*16 + +void do_fp(FILE *f); +void pt(unsigned char *md); +#if !defined(_OSD_POSIX) && !defined(__DJGPP__) +int read(int, void *, unsigned int); +#endif + +int main(int argc, char **argv) +{ + int i, err = 0; + FILE *IN; + + if (argc == 1) { + do_fp(stdin); + } else { + for (i = 1; i < argc; i++) { + IN = fopen(argv[i], "r"); + if (IN == NULL) { + perror(argv[i]); + err++; + continue; + } + printf("RIPEMD160(%s)= ", argv[i]); + do_fp(IN); + fclose(IN); + } + } + exit(err); +} + +void do_fp(FILE *f) +{ + RIPEMD160_CTX c; + unsigned char md[RIPEMD160_DIGEST_LENGTH]; + int fd; + int i; + static unsigned char buf[BUFSIZE]; + + fd = fileno(f); + RIPEMD160_Init(&c); + for (;;) { + i = read(fd, buf, BUFSIZE); + if (i <= 0) + break; + RIPEMD160_Update(&c, buf, (unsigned long)i); + } + RIPEMD160_Final(&(md[0]), &c); + pt(md); +} + +void pt(unsigned char *md) +{ + int i; + + for (i = 0; i < RIPEMD160_DIGEST_LENGTH; i++) + printf("%02x", md[i]); + printf("\n"); +} diff --git a/libs/openssl/crypto/ripemd/rmd_dgst.c b/libs/openssl/crypto/ripemd/rmd_dgst.c new file mode 100644 index 00000000..4ddd939f --- /dev/null +++ b/libs/openssl/crypto/ripemd/rmd_dgst.c @@ -0,0 +1,334 @@ +/* crypto/ripemd/rmd_dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "rmd_locl.h" +#include +#include + +const char RMD160_version[] = "RIPE-MD160" OPENSSL_VERSION_PTEXT; + +#ifdef RMD160_ASM +void ripemd160_block_x86(RIPEMD160_CTX *c, unsigned long *p, size_t num); +# define ripemd160_block ripemd160_block_x86 +#else +void ripemd160_block(RIPEMD160_CTX *c, unsigned long *p, size_t num); +#endif + +fips_md_init(RIPEMD160) +{ + memset(c, 0, sizeof(*c)); + c->A = RIPEMD160_A; + c->B = RIPEMD160_B; + c->C = RIPEMD160_C; + c->D = RIPEMD160_D; + c->E = RIPEMD160_E; + return 1; +} + +#ifndef ripemd160_block_data_order +# ifdef X +# undef X +# endif +void ripemd160_block_data_order(RIPEMD160_CTX *ctx, const void *p, size_t num) +{ + const unsigned char *data = p; + register unsigned MD32_REG_T A, B, C, D, E; + unsigned MD32_REG_T a, b, c, d, e, l; +# ifndef MD32_XARRAY + /* See comment in crypto/sha/sha_locl.h for details. */ + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; +# define X(i) XX##i +# else + RIPEMD160_LONG XX[16]; +# define X(i) XX[i] +# endif + + for (; num--;) { + + A = ctx->A; + B = ctx->B; + C = ctx->C; + D = ctx->D; + E = ctx->E; + + (void)HOST_c2l(data, l); + X(0) = l; + (void)HOST_c2l(data, l); + X(1) = l; + RIP1(A, B, C, D, E, WL00, SL00); + (void)HOST_c2l(data, l); + X(2) = l; + RIP1(E, A, B, C, D, WL01, SL01); + (void)HOST_c2l(data, l); + X(3) = l; + RIP1(D, E, A, B, C, WL02, SL02); + (void)HOST_c2l(data, l); + X(4) = l; + RIP1(C, D, E, A, B, WL03, SL03); + (void)HOST_c2l(data, l); + X(5) = l; + RIP1(B, C, D, E, A, WL04, SL04); + (void)HOST_c2l(data, l); + X(6) = l; + RIP1(A, B, C, D, E, WL05, SL05); + (void)HOST_c2l(data, l); + X(7) = l; + RIP1(E, A, B, C, D, WL06, SL06); + (void)HOST_c2l(data, l); + X(8) = l; + RIP1(D, E, A, B, C, WL07, SL07); + (void)HOST_c2l(data, l); + X(9) = l; + RIP1(C, D, E, A, B, WL08, SL08); + (void)HOST_c2l(data, l); + X(10) = l; + RIP1(B, C, D, E, A, WL09, SL09); + (void)HOST_c2l(data, l); + X(11) = l; + RIP1(A, B, C, D, E, WL10, SL10); + (void)HOST_c2l(data, l); + X(12) = l; + RIP1(E, A, B, C, D, WL11, SL11); + (void)HOST_c2l(data, l); + X(13) = l; + RIP1(D, E, A, B, C, WL12, SL12); + (void)HOST_c2l(data, l); + X(14) = l; + RIP1(C, D, E, A, B, WL13, SL13); + (void)HOST_c2l(data, l); + X(15) = l; + RIP1(B, C, D, E, A, WL14, SL14); + RIP1(A, B, C, D, E, WL15, SL15); + + RIP2(E, A, B, C, D, WL16, SL16, KL1); + RIP2(D, E, A, B, C, WL17, SL17, KL1); + RIP2(C, D, E, A, B, WL18, SL18, KL1); + RIP2(B, C, D, E, A, WL19, SL19, KL1); + RIP2(A, B, C, D, E, WL20, SL20, KL1); + RIP2(E, A, B, C, D, WL21, SL21, KL1); + RIP2(D, E, A, B, C, WL22, SL22, KL1); + RIP2(C, D, E, A, B, WL23, SL23, KL1); + RIP2(B, C, D, E, A, WL24, SL24, KL1); + RIP2(A, B, C, D, E, WL25, SL25, KL1); + RIP2(E, A, B, C, D, WL26, SL26, KL1); + RIP2(D, E, A, B, C, WL27, SL27, KL1); + RIP2(C, D, E, A, B, WL28, SL28, KL1); + RIP2(B, C, D, E, A, WL29, SL29, KL1); + RIP2(A, B, C, D, E, WL30, SL30, KL1); + RIP2(E, A, B, C, D, WL31, SL31, KL1); + + RIP3(D, E, A, B, C, WL32, SL32, KL2); + RIP3(C, D, E, A, B, WL33, SL33, KL2); + RIP3(B, C, D, E, A, WL34, SL34, KL2); + RIP3(A, B, C, D, E, WL35, SL35, KL2); + RIP3(E, A, B, C, D, WL36, SL36, KL2); + RIP3(D, E, A, B, C, WL37, SL37, KL2); + RIP3(C, D, E, A, B, WL38, SL38, KL2); + RIP3(B, C, D, E, A, WL39, SL39, KL2); + RIP3(A, B, C, D, E, WL40, SL40, KL2); + RIP3(E, A, B, C, D, WL41, SL41, KL2); + RIP3(D, E, A, B, C, WL42, SL42, KL2); + RIP3(C, D, E, A, B, WL43, SL43, KL2); + RIP3(B, C, D, E, A, WL44, SL44, KL2); + RIP3(A, B, C, D, E, WL45, SL45, KL2); + RIP3(E, A, B, C, D, WL46, SL46, KL2); + RIP3(D, E, A, B, C, WL47, SL47, KL2); + + RIP4(C, D, E, A, B, WL48, SL48, KL3); + RIP4(B, C, D, E, A, WL49, SL49, KL3); + RIP4(A, B, C, D, E, WL50, SL50, KL3); + RIP4(E, A, B, C, D, WL51, SL51, KL3); + RIP4(D, E, A, B, C, WL52, SL52, KL3); + RIP4(C, D, E, A, B, WL53, SL53, KL3); + RIP4(B, C, D, E, A, WL54, SL54, KL3); + RIP4(A, B, C, D, E, WL55, SL55, KL3); + RIP4(E, A, B, C, D, WL56, SL56, KL3); + RIP4(D, E, A, B, C, WL57, SL57, KL3); + RIP4(C, D, E, A, B, WL58, SL58, KL3); + RIP4(B, C, D, E, A, WL59, SL59, KL3); + RIP4(A, B, C, D, E, WL60, SL60, KL3); + RIP4(E, A, B, C, D, WL61, SL61, KL3); + RIP4(D, E, A, B, C, WL62, SL62, KL3); + RIP4(C, D, E, A, B, WL63, SL63, KL3); + + RIP5(B, C, D, E, A, WL64, SL64, KL4); + RIP5(A, B, C, D, E, WL65, SL65, KL4); + RIP5(E, A, B, C, D, WL66, SL66, KL4); + RIP5(D, E, A, B, C, WL67, SL67, KL4); + RIP5(C, D, E, A, B, WL68, SL68, KL4); + RIP5(B, C, D, E, A, WL69, SL69, KL4); + RIP5(A, B, C, D, E, WL70, SL70, KL4); + RIP5(E, A, B, C, D, WL71, SL71, KL4); + RIP5(D, E, A, B, C, WL72, SL72, KL4); + RIP5(C, D, E, A, B, WL73, SL73, KL4); + RIP5(B, C, D, E, A, WL74, SL74, KL4); + RIP5(A, B, C, D, E, WL75, SL75, KL4); + RIP5(E, A, B, C, D, WL76, SL76, KL4); + RIP5(D, E, A, B, C, WL77, SL77, KL4); + RIP5(C, D, E, A, B, WL78, SL78, KL4); + RIP5(B, C, D, E, A, WL79, SL79, KL4); + + a = A; + b = B; + c = C; + d = D; + e = E; + /* Do other half */ + A = ctx->A; + B = ctx->B; + C = ctx->C; + D = ctx->D; + E = ctx->E; + + RIP5(A, B, C, D, E, WR00, SR00, KR0); + RIP5(E, A, B, C, D, WR01, SR01, KR0); + RIP5(D, E, A, B, C, WR02, SR02, KR0); + RIP5(C, D, E, A, B, WR03, SR03, KR0); + RIP5(B, C, D, E, A, WR04, SR04, KR0); + RIP5(A, B, C, D, E, WR05, SR05, KR0); + RIP5(E, A, B, C, D, WR06, SR06, KR0); + RIP5(D, E, A, B, C, WR07, SR07, KR0); + RIP5(C, D, E, A, B, WR08, SR08, KR0); + RIP5(B, C, D, E, A, WR09, SR09, KR0); + RIP5(A, B, C, D, E, WR10, SR10, KR0); + RIP5(E, A, B, C, D, WR11, SR11, KR0); + RIP5(D, E, A, B, C, WR12, SR12, KR0); + RIP5(C, D, E, A, B, WR13, SR13, KR0); + RIP5(B, C, D, E, A, WR14, SR14, KR0); + RIP5(A, B, C, D, E, WR15, SR15, KR0); + + RIP4(E, A, B, C, D, WR16, SR16, KR1); + RIP4(D, E, A, B, C, WR17, SR17, KR1); + RIP4(C, D, E, A, B, WR18, SR18, KR1); + RIP4(B, C, D, E, A, WR19, SR19, KR1); + RIP4(A, B, C, D, E, WR20, SR20, KR1); + RIP4(E, A, B, C, D, WR21, SR21, KR1); + RIP4(D, E, A, B, C, WR22, SR22, KR1); + RIP4(C, D, E, A, B, WR23, SR23, KR1); + RIP4(B, C, D, E, A, WR24, SR24, KR1); + RIP4(A, B, C, D, E, WR25, SR25, KR1); + RIP4(E, A, B, C, D, WR26, SR26, KR1); + RIP4(D, E, A, B, C, WR27, SR27, KR1); + RIP4(C, D, E, A, B, WR28, SR28, KR1); + RIP4(B, C, D, E, A, WR29, SR29, KR1); + RIP4(A, B, C, D, E, WR30, SR30, KR1); + RIP4(E, A, B, C, D, WR31, SR31, KR1); + + RIP3(D, E, A, B, C, WR32, SR32, KR2); + RIP3(C, D, E, A, B, WR33, SR33, KR2); + RIP3(B, C, D, E, A, WR34, SR34, KR2); + RIP3(A, B, C, D, E, WR35, SR35, KR2); + RIP3(E, A, B, C, D, WR36, SR36, KR2); + RIP3(D, E, A, B, C, WR37, SR37, KR2); + RIP3(C, D, E, A, B, WR38, SR38, KR2); + RIP3(B, C, D, E, A, WR39, SR39, KR2); + RIP3(A, B, C, D, E, WR40, SR40, KR2); + RIP3(E, A, B, C, D, WR41, SR41, KR2); + RIP3(D, E, A, B, C, WR42, SR42, KR2); + RIP3(C, D, E, A, B, WR43, SR43, KR2); + RIP3(B, C, D, E, A, WR44, SR44, KR2); + RIP3(A, B, C, D, E, WR45, SR45, KR2); + RIP3(E, A, B, C, D, WR46, SR46, KR2); + RIP3(D, E, A, B, C, WR47, SR47, KR2); + + RIP2(C, D, E, A, B, WR48, SR48, KR3); + RIP2(B, C, D, E, A, WR49, SR49, KR3); + RIP2(A, B, C, D, E, WR50, SR50, KR3); + RIP2(E, A, B, C, D, WR51, SR51, KR3); + RIP2(D, E, A, B, C, WR52, SR52, KR3); + RIP2(C, D, E, A, B, WR53, SR53, KR3); + RIP2(B, C, D, E, A, WR54, SR54, KR3); + RIP2(A, B, C, D, E, WR55, SR55, KR3); + RIP2(E, A, B, C, D, WR56, SR56, KR3); + RIP2(D, E, A, B, C, WR57, SR57, KR3); + RIP2(C, D, E, A, B, WR58, SR58, KR3); + RIP2(B, C, D, E, A, WR59, SR59, KR3); + RIP2(A, B, C, D, E, WR60, SR60, KR3); + RIP2(E, A, B, C, D, WR61, SR61, KR3); + RIP2(D, E, A, B, C, WR62, SR62, KR3); + RIP2(C, D, E, A, B, WR63, SR63, KR3); + + RIP1(B, C, D, E, A, WR64, SR64); + RIP1(A, B, C, D, E, WR65, SR65); + RIP1(E, A, B, C, D, WR66, SR66); + RIP1(D, E, A, B, C, WR67, SR67); + RIP1(C, D, E, A, B, WR68, SR68); + RIP1(B, C, D, E, A, WR69, SR69); + RIP1(A, B, C, D, E, WR70, SR70); + RIP1(E, A, B, C, D, WR71, SR71); + RIP1(D, E, A, B, C, WR72, SR72); + RIP1(C, D, E, A, B, WR73, SR73); + RIP1(B, C, D, E, A, WR74, SR74); + RIP1(A, B, C, D, E, WR75, SR75); + RIP1(E, A, B, C, D, WR76, SR76); + RIP1(D, E, A, B, C, WR77, SR77); + RIP1(C, D, E, A, B, WR78, SR78); + RIP1(B, C, D, E, A, WR79, SR79); + + D = ctx->B + c + D; + ctx->B = ctx->C + d + E; + ctx->C = ctx->D + e + A; + ctx->D = ctx->E + a + B; + ctx->E = ctx->A + b + C; + ctx->A = D; + + } +} +#endif diff --git a/libs/openssl/crypto/ripemd/rmd_locl.h b/libs/openssl/crypto/ripemd/rmd_locl.h new file mode 100644 index 00000000..26e02563 --- /dev/null +++ b/libs/openssl/crypto/ripemd/rmd_locl.h @@ -0,0 +1,149 @@ +/* crypto/ripemd/rmd_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#ifndef RIPEMD160_LONG_LOG2 +# define RIPEMD160_LONG_LOG2 2 /* default to 32 bits */ +#endif + +/* + * DO EXAMINE COMMENTS IN crypto/md5/md5_locl.h & crypto/md5/md5_dgst.c + * FOR EXPLANATIONS ON FOLLOWING "CODE." + * + */ +#ifdef RMD160_ASM +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || defined(__INTEL__) +# define ripemd160_block_data_order ripemd160_block_asm_data_order +# endif +#endif + +void ripemd160_block_data_order(RIPEMD160_CTX *c, const void *p, size_t num); + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_LONG RIPEMD160_LONG +#define HASH_CTX RIPEMD160_CTX +#define HASH_CBLOCK RIPEMD160_CBLOCK +#define HASH_UPDATE RIPEMD160_Update +#define HASH_TRANSFORM RIPEMD160_Transform +#define HASH_FINAL RIPEMD160_Final +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->A; (void)HOST_l2c(ll,(s)); \ + ll=(c)->B; (void)HOST_l2c(ll,(s)); \ + ll=(c)->C; (void)HOST_l2c(ll,(s)); \ + ll=(c)->D; (void)HOST_l2c(ll,(s)); \ + ll=(c)->E; (void)HOST_l2c(ll,(s)); \ + } while (0) +#define HASH_BLOCK_DATA_ORDER ripemd160_block_data_order + +#include "md32_common.h" + +#if 0 +# define F1(x,y,z) ((x)^(y)^(z)) +# define F2(x,y,z) (((x)&(y))|((~x)&z)) +# define F3(x,y,z) (((x)|(~y))^(z)) +# define F4(x,y,z) (((x)&(z))|((y)&(~(z)))) +# define F5(x,y,z) ((x)^((y)|(~(z)))) +#else +/* + * Transformed F2 and F4 are courtesy of Wei Dai + */ +# define F1(x,y,z) ((x) ^ (y) ^ (z)) +# define F2(x,y,z) ((((y) ^ (z)) & (x)) ^ (z)) +# define F3(x,y,z) (((~(y)) | (x)) ^ (z)) +# define F4(x,y,z) ((((x) ^ (y)) & (z)) ^ (y)) +# define F5(x,y,z) (((~(z)) | (y)) ^ (x)) +#endif + +#define RIPEMD160_A 0x67452301L +#define RIPEMD160_B 0xEFCDAB89L +#define RIPEMD160_C 0x98BADCFEL +#define RIPEMD160_D 0x10325476L +#define RIPEMD160_E 0xC3D2E1F0L + +#include "rmdconst.h" + +#define RIP1(a,b,c,d,e,w,s) { \ + a+=F1(b,c,d)+X(w); \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } + +#define RIP2(a,b,c,d,e,w,s,K) { \ + a+=F2(b,c,d)+X(w)+K; \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } + +#define RIP3(a,b,c,d,e,w,s,K) { \ + a+=F3(b,c,d)+X(w)+K; \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } + +#define RIP4(a,b,c,d,e,w,s,K) { \ + a+=F4(b,c,d)+X(w)+K; \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } + +#define RIP5(a,b,c,d,e,w,s,K) { \ + a+=F5(b,c,d)+X(w)+K; \ + a=ROTATE(a,s)+e; \ + c=ROTATE(c,10); } diff --git a/libs/openssl/crypto/ripemd/rmd_one.c b/libs/openssl/crypto/ripemd/rmd_one.c new file mode 100644 index 00000000..666e01a4 --- /dev/null +++ b/libs/openssl/crypto/ripemd/rmd_one.c @@ -0,0 +1,77 @@ +/* crypto/ripemd/rmd_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +unsigned char *RIPEMD160(const unsigned char *d, size_t n, unsigned char *md) +{ + RIPEMD160_CTX c; + static unsigned char m[RIPEMD160_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!RIPEMD160_Init(&c)) + return NULL; + RIPEMD160_Update(&c, d, n); + RIPEMD160_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); /* security consideration */ + return (md); +} diff --git a/libs/openssl/crypto/ripemd/rmdconst.h b/libs/openssl/crypto/ripemd/rmdconst.h new file mode 100644 index 00000000..8fe33de1 --- /dev/null +++ b/libs/openssl/crypto/ripemd/rmdconst.h @@ -0,0 +1,398 @@ +/* crypto/ripemd/rmdconst.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +#define KL0 0x00000000L +#define KL1 0x5A827999L +#define KL2 0x6ED9EBA1L +#define KL3 0x8F1BBCDCL +#define KL4 0xA953FD4EL + +#define KR0 0x50A28BE6L +#define KR1 0x5C4DD124L +#define KR2 0x6D703EF3L +#define KR3 0x7A6D76E9L +#define KR4 0x00000000L + +#define WL00 0 +#define SL00 11 +#define WL01 1 +#define SL01 14 +#define WL02 2 +#define SL02 15 +#define WL03 3 +#define SL03 12 +#define WL04 4 +#define SL04 5 +#define WL05 5 +#define SL05 8 +#define WL06 6 +#define SL06 7 +#define WL07 7 +#define SL07 9 +#define WL08 8 +#define SL08 11 +#define WL09 9 +#define SL09 13 +#define WL10 10 +#define SL10 14 +#define WL11 11 +#define SL11 15 +#define WL12 12 +#define SL12 6 +#define WL13 13 +#define SL13 7 +#define WL14 14 +#define SL14 9 +#define WL15 15 +#define SL15 8 + +#define WL16 7 +#define SL16 7 +#define WL17 4 +#define SL17 6 +#define WL18 13 +#define SL18 8 +#define WL19 1 +#define SL19 13 +#define WL20 10 +#define SL20 11 +#define WL21 6 +#define SL21 9 +#define WL22 15 +#define SL22 7 +#define WL23 3 +#define SL23 15 +#define WL24 12 +#define SL24 7 +#define WL25 0 +#define SL25 12 +#define WL26 9 +#define SL26 15 +#define WL27 5 +#define SL27 9 +#define WL28 2 +#define SL28 11 +#define WL29 14 +#define SL29 7 +#define WL30 11 +#define SL30 13 +#define WL31 8 +#define SL31 12 + +#define WL32 3 +#define SL32 11 +#define WL33 10 +#define SL33 13 +#define WL34 14 +#define SL34 6 +#define WL35 4 +#define SL35 7 +#define WL36 9 +#define SL36 14 +#define WL37 15 +#define SL37 9 +#define WL38 8 +#define SL38 13 +#define WL39 1 +#define SL39 15 +#define WL40 2 +#define SL40 14 +#define WL41 7 +#define SL41 8 +#define WL42 0 +#define SL42 13 +#define WL43 6 +#define SL43 6 +#define WL44 13 +#define SL44 5 +#define WL45 11 +#define SL45 12 +#define WL46 5 +#define SL46 7 +#define WL47 12 +#define SL47 5 + +#define WL48 1 +#define SL48 11 +#define WL49 9 +#define SL49 12 +#define WL50 11 +#define SL50 14 +#define WL51 10 +#define SL51 15 +#define WL52 0 +#define SL52 14 +#define WL53 8 +#define SL53 15 +#define WL54 12 +#define SL54 9 +#define WL55 4 +#define SL55 8 +#define WL56 13 +#define SL56 9 +#define WL57 3 +#define SL57 14 +#define WL58 7 +#define SL58 5 +#define WL59 15 +#define SL59 6 +#define WL60 14 +#define SL60 8 +#define WL61 5 +#define SL61 6 +#define WL62 6 +#define SL62 5 +#define WL63 2 +#define SL63 12 + +#define WL64 4 +#define SL64 9 +#define WL65 0 +#define SL65 15 +#define WL66 5 +#define SL66 5 +#define WL67 9 +#define SL67 11 +#define WL68 7 +#define SL68 6 +#define WL69 12 +#define SL69 8 +#define WL70 2 +#define SL70 13 +#define WL71 10 +#define SL71 12 +#define WL72 14 +#define SL72 5 +#define WL73 1 +#define SL73 12 +#define WL74 3 +#define SL74 13 +#define WL75 8 +#define SL75 14 +#define WL76 11 +#define SL76 11 +#define WL77 6 +#define SL77 8 +#define WL78 15 +#define SL78 5 +#define WL79 13 +#define SL79 6 + +#define WR00 5 +#define SR00 8 +#define WR01 14 +#define SR01 9 +#define WR02 7 +#define SR02 9 +#define WR03 0 +#define SR03 11 +#define WR04 9 +#define SR04 13 +#define WR05 2 +#define SR05 15 +#define WR06 11 +#define SR06 15 +#define WR07 4 +#define SR07 5 +#define WR08 13 +#define SR08 7 +#define WR09 6 +#define SR09 7 +#define WR10 15 +#define SR10 8 +#define WR11 8 +#define SR11 11 +#define WR12 1 +#define SR12 14 +#define WR13 10 +#define SR13 14 +#define WR14 3 +#define SR14 12 +#define WR15 12 +#define SR15 6 + +#define WR16 6 +#define SR16 9 +#define WR17 11 +#define SR17 13 +#define WR18 3 +#define SR18 15 +#define WR19 7 +#define SR19 7 +#define WR20 0 +#define SR20 12 +#define WR21 13 +#define SR21 8 +#define WR22 5 +#define SR22 9 +#define WR23 10 +#define SR23 11 +#define WR24 14 +#define SR24 7 +#define WR25 15 +#define SR25 7 +#define WR26 8 +#define SR26 12 +#define WR27 12 +#define SR27 7 +#define WR28 4 +#define SR28 6 +#define WR29 9 +#define SR29 15 +#define WR30 1 +#define SR30 13 +#define WR31 2 +#define SR31 11 + +#define WR32 15 +#define SR32 9 +#define WR33 5 +#define SR33 7 +#define WR34 1 +#define SR34 15 +#define WR35 3 +#define SR35 11 +#define WR36 7 +#define SR36 8 +#define WR37 14 +#define SR37 6 +#define WR38 6 +#define SR38 6 +#define WR39 9 +#define SR39 14 +#define WR40 11 +#define SR40 12 +#define WR41 8 +#define SR41 13 +#define WR42 12 +#define SR42 5 +#define WR43 2 +#define SR43 14 +#define WR44 10 +#define SR44 13 +#define WR45 0 +#define SR45 13 +#define WR46 4 +#define SR46 7 +#define WR47 13 +#define SR47 5 + +#define WR48 8 +#define SR48 15 +#define WR49 6 +#define SR49 5 +#define WR50 4 +#define SR50 8 +#define WR51 1 +#define SR51 11 +#define WR52 3 +#define SR52 14 +#define WR53 11 +#define SR53 14 +#define WR54 15 +#define SR54 6 +#define WR55 0 +#define SR55 14 +#define WR56 5 +#define SR56 6 +#define WR57 12 +#define SR57 9 +#define WR58 2 +#define SR58 12 +#define WR59 13 +#define SR59 9 +#define WR60 9 +#define SR60 12 +#define WR61 7 +#define SR61 5 +#define WR62 10 +#define SR62 15 +#define WR63 14 +#define SR63 8 + +#define WR64 12 +#define SR64 8 +#define WR65 15 +#define SR65 5 +#define WR66 10 +#define SR66 12 +#define WR67 4 +#define SR67 9 +#define WR68 1 +#define SR68 12 +#define WR69 5 +#define SR69 5 +#define WR70 8 +#define SR70 14 +#define WR71 7 +#define SR71 6 +#define WR72 6 +#define SR72 8 +#define WR73 2 +#define SR73 13 +#define WR74 13 +#define SR74 6 +#define WR75 14 +#define SR75 5 +#define WR76 0 +#define SR76 15 +#define WR77 3 +#define SR77 13 +#define WR78 9 +#define SR78 11 +#define WR79 11 +#define SR79 11 diff --git a/libs/openssl/crypto/ripemd/rmdtest.c b/libs/openssl/crypto/ripemd/rmdtest.c new file mode 100644 index 00000000..95f6f46a --- /dev/null +++ b/libs/openssl/crypto/ripemd/rmdtest.c @@ -0,0 +1,143 @@ +/* crypto/ripemd/rmdtest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "../e_os.h" + +#ifdef OPENSSL_NO_RIPEMD +int main(int argc, char *argv[]) +{ + printf("No ripemd support\n"); + return (0); +} +#else +# include +# include + +# ifdef CHARSET_EBCDIC +# include +# endif + +static char *test[] = { + "", + "a", + "abc", + "message digest", + "abcdefghijklmnopqrstuvwxyz", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "12345678901234567890123456789012345678901234567890123456789012345678901234567890", + NULL, +}; + +static char *ret[] = { + "9c1185a5c5e9fc54612808977ee8f548b2258d31", + "0bdc9d2d256b3ee9daae347be6f4dc835a467ffe", + "8eb208f7e05d987a9b044a8e98c6b087f15a0bfc", + "5d0689ef49d2fae572b881b123a85ffa21595f36", + "f71c27109c692c1b56bbdceb5b9d2865b3708dbc", + "12a053384a9c0c88e405a06c27dcf49ada62eb2b", + "b0e20b6e3116640286ed3a87a5713079b21f5189", + "9b752e45573d4b39f4dbd3323cab82bf63326bfb", +}; + +static char *pt(unsigned char *md); +int main(int argc, char *argv[]) +{ + int i, err = 0; + char **P, **R; + char *p; + unsigned char md[RIPEMD160_DIGEST_LENGTH]; + + P = test; + R = ret; + i = 1; + while (*P != NULL) { +# ifdef CHARSET_EBCDIC + ebcdic2ascii((char *)*P, (char *)*P, strlen((char *)*P)); +# endif + EVP_Digest(&(P[0][0]), strlen((char *)*P), md, NULL, EVP_ripemd160(), + NULL); + p = pt(md); + if (strcmp(p, (char *)*R) != 0) { + printf("error calculating RIPEMD160 on '%s'\n", *P); + printf("got %s instead of %s\n", p, *R); + err++; + } else + printf("test %d ok\n", i); + i++; + R++; + P++; + } + EXIT(err); + return (0); +} + +static char *pt(unsigned char *md) +{ + int i; + static char buf[80]; + + for (i = 0; i < RIPEMD160_DIGEST_LENGTH; i++) + sprintf(&(buf[i * 2]), "%02x", md[i]); + return (buf); +} +#endif diff --git a/libs/openssl/crypto/rsa/rsa.h b/libs/openssl/crypto/rsa/rsa.h new file mode 100644 index 00000000..a8b59a95 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa.h @@ -0,0 +1,610 @@ +/* crypto/rsa/rsa.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_RSA_H +# define HEADER_RSA_H + +# include + +# ifndef OPENSSL_NO_BIO +# include +# endif +# include +# include +# ifndef OPENSSL_NO_DEPRECATED +# include +# endif + +# ifdef OPENSSL_NO_RSA +# error RSA is disabled. +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Declared already in ossl_typ.h */ +/* typedef struct rsa_st RSA; */ +/* typedef struct rsa_meth_st RSA_METHOD; */ + +struct rsa_meth_st { + const char *name; + int (*rsa_pub_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_pub_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_priv_enc) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + int (*rsa_priv_dec) (int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); + /* Can be null */ + int (*rsa_mod_exp) (BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); + /* Can be null */ + int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx); + /* called at new */ + int (*init) (RSA *rsa); + /* called at free */ + int (*finish) (RSA *rsa); + /* RSA_METHOD_FLAG_* things */ + int flags; + /* may be needed! */ + char *app_data; + /* + * New sign and verify functions: some libraries don't allow arbitrary + * data to be signed/verified: this allows them to be used. Note: for + * this to work the RSA_public_decrypt() and RSA_private_encrypt() should + * *NOT* be used RSA_sign(), RSA_verify() should be used instead. Note: + * for backwards compatibility this functionality is only enabled if the + * RSA_FLAG_SIGN_VER option is set in 'flags'. + */ + int (*rsa_sign) (int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + const RSA *rsa); + int (*rsa_verify) (int dtype, const unsigned char *m, + unsigned int m_length, const unsigned char *sigbuf, + unsigned int siglen, const RSA *rsa); + /* + * If this callback is NULL, the builtin software RSA key-gen will be + * used. This is for behavioural compatibility whilst the code gets + * rewired, but one day it would be nice to assume there are no such + * things as "builtin software" implementations. + */ + int (*rsa_keygen) (RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); +}; + +struct rsa_st { + /* + * The first parameter is used to pickup errors where this is passed + * instead of aEVP_PKEY, it is set to 0 + */ + int pad; + long version; + const RSA_METHOD *meth; + /* functional reference if 'meth' is ENGINE-provided */ + ENGINE *engine; + BIGNUM *n; + BIGNUM *e; + BIGNUM *d; + BIGNUM *p; + BIGNUM *q; + BIGNUM *dmp1; + BIGNUM *dmq1; + BIGNUM *iqmp; + /* be careful using this if the RSA structure is shared */ + CRYPTO_EX_DATA ex_data; + int references; + int flags; + /* Used to cache montgomery values */ + BN_MONT_CTX *_method_mod_n; + BN_MONT_CTX *_method_mod_p; + BN_MONT_CTX *_method_mod_q; + /* + * all BIGNUM values are actually in the following data, if it is not + * NULL + */ + char *bignum_data; + BN_BLINDING *blinding; + BN_BLINDING *mt_blinding; +}; + +# ifndef OPENSSL_RSA_MAX_MODULUS_BITS +# define OPENSSL_RSA_MAX_MODULUS_BITS 16384 +# endif + +# ifndef OPENSSL_RSA_SMALL_MODULUS_BITS +# define OPENSSL_RSA_SMALL_MODULUS_BITS 3072 +# endif +# ifndef OPENSSL_RSA_MAX_PUBEXP_BITS + +/* exponent limit enforced for "large" modulus only */ +# define OPENSSL_RSA_MAX_PUBEXP_BITS 64 +# endif + +# define RSA_3 0x3L +# define RSA_F4 0x10001L + +# define RSA_METHOD_FLAG_NO_CHECK 0x0001/* don't check pub/private + * match */ + +# define RSA_FLAG_CACHE_PUBLIC 0x0002 +# define RSA_FLAG_CACHE_PRIVATE 0x0004 +# define RSA_FLAG_BLINDING 0x0008 +# define RSA_FLAG_THREAD_SAFE 0x0010 +/* + * This flag means the private key operations will be handled by rsa_mod_exp + * and that they do not depend on the private key components being present: + * for example a key stored in external hardware. Without this flag + * bn_mod_exp gets called when private key components are absent. + */ +# define RSA_FLAG_EXT_PKEY 0x0020 + +/* + * This flag in the RSA_METHOD enables the new rsa_sign, rsa_verify + * functions. + */ +# define RSA_FLAG_SIGN_VER 0x0040 + +/* + * new with 0.9.6j and 0.9.7b; the built-in + * RSA implementation now uses blinding by + * default (ignoring RSA_FLAG_BLINDING), + * but other engines might not need it + */ +# define RSA_FLAG_NO_BLINDING 0x0080 +/* + * new with 0.9.8f; the built-in RSA + * implementation now uses constant time + * operations by default in private key operations, + * e.g., constant time modular exponentiation, + * modular inverse without leaking branches, + * division without leaking branches. This + * flag disables these constant time + * operations and results in faster RSA + * private key operations. + */ +# define RSA_FLAG_NO_CONSTTIME 0x0100 +# ifdef OPENSSL_USE_DEPRECATED +/* deprecated name for the flag*/ +/* + * new with 0.9.7h; the built-in RSA + * implementation now uses constant time + * modular exponentiation for secret exponents + * by default. This flag causes the + * faster variable sliding window method to + * be used for all exponents. + */ +# define RSA_FLAG_NO_EXP_CONSTTIME RSA_FLAG_NO_CONSTTIME +# endif + +# define EVP_PKEY_CTX_set_rsa_padding(ctx, pad) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, \ + pad, NULL) + +# define EVP_PKEY_CTX_get_rsa_padding(ctx, ppad) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, \ + EVP_PKEY_CTRL_GET_RSA_PADDING, 0, ppad) + +# define EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, len) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, \ + len, NULL) + +# define EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx, plen) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, \ + (EVP_PKEY_OP_SIGN|EVP_PKEY_OP_VERIFY), \ + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, \ + 0, plen) + +# define EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, bits) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL) + +# define EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, \ + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, pubexp) + +# define EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, md) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_RSA_MGF1_MD, 0, (void *)md) + +# define EVP_PKEY_CTX_get_rsa_mgf1_md(ctx, pmd) \ + EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_SIG, \ + EVP_PKEY_CTRL_GET_RSA_MGF1_MD, 0, (void *)pmd) + +# define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +# define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 2) + +# define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 3) +# define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 4) +# define EVP_PKEY_CTRL_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 5) + +# define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 6) +# define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 7) +# define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 8) + +# define RSA_PKCS1_PADDING 1 +# define RSA_SSLV23_PADDING 2 +# define RSA_NO_PADDING 3 +# define RSA_PKCS1_OAEP_PADDING 4 +# define RSA_X931_PADDING 5 +/* EVP_PKEY_ only */ +# define RSA_PKCS1_PSS_PADDING 6 + +# define RSA_PKCS1_PADDING_SIZE 11 + +# define RSA_set_app_data(s,arg) RSA_set_ex_data(s,0,arg) +# define RSA_get_app_data(s) RSA_get_ex_data(s,0) + +RSA *RSA_new(void); +RSA *RSA_new_method(ENGINE *engine); +int RSA_size(const RSA *rsa); + +/* Deprecated version */ +# ifndef OPENSSL_NO_DEPRECATED +RSA *RSA_generate_key(int bits, unsigned long e, void + (*callback) (int, int, void *), void *cb_arg); +# endif /* !defined(OPENSSL_NO_DEPRECATED) */ + +/* New version */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, BN_GENCB *cb); + +int RSA_check_key(const RSA *); + /* next 4 return -1 on error */ +int RSA_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +int RSA_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +void RSA_free(RSA *r); +/* "up" the RSA object's reference count */ +int RSA_up_ref(RSA *r); + +int RSA_flags(const RSA *r); + +void RSA_set_default_method(const RSA_METHOD *meth); +const RSA_METHOD *RSA_get_default_method(void); +const RSA_METHOD *RSA_get_method(const RSA *rsa); +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth); + +/* This function needs the memory locking malloc callbacks to be installed */ +int RSA_memory_lock(RSA *r); + +/* these are the actual SSLeay RSA functions */ +const RSA_METHOD *RSA_PKCS1_SSLeay(void); + +const RSA_METHOD *RSA_null_method(void); + +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPublicKey) +DECLARE_ASN1_ENCODE_FUNCTIONS_const(RSA, RSAPrivateKey) + +typedef struct rsa_pss_params_st { + X509_ALGOR *hashAlgorithm; + X509_ALGOR *maskGenAlgorithm; + ASN1_INTEGER *saltLength; + ASN1_INTEGER *trailerField; +} RSA_PSS_PARAMS; + +DECLARE_ASN1_FUNCTIONS(RSA_PSS_PARAMS) + +# ifndef OPENSSL_NO_FP_API +int RSA_print_fp(FILE *fp, const RSA *r, int offset); +# endif + +# ifndef OPENSSL_NO_BIO +int RSA_print(BIO *bp, const RSA *r, int offset); +# endif + +# ifndef OPENSSL_NO_RC4 +int i2d_RSA_NET(const RSA *a, unsigned char **pp, + int (*cb) (char *buf, int len, const char *prompt, + int verify), int sgckey); +RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length, + int (*cb) (char *buf, int len, const char *prompt, + int verify), int sgckey); + +int i2d_Netscape_RSA(const RSA *a, unsigned char **pp, + int (*cb) (char *buf, int len, const char *prompt, + int verify)); +RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length, + int (*cb) (char *buf, int len, const char *prompt, + int verify)); +# endif + +/* + * The following 2 functions sign and verify a X509_SIG ASN1 object inside + * PKCS#1 padded RSA encryption + */ +int RSA_sign(int type, const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, RSA *rsa); +int RSA_verify(int type, const unsigned char *m, unsigned int m_length, + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa); + +/* + * The following 2 function sign and verify a ASN1_OCTET_STRING object inside + * PKCS#1 padded RSA encryption + */ +int RSA_sign_ASN1_OCTET_STRING(int type, + const unsigned char *m, unsigned int m_length, + unsigned char *sigret, unsigned int *siglen, + RSA *rsa); +int RSA_verify_ASN1_OCTET_STRING(int type, const unsigned char *m, + unsigned int m_length, unsigned char *sigbuf, + unsigned int siglen, RSA *rsa); + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); +void RSA_blinding_off(RSA *rsa); +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *ctx); + +int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *f, int fl, + int rsa_len); +int PKCS1_MGF1(unsigned char *mask, long len, const unsigned char *seed, + long seedlen, const EVP_MD *dgst); +int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, + const unsigned char *p, int pl); +int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len, + const unsigned char *p, int pl); +int RSA_padding_add_SSLv23(unsigned char *to, int tlen, + const unsigned char *f, int fl); +int RSA_padding_check_SSLv23(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_none(unsigned char *to, int tlen, const unsigned char *f, + int fl); +int RSA_padding_check_none(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_padding_add_X931(unsigned char *to, int tlen, const unsigned char *f, + int fl); +int RSA_padding_check_X931(unsigned char *to, int tlen, + const unsigned char *f, int fl, int rsa_len); +int RSA_X931_hash_id(int nid); + +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const unsigned char *EM, + int sLen); +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, const EVP_MD *Hash, + int sLen); + +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + const unsigned char *EM, int sLen); + +int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + int sLen); + +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int RSA_set_ex_data(RSA *r, int idx, void *arg); +void *RSA_get_ex_data(const RSA *r, int idx); + +RSA *RSAPublicKey_dup(RSA *rsa); +RSA *RSAPrivateKey_dup(RSA *rsa); + +/* + * If this flag is set the RSA method is FIPS compliant and can be used in + * FIPS mode. This is set in the validated module method. If an application + * sets this flag in its own methods it is its responsibility to ensure the + * result is compliant. + */ + +# define RSA_FLAG_FIPS_METHOD 0x0400 + +/* + * If this flag is set the operations normally disabled in FIPS mode are + * permitted it is then the applications responsibility to ensure that the + * usage is compliant. + */ + +# define RSA_FLAG_NON_FIPS_ALLOW 0x0400 +/* + * Application has decided PRNG is good enough to generate a key: don't + * check. + */ +# define RSA_FLAG_CHECKED 0x0800 + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_RSA_strings(void); + +/* Error codes for the RSA functions. */ + +/* Function codes. */ +# define RSA_F_CHECK_PADDING_MD 140 +# define RSA_F_DO_RSA_PRINT 146 +# define RSA_F_INT_RSA_VERIFY 145 +# define RSA_F_MEMORY_LOCK 100 +# define RSA_F_OLD_RSA_PRIV_DECODE 147 +# define RSA_F_PKEY_RSA_CTRL 143 +# define RSA_F_PKEY_RSA_CTRL_STR 144 +# define RSA_F_PKEY_RSA_SIGN 142 +# define RSA_F_PKEY_RSA_VERIFY 154 +# define RSA_F_PKEY_RSA_VERIFYRECOVER 141 +# define RSA_F_RSA_BUILTIN_KEYGEN 129 +# define RSA_F_RSA_CHECK_KEY 123 +# define RSA_F_RSA_EAY_PRIVATE_DECRYPT 101 +# define RSA_F_RSA_EAY_PRIVATE_ENCRYPT 102 +# define RSA_F_RSA_EAY_PUBLIC_DECRYPT 103 +# define RSA_F_RSA_EAY_PUBLIC_ENCRYPT 104 +# define RSA_F_RSA_GENERATE_KEY 105 +# define RSA_F_RSA_GENERATE_KEY_EX 155 +# define RSA_F_RSA_ITEM_VERIFY 156 +# define RSA_F_RSA_MEMORY_LOCK 130 +# define RSA_F_RSA_NEW_METHOD 106 +# define RSA_F_RSA_NULL 124 +# define RSA_F_RSA_NULL_MOD_EXP 131 +# define RSA_F_RSA_NULL_PRIVATE_DECRYPT 132 +# define RSA_F_RSA_NULL_PRIVATE_ENCRYPT 133 +# define RSA_F_RSA_NULL_PUBLIC_DECRYPT 134 +# define RSA_F_RSA_NULL_PUBLIC_ENCRYPT 135 +# define RSA_F_RSA_PADDING_ADD_NONE 107 +# define RSA_F_RSA_PADDING_ADD_PKCS1_OAEP 121 +# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS 125 +# define RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1 148 +# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1 108 +# define RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2 109 +# define RSA_F_RSA_PADDING_ADD_SSLV23 110 +# define RSA_F_RSA_PADDING_ADD_X931 127 +# define RSA_F_RSA_PADDING_CHECK_NONE 111 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP 122 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1 112 +# define RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2 113 +# define RSA_F_RSA_PADDING_CHECK_SSLV23 114 +# define RSA_F_RSA_PADDING_CHECK_X931 128 +# define RSA_F_RSA_PRINT 115 +# define RSA_F_RSA_PRINT_FP 116 +# define RSA_F_RSA_PRIVATE_DECRYPT 150 +# define RSA_F_RSA_PRIVATE_ENCRYPT 151 +# define RSA_F_RSA_PRIV_DECODE 137 +# define RSA_F_RSA_PRIV_ENCODE 138 +# define RSA_F_RSA_PUBLIC_DECRYPT 152 +# define RSA_F_RSA_PUBLIC_ENCRYPT 153 +# define RSA_F_RSA_PUB_DECODE 139 +# define RSA_F_RSA_SETUP_BLINDING 136 +# define RSA_F_RSA_SIGN 117 +# define RSA_F_RSA_SIGN_ASN1_OCTET_STRING 118 +# define RSA_F_RSA_VERIFY 119 +# define RSA_F_RSA_VERIFY_ASN1_OCTET_STRING 120 +# define RSA_F_RSA_VERIFY_PKCS1_PSS 126 +# define RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1 149 + +/* Reason codes. */ +# define RSA_R_ALGORITHM_MISMATCH 100 +# define RSA_R_BAD_E_VALUE 101 +# define RSA_R_BAD_FIXED_HEADER_DECRYPT 102 +# define RSA_R_BAD_PAD_BYTE_COUNT 103 +# define RSA_R_BAD_SIGNATURE 104 +# define RSA_R_BLOCK_TYPE_IS_NOT_01 106 +# define RSA_R_BLOCK_TYPE_IS_NOT_02 107 +# define RSA_R_DATA_GREATER_THAN_MOD_LEN 108 +# define RSA_R_DATA_TOO_LARGE 109 +# define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 110 +# define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 132 +# define RSA_R_DATA_TOO_SMALL 111 +# define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 122 +# define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 112 +# define RSA_R_DMP1_NOT_CONGRUENT_TO_D 124 +# define RSA_R_DMQ1_NOT_CONGRUENT_TO_D 125 +# define RSA_R_D_E_NOT_CONGRUENT_TO_1 123 +# define RSA_R_FIRST_OCTET_INVALID 133 +# define RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 144 +# define RSA_R_INVALID_DIGEST_LENGTH 143 +# define RSA_R_INVALID_HEADER 137 +# define RSA_R_INVALID_KEYBITS 145 +# define RSA_R_INVALID_MESSAGE_LENGTH 131 +# define RSA_R_INVALID_MGF1_MD 156 +# define RSA_R_INVALID_PADDING 138 +# define RSA_R_INVALID_PADDING_MODE 141 +# define RSA_R_INVALID_PSS_PARAMETERS 149 +# define RSA_R_INVALID_PSS_SALTLEN 146 +# define RSA_R_INVALID_SALT_LENGTH 150 +# define RSA_R_INVALID_TRAILER 139 +# define RSA_R_INVALID_X931_DIGEST 142 +# define RSA_R_IQMP_NOT_INVERSE_OF_Q 126 +# define RSA_R_KEY_SIZE_TOO_SMALL 120 +# define RSA_R_LAST_OCTET_INVALID 134 +# define RSA_R_MODULUS_TOO_LARGE 105 +# define RSA_R_NON_FIPS_RSA_METHOD 157 +# define RSA_R_NO_PUBLIC_EXPONENT 140 +# define RSA_R_NULL_BEFORE_BLOCK_MISSING 113 +# define RSA_R_N_DOES_NOT_EQUAL_P_Q 127 +# define RSA_R_OAEP_DECODING_ERROR 121 +# define RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE 158 +# define RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 148 +# define RSA_R_PADDING_CHECK_FAILED 114 +# define RSA_R_PKCS_DECODING_ERROR 159 +# define RSA_R_P_NOT_PRIME 128 +# define RSA_R_Q_NOT_PRIME 129 +# define RSA_R_RSA_OPERATIONS_NOT_SUPPORTED 130 +# define RSA_R_SLEN_CHECK_FAILED 136 +# define RSA_R_SLEN_RECOVERY_FAILED 135 +# define RSA_R_SSLV3_ROLLBACK_ATTACK 115 +# define RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD 116 +# define RSA_R_UNKNOWN_ALGORITHM_TYPE 117 +# define RSA_R_UNKNOWN_MASK_DIGEST 151 +# define RSA_R_UNKNOWN_PADDING_TYPE 118 +# define RSA_R_UNKNOWN_PSS_DIGEST 152 +# define RSA_R_UNSUPPORTED_MASK_ALGORITHM 153 +# define RSA_R_UNSUPPORTED_MASK_PARAMETER 154 +# define RSA_R_UNSUPPORTED_SIGNATURE_TYPE 155 +# define RSA_R_VALUE_MISSING 147 +# define RSA_R_WRONG_SIGNATURE_LENGTH 119 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/rsa/rsa_ameth.c b/libs/openssl/crypto/rsa/rsa_ameth.c new file mode 100644 index 00000000..c7f1148a --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_ameth.c @@ -0,0 +1,649 @@ +/* crypto/rsa/rsa_ameth.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#ifndef OPENSSL_NO_CMS +# include +#endif +#include "asn1_locl.h" + +static int rsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) +{ + unsigned char *penc = NULL; + int penclen; + penclen = i2d_RSAPublicKey(pkey->pkey.rsa, &penc); + if (penclen <= 0) + return 0; + if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_RSA), + V_ASN1_NULL, NULL, penc, penclen)) + return 1; + + OPENSSL_free(penc); + return 0; +} + +static int rsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) +{ + const unsigned char *p; + int pklen; + RSA *rsa = NULL; + if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, NULL, pubkey)) + return 0; + if (!(rsa = d2i_RSAPublicKey(NULL, &p, pklen))) { + RSAerr(RSA_F_RSA_PUB_DECODE, ERR_R_RSA_LIB); + return 0; + } + EVP_PKEY_assign_RSA(pkey, rsa); + return 1; +} + +static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) +{ + if (BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) != 0 + || BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) != 0) + return 0; + return 1; +} + +static int old_rsa_priv_decode(EVP_PKEY *pkey, + const unsigned char **pder, int derlen) +{ + RSA *rsa; + if (!(rsa = d2i_RSAPrivateKey(NULL, pder, derlen))) { + RSAerr(RSA_F_OLD_RSA_PRIV_DECODE, ERR_R_RSA_LIB); + return 0; + } + EVP_PKEY_assign_RSA(pkey, rsa); + return 1; +} + +static int old_rsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) +{ + return i2d_RSAPrivateKey(pkey->pkey.rsa, pder); +} + +static int rsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) +{ + unsigned char *rk = NULL; + int rklen; + rklen = i2d_RSAPrivateKey(pkey->pkey.rsa, &rk); + + if (rklen <= 0) { + RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_rsaEncryption), 0, + V_ASN1_NULL, NULL, rk, rklen)) { + RSAerr(RSA_F_RSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; +} + +static int rsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) +{ + const unsigned char *p; + int pklen; + if (!PKCS8_pkey_get0(NULL, &p, &pklen, NULL, p8)) + return 0; + return old_rsa_priv_decode(pkey, &p, pklen); +} + +static int int_rsa_size(const EVP_PKEY *pkey) +{ + return RSA_size(pkey->pkey.rsa); +} + +static int rsa_bits(const EVP_PKEY *pkey) +{ + return BN_num_bits(pkey->pkey.rsa->n); +} + +static void int_rsa_free(EVP_PKEY *pkey) +{ + RSA_free(pkey->pkey.rsa); +} + +static void update_buflen(const BIGNUM *b, size_t *pbuflen) +{ + size_t i; + if (!b) + return; + if (*pbuflen < (i = (size_t)BN_num_bytes(b))) + *pbuflen = i; +} + +static int do_rsa_print(BIO *bp, const RSA *x, int off, int priv) +{ + char *str; + const char *s; + unsigned char *m = NULL; + int ret = 0, mod_len = 0; + size_t buf_len = 0; + + update_buflen(x->n, &buf_len); + update_buflen(x->e, &buf_len); + + if (priv) { + update_buflen(x->d, &buf_len); + update_buflen(x->p, &buf_len); + update_buflen(x->q, &buf_len); + update_buflen(x->dmp1, &buf_len); + update_buflen(x->dmq1, &buf_len); + update_buflen(x->iqmp, &buf_len); + } + + m = (unsigned char *)OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + RSAerr(RSA_F_DO_RSA_PRINT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (x->n != NULL) + mod_len = BN_num_bits(x->n); + + if (!BIO_indent(bp, off, 128)) + goto err; + + if (priv && x->d) { + if (BIO_printf(bp, "Private-Key: (%d bit)\n", mod_len) + <= 0) + goto err; + str = "modulus:"; + s = "publicExponent:"; + } else { + if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) + <= 0) + goto err; + str = "Modulus:"; + s = "Exponent:"; + } + if (!ASN1_bn_print(bp, str, x->n, m, off)) + goto err; + if (!ASN1_bn_print(bp, s, x->e, m, off)) + goto err; + if (priv) { + if (!ASN1_bn_print(bp, "privateExponent:", x->d, m, off)) + goto err; + if (!ASN1_bn_print(bp, "prime1:", x->p, m, off)) + goto err; + if (!ASN1_bn_print(bp, "prime2:", x->q, m, off)) + goto err; + if (!ASN1_bn_print(bp, "exponent1:", x->dmp1, m, off)) + goto err; + if (!ASN1_bn_print(bp, "exponent2:", x->dmq1, m, off)) + goto err; + if (!ASN1_bn_print(bp, "coefficient:", x->iqmp, m, off)) + goto err; + } + ret = 1; + err: + if (m != NULL) + OPENSSL_free(m); + return (ret); +} + +static int rsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_rsa_print(bp, pkey->pkey.rsa, indent, 0); +} + +static int rsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *ctx) +{ + return do_rsa_print(bp, pkey->pkey.rsa, indent, 1); +} + +static RSA_PSS_PARAMS *rsa_pss_decode(const X509_ALGOR *alg, + X509_ALGOR **pmaskHash) +{ + const unsigned char *p; + int plen; + RSA_PSS_PARAMS *pss; + + *pmaskHash = NULL; + + if (!alg->parameter || alg->parameter->type != V_ASN1_SEQUENCE) + return NULL; + p = alg->parameter->value.sequence->data; + plen = alg->parameter->value.sequence->length; + pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen); + + if (!pss) + return NULL; + + if (pss->maskGenAlgorithm) { + ASN1_TYPE *param = pss->maskGenAlgorithm->parameter; + if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) == NID_mgf1 + && param && param->type == V_ASN1_SEQUENCE) { + p = param->value.sequence->data; + plen = param->value.sequence->length; + *pmaskHash = d2i_X509_ALGOR(NULL, &p, plen); + } + } + + return pss; +} + +static int rsa_pss_param_print(BIO *bp, RSA_PSS_PARAMS *pss, + X509_ALGOR *maskHash, int indent) +{ + int rv = 0; + if (!pss) { + if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) + return 0; + return 1; + } + if (BIO_puts(bp, "\n") <= 0) + goto err; + if (!BIO_indent(bp, indent, 128)) + goto err; + if (BIO_puts(bp, "Hash Algorithm: ") <= 0) + goto err; + + if (pss->hashAlgorithm) { + if (i2a_ASN1_OBJECT(bp, pss->hashAlgorithm->algorithm) <= 0) + goto err; + } else if (BIO_puts(bp, "sha1 (default)") <= 0) + goto err; + + if (BIO_puts(bp, "\n") <= 0) + goto err; + + if (!BIO_indent(bp, indent, 128)) + goto err; + + if (BIO_puts(bp, "Mask Algorithm: ") <= 0) + goto err; + if (pss->maskGenAlgorithm) { + if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0) + goto err; + if (BIO_puts(bp, " with ") <= 0) + goto err; + if (maskHash) { + if (i2a_ASN1_OBJECT(bp, maskHash->algorithm) <= 0) + goto err; + } else if (BIO_puts(bp, "INVALID") <= 0) + goto err; + } else if (BIO_puts(bp, "mgf1 with sha1 (default)") <= 0) + goto err; + BIO_puts(bp, "\n"); + + if (!BIO_indent(bp, indent, 128)) + goto err; + if (BIO_puts(bp, "Salt Length: 0x") <= 0) + goto err; + if (pss->saltLength) { + if (i2a_ASN1_INTEGER(bp, pss->saltLength) <= 0) + goto err; + } else if (BIO_puts(bp, "14 (default)") <= 0) + goto err; + BIO_puts(bp, "\n"); + + if (!BIO_indent(bp, indent, 128)) + goto err; + if (BIO_puts(bp, "Trailer Field: 0x") <= 0) + goto err; + if (pss->trailerField) { + if (i2a_ASN1_INTEGER(bp, pss->trailerField) <= 0) + goto err; + } else if (BIO_puts(bp, "BC (default)") <= 0) + goto err; + BIO_puts(bp, "\n"); + + rv = 1; + + err: + return rv; + +} + +static int rsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, + const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) +{ + if (OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss) { + int rv; + RSA_PSS_PARAMS *pss; + X509_ALGOR *maskHash; + pss = rsa_pss_decode(sigalg, &maskHash); + rv = rsa_pss_param_print(bp, pss, maskHash, indent); + if (pss) + RSA_PSS_PARAMS_free(pss); + if (maskHash) + X509_ALGOR_free(maskHash); + if (!rv) + return 0; + } else if (!sig && BIO_puts(bp, "\n") <= 0) + return 0; + if (sig) + return X509_signature_dump(bp, sig, indent); + return 1; +} + +static int rsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) +{ + X509_ALGOR *alg = NULL; + switch (op) { + + case ASN1_PKEY_CTRL_PKCS7_SIGN: + if (arg1 == 0) + PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, NULL, &alg); + break; + + case ASN1_PKEY_CTRL_PKCS7_ENCRYPT: + if (arg1 == 0) + PKCS7_RECIP_INFO_get0_alg(arg2, &alg); + break; +#ifndef OPENSSL_NO_CMS + case ASN1_PKEY_CTRL_CMS_SIGN: + if (arg1 == 0) + CMS_SignerInfo_get0_algs(arg2, NULL, NULL, NULL, &alg); + break; + + case ASN1_PKEY_CTRL_CMS_ENVELOPE: + if (arg1 == 0) + CMS_RecipientInfo_ktri_get0_algs(arg2, NULL, NULL, &alg); + break; +#endif + + case ASN1_PKEY_CTRL_DEFAULT_MD_NID: + *(int *)arg2 = NID_sha1; + return 1; + + default: + return -2; + + } + + if (alg) + X509_ALGOR_set0(alg, OBJ_nid2obj(NID_rsaEncryption), V_ASN1_NULL, 0); + + return 1; + +} + +/* + * Customised RSA item verification routine. This is called when a signature + * is encountered requiring special handling. We currently only handle PSS. + */ + +static int rsa_item_verify(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *sigalg, ASN1_BIT_STRING *sig, + EVP_PKEY *pkey) +{ + int rv = -1; + int saltlen; + const EVP_MD *mgf1md = NULL, *md = NULL; + RSA_PSS_PARAMS *pss; + X509_ALGOR *maskHash; + EVP_PKEY_CTX *pkctx; + /* Sanity check: make sure it is PSS */ + if (OBJ_obj2nid(sigalg->algorithm) != NID_rsassaPss) { + RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_SIGNATURE_TYPE); + return -1; + } + /* Decode PSS parameters */ + pss = rsa_pss_decode(sigalg, &maskHash); + + if (pss == NULL) { + RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_PSS_PARAMETERS); + goto err; + } + /* Check mask and lookup mask hash algorithm */ + if (pss->maskGenAlgorithm) { + if (OBJ_obj2nid(pss->maskGenAlgorithm->algorithm) != NID_mgf1) { + RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_ALGORITHM); + goto err; + } + if (!maskHash) { + RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNSUPPORTED_MASK_PARAMETER); + goto err; + } + mgf1md = EVP_get_digestbyobj(maskHash->algorithm); + if (mgf1md == NULL) { + RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_MASK_DIGEST); + goto err; + } + } else + mgf1md = EVP_sha1(); + + if (pss->hashAlgorithm) { + md = EVP_get_digestbyobj(pss->hashAlgorithm->algorithm); + if (md == NULL) { + RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_UNKNOWN_PSS_DIGEST); + goto err; + } + } else + md = EVP_sha1(); + + if (pss->saltLength) { + saltlen = ASN1_INTEGER_get(pss->saltLength); + + /* + * Could perform more salt length sanity checks but the main RSA + * routines will trap other invalid values anyway. + */ + if (saltlen < 0) { + RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_SALT_LENGTH); + goto err; + } + } else + saltlen = 20; + + /* + * low-level routines support only trailer field 0xbc (value 1) and + * PKCS#1 says we should reject any other value anyway. + */ + if (pss->trailerField && ASN1_INTEGER_get(pss->trailerField) != 1) { + RSAerr(RSA_F_RSA_ITEM_VERIFY, RSA_R_INVALID_TRAILER); + goto err; + } + + /* We have all parameters now set up context */ + + if (!EVP_DigestVerifyInit(ctx, &pkctx, md, NULL, pkey)) + goto err; + + if (EVP_PKEY_CTX_set_rsa_padding(pkctx, RSA_PKCS1_PSS_PADDING) <= 0) + goto err; + + if (EVP_PKEY_CTX_set_rsa_pss_saltlen(pkctx, saltlen) <= 0) + goto err; + + if (EVP_PKEY_CTX_set_rsa_mgf1_md(pkctx, mgf1md) <= 0) + goto err; + /* Carry on */ + rv = 2; + + err: + RSA_PSS_PARAMS_free(pss); + if (maskHash) + X509_ALGOR_free(maskHash); + return rv; +} + +static int rsa_item_sign(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn, + X509_ALGOR *alg1, X509_ALGOR *alg2, + ASN1_BIT_STRING *sig) +{ + int pad_mode; + EVP_PKEY_CTX *pkctx = ctx->pctx; + if (EVP_PKEY_CTX_get_rsa_padding(pkctx, &pad_mode) <= 0) + return 0; + if (pad_mode == RSA_PKCS1_PADDING) + return 2; + if (pad_mode == RSA_PKCS1_PSS_PADDING) { + const EVP_MD *sigmd, *mgf1md; + RSA_PSS_PARAMS *pss = NULL; + X509_ALGOR *mgf1alg = NULL; + ASN1_STRING *os1 = NULL, *os2 = NULL; + EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(pkctx); + int saltlen, rv = 0; + sigmd = EVP_MD_CTX_md(ctx); + if (EVP_PKEY_CTX_get_rsa_mgf1_md(pkctx, &mgf1md) <= 0) + goto err; + if (!EVP_PKEY_CTX_get_rsa_pss_saltlen(pkctx, &saltlen)) + goto err; + if (saltlen == -1) + saltlen = EVP_MD_size(sigmd); + else if (saltlen == -2) { + saltlen = EVP_PKEY_size(pk) - EVP_MD_size(sigmd) - 2; + if (((EVP_PKEY_bits(pk) - 1) & 0x7) == 0) + saltlen--; + } + pss = RSA_PSS_PARAMS_new(); + if (!pss) + goto err; + if (saltlen != 20) { + pss->saltLength = ASN1_INTEGER_new(); + if (!pss->saltLength) + goto err; + if (!ASN1_INTEGER_set(pss->saltLength, saltlen)) + goto err; + } + if (EVP_MD_type(sigmd) != NID_sha1) { + pss->hashAlgorithm = X509_ALGOR_new(); + if (!pss->hashAlgorithm) + goto err; + X509_ALGOR_set_md(pss->hashAlgorithm, sigmd); + } + if (EVP_MD_type(mgf1md) != NID_sha1) { + ASN1_STRING *stmp = NULL; + /* need to embed algorithm ID inside another */ + mgf1alg = X509_ALGOR_new(); + X509_ALGOR_set_md(mgf1alg, mgf1md); + if (!ASN1_item_pack(mgf1alg, ASN1_ITEM_rptr(X509_ALGOR), &stmp)) + goto err; + pss->maskGenAlgorithm = X509_ALGOR_new(); + if (!pss->maskGenAlgorithm) + goto err; + X509_ALGOR_set0(pss->maskGenAlgorithm, + OBJ_nid2obj(NID_mgf1), V_ASN1_SEQUENCE, stmp); + } + /* Finally create string with pss parameter encoding. */ + if (!ASN1_item_pack(pss, ASN1_ITEM_rptr(RSA_PSS_PARAMS), &os1)) + goto err; + if (alg2) { + os2 = ASN1_STRING_dup(os1); + if (!os2) + goto err; + X509_ALGOR_set0(alg2, OBJ_nid2obj(NID_rsassaPss), + V_ASN1_SEQUENCE, os2); + } + X509_ALGOR_set0(alg1, OBJ_nid2obj(NID_rsassaPss), + V_ASN1_SEQUENCE, os1); + os1 = os2 = NULL; + rv = 3; + err: + if (mgf1alg) + X509_ALGOR_free(mgf1alg); + if (pss) + RSA_PSS_PARAMS_free(pss); + if (os1) + ASN1_STRING_free(os1); + return rv; + + } + return 2; +} + +const EVP_PKEY_ASN1_METHOD rsa_asn1_meths[] = { + { + EVP_PKEY_RSA, + EVP_PKEY_RSA, + ASN1_PKEY_SIGPARAM_NULL, + + "RSA", + "OpenSSL RSA method", + + rsa_pub_decode, + rsa_pub_encode, + rsa_pub_cmp, + rsa_pub_print, + + rsa_priv_decode, + rsa_priv_encode, + rsa_priv_print, + + int_rsa_size, + rsa_bits, + + 0, 0, 0, 0, 0, 0, + + rsa_sig_print, + int_rsa_free, + rsa_pkey_ctrl, + old_rsa_priv_decode, + old_rsa_priv_encode, + rsa_item_verify, + rsa_item_sign}, + + { + EVP_PKEY_RSA2, + EVP_PKEY_RSA, + ASN1_PKEY_ALIAS} +}; diff --git a/libs/openssl/crypto/rsa/rsa_asn1.c b/libs/openssl/crypto/rsa/rsa_asn1.c new file mode 100644 index 00000000..3d82c1d0 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_asn1.c @@ -0,0 +1,123 @@ +/* rsa_asn1.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +/* Override the default free and new methods */ +static int rsa_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + if (operation == ASN1_OP_NEW_PRE) { + *pval = (ASN1_VALUE *)RSA_new(); + if (*pval) + return 2; + return 0; + } else if (operation == ASN1_OP_FREE_PRE) { + RSA_free((RSA *)*pval); + *pval = NULL; + return 2; + } + return 1; +} + +ASN1_SEQUENCE_cb(RSAPrivateKey, rsa_cb) = { + ASN1_SIMPLE(RSA, version, LONG), + ASN1_SIMPLE(RSA, n, BIGNUM), + ASN1_SIMPLE(RSA, e, BIGNUM), + ASN1_SIMPLE(RSA, d, BIGNUM), + ASN1_SIMPLE(RSA, p, BIGNUM), + ASN1_SIMPLE(RSA, q, BIGNUM), + ASN1_SIMPLE(RSA, dmp1, BIGNUM), + ASN1_SIMPLE(RSA, dmq1, BIGNUM), + ASN1_SIMPLE(RSA, iqmp, BIGNUM) +} ASN1_SEQUENCE_END_cb(RSA, RSAPrivateKey) + + +ASN1_SEQUENCE_cb(RSAPublicKey, rsa_cb) = { + ASN1_SIMPLE(RSA, n, BIGNUM), + ASN1_SIMPLE(RSA, e, BIGNUM), +} ASN1_SEQUENCE_END_cb(RSA, RSAPublicKey) + +ASN1_SEQUENCE(RSA_PSS_PARAMS) = { + ASN1_EXP_OPT(RSA_PSS_PARAMS, hashAlgorithm, X509_ALGOR,0), + ASN1_EXP_OPT(RSA_PSS_PARAMS, maskGenAlgorithm, X509_ALGOR,1), + ASN1_EXP_OPT(RSA_PSS_PARAMS, saltLength, ASN1_INTEGER,2), + ASN1_EXP_OPT(RSA_PSS_PARAMS, trailerField, ASN1_INTEGER,3) +} ASN1_SEQUENCE_END(RSA_PSS_PARAMS) + +IMPLEMENT_ASN1_FUNCTIONS(RSA_PSS_PARAMS) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPrivateKey, RSAPrivateKey) + +IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(RSA, RSAPublicKey, RSAPublicKey) + +RSA *RSAPublicKey_dup(RSA *rsa) +{ + return ASN1_item_dup(ASN1_ITEM_rptr(RSAPublicKey), rsa); +} + +RSA *RSAPrivateKey_dup(RSA *rsa) +{ + return ASN1_item_dup(ASN1_ITEM_rptr(RSAPrivateKey), rsa); +} diff --git a/libs/openssl/crypto/rsa/rsa_chk.c b/libs/openssl/crypto/rsa/rsa_chk.c new file mode 100644 index 00000000..607faa00 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_chk.c @@ -0,0 +1,214 @@ +/* crypto/rsa/rsa_chk.c */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + */ + +#include +#include +#include + +int RSA_check_key(const RSA *key) +{ + BIGNUM *i, *j, *k, *l, *m; + BN_CTX *ctx; + int r; + int ret = 1; + + if (!key->p || !key->q || !key->n || !key->e || !key->d) { + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_VALUE_MISSING); + return 0; + } + + i = BN_new(); + j = BN_new(); + k = BN_new(); + l = BN_new(); + m = BN_new(); + ctx = BN_CTX_new(); + if (i == NULL || j == NULL || k == NULL || l == NULL || + m == NULL || ctx == NULL) { + ret = -1; + RSAerr(RSA_F_RSA_CHECK_KEY, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* p prime? */ + r = BN_is_prime_ex(key->p, BN_prime_checks, NULL, NULL); + if (r != 1) { + ret = r; + if (r != 0) + goto err; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_P_NOT_PRIME); + } + + /* q prime? */ + r = BN_is_prime_ex(key->q, BN_prime_checks, NULL, NULL); + if (r != 1) { + ret = r; + if (r != 0) + goto err; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_Q_NOT_PRIME); + } + + /* n = p*q? */ + r = BN_mul(i, key->p, key->q, ctx); + if (!r) { + ret = -1; + goto err; + } + + if (BN_cmp(i, key->n) != 0) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_N_DOES_NOT_EQUAL_P_Q); + } + + /* d*e = 1 mod lcm(p-1,q-1)? */ + + r = BN_sub(i, key->p, BN_value_one()); + if (!r) { + ret = -1; + goto err; + } + r = BN_sub(j, key->q, BN_value_one()); + if (!r) { + ret = -1; + goto err; + } + + /* now compute k = lcm(i,j) */ + r = BN_mul(l, i, j, ctx); + if (!r) { + ret = -1; + goto err; + } + r = BN_gcd(m, i, j, ctx); + if (!r) { + ret = -1; + goto err; + } + r = BN_div(k, NULL, l, m, ctx); /* remainder is 0 */ + if (!r) { + ret = -1; + goto err; + } + + r = BN_mod_mul(i, key->d, key->e, k, ctx); + if (!r) { + ret = -1; + goto err; + } + + if (!BN_is_one(i)) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_D_E_NOT_CONGRUENT_TO_1); + } + + if (key->dmp1 != NULL && key->dmq1 != NULL && key->iqmp != NULL) { + /* dmp1 = d mod (p-1)? */ + r = BN_sub(i, key->p, BN_value_one()); + if (!r) { + ret = -1; + goto err; + } + + r = BN_mod(j, key->d, i, ctx); + if (!r) { + ret = -1; + goto err; + } + + if (BN_cmp(j, key->dmp1) != 0) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMP1_NOT_CONGRUENT_TO_D); + } + + /* dmq1 = d mod (q-1)? */ + r = BN_sub(i, key->q, BN_value_one()); + if (!r) { + ret = -1; + goto err; + } + + r = BN_mod(j, key->d, i, ctx); + if (!r) { + ret = -1; + goto err; + } + + if (BN_cmp(j, key->dmq1) != 0) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_DMQ1_NOT_CONGRUENT_TO_D); + } + + /* iqmp = q^-1 mod p? */ + if (!BN_mod_inverse(i, key->q, key->p, ctx)) { + ret = -1; + goto err; + } + + if (BN_cmp(i, key->iqmp) != 0) { + ret = 0; + RSAerr(RSA_F_RSA_CHECK_KEY, RSA_R_IQMP_NOT_INVERSE_OF_Q); + } + } + + err: + if (i != NULL) + BN_free(i); + if (j != NULL) + BN_free(j); + if (k != NULL) + BN_free(k); + if (l != NULL) + BN_free(l); + if (m != NULL) + BN_free(m); + if (ctx != NULL) + BN_CTX_free(ctx); + return (ret); +} diff --git a/libs/openssl/crypto/rsa/rsa_crpt.c b/libs/openssl/crypto/rsa/rsa_crpt.c new file mode 100644 index 00000000..5c416b53 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_crpt.c @@ -0,0 +1,247 @@ +/* crypto/rsa/rsa_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif + +int RSA_size(const RSA *r) +{ + return (BN_num_bytes(r->n)); +} + +int RSA_public_encrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_RSA_PUBLIC_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD); + return -1; + } +#endif + return (rsa->meth->rsa_pub_enc(flen, from, to, rsa, padding)); +} + +int RSA_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_RSA_PRIVATE_ENCRYPT, RSA_R_NON_FIPS_RSA_METHOD); + return -1; + } +#endif + return (rsa->meth->rsa_priv_enc(flen, from, to, rsa, padding)); +} + +int RSA_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_RSA_PRIVATE_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD); + return -1; + } +#endif + return (rsa->meth->rsa_priv_dec(flen, from, to, rsa, padding)); +} + +int RSA_public_decrypt(int flen, const unsigned char *from, unsigned char *to, + RSA *rsa, int padding) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_RSA_PUBLIC_DECRYPT, RSA_R_NON_FIPS_RSA_METHOD); + return -1; + } +#endif + return (rsa->meth->rsa_pub_dec(flen, from, to, rsa, padding)); +} + +int RSA_flags(const RSA *r) +{ + return ((r == NULL) ? 0 : r->meth->flags); +} + +void RSA_blinding_off(RSA *rsa) +{ + if (rsa->blinding != NULL) { + BN_BLINDING_free(rsa->blinding); + rsa->blinding = NULL; + } + rsa->flags &= ~RSA_FLAG_BLINDING; + rsa->flags |= RSA_FLAG_NO_BLINDING; +} + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) +{ + int ret = 0; + + if (rsa->blinding != NULL) + RSA_blinding_off(rsa); + + rsa->blinding = RSA_setup_blinding(rsa, ctx); + if (rsa->blinding == NULL) + goto err; + + rsa->flags |= RSA_FLAG_BLINDING; + rsa->flags &= ~RSA_FLAG_NO_BLINDING; + ret = 1; + err: + return (ret); +} + +static BIGNUM *rsa_get_public_exp(const BIGNUM *d, const BIGNUM *p, + const BIGNUM *q, BN_CTX *ctx) +{ + BIGNUM *ret = NULL, *r0, *r1, *r2; + + if (d == NULL || p == NULL || q == NULL) + return NULL; + + BN_CTX_start(ctx); + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + if (r2 == NULL) + goto err; + + if (!BN_sub(r1, p, BN_value_one())) + goto err; + if (!BN_sub(r2, q, BN_value_one())) + goto err; + if (!BN_mul(r0, r1, r2, ctx)) + goto err; + + ret = BN_mod_inverse(NULL, d, r0, ctx); + err: + BN_CTX_end(ctx); + return ret; +} + +BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) +{ + BIGNUM local_n; + BIGNUM *e, *n; + BN_CTX *ctx; + BN_BLINDING *ret = NULL; + + if (in_ctx == NULL) { + if ((ctx = BN_CTX_new()) == NULL) + return 0; + } else + ctx = in_ctx; + + BN_CTX_start(ctx); + e = BN_CTX_get(ctx); + if (e == NULL) { + RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (rsa->e == NULL) { + e = rsa_get_public_exp(rsa->d, rsa->p, rsa->q, ctx); + if (e == NULL) { + RSAerr(RSA_F_RSA_SETUP_BLINDING, RSA_R_NO_PUBLIC_EXPONENT); + goto err; + } + } else + e = rsa->e; + + if ((RAND_status() == 0) && rsa->d != NULL && rsa->d->d != NULL) { + /* + * if PRNG is not properly seeded, resort to secret exponent as + * unpredictable seed + */ + RAND_add(rsa->d->d, rsa->d->dmax * sizeof rsa->d->d[0], 0.0); + } + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + /* Set BN_FLG_CONSTTIME flag */ + n = &local_n; + BN_with_flags(n, rsa->n, BN_FLG_CONSTTIME); + } else + n = rsa->n; + + ret = BN_BLINDING_create_param(NULL, e, n, ctx, + rsa->meth->bn_mod_exp, rsa->_method_mod_n); + if (ret == NULL) { + RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB); + goto err; + } + CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret)); + err: + BN_CTX_end(ctx); + if (in_ctx == NULL) + BN_CTX_free(ctx); + if (rsa->e == NULL) + BN_free(e); + + return ret; +} diff --git a/libs/openssl/crypto/rsa/rsa_depr.c b/libs/openssl/crypto/rsa/rsa_depr.c new file mode 100644 index 00000000..32f0c888 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_depr.c @@ -0,0 +1,107 @@ +/* crypto/rsa/rsa_depr.c */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NB: This file contains deprecated functions (compatibility wrappers to the + * "new" versions). + */ + +#include +#include +#include "cryptlib.h" +#include +#include + +#ifdef OPENSSL_NO_DEPRECATED + +static void *dummy = &dummy; + +#else + +RSA *RSA_generate_key(int bits, unsigned long e_value, + void (*callback) (int, int, void *), void *cb_arg) +{ + BN_GENCB cb; + int i; + RSA *rsa = RSA_new(); + BIGNUM *e = BN_new(); + + if (!rsa || !e) + goto err; + + /* + * The problem is when building with 8, 16, or 32 BN_ULONG, unsigned long + * can be larger + */ + for (i = 0; i < (int)sizeof(unsigned long) * 8; i++) { + if (e_value & (1UL << i)) + if (BN_set_bit(e, i) == 0) + goto err; + } + + BN_GENCB_set_old(&cb, callback, cb_arg); + + if (RSA_generate_key_ex(rsa, bits, e, &cb)) { + BN_free(e); + return rsa; + } + err: + if (e) + BN_free(e); + if (rsa) + RSA_free(rsa); + return 0; +} +#endif diff --git a/libs/openssl/crypto/rsa/rsa_eay.c b/libs/openssl/crypto/rsa/rsa_eay.c new file mode 100644 index 00000000..b147fff8 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_eay.c @@ -0,0 +1,904 @@ +/* crypto/rsa/rsa_eay.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +#ifndef RSA_NULL + +static int RSA_eay_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int RSA_eay_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int RSA_eay_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int RSA_eay_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *i, RSA *rsa, + BN_CTX *ctx); +static int RSA_eay_init(RSA *rsa); +static int RSA_eay_finish(RSA *rsa); +static RSA_METHOD rsa_pkcs1_eay_meth = { + "Eric Young's PKCS#1 RSA", + RSA_eay_public_encrypt, + RSA_eay_public_decrypt, /* signature verification */ + RSA_eay_private_encrypt, /* signing */ + RSA_eay_private_decrypt, + RSA_eay_mod_exp, + BN_mod_exp_mont, /* XXX probably we should not use Montgomery + * if e == 3 */ + RSA_eay_init, + RSA_eay_finish, + 0, /* flags */ + NULL, + 0, /* rsa_sign */ + 0, /* rsa_verify */ + NULL /* rsa_keygen */ +}; + +const RSA_METHOD *RSA_PKCS1_SSLeay(void) +{ + return (&rsa_pkcs1_eay_meth); +} + +static int RSA_eay_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + BIGNUM *f, *ret; + int i, j, k, num = 0, r = -1; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_MODULUS_TOO_LARGE); + return -1; + } + + if (BN_ucmp(rsa->n, rsa->e) <= 0) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + + /* for large moduli, enforce exponent limit */ + if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { + if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if (!f || !ret || !buf) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_2(buf, num, from, flen); + break; +# ifndef OPENSSL_NO_SHA + case RSA_PKCS1_OAEP_PADDING: + i = RSA_padding_add_PKCS1_OAEP(buf, num, from, flen, NULL, 0); + break; +# endif + case RSA_SSLV23_PADDING: + i = RSA_padding_add_SSLv23(buf, num, from, flen); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, num, from, flen); + break; + default: + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (i <= 0) + goto err; + + if (BN_bin2bn(buf, num, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + /* usually the padding functions would catch this */ + RSAerr(RSA_F_RSA_EAY_PUBLIC_ENCRYPT, + RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked + (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + goto err; + + if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + + /* + * put in leading 0 bytes if the number is less than the length of the + * modulus + */ + j = BN_num_bytes(ret); + i = BN_bn2bin(ret, &(to[num - j])); + for (k = 0; k < (num - i); k++) + to[k] = 0; + + r = num; + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) { + OPENSSL_cleanse(buf, num); + OPENSSL_free(buf); + } + return (r); +} + +static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) +{ + BN_BLINDING *ret; + int got_write_lock = 0; + CRYPTO_THREADID cur; + + CRYPTO_r_lock(CRYPTO_LOCK_RSA); + + if (rsa->blinding == NULL) { + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + CRYPTO_w_lock(CRYPTO_LOCK_RSA); + got_write_lock = 1; + + if (rsa->blinding == NULL) + rsa->blinding = RSA_setup_blinding(rsa, ctx); + } + + ret = rsa->blinding; + if (ret == NULL) + goto err; + + CRYPTO_THREADID_current(&cur); + if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret))) { + /* rsa->blinding is ours! */ + + *local = 1; + } else { + /* resort to rsa->mt_blinding instead */ + + /* + * instructs rsa_blinding_convert(), rsa_blinding_invert() that the + * BN_BLINDING is shared, meaning that accesses require locks, and + * that the blinding factor must be stored outside the BN_BLINDING + */ + *local = 0; + + if (rsa->mt_blinding == NULL) { + if (!got_write_lock) { + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + CRYPTO_w_lock(CRYPTO_LOCK_RSA); + got_write_lock = 1; + } + + if (rsa->mt_blinding == NULL) + rsa->mt_blinding = RSA_setup_blinding(rsa, ctx); + } + ret = rsa->mt_blinding; + } + + err: + if (got_write_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_RSA); + else + CRYPTO_r_unlock(CRYPTO_LOCK_RSA); + return ret; +} + +static int rsa_blinding_convert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, + BN_CTX *ctx) +{ + if (unblind == NULL) + /* + * Local blinding: store the unblinding factor in BN_BLINDING. + */ + return BN_BLINDING_convert_ex(f, NULL, b, ctx); + else { + /* + * Shared blinding: store the unblinding factor outside BN_BLINDING. + */ + int ret; + CRYPTO_w_lock(CRYPTO_LOCK_RSA_BLINDING); + ret = BN_BLINDING_convert_ex(f, unblind, b, ctx); + CRYPTO_w_unlock(CRYPTO_LOCK_RSA_BLINDING); + return ret; + } +} + +static int rsa_blinding_invert(BN_BLINDING *b, BIGNUM *f, BIGNUM *unblind, + BN_CTX *ctx) +{ + /* + * For local blinding, unblind is set to NULL, and BN_BLINDING_invert_ex + * will use the unblinding factor stored in BN_BLINDING. If BN_BLINDING + * is shared between threads, unblind must be non-null: + * BN_BLINDING_invert_ex will then use the local unblinding factor, and + * will only read the modulus from BN_BLINDING. In both cases it's safe + * to access the blinding without a lock. + */ + return BN_BLINDING_invert_ex(f, unblind, b, ctx); +} + +/* signing */ +static int RSA_eay_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + BIGNUM *f, *ret, *res; + int i, j, k, num = 0, r = -1; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + int local_blinding = 0; + /* + * Used only if the blinding structure is shared. A non-NULL unblind + * instructs rsa_blinding_convert() and rsa_blinding_invert() to store + * the unblinding factor outside the blinding structure. + */ + BIGNUM *unblind = NULL; + BN_BLINDING *blinding = NULL; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if (!f || !ret || !buf) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_1(buf, num, from, flen); + break; + case RSA_X931_PADDING: + i = RSA_padding_add_X931(buf, num, from, flen); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, num, from, flen); + break; + case RSA_SSLV23_PADDING: + default: + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (i <= 0) + goto err; + + if (BN_bin2bn(buf, num, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + /* usually the padding functions would catch this */ + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, + RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { + blinding = rsa_get_blinding(rsa, &local_blinding, ctx); + if (blinding == NULL) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (blinding != NULL) { + if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_ENCRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!rsa_blinding_convert(blinding, f, unblind, ctx)) + goto err; + } + + if ((rsa->flags & RSA_FLAG_EXT_PKEY) || + ((rsa->p != NULL) && + (rsa->q != NULL) && + (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { + if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) + goto err; + } else { + BIGNUM local_d; + BIGNUM *d = NULL; + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + BN_init(&local_d); + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } else + d = rsa->d; + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked + (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + goto err; + + if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + } + + if (blinding) + if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) + goto err; + + if (padding == RSA_X931_PADDING) { + BN_sub(f, rsa->n, ret); + if (BN_cmp(ret, f) > 0) + res = f; + else + res = ret; + } else + res = ret; + + /* + * put in leading 0 bytes if the number is less than the length of the + * modulus + */ + j = BN_num_bytes(res); + i = BN_bn2bin(res, &(to[num - j])); + for (k = 0; k < (num - i); k++) + to[k] = 0; + + r = num; + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) { + OPENSSL_cleanse(buf, num); + OPENSSL_free(buf); + } + return (r); +} + +static int RSA_eay_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + BIGNUM *f, *ret; + int j, num = 0, r = -1; + unsigned char *p; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + int local_blinding = 0; + /* + * Used only if the blinding structure is shared. A non-NULL unblind + * instructs rsa_blinding_convert() and rsa_blinding_invert() to store + * the unblinding factor outside the blinding structure. + */ + BIGNUM *unblind = NULL; + BN_BLINDING *blinding = NULL; + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if (!f || !ret || !buf) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * This check was for equality but PGP does evil things and chops off the + * top '0' bytes + */ + if (flen > num) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, + RSA_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + /* make data into a big number */ + if (BN_bin2bn(from, (int)flen, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, + RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (!(rsa->flags & RSA_FLAG_NO_BLINDING)) { + blinding = rsa_get_blinding(rsa, &local_blinding, ctx); + if (blinding == NULL) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + if (blinding != NULL) { + if (!local_blinding && ((unblind = BN_CTX_get(ctx)) == NULL)) { + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!rsa_blinding_convert(blinding, f, unblind, ctx)) + goto err; + } + + /* do the decrypt */ + if ((rsa->flags & RSA_FLAG_EXT_PKEY) || + ((rsa->p != NULL) && + (rsa->q != NULL) && + (rsa->dmp1 != NULL) && (rsa->dmq1 != NULL) && (rsa->iqmp != NULL))) { + if (!rsa->meth->rsa_mod_exp(ret, f, rsa, ctx)) + goto err; + } else { + BIGNUM local_d; + BIGNUM *d = NULL; + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } else + d = rsa->d; + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked + (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + goto err; + if (!rsa->meth->bn_mod_exp(ret, f, d, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + } + + if (blinding) + if (!rsa_blinding_invert(blinding, ret, unblind, ctx)) + goto err; + + p = buf; + j = BN_bn2bin(ret, p); /* j is only used with no-padding mode */ + + switch (padding) { + case RSA_PKCS1_PADDING: + r = RSA_padding_check_PKCS1_type_2(to, num, buf, j, num); + break; +# ifndef OPENSSL_NO_SHA + case RSA_PKCS1_OAEP_PADDING: + r = RSA_padding_check_PKCS1_OAEP(to, num, buf, j, num, NULL, 0); + break; +# endif + case RSA_SSLV23_PADDING: + r = RSA_padding_check_SSLv23(to, num, buf, j, num); + break; + case RSA_NO_PADDING: + r = RSA_padding_check_none(to, num, buf, j, num); + break; + default: + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (r < 0) + RSAerr(RSA_F_RSA_EAY_PRIVATE_DECRYPT, RSA_R_PADDING_CHECK_FAILED); + + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) { + OPENSSL_cleanse(buf, num); + OPENSSL_free(buf); + } + return (r); +} + +/* signature verification */ +static int RSA_eay_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + BIGNUM *f, *ret; + int i, num = 0, r = -1; + unsigned char *p; + unsigned char *buf = NULL; + BN_CTX *ctx = NULL; + + if (BN_num_bits(rsa->n) > OPENSSL_RSA_MAX_MODULUS_BITS) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_MODULUS_TOO_LARGE); + return -1; + } + + if (BN_ucmp(rsa->n, rsa->e) <= 0) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + + /* for large moduli, enforce exponent limit */ + if (BN_num_bits(rsa->n) > OPENSSL_RSA_SMALL_MODULUS_BITS) { + if (BN_num_bits(rsa->e) > OPENSSL_RSA_MAX_PUBEXP_BITS) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_BAD_E_VALUE); + return -1; + } + } + + if ((ctx = BN_CTX_new()) == NULL) + goto err; + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + ret = BN_CTX_get(ctx); + num = BN_num_bytes(rsa->n); + buf = OPENSSL_malloc(num); + if (!f || !ret || !buf) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * This check was for equality but PGP does evil things and chops off the + * top '0' bytes + */ + if (flen > num) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_DATA_GREATER_THAN_MOD_LEN); + goto err; + } + + if (BN_bin2bn(from, flen, f) == NULL) + goto err; + + if (BN_ucmp(f, rsa->n) >= 0) { + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, + RSA_R_DATA_TOO_LARGE_FOR_MODULUS); + goto err; + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked + (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + goto err; + + if (!rsa->meth->bn_mod_exp(ret, f, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + + if ((padding == RSA_X931_PADDING) && ((ret->d[0] & 0xf) != 12)) + if (!BN_sub(ret, rsa->n, ret)) + goto err; + + p = buf; + i = BN_bn2bin(ret, p); + + switch (padding) { + case RSA_PKCS1_PADDING: + r = RSA_padding_check_PKCS1_type_1(to, num, buf, i, num); + break; + case RSA_X931_PADDING: + r = RSA_padding_check_X931(to, num, buf, i, num); + break; + case RSA_NO_PADDING: + r = RSA_padding_check_none(to, num, buf, i, num); + break; + default: + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + if (r < 0) + RSAerr(RSA_F_RSA_EAY_PUBLIC_DECRYPT, RSA_R_PADDING_CHECK_FAILED); + + err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (buf != NULL) { + OPENSSL_cleanse(buf, num); + OPENSSL_free(buf); + } + return (r); +} + +static int RSA_eay_mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) +{ + BIGNUM *r1, *m1, *vrfy; + BIGNUM local_dmp1, local_dmq1, local_c, local_r1; + BIGNUM *dmp1, *dmq1, *c, *pr1; + int ret = 0; + + BN_CTX_start(ctx); + r1 = BN_CTX_get(ctx); + m1 = BN_CTX_get(ctx); + vrfy = BN_CTX_get(ctx); + + { + BIGNUM local_p, local_q; + BIGNUM *p = NULL, *q = NULL; + + /* + * Make sure BN_mod_inverse in Montgomery intialization uses the + * BN_FLG_CONSTTIME flag (unless RSA_FLAG_NO_CONSTTIME is set) + */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + BN_init(&local_p); + p = &local_p; + BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); + + BN_init(&local_q); + q = &local_q; + BN_with_flags(q, rsa->q, BN_FLG_CONSTTIME); + } else { + p = rsa->p; + q = rsa->q; + } + + if (rsa->flags & RSA_FLAG_CACHE_PRIVATE) { + if (!BN_MONT_CTX_set_locked + (&rsa->_method_mod_p, CRYPTO_LOCK_RSA, p, ctx)) + goto err; + if (!BN_MONT_CTX_set_locked + (&rsa->_method_mod_q, CRYPTO_LOCK_RSA, q, ctx)) + goto err; + } + } + + if (rsa->flags & RSA_FLAG_CACHE_PUBLIC) + if (!BN_MONT_CTX_set_locked + (&rsa->_method_mod_n, CRYPTO_LOCK_RSA, rsa->n, ctx)) + goto err; + + /* compute I mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + c = &local_c; + BN_with_flags(c, I, BN_FLG_CONSTTIME); + if (!BN_mod(r1, c, rsa->q, ctx)) + goto err; + } else { + if (!BN_mod(r1, I, rsa->q, ctx)) + goto err; + } + + /* compute r1^dmq1 mod q */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + dmq1 = &local_dmq1; + BN_with_flags(dmq1, rsa->dmq1, BN_FLG_CONSTTIME); + } else + dmq1 = rsa->dmq1; + if (!rsa->meth->bn_mod_exp(m1, r1, dmq1, rsa->q, ctx, rsa->_method_mod_q)) + goto err; + + /* compute I mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + c = &local_c; + BN_with_flags(c, I, BN_FLG_CONSTTIME); + if (!BN_mod(r1, c, rsa->p, ctx)) + goto err; + } else { + if (!BN_mod(r1, I, rsa->p, ctx)) + goto err; + } + + /* compute r1^dmp1 mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + dmp1 = &local_dmp1; + BN_with_flags(dmp1, rsa->dmp1, BN_FLG_CONSTTIME); + } else + dmp1 = rsa->dmp1; + if (!rsa->meth->bn_mod_exp(r0, r1, dmp1, rsa->p, ctx, rsa->_method_mod_p)) + goto err; + + if (!BN_sub(r0, r0, m1)) + goto err; + /* + * This will help stop the size of r0 increasing, which does affect the + * multiply if it optimised for a power of 2 size + */ + if (BN_is_negative(r0)) + if (!BN_add(r0, r0, rsa->p)) + goto err; + + if (!BN_mul(r1, r0, rsa->iqmp, ctx)) + goto err; + + /* Turn BN_FLG_CONSTTIME flag on before division operation */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + pr1 = &local_r1; + BN_with_flags(pr1, r1, BN_FLG_CONSTTIME); + } else + pr1 = r1; + if (!BN_mod(r0, pr1, rsa->p, ctx)) + goto err; + + /* + * If p < q it is occasionally possible for the correction of adding 'p' + * if r0 is negative above to leave the result still negative. This can + * break the private key operations: the following second correction + * should *always* correct this rare occurrence. This will *never* happen + * with OpenSSL generated keys because they ensure p > q [steve] + */ + if (BN_is_negative(r0)) + if (!BN_add(r0, r0, rsa->p)) + goto err; + if (!BN_mul(r1, r0, rsa->q, ctx)) + goto err; + if (!BN_add(r0, r1, m1)) + goto err; + + if (rsa->e && rsa->n) { + if (!rsa->meth->bn_mod_exp(vrfy, r0, rsa->e, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + /* + * If 'I' was greater than (or equal to) rsa->n, the operation will + * be equivalent to using 'I mod n'. However, the result of the + * verify will *always* be less than 'n' so we don't check for + * absolute equality, just congruency. + */ + if (!BN_sub(vrfy, vrfy, I)) + goto err; + if (!BN_mod(vrfy, vrfy, rsa->n, ctx)) + goto err; + if (BN_is_negative(vrfy)) + if (!BN_add(vrfy, vrfy, rsa->n)) + goto err; + if (!BN_is_zero(vrfy)) { + /* + * 'I' and 'vrfy' aren't congruent mod n. Don't leak + * miscalculated CRT output, just do a raw (slower) mod_exp and + * return that instead. + */ + + BIGNUM local_d; + BIGNUM *d = NULL; + + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } else + d = rsa->d; + if (!rsa->meth->bn_mod_exp(r0, I, d, rsa->n, ctx, + rsa->_method_mod_n)) + goto err; + } + } + ret = 1; + err: + BN_CTX_end(ctx); + return (ret); +} + +static int RSA_eay_init(RSA *rsa) +{ + rsa->flags |= RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE; + return (1); +} + +static int RSA_eay_finish(RSA *rsa) +{ + if (rsa->_method_mod_n != NULL) + BN_MONT_CTX_free(rsa->_method_mod_n); + if (rsa->_method_mod_p != NULL) + BN_MONT_CTX_free(rsa->_method_mod_p); + if (rsa->_method_mod_q != NULL) + BN_MONT_CTX_free(rsa->_method_mod_q); + return (1); +} + +#endif diff --git a/libs/openssl/crypto/rsa/rsa_err.c b/libs/openssl/crypto/rsa/rsa_err.c new file mode 100644 index 00000000..25b3fa74 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_err.c @@ -0,0 +1,231 @@ +/* crypto/rsa/rsa_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_RSA,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_RSA,0,reason) + +static ERR_STRING_DATA RSA_str_functs[] = { + {ERR_FUNC(RSA_F_CHECK_PADDING_MD), "CHECK_PADDING_MD"}, + {ERR_FUNC(RSA_F_DO_RSA_PRINT), "DO_RSA_PRINT"}, + {ERR_FUNC(RSA_F_INT_RSA_VERIFY), "INT_RSA_VERIFY"}, + {ERR_FUNC(RSA_F_MEMORY_LOCK), "MEMORY_LOCK"}, + {ERR_FUNC(RSA_F_OLD_RSA_PRIV_DECODE), "OLD_RSA_PRIV_DECODE"}, + {ERR_FUNC(RSA_F_PKEY_RSA_CTRL), "PKEY_RSA_CTRL"}, + {ERR_FUNC(RSA_F_PKEY_RSA_CTRL_STR), "PKEY_RSA_CTRL_STR"}, + {ERR_FUNC(RSA_F_PKEY_RSA_SIGN), "PKEY_RSA_SIGN"}, + {ERR_FUNC(RSA_F_PKEY_RSA_VERIFY), "PKEY_RSA_VERIFY"}, + {ERR_FUNC(RSA_F_PKEY_RSA_VERIFYRECOVER), "PKEY_RSA_VERIFYRECOVER"}, + {ERR_FUNC(RSA_F_RSA_BUILTIN_KEYGEN), "RSA_BUILTIN_KEYGEN"}, + {ERR_FUNC(RSA_F_RSA_CHECK_KEY), "RSA_check_key"}, + {ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_DECRYPT), "RSA_EAY_PRIVATE_DECRYPT"}, + {ERR_FUNC(RSA_F_RSA_EAY_PRIVATE_ENCRYPT), "RSA_EAY_PRIVATE_ENCRYPT"}, + {ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_DECRYPT), "RSA_EAY_PUBLIC_DECRYPT"}, + {ERR_FUNC(RSA_F_RSA_EAY_PUBLIC_ENCRYPT), "RSA_EAY_PUBLIC_ENCRYPT"}, + {ERR_FUNC(RSA_F_RSA_GENERATE_KEY), "RSA_generate_key"}, + {ERR_FUNC(RSA_F_RSA_GENERATE_KEY_EX), "RSA_generate_key_ex"}, + {ERR_FUNC(RSA_F_RSA_ITEM_VERIFY), "RSA_ITEM_VERIFY"}, + {ERR_FUNC(RSA_F_RSA_MEMORY_LOCK), "RSA_memory_lock"}, + {ERR_FUNC(RSA_F_RSA_NEW_METHOD), "RSA_new_method"}, + {ERR_FUNC(RSA_F_RSA_NULL), "RSA_NULL"}, + {ERR_FUNC(RSA_F_RSA_NULL_MOD_EXP), "RSA_NULL_MOD_EXP"}, + {ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_DECRYPT), "RSA_NULL_PRIVATE_DECRYPT"}, + {ERR_FUNC(RSA_F_RSA_NULL_PRIVATE_ENCRYPT), "RSA_NULL_PRIVATE_ENCRYPT"}, + {ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_DECRYPT), "RSA_NULL_PUBLIC_DECRYPT"}, + {ERR_FUNC(RSA_F_RSA_NULL_PUBLIC_ENCRYPT), "RSA_NULL_PUBLIC_ENCRYPT"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_NONE), "RSA_padding_add_none"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP), + "RSA_padding_add_PKCS1_OAEP"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS), "RSA_padding_add_PKCS1_PSS"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1), + "RSA_padding_add_PKCS1_PSS_mgf1"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1), + "RSA_padding_add_PKCS1_type_1"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2), + "RSA_padding_add_PKCS1_type_2"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_SSLV23), "RSA_padding_add_SSLv23"}, + {ERR_FUNC(RSA_F_RSA_PADDING_ADD_X931), "RSA_padding_add_X931"}, + {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_NONE), "RSA_padding_check_none"}, + {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP), + "RSA_padding_check_PKCS1_OAEP"}, + {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1), + "RSA_padding_check_PKCS1_type_1"}, + {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2), + "RSA_padding_check_PKCS1_type_2"}, + {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_SSLV23), "RSA_padding_check_SSLv23"}, + {ERR_FUNC(RSA_F_RSA_PADDING_CHECK_X931), "RSA_padding_check_X931"}, + {ERR_FUNC(RSA_F_RSA_PRINT), "RSA_print"}, + {ERR_FUNC(RSA_F_RSA_PRINT_FP), "RSA_print_fp"}, + {ERR_FUNC(RSA_F_RSA_PRIVATE_DECRYPT), "RSA_private_decrypt"}, + {ERR_FUNC(RSA_F_RSA_PRIVATE_ENCRYPT), "RSA_private_encrypt"}, + {ERR_FUNC(RSA_F_RSA_PRIV_DECODE), "RSA_PRIV_DECODE"}, + {ERR_FUNC(RSA_F_RSA_PRIV_ENCODE), "RSA_PRIV_ENCODE"}, + {ERR_FUNC(RSA_F_RSA_PUBLIC_DECRYPT), "RSA_public_decrypt"}, + {ERR_FUNC(RSA_F_RSA_PUBLIC_ENCRYPT), "RSA_public_encrypt"}, + {ERR_FUNC(RSA_F_RSA_PUB_DECODE), "RSA_PUB_DECODE"}, + {ERR_FUNC(RSA_F_RSA_SETUP_BLINDING), "RSA_setup_blinding"}, + {ERR_FUNC(RSA_F_RSA_SIGN), "RSA_sign"}, + {ERR_FUNC(RSA_F_RSA_SIGN_ASN1_OCTET_STRING), + "RSA_sign_ASN1_OCTET_STRING"}, + {ERR_FUNC(RSA_F_RSA_VERIFY), "RSA_verify"}, + {ERR_FUNC(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING), + "RSA_verify_ASN1_OCTET_STRING"}, + {ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS), "RSA_verify_PKCS1_PSS"}, + {ERR_FUNC(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1), "RSA_verify_PKCS1_PSS_mgf1"}, + {0, NULL} +}; + +static ERR_STRING_DATA RSA_str_reasons[] = { + {ERR_REASON(RSA_R_ALGORITHM_MISMATCH), "algorithm mismatch"}, + {ERR_REASON(RSA_R_BAD_E_VALUE), "bad e value"}, + {ERR_REASON(RSA_R_BAD_FIXED_HEADER_DECRYPT), "bad fixed header decrypt"}, + {ERR_REASON(RSA_R_BAD_PAD_BYTE_COUNT), "bad pad byte count"}, + {ERR_REASON(RSA_R_BAD_SIGNATURE), "bad signature"}, + {ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_01), "block type is not 01"}, + {ERR_REASON(RSA_R_BLOCK_TYPE_IS_NOT_02), "block type is not 02"}, + {ERR_REASON(RSA_R_DATA_GREATER_THAN_MOD_LEN), + "data greater than mod len"}, + {ERR_REASON(RSA_R_DATA_TOO_LARGE), "data too large"}, + {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE), + "data too large for key size"}, + {ERR_REASON(RSA_R_DATA_TOO_LARGE_FOR_MODULUS), + "data too large for modulus"}, + {ERR_REASON(RSA_R_DATA_TOO_SMALL), "data too small"}, + {ERR_REASON(RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE), + "data too small for key size"}, + {ERR_REASON(RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY), + "digest too big for rsa key"}, + {ERR_REASON(RSA_R_DMP1_NOT_CONGRUENT_TO_D), "dmp1 not congruent to d"}, + {ERR_REASON(RSA_R_DMQ1_NOT_CONGRUENT_TO_D), "dmq1 not congruent to d"}, + {ERR_REASON(RSA_R_D_E_NOT_CONGRUENT_TO_1), "d e not congruent to 1"}, + {ERR_REASON(RSA_R_FIRST_OCTET_INVALID), "first octet invalid"}, + {ERR_REASON(RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE), + "illegal or unsupported padding mode"}, + {ERR_REASON(RSA_R_INVALID_DIGEST_LENGTH), "invalid digest length"}, + {ERR_REASON(RSA_R_INVALID_HEADER), "invalid header"}, + {ERR_REASON(RSA_R_INVALID_KEYBITS), "invalid keybits"}, + {ERR_REASON(RSA_R_INVALID_MESSAGE_LENGTH), "invalid message length"}, + {ERR_REASON(RSA_R_INVALID_MGF1_MD), "invalid mgf1 md"}, + {ERR_REASON(RSA_R_INVALID_PADDING), "invalid padding"}, + {ERR_REASON(RSA_R_INVALID_PADDING_MODE), "invalid padding mode"}, + {ERR_REASON(RSA_R_INVALID_PSS_PARAMETERS), "invalid pss parameters"}, + {ERR_REASON(RSA_R_INVALID_PSS_SALTLEN), "invalid pss saltlen"}, + {ERR_REASON(RSA_R_INVALID_SALT_LENGTH), "invalid salt length"}, + {ERR_REASON(RSA_R_INVALID_TRAILER), "invalid trailer"}, + {ERR_REASON(RSA_R_INVALID_X931_DIGEST), "invalid x931 digest"}, + {ERR_REASON(RSA_R_IQMP_NOT_INVERSE_OF_Q), "iqmp not inverse of q"}, + {ERR_REASON(RSA_R_KEY_SIZE_TOO_SMALL), "key size too small"}, + {ERR_REASON(RSA_R_LAST_OCTET_INVALID), "last octet invalid"}, + {ERR_REASON(RSA_R_MODULUS_TOO_LARGE), "modulus too large"}, + {ERR_REASON(RSA_R_NON_FIPS_RSA_METHOD), "non fips rsa method"}, + {ERR_REASON(RSA_R_NO_PUBLIC_EXPONENT), "no public exponent"}, + {ERR_REASON(RSA_R_NULL_BEFORE_BLOCK_MISSING), + "null before block missing"}, + {ERR_REASON(RSA_R_N_DOES_NOT_EQUAL_P_Q), "n does not equal p q"}, + {ERR_REASON(RSA_R_OAEP_DECODING_ERROR), "oaep decoding error"}, + {ERR_REASON(RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE), + "operation not allowed in fips mode"}, + {ERR_REASON(RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE), + "operation not supported for this keytype"}, + {ERR_REASON(RSA_R_PADDING_CHECK_FAILED), "padding check failed"}, + {ERR_REASON(RSA_R_PKCS_DECODING_ERROR), "pkcs decoding error"}, + {ERR_REASON(RSA_R_P_NOT_PRIME), "p not prime"}, + {ERR_REASON(RSA_R_Q_NOT_PRIME), "q not prime"}, + {ERR_REASON(RSA_R_RSA_OPERATIONS_NOT_SUPPORTED), + "rsa operations not supported"}, + {ERR_REASON(RSA_R_SLEN_CHECK_FAILED), "salt length check failed"}, + {ERR_REASON(RSA_R_SLEN_RECOVERY_FAILED), "salt length recovery failed"}, + {ERR_REASON(RSA_R_SSLV3_ROLLBACK_ATTACK), "sslv3 rollback attack"}, + {ERR_REASON(RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD), + "the asn1 object identifier is not known for this md"}, + {ERR_REASON(RSA_R_UNKNOWN_ALGORITHM_TYPE), "unknown algorithm type"}, + {ERR_REASON(RSA_R_UNKNOWN_MASK_DIGEST), "unknown mask digest"}, + {ERR_REASON(RSA_R_UNKNOWN_PADDING_TYPE), "unknown padding type"}, + {ERR_REASON(RSA_R_UNKNOWN_PSS_DIGEST), "unknown pss digest"}, + {ERR_REASON(RSA_R_UNSUPPORTED_MASK_ALGORITHM), + "unsupported mask algorithm"}, + {ERR_REASON(RSA_R_UNSUPPORTED_MASK_PARAMETER), + "unsupported mask parameter"}, + {ERR_REASON(RSA_R_UNSUPPORTED_SIGNATURE_TYPE), + "unsupported signature type"}, + {ERR_REASON(RSA_R_VALUE_MISSING), "value missing"}, + {ERR_REASON(RSA_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"}, + {0, NULL} +}; + +#endif + +void ERR_load_RSA_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(RSA_str_functs[0].error) == NULL) { + ERR_load_strings(0, RSA_str_functs); + ERR_load_strings(0, RSA_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/rsa/rsa_gen.c b/libs/openssl/crypto/rsa/rsa_gen.c new file mode 100644 index 00000000..7f7dca39 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_gen.c @@ -0,0 +1,250 @@ +/* crypto/rsa/rsa_gen.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/* + * NB: these functions have been "upgraded", the deprecated versions (which + * are compatibility wrappers using these functions) are in rsa_depr.c. - + * Geoff + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#ifdef OPENSSL_FIPS +# include +extern int FIPS_rsa_x931_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, + BN_GENCB *cb); +#endif + +static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + BN_GENCB *cb); + +/* + * NB: this wrapper would normally be placed in rsa_lib.c and the static + * implementation would probably be in rsa_eay.c. Nonetheless, is kept here + * so that we don't introduce a new linker dependency. Eg. any application + * that wasn't previously linking object code related to key-generation won't + * have to now just because key-generation is part of RSA_METHOD. + */ +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_RSA_GENERATE_KEY_EX, RSA_R_NON_FIPS_RSA_METHOD); + return 0; + } +#endif + if (rsa->meth->rsa_keygen) + return rsa->meth->rsa_keygen(rsa, bits, e_value, cb); +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_rsa_x931_generate_key_ex(rsa, bits, e_value, cb); +#endif + return rsa_builtin_keygen(rsa, bits, e_value, cb); +} + +static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value, + BN_GENCB *cb) +{ + BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *r3 = NULL, *tmp; + BIGNUM local_r0, local_d, local_p; + BIGNUM *pr0, *d, *p; + int bitsp, bitsq, ok = -1, n = 0; + BN_CTX *ctx = NULL; + + ctx = BN_CTX_new(); + if (ctx == NULL) + goto err; + BN_CTX_start(ctx); + r0 = BN_CTX_get(ctx); + r1 = BN_CTX_get(ctx); + r2 = BN_CTX_get(ctx); + r3 = BN_CTX_get(ctx); + if (r3 == NULL) + goto err; + + bitsp = (bits + 1) / 2; + bitsq = bits - bitsp; + + /* We need the RSA components non-NULL */ + if (!rsa->n && ((rsa->n = BN_new()) == NULL)) + goto err; + if (!rsa->d && ((rsa->d = BN_new()) == NULL)) + goto err; + if (!rsa->e && ((rsa->e = BN_new()) == NULL)) + goto err; + if (!rsa->p && ((rsa->p = BN_new()) == NULL)) + goto err; + if (!rsa->q && ((rsa->q = BN_new()) == NULL)) + goto err; + if (!rsa->dmp1 && ((rsa->dmp1 = BN_new()) == NULL)) + goto err; + if (!rsa->dmq1 && ((rsa->dmq1 = BN_new()) == NULL)) + goto err; + if (!rsa->iqmp && ((rsa->iqmp = BN_new()) == NULL)) + goto err; + + BN_copy(rsa->e, e_value); + + /* generate p and q */ + for (;;) { + if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb)) + goto err; + if (!BN_sub(r2, rsa->p, BN_value_one())) + goto err; + if (!BN_gcd(r1, r2, rsa->e, ctx)) + goto err; + if (BN_is_one(r1)) + break; + if (!BN_GENCB_call(cb, 2, n++)) + goto err; + } + if (!BN_GENCB_call(cb, 3, 0)) + goto err; + for (;;) { + /* + * When generating ridiculously small keys, we can get stuck + * continually regenerating the same prime values. Check for this and + * bail if it happens 3 times. + */ + unsigned int degenerate = 0; + do { + if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb)) + goto err; + } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3)); + if (degenerate == 3) { + ok = 0; /* we set our own err */ + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL); + goto err; + } + if (!BN_sub(r2, rsa->q, BN_value_one())) + goto err; + if (!BN_gcd(r1, r2, rsa->e, ctx)) + goto err; + if (BN_is_one(r1)) + break; + if (!BN_GENCB_call(cb, 2, n++)) + goto err; + } + if (!BN_GENCB_call(cb, 3, 1)) + goto err; + if (BN_cmp(rsa->p, rsa->q) < 0) { + tmp = rsa->p; + rsa->p = rsa->q; + rsa->q = tmp; + } + + /* calculate n */ + if (!BN_mul(rsa->n, rsa->p, rsa->q, ctx)) + goto err; + + /* calculate d */ + if (!BN_sub(r1, rsa->p, BN_value_one())) + goto err; /* p-1 */ + if (!BN_sub(r2, rsa->q, BN_value_one())) + goto err; /* q-1 */ + if (!BN_mul(r0, r1, r2, ctx)) + goto err; /* (p-1)(q-1) */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + pr0 = &local_r0; + BN_with_flags(pr0, r0, BN_FLG_CONSTTIME); + } else + pr0 = r0; + if (!BN_mod_inverse(rsa->d, rsa->e, pr0, ctx)) + goto err; /* d */ + + /* set up d for correct BN_FLG_CONSTTIME flag */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + d = &local_d; + BN_with_flags(d, rsa->d, BN_FLG_CONSTTIME); + } else + d = rsa->d; + + /* calculate d mod (p-1) */ + if (!BN_mod(rsa->dmp1, d, r1, ctx)) + goto err; + + /* calculate d mod (q-1) */ + if (!BN_mod(rsa->dmq1, d, r2, ctx)) + goto err; + + /* calculate inverse of q mod p */ + if (!(rsa->flags & RSA_FLAG_NO_CONSTTIME)) { + p = &local_p; + BN_with_flags(p, rsa->p, BN_FLG_CONSTTIME); + } else + p = rsa->p; + if (!BN_mod_inverse(rsa->iqmp, rsa->q, p, ctx)) + goto err; + + ok = 1; + err: + if (ok == -1) { + RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN); + ok = 0; + } + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + return ok; +} diff --git a/libs/openssl/crypto/rsa/rsa_lib.c b/libs/openssl/crypto/rsa/rsa_lib.c new file mode 100644 index 00000000..a6805deb --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_lib.c @@ -0,0 +1,336 @@ +/* crypto/rsa/rsa_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif + +#ifdef OPENSSL_FIPS +# include +#endif + +const char RSA_version[] = "RSA" OPENSSL_VERSION_PTEXT; + +static const RSA_METHOD *default_RSA_meth = NULL; + +RSA *RSA_new(void) +{ + RSA *r = RSA_new_method(NULL); + + return r; +} + +void RSA_set_default_method(const RSA_METHOD *meth) +{ + default_RSA_meth = meth; +} + +const RSA_METHOD *RSA_get_default_method(void) +{ + if (default_RSA_meth == NULL) { +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return FIPS_rsa_pkcs1_ssleay(); + else + return RSA_PKCS1_SSLeay(); +#else +# ifdef RSA_NULL + default_RSA_meth = RSA_null_method(); +# else + default_RSA_meth = RSA_PKCS1_SSLeay(); +# endif +#endif + } + + return default_RSA_meth; +} + +const RSA_METHOD *RSA_get_method(const RSA *rsa) +{ + return rsa->meth; +} + +int RSA_set_method(RSA *rsa, const RSA_METHOD *meth) +{ + /* + * NB: The caller is specifically setting a method, so it's not up to us + * to deal with which ENGINE it comes from. + */ + const RSA_METHOD *mtmp; + mtmp = rsa->meth; + if (mtmp->finish) + mtmp->finish(rsa); +#ifndef OPENSSL_NO_ENGINE + if (rsa->engine) { + ENGINE_finish(rsa->engine); + rsa->engine = NULL; + } +#endif + rsa->meth = meth; + if (meth->init) + meth->init(rsa); + return 1; +} + +RSA *RSA_new_method(ENGINE *engine) +{ + RSA *ret; + + ret = (RSA *)OPENSSL_malloc(sizeof(RSA)); + if (ret == NULL) { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->meth = RSA_get_default_method(); +#ifndef OPENSSL_NO_ENGINE + if (engine) { + if (!ENGINE_init(engine)) { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); + OPENSSL_free(ret); + return NULL; + } + ret->engine = engine; + } else + ret->engine = ENGINE_get_default_RSA(); + if (ret->engine) { + ret->meth = ENGINE_get_RSA(ret->engine); + if (!ret->meth) { + RSAerr(RSA_F_RSA_NEW_METHOD, ERR_R_ENGINE_LIB); + ENGINE_finish(ret->engine); + OPENSSL_free(ret); + return NULL; + } + } +#endif + + ret->pad = 0; + ret->version = 0; + ret->n = NULL; + ret->e = NULL; + ret->d = NULL; + ret->p = NULL; + ret->q = NULL; + ret->dmp1 = NULL; + ret->dmq1 = NULL; + ret->iqmp = NULL; + ret->references = 1; + ret->_method_mod_n = NULL; + ret->_method_mod_p = NULL; + ret->_method_mod_q = NULL; + ret->blinding = NULL; + ret->mt_blinding = NULL; + ret->bignum_data = NULL; + ret->flags = ret->meth->flags & ~RSA_FLAG_NON_FIPS_ALLOW; + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data)) { +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + OPENSSL_free(ret); + return (NULL); + } + + if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { +#ifndef OPENSSL_NO_ENGINE + if (ret->engine) + ENGINE_finish(ret->engine); +#endif + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, ret, &ret->ex_data); + OPENSSL_free(ret); + ret = NULL; + } + return (ret); +} + +void RSA_free(RSA *r) +{ + int i; + + if (r == NULL) + return; + + i = CRYPTO_add(&r->references, -1, CRYPTO_LOCK_RSA); +#ifdef REF_PRINT + REF_PRINT("RSA", r); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "RSA_free, bad reference count\n"); + abort(); + } +#endif + + if (r->meth->finish) + r->meth->finish(r); +#ifndef OPENSSL_NO_ENGINE + if (r->engine) + ENGINE_finish(r->engine); +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_RSA, r, &r->ex_data); + + if (r->n != NULL) + BN_clear_free(r->n); + if (r->e != NULL) + BN_clear_free(r->e); + if (r->d != NULL) + BN_clear_free(r->d); + if (r->p != NULL) + BN_clear_free(r->p); + if (r->q != NULL) + BN_clear_free(r->q); + if (r->dmp1 != NULL) + BN_clear_free(r->dmp1); + if (r->dmq1 != NULL) + BN_clear_free(r->dmq1); + if (r->iqmp != NULL) + BN_clear_free(r->iqmp); + if (r->blinding != NULL) + BN_BLINDING_free(r->blinding); + if (r->mt_blinding != NULL) + BN_BLINDING_free(r->mt_blinding); + if (r->bignum_data != NULL) + OPENSSL_free_locked(r->bignum_data); + OPENSSL_free(r); +} + +int RSA_up_ref(RSA *r) +{ + int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_RSA); +#ifdef REF_PRINT + REF_PRINT("RSA", r); +#endif +#ifdef REF_CHECK + if (i < 2) { + fprintf(stderr, "RSA_up_ref, bad reference count\n"); + abort(); + } +#endif + return ((i > 1) ? 1 : 0); +} + +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_RSA, argl, argp, + new_func, dup_func, free_func); +} + +int RSA_set_ex_data(RSA *r, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); +} + +void *RSA_get_ex_data(const RSA *r, int idx) +{ + return (CRYPTO_get_ex_data(&r->ex_data, idx)); +} + +int RSA_memory_lock(RSA *r) +{ + int i, j, k, off; + char *p; + BIGNUM *bn, **t[6], *b; + BN_ULONG *ul; + + if (r->d == NULL) + return (1); + t[0] = &r->d; + t[1] = &r->p; + t[2] = &r->q; + t[3] = &r->dmp1; + t[4] = &r->dmq1; + t[5] = &r->iqmp; + k = sizeof(BIGNUM) * 6; + off = k / sizeof(BN_ULONG) + 1; + j = 1; + for (i = 0; i < 6; i++) + j += (*t[i])->top; + if ((p = OPENSSL_malloc_locked((off + j) * sizeof(BN_ULONG))) == NULL) { + RSAerr(RSA_F_RSA_MEMORY_LOCK, ERR_R_MALLOC_FAILURE); + return (0); + } + bn = (BIGNUM *)p; + ul = (BN_ULONG *)&(p[off]); + for (i = 0; i < 6; i++) { + b = *(t[i]); + *(t[i]) = &(bn[i]); + memcpy((char *)&(bn[i]), (char *)b, sizeof(BIGNUM)); + bn[i].flags = BN_FLG_STATIC_DATA; + bn[i].d = ul; + memcpy((char *)ul, b->d, sizeof(BN_ULONG) * b->top); + ul += b->top; + BN_clear_free(b); + } + + /* I should fix this so it can still be done */ + r->flags &= ~(RSA_FLAG_CACHE_PRIVATE | RSA_FLAG_CACHE_PUBLIC); + + r->bignum_data = p; + return (1); +} diff --git a/libs/openssl/crypto/rsa/rsa_locl.h b/libs/openssl/crypto/rsa/rsa_locl.h new file mode 100644 index 00000000..3e88187d --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_locl.h @@ -0,0 +1,4 @@ +extern int int_rsa_verify(int dtype, const unsigned char *m, + unsigned int m_len, unsigned char *rm, + size_t *prm_len, const unsigned char *sigbuf, + size_t siglen, RSA *rsa); diff --git a/libs/openssl/crypto/rsa/rsa_none.c b/libs/openssl/crypto/rsa/rsa_none.c new file mode 100644 index 00000000..982b31f2 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_none.c @@ -0,0 +1,94 @@ +/* crypto/rsa/rsa_none.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +int RSA_padding_add_none(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + if (flen > tlen) { + RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return (0); + } + + if (flen < tlen) { + RSAerr(RSA_F_RSA_PADDING_ADD_NONE, RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE); + return (0); + } + + memcpy(to, from, (unsigned int)flen); + return (1); +} + +int RSA_padding_check_none(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num) +{ + + if (flen > tlen) { + RSAerr(RSA_F_RSA_PADDING_CHECK_NONE, RSA_R_DATA_TOO_LARGE); + return (-1); + } + + memset(to, 0, tlen - flen); + memcpy(to + tlen - flen, from, flen); + return (tlen); +} diff --git a/libs/openssl/crypto/rsa/rsa_null.c b/libs/openssl/crypto/rsa/rsa_null.c new file mode 100644 index 00000000..241b431a --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_null.c @@ -0,0 +1,155 @@ +/* rsa_null.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +/* + * This is a dummy RSA implementation that just returns errors when called. + * It is designed to allow some RSA functions to work while stopping those + * covered by the RSA patent. That is RSA, encryption, decryption, signing + * and verify is not allowed but RSA key generation, key checking and other + * operations (like storing RSA keys) are permitted. + */ + +static int RSA_null_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int RSA_null_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int RSA_null_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +static int RSA_null_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding); +#if 0 /* not currently used */ +static int RSA_null_mod_exp(const BIGNUM *r0, const BIGNUM *i, RSA *rsa); +#endif +static int RSA_null_init(RSA *rsa); +static int RSA_null_finish(RSA *rsa); +static RSA_METHOD rsa_null_meth = { + "Null RSA", + RSA_null_public_encrypt, + RSA_null_public_decrypt, + RSA_null_private_encrypt, + RSA_null_private_decrypt, + NULL, + NULL, + RSA_null_init, + RSA_null_finish, + 0, + NULL, + NULL, + NULL, + NULL +}; + +const RSA_METHOD *RSA_null_method(void) +{ + return (&rsa_null_meth); +} + +static int RSA_null_public_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + RSAerr(RSA_F_RSA_NULL_PUBLIC_ENCRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); + return -1; +} + +static int RSA_null_private_encrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + RSAerr(RSA_F_RSA_NULL_PRIVATE_ENCRYPT, + RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); + return -1; +} + +static int RSA_null_private_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + RSAerr(RSA_F_RSA_NULL_PRIVATE_DECRYPT, + RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); + return -1; +} + +static int RSA_null_public_decrypt(int flen, const unsigned char *from, + unsigned char *to, RSA *rsa, int padding) +{ + RSAerr(RSA_F_RSA_NULL_PUBLIC_DECRYPT, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); + return -1; +} + +#if 0 /* not currently used */ +static int RSA_null_mod_exp(BIGNUM *r0, BIGNUM *I, RSA *rsa) +{ + ... err(RSA_F_RSA_NULL_MOD_EXP, RSA_R_RSA_OPERATIONS_NOT_SUPPORTED); + return -1; +} +#endif + +static int RSA_null_init(RSA *rsa) +{ + return (1); +} + +static int RSA_null_finish(RSA *rsa) +{ + return (1); +} diff --git a/libs/openssl/crypto/rsa/rsa_oaep.c b/libs/openssl/crypto/rsa/rsa_oaep.c new file mode 100644 index 00000000..499835f8 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_oaep.c @@ -0,0 +1,257 @@ +/* crypto/rsa/rsa_oaep.c */ +/* + * Written by Ulf Moeller. This software is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. + */ + +/* EME-OAEP as defined in RFC 2437 (PKCS #1 v2.0) */ + +/* + * See Victor Shoup, "OAEP reconsidered," Nov. 2000, for problems with the security + * proof for the original OAEP scheme, which EME-OAEP is based on. A new + * proof can be found in E. Fujisaki, T. Okamoto, D. Pointcheval, J. Stern, + * "RSA-OEAP is Still Alive!", Dec. 2000, . The new proof has stronger requirements + * for the underlying permutation: "partial-one-wayness" instead of + * one-wayness. For the RSA function, this is an equivalent notion. + */ + +#include "constant_time_locl.h" + +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) +# include +# include "cryptlib.h" +# include +# include +# include +# include +# include + +static int MGF1(unsigned char *mask, long len, + const unsigned char *seed, long seedlen); + +int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *from, int flen, + const unsigned char *param, int plen) +{ + int i, emlen = tlen - 1; + unsigned char *db, *seed; + unsigned char *dbmask, seedmask[SHA_DIGEST_LENGTH]; + + if (flen > emlen - 2 * SHA_DIGEST_LENGTH - 1) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return 0; + } + + if (emlen < 2 * SHA_DIGEST_LENGTH + 1) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + to[0] = 0; + seed = to + 1; + db = to + SHA_DIGEST_LENGTH + 1; + + if (!EVP_Digest((void *)param, plen, db, NULL, EVP_sha1(), NULL)) + return 0; + memset(db + SHA_DIGEST_LENGTH, 0, + emlen - flen - 2 * SHA_DIGEST_LENGTH - 1); + db[emlen - flen - SHA_DIGEST_LENGTH - 1] = 0x01; + memcpy(db + emlen - flen - SHA_DIGEST_LENGTH, from, (unsigned int)flen); + if (RAND_bytes(seed, SHA_DIGEST_LENGTH) <= 0) + return 0; +# ifdef PKCS_TESTVECT + memcpy(seed, + "\xaa\xfd\x12\xf6\x59\xca\xe6\x34\x89\xb4\x79\xe5\x07\x6d\xde\xc2\xf0\x6c\xb5\x8f", + 20); +# endif + + dbmask = OPENSSL_malloc(emlen - SHA_DIGEST_LENGTH); + if (dbmask == NULL) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_OAEP, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (MGF1(dbmask, emlen - SHA_DIGEST_LENGTH, seed, SHA_DIGEST_LENGTH) < 0) + return 0; + for (i = 0; i < emlen - SHA_DIGEST_LENGTH; i++) + db[i] ^= dbmask[i]; + + if (MGF1(seedmask, SHA_DIGEST_LENGTH, db, emlen - SHA_DIGEST_LENGTH) < 0) + return 0; + for (i = 0; i < SHA_DIGEST_LENGTH; i++) + seed[i] ^= seedmask[i]; + + OPENSSL_free(dbmask); + return 1; +} + +int RSA_padding_check_PKCS1_OAEP(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num, + const unsigned char *param, int plen) +{ + int i, dblen, mlen = -1, one_index = 0, msg_index; + unsigned int good, found_one_byte; + const unsigned char *maskedseed, *maskeddb; + /* + * |em| is the encoded message, zero-padded to exactly |num| bytes: em = + * Y || maskedSeed || maskedDB + */ + unsigned char *db = NULL, *em = NULL, seed[EVP_MAX_MD_SIZE], + phash[EVP_MAX_MD_SIZE]; + + if (tlen <= 0 || flen <= 0) + return -1; + + /* + * |num| is the length of the modulus; |flen| is the length of the + * encoded message. Therefore, for any |from| that was obtained by + * decrypting a ciphertext, we must have |flen| <= |num|. Similarly, + * num < 2 * SHA_DIGEST_LENGTH + 2 must hold for the modulus + * irrespective of the ciphertext, see PKCS #1 v2.2, section 7.1.2. + * This does not leak any side-channel information. + */ + if (num < flen || num < 2 * SHA_DIGEST_LENGTH + 2) + goto decoding_err; + + dblen = num - SHA_DIGEST_LENGTH - 1; + db = OPENSSL_malloc(dblen); + em = OPENSSL_malloc(num); + if (db == NULL || em == NULL) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, ERR_R_MALLOC_FAILURE); + goto cleanup; + } + + /* + * Always do this zero-padding copy (even when num == flen) to avoid + * leaking that information. The copy still leaks some side-channel + * information, but it's impossible to have a fixed memory access + * pattern since we can't read out of the bounds of |from|. + * + * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL. + */ + memset(em, 0, num); + memcpy(em + num - flen, from, flen); + + /* + * The first byte must be zero, however we must not leak if this is + * true. See James H. Manger, "A Chosen Ciphertext Attack on RSA + * Optimal Asymmetric Encryption Padding (OAEP) [...]", CRYPTO 2001). + */ + good = constant_time_is_zero(em[0]); + + maskedseed = em + 1; + maskeddb = em + 1 + SHA_DIGEST_LENGTH; + + if (MGF1(seed, SHA_DIGEST_LENGTH, maskeddb, dblen)) + goto cleanup; + for (i = 0; i < SHA_DIGEST_LENGTH; i++) + seed[i] ^= maskedseed[i]; + + if (MGF1(db, dblen, seed, SHA_DIGEST_LENGTH)) + goto cleanup; + for (i = 0; i < dblen; i++) + db[i] ^= maskeddb[i]; + + if (!EVP_Digest((void *)param, plen, phash, NULL, EVP_sha1(), NULL)) + goto cleanup; + + good &= + constant_time_is_zero(CRYPTO_memcmp(db, phash, SHA_DIGEST_LENGTH)); + + found_one_byte = 0; + for (i = SHA_DIGEST_LENGTH; i < dblen; i++) { + /* + * Padding consists of a number of 0-bytes, followed by a 1. + */ + unsigned int equals1 = constant_time_eq(db[i], 1); + unsigned int equals0 = constant_time_is_zero(db[i]); + one_index = constant_time_select_int(~found_one_byte & equals1, + i, one_index); + found_one_byte |= equals1; + good &= (found_one_byte | equals0); + } + + good &= found_one_byte; + + /* + * At this point |good| is zero unless the plaintext was valid, + * so plaintext-awareness ensures timing side-channels are no longer a + * concern. + */ + if (!good) + goto decoding_err; + + msg_index = one_index + 1; + mlen = dblen - msg_index; + + if (tlen < mlen) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_DATA_TOO_LARGE); + mlen = -1; + } else { + memcpy(to, db + msg_index, mlen); + goto cleanup; + } + + decoding_err: + /* + * To avoid chosen ciphertext attacks, the error message should not + * reveal which kind of decoding error happened. + */ + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_OAEP, RSA_R_OAEP_DECODING_ERROR); + cleanup: + if (db != NULL) + OPENSSL_free(db); + if (em != NULL) + OPENSSL_free(em); + return mlen; +} + +int PKCS1_MGF1(unsigned char *mask, long len, + const unsigned char *seed, long seedlen, const EVP_MD *dgst) +{ + long i, outlen = 0; + unsigned char cnt[4]; + EVP_MD_CTX c; + unsigned char md[EVP_MAX_MD_SIZE]; + int mdlen; + int rv = -1; + + EVP_MD_CTX_init(&c); + mdlen = EVP_MD_size(dgst); + if (mdlen < 0) + goto err; + for (i = 0; outlen < len; i++) { + cnt[0] = (unsigned char)((i >> 24) & 255); + cnt[1] = (unsigned char)((i >> 16) & 255); + cnt[2] = (unsigned char)((i >> 8)) & 255; + cnt[3] = (unsigned char)(i & 255); + if (!EVP_DigestInit_ex(&c, dgst, NULL) + || !EVP_DigestUpdate(&c, seed, seedlen) + || !EVP_DigestUpdate(&c, cnt, 4)) + goto err; + if (outlen + mdlen <= len) { + if (!EVP_DigestFinal_ex(&c, mask + outlen, NULL)) + goto err; + outlen += mdlen; + } else { + if (!EVP_DigestFinal_ex(&c, md, NULL)) + goto err; + memcpy(mask + outlen, md, len - outlen); + outlen = len; + } + } + rv = 0; + err: + EVP_MD_CTX_cleanup(&c); + return rv; +} + +static int MGF1(unsigned char *mask, long len, const unsigned char *seed, + long seedlen) +{ + return PKCS1_MGF1(mask, len, seed, seedlen, EVP_sha1()); +} +#endif diff --git a/libs/openssl/crypto/rsa/rsa_pk1.c b/libs/openssl/crypto/rsa/rsa_pk1.c new file mode 100644 index 00000000..efa1fd3e --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_pk1.c @@ -0,0 +1,275 @@ +/* crypto/rsa/rsa_pk1.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "constant_time_locl.h" + +#include +#include "cryptlib.h" +#include +#include +#include + +int RSA_padding_add_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + int j; + unsigned char *p; + + if (flen > (tlen - RSA_PKCS1_PADDING_SIZE)) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_1, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return (0); + } + + p = (unsigned char *)to; + + *(p++) = 0; + *(p++) = 1; /* Private Key BT (Block Type) */ + + /* pad out with 0xff data */ + j = tlen - 3 - flen; + memset(p, 0xff, j); + p += j; + *(p++) = '\0'; + memcpy(p, from, (unsigned int)flen); + return (1); +} + +int RSA_padding_check_PKCS1_type_1(unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num) +{ + int i, j; + const unsigned char *p; + + p = from; + if ((num != (flen + 1)) || (*(p++) != 01)) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_BLOCK_TYPE_IS_NOT_01); + return (-1); + } + + /* scan over padding data */ + j = flen - 1; /* one for type. */ + for (i = 0; i < j; i++) { + if (*p != 0xff) { /* should decrypt to 0xff */ + if (*p == 0) { + p++; + break; + } else { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_BAD_FIXED_HEADER_DECRYPT); + return (-1); + } + } + p++; + } + + if (i == j) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_NULL_BEFORE_BLOCK_MISSING); + return (-1); + } + + if (i < 8) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, + RSA_R_BAD_PAD_BYTE_COUNT); + return (-1); + } + i++; /* Skip over the '\0' */ + j -= i; + if (j > tlen) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_1, RSA_R_DATA_TOO_LARGE); + return (-1); + } + memcpy(to, p, (unsigned int)j); + + return (j); +} + +int RSA_padding_add_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + int i, j; + unsigned char *p; + + if (flen > (tlen - 11)) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_TYPE_2, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return (0); + } + + p = (unsigned char *)to; + + *(p++) = 0; + *(p++) = 2; /* Public Key BT (Block Type) */ + + /* pad out with non-zero random data */ + j = tlen - 3 - flen; + + if (RAND_bytes(p, j) <= 0) + return (0); + for (i = 0; i < j; i++) { + if (*p == '\0') + do { + if (RAND_bytes(p, 1) <= 0) + return (0); + } while (*p == '\0'); + p++; + } + + *(p++) = '\0'; + + memcpy(p, from, (unsigned int)flen); + return (1); +} + +int RSA_padding_check_PKCS1_type_2(unsigned char *to, int tlen, + const unsigned char *from, int flen, + int num) +{ + int i; + /* |em| is the encoded message, zero-padded to exactly |num| bytes */ + unsigned char *em = NULL; + unsigned int good, found_zero_byte; + int zero_index = 0, msg_index, mlen = -1; + + if (tlen < 0 || flen < 0) + return -1; + + /* + * PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography Standard", + * section 7.2.2. + */ + + if (flen > num) + goto err; + + if (num < 11) + goto err; + + em = OPENSSL_malloc(num); + if (em == NULL) { + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, ERR_R_MALLOC_FAILURE); + return -1; + } + memset(em, 0, num); + /* + * Always do this zero-padding copy (even when num == flen) to avoid + * leaking that information. The copy still leaks some side-channel + * information, but it's impossible to have a fixed memory access + * pattern since we can't read out of the bounds of |from|. + * + * TODO(emilia): Consider porting BN_bn2bin_padded from BoringSSL. + */ + memcpy(em + num - flen, from, flen); + + good = constant_time_is_zero(em[0]); + good &= constant_time_eq(em[1], 2); + + found_zero_byte = 0; + for (i = 2; i < num; i++) { + unsigned int equals0 = constant_time_is_zero(em[i]); + zero_index = + constant_time_select_int(~found_zero_byte & equals0, i, + zero_index); + found_zero_byte |= equals0; + } + + /* + * PS must be at least 8 bytes long, and it starts two bytes into |em|. + * If we never found a 0-byte, then |zero_index| is 0 and the check + * also fails. + */ + good &= constant_time_ge((unsigned int)(zero_index), 2 + 8); + + /* + * Skip the zero byte. This is incorrect if we never found a zero-byte + * but in this case we also do not copy the message out. + */ + msg_index = zero_index + 1; + mlen = num - msg_index; + + /* + * For good measure, do this check in constant time as well; it could + * leak something if |tlen| was assuming valid padding. + */ + good &= constant_time_ge((unsigned int)(tlen), (unsigned int)(mlen)); + + /* + * We can't continue in constant-time because we need to copy the result + * and we cannot fake its length. This unavoidably leaks timing + * information at the API boundary. + * TODO(emilia): this could be addressed at the call site, + * see BoringSSL commit 0aa0767340baf925bda4804882aab0cb974b2d26. + */ + if (!good) { + mlen = -1; + goto err; + } + + memcpy(to, em + msg_index, mlen); + + err: + if (em != NULL) + OPENSSL_free(em); + if (mlen == -1) + RSAerr(RSA_F_RSA_PADDING_CHECK_PKCS1_TYPE_2, + RSA_R_PKCS_DECODING_ERROR); + return mlen; +} diff --git a/libs/openssl/crypto/rsa/rsa_pmeth.c b/libs/openssl/crypto/rsa/rsa_pmeth.c new file mode 100644 index 00000000..6a7c67cd --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_pmeth.c @@ -0,0 +1,665 @@ +/* crypto/rsa/rsa_pmeth.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_CMS +# include +#endif +#ifdef OPENSSL_FIPS +# include +#endif +#include "evp_locl.h" +#include "rsa_locl.h" + +/* RSA pkey context structure */ + +typedef struct { + /* Key gen parameters */ + int nbits; + BIGNUM *pub_exp; + /* Keygen callback info */ + int gentmp[2]; + /* RSA padding mode */ + int pad_mode; + /* message digest */ + const EVP_MD *md; + /* message digest for MGF1 */ + const EVP_MD *mgf1md; + /* PSS/OAEP salt length */ + int saltlen; + /* Temp buffer */ + unsigned char *tbuf; +} RSA_PKEY_CTX; + +static int pkey_rsa_init(EVP_PKEY_CTX *ctx) +{ + RSA_PKEY_CTX *rctx; + rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX)); + if (!rctx) + return 0; + rctx->nbits = 1024; + rctx->pub_exp = NULL; + rctx->pad_mode = RSA_PKCS1_PADDING; + rctx->md = NULL; + rctx->mgf1md = NULL; + rctx->tbuf = NULL; + + rctx->saltlen = -2; + + ctx->data = rctx; + ctx->keygen_info = rctx->gentmp; + ctx->keygen_info_count = 2; + + return 1; +} + +static int pkey_rsa_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) +{ + RSA_PKEY_CTX *dctx, *sctx; + if (!pkey_rsa_init(dst)) + return 0; + sctx = src->data; + dctx = dst->data; + dctx->nbits = sctx->nbits; + if (sctx->pub_exp) { + dctx->pub_exp = BN_dup(sctx->pub_exp); + if (!dctx->pub_exp) + return 0; + } + dctx->pad_mode = sctx->pad_mode; + dctx->md = sctx->md; + return 1; +} + +static int setup_tbuf(RSA_PKEY_CTX *ctx, EVP_PKEY_CTX *pk) +{ + if (ctx->tbuf) + return 1; + ctx->tbuf = OPENSSL_malloc(EVP_PKEY_size(pk->pkey)); + if (!ctx->tbuf) + return 0; + return 1; +} + +static void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) +{ + RSA_PKEY_CTX *rctx = ctx->data; + if (rctx) { + if (rctx->pub_exp) + BN_free(rctx->pub_exp); + if (rctx->tbuf) + OPENSSL_free(rctx->tbuf); + OPENSSL_free(rctx); + } +} + +#ifdef OPENSSL_FIPS +/* + * FIP checker. Return value indicates status of context parameters: 1 : + * redirect to FIPS. 0 : don't redirect to FIPS. -1 : illegal operation in + * FIPS mode. + */ + +static int pkey_fips_check_ctx(EVP_PKEY_CTX *ctx) +{ + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + int rv = -1; + if (!FIPS_mode()) + return 0; + if (rsa->flags & RSA_FLAG_NON_FIPS_ALLOW) + rv = 0; + if (!(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) && rv) + return -1; + if (rctx->md && !(rctx->md->flags & EVP_MD_FLAG_FIPS)) + return rv; + if (rctx->mgf1md && !(rctx->mgf1md->flags & EVP_MD_FLAG_FIPS)) + return rv; + return 1; +} +#endif + +static int pkey_rsa_sign(EVP_PKEY_CTX *ctx, unsigned char *sig, + size_t *siglen, const unsigned char *tbs, + size_t tbslen) +{ + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + +#ifdef OPENSSL_FIPS + ret = pkey_fips_check_ctx(ctx); + if (ret < 0) { + RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return -1; + } +#endif + + if (rctx->md) { + if (tbslen != (size_t)EVP_MD_size(rctx->md)) { + RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_INVALID_DIGEST_LENGTH); + return -1; + } +#ifdef OPENSSL_FIPS + if (ret > 0) { + unsigned int slen; + ret = FIPS_rsa_sign_digest(rsa, tbs, tbslen, rctx->md, + rctx->pad_mode, + rctx->saltlen, + rctx->mgf1md, sig, &slen); + if (ret > 0) + *siglen = slen; + else + *siglen = 0; + return ret; + } +#endif + + if (EVP_MD_type(rctx->md) == NID_mdc2) { + unsigned int sltmp; + if (rctx->pad_mode != RSA_PKCS1_PADDING) + return -1; + ret = RSA_sign_ASN1_OCTET_STRING(NID_mdc2, + tbs, tbslen, sig, &sltmp, rsa); + + if (ret <= 0) + return ret; + ret = sltmp; + } else if (rctx->pad_mode == RSA_X931_PADDING) { + if ((size_t)EVP_PKEY_size(ctx->pkey) < tbslen + 1) { + RSAerr(RSA_F_PKEY_RSA_SIGN, RSA_R_KEY_SIZE_TOO_SMALL); + return -1; + } + if (!setup_tbuf(rctx, ctx)) { + RSAerr(RSA_F_PKEY_RSA_SIGN, ERR_R_MALLOC_FAILURE); + return -1; + } + memcpy(rctx->tbuf, tbs, tbslen); + rctx->tbuf[tbslen] = RSA_X931_hash_id(EVP_MD_type(rctx->md)); + ret = RSA_private_encrypt(tbslen + 1, rctx->tbuf, + sig, rsa, RSA_X931_PADDING); + } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { + unsigned int sltmp; + ret = RSA_sign(EVP_MD_type(rctx->md), + tbs, tbslen, sig, &sltmp, rsa); + if (ret <= 0) + return ret; + ret = sltmp; + } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { + if (!setup_tbuf(rctx, ctx)) + return -1; + if (!RSA_padding_add_PKCS1_PSS_mgf1(rsa, + rctx->tbuf, tbs, + rctx->md, rctx->mgf1md, + rctx->saltlen)) + return -1; + ret = RSA_private_encrypt(RSA_size(rsa), rctx->tbuf, + sig, rsa, RSA_NO_PADDING); + } else + return -1; + } else + ret = RSA_private_encrypt(tbslen, tbs, sig, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *siglen = ret; + return 1; +} + +static int pkey_rsa_verifyrecover(EVP_PKEY_CTX *ctx, + unsigned char *rout, size_t *routlen, + const unsigned char *sig, size_t siglen) +{ + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + + if (rctx->md) { + if (rctx->pad_mode == RSA_X931_PADDING) { + if (!setup_tbuf(rctx, ctx)) + return -1; + ret = RSA_public_decrypt(siglen, sig, + rctx->tbuf, ctx->pkey->pkey.rsa, + RSA_X931_PADDING); + if (ret < 1) + return 0; + ret--; + if (rctx->tbuf[ret] != RSA_X931_hash_id(EVP_MD_type(rctx->md))) { + RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, + RSA_R_ALGORITHM_MISMATCH); + return 0; + } + if (ret != EVP_MD_size(rctx->md)) { + RSAerr(RSA_F_PKEY_RSA_VERIFYRECOVER, + RSA_R_INVALID_DIGEST_LENGTH); + return 0; + } + if (rout) + memcpy(rout, rctx->tbuf, ret); + } else if (rctx->pad_mode == RSA_PKCS1_PADDING) { + size_t sltmp; + ret = int_rsa_verify(EVP_MD_type(rctx->md), + NULL, 0, rout, &sltmp, + sig, siglen, ctx->pkey->pkey.rsa); + if (ret <= 0) + return 0; + ret = sltmp; + } else + return -1; + } else + ret = RSA_public_decrypt(siglen, sig, rout, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *routlen = ret; + return 1; +} + +static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, + const unsigned char *sig, size_t siglen, + const unsigned char *tbs, size_t tbslen) +{ + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + size_t rslen; +#ifdef OPENSSL_FIPS + int rv; + rv = pkey_fips_check_ctx(ctx); + if (rv < 0) { + RSAerr(RSA_F_PKEY_RSA_VERIFY, + RSA_R_OPERATION_NOT_ALLOWED_IN_FIPS_MODE); + return -1; + } +#endif + if (rctx->md) { +#ifdef OPENSSL_FIPS + if (rv > 0) { + return FIPS_rsa_verify_digest(rsa, + tbs, tbslen, + rctx->md, + rctx->pad_mode, + rctx->saltlen, + rctx->mgf1md, sig, siglen); + + } +#endif + if (rctx->pad_mode == RSA_PKCS1_PADDING) + return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, + sig, siglen, rsa); + if (rctx->pad_mode == RSA_X931_PADDING) { + if (pkey_rsa_verifyrecover(ctx, NULL, &rslen, sig, siglen) <= 0) + return 0; + } else if (rctx->pad_mode == RSA_PKCS1_PSS_PADDING) { + int ret; + if (!setup_tbuf(rctx, ctx)) + return -1; + ret = RSA_public_decrypt(siglen, sig, rctx->tbuf, + rsa, RSA_NO_PADDING); + if (ret <= 0) + return 0; + ret = RSA_verify_PKCS1_PSS_mgf1(rsa, tbs, + rctx->md, rctx->mgf1md, + rctx->tbuf, rctx->saltlen); + if (ret <= 0) + return 0; + return 1; + } else + return -1; + } else { + if (!setup_tbuf(rctx, ctx)) + return -1; + rslen = RSA_public_decrypt(siglen, sig, rctx->tbuf, + rsa, rctx->pad_mode); + if (rslen == 0) + return 0; + } + + if ((rslen != tbslen) || memcmp(tbs, rctx->tbuf, rslen)) + return 0; + + return 1; + +} + +static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + ret = RSA_public_encrypt(inlen, in, out, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *outlen = ret; + return 1; +} + +static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, + unsigned char *out, size_t *outlen, + const unsigned char *in, size_t inlen) +{ + int ret; + RSA_PKEY_CTX *rctx = ctx->data; + ret = RSA_private_decrypt(inlen, in, out, ctx->pkey->pkey.rsa, + rctx->pad_mode); + if (ret < 0) + return ret; + *outlen = ret; + return 1; +} + +static int check_padding_md(const EVP_MD *md, int padding) +{ + if (!md) + return 1; + + if (padding == RSA_NO_PADDING) { + RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_PADDING_MODE); + return 0; + } + + if (padding == RSA_X931_PADDING) { + if (RSA_X931_hash_id(EVP_MD_type(md)) == -1) { + RSAerr(RSA_F_CHECK_PADDING_MD, RSA_R_INVALID_X931_DIGEST); + return 0; + } + return 1; + } + + return 1; +} + +static int pkey_rsa_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) +{ + RSA_PKEY_CTX *rctx = ctx->data; + switch (type) { + case EVP_PKEY_CTRL_RSA_PADDING: + if ((p1 >= RSA_PKCS1_PADDING) && (p1 <= RSA_PKCS1_PSS_PADDING)) { + if (!check_padding_md(rctx->md, p1)) + return 0; + if (p1 == RSA_PKCS1_PSS_PADDING) { + if (!(ctx->operation & + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) + goto bad_pad; + if (!rctx->md) + rctx->md = EVP_sha1(); + } + if (p1 == RSA_PKCS1_OAEP_PADDING) { + if (!(ctx->operation & EVP_PKEY_OP_TYPE_CRYPT)) + goto bad_pad; + if (!rctx->md) + rctx->md = EVP_sha1(); + } + rctx->pad_mode = p1; + return 1; + } + bad_pad: + RSAerr(RSA_F_PKEY_RSA_CTRL, + RSA_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return -2; + + case EVP_PKEY_CTRL_GET_RSA_PADDING: + *(int *)p2 = rctx->pad_mode; + return 1; + + case EVP_PKEY_CTRL_RSA_PSS_SALTLEN: + case EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN: + if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_PSS_SALTLEN); + return -2; + } + if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) + *(int *)p2 = rctx->saltlen; + else { + if (p1 < -2) + return -2; + rctx->saltlen = p1; + } + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: + if (p1 < 256) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_KEYBITS); + return -2; + } + rctx->nbits = p1; + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: + if (!p2) + return -2; + rctx->pub_exp = p2; + return 1; + + case EVP_PKEY_CTRL_MD: + if (!check_padding_md(p2, rctx->pad_mode)) + return 0; + rctx->md = p2; + return 1; + + case EVP_PKEY_CTRL_RSA_MGF1_MD: + case EVP_PKEY_CTRL_GET_RSA_MGF1_MD: + if (rctx->pad_mode != RSA_PKCS1_PSS_PADDING) { + RSAerr(RSA_F_PKEY_RSA_CTRL, RSA_R_INVALID_MGF1_MD); + return -2; + } + if (type == EVP_PKEY_CTRL_GET_RSA_MGF1_MD) { + if (rctx->mgf1md) + *(const EVP_MD **)p2 = rctx->mgf1md; + else + *(const EVP_MD **)p2 = rctx->md; + } else + rctx->mgf1md = p2; + return 1; + + case EVP_PKEY_CTRL_DIGESTINIT: + case EVP_PKEY_CTRL_PKCS7_ENCRYPT: + case EVP_PKEY_CTRL_PKCS7_DECRYPT: + case EVP_PKEY_CTRL_PKCS7_SIGN: + return 1; +#ifndef OPENSSL_NO_CMS + case EVP_PKEY_CTRL_CMS_DECRYPT: + { + X509_ALGOR *alg = NULL; + ASN1_OBJECT *encalg = NULL; + if (p2) + CMS_RecipientInfo_ktri_get0_algs(p2, NULL, NULL, &alg); + if (alg) + X509_ALGOR_get0(&encalg, NULL, NULL, alg); + if (encalg && OBJ_obj2nid(encalg) == NID_rsaesOaep) + rctx->pad_mode = RSA_PKCS1_OAEP_PADDING; + } + case EVP_PKEY_CTRL_CMS_ENCRYPT: + case EVP_PKEY_CTRL_CMS_SIGN: + return 1; +#endif + case EVP_PKEY_CTRL_PEER_KEY: + RSAerr(RSA_F_PKEY_RSA_CTRL, + RSA_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return -2; + + default: + return -2; + + } +} + +static int pkey_rsa_ctrl_str(EVP_PKEY_CTX *ctx, + const char *type, const char *value) +{ + if (!value) { + RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_VALUE_MISSING); + return 0; + } + if (!strcmp(type, "rsa_padding_mode")) { + int pm; + if (!strcmp(value, "pkcs1")) + pm = RSA_PKCS1_PADDING; + else if (!strcmp(value, "sslv23")) + pm = RSA_SSLV23_PADDING; + else if (!strcmp(value, "none")) + pm = RSA_NO_PADDING; + else if (!strcmp(value, "oeap")) + pm = RSA_PKCS1_OAEP_PADDING; + else if (!strcmp(value, "oaep")) + pm = RSA_PKCS1_OAEP_PADDING; + else if (!strcmp(value, "x931")) + pm = RSA_X931_PADDING; + else if (!strcmp(value, "pss")) + pm = RSA_PKCS1_PSS_PADDING; + else { + RSAerr(RSA_F_PKEY_RSA_CTRL_STR, RSA_R_UNKNOWN_PADDING_TYPE); + return -2; + } + return EVP_PKEY_CTX_set_rsa_padding(ctx, pm); + } + + if (!strcmp(type, "rsa_pss_saltlen")) { + int saltlen; + saltlen = atoi(value); + return EVP_PKEY_CTX_set_rsa_pss_saltlen(ctx, saltlen); + } + + if (!strcmp(type, "rsa_keygen_bits")) { + int nbits; + nbits = atoi(value); + return EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, nbits); + } + + if (!strcmp(type, "rsa_keygen_pubexp")) { + int ret; + BIGNUM *pubexp = NULL; + if (!BN_asc2bn(&pubexp, value)) + return 0; + ret = EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, pubexp); + if (ret <= 0) + BN_free(pubexp); + return ret; + } + + return -2; +} + +static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) +{ + RSA *rsa = NULL; + RSA_PKEY_CTX *rctx = ctx->data; + BN_GENCB *pcb, cb; + int ret; + if (!rctx->pub_exp) { + rctx->pub_exp = BN_new(); + if (!rctx->pub_exp || !BN_set_word(rctx->pub_exp, RSA_F4)) + return 0; + } + rsa = RSA_new(); + if (!rsa) + return 0; + if (ctx->pkey_gencb) { + pcb = &cb; + evp_pkey_set_cb_translate(pcb, ctx); + } else + pcb = NULL; + ret = RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, pcb); + if (ret > 0) + EVP_PKEY_assign_RSA(pkey, rsa); + else + RSA_free(rsa); + return ret; +} + +const EVP_PKEY_METHOD rsa_pkey_meth = { + EVP_PKEY_RSA, + EVP_PKEY_FLAG_AUTOARGLEN, + pkey_rsa_init, + pkey_rsa_copy, + pkey_rsa_cleanup, + + 0, 0, + + 0, + pkey_rsa_keygen, + + 0, + pkey_rsa_sign, + + 0, + pkey_rsa_verify, + + 0, + pkey_rsa_verifyrecover, + + 0, 0, 0, 0, + + 0, + pkey_rsa_encrypt, + + 0, + pkey_rsa_decrypt, + + 0, 0, + + pkey_rsa_ctrl, + pkey_rsa_ctrl_str +}; diff --git a/libs/openssl/crypto/rsa/rsa_prn.c b/libs/openssl/crypto/rsa/rsa_prn.c new file mode 100644 index 00000000..076f871b --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_prn.c @@ -0,0 +1,92 @@ +/* crypto/rsa/rsa_prn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2006. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include + +#ifndef OPENSSL_NO_FP_API +int RSA_print_fp(FILE *fp, const RSA *x, int off) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + RSAerr(RSA_F_RSA_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = RSA_print(b, x, off); + BIO_free(b); + return (ret); +} +#endif + +int RSA_print(BIO *bp, const RSA *x, int off) +{ + EVP_PKEY *pk; + int ret; + pk = EVP_PKEY_new(); + if (!pk || !EVP_PKEY_set1_RSA(pk, (RSA *)x)) + return 0; + ret = EVP_PKEY_print_private(bp, pk, off, NULL); + EVP_PKEY_free(pk); + return ret; +} diff --git a/libs/openssl/crypto/rsa/rsa_pss.c b/libs/openssl/crypto/rsa/rsa_pss.c new file mode 100644 index 00000000..41bc0844 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_pss.c @@ -0,0 +1,290 @@ +/* rsa_pss.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include + +static const unsigned char zeroes[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; + +#if defined(_MSC_VER) && defined(_ARM_) +# pragma optimize("g", off) +#endif + +int RSA_verify_PKCS1_PSS(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const unsigned char *EM, + int sLen) +{ + return RSA_verify_PKCS1_PSS_mgf1(rsa, mHash, Hash, NULL, EM, sLen); +} + +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + const unsigned char *EM, int sLen) +{ + int i; + int ret = 0; + int hLen, maskedDBLen, MSBits, emLen; + const unsigned char *H; + unsigned char *DB = NULL; + EVP_MD_CTX ctx; + unsigned char H_[EVP_MAX_MD_SIZE]; + EVP_MD_CTX_init(&ctx); + + if (mgf1Hash == NULL) + mgf1Hash = Hash; + + hLen = EVP_MD_size(Hash); + if (hLen < 0) + goto err; + /*- + * Negative sLen has special meanings: + * -1 sLen == hLen + * -2 salt length is autorecovered from signature + * -N reserved + */ + if (sLen == -1) + sLen = hLen; + else if (sLen == -2) + sLen = -2; + else if (sLen < -2) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + + MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + emLen = RSA_size(rsa); + if (EM[0] & (0xFF << MSBits)) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_FIRST_OCTET_INVALID); + goto err; + } + if (MSBits == 0) { + EM++; + emLen--; + } + if (emLen < (hLen + sLen + 2)) { /* sLen can be small negative */ + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_DATA_TOO_LARGE); + goto err; + } + if (EM[emLen - 1] != 0xbc) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_LAST_OCTET_INVALID); + goto err; + } + maskedDBLen = emLen - hLen - 1; + H = EM + maskedDBLen; + DB = OPENSSL_malloc(maskedDBLen); + if (!DB) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, ERR_R_MALLOC_FAILURE); + goto err; + } + if (PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash) < 0) + goto err; + for (i = 0; i < maskedDBLen; i++) + DB[i] ^= EM[i]; + if (MSBits) + DB[0] &= 0xFF >> (8 - MSBits); + for (i = 0; DB[i] == 0 && i < (maskedDBLen - 1); i++) ; + if (DB[i++] != 0x1) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_RECOVERY_FAILED); + goto err; + } + if (sLen >= 0 && (maskedDBLen - i) != sLen) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + if (!EVP_DigestInit_ex(&ctx, Hash, NULL) + || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes) + || !EVP_DigestUpdate(&ctx, mHash, hLen)) + goto err; + if (maskedDBLen - i) { + if (!EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i)) + goto err; + } + if (!EVP_DigestFinal_ex(&ctx, H_, NULL)) + goto err; + if (memcmp(H_, H, hLen)) { + RSAerr(RSA_F_RSA_VERIFY_PKCS1_PSS_MGF1, RSA_R_BAD_SIGNATURE); + ret = 0; + } else + ret = 1; + + err: + if (DB) + OPENSSL_free(DB); + EVP_MD_CTX_cleanup(&ctx); + + return ret; + +} + +int RSA_padding_add_PKCS1_PSS(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, int sLen) +{ + return RSA_padding_add_PKCS1_PSS_mgf1(rsa, EM, mHash, Hash, NULL, sLen); +} + +int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, unsigned char *EM, + const unsigned char *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + int sLen) +{ + int i; + int ret = 0; + int hLen, maskedDBLen, MSBits, emLen; + unsigned char *H, *salt = NULL, *p; + EVP_MD_CTX ctx; + + if (mgf1Hash == NULL) + mgf1Hash = Hash; + + hLen = EVP_MD_size(Hash); + if (hLen < 0) + goto err; + /*- + * Negative sLen has special meanings: + * -1 sLen == hLen + * -2 salt length is maximized + * -N reserved + */ + if (sLen == -1) + sLen = hLen; + else if (sLen == -2) + sLen = -2; + else if (sLen < -2) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + + MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + emLen = RSA_size(rsa); + if (MSBits == 0) { + *EM++ = 0; + emLen--; + } + if (sLen == -2) { + sLen = emLen - hLen - 2; + } else if (emLen < (hLen + sLen + 2)) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + goto err; + } + if (sLen > 0) { + salt = OPENSSL_malloc(sLen); + if (!salt) { + RSAerr(RSA_F_RSA_PADDING_ADD_PKCS1_PSS_MGF1, + ERR_R_MALLOC_FAILURE); + goto err; + } + if (RAND_bytes(salt, sLen) <= 0) + goto err; + } + maskedDBLen = emLen - hLen - 1; + H = EM + maskedDBLen; + EVP_MD_CTX_init(&ctx); + if (!EVP_DigestInit_ex(&ctx, Hash, NULL) + || !EVP_DigestUpdate(&ctx, zeroes, sizeof zeroes) + || !EVP_DigestUpdate(&ctx, mHash, hLen)) + goto err; + if (sLen && !EVP_DigestUpdate(&ctx, salt, sLen)) + goto err; + if (!EVP_DigestFinal_ex(&ctx, H, NULL)) + goto err; + EVP_MD_CTX_cleanup(&ctx); + + /* Generate dbMask in place then perform XOR on it */ + if (PKCS1_MGF1(EM, maskedDBLen, H, hLen, mgf1Hash)) + goto err; + + p = EM; + + /* + * Initial PS XORs with all zeroes which is a NOP so just update pointer. + * Note from a test above this value is guaranteed to be non-negative. + */ + p += emLen - sLen - hLen - 2; + *p++ ^= 0x1; + if (sLen > 0) { + for (i = 0; i < sLen; i++) + *p++ ^= salt[i]; + } + if (MSBits) + EM[0] &= 0xFF >> (8 - MSBits); + + /* H is already in place so just set final 0xbc */ + + EM[emLen - 1] = 0xbc; + + ret = 1; + + err: + if (salt) + OPENSSL_free(salt); + + return ret; + +} + +#if defined(_MSC_VER) +# pragma optimize("",on) +#endif diff --git a/libs/openssl/crypto/rsa/rsa_saos.c b/libs/openssl/crypto/rsa/rsa_saos.c new file mode 100644 index 00000000..e4002360 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_saos.c @@ -0,0 +1,148 @@ +/* crypto/rsa/rsa_saos.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +int RSA_sign_ASN1_OCTET_STRING(int type, + const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, + RSA *rsa) +{ + ASN1_OCTET_STRING sig; + int i, j, ret = 1; + unsigned char *p, *s; + + sig.type = V_ASN1_OCTET_STRING; + sig.length = m_len; + sig.data = (unsigned char *)m; + + i = i2d_ASN1_OCTET_STRING(&sig, NULL); + j = RSA_size(rsa); + if (i > (j - RSA_PKCS1_PADDING_SIZE)) { + RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, + RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + return (0); + } + s = (unsigned char *)OPENSSL_malloc((unsigned int)j + 1); + if (s == NULL) { + RSAerr(RSA_F_RSA_SIGN_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); + return (0); + } + p = s; + i2d_ASN1_OCTET_STRING(&sig, &p); + i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); + if (i <= 0) + ret = 0; + else + *siglen = i; + + OPENSSL_cleanse(s, (unsigned int)j + 1); + OPENSSL_free(s); + return (ret); +} + +int RSA_verify_ASN1_OCTET_STRING(int dtype, + const unsigned char *m, + unsigned int m_len, unsigned char *sigbuf, + unsigned int siglen, RSA *rsa) +{ + int i, ret = 0; + unsigned char *s; + const unsigned char *p; + ASN1_OCTET_STRING *sig = NULL; + + if (siglen != (unsigned int)RSA_size(rsa)) { + RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, + RSA_R_WRONG_SIGNATURE_LENGTH); + return (0); + } + + s = (unsigned char *)OPENSSL_malloc((unsigned int)siglen); + if (s == NULL) { + RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); + goto err; + } + i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); + + if (i <= 0) + goto err; + + p = s; + sig = d2i_ASN1_OCTET_STRING(NULL, &p, (long)i); + if (sig == NULL) + goto err; + + if (((unsigned int)sig->length != m_len) || + (memcmp(m, sig->data, m_len) != 0)) { + RSAerr(RSA_F_RSA_VERIFY_ASN1_OCTET_STRING, RSA_R_BAD_SIGNATURE); + } else + ret = 1; + err: + if (sig != NULL) + M_ASN1_OCTET_STRING_free(sig); + if (s != NULL) { + OPENSSL_cleanse(s, (unsigned int)siglen); + OPENSSL_free(s); + } + return (ret); +} diff --git a/libs/openssl/crypto/rsa/rsa_sign.c b/libs/openssl/crypto/rsa/rsa_sign.c new file mode 100644 index 00000000..41c827f4 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_sign.c @@ -0,0 +1,312 @@ +/* crypto/rsa/rsa_sign.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include "rsa_locl.h" + +/* Size of an SSL signature: MD5+SHA1 */ +#define SSL_SIG_LENGTH 36 + +int RSA_sign(int type, const unsigned char *m, unsigned int m_len, + unsigned char *sigret, unsigned int *siglen, RSA *rsa) +{ + X509_SIG sig; + ASN1_TYPE parameter; + int i, j, ret = 1; + unsigned char *p, *tmps = NULL; + const unsigned char *s = NULL; + X509_ALGOR algor; + ASN1_OCTET_STRING digest; +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_RSA_SIGN, RSA_R_NON_FIPS_RSA_METHOD); + return 0; + } +#endif + if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_sign) { + return rsa->meth->rsa_sign(type, m, m_len, sigret, siglen, rsa); + } + /* Special case: SSL signature, just check the length */ + if (type == NID_md5_sha1) { + if (m_len != SSL_SIG_LENGTH) { + RSAerr(RSA_F_RSA_SIGN, RSA_R_INVALID_MESSAGE_LENGTH); + return (0); + } + i = SSL_SIG_LENGTH; + s = m; + } else { + sig.algor = &algor; + sig.algor->algorithm = OBJ_nid2obj(type); + if (sig.algor->algorithm == NULL) { + RSAerr(RSA_F_RSA_SIGN, RSA_R_UNKNOWN_ALGORITHM_TYPE); + return (0); + } + if (sig.algor->algorithm->length == 0) { + RSAerr(RSA_F_RSA_SIGN, + RSA_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD); + return (0); + } + parameter.type = V_ASN1_NULL; + parameter.value.ptr = NULL; + sig.algor->parameter = ¶meter; + + sig.digest = &digest; + sig.digest->data = (unsigned char *)m; /* TMP UGLY CAST */ + sig.digest->length = m_len; + + i = i2d_X509_SIG(&sig, NULL); + } + j = RSA_size(rsa); + if (i > (j - RSA_PKCS1_PADDING_SIZE)) { + RSAerr(RSA_F_RSA_SIGN, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + return (0); + } + if (type != NID_md5_sha1) { + tmps = (unsigned char *)OPENSSL_malloc((unsigned int)j + 1); + if (tmps == NULL) { + RSAerr(RSA_F_RSA_SIGN, ERR_R_MALLOC_FAILURE); + return (0); + } + p = tmps; + i2d_X509_SIG(&sig, &p); + s = tmps; + } + i = RSA_private_encrypt(i, s, sigret, rsa, RSA_PKCS1_PADDING); + if (i <= 0) + ret = 0; + else + *siglen = i; + + if (type != NID_md5_sha1) { + OPENSSL_cleanse(tmps, (unsigned int)j + 1); + OPENSSL_free(tmps); + } + return (ret); +} + +/* + * Check DigestInfo structure does not contain extraneous data by reencoding + * using DER and checking encoding against original. + */ +static int rsa_check_digestinfo(X509_SIG *sig, const unsigned char *dinfo, + int dinfolen) +{ + unsigned char *der = NULL; + int derlen; + int ret = 0; + derlen = i2d_X509_SIG(sig, &der); + if (derlen <= 0) + return 0; + if (derlen == dinfolen && !memcmp(dinfo, der, derlen)) + ret = 1; + OPENSSL_cleanse(der, derlen); + OPENSSL_free(der); + return ret; +} + +int int_rsa_verify(int dtype, const unsigned char *m, + unsigned int m_len, + unsigned char *rm, size_t *prm_len, + const unsigned char *sigbuf, size_t siglen, RSA *rsa) +{ + int i, ret = 0, sigtype; + unsigned char *s; + X509_SIG *sig = NULL; + +#ifdef OPENSSL_FIPS + if (FIPS_mode() && !(rsa->meth->flags & RSA_FLAG_FIPS_METHOD) + && !(rsa->flags & RSA_FLAG_NON_FIPS_ALLOW)) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_NON_FIPS_RSA_METHOD); + return 0; + } +#endif + + if (siglen != (unsigned int)RSA_size(rsa)) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_WRONG_SIGNATURE_LENGTH); + return (0); + } + + if ((dtype == NID_md5_sha1) && rm) { + i = RSA_public_decrypt((int)siglen, + sigbuf, rm, rsa, RSA_PKCS1_PADDING); + if (i <= 0) + return 0; + *prm_len = i; + return 1; + } + + s = (unsigned char *)OPENSSL_malloc((unsigned int)siglen); + if (s == NULL) { + RSAerr(RSA_F_INT_RSA_VERIFY, ERR_R_MALLOC_FAILURE); + goto err; + } + if ((dtype == NID_md5_sha1) && (m_len != SSL_SIG_LENGTH)) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_MESSAGE_LENGTH); + goto err; + } + i = RSA_public_decrypt((int)siglen, sigbuf, s, rsa, RSA_PKCS1_PADDING); + + if (i <= 0) + goto err; + /* + * Oddball MDC2 case: signature can be OCTET STRING. check for correct + * tag and length octets. + */ + if (dtype == NID_mdc2 && i == 18 && s[0] == 0x04 && s[1] == 0x10) { + if (rm) { + memcpy(rm, s + 2, 16); + *prm_len = 16; + ret = 1; + } else if (memcmp(m, s + 2, 16)) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + } else { + ret = 1; + } + } else if (dtype == NID_md5_sha1) { + /* Special case: SSL signature */ + if ((i != SSL_SIG_LENGTH) || memcmp(s, m, SSL_SIG_LENGTH)) + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + else + ret = 1; + } else { + const unsigned char *p = s; + sig = d2i_X509_SIG(NULL, &p, (long)i); + + if (sig == NULL) + goto err; + + /* Excess data can be used to create forgeries */ + if (p != s + i || !rsa_check_digestinfo(sig, s, i)) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + goto err; + } + + /* + * Parameters to the signature algorithm can also be used to create + * forgeries + */ + if (sig->algor->parameter + && ASN1_TYPE_get(sig->algor->parameter) != V_ASN1_NULL) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + goto err; + } + + sigtype = OBJ_obj2nid(sig->algor->algorithm); + +#ifdef RSA_DEBUG + /* put a backward compatibility flag in EAY */ + fprintf(stderr, "in(%s) expect(%s)\n", OBJ_nid2ln(sigtype), + OBJ_nid2ln(dtype)); +#endif + if (sigtype != dtype) { + if (((dtype == NID_md5) && + (sigtype == NID_md5WithRSAEncryption)) || + ((dtype == NID_md2) && + (sigtype == NID_md2WithRSAEncryption))) { + /* ok, we will let it through */ +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) + fprintf(stderr, + "signature has problems, re-make with post SSLeay045\n"); +#endif + } else { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_ALGORITHM_MISMATCH); + goto err; + } + } + if (rm) { + const EVP_MD *md; + md = EVP_get_digestbynid(dtype); + if (md && (EVP_MD_size(md) != sig->digest->length)) + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_INVALID_DIGEST_LENGTH); + else { + memcpy(rm, sig->digest->data, sig->digest->length); + *prm_len = sig->digest->length; + ret = 1; + } + } else if (((unsigned int)sig->digest->length != m_len) || + (memcmp(m, sig->digest->data, m_len) != 0)) { + RSAerr(RSA_F_INT_RSA_VERIFY, RSA_R_BAD_SIGNATURE); + } else + ret = 1; + } + err: + if (sig != NULL) + X509_SIG_free(sig); + if (s != NULL) { + OPENSSL_cleanse(s, (unsigned int)siglen); + OPENSSL_free(s); + } + return (ret); +} + +int RSA_verify(int dtype, const unsigned char *m, unsigned int m_len, + const unsigned char *sigbuf, unsigned int siglen, RSA *rsa) +{ + + if ((rsa->flags & RSA_FLAG_SIGN_VER) && rsa->meth->rsa_verify) { + return rsa->meth->rsa_verify(dtype, m, m_len, sigbuf, siglen, rsa); + } + + return int_rsa_verify(dtype, m, m_len, NULL, NULL, sigbuf, siglen, rsa); +} diff --git a/libs/openssl/crypto/rsa/rsa_ssl.c b/libs/openssl/crypto/rsa/rsa_ssl.c new file mode 100644 index 00000000..746e01f6 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_ssl.c @@ -0,0 +1,149 @@ +/* crypto/rsa/rsa_ssl.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +int RSA_padding_add_SSLv23(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + int i, j; + unsigned char *p; + + if (flen > (tlen - 11)) { + RSAerr(RSA_F_RSA_PADDING_ADD_SSLV23, + RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return (0); + } + + p = (unsigned char *)to; + + *(p++) = 0; + *(p++) = 2; /* Public Key BT (Block Type) */ + + /* pad out with non-zero random data */ + j = tlen - 3 - 8 - flen; + + if (RAND_bytes(p, j) <= 0) + return (0); + for (i = 0; i < j; i++) { + if (*p == '\0') + do { + if (RAND_bytes(p, 1) <= 0) + return (0); + } while (*p == '\0'); + p++; + } + + memset(p, 3, 8); + p += 8; + *(p++) = '\0'; + + memcpy(p, from, (unsigned int)flen); + return (1); +} + +int RSA_padding_check_SSLv23(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num) +{ + int i, j, k; + const unsigned char *p; + + p = from; + if (flen < 10) { + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_SMALL); + return (-1); + } + if ((num != (flen + 1)) || (*(p++) != 02)) { + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_BLOCK_TYPE_IS_NOT_02); + return (-1); + } + + /* scan over padding data */ + j = flen - 1; /* one for type */ + for (i = 0; i < j; i++) + if (*(p++) == 0) + break; + + if ((i == j) || (i < 8)) { + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, + RSA_R_NULL_BEFORE_BLOCK_MISSING); + return (-1); + } + for (k = -9; k < -1; k++) { + if (p[k] != 0x03) + break; + } + if (k == -1) { + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_SSLV3_ROLLBACK_ATTACK); + return (-1); + } + + i++; /* Skip over the '\0' */ + j -= i; + if (j > tlen) { + RSAerr(RSA_F_RSA_PADDING_CHECK_SSLV23, RSA_R_DATA_TOO_LARGE); + return (-1); + } + memcpy(to, p, (unsigned int)j); + + return (j); +} diff --git a/libs/openssl/crypto/rsa/rsa_test.c b/libs/openssl/crypto/rsa/rsa_test.c new file mode 100644 index 00000000..85c7440b --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_test.c @@ -0,0 +1,339 @@ +/* test vectors from p1ovect1.txt */ + +#include +#include + +#include "e_os.h" + +#include +#include +#include +#include +#ifdef OPENSSL_NO_RSA +int main(int argc, char *argv[]) +{ + printf("No RSA support\n"); + return (0); +} +#else +# include + +# define SetKey \ + key->n = BN_bin2bn(n, sizeof(n)-1, key->n); \ + key->e = BN_bin2bn(e, sizeof(e)-1, key->e); \ + key->d = BN_bin2bn(d, sizeof(d)-1, key->d); \ + key->p = BN_bin2bn(p, sizeof(p)-1, key->p); \ + key->q = BN_bin2bn(q, sizeof(q)-1, key->q); \ + key->dmp1 = BN_bin2bn(dmp1, sizeof(dmp1)-1, key->dmp1); \ + key->dmq1 = BN_bin2bn(dmq1, sizeof(dmq1)-1, key->dmq1); \ + key->iqmp = BN_bin2bn(iqmp, sizeof(iqmp)-1, key->iqmp); \ + memcpy(c, ctext_ex, sizeof(ctext_ex) - 1); \ + return (sizeof(ctext_ex) - 1); + +static int key1(RSA *key, unsigned char *c) +{ + static unsigned char n[] = + "\x00\xAA\x36\xAB\xCE\x88\xAC\xFD\xFF\x55\x52\x3C\x7F\xC4\x52\x3F" + "\x90\xEF\xA0\x0D\xF3\x77\x4A\x25\x9F\x2E\x62\xB4\xC5\xD9\x9C\xB5" + "\xAD\xB3\x00\xA0\x28\x5E\x53\x01\x93\x0E\x0C\x70\xFB\x68\x76\x93" + "\x9C\xE6\x16\xCE\x62\x4A\x11\xE0\x08\x6D\x34\x1E\xBC\xAC\xA0\xA1" + "\xF5"; + + static unsigned char e[] = "\x11"; + + static unsigned char d[] = + "\x0A\x03\x37\x48\x62\x64\x87\x69\x5F\x5F\x30\xBC\x38\xB9\x8B\x44" + "\xC2\xCD\x2D\xFF\x43\x40\x98\xCD\x20\xD8\xA1\x38\xD0\x90\xBF\x64" + "\x79\x7C\x3F\xA7\xA2\xCD\xCB\x3C\xD1\xE0\xBD\xBA\x26\x54\xB4\xF9" + "\xDF\x8E\x8A\xE5\x9D\x73\x3D\x9F\x33\xB3\x01\x62\x4A\xFD\x1D\x51"; + + static unsigned char p[] = + "\x00\xD8\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5" + "\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x12" + "\x0D"; + + static unsigned char q[] = + "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9" + "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D" + "\x89"; + + static unsigned char dmp1[] = + "\x59\x0B\x95\x72\xA2\xC2\xA9\xC4\x06\x05\x9D\xC2\xAB\x2F\x1D\xAF" + "\xEB\x7E\x8B\x4F\x10\xA7\x54\x9E\x8E\xED\xF5\xB4\xFC\xE0\x9E\x05"; + + static unsigned char dmq1[] = + "\x00\x8E\x3C\x05\x21\xFE\x15\xE0\xEA\x06\xA3\x6F\xF0\xF1\x0C\x99" + "\x52\xC3\x5B\x7A\x75\x14\xFD\x32\x38\xB8\x0A\xAD\x52\x98\x62\x8D" + "\x51"; + + static unsigned char iqmp[] = + "\x36\x3F\xF7\x18\x9D\xA8\xE9\x0B\x1D\x34\x1F\x71\xD0\x9B\x76\xA8" + "\xA9\x43\xE1\x1D\x10\xB2\x4D\x24\x9F\x2D\xEA\xFE\xF8\x0C\x18\x26"; + + static unsigned char ctext_ex[] = + "\x1b\x8f\x05\xf9\xca\x1a\x79\x52\x6e\x53\xf3\xcc\x51\x4f\xdb\x89" + "\x2b\xfb\x91\x93\x23\x1e\x78\xb9\x92\xe6\x8d\x50\xa4\x80\xcb\x52" + "\x33\x89\x5c\x74\x95\x8d\x5d\x02\xab\x8c\x0f\xd0\x40\xeb\x58\x44" + "\xb0\x05\xc3\x9e\xd8\x27\x4a\x9d\xbf\xa8\x06\x71\x40\x94\x39\xd2"; + + SetKey; +} + +static int key2(RSA *key, unsigned char *c) +{ + static unsigned char n[] = + "\x00\xA3\x07\x9A\x90\xDF\x0D\xFD\x72\xAC\x09\x0C\xCC\x2A\x78\xB8" + "\x74\x13\x13\x3E\x40\x75\x9C\x98\xFA\xF8\x20\x4F\x35\x8A\x0B\x26" + "\x3C\x67\x70\xE7\x83\xA9\x3B\x69\x71\xB7\x37\x79\xD2\x71\x7B\xE8" + "\x34\x77\xCF"; + + static unsigned char e[] = "\x3"; + + static unsigned char d[] = + "\x6C\xAF\xBC\x60\x94\xB3\xFE\x4C\x72\xB0\xB3\x32\xC6\xFB\x25\xA2" + "\xB7\x62\x29\x80\x4E\x68\x65\xFC\xA4\x5A\x74\xDF\x0F\x8F\xB8\x41" + "\x3B\x52\xC0\xD0\xE5\x3D\x9B\x59\x0F\xF1\x9B\xE7\x9F\x49\xDD\x21" + "\xE5\xEB"; + + static unsigned char p[] = + "\x00\xCF\x20\x35\x02\x8B\x9D\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92" + "\xEA\x0D\xA3\xB4\x32\x04\xB5\xCF\xCE\x91"; + + static unsigned char q[] = + "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9" + "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5F"; + + static unsigned char dmp1[] = + "\x00\x8A\x15\x78\xAC\x5D\x13\xAF\x10\x2B\x22\xB9\x99\xCD\x74\x61" + "\xF1\x5E\x6D\x22\xCC\x03\x23\xDF\xDF\x0B"; + + static unsigned char dmq1[] = + "\x00\x86\x55\x21\x4A\xC5\x4D\x8D\x4E\xCD\x61\x77\xF1\xC7\x36\x90" + "\xCE\x2A\x48\x2C\x8B\x05\x99\xCB\xE0\x3F"; + + static unsigned char iqmp[] = + "\x00\x83\xEF\xEF\xB8\xA9\xA4\x0D\x1D\xB6\xED\x98\xAD\x84\xED\x13" + "\x35\xDC\xC1\x08\xF3\x22\xD0\x57\xCF\x8D"; + + static unsigned char ctext_ex[] = + "\x14\xbd\xdd\x28\xc9\x83\x35\x19\x23\x80\xe8\xe5\x49\xb1\x58\x2a" + "\x8b\x40\xb4\x48\x6d\x03\xa6\xa5\x31\x1f\x1f\xd5\xf0\xa1\x80\xe4" + "\x17\x53\x03\x29\xa9\x34\x90\x74\xb1\x52\x13\x54\x29\x08\x24\x52" + "\x62\x51"; + + SetKey; +} + +static int key3(RSA *key, unsigned char *c) +{ + static unsigned char n[] = + "\x00\xBB\xF8\x2F\x09\x06\x82\xCE\x9C\x23\x38\xAC\x2B\x9D\xA8\x71" + "\xF7\x36\x8D\x07\xEE\xD4\x10\x43\xA4\x40\xD6\xB6\xF0\x74\x54\xF5" + "\x1F\xB8\xDF\xBA\xAF\x03\x5C\x02\xAB\x61\xEA\x48\xCE\xEB\x6F\xCD" + "\x48\x76\xED\x52\x0D\x60\xE1\xEC\x46\x19\x71\x9D\x8A\x5B\x8B\x80" + "\x7F\xAF\xB8\xE0\xA3\xDF\xC7\x37\x72\x3E\xE6\xB4\xB7\xD9\x3A\x25" + "\x84\xEE\x6A\x64\x9D\x06\x09\x53\x74\x88\x34\xB2\x45\x45\x98\x39" + "\x4E\xE0\xAA\xB1\x2D\x7B\x61\xA5\x1F\x52\x7A\x9A\x41\xF6\xC1\x68" + "\x7F\xE2\x53\x72\x98\xCA\x2A\x8F\x59\x46\xF8\xE5\xFD\x09\x1D\xBD" + "\xCB"; + + static unsigned char e[] = "\x11"; + + static unsigned char d[] = + "\x00\xA5\xDA\xFC\x53\x41\xFA\xF2\x89\xC4\xB9\x88\xDB\x30\xC1\xCD" + "\xF8\x3F\x31\x25\x1E\x06\x68\xB4\x27\x84\x81\x38\x01\x57\x96\x41" + "\xB2\x94\x10\xB3\xC7\x99\x8D\x6B\xC4\x65\x74\x5E\x5C\x39\x26\x69" + "\xD6\x87\x0D\xA2\xC0\x82\xA9\x39\xE3\x7F\xDC\xB8\x2E\xC9\x3E\xDA" + "\xC9\x7F\xF3\xAD\x59\x50\xAC\xCF\xBC\x11\x1C\x76\xF1\xA9\x52\x94" + "\x44\xE5\x6A\xAF\x68\xC5\x6C\x09\x2C\xD3\x8D\xC3\xBE\xF5\xD2\x0A" + "\x93\x99\x26\xED\x4F\x74\xA1\x3E\xDD\xFB\xE1\xA1\xCE\xCC\x48\x94" + "\xAF\x94\x28\xC2\xB7\xB8\x88\x3F\xE4\x46\x3A\x4B\xC8\x5B\x1C\xB3" + "\xC1"; + + static unsigned char p[] = + "\x00\xEE\xCF\xAE\x81\xB1\xB9\xB3\xC9\x08\x81\x0B\x10\xA1\xB5\x60" + "\x01\x99\xEB\x9F\x44\xAE\xF4\xFD\xA4\x93\xB8\x1A\x9E\x3D\x84\xF6" + "\x32\x12\x4E\xF0\x23\x6E\x5D\x1E\x3B\x7E\x28\xFA\xE7\xAA\x04\x0A" + "\x2D\x5B\x25\x21\x76\x45\x9D\x1F\x39\x75\x41\xBA\x2A\x58\xFB\x65" + "\x99"; + + static unsigned char q[] = + "\x00\xC9\x7F\xB1\xF0\x27\xF4\x53\xF6\x34\x12\x33\xEA\xAA\xD1\xD9" + "\x35\x3F\x6C\x42\xD0\x88\x66\xB1\xD0\x5A\x0F\x20\x35\x02\x8B\x9D" + "\x86\x98\x40\xB4\x16\x66\xB4\x2E\x92\xEA\x0D\xA3\xB4\x32\x04\xB5" + "\xCF\xCE\x33\x52\x52\x4D\x04\x16\xA5\xA4\x41\xE7\x00\xAF\x46\x15" + "\x03"; + + static unsigned char dmp1[] = + "\x54\x49\x4C\xA6\x3E\xBA\x03\x37\xE4\xE2\x40\x23\xFC\xD6\x9A\x5A" + "\xEB\x07\xDD\xDC\x01\x83\xA4\xD0\xAC\x9B\x54\xB0\x51\xF2\xB1\x3E" + "\xD9\x49\x09\x75\xEA\xB7\x74\x14\xFF\x59\xC1\xF7\x69\x2E\x9A\x2E" + "\x20\x2B\x38\xFC\x91\x0A\x47\x41\x74\xAD\xC9\x3C\x1F\x67\xC9\x81"; + + static unsigned char dmq1[] = + "\x47\x1E\x02\x90\xFF\x0A\xF0\x75\x03\x51\xB7\xF8\x78\x86\x4C\xA9" + "\x61\xAD\xBD\x3A\x8A\x7E\x99\x1C\x5C\x05\x56\xA9\x4C\x31\x46\xA7" + "\xF9\x80\x3F\x8F\x6F\x8A\xE3\x42\xE9\x31\xFD\x8A\xE4\x7A\x22\x0D" + "\x1B\x99\xA4\x95\x84\x98\x07\xFE\x39\xF9\x24\x5A\x98\x36\xDA\x3D"; + + static unsigned char iqmp[] = + "\x00\xB0\x6C\x4F\xDA\xBB\x63\x01\x19\x8D\x26\x5B\xDB\xAE\x94\x23" + "\xB3\x80\xF2\x71\xF7\x34\x53\x88\x50\x93\x07\x7F\xCD\x39\xE2\x11" + "\x9F\xC9\x86\x32\x15\x4F\x58\x83\xB1\x67\xA9\x67\xBF\x40\x2B\x4E" + "\x9E\x2E\x0F\x96\x56\xE6\x98\xEA\x36\x66\xED\xFB\x25\x79\x80\x39" + "\xF7"; + + static unsigned char ctext_ex[] = + "\xb8\x24\x6b\x56\xa6\xed\x58\x81\xae\xb5\x85\xd9\xa2\x5b\x2a\xd7" + "\x90\xc4\x17\xe0\x80\x68\x1b\xf1\xac\x2b\xc3\xde\xb6\x9d\x8b\xce" + "\xf0\xc4\x36\x6f\xec\x40\x0a\xf0\x52\xa7\x2e\x9b\x0e\xff\xb5\xb3" + "\xf2\xf1\x92\xdb\xea\xca\x03\xc1\x27\x40\x05\x71\x13\xbf\x1f\x06" + "\x69\xac\x22\xe9\xf3\xa7\x85\x2e\x3c\x15\xd9\x13\xca\xb0\xb8\x86" + "\x3a\x95\xc9\x92\x94\xce\x86\x74\x21\x49\x54\x61\x03\x46\xf4\xd4" + "\x74\xb2\x6f\x7c\x48\xb4\x2e\xe6\x8e\x1f\x57\x2a\x1f\xc4\x02\x6a" + "\xc4\x56\xb4\xf5\x9f\x7b\x62\x1e\xa1\xb9\xd8\x8f\x64\x20\x2f\xb1"; + + SetKey; +} + +static int pad_unknown(void) +{ + unsigned long l; + while ((l = ERR_get_error()) != 0) + if (ERR_GET_REASON(l) == RSA_R_UNKNOWN_PADDING_TYPE) + return (1); + return (0); +} + +static const char rnd_seed[] = + "string to make the random number generator think it has entropy"; + +int main(int argc, char *argv[]) +{ + int err = 0; + int v; + RSA *key; + unsigned char ptext[256]; + unsigned char ctext[256]; + static unsigned char ptext_ex[] = "\x54\x85\x9b\x34\x2c\x49\xea\x2a"; + unsigned char ctext_ex[256]; + int plen; + int clen = 0; + int num; + int n; + + CRYPTO_malloc_debug_init(); + CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + + RAND_seed(rnd_seed, sizeof rnd_seed); /* or OAEP may fail */ + + plen = sizeof(ptext_ex) - 1; + + for (v = 0; v < 6; v++) { + key = RSA_new(); + switch (v % 3) { + case 0: + clen = key1(key, ctext_ex); + break; + case 1: + clen = key2(key, ctext_ex); + break; + case 2: + clen = key3(key, ctext_ex); + break; + } + if (v / 3 >= 1) + key->flags |= RSA_FLAG_NO_CONSTTIME; + + num = RSA_public_encrypt(plen, ptext_ex, ctext, key, + RSA_PKCS1_PADDING); + if (num != clen) { + printf("PKCS#1 v1.5 encryption failed!\n"); + err = 1; + goto oaep; + } + + num = RSA_private_decrypt(num, ctext, ptext, key, RSA_PKCS1_PADDING); + if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { + printf("PKCS#1 v1.5 decryption failed!\n"); + err = 1; + } else + printf("PKCS #1 v1.5 encryption/decryption ok\n"); + + oaep: + ERR_clear_error(); + num = RSA_public_encrypt(plen, ptext_ex, ctext, key, + RSA_PKCS1_OAEP_PADDING); + if (num == -1 && pad_unknown()) { + printf("No OAEP support\n"); + goto next; + } + if (num != clen) { + printf("OAEP encryption failed!\n"); + err = 1; + goto next; + } + + num = RSA_private_decrypt(num, ctext, ptext, key, + RSA_PKCS1_OAEP_PADDING); + if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { + printf("OAEP decryption (encrypted data) failed!\n"); + err = 1; + } else if (memcmp(ctext, ctext_ex, num) == 0) + printf("OAEP test vector %d passed!\n", v); + + /* + * Different ciphertexts (rsa_oaep.c without -DPKCS_TESTVECT). Try + * decrypting ctext_ex + */ + + num = RSA_private_decrypt(clen, ctext_ex, ptext, key, + RSA_PKCS1_OAEP_PADDING); + + if (num != plen || memcmp(ptext, ptext_ex, num) != 0) { + printf("OAEP decryption (test vector data) failed!\n"); + err = 1; + } else + printf("OAEP encryption/decryption ok\n"); + + /* Try decrypting corrupted ciphertexts. */ + for (n = 0; n < clen; ++n) { + ctext[n] ^= 1; + num = RSA_private_decrypt(clen, ctext, ptext, key, + RSA_PKCS1_OAEP_PADDING); + if (num > 0) { + printf("Corrupt data decrypted!\n"); + err = 1; + break; + } + ctext[n] ^= 1; + } + + /* Test truncated ciphertexts, as well as negative length. */ + for (n = -1; n < clen; ++n) { + num = RSA_private_decrypt(n, ctext, ptext, key, + RSA_PKCS1_OAEP_PADDING); + if (num > 0) { + printf("Truncated data decrypted!\n"); + err = 1; + break; + } + } + + next: + RSA_free(key); + } + + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + + CRYPTO_mem_leaks_fp(stderr); + +# ifdef OPENSSL_SYS_NETWARE + if (err) + printf("ERROR: %d\n", err); +# endif + return err; +} +#endif diff --git a/libs/openssl/crypto/rsa/rsa_x931.c b/libs/openssl/crypto/rsa/rsa_x931.c new file mode 100644 index 00000000..725ead04 --- /dev/null +++ b/libs/openssl/crypto/rsa/rsa_x931.c @@ -0,0 +1,167 @@ +/* rsa_x931.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2005. + */ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +int RSA_padding_add_X931(unsigned char *to, int tlen, + const unsigned char *from, int flen) +{ + int j; + unsigned char *p; + + /* + * Absolute minimum amount of padding is 1 header nibble, 1 padding + * nibble and 2 trailer bytes: but 1 hash if is already in 'from'. + */ + + j = tlen - flen - 2; + + if (j < 0) { + RSAerr(RSA_F_RSA_PADDING_ADD_X931, RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE); + return -1; + } + + p = (unsigned char *)to; + + /* If no padding start and end nibbles are in one byte */ + if (j == 0) + *p++ = 0x6A; + else { + *p++ = 0x6B; + if (j > 1) { + memset(p, 0xBB, j - 1); + p += j - 1; + } + *p++ = 0xBA; + } + memcpy(p, from, (unsigned int)flen); + p += flen; + *p = 0xCC; + return (1); +} + +int RSA_padding_check_X931(unsigned char *to, int tlen, + const unsigned char *from, int flen, int num) +{ + int i = 0, j; + const unsigned char *p; + + p = from; + if ((num != flen) || ((*p != 0x6A) && (*p != 0x6B))) { + RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_HEADER); + return -1; + } + + if (*p++ == 0x6B) { + j = flen - 3; + for (i = 0; i < j; i++) { + unsigned char c = *p++; + if (c == 0xBA) + break; + if (c != 0xBB) { + RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING); + return -1; + } + } + + j -= i; + + if (i == 0) { + RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_PADDING); + return -1; + } + + } else + j = flen - 2; + + if (p[j] != 0xCC) { + RSAerr(RSA_F_RSA_PADDING_CHECK_X931, RSA_R_INVALID_TRAILER); + return -1; + } + + memcpy(to, p, (unsigned int)j); + + return (j); +} + +/* Translate between X931 hash ids and NIDs */ + +int RSA_X931_hash_id(int nid) +{ + switch (nid) { + case NID_sha1: + return 0x33; + + case NID_sha256: + return 0x34; + + case NID_sha384: + return 0x36; + + case NID_sha512: + return 0x35; + + } + return -1; +} diff --git a/libs/openssl/crypto/s390xcap.c b/libs/openssl/crypto/s390xcap.c new file mode 100644 index 00000000..47d6b6ff --- /dev/null +++ b/libs/openssl/crypto/s390xcap.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include + +extern unsigned long OPENSSL_s390xcap_P[]; + +static sigjmp_buf ill_jmp; +static void ill_handler(int sig) +{ + siglongjmp(ill_jmp, sig); +} + +unsigned long OPENSSL_s390x_facilities(void); + +void OPENSSL_cpuid_setup(void) +{ + sigset_t oset; + struct sigaction ill_act, oact; + + if (OPENSSL_s390xcap_P[0]) + return; + + OPENSSL_s390xcap_P[0] = 1UL << (8 * sizeof(unsigned long) - 1); + + memset(&ill_act, 0, sizeof(ill_act)); + ill_act.sa_handler = ill_handler; + sigfillset(&ill_act.sa_mask); + sigdelset(&ill_act.sa_mask, SIGILL); + sigdelset(&ill_act.sa_mask, SIGTRAP); + sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset); + sigaction(SIGILL, &ill_act, &oact); + + /* protection against missing store-facility-list-extended */ + if (sigsetjmp(ill_jmp, 1) == 0) + OPENSSL_s390x_facilities(); + + sigaction(SIGILL, &oact, NULL); + sigprocmask(SIG_SETMASK, &oset, NULL); +} diff --git a/libs/openssl/crypto/s390xcpuid.S b/libs/openssl/crypto/s390xcpuid.S new file mode 100644 index 00000000..06815347 --- /dev/null +++ b/libs/openssl/crypto/s390xcpuid.S @@ -0,0 +1,99 @@ +.text + +.globl OPENSSL_s390x_facilities +.type OPENSSL_s390x_facilities,@function +.align 16 +OPENSSL_s390x_facilities: + lghi %r0,0 + larl %r2,OPENSSL_s390xcap_P + stg %r0,8(%r2) + .long 0xb2b02000 # stfle 0(%r2) + brc 8,.Ldone + lghi %r0,1 + .long 0xb2b02000 # stfle 0(%r2) +.Ldone: + lg %r2,0(%r2) + br %r14 +.size OPENSSL_s390x_facilities,.-OPENSSL_s390x_facilities + +.globl OPENSSL_rdtsc +.type OPENSSL_rdtsc,@function +.align 16 +OPENSSL_rdtsc: + stck 16(%r15) + lg %r2,16(%r15) + br %r14 +.size OPENSSL_rdtsc,.-OPENSSL_rdtsc + +.globl OPENSSL_atomic_add +.type OPENSSL_atomic_add,@function +.align 16 +OPENSSL_atomic_add: + l %r1,0(%r2) +.Lspin: lr %r0,%r1 + ar %r0,%r3 + cs %r1,%r0,0(%r2) + brc 4,.Lspin + lgfr %r2,%r0 # OpenSSL expects the new value + br %r14 +.size OPENSSL_atomic_add,.-OPENSSL_atomic_add + +.globl OPENSSL_wipe_cpu +.type OPENSSL_wipe_cpu,@function +.align 16 +OPENSSL_wipe_cpu: + xgr %r0,%r0 + xgr %r1,%r1 + lgr %r2,%r15 + xgr %r3,%r3 + xgr %r4,%r4 + lzdr %f0 + lzdr %f1 + lzdr %f2 + lzdr %f3 + lzdr %f4 + lzdr %f5 + lzdr %f6 + lzdr %f7 + br %r14 +.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu + +.globl OPENSSL_cleanse +.type OPENSSL_cleanse,@function +.align 16 +OPENSSL_cleanse: +#if !defined(__s390x__) && !defined(__s390x) + llgfr %r3,%r3 +#endif + lghi %r4,15 + lghi %r0,0 + clgr %r3,%r4 + jh .Lot + clgr %r3,%r0 + bcr 8,%r14 +.Little: + stc %r0,0(%r2) + la %r2,1(%r2) + brctg %r3,.Little + br %r14 +.align 4 +.Lot: tmll %r2,7 + jz .Laligned + stc %r0,0(%r2) + la %r2,1(%r2) + brctg %r3,.Lot +.Laligned: + srlg %r4,%r3,3 +.Loop: stg %r0,0(%r2) + la %r2,8(%r2) + brctg %r4,.Loop + lghi %r4,7 + ngr %r3,%r4 + jnz .Little + br %r14 +.size OPENSSL_cleanse,.-OPENSSL_cleanse + +.section .init + brasl %r14,OPENSSL_cpuid_setup + +.comm OPENSSL_s390xcap_P,16,8 diff --git a/libs/openssl/crypto/seed/seed.c b/libs/openssl/crypto/seed/seed.c new file mode 100644 index 00000000..a9058722 --- /dev/null +++ b/libs/openssl/crypto/seed/seed.c @@ -0,0 +1,711 @@ +/* + * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of author nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#ifndef OPENSSL_NO_SEED + +# include +# include +# include +# ifdef WIN32 +# include +# endif + +# include +# include +# include "seed_locl.h" + +# ifdef SS /* can get defined on Solaris by inclusion of + * */ +# undef SS +# endif + +static const seed_word SS[4][256] = { { + 0x2989a1a8, 0x05858184, 0x16c6d2d4, + 0x13c3d3d0, 0x14445054, 0x1d0d111c, + 0x2c8ca0ac, 0x25052124, + 0x1d4d515c, 0x03434340, 0x18081018, + 0x1e0e121c, 0x11415150, 0x3cccf0fc, + 0x0acac2c8, 0x23436360, + 0x28082028, 0x04444044, 0x20002020, + 0x1d8d919c, 0x20c0e0e0, 0x22c2e2e0, + 0x08c8c0c8, 0x17071314, + 0x2585a1a4, 0x0f8f838c, 0x03030300, + 0x3b4b7378, 0x3b8bb3b8, 0x13031310, + 0x12c2d2d0, 0x2ecee2ec, + 0x30407070, 0x0c8c808c, 0x3f0f333c, + 0x2888a0a8, 0x32023230, 0x1dcdd1dc, + 0x36c6f2f4, 0x34447074, + 0x2ccce0ec, 0x15859194, 0x0b0b0308, + 0x17475354, 0x1c4c505c, 0x1b4b5358, + 0x3d8db1bc, 0x01010100, + 0x24042024, 0x1c0c101c, 0x33437370, + 0x18889098, 0x10001010, 0x0cccc0cc, + 0x32c2f2f0, 0x19c9d1d8, + 0x2c0c202c, 0x27c7e3e4, 0x32427270, + 0x03838380, 0x1b8b9398, 0x11c1d1d0, + 0x06868284, 0x09c9c1c8, + 0x20406060, 0x10405050, 0x2383a3a0, + 0x2bcbe3e8, 0x0d0d010c, 0x3686b2b4, + 0x1e8e929c, 0x0f4f434c, + 0x3787b3b4, 0x1a4a5258, 0x06c6c2c4, + 0x38487078, 0x2686a2a4, 0x12021210, + 0x2f8fa3ac, 0x15c5d1d4, + 0x21416160, 0x03c3c3c0, 0x3484b0b4, + 0x01414140, 0x12425250, 0x3d4d717c, + 0x0d8d818c, 0x08080008, + 0x1f0f131c, 0x19899198, 0x00000000, + 0x19091118, 0x04040004, 0x13435350, + 0x37c7f3f4, 0x21c1e1e0, + 0x3dcdf1fc, 0x36467274, 0x2f0f232c, + 0x27072324, 0x3080b0b0, 0x0b8b8388, + 0x0e0e020c, 0x2b8ba3a8, + 0x2282a2a0, 0x2e4e626c, 0x13839390, + 0x0d4d414c, 0x29496168, 0x3c4c707c, + 0x09090108, 0x0a0a0208, + 0x3f8fb3bc, 0x2fcfe3ec, 0x33c3f3f0, + 0x05c5c1c4, 0x07878384, 0x14041014, + 0x3ecef2fc, 0x24446064, + 0x1eced2dc, 0x2e0e222c, 0x0b4b4348, + 0x1a0a1218, 0x06060204, 0x21012120, + 0x2b4b6368, 0x26466264, + 0x02020200, 0x35c5f1f4, 0x12829290, + 0x0a8a8288, 0x0c0c000c, 0x3383b3b0, + 0x3e4e727c, 0x10c0d0d0, + 0x3a4a7278, 0x07474344, 0x16869294, + 0x25c5e1e4, 0x26062224, 0x00808080, + 0x2d8da1ac, 0x1fcfd3dc, + 0x2181a1a0, 0x30003030, 0x37073334, + 0x2e8ea2ac, 0x36063234, 0x15051114, + 0x22022220, 0x38083038, + 0x34c4f0f4, 0x2787a3a4, 0x05454144, + 0x0c4c404c, 0x01818180, 0x29c9e1e8, + 0x04848084, 0x17879394, + 0x35053134, 0x0bcbc3c8, 0x0ecec2cc, + 0x3c0c303c, 0x31417170, 0x11011110, + 0x07c7c3c4, 0x09898188, + 0x35457174, 0x3bcbf3f8, 0x1acad2d8, + 0x38c8f0f8, 0x14849094, 0x19495158, + 0x02828280, 0x04c4c0c4, + 0x3fcff3fc, 0x09494148, 0x39093138, + 0x27476364, 0x00c0c0c0, 0x0fcfc3cc, + 0x17c7d3d4, 0x3888b0b8, + 0x0f0f030c, 0x0e8e828c, 0x02424240, + 0x23032320, 0x11819190, 0x2c4c606c, + 0x1bcbd3d8, 0x2484a0a4, + 0x34043034, 0x31c1f1f0, 0x08484048, + 0x02c2c2c0, 0x2f4f636c, 0x3d0d313c, + 0x2d0d212c, 0x00404040, + 0x3e8eb2bc, 0x3e0e323c, 0x3c8cb0bc, + 0x01c1c1c0, 0x2a8aa2a8, 0x3a8ab2b8, + 0x0e4e424c, 0x15455154, + 0x3b0b3338, 0x1cccd0dc, 0x28486068, + 0x3f4f737c, 0x1c8c909c, 0x18c8d0d8, + 0x0a4a4248, 0x16465254, + 0x37477374, 0x2080a0a0, 0x2dcde1ec, + 0x06464244, 0x3585b1b4, 0x2b0b2328, + 0x25456164, 0x3acaf2f8, + 0x23c3e3e0, 0x3989b1b8, 0x3181b1b0, + 0x1f8f939c, 0x1e4e525c, 0x39c9f1f8, + 0x26c6e2e4, 0x3282b2b0, + 0x31013130, 0x2acae2e8, 0x2d4d616c, + 0x1f4f535c, 0x24c4e0e4, 0x30c0f0f0, + 0x0dcdc1cc, 0x08888088, + 0x16061214, 0x3a0a3238, 0x18485058, + 0x14c4d0d4, 0x22426260, 0x29092128, + 0x07070304, 0x33033330, + 0x28c8e0e8, 0x1b0b1318, 0x05050104, + 0x39497178, 0x10809090, 0x2a4a6268, + 0x2a0a2228, 0x1a8a9298}, { + 0x38380830, + 0xe828c8e0, + 0x2c2d0d21, + 0xa42686a2, + 0xcc0fcfc3, + 0xdc1eced2, + 0xb03383b3, + 0xb83888b0, + 0xac2f8fa3, + 0x60204060, + 0x54154551, + 0xc407c7c3, + 0x44044440, + 0x6c2f4f63, + 0x682b4b63, + 0x581b4b53, + 0xc003c3c3, + 0x60224262, + 0x30330333, + 0xb43585b1, + 0x28290921, + 0xa02080a0, + 0xe022c2e2, + 0xa42787a3, + 0xd013c3d3, + 0x90118191, + 0x10110111, + 0x04060602, + 0x1c1c0c10, + 0xbc3c8cb0, + 0x34360632, + 0x480b4b43, + 0xec2fcfe3, + 0x88088880, + 0x6c2c4c60, + 0xa82888a0, + 0x14170713, + 0xc404c4c0, + 0x14160612, + 0xf434c4f0, + 0xc002c2c2, + 0x44054541, + 0xe021c1e1, + 0xd416c6d2, + 0x3c3f0f33, + 0x3c3d0d31, + 0x8c0e8e82, + 0x98188890, + 0x28280820, + 0x4c0e4e42, + 0xf436c6f2, + 0x3c3e0e32, + 0xa42585a1, + 0xf839c9f1, + 0x0c0d0d01, + 0xdc1fcfd3, + 0xd818c8d0, + 0x282b0b23, + 0x64264662, + 0x783a4a72, + 0x24270723, + 0x2c2f0f23, + 0xf031c1f1, + 0x70324272, + 0x40024242, + 0xd414c4d0, + 0x40014141, + 0xc000c0c0, + 0x70334373, + 0x64274763, + 0xac2c8ca0, + 0x880b8b83, + 0xf437c7f3, + 0xac2d8da1, + 0x80008080, + 0x1c1f0f13, + 0xc80acac2, + 0x2c2c0c20, + 0xa82a8aa2, + 0x34340430, + 0xd012c2d2, + 0x080b0b03, + 0xec2ecee2, + 0xe829c9e1, + 0x5c1d4d51, + 0x94148490, + 0x18180810, + 0xf838c8f0, + 0x54174753, + 0xac2e8ea2, + 0x08080800, + 0xc405c5c1, + 0x10130313, + 0xcc0dcdc1, + 0x84068682, + 0xb83989b1, + 0xfc3fcff3, + 0x7c3d4d71, + 0xc001c1c1, + 0x30310131, + 0xf435c5f1, + 0x880a8a82, + 0x682a4a62, + 0xb03181b1, + 0xd011c1d1, + 0x20200020, + 0xd417c7d3, + 0x00020202, + 0x20220222, + 0x04040400, + 0x68284860, + 0x70314171, + 0x04070703, + 0xd81bcbd3, + 0x9c1d8d91, + 0x98198991, + 0x60214161, + 0xbc3e8eb2, + 0xe426c6e2, + 0x58194951, + 0xdc1dcdd1, + 0x50114151, + 0x90108090, + 0xdc1cccd0, + 0x981a8a92, + 0xa02383a3, + 0xa82b8ba3, + 0xd010c0d0, + 0x80018181, + 0x0c0f0f03, + 0x44074743, + 0x181a0a12, + 0xe023c3e3, + 0xec2ccce0, + 0x8c0d8d81, + 0xbc3f8fb3, + 0x94168692, + 0x783b4b73, + 0x5c1c4c50, + 0xa02282a2, + 0xa02181a1, + 0x60234363, + 0x20230323, + 0x4c0d4d41, + 0xc808c8c0, + 0x9c1e8e92, + 0x9c1c8c90, + 0x383a0a32, + 0x0c0c0c00, + 0x2c2e0e22, + 0xb83a8ab2, + 0x6c2e4e62, + 0x9c1f8f93, + 0x581a4a52, + 0xf032c2f2, + 0x90128292, + 0xf033c3f3, + 0x48094941, + 0x78384870, + 0xcc0cccc0, + 0x14150511, + 0xf83bcbf3, + 0x70304070, + 0x74354571, + 0x7c3f4f73, + 0x34350531, + 0x10100010, + 0x00030303, + 0x64244460, + 0x6c2d4d61, + 0xc406c6c2, + 0x74344470, + 0xd415c5d1, + 0xb43484b0, + 0xe82acae2, + 0x08090901, + 0x74364672, + 0x18190911, + 0xfc3ecef2, + 0x40004040, + 0x10120212, + 0xe020c0e0, + 0xbc3d8db1, + 0x04050501, + 0xf83acaf2, + 0x00010101, + 0xf030c0f0, + 0x282a0a22, + 0x5c1e4e52, + 0xa82989a1, + 0x54164652, + 0x40034343, + 0x84058581, + 0x14140410, + 0x88098981, + 0x981b8b93, + 0xb03080b0, + 0xe425c5e1, + 0x48084840, + 0x78394971, + 0x94178793, + 0xfc3cccf0, + 0x1c1e0e12, + 0x80028282, + 0x20210121, + 0x8c0c8c80, + 0x181b0b13, + 0x5c1f4f53, + 0x74374773, + 0x54144450, + 0xb03282b2, + 0x1c1d0d11, + 0x24250521, + 0x4c0f4f43, + 0x00000000, + 0x44064642, + 0xec2dcde1, + 0x58184850, + 0x50124252, + 0xe82bcbe3, + 0x7c3e4e72, + 0xd81acad2, + 0xc809c9c1, + 0xfc3dcdf1, + 0x30300030, + 0x94158591, + 0x64254561, + 0x3c3c0c30, + 0xb43686b2, + 0xe424c4e0, + 0xb83b8bb3, + 0x7c3c4c70, + 0x0c0e0e02, + 0x50104050, + 0x38390931, + 0x24260622, + 0x30320232, + 0x84048480, + 0x68294961, + 0x90138393, + 0x34370733, + 0xe427c7e3, + 0x24240420, + 0xa42484a0, + 0xc80bcbc3, + 0x50134353, + 0x080a0a02, + 0x84078783, + 0xd819c9d1, + 0x4c0c4c40, + 0x80038383, + 0x8c0f8f83, + 0xcc0ecec2, + 0x383b0b33, + 0x480a4a42, + 0xb43787b3}, +{ + 0xa1a82989, 0x81840585, 0xd2d416c6, 0xd3d013c3, 0x50541444, 0x111c1d0d, + 0xa0ac2c8c, 0x21242505, + 0x515c1d4d, 0x43400343, 0x10181808, 0x121c1e0e, 0x51501141, 0xf0fc3ccc, + 0xc2c80aca, 0x63602343, + 0x20282808, 0x40440444, 0x20202000, 0x919c1d8d, 0xe0e020c0, 0xe2e022c2, + 0xc0c808c8, 0x13141707, + 0xa1a42585, 0x838c0f8f, 0x03000303, 0x73783b4b, 0xb3b83b8b, 0x13101303, + 0xd2d012c2, 0xe2ec2ece, + 0x70703040, 0x808c0c8c, 0x333c3f0f, 0xa0a82888, 0x32303202, 0xd1dc1dcd, + 0xf2f436c6, 0x70743444, + 0xe0ec2ccc, 0x91941585, 0x03080b0b, 0x53541747, 0x505c1c4c, 0x53581b4b, + 0xb1bc3d8d, 0x01000101, + 0x20242404, 0x101c1c0c, 0x73703343, 0x90981888, 0x10101000, 0xc0cc0ccc, + 0xf2f032c2, 0xd1d819c9, + 0x202c2c0c, 0xe3e427c7, 0x72703242, 0x83800383, 0x93981b8b, 0xd1d011c1, + 0x82840686, 0xc1c809c9, + 0x60602040, 0x50501040, 0xa3a02383, 0xe3e82bcb, 0x010c0d0d, 0xb2b43686, + 0x929c1e8e, 0x434c0f4f, + 0xb3b43787, 0x52581a4a, 0xc2c406c6, 0x70783848, 0xa2a42686, 0x12101202, + 0xa3ac2f8f, 0xd1d415c5, + 0x61602141, 0xc3c003c3, 0xb0b43484, 0x41400141, 0x52501242, 0x717c3d4d, + 0x818c0d8d, 0x00080808, + 0x131c1f0f, 0x91981989, 0x00000000, 0x11181909, 0x00040404, 0x53501343, + 0xf3f437c7, 0xe1e021c1, + 0xf1fc3dcd, 0x72743646, 0x232c2f0f, 0x23242707, 0xb0b03080, 0x83880b8b, + 0x020c0e0e, 0xa3a82b8b, + 0xa2a02282, 0x626c2e4e, 0x93901383, 0x414c0d4d, 0x61682949, 0x707c3c4c, + 0x01080909, 0x02080a0a, + 0xb3bc3f8f, 0xe3ec2fcf, 0xf3f033c3, 0xc1c405c5, 0x83840787, 0x10141404, + 0xf2fc3ece, 0x60642444, + 0xd2dc1ece, 0x222c2e0e, 0x43480b4b, 0x12181a0a, 0x02040606, 0x21202101, + 0x63682b4b, 0x62642646, + 0x02000202, 0xf1f435c5, 0x92901282, 0x82880a8a, 0x000c0c0c, 0xb3b03383, + 0x727c3e4e, 0xd0d010c0, + 0x72783a4a, 0x43440747, 0x92941686, 0xe1e425c5, 0x22242606, 0x80800080, + 0xa1ac2d8d, 0xd3dc1fcf, + 0xa1a02181, 0x30303000, 0x33343707, 0xa2ac2e8e, 0x32343606, 0x11141505, + 0x22202202, 0x30383808, + 0xf0f434c4, 0xa3a42787, 0x41440545, 0x404c0c4c, 0x81800181, 0xe1e829c9, + 0x80840484, 0x93941787, + 0x31343505, 0xc3c80bcb, 0xc2cc0ece, 0x303c3c0c, 0x71703141, 0x11101101, + 0xc3c407c7, 0x81880989, + 0x71743545, 0xf3f83bcb, 0xd2d81aca, 0xf0f838c8, 0x90941484, 0x51581949, + 0x82800282, 0xc0c404c4, + 0xf3fc3fcf, 0x41480949, 0x31383909, 0x63642747, 0xc0c000c0, 0xc3cc0fcf, + 0xd3d417c7, 0xb0b83888, + 0x030c0f0f, 0x828c0e8e, 0x42400242, 0x23202303, 0x91901181, 0x606c2c4c, + 0xd3d81bcb, 0xa0a42484, + 0x30343404, 0xf1f031c1, 0x40480848, 0xc2c002c2, 0x636c2f4f, 0x313c3d0d, + 0x212c2d0d, 0x40400040, + 0xb2bc3e8e, 0x323c3e0e, 0xb0bc3c8c, 0xc1c001c1, 0xa2a82a8a, 0xb2b83a8a, + 0x424c0e4e, 0x51541545, + 0x33383b0b, 0xd0dc1ccc, 0x60682848, 0x737c3f4f, 0x909c1c8c, 0xd0d818c8, + 0x42480a4a, 0x52541646, + 0x73743747, 0xa0a02080, 0xe1ec2dcd, 0x42440646, 0xb1b43585, 0x23282b0b, + 0x61642545, 0xf2f83aca, + 0xe3e023c3, 0xb1b83989, 0xb1b03181, 0x939c1f8f, 0x525c1e4e, 0xf1f839c9, + 0xe2e426c6, 0xb2b03282, + 0x31303101, 0xe2e82aca, 0x616c2d4d, 0x535c1f4f, 0xe0e424c4, 0xf0f030c0, + 0xc1cc0dcd, 0x80880888, + 0x12141606, 0x32383a0a, 0x50581848, 0xd0d414c4, 0x62602242, 0x21282909, + 0x03040707, 0x33303303, + 0xe0e828c8, 0x13181b0b, 0x01040505, 0x71783949, 0x90901080, 0x62682a4a, + 0x22282a0a, 0x92981a8a}, { + 0x08303838, 0xc8e0e828, 0x0d212c2d, 0x86a2a426, + 0xcfc3cc0f, 0xced2dc1e, 0x83b3b033, 0x88b0b838, + 0x8fa3ac2f, 0x40606020, 0x45515415, 0xc7c3c407, + 0x44404404, 0x4f636c2f, 0x4b63682b, 0x4b53581b, + 0xc3c3c003, 0x42626022, 0x03333033, 0x85b1b435, + 0x09212829, 0x80a0a020, 0xc2e2e022, 0x87a3a427, + 0xc3d3d013, 0x81919011, 0x01111011, 0x06020406, + 0x0c101c1c, 0x8cb0bc3c, 0x06323436, 0x4b43480b, + 0xcfe3ec2f, 0x88808808, 0x4c606c2c, 0x88a0a828, + 0x07131417, 0xc4c0c404, 0x06121416, 0xc4f0f434, + 0xc2c2c002, 0x45414405, 0xc1e1e021, 0xc6d2d416, + 0x0f333c3f, 0x0d313c3d, 0x8e828c0e, 0x88909818, + 0x08202828, 0x4e424c0e, 0xc6f2f436, 0x0e323c3e, + 0x85a1a425, 0xc9f1f839, 0x0d010c0d, 0xcfd3dc1f, + 0xc8d0d818, 0x0b23282b, 0x46626426, 0x4a72783a, + 0x07232427, 0x0f232c2f, 0xc1f1f031, 0x42727032, + 0x42424002, 0xc4d0d414, 0x41414001, 0xc0c0c000, + 0x43737033, 0x47636427, 0x8ca0ac2c, 0x8b83880b, + 0xc7f3f437, 0x8da1ac2d, 0x80808000, 0x0f131c1f, + 0xcac2c80a, 0x0c202c2c, 0x8aa2a82a, 0x04303434, + 0xc2d2d012, 0x0b03080b, 0xcee2ec2e, 0xc9e1e829, + 0x4d515c1d, 0x84909414, 0x08101818, 0xc8f0f838, + 0x47535417, 0x8ea2ac2e, 0x08000808, 0xc5c1c405, + 0x03131013, 0xcdc1cc0d, 0x86828406, 0x89b1b839, + 0xcff3fc3f, 0x4d717c3d, 0xc1c1c001, 0x01313031, + 0xc5f1f435, 0x8a82880a, 0x4a62682a, 0x81b1b031, + 0xc1d1d011, 0x00202020, 0xc7d3d417, 0x02020002, + 0x02222022, 0x04000404, 0x48606828, 0x41717031, + 0x07030407, 0xcbd3d81b, 0x8d919c1d, 0x89919819, + 0x41616021, 0x8eb2bc3e, 0xc6e2e426, 0x49515819, + 0xcdd1dc1d, 0x41515011, 0x80909010, 0xccd0dc1c, + 0x8a92981a, 0x83a3a023, 0x8ba3a82b, 0xc0d0d010, + 0x81818001, 0x0f030c0f, 0x47434407, 0x0a12181a, + 0xc3e3e023, 0xcce0ec2c, 0x8d818c0d, 0x8fb3bc3f, + 0x86929416, 0x4b73783b, 0x4c505c1c, 0x82a2a022, + 0x81a1a021, 0x43636023, 0x03232023, 0x4d414c0d, + 0xc8c0c808, 0x8e929c1e, 0x8c909c1c, 0x0a32383a, + 0x0c000c0c, 0x0e222c2e, 0x8ab2b83a, 0x4e626c2e, + 0x8f939c1f, 0x4a52581a, 0xc2f2f032, 0x82929012, + 0xc3f3f033, 0x49414809, 0x48707838, 0xccc0cc0c, + 0x05111415, 0xcbf3f83b, 0x40707030, 0x45717435, + 0x4f737c3f, 0x05313435, 0x00101010, 0x03030003, + 0x44606424, 0x4d616c2d, 0xc6c2c406, 0x44707434, + 0xc5d1d415, 0x84b0b434, 0xcae2e82a, 0x09010809, + 0x46727436, 0x09111819, 0xcef2fc3e, 0x40404000, + 0x02121012, 0xc0e0e020, 0x8db1bc3d, 0x05010405, + 0xcaf2f83a, 0x01010001, 0xc0f0f030, 0x0a22282a, + 0x4e525c1e, 0x89a1a829, 0x46525416, 0x43434003, + 0x85818405, 0x04101414, 0x89818809, 0x8b93981b, + 0x80b0b030, 0xc5e1e425, 0x48404808, 0x49717839, + 0x87939417, 0xccf0fc3c, 0x0e121c1e, 0x82828002, + 0x01212021, 0x8c808c0c, 0x0b13181b, 0x4f535c1f, + 0x47737437, 0x44505414, 0x82b2b032, 0x0d111c1d, + 0x05212425, 0x4f434c0f, 0x00000000, 0x46424406, + 0xcde1ec2d, 0x48505818, 0x42525012, 0xcbe3e82b, + 0x4e727c3e, 0xcad2d81a, 0xc9c1c809, 0xcdf1fc3d, + 0x00303030, 0x85919415, 0x45616425, 0x0c303c3c, + 0x86b2b436, 0xc4e0e424, 0x8bb3b83b, 0x4c707c3c, + 0x0e020c0e, 0x40505010, 0x09313839, 0x06222426, + 0x02323032, 0x84808404, 0x49616829, 0x83939013, + 0x07333437, 0xc7e3e427, 0x04202424, 0x84a0a424, + 0xcbc3c80b, 0x43535013, 0x0a02080a, 0x87838407, + 0xc9d1d819, 0x4c404c0c, 0x83838003, 0x8f838c0f, + 0xcec2cc0e, 0x0b33383b, 0x4a42480a, 0x87b3b437} +}; + +/* key schedule constants - golden ratio */ +# define KC0 0x9e3779b9 +# define KC1 0x3c6ef373 +# define KC2 0x78dde6e6 +# define KC3 0xf1bbcdcc +# define KC4 0xe3779b99 +# define KC5 0xc6ef3733 +# define KC6 0x8dde6e67 +# define KC7 0x1bbcdccf +# define KC8 0x3779b99e +# define KC9 0x6ef3733c +# define KC10 0xdde6e678 +# define KC11 0xbbcdccf1 +# define KC12 0x779b99e3 +# define KC13 0xef3733c6 +# define KC14 0xde6e678d +# define KC15 0xbcdccf1b + +# if defined(OPENSSL_SMALL_FOOTPRINT) +static const seed_word KC[] = { + KC0, KC1, KC2, KC3, KC4, KC5, KC6, KC7, + KC8, KC9, KC10, KC11, KC12, KC13, KC14, KC15 +}; +# endif +void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], + SEED_KEY_SCHEDULE *ks) +# ifdef OPENSSL_FIPS +{ + fips_cipher_abort(SEED); + private_SEED_set_key(rawkey, ks); +} + +void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], + SEED_KEY_SCHEDULE *ks) +# endif +{ + seed_word x1, x2, x3, x4; + seed_word t0, t1; + + char2word(rawkey, x1); + char2word(rawkey + 4, x2); + char2word(rawkey + 8, x3); + char2word(rawkey + 12, x4); + + t0 = (x1 + x3 - KC0) & 0xffffffff; + t1 = (x2 - x4 + KC0) & 0xffffffff; + KEYUPDATE_TEMP(t0, t1, &ks->data[0]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC1); + KEYUPDATE_TEMP(t0, t1, &ks->data[2]); + +# if !defined(OPENSSL_SMALL_FOOTPRINT) + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC2); + KEYUPDATE_TEMP(t0, t1, &ks->data[4]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC3); + KEYUPDATE_TEMP(t0, t1, &ks->data[6]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC4); + KEYUPDATE_TEMP(t0, t1, &ks->data[8]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC5); + KEYUPDATE_TEMP(t0, t1, &ks->data[10]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC6); + KEYUPDATE_TEMP(t0, t1, &ks->data[12]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC7); + KEYUPDATE_TEMP(t0, t1, &ks->data[14]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC8); + KEYUPDATE_TEMP(t0, t1, &ks->data[16]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC9); + KEYUPDATE_TEMP(t0, t1, &ks->data[18]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC10); + KEYUPDATE_TEMP(t0, t1, &ks->data[20]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC11); + KEYUPDATE_TEMP(t0, t1, &ks->data[22]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC12); + KEYUPDATE_TEMP(t0, t1, &ks->data[24]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC13); + KEYUPDATE_TEMP(t0, t1, &ks->data[26]); + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC14); + KEYUPDATE_TEMP(t0, t1, &ks->data[28]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC15); + KEYUPDATE_TEMP(t0, t1, &ks->data[30]); +# else + { + int i; + for (i = 2; i < 16; i += 2) { + KEYSCHEDULE_UPDATE0(t0, t1, x1, x2, x3, x4, KC[i]); + KEYUPDATE_TEMP(t0, t1, &ks->data[i * 2]); + KEYSCHEDULE_UPDATE1(t0, t1, x1, x2, x3, x4, KC[i + 1]); + KEYUPDATE_TEMP(t0, t1, &ks->data[i * 2 + 2]); + } + } +# endif +} + +void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks) +{ + seed_word x1, x2, x3, x4; + seed_word t0, t1; + + char2word(s, x1); + char2word(s + 4, x2); + char2word(s + 8, x3); + char2word(s + 12, x4); + +# if !defined(OPENSSL_SMALL_FOOTPRINT) + E_SEED(t0, t1, x1, x2, x3, x4, 0); + E_SEED(t0, t1, x3, x4, x1, x2, 2); + E_SEED(t0, t1, x1, x2, x3, x4, 4); + E_SEED(t0, t1, x3, x4, x1, x2, 6); + E_SEED(t0, t1, x1, x2, x3, x4, 8); + E_SEED(t0, t1, x3, x4, x1, x2, 10); + E_SEED(t0, t1, x1, x2, x3, x4, 12); + E_SEED(t0, t1, x3, x4, x1, x2, 14); + E_SEED(t0, t1, x1, x2, x3, x4, 16); + E_SEED(t0, t1, x3, x4, x1, x2, 18); + E_SEED(t0, t1, x1, x2, x3, x4, 20); + E_SEED(t0, t1, x3, x4, x1, x2, 22); + E_SEED(t0, t1, x1, x2, x3, x4, 24); + E_SEED(t0, t1, x3, x4, x1, x2, 26); + E_SEED(t0, t1, x1, x2, x3, x4, 28); + E_SEED(t0, t1, x3, x4, x1, x2, 30); +# else + { + int i; + for (i = 0; i < 30; i += 4) { + E_SEED(t0, t1, x1, x2, x3, x4, i); + E_SEED(t0, t1, x3, x4, x1, x2, i + 2); + } + } +# endif + + word2char(x3, d); + word2char(x4, d + 4); + word2char(x1, d + 8); + word2char(x2, d + 12); +} + +void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks) +{ + seed_word x1, x2, x3, x4; + seed_word t0, t1; + + char2word(s, x1); + char2word(s + 4, x2); + char2word(s + 8, x3); + char2word(s + 12, x4); + +# if !defined(OPENSSL_SMALL_FOOTPRINT) + E_SEED(t0, t1, x1, x2, x3, x4, 30); + E_SEED(t0, t1, x3, x4, x1, x2, 28); + E_SEED(t0, t1, x1, x2, x3, x4, 26); + E_SEED(t0, t1, x3, x4, x1, x2, 24); + E_SEED(t0, t1, x1, x2, x3, x4, 22); + E_SEED(t0, t1, x3, x4, x1, x2, 20); + E_SEED(t0, t1, x1, x2, x3, x4, 18); + E_SEED(t0, t1, x3, x4, x1, x2, 16); + E_SEED(t0, t1, x1, x2, x3, x4, 14); + E_SEED(t0, t1, x3, x4, x1, x2, 12); + E_SEED(t0, t1, x1, x2, x3, x4, 10); + E_SEED(t0, t1, x3, x4, x1, x2, 8); + E_SEED(t0, t1, x1, x2, x3, x4, 6); + E_SEED(t0, t1, x3, x4, x1, x2, 4); + E_SEED(t0, t1, x1, x2, x3, x4, 2); + E_SEED(t0, t1, x3, x4, x1, x2, 0); +# else + { + int i; + for (i = 30; i > 0; i -= 4) { + E_SEED(t0, t1, x1, x2, x3, x4, i); + E_SEED(t0, t1, x3, x4, x1, x2, i - 2); + + } + } +# endif + + word2char(x3, d); + word2char(x4, d + 4); + word2char(x1, d + 8); + word2char(x2, d + 12); +} + +#endif /* OPENSSL_NO_SEED */ diff --git a/libs/openssl/crypto/seed/seed.h b/libs/openssl/crypto/seed/seed.h new file mode 100644 index 00000000..8cbf0d92 --- /dev/null +++ b/libs/openssl/crypto/seed/seed.h @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of author nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SEED_H +# define HEADER_SEED_H + +# include +# include +# include + +# ifdef OPENSSL_NO_SEED +# error SEED is disabled. +# endif + +/* look whether we need 'long' to get 32 bits */ +# ifdef AES_LONG +# ifndef SEED_LONG +# define SEED_LONG 1 +# endif +# endif + +# if !defined(NO_SYS_TYPES_H) +# include +# endif + +# define SEED_BLOCK_SIZE 16 +# define SEED_KEY_LENGTH 16 + + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct seed_key_st { +# ifdef SEED_LONG + unsigned long data[32]; +# else + unsigned int data[32]; +# endif +} SEED_KEY_SCHEDULE; + +# ifdef OPENSSL_FIPS +void private_SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], + SEED_KEY_SCHEDULE *ks); +# endif +void SEED_set_key(const unsigned char rawkey[SEED_KEY_LENGTH], + SEED_KEY_SCHEDULE *ks); + +void SEED_encrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks); +void SEED_decrypt(const unsigned char s[SEED_BLOCK_SIZE], + unsigned char d[SEED_BLOCK_SIZE], + const SEED_KEY_SCHEDULE *ks); + +void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, + const SEED_KEY_SCHEDULE *ks, int enc); +void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, size_t len, + const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int enc); +void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num, + int enc); +void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num); + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_SEED_H */ diff --git a/libs/openssl/crypto/seed/seed_cbc.c b/libs/openssl/crypto/seed/seed_cbc.c new file mode 100644 index 00000000..ee1115b4 --- /dev/null +++ b/libs/openssl/crypto/seed/seed_cbc.c @@ -0,0 +1,65 @@ +/* crypto/seed/seed_cbc.c */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include +#include + +void SEED_cbc_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int enc) +{ + if (enc) + CRYPTO_cbc128_encrypt(in, out, len, ks, ivec, + (block128_f) SEED_encrypt); + else + CRYPTO_cbc128_decrypt(in, out, len, ks, ivec, + (block128_f) SEED_decrypt); +} diff --git a/libs/openssl/crypto/seed/seed_cfb.c b/libs/openssl/crypto/seed/seed_cfb.c new file mode 100644 index 00000000..b6a5648b --- /dev/null +++ b/libs/openssl/crypto/seed/seed_cfb.c @@ -0,0 +1,118 @@ +/* crypto/seed/seed_cfb.c */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +void SEED_cfb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num, + int enc) +{ + CRYPTO_cfb128_encrypt(in, out, len, ks, ivec, num, enc, + (block128_f) SEED_encrypt); +} diff --git a/libs/openssl/crypto/seed/seed_ecb.c b/libs/openssl/crypto/seed/seed_ecb.c new file mode 100644 index 00000000..9363d550 --- /dev/null +++ b/libs/openssl/crypto/seed/seed_ecb.c @@ -0,0 +1,61 @@ +/* crypto/seed/seed_ecb.c */ +/* ==================================================================== + * Copyright (c) 2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include + +void SEED_ecb_encrypt(const unsigned char *in, unsigned char *out, + const SEED_KEY_SCHEDULE *ks, int enc) +{ + if (enc) + SEED_encrypt(in, out, ks); + else + SEED_decrypt(in, out, ks); +} diff --git a/libs/openssl/crypto/seed/seed_locl.h b/libs/openssl/crypto/seed/seed_locl.h new file mode 100644 index 00000000..96ec4302 --- /dev/null +++ b/libs/openssl/crypto/seed/seed_locl.h @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2007 KISA(Korea Information Security Agency). All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Neither the name of author nor the names of its contributors may + * be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#ifndef HEADER_SEED_LOCL_H +# define HEADER_SEED_LOCL_H + +# include "openssl/e_os2.h" +# include + +# ifdef SEED_LONG /* need 32-bit type */ +typedef unsigned long seed_word; +# else +typedef unsigned int seed_word; +# endif + + +#ifdef __cplusplus +extern "C" { +#endif + +# define G_FUNC(v) \ + SS[0][(unsigned char) (v) & 0xff] ^ SS[1][(unsigned char) ((v)>>8) & 0xff] ^ \ + SS[2][(unsigned char)((v)>>16) & 0xff] ^ SS[3][(unsigned char)((v)>>24) & 0xff] + +# define char2word(c, i) \ + (i) = ((((seed_word)(c)[0]) << 24) | (((seed_word)(c)[1]) << 16) | (((seed_word)(c)[2]) << 8) | ((seed_word)(c)[3])) + +# define word2char(l, c) \ + *((c)+0) = (unsigned char)((l)>>24) & 0xff; \ + *((c)+1) = (unsigned char)((l)>>16) & 0xff; \ + *((c)+2) = (unsigned char)((l)>> 8) & 0xff; \ + *((c)+3) = (unsigned char)((l)) & 0xff + +# define KEYSCHEDULE_UPDATE0(T0, T1, X1, X2, X3, X4, KC) \ + (T0) = (X3); \ + (X3) = (((X3)<<8) ^ ((X4)>>24)) & 0xffffffff; \ + (X4) = (((X4)<<8) ^ ((T0)>>24)) & 0xffffffff; \ + (T0) = ((X1) + (X3) - (KC)) & 0xffffffff; \ + (T1) = ((X2) + (KC) - (X4)) & 0xffffffff + +# define KEYSCHEDULE_UPDATE1(T0, T1, X1, X2, X3, X4, KC) \ + (T0) = (X1); \ + (X1) = (((X1)>>8) ^ ((X2)<<24)) & 0xffffffff; \ + (X2) = (((X2)>>8) ^ ((T0)<<24)) & 0xffffffff; \ + (T0) = ((X1) + (X3) - (KC)) & 0xffffffff; \ + (T1) = ((X2) + (KC) - (X4)) & 0xffffffff + +# define KEYUPDATE_TEMP(T0, T1, K) \ + (K)[0] = G_FUNC((T0)); \ + (K)[1] = G_FUNC((T1)) + +# define XOR_SEEDBLOCK(DST, SRC) \ + ((DST))[0] ^= ((SRC))[0]; \ + ((DST))[1] ^= ((SRC))[1]; \ + ((DST))[2] ^= ((SRC))[2]; \ + ((DST))[3] ^= ((SRC))[3] + +# define MOV_SEEDBLOCK(DST, SRC) \ + ((DST))[0] = ((SRC))[0]; \ + ((DST))[1] = ((SRC))[1]; \ + ((DST))[2] = ((SRC))[2]; \ + ((DST))[3] = ((SRC))[3] + +# define CHAR2WORD(C, I) \ + char2word((C), (I)[0]); \ + char2word((C+4), (I)[1]); \ + char2word((C+8), (I)[2]); \ + char2word((C+12), (I)[3]) + +# define WORD2CHAR(I, C) \ + word2char((I)[0], (C)); \ + word2char((I)[1], (C+4)); \ + word2char((I)[2], (C+8)); \ + word2char((I)[3], (C+12)) + +# define E_SEED(T0, T1, X1, X2, X3, X4, rbase) \ + (T0) = (X3) ^ (ks->data)[(rbase)]; \ + (T1) = (X4) ^ (ks->data)[(rbase)+1]; \ + (T1) ^= (T0); \ + (T1) = G_FUNC((T1)); \ + (T0) = ((T0) + (T1)) & 0xffffffff; \ + (T0) = G_FUNC((T0)); \ + (T1) = ((T1) + (T0)) & 0xffffffff; \ + (T1) = G_FUNC((T1)); \ + (T0) = ((T0) + (T1)) & 0xffffffff; \ + (X1) ^= (T0); \ + (X2) ^= (T1) + +#ifdef __cplusplus +} +#endif + +#endif /* HEADER_SEED_LOCL_H */ diff --git a/libs/openssl/crypto/seed/seed_ofb.c b/libs/openssl/crypto/seed/seed_ofb.c new file mode 100644 index 00000000..48b71224 --- /dev/null +++ b/libs/openssl/crypto/seed/seed_ofb.c @@ -0,0 +1,117 @@ +/* crypto/seed/seed_ofb.c */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +void SEED_ofb128_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const SEED_KEY_SCHEDULE *ks, + unsigned char ivec[SEED_BLOCK_SIZE], int *num) +{ + CRYPTO_ofb128_encrypt(in, out, len, ks, ivec, num, + (block128_f) SEED_encrypt); +} diff --git a/libs/openssl/crypto/sha/asm/README b/libs/openssl/crypto/sha/asm/README new file mode 100644 index 00000000..b7e75576 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/README @@ -0,0 +1 @@ +C2.pl works diff --git a/libs/openssl/crypto/sha/asm/sha1-586.pl b/libs/openssl/crypto/sha/asm/sha1-586.pl new file mode 100644 index 00000000..2b119ffa --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha1-586.pl @@ -0,0 +1,1229 @@ +#!/usr/bin/env perl + +# ==================================================================== +# [Re]written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# "[Re]written" was achieved in two major overhauls. In 2004 BODY_* +# functions were re-implemented to address P4 performance issue [see +# commentary below], and in 2006 the rest was rewritten in order to +# gain freedom to liberate licensing terms. + +# January, September 2004. +# +# It was noted that Intel IA-32 C compiler generates code which +# performs ~30% *faster* on P4 CPU than original *hand-coded* +# SHA1 assembler implementation. To address this problem (and +# prove that humans are still better than machines:-), the +# original code was overhauled, which resulted in following +# performance changes: +# +# compared with original compared with Intel cc +# assembler impl. generated code +# Pentium -16% +48% +# PIII/AMD +8% +16% +# P4 +85%(!) +45% +# +# As you can see Pentium came out as looser:-( Yet I reckoned that +# improvement on P4 outweights the loss and incorporate this +# re-tuned code to 0.9.7 and later. +# ---------------------------------------------------------------- +# + +# August 2009. +# +# George Spelvin has tipped that F_40_59(b,c,d) can be rewritten as +# '(c&d) + (b&(c^d))', which allows to accumulate partial results +# and lighten "pressure" on scratch registers. This resulted in +# >12% performance improvement on contemporary AMD cores (with no +# degradation on other CPUs:-). Also, the code was revised to maximize +# "distance" between instructions producing input to 'lea' instruction +# and the 'lea' instruction itself, which is essential for Intel Atom +# core and resulted in ~15% improvement. + +# October 2010. +# +# Add SSSE3, Supplemental[!] SSE3, implementation. The idea behind it +# is to offload message schedule denoted by Wt in NIST specification, +# or Xupdate in OpenSSL source, to SIMD unit. The idea is not novel, +# and in SSE2 context was first explored by Dean Gaudet in 2004, see +# http://arctic.org/~dean/crypto/sha1.html. Since then several things +# have changed that made it interesting again: +# +# a) XMM units became faster and wider; +# b) instruction set became more versatile; +# c) an important observation was made by Max Locktykhin, which made +# it possible to reduce amount of instructions required to perform +# the operation in question, for further details see +# http://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1/. + +# April 2011. +# +# Add AVX code path, probably most controversial... The thing is that +# switch to AVX alone improves performance by as little as 4% in +# comparison to SSSE3 code path. But below result doesn't look like +# 4% improvement... Trouble is that Sandy Bridge decodes 'ro[rl]' as +# pair of µ-ops, and it's the additional µ-ops, two per round, that +# make it run slower than Core2 and Westmere. But 'sh[rl]d' is decoded +# as single µ-op by Sandy Bridge and it's replacing 'ro[rl]' with +# equivalent 'sh[rl]d' that is responsible for the impressive 5.1 +# cycles per processed byte. But 'sh[rl]d' is not something that used +# to be fast, nor does it appear to be fast in upcoming Bulldozer +# [according to its optimization manual]. Which is why AVX code path +# is guarded by *both* AVX and synthetic bit denoting Intel CPUs. +# One can argue that it's unfair to AMD, but without 'sh[rl]d' it +# makes no sense to keep the AVX code path. If somebody feels that +# strongly, it's probably more appropriate to discuss possibility of +# using vector rotate XOP on AMD... + +###################################################################### +# Current performance is summarized in following table. Numbers are +# CPU clock cycles spent to process single byte (less is better). +# +# x86 SSSE3 AVX +# Pentium 15.7 - +# PIII 11.5 - +# P4 10.6 - +# AMD K8 7.1 - +# Core2 7.3 6.1/+20% - +# Atom 12.5 9.5(*)/+32% - +# Westmere 7.3 5.6/+30% - +# Sandy Bridge 8.8 6.2/+40% 5.1(**)/+70% +# +# (*) Loop is 1056 instructions long and expected result is ~8.25. +# It remains mystery [to me] why ILP is limited to 1.7. +# +# (**) As per above comment, the result is for AVX *plus* sh[rl]d. + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"sha1-586.pl",$ARGV[$#ARGV] eq "386"); + +$xmm=$ymm=0; +for (@ARGV) { $xmm=1 if (/-DOPENSSL_IA32_SSE2/); } + +$ymm=1 if ($xmm && + `$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` + =~ /GNU assembler version ([2-9]\.[0-9]+)/ && + $1>=2.19); # first version supporting AVX + +$ymm=1 if ($xmm && !$ymm && $ARGV[0] eq "win32n" && + `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ && + $1>=2.03); # first version supporting AVX + +&external_label("OPENSSL_ia32cap_P") if ($xmm); + + +$A="eax"; +$B="ebx"; +$C="ecx"; +$D="edx"; +$E="edi"; +$T="esi"; +$tmp1="ebp"; + +@V=($A,$B,$C,$D,$E,$T); + +$alt=0; # 1 denotes alternative IALU implementation, which performs + # 8% *worse* on P4, same on Westmere and Atom, 2% better on + # Sandy Bridge... + +sub BODY_00_15 + { + local($n,$a,$b,$c,$d,$e,$f)=@_; + + &comment("00_15 $n"); + + &mov($f,$c); # f to hold F_00_19(b,c,d) + if ($n==0) { &mov($tmp1,$a); } + else { &mov($a,$tmp1); } + &rotl($tmp1,5); # tmp1=ROTATE(a,5) + &xor($f,$d); + &add($tmp1,$e); # tmp1+=e; + &mov($e,&swtmp($n%16)); # e becomes volatile and is loaded + # with xi, also note that e becomes + # f in next round... + &and($f,$b); + &rotr($b,2); # b=ROTATE(b,30) + &xor($f,$d); # f holds F_00_19(b,c,d) + &lea($tmp1,&DWP(0x5a827999,$tmp1,$e)); # tmp1+=K_00_19+xi + + if ($n==15) { &mov($e,&swtmp(($n+1)%16));# pre-fetch f for next round + &add($f,$tmp1); } # f+=tmp1 + else { &add($tmp1,$f); } # f becomes a in next round + &mov($tmp1,$a) if ($alt && $n==15); + } + +sub BODY_16_19 + { + local($n,$a,$b,$c,$d,$e,$f)=@_; + + &comment("16_19 $n"); + +if ($alt) { + &xor($c,$d); + &xor($f,&swtmp(($n+2)%16)); # f to hold Xupdate(xi,xa,xb,xc,xd) + &and($tmp1,$c); # tmp1 to hold F_00_19(b,c,d), b&=c^d + &xor($f,&swtmp(($n+8)%16)); + &xor($tmp1,$d); # tmp1=F_00_19(b,c,d) + &xor($f,&swtmp(($n+13)%16)); # f holds xa^xb^xc^xd + &rotl($f,1); # f=ROTATE(f,1) + &add($e,$tmp1); # e+=F_00_19(b,c,d) + &xor($c,$d); # restore $c + &mov($tmp1,$a); # b in next round + &rotr($b,$n==16?2:7); # b=ROTATE(b,30) + &mov(&swtmp($n%16),$f); # xi=f + &rotl($a,5); # ROTATE(a,5) + &lea($f,&DWP(0x5a827999,$f,$e));# f+=F_00_19(b,c,d)+e + &mov($e,&swtmp(($n+1)%16)); # pre-fetch f for next round + &add($f,$a); # f+=ROTATE(a,5) +} else { + &mov($tmp1,$c); # tmp1 to hold F_00_19(b,c,d) + &xor($f,&swtmp(($n+2)%16)); # f to hold Xupdate(xi,xa,xb,xc,xd) + &xor($tmp1,$d); + &xor($f,&swtmp(($n+8)%16)); + &and($tmp1,$b); + &xor($f,&swtmp(($n+13)%16)); # f holds xa^xb^xc^xd + &rotl($f,1); # f=ROTATE(f,1) + &xor($tmp1,$d); # tmp1=F_00_19(b,c,d) + &add($e,$tmp1); # e+=F_00_19(b,c,d) + &mov($tmp1,$a); + &rotr($b,2); # b=ROTATE(b,30) + &mov(&swtmp($n%16),$f); # xi=f + &rotl($tmp1,5); # ROTATE(a,5) + &lea($f,&DWP(0x5a827999,$f,$e));# f+=F_00_19(b,c,d)+e + &mov($e,&swtmp(($n+1)%16)); # pre-fetch f for next round + &add($f,$tmp1); # f+=ROTATE(a,5) +} + } + +sub BODY_20_39 + { + local($n,$a,$b,$c,$d,$e,$f)=@_; + local $K=($n<40)?0x6ed9eba1:0xca62c1d6; + + &comment("20_39 $n"); + +if ($alt) { + &xor($tmp1,$c); # tmp1 to hold F_20_39(b,c,d), b^=c + &xor($f,&swtmp(($n+2)%16)); # f to hold Xupdate(xi,xa,xb,xc,xd) + &xor($tmp1,$d); # tmp1 holds F_20_39(b,c,d) + &xor($f,&swtmp(($n+8)%16)); + &add($e,$tmp1); # e+=F_20_39(b,c,d) + &xor($f,&swtmp(($n+13)%16)); # f holds xa^xb^xc^xd + &rotl($f,1); # f=ROTATE(f,1) + &mov($tmp1,$a); # b in next round + &rotr($b,7); # b=ROTATE(b,30) + &mov(&swtmp($n%16),$f) if($n<77);# xi=f + &rotl($a,5); # ROTATE(a,5) + &xor($b,$c) if($n==39);# warm up for BODY_40_59 + &and($tmp1,$b) if($n==39); + &lea($f,&DWP($K,$f,$e)); # f+=e+K_XX_YY + &mov($e,&swtmp(($n+1)%16)) if($n<79);# pre-fetch f for next round + &add($f,$a); # f+=ROTATE(a,5) + &rotr($a,5) if ($n==79); +} else { + &mov($tmp1,$b); # tmp1 to hold F_20_39(b,c,d) + &xor($f,&swtmp(($n+2)%16)); # f to hold Xupdate(xi,xa,xb,xc,xd) + &xor($tmp1,$c); + &xor($f,&swtmp(($n+8)%16)); + &xor($tmp1,$d); # tmp1 holds F_20_39(b,c,d) + &xor($f,&swtmp(($n+13)%16)); # f holds xa^xb^xc^xd + &rotl($f,1); # f=ROTATE(f,1) + &add($e,$tmp1); # e+=F_20_39(b,c,d) + &rotr($b,2); # b=ROTATE(b,30) + &mov($tmp1,$a); + &rotl($tmp1,5); # ROTATE(a,5) + &mov(&swtmp($n%16),$f) if($n<77);# xi=f + &lea($f,&DWP($K,$f,$e)); # f+=e+K_XX_YY + &mov($e,&swtmp(($n+1)%16)) if($n<79);# pre-fetch f for next round + &add($f,$tmp1); # f+=ROTATE(a,5) +} + } + +sub BODY_40_59 + { + local($n,$a,$b,$c,$d,$e,$f)=@_; + + &comment("40_59 $n"); + +if ($alt) { + &add($e,$tmp1); # e+=b&(c^d) + &xor($f,&swtmp(($n+2)%16)); # f to hold Xupdate(xi,xa,xb,xc,xd) + &mov($tmp1,$d); + &xor($f,&swtmp(($n+8)%16)); + &xor($c,$d); # restore $c + &xor($f,&swtmp(($n+13)%16)); # f holds xa^xb^xc^xd + &rotl($f,1); # f=ROTATE(f,1) + &and($tmp1,$c); + &rotr($b,7); # b=ROTATE(b,30) + &add($e,$tmp1); # e+=c&d + &mov($tmp1,$a); # b in next round + &mov(&swtmp($n%16),$f); # xi=f + &rotl($a,5); # ROTATE(a,5) + &xor($b,$c) if ($n<59); + &and($tmp1,$b) if ($n<59);# tmp1 to hold F_40_59(b,c,d) + &lea($f,&DWP(0x8f1bbcdc,$f,$e));# f+=K_40_59+e+(b&(c^d)) + &mov($e,&swtmp(($n+1)%16)); # pre-fetch f for next round + &add($f,$a); # f+=ROTATE(a,5) +} else { + &mov($tmp1,$c); # tmp1 to hold F_40_59(b,c,d) + &xor($f,&swtmp(($n+2)%16)); # f to hold Xupdate(xi,xa,xb,xc,xd) + &xor($tmp1,$d); + &xor($f,&swtmp(($n+8)%16)); + &and($tmp1,$b); + &xor($f,&swtmp(($n+13)%16)); # f holds xa^xb^xc^xd + &rotl($f,1); # f=ROTATE(f,1) + &add($tmp1,$e); # b&(c^d)+=e + &rotr($b,2); # b=ROTATE(b,30) + &mov($e,$a); # e becomes volatile + &rotl($e,5); # ROTATE(a,5) + &mov(&swtmp($n%16),$f); # xi=f + &lea($f,&DWP(0x8f1bbcdc,$f,$tmp1));# f+=K_40_59+e+(b&(c^d)) + &mov($tmp1,$c); + &add($f,$e); # f+=ROTATE(a,5) + &and($tmp1,$d); + &mov($e,&swtmp(($n+1)%16)); # pre-fetch f for next round + &add($f,$tmp1); # f+=c&d +} + } + +&function_begin("sha1_block_data_order"); +if ($xmm) { + &static_label("ssse3_shortcut"); + &static_label("avx_shortcut") if ($ymm); + &static_label("K_XX_XX"); + + &call (&label("pic_point")); # make it PIC! + &set_label("pic_point"); + &blindpop($tmp1); + &picmeup($T,"OPENSSL_ia32cap_P",$tmp1,&label("pic_point")); + &lea ($tmp1,&DWP(&label("K_XX_XX")."-".&label("pic_point"),$tmp1)); + + &mov ($A,&DWP(0,$T)); + &mov ($D,&DWP(4,$T)); + &test ($D,1<<9); # check SSSE3 bit + &jz (&label("x86")); + &test ($A,1<<24); # check FXSR bit + &jz (&label("x86")); + if ($ymm) { + &and ($D,1<<28); # mask AVX bit + &and ($A,1<<30); # mask "Intel CPU" bit + &or ($A,$D); + &cmp ($A,1<<28|1<<30); + &je (&label("avx_shortcut")); + } + &jmp (&label("ssse3_shortcut")); + &set_label("x86",16); +} + &mov($tmp1,&wparam(0)); # SHA_CTX *c + &mov($T,&wparam(1)); # const void *input + &mov($A,&wparam(2)); # size_t num + &stack_push(16+3); # allocate X[16] + &shl($A,6); + &add($A,$T); + &mov(&wparam(2),$A); # pointer beyond the end of input + &mov($E,&DWP(16,$tmp1));# pre-load E + &jmp(&label("loop")); + +&set_label("loop",16); + + # copy input chunk to X, but reversing byte order! + for ($i=0; $i<16; $i+=4) + { + &mov($A,&DWP(4*($i+0),$T)); + &mov($B,&DWP(4*($i+1),$T)); + &mov($C,&DWP(4*($i+2),$T)); + &mov($D,&DWP(4*($i+3),$T)); + &bswap($A); + &bswap($B); + &bswap($C); + &bswap($D); + &mov(&swtmp($i+0),$A); + &mov(&swtmp($i+1),$B); + &mov(&swtmp($i+2),$C); + &mov(&swtmp($i+3),$D); + } + &mov(&wparam(1),$T); # redundant in 1st spin + + &mov($A,&DWP(0,$tmp1)); # load SHA_CTX + &mov($B,&DWP(4,$tmp1)); + &mov($C,&DWP(8,$tmp1)); + &mov($D,&DWP(12,$tmp1)); + # E is pre-loaded + + for($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); } + for(;$i<20;$i++) { &BODY_16_19($i,@V); unshift(@V,pop(@V)); } + for(;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } + for(;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } + for(;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } + + (($V[5] eq $D) and ($V[0] eq $E)) or die; # double-check + + &mov($tmp1,&wparam(0)); # re-load SHA_CTX* + &mov($D,&wparam(1)); # D is last "T" and is discarded + + &add($E,&DWP(0,$tmp1)); # E is last "A"... + &add($T,&DWP(4,$tmp1)); + &add($A,&DWP(8,$tmp1)); + &add($B,&DWP(12,$tmp1)); + &add($C,&DWP(16,$tmp1)); + + &mov(&DWP(0,$tmp1),$E); # update SHA_CTX + &add($D,64); # advance input pointer + &mov(&DWP(4,$tmp1),$T); + &cmp($D,&wparam(2)); # have we reached the end yet? + &mov(&DWP(8,$tmp1),$A); + &mov($E,$C); # C is last "E" which needs to be "pre-loaded" + &mov(&DWP(12,$tmp1),$B); + &mov($T,$D); # input pointer + &mov(&DWP(16,$tmp1),$C); + &jb(&label("loop")); + + &stack_pop(16+3); +&function_end("sha1_block_data_order"); + +if ($xmm) { +###################################################################### +# The SSSE3 implementation. +# +# %xmm[0-7] are used as ring @X[] buffer containing quadruples of last +# 32 elements of the message schedule or Xupdate outputs. First 4 +# quadruples are simply byte-swapped input, next 4 are calculated +# according to method originally suggested by Dean Gaudet (modulo +# being implemented in SSSE3). Once 8 quadruples or 32 elements are +# collected, it switches to routine proposed by Max Locktyukhin. +# +# Calculations inevitably require temporary reqisters, and there are +# no %xmm registers left to spare. For this reason part of the ring +# buffer, X[2..4] to be specific, is offloaded to 3 quadriples ring +# buffer on the stack. Keep in mind that X[2] is alias X[-6], X[3] - +# X[-5], and X[4] - X[-4]... +# +# Another notable optimization is aggressive stack frame compression +# aiming to minimize amount of 9-byte instructions... +# +# Yet another notable optimization is "jumping" $B variable. It means +# that there is no register permanently allocated for $B value. This +# allowed to eliminate one instruction from body_20_39... +# +my $Xi=4; # 4xSIMD Xupdate round, start pre-seeded +my @X=map("xmm$_",(4..7,0..3)); # pre-seeded for $Xi=4 +my @V=($A,$B,$C,$D,$E); +my $j=0; # hash round +my @T=($T,$tmp1); +my $inp; + +my $_rol=sub { &rol(@_) }; +my $_ror=sub { &ror(@_) }; + +&function_begin("_sha1_block_data_order_ssse3"); + &call (&label("pic_point")); # make it PIC! + &set_label("pic_point"); + &blindpop($tmp1); + &lea ($tmp1,&DWP(&label("K_XX_XX")."-".&label("pic_point"),$tmp1)); +&set_label("ssse3_shortcut"); + + &movdqa (@X[3],&QWP(0,$tmp1)); # K_00_19 + &movdqa (@X[4],&QWP(16,$tmp1)); # K_20_39 + &movdqa (@X[5],&QWP(32,$tmp1)); # K_40_59 + &movdqa (@X[6],&QWP(48,$tmp1)); # K_60_79 + &movdqa (@X[2],&QWP(64,$tmp1)); # pbswap mask + + &mov ($E,&wparam(0)); # load argument block + &mov ($inp=@T[1],&wparam(1)); + &mov ($D,&wparam(2)); + &mov (@T[0],"esp"); + + # stack frame layout + # + # +0 X[0]+K X[1]+K X[2]+K X[3]+K # XMM->IALU xfer area + # X[4]+K X[5]+K X[6]+K X[7]+K + # X[8]+K X[9]+K X[10]+K X[11]+K + # X[12]+K X[13]+K X[14]+K X[15]+K + # + # +64 X[0] X[1] X[2] X[3] # XMM->XMM backtrace area + # X[4] X[5] X[6] X[7] + # X[8] X[9] X[10] X[11] # even borrowed for K_00_19 + # + # +112 K_20_39 K_20_39 K_20_39 K_20_39 # constants + # K_40_59 K_40_59 K_40_59 K_40_59 + # K_60_79 K_60_79 K_60_79 K_60_79 + # K_00_19 K_00_19 K_00_19 K_00_19 + # pbswap mask + # + # +192 ctx # argument block + # +196 inp + # +200 end + # +204 esp + &sub ("esp",208); + &and ("esp",-64); + + &movdqa (&QWP(112+0,"esp"),@X[4]); # copy constants + &movdqa (&QWP(112+16,"esp"),@X[5]); + &movdqa (&QWP(112+32,"esp"),@X[6]); + &shl ($D,6); # len*64 + &movdqa (&QWP(112+48,"esp"),@X[3]); + &add ($D,$inp); # end of input + &movdqa (&QWP(112+64,"esp"),@X[2]); + &add ($inp,64); + &mov (&DWP(192+0,"esp"),$E); # save argument block + &mov (&DWP(192+4,"esp"),$inp); + &mov (&DWP(192+8,"esp"),$D); + &mov (&DWP(192+12,"esp"),@T[0]); # save original %esp + + &mov ($A,&DWP(0,$E)); # load context + &mov ($B,&DWP(4,$E)); + &mov ($C,&DWP(8,$E)); + &mov ($D,&DWP(12,$E)); + &mov ($E,&DWP(16,$E)); + &mov (@T[0],$B); # magic seed + + &movdqu (@X[-4&7],&QWP(-64,$inp)); # load input to %xmm[0-3] + &movdqu (@X[-3&7],&QWP(-48,$inp)); + &movdqu (@X[-2&7],&QWP(-32,$inp)); + &movdqu (@X[-1&7],&QWP(-16,$inp)); + &pshufb (@X[-4&7],@X[2]); # byte swap + &pshufb (@X[-3&7],@X[2]); + &pshufb (@X[-2&7],@X[2]); + &movdqa (&QWP(112-16,"esp"),@X[3]); # borrow last backtrace slot + &pshufb (@X[-1&7],@X[2]); + &paddd (@X[-4&7],@X[3]); # add K_00_19 + &paddd (@X[-3&7],@X[3]); + &paddd (@X[-2&7],@X[3]); + &movdqa (&QWP(0,"esp"),@X[-4&7]); # X[]+K xfer to IALU + &psubd (@X[-4&7],@X[3]); # restore X[] + &movdqa (&QWP(0+16,"esp"),@X[-3&7]); + &psubd (@X[-3&7],@X[3]); + &movdqa (&QWP(0+32,"esp"),@X[-2&7]); + &psubd (@X[-2&7],@X[3]); + &movdqa (@X[0],@X[-3&7]); + &jmp (&label("loop")); + +###################################################################### +# SSE instruction sequence is first broken to groups of indepentent +# instructions, independent in respect to their inputs and shifter +# (not all architectures have more than one). Then IALU instructions +# are "knitted in" between the SSE groups. Distance is maintained for +# SSE latency of 2 in hope that it fits better upcoming AMD Bulldozer +# [which allegedly also implements SSSE3]... +# +# Temporary registers usage. X[2] is volatile at the entry and at the +# end is restored from backtrace ring buffer. X[3] is expected to +# contain current K_XX_XX constant and is used to caclulate X[-1]+K +# from previous round, it becomes volatile the moment the value is +# saved to stack for transfer to IALU. X[4] becomes volatile whenever +# X[-4] is accumulated and offloaded to backtrace ring buffer, at the +# end it is loaded with next K_XX_XX [which becomes X[3] in next +# round]... +# +sub Xupdate_ssse3_16_31() # recall that $Xi starts wtih 4 +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 40 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + eval(shift(@insns)); + &palignr(@X[0],@X[-4&7],8); # compose "X[-14]" in "X[0]" + &movdqa (@X[2],@X[-1&7]); + eval(shift(@insns)); + eval(shift(@insns)); + + &paddd (@X[3],@X[-1&7]); + &movdqa (&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]);# save X[] to backtrace buffer + eval(shift(@insns)); + eval(shift(@insns)); + &psrldq (@X[2],4); # "X[-3]", 3 dwords + eval(shift(@insns)); + eval(shift(@insns)); + &pxor (@X[0],@X[-4&7]); # "X[0]"^="X[-16]" + eval(shift(@insns)); + eval(shift(@insns)); + + &pxor (@X[2],@X[-2&7]); # "X[-3]"^"X[-8]" + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &pxor (@X[0],@X[2]); # "X[0]"^="X[-3]"^"X[-8]" + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + + &movdqa (@X[4],@X[0]); + &movdqa (@X[2],@X[0]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &pslldq (@X[4],12); # "X[0]"<<96, extract one dword + &paddd (@X[0],@X[0]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &psrld (@X[2],31); + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (@X[3],@X[4]); + eval(shift(@insns)); + eval(shift(@insns)); + + &psrld (@X[4],30); + &por (@X[0],@X[2]); # "X[0]"<<<=1 + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if ($Xi>5); # restore X[] from backtrace buffer + eval(shift(@insns)); + eval(shift(@insns)); + + &pslld (@X[3],2); + &pxor (@X[0],@X[4]); + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (@X[4],&QWP(112-16+16*(($Xi)/5),"esp")); # K_XX_XX + eval(shift(@insns)); + eval(shift(@insns)); + + &pxor (@X[0],@X[3]); # "X[0]"^=("X[0]"<<96)<<<2 + &movdqa (@X[1],@X[-2&7]) if ($Xi<7); + eval(shift(@insns)); + eval(shift(@insns)); + + foreach (@insns) { eval; } # remaining instructions [if any] + + $Xi++; push(@X,shift(@X)); # "rotate" X[] +} + +sub Xupdate_ssse3_32_79() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 to 48 instructions + my ($a,$b,$c,$d,$e); + + &movdqa (@X[2],@X[-1&7]) if ($Xi==8); + eval(shift(@insns)); # body_20_39 + &pxor (@X[0],@X[-4&7]); # "X[0]"="X[-32]"^"X[-16]" + &palignr(@X[2],@X[-2&7],8); # compose "X[-6]" + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + + &pxor (@X[0],@X[-7&7]); # "X[0]"^="X[-28]" + &movdqa (&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]); # save X[] to backtrace buffer + eval(shift(@insns)); + eval(shift(@insns)); + if ($Xi%5) { + &movdqa (@X[4],@X[3]); # "perpetuate" K_XX_XX... + } else { # ... or load next one + &movdqa (@X[4],&QWP(112-16+16*($Xi/5),"esp")); + } + &paddd (@X[3],@X[-1&7]); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &pxor (@X[0],@X[2]); # "X[0]"^="X[-6]" + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + + &movdqa (@X[2],@X[0]); + &movdqa (&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &pslld (@X[0],2); + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + &psrld (@X[2],30); + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &por (@X[0],@X[2]); # "X[0]"<<<=2 + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + &movdqa (@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if($Xi<19); # restore X[] from backtrace buffer + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # ror + &movdqa (@X[3],@X[0]) if ($Xi<19); + eval(shift(@insns)); + + foreach (@insns) { eval; } # remaining instructions + + $Xi++; push(@X,shift(@X)); # "rotate" X[] +} + +sub Xuplast_ssse3_80() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + &paddd (@X[3],@X[-1&7]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &movdqa (&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]); # X[]+K xfer IALU + + foreach (@insns) { eval; } # remaining instructions + + &mov ($inp=@T[1],&DWP(192+4,"esp")); + &cmp ($inp,&DWP(192+8,"esp")); + &je (&label("done")); + + &movdqa (@X[3],&QWP(112+48,"esp")); # K_00_19 + &movdqa (@X[2],&QWP(112+64,"esp")); # pbswap mask + &movdqu (@X[-4&7],&QWP(0,$inp)); # load input + &movdqu (@X[-3&7],&QWP(16,$inp)); + &movdqu (@X[-2&7],&QWP(32,$inp)); + &movdqu (@X[-1&7],&QWP(48,$inp)); + &add ($inp,64); + &pshufb (@X[-4&7],@X[2]); # byte swap + &mov (&DWP(192+4,"esp"),$inp); + &movdqa (&QWP(112-16,"esp"),@X[3]); # borrow last backtrace slot + + $Xi=0; +} + +sub Xloop_ssse3() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + eval(shift(@insns)); + &pshufb (@X[($Xi-3)&7],@X[2]); + eval(shift(@insns)); + eval(shift(@insns)); + &paddd (@X[($Xi-4)&7],@X[3]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (&QWP(0+16*$Xi,"esp"),@X[($Xi-4)&7]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + &psubd (@X[($Xi-4)&7],@X[3]); + + foreach (@insns) { eval; } + $Xi++; +} + +sub Xtail_ssse3() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + foreach (@insns) { eval; } +} + +sub body_00_19 () { + ( + '($a,$b,$c,$d,$e)=@V;'. + '&add ($e,&DWP(4*($j&15),"esp"));', # X[]+K xfer + '&xor ($c,$d);', + '&mov (@T[1],$a);', # $b in next round + '&$_rol ($a,5);', + '&and (@T[0],$c);', # ($b&($c^$d)) + '&xor ($c,$d);', # restore $c + '&xor (@T[0],$d);', + '&add ($e,$a);', + '&$_ror ($b,$j?7:2);', # $b>>>2 + '&add ($e,@T[0]);' .'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));' + ); +} + +sub body_20_39 () { + ( + '($a,$b,$c,$d,$e)=@V;'. + '&add ($e,&DWP(4*($j++&15),"esp"));', # X[]+K xfer + '&xor (@T[0],$d);', # ($b^$d) + '&mov (@T[1],$a);', # $b in next round + '&$_rol ($a,5);', + '&xor (@T[0],$c);', # ($b^$d^$c) + '&add ($e,$a);', + '&$_ror ($b,7);', # $b>>>2 + '&add ($e,@T[0]);' .'unshift(@V,pop(@V)); unshift(@T,pop(@T));' + ); +} + +sub body_40_59 () { + ( + '($a,$b,$c,$d,$e)=@V;'. + '&mov (@T[1],$c);', + '&xor ($c,$d);', + '&add ($e,&DWP(4*($j++&15),"esp"));', # X[]+K xfer + '&and (@T[1],$d);', + '&and (@T[0],$c);', # ($b&($c^$d)) + '&$_ror ($b,7);', # $b>>>2 + '&add ($e,@T[1]);', + '&mov (@T[1],$a);', # $b in next round + '&$_rol ($a,5);', + '&add ($e,@T[0]);', + '&xor ($c,$d);', # restore $c + '&add ($e,$a);' .'unshift(@V,pop(@V)); unshift(@T,pop(@T));' + ); +} + +&set_label("loop",16); + &Xupdate_ssse3_16_31(\&body_00_19); + &Xupdate_ssse3_16_31(\&body_00_19); + &Xupdate_ssse3_16_31(\&body_00_19); + &Xupdate_ssse3_16_31(\&body_00_19); + &Xupdate_ssse3_32_79(\&body_00_19); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xuplast_ssse3_80(\&body_20_39); # can jump to "done" + + $saved_j=$j; @saved_V=@V; + + &Xloop_ssse3(\&body_20_39); + &Xloop_ssse3(\&body_20_39); + &Xloop_ssse3(\&body_20_39); + + &mov (@T[1],&DWP(192,"esp")); # update context + &add ($A,&DWP(0,@T[1])); + &add (@T[0],&DWP(4,@T[1])); # $b + &add ($C,&DWP(8,@T[1])); + &mov (&DWP(0,@T[1]),$A); + &add ($D,&DWP(12,@T[1])); + &mov (&DWP(4,@T[1]),@T[0]); + &add ($E,&DWP(16,@T[1])); + &mov (&DWP(8,@T[1]),$C); + &mov ($B,@T[0]); + &mov (&DWP(12,@T[1]),$D); + &mov (&DWP(16,@T[1]),$E); + &movdqa (@X[0],@X[-3&7]); + + &jmp (&label("loop")); + +&set_label("done",16); $j=$saved_j; @V=@saved_V; + + &Xtail_ssse3(\&body_20_39); + &Xtail_ssse3(\&body_20_39); + &Xtail_ssse3(\&body_20_39); + + &mov (@T[1],&DWP(192,"esp")); # update context + &add ($A,&DWP(0,@T[1])); + &mov ("esp",&DWP(192+12,"esp")); # restore %esp + &add (@T[0],&DWP(4,@T[1])); # $b + &add ($C,&DWP(8,@T[1])); + &mov (&DWP(0,@T[1]),$A); + &add ($D,&DWP(12,@T[1])); + &mov (&DWP(4,@T[1]),@T[0]); + &add ($E,&DWP(16,@T[1])); + &mov (&DWP(8,@T[1]),$C); + &mov (&DWP(12,@T[1]),$D); + &mov (&DWP(16,@T[1]),$E); + +&function_end("_sha1_block_data_order_ssse3"); + +if ($ymm) { +my $Xi=4; # 4xSIMD Xupdate round, start pre-seeded +my @X=map("xmm$_",(4..7,0..3)); # pre-seeded for $Xi=4 +my @V=($A,$B,$C,$D,$E); +my $j=0; # hash round +my @T=($T,$tmp1); +my $inp; + +my $_rol=sub { &shld(@_[0],@_) }; +my $_ror=sub { &shrd(@_[0],@_) }; + +&function_begin("_sha1_block_data_order_avx"); + &call (&label("pic_point")); # make it PIC! + &set_label("pic_point"); + &blindpop($tmp1); + &lea ($tmp1,&DWP(&label("K_XX_XX")."-".&label("pic_point"),$tmp1)); +&set_label("avx_shortcut"); + &vzeroall(); + + &vmovdqa(@X[3],&QWP(0,$tmp1)); # K_00_19 + &vmovdqa(@X[4],&QWP(16,$tmp1)); # K_20_39 + &vmovdqa(@X[5],&QWP(32,$tmp1)); # K_40_59 + &vmovdqa(@X[6],&QWP(48,$tmp1)); # K_60_79 + &vmovdqa(@X[2],&QWP(64,$tmp1)); # pbswap mask + + &mov ($E,&wparam(0)); # load argument block + &mov ($inp=@T[1],&wparam(1)); + &mov ($D,&wparam(2)); + &mov (@T[0],"esp"); + + # stack frame layout + # + # +0 X[0]+K X[1]+K X[2]+K X[3]+K # XMM->IALU xfer area + # X[4]+K X[5]+K X[6]+K X[7]+K + # X[8]+K X[9]+K X[10]+K X[11]+K + # X[12]+K X[13]+K X[14]+K X[15]+K + # + # +64 X[0] X[1] X[2] X[3] # XMM->XMM backtrace area + # X[4] X[5] X[6] X[7] + # X[8] X[9] X[10] X[11] # even borrowed for K_00_19 + # + # +112 K_20_39 K_20_39 K_20_39 K_20_39 # constants + # K_40_59 K_40_59 K_40_59 K_40_59 + # K_60_79 K_60_79 K_60_79 K_60_79 + # K_00_19 K_00_19 K_00_19 K_00_19 + # pbswap mask + # + # +192 ctx # argument block + # +196 inp + # +200 end + # +204 esp + &sub ("esp",208); + &and ("esp",-64); + + &vmovdqa(&QWP(112+0,"esp"),@X[4]); # copy constants + &vmovdqa(&QWP(112+16,"esp"),@X[5]); + &vmovdqa(&QWP(112+32,"esp"),@X[6]); + &shl ($D,6); # len*64 + &vmovdqa(&QWP(112+48,"esp"),@X[3]); + &add ($D,$inp); # end of input + &vmovdqa(&QWP(112+64,"esp"),@X[2]); + &add ($inp,64); + &mov (&DWP(192+0,"esp"),$E); # save argument block + &mov (&DWP(192+4,"esp"),$inp); + &mov (&DWP(192+8,"esp"),$D); + &mov (&DWP(192+12,"esp"),@T[0]); # save original %esp + + &mov ($A,&DWP(0,$E)); # load context + &mov ($B,&DWP(4,$E)); + &mov ($C,&DWP(8,$E)); + &mov ($D,&DWP(12,$E)); + &mov ($E,&DWP(16,$E)); + &mov (@T[0],$B); # magic seed + + &vmovdqu(@X[-4&7],&QWP(-64,$inp)); # load input to %xmm[0-3] + &vmovdqu(@X[-3&7],&QWP(-48,$inp)); + &vmovdqu(@X[-2&7],&QWP(-32,$inp)); + &vmovdqu(@X[-1&7],&QWP(-16,$inp)); + &vpshufb(@X[-4&7],@X[-4&7],@X[2]); # byte swap + &vpshufb(@X[-3&7],@X[-3&7],@X[2]); + &vpshufb(@X[-2&7],@X[-2&7],@X[2]); + &vmovdqa(&QWP(112-16,"esp"),@X[3]); # borrow last backtrace slot + &vpshufb(@X[-1&7],@X[-1&7],@X[2]); + &vpaddd (@X[0],@X[-4&7],@X[3]); # add K_00_19 + &vpaddd (@X[1],@X[-3&7],@X[3]); + &vpaddd (@X[2],@X[-2&7],@X[3]); + &vmovdqa(&QWP(0,"esp"),@X[0]); # X[]+K xfer to IALU + &vmovdqa(&QWP(0+16,"esp"),@X[1]); + &vmovdqa(&QWP(0+32,"esp"),@X[2]); + &jmp (&label("loop")); + +sub Xupdate_avx_16_31() # recall that $Xi starts wtih 4 +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 40 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + eval(shift(@insns)); + &vpalignr(@X[0],@X[-3&7],@X[-4&7],8); # compose "X[-14]" in "X[0]" + eval(shift(@insns)); + eval(shift(@insns)); + + &vpaddd (@X[3],@X[3],@X[-1&7]); + &vmovdqa (&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]);# save X[] to backtrace buffer + eval(shift(@insns)); + eval(shift(@insns)); + &vpsrldq(@X[2],@X[-1&7],4); # "X[-3]", 3 dwords + eval(shift(@insns)); + eval(shift(@insns)); + &vpxor (@X[0],@X[0],@X[-4&7]); # "X[0]"^="X[-16]" + eval(shift(@insns)); + eval(shift(@insns)); + + &vpxor (@X[2],@X[2],@X[-2&7]); # "X[-3]"^"X[-8]" + eval(shift(@insns)); + eval(shift(@insns)); + &vmovdqa (&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + + &vpxor (@X[0],@X[0],@X[2]); # "X[0]"^="X[-3]"^"X[-8]" + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpsrld (@X[2],@X[0],31); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpslldq(@X[4],@X[0],12); # "X[0]"<<96, extract one dword + &vpaddd (@X[0],@X[0],@X[0]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpsrld (@X[3],@X[4],30); + &vpor (@X[0],@X[0],@X[2]); # "X[0]"<<<=1 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpslld (@X[4],@X[4],2); + &vmovdqa (@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if ($Xi>5); # restore X[] from backtrace buffer + eval(shift(@insns)); + eval(shift(@insns)); + &vpxor (@X[0],@X[0],@X[3]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpxor (@X[0],@X[0],@X[4]); # "X[0]"^=("X[0]"<<96)<<<2 + eval(shift(@insns)); + eval(shift(@insns)); + &vmovdqa (@X[4],&QWP(112-16+16*(($Xi)/5),"esp")); # K_XX_XX + eval(shift(@insns)); + eval(shift(@insns)); + + foreach (@insns) { eval; } # remaining instructions [if any] + + $Xi++; push(@X,shift(@X)); # "rotate" X[] +} + +sub Xupdate_avx_32_79() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 to 48 instructions + my ($a,$b,$c,$d,$e); + + &vpalignr(@X[2],@X[-1&7],@X[-2&7],8); # compose "X[-6]" + &vpxor (@X[0],@X[0],@X[-4&7]); # "X[0]"="X[-32]"^"X[-16]" + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + + &vpxor (@X[0],@X[0],@X[-7&7]); # "X[0]"^="X[-28]" + &vmovdqa (&QWP(64+16*(($Xi-4)%3),"esp"),@X[-4&7]); # save X[] to backtrace buffer + eval(shift(@insns)); + eval(shift(@insns)); + if ($Xi%5) { + &vmovdqa (@X[4],@X[3]); # "perpetuate" K_XX_XX... + } else { # ... or load next one + &vmovdqa (@X[4],&QWP(112-16+16*($Xi/5),"esp")); + } + &vpaddd (@X[3],@X[3],@X[-1&7]); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &vpxor (@X[0],@X[0],@X[2]); # "X[0]"^="X[-6]" + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + + &vpsrld (@X[2],@X[0],30); + &vmovdqa (&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &vpslld (@X[0],@X[0],2); + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &vpor (@X[0],@X[0],@X[2]); # "X[0]"<<<=2 + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + &vmovdqa (@X[2],&QWP(64+16*(($Xi-6)%3),"esp")) if($Xi<19); # restore X[] from backtrace buffer + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + foreach (@insns) { eval; } # remaining instructions + + $Xi++; push(@X,shift(@X)); # "rotate" X[] +} + +sub Xuplast_avx_80() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + &vpaddd (@X[3],@X[3],@X[-1&7]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vmovdqa (&QWP(0+16*(($Xi-1)&3),"esp"),@X[3]); # X[]+K xfer IALU + + foreach (@insns) { eval; } # remaining instructions + + &mov ($inp=@T[1],&DWP(192+4,"esp")); + &cmp ($inp,&DWP(192+8,"esp")); + &je (&label("done")); + + &vmovdqa(@X[3],&QWP(112+48,"esp")); # K_00_19 + &vmovdqa(@X[2],&QWP(112+64,"esp")); # pbswap mask + &vmovdqu(@X[-4&7],&QWP(0,$inp)); # load input + &vmovdqu(@X[-3&7],&QWP(16,$inp)); + &vmovdqu(@X[-2&7],&QWP(32,$inp)); + &vmovdqu(@X[-1&7],&QWP(48,$inp)); + &add ($inp,64); + &vpshufb(@X[-4&7],@X[-4&7],@X[2]); # byte swap + &mov (&DWP(192+4,"esp"),$inp); + &vmovdqa(&QWP(112-16,"esp"),@X[3]); # borrow last backtrace slot + + $Xi=0; +} + +sub Xloop_avx() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + eval(shift(@insns)); + &vpshufb (@X[($Xi-3)&7],@X[($Xi-3)&7],@X[2]); + eval(shift(@insns)); + eval(shift(@insns)); + &vpaddd (@X[$Xi&7],@X[($Xi-4)&7],@X[3]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + &vmovdqa (&QWP(0+16*$Xi,"esp"),@X[$Xi&7]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + + foreach (@insns) { eval; } + $Xi++; +} + +sub Xtail_avx() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + foreach (@insns) { eval; } +} + +&set_label("loop",16); + &Xupdate_avx_16_31(\&body_00_19); + &Xupdate_avx_16_31(\&body_00_19); + &Xupdate_avx_16_31(\&body_00_19); + &Xupdate_avx_16_31(\&body_00_19); + &Xupdate_avx_32_79(\&body_00_19); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_20_39); + &Xuplast_avx_80(\&body_20_39); # can jump to "done" + + $saved_j=$j; @saved_V=@V; + + &Xloop_avx(\&body_20_39); + &Xloop_avx(\&body_20_39); + &Xloop_avx(\&body_20_39); + + &mov (@T[1],&DWP(192,"esp")); # update context + &add ($A,&DWP(0,@T[1])); + &add (@T[0],&DWP(4,@T[1])); # $b + &add ($C,&DWP(8,@T[1])); + &mov (&DWP(0,@T[1]),$A); + &add ($D,&DWP(12,@T[1])); + &mov (&DWP(4,@T[1]),@T[0]); + &add ($E,&DWP(16,@T[1])); + &mov (&DWP(8,@T[1]),$C); + &mov ($B,@T[0]); + &mov (&DWP(12,@T[1]),$D); + &mov (&DWP(16,@T[1]),$E); + + &jmp (&label("loop")); + +&set_label("done",16); $j=$saved_j; @V=@saved_V; + + &Xtail_avx(\&body_20_39); + &Xtail_avx(\&body_20_39); + &Xtail_avx(\&body_20_39); + + &vzeroall(); + + &mov (@T[1],&DWP(192,"esp")); # update context + &add ($A,&DWP(0,@T[1])); + &mov ("esp",&DWP(192+12,"esp")); # restore %esp + &add (@T[0],&DWP(4,@T[1])); # $b + &add ($C,&DWP(8,@T[1])); + &mov (&DWP(0,@T[1]),$A); + &add ($D,&DWP(12,@T[1])); + &mov (&DWP(4,@T[1]),@T[0]); + &add ($E,&DWP(16,@T[1])); + &mov (&DWP(8,@T[1]),$C); + &mov (&DWP(12,@T[1]),$D); + &mov (&DWP(16,@T[1]),$E); +&function_end("_sha1_block_data_order_avx"); +} +&set_label("K_XX_XX",64); +&data_word(0x5a827999,0x5a827999,0x5a827999,0x5a827999); # K_00_19 +&data_word(0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1); # K_20_39 +&data_word(0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc); # K_40_59 +&data_word(0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6); # K_60_79 +&data_word(0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f); # pbswap mask +} +&asciz("SHA1 block transform for x86, CRYPTOGAMS by "); + +&asm_finish(); diff --git a/libs/openssl/crypto/sha/asm/sha1-alpha.pl b/libs/openssl/crypto/sha/asm/sha1-alpha.pl new file mode 100644 index 00000000..6c4b9251 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha1-alpha.pl @@ -0,0 +1,322 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# SHA1 block procedure for Alpha. + +# On 21264 performance is 33% better than code generated by vendor +# compiler, and 75% better than GCC [3.4], and in absolute terms is +# 8.7 cycles per processed byte. Implementation features vectorized +# byte swap, but not Xupdate. + +@X=( "\$0", "\$1", "\$2", "\$3", "\$4", "\$5", "\$6", "\$7", + "\$8", "\$9", "\$10", "\$11", "\$12", "\$13", "\$14", "\$15"); +$ctx="a0"; # $16 +$inp="a1"; +$num="a2"; +$A="a3"; +$B="a4"; # 20 +$C="a5"; +$D="t8"; +$E="t9"; @V=($A,$B,$C,$D,$E); +$t0="t10"; # 24 +$t1="t11"; +$t2="ra"; +$t3="t12"; +$K="AT"; # 28 + +sub BODY_00_19 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +$code.=<<___ if ($i==0); + ldq_u @X[0],0+0($inp) + ldq_u @X[1],0+7($inp) +___ +$code.=<<___ if (!($i&1) && $i<14); + ldq_u @X[$i+2],($i+2)*4+0($inp) + ldq_u @X[$i+3],($i+2)*4+7($inp) +___ +$code.=<<___ if (!($i&1) && $i<15); + extql @X[$i],$inp,@X[$i] + extqh @X[$i+1],$inp,@X[$i+1] + + or @X[$i+1],@X[$i],@X[$i] # pair of 32-bit values are fetched + + srl @X[$i],24,$t0 # vectorized byte swap + srl @X[$i],8,$t2 + + sll @X[$i],8,$t3 + sll @X[$i],24,@X[$i] + zapnot $t0,0x11,$t0 + zapnot $t2,0x22,$t2 + + zapnot @X[$i],0x88,@X[$i] + or $t0,$t2,$t0 + zapnot $t3,0x44,$t3 + sll $a,5,$t1 + + or @X[$i],$t0,@X[$i] + addl $K,$e,$e + and $b,$c,$t2 + zapnot $a,0xf,$a + + or @X[$i],$t3,@X[$i] + srl $a,27,$t0 + bic $d,$b,$t3 + sll $b,30,$b + + extll @X[$i],4,@X[$i+1] # extract upper half + or $t2,$t3,$t2 + addl @X[$i],$e,$e + + addl $t1,$e,$e + srl $b,32,$t3 + zapnot @X[$i],0xf,@X[$i] + + addl $t0,$e,$e + addl $t2,$e,$e + or $t3,$b,$b +___ +$code.=<<___ if (($i&1) && $i<15); + sll $a,5,$t1 + addl $K,$e,$e + and $b,$c,$t2 + zapnot $a,0xf,$a + + srl $a,27,$t0 + addl @X[$i%16],$e,$e + bic $d,$b,$t3 + sll $b,30,$b + + or $t2,$t3,$t2 + addl $t1,$e,$e + srl $b,32,$t3 + zapnot @X[$i],0xf,@X[$i] + + addl $t0,$e,$e + addl $t2,$e,$e + or $t3,$b,$b +___ +$code.=<<___ if ($i>=15); # with forward Xupdate + sll $a,5,$t1 + addl $K,$e,$e + and $b,$c,$t2 + xor @X[($j+2)%16],@X[$j%16],@X[$j%16] + + zapnot $a,0xf,$a + addl @X[$i%16],$e,$e + bic $d,$b,$t3 + xor @X[($j+8)%16],@X[$j%16],@X[$j%16] + + srl $a,27,$t0 + addl $t1,$e,$e + or $t2,$t3,$t2 + xor @X[($j+13)%16],@X[$j%16],@X[$j%16] + + sll $b,30,$b + addl $t0,$e,$e + srl @X[$j%16],31,$t1 + + addl $t2,$e,$e + srl $b,32,$t3 + addl @X[$j%16],@X[$j%16],@X[$j%16] + + or $t3,$b,$b + zapnot @X[$i%16],0xf,@X[$i%16] + or $t1,@X[$j%16],@X[$j%16] +___ +} + +sub BODY_20_39 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +$code.=<<___ if ($i<79); # with forward Xupdate + sll $a,5,$t1 + addl $K,$e,$e + zapnot $a,0xf,$a + xor @X[($j+2)%16],@X[$j%16],@X[$j%16] + + sll $b,30,$t3 + addl $t1,$e,$e + xor $b,$c,$t2 + xor @X[($j+8)%16],@X[$j%16],@X[$j%16] + + srl $b,2,$b + addl @X[$i%16],$e,$e + xor $d,$t2,$t2 + xor @X[($j+13)%16],@X[$j%16],@X[$j%16] + + srl @X[$j%16],31,$t1 + addl $t2,$e,$e + srl $a,27,$t0 + addl @X[$j%16],@X[$j%16],@X[$j%16] + + or $t3,$b,$b + addl $t0,$e,$e + or $t1,@X[$j%16],@X[$j%16] +___ +$code.=<<___ if ($i<77); + zapnot @X[$i%16],0xf,@X[$i%16] +___ +$code.=<<___ if ($i==79); # with context fetch + sll $a,5,$t1 + addl $K,$e,$e + zapnot $a,0xf,$a + ldl @X[0],0($ctx) + + sll $b,30,$t3 + addl $t1,$e,$e + xor $b,$c,$t2 + ldl @X[1],4($ctx) + + srl $b,2,$b + addl @X[$i%16],$e,$e + xor $d,$t2,$t2 + ldl @X[2],8($ctx) + + srl $a,27,$t0 + addl $t2,$e,$e + ldl @X[3],12($ctx) + + or $t3,$b,$b + addl $t0,$e,$e + ldl @X[4],16($ctx) +___ +} + +sub BODY_40_59 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +$code.=<<___; # with forward Xupdate + sll $a,5,$t1 + addl $K,$e,$e + zapnot $a,0xf,$a + xor @X[($j+2)%16],@X[$j%16],@X[$j%16] + + srl $a,27,$t0 + and $b,$c,$t2 + and $b,$d,$t3 + xor @X[($j+8)%16],@X[$j%16],@X[$j%16] + + sll $b,30,$b + addl $t1,$e,$e + xor @X[($j+13)%16],@X[$j%16],@X[$j%16] + + srl @X[$j%16],31,$t1 + addl $t0,$e,$e + or $t2,$t3,$t2 + and $c,$d,$t3 + + or $t2,$t3,$t2 + srl $b,32,$t3 + addl @X[$i%16],$e,$e + addl @X[$j%16],@X[$j%16],@X[$j%16] + + or $t3,$b,$b + addl $t2,$e,$e + or $t1,@X[$j%16],@X[$j%16] + zapnot @X[$i%16],0xf,@X[$i%16] +___ +} + +$code=<<___; +#ifdef __linux__ +#include +#else +#include +#include +#endif + +.text + +.set noat +.set noreorder +.globl sha1_block_data_order +.align 5 +.ent sha1_block_data_order +sha1_block_data_order: + lda sp,-64(sp) + stq ra,0(sp) + stq s0,8(sp) + stq s1,16(sp) + stq s2,24(sp) + stq s3,32(sp) + stq s4,40(sp) + stq s5,48(sp) + stq fp,56(sp) + .mask 0x0400fe00,-64 + .frame sp,64,ra + .prologue 0 + + ldl $A,0($ctx) + ldl $B,4($ctx) + sll $num,6,$num + ldl $C,8($ctx) + ldl $D,12($ctx) + ldl $E,16($ctx) + addq $inp,$num,$num + +.Lloop: + .set noreorder + ldah $K,23170(zero) + zapnot $B,0xf,$B + lda $K,31129($K) # K_00_19 +___ +for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); } + +$code.=<<___; + ldah $K,28378(zero) + lda $K,-5215($K) # K_20_39 +___ +for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } + +$code.=<<___; + ldah $K,-28900(zero) + lda $K,-17188($K) # K_40_59 +___ +for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } + +$code.=<<___; + ldah $K,-13725(zero) + lda $K,-15914($K) # K_60_79 +___ +for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } + +$code.=<<___; + addl @X[0],$A,$A + addl @X[1],$B,$B + addl @X[2],$C,$C + addl @X[3],$D,$D + addl @X[4],$E,$E + stl $A,0($ctx) + stl $B,4($ctx) + addq $inp,64,$inp + stl $C,8($ctx) + stl $D,12($ctx) + stl $E,16($ctx) + cmpult $inp,$num,$t1 + bne $t1,.Lloop + + .set noreorder + ldq ra,0(sp) + ldq s0,8(sp) + ldq s1,16(sp) + ldq s2,24(sp) + ldq s3,32(sp) + ldq s4,40(sp) + ldq s5,48(sp) + ldq fp,56(sp) + lda sp,64(sp) + ret (ra) +.end sha1_block_data_order +.ascii "SHA1 block transform for Alpha, CRYPTOGAMS by " +.align 2 +___ +$output=shift and open STDOUT,">$output"; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/sha/asm/sha1-armv4-large.pl b/libs/openssl/crypto/sha/asm/sha1-armv4-large.pl new file mode 100644 index 00000000..33da3e0e --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha1-armv4-large.pl @@ -0,0 +1,248 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# sha1_block procedure for ARMv4. +# +# January 2007. + +# Size/performance trade-off +# ==================================================================== +# impl size in bytes comp cycles[*] measured performance +# ==================================================================== +# thumb 304 3212 4420 +# armv4-small 392/+29% 1958/+64% 2250/+96% +# armv4-compact 740/+89% 1552/+26% 1840/+22% +# armv4-large 1420/+92% 1307/+19% 1370/+34%[***] +# full unroll ~5100/+260% ~1260/+4% ~1300/+5% +# ==================================================================== +# thumb = same as 'small' but in Thumb instructions[**] and +# with recurring code in two private functions; +# small = detached Xload/update, loops are folded; +# compact = detached Xload/update, 5x unroll; +# large = interleaved Xload/update, 5x unroll; +# full unroll = interleaved Xload/update, full unroll, estimated[!]; +# +# [*] Manually counted instructions in "grand" loop body. Measured +# performance is affected by prologue and epilogue overhead, +# i-cache availability, branch penalties, etc. +# [**] While each Thumb instruction is twice smaller, they are not as +# diverse as ARM ones: e.g., there are only two arithmetic +# instructions with 3 arguments, no [fixed] rotate, addressing +# modes are limited. As result it takes more instructions to do +# the same job in Thumb, therefore the code is never twice as +# small and always slower. +# [***] which is also ~35% better than compiler generated code. Dual- +# issue Cortex A8 core was measured to process input block in +# ~990 cycles. + +# August 2010. +# +# Rescheduling for dual-issue pipeline resulted in 13% improvement on +# Cortex A8 core and in absolute terms ~870 cycles per input block +# [or 13.6 cycles per byte]. + +# February 2011. +# +# Profiler-assisted and platform-specific optimization resulted in 10% +# improvement on Cortex A8 core and 12.2 cycles per byte. + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +$ctx="r0"; +$inp="r1"; +$len="r2"; +$a="r3"; +$b="r4"; +$c="r5"; +$d="r6"; +$e="r7"; +$K="r8"; +$t0="r9"; +$t1="r10"; +$t2="r11"; +$t3="r12"; +$Xi="r14"; +@V=($a,$b,$c,$d,$e); + +sub Xupdate { +my ($a,$b,$c,$d,$e,$opt1,$opt2)=@_; +$code.=<<___; + ldr $t0,[$Xi,#15*4] + ldr $t1,[$Xi,#13*4] + ldr $t2,[$Xi,#7*4] + add $e,$K,$e,ror#2 @ E+=K_xx_xx + ldr $t3,[$Xi,#2*4] + eor $t0,$t0,$t1 + eor $t2,$t2,$t3 @ 1 cycle stall + eor $t1,$c,$d @ F_xx_xx + mov $t0,$t0,ror#31 + add $e,$e,$a,ror#27 @ E+=ROR(A,27) + eor $t0,$t0,$t2,ror#31 + str $t0,[$Xi,#-4]! + $opt1 @ F_xx_xx + $opt2 @ F_xx_xx + add $e,$e,$t0 @ E+=X[i] +___ +} + +sub BODY_00_15 { +my ($a,$b,$c,$d,$e)=@_; +$code.=<<___; +#if __ARM_ARCH__<7 + ldrb $t1,[$inp,#2] + ldrb $t0,[$inp,#3] + ldrb $t2,[$inp,#1] + add $e,$K,$e,ror#2 @ E+=K_00_19 + ldrb $t3,[$inp],#4 + orr $t0,$t0,$t1,lsl#8 + eor $t1,$c,$d @ F_xx_xx + orr $t0,$t0,$t2,lsl#16 + add $e,$e,$a,ror#27 @ E+=ROR(A,27) + orr $t0,$t0,$t3,lsl#24 +#else + ldr $t0,[$inp],#4 @ handles unaligned + add $e,$K,$e,ror#2 @ E+=K_00_19 + eor $t1,$c,$d @ F_xx_xx + add $e,$e,$a,ror#27 @ E+=ROR(A,27) +#ifdef __ARMEL__ + rev $t0,$t0 @ byte swap +#endif +#endif + and $t1,$b,$t1,ror#2 + add $e,$e,$t0 @ E+=X[i] + eor $t1,$t1,$d,ror#2 @ F_00_19(B,C,D) + str $t0,[$Xi,#-4]! + add $e,$e,$t1 @ E+=F_00_19(B,C,D) +___ +} + +sub BODY_16_19 { +my ($a,$b,$c,$d,$e)=@_; + &Xupdate(@_,"and $t1,$b,$t1,ror#2"); +$code.=<<___; + eor $t1,$t1,$d,ror#2 @ F_00_19(B,C,D) + add $e,$e,$t1 @ E+=F_00_19(B,C,D) +___ +} + +sub BODY_20_39 { +my ($a,$b,$c,$d,$e)=@_; + &Xupdate(@_,"eor $t1,$b,$t1,ror#2"); +$code.=<<___; + add $e,$e,$t1 @ E+=F_20_39(B,C,D) +___ +} + +sub BODY_40_59 { +my ($a,$b,$c,$d,$e)=@_; + &Xupdate(@_,"and $t1,$b,$t1,ror#2","and $t2,$c,$d"); +$code.=<<___; + add $e,$e,$t1 @ E+=F_40_59(B,C,D) + add $e,$e,$t2,ror#2 +___ +} + +$code=<<___; +#include "arm_arch.h" + +.text + +.global sha1_block_data_order +.type sha1_block_data_order,%function + +.align 2 +sha1_block_data_order: + stmdb sp!,{r4-r12,lr} + add $len,$inp,$len,lsl#6 @ $len to point at the end of $inp + ldmia $ctx,{$a,$b,$c,$d,$e} +.Lloop: + ldr $K,.LK_00_19 + mov $Xi,sp + sub sp,sp,#15*4 + mov $c,$c,ror#30 + mov $d,$d,ror#30 + mov $e,$e,ror#30 @ [6] +.L_00_15: +___ +for($i=0;$i<5;$i++) { + &BODY_00_15(@V); unshift(@V,pop(@V)); +} +$code.=<<___; + teq $Xi,sp + bne .L_00_15 @ [((11+4)*5+2)*3] + sub sp,sp,#25*4 +___ + &BODY_00_15(@V); unshift(@V,pop(@V)); + &BODY_16_19(@V); unshift(@V,pop(@V)); + &BODY_16_19(@V); unshift(@V,pop(@V)); + &BODY_16_19(@V); unshift(@V,pop(@V)); + &BODY_16_19(@V); unshift(@V,pop(@V)); +$code.=<<___; + + ldr $K,.LK_20_39 @ [+15+16*4] + cmn sp,#0 @ [+3], clear carry to denote 20_39 +.L_20_39_or_60_79: +___ +for($i=0;$i<5;$i++) { + &BODY_20_39(@V); unshift(@V,pop(@V)); +} +$code.=<<___; + teq $Xi,sp @ preserve carry + bne .L_20_39_or_60_79 @ [+((12+3)*5+2)*4] + bcs .L_done @ [+((12+3)*5+2)*4], spare 300 bytes + + ldr $K,.LK_40_59 + sub sp,sp,#20*4 @ [+2] +.L_40_59: +___ +for($i=0;$i<5;$i++) { + &BODY_40_59(@V); unshift(@V,pop(@V)); +} +$code.=<<___; + teq $Xi,sp + bne .L_40_59 @ [+((12+5)*5+2)*4] + + ldr $K,.LK_60_79 + sub sp,sp,#20*4 + cmp sp,#0 @ set carry to denote 60_79 + b .L_20_39_or_60_79 @ [+4], spare 300 bytes +.L_done: + add sp,sp,#80*4 @ "deallocate" stack frame + ldmia $ctx,{$K,$t0,$t1,$t2,$t3} + add $a,$K,$a + add $b,$t0,$b + add $c,$t1,$c,ror#2 + add $d,$t2,$d,ror#2 + add $e,$t3,$e,ror#2 + stmia $ctx,{$a,$b,$c,$d,$e} + teq $inp,$len + bne .Lloop @ [+18], total 1307 + +#if __ARM_ARCH__>=5 + ldmia sp!,{r4-r12,pc} +#else + ldmia sp!,{r4-r12,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif +.align 2 +.LK_00_19: .word 0x5a827999 +.LK_20_39: .word 0x6ed9eba1 +.LK_40_59: .word 0x8f1bbcdc +.LK_60_79: .word 0xca62c1d6 +.size sha1_block_data_order,.-sha1_block_data_order +.asciz "SHA1 block transform for ARMv4, CRYPTOGAMS by " +.align 2 +___ + +$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 +print $code; +close STDOUT; # enforce flush diff --git a/libs/openssl/crypto/sha/asm/sha1-ia64.pl b/libs/openssl/crypto/sha/asm/sha1-ia64.pl new file mode 100644 index 00000000..02d35d16 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha1-ia64.pl @@ -0,0 +1,305 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# Eternal question is what's wrong with compiler generated code? The +# trick is that it's possible to reduce the number of shifts required +# to perform rotations by maintaining copy of 32-bit value in upper +# bits of 64-bit register. Just follow mux2 and shrp instructions... +# Performance under big-endian OS such as HP-UX is 179MBps*1GHz, which +# is >50% better than HP C and >2x better than gcc. + +$code=<<___; +.ident \"sha1-ia64.s, version 1.3\" +.ident \"IA-64 ISA artwork by Andy Polyakov \" +.explicit + +___ + + +if ($^O eq "hpux") { + $ADDP="addp4"; + for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); } +} else { $ADDP="add"; } + +#$human=1; +if ($human) { # useful for visual code auditing... + ($A,$B,$C,$D,$E) = ("A","B","C","D","E"); + ($h0,$h1,$h2,$h3,$h4) = ("h0","h1","h2","h3","h4"); + ($K_00_19, $K_20_39, $K_40_59, $K_60_79) = + ( "K_00_19","K_20_39","K_40_59","K_60_79" ); + @X= ( "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", + "X8", "X9","X10","X11","X12","X13","X14","X15" ); +} +else { + ($A,$B,$C,$D,$E) = ("loc0","loc1","loc2","loc3","loc4"); + ($h0,$h1,$h2,$h3,$h4) = ("loc5","loc6","loc7","loc8","loc9"); + ($K_00_19, $K_20_39, $K_40_59, $K_60_79) = + ( "r14", "r15", "loc10", "loc11" ); + @X= ( "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" ); +} + +sub BODY_00_15 { +local *code=shift; +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +my $Xn=@X[$j%16]; + +$code.=<<___ if ($i==0); +{ .mmi; ld1 $X[$i]=[inp],2 // MSB + ld1 tmp2=[tmp3],2 };; +{ .mmi; ld1 tmp0=[inp],2 + ld1 tmp4=[tmp3],2 // LSB + dep $X[$i]=$X[$i],tmp2,8,8 };; +___ +if ($i<15) { + $code.=<<___; +{ .mmi; ld1 $Xn=[inp],2 // forward Xload + nop.m 0x0 + dep tmp1=tmp0,tmp4,8,8 };; +{ .mmi; ld1 tmp2=[tmp3],2 // forward Xload + and tmp4=$c,$b + dep $X[$i]=$X[$i],tmp1,16,16} //;; +{ .mmi; add $e=$e,$K_00_19 // e+=K_00_19 + andcm tmp1=$d,$b + dep.z tmp5=$a,5,27 };; // a<<5 +{ .mmi; add $e=$e,$X[$i] // e+=Xload + or tmp4=tmp4,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d) + extr.u tmp1=$a,27,5 };; // a>>27 +{ .mmi; ld1 tmp0=[inp],2 // forward Xload + add $e=$e,tmp4 // e+=F_00_19(b,c,d) + shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) +{ .mmi; ld1 tmp4=[tmp3],2 // forward Xload + or tmp5=tmp1,tmp5 // ROTATE(a,5) + mux2 tmp6=$a,0x44 };; // see b in next iteration +{ .mii; add $e=$e,tmp5 // e+=ROTATE(a,5) + dep $Xn=$Xn,tmp2,8,8 // forward Xload + mux2 $X[$i]=$X[$i],0x44 } //;; + +___ + } +else { + $code.=<<___; +{ .mii; and tmp3=$c,$b + dep tmp1=tmp0,tmp4,8,8;; + dep $X[$i]=$X[$i],tmp1,16,16} //;; +{ .mmi; add $e=$e,$K_00_19 // e+=K_00_19 + andcm tmp1=$d,$b + dep.z tmp5=$a,5,27 };; // a<<5 +{ .mmi; add $e=$e,$X[$i] // e+=Xupdate + or tmp4=tmp3,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d) + extr.u tmp1=$a,27,5 } // a>>27 +{ .mmi; xor $Xn=$Xn,$X[($j+2)%16] // forward Xupdate + xor tmp3=$X[($j+8)%16],$X[($j+13)%16] // forward Xupdate + nop.i 0 };; +{ .mmi; add $e=$e,tmp4 // e+=F_00_19(b,c,d) + xor $Xn=$Xn,tmp3 // forward Xupdate + shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) +{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5) + mux2 tmp6=$a,0x44 };; // see b in next iteration +{ .mii; add $e=$e,tmp1 // e+=ROTATE(a,5) + shrp $Xn=$Xn,$Xn,31 // ROTATE(x[0]^x[2]^x[8]^x[13],1) + mux2 $X[$i]=$X[$i],0x44 };; + +___ + } +} + +sub BODY_16_19 { +local *code=shift; +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +my $Xn=@X[$j%16]; + +$code.=<<___; +{ .mib; add $e=$e,$K_00_19 // e+=K_00_19 + dep.z tmp5=$a,5,27 } // a<<5 +{ .mib; andcm tmp1=$d,$b + and tmp0=$c,$b };; +{ .mmi; add $e=$e,$X[$i%16] // e+=Xupdate + or tmp0=tmp0,tmp1 // F_00_19(b,c,d)=(b&c)|(~b&d) + extr.u tmp1=$a,27,5 } // a>>27 +{ .mmi; xor $Xn=$Xn,$X[($j+2)%16] // forward Xupdate + xor tmp3=$X[($j+8)%16],$X[($j+13)%16] // forward Xupdate + nop.i 0 };; +{ .mmi; add $e=$e,tmp0 // f+=F_00_19(b,c,d) + xor $Xn=$Xn,tmp3 // forward Xupdate + shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) +{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5) + mux2 tmp6=$a,0x44 };; // see b in next iteration +{ .mii; add $e=$e,tmp1 // e+=ROTATE(a,5) + shrp $Xn=$Xn,$Xn,31 // ROTATE(x[0]^x[2]^x[8]^x[13],1) + nop.i 0 };; + +___ +} + +sub BODY_20_39 { +local *code=shift; +my ($i,$a,$b,$c,$d,$e,$Konst)=@_; + $Konst = $K_20_39 if (!defined($Konst)); +my $j=$i+1; +my $Xn=@X[$j%16]; + +if ($i<79) { +$code.=<<___; +{ .mib; add $e=$e,$Konst // e+=K_XX_XX + dep.z tmp5=$a,5,27 } // a<<5 +{ .mib; xor tmp0=$c,$b + xor $Xn=$Xn,$X[($j+2)%16] };; // forward Xupdate +{ .mib; add $e=$e,$X[$i%16] // e+=Xupdate + extr.u tmp1=$a,27,5 } // a>>27 +{ .mib; xor tmp0=tmp0,$d // F_20_39(b,c,d)=b^c^d + xor $Xn=$Xn,$X[($j+8)%16] };; // forward Xupdate +{ .mmi; add $e=$e,tmp0 // e+=F_20_39(b,c,d) + xor $Xn=$Xn,$X[($j+13)%16] // forward Xupdate + shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) +{ .mmi; or tmp1=tmp1,tmp5 // ROTATE(a,5) + mux2 tmp6=$a,0x44 };; // see b in next iteration +{ .mii; add $e=$e,tmp1 // e+=ROTATE(a,5) + shrp $Xn=$Xn,$Xn,31 // ROTATE(x[0]^x[2]^x[8]^x[13],1) + nop.i 0 };; + +___ +} +else { +$code.=<<___; +{ .mib; add $e=$e,$Konst // e+=K_60_79 + dep.z tmp5=$a,5,27 } // a<<5 +{ .mib; xor tmp0=$c,$b + add $h1=$h1,$a };; // wrap up +{ .mib; add $e=$e,$X[$i%16] // e+=Xupdate + extr.u tmp1=$a,27,5 } // a>>27 +{ .mib; xor tmp0=tmp0,$d // F_20_39(b,c,d)=b^c^d + add $h3=$h3,$c };; // wrap up +{ .mmi; add $e=$e,tmp0 // e+=F_20_39(b,c,d) + or tmp1=tmp1,tmp5 // ROTATE(a,5) + shrp $b=tmp6,tmp6,2 };; // b=ROTATE(b,30) ;;? +{ .mmi; add $e=$e,tmp1 // e+=ROTATE(a,5) + add tmp3=1,inp // used in unaligned codepath + add $h4=$h4,$d };; // wrap up + +___ +} +} + +sub BODY_40_59 { +local *code=shift; +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +my $Xn=@X[$j%16]; + +$code.=<<___; +{ .mib; add $e=$e,$K_40_59 // e+=K_40_59 + dep.z tmp5=$a,5,27 } // a<<5 +{ .mib; and tmp1=$c,$d + xor tmp0=$c,$d };; +{ .mmi; add $e=$e,$X[$i%16] // e+=Xupdate + add tmp5=tmp5,tmp1 // a<<5+(c&d) + extr.u tmp1=$a,27,5 } // a>>27 +{ .mmi; and tmp0=tmp0,$b + xor $Xn=$Xn,$X[($j+2)%16] // forward Xupdate + xor tmp3=$X[($j+8)%16],$X[($j+13)%16] };; // forward Xupdate +{ .mmi; add $e=$e,tmp0 // e+=b&(c^d) + add tmp5=tmp5,tmp1 // ROTATE(a,5)+(c&d) + shrp $b=tmp6,tmp6,2 } // b=ROTATE(b,30) +{ .mmi; xor $Xn=$Xn,tmp3 + mux2 tmp6=$a,0x44 };; // see b in next iteration +{ .mii; add $e=$e,tmp5 // e+=ROTATE(a,5)+(c&d) + shrp $Xn=$Xn,$Xn,31 // ROTATE(x[0]^x[2]^x[8]^x[13],1) + nop.i 0x0 };; + +___ +} +sub BODY_60_79 { &BODY_20_39(@_,$K_60_79); } + +$code.=<<___; +.text + +tmp0=r8; +tmp1=r9; +tmp2=r10; +tmp3=r11; +ctx=r32; // in0 +inp=r33; // in1 + +// void sha1_block_data_order(SHA_CTX *c,const void *p,size_t num); +.global sha1_block_data_order# +.proc sha1_block_data_order# +.align 32 +sha1_block_data_order: + .prologue +{ .mmi; alloc tmp1=ar.pfs,3,14,0,0 + $ADDP tmp0=4,ctx + .save ar.lc,r3 + mov r3=ar.lc } +{ .mmi; $ADDP ctx=0,ctx + $ADDP inp=0,inp + mov r2=pr };; +tmp4=in2; +tmp5=loc12; +tmp6=loc13; + .body +{ .mlx; ld4 $h0=[ctx],8 + movl $K_00_19=0x5a827999 } +{ .mlx; ld4 $h1=[tmp0],8 + movl $K_20_39=0x6ed9eba1 };; +{ .mlx; ld4 $h2=[ctx],8 + movl $K_40_59=0x8f1bbcdc } +{ .mlx; ld4 $h3=[tmp0] + movl $K_60_79=0xca62c1d6 };; +{ .mmi; ld4 $h4=[ctx],-16 + add in2=-1,in2 // adjust num for ar.lc + mov ar.ec=1 };; +{ .mmi; nop.m 0 + add tmp3=1,inp + mov ar.lc=in2 };; // brp.loop.imp: too far + +.Ldtop: +{ .mmi; mov $A=$h0 + mov $B=$h1 + mux2 tmp6=$h1,0x44 } +{ .mmi; mov $C=$h2 + mov $D=$h3 + mov $E=$h4 };; + +___ + +{ my $i; + my @V=($A,$B,$C,$D,$E); + + for($i=0;$i<16;$i++) { &BODY_00_15(\$code,$i,@V); unshift(@V,pop(@V)); } + for(;$i<20;$i++) { &BODY_16_19(\$code,$i,@V); unshift(@V,pop(@V)); } + for(;$i<40;$i++) { &BODY_20_39(\$code,$i,@V); unshift(@V,pop(@V)); } + for(;$i<60;$i++) { &BODY_40_59(\$code,$i,@V); unshift(@V,pop(@V)); } + for(;$i<80;$i++) { &BODY_60_79(\$code,$i,@V); unshift(@V,pop(@V)); } + + (($V[0] eq $A) and ($V[4] eq $E)) or die; # double-check +} + +$code.=<<___; +{ .mmb; add $h0=$h0,$A + add $h2=$h2,$C + br.ctop.dptk.many .Ldtop };; +.Ldend: +{ .mmi; add tmp0=4,ctx + mov ar.lc=r3 };; +{ .mmi; st4 [ctx]=$h0,8 + st4 [tmp0]=$h1,8 };; +{ .mmi; st4 [ctx]=$h2,8 + st4 [tmp0]=$h3 };; +{ .mib; st4 [ctx]=$h4,-16 + mov pr=r2,0x1ffff + br.ret.sptk.many b0 };; +.endp sha1_block_data_order# +stringz "SHA1 block transform for IA64, CRYPTOGAMS by " +___ + +$output=shift and open STDOUT,">$output"; +print $code; diff --git a/libs/openssl/crypto/sha/asm/sha1-mips.pl b/libs/openssl/crypto/sha/asm/sha1-mips.pl new file mode 100644 index 00000000..197bc6b5 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha1-mips.pl @@ -0,0 +1,354 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# SHA1 block procedure for MIPS. + +# Performance improvement is 30% on unaligned input. The "secret" is +# to deploy lwl/lwr pair to load unaligned input. One could have +# vectorized Xupdate on MIPSIII/IV, but the goal was to code MIPS32- +# compatible subroutine. There is room for minor optimization on +# little-endian platforms... + +###################################################################### +# There is a number of MIPS ABI in use, O32 and N32/64 are most +# widely used. Then there is a new contender: NUBI. It appears that if +# one picks the latter, it's possible to arrange code in ABI neutral +# manner. Therefore let's stick to NUBI register layout: +# +($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25)); +($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11)); +($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23)); +($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31)); +# +# The return value is placed in $a0. Following coding rules facilitate +# interoperability: +# +# - never ever touch $tp, "thread pointer", former $gp; +# - copy return value to $t0, former $v0 [or to $a0 if you're adapting +# old code]; +# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary; +# +# For reference here is register layout for N32/64 MIPS ABIs: +# +# ($zero,$at,$v0,$v1)=map("\$$_",(0..3)); +# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11)); +# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25)); +# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23)); +# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31)); +# +$flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64 + +if ($flavour =~ /64|n32/i) { + $PTR_ADD="dadd"; # incidentally works even on n32 + $PTR_SUB="dsub"; # incidentally works even on n32 + $REG_S="sd"; + $REG_L="ld"; + $PTR_SLL="dsll"; # incidentally works even on n32 + $SZREG=8; +} else { + $PTR_ADD="add"; + $PTR_SUB="sub"; + $REG_S="sw"; + $REG_L="lw"; + $PTR_SLL="sll"; + $SZREG=4; +} +# +# +# +###################################################################### + +$big_endian=(`echo MIPSEL | $ENV{CC} -E -`=~/MIPSEL/)?1:0 if ($ENV{CC}); + +for (@ARGV) { $output=$_ if (/^\w[\w\-]*\.\w+$/); } +open STDOUT,">$output"; + +if (!defined($big_endian)) + { $big_endian=(unpack('L',pack('N',1))==1); } + +# offsets of the Most and Least Significant Bytes +$MSB=$big_endian?0:3; +$LSB=3&~$MSB; + +@X=map("\$$_",(8..23)); # a4-a7,s0-s11 + +$ctx=$a0; +$inp=$a1; +$num=$a2; +$A="\$1"; +$B="\$2"; +$C="\$3"; +$D="\$7"; +$E="\$24"; @V=($A,$B,$C,$D,$E); +$t0="\$25"; +$t1=$num; # $num is offloaded to stack +$t2="\$30"; # fp +$K="\$31"; # ra + +sub BODY_00_14 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +$code.=<<___ if (!$big_endian); + srl $t0,@X[$i],24 # byte swap($i) + srl $t1,@X[$i],8 + andi $t2,@X[$i],0xFF00 + sll @X[$i],@X[$i],24 + andi $t1,0xFF00 + sll $t2,$t2,8 + or @X[$i],$t0 + or $t1,$t2 + or @X[$i],$t1 +___ +$code.=<<___; + lwl @X[$j],$j*4+$MSB($inp) + sll $t0,$a,5 # $i + addu $e,$K + lwr @X[$j],$j*4+$LSB($inp) + srl $t1,$a,27 + addu $e,$t0 + xor $t0,$c,$d + addu $e,$t1 + sll $t2,$b,30 + and $t0,$b + srl $b,$b,2 + xor $t0,$d + addu $e,@X[$i] + or $b,$t2 + addu $e,$t0 +___ +} + +sub BODY_15_19 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; + +$code.=<<___ if (!$big_endian && $i==15); + srl $t0,@X[$i],24 # byte swap($i) + srl $t1,@X[$i],8 + andi $t2,@X[$i],0xFF00 + sll @X[$i],@X[$i],24 + andi $t1,0xFF00 + sll $t2,$t2,8 + or @X[$i],$t0 + or @X[$i],$t1 + or @X[$i],$t2 +___ +$code.=<<___; + xor @X[$j%16],@X[($j+2)%16] + sll $t0,$a,5 # $i + addu $e,$K + srl $t1,$a,27 + addu $e,$t0 + xor @X[$j%16],@X[($j+8)%16] + xor $t0,$c,$d + addu $e,$t1 + xor @X[$j%16],@X[($j+13)%16] + sll $t2,$b,30 + and $t0,$b + srl $t1,@X[$j%16],31 + addu @X[$j%16],@X[$j%16] + srl $b,$b,2 + xor $t0,$d + or @X[$j%16],$t1 + addu $e,@X[$i%16] + or $b,$t2 + addu $e,$t0 +___ +} + +sub BODY_20_39 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +$code.=<<___ if ($i<79); + xor @X[$j%16],@X[($j+2)%16] + sll $t0,$a,5 # $i + addu $e,$K + srl $t1,$a,27 + addu $e,$t0 + xor @X[$j%16],@X[($j+8)%16] + xor $t0,$c,$d + addu $e,$t1 + xor @X[$j%16],@X[($j+13)%16] + sll $t2,$b,30 + xor $t0,$b + srl $t1,@X[$j%16],31 + addu @X[$j%16],@X[$j%16] + srl $b,$b,2 + addu $e,@X[$i%16] + or @X[$j%16],$t1 + or $b,$t2 + addu $e,$t0 +___ +$code.=<<___ if ($i==79); + lw @X[0],0($ctx) + sll $t0,$a,5 # $i + addu $e,$K + lw @X[1],4($ctx) + srl $t1,$a,27 + addu $e,$t0 + lw @X[2],8($ctx) + xor $t0,$c,$d + addu $e,$t1 + lw @X[3],12($ctx) + sll $t2,$b,30 + xor $t0,$b + lw @X[4],16($ctx) + srl $b,$b,2 + addu $e,@X[$i%16] + or $b,$t2 + addu $e,$t0 +___ +} + +sub BODY_40_59 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +$code.=<<___ if ($i<79); + xor @X[$j%16],@X[($j+2)%16] + sll $t0,$a,5 # $i + addu $e,$K + srl $t1,$a,27 + addu $e,$t0 + xor @X[$j%16],@X[($j+8)%16] + and $t0,$c,$d + addu $e,$t1 + xor @X[$j%16],@X[($j+13)%16] + sll $t2,$b,30 + addu $e,$t0 + srl $t1,@X[$j%16],31 + xor $t0,$c,$d + addu @X[$j%16],@X[$j%16] + and $t0,$b + srl $b,$b,2 + or @X[$j%16],$t1 + addu $e,@X[$i%16] + or $b,$t2 + addu $e,$t0 +___ +} + +$FRAMESIZE=16; # large enough to accomodate NUBI saved registers +$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc0fff008 : 0xc0ff0000; + +$code=<<___; +#ifdef OPENSSL_FIPSCANISTER +# include +#endif + +.text + +.set noat +.set noreorder +.align 5 +.globl sha1_block_data_order +.ent sha1_block_data_order +sha1_block_data_order: + .frame $sp,$FRAMESIZE*$SZREG,$ra + .mask $SAVED_REGS_MASK,-$SZREG + .set noreorder + $PTR_SUB $sp,$FRAMESIZE*$SZREG + $REG_S $ra,($FRAMESIZE-1)*$SZREG($sp) + $REG_S $fp,($FRAMESIZE-2)*$SZREG($sp) + $REG_S $s11,($FRAMESIZE-3)*$SZREG($sp) + $REG_S $s10,($FRAMESIZE-4)*$SZREG($sp) + $REG_S $s9,($FRAMESIZE-5)*$SZREG($sp) + $REG_S $s8,($FRAMESIZE-6)*$SZREG($sp) + $REG_S $s7,($FRAMESIZE-7)*$SZREG($sp) + $REG_S $s6,($FRAMESIZE-8)*$SZREG($sp) + $REG_S $s5,($FRAMESIZE-9)*$SZREG($sp) + $REG_S $s4,($FRAMESIZE-10)*$SZREG($sp) +___ +$code.=<<___ if ($flavour =~ /nubi/i); # optimize non-nubi prologue + $REG_S $s3,($FRAMESIZE-11)*$SZREG($sp) + $REG_S $s2,($FRAMESIZE-12)*$SZREG($sp) + $REG_S $s1,($FRAMESIZE-13)*$SZREG($sp) + $REG_S $s0,($FRAMESIZE-14)*$SZREG($sp) + $REG_S $gp,($FRAMESIZE-15)*$SZREG($sp) +___ +$code.=<<___; + $PTR_SLL $num,6 + $PTR_ADD $num,$inp + $REG_S $num,0($sp) + lw $A,0($ctx) + lw $B,4($ctx) + lw $C,8($ctx) + lw $D,12($ctx) + b .Loop + lw $E,16($ctx) +.align 4 +.Loop: + .set reorder + lwl @X[0],$MSB($inp) + lui $K,0x5a82 + lwr @X[0],$LSB($inp) + ori $K,0x7999 # K_00_19 +___ +for ($i=0;$i<15;$i++) { &BODY_00_14($i,@V); unshift(@V,pop(@V)); } +for (;$i<20;$i++) { &BODY_15_19($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + lui $K,0x6ed9 + ori $K,0xeba1 # K_20_39 +___ +for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + lui $K,0x8f1b + ori $K,0xbcdc # K_40_59 +___ +for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + lui $K,0xca62 + ori $K,0xc1d6 # K_60_79 +___ +for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + $PTR_ADD $inp,64 + $REG_L $num,0($sp) + + addu $A,$X[0] + addu $B,$X[1] + sw $A,0($ctx) + addu $C,$X[2] + addu $D,$X[3] + sw $B,4($ctx) + addu $E,$X[4] + sw $C,8($ctx) + sw $D,12($ctx) + sw $E,16($ctx) + .set noreorder + bne $inp,$num,.Loop + nop + + .set noreorder + $REG_L $ra,($FRAMESIZE-1)*$SZREG($sp) + $REG_L $fp,($FRAMESIZE-2)*$SZREG($sp) + $REG_L $s11,($FRAMESIZE-3)*$SZREG($sp) + $REG_L $s10,($FRAMESIZE-4)*$SZREG($sp) + $REG_L $s9,($FRAMESIZE-5)*$SZREG($sp) + $REG_L $s8,($FRAMESIZE-6)*$SZREG($sp) + $REG_L $s7,($FRAMESIZE-7)*$SZREG($sp) + $REG_L $s6,($FRAMESIZE-8)*$SZREG($sp) + $REG_L $s5,($FRAMESIZE-9)*$SZREG($sp) + $REG_L $s4,($FRAMESIZE-10)*$SZREG($sp) +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $s3,($FRAMESIZE-11)*$SZREG($sp) + $REG_L $s2,($FRAMESIZE-12)*$SZREG($sp) + $REG_L $s1,($FRAMESIZE-13)*$SZREG($sp) + $REG_L $s0,($FRAMESIZE-14)*$SZREG($sp) + $REG_L $gp,($FRAMESIZE-15)*$SZREG($sp) +___ +$code.=<<___; + jr $ra + $PTR_ADD $sp,$FRAMESIZE*$SZREG +.end sha1_block_data_order +.rdata +.asciiz "SHA1 for MIPS, CRYPTOGAMS by " +___ +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/sha/asm/sha1-parisc.pl b/libs/openssl/crypto/sha/asm/sha1-parisc.pl new file mode 100644 index 00000000..6e5a328a --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha1-parisc.pl @@ -0,0 +1,260 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# SHA1 block procedure for PA-RISC. + +# June 2009. +# +# On PA-7100LC performance is >30% better than gcc 3.2 generated code +# for aligned input and >50% better for unaligned. Compared to vendor +# compiler on PA-8600 it's almost 60% faster in 64-bit build and just +# few percent faster in 32-bit one (this for aligned input, data for +# unaligned input is not available). +# +# Special thanks to polarhome.com for providing HP-UX account. + +$flavour = shift; +$output = shift; +open STDOUT,">$output"; + +if ($flavour =~ /64/) { + $LEVEL ="2.0W"; + $SIZE_T =8; + $FRAME_MARKER =80; + $SAVED_RP =16; + $PUSH ="std"; + $PUSHMA ="std,ma"; + $POP ="ldd"; + $POPMB ="ldd,mb"; +} else { + $LEVEL ="1.0"; + $SIZE_T =4; + $FRAME_MARKER =48; + $SAVED_RP =20; + $PUSH ="stw"; + $PUSHMA ="stwm"; + $POP ="ldw"; + $POPMB ="ldwm"; +} + +$FRAME=14*$SIZE_T+$FRAME_MARKER;# 14 saved regs + frame marker + # [+ argument transfer] +$ctx="%r26"; # arg0 +$inp="%r25"; # arg1 +$num="%r24"; # arg2 + +$t0="%r28"; +$t1="%r29"; +$K="%r31"; + +@X=("%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", "%r8", + "%r9", "%r10","%r11","%r12","%r13","%r14","%r15","%r16",$t0); + +@V=($A,$B,$C,$D,$E)=("%r19","%r20","%r21","%r22","%r23"); + +sub BODY_00_19 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +$code.=<<___ if ($i<15); + addl $K,$e,$e ; $i + shd $a,$a,27,$t1 + addl @X[$i],$e,$e + and $c,$b,$t0 + addl $t1,$e,$e + andcm $d,$b,$t1 + shd $b,$b,2,$b + or $t1,$t0,$t0 + addl $t0,$e,$e +___ +$code.=<<___ if ($i>=15); # with forward Xupdate + addl $K,$e,$e ; $i + shd $a,$a,27,$t1 + xor @X[($j+2)%16],@X[$j%16],@X[$j%16] + addl @X[$i%16],$e,$e + and $c,$b,$t0 + xor @X[($j+8)%16],@X[$j%16],@X[$j%16] + addl $t1,$e,$e + andcm $d,$b,$t1 + shd $b,$b,2,$b + or $t1,$t0,$t0 + xor @X[($j+13)%16],@X[$j%16],@X[$j%16] + add $t0,$e,$e + shd @X[$j%16],@X[$j%16],31,@X[$j%16] +___ +} + +sub BODY_20_39 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +$code.=<<___ if ($i<79); + xor @X[($j+2)%16],@X[$j%16],@X[$j%16] ; $i + addl $K,$e,$e + shd $a,$a,27,$t1 + xor @X[($j+8)%16],@X[$j%16],@X[$j%16] + addl @X[$i%16],$e,$e + xor $b,$c,$t0 + xor @X[($j+13)%16],@X[$j%16],@X[$j%16] + addl $t1,$e,$e + shd $b,$b,2,$b + xor $d,$t0,$t0 + shd @X[$j%16],@X[$j%16],31,@X[$j%16] + addl $t0,$e,$e +___ +$code.=<<___ if ($i==79); # with context load + ldw 0($ctx),@X[0] ; $i + addl $K,$e,$e + shd $a,$a,27,$t1 + ldw 4($ctx),@X[1] + addl @X[$i%16],$e,$e + xor $b,$c,$t0 + ldw 8($ctx),@X[2] + addl $t1,$e,$e + shd $b,$b,2,$b + xor $d,$t0,$t0 + ldw 12($ctx),@X[3] + addl $t0,$e,$e + ldw 16($ctx),@X[4] +___ +} + +sub BODY_40_59 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +$code.=<<___; + shd $a,$a,27,$t1 ; $i + addl $K,$e,$e + xor @X[($j+2)%16],@X[$j%16],@X[$j%16] + xor $d,$c,$t0 + addl @X[$i%16],$e,$e + xor @X[($j+8)%16],@X[$j%16],@X[$j%16] + and $b,$t0,$t0 + addl $t1,$e,$e + shd $b,$b,2,$b + xor @X[($j+13)%16],@X[$j%16],@X[$j%16] + addl $t0,$e,$e + and $d,$c,$t1 + shd @X[$j%16],@X[$j%16],31,@X[$j%16] + addl $t1,$e,$e +___ +} + +$code=<<___; + .LEVEL $LEVEL + .SPACE \$TEXT\$ + .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY + + .EXPORT sha1_block_data_order,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR +sha1_block_data_order + .PROC + .CALLINFO FRAME=`$FRAME-14*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=16 + .ENTRY + $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue + $PUSHMA %r3,$FRAME(%sp) + $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp) + $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp) + $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp) + $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp) + $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp) + $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp) + $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp) + $PUSH %r11,`-$FRAME+8*$SIZE_T`(%sp) + $PUSH %r12,`-$FRAME+9*$SIZE_T`(%sp) + $PUSH %r13,`-$FRAME+10*$SIZE_T`(%sp) + $PUSH %r14,`-$FRAME+11*$SIZE_T`(%sp) + $PUSH %r15,`-$FRAME+12*$SIZE_T`(%sp) + $PUSH %r16,`-$FRAME+13*$SIZE_T`(%sp) + + ldw 0($ctx),$A + ldw 4($ctx),$B + ldw 8($ctx),$C + ldw 12($ctx),$D + ldw 16($ctx),$E + + extru $inp,31,2,$t0 ; t0=inp&3; + sh3addl $t0,%r0,$t0 ; t0*=8; + subi 32,$t0,$t0 ; t0=32-t0; + mtctl $t0,%cr11 ; %sar=t0; + +L\$oop + ldi 3,$t0 + andcm $inp,$t0,$t0 ; 64-bit neutral +___ + for ($i=0;$i<15;$i++) { # load input block + $code.="\tldw `4*$i`($t0),@X[$i]\n"; } +$code.=<<___; + cmpb,*= $inp,$t0,L\$aligned + ldw 60($t0),@X[15] + ldw 64($t0),@X[16] +___ + for ($i=0;$i<16;$i++) { # align input + $code.="\tvshd @X[$i],@X[$i+1],@X[$i]\n"; } +$code.=<<___; +L\$aligned + ldil L'0x5a827000,$K ; K_00_19 + ldo 0x999($K),$K +___ +for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + ldil L'0x6ed9e000,$K ; K_20_39 + ldo 0xba1($K),$K +___ + +for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + ldil L'0x8f1bb000,$K ; K_40_59 + ldo 0xcdc($K),$K +___ + +for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + ldil L'0xca62c000,$K ; K_60_79 + ldo 0x1d6($K),$K +___ +for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } + +$code.=<<___; + addl @X[0],$A,$A + addl @X[1],$B,$B + addl @X[2],$C,$C + addl @X[3],$D,$D + addl @X[4],$E,$E + stw $A,0($ctx) + stw $B,4($ctx) + stw $C,8($ctx) + stw $D,12($ctx) + stw $E,16($ctx) + addib,*<> -1,$num,L\$oop + ldo 64($inp),$inp + + $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue + $POP `-$FRAME+1*$SIZE_T`(%sp),%r4 + $POP `-$FRAME+2*$SIZE_T`(%sp),%r5 + $POP `-$FRAME+3*$SIZE_T`(%sp),%r6 + $POP `-$FRAME+4*$SIZE_T`(%sp),%r7 + $POP `-$FRAME+5*$SIZE_T`(%sp),%r8 + $POP `-$FRAME+6*$SIZE_T`(%sp),%r9 + $POP `-$FRAME+7*$SIZE_T`(%sp),%r10 + $POP `-$FRAME+8*$SIZE_T`(%sp),%r11 + $POP `-$FRAME+9*$SIZE_T`(%sp),%r12 + $POP `-$FRAME+10*$SIZE_T`(%sp),%r13 + $POP `-$FRAME+11*$SIZE_T`(%sp),%r14 + $POP `-$FRAME+12*$SIZE_T`(%sp),%r15 + $POP `-$FRAME+13*$SIZE_T`(%sp),%r16 + bv (%r2) + .EXIT + $POPMB -$FRAME(%sp),%r3 + .PROCEND + .STRINGZ "SHA1 block transform for PA-RISC, CRYPTOGAMS by " +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +$code =~ s/,\*/,/gm if ($SIZE_T==4); +$code =~ s/\bbv\b/bve/gm if ($SIZE_T==8); +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/sha/asm/sha1-ppc.pl b/libs/openssl/crypto/sha/asm/sha1-ppc.pl new file mode 100755 index 00000000..2140dd2f --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha1-ppc.pl @@ -0,0 +1,326 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# I let hardware handle unaligned input(*), except on page boundaries +# (see below for details). Otherwise straightforward implementation +# with X vector in register bank. The module is big-endian [which is +# not big deal as there're no little-endian targets left around]. +# +# (*) this means that this module is inappropriate for PPC403? Does +# anybody know if pre-POWER3 can sustain unaligned load? + +# -m64 -m32 +# ---------------------------------- +# PPC970,gcc-4.0.0 +76% +59% +# Power6,xlc-7 +68% +33% + +$flavour = shift; + +if ($flavour =~ /64/) { + $SIZE_T =8; + $LRSAVE =2*$SIZE_T; + $UCMP ="cmpld"; + $STU ="stdu"; + $POP ="ld"; + $PUSH ="std"; +} elsif ($flavour =~ /32/) { + $SIZE_T =4; + $LRSAVE =$SIZE_T; + $UCMP ="cmplw"; + $STU ="stwu"; + $POP ="lwz"; + $PUSH ="stw"; +} else { die "nonsense $flavour"; } + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or +die "can't locate ppc-xlate.pl"; + +open STDOUT,"| $^X $xlate $flavour ".shift || die "can't call $xlate: $!"; + +$FRAME=24*$SIZE_T+64; +$LOCALS=6*$SIZE_T; + +$K ="r0"; +$sp ="r1"; +$toc="r2"; +$ctx="r3"; +$inp="r4"; +$num="r5"; +$t0 ="r15"; +$t1 ="r6"; + +$A ="r7"; +$B ="r8"; +$C ="r9"; +$D ="r10"; +$E ="r11"; +$T ="r12"; + +@V=($A,$B,$C,$D,$E,$T); +@X=("r16","r17","r18","r19","r20","r21","r22","r23", + "r24","r25","r26","r27","r28","r29","r30","r31"); + +sub BODY_00_19 { +my ($i,$a,$b,$c,$d,$e,$f)=@_; +my $j=$i+1; +$code.=<<___ if ($i==0); + lwz @X[$i],`$i*4`($inp) +___ +$code.=<<___ if ($i<15); + lwz @X[$j],`$j*4`($inp) + add $f,$K,$e + rotlwi $e,$a,5 + add $f,$f,@X[$i] + and $t0,$c,$b + add $f,$f,$e + andc $t1,$d,$b + rotlwi $b,$b,30 + or $t0,$t0,$t1 + add $f,$f,$t0 +___ +$code.=<<___ if ($i>=15); + add $f,$K,$e + rotlwi $e,$a,5 + xor @X[$j%16],@X[$j%16],@X[($j+2)%16] + add $f,$f,@X[$i%16] + and $t0,$c,$b + xor @X[$j%16],@X[$j%16],@X[($j+8)%16] + add $f,$f,$e + andc $t1,$d,$b + rotlwi $b,$b,30 + or $t0,$t0,$t1 + xor @X[$j%16],@X[$j%16],@X[($j+13)%16] + add $f,$f,$t0 + rotlwi @X[$j%16],@X[$j%16],1 +___ +} + +sub BODY_20_39 { +my ($i,$a,$b,$c,$d,$e,$f)=@_; +my $j=$i+1; +$code.=<<___ if ($i<79); + add $f,$K,$e + rotlwi $e,$a,5 + xor @X[$j%16],@X[$j%16],@X[($j+2)%16] + add $f,$f,@X[$i%16] + xor $t0,$b,$c + xor @X[$j%16],@X[$j%16],@X[($j+8)%16] + add $f,$f,$e + rotlwi $b,$b,30 + xor $t0,$t0,$d + xor @X[$j%16],@X[$j%16],@X[($j+13)%16] + add $f,$f,$t0 + rotlwi @X[$j%16],@X[$j%16],1 +___ +$code.=<<___ if ($i==79); + add $f,$K,$e + rotlwi $e,$a,5 + lwz r16,0($ctx) + add $f,$f,@X[$i%16] + xor $t0,$b,$c + lwz r17,4($ctx) + add $f,$f,$e + rotlwi $b,$b,30 + lwz r18,8($ctx) + xor $t0,$t0,$d + lwz r19,12($ctx) + add $f,$f,$t0 + lwz r20,16($ctx) +___ +} + +sub BODY_40_59 { +my ($i,$a,$b,$c,$d,$e,$f)=@_; +my $j=$i+1; +$code.=<<___; + add $f,$K,$e + rotlwi $e,$a,5 + xor @X[$j%16],@X[$j%16],@X[($j+2)%16] + add $f,$f,@X[$i%16] + and $t0,$b,$c + xor @X[$j%16],@X[$j%16],@X[($j+8)%16] + add $f,$f,$e + or $t1,$b,$c + rotlwi $b,$b,30 + xor @X[$j%16],@X[$j%16],@X[($j+13)%16] + and $t1,$t1,$d + or $t0,$t0,$t1 + rotlwi @X[$j%16],@X[$j%16],1 + add $f,$f,$t0 +___ +} + +$code=<<___; +.machine "any" +.text + +.globl .sha1_block_data_order +.align 4 +.sha1_block_data_order: + $STU $sp,-$FRAME($sp) + mflr r0 + $PUSH r15,`$FRAME-$SIZE_T*17`($sp) + $PUSH r16,`$FRAME-$SIZE_T*16`($sp) + $PUSH r17,`$FRAME-$SIZE_T*15`($sp) + $PUSH r18,`$FRAME-$SIZE_T*14`($sp) + $PUSH r19,`$FRAME-$SIZE_T*13`($sp) + $PUSH r20,`$FRAME-$SIZE_T*12`($sp) + $PUSH r21,`$FRAME-$SIZE_T*11`($sp) + $PUSH r22,`$FRAME-$SIZE_T*10`($sp) + $PUSH r23,`$FRAME-$SIZE_T*9`($sp) + $PUSH r24,`$FRAME-$SIZE_T*8`($sp) + $PUSH r25,`$FRAME-$SIZE_T*7`($sp) + $PUSH r26,`$FRAME-$SIZE_T*6`($sp) + $PUSH r27,`$FRAME-$SIZE_T*5`($sp) + $PUSH r28,`$FRAME-$SIZE_T*4`($sp) + $PUSH r29,`$FRAME-$SIZE_T*3`($sp) + $PUSH r30,`$FRAME-$SIZE_T*2`($sp) + $PUSH r31,`$FRAME-$SIZE_T*1`($sp) + $PUSH r0,`$FRAME+$LRSAVE`($sp) + lwz $A,0($ctx) + lwz $B,4($ctx) + lwz $C,8($ctx) + lwz $D,12($ctx) + lwz $E,16($ctx) + andi. r0,$inp,3 + bne Lunaligned +Laligned: + mtctr $num + bl Lsha1_block_private + b Ldone + +; PowerPC specification allows an implementation to be ill-behaved +; upon unaligned access which crosses page boundary. "Better safe +; than sorry" principle makes me treat it specially. But I don't +; look for particular offending word, but rather for 64-byte input +; block which crosses the boundary. Once found that block is aligned +; and hashed separately... +.align 4 +Lunaligned: + subfic $t1,$inp,4096 + andi. $t1,$t1,4095 ; distance to closest page boundary + srwi. $t1,$t1,6 ; t1/=64 + beq Lcross_page + $UCMP $num,$t1 + ble- Laligned ; didn't cross the page boundary + mtctr $t1 + subfc $num,$t1,$num + bl Lsha1_block_private +Lcross_page: + li $t1,16 + mtctr $t1 + addi r20,$sp,$LOCALS ; spot within the frame +Lmemcpy: + lbz r16,0($inp) + lbz r17,1($inp) + lbz r18,2($inp) + lbz r19,3($inp) + addi $inp,$inp,4 + stb r16,0(r20) + stb r17,1(r20) + stb r18,2(r20) + stb r19,3(r20) + addi r20,r20,4 + bdnz Lmemcpy + + $PUSH $inp,`$FRAME-$SIZE_T*18`($sp) + li $t1,1 + addi $inp,$sp,$LOCALS + mtctr $t1 + bl Lsha1_block_private + $POP $inp,`$FRAME-$SIZE_T*18`($sp) + addic. $num,$num,-1 + bne- Lunaligned + +Ldone: + $POP r0,`$FRAME+$LRSAVE`($sp) + $POP r15,`$FRAME-$SIZE_T*17`($sp) + $POP r16,`$FRAME-$SIZE_T*16`($sp) + $POP r17,`$FRAME-$SIZE_T*15`($sp) + $POP r18,`$FRAME-$SIZE_T*14`($sp) + $POP r19,`$FRAME-$SIZE_T*13`($sp) + $POP r20,`$FRAME-$SIZE_T*12`($sp) + $POP r21,`$FRAME-$SIZE_T*11`($sp) + $POP r22,`$FRAME-$SIZE_T*10`($sp) + $POP r23,`$FRAME-$SIZE_T*9`($sp) + $POP r24,`$FRAME-$SIZE_T*8`($sp) + $POP r25,`$FRAME-$SIZE_T*7`($sp) + $POP r26,`$FRAME-$SIZE_T*6`($sp) + $POP r27,`$FRAME-$SIZE_T*5`($sp) + $POP r28,`$FRAME-$SIZE_T*4`($sp) + $POP r29,`$FRAME-$SIZE_T*3`($sp) + $POP r30,`$FRAME-$SIZE_T*2`($sp) + $POP r31,`$FRAME-$SIZE_T*1`($sp) + mtlr r0 + addi $sp,$sp,$FRAME + blr + .long 0 + .byte 0,12,4,1,0x80,18,3,0 + .long 0 +___ + +# This is private block function, which uses tailored calling +# interface, namely upon entry SHA_CTX is pre-loaded to given +# registers and counter register contains amount of chunks to +# digest... +$code.=<<___; +.align 4 +Lsha1_block_private: +___ +$code.=<<___; # load K_00_19 + lis $K,0x5a82 + ori $K,$K,0x7999 +___ +for($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; # load K_20_39 + lis $K,0x6ed9 + ori $K,$K,0xeba1 +___ +for(;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; # load K_40_59 + lis $K,0x8f1b + ori $K,$K,0xbcdc +___ +for(;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; # load K_60_79 + lis $K,0xca62 + ori $K,$K,0xc1d6 +___ +for(;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + add r16,r16,$E + add r17,r17,$T + add r18,r18,$A + add r19,r19,$B + add r20,r20,$C + stw r16,0($ctx) + mr $A,r16 + stw r17,4($ctx) + mr $B,r17 + stw r18,8($ctx) + mr $C,r18 + stw r19,12($ctx) + mr $D,r19 + stw r20,16($ctx) + mr $E,r20 + addi $inp,$inp,`16*4` + bdnz- Lsha1_block_private + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 +___ +$code.=<<___; +.asciz "SHA1 block transform for PPC, CRYPTOGAMS by " +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/sha/asm/sha1-s390x.pl b/libs/openssl/crypto/sha/asm/sha1-s390x.pl new file mode 100644 index 00000000..9193dda4 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha1-s390x.pl @@ -0,0 +1,246 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# SHA1 block procedure for s390x. + +# April 2007. +# +# Performance is >30% better than gcc 3.3 generated code. But the real +# twist is that SHA1 hardware support is detected and utilized. In +# which case performance can reach further >4.5x for larger chunks. + +# January 2009. +# +# Optimize Xupdate for amount of memory references and reschedule +# instructions to favour dual-issue z10 pipeline. On z10 hardware is +# "only" ~2.3x faster than software. + +# November 2010. +# +# Adapt for -m31 build. If kernel supports what's called "highgprs" +# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit +# instructions and achieve "64-bit" performance even in 31-bit legacy +# application context. The feature is not specific to any particular +# processor, as long as it's "z-CPU". Latter implies that the code +# remains z/Architecture specific. + +$kimdfunc=1; # magic function code for kimd instruction + +$flavour = shift; + +if ($flavour =~ /3[12]/) { + $SIZE_T=4; + $g=""; +} else { + $SIZE_T=8; + $g="g"; +} + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +$K_00_39="%r0"; $K=$K_00_39; +$K_40_79="%r1"; +$ctx="%r2"; $prefetch="%r2"; +$inp="%r3"; +$len="%r4"; + +$A="%r5"; +$B="%r6"; +$C="%r7"; +$D="%r8"; +$E="%r9"; @V=($A,$B,$C,$D,$E); +$t0="%r10"; +$t1="%r11"; +@X=("%r12","%r13","%r14"); +$sp="%r15"; + +$stdframe=16*$SIZE_T+4*8; +$frame=$stdframe+16*4; + +sub Xupdate { +my $i=shift; + +$code.=<<___ if ($i==15); + lg $prefetch,$stdframe($sp) ### Xupdate(16) warm-up + lr $X[0],$X[2] +___ +return if ($i&1); # Xupdate is vectorized and executed every 2nd cycle +$code.=<<___ if ($i<16); + lg $X[0],`$i*4`($inp) ### Xload($i) + rllg $X[1],$X[0],32 +___ +$code.=<<___ if ($i>=16); + xgr $X[0],$prefetch ### Xupdate($i) + lg $prefetch,`$stdframe+4*(($i+2)%16)`($sp) + xg $X[0],`$stdframe+4*(($i+8)%16)`($sp) + xgr $X[0],$prefetch + rll $X[0],$X[0],1 + rllg $X[1],$X[0],32 + rll $X[1],$X[1],1 + rllg $X[0],$X[1],32 + lr $X[2],$X[1] # feedback +___ +$code.=<<___ if ($i<=70); + stg $X[0],`$stdframe+4*($i%16)`($sp) +___ +unshift(@X,pop(@X)); +} + +sub BODY_00_19 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $xi=$X[1]; + + &Xupdate($i); +$code.=<<___; + alr $e,$K ### $i + rll $t1,$a,5 + lr $t0,$d + xr $t0,$c + alr $e,$t1 + nr $t0,$b + alr $e,$xi + xr $t0,$d + rll $b,$b,30 + alr $e,$t0 +___ +} + +sub BODY_20_39 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $xi=$X[1]; + + &Xupdate($i); +$code.=<<___; + alr $e,$K ### $i + rll $t1,$a,5 + lr $t0,$b + alr $e,$t1 + xr $t0,$c + alr $e,$xi + xr $t0,$d + rll $b,$b,30 + alr $e,$t0 +___ +} + +sub BODY_40_59 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $xi=$X[1]; + + &Xupdate($i); +$code.=<<___; + alr $e,$K ### $i + rll $t1,$a,5 + lr $t0,$b + alr $e,$t1 + or $t0,$c + lr $t1,$b + nr $t0,$d + nr $t1,$c + alr $e,$xi + or $t0,$t1 + rll $b,$b,30 + alr $e,$t0 +___ +} + +$code.=<<___; +.text +.align 64 +.type Ktable,\@object +Ktable: .long 0x5a827999,0x6ed9eba1,0x8f1bbcdc,0xca62c1d6 + .skip 48 #.long 0,0,0,0,0,0,0,0,0,0,0,0 +.size Ktable,.-Ktable +.globl sha1_block_data_order +.type sha1_block_data_order,\@function +sha1_block_data_order: +___ +$code.=<<___ if ($kimdfunc); + larl %r1,OPENSSL_s390xcap_P + lg %r0,0(%r1) + tmhl %r0,0x4000 # check for message-security assist + jz .Lsoftware + lghi %r0,0 + la %r1,`2*$SIZE_T`($sp) + .long 0xb93e0002 # kimd %r0,%r2 + lg %r0,`2*$SIZE_T`($sp) + tmhh %r0,`0x8000>>$kimdfunc` + jz .Lsoftware + lghi %r0,$kimdfunc + lgr %r1,$ctx + lgr %r2,$inp + sllg %r3,$len,6 + .long 0xb93e0002 # kimd %r0,%r2 + brc 1,.-4 # pay attention to "partial completion" + br %r14 +.align 16 +.Lsoftware: +___ +$code.=<<___; + lghi %r1,-$frame + st${g} $ctx,`2*$SIZE_T`($sp) + stm${g} %r6,%r15,`6*$SIZE_T`($sp) + lgr %r0,$sp + la $sp,0(%r1,$sp) + st${g} %r0,0($sp) + + larl $t0,Ktable + llgf $A,0($ctx) + llgf $B,4($ctx) + llgf $C,8($ctx) + llgf $D,12($ctx) + llgf $E,16($ctx) + + lg $K_00_39,0($t0) + lg $K_40_79,8($t0) + +.Lloop: + rllg $K_00_39,$K_00_39,32 +___ +for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + rllg $K_00_39,$K_00_39,32 +___ +for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; $K=$K_40_79; + rllg $K_40_79,$K_40_79,32 +___ +for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + rllg $K_40_79,$K_40_79,32 +___ +for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + + l${g} $ctx,`$frame+2*$SIZE_T`($sp) + la $inp,64($inp) + al $A,0($ctx) + al $B,4($ctx) + al $C,8($ctx) + al $D,12($ctx) + al $E,16($ctx) + st $A,0($ctx) + st $B,4($ctx) + st $C,8($ctx) + st $D,12($ctx) + st $E,16($ctx) + brct${g} $len,.Lloop + + lm${g} %r6,%r15,`$frame+6*$SIZE_T`($sp) + br %r14 +.size sha1_block_data_order,.-sha1_block_data_order +.string "SHA1 block transform for s390x, CRYPTOGAMS by " +.comm OPENSSL_s390xcap_P,16,8 +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; + +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/sha/asm/sha1-sparcv9.pl b/libs/openssl/crypto/sha/asm/sha1-sparcv9.pl new file mode 100644 index 00000000..5c161cec --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha1-sparcv9.pl @@ -0,0 +1,284 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# Performance improvement is not really impressive on pre-T1 CPU: +8% +# over Sun C and +25% over gcc [3.3]. While on T1, a.k.a. Niagara, it +# turned to be 40% faster than 64-bit code generated by Sun C 5.8 and +# >2x than 64-bit code generated by gcc 3.4. And there is a gimmick. +# X[16] vector is packed to 8 64-bit registers and as result nothing +# is spilled on stack. In addition input data is loaded in compact +# instruction sequence, thus minimizing the window when the code is +# subject to [inter-thread] cache-thrashing hazard. The goal is to +# ensure scalability on UltraSPARC T1, or rather to avoid decay when +# amount of active threads exceeds the number of physical cores. + +$bits=32; +for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); } +if ($bits==64) { $bias=2047; $frame=192; } +else { $bias=0; $frame=112; } + +$output=shift; +open STDOUT,">$output"; + +@X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7"); +$rot1m="%g2"; +$tmp64="%g3"; +$Xi="%g4"; +$A="%l0"; +$B="%l1"; +$C="%l2"; +$D="%l3"; +$E="%l4"; +@V=($A,$B,$C,$D,$E); +$K_00_19="%l5"; +$K_20_39="%l6"; +$K_40_59="%l7"; +$K_60_79="%g5"; +@K=($K_00_19,$K_20_39,$K_40_59,$K_60_79); + +$ctx="%i0"; +$inp="%i1"; +$len="%i2"; +$tmp0="%i3"; +$tmp1="%i4"; +$tmp2="%i5"; + +sub BODY_00_15 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $xi=($i&1)?@X[($i/2)%8]:$Xi; + +$code.=<<___; + sll $a,5,$tmp0 !! $i + add @K[$i/20],$e,$e + srl $a,27,$tmp1 + add $tmp0,$e,$e + and $c,$b,$tmp0 + add $tmp1,$e,$e + sll $b,30,$tmp2 + andn $d,$b,$tmp1 + srl $b,2,$b + or $tmp1,$tmp0,$tmp1 + or $tmp2,$b,$b + add $xi,$e,$e +___ +if ($i&1 && $i<15) { + $code.= + " srlx @X[(($i+1)/2)%8],32,$Xi\n"; +} +$code.=<<___; + add $tmp1,$e,$e +___ +} + +sub Xupdate { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i/2; + +if ($i&1) { +$code.=<<___; + sll $a,5,$tmp0 !! $i + add @K[$i/20],$e,$e + srl $a,27,$tmp1 +___ +} else { +$code.=<<___; + sllx @X[($j+6)%8],32,$Xi ! Xupdate($i) + xor @X[($j+1)%8],@X[$j%8],@X[$j%8] + srlx @X[($j+7)%8],32,$tmp1 + xor @X[($j+4)%8],@X[$j%8],@X[$j%8] + sll $a,5,$tmp0 !! $i + or $tmp1,$Xi,$Xi + add @K[$i/20],$e,$e !! + xor $Xi,@X[$j%8],@X[$j%8] + srlx @X[$j%8],31,$Xi + add @X[$j%8],@X[$j%8],@X[$j%8] + and $Xi,$rot1m,$Xi + andn @X[$j%8],$rot1m,@X[$j%8] + srl $a,27,$tmp1 !! + or $Xi,@X[$j%8],@X[$j%8] +___ +} +} + +sub BODY_16_19 { +my ($i,$a,$b,$c,$d,$e)=@_; + + &Xupdate(@_); + if ($i&1) { + $xi=@X[($i/2)%8]; + } else { + $xi=$Xi; + $code.="\tsrlx @X[($i/2)%8],32,$xi\n"; + } +$code.=<<___; + add $tmp0,$e,$e !! + and $c,$b,$tmp0 + add $tmp1,$e,$e + sll $b,30,$tmp2 + add $xi,$e,$e + andn $d,$b,$tmp1 + srl $b,2,$b + or $tmp1,$tmp0,$tmp1 + or $tmp2,$b,$b + add $tmp1,$e,$e +___ +} + +sub BODY_20_39 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $xi; + &Xupdate(@_); + if ($i&1) { + $xi=@X[($i/2)%8]; + } else { + $xi=$Xi; + $code.="\tsrlx @X[($i/2)%8],32,$xi\n"; + } +$code.=<<___; + add $tmp0,$e,$e !! + xor $c,$b,$tmp0 + add $tmp1,$e,$e + sll $b,30,$tmp2 + xor $d,$tmp0,$tmp1 + srl $b,2,$b + add $tmp1,$e,$e + or $tmp2,$b,$b + add $xi,$e,$e +___ +} + +sub BODY_40_59 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $xi; + &Xupdate(@_); + if ($i&1) { + $xi=@X[($i/2)%8]; + } else { + $xi=$Xi; + $code.="\tsrlx @X[($i/2)%8],32,$xi\n"; + } +$code.=<<___; + add $tmp0,$e,$e !! + and $c,$b,$tmp0 + add $tmp1,$e,$e + sll $b,30,$tmp2 + or $c,$b,$tmp1 + srl $b,2,$b + and $d,$tmp1,$tmp1 + add $xi,$e,$e + or $tmp1,$tmp0,$tmp1 + or $tmp2,$b,$b + add $tmp1,$e,$e +___ +} + +$code.=<<___ if ($bits==64); +.register %g2,#scratch +.register %g3,#scratch +___ +$code.=<<___; +.section ".text",#alloc,#execinstr + +.align 32 +.globl sha1_block_data_order +sha1_block_data_order: + save %sp,-$frame,%sp + sllx $len,6,$len + add $inp,$len,$len + + or %g0,1,$rot1m + sllx $rot1m,32,$rot1m + or $rot1m,1,$rot1m + + ld [$ctx+0],$A + ld [$ctx+4],$B + ld [$ctx+8],$C + ld [$ctx+12],$D + ld [$ctx+16],$E + andn $inp,7,$tmp0 + + sethi %hi(0x5a827999),$K_00_19 + or $K_00_19,%lo(0x5a827999),$K_00_19 + sethi %hi(0x6ed9eba1),$K_20_39 + or $K_20_39,%lo(0x6ed9eba1),$K_20_39 + sethi %hi(0x8f1bbcdc),$K_40_59 + or $K_40_59,%lo(0x8f1bbcdc),$K_40_59 + sethi %hi(0xca62c1d6),$K_60_79 + or $K_60_79,%lo(0xca62c1d6),$K_60_79 + +.Lloop: + ldx [$tmp0+0],@X[0] + ldx [$tmp0+16],@X[2] + ldx [$tmp0+32],@X[4] + ldx [$tmp0+48],@X[6] + and $inp,7,$tmp1 + ldx [$tmp0+8],@X[1] + sll $tmp1,3,$tmp1 + ldx [$tmp0+24],@X[3] + subcc %g0,$tmp1,$tmp2 ! should be 64-$tmp1, but -$tmp1 works too + ldx [$tmp0+40],@X[5] + bz,pt %icc,.Laligned + ldx [$tmp0+56],@X[7] + + sllx @X[0],$tmp1,@X[0] + ldx [$tmp0+64],$tmp64 +___ +for($i=0;$i<7;$i++) +{ $code.=<<___; + srlx @X[$i+1],$tmp2,$Xi + sllx @X[$i+1],$tmp1,@X[$i+1] + or $Xi,@X[$i],@X[$i] +___ +} +$code.=<<___; + srlx $tmp64,$tmp2,$tmp64 + or $tmp64,@X[7],@X[7] +.Laligned: + srlx @X[0],32,$Xi +___ +for ($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); } +for (;$i<20;$i++) { &BODY_16_19($i,@V); unshift(@V,pop(@V)); } +for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } +for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } +for (;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + + ld [$ctx+0],@X[0] + ld [$ctx+4],@X[1] + ld [$ctx+8],@X[2] + ld [$ctx+12],@X[3] + add $inp,64,$inp + ld [$ctx+16],@X[4] + cmp $inp,$len + + add $A,@X[0],$A + st $A,[$ctx+0] + add $B,@X[1],$B + st $B,[$ctx+4] + add $C,@X[2],$C + st $C,[$ctx+8] + add $D,@X[3],$D + st $D,[$ctx+12] + add $E,@X[4],$E + st $E,[$ctx+16] + + bne `$bits==64?"%xcc":"%icc"`,.Lloop + andn $inp,7,$tmp0 + + ret + restore +.type sha1_block_data_order,#function +.size sha1_block_data_order,(.-sha1_block_data_order) +.asciz "SHA1 block transform for SPARCv9, CRYPTOGAMS by " +.align 4 +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/sha/asm/sha1-sparcv9a.pl b/libs/openssl/crypto/sha/asm/sha1-sparcv9a.pl new file mode 100644 index 00000000..e65291bb --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha1-sparcv9a.pl @@ -0,0 +1,601 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# January 2009 +# +# Provided that UltraSPARC VIS instructions are pipe-lined(*) and +# pairable(*) with IALU ones, offloading of Xupdate to the UltraSPARC +# Graphic Unit would make it possible to achieve higher instruction- +# level parallelism, ILP, and thus higher performance. It should be +# explicitly noted that ILP is the keyword, and it means that this +# code would be unsuitable for cores like UltraSPARC-Tx. The idea is +# not really novel, Sun had VIS-powered implementation for a while. +# Unlike Sun's implementation this one can process multiple unaligned +# input blocks, and as such works as drop-in replacement for OpenSSL +# sha1_block_data_order. Performance improvement was measured to be +# 40% over pure IALU sha1-sparcv9.pl on UltraSPARC-IIi, but 12% on +# UltraSPARC-III. See below for discussion... +# +# The module does not present direct interest for OpenSSL, because +# it doesn't provide better performance on contemporary SPARCv9 CPUs, +# UltraSPARC-Tx and SPARC64-V[II] to be specific. Those who feel they +# absolutely must score on UltraSPARC-I-IV can simply replace +# crypto/sha/asm/sha1-sparcv9.pl with this module. +# +# (*) "Pipe-lined" means that even if it takes several cycles to +# complete, next instruction using same functional unit [but not +# depending on the result of the current instruction] can start +# execution without having to wait for the unit. "Pairable" +# means that two [or more] independent instructions can be +# issued at the very same time. + +$bits=32; +for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); } +if ($bits==64) { $bias=2047; $frame=192; } +else { $bias=0; $frame=112; } + +$output=shift; +open STDOUT,">$output"; + +$ctx="%i0"; +$inp="%i1"; +$len="%i2"; +$tmp0="%i3"; +$tmp1="%i4"; +$tmp2="%i5"; +$tmp3="%g5"; + +$base="%g1"; +$align="%g4"; +$Xfer="%o5"; +$nXfer=$tmp3; +$Xi="%o7"; + +$A="%l0"; +$B="%l1"; +$C="%l2"; +$D="%l3"; +$E="%l4"; +@V=($A,$B,$C,$D,$E); + +$Actx="%o0"; +$Bctx="%o1"; +$Cctx="%o2"; +$Dctx="%o3"; +$Ectx="%o4"; + +$fmul="%f32"; +$VK_00_19="%f34"; +$VK_20_39="%f36"; +$VK_40_59="%f38"; +$VK_60_79="%f40"; +@VK=($VK_00_19,$VK_20_39,$VK_40_59,$VK_60_79); +@X=("%f0", "%f1", "%f2", "%f3", "%f4", "%f5", "%f6", "%f7", + "%f8", "%f9","%f10","%f11","%f12","%f13","%f14","%f15","%f16"); + +# This is reference 2x-parallelized VIS-powered Xupdate procedure. It +# covers even K_NN_MM addition... +sub Xupdate { +my ($i)=@_; +my $K=@VK[($i+16)/20]; +my $j=($i+16)%16; + +# [ provided that GSR.alignaddr_offset is 5, $mul contains +# 0x100ULL<<32|0x100 value and K_NN_MM are pre-loaded to +# chosen registers... ] +$code.=<<___; + fxors @X[($j+13)%16],@X[$j],@X[$j] !-1/-1/-1:X[0]^=X[13] + fxors @X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14] + fxor @X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9] + fxor %f18,@X[$j],@X[$j] ! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9] + faligndata @X[$j],@X[$j],%f18 ! 3/ 7/ 5:Tmp=X[0,1]>>>24 + fpadd32 @X[$j],@X[$j],@X[$j] ! 4/ 8/ 6:X[0,1]<<=1 + fmul8ulx16 %f18,$fmul,%f18 ! 5/10/ 7:Tmp>>=7, Tmp&=1 + ![fxors %f15,%f2,%f2] + for %f18,@X[$j],@X[$j] ! 8/14/10:X[0,1]|=Tmp + ![fxors %f0,%f3,%f3] !10/17/12:X[0] dependency + fpadd32 $K,@X[$j],%f20 + std %f20,[$Xfer+`4*$j`] +___ +# The numbers delimited with slash are the earliest possible dispatch +# cycles for given instruction assuming 1 cycle latency for simple VIS +# instructions, such as on UltraSPARC-I&II, 3 cycles latency, such as +# on UltraSPARC-III&IV, and 2 cycles latency(*), respectively. Being +# 2x-parallelized the procedure is "worth" 5, 8.5 or 6 ticks per SHA1 +# round. As [long as] FPU/VIS instructions are perfectly pairable with +# IALU ones, the round timing is defined by the maximum between VIS +# and IALU timings. The latter varies from round to round and averages +# out at 6.25 ticks. This means that USI&II should operate at IALU +# rate, while USIII&IV - at VIS rate. This explains why performance +# improvement varies among processors. Well, given that pure IALU +# sha1-sparcv9.pl module exhibits virtually uniform performance of +# ~9.3 cycles per SHA1 round. Timings mentioned above are theoretical +# lower limits. Real-life performance was measured to be 6.6 cycles +# per SHA1 round on USIIi and 8.3 on USIII. The latter is lower than +# half-round VIS timing, because there are 16 Xupdate-free rounds, +# which "push down" average theoretical timing to 8 cycles... + +# (*) SPARC64-V[II] was originally believed to have 2 cycles VIS +# latency. Well, it might have, but it doesn't have dedicated +# VIS-unit. Instead, VIS instructions are executed by other +# functional units, ones used here - by IALU. This doesn't +# improve effective ILP... +} + +# The reference Xupdate procedure is then "strained" over *pairs* of +# BODY_NN_MM and kind of modulo-scheduled in respect to X[n]^=X[n+13] +# and K_NN_MM addition. It's "running" 15 rounds ahead, which leaves +# plenty of room to amortize for read-after-write hazard, as well as +# to fetch and align input for the next spin. The VIS instructions are +# scheduled for latency of 2 cycles, because there are not enough IALU +# instructions to schedule for latency of 3, while scheduling for 1 +# would give no gain on USI&II anyway. + +sub BODY_00_19 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i&~1; +my $k=($j+16+2)%16; # ahead reference +my $l=($j+16-2)%16; # behind reference +my $K=@VK[($j+16-2)/20]; + +$j=($j+16)%16; + +$code.=<<___ if (!($i&1)); + sll $a,5,$tmp0 !! $i + and $c,$b,$tmp3 + ld [$Xfer+`4*($i%16)`],$Xi + fxors @X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14] + srl $a,27,$tmp1 + add $tmp0,$e,$e + fxor @X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9] + sll $b,30,$tmp2 + add $tmp1,$e,$e + andn $d,$b,$tmp1 + add $Xi,$e,$e + fxor %f18,@X[$j],@X[$j] ! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9] + srl $b,2,$b + or $tmp1,$tmp3,$tmp1 + or $tmp2,$b,$b + add $tmp1,$e,$e + faligndata @X[$j],@X[$j],%f18 ! 3/ 7/ 5:Tmp=X[0,1]>>>24 +___ +$code.=<<___ if ($i&1); + sll $a,5,$tmp0 !! $i + and $c,$b,$tmp3 + ld [$Xfer+`4*($i%16)`],$Xi + fpadd32 @X[$j],@X[$j],@X[$j] ! 4/ 8/ 6:X[0,1]<<=1 + srl $a,27,$tmp1 + add $tmp0,$e,$e + fmul8ulx16 %f18,$fmul,%f18 ! 5/10/ 7:Tmp>>=7, Tmp&=1 + sll $b,30,$tmp2 + add $tmp1,$e,$e + fpadd32 $K,@X[$l],%f20 ! + andn $d,$b,$tmp1 + add $Xi,$e,$e + fxors @X[($k+13)%16],@X[$k],@X[$k] !-1/-1/-1:X[0]^=X[13] + srl $b,2,$b + or $tmp1,$tmp3,$tmp1 + fxor %f18,@X[$j],@X[$j] ! 8/14/10:X[0,1]|=Tmp + or $tmp2,$b,$b + add $tmp1,$e,$e +___ +$code.=<<___ if ($i&1 && $i>=2); + std %f20,[$Xfer+`4*$l`] ! +___ +} + +sub BODY_20_39 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i&~1; +my $k=($j+16+2)%16; # ahead reference +my $l=($j+16-2)%16; # behind reference +my $K=@VK[($j+16-2)/20]; + +$j=($j+16)%16; + +$code.=<<___ if (!($i&1) && $i<64); + sll $a,5,$tmp0 !! $i + ld [$Xfer+`4*($i%16)`],$Xi + fxors @X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14] + srl $a,27,$tmp1 + add $tmp0,$e,$e + fxor @X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9] + xor $c,$b,$tmp0 + add $tmp1,$e,$e + sll $b,30,$tmp2 + xor $d,$tmp0,$tmp1 + fxor %f18,@X[$j],@X[$j] ! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9] + srl $b,2,$b + add $tmp1,$e,$e + or $tmp2,$b,$b + add $Xi,$e,$e + faligndata @X[$j],@X[$j],%f18 ! 3/ 7/ 5:Tmp=X[0,1]>>>24 +___ +$code.=<<___ if ($i&1 && $i<64); + sll $a,5,$tmp0 !! $i + ld [$Xfer+`4*($i%16)`],$Xi + fpadd32 @X[$j],@X[$j],@X[$j] ! 4/ 8/ 6:X[0,1]<<=1 + srl $a,27,$tmp1 + add $tmp0,$e,$e + fmul8ulx16 %f18,$fmul,%f18 ! 5/10/ 7:Tmp>>=7, Tmp&=1 + xor $c,$b,$tmp0 + add $tmp1,$e,$e + fpadd32 $K,@X[$l],%f20 ! + sll $b,30,$tmp2 + xor $d,$tmp0,$tmp1 + fxors @X[($k+13)%16],@X[$k],@X[$k] !-1/-1/-1:X[0]^=X[13] + srl $b,2,$b + add $tmp1,$e,$e + fxor %f18,@X[$j],@X[$j] ! 8/14/10:X[0,1]|=Tmp + or $tmp2,$b,$b + add $Xi,$e,$e + std %f20,[$Xfer+`4*$l`] ! +___ +$code.=<<___ if ($i==64); + sll $a,5,$tmp0 !! $i + ld [$Xfer+`4*($i%16)`],$Xi + fpadd32 $K,@X[$l],%f20 + srl $a,27,$tmp1 + add $tmp0,$e,$e + xor $c,$b,$tmp0 + add $tmp1,$e,$e + sll $b,30,$tmp2 + xor $d,$tmp0,$tmp1 + std %f20,[$Xfer+`4*$l`] + srl $b,2,$b + add $tmp1,$e,$e + or $tmp2,$b,$b + add $Xi,$e,$e +___ +$code.=<<___ if ($i>64); + sll $a,5,$tmp0 !! $i + ld [$Xfer+`4*($i%16)`],$Xi + srl $a,27,$tmp1 + add $tmp0,$e,$e + xor $c,$b,$tmp0 + add $tmp1,$e,$e + sll $b,30,$tmp2 + xor $d,$tmp0,$tmp1 + srl $b,2,$b + add $tmp1,$e,$e + or $tmp2,$b,$b + add $Xi,$e,$e +___ +} + +sub BODY_40_59 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i&~1; +my $k=($j+16+2)%16; # ahead reference +my $l=($j+16-2)%16; # behind reference +my $K=@VK[($j+16-2)/20]; + +$j=($j+16)%16; + +$code.=<<___ if (!($i&1)); + sll $a,5,$tmp0 !! $i + ld [$Xfer+`4*($i%16)`],$Xi + fxors @X[($j+14)%16],@X[$j+1],@X[$j+1]! 0/ 0/ 0:X[1]^=X[14] + srl $a,27,$tmp1 + add $tmp0,$e,$e + fxor @X[($j+2)%16],@X[($j+8)%16],%f18! 1/ 1/ 1:Tmp=X[2,3]^X[8,9] + and $c,$b,$tmp0 + add $tmp1,$e,$e + sll $b,30,$tmp2 + or $c,$b,$tmp1 + fxor %f18,@X[$j],@X[$j] ! 2/ 4/ 3:X[0,1]^=X[2,3]^X[8,9] + srl $b,2,$b + and $d,$tmp1,$tmp1 + add $Xi,$e,$e + or $tmp1,$tmp0,$tmp1 + faligndata @X[$j],@X[$j],%f18 ! 3/ 7/ 5:Tmp=X[0,1]>>>24 + or $tmp2,$b,$b + add $tmp1,$e,$e + fpadd32 @X[$j],@X[$j],@X[$j] ! 4/ 8/ 6:X[0,1]<<=1 +___ +$code.=<<___ if ($i&1); + sll $a,5,$tmp0 !! $i + ld [$Xfer+`4*($i%16)`],$Xi + srl $a,27,$tmp1 + add $tmp0,$e,$e + fmul8ulx16 %f18,$fmul,%f18 ! 5/10/ 7:Tmp>>=7, Tmp&=1 + and $c,$b,$tmp0 + add $tmp1,$e,$e + fpadd32 $K,@X[$l],%f20 ! + sll $b,30,$tmp2 + or $c,$b,$tmp1 + fxors @X[($k+13)%16],@X[$k],@X[$k] !-1/-1/-1:X[0]^=X[13] + srl $b,2,$b + and $d,$tmp1,$tmp1 + fxor %f18,@X[$j],@X[$j] ! 8/14/10:X[0,1]|=Tmp + add $Xi,$e,$e + or $tmp1,$tmp0,$tmp1 + or $tmp2,$b,$b + add $tmp1,$e,$e + std %f20,[$Xfer+`4*$l`] ! +___ +} + +# If there is more data to process, then we pre-fetch the data for +# next iteration in last ten rounds... +sub BODY_70_79 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i&~1; +my $m=($i%8)*2; + +$j=($j+16)%16; + +$code.=<<___ if ($i==70); + sll $a,5,$tmp0 !! $i + ld [$Xfer+`4*($i%16)`],$Xi + srl $a,27,$tmp1 + add $tmp0,$e,$e + ldd [$inp+64],@X[0] + xor $c,$b,$tmp0 + add $tmp1,$e,$e + sll $b,30,$tmp2 + xor $d,$tmp0,$tmp1 + srl $b,2,$b + add $tmp1,$e,$e + or $tmp2,$b,$b + add $Xi,$e,$e + + and $inp,-64,$nXfer + inc 64,$inp + and $nXfer,255,$nXfer + alignaddr %g0,$align,%g0 + add $base,$nXfer,$nXfer +___ +$code.=<<___ if ($i==71); + sll $a,5,$tmp0 !! $i + ld [$Xfer+`4*($i%16)`],$Xi + srl $a,27,$tmp1 + add $tmp0,$e,$e + xor $c,$b,$tmp0 + add $tmp1,$e,$e + sll $b,30,$tmp2 + xor $d,$tmp0,$tmp1 + srl $b,2,$b + add $tmp1,$e,$e + or $tmp2,$b,$b + add $Xi,$e,$e +___ +$code.=<<___ if ($i>=72); + faligndata @X[$m],@X[$m+2],@X[$m] + sll $a,5,$tmp0 !! $i + ld [$Xfer+`4*($i%16)`],$Xi + srl $a,27,$tmp1 + add $tmp0,$e,$e + xor $c,$b,$tmp0 + add $tmp1,$e,$e + fpadd32 $VK_00_19,@X[$m],%f20 + sll $b,30,$tmp2 + xor $d,$tmp0,$tmp1 + srl $b,2,$b + add $tmp1,$e,$e + or $tmp2,$b,$b + add $Xi,$e,$e +___ +$code.=<<___ if ($i<77); + ldd [$inp+`8*($i+1-70)`],@X[2*($i+1-70)] +___ +$code.=<<___ if ($i==77); # redundant if $inp was aligned + add $align,63,$tmp0 + and $tmp0,-8,$tmp0 + ldd [$inp+$tmp0],@X[16] +___ +$code.=<<___ if ($i>=72); + std %f20,[$nXfer+`4*$m`] +___ +} + +$code.=<<___; +.section ".text",#alloc,#execinstr + +.align 64 +vis_const: +.long 0x5a827999,0x5a827999 ! K_00_19 +.long 0x6ed9eba1,0x6ed9eba1 ! K_20_39 +.long 0x8f1bbcdc,0x8f1bbcdc ! K_40_59 +.long 0xca62c1d6,0xca62c1d6 ! K_60_79 +.long 0x00000100,0x00000100 +.align 64 +.type vis_const,#object +.size vis_const,(.-vis_const) + +.globl sha1_block_data_order +sha1_block_data_order: + save %sp,-$frame,%sp + add %fp,$bias-256,$base + +1: call .+8 + add %o7,vis_const-1b,$tmp0 + + ldd [$tmp0+0],$VK_00_19 + ldd [$tmp0+8],$VK_20_39 + ldd [$tmp0+16],$VK_40_59 + ldd [$tmp0+24],$VK_60_79 + ldd [$tmp0+32],$fmul + + ld [$ctx+0],$Actx + and $base,-256,$base + ld [$ctx+4],$Bctx + sub $base,$bias+$frame,%sp + ld [$ctx+8],$Cctx + and $inp,7,$align + ld [$ctx+12],$Dctx + and $inp,-8,$inp + ld [$ctx+16],$Ectx + + ! X[16] is maintained in FP register bank + alignaddr %g0,$align,%g0 + ldd [$inp+0],@X[0] + sub $inp,-64,$Xfer + ldd [$inp+8],@X[2] + and $Xfer,-64,$Xfer + ldd [$inp+16],@X[4] + and $Xfer,255,$Xfer + ldd [$inp+24],@X[6] + add $base,$Xfer,$Xfer + ldd [$inp+32],@X[8] + ldd [$inp+40],@X[10] + ldd [$inp+48],@X[12] + brz,pt $align,.Laligned + ldd [$inp+56],@X[14] + + ldd [$inp+64],@X[16] + faligndata @X[0],@X[2],@X[0] + faligndata @X[2],@X[4],@X[2] + faligndata @X[4],@X[6],@X[4] + faligndata @X[6],@X[8],@X[6] + faligndata @X[8],@X[10],@X[8] + faligndata @X[10],@X[12],@X[10] + faligndata @X[12],@X[14],@X[12] + faligndata @X[14],@X[16],@X[14] + +.Laligned: + mov 5,$tmp0 + dec 1,$len + alignaddr %g0,$tmp0,%g0 + fpadd32 $VK_00_19,@X[0],%f16 + fpadd32 $VK_00_19,@X[2],%f18 + fpadd32 $VK_00_19,@X[4],%f20 + fpadd32 $VK_00_19,@X[6],%f22 + fpadd32 $VK_00_19,@X[8],%f24 + fpadd32 $VK_00_19,@X[10],%f26 + fpadd32 $VK_00_19,@X[12],%f28 + fpadd32 $VK_00_19,@X[14],%f30 + std %f16,[$Xfer+0] + mov $Actx,$A + std %f18,[$Xfer+8] + mov $Bctx,$B + std %f20,[$Xfer+16] + mov $Cctx,$C + std %f22,[$Xfer+24] + mov $Dctx,$D + std %f24,[$Xfer+32] + mov $Ectx,$E + std %f26,[$Xfer+40] + fxors @X[13],@X[0],@X[0] + std %f28,[$Xfer+48] + ba .Loop + std %f30,[$Xfer+56] +.align 32 +.Loop: +___ +for ($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); } +for (;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } +for (;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } +for (;$i<70;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + tst $len + bz,pn `$bits==32?"%icc":"%xcc"`,.Ltail + nop +___ +for (;$i<80;$i++) { &BODY_70_79($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + add $A,$Actx,$Actx + add $B,$Bctx,$Bctx + add $C,$Cctx,$Cctx + add $D,$Dctx,$Dctx + add $E,$Ectx,$Ectx + mov 5,$tmp0 + fxors @X[13],@X[0],@X[0] + mov $Actx,$A + mov $Bctx,$B + mov $Cctx,$C + mov $Dctx,$D + mov $Ectx,$E + alignaddr %g0,$tmp0,%g0 + dec 1,$len + ba .Loop + mov $nXfer,$Xfer + +.align 32 +.Ltail: +___ +for($i=70;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + add $A,$Actx,$Actx + add $B,$Bctx,$Bctx + add $C,$Cctx,$Cctx + add $D,$Dctx,$Dctx + add $E,$Ectx,$Ectx + + st $Actx,[$ctx+0] + st $Bctx,[$ctx+4] + st $Cctx,[$ctx+8] + st $Dctx,[$ctx+12] + st $Ectx,[$ctx+16] + + ret + restore +.type sha1_block_data_order,#function +.size sha1_block_data_order,(.-sha1_block_data_order) +.asciz "SHA1 block transform for SPARCv9a, CRYPTOGAMS by " +.align 4 +___ + +# Purpose of these subroutines is to explicitly encode VIS instructions, +# so that one can compile the module without having to specify VIS +# extentions on compiler command line, e.g. -xarch=v9 vs. -xarch=v9a. +# Idea is to reserve for option to produce "universal" binary and let +# programmer detect if current CPU is VIS capable at run-time. +sub unvis { +my ($mnemonic,$rs1,$rs2,$rd)=@_; +my ($ref,$opf); +my %visopf = ( "fmul8ulx16" => 0x037, + "faligndata" => 0x048, + "fpadd32" => 0x052, + "fxor" => 0x06c, + "fxors" => 0x06d ); + + $ref = "$mnemonic\t$rs1,$rs2,$rd"; + + if ($opf=$visopf{$mnemonic}) { + foreach ($rs1,$rs2,$rd) { + return $ref if (!/%f([0-9]{1,2})/); + $_=$1; + if ($1>=32) { + return $ref if ($1&1); + # re-encode for upper double register addressing + $_=($1|$1>>5)&31; + } + } + + return sprintf ".word\t0x%08x !%s", + 0x81b00000|$rd<<25|$rs1<<14|$opf<<5|$rs2, + $ref; + } else { + return $ref; + } +} +sub unalignaddr { +my ($mnemonic,$rs1,$rs2,$rd)=@_; +my %bias = ( "g" => 0, "o" => 8, "l" => 16, "i" => 24 ); +my $ref="$mnemonic\t$rs1,$rs2,$rd"; + + foreach ($rs1,$rs2,$rd) { + if (/%([goli])([0-7])/) { $_=$bias{$1}+$2; } + else { return $ref; } + } + return sprintf ".word\t0x%08x !%s", + 0x81b00300|$rd<<25|$rs1<<14|$rs2, + $ref; +} + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +$code =~ s/\b(f[^\s]*)\s+(%f[0-9]{1,2}),(%f[0-9]{1,2}),(%f[0-9]{1,2})/ + &unvis($1,$2,$3,$4) + /gem; +$code =~ s/\b(alignaddr)\s+(%[goli][0-7]),(%[goli][0-7]),(%[goli][0-7])/ + &unalignaddr($1,$2,$3,$4) + /gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/sha/asm/sha1-thumb.pl b/libs/openssl/crypto/sha/asm/sha1-thumb.pl new file mode 100644 index 00000000..7c9ea9b0 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha1-thumb.pl @@ -0,0 +1,259 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# sha1_block for Thumb. +# +# January 2007. +# +# The code does not present direct interest to OpenSSL, because of low +# performance. Its purpose is to establish _size_ benchmark. Pretty +# useless one I must say, because 30% or 88 bytes larger ARMv4 code +# [avialable on demand] is almost _twice_ as fast. It should also be +# noted that in-lining of .Lcommon and .Lrotate improves performance +# by over 40%, while code increases by only 10% or 32 bytes. But once +# again, the goal was to establish _size_ benchmark, not performance. + +$output=shift; +open STDOUT,">$output"; + +$inline=0; +#$cheat_on_binutils=1; + +$t0="r0"; +$t1="r1"; +$t2="r2"; +$a="r3"; +$b="r4"; +$c="r5"; +$d="r6"; +$e="r7"; +$K="r8"; # "upper" registers can be used in add/sub and mov insns +$ctx="r9"; +$inp="r10"; +$len="r11"; +$Xi="r12"; + +sub common { +<<___; + sub $t0,#4 + ldr $t1,[$t0] + add $e,$K @ E+=K_xx_xx + lsl $t2,$a,#5 + add $t2,$e + lsr $e,$a,#27 + add $t2,$e @ E+=ROR(A,27) + add $t2,$t1 @ E+=X[i] +___ +} +sub rotate { +<<___; + mov $e,$d @ E=D + mov $d,$c @ D=C + lsl $c,$b,#30 + lsr $b,$b,#2 + orr $c,$b @ C=ROR(B,2) + mov $b,$a @ B=A + add $a,$t2,$t1 @ A=E+F_xx_xx(B,C,D) +___ +} + +sub BODY_00_19 { +$code.=$inline?&common():"\tbl .Lcommon\n"; +$code.=<<___; + mov $t1,$c + eor $t1,$d + and $t1,$b + eor $t1,$d @ F_00_19(B,C,D) +___ +$code.=$inline?&rotate():"\tbl .Lrotate\n"; +} + +sub BODY_20_39 { +$code.=$inline?&common():"\tbl .Lcommon\n"; +$code.=<<___; + mov $t1,$b + eor $t1,$c + eor $t1,$d @ F_20_39(B,C,D) +___ +$code.=$inline?&rotate():"\tbl .Lrotate\n"; +} + +sub BODY_40_59 { +$code.=$inline?&common():"\tbl .Lcommon\n"; +$code.=<<___; + mov $t1,$b + and $t1,$c + mov $e,$b + orr $e,$c + and $e,$d + orr $t1,$e @ F_40_59(B,C,D) +___ +$code.=$inline?&rotate():"\tbl .Lrotate\n"; +} + +$code=<<___; +.text +.code 16 + +.global sha1_block_data_order +.type sha1_block_data_order,%function + +.align 2 +sha1_block_data_order: +___ +if ($cheat_on_binutils) { +$code.=<<___; +.code 32 + add r3,pc,#1 + bx r3 @ switch to Thumb ISA +.code 16 +___ +} +$code.=<<___; + push {r4-r7} + mov r3,r8 + mov r4,r9 + mov r5,r10 + mov r6,r11 + mov r7,r12 + push {r3-r7,lr} + lsl r2,#6 + mov $ctx,r0 @ save context + mov $inp,r1 @ save inp + mov $len,r2 @ save len + add $len,$inp @ $len to point at inp end + +.Lloop: + mov $Xi,sp + mov $t2,sp + sub $t2,#16*4 @ [3] +.LXload: + ldrb $a,[$t1,#0] @ $t1 is r1 and holds inp + ldrb $b,[$t1,#1] + ldrb $c,[$t1,#2] + ldrb $d,[$t1,#3] + lsl $a,#24 + lsl $b,#16 + lsl $c,#8 + orr $a,$b + orr $a,$c + orr $a,$d + add $t1,#4 + push {$a} + cmp sp,$t2 + bne .LXload @ [+14*16] + + mov $inp,$t1 @ update $inp + sub $t2,#32*4 + sub $t2,#32*4 + mov $e,#31 @ [+4] +.LXupdate: + ldr $a,[sp,#15*4] + ldr $b,[sp,#13*4] + ldr $c,[sp,#7*4] + ldr $d,[sp,#2*4] + eor $a,$b + eor $a,$c + eor $a,$d + ror $a,$e + push {$a} + cmp sp,$t2 + bne .LXupdate @ [+(11+1)*64] + + ldmia $t0!,{$a,$b,$c,$d,$e} @ $t0 is r0 and holds ctx + mov $t0,$Xi + + ldr $t2,.LK_00_19 + mov $t1,$t0 + sub $t1,#20*4 + mov $Xi,$t1 + mov $K,$t2 @ [+7+4] +.L_00_19: +___ + &BODY_00_19(); +$code.=<<___; + cmp $Xi,$t0 + bne .L_00_19 @ [+(2+9+4+2+8+2)*20] + + ldr $t2,.LK_20_39 + mov $t1,$t0 + sub $t1,#20*4 + mov $Xi,$t1 + mov $K,$t2 @ [+5] +.L_20_39_or_60_79: +___ + &BODY_20_39(); +$code.=<<___; + cmp $Xi,$t0 + bne .L_20_39_or_60_79 @ [+(2+9+3+2+8+2)*20*2] + cmp sp,$t0 + beq .Ldone @ [+2] + + ldr $t2,.LK_40_59 + mov $t1,$t0 + sub $t1,#20*4 + mov $Xi,$t1 + mov $K,$t2 @ [+5] +.L_40_59: +___ + &BODY_40_59(); +$code.=<<___; + cmp $Xi,$t0 + bne .L_40_59 @ [+(2+9+6+2+8+2)*20] + + ldr $t2,.LK_60_79 + mov $Xi,sp + mov $K,$t2 + b .L_20_39_or_60_79 @ [+4] +.Ldone: + mov $t0,$ctx + ldr $t1,[$t0,#0] + ldr $t2,[$t0,#4] + add $a,$t1 + ldr $t1,[$t0,#8] + add $b,$t2 + ldr $t2,[$t0,#12] + add $c,$t1 + ldr $t1,[$t0,#16] + add $d,$t2 + add $e,$t1 + stmia $t0!,{$a,$b,$c,$d,$e} @ [+20] + + add sp,#80*4 @ deallocate stack frame + mov $t0,$ctx @ restore ctx + mov $t1,$inp @ restore inp + cmp $t1,$len + beq .Lexit + b .Lloop @ [+6] total 3212 cycles +.Lexit: + pop {r2-r7} + mov r8,r2 + mov r9,r3 + mov r10,r4 + mov r11,r5 + mov r12,r6 + mov lr,r7 + pop {r4-r7} + bx lr +.align 2 +___ +$code.=".Lcommon:\n".&common()."\tmov pc,lr\n" if (!$inline); +$code.=".Lrotate:\n".&rotate()."\tmov pc,lr\n" if (!$inline); +$code.=<<___; +.align 2 +.LK_00_19: .word 0x5a827999 +.LK_20_39: .word 0x6ed9eba1 +.LK_40_59: .word 0x8f1bbcdc +.LK_60_79: .word 0xca62c1d6 +.size sha1_block_data_order,.-sha1_block_data_order +.asciz "SHA1 block transform for Thumb, CRYPTOGAMS by " +___ + +print $code; +close STDOUT; # enforce flush diff --git a/libs/openssl/crypto/sha/asm/sha1-x86_64.pl b/libs/openssl/crypto/sha/asm/sha1-x86_64.pl new file mode 100755 index 00000000..f15c7ec3 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha1-x86_64.pl @@ -0,0 +1,1261 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# sha1_block procedure for x86_64. +# +# It was brought to my attention that on EM64T compiler-generated code +# was far behind 32-bit assembler implementation. This is unlike on +# Opteron where compiler-generated code was only 15% behind 32-bit +# assembler, which originally made it hard to motivate the effort. +# There was suggestion to mechanically translate 32-bit code, but I +# dismissed it, reasoning that x86_64 offers enough register bank +# capacity to fully utilize SHA-1 parallelism. Therefore this fresh +# implementation:-) However! While 64-bit code does perform better +# on Opteron, I failed to beat 32-bit assembler on EM64T core. Well, +# x86_64 does offer larger *addressable* bank, but out-of-order core +# reaches for even more registers through dynamic aliasing, and EM64T +# core must have managed to run-time optimize even 32-bit code just as +# good as 64-bit one. Performance improvement is summarized in the +# following table: +# +# gcc 3.4 32-bit asm cycles/byte +# Opteron +45% +20% 6.8 +# Xeon P4 +65% +0% 9.9 +# Core2 +60% +10% 7.0 + +# August 2009. +# +# The code was revised to minimize code size and to maximize +# "distance" between instructions producing input to 'lea' +# instruction and the 'lea' instruction itself, which is essential +# for Intel Atom core. + +# October 2010. +# +# Add SSSE3, Supplemental[!] SSE3, implementation. The idea behind it +# is to offload message schedule denoted by Wt in NIST specification, +# or Xupdate in OpenSSL source, to SIMD unit. See sha1-586.pl module +# for background and implementation details. The only difference from +# 32-bit code is that 64-bit code doesn't have to spill @X[] elements +# to free temporary registers. + +# April 2011. +# +# Add AVX code path. See sha1-586.pl for further information. + +###################################################################### +# Current performance is summarized in following table. Numbers are +# CPU clock cycles spent to process single byte (less is better). +# +# x86_64 SSSE3 AVX +# P4 9.8 - +# Opteron 6.6 - +# Core2 6.7 6.1/+10% - +# Atom 11.0 9.7/+13% - +# Westmere 7.1 5.6/+27% - +# Sandy Bridge 7.9 6.3/+25% 5.2/+51% + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +$avx=1 if (`$ENV{CC} -Wa,-v -c -o /dev/null -x assembler /dev/null 2>&1` + =~ /GNU assembler version ([2-9]\.[0-9]+)/ && + $1>=2.19); +$avx=1 if (!$avx && $win64 && ($flavour =~ /nasm/ || $ENV{ASM} =~ /nasm/) && + `nasm -v 2>&1` =~ /NASM version ([2-9]\.[0-9]+)/ && + $1>=2.09); +$avx=1 if (!$avx && $win64 && ($flavour =~ /masm/ || $ENV{ASM} =~ /ml64/) && + `ml64 2>&1` =~ /Version ([0-9]+)\./ && + $1>=10); + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +$ctx="%rdi"; # 1st arg +$inp="%rsi"; # 2nd arg +$num="%rdx"; # 3rd arg + +# reassign arguments in order to produce more compact code +$ctx="%r8"; +$inp="%r9"; +$num="%r10"; + +$t0="%eax"; +$t1="%ebx"; +$t2="%ecx"; +@xi=("%edx","%ebp"); +$A="%esi"; +$B="%edi"; +$C="%r11d"; +$D="%r12d"; +$E="%r13d"; + +@V=($A,$B,$C,$D,$E); + +sub BODY_00_19 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +$code.=<<___ if ($i==0); + mov `4*$i`($inp),$xi[0] + bswap $xi[0] + mov $xi[0],`4*$i`(%rsp) +___ +$code.=<<___ if ($i<15); + mov $c,$t0 + mov `4*$j`($inp),$xi[1] + mov $a,$t2 + xor $d,$t0 + bswap $xi[1] + rol \$5,$t2 + lea 0x5a827999($xi[0],$e),$e + and $b,$t0 + mov $xi[1],`4*$j`(%rsp) + add $t2,$e + xor $d,$t0 + rol \$30,$b + add $t0,$e +___ +$code.=<<___ if ($i>=15); + mov `4*($j%16)`(%rsp),$xi[1] + mov $c,$t0 + mov $a,$t2 + xor `4*(($j+2)%16)`(%rsp),$xi[1] + xor $d,$t0 + rol \$5,$t2 + xor `4*(($j+8)%16)`(%rsp),$xi[1] + and $b,$t0 + lea 0x5a827999($xi[0],$e),$e + xor `4*(($j+13)%16)`(%rsp),$xi[1] + xor $d,$t0 + rol \$1,$xi[1] + add $t2,$e + rol \$30,$b + mov $xi[1],`4*($j%16)`(%rsp) + add $t0,$e +___ +unshift(@xi,pop(@xi)); +} + +sub BODY_20_39 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +my $K=($i<40)?0x6ed9eba1:0xca62c1d6; +$code.=<<___ if ($i<79); + mov `4*($j%16)`(%rsp),$xi[1] + mov $c,$t0 + mov $a,$t2 + xor `4*(($j+2)%16)`(%rsp),$xi[1] + xor $b,$t0 + rol \$5,$t2 + lea $K($xi[0],$e),$e + xor `4*(($j+8)%16)`(%rsp),$xi[1] + xor $d,$t0 + add $t2,$e + xor `4*(($j+13)%16)`(%rsp),$xi[1] + rol \$30,$b + add $t0,$e + rol \$1,$xi[1] +___ +$code.=<<___ if ($i<76); + mov $xi[1],`4*($j%16)`(%rsp) +___ +$code.=<<___ if ($i==79); + mov $c,$t0 + mov $a,$t2 + xor $b,$t0 + lea $K($xi[0],$e),$e + rol \$5,$t2 + xor $d,$t0 + add $t2,$e + rol \$30,$b + add $t0,$e +___ +unshift(@xi,pop(@xi)); +} + +sub BODY_40_59 { +my ($i,$a,$b,$c,$d,$e)=@_; +my $j=$i+1; +$code.=<<___; + mov `4*($j%16)`(%rsp),$xi[1] + mov $c,$t0 + mov $c,$t1 + xor `4*(($j+2)%16)`(%rsp),$xi[1] + and $d,$t0 + mov $a,$t2 + xor `4*(($j+8)%16)`(%rsp),$xi[1] + xor $d,$t1 + lea 0x8f1bbcdc($xi[0],$e),$e + rol \$5,$t2 + xor `4*(($j+13)%16)`(%rsp),$xi[1] + add $t0,$e + and $b,$t1 + rol \$1,$xi[1] + add $t1,$e + rol \$30,$b + mov $xi[1],`4*($j%16)`(%rsp) + add $t2,$e +___ +unshift(@xi,pop(@xi)); +} + +$code.=<<___; +.text +.extern OPENSSL_ia32cap_P + +.globl sha1_block_data_order +.type sha1_block_data_order,\@function,3 +.align 16 +sha1_block_data_order: + mov OPENSSL_ia32cap_P+0(%rip),%r9d + mov OPENSSL_ia32cap_P+4(%rip),%r8d + test \$`1<<9`,%r8d # check SSSE3 bit + jz .Lialu +___ +$code.=<<___ if ($avx); + and \$`1<<28`,%r8d # mask AVX bit + and \$`1<<30`,%r9d # mask "Intel CPU" bit + or %r9d,%r8d + cmp \$`1<<28|1<<30`,%r8d + je _avx_shortcut +___ +$code.=<<___; + jmp _ssse3_shortcut + +.align 16 +.Lialu: + push %rbx + push %rbp + push %r12 + push %r13 + mov %rsp,%r11 + mov %rdi,$ctx # reassigned argument + sub \$`8+16*4`,%rsp + mov %rsi,$inp # reassigned argument + and \$-64,%rsp + mov %rdx,$num # reassigned argument + mov %r11,`16*4`(%rsp) +.Lprologue: + + mov 0($ctx),$A + mov 4($ctx),$B + mov 8($ctx),$C + mov 12($ctx),$D + mov 16($ctx),$E + jmp .Lloop + +.align 16 +.Lloop: +___ +for($i=0;$i<20;$i++) { &BODY_00_19($i,@V); unshift(@V,pop(@V)); } +for(;$i<40;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } +for(;$i<60;$i++) { &BODY_40_59($i,@V); unshift(@V,pop(@V)); } +for(;$i<80;$i++) { &BODY_20_39($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + add 0($ctx),$A + add 4($ctx),$B + add 8($ctx),$C + add 12($ctx),$D + add 16($ctx),$E + mov $A,0($ctx) + mov $B,4($ctx) + mov $C,8($ctx) + mov $D,12($ctx) + mov $E,16($ctx) + + sub \$1,$num + lea `16*4`($inp),$inp + jnz .Lloop + + mov `16*4`(%rsp),%rsi + mov (%rsi),%r13 + mov 8(%rsi),%r12 + mov 16(%rsi),%rbp + mov 24(%rsi),%rbx + lea 32(%rsi),%rsp +.Lepilogue: + ret +.size sha1_block_data_order,.-sha1_block_data_order +___ +{{{ +my $Xi=4; +my @X=map("%xmm$_",(4..7,0..3)); +my @Tx=map("%xmm$_",(8..10)); +my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp"); # size optimization +my @T=("%esi","%edi"); +my $j=0; +my $K_XX_XX="%r11"; + +my $_rol=sub { &rol(@_) }; +my $_ror=sub { &ror(@_) }; + +$code.=<<___; +.type sha1_block_data_order_ssse3,\@function,3 +.align 16 +sha1_block_data_order_ssse3: +_ssse3_shortcut: + push %rbx + push %rbp + push %r12 + lea `-64-($win64?5*16:0)`(%rsp),%rsp +___ +$code.=<<___ if ($win64); + movaps %xmm6,64+0(%rsp) + movaps %xmm7,64+16(%rsp) + movaps %xmm8,64+32(%rsp) + movaps %xmm9,64+48(%rsp) + movaps %xmm10,64+64(%rsp) +.Lprologue_ssse3: +___ +$code.=<<___; + mov %rdi,$ctx # reassigned argument + mov %rsi,$inp # reassigned argument + mov %rdx,$num # reassigned argument + + shl \$6,$num + add $inp,$num + lea K_XX_XX(%rip),$K_XX_XX + + mov 0($ctx),$A # load context + mov 4($ctx),$B + mov 8($ctx),$C + mov 12($ctx),$D + mov $B,@T[0] # magic seed + mov 16($ctx),$E + + movdqa 64($K_XX_XX),@X[2] # pbswap mask + movdqa 0($K_XX_XX),@Tx[1] # K_00_19 + movdqu 0($inp),@X[-4&7] # load input to %xmm[0-3] + movdqu 16($inp),@X[-3&7] + movdqu 32($inp),@X[-2&7] + movdqu 48($inp),@X[-1&7] + pshufb @X[2],@X[-4&7] # byte swap + add \$64,$inp + pshufb @X[2],@X[-3&7] + pshufb @X[2],@X[-2&7] + pshufb @X[2],@X[-1&7] + paddd @Tx[1],@X[-4&7] # add K_00_19 + paddd @Tx[1],@X[-3&7] + paddd @Tx[1],@X[-2&7] + movdqa @X[-4&7],0(%rsp) # X[]+K xfer to IALU + psubd @Tx[1],@X[-4&7] # restore X[] + movdqa @X[-3&7],16(%rsp) + psubd @Tx[1],@X[-3&7] + movdqa @X[-2&7],32(%rsp) + psubd @Tx[1],@X[-2&7] + jmp .Loop_ssse3 +___ + +sub AUTOLOAD() # thunk [simplified] 32-bit style perlasm +{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; + my $arg = pop; + $arg = "\$$arg" if ($arg*1 eq $arg); + $code .= "\t$opcode\t".join(',',$arg,reverse @_)."\n"; +} + +sub Xupdate_ssse3_16_31() # recall that $Xi starts wtih 4 +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 40 instructions + my ($a,$b,$c,$d,$e); + + &movdqa (@X[0],@X[-3&7]); + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (@Tx[0],@X[-1&7]); + &palignr(@X[0],@X[-4&7],8); # compose "X[-14]" in "X[0]" + eval(shift(@insns)); + eval(shift(@insns)); + + &paddd (@Tx[1],@X[-1&7]); + eval(shift(@insns)); + eval(shift(@insns)); + &psrldq (@Tx[0],4); # "X[-3]", 3 dwords + eval(shift(@insns)); + eval(shift(@insns)); + &pxor (@X[0],@X[-4&7]); # "X[0]"^="X[-16]" + eval(shift(@insns)); + eval(shift(@insns)); + + &pxor (@Tx[0],@X[-2&7]); # "X[-3]"^"X[-8]" + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &pxor (@X[0],@Tx[0]); # "X[0]"^="X[-3]"^"X[-8]" + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + + &movdqa (@Tx[2],@X[0]); + &movdqa (@Tx[0],@X[0]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &pslldq (@Tx[2],12); # "X[0]"<<96, extract one dword + &paddd (@X[0],@X[0]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &psrld (@Tx[0],31); + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (@Tx[1],@Tx[2]); + eval(shift(@insns)); + eval(shift(@insns)); + + &psrld (@Tx[2],30); + &por (@X[0],@Tx[0]); # "X[0]"<<<=1 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &pslld (@Tx[1],2); + &pxor (@X[0],@Tx[2]); + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (@Tx[2],eval(16*(($Xi)/5))."($K_XX_XX)"); # K_XX_XX + eval(shift(@insns)); + eval(shift(@insns)); + + &pxor (@X[0],@Tx[1]); # "X[0]"^=("X[0]">>96)<<<2 + + foreach (@insns) { eval; } # remaining instructions [if any] + + $Xi++; push(@X,shift(@X)); # "rotate" X[] + push(@Tx,shift(@Tx)); +} + +sub Xupdate_ssse3_32_79() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 to 48 instructions + my ($a,$b,$c,$d,$e); + + &movdqa (@Tx[0],@X[-1&7]) if ($Xi==8); + eval(shift(@insns)); # body_20_39 + &pxor (@X[0],@X[-4&7]); # "X[0]"="X[-32]"^"X[-16]" + &palignr(@Tx[0],@X[-2&7],8); # compose "X[-6]" + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + + &pxor (@X[0],@X[-7&7]); # "X[0]"^="X[-28]" + eval(shift(@insns)); + eval(shift(@insns)) if (@insns[0] !~ /&ro[rl]/); + if ($Xi%5) { + &movdqa (@Tx[2],@Tx[1]);# "perpetuate" K_XX_XX... + } else { # ... or load next one + &movdqa (@Tx[2],eval(16*($Xi/5))."($K_XX_XX)"); + } + &paddd (@Tx[1],@X[-1&7]); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &pxor (@X[0],@Tx[0]); # "X[0]"^="X[-6]" + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + + &movdqa (@Tx[0],@X[0]); + &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &pslld (@X[0],2); + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + &psrld (@Tx[0],30); + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &por (@X[0],@Tx[0]); # "X[0]"<<<=2 + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + &movdqa (@Tx[1],@X[0]) if ($Xi<19); + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + + foreach (@insns) { eval; } # remaining instructions + + $Xi++; push(@X,shift(@X)); # "rotate" X[] + push(@Tx,shift(@Tx)); +} + +sub Xuplast_ssse3_80() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + &paddd (@Tx[1],@X[-1&7]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer IALU + + foreach (@insns) { eval; } # remaining instructions + + &cmp ($inp,$num); + &je (".Ldone_ssse3"); + + unshift(@Tx,pop(@Tx)); + + &movdqa (@X[2],"64($K_XX_XX)"); # pbswap mask + &movdqa (@Tx[1],"0($K_XX_XX)"); # K_00_19 + &movdqu (@X[-4&7],"0($inp)"); # load input + &movdqu (@X[-3&7],"16($inp)"); + &movdqu (@X[-2&7],"32($inp)"); + &movdqu (@X[-1&7],"48($inp)"); + &pshufb (@X[-4&7],@X[2]); # byte swap + &add ($inp,64); + + $Xi=0; +} + +sub Xloop_ssse3() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + eval(shift(@insns)); + &pshufb (@X[($Xi-3)&7],@X[2]); + eval(shift(@insns)); + eval(shift(@insns)); + &paddd (@X[($Xi-4)&7],@Tx[1]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + &movdqa (eval(16*$Xi)."(%rsp)",@X[($Xi-4)&7]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + &psubd (@X[($Xi-4)&7],@Tx[1]); + + foreach (@insns) { eval; } + $Xi++; +} + +sub Xtail_ssse3() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + foreach (@insns) { eval; } +} + +sub body_00_19 () { + ( + '($a,$b,$c,$d,$e)=@V;'. + '&add ($e,eval(4*($j&15))."(%rsp)");', # X[]+K xfer + '&xor ($c,$d);', + '&mov (@T[1],$a);', # $b in next round + '&$_rol ($a,5);', + '&and (@T[0],$c);', # ($b&($c^$d)) + '&xor ($c,$d);', # restore $c + '&xor (@T[0],$d);', + '&add ($e,$a);', + '&$_ror ($b,$j?7:2);', # $b>>>2 + '&add ($e,@T[0]);' .'$j++; unshift(@V,pop(@V)); unshift(@T,pop(@T));' + ); +} + +sub body_20_39 () { + ( + '($a,$b,$c,$d,$e)=@V;'. + '&add ($e,eval(4*($j++&15))."(%rsp)");', # X[]+K xfer + '&xor (@T[0],$d);', # ($b^$d) + '&mov (@T[1],$a);', # $b in next round + '&$_rol ($a,5);', + '&xor (@T[0],$c);', # ($b^$d^$c) + '&add ($e,$a);', + '&$_ror ($b,7);', # $b>>>2 + '&add ($e,@T[0]);' .'unshift(@V,pop(@V)); unshift(@T,pop(@T));' + ); +} + +sub body_40_59 () { + ( + '($a,$b,$c,$d,$e)=@V;'. + '&mov (@T[1],$c);', + '&xor ($c,$d);', + '&add ($e,eval(4*($j++&15))."(%rsp)");', # X[]+K xfer + '&and (@T[1],$d);', + '&and (@T[0],$c);', # ($b&($c^$d)) + '&$_ror ($b,7);', # $b>>>2 + '&add ($e,@T[1]);', + '&mov (@T[1],$a);', # $b in next round + '&$_rol ($a,5);', + '&add ($e,@T[0]);', + '&xor ($c,$d);', # restore $c + '&add ($e,$a);' .'unshift(@V,pop(@V)); unshift(@T,pop(@T));' + ); +} +$code.=<<___; +.align 16 +.Loop_ssse3: +___ + &Xupdate_ssse3_16_31(\&body_00_19); + &Xupdate_ssse3_16_31(\&body_00_19); + &Xupdate_ssse3_16_31(\&body_00_19); + &Xupdate_ssse3_16_31(\&body_00_19); + &Xupdate_ssse3_32_79(\&body_00_19); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_40_59); + &Xupdate_ssse3_32_79(\&body_20_39); + &Xuplast_ssse3_80(\&body_20_39); # can jump to "done" + + $saved_j=$j; @saved_V=@V; + + &Xloop_ssse3(\&body_20_39); + &Xloop_ssse3(\&body_20_39); + &Xloop_ssse3(\&body_20_39); + +$code.=<<___; + add 0($ctx),$A # update context + add 4($ctx),@T[0] + add 8($ctx),$C + add 12($ctx),$D + mov $A,0($ctx) + add 16($ctx),$E + mov @T[0],4($ctx) + mov @T[0],$B # magic seed + mov $C,8($ctx) + mov $D,12($ctx) + mov $E,16($ctx) + jmp .Loop_ssse3 + +.align 16 +.Ldone_ssse3: +___ + $j=$saved_j; @V=@saved_V; + + &Xtail_ssse3(\&body_20_39); + &Xtail_ssse3(\&body_20_39); + &Xtail_ssse3(\&body_20_39); + +$code.=<<___; + add 0($ctx),$A # update context + add 4($ctx),@T[0] + add 8($ctx),$C + mov $A,0($ctx) + add 12($ctx),$D + mov @T[0],4($ctx) + add 16($ctx),$E + mov $C,8($ctx) + mov $D,12($ctx) + mov $E,16($ctx) +___ +$code.=<<___ if ($win64); + movaps 64+0(%rsp),%xmm6 + movaps 64+16(%rsp),%xmm7 + movaps 64+32(%rsp),%xmm8 + movaps 64+48(%rsp),%xmm9 + movaps 64+64(%rsp),%xmm10 +___ +$code.=<<___; + lea `64+($win64?5*16:0)`(%rsp),%rsi + mov 0(%rsi),%r12 + mov 8(%rsi),%rbp + mov 16(%rsi),%rbx + lea 24(%rsi),%rsp +.Lepilogue_ssse3: + ret +.size sha1_block_data_order_ssse3,.-sha1_block_data_order_ssse3 +___ + +if ($avx) { +my $Xi=4; +my @X=map("%xmm$_",(4..7,0..3)); +my @Tx=map("%xmm$_",(8..10)); +my @V=($A,$B,$C,$D,$E)=("%eax","%ebx","%ecx","%edx","%ebp"); # size optimization +my @T=("%esi","%edi"); +my $j=0; +my $K_XX_XX="%r11"; + +my $_rol=sub { &shld(@_[0],@_) }; +my $_ror=sub { &shrd(@_[0],@_) }; + +$code.=<<___; +.type sha1_block_data_order_avx,\@function,3 +.align 16 +sha1_block_data_order_avx: +_avx_shortcut: + push %rbx + push %rbp + push %r12 + lea `-64-($win64?5*16:0)`(%rsp),%rsp +___ +$code.=<<___ if ($win64); + movaps %xmm6,64+0(%rsp) + movaps %xmm7,64+16(%rsp) + movaps %xmm8,64+32(%rsp) + movaps %xmm9,64+48(%rsp) + movaps %xmm10,64+64(%rsp) +.Lprologue_avx: +___ +$code.=<<___; + mov %rdi,$ctx # reassigned argument + mov %rsi,$inp # reassigned argument + mov %rdx,$num # reassigned argument + vzeroupper + + shl \$6,$num + add $inp,$num + lea K_XX_XX(%rip),$K_XX_XX + + mov 0($ctx),$A # load context + mov 4($ctx),$B + mov 8($ctx),$C + mov 12($ctx),$D + mov $B,@T[0] # magic seed + mov 16($ctx),$E + + vmovdqa 64($K_XX_XX),@X[2] # pbswap mask + vmovdqa 0($K_XX_XX),@Tx[1] # K_00_19 + vmovdqu 0($inp),@X[-4&7] # load input to %xmm[0-3] + vmovdqu 16($inp),@X[-3&7] + vmovdqu 32($inp),@X[-2&7] + vmovdqu 48($inp),@X[-1&7] + vpshufb @X[2],@X[-4&7],@X[-4&7] # byte swap + add \$64,$inp + vpshufb @X[2],@X[-3&7],@X[-3&7] + vpshufb @X[2],@X[-2&7],@X[-2&7] + vpshufb @X[2],@X[-1&7],@X[-1&7] + vpaddd @Tx[1],@X[-4&7],@X[0] # add K_00_19 + vpaddd @Tx[1],@X[-3&7],@X[1] + vpaddd @Tx[1],@X[-2&7],@X[2] + vmovdqa @X[0],0(%rsp) # X[]+K xfer to IALU + vmovdqa @X[1],16(%rsp) + vmovdqa @X[2],32(%rsp) + jmp .Loop_avx +___ + +sub Xupdate_avx_16_31() # recall that $Xi starts wtih 4 +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 40 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + eval(shift(@insns)); + &vpalignr(@X[0],@X[-3&7],@X[-4&7],8); # compose "X[-14]" in "X[0]" + eval(shift(@insns)); + eval(shift(@insns)); + + &vpaddd (@Tx[1],@Tx[1],@X[-1&7]); + eval(shift(@insns)); + eval(shift(@insns)); + &vpsrldq(@Tx[0],@X[-1&7],4); # "X[-3]", 3 dwords + eval(shift(@insns)); + eval(shift(@insns)); + &vpxor (@X[0],@X[0],@X[-4&7]); # "X[0]"^="X[-16]" + eval(shift(@insns)); + eval(shift(@insns)); + + &vpxor (@Tx[0],@Tx[0],@X[-2&7]); # "X[-3]"^"X[-8]" + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpxor (@X[0],@X[0],@Tx[0]); # "X[0]"^="X[-3]"^"X[-8]" + eval(shift(@insns)); + eval(shift(@insns)); + &vmovdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + + &vpsrld (@Tx[0],@X[0],31); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpslldq(@Tx[2],@X[0],12); # "X[0]"<<96, extract one dword + &vpaddd (@X[0],@X[0],@X[0]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpsrld (@Tx[1],@Tx[2],30); + &vpor (@X[0],@X[0],@Tx[0]); # "X[0]"<<<=1 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpslld (@Tx[2],@Tx[2],2); + &vpxor (@X[0],@X[0],@Tx[1]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &vpxor (@X[0],@X[0],@Tx[2]); # "X[0]"^=("X[0]">>96)<<<2 + eval(shift(@insns)); + eval(shift(@insns)); + &vmovdqa (@Tx[2],eval(16*(($Xi)/5))."($K_XX_XX)"); # K_XX_XX + eval(shift(@insns)); + eval(shift(@insns)); + + + foreach (@insns) { eval; } # remaining instructions [if any] + + $Xi++; push(@X,shift(@X)); # "rotate" X[] + push(@Tx,shift(@Tx)); +} + +sub Xupdate_avx_32_79() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 to 48 instructions + my ($a,$b,$c,$d,$e); + + &vpalignr(@Tx[0],@X[-1&7],@X[-2&7],8); # compose "X[-6]" + &vpxor (@X[0],@X[0],@X[-4&7]); # "X[0]"="X[-32]"^"X[-16]" + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + + &vpxor (@X[0],@X[0],@X[-7&7]); # "X[0]"^="X[-28]" + eval(shift(@insns)); + eval(shift(@insns)) if (@insns[0] !~ /&ro[rl]/); + if ($Xi%5) { + &vmovdqa (@Tx[2],@Tx[1]);# "perpetuate" K_XX_XX... + } else { # ... or load next one + &vmovdqa (@Tx[2],eval(16*($Xi/5))."($K_XX_XX)"); + } + &vpaddd (@Tx[1],@Tx[1],@X[-1&7]); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &vpxor (@X[0],@X[0],@Tx[0]); # "X[0]"^="X[-6]" + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + + &vpsrld (@Tx[0],@X[0],30); + &vmovdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &vpslld (@X[0],@X[0],2); + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # ror + eval(shift(@insns)); + + &vpor (@X[0],@X[0],@Tx[0]); # "X[0]"<<<=2 + eval(shift(@insns)); # body_20_39 + eval(shift(@insns)); + &vmovdqa (@Tx[1],@X[0]) if ($Xi<19); + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); # rol + eval(shift(@insns)); + + foreach (@insns) { eval; } # remaining instructions + + $Xi++; push(@X,shift(@X)); # "rotate" X[] + push(@Tx,shift(@Tx)); +} + +sub Xuplast_avx_80() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + &vpaddd (@Tx[1],@Tx[1],@X[-1&7]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + + &movdqa (eval(16*(($Xi-1)&3))."(%rsp)",@Tx[1]); # X[]+K xfer IALU + + foreach (@insns) { eval; } # remaining instructions + + &cmp ($inp,$num); + &je (".Ldone_avx"); + + unshift(@Tx,pop(@Tx)); + + &vmovdqa(@X[2],"64($K_XX_XX)"); # pbswap mask + &vmovdqa(@Tx[1],"0($K_XX_XX)"); # K_00_19 + &vmovdqu(@X[-4&7],"0($inp)"); # load input + &vmovdqu(@X[-3&7],"16($inp)"); + &vmovdqu(@X[-2&7],"32($inp)"); + &vmovdqu(@X[-1&7],"48($inp)"); + &vpshufb(@X[-4&7],@X[-4&7],@X[2]); # byte swap + &add ($inp,64); + + $Xi=0; +} + +sub Xloop_avx() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + eval(shift(@insns)); + eval(shift(@insns)); + &vpshufb(@X[($Xi-3)&7],@X[($Xi-3)&7],@X[2]); + eval(shift(@insns)); + eval(shift(@insns)); + &vpaddd (@X[$Xi&7],@X[($Xi-4)&7],@Tx[1]); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + eval(shift(@insns)); + &vmovdqa(eval(16*$Xi)."(%rsp)",@X[$Xi&7]); # X[]+K xfer to IALU + eval(shift(@insns)); + eval(shift(@insns)); + + foreach (@insns) { eval; } + $Xi++; +} + +sub Xtail_avx() +{ use integer; + my $body = shift; + my @insns = (&$body,&$body,&$body,&$body); # 32 instructions + my ($a,$b,$c,$d,$e); + + foreach (@insns) { eval; } +} + +$code.=<<___; +.align 16 +.Loop_avx: +___ + &Xupdate_avx_16_31(\&body_00_19); + &Xupdate_avx_16_31(\&body_00_19); + &Xupdate_avx_16_31(\&body_00_19); + &Xupdate_avx_16_31(\&body_00_19); + &Xupdate_avx_32_79(\&body_00_19); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_20_39); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_40_59); + &Xupdate_avx_32_79(\&body_20_39); + &Xuplast_avx_80(\&body_20_39); # can jump to "done" + + $saved_j=$j; @saved_V=@V; + + &Xloop_avx(\&body_20_39); + &Xloop_avx(\&body_20_39); + &Xloop_avx(\&body_20_39); + +$code.=<<___; + add 0($ctx),$A # update context + add 4($ctx),@T[0] + add 8($ctx),$C + add 12($ctx),$D + mov $A,0($ctx) + add 16($ctx),$E + mov @T[0],4($ctx) + mov @T[0],$B # magic seed + mov $C,8($ctx) + mov $D,12($ctx) + mov $E,16($ctx) + jmp .Loop_avx + +.align 16 +.Ldone_avx: +___ + $j=$saved_j; @V=@saved_V; + + &Xtail_avx(\&body_20_39); + &Xtail_avx(\&body_20_39); + &Xtail_avx(\&body_20_39); + +$code.=<<___; + vzeroupper + + add 0($ctx),$A # update context + add 4($ctx),@T[0] + add 8($ctx),$C + mov $A,0($ctx) + add 12($ctx),$D + mov @T[0],4($ctx) + add 16($ctx),$E + mov $C,8($ctx) + mov $D,12($ctx) + mov $E,16($ctx) +___ +$code.=<<___ if ($win64); + movaps 64+0(%rsp),%xmm6 + movaps 64+16(%rsp),%xmm7 + movaps 64+32(%rsp),%xmm8 + movaps 64+48(%rsp),%xmm9 + movaps 64+64(%rsp),%xmm10 +___ +$code.=<<___; + lea `64+($win64?5*16:0)`(%rsp),%rsi + mov 0(%rsi),%r12 + mov 8(%rsi),%rbp + mov 16(%rsi),%rbx + lea 24(%rsi),%rsp +.Lepilogue_avx: + ret +.size sha1_block_data_order_avx,.-sha1_block_data_order_avx +___ +} +$code.=<<___; +.align 64 +K_XX_XX: +.long 0x5a827999,0x5a827999,0x5a827999,0x5a827999 # K_00_19 +.long 0x6ed9eba1,0x6ed9eba1,0x6ed9eba1,0x6ed9eba1 # K_20_39 +.long 0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc,0x8f1bbcdc # K_40_59 +.long 0xca62c1d6,0xca62c1d6,0xca62c1d6,0xca62c1d6 # K_60_79 +.long 0x00010203,0x04050607,0x08090a0b,0x0c0d0e0f # pbswap mask +___ +}}} +$code.=<<___; +.asciz "SHA1 block transform for x86_64, CRYPTOGAMS by " +.align 64 +___ + +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type se_handler,\@abi-omnipotent +.align 16 +se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + lea .Lprologue(%rip),%r10 + cmp %r10,%rbx # context->Rip<.Lprologue + jb .Lcommon_seh_tail + + mov 152($context),%rax # pull context->Rsp + + lea .Lepilogue(%rip),%r10 + cmp %r10,%rbx # context->Rip>=.Lepilogue + jae .Lcommon_seh_tail + + mov `16*4`(%rax),%rax # pull saved stack pointer + lea 32(%rax),%rax + + mov -8(%rax),%rbx + mov -16(%rax),%rbp + mov -24(%rax),%r12 + mov -32(%rax),%r13 + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + + jmp .Lcommon_seh_tail +.size se_handler,.-se_handler + +.type ssse3_handler,\@abi-omnipotent +.align 16 +ssse3_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + mov 8($disp),%rsi # disp->ImageBase + mov 56($disp),%r11 # disp->HandlerData + + mov 0(%r11),%r10d # HandlerData[0] + lea (%rsi,%r10),%r10 # prologue label + cmp %r10,%rbx # context->RipRsp + + mov 4(%r11),%r10d # HandlerData[1] + lea (%rsi,%r10),%r10 # epilogue label + cmp %r10,%rbx # context->Rip>=epilogue label + jae .Lcommon_seh_tail + + lea 64(%rax),%rsi + lea 512($context),%rdi # &context.Xmm6 + mov \$10,%ecx + .long 0xa548f3fc # cld; rep movsq + lea `24+64+5*16`(%rax),%rax # adjust stack pointer + + mov -8(%rax),%rbx + mov -16(%rax),%rbp + mov -24(%rax),%r12 + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore cotnext->R12 + +.Lcommon_seh_tail: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$154,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size ssse3_handler,.-ssse3_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_sha1_block_data_order + .rva .LSEH_end_sha1_block_data_order + .rva .LSEH_info_sha1_block_data_order + .rva .LSEH_begin_sha1_block_data_order_ssse3 + .rva .LSEH_end_sha1_block_data_order_ssse3 + .rva .LSEH_info_sha1_block_data_order_ssse3 +___ +$code.=<<___ if ($avx); + .rva .LSEH_begin_sha1_block_data_order_avx + .rva .LSEH_end_sha1_block_data_order_avx + .rva .LSEH_info_sha1_block_data_order_avx +___ +$code.=<<___; +.section .xdata +.align 8 +.LSEH_info_sha1_block_data_order: + .byte 9,0,0,0 + .rva se_handler +.LSEH_info_sha1_block_data_order_ssse3: + .byte 9,0,0,0 + .rva ssse3_handler + .rva .Lprologue_ssse3,.Lepilogue_ssse3 # HandlerData[] +___ +$code.=<<___ if ($avx); +.LSEH_info_sha1_block_data_order_avx: + .byte 9,0,0,0 + .rva ssse3_handler + .rva .Lprologue_avx,.Lepilogue_avx # HandlerData[] +___ +} + +#################################################################### + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/sha/asm/sha256-586.pl b/libs/openssl/crypto/sha/asm/sha256-586.pl new file mode 100644 index 00000000..52a7c7f8 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha256-586.pl @@ -0,0 +1,249 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# SHA256 block transform for x86. September 2007. +# +# Performance in clock cycles per processed byte (less is better): +# +# Pentium PIII P4 AMD K8 Core2 +# gcc 46 36 41 27 26 +# icc 57 33 38 25 23 +# x86 asm 40 30 33 20 18 +# x86_64 asm(*) - - 21 16 16 +# +# (*) x86_64 assembler performance is presented for reference +# purposes. +# +# Performance improvement over compiler generated code varies from +# 10% to 40% [see above]. Not very impressive on some µ-archs, but +# it's 5 times smaller and optimizies amount of writes. + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386"); + +$A="eax"; +$E="edx"; +$T="ebx"; +$Aoff=&DWP(0,"esp"); +$Boff=&DWP(4,"esp"); +$Coff=&DWP(8,"esp"); +$Doff=&DWP(12,"esp"); +$Eoff=&DWP(16,"esp"); +$Foff=&DWP(20,"esp"); +$Goff=&DWP(24,"esp"); +$Hoff=&DWP(28,"esp"); +$Xoff=&DWP(32,"esp"); +$K256="ebp"; + +sub BODY_00_15() { + my $in_16_63=shift; + + &mov ("ecx",$E); + &add ($T,"edi") if ($in_16_63); # T += sigma1(X[-2]) + &ror ("ecx",25-11); + &mov ("esi",$Foff); + &xor ("ecx",$E); + &ror ("ecx",11-6); + &mov (&DWP(4*(8+15),"esp"),$T) if ($in_16_63); # save X[0] + &xor ("ecx",$E); + &ror ("ecx",6); # Sigma1(e) + &mov ("edi",$Goff); + &add ($T,"ecx"); # T += Sigma1(e) + + &xor ("esi","edi"); + &mov ($Eoff,$E); # modulo-scheduled + &mov ("ecx",$A); + &and ("esi",$E); + &mov ($E,$Doff); # e becomes d, which is e in next iteration + &xor ("esi","edi"); # Ch(e,f,g) + &mov ("edi",$A); + &add ($T,"esi"); # T += Ch(e,f,g) + + &ror ("ecx",22-13); + &add ($T,$Hoff); # T += h + &xor ("ecx",$A); + &ror ("ecx",13-2); + &mov ("esi",$Boff); + &xor ("ecx",$A); + &ror ("ecx",2); # Sigma0(a) + &add ($E,$T); # d += T + &mov ("edi",$Coff); + + &add ($T,"ecx"); # T += Sigma0(a) + &mov ($Aoff,$A); # modulo-scheduled + + &mov ("ecx",$A); + &sub ("esp",4); + &or ($A,"esi"); # a becomes h, which is a in next iteration + &and ("ecx","esi"); + &and ($A,"edi"); + &mov ("esi",&DWP(0,$K256)); + &or ($A,"ecx"); # h=Maj(a,b,c) + + &add ($K256,4); + &add ($A,$T); # h += T + &mov ($T,&DWP(4*(8+15+16-1),"esp")) if ($in_16_63); # preload T + &add ($E,"esi"); # d += K256[i] + &add ($A,"esi"); # h += K256[i] +} + +&function_begin("sha256_block_data_order"); + &mov ("esi",wparam(0)); # ctx + &mov ("edi",wparam(1)); # inp + &mov ("eax",wparam(2)); # num + &mov ("ebx","esp"); # saved sp + + &call (&label("pic_point")); # make it PIC! +&set_label("pic_point"); + &blindpop($K256); + &lea ($K256,&DWP(&label("K256")."-".&label("pic_point"),$K256)); + + &sub ("esp",16); + &and ("esp",-64); + + &shl ("eax",6); + &add ("eax","edi"); + &mov (&DWP(0,"esp"),"esi"); # ctx + &mov (&DWP(4,"esp"),"edi"); # inp + &mov (&DWP(8,"esp"),"eax"); # inp+num*128 + &mov (&DWP(12,"esp"),"ebx"); # saved sp + +&set_label("loop",16); + # copy input block to stack reversing byte and dword order + for($i=0;$i<4;$i++) { + &mov ("eax",&DWP($i*16+0,"edi")); + &mov ("ebx",&DWP($i*16+4,"edi")); + &mov ("ecx",&DWP($i*16+8,"edi")); + &mov ("edx",&DWP($i*16+12,"edi")); + &bswap ("eax"); + &bswap ("ebx"); + &bswap ("ecx"); + &bswap ("edx"); + &push ("eax"); + &push ("ebx"); + &push ("ecx"); + &push ("edx"); + } + &add ("edi",64); + &sub ("esp",4*8); # place for A,B,C,D,E,F,G,H + &mov (&DWP(4*(8+16)+4,"esp"),"edi"); + + # copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack + &mov ($A,&DWP(0,"esi")); + &mov ("ebx",&DWP(4,"esi")); + &mov ("ecx",&DWP(8,"esi")); + &mov ("edi",&DWP(12,"esi")); + # &mov ($Aoff,$A); + &mov ($Boff,"ebx"); + &mov ($Coff,"ecx"); + &mov ($Doff,"edi"); + &mov ($E,&DWP(16,"esi")); + &mov ("ebx",&DWP(20,"esi")); + &mov ("ecx",&DWP(24,"esi")); + &mov ("edi",&DWP(28,"esi")); + # &mov ($Eoff,$E); + &mov ($Foff,"ebx"); + &mov ($Goff,"ecx"); + &mov ($Hoff,"edi"); + +&set_label("00_15",16); + &mov ($T,&DWP(4*(8+15),"esp")); + + &BODY_00_15(); + + &cmp ("esi",0xc19bf174); + &jne (&label("00_15")); + + &mov ($T,&DWP(4*(8+15+16-1),"esp")); # preloaded in BODY_00_15(1) +&set_label("16_63",16); + &mov ("esi",$T); + &mov ("ecx",&DWP(4*(8+15+16-14),"esp")); + &ror ("esi",18-7); + &mov ("edi","ecx"); + &xor ("esi",$T); + &ror ("esi",7); + &shr ($T,3); + + &ror ("edi",19-17); + &xor ($T,"esi"); # T = sigma0(X[-15]) + &xor ("edi","ecx"); + &ror ("edi",17); + &shr ("ecx",10); + &add ($T,&DWP(4*(8+15+16),"esp")); # T += X[-16] + &xor ("edi","ecx"); # sigma1(X[-2]) + + &add ($T,&DWP(4*(8+15+16-9),"esp")); # T += X[-7] + # &add ($T,"edi"); # T += sigma1(X[-2]) + # &mov (&DWP(4*(8+15),"esp"),$T); # save X[0] + + &BODY_00_15(1); + + &cmp ("esi",0xc67178f2); + &jne (&label("16_63")); + + &mov ("esi",&DWP(4*(8+16+64)+0,"esp"));#ctx + # &mov ($A,$Aoff); + &mov ("ebx",$Boff); + &mov ("ecx",$Coff); + &mov ("edi",$Doff); + &add ($A,&DWP(0,"esi")); + &add ("ebx",&DWP(4,"esi")); + &add ("ecx",&DWP(8,"esi")); + &add ("edi",&DWP(12,"esi")); + &mov (&DWP(0,"esi"),$A); + &mov (&DWP(4,"esi"),"ebx"); + &mov (&DWP(8,"esi"),"ecx"); + &mov (&DWP(12,"esi"),"edi"); + # &mov ($E,$Eoff); + &mov ("eax",$Foff); + &mov ("ebx",$Goff); + &mov ("ecx",$Hoff); + &mov ("edi",&DWP(4*(8+16+64)+4,"esp"));#inp + &add ($E,&DWP(16,"esi")); + &add ("eax",&DWP(20,"esi")); + &add ("ebx",&DWP(24,"esi")); + &add ("ecx",&DWP(28,"esi")); + &mov (&DWP(16,"esi"),$E); + &mov (&DWP(20,"esi"),"eax"); + &mov (&DWP(24,"esi"),"ebx"); + &mov (&DWP(28,"esi"),"ecx"); + + &add ("esp",4*(8+16+64)); # destroy frame + &sub ($K256,4*64); # rewind K + + &cmp ("edi",&DWP(8,"esp")); # are we done yet? + &jb (&label("loop")); + + &mov ("esp",&DWP(12,"esp")); # restore sp +&function_end_A(); + +&set_label("K256",64); # Yes! I keep it in the code segment! + &data_word(0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5); + &data_word(0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5); + &data_word(0xd807aa98,0x12835b01,0x243185be,0x550c7dc3); + &data_word(0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174); + &data_word(0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc); + &data_word(0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da); + &data_word(0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7); + &data_word(0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967); + &data_word(0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13); + &data_word(0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85); + &data_word(0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3); + &data_word(0xd192e819,0xd6990624,0xf40e3585,0x106aa070); + &data_word(0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5); + &data_word(0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3); + &data_word(0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208); + &data_word(0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2); +&function_end_B("sha256_block_data_order"); +&asciz("SHA256 block transform for x86, CRYPTOGAMS by "); + +&asm_finish(); diff --git a/libs/openssl/crypto/sha/asm/sha256-armv4.pl b/libs/openssl/crypto/sha/asm/sha256-armv4.pl new file mode 100644 index 00000000..9c84e8d9 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha256-armv4.pl @@ -0,0 +1,211 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# SHA256 block procedure for ARMv4. May 2007. + +# Performance is ~2x better than gcc 3.4 generated code and in "abso- +# lute" terms is ~2250 cycles per 64-byte block or ~35 cycles per +# byte [on single-issue Xscale PXA250 core]. + +# July 2010. +# +# Rescheduling for dual-issue pipeline resulted in 22% improvement on +# Cortex A8 core and ~20 cycles per processed byte. + +# February 2011. +# +# Profiler-assisted and platform-specific optimization resulted in 16% +# improvement on Cortex A8 core and ~17 cycles per processed byte. + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +$ctx="r0"; $t0="r0"; +$inp="r1"; $t3="r1"; +$len="r2"; $t1="r2"; +$T1="r3"; +$A="r4"; +$B="r5"; +$C="r6"; +$D="r7"; +$E="r8"; +$F="r9"; +$G="r10"; +$H="r11"; +@V=($A,$B,$C,$D,$E,$F,$G,$H); +$t2="r12"; +$Ktbl="r14"; + +@Sigma0=( 2,13,22); +@Sigma1=( 6,11,25); +@sigma0=( 7,18, 3); +@sigma1=(17,19,10); + +sub BODY_00_15 { +my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_; + +$code.=<<___ if ($i<16); +#if __ARM_ARCH__>=7 + ldr $T1,[$inp],#4 +#else + ldrb $T1,[$inp,#3] @ $i + ldrb $t2,[$inp,#2] + ldrb $t1,[$inp,#1] + ldrb $t0,[$inp],#4 + orr $T1,$T1,$t2,lsl#8 + orr $T1,$T1,$t1,lsl#16 + orr $T1,$T1,$t0,lsl#24 +#endif +___ +$code.=<<___; + mov $t0,$e,ror#$Sigma1[0] + ldr $t2,[$Ktbl],#4 @ *K256++ + eor $t0,$t0,$e,ror#$Sigma1[1] + eor $t1,$f,$g +#if $i>=16 + add $T1,$T1,$t3 @ from BODY_16_xx +#elif __ARM_ARCH__>=7 && defined(__ARMEL__) + rev $T1,$T1 +#endif +#if $i==15 + str $inp,[sp,#17*4] @ leave room for $t3 +#endif + eor $t0,$t0,$e,ror#$Sigma1[2] @ Sigma1(e) + and $t1,$t1,$e + str $T1,[sp,#`$i%16`*4] + add $T1,$T1,$t0 + eor $t1,$t1,$g @ Ch(e,f,g) + add $T1,$T1,$h + mov $h,$a,ror#$Sigma0[0] + add $T1,$T1,$t1 + eor $h,$h,$a,ror#$Sigma0[1] + add $T1,$T1,$t2 + eor $h,$h,$a,ror#$Sigma0[2] @ Sigma0(a) +#if $i>=15 + ldr $t3,[sp,#`($i+2)%16`*4] @ from BODY_16_xx +#endif + orr $t0,$a,$b + and $t1,$a,$b + and $t0,$t0,$c + add $h,$h,$T1 + orr $t0,$t0,$t1 @ Maj(a,b,c) + add $d,$d,$T1 + add $h,$h,$t0 +___ +} + +sub BODY_16_XX { +my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_; + +$code.=<<___; + @ ldr $t3,[sp,#`($i+1)%16`*4] @ $i + ldr $t2,[sp,#`($i+14)%16`*4] + mov $t0,$t3,ror#$sigma0[0] + ldr $T1,[sp,#`($i+0)%16`*4] + eor $t0,$t0,$t3,ror#$sigma0[1] + ldr $t1,[sp,#`($i+9)%16`*4] + eor $t0,$t0,$t3,lsr#$sigma0[2] @ sigma0(X[i+1]) + mov $t3,$t2,ror#$sigma1[0] + add $T1,$T1,$t0 + eor $t3,$t3,$t2,ror#$sigma1[1] + add $T1,$T1,$t1 + eor $t3,$t3,$t2,lsr#$sigma1[2] @ sigma1(X[i+14]) + @ add $T1,$T1,$t3 +___ + &BODY_00_15(@_); +} + +$code=<<___; +#include "arm_arch.h" + +.text +.code 32 + +.type K256,%object +.align 5 +K256: +.word 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 +.word 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 +.word 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 +.word 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 +.word 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc +.word 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da +.word 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 +.word 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 +.word 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 +.word 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 +.word 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 +.word 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 +.word 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 +.word 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 +.word 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 +.word 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.size K256,.-K256 + +.global sha256_block_data_order +.type sha256_block_data_order,%function +sha256_block_data_order: + sub r3,pc,#8 @ sha256_block_data_order + add $len,$inp,$len,lsl#6 @ len to point at the end of inp + stmdb sp!,{$ctx,$inp,$len,r4-r11,lr} + ldmia $ctx,{$A,$B,$C,$D,$E,$F,$G,$H} + sub $Ktbl,r3,#256 @ K256 + sub sp,sp,#16*4 @ alloca(X[16]) +.Loop: +___ +for($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); } +$code.=".Lrounds_16_xx:\n"; +for (;$i<32;$i++) { &BODY_16_XX($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + and $t2,$t2,#0xff + cmp $t2,#0xf2 + bne .Lrounds_16_xx + + ldr $T1,[sp,#16*4] @ pull ctx + ldr $t0,[$T1,#0] + ldr $t1,[$T1,#4] + ldr $t2,[$T1,#8] + add $A,$A,$t0 + ldr $t0,[$T1,#12] + add $B,$B,$t1 + ldr $t1,[$T1,#16] + add $C,$C,$t2 + ldr $t2,[$T1,#20] + add $D,$D,$t0 + ldr $t0,[$T1,#24] + add $E,$E,$t1 + ldr $t1,[$T1,#28] + add $F,$F,$t2 + ldr $inp,[sp,#17*4] @ pull inp + ldr $t2,[sp,#18*4] @ pull inp+len + add $G,$G,$t0 + add $H,$H,$t1 + stmia $T1,{$A,$B,$C,$D,$E,$F,$G,$H} + cmp $inp,$t2 + sub $Ktbl,$Ktbl,#256 @ rewind Ktbl + bne .Loop + + add sp,sp,#`16+3`*4 @ destroy frame +#if __ARM_ARCH__>=5 + ldmia sp!,{r4-r11,pc} +#else + ldmia sp!,{r4-r11,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif +.size sha256_block_data_order,.-sha256_block_data_order +.asciz "SHA256 block transform for ARMv4, CRYPTOGAMS by " +.align 2 +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 +print $code; +close STDOUT; # enforce flush diff --git a/libs/openssl/crypto/sha/asm/sha512-586.pl b/libs/openssl/crypto/sha/asm/sha512-586.pl new file mode 100644 index 00000000..9f8c51eb --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha512-586.pl @@ -0,0 +1,644 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# SHA512 block transform for x86. September 2007. +# +# Performance in clock cycles per processed byte (less is better): +# +# Pentium PIII P4 AMD K8 Core2 +# gcc 100 75 116 54 66 +# icc 97 77 95 55 57 +# x86 asm 61 56 82 36 40 +# SSE2 asm - - 38 24 20 +# x86_64 asm(*) - - 30 10.0 10.5 +# +# (*) x86_64 assembler performance is presented for reference +# purposes. +# +# IALU code-path is optimized for elder Pentiums. On vanilla Pentium +# performance improvement over compiler generated code reaches ~60%, +# while on PIII - ~35%. On newer µ-archs improvement varies from 15% +# to 50%, but it's less important as they are expected to execute SSE2 +# code-path, which is commonly ~2-3x faster [than compiler generated +# code]. SSE2 code-path is as fast as original sha512-sse2.pl, even +# though it does not use 128-bit operations. The latter means that +# SSE2-aware kernel is no longer required to execute the code. Another +# difference is that new code optimizes amount of writes, but at the +# cost of increased data cache "footprint" by 1/2KB. + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"sha512-586.pl",$ARGV[$#ARGV] eq "386"); + +$sse2=0; +for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } + +&external_label("OPENSSL_ia32cap_P") if ($sse2); + +$Tlo=&DWP(0,"esp"); $Thi=&DWP(4,"esp"); +$Alo=&DWP(8,"esp"); $Ahi=&DWP(8+4,"esp"); +$Blo=&DWP(16,"esp"); $Bhi=&DWP(16+4,"esp"); +$Clo=&DWP(24,"esp"); $Chi=&DWP(24+4,"esp"); +$Dlo=&DWP(32,"esp"); $Dhi=&DWP(32+4,"esp"); +$Elo=&DWP(40,"esp"); $Ehi=&DWP(40+4,"esp"); +$Flo=&DWP(48,"esp"); $Fhi=&DWP(48+4,"esp"); +$Glo=&DWP(56,"esp"); $Ghi=&DWP(56+4,"esp"); +$Hlo=&DWP(64,"esp"); $Hhi=&DWP(64+4,"esp"); +$K512="ebp"; + +$Asse2=&QWP(0,"esp"); +$Bsse2=&QWP(8,"esp"); +$Csse2=&QWP(16,"esp"); +$Dsse2=&QWP(24,"esp"); +$Esse2=&QWP(32,"esp"); +$Fsse2=&QWP(40,"esp"); +$Gsse2=&QWP(48,"esp"); +$Hsse2=&QWP(56,"esp"); + +$A="mm0"; # B-D and +$E="mm4"; # F-H are commonly loaded to respectively mm1-mm3 and + # mm5-mm7, but it's done on on-demand basis... + +sub BODY_00_15_sse2 { + my $prefetch=shift; + + &movq ("mm5",$Fsse2); # load f + &movq ("mm6",$Gsse2); # load g + &movq ("mm7",$Hsse2); # load h + + &movq ("mm1",$E); # %mm1 is sliding right + &movq ("mm2",$E); # %mm2 is sliding left + &psrlq ("mm1",14); + &movq ($Esse2,$E); # modulo-scheduled save e + &psllq ("mm2",23); + &movq ("mm3","mm1"); # %mm3 is T1 + &psrlq ("mm1",4); + &pxor ("mm3","mm2"); + &psllq ("mm2",23); + &pxor ("mm3","mm1"); + &psrlq ("mm1",23); + &pxor ("mm3","mm2"); + &psllq ("mm2",4); + &pxor ("mm3","mm1"); + &paddq ("mm7",QWP(0,$K512)); # h+=K512[i] + &pxor ("mm3","mm2"); # T1=Sigma1_512(e) + + &pxor ("mm5","mm6"); # f^=g + &movq ("mm1",$Bsse2); # load b + &pand ("mm5",$E); # f&=e + &movq ("mm2",$Csse2); # load c + &pxor ("mm5","mm6"); # f^=g + &movq ($E,$Dsse2); # e = load d + &paddq ("mm3","mm5"); # T1+=Ch(e,f,g) + &movq (&QWP(0,"esp"),$A); # modulo-scheduled save a + &paddq ("mm3","mm7"); # T1+=h + + &movq ("mm5",$A); # %mm5 is sliding right + &movq ("mm6",$A); # %mm6 is sliding left + &paddq ("mm3",&QWP(8*9,"esp")); # T1+=X[0] + &psrlq ("mm5",28); + &paddq ($E,"mm3"); # e += T1 + &psllq ("mm6",25); + &movq ("mm7","mm5"); # %mm7 is T2 + &psrlq ("mm5",6); + &pxor ("mm7","mm6"); + &psllq ("mm6",5); + &pxor ("mm7","mm5"); + &psrlq ("mm5",5); + &pxor ("mm7","mm6"); + &psllq ("mm6",6); + &pxor ("mm7","mm5"); + &sub ("esp",8); + &pxor ("mm7","mm6"); # T2=Sigma0_512(a) + + &movq ("mm5",$A); # %mm5=a + &por ($A,"mm2"); # a=a|c + &movq ("mm6",&QWP(8*(9+16-14),"esp")) if ($prefetch); + &pand ("mm5","mm2"); # %mm5=a&c + &pand ($A,"mm1"); # a=(a|c)&b + &movq ("mm2",&QWP(8*(9+16-1),"esp")) if ($prefetch); + &por ("mm5",$A); # %mm5=(a&c)|((a|c)&b) + &paddq ("mm7","mm5"); # T2+=Maj(a,b,c) + &movq ($A,"mm3"); # a=T1 + + &mov (&LB("edx"),&BP(0,$K512)); + &paddq ($A,"mm7"); # a+=T2 + &add ($K512,8); +} + +sub BODY_00_15_x86 { + #define Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) + # LO lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23 + # HI hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23 + &mov ("ecx",$Elo); + &mov ("edx",$Ehi); + &mov ("esi","ecx"); + + &shr ("ecx",9); # lo>>9 + &mov ("edi","edx"); + &shr ("edx",9); # hi>>9 + &mov ("ebx","ecx"); + &shl ("esi",14); # lo<<14 + &mov ("eax","edx"); + &shl ("edi",14); # hi<<14 + &xor ("ebx","esi"); + + &shr ("ecx",14-9); # lo>>14 + &xor ("eax","edi"); + &shr ("edx",14-9); # hi>>14 + &xor ("eax","ecx"); + &shl ("esi",18-14); # lo<<18 + &xor ("ebx","edx"); + &shl ("edi",18-14); # hi<<18 + &xor ("ebx","esi"); + + &shr ("ecx",18-14); # lo>>18 + &xor ("eax","edi"); + &shr ("edx",18-14); # hi>>18 + &xor ("eax","ecx"); + &shl ("esi",23-18); # lo<<23 + &xor ("ebx","edx"); + &shl ("edi",23-18); # hi<<23 + &xor ("eax","esi"); + &xor ("ebx","edi"); # T1 = Sigma1(e) + + &mov ("ecx",$Flo); + &mov ("edx",$Fhi); + &mov ("esi",$Glo); + &mov ("edi",$Ghi); + &add ("eax",$Hlo); + &adc ("ebx",$Hhi); # T1 += h + &xor ("ecx","esi"); + &xor ("edx","edi"); + &and ("ecx",$Elo); + &and ("edx",$Ehi); + &add ("eax",&DWP(8*(9+15)+0,"esp")); + &adc ("ebx",&DWP(8*(9+15)+4,"esp")); # T1 += X[0] + &xor ("ecx","esi"); + &xor ("edx","edi"); # Ch(e,f,g) = (f^g)&e)^g + + &mov ("esi",&DWP(0,$K512)); + &mov ("edi",&DWP(4,$K512)); # K[i] + &add ("eax","ecx"); + &adc ("ebx","edx"); # T1 += Ch(e,f,g) + &mov ("ecx",$Dlo); + &mov ("edx",$Dhi); + &add ("eax","esi"); + &adc ("ebx","edi"); # T1 += K[i] + &mov ($Tlo,"eax"); + &mov ($Thi,"ebx"); # put T1 away + &add ("eax","ecx"); + &adc ("ebx","edx"); # d += T1 + + #define Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) + # LO lo>>28^hi<<4 ^ hi>>2^lo<<30 ^ hi>>7^lo<<25 + # HI hi>>28^lo<<4 ^ lo>>2^hi<<30 ^ lo>>7^hi<<25 + &mov ("ecx",$Alo); + &mov ("edx",$Ahi); + &mov ($Dlo,"eax"); + &mov ($Dhi,"ebx"); + &mov ("esi","ecx"); + + &shr ("ecx",2); # lo>>2 + &mov ("edi","edx"); + &shr ("edx",2); # hi>>2 + &mov ("ebx","ecx"); + &shl ("esi",4); # lo<<4 + &mov ("eax","edx"); + &shl ("edi",4); # hi<<4 + &xor ("ebx","esi"); + + &shr ("ecx",7-2); # lo>>7 + &xor ("eax","edi"); + &shr ("edx",7-2); # hi>>7 + &xor ("ebx","ecx"); + &shl ("esi",25-4); # lo<<25 + &xor ("eax","edx"); + &shl ("edi",25-4); # hi<<25 + &xor ("eax","esi"); + + &shr ("ecx",28-7); # lo>>28 + &xor ("ebx","edi"); + &shr ("edx",28-7); # hi>>28 + &xor ("eax","ecx"); + &shl ("esi",30-25); # lo<<30 + &xor ("ebx","edx"); + &shl ("edi",30-25); # hi<<30 + &xor ("eax","esi"); + &xor ("ebx","edi"); # Sigma0(a) + + &mov ("ecx",$Alo); + &mov ("edx",$Ahi); + &mov ("esi",$Blo); + &mov ("edi",$Bhi); + &add ("eax",$Tlo); + &adc ("ebx",$Thi); # T1 = Sigma0(a)+T1 + &or ("ecx","esi"); + &or ("edx","edi"); + &and ("ecx",$Clo); + &and ("edx",$Chi); + &and ("esi",$Alo); + &and ("edi",$Ahi); + &or ("ecx","esi"); + &or ("edx","edi"); # Maj(a,b,c) = ((a|b)&c)|(a&b) + + &add ("eax","ecx"); + &adc ("ebx","edx"); # T1 += Maj(a,b,c) + &mov ($Tlo,"eax"); + &mov ($Thi,"ebx"); + + &mov (&LB("edx"),&BP(0,$K512)); # pre-fetch LSB of *K + &sub ("esp",8); + &lea ($K512,&DWP(8,$K512)); # K++ +} + + +&function_begin("sha512_block_data_order"); + &mov ("esi",wparam(0)); # ctx + &mov ("edi",wparam(1)); # inp + &mov ("eax",wparam(2)); # num + &mov ("ebx","esp"); # saved sp + + &call (&label("pic_point")); # make it PIC! +&set_label("pic_point"); + &blindpop($K512); + &lea ($K512,&DWP(&label("K512")."-".&label("pic_point"),$K512)); + + &sub ("esp",16); + &and ("esp",-64); + + &shl ("eax",7); + &add ("eax","edi"); + &mov (&DWP(0,"esp"),"esi"); # ctx + &mov (&DWP(4,"esp"),"edi"); # inp + &mov (&DWP(8,"esp"),"eax"); # inp+num*128 + &mov (&DWP(12,"esp"),"ebx"); # saved sp + +if ($sse2) { + &picmeup("edx","OPENSSL_ia32cap_P",$K512,&label("K512")); + &bt (&DWP(0,"edx"),26); + &jnc (&label("loop_x86")); + + # load ctx->h[0-7] + &movq ($A,&QWP(0,"esi")); + &movq ("mm1",&QWP(8,"esi")); + &movq ("mm2",&QWP(16,"esi")); + &movq ("mm3",&QWP(24,"esi")); + &movq ($E,&QWP(32,"esi")); + &movq ("mm5",&QWP(40,"esi")); + &movq ("mm6",&QWP(48,"esi")); + &movq ("mm7",&QWP(56,"esi")); + &sub ("esp",8*10); + +&set_label("loop_sse2",16); + # &movq ($Asse2,$A); + &movq ($Bsse2,"mm1"); + &movq ($Csse2,"mm2"); + &movq ($Dsse2,"mm3"); + # &movq ($Esse2,$E); + &movq ($Fsse2,"mm5"); + &movq ($Gsse2,"mm6"); + &movq ($Hsse2,"mm7"); + + &mov ("ecx",&DWP(0,"edi")); + &mov ("edx",&DWP(4,"edi")); + &add ("edi",8); + &bswap ("ecx"); + &bswap ("edx"); + &mov (&DWP(8*9+4,"esp"),"ecx"); + &mov (&DWP(8*9+0,"esp"),"edx"); + +&set_label("00_14_sse2",16); + &mov ("eax",&DWP(0,"edi")); + &mov ("ebx",&DWP(4,"edi")); + &add ("edi",8); + &bswap ("eax"); + &bswap ("ebx"); + &mov (&DWP(8*8+4,"esp"),"eax"); + &mov (&DWP(8*8+0,"esp"),"ebx"); + + &BODY_00_15_sse2(); + + &cmp (&LB("edx"),0x35); + &jne (&label("00_14_sse2")); + + &BODY_00_15_sse2(1); + +&set_label("16_79_sse2",16); + #&movq ("mm2",&QWP(8*(9+16-1),"esp")); #prefetched in BODY_00_15 + #&movq ("mm6",&QWP(8*(9+16-14),"esp")); + &movq ("mm1","mm2"); + + &psrlq ("mm2",1); + &movq ("mm7","mm6"); + &psrlq ("mm6",6); + &movq ("mm3","mm2"); + + &psrlq ("mm2",7-1); + &movq ("mm5","mm6"); + &psrlq ("mm6",19-6); + &pxor ("mm3","mm2"); + + &psrlq ("mm2",8-7); + &pxor ("mm5","mm6"); + &psrlq ("mm6",61-19); + &pxor ("mm3","mm2"); + + &movq ("mm2",&QWP(8*(9+16),"esp")); + + &psllq ("mm1",56); + &pxor ("mm5","mm6"); + &psllq ("mm7",3); + &pxor ("mm3","mm1"); + + &paddq ("mm2",&QWP(8*(9+16-9),"esp")); + + &psllq ("mm1",63-56); + &pxor ("mm5","mm7"); + &psllq ("mm7",45-3); + &pxor ("mm3","mm1"); + &pxor ("mm5","mm7"); + + &paddq ("mm3","mm5"); + &paddq ("mm3","mm2"); + &movq (&QWP(8*9,"esp"),"mm3"); + + &BODY_00_15_sse2(1); + + &cmp (&LB("edx"),0x17); + &jne (&label("16_79_sse2")); + + # &movq ($A,$Asse2); + &movq ("mm1",$Bsse2); + &movq ("mm2",$Csse2); + &movq ("mm3",$Dsse2); + # &movq ($E,$Esse2); + &movq ("mm5",$Fsse2); + &movq ("mm6",$Gsse2); + &movq ("mm7",$Hsse2); + + &paddq ($A,&QWP(0,"esi")); + &paddq ("mm1",&QWP(8,"esi")); + &paddq ("mm2",&QWP(16,"esi")); + &paddq ("mm3",&QWP(24,"esi")); + &paddq ($E,&QWP(32,"esi")); + &paddq ("mm5",&QWP(40,"esi")); + &paddq ("mm6",&QWP(48,"esi")); + &paddq ("mm7",&QWP(56,"esi")); + + &movq (&QWP(0,"esi"),$A); + &movq (&QWP(8,"esi"),"mm1"); + &movq (&QWP(16,"esi"),"mm2"); + &movq (&QWP(24,"esi"),"mm3"); + &movq (&QWP(32,"esi"),$E); + &movq (&QWP(40,"esi"),"mm5"); + &movq (&QWP(48,"esi"),"mm6"); + &movq (&QWP(56,"esi"),"mm7"); + + &add ("esp",8*80); # destroy frame + &sub ($K512,8*80); # rewind K + + &cmp ("edi",&DWP(8*10+8,"esp")); # are we done yet? + &jb (&label("loop_sse2")); + + &emms (); + &mov ("esp",&DWP(8*10+12,"esp")); # restore sp +&function_end_A(); +} +&set_label("loop_x86",16); + # copy input block to stack reversing byte and qword order + for ($i=0;$i<8;$i++) { + &mov ("eax",&DWP($i*16+0,"edi")); + &mov ("ebx",&DWP($i*16+4,"edi")); + &mov ("ecx",&DWP($i*16+8,"edi")); + &mov ("edx",&DWP($i*16+12,"edi")); + &bswap ("eax"); + &bswap ("ebx"); + &bswap ("ecx"); + &bswap ("edx"); + &push ("eax"); + &push ("ebx"); + &push ("ecx"); + &push ("edx"); + } + &add ("edi",128); + &sub ("esp",9*8); # place for T,A,B,C,D,E,F,G,H + &mov (&DWP(8*(9+16)+4,"esp"),"edi"); + + # copy ctx->h[0-7] to A,B,C,D,E,F,G,H on stack + &lea ("edi",&DWP(8,"esp")); + &mov ("ecx",16); + &data_word(0xA5F3F689); # rep movsd + +&set_label("00_15_x86",16); + &BODY_00_15_x86(); + + &cmp (&LB("edx"),0x94); + &jne (&label("00_15_x86")); + +&set_label("16_79_x86",16); + #define sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) + # LO lo>>1^hi<<31 ^ lo>>8^hi<<24 ^ lo>>7^hi<<25 + # HI hi>>1^lo<<31 ^ hi>>8^lo<<24 ^ hi>>7 + &mov ("ecx",&DWP(8*(9+15+16-1)+0,"esp")); + &mov ("edx",&DWP(8*(9+15+16-1)+4,"esp")); + &mov ("esi","ecx"); + + &shr ("ecx",1); # lo>>1 + &mov ("edi","edx"); + &shr ("edx",1); # hi>>1 + &mov ("eax","ecx"); + &shl ("esi",24); # lo<<24 + &mov ("ebx","edx"); + &shl ("edi",24); # hi<<24 + &xor ("ebx","esi"); + + &shr ("ecx",7-1); # lo>>7 + &xor ("eax","edi"); + &shr ("edx",7-1); # hi>>7 + &xor ("eax","ecx"); + &shl ("esi",31-24); # lo<<31 + &xor ("ebx","edx"); + &shl ("edi",25-24); # hi<<25 + &xor ("ebx","esi"); + + &shr ("ecx",8-7); # lo>>8 + &xor ("eax","edi"); + &shr ("edx",8-7); # hi>>8 + &xor ("eax","ecx"); + &shl ("edi",31-25); # hi<<31 + &xor ("ebx","edx"); + &xor ("eax","edi"); # T1 = sigma0(X[-15]) + + &mov (&DWP(0,"esp"),"eax"); + &mov (&DWP(4,"esp"),"ebx"); # put T1 away + + #define sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) + # LO lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26 + # HI hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6 + &mov ("ecx",&DWP(8*(9+15+16-14)+0,"esp")); + &mov ("edx",&DWP(8*(9+15+16-14)+4,"esp")); + &mov ("esi","ecx"); + + &shr ("ecx",6); # lo>>6 + &mov ("edi","edx"); + &shr ("edx",6); # hi>>6 + &mov ("eax","ecx"); + &shl ("esi",3); # lo<<3 + &mov ("ebx","edx"); + &shl ("edi",3); # hi<<3 + &xor ("eax","esi"); + + &shr ("ecx",19-6); # lo>>19 + &xor ("ebx","edi"); + &shr ("edx",19-6); # hi>>19 + &xor ("eax","ecx"); + &shl ("esi",13-3); # lo<<13 + &xor ("ebx","edx"); + &shl ("edi",13-3); # hi<<13 + &xor ("ebx","esi"); + + &shr ("ecx",29-19); # lo>>29 + &xor ("eax","edi"); + &shr ("edx",29-19); # hi>>29 + &xor ("ebx","ecx"); + &shl ("edi",26-13); # hi<<26 + &xor ("eax","edx"); + &xor ("eax","edi"); # sigma1(X[-2]) + + &mov ("ecx",&DWP(8*(9+15+16)+0,"esp")); + &mov ("edx",&DWP(8*(9+15+16)+4,"esp")); + &add ("eax",&DWP(0,"esp")); + &adc ("ebx",&DWP(4,"esp")); # T1 = sigma1(X[-2])+T1 + &mov ("esi",&DWP(8*(9+15+16-9)+0,"esp")); + &mov ("edi",&DWP(8*(9+15+16-9)+4,"esp")); + &add ("eax","ecx"); + &adc ("ebx","edx"); # T1 += X[-16] + &add ("eax","esi"); + &adc ("ebx","edi"); # T1 += X[-7] + &mov (&DWP(8*(9+15)+0,"esp"),"eax"); + &mov (&DWP(8*(9+15)+4,"esp"),"ebx"); # save X[0] + + &BODY_00_15_x86(); + + &cmp (&LB("edx"),0x17); + &jne (&label("16_79_x86")); + + &mov ("esi",&DWP(8*(9+16+80)+0,"esp"));# ctx + &mov ("edi",&DWP(8*(9+16+80)+4,"esp"));# inp + for($i=0;$i<4;$i++) { + &mov ("eax",&DWP($i*16+0,"esi")); + &mov ("ebx",&DWP($i*16+4,"esi")); + &mov ("ecx",&DWP($i*16+8,"esi")); + &mov ("edx",&DWP($i*16+12,"esi")); + &add ("eax",&DWP(8+($i*16)+0,"esp")); + &adc ("ebx",&DWP(8+($i*16)+4,"esp")); + &mov (&DWP($i*16+0,"esi"),"eax"); + &mov (&DWP($i*16+4,"esi"),"ebx"); + &add ("ecx",&DWP(8+($i*16)+8,"esp")); + &adc ("edx",&DWP(8+($i*16)+12,"esp")); + &mov (&DWP($i*16+8,"esi"),"ecx"); + &mov (&DWP($i*16+12,"esi"),"edx"); + } + &add ("esp",8*(9+16+80)); # destroy frame + &sub ($K512,8*80); # rewind K + + &cmp ("edi",&DWP(8,"esp")); # are we done yet? + &jb (&label("loop_x86")); + + &mov ("esp",&DWP(12,"esp")); # restore sp +&function_end_A(); + +&set_label("K512",64); # Yes! I keep it in the code segment! + &data_word(0xd728ae22,0x428a2f98); # u64 + &data_word(0x23ef65cd,0x71374491); # u64 + &data_word(0xec4d3b2f,0xb5c0fbcf); # u64 + &data_word(0x8189dbbc,0xe9b5dba5); # u64 + &data_word(0xf348b538,0x3956c25b); # u64 + &data_word(0xb605d019,0x59f111f1); # u64 + &data_word(0xaf194f9b,0x923f82a4); # u64 + &data_word(0xda6d8118,0xab1c5ed5); # u64 + &data_word(0xa3030242,0xd807aa98); # u64 + &data_word(0x45706fbe,0x12835b01); # u64 + &data_word(0x4ee4b28c,0x243185be); # u64 + &data_word(0xd5ffb4e2,0x550c7dc3); # u64 + &data_word(0xf27b896f,0x72be5d74); # u64 + &data_word(0x3b1696b1,0x80deb1fe); # u64 + &data_word(0x25c71235,0x9bdc06a7); # u64 + &data_word(0xcf692694,0xc19bf174); # u64 + &data_word(0x9ef14ad2,0xe49b69c1); # u64 + &data_word(0x384f25e3,0xefbe4786); # u64 + &data_word(0x8b8cd5b5,0x0fc19dc6); # u64 + &data_word(0x77ac9c65,0x240ca1cc); # u64 + &data_word(0x592b0275,0x2de92c6f); # u64 + &data_word(0x6ea6e483,0x4a7484aa); # u64 + &data_word(0xbd41fbd4,0x5cb0a9dc); # u64 + &data_word(0x831153b5,0x76f988da); # u64 + &data_word(0xee66dfab,0x983e5152); # u64 + &data_word(0x2db43210,0xa831c66d); # u64 + &data_word(0x98fb213f,0xb00327c8); # u64 + &data_word(0xbeef0ee4,0xbf597fc7); # u64 + &data_word(0x3da88fc2,0xc6e00bf3); # u64 + &data_word(0x930aa725,0xd5a79147); # u64 + &data_word(0xe003826f,0x06ca6351); # u64 + &data_word(0x0a0e6e70,0x14292967); # u64 + &data_word(0x46d22ffc,0x27b70a85); # u64 + &data_word(0x5c26c926,0x2e1b2138); # u64 + &data_word(0x5ac42aed,0x4d2c6dfc); # u64 + &data_word(0x9d95b3df,0x53380d13); # u64 + &data_word(0x8baf63de,0x650a7354); # u64 + &data_word(0x3c77b2a8,0x766a0abb); # u64 + &data_word(0x47edaee6,0x81c2c92e); # u64 + &data_word(0x1482353b,0x92722c85); # u64 + &data_word(0x4cf10364,0xa2bfe8a1); # u64 + &data_word(0xbc423001,0xa81a664b); # u64 + &data_word(0xd0f89791,0xc24b8b70); # u64 + &data_word(0x0654be30,0xc76c51a3); # u64 + &data_word(0xd6ef5218,0xd192e819); # u64 + &data_word(0x5565a910,0xd6990624); # u64 + &data_word(0x5771202a,0xf40e3585); # u64 + &data_word(0x32bbd1b8,0x106aa070); # u64 + &data_word(0xb8d2d0c8,0x19a4c116); # u64 + &data_word(0x5141ab53,0x1e376c08); # u64 + &data_word(0xdf8eeb99,0x2748774c); # u64 + &data_word(0xe19b48a8,0x34b0bcb5); # u64 + &data_word(0xc5c95a63,0x391c0cb3); # u64 + &data_word(0xe3418acb,0x4ed8aa4a); # u64 + &data_word(0x7763e373,0x5b9cca4f); # u64 + &data_word(0xd6b2b8a3,0x682e6ff3); # u64 + &data_word(0x5defb2fc,0x748f82ee); # u64 + &data_word(0x43172f60,0x78a5636f); # u64 + &data_word(0xa1f0ab72,0x84c87814); # u64 + &data_word(0x1a6439ec,0x8cc70208); # u64 + &data_word(0x23631e28,0x90befffa); # u64 + &data_word(0xde82bde9,0xa4506ceb); # u64 + &data_word(0xb2c67915,0xbef9a3f7); # u64 + &data_word(0xe372532b,0xc67178f2); # u64 + &data_word(0xea26619c,0xca273ece); # u64 + &data_word(0x21c0c207,0xd186b8c7); # u64 + &data_word(0xcde0eb1e,0xeada7dd6); # u64 + &data_word(0xee6ed178,0xf57d4f7f); # u64 + &data_word(0x72176fba,0x06f067aa); # u64 + &data_word(0xa2c898a6,0x0a637dc5); # u64 + &data_word(0xbef90dae,0x113f9804); # u64 + &data_word(0x131c471b,0x1b710b35); # u64 + &data_word(0x23047d84,0x28db77f5); # u64 + &data_word(0x40c72493,0x32caab7b); # u64 + &data_word(0x15c9bebc,0x3c9ebe0a); # u64 + &data_word(0x9c100d4c,0x431d67c4); # u64 + &data_word(0xcb3e42b6,0x4cc5d4be); # u64 + &data_word(0xfc657e2a,0x597f299c); # u64 + &data_word(0x3ad6faec,0x5fcb6fab); # u64 + &data_word(0x4a475817,0x6c44198c); # u64 +&function_end_B("sha512_block_data_order"); +&asciz("SHA512 block transform for x86, CRYPTOGAMS by "); + +&asm_finish(); diff --git a/libs/openssl/crypto/sha/asm/sha512-armv4.pl b/libs/openssl/crypto/sha/asm/sha512-armv4.pl new file mode 100644 index 00000000..7faf37b1 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha512-armv4.pl @@ -0,0 +1,582 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# SHA512 block procedure for ARMv4. September 2007. + +# This code is ~4.5 (four and a half) times faster than code generated +# by gcc 3.4 and it spends ~72 clock cycles per byte [on single-issue +# Xscale PXA250 core]. +# +# July 2010. +# +# Rescheduling for dual-issue pipeline resulted in 6% improvement on +# Cortex A8 core and ~40 cycles per processed byte. + +# February 2011. +# +# Profiler-assisted and platform-specific optimization resulted in 7% +# improvement on Coxtex A8 core and ~38 cycles per byte. + +# March 2011. +# +# Add NEON implementation. On Cortex A8 it was measured to process +# one byte in 25.5 cycles or 47% faster than integer-only code. + +# Byte order [in]dependence. ========================================= +# +# Originally caller was expected to maintain specific *dword* order in +# h[0-7], namely with most significant dword at *lower* address, which +# was reflected in below two parameters as 0 and 4. Now caller is +# expected to maintain native byte order for whole 64-bit values. +$hi="HI"; +$lo="LO"; +# ==================================================================== + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +$ctx="r0"; # parameter block +$inp="r1"; +$len="r2"; + +$Tlo="r3"; +$Thi="r4"; +$Alo="r5"; +$Ahi="r6"; +$Elo="r7"; +$Ehi="r8"; +$t0="r9"; +$t1="r10"; +$t2="r11"; +$t3="r12"; +############ r13 is stack pointer +$Ktbl="r14"; +############ r15 is program counter + +$Aoff=8*0; +$Boff=8*1; +$Coff=8*2; +$Doff=8*3; +$Eoff=8*4; +$Foff=8*5; +$Goff=8*6; +$Hoff=8*7; +$Xoff=8*8; + +sub BODY_00_15() { +my $magic = shift; +$code.=<<___; + @ Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) + @ LO lo>>14^hi<<18 ^ lo>>18^hi<<14 ^ hi>>9^lo<<23 + @ HI hi>>14^lo<<18 ^ hi>>18^lo<<14 ^ lo>>9^hi<<23 + mov $t0,$Elo,lsr#14 + str $Tlo,[sp,#$Xoff+0] + mov $t1,$Ehi,lsr#14 + str $Thi,[sp,#$Xoff+4] + eor $t0,$t0,$Ehi,lsl#18 + ldr $t2,[sp,#$Hoff+0] @ h.lo + eor $t1,$t1,$Elo,lsl#18 + ldr $t3,[sp,#$Hoff+4] @ h.hi + eor $t0,$t0,$Elo,lsr#18 + eor $t1,$t1,$Ehi,lsr#18 + eor $t0,$t0,$Ehi,lsl#14 + eor $t1,$t1,$Elo,lsl#14 + eor $t0,$t0,$Ehi,lsr#9 + eor $t1,$t1,$Elo,lsr#9 + eor $t0,$t0,$Elo,lsl#23 + eor $t1,$t1,$Ehi,lsl#23 @ Sigma1(e) + adds $Tlo,$Tlo,$t0 + ldr $t0,[sp,#$Foff+0] @ f.lo + adc $Thi,$Thi,$t1 @ T += Sigma1(e) + ldr $t1,[sp,#$Foff+4] @ f.hi + adds $Tlo,$Tlo,$t2 + ldr $t2,[sp,#$Goff+0] @ g.lo + adc $Thi,$Thi,$t3 @ T += h + ldr $t3,[sp,#$Goff+4] @ g.hi + + eor $t0,$t0,$t2 + str $Elo,[sp,#$Eoff+0] + eor $t1,$t1,$t3 + str $Ehi,[sp,#$Eoff+4] + and $t0,$t0,$Elo + str $Alo,[sp,#$Aoff+0] + and $t1,$t1,$Ehi + str $Ahi,[sp,#$Aoff+4] + eor $t0,$t0,$t2 + ldr $t2,[$Ktbl,#$lo] @ K[i].lo + eor $t1,$t1,$t3 @ Ch(e,f,g) + ldr $t3,[$Ktbl,#$hi] @ K[i].hi + + adds $Tlo,$Tlo,$t0 + ldr $Elo,[sp,#$Doff+0] @ d.lo + adc $Thi,$Thi,$t1 @ T += Ch(e,f,g) + ldr $Ehi,[sp,#$Doff+4] @ d.hi + adds $Tlo,$Tlo,$t2 + and $t0,$t2,#0xff + adc $Thi,$Thi,$t3 @ T += K[i] + adds $Elo,$Elo,$Tlo + ldr $t2,[sp,#$Boff+0] @ b.lo + adc $Ehi,$Ehi,$Thi @ d += T + teq $t0,#$magic + + ldr $t3,[sp,#$Coff+0] @ c.lo + orreq $Ktbl,$Ktbl,#1 + @ Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) + @ LO lo>>28^hi<<4 ^ hi>>2^lo<<30 ^ hi>>7^lo<<25 + @ HI hi>>28^lo<<4 ^ lo>>2^hi<<30 ^ lo>>7^hi<<25 + mov $t0,$Alo,lsr#28 + mov $t1,$Ahi,lsr#28 + eor $t0,$t0,$Ahi,lsl#4 + eor $t1,$t1,$Alo,lsl#4 + eor $t0,$t0,$Ahi,lsr#2 + eor $t1,$t1,$Alo,lsr#2 + eor $t0,$t0,$Alo,lsl#30 + eor $t1,$t1,$Ahi,lsl#30 + eor $t0,$t0,$Ahi,lsr#7 + eor $t1,$t1,$Alo,lsr#7 + eor $t0,$t0,$Alo,lsl#25 + eor $t1,$t1,$Ahi,lsl#25 @ Sigma0(a) + adds $Tlo,$Tlo,$t0 + and $t0,$Alo,$t2 + adc $Thi,$Thi,$t1 @ T += Sigma0(a) + + ldr $t1,[sp,#$Boff+4] @ b.hi + orr $Alo,$Alo,$t2 + ldr $t2,[sp,#$Coff+4] @ c.hi + and $Alo,$Alo,$t3 + and $t3,$Ahi,$t1 + orr $Ahi,$Ahi,$t1 + orr $Alo,$Alo,$t0 @ Maj(a,b,c).lo + and $Ahi,$Ahi,$t2 + adds $Alo,$Alo,$Tlo + orr $Ahi,$Ahi,$t3 @ Maj(a,b,c).hi + sub sp,sp,#8 + adc $Ahi,$Ahi,$Thi @ h += T + tst $Ktbl,#1 + add $Ktbl,$Ktbl,#8 +___ +} +$code=<<___; +#include "arm_arch.h" +#ifdef __ARMEL__ +# define LO 0 +# define HI 4 +# define WORD64(hi0,lo0,hi1,lo1) .word lo0,hi0, lo1,hi1 +#else +# define HI 0 +# define LO 4 +# define WORD64(hi0,lo0,hi1,lo1) .word hi0,lo0, hi1,lo1 +#endif + +.text +.code 32 +.type K512,%object +.align 5 +K512: +WORD64(0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd) +WORD64(0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc) +WORD64(0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019) +WORD64(0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118) +WORD64(0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe) +WORD64(0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2) +WORD64(0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1) +WORD64(0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694) +WORD64(0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3) +WORD64(0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65) +WORD64(0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483) +WORD64(0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5) +WORD64(0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210) +WORD64(0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4) +WORD64(0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725) +WORD64(0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70) +WORD64(0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926) +WORD64(0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df) +WORD64(0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8) +WORD64(0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b) +WORD64(0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001) +WORD64(0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30) +WORD64(0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910) +WORD64(0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8) +WORD64(0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53) +WORD64(0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8) +WORD64(0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb) +WORD64(0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3) +WORD64(0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60) +WORD64(0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec) +WORD64(0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9) +WORD64(0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b) +WORD64(0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207) +WORD64(0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178) +WORD64(0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6) +WORD64(0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b) +WORD64(0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493) +WORD64(0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c) +WORD64(0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a) +WORD64(0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817) +.size K512,.-K512 +.LOPENSSL_armcap: +.word OPENSSL_armcap_P-sha512_block_data_order +.skip 32-4 + +.global sha512_block_data_order +.type sha512_block_data_order,%function +sha512_block_data_order: + sub r3,pc,#8 @ sha512_block_data_order + add $len,$inp,$len,lsl#7 @ len to point at the end of inp +#if __ARM_ARCH__>=7 + ldr r12,.LOPENSSL_armcap + ldr r12,[r3,r12] @ OPENSSL_armcap_P + tst r12,#1 + bne .LNEON +#endif + stmdb sp!,{r4-r12,lr} + sub $Ktbl,r3,#672 @ K512 + sub sp,sp,#9*8 + + ldr $Elo,[$ctx,#$Eoff+$lo] + ldr $Ehi,[$ctx,#$Eoff+$hi] + ldr $t0, [$ctx,#$Goff+$lo] + ldr $t1, [$ctx,#$Goff+$hi] + ldr $t2, [$ctx,#$Hoff+$lo] + ldr $t3, [$ctx,#$Hoff+$hi] +.Loop: + str $t0, [sp,#$Goff+0] + str $t1, [sp,#$Goff+4] + str $t2, [sp,#$Hoff+0] + str $t3, [sp,#$Hoff+4] + ldr $Alo,[$ctx,#$Aoff+$lo] + ldr $Ahi,[$ctx,#$Aoff+$hi] + ldr $Tlo,[$ctx,#$Boff+$lo] + ldr $Thi,[$ctx,#$Boff+$hi] + ldr $t0, [$ctx,#$Coff+$lo] + ldr $t1, [$ctx,#$Coff+$hi] + ldr $t2, [$ctx,#$Doff+$lo] + ldr $t3, [$ctx,#$Doff+$hi] + str $Tlo,[sp,#$Boff+0] + str $Thi,[sp,#$Boff+4] + str $t0, [sp,#$Coff+0] + str $t1, [sp,#$Coff+4] + str $t2, [sp,#$Doff+0] + str $t3, [sp,#$Doff+4] + ldr $Tlo,[$ctx,#$Foff+$lo] + ldr $Thi,[$ctx,#$Foff+$hi] + str $Tlo,[sp,#$Foff+0] + str $Thi,[sp,#$Foff+4] + +.L00_15: +#if __ARM_ARCH__<7 + ldrb $Tlo,[$inp,#7] + ldrb $t0, [$inp,#6] + ldrb $t1, [$inp,#5] + ldrb $t2, [$inp,#4] + ldrb $Thi,[$inp,#3] + ldrb $t3, [$inp,#2] + orr $Tlo,$Tlo,$t0,lsl#8 + ldrb $t0, [$inp,#1] + orr $Tlo,$Tlo,$t1,lsl#16 + ldrb $t1, [$inp],#8 + orr $Tlo,$Tlo,$t2,lsl#24 + orr $Thi,$Thi,$t3,lsl#8 + orr $Thi,$Thi,$t0,lsl#16 + orr $Thi,$Thi,$t1,lsl#24 +#else + ldr $Tlo,[$inp,#4] + ldr $Thi,[$inp],#8 +#ifdef __ARMEL__ + rev $Tlo,$Tlo + rev $Thi,$Thi +#endif +#endif +___ + &BODY_00_15(0x94); +$code.=<<___; + tst $Ktbl,#1 + beq .L00_15 + ldr $t0,[sp,#`$Xoff+8*(16-1)`+0] + ldr $t1,[sp,#`$Xoff+8*(16-1)`+4] + bic $Ktbl,$Ktbl,#1 +.L16_79: + @ sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) + @ LO lo>>1^hi<<31 ^ lo>>8^hi<<24 ^ lo>>7^hi<<25 + @ HI hi>>1^lo<<31 ^ hi>>8^lo<<24 ^ hi>>7 + mov $Tlo,$t0,lsr#1 + ldr $t2,[sp,#`$Xoff+8*(16-14)`+0] + mov $Thi,$t1,lsr#1 + ldr $t3,[sp,#`$Xoff+8*(16-14)`+4] + eor $Tlo,$Tlo,$t1,lsl#31 + eor $Thi,$Thi,$t0,lsl#31 + eor $Tlo,$Tlo,$t0,lsr#8 + eor $Thi,$Thi,$t1,lsr#8 + eor $Tlo,$Tlo,$t1,lsl#24 + eor $Thi,$Thi,$t0,lsl#24 + eor $Tlo,$Tlo,$t0,lsr#7 + eor $Thi,$Thi,$t1,lsr#7 + eor $Tlo,$Tlo,$t1,lsl#25 + + @ sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) + @ LO lo>>19^hi<<13 ^ hi>>29^lo<<3 ^ lo>>6^hi<<26 + @ HI hi>>19^lo<<13 ^ lo>>29^hi<<3 ^ hi>>6 + mov $t0,$t2,lsr#19 + mov $t1,$t3,lsr#19 + eor $t0,$t0,$t3,lsl#13 + eor $t1,$t1,$t2,lsl#13 + eor $t0,$t0,$t3,lsr#29 + eor $t1,$t1,$t2,lsr#29 + eor $t0,$t0,$t2,lsl#3 + eor $t1,$t1,$t3,lsl#3 + eor $t0,$t0,$t2,lsr#6 + eor $t1,$t1,$t3,lsr#6 + ldr $t2,[sp,#`$Xoff+8*(16-9)`+0] + eor $t0,$t0,$t3,lsl#26 + + ldr $t3,[sp,#`$Xoff+8*(16-9)`+4] + adds $Tlo,$Tlo,$t0 + ldr $t0,[sp,#`$Xoff+8*16`+0] + adc $Thi,$Thi,$t1 + + ldr $t1,[sp,#`$Xoff+8*16`+4] + adds $Tlo,$Tlo,$t2 + adc $Thi,$Thi,$t3 + adds $Tlo,$Tlo,$t0 + adc $Thi,$Thi,$t1 +___ + &BODY_00_15(0x17); +$code.=<<___; + ldreq $t0,[sp,#`$Xoff+8*(16-1)`+0] + ldreq $t1,[sp,#`$Xoff+8*(16-1)`+4] + beq .L16_79 + bic $Ktbl,$Ktbl,#1 + + ldr $Tlo,[sp,#$Boff+0] + ldr $Thi,[sp,#$Boff+4] + ldr $t0, [$ctx,#$Aoff+$lo] + ldr $t1, [$ctx,#$Aoff+$hi] + ldr $t2, [$ctx,#$Boff+$lo] + ldr $t3, [$ctx,#$Boff+$hi] + adds $t0,$Alo,$t0 + str $t0, [$ctx,#$Aoff+$lo] + adc $t1,$Ahi,$t1 + str $t1, [$ctx,#$Aoff+$hi] + adds $t2,$Tlo,$t2 + str $t2, [$ctx,#$Boff+$lo] + adc $t3,$Thi,$t3 + str $t3, [$ctx,#$Boff+$hi] + + ldr $Alo,[sp,#$Coff+0] + ldr $Ahi,[sp,#$Coff+4] + ldr $Tlo,[sp,#$Doff+0] + ldr $Thi,[sp,#$Doff+4] + ldr $t0, [$ctx,#$Coff+$lo] + ldr $t1, [$ctx,#$Coff+$hi] + ldr $t2, [$ctx,#$Doff+$lo] + ldr $t3, [$ctx,#$Doff+$hi] + adds $t0,$Alo,$t0 + str $t0, [$ctx,#$Coff+$lo] + adc $t1,$Ahi,$t1 + str $t1, [$ctx,#$Coff+$hi] + adds $t2,$Tlo,$t2 + str $t2, [$ctx,#$Doff+$lo] + adc $t3,$Thi,$t3 + str $t3, [$ctx,#$Doff+$hi] + + ldr $Tlo,[sp,#$Foff+0] + ldr $Thi,[sp,#$Foff+4] + ldr $t0, [$ctx,#$Eoff+$lo] + ldr $t1, [$ctx,#$Eoff+$hi] + ldr $t2, [$ctx,#$Foff+$lo] + ldr $t3, [$ctx,#$Foff+$hi] + adds $Elo,$Elo,$t0 + str $Elo,[$ctx,#$Eoff+$lo] + adc $Ehi,$Ehi,$t1 + str $Ehi,[$ctx,#$Eoff+$hi] + adds $t2,$Tlo,$t2 + str $t2, [$ctx,#$Foff+$lo] + adc $t3,$Thi,$t3 + str $t3, [$ctx,#$Foff+$hi] + + ldr $Alo,[sp,#$Goff+0] + ldr $Ahi,[sp,#$Goff+4] + ldr $Tlo,[sp,#$Hoff+0] + ldr $Thi,[sp,#$Hoff+4] + ldr $t0, [$ctx,#$Goff+$lo] + ldr $t1, [$ctx,#$Goff+$hi] + ldr $t2, [$ctx,#$Hoff+$lo] + ldr $t3, [$ctx,#$Hoff+$hi] + adds $t0,$Alo,$t0 + str $t0, [$ctx,#$Goff+$lo] + adc $t1,$Ahi,$t1 + str $t1, [$ctx,#$Goff+$hi] + adds $t2,$Tlo,$t2 + str $t2, [$ctx,#$Hoff+$lo] + adc $t3,$Thi,$t3 + str $t3, [$ctx,#$Hoff+$hi] + + add sp,sp,#640 + sub $Ktbl,$Ktbl,#640 + + teq $inp,$len + bne .Loop + + add sp,sp,#8*9 @ destroy frame +#if __ARM_ARCH__>=5 + ldmia sp!,{r4-r12,pc} +#else + ldmia sp!,{r4-r12,lr} + tst lr,#1 + moveq pc,lr @ be binary compatible with V4, yet + bx lr @ interoperable with Thumb ISA:-) +#endif +___ + +{ +my @Sigma0=(28,34,39); +my @Sigma1=(14,18,41); +my @sigma0=(1, 8, 7); +my @sigma1=(19,61,6); + +my $Ktbl="r3"; +my $cnt="r12"; # volatile register known as ip, intra-procedure-call scratch + +my @X=map("d$_",(0..15)); +my @V=($A,$B,$C,$D,$E,$F,$G,$H)=map("d$_",(16..23)); + +sub NEON_00_15() { +my $i=shift; +my ($a,$b,$c,$d,$e,$f,$g,$h)=@_; +my ($t0,$t1,$t2,$T1,$K,$Ch,$Maj)=map("d$_",(24..31)); # temps + +$code.=<<___ if ($i<16 || $i&1); + vshr.u64 $t0,$e,#@Sigma1[0] @ $i +#if $i<16 + vld1.64 {@X[$i%16]},[$inp]! @ handles unaligned +#endif + vshr.u64 $t1,$e,#@Sigma1[1] + vshr.u64 $t2,$e,#@Sigma1[2] +___ +$code.=<<___; + vld1.64 {$K},[$Ktbl,:64]! @ K[i++] + vsli.64 $t0,$e,#`64-@Sigma1[0]` + vsli.64 $t1,$e,#`64-@Sigma1[1]` + vsli.64 $t2,$e,#`64-@Sigma1[2]` +#if $i<16 && defined(__ARMEL__) + vrev64.8 @X[$i],@X[$i] +#endif + vadd.i64 $T1,$K,$h + veor $Ch,$f,$g + veor $t0,$t1 + vand $Ch,$e + veor $t0,$t2 @ Sigma1(e) + veor $Ch,$g @ Ch(e,f,g) + vadd.i64 $T1,$t0 + vshr.u64 $t0,$a,#@Sigma0[0] + vadd.i64 $T1,$Ch + vshr.u64 $t1,$a,#@Sigma0[1] + vshr.u64 $t2,$a,#@Sigma0[2] + vsli.64 $t0,$a,#`64-@Sigma0[0]` + vsli.64 $t1,$a,#`64-@Sigma0[1]` + vsli.64 $t2,$a,#`64-@Sigma0[2]` + vadd.i64 $T1,@X[$i%16] + vorr $Maj,$a,$c + vand $Ch,$a,$c + veor $h,$t0,$t1 + vand $Maj,$b + veor $h,$t2 @ Sigma0(a) + vorr $Maj,$Ch @ Maj(a,b,c) + vadd.i64 $h,$T1 + vadd.i64 $d,$T1 + vadd.i64 $h,$Maj +___ +} + +sub NEON_16_79() { +my $i=shift; + +if ($i&1) { &NEON_00_15($i,@_); return; } + +# 2x-vectorized, therefore runs every 2nd round +my @X=map("q$_",(0..7)); # view @X as 128-bit vector +my ($t0,$t1,$s0,$s1) = map("q$_",(12..15)); # temps +my ($d0,$d1,$d2) = map("d$_",(24..26)); # temps from NEON_00_15 +my $e=@_[4]; # $e from NEON_00_15 +$i /= 2; +$code.=<<___; + vshr.u64 $t0,@X[($i+7)%8],#@sigma1[0] + vshr.u64 $t1,@X[($i+7)%8],#@sigma1[1] + vshr.u64 $s1,@X[($i+7)%8],#@sigma1[2] + vsli.64 $t0,@X[($i+7)%8],#`64-@sigma1[0]` + vext.8 $s0,@X[$i%8],@X[($i+1)%8],#8 @ X[i+1] + vsli.64 $t1,@X[($i+7)%8],#`64-@sigma1[1]` + veor $s1,$t0 + vshr.u64 $t0,$s0,#@sigma0[0] + veor $s1,$t1 @ sigma1(X[i+14]) + vshr.u64 $t1,$s0,#@sigma0[1] + vadd.i64 @X[$i%8],$s1 + vshr.u64 $s1,$s0,#@sigma0[2] + vsli.64 $t0,$s0,#`64-@sigma0[0]` + vsli.64 $t1,$s0,#`64-@sigma0[1]` + vext.8 $s0,@X[($i+4)%8],@X[($i+5)%8],#8 @ X[i+9] + veor $s1,$t0 + vshr.u64 $d0,$e,#@Sigma1[0] @ from NEON_00_15 + vadd.i64 @X[$i%8],$s0 + vshr.u64 $d1,$e,#@Sigma1[1] @ from NEON_00_15 + veor $s1,$t1 @ sigma0(X[i+1]) + vshr.u64 $d2,$e,#@Sigma1[2] @ from NEON_00_15 + vadd.i64 @X[$i%8],$s1 +___ + &NEON_00_15(2*$i,@_); +} + +$code.=<<___; +#if __ARM_ARCH__>=7 +.fpu neon + +.align 4 +.LNEON: + dmb @ errata #451034 on early Cortex A8 + vstmdb sp!,{d8-d15} @ ABI specification says so + sub $Ktbl,r3,#672 @ K512 + vldmia $ctx,{$A-$H} @ load context +.Loop_neon: +___ +for($i=0;$i<16;$i++) { &NEON_00_15($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + mov $cnt,#4 +.L16_79_neon: + subs $cnt,#1 +___ +for(;$i<32;$i++) { &NEON_16_79($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + bne .L16_79_neon + + vldmia $ctx,{d24-d31} @ load context to temp + vadd.i64 q8,q12 @ vectorized accumulate + vadd.i64 q9,q13 + vadd.i64 q10,q14 + vadd.i64 q11,q15 + vstmia $ctx,{$A-$H} @ save context + teq $inp,$len + sub $Ktbl,#640 @ rewind K512 + bne .Loop_neon + + vldmia sp!,{d8-d15} @ epilogue + bx lr +#endif +___ +} +$code.=<<___; +.size sha512_block_data_order,.-sha512_block_data_order +.asciz "SHA512 block transform for ARMv4/NEON, CRYPTOGAMS by " +.align 2 +.comm OPENSSL_armcap_P,4,4 +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +$code =~ s/\bbx\s+lr\b/.word\t0xe12fff1e/gm; # make it possible to compile with -march=armv4 +print $code; +close STDOUT; # enforce flush diff --git a/libs/openssl/crypto/sha/asm/sha512-ia64.pl b/libs/openssl/crypto/sha/asm/sha512-ia64.pl new file mode 100755 index 00000000..1c6ce565 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha512-ia64.pl @@ -0,0 +1,672 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== +# +# SHA256/512_Transform for Itanium. +# +# sha512_block runs in 1003 cycles on Itanium 2, which is almost 50% +# faster than gcc and >60%(!) faster than code generated by HP-UX +# compiler (yes, HP-UX is generating slower code, because unlike gcc, +# it failed to deploy "shift right pair," 'shrp' instruction, which +# substitutes for 64-bit rotate). +# +# 924 cycles long sha256_block outperforms gcc by over factor of 2(!) +# and HP-UX compiler - by >40% (yes, gcc won sha512_block, but lost +# this one big time). Note that "formally" 924 is about 100 cycles +# too much. I mean it's 64 32-bit rounds vs. 80 virtually identical +# 64-bit ones and 1003*64/80 gives 802. Extra cycles, 2 per round, +# are spent on extra work to provide for 32-bit rotations. 32-bit +# rotations are still handled by 'shrp' instruction and for this +# reason lower 32 bits are deposited to upper half of 64-bit register +# prior 'shrp' issue. And in order to minimize the amount of such +# operations, X[16] values are *maintained* with copies of lower +# halves in upper halves, which is why you'll spot such instructions +# as custom 'mux2', "parallel 32-bit add," 'padd4' and "parallel +# 32-bit unsigned right shift," 'pshr4.u' instructions here. +# +# Rules of engagement. +# +# There is only one integer shifter meaning that if I have two rotate, +# deposit or extract instructions in adjacent bundles, they shall +# split [at run-time if they have to]. But note that variable and +# parallel shifts are performed by multi-media ALU and *are* pairable +# with rotates [and alike]. On the backside MMALU is rather slow: it +# takes 2 extra cycles before the result of integer operation is +# available *to* MMALU and 2(*) extra cycles before the result of MM +# operation is available "back" *to* integer ALU, not to mention that +# MMALU itself has 2 cycles latency. However! I explicitly scheduled +# these MM instructions to avoid MM stalls, so that all these extra +# latencies get "hidden" in instruction-level parallelism. +# +# (*) 2 cycles on Itanium 1 and 1 cycle on Itanium 2. But I schedule +# for 2 in order to provide for best *overall* performance, +# because on Itanium 1 stall on MM result is accompanied by +# pipeline flush, which takes 6 cycles:-( +# +# Resulting performance numbers for 900MHz Itanium 2 system: +# +# The 'numbers' are in 1000s of bytes per second processed. +# type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes +# sha1(*) 6210.14k 20376.30k 52447.83k 85870.05k 105478.12k +# sha256 7476.45k 20572.05k 41538.34k 56062.29k 62093.18k +# sha512 4996.56k 20026.28k 47597.20k 85278.79k 111501.31k +# +# (*) SHA1 numbers are for HP-UX compiler and are presented purely +# for reference purposes. I bet it can improved too... +# +# To generate code, pass the file name with either 256 or 512 in its +# name and compiler flags. + +$output=shift; + +if ($output =~ /512.*\.[s|asm]/) { + $SZ=8; + $BITS=8*$SZ; + $LDW="ld8"; + $STW="st8"; + $ADD="add"; + $SHRU="shr.u"; + $TABLE="K512"; + $func="sha512_block_data_order"; + @Sigma0=(28,34,39); + @Sigma1=(14,18,41); + @sigma0=(1, 8, 7); + @sigma1=(19,61, 6); + $rounds=80; +} elsif ($output =~ /256.*\.[s|asm]/) { + $SZ=4; + $BITS=8*$SZ; + $LDW="ld4"; + $STW="st4"; + $ADD="padd4"; + $SHRU="pshr4.u"; + $TABLE="K256"; + $func="sha256_block_data_order"; + @Sigma0=( 2,13,22); + @Sigma1=( 6,11,25); + @sigma0=( 7,18, 3); + @sigma1=(17,19,10); + $rounds=64; +} else { die "nonsense $output"; } + +open STDOUT,">$output" || die "can't open $output: $!"; + +if ($^O eq "hpux") { + $ADDP="addp4"; + for (@ARGV) { $ADDP="add" if (/[\+DD|\-mlp]64/); } +} else { $ADDP="add"; } +for (@ARGV) { $big_endian=1 if (/\-DB_ENDIAN/); + $big_endian=0 if (/\-DL_ENDIAN/); } +if (!defined($big_endian)) + { $big_endian=(unpack('L',pack('N',1))==1); } + +$code=<<___; +.ident \"$output, version 1.1\" +.ident \"IA-64 ISA artwork by Andy Polyakov \" +.explicit +.text + +pfssave=r2; +lcsave=r3; +prsave=r14; +K=r15; +A=r16; B=r17; C=r18; D=r19; +E=r20; F=r21; G=r22; H=r23; +T1=r24; T2=r25; +s0=r26; s1=r27; t0=r28; t1=r29; +Ktbl=r30; +ctx=r31; // 1st arg +input=r48; // 2nd arg +num=r49; // 3rd arg +sgm0=r50; sgm1=r51; // small constants +A_=r54; B_=r55; C_=r56; D_=r57; +E_=r58; F_=r59; G_=r60; H_=r61; + +// void $func (SHA_CTX *ctx, const void *in,size_t num[,int host]) +.global $func# +.proc $func# +.align 32 +$func: + .prologue + .save ar.pfs,pfssave +{ .mmi; alloc pfssave=ar.pfs,3,27,0,16 + $ADDP ctx=0,r32 // 1st arg + .save ar.lc,lcsave + mov lcsave=ar.lc } +{ .mmi; $ADDP input=0,r33 // 2nd arg + mov num=r34 // 3rd arg + .save pr,prsave + mov prsave=pr };; + + .body +{ .mib; add r8=0*$SZ,ctx + add r9=1*$SZ,ctx + brp.loop.imp .L_first16,.L_first16_end-16 } +{ .mib; add r10=2*$SZ,ctx + add r11=3*$SZ,ctx + brp.loop.imp .L_rest,.L_rest_end-16 };; + +// load A-H +.Lpic_point: +{ .mmi; $LDW A_=[r8],4*$SZ + $LDW B_=[r9],4*$SZ + mov Ktbl=ip } +{ .mmi; $LDW C_=[r10],4*$SZ + $LDW D_=[r11],4*$SZ + mov sgm0=$sigma0[2] };; +{ .mmi; $LDW E_=[r8] + $LDW F_=[r9] + add Ktbl=($TABLE#-.Lpic_point),Ktbl } +{ .mmi; $LDW G_=[r10] + $LDW H_=[r11] + cmp.ne p0,p16=0,r0 };; // used in sha256_block +___ +$code.=<<___ if ($BITS==64); +{ .mii; and r8=7,input + and input=~7,input;; + cmp.eq p9,p0=1,r8 } +{ .mmi; cmp.eq p10,p0=2,r8 + cmp.eq p11,p0=3,r8 + cmp.eq p12,p0=4,r8 } +{ .mmi; cmp.eq p13,p0=5,r8 + cmp.eq p14,p0=6,r8 + cmp.eq p15,p0=7,r8 };; +___ +$code.=<<___; +.L_outer: +.rotr X[16] +{ .mmi; mov A=A_ + mov B=B_ + mov ar.lc=14 } +{ .mmi; mov C=C_ + mov D=D_ + mov E=E_ } +{ .mmi; mov F=F_ + mov G=G_ + mov ar.ec=2 } +{ .mmi; ld1 X[15]=[input],$SZ // eliminated in 64-bit + mov H=H_ + mov sgm1=$sigma1[2] };; + +___ +$t0="t0", $t1="t1", $code.=<<___ if ($BITS==32); +.align 32 +.L_first16: +{ .mmi; add r9=1-$SZ,input + add r10=2-$SZ,input + add r11=3-$SZ,input };; +{ .mmi; ld1 r9=[r9] + ld1 r10=[r10] + dep.z $t1=E,32,32 } +{ .mmi; $LDW K=[Ktbl],$SZ + ld1 r11=[r11] + zxt4 E=E };; +{ .mii; or $t1=$t1,E + dep X[15]=X[15],r9,8,8 + dep r11=r10,r11,8,8 };; +{ .mmi; and T1=F,E + and T2=A,B + dep X[15]=X[15],r11,16,16 } +{ .mmi; andcm r8=G,E + and r9=A,C + mux2 $t0=A,0x44 };; // copy lower half to upper +{ .mmi; (p16) ld1 X[15-1]=[input],$SZ // prefetch + xor T1=T1,r8 // T1=((e & f) ^ (~e & g)) + _rotr r11=$t1,$Sigma1[0] } // ROTR(e,14) +{ .mib; and r10=B,C + xor T2=T2,r9 };; +___ +$t0="A", $t1="E", $code.=<<___ if ($BITS==64); +// in 64-bit mode I load whole X[16] at once and take care of alignment... +{ .mmi; add r8=1*$SZ,input + add r9=2*$SZ,input + add r10=3*$SZ,input };; +{ .mmb; $LDW X[15]=[input],4*$SZ + $LDW X[14]=[r8],4*$SZ +(p9) br.cond.dpnt.many .L1byte };; +{ .mmb; $LDW X[13]=[r9],4*$SZ + $LDW X[12]=[r10],4*$SZ +(p10) br.cond.dpnt.many .L2byte };; +{ .mmb; $LDW X[11]=[input],4*$SZ + $LDW X[10]=[r8],4*$SZ +(p11) br.cond.dpnt.many .L3byte };; +{ .mmb; $LDW X[ 9]=[r9],4*$SZ + $LDW X[ 8]=[r10],4*$SZ +(p12) br.cond.dpnt.many .L4byte };; +{ .mmb; $LDW X[ 7]=[input],4*$SZ + $LDW X[ 6]=[r8],4*$SZ +(p13) br.cond.dpnt.many .L5byte };; +{ .mmb; $LDW X[ 5]=[r9],4*$SZ + $LDW X[ 4]=[r10],4*$SZ +(p14) br.cond.dpnt.many .L6byte };; +{ .mmb; $LDW X[ 3]=[input],4*$SZ + $LDW X[ 2]=[r8],4*$SZ +(p15) br.cond.dpnt.many .L7byte };; +{ .mmb; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + br.many .L_first16 };; +.L1byte: +{ .mmi; $LDW X[13]=[r9],4*$SZ + $LDW X[12]=[r10],4*$SZ + shrp X[15]=X[15],X[14],56 };; +{ .mmi; $LDW X[11]=[input],4*$SZ + $LDW X[10]=[r8],4*$SZ + shrp X[14]=X[14],X[13],56 } +{ .mmi; $LDW X[ 9]=[r9],4*$SZ + $LDW X[ 8]=[r10],4*$SZ + shrp X[13]=X[13],X[12],56 };; +{ .mmi; $LDW X[ 7]=[input],4*$SZ + $LDW X[ 6]=[r8],4*$SZ + shrp X[12]=X[12],X[11],56 } +{ .mmi; $LDW X[ 5]=[r9],4*$SZ + $LDW X[ 4]=[r10],4*$SZ + shrp X[11]=X[11],X[10],56 };; +{ .mmi; $LDW X[ 3]=[input],4*$SZ + $LDW X[ 2]=[r8],4*$SZ + shrp X[10]=X[10],X[ 9],56 } +{ .mmi; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + shrp X[ 9]=X[ 9],X[ 8],56 };; +{ .mii; $LDW T1=[input] + shrp X[ 8]=X[ 8],X[ 7],56 + shrp X[ 7]=X[ 7],X[ 6],56 } +{ .mii; shrp X[ 6]=X[ 6],X[ 5],56 + shrp X[ 5]=X[ 5],X[ 4],56 };; +{ .mii; shrp X[ 4]=X[ 4],X[ 3],56 + shrp X[ 3]=X[ 3],X[ 2],56 } +{ .mii; shrp X[ 2]=X[ 2],X[ 1],56 + shrp X[ 1]=X[ 1],X[ 0],56 } +{ .mib; shrp X[ 0]=X[ 0],T1,56 + br.many .L_first16 };; +.L2byte: +{ .mmi; $LDW X[11]=[input],4*$SZ + $LDW X[10]=[r8],4*$SZ + shrp X[15]=X[15],X[14],48 } +{ .mmi; $LDW X[ 9]=[r9],4*$SZ + $LDW X[ 8]=[r10],4*$SZ + shrp X[14]=X[14],X[13],48 };; +{ .mmi; $LDW X[ 7]=[input],4*$SZ + $LDW X[ 6]=[r8],4*$SZ + shrp X[13]=X[13],X[12],48 } +{ .mmi; $LDW X[ 5]=[r9],4*$SZ + $LDW X[ 4]=[r10],4*$SZ + shrp X[12]=X[12],X[11],48 };; +{ .mmi; $LDW X[ 3]=[input],4*$SZ + $LDW X[ 2]=[r8],4*$SZ + shrp X[11]=X[11],X[10],48 } +{ .mmi; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + shrp X[10]=X[10],X[ 9],48 };; +{ .mii; $LDW T1=[input] + shrp X[ 9]=X[ 9],X[ 8],48 + shrp X[ 8]=X[ 8],X[ 7],48 } +{ .mii; shrp X[ 7]=X[ 7],X[ 6],48 + shrp X[ 6]=X[ 6],X[ 5],48 };; +{ .mii; shrp X[ 5]=X[ 5],X[ 4],48 + shrp X[ 4]=X[ 4],X[ 3],48 } +{ .mii; shrp X[ 3]=X[ 3],X[ 2],48 + shrp X[ 2]=X[ 2],X[ 1],48 } +{ .mii; shrp X[ 1]=X[ 1],X[ 0],48 + shrp X[ 0]=X[ 0],T1,48 } +{ .mfb; br.many .L_first16 };; +.L3byte: +{ .mmi; $LDW X[ 9]=[r9],4*$SZ + $LDW X[ 8]=[r10],4*$SZ + shrp X[15]=X[15],X[14],40 };; +{ .mmi; $LDW X[ 7]=[input],4*$SZ + $LDW X[ 6]=[r8],4*$SZ + shrp X[14]=X[14],X[13],40 } +{ .mmi; $LDW X[ 5]=[r9],4*$SZ + $LDW X[ 4]=[r10],4*$SZ + shrp X[13]=X[13],X[12],40 };; +{ .mmi; $LDW X[ 3]=[input],4*$SZ + $LDW X[ 2]=[r8],4*$SZ + shrp X[12]=X[12],X[11],40 } +{ .mmi; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + shrp X[11]=X[11],X[10],40 };; +{ .mii; $LDW T1=[input] + shrp X[10]=X[10],X[ 9],40 + shrp X[ 9]=X[ 9],X[ 8],40 } +{ .mii; shrp X[ 8]=X[ 8],X[ 7],40 + shrp X[ 7]=X[ 7],X[ 6],40 };; +{ .mii; shrp X[ 6]=X[ 6],X[ 5],40 + shrp X[ 5]=X[ 5],X[ 4],40 } +{ .mii; shrp X[ 4]=X[ 4],X[ 3],40 + shrp X[ 3]=X[ 3],X[ 2],40 } +{ .mii; shrp X[ 2]=X[ 2],X[ 1],40 + shrp X[ 1]=X[ 1],X[ 0],40 } +{ .mib; shrp X[ 0]=X[ 0],T1,40 + br.many .L_first16 };; +.L4byte: +{ .mmi; $LDW X[ 7]=[input],4*$SZ + $LDW X[ 6]=[r8],4*$SZ + shrp X[15]=X[15],X[14],32 } +{ .mmi; $LDW X[ 5]=[r9],4*$SZ + $LDW X[ 4]=[r10],4*$SZ + shrp X[14]=X[14],X[13],32 };; +{ .mmi; $LDW X[ 3]=[input],4*$SZ + $LDW X[ 2]=[r8],4*$SZ + shrp X[13]=X[13],X[12],32 } +{ .mmi; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + shrp X[12]=X[12],X[11],32 };; +{ .mii; $LDW T1=[input] + shrp X[11]=X[11],X[10],32 + shrp X[10]=X[10],X[ 9],32 } +{ .mii; shrp X[ 9]=X[ 9],X[ 8],32 + shrp X[ 8]=X[ 8],X[ 7],32 };; +{ .mii; shrp X[ 7]=X[ 7],X[ 6],32 + shrp X[ 6]=X[ 6],X[ 5],32 } +{ .mii; shrp X[ 5]=X[ 5],X[ 4],32 + shrp X[ 4]=X[ 4],X[ 3],32 } +{ .mii; shrp X[ 3]=X[ 3],X[ 2],32 + shrp X[ 2]=X[ 2],X[ 1],32 } +{ .mii; shrp X[ 1]=X[ 1],X[ 0],32 + shrp X[ 0]=X[ 0],T1,32 } +{ .mfb; br.many .L_first16 };; +.L5byte: +{ .mmi; $LDW X[ 5]=[r9],4*$SZ + $LDW X[ 4]=[r10],4*$SZ + shrp X[15]=X[15],X[14],24 };; +{ .mmi; $LDW X[ 3]=[input],4*$SZ + $LDW X[ 2]=[r8],4*$SZ + shrp X[14]=X[14],X[13],24 } +{ .mmi; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + shrp X[13]=X[13],X[12],24 };; +{ .mii; $LDW T1=[input] + shrp X[12]=X[12],X[11],24 + shrp X[11]=X[11],X[10],24 } +{ .mii; shrp X[10]=X[10],X[ 9],24 + shrp X[ 9]=X[ 9],X[ 8],24 };; +{ .mii; shrp X[ 8]=X[ 8],X[ 7],24 + shrp X[ 7]=X[ 7],X[ 6],24 } +{ .mii; shrp X[ 6]=X[ 6],X[ 5],24 + shrp X[ 5]=X[ 5],X[ 4],24 } +{ .mii; shrp X[ 4]=X[ 4],X[ 3],24 + shrp X[ 3]=X[ 3],X[ 2],24 } +{ .mii; shrp X[ 2]=X[ 2],X[ 1],24 + shrp X[ 1]=X[ 1],X[ 0],24 } +{ .mib; shrp X[ 0]=X[ 0],T1,24 + br.many .L_first16 };; +.L6byte: +{ .mmi; $LDW X[ 3]=[input],4*$SZ + $LDW X[ 2]=[r8],4*$SZ + shrp X[15]=X[15],X[14],16 } +{ .mmi; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + shrp X[14]=X[14],X[13],16 };; +{ .mii; $LDW T1=[input] + shrp X[13]=X[13],X[12],16 + shrp X[12]=X[12],X[11],16 } +{ .mii; shrp X[11]=X[11],X[10],16 + shrp X[10]=X[10],X[ 9],16 };; +{ .mii; shrp X[ 9]=X[ 9],X[ 8],16 + shrp X[ 8]=X[ 8],X[ 7],16 } +{ .mii; shrp X[ 7]=X[ 7],X[ 6],16 + shrp X[ 6]=X[ 6],X[ 5],16 } +{ .mii; shrp X[ 5]=X[ 5],X[ 4],16 + shrp X[ 4]=X[ 4],X[ 3],16 } +{ .mii; shrp X[ 3]=X[ 3],X[ 2],16 + shrp X[ 2]=X[ 2],X[ 1],16 } +{ .mii; shrp X[ 1]=X[ 1],X[ 0],16 + shrp X[ 0]=X[ 0],T1,16 } +{ .mfb; br.many .L_first16 };; +.L7byte: +{ .mmi; $LDW X[ 1]=[r9],4*$SZ + $LDW X[ 0]=[r10],4*$SZ + shrp X[15]=X[15],X[14],8 };; +{ .mii; $LDW T1=[input] + shrp X[14]=X[14],X[13],8 + shrp X[13]=X[13],X[12],8 } +{ .mii; shrp X[12]=X[12],X[11],8 + shrp X[11]=X[11],X[10],8 };; +{ .mii; shrp X[10]=X[10],X[ 9],8 + shrp X[ 9]=X[ 9],X[ 8],8 } +{ .mii; shrp X[ 8]=X[ 8],X[ 7],8 + shrp X[ 7]=X[ 7],X[ 6],8 } +{ .mii; shrp X[ 6]=X[ 6],X[ 5],8 + shrp X[ 5]=X[ 5],X[ 4],8 } +{ .mii; shrp X[ 4]=X[ 4],X[ 3],8 + shrp X[ 3]=X[ 3],X[ 2],8 } +{ .mii; shrp X[ 2]=X[ 2],X[ 1],8 + shrp X[ 1]=X[ 1],X[ 0],8 } +{ .mib; shrp X[ 0]=X[ 0],T1,8 + br.many .L_first16 };; + +.align 32 +.L_first16: +{ .mmi; $LDW K=[Ktbl],$SZ + and T1=F,E + and T2=A,B } +{ .mmi; //$LDW X[15]=[input],$SZ // X[i]=*input++ + andcm r8=G,E + and r9=A,C };; +{ .mmi; xor T1=T1,r8 //T1=((e & f) ^ (~e & g)) + and r10=B,C + _rotr r11=$t1,$Sigma1[0] } // ROTR(e,14) +{ .mmi; xor T2=T2,r9 + mux1 X[15]=X[15],\@rev };; // eliminated in big-endian +___ +$code.=<<___; +{ .mib; add T1=T1,H // T1=Ch(e,f,g)+h + _rotr r8=$t1,$Sigma1[1] } // ROTR(e,18) +{ .mib; xor T2=T2,r10 // T2=((a & b) ^ (a & c) ^ (b & c)) + mov H=G };; +{ .mib; xor r11=r8,r11 + _rotr r9=$t1,$Sigma1[2] } // ROTR(e,41) +{ .mib; mov G=F + mov F=E };; +{ .mib; xor r9=r9,r11 // r9=Sigma1(e) + _rotr r10=$t0,$Sigma0[0] } // ROTR(a,28) +{ .mib; add T1=T1,K // T1=Ch(e,f,g)+h+K512[i] + mov E=D };; +{ .mib; add T1=T1,r9 // T1+=Sigma1(e) + _rotr r11=$t0,$Sigma0[1] } // ROTR(a,34) +{ .mib; mov D=C + mov C=B };; +{ .mib; add T1=T1,X[15] // T1+=X[i] + _rotr r8=$t0,$Sigma0[2] } // ROTR(a,39) +{ .mib; xor r10=r10,r11 + mux2 X[15]=X[15],0x44 };; // eliminated in 64-bit +{ .mmi; xor r10=r8,r10 // r10=Sigma0(a) + mov B=A + add A=T1,T2 };; +{ .mib; add E=E,T1 + add A=A,r10 // T2=Maj(a,b,c)+Sigma0(a) + br.ctop.sptk .L_first16 };; +.L_first16_end: + +{ .mii; mov ar.lc=$rounds-17 + mov ar.ec=1 };; + +.align 32 +.L_rest: +.rotr X[16] +{ .mib; $LDW K=[Ktbl],$SZ + _rotr r8=X[15-1],$sigma0[0] } // ROTR(s0,1) +{ .mib; $ADD X[15]=X[15],X[15-9] // X[i&0xF]+=X[(i+9)&0xF] + $SHRU s0=X[15-1],sgm0 };; // s0=X[(i+1)&0xF]>>7 +{ .mib; and T1=F,E + _rotr r9=X[15-1],$sigma0[1] } // ROTR(s0,8) +{ .mib; andcm r10=G,E + $SHRU s1=X[15-14],sgm1 };; // s1=X[(i+14)&0xF]>>6 +{ .mmi; xor T1=T1,r10 // T1=((e & f) ^ (~e & g)) + xor r9=r8,r9 + _rotr r10=X[15-14],$sigma1[0] };;// ROTR(s1,19) +{ .mib; and T2=A,B + _rotr r11=X[15-14],$sigma1[1] }// ROTR(s1,61) +{ .mib; and r8=A,C };; +___ +$t0="t0", $t1="t1", $code.=<<___ if ($BITS==32); +// I adhere to mmi; in order to hold Itanium 1 back and avoid 6 cycle +// pipeline flush in last bundle. Note that even on Itanium2 the +// latter stalls for one clock cycle... +{ .mmi; xor s0=s0,r9 // s0=sigma0(X[(i+1)&0xF]) + dep.z $t1=E,32,32 } +{ .mmi; xor r10=r11,r10 + zxt4 E=E };; +{ .mmi; or $t1=$t1,E + xor s1=s1,r10 // s1=sigma1(X[(i+14)&0xF]) + mux2 $t0=A,0x44 };; // copy lower half to upper +{ .mmi; xor T2=T2,r8 + _rotr r9=$t1,$Sigma1[0] } // ROTR(e,14) +{ .mmi; and r10=B,C + add T1=T1,H // T1=Ch(e,f,g)+h + $ADD X[15]=X[15],s0 };; // X[i&0xF]+=sigma0(X[(i+1)&0xF]) +___ +$t0="A", $t1="E", $code.=<<___ if ($BITS==64); +{ .mib; xor s0=s0,r9 // s0=sigma0(X[(i+1)&0xF]) + _rotr r9=$t1,$Sigma1[0] } // ROTR(e,14) +{ .mib; xor r10=r11,r10 + xor T2=T2,r8 };; +{ .mib; xor s1=s1,r10 // s1=sigma1(X[(i+14)&0xF]) + add T1=T1,H } +{ .mib; and r10=B,C + $ADD X[15]=X[15],s0 };; // X[i&0xF]+=sigma0(X[(i+1)&0xF]) +___ +$code.=<<___; +{ .mmi; xor T2=T2,r10 // T2=((a & b) ^ (a & c) ^ (b & c)) + mov H=G + _rotr r8=$t1,$Sigma1[1] };; // ROTR(e,18) +{ .mmi; xor r11=r8,r9 + $ADD X[15]=X[15],s1 // X[i&0xF]+=sigma1(X[(i+14)&0xF]) + _rotr r9=$t1,$Sigma1[2] } // ROTR(e,41) +{ .mmi; mov G=F + mov F=E };; +{ .mib; xor r9=r9,r11 // r9=Sigma1(e) + _rotr r10=$t0,$Sigma0[0] } // ROTR(a,28) +{ .mib; add T1=T1,K // T1=Ch(e,f,g)+h+K512[i] + mov E=D };; +{ .mib; add T1=T1,r9 // T1+=Sigma1(e) + _rotr r11=$t0,$Sigma0[1] } // ROTR(a,34) +{ .mib; mov D=C + mov C=B };; +{ .mmi; add T1=T1,X[15] // T1+=X[i] + xor r10=r10,r11 + _rotr r8=$t0,$Sigma0[2] };; // ROTR(a,39) +{ .mmi; xor r10=r8,r10 // r10=Sigma0(a) + mov B=A + add A=T1,T2 };; +{ .mib; add E=E,T1 + add A=A,r10 // T2=Maj(a,b,c)+Sigma0(a) + br.ctop.sptk .L_rest };; +.L_rest_end: + +{ .mmi; add A_=A_,A + add B_=B_,B + add C_=C_,C } +{ .mmi; add D_=D_,D + add E_=E_,E + cmp.ltu p16,p0=1,num };; +{ .mmi; add F_=F_,F + add G_=G_,G + add H_=H_,H } +{ .mmb; add Ktbl=-$SZ*$rounds,Ktbl +(p16) add num=-1,num +(p16) br.dptk.many .L_outer };; + +{ .mib; add r8=0*$SZ,ctx + add r9=1*$SZ,ctx } +{ .mib; add r10=2*$SZ,ctx + add r11=3*$SZ,ctx };; +{ .mmi; $STW [r8]=A_,4*$SZ + $STW [r9]=B_,4*$SZ + mov ar.lc=lcsave } +{ .mmi; $STW [r10]=C_,4*$SZ + $STW [r11]=D_,4*$SZ + mov pr=prsave,0x1ffff };; +{ .mmb; $STW [r8]=E_ + $STW [r9]=F_ } +{ .mmb; $STW [r10]=G_ + $STW [r11]=H_ + br.ret.sptk.many b0 };; +.endp $func# +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +$code =~ s/_rotr(\s+)([^=]+)=([^,]+),([0-9]+)/shrp$1$2=$3,$3,$4/gm; +if ($BITS==64) { + $code =~ s/mux2(\s+)\S+/nop.i$1 0x0/gm; + $code =~ s/mux1(\s+)\S+/nop.i$1 0x0/gm if ($big_endian); + $code =~ s/(shrp\s+X\[[^=]+)=([^,]+),([^,]+),([1-9]+)/$1=$3,$2,64-$4/gm + if (!$big_endian); + $code =~ s/ld1(\s+)X\[\S+/nop.m$1 0x0/gm; +} + +print $code; + +print<<___ if ($BITS==32); +.align 64 +.type K256#,\@object +K256: data4 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 + data4 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 + data4 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 + data4 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 + data4 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc + data4 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da + data4 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 + data4 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 + data4 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 + data4 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 + data4 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 + data4 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 + data4 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 + data4 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 + data4 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 + data4 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +.size K256#,$SZ*$rounds +stringz "SHA256 block transform for IA64, CRYPTOGAMS by " +___ +print<<___ if ($BITS==64); +.align 64 +.type K512#,\@object +K512: data8 0x428a2f98d728ae22,0x7137449123ef65cd + data8 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc + data8 0x3956c25bf348b538,0x59f111f1b605d019 + data8 0x923f82a4af194f9b,0xab1c5ed5da6d8118 + data8 0xd807aa98a3030242,0x12835b0145706fbe + data8 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 + data8 0x72be5d74f27b896f,0x80deb1fe3b1696b1 + data8 0x9bdc06a725c71235,0xc19bf174cf692694 + data8 0xe49b69c19ef14ad2,0xefbe4786384f25e3 + data8 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 + data8 0x2de92c6f592b0275,0x4a7484aa6ea6e483 + data8 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 + data8 0x983e5152ee66dfab,0xa831c66d2db43210 + data8 0xb00327c898fb213f,0xbf597fc7beef0ee4 + data8 0xc6e00bf33da88fc2,0xd5a79147930aa725 + data8 0x06ca6351e003826f,0x142929670a0e6e70 + data8 0x27b70a8546d22ffc,0x2e1b21385c26c926 + data8 0x4d2c6dfc5ac42aed,0x53380d139d95b3df + data8 0x650a73548baf63de,0x766a0abb3c77b2a8 + data8 0x81c2c92e47edaee6,0x92722c851482353b + data8 0xa2bfe8a14cf10364,0xa81a664bbc423001 + data8 0xc24b8b70d0f89791,0xc76c51a30654be30 + data8 0xd192e819d6ef5218,0xd69906245565a910 + data8 0xf40e35855771202a,0x106aa07032bbd1b8 + data8 0x19a4c116b8d2d0c8,0x1e376c085141ab53 + data8 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 + data8 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb + data8 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 + data8 0x748f82ee5defb2fc,0x78a5636f43172f60 + data8 0x84c87814a1f0ab72,0x8cc702081a6439ec + data8 0x90befffa23631e28,0xa4506cebde82bde9 + data8 0xbef9a3f7b2c67915,0xc67178f2e372532b + data8 0xca273eceea26619c,0xd186b8c721c0c207 + data8 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 + data8 0x06f067aa72176fba,0x0a637dc5a2c898a6 + data8 0x113f9804bef90dae,0x1b710b35131c471b + data8 0x28db77f523047d84,0x32caab7b40c72493 + data8 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c + data8 0x4cc5d4becb3e42b6,0x597f299cfc657e2a + data8 0x5fcb6fab3ad6faec,0x6c44198c4a475817 +.size K512#,$SZ*$rounds +stringz "SHA512 block transform for IA64, CRYPTOGAMS by " +___ diff --git a/libs/openssl/crypto/sha/asm/sha512-mips.pl b/libs/openssl/crypto/sha/asm/sha512-mips.pl new file mode 100644 index 00000000..6807a2c7 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha512-mips.pl @@ -0,0 +1,455 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# SHA2 block procedures for MIPS. + +# October 2010. +# +# SHA256 performance improvement on MIPS R5000 CPU is ~27% over gcc- +# generated code in o32 build and ~55% in n32/64 build. SHA512 [which +# for now can only be compiled for MIPS64 ISA] improvement is modest +# ~17%, but it comes for free, because it's same instruction sequence. +# Improvement coefficients are for aligned input. + +###################################################################### +# There is a number of MIPS ABI in use, O32 and N32/64 are most +# widely used. Then there is a new contender: NUBI. It appears that if +# one picks the latter, it's possible to arrange code in ABI neutral +# manner. Therefore let's stick to NUBI register layout: +# +($zero,$at,$t0,$t1,$t2)=map("\$$_",(0..2,24,25)); +($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11)); +($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7,$s8,$s9,$s10,$s11)=map("\$$_",(12..23)); +($gp,$tp,$sp,$fp,$ra)=map("\$$_",(3,28..31)); +# +# The return value is placed in $a0. Following coding rules facilitate +# interoperability: +# +# - never ever touch $tp, "thread pointer", former $gp [o32 can be +# excluded from the rule, because it's specified volatile]; +# - copy return value to $t0, former $v0 [or to $a0 if you're adapting +# old code]; +# - on O32 populate $a4-$a7 with 'lw $aN,4*N($sp)' if necessary; +# +# For reference here is register layout for N32/64 MIPS ABIs: +# +# ($zero,$at,$v0,$v1)=map("\$$_",(0..3)); +# ($a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7)=map("\$$_",(4..11)); +# ($t0,$t1,$t2,$t3,$t8,$t9)=map("\$$_",(12..15,24,25)); +# ($s0,$s1,$s2,$s3,$s4,$s5,$s6,$s7)=map("\$$_",(16..23)); +# ($gp,$sp,$fp,$ra)=map("\$$_",(28..31)); +# +$flavour = shift; # supported flavours are o32,n32,64,nubi32,nubi64 + +if ($flavour =~ /64|n32/i) { + $PTR_ADD="dadd"; # incidentally works even on n32 + $PTR_SUB="dsub"; # incidentally works even on n32 + $REG_S="sd"; + $REG_L="ld"; + $PTR_SLL="dsll"; # incidentally works even on n32 + $SZREG=8; +} else { + $PTR_ADD="add"; + $PTR_SUB="sub"; + $REG_S="sw"; + $REG_L="lw"; + $PTR_SLL="sll"; + $SZREG=4; +} +$pf = ($flavour =~ /nubi/i) ? $t0 : $t2; +# +# +# +###################################################################### + +$big_endian=(`echo MIPSEL | $ENV{CC} -E -`=~/MIPSEL/)?1:0 if ($ENV{CC}); + +for (@ARGV) { $output=$_ if (/^\w[\w\-]*\.\w+$/); } +open STDOUT,">$output"; + +if (!defined($big_endian)) { $big_endian=(unpack('L',pack('N',1))==1); } + +if ($output =~ /512/) { + $label="512"; + $SZ=8; + $LD="ld"; # load from memory + $ST="sd"; # store to memory + $SLL="dsll"; # shift left logical + $SRL="dsrl"; # shift right logical + $ADDU="daddu"; + @Sigma0=(28,34,39); + @Sigma1=(14,18,41); + @sigma0=( 7, 1, 8); # right shift first + @sigma1=( 6,19,61); # right shift first + $lastK=0x817; + $rounds=80; +} else { + $label="256"; + $SZ=4; + $LD="lw"; # load from memory + $ST="sw"; # store to memory + $SLL="sll"; # shift left logical + $SRL="srl"; # shift right logical + $ADDU="addu"; + @Sigma0=( 2,13,22); + @Sigma1=( 6,11,25); + @sigma0=( 3, 7,18); # right shift first + @sigma1=(10,17,19); # right shift first + $lastK=0x8f2; + $rounds=64; +} + +$MSB = $big_endian ? 0 : ($SZ-1); +$LSB = ($SZ-1)&~$MSB; + +@V=($A,$B,$C,$D,$E,$F,$G,$H)=map("\$$_",(1,2,3,7,24,25,30,31)); +@X=map("\$$_",(8..23)); + +$ctx=$a0; +$inp=$a1; +$len=$a2; $Ktbl=$len; + +sub BODY_00_15 { +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; +my ($T1,$tmp0,$tmp1,$tmp2)=(@X[4],@X[5],@X[6],@X[7]); + +$code.=<<___ if ($i<15); + ${LD}l @X[1],`($i+1)*$SZ+$MSB`($inp) + ${LD}r @X[1],`($i+1)*$SZ+$LSB`($inp) +___ +$code.=<<___ if (!$big_endian && $i<16 && $SZ==4); + srl $tmp0,@X[0],24 # byte swap($i) + srl $tmp1,@X[0],8 + andi $tmp2,@X[0],0xFF00 + sll @X[0],@X[0],24 + andi $tmp1,0xFF00 + sll $tmp2,$tmp2,8 + or @X[0],$tmp0 + or $tmp1,$tmp2 + or @X[0],$tmp1 +___ +$code.=<<___ if (!$big_endian && $i<16 && $SZ==8); + ori $tmp0,$zero,0xFF + dsll $tmp2,$tmp0,32 + or $tmp0,$tmp2 # 0x000000FF000000FF + and $tmp1,@X[0],$tmp0 # byte swap($i) + dsrl $tmp2,@X[0],24 + dsll $tmp1,24 + and $tmp2,$tmp0 + dsll $tmp0,8 # 0x0000FF000000FF00 + or $tmp1,$tmp2 + and $tmp2,@X[0],$tmp0 + dsrl @X[0],8 + dsll $tmp2,8 + and @X[0],$tmp0 + or $tmp1,$tmp2 + or @X[0],$tmp1 + dsrl $tmp1,@X[0],32 + dsll @X[0],32 + or @X[0],$tmp1 +___ +$code.=<<___; + $ADDU $T1,$X[0],$h # $i + $SRL $h,$e,@Sigma1[0] + xor $tmp2,$f,$g + $SLL $tmp1,$e,`$SZ*8-@Sigma1[2]` + and $tmp2,$e + $SRL $tmp0,$e,@Sigma1[1] + xor $h,$tmp1 + $SLL $tmp1,$e,`$SZ*8-@Sigma1[1]` + xor $h,$tmp0 + $SRL $tmp0,$e,@Sigma1[2] + xor $h,$tmp1 + $SLL $tmp1,$e,`$SZ*8-@Sigma1[0]` + xor $h,$tmp0 + xor $tmp2,$g # Ch(e,f,g) + xor $tmp0,$tmp1,$h # Sigma1(e) + + $SRL $h,$a,@Sigma0[0] + $ADDU $T1,$tmp2 + $LD $tmp2,`$i*$SZ`($Ktbl) # K[$i] + $SLL $tmp1,$a,`$SZ*8-@Sigma0[2]` + $ADDU $T1,$tmp0 + $SRL $tmp0,$a,@Sigma0[1] + xor $h,$tmp1 + $SLL $tmp1,$a,`$SZ*8-@Sigma0[1]` + xor $h,$tmp0 + $SRL $tmp0,$a,@Sigma0[2] + xor $h,$tmp1 + $SLL $tmp1,$a,`$SZ*8-@Sigma0[0]` + xor $h,$tmp0 + $ST @X[0],`($i%16)*$SZ`($sp) # offload to ring buffer + xor $h,$tmp1 # Sigma0(a) + + or $tmp0,$a,$b + and $tmp1,$a,$b + and $tmp0,$c + or $tmp1,$tmp0 # Maj(a,b,c) + $ADDU $T1,$tmp2 # +=K[$i] + $ADDU $h,$tmp1 + + $ADDU $d,$T1 + $ADDU $h,$T1 +___ +$code.=<<___ if ($i>=13); + $LD @X[3],`(($i+3)%16)*$SZ`($sp) # prefetch from ring buffer +___ +} + +sub BODY_16_XX { +my $i=@_[0]; +my ($tmp0,$tmp1,$tmp2,$tmp3)=(@X[4],@X[5],@X[6],@X[7]); + +$code.=<<___; + $SRL $tmp2,@X[1],@sigma0[0] # Xupdate($i) + $ADDU @X[0],@X[9] # +=X[i+9] + $SLL $tmp1,@X[1],`$SZ*8-@sigma0[2]` + $SRL $tmp0,@X[1],@sigma0[1] + xor $tmp2,$tmp1 + $SLL $tmp1,`@sigma0[2]-@sigma0[1]` + xor $tmp2,$tmp0 + $SRL $tmp0,@X[1],@sigma0[2] + xor $tmp2,$tmp1 + + $SRL $tmp3,@X[14],@sigma1[0] + xor $tmp2,$tmp0 # sigma0(X[i+1]) + $SLL $tmp1,@X[14],`$SZ*8-@sigma1[2]` + $ADDU @X[0],$tmp2 + $SRL $tmp0,@X[14],@sigma1[1] + xor $tmp3,$tmp1 + $SLL $tmp1,`@sigma1[2]-@sigma1[1]` + xor $tmp3,$tmp0 + $SRL $tmp0,@X[14],@sigma1[2] + xor $tmp3,$tmp1 + + xor $tmp3,$tmp0 # sigma1(X[i+14]) + $ADDU @X[0],$tmp3 +___ + &BODY_00_15(@_); +} + +$FRAMESIZE=16*$SZ+16*$SZREG; +$SAVED_REGS_MASK = ($flavour =~ /nubi/i) ? 0xc0fff008 : 0xc0ff0000; + +$code.=<<___; +#ifdef OPENSSL_FIPSCANISTER +# include +#endif + +.text +.set noat +#if !defined(__vxworks) || defined(__pic__) +.option pic2 +#endif + +.align 5 +.globl sha${label}_block_data_order +.ent sha${label}_block_data_order +sha${label}_block_data_order: + .frame $sp,$FRAMESIZE,$ra + .mask $SAVED_REGS_MASK,-$SZREG + .set noreorder +___ +$code.=<<___ if ($flavour =~ /o32/i); # o32 PIC-ification + .cpload $pf +___ +$code.=<<___; + $PTR_SUB $sp,$FRAMESIZE + $REG_S $ra,$FRAMESIZE-1*$SZREG($sp) + $REG_S $fp,$FRAMESIZE-2*$SZREG($sp) + $REG_S $s11,$FRAMESIZE-3*$SZREG($sp) + $REG_S $s10,$FRAMESIZE-4*$SZREG($sp) + $REG_S $s9,$FRAMESIZE-5*$SZREG($sp) + $REG_S $s8,$FRAMESIZE-6*$SZREG($sp) + $REG_S $s7,$FRAMESIZE-7*$SZREG($sp) + $REG_S $s6,$FRAMESIZE-8*$SZREG($sp) + $REG_S $s5,$FRAMESIZE-9*$SZREG($sp) + $REG_S $s4,$FRAMESIZE-10*$SZREG($sp) +___ +$code.=<<___ if ($flavour =~ /nubi/i); # optimize non-nubi prologue + $REG_S $s3,$FRAMESIZE-11*$SZREG($sp) + $REG_S $s2,$FRAMESIZE-12*$SZREG($sp) + $REG_S $s1,$FRAMESIZE-13*$SZREG($sp) + $REG_S $s0,$FRAMESIZE-14*$SZREG($sp) + $REG_S $gp,$FRAMESIZE-15*$SZREG($sp) +___ +$code.=<<___; + $PTR_SLL @X[15],$len,`log(16*$SZ)/log(2)` +___ +$code.=<<___ if ($flavour !~ /o32/i); # non-o32 PIC-ification + .cplocal $Ktbl + .cpsetup $pf,$zero,sha${label}_block_data_order +___ +$code.=<<___; + .set reorder + la $Ktbl,K${label} # PIC-ified 'load address' + + $LD $A,0*$SZ($ctx) # load context + $LD $B,1*$SZ($ctx) + $LD $C,2*$SZ($ctx) + $LD $D,3*$SZ($ctx) + $LD $E,4*$SZ($ctx) + $LD $F,5*$SZ($ctx) + $LD $G,6*$SZ($ctx) + $LD $H,7*$SZ($ctx) + + $PTR_ADD @X[15],$inp # pointer to the end of input + $REG_S @X[15],16*$SZ($sp) + b .Loop + +.align 5 +.Loop: + ${LD}l @X[0],$MSB($inp) + ${LD}r @X[0],$LSB($inp) +___ +for ($i=0;$i<16;$i++) +{ &BODY_00_15($i,@V); unshift(@V,pop(@V)); push(@X,shift(@X)); } +$code.=<<___; + b .L16_xx +.align 4 +.L16_xx: +___ +for (;$i<32;$i++) +{ &BODY_16_XX($i,@V); unshift(@V,pop(@V)); push(@X,shift(@X)); } +$code.=<<___; + and @X[6],0xfff + li @X[7],$lastK + .set noreorder + bne @X[6],@X[7],.L16_xx + $PTR_ADD $Ktbl,16*$SZ # Ktbl+=16 + + $REG_L @X[15],16*$SZ($sp) # restore pointer to the end of input + $LD @X[0],0*$SZ($ctx) + $LD @X[1],1*$SZ($ctx) + $LD @X[2],2*$SZ($ctx) + $PTR_ADD $inp,16*$SZ + $LD @X[3],3*$SZ($ctx) + $ADDU $A,@X[0] + $LD @X[4],4*$SZ($ctx) + $ADDU $B,@X[1] + $LD @X[5],5*$SZ($ctx) + $ADDU $C,@X[2] + $LD @X[6],6*$SZ($ctx) + $ADDU $D,@X[3] + $LD @X[7],7*$SZ($ctx) + $ADDU $E,@X[4] + $ST $A,0*$SZ($ctx) + $ADDU $F,@X[5] + $ST $B,1*$SZ($ctx) + $ADDU $G,@X[6] + $ST $C,2*$SZ($ctx) + $ADDU $H,@X[7] + $ST $D,3*$SZ($ctx) + $ST $E,4*$SZ($ctx) + $ST $F,5*$SZ($ctx) + $ST $G,6*$SZ($ctx) + $ST $H,7*$SZ($ctx) + + bne $inp,@X[15],.Loop + $PTR_SUB $Ktbl,`($rounds-16)*$SZ` # rewind $Ktbl + + $REG_L $ra,$FRAMESIZE-1*$SZREG($sp) + $REG_L $fp,$FRAMESIZE-2*$SZREG($sp) + $REG_L $s11,$FRAMESIZE-3*$SZREG($sp) + $REG_L $s10,$FRAMESIZE-4*$SZREG($sp) + $REG_L $s9,$FRAMESIZE-5*$SZREG($sp) + $REG_L $s8,$FRAMESIZE-6*$SZREG($sp) + $REG_L $s7,$FRAMESIZE-7*$SZREG($sp) + $REG_L $s6,$FRAMESIZE-8*$SZREG($sp) + $REG_L $s5,$FRAMESIZE-9*$SZREG($sp) + $REG_L $s4,$FRAMESIZE-10*$SZREG($sp) +___ +$code.=<<___ if ($flavour =~ /nubi/i); + $REG_L $s3,$FRAMESIZE-11*$SZREG($sp) + $REG_L $s2,$FRAMESIZE-12*$SZREG($sp) + $REG_L $s1,$FRAMESIZE-13*$SZREG($sp) + $REG_L $s0,$FRAMESIZE-14*$SZREG($sp) + $REG_L $gp,$FRAMESIZE-15*$SZREG($sp) +___ +$code.=<<___; + jr $ra + $PTR_ADD $sp,$FRAMESIZE +.end sha${label}_block_data_order + +.rdata +.align 5 +K${label}: +___ +if ($SZ==4) { +$code.=<<___; + .word 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5 + .word 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5 + .word 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3 + .word 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174 + .word 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc + .word 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da + .word 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7 + .word 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967 + .word 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13 + .word 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85 + .word 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3 + .word 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070 + .word 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5 + .word 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3 + .word 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208 + .word 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +___ +} else { +$code.=<<___; + .dword 0x428a2f98d728ae22, 0x7137449123ef65cd + .dword 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc + .dword 0x3956c25bf348b538, 0x59f111f1b605d019 + .dword 0x923f82a4af194f9b, 0xab1c5ed5da6d8118 + .dword 0xd807aa98a3030242, 0x12835b0145706fbe + .dword 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2 + .dword 0x72be5d74f27b896f, 0x80deb1fe3b1696b1 + .dword 0x9bdc06a725c71235, 0xc19bf174cf692694 + .dword 0xe49b69c19ef14ad2, 0xefbe4786384f25e3 + .dword 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65 + .dword 0x2de92c6f592b0275, 0x4a7484aa6ea6e483 + .dword 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5 + .dword 0x983e5152ee66dfab, 0xa831c66d2db43210 + .dword 0xb00327c898fb213f, 0xbf597fc7beef0ee4 + .dword 0xc6e00bf33da88fc2, 0xd5a79147930aa725 + .dword 0x06ca6351e003826f, 0x142929670a0e6e70 + .dword 0x27b70a8546d22ffc, 0x2e1b21385c26c926 + .dword 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df + .dword 0x650a73548baf63de, 0x766a0abb3c77b2a8 + .dword 0x81c2c92e47edaee6, 0x92722c851482353b + .dword 0xa2bfe8a14cf10364, 0xa81a664bbc423001 + .dword 0xc24b8b70d0f89791, 0xc76c51a30654be30 + .dword 0xd192e819d6ef5218, 0xd69906245565a910 + .dword 0xf40e35855771202a, 0x106aa07032bbd1b8 + .dword 0x19a4c116b8d2d0c8, 0x1e376c085141ab53 + .dword 0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8 + .dword 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb + .dword 0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3 + .dword 0x748f82ee5defb2fc, 0x78a5636f43172f60 + .dword 0x84c87814a1f0ab72, 0x8cc702081a6439ec + .dword 0x90befffa23631e28, 0xa4506cebde82bde9 + .dword 0xbef9a3f7b2c67915, 0xc67178f2e372532b + .dword 0xca273eceea26619c, 0xd186b8c721c0c207 + .dword 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178 + .dword 0x06f067aa72176fba, 0x0a637dc5a2c898a6 + .dword 0x113f9804bef90dae, 0x1b710b35131c471b + .dword 0x28db77f523047d84, 0x32caab7b40c72493 + .dword 0x3c9ebe0a15c9bebc, 0x431d67c49c100d4c + .dword 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a + .dword 0x5fcb6fab3ad6faec, 0x6c44198c4a475817 +___ +} +$code.=<<___; +.asciiz "SHA${label} for MIPS, CRYPTOGAMS by " +.align 5 + +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/sha/asm/sha512-parisc.pl b/libs/openssl/crypto/sha/asm/sha512-parisc.pl new file mode 100755 index 00000000..6cad72e2 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha512-parisc.pl @@ -0,0 +1,793 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# SHA256/512 block procedure for PA-RISC. + +# June 2009. +# +# SHA256 performance is >75% better than gcc 3.2 generated code on +# PA-7100LC. Compared to code generated by vendor compiler this +# implementation is almost 70% faster in 64-bit build, but delivers +# virtually same performance in 32-bit build on PA-8600. +# +# SHA512 performance is >2.9x better than gcc 3.2 generated code on +# PA-7100LC, PA-RISC 1.1 processor. Then implementation detects if the +# code is executed on PA-RISC 2.0 processor and switches to 64-bit +# code path delivering adequate performance even in "blended" 32-bit +# build. Though 64-bit code is not any faster than code generated by +# vendor compiler on PA-8600... +# +# Special thanks to polarhome.com for providing HP-UX account. + +$flavour = shift; +$output = shift; +open STDOUT,">$output"; + +if ($flavour =~ /64/) { + $LEVEL ="2.0W"; + $SIZE_T =8; + $FRAME_MARKER =80; + $SAVED_RP =16; + $PUSH ="std"; + $PUSHMA ="std,ma"; + $POP ="ldd"; + $POPMB ="ldd,mb"; +} else { + $LEVEL ="1.0"; + $SIZE_T =4; + $FRAME_MARKER =48; + $SAVED_RP =20; + $PUSH ="stw"; + $PUSHMA ="stwm"; + $POP ="ldw"; + $POPMB ="ldwm"; +} + +if ($output =~ /512/) { + $func="sha512_block_data_order"; + $SZ=8; + @Sigma0=(28,34,39); + @Sigma1=(14,18,41); + @sigma0=(1, 8, 7); + @sigma1=(19,61, 6); + $rounds=80; + $LAST10BITS=0x017; + $LD="ldd"; + $LDM="ldd,ma"; + $ST="std"; +} else { + $func="sha256_block_data_order"; + $SZ=4; + @Sigma0=( 2,13,22); + @Sigma1=( 6,11,25); + @sigma0=( 7,18, 3); + @sigma1=(17,19,10); + $rounds=64; + $LAST10BITS=0x0f2; + $LD="ldw"; + $LDM="ldwm"; + $ST="stw"; +} + +$FRAME=16*$SIZE_T+$FRAME_MARKER;# 16 saved regs + frame marker + # [+ argument transfer] +$XOFF=16*$SZ+32; # local variables +$FRAME+=$XOFF; +$XOFF+=$FRAME_MARKER; # distance between %sp and local variables + +$ctx="%r26"; # zapped by $a0 +$inp="%r25"; # zapped by $a1 +$num="%r24"; # zapped by $t0 + +$a0 ="%r26"; +$a1 ="%r25"; +$t0 ="%r24"; +$t1 ="%r29"; +$Tbl="%r31"; + +@V=($A,$B,$C,$D,$E,$F,$G,$H)=("%r17","%r18","%r19","%r20","%r21","%r22","%r23","%r28"); + +@X=("%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", "%r8", + "%r9", "%r10","%r11","%r12","%r13","%r14","%r15","%r16",$inp); + +sub ROUND_00_15 { +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; +$code.=<<___; + _ror $e,$Sigma1[0],$a0 + and $f,$e,$t0 + _ror $e,$Sigma1[1],$a1 + addl $t1,$h,$h + andcm $g,$e,$t1 + xor $a1,$a0,$a0 + _ror $a1,`$Sigma1[2]-$Sigma1[1]`,$a1 + or $t0,$t1,$t1 ; Ch(e,f,g) + addl @X[$i%16],$h,$h + xor $a0,$a1,$a1 ; Sigma1(e) + addl $t1,$h,$h + _ror $a,$Sigma0[0],$a0 + addl $a1,$h,$h + + _ror $a,$Sigma0[1],$a1 + and $a,$b,$t0 + and $a,$c,$t1 + xor $a1,$a0,$a0 + _ror $a1,`$Sigma0[2]-$Sigma0[1]`,$a1 + xor $t1,$t0,$t0 + and $b,$c,$t1 + xor $a0,$a1,$a1 ; Sigma0(a) + addl $h,$d,$d + xor $t1,$t0,$t0 ; Maj(a,b,c) + `"$LDM $SZ($Tbl),$t1" if ($i<15)` + addl $a1,$h,$h + addl $t0,$h,$h + +___ +} + +sub ROUND_16_xx { +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; +$i-=16; +$code.=<<___; + _ror @X[($i+1)%16],$sigma0[0],$a0 + _ror @X[($i+1)%16],$sigma0[1],$a1 + addl @X[($i+9)%16],@X[$i],@X[$i] + _ror @X[($i+14)%16],$sigma1[0],$t0 + _ror @X[($i+14)%16],$sigma1[1],$t1 + xor $a1,$a0,$a0 + _shr @X[($i+1)%16],$sigma0[2],$a1 + xor $t1,$t0,$t0 + _shr @X[($i+14)%16],$sigma1[2],$t1 + xor $a1,$a0,$a0 ; sigma0(X[(i+1)&0x0f]) + xor $t1,$t0,$t0 ; sigma1(X[(i+14)&0x0f]) + $LDM $SZ($Tbl),$t1 + addl $a0,@X[$i],@X[$i] + addl $t0,@X[$i],@X[$i] +___ +$code.=<<___ if ($i==15); + extru $t1,31,10,$a1 + comiclr,<> $LAST10BITS,$a1,%r0 + ldo 1($Tbl),$Tbl ; signal end of $Tbl +___ +&ROUND_00_15($i+16,$a,$b,$c,$d,$e,$f,$g,$h); +} + +$code=<<___; + .LEVEL $LEVEL + .SPACE \$TEXT\$ + .SUBSPA \$CODE\$,QUAD=0,ALIGN=8,ACCESS=0x2C,CODE_ONLY + + .ALIGN 64 +L\$table +___ +$code.=<<___ if ($SZ==8); + .WORD 0x428a2f98,0xd728ae22,0x71374491,0x23ef65cd + .WORD 0xb5c0fbcf,0xec4d3b2f,0xe9b5dba5,0x8189dbbc + .WORD 0x3956c25b,0xf348b538,0x59f111f1,0xb605d019 + .WORD 0x923f82a4,0xaf194f9b,0xab1c5ed5,0xda6d8118 + .WORD 0xd807aa98,0xa3030242,0x12835b01,0x45706fbe + .WORD 0x243185be,0x4ee4b28c,0x550c7dc3,0xd5ffb4e2 + .WORD 0x72be5d74,0xf27b896f,0x80deb1fe,0x3b1696b1 + .WORD 0x9bdc06a7,0x25c71235,0xc19bf174,0xcf692694 + .WORD 0xe49b69c1,0x9ef14ad2,0xefbe4786,0x384f25e3 + .WORD 0x0fc19dc6,0x8b8cd5b5,0x240ca1cc,0x77ac9c65 + .WORD 0x2de92c6f,0x592b0275,0x4a7484aa,0x6ea6e483 + .WORD 0x5cb0a9dc,0xbd41fbd4,0x76f988da,0x831153b5 + .WORD 0x983e5152,0xee66dfab,0xa831c66d,0x2db43210 + .WORD 0xb00327c8,0x98fb213f,0xbf597fc7,0xbeef0ee4 + .WORD 0xc6e00bf3,0x3da88fc2,0xd5a79147,0x930aa725 + .WORD 0x06ca6351,0xe003826f,0x14292967,0x0a0e6e70 + .WORD 0x27b70a85,0x46d22ffc,0x2e1b2138,0x5c26c926 + .WORD 0x4d2c6dfc,0x5ac42aed,0x53380d13,0x9d95b3df + .WORD 0x650a7354,0x8baf63de,0x766a0abb,0x3c77b2a8 + .WORD 0x81c2c92e,0x47edaee6,0x92722c85,0x1482353b + .WORD 0xa2bfe8a1,0x4cf10364,0xa81a664b,0xbc423001 + .WORD 0xc24b8b70,0xd0f89791,0xc76c51a3,0x0654be30 + .WORD 0xd192e819,0xd6ef5218,0xd6990624,0x5565a910 + .WORD 0xf40e3585,0x5771202a,0x106aa070,0x32bbd1b8 + .WORD 0x19a4c116,0xb8d2d0c8,0x1e376c08,0x5141ab53 + .WORD 0x2748774c,0xdf8eeb99,0x34b0bcb5,0xe19b48a8 + .WORD 0x391c0cb3,0xc5c95a63,0x4ed8aa4a,0xe3418acb + .WORD 0x5b9cca4f,0x7763e373,0x682e6ff3,0xd6b2b8a3 + .WORD 0x748f82ee,0x5defb2fc,0x78a5636f,0x43172f60 + .WORD 0x84c87814,0xa1f0ab72,0x8cc70208,0x1a6439ec + .WORD 0x90befffa,0x23631e28,0xa4506ceb,0xde82bde9 + .WORD 0xbef9a3f7,0xb2c67915,0xc67178f2,0xe372532b + .WORD 0xca273ece,0xea26619c,0xd186b8c7,0x21c0c207 + .WORD 0xeada7dd6,0xcde0eb1e,0xf57d4f7f,0xee6ed178 + .WORD 0x06f067aa,0x72176fba,0x0a637dc5,0xa2c898a6 + .WORD 0x113f9804,0xbef90dae,0x1b710b35,0x131c471b + .WORD 0x28db77f5,0x23047d84,0x32caab7b,0x40c72493 + .WORD 0x3c9ebe0a,0x15c9bebc,0x431d67c4,0x9c100d4c + .WORD 0x4cc5d4be,0xcb3e42b6,0x597f299c,0xfc657e2a + .WORD 0x5fcb6fab,0x3ad6faec,0x6c44198c,0x4a475817 +___ +$code.=<<___ if ($SZ==4); + .WORD 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 + .WORD 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 + .WORD 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 + .WORD 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 + .WORD 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc + .WORD 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da + .WORD 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 + .WORD 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 + .WORD 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 + .WORD 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 + .WORD 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 + .WORD 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 + .WORD 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 + .WORD 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 + .WORD 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 + .WORD 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +___ +$code.=<<___; + + .EXPORT $func,ENTRY,ARGW0=GR,ARGW1=GR,ARGW2=GR + .ALIGN 64 +$func + .PROC + .CALLINFO FRAME=`$FRAME-16*$SIZE_T`,NO_CALLS,SAVE_RP,ENTRY_GR=18 + .ENTRY + $PUSH %r2,-$SAVED_RP(%sp) ; standard prologue + $PUSHMA %r3,$FRAME(%sp) + $PUSH %r4,`-$FRAME+1*$SIZE_T`(%sp) + $PUSH %r5,`-$FRAME+2*$SIZE_T`(%sp) + $PUSH %r6,`-$FRAME+3*$SIZE_T`(%sp) + $PUSH %r7,`-$FRAME+4*$SIZE_T`(%sp) + $PUSH %r8,`-$FRAME+5*$SIZE_T`(%sp) + $PUSH %r9,`-$FRAME+6*$SIZE_T`(%sp) + $PUSH %r10,`-$FRAME+7*$SIZE_T`(%sp) + $PUSH %r11,`-$FRAME+8*$SIZE_T`(%sp) + $PUSH %r12,`-$FRAME+9*$SIZE_T`(%sp) + $PUSH %r13,`-$FRAME+10*$SIZE_T`(%sp) + $PUSH %r14,`-$FRAME+11*$SIZE_T`(%sp) + $PUSH %r15,`-$FRAME+12*$SIZE_T`(%sp) + $PUSH %r16,`-$FRAME+13*$SIZE_T`(%sp) + $PUSH %r17,`-$FRAME+14*$SIZE_T`(%sp) + $PUSH %r18,`-$FRAME+15*$SIZE_T`(%sp) + + _shl $num,`log(16*$SZ)/log(2)`,$num + addl $inp,$num,$num ; $num to point at the end of $inp + + $PUSH $num,`-$FRAME_MARKER-4*$SIZE_T`(%sp) ; save arguments + $PUSH $inp,`-$FRAME_MARKER-3*$SIZE_T`(%sp) + $PUSH $ctx,`-$FRAME_MARKER-2*$SIZE_T`(%sp) + + blr %r0,$Tbl + ldi 3,$t1 +L\$pic + andcm $Tbl,$t1,$Tbl ; wipe privilege level + ldo L\$table-L\$pic($Tbl),$Tbl +___ +$code.=<<___ if ($SZ==8 && $SIZE_T==4); + ldi 31,$t1 + mtctl $t1,%cr11 + extrd,u,*= $t1,%sar,1,$t1 ; executes on PA-RISC 1.0 + b L\$parisc1 + nop +___ +$code.=<<___; + $LD `0*$SZ`($ctx),$A ; load context + $LD `1*$SZ`($ctx),$B + $LD `2*$SZ`($ctx),$C + $LD `3*$SZ`($ctx),$D + $LD `4*$SZ`($ctx),$E + $LD `5*$SZ`($ctx),$F + $LD `6*$SZ`($ctx),$G + $LD `7*$SZ`($ctx),$H + + extru $inp,31,`log($SZ)/log(2)`,$t0 + sh3addl $t0,%r0,$t0 + subi `8*$SZ`,$t0,$t0 + mtctl $t0,%cr11 ; load %sar with align factor + +L\$oop + ldi `$SZ-1`,$t0 + $LDM $SZ($Tbl),$t1 + andcm $inp,$t0,$t0 ; align $inp +___ + for ($i=0;$i<15;$i++) { # load input block + $code.="\t$LD `$SZ*$i`($t0),@X[$i]\n"; } +$code.=<<___; + cmpb,*= $inp,$t0,L\$aligned + $LD `$SZ*15`($t0),@X[15] + $LD `$SZ*16`($t0),@X[16] +___ + for ($i=0;$i<16;$i++) { # align data + $code.="\t_align @X[$i],@X[$i+1],@X[$i]\n"; } +$code.=<<___; +L\$aligned + nop ; otherwise /usr/ccs/bin/as is confused by below .WORD +___ + +for($i=0;$i<16;$i++) { &ROUND_00_15($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; +L\$rounds + nop ; otherwise /usr/ccs/bin/as is confused by below .WORD +___ +for(;$i<32;$i++) { &ROUND_16_xx($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + bb,>= $Tbl,31,L\$rounds ; end of $Tbl signalled? + nop + + $POP `-$FRAME_MARKER-2*$SIZE_T`(%sp),$ctx ; restore arguments + $POP `-$FRAME_MARKER-3*$SIZE_T`(%sp),$inp + $POP `-$FRAME_MARKER-4*$SIZE_T`(%sp),$num + ldo `-$rounds*$SZ-1`($Tbl),$Tbl ; rewind $Tbl + + $LD `0*$SZ`($ctx),@X[0] ; load context + $LD `1*$SZ`($ctx),@X[1] + $LD `2*$SZ`($ctx),@X[2] + $LD `3*$SZ`($ctx),@X[3] + $LD `4*$SZ`($ctx),@X[4] + $LD `5*$SZ`($ctx),@X[5] + addl @X[0],$A,$A + $LD `6*$SZ`($ctx),@X[6] + addl @X[1],$B,$B + $LD `7*$SZ`($ctx),@X[7] + ldo `16*$SZ`($inp),$inp ; advance $inp + + $ST $A,`0*$SZ`($ctx) ; save context + addl @X[2],$C,$C + $ST $B,`1*$SZ`($ctx) + addl @X[3],$D,$D + $ST $C,`2*$SZ`($ctx) + addl @X[4],$E,$E + $ST $D,`3*$SZ`($ctx) + addl @X[5],$F,$F + $ST $E,`4*$SZ`($ctx) + addl @X[6],$G,$G + $ST $F,`5*$SZ`($ctx) + addl @X[7],$H,$H + $ST $G,`6*$SZ`($ctx) + $ST $H,`7*$SZ`($ctx) + + cmpb,*<>,n $inp,$num,L\$oop + $PUSH $inp,`-$FRAME_MARKER-3*$SIZE_T`(%sp) ; save $inp +___ +if ($SZ==8 && $SIZE_T==4) # SHA512 for 32-bit PA-RISC 1.0 +{{ +$code.=<<___; + b L\$done + nop + + .ALIGN 64 +L\$parisc1 +___ + +@V=( $Ahi, $Alo, $Bhi, $Blo, $Chi, $Clo, $Dhi, $Dlo, + $Ehi, $Elo, $Fhi, $Flo, $Ghi, $Glo, $Hhi, $Hlo) = + ( "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", "%r8", + "%r9","%r10","%r11","%r12","%r13","%r14","%r15","%r16"); +$a0 ="%r17"; +$a1 ="%r18"; +$a2 ="%r19"; +$a3 ="%r20"; +$t0 ="%r21"; +$t1 ="%r22"; +$t2 ="%r28"; +$t3 ="%r29"; +$Tbl="%r31"; + +@X=("%r23","%r24","%r25","%r26"); # zaps $num,$inp,$ctx + +sub ROUND_00_15_pa1 { +my ($i,$ahi,$alo,$bhi,$blo,$chi,$clo,$dhi,$dlo, + $ehi,$elo,$fhi,$flo,$ghi,$glo,$hhi,$hlo,$flag)=@_; +my ($Xhi,$Xlo,$Xnhi,$Xnlo) = @X; + +$code.=<<___ if (!$flag); + ldw `-$XOFF+8*(($i+1)%16)`(%sp),$Xnhi + ldw `-$XOFF+8*(($i+1)%16)+4`(%sp),$Xnlo ; load X[i+1] +___ +$code.=<<___; + shd $ehi,$elo,$Sigma1[0],$t0 + add $Xlo,$hlo,$hlo + shd $elo,$ehi,$Sigma1[0],$t1 + addc $Xhi,$hhi,$hhi ; h += X[i] + shd $ehi,$elo,$Sigma1[1],$t2 + ldwm 8($Tbl),$Xhi + shd $elo,$ehi,$Sigma1[1],$t3 + ldw -4($Tbl),$Xlo ; load K[i] + xor $t2,$t0,$t0 + xor $t3,$t1,$t1 + and $flo,$elo,$a0 + and $fhi,$ehi,$a1 + shd $ehi,$elo,$Sigma1[2],$t2 + andcm $glo,$elo,$a2 + shd $elo,$ehi,$Sigma1[2],$t3 + andcm $ghi,$ehi,$a3 + xor $t2,$t0,$t0 + xor $t3,$t1,$t1 ; Sigma1(e) + add $Xlo,$hlo,$hlo + xor $a2,$a0,$a0 + addc $Xhi,$hhi,$hhi ; h += K[i] + xor $a3,$a1,$a1 ; Ch(e,f,g) + + add $t0,$hlo,$hlo + shd $ahi,$alo,$Sigma0[0],$t0 + addc $t1,$hhi,$hhi ; h += Sigma1(e) + shd $alo,$ahi,$Sigma0[0],$t1 + add $a0,$hlo,$hlo + shd $ahi,$alo,$Sigma0[1],$t2 + addc $a1,$hhi,$hhi ; h += Ch(e,f,g) + shd $alo,$ahi,$Sigma0[1],$t3 + + xor $t2,$t0,$t0 + xor $t3,$t1,$t1 + shd $ahi,$alo,$Sigma0[2],$t2 + and $alo,$blo,$a0 + shd $alo,$ahi,$Sigma0[2],$t3 + and $ahi,$bhi,$a1 + xor $t2,$t0,$t0 + xor $t3,$t1,$t1 ; Sigma0(a) + + and $alo,$clo,$a2 + and $ahi,$chi,$a3 + xor $a2,$a0,$a0 + add $hlo,$dlo,$dlo + xor $a3,$a1,$a1 + addc $hhi,$dhi,$dhi ; d += h + and $blo,$clo,$a2 + add $t0,$hlo,$hlo + and $bhi,$chi,$a3 + addc $t1,$hhi,$hhi ; h += Sigma0(a) + xor $a2,$a0,$a0 + add $a0,$hlo,$hlo + xor $a3,$a1,$a1 ; Maj(a,b,c) + addc $a1,$hhi,$hhi ; h += Maj(a,b,c) + +___ +$code.=<<___ if ($i==15 && $flag); + extru $Xlo,31,10,$Xlo + comiclr,= $LAST10BITS,$Xlo,%r0 + b L\$rounds_pa1 + nop +___ +push(@X,shift(@X)); push(@X,shift(@X)); +} + +sub ROUND_16_xx_pa1 { +my ($Xhi,$Xlo,$Xnhi,$Xnlo) = @X; +my ($i)=shift; +$i-=16; +$code.=<<___; + ldw `-$XOFF+8*(($i+1)%16)`(%sp),$Xnhi + ldw `-$XOFF+8*(($i+1)%16)+4`(%sp),$Xnlo ; load X[i+1] + ldw `-$XOFF+8*(($i+9)%16)`(%sp),$a1 + ldw `-$XOFF+8*(($i+9)%16)+4`(%sp),$a0 ; load X[i+9] + ldw `-$XOFF+8*(($i+14)%16)`(%sp),$a3 + ldw `-$XOFF+8*(($i+14)%16)+4`(%sp),$a2 ; load X[i+14] + shd $Xnhi,$Xnlo,$sigma0[0],$t0 + shd $Xnlo,$Xnhi,$sigma0[0],$t1 + add $a0,$Xlo,$Xlo + shd $Xnhi,$Xnlo,$sigma0[1],$t2 + addc $a1,$Xhi,$Xhi + shd $Xnlo,$Xnhi,$sigma0[1],$t3 + xor $t2,$t0,$t0 + shd $Xnhi,$Xnlo,$sigma0[2],$t2 + xor $t3,$t1,$t1 + extru $Xnhi,`31-$sigma0[2]`,`32-$sigma0[2]`,$t3 + xor $t2,$t0,$t0 + shd $a3,$a2,$sigma1[0],$a0 + xor $t3,$t1,$t1 ; sigma0(X[i+1)&0x0f]) + shd $a2,$a3,$sigma1[0],$a1 + add $t0,$Xlo,$Xlo + shd $a3,$a2,$sigma1[1],$t2 + addc $t1,$Xhi,$Xhi + shd $a2,$a3,$sigma1[1],$t3 + xor $t2,$a0,$a0 + shd $a3,$a2,$sigma1[2],$t2 + xor $t3,$a1,$a1 + extru $a3,`31-$sigma1[2]`,`32-$sigma1[2]`,$t3 + xor $t2,$a0,$a0 + xor $t3,$a1,$a1 ; sigma0(X[i+14)&0x0f]) + add $a0,$Xlo,$Xlo + addc $a1,$Xhi,$Xhi + + stw $Xhi,`-$XOFF+8*($i%16)`(%sp) + stw $Xlo,`-$XOFF+8*($i%16)+4`(%sp) +___ +&ROUND_00_15_pa1($i,@_,1); +} +$code.=<<___; + ldw `0*4`($ctx),$Ahi ; load context + ldw `1*4`($ctx),$Alo + ldw `2*4`($ctx),$Bhi + ldw `3*4`($ctx),$Blo + ldw `4*4`($ctx),$Chi + ldw `5*4`($ctx),$Clo + ldw `6*4`($ctx),$Dhi + ldw `7*4`($ctx),$Dlo + ldw `8*4`($ctx),$Ehi + ldw `9*4`($ctx),$Elo + ldw `10*4`($ctx),$Fhi + ldw `11*4`($ctx),$Flo + ldw `12*4`($ctx),$Ghi + ldw `13*4`($ctx),$Glo + ldw `14*4`($ctx),$Hhi + ldw `15*4`($ctx),$Hlo + + extru $inp,31,2,$t0 + sh3addl $t0,%r0,$t0 + subi 32,$t0,$t0 + mtctl $t0,%cr11 ; load %sar with align factor + +L\$oop_pa1 + extru $inp,31,2,$a3 + comib,= 0,$a3,L\$aligned_pa1 + sub $inp,$a3,$inp + + ldw `0*4`($inp),$X[0] + ldw `1*4`($inp),$X[1] + ldw `2*4`($inp),$t2 + ldw `3*4`($inp),$t3 + ldw `4*4`($inp),$a0 + ldw `5*4`($inp),$a1 + ldw `6*4`($inp),$a2 + ldw `7*4`($inp),$a3 + vshd $X[0],$X[1],$X[0] + vshd $X[1],$t2,$X[1] + stw $X[0],`-$XOFF+0*4`(%sp) + ldw `8*4`($inp),$t0 + vshd $t2,$t3,$t2 + stw $X[1],`-$XOFF+1*4`(%sp) + ldw `9*4`($inp),$t1 + vshd $t3,$a0,$t3 +___ +{ +my @t=($t2,$t3,$a0,$a1,$a2,$a3,$t0,$t1); +for ($i=2;$i<=(128/4-8);$i++) { +$code.=<<___; + stw $t[0],`-$XOFF+$i*4`(%sp) + ldw `(8+$i)*4`($inp),$t[0] + vshd $t[1],$t[2],$t[1] +___ +push(@t,shift(@t)); +} +for (;$i<(128/4-1);$i++) { +$code.=<<___; + stw $t[0],`-$XOFF+$i*4`(%sp) + vshd $t[1],$t[2],$t[1] +___ +push(@t,shift(@t)); +} +$code.=<<___; + b L\$collected_pa1 + stw $t[0],`-$XOFF+$i*4`(%sp) + +___ +} +$code.=<<___; +L\$aligned_pa1 + ldw `0*4`($inp),$X[0] + ldw `1*4`($inp),$X[1] + ldw `2*4`($inp),$t2 + ldw `3*4`($inp),$t3 + ldw `4*4`($inp),$a0 + ldw `5*4`($inp),$a1 + ldw `6*4`($inp),$a2 + ldw `7*4`($inp),$a3 + stw $X[0],`-$XOFF+0*4`(%sp) + ldw `8*4`($inp),$t0 + stw $X[1],`-$XOFF+1*4`(%sp) + ldw `9*4`($inp),$t1 +___ +{ +my @t=($t2,$t3,$a0,$a1,$a2,$a3,$t0,$t1); +for ($i=2;$i<(128/4-8);$i++) { +$code.=<<___; + stw $t[0],`-$XOFF+$i*4`(%sp) + ldw `(8+$i)*4`($inp),$t[0] +___ +push(@t,shift(@t)); +} +for (;$i<128/4;$i++) { +$code.=<<___; + stw $t[0],`-$XOFF+$i*4`(%sp) +___ +push(@t,shift(@t)); +} +$code.="L\$collected_pa1\n"; +} + +for($i=0;$i<16;$i++) { &ROUND_00_15_pa1($i,@V); unshift(@V,pop(@V)); unshift(@V,pop(@V)); } +$code.="L\$rounds_pa1\n"; +for(;$i<32;$i++) { &ROUND_16_xx_pa1($i,@V); unshift(@V,pop(@V)); unshift(@V,pop(@V)); } + +$code.=<<___; + $POP `-$FRAME_MARKER-2*$SIZE_T`(%sp),$ctx ; restore arguments + $POP `-$FRAME_MARKER-3*$SIZE_T`(%sp),$inp + $POP `-$FRAME_MARKER-4*$SIZE_T`(%sp),$num + ldo `-$rounds*$SZ`($Tbl),$Tbl ; rewind $Tbl + + ldw `0*4`($ctx),$t1 ; update context + ldw `1*4`($ctx),$t0 + ldw `2*4`($ctx),$t3 + ldw `3*4`($ctx),$t2 + ldw `4*4`($ctx),$a1 + ldw `5*4`($ctx),$a0 + ldw `6*4`($ctx),$a3 + add $t0,$Alo,$Alo + ldw `7*4`($ctx),$a2 + addc $t1,$Ahi,$Ahi + ldw `8*4`($ctx),$t1 + add $t2,$Blo,$Blo + ldw `9*4`($ctx),$t0 + addc $t3,$Bhi,$Bhi + ldw `10*4`($ctx),$t3 + add $a0,$Clo,$Clo + ldw `11*4`($ctx),$t2 + addc $a1,$Chi,$Chi + ldw `12*4`($ctx),$a1 + add $a2,$Dlo,$Dlo + ldw `13*4`($ctx),$a0 + addc $a3,$Dhi,$Dhi + ldw `14*4`($ctx),$a3 + add $t0,$Elo,$Elo + ldw `15*4`($ctx),$a2 + addc $t1,$Ehi,$Ehi + stw $Ahi,`0*4`($ctx) + add $t2,$Flo,$Flo + stw $Alo,`1*4`($ctx) + addc $t3,$Fhi,$Fhi + stw $Bhi,`2*4`($ctx) + add $a0,$Glo,$Glo + stw $Blo,`3*4`($ctx) + addc $a1,$Ghi,$Ghi + stw $Chi,`4*4`($ctx) + add $a2,$Hlo,$Hlo + stw $Clo,`5*4`($ctx) + addc $a3,$Hhi,$Hhi + stw $Dhi,`6*4`($ctx) + ldo `16*$SZ`($inp),$inp ; advance $inp + stw $Dlo,`7*4`($ctx) + stw $Ehi,`8*4`($ctx) + stw $Elo,`9*4`($ctx) + stw $Fhi,`10*4`($ctx) + stw $Flo,`11*4`($ctx) + stw $Ghi,`12*4`($ctx) + stw $Glo,`13*4`($ctx) + stw $Hhi,`14*4`($ctx) + comb,= $inp,$num,L\$done + stw $Hlo,`15*4`($ctx) + b L\$oop_pa1 + $PUSH $inp,`-$FRAME_MARKER-3*$SIZE_T`(%sp) ; save $inp +L\$done +___ +}} +$code.=<<___; + $POP `-$FRAME-$SAVED_RP`(%sp),%r2 ; standard epilogue + $POP `-$FRAME+1*$SIZE_T`(%sp),%r4 + $POP `-$FRAME+2*$SIZE_T`(%sp),%r5 + $POP `-$FRAME+3*$SIZE_T`(%sp),%r6 + $POP `-$FRAME+4*$SIZE_T`(%sp),%r7 + $POP `-$FRAME+5*$SIZE_T`(%sp),%r8 + $POP `-$FRAME+6*$SIZE_T`(%sp),%r9 + $POP `-$FRAME+7*$SIZE_T`(%sp),%r10 + $POP `-$FRAME+8*$SIZE_T`(%sp),%r11 + $POP `-$FRAME+9*$SIZE_T`(%sp),%r12 + $POP `-$FRAME+10*$SIZE_T`(%sp),%r13 + $POP `-$FRAME+11*$SIZE_T`(%sp),%r14 + $POP `-$FRAME+12*$SIZE_T`(%sp),%r15 + $POP `-$FRAME+13*$SIZE_T`(%sp),%r16 + $POP `-$FRAME+14*$SIZE_T`(%sp),%r17 + $POP `-$FRAME+15*$SIZE_T`(%sp),%r18 + bv (%r2) + .EXIT + $POPMB -$FRAME(%sp),%r3 + .PROCEND + .STRINGZ "SHA`64*$SZ` block transform for PA-RISC, CRYPTOGAMS by " +___ + +# Explicitly encode PA-RISC 2.0 instructions used in this module, so +# that it can be compiled with .LEVEL 1.0. It should be noted that I +# wouldn't have to do this, if GNU assembler understood .ALLOW 2.0 +# directive... + +my $ldd = sub { + my ($mod,$args) = @_; + my $orig = "ldd$mod\t$args"; + + if ($args =~ /(\-?[0-9]+)\(%r([0-9]+)\),%r([0-9]+)/) # format 3 suffices + { my $opcode=(0x14<<26)|($2<<21)|($3<<16)|(($1&0x1FF8)<<1)|(($1>>13)&1); + $opcode|=(1<<3) if ($mod =~ /^,m/); + $opcode|=(1<<2) if ($mod =~ /^,mb/); + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + else { "\t".$orig; } +}; + +my $std = sub { + my ($mod,$args) = @_; + my $orig = "std$mod\t$args"; + + if ($args =~ /%r([0-9]+),(\-?[0-9]+)\(%r([0-9]+)\)/) # format 3 suffices + { my $opcode=(0x1c<<26)|($3<<21)|($1<<16)|(($2&0x1FF8)<<1)|(($2>>13)&1); + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + else { "\t".$orig; } +}; + +my $extrd = sub { + my ($mod,$args) = @_; + my $orig = "extrd$mod\t$args"; + + # I only have ",u" completer, it's implicitly encoded... + if ($args =~ /%r([0-9]+),([0-9]+),([0-9]+),%r([0-9]+)/) # format 15 + { my $opcode=(0x36<<26)|($1<<21)|($4<<16); + my $len=32-$3; + $opcode |= (($2&0x20)<<6)|(($2&0x1f)<<5); # encode pos + $opcode |= (($len&0x20)<<7)|($len&0x1f); # encode len + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + elsif ($args =~ /%r([0-9]+),%sar,([0-9]+),%r([0-9]+)/) # format 12 + { my $opcode=(0x34<<26)|($1<<21)|($3<<16)|(2<<11)|(1<<9); + my $len=32-$2; + $opcode |= (($len&0x20)<<3)|($len&0x1f); # encode len + $opcode |= (1<<13) if ($mod =~ /,\**=/); + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + else { "\t".$orig; } +}; + +my $shrpd = sub { + my ($mod,$args) = @_; + my $orig = "shrpd$mod\t$args"; + + if ($args =~ /%r([0-9]+),%r([0-9]+),([0-9]+),%r([0-9]+)/) # format 14 + { my $opcode=(0x34<<26)|($2<<21)|($1<<16)|(1<<10)|$4; + my $cpos=63-$3; + $opcode |= (($cpos&0x20)<<6)|(($cpos&0x1f)<<5); # encode sa + sprintf "\t.WORD\t0x%08x\t; %s",$opcode,$orig; + } + elsif ($args =~ /%r([0-9]+),%r([0-9]+),%sar,%r([0-9]+)/) # format 11 + { sprintf "\t.WORD\t0x%08x\t; %s", + (0x34<<26)|($2<<21)|($1<<16)|(1<<9)|$3,$orig; + } + else { "\t".$orig; } +}; + +sub assemble { + my ($mnemonic,$mod,$args)=@_; + my $opcode = eval("\$$mnemonic"); + + ref($opcode) eq 'CODE' ? &$opcode($mod,$args) : "\t$mnemonic$mod\t$args"; +} + +foreach (split("\n",$code)) { + s/\`([^\`]*)\`/eval $1/ge; + + s/shd\s+(%r[0-9]+),(%r[0-9]+),([0-9]+)/ + $3>31 ? sprintf("shd\t%$2,%$1,%d",$3-32) # rotation for >=32 + : sprintf("shd\t%$1,%$2,%d",$3)/e or + # translate made up instructons: _ror, _shr, _align, _shl + s/_ror(\s+)(%r[0-9]+),/ + ($SZ==4 ? "shd" : "shrpd")."$1$2,$2,"/e or + + s/_shr(\s+%r[0-9]+),([0-9]+),/ + $SZ==4 ? sprintf("extru%s,%d,%d,",$1,31-$2,32-$2) + : sprintf("extrd,u%s,%d,%d,",$1,63-$2,64-$2)/e or + + s/_align(\s+%r[0-9]+,%r[0-9]+),/ + ($SZ==4 ? "vshd$1," : "shrpd$1,%sar,")/e or + + s/_shl(\s+%r[0-9]+),([0-9]+),/ + $SIZE_T==4 ? sprintf("zdep%s,%d,%d,",$1,31-$2,32-$2) + : sprintf("depd,z%s,%d,%d,",$1,63-$2,64-$2)/e; + + s/^\s+([a-z]+)([\S]*)\s+([\S]*)/&assemble($1,$2,$3)/e if ($SIZE_T==4); + + s/cmpb,\*/comb,/ if ($SIZE_T==4); + + s/\bbv\b/bve/ if ($SIZE_T==8); + + print $_,"\n"; +} + +close STDOUT; diff --git a/libs/openssl/crypto/sha/asm/sha512-ppc.pl b/libs/openssl/crypto/sha/asm/sha512-ppc.pl new file mode 100755 index 00000000..6b44a68e --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha512-ppc.pl @@ -0,0 +1,460 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# I let hardware handle unaligned input, except on page boundaries +# (see below for details). Otherwise straightforward implementation +# with X vector in register bank. The module is big-endian [which is +# not big deal as there're no little-endian targets left around]. + +# sha256 | sha512 +# -m64 -m32 | -m64 -m32 +# --------------------------------------+----------------------- +# PPC970,gcc-4.0.0 +50% +38% | +40% +410%(*) +# Power6,xlc-7 +150% +90% | +100% +430%(*) +# +# (*) 64-bit code in 32-bit application context, which actually is +# on TODO list. It should be noted that for safe deployment in +# 32-bit *mutli-threaded* context asyncronous signals should be +# blocked upon entry to SHA512 block routine. This is because +# 32-bit signaling procedure invalidates upper halves of GPRs. +# Context switch procedure preserves them, but not signaling:-( + +# Second version is true multi-thread safe. Trouble with the original +# version was that it was using thread local storage pointer register. +# Well, it scrupulously preserved it, but the problem would arise the +# moment asynchronous signal was delivered and signal handler would +# dereference the TLS pointer. While it's never the case in openssl +# application or test suite, we have to respect this scenario and not +# use TLS pointer register. Alternative would be to require caller to +# block signals prior calling this routine. For the record, in 32-bit +# context R2 serves as TLS pointer, while in 64-bit context - R13. + +$flavour=shift; +$output =shift; + +if ($flavour =~ /64/) { + $SIZE_T=8; + $LRSAVE=2*$SIZE_T; + $STU="stdu"; + $UCMP="cmpld"; + $SHL="sldi"; + $POP="ld"; + $PUSH="std"; +} elsif ($flavour =~ /32/) { + $SIZE_T=4; + $LRSAVE=$SIZE_T; + $STU="stwu"; + $UCMP="cmplw"; + $SHL="slwi"; + $POP="lwz"; + $PUSH="stw"; +} else { die "nonsense $flavour"; } + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or +die "can't locate ppc-xlate.pl"; + +open STDOUT,"| $^X $xlate $flavour $output" || die "can't call $xlate: $!"; + +if ($output =~ /512/) { + $func="sha512_block_data_order"; + $SZ=8; + @Sigma0=(28,34,39); + @Sigma1=(14,18,41); + @sigma0=(1, 8, 7); + @sigma1=(19,61, 6); + $rounds=80; + $LD="ld"; + $ST="std"; + $ROR="rotrdi"; + $SHR="srdi"; +} else { + $func="sha256_block_data_order"; + $SZ=4; + @Sigma0=( 2,13,22); + @Sigma1=( 6,11,25); + @sigma0=( 7,18, 3); + @sigma1=(17,19,10); + $rounds=64; + $LD="lwz"; + $ST="stw"; + $ROR="rotrwi"; + $SHR="srwi"; +} + +$FRAME=32*$SIZE_T+16*$SZ; +$LOCALS=6*$SIZE_T; + +$sp ="r1"; +$toc="r2"; +$ctx="r3"; # zapped by $a0 +$inp="r4"; # zapped by $a1 +$num="r5"; # zapped by $t0 + +$T ="r0"; +$a0 ="r3"; +$a1 ="r4"; +$t0 ="r5"; +$t1 ="r6"; +$Tbl="r7"; + +$A ="r8"; +$B ="r9"; +$C ="r10"; +$D ="r11"; +$E ="r12"; +$F ="r13"; $F="r2" if ($SIZE_T==8);# reassigned to exempt TLS pointer +$G ="r14"; +$H ="r15"; + +@V=($A,$B,$C,$D,$E,$F,$G,$H); +@X=("r16","r17","r18","r19","r20","r21","r22","r23", + "r24","r25","r26","r27","r28","r29","r30","r31"); + +$inp="r31"; # reassigned $inp! aliases with @X[15] + +sub ROUND_00_15 { +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; +$code.=<<___; + $LD $T,`$i*$SZ`($Tbl) + $ROR $a0,$e,$Sigma1[0] + $ROR $a1,$e,$Sigma1[1] + and $t0,$f,$e + andc $t1,$g,$e + add $T,$T,$h + xor $a0,$a0,$a1 + $ROR $a1,$a1,`$Sigma1[2]-$Sigma1[1]` + or $t0,$t0,$t1 ; Ch(e,f,g) + add $T,$T,@X[$i] + xor $a0,$a0,$a1 ; Sigma1(e) + add $T,$T,$t0 + add $T,$T,$a0 + + $ROR $a0,$a,$Sigma0[0] + $ROR $a1,$a,$Sigma0[1] + and $t0,$a,$b + and $t1,$a,$c + xor $a0,$a0,$a1 + $ROR $a1,$a1,`$Sigma0[2]-$Sigma0[1]` + xor $t0,$t0,$t1 + and $t1,$b,$c + xor $a0,$a0,$a1 ; Sigma0(a) + add $d,$d,$T + xor $t0,$t0,$t1 ; Maj(a,b,c) + add $h,$T,$a0 + add $h,$h,$t0 + +___ +} + +sub ROUND_16_xx { +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; +$i-=16; +$code.=<<___; + $ROR $a0,@X[($i+1)%16],$sigma0[0] + $ROR $a1,@X[($i+1)%16],$sigma0[1] + $ROR $t0,@X[($i+14)%16],$sigma1[0] + $ROR $t1,@X[($i+14)%16],$sigma1[1] + xor $a0,$a0,$a1 + $SHR $a1,@X[($i+1)%16],$sigma0[2] + xor $t0,$t0,$t1 + $SHR $t1,@X[($i+14)%16],$sigma1[2] + add @X[$i],@X[$i],@X[($i+9)%16] + xor $a0,$a0,$a1 ; sigma0(X[(i+1)&0x0f]) + xor $t0,$t0,$t1 ; sigma1(X[(i+14)&0x0f]) + add @X[$i],@X[$i],$a0 + add @X[$i],@X[$i],$t0 +___ +&ROUND_00_15($i,$a,$b,$c,$d,$e,$f,$g,$h); +} + +$code=<<___; +.machine "any" +.text + +.globl $func +.align 6 +$func: + $STU $sp,-$FRAME($sp) + mflr r0 + $SHL $num,$num,`log(16*$SZ)/log(2)` + + $PUSH $ctx,`$FRAME-$SIZE_T*22`($sp) + + $PUSH $toc,`$FRAME-$SIZE_T*20`($sp) + $PUSH r13,`$FRAME-$SIZE_T*19`($sp) + $PUSH r14,`$FRAME-$SIZE_T*18`($sp) + $PUSH r15,`$FRAME-$SIZE_T*17`($sp) + $PUSH r16,`$FRAME-$SIZE_T*16`($sp) + $PUSH r17,`$FRAME-$SIZE_T*15`($sp) + $PUSH r18,`$FRAME-$SIZE_T*14`($sp) + $PUSH r19,`$FRAME-$SIZE_T*13`($sp) + $PUSH r20,`$FRAME-$SIZE_T*12`($sp) + $PUSH r21,`$FRAME-$SIZE_T*11`($sp) + $PUSH r22,`$FRAME-$SIZE_T*10`($sp) + $PUSH r23,`$FRAME-$SIZE_T*9`($sp) + $PUSH r24,`$FRAME-$SIZE_T*8`($sp) + $PUSH r25,`$FRAME-$SIZE_T*7`($sp) + $PUSH r26,`$FRAME-$SIZE_T*6`($sp) + $PUSH r27,`$FRAME-$SIZE_T*5`($sp) + $PUSH r28,`$FRAME-$SIZE_T*4`($sp) + $PUSH r29,`$FRAME-$SIZE_T*3`($sp) + $PUSH r30,`$FRAME-$SIZE_T*2`($sp) + $PUSH r31,`$FRAME-$SIZE_T*1`($sp) + $PUSH r0,`$FRAME+$LRSAVE`($sp) + + $LD $A,`0*$SZ`($ctx) + mr $inp,r4 ; incarnate $inp + $LD $B,`1*$SZ`($ctx) + $LD $C,`2*$SZ`($ctx) + $LD $D,`3*$SZ`($ctx) + $LD $E,`4*$SZ`($ctx) + $LD $F,`5*$SZ`($ctx) + $LD $G,`6*$SZ`($ctx) + $LD $H,`7*$SZ`($ctx) + + bl LPICmeup +LPICedup: + andi. r0,$inp,3 + bne Lunaligned +Laligned: + add $num,$inp,$num + $PUSH $num,`$FRAME-$SIZE_T*24`($sp) ; end pointer + $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer + bl Lsha2_block_private + b Ldone + +; PowerPC specification allows an implementation to be ill-behaved +; upon unaligned access which crosses page boundary. "Better safe +; than sorry" principle makes me treat it specially. But I don't +; look for particular offending word, but rather for the input +; block which crosses the boundary. Once found that block is aligned +; and hashed separately... +.align 4 +Lunaligned: + subfic $t1,$inp,4096 + andi. $t1,$t1,`4096-16*$SZ` ; distance to closest page boundary + beq Lcross_page + $UCMP $num,$t1 + ble- Laligned ; didn't cross the page boundary + subfc $num,$t1,$num + add $t1,$inp,$t1 + $PUSH $num,`$FRAME-$SIZE_T*25`($sp) ; save real remaining num + $PUSH $t1,`$FRAME-$SIZE_T*24`($sp) ; intermediate end pointer + $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer + bl Lsha2_block_private + ; $inp equals to the intermediate end pointer here + $POP $num,`$FRAME-$SIZE_T*25`($sp) ; restore real remaining num +Lcross_page: + li $t1,`16*$SZ/4` + mtctr $t1 + addi r20,$sp,$LOCALS ; aligned spot below the frame +Lmemcpy: + lbz r16,0($inp) + lbz r17,1($inp) + lbz r18,2($inp) + lbz r19,3($inp) + addi $inp,$inp,4 + stb r16,0(r20) + stb r17,1(r20) + stb r18,2(r20) + stb r19,3(r20) + addi r20,r20,4 + bdnz Lmemcpy + + $PUSH $inp,`$FRAME-$SIZE_T*26`($sp) ; save real inp + addi $t1,$sp,`$LOCALS+16*$SZ` ; fictitious end pointer + addi $inp,$sp,$LOCALS ; fictitious inp pointer + $PUSH $num,`$FRAME-$SIZE_T*25`($sp) ; save real num + $PUSH $t1,`$FRAME-$SIZE_T*24`($sp) ; end pointer + $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer + bl Lsha2_block_private + $POP $inp,`$FRAME-$SIZE_T*26`($sp) ; restore real inp + $POP $num,`$FRAME-$SIZE_T*25`($sp) ; restore real num + addic. $num,$num,`-16*$SZ` ; num-- + bne- Lunaligned + +Ldone: + $POP r0,`$FRAME+$LRSAVE`($sp) + $POP $toc,`$FRAME-$SIZE_T*20`($sp) + $POP r13,`$FRAME-$SIZE_T*19`($sp) + $POP r14,`$FRAME-$SIZE_T*18`($sp) + $POP r15,`$FRAME-$SIZE_T*17`($sp) + $POP r16,`$FRAME-$SIZE_T*16`($sp) + $POP r17,`$FRAME-$SIZE_T*15`($sp) + $POP r18,`$FRAME-$SIZE_T*14`($sp) + $POP r19,`$FRAME-$SIZE_T*13`($sp) + $POP r20,`$FRAME-$SIZE_T*12`($sp) + $POP r21,`$FRAME-$SIZE_T*11`($sp) + $POP r22,`$FRAME-$SIZE_T*10`($sp) + $POP r23,`$FRAME-$SIZE_T*9`($sp) + $POP r24,`$FRAME-$SIZE_T*8`($sp) + $POP r25,`$FRAME-$SIZE_T*7`($sp) + $POP r26,`$FRAME-$SIZE_T*6`($sp) + $POP r27,`$FRAME-$SIZE_T*5`($sp) + $POP r28,`$FRAME-$SIZE_T*4`($sp) + $POP r29,`$FRAME-$SIZE_T*3`($sp) + $POP r30,`$FRAME-$SIZE_T*2`($sp) + $POP r31,`$FRAME-$SIZE_T*1`($sp) + mtlr r0 + addi $sp,$sp,$FRAME + blr + .long 0 + .byte 0,12,4,1,0x80,18,3,0 + .long 0 + +.align 4 +Lsha2_block_private: +___ +for($i=0;$i<16;$i++) { +$code.=<<___ if ($SZ==4); + lwz @X[$i],`$i*$SZ`($inp) +___ +# 64-bit loads are split to 2x32-bit ones, as CPU can't handle +# unaligned 64-bit loads, only 32-bit ones... +$code.=<<___ if ($SZ==8); + lwz $t0,`$i*$SZ`($inp) + lwz @X[$i],`$i*$SZ+4`($inp) + insrdi @X[$i],$t0,32,0 +___ + &ROUND_00_15($i,@V); + unshift(@V,pop(@V)); +} +$code.=<<___; + li $T,`$rounds/16-1` + mtctr $T +.align 4 +Lrounds: + addi $Tbl,$Tbl,`16*$SZ` +___ +for(;$i<32;$i++) { + &ROUND_16_xx($i,@V); + unshift(@V,pop(@V)); +} +$code.=<<___; + bdnz- Lrounds + + $POP $ctx,`$FRAME-$SIZE_T*22`($sp) + $POP $inp,`$FRAME-$SIZE_T*23`($sp) ; inp pointer + $POP $num,`$FRAME-$SIZE_T*24`($sp) ; end pointer + subi $Tbl,$Tbl,`($rounds-16)*$SZ` ; rewind Tbl + + $LD r16,`0*$SZ`($ctx) + $LD r17,`1*$SZ`($ctx) + $LD r18,`2*$SZ`($ctx) + $LD r19,`3*$SZ`($ctx) + $LD r20,`4*$SZ`($ctx) + $LD r21,`5*$SZ`($ctx) + $LD r22,`6*$SZ`($ctx) + addi $inp,$inp,`16*$SZ` ; advance inp + $LD r23,`7*$SZ`($ctx) + add $A,$A,r16 + add $B,$B,r17 + $PUSH $inp,`$FRAME-$SIZE_T*23`($sp) + add $C,$C,r18 + $ST $A,`0*$SZ`($ctx) + add $D,$D,r19 + $ST $B,`1*$SZ`($ctx) + add $E,$E,r20 + $ST $C,`2*$SZ`($ctx) + add $F,$F,r21 + $ST $D,`3*$SZ`($ctx) + add $G,$G,r22 + $ST $E,`4*$SZ`($ctx) + add $H,$H,r23 + $ST $F,`5*$SZ`($ctx) + $ST $G,`6*$SZ`($ctx) + $UCMP $inp,$num + $ST $H,`7*$SZ`($ctx) + bne Lsha2_block_private + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 +___ + +# Ugly hack here, because PPC assembler syntax seem to vary too +# much from platforms to platform... +$code.=<<___; +.align 6 +LPICmeup: + mflr r0 + bcl 20,31,\$+4 + mflr $Tbl ; vvvvvv "distance" between . and 1st data entry + addi $Tbl,$Tbl,`64-8` + mtlr r0 + blr + .long 0 + .byte 0,12,0x14,0,0,0,0,0 + .space `64-9*4` +___ +$code.=<<___ if ($SZ==8); + .long 0x428a2f98,0xd728ae22,0x71374491,0x23ef65cd + .long 0xb5c0fbcf,0xec4d3b2f,0xe9b5dba5,0x8189dbbc + .long 0x3956c25b,0xf348b538,0x59f111f1,0xb605d019 + .long 0x923f82a4,0xaf194f9b,0xab1c5ed5,0xda6d8118 + .long 0xd807aa98,0xa3030242,0x12835b01,0x45706fbe + .long 0x243185be,0x4ee4b28c,0x550c7dc3,0xd5ffb4e2 + .long 0x72be5d74,0xf27b896f,0x80deb1fe,0x3b1696b1 + .long 0x9bdc06a7,0x25c71235,0xc19bf174,0xcf692694 + .long 0xe49b69c1,0x9ef14ad2,0xefbe4786,0x384f25e3 + .long 0x0fc19dc6,0x8b8cd5b5,0x240ca1cc,0x77ac9c65 + .long 0x2de92c6f,0x592b0275,0x4a7484aa,0x6ea6e483 + .long 0x5cb0a9dc,0xbd41fbd4,0x76f988da,0x831153b5 + .long 0x983e5152,0xee66dfab,0xa831c66d,0x2db43210 + .long 0xb00327c8,0x98fb213f,0xbf597fc7,0xbeef0ee4 + .long 0xc6e00bf3,0x3da88fc2,0xd5a79147,0x930aa725 + .long 0x06ca6351,0xe003826f,0x14292967,0x0a0e6e70 + .long 0x27b70a85,0x46d22ffc,0x2e1b2138,0x5c26c926 + .long 0x4d2c6dfc,0x5ac42aed,0x53380d13,0x9d95b3df + .long 0x650a7354,0x8baf63de,0x766a0abb,0x3c77b2a8 + .long 0x81c2c92e,0x47edaee6,0x92722c85,0x1482353b + .long 0xa2bfe8a1,0x4cf10364,0xa81a664b,0xbc423001 + .long 0xc24b8b70,0xd0f89791,0xc76c51a3,0x0654be30 + .long 0xd192e819,0xd6ef5218,0xd6990624,0x5565a910 + .long 0xf40e3585,0x5771202a,0x106aa070,0x32bbd1b8 + .long 0x19a4c116,0xb8d2d0c8,0x1e376c08,0x5141ab53 + .long 0x2748774c,0xdf8eeb99,0x34b0bcb5,0xe19b48a8 + .long 0x391c0cb3,0xc5c95a63,0x4ed8aa4a,0xe3418acb + .long 0x5b9cca4f,0x7763e373,0x682e6ff3,0xd6b2b8a3 + .long 0x748f82ee,0x5defb2fc,0x78a5636f,0x43172f60 + .long 0x84c87814,0xa1f0ab72,0x8cc70208,0x1a6439ec + .long 0x90befffa,0x23631e28,0xa4506ceb,0xde82bde9 + .long 0xbef9a3f7,0xb2c67915,0xc67178f2,0xe372532b + .long 0xca273ece,0xea26619c,0xd186b8c7,0x21c0c207 + .long 0xeada7dd6,0xcde0eb1e,0xf57d4f7f,0xee6ed178 + .long 0x06f067aa,0x72176fba,0x0a637dc5,0xa2c898a6 + .long 0x113f9804,0xbef90dae,0x1b710b35,0x131c471b + .long 0x28db77f5,0x23047d84,0x32caab7b,0x40c72493 + .long 0x3c9ebe0a,0x15c9bebc,0x431d67c4,0x9c100d4c + .long 0x4cc5d4be,0xcb3e42b6,0x597f299c,0xfc657e2a + .long 0x5fcb6fab,0x3ad6faec,0x6c44198c,0x4a475817 +___ +$code.=<<___ if ($SZ==4); + .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 + .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 + .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 + .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 + .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc + .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da + .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 + .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 + .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 + .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 + .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 + .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 + .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 + .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 + .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 + .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/sha/asm/sha512-s390x.pl b/libs/openssl/crypto/sha/asm/sha512-s390x.pl new file mode 100644 index 00000000..079a3fc7 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha512-s390x.pl @@ -0,0 +1,322 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# SHA256/512 block procedures for s390x. + +# April 2007. +# +# sha256_block_data_order is reportedly >3 times faster than gcc 3.3 +# generated code (must be a bug in compiler, as improvement is +# "pathologically" high, in particular in comparison to other SHA +# modules). But the real twist is that it detects if hardware support +# for SHA256 is available and in such case utilizes it. Then the +# performance can reach >6.5x of assembler one for larger chunks. +# +# sha512_block_data_order is ~70% faster than gcc 3.3 generated code. + +# January 2009. +# +# Add support for hardware SHA512 and reschedule instructions to +# favour dual-issue z10 pipeline. Hardware SHA256/512 is ~4.7x faster +# than software. + +# November 2010. +# +# Adapt for -m31 build. If kernel supports what's called "highgprs" +# feature on Linux [see /proc/cpuinfo], it's possible to use 64-bit +# instructions and achieve "64-bit" performance even in 31-bit legacy +# application context. The feature is not specific to any particular +# processor, as long as it's "z-CPU". Latter implies that the code +# remains z/Architecture specific. On z900 SHA256 was measured to +# perform 2.4x and SHA512 - 13x better than code generated by gcc 4.3. + +$flavour = shift; + +if ($flavour =~ /3[12]/) { + $SIZE_T=4; + $g=""; +} else { + $SIZE_T=8; + $g="g"; +} + +$t0="%r0"; +$t1="%r1"; +$ctx="%r2"; $t2="%r2"; +$inp="%r3"; +$len="%r4"; # used as index in inner loop + +$A="%r5"; +$B="%r6"; +$C="%r7"; +$D="%r8"; +$E="%r9"; +$F="%r10"; +$G="%r11"; +$H="%r12"; @V=($A,$B,$C,$D,$E,$F,$G,$H); +$tbl="%r13"; +$T1="%r14"; +$sp="%r15"; + +while (($output=shift) && ($output!~/^\w[\w\-]*\.\w+$/)) {} +open STDOUT,">$output"; + +if ($output =~ /512/) { + $label="512"; + $SZ=8; + $LD="lg"; # load from memory + $ST="stg"; # store to memory + $ADD="alg"; # add with memory operand + $ROT="rllg"; # rotate left + $SHR="srlg"; # logical right shift [see even at the end] + @Sigma0=(25,30,36); + @Sigma1=(23,46,50); + @sigma0=(56,63, 7); + @sigma1=( 3,45, 6); + $rounds=80; + $kimdfunc=3; # 0 means unknown/unsupported/unimplemented/disabled +} else { + $label="256"; + $SZ=4; + $LD="llgf"; # load from memory + $ST="st"; # store to memory + $ADD="al"; # add with memory operand + $ROT="rll"; # rotate left + $SHR="srl"; # logical right shift + @Sigma0=(10,19,30); + @Sigma1=( 7,21,26); + @sigma0=(14,25, 3); + @sigma1=(13,15,10); + $rounds=64; + $kimdfunc=2; # magic function code for kimd instruction +} +$Func="sha${label}_block_data_order"; +$Table="K${label}"; +$stdframe=16*$SIZE_T+4*8; +$frame=$stdframe+16*$SZ; + +sub BODY_00_15 { +my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_; + +$code.=<<___ if ($i<16); + $LD $T1,`$i*$SZ`($inp) ### $i +___ +$code.=<<___; + $ROT $t0,$e,$Sigma1[0] + $ROT $t1,$e,$Sigma1[1] + lgr $t2,$f + xgr $t0,$t1 + $ROT $t1,$t1,`$Sigma1[2]-$Sigma1[1]` + xgr $t2,$g + $ST $T1,`$stdframe+$SZ*($i%16)`($sp) + xgr $t0,$t1 # Sigma1(e) + algr $T1,$h # T1+=h + ngr $t2,$e + lgr $t1,$a + algr $T1,$t0 # T1+=Sigma1(e) + $ROT $h,$a,$Sigma0[0] + xgr $t2,$g # Ch(e,f,g) + $ADD $T1,`$i*$SZ`($len,$tbl) # T1+=K[i] + $ROT $t0,$a,$Sigma0[1] + algr $T1,$t2 # T1+=Ch(e,f,g) + ogr $t1,$b + xgr $h,$t0 + lgr $t2,$a + ngr $t1,$c + $ROT $t0,$t0,`$Sigma0[2]-$Sigma0[1]` + xgr $h,$t0 # h=Sigma0(a) + ngr $t2,$b + algr $h,$T1 # h+=T1 + ogr $t2,$t1 # Maj(a,b,c) + algr $d,$T1 # d+=T1 + algr $h,$t2 # h+=Maj(a,b,c) +___ +} + +sub BODY_16_XX { +my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_; + +$code.=<<___; + $LD $T1,`$stdframe+$SZ*(($i+1)%16)`($sp) ### $i + $LD $t1,`$stdframe+$SZ*(($i+14)%16)`($sp) + $ROT $t0,$T1,$sigma0[0] + $SHR $T1,$sigma0[2] + $ROT $t2,$t0,`$sigma0[1]-$sigma0[0]` + xgr $T1,$t0 + $ROT $t0,$t1,$sigma1[0] + xgr $T1,$t2 # sigma0(X[i+1]) + $SHR $t1,$sigma1[2] + $ADD $T1,`$stdframe+$SZ*($i%16)`($sp) # +=X[i] + xgr $t1,$t0 + $ROT $t0,$t0,`$sigma1[1]-$sigma1[0]` + $ADD $T1,`$stdframe+$SZ*(($i+9)%16)`($sp) # +=X[i+9] + xgr $t1,$t0 # sigma1(X[i+14]) + algr $T1,$t1 # +=sigma1(X[i+14]) +___ + &BODY_00_15(@_); +} + +$code.=<<___; +.text +.align 64 +.type $Table,\@object +$Table: +___ +$code.=<<___ if ($SZ==4); + .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 + .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 + .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 + .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 + .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc + .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da + .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 + .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 + .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 + .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 + .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 + .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 + .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 + .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 + .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 + .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +___ +$code.=<<___ if ($SZ==8); + .quad 0x428a2f98d728ae22,0x7137449123ef65cd + .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc + .quad 0x3956c25bf348b538,0x59f111f1b605d019 + .quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 + .quad 0xd807aa98a3030242,0x12835b0145706fbe + .quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 + .quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 + .quad 0x9bdc06a725c71235,0xc19bf174cf692694 + .quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 + .quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 + .quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 + .quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 + .quad 0x983e5152ee66dfab,0xa831c66d2db43210 + .quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 + .quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 + .quad 0x06ca6351e003826f,0x142929670a0e6e70 + .quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 + .quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df + .quad 0x650a73548baf63de,0x766a0abb3c77b2a8 + .quad 0x81c2c92e47edaee6,0x92722c851482353b + .quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 + .quad 0xc24b8b70d0f89791,0xc76c51a30654be30 + .quad 0xd192e819d6ef5218,0xd69906245565a910 + .quad 0xf40e35855771202a,0x106aa07032bbd1b8 + .quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 + .quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 + .quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb + .quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 + .quad 0x748f82ee5defb2fc,0x78a5636f43172f60 + .quad 0x84c87814a1f0ab72,0x8cc702081a6439ec + .quad 0x90befffa23631e28,0xa4506cebde82bde9 + .quad 0xbef9a3f7b2c67915,0xc67178f2e372532b + .quad 0xca273eceea26619c,0xd186b8c721c0c207 + .quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 + .quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 + .quad 0x113f9804bef90dae,0x1b710b35131c471b + .quad 0x28db77f523047d84,0x32caab7b40c72493 + .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c + .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a + .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 +___ +$code.=<<___; +.size $Table,.-$Table +.globl $Func +.type $Func,\@function +$Func: + sllg $len,$len,`log(16*$SZ)/log(2)` +___ +$code.=<<___ if ($kimdfunc); + larl %r1,OPENSSL_s390xcap_P + lg %r0,0(%r1) + tmhl %r0,0x4000 # check for message-security assist + jz .Lsoftware + lghi %r0,0 + la %r1,`2*$SIZE_T`($sp) + .long 0xb93e0002 # kimd %r0,%r2 + lg %r0,`2*$SIZE_T`($sp) + tmhh %r0,`0x8000>>$kimdfunc` + jz .Lsoftware + lghi %r0,$kimdfunc + lgr %r1,$ctx + lgr %r2,$inp + lgr %r3,$len + .long 0xb93e0002 # kimd %r0,%r2 + brc 1,.-4 # pay attention to "partial completion" + br %r14 +.align 16 +.Lsoftware: +___ +$code.=<<___; + lghi %r1,-$frame + la $len,0($len,$inp) + stm${g} $ctx,%r15,`2*$SIZE_T`($sp) + lgr %r0,$sp + la $sp,0(%r1,$sp) + st${g} %r0,0($sp) + + larl $tbl,$Table + $LD $A,`0*$SZ`($ctx) + $LD $B,`1*$SZ`($ctx) + $LD $C,`2*$SZ`($ctx) + $LD $D,`3*$SZ`($ctx) + $LD $E,`4*$SZ`($ctx) + $LD $F,`5*$SZ`($ctx) + $LD $G,`6*$SZ`($ctx) + $LD $H,`7*$SZ`($ctx) + +.Lloop: + lghi $len,0 +___ +for ($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); } +$code.=".Lrounds_16_xx:\n"; +for (;$i<32;$i++) { &BODY_16_XX($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + aghi $len,`16*$SZ` + lghi $t0,`($rounds-16)*$SZ` + clgr $len,$t0 + jne .Lrounds_16_xx + + l${g} $ctx,`$frame+2*$SIZE_T`($sp) + la $inp,`16*$SZ`($inp) + $ADD $A,`0*$SZ`($ctx) + $ADD $B,`1*$SZ`($ctx) + $ADD $C,`2*$SZ`($ctx) + $ADD $D,`3*$SZ`($ctx) + $ADD $E,`4*$SZ`($ctx) + $ADD $F,`5*$SZ`($ctx) + $ADD $G,`6*$SZ`($ctx) + $ADD $H,`7*$SZ`($ctx) + $ST $A,`0*$SZ`($ctx) + $ST $B,`1*$SZ`($ctx) + $ST $C,`2*$SZ`($ctx) + $ST $D,`3*$SZ`($ctx) + $ST $E,`4*$SZ`($ctx) + $ST $F,`5*$SZ`($ctx) + $ST $G,`6*$SZ`($ctx) + $ST $H,`7*$SZ`($ctx) + cl${g} $inp,`$frame+4*$SIZE_T`($sp) + jne .Lloop + + lm${g} %r6,%r15,`$frame+6*$SIZE_T`($sp) + br %r14 +.size $Func,.-$Func +.string "SHA${label} block transform for s390x, CRYPTOGAMS by " +.comm OPENSSL_s390xcap_P,16,8 +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +# unlike 32-bit shift 64-bit one takes three arguments +$code =~ s/(srlg\s+)(%r[0-9]+),/$1$2,$2,/gm; + +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/sha/asm/sha512-sparcv9.pl b/libs/openssl/crypto/sha/asm/sha512-sparcv9.pl new file mode 100644 index 00000000..58574078 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha512-sparcv9.pl @@ -0,0 +1,594 @@ +#!/usr/bin/env perl + +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. The module is, however, dual licensed under OpenSSL and +# CRYPTOGAMS licenses depending on where you obtain it. For further +# details see http://www.openssl.org/~appro/cryptogams/. +# ==================================================================== + +# SHA256 performance improvement over compiler generated code varies +# from 40% for Sun C [32-bit build] to 70% for gcc [3.3, 64-bit +# build]. Just like in SHA1 module I aim to ensure scalability on +# UltraSPARC T1 by packing X[16] to 8 64-bit registers. + +# SHA512 on pre-T1 UltraSPARC. +# +# Performance is >75% better than 64-bit code generated by Sun C and +# over 2x than 32-bit code. X[16] resides on stack, but access to it +# is scheduled for L2 latency and staged through 32 least significant +# bits of %l0-%l7. The latter is done to achieve 32-/64-bit ABI +# duality. Nevetheless it's ~40% faster than SHA256, which is pretty +# good [optimal coefficient is 50%]. +# +# SHA512 on UltraSPARC T1. +# +# It's not any faster than 64-bit code generated by Sun C 5.8. This is +# because 64-bit code generator has the advantage of using 64-bit +# loads(*) to access X[16], which I consciously traded for 32-/64-bit +# ABI duality [as per above]. But it surpasses 32-bit Sun C generated +# code by 60%, not to mention that it doesn't suffer from severe decay +# when running 4 times physical cores threads and that it leaves gcc +# [3.4] behind by over 4x factor! If compared to SHA256, single thread +# performance is only 10% better, but overall throughput for maximum +# amount of threads for given CPU exceeds corresponding one of SHA256 +# by 30% [again, optimal coefficient is 50%]. +# +# (*) Unlike pre-T1 UltraSPARC loads on T1 are executed strictly +# in-order, i.e. load instruction has to complete prior next +# instruction in given thread is executed, even if the latter is +# not dependent on load result! This means that on T1 two 32-bit +# loads are always slower than one 64-bit load. Once again this +# is unlike pre-T1 UltraSPARC, where, if scheduled appropriately, +# 2x32-bit loads can be as fast as 1x64-bit ones. + +$bits=32; +for (@ARGV) { $bits=64 if (/\-m64/ || /\-xarch\=v9/); } +if ($bits==64) { $bias=2047; $frame=192; } +else { $bias=0; $frame=112; } + +$output=shift; +open STDOUT,">$output"; + +if ($output =~ /512/) { + $label="512"; + $SZ=8; + $LD="ldx"; # load from memory + $ST="stx"; # store to memory + $SLL="sllx"; # shift left logical + $SRL="srlx"; # shift right logical + @Sigma0=(28,34,39); + @Sigma1=(14,18,41); + @sigma0=( 7, 1, 8); # right shift first + @sigma1=( 6,19,61); # right shift first + $lastK=0x817; + $rounds=80; + $align=4; + + $locals=16*$SZ; # X[16] + + $A="%o0"; + $B="%o1"; + $C="%o2"; + $D="%o3"; + $E="%o4"; + $F="%o5"; + $G="%g1"; + $H="%o7"; + @V=($A,$B,$C,$D,$E,$F,$G,$H); +} else { + $label="256"; + $SZ=4; + $LD="ld"; # load from memory + $ST="st"; # store to memory + $SLL="sll"; # shift left logical + $SRL="srl"; # shift right logical + @Sigma0=( 2,13,22); + @Sigma1=( 6,11,25); + @sigma0=( 3, 7,18); # right shift first + @sigma1=(10,17,19); # right shift first + $lastK=0x8f2; + $rounds=64; + $align=8; + + $locals=0; # X[16] is register resident + @X=("%o0","%o1","%o2","%o3","%o4","%o5","%g1","%o7"); + + $A="%l0"; + $B="%l1"; + $C="%l2"; + $D="%l3"; + $E="%l4"; + $F="%l5"; + $G="%l6"; + $H="%l7"; + @V=($A,$B,$C,$D,$E,$F,$G,$H); +} +$T1="%g2"; +$tmp0="%g3"; +$tmp1="%g4"; +$tmp2="%g5"; + +$ctx="%i0"; +$inp="%i1"; +$len="%i2"; +$Ktbl="%i3"; +$tmp31="%i4"; +$tmp32="%i5"; + +########### SHA256 +$Xload = sub { +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; + + if ($i==0) { +$code.=<<___; + ldx [$inp+0],@X[0] + ldx [$inp+16],@X[2] + ldx [$inp+32],@X[4] + ldx [$inp+48],@X[6] + ldx [$inp+8],@X[1] + ldx [$inp+24],@X[3] + subcc %g0,$tmp31,$tmp32 ! should be 64-$tmp31, but -$tmp31 works too + ldx [$inp+40],@X[5] + bz,pt %icc,.Laligned + ldx [$inp+56],@X[7] + + sllx @X[0],$tmp31,@X[0] + ldx [$inp+64],$T1 +___ +for($j=0;$j<7;$j++) +{ $code.=<<___; + srlx @X[$j+1],$tmp32,$tmp1 + sllx @X[$j+1],$tmp31,@X[$j+1] + or $tmp1,@X[$j],@X[$j] +___ +} +$code.=<<___; + srlx $T1,$tmp32,$T1 + or $T1,@X[7],@X[7] +.Laligned: +___ + } + + if ($i&1) { + $code.="\tadd @X[$i/2],$h,$T1\n"; + } else { + $code.="\tsrlx @X[$i/2],32,$T1\n\tadd $h,$T1,$T1\n"; + } +} if ($SZ==4); + +########### SHA512 +$Xload = sub { +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; +my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1),"%l".eval((($i+1)*2)%8)); + +$code.=<<___ if ($i==0); + ld [$inp+0],%l0 + ld [$inp+4],%l1 + ld [$inp+8],%l2 + ld [$inp+12],%l3 + ld [$inp+16],%l4 + ld [$inp+20],%l5 + ld [$inp+24],%l6 + ld [$inp+28],%l7 +___ +$code.=<<___ if ($i<15); + sllx @pair[1],$tmp31,$tmp2 ! Xload($i) + add $tmp31,32,$tmp0 + sllx @pair[0],$tmp0,$tmp1 + `"ld [$inp+".eval(32+0+$i*8)."],@pair[0]" if ($i<12)` + srlx @pair[2],$tmp32,@pair[1] + or $tmp1,$tmp2,$tmp2 + or @pair[1],$tmp2,$tmp2 + `"ld [$inp+".eval(32+4+$i*8)."],@pair[1]" if ($i<12)` + add $h,$tmp2,$T1 + $ST $tmp2,[%sp+`$bias+$frame+$i*$SZ`] +___ +$code.=<<___ if ($i==12); + brnz,a $tmp31,.+8 + ld [$inp+128],%l0 +___ +$code.=<<___ if ($i==15); + ld [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+0`],%l2 + sllx @pair[1],$tmp31,$tmp2 ! Xload($i) + add $tmp31,32,$tmp0 + ld [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+4`],%l3 + sllx @pair[0],$tmp0,$tmp1 + ld [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+0`],%l4 + srlx @pair[2],$tmp32,@pair[1] + or $tmp1,$tmp2,$tmp2 + ld [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+4`],%l5 + or @pair[1],$tmp2,$tmp2 + ld [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+0`],%l6 + add $h,$tmp2,$T1 + $ST $tmp2,[%sp+`$bias+$frame+$i*$SZ`] + ld [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+4`],%l7 + ld [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+0`],%l0 + ld [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+4`],%l1 +___ +} if ($SZ==8); + +########### common +sub BODY_00_15 { +my ($i,$a,$b,$c,$d,$e,$f,$g,$h)=@_; + + if ($i<16) { + &$Xload(@_); + } else { + $code.="\tadd $h,$T1,$T1\n"; + } + +$code.=<<___; + $SRL $e,@Sigma1[0],$h !! $i + xor $f,$g,$tmp2 + $SLL $e,`$SZ*8-@Sigma1[2]`,$tmp1 + and $e,$tmp2,$tmp2 + $SRL $e,@Sigma1[1],$tmp0 + xor $tmp1,$h,$h + $SLL $e,`$SZ*8-@Sigma1[1]`,$tmp1 + xor $tmp0,$h,$h + $SRL $e,@Sigma1[2],$tmp0 + xor $tmp1,$h,$h + $SLL $e,`$SZ*8-@Sigma1[0]`,$tmp1 + xor $tmp0,$h,$h + xor $g,$tmp2,$tmp2 ! Ch(e,f,g) + xor $tmp1,$h,$tmp0 ! Sigma1(e) + + $SRL $a,@Sigma0[0],$h + add $tmp2,$T1,$T1 + $LD [$Ktbl+`$i*$SZ`],$tmp2 ! K[$i] + $SLL $a,`$SZ*8-@Sigma0[2]`,$tmp1 + add $tmp0,$T1,$T1 + $SRL $a,@Sigma0[1],$tmp0 + xor $tmp1,$h,$h + $SLL $a,`$SZ*8-@Sigma0[1]`,$tmp1 + xor $tmp0,$h,$h + $SRL $a,@Sigma0[2],$tmp0 + xor $tmp1,$h,$h + $SLL $a,`$SZ*8-@Sigma0[0]`,$tmp1 + xor $tmp0,$h,$h + xor $tmp1,$h,$h ! Sigma0(a) + + or $a,$b,$tmp0 + and $a,$b,$tmp1 + and $c,$tmp0,$tmp0 + or $tmp0,$tmp1,$tmp1 ! Maj(a,b,c) + add $tmp2,$T1,$T1 ! +=K[$i] + add $tmp1,$h,$h + + add $T1,$d,$d + add $T1,$h,$h +___ +} + +########### SHA256 +$BODY_16_XX = sub { +my $i=@_[0]; +my $xi; + + if ($i&1) { + $xi=$tmp32; + $code.="\tsrlx @X[(($i+1)/2)%8],32,$xi\n"; + } else { + $xi=@X[(($i+1)/2)%8]; + } +$code.=<<___; + srl $xi,@sigma0[0],$T1 !! Xupdate($i) + sll $xi,`32-@sigma0[2]`,$tmp1 + srl $xi,@sigma0[1],$tmp0 + xor $tmp1,$T1,$T1 + sll $tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1 + xor $tmp0,$T1,$T1 + srl $xi,@sigma0[2],$tmp0 + xor $tmp1,$T1,$T1 +___ + if ($i&1) { + $xi=@X[(($i+14)/2)%8]; + } else { + $xi=$tmp32; + $code.="\tsrlx @X[(($i+14)/2)%8],32,$xi\n"; + } +$code.=<<___; + srl $xi,@sigma1[0],$tmp2 + xor $tmp0,$T1,$T1 ! T1=sigma0(X[i+1]) + sll $xi,`32-@sigma1[2]`,$tmp1 + srl $xi,@sigma1[1],$tmp0 + xor $tmp1,$tmp2,$tmp2 + sll $tmp1,`@sigma1[2]-@sigma1[1]`,$tmp1 + xor $tmp0,$tmp2,$tmp2 + srl $xi,@sigma1[2],$tmp0 + xor $tmp1,$tmp2,$tmp2 +___ + if ($i&1) { + $xi=@X[($i/2)%8]; +$code.=<<___; + srlx @X[(($i+9)/2)%8],32,$tmp1 ! X[i+9] + xor $tmp0,$tmp2,$tmp2 ! sigma1(X[i+14]) + srl @X[($i/2)%8],0,$tmp0 + add $tmp2,$tmp1,$tmp1 + add $xi,$T1,$T1 ! +=X[i] + xor $tmp0,@X[($i/2)%8],@X[($i/2)%8] + add $tmp1,$T1,$T1 + + srl $T1,0,$T1 + or $T1,@X[($i/2)%8],@X[($i/2)%8] +___ + } else { + $xi=@X[(($i+9)/2)%8]; +$code.=<<___; + srlx @X[($i/2)%8],32,$tmp1 ! X[i] + xor $tmp0,$tmp2,$tmp2 ! sigma1(X[i+14]) + add $xi,$T1,$T1 ! +=X[i+9] + add $tmp2,$tmp1,$tmp1 + srl @X[($i/2)%8],0,@X[($i/2)%8] + add $tmp1,$T1,$T1 + + sllx $T1,32,$tmp0 + or $tmp0,@X[($i/2)%8],@X[($i/2)%8] +___ + } + &BODY_00_15(@_); +} if ($SZ==4); + +########### SHA512 +$BODY_16_XX = sub { +my $i=@_[0]; +my @pair=("%l".eval(($i*2)%8),"%l".eval(($i*2)%8+1)); + +$code.=<<___; + sllx %l2,32,$tmp0 !! Xupdate($i) + or %l3,$tmp0,$tmp0 + + srlx $tmp0,@sigma0[0],$T1 + ld [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+0`],%l2 + sllx $tmp0,`64-@sigma0[2]`,$tmp1 + ld [%sp+`$bias+$frame+(($i+1+1)%16)*$SZ+4`],%l3 + srlx $tmp0,@sigma0[1],$tmp0 + xor $tmp1,$T1,$T1 + sllx $tmp1,`@sigma0[2]-@sigma0[1]`,$tmp1 + xor $tmp0,$T1,$T1 + srlx $tmp0,`@sigma0[2]-@sigma0[1]`,$tmp0 + xor $tmp1,$T1,$T1 + sllx %l6,32,$tmp2 + xor $tmp0,$T1,$T1 ! sigma0(X[$i+1]) + or %l7,$tmp2,$tmp2 + + srlx $tmp2,@sigma1[0],$tmp1 + ld [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+0`],%l6 + sllx $tmp2,`64-@sigma1[2]`,$tmp0 + ld [%sp+`$bias+$frame+(($i+1+14)%16)*$SZ+4`],%l7 + srlx $tmp2,@sigma1[1],$tmp2 + xor $tmp0,$tmp1,$tmp1 + sllx $tmp0,`@sigma1[2]-@sigma1[1]`,$tmp0 + xor $tmp2,$tmp1,$tmp1 + srlx $tmp2,`@sigma1[2]-@sigma1[1]`,$tmp2 + xor $tmp0,$tmp1,$tmp1 + sllx %l4,32,$tmp0 + xor $tmp2,$tmp1,$tmp1 ! sigma1(X[$i+14]) + ld [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+0`],%l4 + or %l5,$tmp0,$tmp0 + ld [%sp+`$bias+$frame+(($i+1+9)%16)*$SZ+4`],%l5 + + sllx %l0,32,$tmp2 + add $tmp1,$T1,$T1 + ld [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+0`],%l0 + or %l1,$tmp2,$tmp2 + add $tmp0,$T1,$T1 ! +=X[$i+9] + ld [%sp+`$bias+$frame+(($i+1+0)%16)*$SZ+4`],%l1 + add $tmp2,$T1,$T1 ! +=X[$i] + $ST $T1,[%sp+`$bias+$frame+($i%16)*$SZ`] +___ + &BODY_00_15(@_); +} if ($SZ==8); + +$code.=<<___ if ($bits==64); +.register %g2,#scratch +.register %g3,#scratch +___ +$code.=<<___; +.section ".text",#alloc,#execinstr + +.align 64 +K${label}: +.type K${label},#object +___ +if ($SZ==4) { +$code.=<<___; + .long 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5 + .long 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5 + .long 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3 + .long 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174 + .long 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc + .long 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da + .long 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7 + .long 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967 + .long 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13 + .long 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85 + .long 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3 + .long 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070 + .long 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5 + .long 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3 + .long 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208 + .long 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +___ +} else { +$code.=<<___; + .long 0x428a2f98,0xd728ae22, 0x71374491,0x23ef65cd + .long 0xb5c0fbcf,0xec4d3b2f, 0xe9b5dba5,0x8189dbbc + .long 0x3956c25b,0xf348b538, 0x59f111f1,0xb605d019 + .long 0x923f82a4,0xaf194f9b, 0xab1c5ed5,0xda6d8118 + .long 0xd807aa98,0xa3030242, 0x12835b01,0x45706fbe + .long 0x243185be,0x4ee4b28c, 0x550c7dc3,0xd5ffb4e2 + .long 0x72be5d74,0xf27b896f, 0x80deb1fe,0x3b1696b1 + .long 0x9bdc06a7,0x25c71235, 0xc19bf174,0xcf692694 + .long 0xe49b69c1,0x9ef14ad2, 0xefbe4786,0x384f25e3 + .long 0x0fc19dc6,0x8b8cd5b5, 0x240ca1cc,0x77ac9c65 + .long 0x2de92c6f,0x592b0275, 0x4a7484aa,0x6ea6e483 + .long 0x5cb0a9dc,0xbd41fbd4, 0x76f988da,0x831153b5 + .long 0x983e5152,0xee66dfab, 0xa831c66d,0x2db43210 + .long 0xb00327c8,0x98fb213f, 0xbf597fc7,0xbeef0ee4 + .long 0xc6e00bf3,0x3da88fc2, 0xd5a79147,0x930aa725 + .long 0x06ca6351,0xe003826f, 0x14292967,0x0a0e6e70 + .long 0x27b70a85,0x46d22ffc, 0x2e1b2138,0x5c26c926 + .long 0x4d2c6dfc,0x5ac42aed, 0x53380d13,0x9d95b3df + .long 0x650a7354,0x8baf63de, 0x766a0abb,0x3c77b2a8 + .long 0x81c2c92e,0x47edaee6, 0x92722c85,0x1482353b + .long 0xa2bfe8a1,0x4cf10364, 0xa81a664b,0xbc423001 + .long 0xc24b8b70,0xd0f89791, 0xc76c51a3,0x0654be30 + .long 0xd192e819,0xd6ef5218, 0xd6990624,0x5565a910 + .long 0xf40e3585,0x5771202a, 0x106aa070,0x32bbd1b8 + .long 0x19a4c116,0xb8d2d0c8, 0x1e376c08,0x5141ab53 + .long 0x2748774c,0xdf8eeb99, 0x34b0bcb5,0xe19b48a8 + .long 0x391c0cb3,0xc5c95a63, 0x4ed8aa4a,0xe3418acb + .long 0x5b9cca4f,0x7763e373, 0x682e6ff3,0xd6b2b8a3 + .long 0x748f82ee,0x5defb2fc, 0x78a5636f,0x43172f60 + .long 0x84c87814,0xa1f0ab72, 0x8cc70208,0x1a6439ec + .long 0x90befffa,0x23631e28, 0xa4506ceb,0xde82bde9 + .long 0xbef9a3f7,0xb2c67915, 0xc67178f2,0xe372532b + .long 0xca273ece,0xea26619c, 0xd186b8c7,0x21c0c207 + .long 0xeada7dd6,0xcde0eb1e, 0xf57d4f7f,0xee6ed178 + .long 0x06f067aa,0x72176fba, 0x0a637dc5,0xa2c898a6 + .long 0x113f9804,0xbef90dae, 0x1b710b35,0x131c471b + .long 0x28db77f5,0x23047d84, 0x32caab7b,0x40c72493 + .long 0x3c9ebe0a,0x15c9bebc, 0x431d67c4,0x9c100d4c + .long 0x4cc5d4be,0xcb3e42b6, 0x597f299c,0xfc657e2a + .long 0x5fcb6fab,0x3ad6faec, 0x6c44198c,0x4a475817 +___ +} +$code.=<<___; +.size K${label},.-K${label} +.globl sha${label}_block_data_order +sha${label}_block_data_order: + save %sp,`-$frame-$locals`,%sp + and $inp,`$align-1`,$tmp31 + sllx $len,`log(16*$SZ)/log(2)`,$len + andn $inp,`$align-1`,$inp + sll $tmp31,3,$tmp31 + add $inp,$len,$len +___ +$code.=<<___ if ($SZ==8); # SHA512 + mov 32,$tmp32 + sub $tmp32,$tmp31,$tmp32 +___ +$code.=<<___; +.Lpic: call .+8 + add %o7,K${label}-.Lpic,$Ktbl + + $LD [$ctx+`0*$SZ`],$A + $LD [$ctx+`1*$SZ`],$B + $LD [$ctx+`2*$SZ`],$C + $LD [$ctx+`3*$SZ`],$D + $LD [$ctx+`4*$SZ`],$E + $LD [$ctx+`5*$SZ`],$F + $LD [$ctx+`6*$SZ`],$G + $LD [$ctx+`7*$SZ`],$H + +.Lloop: +___ +for ($i=0;$i<16;$i++) { &BODY_00_15($i,@V); unshift(@V,pop(@V)); } +$code.=".L16_xx:\n"; +for (;$i<32;$i++) { &$BODY_16_XX($i,@V); unshift(@V,pop(@V)); } +$code.=<<___; + and $tmp2,0xfff,$tmp2 + cmp $tmp2,$lastK + bne .L16_xx + add $Ktbl,`16*$SZ`,$Ktbl ! Ktbl+=16 + +___ +$code.=<<___ if ($SZ==4); # SHA256 + $LD [$ctx+`0*$SZ`],@X[0] + $LD [$ctx+`1*$SZ`],@X[1] + $LD [$ctx+`2*$SZ`],@X[2] + $LD [$ctx+`3*$SZ`],@X[3] + $LD [$ctx+`4*$SZ`],@X[4] + $LD [$ctx+`5*$SZ`],@X[5] + $LD [$ctx+`6*$SZ`],@X[6] + $LD [$ctx+`7*$SZ`],@X[7] + + add $A,@X[0],$A + $ST $A,[$ctx+`0*$SZ`] + add $B,@X[1],$B + $ST $B,[$ctx+`1*$SZ`] + add $C,@X[2],$C + $ST $C,[$ctx+`2*$SZ`] + add $D,@X[3],$D + $ST $D,[$ctx+`3*$SZ`] + add $E,@X[4],$E + $ST $E,[$ctx+`4*$SZ`] + add $F,@X[5],$F + $ST $F,[$ctx+`5*$SZ`] + add $G,@X[6],$G + $ST $G,[$ctx+`6*$SZ`] + add $H,@X[7],$H + $ST $H,[$ctx+`7*$SZ`] +___ +$code.=<<___ if ($SZ==8); # SHA512 + ld [$ctx+`0*$SZ+0`],%l0 + ld [$ctx+`0*$SZ+4`],%l1 + ld [$ctx+`1*$SZ+0`],%l2 + ld [$ctx+`1*$SZ+4`],%l3 + ld [$ctx+`2*$SZ+0`],%l4 + ld [$ctx+`2*$SZ+4`],%l5 + ld [$ctx+`3*$SZ+0`],%l6 + + sllx %l0,32,$tmp0 + ld [$ctx+`3*$SZ+4`],%l7 + sllx %l2,32,$tmp1 + or %l1,$tmp0,$tmp0 + or %l3,$tmp1,$tmp1 + add $tmp0,$A,$A + add $tmp1,$B,$B + $ST $A,[$ctx+`0*$SZ`] + sllx %l4,32,$tmp2 + $ST $B,[$ctx+`1*$SZ`] + sllx %l6,32,$T1 + or %l5,$tmp2,$tmp2 + or %l7,$T1,$T1 + add $tmp2,$C,$C + $ST $C,[$ctx+`2*$SZ`] + add $T1,$D,$D + $ST $D,[$ctx+`3*$SZ`] + + ld [$ctx+`4*$SZ+0`],%l0 + ld [$ctx+`4*$SZ+4`],%l1 + ld [$ctx+`5*$SZ+0`],%l2 + ld [$ctx+`5*$SZ+4`],%l3 + ld [$ctx+`6*$SZ+0`],%l4 + ld [$ctx+`6*$SZ+4`],%l5 + ld [$ctx+`7*$SZ+0`],%l6 + + sllx %l0,32,$tmp0 + ld [$ctx+`7*$SZ+4`],%l7 + sllx %l2,32,$tmp1 + or %l1,$tmp0,$tmp0 + or %l3,$tmp1,$tmp1 + add $tmp0,$E,$E + add $tmp1,$F,$F + $ST $E,[$ctx+`4*$SZ`] + sllx %l4,32,$tmp2 + $ST $F,[$ctx+`5*$SZ`] + sllx %l6,32,$T1 + or %l5,$tmp2,$tmp2 + or %l7,$T1,$T1 + add $tmp2,$G,$G + $ST $G,[$ctx+`6*$SZ`] + add $T1,$H,$H + $ST $H,[$ctx+`7*$SZ`] +___ +$code.=<<___; + add $inp,`16*$SZ`,$inp ! advance inp + cmp $inp,$len + bne `$bits==64?"%xcc":"%icc"`,.Lloop + sub $Ktbl,`($rounds-16)*$SZ`,$Ktbl ! rewind Ktbl + + ret + restore +.type sha${label}_block_data_order,#function +.size sha${label}_block_data_order,(.-sha${label}_block_data_order) +.asciz "SHA${label} block transform for SPARCv9, CRYPTOGAMS by " +.align 4 +___ + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/sha/asm/sha512-x86_64.pl b/libs/openssl/crypto/sha/asm/sha512-x86_64.pl new file mode 100755 index 00000000..8d516785 --- /dev/null +++ b/libs/openssl/crypto/sha/asm/sha512-x86_64.pl @@ -0,0 +1,451 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. Rights for redistribution and usage in source and binary +# forms are granted according to the OpenSSL license. +# ==================================================================== +# +# sha256/512_block procedure for x86_64. +# +# 40% improvement over compiler-generated code on Opteron. On EM64T +# sha256 was observed to run >80% faster and sha512 - >40%. No magical +# tricks, just straight implementation... I really wonder why gcc +# [being armed with inline assembler] fails to generate as fast code. +# The only thing which is cool about this module is that it's very +# same instruction sequence used for both SHA-256 and SHA-512. In +# former case the instructions operate on 32-bit operands, while in +# latter - on 64-bit ones. All I had to do is to get one flavor right, +# the other one passed the test right away:-) +# +# sha256_block runs in ~1005 cycles on Opteron, which gives you +# asymptotic performance of 64*1000/1005=63.7MBps times CPU clock +# frequency in GHz. sha512_block runs in ~1275 cycles, which results +# in 128*1000/1275=100MBps per GHz. Is there room for improvement? +# Well, if you compare it to IA-64 implementation, which maintains +# X[16] in register bank[!], tends to 4 instructions per CPU clock +# cycle and runs in 1003 cycles, 1275 is very good result for 3-way +# issue Opteron pipeline and X[16] maintained in memory. So that *if* +# there is a way to improve it, *then* the only way would be to try to +# offload X[16] updates to SSE unit, but that would require "deeper" +# loop unroll, which in turn would naturally cause size blow-up, not +# to mention increased complexity! And once again, only *if* it's +# actually possible to noticeably improve overall ILP, instruction +# level parallelism, on a given CPU implementation in this case. +# +# Special note on Intel EM64T. While Opteron CPU exhibits perfect +# perfromance ratio of 1.5 between 64- and 32-bit flavors [see above], +# [currently available] EM64T CPUs apparently are far from it. On the +# contrary, 64-bit version, sha512_block, is ~30% *slower* than 32-bit +# sha256_block:-( This is presumably because 64-bit shifts/rotates +# apparently are not atomic instructions, but implemented in microcode. + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +if ($output =~ /512/) { + $func="sha512_block_data_order"; + $TABLE="K512"; + $SZ=8; + @ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%rax","%rbx","%rcx","%rdx", + "%r8", "%r9", "%r10","%r11"); + ($T1,$a0,$a1,$a2)=("%r12","%r13","%r14","%r15"); + @Sigma0=(28,34,39); + @Sigma1=(14,18,41); + @sigma0=(1, 8, 7); + @sigma1=(19,61, 6); + $rounds=80; +} else { + $func="sha256_block_data_order"; + $TABLE="K256"; + $SZ=4; + @ROT=($A,$B,$C,$D,$E,$F,$G,$H)=("%eax","%ebx","%ecx","%edx", + "%r8d","%r9d","%r10d","%r11d"); + ($T1,$a0,$a1,$a2)=("%r12d","%r13d","%r14d","%r15d"); + @Sigma0=( 2,13,22); + @Sigma1=( 6,11,25); + @sigma0=( 7,18, 3); + @sigma1=(17,19,10); + $rounds=64; +} + +$ctx="%rdi"; # 1st arg +$round="%rdi"; # zaps $ctx +$inp="%rsi"; # 2nd arg +$Tbl="%rbp"; + +$_ctx="16*$SZ+0*8(%rsp)"; +$_inp="16*$SZ+1*8(%rsp)"; +$_end="16*$SZ+2*8(%rsp)"; +$_rsp="16*$SZ+3*8(%rsp)"; +$framesz="16*$SZ+4*8"; + + +sub ROUND_00_15() +{ my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_; + +$code.=<<___; + ror \$`$Sigma1[2]-$Sigma1[1]`,$a0 + mov $f,$a2 + mov $T1,`$SZ*($i&0xf)`(%rsp) + + ror \$`$Sigma0[2]-$Sigma0[1]`,$a1 + xor $e,$a0 + xor $g,$a2 # f^g + + ror \$`$Sigma1[1]-$Sigma1[0]`,$a0 + add $h,$T1 # T1+=h + xor $a,$a1 + + add ($Tbl,$round,$SZ),$T1 # T1+=K[round] + and $e,$a2 # (f^g)&e + mov $b,$h + + ror \$`$Sigma0[1]-$Sigma0[0]`,$a1 + xor $e,$a0 + xor $g,$a2 # Ch(e,f,g)=((f^g)&e)^g + + xor $c,$h # b^c + xor $a,$a1 + add $a2,$T1 # T1+=Ch(e,f,g) + mov $b,$a2 + + ror \$$Sigma1[0],$a0 # Sigma1(e) + and $a,$h # h=(b^c)&a + and $c,$a2 # b&c + + ror \$$Sigma0[0],$a1 # Sigma0(a) + add $a0,$T1 # T1+=Sigma1(e) + add $a2,$h # h+=b&c (completes +=Maj(a,b,c) + + add $T1,$d # d+=T1 + add $T1,$h # h+=T1 + lea 1($round),$round # round++ + add $a1,$h # h+=Sigma0(a) + +___ +} + +sub ROUND_16_XX() +{ my ($i,$a,$b,$c,$d,$e,$f,$g,$h) = @_; + +$code.=<<___; + mov `$SZ*(($i+1)&0xf)`(%rsp),$a0 + mov `$SZ*(($i+14)&0xf)`(%rsp),$a1 + mov $a0,$T1 + mov $a1,$a2 + + ror \$`$sigma0[1]-$sigma0[0]`,$T1 + xor $a0,$T1 + shr \$$sigma0[2],$a0 + + ror \$$sigma0[0],$T1 + xor $T1,$a0 # sigma0(X[(i+1)&0xf]) + mov `$SZ*(($i+9)&0xf)`(%rsp),$T1 + + ror \$`$sigma1[1]-$sigma1[0]`,$a2 + xor $a1,$a2 + shr \$$sigma1[2],$a1 + + ror \$$sigma1[0],$a2 + add $a0,$T1 + xor $a2,$a1 # sigma1(X[(i+14)&0xf]) + + add `$SZ*($i&0xf)`(%rsp),$T1 + mov $e,$a0 + add $a1,$T1 + mov $a,$a1 +___ + &ROUND_00_15(@_); +} + +$code=<<___; +.text + +.globl $func +.type $func,\@function,4 +.align 16 +$func: + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + mov %rsp,%r11 # copy %rsp + shl \$4,%rdx # num*16 + sub \$$framesz,%rsp + lea ($inp,%rdx,$SZ),%rdx # inp+num*16*$SZ + and \$-64,%rsp # align stack frame + mov $ctx,$_ctx # save ctx, 1st arg + mov $inp,$_inp # save inp, 2nd arh + mov %rdx,$_end # save end pointer, "3rd" arg + mov %r11,$_rsp # save copy of %rsp +.Lprologue: + + lea $TABLE(%rip),$Tbl + + mov $SZ*0($ctx),$A + mov $SZ*1($ctx),$B + mov $SZ*2($ctx),$C + mov $SZ*3($ctx),$D + mov $SZ*4($ctx),$E + mov $SZ*5($ctx),$F + mov $SZ*6($ctx),$G + mov $SZ*7($ctx),$H + jmp .Lloop + +.align 16 +.Lloop: + xor $round,$round +___ + for($i=0;$i<16;$i++) { + $code.=" mov $SZ*$i($inp),$T1\n"; + $code.=" mov @ROT[4],$a0\n"; + $code.=" mov @ROT[0],$a1\n"; + $code.=" bswap $T1\n"; + &ROUND_00_15($i,@ROT); + unshift(@ROT,pop(@ROT)); + } +$code.=<<___; + jmp .Lrounds_16_xx +.align 16 +.Lrounds_16_xx: +___ + for(;$i<32;$i++) { + &ROUND_16_XX($i,@ROT); + unshift(@ROT,pop(@ROT)); + } + +$code.=<<___; + cmp \$$rounds,$round + jb .Lrounds_16_xx + + mov $_ctx,$ctx + lea 16*$SZ($inp),$inp + + add $SZ*0($ctx),$A + add $SZ*1($ctx),$B + add $SZ*2($ctx),$C + add $SZ*3($ctx),$D + add $SZ*4($ctx),$E + add $SZ*5($ctx),$F + add $SZ*6($ctx),$G + add $SZ*7($ctx),$H + + cmp $_end,$inp + + mov $A,$SZ*0($ctx) + mov $B,$SZ*1($ctx) + mov $C,$SZ*2($ctx) + mov $D,$SZ*3($ctx) + mov $E,$SZ*4($ctx) + mov $F,$SZ*5($ctx) + mov $G,$SZ*6($ctx) + mov $H,$SZ*7($ctx) + jb .Lloop + + mov $_rsp,%rsi + mov (%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 + mov 24(%rsi),%r12 + mov 32(%rsi),%rbp + mov 40(%rsi),%rbx + lea 48(%rsi),%rsp +.Lepilogue: + ret +.size $func,.-$func +___ + +if ($SZ==4) { +$code.=<<___; +.align 64 +.type $TABLE,\@object +$TABLE: + .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 + .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 + .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 + .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 + .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc + .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da + .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 + .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 + .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 + .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 + .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 + .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 + .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 + .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 + .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 + .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 +___ +} else { +$code.=<<___; +.align 64 +.type $TABLE,\@object +$TABLE: + .quad 0x428a2f98d728ae22,0x7137449123ef65cd + .quad 0xb5c0fbcfec4d3b2f,0xe9b5dba58189dbbc + .quad 0x3956c25bf348b538,0x59f111f1b605d019 + .quad 0x923f82a4af194f9b,0xab1c5ed5da6d8118 + .quad 0xd807aa98a3030242,0x12835b0145706fbe + .quad 0x243185be4ee4b28c,0x550c7dc3d5ffb4e2 + .quad 0x72be5d74f27b896f,0x80deb1fe3b1696b1 + .quad 0x9bdc06a725c71235,0xc19bf174cf692694 + .quad 0xe49b69c19ef14ad2,0xefbe4786384f25e3 + .quad 0x0fc19dc68b8cd5b5,0x240ca1cc77ac9c65 + .quad 0x2de92c6f592b0275,0x4a7484aa6ea6e483 + .quad 0x5cb0a9dcbd41fbd4,0x76f988da831153b5 + .quad 0x983e5152ee66dfab,0xa831c66d2db43210 + .quad 0xb00327c898fb213f,0xbf597fc7beef0ee4 + .quad 0xc6e00bf33da88fc2,0xd5a79147930aa725 + .quad 0x06ca6351e003826f,0x142929670a0e6e70 + .quad 0x27b70a8546d22ffc,0x2e1b21385c26c926 + .quad 0x4d2c6dfc5ac42aed,0x53380d139d95b3df + .quad 0x650a73548baf63de,0x766a0abb3c77b2a8 + .quad 0x81c2c92e47edaee6,0x92722c851482353b + .quad 0xa2bfe8a14cf10364,0xa81a664bbc423001 + .quad 0xc24b8b70d0f89791,0xc76c51a30654be30 + .quad 0xd192e819d6ef5218,0xd69906245565a910 + .quad 0xf40e35855771202a,0x106aa07032bbd1b8 + .quad 0x19a4c116b8d2d0c8,0x1e376c085141ab53 + .quad 0x2748774cdf8eeb99,0x34b0bcb5e19b48a8 + .quad 0x391c0cb3c5c95a63,0x4ed8aa4ae3418acb + .quad 0x5b9cca4f7763e373,0x682e6ff3d6b2b8a3 + .quad 0x748f82ee5defb2fc,0x78a5636f43172f60 + .quad 0x84c87814a1f0ab72,0x8cc702081a6439ec + .quad 0x90befffa23631e28,0xa4506cebde82bde9 + .quad 0xbef9a3f7b2c67915,0xc67178f2e372532b + .quad 0xca273eceea26619c,0xd186b8c721c0c207 + .quad 0xeada7dd6cde0eb1e,0xf57d4f7fee6ed178 + .quad 0x06f067aa72176fba,0x0a637dc5a2c898a6 + .quad 0x113f9804bef90dae,0x1b710b35131c471b + .quad 0x28db77f523047d84,0x32caab7b40c72493 + .quad 0x3c9ebe0a15c9bebc,0x431d67c49c100d4c + .quad 0x4cc5d4becb3e42b6,0x597f299cfc657e2a + .quad 0x5fcb6fab3ad6faec,0x6c44198c4a475817 +___ +} + +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type se_handler,\@abi-omnipotent +.align 16 +se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + lea .Lprologue(%rip),%r10 + cmp %r10,%rbx # context->Rip<.Lprologue + jb .Lin_prologue + + mov 152($context),%rax # pull context->Rsp + + lea .Lepilogue(%rip),%r10 + cmp %r10,%rbx # context->Rip>=.Lepilogue + jae .Lin_prologue + + mov 16*$SZ+3*8(%rax),%rax # pull $_rsp + lea 48(%rax),%rax + + mov -8(%rax),%rbx + mov -16(%rax),%rbp + mov -24(%rax),%r12 + mov -32(%rax),%r13 + mov -40(%rax),%r14 + mov -48(%rax),%r15 + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + +.Lin_prologue: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$154,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size se_handler,.-se_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_$func + .rva .LSEH_end_$func + .rva .LSEH_info_$func + +.section .xdata +.align 8 +.LSEH_info_$func: + .byte 9,0,0,0 + .rva se_handler +___ +} + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/sha/sha.c b/libs/openssl/crypto/sha/sha.c new file mode 100644 index 00000000..cfc12f3e --- /dev/null +++ b/libs/openssl/crypto/sha/sha.c @@ -0,0 +1,118 @@ +/* crypto/sha/sha.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#define BUFSIZE 1024*16 + +void do_fp(FILE *f); +void pt(unsigned char *md); +int read(int, void *, unsigned int); +int main(int argc, char **argv) +{ + int i, err = 0; + FILE *IN; + + if (argc == 1) { + do_fp(stdin); + } else { + for (i = 1; i < argc; i++) { + IN = fopen(argv[i], "r"); + if (IN == NULL) { + perror(argv[i]); + err++; + continue; + } + printf("SHA(%s)= ", argv[i]); + do_fp(IN); + fclose(IN); + } + } + exit(err); +} + +void do_fp(FILE *f) +{ + SHA_CTX c; + unsigned char md[SHA_DIGEST_LENGTH]; + int fd; + int i; + unsigned char buf[BUFSIZE]; + + fd = fileno(f); + SHA_Init(&c); + for (;;) { + i = read(fd, buf, BUFSIZE); + if (i <= 0) + break; + SHA_Update(&c, buf, (unsigned long)i); + } + SHA_Final(&(md[0]), &c); + pt(md); +} + +void pt(unsigned char *md) +{ + int i; + + for (i = 0; i < SHA_DIGEST_LENGTH; i++) + printf("%02x", md[i]); + printf("\n"); +} diff --git a/libs/openssl/crypto/sha/sha.h b/libs/openssl/crypto/sha/sha.h new file mode 100644 index 00000000..e5169e4f --- /dev/null +++ b/libs/openssl/crypto/sha/sha.h @@ -0,0 +1,214 @@ +/* crypto/sha/sha.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SHA_H +# define HEADER_SHA_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# if defined(OPENSSL_NO_SHA) || (defined(OPENSSL_NO_SHA0) && defined(OPENSSL_NO_SHA1)) +# error SHA is disabled. +# endif + +# if defined(OPENSSL_FIPS) +# define FIPS_SHA_SIZE_T size_t +# endif + +/*- + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * ! SHA_LONG has to be at least 32 bits wide. If it's wider, then ! + * ! SHA_LONG_LOG2 has to be defined along. ! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +# if defined(__LP32__) +# define SHA_LONG unsigned long +# elif defined(OPENSSL_SYS_CRAY) || defined(__ILP64__) +# define SHA_LONG unsigned long +# define SHA_LONG_LOG2 3 +# else +# define SHA_LONG unsigned int +# endif + +# define SHA_LBLOCK 16 +# define SHA_CBLOCK (SHA_LBLOCK*4)/* SHA treats input data as a + * contiguous array of 32 bit wide + * big-endian values. */ +# define SHA_LAST_BLOCK (SHA_CBLOCK-8) +# define SHA_DIGEST_LENGTH 20 + +typedef struct SHAstate_st { + SHA_LONG h0, h1, h2, h3, h4; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num; +} SHA_CTX; + +# ifndef OPENSSL_NO_SHA0 +# ifdef OPENSSL_FIPS +int private_SHA_Init(SHA_CTX *c); +# endif +int SHA_Init(SHA_CTX *c); +int SHA_Update(SHA_CTX *c, const void *data, size_t len); +int SHA_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md); +void SHA_Transform(SHA_CTX *c, const unsigned char *data); +# endif +# ifndef OPENSSL_NO_SHA1 +# ifdef OPENSSL_FIPS +int private_SHA1_Init(SHA_CTX *c); +# endif +int SHA1_Init(SHA_CTX *c); +int SHA1_Update(SHA_CTX *c, const void *data, size_t len); +int SHA1_Final(unsigned char *md, SHA_CTX *c); +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md); +void SHA1_Transform(SHA_CTX *c, const unsigned char *data); +# endif + +# define SHA256_CBLOCK (SHA_LBLOCK*4)/* SHA-256 treats input data as a + * contiguous array of 32 bit wide + * big-endian values. */ +# define SHA224_DIGEST_LENGTH 28 +# define SHA256_DIGEST_LENGTH 32 + +typedef struct SHA256state_st { + SHA_LONG h[8]; + SHA_LONG Nl, Nh; + SHA_LONG data[SHA_LBLOCK]; + unsigned int num, md_len; +} SHA256_CTX; + +# ifndef OPENSSL_NO_SHA256 +# ifdef OPENSSL_FIPS +int private_SHA224_Init(SHA256_CTX *c); +int private_SHA256_Init(SHA256_CTX *c); +# endif +int SHA224_Init(SHA256_CTX *c); +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA224_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md); +int SHA256_Init(SHA256_CTX *c); +int SHA256_Update(SHA256_CTX *c, const void *data, size_t len); +int SHA256_Final(unsigned char *md, SHA256_CTX *c); +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md); +void SHA256_Transform(SHA256_CTX *c, const unsigned char *data); +# endif + +# define SHA384_DIGEST_LENGTH 48 +# define SHA512_DIGEST_LENGTH 64 + +# ifndef OPENSSL_NO_SHA512 +/* + * Unlike 32-bit digest algorithms, SHA-512 *relies* on SHA_LONG64 + * being exactly 64-bit wide. See Implementation Notes in sha512.c + * for further details. + */ +/* + * SHA-512 treats input data as a + * contiguous array of 64 bit + * wide big-endian values. + */ +# define SHA512_CBLOCK (SHA_LBLOCK*8) +# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +# define SHA_LONG64 unsigned __int64 +# define U64(C) C##UI64 +# elif defined(__arch64__) +# define SHA_LONG64 unsigned long +# define U64(C) C##UL +# else +# define SHA_LONG64 unsigned long long +# define U64(C) C##ULL +# endif + +typedef struct SHA512state_st { + SHA_LONG64 h[8]; + SHA_LONG64 Nl, Nh; + union { + SHA_LONG64 d[SHA_LBLOCK]; + unsigned char p[SHA512_CBLOCK]; + } u; + unsigned int num, md_len; +} SHA512_CTX; +# endif + +# ifndef OPENSSL_NO_SHA512 +# ifdef OPENSSL_FIPS +int private_SHA384_Init(SHA512_CTX *c); +int private_SHA512_Init(SHA512_CTX *c); +# endif +int SHA384_Init(SHA512_CTX *c); +int SHA384_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA384_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md); +int SHA512_Init(SHA512_CTX *c); +int SHA512_Update(SHA512_CTX *c, const void *data, size_t len); +int SHA512_Final(unsigned char *md, SHA512_CTX *c); +unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md); +void SHA512_Transform(SHA512_CTX *c, const unsigned char *data); +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/sha/sha1.c b/libs/openssl/crypto/sha/sha1.c new file mode 100644 index 00000000..8dd19431 --- /dev/null +++ b/libs/openssl/crypto/sha/sha1.c @@ -0,0 +1,121 @@ +/* crypto/sha/sha1.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#define BUFSIZE 1024*16 + +void do_fp(FILE *f); +void pt(unsigned char *md); +#ifndef _OSD_POSIX +int read(int, void *, unsigned int); +#endif + +int main(int argc, char **argv) +{ + int i, err = 0; + FILE *IN; + + if (argc == 1) { + do_fp(stdin); + } else { + for (i = 1; i < argc; i++) { + IN = fopen(argv[i], "r"); + if (IN == NULL) { + perror(argv[i]); + err++; + continue; + } + printf("SHA1(%s)= ", argv[i]); + do_fp(IN); + fclose(IN); + } + } + exit(err); +} + +void do_fp(FILE *f) +{ + SHA_CTX c; + unsigned char md[SHA_DIGEST_LENGTH]; + int fd; + int i; + unsigned char buf[BUFSIZE]; + + fd = fileno(f); + SHA1_Init(&c); + for (;;) { + i = read(fd, buf, BUFSIZE); + if (i <= 0) + break; + SHA1_Update(&c, buf, (unsigned long)i); + } + SHA1_Final(&(md[0]), &c); + pt(md); +} + +void pt(unsigned char *md) +{ + int i; + + for (i = 0; i < SHA_DIGEST_LENGTH; i++) + printf("%02x", md[i]); + printf("\n"); +} diff --git a/libs/openssl/crypto/sha/sha1_one.c b/libs/openssl/crypto/sha/sha1_one.c new file mode 100644 index 00000000..a6dd760a --- /dev/null +++ b/libs/openssl/crypto/sha/sha1_one.c @@ -0,0 +1,79 @@ +/* crypto/sha/sha1_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#ifndef OPENSSL_NO_SHA1 +unsigned char *SHA1(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA_CTX c; + static unsigned char m[SHA_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!SHA1_Init(&c)) + return NULL; + SHA1_Update(&c, d, n); + SHA1_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); + return (md); +} +#endif diff --git a/libs/openssl/crypto/sha/sha1dgst.c b/libs/openssl/crypto/sha/sha1dgst.c new file mode 100644 index 00000000..a67f1fe3 --- /dev/null +++ b/libs/openssl/crypto/sha/sha1dgst.c @@ -0,0 +1,74 @@ +/* crypto/sha/sha1dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#if !defined(OPENSSL_NO_SHA1) && !defined(OPENSSL_NO_SHA) + +# undef SHA_0 +# define SHA_1 + +# include + +const char SHA1_version[] = "SHA1" OPENSSL_VERSION_PTEXT; + +/* The implementation is in ../md32_common.h */ + +# include "sha_locl.h" + +#endif diff --git a/libs/openssl/crypto/sha/sha1test.c b/libs/openssl/crypto/sha/sha1test.c new file mode 100644 index 00000000..551a348d --- /dev/null +++ b/libs/openssl/crypto/sha/sha1test.c @@ -0,0 +1,174 @@ +/* crypto/sha/sha1test.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "../e_os.h" + +#ifdef OPENSSL_NO_SHA +int main(int argc, char *argv[]) +{ + printf("No SHA support\n"); + return (0); +} +#else +# include +# include + +# ifdef CHARSET_EBCDIC +# include +# endif + +# undef SHA_0 /* FIPS 180 */ +# define SHA_1 /* FIPS 180-1 */ + +static char *test[] = { + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + NULL, +}; + +# ifdef SHA_0 +static char *ret[] = { + "0164b8a914cd2a5e74c4f7ff082c4d97f1edf880", + "d2516ee1acfa5baf33dfc1c471e438449ef134c8", +}; + +static char *bigret = "3232affa48628a26653b5aaa44541fd90d690603"; +# endif +# ifdef SHA_1 +static char *ret[] = { + "a9993e364706816aba3e25717850c26c9cd0d89d", + "84983e441c3bd26ebaae4aa1f95129e5e54670f1", +}; + +static char *bigret = "34aa973cd4c4daa4f61eeb2bdbad27316534016f"; +# endif + +static char *pt(unsigned char *md); +int main(int argc, char *argv[]) +{ + int i, err = 0; + char **P, **R; + static unsigned char buf[1000]; + char *p, *r; + EVP_MD_CTX c; + unsigned char md[SHA_DIGEST_LENGTH]; + +# ifdef CHARSET_EBCDIC + ebcdic2ascii(test[0], test[0], strlen(test[0])); + ebcdic2ascii(test[1], test[1], strlen(test[1])); +# endif + + EVP_MD_CTX_init(&c); + P = test; + R = ret; + i = 1; + while (*P != NULL) { + EVP_Digest(*P, strlen((char *)*P), md, NULL, EVP_sha1(), NULL); + p = pt(md); + if (strcmp(p, (char *)*R) != 0) { + printf("error calculating SHA1 on '%s'\n", *P); + printf("got %s instead of %s\n", p, *R); + err++; + } else + printf("test %d ok\n", i); + i++; + R++; + P++; + } + + memset(buf, 'a', 1000); +# ifdef CHARSET_EBCDIC + ebcdic2ascii(buf, buf, 1000); +# endif /* CHARSET_EBCDIC */ + EVP_DigestInit_ex(&c, EVP_sha1(), NULL); + for (i = 0; i < 1000; i++) + EVP_DigestUpdate(&c, buf, 1000); + EVP_DigestFinal_ex(&c, md, NULL); + p = pt(md); + + r = bigret; + if (strcmp(p, r) != 0) { + printf("error calculating SHA1 on 'a' * 1000\n"); + printf("got %s instead of %s\n", p, r); + err++; + } else + printf("test 3 ok\n"); + +# ifdef OPENSSL_SYS_NETWARE + if (err) + printf("ERROR: %d\n", err); +# endif + EVP_MD_CTX_cleanup(&c); + EXIT(err); + return (0); +} + +static char *pt(unsigned char *md) +{ + int i; + static char buf[80]; + + for (i = 0; i < SHA_DIGEST_LENGTH; i++) + sprintf(&(buf[i * 2]), "%02x", md[i]); + return (buf); +} +#endif diff --git a/libs/openssl/crypto/sha/sha256.c b/libs/openssl/crypto/sha/sha256.c new file mode 100644 index 00000000..72a11593 --- /dev/null +++ b/libs/openssl/crypto/sha/sha256.c @@ -0,0 +1,387 @@ +/* crypto/sha/sha256.c */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved + * according to the OpenSSL license [found in ../../LICENSE]. + * ==================================================================== + */ +#include +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA256) + +# include +# include + +# include +# include +# include + +const char SHA256_version[] = "SHA-256" OPENSSL_VERSION_PTEXT; + +fips_md_init_ctx(SHA224, SHA256) +{ + memset(c, 0, sizeof(*c)); + c->h[0] = 0xc1059ed8UL; + c->h[1] = 0x367cd507UL; + c->h[2] = 0x3070dd17UL; + c->h[3] = 0xf70e5939UL; + c->h[4] = 0xffc00b31UL; + c->h[5] = 0x68581511UL; + c->h[6] = 0x64f98fa7UL; + c->h[7] = 0xbefa4fa4UL; + c->md_len = SHA224_DIGEST_LENGTH; + return 1; +} + +fips_md_init(SHA256) +{ + memset(c, 0, sizeof(*c)); + c->h[0] = 0x6a09e667UL; + c->h[1] = 0xbb67ae85UL; + c->h[2] = 0x3c6ef372UL; + c->h[3] = 0xa54ff53aUL; + c->h[4] = 0x510e527fUL; + c->h[5] = 0x9b05688cUL; + c->h[6] = 0x1f83d9abUL; + c->h[7] = 0x5be0cd19UL; + c->md_len = SHA256_DIGEST_LENGTH; + return 1; +} + +unsigned char *SHA224(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA256_CTX c; + static unsigned char m[SHA224_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + SHA224_Init(&c); + SHA256_Update(&c, d, n); + SHA256_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); + return (md); +} + +unsigned char *SHA256(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA256_CTX c; + static unsigned char m[SHA256_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + SHA256_Init(&c); + SHA256_Update(&c, d, n); + SHA256_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); + return (md); +} + +int SHA224_Update(SHA256_CTX *c, const void *data, size_t len) +{ + return SHA256_Update(c, data, len); +} + +int SHA224_Final(unsigned char *md, SHA256_CTX *c) +{ + return SHA256_Final(md, c); +} + +# define DATA_ORDER_IS_BIG_ENDIAN + +# define HASH_LONG SHA_LONG +# define HASH_CTX SHA256_CTX +# define HASH_CBLOCK SHA_CBLOCK +/* + * Note that FIPS180-2 discusses "Truncation of the Hash Function Output." + * default: case below covers for it. It's not clear however if it's + * permitted to truncate to amount of bytes not divisible by 4. I bet not, + * but if it is, then default: case shall be extended. For reference. + * Idea behind separate cases for pre-defined lenghts is to let the + * compiler decide if it's appropriate to unroll small loops. + */ +# define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + unsigned int nn; \ + switch ((c)->md_len) \ + { case SHA224_DIGEST_LENGTH: \ + for (nn=0;nnh[nn]; (void)HOST_l2c(ll,(s)); } \ + break; \ + case SHA256_DIGEST_LENGTH: \ + for (nn=0;nnh[nn]; (void)HOST_l2c(ll,(s)); } \ + break; \ + default: \ + if ((c)->md_len > SHA256_DIGEST_LENGTH) \ + return 0; \ + for (nn=0;nn<(c)->md_len/4;nn++) \ + { ll=(c)->h[nn]; (void)HOST_l2c(ll,(s)); } \ + break; \ + } \ + } while (0) + +# define HASH_UPDATE SHA256_Update +# define HASH_TRANSFORM SHA256_Transform +# define HASH_FINAL SHA256_Final +# define HASH_BLOCK_DATA_ORDER sha256_block_data_order +# ifndef SHA256_ASM +static +# endif +void sha256_block_data_order(SHA256_CTX *ctx, const void *in, size_t num); + +# include "md32_common.h" + +# ifndef SHA256_ASM +static const SHA_LONG K256[64] = { + 0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, + 0x3956c25bUL, 0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, + 0xd807aa98UL, 0x12835b01UL, 0x243185beUL, 0x550c7dc3UL, + 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL, 0xc19bf174UL, + 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL, + 0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, + 0x983e5152UL, 0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, + 0xc6e00bf3UL, 0xd5a79147UL, 0x06ca6351UL, 0x14292967UL, + 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL, 0x53380d13UL, + 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL, + 0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, + 0xd192e819UL, 0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, + 0x19a4c116UL, 0x1e376c08UL, 0x2748774cUL, 0x34b0bcb5UL, + 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL, 0x682e6ff3UL, + 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL, + 0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL +}; + +/* + * FIPS specification refers to right rotations, while our ROTATE macro + * is left one. This is why you might notice that rotation coefficients + * differ from those observed in FIPS document by 32-N... + */ +# define Sigma0(x) (ROTATE((x),30) ^ ROTATE((x),19) ^ ROTATE((x),10)) +# define Sigma1(x) (ROTATE((x),26) ^ ROTATE((x),21) ^ ROTATE((x),7)) +# define sigma0(x) (ROTATE((x),25) ^ ROTATE((x),14) ^ ((x)>>3)) +# define sigma1(x) (ROTATE((x),15) ^ ROTATE((x),13) ^ ((x)>>10)) + +# define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +# define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) + +# ifdef OPENSSL_SMALL_FOOTPRINT + +static void sha256_block_data_order(SHA256_CTX *ctx, const void *in, + size_t num) +{ + unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1, T2; + SHA_LONG X[16], l; + int i; + const unsigned char *data = in; + + while (num--) { + + a = ctx->h[0]; + b = ctx->h[1]; + c = ctx->h[2]; + d = ctx->h[3]; + e = ctx->h[4]; + f = ctx->h[5]; + g = ctx->h[6]; + h = ctx->h[7]; + + for (i = 0; i < 16; i++) { + HOST_c2l(data, l); + T1 = X[i] = l; + T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; + T2 = Sigma0(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + for (; i < 64; i++) { + s0 = X[(i + 1) & 0x0f]; + s0 = sigma0(s0); + s1 = X[(i + 14) & 0x0f]; + s1 = sigma1(s1); + + T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf]; + T1 += h + Sigma1(e) + Ch(e, f, g) + K256[i]; + T2 = Sigma0(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + ctx->h[0] += a; + ctx->h[1] += b; + ctx->h[2] += c; + ctx->h[3] += d; + ctx->h[4] += e; + ctx->h[5] += f; + ctx->h[6] += g; + ctx->h[7] += h; + + } +} + +# else + +# define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \ + T1 += h + Sigma1(e) + Ch(e,f,g) + K256[i]; \ + h = Sigma0(a) + Maj(a,b,c); \ + d += T1; h += T1; } while (0) + +# define ROUND_16_63(i,a,b,c,d,e,f,g,h,X) do { \ + s0 = X[(i+1)&0x0f]; s0 = sigma0(s0); \ + s1 = X[(i+14)&0x0f]; s1 = sigma1(s1); \ + T1 = X[(i)&0x0f] += s0 + s1 + X[(i+9)&0x0f]; \ + ROUND_00_15(i,a,b,c,d,e,f,g,h); } while (0) + +static void sha256_block_data_order(SHA256_CTX *ctx, const void *in, + size_t num) +{ + unsigned MD32_REG_T a, b, c, d, e, f, g, h, s0, s1, T1; + SHA_LONG X[16]; + int i; + const unsigned char *data = in; + const union { + long one; + char little; + } is_endian = { + 1 + }; + + while (num--) { + + a = ctx->h[0]; + b = ctx->h[1]; + c = ctx->h[2]; + d = ctx->h[3]; + e = ctx->h[4]; + f = ctx->h[5]; + g = ctx->h[6]; + h = ctx->h[7]; + + if (!is_endian.little && sizeof(SHA_LONG) == 4 + && ((size_t)in % 4) == 0) { + const SHA_LONG *W = (const SHA_LONG *)data; + + T1 = X[0] = W[0]; + ROUND_00_15(0, a, b, c, d, e, f, g, h); + T1 = X[1] = W[1]; + ROUND_00_15(1, h, a, b, c, d, e, f, g); + T1 = X[2] = W[2]; + ROUND_00_15(2, g, h, a, b, c, d, e, f); + T1 = X[3] = W[3]; + ROUND_00_15(3, f, g, h, a, b, c, d, e); + T1 = X[4] = W[4]; + ROUND_00_15(4, e, f, g, h, a, b, c, d); + T1 = X[5] = W[5]; + ROUND_00_15(5, d, e, f, g, h, a, b, c); + T1 = X[6] = W[6]; + ROUND_00_15(6, c, d, e, f, g, h, a, b); + T1 = X[7] = W[7]; + ROUND_00_15(7, b, c, d, e, f, g, h, a); + T1 = X[8] = W[8]; + ROUND_00_15(8, a, b, c, d, e, f, g, h); + T1 = X[9] = W[9]; + ROUND_00_15(9, h, a, b, c, d, e, f, g); + T1 = X[10] = W[10]; + ROUND_00_15(10, g, h, a, b, c, d, e, f); + T1 = X[11] = W[11]; + ROUND_00_15(11, f, g, h, a, b, c, d, e); + T1 = X[12] = W[12]; + ROUND_00_15(12, e, f, g, h, a, b, c, d); + T1 = X[13] = W[13]; + ROUND_00_15(13, d, e, f, g, h, a, b, c); + T1 = X[14] = W[14]; + ROUND_00_15(14, c, d, e, f, g, h, a, b); + T1 = X[15] = W[15]; + ROUND_00_15(15, b, c, d, e, f, g, h, a); + + data += SHA256_CBLOCK; + } else { + SHA_LONG l; + + HOST_c2l(data, l); + T1 = X[0] = l; + ROUND_00_15(0, a, b, c, d, e, f, g, h); + HOST_c2l(data, l); + T1 = X[1] = l; + ROUND_00_15(1, h, a, b, c, d, e, f, g); + HOST_c2l(data, l); + T1 = X[2] = l; + ROUND_00_15(2, g, h, a, b, c, d, e, f); + HOST_c2l(data, l); + T1 = X[3] = l; + ROUND_00_15(3, f, g, h, a, b, c, d, e); + HOST_c2l(data, l); + T1 = X[4] = l; + ROUND_00_15(4, e, f, g, h, a, b, c, d); + HOST_c2l(data, l); + T1 = X[5] = l; + ROUND_00_15(5, d, e, f, g, h, a, b, c); + HOST_c2l(data, l); + T1 = X[6] = l; + ROUND_00_15(6, c, d, e, f, g, h, a, b); + HOST_c2l(data, l); + T1 = X[7] = l; + ROUND_00_15(7, b, c, d, e, f, g, h, a); + HOST_c2l(data, l); + T1 = X[8] = l; + ROUND_00_15(8, a, b, c, d, e, f, g, h); + HOST_c2l(data, l); + T1 = X[9] = l; + ROUND_00_15(9, h, a, b, c, d, e, f, g); + HOST_c2l(data, l); + T1 = X[10] = l; + ROUND_00_15(10, g, h, a, b, c, d, e, f); + HOST_c2l(data, l); + T1 = X[11] = l; + ROUND_00_15(11, f, g, h, a, b, c, d, e); + HOST_c2l(data, l); + T1 = X[12] = l; + ROUND_00_15(12, e, f, g, h, a, b, c, d); + HOST_c2l(data, l); + T1 = X[13] = l; + ROUND_00_15(13, d, e, f, g, h, a, b, c); + HOST_c2l(data, l); + T1 = X[14] = l; + ROUND_00_15(14, c, d, e, f, g, h, a, b); + HOST_c2l(data, l); + T1 = X[15] = l; + ROUND_00_15(15, b, c, d, e, f, g, h, a); + } + + for (i = 16; i < 64; i += 8) { + ROUND_16_63(i + 0, a, b, c, d, e, f, g, h, X); + ROUND_16_63(i + 1, h, a, b, c, d, e, f, g, X); + ROUND_16_63(i + 2, g, h, a, b, c, d, e, f, X); + ROUND_16_63(i + 3, f, g, h, a, b, c, d, e, X); + ROUND_16_63(i + 4, e, f, g, h, a, b, c, d, X); + ROUND_16_63(i + 5, d, e, f, g, h, a, b, c, X); + ROUND_16_63(i + 6, c, d, e, f, g, h, a, b, X); + ROUND_16_63(i + 7, b, c, d, e, f, g, h, a, X); + } + + ctx->h[0] += a; + ctx->h[1] += b; + ctx->h[2] += c; + ctx->h[3] += d; + ctx->h[4] += e; + ctx->h[5] += f; + ctx->h[6] += g; + ctx->h[7] += h; + + } +} + +# endif +# endif /* SHA256_ASM */ + +#endif /* OPENSSL_NO_SHA256 */ diff --git a/libs/openssl/crypto/sha/sha256t.c b/libs/openssl/crypto/sha/sha256t.c new file mode 100644 index 00000000..35dbbc2a --- /dev/null +++ b/libs/openssl/crypto/sha/sha256t.c @@ -0,0 +1,158 @@ +/* crypto/sha/sha256t.c */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * ==================================================================== + */ +#include +#include +#include + +#include +#include + +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA256) +int main(int argc, char *argv[]) +{ + printf("No SHA256 support\n"); + return (0); +} +#else + +unsigned char app_b1[SHA256_DIGEST_LENGTH] = { + 0xba, 0x78, 0x16, 0xbf, 0x8f, 0x01, 0xcf, 0xea, + 0x41, 0x41, 0x40, 0xde, 0x5d, 0xae, 0x22, 0x23, + 0xb0, 0x03, 0x61, 0xa3, 0x96, 0x17, 0x7a, 0x9c, + 0xb4, 0x10, 0xff, 0x61, 0xf2, 0x00, 0x15, 0xad +}; + +unsigned char app_b2[SHA256_DIGEST_LENGTH] = { + 0x24, 0x8d, 0x6a, 0x61, 0xd2, 0x06, 0x38, 0xb8, + 0xe5, 0xc0, 0x26, 0x93, 0x0c, 0x3e, 0x60, 0x39, + 0xa3, 0x3c, 0xe4, 0x59, 0x64, 0xff, 0x21, 0x67, + 0xf6, 0xec, 0xed, 0xd4, 0x19, 0xdb, 0x06, 0xc1 +}; + +unsigned char app_b3[SHA256_DIGEST_LENGTH] = { + 0xcd, 0xc7, 0x6e, 0x5c, 0x99, 0x14, 0xfb, 0x92, + 0x81, 0xa1, 0xc7, 0xe2, 0x84, 0xd7, 0x3e, 0x67, + 0xf1, 0x80, 0x9a, 0x48, 0xa4, 0x97, 0x20, 0x0e, + 0x04, 0x6d, 0x39, 0xcc, 0xc7, 0x11, 0x2c, 0xd0 +}; + +unsigned char addenum_1[SHA224_DIGEST_LENGTH] = { + 0x23, 0x09, 0x7d, 0x22, 0x34, 0x05, 0xd8, 0x22, + 0x86, 0x42, 0xa4, 0x77, 0xbd, 0xa2, 0x55, 0xb3, + 0x2a, 0xad, 0xbc, 0xe4, 0xbd, 0xa0, 0xb3, 0xf7, + 0xe3, 0x6c, 0x9d, 0xa7 +}; + +unsigned char addenum_2[SHA224_DIGEST_LENGTH] = { + 0x75, 0x38, 0x8b, 0x16, 0x51, 0x27, 0x76, 0xcc, + 0x5d, 0xba, 0x5d, 0xa1, 0xfd, 0x89, 0x01, 0x50, + 0xb0, 0xc6, 0x45, 0x5c, 0xb4, 0xf5, 0x8b, 0x19, + 0x52, 0x52, 0x25, 0x25 +}; + +unsigned char addenum_3[SHA224_DIGEST_LENGTH] = { + 0x20, 0x79, 0x46, 0x55, 0x98, 0x0c, 0x91, 0xd8, + 0xbb, 0xb4, 0xc1, 0xea, 0x97, 0x61, 0x8a, 0x4b, + 0xf0, 0x3f, 0x42, 0x58, 0x19, 0x48, 0xb2, 0xee, + 0x4e, 0xe7, 0xad, 0x67 +}; + +int main(int argc, char **argv) +{ + unsigned char md[SHA256_DIGEST_LENGTH]; + int i; + EVP_MD_CTX evp; + + fprintf(stdout, "Testing SHA-256 "); + + EVP_Digest("abc", 3, md, NULL, EVP_sha256(), NULL); + if (memcmp(md, app_b1, sizeof(app_b1))) { + fflush(stdout); + fprintf(stderr, "\nTEST 1 of 3 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + EVP_Digest("abcdbcde" "cdefdefg" "efghfghi" "ghijhijk" + "ijkljklm" "klmnlmno" "mnopnopq", 56, md, NULL, EVP_sha256(), + NULL); + if (memcmp(md, app_b2, sizeof(app_b2))) { + fflush(stdout); + fprintf(stderr, "\nTEST 2 of 3 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + EVP_MD_CTX_init(&evp); + EVP_DigestInit_ex(&evp, EVP_sha256(), NULL); + for (i = 0; i < 1000000; i += 160) + EVP_DigestUpdate(&evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa", + (1000000 - i) < 160 ? 1000000 - i : 160); + EVP_DigestFinal_ex(&evp, md, NULL); + EVP_MD_CTX_cleanup(&evp); + + if (memcmp(md, app_b3, sizeof(app_b3))) { + fflush(stdout); + fprintf(stderr, "\nTEST 3 of 3 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + fprintf(stdout, " passed.\n"); + fflush(stdout); + + fprintf(stdout, "Testing SHA-224 "); + + EVP_Digest("abc", 3, md, NULL, EVP_sha224(), NULL); + if (memcmp(md, addenum_1, sizeof(addenum_1))) { + fflush(stdout); + fprintf(stderr, "\nTEST 1 of 3 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + EVP_Digest("abcdbcde" "cdefdefg" "efghfghi" "ghijhijk" + "ijkljklm" "klmnlmno" "mnopnopq", 56, md, NULL, EVP_sha224(), + NULL); + if (memcmp(md, addenum_2, sizeof(addenum_2))) { + fflush(stdout); + fprintf(stderr, "\nTEST 2 of 3 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + EVP_MD_CTX_init(&evp); + EVP_DigestInit_ex(&evp, EVP_sha224(), NULL); + for (i = 0; i < 1000000; i += 64) + EVP_DigestUpdate(&evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa", + (1000000 - i) < 64 ? 1000000 - i : 64); + EVP_DigestFinal_ex(&evp, md, NULL); + EVP_MD_CTX_cleanup(&evp); + + if (memcmp(md, addenum_3, sizeof(addenum_3))) { + fflush(stdout); + fprintf(stderr, "\nTEST 3 of 3 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + fprintf(stdout, " passed.\n"); + fflush(stdout); + + return 0; +} +#endif diff --git a/libs/openssl/crypto/sha/sha512.c b/libs/openssl/crypto/sha/sha512.c new file mode 100644 index 00000000..de0aad8c --- /dev/null +++ b/libs/openssl/crypto/sha/sha512.c @@ -0,0 +1,671 @@ +/* crypto/sha/sha512.c */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved + * according to the OpenSSL license [found in ../../LICENSE]. + * ==================================================================== + */ +#include +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA512) +/*- + * IMPLEMENTATION NOTES. + * + * As you might have noticed 32-bit hash algorithms: + * + * - permit SHA_LONG to be wider than 32-bit (case on CRAY); + * - optimized versions implement two transform functions: one operating + * on [aligned] data in host byte order and one - on data in input + * stream byte order; + * - share common byte-order neutral collector and padding function + * implementations, ../md32_common.h; + * + * Neither of the above applies to this SHA-512 implementations. Reasons + * [in reverse order] are: + * + * - it's the only 64-bit hash algorithm for the moment of this writing, + * there is no need for common collector/padding implementation [yet]; + * - by supporting only one transform function [which operates on + * *aligned* data in input stream byte order, big-endian in this case] + * we minimize burden of maintenance in two ways: a) collector/padding + * function is simpler; b) only one transform function to stare at; + * - SHA_LONG64 is required to be exactly 64-bit in order to be able to + * apply a number of optimizations to mitigate potential performance + * penalties caused by previous design decision; + * + * Caveat lector. + * + * Implementation relies on the fact that "long long" is 64-bit on + * both 32- and 64-bit platforms. If some compiler vendor comes up + * with 128-bit long long, adjustment to sha.h would be required. + * As this implementation relies on 64-bit integer type, it's totally + * inappropriate for platforms which don't support it, most notably + * 16-bit platforms. + * + */ +# include +# include + +# include +# include +# include + +# include "cryptlib.h" + +const char SHA512_version[] = "SHA-512" OPENSSL_VERSION_PTEXT; + +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) || \ + defined(__s390__) || defined(__s390x__) || \ + defined(SHA512_ASM) +# define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA +# endif + +fips_md_init_ctx(SHA384, SHA512) +{ + c->h[0] = U64(0xcbbb9d5dc1059ed8); + c->h[1] = U64(0x629a292a367cd507); + c->h[2] = U64(0x9159015a3070dd17); + c->h[3] = U64(0x152fecd8f70e5939); + c->h[4] = U64(0x67332667ffc00b31); + c->h[5] = U64(0x8eb44a8768581511); + c->h[6] = U64(0xdb0c2e0d64f98fa7); + c->h[7] = U64(0x47b5481dbefa4fa4); + + c->Nl = 0; + c->Nh = 0; + c->num = 0; + c->md_len = SHA384_DIGEST_LENGTH; + return 1; +} + +fips_md_init(SHA512) +{ + c->h[0] = U64(0x6a09e667f3bcc908); + c->h[1] = U64(0xbb67ae8584caa73b); + c->h[2] = U64(0x3c6ef372fe94f82b); + c->h[3] = U64(0xa54ff53a5f1d36f1); + c->h[4] = U64(0x510e527fade682d1); + c->h[5] = U64(0x9b05688c2b3e6c1f); + c->h[6] = U64(0x1f83d9abfb41bd6b); + c->h[7] = U64(0x5be0cd19137e2179); + + c->Nl = 0; + c->Nh = 0; + c->num = 0; + c->md_len = SHA512_DIGEST_LENGTH; + return 1; +} + +# ifndef SHA512_ASM +static +# endif +void sha512_block_data_order(SHA512_CTX *ctx, const void *in, size_t num); + +int SHA512_Final(unsigned char *md, SHA512_CTX *c) +{ + unsigned char *p = (unsigned char *)c->u.p; + size_t n = c->num; + + p[n] = 0x80; /* There always is a room for one */ + n++; + if (n > (sizeof(c->u) - 16)) + memset(p + n, 0, sizeof(c->u) - n), n = 0, + sha512_block_data_order(c, p, 1); + + memset(p + n, 0, sizeof(c->u) - 16 - n); +# ifdef B_ENDIAN + c->u.d[SHA_LBLOCK - 2] = c->Nh; + c->u.d[SHA_LBLOCK - 1] = c->Nl; +# else + p[sizeof(c->u) - 1] = (unsigned char)(c->Nl); + p[sizeof(c->u) - 2] = (unsigned char)(c->Nl >> 8); + p[sizeof(c->u) - 3] = (unsigned char)(c->Nl >> 16); + p[sizeof(c->u) - 4] = (unsigned char)(c->Nl >> 24); + p[sizeof(c->u) - 5] = (unsigned char)(c->Nl >> 32); + p[sizeof(c->u) - 6] = (unsigned char)(c->Nl >> 40); + p[sizeof(c->u) - 7] = (unsigned char)(c->Nl >> 48); + p[sizeof(c->u) - 8] = (unsigned char)(c->Nl >> 56); + p[sizeof(c->u) - 9] = (unsigned char)(c->Nh); + p[sizeof(c->u) - 10] = (unsigned char)(c->Nh >> 8); + p[sizeof(c->u) - 11] = (unsigned char)(c->Nh >> 16); + p[sizeof(c->u) - 12] = (unsigned char)(c->Nh >> 24); + p[sizeof(c->u) - 13] = (unsigned char)(c->Nh >> 32); + p[sizeof(c->u) - 14] = (unsigned char)(c->Nh >> 40); + p[sizeof(c->u) - 15] = (unsigned char)(c->Nh >> 48); + p[sizeof(c->u) - 16] = (unsigned char)(c->Nh >> 56); +# endif + + sha512_block_data_order(c, p, 1); + + if (md == 0) + return 0; + + switch (c->md_len) { + /* Let compiler decide if it's appropriate to unroll... */ + case SHA384_DIGEST_LENGTH: + for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) { + SHA_LONG64 t = c->h[n]; + + *(md++) = (unsigned char)(t >> 56); + *(md++) = (unsigned char)(t >> 48); + *(md++) = (unsigned char)(t >> 40); + *(md++) = (unsigned char)(t >> 32); + *(md++) = (unsigned char)(t >> 24); + *(md++) = (unsigned char)(t >> 16); + *(md++) = (unsigned char)(t >> 8); + *(md++) = (unsigned char)(t); + } + break; + case SHA512_DIGEST_LENGTH: + for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) { + SHA_LONG64 t = c->h[n]; + + *(md++) = (unsigned char)(t >> 56); + *(md++) = (unsigned char)(t >> 48); + *(md++) = (unsigned char)(t >> 40); + *(md++) = (unsigned char)(t >> 32); + *(md++) = (unsigned char)(t >> 24); + *(md++) = (unsigned char)(t >> 16); + *(md++) = (unsigned char)(t >> 8); + *(md++) = (unsigned char)(t); + } + break; + /* ... as well as make sure md_len is not abused. */ + default: + return 0; + } + + return 1; +} + +int SHA384_Final(unsigned char *md, SHA512_CTX *c) +{ + return SHA512_Final(md, c); +} + +int SHA512_Update(SHA512_CTX *c, const void *_data, size_t len) +{ + SHA_LONG64 l; + unsigned char *p = c->u.p; + const unsigned char *data = (const unsigned char *)_data; + + if (len == 0) + return 1; + + l = (c->Nl + (((SHA_LONG64) len) << 3)) & U64(0xffffffffffffffff); + if (l < c->Nl) + c->Nh++; + if (sizeof(len) >= 8) + c->Nh += (((SHA_LONG64) len) >> 61); + c->Nl = l; + + if (c->num != 0) { + size_t n = sizeof(c->u) - c->num; + + if (len < n) { + memcpy(p + c->num, data, len), c->num += (unsigned int)len; + return 1; + } else { + memcpy(p + c->num, data, n), c->num = 0; + len -= n, data += n; + sha512_block_data_order(c, p, 1); + } + } + + if (len >= sizeof(c->u)) { +# ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA + if ((size_t)data % sizeof(c->u.d[0]) != 0) + while (len >= sizeof(c->u)) + memcpy(p, data, sizeof(c->u)), + sha512_block_data_order(c, p, 1), + len -= sizeof(c->u), data += sizeof(c->u); + else +# endif + sha512_block_data_order(c, data, len / sizeof(c->u)), + data += len, len %= sizeof(c->u), data -= len; + } + + if (len != 0) + memcpy(p, data, len), c->num = (int)len; + + return 1; +} + +int SHA384_Update(SHA512_CTX *c, const void *data, size_t len) +{ + return SHA512_Update(c, data, len); +} + +void SHA512_Transform(SHA512_CTX *c, const unsigned char *data) +{ +# ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA + if ((size_t)data % sizeof(c->u.d[0]) != 0) + memcpy(c->u.p, data, sizeof(c->u.p)), data = c->u.p; +# endif + sha512_block_data_order(c, data, 1); +} + +unsigned char *SHA384(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA512_CTX c; + static unsigned char m[SHA384_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + SHA384_Init(&c); + SHA512_Update(&c, d, n); + SHA512_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); + return (md); +} + +unsigned char *SHA512(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA512_CTX c; + static unsigned char m[SHA512_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + SHA512_Init(&c); + SHA512_Update(&c, d, n); + SHA512_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); + return (md); +} + +# ifndef SHA512_ASM +static const SHA_LONG64 K512[80] = { + U64(0x428a2f98d728ae22), U64(0x7137449123ef65cd), + U64(0xb5c0fbcfec4d3b2f), U64(0xe9b5dba58189dbbc), + U64(0x3956c25bf348b538), U64(0x59f111f1b605d019), + U64(0x923f82a4af194f9b), U64(0xab1c5ed5da6d8118), + U64(0xd807aa98a3030242), U64(0x12835b0145706fbe), + U64(0x243185be4ee4b28c), U64(0x550c7dc3d5ffb4e2), + U64(0x72be5d74f27b896f), U64(0x80deb1fe3b1696b1), + U64(0x9bdc06a725c71235), U64(0xc19bf174cf692694), + U64(0xe49b69c19ef14ad2), U64(0xefbe4786384f25e3), + U64(0x0fc19dc68b8cd5b5), U64(0x240ca1cc77ac9c65), + U64(0x2de92c6f592b0275), U64(0x4a7484aa6ea6e483), + U64(0x5cb0a9dcbd41fbd4), U64(0x76f988da831153b5), + U64(0x983e5152ee66dfab), U64(0xa831c66d2db43210), + U64(0xb00327c898fb213f), U64(0xbf597fc7beef0ee4), + U64(0xc6e00bf33da88fc2), U64(0xd5a79147930aa725), + U64(0x06ca6351e003826f), U64(0x142929670a0e6e70), + U64(0x27b70a8546d22ffc), U64(0x2e1b21385c26c926), + U64(0x4d2c6dfc5ac42aed), U64(0x53380d139d95b3df), + U64(0x650a73548baf63de), U64(0x766a0abb3c77b2a8), + U64(0x81c2c92e47edaee6), U64(0x92722c851482353b), + U64(0xa2bfe8a14cf10364), U64(0xa81a664bbc423001), + U64(0xc24b8b70d0f89791), U64(0xc76c51a30654be30), + U64(0xd192e819d6ef5218), U64(0xd69906245565a910), + U64(0xf40e35855771202a), U64(0x106aa07032bbd1b8), + U64(0x19a4c116b8d2d0c8), U64(0x1e376c085141ab53), + U64(0x2748774cdf8eeb99), U64(0x34b0bcb5e19b48a8), + U64(0x391c0cb3c5c95a63), U64(0x4ed8aa4ae3418acb), + U64(0x5b9cca4f7763e373), U64(0x682e6ff3d6b2b8a3), + U64(0x748f82ee5defb2fc), U64(0x78a5636f43172f60), + U64(0x84c87814a1f0ab72), U64(0x8cc702081a6439ec), + U64(0x90befffa23631e28), U64(0xa4506cebde82bde9), + U64(0xbef9a3f7b2c67915), U64(0xc67178f2e372532b), + U64(0xca273eceea26619c), U64(0xd186b8c721c0c207), + U64(0xeada7dd6cde0eb1e), U64(0xf57d4f7fee6ed178), + U64(0x06f067aa72176fba), U64(0x0a637dc5a2c898a6), + U64(0x113f9804bef90dae), U64(0x1b710b35131c471b), + U64(0x28db77f523047d84), U64(0x32caab7b40c72493), + U64(0x3c9ebe0a15c9bebc), U64(0x431d67c49c100d4c), + U64(0x4cc5d4becb3e42b6), U64(0x597f299cfc657e2a), + U64(0x5fcb6fab3ad6faec), U64(0x6c44198c4a475817) +}; + +# ifndef PEDANTIC +# if defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(__x86_64) || defined(__x86_64__) +# define ROTR(a,n) ({ SHA_LONG64 ret; \ + asm ("rorq %1,%0" \ + : "=r"(ret) \ + : "J"(n),"0"(a) \ + : "cc"); ret; }) +# if !defined(B_ENDIAN) +# define PULL64(x) ({ SHA_LONG64 ret=*((const SHA_LONG64 *)(&(x))); \ + asm ("bswapq %0" \ + : "=r"(ret) \ + : "0"(ret)); ret; }) +# endif +# elif (defined(__i386) || defined(__i386__)) && !defined(B_ENDIAN) +# if defined(I386_ONLY) +# define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ + unsigned int hi=p[0],lo=p[1]; \ + asm("xchgb %%ah,%%al;xchgb %%dh,%%dl;"\ + "roll $16,%%eax; roll $16,%%edx; "\ + "xchgb %%ah,%%al;xchgb %%dh,%%dl;" \ + : "=a"(lo),"=d"(hi) \ + : "0"(lo),"1"(hi) : "cc"); \ + ((SHA_LONG64)hi)<<32|lo; }) +# else +# define PULL64(x) ({ const unsigned int *p=(const unsigned int *)(&(x));\ + unsigned int hi=p[0],lo=p[1]; \ + asm ("bswapl %0; bswapl %1;" \ + : "=r"(lo),"=r"(hi) \ + : "0"(lo),"1"(hi)); \ + ((SHA_LONG64)hi)<<32|lo; }) +# endif +# elif (defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64) +# define ROTR(a,n) ({ SHA_LONG64 ret; \ + asm ("rotrdi %0,%1,%2" \ + : "=r"(ret) \ + : "r"(a),"K"(n)); ret; }) +# endif +# elif defined(_MSC_VER) +# if defined(_WIN64) /* applies to both IA-64 and AMD64 */ +# pragma intrinsic(_rotr64) +# define ROTR(a,n) _rotr64((a),n) +# endif +# if defined(_M_IX86) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM) +# if defined(I386_ONLY) +static SHA_LONG64 __fastcall __pull64be(const void *x) +{ + _asm mov edx,[ecx + 0] + _asm mov eax,[ecx + 4] +_asm xchg dh, dl + _asm xchg ah, al + _asm rol edx, 16 _asm rol eax, 16 _asm xchg dh, dl _asm xchg ah, al} +# else +static SHA_LONG64 __fastcall __pull64be(const void *x) +{ + _asm mov edx,[ecx + 0] + _asm mov eax,[ecx + 4] +_asm bswap edx _asm bswap eax} +# endif +# define PULL64(x) __pull64be(&(x)) +# if _MSC_VER<=1200 +# pragma inline_depth(0) +# endif +# endif +# endif +# endif +# ifndef PULL64 +# define B(x,j) (((SHA_LONG64)(*(((const unsigned char *)(&x))+j)))<<((7-j)*8)) +# define PULL64(x) (B(x,0)|B(x,1)|B(x,2)|B(x,3)|B(x,4)|B(x,5)|B(x,6)|B(x,7)) +# endif +# ifndef ROTR +# define ROTR(x,s) (((x)>>s) | (x)<<(64-s)) +# endif +# define Sigma0(x) (ROTR((x),28) ^ ROTR((x),34) ^ ROTR((x),39)) +# define Sigma1(x) (ROTR((x),14) ^ ROTR((x),18) ^ ROTR((x),41)) +# define sigma0(x) (ROTR((x),1) ^ ROTR((x),8) ^ ((x)>>7)) +# define sigma1(x) (ROTR((x),19) ^ ROTR((x),61) ^ ((x)>>6)) +# define Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +# define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +# if defined(__i386) || defined(__i386__) || defined(_M_IX86) +/* + * This code should give better results on 32-bit CPU with less than + * ~24 registers, both size and performance wise... + */ static void sha512_block_data_order(SHA512_CTX *ctx, const void *in, + size_t num) +{ + const SHA_LONG64 *W = in; + SHA_LONG64 A, E, T; + SHA_LONG64 X[9 + 80], *F; + int i; + + while (num--) { + + F = X + 80; + A = ctx->h[0]; + F[1] = ctx->h[1]; + F[2] = ctx->h[2]; + F[3] = ctx->h[3]; + E = ctx->h[4]; + F[5] = ctx->h[5]; + F[6] = ctx->h[6]; + F[7] = ctx->h[7]; + + for (i = 0; i < 16; i++, F--) { +# ifdef B_ENDIAN + T = W[i]; +# else + T = PULL64(W[i]); +# endif + F[0] = A; + F[4] = E; + F[8] = T; + T += F[7] + Sigma1(E) + Ch(E, F[5], F[6]) + K512[i]; + E = F[3] + T; + A = T + Sigma0(A) + Maj(A, F[1], F[2]); + } + + for (; i < 80; i++, F--) { + T = sigma0(F[8 + 16 - 1]); + T += sigma1(F[8 + 16 - 14]); + T += F[8 + 16] + F[8 + 16 - 9]; + + F[0] = A; + F[4] = E; + F[8] = T; + T += F[7] + Sigma1(E) + Ch(E, F[5], F[6]) + K512[i]; + E = F[3] + T; + A = T + Sigma0(A) + Maj(A, F[1], F[2]); + } + + ctx->h[0] += A; + ctx->h[1] += F[1]; + ctx->h[2] += F[2]; + ctx->h[3] += F[3]; + ctx->h[4] += E; + ctx->h[5] += F[5]; + ctx->h[6] += F[6]; + ctx->h[7] += F[7]; + + W += SHA_LBLOCK; + } +} + +# elif defined(OPENSSL_SMALL_FOOTPRINT) +static void sha512_block_data_order(SHA512_CTX *ctx, const void *in, + size_t num) +{ + const SHA_LONG64 *W = in; + SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1, T2; + SHA_LONG64 X[16]; + int i; + + while (num--) { + + a = ctx->h[0]; + b = ctx->h[1]; + c = ctx->h[2]; + d = ctx->h[3]; + e = ctx->h[4]; + f = ctx->h[5]; + g = ctx->h[6]; + h = ctx->h[7]; + + for (i = 0; i < 16; i++) { +# ifdef B_ENDIAN + T1 = X[i] = W[i]; +# else + T1 = X[i] = PULL64(W[i]); +# endif + T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i]; + T2 = Sigma0(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + for (; i < 80; i++) { + s0 = X[(i + 1) & 0x0f]; + s0 = sigma0(s0); + s1 = X[(i + 14) & 0x0f]; + s1 = sigma1(s1); + + T1 = X[i & 0xf] += s0 + s1 + X[(i + 9) & 0xf]; + T1 += h + Sigma1(e) + Ch(e, f, g) + K512[i]; + T2 = Sigma0(a) + Maj(a, b, c); + h = g; + g = f; + f = e; + e = d + T1; + d = c; + c = b; + b = a; + a = T1 + T2; + } + + ctx->h[0] += a; + ctx->h[1] += b; + ctx->h[2] += c; + ctx->h[3] += d; + ctx->h[4] += e; + ctx->h[5] += f; + ctx->h[6] += g; + ctx->h[7] += h; + + W += SHA_LBLOCK; + } +} + +# else +# define ROUND_00_15(i,a,b,c,d,e,f,g,h) do { \ + T1 += h + Sigma1(e) + Ch(e,f,g) + K512[i]; \ + h = Sigma0(a) + Maj(a,b,c); \ + d += T1; h += T1; } while (0) +# define ROUND_16_80(i,j,a,b,c,d,e,f,g,h,X) do { \ + s0 = X[(j+1)&0x0f]; s0 = sigma0(s0); \ + s1 = X[(j+14)&0x0f]; s1 = sigma1(s1); \ + T1 = X[(j)&0x0f] += s0 + s1 + X[(j+9)&0x0f]; \ + ROUND_00_15(i+j,a,b,c,d,e,f,g,h); } while (0) +static void sha512_block_data_order(SHA512_CTX *ctx, const void *in, + size_t num) +{ + const SHA_LONG64 *W = in; + SHA_LONG64 a, b, c, d, e, f, g, h, s0, s1, T1; + SHA_LONG64 X[16]; + int i; + + while (num--) { + + a = ctx->h[0]; + b = ctx->h[1]; + c = ctx->h[2]; + d = ctx->h[3]; + e = ctx->h[4]; + f = ctx->h[5]; + g = ctx->h[6]; + h = ctx->h[7]; + +# ifdef B_ENDIAN + T1 = X[0] = W[0]; + ROUND_00_15(0, a, b, c, d, e, f, g, h); + T1 = X[1] = W[1]; + ROUND_00_15(1, h, a, b, c, d, e, f, g); + T1 = X[2] = W[2]; + ROUND_00_15(2, g, h, a, b, c, d, e, f); + T1 = X[3] = W[3]; + ROUND_00_15(3, f, g, h, a, b, c, d, e); + T1 = X[4] = W[4]; + ROUND_00_15(4, e, f, g, h, a, b, c, d); + T1 = X[5] = W[5]; + ROUND_00_15(5, d, e, f, g, h, a, b, c); + T1 = X[6] = W[6]; + ROUND_00_15(6, c, d, e, f, g, h, a, b); + T1 = X[7] = W[7]; + ROUND_00_15(7, b, c, d, e, f, g, h, a); + T1 = X[8] = W[8]; + ROUND_00_15(8, a, b, c, d, e, f, g, h); + T1 = X[9] = W[9]; + ROUND_00_15(9, h, a, b, c, d, e, f, g); + T1 = X[10] = W[10]; + ROUND_00_15(10, g, h, a, b, c, d, e, f); + T1 = X[11] = W[11]; + ROUND_00_15(11, f, g, h, a, b, c, d, e); + T1 = X[12] = W[12]; + ROUND_00_15(12, e, f, g, h, a, b, c, d); + T1 = X[13] = W[13]; + ROUND_00_15(13, d, e, f, g, h, a, b, c); + T1 = X[14] = W[14]; + ROUND_00_15(14, c, d, e, f, g, h, a, b); + T1 = X[15] = W[15]; + ROUND_00_15(15, b, c, d, e, f, g, h, a); +# else + T1 = X[0] = PULL64(W[0]); + ROUND_00_15(0, a, b, c, d, e, f, g, h); + T1 = X[1] = PULL64(W[1]); + ROUND_00_15(1, h, a, b, c, d, e, f, g); + T1 = X[2] = PULL64(W[2]); + ROUND_00_15(2, g, h, a, b, c, d, e, f); + T1 = X[3] = PULL64(W[3]); + ROUND_00_15(3, f, g, h, a, b, c, d, e); + T1 = X[4] = PULL64(W[4]); + ROUND_00_15(4, e, f, g, h, a, b, c, d); + T1 = X[5] = PULL64(W[5]); + ROUND_00_15(5, d, e, f, g, h, a, b, c); + T1 = X[6] = PULL64(W[6]); + ROUND_00_15(6, c, d, e, f, g, h, a, b); + T1 = X[7] = PULL64(W[7]); + ROUND_00_15(7, b, c, d, e, f, g, h, a); + T1 = X[8] = PULL64(W[8]); + ROUND_00_15(8, a, b, c, d, e, f, g, h); + T1 = X[9] = PULL64(W[9]); + ROUND_00_15(9, h, a, b, c, d, e, f, g); + T1 = X[10] = PULL64(W[10]); + ROUND_00_15(10, g, h, a, b, c, d, e, f); + T1 = X[11] = PULL64(W[11]); + ROUND_00_15(11, f, g, h, a, b, c, d, e); + T1 = X[12] = PULL64(W[12]); + ROUND_00_15(12, e, f, g, h, a, b, c, d); + T1 = X[13] = PULL64(W[13]); + ROUND_00_15(13, d, e, f, g, h, a, b, c); + T1 = X[14] = PULL64(W[14]); + ROUND_00_15(14, c, d, e, f, g, h, a, b); + T1 = X[15] = PULL64(W[15]); + ROUND_00_15(15, b, c, d, e, f, g, h, a); +# endif + + for (i = 16; i < 80; i += 16) { + ROUND_16_80(i, 0, a, b, c, d, e, f, g, h, X); + ROUND_16_80(i, 1, h, a, b, c, d, e, f, g, X); + ROUND_16_80(i, 2, g, h, a, b, c, d, e, f, X); + ROUND_16_80(i, 3, f, g, h, a, b, c, d, e, X); + ROUND_16_80(i, 4, e, f, g, h, a, b, c, d, X); + ROUND_16_80(i, 5, d, e, f, g, h, a, b, c, X); + ROUND_16_80(i, 6, c, d, e, f, g, h, a, b, X); + ROUND_16_80(i, 7, b, c, d, e, f, g, h, a, X); + ROUND_16_80(i, 8, a, b, c, d, e, f, g, h, X); + ROUND_16_80(i, 9, h, a, b, c, d, e, f, g, X); + ROUND_16_80(i, 10, g, h, a, b, c, d, e, f, X); + ROUND_16_80(i, 11, f, g, h, a, b, c, d, e, X); + ROUND_16_80(i, 12, e, f, g, h, a, b, c, d, X); + ROUND_16_80(i, 13, d, e, f, g, h, a, b, c, X); + ROUND_16_80(i, 14, c, d, e, f, g, h, a, b, X); + ROUND_16_80(i, 15, b, c, d, e, f, g, h, a, X); + } + + ctx->h[0] += a; + ctx->h[1] += b; + ctx->h[2] += c; + ctx->h[3] += d; + ctx->h[4] += e; + ctx->h[5] += f; + ctx->h[6] += g; + ctx->h[7] += h; + + W += SHA_LBLOCK; + } +} + +# endif + +# endif /* SHA512_ASM */ + +#else /* !OPENSSL_NO_SHA512 */ + +# if defined(PEDANTIC) || defined(__DECC) || defined(OPENSSL_SYS_MACOSX) +static void *dummy = &dummy; +# endif + +#endif /* !OPENSSL_NO_SHA512 */ diff --git a/libs/openssl/crypto/sha/sha512t.c b/libs/openssl/crypto/sha/sha512t.c new file mode 100644 index 00000000..178882fc --- /dev/null +++ b/libs/openssl/crypto/sha/sha512t.c @@ -0,0 +1,196 @@ +/* crypto/sha/sha512t.c */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * ==================================================================== + */ +#include +#include +#include + +#include +#include +#include + +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA512) +int main(int argc, char *argv[]) +{ + printf("No SHA512 support\n"); + return (0); +} +#else + +unsigned char app_c1[SHA512_DIGEST_LENGTH] = { + 0xdd, 0xaf, 0x35, 0xa1, 0x93, 0x61, 0x7a, 0xba, + 0xcc, 0x41, 0x73, 0x49, 0xae, 0x20, 0x41, 0x31, + 0x12, 0xe6, 0xfa, 0x4e, 0x89, 0xa9, 0x7e, 0xa2, + 0x0a, 0x9e, 0xee, 0xe6, 0x4b, 0x55, 0xd3, 0x9a, + 0x21, 0x92, 0x99, 0x2a, 0x27, 0x4f, 0xc1, 0xa8, + 0x36, 0xba, 0x3c, 0x23, 0xa3, 0xfe, 0xeb, 0xbd, + 0x45, 0x4d, 0x44, 0x23, 0x64, 0x3c, 0xe8, 0x0e, + 0x2a, 0x9a, 0xc9, 0x4f, 0xa5, 0x4c, 0xa4, 0x9f +}; + +unsigned char app_c2[SHA512_DIGEST_LENGTH] = { + 0x8e, 0x95, 0x9b, 0x75, 0xda, 0xe3, 0x13, 0xda, + 0x8c, 0xf4, 0xf7, 0x28, 0x14, 0xfc, 0x14, 0x3f, + 0x8f, 0x77, 0x79, 0xc6, 0xeb, 0x9f, 0x7f, 0xa1, + 0x72, 0x99, 0xae, 0xad, 0xb6, 0x88, 0x90, 0x18, + 0x50, 0x1d, 0x28, 0x9e, 0x49, 0x00, 0xf7, 0xe4, + 0x33, 0x1b, 0x99, 0xde, 0xc4, 0xb5, 0x43, 0x3a, + 0xc7, 0xd3, 0x29, 0xee, 0xb6, 0xdd, 0x26, 0x54, + 0x5e, 0x96, 0xe5, 0x5b, 0x87, 0x4b, 0xe9, 0x09 +}; + +unsigned char app_c3[SHA512_DIGEST_LENGTH] = { + 0xe7, 0x18, 0x48, 0x3d, 0x0c, 0xe7, 0x69, 0x64, + 0x4e, 0x2e, 0x42, 0xc7, 0xbc, 0x15, 0xb4, 0x63, + 0x8e, 0x1f, 0x98, 0xb1, 0x3b, 0x20, 0x44, 0x28, + 0x56, 0x32, 0xa8, 0x03, 0xaf, 0xa9, 0x73, 0xeb, + 0xde, 0x0f, 0xf2, 0x44, 0x87, 0x7e, 0xa6, 0x0a, + 0x4c, 0xb0, 0x43, 0x2c, 0xe5, 0x77, 0xc3, 0x1b, + 0xeb, 0x00, 0x9c, 0x5c, 0x2c, 0x49, 0xaa, 0x2e, + 0x4e, 0xad, 0xb2, 0x17, 0xad, 0x8c, 0xc0, 0x9b +}; + +unsigned char app_d1[SHA384_DIGEST_LENGTH] = { + 0xcb, 0x00, 0x75, 0x3f, 0x45, 0xa3, 0x5e, 0x8b, + 0xb5, 0xa0, 0x3d, 0x69, 0x9a, 0xc6, 0x50, 0x07, + 0x27, 0x2c, 0x32, 0xab, 0x0e, 0xde, 0xd1, 0x63, + 0x1a, 0x8b, 0x60, 0x5a, 0x43, 0xff, 0x5b, 0xed, + 0x80, 0x86, 0x07, 0x2b, 0xa1, 0xe7, 0xcc, 0x23, + 0x58, 0xba, 0xec, 0xa1, 0x34, 0xc8, 0x25, 0xa7 +}; + +unsigned char app_d2[SHA384_DIGEST_LENGTH] = { + 0x09, 0x33, 0x0c, 0x33, 0xf7, 0x11, 0x47, 0xe8, + 0x3d, 0x19, 0x2f, 0xc7, 0x82, 0xcd, 0x1b, 0x47, + 0x53, 0x11, 0x1b, 0x17, 0x3b, 0x3b, 0x05, 0xd2, + 0x2f, 0xa0, 0x80, 0x86, 0xe3, 0xb0, 0xf7, 0x12, + 0xfc, 0xc7, 0xc7, 0x1a, 0x55, 0x7e, 0x2d, 0xb9, + 0x66, 0xc3, 0xe9, 0xfa, 0x91, 0x74, 0x60, 0x39 +}; + +unsigned char app_d3[SHA384_DIGEST_LENGTH] = { + 0x9d, 0x0e, 0x18, 0x09, 0x71, 0x64, 0x74, 0xcb, + 0x08, 0x6e, 0x83, 0x4e, 0x31, 0x0a, 0x4a, 0x1c, + 0xed, 0x14, 0x9e, 0x9c, 0x00, 0xf2, 0x48, 0x52, + 0x79, 0x72, 0xce, 0xc5, 0x70, 0x4c, 0x2a, 0x5b, + 0x07, 0xb8, 0xb3, 0xdc, 0x38, 0xec, 0xc4, 0xeb, + 0xae, 0x97, 0xdd, 0xd8, 0x7f, 0x3d, 0x89, 0x85 +}; + +int main(int argc, char **argv) +{ + unsigned char md[SHA512_DIGEST_LENGTH]; + int i; + EVP_MD_CTX evp; + +# ifdef OPENSSL_IA32_SSE2 + /* + * Alternative to this is to call OpenSSL_add_all_algorithms... The below + * code is retained exclusively for debugging purposes. + */ + { + char *env; + + if ((env = getenv("OPENSSL_ia32cap"))) + OPENSSL_ia32cap = strtoul(env, NULL, 0); + } +# endif + + fprintf(stdout, "Testing SHA-512 "); + + EVP_Digest("abc", 3, md, NULL, EVP_sha512(), NULL); + if (memcmp(md, app_c1, sizeof(app_c1))) { + fflush(stdout); + fprintf(stderr, "\nTEST 1 of 3 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + EVP_Digest("abcdefgh" "bcdefghi" "cdefghij" "defghijk" + "efghijkl" "fghijklm" "ghijklmn" "hijklmno" + "ijklmnop" "jklmnopq" "klmnopqr" "lmnopqrs" + "mnopqrst" "nopqrstu", 112, md, NULL, EVP_sha512(), NULL); + if (memcmp(md, app_c2, sizeof(app_c2))) { + fflush(stdout); + fprintf(stderr, "\nTEST 2 of 3 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + EVP_MD_CTX_init(&evp); + EVP_DigestInit_ex(&evp, EVP_sha512(), NULL); + for (i = 0; i < 1000000; i += 288) + EVP_DigestUpdate(&evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa", + (1000000 - i) < 288 ? 1000000 - i : 288); + EVP_DigestFinal_ex(&evp, md, NULL); + EVP_MD_CTX_cleanup(&evp); + + if (memcmp(md, app_c3, sizeof(app_c3))) { + fflush(stdout); + fprintf(stderr, "\nTEST 3 of 3 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + fprintf(stdout, " passed.\n"); + fflush(stdout); + + fprintf(stdout, "Testing SHA-384 "); + + EVP_Digest("abc", 3, md, NULL, EVP_sha384(), NULL); + if (memcmp(md, app_d1, sizeof(app_d1))) { + fflush(stdout); + fprintf(stderr, "\nTEST 1 of 3 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + EVP_Digest("abcdefgh" "bcdefghi" "cdefghij" "defghijk" + "efghijkl" "fghijklm" "ghijklmn" "hijklmno" + "ijklmnop" "jklmnopq" "klmnopqr" "lmnopqrs" + "mnopqrst" "nopqrstu", 112, md, NULL, EVP_sha384(), NULL); + if (memcmp(md, app_d2, sizeof(app_d2))) { + fflush(stdout); + fprintf(stderr, "\nTEST 2 of 3 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + EVP_MD_CTX_init(&evp); + EVP_DigestInit_ex(&evp, EVP_sha384(), NULL); + for (i = 0; i < 1000000; i += 64) + EVP_DigestUpdate(&evp, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa", + (1000000 - i) < 64 ? 1000000 - i : 64); + EVP_DigestFinal_ex(&evp, md, NULL); + EVP_MD_CTX_cleanup(&evp); + + if (memcmp(md, app_d3, sizeof(app_d3))) { + fflush(stdout); + fprintf(stderr, "\nTEST 3 of 3 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + fprintf(stdout, " passed.\n"); + fflush(stdout); + + return 0; +} +#endif diff --git a/libs/openssl/crypto/sha/sha_dgst.c b/libs/openssl/crypto/sha/sha_dgst.c new file mode 100644 index 00000000..f77cf5e3 --- /dev/null +++ b/libs/openssl/crypto/sha/sha_dgst.c @@ -0,0 +1,74 @@ +/* crypto/sha/sha1dgst.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#if !defined(OPENSSL_NO_SHA0) && !defined(OPENSSL_NO_SHA) + +# undef SHA_1 +# define SHA_0 + +# include + +const char SHA_version[] = "SHA" OPENSSL_VERSION_PTEXT; + +/* The implementation is in ../md32_common.h */ + +# include "sha_locl.h" + +#endif diff --git a/libs/openssl/crypto/sha/sha_locl.h b/libs/openssl/crypto/sha/sha_locl.h new file mode 100644 index 00000000..03bd411e --- /dev/null +++ b/libs/openssl/crypto/sha/sha_locl.h @@ -0,0 +1,500 @@ +/* crypto/sha/sha_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include + +#include +#include + +#define DATA_ORDER_IS_BIG_ENDIAN + +#define HASH_LONG SHA_LONG +#define HASH_CTX SHA_CTX +#define HASH_CBLOCK SHA_CBLOCK +#define HASH_MAKE_STRING(c,s) do { \ + unsigned long ll; \ + ll=(c)->h0; (void)HOST_l2c(ll,(s)); \ + ll=(c)->h1; (void)HOST_l2c(ll,(s)); \ + ll=(c)->h2; (void)HOST_l2c(ll,(s)); \ + ll=(c)->h3; (void)HOST_l2c(ll,(s)); \ + ll=(c)->h4; (void)HOST_l2c(ll,(s)); \ + } while (0) + +#if defined(SHA_0) + +# define HASH_UPDATE SHA_Update +# define HASH_TRANSFORM SHA_Transform +# define HASH_FINAL SHA_Final +# define HASH_INIT SHA_Init +# define HASH_BLOCK_DATA_ORDER sha_block_data_order +# define Xupdate(a,ix,ia,ib,ic,id) (ix=(a)=(ia^ib^ic^id)) + +static void sha_block_data_order(SHA_CTX *c, const void *p, size_t num); + +#elif defined(SHA_1) + +# define HASH_UPDATE SHA1_Update +# define HASH_TRANSFORM SHA1_Transform +# define HASH_FINAL SHA1_Final +# define HASH_INIT SHA1_Init +# define HASH_BLOCK_DATA_ORDER sha1_block_data_order +# if defined(__MWERKS__) && defined(__MC68K__) + /* Metrowerks for Motorola fails otherwise:-( */ +# define Xupdate(a,ix,ia,ib,ic,id) do { (a)=(ia^ib^ic^id); \ + ix=(a)=ROTATE((a),1); \ + } while (0) +# else +# define Xupdate(a,ix,ia,ib,ic,id) ( (a)=(ia^ib^ic^id), \ + ix=(a)=ROTATE((a),1) \ + ) +# endif + +# ifndef SHA1_ASM +static +# endif +void sha1_block_data_order(SHA_CTX *c, const void *p, size_t num); + +#else +# error "Either SHA_0 or SHA_1 must be defined." +#endif + +#include "md32_common.h" + +#define INIT_DATA_h0 0x67452301UL +#define INIT_DATA_h1 0xefcdab89UL +#define INIT_DATA_h2 0x98badcfeUL +#define INIT_DATA_h3 0x10325476UL +#define INIT_DATA_h4 0xc3d2e1f0UL + +#ifdef SHA_0 +fips_md_init(SHA) +#else +fips_md_init_ctx(SHA1, SHA) +#endif +{ + memset(c, 0, sizeof(*c)); + c->h0 = INIT_DATA_h0; + c->h1 = INIT_DATA_h1; + c->h2 = INIT_DATA_h2; + c->h3 = INIT_DATA_h3; + c->h4 = INIT_DATA_h4; + return 1; +} + +#define K_00_19 0x5a827999UL +#define K_20_39 0x6ed9eba1UL +#define K_40_59 0x8f1bbcdcUL +#define K_60_79 0xca62c1d6UL + +/* + * As pointed out by Wei Dai , F() below can be simplified + * to the code in F_00_19. Wei attributes these optimisations to Peter + * Gutmann's SHS code, and he attributes it to Rich Schroeppel. #define + * F(x,y,z) (((x) & (y)) | ((~(x)) & (z))) I've just become aware of another + * tweak to be made, again from Wei Dai, in F_40_59, (x&a)|(y&a) -> (x|y)&a + */ +#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define F_20_39(b,c,d) ((b) ^ (c) ^ (d)) +#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d))) +#define F_60_79(b,c,d) F_20_39(b,c,d) + +#ifndef OPENSSL_SMALL_FOOTPRINT + +# define BODY_00_15(i,a,b,c,d,e,f,xi) \ + (f)=xi+(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ + (b)=ROTATE((b),30); + +# define BODY_16_19(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \ + Xupdate(f,xi,xa,xb,xc,xd); \ + (f)+=(e)+K_00_19+ROTATE((a),5)+F_00_19((b),(c),(d)); \ + (b)=ROTATE((b),30); + +# define BODY_20_31(i,a,b,c,d,e,f,xi,xa,xb,xc,xd) \ + Xupdate(f,xi,xa,xb,xc,xd); \ + (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ + (b)=ROTATE((b),30); + +# define BODY_32_39(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)+=(e)+K_20_39+ROTATE((a),5)+F_20_39((b),(c),(d)); \ + (b)=ROTATE((b),30); + +# define BODY_40_59(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)+=(e)+K_40_59+ROTATE((a),5)+F_40_59((b),(c),(d)); \ + (b)=ROTATE((b),30); + +# define BODY_60_79(i,a,b,c,d,e,f,xa,xb,xc,xd) \ + Xupdate(f,xa,xa,xb,xc,xd); \ + (f)=xa+(e)+K_60_79+ROTATE((a),5)+F_60_79((b),(c),(d)); \ + (b)=ROTATE((b),30); + +# ifdef X +# undef X +# endif +# ifndef MD32_XARRAY + /* + * Originally X was an array. As it's automatic it's natural + * to expect RISC compiler to accomodate at least part of it in + * the register bank, isn't it? Unfortunately not all compilers + * "find" this expectation reasonable:-( On order to make such + * compilers generate better code I replace X[] with a bunch of + * X0, X1, etc. See the function body below... + * + */ +# define X(i) XX##i +# else + /* + * However! Some compilers (most notably HP C) get overwhelmed by + * that many local variables so that we have to have the way to + * fall down to the original behavior. + */ +# define X(i) XX[i] +# endif + +# if !defined(SHA_1) || !defined(SHA1_ASM) +static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num) +{ + const unsigned char *data = p; + register unsigned MD32_REG_T A, B, C, D, E, T, l; +# ifndef MD32_XARRAY + unsigned MD32_REG_T XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, + XX8, XX9, XX10, XX11, XX12, XX13, XX14, XX15; +# else + SHA_LONG XX[16]; +# endif + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + for (;;) { + const union { + long one; + char little; + } is_endian = { + 1 + }; + + if (!is_endian.little && sizeof(SHA_LONG) == 4 + && ((size_t)p % 4) == 0) { + const SHA_LONG *W = (const SHA_LONG *)data; + + X(0) = W[0]; + X(1) = W[1]; + BODY_00_15(0, A, B, C, D, E, T, X(0)); + X(2) = W[2]; + BODY_00_15(1, T, A, B, C, D, E, X(1)); + X(3) = W[3]; + BODY_00_15(2, E, T, A, B, C, D, X(2)); + X(4) = W[4]; + BODY_00_15(3, D, E, T, A, B, C, X(3)); + X(5) = W[5]; + BODY_00_15(4, C, D, E, T, A, B, X(4)); + X(6) = W[6]; + BODY_00_15(5, B, C, D, E, T, A, X(5)); + X(7) = W[7]; + BODY_00_15(6, A, B, C, D, E, T, X(6)); + X(8) = W[8]; + BODY_00_15(7, T, A, B, C, D, E, X(7)); + X(9) = W[9]; + BODY_00_15(8, E, T, A, B, C, D, X(8)); + X(10) = W[10]; + BODY_00_15(9, D, E, T, A, B, C, X(9)); + X(11) = W[11]; + BODY_00_15(10, C, D, E, T, A, B, X(10)); + X(12) = W[12]; + BODY_00_15(11, B, C, D, E, T, A, X(11)); + X(13) = W[13]; + BODY_00_15(12, A, B, C, D, E, T, X(12)); + X(14) = W[14]; + BODY_00_15(13, T, A, B, C, D, E, X(13)); + X(15) = W[15]; + BODY_00_15(14, E, T, A, B, C, D, X(14)); + BODY_00_15(15, D, E, T, A, B, C, X(15)); + + data += SHA_CBLOCK; + } else { + (void)HOST_c2l(data, l); + X(0) = l; + (void)HOST_c2l(data, l); + X(1) = l; + BODY_00_15(0, A, B, C, D, E, T, X(0)); + (void)HOST_c2l(data, l); + X(2) = l; + BODY_00_15(1, T, A, B, C, D, E, X(1)); + (void)HOST_c2l(data, l); + X(3) = l; + BODY_00_15(2, E, T, A, B, C, D, X(2)); + (void)HOST_c2l(data, l); + X(4) = l; + BODY_00_15(3, D, E, T, A, B, C, X(3)); + (void)HOST_c2l(data, l); + X(5) = l; + BODY_00_15(4, C, D, E, T, A, B, X(4)); + (void)HOST_c2l(data, l); + X(6) = l; + BODY_00_15(5, B, C, D, E, T, A, X(5)); + (void)HOST_c2l(data, l); + X(7) = l; + BODY_00_15(6, A, B, C, D, E, T, X(6)); + (void)HOST_c2l(data, l); + X(8) = l; + BODY_00_15(7, T, A, B, C, D, E, X(7)); + (void)HOST_c2l(data, l); + X(9) = l; + BODY_00_15(8, E, T, A, B, C, D, X(8)); + (void)HOST_c2l(data, l); + X(10) = l; + BODY_00_15(9, D, E, T, A, B, C, X(9)); + (void)HOST_c2l(data, l); + X(11) = l; + BODY_00_15(10, C, D, E, T, A, B, X(10)); + (void)HOST_c2l(data, l); + X(12) = l; + BODY_00_15(11, B, C, D, E, T, A, X(11)); + (void)HOST_c2l(data, l); + X(13) = l; + BODY_00_15(12, A, B, C, D, E, T, X(12)); + (void)HOST_c2l(data, l); + X(14) = l; + BODY_00_15(13, T, A, B, C, D, E, X(13)); + (void)HOST_c2l(data, l); + X(15) = l; + BODY_00_15(14, E, T, A, B, C, D, X(14)); + BODY_00_15(15, D, E, T, A, B, C, X(15)); + } + + BODY_16_19(16, C, D, E, T, A, B, X(0), X(0), X(2), X(8), X(13)); + BODY_16_19(17, B, C, D, E, T, A, X(1), X(1), X(3), X(9), X(14)); + BODY_16_19(18, A, B, C, D, E, T, X(2), X(2), X(4), X(10), X(15)); + BODY_16_19(19, T, A, B, C, D, E, X(3), X(3), X(5), X(11), X(0)); + + BODY_20_31(20, E, T, A, B, C, D, X(4), X(4), X(6), X(12), X(1)); + BODY_20_31(21, D, E, T, A, B, C, X(5), X(5), X(7), X(13), X(2)); + BODY_20_31(22, C, D, E, T, A, B, X(6), X(6), X(8), X(14), X(3)); + BODY_20_31(23, B, C, D, E, T, A, X(7), X(7), X(9), X(15), X(4)); + BODY_20_31(24, A, B, C, D, E, T, X(8), X(8), X(10), X(0), X(5)); + BODY_20_31(25, T, A, B, C, D, E, X(9), X(9), X(11), X(1), X(6)); + BODY_20_31(26, E, T, A, B, C, D, X(10), X(10), X(12), X(2), X(7)); + BODY_20_31(27, D, E, T, A, B, C, X(11), X(11), X(13), X(3), X(8)); + BODY_20_31(28, C, D, E, T, A, B, X(12), X(12), X(14), X(4), X(9)); + BODY_20_31(29, B, C, D, E, T, A, X(13), X(13), X(15), X(5), X(10)); + BODY_20_31(30, A, B, C, D, E, T, X(14), X(14), X(0), X(6), X(11)); + BODY_20_31(31, T, A, B, C, D, E, X(15), X(15), X(1), X(7), X(12)); + + BODY_32_39(32, E, T, A, B, C, D, X(0), X(2), X(8), X(13)); + BODY_32_39(33, D, E, T, A, B, C, X(1), X(3), X(9), X(14)); + BODY_32_39(34, C, D, E, T, A, B, X(2), X(4), X(10), X(15)); + BODY_32_39(35, B, C, D, E, T, A, X(3), X(5), X(11), X(0)); + BODY_32_39(36, A, B, C, D, E, T, X(4), X(6), X(12), X(1)); + BODY_32_39(37, T, A, B, C, D, E, X(5), X(7), X(13), X(2)); + BODY_32_39(38, E, T, A, B, C, D, X(6), X(8), X(14), X(3)); + BODY_32_39(39, D, E, T, A, B, C, X(7), X(9), X(15), X(4)); + + BODY_40_59(40, C, D, E, T, A, B, X(8), X(10), X(0), X(5)); + BODY_40_59(41, B, C, D, E, T, A, X(9), X(11), X(1), X(6)); + BODY_40_59(42, A, B, C, D, E, T, X(10), X(12), X(2), X(7)); + BODY_40_59(43, T, A, B, C, D, E, X(11), X(13), X(3), X(8)); + BODY_40_59(44, E, T, A, B, C, D, X(12), X(14), X(4), X(9)); + BODY_40_59(45, D, E, T, A, B, C, X(13), X(15), X(5), X(10)); + BODY_40_59(46, C, D, E, T, A, B, X(14), X(0), X(6), X(11)); + BODY_40_59(47, B, C, D, E, T, A, X(15), X(1), X(7), X(12)); + BODY_40_59(48, A, B, C, D, E, T, X(0), X(2), X(8), X(13)); + BODY_40_59(49, T, A, B, C, D, E, X(1), X(3), X(9), X(14)); + BODY_40_59(50, E, T, A, B, C, D, X(2), X(4), X(10), X(15)); + BODY_40_59(51, D, E, T, A, B, C, X(3), X(5), X(11), X(0)); + BODY_40_59(52, C, D, E, T, A, B, X(4), X(6), X(12), X(1)); + BODY_40_59(53, B, C, D, E, T, A, X(5), X(7), X(13), X(2)); + BODY_40_59(54, A, B, C, D, E, T, X(6), X(8), X(14), X(3)); + BODY_40_59(55, T, A, B, C, D, E, X(7), X(9), X(15), X(4)); + BODY_40_59(56, E, T, A, B, C, D, X(8), X(10), X(0), X(5)); + BODY_40_59(57, D, E, T, A, B, C, X(9), X(11), X(1), X(6)); + BODY_40_59(58, C, D, E, T, A, B, X(10), X(12), X(2), X(7)); + BODY_40_59(59, B, C, D, E, T, A, X(11), X(13), X(3), X(8)); + + BODY_60_79(60, A, B, C, D, E, T, X(12), X(14), X(4), X(9)); + BODY_60_79(61, T, A, B, C, D, E, X(13), X(15), X(5), X(10)); + BODY_60_79(62, E, T, A, B, C, D, X(14), X(0), X(6), X(11)); + BODY_60_79(63, D, E, T, A, B, C, X(15), X(1), X(7), X(12)); + BODY_60_79(64, C, D, E, T, A, B, X(0), X(2), X(8), X(13)); + BODY_60_79(65, B, C, D, E, T, A, X(1), X(3), X(9), X(14)); + BODY_60_79(66, A, B, C, D, E, T, X(2), X(4), X(10), X(15)); + BODY_60_79(67, T, A, B, C, D, E, X(3), X(5), X(11), X(0)); + BODY_60_79(68, E, T, A, B, C, D, X(4), X(6), X(12), X(1)); + BODY_60_79(69, D, E, T, A, B, C, X(5), X(7), X(13), X(2)); + BODY_60_79(70, C, D, E, T, A, B, X(6), X(8), X(14), X(3)); + BODY_60_79(71, B, C, D, E, T, A, X(7), X(9), X(15), X(4)); + BODY_60_79(72, A, B, C, D, E, T, X(8), X(10), X(0), X(5)); + BODY_60_79(73, T, A, B, C, D, E, X(9), X(11), X(1), X(6)); + BODY_60_79(74, E, T, A, B, C, D, X(10), X(12), X(2), X(7)); + BODY_60_79(75, D, E, T, A, B, C, X(11), X(13), X(3), X(8)); + BODY_60_79(76, C, D, E, T, A, B, X(12), X(14), X(4), X(9)); + BODY_60_79(77, B, C, D, E, T, A, X(13), X(15), X(5), X(10)); + BODY_60_79(78, A, B, C, D, E, T, X(14), X(0), X(6), X(11)); + BODY_60_79(79, T, A, B, C, D, E, X(15), X(1), X(7), X(12)); + + c->h0 = (c->h0 + E) & 0xffffffffL; + c->h1 = (c->h1 + T) & 0xffffffffL; + c->h2 = (c->h2 + A) & 0xffffffffL; + c->h3 = (c->h3 + B) & 0xffffffffL; + c->h4 = (c->h4 + C) & 0xffffffffL; + + if (--num == 0) + break; + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + } +} +# endif + +#else /* OPENSSL_SMALL_FOOTPRINT */ + +# define BODY_00_15(xi) do { \ + T=E+K_00_19+F_00_19(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T+xi; } while(0) + +# define BODY_16_19(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T+=E+K_00_19+F_00_19(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T; } while(0) + +# define BODY_20_39(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T+=E+K_20_39+F_20_39(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T; } while(0) + +# define BODY_40_59(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T+=E+K_40_59+F_40_59(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T; } while(0) + +# define BODY_60_79(xa,xb,xc,xd) do { \ + Xupdate(T,xa,xa,xb,xc,xd); \ + T=E+K_60_79+F_60_79(B,C,D); \ + E=D, D=C, C=ROTATE(B,30), B=A; \ + A=ROTATE(A,5)+T+xa; } while(0) + +# if !defined(SHA_1) || !defined(SHA1_ASM) +static void HASH_BLOCK_DATA_ORDER(SHA_CTX *c, const void *p, size_t num) +{ + const unsigned char *data = p; + register unsigned MD32_REG_T A, B, C, D, E, T, l; + int i; + SHA_LONG X[16]; + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + for (;;) { + for (i = 0; i < 16; i++) { + HOST_c2l(data, l); + X[i] = l; + BODY_00_15(X[i]); + } + for (i = 0; i < 4; i++) { + BODY_16_19(X[i], X[i + 2], X[i + 8], X[(i + 13) & 15]); + } + for (; i < 24; i++) { + BODY_20_39(X[i & 15], X[(i + 2) & 15], X[(i + 8) & 15], + X[(i + 13) & 15]); + } + for (i = 0; i < 20; i++) { + BODY_40_59(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15], + X[(i + 5) & 15]); + } + for (i = 4; i < 24; i++) { + BODY_60_79(X[(i + 8) & 15], X[(i + 10) & 15], X[i & 15], + X[(i + 5) & 15]); + } + + c->h0 = (c->h0 + A) & 0xffffffffL; + c->h1 = (c->h1 + B) & 0xffffffffL; + c->h2 = (c->h2 + C) & 0xffffffffL; + c->h3 = (c->h3 + D) & 0xffffffffL; + c->h4 = (c->h4 + E) & 0xffffffffL; + + if (--num == 0) + break; + + A = c->h0; + B = c->h1; + C = c->h2; + D = c->h3; + E = c->h4; + + } +} +# endif + +#endif diff --git a/libs/openssl/crypto/sha/sha_one.c b/libs/openssl/crypto/sha/sha_one.c new file mode 100644 index 00000000..0930b98a --- /dev/null +++ b/libs/openssl/crypto/sha/sha_one.c @@ -0,0 +1,79 @@ +/* crypto/sha/sha_one.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include + +#ifndef OPENSSL_NO_SHA0 +unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md) +{ + SHA_CTX c; + static unsigned char m[SHA_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + if (!SHA_Init(&c)) + return NULL; + SHA_Update(&c, d, n); + SHA_Final(md, &c); + OPENSSL_cleanse(&c, sizeof(c)); + return (md); +} +#endif diff --git a/libs/openssl/crypto/sha/shatest.c b/libs/openssl/crypto/sha/shatest.c new file mode 100644 index 00000000..105060a7 --- /dev/null +++ b/libs/openssl/crypto/sha/shatest.c @@ -0,0 +1,174 @@ +/* crypto/sha/shatest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "../e_os.h" + +#if defined(OPENSSL_NO_SHA) || defined(OPENSSL_NO_SHA0) +int main(int argc, char *argv[]) +{ + printf("No SHA0 support\n"); + return (0); +} +#else +# include +# include + +# ifdef CHARSET_EBCDIC +# include +# endif + +# define SHA_0 /* FIPS 180 */ +# undef SHA_1 /* FIPS 180-1 */ + +static char *test[] = { + "abc", + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + NULL, +}; + +# ifdef SHA_0 +static char *ret[] = { + "0164b8a914cd2a5e74c4f7ff082c4d97f1edf880", + "d2516ee1acfa5baf33dfc1c471e438449ef134c8", +}; + +static char *bigret = "3232affa48628a26653b5aaa44541fd90d690603"; +# endif +# ifdef SHA_1 +static char *ret[] = { + "a9993e364706816aba3e25717850c26c9cd0d89d", + "84983e441c3bd26ebaae4aa1f95129e5e54670f1", +}; + +static char *bigret = "34aa973cd4c4daa4f61eeb2bdbad27316534016f"; +# endif + +static char *pt(unsigned char *md); +int main(int argc, char *argv[]) +{ + int i, err = 0; + char **P, **R; + static unsigned char buf[1000]; + char *p, *r; + EVP_MD_CTX c; + unsigned char md[SHA_DIGEST_LENGTH]; + +# ifdef CHARSET_EBCDIC + ebcdic2ascii(test[0], test[0], strlen(test[0])); + ebcdic2ascii(test[1], test[1], strlen(test[1])); +# endif + + EVP_MD_CTX_init(&c); + P = test; + R = ret; + i = 1; + while (*P != NULL) { + EVP_Digest(*P, strlen(*P), md, NULL, EVP_sha(), NULL); + p = pt(md); + if (strcmp(p, *R) != 0) { + printf("error calculating SHA on '%s'\n", *P); + printf("got %s instead of %s\n", p, *R); + err++; + } else + printf("test %d ok\n", i); + i++; + R++; + P++; + } + + memset(buf, 'a', 1000); +# ifdef CHARSET_EBCDIC + ebcdic2ascii(buf, buf, 1000); +# endif /* CHARSET_EBCDIC */ + EVP_DigestInit_ex(&c, EVP_sha(), NULL); + for (i = 0; i < 1000; i++) + EVP_DigestUpdate(&c, buf, 1000); + EVP_DigestFinal_ex(&c, md, NULL); + p = pt(md); + + r = bigret; + if (strcmp(p, r) != 0) { + printf("error calculating SHA on '%s'\n", p); + printf("got %s instead of %s\n", p, r); + err++; + } else + printf("test 3 ok\n"); + +# ifdef OPENSSL_SYS_NETWARE + if (err) + printf("ERROR: %d\n", err); +# endif + EVP_MD_CTX_cleanup(&c); + EXIT(err); + return (0); +} + +static char *pt(unsigned char *md) +{ + int i; + static char buf[80]; + + for (i = 0; i < SHA_DIGEST_LENGTH; i++) + sprintf(&(buf[i * 2]), "%02x", md[i]); + return (buf); +} +#endif diff --git a/libs/openssl/crypto/sparccpuid.S b/libs/openssl/crypto/sparccpuid.S new file mode 100644 index 00000000..c63d5da4 --- /dev/null +++ b/libs/openssl/crypto/sparccpuid.S @@ -0,0 +1,402 @@ +#if defined(__SUNPRO_C) && defined(__sparcv9) +# define ABI64 /* They've said -xarch=v9 at command line */ +#elif defined(__GNUC__) && defined(__arch64__) +# define ABI64 /* They've said -m64 at command line */ +#endif + +#ifdef ABI64 + .register %g2,#scratch + .register %g3,#scratch +# define FRAME -192 +# define BIAS 2047 +#else +# define FRAME -96 +# define BIAS 0 +#endif + +.text +.align 32 +.global OPENSSL_wipe_cpu +.type OPENSSL_wipe_cpu,#function +! Keep in mind that this does not excuse us from wiping the stack! +! This routine wipes registers, but not the backing store [which +! resides on the stack, toward lower addresses]. To facilitate for +! stack wiping I return pointer to the top of stack of the *caller*. +OPENSSL_wipe_cpu: + save %sp,FRAME,%sp + nop +#ifdef __sun +#include + ta ST_CLEAN_WINDOWS +#else + call .walk.reg.wins +#endif + nop + call .PIC.zero.up + mov .zero-(.-4),%o0 + ld [%o0],%f0 + ld [%o0],%f1 + + subcc %g0,1,%o0 + ! Following is V9 "rd %ccr,%o0" instruction. However! V8 + ! specification says that it ("rd %asr2,%o0" in V8 terms) does + ! not cause illegal_instruction trap. It therefore can be used + ! to determine if the CPU the code is executing on is V8- or + ! V9-compliant, as V9 returns a distinct value of 0x99, + ! "negative" and "borrow" bits set in both %icc and %xcc. + .word 0x91408000 !rd %ccr,%o0 + cmp %o0,0x99 + bne .v8 + nop + ! Even though we do not use %fp register bank, + ! we wipe it as memcpy might have used it... + .word 0xbfa00040 !fmovd %f0,%f62 + .word 0xbba00040 !... + .word 0xb7a00040 + .word 0xb3a00040 + .word 0xafa00040 + .word 0xaba00040 + .word 0xa7a00040 + .word 0xa3a00040 + .word 0x9fa00040 + .word 0x9ba00040 + .word 0x97a00040 + .word 0x93a00040 + .word 0x8fa00040 + .word 0x8ba00040 + .word 0x87a00040 + .word 0x83a00040 !fmovd %f0,%f32 +.v8: fmovs %f1,%f31 + clr %o0 + fmovs %f0,%f30 + clr %o1 + fmovs %f1,%f29 + clr %o2 + fmovs %f0,%f28 + clr %o3 + fmovs %f1,%f27 + clr %o4 + fmovs %f0,%f26 + clr %o5 + fmovs %f1,%f25 + clr %o7 + fmovs %f0,%f24 + clr %l0 + fmovs %f1,%f23 + clr %l1 + fmovs %f0,%f22 + clr %l2 + fmovs %f1,%f21 + clr %l3 + fmovs %f0,%f20 + clr %l4 + fmovs %f1,%f19 + clr %l5 + fmovs %f0,%f18 + clr %l6 + fmovs %f1,%f17 + clr %l7 + fmovs %f0,%f16 + clr %i0 + fmovs %f1,%f15 + clr %i1 + fmovs %f0,%f14 + clr %i2 + fmovs %f1,%f13 + clr %i3 + fmovs %f0,%f12 + clr %i4 + fmovs %f1,%f11 + clr %i5 + fmovs %f0,%f10 + clr %g1 + fmovs %f1,%f9 + clr %g2 + fmovs %f0,%f8 + clr %g3 + fmovs %f1,%f7 + clr %g4 + fmovs %f0,%f6 + clr %g5 + fmovs %f1,%f5 + fmovs %f0,%f4 + fmovs %f1,%f3 + fmovs %f0,%f2 + + add %fp,BIAS,%i0 ! return pointer to caller´s top of stack + + ret + restore + +.zero: .long 0x0,0x0 +.PIC.zero.up: + retl + add %o0,%o7,%o0 +#ifdef DEBUG +.global walk_reg_wins +.type walk_reg_wins,#function +walk_reg_wins: +#endif +.walk.reg.wins: + save %sp,FRAME,%sp + cmp %i7,%o7 + be 2f + clr %o0 + cmp %o7,0 ! compiler never cleans %o7... + be 1f ! could have been a leaf function... + clr %o1 + call .walk.reg.wins + nop +1: clr %o2 + clr %o3 + clr %o4 + clr %o5 + clr %o7 + clr %l0 + clr %l1 + clr %l2 + clr %l3 + clr %l4 + clr %l5 + clr %l6 + clr %l7 + add %o0,1,%i0 ! used for debugging +2: ret + restore +.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu + +.global OPENSSL_atomic_add +.type OPENSSL_atomic_add,#function +.align 32 +OPENSSL_atomic_add: +#ifndef ABI64 + subcc %g0,1,%o2 + .word 0x95408000 !rd %ccr,%o2, see comment above + cmp %o2,0x99 + be .v9 + nop + save %sp,FRAME,%sp + ba .enter + nop +#ifdef __sun +! Note that you do not have to link with libthread to call thr_yield, +! as libc provides a stub, which is overloaded the moment you link +! with *either* libpthread or libthread... +#define YIELD_CPU thr_yield +#else +! applies at least to Linux and FreeBSD... Feedback expected... +#define YIELD_CPU sched_yield +#endif +.spin: call YIELD_CPU + nop +.enter: ld [%i0],%i2 + cmp %i2,-4096 + be .spin + mov -1,%i2 + swap [%i0],%i2 + cmp %i2,-1 + be .spin + add %i2,%i1,%i2 + stbar + st %i2,[%i0] + sra %i2,%g0,%i0 + ret + restore +.v9: +#endif + ld [%o0],%o2 +1: add %o1,%o2,%o3 + .word 0xd7e2100a !cas [%o0],%o2,%o3, compare [%o0] with %o2 and swap %o3 + cmp %o2,%o3 + bne 1b + mov %o3,%o2 ! cas is always fetching to dest. register + add %o1,%o2,%o0 ! OpenSSL expects the new value + retl + sra %o0,%g0,%o0 ! we return signed int, remember? +.size OPENSSL_atomic_add,.-OPENSSL_atomic_add + +.global _sparcv9_rdtick +.align 32 +_sparcv9_rdtick: + subcc %g0,1,%o0 + .word 0x91408000 !rd %ccr,%o0 + cmp %o0,0x99 + bne .notick + xor %o0,%o0,%o0 + .word 0x91410000 !rd %tick,%o0 + retl + .word 0x93323020 !srlx %o0,32,%o1 +.notick: + retl + xor %o1,%o1,%o1 +.type _sparcv9_rdtick,#function +.size _sparcv9_rdtick,.-_sparcv9_rdtick + +.global _sparcv9_vis1_probe +.align 8 +_sparcv9_vis1_probe: + add %sp,BIAS+2,%o1 + .word 0xc19a5a40 !ldda [%o1]ASI_FP16_P,%f0 + retl + .word 0x81b00d80 !fxor %f0,%f0,%f0 +.type _sparcv9_vis1_probe,#function +.size _sparcv9_vis1_probe,.-_sparcv9_vis1_probe + +! Probe and instrument VIS1 instruction. Output is number of cycles it +! takes to execute rdtick and pair of VIS1 instructions. US-Tx VIS unit +! is slow (documented to be 6 cycles on T2) and the core is in-order +! single-issue, it should be possible to distinguish Tx reliably... +! Observed return values are: +! +! UltraSPARC IIe 7 +! UltraSPARC III 7 +! UltraSPARC T1 24 +! +! Numbers for T2 and SPARC64 V-VII are more than welcomed. +! +! It would be possible to detect specifically US-T1 by instrumenting +! fmul8ulx16, which is emulated on T1 and as such accounts for quite +! a lot of %tick-s, couple of thousand on Linux... +.global _sparcv9_vis1_instrument +.align 8 +_sparcv9_vis1_instrument: + .word 0x91410000 !rd %tick,%o0 + .word 0x81b00d80 !fxor %f0,%f0,%f0 + .word 0x85b08d82 !fxor %f2,%f2,%f2 + .word 0x93410000 !rd %tick,%o1 + .word 0x81b00d80 !fxor %f0,%f0,%f0 + .word 0x85b08d82 !fxor %f2,%f2,%f2 + .word 0x95410000 !rd %tick,%o2 + .word 0x81b00d80 !fxor %f0,%f0,%f0 + .word 0x85b08d82 !fxor %f2,%f2,%f2 + .word 0x97410000 !rd %tick,%o3 + .word 0x81b00d80 !fxor %f0,%f0,%f0 + .word 0x85b08d82 !fxor %f2,%f2,%f2 + .word 0x99410000 !rd %tick,%o4 + + ! calculate intervals + sub %o1,%o0,%o0 + sub %o2,%o1,%o1 + sub %o3,%o2,%o2 + sub %o4,%o3,%o3 + + ! find minumum value + cmp %o0,%o1 + .word 0x38680002 !bgu,a %xcc,.+8 + mov %o1,%o0 + cmp %o0,%o2 + .word 0x38680002 !bgu,a %xcc,.+8 + mov %o2,%o0 + cmp %o0,%o3 + .word 0x38680002 !bgu,a %xcc,.+8 + mov %o3,%o0 + + retl + nop +.type _sparcv9_vis1_instrument,#function +.size _sparcv9_vis1_instrument,.-_sparcv9_vis1_instrument + +.global _sparcv9_vis2_probe +.align 8 +_sparcv9_vis2_probe: + retl + .word 0x81b00980 !bshuffle %f0,%f0,%f0 +.type _sparcv9_vis2_probe,#function +.size _sparcv9_vis2_probe,.-_sparcv9_vis2_probe + +.global _sparcv9_fmadd_probe +.align 8 +_sparcv9_fmadd_probe: + .word 0x81b00d80 !fxor %f0,%f0,%f0 + .word 0x85b08d82 !fxor %f2,%f2,%f2 + retl + .word 0x81b80440 !fmaddd %f0,%f0,%f2,%f0 +.type _sparcv9_fmadd_probe,#function +.size _sparcv9_fmadd_probe,.-_sparcv9_fmadd_probe + +.global OPENSSL_cleanse +.align 32 +OPENSSL_cleanse: + cmp %o1,14 + nop +#ifdef ABI64 + bgu %xcc,.Lot +#else + bgu .Lot +#endif + cmp %o1,0 + bne .Little + nop + retl + nop + +.Little: + stb %g0,[%o0] + subcc %o1,1,%o1 + bnz .Little + add %o0,1,%o0 + retl + nop +.align 32 +.Lot: +#ifndef ABI64 + subcc %g0,1,%g1 + ! see above for explanation + .word 0x83408000 !rd %ccr,%g1 + cmp %g1,0x99 + bne .v8lot + nop +#endif + +.v9lot: andcc %o0,7,%g0 + bz .v9aligned + nop + stb %g0,[%o0] + sub %o1,1,%o1 + ba .v9lot + add %o0,1,%o0 +.align 16,0x01000000 +.v9aligned: + .word 0xc0720000 !stx %g0,[%o0] + sub %o1,8,%o1 + andcc %o1,-8,%g0 +#ifdef ABI64 + .word 0x126ffffd !bnz %xcc,.v9aligned +#else + .word 0x124ffffd !bnz %icc,.v9aligned +#endif + add %o0,8,%o0 + + cmp %o1,0 + bne .Little + nop + retl + nop +#ifndef ABI64 +.v8lot: andcc %o0,3,%g0 + bz .v8aligned + nop + stb %g0,[%o0] + sub %o1,1,%o1 + ba .v8lot + add %o0,1,%o0 + nop +.v8aligned: + st %g0,[%o0] + sub %o1,4,%o1 + andcc %o1,-4,%g0 + bnz .v8aligned + add %o0,4,%o0 + + cmp %o1,0 + bne .Little + nop + retl + nop +#endif +.type OPENSSL_cleanse,#function +.size OPENSSL_cleanse,.-OPENSSL_cleanse + +.section ".init",#alloc,#execinstr + call OPENSSL_cpuid_setup + nop diff --git a/libs/openssl/crypto/sparcv9cap.c b/libs/openssl/crypto/sparcv9cap.c new file mode 100644 index 00000000..d9f986f6 --- /dev/null +++ b/libs/openssl/crypto/sparcv9cap.c @@ -0,0 +1,245 @@ +#include +#include +#include +#include +#include +#include +#include + +#define SPARCV9_TICK_PRIVILEGED (1<<0) +#define SPARCV9_PREFER_FPU (1<<1) +#define SPARCV9_VIS1 (1<<2) +#define SPARCV9_VIS2 (1<<3) /* reserved */ +#define SPARCV9_FMADD (1<<4) /* reserved for SPARC64 V */ + +static int OPENSSL_sparcv9cap_P = SPARCV9_TICK_PRIVILEGED; + +int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num) +{ + int bn_mul_mont_fpu(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num); + int bn_mul_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + const BN_ULONG *np, const BN_ULONG *n0, int num); + + if (num >= 8 && !(num & 1) && + (OPENSSL_sparcv9cap_P & (SPARCV9_PREFER_FPU | SPARCV9_VIS1)) == + (SPARCV9_PREFER_FPU | SPARCV9_VIS1)) + return bn_mul_mont_fpu(rp, ap, bp, np, n0, num); + else + return bn_mul_mont_int(rp, ap, bp, np, n0, num); +} + +unsigned long _sparcv9_rdtick(void); +void _sparcv9_vis1_probe(void); +unsigned long _sparcv9_vis1_instrument(void); +void _sparcv9_vis2_probe(void); +void _sparcv9_fmadd_probe(void); + +unsigned long OPENSSL_rdtsc(void) +{ + if (OPENSSL_sparcv9cap_P & SPARCV9_TICK_PRIVILEGED) +#if defined(__sun) && defined(__SVR4) + return gethrtime(); +#else + return 0; +#endif + else + return _sparcv9_rdtick(); +} + +#if 0 && defined(__sun) && defined(__SVR4) +/* + * This code path is disabled, because of incompatibility of libdevinfo.so.1 + * and libmalloc.so.1 (see below for details) + */ +# include +# include +# include +# include + +typedef di_node_t(*di_init_t) (const char *, uint_t); +typedef void (*di_fini_t) (di_node_t); +typedef char *(*di_node_name_t) (di_node_t); +typedef int (*di_walk_node_t) (di_node_t, uint_t, di_node_name_t, + int (*)(di_node_t, di_node_name_t)); + +# define DLLINK(h,name) (name=(name##_t)dlsym((h),#name)) + +static int walk_nodename(di_node_t node, di_node_name_t di_node_name) +{ + char *name = (*di_node_name) (node); + + /* This is expected to catch all UltraSPARC flavors prior T1 */ + if (!strcmp(name, "SUNW,UltraSPARC") || + /* covers II,III,IV */ + !strncmp(name, "SUNW,UltraSPARC-I", 17)) { + OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU | SPARCV9_VIS1; + + /* %tick is privileged only on UltraSPARC-I/II, but not IIe */ + if (name[14] != '\0' && name[17] != '\0' && name[18] != '\0') + OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED; + + return DI_WALK_TERMINATE; + } + /* This is expected to catch remaining UltraSPARCs, such as T1 */ + else if (!strncmp(name, "SUNW,UltraSPARC", 15)) { + OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED; + + return DI_WALK_TERMINATE; + } + + return DI_WALK_CONTINUE; +} + +void OPENSSL_cpuid_setup(void) +{ + void *h; + char *e, si[256]; + static int trigger = 0; + + if (trigger) + return; + trigger = 1; + + if ((e = getenv("OPENSSL_sparcv9cap"))) { + OPENSSL_sparcv9cap_P = strtoul(e, NULL, 0); + return; + } + + if (sysinfo(SI_MACHINE, si, sizeof(si)) > 0) { + if (strcmp(si, "sun4v")) + /* FPU is preferred for all CPUs, but US-T1/2 */ + OPENSSL_sparcv9cap_P |= SPARCV9_PREFER_FPU; + } + + if (sysinfo(SI_ISALIST, si, sizeof(si)) > 0) { + if (strstr(si, "+vis")) + OPENSSL_sparcv9cap_P |= SPARCV9_VIS1; + if (strstr(si, "+vis2")) { + OPENSSL_sparcv9cap_P |= SPARCV9_VIS2; + OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED; + return; + } + } +# ifdef M_KEEP + /* + * Solaris libdevinfo.so.1 is effectively incomatible with + * libmalloc.so.1. Specifically, if application is linked with + * -lmalloc, it crashes upon startup with SIGSEGV in + * free(3LIBMALLOC) called by di_fini. Prior call to + * mallopt(M_KEEP,0) somehow helps... But not always... + */ + if ((h = dlopen(NULL, RTLD_LAZY))) { + union { + void *p; + int (*f) (int, int); + } sym; + if ((sym.p = dlsym(h, "mallopt"))) + (*sym.f) (M_KEEP, 0); + dlclose(h); + } +# endif + if ((h = dlopen("libdevinfo.so.1", RTLD_LAZY))) + do { + di_init_t di_init; + di_fini_t di_fini; + di_walk_node_t di_walk_node; + di_node_name_t di_node_name; + di_node_t root_node; + + if (!DLLINK(h, di_init)) + break; + if (!DLLINK(h, di_fini)) + break; + if (!DLLINK(h, di_walk_node)) + break; + if (!DLLINK(h, di_node_name)) + break; + + if ((root_node = (*di_init) ("/", DINFOSUBTREE)) != DI_NODE_NIL) { + (*di_walk_node) (root_node, DI_WALK_SIBFIRST, + di_node_name, walk_nodename); + (*di_fini) (root_node); + } + } while (0); + + if (h) + dlclose(h); +} + +#else + +static sigjmp_buf common_jmp; +static void common_handler(int sig) +{ + siglongjmp(common_jmp, sig); +} + +void OPENSSL_cpuid_setup(void) +{ + char *e; + struct sigaction common_act, ill_oact, bus_oact; + sigset_t all_masked, oset; + static int trigger = 0; + + if (trigger) + return; + trigger = 1; + + if ((e = getenv("OPENSSL_sparcv9cap"))) { + OPENSSL_sparcv9cap_P = strtoul(e, NULL, 0); + return; + } + + /* Initial value, fits UltraSPARC-I&II... */ + OPENSSL_sparcv9cap_P = SPARCV9_PREFER_FPU | SPARCV9_TICK_PRIVILEGED; + + sigfillset(&all_masked); + sigdelset(&all_masked, SIGILL); + sigdelset(&all_masked, SIGTRAP); +# ifdef SIGEMT + sigdelset(&all_masked, SIGEMT); +# endif + sigdelset(&all_masked, SIGFPE); + sigdelset(&all_masked, SIGBUS); + sigdelset(&all_masked, SIGSEGV); + sigprocmask(SIG_SETMASK, &all_masked, &oset); + + memset(&common_act, 0, sizeof(common_act)); + common_act.sa_handler = common_handler; + common_act.sa_mask = all_masked; + + sigaction(SIGILL, &common_act, &ill_oact); + sigaction(SIGBUS, &common_act, &bus_oact); /* T1 fails 16-bit ldda [on + * Linux] */ + + if (sigsetjmp(common_jmp, 1) == 0) { + _sparcv9_rdtick(); + OPENSSL_sparcv9cap_P &= ~SPARCV9_TICK_PRIVILEGED; + } + + if (sigsetjmp(common_jmp, 1) == 0) { + _sparcv9_vis1_probe(); + OPENSSL_sparcv9cap_P |= SPARCV9_VIS1; + /* detect UltraSPARC-Tx, see sparccpud.S for details... */ + if (_sparcv9_vis1_instrument() >= 12) + OPENSSL_sparcv9cap_P &= ~(SPARCV9_VIS1 | SPARCV9_PREFER_FPU); + else { + _sparcv9_vis2_probe(); + OPENSSL_sparcv9cap_P |= SPARCV9_VIS2; + } + } + + if (sigsetjmp(common_jmp, 1) == 0) { + _sparcv9_fmadd_probe(); + OPENSSL_sparcv9cap_P |= SPARCV9_FMADD; + } + + sigaction(SIGBUS, &bus_oact, NULL); + sigaction(SIGILL, &ill_oact, NULL); + + sigprocmask(SIG_SETMASK, &oset, NULL); +} + +#endif diff --git a/libs/openssl/crypto/srp/srp.h b/libs/openssl/crypto/srp/srp.h new file mode 100644 index 00000000..028892a1 --- /dev/null +++ b/libs/openssl/crypto/srp/srp.h @@ -0,0 +1,179 @@ +/* crypto/srp/srp.h */ +/* + * Written by Christophe Renou (christophe.renou@edelweb.fr) with the + * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the + * EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef __SRP_H__ +# define __SRP_H__ + +# ifndef OPENSSL_NO_SRP + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# include +# include +# include + +typedef struct SRP_gN_cache_st { + char *b64_bn; + BIGNUM *bn; +} SRP_gN_cache; + + +DECLARE_STACK_OF(SRP_gN_cache) + +typedef struct SRP_user_pwd_st { + /* Owned by us. */ + char *id; + BIGNUM *s; + BIGNUM *v; + /* Not owned by us. */ + const BIGNUM *g; + const BIGNUM *N; + /* Owned by us. */ + char *info; +} SRP_user_pwd; + +DECLARE_STACK_OF(SRP_user_pwd) + +void SRP_user_pwd_free(SRP_user_pwd *user_pwd); + +typedef struct SRP_VBASE_st { + STACK_OF(SRP_user_pwd) *users_pwd; + STACK_OF(SRP_gN_cache) *gN_cache; +/* to simulate a user */ + char *seed_key; + BIGNUM *default_g; + BIGNUM *default_N; +} SRP_VBASE; + +/* + * Structure interne pour retenir les couples N et g + */ +typedef struct SRP_gN_st { + char *id; + BIGNUM *g; + BIGNUM *N; +} SRP_gN; + +DECLARE_STACK_OF(SRP_gN) + +SRP_VBASE *SRP_VBASE_new(char *seed_key); +int SRP_VBASE_free(SRP_VBASE *vb); +int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file); + +/* This method ignores the configured seed and fails for an unknown user. */ +SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username); +/* NOTE: unlike in SRP_VBASE_get_by_user, caller owns the returned pointer.*/ +SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username); + +char *SRP_create_verifier(const char *user, const char *pass, char **salt, + char **verifier, const char *N, const char *g); +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, + BIGNUM **verifier, BIGNUM *N, BIGNUM *g); + +# define SRP_NO_ERROR 0 +# define SRP_ERR_VBASE_INCOMPLETE_FILE 1 +# define SRP_ERR_VBASE_BN_LIB 2 +# define SRP_ERR_OPEN_FILE 3 +# define SRP_ERR_MEMORY 4 + +# define DB_srptype 0 +# define DB_srpverifier 1 +# define DB_srpsalt 2 +# define DB_srpid 3 +# define DB_srpgN 4 +# define DB_srpinfo 5 +# undef DB_NUMBER +# define DB_NUMBER 6 + +# define DB_SRP_INDEX 'I' +# define DB_SRP_VALID 'V' +# define DB_SRP_REVOKED 'R' +# define DB_SRP_MODIF 'v' + +/* see srp.c */ +char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N); +SRP_gN *SRP_get_default_gN(const char *id); + +/* server side .... */ +BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, + BIGNUM *N); +BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v); +int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N); +BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N); + +/* client side .... */ +BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass); +BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g); +BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, + BIGNUM *a, BIGNUM *u); +int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N); + +# define SRP_MINIMAL_N 1024 + +#ifdef __cplusplus +} +#endif + +# endif +#endif diff --git a/libs/openssl/crypto/srp/srp_grps.h b/libs/openssl/crypto/srp/srp_grps.h new file mode 100644 index 00000000..31312de1 --- /dev/null +++ b/libs/openssl/crypto/srp/srp_grps.h @@ -0,0 +1,528 @@ +/* start of generated data */ + +static BN_ULONG bn_group_1024_value[] = { + bn_pack4(0x9FC6, 0x1D2F, 0xC0EB, 0x06E3), + bn_pack4(0xFD51, 0x38FE, 0x8376, 0x435B), + bn_pack4(0x2FD4, 0xCBF4, 0x976E, 0xAA9A), + bn_pack4(0x68ED, 0xBC3C, 0x0572, 0x6CC0), + bn_pack4(0xC529, 0xF566, 0x660E, 0x57EC), + bn_pack4(0x8255, 0x9B29, 0x7BCF, 0x1885), + bn_pack4(0xCE8E, 0xF4AD, 0x69B1, 0x5D49), + bn_pack4(0x5DC7, 0xD7B4, 0x6154, 0xD6B6), + bn_pack4(0x8E49, 0x5C1D, 0x6089, 0xDAD1), + bn_pack4(0xE0D5, 0xD8E2, 0x50B9, 0x8BE4), + bn_pack4(0x383B, 0x4813, 0xD692, 0xC6E0), + bn_pack4(0xD674, 0xDF74, 0x96EA, 0x81D3), + bn_pack4(0x9EA2, 0x314C, 0x9C25, 0x6576), + bn_pack4(0x6072, 0x6187, 0x75FF, 0x3C0B), + bn_pack4(0x9C33, 0xF80A, 0xFA8F, 0xC5E8), + bn_pack4(0xEEAF, 0x0AB9, 0xADB3, 0x8DD6) +}; + +static BIGNUM bn_group_1024 = { + bn_group_1024_value, + (sizeof bn_group_1024_value) / sizeof(BN_ULONG), + (sizeof bn_group_1024_value) / sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_1536_value[] = { + bn_pack4(0xCF76, 0xE3FE, 0xD135, 0xF9BB), + bn_pack4(0x1518, 0x0F93, 0x499A, 0x234D), + bn_pack4(0x8CE7, 0xA28C, 0x2442, 0xC6F3), + bn_pack4(0x5A02, 0x1FFF, 0x5E91, 0x479E), + bn_pack4(0x7F8A, 0x2FE9, 0xB8B5, 0x292E), + bn_pack4(0x837C, 0x264A, 0xE3A9, 0xBEB8), + bn_pack4(0xE442, 0x734A, 0xF7CC, 0xB7AE), + bn_pack4(0x6577, 0x2E43, 0x7D6C, 0x7F8C), + bn_pack4(0xDB2F, 0xD53D, 0x24B7, 0xC486), + bn_pack4(0x6EDF, 0x0195, 0x3934, 0x9627), + bn_pack4(0x158B, 0xFD3E, 0x2B9C, 0x8CF5), + bn_pack4(0x764E, 0x3F4B, 0x53DD, 0x9DA1), + bn_pack4(0x4754, 0x8381, 0xDBC5, 0xB1FC), + bn_pack4(0x9B60, 0x9E0B, 0xE3BA, 0xB63D), + bn_pack4(0x8134, 0xB1C8, 0xB979, 0x8914), + bn_pack4(0xDF02, 0x8A7C, 0xEC67, 0xF0D0), + bn_pack4(0x80B6, 0x55BB, 0x9A22, 0xE8DC), + bn_pack4(0x1558, 0x903B, 0xA0D0, 0xF843), + bn_pack4(0x51C6, 0xA94B, 0xE460, 0x7A29), + bn_pack4(0x5F4F, 0x5F55, 0x6E27, 0xCBDE), + bn_pack4(0xBEEE, 0xA961, 0x4B19, 0xCC4D), + bn_pack4(0xDBA5, 0x1DF4, 0x99AC, 0x4C80), + bn_pack4(0xB1F1, 0x2A86, 0x17A4, 0x7BBB), + bn_pack4(0x9DEF, 0x3CAF, 0xB939, 0x277A) +}; + +static BIGNUM bn_group_1536 = { + bn_group_1536_value, + (sizeof bn_group_1536_value) / sizeof(BN_ULONG), + (sizeof bn_group_1536_value) / sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_2048_value[] = { + bn_pack4(0x0FA7, 0x111F, 0x9E4A, 0xFF73), + bn_pack4(0x9B65, 0xE372, 0xFCD6, 0x8EF2), + bn_pack4(0x35DE, 0x236D, 0x525F, 0x5475), + bn_pack4(0x94B5, 0xC803, 0xD89F, 0x7AE4), + bn_pack4(0x71AE, 0x35F8, 0xE9DB, 0xFBB6), + bn_pack4(0x2A56, 0x98F3, 0xA8D0, 0xC382), + bn_pack4(0x9CCC, 0x041C, 0x7BC3, 0x08D8), + bn_pack4(0xAF87, 0x4E73, 0x03CE, 0x5329), + bn_pack4(0x6160, 0x2790, 0x04E5, 0x7AE6), + bn_pack4(0x032C, 0xFBDB, 0xF52F, 0xB378), + bn_pack4(0x5EA7, 0x7A27, 0x75D2, 0xECFA), + bn_pack4(0x5445, 0x23B5, 0x24B0, 0xD57D), + bn_pack4(0x5B9D, 0x32E6, 0x88F8, 0x7748), + bn_pack4(0xF1D2, 0xB907, 0x8717, 0x461A), + bn_pack4(0x76BD, 0x207A, 0x436C, 0x6481), + bn_pack4(0xCA97, 0xB43A, 0x23FB, 0x8016), + bn_pack4(0x1D28, 0x1E44, 0x6B14, 0x773B), + bn_pack4(0x7359, 0xD041, 0xD5C3, 0x3EA7), + bn_pack4(0xA80D, 0x740A, 0xDBF4, 0xFF74), + bn_pack4(0x55F9, 0x7993, 0xEC97, 0x5EEA), + bn_pack4(0x2918, 0xA996, 0x2F0B, 0x93B8), + bn_pack4(0x661A, 0x05FB, 0xD5FA, 0xAAE8), + bn_pack4(0xCF60, 0x9517, 0x9A16, 0x3AB3), + bn_pack4(0xE808, 0x3969, 0xEDB7, 0x67B0), + bn_pack4(0xCD7F, 0x48A9, 0xDA04, 0xFD50), + bn_pack4(0xD523, 0x12AB, 0x4B03, 0x310D), + bn_pack4(0x8193, 0xE075, 0x7767, 0xA13D), + bn_pack4(0xA373, 0x29CB, 0xB4A0, 0x99ED), + bn_pack4(0xFC31, 0x9294, 0x3DB5, 0x6050), + bn_pack4(0xAF72, 0xB665, 0x1987, 0xEE07), + bn_pack4(0xF166, 0xDE5E, 0x1389, 0x582F), + bn_pack4(0xAC6B, 0xDB41, 0x324A, 0x9A9B) +}; + +static BIGNUM bn_group_2048 = { + bn_group_2048_value, + (sizeof bn_group_2048_value) / sizeof(BN_ULONG), + (sizeof bn_group_2048_value) / sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_3072_value[] = { + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF), + bn_pack4(0x4B82, 0xD120, 0xA93A, 0xD2CA), + bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E), + bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31), + bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2), + bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C), + bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C), + bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64), + bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864), + bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B), + bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D), + bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7), + bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7), + bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D), + bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A), + bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64), + bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33), + bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D), + bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510), + bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5), + bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718), + bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9), + bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F), + bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603), + bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B), + bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C), + bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804), + bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D), + bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB), + bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96), + bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F), + bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A), + bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05), + bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D), + bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6), + bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5), + bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED), + bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B), + bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6), + bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245), + bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437), + bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B), + bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD), + bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22), + bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74), + bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1), + bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234), + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) +}; + +static BIGNUM bn_group_3072 = { + bn_group_3072_value, + (sizeof bn_group_3072_value) / sizeof(BN_ULONG), + (sizeof bn_group_3072_value) / sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_4096_value[] = { + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF), + bn_pack4(0x4DF4, 0x35C9, 0x3406, 0x3199), + bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F), + bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1), + bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9), + bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C), + bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF), + bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED), + bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2), + bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D), + bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6), + bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9), + bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8), + bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA), + bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C), + bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26), + bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7), + bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801), + bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E), + bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31), + bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2), + bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C), + bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C), + bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64), + bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864), + bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B), + bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D), + bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7), + bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7), + bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D), + bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A), + bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64), + bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33), + bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D), + bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510), + bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5), + bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718), + bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9), + bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F), + bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603), + bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B), + bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C), + bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804), + bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D), + bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB), + bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96), + bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F), + bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A), + bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05), + bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D), + bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6), + bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5), + bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED), + bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B), + bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6), + bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245), + bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437), + bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B), + bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD), + bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22), + bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74), + bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1), + bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234), + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) +}; + +static BIGNUM bn_group_4096 = { + bn_group_4096_value, + (sizeof bn_group_4096_value) / sizeof(BN_ULONG), + (sizeof bn_group_4096_value) / sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_6144_value[] = { + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF), + bn_pack4(0xE694, 0xF91E, 0x6DCC, 0x4024), + bn_pack4(0x12BF, 0x2D5B, 0x0B74, 0x74D6), + bn_pack4(0x043E, 0x8F66, 0x3F48, 0x60EE), + bn_pack4(0x387F, 0xE8D7, 0x6E3C, 0x0468), + bn_pack4(0xDA56, 0xC9EC, 0x2EF2, 0x9632), + bn_pack4(0xEB19, 0xCCB1, 0xA313, 0xD55C), + bn_pack4(0xF550, 0xAA3D, 0x8A1F, 0xBFF0), + bn_pack4(0x06A1, 0xD58B, 0xB7C5, 0xDA76), + bn_pack4(0xA797, 0x15EE, 0xF29B, 0xE328), + bn_pack4(0x14CC, 0x5ED2, 0x0F80, 0x37E0), + bn_pack4(0xCC8F, 0x6D7E, 0xBF48, 0xE1D8), + bn_pack4(0x4BD4, 0x07B2, 0x2B41, 0x54AA), + bn_pack4(0x0F1D, 0x45B7, 0xFF58, 0x5AC5), + bn_pack4(0x23A9, 0x7A7E, 0x36CC, 0x88BE), + bn_pack4(0x59E7, 0xC97F, 0xBEC7, 0xE8F3), + bn_pack4(0xB5A8, 0x4031, 0x900B, 0x1C9E), + bn_pack4(0xD55E, 0x702F, 0x4698, 0x0C82), + bn_pack4(0xF482, 0xD7CE, 0x6E74, 0xFEF6), + bn_pack4(0xF032, 0xEA15, 0xD172, 0x1D03), + bn_pack4(0x5983, 0xCA01, 0xC64B, 0x92EC), + bn_pack4(0x6FB8, 0xF401, 0x378C, 0xD2BF), + bn_pack4(0x3320, 0x5151, 0x2BD7, 0xAF42), + bn_pack4(0xDB7F, 0x1447, 0xE6CC, 0x254B), + bn_pack4(0x44CE, 0x6CBA, 0xCED4, 0xBB1B), + bn_pack4(0xDA3E, 0xDBEB, 0xCF9B, 0x14ED), + bn_pack4(0x1797, 0x27B0, 0x865A, 0x8918), + bn_pack4(0xB06A, 0x53ED, 0x9027, 0xD831), + bn_pack4(0xE5DB, 0x382F, 0x4130, 0x01AE), + bn_pack4(0xF8FF, 0x9406, 0xAD9E, 0x530E), + bn_pack4(0xC975, 0x1E76, 0x3DBA, 0x37BD), + bn_pack4(0xC1D4, 0xDCB2, 0x6026, 0x46DE), + bn_pack4(0x36C3, 0xFAB4, 0xD27C, 0x7026), + bn_pack4(0x4DF4, 0x35C9, 0x3402, 0x8492), + bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F), + bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1), + bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9), + bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C), + bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF), + bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED), + bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2), + bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D), + bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6), + bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9), + bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8), + bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA), + bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C), + bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26), + bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7), + bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801), + bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E), + bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31), + bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2), + bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C), + bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C), + bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64), + bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864), + bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B), + bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D), + bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7), + bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7), + bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D), + bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A), + bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64), + bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33), + bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D), + bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510), + bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5), + bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718), + bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9), + bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F), + bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603), + bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B), + bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C), + bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804), + bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D), + bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB), + bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96), + bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F), + bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A), + bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05), + bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D), + bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6), + bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5), + bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED), + bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B), + bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6), + bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245), + bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437), + bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B), + bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD), + bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22), + bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74), + bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1), + bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234), + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) +}; + +static BIGNUM bn_group_6144 = { + bn_group_6144_value, + (sizeof bn_group_6144_value) / sizeof(BN_ULONG), + (sizeof bn_group_6144_value) / sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_group_8192_value[] = { + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF), + bn_pack4(0x60C9, 0x80DD, 0x98ED, 0xD3DF), + bn_pack4(0xC81F, 0x56E8, 0x80B9, 0x6E71), + bn_pack4(0x9E30, 0x50E2, 0x7656, 0x94DF), + bn_pack4(0x9558, 0xE447, 0x5677, 0xE9AA), + bn_pack4(0xC919, 0x0DA6, 0xFC02, 0x6E47), + bn_pack4(0x889A, 0x002E, 0xD5EE, 0x382B), + bn_pack4(0x4009, 0x438B, 0x481C, 0x6CD7), + bn_pack4(0x3590, 0x46F4, 0xEB87, 0x9F92), + bn_pack4(0xFAF3, 0x6BC3, 0x1ECF, 0xA268), + bn_pack4(0xB1D5, 0x10BD, 0x7EE7, 0x4D73), + bn_pack4(0xF9AB, 0x4819, 0x5DED, 0x7EA1), + bn_pack4(0x64F3, 0x1CC5, 0x0846, 0x851D), + bn_pack4(0x4597, 0xE899, 0xA025, 0x5DC1), + bn_pack4(0xDF31, 0x0EE0, 0x74AB, 0x6A36), + bn_pack4(0x6D2A, 0x13F8, 0x3F44, 0xF82D), + bn_pack4(0x062B, 0x3CF5, 0xB3A2, 0x78A6), + bn_pack4(0x7968, 0x3303, 0xED5B, 0xDD3A), + bn_pack4(0xFA9D, 0x4B7F, 0xA2C0, 0x87E8), + bn_pack4(0x4BCB, 0xC886, 0x2F83, 0x85DD), + bn_pack4(0x3473, 0xFC64, 0x6CEA, 0x306B), + bn_pack4(0x13EB, 0x57A8, 0x1A23, 0xF0C7), + bn_pack4(0x2222, 0x2E04, 0xA403, 0x7C07), + bn_pack4(0xE3FD, 0xB8BE, 0xFC84, 0x8AD9), + bn_pack4(0x238F, 0x16CB, 0xE39D, 0x652D), + bn_pack4(0x3423, 0xB474, 0x2BF1, 0xC978), + bn_pack4(0x3AAB, 0x639C, 0x5AE4, 0xF568), + bn_pack4(0x2576, 0xF693, 0x6BA4, 0x2466), + bn_pack4(0x741F, 0xA7BF, 0x8AFC, 0x47ED), + bn_pack4(0x3BC8, 0x32B6, 0x8D9D, 0xD300), + bn_pack4(0xD8BE, 0xC4D0, 0x73B9, 0x31BA), + bn_pack4(0x3877, 0x7CB6, 0xA932, 0xDF8C), + bn_pack4(0x74A3, 0x926F, 0x12FE, 0xE5E4), + bn_pack4(0xE694, 0xF91E, 0x6DBE, 0x1159), + bn_pack4(0x12BF, 0x2D5B, 0x0B74, 0x74D6), + bn_pack4(0x043E, 0x8F66, 0x3F48, 0x60EE), + bn_pack4(0x387F, 0xE8D7, 0x6E3C, 0x0468), + bn_pack4(0xDA56, 0xC9EC, 0x2EF2, 0x9632), + bn_pack4(0xEB19, 0xCCB1, 0xA313, 0xD55C), + bn_pack4(0xF550, 0xAA3D, 0x8A1F, 0xBFF0), + bn_pack4(0x06A1, 0xD58B, 0xB7C5, 0xDA76), + bn_pack4(0xA797, 0x15EE, 0xF29B, 0xE328), + bn_pack4(0x14CC, 0x5ED2, 0x0F80, 0x37E0), + bn_pack4(0xCC8F, 0x6D7E, 0xBF48, 0xE1D8), + bn_pack4(0x4BD4, 0x07B2, 0x2B41, 0x54AA), + bn_pack4(0x0F1D, 0x45B7, 0xFF58, 0x5AC5), + bn_pack4(0x23A9, 0x7A7E, 0x36CC, 0x88BE), + bn_pack4(0x59E7, 0xC97F, 0xBEC7, 0xE8F3), + bn_pack4(0xB5A8, 0x4031, 0x900B, 0x1C9E), + bn_pack4(0xD55E, 0x702F, 0x4698, 0x0C82), + bn_pack4(0xF482, 0xD7CE, 0x6E74, 0xFEF6), + bn_pack4(0xF032, 0xEA15, 0xD172, 0x1D03), + bn_pack4(0x5983, 0xCA01, 0xC64B, 0x92EC), + bn_pack4(0x6FB8, 0xF401, 0x378C, 0xD2BF), + bn_pack4(0x3320, 0x5151, 0x2BD7, 0xAF42), + bn_pack4(0xDB7F, 0x1447, 0xE6CC, 0x254B), + bn_pack4(0x44CE, 0x6CBA, 0xCED4, 0xBB1B), + bn_pack4(0xDA3E, 0xDBEB, 0xCF9B, 0x14ED), + bn_pack4(0x1797, 0x27B0, 0x865A, 0x8918), + bn_pack4(0xB06A, 0x53ED, 0x9027, 0xD831), + bn_pack4(0xE5DB, 0x382F, 0x4130, 0x01AE), + bn_pack4(0xF8FF, 0x9406, 0xAD9E, 0x530E), + bn_pack4(0xC975, 0x1E76, 0x3DBA, 0x37BD), + bn_pack4(0xC1D4, 0xDCB2, 0x6026, 0x46DE), + bn_pack4(0x36C3, 0xFAB4, 0xD27C, 0x7026), + bn_pack4(0x4DF4, 0x35C9, 0x3402, 0x8492), + bn_pack4(0x86FF, 0xB7DC, 0x90A6, 0xC08F), + bn_pack4(0x93B4, 0xEA98, 0x8D8F, 0xDDC1), + bn_pack4(0xD006, 0x9127, 0xD5B0, 0x5AA9), + bn_pack4(0xB81B, 0xDD76, 0x2170, 0x481C), + bn_pack4(0x1F61, 0x2970, 0xCEE2, 0xD7AF), + bn_pack4(0x233B, 0xA186, 0x515B, 0xE7ED), + bn_pack4(0x99B2, 0x964F, 0xA090, 0xC3A2), + bn_pack4(0x287C, 0x5947, 0x4E6B, 0xC05D), + bn_pack4(0x2E8E, 0xFC14, 0x1FBE, 0xCAA6), + bn_pack4(0xDBBB, 0xC2DB, 0x04DE, 0x8EF9), + bn_pack4(0x2583, 0xE9CA, 0x2AD4, 0x4CE8), + bn_pack4(0x1A94, 0x6834, 0xB615, 0x0BDA), + bn_pack4(0x99C3, 0x2718, 0x6AF4, 0xE23C), + bn_pack4(0x8871, 0x9A10, 0xBDBA, 0x5B26), + bn_pack4(0x1A72, 0x3C12, 0xA787, 0xE6D7), + bn_pack4(0x4B82, 0xD120, 0xA921, 0x0801), + bn_pack4(0x43DB, 0x5BFC, 0xE0FD, 0x108E), + bn_pack4(0x08E2, 0x4FA0, 0x74E5, 0xAB31), + bn_pack4(0x7709, 0x88C0, 0xBAD9, 0x46E2), + bn_pack4(0xBBE1, 0x1757, 0x7A61, 0x5D6C), + bn_pack4(0x521F, 0x2B18, 0x177B, 0x200C), + bn_pack4(0xD876, 0x0273, 0x3EC8, 0x6A64), + bn_pack4(0xF12F, 0xFA06, 0xD98A, 0x0864), + bn_pack4(0xCEE3, 0xD226, 0x1AD2, 0xEE6B), + bn_pack4(0x1E8C, 0x94E0, 0x4A25, 0x619D), + bn_pack4(0xABF5, 0xAE8C, 0xDB09, 0x33D7), + bn_pack4(0xB397, 0x0F85, 0xA6E1, 0xE4C7), + bn_pack4(0x8AEA, 0x7157, 0x5D06, 0x0C7D), + bn_pack4(0xECFB, 0x8504, 0x58DB, 0xEF0A), + bn_pack4(0xA855, 0x21AB, 0xDF1C, 0xBA64), + bn_pack4(0xAD33, 0x170D, 0x0450, 0x7A33), + bn_pack4(0x1572, 0x8E5A, 0x8AAA, 0xC42D), + bn_pack4(0x15D2, 0x2618, 0x98FA, 0x0510), + bn_pack4(0x3995, 0x497C, 0xEA95, 0x6AE5), + bn_pack4(0xDE2B, 0xCBF6, 0x9558, 0x1718), + bn_pack4(0xB5C5, 0x5DF0, 0x6F4C, 0x52C9), + bn_pack4(0x9B27, 0x83A2, 0xEC07, 0xA28F), + bn_pack4(0xE39E, 0x772C, 0x180E, 0x8603), + bn_pack4(0x3290, 0x5E46, 0x2E36, 0xCE3B), + bn_pack4(0xF174, 0x6C08, 0xCA18, 0x217C), + bn_pack4(0x670C, 0x354E, 0x4ABC, 0x9804), + bn_pack4(0x9ED5, 0x2907, 0x7096, 0x966D), + bn_pack4(0x1C62, 0xF356, 0x2085, 0x52BB), + bn_pack4(0x8365, 0x5D23, 0xDCA3, 0xAD96), + bn_pack4(0x6916, 0x3FA8, 0xFD24, 0xCF5F), + bn_pack4(0x98DA, 0x4836, 0x1C55, 0xD39A), + bn_pack4(0xC200, 0x7CB8, 0xA163, 0xBF05), + bn_pack4(0x4928, 0x6651, 0xECE4, 0x5B3D), + bn_pack4(0xAE9F, 0x2411, 0x7C4B, 0x1FE6), + bn_pack4(0xEE38, 0x6BFB, 0x5A89, 0x9FA5), + bn_pack4(0x0BFF, 0x5CB6, 0xF406, 0xB7ED), + bn_pack4(0xF44C, 0x42E9, 0xA637, 0xED6B), + bn_pack4(0xE485, 0xB576, 0x625E, 0x7EC6), + bn_pack4(0x4FE1, 0x356D, 0x6D51, 0xC245), + bn_pack4(0x302B, 0x0A6D, 0xF25F, 0x1437), + bn_pack4(0xEF95, 0x19B3, 0xCD3A, 0x431B), + bn_pack4(0x514A, 0x0879, 0x8E34, 0x04DD), + bn_pack4(0x020B, 0xBEA6, 0x3B13, 0x9B22), + bn_pack4(0x2902, 0x4E08, 0x8A67, 0xCC74), + bn_pack4(0xC4C6, 0x628B, 0x80DC, 0x1CD1), + bn_pack4(0xC90F, 0xDAA2, 0x2168, 0xC234), + bn_pack4(0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF) +}; + +static BIGNUM bn_group_8192 = { + bn_group_8192_value, + (sizeof bn_group_8192_value) / sizeof(BN_ULONG), + (sizeof bn_group_8192_value) / sizeof(BN_ULONG), + 0, + BN_FLG_STATIC_DATA +}; + +static BN_ULONG bn_generator_19_value[] = { 19 }; + +static BIGNUM bn_generator_19 = { + bn_generator_19_value, + 1, + 1, + 0, + BN_FLG_STATIC_DATA +}; +static BN_ULONG bn_generator_5_value[] = { 5 }; + +static BIGNUM bn_generator_5 = { + bn_generator_5_value, + 1, + 1, + 0, + BN_FLG_STATIC_DATA +}; +static BN_ULONG bn_generator_2_value[] = { 2 }; + +static BIGNUM bn_generator_2 = { + bn_generator_2_value, + 1, + 1, + 0, + BN_FLG_STATIC_DATA +}; + +static SRP_gN knowngN[] = { + {"8192", &bn_generator_19, &bn_group_8192}, + {"6144", &bn_generator_5, &bn_group_6144}, + {"4096", &bn_generator_5, &bn_group_4096}, + {"3072", &bn_generator_5, &bn_group_3072}, + {"2048", &bn_generator_2, &bn_group_2048}, + {"1536", &bn_generator_2, &bn_group_1536}, + {"1024", &bn_generator_2, &bn_group_1024}, +}; + +#define KNOWN_GN_NUMBER sizeof(knowngN) / sizeof(SRP_gN) + +/* end of generated data */ diff --git a/libs/openssl/crypto/srp/srp_lcl.h b/libs/openssl/crypto/srp/srp_lcl.h new file mode 100644 index 00000000..9a7fce1b --- /dev/null +++ b/libs/openssl/crypto/srp/srp_lcl.h @@ -0,0 +1,84 @@ +/* crypto/srp/srp_lcl.h */ +/* + * Written by Peter Sylvester (peter.sylvester@edelweb.fr) for the EdelKey + * project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_SRP_LCL_H +# define HEADER_SRP_LCL_H + +# include +# include + +# if 0 +# define srp_bn_print(a) {fprintf(stderr, #a "="); BN_print_fp(stderr,a); \ + fprintf(stderr,"\n");} +# else +# define srp_bn_print(a) +# endif + + + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/srp/srp_lib.c b/libs/openssl/crypto/srp/srp_lib.c new file mode 100644 index 00000000..e9a2e058 --- /dev/null +++ b/libs/openssl/crypto/srp/srp_lib.c @@ -0,0 +1,357 @@ +/* crypto/srp/srp_lib.c */ +/* + * Written by Christophe Renou (christophe.renou@edelweb.fr) with the + * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the + * EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef OPENSSL_NO_SRP +# include "cryptlib.h" +# include "srp_lcl.h" +# include +# include + +# if (BN_BYTES == 8) +# if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32__) +# define bn_pack4(a1,a2,a3,a4) ((a1##UI64<<48)|(a2##UI64<<32)|(a3##UI64<<16)|a4##UI64) +# elif defined(__arch64__) +# define bn_pack4(a1,a2,a3,a4) ((a1##UL<<48)|(a2##UL<<32)|(a3##UL<<16)|a4##UL) +# else +# define bn_pack4(a1,a2,a3,a4) ((a1##ULL<<48)|(a2##ULL<<32)|(a3##ULL<<16)|a4##ULL) +# endif +# elif (BN_BYTES == 4) +# define bn_pack4(a1,a2,a3,a4) ((a3##UL<<16)|a4##UL), ((a1##UL<<16)|a2##UL) +# else +# error "unsupported BN_BYTES" +# endif + +# include "srp_grps.h" + +static BIGNUM *srp_Calc_k(BIGNUM *N, BIGNUM *g) +{ + /* k = SHA1(N | PAD(g)) -- tls-srp draft 8 */ + + unsigned char digest[SHA_DIGEST_LENGTH]; + unsigned char *tmp; + EVP_MD_CTX ctxt; + int longg; + int longN = BN_num_bytes(N); + + if (BN_ucmp(g, N) >= 0) + return NULL; + + if ((tmp = OPENSSL_malloc(longN)) == NULL) + return NULL; + BN_bn2bin(N, tmp); + + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, tmp, longN); + + memset(tmp, 0, longN); + longg = BN_bn2bin(g, tmp); + /* use the zeros behind to pad on left */ + EVP_DigestUpdate(&ctxt, tmp + longg, longN - longg); + EVP_DigestUpdate(&ctxt, tmp, longg); + OPENSSL_free(tmp); + + EVP_DigestFinal_ex(&ctxt, digest, NULL); + EVP_MD_CTX_cleanup(&ctxt); + return BN_bin2bn(digest, sizeof(digest), NULL); +} + +BIGNUM *SRP_Calc_u(BIGNUM *A, BIGNUM *B, BIGNUM *N) +{ + /* k = SHA1(PAD(A) || PAD(B) ) -- tls-srp draft 8 */ + + BIGNUM *u; + unsigned char cu[SHA_DIGEST_LENGTH]; + unsigned char *cAB; + EVP_MD_CTX ctxt; + int longN; + if ((A == NULL) || (B == NULL) || (N == NULL)) + return NULL; + + if (BN_ucmp(A, N) >= 0 || BN_ucmp(B, N) >= 0) + return NULL; + + longN = BN_num_bytes(N); + + if ((cAB = OPENSSL_malloc(2 * longN)) == NULL) + return NULL; + + memset(cAB, 0, longN); + + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(A, cAB + longN), longN); + EVP_DigestUpdate(&ctxt, cAB + BN_bn2bin(B, cAB + longN), longN); + OPENSSL_free(cAB); + EVP_DigestFinal_ex(&ctxt, cu, NULL); + EVP_MD_CTX_cleanup(&ctxt); + + if (!(u = BN_bin2bn(cu, sizeof(cu), NULL))) + return NULL; + if (!BN_is_zero(u)) + return u; + BN_free(u); + return NULL; +} + +BIGNUM *SRP_Calc_server_key(BIGNUM *A, BIGNUM *v, BIGNUM *u, BIGNUM *b, + BIGNUM *N) +{ + BIGNUM *tmp = NULL, *S = NULL; + BN_CTX *bn_ctx; + + if (u == NULL || A == NULL || v == NULL || b == NULL || N == NULL) + return NULL; + + if ((bn_ctx = BN_CTX_new()) == NULL || + (tmp = BN_new()) == NULL || (S = BN_new()) == NULL) + goto err; + + /* S = (A*v**u) ** b */ + + if (!BN_mod_exp(tmp, v, u, N, bn_ctx)) + goto err; + if (!BN_mod_mul(tmp, A, tmp, N, bn_ctx)) + goto err; + if (!BN_mod_exp(S, tmp, b, N, bn_ctx)) + goto err; + err: + BN_CTX_free(bn_ctx); + BN_clear_free(tmp); + return S; +} + +BIGNUM *SRP_Calc_B(BIGNUM *b, BIGNUM *N, BIGNUM *g, BIGNUM *v) +{ + BIGNUM *kv = NULL, *gb = NULL; + BIGNUM *B = NULL, *k = NULL; + BN_CTX *bn_ctx; + + if (b == NULL || N == NULL || g == NULL || v == NULL || + (bn_ctx = BN_CTX_new()) == NULL) + return NULL; + + if ((kv = BN_new()) == NULL || + (gb = BN_new()) == NULL || (B = BN_new()) == NULL) + goto err; + + /* B = g**b + k*v */ + + if (!BN_mod_exp(gb, g, b, N, bn_ctx) || + !(k = srp_Calc_k(N, g)) || + !BN_mod_mul(kv, v, k, N, bn_ctx) || + !BN_mod_add(B, gb, kv, N, bn_ctx)) { + BN_free(B); + B = NULL; + } + err: + BN_CTX_free(bn_ctx); + BN_clear_free(kv); + BN_clear_free(gb); + BN_free(k); + return B; +} + +BIGNUM *SRP_Calc_x(BIGNUM *s, const char *user, const char *pass) +{ + unsigned char dig[SHA_DIGEST_LENGTH]; + EVP_MD_CTX ctxt; + unsigned char *cs; + + if ((s == NULL) || (user == NULL) || (pass == NULL)) + return NULL; + + if ((cs = OPENSSL_malloc(BN_num_bytes(s))) == NULL) + return NULL; + + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, user, strlen(user)); + EVP_DigestUpdate(&ctxt, ":", 1); + EVP_DigestUpdate(&ctxt, pass, strlen(pass)); + EVP_DigestFinal_ex(&ctxt, dig, NULL); + + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + BN_bn2bin(s, cs); + EVP_DigestUpdate(&ctxt, cs, BN_num_bytes(s)); + OPENSSL_free(cs); + EVP_DigestUpdate(&ctxt, dig, sizeof(dig)); + EVP_DigestFinal_ex(&ctxt, dig, NULL); + EVP_MD_CTX_cleanup(&ctxt); + + return BN_bin2bn(dig, sizeof(dig), NULL); +} + +BIGNUM *SRP_Calc_A(BIGNUM *a, BIGNUM *N, BIGNUM *g) +{ + BN_CTX *bn_ctx; + BIGNUM *A = NULL; + + if (a == NULL || N == NULL || g == NULL || + (bn_ctx = BN_CTX_new()) == NULL) + return NULL; + + if ((A = BN_new()) != NULL && !BN_mod_exp(A, g, a, N, bn_ctx)) { + BN_free(A); + A = NULL; + } + BN_CTX_free(bn_ctx); + return A; +} + +BIGNUM *SRP_Calc_client_key(BIGNUM *N, BIGNUM *B, BIGNUM *g, BIGNUM *x, + BIGNUM *a, BIGNUM *u) +{ + BIGNUM *tmp = NULL, *tmp2 = NULL, *tmp3 = NULL, *k = NULL, *K = NULL; + BN_CTX *bn_ctx; + + if (u == NULL || B == NULL || N == NULL || g == NULL || x == NULL + || a == NULL || (bn_ctx = BN_CTX_new()) == NULL) + return NULL; + + if ((tmp = BN_new()) == NULL || + (tmp2 = BN_new()) == NULL || + (tmp3 = BN_new()) == NULL || (K = BN_new()) == NULL) + goto err; + + if (!BN_mod_exp(tmp, g, x, N, bn_ctx)) + goto err; + if (!(k = srp_Calc_k(N, g))) + goto err; + if (!BN_mod_mul(tmp2, tmp, k, N, bn_ctx)) + goto err; + if (!BN_mod_sub(tmp, B, tmp2, N, bn_ctx)) + goto err; + + if (!BN_mod_mul(tmp3, u, x, N, bn_ctx)) + goto err; + if (!BN_mod_add(tmp2, a, tmp3, N, bn_ctx)) + goto err; + if (!BN_mod_exp(K, tmp, tmp2, N, bn_ctx)) + goto err; + + err: + BN_CTX_free(bn_ctx); + BN_clear_free(tmp); + BN_clear_free(tmp2); + BN_clear_free(tmp3); + BN_free(k); + return K; +} + +int SRP_Verify_B_mod_N(BIGNUM *B, BIGNUM *N) +{ + BIGNUM *r; + BN_CTX *bn_ctx; + int ret = 0; + + if (B == NULL || N == NULL || (bn_ctx = BN_CTX_new()) == NULL) + return 0; + + if ((r = BN_new()) == NULL) + goto err; + /* Checks if B % N == 0 */ + if (!BN_nnmod(r, B, N, bn_ctx)) + goto err; + ret = !BN_is_zero(r); + err: + BN_CTX_free(bn_ctx); + BN_free(r); + return ret; +} + +int SRP_Verify_A_mod_N(BIGNUM *A, BIGNUM *N) +{ + /* Checks if A % N == 0 */ + return SRP_Verify_B_mod_N(A, N); +} + +/* + * Check if G and N are kwown parameters. The values have been generated + * from the ietf-tls-srp draft version 8 + */ +char *SRP_check_known_gN_param(BIGNUM *g, BIGNUM *N) +{ + size_t i; + if ((g == NULL) || (N == NULL)) + return 0; + + srp_bn_print(g); + srp_bn_print(N); + + for (i = 0; i < KNOWN_GN_NUMBER; i++) { + if (BN_cmp(knowngN[i].g, g) == 0 && BN_cmp(knowngN[i].N, N) == 0) + return knowngN[i].id; + } + return NULL; +} + +SRP_gN *SRP_get_default_gN(const char *id) +{ + size_t i; + + if (id == NULL) + return knowngN; + for (i = 0; i < KNOWN_GN_NUMBER; i++) { + if (strcmp(knowngN[i].id, id) == 0) + return knowngN + i; + } + return NULL; +} +#endif diff --git a/libs/openssl/crypto/srp/srp_vfy.c b/libs/openssl/crypto/srp/srp_vfy.c new file mode 100644 index 00000000..26ad3e07 --- /dev/null +++ b/libs/openssl/crypto/srp/srp_vfy.c @@ -0,0 +1,705 @@ +/* crypto/srp/srp_vfy.c */ +/* + * Written by Christophe Renou (christophe.renou@edelweb.fr) with the + * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the + * EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef OPENSSL_NO_SRP +# include "cryptlib.h" +# include "srp_lcl.h" +# include +# include +# include +# include +# include + +# define SRP_RANDOM_SALT_LEN 20 +# define MAX_LEN 2500 + +static char b64table[] = + "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz./"; + +/* + * the following two conversion routines have been inspired by code from + * Stanford + */ + +/* + * Convert a base64 string into raw byte array representation. + */ +static int t_fromb64(unsigned char *a, const char *src) +{ + char *loc; + int i, j; + int size; + + while (*src && (*src == ' ' || *src == '\t' || *src == '\n')) + ++src; + size = strlen(src); + i = 0; + while (i < size) { + loc = strchr(b64table, src[i]); + if (loc == (char *)0) + break; + else + a[i] = loc - b64table; + ++i; + } + /* if nothing valid to process we have a zero length response */ + if (i == 0) + return 0; + size = i; + i = size - 1; + j = size; + while (1) { + a[j] = a[i]; + if (--i < 0) + break; + a[j] |= (a[i] & 3) << 6; + --j; + a[j] = (unsigned char)((a[i] & 0x3c) >> 2); + if (--i < 0) + break; + a[j] |= (a[i] & 0xf) << 4; + --j; + a[j] = (unsigned char)((a[i] & 0x30) >> 4); + if (--i < 0) + break; + a[j] |= (a[i] << 2); + + a[--j] = 0; + if (--i < 0) + break; + } + while (a[j] == 0 && j <= size) + ++j; + i = 0; + while (j <= size) + a[i++] = a[j++]; + return i; +} + +/* + * Convert a raw byte string into a null-terminated base64 ASCII string. + */ +static char *t_tob64(char *dst, const unsigned char *src, int size) +{ + int c, pos = size % 3; + unsigned char b0 = 0, b1 = 0, b2 = 0, notleading = 0; + char *olddst = dst; + + switch (pos) { + case 1: + b2 = src[0]; + break; + case 2: + b1 = src[0]; + b2 = src[1]; + break; + } + + while (1) { + c = (b0 & 0xfc) >> 2; + if (notleading || c != 0) { + *dst++ = b64table[c]; + notleading = 1; + } + c = ((b0 & 3) << 4) | ((b1 & 0xf0) >> 4); + if (notleading || c != 0) { + *dst++ = b64table[c]; + notleading = 1; + } + c = ((b1 & 0xf) << 2) | ((b2 & 0xc0) >> 6); + if (notleading || c != 0) { + *dst++ = b64table[c]; + notleading = 1; + } + c = b2 & 0x3f; + if (notleading || c != 0) { + *dst++ = b64table[c]; + notleading = 1; + } + if (pos >= size) + break; + else { + b0 = src[pos++]; + b1 = src[pos++]; + b2 = src[pos++]; + } + } + + *dst++ = '\0'; + return olddst; +} + +void SRP_user_pwd_free(SRP_user_pwd *user_pwd) +{ + if (user_pwd == NULL) + return; + BN_free(user_pwd->s); + BN_clear_free(user_pwd->v); + OPENSSL_free(user_pwd->id); + OPENSSL_free(user_pwd->info); + OPENSSL_free(user_pwd); +} + +static SRP_user_pwd *SRP_user_pwd_new() +{ + SRP_user_pwd *ret = OPENSSL_malloc(sizeof(SRP_user_pwd)); + if (ret == NULL) + return NULL; + ret->N = NULL; + ret->g = NULL; + ret->s = NULL; + ret->v = NULL; + ret->id = NULL; + ret->info = NULL; + return ret; +} + +static void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g, + const BIGNUM *N) +{ + vinfo->N = N; + vinfo->g = g; +} + +static int SRP_user_pwd_set_ids(SRP_user_pwd *vinfo, const char *id, + const char *info) +{ + if (id != NULL && NULL == (vinfo->id = BUF_strdup(id))) + return 0; + return (info == NULL || NULL != (vinfo->info = BUF_strdup(info))); +} + +static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s, + const char *v) +{ + unsigned char tmp[MAX_LEN]; + int len; + + if (strlen(s) > MAX_LEN || strlen(v) > MAX_LEN) + return 0; + len = t_fromb64(tmp, v); + if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL))) + return 0; + len = t_fromb64(tmp, s); + return ((vinfo->s = BN_bin2bn(tmp, len, NULL)) != NULL); +} + +static int SRP_user_pwd_set_sv_BN(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v) +{ + vinfo->v = v; + vinfo->s = s; + return (vinfo->s != NULL && vinfo->v != NULL); +} + +static SRP_user_pwd *srp_user_pwd_dup(SRP_user_pwd *src) +{ + SRP_user_pwd *ret; + + if (src == NULL) + return NULL; + if ((ret = SRP_user_pwd_new()) == NULL) + return NULL; + + SRP_user_pwd_set_gN(ret, src->g, src->N); + if (!SRP_user_pwd_set_ids(ret, src->id, src->info) + || !SRP_user_pwd_set_sv_BN(ret, BN_dup(src->s), BN_dup(src->v))) { + SRP_user_pwd_free(ret); + return NULL; + } + return ret; +} + +SRP_VBASE *SRP_VBASE_new(char *seed_key) +{ + SRP_VBASE *vb = (SRP_VBASE *)OPENSSL_malloc(sizeof(SRP_VBASE)); + + if (vb == NULL) + return NULL; + if (!(vb->users_pwd = sk_SRP_user_pwd_new_null()) || + !(vb->gN_cache = sk_SRP_gN_cache_new_null())) { + OPENSSL_free(vb); + return NULL; + } + vb->default_g = NULL; + vb->default_N = NULL; + vb->seed_key = NULL; + if ((seed_key != NULL) && (vb->seed_key = BUF_strdup(seed_key)) == NULL) { + sk_SRP_user_pwd_free(vb->users_pwd); + sk_SRP_gN_cache_free(vb->gN_cache); + OPENSSL_free(vb); + return NULL; + } + return vb; +} + +int SRP_VBASE_free(SRP_VBASE *vb) +{ + sk_SRP_user_pwd_pop_free(vb->users_pwd, SRP_user_pwd_free); + sk_SRP_gN_cache_free(vb->gN_cache); + OPENSSL_free(vb->seed_key); + OPENSSL_free(vb); + return 0; +} + +static SRP_gN_cache *SRP_gN_new_init(const char *ch) +{ + unsigned char tmp[MAX_LEN]; + int len; + + SRP_gN_cache *newgN = + (SRP_gN_cache *)OPENSSL_malloc(sizeof(SRP_gN_cache)); + if (newgN == NULL) + return NULL; + + if ((newgN->b64_bn = BUF_strdup(ch)) == NULL) + goto err; + + len = t_fromb64(tmp, ch); + if ((newgN->bn = BN_bin2bn(tmp, len, NULL))) + return newgN; + + OPENSSL_free(newgN->b64_bn); + err: + OPENSSL_free(newgN); + return NULL; +} + +static void SRP_gN_free(SRP_gN_cache *gN_cache) +{ + if (gN_cache == NULL) + return; + OPENSSL_free(gN_cache->b64_bn); + BN_free(gN_cache->bn); + OPENSSL_free(gN_cache); +} + +static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab) +{ + int i; + + SRP_gN *gN; + if (gN_tab != NULL) + for (i = 0; i < sk_SRP_gN_num(gN_tab); i++) { + gN = sk_SRP_gN_value(gN_tab, i); + if (gN && (id == NULL || strcmp(gN->id, id) == 0)) + return gN; + } + + return SRP_get_default_gN(id); +} + +static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch) +{ + int i; + if (gN_cache == NULL) + return NULL; + + /* search if we have already one... */ + for (i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++) { + SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i); + if (strcmp(cache->b64_bn, ch) == 0) + return cache->bn; + } + { /* it is the first time that we find it */ + SRP_gN_cache *newgN = SRP_gN_new_init(ch); + if (newgN) { + if (sk_SRP_gN_cache_insert(gN_cache, newgN, 0) > 0) + return newgN->bn; + SRP_gN_free(newgN); + } + } + return NULL; +} + +/* + * this function parses verifier file. Format is: + * string(index):base64(N):base64(g):0 + * string(username):base64(v):base64(salt):int(index) + */ + +int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file) +{ + int error_code; + STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null(); + char *last_index = NULL; + int i; + char **pp; + + SRP_gN *gN = NULL; + SRP_user_pwd *user_pwd = NULL; + + TXT_DB *tmpdb = NULL; + BIO *in = BIO_new(BIO_s_file()); + + error_code = SRP_ERR_OPEN_FILE; + + if (in == NULL || BIO_read_filename(in, verifier_file) <= 0) + goto err; + + error_code = SRP_ERR_VBASE_INCOMPLETE_FILE; + + if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL) + goto err; + + error_code = SRP_ERR_MEMORY; + + if (vb->seed_key) { + last_index = SRP_get_default_gN(NULL)->id; + } + for (i = 0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++) { + pp = sk_OPENSSL_PSTRING_value(tmpdb->data, i); + if (pp[DB_srptype][0] == DB_SRP_INDEX) { + /* + * we add this couple in the internal Stack + */ + + if ((gN = (SRP_gN *) OPENSSL_malloc(sizeof(SRP_gN))) == NULL) + goto err; + + if (!(gN->id = BUF_strdup(pp[DB_srpid])) + || !(gN->N = + SRP_gN_place_bn(vb->gN_cache, pp[DB_srpverifier])) + || !(gN->g = SRP_gN_place_bn(vb->gN_cache, pp[DB_srpsalt])) + || sk_SRP_gN_insert(SRP_gN_tab, gN, 0) == 0) + goto err; + + gN = NULL; + + if (vb->seed_key != NULL) { + last_index = pp[DB_srpid]; + } + } else if (pp[DB_srptype][0] == DB_SRP_VALID) { + /* it is a user .... */ + SRP_gN *lgN; + if ((lgN = SRP_get_gN_by_id(pp[DB_srpgN], SRP_gN_tab)) != NULL) { + error_code = SRP_ERR_MEMORY; + if ((user_pwd = SRP_user_pwd_new()) == NULL) + goto err; + + SRP_user_pwd_set_gN(user_pwd, lgN->g, lgN->N); + if (!SRP_user_pwd_set_ids + (user_pwd, pp[DB_srpid], pp[DB_srpinfo])) + goto err; + + error_code = SRP_ERR_VBASE_BN_LIB; + if (!SRP_user_pwd_set_sv + (user_pwd, pp[DB_srpsalt], pp[DB_srpverifier])) + goto err; + + if (sk_SRP_user_pwd_insert(vb->users_pwd, user_pwd, 0) == 0) + goto err; + user_pwd = NULL; /* abandon responsability */ + } + } + } + + if (last_index != NULL) { + /* this means that we want to simulate a default user */ + + if (((gN = SRP_get_gN_by_id(last_index, SRP_gN_tab)) == NULL)) { + error_code = SRP_ERR_VBASE_BN_LIB; + goto err; + } + vb->default_g = gN->g; + vb->default_N = gN->N; + gN = NULL; + } + error_code = SRP_NO_ERROR; + + err: + /* + * there may be still some leaks to fix, if this fails, the application + * terminates most likely + */ + + if (gN != NULL) { + OPENSSL_free(gN->id); + OPENSSL_free(gN); + } + + SRP_user_pwd_free(user_pwd); + + if (tmpdb) + TXT_DB_free(tmpdb); + if (in) + BIO_free_all(in); + + sk_SRP_gN_free(SRP_gN_tab); + + return error_code; + +} + +static SRP_user_pwd *find_user(SRP_VBASE *vb, char *username) +{ + int i; + SRP_user_pwd *user; + + if (vb == NULL) + return NULL; + + for (i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++) { + user = sk_SRP_user_pwd_value(vb->users_pwd, i); + if (strcmp(user->id, username) == 0) + return user; + } + + return NULL; +} + +/* + * This method ignores the configured seed and fails for an unknown user. + * Ownership of the returned pointer is not released to the caller. + * In other words, caller must not free the result. + */ +SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username) +{ + return find_user(vb, username); +} + +/* + * Ownership of the returned pointer is released to the caller. + * In other words, caller must free the result once done. + */ +SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username) +{ + SRP_user_pwd *user; + unsigned char digv[SHA_DIGEST_LENGTH]; + unsigned char digs[SHA_DIGEST_LENGTH]; + EVP_MD_CTX ctxt; + + if (vb == NULL) + return NULL; + + if ((user = find_user(vb, username)) != NULL) + return srp_user_pwd_dup(user); + + if ((vb->seed_key == NULL) || + (vb->default_g == NULL) || (vb->default_N == NULL)) + return NULL; + +/* if the user is unknown we set parameters as well if we have a seed_key */ + + if ((user = SRP_user_pwd_new()) == NULL) + return NULL; + + SRP_user_pwd_set_gN(user, vb->default_g, vb->default_N); + + if (!SRP_user_pwd_set_ids(user, username, NULL)) + goto err; + + if (RAND_pseudo_bytes(digv, SHA_DIGEST_LENGTH) < 0) + goto err; + EVP_MD_CTX_init(&ctxt); + EVP_DigestInit_ex(&ctxt, EVP_sha1(), NULL); + EVP_DigestUpdate(&ctxt, vb->seed_key, strlen(vb->seed_key)); + EVP_DigestUpdate(&ctxt, username, strlen(username)); + EVP_DigestFinal_ex(&ctxt, digs, NULL); + EVP_MD_CTX_cleanup(&ctxt); + if (SRP_user_pwd_set_sv_BN + (user, BN_bin2bn(digs, SHA_DIGEST_LENGTH, NULL), + BN_bin2bn(digv, SHA_DIGEST_LENGTH, NULL))) + return user; + + err:SRP_user_pwd_free(user); + return NULL; +} + +/* + * create a verifier (*salt,*verifier,g and N are in base64) + */ +char *SRP_create_verifier(const char *user, const char *pass, char **salt, + char **verifier, const char *N, const char *g) +{ + int len; + char *result = NULL, *vf = NULL; + BIGNUM *N_bn = NULL, *g_bn = NULL, *s = NULL, *v = NULL; + unsigned char tmp[MAX_LEN]; + unsigned char tmp2[MAX_LEN]; + char *defgNid = NULL; + int vfsize = 0; + + if ((user == NULL) || + (pass == NULL) || (salt == NULL) || (verifier == NULL)) + goto err; + + if (N) { + if (!(len = t_fromb64(tmp, N))) + goto err; + N_bn = BN_bin2bn(tmp, len, NULL); + if (!(len = t_fromb64(tmp, g))) + goto err; + g_bn = BN_bin2bn(tmp, len, NULL); + defgNid = "*"; + } else { + SRP_gN *gN = SRP_get_gN_by_id(g, NULL); + if (gN == NULL) + goto err; + N_bn = gN->N; + g_bn = gN->g; + defgNid = gN->id; + } + + if (*salt == NULL) { + if (RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN) < 0) + goto err; + + s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL); + } else { + if (!(len = t_fromb64(tmp2, *salt))) + goto err; + s = BN_bin2bn(tmp2, len, NULL); + } + + if (!SRP_create_verifier_BN(user, pass, &s, &v, N_bn, g_bn)) + goto err; + + BN_bn2bin(v, tmp); + vfsize = BN_num_bytes(v) * 2; + if (((vf = OPENSSL_malloc(vfsize)) == NULL)) + goto err; + t_tob64(vf, tmp, BN_num_bytes(v)); + + if (*salt == NULL) { + char *tmp_salt; + + if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL) { + goto err; + } + t_tob64(tmp_salt, tmp2, SRP_RANDOM_SALT_LEN); + *salt = tmp_salt; + } + + *verifier = vf; + vf = NULL; + result = defgNid; + + err: + if (N) { + BN_free(N_bn); + BN_free(g_bn); + } + OPENSSL_cleanse(vf, vfsize); + OPENSSL_free(vf); + BN_clear_free(s); + BN_clear_free(v); + return result; +} + +/* + * create a verifier (*salt,*verifier,g and N are BIGNUMs). If *salt != NULL + * then the provided salt will be used. On successful exit *verifier will point + * to a newly allocated BIGNUM containing the verifier and (if a salt was not + * provided) *salt will be populated with a newly allocated BIGNUM containing a + * random salt. + * The caller is responsible for freeing the allocated *salt and *verifier + * BIGNUMS. + */ +int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt, + BIGNUM **verifier, BIGNUM *N, BIGNUM *g) +{ + int result = 0; + BIGNUM *x = NULL; + BN_CTX *bn_ctx = BN_CTX_new(); + unsigned char tmp2[MAX_LEN]; + BIGNUM *salttmp = NULL; + + if ((user == NULL) || + (pass == NULL) || + (salt == NULL) || + (verifier == NULL) || (N == NULL) || (g == NULL) || (bn_ctx == NULL)) + goto err; + + srp_bn_print(N); + srp_bn_print(g); + + if (*salt == NULL) { + if (RAND_pseudo_bytes(tmp2, SRP_RANDOM_SALT_LEN) < 0) + goto err; + + salttmp = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL); + } else { + salttmp = *salt; + } + + x = SRP_Calc_x(salttmp, user, pass); + + *verifier = BN_new(); + if (*verifier == NULL) + goto err; + + if (!BN_mod_exp(*verifier, g, x, N, bn_ctx)) { + BN_clear_free(*verifier); + goto err; + } + + srp_bn_print(*verifier); + + result = 1; + *salt = salttmp; + + err: + if (*salt != salttmp) + BN_clear_free(salttmp); + BN_clear_free(x); + BN_CTX_free(bn_ctx); + return result; +} + +#endif diff --git a/libs/openssl/crypto/srp/srptest.c b/libs/openssl/crypto/srp/srptest.c new file mode 100644 index 00000000..451c70e4 --- /dev/null +++ b/libs/openssl/crypto/srp/srptest.c @@ -0,0 +1,154 @@ +#include +#ifdef OPENSSL_NO_SRP + +# include + +int main(int argc, char *argv[]) +{ + printf("No SRP support\n"); + return (0); +} + +#else + +# include +# include +# include + +static void showbn(const char *name, const BIGNUM *bn) +{ + fputs(name, stdout); + fputs(" = ", stdout); + BN_print_fp(stdout, bn); + putc('\n', stdout); +} + +# define RANDOM_SIZE 32 /* use 256 bits on each side */ + +static int run_srp(const char *username, const char *client_pass, + const char *server_pass) +{ + int ret = -1; + BIGNUM *s = NULL; + BIGNUM *v = NULL; + BIGNUM *a = NULL; + BIGNUM *b = NULL; + BIGNUM *u = NULL; + BIGNUM *x = NULL; + BIGNUM *Apub = NULL; + BIGNUM *Bpub = NULL; + BIGNUM *Kclient = NULL; + BIGNUM *Kserver = NULL; + unsigned char rand_tmp[RANDOM_SIZE]; + /* use builtin 1024-bit params */ + SRP_gN *GN = SRP_get_default_gN("1024"); + + if (GN == NULL) { + fprintf(stderr, "Failed to get SRP parameters\n"); + return -1; + } + /* Set up server's password entry */ + if (!SRP_create_verifier_BN(username, server_pass, &s, &v, GN->N, GN->g)) { + fprintf(stderr, "Failed to create SRP verifier\n"); + return -1; + } + + showbn("N", GN->N); + showbn("g", GN->g); + showbn("Salt", s); + showbn("Verifier", v); + + /* Server random */ + RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp)); + b = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); + /* TODO - check b != 0 */ + showbn("b", b); + + /* Server's first message */ + Bpub = SRP_Calc_B(b, GN->N, GN->g, v); + showbn("B", Bpub); + + if (!SRP_Verify_B_mod_N(Bpub, GN->N)) { + fprintf(stderr, "Invalid B\n"); + return -1; + } + + /* Client random */ + RAND_pseudo_bytes(rand_tmp, sizeof(rand_tmp)); + a = BN_bin2bn(rand_tmp, sizeof(rand_tmp), NULL); + /* TODO - check a != 0 */ + showbn("a", a); + + /* Client's response */ + Apub = SRP_Calc_A(a, GN->N, GN->g); + showbn("A", Apub); + + if (!SRP_Verify_A_mod_N(Apub, GN->N)) { + fprintf(stderr, "Invalid A\n"); + return -1; + } + + /* Both sides calculate u */ + u = SRP_Calc_u(Apub, Bpub, GN->N); + + /* Client's key */ + x = SRP_Calc_x(s, username, client_pass); + Kclient = SRP_Calc_client_key(GN->N, Bpub, GN->g, x, a, u); + showbn("Client's key", Kclient); + + /* Server's key */ + Kserver = SRP_Calc_server_key(Apub, v, u, b, GN->N); + showbn("Server's key", Kserver); + + if (BN_cmp(Kclient, Kserver) == 0) { + ret = 0; + } else { + fprintf(stderr, "Keys mismatch\n"); + ret = 1; + } + + BN_clear_free(Kclient); + BN_clear_free(Kserver); + BN_clear_free(x); + BN_free(u); + BN_free(Apub); + BN_clear_free(a); + BN_free(Bpub); + BN_clear_free(b); + BN_free(s); + BN_clear_free(v); + + return ret; +} + +int main(int argc, char **argv) +{ + BIO *bio_err; + bio_err = BIO_new_fp(stderr, BIO_NOCLOSE); + + CRYPTO_malloc_debug_init(); + CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + + ERR_load_crypto_strings(); + + /* "Negative" test, expect a mismatch */ + if (run_srp("alice", "password1", "password2") == 0) { + fprintf(stderr, "Mismatched SRP run failed\n"); + return 1; + } + + /* "Positive" test, should pass */ + if (run_srp("alice", "password", "password") != 0) { + fprintf(stderr, "Plain SRP run failed\n"); + return 1; + } + + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + ERR_free_strings(); + CRYPTO_mem_leaks(bio_err); + + return 0; +} +#endif diff --git a/libs/openssl/crypto/stack/safestack.h b/libs/openssl/crypto/stack/safestack.h new file mode 100644 index 00000000..519649b6 --- /dev/null +++ b/libs/openssl/crypto/stack/safestack.h @@ -0,0 +1,2536 @@ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SAFESTACK_H +# define HEADER_SAFESTACK_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifndef CHECKED_PTR_OF +# define CHECKED_PTR_OF(type, p) \ + ((void*) (1 ? p : (type*)0)) +# endif + +/* + * In C++ we get problems because an explicit cast is needed from (void *) we + * use CHECKED_STACK_OF to ensure the correct type is passed in the macros + * below. + */ + +# define CHECKED_STACK_OF(type, p) \ + ((_STACK*) (1 ? p : (STACK_OF(type)*)0)) + +# define CHECKED_SK_FREE_FUNC(type, p) \ + ((void (*)(void *)) ((1 ? p : (void (*)(type *))0))) + +# define CHECKED_SK_FREE_FUNC2(type, p) \ + ((void (*)(void *)) ((1 ? p : (void (*)(type))0))) + +# define CHECKED_SK_CMP_FUNC(type, p) \ + ((int (*)(const void *, const void *)) \ + ((1 ? p : (int (*)(const type * const *, const type * const *))0))) + +# define STACK_OF(type) struct stack_st_##type +# define PREDECLARE_STACK_OF(type) STACK_OF(type); + +# define DECLARE_STACK_OF(type) \ +STACK_OF(type) \ + { \ + _STACK stack; \ + }; +# define DECLARE_SPECIAL_STACK_OF(type, type2) \ +STACK_OF(type) \ + { \ + _STACK stack; \ + }; + +/* nada (obsolete in new safestack approach)*/ +# define IMPLEMENT_STACK_OF(type) + +/*- + * Strings are special: normally an lhash entry will point to a single + * (somewhat) mutable object. In the case of strings: + * + * a) Instead of a single char, there is an array of chars, NUL-terminated. + * b) The string may have be immutable. + * + * So, they need their own declarations. Especially important for + * type-checking tools, such as Deputy. + * + * In practice, however, it appears to be hard to have a const + * string. For now, I'm settling for dealing with the fact it is a + * string at all. + */ +typedef char *OPENSSL_STRING; + +typedef const char *OPENSSL_CSTRING; + +/* + * Confusingly, LHASH_OF(STRING) deals with char ** throughout, but + * STACK_OF(STRING) is really more like STACK_OF(char), only, as mentioned + * above, instead of a single char each entry is a NUL-terminated array of + * chars. So, we have to implement STRING specially for STACK_OF. This is + * dealt with in the autogenerated macros below. + */ + +DECLARE_SPECIAL_STACK_OF(OPENSSL_STRING, char) + +/* + * Similarly, we sometimes use a block of characters, NOT nul-terminated. + * These should also be distinguished from "normal" stacks. + */ +typedef void *OPENSSL_BLOCK; +DECLARE_SPECIAL_STACK_OF(OPENSSL_BLOCK, void) + +/* + * SKM_sk_... stack macros are internal to safestack.h: never use them + * directly, use sk__... instead + */ +# define SKM_sk_new(type, cmp) \ + ((STACK_OF(type) *)sk_new(CHECKED_SK_CMP_FUNC(type, cmp))) +# define SKM_sk_new_null(type) \ + ((STACK_OF(type) *)sk_new_null()) +# define SKM_sk_free(type, st) \ + sk_free(CHECKED_STACK_OF(type, st)) +# define SKM_sk_num(type, st) \ + sk_num(CHECKED_STACK_OF(type, st)) +# define SKM_sk_value(type, st,i) \ + ((type *)sk_value(CHECKED_STACK_OF(type, st), i)) +# define SKM_sk_set(type, st,i,val) \ + sk_set(CHECKED_STACK_OF(type, st), i, CHECKED_PTR_OF(type, val)) +# define SKM_sk_zero(type, st) \ + sk_zero(CHECKED_STACK_OF(type, st)) +# define SKM_sk_push(type, st, val) \ + sk_push(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +# define SKM_sk_unshift(type, st, val) \ + sk_unshift(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +# define SKM_sk_find(type, st, val) \ + sk_find(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val)) +# define SKM_sk_find_ex(type, st, val) \ + sk_find_ex(CHECKED_STACK_OF(type, st), \ + CHECKED_PTR_OF(type, val)) +# define SKM_sk_delete(type, st, i) \ + (type *)sk_delete(CHECKED_STACK_OF(type, st), i) +# define SKM_sk_delete_ptr(type, st, ptr) \ + (type *)sk_delete_ptr(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, ptr)) +# define SKM_sk_insert(type, st,val, i) \ + sk_insert(CHECKED_STACK_OF(type, st), CHECKED_PTR_OF(type, val), i) +# define SKM_sk_set_cmp_func(type, st, cmp) \ + ((int (*)(const type * const *,const type * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(type, st), CHECKED_SK_CMP_FUNC(type, cmp))) +# define SKM_sk_dup(type, st) \ + (STACK_OF(type) *)sk_dup(CHECKED_STACK_OF(type, st)) +# define SKM_sk_pop_free(type, st, free_func) \ + sk_pop_free(CHECKED_STACK_OF(type, st), CHECKED_SK_FREE_FUNC(type, free_func)) +# define SKM_sk_shift(type, st) \ + (type *)sk_shift(CHECKED_STACK_OF(type, st)) +# define SKM_sk_pop(type, st) \ + (type *)sk_pop(CHECKED_STACK_OF(type, st)) +# define SKM_sk_sort(type, st) \ + sk_sort(CHECKED_STACK_OF(type, st)) +# define SKM_sk_is_sorted(type, st) \ + sk_is_sorted(CHECKED_STACK_OF(type, st)) +# define SKM_ASN1_SET_OF_d2i(type, st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + (STACK_OF(type) *)d2i_ASN1_SET( \ + (STACK_OF(OPENSSL_BLOCK) **)CHECKED_PTR_OF(STACK_OF(type)*, st), \ + pp, length, \ + CHECKED_D2I_OF(type, d2i_func), \ + CHECKED_SK_FREE_FUNC(type, free_func), \ + ex_tag, ex_class) +# define SKM_ASN1_SET_OF_i2d(type, st, pp, i2d_func, ex_tag, ex_class, is_set) \ + i2d_ASN1_SET((STACK_OF(OPENSSL_BLOCK) *)CHECKED_STACK_OF(type, st), pp, \ + CHECKED_I2D_OF(type, i2d_func), \ + ex_tag, ex_class, is_set) +# define SKM_ASN1_seq_pack(type, st, i2d_func, buf, len) \ + ASN1_seq_pack(CHECKED_PTR_OF(STACK_OF(type), st), \ + CHECKED_I2D_OF(type, i2d_func), buf, len) +# define SKM_ASN1_seq_unpack(type, buf, len, d2i_func, free_func) \ + (STACK_OF(type) *)ASN1_seq_unpack(buf, len, CHECKED_D2I_OF(type, d2i_func), CHECKED_SK_FREE_FUNC(type, free_func)) +# define SKM_PKCS12_decrypt_d2i(type, algor, d2i_func, free_func, pass, passlen, oct, seq) \ + (STACK_OF(type) *)PKCS12_decrypt_d2i(algor, \ + CHECKED_D2I_OF(type, d2i_func), \ + CHECKED_SK_FREE_FUNC(type, free_func), \ + pass, passlen, oct, seq) +/* + * This block of defines is updated by util/mkstack.pl, please do not touch! + */ +# define sk_ACCESS_DESCRIPTION_new(cmp) SKM_sk_new(ACCESS_DESCRIPTION, (cmp)) +# define sk_ACCESS_DESCRIPTION_new_null() SKM_sk_new_null(ACCESS_DESCRIPTION) +# define sk_ACCESS_DESCRIPTION_free(st) SKM_sk_free(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_num(st) SKM_sk_num(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_value(st, i) SKM_sk_value(ACCESS_DESCRIPTION, (st), (i)) +# define sk_ACCESS_DESCRIPTION_set(st, i, val) SKM_sk_set(ACCESS_DESCRIPTION, (st), (i), (val)) +# define sk_ACCESS_DESCRIPTION_zero(st) SKM_sk_zero(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_push(st, val) SKM_sk_push(ACCESS_DESCRIPTION, (st), (val)) +# define sk_ACCESS_DESCRIPTION_unshift(st, val) SKM_sk_unshift(ACCESS_DESCRIPTION, (st), (val)) +# define sk_ACCESS_DESCRIPTION_find(st, val) SKM_sk_find(ACCESS_DESCRIPTION, (st), (val)) +# define sk_ACCESS_DESCRIPTION_find_ex(st, val) SKM_sk_find_ex(ACCESS_DESCRIPTION, (st), (val)) +# define sk_ACCESS_DESCRIPTION_delete(st, i) SKM_sk_delete(ACCESS_DESCRIPTION, (st), (i)) +# define sk_ACCESS_DESCRIPTION_delete_ptr(st, ptr) SKM_sk_delete_ptr(ACCESS_DESCRIPTION, (st), (ptr)) +# define sk_ACCESS_DESCRIPTION_insert(st, val, i) SKM_sk_insert(ACCESS_DESCRIPTION, (st), (val), (i)) +# define sk_ACCESS_DESCRIPTION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ACCESS_DESCRIPTION, (st), (cmp)) +# define sk_ACCESS_DESCRIPTION_dup(st) SKM_sk_dup(ACCESS_DESCRIPTION, st) +# define sk_ACCESS_DESCRIPTION_pop_free(st, free_func) SKM_sk_pop_free(ACCESS_DESCRIPTION, (st), (free_func)) +# define sk_ACCESS_DESCRIPTION_shift(st) SKM_sk_shift(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_pop(st) SKM_sk_pop(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_sort(st) SKM_sk_sort(ACCESS_DESCRIPTION, (st)) +# define sk_ACCESS_DESCRIPTION_is_sorted(st) SKM_sk_is_sorted(ACCESS_DESCRIPTION, (st)) +# define sk_ASIdOrRange_new(cmp) SKM_sk_new(ASIdOrRange, (cmp)) +# define sk_ASIdOrRange_new_null() SKM_sk_new_null(ASIdOrRange) +# define sk_ASIdOrRange_free(st) SKM_sk_free(ASIdOrRange, (st)) +# define sk_ASIdOrRange_num(st) SKM_sk_num(ASIdOrRange, (st)) +# define sk_ASIdOrRange_value(st, i) SKM_sk_value(ASIdOrRange, (st), (i)) +# define sk_ASIdOrRange_set(st, i, val) SKM_sk_set(ASIdOrRange, (st), (i), (val)) +# define sk_ASIdOrRange_zero(st) SKM_sk_zero(ASIdOrRange, (st)) +# define sk_ASIdOrRange_push(st, val) SKM_sk_push(ASIdOrRange, (st), (val)) +# define sk_ASIdOrRange_unshift(st, val) SKM_sk_unshift(ASIdOrRange, (st), (val)) +# define sk_ASIdOrRange_find(st, val) SKM_sk_find(ASIdOrRange, (st), (val)) +# define sk_ASIdOrRange_find_ex(st, val) SKM_sk_find_ex(ASIdOrRange, (st), (val)) +# define sk_ASIdOrRange_delete(st, i) SKM_sk_delete(ASIdOrRange, (st), (i)) +# define sk_ASIdOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASIdOrRange, (st), (ptr)) +# define sk_ASIdOrRange_insert(st, val, i) SKM_sk_insert(ASIdOrRange, (st), (val), (i)) +# define sk_ASIdOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASIdOrRange, (st), (cmp)) +# define sk_ASIdOrRange_dup(st) SKM_sk_dup(ASIdOrRange, st) +# define sk_ASIdOrRange_pop_free(st, free_func) SKM_sk_pop_free(ASIdOrRange, (st), (free_func)) +# define sk_ASIdOrRange_shift(st) SKM_sk_shift(ASIdOrRange, (st)) +# define sk_ASIdOrRange_pop(st) SKM_sk_pop(ASIdOrRange, (st)) +# define sk_ASIdOrRange_sort(st) SKM_sk_sort(ASIdOrRange, (st)) +# define sk_ASIdOrRange_is_sorted(st) SKM_sk_is_sorted(ASIdOrRange, (st)) +# define sk_ASN1_GENERALSTRING_new(cmp) SKM_sk_new(ASN1_GENERALSTRING, (cmp)) +# define sk_ASN1_GENERALSTRING_new_null() SKM_sk_new_null(ASN1_GENERALSTRING) +# define sk_ASN1_GENERALSTRING_free(st) SKM_sk_free(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_num(st) SKM_sk_num(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_value(st, i) SKM_sk_value(ASN1_GENERALSTRING, (st), (i)) +# define sk_ASN1_GENERALSTRING_set(st, i, val) SKM_sk_set(ASN1_GENERALSTRING, (st), (i), (val)) +# define sk_ASN1_GENERALSTRING_zero(st) SKM_sk_zero(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_push(st, val) SKM_sk_push(ASN1_GENERALSTRING, (st), (val)) +# define sk_ASN1_GENERALSTRING_unshift(st, val) SKM_sk_unshift(ASN1_GENERALSTRING, (st), (val)) +# define sk_ASN1_GENERALSTRING_find(st, val) SKM_sk_find(ASN1_GENERALSTRING, (st), (val)) +# define sk_ASN1_GENERALSTRING_find_ex(st, val) SKM_sk_find_ex(ASN1_GENERALSTRING, (st), (val)) +# define sk_ASN1_GENERALSTRING_delete(st, i) SKM_sk_delete(ASN1_GENERALSTRING, (st), (i)) +# define sk_ASN1_GENERALSTRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_GENERALSTRING, (st), (ptr)) +# define sk_ASN1_GENERALSTRING_insert(st, val, i) SKM_sk_insert(ASN1_GENERALSTRING, (st), (val), (i)) +# define sk_ASN1_GENERALSTRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_GENERALSTRING, (st), (cmp)) +# define sk_ASN1_GENERALSTRING_dup(st) SKM_sk_dup(ASN1_GENERALSTRING, st) +# define sk_ASN1_GENERALSTRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_GENERALSTRING, (st), (free_func)) +# define sk_ASN1_GENERALSTRING_shift(st) SKM_sk_shift(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_pop(st) SKM_sk_pop(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_sort(st) SKM_sk_sort(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_GENERALSTRING_is_sorted(st) SKM_sk_is_sorted(ASN1_GENERALSTRING, (st)) +# define sk_ASN1_INTEGER_new(cmp) SKM_sk_new(ASN1_INTEGER, (cmp)) +# define sk_ASN1_INTEGER_new_null() SKM_sk_new_null(ASN1_INTEGER) +# define sk_ASN1_INTEGER_free(st) SKM_sk_free(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_num(st) SKM_sk_num(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_value(st, i) SKM_sk_value(ASN1_INTEGER, (st), (i)) +# define sk_ASN1_INTEGER_set(st, i, val) SKM_sk_set(ASN1_INTEGER, (st), (i), (val)) +# define sk_ASN1_INTEGER_zero(st) SKM_sk_zero(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_push(st, val) SKM_sk_push(ASN1_INTEGER, (st), (val)) +# define sk_ASN1_INTEGER_unshift(st, val) SKM_sk_unshift(ASN1_INTEGER, (st), (val)) +# define sk_ASN1_INTEGER_find(st, val) SKM_sk_find(ASN1_INTEGER, (st), (val)) +# define sk_ASN1_INTEGER_find_ex(st, val) SKM_sk_find_ex(ASN1_INTEGER, (st), (val)) +# define sk_ASN1_INTEGER_delete(st, i) SKM_sk_delete(ASN1_INTEGER, (st), (i)) +# define sk_ASN1_INTEGER_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_INTEGER, (st), (ptr)) +# define sk_ASN1_INTEGER_insert(st, val, i) SKM_sk_insert(ASN1_INTEGER, (st), (val), (i)) +# define sk_ASN1_INTEGER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_INTEGER, (st), (cmp)) +# define sk_ASN1_INTEGER_dup(st) SKM_sk_dup(ASN1_INTEGER, st) +# define sk_ASN1_INTEGER_pop_free(st, free_func) SKM_sk_pop_free(ASN1_INTEGER, (st), (free_func)) +# define sk_ASN1_INTEGER_shift(st) SKM_sk_shift(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_pop(st) SKM_sk_pop(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_sort(st) SKM_sk_sort(ASN1_INTEGER, (st)) +# define sk_ASN1_INTEGER_is_sorted(st) SKM_sk_is_sorted(ASN1_INTEGER, (st)) +# define sk_ASN1_OBJECT_new(cmp) SKM_sk_new(ASN1_OBJECT, (cmp)) +# define sk_ASN1_OBJECT_new_null() SKM_sk_new_null(ASN1_OBJECT) +# define sk_ASN1_OBJECT_free(st) SKM_sk_free(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_num(st) SKM_sk_num(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_value(st, i) SKM_sk_value(ASN1_OBJECT, (st), (i)) +# define sk_ASN1_OBJECT_set(st, i, val) SKM_sk_set(ASN1_OBJECT, (st), (i), (val)) +# define sk_ASN1_OBJECT_zero(st) SKM_sk_zero(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_push(st, val) SKM_sk_push(ASN1_OBJECT, (st), (val)) +# define sk_ASN1_OBJECT_unshift(st, val) SKM_sk_unshift(ASN1_OBJECT, (st), (val)) +# define sk_ASN1_OBJECT_find(st, val) SKM_sk_find(ASN1_OBJECT, (st), (val)) +# define sk_ASN1_OBJECT_find_ex(st, val) SKM_sk_find_ex(ASN1_OBJECT, (st), (val)) +# define sk_ASN1_OBJECT_delete(st, i) SKM_sk_delete(ASN1_OBJECT, (st), (i)) +# define sk_ASN1_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_OBJECT, (st), (ptr)) +# define sk_ASN1_OBJECT_insert(st, val, i) SKM_sk_insert(ASN1_OBJECT, (st), (val), (i)) +# define sk_ASN1_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_OBJECT, (st), (cmp)) +# define sk_ASN1_OBJECT_dup(st) SKM_sk_dup(ASN1_OBJECT, st) +# define sk_ASN1_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(ASN1_OBJECT, (st), (free_func)) +# define sk_ASN1_OBJECT_shift(st) SKM_sk_shift(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_pop(st) SKM_sk_pop(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_sort(st) SKM_sk_sort(ASN1_OBJECT, (st)) +# define sk_ASN1_OBJECT_is_sorted(st) SKM_sk_is_sorted(ASN1_OBJECT, (st)) +# define sk_ASN1_STRING_TABLE_new(cmp) SKM_sk_new(ASN1_STRING_TABLE, (cmp)) +# define sk_ASN1_STRING_TABLE_new_null() SKM_sk_new_null(ASN1_STRING_TABLE) +# define sk_ASN1_STRING_TABLE_free(st) SKM_sk_free(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_num(st) SKM_sk_num(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_value(st, i) SKM_sk_value(ASN1_STRING_TABLE, (st), (i)) +# define sk_ASN1_STRING_TABLE_set(st, i, val) SKM_sk_set(ASN1_STRING_TABLE, (st), (i), (val)) +# define sk_ASN1_STRING_TABLE_zero(st) SKM_sk_zero(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_push(st, val) SKM_sk_push(ASN1_STRING_TABLE, (st), (val)) +# define sk_ASN1_STRING_TABLE_unshift(st, val) SKM_sk_unshift(ASN1_STRING_TABLE, (st), (val)) +# define sk_ASN1_STRING_TABLE_find(st, val) SKM_sk_find(ASN1_STRING_TABLE, (st), (val)) +# define sk_ASN1_STRING_TABLE_find_ex(st, val) SKM_sk_find_ex(ASN1_STRING_TABLE, (st), (val)) +# define sk_ASN1_STRING_TABLE_delete(st, i) SKM_sk_delete(ASN1_STRING_TABLE, (st), (i)) +# define sk_ASN1_STRING_TABLE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_STRING_TABLE, (st), (ptr)) +# define sk_ASN1_STRING_TABLE_insert(st, val, i) SKM_sk_insert(ASN1_STRING_TABLE, (st), (val), (i)) +# define sk_ASN1_STRING_TABLE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_STRING_TABLE, (st), (cmp)) +# define sk_ASN1_STRING_TABLE_dup(st) SKM_sk_dup(ASN1_STRING_TABLE, st) +# define sk_ASN1_STRING_TABLE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_STRING_TABLE, (st), (free_func)) +# define sk_ASN1_STRING_TABLE_shift(st) SKM_sk_shift(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_pop(st) SKM_sk_pop(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_sort(st) SKM_sk_sort(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_STRING_TABLE_is_sorted(st) SKM_sk_is_sorted(ASN1_STRING_TABLE, (st)) +# define sk_ASN1_TYPE_new(cmp) SKM_sk_new(ASN1_TYPE, (cmp)) +# define sk_ASN1_TYPE_new_null() SKM_sk_new_null(ASN1_TYPE) +# define sk_ASN1_TYPE_free(st) SKM_sk_free(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_num(st) SKM_sk_num(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_value(st, i) SKM_sk_value(ASN1_TYPE, (st), (i)) +# define sk_ASN1_TYPE_set(st, i, val) SKM_sk_set(ASN1_TYPE, (st), (i), (val)) +# define sk_ASN1_TYPE_zero(st) SKM_sk_zero(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_push(st, val) SKM_sk_push(ASN1_TYPE, (st), (val)) +# define sk_ASN1_TYPE_unshift(st, val) SKM_sk_unshift(ASN1_TYPE, (st), (val)) +# define sk_ASN1_TYPE_find(st, val) SKM_sk_find(ASN1_TYPE, (st), (val)) +# define sk_ASN1_TYPE_find_ex(st, val) SKM_sk_find_ex(ASN1_TYPE, (st), (val)) +# define sk_ASN1_TYPE_delete(st, i) SKM_sk_delete(ASN1_TYPE, (st), (i)) +# define sk_ASN1_TYPE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_TYPE, (st), (ptr)) +# define sk_ASN1_TYPE_insert(st, val, i) SKM_sk_insert(ASN1_TYPE, (st), (val), (i)) +# define sk_ASN1_TYPE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_TYPE, (st), (cmp)) +# define sk_ASN1_TYPE_dup(st) SKM_sk_dup(ASN1_TYPE, st) +# define sk_ASN1_TYPE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_TYPE, (st), (free_func)) +# define sk_ASN1_TYPE_shift(st) SKM_sk_shift(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_pop(st) SKM_sk_pop(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_sort(st) SKM_sk_sort(ASN1_TYPE, (st)) +# define sk_ASN1_TYPE_is_sorted(st) SKM_sk_is_sorted(ASN1_TYPE, (st)) +# define sk_ASN1_UTF8STRING_new(cmp) SKM_sk_new(ASN1_UTF8STRING, (cmp)) +# define sk_ASN1_UTF8STRING_new_null() SKM_sk_new_null(ASN1_UTF8STRING) +# define sk_ASN1_UTF8STRING_free(st) SKM_sk_free(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_num(st) SKM_sk_num(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_value(st, i) SKM_sk_value(ASN1_UTF8STRING, (st), (i)) +# define sk_ASN1_UTF8STRING_set(st, i, val) SKM_sk_set(ASN1_UTF8STRING, (st), (i), (val)) +# define sk_ASN1_UTF8STRING_zero(st) SKM_sk_zero(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_push(st, val) SKM_sk_push(ASN1_UTF8STRING, (st), (val)) +# define sk_ASN1_UTF8STRING_unshift(st, val) SKM_sk_unshift(ASN1_UTF8STRING, (st), (val)) +# define sk_ASN1_UTF8STRING_find(st, val) SKM_sk_find(ASN1_UTF8STRING, (st), (val)) +# define sk_ASN1_UTF8STRING_find_ex(st, val) SKM_sk_find_ex(ASN1_UTF8STRING, (st), (val)) +# define sk_ASN1_UTF8STRING_delete(st, i) SKM_sk_delete(ASN1_UTF8STRING, (st), (i)) +# define sk_ASN1_UTF8STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_UTF8STRING, (st), (ptr)) +# define sk_ASN1_UTF8STRING_insert(st, val, i) SKM_sk_insert(ASN1_UTF8STRING, (st), (val), (i)) +# define sk_ASN1_UTF8STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_UTF8STRING, (st), (cmp)) +# define sk_ASN1_UTF8STRING_dup(st) SKM_sk_dup(ASN1_UTF8STRING, st) +# define sk_ASN1_UTF8STRING_pop_free(st, free_func) SKM_sk_pop_free(ASN1_UTF8STRING, (st), (free_func)) +# define sk_ASN1_UTF8STRING_shift(st) SKM_sk_shift(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_pop(st) SKM_sk_pop(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_sort(st) SKM_sk_sort(ASN1_UTF8STRING, (st)) +# define sk_ASN1_UTF8STRING_is_sorted(st) SKM_sk_is_sorted(ASN1_UTF8STRING, (st)) +# define sk_ASN1_VALUE_new(cmp) SKM_sk_new(ASN1_VALUE, (cmp)) +# define sk_ASN1_VALUE_new_null() SKM_sk_new_null(ASN1_VALUE) +# define sk_ASN1_VALUE_free(st) SKM_sk_free(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_num(st) SKM_sk_num(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_value(st, i) SKM_sk_value(ASN1_VALUE, (st), (i)) +# define sk_ASN1_VALUE_set(st, i, val) SKM_sk_set(ASN1_VALUE, (st), (i), (val)) +# define sk_ASN1_VALUE_zero(st) SKM_sk_zero(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_push(st, val) SKM_sk_push(ASN1_VALUE, (st), (val)) +# define sk_ASN1_VALUE_unshift(st, val) SKM_sk_unshift(ASN1_VALUE, (st), (val)) +# define sk_ASN1_VALUE_find(st, val) SKM_sk_find(ASN1_VALUE, (st), (val)) +# define sk_ASN1_VALUE_find_ex(st, val) SKM_sk_find_ex(ASN1_VALUE, (st), (val)) +# define sk_ASN1_VALUE_delete(st, i) SKM_sk_delete(ASN1_VALUE, (st), (i)) +# define sk_ASN1_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ASN1_VALUE, (st), (ptr)) +# define sk_ASN1_VALUE_insert(st, val, i) SKM_sk_insert(ASN1_VALUE, (st), (val), (i)) +# define sk_ASN1_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ASN1_VALUE, (st), (cmp)) +# define sk_ASN1_VALUE_dup(st) SKM_sk_dup(ASN1_VALUE, st) +# define sk_ASN1_VALUE_pop_free(st, free_func) SKM_sk_pop_free(ASN1_VALUE, (st), (free_func)) +# define sk_ASN1_VALUE_shift(st) SKM_sk_shift(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_pop(st) SKM_sk_pop(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_sort(st) SKM_sk_sort(ASN1_VALUE, (st)) +# define sk_ASN1_VALUE_is_sorted(st) SKM_sk_is_sorted(ASN1_VALUE, (st)) +# define sk_BIO_new(cmp) SKM_sk_new(BIO, (cmp)) +# define sk_BIO_new_null() SKM_sk_new_null(BIO) +# define sk_BIO_free(st) SKM_sk_free(BIO, (st)) +# define sk_BIO_num(st) SKM_sk_num(BIO, (st)) +# define sk_BIO_value(st, i) SKM_sk_value(BIO, (st), (i)) +# define sk_BIO_set(st, i, val) SKM_sk_set(BIO, (st), (i), (val)) +# define sk_BIO_zero(st) SKM_sk_zero(BIO, (st)) +# define sk_BIO_push(st, val) SKM_sk_push(BIO, (st), (val)) +# define sk_BIO_unshift(st, val) SKM_sk_unshift(BIO, (st), (val)) +# define sk_BIO_find(st, val) SKM_sk_find(BIO, (st), (val)) +# define sk_BIO_find_ex(st, val) SKM_sk_find_ex(BIO, (st), (val)) +# define sk_BIO_delete(st, i) SKM_sk_delete(BIO, (st), (i)) +# define sk_BIO_delete_ptr(st, ptr) SKM_sk_delete_ptr(BIO, (st), (ptr)) +# define sk_BIO_insert(st, val, i) SKM_sk_insert(BIO, (st), (val), (i)) +# define sk_BIO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BIO, (st), (cmp)) +# define sk_BIO_dup(st) SKM_sk_dup(BIO, st) +# define sk_BIO_pop_free(st, free_func) SKM_sk_pop_free(BIO, (st), (free_func)) +# define sk_BIO_shift(st) SKM_sk_shift(BIO, (st)) +# define sk_BIO_pop(st) SKM_sk_pop(BIO, (st)) +# define sk_BIO_sort(st) SKM_sk_sort(BIO, (st)) +# define sk_BIO_is_sorted(st) SKM_sk_is_sorted(BIO, (st)) +# define sk_BY_DIR_ENTRY_new(cmp) SKM_sk_new(BY_DIR_ENTRY, (cmp)) +# define sk_BY_DIR_ENTRY_new_null() SKM_sk_new_null(BY_DIR_ENTRY) +# define sk_BY_DIR_ENTRY_free(st) SKM_sk_free(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_num(st) SKM_sk_num(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_value(st, i) SKM_sk_value(BY_DIR_ENTRY, (st), (i)) +# define sk_BY_DIR_ENTRY_set(st, i, val) SKM_sk_set(BY_DIR_ENTRY, (st), (i), (val)) +# define sk_BY_DIR_ENTRY_zero(st) SKM_sk_zero(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_push(st, val) SKM_sk_push(BY_DIR_ENTRY, (st), (val)) +# define sk_BY_DIR_ENTRY_unshift(st, val) SKM_sk_unshift(BY_DIR_ENTRY, (st), (val)) +# define sk_BY_DIR_ENTRY_find(st, val) SKM_sk_find(BY_DIR_ENTRY, (st), (val)) +# define sk_BY_DIR_ENTRY_find_ex(st, val) SKM_sk_find_ex(BY_DIR_ENTRY, (st), (val)) +# define sk_BY_DIR_ENTRY_delete(st, i) SKM_sk_delete(BY_DIR_ENTRY, (st), (i)) +# define sk_BY_DIR_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_ENTRY, (st), (ptr)) +# define sk_BY_DIR_ENTRY_insert(st, val, i) SKM_sk_insert(BY_DIR_ENTRY, (st), (val), (i)) +# define sk_BY_DIR_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_ENTRY, (st), (cmp)) +# define sk_BY_DIR_ENTRY_dup(st) SKM_sk_dup(BY_DIR_ENTRY, st) +# define sk_BY_DIR_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_ENTRY, (st), (free_func)) +# define sk_BY_DIR_ENTRY_shift(st) SKM_sk_shift(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_pop(st) SKM_sk_pop(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_sort(st) SKM_sk_sort(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_ENTRY_is_sorted(st) SKM_sk_is_sorted(BY_DIR_ENTRY, (st)) +# define sk_BY_DIR_HASH_new(cmp) SKM_sk_new(BY_DIR_HASH, (cmp)) +# define sk_BY_DIR_HASH_new_null() SKM_sk_new_null(BY_DIR_HASH) +# define sk_BY_DIR_HASH_free(st) SKM_sk_free(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_num(st) SKM_sk_num(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_value(st, i) SKM_sk_value(BY_DIR_HASH, (st), (i)) +# define sk_BY_DIR_HASH_set(st, i, val) SKM_sk_set(BY_DIR_HASH, (st), (i), (val)) +# define sk_BY_DIR_HASH_zero(st) SKM_sk_zero(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_push(st, val) SKM_sk_push(BY_DIR_HASH, (st), (val)) +# define sk_BY_DIR_HASH_unshift(st, val) SKM_sk_unshift(BY_DIR_HASH, (st), (val)) +# define sk_BY_DIR_HASH_find(st, val) SKM_sk_find(BY_DIR_HASH, (st), (val)) +# define sk_BY_DIR_HASH_find_ex(st, val) SKM_sk_find_ex(BY_DIR_HASH, (st), (val)) +# define sk_BY_DIR_HASH_delete(st, i) SKM_sk_delete(BY_DIR_HASH, (st), (i)) +# define sk_BY_DIR_HASH_delete_ptr(st, ptr) SKM_sk_delete_ptr(BY_DIR_HASH, (st), (ptr)) +# define sk_BY_DIR_HASH_insert(st, val, i) SKM_sk_insert(BY_DIR_HASH, (st), (val), (i)) +# define sk_BY_DIR_HASH_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(BY_DIR_HASH, (st), (cmp)) +# define sk_BY_DIR_HASH_dup(st) SKM_sk_dup(BY_DIR_HASH, st) +# define sk_BY_DIR_HASH_pop_free(st, free_func) SKM_sk_pop_free(BY_DIR_HASH, (st), (free_func)) +# define sk_BY_DIR_HASH_shift(st) SKM_sk_shift(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_pop(st) SKM_sk_pop(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_sort(st) SKM_sk_sort(BY_DIR_HASH, (st)) +# define sk_BY_DIR_HASH_is_sorted(st) SKM_sk_is_sorted(BY_DIR_HASH, (st)) +# define sk_CMS_CertificateChoices_new(cmp) SKM_sk_new(CMS_CertificateChoices, (cmp)) +# define sk_CMS_CertificateChoices_new_null() SKM_sk_new_null(CMS_CertificateChoices) +# define sk_CMS_CertificateChoices_free(st) SKM_sk_free(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_num(st) SKM_sk_num(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_value(st, i) SKM_sk_value(CMS_CertificateChoices, (st), (i)) +# define sk_CMS_CertificateChoices_set(st, i, val) SKM_sk_set(CMS_CertificateChoices, (st), (i), (val)) +# define sk_CMS_CertificateChoices_zero(st) SKM_sk_zero(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_push(st, val) SKM_sk_push(CMS_CertificateChoices, (st), (val)) +# define sk_CMS_CertificateChoices_unshift(st, val) SKM_sk_unshift(CMS_CertificateChoices, (st), (val)) +# define sk_CMS_CertificateChoices_find(st, val) SKM_sk_find(CMS_CertificateChoices, (st), (val)) +# define sk_CMS_CertificateChoices_find_ex(st, val) SKM_sk_find_ex(CMS_CertificateChoices, (st), (val)) +# define sk_CMS_CertificateChoices_delete(st, i) SKM_sk_delete(CMS_CertificateChoices, (st), (i)) +# define sk_CMS_CertificateChoices_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_CertificateChoices, (st), (ptr)) +# define sk_CMS_CertificateChoices_insert(st, val, i) SKM_sk_insert(CMS_CertificateChoices, (st), (val), (i)) +# define sk_CMS_CertificateChoices_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_CertificateChoices, (st), (cmp)) +# define sk_CMS_CertificateChoices_dup(st) SKM_sk_dup(CMS_CertificateChoices, st) +# define sk_CMS_CertificateChoices_pop_free(st, free_func) SKM_sk_pop_free(CMS_CertificateChoices, (st), (free_func)) +# define sk_CMS_CertificateChoices_shift(st) SKM_sk_shift(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_pop(st) SKM_sk_pop(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_sort(st) SKM_sk_sort(CMS_CertificateChoices, (st)) +# define sk_CMS_CertificateChoices_is_sorted(st) SKM_sk_is_sorted(CMS_CertificateChoices, (st)) +# define sk_CMS_RecipientInfo_new(cmp) SKM_sk_new(CMS_RecipientInfo, (cmp)) +# define sk_CMS_RecipientInfo_new_null() SKM_sk_new_null(CMS_RecipientInfo) +# define sk_CMS_RecipientInfo_free(st) SKM_sk_free(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_num(st) SKM_sk_num(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_value(st, i) SKM_sk_value(CMS_RecipientInfo, (st), (i)) +# define sk_CMS_RecipientInfo_set(st, i, val) SKM_sk_set(CMS_RecipientInfo, (st), (i), (val)) +# define sk_CMS_RecipientInfo_zero(st) SKM_sk_zero(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_push(st, val) SKM_sk_push(CMS_RecipientInfo, (st), (val)) +# define sk_CMS_RecipientInfo_unshift(st, val) SKM_sk_unshift(CMS_RecipientInfo, (st), (val)) +# define sk_CMS_RecipientInfo_find(st, val) SKM_sk_find(CMS_RecipientInfo, (st), (val)) +# define sk_CMS_RecipientInfo_find_ex(st, val) SKM_sk_find_ex(CMS_RecipientInfo, (st), (val)) +# define sk_CMS_RecipientInfo_delete(st, i) SKM_sk_delete(CMS_RecipientInfo, (st), (i)) +# define sk_CMS_RecipientInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RecipientInfo, (st), (ptr)) +# define sk_CMS_RecipientInfo_insert(st, val, i) SKM_sk_insert(CMS_RecipientInfo, (st), (val), (i)) +# define sk_CMS_RecipientInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RecipientInfo, (st), (cmp)) +# define sk_CMS_RecipientInfo_dup(st) SKM_sk_dup(CMS_RecipientInfo, st) +# define sk_CMS_RecipientInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_RecipientInfo, (st), (free_func)) +# define sk_CMS_RecipientInfo_shift(st) SKM_sk_shift(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_pop(st) SKM_sk_pop(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_sort(st) SKM_sk_sort(CMS_RecipientInfo, (st)) +# define sk_CMS_RecipientInfo_is_sorted(st) SKM_sk_is_sorted(CMS_RecipientInfo, (st)) +# define sk_CMS_RevocationInfoChoice_new(cmp) SKM_sk_new(CMS_RevocationInfoChoice, (cmp)) +# define sk_CMS_RevocationInfoChoice_new_null() SKM_sk_new_null(CMS_RevocationInfoChoice) +# define sk_CMS_RevocationInfoChoice_free(st) SKM_sk_free(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_num(st) SKM_sk_num(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_value(st, i) SKM_sk_value(CMS_RevocationInfoChoice, (st), (i)) +# define sk_CMS_RevocationInfoChoice_set(st, i, val) SKM_sk_set(CMS_RevocationInfoChoice, (st), (i), (val)) +# define sk_CMS_RevocationInfoChoice_zero(st) SKM_sk_zero(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_push(st, val) SKM_sk_push(CMS_RevocationInfoChoice, (st), (val)) +# define sk_CMS_RevocationInfoChoice_unshift(st, val) SKM_sk_unshift(CMS_RevocationInfoChoice, (st), (val)) +# define sk_CMS_RevocationInfoChoice_find(st, val) SKM_sk_find(CMS_RevocationInfoChoice, (st), (val)) +# define sk_CMS_RevocationInfoChoice_find_ex(st, val) SKM_sk_find_ex(CMS_RevocationInfoChoice, (st), (val)) +# define sk_CMS_RevocationInfoChoice_delete(st, i) SKM_sk_delete(CMS_RevocationInfoChoice, (st), (i)) +# define sk_CMS_RevocationInfoChoice_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_RevocationInfoChoice, (st), (ptr)) +# define sk_CMS_RevocationInfoChoice_insert(st, val, i) SKM_sk_insert(CMS_RevocationInfoChoice, (st), (val), (i)) +# define sk_CMS_RevocationInfoChoice_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_RevocationInfoChoice, (st), (cmp)) +# define sk_CMS_RevocationInfoChoice_dup(st) SKM_sk_dup(CMS_RevocationInfoChoice, st) +# define sk_CMS_RevocationInfoChoice_pop_free(st, free_func) SKM_sk_pop_free(CMS_RevocationInfoChoice, (st), (free_func)) +# define sk_CMS_RevocationInfoChoice_shift(st) SKM_sk_shift(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_pop(st) SKM_sk_pop(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_sort(st) SKM_sk_sort(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_RevocationInfoChoice_is_sorted(st) SKM_sk_is_sorted(CMS_RevocationInfoChoice, (st)) +# define sk_CMS_SignerInfo_new(cmp) SKM_sk_new(CMS_SignerInfo, (cmp)) +# define sk_CMS_SignerInfo_new_null() SKM_sk_new_null(CMS_SignerInfo) +# define sk_CMS_SignerInfo_free(st) SKM_sk_free(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_num(st) SKM_sk_num(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_value(st, i) SKM_sk_value(CMS_SignerInfo, (st), (i)) +# define sk_CMS_SignerInfo_set(st, i, val) SKM_sk_set(CMS_SignerInfo, (st), (i), (val)) +# define sk_CMS_SignerInfo_zero(st) SKM_sk_zero(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_push(st, val) SKM_sk_push(CMS_SignerInfo, (st), (val)) +# define sk_CMS_SignerInfo_unshift(st, val) SKM_sk_unshift(CMS_SignerInfo, (st), (val)) +# define sk_CMS_SignerInfo_find(st, val) SKM_sk_find(CMS_SignerInfo, (st), (val)) +# define sk_CMS_SignerInfo_find_ex(st, val) SKM_sk_find_ex(CMS_SignerInfo, (st), (val)) +# define sk_CMS_SignerInfo_delete(st, i) SKM_sk_delete(CMS_SignerInfo, (st), (i)) +# define sk_CMS_SignerInfo_delete_ptr(st, ptr) SKM_sk_delete_ptr(CMS_SignerInfo, (st), (ptr)) +# define sk_CMS_SignerInfo_insert(st, val, i) SKM_sk_insert(CMS_SignerInfo, (st), (val), (i)) +# define sk_CMS_SignerInfo_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CMS_SignerInfo, (st), (cmp)) +# define sk_CMS_SignerInfo_dup(st) SKM_sk_dup(CMS_SignerInfo, st) +# define sk_CMS_SignerInfo_pop_free(st, free_func) SKM_sk_pop_free(CMS_SignerInfo, (st), (free_func)) +# define sk_CMS_SignerInfo_shift(st) SKM_sk_shift(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_pop(st) SKM_sk_pop(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_sort(st) SKM_sk_sort(CMS_SignerInfo, (st)) +# define sk_CMS_SignerInfo_is_sorted(st) SKM_sk_is_sorted(CMS_SignerInfo, (st)) +# define sk_CONF_IMODULE_new(cmp) SKM_sk_new(CONF_IMODULE, (cmp)) +# define sk_CONF_IMODULE_new_null() SKM_sk_new_null(CONF_IMODULE) +# define sk_CONF_IMODULE_free(st) SKM_sk_free(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_num(st) SKM_sk_num(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_value(st, i) SKM_sk_value(CONF_IMODULE, (st), (i)) +# define sk_CONF_IMODULE_set(st, i, val) SKM_sk_set(CONF_IMODULE, (st), (i), (val)) +# define sk_CONF_IMODULE_zero(st) SKM_sk_zero(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_push(st, val) SKM_sk_push(CONF_IMODULE, (st), (val)) +# define sk_CONF_IMODULE_unshift(st, val) SKM_sk_unshift(CONF_IMODULE, (st), (val)) +# define sk_CONF_IMODULE_find(st, val) SKM_sk_find(CONF_IMODULE, (st), (val)) +# define sk_CONF_IMODULE_find_ex(st, val) SKM_sk_find_ex(CONF_IMODULE, (st), (val)) +# define sk_CONF_IMODULE_delete(st, i) SKM_sk_delete(CONF_IMODULE, (st), (i)) +# define sk_CONF_IMODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_IMODULE, (st), (ptr)) +# define sk_CONF_IMODULE_insert(st, val, i) SKM_sk_insert(CONF_IMODULE, (st), (val), (i)) +# define sk_CONF_IMODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_IMODULE, (st), (cmp)) +# define sk_CONF_IMODULE_dup(st) SKM_sk_dup(CONF_IMODULE, st) +# define sk_CONF_IMODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_IMODULE, (st), (free_func)) +# define sk_CONF_IMODULE_shift(st) SKM_sk_shift(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_pop(st) SKM_sk_pop(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_sort(st) SKM_sk_sort(CONF_IMODULE, (st)) +# define sk_CONF_IMODULE_is_sorted(st) SKM_sk_is_sorted(CONF_IMODULE, (st)) +# define sk_CONF_MODULE_new(cmp) SKM_sk_new(CONF_MODULE, (cmp)) +# define sk_CONF_MODULE_new_null() SKM_sk_new_null(CONF_MODULE) +# define sk_CONF_MODULE_free(st) SKM_sk_free(CONF_MODULE, (st)) +# define sk_CONF_MODULE_num(st) SKM_sk_num(CONF_MODULE, (st)) +# define sk_CONF_MODULE_value(st, i) SKM_sk_value(CONF_MODULE, (st), (i)) +# define sk_CONF_MODULE_set(st, i, val) SKM_sk_set(CONF_MODULE, (st), (i), (val)) +# define sk_CONF_MODULE_zero(st) SKM_sk_zero(CONF_MODULE, (st)) +# define sk_CONF_MODULE_push(st, val) SKM_sk_push(CONF_MODULE, (st), (val)) +# define sk_CONF_MODULE_unshift(st, val) SKM_sk_unshift(CONF_MODULE, (st), (val)) +# define sk_CONF_MODULE_find(st, val) SKM_sk_find(CONF_MODULE, (st), (val)) +# define sk_CONF_MODULE_find_ex(st, val) SKM_sk_find_ex(CONF_MODULE, (st), (val)) +# define sk_CONF_MODULE_delete(st, i) SKM_sk_delete(CONF_MODULE, (st), (i)) +# define sk_CONF_MODULE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_MODULE, (st), (ptr)) +# define sk_CONF_MODULE_insert(st, val, i) SKM_sk_insert(CONF_MODULE, (st), (val), (i)) +# define sk_CONF_MODULE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_MODULE, (st), (cmp)) +# define sk_CONF_MODULE_dup(st) SKM_sk_dup(CONF_MODULE, st) +# define sk_CONF_MODULE_pop_free(st, free_func) SKM_sk_pop_free(CONF_MODULE, (st), (free_func)) +# define sk_CONF_MODULE_shift(st) SKM_sk_shift(CONF_MODULE, (st)) +# define sk_CONF_MODULE_pop(st) SKM_sk_pop(CONF_MODULE, (st)) +# define sk_CONF_MODULE_sort(st) SKM_sk_sort(CONF_MODULE, (st)) +# define sk_CONF_MODULE_is_sorted(st) SKM_sk_is_sorted(CONF_MODULE, (st)) +# define sk_CONF_VALUE_new(cmp) SKM_sk_new(CONF_VALUE, (cmp)) +# define sk_CONF_VALUE_new_null() SKM_sk_new_null(CONF_VALUE) +# define sk_CONF_VALUE_free(st) SKM_sk_free(CONF_VALUE, (st)) +# define sk_CONF_VALUE_num(st) SKM_sk_num(CONF_VALUE, (st)) +# define sk_CONF_VALUE_value(st, i) SKM_sk_value(CONF_VALUE, (st), (i)) +# define sk_CONF_VALUE_set(st, i, val) SKM_sk_set(CONF_VALUE, (st), (i), (val)) +# define sk_CONF_VALUE_zero(st) SKM_sk_zero(CONF_VALUE, (st)) +# define sk_CONF_VALUE_push(st, val) SKM_sk_push(CONF_VALUE, (st), (val)) +# define sk_CONF_VALUE_unshift(st, val) SKM_sk_unshift(CONF_VALUE, (st), (val)) +# define sk_CONF_VALUE_find(st, val) SKM_sk_find(CONF_VALUE, (st), (val)) +# define sk_CONF_VALUE_find_ex(st, val) SKM_sk_find_ex(CONF_VALUE, (st), (val)) +# define sk_CONF_VALUE_delete(st, i) SKM_sk_delete(CONF_VALUE, (st), (i)) +# define sk_CONF_VALUE_delete_ptr(st, ptr) SKM_sk_delete_ptr(CONF_VALUE, (st), (ptr)) +# define sk_CONF_VALUE_insert(st, val, i) SKM_sk_insert(CONF_VALUE, (st), (val), (i)) +# define sk_CONF_VALUE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CONF_VALUE, (st), (cmp)) +# define sk_CONF_VALUE_dup(st) SKM_sk_dup(CONF_VALUE, st) +# define sk_CONF_VALUE_pop_free(st, free_func) SKM_sk_pop_free(CONF_VALUE, (st), (free_func)) +# define sk_CONF_VALUE_shift(st) SKM_sk_shift(CONF_VALUE, (st)) +# define sk_CONF_VALUE_pop(st) SKM_sk_pop(CONF_VALUE, (st)) +# define sk_CONF_VALUE_sort(st) SKM_sk_sort(CONF_VALUE, (st)) +# define sk_CONF_VALUE_is_sorted(st) SKM_sk_is_sorted(CONF_VALUE, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_new(cmp) SKM_sk_new(CRYPTO_EX_DATA_FUNCS, (cmp)) +# define sk_CRYPTO_EX_DATA_FUNCS_new_null() SKM_sk_new_null(CRYPTO_EX_DATA_FUNCS) +# define sk_CRYPTO_EX_DATA_FUNCS_free(st) SKM_sk_free(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_num(st) SKM_sk_num(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_value(st, i) SKM_sk_value(CRYPTO_EX_DATA_FUNCS, (st), (i)) +# define sk_CRYPTO_EX_DATA_FUNCS_set(st, i, val) SKM_sk_set(CRYPTO_EX_DATA_FUNCS, (st), (i), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_zero(st) SKM_sk_zero(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_push(st, val) SKM_sk_push(CRYPTO_EX_DATA_FUNCS, (st), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_unshift(st, val) SKM_sk_unshift(CRYPTO_EX_DATA_FUNCS, (st), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_find(st, val) SKM_sk_find(CRYPTO_EX_DATA_FUNCS, (st), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_find_ex(st, val) SKM_sk_find_ex(CRYPTO_EX_DATA_FUNCS, (st), (val)) +# define sk_CRYPTO_EX_DATA_FUNCS_delete(st, i) SKM_sk_delete(CRYPTO_EX_DATA_FUNCS, (st), (i)) +# define sk_CRYPTO_EX_DATA_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_EX_DATA_FUNCS, (st), (ptr)) +# define sk_CRYPTO_EX_DATA_FUNCS_insert(st, val, i) SKM_sk_insert(CRYPTO_EX_DATA_FUNCS, (st), (val), (i)) +# define sk_CRYPTO_EX_DATA_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_EX_DATA_FUNCS, (st), (cmp)) +# define sk_CRYPTO_EX_DATA_FUNCS_dup(st) SKM_sk_dup(CRYPTO_EX_DATA_FUNCS, st) +# define sk_CRYPTO_EX_DATA_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_EX_DATA_FUNCS, (st), (free_func)) +# define sk_CRYPTO_EX_DATA_FUNCS_shift(st) SKM_sk_shift(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_pop(st) SKM_sk_pop(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_sort(st) SKM_sk_sort(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_EX_DATA_FUNCS_is_sorted(st) SKM_sk_is_sorted(CRYPTO_EX_DATA_FUNCS, (st)) +# define sk_CRYPTO_dynlock_new(cmp) SKM_sk_new(CRYPTO_dynlock, (cmp)) +# define sk_CRYPTO_dynlock_new_null() SKM_sk_new_null(CRYPTO_dynlock) +# define sk_CRYPTO_dynlock_free(st) SKM_sk_free(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_num(st) SKM_sk_num(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_value(st, i) SKM_sk_value(CRYPTO_dynlock, (st), (i)) +# define sk_CRYPTO_dynlock_set(st, i, val) SKM_sk_set(CRYPTO_dynlock, (st), (i), (val)) +# define sk_CRYPTO_dynlock_zero(st) SKM_sk_zero(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_push(st, val) SKM_sk_push(CRYPTO_dynlock, (st), (val)) +# define sk_CRYPTO_dynlock_unshift(st, val) SKM_sk_unshift(CRYPTO_dynlock, (st), (val)) +# define sk_CRYPTO_dynlock_find(st, val) SKM_sk_find(CRYPTO_dynlock, (st), (val)) +# define sk_CRYPTO_dynlock_find_ex(st, val) SKM_sk_find_ex(CRYPTO_dynlock, (st), (val)) +# define sk_CRYPTO_dynlock_delete(st, i) SKM_sk_delete(CRYPTO_dynlock, (st), (i)) +# define sk_CRYPTO_dynlock_delete_ptr(st, ptr) SKM_sk_delete_ptr(CRYPTO_dynlock, (st), (ptr)) +# define sk_CRYPTO_dynlock_insert(st, val, i) SKM_sk_insert(CRYPTO_dynlock, (st), (val), (i)) +# define sk_CRYPTO_dynlock_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(CRYPTO_dynlock, (st), (cmp)) +# define sk_CRYPTO_dynlock_dup(st) SKM_sk_dup(CRYPTO_dynlock, st) +# define sk_CRYPTO_dynlock_pop_free(st, free_func) SKM_sk_pop_free(CRYPTO_dynlock, (st), (free_func)) +# define sk_CRYPTO_dynlock_shift(st) SKM_sk_shift(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_pop(st) SKM_sk_pop(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_sort(st) SKM_sk_sort(CRYPTO_dynlock, (st)) +# define sk_CRYPTO_dynlock_is_sorted(st) SKM_sk_is_sorted(CRYPTO_dynlock, (st)) +# define sk_DIST_POINT_new(cmp) SKM_sk_new(DIST_POINT, (cmp)) +# define sk_DIST_POINT_new_null() SKM_sk_new_null(DIST_POINT) +# define sk_DIST_POINT_free(st) SKM_sk_free(DIST_POINT, (st)) +# define sk_DIST_POINT_num(st) SKM_sk_num(DIST_POINT, (st)) +# define sk_DIST_POINT_value(st, i) SKM_sk_value(DIST_POINT, (st), (i)) +# define sk_DIST_POINT_set(st, i, val) SKM_sk_set(DIST_POINT, (st), (i), (val)) +# define sk_DIST_POINT_zero(st) SKM_sk_zero(DIST_POINT, (st)) +# define sk_DIST_POINT_push(st, val) SKM_sk_push(DIST_POINT, (st), (val)) +# define sk_DIST_POINT_unshift(st, val) SKM_sk_unshift(DIST_POINT, (st), (val)) +# define sk_DIST_POINT_find(st, val) SKM_sk_find(DIST_POINT, (st), (val)) +# define sk_DIST_POINT_find_ex(st, val) SKM_sk_find_ex(DIST_POINT, (st), (val)) +# define sk_DIST_POINT_delete(st, i) SKM_sk_delete(DIST_POINT, (st), (i)) +# define sk_DIST_POINT_delete_ptr(st, ptr) SKM_sk_delete_ptr(DIST_POINT, (st), (ptr)) +# define sk_DIST_POINT_insert(st, val, i) SKM_sk_insert(DIST_POINT, (st), (val), (i)) +# define sk_DIST_POINT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(DIST_POINT, (st), (cmp)) +# define sk_DIST_POINT_dup(st) SKM_sk_dup(DIST_POINT, st) +# define sk_DIST_POINT_pop_free(st, free_func) SKM_sk_pop_free(DIST_POINT, (st), (free_func)) +# define sk_DIST_POINT_shift(st) SKM_sk_shift(DIST_POINT, (st)) +# define sk_DIST_POINT_pop(st) SKM_sk_pop(DIST_POINT, (st)) +# define sk_DIST_POINT_sort(st) SKM_sk_sort(DIST_POINT, (st)) +# define sk_DIST_POINT_is_sorted(st) SKM_sk_is_sorted(DIST_POINT, (st)) +# define sk_ENGINE_new(cmp) SKM_sk_new(ENGINE, (cmp)) +# define sk_ENGINE_new_null() SKM_sk_new_null(ENGINE) +# define sk_ENGINE_free(st) SKM_sk_free(ENGINE, (st)) +# define sk_ENGINE_num(st) SKM_sk_num(ENGINE, (st)) +# define sk_ENGINE_value(st, i) SKM_sk_value(ENGINE, (st), (i)) +# define sk_ENGINE_set(st, i, val) SKM_sk_set(ENGINE, (st), (i), (val)) +# define sk_ENGINE_zero(st) SKM_sk_zero(ENGINE, (st)) +# define sk_ENGINE_push(st, val) SKM_sk_push(ENGINE, (st), (val)) +# define sk_ENGINE_unshift(st, val) SKM_sk_unshift(ENGINE, (st), (val)) +# define sk_ENGINE_find(st, val) SKM_sk_find(ENGINE, (st), (val)) +# define sk_ENGINE_find_ex(st, val) SKM_sk_find_ex(ENGINE, (st), (val)) +# define sk_ENGINE_delete(st, i) SKM_sk_delete(ENGINE, (st), (i)) +# define sk_ENGINE_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE, (st), (ptr)) +# define sk_ENGINE_insert(st, val, i) SKM_sk_insert(ENGINE, (st), (val), (i)) +# define sk_ENGINE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE, (st), (cmp)) +# define sk_ENGINE_dup(st) SKM_sk_dup(ENGINE, st) +# define sk_ENGINE_pop_free(st, free_func) SKM_sk_pop_free(ENGINE, (st), (free_func)) +# define sk_ENGINE_shift(st) SKM_sk_shift(ENGINE, (st)) +# define sk_ENGINE_pop(st) SKM_sk_pop(ENGINE, (st)) +# define sk_ENGINE_sort(st) SKM_sk_sort(ENGINE, (st)) +# define sk_ENGINE_is_sorted(st) SKM_sk_is_sorted(ENGINE, (st)) +# define sk_ENGINE_CLEANUP_ITEM_new(cmp) SKM_sk_new(ENGINE_CLEANUP_ITEM, (cmp)) +# define sk_ENGINE_CLEANUP_ITEM_new_null() SKM_sk_new_null(ENGINE_CLEANUP_ITEM) +# define sk_ENGINE_CLEANUP_ITEM_free(st) SKM_sk_free(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_num(st) SKM_sk_num(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_value(st, i) SKM_sk_value(ENGINE_CLEANUP_ITEM, (st), (i)) +# define sk_ENGINE_CLEANUP_ITEM_set(st, i, val) SKM_sk_set(ENGINE_CLEANUP_ITEM, (st), (i), (val)) +# define sk_ENGINE_CLEANUP_ITEM_zero(st) SKM_sk_zero(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_push(st, val) SKM_sk_push(ENGINE_CLEANUP_ITEM, (st), (val)) +# define sk_ENGINE_CLEANUP_ITEM_unshift(st, val) SKM_sk_unshift(ENGINE_CLEANUP_ITEM, (st), (val)) +# define sk_ENGINE_CLEANUP_ITEM_find(st, val) SKM_sk_find(ENGINE_CLEANUP_ITEM, (st), (val)) +# define sk_ENGINE_CLEANUP_ITEM_find_ex(st, val) SKM_sk_find_ex(ENGINE_CLEANUP_ITEM, (st), (val)) +# define sk_ENGINE_CLEANUP_ITEM_delete(st, i) SKM_sk_delete(ENGINE_CLEANUP_ITEM, (st), (i)) +# define sk_ENGINE_CLEANUP_ITEM_delete_ptr(st, ptr) SKM_sk_delete_ptr(ENGINE_CLEANUP_ITEM, (st), (ptr)) +# define sk_ENGINE_CLEANUP_ITEM_insert(st, val, i) SKM_sk_insert(ENGINE_CLEANUP_ITEM, (st), (val), (i)) +# define sk_ENGINE_CLEANUP_ITEM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ENGINE_CLEANUP_ITEM, (st), (cmp)) +# define sk_ENGINE_CLEANUP_ITEM_dup(st) SKM_sk_dup(ENGINE_CLEANUP_ITEM, st) +# define sk_ENGINE_CLEANUP_ITEM_pop_free(st, free_func) SKM_sk_pop_free(ENGINE_CLEANUP_ITEM, (st), (free_func)) +# define sk_ENGINE_CLEANUP_ITEM_shift(st) SKM_sk_shift(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_pop(st) SKM_sk_pop(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_sort(st) SKM_sk_sort(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ENGINE_CLEANUP_ITEM_is_sorted(st) SKM_sk_is_sorted(ENGINE_CLEANUP_ITEM, (st)) +# define sk_ESS_CERT_ID_new(cmp) SKM_sk_new(ESS_CERT_ID, (cmp)) +# define sk_ESS_CERT_ID_new_null() SKM_sk_new_null(ESS_CERT_ID) +# define sk_ESS_CERT_ID_free(st) SKM_sk_free(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_num(st) SKM_sk_num(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_value(st, i) SKM_sk_value(ESS_CERT_ID, (st), (i)) +# define sk_ESS_CERT_ID_set(st, i, val) SKM_sk_set(ESS_CERT_ID, (st), (i), (val)) +# define sk_ESS_CERT_ID_zero(st) SKM_sk_zero(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_push(st, val) SKM_sk_push(ESS_CERT_ID, (st), (val)) +# define sk_ESS_CERT_ID_unshift(st, val) SKM_sk_unshift(ESS_CERT_ID, (st), (val)) +# define sk_ESS_CERT_ID_find(st, val) SKM_sk_find(ESS_CERT_ID, (st), (val)) +# define sk_ESS_CERT_ID_find_ex(st, val) SKM_sk_find_ex(ESS_CERT_ID, (st), (val)) +# define sk_ESS_CERT_ID_delete(st, i) SKM_sk_delete(ESS_CERT_ID, (st), (i)) +# define sk_ESS_CERT_ID_delete_ptr(st, ptr) SKM_sk_delete_ptr(ESS_CERT_ID, (st), (ptr)) +# define sk_ESS_CERT_ID_insert(st, val, i) SKM_sk_insert(ESS_CERT_ID, (st), (val), (i)) +# define sk_ESS_CERT_ID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(ESS_CERT_ID, (st), (cmp)) +# define sk_ESS_CERT_ID_dup(st) SKM_sk_dup(ESS_CERT_ID, st) +# define sk_ESS_CERT_ID_pop_free(st, free_func) SKM_sk_pop_free(ESS_CERT_ID, (st), (free_func)) +# define sk_ESS_CERT_ID_shift(st) SKM_sk_shift(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_pop(st) SKM_sk_pop(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_sort(st) SKM_sk_sort(ESS_CERT_ID, (st)) +# define sk_ESS_CERT_ID_is_sorted(st) SKM_sk_is_sorted(ESS_CERT_ID, (st)) +# define sk_EVP_MD_new(cmp) SKM_sk_new(EVP_MD, (cmp)) +# define sk_EVP_MD_new_null() SKM_sk_new_null(EVP_MD) +# define sk_EVP_MD_free(st) SKM_sk_free(EVP_MD, (st)) +# define sk_EVP_MD_num(st) SKM_sk_num(EVP_MD, (st)) +# define sk_EVP_MD_value(st, i) SKM_sk_value(EVP_MD, (st), (i)) +# define sk_EVP_MD_set(st, i, val) SKM_sk_set(EVP_MD, (st), (i), (val)) +# define sk_EVP_MD_zero(st) SKM_sk_zero(EVP_MD, (st)) +# define sk_EVP_MD_push(st, val) SKM_sk_push(EVP_MD, (st), (val)) +# define sk_EVP_MD_unshift(st, val) SKM_sk_unshift(EVP_MD, (st), (val)) +# define sk_EVP_MD_find(st, val) SKM_sk_find(EVP_MD, (st), (val)) +# define sk_EVP_MD_find_ex(st, val) SKM_sk_find_ex(EVP_MD, (st), (val)) +# define sk_EVP_MD_delete(st, i) SKM_sk_delete(EVP_MD, (st), (i)) +# define sk_EVP_MD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_MD, (st), (ptr)) +# define sk_EVP_MD_insert(st, val, i) SKM_sk_insert(EVP_MD, (st), (val), (i)) +# define sk_EVP_MD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_MD, (st), (cmp)) +# define sk_EVP_MD_dup(st) SKM_sk_dup(EVP_MD, st) +# define sk_EVP_MD_pop_free(st, free_func) SKM_sk_pop_free(EVP_MD, (st), (free_func)) +# define sk_EVP_MD_shift(st) SKM_sk_shift(EVP_MD, (st)) +# define sk_EVP_MD_pop(st) SKM_sk_pop(EVP_MD, (st)) +# define sk_EVP_MD_sort(st) SKM_sk_sort(EVP_MD, (st)) +# define sk_EVP_MD_is_sorted(st) SKM_sk_is_sorted(EVP_MD, (st)) +# define sk_EVP_PBE_CTL_new(cmp) SKM_sk_new(EVP_PBE_CTL, (cmp)) +# define sk_EVP_PBE_CTL_new_null() SKM_sk_new_null(EVP_PBE_CTL) +# define sk_EVP_PBE_CTL_free(st) SKM_sk_free(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_num(st) SKM_sk_num(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_value(st, i) SKM_sk_value(EVP_PBE_CTL, (st), (i)) +# define sk_EVP_PBE_CTL_set(st, i, val) SKM_sk_set(EVP_PBE_CTL, (st), (i), (val)) +# define sk_EVP_PBE_CTL_zero(st) SKM_sk_zero(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_push(st, val) SKM_sk_push(EVP_PBE_CTL, (st), (val)) +# define sk_EVP_PBE_CTL_unshift(st, val) SKM_sk_unshift(EVP_PBE_CTL, (st), (val)) +# define sk_EVP_PBE_CTL_find(st, val) SKM_sk_find(EVP_PBE_CTL, (st), (val)) +# define sk_EVP_PBE_CTL_find_ex(st, val) SKM_sk_find_ex(EVP_PBE_CTL, (st), (val)) +# define sk_EVP_PBE_CTL_delete(st, i) SKM_sk_delete(EVP_PBE_CTL, (st), (i)) +# define sk_EVP_PBE_CTL_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PBE_CTL, (st), (ptr)) +# define sk_EVP_PBE_CTL_insert(st, val, i) SKM_sk_insert(EVP_PBE_CTL, (st), (val), (i)) +# define sk_EVP_PBE_CTL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PBE_CTL, (st), (cmp)) +# define sk_EVP_PBE_CTL_dup(st) SKM_sk_dup(EVP_PBE_CTL, st) +# define sk_EVP_PBE_CTL_pop_free(st, free_func) SKM_sk_pop_free(EVP_PBE_CTL, (st), (free_func)) +# define sk_EVP_PBE_CTL_shift(st) SKM_sk_shift(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_pop(st) SKM_sk_pop(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_sort(st) SKM_sk_sort(EVP_PBE_CTL, (st)) +# define sk_EVP_PBE_CTL_is_sorted(st) SKM_sk_is_sorted(EVP_PBE_CTL, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_ASN1_METHOD, (cmp)) +# define sk_EVP_PKEY_ASN1_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_ASN1_METHOD) +# define sk_EVP_PKEY_ASN1_METHOD_free(st) SKM_sk_free(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_num(st) SKM_sk_num(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_ASN1_METHOD, (st), (i)) +# define sk_EVP_PKEY_ASN1_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_ASN1_METHOD, (st), (i), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_ASN1_METHOD, (st), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_ASN1_METHOD, (st), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_ASN1_METHOD, (st), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_ASN1_METHOD, (st), (val)) +# define sk_EVP_PKEY_ASN1_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_ASN1_METHOD, (st), (i)) +# define sk_EVP_PKEY_ASN1_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_ASN1_METHOD, (st), (ptr)) +# define sk_EVP_PKEY_ASN1_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_ASN1_METHOD, (st), (val), (i)) +# define sk_EVP_PKEY_ASN1_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_ASN1_METHOD, (st), (cmp)) +# define sk_EVP_PKEY_ASN1_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_ASN1_METHOD, st) +# define sk_EVP_PKEY_ASN1_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_ASN1_METHOD, (st), (free_func)) +# define sk_EVP_PKEY_ASN1_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_ASN1_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_ASN1_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_new(cmp) SKM_sk_new(EVP_PKEY_METHOD, (cmp)) +# define sk_EVP_PKEY_METHOD_new_null() SKM_sk_new_null(EVP_PKEY_METHOD) +# define sk_EVP_PKEY_METHOD_free(st) SKM_sk_free(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_num(st) SKM_sk_num(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_value(st, i) SKM_sk_value(EVP_PKEY_METHOD, (st), (i)) +# define sk_EVP_PKEY_METHOD_set(st, i, val) SKM_sk_set(EVP_PKEY_METHOD, (st), (i), (val)) +# define sk_EVP_PKEY_METHOD_zero(st) SKM_sk_zero(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_push(st, val) SKM_sk_push(EVP_PKEY_METHOD, (st), (val)) +# define sk_EVP_PKEY_METHOD_unshift(st, val) SKM_sk_unshift(EVP_PKEY_METHOD, (st), (val)) +# define sk_EVP_PKEY_METHOD_find(st, val) SKM_sk_find(EVP_PKEY_METHOD, (st), (val)) +# define sk_EVP_PKEY_METHOD_find_ex(st, val) SKM_sk_find_ex(EVP_PKEY_METHOD, (st), (val)) +# define sk_EVP_PKEY_METHOD_delete(st, i) SKM_sk_delete(EVP_PKEY_METHOD, (st), (i)) +# define sk_EVP_PKEY_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(EVP_PKEY_METHOD, (st), (ptr)) +# define sk_EVP_PKEY_METHOD_insert(st, val, i) SKM_sk_insert(EVP_PKEY_METHOD, (st), (val), (i)) +# define sk_EVP_PKEY_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(EVP_PKEY_METHOD, (st), (cmp)) +# define sk_EVP_PKEY_METHOD_dup(st) SKM_sk_dup(EVP_PKEY_METHOD, st) +# define sk_EVP_PKEY_METHOD_pop_free(st, free_func) SKM_sk_pop_free(EVP_PKEY_METHOD, (st), (free_func)) +# define sk_EVP_PKEY_METHOD_shift(st) SKM_sk_shift(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_pop(st) SKM_sk_pop(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_sort(st) SKM_sk_sort(EVP_PKEY_METHOD, (st)) +# define sk_EVP_PKEY_METHOD_is_sorted(st) SKM_sk_is_sorted(EVP_PKEY_METHOD, (st)) +# define sk_GENERAL_NAME_new(cmp) SKM_sk_new(GENERAL_NAME, (cmp)) +# define sk_GENERAL_NAME_new_null() SKM_sk_new_null(GENERAL_NAME) +# define sk_GENERAL_NAME_free(st) SKM_sk_free(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_num(st) SKM_sk_num(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_value(st, i) SKM_sk_value(GENERAL_NAME, (st), (i)) +# define sk_GENERAL_NAME_set(st, i, val) SKM_sk_set(GENERAL_NAME, (st), (i), (val)) +# define sk_GENERAL_NAME_zero(st) SKM_sk_zero(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_push(st, val) SKM_sk_push(GENERAL_NAME, (st), (val)) +# define sk_GENERAL_NAME_unshift(st, val) SKM_sk_unshift(GENERAL_NAME, (st), (val)) +# define sk_GENERAL_NAME_find(st, val) SKM_sk_find(GENERAL_NAME, (st), (val)) +# define sk_GENERAL_NAME_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAME, (st), (val)) +# define sk_GENERAL_NAME_delete(st, i) SKM_sk_delete(GENERAL_NAME, (st), (i)) +# define sk_GENERAL_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAME, (st), (ptr)) +# define sk_GENERAL_NAME_insert(st, val, i) SKM_sk_insert(GENERAL_NAME, (st), (val), (i)) +# define sk_GENERAL_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAME, (st), (cmp)) +# define sk_GENERAL_NAME_dup(st) SKM_sk_dup(GENERAL_NAME, st) +# define sk_GENERAL_NAME_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAME, (st), (free_func)) +# define sk_GENERAL_NAME_shift(st) SKM_sk_shift(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_pop(st) SKM_sk_pop(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_sort(st) SKM_sk_sort(GENERAL_NAME, (st)) +# define sk_GENERAL_NAME_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAME, (st)) +# define sk_GENERAL_NAMES_new(cmp) SKM_sk_new(GENERAL_NAMES, (cmp)) +# define sk_GENERAL_NAMES_new_null() SKM_sk_new_null(GENERAL_NAMES) +# define sk_GENERAL_NAMES_free(st) SKM_sk_free(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_num(st) SKM_sk_num(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_value(st, i) SKM_sk_value(GENERAL_NAMES, (st), (i)) +# define sk_GENERAL_NAMES_set(st, i, val) SKM_sk_set(GENERAL_NAMES, (st), (i), (val)) +# define sk_GENERAL_NAMES_zero(st) SKM_sk_zero(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_push(st, val) SKM_sk_push(GENERAL_NAMES, (st), (val)) +# define sk_GENERAL_NAMES_unshift(st, val) SKM_sk_unshift(GENERAL_NAMES, (st), (val)) +# define sk_GENERAL_NAMES_find(st, val) SKM_sk_find(GENERAL_NAMES, (st), (val)) +# define sk_GENERAL_NAMES_find_ex(st, val) SKM_sk_find_ex(GENERAL_NAMES, (st), (val)) +# define sk_GENERAL_NAMES_delete(st, i) SKM_sk_delete(GENERAL_NAMES, (st), (i)) +# define sk_GENERAL_NAMES_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_NAMES, (st), (ptr)) +# define sk_GENERAL_NAMES_insert(st, val, i) SKM_sk_insert(GENERAL_NAMES, (st), (val), (i)) +# define sk_GENERAL_NAMES_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_NAMES, (st), (cmp)) +# define sk_GENERAL_NAMES_dup(st) SKM_sk_dup(GENERAL_NAMES, st) +# define sk_GENERAL_NAMES_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_NAMES, (st), (free_func)) +# define sk_GENERAL_NAMES_shift(st) SKM_sk_shift(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_pop(st) SKM_sk_pop(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_sort(st) SKM_sk_sort(GENERAL_NAMES, (st)) +# define sk_GENERAL_NAMES_is_sorted(st) SKM_sk_is_sorted(GENERAL_NAMES, (st)) +# define sk_GENERAL_SUBTREE_new(cmp) SKM_sk_new(GENERAL_SUBTREE, (cmp)) +# define sk_GENERAL_SUBTREE_new_null() SKM_sk_new_null(GENERAL_SUBTREE) +# define sk_GENERAL_SUBTREE_free(st) SKM_sk_free(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_num(st) SKM_sk_num(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_value(st, i) SKM_sk_value(GENERAL_SUBTREE, (st), (i)) +# define sk_GENERAL_SUBTREE_set(st, i, val) SKM_sk_set(GENERAL_SUBTREE, (st), (i), (val)) +# define sk_GENERAL_SUBTREE_zero(st) SKM_sk_zero(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_push(st, val) SKM_sk_push(GENERAL_SUBTREE, (st), (val)) +# define sk_GENERAL_SUBTREE_unshift(st, val) SKM_sk_unshift(GENERAL_SUBTREE, (st), (val)) +# define sk_GENERAL_SUBTREE_find(st, val) SKM_sk_find(GENERAL_SUBTREE, (st), (val)) +# define sk_GENERAL_SUBTREE_find_ex(st, val) SKM_sk_find_ex(GENERAL_SUBTREE, (st), (val)) +# define sk_GENERAL_SUBTREE_delete(st, i) SKM_sk_delete(GENERAL_SUBTREE, (st), (i)) +# define sk_GENERAL_SUBTREE_delete_ptr(st, ptr) SKM_sk_delete_ptr(GENERAL_SUBTREE, (st), (ptr)) +# define sk_GENERAL_SUBTREE_insert(st, val, i) SKM_sk_insert(GENERAL_SUBTREE, (st), (val), (i)) +# define sk_GENERAL_SUBTREE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(GENERAL_SUBTREE, (st), (cmp)) +# define sk_GENERAL_SUBTREE_dup(st) SKM_sk_dup(GENERAL_SUBTREE, st) +# define sk_GENERAL_SUBTREE_pop_free(st, free_func) SKM_sk_pop_free(GENERAL_SUBTREE, (st), (free_func)) +# define sk_GENERAL_SUBTREE_shift(st) SKM_sk_shift(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_pop(st) SKM_sk_pop(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_sort(st) SKM_sk_sort(GENERAL_SUBTREE, (st)) +# define sk_GENERAL_SUBTREE_is_sorted(st) SKM_sk_is_sorted(GENERAL_SUBTREE, (st)) +# define sk_IPAddressFamily_new(cmp) SKM_sk_new(IPAddressFamily, (cmp)) +# define sk_IPAddressFamily_new_null() SKM_sk_new_null(IPAddressFamily) +# define sk_IPAddressFamily_free(st) SKM_sk_free(IPAddressFamily, (st)) +# define sk_IPAddressFamily_num(st) SKM_sk_num(IPAddressFamily, (st)) +# define sk_IPAddressFamily_value(st, i) SKM_sk_value(IPAddressFamily, (st), (i)) +# define sk_IPAddressFamily_set(st, i, val) SKM_sk_set(IPAddressFamily, (st), (i), (val)) +# define sk_IPAddressFamily_zero(st) SKM_sk_zero(IPAddressFamily, (st)) +# define sk_IPAddressFamily_push(st, val) SKM_sk_push(IPAddressFamily, (st), (val)) +# define sk_IPAddressFamily_unshift(st, val) SKM_sk_unshift(IPAddressFamily, (st), (val)) +# define sk_IPAddressFamily_find(st, val) SKM_sk_find(IPAddressFamily, (st), (val)) +# define sk_IPAddressFamily_find_ex(st, val) SKM_sk_find_ex(IPAddressFamily, (st), (val)) +# define sk_IPAddressFamily_delete(st, i) SKM_sk_delete(IPAddressFamily, (st), (i)) +# define sk_IPAddressFamily_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressFamily, (st), (ptr)) +# define sk_IPAddressFamily_insert(st, val, i) SKM_sk_insert(IPAddressFamily, (st), (val), (i)) +# define sk_IPAddressFamily_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressFamily, (st), (cmp)) +# define sk_IPAddressFamily_dup(st) SKM_sk_dup(IPAddressFamily, st) +# define sk_IPAddressFamily_pop_free(st, free_func) SKM_sk_pop_free(IPAddressFamily, (st), (free_func)) +# define sk_IPAddressFamily_shift(st) SKM_sk_shift(IPAddressFamily, (st)) +# define sk_IPAddressFamily_pop(st) SKM_sk_pop(IPAddressFamily, (st)) +# define sk_IPAddressFamily_sort(st) SKM_sk_sort(IPAddressFamily, (st)) +# define sk_IPAddressFamily_is_sorted(st) SKM_sk_is_sorted(IPAddressFamily, (st)) +# define sk_IPAddressOrRange_new(cmp) SKM_sk_new(IPAddressOrRange, (cmp)) +# define sk_IPAddressOrRange_new_null() SKM_sk_new_null(IPAddressOrRange) +# define sk_IPAddressOrRange_free(st) SKM_sk_free(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_num(st) SKM_sk_num(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_value(st, i) SKM_sk_value(IPAddressOrRange, (st), (i)) +# define sk_IPAddressOrRange_set(st, i, val) SKM_sk_set(IPAddressOrRange, (st), (i), (val)) +# define sk_IPAddressOrRange_zero(st) SKM_sk_zero(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_push(st, val) SKM_sk_push(IPAddressOrRange, (st), (val)) +# define sk_IPAddressOrRange_unshift(st, val) SKM_sk_unshift(IPAddressOrRange, (st), (val)) +# define sk_IPAddressOrRange_find(st, val) SKM_sk_find(IPAddressOrRange, (st), (val)) +# define sk_IPAddressOrRange_find_ex(st, val) SKM_sk_find_ex(IPAddressOrRange, (st), (val)) +# define sk_IPAddressOrRange_delete(st, i) SKM_sk_delete(IPAddressOrRange, (st), (i)) +# define sk_IPAddressOrRange_delete_ptr(st, ptr) SKM_sk_delete_ptr(IPAddressOrRange, (st), (ptr)) +# define sk_IPAddressOrRange_insert(st, val, i) SKM_sk_insert(IPAddressOrRange, (st), (val), (i)) +# define sk_IPAddressOrRange_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(IPAddressOrRange, (st), (cmp)) +# define sk_IPAddressOrRange_dup(st) SKM_sk_dup(IPAddressOrRange, st) +# define sk_IPAddressOrRange_pop_free(st, free_func) SKM_sk_pop_free(IPAddressOrRange, (st), (free_func)) +# define sk_IPAddressOrRange_shift(st) SKM_sk_shift(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_pop(st) SKM_sk_pop(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_sort(st) SKM_sk_sort(IPAddressOrRange, (st)) +# define sk_IPAddressOrRange_is_sorted(st) SKM_sk_is_sorted(IPAddressOrRange, (st)) +# define sk_KRB5_APREQBODY_new(cmp) SKM_sk_new(KRB5_APREQBODY, (cmp)) +# define sk_KRB5_APREQBODY_new_null() SKM_sk_new_null(KRB5_APREQBODY) +# define sk_KRB5_APREQBODY_free(st) SKM_sk_free(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_num(st) SKM_sk_num(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_value(st, i) SKM_sk_value(KRB5_APREQBODY, (st), (i)) +# define sk_KRB5_APREQBODY_set(st, i, val) SKM_sk_set(KRB5_APREQBODY, (st), (i), (val)) +# define sk_KRB5_APREQBODY_zero(st) SKM_sk_zero(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_push(st, val) SKM_sk_push(KRB5_APREQBODY, (st), (val)) +# define sk_KRB5_APREQBODY_unshift(st, val) SKM_sk_unshift(KRB5_APREQBODY, (st), (val)) +# define sk_KRB5_APREQBODY_find(st, val) SKM_sk_find(KRB5_APREQBODY, (st), (val)) +# define sk_KRB5_APREQBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_APREQBODY, (st), (val)) +# define sk_KRB5_APREQBODY_delete(st, i) SKM_sk_delete(KRB5_APREQBODY, (st), (i)) +# define sk_KRB5_APREQBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_APREQBODY, (st), (ptr)) +# define sk_KRB5_APREQBODY_insert(st, val, i) SKM_sk_insert(KRB5_APREQBODY, (st), (val), (i)) +# define sk_KRB5_APREQBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_APREQBODY, (st), (cmp)) +# define sk_KRB5_APREQBODY_dup(st) SKM_sk_dup(KRB5_APREQBODY, st) +# define sk_KRB5_APREQBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_APREQBODY, (st), (free_func)) +# define sk_KRB5_APREQBODY_shift(st) SKM_sk_shift(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_pop(st) SKM_sk_pop(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_sort(st) SKM_sk_sort(KRB5_APREQBODY, (st)) +# define sk_KRB5_APREQBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_APREQBODY, (st)) +# define sk_KRB5_AUTHDATA_new(cmp) SKM_sk_new(KRB5_AUTHDATA, (cmp)) +# define sk_KRB5_AUTHDATA_new_null() SKM_sk_new_null(KRB5_AUTHDATA) +# define sk_KRB5_AUTHDATA_free(st) SKM_sk_free(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_num(st) SKM_sk_num(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_value(st, i) SKM_sk_value(KRB5_AUTHDATA, (st), (i)) +# define sk_KRB5_AUTHDATA_set(st, i, val) SKM_sk_set(KRB5_AUTHDATA, (st), (i), (val)) +# define sk_KRB5_AUTHDATA_zero(st) SKM_sk_zero(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_push(st, val) SKM_sk_push(KRB5_AUTHDATA, (st), (val)) +# define sk_KRB5_AUTHDATA_unshift(st, val) SKM_sk_unshift(KRB5_AUTHDATA, (st), (val)) +# define sk_KRB5_AUTHDATA_find(st, val) SKM_sk_find(KRB5_AUTHDATA, (st), (val)) +# define sk_KRB5_AUTHDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHDATA, (st), (val)) +# define sk_KRB5_AUTHDATA_delete(st, i) SKM_sk_delete(KRB5_AUTHDATA, (st), (i)) +# define sk_KRB5_AUTHDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHDATA, (st), (ptr)) +# define sk_KRB5_AUTHDATA_insert(st, val, i) SKM_sk_insert(KRB5_AUTHDATA, (st), (val), (i)) +# define sk_KRB5_AUTHDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHDATA, (st), (cmp)) +# define sk_KRB5_AUTHDATA_dup(st) SKM_sk_dup(KRB5_AUTHDATA, st) +# define sk_KRB5_AUTHDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHDATA, (st), (free_func)) +# define sk_KRB5_AUTHDATA_shift(st) SKM_sk_shift(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_pop(st) SKM_sk_pop(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_sort(st) SKM_sk_sort(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHDATA, (st)) +# define sk_KRB5_AUTHENTBODY_new(cmp) SKM_sk_new(KRB5_AUTHENTBODY, (cmp)) +# define sk_KRB5_AUTHENTBODY_new_null() SKM_sk_new_null(KRB5_AUTHENTBODY) +# define sk_KRB5_AUTHENTBODY_free(st) SKM_sk_free(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_num(st) SKM_sk_num(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_value(st, i) SKM_sk_value(KRB5_AUTHENTBODY, (st), (i)) +# define sk_KRB5_AUTHENTBODY_set(st, i, val) SKM_sk_set(KRB5_AUTHENTBODY, (st), (i), (val)) +# define sk_KRB5_AUTHENTBODY_zero(st) SKM_sk_zero(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_push(st, val) SKM_sk_push(KRB5_AUTHENTBODY, (st), (val)) +# define sk_KRB5_AUTHENTBODY_unshift(st, val) SKM_sk_unshift(KRB5_AUTHENTBODY, (st), (val)) +# define sk_KRB5_AUTHENTBODY_find(st, val) SKM_sk_find(KRB5_AUTHENTBODY, (st), (val)) +# define sk_KRB5_AUTHENTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_AUTHENTBODY, (st), (val)) +# define sk_KRB5_AUTHENTBODY_delete(st, i) SKM_sk_delete(KRB5_AUTHENTBODY, (st), (i)) +# define sk_KRB5_AUTHENTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_AUTHENTBODY, (st), (ptr)) +# define sk_KRB5_AUTHENTBODY_insert(st, val, i) SKM_sk_insert(KRB5_AUTHENTBODY, (st), (val), (i)) +# define sk_KRB5_AUTHENTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_AUTHENTBODY, (st), (cmp)) +# define sk_KRB5_AUTHENTBODY_dup(st) SKM_sk_dup(KRB5_AUTHENTBODY, st) +# define sk_KRB5_AUTHENTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_AUTHENTBODY, (st), (free_func)) +# define sk_KRB5_AUTHENTBODY_shift(st) SKM_sk_shift(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_pop(st) SKM_sk_pop(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_sort(st) SKM_sk_sort(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_AUTHENTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_AUTHENTBODY, (st)) +# define sk_KRB5_CHECKSUM_new(cmp) SKM_sk_new(KRB5_CHECKSUM, (cmp)) +# define sk_KRB5_CHECKSUM_new_null() SKM_sk_new_null(KRB5_CHECKSUM) +# define sk_KRB5_CHECKSUM_free(st) SKM_sk_free(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_num(st) SKM_sk_num(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_value(st, i) SKM_sk_value(KRB5_CHECKSUM, (st), (i)) +# define sk_KRB5_CHECKSUM_set(st, i, val) SKM_sk_set(KRB5_CHECKSUM, (st), (i), (val)) +# define sk_KRB5_CHECKSUM_zero(st) SKM_sk_zero(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_push(st, val) SKM_sk_push(KRB5_CHECKSUM, (st), (val)) +# define sk_KRB5_CHECKSUM_unshift(st, val) SKM_sk_unshift(KRB5_CHECKSUM, (st), (val)) +# define sk_KRB5_CHECKSUM_find(st, val) SKM_sk_find(KRB5_CHECKSUM, (st), (val)) +# define sk_KRB5_CHECKSUM_find_ex(st, val) SKM_sk_find_ex(KRB5_CHECKSUM, (st), (val)) +# define sk_KRB5_CHECKSUM_delete(st, i) SKM_sk_delete(KRB5_CHECKSUM, (st), (i)) +# define sk_KRB5_CHECKSUM_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_CHECKSUM, (st), (ptr)) +# define sk_KRB5_CHECKSUM_insert(st, val, i) SKM_sk_insert(KRB5_CHECKSUM, (st), (val), (i)) +# define sk_KRB5_CHECKSUM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_CHECKSUM, (st), (cmp)) +# define sk_KRB5_CHECKSUM_dup(st) SKM_sk_dup(KRB5_CHECKSUM, st) +# define sk_KRB5_CHECKSUM_pop_free(st, free_func) SKM_sk_pop_free(KRB5_CHECKSUM, (st), (free_func)) +# define sk_KRB5_CHECKSUM_shift(st) SKM_sk_shift(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_pop(st) SKM_sk_pop(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_sort(st) SKM_sk_sort(KRB5_CHECKSUM, (st)) +# define sk_KRB5_CHECKSUM_is_sorted(st) SKM_sk_is_sorted(KRB5_CHECKSUM, (st)) +# define sk_KRB5_ENCDATA_new(cmp) SKM_sk_new(KRB5_ENCDATA, (cmp)) +# define sk_KRB5_ENCDATA_new_null() SKM_sk_new_null(KRB5_ENCDATA) +# define sk_KRB5_ENCDATA_free(st) SKM_sk_free(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_num(st) SKM_sk_num(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_value(st, i) SKM_sk_value(KRB5_ENCDATA, (st), (i)) +# define sk_KRB5_ENCDATA_set(st, i, val) SKM_sk_set(KRB5_ENCDATA, (st), (i), (val)) +# define sk_KRB5_ENCDATA_zero(st) SKM_sk_zero(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_push(st, val) SKM_sk_push(KRB5_ENCDATA, (st), (val)) +# define sk_KRB5_ENCDATA_unshift(st, val) SKM_sk_unshift(KRB5_ENCDATA, (st), (val)) +# define sk_KRB5_ENCDATA_find(st, val) SKM_sk_find(KRB5_ENCDATA, (st), (val)) +# define sk_KRB5_ENCDATA_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCDATA, (st), (val)) +# define sk_KRB5_ENCDATA_delete(st, i) SKM_sk_delete(KRB5_ENCDATA, (st), (i)) +# define sk_KRB5_ENCDATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCDATA, (st), (ptr)) +# define sk_KRB5_ENCDATA_insert(st, val, i) SKM_sk_insert(KRB5_ENCDATA, (st), (val), (i)) +# define sk_KRB5_ENCDATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCDATA, (st), (cmp)) +# define sk_KRB5_ENCDATA_dup(st) SKM_sk_dup(KRB5_ENCDATA, st) +# define sk_KRB5_ENCDATA_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCDATA, (st), (free_func)) +# define sk_KRB5_ENCDATA_shift(st) SKM_sk_shift(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_pop(st) SKM_sk_pop(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_sort(st) SKM_sk_sort(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCDATA_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCDATA, (st)) +# define sk_KRB5_ENCKEY_new(cmp) SKM_sk_new(KRB5_ENCKEY, (cmp)) +# define sk_KRB5_ENCKEY_new_null() SKM_sk_new_null(KRB5_ENCKEY) +# define sk_KRB5_ENCKEY_free(st) SKM_sk_free(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_num(st) SKM_sk_num(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_value(st, i) SKM_sk_value(KRB5_ENCKEY, (st), (i)) +# define sk_KRB5_ENCKEY_set(st, i, val) SKM_sk_set(KRB5_ENCKEY, (st), (i), (val)) +# define sk_KRB5_ENCKEY_zero(st) SKM_sk_zero(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_push(st, val) SKM_sk_push(KRB5_ENCKEY, (st), (val)) +# define sk_KRB5_ENCKEY_unshift(st, val) SKM_sk_unshift(KRB5_ENCKEY, (st), (val)) +# define sk_KRB5_ENCKEY_find(st, val) SKM_sk_find(KRB5_ENCKEY, (st), (val)) +# define sk_KRB5_ENCKEY_find_ex(st, val) SKM_sk_find_ex(KRB5_ENCKEY, (st), (val)) +# define sk_KRB5_ENCKEY_delete(st, i) SKM_sk_delete(KRB5_ENCKEY, (st), (i)) +# define sk_KRB5_ENCKEY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_ENCKEY, (st), (ptr)) +# define sk_KRB5_ENCKEY_insert(st, val, i) SKM_sk_insert(KRB5_ENCKEY, (st), (val), (i)) +# define sk_KRB5_ENCKEY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_ENCKEY, (st), (cmp)) +# define sk_KRB5_ENCKEY_dup(st) SKM_sk_dup(KRB5_ENCKEY, st) +# define sk_KRB5_ENCKEY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_ENCKEY, (st), (free_func)) +# define sk_KRB5_ENCKEY_shift(st) SKM_sk_shift(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_pop(st) SKM_sk_pop(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_sort(st) SKM_sk_sort(KRB5_ENCKEY, (st)) +# define sk_KRB5_ENCKEY_is_sorted(st) SKM_sk_is_sorted(KRB5_ENCKEY, (st)) +# define sk_KRB5_PRINCNAME_new(cmp) SKM_sk_new(KRB5_PRINCNAME, (cmp)) +# define sk_KRB5_PRINCNAME_new_null() SKM_sk_new_null(KRB5_PRINCNAME) +# define sk_KRB5_PRINCNAME_free(st) SKM_sk_free(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_num(st) SKM_sk_num(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_value(st, i) SKM_sk_value(KRB5_PRINCNAME, (st), (i)) +# define sk_KRB5_PRINCNAME_set(st, i, val) SKM_sk_set(KRB5_PRINCNAME, (st), (i), (val)) +# define sk_KRB5_PRINCNAME_zero(st) SKM_sk_zero(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_push(st, val) SKM_sk_push(KRB5_PRINCNAME, (st), (val)) +# define sk_KRB5_PRINCNAME_unshift(st, val) SKM_sk_unshift(KRB5_PRINCNAME, (st), (val)) +# define sk_KRB5_PRINCNAME_find(st, val) SKM_sk_find(KRB5_PRINCNAME, (st), (val)) +# define sk_KRB5_PRINCNAME_find_ex(st, val) SKM_sk_find_ex(KRB5_PRINCNAME, (st), (val)) +# define sk_KRB5_PRINCNAME_delete(st, i) SKM_sk_delete(KRB5_PRINCNAME, (st), (i)) +# define sk_KRB5_PRINCNAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_PRINCNAME, (st), (ptr)) +# define sk_KRB5_PRINCNAME_insert(st, val, i) SKM_sk_insert(KRB5_PRINCNAME, (st), (val), (i)) +# define sk_KRB5_PRINCNAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_PRINCNAME, (st), (cmp)) +# define sk_KRB5_PRINCNAME_dup(st) SKM_sk_dup(KRB5_PRINCNAME, st) +# define sk_KRB5_PRINCNAME_pop_free(st, free_func) SKM_sk_pop_free(KRB5_PRINCNAME, (st), (free_func)) +# define sk_KRB5_PRINCNAME_shift(st) SKM_sk_shift(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_pop(st) SKM_sk_pop(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_sort(st) SKM_sk_sort(KRB5_PRINCNAME, (st)) +# define sk_KRB5_PRINCNAME_is_sorted(st) SKM_sk_is_sorted(KRB5_PRINCNAME, (st)) +# define sk_KRB5_TKTBODY_new(cmp) SKM_sk_new(KRB5_TKTBODY, (cmp)) +# define sk_KRB5_TKTBODY_new_null() SKM_sk_new_null(KRB5_TKTBODY) +# define sk_KRB5_TKTBODY_free(st) SKM_sk_free(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_num(st) SKM_sk_num(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_value(st, i) SKM_sk_value(KRB5_TKTBODY, (st), (i)) +# define sk_KRB5_TKTBODY_set(st, i, val) SKM_sk_set(KRB5_TKTBODY, (st), (i), (val)) +# define sk_KRB5_TKTBODY_zero(st) SKM_sk_zero(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_push(st, val) SKM_sk_push(KRB5_TKTBODY, (st), (val)) +# define sk_KRB5_TKTBODY_unshift(st, val) SKM_sk_unshift(KRB5_TKTBODY, (st), (val)) +# define sk_KRB5_TKTBODY_find(st, val) SKM_sk_find(KRB5_TKTBODY, (st), (val)) +# define sk_KRB5_TKTBODY_find_ex(st, val) SKM_sk_find_ex(KRB5_TKTBODY, (st), (val)) +# define sk_KRB5_TKTBODY_delete(st, i) SKM_sk_delete(KRB5_TKTBODY, (st), (i)) +# define sk_KRB5_TKTBODY_delete_ptr(st, ptr) SKM_sk_delete_ptr(KRB5_TKTBODY, (st), (ptr)) +# define sk_KRB5_TKTBODY_insert(st, val, i) SKM_sk_insert(KRB5_TKTBODY, (st), (val), (i)) +# define sk_KRB5_TKTBODY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(KRB5_TKTBODY, (st), (cmp)) +# define sk_KRB5_TKTBODY_dup(st) SKM_sk_dup(KRB5_TKTBODY, st) +# define sk_KRB5_TKTBODY_pop_free(st, free_func) SKM_sk_pop_free(KRB5_TKTBODY, (st), (free_func)) +# define sk_KRB5_TKTBODY_shift(st) SKM_sk_shift(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_pop(st) SKM_sk_pop(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_sort(st) SKM_sk_sort(KRB5_TKTBODY, (st)) +# define sk_KRB5_TKTBODY_is_sorted(st) SKM_sk_is_sorted(KRB5_TKTBODY, (st)) +# define sk_MEM_OBJECT_DATA_new(cmp) SKM_sk_new(MEM_OBJECT_DATA, (cmp)) +# define sk_MEM_OBJECT_DATA_new_null() SKM_sk_new_null(MEM_OBJECT_DATA) +# define sk_MEM_OBJECT_DATA_free(st) SKM_sk_free(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_num(st) SKM_sk_num(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_value(st, i) SKM_sk_value(MEM_OBJECT_DATA, (st), (i)) +# define sk_MEM_OBJECT_DATA_set(st, i, val) SKM_sk_set(MEM_OBJECT_DATA, (st), (i), (val)) +# define sk_MEM_OBJECT_DATA_zero(st) SKM_sk_zero(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_push(st, val) SKM_sk_push(MEM_OBJECT_DATA, (st), (val)) +# define sk_MEM_OBJECT_DATA_unshift(st, val) SKM_sk_unshift(MEM_OBJECT_DATA, (st), (val)) +# define sk_MEM_OBJECT_DATA_find(st, val) SKM_sk_find(MEM_OBJECT_DATA, (st), (val)) +# define sk_MEM_OBJECT_DATA_find_ex(st, val) SKM_sk_find_ex(MEM_OBJECT_DATA, (st), (val)) +# define sk_MEM_OBJECT_DATA_delete(st, i) SKM_sk_delete(MEM_OBJECT_DATA, (st), (i)) +# define sk_MEM_OBJECT_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(MEM_OBJECT_DATA, (st), (ptr)) +# define sk_MEM_OBJECT_DATA_insert(st, val, i) SKM_sk_insert(MEM_OBJECT_DATA, (st), (val), (i)) +# define sk_MEM_OBJECT_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MEM_OBJECT_DATA, (st), (cmp)) +# define sk_MEM_OBJECT_DATA_dup(st) SKM_sk_dup(MEM_OBJECT_DATA, st) +# define sk_MEM_OBJECT_DATA_pop_free(st, free_func) SKM_sk_pop_free(MEM_OBJECT_DATA, (st), (free_func)) +# define sk_MEM_OBJECT_DATA_shift(st) SKM_sk_shift(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_pop(st) SKM_sk_pop(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_sort(st) SKM_sk_sort(MEM_OBJECT_DATA, (st)) +# define sk_MEM_OBJECT_DATA_is_sorted(st) SKM_sk_is_sorted(MEM_OBJECT_DATA, (st)) +# define sk_MIME_HEADER_new(cmp) SKM_sk_new(MIME_HEADER, (cmp)) +# define sk_MIME_HEADER_new_null() SKM_sk_new_null(MIME_HEADER) +# define sk_MIME_HEADER_free(st) SKM_sk_free(MIME_HEADER, (st)) +# define sk_MIME_HEADER_num(st) SKM_sk_num(MIME_HEADER, (st)) +# define sk_MIME_HEADER_value(st, i) SKM_sk_value(MIME_HEADER, (st), (i)) +# define sk_MIME_HEADER_set(st, i, val) SKM_sk_set(MIME_HEADER, (st), (i), (val)) +# define sk_MIME_HEADER_zero(st) SKM_sk_zero(MIME_HEADER, (st)) +# define sk_MIME_HEADER_push(st, val) SKM_sk_push(MIME_HEADER, (st), (val)) +# define sk_MIME_HEADER_unshift(st, val) SKM_sk_unshift(MIME_HEADER, (st), (val)) +# define sk_MIME_HEADER_find(st, val) SKM_sk_find(MIME_HEADER, (st), (val)) +# define sk_MIME_HEADER_find_ex(st, val) SKM_sk_find_ex(MIME_HEADER, (st), (val)) +# define sk_MIME_HEADER_delete(st, i) SKM_sk_delete(MIME_HEADER, (st), (i)) +# define sk_MIME_HEADER_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_HEADER, (st), (ptr)) +# define sk_MIME_HEADER_insert(st, val, i) SKM_sk_insert(MIME_HEADER, (st), (val), (i)) +# define sk_MIME_HEADER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_HEADER, (st), (cmp)) +# define sk_MIME_HEADER_dup(st) SKM_sk_dup(MIME_HEADER, st) +# define sk_MIME_HEADER_pop_free(st, free_func) SKM_sk_pop_free(MIME_HEADER, (st), (free_func)) +# define sk_MIME_HEADER_shift(st) SKM_sk_shift(MIME_HEADER, (st)) +# define sk_MIME_HEADER_pop(st) SKM_sk_pop(MIME_HEADER, (st)) +# define sk_MIME_HEADER_sort(st) SKM_sk_sort(MIME_HEADER, (st)) +# define sk_MIME_HEADER_is_sorted(st) SKM_sk_is_sorted(MIME_HEADER, (st)) +# define sk_MIME_PARAM_new(cmp) SKM_sk_new(MIME_PARAM, (cmp)) +# define sk_MIME_PARAM_new_null() SKM_sk_new_null(MIME_PARAM) +# define sk_MIME_PARAM_free(st) SKM_sk_free(MIME_PARAM, (st)) +# define sk_MIME_PARAM_num(st) SKM_sk_num(MIME_PARAM, (st)) +# define sk_MIME_PARAM_value(st, i) SKM_sk_value(MIME_PARAM, (st), (i)) +# define sk_MIME_PARAM_set(st, i, val) SKM_sk_set(MIME_PARAM, (st), (i), (val)) +# define sk_MIME_PARAM_zero(st) SKM_sk_zero(MIME_PARAM, (st)) +# define sk_MIME_PARAM_push(st, val) SKM_sk_push(MIME_PARAM, (st), (val)) +# define sk_MIME_PARAM_unshift(st, val) SKM_sk_unshift(MIME_PARAM, (st), (val)) +# define sk_MIME_PARAM_find(st, val) SKM_sk_find(MIME_PARAM, (st), (val)) +# define sk_MIME_PARAM_find_ex(st, val) SKM_sk_find_ex(MIME_PARAM, (st), (val)) +# define sk_MIME_PARAM_delete(st, i) SKM_sk_delete(MIME_PARAM, (st), (i)) +# define sk_MIME_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(MIME_PARAM, (st), (ptr)) +# define sk_MIME_PARAM_insert(st, val, i) SKM_sk_insert(MIME_PARAM, (st), (val), (i)) +# define sk_MIME_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(MIME_PARAM, (st), (cmp)) +# define sk_MIME_PARAM_dup(st) SKM_sk_dup(MIME_PARAM, st) +# define sk_MIME_PARAM_pop_free(st, free_func) SKM_sk_pop_free(MIME_PARAM, (st), (free_func)) +# define sk_MIME_PARAM_shift(st) SKM_sk_shift(MIME_PARAM, (st)) +# define sk_MIME_PARAM_pop(st) SKM_sk_pop(MIME_PARAM, (st)) +# define sk_MIME_PARAM_sort(st) SKM_sk_sort(MIME_PARAM, (st)) +# define sk_MIME_PARAM_is_sorted(st) SKM_sk_is_sorted(MIME_PARAM, (st)) +# define sk_NAME_FUNCS_new(cmp) SKM_sk_new(NAME_FUNCS, (cmp)) +# define sk_NAME_FUNCS_new_null() SKM_sk_new_null(NAME_FUNCS) +# define sk_NAME_FUNCS_free(st) SKM_sk_free(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_num(st) SKM_sk_num(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_value(st, i) SKM_sk_value(NAME_FUNCS, (st), (i)) +# define sk_NAME_FUNCS_set(st, i, val) SKM_sk_set(NAME_FUNCS, (st), (i), (val)) +# define sk_NAME_FUNCS_zero(st) SKM_sk_zero(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_push(st, val) SKM_sk_push(NAME_FUNCS, (st), (val)) +# define sk_NAME_FUNCS_unshift(st, val) SKM_sk_unshift(NAME_FUNCS, (st), (val)) +# define sk_NAME_FUNCS_find(st, val) SKM_sk_find(NAME_FUNCS, (st), (val)) +# define sk_NAME_FUNCS_find_ex(st, val) SKM_sk_find_ex(NAME_FUNCS, (st), (val)) +# define sk_NAME_FUNCS_delete(st, i) SKM_sk_delete(NAME_FUNCS, (st), (i)) +# define sk_NAME_FUNCS_delete_ptr(st, ptr) SKM_sk_delete_ptr(NAME_FUNCS, (st), (ptr)) +# define sk_NAME_FUNCS_insert(st, val, i) SKM_sk_insert(NAME_FUNCS, (st), (val), (i)) +# define sk_NAME_FUNCS_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(NAME_FUNCS, (st), (cmp)) +# define sk_NAME_FUNCS_dup(st) SKM_sk_dup(NAME_FUNCS, st) +# define sk_NAME_FUNCS_pop_free(st, free_func) SKM_sk_pop_free(NAME_FUNCS, (st), (free_func)) +# define sk_NAME_FUNCS_shift(st) SKM_sk_shift(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_pop(st) SKM_sk_pop(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_sort(st) SKM_sk_sort(NAME_FUNCS, (st)) +# define sk_NAME_FUNCS_is_sorted(st) SKM_sk_is_sorted(NAME_FUNCS, (st)) +# define sk_OCSP_CERTID_new(cmp) SKM_sk_new(OCSP_CERTID, (cmp)) +# define sk_OCSP_CERTID_new_null() SKM_sk_new_null(OCSP_CERTID) +# define sk_OCSP_CERTID_free(st) SKM_sk_free(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_num(st) SKM_sk_num(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_value(st, i) SKM_sk_value(OCSP_CERTID, (st), (i)) +# define sk_OCSP_CERTID_set(st, i, val) SKM_sk_set(OCSP_CERTID, (st), (i), (val)) +# define sk_OCSP_CERTID_zero(st) SKM_sk_zero(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_push(st, val) SKM_sk_push(OCSP_CERTID, (st), (val)) +# define sk_OCSP_CERTID_unshift(st, val) SKM_sk_unshift(OCSP_CERTID, (st), (val)) +# define sk_OCSP_CERTID_find(st, val) SKM_sk_find(OCSP_CERTID, (st), (val)) +# define sk_OCSP_CERTID_find_ex(st, val) SKM_sk_find_ex(OCSP_CERTID, (st), (val)) +# define sk_OCSP_CERTID_delete(st, i) SKM_sk_delete(OCSP_CERTID, (st), (i)) +# define sk_OCSP_CERTID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_CERTID, (st), (ptr)) +# define sk_OCSP_CERTID_insert(st, val, i) SKM_sk_insert(OCSP_CERTID, (st), (val), (i)) +# define sk_OCSP_CERTID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_CERTID, (st), (cmp)) +# define sk_OCSP_CERTID_dup(st) SKM_sk_dup(OCSP_CERTID, st) +# define sk_OCSP_CERTID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_CERTID, (st), (free_func)) +# define sk_OCSP_CERTID_shift(st) SKM_sk_shift(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_pop(st) SKM_sk_pop(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_sort(st) SKM_sk_sort(OCSP_CERTID, (st)) +# define sk_OCSP_CERTID_is_sorted(st) SKM_sk_is_sorted(OCSP_CERTID, (st)) +# define sk_OCSP_ONEREQ_new(cmp) SKM_sk_new(OCSP_ONEREQ, (cmp)) +# define sk_OCSP_ONEREQ_new_null() SKM_sk_new_null(OCSP_ONEREQ) +# define sk_OCSP_ONEREQ_free(st) SKM_sk_free(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_num(st) SKM_sk_num(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_value(st, i) SKM_sk_value(OCSP_ONEREQ, (st), (i)) +# define sk_OCSP_ONEREQ_set(st, i, val) SKM_sk_set(OCSP_ONEREQ, (st), (i), (val)) +# define sk_OCSP_ONEREQ_zero(st) SKM_sk_zero(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_push(st, val) SKM_sk_push(OCSP_ONEREQ, (st), (val)) +# define sk_OCSP_ONEREQ_unshift(st, val) SKM_sk_unshift(OCSP_ONEREQ, (st), (val)) +# define sk_OCSP_ONEREQ_find(st, val) SKM_sk_find(OCSP_ONEREQ, (st), (val)) +# define sk_OCSP_ONEREQ_find_ex(st, val) SKM_sk_find_ex(OCSP_ONEREQ, (st), (val)) +# define sk_OCSP_ONEREQ_delete(st, i) SKM_sk_delete(OCSP_ONEREQ, (st), (i)) +# define sk_OCSP_ONEREQ_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_ONEREQ, (st), (ptr)) +# define sk_OCSP_ONEREQ_insert(st, val, i) SKM_sk_insert(OCSP_ONEREQ, (st), (val), (i)) +# define sk_OCSP_ONEREQ_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_ONEREQ, (st), (cmp)) +# define sk_OCSP_ONEREQ_dup(st) SKM_sk_dup(OCSP_ONEREQ, st) +# define sk_OCSP_ONEREQ_pop_free(st, free_func) SKM_sk_pop_free(OCSP_ONEREQ, (st), (free_func)) +# define sk_OCSP_ONEREQ_shift(st) SKM_sk_shift(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_pop(st) SKM_sk_pop(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_sort(st) SKM_sk_sort(OCSP_ONEREQ, (st)) +# define sk_OCSP_ONEREQ_is_sorted(st) SKM_sk_is_sorted(OCSP_ONEREQ, (st)) +# define sk_OCSP_RESPID_new(cmp) SKM_sk_new(OCSP_RESPID, (cmp)) +# define sk_OCSP_RESPID_new_null() SKM_sk_new_null(OCSP_RESPID) +# define sk_OCSP_RESPID_free(st) SKM_sk_free(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_num(st) SKM_sk_num(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_value(st, i) SKM_sk_value(OCSP_RESPID, (st), (i)) +# define sk_OCSP_RESPID_set(st, i, val) SKM_sk_set(OCSP_RESPID, (st), (i), (val)) +# define sk_OCSP_RESPID_zero(st) SKM_sk_zero(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_push(st, val) SKM_sk_push(OCSP_RESPID, (st), (val)) +# define sk_OCSP_RESPID_unshift(st, val) SKM_sk_unshift(OCSP_RESPID, (st), (val)) +# define sk_OCSP_RESPID_find(st, val) SKM_sk_find(OCSP_RESPID, (st), (val)) +# define sk_OCSP_RESPID_find_ex(st, val) SKM_sk_find_ex(OCSP_RESPID, (st), (val)) +# define sk_OCSP_RESPID_delete(st, i) SKM_sk_delete(OCSP_RESPID, (st), (i)) +# define sk_OCSP_RESPID_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_RESPID, (st), (ptr)) +# define sk_OCSP_RESPID_insert(st, val, i) SKM_sk_insert(OCSP_RESPID, (st), (val), (i)) +# define sk_OCSP_RESPID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_RESPID, (st), (cmp)) +# define sk_OCSP_RESPID_dup(st) SKM_sk_dup(OCSP_RESPID, st) +# define sk_OCSP_RESPID_pop_free(st, free_func) SKM_sk_pop_free(OCSP_RESPID, (st), (free_func)) +# define sk_OCSP_RESPID_shift(st) SKM_sk_shift(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_pop(st) SKM_sk_pop(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_sort(st) SKM_sk_sort(OCSP_RESPID, (st)) +# define sk_OCSP_RESPID_is_sorted(st) SKM_sk_is_sorted(OCSP_RESPID, (st)) +# define sk_OCSP_SINGLERESP_new(cmp) SKM_sk_new(OCSP_SINGLERESP, (cmp)) +# define sk_OCSP_SINGLERESP_new_null() SKM_sk_new_null(OCSP_SINGLERESP) +# define sk_OCSP_SINGLERESP_free(st) SKM_sk_free(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_num(st) SKM_sk_num(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_value(st, i) SKM_sk_value(OCSP_SINGLERESP, (st), (i)) +# define sk_OCSP_SINGLERESP_set(st, i, val) SKM_sk_set(OCSP_SINGLERESP, (st), (i), (val)) +# define sk_OCSP_SINGLERESP_zero(st) SKM_sk_zero(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_push(st, val) SKM_sk_push(OCSP_SINGLERESP, (st), (val)) +# define sk_OCSP_SINGLERESP_unshift(st, val) SKM_sk_unshift(OCSP_SINGLERESP, (st), (val)) +# define sk_OCSP_SINGLERESP_find(st, val) SKM_sk_find(OCSP_SINGLERESP, (st), (val)) +# define sk_OCSP_SINGLERESP_find_ex(st, val) SKM_sk_find_ex(OCSP_SINGLERESP, (st), (val)) +# define sk_OCSP_SINGLERESP_delete(st, i) SKM_sk_delete(OCSP_SINGLERESP, (st), (i)) +# define sk_OCSP_SINGLERESP_delete_ptr(st, ptr) SKM_sk_delete_ptr(OCSP_SINGLERESP, (st), (ptr)) +# define sk_OCSP_SINGLERESP_insert(st, val, i) SKM_sk_insert(OCSP_SINGLERESP, (st), (val), (i)) +# define sk_OCSP_SINGLERESP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(OCSP_SINGLERESP, (st), (cmp)) +# define sk_OCSP_SINGLERESP_dup(st) SKM_sk_dup(OCSP_SINGLERESP, st) +# define sk_OCSP_SINGLERESP_pop_free(st, free_func) SKM_sk_pop_free(OCSP_SINGLERESP, (st), (free_func)) +# define sk_OCSP_SINGLERESP_shift(st) SKM_sk_shift(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_pop(st) SKM_sk_pop(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_sort(st) SKM_sk_sort(OCSP_SINGLERESP, (st)) +# define sk_OCSP_SINGLERESP_is_sorted(st) SKM_sk_is_sorted(OCSP_SINGLERESP, (st)) +# define sk_PKCS12_SAFEBAG_new(cmp) SKM_sk_new(PKCS12_SAFEBAG, (cmp)) +# define sk_PKCS12_SAFEBAG_new_null() SKM_sk_new_null(PKCS12_SAFEBAG) +# define sk_PKCS12_SAFEBAG_free(st) SKM_sk_free(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_num(st) SKM_sk_num(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_value(st, i) SKM_sk_value(PKCS12_SAFEBAG, (st), (i)) +# define sk_PKCS12_SAFEBAG_set(st, i, val) SKM_sk_set(PKCS12_SAFEBAG, (st), (i), (val)) +# define sk_PKCS12_SAFEBAG_zero(st) SKM_sk_zero(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_push(st, val) SKM_sk_push(PKCS12_SAFEBAG, (st), (val)) +# define sk_PKCS12_SAFEBAG_unshift(st, val) SKM_sk_unshift(PKCS12_SAFEBAG, (st), (val)) +# define sk_PKCS12_SAFEBAG_find(st, val) SKM_sk_find(PKCS12_SAFEBAG, (st), (val)) +# define sk_PKCS12_SAFEBAG_find_ex(st, val) SKM_sk_find_ex(PKCS12_SAFEBAG, (st), (val)) +# define sk_PKCS12_SAFEBAG_delete(st, i) SKM_sk_delete(PKCS12_SAFEBAG, (st), (i)) +# define sk_PKCS12_SAFEBAG_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS12_SAFEBAG, (st), (ptr)) +# define sk_PKCS12_SAFEBAG_insert(st, val, i) SKM_sk_insert(PKCS12_SAFEBAG, (st), (val), (i)) +# define sk_PKCS12_SAFEBAG_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS12_SAFEBAG, (st), (cmp)) +# define sk_PKCS12_SAFEBAG_dup(st) SKM_sk_dup(PKCS12_SAFEBAG, st) +# define sk_PKCS12_SAFEBAG_pop_free(st, free_func) SKM_sk_pop_free(PKCS12_SAFEBAG, (st), (free_func)) +# define sk_PKCS12_SAFEBAG_shift(st) SKM_sk_shift(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_pop(st) SKM_sk_pop(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_sort(st) SKM_sk_sort(PKCS12_SAFEBAG, (st)) +# define sk_PKCS12_SAFEBAG_is_sorted(st) SKM_sk_is_sorted(PKCS12_SAFEBAG, (st)) +# define sk_PKCS7_new(cmp) SKM_sk_new(PKCS7, (cmp)) +# define sk_PKCS7_new_null() SKM_sk_new_null(PKCS7) +# define sk_PKCS7_free(st) SKM_sk_free(PKCS7, (st)) +# define sk_PKCS7_num(st) SKM_sk_num(PKCS7, (st)) +# define sk_PKCS7_value(st, i) SKM_sk_value(PKCS7, (st), (i)) +# define sk_PKCS7_set(st, i, val) SKM_sk_set(PKCS7, (st), (i), (val)) +# define sk_PKCS7_zero(st) SKM_sk_zero(PKCS7, (st)) +# define sk_PKCS7_push(st, val) SKM_sk_push(PKCS7, (st), (val)) +# define sk_PKCS7_unshift(st, val) SKM_sk_unshift(PKCS7, (st), (val)) +# define sk_PKCS7_find(st, val) SKM_sk_find(PKCS7, (st), (val)) +# define sk_PKCS7_find_ex(st, val) SKM_sk_find_ex(PKCS7, (st), (val)) +# define sk_PKCS7_delete(st, i) SKM_sk_delete(PKCS7, (st), (i)) +# define sk_PKCS7_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7, (st), (ptr)) +# define sk_PKCS7_insert(st, val, i) SKM_sk_insert(PKCS7, (st), (val), (i)) +# define sk_PKCS7_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7, (st), (cmp)) +# define sk_PKCS7_dup(st) SKM_sk_dup(PKCS7, st) +# define sk_PKCS7_pop_free(st, free_func) SKM_sk_pop_free(PKCS7, (st), (free_func)) +# define sk_PKCS7_shift(st) SKM_sk_shift(PKCS7, (st)) +# define sk_PKCS7_pop(st) SKM_sk_pop(PKCS7, (st)) +# define sk_PKCS7_sort(st) SKM_sk_sort(PKCS7, (st)) +# define sk_PKCS7_is_sorted(st) SKM_sk_is_sorted(PKCS7, (st)) +# define sk_PKCS7_RECIP_INFO_new(cmp) SKM_sk_new(PKCS7_RECIP_INFO, (cmp)) +# define sk_PKCS7_RECIP_INFO_new_null() SKM_sk_new_null(PKCS7_RECIP_INFO) +# define sk_PKCS7_RECIP_INFO_free(st) SKM_sk_free(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_num(st) SKM_sk_num(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_value(st, i) SKM_sk_value(PKCS7_RECIP_INFO, (st), (i)) +# define sk_PKCS7_RECIP_INFO_set(st, i, val) SKM_sk_set(PKCS7_RECIP_INFO, (st), (i), (val)) +# define sk_PKCS7_RECIP_INFO_zero(st) SKM_sk_zero(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_push(st, val) SKM_sk_push(PKCS7_RECIP_INFO, (st), (val)) +# define sk_PKCS7_RECIP_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_RECIP_INFO, (st), (val)) +# define sk_PKCS7_RECIP_INFO_find(st, val) SKM_sk_find(PKCS7_RECIP_INFO, (st), (val)) +# define sk_PKCS7_RECIP_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_RECIP_INFO, (st), (val)) +# define sk_PKCS7_RECIP_INFO_delete(st, i) SKM_sk_delete(PKCS7_RECIP_INFO, (st), (i)) +# define sk_PKCS7_RECIP_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_RECIP_INFO, (st), (ptr)) +# define sk_PKCS7_RECIP_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_RECIP_INFO, (st), (val), (i)) +# define sk_PKCS7_RECIP_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_RECIP_INFO, (st), (cmp)) +# define sk_PKCS7_RECIP_INFO_dup(st) SKM_sk_dup(PKCS7_RECIP_INFO, st) +# define sk_PKCS7_RECIP_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_RECIP_INFO, (st), (free_func)) +# define sk_PKCS7_RECIP_INFO_shift(st) SKM_sk_shift(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_pop(st) SKM_sk_pop(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_sort(st) SKM_sk_sort(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_RECIP_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_RECIP_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_new(cmp) SKM_sk_new(PKCS7_SIGNER_INFO, (cmp)) +# define sk_PKCS7_SIGNER_INFO_new_null() SKM_sk_new_null(PKCS7_SIGNER_INFO) +# define sk_PKCS7_SIGNER_INFO_free(st) SKM_sk_free(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_num(st) SKM_sk_num(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_value(st, i) SKM_sk_value(PKCS7_SIGNER_INFO, (st), (i)) +# define sk_PKCS7_SIGNER_INFO_set(st, i, val) SKM_sk_set(PKCS7_SIGNER_INFO, (st), (i), (val)) +# define sk_PKCS7_SIGNER_INFO_zero(st) SKM_sk_zero(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_push(st, val) SKM_sk_push(PKCS7_SIGNER_INFO, (st), (val)) +# define sk_PKCS7_SIGNER_INFO_unshift(st, val) SKM_sk_unshift(PKCS7_SIGNER_INFO, (st), (val)) +# define sk_PKCS7_SIGNER_INFO_find(st, val) SKM_sk_find(PKCS7_SIGNER_INFO, (st), (val)) +# define sk_PKCS7_SIGNER_INFO_find_ex(st, val) SKM_sk_find_ex(PKCS7_SIGNER_INFO, (st), (val)) +# define sk_PKCS7_SIGNER_INFO_delete(st, i) SKM_sk_delete(PKCS7_SIGNER_INFO, (st), (i)) +# define sk_PKCS7_SIGNER_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(PKCS7_SIGNER_INFO, (st), (ptr)) +# define sk_PKCS7_SIGNER_INFO_insert(st, val, i) SKM_sk_insert(PKCS7_SIGNER_INFO, (st), (val), (i)) +# define sk_PKCS7_SIGNER_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(PKCS7_SIGNER_INFO, (st), (cmp)) +# define sk_PKCS7_SIGNER_INFO_dup(st) SKM_sk_dup(PKCS7_SIGNER_INFO, st) +# define sk_PKCS7_SIGNER_INFO_pop_free(st, free_func) SKM_sk_pop_free(PKCS7_SIGNER_INFO, (st), (free_func)) +# define sk_PKCS7_SIGNER_INFO_shift(st) SKM_sk_shift(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_pop(st) SKM_sk_pop(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_sort(st) SKM_sk_sort(PKCS7_SIGNER_INFO, (st)) +# define sk_PKCS7_SIGNER_INFO_is_sorted(st) SKM_sk_is_sorted(PKCS7_SIGNER_INFO, (st)) +# define sk_POLICYINFO_new(cmp) SKM_sk_new(POLICYINFO, (cmp)) +# define sk_POLICYINFO_new_null() SKM_sk_new_null(POLICYINFO) +# define sk_POLICYINFO_free(st) SKM_sk_free(POLICYINFO, (st)) +# define sk_POLICYINFO_num(st) SKM_sk_num(POLICYINFO, (st)) +# define sk_POLICYINFO_value(st, i) SKM_sk_value(POLICYINFO, (st), (i)) +# define sk_POLICYINFO_set(st, i, val) SKM_sk_set(POLICYINFO, (st), (i), (val)) +# define sk_POLICYINFO_zero(st) SKM_sk_zero(POLICYINFO, (st)) +# define sk_POLICYINFO_push(st, val) SKM_sk_push(POLICYINFO, (st), (val)) +# define sk_POLICYINFO_unshift(st, val) SKM_sk_unshift(POLICYINFO, (st), (val)) +# define sk_POLICYINFO_find(st, val) SKM_sk_find(POLICYINFO, (st), (val)) +# define sk_POLICYINFO_find_ex(st, val) SKM_sk_find_ex(POLICYINFO, (st), (val)) +# define sk_POLICYINFO_delete(st, i) SKM_sk_delete(POLICYINFO, (st), (i)) +# define sk_POLICYINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYINFO, (st), (ptr)) +# define sk_POLICYINFO_insert(st, val, i) SKM_sk_insert(POLICYINFO, (st), (val), (i)) +# define sk_POLICYINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYINFO, (st), (cmp)) +# define sk_POLICYINFO_dup(st) SKM_sk_dup(POLICYINFO, st) +# define sk_POLICYINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYINFO, (st), (free_func)) +# define sk_POLICYINFO_shift(st) SKM_sk_shift(POLICYINFO, (st)) +# define sk_POLICYINFO_pop(st) SKM_sk_pop(POLICYINFO, (st)) +# define sk_POLICYINFO_sort(st) SKM_sk_sort(POLICYINFO, (st)) +# define sk_POLICYINFO_is_sorted(st) SKM_sk_is_sorted(POLICYINFO, (st)) +# define sk_POLICYQUALINFO_new(cmp) SKM_sk_new(POLICYQUALINFO, (cmp)) +# define sk_POLICYQUALINFO_new_null() SKM_sk_new_null(POLICYQUALINFO) +# define sk_POLICYQUALINFO_free(st) SKM_sk_free(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_num(st) SKM_sk_num(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_value(st, i) SKM_sk_value(POLICYQUALINFO, (st), (i)) +# define sk_POLICYQUALINFO_set(st, i, val) SKM_sk_set(POLICYQUALINFO, (st), (i), (val)) +# define sk_POLICYQUALINFO_zero(st) SKM_sk_zero(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_push(st, val) SKM_sk_push(POLICYQUALINFO, (st), (val)) +# define sk_POLICYQUALINFO_unshift(st, val) SKM_sk_unshift(POLICYQUALINFO, (st), (val)) +# define sk_POLICYQUALINFO_find(st, val) SKM_sk_find(POLICYQUALINFO, (st), (val)) +# define sk_POLICYQUALINFO_find_ex(st, val) SKM_sk_find_ex(POLICYQUALINFO, (st), (val)) +# define sk_POLICYQUALINFO_delete(st, i) SKM_sk_delete(POLICYQUALINFO, (st), (i)) +# define sk_POLICYQUALINFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICYQUALINFO, (st), (ptr)) +# define sk_POLICYQUALINFO_insert(st, val, i) SKM_sk_insert(POLICYQUALINFO, (st), (val), (i)) +# define sk_POLICYQUALINFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICYQUALINFO, (st), (cmp)) +# define sk_POLICYQUALINFO_dup(st) SKM_sk_dup(POLICYQUALINFO, st) +# define sk_POLICYQUALINFO_pop_free(st, free_func) SKM_sk_pop_free(POLICYQUALINFO, (st), (free_func)) +# define sk_POLICYQUALINFO_shift(st) SKM_sk_shift(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_pop(st) SKM_sk_pop(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_sort(st) SKM_sk_sort(POLICYQUALINFO, (st)) +# define sk_POLICYQUALINFO_is_sorted(st) SKM_sk_is_sorted(POLICYQUALINFO, (st)) +# define sk_POLICY_MAPPING_new(cmp) SKM_sk_new(POLICY_MAPPING, (cmp)) +# define sk_POLICY_MAPPING_new_null() SKM_sk_new_null(POLICY_MAPPING) +# define sk_POLICY_MAPPING_free(st) SKM_sk_free(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_num(st) SKM_sk_num(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_value(st, i) SKM_sk_value(POLICY_MAPPING, (st), (i)) +# define sk_POLICY_MAPPING_set(st, i, val) SKM_sk_set(POLICY_MAPPING, (st), (i), (val)) +# define sk_POLICY_MAPPING_zero(st) SKM_sk_zero(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_push(st, val) SKM_sk_push(POLICY_MAPPING, (st), (val)) +# define sk_POLICY_MAPPING_unshift(st, val) SKM_sk_unshift(POLICY_MAPPING, (st), (val)) +# define sk_POLICY_MAPPING_find(st, val) SKM_sk_find(POLICY_MAPPING, (st), (val)) +# define sk_POLICY_MAPPING_find_ex(st, val) SKM_sk_find_ex(POLICY_MAPPING, (st), (val)) +# define sk_POLICY_MAPPING_delete(st, i) SKM_sk_delete(POLICY_MAPPING, (st), (i)) +# define sk_POLICY_MAPPING_delete_ptr(st, ptr) SKM_sk_delete_ptr(POLICY_MAPPING, (st), (ptr)) +# define sk_POLICY_MAPPING_insert(st, val, i) SKM_sk_insert(POLICY_MAPPING, (st), (val), (i)) +# define sk_POLICY_MAPPING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(POLICY_MAPPING, (st), (cmp)) +# define sk_POLICY_MAPPING_dup(st) SKM_sk_dup(POLICY_MAPPING, st) +# define sk_POLICY_MAPPING_pop_free(st, free_func) SKM_sk_pop_free(POLICY_MAPPING, (st), (free_func)) +# define sk_POLICY_MAPPING_shift(st) SKM_sk_shift(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_pop(st) SKM_sk_pop(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_sort(st) SKM_sk_sort(POLICY_MAPPING, (st)) +# define sk_POLICY_MAPPING_is_sorted(st) SKM_sk_is_sorted(POLICY_MAPPING, (st)) +# define sk_SRP_gN_new(cmp) SKM_sk_new(SRP_gN, (cmp)) +# define sk_SRP_gN_new_null() SKM_sk_new_null(SRP_gN) +# define sk_SRP_gN_free(st) SKM_sk_free(SRP_gN, (st)) +# define sk_SRP_gN_num(st) SKM_sk_num(SRP_gN, (st)) +# define sk_SRP_gN_value(st, i) SKM_sk_value(SRP_gN, (st), (i)) +# define sk_SRP_gN_set(st, i, val) SKM_sk_set(SRP_gN, (st), (i), (val)) +# define sk_SRP_gN_zero(st) SKM_sk_zero(SRP_gN, (st)) +# define sk_SRP_gN_push(st, val) SKM_sk_push(SRP_gN, (st), (val)) +# define sk_SRP_gN_unshift(st, val) SKM_sk_unshift(SRP_gN, (st), (val)) +# define sk_SRP_gN_find(st, val) SKM_sk_find(SRP_gN, (st), (val)) +# define sk_SRP_gN_find_ex(st, val) SKM_sk_find_ex(SRP_gN, (st), (val)) +# define sk_SRP_gN_delete(st, i) SKM_sk_delete(SRP_gN, (st), (i)) +# define sk_SRP_gN_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN, (st), (ptr)) +# define sk_SRP_gN_insert(st, val, i) SKM_sk_insert(SRP_gN, (st), (val), (i)) +# define sk_SRP_gN_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN, (st), (cmp)) +# define sk_SRP_gN_dup(st) SKM_sk_dup(SRP_gN, st) +# define sk_SRP_gN_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN, (st), (free_func)) +# define sk_SRP_gN_shift(st) SKM_sk_shift(SRP_gN, (st)) +# define sk_SRP_gN_pop(st) SKM_sk_pop(SRP_gN, (st)) +# define sk_SRP_gN_sort(st) SKM_sk_sort(SRP_gN, (st)) +# define sk_SRP_gN_is_sorted(st) SKM_sk_is_sorted(SRP_gN, (st)) +# define sk_SRP_gN_cache_new(cmp) SKM_sk_new(SRP_gN_cache, (cmp)) +# define sk_SRP_gN_cache_new_null() SKM_sk_new_null(SRP_gN_cache) +# define sk_SRP_gN_cache_free(st) SKM_sk_free(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_num(st) SKM_sk_num(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_value(st, i) SKM_sk_value(SRP_gN_cache, (st), (i)) +# define sk_SRP_gN_cache_set(st, i, val) SKM_sk_set(SRP_gN_cache, (st), (i), (val)) +# define sk_SRP_gN_cache_zero(st) SKM_sk_zero(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_push(st, val) SKM_sk_push(SRP_gN_cache, (st), (val)) +# define sk_SRP_gN_cache_unshift(st, val) SKM_sk_unshift(SRP_gN_cache, (st), (val)) +# define sk_SRP_gN_cache_find(st, val) SKM_sk_find(SRP_gN_cache, (st), (val)) +# define sk_SRP_gN_cache_find_ex(st, val) SKM_sk_find_ex(SRP_gN_cache, (st), (val)) +# define sk_SRP_gN_cache_delete(st, i) SKM_sk_delete(SRP_gN_cache, (st), (i)) +# define sk_SRP_gN_cache_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_gN_cache, (st), (ptr)) +# define sk_SRP_gN_cache_insert(st, val, i) SKM_sk_insert(SRP_gN_cache, (st), (val), (i)) +# define sk_SRP_gN_cache_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_gN_cache, (st), (cmp)) +# define sk_SRP_gN_cache_dup(st) SKM_sk_dup(SRP_gN_cache, st) +# define sk_SRP_gN_cache_pop_free(st, free_func) SKM_sk_pop_free(SRP_gN_cache, (st), (free_func)) +# define sk_SRP_gN_cache_shift(st) SKM_sk_shift(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_pop(st) SKM_sk_pop(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_sort(st) SKM_sk_sort(SRP_gN_cache, (st)) +# define sk_SRP_gN_cache_is_sorted(st) SKM_sk_is_sorted(SRP_gN_cache, (st)) +# define sk_SRP_user_pwd_new(cmp) SKM_sk_new(SRP_user_pwd, (cmp)) +# define sk_SRP_user_pwd_new_null() SKM_sk_new_null(SRP_user_pwd) +# define sk_SRP_user_pwd_free(st) SKM_sk_free(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_num(st) SKM_sk_num(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_value(st, i) SKM_sk_value(SRP_user_pwd, (st), (i)) +# define sk_SRP_user_pwd_set(st, i, val) SKM_sk_set(SRP_user_pwd, (st), (i), (val)) +# define sk_SRP_user_pwd_zero(st) SKM_sk_zero(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_push(st, val) SKM_sk_push(SRP_user_pwd, (st), (val)) +# define sk_SRP_user_pwd_unshift(st, val) SKM_sk_unshift(SRP_user_pwd, (st), (val)) +# define sk_SRP_user_pwd_find(st, val) SKM_sk_find(SRP_user_pwd, (st), (val)) +# define sk_SRP_user_pwd_find_ex(st, val) SKM_sk_find_ex(SRP_user_pwd, (st), (val)) +# define sk_SRP_user_pwd_delete(st, i) SKM_sk_delete(SRP_user_pwd, (st), (i)) +# define sk_SRP_user_pwd_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRP_user_pwd, (st), (ptr)) +# define sk_SRP_user_pwd_insert(st, val, i) SKM_sk_insert(SRP_user_pwd, (st), (val), (i)) +# define sk_SRP_user_pwd_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRP_user_pwd, (st), (cmp)) +# define sk_SRP_user_pwd_dup(st) SKM_sk_dup(SRP_user_pwd, st) +# define sk_SRP_user_pwd_pop_free(st, free_func) SKM_sk_pop_free(SRP_user_pwd, (st), (free_func)) +# define sk_SRP_user_pwd_shift(st) SKM_sk_shift(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_pop(st) SKM_sk_pop(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_sort(st) SKM_sk_sort(SRP_user_pwd, (st)) +# define sk_SRP_user_pwd_is_sorted(st) SKM_sk_is_sorted(SRP_user_pwd, (st)) +# define sk_SRTP_PROTECTION_PROFILE_new(cmp) SKM_sk_new(SRTP_PROTECTION_PROFILE, (cmp)) +# define sk_SRTP_PROTECTION_PROFILE_new_null() SKM_sk_new_null(SRTP_PROTECTION_PROFILE) +# define sk_SRTP_PROTECTION_PROFILE_free(st) SKM_sk_free(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_num(st) SKM_sk_num(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_value(st, i) SKM_sk_value(SRTP_PROTECTION_PROFILE, (st), (i)) +# define sk_SRTP_PROTECTION_PROFILE_set(st, i, val) SKM_sk_set(SRTP_PROTECTION_PROFILE, (st), (i), (val)) +# define sk_SRTP_PROTECTION_PROFILE_zero(st) SKM_sk_zero(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_push(st, val) SKM_sk_push(SRTP_PROTECTION_PROFILE, (st), (val)) +# define sk_SRTP_PROTECTION_PROFILE_unshift(st, val) SKM_sk_unshift(SRTP_PROTECTION_PROFILE, (st), (val)) +# define sk_SRTP_PROTECTION_PROFILE_find(st, val) SKM_sk_find(SRTP_PROTECTION_PROFILE, (st), (val)) +# define sk_SRTP_PROTECTION_PROFILE_find_ex(st, val) SKM_sk_find_ex(SRTP_PROTECTION_PROFILE, (st), (val)) +# define sk_SRTP_PROTECTION_PROFILE_delete(st, i) SKM_sk_delete(SRTP_PROTECTION_PROFILE, (st), (i)) +# define sk_SRTP_PROTECTION_PROFILE_delete_ptr(st, ptr) SKM_sk_delete_ptr(SRTP_PROTECTION_PROFILE, (st), (ptr)) +# define sk_SRTP_PROTECTION_PROFILE_insert(st, val, i) SKM_sk_insert(SRTP_PROTECTION_PROFILE, (st), (val), (i)) +# define sk_SRTP_PROTECTION_PROFILE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SRTP_PROTECTION_PROFILE, (st), (cmp)) +# define sk_SRTP_PROTECTION_PROFILE_dup(st) SKM_sk_dup(SRTP_PROTECTION_PROFILE, st) +# define sk_SRTP_PROTECTION_PROFILE_pop_free(st, free_func) SKM_sk_pop_free(SRTP_PROTECTION_PROFILE, (st), (free_func)) +# define sk_SRTP_PROTECTION_PROFILE_shift(st) SKM_sk_shift(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_pop(st) SKM_sk_pop(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_sort(st) SKM_sk_sort(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SRTP_PROTECTION_PROFILE_is_sorted(st) SKM_sk_is_sorted(SRTP_PROTECTION_PROFILE, (st)) +# define sk_SSL_CIPHER_new(cmp) SKM_sk_new(SSL_CIPHER, (cmp)) +# define sk_SSL_CIPHER_new_null() SKM_sk_new_null(SSL_CIPHER) +# define sk_SSL_CIPHER_free(st) SKM_sk_free(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_num(st) SKM_sk_num(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_value(st, i) SKM_sk_value(SSL_CIPHER, (st), (i)) +# define sk_SSL_CIPHER_set(st, i, val) SKM_sk_set(SSL_CIPHER, (st), (i), (val)) +# define sk_SSL_CIPHER_zero(st) SKM_sk_zero(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_push(st, val) SKM_sk_push(SSL_CIPHER, (st), (val)) +# define sk_SSL_CIPHER_unshift(st, val) SKM_sk_unshift(SSL_CIPHER, (st), (val)) +# define sk_SSL_CIPHER_find(st, val) SKM_sk_find(SSL_CIPHER, (st), (val)) +# define sk_SSL_CIPHER_find_ex(st, val) SKM_sk_find_ex(SSL_CIPHER, (st), (val)) +# define sk_SSL_CIPHER_delete(st, i) SKM_sk_delete(SSL_CIPHER, (st), (i)) +# define sk_SSL_CIPHER_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_CIPHER, (st), (ptr)) +# define sk_SSL_CIPHER_insert(st, val, i) SKM_sk_insert(SSL_CIPHER, (st), (val), (i)) +# define sk_SSL_CIPHER_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_CIPHER, (st), (cmp)) +# define sk_SSL_CIPHER_dup(st) SKM_sk_dup(SSL_CIPHER, st) +# define sk_SSL_CIPHER_pop_free(st, free_func) SKM_sk_pop_free(SSL_CIPHER, (st), (free_func)) +# define sk_SSL_CIPHER_shift(st) SKM_sk_shift(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_pop(st) SKM_sk_pop(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_sort(st) SKM_sk_sort(SSL_CIPHER, (st)) +# define sk_SSL_CIPHER_is_sorted(st) SKM_sk_is_sorted(SSL_CIPHER, (st)) +# define sk_SSL_COMP_new(cmp) SKM_sk_new(SSL_COMP, (cmp)) +# define sk_SSL_COMP_new_null() SKM_sk_new_null(SSL_COMP) +# define sk_SSL_COMP_free(st) SKM_sk_free(SSL_COMP, (st)) +# define sk_SSL_COMP_num(st) SKM_sk_num(SSL_COMP, (st)) +# define sk_SSL_COMP_value(st, i) SKM_sk_value(SSL_COMP, (st), (i)) +# define sk_SSL_COMP_set(st, i, val) SKM_sk_set(SSL_COMP, (st), (i), (val)) +# define sk_SSL_COMP_zero(st) SKM_sk_zero(SSL_COMP, (st)) +# define sk_SSL_COMP_push(st, val) SKM_sk_push(SSL_COMP, (st), (val)) +# define sk_SSL_COMP_unshift(st, val) SKM_sk_unshift(SSL_COMP, (st), (val)) +# define sk_SSL_COMP_find(st, val) SKM_sk_find(SSL_COMP, (st), (val)) +# define sk_SSL_COMP_find_ex(st, val) SKM_sk_find_ex(SSL_COMP, (st), (val)) +# define sk_SSL_COMP_delete(st, i) SKM_sk_delete(SSL_COMP, (st), (i)) +# define sk_SSL_COMP_delete_ptr(st, ptr) SKM_sk_delete_ptr(SSL_COMP, (st), (ptr)) +# define sk_SSL_COMP_insert(st, val, i) SKM_sk_insert(SSL_COMP, (st), (val), (i)) +# define sk_SSL_COMP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SSL_COMP, (st), (cmp)) +# define sk_SSL_COMP_dup(st) SKM_sk_dup(SSL_COMP, st) +# define sk_SSL_COMP_pop_free(st, free_func) SKM_sk_pop_free(SSL_COMP, (st), (free_func)) +# define sk_SSL_COMP_shift(st) SKM_sk_shift(SSL_COMP, (st)) +# define sk_SSL_COMP_pop(st) SKM_sk_pop(SSL_COMP, (st)) +# define sk_SSL_COMP_sort(st) SKM_sk_sort(SSL_COMP, (st)) +# define sk_SSL_COMP_is_sorted(st) SKM_sk_is_sorted(SSL_COMP, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_new(cmp) SKM_sk_new(STACK_OF_X509_NAME_ENTRY, (cmp)) +# define sk_STACK_OF_X509_NAME_ENTRY_new_null() SKM_sk_new_null(STACK_OF_X509_NAME_ENTRY) +# define sk_STACK_OF_X509_NAME_ENTRY_free(st) SKM_sk_free(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_num(st) SKM_sk_num(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_value(st, i) SKM_sk_value(STACK_OF_X509_NAME_ENTRY, (st), (i)) +# define sk_STACK_OF_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(STACK_OF_X509_NAME_ENTRY, (st), (i), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_zero(st) SKM_sk_zero(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_push(st, val) SKM_sk_push(STACK_OF_X509_NAME_ENTRY, (st), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(STACK_OF_X509_NAME_ENTRY, (st), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_find(st, val) SKM_sk_find(STACK_OF_X509_NAME_ENTRY, (st), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(STACK_OF_X509_NAME_ENTRY, (st), (val)) +# define sk_STACK_OF_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(STACK_OF_X509_NAME_ENTRY, (st), (i)) +# define sk_STACK_OF_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(STACK_OF_X509_NAME_ENTRY, (st), (ptr)) +# define sk_STACK_OF_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(STACK_OF_X509_NAME_ENTRY, (st), (val), (i)) +# define sk_STACK_OF_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STACK_OF_X509_NAME_ENTRY, (st), (cmp)) +# define sk_STACK_OF_X509_NAME_ENTRY_dup(st) SKM_sk_dup(STACK_OF_X509_NAME_ENTRY, st) +# define sk_STACK_OF_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(STACK_OF_X509_NAME_ENTRY, (st), (free_func)) +# define sk_STACK_OF_X509_NAME_ENTRY_shift(st) SKM_sk_shift(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_pop(st) SKM_sk_pop(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_sort(st) SKM_sk_sort(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STACK_OF_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(STACK_OF_X509_NAME_ENTRY, (st)) +# define sk_STORE_ATTR_INFO_new(cmp) SKM_sk_new(STORE_ATTR_INFO, (cmp)) +# define sk_STORE_ATTR_INFO_new_null() SKM_sk_new_null(STORE_ATTR_INFO) +# define sk_STORE_ATTR_INFO_free(st) SKM_sk_free(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_num(st) SKM_sk_num(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_value(st, i) SKM_sk_value(STORE_ATTR_INFO, (st), (i)) +# define sk_STORE_ATTR_INFO_set(st, i, val) SKM_sk_set(STORE_ATTR_INFO, (st), (i), (val)) +# define sk_STORE_ATTR_INFO_zero(st) SKM_sk_zero(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_push(st, val) SKM_sk_push(STORE_ATTR_INFO, (st), (val)) +# define sk_STORE_ATTR_INFO_unshift(st, val) SKM_sk_unshift(STORE_ATTR_INFO, (st), (val)) +# define sk_STORE_ATTR_INFO_find(st, val) SKM_sk_find(STORE_ATTR_INFO, (st), (val)) +# define sk_STORE_ATTR_INFO_find_ex(st, val) SKM_sk_find_ex(STORE_ATTR_INFO, (st), (val)) +# define sk_STORE_ATTR_INFO_delete(st, i) SKM_sk_delete(STORE_ATTR_INFO, (st), (i)) +# define sk_STORE_ATTR_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_ATTR_INFO, (st), (ptr)) +# define sk_STORE_ATTR_INFO_insert(st, val, i) SKM_sk_insert(STORE_ATTR_INFO, (st), (val), (i)) +# define sk_STORE_ATTR_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_ATTR_INFO, (st), (cmp)) +# define sk_STORE_ATTR_INFO_dup(st) SKM_sk_dup(STORE_ATTR_INFO, st) +# define sk_STORE_ATTR_INFO_pop_free(st, free_func) SKM_sk_pop_free(STORE_ATTR_INFO, (st), (free_func)) +# define sk_STORE_ATTR_INFO_shift(st) SKM_sk_shift(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_pop(st) SKM_sk_pop(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_sort(st) SKM_sk_sort(STORE_ATTR_INFO, (st)) +# define sk_STORE_ATTR_INFO_is_sorted(st) SKM_sk_is_sorted(STORE_ATTR_INFO, (st)) +# define sk_STORE_OBJECT_new(cmp) SKM_sk_new(STORE_OBJECT, (cmp)) +# define sk_STORE_OBJECT_new_null() SKM_sk_new_null(STORE_OBJECT) +# define sk_STORE_OBJECT_free(st) SKM_sk_free(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_num(st) SKM_sk_num(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_value(st, i) SKM_sk_value(STORE_OBJECT, (st), (i)) +# define sk_STORE_OBJECT_set(st, i, val) SKM_sk_set(STORE_OBJECT, (st), (i), (val)) +# define sk_STORE_OBJECT_zero(st) SKM_sk_zero(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_push(st, val) SKM_sk_push(STORE_OBJECT, (st), (val)) +# define sk_STORE_OBJECT_unshift(st, val) SKM_sk_unshift(STORE_OBJECT, (st), (val)) +# define sk_STORE_OBJECT_find(st, val) SKM_sk_find(STORE_OBJECT, (st), (val)) +# define sk_STORE_OBJECT_find_ex(st, val) SKM_sk_find_ex(STORE_OBJECT, (st), (val)) +# define sk_STORE_OBJECT_delete(st, i) SKM_sk_delete(STORE_OBJECT, (st), (i)) +# define sk_STORE_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(STORE_OBJECT, (st), (ptr)) +# define sk_STORE_OBJECT_insert(st, val, i) SKM_sk_insert(STORE_OBJECT, (st), (val), (i)) +# define sk_STORE_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(STORE_OBJECT, (st), (cmp)) +# define sk_STORE_OBJECT_dup(st) SKM_sk_dup(STORE_OBJECT, st) +# define sk_STORE_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(STORE_OBJECT, (st), (free_func)) +# define sk_STORE_OBJECT_shift(st) SKM_sk_shift(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_pop(st) SKM_sk_pop(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_sort(st) SKM_sk_sort(STORE_OBJECT, (st)) +# define sk_STORE_OBJECT_is_sorted(st) SKM_sk_is_sorted(STORE_OBJECT, (st)) +# define sk_SXNETID_new(cmp) SKM_sk_new(SXNETID, (cmp)) +# define sk_SXNETID_new_null() SKM_sk_new_null(SXNETID) +# define sk_SXNETID_free(st) SKM_sk_free(SXNETID, (st)) +# define sk_SXNETID_num(st) SKM_sk_num(SXNETID, (st)) +# define sk_SXNETID_value(st, i) SKM_sk_value(SXNETID, (st), (i)) +# define sk_SXNETID_set(st, i, val) SKM_sk_set(SXNETID, (st), (i), (val)) +# define sk_SXNETID_zero(st) SKM_sk_zero(SXNETID, (st)) +# define sk_SXNETID_push(st, val) SKM_sk_push(SXNETID, (st), (val)) +# define sk_SXNETID_unshift(st, val) SKM_sk_unshift(SXNETID, (st), (val)) +# define sk_SXNETID_find(st, val) SKM_sk_find(SXNETID, (st), (val)) +# define sk_SXNETID_find_ex(st, val) SKM_sk_find_ex(SXNETID, (st), (val)) +# define sk_SXNETID_delete(st, i) SKM_sk_delete(SXNETID, (st), (i)) +# define sk_SXNETID_delete_ptr(st, ptr) SKM_sk_delete_ptr(SXNETID, (st), (ptr)) +# define sk_SXNETID_insert(st, val, i) SKM_sk_insert(SXNETID, (st), (val), (i)) +# define sk_SXNETID_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(SXNETID, (st), (cmp)) +# define sk_SXNETID_dup(st) SKM_sk_dup(SXNETID, st) +# define sk_SXNETID_pop_free(st, free_func) SKM_sk_pop_free(SXNETID, (st), (free_func)) +# define sk_SXNETID_shift(st) SKM_sk_shift(SXNETID, (st)) +# define sk_SXNETID_pop(st) SKM_sk_pop(SXNETID, (st)) +# define sk_SXNETID_sort(st) SKM_sk_sort(SXNETID, (st)) +# define sk_SXNETID_is_sorted(st) SKM_sk_is_sorted(SXNETID, (st)) +# define sk_UI_STRING_new(cmp) SKM_sk_new(UI_STRING, (cmp)) +# define sk_UI_STRING_new_null() SKM_sk_new_null(UI_STRING) +# define sk_UI_STRING_free(st) SKM_sk_free(UI_STRING, (st)) +# define sk_UI_STRING_num(st) SKM_sk_num(UI_STRING, (st)) +# define sk_UI_STRING_value(st, i) SKM_sk_value(UI_STRING, (st), (i)) +# define sk_UI_STRING_set(st, i, val) SKM_sk_set(UI_STRING, (st), (i), (val)) +# define sk_UI_STRING_zero(st) SKM_sk_zero(UI_STRING, (st)) +# define sk_UI_STRING_push(st, val) SKM_sk_push(UI_STRING, (st), (val)) +# define sk_UI_STRING_unshift(st, val) SKM_sk_unshift(UI_STRING, (st), (val)) +# define sk_UI_STRING_find(st, val) SKM_sk_find(UI_STRING, (st), (val)) +# define sk_UI_STRING_find_ex(st, val) SKM_sk_find_ex(UI_STRING, (st), (val)) +# define sk_UI_STRING_delete(st, i) SKM_sk_delete(UI_STRING, (st), (i)) +# define sk_UI_STRING_delete_ptr(st, ptr) SKM_sk_delete_ptr(UI_STRING, (st), (ptr)) +# define sk_UI_STRING_insert(st, val, i) SKM_sk_insert(UI_STRING, (st), (val), (i)) +# define sk_UI_STRING_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(UI_STRING, (st), (cmp)) +# define sk_UI_STRING_dup(st) SKM_sk_dup(UI_STRING, st) +# define sk_UI_STRING_pop_free(st, free_func) SKM_sk_pop_free(UI_STRING, (st), (free_func)) +# define sk_UI_STRING_shift(st) SKM_sk_shift(UI_STRING, (st)) +# define sk_UI_STRING_pop(st) SKM_sk_pop(UI_STRING, (st)) +# define sk_UI_STRING_sort(st) SKM_sk_sort(UI_STRING, (st)) +# define sk_UI_STRING_is_sorted(st) SKM_sk_is_sorted(UI_STRING, (st)) +# define sk_X509_new(cmp) SKM_sk_new(X509, (cmp)) +# define sk_X509_new_null() SKM_sk_new_null(X509) +# define sk_X509_free(st) SKM_sk_free(X509, (st)) +# define sk_X509_num(st) SKM_sk_num(X509, (st)) +# define sk_X509_value(st, i) SKM_sk_value(X509, (st), (i)) +# define sk_X509_set(st, i, val) SKM_sk_set(X509, (st), (i), (val)) +# define sk_X509_zero(st) SKM_sk_zero(X509, (st)) +# define sk_X509_push(st, val) SKM_sk_push(X509, (st), (val)) +# define sk_X509_unshift(st, val) SKM_sk_unshift(X509, (st), (val)) +# define sk_X509_find(st, val) SKM_sk_find(X509, (st), (val)) +# define sk_X509_find_ex(st, val) SKM_sk_find_ex(X509, (st), (val)) +# define sk_X509_delete(st, i) SKM_sk_delete(X509, (st), (i)) +# define sk_X509_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509, (st), (ptr)) +# define sk_X509_insert(st, val, i) SKM_sk_insert(X509, (st), (val), (i)) +# define sk_X509_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509, (st), (cmp)) +# define sk_X509_dup(st) SKM_sk_dup(X509, st) +# define sk_X509_pop_free(st, free_func) SKM_sk_pop_free(X509, (st), (free_func)) +# define sk_X509_shift(st) SKM_sk_shift(X509, (st)) +# define sk_X509_pop(st) SKM_sk_pop(X509, (st)) +# define sk_X509_sort(st) SKM_sk_sort(X509, (st)) +# define sk_X509_is_sorted(st) SKM_sk_is_sorted(X509, (st)) +# define sk_X509V3_EXT_METHOD_new(cmp) SKM_sk_new(X509V3_EXT_METHOD, (cmp)) +# define sk_X509V3_EXT_METHOD_new_null() SKM_sk_new_null(X509V3_EXT_METHOD) +# define sk_X509V3_EXT_METHOD_free(st) SKM_sk_free(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_num(st) SKM_sk_num(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_value(st, i) SKM_sk_value(X509V3_EXT_METHOD, (st), (i)) +# define sk_X509V3_EXT_METHOD_set(st, i, val) SKM_sk_set(X509V3_EXT_METHOD, (st), (i), (val)) +# define sk_X509V3_EXT_METHOD_zero(st) SKM_sk_zero(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_push(st, val) SKM_sk_push(X509V3_EXT_METHOD, (st), (val)) +# define sk_X509V3_EXT_METHOD_unshift(st, val) SKM_sk_unshift(X509V3_EXT_METHOD, (st), (val)) +# define sk_X509V3_EXT_METHOD_find(st, val) SKM_sk_find(X509V3_EXT_METHOD, (st), (val)) +# define sk_X509V3_EXT_METHOD_find_ex(st, val) SKM_sk_find_ex(X509V3_EXT_METHOD, (st), (val)) +# define sk_X509V3_EXT_METHOD_delete(st, i) SKM_sk_delete(X509V3_EXT_METHOD, (st), (i)) +# define sk_X509V3_EXT_METHOD_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509V3_EXT_METHOD, (st), (ptr)) +# define sk_X509V3_EXT_METHOD_insert(st, val, i) SKM_sk_insert(X509V3_EXT_METHOD, (st), (val), (i)) +# define sk_X509V3_EXT_METHOD_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509V3_EXT_METHOD, (st), (cmp)) +# define sk_X509V3_EXT_METHOD_dup(st) SKM_sk_dup(X509V3_EXT_METHOD, st) +# define sk_X509V3_EXT_METHOD_pop_free(st, free_func) SKM_sk_pop_free(X509V3_EXT_METHOD, (st), (free_func)) +# define sk_X509V3_EXT_METHOD_shift(st) SKM_sk_shift(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_pop(st) SKM_sk_pop(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_sort(st) SKM_sk_sort(X509V3_EXT_METHOD, (st)) +# define sk_X509V3_EXT_METHOD_is_sorted(st) SKM_sk_is_sorted(X509V3_EXT_METHOD, (st)) +# define sk_X509_ALGOR_new(cmp) SKM_sk_new(X509_ALGOR, (cmp)) +# define sk_X509_ALGOR_new_null() SKM_sk_new_null(X509_ALGOR) +# define sk_X509_ALGOR_free(st) SKM_sk_free(X509_ALGOR, (st)) +# define sk_X509_ALGOR_num(st) SKM_sk_num(X509_ALGOR, (st)) +# define sk_X509_ALGOR_value(st, i) SKM_sk_value(X509_ALGOR, (st), (i)) +# define sk_X509_ALGOR_set(st, i, val) SKM_sk_set(X509_ALGOR, (st), (i), (val)) +# define sk_X509_ALGOR_zero(st) SKM_sk_zero(X509_ALGOR, (st)) +# define sk_X509_ALGOR_push(st, val) SKM_sk_push(X509_ALGOR, (st), (val)) +# define sk_X509_ALGOR_unshift(st, val) SKM_sk_unshift(X509_ALGOR, (st), (val)) +# define sk_X509_ALGOR_find(st, val) SKM_sk_find(X509_ALGOR, (st), (val)) +# define sk_X509_ALGOR_find_ex(st, val) SKM_sk_find_ex(X509_ALGOR, (st), (val)) +# define sk_X509_ALGOR_delete(st, i) SKM_sk_delete(X509_ALGOR, (st), (i)) +# define sk_X509_ALGOR_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ALGOR, (st), (ptr)) +# define sk_X509_ALGOR_insert(st, val, i) SKM_sk_insert(X509_ALGOR, (st), (val), (i)) +# define sk_X509_ALGOR_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ALGOR, (st), (cmp)) +# define sk_X509_ALGOR_dup(st) SKM_sk_dup(X509_ALGOR, st) +# define sk_X509_ALGOR_pop_free(st, free_func) SKM_sk_pop_free(X509_ALGOR, (st), (free_func)) +# define sk_X509_ALGOR_shift(st) SKM_sk_shift(X509_ALGOR, (st)) +# define sk_X509_ALGOR_pop(st) SKM_sk_pop(X509_ALGOR, (st)) +# define sk_X509_ALGOR_sort(st) SKM_sk_sort(X509_ALGOR, (st)) +# define sk_X509_ALGOR_is_sorted(st) SKM_sk_is_sorted(X509_ALGOR, (st)) +# define sk_X509_ATTRIBUTE_new(cmp) SKM_sk_new(X509_ATTRIBUTE, (cmp)) +# define sk_X509_ATTRIBUTE_new_null() SKM_sk_new_null(X509_ATTRIBUTE) +# define sk_X509_ATTRIBUTE_free(st) SKM_sk_free(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_num(st) SKM_sk_num(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_value(st, i) SKM_sk_value(X509_ATTRIBUTE, (st), (i)) +# define sk_X509_ATTRIBUTE_set(st, i, val) SKM_sk_set(X509_ATTRIBUTE, (st), (i), (val)) +# define sk_X509_ATTRIBUTE_zero(st) SKM_sk_zero(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_push(st, val) SKM_sk_push(X509_ATTRIBUTE, (st), (val)) +# define sk_X509_ATTRIBUTE_unshift(st, val) SKM_sk_unshift(X509_ATTRIBUTE, (st), (val)) +# define sk_X509_ATTRIBUTE_find(st, val) SKM_sk_find(X509_ATTRIBUTE, (st), (val)) +# define sk_X509_ATTRIBUTE_find_ex(st, val) SKM_sk_find_ex(X509_ATTRIBUTE, (st), (val)) +# define sk_X509_ATTRIBUTE_delete(st, i) SKM_sk_delete(X509_ATTRIBUTE, (st), (i)) +# define sk_X509_ATTRIBUTE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_ATTRIBUTE, (st), (ptr)) +# define sk_X509_ATTRIBUTE_insert(st, val, i) SKM_sk_insert(X509_ATTRIBUTE, (st), (val), (i)) +# define sk_X509_ATTRIBUTE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_ATTRIBUTE, (st), (cmp)) +# define sk_X509_ATTRIBUTE_dup(st) SKM_sk_dup(X509_ATTRIBUTE, st) +# define sk_X509_ATTRIBUTE_pop_free(st, free_func) SKM_sk_pop_free(X509_ATTRIBUTE, (st), (free_func)) +# define sk_X509_ATTRIBUTE_shift(st) SKM_sk_shift(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_pop(st) SKM_sk_pop(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_sort(st) SKM_sk_sort(X509_ATTRIBUTE, (st)) +# define sk_X509_ATTRIBUTE_is_sorted(st) SKM_sk_is_sorted(X509_ATTRIBUTE, (st)) +# define sk_X509_CRL_new(cmp) SKM_sk_new(X509_CRL, (cmp)) +# define sk_X509_CRL_new_null() SKM_sk_new_null(X509_CRL) +# define sk_X509_CRL_free(st) SKM_sk_free(X509_CRL, (st)) +# define sk_X509_CRL_num(st) SKM_sk_num(X509_CRL, (st)) +# define sk_X509_CRL_value(st, i) SKM_sk_value(X509_CRL, (st), (i)) +# define sk_X509_CRL_set(st, i, val) SKM_sk_set(X509_CRL, (st), (i), (val)) +# define sk_X509_CRL_zero(st) SKM_sk_zero(X509_CRL, (st)) +# define sk_X509_CRL_push(st, val) SKM_sk_push(X509_CRL, (st), (val)) +# define sk_X509_CRL_unshift(st, val) SKM_sk_unshift(X509_CRL, (st), (val)) +# define sk_X509_CRL_find(st, val) SKM_sk_find(X509_CRL, (st), (val)) +# define sk_X509_CRL_find_ex(st, val) SKM_sk_find_ex(X509_CRL, (st), (val)) +# define sk_X509_CRL_delete(st, i) SKM_sk_delete(X509_CRL, (st), (i)) +# define sk_X509_CRL_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_CRL, (st), (ptr)) +# define sk_X509_CRL_insert(st, val, i) SKM_sk_insert(X509_CRL, (st), (val), (i)) +# define sk_X509_CRL_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_CRL, (st), (cmp)) +# define sk_X509_CRL_dup(st) SKM_sk_dup(X509_CRL, st) +# define sk_X509_CRL_pop_free(st, free_func) SKM_sk_pop_free(X509_CRL, (st), (free_func)) +# define sk_X509_CRL_shift(st) SKM_sk_shift(X509_CRL, (st)) +# define sk_X509_CRL_pop(st) SKM_sk_pop(X509_CRL, (st)) +# define sk_X509_CRL_sort(st) SKM_sk_sort(X509_CRL, (st)) +# define sk_X509_CRL_is_sorted(st) SKM_sk_is_sorted(X509_CRL, (st)) +# define sk_X509_EXTENSION_new(cmp) SKM_sk_new(X509_EXTENSION, (cmp)) +# define sk_X509_EXTENSION_new_null() SKM_sk_new_null(X509_EXTENSION) +# define sk_X509_EXTENSION_free(st) SKM_sk_free(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_num(st) SKM_sk_num(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_value(st, i) SKM_sk_value(X509_EXTENSION, (st), (i)) +# define sk_X509_EXTENSION_set(st, i, val) SKM_sk_set(X509_EXTENSION, (st), (i), (val)) +# define sk_X509_EXTENSION_zero(st) SKM_sk_zero(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_push(st, val) SKM_sk_push(X509_EXTENSION, (st), (val)) +# define sk_X509_EXTENSION_unshift(st, val) SKM_sk_unshift(X509_EXTENSION, (st), (val)) +# define sk_X509_EXTENSION_find(st, val) SKM_sk_find(X509_EXTENSION, (st), (val)) +# define sk_X509_EXTENSION_find_ex(st, val) SKM_sk_find_ex(X509_EXTENSION, (st), (val)) +# define sk_X509_EXTENSION_delete(st, i) SKM_sk_delete(X509_EXTENSION, (st), (i)) +# define sk_X509_EXTENSION_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_EXTENSION, (st), (ptr)) +# define sk_X509_EXTENSION_insert(st, val, i) SKM_sk_insert(X509_EXTENSION, (st), (val), (i)) +# define sk_X509_EXTENSION_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_EXTENSION, (st), (cmp)) +# define sk_X509_EXTENSION_dup(st) SKM_sk_dup(X509_EXTENSION, st) +# define sk_X509_EXTENSION_pop_free(st, free_func) SKM_sk_pop_free(X509_EXTENSION, (st), (free_func)) +# define sk_X509_EXTENSION_shift(st) SKM_sk_shift(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_pop(st) SKM_sk_pop(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_sort(st) SKM_sk_sort(X509_EXTENSION, (st)) +# define sk_X509_EXTENSION_is_sorted(st) SKM_sk_is_sorted(X509_EXTENSION, (st)) +# define sk_X509_INFO_new(cmp) SKM_sk_new(X509_INFO, (cmp)) +# define sk_X509_INFO_new_null() SKM_sk_new_null(X509_INFO) +# define sk_X509_INFO_free(st) SKM_sk_free(X509_INFO, (st)) +# define sk_X509_INFO_num(st) SKM_sk_num(X509_INFO, (st)) +# define sk_X509_INFO_value(st, i) SKM_sk_value(X509_INFO, (st), (i)) +# define sk_X509_INFO_set(st, i, val) SKM_sk_set(X509_INFO, (st), (i), (val)) +# define sk_X509_INFO_zero(st) SKM_sk_zero(X509_INFO, (st)) +# define sk_X509_INFO_push(st, val) SKM_sk_push(X509_INFO, (st), (val)) +# define sk_X509_INFO_unshift(st, val) SKM_sk_unshift(X509_INFO, (st), (val)) +# define sk_X509_INFO_find(st, val) SKM_sk_find(X509_INFO, (st), (val)) +# define sk_X509_INFO_find_ex(st, val) SKM_sk_find_ex(X509_INFO, (st), (val)) +# define sk_X509_INFO_delete(st, i) SKM_sk_delete(X509_INFO, (st), (i)) +# define sk_X509_INFO_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_INFO, (st), (ptr)) +# define sk_X509_INFO_insert(st, val, i) SKM_sk_insert(X509_INFO, (st), (val), (i)) +# define sk_X509_INFO_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_INFO, (st), (cmp)) +# define sk_X509_INFO_dup(st) SKM_sk_dup(X509_INFO, st) +# define sk_X509_INFO_pop_free(st, free_func) SKM_sk_pop_free(X509_INFO, (st), (free_func)) +# define sk_X509_INFO_shift(st) SKM_sk_shift(X509_INFO, (st)) +# define sk_X509_INFO_pop(st) SKM_sk_pop(X509_INFO, (st)) +# define sk_X509_INFO_sort(st) SKM_sk_sort(X509_INFO, (st)) +# define sk_X509_INFO_is_sorted(st) SKM_sk_is_sorted(X509_INFO, (st)) +# define sk_X509_LOOKUP_new(cmp) SKM_sk_new(X509_LOOKUP, (cmp)) +# define sk_X509_LOOKUP_new_null() SKM_sk_new_null(X509_LOOKUP) +# define sk_X509_LOOKUP_free(st) SKM_sk_free(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_num(st) SKM_sk_num(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_value(st, i) SKM_sk_value(X509_LOOKUP, (st), (i)) +# define sk_X509_LOOKUP_set(st, i, val) SKM_sk_set(X509_LOOKUP, (st), (i), (val)) +# define sk_X509_LOOKUP_zero(st) SKM_sk_zero(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_push(st, val) SKM_sk_push(X509_LOOKUP, (st), (val)) +# define sk_X509_LOOKUP_unshift(st, val) SKM_sk_unshift(X509_LOOKUP, (st), (val)) +# define sk_X509_LOOKUP_find(st, val) SKM_sk_find(X509_LOOKUP, (st), (val)) +# define sk_X509_LOOKUP_find_ex(st, val) SKM_sk_find_ex(X509_LOOKUP, (st), (val)) +# define sk_X509_LOOKUP_delete(st, i) SKM_sk_delete(X509_LOOKUP, (st), (i)) +# define sk_X509_LOOKUP_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_LOOKUP, (st), (ptr)) +# define sk_X509_LOOKUP_insert(st, val, i) SKM_sk_insert(X509_LOOKUP, (st), (val), (i)) +# define sk_X509_LOOKUP_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_LOOKUP, (st), (cmp)) +# define sk_X509_LOOKUP_dup(st) SKM_sk_dup(X509_LOOKUP, st) +# define sk_X509_LOOKUP_pop_free(st, free_func) SKM_sk_pop_free(X509_LOOKUP, (st), (free_func)) +# define sk_X509_LOOKUP_shift(st) SKM_sk_shift(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_pop(st) SKM_sk_pop(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_sort(st) SKM_sk_sort(X509_LOOKUP, (st)) +# define sk_X509_LOOKUP_is_sorted(st) SKM_sk_is_sorted(X509_LOOKUP, (st)) +# define sk_X509_NAME_new(cmp) SKM_sk_new(X509_NAME, (cmp)) +# define sk_X509_NAME_new_null() SKM_sk_new_null(X509_NAME) +# define sk_X509_NAME_free(st) SKM_sk_free(X509_NAME, (st)) +# define sk_X509_NAME_num(st) SKM_sk_num(X509_NAME, (st)) +# define sk_X509_NAME_value(st, i) SKM_sk_value(X509_NAME, (st), (i)) +# define sk_X509_NAME_set(st, i, val) SKM_sk_set(X509_NAME, (st), (i), (val)) +# define sk_X509_NAME_zero(st) SKM_sk_zero(X509_NAME, (st)) +# define sk_X509_NAME_push(st, val) SKM_sk_push(X509_NAME, (st), (val)) +# define sk_X509_NAME_unshift(st, val) SKM_sk_unshift(X509_NAME, (st), (val)) +# define sk_X509_NAME_find(st, val) SKM_sk_find(X509_NAME, (st), (val)) +# define sk_X509_NAME_find_ex(st, val) SKM_sk_find_ex(X509_NAME, (st), (val)) +# define sk_X509_NAME_delete(st, i) SKM_sk_delete(X509_NAME, (st), (i)) +# define sk_X509_NAME_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME, (st), (ptr)) +# define sk_X509_NAME_insert(st, val, i) SKM_sk_insert(X509_NAME, (st), (val), (i)) +# define sk_X509_NAME_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME, (st), (cmp)) +# define sk_X509_NAME_dup(st) SKM_sk_dup(X509_NAME, st) +# define sk_X509_NAME_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME, (st), (free_func)) +# define sk_X509_NAME_shift(st) SKM_sk_shift(X509_NAME, (st)) +# define sk_X509_NAME_pop(st) SKM_sk_pop(X509_NAME, (st)) +# define sk_X509_NAME_sort(st) SKM_sk_sort(X509_NAME, (st)) +# define sk_X509_NAME_is_sorted(st) SKM_sk_is_sorted(X509_NAME, (st)) +# define sk_X509_NAME_ENTRY_new(cmp) SKM_sk_new(X509_NAME_ENTRY, (cmp)) +# define sk_X509_NAME_ENTRY_new_null() SKM_sk_new_null(X509_NAME_ENTRY) +# define sk_X509_NAME_ENTRY_free(st) SKM_sk_free(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_num(st) SKM_sk_num(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_value(st, i) SKM_sk_value(X509_NAME_ENTRY, (st), (i)) +# define sk_X509_NAME_ENTRY_set(st, i, val) SKM_sk_set(X509_NAME_ENTRY, (st), (i), (val)) +# define sk_X509_NAME_ENTRY_zero(st) SKM_sk_zero(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_push(st, val) SKM_sk_push(X509_NAME_ENTRY, (st), (val)) +# define sk_X509_NAME_ENTRY_unshift(st, val) SKM_sk_unshift(X509_NAME_ENTRY, (st), (val)) +# define sk_X509_NAME_ENTRY_find(st, val) SKM_sk_find(X509_NAME_ENTRY, (st), (val)) +# define sk_X509_NAME_ENTRY_find_ex(st, val) SKM_sk_find_ex(X509_NAME_ENTRY, (st), (val)) +# define sk_X509_NAME_ENTRY_delete(st, i) SKM_sk_delete(X509_NAME_ENTRY, (st), (i)) +# define sk_X509_NAME_ENTRY_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_NAME_ENTRY, (st), (ptr)) +# define sk_X509_NAME_ENTRY_insert(st, val, i) SKM_sk_insert(X509_NAME_ENTRY, (st), (val), (i)) +# define sk_X509_NAME_ENTRY_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_NAME_ENTRY, (st), (cmp)) +# define sk_X509_NAME_ENTRY_dup(st) SKM_sk_dup(X509_NAME_ENTRY, st) +# define sk_X509_NAME_ENTRY_pop_free(st, free_func) SKM_sk_pop_free(X509_NAME_ENTRY, (st), (free_func)) +# define sk_X509_NAME_ENTRY_shift(st) SKM_sk_shift(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_pop(st) SKM_sk_pop(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_sort(st) SKM_sk_sort(X509_NAME_ENTRY, (st)) +# define sk_X509_NAME_ENTRY_is_sorted(st) SKM_sk_is_sorted(X509_NAME_ENTRY, (st)) +# define sk_X509_OBJECT_new(cmp) SKM_sk_new(X509_OBJECT, (cmp)) +# define sk_X509_OBJECT_new_null() SKM_sk_new_null(X509_OBJECT) +# define sk_X509_OBJECT_free(st) SKM_sk_free(X509_OBJECT, (st)) +# define sk_X509_OBJECT_num(st) SKM_sk_num(X509_OBJECT, (st)) +# define sk_X509_OBJECT_value(st, i) SKM_sk_value(X509_OBJECT, (st), (i)) +# define sk_X509_OBJECT_set(st, i, val) SKM_sk_set(X509_OBJECT, (st), (i), (val)) +# define sk_X509_OBJECT_zero(st) SKM_sk_zero(X509_OBJECT, (st)) +# define sk_X509_OBJECT_push(st, val) SKM_sk_push(X509_OBJECT, (st), (val)) +# define sk_X509_OBJECT_unshift(st, val) SKM_sk_unshift(X509_OBJECT, (st), (val)) +# define sk_X509_OBJECT_find(st, val) SKM_sk_find(X509_OBJECT, (st), (val)) +# define sk_X509_OBJECT_find_ex(st, val) SKM_sk_find_ex(X509_OBJECT, (st), (val)) +# define sk_X509_OBJECT_delete(st, i) SKM_sk_delete(X509_OBJECT, (st), (i)) +# define sk_X509_OBJECT_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_OBJECT, (st), (ptr)) +# define sk_X509_OBJECT_insert(st, val, i) SKM_sk_insert(X509_OBJECT, (st), (val), (i)) +# define sk_X509_OBJECT_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_OBJECT, (st), (cmp)) +# define sk_X509_OBJECT_dup(st) SKM_sk_dup(X509_OBJECT, st) +# define sk_X509_OBJECT_pop_free(st, free_func) SKM_sk_pop_free(X509_OBJECT, (st), (free_func)) +# define sk_X509_OBJECT_shift(st) SKM_sk_shift(X509_OBJECT, (st)) +# define sk_X509_OBJECT_pop(st) SKM_sk_pop(X509_OBJECT, (st)) +# define sk_X509_OBJECT_sort(st) SKM_sk_sort(X509_OBJECT, (st)) +# define sk_X509_OBJECT_is_sorted(st) SKM_sk_is_sorted(X509_OBJECT, (st)) +# define sk_X509_POLICY_DATA_new(cmp) SKM_sk_new(X509_POLICY_DATA, (cmp)) +# define sk_X509_POLICY_DATA_new_null() SKM_sk_new_null(X509_POLICY_DATA) +# define sk_X509_POLICY_DATA_free(st) SKM_sk_free(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_num(st) SKM_sk_num(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_value(st, i) SKM_sk_value(X509_POLICY_DATA, (st), (i)) +# define sk_X509_POLICY_DATA_set(st, i, val) SKM_sk_set(X509_POLICY_DATA, (st), (i), (val)) +# define sk_X509_POLICY_DATA_zero(st) SKM_sk_zero(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_push(st, val) SKM_sk_push(X509_POLICY_DATA, (st), (val)) +# define sk_X509_POLICY_DATA_unshift(st, val) SKM_sk_unshift(X509_POLICY_DATA, (st), (val)) +# define sk_X509_POLICY_DATA_find(st, val) SKM_sk_find(X509_POLICY_DATA, (st), (val)) +# define sk_X509_POLICY_DATA_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_DATA, (st), (val)) +# define sk_X509_POLICY_DATA_delete(st, i) SKM_sk_delete(X509_POLICY_DATA, (st), (i)) +# define sk_X509_POLICY_DATA_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_DATA, (st), (ptr)) +# define sk_X509_POLICY_DATA_insert(st, val, i) SKM_sk_insert(X509_POLICY_DATA, (st), (val), (i)) +# define sk_X509_POLICY_DATA_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_DATA, (st), (cmp)) +# define sk_X509_POLICY_DATA_dup(st) SKM_sk_dup(X509_POLICY_DATA, st) +# define sk_X509_POLICY_DATA_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_DATA, (st), (free_func)) +# define sk_X509_POLICY_DATA_shift(st) SKM_sk_shift(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_pop(st) SKM_sk_pop(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_sort(st) SKM_sk_sort(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_DATA_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_DATA, (st)) +# define sk_X509_POLICY_NODE_new(cmp) SKM_sk_new(X509_POLICY_NODE, (cmp)) +# define sk_X509_POLICY_NODE_new_null() SKM_sk_new_null(X509_POLICY_NODE) +# define sk_X509_POLICY_NODE_free(st) SKM_sk_free(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_num(st) SKM_sk_num(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_value(st, i) SKM_sk_value(X509_POLICY_NODE, (st), (i)) +# define sk_X509_POLICY_NODE_set(st, i, val) SKM_sk_set(X509_POLICY_NODE, (st), (i), (val)) +# define sk_X509_POLICY_NODE_zero(st) SKM_sk_zero(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_push(st, val) SKM_sk_push(X509_POLICY_NODE, (st), (val)) +# define sk_X509_POLICY_NODE_unshift(st, val) SKM_sk_unshift(X509_POLICY_NODE, (st), (val)) +# define sk_X509_POLICY_NODE_find(st, val) SKM_sk_find(X509_POLICY_NODE, (st), (val)) +# define sk_X509_POLICY_NODE_find_ex(st, val) SKM_sk_find_ex(X509_POLICY_NODE, (st), (val)) +# define sk_X509_POLICY_NODE_delete(st, i) SKM_sk_delete(X509_POLICY_NODE, (st), (i)) +# define sk_X509_POLICY_NODE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_POLICY_NODE, (st), (ptr)) +# define sk_X509_POLICY_NODE_insert(st, val, i) SKM_sk_insert(X509_POLICY_NODE, (st), (val), (i)) +# define sk_X509_POLICY_NODE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_POLICY_NODE, (st), (cmp)) +# define sk_X509_POLICY_NODE_dup(st) SKM_sk_dup(X509_POLICY_NODE, st) +# define sk_X509_POLICY_NODE_pop_free(st, free_func) SKM_sk_pop_free(X509_POLICY_NODE, (st), (free_func)) +# define sk_X509_POLICY_NODE_shift(st) SKM_sk_shift(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_pop(st) SKM_sk_pop(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_sort(st) SKM_sk_sort(X509_POLICY_NODE, (st)) +# define sk_X509_POLICY_NODE_is_sorted(st) SKM_sk_is_sorted(X509_POLICY_NODE, (st)) +# define sk_X509_PURPOSE_new(cmp) SKM_sk_new(X509_PURPOSE, (cmp)) +# define sk_X509_PURPOSE_new_null() SKM_sk_new_null(X509_PURPOSE) +# define sk_X509_PURPOSE_free(st) SKM_sk_free(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_num(st) SKM_sk_num(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_value(st, i) SKM_sk_value(X509_PURPOSE, (st), (i)) +# define sk_X509_PURPOSE_set(st, i, val) SKM_sk_set(X509_PURPOSE, (st), (i), (val)) +# define sk_X509_PURPOSE_zero(st) SKM_sk_zero(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_push(st, val) SKM_sk_push(X509_PURPOSE, (st), (val)) +# define sk_X509_PURPOSE_unshift(st, val) SKM_sk_unshift(X509_PURPOSE, (st), (val)) +# define sk_X509_PURPOSE_find(st, val) SKM_sk_find(X509_PURPOSE, (st), (val)) +# define sk_X509_PURPOSE_find_ex(st, val) SKM_sk_find_ex(X509_PURPOSE, (st), (val)) +# define sk_X509_PURPOSE_delete(st, i) SKM_sk_delete(X509_PURPOSE, (st), (i)) +# define sk_X509_PURPOSE_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_PURPOSE, (st), (ptr)) +# define sk_X509_PURPOSE_insert(st, val, i) SKM_sk_insert(X509_PURPOSE, (st), (val), (i)) +# define sk_X509_PURPOSE_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_PURPOSE, (st), (cmp)) +# define sk_X509_PURPOSE_dup(st) SKM_sk_dup(X509_PURPOSE, st) +# define sk_X509_PURPOSE_pop_free(st, free_func) SKM_sk_pop_free(X509_PURPOSE, (st), (free_func)) +# define sk_X509_PURPOSE_shift(st) SKM_sk_shift(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_pop(st) SKM_sk_pop(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_sort(st) SKM_sk_sort(X509_PURPOSE, (st)) +# define sk_X509_PURPOSE_is_sorted(st) SKM_sk_is_sorted(X509_PURPOSE, (st)) +# define sk_X509_REVOKED_new(cmp) SKM_sk_new(X509_REVOKED, (cmp)) +# define sk_X509_REVOKED_new_null() SKM_sk_new_null(X509_REVOKED) +# define sk_X509_REVOKED_free(st) SKM_sk_free(X509_REVOKED, (st)) +# define sk_X509_REVOKED_num(st) SKM_sk_num(X509_REVOKED, (st)) +# define sk_X509_REVOKED_value(st, i) SKM_sk_value(X509_REVOKED, (st), (i)) +# define sk_X509_REVOKED_set(st, i, val) SKM_sk_set(X509_REVOKED, (st), (i), (val)) +# define sk_X509_REVOKED_zero(st) SKM_sk_zero(X509_REVOKED, (st)) +# define sk_X509_REVOKED_push(st, val) SKM_sk_push(X509_REVOKED, (st), (val)) +# define sk_X509_REVOKED_unshift(st, val) SKM_sk_unshift(X509_REVOKED, (st), (val)) +# define sk_X509_REVOKED_find(st, val) SKM_sk_find(X509_REVOKED, (st), (val)) +# define sk_X509_REVOKED_find_ex(st, val) SKM_sk_find_ex(X509_REVOKED, (st), (val)) +# define sk_X509_REVOKED_delete(st, i) SKM_sk_delete(X509_REVOKED, (st), (i)) +# define sk_X509_REVOKED_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_REVOKED, (st), (ptr)) +# define sk_X509_REVOKED_insert(st, val, i) SKM_sk_insert(X509_REVOKED, (st), (val), (i)) +# define sk_X509_REVOKED_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_REVOKED, (st), (cmp)) +# define sk_X509_REVOKED_dup(st) SKM_sk_dup(X509_REVOKED, st) +# define sk_X509_REVOKED_pop_free(st, free_func) SKM_sk_pop_free(X509_REVOKED, (st), (free_func)) +# define sk_X509_REVOKED_shift(st) SKM_sk_shift(X509_REVOKED, (st)) +# define sk_X509_REVOKED_pop(st) SKM_sk_pop(X509_REVOKED, (st)) +# define sk_X509_REVOKED_sort(st) SKM_sk_sort(X509_REVOKED, (st)) +# define sk_X509_REVOKED_is_sorted(st) SKM_sk_is_sorted(X509_REVOKED, (st)) +# define sk_X509_TRUST_new(cmp) SKM_sk_new(X509_TRUST, (cmp)) +# define sk_X509_TRUST_new_null() SKM_sk_new_null(X509_TRUST) +# define sk_X509_TRUST_free(st) SKM_sk_free(X509_TRUST, (st)) +# define sk_X509_TRUST_num(st) SKM_sk_num(X509_TRUST, (st)) +# define sk_X509_TRUST_value(st, i) SKM_sk_value(X509_TRUST, (st), (i)) +# define sk_X509_TRUST_set(st, i, val) SKM_sk_set(X509_TRUST, (st), (i), (val)) +# define sk_X509_TRUST_zero(st) SKM_sk_zero(X509_TRUST, (st)) +# define sk_X509_TRUST_push(st, val) SKM_sk_push(X509_TRUST, (st), (val)) +# define sk_X509_TRUST_unshift(st, val) SKM_sk_unshift(X509_TRUST, (st), (val)) +# define sk_X509_TRUST_find(st, val) SKM_sk_find(X509_TRUST, (st), (val)) +# define sk_X509_TRUST_find_ex(st, val) SKM_sk_find_ex(X509_TRUST, (st), (val)) +# define sk_X509_TRUST_delete(st, i) SKM_sk_delete(X509_TRUST, (st), (i)) +# define sk_X509_TRUST_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_TRUST, (st), (ptr)) +# define sk_X509_TRUST_insert(st, val, i) SKM_sk_insert(X509_TRUST, (st), (val), (i)) +# define sk_X509_TRUST_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_TRUST, (st), (cmp)) +# define sk_X509_TRUST_dup(st) SKM_sk_dup(X509_TRUST, st) +# define sk_X509_TRUST_pop_free(st, free_func) SKM_sk_pop_free(X509_TRUST, (st), (free_func)) +# define sk_X509_TRUST_shift(st) SKM_sk_shift(X509_TRUST, (st)) +# define sk_X509_TRUST_pop(st) SKM_sk_pop(X509_TRUST, (st)) +# define sk_X509_TRUST_sort(st) SKM_sk_sort(X509_TRUST, (st)) +# define sk_X509_TRUST_is_sorted(st) SKM_sk_is_sorted(X509_TRUST, (st)) +# define sk_X509_VERIFY_PARAM_new(cmp) SKM_sk_new(X509_VERIFY_PARAM, (cmp)) +# define sk_X509_VERIFY_PARAM_new_null() SKM_sk_new_null(X509_VERIFY_PARAM) +# define sk_X509_VERIFY_PARAM_free(st) SKM_sk_free(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_num(st) SKM_sk_num(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_value(st, i) SKM_sk_value(X509_VERIFY_PARAM, (st), (i)) +# define sk_X509_VERIFY_PARAM_set(st, i, val) SKM_sk_set(X509_VERIFY_PARAM, (st), (i), (val)) +# define sk_X509_VERIFY_PARAM_zero(st) SKM_sk_zero(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_push(st, val) SKM_sk_push(X509_VERIFY_PARAM, (st), (val)) +# define sk_X509_VERIFY_PARAM_unshift(st, val) SKM_sk_unshift(X509_VERIFY_PARAM, (st), (val)) +# define sk_X509_VERIFY_PARAM_find(st, val) SKM_sk_find(X509_VERIFY_PARAM, (st), (val)) +# define sk_X509_VERIFY_PARAM_find_ex(st, val) SKM_sk_find_ex(X509_VERIFY_PARAM, (st), (val)) +# define sk_X509_VERIFY_PARAM_delete(st, i) SKM_sk_delete(X509_VERIFY_PARAM, (st), (i)) +# define sk_X509_VERIFY_PARAM_delete_ptr(st, ptr) SKM_sk_delete_ptr(X509_VERIFY_PARAM, (st), (ptr)) +# define sk_X509_VERIFY_PARAM_insert(st, val, i) SKM_sk_insert(X509_VERIFY_PARAM, (st), (val), (i)) +# define sk_X509_VERIFY_PARAM_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(X509_VERIFY_PARAM, (st), (cmp)) +# define sk_X509_VERIFY_PARAM_dup(st) SKM_sk_dup(X509_VERIFY_PARAM, st) +# define sk_X509_VERIFY_PARAM_pop_free(st, free_func) SKM_sk_pop_free(X509_VERIFY_PARAM, (st), (free_func)) +# define sk_X509_VERIFY_PARAM_shift(st) SKM_sk_shift(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_pop(st) SKM_sk_pop(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_sort(st) SKM_sk_sort(X509_VERIFY_PARAM, (st)) +# define sk_X509_VERIFY_PARAM_is_sorted(st) SKM_sk_is_sorted(X509_VERIFY_PARAM, (st)) +# define sk_nid_triple_new(cmp) SKM_sk_new(nid_triple, (cmp)) +# define sk_nid_triple_new_null() SKM_sk_new_null(nid_triple) +# define sk_nid_triple_free(st) SKM_sk_free(nid_triple, (st)) +# define sk_nid_triple_num(st) SKM_sk_num(nid_triple, (st)) +# define sk_nid_triple_value(st, i) SKM_sk_value(nid_triple, (st), (i)) +# define sk_nid_triple_set(st, i, val) SKM_sk_set(nid_triple, (st), (i), (val)) +# define sk_nid_triple_zero(st) SKM_sk_zero(nid_triple, (st)) +# define sk_nid_triple_push(st, val) SKM_sk_push(nid_triple, (st), (val)) +# define sk_nid_triple_unshift(st, val) SKM_sk_unshift(nid_triple, (st), (val)) +# define sk_nid_triple_find(st, val) SKM_sk_find(nid_triple, (st), (val)) +# define sk_nid_triple_find_ex(st, val) SKM_sk_find_ex(nid_triple, (st), (val)) +# define sk_nid_triple_delete(st, i) SKM_sk_delete(nid_triple, (st), (i)) +# define sk_nid_triple_delete_ptr(st, ptr) SKM_sk_delete_ptr(nid_triple, (st), (ptr)) +# define sk_nid_triple_insert(st, val, i) SKM_sk_insert(nid_triple, (st), (val), (i)) +# define sk_nid_triple_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(nid_triple, (st), (cmp)) +# define sk_nid_triple_dup(st) SKM_sk_dup(nid_triple, st) +# define sk_nid_triple_pop_free(st, free_func) SKM_sk_pop_free(nid_triple, (st), (free_func)) +# define sk_nid_triple_shift(st) SKM_sk_shift(nid_triple, (st)) +# define sk_nid_triple_pop(st) SKM_sk_pop(nid_triple, (st)) +# define sk_nid_triple_sort(st) SKM_sk_sort(nid_triple, (st)) +# define sk_nid_triple_is_sorted(st) SKM_sk_is_sorted(nid_triple, (st)) +# define sk_void_new(cmp) SKM_sk_new(void, (cmp)) +# define sk_void_new_null() SKM_sk_new_null(void) +# define sk_void_free(st) SKM_sk_free(void, (st)) +# define sk_void_num(st) SKM_sk_num(void, (st)) +# define sk_void_value(st, i) SKM_sk_value(void, (st), (i)) +# define sk_void_set(st, i, val) SKM_sk_set(void, (st), (i), (val)) +# define sk_void_zero(st) SKM_sk_zero(void, (st)) +# define sk_void_push(st, val) SKM_sk_push(void, (st), (val)) +# define sk_void_unshift(st, val) SKM_sk_unshift(void, (st), (val)) +# define sk_void_find(st, val) SKM_sk_find(void, (st), (val)) +# define sk_void_find_ex(st, val) SKM_sk_find_ex(void, (st), (val)) +# define sk_void_delete(st, i) SKM_sk_delete(void, (st), (i)) +# define sk_void_delete_ptr(st, ptr) SKM_sk_delete_ptr(void, (st), (ptr)) +# define sk_void_insert(st, val, i) SKM_sk_insert(void, (st), (val), (i)) +# define sk_void_set_cmp_func(st, cmp) SKM_sk_set_cmp_func(void, (st), (cmp)) +# define sk_void_dup(st) SKM_sk_dup(void, st) +# define sk_void_pop_free(st, free_func) SKM_sk_pop_free(void, (st), (free_func)) +# define sk_void_shift(st) SKM_sk_shift(void, (st)) +# define sk_void_pop(st) SKM_sk_pop(void, (st)) +# define sk_void_sort(st) SKM_sk_sort(void, (st)) +# define sk_void_is_sorted(st) SKM_sk_is_sorted(void, (st)) +# define sk_OPENSSL_STRING_new(cmp) ((STACK_OF(OPENSSL_STRING) *)sk_new(CHECKED_SK_CMP_FUNC(char, cmp))) +# define sk_OPENSSL_STRING_new_null() ((STACK_OF(OPENSSL_STRING) *)sk_new_null()) +# define sk_OPENSSL_STRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_value(st, i) ((OPENSSL_STRING)sk_value(CHECKED_STACK_OF(OPENSSL_STRING, st), i)) +# define sk_OPENSSL_STRING_num(st) SKM_sk_num(OPENSSL_STRING, st) +# define sk_OPENSSL_STRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_STRING, free_func)) +# define sk_OPENSSL_STRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val), i) +# define sk_OPENSSL_STRING_free(st) SKM_sk_free(OPENSSL_STRING, st) +# define sk_OPENSSL_STRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_STRING, st), i, CHECKED_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_zero(st) SKM_sk_zero(OPENSSL_STRING, (st)) +# define sk_OPENSSL_STRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_STRING), st), CHECKED_CONST_PTR_OF(char, val)) +# define sk_OPENSSL_STRING_delete(st, i) SKM_sk_delete(OPENSSL_STRING, (st), (i)) +# define sk_OPENSSL_STRING_delete_ptr(st, ptr) (OPENSSL_STRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_PTR_OF(char, ptr)) +# define sk_OPENSSL_STRING_set_cmp_func(st, cmp) \ + ((int (*)(const char * const *,const char * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_STRING, st), CHECKED_SK_CMP_FUNC(char, cmp))) +# define sk_OPENSSL_STRING_dup(st) SKM_sk_dup(OPENSSL_STRING, st) +# define sk_OPENSSL_STRING_shift(st) SKM_sk_shift(OPENSSL_STRING, (st)) +# define sk_OPENSSL_STRING_pop(st) (char *)sk_pop(CHECKED_STACK_OF(OPENSSL_STRING, st)) +# define sk_OPENSSL_STRING_sort(st) SKM_sk_sort(OPENSSL_STRING, (st)) +# define sk_OPENSSL_STRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_STRING, (st)) +# define sk_OPENSSL_BLOCK_new(cmp) ((STACK_OF(OPENSSL_BLOCK) *)sk_new(CHECKED_SK_CMP_FUNC(void, cmp))) +# define sk_OPENSSL_BLOCK_new_null() ((STACK_OF(OPENSSL_BLOCK) *)sk_new_null()) +# define sk_OPENSSL_BLOCK_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_value(st, i) ((OPENSSL_BLOCK)sk_value(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i)) +# define sk_OPENSSL_BLOCK_num(st) SKM_sk_num(OPENSSL_BLOCK, st) +# define sk_OPENSSL_BLOCK_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_FREE_FUNC2(OPENSSL_BLOCK, free_func)) +# define sk_OPENSSL_BLOCK_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val), i) +# define sk_OPENSSL_BLOCK_free(st) SKM_sk_free(OPENSSL_BLOCK, st) +# define sk_OPENSSL_BLOCK_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_BLOCK, st), i, CHECKED_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_zero(st) SKM_sk_zero(OPENSSL_BLOCK, (st)) +# define sk_OPENSSL_BLOCK_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_BLOCK), st), CHECKED_CONST_PTR_OF(void, val)) +# define sk_OPENSSL_BLOCK_delete(st, i) SKM_sk_delete(OPENSSL_BLOCK, (st), (i)) +# define sk_OPENSSL_BLOCK_delete_ptr(st, ptr) (OPENSSL_BLOCK *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_PTR_OF(void, ptr)) +# define sk_OPENSSL_BLOCK_set_cmp_func(st, cmp) \ + ((int (*)(const void * const *,const void * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_BLOCK, st), CHECKED_SK_CMP_FUNC(void, cmp))) +# define sk_OPENSSL_BLOCK_dup(st) SKM_sk_dup(OPENSSL_BLOCK, st) +# define sk_OPENSSL_BLOCK_shift(st) SKM_sk_shift(OPENSSL_BLOCK, (st)) +# define sk_OPENSSL_BLOCK_pop(st) (void *)sk_pop(CHECKED_STACK_OF(OPENSSL_BLOCK, st)) +# define sk_OPENSSL_BLOCK_sort(st) SKM_sk_sort(OPENSSL_BLOCK, (st)) +# define sk_OPENSSL_BLOCK_is_sorted(st) SKM_sk_is_sorted(OPENSSL_BLOCK, (st)) +# define sk_OPENSSL_PSTRING_new(cmp) ((STACK_OF(OPENSSL_PSTRING) *)sk_new(CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) +# define sk_OPENSSL_PSTRING_new_null() ((STACK_OF(OPENSSL_PSTRING) *)sk_new_null()) +# define sk_OPENSSL_PSTRING_push(st, val) sk_push(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_find(st, val) sk_find(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_value(st, i) ((OPENSSL_PSTRING)sk_value(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i)) +# define sk_OPENSSL_PSTRING_num(st) SKM_sk_num(OPENSSL_PSTRING, st) +# define sk_OPENSSL_PSTRING_pop_free(st, free_func) sk_pop_free(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_FREE_FUNC2(OPENSSL_PSTRING, free_func)) +# define sk_OPENSSL_PSTRING_insert(st, val, i) sk_insert(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val), i) +# define sk_OPENSSL_PSTRING_free(st) SKM_sk_free(OPENSSL_PSTRING, st) +# define sk_OPENSSL_PSTRING_set(st, i, val) sk_set(CHECKED_STACK_OF(OPENSSL_PSTRING, st), i, CHECKED_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_zero(st) SKM_sk_zero(OPENSSL_PSTRING, (st)) +# define sk_OPENSSL_PSTRING_unshift(st, val) sk_unshift(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_find_ex(st, val) sk_find_ex((_STACK *)CHECKED_CONST_PTR_OF(STACK_OF(OPENSSL_PSTRING), st), CHECKED_CONST_PTR_OF(OPENSSL_STRING, val)) +# define sk_OPENSSL_PSTRING_delete(st, i) SKM_sk_delete(OPENSSL_PSTRING, (st), (i)) +# define sk_OPENSSL_PSTRING_delete_ptr(st, ptr) (OPENSSL_PSTRING *)sk_delete_ptr(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_PTR_OF(OPENSSL_STRING, ptr)) +# define sk_OPENSSL_PSTRING_set_cmp_func(st, cmp) \ + ((int (*)(const OPENSSL_STRING * const *,const OPENSSL_STRING * const *)) \ + sk_set_cmp_func(CHECKED_STACK_OF(OPENSSL_PSTRING, st), CHECKED_SK_CMP_FUNC(OPENSSL_STRING, cmp))) +# define sk_OPENSSL_PSTRING_dup(st) SKM_sk_dup(OPENSSL_PSTRING, st) +# define sk_OPENSSL_PSTRING_shift(st) SKM_sk_shift(OPENSSL_PSTRING, (st)) +# define sk_OPENSSL_PSTRING_pop(st) (OPENSSL_STRING *)sk_pop(CHECKED_STACK_OF(OPENSSL_PSTRING, st)) +# define sk_OPENSSL_PSTRING_sort(st) SKM_sk_sort(OPENSSL_PSTRING, (st)) +# define sk_OPENSSL_PSTRING_is_sorted(st) SKM_sk_is_sorted(OPENSSL_PSTRING, (st)) +# define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ACCESS_DESCRIPTION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ACCESS_DESCRIPTION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ACCESS_DESCRIPTION(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ACCESS_DESCRIPTION, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ACCESS_DESCRIPTION(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ACCESS_DESCRIPTION, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ASN1_INTEGER(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_INTEGER, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ASN1_INTEGER(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_INTEGER, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ASN1_INTEGER(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_INTEGER, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ASN1_INTEGER(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_INTEGER, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ASN1_OBJECT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_OBJECT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ASN1_OBJECT(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_OBJECT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ASN1_OBJECT(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_OBJECT, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ASN1_OBJECT(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_OBJECT, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ASN1_TYPE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_TYPE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ASN1_TYPE(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_TYPE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ASN1_TYPE(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_TYPE, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ASN1_TYPE(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_TYPE, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ASN1_UTF8STRING, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ASN1_UTF8STRING(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ASN1_UTF8STRING, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ASN1_UTF8STRING(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ASN1_UTF8STRING, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ASN1_UTF8STRING(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ASN1_UTF8STRING, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_DIST_POINT(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(DIST_POINT, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_DIST_POINT(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(DIST_POINT, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_DIST_POINT(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(DIST_POINT, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_DIST_POINT(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(DIST_POINT, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_ESS_CERT_ID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(ESS_CERT_ID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_ESS_CERT_ID(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(ESS_CERT_ID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_ESS_CERT_ID(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(ESS_CERT_ID, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_ESS_CERT_ID(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(ESS_CERT_ID, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_EVP_MD(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(EVP_MD, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_EVP_MD(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(EVP_MD, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_EVP_MD(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(EVP_MD, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_EVP_MD(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(EVP_MD, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_GENERAL_NAME(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(GENERAL_NAME, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_GENERAL_NAME(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(GENERAL_NAME, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_GENERAL_NAME(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(GENERAL_NAME, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_GENERAL_NAME(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(GENERAL_NAME, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_OCSP_ONEREQ(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(OCSP_ONEREQ, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_OCSP_ONEREQ(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(OCSP_ONEREQ, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_OCSP_ONEREQ(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(OCSP_ONEREQ, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_OCSP_ONEREQ(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(OCSP_ONEREQ, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(OCSP_SINGLERESP, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_OCSP_SINGLERESP(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(OCSP_SINGLERESP, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_OCSP_SINGLERESP(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(OCSP_SINGLERESP, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_OCSP_SINGLERESP(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(OCSP_SINGLERESP, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS12_SAFEBAG, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_PKCS12_SAFEBAG(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS12_SAFEBAG, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_PKCS12_SAFEBAG(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS12_SAFEBAG, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_PKCS12_SAFEBAG(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS12_SAFEBAG, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_PKCS7(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_PKCS7(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_PKCS7(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_PKCS7(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7_RECIP_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7_RECIP_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_PKCS7_RECIP_INFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7_RECIP_INFO, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_PKCS7_RECIP_INFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7_RECIP_INFO, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(PKCS7_SIGNER_INFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(PKCS7_SIGNER_INFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_PKCS7_SIGNER_INFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(PKCS7_SIGNER_INFO, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_PKCS7_SIGNER_INFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(PKCS7_SIGNER_INFO, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_POLICYINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(POLICYINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_POLICYINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(POLICYINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_POLICYINFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(POLICYINFO, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_POLICYINFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(POLICYINFO, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_POLICYQUALINFO(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(POLICYQUALINFO, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_POLICYQUALINFO(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(POLICYQUALINFO, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_POLICYQUALINFO(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(POLICYQUALINFO, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_POLICYQUALINFO(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(POLICYQUALINFO, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_SXNETID(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(SXNETID, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_SXNETID(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(SXNETID, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_SXNETID(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(SXNETID, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_SXNETID(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(SXNETID, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_ALGOR(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_ALGOR, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_ALGOR(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_ALGOR, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_ALGOR(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_ALGOR, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_ALGOR(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_ALGOR, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_ATTRIBUTE, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_ATTRIBUTE(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_ATTRIBUTE, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_ATTRIBUTE(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_ATTRIBUTE, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_ATTRIBUTE(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_ATTRIBUTE, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_CRL(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_CRL, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_CRL(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_CRL, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_CRL(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_CRL, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_CRL(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_CRL, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_EXTENSION(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_EXTENSION, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_EXTENSION(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_EXTENSION, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_EXTENSION(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_EXTENSION, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_EXTENSION(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_EXTENSION, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_NAME_ENTRY, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_NAME_ENTRY(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_NAME_ENTRY, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_NAME_ENTRY(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_NAME_ENTRY, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_NAME_ENTRY(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_NAME_ENTRY, (buf), (len), (d2i_func), (free_func)) +# define d2i_ASN1_SET_OF_X509_REVOKED(st, pp, length, d2i_func, free_func, ex_tag, ex_class) \ + SKM_ASN1_SET_OF_d2i(X509_REVOKED, (st), (pp), (length), (d2i_func), (free_func), (ex_tag), (ex_class)) +# define i2d_ASN1_SET_OF_X509_REVOKED(st, pp, i2d_func, ex_tag, ex_class, is_set) \ + SKM_ASN1_SET_OF_i2d(X509_REVOKED, (st), (pp), (i2d_func), (ex_tag), (ex_class), (is_set)) +# define ASN1_seq_pack_X509_REVOKED(st, i2d_func, buf, len) \ + SKM_ASN1_seq_pack(X509_REVOKED, (st), (i2d_func), (buf), (len)) +# define ASN1_seq_unpack_X509_REVOKED(buf, len, d2i_func, free_func) \ + SKM_ASN1_seq_unpack(X509_REVOKED, (buf), (len), (d2i_func), (free_func)) +# define PKCS12_decrypt_d2i_PKCS12_SAFEBAG(algor, d2i_func, free_func, pass, passlen, oct, seq) \ + SKM_PKCS12_decrypt_d2i(PKCS12_SAFEBAG, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) +# define PKCS12_decrypt_d2i_PKCS7(algor, d2i_func, free_func, pass, passlen, oct, seq) \ + SKM_PKCS12_decrypt_d2i(PKCS7, (algor), (d2i_func), (free_func), (pass), (passlen), (oct), (seq)) +# define lh_ADDED_OBJ_new() LHM_lh_new(ADDED_OBJ,added_obj) +# define lh_ADDED_OBJ_insert(lh,inst) LHM_lh_insert(ADDED_OBJ,lh,inst) +# define lh_ADDED_OBJ_retrieve(lh,inst) LHM_lh_retrieve(ADDED_OBJ,lh,inst) +# define lh_ADDED_OBJ_delete(lh,inst) LHM_lh_delete(ADDED_OBJ,lh,inst) +# define lh_ADDED_OBJ_doall(lh,fn) LHM_lh_doall(ADDED_OBJ,lh,fn) +# define lh_ADDED_OBJ_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ADDED_OBJ,lh,fn,arg_type,arg) +# define lh_ADDED_OBJ_error(lh) LHM_lh_error(ADDED_OBJ,lh) +# define lh_ADDED_OBJ_num_items(lh) LHM_lh_num_items(ADDED_OBJ,lh) +# define lh_ADDED_OBJ_down_load(lh) LHM_lh_down_load(ADDED_OBJ,lh) +# define lh_ADDED_OBJ_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ADDED_OBJ,lh,out) +# define lh_ADDED_OBJ_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ADDED_OBJ,lh,out) +# define lh_ADDED_OBJ_stats_bio(lh,out) \ + LHM_lh_stats_bio(ADDED_OBJ,lh,out) +# define lh_ADDED_OBJ_free(lh) LHM_lh_free(ADDED_OBJ,lh) +# define lh_APP_INFO_new() LHM_lh_new(APP_INFO,app_info) +# define lh_APP_INFO_insert(lh,inst) LHM_lh_insert(APP_INFO,lh,inst) +# define lh_APP_INFO_retrieve(lh,inst) LHM_lh_retrieve(APP_INFO,lh,inst) +# define lh_APP_INFO_delete(lh,inst) LHM_lh_delete(APP_INFO,lh,inst) +# define lh_APP_INFO_doall(lh,fn) LHM_lh_doall(APP_INFO,lh,fn) +# define lh_APP_INFO_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(APP_INFO,lh,fn,arg_type,arg) +# define lh_APP_INFO_error(lh) LHM_lh_error(APP_INFO,lh) +# define lh_APP_INFO_num_items(lh) LHM_lh_num_items(APP_INFO,lh) +# define lh_APP_INFO_down_load(lh) LHM_lh_down_load(APP_INFO,lh) +# define lh_APP_INFO_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(APP_INFO,lh,out) +# define lh_APP_INFO_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(APP_INFO,lh,out) +# define lh_APP_INFO_stats_bio(lh,out) \ + LHM_lh_stats_bio(APP_INFO,lh,out) +# define lh_APP_INFO_free(lh) LHM_lh_free(APP_INFO,lh) +# define lh_CONF_VALUE_new() LHM_lh_new(CONF_VALUE,conf_value) +# define lh_CONF_VALUE_insert(lh,inst) LHM_lh_insert(CONF_VALUE,lh,inst) +# define lh_CONF_VALUE_retrieve(lh,inst) LHM_lh_retrieve(CONF_VALUE,lh,inst) +# define lh_CONF_VALUE_delete(lh,inst) LHM_lh_delete(CONF_VALUE,lh,inst) +# define lh_CONF_VALUE_doall(lh,fn) LHM_lh_doall(CONF_VALUE,lh,fn) +# define lh_CONF_VALUE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(CONF_VALUE,lh,fn,arg_type,arg) +# define lh_CONF_VALUE_error(lh) LHM_lh_error(CONF_VALUE,lh) +# define lh_CONF_VALUE_num_items(lh) LHM_lh_num_items(CONF_VALUE,lh) +# define lh_CONF_VALUE_down_load(lh) LHM_lh_down_load(CONF_VALUE,lh) +# define lh_CONF_VALUE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(CONF_VALUE,lh,out) +# define lh_CONF_VALUE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(CONF_VALUE,lh,out) +# define lh_CONF_VALUE_stats_bio(lh,out) \ + LHM_lh_stats_bio(CONF_VALUE,lh,out) +# define lh_CONF_VALUE_free(lh) LHM_lh_free(CONF_VALUE,lh) +# define lh_ENGINE_PILE_new() LHM_lh_new(ENGINE_PILE,engine_pile) +# define lh_ENGINE_PILE_insert(lh,inst) LHM_lh_insert(ENGINE_PILE,lh,inst) +# define lh_ENGINE_PILE_retrieve(lh,inst) LHM_lh_retrieve(ENGINE_PILE,lh,inst) +# define lh_ENGINE_PILE_delete(lh,inst) LHM_lh_delete(ENGINE_PILE,lh,inst) +# define lh_ENGINE_PILE_doall(lh,fn) LHM_lh_doall(ENGINE_PILE,lh,fn) +# define lh_ENGINE_PILE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ENGINE_PILE,lh,fn,arg_type,arg) +# define lh_ENGINE_PILE_error(lh) LHM_lh_error(ENGINE_PILE,lh) +# define lh_ENGINE_PILE_num_items(lh) LHM_lh_num_items(ENGINE_PILE,lh) +# define lh_ENGINE_PILE_down_load(lh) LHM_lh_down_load(ENGINE_PILE,lh) +# define lh_ENGINE_PILE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ENGINE_PILE,lh,out) +# define lh_ENGINE_PILE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ENGINE_PILE,lh,out) +# define lh_ENGINE_PILE_stats_bio(lh,out) \ + LHM_lh_stats_bio(ENGINE_PILE,lh,out) +# define lh_ENGINE_PILE_free(lh) LHM_lh_free(ENGINE_PILE,lh) +# define lh_ERR_STATE_new() LHM_lh_new(ERR_STATE,err_state) +# define lh_ERR_STATE_insert(lh,inst) LHM_lh_insert(ERR_STATE,lh,inst) +# define lh_ERR_STATE_retrieve(lh,inst) LHM_lh_retrieve(ERR_STATE,lh,inst) +# define lh_ERR_STATE_delete(lh,inst) LHM_lh_delete(ERR_STATE,lh,inst) +# define lh_ERR_STATE_doall(lh,fn) LHM_lh_doall(ERR_STATE,lh,fn) +# define lh_ERR_STATE_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ERR_STATE,lh,fn,arg_type,arg) +# define lh_ERR_STATE_error(lh) LHM_lh_error(ERR_STATE,lh) +# define lh_ERR_STATE_num_items(lh) LHM_lh_num_items(ERR_STATE,lh) +# define lh_ERR_STATE_down_load(lh) LHM_lh_down_load(ERR_STATE,lh) +# define lh_ERR_STATE_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ERR_STATE,lh,out) +# define lh_ERR_STATE_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ERR_STATE,lh,out) +# define lh_ERR_STATE_stats_bio(lh,out) \ + LHM_lh_stats_bio(ERR_STATE,lh,out) +# define lh_ERR_STATE_free(lh) LHM_lh_free(ERR_STATE,lh) +# define lh_ERR_STRING_DATA_new() LHM_lh_new(ERR_STRING_DATA,err_string_data) +# define lh_ERR_STRING_DATA_insert(lh,inst) LHM_lh_insert(ERR_STRING_DATA,lh,inst) +# define lh_ERR_STRING_DATA_retrieve(lh,inst) LHM_lh_retrieve(ERR_STRING_DATA,lh,inst) +# define lh_ERR_STRING_DATA_delete(lh,inst) LHM_lh_delete(ERR_STRING_DATA,lh,inst) +# define lh_ERR_STRING_DATA_doall(lh,fn) LHM_lh_doall(ERR_STRING_DATA,lh,fn) +# define lh_ERR_STRING_DATA_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(ERR_STRING_DATA,lh,fn,arg_type,arg) +# define lh_ERR_STRING_DATA_error(lh) LHM_lh_error(ERR_STRING_DATA,lh) +# define lh_ERR_STRING_DATA_num_items(lh) LHM_lh_num_items(ERR_STRING_DATA,lh) +# define lh_ERR_STRING_DATA_down_load(lh) LHM_lh_down_load(ERR_STRING_DATA,lh) +# define lh_ERR_STRING_DATA_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(ERR_STRING_DATA,lh,out) +# define lh_ERR_STRING_DATA_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(ERR_STRING_DATA,lh,out) +# define lh_ERR_STRING_DATA_stats_bio(lh,out) \ + LHM_lh_stats_bio(ERR_STRING_DATA,lh,out) +# define lh_ERR_STRING_DATA_free(lh) LHM_lh_free(ERR_STRING_DATA,lh) +# define lh_EX_CLASS_ITEM_new() LHM_lh_new(EX_CLASS_ITEM,ex_class_item) +# define lh_EX_CLASS_ITEM_insert(lh,inst) LHM_lh_insert(EX_CLASS_ITEM,lh,inst) +# define lh_EX_CLASS_ITEM_retrieve(lh,inst) LHM_lh_retrieve(EX_CLASS_ITEM,lh,inst) +# define lh_EX_CLASS_ITEM_delete(lh,inst) LHM_lh_delete(EX_CLASS_ITEM,lh,inst) +# define lh_EX_CLASS_ITEM_doall(lh,fn) LHM_lh_doall(EX_CLASS_ITEM,lh,fn) +# define lh_EX_CLASS_ITEM_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(EX_CLASS_ITEM,lh,fn,arg_type,arg) +# define lh_EX_CLASS_ITEM_error(lh) LHM_lh_error(EX_CLASS_ITEM,lh) +# define lh_EX_CLASS_ITEM_num_items(lh) LHM_lh_num_items(EX_CLASS_ITEM,lh) +# define lh_EX_CLASS_ITEM_down_load(lh) LHM_lh_down_load(EX_CLASS_ITEM,lh) +# define lh_EX_CLASS_ITEM_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(EX_CLASS_ITEM,lh,out) +# define lh_EX_CLASS_ITEM_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(EX_CLASS_ITEM,lh,out) +# define lh_EX_CLASS_ITEM_stats_bio(lh,out) \ + LHM_lh_stats_bio(EX_CLASS_ITEM,lh,out) +# define lh_EX_CLASS_ITEM_free(lh) LHM_lh_free(EX_CLASS_ITEM,lh) +# define lh_FUNCTION_new() LHM_lh_new(FUNCTION,function) +# define lh_FUNCTION_insert(lh,inst) LHM_lh_insert(FUNCTION,lh,inst) +# define lh_FUNCTION_retrieve(lh,inst) LHM_lh_retrieve(FUNCTION,lh,inst) +# define lh_FUNCTION_delete(lh,inst) LHM_lh_delete(FUNCTION,lh,inst) +# define lh_FUNCTION_doall(lh,fn) LHM_lh_doall(FUNCTION,lh,fn) +# define lh_FUNCTION_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(FUNCTION,lh,fn,arg_type,arg) +# define lh_FUNCTION_error(lh) LHM_lh_error(FUNCTION,lh) +# define lh_FUNCTION_num_items(lh) LHM_lh_num_items(FUNCTION,lh) +# define lh_FUNCTION_down_load(lh) LHM_lh_down_load(FUNCTION,lh) +# define lh_FUNCTION_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(FUNCTION,lh,out) +# define lh_FUNCTION_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(FUNCTION,lh,out) +# define lh_FUNCTION_stats_bio(lh,out) \ + LHM_lh_stats_bio(FUNCTION,lh,out) +# define lh_FUNCTION_free(lh) LHM_lh_free(FUNCTION,lh) +# define lh_MEM_new() LHM_lh_new(MEM,mem) +# define lh_MEM_insert(lh,inst) LHM_lh_insert(MEM,lh,inst) +# define lh_MEM_retrieve(lh,inst) LHM_lh_retrieve(MEM,lh,inst) +# define lh_MEM_delete(lh,inst) LHM_lh_delete(MEM,lh,inst) +# define lh_MEM_doall(lh,fn) LHM_lh_doall(MEM,lh,fn) +# define lh_MEM_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(MEM,lh,fn,arg_type,arg) +# define lh_MEM_error(lh) LHM_lh_error(MEM,lh) +# define lh_MEM_num_items(lh) LHM_lh_num_items(MEM,lh) +# define lh_MEM_down_load(lh) LHM_lh_down_load(MEM,lh) +# define lh_MEM_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(MEM,lh,out) +# define lh_MEM_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(MEM,lh,out) +# define lh_MEM_stats_bio(lh,out) \ + LHM_lh_stats_bio(MEM,lh,out) +# define lh_MEM_free(lh) LHM_lh_free(MEM,lh) +# define lh_OBJ_NAME_new() LHM_lh_new(OBJ_NAME,obj_name) +# define lh_OBJ_NAME_insert(lh,inst) LHM_lh_insert(OBJ_NAME,lh,inst) +# define lh_OBJ_NAME_retrieve(lh,inst) LHM_lh_retrieve(OBJ_NAME,lh,inst) +# define lh_OBJ_NAME_delete(lh,inst) LHM_lh_delete(OBJ_NAME,lh,inst) +# define lh_OBJ_NAME_doall(lh,fn) LHM_lh_doall(OBJ_NAME,lh,fn) +# define lh_OBJ_NAME_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OBJ_NAME,lh,fn,arg_type,arg) +# define lh_OBJ_NAME_error(lh) LHM_lh_error(OBJ_NAME,lh) +# define lh_OBJ_NAME_num_items(lh) LHM_lh_num_items(OBJ_NAME,lh) +# define lh_OBJ_NAME_down_load(lh) LHM_lh_down_load(OBJ_NAME,lh) +# define lh_OBJ_NAME_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OBJ_NAME,lh,out) +# define lh_OBJ_NAME_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OBJ_NAME,lh,out) +# define lh_OBJ_NAME_stats_bio(lh,out) \ + LHM_lh_stats_bio(OBJ_NAME,lh,out) +# define lh_OBJ_NAME_free(lh) LHM_lh_free(OBJ_NAME,lh) +# define lh_OPENSSL_CSTRING_new() LHM_lh_new(OPENSSL_CSTRING,openssl_cstring) +# define lh_OPENSSL_CSTRING_insert(lh,inst) LHM_lh_insert(OPENSSL_CSTRING,lh,inst) +# define lh_OPENSSL_CSTRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_CSTRING,lh,inst) +# define lh_OPENSSL_CSTRING_delete(lh,inst) LHM_lh_delete(OPENSSL_CSTRING,lh,inst) +# define lh_OPENSSL_CSTRING_doall(lh,fn) LHM_lh_doall(OPENSSL_CSTRING,lh,fn) +# define lh_OPENSSL_CSTRING_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OPENSSL_CSTRING,lh,fn,arg_type,arg) +# define lh_OPENSSL_CSTRING_error(lh) LHM_lh_error(OPENSSL_CSTRING,lh) +# define lh_OPENSSL_CSTRING_num_items(lh) LHM_lh_num_items(OPENSSL_CSTRING,lh) +# define lh_OPENSSL_CSTRING_down_load(lh) LHM_lh_down_load(OPENSSL_CSTRING,lh) +# define lh_OPENSSL_CSTRING_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OPENSSL_CSTRING,lh,out) +# define lh_OPENSSL_CSTRING_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OPENSSL_CSTRING,lh,out) +# define lh_OPENSSL_CSTRING_stats_bio(lh,out) \ + LHM_lh_stats_bio(OPENSSL_CSTRING,lh,out) +# define lh_OPENSSL_CSTRING_free(lh) LHM_lh_free(OPENSSL_CSTRING,lh) +# define lh_OPENSSL_STRING_new() LHM_lh_new(OPENSSL_STRING,openssl_string) +# define lh_OPENSSL_STRING_insert(lh,inst) LHM_lh_insert(OPENSSL_STRING,lh,inst) +# define lh_OPENSSL_STRING_retrieve(lh,inst) LHM_lh_retrieve(OPENSSL_STRING,lh,inst) +# define lh_OPENSSL_STRING_delete(lh,inst) LHM_lh_delete(OPENSSL_STRING,lh,inst) +# define lh_OPENSSL_STRING_doall(lh,fn) LHM_lh_doall(OPENSSL_STRING,lh,fn) +# define lh_OPENSSL_STRING_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(OPENSSL_STRING,lh,fn,arg_type,arg) +# define lh_OPENSSL_STRING_error(lh) LHM_lh_error(OPENSSL_STRING,lh) +# define lh_OPENSSL_STRING_num_items(lh) LHM_lh_num_items(OPENSSL_STRING,lh) +# define lh_OPENSSL_STRING_down_load(lh) LHM_lh_down_load(OPENSSL_STRING,lh) +# define lh_OPENSSL_STRING_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(OPENSSL_STRING,lh,out) +# define lh_OPENSSL_STRING_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(OPENSSL_STRING,lh,out) +# define lh_OPENSSL_STRING_stats_bio(lh,out) \ + LHM_lh_stats_bio(OPENSSL_STRING,lh,out) +# define lh_OPENSSL_STRING_free(lh) LHM_lh_free(OPENSSL_STRING,lh) +# define lh_SSL_SESSION_new() LHM_lh_new(SSL_SESSION,ssl_session) +# define lh_SSL_SESSION_insert(lh,inst) LHM_lh_insert(SSL_SESSION,lh,inst) +# define lh_SSL_SESSION_retrieve(lh,inst) LHM_lh_retrieve(SSL_SESSION,lh,inst) +# define lh_SSL_SESSION_delete(lh,inst) LHM_lh_delete(SSL_SESSION,lh,inst) +# define lh_SSL_SESSION_doall(lh,fn) LHM_lh_doall(SSL_SESSION,lh,fn) +# define lh_SSL_SESSION_doall_arg(lh,fn,arg_type,arg) \ + LHM_lh_doall_arg(SSL_SESSION,lh,fn,arg_type,arg) +# define lh_SSL_SESSION_error(lh) LHM_lh_error(SSL_SESSION,lh) +# define lh_SSL_SESSION_num_items(lh) LHM_lh_num_items(SSL_SESSION,lh) +# define lh_SSL_SESSION_down_load(lh) LHM_lh_down_load(SSL_SESSION,lh) +# define lh_SSL_SESSION_node_stats_bio(lh,out) \ + LHM_lh_node_stats_bio(SSL_SESSION,lh,out) +# define lh_SSL_SESSION_node_usage_stats_bio(lh,out) \ + LHM_lh_node_usage_stats_bio(SSL_SESSION,lh,out) +# define lh_SSL_SESSION_stats_bio(lh,out) \ + LHM_lh_stats_bio(SSL_SESSION,lh,out) +# define lh_SSL_SESSION_free(lh) LHM_lh_free(SSL_SESSION,lh) +#ifdef __cplusplus +} +#endif +#endif /* !defined HEADER_SAFESTACK_H */ diff --git a/libs/openssl/crypto/stack/stack.c b/libs/openssl/crypto/stack/stack.c new file mode 100644 index 00000000..331f9071 --- /dev/null +++ b/libs/openssl/crypto/stack/stack.c @@ -0,0 +1,350 @@ +/* crypto/stack/stack.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +/*- + * Code for stacks + * Author - Eric Young v 1.0 + * 1.2 eay 12-Mar-97 - Modified sk_find so that it _DOES_ return the + * lowest index for the searched item. + * + * 1.1 eay - Take from netdb and added to SSLeay + * + * 1.0 eay - First version 29/07/92 + */ +#include +#include "cryptlib.h" +#include +#include + +#undef MIN_NODES +#define MIN_NODES 4 + +const char STACK_version[] = "Stack" OPENSSL_VERSION_PTEXT; + +#include + +int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *))) + (const void *, const void *) { + int (*old) (const void *, const void *) = sk->comp; + + if (sk->comp != c) + sk->sorted = 0; + sk->comp = c; + + return old; +} + +_STACK *sk_dup(_STACK *sk) +{ + _STACK *ret; + char **s; + + if ((ret = sk_new(sk->comp)) == NULL) + goto err; + s = (char **)OPENSSL_realloc((char *)ret->data, + (unsigned int)sizeof(char *) * + sk->num_alloc); + if (s == NULL) + goto err; + ret->data = s; + + ret->num = sk->num; + memcpy(ret->data, sk->data, sizeof(char *) * sk->num); + ret->sorted = sk->sorted; + ret->num_alloc = sk->num_alloc; + ret->comp = sk->comp; + return (ret); + err: + if (ret) + sk_free(ret); + return (NULL); +} + +_STACK *sk_new_null(void) +{ + return sk_new((int (*)(const void *, const void *))0); +} + +_STACK *sk_new(int (*c) (const void *, const void *)) +{ + _STACK *ret; + int i; + + if ((ret = OPENSSL_malloc(sizeof(_STACK))) == NULL) + goto err; + if ((ret->data = OPENSSL_malloc(sizeof(char *) * MIN_NODES)) == NULL) + goto err; + for (i = 0; i < MIN_NODES; i++) + ret->data[i] = NULL; + ret->comp = c; + ret->num_alloc = MIN_NODES; + ret->num = 0; + ret->sorted = 0; + return (ret); + err: + if (ret) + OPENSSL_free(ret); + return (NULL); +} + +int sk_insert(_STACK *st, void *data, int loc) +{ + char **s; + + if (st == NULL) + return 0; + if (st->num_alloc <= st->num + 1) { + s = OPENSSL_realloc((char *)st->data, + (unsigned int)sizeof(char *) * st->num_alloc * 2); + if (s == NULL) + return (0); + st->data = s; + st->num_alloc *= 2; + } + if ((loc >= (int)st->num) || (loc < 0)) + st->data[st->num] = data; + else { + int i; + char **f, **t; + + f = st->data; + t = &(st->data[1]); + for (i = st->num; i >= loc; i--) + t[i] = f[i]; + +#ifdef undef /* no memmove on sunos :-( */ + memmove(&(st->data[loc + 1]), + &(st->data[loc]), sizeof(char *) * (st->num - loc)); +#endif + st->data[loc] = data; + } + st->num++; + st->sorted = 0; + return (st->num); +} + +void *sk_delete_ptr(_STACK *st, void *p) +{ + int i; + + for (i = 0; i < st->num; i++) + if (st->data[i] == p) + return (sk_delete(st, i)); + return (NULL); +} + +void *sk_delete(_STACK *st, int loc) +{ + char *ret; + int i, j; + + if (!st || (loc < 0) || (loc >= st->num)) + return NULL; + + ret = st->data[loc]; + if (loc != st->num - 1) { + j = st->num - 1; + for (i = loc; i < j; i++) + st->data[i] = st->data[i + 1]; + /* + * In theory memcpy is not safe for this memcpy( &(st->data[loc]), + * &(st->data[loc+1]), sizeof(char *)*(st->num-loc-1)); + */ + } + st->num--; + return (ret); +} + +static int internal_find(_STACK *st, void *data, int ret_val_options) +{ + const void *const *r; + int i; + + if (st == NULL) + return -1; + + if (st->comp == NULL) { + for (i = 0; i < st->num; i++) + if (st->data[i] == data) + return (i); + return (-1); + } + sk_sort(st); + if (data == NULL) + return (-1); + r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp, + ret_val_options); + if (r == NULL) + return (-1); + return (int)((char **)r - st->data); +} + +int sk_find(_STACK *st, void *data) +{ + return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH); +} + +int sk_find_ex(_STACK *st, void *data) +{ + return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH); +} + +int sk_push(_STACK *st, void *data) +{ + return (sk_insert(st, data, st->num)); +} + +int sk_unshift(_STACK *st, void *data) +{ + return (sk_insert(st, data, 0)); +} + +void *sk_shift(_STACK *st) +{ + if (st == NULL) + return (NULL); + if (st->num <= 0) + return (NULL); + return (sk_delete(st, 0)); +} + +void *sk_pop(_STACK *st) +{ + if (st == NULL) + return (NULL); + if (st->num <= 0) + return (NULL); + return (sk_delete(st, st->num - 1)); +} + +void sk_zero(_STACK *st) +{ + if (st == NULL) + return; + if (st->num <= 0) + return; + memset((char *)st->data, 0, sizeof(*st->data) * st->num); + st->num = 0; +} + +void sk_pop_free(_STACK *st, void (*func) (void *)) +{ + int i; + + if (st == NULL) + return; + for (i = 0; i < st->num; i++) + if (st->data[i] != NULL) + func(st->data[i]); + sk_free(st); +} + +void sk_free(_STACK *st) +{ + if (st == NULL) + return; + if (st->data != NULL) + OPENSSL_free(st->data); + OPENSSL_free(st); +} + +int sk_num(const _STACK *st) +{ + if (st == NULL) + return -1; + return st->num; +} + +void *sk_value(const _STACK *st, int i) +{ + if (!st || (i < 0) || (i >= st->num)) + return NULL; + return st->data[i]; +} + +void *sk_set(_STACK *st, int i, void *value) +{ + if (!st || (i < 0) || (i >= st->num)) + return NULL; + return (st->data[i] = value); +} + +void sk_sort(_STACK *st) +{ + if (st && !st->sorted) { + int (*comp_func) (const void *, const void *); + + /* + * same comment as in sk_find ... previously st->comp was declared as + * a (void*,void*) callback type, but this made the population of the + * callback pointer illogical - our callbacks compare type** with + * type**, so we leave the casting until absolutely necessary (ie. + * "now"). + */ + comp_func = (int (*)(const void *, const void *))(st->comp); + qsort(st->data, st->num, sizeof(char *), comp_func); + st->sorted = 1; + } +} + +int sk_is_sorted(const _STACK *st) +{ + if (!st) + return 1; + return st->sorted; +} diff --git a/libs/openssl/crypto/stack/stack.h b/libs/openssl/crypto/stack/stack.h new file mode 100644 index 00000000..8d6e939a --- /dev/null +++ b/libs/openssl/crypto/stack/stack.h @@ -0,0 +1,106 @@ +/* crypto/stack/stack.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_STACK_H +# define HEADER_STACK_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct stack_st { + int num; + char **data; + int sorted; + int num_alloc; + int (*comp) (const void *, const void *); +} _STACK; /* Use STACK_OF(...) instead */ + +# define M_sk_num(sk) ((sk) ? (sk)->num:-1) +# define M_sk_value(sk,n) ((sk) ? (sk)->data[n] : NULL) + +int sk_num(const _STACK *); +void *sk_value(const _STACK *, int); + +void *sk_set(_STACK *, int, void *); + +_STACK *sk_new(int (*cmp) (const void *, const void *)); +_STACK *sk_new_null(void); +void sk_free(_STACK *); +void sk_pop_free(_STACK *st, void (*func) (void *)); +int sk_insert(_STACK *sk, void *data, int where); +void *sk_delete(_STACK *st, int loc); +void *sk_delete_ptr(_STACK *st, void *p); +int sk_find(_STACK *st, void *data); +int sk_find_ex(_STACK *st, void *data); +int sk_push(_STACK *st, void *data); +int sk_unshift(_STACK *st, void *data); +void *sk_shift(_STACK *st); +void *sk_pop(_STACK *st); +void sk_zero(_STACK *st); +int (*sk_set_cmp_func(_STACK *sk, int (*c) (const void *, const void *))) + (const void *, const void *); +_STACK *sk_dup(_STACK *st); +void sk_sort(_STACK *st); +int sk_is_sorted(const _STACK *st); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/store/README b/libs/openssl/crypto/store/README new file mode 100644 index 00000000..966168f6 --- /dev/null +++ b/libs/openssl/crypto/store/README @@ -0,0 +1,95 @@ +The STORE type +============== + +A STORE, as defined in this code section, is really a rather simple +thing which stores objects and per-object associations to a number +of attributes. What attributes are supported entirely depends on +the particular implementation of a STORE. It has some support for +generation of certain objects (for example, keys and CRLs). + + +Supported object types +---------------------- + +For now, the objects that are supported are the following: + +X.509 certificate +X.509 CRL +private key +public key +number +arbitrary (application) data + +The intention is that a STORE should be able to store everything +needed by an application that wants a cert/key store, as well as +the data a CA might need to store (this includes the serial number +counter, which explains the support for numbers). + + +Supported attribute types +------------------------- + +For now, the following attributes are supported: + +Friendly Name - the value is a normal C string +Key ID - the value is a 160 bit SHA1 hash +Issuer Key ID - the value is a 160 bit SHA1 hash +Subject Key ID - the value is a 160 bit SHA1 hash +Issuer/Serial Hash - the value is a 160 bit SHA1 hash +Issuer - the value is a X509_NAME +Serial - the value is a BIGNUM +Subject - the value is a X509_NAME +Certificate Hash - the value is a 160 bit SHA1 hash +Email - the value is a normal C string +Filename - the value is a normal C string + +It is expected that these attributes should be enough to support +the need from most, if not all, current applications. Applications +that need to do certificate verification would typically use Subject +Key ID, Issuer/Serial Hash or Subject to look up issuer certificates. +S/MIME applications would typically use Email to look up recipient +and signer certificates. + +There's added support for combined sets of attributes to search for, +with the special OR attribute. + + +Supported basic functionality +----------------------------- + +The functions that are supported through the STORE type are these: + +generate_object - for example to generate keys and CRLs +get_object - to look up one object + NOTE: this function is really rather + redundant and probably of lesser usage + than the list functions +store_object - store an object and the attributes + associated with it +modify_object - modify the attributes associated with + a specific object +revoke_object - revoke an object + NOTE: this only marks an object as + invalid, it doesn't remove the object + from the database +delete_object - remove an object from the database +list_object - list objects associated with a given + set of attributes + NOTE: this is really four functions: + list_start, list_next, list_end and + list_endp +update_store - update the internal data of the store +lock_store - lock the store +unlock_store - unlock the store + +The list functions need some extra explanation: list_start is +used to set up a lookup. That's where the attributes to use in +the search are set up. It returns a search context. list_next +returns the next object searched for. list_end closes the search. +list_endp is used to check if we have reached the end. + +A few words on the store functions as well: update_store is +typically used by a CA application to update the internal +structure of a database. This may for example involve automatic +removal of expired certificates. lock_store and unlock_store +are used for locking a store to allow exclusive writes. diff --git a/libs/openssl/crypto/store/store.h b/libs/openssl/crypto/store/store.h new file mode 100644 index 00000000..ce3709d9 --- /dev/null +++ b/libs/openssl/crypto/store/store.h @@ -0,0 +1,658 @@ +/* crypto/store/store.h */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2003. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_STORE_H +# define HEADER_STORE_H + +# include + +# ifdef OPENSSL_NO_STORE +# error STORE is disabled. +# endif + +# include +# ifndef OPENSSL_NO_DEPRECATED +# include +# include +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* Already defined in ossl_typ.h */ +/* typedef struct store_st STORE; */ +/* typedef struct store_method_st STORE_METHOD; */ + +/* + * All the following functions return 0, a negative number or NULL on error. + * When everything is fine, they return a positive value or a non-NULL + * pointer, all depending on their purpose. + */ + +/* Creators and destructor. */ +STORE *STORE_new_method(const STORE_METHOD *method); +STORE *STORE_new_engine(ENGINE *engine); +void STORE_free(STORE *ui); + +/* + * Give a user interface parametrised control commands. This can be used to + * send down an integer, a data pointer or a function pointer, as well as be + * used to get information from a STORE. + */ +int STORE_ctrl(STORE *store, int cmd, long i, void *p, void (*f) (void)); + +/* + * A control to set the directory with keys and certificates. Used by the + * built-in directory level method. + */ +# define STORE_CTRL_SET_DIRECTORY 0x0001 +/* + * A control to set a file to load. Used by the built-in file level method. + */ +# define STORE_CTRL_SET_FILE 0x0002 +/* + * A control to set a configuration file to load. Can be used by any method + * that wishes to load a configuration file. + */ +# define STORE_CTRL_SET_CONF_FILE 0x0003 +/* + * A control to set a the section of the loaded configuration file. Can be + * used by any method that wishes to load a configuration file. + */ +# define STORE_CTRL_SET_CONF_SECTION 0x0004 + +/* Some methods may use extra data */ +# define STORE_set_app_data(s,arg) STORE_set_ex_data(s,0,arg) +# define STORE_get_app_data(s) STORE_get_ex_data(s,0) +int STORE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +int STORE_set_ex_data(STORE *r, int idx, void *arg); +void *STORE_get_ex_data(STORE *r, int idx); + +/* Use specific methods instead of the built-in one */ +const STORE_METHOD *STORE_get_method(STORE *store); +const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth); + +/* The standard OpenSSL methods. */ +/* + * This is the in-memory method. It does everything except revoking and + * updating, and is of course volatile. It's used by other methods that have + * an in-memory cache. + */ +const STORE_METHOD *STORE_Memory(void); +# if 0 /* Not yet implemented */ +/* + * This is the directory store. It does everything except revoking and + * updating, and uses STORE_Memory() to cache things in memory. + */ +const STORE_METHOD *STORE_Directory(void); +/* + * This is the file store. It does everything except revoking and updating, + * and uses STORE_Memory() to cache things in memory. Certificates are added + * to it with the store operation, and it will only get cached certificates. + */ +const STORE_METHOD *STORE_File(void); +# endif + +/* + * Store functions take a type code for the type of data they should store or + * fetch + */ +typedef enum STORE_object_types { + STORE_OBJECT_TYPE_X509_CERTIFICATE = 0x01, /* X509 * */ + STORE_OBJECT_TYPE_X509_CRL = 0x02, /* X509_CRL * */ + STORE_OBJECT_TYPE_PRIVATE_KEY = 0x03, /* EVP_PKEY * */ + STORE_OBJECT_TYPE_PUBLIC_KEY = 0x04, /* EVP_PKEY * */ + STORE_OBJECT_TYPE_NUMBER = 0x05, /* BIGNUM * */ + STORE_OBJECT_TYPE_ARBITRARY = 0x06, /* BUF_MEM * */ + STORE_OBJECT_TYPE_NUM = 0x06 /* The amount of known object types */ +} STORE_OBJECT_TYPES; +/* List of text strings corresponding to the object types. */ +extern const char *const STORE_object_type_string[STORE_OBJECT_TYPE_NUM + 1]; + +/* + * Some store functions take a parameter list. Those parameters come with + * one of the following codes. The comments following the codes below + * indicate what type the value should be a pointer to. + */ +typedef enum STORE_params { + STORE_PARAM_EVP_TYPE = 0x01, /* int */ + STORE_PARAM_BITS = 0x02, /* size_t */ + STORE_PARAM_KEY_PARAMETERS = 0x03, /* ??? */ + STORE_PARAM_KEY_NO_PARAMETERS = 0x04, /* N/A */ + STORE_PARAM_AUTH_PASSPHRASE = 0x05, /* char * */ + STORE_PARAM_AUTH_KRB5_TICKET = 0x06, /* void * */ + STORE_PARAM_TYPE_NUM = 0x06 /* The amount of known parameter types */ +} STORE_PARAM_TYPES; +/* + * Parameter value sizes. -1 means unknown, anything else is the required + * size. + */ +extern const int STORE_param_sizes[STORE_PARAM_TYPE_NUM + 1]; + +/* + * Store functions take attribute lists. Those attributes come with codes. + * The comments following the codes below indicate what type the value should + * be a pointer to. + */ +typedef enum STORE_attribs { + STORE_ATTR_END = 0x00, + STORE_ATTR_FRIENDLYNAME = 0x01, /* C string */ + STORE_ATTR_KEYID = 0x02, /* 160 bit string (SHA1) */ + STORE_ATTR_ISSUERKEYID = 0x03, /* 160 bit string (SHA1) */ + STORE_ATTR_SUBJECTKEYID = 0x04, /* 160 bit string (SHA1) */ + STORE_ATTR_ISSUERSERIALHASH = 0x05, /* 160 bit string (SHA1) */ + STORE_ATTR_ISSUER = 0x06, /* X509_NAME * */ + STORE_ATTR_SERIAL = 0x07, /* BIGNUM * */ + STORE_ATTR_SUBJECT = 0x08, /* X509_NAME * */ + STORE_ATTR_CERTHASH = 0x09, /* 160 bit string (SHA1) */ + STORE_ATTR_EMAIL = 0x0a, /* C string */ + STORE_ATTR_FILENAME = 0x0b, /* C string */ + STORE_ATTR_TYPE_NUM = 0x0b, /* The amount of known attribute types */ + STORE_ATTR_OR = 0xff /* This is a special separator, which + * expresses the OR operation. */ +} STORE_ATTR_TYPES; +/* + * Attribute value sizes. -1 means unknown, anything else is the required + * size. + */ +extern const int STORE_attr_sizes[STORE_ATTR_TYPE_NUM + 1]; + +typedef enum STORE_certificate_status { + STORE_X509_VALID = 0x00, + STORE_X509_EXPIRED = 0x01, + STORE_X509_SUSPENDED = 0x02, + STORE_X509_REVOKED = 0x03 +} STORE_CERTIFICATE_STATUS; + +/* + * Engine store functions will return a structure that contains all the + * necessary information, including revokation status for certificates. This + * is really not needed for application authors, as the ENGINE framework + * functions will extract the OpenSSL-specific information when at all + * possible. However, for engine authors, it's crucial to know this + * structure. + */ +typedef struct STORE_OBJECT_st { + STORE_OBJECT_TYPES type; + union { + struct { + STORE_CERTIFICATE_STATUS status; + X509 *certificate; + } x509; + X509_CRL *crl; + EVP_PKEY *key; + BIGNUM *number; + BUF_MEM *arbitrary; + } data; +} STORE_OBJECT; +DECLARE_STACK_OF(STORE_OBJECT) +STORE_OBJECT *STORE_OBJECT_new(void); +void STORE_OBJECT_free(STORE_OBJECT *data); + +/* + * The following functions handle the storage. They return 0, a negative + * number or NULL on error, anything else on success. + */ +X509 *STORE_get_certificate(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_store_certificate(STORE *e, X509 *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_modify_certificate(STORE *e, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]); +int STORE_revoke_certificate(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_delete_certificate(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +void *STORE_list_certificate_start(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +X509 *STORE_list_certificate_next(STORE *e, void *handle); +int STORE_list_certificate_end(STORE *e, void *handle); +int STORE_list_certificate_endp(STORE *e, void *handle); +EVP_PKEY *STORE_generate_key(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +EVP_PKEY *STORE_get_private_key(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_store_private_key(STORE *e, EVP_PKEY *data, + OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_modify_private_key(STORE *e, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_sttributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]); +int STORE_revoke_private_key(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_delete_private_key(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +void *STORE_list_private_key_start(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +EVP_PKEY *STORE_list_private_key_next(STORE *e, void *handle); +int STORE_list_private_key_end(STORE *e, void *handle); +int STORE_list_private_key_endp(STORE *e, void *handle); +EVP_PKEY *STORE_get_public_key(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_store_public_key(STORE *e, EVP_PKEY *data, + OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_modify_public_key(STORE *e, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_sttributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]); +int STORE_revoke_public_key(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_delete_public_key(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +void *STORE_list_public_key_start(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +EVP_PKEY *STORE_list_public_key_next(STORE *e, void *handle); +int STORE_list_public_key_end(STORE *e, void *handle); +int STORE_list_public_key_endp(STORE *e, void *handle); +X509_CRL *STORE_generate_crl(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +X509_CRL *STORE_get_crl(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_store_crl(STORE *e, X509_CRL *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_modify_crl(STORE *e, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_sttributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]); +int STORE_delete_crl(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +void *STORE_list_crl_start(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +X509_CRL *STORE_list_crl_next(STORE *e, void *handle); +int STORE_list_crl_end(STORE *e, void *handle); +int STORE_list_crl_endp(STORE *e, void *handle); +int STORE_store_number(STORE *e, BIGNUM *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_modify_number(STORE *e, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_sttributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]); +BIGNUM *STORE_get_number(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_delete_number(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_store_arbitrary(STORE *e, BUF_MEM *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_modify_arbitrary(STORE *e, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_sttributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]); +BUF_MEM *STORE_get_arbitrary(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +int STORE_delete_arbitrary(STORE *e, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); + +/* Create and manipulate methods */ +STORE_METHOD *STORE_create_method(char *name); +void STORE_destroy_method(STORE_METHOD *store_method); + +/* These callback types are use for store handlers */ +typedef int (*STORE_INITIALISE_FUNC_PTR) (STORE *); +typedef void (*STORE_CLEANUP_FUNC_PTR) (STORE *); +typedef STORE_OBJECT *(*STORE_GENERATE_OBJECT_FUNC_PTR)(STORE *, + STORE_OBJECT_TYPES + type, + OPENSSL_ITEM + attributes[], + OPENSSL_ITEM + parameters[]); +typedef STORE_OBJECT *(*STORE_GET_OBJECT_FUNC_PTR)(STORE *, + STORE_OBJECT_TYPES type, + OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +typedef void *(*STORE_START_OBJECT_FUNC_PTR)(STORE *, STORE_OBJECT_TYPES type, + OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +typedef STORE_OBJECT *(*STORE_NEXT_OBJECT_FUNC_PTR)(STORE *, void *handle); +typedef int (*STORE_END_OBJECT_FUNC_PTR) (STORE *, void *handle); +typedef int (*STORE_HANDLE_OBJECT_FUNC_PTR) (STORE *, STORE_OBJECT_TYPES type, + OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +typedef int (*STORE_STORE_OBJECT_FUNC_PTR) (STORE *, STORE_OBJECT_TYPES type, + STORE_OBJECT *data, + OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +typedef int (*STORE_MODIFY_OBJECT_FUNC_PTR) (STORE *, STORE_OBJECT_TYPES type, + OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]); +typedef int (*STORE_GENERIC_FUNC_PTR) (STORE *, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +typedef int (*STORE_CTRL_FUNC_PTR) (STORE *, int cmd, long l, void *p, + void (*f) (void)); + +int STORE_method_set_initialise_function(STORE_METHOD *sm, + STORE_INITIALISE_FUNC_PTR init_f); +int STORE_method_set_cleanup_function(STORE_METHOD *sm, + STORE_CLEANUP_FUNC_PTR clean_f); +int STORE_method_set_generate_function(STORE_METHOD *sm, + STORE_GENERATE_OBJECT_FUNC_PTR + generate_f); +int STORE_method_set_get_function(STORE_METHOD *sm, + STORE_GET_OBJECT_FUNC_PTR get_f); +int STORE_method_set_store_function(STORE_METHOD *sm, + STORE_STORE_OBJECT_FUNC_PTR store_f); +int STORE_method_set_modify_function(STORE_METHOD *sm, + STORE_MODIFY_OBJECT_FUNC_PTR store_f); +int STORE_method_set_revoke_function(STORE_METHOD *sm, + STORE_HANDLE_OBJECT_FUNC_PTR revoke_f); +int STORE_method_set_delete_function(STORE_METHOD *sm, + STORE_HANDLE_OBJECT_FUNC_PTR delete_f); +int STORE_method_set_list_start_function(STORE_METHOD *sm, + STORE_START_OBJECT_FUNC_PTR + list_start_f); +int STORE_method_set_list_next_function(STORE_METHOD *sm, + STORE_NEXT_OBJECT_FUNC_PTR + list_next_f); +int STORE_method_set_list_end_function(STORE_METHOD *sm, + STORE_END_OBJECT_FUNC_PTR list_end_f); +int STORE_method_set_update_store_function(STORE_METHOD *sm, + STORE_GENERIC_FUNC_PTR); +int STORE_method_set_lock_store_function(STORE_METHOD *sm, + STORE_GENERIC_FUNC_PTR); +int STORE_method_set_unlock_store_function(STORE_METHOD *sm, + STORE_GENERIC_FUNC_PTR); +int STORE_method_set_ctrl_function(STORE_METHOD *sm, + STORE_CTRL_FUNC_PTR ctrl_f); + +STORE_INITIALISE_FUNC_PTR STORE_method_get_initialise_function(STORE_METHOD + *sm); +STORE_CLEANUP_FUNC_PTR STORE_method_get_cleanup_function(STORE_METHOD *sm); +STORE_GENERATE_OBJECT_FUNC_PTR STORE_method_get_generate_function(STORE_METHOD + *sm); +STORE_GET_OBJECT_FUNC_PTR STORE_method_get_get_function(STORE_METHOD *sm); +STORE_STORE_OBJECT_FUNC_PTR STORE_method_get_store_function(STORE_METHOD *sm); +STORE_MODIFY_OBJECT_FUNC_PTR STORE_method_get_modify_function(STORE_METHOD + *sm); +STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_revoke_function(STORE_METHOD + *sm); +STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_delete_function(STORE_METHOD + *sm); +STORE_START_OBJECT_FUNC_PTR STORE_method_get_list_start_function(STORE_METHOD + *sm); +STORE_NEXT_OBJECT_FUNC_PTR STORE_method_get_list_next_function(STORE_METHOD + *sm); +STORE_END_OBJECT_FUNC_PTR STORE_method_get_list_end_function(STORE_METHOD + *sm); +STORE_GENERIC_FUNC_PTR STORE_method_get_update_store_function(STORE_METHOD + *sm); +STORE_GENERIC_FUNC_PTR STORE_method_get_lock_store_function(STORE_METHOD *sm); +STORE_GENERIC_FUNC_PTR STORE_method_get_unlock_store_function(STORE_METHOD + *sm); +STORE_CTRL_FUNC_PTR STORE_method_get_ctrl_function(STORE_METHOD *sm); + +/* Method helper structures and functions. */ + +/* + * This structure is the result of parsing through the information in a list + * of OPENSSL_ITEMs. It stores all the necessary information in a structured + * way. + */ +typedef struct STORE_attr_info_st STORE_ATTR_INFO; + +/* + * Parse a list of OPENSSL_ITEMs and return a pointer to a STORE_ATTR_INFO. + * Note that we do this in the list form, since the list of OPENSSL_ITEMs can + * come in blocks separated with STORE_ATTR_OR. Note that the value returned + * by STORE_parse_attrs_next() must be freed with STORE_ATTR_INFO_free(). + */ +void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes); +STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle); +int STORE_parse_attrs_end(void *handle); +int STORE_parse_attrs_endp(void *handle); + +/* Creator and destructor */ +STORE_ATTR_INFO *STORE_ATTR_INFO_new(void); +int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs); + +/* Manipulators */ +char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, + STORE_ATTR_TYPES code); +unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs, + STORE_ATTR_TYPES code); +X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, + STORE_ATTR_TYPES code); +BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, + STORE_ATTR_TYPES code); +int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + char *cstr, size_t cstr_size); +int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + unsigned char *sha1str, size_t sha1str_size); +int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + X509_NAME *dn); +int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + BIGNUM *number); +int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + char *cstr, size_t cstr_size); +int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, + STORE_ATTR_TYPES code, + unsigned char *sha1str, + size_t sha1str_size); +int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + X509_NAME *dn); +int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, + STORE_ATTR_TYPES code, BIGNUM *number); + +/* + * Compare on basis of a bit pattern formed by the STORE_ATTR_TYPES values in + * each contained attribute. + */ +int STORE_ATTR_INFO_compare(const STORE_ATTR_INFO *const *a, + const STORE_ATTR_INFO *const *b); +/* + * Check if the set of attributes in a is within the range of attributes set + * in b. + */ +int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b); +/* Check if the set of attributes in a are also set in b. */ +int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b); +/* Same as STORE_ATTR_INFO_in(), but also checks the attribute values. */ +int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_STORE_strings(void); + +/* Error codes for the STORE functions. */ + +/* Function codes. */ +# define STORE_F_MEM_DELETE 134 +# define STORE_F_MEM_GENERATE 135 +# define STORE_F_MEM_LIST_END 168 +# define STORE_F_MEM_LIST_NEXT 136 +# define STORE_F_MEM_LIST_START 137 +# define STORE_F_MEM_MODIFY 169 +# define STORE_F_MEM_STORE 138 +# define STORE_F_STORE_ATTR_INFO_GET0_CSTR 139 +# define STORE_F_STORE_ATTR_INFO_GET0_DN 140 +# define STORE_F_STORE_ATTR_INFO_GET0_NUMBER 141 +# define STORE_F_STORE_ATTR_INFO_GET0_SHA1STR 142 +# define STORE_F_STORE_ATTR_INFO_MODIFY_CSTR 143 +# define STORE_F_STORE_ATTR_INFO_MODIFY_DN 144 +# define STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER 145 +# define STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR 146 +# define STORE_F_STORE_ATTR_INFO_SET_CSTR 147 +# define STORE_F_STORE_ATTR_INFO_SET_DN 148 +# define STORE_F_STORE_ATTR_INFO_SET_NUMBER 149 +# define STORE_F_STORE_ATTR_INFO_SET_SHA1STR 150 +# define STORE_F_STORE_CERTIFICATE 170 +# define STORE_F_STORE_CTRL 161 +# define STORE_F_STORE_DELETE_ARBITRARY 158 +# define STORE_F_STORE_DELETE_CERTIFICATE 102 +# define STORE_F_STORE_DELETE_CRL 103 +# define STORE_F_STORE_DELETE_NUMBER 104 +# define STORE_F_STORE_DELETE_PRIVATE_KEY 105 +# define STORE_F_STORE_DELETE_PUBLIC_KEY 106 +# define STORE_F_STORE_GENERATE_CRL 107 +# define STORE_F_STORE_GENERATE_KEY 108 +# define STORE_F_STORE_GET_ARBITRARY 159 +# define STORE_F_STORE_GET_CERTIFICATE 109 +# define STORE_F_STORE_GET_CRL 110 +# define STORE_F_STORE_GET_NUMBER 111 +# define STORE_F_STORE_GET_PRIVATE_KEY 112 +# define STORE_F_STORE_GET_PUBLIC_KEY 113 +# define STORE_F_STORE_LIST_CERTIFICATE_END 114 +# define STORE_F_STORE_LIST_CERTIFICATE_ENDP 153 +# define STORE_F_STORE_LIST_CERTIFICATE_NEXT 115 +# define STORE_F_STORE_LIST_CERTIFICATE_START 116 +# define STORE_F_STORE_LIST_CRL_END 117 +# define STORE_F_STORE_LIST_CRL_ENDP 154 +# define STORE_F_STORE_LIST_CRL_NEXT 118 +# define STORE_F_STORE_LIST_CRL_START 119 +# define STORE_F_STORE_LIST_PRIVATE_KEY_END 120 +# define STORE_F_STORE_LIST_PRIVATE_KEY_ENDP 155 +# define STORE_F_STORE_LIST_PRIVATE_KEY_NEXT 121 +# define STORE_F_STORE_LIST_PRIVATE_KEY_START 122 +# define STORE_F_STORE_LIST_PUBLIC_KEY_END 123 +# define STORE_F_STORE_LIST_PUBLIC_KEY_ENDP 156 +# define STORE_F_STORE_LIST_PUBLIC_KEY_NEXT 124 +# define STORE_F_STORE_LIST_PUBLIC_KEY_START 125 +# define STORE_F_STORE_MODIFY_ARBITRARY 162 +# define STORE_F_STORE_MODIFY_CERTIFICATE 163 +# define STORE_F_STORE_MODIFY_CRL 164 +# define STORE_F_STORE_MODIFY_NUMBER 165 +# define STORE_F_STORE_MODIFY_PRIVATE_KEY 166 +# define STORE_F_STORE_MODIFY_PUBLIC_KEY 167 +# define STORE_F_STORE_NEW_ENGINE 133 +# define STORE_F_STORE_NEW_METHOD 132 +# define STORE_F_STORE_PARSE_ATTRS_END 151 +# define STORE_F_STORE_PARSE_ATTRS_ENDP 172 +# define STORE_F_STORE_PARSE_ATTRS_NEXT 152 +# define STORE_F_STORE_PARSE_ATTRS_START 171 +# define STORE_F_STORE_REVOKE_CERTIFICATE 129 +# define STORE_F_STORE_REVOKE_PRIVATE_KEY 130 +# define STORE_F_STORE_REVOKE_PUBLIC_KEY 131 +# define STORE_F_STORE_STORE_ARBITRARY 157 +# define STORE_F_STORE_STORE_CERTIFICATE 100 +# define STORE_F_STORE_STORE_CRL 101 +# define STORE_F_STORE_STORE_NUMBER 126 +# define STORE_F_STORE_STORE_PRIVATE_KEY 127 +# define STORE_F_STORE_STORE_PUBLIC_KEY 128 + +/* Reason codes. */ +# define STORE_R_ALREADY_HAS_A_VALUE 127 +# define STORE_R_FAILED_DELETING_ARBITRARY 132 +# define STORE_R_FAILED_DELETING_CERTIFICATE 100 +# define STORE_R_FAILED_DELETING_KEY 101 +# define STORE_R_FAILED_DELETING_NUMBER 102 +# define STORE_R_FAILED_GENERATING_CRL 103 +# define STORE_R_FAILED_GENERATING_KEY 104 +# define STORE_R_FAILED_GETTING_ARBITRARY 133 +# define STORE_R_FAILED_GETTING_CERTIFICATE 105 +# define STORE_R_FAILED_GETTING_KEY 106 +# define STORE_R_FAILED_GETTING_NUMBER 107 +# define STORE_R_FAILED_LISTING_CERTIFICATES 108 +# define STORE_R_FAILED_LISTING_KEYS 109 +# define STORE_R_FAILED_MODIFYING_ARBITRARY 138 +# define STORE_R_FAILED_MODIFYING_CERTIFICATE 139 +# define STORE_R_FAILED_MODIFYING_CRL 140 +# define STORE_R_FAILED_MODIFYING_NUMBER 141 +# define STORE_R_FAILED_MODIFYING_PRIVATE_KEY 142 +# define STORE_R_FAILED_MODIFYING_PUBLIC_KEY 143 +# define STORE_R_FAILED_REVOKING_CERTIFICATE 110 +# define STORE_R_FAILED_REVOKING_KEY 111 +# define STORE_R_FAILED_STORING_ARBITRARY 134 +# define STORE_R_FAILED_STORING_CERTIFICATE 112 +# define STORE_R_FAILED_STORING_KEY 113 +# define STORE_R_FAILED_STORING_NUMBER 114 +# define STORE_R_NOT_IMPLEMENTED 128 +# define STORE_R_NO_CONTROL_FUNCTION 144 +# define STORE_R_NO_DELETE_ARBITRARY_FUNCTION 135 +# define STORE_R_NO_DELETE_NUMBER_FUNCTION 115 +# define STORE_R_NO_DELETE_OBJECT_FUNCTION 116 +# define STORE_R_NO_GENERATE_CRL_FUNCTION 117 +# define STORE_R_NO_GENERATE_OBJECT_FUNCTION 118 +# define STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION 136 +# define STORE_R_NO_GET_OBJECT_FUNCTION 119 +# define STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION 120 +# define STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION 131 +# define STORE_R_NO_LIST_OBJECT_END_FUNCTION 121 +# define STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION 122 +# define STORE_R_NO_LIST_OBJECT_START_FUNCTION 123 +# define STORE_R_NO_MODIFY_OBJECT_FUNCTION 145 +# define STORE_R_NO_REVOKE_OBJECT_FUNCTION 124 +# define STORE_R_NO_STORE 129 +# define STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION 137 +# define STORE_R_NO_STORE_OBJECT_FUNCTION 125 +# define STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION 126 +# define STORE_R_NO_VALUE 130 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/store/str_err.c b/libs/openssl/crypto/store/str_err.c new file mode 100644 index 00000000..9858e606 --- /dev/null +++ b/libs/openssl/crypto/store/str_err.c @@ -0,0 +1,258 @@ +/* crypto/store/str_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_STORE,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_STORE,0,reason) + +static ERR_STRING_DATA STORE_str_functs[] = { + {ERR_FUNC(STORE_F_MEM_DELETE), "MEM_DELETE"}, + {ERR_FUNC(STORE_F_MEM_GENERATE), "MEM_GENERATE"}, + {ERR_FUNC(STORE_F_MEM_LIST_END), "MEM_LIST_END"}, + {ERR_FUNC(STORE_F_MEM_LIST_NEXT), "MEM_LIST_NEXT"}, + {ERR_FUNC(STORE_F_MEM_LIST_START), "MEM_LIST_START"}, + {ERR_FUNC(STORE_F_MEM_MODIFY), "MEM_MODIFY"}, + {ERR_FUNC(STORE_F_MEM_STORE), "MEM_STORE"}, + {ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_CSTR), + "STORE_ATTR_INFO_get0_cstr"}, + {ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_DN), "STORE_ATTR_INFO_get0_dn"}, + {ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_NUMBER), + "STORE_ATTR_INFO_get0_number"}, + {ERR_FUNC(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR), + "STORE_ATTR_INFO_get0_sha1str"}, + {ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_CSTR), + "STORE_ATTR_INFO_modify_cstr"}, + {ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_DN), + "STORE_ATTR_INFO_modify_dn"}, + {ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER), + "STORE_ATTR_INFO_modify_number"}, + {ERR_FUNC(STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR), + "STORE_ATTR_INFO_modify_sha1str"}, + {ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_CSTR), "STORE_ATTR_INFO_set_cstr"}, + {ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_DN), "STORE_ATTR_INFO_set_dn"}, + {ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_NUMBER), + "STORE_ATTR_INFO_set_number"}, + {ERR_FUNC(STORE_F_STORE_ATTR_INFO_SET_SHA1STR), + "STORE_ATTR_INFO_set_sha1str"}, + {ERR_FUNC(STORE_F_STORE_CERTIFICATE), "STORE_CERTIFICATE"}, + {ERR_FUNC(STORE_F_STORE_CTRL), "STORE_ctrl"}, + {ERR_FUNC(STORE_F_STORE_DELETE_ARBITRARY), "STORE_delete_arbitrary"}, + {ERR_FUNC(STORE_F_STORE_DELETE_CERTIFICATE), "STORE_delete_certificate"}, + {ERR_FUNC(STORE_F_STORE_DELETE_CRL), "STORE_delete_crl"}, + {ERR_FUNC(STORE_F_STORE_DELETE_NUMBER), "STORE_delete_number"}, + {ERR_FUNC(STORE_F_STORE_DELETE_PRIVATE_KEY), "STORE_delete_private_key"}, + {ERR_FUNC(STORE_F_STORE_DELETE_PUBLIC_KEY), "STORE_delete_public_key"}, + {ERR_FUNC(STORE_F_STORE_GENERATE_CRL), "STORE_generate_crl"}, + {ERR_FUNC(STORE_F_STORE_GENERATE_KEY), "STORE_generate_key"}, + {ERR_FUNC(STORE_F_STORE_GET_ARBITRARY), "STORE_get_arbitrary"}, + {ERR_FUNC(STORE_F_STORE_GET_CERTIFICATE), "STORE_get_certificate"}, + {ERR_FUNC(STORE_F_STORE_GET_CRL), "STORE_get_crl"}, + {ERR_FUNC(STORE_F_STORE_GET_NUMBER), "STORE_get_number"}, + {ERR_FUNC(STORE_F_STORE_GET_PRIVATE_KEY), "STORE_get_private_key"}, + {ERR_FUNC(STORE_F_STORE_GET_PUBLIC_KEY), "STORE_get_public_key"}, + {ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_END), + "STORE_list_certificate_end"}, + {ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_ENDP), + "STORE_list_certificate_endp"}, + {ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_NEXT), + "STORE_list_certificate_next"}, + {ERR_FUNC(STORE_F_STORE_LIST_CERTIFICATE_START), + "STORE_list_certificate_start"}, + {ERR_FUNC(STORE_F_STORE_LIST_CRL_END), "STORE_list_crl_end"}, + {ERR_FUNC(STORE_F_STORE_LIST_CRL_ENDP), "STORE_list_crl_endp"}, + {ERR_FUNC(STORE_F_STORE_LIST_CRL_NEXT), "STORE_list_crl_next"}, + {ERR_FUNC(STORE_F_STORE_LIST_CRL_START), "STORE_list_crl_start"}, + {ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_END), + "STORE_list_private_key_end"}, + {ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_ENDP), + "STORE_list_private_key_endp"}, + {ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_NEXT), + "STORE_list_private_key_next"}, + {ERR_FUNC(STORE_F_STORE_LIST_PRIVATE_KEY_START), + "STORE_list_private_key_start"}, + {ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_END), + "STORE_list_public_key_end"}, + {ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_ENDP), + "STORE_list_public_key_endp"}, + {ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_NEXT), + "STORE_list_public_key_next"}, + {ERR_FUNC(STORE_F_STORE_LIST_PUBLIC_KEY_START), + "STORE_list_public_key_start"}, + {ERR_FUNC(STORE_F_STORE_MODIFY_ARBITRARY), "STORE_modify_arbitrary"}, + {ERR_FUNC(STORE_F_STORE_MODIFY_CERTIFICATE), "STORE_modify_certificate"}, + {ERR_FUNC(STORE_F_STORE_MODIFY_CRL), "STORE_modify_crl"}, + {ERR_FUNC(STORE_F_STORE_MODIFY_NUMBER), "STORE_modify_number"}, + {ERR_FUNC(STORE_F_STORE_MODIFY_PRIVATE_KEY), "STORE_modify_private_key"}, + {ERR_FUNC(STORE_F_STORE_MODIFY_PUBLIC_KEY), "STORE_modify_public_key"}, + {ERR_FUNC(STORE_F_STORE_NEW_ENGINE), "STORE_new_engine"}, + {ERR_FUNC(STORE_F_STORE_NEW_METHOD), "STORE_new_method"}, + {ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_END), "STORE_parse_attrs_end"}, + {ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_ENDP), "STORE_parse_attrs_endp"}, + {ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_NEXT), "STORE_parse_attrs_next"}, + {ERR_FUNC(STORE_F_STORE_PARSE_ATTRS_START), "STORE_parse_attrs_start"}, + {ERR_FUNC(STORE_F_STORE_REVOKE_CERTIFICATE), "STORE_revoke_certificate"}, + {ERR_FUNC(STORE_F_STORE_REVOKE_PRIVATE_KEY), "STORE_revoke_private_key"}, + {ERR_FUNC(STORE_F_STORE_REVOKE_PUBLIC_KEY), "STORE_revoke_public_key"}, + {ERR_FUNC(STORE_F_STORE_STORE_ARBITRARY), "STORE_store_arbitrary"}, + {ERR_FUNC(STORE_F_STORE_STORE_CERTIFICATE), "STORE_store_certificate"}, + {ERR_FUNC(STORE_F_STORE_STORE_CRL), "STORE_store_crl"}, + {ERR_FUNC(STORE_F_STORE_STORE_NUMBER), "STORE_store_number"}, + {ERR_FUNC(STORE_F_STORE_STORE_PRIVATE_KEY), "STORE_store_private_key"}, + {ERR_FUNC(STORE_F_STORE_STORE_PUBLIC_KEY), "STORE_store_public_key"}, + {0, NULL} +}; + +static ERR_STRING_DATA STORE_str_reasons[] = { + {ERR_REASON(STORE_R_ALREADY_HAS_A_VALUE), "already has a value"}, + {ERR_REASON(STORE_R_FAILED_DELETING_ARBITRARY), + "failed deleting arbitrary"}, + {ERR_REASON(STORE_R_FAILED_DELETING_CERTIFICATE), + "failed deleting certificate"}, + {ERR_REASON(STORE_R_FAILED_DELETING_KEY), "failed deleting key"}, + {ERR_REASON(STORE_R_FAILED_DELETING_NUMBER), "failed deleting number"}, + {ERR_REASON(STORE_R_FAILED_GENERATING_CRL), "failed generating crl"}, + {ERR_REASON(STORE_R_FAILED_GENERATING_KEY), "failed generating key"}, + {ERR_REASON(STORE_R_FAILED_GETTING_ARBITRARY), + "failed getting arbitrary"}, + {ERR_REASON(STORE_R_FAILED_GETTING_CERTIFICATE), + "failed getting certificate"}, + {ERR_REASON(STORE_R_FAILED_GETTING_KEY), "failed getting key"}, + {ERR_REASON(STORE_R_FAILED_GETTING_NUMBER), "failed getting number"}, + {ERR_REASON(STORE_R_FAILED_LISTING_CERTIFICATES), + "failed listing certificates"}, + {ERR_REASON(STORE_R_FAILED_LISTING_KEYS), "failed listing keys"}, + {ERR_REASON(STORE_R_FAILED_MODIFYING_ARBITRARY), + "failed modifying arbitrary"}, + {ERR_REASON(STORE_R_FAILED_MODIFYING_CERTIFICATE), + "failed modifying certificate"}, + {ERR_REASON(STORE_R_FAILED_MODIFYING_CRL), "failed modifying crl"}, + {ERR_REASON(STORE_R_FAILED_MODIFYING_NUMBER), "failed modifying number"}, + {ERR_REASON(STORE_R_FAILED_MODIFYING_PRIVATE_KEY), + "failed modifying private key"}, + {ERR_REASON(STORE_R_FAILED_MODIFYING_PUBLIC_KEY), + "failed modifying public key"}, + {ERR_REASON(STORE_R_FAILED_REVOKING_CERTIFICATE), + "failed revoking certificate"}, + {ERR_REASON(STORE_R_FAILED_REVOKING_KEY), "failed revoking key"}, + {ERR_REASON(STORE_R_FAILED_STORING_ARBITRARY), + "failed storing arbitrary"}, + {ERR_REASON(STORE_R_FAILED_STORING_CERTIFICATE), + "failed storing certificate"}, + {ERR_REASON(STORE_R_FAILED_STORING_KEY), "failed storing key"}, + {ERR_REASON(STORE_R_FAILED_STORING_NUMBER), "failed storing number"}, + {ERR_REASON(STORE_R_NOT_IMPLEMENTED), "not implemented"}, + {ERR_REASON(STORE_R_NO_CONTROL_FUNCTION), "no control function"}, + {ERR_REASON(STORE_R_NO_DELETE_ARBITRARY_FUNCTION), + "no delete arbitrary function"}, + {ERR_REASON(STORE_R_NO_DELETE_NUMBER_FUNCTION), + "no delete number function"}, + {ERR_REASON(STORE_R_NO_DELETE_OBJECT_FUNCTION), + "no delete object function"}, + {ERR_REASON(STORE_R_NO_GENERATE_CRL_FUNCTION), + "no generate crl function"}, + {ERR_REASON(STORE_R_NO_GENERATE_OBJECT_FUNCTION), + "no generate object function"}, + {ERR_REASON(STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION), + "no get object arbitrary function"}, + {ERR_REASON(STORE_R_NO_GET_OBJECT_FUNCTION), "no get object function"}, + {ERR_REASON(STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION), + "no get object number function"}, + {ERR_REASON(STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION), + "no list object endp function"}, + {ERR_REASON(STORE_R_NO_LIST_OBJECT_END_FUNCTION), + "no list object end function"}, + {ERR_REASON(STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION), + "no list object next function"}, + {ERR_REASON(STORE_R_NO_LIST_OBJECT_START_FUNCTION), + "no list object start function"}, + {ERR_REASON(STORE_R_NO_MODIFY_OBJECT_FUNCTION), + "no modify object function"}, + {ERR_REASON(STORE_R_NO_REVOKE_OBJECT_FUNCTION), + "no revoke object function"}, + {ERR_REASON(STORE_R_NO_STORE), "no store"}, + {ERR_REASON(STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION), + "no store object arbitrary function"}, + {ERR_REASON(STORE_R_NO_STORE_OBJECT_FUNCTION), + "no store object function"}, + {ERR_REASON(STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION), + "no store object number function"}, + {ERR_REASON(STORE_R_NO_VALUE), "no value"}, + {0, NULL} +}; + +#endif + +void ERR_load_STORE_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(STORE_str_functs[0].error) == NULL) { + ERR_load_strings(0, STORE_str_functs); + ERR_load_strings(0, STORE_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/store/str_lib.c b/libs/openssl/crypto/store/str_lib.c new file mode 100644 index 00000000..e3d5da93 --- /dev/null +++ b/libs/openssl/crypto/store/str_lib.c @@ -0,0 +1,1772 @@ +/* crypto/store/str_lib.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2003. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include +#include +#include "str_locl.h" + +const char *const STORE_object_type_string[STORE_OBJECT_TYPE_NUM + 1] = { + 0, + "X.509 Certificate", + "X.509 CRL", + "Private Key", + "Public Key", + "Number", + "Arbitrary Data" +}; + +const int STORE_param_sizes[STORE_PARAM_TYPE_NUM + 1] = { + 0, + sizeof(int), /* EVP_TYPE */ + sizeof(size_t), /* BITS */ + -1, /* KEY_PARAMETERS */ + 0 /* KEY_NO_PARAMETERS */ +}; + +const int STORE_attr_sizes[STORE_ATTR_TYPE_NUM + 1] = { + 0, + -1, /* FRIENDLYNAME: C string */ + SHA_DIGEST_LENGTH, /* KEYID: SHA1 digest, 160 bits */ + SHA_DIGEST_LENGTH, /* ISSUERKEYID: SHA1 digest, 160 bits */ + SHA_DIGEST_LENGTH, /* SUBJECTKEYID: SHA1 digest, 160 bits */ + SHA_DIGEST_LENGTH, /* ISSUERSERIALHASH: SHA1 digest, 160 bits */ + sizeof(X509_NAME *), /* ISSUER: X509_NAME * */ + sizeof(BIGNUM *), /* SERIAL: BIGNUM * */ + sizeof(X509_NAME *), /* SUBJECT: X509_NAME * */ + SHA_DIGEST_LENGTH, /* CERTHASH: SHA1 digest, 160 bits */ + -1, /* EMAIL: C string */ + -1, /* FILENAME: C string */ +}; + +STORE *STORE_new_method(const STORE_METHOD *method) +{ + STORE *ret; + + if (method == NULL) { + STOREerr(STORE_F_STORE_NEW_METHOD, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + ret = (STORE *)OPENSSL_malloc(sizeof(STORE)); + if (ret == NULL) { + STOREerr(STORE_F_STORE_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->meth = method; + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_STORE, ret, &ret->ex_data); + if (ret->meth->init && !ret->meth->init(ret)) { + STORE_free(ret); + ret = NULL; + } + return ret; +} + +STORE *STORE_new_engine(ENGINE *engine) +{ + STORE *ret = NULL; + ENGINE *e = engine; + const STORE_METHOD *meth = 0; + +#ifdef OPENSSL_NO_ENGINE + e = NULL; +#else + if (engine) { + if (!ENGINE_init(engine)) { + STOREerr(STORE_F_STORE_NEW_ENGINE, ERR_R_ENGINE_LIB); + return NULL; + } + e = engine; + } else { + STOREerr(STORE_F_STORE_NEW_ENGINE, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (e) { + meth = ENGINE_get_STORE(e); + if (!meth) { + STOREerr(STORE_F_STORE_NEW_ENGINE, ERR_R_ENGINE_LIB); + ENGINE_finish(e); + return NULL; + } + } +#endif + + ret = STORE_new_method(meth); + if (ret == NULL) { + STOREerr(STORE_F_STORE_NEW_ENGINE, ERR_R_STORE_LIB); + return NULL; + } + + ret->engine = e; + + return (ret); +} + +void STORE_free(STORE *store) +{ + if (store == NULL) + return; + if (store->meth->clean) + store->meth->clean(store); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_STORE, store, &store->ex_data); + OPENSSL_free(store); +} + +int STORE_ctrl(STORE *store, int cmd, long i, void *p, void (*f) (void)) +{ + if (store == NULL) { + STOREerr(STORE_F_STORE_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (store->meth->ctrl) + return store->meth->ctrl(store, cmd, i, p, f); + STOREerr(STORE_F_STORE_CTRL, STORE_R_NO_CONTROL_FUNCTION); + return 0; +} + +int STORE_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_STORE, argl, argp, + new_func, dup_func, free_func); +} + +int STORE_set_ex_data(STORE *r, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); +} + +void *STORE_get_ex_data(STORE *r, int idx) +{ + return (CRYPTO_get_ex_data(&r->ex_data, idx)); +} + +const STORE_METHOD *STORE_get_method(STORE *store) +{ + return store->meth; +} + +const STORE_METHOD *STORE_set_method(STORE *store, const STORE_METHOD *meth) +{ + store->meth = meth; + return store->meth; +} + +/* API helpers */ + +#define check_store(s,fncode,fnname,fnerrcode) \ + do \ + { \ + if ((s) == NULL || (s)->meth == NULL) \ + { \ + STOREerr((fncode), ERR_R_PASSED_NULL_PARAMETER); \ + return 0; \ + } \ + if ((s)->meth->fnname == NULL) \ + { \ + STOREerr((fncode), (fnerrcode)); \ + return 0; \ + } \ + } \ + while(0) + +/* API functions */ + +X509 *STORE_get_certificate(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STORE_OBJECT *object; + X509 *x; + + check_store(s, STORE_F_STORE_GET_CERTIFICATE, + get_object, STORE_R_NO_GET_OBJECT_FUNCTION); + + object = s->meth->get_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, + attributes, parameters); + if (!object || !object->data.x509.certificate) { + STOREerr(STORE_F_STORE_GET_CERTIFICATE, + STORE_R_FAILED_GETTING_CERTIFICATE); + return 0; + } + CRYPTO_add(&object->data.x509.certificate->references, 1, + CRYPTO_LOCK_X509); +#ifdef REF_PRINT + REF_PRINT("X509", data); +#endif + x = object->data.x509.certificate; + STORE_OBJECT_free(object); + return x; +} + +int STORE_store_certificate(STORE *s, X509 *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STORE_OBJECT *object; + int i; + + check_store(s, STORE_F_STORE_CERTIFICATE, + store_object, STORE_R_NO_STORE_OBJECT_FUNCTION); + + object = STORE_OBJECT_new(); + if (!object) { + STOREerr(STORE_F_STORE_STORE_CERTIFICATE, ERR_R_MALLOC_FAILURE); + return 0; + } + + CRYPTO_add(&data->references, 1, CRYPTO_LOCK_X509); +#ifdef REF_PRINT + REF_PRINT("X509", data); +#endif + object->data.x509.certificate = data; + + i = s->meth->store_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, + object, attributes, parameters); + + STORE_OBJECT_free(object); + + if (!i) { + STOREerr(STORE_F_STORE_STORE_CERTIFICATE, + STORE_R_FAILED_STORING_CERTIFICATE); + return 0; + } + return 1; +} + +int STORE_modify_certificate(STORE *s, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]) +{ + check_store(s, STORE_F_STORE_MODIFY_CERTIFICATE, + modify_object, STORE_R_NO_MODIFY_OBJECT_FUNCTION); + + if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, + search_attributes, add_attributes, + modify_attributes, delete_attributes, + parameters)) { + STOREerr(STORE_F_STORE_MODIFY_CERTIFICATE, + STORE_R_FAILED_MODIFYING_CERTIFICATE); + return 0; + } + return 1; +} + +int STORE_revoke_certificate(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + check_store(s, STORE_F_STORE_REVOKE_CERTIFICATE, + revoke_object, STORE_R_NO_REVOKE_OBJECT_FUNCTION); + + if (!s->meth->revoke_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, + attributes, parameters)) { + STOREerr(STORE_F_STORE_REVOKE_CERTIFICATE, + STORE_R_FAILED_REVOKING_CERTIFICATE); + return 0; + } + return 1; +} + +int STORE_delete_certificate(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + check_store(s, STORE_F_STORE_DELETE_CERTIFICATE, + delete_object, STORE_R_NO_DELETE_OBJECT_FUNCTION); + + if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_X509_CERTIFICATE, + attributes, parameters)) { + STOREerr(STORE_F_STORE_DELETE_CERTIFICATE, + STORE_R_FAILED_DELETING_CERTIFICATE); + return 0; + } + return 1; +} + +void *STORE_list_certificate_start(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + void *handle; + + check_store(s, STORE_F_STORE_LIST_CERTIFICATE_START, + list_object_start, STORE_R_NO_LIST_OBJECT_START_FUNCTION); + + handle = s->meth->list_object_start(s, + STORE_OBJECT_TYPE_X509_CERTIFICATE, + attributes, parameters); + if (!handle) { + STOREerr(STORE_F_STORE_LIST_CERTIFICATE_START, + STORE_R_FAILED_LISTING_CERTIFICATES); + return 0; + } + return handle; +} + +X509 *STORE_list_certificate_next(STORE *s, void *handle) +{ + STORE_OBJECT *object; + X509 *x; + + check_store(s, STORE_F_STORE_LIST_CERTIFICATE_NEXT, + list_object_next, STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION); + + object = s->meth->list_object_next(s, handle); + if (!object || !object->data.x509.certificate) { + STOREerr(STORE_F_STORE_LIST_CERTIFICATE_NEXT, + STORE_R_FAILED_LISTING_CERTIFICATES); + return 0; + } + CRYPTO_add(&object->data.x509.certificate->references, 1, + CRYPTO_LOCK_X509); +#ifdef REF_PRINT + REF_PRINT("X509", data); +#endif + x = object->data.x509.certificate; + STORE_OBJECT_free(object); + return x; +} + +int STORE_list_certificate_end(STORE *s, void *handle) +{ + check_store(s, STORE_F_STORE_LIST_CERTIFICATE_END, + list_object_end, STORE_R_NO_LIST_OBJECT_END_FUNCTION); + + if (!s->meth->list_object_end(s, handle)) { + STOREerr(STORE_F_STORE_LIST_CERTIFICATE_END, + STORE_R_FAILED_LISTING_CERTIFICATES); + return 0; + } + return 1; +} + +int STORE_list_certificate_endp(STORE *s, void *handle) +{ + check_store(s, STORE_F_STORE_LIST_CERTIFICATE_ENDP, + list_object_endp, STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION); + + if (!s->meth->list_object_endp(s, handle)) { + STOREerr(STORE_F_STORE_LIST_CERTIFICATE_ENDP, + STORE_R_FAILED_LISTING_CERTIFICATES); + return 0; + } + return 1; +} + +EVP_PKEY *STORE_generate_key(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STORE_OBJECT *object; + EVP_PKEY *pkey; + + check_store(s, STORE_F_STORE_GENERATE_KEY, + generate_object, STORE_R_NO_GENERATE_OBJECT_FUNCTION); + + object = s->meth->generate_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, + attributes, parameters); + if (!object || !object->data.key) { + STOREerr(STORE_F_STORE_GENERATE_KEY, STORE_R_FAILED_GENERATING_KEY); + return 0; + } + CRYPTO_add(&object->data.key->references, 1, CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY", data); +#endif + pkey = object->data.key; + STORE_OBJECT_free(object); + return pkey; +} + +EVP_PKEY *STORE_get_private_key(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STORE_OBJECT *object; + EVP_PKEY *pkey; + + check_store(s, STORE_F_STORE_GET_PRIVATE_KEY, + get_object, STORE_R_NO_GET_OBJECT_FUNCTION); + + object = s->meth->get_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, + attributes, parameters); + if (!object || !object->data.key || !object->data.key) { + STOREerr(STORE_F_STORE_GET_PRIVATE_KEY, STORE_R_FAILED_GETTING_KEY); + return 0; + } + CRYPTO_add(&object->data.key->references, 1, CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY", data); +#endif + pkey = object->data.key; + STORE_OBJECT_free(object); + return pkey; +} + +int STORE_store_private_key(STORE *s, EVP_PKEY *data, + OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STORE_OBJECT *object; + int i; + + check_store(s, STORE_F_STORE_STORE_PRIVATE_KEY, + store_object, STORE_R_NO_STORE_OBJECT_FUNCTION); + + object = STORE_OBJECT_new(); + if (!object) { + STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY, ERR_R_MALLOC_FAILURE); + return 0; + } + object->data.key = EVP_PKEY_new(); + if (!object->data.key) { + STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY, ERR_R_MALLOC_FAILURE); + return 0; + } + + CRYPTO_add(&data->references, 1, CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY", data); +#endif + object->data.key = data; + + i = s->meth->store_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, object, + attributes, parameters); + + STORE_OBJECT_free(object); + + if (!i) { + STOREerr(STORE_F_STORE_STORE_PRIVATE_KEY, STORE_R_FAILED_STORING_KEY); + return 0; + } + return i; +} + +int STORE_modify_private_key(STORE *s, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]) +{ + check_store(s, STORE_F_STORE_MODIFY_PRIVATE_KEY, + modify_object, STORE_R_NO_MODIFY_OBJECT_FUNCTION); + + if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, + search_attributes, add_attributes, + modify_attributes, delete_attributes, + parameters)) { + STOREerr(STORE_F_STORE_MODIFY_PRIVATE_KEY, + STORE_R_FAILED_MODIFYING_PRIVATE_KEY); + return 0; + } + return 1; +} + +int STORE_revoke_private_key(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + int i; + + check_store(s, STORE_F_STORE_REVOKE_PRIVATE_KEY, + revoke_object, STORE_R_NO_REVOKE_OBJECT_FUNCTION); + + i = s->meth->revoke_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, + attributes, parameters); + + if (!i) { + STOREerr(STORE_F_STORE_REVOKE_PRIVATE_KEY, + STORE_R_FAILED_REVOKING_KEY); + return 0; + } + return i; +} + +int STORE_delete_private_key(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + check_store(s, STORE_F_STORE_DELETE_PRIVATE_KEY, + delete_object, STORE_R_NO_DELETE_OBJECT_FUNCTION); + + if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_PRIVATE_KEY, + attributes, parameters)) { + STOREerr(STORE_F_STORE_DELETE_PRIVATE_KEY, + STORE_R_FAILED_DELETING_KEY); + return 0; + } + return 1; +} + +void *STORE_list_private_key_start(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + void *handle; + + check_store(s, STORE_F_STORE_LIST_PRIVATE_KEY_START, + list_object_start, STORE_R_NO_LIST_OBJECT_START_FUNCTION); + + handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_PRIVATE_KEY, + attributes, parameters); + if (!handle) { + STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_START, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return handle; +} + +EVP_PKEY *STORE_list_private_key_next(STORE *s, void *handle) +{ + STORE_OBJECT *object; + EVP_PKEY *pkey; + + check_store(s, STORE_F_STORE_LIST_PRIVATE_KEY_NEXT, + list_object_next, STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION); + + object = s->meth->list_object_next(s, handle); + if (!object || !object->data.key || !object->data.key) { + STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_NEXT, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + CRYPTO_add(&object->data.key->references, 1, CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY", data); +#endif + pkey = object->data.key; + STORE_OBJECT_free(object); + return pkey; +} + +int STORE_list_private_key_end(STORE *s, void *handle) +{ + check_store(s, STORE_F_STORE_LIST_PRIVATE_KEY_END, + list_object_end, STORE_R_NO_LIST_OBJECT_END_FUNCTION); + + if (!s->meth->list_object_end(s, handle)) { + STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_END, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return 1; +} + +int STORE_list_private_key_endp(STORE *s, void *handle) +{ + check_store(s, STORE_F_STORE_LIST_PRIVATE_KEY_ENDP, + list_object_endp, STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION); + + if (!s->meth->list_object_endp(s, handle)) { + STOREerr(STORE_F_STORE_LIST_PRIVATE_KEY_ENDP, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return 1; +} + +EVP_PKEY *STORE_get_public_key(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STORE_OBJECT *object; + EVP_PKEY *pkey; + + check_store(s, STORE_F_STORE_GET_PUBLIC_KEY, + get_object, STORE_R_NO_GET_OBJECT_FUNCTION); + + object = s->meth->get_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, + attributes, parameters); + if (!object || !object->data.key || !object->data.key) { + STOREerr(STORE_F_STORE_GET_PUBLIC_KEY, STORE_R_FAILED_GETTING_KEY); + return 0; + } + CRYPTO_add(&object->data.key->references, 1, CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY", data); +#endif + pkey = object->data.key; + STORE_OBJECT_free(object); + return pkey; +} + +int STORE_store_public_key(STORE *s, EVP_PKEY *data, + OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STORE_OBJECT *object; + int i; + + check_store(s, STORE_F_STORE_STORE_PUBLIC_KEY, + store_object, STORE_R_NO_STORE_OBJECT_FUNCTION); + + object = STORE_OBJECT_new(); + if (!object) { + STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY, ERR_R_MALLOC_FAILURE); + return 0; + } + object->data.key = EVP_PKEY_new(); + if (!object->data.key) { + STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY, ERR_R_MALLOC_FAILURE); + return 0; + } + + CRYPTO_add(&data->references, 1, CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY", data); +#endif + object->data.key = data; + + i = s->meth->store_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, object, + attributes, parameters); + + STORE_OBJECT_free(object); + + if (!i) { + STOREerr(STORE_F_STORE_STORE_PUBLIC_KEY, STORE_R_FAILED_STORING_KEY); + return 0; + } + return i; +} + +int STORE_modify_public_key(STORE *s, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]) +{ + check_store(s, STORE_F_STORE_MODIFY_PUBLIC_KEY, + modify_object, STORE_R_NO_MODIFY_OBJECT_FUNCTION); + + if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, + search_attributes, add_attributes, + modify_attributes, delete_attributes, + parameters)) { + STOREerr(STORE_F_STORE_MODIFY_PUBLIC_KEY, + STORE_R_FAILED_MODIFYING_PUBLIC_KEY); + return 0; + } + return 1; +} + +int STORE_revoke_public_key(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + int i; + + check_store(s, STORE_F_STORE_REVOKE_PUBLIC_KEY, + revoke_object, STORE_R_NO_REVOKE_OBJECT_FUNCTION); + + i = s->meth->revoke_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, + attributes, parameters); + + if (!i) { + STOREerr(STORE_F_STORE_REVOKE_PUBLIC_KEY, + STORE_R_FAILED_REVOKING_KEY); + return 0; + } + return i; +} + +int STORE_delete_public_key(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + check_store(s, STORE_F_STORE_DELETE_PUBLIC_KEY, + delete_object, STORE_R_NO_DELETE_OBJECT_FUNCTION); + + if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_PUBLIC_KEY, + attributes, parameters)) { + STOREerr(STORE_F_STORE_DELETE_PUBLIC_KEY, + STORE_R_FAILED_DELETING_KEY); + return 0; + } + return 1; +} + +void *STORE_list_public_key_start(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + void *handle; + + check_store(s, STORE_F_STORE_LIST_PUBLIC_KEY_START, + list_object_start, STORE_R_NO_LIST_OBJECT_START_FUNCTION); + + handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_PUBLIC_KEY, + attributes, parameters); + if (!handle) { + STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_START, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return handle; +} + +EVP_PKEY *STORE_list_public_key_next(STORE *s, void *handle) +{ + STORE_OBJECT *object; + EVP_PKEY *pkey; + + check_store(s, STORE_F_STORE_LIST_PUBLIC_KEY_NEXT, + list_object_next, STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION); + + object = s->meth->list_object_next(s, handle); + if (!object || !object->data.key || !object->data.key) { + STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_NEXT, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + CRYPTO_add(&object->data.key->references, 1, CRYPTO_LOCK_EVP_PKEY); +#ifdef REF_PRINT + REF_PRINT("EVP_PKEY", data); +#endif + pkey = object->data.key; + STORE_OBJECT_free(object); + return pkey; +} + +int STORE_list_public_key_end(STORE *s, void *handle) +{ + check_store(s, STORE_F_STORE_LIST_PUBLIC_KEY_END, + list_object_end, STORE_R_NO_LIST_OBJECT_END_FUNCTION); + + if (!s->meth->list_object_end(s, handle)) { + STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_END, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return 1; +} + +int STORE_list_public_key_endp(STORE *s, void *handle) +{ + check_store(s, STORE_F_STORE_LIST_PUBLIC_KEY_ENDP, + list_object_endp, STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION); + + if (!s->meth->list_object_endp(s, handle)) { + STOREerr(STORE_F_STORE_LIST_PUBLIC_KEY_ENDP, + STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return 1; +} + +X509_CRL *STORE_generate_crl(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STORE_OBJECT *object; + X509_CRL *crl; + + check_store(s, STORE_F_STORE_GENERATE_CRL, + generate_object, STORE_R_NO_GENERATE_CRL_FUNCTION); + + object = s->meth->generate_object(s, STORE_OBJECT_TYPE_X509_CRL, + attributes, parameters); + if (!object || !object->data.crl) { + STOREerr(STORE_F_STORE_GENERATE_CRL, STORE_R_FAILED_GENERATING_CRL); + return 0; + } + CRYPTO_add(&object->data.crl->references, 1, CRYPTO_LOCK_X509_CRL); +#ifdef REF_PRINT + REF_PRINT("X509_CRL", data); +#endif + crl = object->data.crl; + STORE_OBJECT_free(object); + return crl; +} + +X509_CRL *STORE_get_crl(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STORE_OBJECT *object; + X509_CRL *crl; + + check_store(s, STORE_F_STORE_GET_CRL, + get_object, STORE_R_NO_GET_OBJECT_FUNCTION); + + object = s->meth->get_object(s, STORE_OBJECT_TYPE_X509_CRL, + attributes, parameters); + if (!object || !object->data.crl) { + STOREerr(STORE_F_STORE_GET_CRL, STORE_R_FAILED_GETTING_KEY); + return 0; + } + CRYPTO_add(&object->data.crl->references, 1, CRYPTO_LOCK_X509_CRL); +#ifdef REF_PRINT + REF_PRINT("X509_CRL", data); +#endif + crl = object->data.crl; + STORE_OBJECT_free(object); + return crl; +} + +int STORE_store_crl(STORE *s, X509_CRL *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STORE_OBJECT *object; + int i; + + check_store(s, STORE_F_STORE_STORE_CRL, + store_object, STORE_R_NO_STORE_OBJECT_FUNCTION); + + object = STORE_OBJECT_new(); + if (!object) { + STOREerr(STORE_F_STORE_STORE_CRL, ERR_R_MALLOC_FAILURE); + return 0; + } + + CRYPTO_add(&data->references, 1, CRYPTO_LOCK_X509_CRL); +#ifdef REF_PRINT + REF_PRINT("X509_CRL", data); +#endif + object->data.crl = data; + + i = s->meth->store_object(s, STORE_OBJECT_TYPE_X509_CRL, object, + attributes, parameters); + + STORE_OBJECT_free(object); + + if (!i) { + STOREerr(STORE_F_STORE_STORE_CRL, STORE_R_FAILED_STORING_KEY); + return 0; + } + return i; +} + +int STORE_modify_crl(STORE *s, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]) +{ + check_store(s, STORE_F_STORE_MODIFY_CRL, + modify_object, STORE_R_NO_MODIFY_OBJECT_FUNCTION); + + if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_X509_CRL, + search_attributes, add_attributes, + modify_attributes, delete_attributes, + parameters)) { + STOREerr(STORE_F_STORE_MODIFY_CRL, STORE_R_FAILED_MODIFYING_CRL); + return 0; + } + return 1; +} + +int STORE_delete_crl(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + check_store(s, STORE_F_STORE_DELETE_CRL, + delete_object, STORE_R_NO_DELETE_OBJECT_FUNCTION); + + if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_X509_CRL, + attributes, parameters)) { + STOREerr(STORE_F_STORE_DELETE_CRL, STORE_R_FAILED_DELETING_KEY); + return 0; + } + return 1; +} + +void *STORE_list_crl_start(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + void *handle; + + check_store(s, STORE_F_STORE_LIST_CRL_START, + list_object_start, STORE_R_NO_LIST_OBJECT_START_FUNCTION); + + handle = s->meth->list_object_start(s, STORE_OBJECT_TYPE_X509_CRL, + attributes, parameters); + if (!handle) { + STOREerr(STORE_F_STORE_LIST_CRL_START, STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return handle; +} + +X509_CRL *STORE_list_crl_next(STORE *s, void *handle) +{ + STORE_OBJECT *object; + X509_CRL *crl; + + check_store(s, STORE_F_STORE_LIST_CRL_NEXT, + list_object_next, STORE_R_NO_LIST_OBJECT_NEXT_FUNCTION); + + object = s->meth->list_object_next(s, handle); + if (!object || !object->data.crl) { + STOREerr(STORE_F_STORE_LIST_CRL_NEXT, STORE_R_FAILED_LISTING_KEYS); + return 0; + } + CRYPTO_add(&object->data.crl->references, 1, CRYPTO_LOCK_X509_CRL); +#ifdef REF_PRINT + REF_PRINT("X509_CRL", data); +#endif + crl = object->data.crl; + STORE_OBJECT_free(object); + return crl; +} + +int STORE_list_crl_end(STORE *s, void *handle) +{ + check_store(s, STORE_F_STORE_LIST_CRL_END, + list_object_end, STORE_R_NO_LIST_OBJECT_END_FUNCTION); + + if (!s->meth->list_object_end(s, handle)) { + STOREerr(STORE_F_STORE_LIST_CRL_END, STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return 1; +} + +int STORE_list_crl_endp(STORE *s, void *handle) +{ + check_store(s, STORE_F_STORE_LIST_CRL_ENDP, + list_object_endp, STORE_R_NO_LIST_OBJECT_ENDP_FUNCTION); + + if (!s->meth->list_object_endp(s, handle)) { + STOREerr(STORE_F_STORE_LIST_CRL_ENDP, STORE_R_FAILED_LISTING_KEYS); + return 0; + } + return 1; +} + +int STORE_store_number(STORE *s, BIGNUM *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STORE_OBJECT *object; + int i; + + check_store(s, STORE_F_STORE_STORE_NUMBER, + store_object, STORE_R_NO_STORE_OBJECT_NUMBER_FUNCTION); + + object = STORE_OBJECT_new(); + if (!object) { + STOREerr(STORE_F_STORE_STORE_NUMBER, ERR_R_MALLOC_FAILURE); + return 0; + } + + object->data.number = data; + + i = s->meth->store_object(s, STORE_OBJECT_TYPE_NUMBER, object, + attributes, parameters); + + STORE_OBJECT_free(object); + + if (!i) { + STOREerr(STORE_F_STORE_STORE_NUMBER, STORE_R_FAILED_STORING_NUMBER); + return 0; + } + return 1; +} + +int STORE_modify_number(STORE *s, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]) +{ + check_store(s, STORE_F_STORE_MODIFY_NUMBER, + modify_object, STORE_R_NO_MODIFY_OBJECT_FUNCTION); + + if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_NUMBER, + search_attributes, add_attributes, + modify_attributes, delete_attributes, + parameters)) { + STOREerr(STORE_F_STORE_MODIFY_NUMBER, + STORE_R_FAILED_MODIFYING_NUMBER); + return 0; + } + return 1; +} + +BIGNUM *STORE_get_number(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STORE_OBJECT *object; + BIGNUM *n; + + check_store(s, STORE_F_STORE_GET_NUMBER, + get_object, STORE_R_NO_GET_OBJECT_NUMBER_FUNCTION); + + object = s->meth->get_object(s, STORE_OBJECT_TYPE_NUMBER, attributes, + parameters); + if (!object || !object->data.number) { + STOREerr(STORE_F_STORE_GET_NUMBER, STORE_R_FAILED_GETTING_NUMBER); + return 0; + } + n = object->data.number; + object->data.number = NULL; + STORE_OBJECT_free(object); + return n; +} + +int STORE_delete_number(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + check_store(s, STORE_F_STORE_DELETE_NUMBER, + delete_object, STORE_R_NO_DELETE_NUMBER_FUNCTION); + + if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_NUMBER, attributes, + parameters)) { + STOREerr(STORE_F_STORE_DELETE_NUMBER, STORE_R_FAILED_DELETING_NUMBER); + return 0; + } + return 1; +} + +int STORE_store_arbitrary(STORE *s, BUF_MEM *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STORE_OBJECT *object; + int i; + + check_store(s, STORE_F_STORE_STORE_ARBITRARY, + store_object, STORE_R_NO_STORE_OBJECT_ARBITRARY_FUNCTION); + + object = STORE_OBJECT_new(); + if (!object) { + STOREerr(STORE_F_STORE_STORE_ARBITRARY, ERR_R_MALLOC_FAILURE); + return 0; + } + + object->data.arbitrary = data; + + i = s->meth->store_object(s, STORE_OBJECT_TYPE_ARBITRARY, object, + attributes, parameters); + + STORE_OBJECT_free(object); + + if (!i) { + STOREerr(STORE_F_STORE_STORE_ARBITRARY, + STORE_R_FAILED_STORING_ARBITRARY); + return 0; + } + return 1; +} + +int STORE_modify_arbitrary(STORE *s, OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]) +{ + check_store(s, STORE_F_STORE_MODIFY_ARBITRARY, + modify_object, STORE_R_NO_MODIFY_OBJECT_FUNCTION); + + if (!s->meth->modify_object(s, STORE_OBJECT_TYPE_ARBITRARY, + search_attributes, add_attributes, + modify_attributes, delete_attributes, + parameters)) { + STOREerr(STORE_F_STORE_MODIFY_ARBITRARY, + STORE_R_FAILED_MODIFYING_ARBITRARY); + return 0; + } + return 1; +} + +BUF_MEM *STORE_get_arbitrary(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STORE_OBJECT *object; + BUF_MEM *b; + + check_store(s, STORE_F_STORE_GET_ARBITRARY, + get_object, STORE_R_NO_GET_OBJECT_ARBITRARY_FUNCTION); + + object = s->meth->get_object(s, STORE_OBJECT_TYPE_ARBITRARY, + attributes, parameters); + if (!object || !object->data.arbitrary) { + STOREerr(STORE_F_STORE_GET_ARBITRARY, + STORE_R_FAILED_GETTING_ARBITRARY); + return 0; + } + b = object->data.arbitrary; + object->data.arbitrary = NULL; + STORE_OBJECT_free(object); + return b; +} + +int STORE_delete_arbitrary(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + check_store(s, STORE_F_STORE_DELETE_ARBITRARY, + delete_object, STORE_R_NO_DELETE_ARBITRARY_FUNCTION); + + if (!s->meth->delete_object(s, STORE_OBJECT_TYPE_ARBITRARY, attributes, + parameters)) { + STOREerr(STORE_F_STORE_DELETE_ARBITRARY, + STORE_R_FAILED_DELETING_ARBITRARY); + return 0; + } + return 1; +} + +STORE_OBJECT *STORE_OBJECT_new(void) +{ + STORE_OBJECT *object = OPENSSL_malloc(sizeof(STORE_OBJECT)); + if (object) + memset(object, 0, sizeof(STORE_OBJECT)); + return object; +} + +void STORE_OBJECT_free(STORE_OBJECT *data) +{ + if (!data) + return; + switch (data->type) { + case STORE_OBJECT_TYPE_X509_CERTIFICATE: + X509_free(data->data.x509.certificate); + break; + case STORE_OBJECT_TYPE_X509_CRL: + X509_CRL_free(data->data.crl); + break; + case STORE_OBJECT_TYPE_PRIVATE_KEY: + case STORE_OBJECT_TYPE_PUBLIC_KEY: + EVP_PKEY_free(data->data.key); + break; + case STORE_OBJECT_TYPE_NUMBER: + BN_free(data->data.number); + break; + case STORE_OBJECT_TYPE_ARBITRARY: + BUF_MEM_free(data->data.arbitrary); + break; + } + OPENSSL_free(data); +} + +IMPLEMENT_STACK_OF(STORE_OBJECT*) + +struct STORE_attr_info_st { + unsigned char set[(STORE_ATTR_TYPE_NUM + 8) / 8]; + union { + char *cstring; + unsigned char *sha1string; + X509_NAME *dn; + BIGNUM *number; + void *any; + } values[STORE_ATTR_TYPE_NUM + 1]; + size_t value_sizes[STORE_ATTR_TYPE_NUM + 1]; +}; + +#define ATTR_IS_SET(a,i) ((i) > 0 && (i) < STORE_ATTR_TYPE_NUM \ + && ((a)->set[(i) / 8] & (1 << ((i) % 8)))) +#define SET_ATTRBIT(a,i) ((a)->set[(i) / 8] |= (1 << ((i) % 8))) +#define CLEAR_ATTRBIT(a,i) ((a)->set[(i) / 8] &= ~(1 << ((i) % 8))) + +STORE_ATTR_INFO *STORE_ATTR_INFO_new(void) +{ + return (STORE_ATTR_INFO *)OPENSSL_malloc(sizeof(STORE_ATTR_INFO)); +} + +static void STORE_ATTR_INFO_attr_free(STORE_ATTR_INFO *attrs, + STORE_ATTR_TYPES code) +{ + if (ATTR_IS_SET(attrs, code)) { + switch (code) { + case STORE_ATTR_FRIENDLYNAME: + case STORE_ATTR_EMAIL: + case STORE_ATTR_FILENAME: + STORE_ATTR_INFO_modify_cstr(attrs, code, NULL, 0); + break; + case STORE_ATTR_KEYID: + case STORE_ATTR_ISSUERKEYID: + case STORE_ATTR_SUBJECTKEYID: + case STORE_ATTR_ISSUERSERIALHASH: + case STORE_ATTR_CERTHASH: + STORE_ATTR_INFO_modify_sha1str(attrs, code, NULL, 0); + break; + case STORE_ATTR_ISSUER: + case STORE_ATTR_SUBJECT: + STORE_ATTR_INFO_modify_dn(attrs, code, NULL); + break; + case STORE_ATTR_SERIAL: + STORE_ATTR_INFO_modify_number(attrs, code, NULL); + break; + default: + break; + } + } +} + +int STORE_ATTR_INFO_free(STORE_ATTR_INFO *attrs) +{ + if (attrs) { + STORE_ATTR_TYPES i; + for (i = 0; i++ < STORE_ATTR_TYPE_NUM;) + STORE_ATTR_INFO_attr_free(attrs, i); + OPENSSL_free(attrs); + } + return 1; +} + +char *STORE_ATTR_INFO_get0_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code) +{ + if (!attrs) { + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR, + ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (ATTR_IS_SET(attrs, code)) + return attrs->values[code].cstring; + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_CSTR, STORE_R_NO_VALUE); + return NULL; +} + +unsigned char *STORE_ATTR_INFO_get0_sha1str(STORE_ATTR_INFO *attrs, + STORE_ATTR_TYPES code) +{ + if (!attrs) { + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR, + ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (ATTR_IS_SET(attrs, code)) + return attrs->values[code].sha1string; + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_SHA1STR, STORE_R_NO_VALUE); + return NULL; +} + +X509_NAME *STORE_ATTR_INFO_get0_dn(STORE_ATTR_INFO *attrs, + STORE_ATTR_TYPES code) +{ + if (!attrs) { + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN, + ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (ATTR_IS_SET(attrs, code)) + return attrs->values[code].dn; + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_DN, STORE_R_NO_VALUE); + return NULL; +} + +BIGNUM *STORE_ATTR_INFO_get0_number(STORE_ATTR_INFO *attrs, + STORE_ATTR_TYPES code) +{ + if (!attrs) { + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER, + ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (ATTR_IS_SET(attrs, code)) + return attrs->values[code].number; + STOREerr(STORE_F_STORE_ATTR_INFO_GET0_NUMBER, STORE_R_NO_VALUE); + return NULL; +} + +int STORE_ATTR_INFO_set_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + char *cstr, size_t cstr_size) +{ + if (!attrs) { + STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (!ATTR_IS_SET(attrs, code)) { + if ((attrs->values[code].cstring = BUF_strndup(cstr, cstr_size))) + return 1; + STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR, ERR_R_MALLOC_FAILURE); + return 0; + } + STOREerr(STORE_F_STORE_ATTR_INFO_SET_CSTR, STORE_R_ALREADY_HAS_A_VALUE); + return 0; +} + +int STORE_ATTR_INFO_set_sha1str(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + unsigned char *sha1str, size_t sha1str_size) +{ + if (!attrs) { + STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (!ATTR_IS_SET(attrs, code)) { + if ((attrs->values[code].sha1string = + (unsigned char *)BUF_memdup(sha1str, sha1str_size))) + return 1; + STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR, ERR_R_MALLOC_FAILURE); + return 0; + } + STOREerr(STORE_F_STORE_ATTR_INFO_SET_SHA1STR, + STORE_R_ALREADY_HAS_A_VALUE); + return 0; +} + +int STORE_ATTR_INFO_set_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + X509_NAME *dn) +{ + if (!attrs) { + STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (!ATTR_IS_SET(attrs, code)) { + if ((attrs->values[code].dn = X509_NAME_dup(dn))) + return 1; + STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, ERR_R_MALLOC_FAILURE); + return 0; + } + STOREerr(STORE_F_STORE_ATTR_INFO_SET_DN, STORE_R_ALREADY_HAS_A_VALUE); + return 0; +} + +int STORE_ATTR_INFO_set_number(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + BIGNUM *number) +{ + if (!attrs) { + STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (!ATTR_IS_SET(attrs, code)) { + if ((attrs->values[code].number = BN_dup(number))) + return 1; + STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER, ERR_R_MALLOC_FAILURE); + return 0; + } + STOREerr(STORE_F_STORE_ATTR_INFO_SET_NUMBER, STORE_R_ALREADY_HAS_A_VALUE); + return 0; +} + +int STORE_ATTR_INFO_modify_cstr(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + char *cstr, size_t cstr_size) +{ + if (!attrs) { + STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_CSTR, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (ATTR_IS_SET(attrs, code)) { + OPENSSL_free(attrs->values[code].cstring); + attrs->values[code].cstring = NULL; + CLEAR_ATTRBIT(attrs, code); + } + return STORE_ATTR_INFO_set_cstr(attrs, code, cstr, cstr_size); +} + +int STORE_ATTR_INFO_modify_sha1str(STORE_ATTR_INFO *attrs, + STORE_ATTR_TYPES code, + unsigned char *sha1str, + size_t sha1str_size) +{ + if (!attrs) { + STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_SHA1STR, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (ATTR_IS_SET(attrs, code)) { + OPENSSL_free(attrs->values[code].sha1string); + attrs->values[code].sha1string = NULL; + CLEAR_ATTRBIT(attrs, code); + } + return STORE_ATTR_INFO_set_sha1str(attrs, code, sha1str, sha1str_size); +} + +int STORE_ATTR_INFO_modify_dn(STORE_ATTR_INFO *attrs, STORE_ATTR_TYPES code, + X509_NAME *dn) +{ + if (!attrs) { + STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_DN, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (ATTR_IS_SET(attrs, code)) { + OPENSSL_free(attrs->values[code].dn); + attrs->values[code].dn = NULL; + CLEAR_ATTRBIT(attrs, code); + } + return STORE_ATTR_INFO_set_dn(attrs, code, dn); +} + +int STORE_ATTR_INFO_modify_number(STORE_ATTR_INFO *attrs, + STORE_ATTR_TYPES code, BIGNUM *number) +{ + if (!attrs) { + STOREerr(STORE_F_STORE_ATTR_INFO_MODIFY_NUMBER, + ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (ATTR_IS_SET(attrs, code)) { + OPENSSL_free(attrs->values[code].number); + attrs->values[code].number = NULL; + CLEAR_ATTRBIT(attrs, code); + } + return STORE_ATTR_INFO_set_number(attrs, code, number); +} + +struct attr_list_ctx_st { + OPENSSL_ITEM *attributes; +}; +void *STORE_parse_attrs_start(OPENSSL_ITEM *attributes) +{ + if (attributes) { + struct attr_list_ctx_st *context = (struct attr_list_ctx_st *) + OPENSSL_malloc(sizeof(struct attr_list_ctx_st)); + if (context) + context->attributes = attributes; + else + STOREerr(STORE_F_STORE_PARSE_ATTRS_START, ERR_R_MALLOC_FAILURE); + return context; + } + STOREerr(STORE_F_STORE_PARSE_ATTRS_START, ERR_R_PASSED_NULL_PARAMETER); + return 0; +} + +STORE_ATTR_INFO *STORE_parse_attrs_next(void *handle) +{ + struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle; + + if (context && context->attributes) { + STORE_ATTR_INFO *attrs = NULL; + + while (context->attributes + && context->attributes->code != STORE_ATTR_OR + && context->attributes->code != STORE_ATTR_END) { + switch (context->attributes->code) { + case STORE_ATTR_FRIENDLYNAME: + case STORE_ATTR_EMAIL: + case STORE_ATTR_FILENAME: + if (!attrs) + attrs = STORE_ATTR_INFO_new(); + if (attrs == NULL) { + STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, + ERR_R_MALLOC_FAILURE); + goto err; + } + STORE_ATTR_INFO_set_cstr(attrs, + context->attributes->code, + context->attributes->value, + context->attributes->value_size); + break; + case STORE_ATTR_KEYID: + case STORE_ATTR_ISSUERKEYID: + case STORE_ATTR_SUBJECTKEYID: + case STORE_ATTR_ISSUERSERIALHASH: + case STORE_ATTR_CERTHASH: + if (!attrs) + attrs = STORE_ATTR_INFO_new(); + if (attrs == NULL) { + STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, + ERR_R_MALLOC_FAILURE); + goto err; + } + STORE_ATTR_INFO_set_sha1str(attrs, + context->attributes->code, + context->attributes->value, + context->attributes->value_size); + break; + case STORE_ATTR_ISSUER: + case STORE_ATTR_SUBJECT: + if (!attrs) + attrs = STORE_ATTR_INFO_new(); + if (attrs == NULL) { + STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, + ERR_R_MALLOC_FAILURE); + goto err; + } + STORE_ATTR_INFO_modify_dn(attrs, + context->attributes->code, + context->attributes->value); + break; + case STORE_ATTR_SERIAL: + if (!attrs) + attrs = STORE_ATTR_INFO_new(); + if (attrs == NULL) { + STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, + ERR_R_MALLOC_FAILURE); + goto err; + } + STORE_ATTR_INFO_modify_number(attrs, + context->attributes->code, + context->attributes->value); + break; + } + context->attributes++; + } + if (context->attributes->code == STORE_ATTR_OR) + context->attributes++; + return attrs; + err: + while (context->attributes + && context->attributes->code != STORE_ATTR_OR + && context->attributes->code != STORE_ATTR_END) + context->attributes++; + if (context->attributes->code == STORE_ATTR_OR) + context->attributes++; + return NULL; + } + STOREerr(STORE_F_STORE_PARSE_ATTRS_NEXT, ERR_R_PASSED_NULL_PARAMETER); + return NULL; +} + +int STORE_parse_attrs_end(void *handle) +{ + struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle; + + if (context && context->attributes) { +#if 0 + OPENSSL_ITEM *attributes = context->attributes; +#endif + OPENSSL_free(context); + return 1; + } + STOREerr(STORE_F_STORE_PARSE_ATTRS_END, ERR_R_PASSED_NULL_PARAMETER); + return 0; +} + +int STORE_parse_attrs_endp(void *handle) +{ + struct attr_list_ctx_st *context = (struct attr_list_ctx_st *)handle; + + if (context && context->attributes) { + return context->attributes->code == STORE_ATTR_END; + } + STOREerr(STORE_F_STORE_PARSE_ATTRS_ENDP, ERR_R_PASSED_NULL_PARAMETER); + return 0; +} + +static int attr_info_compare_compute_range(const unsigned char *abits, + const unsigned char *bbits, + unsigned int *alowp, + unsigned int *ahighp, + unsigned int *blowp, + unsigned int *bhighp) +{ + unsigned int alow = (unsigned int)-1, ahigh = 0; + unsigned int blow = (unsigned int)-1, bhigh = 0; + int i, res = 0; + + for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++) { + if (res == 0) { + if (*abits < *bbits) + res = -1; + if (*abits > *bbits) + res = 1; + } + if (*abits) { + if (alow == (unsigned int)-1) { + alow = i * 8; + if (!(*abits & 0x01)) + alow++; + if (!(*abits & 0x02)) + alow++; + if (!(*abits & 0x04)) + alow++; + if (!(*abits & 0x08)) + alow++; + if (!(*abits & 0x10)) + alow++; + if (!(*abits & 0x20)) + alow++; + if (!(*abits & 0x40)) + alow++; + } + ahigh = i * 8 + 7; + if (!(*abits & 0x80)) + ahigh++; + if (!(*abits & 0x40)) + ahigh++; + if (!(*abits & 0x20)) + ahigh++; + if (!(*abits & 0x10)) + ahigh++; + if (!(*abits & 0x08)) + ahigh++; + if (!(*abits & 0x04)) + ahigh++; + if (!(*abits & 0x02)) + ahigh++; + } + if (*bbits) { + if (blow == (unsigned int)-1) { + blow = i * 8; + if (!(*bbits & 0x01)) + blow++; + if (!(*bbits & 0x02)) + blow++; + if (!(*bbits & 0x04)) + blow++; + if (!(*bbits & 0x08)) + blow++; + if (!(*bbits & 0x10)) + blow++; + if (!(*bbits & 0x20)) + blow++; + if (!(*bbits & 0x40)) + blow++; + } + bhigh = i * 8 + 7; + if (!(*bbits & 0x80)) + bhigh++; + if (!(*bbits & 0x40)) + bhigh++; + if (!(*bbits & 0x20)) + bhigh++; + if (!(*bbits & 0x10)) + bhigh++; + if (!(*bbits & 0x08)) + bhigh++; + if (!(*bbits & 0x04)) + bhigh++; + if (!(*bbits & 0x02)) + bhigh++; + } + } + if (ahigh + alow < bhigh + blow) + res = -1; + if (ahigh + alow > bhigh + blow) + res = 1; + if (alowp) + *alowp = alow; + if (ahighp) + *ahighp = ahigh; + if (blowp) + *blowp = blow; + if (bhighp) + *bhighp = bhigh; + return res; +} + +int STORE_ATTR_INFO_compare(const STORE_ATTR_INFO *const *a, + const STORE_ATTR_INFO *const *b) +{ + if (a == b) + return 0; + if (!a) + return -1; + if (!b) + return 1; + return attr_info_compare_compute_range((*a)->set, (*b)->set, 0, 0, 0, 0); +} + +int STORE_ATTR_INFO_in_range(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b) +{ + unsigned int alow, ahigh, blow, bhigh; + + if (a == b) + return 1; + if (!a) + return 0; + if (!b) + return 0; + attr_info_compare_compute_range(a->set, b->set, + &alow, &ahigh, &blow, &bhigh); + if (alow >= blow && ahigh <= bhigh) + return 1; + return 0; +} + +int STORE_ATTR_INFO_in(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b) +{ + unsigned char *abits, *bbits; + int i; + + if (a == b) + return 1; + if (!a) + return 0; + if (!b) + return 0; + abits = a->set; + bbits = b->set; + for (i = 0; i < (STORE_ATTR_TYPE_NUM + 8) / 8; i++, abits++, bbits++) { + if (*abits && (*bbits & *abits) != *abits) + return 0; + } + return 1; +} + +int STORE_ATTR_INFO_in_ex(STORE_ATTR_INFO *a, STORE_ATTR_INFO *b) +{ + STORE_ATTR_TYPES i; + + if (a == b) + return 1; + if (!STORE_ATTR_INFO_in(a, b)) + return 0; + for (i = 1; i < STORE_ATTR_TYPE_NUM; i++) + if (ATTR_IS_SET(a, i)) { + switch (i) { + case STORE_ATTR_FRIENDLYNAME: + case STORE_ATTR_EMAIL: + case STORE_ATTR_FILENAME: + if (strcmp(a->values[i].cstring, b->values[i].cstring)) + return 0; + break; + case STORE_ATTR_KEYID: + case STORE_ATTR_ISSUERKEYID: + case STORE_ATTR_SUBJECTKEYID: + case STORE_ATTR_ISSUERSERIALHASH: + case STORE_ATTR_CERTHASH: + if (memcmp(a->values[i].sha1string, + b->values[i].sha1string, a->value_sizes[i])) + return 0; + break; + case STORE_ATTR_ISSUER: + case STORE_ATTR_SUBJECT: + if (X509_NAME_cmp(a->values[i].dn, b->values[i].dn)) + return 0; + break; + case STORE_ATTR_SERIAL: + if (BN_cmp(a->values[i].number, b->values[i].number)) + return 0; + break; + default: + break; + } + } + + return 1; +} diff --git a/libs/openssl/crypto/store/str_locl.h b/libs/openssl/crypto/store/str_locl.h new file mode 100644 index 00000000..c0b40f0d --- /dev/null +++ b/libs/openssl/crypto/store/str_locl.h @@ -0,0 +1,125 @@ +/* crypto/store/str_locl.h */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2003. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_STORE_LOCL_H +# define HEADER_STORE_LOCL_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +struct store_method_st { + char *name; + /* + * All the functions return a positive integer or non-NULL for success + * and 0, a negative integer or NULL for failure + */ + /* Initialise the STORE with private data */ + STORE_INITIALISE_FUNC_PTR init; + /* Initialise the STORE with private data */ + STORE_CLEANUP_FUNC_PTR clean; + /* Generate an object of a given type */ + STORE_GENERATE_OBJECT_FUNC_PTR generate_object; + /* + * Get an object of a given type. This function isn't really very useful + * since the listing functions (below) can be used for the same purpose + * and are much more general. + */ + STORE_GET_OBJECT_FUNC_PTR get_object; + /* Store an object of a given type. */ + STORE_STORE_OBJECT_FUNC_PTR store_object; + /* Modify the attributes bound to an object of a given type. */ + STORE_MODIFY_OBJECT_FUNC_PTR modify_object; + /* Revoke an object of a given type. */ + STORE_HANDLE_OBJECT_FUNC_PTR revoke_object; + /* Delete an object of a given type. */ + STORE_HANDLE_OBJECT_FUNC_PTR delete_object; + /* + * List a bunch of objects of a given type and with the associated + * attributes. + */ + STORE_START_OBJECT_FUNC_PTR list_object_start; + STORE_NEXT_OBJECT_FUNC_PTR list_object_next; + STORE_END_OBJECT_FUNC_PTR list_object_end; + STORE_END_OBJECT_FUNC_PTR list_object_endp; + /* Store-level function to make any necessary update operations. */ + STORE_GENERIC_FUNC_PTR update_store; + /* Store-level function to get exclusive access to the store. */ + STORE_GENERIC_FUNC_PTR lock_store; + /* Store-level function to release exclusive access to the store. */ + STORE_GENERIC_FUNC_PTR unlock_store; + /* Generic control function */ + STORE_CTRL_FUNC_PTR ctrl; +}; + +struct store_st { + const STORE_METHOD *meth; + /* functional reference if 'meth' is ENGINE-provided */ + ENGINE *engine; + CRYPTO_EX_DATA ex_data; + int references; +}; +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/store/str_mem.c b/libs/openssl/crypto/store/str_mem.c new file mode 100644 index 00000000..6eee5bba --- /dev/null +++ b/libs/openssl/crypto/store/str_mem.c @@ -0,0 +1,383 @@ +/* crypto/store/str_mem.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2003. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "str_locl.h" + +/* + * The memory store is currently highly experimental. It's meant to become a + * base store used by other stores for internal caching (for full caching + * support, aging needs to be added). + * + * The database use is meant to support as much attribute association as + * possible, while providing for as small search ranges as possible. This is + * currently provided for by sorting the entries by numbers that are composed + * of bits set at the positions indicated by attribute type codes. This + * provides for ranges determined by the highest attribute type code value. + * A better idea might be to sort by values computed from the range of + * attributes associated with the object (basically, the difference between + * the highest and lowest attribute type code) and it's distance from a base + * (basically, the lowest associated attribute type code). + */ + +typedef struct mem_object_data_st { + STORE_OBJECT *object; + STORE_ATTR_INFO *attr_info; + int references; +} MEM_OBJECT_DATA; + +DECLARE_STACK_OF(MEM_OBJECT_DATA) +struct mem_data_st { + /* + * sorted with + * STORE_ATTR_INFO_compare(). + */ + STACK_OF(MEM_OBJECT_DATA) *data; + /* + * Currently unused, but can + * be used to add attributes + * from parts of the data. + */ + unsigned int compute_components:1; +}; + +DECLARE_STACK_OF(STORE_ATTR_INFO) +struct mem_ctx_st { + /* The type we're searching for */ + int type; + /* + * Sets of + * attributes to search for. Each + * element is a STORE_ATTR_INFO. + */ + STACK_OF(STORE_ATTR_INFO) *search_attributes; + /* + * which of the search attributes we + * found a match for, -1 when we still + * haven't found any + */ + int search_index; + /* -1 as long as we're searching for the first */ + int index; +}; + +static int mem_init(STORE *s); +static void mem_clean(STORE *s); +static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, + OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, + OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +static int mem_store(STORE *s, STORE_OBJECT_TYPES type, STORE_OBJECT *data, + OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); +static int mem_modify(STORE *s, STORE_OBJECT_TYPES type, + OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]); +static int mem_delete(STORE *s, STORE_OBJECT_TYPES type, + OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]); +static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, + OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +static STORE_OBJECT *mem_list_next(STORE *s, void *handle); +static int mem_list_end(STORE *s, void *handle); +static int mem_list_endp(STORE *s, void *handle); +static int mem_lock(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]); +static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f) (void)); + +static STORE_METHOD store_memory = { + "OpenSSL memory store interface", + mem_init, + mem_clean, + mem_generate, + mem_get, + mem_store, + mem_modify, + NULL, /* revoke */ + mem_delete, + mem_list_start, + mem_list_next, + mem_list_end, + mem_list_endp, + NULL, /* update */ + mem_lock, + mem_unlock, + mem_ctrl +}; + +const STORE_METHOD *STORE_Memory(void) +{ + return &store_memory; +} + +static int mem_init(STORE *s) +{ + return 1; +} + +static void mem_clean(STORE *s) +{ + return; +} + +static STORE_OBJECT *mem_generate(STORE *s, STORE_OBJECT_TYPES type, + OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STOREerr(STORE_F_MEM_GENERATE, STORE_R_NOT_IMPLEMENTED); + return 0; +} + +static STORE_OBJECT *mem_get(STORE *s, STORE_OBJECT_TYPES type, + OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + void *context = mem_list_start(s, type, attributes, parameters); + + if (context) { + STORE_OBJECT *object = mem_list_next(s, context); + + if (mem_list_end(s, context)) + return object; + } + return NULL; +} + +static int mem_store(STORE *s, STORE_OBJECT_TYPES type, + STORE_OBJECT *data, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + STOREerr(STORE_F_MEM_STORE, STORE_R_NOT_IMPLEMENTED); + return 0; +} + +static int mem_modify(STORE *s, STORE_OBJECT_TYPES type, + OPENSSL_ITEM search_attributes[], + OPENSSL_ITEM add_attributes[], + OPENSSL_ITEM modify_attributes[], + OPENSSL_ITEM delete_attributes[], + OPENSSL_ITEM parameters[]) +{ + STOREerr(STORE_F_MEM_MODIFY, STORE_R_NOT_IMPLEMENTED); + return 0; +} + +static int mem_delete(STORE *s, STORE_OBJECT_TYPES type, + OPENSSL_ITEM attributes[], OPENSSL_ITEM parameters[]) +{ + STOREerr(STORE_F_MEM_DELETE, STORE_R_NOT_IMPLEMENTED); + return 0; +} + +/* + * The list functions may be the hardest to understand. Basically, + * mem_list_start compiles a stack of attribute info elements, and puts that + * stack into the context to be returned. mem_list_next will then find the + * first matching element in the store, and then walk all the way to the end + * of the store (since any combination of attribute bits above the starting + * point may match the searched for bit pattern...). + */ +static void *mem_list_start(STORE *s, STORE_OBJECT_TYPES type, + OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + struct mem_ctx_st *context = + (struct mem_ctx_st *)OPENSSL_malloc(sizeof(struct mem_ctx_st)); + void *attribute_context = NULL; + STORE_ATTR_INFO *attrs = NULL; + + if (!context) { + STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); + return 0; + } + memset(context, 0, sizeof(struct mem_ctx_st)); + + attribute_context = STORE_parse_attrs_start(attributes); + if (!attribute_context) { + STOREerr(STORE_F_MEM_LIST_START, ERR_R_STORE_LIB); + goto err; + } + + while ((attrs = STORE_parse_attrs_next(attribute_context))) { + if (context->search_attributes == NULL) { + context->search_attributes = + sk_STORE_ATTR_INFO_new(STORE_ATTR_INFO_compare); + if (!context->search_attributes) { + STOREerr(STORE_F_MEM_LIST_START, ERR_R_MALLOC_FAILURE); + goto err; + } + } + sk_STORE_ATTR_INFO_push(context->search_attributes, attrs); + } + if (!STORE_parse_attrs_endp(attribute_context)) + goto err; + STORE_parse_attrs_end(attribute_context); + context->search_index = -1; + context->index = -1; + return context; + err: + if (attribute_context) + STORE_parse_attrs_end(attribute_context); + mem_list_end(s, context); + return NULL; +} + +static STORE_OBJECT *mem_list_next(STORE *s, void *handle) +{ + int i; + struct mem_ctx_st *context = (struct mem_ctx_st *)handle; + struct mem_object_data_st key = { 0, 0, 1 }; + struct mem_data_st *store = (struct mem_data_st *)STORE_get_ex_data(s, 1); + int srch; + int cres = 0; + + if (!context) { + STOREerr(STORE_F_MEM_LIST_NEXT, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if (!store) { + STOREerr(STORE_F_MEM_LIST_NEXT, STORE_R_NO_STORE); + return NULL; + } + + if (context->search_index == -1) { + for (i = 0; + i < sk_STORE_ATTR_INFO_num(context->search_attributes); i++) { + key.attr_info + = sk_STORE_ATTR_INFO_value(context->search_attributes, i); + srch = sk_MEM_OBJECT_DATA_find_ex(store->data, &key); + + if (srch >= 0) { + context->search_index = srch; + break; + } + } + } + if (context->search_index < 0) + return NULL; + + key.attr_info = + sk_STORE_ATTR_INFO_value(context->search_attributes, + context->search_index); + for (srch = context->search_index; + srch < sk_MEM_OBJECT_DATA_num(store->data) + && STORE_ATTR_INFO_in_range(key.attr_info, + sk_MEM_OBJECT_DATA_value(store->data, + srch)->attr_info) + && !(cres = + STORE_ATTR_INFO_in_ex(key.attr_info, + sk_MEM_OBJECT_DATA_value(store->data, + srch)->attr_info)); + srch++) ; + + context->search_index = srch; + if (cres) + return (sk_MEM_OBJECT_DATA_value(store->data, srch))->object; + return NULL; +} + +static int mem_list_end(STORE *s, void *handle) +{ + struct mem_ctx_st *context = (struct mem_ctx_st *)handle; + + if (!context) { + STOREerr(STORE_F_MEM_LIST_END, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (context && context->search_attributes) + sk_STORE_ATTR_INFO_free(context->search_attributes); + if (context) + OPENSSL_free(context); + return 1; +} + +static int mem_list_endp(STORE *s, void *handle) +{ + struct mem_ctx_st *context = (struct mem_ctx_st *)handle; + + if (!context + || context->search_index + == sk_STORE_ATTR_INFO_num(context->search_attributes)) + return 1; + return 0; +} + +static int mem_lock(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + return 1; +} + +static int mem_unlock(STORE *s, OPENSSL_ITEM attributes[], + OPENSSL_ITEM parameters[]) +{ + return 1; +} + +static int mem_ctrl(STORE *s, int cmd, long l, void *p, void (*f) (void)) +{ + return 1; +} diff --git a/libs/openssl/crypto/store/str_meth.c b/libs/openssl/crypto/store/str_meth.c new file mode 100644 index 00000000..c83fbc56 --- /dev/null +++ b/libs/openssl/crypto/store/str_meth.c @@ -0,0 +1,280 @@ +/* crypto/store/str_meth.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2003. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "str_locl.h" + +STORE_METHOD *STORE_create_method(char *name) +{ + STORE_METHOD *store_method = + (STORE_METHOD *)OPENSSL_malloc(sizeof(STORE_METHOD)); + + if (store_method) { + memset(store_method, 0, sizeof(*store_method)); + store_method->name = BUF_strdup(name); + } + return store_method; +} + +/* + * BIG FSCKING WARNING!!!! If you use this on a statically allocated method + * (that is, it hasn't been allocated using STORE_create_method(), you + * deserve anything Murphy can throw at you and more! You have been warned. + */ +void STORE_destroy_method(STORE_METHOD *store_method) +{ + if (!store_method) + return; + OPENSSL_free(store_method->name); + store_method->name = NULL; + OPENSSL_free(store_method); +} + +int STORE_method_set_initialise_function(STORE_METHOD *sm, + STORE_INITIALISE_FUNC_PTR init_f) +{ + sm->init = init_f; + return 1; +} + +int STORE_method_set_cleanup_function(STORE_METHOD *sm, + STORE_CLEANUP_FUNC_PTR clean_f) +{ + sm->clean = clean_f; + return 1; +} + +int STORE_method_set_generate_function(STORE_METHOD *sm, + STORE_GENERATE_OBJECT_FUNC_PTR + generate_f) +{ + sm->generate_object = generate_f; + return 1; +} + +int STORE_method_set_get_function(STORE_METHOD *sm, + STORE_GET_OBJECT_FUNC_PTR get_f) +{ + sm->get_object = get_f; + return 1; +} + +int STORE_method_set_store_function(STORE_METHOD *sm, + STORE_STORE_OBJECT_FUNC_PTR store_f) +{ + sm->store_object = store_f; + return 1; +} + +int STORE_method_set_modify_function(STORE_METHOD *sm, + STORE_MODIFY_OBJECT_FUNC_PTR modify_f) +{ + sm->modify_object = modify_f; + return 1; +} + +int STORE_method_set_revoke_function(STORE_METHOD *sm, + STORE_HANDLE_OBJECT_FUNC_PTR revoke_f) +{ + sm->revoke_object = revoke_f; + return 1; +} + +int STORE_method_set_delete_function(STORE_METHOD *sm, + STORE_HANDLE_OBJECT_FUNC_PTR delete_f) +{ + sm->delete_object = delete_f; + return 1; +} + +int STORE_method_set_list_start_function(STORE_METHOD *sm, + STORE_START_OBJECT_FUNC_PTR + list_start_f) +{ + sm->list_object_start = list_start_f; + return 1; +} + +int STORE_method_set_list_next_function(STORE_METHOD *sm, + STORE_NEXT_OBJECT_FUNC_PTR + list_next_f) +{ + sm->list_object_next = list_next_f; + return 1; +} + +int STORE_method_set_list_end_function(STORE_METHOD *sm, + STORE_END_OBJECT_FUNC_PTR list_end_f) +{ + sm->list_object_end = list_end_f; + return 1; +} + +int STORE_method_set_update_store_function(STORE_METHOD *sm, + STORE_GENERIC_FUNC_PTR update_f) +{ + sm->update_store = update_f; + return 1; +} + +int STORE_method_set_lock_store_function(STORE_METHOD *sm, + STORE_GENERIC_FUNC_PTR lock_f) +{ + sm->lock_store = lock_f; + return 1; +} + +int STORE_method_set_unlock_store_function(STORE_METHOD *sm, + STORE_GENERIC_FUNC_PTR unlock_f) +{ + sm->unlock_store = unlock_f; + return 1; +} + +int STORE_method_set_ctrl_function(STORE_METHOD *sm, + STORE_CTRL_FUNC_PTR ctrl_f) +{ + sm->ctrl = ctrl_f; + return 1; +} + +STORE_INITIALISE_FUNC_PTR STORE_method_get_initialise_function(STORE_METHOD + *sm) +{ + return sm->init; +} + +STORE_CLEANUP_FUNC_PTR STORE_method_get_cleanup_function(STORE_METHOD *sm) +{ + return sm->clean; +} + +STORE_GENERATE_OBJECT_FUNC_PTR STORE_method_get_generate_function(STORE_METHOD + *sm) +{ + return sm->generate_object; +} + +STORE_GET_OBJECT_FUNC_PTR STORE_method_get_get_function(STORE_METHOD *sm) +{ + return sm->get_object; +} + +STORE_STORE_OBJECT_FUNC_PTR STORE_method_get_store_function(STORE_METHOD *sm) +{ + return sm->store_object; +} + +STORE_MODIFY_OBJECT_FUNC_PTR STORE_method_get_modify_function(STORE_METHOD + *sm) +{ + return sm->modify_object; +} + +STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_revoke_function(STORE_METHOD + *sm) +{ + return sm->revoke_object; +} + +STORE_HANDLE_OBJECT_FUNC_PTR STORE_method_get_delete_function(STORE_METHOD + *sm) +{ + return sm->delete_object; +} + +STORE_START_OBJECT_FUNC_PTR STORE_method_get_list_start_function(STORE_METHOD + *sm) +{ + return sm->list_object_start; +} + +STORE_NEXT_OBJECT_FUNC_PTR STORE_method_get_list_next_function(STORE_METHOD + *sm) +{ + return sm->list_object_next; +} + +STORE_END_OBJECT_FUNC_PTR STORE_method_get_list_end_function(STORE_METHOD *sm) +{ + return sm->list_object_end; +} + +STORE_GENERIC_FUNC_PTR STORE_method_get_update_store_function(STORE_METHOD + *sm) +{ + return sm->update_store; +} + +STORE_GENERIC_FUNC_PTR STORE_method_get_lock_store_function(STORE_METHOD *sm) +{ + return sm->lock_store; +} + +STORE_GENERIC_FUNC_PTR STORE_method_get_unlock_store_function(STORE_METHOD + *sm) +{ + return sm->unlock_store; +} + +STORE_CTRL_FUNC_PTR STORE_method_get_ctrl_function(STORE_METHOD *sm) +{ + return sm->ctrl; +} diff --git a/libs/openssl/crypto/symhacks.h b/libs/openssl/crypto/symhacks.h new file mode 100644 index 00000000..2eadf7f3 --- /dev/null +++ b/libs/openssl/crypto/symhacks.h @@ -0,0 +1,486 @@ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_SYMHACKS_H +# define HEADER_SYMHACKS_H + +# include + +/* + * Hacks to solve the problem with linkers incapable of handling very long + * symbol names. In the case of VMS, the limit is 31 characters on VMS for + * VAX. + */ +/* + * Note that this affects util/libeay.num and util/ssleay.num... you may + * change those manually, but that's not recommended, as those files are + * controlled centrally and updated on Unix, and the central definition may + * disagree with yours, which in turn may come with shareable library + * incompatibilities. + */ +# ifdef OPENSSL_SYS_VMS + +/* Hack a long name in crypto/ex_data.c */ +# undef CRYPTO_get_ex_data_implementation +# define CRYPTO_get_ex_data_implementation CRYPTO_get_ex_data_impl +# undef CRYPTO_set_ex_data_implementation +# define CRYPTO_set_ex_data_implementation CRYPTO_set_ex_data_impl + +/* Hack a long name in crypto/asn1/a_mbstr.c */ +# undef ASN1_STRING_set_default_mask_asc +# define ASN1_STRING_set_default_mask_asc ASN1_STRING_set_def_mask_asc + +# if 0 /* No longer needed, since safestack macro + * magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_SIGNER_INFO) */ +# undef i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO +# define i2d_ASN1_SET_OF_PKCS7_SIGNER_INFO i2d_ASN1_SET_OF_PKCS7_SIGINF +# undef d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO +# define d2i_ASN1_SET_OF_PKCS7_SIGNER_INFO d2i_ASN1_SET_OF_PKCS7_SIGINF +# endif + +# if 0 /* No longer needed, since safestack macro + * magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(PKCS7_RECIP_INFO) */ +# undef i2d_ASN1_SET_OF_PKCS7_RECIP_INFO +# define i2d_ASN1_SET_OF_PKCS7_RECIP_INFO i2d_ASN1_SET_OF_PKCS7_RECINF +# undef d2i_ASN1_SET_OF_PKCS7_RECIP_INFO +# define d2i_ASN1_SET_OF_PKCS7_RECIP_INFO d2i_ASN1_SET_OF_PKCS7_RECINF +# endif + +# if 0 /* No longer needed, since safestack macro + * magic does the job */ +/* Hack the names created with DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) */ +# undef i2d_ASN1_SET_OF_ACCESS_DESCRIPTION +# define i2d_ASN1_SET_OF_ACCESS_DESCRIPTION i2d_ASN1_SET_OF_ACC_DESC +# undef d2i_ASN1_SET_OF_ACCESS_DESCRIPTION +# define d2i_ASN1_SET_OF_ACCESS_DESCRIPTION d2i_ASN1_SET_OF_ACC_DESC +# endif + +/* Hack the names created with DECLARE_PEM_rw(NETSCAPE_CERT_SEQUENCE) */ +# undef PEM_read_NETSCAPE_CERT_SEQUENCE +# define PEM_read_NETSCAPE_CERT_SEQUENCE PEM_read_NS_CERT_SEQ +# undef PEM_write_NETSCAPE_CERT_SEQUENCE +# define PEM_write_NETSCAPE_CERT_SEQUENCE PEM_write_NS_CERT_SEQ +# undef PEM_read_bio_NETSCAPE_CERT_SEQUENCE +# define PEM_read_bio_NETSCAPE_CERT_SEQUENCE PEM_read_bio_NS_CERT_SEQ +# undef PEM_write_bio_NETSCAPE_CERT_SEQUENCE +# define PEM_write_bio_NETSCAPE_CERT_SEQUENCE PEM_write_bio_NS_CERT_SEQ +# undef PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE +# define PEM_write_cb_bio_NETSCAPE_CERT_SEQUENCE PEM_write_cb_bio_NS_CERT_SEQ + +/* Hack the names created with DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO) */ +# undef PEM_read_PKCS8_PRIV_KEY_INFO +# define PEM_read_PKCS8_PRIV_KEY_INFO PEM_read_P8_PRIV_KEY_INFO +# undef PEM_write_PKCS8_PRIV_KEY_INFO +# define PEM_write_PKCS8_PRIV_KEY_INFO PEM_write_P8_PRIV_KEY_INFO +# undef PEM_read_bio_PKCS8_PRIV_KEY_INFO +# define PEM_read_bio_PKCS8_PRIV_KEY_INFO PEM_read_bio_P8_PRIV_KEY_INFO +# undef PEM_write_bio_PKCS8_PRIV_KEY_INFO +# define PEM_write_bio_PKCS8_PRIV_KEY_INFO PEM_write_bio_P8_PRIV_KEY_INFO +# undef PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO +# define PEM_write_cb_bio_PKCS8_PRIV_KEY_INFO PEM_wrt_cb_bio_P8_PRIV_KEY_INFO + +/* Hack other PEM names */ +# undef PEM_write_bio_PKCS8PrivateKey_nid +# define PEM_write_bio_PKCS8PrivateKey_nid PEM_write_bio_PKCS8PrivKey_nid + +/* Hack some long X509 names */ +# undef X509_REVOKED_get_ext_by_critical +# define X509_REVOKED_get_ext_by_critical X509_REVOKED_get_ext_by_critic +# undef X509_policy_tree_get0_user_policies +# define X509_policy_tree_get0_user_policies X509_pcy_tree_get0_usr_policies +# undef X509_policy_node_get0_qualifiers +# define X509_policy_node_get0_qualifiers X509_pcy_node_get0_qualifiers +# undef X509_STORE_CTX_get_explicit_policy +# define X509_STORE_CTX_get_explicit_policy X509_STORE_CTX_get_expl_policy +# undef X509_STORE_CTX_get0_current_issuer +# define X509_STORE_CTX_get0_current_issuer X509_STORE_CTX_get0_cur_issuer + +/* Hack some long CRYPTO names */ +# undef CRYPTO_set_dynlock_destroy_callback +# define CRYPTO_set_dynlock_destroy_callback CRYPTO_set_dynlock_destroy_cb +# undef CRYPTO_set_dynlock_create_callback +# define CRYPTO_set_dynlock_create_callback CRYPTO_set_dynlock_create_cb +# undef CRYPTO_set_dynlock_lock_callback +# define CRYPTO_set_dynlock_lock_callback CRYPTO_set_dynlock_lock_cb +# undef CRYPTO_get_dynlock_lock_callback +# define CRYPTO_get_dynlock_lock_callback CRYPTO_get_dynlock_lock_cb +# undef CRYPTO_get_dynlock_destroy_callback +# define CRYPTO_get_dynlock_destroy_callback CRYPTO_get_dynlock_destroy_cb +# undef CRYPTO_get_dynlock_create_callback +# define CRYPTO_get_dynlock_create_callback CRYPTO_get_dynlock_create_cb +# undef CRYPTO_set_locked_mem_ex_functions +# define CRYPTO_set_locked_mem_ex_functions CRYPTO_set_locked_mem_ex_funcs +# undef CRYPTO_get_locked_mem_ex_functions +# define CRYPTO_get_locked_mem_ex_functions CRYPTO_get_locked_mem_ex_funcs + +/* Hack some long SSL names */ +# undef SSL_CTX_set_default_verify_paths +# define SSL_CTX_set_default_verify_paths SSL_CTX_set_def_verify_paths +# undef SSL_get_ex_data_X509_STORE_CTX_idx +# define SSL_get_ex_data_X509_STORE_CTX_idx SSL_get_ex_d_X509_STORE_CTX_idx +# undef SSL_add_file_cert_subjects_to_stack +# define SSL_add_file_cert_subjects_to_stack SSL_add_file_cert_subjs_to_stk +# undef SSL_add_dir_cert_subjects_to_stack +# define SSL_add_dir_cert_subjects_to_stack SSL_add_dir_cert_subjs_to_stk +# undef SSL_CTX_use_certificate_chain_file +# define SSL_CTX_use_certificate_chain_file SSL_CTX_use_cert_chain_file +# undef SSL_CTX_set_cert_verify_callback +# define SSL_CTX_set_cert_verify_callback SSL_CTX_set_cert_verify_cb +# undef SSL_CTX_set_default_passwd_cb_userdata +# define SSL_CTX_set_default_passwd_cb_userdata SSL_CTX_set_def_passwd_cb_ud +# undef SSL_COMP_get_compression_methods +# define SSL_COMP_get_compression_methods SSL_COMP_get_compress_methods +# undef ssl_add_clienthello_renegotiate_ext +# define ssl_add_clienthello_renegotiate_ext ssl_add_clienthello_reneg_ext +# undef ssl_add_serverhello_renegotiate_ext +# define ssl_add_serverhello_renegotiate_ext ssl_add_serverhello_reneg_ext +# undef ssl_parse_clienthello_renegotiate_ext +# define ssl_parse_clienthello_renegotiate_ext ssl_parse_clienthello_reneg_ext +# undef ssl_parse_serverhello_renegotiate_ext +# define ssl_parse_serverhello_renegotiate_ext ssl_parse_serverhello_reneg_ext +# undef SSL_srp_server_param_with_username +# define SSL_srp_server_param_with_username SSL_srp_server_param_with_un +# undef SSL_CTX_set_srp_client_pwd_callback +# define SSL_CTX_set_srp_client_pwd_callback SSL_CTX_set_srp_client_pwd_cb +# undef SSL_CTX_set_srp_verify_param_callback +# define SSL_CTX_set_srp_verify_param_callback SSL_CTX_set_srp_vfy_param_cb +# undef SSL_CTX_set_srp_username_callback +# define SSL_CTX_set_srp_username_callback SSL_CTX_set_srp_un_cb +# undef ssl_add_clienthello_use_srtp_ext +# define ssl_add_clienthello_use_srtp_ext ssl_add_clihello_use_srtp_ext +# undef ssl_add_serverhello_use_srtp_ext +# define ssl_add_serverhello_use_srtp_ext ssl_add_serhello_use_srtp_ext +# undef ssl_parse_clienthello_use_srtp_ext +# define ssl_parse_clienthello_use_srtp_ext ssl_parse_clihello_use_srtp_ext +# undef ssl_parse_serverhello_use_srtp_ext +# define ssl_parse_serverhello_use_srtp_ext ssl_parse_serhello_use_srtp_ext +# undef SSL_CTX_set_next_protos_advertised_cb +# define SSL_CTX_set_next_protos_advertised_cb SSL_CTX_set_next_protos_adv_cb +# undef SSL_CTX_set_next_proto_select_cb +# define SSL_CTX_set_next_proto_select_cb SSL_CTX_set_next_proto_sel_cb +# undef ssl3_cbc_record_digest_supported +# define ssl3_cbc_record_digest_supported ssl3_cbc_record_digest_support +# undef ssl_check_clienthello_tlsext_late +# define ssl_check_clienthello_tlsext_late ssl_check_clihello_tlsext_late +# undef ssl_check_clienthello_tlsext_early +# define ssl_check_clienthello_tlsext_early ssl_check_clihello_tlsext_early + +/* Hack some long ENGINE names */ +# undef ENGINE_get_default_BN_mod_exp_crt +# define ENGINE_get_default_BN_mod_exp_crt ENGINE_get_def_BN_mod_exp_crt +# undef ENGINE_set_default_BN_mod_exp_crt +# define ENGINE_set_default_BN_mod_exp_crt ENGINE_set_def_BN_mod_exp_crt +# undef ENGINE_set_load_privkey_function +# define ENGINE_set_load_privkey_function ENGINE_set_load_privkey_fn +# undef ENGINE_get_load_privkey_function +# define ENGINE_get_load_privkey_function ENGINE_get_load_privkey_fn +# undef ENGINE_unregister_pkey_asn1_meths +# define ENGINE_unregister_pkey_asn1_meths ENGINE_unreg_pkey_asn1_meths +# undef ENGINE_register_all_pkey_asn1_meths +# define ENGINE_register_all_pkey_asn1_meths ENGINE_reg_all_pkey_asn1_meths +# undef ENGINE_set_default_pkey_asn1_meths +# define ENGINE_set_default_pkey_asn1_meths ENGINE_set_def_pkey_asn1_meths +# undef ENGINE_get_pkey_asn1_meth_engine +# define ENGINE_get_pkey_asn1_meth_engine ENGINE_get_pkey_asn1_meth_eng +# undef ENGINE_set_load_ssl_client_cert_function +# define ENGINE_set_load_ssl_client_cert_function \ + ENGINE_set_ld_ssl_clnt_cert_fn +# undef ENGINE_get_ssl_client_cert_function +# define ENGINE_get_ssl_client_cert_function ENGINE_get_ssl_client_cert_fn + +/* Hack some long OCSP names */ +# undef OCSP_REQUEST_get_ext_by_critical +# define OCSP_REQUEST_get_ext_by_critical OCSP_REQUEST_get_ext_by_crit +# undef OCSP_BASICRESP_get_ext_by_critical +# define OCSP_BASICRESP_get_ext_by_critical OCSP_BASICRESP_get_ext_by_crit +# undef OCSP_SINGLERESP_get_ext_by_critical +# define OCSP_SINGLERESP_get_ext_by_critical OCSP_SINGLERESP_get_ext_by_crit + +/* Hack some long DES names */ +# undef _ossl_old_des_ede3_cfb64_encrypt +# define _ossl_old_des_ede3_cfb64_encrypt _ossl_odes_ede3_cfb64_encrypt +# undef _ossl_old_des_ede3_ofb64_encrypt +# define _ossl_old_des_ede3_ofb64_encrypt _ossl_odes_ede3_ofb64_encrypt + +/* Hack some long EVP names */ +# undef OPENSSL_add_all_algorithms_noconf +# define OPENSSL_add_all_algorithms_noconf OPENSSL_add_all_algo_noconf +# undef OPENSSL_add_all_algorithms_conf +# define OPENSSL_add_all_algorithms_conf OPENSSL_add_all_algo_conf +# undef EVP_PKEY_meth_set_verify_recover +# define EVP_PKEY_meth_set_verify_recover EVP_PKEY_meth_set_vrfy_recover + +/* Hack some long EC names */ +# undef EC_GROUP_set_point_conversion_form +# define EC_GROUP_set_point_conversion_form EC_GROUP_set_point_conv_form +# undef EC_GROUP_get_point_conversion_form +# define EC_GROUP_get_point_conversion_form EC_GROUP_get_point_conv_form +# undef EC_GROUP_clear_free_all_extra_data +# define EC_GROUP_clear_free_all_extra_data EC_GROUP_clr_free_all_xtra_data +# undef EC_KEY_set_public_key_affine_coordinates +# define EC_KEY_set_public_key_affine_coordinates \ + EC_KEY_set_pub_key_aff_coords +# undef EC_POINT_set_Jprojective_coordinates_GFp +# define EC_POINT_set_Jprojective_coordinates_GFp \ + EC_POINT_set_Jproj_coords_GFp +# undef EC_POINT_get_Jprojective_coordinates_GFp +# define EC_POINT_get_Jprojective_coordinates_GFp \ + EC_POINT_get_Jproj_coords_GFp +# undef EC_POINT_set_affine_coordinates_GFp +# define EC_POINT_set_affine_coordinates_GFp EC_POINT_set_affine_coords_GFp +# undef EC_POINT_get_affine_coordinates_GFp +# define EC_POINT_get_affine_coordinates_GFp EC_POINT_get_affine_coords_GFp +# undef EC_POINT_set_compressed_coordinates_GFp +# define EC_POINT_set_compressed_coordinates_GFp EC_POINT_set_compr_coords_GFp +# undef EC_POINT_set_affine_coordinates_GF2m +# define EC_POINT_set_affine_coordinates_GF2m EC_POINT_set_affine_coords_GF2m +# undef EC_POINT_get_affine_coordinates_GF2m +# define EC_POINT_get_affine_coordinates_GF2m EC_POINT_get_affine_coords_GF2m +# undef EC_POINT_set_compressed_coordinates_GF2m +# define EC_POINT_set_compressed_coordinates_GF2m \ + EC_POINT_set_compr_coords_GF2m +# undef ec_GF2m_simple_group_clear_finish +# define ec_GF2m_simple_group_clear_finish ec_GF2m_simple_grp_clr_finish +# undef ec_GF2m_simple_group_check_discriminant +# define ec_GF2m_simple_group_check_discriminant ec_GF2m_simple_grp_chk_discrim +# undef ec_GF2m_simple_point_clear_finish +# define ec_GF2m_simple_point_clear_finish ec_GF2m_simple_pt_clr_finish +# undef ec_GF2m_simple_point_set_to_infinity +# define ec_GF2m_simple_point_set_to_infinity ec_GF2m_simple_pt_set_to_inf +# undef ec_GF2m_simple_points_make_affine +# define ec_GF2m_simple_points_make_affine ec_GF2m_simple_pts_make_affine +# undef ec_GF2m_simple_point_set_affine_coordinates +# define ec_GF2m_simple_point_set_affine_coordinates \ + ec_GF2m_smp_pt_set_af_coords +# undef ec_GF2m_simple_point_get_affine_coordinates +# define ec_GF2m_simple_point_get_affine_coordinates \ + ec_GF2m_smp_pt_get_af_coords +# undef ec_GF2m_simple_set_compressed_coordinates +# define ec_GF2m_simple_set_compressed_coordinates \ + ec_GF2m_smp_set_compr_coords +# undef ec_GFp_simple_group_set_curve_GFp +# define ec_GFp_simple_group_set_curve_GFp ec_GFp_simple_grp_set_curve_GFp +# undef ec_GFp_simple_group_get_curve_GFp +# define ec_GFp_simple_group_get_curve_GFp ec_GFp_simple_grp_get_curve_GFp +# undef ec_GFp_simple_group_clear_finish +# define ec_GFp_simple_group_clear_finish ec_GFp_simple_grp_clear_finish +# undef ec_GFp_simple_group_set_generator +# define ec_GFp_simple_group_set_generator ec_GFp_simple_grp_set_generator +# undef ec_GFp_simple_group_get0_generator +# define ec_GFp_simple_group_get0_generator ec_GFp_simple_grp_gt0_generator +# undef ec_GFp_simple_group_get_cofactor +# define ec_GFp_simple_group_get_cofactor ec_GFp_simple_grp_get_cofactor +# undef ec_GFp_simple_point_clear_finish +# define ec_GFp_simple_point_clear_finish ec_GFp_simple_pt_clear_finish +# undef ec_GFp_simple_point_set_to_infinity +# define ec_GFp_simple_point_set_to_infinity ec_GFp_simple_pt_set_to_inf +# undef ec_GFp_simple_points_make_affine +# define ec_GFp_simple_points_make_affine ec_GFp_simple_pts_make_affine +# undef ec_GFp_simple_set_Jprojective_coordinates_GFp +# define ec_GFp_simple_set_Jprojective_coordinates_GFp \ + ec_GFp_smp_set_Jproj_coords_GFp +# undef ec_GFp_simple_get_Jprojective_coordinates_GFp +# define ec_GFp_simple_get_Jprojective_coordinates_GFp \ + ec_GFp_smp_get_Jproj_coords_GFp +# undef ec_GFp_simple_point_set_affine_coordinates_GFp +# define ec_GFp_simple_point_set_affine_coordinates_GFp \ + ec_GFp_smp_pt_set_af_coords_GFp +# undef ec_GFp_simple_point_get_affine_coordinates_GFp +# define ec_GFp_simple_point_get_affine_coordinates_GFp \ + ec_GFp_smp_pt_get_af_coords_GFp +# undef ec_GFp_simple_set_compressed_coordinates_GFp +# define ec_GFp_simple_set_compressed_coordinates_GFp \ + ec_GFp_smp_set_compr_coords_GFp +# undef ec_GFp_simple_point_set_affine_coordinates +# define ec_GFp_simple_point_set_affine_coordinates \ + ec_GFp_smp_pt_set_af_coords +# undef ec_GFp_simple_point_get_affine_coordinates +# define ec_GFp_simple_point_get_affine_coordinates \ + ec_GFp_smp_pt_get_af_coords +# undef ec_GFp_simple_set_compressed_coordinates +# define ec_GFp_simple_set_compressed_coordinates \ + ec_GFp_smp_set_compr_coords +# undef ec_GFp_simple_group_check_discriminant +# define ec_GFp_simple_group_check_discriminant ec_GFp_simple_grp_chk_discrim + +/* Hack som long STORE names */ +# undef STORE_method_set_initialise_function +# define STORE_method_set_initialise_function STORE_meth_set_initialise_fn +# undef STORE_method_set_cleanup_function +# define STORE_method_set_cleanup_function STORE_meth_set_cleanup_fn +# undef STORE_method_set_generate_function +# define STORE_method_set_generate_function STORE_meth_set_generate_fn +# undef STORE_method_set_modify_function +# define STORE_method_set_modify_function STORE_meth_set_modify_fn +# undef STORE_method_set_revoke_function +# define STORE_method_set_revoke_function STORE_meth_set_revoke_fn +# undef STORE_method_set_delete_function +# define STORE_method_set_delete_function STORE_meth_set_delete_fn +# undef STORE_method_set_list_start_function +# define STORE_method_set_list_start_function STORE_meth_set_list_start_fn +# undef STORE_method_set_list_next_function +# define STORE_method_set_list_next_function STORE_meth_set_list_next_fn +# undef STORE_method_set_list_end_function +# define STORE_method_set_list_end_function STORE_meth_set_list_end_fn +# undef STORE_method_set_update_store_function +# define STORE_method_set_update_store_function STORE_meth_set_update_store_fn +# undef STORE_method_set_lock_store_function +# define STORE_method_set_lock_store_function STORE_meth_set_lock_store_fn +# undef STORE_method_set_unlock_store_function +# define STORE_method_set_unlock_store_function STORE_meth_set_unlock_store_fn +# undef STORE_method_get_initialise_function +# define STORE_method_get_initialise_function STORE_meth_get_initialise_fn +# undef STORE_method_get_cleanup_function +# define STORE_method_get_cleanup_function STORE_meth_get_cleanup_fn +# undef STORE_method_get_generate_function +# define STORE_method_get_generate_function STORE_meth_get_generate_fn +# undef STORE_method_get_modify_function +# define STORE_method_get_modify_function STORE_meth_get_modify_fn +# undef STORE_method_get_revoke_function +# define STORE_method_get_revoke_function STORE_meth_get_revoke_fn +# undef STORE_method_get_delete_function +# define STORE_method_get_delete_function STORE_meth_get_delete_fn +# undef STORE_method_get_list_start_function +# define STORE_method_get_list_start_function STORE_meth_get_list_start_fn +# undef STORE_method_get_list_next_function +# define STORE_method_get_list_next_function STORE_meth_get_list_next_fn +# undef STORE_method_get_list_end_function +# define STORE_method_get_list_end_function STORE_meth_get_list_end_fn +# undef STORE_method_get_update_store_function +# define STORE_method_get_update_store_function STORE_meth_get_update_store_fn +# undef STORE_method_get_lock_store_function +# define STORE_method_get_lock_store_function STORE_meth_get_lock_store_fn +# undef STORE_method_get_unlock_store_function +# define STORE_method_get_unlock_store_function STORE_meth_get_unlock_store_fn + +/* Hack some long TS names */ +# undef TS_RESP_CTX_set_status_info_cond +# define TS_RESP_CTX_set_status_info_cond TS_RESP_CTX_set_stat_info_cond +# undef TS_RESP_CTX_set_clock_precision_digits +# define TS_RESP_CTX_set_clock_precision_digits TS_RESP_CTX_set_clk_prec_digits +# undef TS_CONF_set_clock_precision_digits +# define TS_CONF_set_clock_precision_digits TS_CONF_set_clk_prec_digits + +/* Hack some long CMS names */ +# undef CMS_RecipientInfo_ktri_get0_algs +# define CMS_RecipientInfo_ktri_get0_algs CMS_RecipInfo_ktri_get0_algs +# undef CMS_RecipientInfo_ktri_get0_signer_id +# define CMS_RecipientInfo_ktri_get0_signer_id CMS_RecipInfo_ktri_get0_sigr_id +# undef CMS_OtherRevocationInfoFormat_it +# define CMS_OtherRevocationInfoFormat_it CMS_OtherRevocInfoFormat_it +# undef CMS_KeyAgreeRecipientIdentifier_it +# define CMS_KeyAgreeRecipientIdentifier_it CMS_KeyAgreeRecipIdentifier_it +# undef CMS_OriginatorIdentifierOrKey_it +# define CMS_OriginatorIdentifierOrKey_it CMS_OriginatorIdOrKey_it +# undef cms_SignerIdentifier_get0_signer_id +# define cms_SignerIdentifier_get0_signer_id cms_SignerId_get0_signer_id + +/* Hack some long DTLS1 names */ +# undef dtls1_retransmit_buffered_messages +# define dtls1_retransmit_buffered_messages dtls1_retransmit_buffered_msgs + +/* Hack some long SRP names */ +# undef SRP_generate_server_master_secret +# define SRP_generate_server_master_secret SRP_gen_server_master_secret +# undef SRP_generate_client_master_secret +# define SRP_generate_client_master_secret SRP_gen_client_master_secret + +/* Hack some long UI names */ +# undef UI_method_get_prompt_constructor +# define UI_method_get_prompt_constructor UI_method_get_prompt_constructr +# undef UI_method_set_prompt_constructor +# define UI_method_set_prompt_constructor UI_method_set_prompt_constructr + +# endif /* defined OPENSSL_SYS_VMS */ + +/* Case insensitive linking causes problems.... */ +# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) +# undef ERR_load_CRYPTO_strings +# define ERR_load_CRYPTO_strings ERR_load_CRYPTOlib_strings +# undef OCSP_crlID_new +# define OCSP_crlID_new OCSP_crlID2_new + +# undef d2i_ECPARAMETERS +# define d2i_ECPARAMETERS d2i_UC_ECPARAMETERS +# undef i2d_ECPARAMETERS +# define i2d_ECPARAMETERS i2d_UC_ECPARAMETERS +# undef d2i_ECPKPARAMETERS +# define d2i_ECPKPARAMETERS d2i_UC_ECPKPARAMETERS +# undef i2d_ECPKPARAMETERS +# define i2d_ECPKPARAMETERS i2d_UC_ECPKPARAMETERS + +/* + * These functions do not seem to exist! However, I'm paranoid... Original + * command in x509v3.h: These functions are being redefined in another + * directory, and clash when the linker is case-insensitive, so let's hide + * them a little, by giving them an extra 'o' at the beginning of the name... + */ +# undef X509v3_cleanup_extensions +# define X509v3_cleanup_extensions oX509v3_cleanup_extensions +# undef X509v3_add_extension +# define X509v3_add_extension oX509v3_add_extension +# undef X509v3_add_netscape_extensions +# define X509v3_add_netscape_extensions oX509v3_add_netscape_extensions +# undef X509v3_add_standard_extensions +# define X509v3_add_standard_extensions oX509v3_add_standard_extensions + +/* This one clashes with CMS_data_create */ +# undef cms_Data_create +# define cms_Data_create priv_cms_Data_create + +# endif + +#endif /* ! defined HEADER_VMS_IDHACKS_H */ diff --git a/libs/openssl/crypto/threads/README b/libs/openssl/crypto/threads/README new file mode 100644 index 00000000..df6b26e1 --- /dev/null +++ b/libs/openssl/crypto/threads/README @@ -0,0 +1,14 @@ +Mutithreading testing area. + +Since this stuff is very very platorm specific, this is not part of the +normal build. Have a read of doc/threads.doc. + +mttest will do some testing and will currently build under Windows NT/95, +Solaris and Linux. The IRIX stuff is not finished. + +I have tested this program on a 12 CPU ultra sparc box (solaris 2.5.1) +and things seem to work ok. + +The Linux pthreads package can be retrieved from +http://www.mit.edu:8001/people/proven/pthreads.html + diff --git a/libs/openssl/crypto/threads/mttest.c b/libs/openssl/crypto/threads/mttest.c new file mode 100644 index 00000000..dbff4a69 --- /dev/null +++ b/libs/openssl/crypto/threads/mttest.c @@ -0,0 +1,1211 @@ +/* crypto/threads/mttest.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#ifdef LINUX +# include +#endif +#ifdef OPENSSL_SYS_WIN32 +# include +#endif +#ifdef SOLARIS +# include +# include +#endif +#ifdef IRIX +# include +# include +#endif +#ifdef PTHREADS +# include +#endif +#ifdef OPENSSL_SYS_NETWARE +# if !defined __int64 +# define __int64 long long +# endif +# include +#endif +#include +#include +#include +#include +#include +#include +#include + +#ifdef OPENSSL_SYS_NETWARE +# define TEST_SERVER_CERT "/openssl/apps/server.pem" +# define TEST_CLIENT_CERT "/openssl/apps/client.pem" +#else +# define TEST_SERVER_CERT "../../apps/server.pem" +# define TEST_CLIENT_CERT "../../apps/client.pem" +#endif + +#define MAX_THREAD_NUMBER 100 + +int verify_callback(int ok, X509_STORE_CTX *xs); +void thread_setup(void); +void thread_cleanup(void); +void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx); + +void irix_locking_callback(int mode, int type, const char *file, int line); +void solaris_locking_callback(int mode, int type, const char *file, int line); +void win32_locking_callback(int mode, int type, const char *file, int line); +void pthreads_locking_callback(int mode, int type, const char *file, int line); +void netware_locking_callback(int mode, int type, const char *file, int line); +void beos_locking_callback(int mode, int type, const char *file, int line); + +void irix_thread_id(CRYPTO_THREADID *tid); +void solaris_thread_id(CRYPTO_THREADID *tid); +void pthreads_thread_id(CRYPTO_THREADID *tid); +void netware_thread_id(CRYPTO_THREADID *tid); +void beos_thread_id(CRYPTO_THREADID *tid); + +#if defined(OPENSSL_SYS_NETWARE) +static MPKMutex *lock_cs; +static MPKSema ThreadSem; +static long *lock_count; +#endif + +BIO *bio_err = NULL; +BIO *bio_stdout = NULL; + +static char *cipher = NULL; +int verbose = 0; +#ifdef FIONBIO +static int s_nbio = 0; +#endif + +int thread_number = 10; +int number_of_loops = 10; +int reconnect = 0; +int cache_stats = 0; + +static const char rnd_seed[] = + "string to make the random number generator think it has entropy"; + +int doit(char *ctx[4]); +static void print_stats(BIO *bio, SSL_CTX *ctx) +{ + BIO_printf(bio, "%4ld items in the session cache\n", + SSL_CTX_sess_number(ctx)); + BIO_printf(bio, "%4d client connects (SSL_connect())\n", + SSL_CTX_sess_connect(ctx)); + BIO_printf(bio, "%4d client connects that finished\n", + SSL_CTX_sess_connect_good(ctx)); + BIO_printf(bio, "%4d server connects (SSL_accept())\n", + SSL_CTX_sess_accept(ctx)); + BIO_printf(bio, "%4d server connects that finished\n", + SSL_CTX_sess_accept_good(ctx)); + BIO_printf(bio, "%4d session cache hits\n", SSL_CTX_sess_hits(ctx)); + BIO_printf(bio, "%4d session cache misses\n", SSL_CTX_sess_misses(ctx)); + BIO_printf(bio, "%4d session cache timeouts\n", SSL_CTX_sess_timeouts(ctx)); +} + +static void sv_usage(void) +{ + BIO_printf(bio_err, "usage: ssltest [args ...]\n"); + BIO_printf(bio_err, "\n"); + BIO_printf(bio_err, " -server_auth - check server certificate\n"); + BIO_printf(bio_err, " -client_auth - do client authentication\n"); + BIO_printf(bio_err, " -v - more output\n"); + BIO_printf(bio_err, " -CApath arg - PEM format directory of CA's\n"); + BIO_printf(bio_err, " -CAfile arg - PEM format file of CA's\n"); + BIO_printf(bio_err, " -threads arg - number of threads\n"); + BIO_printf(bio_err, " -loops arg - number of 'connections', per thread\n"); + BIO_printf(bio_err, " -reconnect - reuse session-id's\n"); + BIO_printf(bio_err, " -stats - server session-id cache stats\n"); + BIO_printf(bio_err, " -cert arg - server certificate/key\n"); + BIO_printf(bio_err, " -ccert arg - client certificate/key\n"); + BIO_printf(bio_err, " -ssl3 - just SSLv3n\n"); +} + +int main(int argc, char *argv[]) +{ + char *CApath = NULL, *CAfile = NULL; + int badop = 0; + int ret = 1; + int client_auth = 0; + int server_auth = 0; + SSL_CTX *s_ctx = NULL; + SSL_CTX *c_ctx = NULL; + char *scert = TEST_SERVER_CERT; + char *ccert = TEST_CLIENT_CERT; + const SSL_METHOD *ssl_method = SSLv23_method(); + + RAND_seed(rnd_seed, sizeof rnd_seed); + + if (bio_err == NULL) + bio_err = BIO_new_fd(2, BIO_NOCLOSE); + if (bio_stdout == NULL) + bio_stdout = BIO_new_fd(1, BIO_NOCLOSE); + argc--; + argv++; + + while (argc >= 1) { + if (strcmp(*argv, "-server_auth") == 0) + server_auth = 1; + else if (strcmp(*argv, "-client_auth") == 0) + client_auth = 1; + else if (strcmp(*argv, "-reconnect") == 0) + reconnect = 1; + else if (strcmp(*argv, "-stats") == 0) + cache_stats = 1; + else if (strcmp(*argv, "-ssl3") == 0) + ssl_method = SSLv3_method(); + else if (strcmp(*argv, "-ssl2") == 0) + ssl_method = SSLv2_method(); + else if (strcmp(*argv, "-CApath") == 0) { + if (--argc < 1) + goto bad; + CApath = *(++argv); + } else if (strcmp(*argv, "-CAfile") == 0) { + if (--argc < 1) + goto bad; + CAfile = *(++argv); + } else if (strcmp(*argv, "-cert") == 0) { + if (--argc < 1) + goto bad; + scert = *(++argv); + } else if (strcmp(*argv, "-ccert") == 0) { + if (--argc < 1) + goto bad; + ccert = *(++argv); + } else if (strcmp(*argv, "-threads") == 0) { + if (--argc < 1) + goto bad; + thread_number = atoi(*(++argv)); + if (thread_number == 0) + thread_number = 1; + if (thread_number > MAX_THREAD_NUMBER) + thread_number = MAX_THREAD_NUMBER; + } else if (strcmp(*argv, "-loops") == 0) { + if (--argc < 1) + goto bad; + number_of_loops = atoi(*(++argv)); + if (number_of_loops == 0) + number_of_loops = 1; + } else { + BIO_printf(bio_err, "unknown option %s\n", *argv); + badop = 1; + break; + } + argc--; + argv++; + } + if (badop) { + bad: + sv_usage(); + goto end; + } + + if (cipher == NULL && OPENSSL_issetugid() == 0) + cipher = getenv("SSL_CIPHER"); + + SSL_load_error_strings(); + OpenSSL_add_ssl_algorithms(); + + c_ctx = SSL_CTX_new(ssl_method); + s_ctx = SSL_CTX_new(ssl_method); + if ((c_ctx == NULL) || (s_ctx == NULL)) { + ERR_print_errors(bio_err); + goto end; + } + + SSL_CTX_set_session_cache_mode(s_ctx, + SSL_SESS_CACHE_NO_AUTO_CLEAR | + SSL_SESS_CACHE_SERVER); + SSL_CTX_set_session_cache_mode(c_ctx, + SSL_SESS_CACHE_NO_AUTO_CLEAR | + SSL_SESS_CACHE_SERVER); + + if (!SSL_CTX_use_certificate_file(s_ctx, scert, SSL_FILETYPE_PEM)) { + BIO_printf(bio_err, "SSL_CTX_use_certificate_file (%s)\n", scert); + ERR_print_errors(bio_err); + goto end; + } else + if (!SSL_CTX_use_RSAPrivateKey_file(s_ctx, scert, SSL_FILETYPE_PEM)) { + BIO_printf(bio_err, "SSL_CTX_use_RSAPrivateKey_file (%s)\n", scert); + ERR_print_errors(bio_err); + goto end; + } + + if (client_auth) { + SSL_CTX_use_certificate_file(c_ctx, ccert, SSL_FILETYPE_PEM); + SSL_CTX_use_RSAPrivateKey_file(c_ctx, ccert, SSL_FILETYPE_PEM); + } + + if ((!SSL_CTX_load_verify_locations(s_ctx, CAfile, CApath)) || + (!SSL_CTX_set_default_verify_paths(s_ctx)) || + (!SSL_CTX_load_verify_locations(c_ctx, CAfile, CApath)) || + (!SSL_CTX_set_default_verify_paths(c_ctx))) { + BIO_printf(bio_err, "SSL_load_verify_locations\n"); + ERR_print_errors(bio_err); + goto end; + } + + if (client_auth) { + BIO_printf(bio_err, "client authentication\n"); + SSL_CTX_set_verify(s_ctx, + SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, + verify_callback); + } + if (server_auth) { + BIO_printf(bio_err, "server authentication\n"); + SSL_CTX_set_verify(c_ctx, SSL_VERIFY_PEER, verify_callback); + } + + thread_setup(); + do_threads(s_ctx, c_ctx); + thread_cleanup(); + end: + + if (c_ctx != NULL) { + BIO_printf(bio_err, "Client SSL_CTX stats then free it\n"); + print_stats(bio_err, c_ctx); + SSL_CTX_free(c_ctx); + } + if (s_ctx != NULL) { + BIO_printf(bio_err, "Server SSL_CTX stats then free it\n"); + print_stats(bio_err, s_ctx); + if (cache_stats) { + BIO_printf(bio_err, "-----\n"); + lh_SSL_SESSION_stats_bio(SSL_CTX_sessions(s_ctx), bio_err); + BIO_printf(bio_err, "-----\n"); + /*- lh_SSL_SESSION_node_stats_bio(SSL_CTX_sessions(s_ctx),bio_err); + BIO_printf(bio_err,"-----\n"); */ + lh_SSL_SESSION_node_usage_stats_bio(SSL_CTX_sessions(s_ctx), bio_err); + BIO_printf(bio_err, "-----\n"); + } + SSL_CTX_free(s_ctx); + BIO_printf(bio_err, "done free\n"); + } + exit(ret); + return (0); +} + +#define W_READ 1 +#define W_WRITE 2 +#define C_DONE 1 +#define S_DONE 2 + +int ndoit(SSL_CTX *ssl_ctx[2]) +{ + int i; + int ret; + char *ctx[4]; + CRYPTO_THREADID thread_id; + + ctx[0] = (char *)ssl_ctx[0]; + ctx[1] = (char *)ssl_ctx[1]; + + if (reconnect) { + ctx[2] = (char *)SSL_new(ssl_ctx[0]); + ctx[3] = (char *)SSL_new(ssl_ctx[1]); + } else { + ctx[2] = NULL; + ctx[3] = NULL; + } + + CRYPTO_THREADID_current(&thread_id); + BIO_printf(bio_stdout, "started thread %lu\n", + CRYPTO_THREADID_hash(&thread_id)); + for (i = 0; i < number_of_loops; i++) { +/*- BIO_printf(bio_err,"%4d %2d ctx->ref (%3d,%3d)\n", + CRYPTO_THREADID_hash(&thread_id),i, + ssl_ctx[0]->references, + ssl_ctx[1]->references); */ +/* pthread_delay_np(&tm); */ + + ret = doit(ctx); + if (ret != 0) { + BIO_printf(bio_stdout, "error[%d] %lu - %d\n", + i, CRYPTO_THREADID_hash(&thread_id), ret); + return (ret); + } + } + BIO_printf(bio_stdout, "DONE %lu\n", CRYPTO_THREADID_hash(&thread_id)); + if (reconnect) { + SSL_free((SSL *)ctx[2]); + SSL_free((SSL *)ctx[3]); + } +#ifdef OPENSSL_SYS_NETWARE + MPKSemaphoreSignal(ThreadSem); +#endif + return (0); +} + +int doit(char *ctx[4]) +{ + SSL_CTX *s_ctx, *c_ctx; + static char cbuf[200], sbuf[200]; + SSL *c_ssl = NULL; + SSL *s_ssl = NULL; + BIO *c_to_s = NULL; + BIO *s_to_c = NULL; + BIO *c_bio = NULL; + BIO *s_bio = NULL; + int c_r, c_w, s_r, s_w; + int c_want, s_want; + int i; + int done = 0; + int c_write, s_write; + int do_server = 0, do_client = 0; + + s_ctx = (SSL_CTX *)ctx[0]; + c_ctx = (SSL_CTX *)ctx[1]; + + if (ctx[2] != NULL) + s_ssl = (SSL *)ctx[2]; + else + s_ssl = SSL_new(s_ctx); + + if (ctx[3] != NULL) + c_ssl = (SSL *)ctx[3]; + else + c_ssl = SSL_new(c_ctx); + + if ((s_ssl == NULL) || (c_ssl == NULL)) + goto err; + + c_to_s = BIO_new(BIO_s_mem()); + s_to_c = BIO_new(BIO_s_mem()); + if ((s_to_c == NULL) || (c_to_s == NULL)) + goto err; + + c_bio = BIO_new(BIO_f_ssl()); + s_bio = BIO_new(BIO_f_ssl()); + if ((c_bio == NULL) || (s_bio == NULL)) + goto err; + + SSL_set_connect_state(c_ssl); + SSL_set_bio(c_ssl, s_to_c, c_to_s); + BIO_set_ssl(c_bio, c_ssl, (ctx[2] == NULL) ? BIO_CLOSE : BIO_NOCLOSE); + + SSL_set_accept_state(s_ssl); + SSL_set_bio(s_ssl, c_to_s, s_to_c); + BIO_set_ssl(s_bio, s_ssl, (ctx[3] == NULL) ? BIO_CLOSE : BIO_NOCLOSE); + + c_r = 0; + s_r = 1; + c_w = 1; + s_w = 0; + c_want = W_WRITE; + s_want = 0; + c_write = 1, s_write = 0; + + /* We can always do writes */ + for (;;) { + do_server = 0; + do_client = 0; + + i = (int)BIO_pending(s_bio); + if ((i && s_r) || s_w) + do_server = 1; + + i = (int)BIO_pending(c_bio); + if ((i && c_r) || c_w) + do_client = 1; + + if (do_server && verbose) { + if (SSL_in_init(s_ssl)) + BIO_printf(bio_stdout, "server waiting in SSL_accept - %s\n", + SSL_state_string_long(s_ssl)); + else if (s_write) + BIO_printf(bio_stdout, "server:SSL_write()\n"); + else + BIO_printf(bio_stdout, "server:SSL_read()\n"); + } + + if (do_client && verbose) { + if (SSL_in_init(c_ssl)) + BIO_printf(bio_stdout, "client waiting in SSL_connect - %s\n", + SSL_state_string_long(c_ssl)); + else if (c_write) + BIO_printf(bio_stdout, "client:SSL_write()\n"); + else + BIO_printf(bio_stdout, "client:SSL_read()\n"); + } + + if (!do_client && !do_server) { + BIO_printf(bio_stdout, "ERROR IN STARTUP\n"); + break; + } + if (do_client && !(done & C_DONE)) { + if (c_write) { + i = BIO_write(c_bio, "hello from client\n", 18); + if (i < 0) { + c_r = 0; + c_w = 0; + if (BIO_should_retry(c_bio)) { + if (BIO_should_read(c_bio)) + c_r = 1; + if (BIO_should_write(c_bio)) + c_w = 1; + } else { + BIO_printf(bio_err, "ERROR in CLIENT\n"); + ERR_print_errors_fp(stderr); + return (1); + } + } else if (i == 0) { + BIO_printf(bio_err, "SSL CLIENT STARTUP FAILED\n"); + return (1); + } else { + /* ok */ + c_write = 0; + } + } else { + i = BIO_read(c_bio, cbuf, 100); + if (i < 0) { + c_r = 0; + c_w = 0; + if (BIO_should_retry(c_bio)) { + if (BIO_should_read(c_bio)) + c_r = 1; + if (BIO_should_write(c_bio)) + c_w = 1; + } else { + BIO_printf(bio_err, "ERROR in CLIENT\n"); + ERR_print_errors_fp(stderr); + return (1); + } + } else if (i == 0) { + BIO_printf(bio_err, "SSL CLIENT STARTUP FAILED\n"); + return (1); + } else { + done |= C_DONE; +#ifdef undef + BIO_printf(bio_stdout, "CLIENT:from server:"); + BIO_write(bio_stdout, cbuf, i); + BIO_flush(bio_stdout); +#endif + } + } + } + + if (do_server && !(done & S_DONE)) { + if (!s_write) { + i = BIO_read(s_bio, sbuf, 100); + if (i < 0) { + s_r = 0; + s_w = 0; + if (BIO_should_retry(s_bio)) { + if (BIO_should_read(s_bio)) + s_r = 1; + if (BIO_should_write(s_bio)) + s_w = 1; + } else { + BIO_printf(bio_err, "ERROR in SERVER\n"); + ERR_print_errors_fp(stderr); + return (1); + } + } else if (i == 0) { + BIO_printf(bio_err, "SSL SERVER STARTUP FAILED\n"); + return (1); + } else { + s_write = 1; + s_w = 1; +#ifdef undef + BIO_printf(bio_stdout, "SERVER:from client:"); + BIO_write(bio_stdout, sbuf, i); + BIO_flush(bio_stdout); +#endif + } + } else { + i = BIO_write(s_bio, "hello from server\n", 18); + if (i < 0) { + s_r = 0; + s_w = 0; + if (BIO_should_retry(s_bio)) { + if (BIO_should_read(s_bio)) + s_r = 1; + if (BIO_should_write(s_bio)) + s_w = 1; + } else { + BIO_printf(bio_err, "ERROR in SERVER\n"); + ERR_print_errors_fp(stderr); + return (1); + } + } else if (i == 0) { + BIO_printf(bio_err, "SSL SERVER STARTUP FAILED\n"); + return (1); + } else { + s_write = 0; + s_r = 1; + done |= S_DONE; + } + } + } + + if ((done & S_DONE) && (done & C_DONE)) + break; +#if defined(OPENSSL_SYS_NETWARE) + ThreadSwitchWithDelay(); +#endif + } + + SSL_set_shutdown(c_ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); + SSL_set_shutdown(s_ssl, SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); + +#ifdef undef + BIO_printf(bio_stdout, "DONE\n"); +#endif + err: + /* + * We have to set the BIO's to NULL otherwise they will be free()ed + * twice. Once when th s_ssl is SSL_free()ed and again when c_ssl is + * SSL_free()ed. This is a hack required because s_ssl and c_ssl are + * sharing the same BIO structure and SSL_set_bio() and SSL_free() + * automatically BIO_free non NULL entries. You should not normally do + * this or be required to do this + */ + + if (s_ssl != NULL) { + s_ssl->rbio = NULL; + s_ssl->wbio = NULL; + } + if (c_ssl != NULL) { + c_ssl->rbio = NULL; + c_ssl->wbio = NULL; + } + + /* The SSL's are optionally freed in the following calls */ + if (c_to_s != NULL) + BIO_free(c_to_s); + if (s_to_c != NULL) + BIO_free(s_to_c); + + if (c_bio != NULL) + BIO_free(c_bio); + if (s_bio != NULL) + BIO_free(s_bio); + return (0); +} + +int verify_callback(int ok, X509_STORE_CTX *ctx) +{ + char *s, buf[256]; + + if (verbose) { + s = X509_NAME_oneline(X509_get_subject_name(ctx->current_cert), + buf, 256); + if (s != NULL) { + if (ok) + BIO_printf(bio_err, "depth=%d %s\n", ctx->error_depth, buf); + else + BIO_printf(bio_err, "depth=%d error=%d %s\n", + ctx->error_depth, ctx->error, buf); + } + } + return (ok); +} + +#define THREAD_STACK_SIZE (16*1024) + +#ifdef OPENSSL_SYS_WIN32 + +static HANDLE *lock_cs; + +void thread_setup(void) +{ + int i; + + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE)); + for (i = 0; i < CRYPTO_num_locks(); i++) { + lock_cs[i] = CreateMutex(NULL, FALSE, NULL); + } + + CRYPTO_set_locking_callback((void (*)(int, int, char *, int)) + win32_locking_callback); + /* id callback defined */ +} + +void thread_cleanup(void) +{ + int i; + + CRYPTO_set_locking_callback(NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) + CloseHandle(lock_cs[i]); + OPENSSL_free(lock_cs); +} + +void win32_locking_callback(int mode, int type, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) { + WaitForSingleObject(lock_cs[type], INFINITE); + } else { + ReleaseMutex(lock_cs[type]); + } +} + +void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) +{ + double ret; + SSL_CTX *ssl_ctx[2]; + DWORD thread_id[MAX_THREAD_NUMBER]; + HANDLE thread_handle[MAX_THREAD_NUMBER]; + int i; + SYSTEMTIME start, end; + + ssl_ctx[0] = s_ctx; + ssl_ctx[1] = c_ctx; + + GetSystemTime(&start); + for (i = 0; i < thread_number; i++) { + thread_handle[i] = CreateThread(NULL, + THREAD_STACK_SIZE, + (LPTHREAD_START_ROUTINE) ndoit, + (void *)ssl_ctx, 0L, &(thread_id[i])); + } + + BIO_printf(bio_stdout, "reaping\n"); + for (i = 0; i < thread_number; i += 50) { + int j; + + j = (thread_number < (i + 50)) ? (thread_number - i) : 50; + + if (WaitForMultipleObjects(j, + (CONST HANDLE *) & (thread_handle[i]), + TRUE, INFINITE) + == WAIT_FAILED) { + BIO_printf(bio_err, "WaitForMultipleObjects failed:%d\n", + GetLastError()); + exit(1); + } + } + GetSystemTime(&end); + + if (start.wDayOfWeek > end.wDayOfWeek) + end.wDayOfWeek += 7; + ret = (end.wDayOfWeek - start.wDayOfWeek) * 24; + + ret = (ret + end.wHour - start.wHour) * 60; + ret = (ret + end.wMinute - start.wMinute) * 60; + ret = (ret + end.wSecond - start.wSecond); + ret += (end.wMilliseconds - start.wMilliseconds) / 1000.0; + + BIO_printf(bio_stdout, "win32 threads done - %.3f seconds\n", ret); +} + +#endif /* OPENSSL_SYS_WIN32 */ + +#ifdef SOLARIS + +static mutex_t *lock_cs; +/* + * static rwlock_t *lock_cs; + */ +static long *lock_count; + +void thread_setup(void) +{ + int i; + + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t)); + lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); + for (i = 0; i < CRYPTO_num_locks(); i++) { + lock_count[i] = 0; + /* rwlock_init(&(lock_cs[i]),USYNC_THREAD,NULL); */ + mutex_init(&(lock_cs[i]), USYNC_THREAD, NULL); + } + + CRYPTO_set_id_callback(solaris_thread_id); + CRYPTO_set_locking_callback(solaris_locking_callback); +} + +void thread_cleanup(void) +{ + int i; + + CRYPTO_set_locking_callback(NULL); + + BIO_printf(bio_err, "cleanup\n"); + + for (i = 0; i < CRYPTO_num_locks(); i++) { + /* rwlock_destroy(&(lock_cs[i])); */ + mutex_destroy(&(lock_cs[i])); + BIO_printf(bio_err, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i)); + } + OPENSSL_free(lock_cs); + OPENSSL_free(lock_count); + + BIO_printf(bio_err, "done cleanup\n"); + +} + +void solaris_locking_callback(int mode, int type, const char *file, int line) +{ +# ifdef undef + BIO_printf(bio_err, "thread=%4d mode=%s lock=%s %s:%d\n", + CRYPTO_thread_id(), + (mode & CRYPTO_LOCK) ? "l" : "u", + (type & CRYPTO_READ) ? "r" : "w", file, line); +# endif + + /*- + if (CRYPTO_LOCK_SSL_CERT == type) + BIO_printf(bio_err,"(t,m,f,l) %ld %d %s %d\n", + CRYPTO_thread_id(), + mode,file,line); + */ + if (mode & CRYPTO_LOCK) { + /*- + if (mode & CRYPTO_READ) + rw_rdlock(&(lock_cs[type])); + else + rw_wrlock(&(lock_cs[type])); */ + + mutex_lock(&(lock_cs[type])); + lock_count[type]++; + } else { +/* rw_unlock(&(lock_cs[type])); */ + mutex_unlock(&(lock_cs[type])); + } +} + +void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) +{ + SSL_CTX *ssl_ctx[2]; + thread_t thread_ctx[MAX_THREAD_NUMBER]; + int i; + + ssl_ctx[0] = s_ctx; + ssl_ctx[1] = c_ctx; + + thr_setconcurrency(thread_number); + for (i = 0; i < thread_number; i++) { + thr_create(NULL, THREAD_STACK_SIZE, + (void *(*)())ndoit, (void *)ssl_ctx, 0L, &(thread_ctx[i])); + } + + BIO_printf(bio_stdout, "reaping\n"); + for (i = 0; i < thread_number; i++) { + thr_join(thread_ctx[i], NULL, NULL); + } + +#if 0 /* We can't currently find out the reference amount */ + BIO_printf(bio_stdout, "solaris threads done (%d,%d)\n", + s_ctx->references, c_ctx->references); +#else + BIO_printf(bio_stdout, "solaris threads done\n"); +#endif +} + +void solaris_thread_id(CRYPTO_THREADID *tid) +{ + CRYPTO_THREADID_set_numeric((unsigned long)thr_self()); +} +#endif /* SOLARIS */ + +#ifdef IRIX + +static usptr_t *arena; +static usema_t **lock_cs; + +void thread_setup(void) +{ + int i; + char filename[20]; + + strcpy(filename, "/tmp/mttest.XXXXXX"); + mktemp(filename); + + usconfig(CONF_STHREADIOOFF); + usconfig(CONF_STHREADMALLOCOFF); + usconfig(CONF_INITUSERS, 100); + usconfig(CONF_LOCKTYPE, US_DEBUGPLUS); + arena = usinit(filename); + unlink(filename); + + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *)); + for (i = 0; i < CRYPTO_num_locks(); i++) { + lock_cs[i] = usnewsema(arena, 1); + } + + CRYPTO_set_id_callback(irix_thread_id); + CRYPTO_set_locking_callback(irix_locking_callback); +} + +void thread_cleanup(void) +{ + int i; + + CRYPTO_set_locking_callback(NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) { + char buf[10]; + + sprintf(buf, "%2d:", i); + usdumpsema(lock_cs[i], stdout, buf); + usfreesema(lock_cs[i], arena); + } + OPENSSL_free(lock_cs); +} + +void irix_locking_callback(int mode, int type, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) { + BIO_printf(bio_stdout, "lock %d\n", type); + uspsema(lock_cs[type]); + } else { + BIO_printf(bio_stdout, "unlock %d\n", type); + usvsema(lock_cs[type]); + } +} + +void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) +{ + SSL_CTX *ssl_ctx[2]; + int thread_ctx[MAX_THREAD_NUMBER]; + int i; + + ssl_ctx[0] = s_ctx; + ssl_ctx[1] = c_ctx; + + for (i = 0; i < thread_number; i++) { + thread_ctx[i] = sproc((void (*)())ndoit, + PR_SADDR | PR_SFDS, (void *)ssl_ctx); + } + + BIO_printf(bio_stdout, "reaping\n"); + for (i = 0; i < thread_number; i++) { + wait(NULL); + } + +#if 0 /* We can't currently find out the reference amount */ + BIO_printf(bio_stdout, "irix threads done (%d,%d)\n", + s_ctx->references, c_ctx->references); +#else + BIO_printf(bio_stdout, "irix threads done\n"); +#endif +} + +unsigned long irix_thread_id(void) +{ + CRYPTO_THREADID_set_numeric((unsigned long)getpid()); +} +#endif /* IRIX */ + +#ifdef PTHREADS + +static pthread_mutex_t *lock_cs; +static long *lock_count; + +void thread_setup(void) +{ + int i; + + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); + lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); + for (i = 0; i < CRYPTO_num_locks(); i++) { + lock_count[i] = 0; + pthread_mutex_init(&(lock_cs[i]), NULL); + } + + CRYPTO_THREADID_set_callback(pthreads_thread_id); + CRYPTO_set_locking_callback(pthreads_locking_callback); +} + +void thread_cleanup(void) +{ + int i; + + CRYPTO_set_locking_callback(NULL); + BIO_printf(bio_err, "cleanup\n"); + for (i = 0; i < CRYPTO_num_locks(); i++) { + pthread_mutex_destroy(&(lock_cs[i])); + BIO_printf(bio_err, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i)); + } + OPENSSL_free(lock_cs); + OPENSSL_free(lock_count); + + BIO_printf(bio_err, "done cleanup\n"); +} + +void pthreads_locking_callback(int mode, int type, const char *file, int line) +{ +# ifdef undef + BIO_printf(bio_err, "thread=%4d mode=%s lock=%s %s:%d\n", + CRYPTO_thread_id(), + (mode & CRYPTO_LOCK) ? "l" : "u", + (type & CRYPTO_READ) ? "r" : "w", file, line); +# endif +/*- + if (CRYPTO_LOCK_SSL_CERT == type) + BIO_printf(bio_err,"(t,m,f,l) %ld %d %s %d\n", + CRYPTO_thread_id(), + mode,file,line); +*/ + if (mode & CRYPTO_LOCK) { + pthread_mutex_lock(&(lock_cs[type])); + lock_count[type]++; + } else { + pthread_mutex_unlock(&(lock_cs[type])); + } +} + +void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) +{ + SSL_CTX *ssl_ctx[2]; + pthread_t thread_ctx[MAX_THREAD_NUMBER]; + int i; + + ssl_ctx[0] = s_ctx; + ssl_ctx[1] = c_ctx; + + /* + * thr_setconcurrency(thread_number); + */ + for (i = 0; i < thread_number; i++) { + pthread_create(&(thread_ctx[i]), NULL, + (void *(*)())ndoit, (void *)ssl_ctx); + } + + BIO_printf(bio_stdout, "reaping\n"); + for (i = 0; i < thread_number; i++) { + pthread_join(thread_ctx[i], NULL); + } + +#if 0 /* We can't currently find out the reference amount */ + BIO_printf(bio_stdout, "pthreads threads done (%d,%d)\n", + s_ctx->references, c_ctx->references); +#else + BIO_printf(bio_stdout, "pthreads threads done\n"); +#endif +} + +void pthreads_thread_id(CRYPTO_THREADID *tid) +{ + CRYPTO_THREADID_set_numeric(tid, (unsigned long)pthread_self()); +} + +#endif /* PTHREADS */ + +#ifdef OPENSSL_SYS_NETWARE + +void thread_setup(void) +{ + int i; + + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(MPKMutex)); + lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); + for (i = 0; i < CRYPTO_num_locks(); i++) { + lock_count[i] = 0; + lock_cs[i] = MPKMutexAlloc("OpenSSL mutex"); + } + + ThreadSem = MPKSemaphoreAlloc("OpenSSL mttest semaphore", 0); + + CRYPTO_set_id_callback(netware_thread_id); + CRYPTO_set_locking_callback(netware_locking_callback); +} + +void thread_cleanup(void) +{ + int i; + + CRYPTO_set_locking_callback(NULL); + + BIO_printf(bio_stdout, "thread_cleanup\n"); + + for (i = 0; i < CRYPTO_num_locks(); i++) { + MPKMutexFree(lock_cs[i]); + BIO_printf(bio_stdout, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i)); + } + OPENSSL_free(lock_cs); + OPENSSL_free(lock_count); + + MPKSemaphoreFree(ThreadSem); + + BIO_printf(bio_stdout, "done cleanup\n"); +} + +void netware_locking_callback(int mode, int type, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) { + MPKMutexLock(lock_cs[type]); + lock_count[type]++; + } else + MPKMutexUnlock(lock_cs[type]); +} + +void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) +{ + SSL_CTX *ssl_ctx[2]; + int i; + ssl_ctx[0] = s_ctx; + ssl_ctx[1] = c_ctx; + + for (i = 0; i < thread_number; i++) { + BeginThread((void (*)(void *))ndoit, NULL, THREAD_STACK_SIZE, + (void *)ssl_ctx); + ThreadSwitchWithDelay(); + } + + BIO_printf(bio_stdout, "reaping\n"); + + /* loop until all threads have signaled the semaphore */ + for (i = 0; i < thread_number; i++) { + MPKSemaphoreWait(ThreadSem); + } +#if 0 /* We can't currently find out the reference amount */ + BIO_printf(bio_stdout, "netware threads done (%d,%d)\n", + s_ctx->references, c_ctx->references); +#else + BIO_printf(bio_stdout, "netware threads done\n"); +#endif +} + +unsigned long netware_thread_id(void) +{ + CRYPTO_THREADID_set_numeric((unsigned long)GetThreadID()); +} +#endif /* NETWARE */ + +#ifdef BEOS_THREADS + +# include + +static BLocker **lock_cs; +static long *lock_count; + +void thread_setup(void) +{ + int i; + + lock_cs = + (BLocker **) OPENSSL_malloc(CRYPTO_num_locks() * sizeof(BLocker *)); + lock_count = (long *)OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); + for (i = 0; i < CRYPTO_num_locks(); i++) { + lock_count[i] = 0; + lock_cs[i] = new BLocker(CRYPTO_get_lock_name(i)); + } + + CRYPTO_set_id_callback((unsigned long (*)())beos_thread_id); + CRYPTO_set_locking_callback(beos_locking_callback); +} + +void thread_cleanup(void) +{ + int i; + + CRYPTO_set_locking_callback(NULL); + BIO_printf(bio_err, "cleanup\n"); + for (i = 0; i < CRYPTO_num_locks(); i++) { + delete lock_cs[i]; + BIO_printf(bio_err, "%8ld:%s\n", lock_count[i], CRYPTO_get_lock_name(i)); + } + OPENSSL_free(lock_cs); + OPENSSL_free(lock_count); + + BIO_printf(bio_err, "done cleanup\n"); +} + +void beos_locking_callback(int mode, int type, const char *file, int line) +{ +# if 0 + BIO_printf(bio_err, "thread=%4d mode=%s lock=%s %s:%d\n", + CRYPTO_thread_id(), + (mode & CRYPTO_LOCK) ? "l" : "u", + (type & CRYPTO_READ) ? "r" : "w", file, line); +# endif + if (mode & CRYPTO_LOCK) { + lock_cs[type]->Lock(); + lock_count[type]++; + } else { + lock_cs[type]->Unlock(); + } +} + +void do_threads(SSL_CTX *s_ctx, SSL_CTX *c_ctx) +{ + SSL_CTX *ssl_ctx[2]; + thread_id thread_ctx[MAX_THREAD_NUMBER]; + int i; + + ssl_ctx[0] = s_ctx; + ssl_ctx[1] = c_ctx; + + for (i = 0; i < thread_number; i++) { + thread_ctx[i] = spawn_thread((thread_func) ndoit, + NULL, B_NORMAL_PRIORITY, + (void *)ssl_ctx); + resume_thread(thread_ctx[i]); + } + + BIO_printf(bio_stdout, "waiting...\n"); + for (i = 0; i < thread_number; i++) { + status_t result; + wait_for_thread(thread_ctx[i], &result); + } + + BIO_printf(bio_stdout, "beos threads done (%d,%d)\n", + s_ctx->references, c_ctx->references); +} + +unsigned long beos_thread_id(void) +{ + unsigned long ret; + + ret = (unsigned long)find_thread(NULL); + return (ret); +} + +#endif /* BEOS_THREADS */ diff --git a/libs/openssl/crypto/threads/netware.bat b/libs/openssl/crypto/threads/netware.bat new file mode 100644 index 00000000..0b3eca3c --- /dev/null +++ b/libs/openssl/crypto/threads/netware.bat @@ -0,0 +1,79 @@ +@echo off +rem batch file to build multi-thread test ( mttest.nlm ) + +rem command line arguments: +rem debug => build using debug settings + +rem +rem After building, copy mttest.nlm to the server and run it, you'll probably +rem want to redirect stdout and stderr. An example command line would be +rem "mttest.nlm -thread 20 -loops 10 -CAfile \openssl\apps\server.pem >mttest.out 2>mttest.err" +rem + +del mttest.nlm + +set BLD_DEBUG= +set CFLAGS= +set LFLAGS= +set LIBS= + +if "%1" == "DEBUG" set BLD_DEBUG=YES +if "%1" == "debug" set BLD_DEBUG=YES + +if "%MWCIncludes%" == "" goto inc_error +if "%PRELUDE%" == "" goto prelude_error +if "%IMPORTS%" == "" goto imports_error + +set CFLAGS=-c -I..\..\outinc_nw -nosyspath -DOPENSSL_SYS_NETWARE -opt off -g -sym internal -maxerrors 20 + +if "%BLD_DEBUG%" == "YES" set LIBS=..\..\out_nw.dbg\ssl.lib ..\..\out_nw.dbg\crypto.lib +if "%BLD_DEBUG%" == "" set LIBS=..\..\out_nw\ssl.lib ..\..\out_nw\crypto.lib + +set LFLAGS=-msgstyle gcc -zerobss -stacksize 32768 -nostdlib -sym internal + +rem generate command file for metrowerks +echo. +echo Generating Metrowerks command file: mttest.def +echo # dynamically generated command file for metrowerks build > mttest.def +echo IMPORT @%IMPORTS%\clib.imp >> mttest.def +echo IMPORT @%IMPORTS%\threads.imp >> mttest.def +echo IMPORT @%IMPORTS%\ws2nlm.imp >> mttest.def +echo IMPORT GetProcessSwitchCount >> mttest.def +echo MODULE clib >> mttest.def + +rem compile +echo. +echo Compiling mttest.c +mwccnlm.exe mttest.c %CFLAGS% +if errorlevel 1 goto end + +rem link +echo. +echo Linking mttest.nlm +mwldnlm.exe %LFLAGS% -screenname mttest -commandfile mttest.def mttest.o "%PRELUDE%" %LIBS% -o mttest.nlm +if errorlevel 1 goto end + +goto end + +:inc_error +echo. +echo Environment variable MWCIncludes is not set - see install.nw +goto end + +:prelude_error +echo. +echo Environment variable PRELUDE is not set - see install.nw +goto end + +:imports_error +echo. +echo Environment variable IMPORTS is not set - see install.nw +goto end + + +:end +set BLD_DEBUG= +set CFLAGS= +set LFLAGS= +set LIBS= + diff --git a/libs/openssl/crypto/threads/ptest.bat b/libs/openssl/crypto/threads/ptest.bat new file mode 100755 index 00000000..4071b5ff --- /dev/null +++ b/libs/openssl/crypto/threads/ptest.bat @@ -0,0 +1,4 @@ +del mttest.exe + +purify cl /O2 -DWIN32 /MD -I..\..\out mttest.c /Femttest ..\..\out\ssl32.lib ..\..\out\crypt32.lib + diff --git a/libs/openssl/crypto/threads/pthreads-vms.com b/libs/openssl/crypto/threads/pthreads-vms.com new file mode 100644 index 00000000..1cf92bdf --- /dev/null +++ b/libs/openssl/crypto/threads/pthreads-vms.com @@ -0,0 +1,14 @@ +$! To compile mttest on VMS. +$! +$! WARNING: only tested with DEC C so far. +$ +$ if (f$getsyi("cpu").lt.128) +$ then +$ arch := VAX +$ else +$ arch = f$edit( f$getsyi( "ARCH_NAME"), "UPCASE") +$ if (arch .eqs. "") then arch = "UNK" +$ endif +$ define/user openssl [--.include.openssl] +$ cc/def=PTHREADS mttest.c +$ link mttest,[--.'arch'.exe.ssl]libssl/lib,[--.'arch'.exe.crypto]libcrypto/lib diff --git a/libs/openssl/crypto/threads/th-lock.c b/libs/openssl/crypto/threads/th-lock.c new file mode 100644 index 00000000..cc8cf258 --- /dev/null +++ b/libs/openssl/crypto/threads/th-lock.c @@ -0,0 +1,389 @@ +/* crypto/threads/th-lock.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#ifdef LINUX +# include +#endif +#ifdef OPENSSL_SYS_WIN32 +# include +#endif +#ifdef SOLARIS +# include +# include +#endif +#ifdef IRIX +# include +# include +#endif +#ifdef PTHREADS +# include +#endif +#include +#include +#include +#include "../../e_os.h" +#include +#include +#include + +void CRYPTO_thread_setup(void); +void CRYPTO_thread_cleanup(void); + +static void irix_locking_callback(int mode, int type, char *file, int line); +static void solaris_locking_callback(int mode, int type, char *file, + int line); +static void win32_locking_callback(int mode, int type, char *file, int line); +static void pthreads_locking_callback(int mode, int type, char *file, + int line); + +static unsigned long irix_thread_id(void); +static unsigned long solaris_thread_id(void); +static unsigned long pthreads_thread_id(void); + +/*- + * usage: + * CRYPTO_thread_setup(); + * application code + * CRYPTO_thread_cleanup(); + */ + +#define THREAD_STACK_SIZE (16*1024) + +#ifdef OPENSSL_SYS_WIN32 + +static HANDLE *lock_cs; + +void CRYPTO_thread_setup(void) +{ + int i; + + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(HANDLE)); + if (!lock_cs) { + /* Nothing we can do about this...void function! */ + return; + } + for (i = 0; i < CRYPTO_num_locks(); i++) { + lock_cs[i] = CreateMutex(NULL, FALSE, NULL); + } + + CRYPTO_set_locking_callback((void (*)(int, int, char *, int)) + win32_locking_callback); + /* id callback defined */ + return (1); +} + +static void CRYPTO_thread_cleanup(void) +{ + int i; + + CRYPTO_set_locking_callback(NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) + CloseHandle(lock_cs[i]); + OPENSSL_free(lock_cs); +} + +void win32_locking_callback(int mode, int type, char *file, int line) +{ + if (mode & CRYPTO_LOCK) { + WaitForSingleObject(lock_cs[type], INFINITE); + } else { + ReleaseMutex(lock_cs[type]); + } +} + +#endif /* OPENSSL_SYS_WIN32 */ + +#ifdef SOLARIS + +# define USE_MUTEX + +# ifdef USE_MUTEX +static mutex_t *lock_cs; +# else +static rwlock_t *lock_cs; +# endif +static long *lock_count; + +void CRYPTO_thread_setup(void) +{ + int i; + +# ifdef USE_MUTEX + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(mutex_t)); +# else + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(rwlock_t)); +# endif + if (!lock_cs) { + /* Nothing we can do about this...void function! */ + return; + } + lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); + for (i = 0; i < CRYPTO_num_locks(); i++) { + lock_count[i] = 0; +# ifdef USE_MUTEX + mutex_init(&(lock_cs[i]), USYNC_THREAD, NULL); +# else + rwlock_init(&(lock_cs[i]), USYNC_THREAD, NULL); +# endif + } + + CRYPTO_set_id_callback((unsigned long (*)())solaris_thread_id); + CRYPTO_set_locking_callback((void (*)())solaris_locking_callback); +} + +void CRYPTO_thread_cleanup(void) +{ + int i; + + CRYPTO_set_locking_callback(NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) { +# ifdef USE_MUTEX + mutex_destroy(&(lock_cs[i])); +# else + rwlock_destroy(&(lock_cs[i])); +# endif + } + OPENSSL_free(lock_cs); + OPENSSL_free(lock_count); +} + +void solaris_locking_callback(int mode, int type, char *file, int line) +{ +# if 0 + fprintf(stderr, "thread=%4d mode=%s lock=%s %s:%d\n", + CRYPTO_thread_id(), + (mode & CRYPTO_LOCK) ? "l" : "u", + (type & CRYPTO_READ) ? "r" : "w", file, line); +# endif + +# if 0 + if (CRYPTO_LOCK_SSL_CERT == type) + fprintf(stderr, "(t,m,f,l) %ld %d %s %d\n", + CRYPTO_thread_id(), mode, file, line); +# endif + if (mode & CRYPTO_LOCK) { +# ifdef USE_MUTEX + mutex_lock(&(lock_cs[type])); +# else + if (mode & CRYPTO_READ) + rw_rdlock(&(lock_cs[type])); + else + rw_wrlock(&(lock_cs[type])); +# endif + lock_count[type]++; + } else { +# ifdef USE_MUTEX + mutex_unlock(&(lock_cs[type])); +# else + rw_unlock(&(lock_cs[type])); +# endif + } +} + +unsigned long solaris_thread_id(void) +{ + unsigned long ret; + + ret = (unsigned long)thr_self(); + return (ret); +} +#endif /* SOLARIS */ + +#ifdef IRIX +/* I don't think this works..... */ + +static usptr_t *arena; +static usema_t **lock_cs; + +void CRYPTO_thread_setup(void) +{ + int i; + char filename[20]; + + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(usema_t *)); + if (!lock_cs) { + /* Nothing we can do about this...void function! */ + return; + } + + strcpy(filename, "/tmp/mttest.XXXXXX"); + mktemp(filename); + + usconfig(CONF_STHREADIOOFF); + usconfig(CONF_STHREADMALLOCOFF); + usconfig(CONF_INITUSERS, 100); + usconfig(CONF_LOCKTYPE, US_DEBUGPLUS); + arena = usinit(filename); + unlink(filename); + + for (i = 0; i < CRYPTO_num_locks(); i++) { + lock_cs[i] = usnewsema(arena, 1); + } + + CRYPTO_set_id_callback((unsigned long (*)())irix_thread_id); + CRYPTO_set_locking_callback((void (*)())irix_locking_callback); +} + +void CRYPTO_thread_cleanup(void) +{ + int i; + + CRYPTO_set_locking_callback(NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) { + char buf[10]; + + sprintf(buf, "%2d:", i); + usdumpsema(lock_cs[i], stdout, buf); + usfreesema(lock_cs[i], arena); + } + OPENSSL_free(lock_cs); +} + +void irix_locking_callback(int mode, int type, char *file, int line) +{ + if (mode & CRYPTO_LOCK) { + uspsema(lock_cs[type]); + } else { + usvsema(lock_cs[type]); + } +} + +unsigned long irix_thread_id(void) +{ + unsigned long ret; + + ret = (unsigned long)getpid(); + return (ret); +} +#endif /* IRIX */ + +/* Linux and a few others */ +#ifdef PTHREADS + +static pthread_mutex_t *lock_cs; +static long *lock_count; + +void CRYPTO_thread_setup(void) +{ + int i; + + lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t)); + lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long)); + if (!lock_cs || !lock_count) { + /* Nothing we can do about this...void function! */ + if (lock_cs) + OPENSSL_free(lock_cs); + if (lock_count) + OPENSSL_free(lock_count); + return; + } + for (i = 0; i < CRYPTO_num_locks(); i++) { + lock_count[i] = 0; + pthread_mutex_init(&(lock_cs[i]), NULL); + } + + CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id); + CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback); +} + +void thread_cleanup(void) +{ + int i; + + CRYPTO_set_locking_callback(NULL); + for (i = 0; i < CRYPTO_num_locks(); i++) { + pthread_mutex_destroy(&(lock_cs[i])); + } + OPENSSL_free(lock_cs); + OPENSSL_free(lock_count); +} + +void pthreads_locking_callback(int mode, int type, char *file, int line) +{ +# if 0 + fprintf(stderr, "thread=%4d mode=%s lock=%s %s:%d\n", + CRYPTO_thread_id(), + (mode & CRYPTO_LOCK) ? "l" : "u", + (type & CRYPTO_READ) ? "r" : "w", file, line); +# endif +# if 0 + if (CRYPTO_LOCK_SSL_CERT == type) + fprintf(stderr, "(t,m,f,l) %ld %d %s %d\n", + CRYPTO_thread_id(), mode, file, line); +# endif + if (mode & CRYPTO_LOCK) { + pthread_mutex_lock(&(lock_cs[type])); + lock_count[type]++; + } else { + pthread_mutex_unlock(&(lock_cs[type])); + } +} + +unsigned long pthreads_thread_id(void) +{ + unsigned long ret; + + ret = (unsigned long)pthread_self(); + return (ret); +} + +#endif /* PTHREADS */ diff --git a/libs/openssl/crypto/threads/win32.bat b/libs/openssl/crypto/threads/win32.bat new file mode 100755 index 00000000..ee6da80a --- /dev/null +++ b/libs/openssl/crypto/threads/win32.bat @@ -0,0 +1,4 @@ +del mttest.exe + +cl /O2 -DWIN32 /MD -I..\..\out mttest.c /Femttest ..\..\out\ssleay32.lib ..\..\out\libeay32.lib + diff --git a/libs/openssl/crypto/ts/ts.h b/libs/openssl/crypto/ts/ts.h new file mode 100644 index 00000000..16eccbb3 --- /dev/null +++ b/libs/openssl/crypto/ts/ts.h @@ -0,0 +1,862 @@ +/* crypto/ts/ts.h */ +/* + * Written by Zoltan Glozik (zglozik@opentsa.org) for the OpenSSL project + * 2002, 2003, 2004. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_TS_H +# define HEADER_TS_H + +# include +# include +# ifndef OPENSSL_NO_BUFFER +# include +# endif +# ifndef OPENSSL_NO_EVP +# include +# endif +# ifndef OPENSSL_NO_BIO +# include +# endif +# include +# include +# include + +# ifndef OPENSSL_NO_RSA +# include +# endif + +# ifndef OPENSSL_NO_DSA +# include +# endif + +# ifndef OPENSSL_NO_DH +# include +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef WIN32 +/* Under Win32 this is defined in wincrypt.h */ +# undef X509_NAME +# endif + +# include +# include + +/*- +MessageImprint ::= SEQUENCE { + hashAlgorithm AlgorithmIdentifier, + hashedMessage OCTET STRING } +*/ + +typedef struct TS_msg_imprint_st { + X509_ALGOR *hash_algo; + ASN1_OCTET_STRING *hashed_msg; +} TS_MSG_IMPRINT; + +/*- +TimeStampReq ::= SEQUENCE { + version INTEGER { v1(1) }, + messageImprint MessageImprint, + --a hash algorithm OID and the hash value of the data to be + --time-stamped + reqPolicy TSAPolicyId OPTIONAL, + nonce INTEGER OPTIONAL, + certReq BOOLEAN DEFAULT FALSE, + extensions [0] IMPLICIT Extensions OPTIONAL } +*/ + +typedef struct TS_req_st { + ASN1_INTEGER *version; + TS_MSG_IMPRINT *msg_imprint; + ASN1_OBJECT *policy_id; /* OPTIONAL */ + ASN1_INTEGER *nonce; /* OPTIONAL */ + ASN1_BOOLEAN cert_req; /* DEFAULT FALSE */ + STACK_OF(X509_EXTENSION) *extensions; /* [0] OPTIONAL */ +} TS_REQ; + +/*- +Accuracy ::= SEQUENCE { + seconds INTEGER OPTIONAL, + millis [0] INTEGER (1..999) OPTIONAL, + micros [1] INTEGER (1..999) OPTIONAL } +*/ + +typedef struct TS_accuracy_st { + ASN1_INTEGER *seconds; + ASN1_INTEGER *millis; + ASN1_INTEGER *micros; +} TS_ACCURACY; + +/*- +TSTInfo ::= SEQUENCE { + version INTEGER { v1(1) }, + policy TSAPolicyId, + messageImprint MessageImprint, + -- MUST have the same value as the similar field in + -- TimeStampReq + serialNumber INTEGER, + -- Time-Stamping users MUST be ready to accommodate integers + -- up to 160 bits. + genTime GeneralizedTime, + accuracy Accuracy OPTIONAL, + ordering BOOLEAN DEFAULT FALSE, + nonce INTEGER OPTIONAL, + -- MUST be present if the similar field was present + -- in TimeStampReq. In that case it MUST have the same value. + tsa [0] GeneralName OPTIONAL, + extensions [1] IMPLICIT Extensions OPTIONAL } +*/ + +typedef struct TS_tst_info_st { + ASN1_INTEGER *version; + ASN1_OBJECT *policy_id; + TS_MSG_IMPRINT *msg_imprint; + ASN1_INTEGER *serial; + ASN1_GENERALIZEDTIME *time; + TS_ACCURACY *accuracy; + ASN1_BOOLEAN ordering; + ASN1_INTEGER *nonce; + GENERAL_NAME *tsa; + STACK_OF(X509_EXTENSION) *extensions; +} TS_TST_INFO; + +/*- +PKIStatusInfo ::= SEQUENCE { + status PKIStatus, + statusString PKIFreeText OPTIONAL, + failInfo PKIFailureInfo OPTIONAL } + +From RFC 1510 - section 3.1.1: +PKIFreeText ::= SEQUENCE SIZE (1..MAX) OF UTF8String + -- text encoded as UTF-8 String (note: each UTF8String SHOULD + -- include an RFC 1766 language tag to indicate the language + -- of the contained text) +*/ + +/* Possible values for status. See ts_resp_print.c && ts_resp_verify.c. */ + +# define TS_STATUS_GRANTED 0 +# define TS_STATUS_GRANTED_WITH_MODS 1 +# define TS_STATUS_REJECTION 2 +# define TS_STATUS_WAITING 3 +# define TS_STATUS_REVOCATION_WARNING 4 +# define TS_STATUS_REVOCATION_NOTIFICATION 5 + +/* + * Possible values for failure_info. See ts_resp_print.c && ts_resp_verify.c + */ + +# define TS_INFO_BAD_ALG 0 +# define TS_INFO_BAD_REQUEST 2 +# define TS_INFO_BAD_DATA_FORMAT 5 +# define TS_INFO_TIME_NOT_AVAILABLE 14 +# define TS_INFO_UNACCEPTED_POLICY 15 +# define TS_INFO_UNACCEPTED_EXTENSION 16 +# define TS_INFO_ADD_INFO_NOT_AVAILABLE 17 +# define TS_INFO_SYSTEM_FAILURE 25 + +typedef struct TS_status_info_st { + ASN1_INTEGER *status; + STACK_OF(ASN1_UTF8STRING) *text; + ASN1_BIT_STRING *failure_info; +} TS_STATUS_INFO; + +DECLARE_STACK_OF(ASN1_UTF8STRING) +DECLARE_ASN1_SET_OF(ASN1_UTF8STRING) + +/*- +TimeStampResp ::= SEQUENCE { + status PKIStatusInfo, + timeStampToken TimeStampToken OPTIONAL } +*/ + +typedef struct TS_resp_st { + TS_STATUS_INFO *status_info; + PKCS7 *token; + TS_TST_INFO *tst_info; +} TS_RESP; + +/* The structure below would belong to the ESS component. */ + +/*- +IssuerSerial ::= SEQUENCE { + issuer GeneralNames, + serialNumber CertificateSerialNumber + } +*/ + +typedef struct ESS_issuer_serial { + STACK_OF(GENERAL_NAME) *issuer; + ASN1_INTEGER *serial; +} ESS_ISSUER_SERIAL; + +/*- +ESSCertID ::= SEQUENCE { + certHash Hash, + issuerSerial IssuerSerial OPTIONAL +} +*/ + +typedef struct ESS_cert_id { + ASN1_OCTET_STRING *hash; /* Always SHA-1 digest. */ + ESS_ISSUER_SERIAL *issuer_serial; +} ESS_CERT_ID; + +DECLARE_STACK_OF(ESS_CERT_ID) +DECLARE_ASN1_SET_OF(ESS_CERT_ID) + +/*- +SigningCertificate ::= SEQUENCE { + certs SEQUENCE OF ESSCertID, + policies SEQUENCE OF PolicyInformation OPTIONAL +} +*/ + +typedef struct ESS_signing_cert { + STACK_OF(ESS_CERT_ID) *cert_ids; + STACK_OF(POLICYINFO) *policy_info; +} ESS_SIGNING_CERT; + +TS_REQ *TS_REQ_new(void); +void TS_REQ_free(TS_REQ *a); +int i2d_TS_REQ(const TS_REQ *a, unsigned char **pp); +TS_REQ *d2i_TS_REQ(TS_REQ **a, const unsigned char **pp, long length); + +TS_REQ *TS_REQ_dup(TS_REQ *a); + +TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a); +int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a); +TS_REQ *d2i_TS_REQ_bio(BIO *fp, TS_REQ **a); +int i2d_TS_REQ_bio(BIO *fp, TS_REQ *a); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_new(void); +void TS_MSG_IMPRINT_free(TS_MSG_IMPRINT *a); +int i2d_TS_MSG_IMPRINT(const TS_MSG_IMPRINT *a, unsigned char **pp); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT(TS_MSG_IMPRINT **a, + const unsigned char **pp, long length); + +TS_MSG_IMPRINT *TS_MSG_IMPRINT_dup(TS_MSG_IMPRINT *a); + +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a); +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT **a); +int i2d_TS_MSG_IMPRINT_bio(BIO *fp, TS_MSG_IMPRINT *a); + +TS_RESP *TS_RESP_new(void); +void TS_RESP_free(TS_RESP *a); +int i2d_TS_RESP(const TS_RESP *a, unsigned char **pp); +TS_RESP *d2i_TS_RESP(TS_RESP **a, const unsigned char **pp, long length); +TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token); +TS_RESP *TS_RESP_dup(TS_RESP *a); + +TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a); +int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a); +TS_RESP *d2i_TS_RESP_bio(BIO *fp, TS_RESP **a); +int i2d_TS_RESP_bio(BIO *fp, TS_RESP *a); + +TS_STATUS_INFO *TS_STATUS_INFO_new(void); +void TS_STATUS_INFO_free(TS_STATUS_INFO *a); +int i2d_TS_STATUS_INFO(const TS_STATUS_INFO *a, unsigned char **pp); +TS_STATUS_INFO *d2i_TS_STATUS_INFO(TS_STATUS_INFO **a, + const unsigned char **pp, long length); +TS_STATUS_INFO *TS_STATUS_INFO_dup(TS_STATUS_INFO *a); + +TS_TST_INFO *TS_TST_INFO_new(void); +void TS_TST_INFO_free(TS_TST_INFO *a); +int i2d_TS_TST_INFO(const TS_TST_INFO *a, unsigned char **pp); +TS_TST_INFO *d2i_TS_TST_INFO(TS_TST_INFO **a, const unsigned char **pp, + long length); +TS_TST_INFO *TS_TST_INFO_dup(TS_TST_INFO *a); + +TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a); +TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO **a); +int i2d_TS_TST_INFO_bio(BIO *fp, TS_TST_INFO *a); + +TS_ACCURACY *TS_ACCURACY_new(void); +void TS_ACCURACY_free(TS_ACCURACY *a); +int i2d_TS_ACCURACY(const TS_ACCURACY *a, unsigned char **pp); +TS_ACCURACY *d2i_TS_ACCURACY(TS_ACCURACY **a, const unsigned char **pp, + long length); +TS_ACCURACY *TS_ACCURACY_dup(TS_ACCURACY *a); + +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_new(void); +void ESS_ISSUER_SERIAL_free(ESS_ISSUER_SERIAL *a); +int i2d_ESS_ISSUER_SERIAL(const ESS_ISSUER_SERIAL *a, unsigned char **pp); +ESS_ISSUER_SERIAL *d2i_ESS_ISSUER_SERIAL(ESS_ISSUER_SERIAL **a, + const unsigned char **pp, + long length); +ESS_ISSUER_SERIAL *ESS_ISSUER_SERIAL_dup(ESS_ISSUER_SERIAL *a); + +ESS_CERT_ID *ESS_CERT_ID_new(void); +void ESS_CERT_ID_free(ESS_CERT_ID *a); +int i2d_ESS_CERT_ID(const ESS_CERT_ID *a, unsigned char **pp); +ESS_CERT_ID *d2i_ESS_CERT_ID(ESS_CERT_ID **a, const unsigned char **pp, + long length); +ESS_CERT_ID *ESS_CERT_ID_dup(ESS_CERT_ID *a); + +ESS_SIGNING_CERT *ESS_SIGNING_CERT_new(void); +void ESS_SIGNING_CERT_free(ESS_SIGNING_CERT *a); +int i2d_ESS_SIGNING_CERT(const ESS_SIGNING_CERT *a, unsigned char **pp); +ESS_SIGNING_CERT *d2i_ESS_SIGNING_CERT(ESS_SIGNING_CERT **a, + const unsigned char **pp, long length); +ESS_SIGNING_CERT *ESS_SIGNING_CERT_dup(ESS_SIGNING_CERT *a); + +void ERR_load_TS_strings(void); + +int TS_REQ_set_version(TS_REQ *a, long version); +long TS_REQ_get_version(const TS_REQ *a); + +int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a); + +int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg); +X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a); + +int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len); +ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a); + +int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy); +ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a); + +int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a); + +int TS_REQ_set_cert_req(TS_REQ *a, int cert_req); +int TS_REQ_get_cert_req(const TS_REQ *a); + +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a); +void TS_REQ_ext_free(TS_REQ *a); +int TS_REQ_get_ext_count(TS_REQ *a); +int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos); +int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos); +int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos); +X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc); +X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc); +int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc); +void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx); + +/* Function declarations for TS_REQ defined in ts/ts_req_print.c */ + +int TS_REQ_print_bio(BIO *bio, TS_REQ *a); + +/* Function declarations for TS_RESP defined in ts/ts_resp_utils.c */ + +int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *info); +TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a); + +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ +void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info); +PKCS7 *TS_RESP_get_token(TS_RESP *a); +TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a); + +int TS_TST_INFO_set_version(TS_TST_INFO *a, long version); +long TS_TST_INFO_get_version(const TS_TST_INFO *a); + +int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy_id); +ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a); + +int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint); +TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a); + +int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial); +const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a); + +int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime); +const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a); + +int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy); +TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a); + +int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds); +const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a); + +int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis); +const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a); + +int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros); +const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a); + +int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering); +int TS_TST_INFO_get_ordering(const TS_TST_INFO *a); + +int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce); +const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a); + +int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa); +GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a); + +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a); +void TS_TST_INFO_ext_free(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_count(TS_TST_INFO *a); +int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos); +int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos); +int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos); +X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc); +X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc); +int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc); +void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx); + +/* + * Declarations related to response generation, defined in ts/ts_resp_sign.c. + */ + +/* Optional flags for response generation. */ + +/* Don't include the TSA name in response. */ +# define TS_TSA_NAME 0x01 + +/* Set ordering to true in response. */ +# define TS_ORDERING 0x02 + +/* + * Include the signer certificate and the other specified certificates in + * the ESS signing certificate attribute beside the PKCS7 signed data. + * Only the signer certificates is included by default. + */ +# define TS_ESS_CERT_ID_CHAIN 0x04 + +/* Forward declaration. */ +struct TS_resp_ctx; + +/* This must return a unique number less than 160 bits long. */ +typedef ASN1_INTEGER *(*TS_serial_cb) (struct TS_resp_ctx *, void *); + +/* + * This must return the seconds and microseconds since Jan 1, 1970 in the sec + * and usec variables allocated by the caller. Return non-zero for success + * and zero for failure. + */ +typedef int (*TS_time_cb) (struct TS_resp_ctx *, void *, long *sec, + long *usec); + +/* + * This must process the given extension. It can modify the TS_TST_INFO + * object of the context. Return values: !0 (processed), 0 (error, it must + * set the status info/failure info of the response). + */ +typedef int (*TS_extension_cb) (struct TS_resp_ctx *, X509_EXTENSION *, + void *); + +typedef struct TS_resp_ctx { + X509 *signer_cert; + EVP_PKEY *signer_key; + STACK_OF(X509) *certs; /* Certs to include in signed data. */ + STACK_OF(ASN1_OBJECT) *policies; /* Acceptable policies. */ + ASN1_OBJECT *default_policy; /* It may appear in policies, too. */ + STACK_OF(EVP_MD) *mds; /* Acceptable message digests. */ + ASN1_INTEGER *seconds; /* accuracy, 0 means not specified. */ + ASN1_INTEGER *millis; /* accuracy, 0 means not specified. */ + ASN1_INTEGER *micros; /* accuracy, 0 means not specified. */ + unsigned clock_precision_digits; /* fraction of seconds in time stamp + * token. */ + unsigned flags; /* Optional info, see values above. */ + /* Callback functions. */ + TS_serial_cb serial_cb; + void *serial_cb_data; /* User data for serial_cb. */ + TS_time_cb time_cb; + void *time_cb_data; /* User data for time_cb. */ + TS_extension_cb extension_cb; + void *extension_cb_data; /* User data for extension_cb. */ + /* These members are used only while creating the response. */ + TS_REQ *request; + TS_RESP *response; + TS_TST_INFO *tst_info; +} TS_RESP_CTX; + +DECLARE_STACK_OF(EVP_MD) +DECLARE_ASN1_SET_OF(EVP_MD) + +/* Creates a response context that can be used for generating responses. */ +TS_RESP_CTX *TS_RESP_CTX_new(void); +void TS_RESP_CTX_free(TS_RESP_CTX *ctx); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key); + +/* This parameter must be set. */ +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy); + +/* No additional certs are included in the response by default. */ +int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs); + +/* + * Adds a new acceptable policy, only the default policy is accepted by + * default. + */ +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy); + +/* + * Adds a new acceptable message digest. Note that no message digests are + * accepted by default. The md argument is shared with the caller. + */ +int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md); + +/* Accuracy is not included by default. */ +int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, + int secs, int millis, int micros); + +/* + * Clock precision digits, i.e. the number of decimal digits: '0' means sec, + * '3' msec, '6' usec, and so on. Default is 0. + */ +int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, + unsigned clock_precision_digits); +/* At most we accept usec precision. */ +# define TS_MAX_CLOCK_PRECISION_DIGITS 6 + +/* No flags are set by default. */ +void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags); + +/* Default callback always returns a constant. */ +void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data); + +/* Default callback uses the gettimeofday() and gmtime() system calls. */ +void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data); + +/* + * Default callback rejects all extensions. The extension callback is called + * when the TS_TST_INFO object is already set up and not signed yet. + */ +/* FIXME: extension handling is not tested yet. */ +void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, + TS_extension_cb cb, void *data); + +/* The following methods can be used in the callbacks. */ +int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, + int status, const char *text); + +/* Sets the status info only if it is still TS_STATUS_GRANTED. */ +int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, + int status, const char *text); + +int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure); + +/* The get methods below can be used in the extension callback. */ +TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx); + +TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx); + +/* + * Creates the signed TS_TST_INFO and puts it in TS_RESP. + * In case of errors it sets the status info properly. + * Returns NULL only in case of memory allocation/fatal error. + */ +TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio); + +/* + * Declarations related to response verification, + * they are defined in ts/ts_resp_verify.c. + */ + +int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, + X509_STORE *store, X509 **signer_out); + +/* Context structure for the generic verify method. */ + +/* Verify the signer's certificate and the signature of the response. */ +# define TS_VFY_SIGNATURE (1u << 0) +/* Verify the version number of the response. */ +# define TS_VFY_VERSION (1u << 1) +/* Verify if the policy supplied by the user matches the policy of the TSA. */ +# define TS_VFY_POLICY (1u << 2) +/* + * Verify the message imprint provided by the user. This flag should not be + * specified with TS_VFY_DATA. + */ +# define TS_VFY_IMPRINT (1u << 3) +/* + * Verify the message imprint computed by the verify method from the user + * provided data and the MD algorithm of the response. This flag should not + * be specified with TS_VFY_IMPRINT. + */ +# define TS_VFY_DATA (1u << 4) +/* Verify the nonce value. */ +# define TS_VFY_NONCE (1u << 5) +/* Verify if the TSA name field matches the signer certificate. */ +# define TS_VFY_SIGNER (1u << 6) +/* Verify if the TSA name field equals to the user provided name. */ +# define TS_VFY_TSA_NAME (1u << 7) + +/* You can use the following convenience constants. */ +# define TS_VFY_ALL_IMPRINT (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_IMPRINT \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) +# define TS_VFY_ALL_DATA (TS_VFY_SIGNATURE \ + | TS_VFY_VERSION \ + | TS_VFY_POLICY \ + | TS_VFY_DATA \ + | TS_VFY_NONCE \ + | TS_VFY_SIGNER \ + | TS_VFY_TSA_NAME) + +typedef struct TS_verify_ctx { + /* Set this to the union of TS_VFY_... flags you want to carry out. */ + unsigned flags; + /* Must be set only with TS_VFY_SIGNATURE. certs is optional. */ + X509_STORE *store; + STACK_OF(X509) *certs; + /* Must be set only with TS_VFY_POLICY. */ + ASN1_OBJECT *policy; + /* + * Must be set only with TS_VFY_IMPRINT. If md_alg is NULL, the + * algorithm from the response is used. + */ + X509_ALGOR *md_alg; + unsigned char *imprint; + unsigned imprint_len; + /* Must be set only with TS_VFY_DATA. */ + BIO *data; + /* Must be set only with TS_VFY_TSA_NAME. */ + ASN1_INTEGER *nonce; + /* Must be set only with TS_VFY_TSA_NAME. */ + GENERAL_NAME *tsa_name; +} TS_VERIFY_CTX; + +int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response); +int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token); + +/* + * Declarations related to response verification context, + * they are defined in ts/ts_verify_ctx.c. + */ + +/* Set all fields to zero. */ +TS_VERIFY_CTX *TS_VERIFY_CTX_new(void); +void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx); +void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx); + +/*- + * If ctx is NULL, it allocates and returns a new object, otherwise + * it returns ctx. It initialises all the members as follows: + * flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE) + * certs = NULL + * store = NULL + * policy = policy from the request or NULL if absent (in this case + * TS_VFY_POLICY is cleared from flags as well) + * md_alg = MD algorithm from request + * imprint, imprint_len = imprint from request + * data = NULL + * nonce, nonce_len = nonce from the request or NULL if absent (in this case + * TS_VFY_NONCE is cleared from flags as well) + * tsa_name = NULL + * Important: after calling this method TS_VFY_SIGNATURE should be added! + */ +TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx); + +/* Function declarations for TS_RESP defined in ts/ts_resp_print.c */ + +int TS_RESP_print_bio(BIO *bio, TS_RESP *a); +int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a); +int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a); + +/* Common utility functions defined in ts/ts_lib.c */ + +int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num); +int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj); +int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions); +int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg); +int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *msg); + +/* + * Function declarations for handling configuration options, defined in + * ts/ts_conf.c + */ + +X509 *TS_CONF_load_cert(const char *file); +STACK_OF(X509) *TS_CONF_load_certs(const char *file); +EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass); +const char *TS_CONF_get_tsa_section(CONF *conf, const char *section); +int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, + TS_RESP_CTX *ctx); +int TS_CONF_set_crypto_device(CONF *conf, const char *section, + const char *device); +int TS_CONF_set_default_engine(const char *name); +int TS_CONF_set_signer_cert(CONF *conf, const char *section, + const char *cert, TS_RESP_CTX *ctx); +int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, + TS_RESP_CTX *ctx); +int TS_CONF_set_signer_key(CONF *conf, const char *section, + const char *key, const char *pass, + TS_RESP_CTX *ctx); +int TS_CONF_set_def_policy(CONF *conf, const char *section, + const char *policy, TS_RESP_CTX *ctx); +int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, + TS_RESP_CTX *ctx); +int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx); +int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, + TS_RESP_CTX *ctx); + +/* -------------------------------------------------- */ +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_TS_strings(void); + +/* Error codes for the TS functions. */ + +/* Function codes. */ +# define TS_F_D2I_TS_RESP 147 +# define TS_F_DEF_SERIAL_CB 110 +# define TS_F_DEF_TIME_CB 111 +# define TS_F_ESS_ADD_SIGNING_CERT 112 +# define TS_F_ESS_CERT_ID_NEW_INIT 113 +# define TS_F_ESS_SIGNING_CERT_NEW_INIT 114 +# define TS_F_INT_TS_RESP_VERIFY_TOKEN 149 +# define TS_F_PKCS7_TO_TS_TST_INFO 148 +# define TS_F_TS_ACCURACY_SET_MICROS 115 +# define TS_F_TS_ACCURACY_SET_MILLIS 116 +# define TS_F_TS_ACCURACY_SET_SECONDS 117 +# define TS_F_TS_CHECK_IMPRINTS 100 +# define TS_F_TS_CHECK_NONCES 101 +# define TS_F_TS_CHECK_POLICY 102 +# define TS_F_TS_CHECK_SIGNING_CERTS 103 +# define TS_F_TS_CHECK_STATUS_INFO 104 +# define TS_F_TS_COMPUTE_IMPRINT 145 +# define TS_F_TS_CONF_SET_DEFAULT_ENGINE 146 +# define TS_F_TS_GET_STATUS_TEXT 105 +# define TS_F_TS_MSG_IMPRINT_SET_ALGO 118 +# define TS_F_TS_REQ_SET_MSG_IMPRINT 119 +# define TS_F_TS_REQ_SET_NONCE 120 +# define TS_F_TS_REQ_SET_POLICY_ID 121 +# define TS_F_TS_RESP_CREATE_RESPONSE 122 +# define TS_F_TS_RESP_CREATE_TST_INFO 123 +# define TS_F_TS_RESP_CTX_ADD_FAILURE_INFO 124 +# define TS_F_TS_RESP_CTX_ADD_MD 125 +# define TS_F_TS_RESP_CTX_ADD_POLICY 126 +# define TS_F_TS_RESP_CTX_NEW 127 +# define TS_F_TS_RESP_CTX_SET_ACCURACY 128 +# define TS_F_TS_RESP_CTX_SET_CERTS 129 +# define TS_F_TS_RESP_CTX_SET_DEF_POLICY 130 +# define TS_F_TS_RESP_CTX_SET_SIGNER_CERT 131 +# define TS_F_TS_RESP_CTX_SET_STATUS_INFO 132 +# define TS_F_TS_RESP_GET_POLICY 133 +# define TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION 134 +# define TS_F_TS_RESP_SET_STATUS_INFO 135 +# define TS_F_TS_RESP_SET_TST_INFO 150 +# define TS_F_TS_RESP_SIGN 136 +# define TS_F_TS_RESP_VERIFY_SIGNATURE 106 +# define TS_F_TS_RESP_VERIFY_TOKEN 107 +# define TS_F_TS_TST_INFO_SET_ACCURACY 137 +# define TS_F_TS_TST_INFO_SET_MSG_IMPRINT 138 +# define TS_F_TS_TST_INFO_SET_NONCE 139 +# define TS_F_TS_TST_INFO_SET_POLICY_ID 140 +# define TS_F_TS_TST_INFO_SET_SERIAL 141 +# define TS_F_TS_TST_INFO_SET_TIME 142 +# define TS_F_TS_TST_INFO_SET_TSA 143 +# define TS_F_TS_VERIFY 108 +# define TS_F_TS_VERIFY_CERT 109 +# define TS_F_TS_VERIFY_CTX_NEW 144 + +/* Reason codes. */ +# define TS_R_BAD_PKCS7_TYPE 132 +# define TS_R_BAD_TYPE 133 +# define TS_R_CERTIFICATE_VERIFY_ERROR 100 +# define TS_R_COULD_NOT_SET_ENGINE 127 +# define TS_R_COULD_NOT_SET_TIME 115 +# define TS_R_D2I_TS_RESP_INT_FAILED 128 +# define TS_R_DETACHED_CONTENT 134 +# define TS_R_ESS_ADD_SIGNING_CERT_ERROR 116 +# define TS_R_ESS_SIGNING_CERTIFICATE_ERROR 101 +# define TS_R_INVALID_NULL_POINTER 102 +# define TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE 117 +# define TS_R_MESSAGE_IMPRINT_MISMATCH 103 +# define TS_R_NONCE_MISMATCH 104 +# define TS_R_NONCE_NOT_RETURNED 105 +# define TS_R_NO_CONTENT 106 +# define TS_R_NO_TIME_STAMP_TOKEN 107 +# define TS_R_PKCS7_ADD_SIGNATURE_ERROR 118 +# define TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR 119 +# define TS_R_PKCS7_TO_TS_TST_INFO_FAILED 129 +# define TS_R_POLICY_MISMATCH 108 +# define TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE 120 +# define TS_R_RESPONSE_SETUP_ERROR 121 +# define TS_R_SIGNATURE_FAILURE 109 +# define TS_R_THERE_MUST_BE_ONE_SIGNER 110 +# define TS_R_TIME_SYSCALL_ERROR 122 +# define TS_R_TOKEN_NOT_PRESENT 130 +# define TS_R_TOKEN_PRESENT 131 +# define TS_R_TSA_NAME_MISMATCH 111 +# define TS_R_TSA_UNTRUSTED 112 +# define TS_R_TST_INFO_SETUP_ERROR 123 +# define TS_R_TS_DATASIGN 124 +# define TS_R_UNACCEPTABLE_POLICY 125 +# define TS_R_UNSUPPORTED_MD_ALGORITHM 126 +# define TS_R_UNSUPPORTED_VERSION 113 +# define TS_R_WRONG_CONTENT_TYPE 114 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/ts/ts_asn1.c b/libs/openssl/crypto/ts/ts_asn1.c new file mode 100644 index 00000000..657dc4ca --- /dev/null +++ b/libs/openssl/crypto/ts/ts_asn1.c @@ -0,0 +1,326 @@ +/* crypto/ts/ts_asn1.c */ +/* + * Written by Nils Larsch for the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +ASN1_SEQUENCE(TS_MSG_IMPRINT) = { + ASN1_SIMPLE(TS_MSG_IMPRINT, hash_algo, X509_ALGOR), + ASN1_SIMPLE(TS_MSG_IMPRINT, hashed_msg, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(TS_MSG_IMPRINT) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_MSG_IMPRINT) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_MSG_IMPRINT) +#ifndef OPENSSL_NO_BIO +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT **a) +{ + return ASN1_d2i_bio_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, + d2i_TS_MSG_IMPRINT, bp, a); +} + +int i2d_TS_MSG_IMPRINT_bio(BIO *bp, TS_MSG_IMPRINT *a) +{ + return ASN1_i2d_bio_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, bp, a); +} +#endif +#ifndef OPENSSL_NO_FP_API +TS_MSG_IMPRINT *d2i_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT **a) +{ + return ASN1_d2i_fp_of(TS_MSG_IMPRINT, TS_MSG_IMPRINT_new, + d2i_TS_MSG_IMPRINT, fp, a); +} + +int i2d_TS_MSG_IMPRINT_fp(FILE *fp, TS_MSG_IMPRINT *a) +{ + return ASN1_i2d_fp_of_const(TS_MSG_IMPRINT, i2d_TS_MSG_IMPRINT, fp, a); +} +#endif + +ASN1_SEQUENCE(TS_REQ) = { + ASN1_SIMPLE(TS_REQ, version, ASN1_INTEGER), + ASN1_SIMPLE(TS_REQ, msg_imprint, TS_MSG_IMPRINT), + ASN1_OPT(TS_REQ, policy_id, ASN1_OBJECT), + ASN1_OPT(TS_REQ, nonce, ASN1_INTEGER), + ASN1_OPT(TS_REQ, cert_req, ASN1_FBOOLEAN), + ASN1_IMP_SEQUENCE_OF_OPT(TS_REQ, extensions, X509_EXTENSION, 0) +} ASN1_SEQUENCE_END(TS_REQ) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_REQ) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_REQ) +#ifndef OPENSSL_NO_BIO +TS_REQ *d2i_TS_REQ_bio(BIO *bp, TS_REQ **a) +{ + return ASN1_d2i_bio_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, bp, a); +} + +int i2d_TS_REQ_bio(BIO *bp, TS_REQ *a) +{ + return ASN1_i2d_bio_of_const(TS_REQ, i2d_TS_REQ, bp, a); +} +#endif +#ifndef OPENSSL_NO_FP_API +TS_REQ *d2i_TS_REQ_fp(FILE *fp, TS_REQ **a) +{ + return ASN1_d2i_fp_of(TS_REQ, TS_REQ_new, d2i_TS_REQ, fp, a); +} + +int i2d_TS_REQ_fp(FILE *fp, TS_REQ *a) +{ + return ASN1_i2d_fp_of_const(TS_REQ, i2d_TS_REQ, fp, a); +} +#endif + +ASN1_SEQUENCE(TS_ACCURACY) = { + ASN1_OPT(TS_ACCURACY, seconds, ASN1_INTEGER), + ASN1_IMP_OPT(TS_ACCURACY, millis, ASN1_INTEGER, 0), + ASN1_IMP_OPT(TS_ACCURACY, micros, ASN1_INTEGER, 1) +} ASN1_SEQUENCE_END(TS_ACCURACY) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_ACCURACY) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_ACCURACY) + +ASN1_SEQUENCE(TS_TST_INFO) = { + ASN1_SIMPLE(TS_TST_INFO, version, ASN1_INTEGER), + ASN1_SIMPLE(TS_TST_INFO, policy_id, ASN1_OBJECT), + ASN1_SIMPLE(TS_TST_INFO, msg_imprint, TS_MSG_IMPRINT), + ASN1_SIMPLE(TS_TST_INFO, serial, ASN1_INTEGER), + ASN1_SIMPLE(TS_TST_INFO, time, ASN1_GENERALIZEDTIME), + ASN1_OPT(TS_TST_INFO, accuracy, TS_ACCURACY), + ASN1_OPT(TS_TST_INFO, ordering, ASN1_FBOOLEAN), + ASN1_OPT(TS_TST_INFO, nonce, ASN1_INTEGER), + ASN1_EXP_OPT(TS_TST_INFO, tsa, GENERAL_NAME, 0), + ASN1_IMP_SEQUENCE_OF_OPT(TS_TST_INFO, extensions, X509_EXTENSION, 1) +} ASN1_SEQUENCE_END(TS_TST_INFO) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_TST_INFO) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_TST_INFO) +#ifndef OPENSSL_NO_BIO +TS_TST_INFO *d2i_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO **a) +{ + return ASN1_d2i_bio_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, bp, + a); +} + +int i2d_TS_TST_INFO_bio(BIO *bp, TS_TST_INFO *a) +{ + return ASN1_i2d_bio_of_const(TS_TST_INFO, i2d_TS_TST_INFO, bp, a); +} +#endif +#ifndef OPENSSL_NO_FP_API +TS_TST_INFO *d2i_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO **a) +{ + return ASN1_d2i_fp_of(TS_TST_INFO, TS_TST_INFO_new, d2i_TS_TST_INFO, fp, + a); +} + +int i2d_TS_TST_INFO_fp(FILE *fp, TS_TST_INFO *a) +{ + return ASN1_i2d_fp_of_const(TS_TST_INFO, i2d_TS_TST_INFO, fp, a); +} +#endif + +ASN1_SEQUENCE(TS_STATUS_INFO) = { + ASN1_SIMPLE(TS_STATUS_INFO, status, ASN1_INTEGER), + ASN1_SEQUENCE_OF_OPT(TS_STATUS_INFO, text, ASN1_UTF8STRING), + ASN1_OPT(TS_STATUS_INFO, failure_info, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(TS_STATUS_INFO) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_STATUS_INFO) +IMPLEMENT_ASN1_DUP_FUNCTION(TS_STATUS_INFO) + +static int ts_resp_set_tst_info(TS_RESP *a) +{ + long status; + + status = ASN1_INTEGER_get(a->status_info->status); + + if (a->token) { + if (status != 0 && status != 1) { + TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_PRESENT); + return 0; + } + if (a->tst_info != NULL) + TS_TST_INFO_free(a->tst_info); + a->tst_info = PKCS7_to_TS_TST_INFO(a->token); + if (!a->tst_info) { + TSerr(TS_F_TS_RESP_SET_TST_INFO, + TS_R_PKCS7_TO_TS_TST_INFO_FAILED); + return 0; + } + } else if (status == 0 || status == 1) { + TSerr(TS_F_TS_RESP_SET_TST_INFO, TS_R_TOKEN_NOT_PRESENT); + return 0; + } + + return 1; +} + +static int ts_resp_cb(int op, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + TS_RESP *ts_resp = (TS_RESP *)*pval; + if (op == ASN1_OP_NEW_POST) { + ts_resp->tst_info = NULL; + } else if (op == ASN1_OP_FREE_POST) { + if (ts_resp->tst_info != NULL) + TS_TST_INFO_free(ts_resp->tst_info); + } else if (op == ASN1_OP_D2I_POST) { + if (ts_resp_set_tst_info(ts_resp) == 0) + return 0; + } + return 1; +} + +ASN1_SEQUENCE_cb(TS_RESP, ts_resp_cb) = { + ASN1_SIMPLE(TS_RESP, status_info, TS_STATUS_INFO), + ASN1_OPT(TS_RESP, token, PKCS7), +} ASN1_SEQUENCE_END_cb(TS_RESP, TS_RESP) + +IMPLEMENT_ASN1_FUNCTIONS_const(TS_RESP) + +IMPLEMENT_ASN1_DUP_FUNCTION(TS_RESP) + +#ifndef OPENSSL_NO_BIO +TS_RESP *d2i_TS_RESP_bio(BIO *bp, TS_RESP **a) +{ + return ASN1_d2i_bio_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, bp, a); +} + +int i2d_TS_RESP_bio(BIO *bp, TS_RESP *a) +{ + return ASN1_i2d_bio_of_const(TS_RESP, i2d_TS_RESP, bp, a); +} +#endif +#ifndef OPENSSL_NO_FP_API +TS_RESP *d2i_TS_RESP_fp(FILE *fp, TS_RESP **a) +{ + return ASN1_d2i_fp_of(TS_RESP, TS_RESP_new, d2i_TS_RESP, fp, a); +} + +int i2d_TS_RESP_fp(FILE *fp, TS_RESP *a) +{ + return ASN1_i2d_fp_of_const(TS_RESP, i2d_TS_RESP, fp, a); +} +#endif + +ASN1_SEQUENCE(ESS_ISSUER_SERIAL) = { + ASN1_SEQUENCE_OF(ESS_ISSUER_SERIAL, issuer, GENERAL_NAME), + ASN1_SIMPLE(ESS_ISSUER_SERIAL, serial, ASN1_INTEGER) +} ASN1_SEQUENCE_END(ESS_ISSUER_SERIAL) + +IMPLEMENT_ASN1_FUNCTIONS_const(ESS_ISSUER_SERIAL) +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_ISSUER_SERIAL) + +ASN1_SEQUENCE(ESS_CERT_ID) = { + ASN1_SIMPLE(ESS_CERT_ID, hash, ASN1_OCTET_STRING), + ASN1_OPT(ESS_CERT_ID, issuer_serial, ESS_ISSUER_SERIAL) +} ASN1_SEQUENCE_END(ESS_CERT_ID) + +IMPLEMENT_ASN1_FUNCTIONS_const(ESS_CERT_ID) +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_CERT_ID) + +ASN1_SEQUENCE(ESS_SIGNING_CERT) = { + ASN1_SEQUENCE_OF(ESS_SIGNING_CERT, cert_ids, ESS_CERT_ID), + ASN1_SEQUENCE_OF_OPT(ESS_SIGNING_CERT, policy_info, POLICYINFO) +} ASN1_SEQUENCE_END(ESS_SIGNING_CERT) + +IMPLEMENT_ASN1_FUNCTIONS_const(ESS_SIGNING_CERT) +IMPLEMENT_ASN1_DUP_FUNCTION(ESS_SIGNING_CERT) + +/* Getting encapsulated TS_TST_INFO object from PKCS7. */ +TS_TST_INFO *PKCS7_to_TS_TST_INFO(PKCS7 *token) +{ + PKCS7_SIGNED *pkcs7_signed; + PKCS7 *enveloped; + ASN1_TYPE *tst_info_wrapper; + ASN1_OCTET_STRING *tst_info_der; + const unsigned char *p; + + if (!PKCS7_type_is_signed(token)) { + TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE); + return NULL; + } + + /* Content must be present. */ + if (PKCS7_get_detached(token)) { + TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_DETACHED_CONTENT); + return NULL; + } + + /* We have a signed data with content. */ + pkcs7_signed = token->d.sign; + enveloped = pkcs7_signed->contents; + if (OBJ_obj2nid(enveloped->type) != NID_id_smime_ct_TSTInfo) { + TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_PKCS7_TYPE); + return NULL; + } + + /* We have a DER encoded TST_INFO as the signed data. */ + tst_info_wrapper = enveloped->d.other; + if (tst_info_wrapper->type != V_ASN1_OCTET_STRING) { + TSerr(TS_F_PKCS7_TO_TS_TST_INFO, TS_R_BAD_TYPE); + return NULL; + } + + /* We have the correct ASN1_OCTET_STRING type. */ + tst_info_der = tst_info_wrapper->value.octet_string; + /* At last, decode the TST_INFO. */ + p = tst_info_der->data; + return d2i_TS_TST_INFO(NULL, &p, tst_info_der->length); +} diff --git a/libs/openssl/crypto/ts/ts_conf.c b/libs/openssl/crypto/ts/ts_conf.c new file mode 100644 index 00000000..4716b233 --- /dev/null +++ b/libs/openssl/crypto/ts/ts_conf.c @@ -0,0 +1,491 @@ +/* crypto/ts/ts_conf.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include +#include "cryptlib.h" +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include + +/* Macro definitions for the configuration file. */ + +#define BASE_SECTION "tsa" +#define ENV_DEFAULT_TSA "default_tsa" +#define ENV_SERIAL "serial" +#define ENV_CRYPTO_DEVICE "crypto_device" +#define ENV_SIGNER_CERT "signer_cert" +#define ENV_CERTS "certs" +#define ENV_SIGNER_KEY "signer_key" +#define ENV_DEFAULT_POLICY "default_policy" +#define ENV_OTHER_POLICIES "other_policies" +#define ENV_DIGESTS "digests" +#define ENV_ACCURACY "accuracy" +#define ENV_ORDERING "ordering" +#define ENV_TSA_NAME "tsa_name" +#define ENV_ESS_CERT_ID_CHAIN "ess_cert_id_chain" +#define ENV_VALUE_SECS "secs" +#define ENV_VALUE_MILLISECS "millisecs" +#define ENV_VALUE_MICROSECS "microsecs" +#define ENV_CLOCK_PRECISION_DIGITS "clock_precision_digits" +#define ENV_VALUE_YES "yes" +#define ENV_VALUE_NO "no" + +/* Function definitions for certificate and key loading. */ + +X509 *TS_CONF_load_cert(const char *file) +{ + BIO *cert = NULL; + X509 *x = NULL; + + if ((cert = BIO_new_file(file, "r")) == NULL) + goto end; + x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL); + end: + if (x == NULL) + fprintf(stderr, "unable to load certificate: %s\n", file); + BIO_free(cert); + return x; +} + +STACK_OF(X509) *TS_CONF_load_certs(const char *file) +{ + BIO *certs = NULL; + STACK_OF(X509) *othercerts = NULL; + STACK_OF(X509_INFO) *allcerts = NULL; + int i; + + if (!(certs = BIO_new_file(file, "r"))) + goto end; + + if (!(othercerts = sk_X509_new_null())) + goto end; + allcerts = PEM_X509_INFO_read_bio(certs, NULL, NULL, NULL); + for (i = 0; i < sk_X509_INFO_num(allcerts); i++) { + X509_INFO *xi = sk_X509_INFO_value(allcerts, i); + if (xi->x509) { + sk_X509_push(othercerts, xi->x509); + xi->x509 = NULL; + } + } + end: + if (othercerts == NULL) + fprintf(stderr, "unable to load certificates: %s\n", file); + sk_X509_INFO_pop_free(allcerts, X509_INFO_free); + BIO_free(certs); + return othercerts; +} + +EVP_PKEY *TS_CONF_load_key(const char *file, const char *pass) +{ + BIO *key = NULL; + EVP_PKEY *pkey = NULL; + + if (!(key = BIO_new_file(file, "r"))) + goto end; + pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, (char *)pass); + end: + if (pkey == NULL) + fprintf(stderr, "unable to load private key: %s\n", file); + BIO_free(key); + return pkey; +} + +/* Function definitions for handling configuration options. */ + +static void TS_CONF_lookup_fail(const char *name, const char *tag) +{ + fprintf(stderr, "variable lookup failed for %s::%s\n", name, tag); +} + +static void TS_CONF_invalid(const char *name, const char *tag) +{ + fprintf(stderr, "invalid variable value for %s::%s\n", name, tag); +} + +const char *TS_CONF_get_tsa_section(CONF *conf, const char *section) +{ + if (!section) { + section = NCONF_get_string(conf, BASE_SECTION, ENV_DEFAULT_TSA); + if (!section) + TS_CONF_lookup_fail(BASE_SECTION, ENV_DEFAULT_TSA); + } + return section; +} + +int TS_CONF_set_serial(CONF *conf, const char *section, TS_serial_cb cb, + TS_RESP_CTX *ctx) +{ + int ret = 0; + char *serial = NCONF_get_string(conf, section, ENV_SERIAL); + if (!serial) { + TS_CONF_lookup_fail(section, ENV_SERIAL); + goto err; + } + TS_RESP_CTX_set_serial_cb(ctx, cb, serial); + + ret = 1; + err: + return ret; +} + +#ifndef OPENSSL_NO_ENGINE + +int TS_CONF_set_crypto_device(CONF *conf, const char *section, + const char *device) +{ + int ret = 0; + + if (!device) + device = NCONF_get_string(conf, section, ENV_CRYPTO_DEVICE); + + if (device && !TS_CONF_set_default_engine(device)) { + TS_CONF_invalid(section, ENV_CRYPTO_DEVICE); + goto err; + } + ret = 1; + err: + return ret; +} + +int TS_CONF_set_default_engine(const char *name) +{ + ENGINE *e = NULL; + int ret = 0; + + /* Leave the default if builtin specified. */ + if (strcmp(name, "builtin") == 0) + return 1; + + if (!(e = ENGINE_by_id(name))) + goto err; + /* Enable the use of the NCipher HSM for forked children. */ + if (strcmp(name, "chil") == 0) + ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0); + /* All the operations are going to be carried out by the engine. */ + if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) + goto err; + ret = 1; + err: + if (!ret) { + TSerr(TS_F_TS_CONF_SET_DEFAULT_ENGINE, TS_R_COULD_NOT_SET_ENGINE); + ERR_add_error_data(2, "engine:", name); + } + if (e) + ENGINE_free(e); + return ret; +} + +#endif + +int TS_CONF_set_signer_cert(CONF *conf, const char *section, + const char *cert, TS_RESP_CTX *ctx) +{ + int ret = 0; + X509 *cert_obj = NULL; + if (!cert) + cert = NCONF_get_string(conf, section, ENV_SIGNER_CERT); + if (!cert) { + TS_CONF_lookup_fail(section, ENV_SIGNER_CERT); + goto err; + } + if (!(cert_obj = TS_CONF_load_cert(cert))) + goto err; + if (!TS_RESP_CTX_set_signer_cert(ctx, cert_obj)) + goto err; + + ret = 1; + err: + X509_free(cert_obj); + return ret; +} + +int TS_CONF_set_certs(CONF *conf, const char *section, const char *certs, + TS_RESP_CTX *ctx) +{ + int ret = 0; + STACK_OF(X509) *certs_obj = NULL; + if (!certs) + certs = NCONF_get_string(conf, section, ENV_CERTS); + /* Certificate chain is optional. */ + if (!certs) + goto end; + if (!(certs_obj = TS_CONF_load_certs(certs))) + goto err; + if (!TS_RESP_CTX_set_certs(ctx, certs_obj)) + goto err; + end: + ret = 1; + err: + sk_X509_pop_free(certs_obj, X509_free); + return ret; +} + +int TS_CONF_set_signer_key(CONF *conf, const char *section, + const char *key, const char *pass, + TS_RESP_CTX *ctx) +{ + int ret = 0; + EVP_PKEY *key_obj = NULL; + if (!key) + key = NCONF_get_string(conf, section, ENV_SIGNER_KEY); + if (!key) { + TS_CONF_lookup_fail(section, ENV_SIGNER_KEY); + goto err; + } + if (!(key_obj = TS_CONF_load_key(key, pass))) + goto err; + if (!TS_RESP_CTX_set_signer_key(ctx, key_obj)) + goto err; + + ret = 1; + err: + EVP_PKEY_free(key_obj); + return ret; +} + +int TS_CONF_set_def_policy(CONF *conf, const char *section, + const char *policy, TS_RESP_CTX *ctx) +{ + int ret = 0; + ASN1_OBJECT *policy_obj = NULL; + if (!policy) + policy = NCONF_get_string(conf, section, ENV_DEFAULT_POLICY); + if (!policy) { + TS_CONF_lookup_fail(section, ENV_DEFAULT_POLICY); + goto err; + } + if (!(policy_obj = OBJ_txt2obj(policy, 0))) { + TS_CONF_invalid(section, ENV_DEFAULT_POLICY); + goto err; + } + if (!TS_RESP_CTX_set_def_policy(ctx, policy_obj)) + goto err; + + ret = 1; + err: + ASN1_OBJECT_free(policy_obj); + return ret; +} + +int TS_CONF_set_policies(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + int ret = 0; + int i; + STACK_OF(CONF_VALUE) *list = NULL; + char *policies = NCONF_get_string(conf, section, + ENV_OTHER_POLICIES); + /* If no other policy is specified, that's fine. */ + if (policies && !(list = X509V3_parse_list(policies))) { + TS_CONF_invalid(section, ENV_OTHER_POLICIES); + goto err; + } + for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { + CONF_VALUE *val = sk_CONF_VALUE_value(list, i); + const char *extval = val->value ? val->value : val->name; + ASN1_OBJECT *objtmp; + if (!(objtmp = OBJ_txt2obj(extval, 0))) { + TS_CONF_invalid(section, ENV_OTHER_POLICIES); + goto err; + } + if (!TS_RESP_CTX_add_policy(ctx, objtmp)) + goto err; + ASN1_OBJECT_free(objtmp); + } + + ret = 1; + err: + sk_CONF_VALUE_pop_free(list, X509V3_conf_free); + return ret; +} + +int TS_CONF_set_digests(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + int ret = 0; + int i; + STACK_OF(CONF_VALUE) *list = NULL; + char *digests = NCONF_get_string(conf, section, ENV_DIGESTS); + if (!digests) { + TS_CONF_lookup_fail(section, ENV_DIGESTS); + goto err; + } + if (!(list = X509V3_parse_list(digests))) { + TS_CONF_invalid(section, ENV_DIGESTS); + goto err; + } + if (sk_CONF_VALUE_num(list) == 0) { + TS_CONF_invalid(section, ENV_DIGESTS); + goto err; + } + for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { + CONF_VALUE *val = sk_CONF_VALUE_value(list, i); + const char *extval = val->value ? val->value : val->name; + const EVP_MD *md; + if (!(md = EVP_get_digestbyname(extval))) { + TS_CONF_invalid(section, ENV_DIGESTS); + goto err; + } + if (!TS_RESP_CTX_add_md(ctx, md)) + goto err; + } + + ret = 1; + err: + sk_CONF_VALUE_pop_free(list, X509V3_conf_free); + return ret; +} + +int TS_CONF_set_accuracy(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + int ret = 0; + int i; + int secs = 0, millis = 0, micros = 0; + STACK_OF(CONF_VALUE) *list = NULL; + char *accuracy = NCONF_get_string(conf, section, ENV_ACCURACY); + + if (accuracy && !(list = X509V3_parse_list(accuracy))) { + TS_CONF_invalid(section, ENV_ACCURACY); + goto err; + } + for (i = 0; i < sk_CONF_VALUE_num(list); ++i) { + CONF_VALUE *val = sk_CONF_VALUE_value(list, i); + if (strcmp(val->name, ENV_VALUE_SECS) == 0) { + if (val->value) + secs = atoi(val->value); + } else if (strcmp(val->name, ENV_VALUE_MILLISECS) == 0) { + if (val->value) + millis = atoi(val->value); + } else if (strcmp(val->name, ENV_VALUE_MICROSECS) == 0) { + if (val->value) + micros = atoi(val->value); + } else { + TS_CONF_invalid(section, ENV_ACCURACY); + goto err; + } + } + if (!TS_RESP_CTX_set_accuracy(ctx, secs, millis, micros)) + goto err; + + ret = 1; + err: + sk_CONF_VALUE_pop_free(list, X509V3_conf_free); + return ret; +} + +int TS_CONF_set_clock_precision_digits(CONF *conf, const char *section, + TS_RESP_CTX *ctx) +{ + int ret = 0; + long digits = 0; + + /* + * If not specified, set the default value to 0, i.e. sec precision + */ + if (!NCONF_get_number_e(conf, section, ENV_CLOCK_PRECISION_DIGITS, + &digits)) + digits = 0; + if (digits < 0 || digits > TS_MAX_CLOCK_PRECISION_DIGITS) { + TS_CONF_invalid(section, ENV_CLOCK_PRECISION_DIGITS); + goto err; + } + + if (!TS_RESP_CTX_set_clock_precision_digits(ctx, digits)) + goto err; + + return 1; + err: + return ret; +} + +static int TS_CONF_add_flag(CONF *conf, const char *section, + const char *field, int flag, TS_RESP_CTX *ctx) +{ + /* Default is false. */ + const char *value = NCONF_get_string(conf, section, field); + if (value) { + if (strcmp(value, ENV_VALUE_YES) == 0) + TS_RESP_CTX_add_flags(ctx, flag); + else if (strcmp(value, ENV_VALUE_NO) != 0) { + TS_CONF_invalid(section, field); + return 0; + } + } + + return 1; +} + +int TS_CONF_set_ordering(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + return TS_CONF_add_flag(conf, section, ENV_ORDERING, TS_ORDERING, ctx); +} + +int TS_CONF_set_tsa_name(CONF *conf, const char *section, TS_RESP_CTX *ctx) +{ + return TS_CONF_add_flag(conf, section, ENV_TSA_NAME, TS_TSA_NAME, ctx); +} + +int TS_CONF_set_ess_cert_id_chain(CONF *conf, const char *section, + TS_RESP_CTX *ctx) +{ + return TS_CONF_add_flag(conf, section, ENV_ESS_CERT_ID_CHAIN, + TS_ESS_CERT_ID_CHAIN, ctx); +} diff --git a/libs/openssl/crypto/ts/ts_err.c b/libs/openssl/crypto/ts/ts_err.c new file mode 100644 index 00000000..ff1abf45 --- /dev/null +++ b/libs/openssl/crypto/ts/ts_err.c @@ -0,0 +1,188 @@ +/* crypto/ts/ts_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_TS,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_TS,0,reason) + +static ERR_STRING_DATA TS_str_functs[] = { + {ERR_FUNC(TS_F_D2I_TS_RESP), "d2i_TS_RESP"}, + {ERR_FUNC(TS_F_DEF_SERIAL_CB), "DEF_SERIAL_CB"}, + {ERR_FUNC(TS_F_DEF_TIME_CB), "DEF_TIME_CB"}, + {ERR_FUNC(TS_F_ESS_ADD_SIGNING_CERT), "ESS_ADD_SIGNING_CERT"}, + {ERR_FUNC(TS_F_ESS_CERT_ID_NEW_INIT), "ESS_CERT_ID_NEW_INIT"}, + {ERR_FUNC(TS_F_ESS_SIGNING_CERT_NEW_INIT), "ESS_SIGNING_CERT_NEW_INIT"}, + {ERR_FUNC(TS_F_INT_TS_RESP_VERIFY_TOKEN), "INT_TS_RESP_VERIFY_TOKEN"}, + {ERR_FUNC(TS_F_PKCS7_TO_TS_TST_INFO), "PKCS7_to_TS_TST_INFO"}, + {ERR_FUNC(TS_F_TS_ACCURACY_SET_MICROS), "TS_ACCURACY_set_micros"}, + {ERR_FUNC(TS_F_TS_ACCURACY_SET_MILLIS), "TS_ACCURACY_set_millis"}, + {ERR_FUNC(TS_F_TS_ACCURACY_SET_SECONDS), "TS_ACCURACY_set_seconds"}, + {ERR_FUNC(TS_F_TS_CHECK_IMPRINTS), "TS_CHECK_IMPRINTS"}, + {ERR_FUNC(TS_F_TS_CHECK_NONCES), "TS_CHECK_NONCES"}, + {ERR_FUNC(TS_F_TS_CHECK_POLICY), "TS_CHECK_POLICY"}, + {ERR_FUNC(TS_F_TS_CHECK_SIGNING_CERTS), "TS_CHECK_SIGNING_CERTS"}, + {ERR_FUNC(TS_F_TS_CHECK_STATUS_INFO), "TS_CHECK_STATUS_INFO"}, + {ERR_FUNC(TS_F_TS_COMPUTE_IMPRINT), "TS_COMPUTE_IMPRINT"}, + {ERR_FUNC(TS_F_TS_CONF_SET_DEFAULT_ENGINE), "TS_CONF_set_default_engine"}, + {ERR_FUNC(TS_F_TS_GET_STATUS_TEXT), "TS_GET_STATUS_TEXT"}, + {ERR_FUNC(TS_F_TS_MSG_IMPRINT_SET_ALGO), "TS_MSG_IMPRINT_set_algo"}, + {ERR_FUNC(TS_F_TS_REQ_SET_MSG_IMPRINT), "TS_REQ_set_msg_imprint"}, + {ERR_FUNC(TS_F_TS_REQ_SET_NONCE), "TS_REQ_set_nonce"}, + {ERR_FUNC(TS_F_TS_REQ_SET_POLICY_ID), "TS_REQ_set_policy_id"}, + {ERR_FUNC(TS_F_TS_RESP_CREATE_RESPONSE), "TS_RESP_create_response"}, + {ERR_FUNC(TS_F_TS_RESP_CREATE_TST_INFO), "TS_RESP_CREATE_TST_INFO"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO), + "TS_RESP_CTX_add_failure_info"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_MD), "TS_RESP_CTX_add_md"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_ADD_POLICY), "TS_RESP_CTX_add_policy"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_NEW), "TS_RESP_CTX_new"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_SET_ACCURACY), "TS_RESP_CTX_set_accuracy"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_SET_CERTS), "TS_RESP_CTX_set_certs"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_SET_DEF_POLICY), "TS_RESP_CTX_set_def_policy"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_SET_SIGNER_CERT), + "TS_RESP_CTX_set_signer_cert"}, + {ERR_FUNC(TS_F_TS_RESP_CTX_SET_STATUS_INFO), + "TS_RESP_CTX_set_status_info"}, + {ERR_FUNC(TS_F_TS_RESP_GET_POLICY), "TS_RESP_GET_POLICY"}, + {ERR_FUNC(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION), + "TS_RESP_SET_GENTIME_WITH_PRECISION"}, + {ERR_FUNC(TS_F_TS_RESP_SET_STATUS_INFO), "TS_RESP_set_status_info"}, + {ERR_FUNC(TS_F_TS_RESP_SET_TST_INFO), "TS_RESP_set_tst_info"}, + {ERR_FUNC(TS_F_TS_RESP_SIGN), "TS_RESP_SIGN"}, + {ERR_FUNC(TS_F_TS_RESP_VERIFY_SIGNATURE), "TS_RESP_verify_signature"}, + {ERR_FUNC(TS_F_TS_RESP_VERIFY_TOKEN), "TS_RESP_verify_token"}, + {ERR_FUNC(TS_F_TS_TST_INFO_SET_ACCURACY), "TS_TST_INFO_set_accuracy"}, + {ERR_FUNC(TS_F_TS_TST_INFO_SET_MSG_IMPRINT), + "TS_TST_INFO_set_msg_imprint"}, + {ERR_FUNC(TS_F_TS_TST_INFO_SET_NONCE), "TS_TST_INFO_set_nonce"}, + {ERR_FUNC(TS_F_TS_TST_INFO_SET_POLICY_ID), "TS_TST_INFO_set_policy_id"}, + {ERR_FUNC(TS_F_TS_TST_INFO_SET_SERIAL), "TS_TST_INFO_set_serial"}, + {ERR_FUNC(TS_F_TS_TST_INFO_SET_TIME), "TS_TST_INFO_set_time"}, + {ERR_FUNC(TS_F_TS_TST_INFO_SET_TSA), "TS_TST_INFO_set_tsa"}, + {ERR_FUNC(TS_F_TS_VERIFY), "TS_VERIFY"}, + {ERR_FUNC(TS_F_TS_VERIFY_CERT), "TS_VERIFY_CERT"}, + {ERR_FUNC(TS_F_TS_VERIFY_CTX_NEW), "TS_VERIFY_CTX_new"}, + {0, NULL} +}; + +static ERR_STRING_DATA TS_str_reasons[] = { + {ERR_REASON(TS_R_BAD_PKCS7_TYPE), "bad pkcs7 type"}, + {ERR_REASON(TS_R_BAD_TYPE), "bad type"}, + {ERR_REASON(TS_R_CERTIFICATE_VERIFY_ERROR), "certificate verify error"}, + {ERR_REASON(TS_R_COULD_NOT_SET_ENGINE), "could not set engine"}, + {ERR_REASON(TS_R_COULD_NOT_SET_TIME), "could not set time"}, + {ERR_REASON(TS_R_D2I_TS_RESP_INT_FAILED), "d2i ts resp int failed"}, + {ERR_REASON(TS_R_DETACHED_CONTENT), "detached content"}, + {ERR_REASON(TS_R_ESS_ADD_SIGNING_CERT_ERROR), + "ess add signing cert error"}, + {ERR_REASON(TS_R_ESS_SIGNING_CERTIFICATE_ERROR), + "ess signing certificate error"}, + {ERR_REASON(TS_R_INVALID_NULL_POINTER), "invalid null pointer"}, + {ERR_REASON(TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE), + "invalid signer certificate purpose"}, + {ERR_REASON(TS_R_MESSAGE_IMPRINT_MISMATCH), "message imprint mismatch"}, + {ERR_REASON(TS_R_NONCE_MISMATCH), "nonce mismatch"}, + {ERR_REASON(TS_R_NONCE_NOT_RETURNED), "nonce not returned"}, + {ERR_REASON(TS_R_NO_CONTENT), "no content"}, + {ERR_REASON(TS_R_NO_TIME_STAMP_TOKEN), "no time stamp token"}, + {ERR_REASON(TS_R_PKCS7_ADD_SIGNATURE_ERROR), "pkcs7 add signature error"}, + {ERR_REASON(TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR), + "pkcs7 add signed attr error"}, + {ERR_REASON(TS_R_PKCS7_TO_TS_TST_INFO_FAILED), + "pkcs7 to ts tst info failed"}, + {ERR_REASON(TS_R_POLICY_MISMATCH), "policy mismatch"}, + {ERR_REASON(TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE), + "private key does not match certificate"}, + {ERR_REASON(TS_R_RESPONSE_SETUP_ERROR), "response setup error"}, + {ERR_REASON(TS_R_SIGNATURE_FAILURE), "signature failure"}, + {ERR_REASON(TS_R_THERE_MUST_BE_ONE_SIGNER), "there must be one signer"}, + {ERR_REASON(TS_R_TIME_SYSCALL_ERROR), "time syscall error"}, + {ERR_REASON(TS_R_TOKEN_NOT_PRESENT), "token not present"}, + {ERR_REASON(TS_R_TOKEN_PRESENT), "token present"}, + {ERR_REASON(TS_R_TSA_NAME_MISMATCH), "tsa name mismatch"}, + {ERR_REASON(TS_R_TSA_UNTRUSTED), "tsa untrusted"}, + {ERR_REASON(TS_R_TST_INFO_SETUP_ERROR), "tst info setup error"}, + {ERR_REASON(TS_R_TS_DATASIGN), "ts datasign"}, + {ERR_REASON(TS_R_UNACCEPTABLE_POLICY), "unacceptable policy"}, + {ERR_REASON(TS_R_UNSUPPORTED_MD_ALGORITHM), "unsupported md algorithm"}, + {ERR_REASON(TS_R_UNSUPPORTED_VERSION), "unsupported version"}, + {ERR_REASON(TS_R_WRONG_CONTENT_TYPE), "wrong content type"}, + {0, NULL} +}; + +#endif + +void ERR_load_TS_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(TS_str_functs[0].error) == NULL) { + ERR_load_strings(0, TS_str_functs); + ERR_load_strings(0, TS_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/ts/ts_lib.c b/libs/openssl/crypto/ts/ts_lib.c new file mode 100644 index 00000000..c51538a1 --- /dev/null +++ b/libs/openssl/crypto/ts/ts_lib.c @@ -0,0 +1,143 @@ +/* crypto/ts/ts_lib.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include "ts.h" + +/* Local function declarations. */ + +/* Function definitions. */ + +int TS_ASN1_INTEGER_print_bio(BIO *bio, const ASN1_INTEGER *num) +{ + BIGNUM num_bn; + int result = 0; + char *hex; + + BN_init(&num_bn); + ASN1_INTEGER_to_BN(num, &num_bn); + if ((hex = BN_bn2hex(&num_bn))) { + result = BIO_write(bio, "0x", 2) > 0; + result = result && BIO_write(bio, hex, strlen(hex)) > 0; + OPENSSL_free(hex); + } + BN_free(&num_bn); + + return result; +} + +int TS_OBJ_print_bio(BIO *bio, const ASN1_OBJECT *obj) +{ + char obj_txt[128]; + + int len = OBJ_obj2txt(obj_txt, sizeof(obj_txt), obj, 0); + BIO_write(bio, obj_txt, len); + BIO_write(bio, "\n", 1); + + return 1; +} + +int TS_ext_print_bio(BIO *bio, const STACK_OF(X509_EXTENSION) *extensions) +{ + int i, critical, n; + X509_EXTENSION *ex; + ASN1_OBJECT *obj; + + BIO_printf(bio, "Extensions:\n"); + n = X509v3_get_ext_count(extensions); + for (i = 0; i < n; i++) { + ex = X509v3_get_ext(extensions, i); + obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bio, obj); + critical = X509_EXTENSION_get_critical(ex); + BIO_printf(bio, ": %s\n", critical ? "critical" : ""); + if (!X509V3_EXT_print(bio, ex, 0, 4)) { + BIO_printf(bio, "%4s", ""); + M_ASN1_OCTET_STRING_print(bio, ex->value); + } + BIO_write(bio, "\n", 1); + } + + return 1; +} + +int TS_X509_ALGOR_print_bio(BIO *bio, const X509_ALGOR *alg) +{ + int i = OBJ_obj2nid(alg->algorithm); + return BIO_printf(bio, "Hash Algorithm: %s\n", + (i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i)); +} + +int TS_MSG_IMPRINT_print_bio(BIO *bio, TS_MSG_IMPRINT *a) +{ + const ASN1_OCTET_STRING *msg; + + TS_X509_ALGOR_print_bio(bio, TS_MSG_IMPRINT_get_algo(a)); + + BIO_printf(bio, "Message data:\n"); + msg = TS_MSG_IMPRINT_get_msg(a); + BIO_dump_indent(bio, (const char *)M_ASN1_STRING_data(msg), + M_ASN1_STRING_length(msg), 4); + + return 1; +} diff --git a/libs/openssl/crypto/ts/ts_req_print.c b/libs/openssl/crypto/ts/ts_req_print.c new file mode 100644 index 00000000..31940eef --- /dev/null +++ b/libs/openssl/crypto/ts/ts_req_print.c @@ -0,0 +1,104 @@ +/* crypto/ts/ts_req_print.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +/* Function definitions. */ + +int TS_REQ_print_bio(BIO *bio, TS_REQ *a) +{ + int v; + ASN1_OBJECT *policy_id; + const ASN1_INTEGER *nonce; + + if (a == NULL) + return 0; + + v = TS_REQ_get_version(a); + BIO_printf(bio, "Version: %d\n", v); + + TS_MSG_IMPRINT_print_bio(bio, TS_REQ_get_msg_imprint(a)); + + BIO_printf(bio, "Policy OID: "); + policy_id = TS_REQ_get_policy_id(a); + if (policy_id == NULL) + BIO_printf(bio, "unspecified\n"); + else + TS_OBJ_print_bio(bio, policy_id); + + BIO_printf(bio, "Nonce: "); + nonce = TS_REQ_get_nonce(a); + if (nonce == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ASN1_INTEGER_print_bio(bio, nonce); + BIO_write(bio, "\n", 1); + + BIO_printf(bio, "Certificate required: %s\n", + TS_REQ_get_cert_req(a) ? "yes" : "no"); + + TS_ext_print_bio(bio, TS_REQ_get_exts(a)); + + return 1; +} diff --git a/libs/openssl/crypto/ts/ts_req_utils.c b/libs/openssl/crypto/ts/ts_req_utils.c new file mode 100644 index 00000000..362e5e58 --- /dev/null +++ b/libs/openssl/crypto/ts/ts_req_utils.c @@ -0,0 +1,232 @@ +/* crypto/ts/ts_req_utils.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +int TS_REQ_set_version(TS_REQ *a, long version) +{ + return ASN1_INTEGER_set(a->version, version); +} + +long TS_REQ_get_version(const TS_REQ *a) +{ + return ASN1_INTEGER_get(a->version); +} + +int TS_REQ_set_msg_imprint(TS_REQ *a, TS_MSG_IMPRINT *msg_imprint) +{ + TS_MSG_IMPRINT *new_msg_imprint; + + if (a->msg_imprint == msg_imprint) + return 1; + new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint); + if (new_msg_imprint == NULL) { + TSerr(TS_F_TS_REQ_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE); + return 0; + } + TS_MSG_IMPRINT_free(a->msg_imprint); + a->msg_imprint = new_msg_imprint; + return 1; +} + +TS_MSG_IMPRINT *TS_REQ_get_msg_imprint(TS_REQ *a) +{ + return a->msg_imprint; +} + +int TS_MSG_IMPRINT_set_algo(TS_MSG_IMPRINT *a, X509_ALGOR *alg) +{ + X509_ALGOR *new_alg; + + if (a->hash_algo == alg) + return 1; + new_alg = X509_ALGOR_dup(alg); + if (new_alg == NULL) { + TSerr(TS_F_TS_MSG_IMPRINT_SET_ALGO, ERR_R_MALLOC_FAILURE); + return 0; + } + X509_ALGOR_free(a->hash_algo); + a->hash_algo = new_alg; + return 1; +} + +X509_ALGOR *TS_MSG_IMPRINT_get_algo(TS_MSG_IMPRINT *a) +{ + return a->hash_algo; +} + +int TS_MSG_IMPRINT_set_msg(TS_MSG_IMPRINT *a, unsigned char *d, int len) +{ + return ASN1_OCTET_STRING_set(a->hashed_msg, d, len); +} + +ASN1_OCTET_STRING *TS_MSG_IMPRINT_get_msg(TS_MSG_IMPRINT *a) +{ + return a->hashed_msg; +} + +int TS_REQ_set_policy_id(TS_REQ *a, ASN1_OBJECT *policy) +{ + ASN1_OBJECT *new_policy; + + if (a->policy_id == policy) + return 1; + new_policy = OBJ_dup(policy); + if (new_policy == NULL) { + TSerr(TS_F_TS_REQ_SET_POLICY_ID, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_OBJECT_free(a->policy_id); + a->policy_id = new_policy; + return 1; +} + +ASN1_OBJECT *TS_REQ_get_policy_id(TS_REQ *a) +{ + return a->policy_id; +} + +int TS_REQ_set_nonce(TS_REQ *a, const ASN1_INTEGER *nonce) +{ + ASN1_INTEGER *new_nonce; + + if (a->nonce == nonce) + return 1; + new_nonce = ASN1_INTEGER_dup(nonce); + if (new_nonce == NULL) { + TSerr(TS_F_TS_REQ_SET_NONCE, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->nonce); + a->nonce = new_nonce; + return 1; +} + +const ASN1_INTEGER *TS_REQ_get_nonce(const TS_REQ *a) +{ + return a->nonce; +} + +int TS_REQ_set_cert_req(TS_REQ *a, int cert_req) +{ + a->cert_req = cert_req ? 0xFF : 0x00; + return 1; +} + +int TS_REQ_get_cert_req(const TS_REQ *a) +{ + return a->cert_req ? 1 : 0; +} + +STACK_OF(X509_EXTENSION) *TS_REQ_get_exts(TS_REQ *a) +{ + return a->extensions; +} + +void TS_REQ_ext_free(TS_REQ *a) +{ + if (!a) + return; + sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free); + a->extensions = NULL; +} + +int TS_REQ_get_ext_count(TS_REQ *a) +{ + return X509v3_get_ext_count(a->extensions); +} + +int TS_REQ_get_ext_by_NID(TS_REQ *a, int nid, int lastpos) +{ + return X509v3_get_ext_by_NID(a->extensions, nid, lastpos); +} + +int TS_REQ_get_ext_by_OBJ(TS_REQ *a, ASN1_OBJECT *obj, int lastpos) +{ + return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos); +} + +int TS_REQ_get_ext_by_critical(TS_REQ *a, int crit, int lastpos) +{ + return X509v3_get_ext_by_critical(a->extensions, crit, lastpos); +} + +X509_EXTENSION *TS_REQ_get_ext(TS_REQ *a, int loc) +{ + return X509v3_get_ext(a->extensions, loc); +} + +X509_EXTENSION *TS_REQ_delete_ext(TS_REQ *a, int loc) +{ + return X509v3_delete_ext(a->extensions, loc); +} + +int TS_REQ_add_ext(TS_REQ *a, X509_EXTENSION *ex, int loc) +{ + return X509v3_add_ext(&a->extensions, ex, loc) != NULL; +} + +void *TS_REQ_get_ext_d2i(TS_REQ *a, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(a->extensions, nid, crit, idx); +} diff --git a/libs/openssl/crypto/ts/ts_rsp_print.c b/libs/openssl/crypto/ts/ts_rsp_print.c new file mode 100644 index 00000000..e706a568 --- /dev/null +++ b/libs/openssl/crypto/ts/ts_rsp_print.c @@ -0,0 +1,281 @@ +/* crypto/ts/ts_resp_print.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include "ts.h" + +struct status_map_st { + int bit; + const char *text; +}; + +/* Local function declarations. */ + +static int TS_status_map_print(BIO *bio, struct status_map_st *a, + ASN1_BIT_STRING *v); +static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy); + +/* Function definitions. */ + +int TS_RESP_print_bio(BIO *bio, TS_RESP *a) +{ + TS_TST_INFO *tst_info; + + BIO_printf(bio, "Status info:\n"); + TS_STATUS_INFO_print_bio(bio, TS_RESP_get_status_info(a)); + + BIO_printf(bio, "\nTST info:\n"); + tst_info = TS_RESP_get_tst_info(a); + if (tst_info != NULL) + TS_TST_INFO_print_bio(bio, TS_RESP_get_tst_info(a)); + else + BIO_printf(bio, "Not included.\n"); + + return 1; +} + +int TS_STATUS_INFO_print_bio(BIO *bio, TS_STATUS_INFO *a) +{ + static const char *status_map[] = { + "Granted.", + "Granted with modifications.", + "Rejected.", + "Waiting.", + "Revocation warning.", + "Revoked." + }; + static struct status_map_st failure_map[] = { + {TS_INFO_BAD_ALG, + "unrecognized or unsupported algorithm identifier"}, + {TS_INFO_BAD_REQUEST, + "transaction not permitted or supported"}, + {TS_INFO_BAD_DATA_FORMAT, + "the data submitted has the wrong format"}, + {TS_INFO_TIME_NOT_AVAILABLE, + "the TSA's time source is not available"}, + {TS_INFO_UNACCEPTED_POLICY, + "the requested TSA policy is not supported by the TSA"}, + {TS_INFO_UNACCEPTED_EXTENSION, + "the requested extension is not supported by the TSA"}, + {TS_INFO_ADD_INFO_NOT_AVAILABLE, + "the additional information requested could not be understood " + "or is not available"}, + {TS_INFO_SYSTEM_FAILURE, + "the request cannot be handled due to system failure"}, + {-1, NULL} + }; + long status; + int i, lines = 0; + + /* Printing status code. */ + BIO_printf(bio, "Status: "); + status = ASN1_INTEGER_get(a->status); + if (0 <= status + && status < (long)(sizeof(status_map) / sizeof(status_map[0]))) + BIO_printf(bio, "%s\n", status_map[status]); + else + BIO_printf(bio, "out of bounds\n"); + + /* Printing status description. */ + BIO_printf(bio, "Status description: "); + for (i = 0; i < sk_ASN1_UTF8STRING_num(a->text); ++i) { + if (i > 0) + BIO_puts(bio, "\t"); + ASN1_STRING_print_ex(bio, sk_ASN1_UTF8STRING_value(a->text, i), 0); + BIO_puts(bio, "\n"); + } + if (i == 0) + BIO_printf(bio, "unspecified\n"); + + /* Printing failure information. */ + BIO_printf(bio, "Failure info: "); + if (a->failure_info != NULL) + lines = TS_status_map_print(bio, failure_map, a->failure_info); + if (lines == 0) + BIO_printf(bio, "unspecified"); + BIO_printf(bio, "\n"); + + return 1; +} + +static int TS_status_map_print(BIO *bio, struct status_map_st *a, + ASN1_BIT_STRING *v) +{ + int lines = 0; + + for (; a->bit >= 0; ++a) { + if (ASN1_BIT_STRING_get_bit(v, a->bit)) { + if (++lines > 1) + BIO_printf(bio, ", "); + BIO_printf(bio, "%s", a->text); + } + } + + return lines; +} + +int TS_TST_INFO_print_bio(BIO *bio, TS_TST_INFO *a) +{ + int v; + ASN1_OBJECT *policy_id; + const ASN1_INTEGER *serial; + const ASN1_GENERALIZEDTIME *gtime; + TS_ACCURACY *accuracy; + const ASN1_INTEGER *nonce; + GENERAL_NAME *tsa_name; + + if (a == NULL) + return 0; + + /* Print version. */ + v = TS_TST_INFO_get_version(a); + BIO_printf(bio, "Version: %d\n", v); + + /* Print policy id. */ + BIO_printf(bio, "Policy OID: "); + policy_id = TS_TST_INFO_get_policy_id(a); + TS_OBJ_print_bio(bio, policy_id); + + /* Print message imprint. */ + TS_MSG_IMPRINT_print_bio(bio, TS_TST_INFO_get_msg_imprint(a)); + + /* Print serial number. */ + BIO_printf(bio, "Serial number: "); + serial = TS_TST_INFO_get_serial(a); + if (serial == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ASN1_INTEGER_print_bio(bio, serial); + BIO_write(bio, "\n", 1); + + /* Print time stamp. */ + BIO_printf(bio, "Time stamp: "); + gtime = TS_TST_INFO_get_time(a); + ASN1_GENERALIZEDTIME_print(bio, gtime); + BIO_write(bio, "\n", 1); + + /* Print accuracy. */ + BIO_printf(bio, "Accuracy: "); + accuracy = TS_TST_INFO_get_accuracy(a); + if (accuracy == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ACCURACY_print_bio(bio, accuracy); + BIO_write(bio, "\n", 1); + + /* Print ordering. */ + BIO_printf(bio, "Ordering: %s\n", + TS_TST_INFO_get_ordering(a) ? "yes" : "no"); + + /* Print nonce. */ + BIO_printf(bio, "Nonce: "); + nonce = TS_TST_INFO_get_nonce(a); + if (nonce == NULL) + BIO_printf(bio, "unspecified"); + else + TS_ASN1_INTEGER_print_bio(bio, nonce); + BIO_write(bio, "\n", 1); + + /* Print TSA name. */ + BIO_printf(bio, "TSA: "); + tsa_name = TS_TST_INFO_get_tsa(a); + if (tsa_name == NULL) + BIO_printf(bio, "unspecified"); + else { + STACK_OF(CONF_VALUE) *nval; + if ((nval = i2v_GENERAL_NAME(NULL, tsa_name, NULL))) + X509V3_EXT_val_prn(bio, nval, 0, 0); + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + } + BIO_write(bio, "\n", 1); + + /* Print extensions. */ + TS_ext_print_bio(bio, TS_TST_INFO_get_exts(a)); + + return 1; +} + +static int TS_ACCURACY_print_bio(BIO *bio, const TS_ACCURACY *accuracy) +{ + const ASN1_INTEGER *seconds = TS_ACCURACY_get_seconds(accuracy); + const ASN1_INTEGER *millis = TS_ACCURACY_get_millis(accuracy); + const ASN1_INTEGER *micros = TS_ACCURACY_get_micros(accuracy); + + if (seconds != NULL) + TS_ASN1_INTEGER_print_bio(bio, seconds); + else + BIO_printf(bio, "unspecified"); + BIO_printf(bio, " seconds, "); + if (millis != NULL) + TS_ASN1_INTEGER_print_bio(bio, millis); + else + BIO_printf(bio, "unspecified"); + BIO_printf(bio, " millis, "); + if (micros != NULL) + TS_ASN1_INTEGER_print_bio(bio, micros); + else + BIO_printf(bio, "unspecified"); + BIO_printf(bio, " micros"); + + return 1; +} diff --git a/libs/openssl/crypto/ts/ts_rsp_sign.c b/libs/openssl/crypto/ts/ts_rsp_sign.c new file mode 100644 index 00000000..031d872e --- /dev/null +++ b/libs/openssl/crypto/ts/ts_rsp_sign.c @@ -0,0 +1,1025 @@ +/* crypto/ts/ts_resp_sign.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" + +#if defined(OPENSSL_SYS_UNIX) +# include +#endif + +#include +#include +#include + +/* Private function declarations. */ + +static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *, void *); +static int def_time_cb(struct TS_resp_ctx *, void *, long *sec, long *usec); +static int def_extension_cb(struct TS_resp_ctx *, X509_EXTENSION *, void *); + +static void TS_RESP_CTX_init(TS_RESP_CTX *ctx); +static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx); +static int TS_RESP_check_request(TS_RESP_CTX *ctx); +static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx); +static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, + ASN1_OBJECT *policy); +static int TS_RESP_process_extensions(TS_RESP_CTX *ctx); +static int TS_RESP_sign(TS_RESP_CTX *ctx); + +static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, + STACK_OF(X509) *certs); +static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed); +static int TS_TST_INFO_content_new(PKCS7 *p7); +static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc); + +static ASN1_GENERALIZEDTIME +*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *, long, long, + unsigned); + +/* Default callbacks for response generation. */ + +static ASN1_INTEGER *def_serial_cb(struct TS_resp_ctx *ctx, void *data) +{ + ASN1_INTEGER *serial = ASN1_INTEGER_new(); + if (!serial) + goto err; + if (!ASN1_INTEGER_set(serial, 1)) + goto err; + return serial; + err: + TSerr(TS_F_DEF_SERIAL_CB, ERR_R_MALLOC_FAILURE); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Error during serial number generation."); + return NULL; +} + +#if defined(OPENSSL_SYS_UNIX) + +/* Use the gettimeofday function call. */ +static int def_time_cb(struct TS_resp_ctx *ctx, void *data, + long *sec, long *usec) +{ + struct timeval tv; + if (gettimeofday(&tv, NULL) != 0) { + TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Time is not available."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); + return 0; + } + /* Return time to caller. */ + *sec = tv.tv_sec; + *usec = tv.tv_usec; + + return 1; +} + +#else + +/* Use the time function call that provides only seconds precision. */ +static int def_time_cb(struct TS_resp_ctx *ctx, void *data, + long *sec, long *usec) +{ + time_t t; + if (time(&t) == (time_t)-1) { + TSerr(TS_F_DEF_TIME_CB, TS_R_TIME_SYSCALL_ERROR); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Time is not available."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_TIME_NOT_AVAILABLE); + return 0; + } + /* Return time to caller, only second precision. */ + *sec = (long)t; + *usec = 0; + + return 1; +} + +#endif + +static int def_extension_cb(struct TS_resp_ctx *ctx, X509_EXTENSION *ext, + void *data) +{ + /* No extensions are processed here. */ + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Unsupported extension."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_EXTENSION); + return 0; +} + +/* TS_RESP_CTX management functions. */ + +TS_RESP_CTX *TS_RESP_CTX_new() +{ + TS_RESP_CTX *ctx; + + if (!(ctx = (TS_RESP_CTX *)OPENSSL_malloc(sizeof(TS_RESP_CTX)))) { + TSerr(TS_F_TS_RESP_CTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + memset(ctx, 0, sizeof(TS_RESP_CTX)); + + /* Setting default callbacks. */ + ctx->serial_cb = def_serial_cb; + ctx->time_cb = def_time_cb; + ctx->extension_cb = def_extension_cb; + + return ctx; +} + +void TS_RESP_CTX_free(TS_RESP_CTX *ctx) +{ + if (!ctx) + return; + + X509_free(ctx->signer_cert); + EVP_PKEY_free(ctx->signer_key); + sk_X509_pop_free(ctx->certs, X509_free); + sk_ASN1_OBJECT_pop_free(ctx->policies, ASN1_OBJECT_free); + ASN1_OBJECT_free(ctx->default_policy); + sk_EVP_MD_free(ctx->mds); /* No EVP_MD_free method exists. */ + ASN1_INTEGER_free(ctx->seconds); + ASN1_INTEGER_free(ctx->millis); + ASN1_INTEGER_free(ctx->micros); + OPENSSL_free(ctx); +} + +int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer) +{ + if (X509_check_purpose(signer, X509_PURPOSE_TIMESTAMP_SIGN, 0) != 1) { + TSerr(TS_F_TS_RESP_CTX_SET_SIGNER_CERT, + TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE); + return 0; + } + if (ctx->signer_cert) + X509_free(ctx->signer_cert); + ctx->signer_cert = signer; + CRYPTO_add(&ctx->signer_cert->references, +1, CRYPTO_LOCK_X509); + return 1; +} + +int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key) +{ + if (ctx->signer_key) + EVP_PKEY_free(ctx->signer_key); + ctx->signer_key = key; + CRYPTO_add(&ctx->signer_key->references, +1, CRYPTO_LOCK_EVP_PKEY); + + return 1; +} + +int TS_RESP_CTX_set_def_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *def_policy) +{ + if (ctx->default_policy) + ASN1_OBJECT_free(ctx->default_policy); + if (!(ctx->default_policy = OBJ_dup(def_policy))) + goto err; + return 1; + err: + TSerr(TS_F_TS_RESP_CTX_SET_DEF_POLICY, ERR_R_MALLOC_FAILURE); + return 0; +} + +int TS_RESP_CTX_set_certs(TS_RESP_CTX *ctx, STACK_OF(X509) *certs) +{ + int i; + + if (ctx->certs) { + sk_X509_pop_free(ctx->certs, X509_free); + ctx->certs = NULL; + } + if (!certs) + return 1; + if (!(ctx->certs = sk_X509_dup(certs))) { + TSerr(TS_F_TS_RESP_CTX_SET_CERTS, ERR_R_MALLOC_FAILURE); + return 0; + } + for (i = 0; i < sk_X509_num(ctx->certs); ++i) { + X509 *cert = sk_X509_value(ctx->certs, i); + CRYPTO_add(&cert->references, +1, CRYPTO_LOCK_X509); + } + + return 1; +} + +int TS_RESP_CTX_add_policy(TS_RESP_CTX *ctx, ASN1_OBJECT *policy) +{ + ASN1_OBJECT *copy = NULL; + + /* Create new policy stack if necessary. */ + if (!ctx->policies && !(ctx->policies = sk_ASN1_OBJECT_new_null())) + goto err; + if (!(copy = OBJ_dup(policy))) + goto err; + if (!sk_ASN1_OBJECT_push(ctx->policies, copy)) + goto err; + + return 1; + err: + TSerr(TS_F_TS_RESP_CTX_ADD_POLICY, ERR_R_MALLOC_FAILURE); + ASN1_OBJECT_free(copy); + return 0; +} + +int TS_RESP_CTX_add_md(TS_RESP_CTX *ctx, const EVP_MD *md) +{ + /* Create new md stack if necessary. */ + if (!ctx->mds && !(ctx->mds = sk_EVP_MD_new_null())) + goto err; + /* Add the shared md, no copy needed. */ + if (!sk_EVP_MD_push(ctx->mds, (EVP_MD *)md)) + goto err; + + return 1; + err: + TSerr(TS_F_TS_RESP_CTX_ADD_MD, ERR_R_MALLOC_FAILURE); + return 0; +} + +#define TS_RESP_CTX_accuracy_free(ctx) \ + ASN1_INTEGER_free(ctx->seconds); \ + ctx->seconds = NULL; \ + ASN1_INTEGER_free(ctx->millis); \ + ctx->millis = NULL; \ + ASN1_INTEGER_free(ctx->micros); \ + ctx->micros = NULL; + +int TS_RESP_CTX_set_accuracy(TS_RESP_CTX *ctx, + int secs, int millis, int micros) +{ + + TS_RESP_CTX_accuracy_free(ctx); + if (secs && (!(ctx->seconds = ASN1_INTEGER_new()) + || !ASN1_INTEGER_set(ctx->seconds, secs))) + goto err; + if (millis && (!(ctx->millis = ASN1_INTEGER_new()) + || !ASN1_INTEGER_set(ctx->millis, millis))) + goto err; + if (micros && (!(ctx->micros = ASN1_INTEGER_new()) + || !ASN1_INTEGER_set(ctx->micros, micros))) + goto err; + + return 1; + err: + TS_RESP_CTX_accuracy_free(ctx); + TSerr(TS_F_TS_RESP_CTX_SET_ACCURACY, ERR_R_MALLOC_FAILURE); + return 0; +} + +void TS_RESP_CTX_add_flags(TS_RESP_CTX *ctx, int flags) +{ + ctx->flags |= flags; +} + +void TS_RESP_CTX_set_serial_cb(TS_RESP_CTX *ctx, TS_serial_cb cb, void *data) +{ + ctx->serial_cb = cb; + ctx->serial_cb_data = data; +} + +void TS_RESP_CTX_set_time_cb(TS_RESP_CTX *ctx, TS_time_cb cb, void *data) +{ + ctx->time_cb = cb; + ctx->time_cb_data = data; +} + +void TS_RESP_CTX_set_extension_cb(TS_RESP_CTX *ctx, + TS_extension_cb cb, void *data) +{ + ctx->extension_cb = cb; + ctx->extension_cb_data = data; +} + +int TS_RESP_CTX_set_status_info(TS_RESP_CTX *ctx, + int status, const char *text) +{ + TS_STATUS_INFO *si = NULL; + ASN1_UTF8STRING *utf8_text = NULL; + int ret = 0; + + if (!(si = TS_STATUS_INFO_new())) + goto err; + if (!ASN1_INTEGER_set(si->status, status)) + goto err; + if (text) { + if (!(utf8_text = ASN1_UTF8STRING_new()) + || !ASN1_STRING_set(utf8_text, text, strlen(text))) + goto err; + if (!si->text && !(si->text = sk_ASN1_UTF8STRING_new_null())) + goto err; + if (!sk_ASN1_UTF8STRING_push(si->text, utf8_text)) + goto err; + utf8_text = NULL; /* Ownership is lost. */ + } + if (!TS_RESP_set_status_info(ctx->response, si)) + goto err; + ret = 1; + err: + if (!ret) + TSerr(TS_F_TS_RESP_CTX_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE); + TS_STATUS_INFO_free(si); + ASN1_UTF8STRING_free(utf8_text); + return ret; +} + +int TS_RESP_CTX_set_status_info_cond(TS_RESP_CTX *ctx, + int status, const char *text) +{ + int ret = 1; + TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response); + + if (ASN1_INTEGER_get(si->status) == TS_STATUS_GRANTED) { + /* Status has not been set, set it now. */ + ret = TS_RESP_CTX_set_status_info(ctx, status, text); + } + return ret; +} + +int TS_RESP_CTX_add_failure_info(TS_RESP_CTX *ctx, int failure) +{ + TS_STATUS_INFO *si = TS_RESP_get_status_info(ctx->response); + if (!si->failure_info && !(si->failure_info = ASN1_BIT_STRING_new())) + goto err; + if (!ASN1_BIT_STRING_set_bit(si->failure_info, failure, 1)) + goto err; + return 1; + err: + TSerr(TS_F_TS_RESP_CTX_ADD_FAILURE_INFO, ERR_R_MALLOC_FAILURE); + return 0; +} + +TS_REQ *TS_RESP_CTX_get_request(TS_RESP_CTX *ctx) +{ + return ctx->request; +} + +TS_TST_INFO *TS_RESP_CTX_get_tst_info(TS_RESP_CTX *ctx) +{ + return ctx->tst_info; +} + +int TS_RESP_CTX_set_clock_precision_digits(TS_RESP_CTX *ctx, + unsigned precision) +{ + if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) + return 0; + ctx->clock_precision_digits = precision; + return 1; +} + +/* Main entry method of the response generation. */ +TS_RESP *TS_RESP_create_response(TS_RESP_CTX *ctx, BIO *req_bio) +{ + ASN1_OBJECT *policy; + TS_RESP *response; + int result = 0; + + TS_RESP_CTX_init(ctx); + + /* Creating the response object. */ + if (!(ctx->response = TS_RESP_new())) { + TSerr(TS_F_TS_RESP_CREATE_RESPONSE, ERR_R_MALLOC_FAILURE); + goto end; + } + + /* Parsing DER request. */ + if (!(ctx->request = d2i_TS_REQ_bio(req_bio, NULL))) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Bad request format or " "system error."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); + goto end; + } + + /* Setting default status info. */ + if (!TS_RESP_CTX_set_status_info(ctx, TS_STATUS_GRANTED, NULL)) + goto end; + + /* Checking the request format. */ + if (!TS_RESP_check_request(ctx)) + goto end; + + /* Checking acceptable policies. */ + if (!(policy = TS_RESP_get_policy(ctx))) + goto end; + + /* Creating the TS_TST_INFO object. */ + if (!(ctx->tst_info = TS_RESP_create_tst_info(ctx, policy))) + goto end; + + /* Processing extensions. */ + if (!TS_RESP_process_extensions(ctx)) + goto end; + + /* Generating the signature. */ + if (!TS_RESP_sign(ctx)) + goto end; + + /* Everything was successful. */ + result = 1; + end: + if (!result) { + TSerr(TS_F_TS_RESP_CREATE_RESPONSE, TS_R_RESPONSE_SETUP_ERROR); + if (ctx->response != NULL) { + if (TS_RESP_CTX_set_status_info_cond(ctx, + TS_STATUS_REJECTION, + "Error during response " + "generation.") == 0) { + TS_RESP_free(ctx->response); + ctx->response = NULL; + } + } + } + response = ctx->response; + ctx->response = NULL; /* Ownership will be returned to caller. */ + TS_RESP_CTX_cleanup(ctx); + return response; +} + +/* Initializes the variable part of the context. */ +static void TS_RESP_CTX_init(TS_RESP_CTX *ctx) +{ + ctx->request = NULL; + ctx->response = NULL; + ctx->tst_info = NULL; +} + +/* Cleans up the variable part of the context. */ +static void TS_RESP_CTX_cleanup(TS_RESP_CTX *ctx) +{ + TS_REQ_free(ctx->request); + ctx->request = NULL; + TS_RESP_free(ctx->response); + ctx->response = NULL; + TS_TST_INFO_free(ctx->tst_info); + ctx->tst_info = NULL; +} + +/* Checks the format and content of the request. */ +static int TS_RESP_check_request(TS_RESP_CTX *ctx) +{ + TS_REQ *request = ctx->request; + TS_MSG_IMPRINT *msg_imprint; + X509_ALGOR *md_alg; + int md_alg_id; + const ASN1_OCTET_STRING *digest; + EVP_MD *md = NULL; + int i; + + /* Checking request version. */ + if (TS_REQ_get_version(request) != 1) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Bad request version."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_REQUEST); + return 0; + } + + /* Checking message digest algorithm. */ + msg_imprint = TS_REQ_get_msg_imprint(request); + md_alg = TS_MSG_IMPRINT_get_algo(msg_imprint); + md_alg_id = OBJ_obj2nid(md_alg->algorithm); + for (i = 0; !md && i < sk_EVP_MD_num(ctx->mds); ++i) { + EVP_MD *current_md = sk_EVP_MD_value(ctx->mds, i); + if (md_alg_id == EVP_MD_type(current_md)) + md = current_md; + } + if (!md) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Message digest algorithm is " + "not supported."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); + return 0; + } + + /* No message digest takes parameter. */ + if (md_alg->parameter && ASN1_TYPE_get(md_alg->parameter) != V_ASN1_NULL) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Superfluous message digest " + "parameter."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_ALG); + return 0; + } + /* Checking message digest size. */ + digest = TS_MSG_IMPRINT_get_msg(msg_imprint); + if (digest->length != EVP_MD_size(md)) { + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Bad message digest."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_BAD_DATA_FORMAT); + return 0; + } + + return 1; +} + +/* Returns the TSA policy based on the requested and acceptable policies. */ +static ASN1_OBJECT *TS_RESP_get_policy(TS_RESP_CTX *ctx) +{ + ASN1_OBJECT *requested = TS_REQ_get_policy_id(ctx->request); + ASN1_OBJECT *policy = NULL; + int i; + + if (ctx->default_policy == NULL) { + TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_INVALID_NULL_POINTER); + return NULL; + } + /* + * Return the default policy if none is requested or the default is + * requested. + */ + if (!requested || !OBJ_cmp(requested, ctx->default_policy)) + policy = ctx->default_policy; + + /* Check if the policy is acceptable. */ + for (i = 0; !policy && i < sk_ASN1_OBJECT_num(ctx->policies); ++i) { + ASN1_OBJECT *current = sk_ASN1_OBJECT_value(ctx->policies, i); + if (!OBJ_cmp(requested, current)) + policy = current; + } + if (!policy) { + TSerr(TS_F_TS_RESP_GET_POLICY, TS_R_UNACCEPTABLE_POLICY); + TS_RESP_CTX_set_status_info(ctx, TS_STATUS_REJECTION, + "Requested policy is not " "supported."); + TS_RESP_CTX_add_failure_info(ctx, TS_INFO_UNACCEPTED_POLICY); + } + return policy; +} + +/* Creates the TS_TST_INFO object based on the settings of the context. */ +static TS_TST_INFO *TS_RESP_create_tst_info(TS_RESP_CTX *ctx, + ASN1_OBJECT *policy) +{ + int result = 0; + TS_TST_INFO *tst_info = NULL; + ASN1_INTEGER *serial = NULL; + ASN1_GENERALIZEDTIME *asn1_time = NULL; + long sec, usec; + TS_ACCURACY *accuracy = NULL; + const ASN1_INTEGER *nonce; + GENERAL_NAME *tsa_name = NULL; + + if (!(tst_info = TS_TST_INFO_new())) + goto end; + if (!TS_TST_INFO_set_version(tst_info, 1)) + goto end; + if (!TS_TST_INFO_set_policy_id(tst_info, policy)) + goto end; + if (!TS_TST_INFO_set_msg_imprint(tst_info, ctx->request->msg_imprint)) + goto end; + if (!(serial = (*ctx->serial_cb) (ctx, ctx->serial_cb_data)) + || !TS_TST_INFO_set_serial(tst_info, serial)) + goto end; + if (!(*ctx->time_cb) (ctx, ctx->time_cb_data, &sec, &usec) + || !(asn1_time = TS_RESP_set_genTime_with_precision(NULL, + sec, usec, + ctx->clock_precision_digits)) + || !TS_TST_INFO_set_time(tst_info, asn1_time)) + goto end; + + /* Setting accuracy if needed. */ + if ((ctx->seconds || ctx->millis || ctx->micros) + && !(accuracy = TS_ACCURACY_new())) + goto end; + + if (ctx->seconds && !TS_ACCURACY_set_seconds(accuracy, ctx->seconds)) + goto end; + if (ctx->millis && !TS_ACCURACY_set_millis(accuracy, ctx->millis)) + goto end; + if (ctx->micros && !TS_ACCURACY_set_micros(accuracy, ctx->micros)) + goto end; + if (accuracy && !TS_TST_INFO_set_accuracy(tst_info, accuracy)) + goto end; + + /* Setting ordering. */ + if ((ctx->flags & TS_ORDERING) + && !TS_TST_INFO_set_ordering(tst_info, 1)) + goto end; + + /* Setting nonce if needed. */ + if ((nonce = TS_REQ_get_nonce(ctx->request)) != NULL + && !TS_TST_INFO_set_nonce(tst_info, nonce)) + goto end; + + /* Setting TSA name to subject of signer certificate. */ + if (ctx->flags & TS_TSA_NAME) { + if (!(tsa_name = GENERAL_NAME_new())) + goto end; + tsa_name->type = GEN_DIRNAME; + tsa_name->d.dirn = + X509_NAME_dup(ctx->signer_cert->cert_info->subject); + if (!tsa_name->d.dirn) + goto end; + if (!TS_TST_INFO_set_tsa(tst_info, tsa_name)) + goto end; + } + + result = 1; + end: + if (!result) { + TS_TST_INFO_free(tst_info); + tst_info = NULL; + TSerr(TS_F_TS_RESP_CREATE_TST_INFO, TS_R_TST_INFO_SETUP_ERROR); + TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, + "Error during TSTInfo " + "generation."); + } + GENERAL_NAME_free(tsa_name); + TS_ACCURACY_free(accuracy); + ASN1_GENERALIZEDTIME_free(asn1_time); + ASN1_INTEGER_free(serial); + + return tst_info; +} + +/* Processing the extensions of the request. */ +static int TS_RESP_process_extensions(TS_RESP_CTX *ctx) +{ + STACK_OF(X509_EXTENSION) *exts = TS_REQ_get_exts(ctx->request); + int i; + int ok = 1; + + for (i = 0; ok && i < sk_X509_EXTENSION_num(exts); ++i) { + X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i); + /* + * XXXXX The last argument was previously (void *)ctx->extension_cb, + * but ISO C doesn't permit converting a function pointer to void *. + * For lack of better information, I'm placing a NULL there instead. + * The callback can pick its own address out from the ctx anyway... + */ + ok = (*ctx->extension_cb) (ctx, ext, NULL); + } + + return ok; +} + +/* Functions for signing the TS_TST_INFO structure of the context. */ +static int TS_RESP_sign(TS_RESP_CTX *ctx) +{ + int ret = 0; + PKCS7 *p7 = NULL; + PKCS7_SIGNER_INFO *si; + STACK_OF(X509) *certs; /* Certificates to include in sc. */ + ESS_SIGNING_CERT *sc = NULL; + ASN1_OBJECT *oid; + BIO *p7bio = NULL; + int i; + + /* Check if signcert and pkey match. */ + if (!X509_check_private_key(ctx->signer_cert, ctx->signer_key)) { + TSerr(TS_F_TS_RESP_SIGN, TS_R_PRIVATE_KEY_DOES_NOT_MATCH_CERTIFICATE); + goto err; + } + + /* Create a new PKCS7 signed object. */ + if (!(p7 = PKCS7_new())) { + TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!PKCS7_set_type(p7, NID_pkcs7_signed)) + goto err; + + /* Force SignedData version to be 3 instead of the default 1. */ + if (!ASN1_INTEGER_set(p7->d.sign->version, 3)) + goto err; + + /* Add signer certificate and optional certificate chain. */ + if (TS_REQ_get_cert_req(ctx->request)) { + PKCS7_add_certificate(p7, ctx->signer_cert); + if (ctx->certs) { + for (i = 0; i < sk_X509_num(ctx->certs); ++i) { + X509 *cert = sk_X509_value(ctx->certs, i); + PKCS7_add_certificate(p7, cert); + } + } + } + + /* Add a new signer info. */ + if (!(si = PKCS7_add_signature(p7, ctx->signer_cert, + ctx->signer_key, EVP_sha1()))) { + TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNATURE_ERROR); + goto err; + } + + /* Add content type signed attribute to the signer info. */ + oid = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); + if (!PKCS7_add_signed_attribute(si, NID_pkcs9_contentType, + V_ASN1_OBJECT, oid)) { + TSerr(TS_F_TS_RESP_SIGN, TS_R_PKCS7_ADD_SIGNED_ATTR_ERROR); + goto err; + } + + /* + * Create the ESS SigningCertificate attribute which contains the signer + * certificate id and optionally the certificate chain. + */ + certs = ctx->flags & TS_ESS_CERT_ID_CHAIN ? ctx->certs : NULL; + if (!(sc = ESS_SIGNING_CERT_new_init(ctx->signer_cert, certs))) + goto err; + + /* Add SigningCertificate signed attribute to the signer info. */ + if (!ESS_add_signing_cert(si, sc)) { + TSerr(TS_F_TS_RESP_SIGN, TS_R_ESS_ADD_SIGNING_CERT_ERROR); + goto err; + } + + /* Add a new empty NID_id_smime_ct_TSTInfo encapsulated content. */ + if (!TS_TST_INFO_content_new(p7)) + goto err; + + /* Add the DER encoded tst_info to the PKCS7 structure. */ + if (!(p7bio = PKCS7_dataInit(p7, NULL))) { + TSerr(TS_F_TS_RESP_SIGN, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Convert tst_info to DER. */ + if (!i2d_TS_TST_INFO_bio(p7bio, ctx->tst_info)) { + TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); + goto err; + } + + /* Create the signature and add it to the signer info. */ + if (!PKCS7_dataFinal(p7, p7bio)) { + TSerr(TS_F_TS_RESP_SIGN, TS_R_TS_DATASIGN); + goto err; + } + + /* Set new PKCS7 and TST_INFO objects. */ + TS_RESP_set_tst_info(ctx->response, p7, ctx->tst_info); + p7 = NULL; /* Ownership is lost. */ + ctx->tst_info = NULL; /* Ownership is lost. */ + + ret = 1; + err: + if (!ret) + TS_RESP_CTX_set_status_info_cond(ctx, TS_STATUS_REJECTION, + "Error during signature " + "generation."); + BIO_free_all(p7bio); + ESS_SIGNING_CERT_free(sc); + PKCS7_free(p7); + return ret; +} + +static ESS_SIGNING_CERT *ESS_SIGNING_CERT_new_init(X509 *signcert, + STACK_OF(X509) *certs) +{ + ESS_CERT_ID *cid; + ESS_SIGNING_CERT *sc = NULL; + int i; + + /* Creating the ESS_CERT_ID stack. */ + if (!(sc = ESS_SIGNING_CERT_new())) + goto err; + if (!sc->cert_ids && !(sc->cert_ids = sk_ESS_CERT_ID_new_null())) + goto err; + + /* Adding the signing certificate id. */ + if (!(cid = ESS_CERT_ID_new_init(signcert, 0)) + || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) + goto err; + /* Adding the certificate chain ids. */ + for (i = 0; i < sk_X509_num(certs); ++i) { + X509 *cert = sk_X509_value(certs, i); + if (!(cid = ESS_CERT_ID_new_init(cert, 1)) + || !sk_ESS_CERT_ID_push(sc->cert_ids, cid)) + goto err; + } + + return sc; + err: + ESS_SIGNING_CERT_free(sc); + TSerr(TS_F_ESS_SIGNING_CERT_NEW_INIT, ERR_R_MALLOC_FAILURE); + return NULL; +} + +static ESS_CERT_ID *ESS_CERT_ID_new_init(X509 *cert, int issuer_needed) +{ + ESS_CERT_ID *cid = NULL; + GENERAL_NAME *name = NULL; + + /* Recompute SHA1 hash of certificate if necessary (side effect). */ + X509_check_purpose(cert, -1, 0); + + if (!(cid = ESS_CERT_ID_new())) + goto err; + if (!ASN1_OCTET_STRING_set(cid->hash, cert->sha1_hash, + sizeof(cert->sha1_hash))) + goto err; + + /* Setting the issuer/serial if requested. */ + if (issuer_needed) { + /* Creating issuer/serial structure. */ + if (!cid->issuer_serial + && !(cid->issuer_serial = ESS_ISSUER_SERIAL_new())) + goto err; + /* Creating general name from the certificate issuer. */ + if (!(name = GENERAL_NAME_new())) + goto err; + name->type = GEN_DIRNAME; + if (!(name->d.dirn = X509_NAME_dup(cert->cert_info->issuer))) + goto err; + if (!sk_GENERAL_NAME_push(cid->issuer_serial->issuer, name)) + goto err; + name = NULL; /* Ownership is lost. */ + /* Setting the serial number. */ + ASN1_INTEGER_free(cid->issuer_serial->serial); + if (!(cid->issuer_serial->serial = + ASN1_INTEGER_dup(cert->cert_info->serialNumber))) + goto err; + } + + return cid; + err: + GENERAL_NAME_free(name); + ESS_CERT_ID_free(cid); + TSerr(TS_F_ESS_CERT_ID_NEW_INIT, ERR_R_MALLOC_FAILURE); + return NULL; +} + +static int TS_TST_INFO_content_new(PKCS7 *p7) +{ + PKCS7 *ret = NULL; + ASN1_OCTET_STRING *octet_string = NULL; + + /* Create new encapsulated NID_id_smime_ct_TSTInfo content. */ + if (!(ret = PKCS7_new())) + goto err; + if (!(ret->d.other = ASN1_TYPE_new())) + goto err; + ret->type = OBJ_nid2obj(NID_id_smime_ct_TSTInfo); + if (!(octet_string = ASN1_OCTET_STRING_new())) + goto err; + ASN1_TYPE_set(ret->d.other, V_ASN1_OCTET_STRING, octet_string); + octet_string = NULL; + + /* Add encapsulated content to signed PKCS7 structure. */ + if (!PKCS7_set_content(p7, ret)) + goto err; + + return 1; + err: + ASN1_OCTET_STRING_free(octet_string); + PKCS7_free(ret); + return 0; +} + +static int ESS_add_signing_cert(PKCS7_SIGNER_INFO *si, ESS_SIGNING_CERT *sc) +{ + ASN1_STRING *seq = NULL; + unsigned char *p, *pp = NULL; + int len; + + len = i2d_ESS_SIGNING_CERT(sc, NULL); + if (!(pp = (unsigned char *)OPENSSL_malloc(len))) { + TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); + goto err; + } + p = pp; + i2d_ESS_SIGNING_CERT(sc, &p); + if (!(seq = ASN1_STRING_new()) || !ASN1_STRING_set(seq, pp, len)) { + TSerr(TS_F_ESS_ADD_SIGNING_CERT, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_free(pp); + pp = NULL; + return PKCS7_add_signed_attribute(si, + NID_id_smime_aa_signingCertificate, + V_ASN1_SEQUENCE, seq); + err: + ASN1_STRING_free(seq); + OPENSSL_free(pp); + + return 0; +} + +static ASN1_GENERALIZEDTIME +*TS_RESP_set_genTime_with_precision(ASN1_GENERALIZEDTIME *asn1_time, + long sec, long usec, unsigned precision) +{ + time_t time_sec = (time_t)sec; + struct tm *tm = NULL; + char genTime_str[17 + TS_MAX_CLOCK_PRECISION_DIGITS]; + char *p = genTime_str; + char *p_end = genTime_str + sizeof(genTime_str); + + if (precision > TS_MAX_CLOCK_PRECISION_DIGITS) + goto err; + + if (!(tm = gmtime(&time_sec))) + goto err; + + /* + * Put "genTime_str" in GeneralizedTime format. We work around the + * restrictions imposed by rfc3280 (i.e. "GeneralizedTime values MUST + * NOT include fractional seconds") and OpenSSL related functions to + * meet the rfc3161 requirement: "GeneralizedTime syntax can include + * fraction-of-second details". + */ + p += BIO_snprintf(p, p_end - p, + "%04d%02d%02d%02d%02d%02d", + tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, + tm->tm_hour, tm->tm_min, tm->tm_sec); + if (precision > 0) { + /* Add fraction of seconds (leave space for dot and null). */ + BIO_snprintf(p, 2 + precision, ".%06ld", usec); + /* + * We cannot use the snprintf return value, because it might have + * been truncated. + */ + p += strlen(p); + + /* + * To make things a bit harder, X.690 | ISO/IEC 8825-1 provides the + * following restrictions for a DER-encoding, which OpenSSL + * (specifically ASN1_GENERALIZEDTIME_check() function) doesn't + * support: "The encoding MUST terminate with a "Z" (which means + * "Zulu" time). The decimal point element, if present, MUST be the + * point option ".". The fractional-seconds elements, if present, + * MUST omit all trailing 0's; if the elements correspond to 0, they + * MUST be wholly omitted, and the decimal point element also MUST be + * omitted." + */ + /* + * Remove trailing zeros. The dot guarantees the exit condition of + * this loop even if all the digits are zero. + */ + while (*--p == '0') + /* + * empty + */ ; + /* p points to either the dot or the last non-zero digit. */ + if (*p != '.') + ++p; + } + /* Add the trailing Z and the terminating null. */ + *p++ = 'Z'; + *p++ = '\0'; + + /* Now call OpenSSL to check and set our genTime value */ + if (!asn1_time && !(asn1_time = M_ASN1_GENERALIZEDTIME_new())) + goto err; + if (!ASN1_GENERALIZEDTIME_set_string(asn1_time, genTime_str)) { + ASN1_GENERALIZEDTIME_free(asn1_time); + goto err; + } + + return asn1_time; + err: + TSerr(TS_F_TS_RESP_SET_GENTIME_WITH_PRECISION, TS_R_COULD_NOT_SET_TIME); + return NULL; +} diff --git a/libs/openssl/crypto/ts/ts_rsp_utils.c b/libs/openssl/crypto/ts/ts_rsp_utils.c new file mode 100644 index 00000000..f6f63329 --- /dev/null +++ b/libs/openssl/crypto/ts/ts_rsp_utils.c @@ -0,0 +1,396 @@ +/* crypto/ts/ts_resp_utils.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +/* Function definitions. */ + +int TS_RESP_set_status_info(TS_RESP *a, TS_STATUS_INFO *status_info) +{ + TS_STATUS_INFO *new_status_info; + + if (a->status_info == status_info) + return 1; + new_status_info = TS_STATUS_INFO_dup(status_info); + if (new_status_info == NULL) { + TSerr(TS_F_TS_RESP_SET_STATUS_INFO, ERR_R_MALLOC_FAILURE); + return 0; + } + TS_STATUS_INFO_free(a->status_info); + a->status_info = new_status_info; + + return 1; +} + +TS_STATUS_INFO *TS_RESP_get_status_info(TS_RESP *a) +{ + return a->status_info; +} + +/* Caller loses ownership of PKCS7 and TS_TST_INFO objects. */ +void TS_RESP_set_tst_info(TS_RESP *a, PKCS7 *p7, TS_TST_INFO *tst_info) +{ + /* Set new PKCS7 and TST_INFO objects. */ + PKCS7_free(a->token); + a->token = p7; + TS_TST_INFO_free(a->tst_info); + a->tst_info = tst_info; +} + +PKCS7 *TS_RESP_get_token(TS_RESP *a) +{ + return a->token; +} + +TS_TST_INFO *TS_RESP_get_tst_info(TS_RESP *a) +{ + return a->tst_info; +} + +int TS_TST_INFO_set_version(TS_TST_INFO *a, long version) +{ + return ASN1_INTEGER_set(a->version, version); +} + +long TS_TST_INFO_get_version(const TS_TST_INFO *a) +{ + return ASN1_INTEGER_get(a->version); +} + +int TS_TST_INFO_set_policy_id(TS_TST_INFO *a, ASN1_OBJECT *policy) +{ + ASN1_OBJECT *new_policy; + + if (a->policy_id == policy) + return 1; + new_policy = OBJ_dup(policy); + if (new_policy == NULL) { + TSerr(TS_F_TS_TST_INFO_SET_POLICY_ID, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_OBJECT_free(a->policy_id); + a->policy_id = new_policy; + return 1; +} + +ASN1_OBJECT *TS_TST_INFO_get_policy_id(TS_TST_INFO *a) +{ + return a->policy_id; +} + +int TS_TST_INFO_set_msg_imprint(TS_TST_INFO *a, TS_MSG_IMPRINT *msg_imprint) +{ + TS_MSG_IMPRINT *new_msg_imprint; + + if (a->msg_imprint == msg_imprint) + return 1; + new_msg_imprint = TS_MSG_IMPRINT_dup(msg_imprint); + if (new_msg_imprint == NULL) { + TSerr(TS_F_TS_TST_INFO_SET_MSG_IMPRINT, ERR_R_MALLOC_FAILURE); + return 0; + } + TS_MSG_IMPRINT_free(a->msg_imprint); + a->msg_imprint = new_msg_imprint; + return 1; +} + +TS_MSG_IMPRINT *TS_TST_INFO_get_msg_imprint(TS_TST_INFO *a) +{ + return a->msg_imprint; +} + +int TS_TST_INFO_set_serial(TS_TST_INFO *a, const ASN1_INTEGER *serial) +{ + ASN1_INTEGER *new_serial; + + if (a->serial == serial) + return 1; + new_serial = ASN1_INTEGER_dup(serial); + if (new_serial == NULL) { + TSerr(TS_F_TS_TST_INFO_SET_SERIAL, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->serial); + a->serial = new_serial; + return 1; +} + +const ASN1_INTEGER *TS_TST_INFO_get_serial(const TS_TST_INFO *a) +{ + return a->serial; +} + +int TS_TST_INFO_set_time(TS_TST_INFO *a, const ASN1_GENERALIZEDTIME *gtime) +{ + ASN1_GENERALIZEDTIME *new_time; + + if (a->time == gtime) + return 1; + new_time = M_ASN1_GENERALIZEDTIME_dup(gtime); + if (new_time == NULL) { + TSerr(TS_F_TS_TST_INFO_SET_TIME, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_GENERALIZEDTIME_free(a->time); + a->time = new_time; + return 1; +} + +const ASN1_GENERALIZEDTIME *TS_TST_INFO_get_time(const TS_TST_INFO *a) +{ + return a->time; +} + +int TS_TST_INFO_set_accuracy(TS_TST_INFO *a, TS_ACCURACY *accuracy) +{ + TS_ACCURACY *new_accuracy; + + if (a->accuracy == accuracy) + return 1; + new_accuracy = TS_ACCURACY_dup(accuracy); + if (new_accuracy == NULL) { + TSerr(TS_F_TS_TST_INFO_SET_ACCURACY, ERR_R_MALLOC_FAILURE); + return 0; + } + TS_ACCURACY_free(a->accuracy); + a->accuracy = new_accuracy; + return 1; +} + +TS_ACCURACY *TS_TST_INFO_get_accuracy(TS_TST_INFO *a) +{ + return a->accuracy; +} + +int TS_ACCURACY_set_seconds(TS_ACCURACY *a, const ASN1_INTEGER *seconds) +{ + ASN1_INTEGER *new_seconds; + + if (a->seconds == seconds) + return 1; + new_seconds = ASN1_INTEGER_dup(seconds); + if (new_seconds == NULL) { + TSerr(TS_F_TS_ACCURACY_SET_SECONDS, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->seconds); + a->seconds = new_seconds; + return 1; +} + +const ASN1_INTEGER *TS_ACCURACY_get_seconds(const TS_ACCURACY *a) +{ + return a->seconds; +} + +int TS_ACCURACY_set_millis(TS_ACCURACY *a, const ASN1_INTEGER *millis) +{ + ASN1_INTEGER *new_millis = NULL; + + if (a->millis == millis) + return 1; + if (millis != NULL) { + new_millis = ASN1_INTEGER_dup(millis); + if (new_millis == NULL) { + TSerr(TS_F_TS_ACCURACY_SET_MILLIS, ERR_R_MALLOC_FAILURE); + return 0; + } + } + ASN1_INTEGER_free(a->millis); + a->millis = new_millis; + return 1; +} + +const ASN1_INTEGER *TS_ACCURACY_get_millis(const TS_ACCURACY *a) +{ + return a->millis; +} + +int TS_ACCURACY_set_micros(TS_ACCURACY *a, const ASN1_INTEGER *micros) +{ + ASN1_INTEGER *new_micros = NULL; + + if (a->micros == micros) + return 1; + if (micros != NULL) { + new_micros = ASN1_INTEGER_dup(micros); + if (new_micros == NULL) { + TSerr(TS_F_TS_ACCURACY_SET_MICROS, ERR_R_MALLOC_FAILURE); + return 0; + } + } + ASN1_INTEGER_free(a->micros); + a->micros = new_micros; + return 1; +} + +const ASN1_INTEGER *TS_ACCURACY_get_micros(const TS_ACCURACY *a) +{ + return a->micros; +} + +int TS_TST_INFO_set_ordering(TS_TST_INFO *a, int ordering) +{ + a->ordering = ordering ? 0xFF : 0x00; + return 1; +} + +int TS_TST_INFO_get_ordering(const TS_TST_INFO *a) +{ + return a->ordering ? 1 : 0; +} + +int TS_TST_INFO_set_nonce(TS_TST_INFO *a, const ASN1_INTEGER *nonce) +{ + ASN1_INTEGER *new_nonce; + + if (a->nonce == nonce) + return 1; + new_nonce = ASN1_INTEGER_dup(nonce); + if (new_nonce == NULL) { + TSerr(TS_F_TS_TST_INFO_SET_NONCE, ERR_R_MALLOC_FAILURE); + return 0; + } + ASN1_INTEGER_free(a->nonce); + a->nonce = new_nonce; + return 1; +} + +const ASN1_INTEGER *TS_TST_INFO_get_nonce(const TS_TST_INFO *a) +{ + return a->nonce; +} + +int TS_TST_INFO_set_tsa(TS_TST_INFO *a, GENERAL_NAME *tsa) +{ + GENERAL_NAME *new_tsa; + + if (a->tsa == tsa) + return 1; + new_tsa = GENERAL_NAME_dup(tsa); + if (new_tsa == NULL) { + TSerr(TS_F_TS_TST_INFO_SET_TSA, ERR_R_MALLOC_FAILURE); + return 0; + } + GENERAL_NAME_free(a->tsa); + a->tsa = new_tsa; + return 1; +} + +GENERAL_NAME *TS_TST_INFO_get_tsa(TS_TST_INFO *a) +{ + return a->tsa; +} + +STACK_OF(X509_EXTENSION) *TS_TST_INFO_get_exts(TS_TST_INFO *a) +{ + return a->extensions; +} + +void TS_TST_INFO_ext_free(TS_TST_INFO *a) +{ + if (!a) + return; + sk_X509_EXTENSION_pop_free(a->extensions, X509_EXTENSION_free); + a->extensions = NULL; +} + +int TS_TST_INFO_get_ext_count(TS_TST_INFO *a) +{ + return X509v3_get_ext_count(a->extensions); +} + +int TS_TST_INFO_get_ext_by_NID(TS_TST_INFO *a, int nid, int lastpos) +{ + return X509v3_get_ext_by_NID(a->extensions, nid, lastpos); +} + +int TS_TST_INFO_get_ext_by_OBJ(TS_TST_INFO *a, ASN1_OBJECT *obj, int lastpos) +{ + return X509v3_get_ext_by_OBJ(a->extensions, obj, lastpos); +} + +int TS_TST_INFO_get_ext_by_critical(TS_TST_INFO *a, int crit, int lastpos) +{ + return X509v3_get_ext_by_critical(a->extensions, crit, lastpos); +} + +X509_EXTENSION *TS_TST_INFO_get_ext(TS_TST_INFO *a, int loc) +{ + return X509v3_get_ext(a->extensions, loc); +} + +X509_EXTENSION *TS_TST_INFO_delete_ext(TS_TST_INFO *a, int loc) +{ + return X509v3_delete_ext(a->extensions, loc); +} + +int TS_TST_INFO_add_ext(TS_TST_INFO *a, X509_EXTENSION *ex, int loc) +{ + return X509v3_add_ext(&a->extensions, ex, loc) != NULL; +} + +void *TS_TST_INFO_get_ext_d2i(TS_TST_INFO *a, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(a->extensions, nid, crit, idx); +} diff --git a/libs/openssl/crypto/ts/ts_rsp_verify.c b/libs/openssl/crypto/ts/ts_rsp_verify.c new file mode 100644 index 00000000..e24b2d53 --- /dev/null +++ b/libs/openssl/crypto/ts/ts_rsp_verify.c @@ -0,0 +1,737 @@ +/* crypto/ts/ts_resp_verify.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2002. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +/* Private function declarations. */ + +static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, + X509 *signer, STACK_OF(X509) **chain); +static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, + STACK_OF(X509) *chain); +static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si); +static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert); +static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo); +static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, + PKCS7 *token, TS_TST_INFO *tst_info); +static int TS_check_status_info(TS_RESP *response); +static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text); +static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info); +static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, + X509_ALGOR **md_alg, + unsigned char **imprint, unsigned *imprint_len); +static int TS_check_imprints(X509_ALGOR *algor_a, + unsigned char *imprint_a, unsigned len_a, + TS_TST_INFO *tst_info); +static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info); +static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer); +static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, + GENERAL_NAME *name); + +/* + * Local mapping between response codes and descriptions. + * Don't forget to change TS_STATUS_BUF_SIZE when modifying + * the elements of this array. + */ +static const char *TS_status_text[] = { "granted", + "grantedWithMods", + "rejection", + "waiting", + "revocationWarning", + "revocationNotification" +}; + +#define TS_STATUS_TEXT_SIZE (sizeof(TS_status_text)/sizeof(*TS_status_text)) + +/* + * This must be greater or equal to the sum of the strings in TS_status_text + * plus the number of its elements. + */ +#define TS_STATUS_BUF_SIZE 256 + +static struct { + int code; + const char *text; +} TS_failure_info[] = { + { + TS_INFO_BAD_ALG, "badAlg" + }, + { + TS_INFO_BAD_REQUEST, "badRequest" + }, + { + TS_INFO_BAD_DATA_FORMAT, "badDataFormat" + }, + { + TS_INFO_TIME_NOT_AVAILABLE, "timeNotAvailable" + }, + { + TS_INFO_UNACCEPTED_POLICY, "unacceptedPolicy" + }, + { + TS_INFO_UNACCEPTED_EXTENSION, "unacceptedExtension" + }, + { + TS_INFO_ADD_INFO_NOT_AVAILABLE, "addInfoNotAvailable" + }, + { + TS_INFO_SYSTEM_FAILURE, "systemFailure" + } +}; + +#define TS_FAILURE_INFO_SIZE (sizeof(TS_failure_info) / \ + sizeof(*TS_failure_info)) + +/* Functions for verifying a signed TS_TST_INFO structure. */ + +/*- + * This function carries out the following tasks: + * - Checks if there is one and only one signer. + * - Search for the signing certificate in 'certs' and in the response. + * - Check the extended key usage and key usage fields of the signer + * certificate (done by the path validation). + * - Build and validate the certificate path. + * - Check if the certificate path meets the requirements of the + * SigningCertificate ESS signed attribute. + * - Verify the signature value. + * - Returns the signer certificate in 'signer', if 'signer' is not NULL. + */ +int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs, + X509_STORE *store, X509 **signer_out) +{ + STACK_OF(PKCS7_SIGNER_INFO) *sinfos = NULL; + PKCS7_SIGNER_INFO *si; + STACK_OF(X509) *signers = NULL; + X509 *signer; + STACK_OF(X509) *chain = NULL; + char buf[4096]; + int i, j = 0, ret = 0; + BIO *p7bio = NULL; + + /* Some sanity checks first. */ + if (!token) { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_INVALID_NULL_POINTER); + goto err; + } + + /* Check for the correct content type */ + if (!PKCS7_type_is_signed(token)) { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_WRONG_CONTENT_TYPE); + goto err; + } + + /* Check if there is one and only one signer. */ + sinfos = PKCS7_get_signer_info(token); + if (!sinfos || sk_PKCS7_SIGNER_INFO_num(sinfos) != 1) { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_THERE_MUST_BE_ONE_SIGNER); + goto err; + } + si = sk_PKCS7_SIGNER_INFO_value(sinfos, 0); + + /* Check for no content: no data to verify signature. */ + if (PKCS7_get_detached(token)) { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_NO_CONTENT); + goto err; + } + + /* + * Get hold of the signer certificate, search only internal certificates + * if it was requested. + */ + signers = PKCS7_get0_signers(token, certs, 0); + if (!signers || sk_X509_num(signers) != 1) + goto err; + signer = sk_X509_value(signers, 0); + + /* Now verify the certificate. */ + if (!TS_verify_cert(store, certs, signer, &chain)) + goto err; + + /* + * Check if the signer certificate is consistent with the ESS extension. + */ + if (!TS_check_signing_certs(si, chain)) + goto err; + + /* Creating the message digest. */ + p7bio = PKCS7_dataInit(token, NULL); + + /* We now have to 'read' from p7bio to calculate digests etc. */ + while ((i = BIO_read(p7bio, buf, sizeof(buf))) > 0) ; + + /* Verifying the signature. */ + j = PKCS7_signatureVerify(p7bio, token, si, signer); + if (j <= 0) { + TSerr(TS_F_TS_RESP_VERIFY_SIGNATURE, TS_R_SIGNATURE_FAILURE); + goto err; + } + + /* Return the signer certificate if needed. */ + if (signer_out) { + *signer_out = signer; + CRYPTO_add(&signer->references, 1, CRYPTO_LOCK_X509); + } + + ret = 1; + + err: + BIO_free_all(p7bio); + sk_X509_pop_free(chain, X509_free); + sk_X509_free(signers); + + return ret; +} + +/* + * The certificate chain is returned in chain. Caller is responsible for + * freeing the vector. + */ +static int TS_verify_cert(X509_STORE *store, STACK_OF(X509) *untrusted, + X509 *signer, STACK_OF(X509) **chain) +{ + X509_STORE_CTX cert_ctx; + int i; + int ret = 1; + + /* chain is an out argument. */ + *chain = NULL; + if (!X509_STORE_CTX_init(&cert_ctx, store, signer, untrusted)) + return 0; + X509_STORE_CTX_set_purpose(&cert_ctx, X509_PURPOSE_TIMESTAMP_SIGN); + i = X509_verify_cert(&cert_ctx); + if (i <= 0) { + int j = X509_STORE_CTX_get_error(&cert_ctx); + TSerr(TS_F_TS_VERIFY_CERT, TS_R_CERTIFICATE_VERIFY_ERROR); + ERR_add_error_data(2, "Verify error:", + X509_verify_cert_error_string(j)); + ret = 0; + } else { + /* Get a copy of the certificate chain. */ + *chain = X509_STORE_CTX_get1_chain(&cert_ctx); + } + + X509_STORE_CTX_cleanup(&cert_ctx); + + return ret; +} + +static int TS_check_signing_certs(PKCS7_SIGNER_INFO *si, + STACK_OF(X509) *chain) +{ + ESS_SIGNING_CERT *ss = ESS_get_signing_cert(si); + STACK_OF(ESS_CERT_ID) *cert_ids = NULL; + X509 *cert; + int i = 0; + int ret = 0; + + if (!ss) + goto err; + cert_ids = ss->cert_ids; + /* The signer certificate must be the first in cert_ids. */ + cert = sk_X509_value(chain, 0); + if (TS_find_cert(cert_ids, cert) != 0) + goto err; + + /* + * Check the other certificates of the chain if there are more than one + * certificate ids in cert_ids. + */ + if (sk_ESS_CERT_ID_num(cert_ids) > 1) { + /* All the certificates of the chain must be in cert_ids. */ + for (i = 1; i < sk_X509_num(chain); ++i) { + cert = sk_X509_value(chain, i); + if (TS_find_cert(cert_ids, cert) < 0) + goto err; + } + } + ret = 1; + err: + if (!ret) + TSerr(TS_F_TS_CHECK_SIGNING_CERTS, + TS_R_ESS_SIGNING_CERTIFICATE_ERROR); + ESS_SIGNING_CERT_free(ss); + return ret; +} + +static ESS_SIGNING_CERT *ESS_get_signing_cert(PKCS7_SIGNER_INFO *si) +{ + ASN1_TYPE *attr; + const unsigned char *p; + attr = PKCS7_get_signed_attribute(si, NID_id_smime_aa_signingCertificate); + if (!attr) + return NULL; + p = attr->value.sequence->data; + return d2i_ESS_SIGNING_CERT(NULL, &p, attr->value.sequence->length); +} + +/* Returns < 0 if certificate is not found, certificate index otherwise. */ +static int TS_find_cert(STACK_OF(ESS_CERT_ID) *cert_ids, X509 *cert) +{ + int i; + + if (!cert_ids || !cert) + return -1; + + /* Recompute SHA1 hash of certificate if necessary (side effect). */ + X509_check_purpose(cert, -1, 0); + + /* Look for cert in the cert_ids vector. */ + for (i = 0; i < sk_ESS_CERT_ID_num(cert_ids); ++i) { + ESS_CERT_ID *cid = sk_ESS_CERT_ID_value(cert_ids, i); + + /* Check the SHA-1 hash first. */ + if (cid->hash->length == sizeof(cert->sha1_hash) + && !memcmp(cid->hash->data, cert->sha1_hash, + sizeof(cert->sha1_hash))) { + /* Check the issuer/serial as well if specified. */ + ESS_ISSUER_SERIAL *is = cid->issuer_serial; + if (!is || !TS_issuer_serial_cmp(is, cert->cert_info)) + return i; + } + } + + return -1; +} + +static int TS_issuer_serial_cmp(ESS_ISSUER_SERIAL *is, X509_CINF *cinfo) +{ + GENERAL_NAME *issuer; + + if (!is || !cinfo || sk_GENERAL_NAME_num(is->issuer) != 1) + return -1; + + /* Check the issuer first. It must be a directory name. */ + issuer = sk_GENERAL_NAME_value(is->issuer, 0); + if (issuer->type != GEN_DIRNAME + || X509_NAME_cmp(issuer->d.dirn, cinfo->issuer)) + return -1; + + /* Check the serial number, too. */ + if (ASN1_INTEGER_cmp(is->serial, cinfo->serialNumber)) + return -1; + + return 0; +} + +/*- + * Verifies whether 'response' contains a valid response with regards + * to the settings of the context: + * - Gives an error message if the TS_TST_INFO is not present. + * - Calls _TS_RESP_verify_token to verify the token content. + */ +int TS_RESP_verify_response(TS_VERIFY_CTX *ctx, TS_RESP *response) +{ + PKCS7 *token = TS_RESP_get_token(response); + TS_TST_INFO *tst_info = TS_RESP_get_tst_info(response); + int ret = 0; + + /* Check if we have a successful TS_TST_INFO object in place. */ + if (!TS_check_status_info(response)) + goto err; + + /* Check the contents of the time stamp token. */ + if (!int_TS_RESP_verify_token(ctx, token, tst_info)) + goto err; + + ret = 1; + err: + return ret; +} + +/* + * Tries to extract a TS_TST_INFO structure from the PKCS7 token and + * calls the internal int_TS_RESP_verify_token function for verifying it. + */ +int TS_RESP_verify_token(TS_VERIFY_CTX *ctx, PKCS7 *token) +{ + TS_TST_INFO *tst_info = PKCS7_to_TS_TST_INFO(token); + int ret = 0; + if (tst_info) { + ret = int_TS_RESP_verify_token(ctx, token, tst_info); + TS_TST_INFO_free(tst_info); + } + return ret; +} + +/*- + * Verifies whether the 'token' contains a valid time stamp token + * with regards to the settings of the context. Only those checks are + * carried out that are specified in the context: + * - Verifies the signature of the TS_TST_INFO. + * - Checks the version number of the response. + * - Check if the requested and returned policies math. + * - Check if the message imprints are the same. + * - Check if the nonces are the same. + * - Check if the TSA name matches the signer. + * - Check if the TSA name is the expected TSA. + */ +static int int_TS_RESP_verify_token(TS_VERIFY_CTX *ctx, + PKCS7 *token, TS_TST_INFO *tst_info) +{ + X509 *signer = NULL; + GENERAL_NAME *tsa_name = TS_TST_INFO_get_tsa(tst_info); + X509_ALGOR *md_alg = NULL; + unsigned char *imprint = NULL; + unsigned imprint_len = 0; + int ret = 0; + + /* Verify the signature. */ + if ((ctx->flags & TS_VFY_SIGNATURE) + && !TS_RESP_verify_signature(token, ctx->certs, ctx->store, &signer)) + goto err; + + /* Check version number of response. */ + if ((ctx->flags & TS_VFY_VERSION) + && TS_TST_INFO_get_version(tst_info) != 1) { + TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_UNSUPPORTED_VERSION); + goto err; + } + + /* Check policies. */ + if ((ctx->flags & TS_VFY_POLICY) + && !TS_check_policy(ctx->policy, tst_info)) + goto err; + + /* Check message imprints. */ + if ((ctx->flags & TS_VFY_IMPRINT) + && !TS_check_imprints(ctx->md_alg, ctx->imprint, ctx->imprint_len, + tst_info)) + goto err; + + /* Compute and check message imprints. */ + if ((ctx->flags & TS_VFY_DATA) + && (!TS_compute_imprint(ctx->data, tst_info, + &md_alg, &imprint, &imprint_len) + || !TS_check_imprints(md_alg, imprint, imprint_len, tst_info))) + goto err; + + /* Check nonces. */ + if ((ctx->flags & TS_VFY_NONCE) + && !TS_check_nonces(ctx->nonce, tst_info)) + goto err; + + /* Check whether TSA name and signer certificate match. */ + if ((ctx->flags & TS_VFY_SIGNER) + && tsa_name && !TS_check_signer_name(tsa_name, signer)) { + TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_NAME_MISMATCH); + goto err; + } + + /* Check whether the TSA is the expected one. */ + if ((ctx->flags & TS_VFY_TSA_NAME) + && !TS_check_signer_name(ctx->tsa_name, signer)) { + TSerr(TS_F_INT_TS_RESP_VERIFY_TOKEN, TS_R_TSA_UNTRUSTED); + goto err; + } + + ret = 1; + err: + X509_free(signer); + X509_ALGOR_free(md_alg); + OPENSSL_free(imprint); + return ret; +} + +static int TS_check_status_info(TS_RESP *response) +{ + TS_STATUS_INFO *info = TS_RESP_get_status_info(response); + long status = ASN1_INTEGER_get(info->status); + const char *status_text = NULL; + char *embedded_status_text = NULL; + char failure_text[TS_STATUS_BUF_SIZE] = ""; + + /* Check if everything went fine. */ + if (status == 0 || status == 1) + return 1; + + /* There was an error, get the description in status_text. */ + if (0 <= status && status < (long)TS_STATUS_TEXT_SIZE) + status_text = TS_status_text[status]; + else + status_text = "unknown code"; + + /* Set the embedded_status_text to the returned description. */ + if (sk_ASN1_UTF8STRING_num(info->text) > 0 + && !(embedded_status_text = TS_get_status_text(info->text))) + return 0; + + /* Filling in failure_text with the failure information. */ + if (info->failure_info) { + int i; + int first = 1; + for (i = 0; i < (int)TS_FAILURE_INFO_SIZE; ++i) { + if (ASN1_BIT_STRING_get_bit(info->failure_info, + TS_failure_info[i].code)) { + if (!first) + strcat(failure_text, ","); + else + first = 0; + strcat(failure_text, TS_failure_info[i].text); + } + } + } + if (failure_text[0] == '\0') + strcpy(failure_text, "unspecified"); + + /* Making up the error string. */ + TSerr(TS_F_TS_CHECK_STATUS_INFO, TS_R_NO_TIME_STAMP_TOKEN); + ERR_add_error_data(6, + "status code: ", status_text, + ", status text: ", embedded_status_text ? + embedded_status_text : "unspecified", + ", failure codes: ", failure_text); + OPENSSL_free(embedded_status_text); + + return 0; +} + +static char *TS_get_status_text(STACK_OF(ASN1_UTF8STRING) *text) +{ + int i; + unsigned int length = 0; + char *result = NULL; + char *p; + + /* Determine length first. */ + for (i = 0; i < sk_ASN1_UTF8STRING_num(text); ++i) { + ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); + length += ASN1_STRING_length(current); + length += 1; /* separator character */ + } + /* Allocate memory (closing '\0' included). */ + if (!(result = OPENSSL_malloc(length))) { + TSerr(TS_F_TS_GET_STATUS_TEXT, ERR_R_MALLOC_FAILURE); + return NULL; + } + /* Concatenate the descriptions. */ + for (i = 0, p = result; i < sk_ASN1_UTF8STRING_num(text); ++i) { + ASN1_UTF8STRING *current = sk_ASN1_UTF8STRING_value(text, i); + length = ASN1_STRING_length(current); + if (i > 0) + *p++ = '/'; + strncpy(p, (const char *)ASN1_STRING_data(current), length); + p += length; + } + /* We do have space for this, too. */ + *p = '\0'; + + return result; +} + +static int TS_check_policy(ASN1_OBJECT *req_oid, TS_TST_INFO *tst_info) +{ + ASN1_OBJECT *resp_oid = TS_TST_INFO_get_policy_id(tst_info); + + if (OBJ_cmp(req_oid, resp_oid) != 0) { + TSerr(TS_F_TS_CHECK_POLICY, TS_R_POLICY_MISMATCH); + return 0; + } + + return 1; +} + +static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, + X509_ALGOR **md_alg, + unsigned char **imprint, unsigned *imprint_len) +{ + TS_MSG_IMPRINT *msg_imprint = TS_TST_INFO_get_msg_imprint(tst_info); + X509_ALGOR *md_alg_resp = TS_MSG_IMPRINT_get_algo(msg_imprint); + const EVP_MD *md; + EVP_MD_CTX md_ctx; + unsigned char buffer[4096]; + int length; + + *md_alg = NULL; + *imprint = NULL; + + /* Return the MD algorithm of the response. */ + if (!(*md_alg = X509_ALGOR_dup(md_alg_resp))) + goto err; + + /* Getting the MD object. */ + if (!(md = EVP_get_digestbyobj((*md_alg)->algorithm))) { + TSerr(TS_F_TS_COMPUTE_IMPRINT, TS_R_UNSUPPORTED_MD_ALGORITHM); + goto err; + } + + /* Compute message digest. */ + length = EVP_MD_size(md); + if (length < 0) + goto err; + *imprint_len = length; + if (!(*imprint = OPENSSL_malloc(*imprint_len))) { + TSerr(TS_F_TS_COMPUTE_IMPRINT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestInit(&md_ctx, md)) + goto err; + while ((length = BIO_read(data, buffer, sizeof(buffer))) > 0) { + if (!EVP_DigestUpdate(&md_ctx, buffer, length)) + goto err; + } + if (!EVP_DigestFinal(&md_ctx, *imprint, NULL)) + goto err; + + return 1; + err: + X509_ALGOR_free(*md_alg); + OPENSSL_free(*imprint); + *imprint_len = 0; + *imprint = NULL; + return 0; +} + +static int TS_check_imprints(X509_ALGOR *algor_a, + unsigned char *imprint_a, unsigned len_a, + TS_TST_INFO *tst_info) +{ + TS_MSG_IMPRINT *b = TS_TST_INFO_get_msg_imprint(tst_info); + X509_ALGOR *algor_b = TS_MSG_IMPRINT_get_algo(b); + int ret = 0; + + /* algor_a is optional. */ + if (algor_a) { + /* Compare algorithm OIDs. */ + if (OBJ_cmp(algor_a->algorithm, algor_b->algorithm)) + goto err; + + /* The parameter must be NULL in both. */ + if ((algor_a->parameter + && ASN1_TYPE_get(algor_a->parameter) != V_ASN1_NULL) + || (algor_b->parameter + && ASN1_TYPE_get(algor_b->parameter) != V_ASN1_NULL)) + goto err; + } + + /* Compare octet strings. */ + ret = len_a == (unsigned)ASN1_STRING_length(b->hashed_msg) && + memcmp(imprint_a, ASN1_STRING_data(b->hashed_msg), len_a) == 0; + err: + if (!ret) + TSerr(TS_F_TS_CHECK_IMPRINTS, TS_R_MESSAGE_IMPRINT_MISMATCH); + return ret; +} + +static int TS_check_nonces(const ASN1_INTEGER *a, TS_TST_INFO *tst_info) +{ + const ASN1_INTEGER *b = TS_TST_INFO_get_nonce(tst_info); + + /* Error if nonce is missing. */ + if (!b) { + TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_NOT_RETURNED); + return 0; + } + + /* No error if a nonce is returned without being requested. */ + if (ASN1_INTEGER_cmp(a, b) != 0) { + TSerr(TS_F_TS_CHECK_NONCES, TS_R_NONCE_MISMATCH); + return 0; + } + + return 1; +} + +/* + * Check if the specified TSA name matches either the subject or one of the + * subject alternative names of the TSA certificate. + */ +static int TS_check_signer_name(GENERAL_NAME *tsa_name, X509 *signer) +{ + STACK_OF(GENERAL_NAME) *gen_names = NULL; + int idx = -1; + int found = 0; + + /* Check the subject name first. */ + if (tsa_name->type == GEN_DIRNAME + && X509_name_cmp(tsa_name->d.dirn, signer->cert_info->subject) == 0) + return 1; + + /* Check all the alternative names. */ + gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, NULL, &idx); + while (gen_names != NULL + && !(found = TS_find_name(gen_names, tsa_name) >= 0)) { + /* + * Get the next subject alternative name, although there should be no + * more than one. + */ + GENERAL_NAMES_free(gen_names); + gen_names = X509_get_ext_d2i(signer, NID_subject_alt_name, + NULL, &idx); + } + if (gen_names) + GENERAL_NAMES_free(gen_names); + + return found; +} + +/* Returns 1 if name is in gen_names, 0 otherwise. */ +static int TS_find_name(STACK_OF(GENERAL_NAME) *gen_names, GENERAL_NAME *name) +{ + int i, found; + for (i = 0, found = 0; !found && i < sk_GENERAL_NAME_num(gen_names); ++i) { + GENERAL_NAME *current = sk_GENERAL_NAME_value(gen_names, i); + found = GENERAL_NAME_cmp(current, name) == 0; + } + return found ? i - 1 : -1; +} diff --git a/libs/openssl/crypto/ts/ts_verify_ctx.c b/libs/openssl/crypto/ts/ts_verify_ctx.c new file mode 100644 index 00000000..3e6fcb57 --- /dev/null +++ b/libs/openssl/crypto/ts/ts_verify_ctx.c @@ -0,0 +1,162 @@ +/* crypto/ts/ts_verify_ctx.c */ +/* + * Written by Zoltan Glozik (zglozik@stones.com) for the OpenSSL project + * 2003. + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include +#include + +TS_VERIFY_CTX *TS_VERIFY_CTX_new(void) +{ + TS_VERIFY_CTX *ctx = + (TS_VERIFY_CTX *)OPENSSL_malloc(sizeof(TS_VERIFY_CTX)); + if (ctx) + memset(ctx, 0, sizeof(TS_VERIFY_CTX)); + else + TSerr(TS_F_TS_VERIFY_CTX_NEW, ERR_R_MALLOC_FAILURE); + return ctx; +} + +void TS_VERIFY_CTX_init(TS_VERIFY_CTX *ctx) +{ + OPENSSL_assert(ctx != NULL); + memset(ctx, 0, sizeof(TS_VERIFY_CTX)); +} + +void TS_VERIFY_CTX_free(TS_VERIFY_CTX *ctx) +{ + if (!ctx) + return; + + TS_VERIFY_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +void TS_VERIFY_CTX_cleanup(TS_VERIFY_CTX *ctx) +{ + if (!ctx) + return; + + X509_STORE_free(ctx->store); + sk_X509_pop_free(ctx->certs, X509_free); + + ASN1_OBJECT_free(ctx->policy); + + X509_ALGOR_free(ctx->md_alg); + OPENSSL_free(ctx->imprint); + + BIO_free_all(ctx->data); + + ASN1_INTEGER_free(ctx->nonce); + + GENERAL_NAME_free(ctx->tsa_name); + + TS_VERIFY_CTX_init(ctx); +} + +TS_VERIFY_CTX *TS_REQ_to_TS_VERIFY_CTX(TS_REQ *req, TS_VERIFY_CTX *ctx) +{ + TS_VERIFY_CTX *ret = ctx; + ASN1_OBJECT *policy; + TS_MSG_IMPRINT *imprint; + X509_ALGOR *md_alg; + ASN1_OCTET_STRING *msg; + const ASN1_INTEGER *nonce; + + OPENSSL_assert(req != NULL); + if (ret) + TS_VERIFY_CTX_cleanup(ret); + else if (!(ret = TS_VERIFY_CTX_new())) + return NULL; + + /* Setting flags. */ + ret->flags = TS_VFY_ALL_IMPRINT & ~(TS_VFY_TSA_NAME | TS_VFY_SIGNATURE); + + /* Setting policy. */ + if ((policy = TS_REQ_get_policy_id(req)) != NULL) { + if (!(ret->policy = OBJ_dup(policy))) + goto err; + } else + ret->flags &= ~TS_VFY_POLICY; + + /* Setting md_alg, imprint and imprint_len. */ + imprint = TS_REQ_get_msg_imprint(req); + md_alg = TS_MSG_IMPRINT_get_algo(imprint); + if (!(ret->md_alg = X509_ALGOR_dup(md_alg))) + goto err; + msg = TS_MSG_IMPRINT_get_msg(imprint); + ret->imprint_len = ASN1_STRING_length(msg); + if (!(ret->imprint = OPENSSL_malloc(ret->imprint_len))) + goto err; + memcpy(ret->imprint, ASN1_STRING_data(msg), ret->imprint_len); + + /* Setting nonce. */ + if ((nonce = TS_REQ_get_nonce(req)) != NULL) { + if (!(ret->nonce = ASN1_INTEGER_dup(nonce))) + goto err; + } else + ret->flags &= ~TS_VFY_NONCE; + + return ret; + err: + if (ctx) + TS_VERIFY_CTX_cleanup(ctx); + else + TS_VERIFY_CTX_free(ret); + return NULL; +} diff --git a/libs/openssl/crypto/txt_db/txt_db.c b/libs/openssl/crypto/txt_db/txt_db.c new file mode 100644 index 00000000..f9b42ac6 --- /dev/null +++ b/libs/openssl/crypto/txt_db/txt_db.c @@ -0,0 +1,381 @@ +/* crypto/txt_db/txt_db.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include "cryptlib.h" +#include +#include + +#undef BUFSIZE +#define BUFSIZE 512 + +const char TXT_DB_version[] = "TXT_DB" OPENSSL_VERSION_PTEXT; + +TXT_DB *TXT_DB_read(BIO *in, int num) +{ + TXT_DB *ret = NULL; + int er = 1; + int esc = 0; + long ln = 0; + int i, add, n; + int size = BUFSIZE; + int offset = 0; + char *p, *f; + OPENSSL_STRING *pp; + BUF_MEM *buf = NULL; + + if ((buf = BUF_MEM_new()) == NULL) + goto err; + if (!BUF_MEM_grow(buf, size)) + goto err; + + if ((ret = OPENSSL_malloc(sizeof(TXT_DB))) == NULL) + goto err; + ret->num_fields = num; + ret->index = NULL; + ret->qual = NULL; + if ((ret->data = sk_OPENSSL_PSTRING_new_null()) == NULL) + goto err; + if ((ret->index = OPENSSL_malloc(sizeof(*ret->index) * num)) == NULL) + goto err; + if ((ret->qual = OPENSSL_malloc(sizeof(*(ret->qual)) * num)) == NULL) + goto err; + for (i = 0; i < num; i++) { + ret->index[i] = NULL; + ret->qual[i] = NULL; + } + + add = (num + 1) * sizeof(char *); + buf->data[size - 1] = '\0'; + offset = 0; + for (;;) { + if (offset != 0) { + size += BUFSIZE; + if (!BUF_MEM_grow_clean(buf, size)) + goto err; + } + buf->data[offset] = '\0'; + BIO_gets(in, &(buf->data[offset]), size - offset); + ln++; + if (buf->data[offset] == '\0') + break; + if ((offset == 0) && (buf->data[0] == '#')) + continue; + i = strlen(&(buf->data[offset])); + offset += i; + if (buf->data[offset - 1] != '\n') + continue; + else { + buf->data[offset - 1] = '\0'; /* blat the '\n' */ + if (!(p = OPENSSL_malloc(add + offset))) + goto err; + offset = 0; + } + pp = (char **)p; + p += add; + n = 0; + pp[n++] = p; + i = 0; + f = buf->data; + + esc = 0; + for (;;) { + if (*f == '\0') + break; + if (*f == '\t') { + if (esc) + p--; + else { + *(p++) = '\0'; + f++; + if (n >= num) + break; + pp[n++] = p; + continue; + } + } + esc = (*f == '\\'); + *(p++) = *(f++); + } + *(p++) = '\0'; + if ((n != num) || (*f != '\0')) { +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporary + * fix :-( */ + fprintf(stderr, + "wrong number of fields on line %ld (looking for field %d, got %d, '%s' left)\n", + ln, num, n, f); +#endif + er = 2; + goto err; + } + pp[n] = p; + if (!sk_OPENSSL_PSTRING_push(ret->data, pp)) { +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) /* temporary + * fix :-( */ + fprintf(stderr, "failure in sk_push\n"); +#endif + er = 2; + goto err; + } + } + er = 0; + err: + BUF_MEM_free(buf); + if (er) { +#if !defined(OPENSSL_NO_STDIO) && !defined(OPENSSL_SYS_WIN16) + if (er == 1) + fprintf(stderr, "OPENSSL_malloc failure\n"); +#endif + if (ret != NULL) { + if (ret->data != NULL) + sk_OPENSSL_PSTRING_free(ret->data); + if (ret->index != NULL) + OPENSSL_free(ret->index); + if (ret->qual != NULL) + OPENSSL_free(ret->qual); + if (ret != NULL) + OPENSSL_free(ret); + } + return (NULL); + } else + return (ret); +} + +OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, + OPENSSL_STRING *value) +{ + OPENSSL_STRING *ret; + LHASH_OF(OPENSSL_STRING) *lh; + + if (idx >= db->num_fields) { + db->error = DB_ERROR_INDEX_OUT_OF_RANGE; + return (NULL); + } + lh = db->index[idx]; + if (lh == NULL) { + db->error = DB_ERROR_NO_INDEX; + return (NULL); + } + ret = lh_OPENSSL_STRING_retrieve(lh, value); + db->error = DB_ERROR_OK; + return (ret); +} + +int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), + LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp) +{ + LHASH_OF(OPENSSL_STRING) *idx; + OPENSSL_STRING *r; + int i, n; + + if (field >= db->num_fields) { + db->error = DB_ERROR_INDEX_OUT_OF_RANGE; + return (0); + } + /* FIXME: we lose type checking at this point */ + if ((idx = (LHASH_OF(OPENSSL_STRING) *)lh_new(hash, cmp)) == NULL) { + db->error = DB_ERROR_MALLOC; + return (0); + } + n = sk_OPENSSL_PSTRING_num(db->data); + for (i = 0; i < n; i++) { + r = sk_OPENSSL_PSTRING_value(db->data, i); + if ((qual != NULL) && (qual(r) == 0)) + continue; + if ((r = lh_OPENSSL_STRING_insert(idx, r)) != NULL) { + db->error = DB_ERROR_INDEX_CLASH; + db->arg1 = sk_OPENSSL_PSTRING_find(db->data, r); + db->arg2 = i; + lh_OPENSSL_STRING_free(idx); + return (0); + } + } + if (db->index[field] != NULL) + lh_OPENSSL_STRING_free(db->index[field]); + db->index[field] = idx; + db->qual[field] = qual; + return (1); +} + +long TXT_DB_write(BIO *out, TXT_DB *db) +{ + long i, j, n, nn, l, tot = 0; + char *p, **pp, *f; + BUF_MEM *buf = NULL; + long ret = -1; + + if ((buf = BUF_MEM_new()) == NULL) + goto err; + n = sk_OPENSSL_PSTRING_num(db->data); + nn = db->num_fields; + for (i = 0; i < n; i++) { + pp = sk_OPENSSL_PSTRING_value(db->data, i); + + l = 0; + for (j = 0; j < nn; j++) { + if (pp[j] != NULL) + l += strlen(pp[j]); + } + if (!BUF_MEM_grow_clean(buf, (int)(l * 2 + nn))) + goto err; + + p = buf->data; + for (j = 0; j < nn; j++) { + f = pp[j]; + if (f != NULL) + for (;;) { + if (*f == '\0') + break; + if (*f == '\t') + *(p++) = '\\'; + *(p++) = *(f++); + } + *(p++) = '\t'; + } + p[-1] = '\n'; + j = p - buf->data; + if (BIO_write(out, buf->data, (int)j) != j) + goto err; + tot += j; + } + ret = tot; + err: + if (buf != NULL) + BUF_MEM_free(buf); + return (ret); +} + +int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *row) +{ + int i; + OPENSSL_STRING *r; + + for (i = 0; i < db->num_fields; i++) { + if (db->index[i] != NULL) { + if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0)) + continue; + r = lh_OPENSSL_STRING_retrieve(db->index[i], row); + if (r != NULL) { + db->error = DB_ERROR_INDEX_CLASH; + db->arg1 = i; + db->arg_row = r; + goto err; + } + } + } + /* We have passed the index checks, now just append and insert */ + if (!sk_OPENSSL_PSTRING_push(db->data, row)) { + db->error = DB_ERROR_MALLOC; + goto err; + } + + for (i = 0; i < db->num_fields; i++) { + if (db->index[i] != NULL) { + if ((db->qual[i] != NULL) && (db->qual[i] (row) == 0)) + continue; + (void)lh_OPENSSL_STRING_insert(db->index[i], row); + } + } + return (1); + err: + return (0); +} + +void TXT_DB_free(TXT_DB *db) +{ + int i, n; + char **p, *max; + + if (db == NULL) + return; + + if (db->index != NULL) { + for (i = db->num_fields - 1; i >= 0; i--) + if (db->index[i] != NULL) + lh_OPENSSL_STRING_free(db->index[i]); + OPENSSL_free(db->index); + } + if (db->qual != NULL) + OPENSSL_free(db->qual); + if (db->data != NULL) { + for (i = sk_OPENSSL_PSTRING_num(db->data) - 1; i >= 0; i--) { + /* + * check if any 'fields' have been allocated from outside of the + * initial block + */ + p = sk_OPENSSL_PSTRING_value(db->data, i); + max = p[db->num_fields]; /* last address */ + if (max == NULL) { /* new row */ + for (n = 0; n < db->num_fields; n++) + if (p[n] != NULL) + OPENSSL_free(p[n]); + } else { + for (n = 0; n < db->num_fields; n++) { + if (((p[n] < (char *)p) || (p[n] > max)) + && (p[n] != NULL)) + OPENSSL_free(p[n]); + } + } + OPENSSL_free(sk_OPENSSL_PSTRING_value(db->data, i)); + } + sk_OPENSSL_PSTRING_free(db->data); + } + OPENSSL_free(db); +} diff --git a/libs/openssl/crypto/txt_db/txt_db.h b/libs/openssl/crypto/txt_db/txt_db.h new file mode 100644 index 00000000..98e23a20 --- /dev/null +++ b/libs/openssl/crypto/txt_db/txt_db.h @@ -0,0 +1,112 @@ +/* crypto/txt_db/txt_db.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_TXT_DB_H +# define HEADER_TXT_DB_H + +# include +# ifndef OPENSSL_NO_BIO +# include +# endif +# include +# include + +# define DB_ERROR_OK 0 +# define DB_ERROR_MALLOC 1 +# define DB_ERROR_INDEX_CLASH 2 +# define DB_ERROR_INDEX_OUT_OF_RANGE 3 +# define DB_ERROR_NO_INDEX 4 +# define DB_ERROR_INSERT_INDEX_CLASH 5 + +#ifdef __cplusplus +extern "C" { +#endif + +typedef OPENSSL_STRING *OPENSSL_PSTRING; +DECLARE_SPECIAL_STACK_OF(OPENSSL_PSTRING, OPENSSL_STRING) + +typedef struct txt_db_st { + int num_fields; + STACK_OF(OPENSSL_PSTRING) *data; + LHASH_OF(OPENSSL_STRING) **index; + int (**qual) (OPENSSL_STRING *); + long error; + long arg1; + long arg2; + OPENSSL_STRING *arg_row; +} TXT_DB; + +# ifndef OPENSSL_NO_BIO +TXT_DB *TXT_DB_read(BIO *in, int num); +long TXT_DB_write(BIO *out, TXT_DB *db); +# else +TXT_DB *TXT_DB_read(char *in, int num); +long TXT_DB_write(char *out, TXT_DB *db); +# endif +int TXT_DB_create_index(TXT_DB *db, int field, int (*qual) (OPENSSL_STRING *), + LHASH_HASH_FN_TYPE hash, LHASH_COMP_FN_TYPE cmp); +void TXT_DB_free(TXT_DB *db); +OPENSSL_STRING *TXT_DB_get_by_index(TXT_DB *db, int idx, + OPENSSL_STRING *value); +int TXT_DB_insert(TXT_DB *db, OPENSSL_STRING *value); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/ui/ui.h b/libs/openssl/crypto/ui/ui.h new file mode 100644 index 00000000..0dc16330 --- /dev/null +++ b/libs/openssl/crypto/ui/ui.h @@ -0,0 +1,415 @@ +/* crypto/ui/ui.h */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_UI_H +# define HEADER_UI_H + +# ifndef OPENSSL_NO_DEPRECATED +# include +# endif +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Declared already in ossl_typ.h */ +/* typedef struct ui_st UI; */ +/* typedef struct ui_method_st UI_METHOD; */ + +/* + * All the following functions return -1 or NULL on error and in some cases + * (UI_process()) -2 if interrupted or in some other way cancelled. When + * everything is fine, they return 0, a positive value or a non-NULL pointer, + * all depending on their purpose. + */ + +/* Creators and destructor. */ +UI *UI_new(void); +UI *UI_new_method(const UI_METHOD *method); +void UI_free(UI *ui); + +/*- + The following functions are used to add strings to be printed and prompt + strings to prompt for data. The names are UI_{add,dup}__string + and UI_{add,dup}_input_boolean. + + UI_{add,dup}__string have the following meanings: + add add a text or prompt string. The pointers given to these + functions are used verbatim, no copying is done. + dup make a copy of the text or prompt string, then add the copy + to the collection of strings in the user interface. + + The function is a name for the functionality that the given + string shall be used for. It can be one of: + input use the string as data prompt. + verify use the string as verification prompt. This + is used to verify a previous input. + info use the string for informational output. + error use the string for error output. + Honestly, there's currently no difference between info and error for the + moment. + + UI_{add,dup}_input_boolean have the same semantics for "add" and "dup", + and are typically used when one wants to prompt for a yes/no response. + + All of the functions in this group take a UI and a prompt string. + The string input and verify addition functions also take a flag argument, + a buffer for the result to end up with, a minimum input size and a maximum + input size (the result buffer MUST be large enough to be able to contain + the maximum number of characters). Additionally, the verify addition + functions takes another buffer to compare the result against. + The boolean input functions take an action description string (which should + be safe to ignore if the expected user action is obvious, for example with + a dialog box with an OK button and a Cancel button), a string of acceptable + characters to mean OK and to mean Cancel. The two last strings are checked + to make sure they don't have common characters. Additionally, the same + flag argument as for the string input is taken, as well as a result buffer. + The result buffer is required to be at least one byte long. Depending on + the answer, the first character from the OK or the Cancel character strings + will be stored in the first byte of the result buffer. No NUL will be + added, so the result is *not* a string. + + On success, the all return an index of the added information. That index + is usefull when retrieving results with UI_get0_result(). */ +int UI_add_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_dup_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize); +int UI_add_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf); +int UI_dup_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf); +int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf); +int UI_add_info_string(UI *ui, const char *text); +int UI_dup_info_string(UI *ui, const char *text); +int UI_add_error_string(UI *ui, const char *text); +int UI_dup_error_string(UI *ui, const char *text); + +/* These are the possible flags. They can be or'ed together. */ +/* Use to have echoing of input */ +# define UI_INPUT_FLAG_ECHO 0x01 +/* + * Use a default password. Where that password is found is completely up to + * the application, it might for example be in the user data set with + * UI_add_user_data(). It is not recommended to have more than one input in + * each UI being marked with this flag, or the application might get + * confused. + */ +# define UI_INPUT_FLAG_DEFAULT_PWD 0x02 + +/*- + * The user of these routines may want to define flags of their own. The core + * UI won't look at those, but will pass them on to the method routines. They + * must use higher bits so they don't get confused with the UI bits above. + * UI_INPUT_FLAG_USER_BASE tells which is the lowest bit to use. A good + * example of use is this: + * + * #define MY_UI_FLAG1 (0x01 << UI_INPUT_FLAG_USER_BASE) + * +*/ +# define UI_INPUT_FLAG_USER_BASE 16 + +/*- + * The following function helps construct a prompt. object_desc is a + * textual short description of the object, for example "pass phrase", + * and object_name is the name of the object (might be a card name or + * a file name. + * The returned string shall always be allocated on the heap with + * OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). + * + * If the ui_method doesn't contain a pointer to a user-defined prompt + * constructor, a default string is built, looking like this: + * + * "Enter {object_desc} for {object_name}:" + * + * So, if object_desc has the value "pass phrase" and object_name has + * the value "foo.key", the resulting string is: + * + * "Enter pass phrase for foo.key:" +*/ +char *UI_construct_prompt(UI *ui_method, + const char *object_desc, const char *object_name); + +/* + * The following function is used to store a pointer to user-specific data. + * Any previous such pointer will be returned and replaced. + * + * For callback purposes, this function makes a lot more sense than using + * ex_data, since the latter requires that different parts of OpenSSL or + * applications share the same ex_data index. + * + * Note that the UI_OpenSSL() method completely ignores the user data. Other + * methods may not, however. + */ +void *UI_add_user_data(UI *ui, void *user_data); +/* We need a user data retrieving function as well. */ +void *UI_get0_user_data(UI *ui); + +/* Return the result associated with a prompt given with the index i. */ +const char *UI_get0_result(UI *ui, int i); + +/* When all strings have been added, process the whole thing. */ +int UI_process(UI *ui); + +/* + * Give a user interface parametrised control commands. This can be used to + * send down an integer, a data pointer or a function pointer, as well as be + * used to get information from a UI. + */ +int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void)); + +/* The commands */ +/* + * Use UI_CONTROL_PRINT_ERRORS with the value 1 to have UI_process print the + * OpenSSL error stack before printing any info or added error messages and + * before any prompting. + */ +# define UI_CTRL_PRINT_ERRORS 1 +/* + * Check if a UI_process() is possible to do again with the same instance of + * a user interface. This makes UI_ctrl() return 1 if it is redoable, and 0 + * if not. + */ +# define UI_CTRL_IS_REDOABLE 2 + +/* Some methods may use extra data */ +# define UI_set_app_data(s,arg) UI_set_ex_data(s,0,arg) +# define UI_get_app_data(s) UI_get_ex_data(s,0) +int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int UI_set_ex_data(UI *r, int idx, void *arg); +void *UI_get_ex_data(UI *r, int idx); + +/* Use specific methods instead of the built-in one */ +void UI_set_default_method(const UI_METHOD *meth); +const UI_METHOD *UI_get_default_method(void); +const UI_METHOD *UI_get_method(UI *ui); +const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth); + +/* The method with all the built-in thingies */ +UI_METHOD *UI_OpenSSL(void); + +/* ---------- For method writers ---------- */ +/*- + A method contains a number of functions that implement the low level + of the User Interface. The functions are: + + an opener This function starts a session, maybe by opening + a channel to a tty, or by opening a window. + a writer This function is called to write a given string, + maybe to the tty, maybe as a field label in a + window. + a flusher This function is called to flush everything that + has been output so far. It can be used to actually + display a dialog box after it has been built. + a reader This function is called to read a given prompt, + maybe from the tty, maybe from a field in a + window. Note that it's called wth all string + structures, not only the prompt ones, so it must + check such things itself. + a closer This function closes the session, maybe by closing + the channel to the tty, or closing the window. + + All these functions are expected to return: + + 0 on error. + 1 on success. + -1 on out-of-band events, for example if some prompting has + been canceled (by pressing Ctrl-C, for example). This is + only checked when returned by the flusher or the reader. + + The way this is used, the opener is first called, then the writer for all + strings, then the flusher, then the reader for all strings and finally the + closer. Note that if you want to prompt from a terminal or other command + line interface, the best is to have the reader also write the prompts + instead of having the writer do it. If you want to prompt from a dialog + box, the writer can be used to build up the contents of the box, and the + flusher to actually display the box and run the event loop until all data + has been given, after which the reader only grabs the given data and puts + them back into the UI strings. + + All method functions take a UI as argument. Additionally, the writer and + the reader take a UI_STRING. +*/ + +/* + * The UI_STRING type is the data structure that contains all the needed info + * about a string or a prompt, including test data for a verification prompt. + */ +typedef struct ui_string_st UI_STRING; +DECLARE_STACK_OF(UI_STRING) + +/* + * The different types of strings that are currently supported. This is only + * needed by method authors. + */ +enum UI_string_types { + UIT_NONE = 0, + UIT_PROMPT, /* Prompt for a string */ + UIT_VERIFY, /* Prompt for a string and verify */ + UIT_BOOLEAN, /* Prompt for a yes/no response */ + UIT_INFO, /* Send info to the user */ + UIT_ERROR /* Send an error message to the user */ +}; + +/* Create and manipulate methods */ +UI_METHOD *UI_create_method(char *name); +void UI_destroy_method(UI_METHOD *ui_method); +int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui)); +int UI_method_set_writer(UI_METHOD *method, + int (*writer) (UI *ui, UI_STRING *uis)); +int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui)); +int UI_method_set_reader(UI_METHOD *method, + int (*reader) (UI *ui, UI_STRING *uis)); +int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui)); +int UI_method_set_prompt_constructor(UI_METHOD *method, + char *(*prompt_constructor) (UI *ui, + const char + *object_desc, + const char + *object_name)); +int (*UI_method_get_opener(UI_METHOD *method)) (UI *); +int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *); +int (*UI_method_get_flusher(UI_METHOD *method)) (UI *); +int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *); +int (*UI_method_get_closer(UI_METHOD *method)) (UI *); +char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *, + const char *, + const char *); + +/* + * The following functions are helpers for method writers to access relevant + * data from a UI_STRING. + */ + +/* Return type of the UI_STRING */ +enum UI_string_types UI_get_string_type(UI_STRING *uis); +/* Return input flags of the UI_STRING */ +int UI_get_input_flags(UI_STRING *uis); +/* Return the actual string to output (the prompt, info or error) */ +const char *UI_get0_output_string(UI_STRING *uis); +/* + * Return the optional action string to output (the boolean promtp + * instruction) + */ +const char *UI_get0_action_string(UI_STRING *uis); +/* Return the result of a prompt */ +const char *UI_get0_result_string(UI_STRING *uis); +/* + * Return the string to test the result against. Only useful with verifies. + */ +const char *UI_get0_test_string(UI_STRING *uis); +/* Return the required minimum size of the result */ +int UI_get_result_minsize(UI_STRING *uis); +/* Return the required maximum size of the result */ +int UI_get_result_maxsize(UI_STRING *uis); +/* Set the result of a UI_STRING. */ +int UI_set_result(UI *ui, UI_STRING *uis, const char *result); + +/* A couple of popular utility functions */ +int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, + int verify); +int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_UI_strings(void); + +/* Error codes for the UI functions. */ + +/* Function codes. */ +# define UI_F_GENERAL_ALLOCATE_BOOLEAN 108 +# define UI_F_GENERAL_ALLOCATE_PROMPT 109 +# define UI_F_GENERAL_ALLOCATE_STRING 100 +# define UI_F_UI_CTRL 111 +# define UI_F_UI_DUP_ERROR_STRING 101 +# define UI_F_UI_DUP_INFO_STRING 102 +# define UI_F_UI_DUP_INPUT_BOOLEAN 110 +# define UI_F_UI_DUP_INPUT_STRING 103 +# define UI_F_UI_DUP_VERIFY_STRING 106 +# define UI_F_UI_GET0_RESULT 107 +# define UI_F_UI_NEW_METHOD 104 +# define UI_F_UI_SET_RESULT 105 + +/* Reason codes. */ +# define UI_R_COMMON_OK_AND_CANCEL_CHARACTERS 104 +# define UI_R_INDEX_TOO_LARGE 102 +# define UI_R_INDEX_TOO_SMALL 103 +# define UI_R_NO_RESULT_BUFFER 105 +# define UI_R_RESULT_TOO_LARGE 100 +# define UI_R_RESULT_TOO_SMALL 101 +# define UI_R_UNKNOWN_CONTROL_COMMAND 106 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/ui/ui_compat.c b/libs/openssl/crypto/ui/ui_compat.c new file mode 100644 index 00000000..e79d54ee --- /dev/null +++ b/libs/openssl/crypto/ui/ui_compat.c @@ -0,0 +1,69 @@ +/* crypto/ui/ui_compat.c */ +/* ==================================================================== + * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +int _ossl_old_des_read_pw_string(char *buf, int length, const char *prompt, + int verify) +{ + return UI_UTIL_read_pw_string(buf, length, prompt, verify); +} + +int _ossl_old_des_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify) +{ + return UI_UTIL_read_pw(buf, buff, size, prompt, verify); +} diff --git a/libs/openssl/crypto/ui/ui_compat.h b/libs/openssl/crypto/ui/ui_compat.h new file mode 100644 index 00000000..bf541542 --- /dev/null +++ b/libs/openssl/crypto/ui/ui_compat.h @@ -0,0 +1,88 @@ +/* crypto/ui/ui.h */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_UI_COMPAT_H +# define HEADER_UI_COMPAT_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following functions were previously part of the DES section, and are + * provided here for backward compatibility reasons. + */ + +# define des_read_pw_string(b,l,p,v) \ + _ossl_old_des_read_pw_string((b),(l),(p),(v)) +# define des_read_pw(b,bf,s,p,v) \ + _ossl_old_des_read_pw((b),(bf),(s),(p),(v)) + +int _ossl_old_des_read_pw_string(char *buf, int length, const char *prompt, + int verify); +int _ossl_old_des_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/ui/ui_err.c b/libs/openssl/crypto/ui/ui_err.c new file mode 100644 index 00000000..8097da83 --- /dev/null +++ b/libs/openssl/crypto/ui/ui_err.c @@ -0,0 +1,111 @@ +/* crypto/ui/ui_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_UI,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_UI,0,reason) + +static ERR_STRING_DATA UI_str_functs[] = { + {ERR_FUNC(UI_F_GENERAL_ALLOCATE_BOOLEAN), "GENERAL_ALLOCATE_BOOLEAN"}, + {ERR_FUNC(UI_F_GENERAL_ALLOCATE_PROMPT), "GENERAL_ALLOCATE_PROMPT"}, + {ERR_FUNC(UI_F_GENERAL_ALLOCATE_STRING), "GENERAL_ALLOCATE_STRING"}, + {ERR_FUNC(UI_F_UI_CTRL), "UI_ctrl"}, + {ERR_FUNC(UI_F_UI_DUP_ERROR_STRING), "UI_dup_error_string"}, + {ERR_FUNC(UI_F_UI_DUP_INFO_STRING), "UI_dup_info_string"}, + {ERR_FUNC(UI_F_UI_DUP_INPUT_BOOLEAN), "UI_dup_input_boolean"}, + {ERR_FUNC(UI_F_UI_DUP_INPUT_STRING), "UI_dup_input_string"}, + {ERR_FUNC(UI_F_UI_DUP_VERIFY_STRING), "UI_dup_verify_string"}, + {ERR_FUNC(UI_F_UI_GET0_RESULT), "UI_get0_result"}, + {ERR_FUNC(UI_F_UI_NEW_METHOD), "UI_new_method"}, + {ERR_FUNC(UI_F_UI_SET_RESULT), "UI_set_result"}, + {0, NULL} +}; + +static ERR_STRING_DATA UI_str_reasons[] = { + {ERR_REASON(UI_R_COMMON_OK_AND_CANCEL_CHARACTERS), + "common ok and cancel characters"}, + {ERR_REASON(UI_R_INDEX_TOO_LARGE), "index too large"}, + {ERR_REASON(UI_R_INDEX_TOO_SMALL), "index too small"}, + {ERR_REASON(UI_R_NO_RESULT_BUFFER), "no result buffer"}, + {ERR_REASON(UI_R_RESULT_TOO_LARGE), "result too large"}, + {ERR_REASON(UI_R_RESULT_TOO_SMALL), "result too small"}, + {ERR_REASON(UI_R_UNKNOWN_CONTROL_COMMAND), "unknown control command"}, + {0, NULL} +}; + +#endif + +void ERR_load_UI_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(UI_str_functs[0].error) == NULL) { + ERR_load_strings(0, UI_str_functs); + ERR_load_strings(0, UI_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/ui/ui_lib.c b/libs/openssl/crypto/ui/ui_lib.c new file mode 100644 index 00000000..2f580352 --- /dev/null +++ b/libs/openssl/crypto/ui/ui_lib.c @@ -0,0 +1,870 @@ +/* crypto/ui/ui_lib.c */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include "ui_locl.h" + +IMPLEMENT_STACK_OF(UI_STRING_ST) + +static const UI_METHOD *default_UI_meth = NULL; + +UI *UI_new(void) +{ + return (UI_new_method(NULL)); +} + +UI *UI_new_method(const UI_METHOD *method) +{ + UI *ret; + + ret = (UI *)OPENSSL_malloc(sizeof(UI)); + if (ret == NULL) { + UIerr(UI_F_UI_NEW_METHOD, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (method == NULL) + ret->meth = UI_get_default_method(); + else + ret->meth = method; + + ret->strings = NULL; + ret->user_data = NULL; + ret->flags = 0; + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_UI, ret, &ret->ex_data); + return ret; +} + +static void free_string(UI_STRING *uis) +{ + if (uis->flags & OUT_STRING_FREEABLE) { + OPENSSL_free((char *)uis->out_string); + switch (uis->type) { + case UIT_BOOLEAN: + OPENSSL_free((char *)uis->_.boolean_data.action_desc); + OPENSSL_free((char *)uis->_.boolean_data.ok_chars); + OPENSSL_free((char *)uis->_.boolean_data.cancel_chars); + break; + default: + break; + } + } + OPENSSL_free(uis); +} + +void UI_free(UI *ui) +{ + if (ui == NULL) + return; + sk_UI_STRING_pop_free(ui->strings, free_string); + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_UI, ui, &ui->ex_data); + OPENSSL_free(ui); +} + +static int allocate_string_stack(UI *ui) +{ + if (ui->strings == NULL) { + ui->strings = sk_UI_STRING_new_null(); + if (ui->strings == NULL) { + return -1; + } + } + return 0; +} + +static UI_STRING *general_allocate_prompt(UI *ui, const char *prompt, + int prompt_freeable, + enum UI_string_types type, + int input_flags, char *result_buf) +{ + UI_STRING *ret = NULL; + + if (prompt == NULL) { + UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, ERR_R_PASSED_NULL_PARAMETER); + } else if ((type == UIT_PROMPT || type == UIT_VERIFY + || type == UIT_BOOLEAN) && result_buf == NULL) { + UIerr(UI_F_GENERAL_ALLOCATE_PROMPT, UI_R_NO_RESULT_BUFFER); + } else if ((ret = (UI_STRING *)OPENSSL_malloc(sizeof(UI_STRING)))) { + ret->out_string = prompt; + ret->flags = prompt_freeable ? OUT_STRING_FREEABLE : 0; + ret->input_flags = input_flags; + ret->type = type; + ret->result_buf = result_buf; + } + return ret; +} + +static int general_allocate_string(UI *ui, const char *prompt, + int prompt_freeable, + enum UI_string_types type, int input_flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf) +{ + int ret = -1; + UI_STRING *s = general_allocate_prompt(ui, prompt, prompt_freeable, + type, input_flags, result_buf); + + if (s) { + if (allocate_string_stack(ui) >= 0) { + s->_.string_data.result_minsize = minsize; + s->_.string_data.result_maxsize = maxsize; + s->_.string_data.test_buf = test_buf; + ret = sk_UI_STRING_push(ui->strings, s); + /* sk_push() returns 0 on error. Let's addapt that */ + if (ret <= 0) + ret--; + } else + free_string(s); + } + return ret; +} + +static int general_allocate_boolean(UI *ui, + const char *prompt, + const char *action_desc, + const char *ok_chars, + const char *cancel_chars, + int prompt_freeable, + enum UI_string_types type, + int input_flags, char *result_buf) +{ + int ret = -1; + UI_STRING *s; + const char *p; + + if (ok_chars == NULL) { + UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER); + } else if (cancel_chars == NULL) { + UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, ERR_R_PASSED_NULL_PARAMETER); + } else { + for (p = ok_chars; *p; p++) { + if (strchr(cancel_chars, *p)) { + UIerr(UI_F_GENERAL_ALLOCATE_BOOLEAN, + UI_R_COMMON_OK_AND_CANCEL_CHARACTERS); + } + } + + s = general_allocate_prompt(ui, prompt, prompt_freeable, + type, input_flags, result_buf); + + if (s) { + if (allocate_string_stack(ui) >= 0) { + s->_.boolean_data.action_desc = action_desc; + s->_.boolean_data.ok_chars = ok_chars; + s->_.boolean_data.cancel_chars = cancel_chars; + ret = sk_UI_STRING_push(ui->strings, s); + /* + * sk_push() returns 0 on error. Let's addapt that + */ + if (ret <= 0) + ret--; + } else + free_string(s); + } + } + return ret; +} + +/* + * Returns the index to the place in the stack or -1 for error. Uses a + * direct reference to the prompt. + */ +int UI_add_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize) +{ + return general_allocate_string(ui, prompt, 0, + UIT_PROMPT, flags, result_buf, minsize, + maxsize, NULL); +} + +/* Same as UI_add_input_string(), excepts it takes a copy of the prompt */ +int UI_dup_input_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize) +{ + char *prompt_copy = NULL; + + if (prompt) { + prompt_copy = BUF_strdup(prompt); + if (prompt_copy == NULL) { + UIerr(UI_F_UI_DUP_INPUT_STRING, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + return general_allocate_string(ui, prompt_copy, 1, + UIT_PROMPT, flags, result_buf, minsize, + maxsize, NULL); +} + +int UI_add_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf) +{ + return general_allocate_string(ui, prompt, 0, + UIT_VERIFY, flags, result_buf, minsize, + maxsize, test_buf); +} + +int UI_dup_verify_string(UI *ui, const char *prompt, int flags, + char *result_buf, int minsize, int maxsize, + const char *test_buf) +{ + char *prompt_copy = NULL; + + if (prompt) { + prompt_copy = BUF_strdup(prompt); + if (prompt_copy == NULL) { + UIerr(UI_F_UI_DUP_VERIFY_STRING, ERR_R_MALLOC_FAILURE); + return -1; + } + } + + return general_allocate_string(ui, prompt_copy, 1, + UIT_VERIFY, flags, result_buf, minsize, + maxsize, test_buf); +} + +int UI_add_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf) +{ + return general_allocate_boolean(ui, prompt, action_desc, + ok_chars, cancel_chars, 0, UIT_BOOLEAN, + flags, result_buf); +} + +int UI_dup_input_boolean(UI *ui, const char *prompt, const char *action_desc, + const char *ok_chars, const char *cancel_chars, + int flags, char *result_buf) +{ + char *prompt_copy = NULL; + char *action_desc_copy = NULL; + char *ok_chars_copy = NULL; + char *cancel_chars_copy = NULL; + + if (prompt) { + prompt_copy = BUF_strdup(prompt); + if (prompt_copy == NULL) { + UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (action_desc) { + action_desc_copy = BUF_strdup(action_desc); + if (action_desc_copy == NULL) { + UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (ok_chars) { + ok_chars_copy = BUF_strdup(ok_chars); + if (ok_chars_copy == NULL) { + UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (cancel_chars) { + cancel_chars_copy = BUF_strdup(cancel_chars); + if (cancel_chars_copy == NULL) { + UIerr(UI_F_UI_DUP_INPUT_BOOLEAN, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + return general_allocate_boolean(ui, prompt_copy, action_desc_copy, + ok_chars_copy, cancel_chars_copy, 1, + UIT_BOOLEAN, flags, result_buf); + err: + if (prompt_copy) + OPENSSL_free(prompt_copy); + if (action_desc_copy) + OPENSSL_free(action_desc_copy); + if (ok_chars_copy) + OPENSSL_free(ok_chars_copy); + if (cancel_chars_copy) + OPENSSL_free(cancel_chars_copy); + return -1; +} + +int UI_add_info_string(UI *ui, const char *text) +{ + return general_allocate_string(ui, text, 0, UIT_INFO, 0, NULL, 0, 0, + NULL); +} + +int UI_dup_info_string(UI *ui, const char *text) +{ + char *text_copy = NULL; + + if (text) { + text_copy = BUF_strdup(text); + if (text_copy == NULL) { + UIerr(UI_F_UI_DUP_INFO_STRING, ERR_R_MALLOC_FAILURE); + return -1; + } + } + + return general_allocate_string(ui, text_copy, 1, UIT_INFO, 0, NULL, + 0, 0, NULL); +} + +int UI_add_error_string(UI *ui, const char *text) +{ + return general_allocate_string(ui, text, 0, UIT_ERROR, 0, NULL, 0, 0, + NULL); +} + +int UI_dup_error_string(UI *ui, const char *text) +{ + char *text_copy = NULL; + + if (text) { + text_copy = BUF_strdup(text); + if (text_copy == NULL) { + UIerr(UI_F_UI_DUP_ERROR_STRING, ERR_R_MALLOC_FAILURE); + return -1; + } + } + return general_allocate_string(ui, text_copy, 1, UIT_ERROR, 0, NULL, + 0, 0, NULL); +} + +char *UI_construct_prompt(UI *ui, const char *object_desc, + const char *object_name) +{ + char *prompt = NULL; + + if (ui->meth->ui_construct_prompt) + prompt = ui->meth->ui_construct_prompt(ui, object_desc, object_name); + else { + char prompt1[] = "Enter "; + char prompt2[] = " for "; + char prompt3[] = ":"; + int len = 0; + + if (object_desc == NULL) + return NULL; + len = sizeof(prompt1) - 1 + strlen(object_desc); + if (object_name) + len += sizeof(prompt2) - 1 + strlen(object_name); + len += sizeof(prompt3) - 1; + + prompt = (char *)OPENSSL_malloc(len + 1); + BUF_strlcpy(prompt, prompt1, len + 1); + BUF_strlcat(prompt, object_desc, len + 1); + if (object_name) { + BUF_strlcat(prompt, prompt2, len + 1); + BUF_strlcat(prompt, object_name, len + 1); + } + BUF_strlcat(prompt, prompt3, len + 1); + } + return prompt; +} + +void *UI_add_user_data(UI *ui, void *user_data) +{ + void *old_data = ui->user_data; + ui->user_data = user_data; + return old_data; +} + +void *UI_get0_user_data(UI *ui) +{ + return ui->user_data; +} + +const char *UI_get0_result(UI *ui, int i) +{ + if (i < 0) { + UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_SMALL); + return NULL; + } + if (i >= sk_UI_STRING_num(ui->strings)) { + UIerr(UI_F_UI_GET0_RESULT, UI_R_INDEX_TOO_LARGE); + return NULL; + } + return UI_get0_result_string(sk_UI_STRING_value(ui->strings, i)); +} + +static int print_error(const char *str, size_t len, UI *ui) +{ + UI_STRING uis; + + memset(&uis, 0, sizeof(uis)); + uis.type = UIT_ERROR; + uis.out_string = str; + + if (ui->meth->ui_write_string && !ui->meth->ui_write_string(ui, &uis)) + return -1; + return 0; +} + +int UI_process(UI *ui) +{ + int i, ok = 0; + + if (ui->meth->ui_open_session && !ui->meth->ui_open_session(ui)) + return -1; + + if (ui->flags & UI_FLAG_PRINT_ERRORS) + ERR_print_errors_cb((int (*)(const char *, size_t, void *)) + print_error, (void *)ui); + + for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) { + if (ui->meth->ui_write_string + && !ui->meth->ui_write_string(ui, + sk_UI_STRING_value(ui->strings, i))) + { + ok = -1; + goto err; + } + } + + if (ui->meth->ui_flush) + switch (ui->meth->ui_flush(ui)) { + case -1: /* Interrupt/Cancel/something... */ + ok = -2; + goto err; + case 0: /* Errors */ + ok = -1; + goto err; + default: /* Success */ + ok = 0; + break; + } + + for (i = 0; i < sk_UI_STRING_num(ui->strings); i++) { + if (ui->meth->ui_read_string) { + switch (ui->meth->ui_read_string(ui, + sk_UI_STRING_value(ui->strings, + i))) { + case -1: /* Interrupt/Cancel/something... */ + ok = -2; + goto err; + case 0: /* Errors */ + ok = -1; + goto err; + default: /* Success */ + ok = 0; + break; + } + } + } + err: + if (ui->meth->ui_close_session && !ui->meth->ui_close_session(ui)) + return -1; + return ok; +} + +int UI_ctrl(UI *ui, int cmd, long i, void *p, void (*f) (void)) +{ + if (ui == NULL) { + UIerr(UI_F_UI_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + switch (cmd) { + case UI_CTRL_PRINT_ERRORS: + { + int save_flag = ! !(ui->flags & UI_FLAG_PRINT_ERRORS); + if (i) + ui->flags |= UI_FLAG_PRINT_ERRORS; + else + ui->flags &= ~UI_FLAG_PRINT_ERRORS; + return save_flag; + } + case UI_CTRL_IS_REDOABLE: + return ! !(ui->flags & UI_FLAG_REDOABLE); + default: + break; + } + UIerr(UI_F_UI_CTRL, UI_R_UNKNOWN_CONTROL_COMMAND); + return -1; +} + +int UI_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_UI, argl, argp, + new_func, dup_func, free_func); +} + +int UI_set_ex_data(UI *r, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&r->ex_data, idx, arg)); +} + +void *UI_get_ex_data(UI *r, int idx) +{ + return (CRYPTO_get_ex_data(&r->ex_data, idx)); +} + +void UI_set_default_method(const UI_METHOD *meth) +{ + default_UI_meth = meth; +} + +const UI_METHOD *UI_get_default_method(void) +{ + if (default_UI_meth == NULL) { + default_UI_meth = UI_OpenSSL(); + } + return default_UI_meth; +} + +const UI_METHOD *UI_get_method(UI *ui) +{ + return ui->meth; +} + +const UI_METHOD *UI_set_method(UI *ui, const UI_METHOD *meth) +{ + ui->meth = meth; + return ui->meth; +} + +UI_METHOD *UI_create_method(char *name) +{ + UI_METHOD *ui_method = (UI_METHOD *)OPENSSL_malloc(sizeof(UI_METHOD)); + + if (ui_method) { + memset(ui_method, 0, sizeof(*ui_method)); + ui_method->name = BUF_strdup(name); + } + return ui_method; +} + +/* + * BIG FSCKING WARNING!!!! If you use this on a statically allocated method + * (that is, it hasn't been allocated using UI_create_method(), you deserve + * anything Murphy can throw at you and more! You have been warned. + */ +void UI_destroy_method(UI_METHOD *ui_method) +{ + OPENSSL_free(ui_method->name); + ui_method->name = NULL; + OPENSSL_free(ui_method); +} + +int UI_method_set_opener(UI_METHOD *method, int (*opener) (UI *ui)) +{ + if (method) { + method->ui_open_session = opener; + return 0; + } else + return -1; +} + +int UI_method_set_writer(UI_METHOD *method, + int (*writer) (UI *ui, UI_STRING *uis)) +{ + if (method) { + method->ui_write_string = writer; + return 0; + } else + return -1; +} + +int UI_method_set_flusher(UI_METHOD *method, int (*flusher) (UI *ui)) +{ + if (method) { + method->ui_flush = flusher; + return 0; + } else + return -1; +} + +int UI_method_set_reader(UI_METHOD *method, + int (*reader) (UI *ui, UI_STRING *uis)) +{ + if (method) { + method->ui_read_string = reader; + return 0; + } else + return -1; +} + +int UI_method_set_closer(UI_METHOD *method, int (*closer) (UI *ui)) +{ + if (method) { + method->ui_close_session = closer; + return 0; + } else + return -1; +} + +int UI_method_set_prompt_constructor(UI_METHOD *method, + char *(*prompt_constructor) (UI *ui, + const char + *object_desc, + const char + *object_name)) +{ + if (method) { + method->ui_construct_prompt = prompt_constructor; + return 0; + } else + return -1; +} + +int (*UI_method_get_opener(UI_METHOD *method)) (UI *) { + if (method) + return method->ui_open_session; + else + return NULL; +} + +int (*UI_method_get_writer(UI_METHOD *method)) (UI *, UI_STRING *) { + if (method) + return method->ui_write_string; + else + return NULL; +} + +int (*UI_method_get_flusher(UI_METHOD *method)) (UI *) { + if (method) + return method->ui_flush; + else + return NULL; +} + +int (*UI_method_get_reader(UI_METHOD *method)) (UI *, UI_STRING *) { + if (method) + return method->ui_read_string; + else + return NULL; +} + +int (*UI_method_get_closer(UI_METHOD *method)) (UI *) { + if (method) + return method->ui_close_session; + else + return NULL; +} + +char *(*UI_method_get_prompt_constructor(UI_METHOD *method)) (UI *, + const char *, + const char *) { + if (method) + return method->ui_construct_prompt; + else + return NULL; +} + +enum UI_string_types UI_get_string_type(UI_STRING *uis) +{ + if (!uis) + return UIT_NONE; + return uis->type; +} + +int UI_get_input_flags(UI_STRING *uis) +{ + if (!uis) + return 0; + return uis->input_flags; +} + +const char *UI_get0_output_string(UI_STRING *uis) +{ + if (!uis) + return NULL; + return uis->out_string; +} + +const char *UI_get0_action_string(UI_STRING *uis) +{ + if (!uis) + return NULL; + switch (uis->type) { + case UIT_PROMPT: + case UIT_BOOLEAN: + return uis->_.boolean_data.action_desc; + default: + return NULL; + } +} + +const char *UI_get0_result_string(UI_STRING *uis) +{ + if (!uis) + return NULL; + switch (uis->type) { + case UIT_PROMPT: + case UIT_VERIFY: + return uis->result_buf; + default: + return NULL; + } +} + +const char *UI_get0_test_string(UI_STRING *uis) +{ + if (!uis) + return NULL; + switch (uis->type) { + case UIT_VERIFY: + return uis->_.string_data.test_buf; + default: + return NULL; + } +} + +int UI_get_result_minsize(UI_STRING *uis) +{ + if (!uis) + return -1; + switch (uis->type) { + case UIT_PROMPT: + case UIT_VERIFY: + return uis->_.string_data.result_minsize; + default: + return -1; + } +} + +int UI_get_result_maxsize(UI_STRING *uis) +{ + if (!uis) + return -1; + switch (uis->type) { + case UIT_PROMPT: + case UIT_VERIFY: + return uis->_.string_data.result_maxsize; + default: + return -1; + } +} + +int UI_set_result(UI *ui, UI_STRING *uis, const char *result) +{ + int l = strlen(result); + + ui->flags &= ~UI_FLAG_REDOABLE; + + if (!uis) + return -1; + switch (uis->type) { + case UIT_PROMPT: + case UIT_VERIFY: + { + char number1[DECIMAL_SIZE(uis->_.string_data.result_minsize) + 1]; + char number2[DECIMAL_SIZE(uis->_.string_data.result_maxsize) + 1]; + + BIO_snprintf(number1, sizeof(number1), "%d", + uis->_.string_data.result_minsize); + BIO_snprintf(number2, sizeof(number2), "%d", + uis->_.string_data.result_maxsize); + + if (l < uis->_.string_data.result_minsize) { + ui->flags |= UI_FLAG_REDOABLE; + UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_SMALL); + ERR_add_error_data(5, "You must type in ", + number1, " to ", number2, " characters"); + return -1; + } + if (l > uis->_.string_data.result_maxsize) { + ui->flags |= UI_FLAG_REDOABLE; + UIerr(UI_F_UI_SET_RESULT, UI_R_RESULT_TOO_LARGE); + ERR_add_error_data(5, "You must type in ", + number1, " to ", number2, " characters"); + return -1; + } + } + + if (!uis->result_buf) { + UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER); + return -1; + } + + BUF_strlcpy(uis->result_buf, result, + uis->_.string_data.result_maxsize + 1); + break; + case UIT_BOOLEAN: + { + const char *p; + + if (!uis->result_buf) { + UIerr(UI_F_UI_SET_RESULT, UI_R_NO_RESULT_BUFFER); + return -1; + } + + uis->result_buf[0] = '\0'; + for (p = result; *p; p++) { + if (strchr(uis->_.boolean_data.ok_chars, *p)) { + uis->result_buf[0] = uis->_.boolean_data.ok_chars[0]; + break; + } + if (strchr(uis->_.boolean_data.cancel_chars, *p)) { + uis->result_buf[0] = uis->_.boolean_data.cancel_chars[0]; + break; + } + } + } + default: + break; + } + return 0; +} diff --git a/libs/openssl/crypto/ui/ui_locl.h b/libs/openssl/crypto/ui/ui_locl.h new file mode 100644 index 00000000..bebc13ab --- /dev/null +++ b/libs/openssl/crypto/ui/ui_locl.h @@ -0,0 +1,145 @@ +/* crypto/ui/ui.h */ +/* + * Written by Richard Levitte (richard@levitte.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_UI_LOCL_H +# define HEADER_UI_LOCL_H + +# include +# include + +# ifdef _ +# undef _ +# endif + +struct ui_method_st { + char *name; + /* + * All the functions return 1 or non-NULL for success and 0 or NULL for + * failure + */ + /* + * Open whatever channel for this, be it the console, an X window or + * whatever. This function should use the ex_data structure to save + * intermediate data. + */ + int (*ui_open_session) (UI *ui); + int (*ui_write_string) (UI *ui, UI_STRING *uis); + /* + * Flush the output. If a GUI dialog box is used, this function can be + * used to actually display it. + */ + int (*ui_flush) (UI *ui); + int (*ui_read_string) (UI *ui, UI_STRING *uis); + int (*ui_close_session) (UI *ui); + /* + * Construct a prompt in a user-defined manner. object_desc is a textual + * short description of the object, for example "pass phrase", and + * object_name is the name of the object (might be a card name or a file + * name. The returned string shall always be allocated on the heap with + * OPENSSL_malloc(), and need to be free'd with OPENSSL_free(). + */ + char *(*ui_construct_prompt) (UI *ui, const char *object_desc, + const char *object_name); +}; + +struct ui_string_st { + enum UI_string_types type; /* Input */ + const char *out_string; /* Input */ + int input_flags; /* Flags from the user */ + /* + * The following parameters are completely irrelevant for UIT_INFO, and + * can therefore be set to 0 or NULL + */ + char *result_buf; /* Input and Output: If not NULL, + * user-defined with size in result_maxsize. + * Otherwise, it may be allocated by the UI + * routine, meaning result_minsize is going + * to be overwritten. */ + union { + struct { + int result_minsize; /* Input: minimum required size of the + * result. */ + int result_maxsize; /* Input: maximum permitted size of the + * result */ + const char *test_buf; /* Input: test string to verify against */ + } string_data; + struct { + const char *action_desc; /* Input */ + const char *ok_chars; /* Input */ + const char *cancel_chars; /* Input */ + } boolean_data; + } _; + +# define OUT_STRING_FREEABLE 0x01 + int flags; /* flags for internal use */ +}; + +struct ui_st { + const UI_METHOD *meth; + STACK_OF(UI_STRING) *strings; /* We might want to prompt for more than + * one thing at a time, and with different + * echoing status. */ + void *user_data; + CRYPTO_EX_DATA ex_data; +# define UI_FLAG_REDOABLE 0x0001 +# define UI_FLAG_PRINT_ERRORS 0x0100 + int flags; +}; + +#endif diff --git a/libs/openssl/crypto/ui/ui_openssl.c b/libs/openssl/crypto/ui/ui_openssl.c new file mode 100644 index 00000000..a8b3d0ca --- /dev/null +++ b/libs/openssl/crypto/ui/ui_openssl.c @@ -0,0 +1,717 @@ +/* crypto/ui/ui_openssl.c */ +/* + * Written by Richard Levitte (richard@levitte.org) and others for the + * OpenSSL project 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/*- + * The lowest level part of this file was previously in crypto/des/read_pwd.c, + * Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include + +/* + * need for #define _POSIX_C_SOURCE arises whenever you pass -ansi to gcc + * [maybe others?], because it masks interfaces not discussed in standard, + * sigaction and fileno included. -pedantic would be more appropriate for the + * intended purposes, but we can't prevent users from adding -ansi. + */ +#if defined(OPENSSL_SYSNAME_VXWORKS) +# include +#endif + +#if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS) +# ifndef _POSIX_C_SOURCE +# define _POSIX_C_SOURCE 2 +# endif +#endif +#include +#include +#include +#include + +#if !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) +# ifdef OPENSSL_UNISTD +# include OPENSSL_UNISTD +# else +# include +# endif +/* + * If unistd.h defines _POSIX_VERSION, we conclude that we are on a POSIX + * system and have sigaction and termios. + */ +# if defined(_POSIX_VERSION) + +# define SIGACTION +# if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) +# define TERMIOS +# endif + +# endif +#endif + +#ifdef WIN16TTY +# undef OPENSSL_SYS_WIN16 +# undef WIN16 +# undef _WINDOWS +# include +#endif + +/* 06-Apr-92 Luke Brennan Support for VMS */ +#include "ui_locl.h" +#include "cryptlib.h" + +#ifdef OPENSSL_SYS_VMS /* prototypes for sys$whatever */ +# include +# ifdef __DECC +# pragma message disable DOLLARID +# endif +#endif + +#ifdef WIN_CONSOLE_BUG +# include +# ifndef OPENSSL_SYS_WINCE +# include +# endif +#endif + +/* + * There are 5 types of terminal interface supported, TERMIO, TERMIOS, VMS, + * MSDOS and SGTTY. + * + * If someone defines one of the macros TERMIO, TERMIOS or SGTTY, it will + * remain respected. Otherwise, we default to TERMIOS except for a few + * systems that require something different. + * + * Note: we do not use SGTTY unless it's defined by the configuration. We + * may eventually opt to remove it's use entirely. + */ + +#if !defined(TERMIOS) && !defined(TERMIO) && !defined(SGTTY) + +# if defined(_LIBC) +# undef TERMIOS +# define TERMIO +# undef SGTTY +/* + * We know that VMS, MSDOS, VXWORKS, NETWARE use entirely other mechanisms. + * MAC_OS_GUSI_SOURCE should probably go away, but that needs to be confirmed. + */ +# elif !defined(OPENSSL_SYS_VMS) \ + && !defined(OPENSSL_SYS_MSDOS) \ + && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) \ + && !defined(MAC_OS_GUSI_SOURCE) \ + && !defined(OPENSSL_SYS_VXWORKS) \ + && !defined(OPENSSL_SYS_NETWARE) +# define TERMIOS +# undef TERMIO +# undef SGTTY +# endif + +#endif + +#ifdef TERMIOS +# include +# define TTY_STRUCT struct termios +# define TTY_FLAGS c_lflag +# define TTY_get(tty,data) tcgetattr(tty,data) +# define TTY_set(tty,data) tcsetattr(tty,TCSANOW,data) +#endif + +#ifdef TERMIO +# include +# define TTY_STRUCT struct termio +# define TTY_FLAGS c_lflag +# define TTY_get(tty,data) ioctl(tty,TCGETA,data) +# define TTY_set(tty,data) ioctl(tty,TCSETA,data) +#endif + +#ifdef SGTTY +# include +# define TTY_STRUCT struct sgttyb +# define TTY_FLAGS sg_flags +# define TTY_get(tty,data) ioctl(tty,TIOCGETP,data) +# define TTY_set(tty,data) ioctl(tty,TIOCSETP,data) +#endif + +#if !defined(_LIBC) && !defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_VMS) && !defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && !defined(OPENSSL_SYS_SUNOS) +# include +#endif + +#ifdef OPENSSL_SYS_MSDOS +# include +#endif + +#ifdef OPENSSL_SYS_VMS +# include +# include +# include +# include +struct IOSB { + short iosb$w_value; + short iosb$w_count; + long iosb$l_info; +}; +#endif + +#ifdef OPENSSL_SYS_SUNOS +typedef int sig_atomic_t; +#endif + +#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(MAC_OS_GUSI_SOURCE) || defined(OPENSSL_SYS_NETWARE) +/* + * This one needs work. As a matter of fact the code is unoperational + * and this is only a trick to get it compiled. + * + */ +# define TTY_STRUCT int +#endif + +#ifndef NX509_SIG +# define NX509_SIG 32 +#endif + +/* Define globals. They are protected by a lock */ +#ifdef SIGACTION +static struct sigaction savsig[NX509_SIG]; +#else +static void (*savsig[NX509_SIG]) (int); +#endif + +#ifdef OPENSSL_SYS_VMS +static struct IOSB iosb; +static $DESCRIPTOR(terminal, "TT"); +static long tty_orig[3], tty_new[3]; /* XXX Is there any guarantee that this + * will always suffice for the actual + * structures? */ +static long status; +static unsigned short channel = 0; +#else +# if !defined(OPENSSL_SYS_MSDOS) || defined(__DJGPP__) +static TTY_STRUCT tty_orig, tty_new; +# endif +#endif +static FILE *tty_in, *tty_out; +static int is_a_tty; + +/* Declare static functions */ +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) +static int read_till_nl(FILE *); +static void recsig(int); +static void pushsig(void); +static void popsig(void); +#endif +#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) +static int noecho_fgets(char *buf, int size, FILE *tty); +#endif +static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl); + +static int read_string(UI *ui, UI_STRING *uis); +static int write_string(UI *ui, UI_STRING *uis); + +static int open_console(UI *ui); +static int echo_console(UI *ui); +static int noecho_console(UI *ui); +static int close_console(UI *ui); + +static UI_METHOD ui_openssl = { + "OpenSSL default user interface", + open_console, + write_string, + NULL, /* No flusher is needed for command lines */ + read_string, + close_console, + NULL +}; + +/* The method with all the built-in thingies */ +UI_METHOD *UI_OpenSSL(void) +{ + return &ui_openssl; +} + +/* + * The following function makes sure that info and error strings are printed + * before any prompt. + */ +static int write_string(UI *ui, UI_STRING *uis) +{ + switch (UI_get_string_type(uis)) { + case UIT_ERROR: + case UIT_INFO: + fputs(UI_get0_output_string(uis), tty_out); + fflush(tty_out); + break; + default: + break; + } + return 1; +} + +static int read_string(UI *ui, UI_STRING *uis) +{ + int ok = 0; + + switch (UI_get_string_type(uis)) { + case UIT_BOOLEAN: + fputs(UI_get0_output_string(uis), tty_out); + fputs(UI_get0_action_string(uis), tty_out); + fflush(tty_out); + return read_string_inner(ui, uis, + UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, + 0); + case UIT_PROMPT: + fputs(UI_get0_output_string(uis), tty_out); + fflush(tty_out); + return read_string_inner(ui, uis, + UI_get_input_flags(uis) & UI_INPUT_FLAG_ECHO, + 1); + case UIT_VERIFY: + fprintf(tty_out, "Verifying - %s", UI_get0_output_string(uis)); + fflush(tty_out); + if ((ok = read_string_inner(ui, uis, + UI_get_input_flags(uis) & + UI_INPUT_FLAG_ECHO, 1)) <= 0) + return ok; + if (strcmp(UI_get0_result_string(uis), UI_get0_test_string(uis)) != 0) { + fprintf(tty_out, "Verify failure\n"); + fflush(tty_out); + return 0; + } + break; + default: + break; + } + return 1; +} + +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) +/* Internal functions to read a string without echoing */ +static int read_till_nl(FILE *in) +{ +# define SIZE 4 + char buf[SIZE + 1]; + + do { + if (!fgets(buf, SIZE, in)) + return 0; + } while (strchr(buf, '\n') == NULL); + return 1; +} + +static volatile sig_atomic_t intr_signal; +#endif + +static int read_string_inner(UI *ui, UI_STRING *uis, int echo, int strip_nl) +{ + static int ps; + int ok; + char result[BUFSIZ]; + int maxsize = BUFSIZ - 1; +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) + char *p; + + intr_signal = 0; + ok = 0; + ps = 0; + + pushsig(); + ps = 1; + + if (!echo && !noecho_console(ui)) + goto error; + ps = 2; + + result[0] = '\0'; +# ifdef OPENSSL_SYS_MSDOS + if (!echo) { + noecho_fgets(result, maxsize, tty_in); + p = result; /* FIXME: noecho_fgets doesn't return errors */ + } else + p = fgets(result, maxsize, tty_in); +# else + p = fgets(result, maxsize, tty_in); +# endif + if (!p) + goto error; + if (feof(tty_in)) + goto error; + if (ferror(tty_in)) + goto error; + if ((p = (char *)strchr(result, '\n')) != NULL) { + if (strip_nl) + *p = '\0'; + } else if (!read_till_nl(tty_in)) + goto error; + if (UI_set_result(ui, uis, result) >= 0) + ok = 1; + + error: + if (intr_signal == SIGINT) + ok = -1; + if (!echo) + fprintf(tty_out, "\n"); + if (ps >= 2 && !echo && !echo_console(ui)) + ok = 0; + + if (ps >= 1) + popsig(); +#else + ok = 1; +#endif + + OPENSSL_cleanse(result, BUFSIZ); + return ok; +} + +/* Internal functions to open, handle and close a channel to the console. */ +static int open_console(UI *ui) +{ + CRYPTO_w_lock(CRYPTO_LOCK_UI); + is_a_tty = 1; + +#if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS) + tty_in = stdin; + tty_out = stderr; +#else +# ifdef OPENSSL_SYS_MSDOS +# define DEV_TTY "con" +# else +# define DEV_TTY "/dev/tty" +# endif + if ((tty_in = fopen(DEV_TTY, "r")) == NULL) + tty_in = stdin; + if ((tty_out = fopen(DEV_TTY, "w")) == NULL) + tty_out = stderr; +#endif + +#if defined(TTY_get) && !defined(OPENSSL_SYS_VMS) + if (TTY_get(fileno(tty_in), &tty_orig) == -1) { +# ifdef ENOTTY + if (errno == ENOTTY) + is_a_tty = 0; + else +# endif +# ifdef EINVAL + /* + * Ariel Glenn ariel@columbia.edu reports that solaris can return + * EINVAL instead. This should be ok + */ + if (errno == EINVAL) + is_a_tty = 0; + else +# endif + return 0; + } +#endif +#ifdef OPENSSL_SYS_VMS + status = sys$assign(&terminal, &channel, 0, 0); + if (status != SS$_NORMAL) + return 0; + status = + sys$qiow(0, channel, IO$_SENSEMODE, &iosb, 0, 0, tty_orig, 12, 0, 0, + 0, 0); + if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) + return 0; +#endif + return 1; +} + +static int noecho_console(UI *ui) +{ +#ifdef TTY_FLAGS + memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig)); + tty_new.TTY_FLAGS &= ~ECHO; +#endif + +#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) + if (is_a_tty && (TTY_set(fileno(tty_in), &tty_new) == -1)) + return 0; +#endif +#ifdef OPENSSL_SYS_VMS + tty_new[0] = tty_orig[0]; + tty_new[1] = tty_orig[1] | TT$M_NOECHO; + tty_new[2] = tty_orig[2]; + status = + sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0, + 0); + if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) + return 0; +#endif + return 1; +} + +static int echo_console(UI *ui) +{ +#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) + memcpy(&(tty_new), &(tty_orig), sizeof(tty_orig)); + tty_new.TTY_FLAGS |= ECHO; +#endif + +#if defined(TTY_set) && !defined(OPENSSL_SYS_VMS) + if (is_a_tty && (TTY_set(fileno(tty_in), &tty_new) == -1)) + return 0; +#endif +#ifdef OPENSSL_SYS_VMS + tty_new[0] = tty_orig[0]; + tty_new[1] = tty_orig[1] & ~TT$M_NOECHO; + tty_new[2] = tty_orig[2]; + status = + sys$qiow(0, channel, IO$_SETMODE, &iosb, 0, 0, tty_new, 12, 0, 0, 0, + 0); + if ((status != SS$_NORMAL) || (iosb.iosb$w_value != SS$_NORMAL)) + return 0; +#endif + return 1; +} + +static int close_console(UI *ui) +{ + if (tty_in != stdin) + fclose(tty_in); + if (tty_out != stderr) + fclose(tty_out); +#ifdef OPENSSL_SYS_VMS + status = sys$dassgn(channel); +#endif + CRYPTO_w_unlock(CRYPTO_LOCK_UI); + + return 1; +} + +#if !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) +/* Internal functions to handle signals and act on them */ +static void pushsig(void) +{ +# ifndef OPENSSL_SYS_WIN32 + int i; +# endif +# ifdef SIGACTION + struct sigaction sa; + + memset(&sa, 0, sizeof sa); + sa.sa_handler = recsig; +# endif + +# ifdef OPENSSL_SYS_WIN32 + savsig[SIGABRT] = signal(SIGABRT, recsig); + savsig[SIGFPE] = signal(SIGFPE, recsig); + savsig[SIGILL] = signal(SIGILL, recsig); + savsig[SIGINT] = signal(SIGINT, recsig); + savsig[SIGSEGV] = signal(SIGSEGV, recsig); + savsig[SIGTERM] = signal(SIGTERM, recsig); +# else + for (i = 1; i < NX509_SIG; i++) { +# ifdef SIGUSR1 + if (i == SIGUSR1) + continue; +# endif +# ifdef SIGUSR2 + if (i == SIGUSR2) + continue; +# endif +# ifdef SIGKILL + if (i == SIGKILL) /* We can't make any action on that. */ + continue; +# endif +# ifdef SIGACTION + sigaction(i, &sa, &savsig[i]); +# else + savsig[i] = signal(i, recsig); +# endif + } +# endif + +# ifdef SIGWINCH + signal(SIGWINCH, SIG_DFL); +# endif +} + +static void popsig(void) +{ +# ifdef OPENSSL_SYS_WIN32 + signal(SIGABRT, savsig[SIGABRT]); + signal(SIGFPE, savsig[SIGFPE]); + signal(SIGILL, savsig[SIGILL]); + signal(SIGINT, savsig[SIGINT]); + signal(SIGSEGV, savsig[SIGSEGV]); + signal(SIGTERM, savsig[SIGTERM]); +# else + int i; + for (i = 1; i < NX509_SIG; i++) { +# ifdef SIGUSR1 + if (i == SIGUSR1) + continue; +# endif +# ifdef SIGUSR2 + if (i == SIGUSR2) + continue; +# endif +# ifdef SIGACTION + sigaction(i, &savsig[i], NULL); +# else + signal(i, savsig[i]); +# endif + } +# endif +} + +static void recsig(int i) +{ + intr_signal = i; +} +#endif + +/* Internal functions specific for Windows */ +#if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN16) && !defined(OPENSSL_SYS_WINCE) +static int noecho_fgets(char *buf, int size, FILE *tty) +{ + int i; + char *p; + + p = buf; + for (;;) { + if (size == 0) { + *p = '\0'; + break; + } + size--; +# ifdef WIN16TTY + i = _inchar(); +# elif defined(_WIN32) + i = _getch(); +# else + i = getch(); +# endif + if (i == '\r') + i = '\n'; + *(p++) = i; + if (i == '\n') { + *p = '\0'; + break; + } + } +# ifdef WIN_CONSOLE_BUG + /* + * Win95 has several evil console bugs: one of these is that the last + * character read using getch() is passed to the next read: this is + * usually a CR so this can be trouble. No STDIO fix seems to work but + * flushing the console appears to do the trick. + */ + { + HANDLE inh; + inh = GetStdHandle(STD_INPUT_HANDLE); + FlushConsoleInputBuffer(inh); + } +# endif + return (strlen(buf)); +} +#endif diff --git a/libs/openssl/crypto/ui/ui_util.c b/libs/openssl/crypto/ui/ui_util.c new file mode 100644 index 00000000..0f290115 --- /dev/null +++ b/libs/openssl/crypto/ui/ui_util.c @@ -0,0 +1,93 @@ +/* crypto/ui/ui_util.c */ +/* ==================================================================== + * Copyright (c) 2001-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "ui_locl.h" + +int UI_UTIL_read_pw_string(char *buf, int length, const char *prompt, + int verify) +{ + char buff[BUFSIZ]; + int ret; + + ret = + UI_UTIL_read_pw(buf, buff, (length > BUFSIZ) ? BUFSIZ : length, + prompt, verify); + OPENSSL_cleanse(buff, BUFSIZ); + return (ret); +} + +int UI_UTIL_read_pw(char *buf, char *buff, int size, const char *prompt, + int verify) +{ + int ok = 0; + UI *ui; + + if (size < 1) + return -1; + + ui = UI_new(); + if (ui) { + ok = UI_add_input_string(ui, prompt, 0, buf, 0, size - 1); + if (ok >= 0 && verify) + ok = UI_add_verify_string(ui, prompt, 0, buff, 0, size - 1, buf); + if (ok >= 0) + ok = UI_process(ui); + UI_free(ui); + } + if (ok > 0) + ok = 0; + return (ok); +} diff --git a/libs/openssl/crypto/uid.c b/libs/openssl/crypto/uid.c new file mode 100644 index 00000000..90694c67 --- /dev/null +++ b/libs/openssl/crypto/uid.c @@ -0,0 +1,88 @@ +/* crypto/uid.c */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include + +#if defined(__OpenBSD__) || (defined(__FreeBSD__) && __FreeBSD__ > 2) + +# include OPENSSL_UNISTD + +int OPENSSL_issetugid(void) +{ + return issetugid(); +} + +#elif defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) + +int OPENSSL_issetugid(void) +{ + return 0; +} + +#else + +# include OPENSSL_UNISTD +# include + +int OPENSSL_issetugid(void) +{ + if (getuid() != geteuid()) + return 1; + if (getgid() != getegid()) + return 1; + return 0; +} +#endif diff --git a/libs/openssl/crypto/vms_rms.h b/libs/openssl/crypto/vms_rms.h new file mode 100644 index 00000000..09c280e8 --- /dev/null +++ b/libs/openssl/crypto/vms_rms.h @@ -0,0 +1,50 @@ + +#ifdef NAML$C_MAXRSS + +# define CC_RMS_NAMX cc$rms_naml +# define FAB_NAMX fab$l_naml +# define FAB_OR_NAML( fab, naml) naml +# define FAB_OR_NAML_DNA naml$l_long_defname +# define FAB_OR_NAML_DNS naml$l_long_defname_size +# define FAB_OR_NAML_FNA naml$l_long_filename +# define FAB_OR_NAML_FNS naml$l_long_filename_size +# define NAMX_ESA naml$l_long_expand +# define NAMX_ESL naml$l_long_expand_size +# define NAMX_ESS naml$l_long_expand_alloc +# define NAMX_NOP naml$b_nop +# define SET_NAMX_NO_SHORT_UPCASE( nam) nam.naml$v_no_short_upcase = 1 + +# if __INITIAL_POINTER_SIZE == 64 +# define NAMX_DNA_FNA_SET(fab) fab.fab$l_dna = (__char_ptr32) -1; \ + fab.fab$l_fna = (__char_ptr32) -1; +# else /* __INITIAL_POINTER_SIZE == 64 */ +# define NAMX_DNA_FNA_SET(fab) fab.fab$l_dna = (char *) -1; \ + fab.fab$l_fna = (char *) -1; +# endif /* __INITIAL_POINTER_SIZE == 64 [else] */ + +# define NAMX_MAXRSS NAML$C_MAXRSS +# define NAMX_STRUCT NAML + +#else /* def NAML$C_MAXRSS */ + +# define CC_RMS_NAMX cc$rms_nam +# define FAB_NAMX fab$l_nam +# define FAB_OR_NAML( fab, naml) fab +# define FAB_OR_NAML_DNA fab$l_dna +# define FAB_OR_NAML_DNS fab$b_dns +# define FAB_OR_NAML_FNA fab$l_fna +# define FAB_OR_NAML_FNS fab$b_fns +# define NAMX_ESA nam$l_esa +# define NAMX_ESL nam$b_esl +# define NAMX_ESS nam$b_ess +# define NAMX_NOP nam$b_nop +# define NAMX_DNA_FNA_SET(fab) +# define NAMX_MAXRSS NAM$C_MAXRSS +# define NAMX_STRUCT NAM +# ifdef NAM$M_NO_SHORT_UPCASE +# define SET_NAMX_NO_SHORT_UPCASE( nam) naml.naml$v_no_short_upcase = 1 +# else /* def NAM$M_NO_SHORT_UPCASE */ +# define SET_NAMX_NO_SHORT_UPCASE( nam) +# endif /* def NAM$M_NO_SHORT_UPCASE [else] */ + +#endif /* def NAML$C_MAXRSS [else] */ diff --git a/libs/openssl/crypto/whrlpool/asm/wp-mmx.pl b/libs/openssl/crypto/whrlpool/asm/wp-mmx.pl new file mode 100644 index 00000000..90c2eca5 --- /dev/null +++ b/libs/openssl/crypto/whrlpool/asm/wp-mmx.pl @@ -0,0 +1,493 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. Rights for redistribution and usage in source and binary +# forms are granted according to the OpenSSL license. +# ==================================================================== +# +# whirlpool_block_mmx implementation. +# +*SCALE=\(2); # 2 or 8, that is the question:-) Value of 8 results +# in 16KB large table, which is tough on L1 cache, but eliminates +# unaligned references to it. Value of 2 results in 4KB table, but +# 7/8 of references to it are unaligned. AMD cores seem to be +# allergic to the latter, while Intel ones - to former [see the +# table]. I stick to value of 2 for two reasons: 1. smaller table +# minimizes cache trashing and thus mitigates the hazard of side- +# channel leakage similar to AES cache-timing one; 2. performance +# gap among different µ-archs is smaller. +# +# Performance table lists rounded amounts of CPU cycles spent by +# whirlpool_block_mmx routine on single 64 byte input block, i.e. +# smaller is better and asymptotic throughput can be estimated by +# multiplying 64 by CPU clock frequency and dividing by relevant +# value from the given table: +# +# $SCALE=2/8 icc8 gcc3 +# Intel P4 3200/4600 4600(*) 6400 +# Intel PIII 2900/3000 4900 5400 +# AMD K[78] 2500/1800 9900 8200(**) +# +# (*) I've sketched even non-MMX assembler, but for the record +# I've failed to beat the Intel compiler on P4, without using +# MMX that is... +# (**) ... on AMD on the other hand non-MMX assembler was observed +# to perform significantly better, but I figured this MMX +# implementation is even faster anyway, so why bother? As for +# pre-MMX AMD core[s], the improvement coefficient is more +# than likely to vary anyway and I don't know how. But the +# least I know is that gcc-generated code compiled with +# -DL_ENDIAN and -DOPENSSL_SMALL_FOOTPRINT [see C module for +# details] and optimized for Pentium was observed to perform +# *better* on Pentium 100 than unrolled non-MMX assembler +# loop... So we just say that I don't know if maintaining +# non-MMX implementation would actually pay off, but till +# opposite is proved "unlikely" is assumed. + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC,"${dir}","${dir}../../perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"wp-mmx.pl"); + +sub L() { &data_byte(@_); } +sub LL() +{ if ($SCALE==2) { &data_byte(@_); &data_byte(@_); } + elsif ($SCALE==8) { for ($i=0;$i<8;$i++) { + &data_byte(@_); + unshift(@_,pop(@_)); + } + } + else { die "unvalid SCALE value"; } +} + +sub scale() +{ if ($SCALE==2) { &lea(@_[0],&DWP(0,@_[1],@_[1])); } + elsif ($SCALE==8) { &lea(@_[0],&DWP(0,"",@_[1],8)); } + else { die "unvalid SCALE value"; } +} + +sub row() +{ if ($SCALE==2) { ((8-shift)&7); } + elsif ($SCALE==8) { (8*shift); } + else { die "unvalid SCALE value"; } +} + +$tbl="ebp"; +@mm=("mm0","mm1","mm2","mm3","mm4","mm5","mm6","mm7"); + +&function_begin_B("whirlpool_block_mmx"); + &push ("ebp"); + &push ("ebx"); + &push ("esi"); + &push ("edi"); + + &mov ("esi",&wparam(0)); # hash value + &mov ("edi",&wparam(1)); # input data stream + &mov ("ebp",&wparam(2)); # number of chunks in input + + &mov ("eax","esp"); # copy stack pointer + &sub ("esp",128+20); # allocate frame + &and ("esp",-64); # align for cache-line + + &lea ("ebx",&DWP(128,"esp")); + &mov (&DWP(0,"ebx"),"esi"); # save parameter block + &mov (&DWP(4,"ebx"),"edi"); + &mov (&DWP(8,"ebx"),"ebp"); + &mov (&DWP(16,"ebx"),"eax"); # saved stack pointer + + &call (&label("pic_point")); +&set_label("pic_point"); + &blindpop($tbl); + &lea ($tbl,&DWP(&label("table")."-".&label("pic_point"),$tbl)); + + &xor ("ecx","ecx"); + &xor ("edx","edx"); + + for($i=0;$i<8;$i++) { &movq(@mm[$i],&QWP($i*8,"esi")); } # L=H +&set_label("outerloop"); + for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esp"),@mm[$i]); } # K=L + for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"edi")); } # L^=inp + for($i=0;$i<8;$i++) { &movq(&QWP(64+$i*8,"esp"),@mm[$i]); } # S=L + + &xor ("esi","esi"); + &mov (&DWP(12,"ebx"),"esi"); # zero round counter + +&set_label("round",16); + &movq (@mm[0],&QWP(2048*$SCALE,$tbl,"esi",8)); # rc[r] + &mov ("eax",&DWP(0,"esp")); + &mov ("ebx",&DWP(4,"esp")); +for($i=0;$i<8;$i++) { + my $func = ($i==0)? \&movq : \&pxor; + &movb (&LB("ecx"),&LB("eax")); + &movb (&LB("edx"),&HB("eax")); + &scale ("esi","ecx"); + &scale ("edi","edx"); + &shr ("eax",16); + &pxor (@mm[0],&QWP(&row(0),$tbl,"esi",8)); + &$func (@mm[1],&QWP(&row(1),$tbl,"edi",8)); + &movb (&LB("ecx"),&LB("eax")); + &movb (&LB("edx"),&HB("eax")); + &mov ("eax",&DWP(($i+1)*8,"esp")); + &scale ("esi","ecx"); + &scale ("edi","edx"); + &$func (@mm[2],&QWP(&row(2),$tbl,"esi",8)); + &$func (@mm[3],&QWP(&row(3),$tbl,"edi",8)); + &movb (&LB("ecx"),&LB("ebx")); + &movb (&LB("edx"),&HB("ebx")); + &scale ("esi","ecx"); + &scale ("edi","edx"); + &shr ("ebx",16); + &$func (@mm[4],&QWP(&row(4),$tbl,"esi",8)); + &$func (@mm[5],&QWP(&row(5),$tbl,"edi",8)); + &movb (&LB("ecx"),&LB("ebx")); + &movb (&LB("edx"),&HB("ebx")); + &mov ("ebx",&DWP(($i+1)*8+4,"esp")); + &scale ("esi","ecx"); + &scale ("edi","edx"); + &$func (@mm[6],&QWP(&row(6),$tbl,"esi",8)); + &$func (@mm[7],&QWP(&row(7),$tbl,"edi",8)); + push(@mm,shift(@mm)); +} + + for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esp"),@mm[$i]); } # K=L + +for($i=0;$i<8;$i++) { + &movb (&LB("ecx"),&LB("eax")); + &movb (&LB("edx"),&HB("eax")); + &scale ("esi","ecx"); + &scale ("edi","edx"); + &shr ("eax",16); + &pxor (@mm[0],&QWP(&row(0),$tbl,"esi",8)); + &pxor (@mm[1],&QWP(&row(1),$tbl,"edi",8)); + &movb (&LB("ecx"),&LB("eax")); + &movb (&LB("edx"),&HB("eax")); + &mov ("eax",&DWP(64+($i+1)*8,"esp")) if ($i<7); + &scale ("esi","ecx"); + &scale ("edi","edx"); + &pxor (@mm[2],&QWP(&row(2),$tbl,"esi",8)); + &pxor (@mm[3],&QWP(&row(3),$tbl,"edi",8)); + &movb (&LB("ecx"),&LB("ebx")); + &movb (&LB("edx"),&HB("ebx")); + &scale ("esi","ecx"); + &scale ("edi","edx"); + &shr ("ebx",16); + &pxor (@mm[4],&QWP(&row(4),$tbl,"esi",8)); + &pxor (@mm[5],&QWP(&row(5),$tbl,"edi",8)); + &movb (&LB("ecx"),&LB("ebx")); + &movb (&LB("edx"),&HB("ebx")); + &mov ("ebx",&DWP(64+($i+1)*8+4,"esp")) if ($i<7); + &scale ("esi","ecx"); + &scale ("edi","edx"); + &pxor (@mm[6],&QWP(&row(6),$tbl,"esi",8)); + &pxor (@mm[7],&QWP(&row(7),$tbl,"edi",8)); + push(@mm,shift(@mm)); +} + &lea ("ebx",&DWP(128,"esp")); + &mov ("esi",&DWP(12,"ebx")); # pull round counter + &add ("esi",1); + &cmp ("esi",10); + &je (&label("roundsdone")); + + &mov (&DWP(12,"ebx"),"esi"); # update round counter + for($i=0;$i<8;$i++) { &movq(&QWP(64+$i*8,"esp"),@mm[$i]); } # S=L + &jmp (&label("round")); + +&set_label("roundsdone",16); + &mov ("esi",&DWP(0,"ebx")); # reload argument block + &mov ("edi",&DWP(4,"ebx")); + &mov ("eax",&DWP(8,"ebx")); + + for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"edi")); } # L^=inp + for($i=0;$i<8;$i++) { &pxor(@mm[$i],&QWP($i*8,"esi")); } # L^=H + for($i=0;$i<8;$i++) { &movq(&QWP($i*8,"esi"),@mm[$i]); } # H=L + + &lea ("edi",&DWP(64,"edi")); # inp+=64 + &sub ("eax",1); # num-- + &jz (&label("alldone")); + &mov (&DWP(4,"ebx"),"edi"); # update argument block + &mov (&DWP(8,"ebx"),"eax"); + &jmp (&label("outerloop")); + +&set_label("alldone"); + &emms (); + &mov ("esp",&DWP(16,"ebx")); # restore saved stack pointer + &pop ("edi"); + &pop ("esi"); + &pop ("ebx"); + &pop ("ebp"); + &ret (); + +&align(64); +&set_label("table"); + &LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8); + &LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26); + &LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8); + &LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb); + &LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb); + &LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11); + &LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09); + &LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d); + &LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b); + &LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff); + &LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c); + &LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e); + &LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96); + &LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30); + &LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d); + &LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8); + &LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47); + &LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35); + &LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37); + &LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a); + &LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2); + &LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c); + &LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84); + &LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80); + &LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5); + &LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3); + &LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21); + &LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c); + &LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43); + &LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29); + &LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d); + &LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5); + &LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd); + &LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8); + &LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92); + &LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e); + &LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13); + &LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23); + &LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20); + &LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44); + &LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2); + &LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf); + &LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c); + &LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a); + &LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50); + &LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9); + &LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14); + &LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9); + &LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c); + &LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f); + &LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90); + &LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07); + &LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd); + &LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3); + &LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d); + &LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78); + &LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97); + &LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02); + &LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73); + &LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7); + &LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6); + &LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2); + &LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49); + &LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56); + &LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70); + &LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd); + &LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb); + &LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71); + &LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b); + &LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf); + &LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45); + &LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a); + &LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4); + &LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58); + &LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e); + &LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f); + &LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac); + &LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0); + &LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef); + &LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6); + &LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c); + &LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12); + &LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93); + &LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde); + &LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6); + &LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1); + &LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b); + &LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f); + &LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31); + &LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8); + &LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9); + &LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc); + &LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e); + &LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b); + &LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf); + &LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59); + &LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2); + &LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77); + &LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33); + &LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4); + &LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27); + &LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb); + &LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89); + &LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32); + &LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54); + &LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d); + &LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64); + &LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d); + &LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d); + &LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f); + &LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca); + &LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7); + &LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d); + &LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce); + &LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f); + &LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f); + &LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63); + &LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a); + &LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc); + &LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82); + &LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a); + &LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48); + &LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95); + &LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf); + &LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d); + &LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0); + &LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91); + &LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8); + &LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b); + &LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00); + &LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9); + &LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e); + &LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1); + &LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6); + &LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28); + &LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3); + &LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74); + &LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe); + &LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d); + &LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea); + &LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57); + &LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38); + &LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad); + &LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4); + &LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda); + &LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7); + &LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb); + &LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9); + &LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a); + &LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03); + &LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a); + &LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e); + &LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60); + &LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc); + &LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46); + &LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f); + &LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76); + &LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa); + &LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36); + &LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae); + &LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b); + &LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85); + &LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e); + &LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7); + &LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55); + &LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a); + &LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81); + &LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52); + &LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62); + &LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3); + &LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10); + &LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab); + &LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0); + &LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5); + &LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec); + &LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16); + &LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94); + &LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f); + &LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5); + &LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98); + &LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17); + &LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4); + &LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1); + &LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e); + &LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42); + &LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34); + &LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08); + &LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee); + &LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61); + &LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1); + &LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f); + &LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24); + &LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3); + &LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25); + &LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22); + &LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65); + &LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79); + &LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69); + &LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9); + &LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19); + &LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe); + &LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a); + &LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0); + &LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99); + &LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83); + &LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04); + &LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66); + &LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0); + &LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1); + &LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd); + &LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40); + &LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c); + &LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18); + &LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b); + &LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51); + &LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05); + &LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c); + &LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39); + &LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa); + &LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b); + &LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc); + &LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e); + &LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0); + &LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88); + &LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67); + &LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a); + &LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87); + &LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1); + &LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72); + &LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53); + &LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01); + &LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b); + &LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4); + &LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3); + &LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15); + &LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c); + &LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5); + &LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5); + &LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4); + &LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba); + &LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6); + &LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7); + &LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06); + &LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41); + &LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7); + &LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f); + &LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e); + &LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6); + &LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2); + &LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68); + &LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c); + &LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed); + &LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75); + &LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86); + &LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b); + &LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2); + + &L(0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f); # rc[ROUNDS] + &L(0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52); + &L(0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35); + &L(0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57); + &L(0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda); + &L(0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85); + &L(0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67); + &L(0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8); + &L(0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e); + &L(0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33); + +&function_end_B("whirlpool_block_mmx"); +&asm_finish(); diff --git a/libs/openssl/crypto/whrlpool/asm/wp-x86_64.pl b/libs/openssl/crypto/whrlpool/asm/wp-x86_64.pl new file mode 100644 index 00000000..24b2ff60 --- /dev/null +++ b/libs/openssl/crypto/whrlpool/asm/wp-x86_64.pl @@ -0,0 +1,590 @@ +#!/usr/bin/env perl +# +# ==================================================================== +# Written by Andy Polyakov for the OpenSSL +# project. Rights for redistribution and usage in source and binary +# forms are granted according to the OpenSSL license. +# ==================================================================== +# +# whirlpool_block for x86_64. +# +# 2500 cycles per 64-byte input block on AMD64, which is *identical* +# to 32-bit MMX version executed on same CPU. So why did I bother? +# Well, it's faster than gcc 3.3.2 generated code by over 50%, and +# over 80% faster than PathScale 1.4, an "ambitious" commercial +# compiler. Furthermore it surpasses gcc 3.4.3 by 170% and Sun Studio +# 10 - by 360%[!]... What is it with x86_64 compilers? It's not the +# first example when they fail to generate more optimal code, when +# I believe they had *all* chances to... +# +# Note that register and stack frame layout are virtually identical +# to 32-bit MMX version, except that %r8-15 are used instead of +# %mm0-8. You can even notice that K[i] and S[i] are loaded to +# %eax:%ebx as pair of 32-bit values and not as single 64-bit one. +# This is done in order to avoid 64-bit shift penalties on Intel +# EM64T core. Speaking of which! I bet it's possible to improve +# Opteron performance by compressing the table to 2KB and replacing +# unaligned references with complementary rotations [which would +# incidentally replace lea instructions], but it would definitely +# just "kill" EM64T, because it has only 1 shifter/rotator [against +# 3 on Opteron] and which is *unacceptably* slow with 64-bit +# operand. + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; my $dir=$1; my $xlate; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}../../perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +sub L() { $code.=".byte ".join(',',@_)."\n"; } +sub LL(){ $code.=".byte ".join(',',@_).",".join(',',@_)."\n"; } + +@mm=("%r8","%r9","%r10","%r11","%r12","%r13","%r14","%r15"); + +$func="whirlpool_block"; +$table=".Ltable"; + +$code=<<___; +.text + +.globl $func +.type $func,\@function,3 +.align 16 +$func: + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + + mov %rsp,%r11 + sub \$128+40,%rsp + and \$-64,%rsp + + lea 128(%rsp),%r10 + mov %rdi,0(%r10) # save parameter block + mov %rsi,8(%r10) + mov %rdx,16(%r10) + mov %r11,32(%r10) # saved stack pointer +.Lprologue: + + mov %r10,%rbx + lea $table(%rip),%rbp + + xor %rcx,%rcx + xor %rdx,%rdx +___ +for($i=0;$i<8;$i++) { $code.="mov $i*8(%rdi),@mm[$i]\n"; } # L=H +$code.=".Louterloop:\n"; +for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rsp)\n"; } # K=L +for($i=0;$i<8;$i++) { $code.="xor $i*8(%rsi),@mm[$i]\n"; } # L^=inp +for($i=0;$i<8;$i++) { $code.="mov @mm[$i],64+$i*8(%rsp)\n"; } # S=L +$code.=<<___; + xor %rsi,%rsi + mov %rsi,24(%rbx) # zero round counter +.align 16 +.Lround: + mov 4096(%rbp,%rsi,8),@mm[0] # rc[r] + mov 0(%rsp),%eax + mov 4(%rsp),%ebx +___ +for($i=0;$i<8;$i++) { + my $func = ($i==0)? "mov" : "xor"; + $code.=<<___; + mov %al,%cl + mov %ah,%dl + lea (%rcx,%rcx),%rsi + lea (%rdx,%rdx),%rdi + shr \$16,%eax + xor 0(%rbp,%rsi,8),@mm[0] + $func 7(%rbp,%rdi,8),@mm[1] + mov %al,%cl + mov %ah,%dl + mov $i*8+8(%rsp),%eax # ($i+1)*8 + lea (%rcx,%rcx),%rsi + lea (%rdx,%rdx),%rdi + $func 6(%rbp,%rsi,8),@mm[2] + $func 5(%rbp,%rdi,8),@mm[3] + mov %bl,%cl + mov %bh,%dl + lea (%rcx,%rcx),%rsi + lea (%rdx,%rdx),%rdi + shr \$16,%ebx + $func 4(%rbp,%rsi,8),@mm[4] + $func 3(%rbp,%rdi,8),@mm[5] + mov %bl,%cl + mov %bh,%dl + mov $i*8+8+4(%rsp),%ebx # ($i+1)*8+4 + lea (%rcx,%rcx),%rsi + lea (%rdx,%rdx),%rdi + $func 2(%rbp,%rsi,8),@mm[6] + $func 1(%rbp,%rdi,8),@mm[7] +___ + push(@mm,shift(@mm)); +} +for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rsp)\n"; } # K=L +for($i=0;$i<8;$i++) { + $code.=<<___; + mov %al,%cl + mov %ah,%dl + lea (%rcx,%rcx),%rsi + lea (%rdx,%rdx),%rdi + shr \$16,%eax + xor 0(%rbp,%rsi,8),@mm[0] + xor 7(%rbp,%rdi,8),@mm[1] + mov %al,%cl + mov %ah,%dl + `"mov 64+$i*8+8(%rsp),%eax" if($i<7);` # 64+($i+1)*8 + lea (%rcx,%rcx),%rsi + lea (%rdx,%rdx),%rdi + xor 6(%rbp,%rsi,8),@mm[2] + xor 5(%rbp,%rdi,8),@mm[3] + mov %bl,%cl + mov %bh,%dl + lea (%rcx,%rcx),%rsi + lea (%rdx,%rdx),%rdi + shr \$16,%ebx + xor 4(%rbp,%rsi,8),@mm[4] + xor 3(%rbp,%rdi,8),@mm[5] + mov %bl,%cl + mov %bh,%dl + `"mov 64+$i*8+8+4(%rsp),%ebx" if($i<7);` # 64+($i+1)*8+4 + lea (%rcx,%rcx),%rsi + lea (%rdx,%rdx),%rdi + xor 2(%rbp,%rsi,8),@mm[6] + xor 1(%rbp,%rdi,8),@mm[7] +___ + push(@mm,shift(@mm)); +} +$code.=<<___; + lea 128(%rsp),%rbx + mov 24(%rbx),%rsi # pull round counter + add \$1,%rsi + cmp \$10,%rsi + je .Lroundsdone + + mov %rsi,24(%rbx) # update round counter +___ +for($i=0;$i<8;$i++) { $code.="mov @mm[$i],64+$i*8(%rsp)\n"; } # S=L +$code.=<<___; + jmp .Lround +.align 16 +.Lroundsdone: + mov 0(%rbx),%rdi # reload argument block + mov 8(%rbx),%rsi + mov 16(%rbx),%rax +___ +for($i=0;$i<8;$i++) { $code.="xor $i*8(%rsi),@mm[$i]\n"; } # L^=inp +for($i=0;$i<8;$i++) { $code.="xor $i*8(%rdi),@mm[$i]\n"; } # L^=H +for($i=0;$i<8;$i++) { $code.="mov @mm[$i],$i*8(%rdi)\n"; } # H=L +$code.=<<___; + lea 64(%rsi),%rsi # inp+=64 + sub \$1,%rax # num-- + jz .Lalldone + mov %rsi,8(%rbx) # update parameter block + mov %rax,16(%rbx) + jmp .Louterloop +.Lalldone: + mov 32(%rbx),%rsi # restore saved pointer + mov (%rsi),%r15 + mov 8(%rsi),%r14 + mov 16(%rsi),%r13 + mov 24(%rsi),%r12 + mov 32(%rsi),%rbp + mov 40(%rsi),%rbx + lea 48(%rsi),%rsp +.Lepilogue: + ret +.size $func,.-$func + +.align 64 +.type $table,\@object +$table: +___ + &LL(0x18,0x18,0x60,0x18,0xc0,0x78,0x30,0xd8); + &LL(0x23,0x23,0x8c,0x23,0x05,0xaf,0x46,0x26); + &LL(0xc6,0xc6,0x3f,0xc6,0x7e,0xf9,0x91,0xb8); + &LL(0xe8,0xe8,0x87,0xe8,0x13,0x6f,0xcd,0xfb); + &LL(0x87,0x87,0x26,0x87,0x4c,0xa1,0x13,0xcb); + &LL(0xb8,0xb8,0xda,0xb8,0xa9,0x62,0x6d,0x11); + &LL(0x01,0x01,0x04,0x01,0x08,0x05,0x02,0x09); + &LL(0x4f,0x4f,0x21,0x4f,0x42,0x6e,0x9e,0x0d); + &LL(0x36,0x36,0xd8,0x36,0xad,0xee,0x6c,0x9b); + &LL(0xa6,0xa6,0xa2,0xa6,0x59,0x04,0x51,0xff); + &LL(0xd2,0xd2,0x6f,0xd2,0xde,0xbd,0xb9,0x0c); + &LL(0xf5,0xf5,0xf3,0xf5,0xfb,0x06,0xf7,0x0e); + &LL(0x79,0x79,0xf9,0x79,0xef,0x80,0xf2,0x96); + &LL(0x6f,0x6f,0xa1,0x6f,0x5f,0xce,0xde,0x30); + &LL(0x91,0x91,0x7e,0x91,0xfc,0xef,0x3f,0x6d); + &LL(0x52,0x52,0x55,0x52,0xaa,0x07,0xa4,0xf8); + &LL(0x60,0x60,0x9d,0x60,0x27,0xfd,0xc0,0x47); + &LL(0xbc,0xbc,0xca,0xbc,0x89,0x76,0x65,0x35); + &LL(0x9b,0x9b,0x56,0x9b,0xac,0xcd,0x2b,0x37); + &LL(0x8e,0x8e,0x02,0x8e,0x04,0x8c,0x01,0x8a); + &LL(0xa3,0xa3,0xb6,0xa3,0x71,0x15,0x5b,0xd2); + &LL(0x0c,0x0c,0x30,0x0c,0x60,0x3c,0x18,0x6c); + &LL(0x7b,0x7b,0xf1,0x7b,0xff,0x8a,0xf6,0x84); + &LL(0x35,0x35,0xd4,0x35,0xb5,0xe1,0x6a,0x80); + &LL(0x1d,0x1d,0x74,0x1d,0xe8,0x69,0x3a,0xf5); + &LL(0xe0,0xe0,0xa7,0xe0,0x53,0x47,0xdd,0xb3); + &LL(0xd7,0xd7,0x7b,0xd7,0xf6,0xac,0xb3,0x21); + &LL(0xc2,0xc2,0x2f,0xc2,0x5e,0xed,0x99,0x9c); + &LL(0x2e,0x2e,0xb8,0x2e,0x6d,0x96,0x5c,0x43); + &LL(0x4b,0x4b,0x31,0x4b,0x62,0x7a,0x96,0x29); + &LL(0xfe,0xfe,0xdf,0xfe,0xa3,0x21,0xe1,0x5d); + &LL(0x57,0x57,0x41,0x57,0x82,0x16,0xae,0xd5); + &LL(0x15,0x15,0x54,0x15,0xa8,0x41,0x2a,0xbd); + &LL(0x77,0x77,0xc1,0x77,0x9f,0xb6,0xee,0xe8); + &LL(0x37,0x37,0xdc,0x37,0xa5,0xeb,0x6e,0x92); + &LL(0xe5,0xe5,0xb3,0xe5,0x7b,0x56,0xd7,0x9e); + &LL(0x9f,0x9f,0x46,0x9f,0x8c,0xd9,0x23,0x13); + &LL(0xf0,0xf0,0xe7,0xf0,0xd3,0x17,0xfd,0x23); + &LL(0x4a,0x4a,0x35,0x4a,0x6a,0x7f,0x94,0x20); + &LL(0xda,0xda,0x4f,0xda,0x9e,0x95,0xa9,0x44); + &LL(0x58,0x58,0x7d,0x58,0xfa,0x25,0xb0,0xa2); + &LL(0xc9,0xc9,0x03,0xc9,0x06,0xca,0x8f,0xcf); + &LL(0x29,0x29,0xa4,0x29,0x55,0x8d,0x52,0x7c); + &LL(0x0a,0x0a,0x28,0x0a,0x50,0x22,0x14,0x5a); + &LL(0xb1,0xb1,0xfe,0xb1,0xe1,0x4f,0x7f,0x50); + &LL(0xa0,0xa0,0xba,0xa0,0x69,0x1a,0x5d,0xc9); + &LL(0x6b,0x6b,0xb1,0x6b,0x7f,0xda,0xd6,0x14); + &LL(0x85,0x85,0x2e,0x85,0x5c,0xab,0x17,0xd9); + &LL(0xbd,0xbd,0xce,0xbd,0x81,0x73,0x67,0x3c); + &LL(0x5d,0x5d,0x69,0x5d,0xd2,0x34,0xba,0x8f); + &LL(0x10,0x10,0x40,0x10,0x80,0x50,0x20,0x90); + &LL(0xf4,0xf4,0xf7,0xf4,0xf3,0x03,0xf5,0x07); + &LL(0xcb,0xcb,0x0b,0xcb,0x16,0xc0,0x8b,0xdd); + &LL(0x3e,0x3e,0xf8,0x3e,0xed,0xc6,0x7c,0xd3); + &LL(0x05,0x05,0x14,0x05,0x28,0x11,0x0a,0x2d); + &LL(0x67,0x67,0x81,0x67,0x1f,0xe6,0xce,0x78); + &LL(0xe4,0xe4,0xb7,0xe4,0x73,0x53,0xd5,0x97); + &LL(0x27,0x27,0x9c,0x27,0x25,0xbb,0x4e,0x02); + &LL(0x41,0x41,0x19,0x41,0x32,0x58,0x82,0x73); + &LL(0x8b,0x8b,0x16,0x8b,0x2c,0x9d,0x0b,0xa7); + &LL(0xa7,0xa7,0xa6,0xa7,0x51,0x01,0x53,0xf6); + &LL(0x7d,0x7d,0xe9,0x7d,0xcf,0x94,0xfa,0xb2); + &LL(0x95,0x95,0x6e,0x95,0xdc,0xfb,0x37,0x49); + &LL(0xd8,0xd8,0x47,0xd8,0x8e,0x9f,0xad,0x56); + &LL(0xfb,0xfb,0xcb,0xfb,0x8b,0x30,0xeb,0x70); + &LL(0xee,0xee,0x9f,0xee,0x23,0x71,0xc1,0xcd); + &LL(0x7c,0x7c,0xed,0x7c,0xc7,0x91,0xf8,0xbb); + &LL(0x66,0x66,0x85,0x66,0x17,0xe3,0xcc,0x71); + &LL(0xdd,0xdd,0x53,0xdd,0xa6,0x8e,0xa7,0x7b); + &LL(0x17,0x17,0x5c,0x17,0xb8,0x4b,0x2e,0xaf); + &LL(0x47,0x47,0x01,0x47,0x02,0x46,0x8e,0x45); + &LL(0x9e,0x9e,0x42,0x9e,0x84,0xdc,0x21,0x1a); + &LL(0xca,0xca,0x0f,0xca,0x1e,0xc5,0x89,0xd4); + &LL(0x2d,0x2d,0xb4,0x2d,0x75,0x99,0x5a,0x58); + &LL(0xbf,0xbf,0xc6,0xbf,0x91,0x79,0x63,0x2e); + &LL(0x07,0x07,0x1c,0x07,0x38,0x1b,0x0e,0x3f); + &LL(0xad,0xad,0x8e,0xad,0x01,0x23,0x47,0xac); + &LL(0x5a,0x5a,0x75,0x5a,0xea,0x2f,0xb4,0xb0); + &LL(0x83,0x83,0x36,0x83,0x6c,0xb5,0x1b,0xef); + &LL(0x33,0x33,0xcc,0x33,0x85,0xff,0x66,0xb6); + &LL(0x63,0x63,0x91,0x63,0x3f,0xf2,0xc6,0x5c); + &LL(0x02,0x02,0x08,0x02,0x10,0x0a,0x04,0x12); + &LL(0xaa,0xaa,0x92,0xaa,0x39,0x38,0x49,0x93); + &LL(0x71,0x71,0xd9,0x71,0xaf,0xa8,0xe2,0xde); + &LL(0xc8,0xc8,0x07,0xc8,0x0e,0xcf,0x8d,0xc6); + &LL(0x19,0x19,0x64,0x19,0xc8,0x7d,0x32,0xd1); + &LL(0x49,0x49,0x39,0x49,0x72,0x70,0x92,0x3b); + &LL(0xd9,0xd9,0x43,0xd9,0x86,0x9a,0xaf,0x5f); + &LL(0xf2,0xf2,0xef,0xf2,0xc3,0x1d,0xf9,0x31); + &LL(0xe3,0xe3,0xab,0xe3,0x4b,0x48,0xdb,0xa8); + &LL(0x5b,0x5b,0x71,0x5b,0xe2,0x2a,0xb6,0xb9); + &LL(0x88,0x88,0x1a,0x88,0x34,0x92,0x0d,0xbc); + &LL(0x9a,0x9a,0x52,0x9a,0xa4,0xc8,0x29,0x3e); + &LL(0x26,0x26,0x98,0x26,0x2d,0xbe,0x4c,0x0b); + &LL(0x32,0x32,0xc8,0x32,0x8d,0xfa,0x64,0xbf); + &LL(0xb0,0xb0,0xfa,0xb0,0xe9,0x4a,0x7d,0x59); + &LL(0xe9,0xe9,0x83,0xe9,0x1b,0x6a,0xcf,0xf2); + &LL(0x0f,0x0f,0x3c,0x0f,0x78,0x33,0x1e,0x77); + &LL(0xd5,0xd5,0x73,0xd5,0xe6,0xa6,0xb7,0x33); + &LL(0x80,0x80,0x3a,0x80,0x74,0xba,0x1d,0xf4); + &LL(0xbe,0xbe,0xc2,0xbe,0x99,0x7c,0x61,0x27); + &LL(0xcd,0xcd,0x13,0xcd,0x26,0xde,0x87,0xeb); + &LL(0x34,0x34,0xd0,0x34,0xbd,0xe4,0x68,0x89); + &LL(0x48,0x48,0x3d,0x48,0x7a,0x75,0x90,0x32); + &LL(0xff,0xff,0xdb,0xff,0xab,0x24,0xe3,0x54); + &LL(0x7a,0x7a,0xf5,0x7a,0xf7,0x8f,0xf4,0x8d); + &LL(0x90,0x90,0x7a,0x90,0xf4,0xea,0x3d,0x64); + &LL(0x5f,0x5f,0x61,0x5f,0xc2,0x3e,0xbe,0x9d); + &LL(0x20,0x20,0x80,0x20,0x1d,0xa0,0x40,0x3d); + &LL(0x68,0x68,0xbd,0x68,0x67,0xd5,0xd0,0x0f); + &LL(0x1a,0x1a,0x68,0x1a,0xd0,0x72,0x34,0xca); + &LL(0xae,0xae,0x82,0xae,0x19,0x2c,0x41,0xb7); + &LL(0xb4,0xb4,0xea,0xb4,0xc9,0x5e,0x75,0x7d); + &LL(0x54,0x54,0x4d,0x54,0x9a,0x19,0xa8,0xce); + &LL(0x93,0x93,0x76,0x93,0xec,0xe5,0x3b,0x7f); + &LL(0x22,0x22,0x88,0x22,0x0d,0xaa,0x44,0x2f); + &LL(0x64,0x64,0x8d,0x64,0x07,0xe9,0xc8,0x63); + &LL(0xf1,0xf1,0xe3,0xf1,0xdb,0x12,0xff,0x2a); + &LL(0x73,0x73,0xd1,0x73,0xbf,0xa2,0xe6,0xcc); + &LL(0x12,0x12,0x48,0x12,0x90,0x5a,0x24,0x82); + &LL(0x40,0x40,0x1d,0x40,0x3a,0x5d,0x80,0x7a); + &LL(0x08,0x08,0x20,0x08,0x40,0x28,0x10,0x48); + &LL(0xc3,0xc3,0x2b,0xc3,0x56,0xe8,0x9b,0x95); + &LL(0xec,0xec,0x97,0xec,0x33,0x7b,0xc5,0xdf); + &LL(0xdb,0xdb,0x4b,0xdb,0x96,0x90,0xab,0x4d); + &LL(0xa1,0xa1,0xbe,0xa1,0x61,0x1f,0x5f,0xc0); + &LL(0x8d,0x8d,0x0e,0x8d,0x1c,0x83,0x07,0x91); + &LL(0x3d,0x3d,0xf4,0x3d,0xf5,0xc9,0x7a,0xc8); + &LL(0x97,0x97,0x66,0x97,0xcc,0xf1,0x33,0x5b); + &LL(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00); + &LL(0xcf,0xcf,0x1b,0xcf,0x36,0xd4,0x83,0xf9); + &LL(0x2b,0x2b,0xac,0x2b,0x45,0x87,0x56,0x6e); + &LL(0x76,0x76,0xc5,0x76,0x97,0xb3,0xec,0xe1); + &LL(0x82,0x82,0x32,0x82,0x64,0xb0,0x19,0xe6); + &LL(0xd6,0xd6,0x7f,0xd6,0xfe,0xa9,0xb1,0x28); + &LL(0x1b,0x1b,0x6c,0x1b,0xd8,0x77,0x36,0xc3); + &LL(0xb5,0xb5,0xee,0xb5,0xc1,0x5b,0x77,0x74); + &LL(0xaf,0xaf,0x86,0xaf,0x11,0x29,0x43,0xbe); + &LL(0x6a,0x6a,0xb5,0x6a,0x77,0xdf,0xd4,0x1d); + &LL(0x50,0x50,0x5d,0x50,0xba,0x0d,0xa0,0xea); + &LL(0x45,0x45,0x09,0x45,0x12,0x4c,0x8a,0x57); + &LL(0xf3,0xf3,0xeb,0xf3,0xcb,0x18,0xfb,0x38); + &LL(0x30,0x30,0xc0,0x30,0x9d,0xf0,0x60,0xad); + &LL(0xef,0xef,0x9b,0xef,0x2b,0x74,0xc3,0xc4); + &LL(0x3f,0x3f,0xfc,0x3f,0xe5,0xc3,0x7e,0xda); + &LL(0x55,0x55,0x49,0x55,0x92,0x1c,0xaa,0xc7); + &LL(0xa2,0xa2,0xb2,0xa2,0x79,0x10,0x59,0xdb); + &LL(0xea,0xea,0x8f,0xea,0x03,0x65,0xc9,0xe9); + &LL(0x65,0x65,0x89,0x65,0x0f,0xec,0xca,0x6a); + &LL(0xba,0xba,0xd2,0xba,0xb9,0x68,0x69,0x03); + &LL(0x2f,0x2f,0xbc,0x2f,0x65,0x93,0x5e,0x4a); + &LL(0xc0,0xc0,0x27,0xc0,0x4e,0xe7,0x9d,0x8e); + &LL(0xde,0xde,0x5f,0xde,0xbe,0x81,0xa1,0x60); + &LL(0x1c,0x1c,0x70,0x1c,0xe0,0x6c,0x38,0xfc); + &LL(0xfd,0xfd,0xd3,0xfd,0xbb,0x2e,0xe7,0x46); + &LL(0x4d,0x4d,0x29,0x4d,0x52,0x64,0x9a,0x1f); + &LL(0x92,0x92,0x72,0x92,0xe4,0xe0,0x39,0x76); + &LL(0x75,0x75,0xc9,0x75,0x8f,0xbc,0xea,0xfa); + &LL(0x06,0x06,0x18,0x06,0x30,0x1e,0x0c,0x36); + &LL(0x8a,0x8a,0x12,0x8a,0x24,0x98,0x09,0xae); + &LL(0xb2,0xb2,0xf2,0xb2,0xf9,0x40,0x79,0x4b); + &LL(0xe6,0xe6,0xbf,0xe6,0x63,0x59,0xd1,0x85); + &LL(0x0e,0x0e,0x38,0x0e,0x70,0x36,0x1c,0x7e); + &LL(0x1f,0x1f,0x7c,0x1f,0xf8,0x63,0x3e,0xe7); + &LL(0x62,0x62,0x95,0x62,0x37,0xf7,0xc4,0x55); + &LL(0xd4,0xd4,0x77,0xd4,0xee,0xa3,0xb5,0x3a); + &LL(0xa8,0xa8,0x9a,0xa8,0x29,0x32,0x4d,0x81); + &LL(0x96,0x96,0x62,0x96,0xc4,0xf4,0x31,0x52); + &LL(0xf9,0xf9,0xc3,0xf9,0x9b,0x3a,0xef,0x62); + &LL(0xc5,0xc5,0x33,0xc5,0x66,0xf6,0x97,0xa3); + &LL(0x25,0x25,0x94,0x25,0x35,0xb1,0x4a,0x10); + &LL(0x59,0x59,0x79,0x59,0xf2,0x20,0xb2,0xab); + &LL(0x84,0x84,0x2a,0x84,0x54,0xae,0x15,0xd0); + &LL(0x72,0x72,0xd5,0x72,0xb7,0xa7,0xe4,0xc5); + &LL(0x39,0x39,0xe4,0x39,0xd5,0xdd,0x72,0xec); + &LL(0x4c,0x4c,0x2d,0x4c,0x5a,0x61,0x98,0x16); + &LL(0x5e,0x5e,0x65,0x5e,0xca,0x3b,0xbc,0x94); + &LL(0x78,0x78,0xfd,0x78,0xe7,0x85,0xf0,0x9f); + &LL(0x38,0x38,0xe0,0x38,0xdd,0xd8,0x70,0xe5); + &LL(0x8c,0x8c,0x0a,0x8c,0x14,0x86,0x05,0x98); + &LL(0xd1,0xd1,0x63,0xd1,0xc6,0xb2,0xbf,0x17); + &LL(0xa5,0xa5,0xae,0xa5,0x41,0x0b,0x57,0xe4); + &LL(0xe2,0xe2,0xaf,0xe2,0x43,0x4d,0xd9,0xa1); + &LL(0x61,0x61,0x99,0x61,0x2f,0xf8,0xc2,0x4e); + &LL(0xb3,0xb3,0xf6,0xb3,0xf1,0x45,0x7b,0x42); + &LL(0x21,0x21,0x84,0x21,0x15,0xa5,0x42,0x34); + &LL(0x9c,0x9c,0x4a,0x9c,0x94,0xd6,0x25,0x08); + &LL(0x1e,0x1e,0x78,0x1e,0xf0,0x66,0x3c,0xee); + &LL(0x43,0x43,0x11,0x43,0x22,0x52,0x86,0x61); + &LL(0xc7,0xc7,0x3b,0xc7,0x76,0xfc,0x93,0xb1); + &LL(0xfc,0xfc,0xd7,0xfc,0xb3,0x2b,0xe5,0x4f); + &LL(0x04,0x04,0x10,0x04,0x20,0x14,0x08,0x24); + &LL(0x51,0x51,0x59,0x51,0xb2,0x08,0xa2,0xe3); + &LL(0x99,0x99,0x5e,0x99,0xbc,0xc7,0x2f,0x25); + &LL(0x6d,0x6d,0xa9,0x6d,0x4f,0xc4,0xda,0x22); + &LL(0x0d,0x0d,0x34,0x0d,0x68,0x39,0x1a,0x65); + &LL(0xfa,0xfa,0xcf,0xfa,0x83,0x35,0xe9,0x79); + &LL(0xdf,0xdf,0x5b,0xdf,0xb6,0x84,0xa3,0x69); + &LL(0x7e,0x7e,0xe5,0x7e,0xd7,0x9b,0xfc,0xa9); + &LL(0x24,0x24,0x90,0x24,0x3d,0xb4,0x48,0x19); + &LL(0x3b,0x3b,0xec,0x3b,0xc5,0xd7,0x76,0xfe); + &LL(0xab,0xab,0x96,0xab,0x31,0x3d,0x4b,0x9a); + &LL(0xce,0xce,0x1f,0xce,0x3e,0xd1,0x81,0xf0); + &LL(0x11,0x11,0x44,0x11,0x88,0x55,0x22,0x99); + &LL(0x8f,0x8f,0x06,0x8f,0x0c,0x89,0x03,0x83); + &LL(0x4e,0x4e,0x25,0x4e,0x4a,0x6b,0x9c,0x04); + &LL(0xb7,0xb7,0xe6,0xb7,0xd1,0x51,0x73,0x66); + &LL(0xeb,0xeb,0x8b,0xeb,0x0b,0x60,0xcb,0xe0); + &LL(0x3c,0x3c,0xf0,0x3c,0xfd,0xcc,0x78,0xc1); + &LL(0x81,0x81,0x3e,0x81,0x7c,0xbf,0x1f,0xfd); + &LL(0x94,0x94,0x6a,0x94,0xd4,0xfe,0x35,0x40); + &LL(0xf7,0xf7,0xfb,0xf7,0xeb,0x0c,0xf3,0x1c); + &LL(0xb9,0xb9,0xde,0xb9,0xa1,0x67,0x6f,0x18); + &LL(0x13,0x13,0x4c,0x13,0x98,0x5f,0x26,0x8b); + &LL(0x2c,0x2c,0xb0,0x2c,0x7d,0x9c,0x58,0x51); + &LL(0xd3,0xd3,0x6b,0xd3,0xd6,0xb8,0xbb,0x05); + &LL(0xe7,0xe7,0xbb,0xe7,0x6b,0x5c,0xd3,0x8c); + &LL(0x6e,0x6e,0xa5,0x6e,0x57,0xcb,0xdc,0x39); + &LL(0xc4,0xc4,0x37,0xc4,0x6e,0xf3,0x95,0xaa); + &LL(0x03,0x03,0x0c,0x03,0x18,0x0f,0x06,0x1b); + &LL(0x56,0x56,0x45,0x56,0x8a,0x13,0xac,0xdc); + &LL(0x44,0x44,0x0d,0x44,0x1a,0x49,0x88,0x5e); + &LL(0x7f,0x7f,0xe1,0x7f,0xdf,0x9e,0xfe,0xa0); + &LL(0xa9,0xa9,0x9e,0xa9,0x21,0x37,0x4f,0x88); + &LL(0x2a,0x2a,0xa8,0x2a,0x4d,0x82,0x54,0x67); + &LL(0xbb,0xbb,0xd6,0xbb,0xb1,0x6d,0x6b,0x0a); + &LL(0xc1,0xc1,0x23,0xc1,0x46,0xe2,0x9f,0x87); + &LL(0x53,0x53,0x51,0x53,0xa2,0x02,0xa6,0xf1); + &LL(0xdc,0xdc,0x57,0xdc,0xae,0x8b,0xa5,0x72); + &LL(0x0b,0x0b,0x2c,0x0b,0x58,0x27,0x16,0x53); + &LL(0x9d,0x9d,0x4e,0x9d,0x9c,0xd3,0x27,0x01); + &LL(0x6c,0x6c,0xad,0x6c,0x47,0xc1,0xd8,0x2b); + &LL(0x31,0x31,0xc4,0x31,0x95,0xf5,0x62,0xa4); + &LL(0x74,0x74,0xcd,0x74,0x87,0xb9,0xe8,0xf3); + &LL(0xf6,0xf6,0xff,0xf6,0xe3,0x09,0xf1,0x15); + &LL(0x46,0x46,0x05,0x46,0x0a,0x43,0x8c,0x4c); + &LL(0xac,0xac,0x8a,0xac,0x09,0x26,0x45,0xa5); + &LL(0x89,0x89,0x1e,0x89,0x3c,0x97,0x0f,0xb5); + &LL(0x14,0x14,0x50,0x14,0xa0,0x44,0x28,0xb4); + &LL(0xe1,0xe1,0xa3,0xe1,0x5b,0x42,0xdf,0xba); + &LL(0x16,0x16,0x58,0x16,0xb0,0x4e,0x2c,0xa6); + &LL(0x3a,0x3a,0xe8,0x3a,0xcd,0xd2,0x74,0xf7); + &LL(0x69,0x69,0xb9,0x69,0x6f,0xd0,0xd2,0x06); + &LL(0x09,0x09,0x24,0x09,0x48,0x2d,0x12,0x41); + &LL(0x70,0x70,0xdd,0x70,0xa7,0xad,0xe0,0xd7); + &LL(0xb6,0xb6,0xe2,0xb6,0xd9,0x54,0x71,0x6f); + &LL(0xd0,0xd0,0x67,0xd0,0xce,0xb7,0xbd,0x1e); + &LL(0xed,0xed,0x93,0xed,0x3b,0x7e,0xc7,0xd6); + &LL(0xcc,0xcc,0x17,0xcc,0x2e,0xdb,0x85,0xe2); + &LL(0x42,0x42,0x15,0x42,0x2a,0x57,0x84,0x68); + &LL(0x98,0x98,0x5a,0x98,0xb4,0xc2,0x2d,0x2c); + &LL(0xa4,0xa4,0xaa,0xa4,0x49,0x0e,0x55,0xed); + &LL(0x28,0x28,0xa0,0x28,0x5d,0x88,0x50,0x75); + &LL(0x5c,0x5c,0x6d,0x5c,0xda,0x31,0xb8,0x86); + &LL(0xf8,0xf8,0xc7,0xf8,0x93,0x3f,0xed,0x6b); + &LL(0x86,0x86,0x22,0x86,0x44,0xa4,0x11,0xc2); + + &L(0x18,0x23,0xc6,0xe8,0x87,0xb8,0x01,0x4f); # rc[ROUNDS] + &L(0x36,0xa6,0xd2,0xf5,0x79,0x6f,0x91,0x52); + &L(0x60,0xbc,0x9b,0x8e,0xa3,0x0c,0x7b,0x35); + &L(0x1d,0xe0,0xd7,0xc2,0x2e,0x4b,0xfe,0x57); + &L(0x15,0x77,0x37,0xe5,0x9f,0xf0,0x4a,0xda); + &L(0x58,0xc9,0x29,0x0a,0xb1,0xa0,0x6b,0x85); + &L(0xbd,0x5d,0x10,0xf4,0xcb,0x3e,0x05,0x67); + &L(0xe4,0x27,0x41,0x8b,0xa7,0x7d,0x95,0xd8); + &L(0xfb,0xee,0x7c,0x66,0xdd,0x17,0x47,0x9e); + &L(0xca,0x2d,0xbf,0x07,0xad,0x5a,0x83,0x33); + +# EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, +# CONTEXT *context,DISPATCHER_CONTEXT *disp) +if ($win64) { +$rec="%rcx"; +$frame="%rdx"; +$context="%r8"; +$disp="%r9"; + +$code.=<<___; +.extern __imp_RtlVirtualUnwind +.type se_handler,\@abi-omnipotent +.align 16 +se_handler: + push %rsi + push %rdi + push %rbx + push %rbp + push %r12 + push %r13 + push %r14 + push %r15 + pushfq + sub \$64,%rsp + + mov 120($context),%rax # pull context->Rax + mov 248($context),%rbx # pull context->Rip + + lea .Lprologue(%rip),%r10 + cmp %r10,%rbx # context->Rip<.Lprologue + jb .Lin_prologue + + mov 152($context),%rax # pull context->Rsp + + lea .Lepilogue(%rip),%r10 + cmp %r10,%rbx # context->Rip>=.Lepilogue + jae .Lin_prologue + + mov 128+32(%rax),%rax # pull saved stack pointer + lea 48(%rax),%rax + + mov -8(%rax),%rbx + mov -16(%rax),%rbp + mov -24(%rax),%r12 + mov -32(%rax),%r13 + mov -40(%rax),%r14 + mov -48(%rax),%r15 + mov %rbx,144($context) # restore context->Rbx + mov %rbp,160($context) # restore context->Rbp + mov %r12,216($context) # restore context->R12 + mov %r13,224($context) # restore context->R13 + mov %r14,232($context) # restore context->R14 + mov %r15,240($context) # restore context->R15 + +.Lin_prologue: + mov 8(%rax),%rdi + mov 16(%rax),%rsi + mov %rax,152($context) # restore context->Rsp + mov %rsi,168($context) # restore context->Rsi + mov %rdi,176($context) # restore context->Rdi + + mov 40($disp),%rdi # disp->ContextRecord + mov $context,%rsi # context + mov \$154,%ecx # sizeof(CONTEXT) + .long 0xa548f3fc # cld; rep movsq + + mov $disp,%rsi + xor %rcx,%rcx # arg1, UNW_FLAG_NHANDLER + mov 8(%rsi),%rdx # arg2, disp->ImageBase + mov 0(%rsi),%r8 # arg3, disp->ControlPc + mov 16(%rsi),%r9 # arg4, disp->FunctionEntry + mov 40(%rsi),%r10 # disp->ContextRecord + lea 56(%rsi),%r11 # &disp->HandlerData + lea 24(%rsi),%r12 # &disp->EstablisherFrame + mov %r10,32(%rsp) # arg5 + mov %r11,40(%rsp) # arg6 + mov %r12,48(%rsp) # arg7 + mov %rcx,56(%rsp) # arg8, (NULL) + call *__imp_RtlVirtualUnwind(%rip) + + mov \$1,%eax # ExceptionContinueSearch + add \$64,%rsp + popfq + pop %r15 + pop %r14 + pop %r13 + pop %r12 + pop %rbp + pop %rbx + pop %rdi + pop %rsi + ret +.size se_handler,.-se_handler + +.section .pdata +.align 4 + .rva .LSEH_begin_$func + .rva .LSEH_end_$func + .rva .LSEH_info_$func + +.section .xdata +.align 8 +.LSEH_info_$func: + .byte 9,0,0,0 + .rva se_handler +___ +} + +$code =~ s/\`([^\`]*)\`/eval $1/gem; +print $code; +close STDOUT; diff --git a/libs/openssl/crypto/whrlpool/whrlpool.h b/libs/openssl/crypto/whrlpool/whrlpool.h new file mode 100644 index 00000000..73c749da --- /dev/null +++ b/libs/openssl/crypto/whrlpool/whrlpool.h @@ -0,0 +1,41 @@ +#ifndef HEADER_WHRLPOOL_H +# define HEADER_WHRLPOOL_H + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define WHIRLPOOL_DIGEST_LENGTH (512/8) +# define WHIRLPOOL_BBLOCK 512 +# define WHIRLPOOL_COUNTER (256/8) + +typedef struct { + union { + unsigned char c[WHIRLPOOL_DIGEST_LENGTH]; + /* double q is here to ensure 64-bit alignment */ + double q[WHIRLPOOL_DIGEST_LENGTH / sizeof(double)]; + } H; + unsigned char data[WHIRLPOOL_BBLOCK / 8]; + unsigned int bitoff; + size_t bitlen[WHIRLPOOL_COUNTER / sizeof(size_t)]; +} WHIRLPOOL_CTX; + +# ifndef OPENSSL_NO_WHIRLPOOL +# ifdef OPENSSL_FIPS +int private_WHIRLPOOL_Init(WHIRLPOOL_CTX *c); +# endif +int WHIRLPOOL_Init(WHIRLPOOL_CTX *c); +int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *inp, size_t bytes); +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *inp, size_t bits); +int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c); +unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md); +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/crypto/whrlpool/wp_block.c b/libs/openssl/crypto/whrlpool/wp_block.c new file mode 100644 index 00000000..920430bd --- /dev/null +++ b/libs/openssl/crypto/whrlpool/wp_block.c @@ -0,0 +1,780 @@ +/** + * The Whirlpool hashing function. + * + *

+ * References + * + *

+ * The Whirlpool algorithm was developed by + * Paulo S. L. M. Barreto and + * Vincent Rijmen. + * + * See + * P.S.L.M. Barreto, V. Rijmen, + * ``The Whirlpool hashing function,'' + * NESSIE submission, 2000 (tweaked version, 2001), + * + * + * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and + * Vincent Rijmen. Lookup "reference implementations" on + * + * + * ============================================================================= + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "wp_locl.h" +#include + +typedef unsigned char u8; +#if (defined(_WIN32) || defined(_WIN64)) && !defined(__MINGW32) +typedef unsigned __int64 u64; +#elif defined(__arch64__) +typedef unsigned long u64; +#else +typedef unsigned long long u64; +#endif + +#define ROUNDS 10 + +#define STRICT_ALIGNMENT +#if defined(__i386) || defined(__i386__) || \ + defined(__x86_64) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64) +/* + * Well, formally there're couple of other architectures, which permit + * unaligned loads, specifically those not crossing cache lines, IA-64 and + * PowerPC... + */ +# undef STRICT_ALIGNMENT +#endif + +#undef SMALL_REGISTER_BANK +#if defined(__i386) || defined(__i386__) || defined(_M_IX86) +# define SMALL_REGISTER_BANK +# if defined(WHIRLPOOL_ASM) +# ifndef OPENSSL_SMALL_FOOTPRINT +/* + * it appears that for elder non-MMX + * CPUs this is actually faster! + */ +# define OPENSSL_SMALL_FOOTPRINT +# endif +# define GO_FOR_MMX(ctx,inp,num) do { \ + extern unsigned int OPENSSL_ia32cap_P[]; \ + void whirlpool_block_mmx(void *,const void *,size_t); \ + if (!(OPENSSL_ia32cap_P[0] & (1<<23))) break; \ + whirlpool_block_mmx(ctx->H.c,inp,num); return; \ + } while (0) +# endif +#endif + +#undef ROTATE +#if defined(_MSC_VER) +# if defined(_WIN64) /* applies to both IA-64 and AMD64 */ +# pragma intrinsic(_rotl64) +# define ROTATE(a,n) _rotl64((a),n) +# endif +#elif defined(__GNUC__) && __GNUC__>=2 +# if defined(__x86_64) || defined(__x86_64__) +# if defined(L_ENDIAN) +# define ROTATE(a,n) ({ u64 ret; asm ("rolq %1,%0" \ + : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; }) +# elif defined(B_ENDIAN) + /* + * Most will argue that x86_64 is always little-endian. Well, yes, but + * then we have stratus.com who has modified gcc to "emulate" + * big-endian on x86. Is there evidence that they [or somebody else] + * won't do same for x86_64? Naturally no. And this line is waiting + * ready for that brave soul:-) + */ +# define ROTATE(a,n) ({ u64 ret; asm ("rorq %1,%0" \ + : "=r"(ret) : "J"(n),"0"(a) : "cc"); ret; }) +# endif +# elif defined(__ia64) || defined(__ia64__) +# if defined(L_ENDIAN) +# define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \ + : "=r"(ret) : "r"(a),"M"(64-(n))); ret; }) +# elif defined(B_ENDIAN) +# define ROTATE(a,n) ({ u64 ret; asm ("shrp %0=%1,%1,%2" \ + : "=r"(ret) : "r"(a),"M"(n)); ret; }) +# endif +# endif +#endif + +#if defined(OPENSSL_SMALL_FOOTPRINT) +# if !defined(ROTATE) +# if defined(L_ENDIAN) /* little-endians have to rotate left */ +# define ROTATE(i,n) ((i)<<(n) ^ (i)>>(64-n)) +# elif defined(B_ENDIAN) /* big-endians have to rotate right */ +# define ROTATE(i,n) ((i)>>(n) ^ (i)<<(64-n)) +# endif +# endif +# if defined(ROTATE) && !defined(STRICT_ALIGNMENT) +# define STRICT_ALIGNMENT /* ensure smallest table size */ +# endif +#endif + +/* + * Table size depends on STRICT_ALIGNMENT and whether or not endian- + * specific ROTATE macro is defined. If STRICT_ALIGNMENT is not + * defined, which is normally the case on x86[_64] CPUs, the table is + * 4KB large unconditionally. Otherwise if ROTATE is defined, the + * table is 2KB large, and otherwise - 16KB. 2KB table requires a + * whole bunch of additional rotations, but I'm willing to "trade," + * because 16KB table certainly trashes L1 cache. I wish all CPUs + * could handle unaligned load as 4KB table doesn't trash the cache, + * nor does it require additional rotations. + */ +/* + * Note that every Cn macro expands as two loads: one byte load and + * one quadword load. One can argue that that many single-byte loads + * is too excessive, as one could load a quadword and "milk" it for + * eight 8-bit values instead. Well, yes, but in order to do so *and* + * avoid excessive loads you have to accomodate a handful of 64-bit + * values in the register bank and issue a bunch of shifts and mask. + * It's a tradeoff: loads vs. shift and mask in big register bank[!]. + * On most CPUs eight single-byte loads are faster and I let other + * ones to depend on smart compiler to fold byte loads if beneficial. + * Hand-coded assembler would be another alternative:-) + */ +#ifdef STRICT_ALIGNMENT +# if defined(ROTATE) +# define N 1 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7 +# define C0(K,i) (Cx.q[K.c[(i)*8+0]]) +# define C1(K,i) ROTATE(Cx.q[K.c[(i)*8+1]],8) +# define C2(K,i) ROTATE(Cx.q[K.c[(i)*8+2]],16) +# define C3(K,i) ROTATE(Cx.q[K.c[(i)*8+3]],24) +# define C4(K,i) ROTATE(Cx.q[K.c[(i)*8+4]],32) +# define C5(K,i) ROTATE(Cx.q[K.c[(i)*8+5]],40) +# define C6(K,i) ROTATE(Cx.q[K.c[(i)*8+6]],48) +# define C7(K,i) ROTATE(Cx.q[K.c[(i)*8+7]],56) +# else +# define N 8 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ + c7,c0,c1,c2,c3,c4,c5,c6, \ + c6,c7,c0,c1,c2,c3,c4,c5, \ + c5,c6,c7,c0,c1,c2,c3,c4, \ + c4,c5,c6,c7,c0,c1,c2,c3, \ + c3,c4,c5,c6,c7,c0,c1,c2, \ + c2,c3,c4,c5,c6,c7,c0,c1, \ + c1,c2,c3,c4,c5,c6,c7,c0 +# define C0(K,i) (Cx.q[0+8*K.c[(i)*8+0]]) +# define C1(K,i) (Cx.q[1+8*K.c[(i)*8+1]]) +# define C2(K,i) (Cx.q[2+8*K.c[(i)*8+2]]) +# define C3(K,i) (Cx.q[3+8*K.c[(i)*8+3]]) +# define C4(K,i) (Cx.q[4+8*K.c[(i)*8+4]]) +# define C5(K,i) (Cx.q[5+8*K.c[(i)*8+5]]) +# define C6(K,i) (Cx.q[6+8*K.c[(i)*8+6]]) +# define C7(K,i) (Cx.q[7+8*K.c[(i)*8+7]]) +# endif +#else +# define N 2 +# define LL(c0,c1,c2,c3,c4,c5,c6,c7) c0,c1,c2,c3,c4,c5,c6,c7, \ + c0,c1,c2,c3,c4,c5,c6,c7 +# define C0(K,i) (((u64*)(Cx.c+0))[2*K.c[(i)*8+0]]) +# define C1(K,i) (((u64*)(Cx.c+7))[2*K.c[(i)*8+1]]) +# define C2(K,i) (((u64*)(Cx.c+6))[2*K.c[(i)*8+2]]) +# define C3(K,i) (((u64*)(Cx.c+5))[2*K.c[(i)*8+3]]) +# define C4(K,i) (((u64*)(Cx.c+4))[2*K.c[(i)*8+4]]) +# define C5(K,i) (((u64*)(Cx.c+3))[2*K.c[(i)*8+5]]) +# define C6(K,i) (((u64*)(Cx.c+2))[2*K.c[(i)*8+6]]) +# define C7(K,i) (((u64*)(Cx.c+1))[2*K.c[(i)*8+7]]) +#endif + +static const + union { + u8 c[(256 * N + ROUNDS) * sizeof(u64)]; + u64 q[(256 * N + ROUNDS)]; +} Cx = { + { + /* Note endian-neutral representation:-) */ + LL(0x18, 0x18, 0x60, 0x18, 0xc0, 0x78, 0x30, 0xd8), + LL(0x23, 0x23, 0x8c, 0x23, 0x05, 0xaf, 0x46, 0x26), + LL(0xc6, 0xc6, 0x3f, 0xc6, 0x7e, 0xf9, 0x91, 0xb8), + LL(0xe8, 0xe8, 0x87, 0xe8, 0x13, 0x6f, 0xcd, 0xfb), + LL(0x87, 0x87, 0x26, 0x87, 0x4c, 0xa1, 0x13, 0xcb), + LL(0xb8, 0xb8, 0xda, 0xb8, 0xa9, 0x62, 0x6d, 0x11), + LL(0x01, 0x01, 0x04, 0x01, 0x08, 0x05, 0x02, 0x09), + LL(0x4f, 0x4f, 0x21, 0x4f, 0x42, 0x6e, 0x9e, 0x0d), + LL(0x36, 0x36, 0xd8, 0x36, 0xad, 0xee, 0x6c, 0x9b), + LL(0xa6, 0xa6, 0xa2, 0xa6, 0x59, 0x04, 0x51, 0xff), + LL(0xd2, 0xd2, 0x6f, 0xd2, 0xde, 0xbd, 0xb9, 0x0c), + LL(0xf5, 0xf5, 0xf3, 0xf5, 0xfb, 0x06, 0xf7, 0x0e), + LL(0x79, 0x79, 0xf9, 0x79, 0xef, 0x80, 0xf2, 0x96), + LL(0x6f, 0x6f, 0xa1, 0x6f, 0x5f, 0xce, 0xde, 0x30), + LL(0x91, 0x91, 0x7e, 0x91, 0xfc, 0xef, 0x3f, 0x6d), + LL(0x52, 0x52, 0x55, 0x52, 0xaa, 0x07, 0xa4, 0xf8), + LL(0x60, 0x60, 0x9d, 0x60, 0x27, 0xfd, 0xc0, 0x47), + LL(0xbc, 0xbc, 0xca, 0xbc, 0x89, 0x76, 0x65, 0x35), + LL(0x9b, 0x9b, 0x56, 0x9b, 0xac, 0xcd, 0x2b, 0x37), + LL(0x8e, 0x8e, 0x02, 0x8e, 0x04, 0x8c, 0x01, 0x8a), + LL(0xa3, 0xa3, 0xb6, 0xa3, 0x71, 0x15, 0x5b, 0xd2), + LL(0x0c, 0x0c, 0x30, 0x0c, 0x60, 0x3c, 0x18, 0x6c), + LL(0x7b, 0x7b, 0xf1, 0x7b, 0xff, 0x8a, 0xf6, 0x84), + LL(0x35, 0x35, 0xd4, 0x35, 0xb5, 0xe1, 0x6a, 0x80), + LL(0x1d, 0x1d, 0x74, 0x1d, 0xe8, 0x69, 0x3a, 0xf5), + LL(0xe0, 0xe0, 0xa7, 0xe0, 0x53, 0x47, 0xdd, 0xb3), + LL(0xd7, 0xd7, 0x7b, 0xd7, 0xf6, 0xac, 0xb3, 0x21), + LL(0xc2, 0xc2, 0x2f, 0xc2, 0x5e, 0xed, 0x99, 0x9c), + LL(0x2e, 0x2e, 0xb8, 0x2e, 0x6d, 0x96, 0x5c, 0x43), + LL(0x4b, 0x4b, 0x31, 0x4b, 0x62, 0x7a, 0x96, 0x29), + LL(0xfe, 0xfe, 0xdf, 0xfe, 0xa3, 0x21, 0xe1, 0x5d), + LL(0x57, 0x57, 0x41, 0x57, 0x82, 0x16, 0xae, 0xd5), + LL(0x15, 0x15, 0x54, 0x15, 0xa8, 0x41, 0x2a, 0xbd), + LL(0x77, 0x77, 0xc1, 0x77, 0x9f, 0xb6, 0xee, 0xe8), + LL(0x37, 0x37, 0xdc, 0x37, 0xa5, 0xeb, 0x6e, 0x92), + LL(0xe5, 0xe5, 0xb3, 0xe5, 0x7b, 0x56, 0xd7, 0x9e), + LL(0x9f, 0x9f, 0x46, 0x9f, 0x8c, 0xd9, 0x23, 0x13), + LL(0xf0, 0xf0, 0xe7, 0xf0, 0xd3, 0x17, 0xfd, 0x23), + LL(0x4a, 0x4a, 0x35, 0x4a, 0x6a, 0x7f, 0x94, 0x20), + LL(0xda, 0xda, 0x4f, 0xda, 0x9e, 0x95, 0xa9, 0x44), + LL(0x58, 0x58, 0x7d, 0x58, 0xfa, 0x25, 0xb0, 0xa2), + LL(0xc9, 0xc9, 0x03, 0xc9, 0x06, 0xca, 0x8f, 0xcf), + LL(0x29, 0x29, 0xa4, 0x29, 0x55, 0x8d, 0x52, 0x7c), + LL(0x0a, 0x0a, 0x28, 0x0a, 0x50, 0x22, 0x14, 0x5a), + LL(0xb1, 0xb1, 0xfe, 0xb1, 0xe1, 0x4f, 0x7f, 0x50), + LL(0xa0, 0xa0, 0xba, 0xa0, 0x69, 0x1a, 0x5d, 0xc9), + LL(0x6b, 0x6b, 0xb1, 0x6b, 0x7f, 0xda, 0xd6, 0x14), + LL(0x85, 0x85, 0x2e, 0x85, 0x5c, 0xab, 0x17, 0xd9), + LL(0xbd, 0xbd, 0xce, 0xbd, 0x81, 0x73, 0x67, 0x3c), + LL(0x5d, 0x5d, 0x69, 0x5d, 0xd2, 0x34, 0xba, 0x8f), + LL(0x10, 0x10, 0x40, 0x10, 0x80, 0x50, 0x20, 0x90), + LL(0xf4, 0xf4, 0xf7, 0xf4, 0xf3, 0x03, 0xf5, 0x07), + LL(0xcb, 0xcb, 0x0b, 0xcb, 0x16, 0xc0, 0x8b, 0xdd), + LL(0x3e, 0x3e, 0xf8, 0x3e, 0xed, 0xc6, 0x7c, 0xd3), + LL(0x05, 0x05, 0x14, 0x05, 0x28, 0x11, 0x0a, 0x2d), + LL(0x67, 0x67, 0x81, 0x67, 0x1f, 0xe6, 0xce, 0x78), + LL(0xe4, 0xe4, 0xb7, 0xe4, 0x73, 0x53, 0xd5, 0x97), + LL(0x27, 0x27, 0x9c, 0x27, 0x25, 0xbb, 0x4e, 0x02), + LL(0x41, 0x41, 0x19, 0x41, 0x32, 0x58, 0x82, 0x73), + LL(0x8b, 0x8b, 0x16, 0x8b, 0x2c, 0x9d, 0x0b, 0xa7), + LL(0xa7, 0xa7, 0xa6, 0xa7, 0x51, 0x01, 0x53, 0xf6), + LL(0x7d, 0x7d, 0xe9, 0x7d, 0xcf, 0x94, 0xfa, 0xb2), + LL(0x95, 0x95, 0x6e, 0x95, 0xdc, 0xfb, 0x37, 0x49), + LL(0xd8, 0xd8, 0x47, 0xd8, 0x8e, 0x9f, 0xad, 0x56), + LL(0xfb, 0xfb, 0xcb, 0xfb, 0x8b, 0x30, 0xeb, 0x70), + LL(0xee, 0xee, 0x9f, 0xee, 0x23, 0x71, 0xc1, 0xcd), + LL(0x7c, 0x7c, 0xed, 0x7c, 0xc7, 0x91, 0xf8, 0xbb), + LL(0x66, 0x66, 0x85, 0x66, 0x17, 0xe3, 0xcc, 0x71), + LL(0xdd, 0xdd, 0x53, 0xdd, 0xa6, 0x8e, 0xa7, 0x7b), + LL(0x17, 0x17, 0x5c, 0x17, 0xb8, 0x4b, 0x2e, 0xaf), + LL(0x47, 0x47, 0x01, 0x47, 0x02, 0x46, 0x8e, 0x45), + LL(0x9e, 0x9e, 0x42, 0x9e, 0x84, 0xdc, 0x21, 0x1a), + LL(0xca, 0xca, 0x0f, 0xca, 0x1e, 0xc5, 0x89, 0xd4), + LL(0x2d, 0x2d, 0xb4, 0x2d, 0x75, 0x99, 0x5a, 0x58), + LL(0xbf, 0xbf, 0xc6, 0xbf, 0x91, 0x79, 0x63, 0x2e), + LL(0x07, 0x07, 0x1c, 0x07, 0x38, 0x1b, 0x0e, 0x3f), + LL(0xad, 0xad, 0x8e, 0xad, 0x01, 0x23, 0x47, 0xac), + LL(0x5a, 0x5a, 0x75, 0x5a, 0xea, 0x2f, 0xb4, 0xb0), + LL(0x83, 0x83, 0x36, 0x83, 0x6c, 0xb5, 0x1b, 0xef), + LL(0x33, 0x33, 0xcc, 0x33, 0x85, 0xff, 0x66, 0xb6), + LL(0x63, 0x63, 0x91, 0x63, 0x3f, 0xf2, 0xc6, 0x5c), + LL(0x02, 0x02, 0x08, 0x02, 0x10, 0x0a, 0x04, 0x12), + LL(0xaa, 0xaa, 0x92, 0xaa, 0x39, 0x38, 0x49, 0x93), + LL(0x71, 0x71, 0xd9, 0x71, 0xaf, 0xa8, 0xe2, 0xde), + LL(0xc8, 0xc8, 0x07, 0xc8, 0x0e, 0xcf, 0x8d, 0xc6), + LL(0x19, 0x19, 0x64, 0x19, 0xc8, 0x7d, 0x32, 0xd1), + LL(0x49, 0x49, 0x39, 0x49, 0x72, 0x70, 0x92, 0x3b), + LL(0xd9, 0xd9, 0x43, 0xd9, 0x86, 0x9a, 0xaf, 0x5f), + LL(0xf2, 0xf2, 0xef, 0xf2, 0xc3, 0x1d, 0xf9, 0x31), + LL(0xe3, 0xe3, 0xab, 0xe3, 0x4b, 0x48, 0xdb, 0xa8), + LL(0x5b, 0x5b, 0x71, 0x5b, 0xe2, 0x2a, 0xb6, 0xb9), + LL(0x88, 0x88, 0x1a, 0x88, 0x34, 0x92, 0x0d, 0xbc), + LL(0x9a, 0x9a, 0x52, 0x9a, 0xa4, 0xc8, 0x29, 0x3e), + LL(0x26, 0x26, 0x98, 0x26, 0x2d, 0xbe, 0x4c, 0x0b), + LL(0x32, 0x32, 0xc8, 0x32, 0x8d, 0xfa, 0x64, 0xbf), + LL(0xb0, 0xb0, 0xfa, 0xb0, 0xe9, 0x4a, 0x7d, 0x59), + LL(0xe9, 0xe9, 0x83, 0xe9, 0x1b, 0x6a, 0xcf, 0xf2), + LL(0x0f, 0x0f, 0x3c, 0x0f, 0x78, 0x33, 0x1e, 0x77), + LL(0xd5, 0xd5, 0x73, 0xd5, 0xe6, 0xa6, 0xb7, 0x33), + LL(0x80, 0x80, 0x3a, 0x80, 0x74, 0xba, 0x1d, 0xf4), + LL(0xbe, 0xbe, 0xc2, 0xbe, 0x99, 0x7c, 0x61, 0x27), + LL(0xcd, 0xcd, 0x13, 0xcd, 0x26, 0xde, 0x87, 0xeb), + LL(0x34, 0x34, 0xd0, 0x34, 0xbd, 0xe4, 0x68, 0x89), + LL(0x48, 0x48, 0x3d, 0x48, 0x7a, 0x75, 0x90, 0x32), + LL(0xff, 0xff, 0xdb, 0xff, 0xab, 0x24, 0xe3, 0x54), + LL(0x7a, 0x7a, 0xf5, 0x7a, 0xf7, 0x8f, 0xf4, 0x8d), + LL(0x90, 0x90, 0x7a, 0x90, 0xf4, 0xea, 0x3d, 0x64), + LL(0x5f, 0x5f, 0x61, 0x5f, 0xc2, 0x3e, 0xbe, 0x9d), + LL(0x20, 0x20, 0x80, 0x20, 0x1d, 0xa0, 0x40, 0x3d), + LL(0x68, 0x68, 0xbd, 0x68, 0x67, 0xd5, 0xd0, 0x0f), + LL(0x1a, 0x1a, 0x68, 0x1a, 0xd0, 0x72, 0x34, 0xca), + LL(0xae, 0xae, 0x82, 0xae, 0x19, 0x2c, 0x41, 0xb7), + LL(0xb4, 0xb4, 0xea, 0xb4, 0xc9, 0x5e, 0x75, 0x7d), + LL(0x54, 0x54, 0x4d, 0x54, 0x9a, 0x19, 0xa8, 0xce), + LL(0x93, 0x93, 0x76, 0x93, 0xec, 0xe5, 0x3b, 0x7f), + LL(0x22, 0x22, 0x88, 0x22, 0x0d, 0xaa, 0x44, 0x2f), + LL(0x64, 0x64, 0x8d, 0x64, 0x07, 0xe9, 0xc8, 0x63), + LL(0xf1, 0xf1, 0xe3, 0xf1, 0xdb, 0x12, 0xff, 0x2a), + LL(0x73, 0x73, 0xd1, 0x73, 0xbf, 0xa2, 0xe6, 0xcc), + LL(0x12, 0x12, 0x48, 0x12, 0x90, 0x5a, 0x24, 0x82), + LL(0x40, 0x40, 0x1d, 0x40, 0x3a, 0x5d, 0x80, 0x7a), + LL(0x08, 0x08, 0x20, 0x08, 0x40, 0x28, 0x10, 0x48), + LL(0xc3, 0xc3, 0x2b, 0xc3, 0x56, 0xe8, 0x9b, 0x95), + LL(0xec, 0xec, 0x97, 0xec, 0x33, 0x7b, 0xc5, 0xdf), + LL(0xdb, 0xdb, 0x4b, 0xdb, 0x96, 0x90, 0xab, 0x4d), + LL(0xa1, 0xa1, 0xbe, 0xa1, 0x61, 0x1f, 0x5f, 0xc0), + LL(0x8d, 0x8d, 0x0e, 0x8d, 0x1c, 0x83, 0x07, 0x91), + LL(0x3d, 0x3d, 0xf4, 0x3d, 0xf5, 0xc9, 0x7a, 0xc8), + LL(0x97, 0x97, 0x66, 0x97, 0xcc, 0xf1, 0x33, 0x5b), + LL(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00), + LL(0xcf, 0xcf, 0x1b, 0xcf, 0x36, 0xd4, 0x83, 0xf9), + LL(0x2b, 0x2b, 0xac, 0x2b, 0x45, 0x87, 0x56, 0x6e), + LL(0x76, 0x76, 0xc5, 0x76, 0x97, 0xb3, 0xec, 0xe1), + LL(0x82, 0x82, 0x32, 0x82, 0x64, 0xb0, 0x19, 0xe6), + LL(0xd6, 0xd6, 0x7f, 0xd6, 0xfe, 0xa9, 0xb1, 0x28), + LL(0x1b, 0x1b, 0x6c, 0x1b, 0xd8, 0x77, 0x36, 0xc3), + LL(0xb5, 0xb5, 0xee, 0xb5, 0xc1, 0x5b, 0x77, 0x74), + LL(0xaf, 0xaf, 0x86, 0xaf, 0x11, 0x29, 0x43, 0xbe), + LL(0x6a, 0x6a, 0xb5, 0x6a, 0x77, 0xdf, 0xd4, 0x1d), + LL(0x50, 0x50, 0x5d, 0x50, 0xba, 0x0d, 0xa0, 0xea), + LL(0x45, 0x45, 0x09, 0x45, 0x12, 0x4c, 0x8a, 0x57), + LL(0xf3, 0xf3, 0xeb, 0xf3, 0xcb, 0x18, 0xfb, 0x38), + LL(0x30, 0x30, 0xc0, 0x30, 0x9d, 0xf0, 0x60, 0xad), + LL(0xef, 0xef, 0x9b, 0xef, 0x2b, 0x74, 0xc3, 0xc4), + LL(0x3f, 0x3f, 0xfc, 0x3f, 0xe5, 0xc3, 0x7e, 0xda), + LL(0x55, 0x55, 0x49, 0x55, 0x92, 0x1c, 0xaa, 0xc7), + LL(0xa2, 0xa2, 0xb2, 0xa2, 0x79, 0x10, 0x59, 0xdb), + LL(0xea, 0xea, 0x8f, 0xea, 0x03, 0x65, 0xc9, 0xe9), + LL(0x65, 0x65, 0x89, 0x65, 0x0f, 0xec, 0xca, 0x6a), + LL(0xba, 0xba, 0xd2, 0xba, 0xb9, 0x68, 0x69, 0x03), + LL(0x2f, 0x2f, 0xbc, 0x2f, 0x65, 0x93, 0x5e, 0x4a), + LL(0xc0, 0xc0, 0x27, 0xc0, 0x4e, 0xe7, 0x9d, 0x8e), + LL(0xde, 0xde, 0x5f, 0xde, 0xbe, 0x81, 0xa1, 0x60), + LL(0x1c, 0x1c, 0x70, 0x1c, 0xe0, 0x6c, 0x38, 0xfc), + LL(0xfd, 0xfd, 0xd3, 0xfd, 0xbb, 0x2e, 0xe7, 0x46), + LL(0x4d, 0x4d, 0x29, 0x4d, 0x52, 0x64, 0x9a, 0x1f), + LL(0x92, 0x92, 0x72, 0x92, 0xe4, 0xe0, 0x39, 0x76), + LL(0x75, 0x75, 0xc9, 0x75, 0x8f, 0xbc, 0xea, 0xfa), + LL(0x06, 0x06, 0x18, 0x06, 0x30, 0x1e, 0x0c, 0x36), + LL(0x8a, 0x8a, 0x12, 0x8a, 0x24, 0x98, 0x09, 0xae), + LL(0xb2, 0xb2, 0xf2, 0xb2, 0xf9, 0x40, 0x79, 0x4b), + LL(0xe6, 0xe6, 0xbf, 0xe6, 0x63, 0x59, 0xd1, 0x85), + LL(0x0e, 0x0e, 0x38, 0x0e, 0x70, 0x36, 0x1c, 0x7e), + LL(0x1f, 0x1f, 0x7c, 0x1f, 0xf8, 0x63, 0x3e, 0xe7), + LL(0x62, 0x62, 0x95, 0x62, 0x37, 0xf7, 0xc4, 0x55), + LL(0xd4, 0xd4, 0x77, 0xd4, 0xee, 0xa3, 0xb5, 0x3a), + LL(0xa8, 0xa8, 0x9a, 0xa8, 0x29, 0x32, 0x4d, 0x81), + LL(0x96, 0x96, 0x62, 0x96, 0xc4, 0xf4, 0x31, 0x52), + LL(0xf9, 0xf9, 0xc3, 0xf9, 0x9b, 0x3a, 0xef, 0x62), + LL(0xc5, 0xc5, 0x33, 0xc5, 0x66, 0xf6, 0x97, 0xa3), + LL(0x25, 0x25, 0x94, 0x25, 0x35, 0xb1, 0x4a, 0x10), + LL(0x59, 0x59, 0x79, 0x59, 0xf2, 0x20, 0xb2, 0xab), + LL(0x84, 0x84, 0x2a, 0x84, 0x54, 0xae, 0x15, 0xd0), + LL(0x72, 0x72, 0xd5, 0x72, 0xb7, 0xa7, 0xe4, 0xc5), + LL(0x39, 0x39, 0xe4, 0x39, 0xd5, 0xdd, 0x72, 0xec), + LL(0x4c, 0x4c, 0x2d, 0x4c, 0x5a, 0x61, 0x98, 0x16), + LL(0x5e, 0x5e, 0x65, 0x5e, 0xca, 0x3b, 0xbc, 0x94), + LL(0x78, 0x78, 0xfd, 0x78, 0xe7, 0x85, 0xf0, 0x9f), + LL(0x38, 0x38, 0xe0, 0x38, 0xdd, 0xd8, 0x70, 0xe5), + LL(0x8c, 0x8c, 0x0a, 0x8c, 0x14, 0x86, 0x05, 0x98), + LL(0xd1, 0xd1, 0x63, 0xd1, 0xc6, 0xb2, 0xbf, 0x17), + LL(0xa5, 0xa5, 0xae, 0xa5, 0x41, 0x0b, 0x57, 0xe4), + LL(0xe2, 0xe2, 0xaf, 0xe2, 0x43, 0x4d, 0xd9, 0xa1), + LL(0x61, 0x61, 0x99, 0x61, 0x2f, 0xf8, 0xc2, 0x4e), + LL(0xb3, 0xb3, 0xf6, 0xb3, 0xf1, 0x45, 0x7b, 0x42), + LL(0x21, 0x21, 0x84, 0x21, 0x15, 0xa5, 0x42, 0x34), + LL(0x9c, 0x9c, 0x4a, 0x9c, 0x94, 0xd6, 0x25, 0x08), + LL(0x1e, 0x1e, 0x78, 0x1e, 0xf0, 0x66, 0x3c, 0xee), + LL(0x43, 0x43, 0x11, 0x43, 0x22, 0x52, 0x86, 0x61), + LL(0xc7, 0xc7, 0x3b, 0xc7, 0x76, 0xfc, 0x93, 0xb1), + LL(0xfc, 0xfc, 0xd7, 0xfc, 0xb3, 0x2b, 0xe5, 0x4f), + LL(0x04, 0x04, 0x10, 0x04, 0x20, 0x14, 0x08, 0x24), + LL(0x51, 0x51, 0x59, 0x51, 0xb2, 0x08, 0xa2, 0xe3), + LL(0x99, 0x99, 0x5e, 0x99, 0xbc, 0xc7, 0x2f, 0x25), + LL(0x6d, 0x6d, 0xa9, 0x6d, 0x4f, 0xc4, 0xda, 0x22), + LL(0x0d, 0x0d, 0x34, 0x0d, 0x68, 0x39, 0x1a, 0x65), + LL(0xfa, 0xfa, 0xcf, 0xfa, 0x83, 0x35, 0xe9, 0x79), + LL(0xdf, 0xdf, 0x5b, 0xdf, 0xb6, 0x84, 0xa3, 0x69), + LL(0x7e, 0x7e, 0xe5, 0x7e, 0xd7, 0x9b, 0xfc, 0xa9), + LL(0x24, 0x24, 0x90, 0x24, 0x3d, 0xb4, 0x48, 0x19), + LL(0x3b, 0x3b, 0xec, 0x3b, 0xc5, 0xd7, 0x76, 0xfe), + LL(0xab, 0xab, 0x96, 0xab, 0x31, 0x3d, 0x4b, 0x9a), + LL(0xce, 0xce, 0x1f, 0xce, 0x3e, 0xd1, 0x81, 0xf0), + LL(0x11, 0x11, 0x44, 0x11, 0x88, 0x55, 0x22, 0x99), + LL(0x8f, 0x8f, 0x06, 0x8f, 0x0c, 0x89, 0x03, 0x83), + LL(0x4e, 0x4e, 0x25, 0x4e, 0x4a, 0x6b, 0x9c, 0x04), + LL(0xb7, 0xb7, 0xe6, 0xb7, 0xd1, 0x51, 0x73, 0x66), + LL(0xeb, 0xeb, 0x8b, 0xeb, 0x0b, 0x60, 0xcb, 0xe0), + LL(0x3c, 0x3c, 0xf0, 0x3c, 0xfd, 0xcc, 0x78, 0xc1), + LL(0x81, 0x81, 0x3e, 0x81, 0x7c, 0xbf, 0x1f, 0xfd), + LL(0x94, 0x94, 0x6a, 0x94, 0xd4, 0xfe, 0x35, 0x40), + LL(0xf7, 0xf7, 0xfb, 0xf7, 0xeb, 0x0c, 0xf3, 0x1c), + LL(0xb9, 0xb9, 0xde, 0xb9, 0xa1, 0x67, 0x6f, 0x18), + LL(0x13, 0x13, 0x4c, 0x13, 0x98, 0x5f, 0x26, 0x8b), + LL(0x2c, 0x2c, 0xb0, 0x2c, 0x7d, 0x9c, 0x58, 0x51), + LL(0xd3, 0xd3, 0x6b, 0xd3, 0xd6, 0xb8, 0xbb, 0x05), + LL(0xe7, 0xe7, 0xbb, 0xe7, 0x6b, 0x5c, 0xd3, 0x8c), + LL(0x6e, 0x6e, 0xa5, 0x6e, 0x57, 0xcb, 0xdc, 0x39), + LL(0xc4, 0xc4, 0x37, 0xc4, 0x6e, 0xf3, 0x95, 0xaa), + LL(0x03, 0x03, 0x0c, 0x03, 0x18, 0x0f, 0x06, 0x1b), + LL(0x56, 0x56, 0x45, 0x56, 0x8a, 0x13, 0xac, 0xdc), + LL(0x44, 0x44, 0x0d, 0x44, 0x1a, 0x49, 0x88, 0x5e), + LL(0x7f, 0x7f, 0xe1, 0x7f, 0xdf, 0x9e, 0xfe, 0xa0), + LL(0xa9, 0xa9, 0x9e, 0xa9, 0x21, 0x37, 0x4f, 0x88), + LL(0x2a, 0x2a, 0xa8, 0x2a, 0x4d, 0x82, 0x54, 0x67), + LL(0xbb, 0xbb, 0xd6, 0xbb, 0xb1, 0x6d, 0x6b, 0x0a), + LL(0xc1, 0xc1, 0x23, 0xc1, 0x46, 0xe2, 0x9f, 0x87), + LL(0x53, 0x53, 0x51, 0x53, 0xa2, 0x02, 0xa6, 0xf1), + LL(0xdc, 0xdc, 0x57, 0xdc, 0xae, 0x8b, 0xa5, 0x72), + LL(0x0b, 0x0b, 0x2c, 0x0b, 0x58, 0x27, 0x16, 0x53), + LL(0x9d, 0x9d, 0x4e, 0x9d, 0x9c, 0xd3, 0x27, 0x01), + LL(0x6c, 0x6c, 0xad, 0x6c, 0x47, 0xc1, 0xd8, 0x2b), + LL(0x31, 0x31, 0xc4, 0x31, 0x95, 0xf5, 0x62, 0xa4), + LL(0x74, 0x74, 0xcd, 0x74, 0x87, 0xb9, 0xe8, 0xf3), + LL(0xf6, 0xf6, 0xff, 0xf6, 0xe3, 0x09, 0xf1, 0x15), + LL(0x46, 0x46, 0x05, 0x46, 0x0a, 0x43, 0x8c, 0x4c), + LL(0xac, 0xac, 0x8a, 0xac, 0x09, 0x26, 0x45, 0xa5), + LL(0x89, 0x89, 0x1e, 0x89, 0x3c, 0x97, 0x0f, 0xb5), + LL(0x14, 0x14, 0x50, 0x14, 0xa0, 0x44, 0x28, 0xb4), + LL(0xe1, 0xe1, 0xa3, 0xe1, 0x5b, 0x42, 0xdf, 0xba), + LL(0x16, 0x16, 0x58, 0x16, 0xb0, 0x4e, 0x2c, 0xa6), + LL(0x3a, 0x3a, 0xe8, 0x3a, 0xcd, 0xd2, 0x74, 0xf7), + LL(0x69, 0x69, 0xb9, 0x69, 0x6f, 0xd0, 0xd2, 0x06), + LL(0x09, 0x09, 0x24, 0x09, 0x48, 0x2d, 0x12, 0x41), + LL(0x70, 0x70, 0xdd, 0x70, 0xa7, 0xad, 0xe0, 0xd7), + LL(0xb6, 0xb6, 0xe2, 0xb6, 0xd9, 0x54, 0x71, 0x6f), + LL(0xd0, 0xd0, 0x67, 0xd0, 0xce, 0xb7, 0xbd, 0x1e), + LL(0xed, 0xed, 0x93, 0xed, 0x3b, 0x7e, 0xc7, 0xd6), + LL(0xcc, 0xcc, 0x17, 0xcc, 0x2e, 0xdb, 0x85, 0xe2), + LL(0x42, 0x42, 0x15, 0x42, 0x2a, 0x57, 0x84, 0x68), + LL(0x98, 0x98, 0x5a, 0x98, 0xb4, 0xc2, 0x2d, 0x2c), + LL(0xa4, 0xa4, 0xaa, 0xa4, 0x49, 0x0e, 0x55, 0xed), + LL(0x28, 0x28, 0xa0, 0x28, 0x5d, 0x88, 0x50, 0x75), + LL(0x5c, 0x5c, 0x6d, 0x5c, 0xda, 0x31, 0xb8, 0x86), + LL(0xf8, 0xf8, 0xc7, 0xf8, 0x93, 0x3f, 0xed, 0x6b), + LL(0x86, 0x86, 0x22, 0x86, 0x44, 0xa4, 0x11, 0xc2), +#define RC (&(Cx.q[256*N])) + 0x18, 0x23, 0xc6, 0xe8, 0x87, 0xb8, 0x01, 0x4f, + /* rc[ROUNDS] */ + 0x36, 0xa6, 0xd2, 0xf5, 0x79, 0x6f, 0x91, 0x52, 0x60, 0xbc, 0x9b, + 0x8e, 0xa3, 0x0c, 0x7b, 0x35, 0x1d, 0xe0, 0xd7, 0xc2, 0x2e, 0x4b, + 0xfe, 0x57, 0x15, 0x77, 0x37, 0xe5, 0x9f, 0xf0, 0x4a, 0xda, 0x58, + 0xc9, 0x29, 0x0a, 0xb1, 0xa0, 0x6b, 0x85, 0xbd, 0x5d, 0x10, 0xf4, + 0xcb, 0x3e, 0x05, 0x67, 0xe4, 0x27, 0x41, 0x8b, 0xa7, 0x7d, 0x95, + 0xd8, 0xfb, 0xee, 0x7c, 0x66, 0xdd, 0x17, 0x47, 0x9e, 0xca, 0x2d, + 0xbf, 0x07, 0xad, 0x5a, 0x83, 0x33 + } + }; + +void whirlpool_block(WHIRLPOOL_CTX *ctx, const void *inp, size_t n) +{ + int r; + const u8 *p = inp; + union { + u64 q[8]; + u8 c[64]; + } S, K, *H = (void *)ctx->H.q; + +#ifdef GO_FOR_MMX + GO_FOR_MMX(ctx, inp, n); +#endif + do { +#ifdef OPENSSL_SMALL_FOOTPRINT + u64 L[8]; + int i; + + for (i = 0; i < 64; i++) + S.c[i] = (K.c[i] = H->c[i]) ^ p[i]; + for (r = 0; r < ROUNDS; r++) { + for (i = 0; i < 8; i++) { + L[i] = i ? 0 : RC[r]; + L[i] ^= C0(K, i) ^ C1(K, (i - 1) & 7) ^ + C2(K, (i - 2) & 7) ^ C3(K, (i - 3) & 7) ^ + C4(K, (i - 4) & 7) ^ C5(K, (i - 5) & 7) ^ + C6(K, (i - 6) & 7) ^ C7(K, (i - 7) & 7); + } + memcpy(K.q, L, 64); + for (i = 0; i < 8; i++) { + L[i] ^= C0(S, i) ^ C1(S, (i - 1) & 7) ^ + C2(S, (i - 2) & 7) ^ C3(S, (i - 3) & 7) ^ + C4(S, (i - 4) & 7) ^ C5(S, (i - 5) & 7) ^ + C6(S, (i - 6) & 7) ^ C7(S, (i - 7) & 7); + } + memcpy(S.q, L, 64); + } + for (i = 0; i < 64; i++) + H->c[i] ^= S.c[i] ^ p[i]; +#else + u64 L0, L1, L2, L3, L4, L5, L6, L7; + +# ifdef STRICT_ALIGNMENT + if ((size_t)p & 7) { + memcpy(S.c, p, 64); + S.q[0] ^= (K.q[0] = H->q[0]); + S.q[1] ^= (K.q[1] = H->q[1]); + S.q[2] ^= (K.q[2] = H->q[2]); + S.q[3] ^= (K.q[3] = H->q[3]); + S.q[4] ^= (K.q[4] = H->q[4]); + S.q[5] ^= (K.q[5] = H->q[5]); + S.q[6] ^= (K.q[6] = H->q[6]); + S.q[7] ^= (K.q[7] = H->q[7]); + } else +# endif + { + const u64 *pa = (const u64 *)p; + S.q[0] = (K.q[0] = H->q[0]) ^ pa[0]; + S.q[1] = (K.q[1] = H->q[1]) ^ pa[1]; + S.q[2] = (K.q[2] = H->q[2]) ^ pa[2]; + S.q[3] = (K.q[3] = H->q[3]) ^ pa[3]; + S.q[4] = (K.q[4] = H->q[4]) ^ pa[4]; + S.q[5] = (K.q[5] = H->q[5]) ^ pa[5]; + S.q[6] = (K.q[6] = H->q[6]) ^ pa[6]; + S.q[7] = (K.q[7] = H->q[7]) ^ pa[7]; + } + + for (r = 0; r < ROUNDS; r++) { +# ifdef SMALL_REGISTER_BANK + L0 = C0(K, 0) ^ C1(K, 7) ^ C2(K, 6) ^ C3(K, 5) ^ + C4(K, 4) ^ C5(K, 3) ^ C6(K, 2) ^ C7(K, 1) ^ RC[r]; + L1 = C0(K, 1) ^ C1(K, 0) ^ C2(K, 7) ^ C3(K, 6) ^ + C4(K, 5) ^ C5(K, 4) ^ C6(K, 3) ^ C7(K, 2); + L2 = C0(K, 2) ^ C1(K, 1) ^ C2(K, 0) ^ C3(K, 7) ^ + C4(K, 6) ^ C5(K, 5) ^ C6(K, 4) ^ C7(K, 3); + L3 = C0(K, 3) ^ C1(K, 2) ^ C2(K, 1) ^ C3(K, 0) ^ + C4(K, 7) ^ C5(K, 6) ^ C6(K, 5) ^ C7(K, 4); + L4 = C0(K, 4) ^ C1(K, 3) ^ C2(K, 2) ^ C3(K, 1) ^ + C4(K, 0) ^ C5(K, 7) ^ C6(K, 6) ^ C7(K, 5); + L5 = C0(K, 5) ^ C1(K, 4) ^ C2(K, 3) ^ C3(K, 2) ^ + C4(K, 1) ^ C5(K, 0) ^ C6(K, 7) ^ C7(K, 6); + L6 = C0(K, 6) ^ C1(K, 5) ^ C2(K, 4) ^ C3(K, 3) ^ + C4(K, 2) ^ C5(K, 1) ^ C6(K, 0) ^ C7(K, 7); + L7 = C0(K, 7) ^ C1(K, 6) ^ C2(K, 5) ^ C3(K, 4) ^ + C4(K, 3) ^ C5(K, 2) ^ C6(K, 1) ^ C7(K, 0); + + K.q[0] = L0; + K.q[1] = L1; + K.q[2] = L2; + K.q[3] = L3; + K.q[4] = L4; + K.q[5] = L5; + K.q[6] = L6; + K.q[7] = L7; + + L0 ^= C0(S, 0) ^ C1(S, 7) ^ C2(S, 6) ^ C3(S, 5) ^ + C4(S, 4) ^ C5(S, 3) ^ C6(S, 2) ^ C7(S, 1); + L1 ^= C0(S, 1) ^ C1(S, 0) ^ C2(S, 7) ^ C3(S, 6) ^ + C4(S, 5) ^ C5(S, 4) ^ C6(S, 3) ^ C7(S, 2); + L2 ^= C0(S, 2) ^ C1(S, 1) ^ C2(S, 0) ^ C3(S, 7) ^ + C4(S, 6) ^ C5(S, 5) ^ C6(S, 4) ^ C7(S, 3); + L3 ^= C0(S, 3) ^ C1(S, 2) ^ C2(S, 1) ^ C3(S, 0) ^ + C4(S, 7) ^ C5(S, 6) ^ C6(S, 5) ^ C7(S, 4); + L4 ^= C0(S, 4) ^ C1(S, 3) ^ C2(S, 2) ^ C3(S, 1) ^ + C4(S, 0) ^ C5(S, 7) ^ C6(S, 6) ^ C7(S, 5); + L5 ^= C0(S, 5) ^ C1(S, 4) ^ C2(S, 3) ^ C3(S, 2) ^ + C4(S, 1) ^ C5(S, 0) ^ C6(S, 7) ^ C7(S, 6); + L6 ^= C0(S, 6) ^ C1(S, 5) ^ C2(S, 4) ^ C3(S, 3) ^ + C4(S, 2) ^ C5(S, 1) ^ C6(S, 0) ^ C7(S, 7); + L7 ^= C0(S, 7) ^ C1(S, 6) ^ C2(S, 5) ^ C3(S, 4) ^ + C4(S, 3) ^ C5(S, 2) ^ C6(S, 1) ^ C7(S, 0); + + S.q[0] = L0; + S.q[1] = L1; + S.q[2] = L2; + S.q[3] = L3; + S.q[4] = L4; + S.q[5] = L5; + S.q[6] = L6; + S.q[7] = L7; +# else + L0 = C0(K, 0); + L1 = C1(K, 0); + L2 = C2(K, 0); + L3 = C3(K, 0); + L4 = C4(K, 0); + L5 = C5(K, 0); + L6 = C6(K, 0); + L7 = C7(K, 0); + L0 ^= RC[r]; + + L1 ^= C0(K, 1); + L2 ^= C1(K, 1); + L3 ^= C2(K, 1); + L4 ^= C3(K, 1); + L5 ^= C4(K, 1); + L6 ^= C5(K, 1); + L7 ^= C6(K, 1); + L0 ^= C7(K, 1); + + L2 ^= C0(K, 2); + L3 ^= C1(K, 2); + L4 ^= C2(K, 2); + L5 ^= C3(K, 2); + L6 ^= C4(K, 2); + L7 ^= C5(K, 2); + L0 ^= C6(K, 2); + L1 ^= C7(K, 2); + + L3 ^= C0(K, 3); + L4 ^= C1(K, 3); + L5 ^= C2(K, 3); + L6 ^= C3(K, 3); + L7 ^= C4(K, 3); + L0 ^= C5(K, 3); + L1 ^= C6(K, 3); + L2 ^= C7(K, 3); + + L4 ^= C0(K, 4); + L5 ^= C1(K, 4); + L6 ^= C2(K, 4); + L7 ^= C3(K, 4); + L0 ^= C4(K, 4); + L1 ^= C5(K, 4); + L2 ^= C6(K, 4); + L3 ^= C7(K, 4); + + L5 ^= C0(K, 5); + L6 ^= C1(K, 5); + L7 ^= C2(K, 5); + L0 ^= C3(K, 5); + L1 ^= C4(K, 5); + L2 ^= C5(K, 5); + L3 ^= C6(K, 5); + L4 ^= C7(K, 5); + + L6 ^= C0(K, 6); + L7 ^= C1(K, 6); + L0 ^= C2(K, 6); + L1 ^= C3(K, 6); + L2 ^= C4(K, 6); + L3 ^= C5(K, 6); + L4 ^= C6(K, 6); + L5 ^= C7(K, 6); + + L7 ^= C0(K, 7); + L0 ^= C1(K, 7); + L1 ^= C2(K, 7); + L2 ^= C3(K, 7); + L3 ^= C4(K, 7); + L4 ^= C5(K, 7); + L5 ^= C6(K, 7); + L6 ^= C7(K, 7); + + K.q[0] = L0; + K.q[1] = L1; + K.q[2] = L2; + K.q[3] = L3; + K.q[4] = L4; + K.q[5] = L5; + K.q[6] = L6; + K.q[7] = L7; + + L0 ^= C0(S, 0); + L1 ^= C1(S, 0); + L2 ^= C2(S, 0); + L3 ^= C3(S, 0); + L4 ^= C4(S, 0); + L5 ^= C5(S, 0); + L6 ^= C6(S, 0); + L7 ^= C7(S, 0); + + L1 ^= C0(S, 1); + L2 ^= C1(S, 1); + L3 ^= C2(S, 1); + L4 ^= C3(S, 1); + L5 ^= C4(S, 1); + L6 ^= C5(S, 1); + L7 ^= C6(S, 1); + L0 ^= C7(S, 1); + + L2 ^= C0(S, 2); + L3 ^= C1(S, 2); + L4 ^= C2(S, 2); + L5 ^= C3(S, 2); + L6 ^= C4(S, 2); + L7 ^= C5(S, 2); + L0 ^= C6(S, 2); + L1 ^= C7(S, 2); + + L3 ^= C0(S, 3); + L4 ^= C1(S, 3); + L5 ^= C2(S, 3); + L6 ^= C3(S, 3); + L7 ^= C4(S, 3); + L0 ^= C5(S, 3); + L1 ^= C6(S, 3); + L2 ^= C7(S, 3); + + L4 ^= C0(S, 4); + L5 ^= C1(S, 4); + L6 ^= C2(S, 4); + L7 ^= C3(S, 4); + L0 ^= C4(S, 4); + L1 ^= C5(S, 4); + L2 ^= C6(S, 4); + L3 ^= C7(S, 4); + + L5 ^= C0(S, 5); + L6 ^= C1(S, 5); + L7 ^= C2(S, 5); + L0 ^= C3(S, 5); + L1 ^= C4(S, 5); + L2 ^= C5(S, 5); + L3 ^= C6(S, 5); + L4 ^= C7(S, 5); + + L6 ^= C0(S, 6); + L7 ^= C1(S, 6); + L0 ^= C2(S, 6); + L1 ^= C3(S, 6); + L2 ^= C4(S, 6); + L3 ^= C5(S, 6); + L4 ^= C6(S, 6); + L5 ^= C7(S, 6); + + L7 ^= C0(S, 7); + L0 ^= C1(S, 7); + L1 ^= C2(S, 7); + L2 ^= C3(S, 7); + L3 ^= C4(S, 7); + L4 ^= C5(S, 7); + L5 ^= C6(S, 7); + L6 ^= C7(S, 7); + + S.q[0] = L0; + S.q[1] = L1; + S.q[2] = L2; + S.q[3] = L3; + S.q[4] = L4; + S.q[5] = L5; + S.q[6] = L6; + S.q[7] = L7; +# endif + } + +# ifdef STRICT_ALIGNMENT + if ((size_t)p & 7) { + int i; + for (i = 0; i < 64; i++) + H->c[i] ^= S.c[i] ^ p[i]; + } else +# endif + { + const u64 *pa = (const u64 *)p; + H->q[0] ^= S.q[0] ^ pa[0]; + H->q[1] ^= S.q[1] ^ pa[1]; + H->q[2] ^= S.q[2] ^ pa[2]; + H->q[3] ^= S.q[3] ^ pa[3]; + H->q[4] ^= S.q[4] ^ pa[4]; + H->q[5] ^= S.q[5] ^ pa[5]; + H->q[6] ^= S.q[6] ^ pa[6]; + H->q[7] ^= S.q[7] ^ pa[7]; + } +#endif + p += 64; + } while (--n); +} diff --git a/libs/openssl/crypto/whrlpool/wp_dgst.c b/libs/openssl/crypto/whrlpool/wp_dgst.c new file mode 100644 index 00000000..e33bb4f8 --- /dev/null +++ b/libs/openssl/crypto/whrlpool/wp_dgst.c @@ -0,0 +1,257 @@ +/** + * The Whirlpool hashing function. + * + *

+ * References + * + *

+ * The Whirlpool algorithm was developed by + * Paulo S. L. M. Barreto and + * Vincent Rijmen. + * + * See + * P.S.L.M. Barreto, V. Rijmen, + * ``The Whirlpool hashing function,'' + * NESSIE submission, 2000 (tweaked version, 2001), + * + * + * Based on "@version 3.0 (2003.03.12)" by Paulo S.L.M. Barreto and + * Vincent Rijmen. Lookup "reference implementations" on + * + * + * ============================================================================= + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* + * OpenSSL-specific implementation notes. + * + * WHIRLPOOL_Update as well as one-stroke WHIRLPOOL both expect + * number of *bytes* as input length argument. Bit-oriented routine + * as specified by authors is called WHIRLPOOL_BitUpdate[!] and + * does not have one-stroke counterpart. + * + * WHIRLPOOL_BitUpdate implements byte-oriented loop, essentially + * to serve WHIRLPOOL_Update. This is done for performance. + * + * Unlike authors' reference implementation, block processing + * routine whirlpool_block is designed to operate on multi-block + * input. This is done for perfomance. + */ + +#include "wp_locl.h" +#include +#include + +fips_md_init(WHIRLPOOL) +{ + memset(c, 0, sizeof(*c)); + return (1); +} + +int WHIRLPOOL_Update(WHIRLPOOL_CTX *c, const void *_inp, size_t bytes) +{ + /* + * Well, largest suitable chunk size actually is + * (1<<(sizeof(size_t)*8-3))-64, but below number is large enough for not + * to care about excessive calls to WHIRLPOOL_BitUpdate... + */ + size_t chunk = ((size_t)1) << (sizeof(size_t) * 8 - 4); + const unsigned char *inp = _inp; + + while (bytes >= chunk) { + WHIRLPOOL_BitUpdate(c, inp, chunk * 8); + bytes -= chunk; + inp += chunk; + } + if (bytes) + WHIRLPOOL_BitUpdate(c, inp, bytes * 8); + + return (1); +} + +void WHIRLPOOL_BitUpdate(WHIRLPOOL_CTX *c, const void *_inp, size_t bits) +{ + size_t n; + unsigned int bitoff = c->bitoff, + bitrem = bitoff % 8, inpgap = (8 - (unsigned int)bits % 8) & 7; + const unsigned char *inp = _inp; + + /* + * This 256-bit increment procedure relies on the size_t being natural + * size of CPU register, so that we don't have to mask the value in order + * to detect overflows. + */ + c->bitlen[0] += bits; + if (c->bitlen[0] < bits) { /* overflow */ + n = 1; + do { + c->bitlen[n]++; + } while (c->bitlen[n] == 0 + && ++n < (WHIRLPOOL_COUNTER / sizeof(size_t))); + } +#ifndef OPENSSL_SMALL_FOOTPRINT + reconsider: + if (inpgap == 0 && bitrem == 0) { /* byte-oriented loop */ + while (bits) { + if (bitoff == 0 && (n = bits / WHIRLPOOL_BBLOCK)) { + whirlpool_block(c, inp, n); + inp += n * WHIRLPOOL_BBLOCK / 8; + bits %= WHIRLPOOL_BBLOCK; + } else { + unsigned int byteoff = bitoff / 8; + + bitrem = WHIRLPOOL_BBLOCK - bitoff; /* re-use bitrem */ + if (bits >= bitrem) { + bits -= bitrem; + bitrem /= 8; + memcpy(c->data + byteoff, inp, bitrem); + inp += bitrem; + whirlpool_block(c, c->data, 1); + bitoff = 0; + } else { + memcpy(c->data + byteoff, inp, bits / 8); + bitoff += (unsigned int)bits; + bits = 0; + } + c->bitoff = bitoff; + } + } + } else /* bit-oriented loop */ +#endif + { + /*- + inp + | + +-------+-------+------- + ||||||||||||||||||||| + +-------+-------+------- + +-------+-------+-------+-------+------- + |||||||||||||| c->data + +-------+-------+-------+-------+------- + | + c->bitoff/8 + */ + while (bits) { + unsigned int byteoff = bitoff / 8; + unsigned char b; + +#ifndef OPENSSL_SMALL_FOOTPRINT + if (bitrem == inpgap) { + c->data[byteoff++] |= inp[0] & (0xff >> inpgap); + inpgap = 8 - inpgap; + bitoff += inpgap; + bitrem = 0; /* bitoff%8 */ + bits -= inpgap; + inpgap = 0; /* bits%8 */ + inp++; + if (bitoff == WHIRLPOOL_BBLOCK) { + whirlpool_block(c, c->data, 1); + bitoff = 0; + } + c->bitoff = bitoff; + goto reconsider; + } else +#endif + if (bits >= 8) { + b = ((inp[0] << inpgap) | (inp[1] >> (8 - inpgap))); + b &= 0xff; + if (bitrem) + c->data[byteoff++] |= b >> bitrem; + else + c->data[byteoff++] = b; + bitoff += 8; + bits -= 8; + inp++; + if (bitoff >= WHIRLPOOL_BBLOCK) { + whirlpool_block(c, c->data, 1); + byteoff = 0; + bitoff %= WHIRLPOOL_BBLOCK; + } + if (bitrem) + c->data[byteoff] = b << (8 - bitrem); + } else { /* remaining less than 8 bits */ + + b = (inp[0] << inpgap) & 0xff; + if (bitrem) + c->data[byteoff++] |= b >> bitrem; + else + c->data[byteoff++] = b; + bitoff += (unsigned int)bits; + if (bitoff == WHIRLPOOL_BBLOCK) { + whirlpool_block(c, c->data, 1); + byteoff = 0; + bitoff %= WHIRLPOOL_BBLOCK; + } + if (bitrem) + c->data[byteoff] = b << (8 - bitrem); + bits = 0; + } + c->bitoff = bitoff; + } + } +} + +int WHIRLPOOL_Final(unsigned char *md, WHIRLPOOL_CTX *c) +{ + unsigned int bitoff = c->bitoff, byteoff = bitoff / 8; + size_t i, j, v; + unsigned char *p; + + bitoff %= 8; + if (bitoff) + c->data[byteoff] |= 0x80 >> bitoff; + else + c->data[byteoff] = 0x80; + byteoff++; + + /* pad with zeros */ + if (byteoff > (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER)) { + if (byteoff < WHIRLPOOL_BBLOCK / 8) + memset(&c->data[byteoff], 0, WHIRLPOOL_BBLOCK / 8 - byteoff); + whirlpool_block(c, c->data, 1); + byteoff = 0; + } + if (byteoff < (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER)) + memset(&c->data[byteoff], 0, + (WHIRLPOOL_BBLOCK / 8 - WHIRLPOOL_COUNTER) - byteoff); + /* smash 256-bit c->bitlen in big-endian order */ + p = &c->data[WHIRLPOOL_BBLOCK / 8 - 1]; /* last byte in c->data */ + for (i = 0; i < WHIRLPOOL_COUNTER / sizeof(size_t); i++) + for (v = c->bitlen[i], j = 0; j < sizeof(size_t); j++, v >>= 8) + *p-- = (unsigned char)(v & 0xff); + + whirlpool_block(c, c->data, 1); + + if (md) { + memcpy(md, c->H.c, WHIRLPOOL_DIGEST_LENGTH); + memset(c, 0, sizeof(*c)); + return (1); + } + return (0); +} + +unsigned char *WHIRLPOOL(const void *inp, size_t bytes, unsigned char *md) +{ + WHIRLPOOL_CTX ctx; + static unsigned char m[WHIRLPOOL_DIGEST_LENGTH]; + + if (md == NULL) + md = m; + WHIRLPOOL_Init(&ctx); + WHIRLPOOL_Update(&ctx, inp, bytes); + WHIRLPOOL_Final(md, &ctx); + return (md); +} diff --git a/libs/openssl/crypto/whrlpool/wp_locl.h b/libs/openssl/crypto/whrlpool/wp_locl.h new file mode 100644 index 00000000..6e7b549e --- /dev/null +++ b/libs/openssl/crypto/whrlpool/wp_locl.h @@ -0,0 +1,3 @@ +#include + +void whirlpool_block(WHIRLPOOL_CTX *, const void *, size_t); diff --git a/libs/openssl/crypto/whrlpool/wp_test.c b/libs/openssl/crypto/whrlpool/wp_test.c new file mode 100644 index 00000000..2ea6251a --- /dev/null +++ b/libs/openssl/crypto/whrlpool/wp_test.c @@ -0,0 +1,241 @@ +/* ==================================================================== + * Copyright (c) 2005 The OpenSSL Project. All rights reserved. + * ==================================================================== + */ +#include +#include +#include + +#include +#include + +#if defined(OPENSSL_NO_WHIRLPOOL) +int main(int argc, char *argv[]) +{ + printf("No Whirlpool support\n"); + return (0); +} +#else + +/* ISO/IEC 10118-3 test vector set */ +unsigned char iso_test_1[WHIRLPOOL_DIGEST_LENGTH] = { + 0x19, 0xFA, 0x61, 0xD7, 0x55, 0x22, 0xA4, 0x66, + 0x9B, 0x44, 0xE3, 0x9C, 0x1D, 0x2E, 0x17, 0x26, + 0xC5, 0x30, 0x23, 0x21, 0x30, 0xD4, 0x07, 0xF8, + 0x9A, 0xFE, 0xE0, 0x96, 0x49, 0x97, 0xF7, 0xA7, + 0x3E, 0x83, 0xBE, 0x69, 0x8B, 0x28, 0x8F, 0xEB, + 0xCF, 0x88, 0xE3, 0xE0, 0x3C, 0x4F, 0x07, 0x57, + 0xEA, 0x89, 0x64, 0xE5, 0x9B, 0x63, 0xD9, 0x37, + 0x08, 0xB1, 0x38, 0xCC, 0x42, 0xA6, 0x6E, 0xB3 +}; + +unsigned char iso_test_2[WHIRLPOOL_DIGEST_LENGTH] = { + 0x8A, 0xCA, 0x26, 0x02, 0x79, 0x2A, 0xEC, 0x6F, + 0x11, 0xA6, 0x72, 0x06, 0x53, 0x1F, 0xB7, 0xD7, + 0xF0, 0xDF, 0xF5, 0x94, 0x13, 0x14, 0x5E, 0x69, + 0x73, 0xC4, 0x50, 0x01, 0xD0, 0x08, 0x7B, 0x42, + 0xD1, 0x1B, 0xC6, 0x45, 0x41, 0x3A, 0xEF, 0xF6, + 0x3A, 0x42, 0x39, 0x1A, 0x39, 0x14, 0x5A, 0x59, + 0x1A, 0x92, 0x20, 0x0D, 0x56, 0x01, 0x95, 0xE5, + 0x3B, 0x47, 0x85, 0x84, 0xFD, 0xAE, 0x23, 0x1A +}; + +unsigned char iso_test_3[WHIRLPOOL_DIGEST_LENGTH] = { + 0x4E, 0x24, 0x48, 0xA4, 0xC6, 0xF4, 0x86, 0xBB, + 0x16, 0xB6, 0x56, 0x2C, 0x73, 0xB4, 0x02, 0x0B, + 0xF3, 0x04, 0x3E, 0x3A, 0x73, 0x1B, 0xCE, 0x72, + 0x1A, 0xE1, 0xB3, 0x03, 0xD9, 0x7E, 0x6D, 0x4C, + 0x71, 0x81, 0xEE, 0xBD, 0xB6, 0xC5, 0x7E, 0x27, + 0x7D, 0x0E, 0x34, 0x95, 0x71, 0x14, 0xCB, 0xD6, + 0xC7, 0x97, 0xFC, 0x9D, 0x95, 0xD8, 0xB5, 0x82, + 0xD2, 0x25, 0x29, 0x20, 0x76, 0xD4, 0xEE, 0xF5 +}; + +unsigned char iso_test_4[WHIRLPOOL_DIGEST_LENGTH] = { + 0x37, 0x8C, 0x84, 0xA4, 0x12, 0x6E, 0x2D, 0xC6, + 0xE5, 0x6D, 0xCC, 0x74, 0x58, 0x37, 0x7A, 0xAC, + 0x83, 0x8D, 0x00, 0x03, 0x22, 0x30, 0xF5, 0x3C, + 0xE1, 0xF5, 0x70, 0x0C, 0x0F, 0xFB, 0x4D, 0x3B, + 0x84, 0x21, 0x55, 0x76, 0x59, 0xEF, 0x55, 0xC1, + 0x06, 0xB4, 0xB5, 0x2A, 0xC5, 0xA4, 0xAA, 0xA6, + 0x92, 0xED, 0x92, 0x00, 0x52, 0x83, 0x8F, 0x33, + 0x62, 0xE8, 0x6D, 0xBD, 0x37, 0xA8, 0x90, 0x3E +}; + +unsigned char iso_test_5[WHIRLPOOL_DIGEST_LENGTH] = { + 0xF1, 0xD7, 0x54, 0x66, 0x26, 0x36, 0xFF, 0xE9, + 0x2C, 0x82, 0xEB, 0xB9, 0x21, 0x2A, 0x48, 0x4A, + 0x8D, 0x38, 0x63, 0x1E, 0xAD, 0x42, 0x38, 0xF5, + 0x44, 0x2E, 0xE1, 0x3B, 0x80, 0x54, 0xE4, 0x1B, + 0x08, 0xBF, 0x2A, 0x92, 0x51, 0xC3, 0x0B, 0x6A, + 0x0B, 0x8A, 0xAE, 0x86, 0x17, 0x7A, 0xB4, 0xA6, + 0xF6, 0x8F, 0x67, 0x3E, 0x72, 0x07, 0x86, 0x5D, + 0x5D, 0x98, 0x19, 0xA3, 0xDB, 0xA4, 0xEB, 0x3B +}; + +unsigned char iso_test_6[WHIRLPOOL_DIGEST_LENGTH] = { + 0xDC, 0x37, 0xE0, 0x08, 0xCF, 0x9E, 0xE6, 0x9B, + 0xF1, 0x1F, 0x00, 0xED, 0x9A, 0xBA, 0x26, 0x90, + 0x1D, 0xD7, 0xC2, 0x8C, 0xDE, 0xC0, 0x66, 0xCC, + 0x6A, 0xF4, 0x2E, 0x40, 0xF8, 0x2F, 0x3A, 0x1E, + 0x08, 0xEB, 0xA2, 0x66, 0x29, 0x12, 0x9D, 0x8F, + 0xB7, 0xCB, 0x57, 0x21, 0x1B, 0x92, 0x81, 0xA6, + 0x55, 0x17, 0xCC, 0x87, 0x9D, 0x7B, 0x96, 0x21, + 0x42, 0xC6, 0x5F, 0x5A, 0x7A, 0xF0, 0x14, 0x67 +}; + +unsigned char iso_test_7[WHIRLPOOL_DIGEST_LENGTH] = { + 0x46, 0x6E, 0xF1, 0x8B, 0xAB, 0xB0, 0x15, 0x4D, + 0x25, 0xB9, 0xD3, 0x8A, 0x64, 0x14, 0xF5, 0xC0, + 0x87, 0x84, 0x37, 0x2B, 0xCC, 0xB2, 0x04, 0xD6, + 0x54, 0x9C, 0x4A, 0xFA, 0xDB, 0x60, 0x14, 0x29, + 0x4D, 0x5B, 0xD8, 0xDF, 0x2A, 0x6C, 0x44, 0xE5, + 0x38, 0xCD, 0x04, 0x7B, 0x26, 0x81, 0xA5, 0x1A, + 0x2C, 0x60, 0x48, 0x1E, 0x88, 0xC5, 0xA2, 0x0B, + 0x2C, 0x2A, 0x80, 0xCF, 0x3A, 0x9A, 0x08, 0x3B +}; + +unsigned char iso_test_8[WHIRLPOOL_DIGEST_LENGTH] = { + 0x2A, 0x98, 0x7E, 0xA4, 0x0F, 0x91, 0x70, 0x61, + 0xF5, 0xD6, 0xF0, 0xA0, 0xE4, 0x64, 0x4F, 0x48, + 0x8A, 0x7A, 0x5A, 0x52, 0xDE, 0xEE, 0x65, 0x62, + 0x07, 0xC5, 0x62, 0xF9, 0x88, 0xE9, 0x5C, 0x69, + 0x16, 0xBD, 0xC8, 0x03, 0x1B, 0xC5, 0xBE, 0x1B, + 0x7B, 0x94, 0x76, 0x39, 0xFE, 0x05, 0x0B, 0x56, + 0x93, 0x9B, 0xAA, 0xA0, 0xAD, 0xFF, 0x9A, 0xE6, + 0x74, 0x5B, 0x7B, 0x18, 0x1C, 0x3B, 0xE3, 0xFD +}; + +unsigned char iso_test_9[WHIRLPOOL_DIGEST_LENGTH] = { + 0x0C, 0x99, 0x00, 0x5B, 0xEB, 0x57, 0xEF, 0xF5, + 0x0A, 0x7C, 0xF0, 0x05, 0x56, 0x0D, 0xDF, 0x5D, + 0x29, 0x05, 0x7F, 0xD8, 0x6B, 0x20, 0xBF, 0xD6, + 0x2D, 0xEC, 0xA0, 0xF1, 0xCC, 0xEA, 0x4A, 0xF5, + 0x1F, 0xC1, 0x54, 0x90, 0xED, 0xDC, 0x47, 0xAF, + 0x32, 0xBB, 0x2B, 0x66, 0xC3, 0x4F, 0xF9, 0xAD, + 0x8C, 0x60, 0x08, 0xAD, 0x67, 0x7F, 0x77, 0x12, + 0x69, 0x53, 0xB2, 0x26, 0xE4, 0xED, 0x8B, 0x01 +}; + +int main(int argc, char *argv[]) +{ + unsigned char md[WHIRLPOOL_DIGEST_LENGTH]; + int i; + WHIRLPOOL_CTX ctx; + +# ifdef OPENSSL_IA32_SSE2 + /* + * Alternative to this is to call OpenSSL_add_all_algorithms... The below + * code is retained exclusively for debugging purposes. + */ + { + char *env; + + if ((env = getenv("OPENSSL_ia32cap"))) + OPENSSL_ia32cap = strtoul(env, NULL, 0); + } +# endif + + fprintf(stdout, "Testing Whirlpool "); + + WHIRLPOOL("", 0, md); + if (memcmp(md, iso_test_1, sizeof(iso_test_1))) { + fflush(stdout); + fprintf(stderr, "\nTEST 1 of 9 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + WHIRLPOOL("a", 1, md); + if (memcmp(md, iso_test_2, sizeof(iso_test_2))) { + fflush(stdout); + fprintf(stderr, "\nTEST 2 of 9 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + WHIRLPOOL("abc", 3, md); + if (memcmp(md, iso_test_3, sizeof(iso_test_3))) { + fflush(stdout); + fprintf(stderr, "\nTEST 3 of 9 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + WHIRLPOOL("message digest", 14, md); + if (memcmp(md, iso_test_4, sizeof(iso_test_4))) { + fflush(stdout); + fprintf(stderr, "\nTEST 4 of 9 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + WHIRLPOOL("abcdefghijklmnopqrstuvwxyz", 26, md); + if (memcmp(md, iso_test_5, sizeof(iso_test_5))) { + fflush(stdout); + fprintf(stderr, "\nTEST 5 of 9 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + WHIRLPOOL("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" "0123456789", 62, md); + if (memcmp(md, iso_test_6, sizeof(iso_test_6))) { + fflush(stdout); + fprintf(stderr, "\nTEST 6 of 9 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + WHIRLPOOL("1234567890" "1234567890" "1234567890" "1234567890" + "1234567890" "1234567890" "1234567890" "1234567890", 80, md); + if (memcmp(md, iso_test_7, sizeof(iso_test_7))) { + fflush(stdout); + fprintf(stderr, "\nTEST 7 of 9 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + WHIRLPOOL("abcdbcdecdefdefgefghfghighijhijk", 32, md); + if (memcmp(md, iso_test_8, sizeof(iso_test_8))) { + fflush(stdout); + fprintf(stderr, "\nTEST 8 of 9 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + WHIRLPOOL_Init(&ctx); + for (i = 0; i < 1000000; i += 288) + WHIRLPOOL_Update(&ctx, "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" + "aaaaaaaa" "aaaaaaaa" "aaaaaaaa" "aaaaaaaa", + (1000000 - i) < 288 ? 1000000 - i : 288); + WHIRLPOOL_Final(md, &ctx); + if (memcmp(md, iso_test_9, sizeof(iso_test_9))) { + fflush(stdout); + fprintf(stderr, "\nTEST 9 of 9 failed.\n"); + return 1; + } else + fprintf(stdout, "."); + fflush(stdout); + + fprintf(stdout, " passed.\n"); + fflush(stdout); + + return 0; +} +#endif diff --git a/libs/openssl/crypto/x509/by_dir.c b/libs/openssl/crypto/x509/by_dir.c new file mode 100644 index 00000000..9ee8f8d8 --- /dev/null +++ b/libs/openssl/crypto/x509/by_dir.c @@ -0,0 +1,436 @@ +/* crypto/x509/by_dir.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "cryptlib.h" + +#ifndef NO_SYS_TYPES_H +# include +#endif +#ifndef OPENSSL_NO_POSIX_IO +# include +#endif + +#include +#include + +typedef struct lookup_dir_hashes_st { + unsigned long hash; + int suffix; +} BY_DIR_HASH; + +typedef struct lookup_dir_entry_st { + char *dir; + int dir_type; + STACK_OF(BY_DIR_HASH) *hashes; +} BY_DIR_ENTRY; + +typedef struct lookup_dir_st { + BUF_MEM *buffer; + STACK_OF(BY_DIR_ENTRY) *dirs; +} BY_DIR; + +DECLARE_STACK_OF(BY_DIR_HASH) +DECLARE_STACK_OF(BY_DIR_ENTRY) + +static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **ret); +static int new_dir(X509_LOOKUP *lu); +static void free_dir(X509_LOOKUP *lu); +static int add_cert_dir(BY_DIR *ctx, const char *dir, int type); +static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, + X509_OBJECT *ret); +X509_LOOKUP_METHOD x509_dir_lookup = { + "Load certs from files in a directory", + new_dir, /* new */ + free_dir, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + dir_ctrl, /* ctrl */ + get_cert_by_subject, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ +}; + +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void) +{ + return (&x509_dir_lookup); +} + +static int dir_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, long argl, + char **retp) +{ + int ret = 0; + BY_DIR *ld; + char *dir = NULL; + + ld = (BY_DIR *)ctx->method_data; + + switch (cmd) { + case X509_L_ADD_DIR: + if (argl == X509_FILETYPE_DEFAULT) { + dir = (char *)getenv(X509_get_default_cert_dir_env()); + if (dir) + ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM); + else + ret = add_cert_dir(ld, X509_get_default_cert_dir(), + X509_FILETYPE_PEM); + if (!ret) { + X509err(X509_F_DIR_CTRL, X509_R_LOADING_CERT_DIR); + } + } else + ret = add_cert_dir(ld, argp, (int)argl); + break; + } + return (ret); +} + +static int new_dir(X509_LOOKUP *lu) +{ + BY_DIR *a; + + if ((a = (BY_DIR *)OPENSSL_malloc(sizeof(BY_DIR))) == NULL) + return (0); + if ((a->buffer = BUF_MEM_new()) == NULL) { + OPENSSL_free(a); + return (0); + } + a->dirs = NULL; + lu->method_data = (char *)a; + return (1); +} + +static void by_dir_hash_free(BY_DIR_HASH *hash) +{ + OPENSSL_free(hash); +} + +static int by_dir_hash_cmp(const BY_DIR_HASH *const *a, + const BY_DIR_HASH *const *b) +{ + if ((*a)->hash > (*b)->hash) + return 1; + if ((*a)->hash < (*b)->hash) + return -1; + return 0; +} + +static void by_dir_entry_free(BY_DIR_ENTRY *ent) +{ + if (ent->dir) + OPENSSL_free(ent->dir); + if (ent->hashes) + sk_BY_DIR_HASH_pop_free(ent->hashes, by_dir_hash_free); + OPENSSL_free(ent); +} + +static void free_dir(X509_LOOKUP *lu) +{ + BY_DIR *a; + + a = (BY_DIR *)lu->method_data; + if (a->dirs != NULL) + sk_BY_DIR_ENTRY_pop_free(a->dirs, by_dir_entry_free); + if (a->buffer != NULL) + BUF_MEM_free(a->buffer); + OPENSSL_free(a); +} + +static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) +{ + int j, len; + const char *s, *ss, *p; + + if (dir == NULL || !*dir) { + X509err(X509_F_ADD_CERT_DIR, X509_R_INVALID_DIRECTORY); + return 0; + } + + s = dir; + p = s; + do { + if ((*p == LIST_SEPARATOR_CHAR) || (*p == '\0')) { + BY_DIR_ENTRY *ent; + ss = s; + s = p + 1; + len = (int)(p - ss); + if (len == 0) + continue; + for (j = 0; j < sk_BY_DIR_ENTRY_num(ctx->dirs); j++) { + ent = sk_BY_DIR_ENTRY_value(ctx->dirs, j); + if (strlen(ent->dir) == (size_t)len && + strncmp(ent->dir, ss, (unsigned int)len) == 0) + break; + } + if (j < sk_BY_DIR_ENTRY_num(ctx->dirs)) + continue; + if (ctx->dirs == NULL) { + ctx->dirs = sk_BY_DIR_ENTRY_new_null(); + if (!ctx->dirs) { + X509err(X509_F_ADD_CERT_DIR, ERR_R_MALLOC_FAILURE); + return 0; + } + } + ent = OPENSSL_malloc(sizeof(BY_DIR_ENTRY)); + if (!ent) + return 0; + ent->dir_type = type; + ent->hashes = sk_BY_DIR_HASH_new(by_dir_hash_cmp); + ent->dir = OPENSSL_malloc((unsigned int)len + 1); + if (!ent->dir || !ent->hashes) { + by_dir_entry_free(ent); + return 0; + } + strncpy(ent->dir, ss, (unsigned int)len); + ent->dir[len] = '\0'; + if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { + by_dir_entry_free(ent); + return 0; + } + } + } while (*p++ != '\0'); + return 1; +} + +static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name, + X509_OBJECT *ret) +{ + BY_DIR *ctx; + union { + struct { + X509 st_x509; + X509_CINF st_x509_cinf; + } x509; + struct { + X509_CRL st_crl; + X509_CRL_INFO st_crl_info; + } crl; + } data; + int ok = 0; + int i, j, k; + unsigned long h; + BUF_MEM *b = NULL; + X509_OBJECT stmp, *tmp; + const char *postfix = ""; + + if (name == NULL) + return (0); + + stmp.type = type; + if (type == X509_LU_X509) { + data.x509.st_x509.cert_info = &data.x509.st_x509_cinf; + data.x509.st_x509_cinf.subject = name; + stmp.data.x509 = &data.x509.st_x509; + postfix = ""; + } else if (type == X509_LU_CRL) { + data.crl.st_crl.crl = &data.crl.st_crl_info; + data.crl.st_crl_info.issuer = name; + stmp.data.crl = &data.crl.st_crl; + postfix = "r"; + } else { + X509err(X509_F_GET_CERT_BY_SUBJECT, X509_R_WRONG_LOOKUP_TYPE); + goto finish; + } + + if ((b = BUF_MEM_new()) == NULL) { + X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_BUF_LIB); + goto finish; + } + + ctx = (BY_DIR *)xl->method_data; + + h = X509_NAME_hash(name); + for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { + BY_DIR_ENTRY *ent; + int idx; + BY_DIR_HASH htmp, *hent; + ent = sk_BY_DIR_ENTRY_value(ctx->dirs, i); + j = strlen(ent->dir) + 1 + 8 + 6 + 1 + 1; + if (!BUF_MEM_grow(b, j)) { + X509err(X509_F_GET_CERT_BY_SUBJECT, ERR_R_MALLOC_FAILURE); + goto finish; + } + if (type == X509_LU_CRL && ent->hashes) { + htmp.hash = h; + CRYPTO_r_lock(CRYPTO_LOCK_X509_STORE); + idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); + if (idx >= 0) { + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + k = hent->suffix; + } else { + hent = NULL; + k = 0; + } + CRYPTO_r_unlock(CRYPTO_LOCK_X509_STORE); + } else { + k = 0; + hent = NULL; + } + for (;;) { + char c = '/'; +#ifdef OPENSSL_SYS_VMS + c = ent->dir[strlen(ent->dir) - 1]; + if (c != ':' && c != '>' && c != ']') { + /* + * If no separator is present, we assume the directory + * specifier is a logical name, and add a colon. We really + * should use better VMS routines for merging things like + * this, but this will do for now... -- Richard Levitte + */ + c = ':'; + } else { + c = '\0'; + } +#endif + if (c == '\0') { + /* + * This is special. When c == '\0', no directory separator + * should be added. + */ + BIO_snprintf(b->data, b->max, + "%s%08lx.%s%d", ent->dir, h, postfix, k); + } else { + BIO_snprintf(b->data, b->max, + "%s%c%08lx.%s%d", ent->dir, c, h, postfix, k); + } +#ifndef OPENSSL_NO_POSIX_IO +# ifdef _WIN32 +# define stat _stat +# endif + { + struct stat st; + if (stat(b->data, &st) < 0) + break; + } +#endif + /* found one. */ + if (type == X509_LU_X509) { + if ((X509_load_cert_file(xl, b->data, ent->dir_type)) == 0) + break; + } else if (type == X509_LU_CRL) { + if ((X509_load_crl_file(xl, b->data, ent->dir_type)) == 0) + break; + } + /* else case will caught higher up */ + k++; + } + + /* + * we have added it to the cache so now pull it out again + */ + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + j = sk_X509_OBJECT_find(xl->store_ctx->objs, &stmp); + if (j != -1) + tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, j); + else + tmp = NULL; + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + /* If a CRL, update the last file suffix added for this */ + + if (type == X509_LU_CRL) { + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + /* + * Look for entry again in case another thread added an entry + * first. + */ + if (!hent) { + htmp.hash = h; + idx = sk_BY_DIR_HASH_find(ent->hashes, &htmp); + if (idx >= 0) + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + } + if (!hent) { + hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); + hent->hash = h; + hent->suffix = k; + if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + OPENSSL_free(hent); + ok = 0; + goto finish; + } + } else if (hent->suffix < k) + hent->suffix = k; + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + } + + if (tmp != NULL) { + ok = 1; + ret->type = tmp->type; + memcpy(&ret->data, &tmp->data, sizeof(ret->data)); + /* + * If we were going to up the reference count, we would need to + * do it on a perl 'type' basis + */ + /*- CRYPTO_add(&tmp->data.x509->references,1, + CRYPTO_LOCK_X509);*/ + goto finish; + } + } + finish: + if (b != NULL) + BUF_MEM_free(b); + return (ok); +} diff --git a/libs/openssl/crypto/x509/by_file.c b/libs/openssl/crypto/x509/by_file.c new file mode 100644 index 00000000..43a07300 --- /dev/null +++ b/libs/openssl/crypto/x509/by_file.c @@ -0,0 +1,277 @@ +/* crypto/x509/by_file.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "cryptlib.h" +#include +#include +#include +#include + +#ifndef OPENSSL_NO_STDIO + +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); +X509_LOOKUP_METHOD x509_file_lookup = { + "Load file into cache", + NULL, /* new */ + NULL, /* free */ + NULL, /* init */ + NULL, /* shutdown */ + by_file_ctrl, /* ctrl */ + NULL, /* get_by_subject */ + NULL, /* get_by_issuer_serial */ + NULL, /* get_by_fingerprint */ + NULL, /* get_by_alias */ +}; + +X509_LOOKUP_METHOD *X509_LOOKUP_file(void) +{ + return (&x509_file_lookup); +} + +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argp, + long argl, char **ret) +{ + int ok = 0; + char *file; + + switch (cmd) { + case X509_L_FILE_LOAD: + if (argl == X509_FILETYPE_DEFAULT) { + file = (char *)getenv(X509_get_default_cert_file_env()); + if (file) + ok = (X509_load_cert_crl_file(ctx, file, + X509_FILETYPE_PEM) != 0); + + else + ok = (X509_load_cert_crl_file + (ctx, X509_get_default_cert_file(), + X509_FILETYPE_PEM) != 0); + + if (!ok) { + X509err(X509_F_BY_FILE_CTRL, X509_R_LOADING_DEFAULTS); + } + } else { + if (argl == X509_FILETYPE_PEM) + ok = (X509_load_cert_crl_file(ctx, argp, + X509_FILETYPE_PEM) != 0); + else + ok = (X509_load_cert_file(ctx, argp, (int)argl) != 0); + } + break; + } + return (ok); +} + +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type) +{ + int ret = 0; + BIO *in = NULL; + int i, count = 0; + X509 *x = NULL; + + if (file == NULL) + return (1); + in = BIO_new(BIO_s_file_internal()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); + if (x == NULL) { + if ((ERR_GET_REASON(ERR_peek_last_error()) == + PEM_R_NO_START_LINE) && (count > 0)) { + ERR_clear_error(); + break; + } else { + X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_PEM_LIB); + goto err; + } + } + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) + goto err; + count++; + X509_free(x); + x = NULL; + } + ret = count; + } else if (type == X509_FILETYPE_ASN1) { + x = d2i_X509_bio(in, NULL); + if (x == NULL) { + X509err(X509_F_X509_LOAD_CERT_FILE, ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) + goto err; + ret = i; + } else { + X509err(X509_F_X509_LOAD_CERT_FILE, X509_R_BAD_X509_FILETYPE); + goto err; + } + err: + if (x != NULL) + X509_free(x); + if (in != NULL) + BIO_free(in); + return (ret); +} + +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type) +{ + int ret = 0; + BIO *in = NULL; + int i, count = 0; + X509_CRL *x = NULL; + + if (file == NULL) + return (1); + in = BIO_new(BIO_s_file_internal()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_CRL(in, NULL, NULL, NULL); + if (x == NULL) { + if ((ERR_GET_REASON(ERR_peek_last_error()) == + PEM_R_NO_START_LINE) && (count > 0)) { + ERR_clear_error(); + break; + } else { + X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_PEM_LIB); + goto err; + } + } + i = X509_STORE_add_crl(ctx->store_ctx, x); + if (!i) + goto err; + count++; + X509_CRL_free(x); + x = NULL; + } + ret = count; + } else if (type == X509_FILETYPE_ASN1) { + x = d2i_X509_CRL_bio(in, NULL); + if (x == NULL) { + X509err(X509_F_X509_LOAD_CRL_FILE, ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_crl(ctx->store_ctx, x); + if (!i) + goto err; + ret = i; + } else { + X509err(X509_F_X509_LOAD_CRL_FILE, X509_R_BAD_X509_FILETYPE); + goto err; + } + err: + if (x != NULL) + X509_CRL_free(x); + if (in != NULL) + BIO_free(in); + return (ret); +} + +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type) +{ + STACK_OF(X509_INFO) *inf; + X509_INFO *itmp; + BIO *in; + int i, count = 0; + if (type != X509_FILETYPE_PEM) + return X509_load_cert_file(ctx, file, type); + in = BIO_new_file(file, "r"); + if (!in) { + X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_SYS_LIB); + return 0; + } + inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); + BIO_free(in); + if (!inf) { + X509err(X509_F_X509_LOAD_CERT_CRL_FILE, ERR_R_PEM_LIB); + return 0; + } + for (i = 0; i < sk_X509_INFO_num(inf); i++) { + itmp = sk_X509_INFO_value(inf, i); + if (itmp->x509) { + X509_STORE_add_cert(ctx->store_ctx, itmp->x509); + count++; + } + if (itmp->crl) { + X509_STORE_add_crl(ctx->store_ctx, itmp->crl); + count++; + } + } + sk_X509_INFO_pop_free(inf, X509_INFO_free); + return count; +} + +#endif /* OPENSSL_NO_STDIO */ diff --git a/libs/openssl/crypto/x509/verify_extra_test.c b/libs/openssl/crypto/x509/verify_extra_test.c new file mode 100644 index 00000000..a1e41f28 --- /dev/null +++ b/libs/openssl/crypto/x509/verify_extra_test.c @@ -0,0 +1,209 @@ +/* + * Written by Matt Caswell for the OpenSSL project. + */ +/* ==================================================================== + * Copyright (c) 1998-2015 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include + +static STACK_OF(X509) *load_certs_from_file(const char *filename) +{ + STACK_OF(X509) *certs; + BIO *bio; + X509 *x; + + bio = BIO_new_file(filename, "r"); + + if (bio == NULL) { + return NULL; + } + + certs = sk_X509_new_null(); + if (certs == NULL) { + BIO_free(bio); + return NULL; + } + + ERR_set_mark(); + do { + x = PEM_read_bio_X509(bio, NULL, 0, NULL); + if (x != NULL && !sk_X509_push(certs, x)) { + sk_X509_pop_free(certs, X509_free); + BIO_free(bio); + return NULL; + } else if (x == NULL) { + /* + * We probably just ran out of certs, so ignore any errors + * generated + */ + ERR_pop_to_mark(); + } + } while (x != NULL); + + BIO_free(bio); + + return certs; +} + +/* + * Test for CVE-2015-1793 (Alternate Chains Certificate Forgery) + * + * Chain is as follows: + * + * rootCA (self-signed) + * | + * interCA + * | + * subinterCA subinterCA (self-signed) + * | | + * leaf ------------------ + * | + * bad + * + * rootCA, interCA, subinterCA, subinterCA (ss) all have CA=TRUE + * leaf and bad have CA=FALSE + * + * subinterCA and subinterCA (ss) have the same subject name and keys + * + * interCA (but not rootCA) and subinterCA (ss) are in the trusted store + * (roots.pem) + * leaf and subinterCA are in the untrusted list (untrusted.pem) + * bad is the certificate being verified (bad.pem) + * + * Versions vulnerable to CVE-2015-1793 will fail to detect that leaf has + * CA=FALSE, and will therefore incorrectly verify bad + * + */ +static int test_alt_chains_cert_forgery(void) +{ + int ret = 0; + int i; + X509 *x = NULL; + STACK_OF(X509) *untrusted = NULL; + BIO *bio = NULL; + X509_STORE_CTX *sctx = NULL; + X509_STORE *store = NULL; + X509_LOOKUP *lookup = NULL; + + store = X509_STORE_new(); + if (store == NULL) + goto err; + + lookup = X509_STORE_add_lookup(store, X509_LOOKUP_file()); + if (lookup == NULL) + goto err; + if(!X509_LOOKUP_load_file(lookup, "certs/roots.pem", X509_FILETYPE_PEM)) + goto err; + + untrusted = load_certs_from_file("certs/untrusted.pem"); + + if ((bio = BIO_new_file("certs/bad.pem", "r")) == NULL) + goto err; + + if((x = PEM_read_bio_X509(bio, NULL, 0, NULL)) == NULL) + goto err; + + sctx = X509_STORE_CTX_new(); + if (sctx == NULL) + goto err; + + if (!X509_STORE_CTX_init(sctx, store, x, untrusted)) + goto err; + + i = X509_verify_cert(sctx); + + if(i == 0 && X509_STORE_CTX_get_error(sctx) + == X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT) { + /* This is the result we were expecting: Test passed */ + ret = 1; + } + err: + X509_STORE_CTX_free(sctx); + X509_free(x); + BIO_free(bio); + sk_X509_pop_free(untrusted, X509_free); + X509_STORE_free(store); + if (ret != 1) + ERR_print_errors_fp(stderr); + return ret; +} + +int main(void) +{ + CRYPTO_malloc_debug_init(); + CRYPTO_set_mem_debug_options(V_CRYPTO_MDEBUG_ALL); + CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); + + ERR_load_crypto_strings(); + OpenSSL_add_all_digests(); + + if (!test_alt_chains_cert_forgery()) { + fprintf(stderr, "Test alt chains cert forgery failed\n"); + return 1; + } + + EVP_cleanup(); + CRYPTO_cleanup_all_ex_data(); + ERR_remove_thread_state(NULL); + ERR_free_strings(); + CRYPTO_mem_leaks_fp(stderr); + + printf("PASS\n"); + return 0; +} diff --git a/libs/openssl/crypto/x509/x509.h b/libs/openssl/crypto/x509/x509.h new file mode 100644 index 00000000..bd600de4 --- /dev/null +++ b/libs/openssl/crypto/x509/x509.h @@ -0,0 +1,1302 @@ +/* crypto/x509/x509.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECDH support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_X509_H +# define HEADER_X509_H + +# include +# include +# ifndef OPENSSL_NO_BUFFER +# include +# endif +# ifndef OPENSSL_NO_EVP +# include +# endif +# ifndef OPENSSL_NO_BIO +# include +# endif +# include +# include +# include + +# ifndef OPENSSL_NO_EC +# include +# endif + +# ifndef OPENSSL_NO_ECDSA +# include +# endif + +# ifndef OPENSSL_NO_ECDH +# include +# endif + +# ifndef OPENSSL_NO_DEPRECATED +# ifndef OPENSSL_NO_RSA +# include +# endif +# ifndef OPENSSL_NO_DSA +# include +# endif +# ifndef OPENSSL_NO_DH +# include +# endif +# endif + +# ifndef OPENSSL_NO_SHA +# include +# endif +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# ifdef OPENSSL_SYS_WIN32 +/* Under Win32 these are defined in wincrypt.h */ +# undef X509_NAME +# undef X509_CERT_PAIR +# undef X509_EXTENSIONS +# endif + +# define X509_FILETYPE_PEM 1 +# define X509_FILETYPE_ASN1 2 +# define X509_FILETYPE_DEFAULT 3 + +# define X509v3_KU_DIGITAL_SIGNATURE 0x0080 +# define X509v3_KU_NON_REPUDIATION 0x0040 +# define X509v3_KU_KEY_ENCIPHERMENT 0x0020 +# define X509v3_KU_DATA_ENCIPHERMENT 0x0010 +# define X509v3_KU_KEY_AGREEMENT 0x0008 +# define X509v3_KU_KEY_CERT_SIGN 0x0004 +# define X509v3_KU_CRL_SIGN 0x0002 +# define X509v3_KU_ENCIPHER_ONLY 0x0001 +# define X509v3_KU_DECIPHER_ONLY 0x8000 +# define X509v3_KU_UNDEF 0xffff + +typedef struct X509_objects_st { + int nid; + int (*a2i) (void); + int (*i2a) (void); +} X509_OBJECTS; + +struct X509_algor_st { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; +} /* X509_ALGOR */ ; + +DECLARE_ASN1_SET_OF(X509_ALGOR) + +typedef STACK_OF(X509_ALGOR) X509_ALGORS; + +typedef struct X509_val_st { + ASN1_TIME *notBefore; + ASN1_TIME *notAfter; +} X509_VAL; + +struct X509_pubkey_st { + X509_ALGOR *algor; + ASN1_BIT_STRING *public_key; + EVP_PKEY *pkey; +}; + +typedef struct X509_sig_st { + X509_ALGOR *algor; + ASN1_OCTET_STRING *digest; +} X509_SIG; + +typedef struct X509_name_entry_st { + ASN1_OBJECT *object; + ASN1_STRING *value; + int set; + int size; /* temp variable */ +} X509_NAME_ENTRY; + +DECLARE_STACK_OF(X509_NAME_ENTRY) +DECLARE_ASN1_SET_OF(X509_NAME_ENTRY) + +/* we always keep X509_NAMEs in 2 forms. */ +struct X509_name_st { + STACK_OF(X509_NAME_ENTRY) *entries; + int modified; /* true if 'bytes' needs to be built */ +# ifndef OPENSSL_NO_BUFFER + BUF_MEM *bytes; +# else + char *bytes; +# endif +/* unsigned long hash; Keep the hash around for lookups */ + unsigned char *canon_enc; + int canon_enclen; +} /* X509_NAME */ ; + +DECLARE_STACK_OF(X509_NAME) + +# define X509_EX_V_NETSCAPE_HACK 0x8000 +# define X509_EX_V_INIT 0x0001 +typedef struct X509_extension_st { + ASN1_OBJECT *object; + ASN1_BOOLEAN critical; + ASN1_OCTET_STRING *value; +} X509_EXTENSION; + +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; + +DECLARE_STACK_OF(X509_EXTENSION) +DECLARE_ASN1_SET_OF(X509_EXTENSION) + +/* a sequence of these are used */ +typedef struct x509_attributes_st { + ASN1_OBJECT *object; + int single; /* 0 for a set, 1 for a single item (which is + * wrong) */ + union { + char *ptr; + /* + * 0 + */ STACK_OF(ASN1_TYPE) *set; + /* + * 1 + */ ASN1_TYPE *single; + } value; +} X509_ATTRIBUTE; + +DECLARE_STACK_OF(X509_ATTRIBUTE) +DECLARE_ASN1_SET_OF(X509_ATTRIBUTE) + +typedef struct X509_req_info_st { + ASN1_ENCODING enc; + ASN1_INTEGER *version; + X509_NAME *subject; + X509_PUBKEY *pubkey; + /* d=2 hl=2 l= 0 cons: cont: 00 */ + STACK_OF(X509_ATTRIBUTE) *attributes; /* [ 0 ] */ +} X509_REQ_INFO; + +typedef struct X509_req_st { + X509_REQ_INFO *req_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int references; +} X509_REQ; + +typedef struct x509_cinf_st { + ASN1_INTEGER *version; /* [ 0 ] default of v1 */ + ASN1_INTEGER *serialNumber; + X509_ALGOR *signature; + X509_NAME *issuer; + X509_VAL *validity; + X509_NAME *subject; + X509_PUBKEY *key; + ASN1_BIT_STRING *issuerUID; /* [ 1 ] optional in v2 */ + ASN1_BIT_STRING *subjectUID; /* [ 2 ] optional in v2 */ + STACK_OF(X509_EXTENSION) *extensions; /* [ 3 ] optional in v3 */ + ASN1_ENCODING enc; +} X509_CINF; + +/* + * This stuff is certificate "auxiliary info" it contains details which are + * useful in certificate stores and databases. When used this is tagged onto + * the end of the certificate itself + */ + +typedef struct x509_cert_aux_st { + STACK_OF(ASN1_OBJECT) *trust; /* trusted uses */ + STACK_OF(ASN1_OBJECT) *reject; /* rejected uses */ + ASN1_UTF8STRING *alias; /* "friendly name" */ + ASN1_OCTET_STRING *keyid; /* key id of private key */ + STACK_OF(X509_ALGOR) *other; /* other unspecified info */ +} X509_CERT_AUX; + +struct x509_st { + X509_CINF *cert_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int valid; + int references; + char *name; + CRYPTO_EX_DATA ex_data; + /* These contain copies of various extension values */ + long ex_pathlen; + long ex_pcpathlen; + unsigned long ex_flags; + unsigned long ex_kusage; + unsigned long ex_xkusage; + unsigned long ex_nscert; + ASN1_OCTET_STRING *skid; + AUTHORITY_KEYID *akid; + X509_POLICY_CACHE *policy_cache; + STACK_OF(DIST_POINT) *crldp; + STACK_OF(GENERAL_NAME) *altname; + NAME_CONSTRAINTS *nc; +# ifndef OPENSSL_NO_RFC3779 + STACK_OF(IPAddressFamily) *rfc3779_addr; + struct ASIdentifiers_st *rfc3779_asid; +# endif +# ifndef OPENSSL_NO_SHA + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; +# endif + X509_CERT_AUX *aux; +} /* X509 */ ; + +DECLARE_STACK_OF(X509) +DECLARE_ASN1_SET_OF(X509) + +/* This is used for a table of trust checking functions */ + +typedef struct x509_trust_st { + int trust; + int flags; + int (*check_trust) (struct x509_trust_st *, X509 *, int); + char *name; + int arg1; + void *arg2; +} X509_TRUST; + +DECLARE_STACK_OF(X509_TRUST) + +typedef struct x509_cert_pair_st { + X509 *forward; + X509 *reverse; +} X509_CERT_PAIR; + +/* standard trust ids */ + +# define X509_TRUST_DEFAULT -1/* Only valid in purpose settings */ + +# define X509_TRUST_COMPAT 1 +# define X509_TRUST_SSL_CLIENT 2 +# define X509_TRUST_SSL_SERVER 3 +# define X509_TRUST_EMAIL 4 +# define X509_TRUST_OBJECT_SIGN 5 +# define X509_TRUST_OCSP_SIGN 6 +# define X509_TRUST_OCSP_REQUEST 7 +# define X509_TRUST_TSA 8 + +/* Keep these up to date! */ +# define X509_TRUST_MIN 1 +# define X509_TRUST_MAX 8 + +/* trust_flags values */ +# define X509_TRUST_DYNAMIC 1 +# define X509_TRUST_DYNAMIC_NAME 2 + +/* check_trust return codes */ + +# define X509_TRUST_TRUSTED 1 +# define X509_TRUST_REJECTED 2 +# define X509_TRUST_UNTRUSTED 3 + +/* Flags for X509_print_ex() */ + +# define X509_FLAG_COMPAT 0 +# define X509_FLAG_NO_HEADER 1L +# define X509_FLAG_NO_VERSION (1L << 1) +# define X509_FLAG_NO_SERIAL (1L << 2) +# define X509_FLAG_NO_SIGNAME (1L << 3) +# define X509_FLAG_NO_ISSUER (1L << 4) +# define X509_FLAG_NO_VALIDITY (1L << 5) +# define X509_FLAG_NO_SUBJECT (1L << 6) +# define X509_FLAG_NO_PUBKEY (1L << 7) +# define X509_FLAG_NO_EXTENSIONS (1L << 8) +# define X509_FLAG_NO_SIGDUMP (1L << 9) +# define X509_FLAG_NO_AUX (1L << 10) +# define X509_FLAG_NO_ATTRIBUTES (1L << 11) + +/* Flags specific to X509_NAME_print_ex() */ + +/* The field separator information */ + +# define XN_FLAG_SEP_MASK (0xf << 16) + +# define XN_FLAG_COMPAT 0/* Traditional SSLeay: use old + * X509_NAME_print */ +# define XN_FLAG_SEP_COMMA_PLUS (1 << 16)/* RFC2253 ,+ */ +# define XN_FLAG_SEP_CPLUS_SPC (2 << 16)/* ,+ spaced: more readable */ +# define XN_FLAG_SEP_SPLUS_SPC (3 << 16)/* ;+ spaced */ +# define XN_FLAG_SEP_MULTILINE (4 << 16)/* One line per field */ + +# define XN_FLAG_DN_REV (1 << 20)/* Reverse DN order */ + +/* How the field name is shown */ + +# define XN_FLAG_FN_MASK (0x3 << 21) + +# define XN_FLAG_FN_SN 0/* Object short name */ +# define XN_FLAG_FN_LN (1 << 21)/* Object long name */ +# define XN_FLAG_FN_OID (2 << 21)/* Always use OIDs */ +# define XN_FLAG_FN_NONE (3 << 21)/* No field names */ + +# define XN_FLAG_SPC_EQ (1 << 23)/* Put spaces round '=' */ + +/* + * This determines if we dump fields we don't recognise: RFC2253 requires + * this. + */ + +# define XN_FLAG_DUMP_UNKNOWN_FIELDS (1 << 24) + +# define XN_FLAG_FN_ALIGN (1 << 25)/* Align field names to 20 + * characters */ + +/* Complete set of RFC2253 flags */ + +# define XN_FLAG_RFC2253 (ASN1_STRFLGS_RFC2253 | \ + XN_FLAG_SEP_COMMA_PLUS | \ + XN_FLAG_DN_REV | \ + XN_FLAG_FN_SN | \ + XN_FLAG_DUMP_UNKNOWN_FIELDS) + +/* readable oneline form */ + +# define XN_FLAG_ONELINE (ASN1_STRFLGS_RFC2253 | \ + ASN1_STRFLGS_ESC_QUOTE | \ + XN_FLAG_SEP_CPLUS_SPC | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_SN) + +/* readable multiline form */ + +# define XN_FLAG_MULTILINE (ASN1_STRFLGS_ESC_CTRL | \ + ASN1_STRFLGS_ESC_MSB | \ + XN_FLAG_SEP_MULTILINE | \ + XN_FLAG_SPC_EQ | \ + XN_FLAG_FN_LN | \ + XN_FLAG_FN_ALIGN) + +struct x509_revoked_st { + ASN1_INTEGER *serialNumber; + ASN1_TIME *revocationDate; + STACK_OF(X509_EXTENSION) /* optional */ *extensions; + /* Set up if indirect CRL */ + STACK_OF(GENERAL_NAME) *issuer; + /* Revocation reason */ + int reason; + int sequence; /* load sequence */ +}; + +DECLARE_STACK_OF(X509_REVOKED) +DECLARE_ASN1_SET_OF(X509_REVOKED) + +typedef struct X509_crl_info_st { + ASN1_INTEGER *version; + X509_ALGOR *sig_alg; + X509_NAME *issuer; + ASN1_TIME *lastUpdate; + ASN1_TIME *nextUpdate; + STACK_OF(X509_REVOKED) *revoked; + STACK_OF(X509_EXTENSION) /* [0] */ *extensions; + ASN1_ENCODING enc; +} X509_CRL_INFO; + +struct X509_crl_st { + /* actual signature */ + X509_CRL_INFO *crl; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + int references; + int flags; + /* Copies of various extensions */ + AUTHORITY_KEYID *akid; + ISSUING_DIST_POINT *idp; + /* Convenient breakdown of IDP */ + int idp_flags; + int idp_reasons; + /* CRL and base CRL numbers for delta processing */ + ASN1_INTEGER *crl_number; + ASN1_INTEGER *base_crl_number; +# ifndef OPENSSL_NO_SHA + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; +# endif + STACK_OF(GENERAL_NAMES) *issuers; + const X509_CRL_METHOD *meth; + void *meth_data; +} /* X509_CRL */ ; + +DECLARE_STACK_OF(X509_CRL) +DECLARE_ASN1_SET_OF(X509_CRL) + +typedef struct private_key_st { + int version; + /* The PKCS#8 data types */ + X509_ALGOR *enc_algor; + ASN1_OCTET_STRING *enc_pkey; /* encrypted pub key */ + /* When decrypted, the following will not be NULL */ + EVP_PKEY *dec_pkey; + /* used to encrypt and decrypt */ + int key_length; + char *key_data; + int key_free; /* true if we should auto free key_data */ + /* expanded version of 'enc_algor' */ + EVP_CIPHER_INFO cipher; + int references; +} X509_PKEY; + +# ifndef OPENSSL_NO_EVP +typedef struct X509_info_st { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; + int references; +} X509_INFO; + +DECLARE_STACK_OF(X509_INFO) +# endif + +/* + * The next 2 structures and their 8 routines were sent to me by Pat Richard + * and are used to manipulate Netscapes spki structures - + * useful if you are writing a CA web page + */ +typedef struct Netscape_spkac_st { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ +} NETSCAPE_SPKAC; + +typedef struct Netscape_spki_st { + NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ + X509_ALGOR *sig_algor; + ASN1_BIT_STRING *signature; +} NETSCAPE_SPKI; + +/* Netscape certificate sequence structure */ +typedef struct Netscape_certificate_sequence { + ASN1_OBJECT *type; + STACK_OF(X509) *certs; +} NETSCAPE_CERT_SEQUENCE; + +/*- Unused (and iv length is wrong) +typedef struct CBCParameter_st + { + unsigned char iv[8]; + } CBC_PARAM; +*/ + +/* Password based encryption structure */ + +typedef struct PBEPARAM_st { + ASN1_OCTET_STRING *salt; + ASN1_INTEGER *iter; +} PBEPARAM; + +/* Password based encryption V2 structures */ + +typedef struct PBE2PARAM_st { + X509_ALGOR *keyfunc; + X509_ALGOR *encryption; +} PBE2PARAM; + +typedef struct PBKDF2PARAM_st { +/* Usually OCTET STRING but could be anything */ + ASN1_TYPE *salt; + ASN1_INTEGER *iter; + ASN1_INTEGER *keylength; + X509_ALGOR *prf; +} PBKDF2PARAM; + +/* PKCS#8 private key info structure */ + +struct pkcs8_priv_key_info_st { + /* Flag for various broken formats */ + int broken; +# define PKCS8_OK 0 +# define PKCS8_NO_OCTET 1 +# define PKCS8_EMBEDDED_PARAM 2 +# define PKCS8_NS_DB 3 +# define PKCS8_NEG_PRIVKEY 4 + ASN1_INTEGER *version; + X509_ALGOR *pkeyalg; + /* Should be OCTET STRING but some are broken */ + ASN1_TYPE *pkey; + STACK_OF(X509_ATTRIBUTE) *attributes; +}; + +#ifdef __cplusplus +} +#endif + +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define X509_EXT_PACK_UNKNOWN 1 +# define X509_EXT_PACK_STRING 2 + +# define X509_get_version(x) ASN1_INTEGER_get((x)->cert_info->version) +/* #define X509_get_serialNumber(x) ((x)->cert_info->serialNumber) */ +# define X509_get_notBefore(x) ((x)->cert_info->validity->notBefore) +# define X509_get_notAfter(x) ((x)->cert_info->validity->notAfter) +# define X509_extract_key(x) X509_get_pubkey(x)/*****/ +# define X509_REQ_get_version(x) ASN1_INTEGER_get((x)->req_info->version) +# define X509_REQ_get_subject_name(x) ((x)->req_info->subject) +# define X509_REQ_extract_key(a) X509_REQ_get_pubkey(a) +# define X509_name_cmp(a,b) X509_NAME_cmp((a),(b)) +# define X509_get_signature_type(x) EVP_PKEY_type(OBJ_obj2nid((x)->sig_alg->algorithm)) + +# define X509_CRL_get_version(x) ASN1_INTEGER_get((x)->crl->version) +# define X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate) +# define X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate) +# define X509_CRL_get_issuer(x) ((x)->crl->issuer) +# define X509_CRL_get_REVOKED(x) ((x)->crl->revoked) + +void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); +X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl), + int (*crl_free) (X509_CRL *crl), + int (*crl_lookup) (X509_CRL *crl, + X509_REVOKED **ret, + ASN1_INTEGER *ser, + X509_NAME *issuer), + int (*crl_verify) (X509_CRL *crl, + EVP_PKEY *pk)); +void X509_CRL_METHOD_free(X509_CRL_METHOD *m); + +void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); +void *X509_CRL_get_meth_data(X509_CRL *crl); + +/* + * This one is only used so that a binary form can output, as in + * i2d_X509_NAME(X509_get_X509_PUBKEY(x),&buf) + */ +# define X509_get_X509_PUBKEY(x) ((x)->cert_info->key) + +const char *X509_verify_cert_error_string(long n); + +# ifndef OPENSSL_NO_EVP +int X509_verify(X509 *a, EVP_PKEY *r); + +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); +int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); + +NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len); +char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); + +int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); + +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent); +int X509_signature_print(BIO *bp, X509_ALGOR *alg, ASN1_STRING *sig); + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); + +int X509_pubkey_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, + unsigned char *md, unsigned int *len); +# endif + +# ifndef OPENSSL_NO_FP_API +X509 *d2i_X509_fp(FILE *fp, X509 **x509); +int i2d_X509_fp(FILE *fp, X509 *x509); +X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl); +int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl); +X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req); +int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req); +# ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa); +int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa); +RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa); +int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa); +RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa); +int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa); +# endif +# ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); +# endif +# ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); +# endif +X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8); +int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); +# endif + +# ifndef OPENSSL_NO_BIO +X509 *d2i_X509_bio(BIO *bp, X509 **x509); +int i2d_X509_bio(BIO *bp, X509 *x509); +X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl); +int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl); +X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req); +int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req); +# ifndef OPENSSL_NO_RSA +RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa); +int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa); +RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa); +int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa); +RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa); +int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa); +# endif +# ifndef OPENSSL_NO_DSA +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); +# endif +# ifndef OPENSSL_NO_EC +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); +# endif +X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8); +int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8); +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf); +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf); +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); +# endif + +X509 *X509_dup(X509 *x509); +X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); +X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); +X509_CRL *X509_CRL_dup(X509_CRL *crl); +X509_REQ *X509_REQ_dup(X509_REQ *req); +X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); +int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, + void *pval); +void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval, + X509_ALGOR *algor); +void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); +int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); + +X509_NAME *X509_NAME_dup(X509_NAME *xn); +X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); + +int X509_cmp_time(const ASN1_TIME *s, time_t *t); +int X509_cmp_current_time(const ASN1_TIME *s); +ASN1_TIME *X509_time_adj(ASN1_TIME *s, long adj, time_t *t); +ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *t); +ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj); + +const char *X509_get_default_cert_area(void); +const char *X509_get_default_cert_dir(void); +const char *X509_get_default_cert_file(void); +const char *X509_get_default_cert_dir_env(void); +const char *X509_get_default_cert_file_env(void); +const char *X509_get_default_private_dir(void); + +X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey); + +DECLARE_ASN1_FUNCTIONS(X509_ALGOR) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) +DECLARE_ASN1_FUNCTIONS(X509_VAL) + +DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) + +int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); +EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key); +int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain); +int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp); +EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length); +# ifndef OPENSSL_NO_RSA +int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp); +RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length); +# endif +# ifndef OPENSSL_NO_DSA +int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp); +DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length); +# endif +# ifndef OPENSSL_NO_EC +int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp); +EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length); +# endif + +DECLARE_ASN1_FUNCTIONS(X509_SIG) +DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) +DECLARE_ASN1_FUNCTIONS(X509_REQ) + +DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) +X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value); + +DECLARE_ASN1_FUNCTIONS(X509_EXTENSION) +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_EXTENSIONS, X509_EXTENSIONS, X509_EXTENSIONS) + +DECLARE_ASN1_FUNCTIONS(X509_NAME_ENTRY) + +DECLARE_ASN1_FUNCTIONS(X509_NAME) + +int X509_NAME_set(X509_NAME **xn, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(X509_CINF) + +DECLARE_ASN1_FUNCTIONS(X509) +DECLARE_ASN1_FUNCTIONS(X509_CERT_AUX) + +DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR) + +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); +int X509_set_ex_data(X509 *r, int idx, void *arg); +void *X509_get_ex_data(X509 *r, int idx); +int i2d_X509_AUX(X509 *a, unsigned char **pp); +X509 *d2i_X509_AUX(X509 **a, const unsigned char **pp, long length); + +int X509_alias_set1(X509 *x, unsigned char *name, int len); +int X509_keyid_set1(X509 *x, unsigned char *id, int len); +unsigned char *X509_alias_get0(X509 *x, int *len); +unsigned char *X509_keyid_get0(X509 *x, int *len); +int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, + int); +int X509_TRUST_set(int *t, int trust); +int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj); +int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj); +void X509_trust_clear(X509 *x); +void X509_reject_clear(X509 *x); + +DECLARE_ASN1_FUNCTIONS(X509_REVOKED) +DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) +DECLARE_ASN1_FUNCTIONS(X509_CRL) + +int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial); +int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); + +X509_PKEY *X509_PKEY_new(void); +void X509_PKEY_free(X509_PKEY *a); +int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp); +X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp, + long length); + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE) + +# ifndef OPENSSL_NO_EVP +X509_INFO *X509_INFO_new(void); +void X509_INFO_free(X509_INFO *a); +char *X509_NAME_oneline(X509_NAME *a, char *buf, int size); + +int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey); + +int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, + unsigned char *md, unsigned int *len); + +int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + char *data, EVP_PKEY *pkey, const EVP_MD *type); + +int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *data, + unsigned char *md, unsigned int *len); + +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature, void *data, EVP_PKEY *pkey); + +int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *data, + EVP_PKEY *pkey, const EVP_MD *type); +int ASN1_item_sign_ctx(const ASN1_ITEM *it, X509_ALGOR *algor1, + X509_ALGOR *algor2, ASN1_BIT_STRING *signature, + void *asn, EVP_MD_CTX *ctx); +# endif + +int X509_set_version(X509 *x, long version); +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); +ASN1_INTEGER *X509_get_serialNumber(X509 *x); +int X509_set_issuer_name(X509 *x, X509_NAME *name); +X509_NAME *X509_get_issuer_name(X509 *a); +int X509_set_subject_name(X509 *x, X509_NAME *name); +X509_NAME *X509_get_subject_name(X509 *a); +int X509_set_notBefore(X509 *x, const ASN1_TIME *tm); +int X509_set_notAfter(X509 *x, const ASN1_TIME *tm); +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); +EVP_PKEY *X509_get_pubkey(X509 *x); +ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x); +int X509_certificate_type(X509 *x, EVP_PKEY *pubkey /* optional */ ); + +int X509_REQ_set_version(X509_REQ *x, long version); +int X509_REQ_set_subject_name(X509_REQ *req, X509_NAME *name); +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); +EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req); +int X509_REQ_extension_nid(int nid); +int *X509_REQ_get_extension_nids(void); +void X509_REQ_set_extension_nids(int *nids); +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid); +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); +int X509_REQ_get_attr_count(const X509_REQ *req); +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos); +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len); +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_CRL_set_version(X509_CRL *x, long version); +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); +int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); +int X509_CRL_sort(X509_CRL *crl); + +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); +int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); + +int X509_REQ_check_private_key(X509_REQ *x509, EVP_PKEY *pkey); + +int X509_check_private_key(X509 *x509, EVP_PKEY *pkey); + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_and_serial_hash(X509 *a); + +int X509_issuer_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_issuer_name_hash(X509 *a); + +int X509_subject_name_cmp(const X509 *a, const X509 *b); +unsigned long X509_subject_name_hash(X509 *x); + +# ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_name_hash_old(X509 *a); +unsigned long X509_subject_name_hash_old(X509 *x); +# endif + +int X509_cmp(const X509 *a, const X509 *b); +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +unsigned long X509_NAME_hash(X509_NAME *x); +unsigned long X509_NAME_hash_old(X509_NAME *x); + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); +# ifndef OPENSSL_NO_FP_API +int X509_print_ex_fp(FILE *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +int X509_print_fp(FILE *bp, X509 *x); +int X509_CRL_print_fp(FILE *bp, X509_CRL *x); +int X509_REQ_print_fp(FILE *bp, X509_REQ *req); +int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, + unsigned long flags); +# endif + +# ifndef OPENSSL_NO_BIO +int X509_NAME_print(BIO *bp, X509_NAME *name, int obase); +int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, + unsigned long flags); +int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflag, + unsigned long cflag); +int X509_print(BIO *bp, X509 *x); +int X509_ocspid_print(BIO *bp, X509 *x); +int X509_CERT_AUX_print(BIO *bp, X509_CERT_AUX *x, int indent); +int X509_CRL_print(BIO *bp, X509_CRL *x); +int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, + unsigned long cflag); +int X509_REQ_print(BIO *bp, X509_REQ *req); +# endif + +int X509_NAME_entry_count(X509_NAME *name); +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len); +int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, + char *buf, int len); + +/* + * NOTE: you should be passsing -1, not 0 as lastpos. The functions that use + * lastpos, search after that position on. + */ +int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos); +int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, + int lastpos); +X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); +int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, + int loc, int set); +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, + unsigned char *bytes, int len, int loc, + int set); +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + unsigned char *bytes, int len, int loc, + int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, + const unsigned char *bytes, + int len); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type, unsigned char *bytes, + int len); +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, + int set); +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + ASN1_OBJECT *obj, int type, + const unsigned char *bytes, + int len); +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj); +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len); +ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); +ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + ASN1_OBJECT *obj, int lastpos); +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc); + +int X509_get_ext_count(X509 *x); +int X509_get_ext_by_NID(X509 *x, int nid, int lastpos); +int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos); +int X509_get_ext_by_critical(X509 *x, int crit, int lastpos); +X509_EXTENSION *X509_get_ext(X509 *x, int loc); +X509_EXTENSION *X509_delete_ext(X509 *x, int loc); +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); +void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx); +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_CRL_get_ext_count(X509_CRL *x); +int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos); +int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos); +int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos); +X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc); +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); +void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx); +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags); + +int X509_REVOKED_get_ext_count(X509_REVOKED *x); +int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos); +int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj, + int lastpos); +int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos); +X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc); +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc); +void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx); +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags); + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, + int nid, int crit, + ASN1_OCTET_STRING *data); +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + ASN1_OBJECT *obj, int crit, + ASN1_OCTET_STRING *data); +int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj); +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); +int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data); +ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex); +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); +int X509_EXTENSION_get_critical(X509_EXTENSION *ex); + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos); +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, + ASN1_OBJECT *obj, int lastpos); +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) + **x, const ASN1_OBJECT *obj, + int type, + const unsigned char *bytes, + int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) + **x, int nid, int type, + const unsigned char *bytes, + int len); +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) + **x, const char *attrname, + int type, + const unsigned char *bytes, + int len); +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, ASN1_OBJECT *obj, + int lastpos, int type); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, + int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, + int atrtype, const void *data, + int len); +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, + const unsigned char *bytes, + int len); +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, + const void *data, int len); +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, int atrtype, + void *data); +int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr); +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); + +int EVP_PKEY_get_attr_count(const EVP_PKEY *key); +int EVP_PKEY_get_attr_by_NID(const EVP_PKEY *key, int nid, int lastpos); +int EVP_PKEY_get_attr_by_OBJ(const EVP_PKEY *key, ASN1_OBJECT *obj, + int lastpos); +X509_ATTRIBUTE *EVP_PKEY_get_attr(const EVP_PKEY *key, int loc); +X509_ATTRIBUTE *EVP_PKEY_delete_attr(EVP_PKEY *key, int loc); +int EVP_PKEY_add1_attr(EVP_PKEY *key, X509_ATTRIBUTE *attr); +int EVP_PKEY_add1_attr_by_OBJ(EVP_PKEY *key, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_NID(EVP_PKEY *key, + int nid, int type, + const unsigned char *bytes, int len); +int EVP_PKEY_add1_attr_by_txt(EVP_PKEY *key, + const char *attrname, int type, + const unsigned char *bytes, int len); + +int X509_verify_cert(X509_STORE_CTX *ctx); + +/* lookup a cert from a X509 STACK */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, + ASN1_INTEGER *serial); +X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name); + +DECLARE_ASN1_FUNCTIONS(PBEPARAM) +DECLARE_ASN1_FUNCTIONS(PBE2PARAM) +DECLARE_ASN1_FUNCTIONS(PBKDF2PARAM) + +int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter, + const unsigned char *salt, int saltlen); + +X509_ALGOR *PKCS5_pbe_set(int alg, int iter, + const unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen); +X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter, + unsigned char *salt, int saltlen, + unsigned char *aiv, int prf_nid); + +X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen, + int prf_nid, int keylen); + +/* PKCS#8 utilities */ + +DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken); +PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken); + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, int ptype, void *pval, + unsigned char *penc, int penclen); +int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8); + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen); +int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, X509_PUBKEY *pub); + +int X509_check_trust(X509 *x, int id, int flags); +int X509_TRUST_get_count(void); +X509_TRUST *X509_TRUST_get0(int idx); +int X509_TRUST_get_by_id(int id); +int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), + char *name, int arg1, void *arg2); +void X509_TRUST_cleanup(void); +int X509_TRUST_get_flags(X509_TRUST *xp); +char *X509_TRUST_get0_name(X509_TRUST *xp); +int X509_TRUST_get_trust(X509_TRUST *xp); + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_X509_strings(void); + +/* Error codes for the X509 functions. */ + +/* Function codes. */ +# define X509_F_ADD_CERT_DIR 100 +# define X509_F_BY_FILE_CTRL 101 +# define X509_F_CHECK_POLICY 145 +# define X509_F_DIR_CTRL 102 +# define X509_F_GET_CERT_BY_SUBJECT 103 +# define X509_F_NETSCAPE_SPKI_B64_DECODE 129 +# define X509_F_NETSCAPE_SPKI_B64_ENCODE 130 +# define X509_F_X509AT_ADD1_ATTR 135 +# define X509_F_X509V3_ADD_EXT 104 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_NID 136 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ 137 +# define X509_F_X509_ATTRIBUTE_CREATE_BY_TXT 140 +# define X509_F_X509_ATTRIBUTE_GET0_DATA 139 +# define X509_F_X509_ATTRIBUTE_SET1_DATA 138 +# define X509_F_X509_CHECK_PRIVATE_KEY 128 +# define X509_F_X509_CRL_PRINT_FP 147 +# define X509_F_X509_EXTENSION_CREATE_BY_NID 108 +# define X509_F_X509_EXTENSION_CREATE_BY_OBJ 109 +# define X509_F_X509_GET_PUBKEY_PARAMETERS 110 +# define X509_F_X509_LOAD_CERT_CRL_FILE 132 +# define X509_F_X509_LOAD_CERT_FILE 111 +# define X509_F_X509_LOAD_CRL_FILE 112 +# define X509_F_X509_NAME_ADD_ENTRY 113 +# define X509_F_X509_NAME_ENTRY_CREATE_BY_NID 114 +# define X509_F_X509_NAME_ENTRY_CREATE_BY_TXT 131 +# define X509_F_X509_NAME_ENTRY_SET_OBJECT 115 +# define X509_F_X509_NAME_ONELINE 116 +# define X509_F_X509_NAME_PRINT 117 +# define X509_F_X509_PRINT_EX_FP 118 +# define X509_F_X509_PUBKEY_GET 119 +# define X509_F_X509_PUBKEY_SET 120 +# define X509_F_X509_REQ_CHECK_PRIVATE_KEY 144 +# define X509_F_X509_REQ_PRINT_EX 121 +# define X509_F_X509_REQ_PRINT_FP 122 +# define X509_F_X509_REQ_TO_X509 123 +# define X509_F_X509_STORE_ADD_CERT 124 +# define X509_F_X509_STORE_ADD_CRL 125 +# define X509_F_X509_STORE_CTX_GET1_ISSUER 146 +# define X509_F_X509_STORE_CTX_INIT 143 +# define X509_F_X509_STORE_CTX_NEW 142 +# define X509_F_X509_STORE_CTX_PURPOSE_INHERIT 134 +# define X509_F_X509_TO_X509_REQ 126 +# define X509_F_X509_TRUST_ADD 133 +# define X509_F_X509_TRUST_SET 141 +# define X509_F_X509_VERIFY_CERT 127 + +/* Reason codes. */ +# define X509_R_BAD_X509_FILETYPE 100 +# define X509_R_BASE64_DECODE_ERROR 118 +# define X509_R_CANT_CHECK_DH_KEY 114 +# define X509_R_CERT_ALREADY_IN_HASH_TABLE 101 +# define X509_R_ERR_ASN1_LIB 102 +# define X509_R_INVALID_DIRECTORY 113 +# define X509_R_INVALID_FIELD_NAME 119 +# define X509_R_INVALID_TRUST 123 +# define X509_R_KEY_TYPE_MISMATCH 115 +# define X509_R_KEY_VALUES_MISMATCH 116 +# define X509_R_LOADING_CERT_DIR 103 +# define X509_R_LOADING_DEFAULTS 104 +# define X509_R_METHOD_NOT_SUPPORTED 124 +# define X509_R_NAME_TOO_LONG 134 +# define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 105 +# define X509_R_PUBLIC_KEY_DECODE_ERROR 125 +# define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 +# define X509_R_SHOULD_RETRY 106 +# define X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN 107 +# define X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY 108 +# define X509_R_UNKNOWN_KEY_TYPE 117 +# define X509_R_UNKNOWN_NID 109 +# define X509_R_UNKNOWN_PURPOSE_ID 121 +# define X509_R_UNKNOWN_TRUST_ID 120 +# define X509_R_UNSUPPORTED_ALGORITHM 111 +# define X509_R_WRONG_LOOKUP_TYPE 112 +# define X509_R_WRONG_TYPE 122 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/x509/x509_att.c b/libs/openssl/crypto/x509/x509_att.c new file mode 100644 index 00000000..bd59281f --- /dev/null +++ b/libs/openssl/crypto/x509/x509_att.c @@ -0,0 +1,384 @@ +/* crypto/x509/x509_att.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include + +int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x) +{ + return sk_X509_ATTRIBUTE_num(x); +} + +int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-2); + return (X509at_get_attr_by_OBJ(x, obj, lastpos)); +} + +int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, + ASN1_OBJECT *obj, int lastpos) +{ + int n; + X509_ATTRIBUTE *ex; + + if (sk == NULL) + return (-1); + lastpos++; + if (lastpos < 0) + lastpos = 0; + n = sk_X509_ATTRIBUTE_num(sk); + for (; lastpos < n; lastpos++) { + ex = sk_X509_ATTRIBUTE_value(sk, lastpos); + if (OBJ_cmp(ex->object, obj) == 0) + return (lastpos); + } + return (-1); +} + +X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc) +{ + if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) + return NULL; + else + return sk_X509_ATTRIBUTE_value(x, loc); +} + +X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc) +{ + X509_ATTRIBUTE *ret; + + if (x == NULL || sk_X509_ATTRIBUTE_num(x) <= loc || loc < 0) + return (NULL); + ret = sk_X509_ATTRIBUTE_delete(x, loc); + return (ret); +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr) +{ + X509_ATTRIBUTE *new_attr = NULL; + STACK_OF(X509_ATTRIBUTE) *sk = NULL; + + if (x == NULL) { + X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_PASSED_NULL_PARAMETER); + goto err2; + } + + if (*x == NULL) { + if ((sk = sk_X509_ATTRIBUTE_new_null()) == NULL) + goto err; + } else + sk = *x; + + if ((new_attr = X509_ATTRIBUTE_dup(attr)) == NULL) + goto err2; + if (!sk_X509_ATTRIBUTE_push(sk, new_attr)) + goto err; + if (*x == NULL) + *x = sk; + return (sk); + err: + X509err(X509_F_X509AT_ADD1_ATTR, ERR_R_MALLOC_FAILURE); + err2: + if (new_attr != NULL) + X509_ATTRIBUTE_free(new_attr); + if (sk != NULL) + sk_X509_ATTRIBUTE_free(sk); + return (NULL); +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_OBJ(STACK_OF(X509_ATTRIBUTE) + **x, const ASN1_OBJECT *obj, + int type, + const unsigned char *bytes, + int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_OBJ(NULL, obj, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) + **x, int nid, int type, + const unsigned char *bytes, + int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_NID(NULL, nid, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_txt(STACK_OF(X509_ATTRIBUTE) + **x, const char *attrname, + int type, + const unsigned char *bytes, + int len) +{ + X509_ATTRIBUTE *attr; + STACK_OF(X509_ATTRIBUTE) *ret; + attr = X509_ATTRIBUTE_create_by_txt(NULL, attrname, type, bytes, len); + if (!attr) + return 0; + ret = X509at_add1_attr(x, attr); + X509_ATTRIBUTE_free(attr); + return ret; +} + +void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, + ASN1_OBJECT *obj, int lastpos, int type) +{ + int i; + X509_ATTRIBUTE *at; + i = X509at_get_attr_by_OBJ(x, obj, lastpos); + if (i == -1) + return NULL; + if ((lastpos <= -2) && (X509at_get_attr_by_OBJ(x, obj, i) != -1)) + return NULL; + at = X509at_get_attr(x, i); + if (lastpos <= -3 && (X509_ATTRIBUTE_count(at) != 1)) + return NULL; + return X509_ATTRIBUTE_get0_data(at, 0, type, NULL); +} + +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, + int len) +{ + ASN1_OBJECT *obj; + X509_ATTRIBUTE *ret; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_NID, X509_R_UNKNOWN_NID); + return (NULL); + } + ret = X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len); + if (ret == NULL) + ASN1_OBJECT_free(obj); + return (ret); +} + +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, + int atrtype, const void *data, + int len) +{ + X509_ATTRIBUTE *ret; + + if ((attr == NULL) || (*attr == NULL)) { + if ((ret = X509_ATTRIBUTE_new()) == NULL) { + X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ, + ERR_R_MALLOC_FAILURE); + return (NULL); + } + } else + ret = *attr; + + if (!X509_ATTRIBUTE_set1_object(ret, obj)) + goto err; + if (!X509_ATTRIBUTE_set1_data(ret, atrtype, data, len)) + goto err; + + if ((attr != NULL) && (*attr == NULL)) + *attr = ret; + return (ret); + err: + if ((attr == NULL) || (ret != *attr)) + X509_ATTRIBUTE_free(ret); + return (NULL); +} + +X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, + const unsigned char *bytes, + int len) +{ + ASN1_OBJECT *obj; + X509_ATTRIBUTE *nattr; + + obj = OBJ_txt2obj(atrname, 0); + if (obj == NULL) { + X509err(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT, + X509_R_INVALID_FIELD_NAME); + ERR_add_error_data(2, "name=", atrname); + return (NULL); + } + nattr = X509_ATTRIBUTE_create_by_OBJ(attr, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nattr; +} + +int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj) +{ + if ((attr == NULL) || (obj == NULL)) + return (0); + ASN1_OBJECT_free(attr->object); + attr->object = OBJ_dup(obj); + return (1); +} + +int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, + const void *data, int len) +{ + ASN1_TYPE *ttmp; + ASN1_STRING *stmp = NULL; + int atype = 0; + if (!attr) + return 0; + if (attrtype & MBSTRING_FLAG) { + stmp = ASN1_STRING_set_by_NID(NULL, data, len, attrtype, + OBJ_obj2nid(attr->object)); + if (!stmp) { + X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_ASN1_LIB); + return 0; + } + atype = stmp->type; + } else if (len != -1) { + if (!(stmp = ASN1_STRING_type_new(attrtype))) + goto err; + if (!ASN1_STRING_set(stmp, data, len)) + goto err; + atype = attrtype; + } + if (!(attr->value.set = sk_ASN1_TYPE_new_null())) + goto err; + attr->single = 0; + /* + * This is a bit naughty because the attribute should really have at + * least one value but some types use and zero length SET and require + * this. + */ + if (attrtype == 0) + return 1; + if (!(ttmp = ASN1_TYPE_new())) + goto err; + if ((len == -1) && !(attrtype & MBSTRING_FLAG)) { + if (!ASN1_TYPE_set1(ttmp, attrtype, data)) + goto err; + } else + ASN1_TYPE_set(ttmp, atype, stmp); + if (!sk_ASN1_TYPE_push(attr->value.set, ttmp)) + goto err; + return 1; + err: + X509err(X509_F_X509_ATTRIBUTE_SET1_DATA, ERR_R_MALLOC_FAILURE); + return 0; +} + +int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr) +{ + if (!attr->single) + return sk_ASN1_TYPE_num(attr->value.set); + if (attr->value.single) + return 1; + return 0; +} + +ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr) +{ + if (attr == NULL) + return (NULL); + return (attr->object); +} + +void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, + int atrtype, void *data) +{ + ASN1_TYPE *ttmp; + ttmp = X509_ATTRIBUTE_get0_type(attr, idx); + if (!ttmp) + return NULL; + if (atrtype != ASN1_TYPE_get(ttmp)) { + X509err(X509_F_X509_ATTRIBUTE_GET0_DATA, X509_R_WRONG_TYPE); + return NULL; + } + return ttmp->value.ptr; +} + +ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx) +{ + if (attr == NULL) + return (NULL); + if (idx >= X509_ATTRIBUTE_count(attr)) + return NULL; + if (!attr->single) + return sk_ASN1_TYPE_value(attr->value.set, idx); + else + return attr->value.single; +} diff --git a/libs/openssl/crypto/x509/x509_cmp.c b/libs/openssl/crypto/x509/x509_cmp.c new file mode 100644 index 00000000..5792e7f5 --- /dev/null +++ b/libs/openssl/crypto/x509/x509_cmp.c @@ -0,0 +1,354 @@ +/* crypto/x509/x509_cmp.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include + +int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b) +{ + int i; + X509_CINF *ai, *bi; + + ai = a->cert_info; + bi = b->cert_info; + i = M_ASN1_INTEGER_cmp(ai->serialNumber, bi->serialNumber); + if (i) + return (i); + return (X509_NAME_cmp(ai->issuer, bi->issuer)); +} + +#ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_and_serial_hash(X509 *a) +{ + unsigned long ret = 0; + EVP_MD_CTX ctx; + unsigned char md[16]; + char *f; + + EVP_MD_CTX_init(&ctx); + f = X509_NAME_oneline(a->cert_info->issuer, NULL, 0); + if (!EVP_DigestInit_ex(&ctx, EVP_md5(), NULL)) + goto err; + if (!EVP_DigestUpdate(&ctx, (unsigned char *)f, strlen(f))) + goto err; + OPENSSL_free(f); + if (!EVP_DigestUpdate + (&ctx, (unsigned char *)a->cert_info->serialNumber->data, + (unsigned long)a->cert_info->serialNumber->length)) + goto err; + if (!EVP_DigestFinal_ex(&ctx, &(md[0]), NULL)) + goto err; + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) + ) & 0xffffffffL; + err: + EVP_MD_CTX_cleanup(&ctx); + return (ret); +} +#endif + +int X509_issuer_name_cmp(const X509 *a, const X509 *b) +{ + return (X509_NAME_cmp(a->cert_info->issuer, b->cert_info->issuer)); +} + +int X509_subject_name_cmp(const X509 *a, const X509 *b) +{ + return (X509_NAME_cmp(a->cert_info->subject, b->cert_info->subject)); +} + +int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b) +{ + return (X509_NAME_cmp(a->crl->issuer, b->crl->issuer)); +} + +#ifndef OPENSSL_NO_SHA +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) +{ + return memcmp(a->sha1_hash, b->sha1_hash, 20); +} +#endif + +X509_NAME *X509_get_issuer_name(X509 *a) +{ + return (a->cert_info->issuer); +} + +unsigned long X509_issuer_name_hash(X509 *x) +{ + return (X509_NAME_hash(x->cert_info->issuer)); +} + +#ifndef OPENSSL_NO_MD5 +unsigned long X509_issuer_name_hash_old(X509 *x) +{ + return (X509_NAME_hash_old(x->cert_info->issuer)); +} +#endif + +X509_NAME *X509_get_subject_name(X509 *a) +{ + return (a->cert_info->subject); +} + +ASN1_INTEGER *X509_get_serialNumber(X509 *a) +{ + return (a->cert_info->serialNumber); +} + +unsigned long X509_subject_name_hash(X509 *x) +{ + return (X509_NAME_hash(x->cert_info->subject)); +} + +#ifndef OPENSSL_NO_MD5 +unsigned long X509_subject_name_hash_old(X509 *x) +{ + return (X509_NAME_hash_old(x->cert_info->subject)); +} +#endif + +#ifndef OPENSSL_NO_SHA +/* + * Compare two certificates: they must be identical for this to work. NB: + * Although "cmp" operations are generally prototyped to take "const" + * arguments (eg. for use in STACKs), the way X509 handling is - these + * operations may involve ensuring the hashes are up-to-date and ensuring + * certain cert information is cached. So this is the point where the + * "depth-first" constification tree has to halt with an evil cast. + */ +int X509_cmp(const X509 *a, const X509 *b) +{ + int rv; + + /* ensure hash is valid */ + X509_check_purpose((X509 *)a, -1, 0); + X509_check_purpose((X509 *)b, -1, 0); + + rv = memcmp(a->sha1_hash, b->sha1_hash, SHA_DIGEST_LENGTH); + if (rv) + return rv; + /* Check for match against stored encoding too */ + if (!a->cert_info->enc.modified && !b->cert_info->enc.modified) { + rv = (int)(a->cert_info->enc.len - b->cert_info->enc.len); + if (rv) + return rv; + return memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc, + a->cert_info->enc.len); + } + return rv; +} +#endif + +int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b) +{ + int ret; + + /* Ensure canonical encoding is present and up to date */ + + if (!a->canon_enc || a->modified) { + ret = i2d_X509_NAME((X509_NAME *)a, NULL); + if (ret < 0) + return -2; + } + + if (!b->canon_enc || b->modified) { + ret = i2d_X509_NAME((X509_NAME *)b, NULL); + if (ret < 0) + return -2; + } + + ret = a->canon_enclen - b->canon_enclen; + + if (ret) + return ret; + + return memcmp(a->canon_enc, b->canon_enc, a->canon_enclen); + +} + +unsigned long X509_NAME_hash(X509_NAME *x) +{ + unsigned long ret = 0; + unsigned char md[SHA_DIGEST_LENGTH]; + + /* Make sure X509_NAME structure contains valid cached encoding */ + i2d_X509_NAME(x, NULL); + if (!EVP_Digest(x->canon_enc, x->canon_enclen, md, NULL, EVP_sha1(), + NULL)) + return 0; + + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) + ) & 0xffffffffL; + return (ret); +} + +#ifndef OPENSSL_NO_MD5 +/* + * I now DER encode the name and hash it. Since I cache the DER encoding, + * this is reasonably efficient. + */ + +unsigned long X509_NAME_hash_old(X509_NAME *x) +{ + EVP_MD_CTX md_ctx; + unsigned long ret = 0; + unsigned char md[16]; + + /* Make sure X509_NAME structure contains valid cached encoding */ + i2d_X509_NAME(x, NULL); + EVP_MD_CTX_init(&md_ctx); + EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + if (EVP_DigestInit_ex(&md_ctx, EVP_md5(), NULL) + && EVP_DigestUpdate(&md_ctx, x->bytes->data, x->bytes->length) + && EVP_DigestFinal_ex(&md_ctx, md, NULL)) + ret = (((unsigned long)md[0]) | ((unsigned long)md[1] << 8L) | + ((unsigned long)md[2] << 16L) | ((unsigned long)md[3] << 24L) + ) & 0xffffffffL; + EVP_MD_CTX_cleanup(&md_ctx); + + return (ret); +} +#endif + +/* Search a stack of X509 for a match */ +X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk, X509_NAME *name, + ASN1_INTEGER *serial) +{ + int i; + X509_CINF cinf; + X509 x, *x509 = NULL; + + if (!sk) + return NULL; + + x.cert_info = &cinf; + cinf.serialNumber = serial; + cinf.issuer = name; + + for (i = 0; i < sk_X509_num(sk); i++) { + x509 = sk_X509_value(sk, i); + if (X509_issuer_and_serial_cmp(x509, &x) == 0) + return (x509); + } + return (NULL); +} + +X509 *X509_find_by_subject(STACK_OF(X509) *sk, X509_NAME *name) +{ + X509 *x509; + int i; + + for (i = 0; i < sk_X509_num(sk); i++) { + x509 = sk_X509_value(sk, i); + if (X509_NAME_cmp(X509_get_subject_name(x509), name) == 0) + return (x509); + } + return (NULL); +} + +EVP_PKEY *X509_get_pubkey(X509 *x) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (NULL); + return (X509_PUBKEY_get(x->cert_info->key)); +} + +ASN1_BIT_STRING *X509_get0_pubkey_bitstr(const X509 *x) +{ + if (!x) + return NULL; + return x->cert_info->key->public_key; +} + +int X509_check_private_key(X509 *x, EVP_PKEY *k) +{ + EVP_PKEY *xk; + int ret; + + xk = X509_get_pubkey(x); + + if (xk) + ret = EVP_PKEY_cmp(xk, k); + else + ret = -2; + + switch (ret) { + case 1: + break; + case 0: + X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH); + break; + case -2: + X509err(X509_F_X509_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE); + } + if (xk) + EVP_PKEY_free(xk); + if (ret > 0) + return 1; + return 0; +} diff --git a/libs/openssl/crypto/x509/x509_d2.c b/libs/openssl/crypto/x509/x509_d2.c new file mode 100644 index 00000000..50ca2a6d --- /dev/null +++ b/libs/openssl/crypto/x509/x509_d2.c @@ -0,0 +1,109 @@ +/* crypto/x509/x509_d2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +#ifndef OPENSSL_NO_STDIO +int X509_STORE_set_default_paths(X509_STORE *ctx) +{ + X509_LOOKUP *lookup; + + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); + if (lookup == NULL) + return (0); + X509_LOOKUP_load_file(lookup, NULL, X509_FILETYPE_DEFAULT); + + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + return (0); + X509_LOOKUP_add_dir(lookup, NULL, X509_FILETYPE_DEFAULT); + + /* clear any errors */ + ERR_clear_error(); + + return (1); +} + +int X509_STORE_load_locations(X509_STORE *ctx, const char *file, + const char *path) +{ + X509_LOOKUP *lookup; + + if (file != NULL) { + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_file()); + if (lookup == NULL) + return (0); + if (X509_LOOKUP_load_file(lookup, file, X509_FILETYPE_PEM) != 1) + return (0); + } + if (path != NULL) { + lookup = X509_STORE_add_lookup(ctx, X509_LOOKUP_hash_dir()); + if (lookup == NULL) + return (0); + if (X509_LOOKUP_add_dir(lookup, path, X509_FILETYPE_PEM) != 1) + return (0); + } + if ((path == NULL) && (file == NULL)) + return (0); + return (1); +} + +#endif diff --git a/libs/openssl/crypto/x509/x509_def.c b/libs/openssl/crypto/x509/x509_def.c new file mode 100644 index 00000000..25c55375 --- /dev/null +++ b/libs/openssl/crypto/x509/x509_def.c @@ -0,0 +1,92 @@ +/* crypto/x509/x509_def.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include + +const char *X509_get_default_private_dir(void) +{ + return (X509_PRIVATE_DIR); +} + +const char *X509_get_default_cert_area(void) +{ + return (X509_CERT_AREA); +} + +const char *X509_get_default_cert_dir(void) +{ + return (X509_CERT_DIR); +} + +const char *X509_get_default_cert_file(void) +{ + return (X509_CERT_FILE); +} + +const char *X509_get_default_cert_dir_env(void) +{ + return (X509_CERT_DIR_EVP); +} + +const char *X509_get_default_cert_file_env(void) +{ + return (X509_CERT_FILE_EVP); +} diff --git a/libs/openssl/crypto/x509/x509_err.c b/libs/openssl/crypto/x509/x509_err.c new file mode 100644 index 00000000..a2b8b7fc --- /dev/null +++ b/libs/openssl/crypto/x509/x509_err.c @@ -0,0 +1,179 @@ +/* crypto/x509/x509_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509,0,reason) + +static ERR_STRING_DATA X509_str_functs[] = { + {ERR_FUNC(X509_F_ADD_CERT_DIR), "ADD_CERT_DIR"}, + {ERR_FUNC(X509_F_BY_FILE_CTRL), "BY_FILE_CTRL"}, + {ERR_FUNC(X509_F_CHECK_POLICY), "CHECK_POLICY"}, + {ERR_FUNC(X509_F_DIR_CTRL), "DIR_CTRL"}, + {ERR_FUNC(X509_F_GET_CERT_BY_SUBJECT), "GET_CERT_BY_SUBJECT"}, + {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_DECODE), "NETSCAPE_SPKI_b64_decode"}, + {ERR_FUNC(X509_F_NETSCAPE_SPKI_B64_ENCODE), "NETSCAPE_SPKI_b64_encode"}, + {ERR_FUNC(X509_F_X509AT_ADD1_ATTR), "X509at_add1_attr"}, + {ERR_FUNC(X509_F_X509V3_ADD_EXT), "X509v3_add_ext"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_NID), + "X509_ATTRIBUTE_create_by_NID"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_OBJ), + "X509_ATTRIBUTE_create_by_OBJ"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_CREATE_BY_TXT), + "X509_ATTRIBUTE_create_by_txt"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_GET0_DATA), "X509_ATTRIBUTE_get0_data"}, + {ERR_FUNC(X509_F_X509_ATTRIBUTE_SET1_DATA), "X509_ATTRIBUTE_set1_data"}, + {ERR_FUNC(X509_F_X509_CHECK_PRIVATE_KEY), "X509_check_private_key"}, + {ERR_FUNC(X509_F_X509_CRL_PRINT_FP), "X509_CRL_print_fp"}, + {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_NID), + "X509_EXTENSION_create_by_NID"}, + {ERR_FUNC(X509_F_X509_EXTENSION_CREATE_BY_OBJ), + "X509_EXTENSION_create_by_OBJ"}, + {ERR_FUNC(X509_F_X509_GET_PUBKEY_PARAMETERS), + "X509_get_pubkey_parameters"}, + {ERR_FUNC(X509_F_X509_LOAD_CERT_CRL_FILE), "X509_load_cert_crl_file"}, + {ERR_FUNC(X509_F_X509_LOAD_CERT_FILE), "X509_load_cert_file"}, + {ERR_FUNC(X509_F_X509_LOAD_CRL_FILE), "X509_load_crl_file"}, + {ERR_FUNC(X509_F_X509_NAME_ADD_ENTRY), "X509_NAME_add_entry"}, + {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_NID), + "X509_NAME_ENTRY_create_by_NID"}, + {ERR_FUNC(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT), + "X509_NAME_ENTRY_create_by_txt"}, + {ERR_FUNC(X509_F_X509_NAME_ENTRY_SET_OBJECT), + "X509_NAME_ENTRY_set_object"}, + {ERR_FUNC(X509_F_X509_NAME_ONELINE), "X509_NAME_oneline"}, + {ERR_FUNC(X509_F_X509_NAME_PRINT), "X509_NAME_print"}, + {ERR_FUNC(X509_F_X509_PRINT_EX_FP), "X509_print_ex_fp"}, + {ERR_FUNC(X509_F_X509_PUBKEY_GET), "X509_PUBKEY_get"}, + {ERR_FUNC(X509_F_X509_PUBKEY_SET), "X509_PUBKEY_set"}, + {ERR_FUNC(X509_F_X509_REQ_CHECK_PRIVATE_KEY), + "X509_REQ_check_private_key"}, + {ERR_FUNC(X509_F_X509_REQ_PRINT_EX), "X509_REQ_print_ex"}, + {ERR_FUNC(X509_F_X509_REQ_PRINT_FP), "X509_REQ_print_fp"}, + {ERR_FUNC(X509_F_X509_REQ_TO_X509), "X509_REQ_to_X509"}, + {ERR_FUNC(X509_F_X509_STORE_ADD_CERT), "X509_STORE_add_cert"}, + {ERR_FUNC(X509_F_X509_STORE_ADD_CRL), "X509_STORE_add_crl"}, + {ERR_FUNC(X509_F_X509_STORE_CTX_GET1_ISSUER), + "X509_STORE_CTX_get1_issuer"}, + {ERR_FUNC(X509_F_X509_STORE_CTX_INIT), "X509_STORE_CTX_init"}, + {ERR_FUNC(X509_F_X509_STORE_CTX_NEW), "X509_STORE_CTX_new"}, + {ERR_FUNC(X509_F_X509_STORE_CTX_PURPOSE_INHERIT), + "X509_STORE_CTX_purpose_inherit"}, + {ERR_FUNC(X509_F_X509_TO_X509_REQ), "X509_to_X509_REQ"}, + {ERR_FUNC(X509_F_X509_TRUST_ADD), "X509_TRUST_add"}, + {ERR_FUNC(X509_F_X509_TRUST_SET), "X509_TRUST_set"}, + {ERR_FUNC(X509_F_X509_VERIFY_CERT), "X509_verify_cert"}, + {0, NULL} +}; + +static ERR_STRING_DATA X509_str_reasons[] = { + {ERR_REASON(X509_R_BAD_X509_FILETYPE), "bad x509 filetype"}, + {ERR_REASON(X509_R_BASE64_DECODE_ERROR), "base64 decode error"}, + {ERR_REASON(X509_R_CANT_CHECK_DH_KEY), "cant check dh key"}, + {ERR_REASON(X509_R_CERT_ALREADY_IN_HASH_TABLE), + "cert already in hash table"}, + {ERR_REASON(X509_R_ERR_ASN1_LIB), "err asn1 lib"}, + {ERR_REASON(X509_R_INVALID_DIRECTORY), "invalid directory"}, + {ERR_REASON(X509_R_INVALID_FIELD_NAME), "invalid field name"}, + {ERR_REASON(X509_R_INVALID_TRUST), "invalid trust"}, + {ERR_REASON(X509_R_KEY_TYPE_MISMATCH), "key type mismatch"}, + {ERR_REASON(X509_R_KEY_VALUES_MISMATCH), "key values mismatch"}, + {ERR_REASON(X509_R_LOADING_CERT_DIR), "loading cert dir"}, + {ERR_REASON(X509_R_LOADING_DEFAULTS), "loading defaults"}, + {ERR_REASON(X509_R_METHOD_NOT_SUPPORTED), "method not supported"}, + {ERR_REASON(X509_R_NAME_TOO_LONG), "name too long"}, + {ERR_REASON(X509_R_NO_CERT_SET_FOR_US_TO_VERIFY), + "no cert set for us to verify"}, + {ERR_REASON(X509_R_PUBLIC_KEY_DECODE_ERROR), "public key decode error"}, + {ERR_REASON(X509_R_PUBLIC_KEY_ENCODE_ERROR), "public key encode error"}, + {ERR_REASON(X509_R_SHOULD_RETRY), "should retry"}, + {ERR_REASON(X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN), + "unable to find parameters in chain"}, + {ERR_REASON(X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY), + "unable to get certs public key"}, + {ERR_REASON(X509_R_UNKNOWN_KEY_TYPE), "unknown key type"}, + {ERR_REASON(X509_R_UNKNOWN_NID), "unknown nid"}, + {ERR_REASON(X509_R_UNKNOWN_PURPOSE_ID), "unknown purpose id"}, + {ERR_REASON(X509_R_UNKNOWN_TRUST_ID), "unknown trust id"}, + {ERR_REASON(X509_R_UNSUPPORTED_ALGORITHM), "unsupported algorithm"}, + {ERR_REASON(X509_R_WRONG_LOOKUP_TYPE), "wrong lookup type"}, + {ERR_REASON(X509_R_WRONG_TYPE), "wrong type"}, + {0, NULL} +}; + +#endif + +void ERR_load_X509_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(X509_str_functs[0].error) == NULL) { + ERR_load_strings(0, X509_str_functs); + ERR_load_strings(0, X509_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/x509/x509_ext.c b/libs/openssl/crypto/x509/x509_ext.c new file mode 100644 index 00000000..fb4e311d --- /dev/null +++ b/libs/openssl/crypto/x509/x509_ext.c @@ -0,0 +1,211 @@ +/* crypto/x509/x509_ext.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include + +int X509_CRL_get_ext_count(X509_CRL *x) +{ + return (X509v3_get_ext_count(x->crl->extensions)); +} + +int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->crl->extensions, nid, lastpos)); +} + +int X509_CRL_get_ext_by_OBJ(X509_CRL *x, ASN1_OBJECT *obj, int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->crl->extensions, obj, lastpos)); +} + +int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical(x->crl->extensions, crit, lastpos)); +} + +X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc) +{ + return (X509v3_get_ext(x->crl->extensions, loc)); +} + +X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc) +{ + return (X509v3_delete_ext(x->crl->extensions, loc)); +} + +void *X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->crl->extensions, nid, crit, idx); +} + +int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->crl->extensions, nid, value, crit, flags); +} + +int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->crl->extensions), ex, loc) != NULL); +} + +int X509_get_ext_count(X509 *x) +{ + return (X509v3_get_ext_count(x->cert_info->extensions)); +} + +int X509_get_ext_by_NID(X509 *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->cert_info->extensions, nid, lastpos)); +} + +int X509_get_ext_by_OBJ(X509 *x, ASN1_OBJECT *obj, int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->cert_info->extensions, obj, lastpos)); +} + +int X509_get_ext_by_critical(X509 *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical + (x->cert_info->extensions, crit, lastpos)); +} + +X509_EXTENSION *X509_get_ext(X509 *x, int loc) +{ + return (X509v3_get_ext(x->cert_info->extensions, loc)); +} + +X509_EXTENSION *X509_delete_ext(X509 *x, int loc) +{ + return (X509v3_delete_ext(x->cert_info->extensions, loc)); +} + +int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->cert_info->extensions), ex, loc) != NULL); +} + +void *X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->cert_info->extensions, nid, crit, idx); +} + +int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->cert_info->extensions, nid, value, crit, + flags); +} + +int X509_REVOKED_get_ext_count(X509_REVOKED *x) +{ + return (X509v3_get_ext_count(x->extensions)); +} + +int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos) +{ + return (X509v3_get_ext_by_NID(x->extensions, nid, lastpos)); +} + +int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x, ASN1_OBJECT *obj, + int lastpos) +{ + return (X509v3_get_ext_by_OBJ(x->extensions, obj, lastpos)); +} + +int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos) +{ + return (X509v3_get_ext_by_critical(x->extensions, crit, lastpos)); +} + +X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc) +{ + return (X509v3_get_ext(x->extensions, loc)); +} + +X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc) +{ + return (X509v3_delete_ext(x->extensions, loc)); +} + +int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc) +{ + return (X509v3_add_ext(&(x->extensions), ex, loc) != NULL); +} + +void *X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx) +{ + return X509V3_get_d2i(x->extensions, nid, crit, idx); +} + +int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags) +{ + return X509V3_add1_i2d(&x->extensions, nid, value, crit, flags); +} + +IMPLEMENT_STACK_OF(X509_EXTENSION) + +IMPLEMENT_ASN1_SET_OF(X509_EXTENSION) diff --git a/libs/openssl/crypto/x509/x509_lu.c b/libs/openssl/crypto/x509/x509_lu.c new file mode 100644 index 00000000..8084c4a4 --- /dev/null +++ b/libs/openssl/crypto/x509/x509_lu.c @@ -0,0 +1,684 @@ +/* crypto/x509/x509_lu.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method) +{ + X509_LOOKUP *ret; + + ret = (X509_LOOKUP *)OPENSSL_malloc(sizeof(X509_LOOKUP)); + if (ret == NULL) + return NULL; + + ret->init = 0; + ret->skip = 0; + ret->method = method; + ret->method_data = NULL; + ret->store_ctx = NULL; + if ((method->new_item != NULL) && !method->new_item(ret)) { + OPENSSL_free(ret); + return NULL; + } + return ret; +} + +void X509_LOOKUP_free(X509_LOOKUP *ctx) +{ + if (ctx == NULL) + return; + if ((ctx->method != NULL) && (ctx->method->free != NULL)) + (*ctx->method->free) (ctx); + OPENSSL_free(ctx); +} + +int X509_LOOKUP_init(X509_LOOKUP *ctx) +{ + if (ctx->method == NULL) + return 0; + if (ctx->method->init != NULL) + return ctx->method->init(ctx); + else + return 1; +} + +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx) +{ + if (ctx->method == NULL) + return 0; + if (ctx->method->shutdown != NULL) + return ctx->method->shutdown(ctx); + else + return 1; +} + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret) +{ + if (ctx->method == NULL) + return -1; + if (ctx->method->ctrl != NULL) + return ctx->method->ctrl(ctx, cmd, argc, argl, ret); + else + return 1; +} + +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_subject == NULL)) + return X509_LU_FAIL; + if (ctx->skip) + return 0; + return ctx->method->get_by_subject(ctx, type, name, ret); +} + +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_issuer_serial == NULL)) + return X509_LU_FAIL; + return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret); +} + +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, + X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_fingerprint == NULL)) + return X509_LU_FAIL; + return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret); +} + +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, + X509_OBJECT *ret) +{ + if ((ctx->method == NULL) || (ctx->method->get_by_alias == NULL)) + return X509_LU_FAIL; + return ctx->method->get_by_alias(ctx, type, str, len, ret); +} + +static int x509_object_cmp(const X509_OBJECT *const *a, + const X509_OBJECT *const *b) +{ + int ret; + + ret = ((*a)->type - (*b)->type); + if (ret) + return ret; + switch ((*a)->type) { + case X509_LU_X509: + ret = X509_subject_name_cmp((*a)->data.x509, (*b)->data.x509); + break; + case X509_LU_CRL: + ret = X509_CRL_cmp((*a)->data.crl, (*b)->data.crl); + break; + default: + /* abort(); */ + return 0; + } + return ret; +} + +X509_STORE *X509_STORE_new(void) +{ + X509_STORE *ret; + + if ((ret = (X509_STORE *)OPENSSL_malloc(sizeof(X509_STORE))) == NULL) + return NULL; + ret->objs = sk_X509_OBJECT_new(x509_object_cmp); + ret->cache = 1; + ret->get_cert_methods = sk_X509_LOOKUP_new_null(); + ret->verify = 0; + ret->verify_cb = 0; + + if ((ret->param = X509_VERIFY_PARAM_new()) == NULL) + return NULL; + + ret->get_issuer = 0; + ret->check_issued = 0; + ret->check_revocation = 0; + ret->get_crl = 0; + ret->check_crl = 0; + ret->cert_crl = 0; + ret->lookup_certs = 0; + ret->lookup_crls = 0; + ret->cleanup = 0; + + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE, ret, &ret->ex_data)) { + sk_X509_OBJECT_free(ret->objs); + OPENSSL_free(ret); + return NULL; + } + + ret->references = 1; + return ret; +} + +static void cleanup(X509_OBJECT *a) +{ + if (!a) + return; + if (a->type == X509_LU_X509) { + X509_free(a->data.x509); + } else if (a->type == X509_LU_CRL) { + X509_CRL_free(a->data.crl); + } else { + /* abort(); */ + } + + OPENSSL_free(a); +} + +void X509_STORE_free(X509_STORE *vfy) +{ + int i; + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + + if (vfy == NULL) + return; + + sk = vfy->get_cert_methods; + for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { + lu = sk_X509_LOOKUP_value(sk, i); + X509_LOOKUP_shutdown(lu); + X509_LOOKUP_free(lu); + } + sk_X509_LOOKUP_free(sk); + sk_X509_OBJECT_pop_free(vfy->objs, cleanup); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE, vfy, &vfy->ex_data); + if (vfy->param) + X509_VERIFY_PARAM_free(vfy->param); + OPENSSL_free(vfy); +} + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m) +{ + int i; + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + + sk = v->get_cert_methods; + for (i = 0; i < sk_X509_LOOKUP_num(sk); i++) { + lu = sk_X509_LOOKUP_value(sk, i); + if (m == lu->method) { + return lu; + } + } + /* a new one */ + lu = X509_LOOKUP_new(m); + if (lu == NULL) + return NULL; + else { + lu->store_ctx = v; + if (sk_X509_LOOKUP_push(v->get_cert_methods, lu)) + return lu; + else { + X509_LOOKUP_free(lu); + return NULL; + } + } +} + +int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, + X509_OBJECT *ret) +{ + X509_STORE *ctx = vs->ctx; + X509_LOOKUP *lu; + X509_OBJECT stmp, *tmp; + int i, j; + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + if (tmp == NULL || type == X509_LU_CRL) { + for (i = vs->current_method; + i < sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { + lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); + j = X509_LOOKUP_by_subject(lu, type, name, &stmp); + if (j < 0) { + vs->current_method = j; + return j; + } else if (j) { + tmp = &stmp; + break; + } + } + vs->current_method = 0; + if (tmp == NULL) + return 0; + } + +/*- if (ret->data.ptr != NULL) + X509_OBJECT_free_contents(ret); */ + + ret->type = tmp->type; + ret->data.ptr = tmp->data.ptr; + + X509_OBJECT_up_ref_count(ret); + + return 1; +} + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x) +{ + X509_OBJECT *obj; + int ret = 1; + + if (x == NULL) + return 0; + obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); + if (obj == NULL) { + X509err(X509_F_X509_STORE_ADD_CERT, ERR_R_MALLOC_FAILURE); + return 0; + } + obj->type = X509_LU_X509; + obj->data.x509 = x; + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + + X509_OBJECT_up_ref_count(obj); + + if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + X509err(X509_F_X509_STORE_ADD_CERT, + X509_R_CERT_ALREADY_IN_HASH_TABLE); + ret = 0; + } else + sk_X509_OBJECT_push(ctx->objs, obj); + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + return ret; +} + +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x) +{ + X509_OBJECT *obj; + int ret = 1; + + if (x == NULL) + return 0; + obj = (X509_OBJECT *)OPENSSL_malloc(sizeof(X509_OBJECT)); + if (obj == NULL) { + X509err(X509_F_X509_STORE_ADD_CRL, ERR_R_MALLOC_FAILURE); + return 0; + } + obj->type = X509_LU_CRL; + obj->data.crl = x; + + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + + X509_OBJECT_up_ref_count(obj); + + if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + X509err(X509_F_X509_STORE_ADD_CRL, X509_R_CERT_ALREADY_IN_HASH_TABLE); + ret = 0; + } else + sk_X509_OBJECT_push(ctx->objs, obj); + + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + + return ret; +} + +void X509_OBJECT_up_ref_count(X509_OBJECT *a) +{ + switch (a->type) { + case X509_LU_X509: + CRYPTO_add(&a->data.x509->references, 1, CRYPTO_LOCK_X509); + break; + case X509_LU_CRL: + CRYPTO_add(&a->data.crl->references, 1, CRYPTO_LOCK_X509_CRL); + break; + } +} + +void X509_OBJECT_free_contents(X509_OBJECT *a) +{ + switch (a->type) { + case X509_LU_X509: + X509_free(a->data.x509); + break; + case X509_LU_CRL: + X509_CRL_free(a->data.crl); + break; + } +} + +static int x509_object_idx_cnt(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name, int *pnmatch) +{ + X509_OBJECT stmp; + X509 x509_s; + X509_CINF cinf_s; + X509_CRL crl_s; + X509_CRL_INFO crl_info_s; + int idx; + + stmp.type = type; + switch (type) { + case X509_LU_X509: + stmp.data.x509 = &x509_s; + x509_s.cert_info = &cinf_s; + cinf_s.subject = name; + break; + case X509_LU_CRL: + stmp.data.crl = &crl_s; + crl_s.crl = &crl_info_s; + crl_info_s.issuer = name; + break; + default: + /* abort(); */ + return -1; + } + + idx = sk_X509_OBJECT_find(h, &stmp); + if (idx >= 0 && pnmatch) { + int tidx; + const X509_OBJECT *tobj, *pstmp; + *pnmatch = 1; + pstmp = &stmp; + for (tidx = idx + 1; tidx < sk_X509_OBJECT_num(h); tidx++) { + tobj = sk_X509_OBJECT_value(h, tidx); + if (x509_object_cmp(&tobj, &pstmp)) + break; + (*pnmatch)++; + } + } + return idx; +} + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name) +{ + return x509_object_idx_cnt(h, type, name, NULL); +} + +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, + int type, X509_NAME *name) +{ + int idx; + idx = X509_OBJECT_idx_by_subject(h, type, name); + if (idx == -1) + return NULL; + return sk_X509_OBJECT_value(h, idx); +} + +STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *ctx, X509_NAME *nm) +{ + int i, idx, cnt; + STACK_OF(X509) *sk; + X509 *x; + X509_OBJECT *obj; + sk = sk_X509_new_null(); + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); + if (idx < 0) { + /* + * Nothing found in cache: do lookup to possibly add new objects to + * cache + */ + X509_OBJECT xobj; + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) { + sk_X509_free(sk); + return NULL; + } + X509_OBJECT_free_contents(&xobj); + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); + if (idx < 0) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + sk_X509_free(sk); + return NULL; + } + } + for (i = 0; i < cnt; i++, idx++) { + obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); + x = obj->data.x509; + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + if (!sk_X509_push(sk, x)) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + X509_free(x); + sk_X509_pop_free(sk, X509_free); + return NULL; + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + return sk; + +} + +STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *ctx, X509_NAME *nm) +{ + int i, idx, cnt; + STACK_OF(X509_CRL) *sk; + X509_CRL *x; + X509_OBJECT *obj, xobj; + sk = sk_X509_CRL_new_null(); + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + + /* + * Always do lookup to possibly add new CRLs to cache + */ + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + if (!X509_STORE_get_by_subject(ctx, X509_LU_CRL, nm, &xobj)) { + sk_X509_CRL_free(sk); + return NULL; + } + X509_OBJECT_free_contents(&xobj); + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); + if (idx < 0) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + sk_X509_CRL_free(sk); + return NULL; + } + + for (i = 0; i < cnt; i++, idx++) { + obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx); + x = obj->data.crl; + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL); + if (!sk_X509_CRL_push(sk, x)) { + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + X509_CRL_free(x); + sk_X509_CRL_pop_free(sk, X509_CRL_free); + return NULL; + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + return sk; +} + +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x) +{ + int idx, i; + X509_OBJECT *obj; + idx = sk_X509_OBJECT_find(h, x); + if (idx == -1) + return NULL; + if ((x->type != X509_LU_X509) && (x->type != X509_LU_CRL)) + return sk_X509_OBJECT_value(h, idx); + for (i = idx; i < sk_X509_OBJECT_num(h); i++) { + obj = sk_X509_OBJECT_value(h, i); + if (x509_object_cmp + ((const X509_OBJECT **)&obj, (const X509_OBJECT **)&x)) + return NULL; + if (x->type == X509_LU_X509) { + if (!X509_cmp(obj->data.x509, x->data.x509)) + return obj; + } else if (x->type == X509_LU_CRL) { + if (!X509_CRL_match(obj->data.crl, x->data.crl)) + return obj; + } else + return obj; + } + return NULL; +} + +/*- + * Try to get issuer certificate from store. Due to limitations + * of the API this can only retrieve a single certificate matching + * a given subject name. However it will fill the cache with all + * matching certificates, so we can examine the cache for all + * matches. + * + * Return values are: + * 1 lookup successful. + * 0 certificate not found. + * -1 some other error. + */ +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) +{ + X509_NAME *xn; + X509_OBJECT obj, *pobj; + int i, ok, idx, ret; + xn = X509_get_issuer_name(x); + ok = X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj); + if (ok != X509_LU_X509) { + if (ok == X509_LU_RETRY) { + X509_OBJECT_free_contents(&obj); + X509err(X509_F_X509_STORE_CTX_GET1_ISSUER, X509_R_SHOULD_RETRY); + return -1; + } else if (ok != X509_LU_FAIL) { + X509_OBJECT_free_contents(&obj); + /* not good :-(, break anyway */ + return -1; + } + return 0; + } + /* If certificate matches all OK */ + if (ctx->check_issued(ctx, x, obj.data.x509)) { + *issuer = obj.data.x509; + return 1; + } + X509_OBJECT_free_contents(&obj); + + /* Else find index of first cert accepted by 'check_issued' */ + ret = 0; + CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); + idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); + if (idx != -1) { /* should be true as we've had at least one + * match */ + /* Look through all matching certs for suitable issuer */ + for (i = idx; i < sk_X509_OBJECT_num(ctx->ctx->objs); i++) { + pobj = sk_X509_OBJECT_value(ctx->ctx->objs, i); + /* See if we've run past the matches */ + if (pobj->type != X509_LU_X509) + break; + if (X509_NAME_cmp(xn, X509_get_subject_name(pobj->data.x509))) + break; + if (ctx->check_issued(ctx, x, pobj->data.x509)) { + *issuer = pobj->data.x509; + X509_OBJECT_up_ref_count(pobj); + ret = 1; + break; + } + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); + return ret; +} + +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags) +{ + return X509_VERIFY_PARAM_set_flags(ctx->param, flags); +} + +int X509_STORE_set_depth(X509_STORE *ctx, int depth) +{ + X509_VERIFY_PARAM_set_depth(ctx->param, depth); + return 1; +} + +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose) +{ + return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); +} + +int X509_STORE_set_trust(X509_STORE *ctx, int trust) +{ + return X509_VERIFY_PARAM_set_trust(ctx->param, trust); +} + +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *param) +{ + return X509_VERIFY_PARAM_set1(ctx->param, param); +} + +void X509_STORE_set_verify_cb(X509_STORE *ctx, + int (*verify_cb) (int, X509_STORE_CTX *)) +{ + ctx->verify_cb = verify_cb; +} + +IMPLEMENT_STACK_OF(X509_LOOKUP) + +IMPLEMENT_STACK_OF(X509_OBJECT) diff --git a/libs/openssl/crypto/x509/x509_obj.c b/libs/openssl/crypto/x509/x509_obj.c new file mode 100644 index 00000000..3de3ac72 --- /dev/null +++ b/libs/openssl/crypto/x509/x509_obj.c @@ -0,0 +1,230 @@ +/* crypto/x509/x509_obj.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +/* + * Limit to ensure we don't overflow: much greater than + * anything enountered in practice. + */ + +#define NAME_ONELINE_MAX (1024 * 1024) + +char *X509_NAME_oneline(X509_NAME *a, char *buf, int len) +{ + X509_NAME_ENTRY *ne; + int i; + int n, lold, l, l1, l2, num, j, type; + const char *s; + char *p; + unsigned char *q; + BUF_MEM *b = NULL; + static const char hex[17] = "0123456789ABCDEF"; + int gs_doit[4]; + char tmp_buf[80]; +#ifdef CHARSET_EBCDIC + char ebcdic_buf[1024]; +#endif + + if (buf == NULL) { + if ((b = BUF_MEM_new()) == NULL) + goto err; + if (!BUF_MEM_grow(b, 200)) + goto err; + b->data[0] = '\0'; + len = 200; + } else if (len == 0) { + return NULL; + } + if (a == NULL) { + if (b) { + buf = b->data; + OPENSSL_free(b); + } + strncpy(buf, "NO X509_NAME", len); + buf[len - 1] = '\0'; + return buf; + } + + len--; /* space for '\0' */ + l = 0; + for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) { + ne = sk_X509_NAME_ENTRY_value(a->entries, i); + n = OBJ_obj2nid(ne->object); + if ((n == NID_undef) || ((s = OBJ_nid2sn(n)) == NULL)) { + i2t_ASN1_OBJECT(tmp_buf, sizeof(tmp_buf), ne->object); + s = tmp_buf; + } + l1 = strlen(s); + + type = ne->value->type; + num = ne->value->length; + if (num > NAME_ONELINE_MAX) { + X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG); + goto end; + } + q = ne->value->data; +#ifdef CHARSET_EBCDIC + if (type == V_ASN1_GENERALSTRING || + type == V_ASN1_VISIBLESTRING || + type == V_ASN1_PRINTABLESTRING || + type == V_ASN1_TELETEXSTRING || + type == V_ASN1_VISIBLESTRING || type == V_ASN1_IA5STRING) { + if (num > (int)sizeof(ebcdic_buf)) + num = sizeof(ebcdic_buf); + ascii2ebcdic(ebcdic_buf, q, num); + q = ebcdic_buf; + } +#endif + + if ((type == V_ASN1_GENERALSTRING) && ((num % 4) == 0)) { + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 0; + for (j = 0; j < num; j++) + if (q[j] != 0) + gs_doit[j & 3] = 1; + + if (gs_doit[0] | gs_doit[1] | gs_doit[2]) + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; + else { + gs_doit[0] = gs_doit[1] = gs_doit[2] = 0; + gs_doit[3] = 1; + } + } else + gs_doit[0] = gs_doit[1] = gs_doit[2] = gs_doit[3] = 1; + + for (l2 = j = 0; j < num; j++) { + if (!gs_doit[j & 3]) + continue; + l2++; +#ifndef CHARSET_EBCDIC + if ((q[j] < ' ') || (q[j] > '~')) + l2 += 3; +#else + if ((os_toascii[q[j]] < os_toascii[' ']) || + (os_toascii[q[j]] > os_toascii['~'])) + l2 += 3; +#endif + } + + lold = l; + l += 1 + l1 + 1 + l2; + if (l > NAME_ONELINE_MAX) { + X509err(X509_F_X509_NAME_ONELINE, X509_R_NAME_TOO_LONG); + goto end; + } + if (b != NULL) { + if (!BUF_MEM_grow(b, l + 1)) + goto err; + p = &(b->data[lold]); + } else if (l > len) { + break; + } else + p = &(buf[lold]); + *(p++) = '/'; + memcpy(p, s, (unsigned int)l1); + p += l1; + *(p++) = '='; + +#ifndef CHARSET_EBCDIC /* q was assigned above already. */ + q = ne->value->data; +#endif + + for (j = 0; j < num; j++) { + if (!gs_doit[j & 3]) + continue; +#ifndef CHARSET_EBCDIC + n = q[j]; + if ((n < ' ') || (n > '~')) { + *(p++) = '\\'; + *(p++) = 'x'; + *(p++) = hex[(n >> 4) & 0x0f]; + *(p++) = hex[n & 0x0f]; + } else + *(p++) = n; +#else + n = os_toascii[q[j]]; + if ((n < os_toascii[' ']) || (n > os_toascii['~'])) { + *(p++) = '\\'; + *(p++) = 'x'; + *(p++) = hex[(n >> 4) & 0x0f]; + *(p++) = hex[n & 0x0f]; + } else + *(p++) = q[j]; +#endif + } + *p = '\0'; + } + if (b != NULL) { + p = b->data; + OPENSSL_free(b); + } else + p = buf; + if (i == 0) + *p = '\0'; + return (p); + err: + X509err(X509_F_X509_NAME_ONELINE, ERR_R_MALLOC_FAILURE); + end: + BUF_MEM_free(b); + return (NULL); +} diff --git a/libs/openssl/crypto/x509/x509_r2x.c b/libs/openssl/crypto/x509/x509_r2x.c new file mode 100644 index 00000000..0ff439c9 --- /dev/null +++ b/libs/openssl/crypto/x509/x509_r2x.c @@ -0,0 +1,113 @@ +/* crypto/x509/x509_r2x.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include + +X509 *X509_REQ_to_X509(X509_REQ *r, int days, EVP_PKEY *pkey) +{ + X509 *ret = NULL; + X509_CINF *xi = NULL; + X509_NAME *xn; + + if ((ret = X509_new()) == NULL) { + X509err(X509_F_X509_REQ_TO_X509, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* duplicate the request */ + xi = ret->cert_info; + + if (sk_X509_ATTRIBUTE_num(r->req_info->attributes) != 0) { + if ((xi->version = M_ASN1_INTEGER_new()) == NULL) + goto err; + if (!ASN1_INTEGER_set(xi->version, 2)) + goto err; +/*- xi->extensions=ri->attributes; <- bad, should not ever be done + ri->attributes=NULL; */ + } + + xn = X509_REQ_get_subject_name(r); + if (X509_set_subject_name(ret, X509_NAME_dup(xn)) == 0) + goto err; + if (X509_set_issuer_name(ret, X509_NAME_dup(xn)) == 0) + goto err; + + if (X509_gmtime_adj(xi->validity->notBefore, 0) == NULL) + goto err; + if (X509_gmtime_adj(xi->validity->notAfter, (long)60 * 60 * 24 * days) == + NULL) + goto err; + + X509_set_pubkey(ret, X509_REQ_get_pubkey(r)); + + if (!X509_sign(ret, pkey, EVP_md5())) + goto err; + if (0) { + err: + X509_free(ret); + ret = NULL; + } + return (ret); +} diff --git a/libs/openssl/crypto/x509/x509_req.c b/libs/openssl/crypto/x509/x509_req.c new file mode 100644 index 00000000..01795f4b --- /dev/null +++ b/libs/openssl/crypto/x509/x509_req.c @@ -0,0 +1,328 @@ +/* crypto/x509/x509_req.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include +#include + +X509_REQ *X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + X509_REQ *ret; + X509_REQ_INFO *ri; + int i; + EVP_PKEY *pktmp; + + ret = X509_REQ_new(); + if (ret == NULL) { + X509err(X509_F_X509_TO_X509_REQ, ERR_R_MALLOC_FAILURE); + goto err; + } + + ri = ret->req_info; + + ri->version->length = 1; + ri->version->data = (unsigned char *)OPENSSL_malloc(1); + if (ri->version->data == NULL) + goto err; + ri->version->data[0] = 0; /* version == 0 */ + + if (!X509_REQ_set_subject_name(ret, X509_get_subject_name(x))) + goto err; + + pktmp = X509_get_pubkey(x); + if (pktmp == NULL) + goto err; + i = X509_REQ_set_pubkey(ret, pktmp); + EVP_PKEY_free(pktmp); + if (!i) + goto err; + + if (pkey != NULL) { + if (!X509_REQ_sign(ret, pkey, md)) + goto err; + } + return (ret); + err: + X509_REQ_free(ret); + return (NULL); +} + +EVP_PKEY *X509_REQ_get_pubkey(X509_REQ *req) +{ + if ((req == NULL) || (req->req_info == NULL)) + return (NULL); + return (X509_PUBKEY_get(req->req_info->pubkey)); +} + +int X509_REQ_check_private_key(X509_REQ *x, EVP_PKEY *k) +{ + EVP_PKEY *xk = NULL; + int ok = 0; + + xk = X509_REQ_get_pubkey(x); + switch (EVP_PKEY_cmp(xk, k)) { + case 1: + ok = 1; + break; + case 0: + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, + X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_KEY_TYPE_MISMATCH); + break; + case -2: +#ifndef OPENSSL_NO_EC + if (k->type == EVP_PKEY_EC) { + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, ERR_R_EC_LIB); + break; + } +#endif +#ifndef OPENSSL_NO_DH + if (k->type == EVP_PKEY_DH) { + /* No idea */ + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, + X509_R_CANT_CHECK_DH_KEY); + break; + } +#endif + X509err(X509_F_X509_REQ_CHECK_PRIVATE_KEY, X509_R_UNKNOWN_KEY_TYPE); + } + + EVP_PKEY_free(xk); + return (ok); +} + +/* + * It seems several organisations had the same idea of including a list of + * extensions in a certificate request. There are at least two OIDs that are + * used and there may be more: so the list is configurable. + */ + +static int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef }; + +static int *ext_nids = ext_nid_list; + +int X509_REQ_extension_nid(int req_nid) +{ + int i, nid; + for (i = 0;; i++) { + nid = ext_nids[i]; + if (nid == NID_undef) + return 0; + else if (req_nid == nid) + return 1; + } +} + +int *X509_REQ_get_extension_nids(void) +{ + return ext_nids; +} + +void X509_REQ_set_extension_nids(int *nids) +{ + ext_nids = nids; +} + +STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req) +{ + X509_ATTRIBUTE *attr; + ASN1_TYPE *ext = NULL; + int idx, *pnid; + const unsigned char *p; + + if ((req == NULL) || (req->req_info == NULL) || !ext_nids) + return (NULL); + for (pnid = ext_nids; *pnid != NID_undef; pnid++) { + idx = X509_REQ_get_attr_by_NID(req, *pnid, -1); + if (idx == -1) + continue; + attr = X509_REQ_get_attr(req, idx); + if (attr->single) + ext = attr->value.single; + else if (sk_ASN1_TYPE_num(attr->value.set)) + ext = sk_ASN1_TYPE_value(attr->value.set, 0); + break; + } + if (!ext || (ext->type != V_ASN1_SEQUENCE)) + return NULL; + p = ext->value.sequence->data; + return (STACK_OF(X509_EXTENSION) *) + ASN1_item_d2i(NULL, &p, ext->value.sequence->length, + ASN1_ITEM_rptr(X509_EXTENSIONS)); +} + +/* + * Add a STACK_OF extensions to a certificate request: allow alternative OIDs + * in case we want to create a non standard one. + */ + +int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid) +{ + ASN1_TYPE *at = NULL; + X509_ATTRIBUTE *attr = NULL; + if (!(at = ASN1_TYPE_new()) || !(at->value.sequence = ASN1_STRING_new())) + goto err; + + at->type = V_ASN1_SEQUENCE; + /* Generate encoding of extensions */ + at->value.sequence->length = + ASN1_item_i2d((ASN1_VALUE *)exts, + &at->value.sequence->data, + ASN1_ITEM_rptr(X509_EXTENSIONS)); + if (!(attr = X509_ATTRIBUTE_new())) + goto err; + if (!(attr->value.set = sk_ASN1_TYPE_new_null())) + goto err; + if (!sk_ASN1_TYPE_push(attr->value.set, at)) + goto err; + at = NULL; + attr->single = 0; + attr->object = OBJ_nid2obj(nid); + if (!req->req_info->attributes) { + if (!(req->req_info->attributes = sk_X509_ATTRIBUTE_new_null())) + goto err; + } + if (!sk_X509_ATTRIBUTE_push(req->req_info->attributes, attr)) + goto err; + return 1; + err: + X509_ATTRIBUTE_free(attr); + ASN1_TYPE_free(at); + return 0; +} + +/* This is the normal usage: use the "official" OID */ +int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts) +{ + return X509_REQ_add_extensions_nid(req, exts, NID_ext_req); +} + +/* Request attribute functions */ + +int X509_REQ_get_attr_count(const X509_REQ *req) +{ + return X509at_get_attr_count(req->req_info->attributes); +} + +int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, int lastpos) +{ + return X509at_get_attr_by_NID(req->req_info->attributes, nid, lastpos); +} + +int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, + int lastpos) +{ + return X509at_get_attr_by_OBJ(req->req_info->attributes, obj, lastpos); +} + +X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc) +{ + return X509at_get_attr(req->req_info->attributes, loc); +} + +X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc) +{ + return X509at_delete_attr(req->req_info->attributes, loc); +} + +int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr) +{ + if (X509at_add1_attr(&req->req_info->attributes, attr)) + return 1; + return 0; +} + +int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_OBJ(&req->req_info->attributes, obj, + type, bytes, len)) + return 1; + return 0; +} + +int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_NID(&req->req_info->attributes, nid, + type, bytes, len)) + return 1; + return 0; +} + +int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len) +{ + if (X509at_add1_attr_by_txt(&req->req_info->attributes, attrname, + type, bytes, len)) + return 1; + return 0; +} diff --git a/libs/openssl/crypto/x509/x509_set.c b/libs/openssl/crypto/x509/x509_set.c new file mode 100644 index 00000000..46457776 --- /dev/null +++ b/libs/openssl/crypto/x509/x509_set.c @@ -0,0 +1,147 @@ +/* crypto/x509/x509_set.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +int X509_set_version(X509 *x, long version) +{ + if (x == NULL) + return (0); + if (x->cert_info->version == NULL) { + if ((x->cert_info->version = M_ASN1_INTEGER_new()) == NULL) + return (0); + } + return (ASN1_INTEGER_set(x->cert_info->version, version)); +} + +int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial) +{ + ASN1_INTEGER *in; + + if (x == NULL) + return (0); + in = x->cert_info->serialNumber; + if (in != serial) { + in = M_ASN1_INTEGER_dup(serial); + if (in != NULL) { + M_ASN1_INTEGER_free(x->cert_info->serialNumber); + x->cert_info->serialNumber = in; + } + } + return (in != NULL); +} + +int X509_set_issuer_name(X509 *x, X509_NAME *name) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (0); + return (X509_NAME_set(&x->cert_info->issuer, name)); +} + +int X509_set_subject_name(X509 *x, X509_NAME *name) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (0); + return (X509_NAME_set(&x->cert_info->subject, name)); +} + +int X509_set_notBefore(X509 *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if ((x == NULL) || (x->cert_info->validity == NULL)) + return (0); + in = x->cert_info->validity->notBefore; + if (in != tm) { + in = M_ASN1_TIME_dup(tm); + if (in != NULL) { + M_ASN1_TIME_free(x->cert_info->validity->notBefore); + x->cert_info->validity->notBefore = in; + } + } + return (in != NULL); +} + +int X509_set_notAfter(X509 *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if ((x == NULL) || (x->cert_info->validity == NULL)) + return (0); + in = x->cert_info->validity->notAfter; + if (in != tm) { + in = M_ASN1_TIME_dup(tm); + if (in != NULL) { + M_ASN1_TIME_free(x->cert_info->validity->notAfter); + x->cert_info->validity->notAfter = in; + } + } + return (in != NULL); +} + +int X509_set_pubkey(X509 *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->cert_info == NULL)) + return (0); + return (X509_PUBKEY_set(&(x->cert_info->key), pkey)); +} diff --git a/libs/openssl/crypto/x509/x509_trs.c b/libs/openssl/crypto/x509/x509_trs.c new file mode 100644 index 00000000..7e444795 --- /dev/null +++ b/libs/openssl/crypto/x509/x509_trs.c @@ -0,0 +1,310 @@ +/* x509_trs.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b); +static void trtable_free(X509_TRUST *p); + +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags); +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags); +static int trust_compat(X509_TRUST *trust, X509 *x, int flags); + +static int obj_trust(int id, X509 *x, int flags); +static int (*default_trust) (int id, X509 *x, int flags) = obj_trust; + +/* + * WARNING: the following table should be kept in order of trust and without + * any gaps so we can just subtract the minimum trust value to get an index + * into the table + */ + +static X509_TRUST trstandard[] = { + {X509_TRUST_COMPAT, 0, trust_compat, "compatible", 0, NULL}, + {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, "SSL Client", NID_client_auth, + NULL}, + {X509_TRUST_SSL_SERVER, 0, trust_1oidany, "SSL Server", NID_server_auth, + NULL}, + {X509_TRUST_EMAIL, 0, trust_1oidany, "S/MIME email", NID_email_protect, + NULL}, + {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, "Object Signer", NID_code_sign, + NULL}, + {X509_TRUST_OCSP_SIGN, 0, trust_1oid, "OCSP responder", NID_OCSP_sign, + NULL}, + {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, "OCSP request", NID_ad_OCSP, + NULL}, + {X509_TRUST_TSA, 0, trust_1oidany, "TSA server", NID_time_stamp, NULL} +}; + +#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST)) + +IMPLEMENT_STACK_OF(X509_TRUST) + +static STACK_OF(X509_TRUST) *trtable = NULL; + +static int tr_cmp(const X509_TRUST *const *a, const X509_TRUST *const *b) +{ + return (*a)->trust - (*b)->trust; +} + +int (*X509_TRUST_set_default(int (*trust) (int, X509 *, int))) (int, X509 *, + int) { + int (*oldtrust) (int, X509 *, int); + oldtrust = default_trust; + default_trust = trust; + return oldtrust; +} + +int X509_check_trust(X509 *x, int id, int flags) +{ + X509_TRUST *pt; + int idx; + if (id == -1) + return 1; + idx = X509_TRUST_get_by_id(id); + if (idx == -1) + return default_trust(id, x, flags); + pt = X509_TRUST_get0(idx); + return pt->check_trust(pt, x, flags); +} + +int X509_TRUST_get_count(void) +{ + if (!trtable) + return X509_TRUST_COUNT; + return sk_X509_TRUST_num(trtable) + X509_TRUST_COUNT; +} + +X509_TRUST *X509_TRUST_get0(int idx) +{ + if (idx < 0) + return NULL; + if (idx < (int)X509_TRUST_COUNT) + return trstandard + idx; + return sk_X509_TRUST_value(trtable, idx - X509_TRUST_COUNT); +} + +int X509_TRUST_get_by_id(int id) +{ + X509_TRUST tmp; + int idx; + if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX)) + return id - X509_TRUST_MIN; + tmp.trust = id; + if (!trtable) + return -1; + idx = sk_X509_TRUST_find(trtable, &tmp); + if (idx == -1) + return -1; + return idx + X509_TRUST_COUNT; +} + +int X509_TRUST_set(int *t, int trust) +{ + if (X509_TRUST_get_by_id(trust) == -1) { + X509err(X509_F_X509_TRUST_SET, X509_R_INVALID_TRUST); + return 0; + } + *t = trust; + return 1; +} + +int X509_TRUST_add(int id, int flags, int (*ck) (X509_TRUST *, X509 *, int), + char *name, int arg1, void *arg2) +{ + int idx; + X509_TRUST *trtmp; + /* + * This is set according to what we change: application can't set it + */ + flags &= ~X509_TRUST_DYNAMIC; + /* This will always be set for application modified trust entries */ + flags |= X509_TRUST_DYNAMIC_NAME; + /* Get existing entry if any */ + idx = X509_TRUST_get_by_id(id); + /* Need a new entry */ + if (idx == -1) { + if (!(trtmp = OPENSSL_malloc(sizeof(X509_TRUST)))) { + X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + trtmp->flags = X509_TRUST_DYNAMIC; + } else + trtmp = X509_TRUST_get0(idx); + + /* OPENSSL_free existing name if dynamic */ + if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) + OPENSSL_free(trtmp->name); + /* dup supplied name */ + if (!(trtmp->name = BUF_strdup(name))) { + X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + /* Keep the dynamic flag of existing entry */ + trtmp->flags &= X509_TRUST_DYNAMIC; + /* Set all other flags */ + trtmp->flags |= flags; + + trtmp->trust = id; + trtmp->check_trust = ck; + trtmp->arg1 = arg1; + trtmp->arg2 = arg2; + + /* If its a new entry manage the dynamic table */ + if (idx == -1) { + if (!trtable && !(trtable = sk_X509_TRUST_new(tr_cmp))) { + X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!sk_X509_TRUST_push(trtable, trtmp)) { + X509err(X509_F_X509_TRUST_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + } + return 1; +} + +static void trtable_free(X509_TRUST *p) +{ + if (!p) + return; + if (p->flags & X509_TRUST_DYNAMIC) { + if (p->flags & X509_TRUST_DYNAMIC_NAME) + OPENSSL_free(p->name); + OPENSSL_free(p); + } +} + +void X509_TRUST_cleanup(void) +{ + unsigned int i; + for (i = 0; i < X509_TRUST_COUNT; i++) + trtable_free(trstandard + i); + sk_X509_TRUST_pop_free(trtable, trtable_free); + trtable = NULL; +} + +int X509_TRUST_get_flags(X509_TRUST *xp) +{ + return xp->flags; +} + +char *X509_TRUST_get0_name(X509_TRUST *xp) +{ + return xp->name; +} + +int X509_TRUST_get_trust(X509_TRUST *xp) +{ + return xp->trust; +} + +static int trust_1oidany(X509_TRUST *trust, X509 *x, int flags) +{ + if (x->aux && (x->aux->trust || x->aux->reject)) + return obj_trust(trust->arg1, x, flags); + /* + * we don't have any trust settings: for compatibility we return trusted + * if it is self signed + */ + return trust_compat(trust, x, flags); +} + +static int trust_1oid(X509_TRUST *trust, X509 *x, int flags) +{ + if (x->aux) + return obj_trust(trust->arg1, x, flags); + return X509_TRUST_UNTRUSTED; +} + +static int trust_compat(X509_TRUST *trust, X509 *x, int flags) +{ + X509_check_purpose(x, -1, 0); + if (x->ex_flags & EXFLAG_SS) + return X509_TRUST_TRUSTED; + else + return X509_TRUST_UNTRUSTED; +} + +static int obj_trust(int id, X509 *x, int flags) +{ + ASN1_OBJECT *obj; + int i; + X509_CERT_AUX *ax; + ax = x->aux; + if (!ax) + return X509_TRUST_UNTRUSTED; + if (ax->reject) { + for (i = 0; i < sk_ASN1_OBJECT_num(ax->reject); i++) { + obj = sk_ASN1_OBJECT_value(ax->reject, i); + if (OBJ_obj2nid(obj) == id) + return X509_TRUST_REJECTED; + } + } + if (ax->trust) { + for (i = 0; i < sk_ASN1_OBJECT_num(ax->trust); i++) { + obj = sk_ASN1_OBJECT_value(ax->trust, i); + if (OBJ_obj2nid(obj) == id) + return X509_TRUST_TRUSTED; + } + } + return X509_TRUST_UNTRUSTED; +} diff --git a/libs/openssl/crypto/x509/x509_txt.c b/libs/openssl/crypto/x509/x509_txt.c new file mode 100644 index 00000000..d834180e --- /dev/null +++ b/libs/openssl/crypto/x509/x509_txt.c @@ -0,0 +1,191 @@ +/* crypto/x509/x509_txt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include + +const char *X509_verify_cert_error_string(long n) +{ + static char buf[100]; + + switch ((int)n) { + case X509_V_OK: + return ("ok"); + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + return ("unable to get issuer certificate"); + case X509_V_ERR_UNABLE_TO_GET_CRL: + return ("unable to get certificate CRL"); + case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: + return ("unable to decrypt certificate's signature"); + case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: + return ("unable to decrypt CRL's signature"); + case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: + return ("unable to decode issuer public key"); + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + return ("certificate signature failure"); + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + return ("CRL signature failure"); + case X509_V_ERR_CERT_NOT_YET_VALID: + return ("certificate is not yet valid"); + case X509_V_ERR_CRL_NOT_YET_VALID: + return ("CRL is not yet valid"); + case X509_V_ERR_CERT_HAS_EXPIRED: + return ("certificate has expired"); + case X509_V_ERR_CRL_HAS_EXPIRED: + return ("CRL has expired"); + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + return ("format error in certificate's notBefore field"); + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + return ("format error in certificate's notAfter field"); + case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: + return ("format error in CRL's lastUpdate field"); + case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: + return ("format error in CRL's nextUpdate field"); + case X509_V_ERR_OUT_OF_MEM: + return ("out of memory"); + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + return ("self signed certificate"); + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + return ("self signed certificate in certificate chain"); + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + return ("unable to get local issuer certificate"); + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + return ("unable to verify the first certificate"); + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + return ("certificate chain too long"); + case X509_V_ERR_CERT_REVOKED: + return ("certificate revoked"); + case X509_V_ERR_INVALID_CA: + return ("invalid CA certificate"); + case X509_V_ERR_INVALID_NON_CA: + return ("invalid non-CA certificate (has CA markings)"); + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + return ("path length constraint exceeded"); + case X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED: + return ("proxy path length constraint exceeded"); + case X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED: + return + ("proxy certificates not allowed, please set the appropriate flag"); + case X509_V_ERR_INVALID_PURPOSE: + return ("unsupported certificate purpose"); + case X509_V_ERR_CERT_UNTRUSTED: + return ("certificate not trusted"); + case X509_V_ERR_CERT_REJECTED: + return ("certificate rejected"); + case X509_V_ERR_APPLICATION_VERIFICATION: + return ("application verification failure"); + case X509_V_ERR_SUBJECT_ISSUER_MISMATCH: + return ("subject issuer mismatch"); + case X509_V_ERR_AKID_SKID_MISMATCH: + return ("authority and subject key identifier mismatch"); + case X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH: + return ("authority and issuer serial number mismatch"); + case X509_V_ERR_KEYUSAGE_NO_CERTSIGN: + return ("key usage does not include certificate signing"); + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + return ("unable to get CRL issuer certificate"); + case X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION: + return ("unhandled critical extension"); + case X509_V_ERR_KEYUSAGE_NO_CRL_SIGN: + return ("key usage does not include CRL signing"); + case X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE: + return ("key usage does not include digital signature"); + case X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION: + return ("unhandled critical CRL extension"); + case X509_V_ERR_INVALID_EXTENSION: + return ("invalid or inconsistent certificate extension"); + case X509_V_ERR_INVALID_POLICY_EXTENSION: + return ("invalid or inconsistent certificate policy extension"); + case X509_V_ERR_NO_EXPLICIT_POLICY: + return ("no explicit policy"); + case X509_V_ERR_DIFFERENT_CRL_SCOPE: + return ("Different CRL scope"); + case X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE: + return ("Unsupported extension feature"); + case X509_V_ERR_UNNESTED_RESOURCE: + return ("RFC 3779 resource not subset of parent's resources"); + + case X509_V_ERR_PERMITTED_VIOLATION: + return ("permitted subtree violation"); + case X509_V_ERR_EXCLUDED_VIOLATION: + return ("excluded subtree violation"); + case X509_V_ERR_SUBTREE_MINMAX: + return ("name constraints minimum and maximum not supported"); + case X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: + return ("unsupported name constraint type"); + case X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: + return ("unsupported or invalid name constraint syntax"); + case X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: + return ("unsupported or invalid name syntax"); + case X509_V_ERR_CRL_PATH_VALIDATION_ERROR: + return ("CRL path validation error"); + + default: + BIO_snprintf(buf, sizeof buf, "error number %ld", n); + return (buf); + } +} diff --git a/libs/openssl/crypto/x509/x509_v3.c b/libs/openssl/crypto/x509/x509_v3.c new file mode 100644 index 00000000..4a03445a --- /dev/null +++ b/libs/openssl/crypto/x509/x509_v3.c @@ -0,0 +1,284 @@ +/* crypto/x509/x509_v3.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include + +int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x) +{ + if (x == NULL) + return (0); + return (sk_X509_EXTENSION_num(x)); +} + +int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, int nid, + int lastpos) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-2); + return (X509v3_get_ext_by_OBJ(x, obj, lastpos)); +} + +int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *sk, + ASN1_OBJECT *obj, int lastpos) +{ + int n; + X509_EXTENSION *ex; + + if (sk == NULL) + return (-1); + lastpos++; + if (lastpos < 0) + lastpos = 0; + n = sk_X509_EXTENSION_num(sk); + for (; lastpos < n; lastpos++) { + ex = sk_X509_EXTENSION_value(sk, lastpos); + if (OBJ_cmp(ex->object, obj) == 0) + return (lastpos); + } + return (-1); +} + +int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *sk, int crit, + int lastpos) +{ + int n; + X509_EXTENSION *ex; + + if (sk == NULL) + return (-1); + lastpos++; + if (lastpos < 0) + lastpos = 0; + n = sk_X509_EXTENSION_num(sk); + for (; lastpos < n; lastpos++) { + ex = sk_X509_EXTENSION_value(sk, lastpos); + if (((ex->critical > 0) && crit) || ((ex->critical <= 0) && !crit)) + return (lastpos); + } + return (-1); +} + +X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc) +{ + if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) + return NULL; + else + return sk_X509_EXTENSION_value(x, loc); +} + +X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc) +{ + X509_EXTENSION *ret; + + if (x == NULL || sk_X509_EXTENSION_num(x) <= loc || loc < 0) + return (NULL); + ret = sk_X509_EXTENSION_delete(x, loc); + return (ret); +} + +STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc) +{ + X509_EXTENSION *new_ex = NULL; + int n; + STACK_OF(X509_EXTENSION) *sk = NULL; + + if (x == NULL) { + X509err(X509_F_X509V3_ADD_EXT, ERR_R_PASSED_NULL_PARAMETER); + goto err2; + } + + if (*x == NULL) { + if ((sk = sk_X509_EXTENSION_new_null()) == NULL) + goto err; + } else + sk = *x; + + n = sk_X509_EXTENSION_num(sk); + if (loc > n) + loc = n; + else if (loc < 0) + loc = n; + + if ((new_ex = X509_EXTENSION_dup(ex)) == NULL) + goto err2; + if (!sk_X509_EXTENSION_insert(sk, new_ex, loc)) + goto err; + if (*x == NULL) + *x = sk; + return (sk); + err: + X509err(X509_F_X509V3_ADD_EXT, ERR_R_MALLOC_FAILURE); + err2: + if (new_ex != NULL) + X509_EXTENSION_free(new_ex); + if (sk != NULL) + sk_X509_EXTENSION_free(sk); + return (NULL); +} + +X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, int nid, + int crit, + ASN1_OCTET_STRING *data) +{ + ASN1_OBJECT *obj; + X509_EXTENSION *ret; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + X509err(X509_F_X509_EXTENSION_CREATE_BY_NID, X509_R_UNKNOWN_NID); + return (NULL); + } + ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); + if (ret == NULL) + ASN1_OBJECT_free(obj); + return (ret); +} + +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + ASN1_OBJECT *obj, int crit, + ASN1_OCTET_STRING *data) +{ + X509_EXTENSION *ret; + + if ((ex == NULL) || (*ex == NULL)) { + if ((ret = X509_EXTENSION_new()) == NULL) { + X509err(X509_F_X509_EXTENSION_CREATE_BY_OBJ, + ERR_R_MALLOC_FAILURE); + return (NULL); + } + } else + ret = *ex; + + if (!X509_EXTENSION_set_object(ret, obj)) + goto err; + if (!X509_EXTENSION_set_critical(ret, crit)) + goto err; + if (!X509_EXTENSION_set_data(ret, data)) + goto err; + + if ((ex != NULL) && (*ex == NULL)) + *ex = ret; + return (ret); + err: + if ((ex == NULL) || (ret != *ex)) + X509_EXTENSION_free(ret); + return (NULL); +} + +int X509_EXTENSION_set_object(X509_EXTENSION *ex, ASN1_OBJECT *obj) +{ + if ((ex == NULL) || (obj == NULL)) + return (0); + ASN1_OBJECT_free(ex->object); + ex->object = OBJ_dup(obj); + return (1); +} + +int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit) +{ + if (ex == NULL) + return (0); + ex->critical = (crit) ? 0xFF : -1; + return (1); +} + +int X509_EXTENSION_set_data(X509_EXTENSION *ex, ASN1_OCTET_STRING *data) +{ + int i; + + if (ex == NULL) + return (0); + i = M_ASN1_OCTET_STRING_set(ex->value, data->data, data->length); + if (!i) + return (0); + return (1); +} + +ASN1_OBJECT *X509_EXTENSION_get_object(X509_EXTENSION *ex) +{ + if (ex == NULL) + return (NULL); + return (ex->object); +} + +ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ex) +{ + if (ex == NULL) + return (NULL); + return (ex->value); +} + +int X509_EXTENSION_get_critical(X509_EXTENSION *ex) +{ + if (ex == NULL) + return (0); + if (ex->critical > 0) + return 1; + return 0; +} diff --git a/libs/openssl/crypto/x509/x509_vfy.c b/libs/openssl/crypto/x509/x509_vfy.c new file mode 100644 index 00000000..3bad523f --- /dev/null +++ b/libs/openssl/crypto/x509/x509_vfy.c @@ -0,0 +1,2230 @@ +/* crypto/x509/x509_vfy.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include +#include +#include + +/* CRL score values */ + +/* No unhandled critical extensions */ + +#define CRL_SCORE_NOCRITICAL 0x100 + +/* certificate is within CRL scope */ + +#define CRL_SCORE_SCOPE 0x080 + +/* CRL times valid */ + +#define CRL_SCORE_TIME 0x040 + +/* Issuer name matches certificate */ + +#define CRL_SCORE_ISSUER_NAME 0x020 + +/* If this score or above CRL is probably valid */ + +#define CRL_SCORE_VALID (CRL_SCORE_NOCRITICAL|CRL_SCORE_TIME|CRL_SCORE_SCOPE) + +/* CRL issuer is certificate issuer */ + +#define CRL_SCORE_ISSUER_CERT 0x018 + +/* CRL issuer is on certificate path */ + +#define CRL_SCORE_SAME_PATH 0x008 + +/* CRL issuer matches CRL AKID */ + +#define CRL_SCORE_AKID 0x004 + +/* Have a delta CRL with valid times */ + +#define CRL_SCORE_TIME_DELTA 0x002 + +static int null_callback(int ok, X509_STORE_CTX *e); +static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); +static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x); +static int check_chain_extensions(X509_STORE_CTX *ctx); +static int check_name_constraints(X509_STORE_CTX *ctx); +static int check_trust(X509_STORE_CTX *ctx); +static int check_revocation(X509_STORE_CTX *ctx); +static int check_cert(X509_STORE_CTX *ctx); +static int check_policy(X509_STORE_CTX *ctx); + +static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, + unsigned int *preasons, X509_CRL *crl, X509 *x); +static int get_crl_delta(X509_STORE_CTX *ctx, + X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x); +static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, + int *pcrl_score, X509_CRL *base, + STACK_OF(X509_CRL) *crls); +static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, X509 **pissuer, + int *pcrl_score); +static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, + unsigned int *preasons); +static int check_crl_path(X509_STORE_CTX *ctx, X509 *x); +static int check_crl_chain(X509_STORE_CTX *ctx, + STACK_OF(X509) *cert_path, + STACK_OF(X509) *crl_path); + +static int internal_verify(X509_STORE_CTX *ctx); +const char X509_version[] = "X.509" OPENSSL_VERSION_PTEXT; + +static int null_callback(int ok, X509_STORE_CTX *e) +{ + return ok; +} + +#if 0 +static int x509_subject_cmp(X509 **a, X509 **b) +{ + return X509_subject_name_cmp(*a, *b); +} +#endif + +int X509_verify_cert(X509_STORE_CTX *ctx) +{ + X509 *x, *xtmp, *xtmp2, *chain_ss = NULL; + int bad_chain = 0; + X509_VERIFY_PARAM *param = ctx->param; + int depth, i, ok = 0; + int num, j, retry; + int (*cb) (int xok, X509_STORE_CTX *xctx); + STACK_OF(X509) *sktmp = NULL; + if (ctx->cert == NULL) { + X509err(X509_F_X509_VERIFY_CERT, X509_R_NO_CERT_SET_FOR_US_TO_VERIFY); + return -1; + } + if (ctx->chain != NULL) { + /* + * This X509_STORE_CTX has already been used to verify a cert. We + * cannot do another one. + */ + X509err(X509_F_X509_VERIFY_CERT, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + cb = ctx->verify_cb; + + /* + * first we make sure the chain we are going to build is present and that + * the first entry is in place + */ + if (((ctx->chain = sk_X509_new_null()) == NULL) || + (!sk_X509_push(ctx->chain, ctx->cert))) { + X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + goto end; + } + CRYPTO_add(&ctx->cert->references, 1, CRYPTO_LOCK_X509); + ctx->last_untrusted = 1; + + /* We use a temporary STACK so we can chop and hack at it */ + if (ctx->untrusted != NULL + && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { + X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + goto end; + } + + num = sk_X509_num(ctx->chain); + x = sk_X509_value(ctx->chain, num - 1); + depth = param->depth; + + for (;;) { + /* If we have enough, we break */ + if (depth < num) + break; /* FIXME: If this happens, we should take + * note of it and, if appropriate, use the + * X509_V_ERR_CERT_CHAIN_TOO_LONG error code + * later. */ + + /* If we are self signed, we break */ + if (ctx->check_issued(ctx, x, x)) + break; + + /* If we were passed a cert chain, use it first */ + if (ctx->untrusted != NULL) { + xtmp = find_issuer(ctx, sktmp, x); + if (xtmp != NULL) { + if (!sk_X509_push(ctx->chain, xtmp)) { + X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + goto end; + } + CRYPTO_add(&xtmp->references, 1, CRYPTO_LOCK_X509); + (void)sk_X509_delete_ptr(sktmp, xtmp); + ctx->last_untrusted++; + x = xtmp; + num++; + /* + * reparse the full chain for the next one + */ + continue; + } + } + break; + } + + /* Remember how many untrusted certs we have */ + j = num; + /* + * at this point, chain should contain a list of untrusted certificates. + * We now need to add at least one trusted one, if possible, otherwise we + * complain. + */ + + do { + /* + * Examine last certificate in chain and see if it is self signed. + */ + i = sk_X509_num(ctx->chain); + x = sk_X509_value(ctx->chain, i - 1); + if (ctx->check_issued(ctx, x, x)) { + /* we have a self signed certificate */ + if (sk_X509_num(ctx->chain) == 1) { + /* + * We have a single self signed certificate: see if we can + * find it in the store. We must have an exact match to avoid + * possible impersonation. + */ + ok = ctx->get_issuer(&xtmp, ctx, x); + if ((ok <= 0) || X509_cmp(x, xtmp)) { + ctx->error = X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT; + ctx->current_cert = x; + ctx->error_depth = i - 1; + if (ok == 1) + X509_free(xtmp); + bad_chain = 1; + ok = cb(0, ctx); + if (!ok) + goto end; + } else { + /* + * We have a match: replace certificate with store + * version so we get any trust settings. + */ + X509_free(x); + x = xtmp; + (void)sk_X509_set(ctx->chain, i - 1, x); + ctx->last_untrusted = 0; + } + } else { + /* + * extract and save self signed certificate for later use + */ + chain_ss = sk_X509_pop(ctx->chain); + ctx->last_untrusted--; + num--; + j--; + x = sk_X509_value(ctx->chain, num - 1); + } + } + /* We now lookup certs from the certificate store */ + for (;;) { + /* If we have enough, we break */ + if (depth < num) + break; + /* If we are self signed, we break */ + if (ctx->check_issued(ctx, x, x)) + break; + ok = ctx->get_issuer(&xtmp, ctx, x); + if (ok < 0) + return ok; + if (ok == 0) + break; + x = xtmp; + if (!sk_X509_push(ctx->chain, x)) { + X509_free(xtmp); + X509err(X509_F_X509_VERIFY_CERT, ERR_R_MALLOC_FAILURE); + return 0; + } + num++; + } + + /* + * If we haven't got a least one certificate from our store then check + * if there is an alternative chain that could be used. We only do this + * if the user hasn't switched off alternate chain checking + */ + retry = 0; + if (num == ctx->last_untrusted && + !(ctx->param->flags & X509_V_FLAG_NO_ALT_CHAINS)) { + while (j-- > 1) { + xtmp2 = sk_X509_value(ctx->chain, j - 1); + ok = ctx->get_issuer(&xtmp, ctx, xtmp2); + if (ok < 0) + goto end; + /* Check if we found an alternate chain */ + if (ok > 0) { + /* + * Free up the found cert we'll add it again later + */ + X509_free(xtmp); + + /* + * Dump all the certs above this point - we've found an + * alternate chain + */ + while (num > j) { + xtmp = sk_X509_pop(ctx->chain); + X509_free(xtmp); + num--; + } + ctx->last_untrusted = sk_X509_num(ctx->chain); + retry = 1; + break; + } + } + } + } while (retry); + + /* Is last certificate looked up self signed? */ + if (!ctx->check_issued(ctx, x, x)) { + if ((chain_ss == NULL) || !ctx->check_issued(ctx, x, chain_ss)) { + if (ctx->last_untrusted >= num) + ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY; + else + ctx->error = X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT; + ctx->current_cert = x; + } else { + + sk_X509_push(ctx->chain, chain_ss); + num++; + ctx->last_untrusted = num; + ctx->current_cert = chain_ss; + ctx->error = X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN; + chain_ss = NULL; + } + + ctx->error_depth = num - 1; + bad_chain = 1; + ok = cb(0, ctx); + if (!ok) + goto end; + } + + /* We have the chain complete: now we need to check its purpose */ + ok = check_chain_extensions(ctx); + + if (!ok) + goto end; + + /* Check name constraints */ + + ok = check_name_constraints(ctx); + + if (!ok) + goto end; + + /* The chain extensions are OK: check trust */ + + if (param->trust > 0) + ok = check_trust(ctx); + + if (!ok) + goto end; + + /* We may as well copy down any DSA parameters that are required */ + X509_get_pubkey_parameters(NULL, ctx->chain); + + /* + * Check revocation status: we do this after copying parameters because + * they may be needed for CRL signature verification. + */ + + ok = ctx->check_revocation(ctx); + if (!ok) + goto end; + + /* At this point, we have a chain and need to verify it */ + if (ctx->verify != NULL) + ok = ctx->verify(ctx); + else + ok = internal_verify(ctx); + if (!ok) + goto end; + +#ifndef OPENSSL_NO_RFC3779 + /* RFC 3779 path validation, now that CRL check has been done */ + ok = v3_asid_validate_path(ctx); + if (!ok) + goto end; + ok = v3_addr_validate_path(ctx); + if (!ok) + goto end; +#endif + + /* If we get this far evaluate policies */ + if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) + ok = ctx->check_policy(ctx); + if (!ok) + goto end; + if (0) { + end: + X509_get_pubkey_parameters(NULL, ctx->chain); + } + if (sktmp != NULL) + sk_X509_free(sktmp); + if (chain_ss != NULL) + X509_free(chain_ss); + return ok; +} + +/* + * Given a STACK_OF(X509) find the issuer of cert (if any) + */ + +static X509 *find_issuer(X509_STORE_CTX *ctx, STACK_OF(X509) *sk, X509 *x) +{ + int i; + X509 *issuer; + for (i = 0; i < sk_X509_num(sk); i++) { + issuer = sk_X509_value(sk, i); + if (ctx->check_issued(ctx, x, issuer)) + return issuer; + } + return NULL; +} + +/* Given a possible certificate and issuer check them */ + +static int check_issued(X509_STORE_CTX *ctx, X509 *x, X509 *issuer) +{ + int ret; + ret = X509_check_issued(issuer, x); + if (ret == X509_V_OK) + return 1; + /* If we haven't asked for issuer errors don't set ctx */ + if (!(ctx->param->flags & X509_V_FLAG_CB_ISSUER_CHECK)) + return 0; + + ctx->error = ret; + ctx->current_cert = x; + ctx->current_issuer = issuer; + return ctx->verify_cb(0, ctx); + return 0; +} + +/* Alternative lookup method: look from a STACK stored in other_ctx */ + +static int get_issuer_sk(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) +{ + *issuer = find_issuer(ctx, ctx->other_ctx, x); + if (*issuer) { + CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509); + return 1; + } else + return 0; +} + +/* + * Check a certificate chains extensions for consistency with the supplied + * purpose + */ + +static int check_chain_extensions(X509_STORE_CTX *ctx) +{ +#ifdef OPENSSL_NO_CHAIN_VERIFY + return 1; +#else + int i, ok = 0, must_be_ca, plen = 0; + X509 *x; + int (*cb) (int xok, X509_STORE_CTX *xctx); + int proxy_path_length = 0; + int purpose; + int allow_proxy_certs; + cb = ctx->verify_cb; + + /*- + * must_be_ca can have 1 of 3 values: + * -1: we accept both CA and non-CA certificates, to allow direct + * use of self-signed certificates (which are marked as CA). + * 0: we only accept non-CA certificates. This is currently not + * used, but the possibility is present for future extensions. + * 1: we only accept CA certificates. This is currently used for + * all certificates in the chain except the leaf certificate. + */ + must_be_ca = -1; + + /* CRL path validation */ + if (ctx->parent) { + allow_proxy_certs = 0; + purpose = X509_PURPOSE_CRL_SIGN; + } else { + allow_proxy_certs = + ! !(ctx->param->flags & X509_V_FLAG_ALLOW_PROXY_CERTS); + /* + * A hack to keep people who don't want to modify their software + * happy + */ + if (getenv("OPENSSL_ALLOW_PROXY_CERTS")) + allow_proxy_certs = 1; + purpose = ctx->param->purpose; + } + + /* Check all untrusted certificates */ + for (i = 0; i < ctx->last_untrusted; i++) { + int ret; + x = sk_X509_value(ctx->chain, i); + if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) + && (x->ex_flags & EXFLAG_CRITICAL)) { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + if (!allow_proxy_certs && (x->ex_flags & EXFLAG_PROXY)) { + ctx->error = X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + ret = X509_check_ca(x); + switch (must_be_ca) { + case -1: + if ((ctx->param->flags & X509_V_FLAG_X509_STRICT) + && (ret != 1) && (ret != 0)) { + ret = 0; + ctx->error = X509_V_ERR_INVALID_CA; + } else + ret = 1; + break; + case 0: + if (ret != 0) { + ret = 0; + ctx->error = X509_V_ERR_INVALID_NON_CA; + } else + ret = 1; + break; + default: + if ((ret == 0) + || ((ctx->param->flags & X509_V_FLAG_X509_STRICT) + && (ret != 1))) { + ret = 0; + ctx->error = X509_V_ERR_INVALID_CA; + } else + ret = 1; + break; + } + if (ret == 0) { + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + if (ctx->param->purpose > 0) { + ret = X509_check_purpose(x, purpose, must_be_ca > 0); + if ((ret == 0) + || ((ctx->param->flags & X509_V_FLAG_X509_STRICT) + && (ret != 1))) { + ctx->error = X509_V_ERR_INVALID_PURPOSE; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + } + /* Check pathlen if not self issued */ + if ((i > 1) && !(x->ex_flags & EXFLAG_SI) + && (x->ex_pathlen != -1) + && (plen > (x->ex_pathlen + proxy_path_length + 1))) { + ctx->error = X509_V_ERR_PATH_LENGTH_EXCEEDED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + /* Increment path length if not self issued */ + if (!(x->ex_flags & EXFLAG_SI)) + plen++; + /* + * If this certificate is a proxy certificate, the next certificate + * must be another proxy certificate or a EE certificate. If not, + * the next certificate must be a CA certificate. + */ + if (x->ex_flags & EXFLAG_PROXY) { + if (x->ex_pcpathlen != -1 && i > x->ex_pcpathlen) { + ctx->error = X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED; + ctx->error_depth = i; + ctx->current_cert = x; + ok = cb(0, ctx); + if (!ok) + goto end; + } + proxy_path_length++; + must_be_ca = 0; + } else + must_be_ca = 1; + } + ok = 1; + end: + return ok; +#endif +} + +static int check_name_constraints(X509_STORE_CTX *ctx) +{ + X509 *x; + int i, j, rv; + /* Check name constraints for all certificates */ + for (i = sk_X509_num(ctx->chain) - 1; i >= 0; i--) { + x = sk_X509_value(ctx->chain, i); + /* Ignore self issued certs unless last in chain */ + if (i && (x->ex_flags & EXFLAG_SI)) + continue; + /* + * Check against constraints for all certificates higher in chain + * including trust anchor. Trust anchor not strictly speaking needed + * but if it includes constraints it is to be assumed it expects them + * to be obeyed. + */ + for (j = sk_X509_num(ctx->chain) - 1; j > i; j--) { + NAME_CONSTRAINTS *nc = sk_X509_value(ctx->chain, j)->nc; + if (nc) { + rv = NAME_CONSTRAINTS_check(x, nc); + if (rv != X509_V_OK) { + ctx->error = rv; + ctx->error_depth = i; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + } + } + } + return 1; +} + +static int check_trust(X509_STORE_CTX *ctx) +{ +#ifdef OPENSSL_NO_CHAIN_VERIFY + return 1; +#else + int i, ok; + X509 *x; + int (*cb) (int xok, X509_STORE_CTX *xctx); + cb = ctx->verify_cb; +/* For now just check the last certificate in the chain */ + i = sk_X509_num(ctx->chain) - 1; + x = sk_X509_value(ctx->chain, i); + ok = X509_check_trust(x, ctx->param->trust, 0); + if (ok == X509_TRUST_TRUSTED) + return 1; + ctx->error_depth = i; + ctx->current_cert = x; + if (ok == X509_TRUST_REJECTED) + ctx->error = X509_V_ERR_CERT_REJECTED; + else + ctx->error = X509_V_ERR_CERT_UNTRUSTED; + ok = cb(0, ctx); + return ok; +#endif +} + +static int check_revocation(X509_STORE_CTX *ctx) +{ + int i, last, ok; + if (!(ctx->param->flags & X509_V_FLAG_CRL_CHECK)) + return 1; + if (ctx->param->flags & X509_V_FLAG_CRL_CHECK_ALL) + last = sk_X509_num(ctx->chain) - 1; + else { + /* If checking CRL paths this isn't the EE certificate */ + if (ctx->parent) + return 1; + last = 0; + } + for (i = 0; i <= last; i++) { + ctx->error_depth = i; + ok = check_cert(ctx); + if (!ok) + return ok; + } + return 1; +} + +static int check_cert(X509_STORE_CTX *ctx) +{ + X509_CRL *crl = NULL, *dcrl = NULL; + X509 *x; + int ok, cnum; + unsigned int last_reasons; + cnum = ctx->error_depth; + x = sk_X509_value(ctx->chain, cnum); + ctx->current_cert = x; + ctx->current_issuer = NULL; + ctx->current_crl_score = 0; + ctx->current_reasons = 0; + while (ctx->current_reasons != CRLDP_ALL_REASONS) { + last_reasons = ctx->current_reasons; + /* Try to retrieve relevant CRL */ + if (ctx->get_crl) + ok = ctx->get_crl(ctx, &crl, x); + else + ok = get_crl_delta(ctx, &crl, &dcrl, x); + /* + * If error looking up CRL, nothing we can do except notify callback + */ + if (!ok) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + ok = ctx->verify_cb(0, ctx); + goto err; + } + ctx->current_crl = crl; + ok = ctx->check_crl(ctx, crl); + if (!ok) + goto err; + + if (dcrl) { + ok = ctx->check_crl(ctx, dcrl); + if (!ok) + goto err; + ok = ctx->cert_crl(ctx, dcrl, x); + if (!ok) + goto err; + } else + ok = 1; + + /* Don't look in full CRL if delta reason is removefromCRL */ + if (ok != 2) { + ok = ctx->cert_crl(ctx, crl, x); + if (!ok) + goto err; + } + + X509_CRL_free(crl); + X509_CRL_free(dcrl); + crl = NULL; + dcrl = NULL; + /* + * If reasons not updated we wont get anywhere by another iteration, + * so exit loop. + */ + if (last_reasons == ctx->current_reasons) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL; + ok = ctx->verify_cb(0, ctx); + goto err; + } + } + err: + X509_CRL_free(crl); + X509_CRL_free(dcrl); + + ctx->current_crl = NULL; + return ok; + +} + +/* Check CRL times against values in X509_STORE_CTX */ + +static int check_crl_time(X509_STORE_CTX *ctx, X509_CRL *crl, int notify) +{ + time_t *ptime; + int i; + if (notify) + ctx->current_crl = crl; + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + ptime = &ctx->param->check_time; + else + ptime = NULL; + + i = X509_cmp_time(X509_CRL_get_lastUpdate(crl), ptime); + if (i == 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i > 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_CRL_NOT_YET_VALID; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (X509_CRL_get_nextUpdate(crl)) { + i = X509_cmp_time(X509_CRL_get_nextUpdate(crl), ptime); + + if (i == 0) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + /* Ignore expiry of base CRL is delta is valid */ + if ((i < 0) && !(ctx->current_crl_score & CRL_SCORE_TIME_DELTA)) { + if (!notify) + return 0; + ctx->error = X509_V_ERR_CRL_HAS_EXPIRED; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + } + + if (notify) + ctx->current_crl = NULL; + + return 1; +} + +static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl, + X509 **pissuer, int *pscore, unsigned int *preasons, + STACK_OF(X509_CRL) *crls) +{ + int i, crl_score, best_score = *pscore; + unsigned int reasons, best_reasons = 0; + X509 *x = ctx->current_cert; + X509_CRL *crl, *best_crl = NULL; + X509 *crl_issuer = NULL, *best_crl_issuer = NULL; + + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + crl = sk_X509_CRL_value(crls, i); + reasons = *preasons; + crl_score = get_crl_score(ctx, &crl_issuer, &reasons, crl, x); + + if (crl_score > best_score) { + best_crl = crl; + best_crl_issuer = crl_issuer; + best_score = crl_score; + best_reasons = reasons; + } + } + + if (best_crl) { + if (*pcrl) + X509_CRL_free(*pcrl); + *pcrl = best_crl; + *pissuer = best_crl_issuer; + *pscore = best_score; + *preasons = best_reasons; + CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL); + if (*pdcrl) { + X509_CRL_free(*pdcrl); + *pdcrl = NULL; + } + get_delta_sk(ctx, pdcrl, pscore, best_crl, crls); + } + + if (best_score >= CRL_SCORE_VALID) + return 1; + + return 0; +} + +/* + * Compare two CRL extensions for delta checking purposes. They should be + * both present or both absent. If both present all fields must be identical. + */ + +static int crl_extension_match(X509_CRL *a, X509_CRL *b, int nid) +{ + ASN1_OCTET_STRING *exta, *extb; + int i; + i = X509_CRL_get_ext_by_NID(a, nid, -1); + if (i >= 0) { + /* Can't have multiple occurrences */ + if (X509_CRL_get_ext_by_NID(a, nid, i) != -1) + return 0; + exta = X509_EXTENSION_get_data(X509_CRL_get_ext(a, i)); + } else + exta = NULL; + + i = X509_CRL_get_ext_by_NID(b, nid, -1); + + if (i >= 0) { + + if (X509_CRL_get_ext_by_NID(b, nid, i) != -1) + return 0; + extb = X509_EXTENSION_get_data(X509_CRL_get_ext(b, i)); + } else + extb = NULL; + + if (!exta && !extb) + return 1; + + if (!exta || !extb) + return 0; + + if (ASN1_OCTET_STRING_cmp(exta, extb)) + return 0; + + return 1; +} + +/* See if a base and delta are compatible */ + +static int check_delta_base(X509_CRL *delta, X509_CRL *base) +{ + /* Delta CRL must be a delta */ + if (!delta->base_crl_number) + return 0; + /* Base must have a CRL number */ + if (!base->crl_number) + return 0; + /* Issuer names must match */ + if (X509_NAME_cmp(X509_CRL_get_issuer(base), X509_CRL_get_issuer(delta))) + return 0; + /* AKID and IDP must match */ + if (!crl_extension_match(delta, base, NID_authority_key_identifier)) + return 0; + if (!crl_extension_match(delta, base, NID_issuing_distribution_point)) + return 0; + /* Delta CRL base number must not exceed Full CRL number. */ + if (ASN1_INTEGER_cmp(delta->base_crl_number, base->crl_number) > 0) + return 0; + /* Delta CRL number must exceed full CRL number */ + if (ASN1_INTEGER_cmp(delta->crl_number, base->crl_number) > 0) + return 1; + return 0; +} + +/* + * For a given base CRL find a delta... maybe extend to delta scoring or + * retrieve a chain of deltas... + */ + +static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore, + X509_CRL *base, STACK_OF(X509_CRL) *crls) +{ + X509_CRL *delta; + int i; + if (!(ctx->param->flags & X509_V_FLAG_USE_DELTAS)) + return; + if (!((ctx->current_cert->ex_flags | base->flags) & EXFLAG_FRESHEST)) + return; + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + delta = sk_X509_CRL_value(crls, i); + if (check_delta_base(delta, base)) { + if (check_crl_time(ctx, delta, 0)) + *pscore |= CRL_SCORE_TIME_DELTA; + CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL); + *dcrl = delta; + return; + } + } + *dcrl = NULL; +} + +/* + * For a given CRL return how suitable it is for the supplied certificate + * 'x'. The return value is a mask of several criteria. If the issuer is not + * the certificate issuer this is returned in *pissuer. The reasons mask is + * also used to determine if the CRL is suitable: if no new reasons the CRL + * is rejected, otherwise reasons is updated. + */ + +static int get_crl_score(X509_STORE_CTX *ctx, X509 **pissuer, + unsigned int *preasons, X509_CRL *crl, X509 *x) +{ + + int crl_score = 0; + unsigned int tmp_reasons = *preasons, crl_reasons; + + /* First see if we can reject CRL straight away */ + + /* Invalid IDP cannot be processed */ + if (crl->idp_flags & IDP_INVALID) + return 0; + /* Reason codes or indirect CRLs need extended CRL support */ + if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) { + if (crl->idp_flags & (IDP_INDIRECT | IDP_REASONS)) + return 0; + } else if (crl->idp_flags & IDP_REASONS) { + /* If no new reasons reject */ + if (!(crl->idp_reasons & ~tmp_reasons)) + return 0; + } + /* Don't process deltas at this stage */ + else if (crl->base_crl_number) + return 0; + /* If issuer name doesn't match certificate need indirect CRL */ + if (X509_NAME_cmp(X509_get_issuer_name(x), X509_CRL_get_issuer(crl))) { + if (!(crl->idp_flags & IDP_INDIRECT)) + return 0; + } else + crl_score |= CRL_SCORE_ISSUER_NAME; + + if (!(crl->flags & EXFLAG_CRITICAL)) + crl_score |= CRL_SCORE_NOCRITICAL; + + /* Check expiry */ + if (check_crl_time(ctx, crl, 0)) + crl_score |= CRL_SCORE_TIME; + + /* Check authority key ID and locate certificate issuer */ + crl_akid_check(ctx, crl, pissuer, &crl_score); + + /* If we can't locate certificate issuer at this point forget it */ + + if (!(crl_score & CRL_SCORE_AKID)) + return 0; + + /* Check cert for matching CRL distribution points */ + + if (crl_crldp_check(x, crl, crl_score, &crl_reasons)) { + /* If no new reasons reject */ + if (!(crl_reasons & ~tmp_reasons)) + return 0; + tmp_reasons |= crl_reasons; + crl_score |= CRL_SCORE_SCOPE; + } + + *preasons = tmp_reasons; + + return crl_score; + +} + +static void crl_akid_check(X509_STORE_CTX *ctx, X509_CRL *crl, + X509 **pissuer, int *pcrl_score) +{ + X509 *crl_issuer = NULL; + X509_NAME *cnm = X509_CRL_get_issuer(crl); + int cidx = ctx->error_depth; + int i; + + if (cidx != sk_X509_num(ctx->chain) - 1) + cidx++; + + crl_issuer = sk_X509_value(ctx->chain, cidx); + + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + if (*pcrl_score & CRL_SCORE_ISSUER_NAME) { + *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_ISSUER_CERT; + *pissuer = crl_issuer; + return; + } + } + + for (cidx++; cidx < sk_X509_num(ctx->chain); cidx++) { + crl_issuer = sk_X509_value(ctx->chain, cidx); + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) + continue; + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + *pcrl_score |= CRL_SCORE_AKID | CRL_SCORE_SAME_PATH; + *pissuer = crl_issuer; + return; + } + } + + /* Anything else needs extended CRL support */ + + if (!(ctx->param->flags & X509_V_FLAG_EXTENDED_CRL_SUPPORT)) + return; + + /* + * Otherwise the CRL issuer is not on the path. Look for it in the set of + * untrusted certificates. + */ + for (i = 0; i < sk_X509_num(ctx->untrusted); i++) { + crl_issuer = sk_X509_value(ctx->untrusted, i); + if (X509_NAME_cmp(X509_get_subject_name(crl_issuer), cnm)) + continue; + if (X509_check_akid(crl_issuer, crl->akid) == X509_V_OK) { + *pissuer = crl_issuer; + *pcrl_score |= CRL_SCORE_AKID; + return; + } + } +} + +/* + * Check the path of a CRL issuer certificate. This creates a new + * X509_STORE_CTX and populates it with most of the parameters from the + * parent. This could be optimised somewhat since a lot of path checking will + * be duplicated by the parent, but this will rarely be used in practice. + */ + +static int check_crl_path(X509_STORE_CTX *ctx, X509 *x) +{ + X509_STORE_CTX crl_ctx; + int ret; + /* Don't allow recursive CRL path validation */ + if (ctx->parent) + return 0; + if (!X509_STORE_CTX_init(&crl_ctx, ctx->ctx, x, ctx->untrusted)) + return -1; + + crl_ctx.crls = ctx->crls; + /* Copy verify params across */ + X509_STORE_CTX_set0_param(&crl_ctx, ctx->param); + + crl_ctx.parent = ctx; + crl_ctx.verify_cb = ctx->verify_cb; + + /* Verify CRL issuer */ + ret = X509_verify_cert(&crl_ctx); + + if (ret <= 0) + goto err; + + /* Check chain is acceptable */ + + ret = check_crl_chain(ctx, ctx->chain, crl_ctx.chain); + err: + X509_STORE_CTX_cleanup(&crl_ctx); + return ret; +} + +/* + * RFC3280 says nothing about the relationship between CRL path and + * certificate path, which could lead to situations where a certificate could + * be revoked or validated by a CA not authorised to do so. RFC5280 is more + * strict and states that the two paths must end in the same trust anchor, + * though some discussions remain... until this is resolved we use the + * RFC5280 version + */ + +static int check_crl_chain(X509_STORE_CTX *ctx, + STACK_OF(X509) *cert_path, + STACK_OF(X509) *crl_path) +{ + X509 *cert_ta, *crl_ta; + cert_ta = sk_X509_value(cert_path, sk_X509_num(cert_path) - 1); + crl_ta = sk_X509_value(crl_path, sk_X509_num(crl_path) - 1); + if (!X509_cmp(cert_ta, crl_ta)) + return 1; + return 0; +} + +/*- + * Check for match between two dist point names: three separate cases. + * 1. Both are relative names and compare X509_NAME types. + * 2. One full, one relative. Compare X509_NAME to GENERAL_NAMES. + * 3. Both are full names and compare two GENERAL_NAMES. + * 4. One is NULL: automatic match. + */ + +static int idp_check_dp(DIST_POINT_NAME *a, DIST_POINT_NAME *b) +{ + X509_NAME *nm = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gena, *genb; + int i, j; + if (!a || !b) + return 1; + if (a->type == 1) { + if (!a->dpname) + return 0; + /* Case 1: two X509_NAME */ + if (b->type == 1) { + if (!b->dpname) + return 0; + if (!X509_NAME_cmp(a->dpname, b->dpname)) + return 1; + else + return 0; + } + /* Case 2: set name and GENERAL_NAMES appropriately */ + nm = a->dpname; + gens = b->name.fullname; + } else if (b->type == 1) { + if (!b->dpname) + return 0; + /* Case 2: set name and GENERAL_NAMES appropriately */ + gens = a->name.fullname; + nm = b->dpname; + } + + /* Handle case 2 with one GENERAL_NAMES and one X509_NAME */ + if (nm) { + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gena = sk_GENERAL_NAME_value(gens, i); + if (gena->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(nm, gena->d.directoryName)) + return 1; + } + return 0; + } + + /* Else case 3: two GENERAL_NAMES */ + + for (i = 0; i < sk_GENERAL_NAME_num(a->name.fullname); i++) { + gena = sk_GENERAL_NAME_value(a->name.fullname, i); + for (j = 0; j < sk_GENERAL_NAME_num(b->name.fullname); j++) { + genb = sk_GENERAL_NAME_value(b->name.fullname, j); + if (!GENERAL_NAME_cmp(gena, genb)) + return 1; + } + } + + return 0; + +} + +static int crldp_check_crlissuer(DIST_POINT *dp, X509_CRL *crl, int crl_score) +{ + int i; + X509_NAME *nm = X509_CRL_get_issuer(crl); + /* If no CRLissuer return is successful iff don't need a match */ + if (!dp->CRLissuer) + return ! !(crl_score & CRL_SCORE_ISSUER_NAME); + for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type != GEN_DIRNAME) + continue; + if (!X509_NAME_cmp(gen->d.directoryName, nm)) + return 1; + } + return 0; +} + +/* Check CRLDP and IDP */ + +static int crl_crldp_check(X509 *x, X509_CRL *crl, int crl_score, + unsigned int *preasons) +{ + int i; + if (crl->idp_flags & IDP_ONLYATTR) + return 0; + if (x->ex_flags & EXFLAG_CA) { + if (crl->idp_flags & IDP_ONLYUSER) + return 0; + } else { + if (crl->idp_flags & IDP_ONLYCA) + return 0; + } + *preasons = crl->idp_reasons; + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) { + DIST_POINT *dp = sk_DIST_POINT_value(x->crldp, i); + if (crldp_check_crlissuer(dp, crl, crl_score)) { + if (!crl->idp || idp_check_dp(dp->distpoint, crl->idp->distpoint)) { + *preasons &= dp->dp_reasons; + return 1; + } + } + } + if ((!crl->idp || !crl->idp->distpoint) + && (crl_score & CRL_SCORE_ISSUER_NAME)) + return 1; + return 0; +} + +/* + * Retrieve CRL corresponding to current certificate. If deltas enabled try + * to find a delta CRL too + */ + +static int get_crl_delta(X509_STORE_CTX *ctx, + X509_CRL **pcrl, X509_CRL **pdcrl, X509 *x) +{ + int ok; + X509 *issuer = NULL; + int crl_score = 0; + unsigned int reasons; + X509_CRL *crl = NULL, *dcrl = NULL; + STACK_OF(X509_CRL) *skcrl; + X509_NAME *nm = X509_get_issuer_name(x); + reasons = ctx->current_reasons; + ok = get_crl_sk(ctx, &crl, &dcrl, + &issuer, &crl_score, &reasons, ctx->crls); + + if (ok) + goto done; + + /* Lookup CRLs from store */ + + skcrl = ctx->lookup_crls(ctx, nm); + + /* If no CRLs found and a near match from get_crl_sk use that */ + if (!skcrl && crl) + goto done; + + get_crl_sk(ctx, &crl, &dcrl, &issuer, &crl_score, &reasons, skcrl); + + sk_X509_CRL_pop_free(skcrl, X509_CRL_free); + + done: + + /* If we got any kind of CRL use it and return success */ + if (crl) { + ctx->current_issuer = issuer; + ctx->current_crl_score = crl_score; + ctx->current_reasons = reasons; + *pcrl = crl; + *pdcrl = dcrl; + return 1; + } + + return 0; +} + +/* Check CRL validity */ +static int check_crl(X509_STORE_CTX *ctx, X509_CRL *crl) +{ + X509 *issuer = NULL; + EVP_PKEY *ikey = NULL; + int ok = 0, chnum, cnum; + cnum = ctx->error_depth; + chnum = sk_X509_num(ctx->chain) - 1; + /* if we have an alternative CRL issuer cert use that */ + if (ctx->current_issuer) + issuer = ctx->current_issuer; + + /* + * Else find CRL issuer: if not last certificate then issuer is next + * certificate in chain. + */ + else if (cnum < chnum) + issuer = sk_X509_value(ctx->chain, cnum + 1); + else { + issuer = sk_X509_value(ctx->chain, chnum); + /* If not self signed, can't check signature */ + if (!ctx->check_issued(ctx, issuer, issuer)) { + ctx->error = X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + + if (issuer) { + /* + * Skip most tests for deltas because they have already been done + */ + if (!crl->base_crl_number) { + /* Check for cRLSign bit if keyUsage present */ + if ((issuer->ex_flags & EXFLAG_KUSAGE) && + !(issuer->ex_kusage & KU_CRL_SIGN)) { + ctx->error = X509_V_ERR_KEYUSAGE_NO_CRL_SIGN; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + if (!(ctx->current_crl_score & CRL_SCORE_SCOPE)) { + ctx->error = X509_V_ERR_DIFFERENT_CRL_SCOPE; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + if (!(ctx->current_crl_score & CRL_SCORE_SAME_PATH)) { + if (check_crl_path(ctx, ctx->current_issuer) <= 0) { + ctx->error = X509_V_ERR_CRL_PATH_VALIDATION_ERROR; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + + if (crl->idp_flags & IDP_INVALID) { + ctx->error = X509_V_ERR_INVALID_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + + } + + if (!(ctx->current_crl_score & CRL_SCORE_TIME)) { + ok = check_crl_time(ctx, crl, 1); + if (!ok) + goto err; + } + + /* Attempt to get issuer certificate public key */ + ikey = X509_get_pubkey(issuer); + + if (!ikey) { + ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } else { + /* Verify CRL signature */ + if (X509_CRL_verify(crl, ikey) <= 0) { + ctx->error = X509_V_ERR_CRL_SIGNATURE_FAILURE; + ok = ctx->verify_cb(0, ctx); + if (!ok) + goto err; + } + } + } + + ok = 1; + + err: + EVP_PKEY_free(ikey); + return ok; +} + +/* Check certificate against CRL */ +static int cert_crl(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x) +{ + int ok; + X509_REVOKED *rev; + /* + * The rules changed for this... previously if a CRL contained unhandled + * critical extensions it could still be used to indicate a certificate + * was revoked. This has since been changed since critical extension can + * change the meaning of CRL entries. + */ + if (!(ctx->param->flags & X509_V_FLAG_IGNORE_CRITICAL) + && (crl->flags & EXFLAG_CRITICAL)) { + ctx->error = X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION; + ok = ctx->verify_cb(0, ctx); + if (!ok) + return 0; + } + /* + * Look for serial number of certificate in CRL If found make sure reason + * is not removeFromCRL. + */ + if (X509_CRL_get0_by_cert(crl, &rev, x)) { + if (rev->reason == CRL_REASON_REMOVE_FROM_CRL) + return 2; + ctx->error = X509_V_ERR_CERT_REVOKED; + ok = ctx->verify_cb(0, ctx); + if (!ok) + return 0; + } + + return 1; +} + +static int check_policy(X509_STORE_CTX *ctx) +{ + int ret; + if (ctx->parent) + return 1; + ret = X509_policy_check(&ctx->tree, &ctx->explicit_policy, ctx->chain, + ctx->param->policies, ctx->param->flags); + if (ret == 0) { + X509err(X509_F_CHECK_POLICY, ERR_R_MALLOC_FAILURE); + return 0; + } + /* Invalid or inconsistent extensions */ + if (ret == -1) { + /* + * Locate certificates with bad extensions and notify callback. + */ + X509 *x; + int i; + for (i = 1; i < sk_X509_num(ctx->chain); i++) { + x = sk_X509_value(ctx->chain, i); + if (!(x->ex_flags & EXFLAG_INVALID_POLICY)) + continue; + ctx->current_cert = x; + ctx->error = X509_V_ERR_INVALID_POLICY_EXTENSION; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + return 1; + } + if (ret == -2) { + ctx->current_cert = NULL; + ctx->error = X509_V_ERR_NO_EXPLICIT_POLICY; + return ctx->verify_cb(0, ctx); + } + + if (ctx->param->flags & X509_V_FLAG_NOTIFY_POLICY) { + ctx->current_cert = NULL; + ctx->error = X509_V_OK; + if (!ctx->verify_cb(2, ctx)) + return 0; + } + + return 1; +} + +static int check_cert_time(X509_STORE_CTX *ctx, X509 *x) +{ + time_t *ptime; + int i; + + if (ctx->param->flags & X509_V_FLAG_USE_CHECK_TIME) + ptime = &ctx->param->check_time; + else + ptime = NULL; + + i = X509_cmp_time(X509_get_notBefore(x), ptime); + if (i == 0) { + ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i > 0) { + ctx->error = X509_V_ERR_CERT_NOT_YET_VALID; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + i = X509_cmp_time(X509_get_notAfter(x), ptime); + if (i == 0) { + ctx->error = X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + if (i < 0) { + ctx->error = X509_V_ERR_CERT_HAS_EXPIRED; + ctx->current_cert = x; + if (!ctx->verify_cb(0, ctx)) + return 0; + } + + return 1; +} + +static int internal_verify(X509_STORE_CTX *ctx) +{ + int ok = 0, n; + X509 *xs, *xi; + EVP_PKEY *pkey = NULL; + int (*cb) (int xok, X509_STORE_CTX *xctx); + + cb = ctx->verify_cb; + + n = sk_X509_num(ctx->chain); + ctx->error_depth = n - 1; + n--; + xi = sk_X509_value(ctx->chain, n); + + if (ctx->check_issued(ctx, xi, xi)) + xs = xi; + else { + if (n <= 0) { + ctx->error = X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE; + ctx->current_cert = xi; + ok = cb(0, ctx); + goto end; + } else { + n--; + ctx->error_depth = n; + xs = sk_X509_value(ctx->chain, n); + } + } + +/* ctx->error=0; not needed */ + while (n >= 0) { + ctx->error_depth = n; + + /* + * Skip signature check for self signed certificates unless + * explicitly asked for. It doesn't add any security and just wastes + * time. + */ + if (!xs->valid + && (xs != xi + || (ctx->param->flags & X509_V_FLAG_CHECK_SS_SIGNATURE))) { + if ((pkey = X509_get_pubkey(xi)) == NULL) { + ctx->error = X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY; + ctx->current_cert = xi; + ok = (*cb) (0, ctx); + if (!ok) + goto end; + } else if (X509_verify(xs, pkey) <= 0) { + ctx->error = X509_V_ERR_CERT_SIGNATURE_FAILURE; + ctx->current_cert = xs; + ok = (*cb) (0, ctx); + if (!ok) { + EVP_PKEY_free(pkey); + goto end; + } + } + EVP_PKEY_free(pkey); + pkey = NULL; + } + + xs->valid = 1; + + ok = check_cert_time(ctx, xs); + if (!ok) + goto end; + + /* The last error (if any) is still in the error value */ + ctx->current_issuer = xi; + ctx->current_cert = xs; + ok = (*cb) (1, ctx); + if (!ok) + goto end; + + n--; + if (n >= 0) { + xi = xs; + xs = sk_X509_value(ctx->chain, n); + } + } + ok = 1; + end: + return ok; +} + +int X509_cmp_current_time(const ASN1_TIME *ctm) +{ + return X509_cmp_time(ctm, NULL); +} + +int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) +{ + char *str; + ASN1_TIME atm; + long offset; + char buff1[24], buff2[24], *p; + int i, j, remaining; + + p = buff1; + remaining = ctm->length; + str = (char *)ctm->data; + /* + * Note that the following (historical) code allows much more slack in the + * time format than RFC5280. In RFC5280, the representation is fixed: + * UTCTime: YYMMDDHHMMSSZ + * GeneralizedTime: YYYYMMDDHHMMSSZ + */ + if (ctm->type == V_ASN1_UTCTIME) { + /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */ + int min_length = sizeof("YYMMDDHHMMZ") - 1; + int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1; + if (remaining < min_length || remaining > max_length) + return 0; + memcpy(p, str, 10); + p += 10; + str += 10; + remaining -= 10; + } else { + /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */ + int min_length = sizeof("YYYYMMDDHHMMZ") - 1; + int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1; + if (remaining < min_length || remaining > max_length) + return 0; + memcpy(p, str, 12); + p += 12; + str += 12; + remaining -= 12; + } + + if ((*str == 'Z') || (*str == '-') || (*str == '+')) { + *(p++) = '0'; + *(p++) = '0'; + } else { + /* SS (seconds) */ + if (remaining < 2) + return 0; + *(p++) = *(str++); + *(p++) = *(str++); + remaining -= 2; + /* + * Skip any (up to three) fractional seconds... + * TODO(emilia): in RFC5280, fractional seconds are forbidden. + * Can we just kill them altogether? + */ + if (remaining && *str == '.') { + str++; + remaining--; + for (i = 0; i < 3 && remaining; i++, str++, remaining--) { + if (*str < '0' || *str > '9') + break; + } + } + + } + *(p++) = 'Z'; + *(p++) = '\0'; + + /* We now need either a terminating 'Z' or an offset. */ + if (!remaining) + return 0; + if (*str == 'Z') { + if (remaining != 1) + return 0; + offset = 0; + } else { + /* (+-)HHMM */ + if ((*str != '+') && (*str != '-')) + return 0; + /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */ + if (remaining != 5) + return 0; + if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' || + str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9') + return 0; + offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60; + offset += (str[3] - '0') * 10 + (str[4] - '0'); + if (*str == '-') + offset = -offset; + } + atm.type = ctm->type; + atm.flags = 0; + atm.length = sizeof(buff2); + atm.data = (unsigned char *)buff2; + + if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL) + return 0; + + if (ctm->type == V_ASN1_UTCTIME) { + i = (buff1[0] - '0') * 10 + (buff1[1] - '0'); + if (i < 50) + i += 100; /* cf. RFC 2459 */ + j = (buff2[0] - '0') * 10 + (buff2[1] - '0'); + if (j < 50) + j += 100; + + if (i < j) + return -1; + if (i > j) + return 1; + } + i = strcmp(buff1, buff2); + if (i == 0) /* wait a second then return younger :-) */ + return -1; + else + return i; +} + +ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj) +{ + return X509_time_adj(s, adj, NULL); +} + +ASN1_TIME *X509_time_adj(ASN1_TIME *s, long offset_sec, time_t *in_tm) +{ + return X509_time_adj_ex(s, 0, offset_sec, in_tm); +} + +ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s, + int offset_day, long offset_sec, time_t *in_tm) +{ + time_t t; + + if (in_tm) + t = *in_tm; + else + time(&t); + + if (s && !(s->flags & ASN1_STRING_FLAG_MSTRING)) { + if (s->type == V_ASN1_UTCTIME) + return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec); + if (s->type == V_ASN1_GENERALIZEDTIME) + return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec); + } + return ASN1_TIME_adj(s, t, offset_day, offset_sec); +} + +int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) +{ + EVP_PKEY *ktmp = NULL, *ktmp2; + int i, j; + + if ((pkey != NULL) && !EVP_PKEY_missing_parameters(pkey)) + return 1; + + for (i = 0; i < sk_X509_num(chain); i++) { + ktmp = X509_get_pubkey(sk_X509_value(chain, i)); + if (ktmp == NULL) { + X509err(X509_F_X509_GET_PUBKEY_PARAMETERS, + X509_R_UNABLE_TO_GET_CERTS_PUBLIC_KEY); + return 0; + } + if (!EVP_PKEY_missing_parameters(ktmp)) + break; + else { + EVP_PKEY_free(ktmp); + ktmp = NULL; + } + } + if (ktmp == NULL) { + X509err(X509_F_X509_GET_PUBKEY_PARAMETERS, + X509_R_UNABLE_TO_FIND_PARAMETERS_IN_CHAIN); + return 0; + } + + /* first, populate the other certs */ + for (j = i - 1; j >= 0; j--) { + ktmp2 = X509_get_pubkey(sk_X509_value(chain, j)); + EVP_PKEY_copy_parameters(ktmp2, ktmp); + EVP_PKEY_free(ktmp2); + } + + if (pkey != NULL) + EVP_PKEY_copy_parameters(pkey, ktmp); + EVP_PKEY_free(ktmp); + return 1; +} + +int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + /* + * This function is (usually) called only once, by + * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). + */ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_X509_STORE_CTX, argl, argp, + new_func, dup_func, free_func); +} + +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data) +{ + return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); +} + +void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx) +{ + return CRYPTO_get_ex_data(&ctx->ex_data, idx); +} + +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx) +{ + return ctx->error; +} + +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int err) +{ + ctx->error = err; +} + +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx) +{ + return ctx->error_depth; +} + +X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx) +{ + return ctx->current_cert; +} + +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx) +{ + return ctx->chain; +} + +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx) +{ + int i; + X509 *x; + STACK_OF(X509) *chain; + if (!ctx->chain || !(chain = sk_X509_dup(ctx->chain))) + return NULL; + for (i = 0; i < sk_X509_num(chain); i++) { + x = sk_X509_value(chain, i); + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + } + return chain; +} + +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx) +{ + return ctx->current_issuer; +} + +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx) +{ + return ctx->current_crl; +} + +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx) +{ + return ctx->parent; +} + +void X509_STORE_CTX_set_cert(X509_STORE_CTX *ctx, X509 *x) +{ + ctx->cert = x; +} + +void X509_STORE_CTX_set_chain(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) +{ + ctx->untrusted = sk; +} + +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *ctx, STACK_OF(X509_CRL) *sk) +{ + ctx->crls = sk; +} + +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose) +{ + return X509_STORE_CTX_purpose_inherit(ctx, 0, purpose, 0); +} + +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust) +{ + return X509_STORE_CTX_purpose_inherit(ctx, 0, 0, trust); +} + +/* + * This function is used to set the X509_STORE_CTX purpose and trust values. + * This is intended to be used when another structure has its own trust and + * purpose values which (if set) will be inherited by the ctx. If they aren't + * set then we will usually have a default purpose in mind which should then + * be used to set the trust value. An example of this is SSL use: an SSL + * structure will have its own purpose and trust settings which the + * application can set: if they aren't set then we use the default of SSL + * client/server. + */ + +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust) +{ + int idx; + /* If purpose not set use default */ + if (!purpose) + purpose = def_purpose; + /* If we have a purpose then check it is valid */ + if (purpose) { + X509_PURPOSE *ptmp; + idx = X509_PURPOSE_get_by_id(purpose); + if (idx == -1) { + X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, + X509_R_UNKNOWN_PURPOSE_ID); + return 0; + } + ptmp = X509_PURPOSE_get0(idx); + if (ptmp->trust == X509_TRUST_DEFAULT) { + idx = X509_PURPOSE_get_by_id(def_purpose); + if (idx == -1) { + X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, + X509_R_UNKNOWN_PURPOSE_ID); + return 0; + } + ptmp = X509_PURPOSE_get0(idx); + } + /* If trust not set then get from purpose default */ + if (!trust) + trust = ptmp->trust; + } + if (trust) { + idx = X509_TRUST_get_by_id(trust); + if (idx == -1) { + X509err(X509_F_X509_STORE_CTX_PURPOSE_INHERIT, + X509_R_UNKNOWN_TRUST_ID); + return 0; + } + } + + if (purpose && !ctx->param->purpose) + ctx->param->purpose = purpose; + if (trust && !ctx->param->trust) + ctx->param->trust = trust; + return 1; +} + +X509_STORE_CTX *X509_STORE_CTX_new(void) +{ + X509_STORE_CTX *ctx; + ctx = (X509_STORE_CTX *)OPENSSL_malloc(sizeof(X509_STORE_CTX)); + if (!ctx) { + X509err(X509_F_X509_STORE_CTX_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + memset(ctx, 0, sizeof(X509_STORE_CTX)); + return ctx; +} + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx) +{ + if (!ctx) + return; + X509_STORE_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, X509 *x509, + STACK_OF(X509) *chain) +{ + int ret = 1; + ctx->ctx = store; + ctx->current_method = 0; + ctx->cert = x509; + ctx->untrusted = chain; + ctx->crls = NULL; + ctx->last_untrusted = 0; + ctx->other_ctx = NULL; + ctx->valid = 0; + ctx->chain = NULL; + ctx->error = 0; + ctx->explicit_policy = 0; + ctx->error_depth = 0; + ctx->current_cert = NULL; + ctx->current_issuer = NULL; + ctx->current_crl = NULL; + ctx->current_crl_score = 0; + ctx->current_reasons = 0; + ctx->tree = NULL; + ctx->parent = NULL; + /* Zero ex_data to make sure we're cleanup-safe */ + memset(&ctx->ex_data, 0, sizeof(ctx->ex_data)); + + ctx->param = X509_VERIFY_PARAM_new(); + if (!ctx->param) { + X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); + return 0; + } + + /* + * Inherit callbacks and flags from X509_STORE if not set use defaults. + */ + if (store) + ret = X509_VERIFY_PARAM_inherit(ctx->param, store->param); + else + ctx->param->inh_flags |= X509_VP_FLAG_DEFAULT | X509_VP_FLAG_ONCE; + + if (store) { + ctx->verify_cb = store->verify_cb; + /* Seems to always be 0 in OpenSSL, else must be idempotent */ + ctx->cleanup = store->cleanup; + } else + ctx->cleanup = 0; + + if (ret) + ret = X509_VERIFY_PARAM_inherit(ctx->param, + X509_VERIFY_PARAM_lookup("default")); + + if (ret == 0) { + X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (store && store->check_issued) + ctx->check_issued = store->check_issued; + else + ctx->check_issued = check_issued; + + if (store && store->get_issuer) + ctx->get_issuer = store->get_issuer; + else + ctx->get_issuer = X509_STORE_CTX_get1_issuer; + + if (store && store->verify_cb) + ctx->verify_cb = store->verify_cb; + else + ctx->verify_cb = null_callback; + + if (store && store->verify) + ctx->verify = store->verify; + else + ctx->verify = internal_verify; + + if (store && store->check_revocation) + ctx->check_revocation = store->check_revocation; + else + ctx->check_revocation = check_revocation; + + if (store && store->get_crl) + ctx->get_crl = store->get_crl; + else + ctx->get_crl = NULL; + + if (store && store->check_crl) + ctx->check_crl = store->check_crl; + else + ctx->check_crl = check_crl; + + if (store && store->cert_crl) + ctx->cert_crl = store->cert_crl; + else + ctx->cert_crl = cert_crl; + + if (store && store->lookup_certs) + ctx->lookup_certs = store->lookup_certs; + else + ctx->lookup_certs = X509_STORE_get1_certs; + + if (store && store->lookup_crls) + ctx->lookup_crls = store->lookup_crls; + else + ctx->lookup_crls = X509_STORE_get1_crls; + + ctx->check_policy = check_policy; + + if (CRYPTO_new_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, + &ctx->ex_data)) + return 1; + X509err(X509_F_X509_STORE_CTX_INIT, ERR_R_MALLOC_FAILURE); + + err: + /* + * On error clean up allocated storage, if the store context was not + * allocated with X509_STORE_CTX_new() this is our last chance to do so. + */ + X509_STORE_CTX_cleanup(ctx); + return 0; +} + +/* + * Set alternative lookup method: just a STACK of trusted certificates. This + * avoids X509_STORE nastiness where it isn't needed. + */ + +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk) +{ + ctx->other_ctx = sk; + ctx->get_issuer = get_issuer_sk; +} + +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx) +{ + /* + * We need to be idempotent because, unfortunately, free() also calls + * cleanup(), so the natural call sequence new(), init(), cleanup(), free() + * calls cleanup() for the same object twice! Thus we must zero the + * pointers below after they're freed! + */ + /* Seems to always be 0 in OpenSSL, do this at most once. */ + if (ctx->cleanup != NULL) { + ctx->cleanup(ctx); + ctx->cleanup = NULL; + } + if (ctx->param != NULL) { + if (ctx->parent == NULL) + X509_VERIFY_PARAM_free(ctx->param); + ctx->param = NULL; + } + if (ctx->tree != NULL) { + X509_policy_tree_free(ctx->tree); + ctx->tree = NULL; + } + if (ctx->chain != NULL) { + sk_X509_pop_free(ctx->chain, X509_free); + ctx->chain = NULL; + } + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_X509_STORE_CTX, ctx, &(ctx->ex_data)); + memset(&ctx->ex_data, 0, sizeof(CRYPTO_EX_DATA)); +} + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth) +{ + X509_VERIFY_PARAM_set_depth(ctx->param, depth); +} + +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags) +{ + X509_VERIFY_PARAM_set_flags(ctx->param, flags); +} + +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t) +{ + X509_VERIFY_PARAM_set_time(ctx->param, t); +} + +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb) (int, X509_STORE_CTX *)) +{ + ctx->verify_cb = verify_cb; +} + +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx) +{ + return ctx->tree; +} + +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx) +{ + return ctx->explicit_policy; +} + +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name) +{ + const X509_VERIFY_PARAM *param; + param = X509_VERIFY_PARAM_lookup(name); + if (!param) + return 0; + return X509_VERIFY_PARAM_inherit(ctx->param, param); +} + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx) +{ + return ctx->param; +} + +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param) +{ + if (ctx->param) + X509_VERIFY_PARAM_free(ctx->param); + ctx->param = param; +} + +IMPLEMENT_STACK_OF(X509) + +IMPLEMENT_ASN1_SET_OF(X509) + +IMPLEMENT_STACK_OF(X509_NAME) + +IMPLEMENT_STACK_OF(X509_ATTRIBUTE) + +IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE) diff --git a/libs/openssl/crypto/x509/x509_vfy.h b/libs/openssl/crypto/x509/x509_vfy.h new file mode 100644 index 00000000..b7d8b247 --- /dev/null +++ b/libs/openssl/crypto/x509/x509_vfy.h @@ -0,0 +1,595 @@ +/* crypto/x509/x509_vfy.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_X509_H +# include +/* + * openssl/x509.h ends up #include-ing this file at about the only + * appropriate moment. + */ +#endif + +#ifndef HEADER_X509_VFY_H +# define HEADER_X509_VFY_H + +# include +# ifndef OPENSSL_NO_LHASH +# include +# endif +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# if 0 +/* Outer object */ +typedef struct x509_hash_dir_st { + int num_dirs; + char **dirs; + int *dirs_type; + int num_dirs_alloced; +} X509_HASH_DIR_CTX; +# endif + +typedef struct x509_file_st { + int num_paths; /* number of paths to files or directories */ + int num_alloced; + char **paths; /* the list of paths or directories */ + int *path_type; +} X509_CERT_FILE_CTX; + +/*******************************/ +/*- +SSL_CTX -> X509_STORE + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + -> X509_LOOKUP + ->X509_LOOKUP_METHOD + +SSL -> X509_STORE_CTX + ->X509_STORE + +The X509_STORE holds the tables etc for verification stuff. +A X509_STORE_CTX is used while validating a single certificate. +The X509_STORE has X509_LOOKUPs for looking up certs. +The X509_STORE then calls a function to actually verify the +certificate chain. +*/ + +# define X509_LU_RETRY -1 +# define X509_LU_FAIL 0 +# define X509_LU_X509 1 +# define X509_LU_CRL 2 +# define X509_LU_PKEY 3 + +typedef struct x509_object_st { + /* one of the above types */ + int type; + union { + char *ptr; + X509 *x509; + X509_CRL *crl; + EVP_PKEY *pkey; + } data; +} X509_OBJECT; + +typedef struct x509_lookup_st X509_LOOKUP; + +DECLARE_STACK_OF(X509_LOOKUP) +DECLARE_STACK_OF(X509_OBJECT) + +/* This is a static that defines the function interface */ +typedef struct x509_lookup_method_st { + const char *name; + int (*new_item) (X509_LOOKUP *ctx); + void (*free) (X509_LOOKUP *ctx); + int (*init) (X509_LOOKUP *ctx); + int (*shutdown) (X509_LOOKUP *ctx); + int (*ctrl) (X509_LOOKUP *ctx, int cmd, const char *argc, long argl, + char **ret); + int (*get_by_subject) (X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); + int (*get_by_issuer_serial) (X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret); + int (*get_by_fingerprint) (X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, + X509_OBJECT *ret); + int (*get_by_alias) (X509_LOOKUP *ctx, int type, char *str, int len, + X509_OBJECT *ret); +} X509_LOOKUP_METHOD; + +/* + * This structure hold all parameters associated with a verify operation by + * including an X509_VERIFY_PARAM structure in related structures the + * parameters used can be customized + */ + +typedef struct X509_VERIFY_PARAM_st { + char *name; + time_t check_time; /* Time to use */ + unsigned long inh_flags; /* Inheritance flags */ + unsigned long flags; /* Various verify flags */ + int purpose; /* purpose to check untrusted certificates */ + int trust; /* trust setting to check */ + int depth; /* Verify depth */ + STACK_OF(ASN1_OBJECT) *policies; /* Permissible policies */ +} X509_VERIFY_PARAM; + +DECLARE_STACK_OF(X509_VERIFY_PARAM) + +/* + * This is used to hold everything. It is used for all certificate + * validation. Once we have a certificate chain, the 'verify' function is + * then called to actually check the cert chain. + */ +struct x509_store_st { + /* The following is a cache of trusted certs */ + int cache; /* if true, stash any hits */ + STACK_OF(X509_OBJECT) *objs; /* Cache of all objects */ + /* These are external lookup methods */ + STACK_OF(X509_LOOKUP) *get_cert_methods; + X509_VERIFY_PARAM *param; + /* Callbacks for various operations */ + /* called to verify a certificate */ + int (*verify) (X509_STORE_CTX *ctx); + /* error callback */ + int (*verify_cb) (int ok, X509_STORE_CTX *ctx); + /* get issuers cert from ctx */ + int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + /* check issued */ + int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer); + /* Check revocation status of chain */ + int (*check_revocation) (X509_STORE_CTX *ctx); + /* retrieve CRL */ + int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); + /* Check CRL validity */ + int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl); + /* Check certificate against CRL */ + int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); + STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm); + int (*cleanup) (X509_STORE_CTX *ctx); + CRYPTO_EX_DATA ex_data; + int references; +} /* X509_STORE */ ; + +int X509_STORE_set_depth(X509_STORE *store, int depth); + +# define X509_STORE_set_verify_cb_func(ctx,func) ((ctx)->verify_cb=(func)) +# define X509_STORE_set_verify_func(ctx,func) ((ctx)->verify=(func)) + +/* This is the functions plus an instance of the local variables. */ +struct x509_lookup_st { + int init; /* have we been started */ + int skip; /* don't use us. */ + X509_LOOKUP_METHOD *method; /* the functions */ + char *method_data; /* method data */ + X509_STORE *store_ctx; /* who owns us */ +} /* X509_LOOKUP */ ; + +/* + * This is a used when verifying cert chains. Since the gathering of the + * cert chain can take some time (and have to be 'retried', this needs to be + * kept and passed around. + */ +struct x509_store_ctx_st { /* X509_STORE_CTX */ + X509_STORE *ctx; + /* used when looking up certs */ + int current_method; + /* The following are set by the caller */ + /* The cert to check */ + X509 *cert; + /* chain of X509s - untrusted - passed in */ + STACK_OF(X509) *untrusted; + /* set of CRLs passed in */ + STACK_OF(X509_CRL) *crls; + X509_VERIFY_PARAM *param; + /* Other info for use with get_issuer() */ + void *other_ctx; + /* Callbacks for various operations */ + /* called to verify a certificate */ + int (*verify) (X509_STORE_CTX *ctx); + /* error callback */ + int (*verify_cb) (int ok, X509_STORE_CTX *ctx); + /* get issuers cert from ctx */ + int (*get_issuer) (X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + /* check issued */ + int (*check_issued) (X509_STORE_CTX *ctx, X509 *x, X509 *issuer); + /* Check revocation status of chain */ + int (*check_revocation) (X509_STORE_CTX *ctx); + /* retrieve CRL */ + int (*get_crl) (X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); + /* Check CRL validity */ + int (*check_crl) (X509_STORE_CTX *ctx, X509_CRL *crl); + /* Check certificate against CRL */ + int (*cert_crl) (X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); + int (*check_policy) (X509_STORE_CTX *ctx); + STACK_OF(X509) *(*lookup_certs) (X509_STORE_CTX *ctx, X509_NAME *nm); + STACK_OF(X509_CRL) *(*lookup_crls) (X509_STORE_CTX *ctx, X509_NAME *nm); + int (*cleanup) (X509_STORE_CTX *ctx); + /* The following is built up */ + /* if 0, rebuild chain */ + int valid; + /* index of last untrusted cert */ + int last_untrusted; + /* chain of X509s - built up and trusted */ + STACK_OF(X509) *chain; + /* Valid policy tree */ + X509_POLICY_TREE *tree; + /* Require explicit policy value */ + int explicit_policy; + /* When something goes wrong, this is why */ + int error_depth; + int error; + X509 *current_cert; + /* cert currently being tested as valid issuer */ + X509 *current_issuer; + /* current CRL */ + X509_CRL *current_crl; + /* score of current CRL */ + int current_crl_score; + /* Reason mask */ + unsigned int current_reasons; + /* For CRL path validation: parent context */ + X509_STORE_CTX *parent; + CRYPTO_EX_DATA ex_data; +} /* X509_STORE_CTX */ ; + +void X509_STORE_CTX_set_depth(X509_STORE_CTX *ctx, int depth); + +# define X509_STORE_CTX_set_app_data(ctx,data) \ + X509_STORE_CTX_set_ex_data(ctx,0,data) +# define X509_STORE_CTX_get_app_data(ctx) \ + X509_STORE_CTX_get_ex_data(ctx,0) + +# define X509_L_FILE_LOAD 1 +# define X509_L_ADD_DIR 2 + +# define X509_LOOKUP_load_file(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_FILE_LOAD,(name),(long)(type),NULL) + +# define X509_LOOKUP_add_dir(x,name,type) \ + X509_LOOKUP_ctrl((x),X509_L_ADD_DIR,(name),(long)(type),NULL) + +# define X509_V_OK 0 +# define X509_V_ERR_UNSPECIFIED 1 + +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT 2 +# define X509_V_ERR_UNABLE_TO_GET_CRL 3 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE 4 +# define X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE 5 +# define X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY 6 +# define X509_V_ERR_CERT_SIGNATURE_FAILURE 7 +# define X509_V_ERR_CRL_SIGNATURE_FAILURE 8 +# define X509_V_ERR_CERT_NOT_YET_VALID 9 +# define X509_V_ERR_CERT_HAS_EXPIRED 10 +# define X509_V_ERR_CRL_NOT_YET_VALID 11 +# define X509_V_ERR_CRL_HAS_EXPIRED 12 +# define X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD 13 +# define X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD 14 +# define X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD 15 +# define X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD 16 +# define X509_V_ERR_OUT_OF_MEM 17 +# define X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT 18 +# define X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN 19 +# define X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY 20 +# define X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE 21 +# define X509_V_ERR_CERT_CHAIN_TOO_LONG 22 +# define X509_V_ERR_CERT_REVOKED 23 +# define X509_V_ERR_INVALID_CA 24 +# define X509_V_ERR_PATH_LENGTH_EXCEEDED 25 +# define X509_V_ERR_INVALID_PURPOSE 26 +# define X509_V_ERR_CERT_UNTRUSTED 27 +# define X509_V_ERR_CERT_REJECTED 28 +/* These are 'informational' when looking for issuer cert */ +# define X509_V_ERR_SUBJECT_ISSUER_MISMATCH 29 +# define X509_V_ERR_AKID_SKID_MISMATCH 30 +# define X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH 31 +# define X509_V_ERR_KEYUSAGE_NO_CERTSIGN 32 + +# define X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER 33 +# define X509_V_ERR_UNHANDLED_CRITICAL_EXTENSION 34 +# define X509_V_ERR_KEYUSAGE_NO_CRL_SIGN 35 +# define X509_V_ERR_UNHANDLED_CRITICAL_CRL_EXTENSION 36 +# define X509_V_ERR_INVALID_NON_CA 37 +# define X509_V_ERR_PROXY_PATH_LENGTH_EXCEEDED 38 +# define X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE 39 +# define X509_V_ERR_PROXY_CERTIFICATES_NOT_ALLOWED 40 + +# define X509_V_ERR_INVALID_EXTENSION 41 +# define X509_V_ERR_INVALID_POLICY_EXTENSION 42 +# define X509_V_ERR_NO_EXPLICIT_POLICY 43 +# define X509_V_ERR_DIFFERENT_CRL_SCOPE 44 +# define X509_V_ERR_UNSUPPORTED_EXTENSION_FEATURE 45 + +# define X509_V_ERR_UNNESTED_RESOURCE 46 + +# define X509_V_ERR_PERMITTED_VIOLATION 47 +# define X509_V_ERR_EXCLUDED_VIOLATION 48 +# define X509_V_ERR_SUBTREE_MINMAX 49 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE 51 +# define X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX 52 +# define X509_V_ERR_UNSUPPORTED_NAME_SYNTAX 53 +# define X509_V_ERR_CRL_PATH_VALIDATION_ERROR 54 + +/* The application is not happy */ +# define X509_V_ERR_APPLICATION_VERIFICATION 50 + +/* Certificate verify flags */ + +/* Send issuer+subject checks to verify_cb */ +# define X509_V_FLAG_CB_ISSUER_CHECK 0x1 +/* Use check time instead of current time */ +# define X509_V_FLAG_USE_CHECK_TIME 0x2 +/* Lookup CRLs */ +# define X509_V_FLAG_CRL_CHECK 0x4 +/* Lookup CRLs for whole chain */ +# define X509_V_FLAG_CRL_CHECK_ALL 0x8 +/* Ignore unhandled critical extensions */ +# define X509_V_FLAG_IGNORE_CRITICAL 0x10 +/* Disable workarounds for broken certificates */ +# define X509_V_FLAG_X509_STRICT 0x20 +/* Enable proxy certificate validation */ +# define X509_V_FLAG_ALLOW_PROXY_CERTS 0x40 +/* Enable policy checking */ +# define X509_V_FLAG_POLICY_CHECK 0x80 +/* Policy variable require-explicit-policy */ +# define X509_V_FLAG_EXPLICIT_POLICY 0x100 +/* Policy variable inhibit-any-policy */ +# define X509_V_FLAG_INHIBIT_ANY 0x200 +/* Policy variable inhibit-policy-mapping */ +# define X509_V_FLAG_INHIBIT_MAP 0x400 +/* Notify callback that policy is OK */ +# define X509_V_FLAG_NOTIFY_POLICY 0x800 +/* Extended CRL features such as indirect CRLs, alternate CRL signing keys */ +# define X509_V_FLAG_EXTENDED_CRL_SUPPORT 0x1000 +/* Delta CRL support */ +# define X509_V_FLAG_USE_DELTAS 0x2000 +/* Check selfsigned CA signature */ +# define X509_V_FLAG_CHECK_SS_SIGNATURE 0x4000 +/* + * If the initial chain is not trusted, do not attempt to build an alternative + * chain. Alternate chain checking was introduced in 1.0.1n/1.0.2b. Setting + * this flag will force the behaviour to match that of previous versions. + */ +# define X509_V_FLAG_NO_ALT_CHAINS 0x100000 + +# define X509_VP_FLAG_DEFAULT 0x1 +# define X509_VP_FLAG_OVERWRITE 0x2 +# define X509_VP_FLAG_RESET_FLAGS 0x4 +# define X509_VP_FLAG_LOCKED 0x8 +# define X509_VP_FLAG_ONCE 0x10 + +/* Internal use: mask of policy related options */ +# define X509_V_FLAG_POLICY_MASK (X509_V_FLAG_POLICY_CHECK \ + | X509_V_FLAG_EXPLICIT_POLICY \ + | X509_V_FLAG_INHIBIT_ANY \ + | X509_V_FLAG_INHIBIT_MAP) + +int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h, + int type, X509_NAME *name); +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x); +void X509_OBJECT_up_ref_count(X509_OBJECT *a); +void X509_OBJECT_free_contents(X509_OBJECT *a); +X509_STORE *X509_STORE_new(void); +void X509_STORE_free(X509_STORE *v); + +STACK_OF(X509) *X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); +STACK_OF(X509_CRL) *X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); +int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); +int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); +int X509_STORE_set_trust(X509_STORE *ctx, int trust); +int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); + +void X509_STORE_set_verify_cb(X509_STORE *ctx, + int (*verify_cb) (int, X509_STORE_CTX *)); + +X509_STORE_CTX *X509_STORE_CTX_new(void); + +int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx); +int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); +void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + +X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); + +X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); +X509_LOOKUP_METHOD *X509_LOOKUP_file(void); + +int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); +int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + +int X509_STORE_get_by_subject(X509_STORE_CTX *vs, int type, X509_NAME *name, + X509_OBJECT *ret); + +int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +# ifndef OPENSSL_NO_STDIO +int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); +int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); +# endif + +X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +void X509_LOOKUP_free(X509_LOOKUP *ctx); +int X509_LOOKUP_init(X509_LOOKUP *ctx); +int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); +int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret); +int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, + X509_OBJECT *ret); +int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, int len, + X509_OBJECT *ret); +int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +# ifndef OPENSSL_NO_STDIO +int X509_STORE_load_locations(X509_STORE *ctx, + const char *file, const char *dir); +int X509_STORE_set_default_paths(X509_STORE *ctx); +# endif + +int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); +int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx, int idx, void *data); +void *X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx, int idx); +int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx, int s); +int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); +X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); +X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); +STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set_cert(X509_STORE_CTX *c, X509 *x); +void X509_STORE_CTX_set_chain(X509_STORE_CTX *c, STACK_OF(X509) *sk); +void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c, STACK_OF(X509_CRL) *sk); +int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); +int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust); +void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); +void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t); +void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb) (int, X509_STORE_CTX *)); + +X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx); +int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); + +X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); +void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); +int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + +/* X509_VERIFY_PARAM functions */ + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies); +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); +void X509_VERIFY_PARAM_table_cleanup(void); + +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags); + +void X509_policy_tree_free(X509_POLICY_TREE *tree); + +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); +X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, + int i); + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const + X509_POLICY_TREE + *tree); + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const + X509_POLICY_TREE + *tree); + +int X509_policy_level_node_count(X509_POLICY_LEVEL *level); + +X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, + int i); + +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node); + +STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const + X509_POLICY_NODE + *node); +const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE + *node); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/x509/x509_vpm.c b/libs/openssl/crypto/x509/x509_vpm.c new file mode 100644 index 00000000..6b0bf8a6 --- /dev/null +++ b/libs/openssl/crypto/x509/x509_vpm.c @@ -0,0 +1,433 @@ +/* x509_vpm.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#include "cryptlib.h" +#include +#include +#include +#include +#include + +/* X509_VERIFY_PARAM functions */ + +static void x509_verify_param_zero(X509_VERIFY_PARAM *param) +{ + if (!param) + return; + param->name = NULL; + param->purpose = 0; + param->trust = 0; + /* + * param->inh_flags = X509_VP_FLAG_DEFAULT; + */ + param->inh_flags = 0; + param->flags = 0; + param->depth = -1; + if (param->policies) { + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + param->policies = NULL; + } +} + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) +{ + X509_VERIFY_PARAM *param; + param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM)); + if (!param) + return NULL; + memset(param, 0, sizeof(X509_VERIFY_PARAM)); + x509_verify_param_zero(param); + return param; +} + +void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param) +{ + if (param == NULL) + return; + x509_verify_param_zero(param); + OPENSSL_free(param); +} + +/*- + * This function determines how parameters are "inherited" from one structure + * to another. There are several different ways this can happen. + * + * 1. If a child structure needs to have its values initialized from a parent + * they are simply copied across. For example SSL_CTX copied to SSL. + * 2. If the structure should take on values only if they are currently unset. + * For example the values in an SSL structure will take appropriate value + * for SSL servers or clients but only if the application has not set new + * ones. + * + * The "inh_flags" field determines how this function behaves. + * + * Normally any values which are set in the default are not copied from the + * destination and verify flags are ORed together. + * + * If X509_VP_FLAG_DEFAULT is set then anything set in the source is copied + * to the destination. Effectively the values in "to" become default values + * which will be used only if nothing new is set in "from". + * + * If X509_VP_FLAG_OVERWRITE is set then all value are copied across whether + * they are set or not. Flags is still Ored though. + * + * If X509_VP_FLAG_RESET_FLAGS is set then the flags value is copied instead + * of ORed. + * + * If X509_VP_FLAG_LOCKED is set then no values are copied. + * + * If X509_VP_FLAG_ONCE is set then the current inh_flags setting is zeroed + * after the next call. + */ + +/* Macro to test if a field should be copied from src to dest */ + +#define test_x509_verify_param_copy(field, def) \ + (to_overwrite || \ + ((src->field != def) && (to_default || (dest->field == def)))) + +/* Macro to test and copy a field if necessary */ + +#define x509_verify_param_copy(field, def) \ + if (test_x509_verify_param_copy(field, def)) \ + dest->field = src->field + +int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *dest, + const X509_VERIFY_PARAM *src) +{ + unsigned long inh_flags; + int to_default, to_overwrite; + if (!src) + return 1; + inh_flags = dest->inh_flags | src->inh_flags; + + if (inh_flags & X509_VP_FLAG_ONCE) + dest->inh_flags = 0; + + if (inh_flags & X509_VP_FLAG_LOCKED) + return 1; + + if (inh_flags & X509_VP_FLAG_DEFAULT) + to_default = 1; + else + to_default = 0; + + if (inh_flags & X509_VP_FLAG_OVERWRITE) + to_overwrite = 1; + else + to_overwrite = 0; + + x509_verify_param_copy(purpose, 0); + x509_verify_param_copy(trust, 0); + x509_verify_param_copy(depth, -1); + + /* If overwrite or check time not set, copy across */ + + if (to_overwrite || !(dest->flags & X509_V_FLAG_USE_CHECK_TIME)) { + dest->check_time = src->check_time; + dest->flags &= ~X509_V_FLAG_USE_CHECK_TIME; + /* Don't need to copy flag: that is done below */ + } + + if (inh_flags & X509_VP_FLAG_RESET_FLAGS) + dest->flags = 0; + + dest->flags |= src->flags; + + if (test_x509_verify_param_copy(policies, NULL)) { + if (!X509_VERIFY_PARAM_set1_policies(dest, src->policies)) + return 0; + } + + return 1; +} + +int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from) +{ + unsigned long save_flags = to->inh_flags; + int ret; + to->inh_flags |= X509_VP_FLAG_DEFAULT; + ret = X509_VERIFY_PARAM_inherit(to, from); + to->inh_flags = save_flags; + return ret; +} + +int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name) +{ + if (param->name) + OPENSSL_free(param->name); + param->name = BUF_strdup(name); + if (param->name) + return 1; + return 0; +} + +int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags) +{ + param->flags |= flags; + if (flags & X509_V_FLAG_POLICY_MASK) + param->flags |= X509_V_FLAG_POLICY_CHECK; + return 1; +} + +int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags) +{ + param->flags &= ~flags; + return 1; +} + +unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param) +{ + return param->flags; +} + +int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose) +{ + return X509_PURPOSE_set(¶m->purpose, purpose); +} + +int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust) +{ + return X509_TRUST_set(¶m->trust, trust); +} + +void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth) +{ + param->depth = depth; +} + +void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t) +{ + param->check_time = t; + param->flags |= X509_V_FLAG_USE_CHECK_TIME; +} + +int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy) +{ + if (!param->policies) { + param->policies = sk_ASN1_OBJECT_new_null(); + if (!param->policies) + return 0; + } + if (!sk_ASN1_OBJECT_push(param->policies, policy)) + return 0; + return 1; +} + +int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies) +{ + int i; + ASN1_OBJECT *oid, *doid; + if (!param) + return 0; + if (param->policies) + sk_ASN1_OBJECT_pop_free(param->policies, ASN1_OBJECT_free); + + if (!policies) { + param->policies = NULL; + return 1; + } + + param->policies = sk_ASN1_OBJECT_new_null(); + if (!param->policies) + return 0; + + for (i = 0; i < sk_ASN1_OBJECT_num(policies); i++) { + oid = sk_ASN1_OBJECT_value(policies, i); + doid = OBJ_dup(oid); + if (!doid) + return 0; + if (!sk_ASN1_OBJECT_push(param->policies, doid)) { + ASN1_OBJECT_free(doid); + return 0; + } + } + param->flags |= X509_V_FLAG_POLICY_CHECK; + return 1; +} + +int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param) +{ + return param->depth; +} + +/* + * Default verify parameters: these are used for various applications and can + * be overridden by the user specified table. NB: the 'name' field *must* be + * in alphabetical order because it will be searched using OBJ_search. + */ + +static const X509_VERIFY_PARAM default_table[] = { + { + "default", /* X509 default parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + 0, /* purpose */ + 0, /* trust */ + 100, /* depth */ + NULL /* policies */ + }, + { + "pkcs7", /* S/MIME sign parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SMIME_SIGN, /* purpose */ + X509_TRUST_EMAIL, /* trust */ + -1, /* depth */ + NULL /* policies */ + }, + { + "smime_sign", /* S/MIME sign parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SMIME_SIGN, /* purpose */ + X509_TRUST_EMAIL, /* trust */ + -1, /* depth */ + NULL /* policies */ + }, + { + "ssl_client", /* SSL/TLS client parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SSL_CLIENT, /* purpose */ + X509_TRUST_SSL_CLIENT, /* trust */ + -1, /* depth */ + NULL /* policies */ + }, + { + "ssl_server", /* SSL/TLS server parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + X509_PURPOSE_SSL_SERVER, /* purpose */ + X509_TRUST_SSL_SERVER, /* trust */ + -1, /* depth */ + NULL /* policies */ + } +}; + +static STACK_OF(X509_VERIFY_PARAM) *param_table = NULL; + +static int table_cmp(const X509_VERIFY_PARAM *a, const X509_VERIFY_PARAM *b) +{ + return strcmp(a->name, b->name); +} + +DECLARE_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(X509_VERIFY_PARAM, X509_VERIFY_PARAM, table); + +static int param_cmp(const X509_VERIFY_PARAM *const *a, + const X509_VERIFY_PARAM *const *b) +{ + return strcmp((*a)->name, (*b)->name); +} + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) +{ + int idx; + X509_VERIFY_PARAM *ptmp; + if (!param_table) { + param_table = sk_X509_VERIFY_PARAM_new(param_cmp); + if (!param_table) + return 0; + } else { + idx = sk_X509_VERIFY_PARAM_find(param_table, param); + if (idx != -1) { + ptmp = sk_X509_VERIFY_PARAM_value(param_table, idx); + X509_VERIFY_PARAM_free(ptmp); + (void)sk_X509_VERIFY_PARAM_delete(param_table, idx); + } + } + if (!sk_X509_VERIFY_PARAM_push(param_table, param)) + return 0; + return 1; +} + +const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name) +{ + int idx; + X509_VERIFY_PARAM pm; + + pm.name = (char *)name; + if (param_table) { + idx = sk_X509_VERIFY_PARAM_find(param_table, &pm); + if (idx != -1) + return sk_X509_VERIFY_PARAM_value(param_table, idx); + } + return OBJ_bsearch_table(&pm, default_table, + sizeof(default_table) / + sizeof(X509_VERIFY_PARAM)); +} + +void X509_VERIFY_PARAM_table_cleanup(void) +{ + if (param_table) + sk_X509_VERIFY_PARAM_pop_free(param_table, X509_VERIFY_PARAM_free); + param_table = NULL; +} diff --git a/libs/openssl/crypto/x509/x509cset.c b/libs/openssl/crypto/x509/x509cset.c new file mode 100644 index 00000000..24ca35b5 --- /dev/null +++ b/libs/openssl/crypto/x509/x509cset.c @@ -0,0 +1,167 @@ +/* crypto/x509/x509cset.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +int X509_CRL_set_version(X509_CRL *x, long version) +{ + if (x == NULL) + return (0); + if (x->crl->version == NULL) { + if ((x->crl->version = M_ASN1_INTEGER_new()) == NULL) + return (0); + } + return (ASN1_INTEGER_set(x->crl->version, version)); +} + +int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name) +{ + if ((x == NULL) || (x->crl == NULL)) + return (0); + return (X509_NAME_set(&x->crl->issuer, name)); +} + +int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL) + return (0); + in = x->crl->lastUpdate; + if (in != tm) { + in = M_ASN1_TIME_dup(tm); + if (in != NULL) { + M_ASN1_TIME_free(x->crl->lastUpdate); + x->crl->lastUpdate = in; + } + } + return (in != NULL); +} + +int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL) + return (0); + in = x->crl->nextUpdate; + if (in != tm) { + in = M_ASN1_TIME_dup(tm); + if (in != NULL) { + M_ASN1_TIME_free(x->crl->nextUpdate); + x->crl->nextUpdate = in; + } + } + return (in != NULL); +} + +int X509_CRL_sort(X509_CRL *c) +{ + int i; + X509_REVOKED *r; + /* + * sort the data so it will be written in serial number order + */ + sk_X509_REVOKED_sort(c->crl->revoked); + for (i = 0; i < sk_X509_REVOKED_num(c->crl->revoked); i++) { + r = sk_X509_REVOKED_value(c->crl->revoked, i); + r->sequence = i; + } + c->crl->enc.modified = 1; + return 1; +} + +int X509_REVOKED_set_revocationDate(X509_REVOKED *x, ASN1_TIME *tm) +{ + ASN1_TIME *in; + + if (x == NULL) + return (0); + in = x->revocationDate; + if (in != tm) { + in = M_ASN1_TIME_dup(tm); + if (in != NULL) { + M_ASN1_TIME_free(x->revocationDate); + x->revocationDate = in; + } + } + return (in != NULL); +} + +int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial) +{ + ASN1_INTEGER *in; + + if (x == NULL) + return (0); + in = x->serialNumber; + if (in != serial) { + in = M_ASN1_INTEGER_dup(serial); + if (in != NULL) { + M_ASN1_INTEGER_free(x->serialNumber); + x->serialNumber = in; + } + } + return (in != NULL); +} diff --git a/libs/openssl/crypto/x509/x509name.c b/libs/openssl/crypto/x509/x509name.c new file mode 100644 index 00000000..6ea601f9 --- /dev/null +++ b/libs/openssl/crypto/x509/x509name.c @@ -0,0 +1,397 @@ +/* crypto/x509/x509name.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include + +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-1); + return (X509_NAME_get_text_by_OBJ(name, obj, buf, len)); +} + +int X509_NAME_get_text_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, char *buf, + int len) +{ + int i; + ASN1_STRING *data; + + i = X509_NAME_get_index_by_OBJ(name, obj, -1); + if (i < 0) + return (-1); + data = X509_NAME_ENTRY_get_data(X509_NAME_get_entry(name, i)); + i = (data->length > (len - 1)) ? (len - 1) : data->length; + if (buf == NULL) + return (data->length); + memcpy(buf, data->data, i); + buf[i] = '\0'; + return (i); +} + +int X509_NAME_entry_count(X509_NAME *name) +{ + if (name == NULL) + return (0); + return (sk_X509_NAME_ENTRY_num(name->entries)); +} + +int X509_NAME_get_index_by_NID(X509_NAME *name, int nid, int lastpos) +{ + ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) + return (-2); + return (X509_NAME_get_index_by_OBJ(name, obj, lastpos)); +} + +/* NOTE: you should be passsing -1, not 0 as lastpos */ +int X509_NAME_get_index_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int lastpos) +{ + int n; + X509_NAME_ENTRY *ne; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL) + return (-1); + if (lastpos < 0) + lastpos = -1; + sk = name->entries; + n = sk_X509_NAME_ENTRY_num(sk); + for (lastpos++; lastpos < n; lastpos++) { + ne = sk_X509_NAME_ENTRY_value(sk, lastpos); + if (OBJ_cmp(ne->object, obj) == 0) + return (lastpos); + } + return (-1); +} + +X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc) +{ + if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc + || loc < 0) + return (NULL); + else + return (sk_X509_NAME_ENTRY_value(name->entries, loc)); +} + +X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc) +{ + X509_NAME_ENTRY *ret; + int i, n, set_prev, set_next; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL || sk_X509_NAME_ENTRY_num(name->entries) <= loc + || loc < 0) + return (NULL); + sk = name->entries; + ret = sk_X509_NAME_ENTRY_delete(sk, loc); + n = sk_X509_NAME_ENTRY_num(sk); + name->modified = 1; + if (loc == n) + return (ret); + + /* else we need to fixup the set field */ + if (loc != 0) + set_prev = (sk_X509_NAME_ENTRY_value(sk, loc - 1))->set; + else + set_prev = ret->set - 1; + set_next = sk_X509_NAME_ENTRY_value(sk, loc)->set; + + /*- + * set_prev is the previous set + * set is the current set + * set_next is the following + * prev 1 1 1 1 1 1 1 1 + * set 1 1 2 2 + * next 1 1 2 2 2 2 3 2 + * so basically only if prev and next differ by 2, then + * re-number down by 1 + */ + if (set_prev + 1 < set_next) + for (i = loc; i < n; i++) + sk_X509_NAME_ENTRY_value(sk, i)->set--; + return (ret); +} + +int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, + unsigned char *bytes, int len, int loc, + int set) +{ + X509_NAME_ENTRY *ne; + int ret; + ne = X509_NAME_ENTRY_create_by_OBJ(NULL, obj, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + unsigned char *bytes, int len, int loc, + int set) +{ + X509_NAME_ENTRY *ne; + int ret; + ne = X509_NAME_ENTRY_create_by_NID(NULL, nid, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +int X509_NAME_add_entry_by_txt(X509_NAME *name, const char *field, int type, + const unsigned char *bytes, int len, int loc, + int set) +{ + X509_NAME_ENTRY *ne; + int ret; + ne = X509_NAME_ENTRY_create_by_txt(NULL, field, type, bytes, len); + if (!ne) + return 0; + ret = X509_NAME_add_entry(name, ne, loc, set); + X509_NAME_ENTRY_free(ne); + return ret; +} + +/* + * if set is -1, append to previous set, 0 'a new one', and 1, prepend to the + * guy we are about to stomp on. + */ +int X509_NAME_add_entry(X509_NAME *name, X509_NAME_ENTRY *ne, int loc, + int set) +{ + X509_NAME_ENTRY *new_name = NULL; + int n, i, inc; + STACK_OF(X509_NAME_ENTRY) *sk; + + if (name == NULL) + return (0); + sk = name->entries; + n = sk_X509_NAME_ENTRY_num(sk); + if (loc > n) + loc = n; + else if (loc < 0) + loc = n; + + name->modified = 1; + + if (set == -1) { + if (loc == 0) { + set = 0; + inc = 1; + } else { + set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set; + inc = 0; + } + } else { /* if (set >= 0) */ + + if (loc >= n) { + if (loc != 0) + set = sk_X509_NAME_ENTRY_value(sk, loc - 1)->set + 1; + else + set = 0; + } else + set = sk_X509_NAME_ENTRY_value(sk, loc)->set; + inc = (set == 0) ? 1 : 0; + } + + if ((new_name = X509_NAME_ENTRY_dup(ne)) == NULL) + goto err; + new_name->set = set; + if (!sk_X509_NAME_ENTRY_insert(sk, new_name, loc)) { + X509err(X509_F_X509_NAME_ADD_ENTRY, ERR_R_MALLOC_FAILURE); + goto err; + } + if (inc) { + n = sk_X509_NAME_ENTRY_num(sk); + for (i = loc + 1; i < n; i++) + sk_X509_NAME_ENTRY_value(sk, i - 1)->set += 1; + } + return (1); + err: + if (new_name != NULL) + X509_NAME_ENTRY_free(new_name); + return (0); +} + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, + const unsigned char *bytes, + int len) +{ + ASN1_OBJECT *obj; + X509_NAME_ENTRY *nentry; + + obj = OBJ_txt2obj(field, 0); + if (obj == NULL) { + X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_TXT, + X509_R_INVALID_FIELD_NAME); + ERR_add_error_data(2, "name=", field); + return (NULL); + } + nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nentry; +} + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type, unsigned char *bytes, + int len) +{ + ASN1_OBJECT *obj; + X509_NAME_ENTRY *nentry; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + X509err(X509_F_X509_NAME_ENTRY_CREATE_BY_NID, X509_R_UNKNOWN_NID); + return (NULL); + } + nentry = X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); + ASN1_OBJECT_free(obj); + return nentry; +} + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + ASN1_OBJECT *obj, int type, + const unsigned char *bytes, + int len) +{ + X509_NAME_ENTRY *ret; + + if ((ne == NULL) || (*ne == NULL)) { + if ((ret = X509_NAME_ENTRY_new()) == NULL) + return (NULL); + } else + ret = *ne; + + if (!X509_NAME_ENTRY_set_object(ret, obj)) + goto err; + if (!X509_NAME_ENTRY_set_data(ret, type, bytes, len)) + goto err; + + if ((ne != NULL) && (*ne == NULL)) + *ne = ret; + return (ret); + err: + if ((ne == NULL) || (ret != *ne)) + X509_NAME_ENTRY_free(ret); + return (NULL); +} + +int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, ASN1_OBJECT *obj) +{ + if ((ne == NULL) || (obj == NULL)) { + X509err(X509_F_X509_NAME_ENTRY_SET_OBJECT, + ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + ASN1_OBJECT_free(ne->object); + ne->object = OBJ_dup(obj); + return ((ne->object == NULL) ? 0 : 1); +} + +int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len) +{ + int i; + + if ((ne == NULL) || ((bytes == NULL) && (len != 0))) + return (0); + if ((type > 0) && (type & MBSTRING_FLAG)) + return ASN1_STRING_set_by_NID(&ne->value, bytes, + len, type, + OBJ_obj2nid(ne->object)) ? 1 : 0; + if (len < 0) + len = strlen((const char *)bytes); + i = ASN1_STRING_set(ne->value, bytes, len); + if (!i) + return (0); + if (type != V_ASN1_UNDEF) { + if (type == V_ASN1_APP_CHOOSE) + ne->value->type = ASN1_PRINTABLE_type(bytes, len); + else + ne->value->type = type; + } + return (1); +} + +ASN1_OBJECT *X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne) +{ + if (ne == NULL) + return (NULL); + return (ne->object); +} + +ASN1_STRING *X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne) +{ + if (ne == NULL) + return (NULL); + return (ne->value); +} diff --git a/libs/openssl/crypto/x509/x509rset.c b/libs/openssl/crypto/x509/x509rset.c new file mode 100644 index 00000000..80e273e6 --- /dev/null +++ b/libs/openssl/crypto/x509/x509rset.c @@ -0,0 +1,85 @@ +/* crypto/x509/x509rset.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +int X509_REQ_set_version(X509_REQ *x, long version) +{ + if (x == NULL) + return (0); + return (ASN1_INTEGER_set(x->req_info->version, version)); +} + +int X509_REQ_set_subject_name(X509_REQ *x, X509_NAME *name) +{ + if ((x == NULL) || (x->req_info == NULL)) + return (0); + return (X509_NAME_set(&x->req_info->subject, name)); +} + +int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->req_info == NULL)) + return (0); + return (X509_PUBKEY_set(&x->req_info->pubkey, pkey)); +} diff --git a/libs/openssl/crypto/x509/x509spki.c b/libs/openssl/crypto/x509/x509spki.c new file mode 100644 index 00000000..2df84ead --- /dev/null +++ b/libs/openssl/crypto/x509/x509spki.c @@ -0,0 +1,123 @@ +/* x509spki.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey) +{ + if ((x == NULL) || (x->spkac == NULL)) + return (0); + return (X509_PUBKEY_set(&(x->spkac->pubkey), pkey)); +} + +EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x) +{ + if ((x == NULL) || (x->spkac == NULL)) + return (NULL); + return (X509_PUBKEY_get(x->spkac->pubkey)); +} + +/* Load a Netscape SPKI from a base64 encoded string */ + +NETSCAPE_SPKI *NETSCAPE_SPKI_b64_decode(const char *str, int len) +{ + unsigned char *spki_der; + const unsigned char *p; + int spki_len; + NETSCAPE_SPKI *spki; + if (len <= 0) + len = strlen(str); + if (!(spki_der = OPENSSL_malloc(len + 1))) { + X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE); + return NULL; + } + spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len); + if (spki_len < 0) { + X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, X509_R_BASE64_DECODE_ERROR); + OPENSSL_free(spki_der); + return NULL; + } + p = spki_der; + spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len); + OPENSSL_free(spki_der); + return spki; +} + +/* Generate a base64 encoded string from an SPKI */ + +char *NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki) +{ + unsigned char *der_spki, *p; + char *b64_str; + int der_len; + der_len = i2d_NETSCAPE_SPKI(spki, NULL); + der_spki = OPENSSL_malloc(der_len); + b64_str = OPENSSL_malloc(der_len * 2); + if (!der_spki || !b64_str) { + X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE); + return NULL; + } + p = der_spki; + i2d_NETSCAPE_SPKI(spki, &p); + EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len); + OPENSSL_free(der_spki); + return b64_str; +} diff --git a/libs/openssl/crypto/x509/x509type.c b/libs/openssl/crypto/x509/x509type.c new file mode 100644 index 00000000..9219f753 --- /dev/null +++ b/libs/openssl/crypto/x509/x509type.c @@ -0,0 +1,127 @@ +/* crypto/x509/x509type.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +int X509_certificate_type(X509 *x, EVP_PKEY *pkey) +{ + EVP_PKEY *pk; + int ret = 0, i; + + if (x == NULL) + return (0); + + if (pkey == NULL) + pk = X509_get_pubkey(x); + else + pk = pkey; + + if (pk == NULL) + return (0); + + switch (pk->type) { + case EVP_PKEY_RSA: + ret = EVP_PK_RSA | EVP_PKT_SIGN; +/* if (!sign only extension) */ + ret |= EVP_PKT_ENC; + break; + case EVP_PKEY_DSA: + ret = EVP_PK_DSA | EVP_PKT_SIGN; + break; + case EVP_PKEY_EC: + ret = EVP_PK_EC | EVP_PKT_SIGN | EVP_PKT_EXCH; + break; + case EVP_PKEY_DH: + ret = EVP_PK_DH | EVP_PKT_EXCH; + break; + case NID_id_GostR3410_94: + case NID_id_GostR3410_2001: + ret = EVP_PKT_EXCH | EVP_PKT_SIGN; + break; + default: + break; + } + + i = OBJ_obj2nid(x->sig_alg->algorithm); + if (i && OBJ_find_sigid_algs(i, NULL, &i)) { + + switch (i) { + case NID_rsaEncryption: + case NID_rsa: + ret |= EVP_PKS_RSA; + break; + case NID_dsa: + case NID_dsa_2: + ret |= EVP_PKS_DSA; + break; + case NID_X9_62_id_ecPublicKey: + ret |= EVP_PKS_EC; + break; + default: + break; + } + } + + if (pkey == NULL) + EVP_PKEY_free(pk); + return (ret); +} diff --git a/libs/openssl/crypto/x509/x_all.c b/libs/openssl/crypto/x509/x_all.c new file mode 100644 index 00000000..43152e93 --- /dev/null +++ b/libs/openssl/crypto/x509/x_all.c @@ -0,0 +1,544 @@ +/* crypto/x509/x_all.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#ifndef OPENSSL_NO_RSA +# include +#endif +#ifndef OPENSSL_NO_DSA +# include +#endif + +int X509_verify(X509 *a, EVP_PKEY *r) +{ + if (X509_ALGOR_cmp(a->sig_alg, a->cert_info->signature)) + return 0; + return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), a->sig_alg, + a->signature, a->cert_info, r)); +} + +int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r) +{ + return (ASN1_item_verify(ASN1_ITEM_rptr(X509_REQ_INFO), + a->sig_alg, a->signature, a->req_info, r)); +} + +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r) +{ + return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), + a->sig_algor, a->signature, a->spkac, r)); +} + +int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + x->cert_info->enc.modified = 1; + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CINF), x->cert_info->signature, + x->sig_alg, x->signature, x->cert_info, pkey, md)); +} + +int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx) +{ + x->cert_info->enc.modified = 1; + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CINF), + x->cert_info->signature, + x->sig_alg, x->signature, x->cert_info, ctx); +} + +int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_REQ_INFO), x->sig_alg, NULL, + x->signature, x->req_info, pkey, md)); +} + +int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx) +{ + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_REQ_INFO), + x->sig_alg, NULL, x->signature, x->req_info, + ctx); +} + +int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + x->crl->enc.modified = 1; + return (ASN1_item_sign(ASN1_ITEM_rptr(X509_CRL_INFO), x->crl->sig_alg, + x->sig_alg, x->signature, x->crl, pkey, md)); +} + +int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx) +{ + x->crl->enc.modified = 1; + return ASN1_item_sign_ctx(ASN1_ITEM_rptr(X509_CRL_INFO), + x->crl->sig_alg, x->sig_alg, x->signature, + x->crl, ctx); +} + +int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md) +{ + return (ASN1_item_sign(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, NULL, + x->signature, x->spkac, pkey, md)); +} + +#ifndef OPENSSL_NO_FP_API +X509 *d2i_X509_fp(FILE *fp, X509 **x509) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509), fp, x509); +} + +int i2d_X509_fp(FILE *fp, X509 *x509) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509), fp, x509); +} +#endif + +X509 *d2i_X509_bio(BIO *bp, X509 **x509) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509), bp, x509); +} + +int i2d_X509_bio(BIO *bp, X509 *x509) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509), bp, x509); +} + +#ifndef OPENSSL_NO_FP_API +X509_CRL *d2i_X509_CRL_fp(FILE *fp, X509_CRL **crl) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); +} + +int i2d_X509_CRL_fp(FILE *fp, X509_CRL *crl) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_CRL), fp, crl); +} +#endif + +X509_CRL *d2i_X509_CRL_bio(BIO *bp, X509_CRL **crl) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); +} + +int i2d_X509_CRL_bio(BIO *bp, X509_CRL *crl) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_CRL), bp, crl); +} + +#ifndef OPENSSL_NO_FP_API +PKCS7 *d2i_PKCS7_fp(FILE *fp, PKCS7 **p7) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); +} + +int i2d_PKCS7_fp(FILE *fp, PKCS7 *p7) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(PKCS7), fp, p7); +} +#endif + +PKCS7 *d2i_PKCS7_bio(BIO *bp, PKCS7 **p7) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); +} + +int i2d_PKCS7_bio(BIO *bp, PKCS7 *p7) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(PKCS7), bp, p7); +} + +#ifndef OPENSSL_NO_FP_API +X509_REQ *d2i_X509_REQ_fp(FILE *fp, X509_REQ **req) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); +} + +int i2d_X509_REQ_fp(FILE *fp, X509_REQ *req) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(X509_REQ), fp, req); +} +#endif + +X509_REQ *d2i_X509_REQ_bio(BIO *bp, X509_REQ **req) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); +} + +int i2d_X509_REQ_bio(BIO *bp, X509_REQ *req) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(X509_REQ), bp, req); +} + +#ifndef OPENSSL_NO_RSA + +# ifndef OPENSSL_NO_FP_API +RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa); +} + +int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPrivateKey), fp, rsa); +} + +RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa) +{ + return ASN1_item_d2i_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa); +} + +RSA *d2i_RSA_PUBKEY_fp(FILE *fp, RSA **rsa) +{ + return ASN1_d2i_fp((void *(*)(void)) + RSA_new, (D2I_OF(void)) d2i_RSA_PUBKEY, fp, + (void **)rsa); +} + +int i2d_RSAPublicKey_fp(FILE *fp, RSA *rsa) +{ + return ASN1_item_i2d_fp(ASN1_ITEM_rptr(RSAPublicKey), fp, rsa); +} + +int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa) +{ + return ASN1_i2d_fp((I2D_OF(void))i2d_RSA_PUBKEY, fp, rsa); +} +# endif + +RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa); +} + +int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPrivateKey), bp, rsa); +} + +RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa) +{ + return ASN1_item_d2i_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa); +} + +RSA *d2i_RSA_PUBKEY_bio(BIO *bp, RSA **rsa) +{ + return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSA_PUBKEY, bp, rsa); +} + +int i2d_RSAPublicKey_bio(BIO *bp, RSA *rsa) +{ + return ASN1_item_i2d_bio(ASN1_ITEM_rptr(RSAPublicKey), bp, rsa); +} + +int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa) +{ + return ASN1_i2d_bio_of(RSA, i2d_RSA_PUBKEY, bp, rsa); +} +#endif + +#ifndef OPENSSL_NO_DSA +# ifndef OPENSSL_NO_FP_API +DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa) +{ + return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSAPrivateKey, fp, dsa); +} + +int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa) +{ + return ASN1_i2d_fp_of_const(DSA, i2d_DSAPrivateKey, fp, dsa); +} + +DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa) +{ + return ASN1_d2i_fp_of(DSA, DSA_new, d2i_DSA_PUBKEY, fp, dsa); +} + +int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa) +{ + return ASN1_i2d_fp_of(DSA, i2d_DSA_PUBKEY, fp, dsa); +} +# endif + +DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa) +{ + return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSAPrivateKey, bp, dsa); +} + +int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa) +{ + return ASN1_i2d_bio_of_const(DSA, i2d_DSAPrivateKey, bp, dsa); +} + +DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa) +{ + return ASN1_d2i_bio_of(DSA, DSA_new, d2i_DSA_PUBKEY, bp, dsa); +} + +int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa) +{ + return ASN1_i2d_bio_of(DSA, i2d_DSA_PUBKEY, bp, dsa); +} + +#endif + +#ifndef OPENSSL_NO_EC +# ifndef OPENSSL_NO_FP_API +EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey) +{ + return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, fp, eckey); +} + +int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey) +{ + return ASN1_i2d_fp_of(EC_KEY, i2d_EC_PUBKEY, fp, eckey); +} + +EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey) +{ + return ASN1_d2i_fp_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, fp, eckey); +} + +int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey) +{ + return ASN1_i2d_fp_of(EC_KEY, i2d_ECPrivateKey, fp, eckey); +} +# endif +EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey) +{ + return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_EC_PUBKEY, bp, eckey); +} + +int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *ecdsa) +{ + return ASN1_i2d_bio_of(EC_KEY, i2d_EC_PUBKEY, bp, ecdsa); +} + +EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey) +{ + return ASN1_d2i_bio_of(EC_KEY, EC_KEY_new, d2i_ECPrivateKey, bp, eckey); +} + +int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey) +{ + return ASN1_i2d_bio_of(EC_KEY, i2d_ECPrivateKey, bp, eckey); +} +#endif + +int X509_pubkey_digest(const X509 *data, const EVP_MD *type, + unsigned char *md, unsigned int *len) +{ + ASN1_BIT_STRING *key; + key = X509_get0_pubkey_bitstr(data); + if (!key) + return 0; + return EVP_Digest(key->data, key->length, md, len, type, NULL); +} + +int X509_digest(const X509 *data, const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + return (ASN1_item_digest + (ASN1_ITEM_rptr(X509), type, (char *)data, md, len)); +} + +int X509_CRL_digest(const X509_CRL *data, const EVP_MD *type, + unsigned char *md, unsigned int *len) +{ + return (ASN1_item_digest + (ASN1_ITEM_rptr(X509_CRL), type, (char *)data, md, len)); +} + +int X509_REQ_digest(const X509_REQ *data, const EVP_MD *type, + unsigned char *md, unsigned int *len) +{ + return (ASN1_item_digest + (ASN1_ITEM_rptr(X509_REQ), type, (char *)data, md, len)); +} + +int X509_NAME_digest(const X509_NAME *data, const EVP_MD *type, + unsigned char *md, unsigned int *len) +{ + return (ASN1_item_digest + (ASN1_ITEM_rptr(X509_NAME), type, (char *)data, md, len)); +} + +int PKCS7_ISSUER_AND_SERIAL_digest(PKCS7_ISSUER_AND_SERIAL *data, + const EVP_MD *type, unsigned char *md, + unsigned int *len) +{ + return (ASN1_item_digest(ASN1_ITEM_rptr(PKCS7_ISSUER_AND_SERIAL), type, + (char *)data, md, len)); +} + +#ifndef OPENSSL_NO_FP_API +X509_SIG *d2i_PKCS8_fp(FILE *fp, X509_SIG **p8) +{ + return ASN1_d2i_fp_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, fp, p8); +} + +int i2d_PKCS8_fp(FILE *fp, X509_SIG *p8) +{ + return ASN1_i2d_fp_of(X509_SIG, i2d_X509_SIG, fp, p8); +} +#endif + +X509_SIG *d2i_PKCS8_bio(BIO *bp, X509_SIG **p8) +{ + return ASN1_d2i_bio_of(X509_SIG, X509_SIG_new, d2i_X509_SIG, bp, p8); +} + +int i2d_PKCS8_bio(BIO *bp, X509_SIG *p8) +{ + return ASN1_i2d_bio_of(X509_SIG, i2d_X509_SIG, bp, p8); +} + +#ifndef OPENSSL_NO_FP_API +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf) +{ + return ASN1_d2i_fp_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new, + d2i_PKCS8_PRIV_KEY_INFO, fp, p8inf); +} + +int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, PKCS8_PRIV_KEY_INFO *p8inf) +{ + return ASN1_i2d_fp_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, fp, + p8inf); +} + +int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key) +{ + PKCS8_PRIV_KEY_INFO *p8inf; + int ret; + p8inf = EVP_PKEY2PKCS8(key); + if (!p8inf) + return 0; + ret = i2d_PKCS8_PRIV_KEY_INFO_fp(fp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; +} + +int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey) +{ + return ASN1_i2d_fp_of(EVP_PKEY, i2d_PrivateKey, fp, pkey); +} + +EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a) +{ + return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, fp, a); +} + +int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey) +{ + return ASN1_i2d_fp_of(EVP_PKEY, i2d_PUBKEY, fp, pkey); +} + +EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a) +{ + return ASN1_d2i_fp_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, fp, a); +} + +#endif + +PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf) +{ + return ASN1_d2i_bio_of(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_new, + d2i_PKCS8_PRIV_KEY_INFO, bp, p8inf); +} + +int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, PKCS8_PRIV_KEY_INFO *p8inf) +{ + return ASN1_i2d_bio_of(PKCS8_PRIV_KEY_INFO, i2d_PKCS8_PRIV_KEY_INFO, bp, + p8inf); +} + +int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key) +{ + PKCS8_PRIV_KEY_INFO *p8inf; + int ret; + p8inf = EVP_PKEY2PKCS8(key); + if (!p8inf) + return 0; + ret = i2d_PKCS8_PRIV_KEY_INFO_bio(bp, p8inf); + PKCS8_PRIV_KEY_INFO_free(p8inf); + return ret; +} + +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey) +{ + return ASN1_i2d_bio_of(EVP_PKEY, i2d_PrivateKey, bp, pkey); +} + +EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a) +{ + return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_AutoPrivateKey, bp, a); +} + +int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey) +{ + return ASN1_i2d_bio_of(EVP_PKEY, i2d_PUBKEY, bp, pkey); +} + +EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a) +{ + return ASN1_d2i_bio_of(EVP_PKEY, EVP_PKEY_new, d2i_PUBKEY, bp, a); +} diff --git a/libs/openssl/crypto/x509v3/ext_dat.h b/libs/openssl/crypto/x509v3/ext_dat.h new file mode 100644 index 00000000..136b1f8e --- /dev/null +++ b/libs/openssl/crypto/x509v3/ext_dat.h @@ -0,0 +1,133 @@ +/* ext_dat.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* This file contains a table of "standard" extensions */ + +extern X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; +extern X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, v3_sinfo; +extern X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, v3_akey_id; +extern X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; +extern X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, v3_freshest_crl; +extern X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, v3_ocsp_acutoff; +extern X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, v3_ocsp_serviceloc; +extern X509V3_EXT_METHOD v3_crl_hold, v3_pci; +extern X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; +extern X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; +extern X509V3_EXT_METHOD v3_addr, v3_asid; + +/* + * This table will be searched using OBJ_bsearch so it *must* kept in order + * of the ext_nid values. + */ + +static const X509V3_EXT_METHOD *standard_exts[] = { + &v3_nscert, + &v3_ns_ia5_list[0], + &v3_ns_ia5_list[1], + &v3_ns_ia5_list[2], + &v3_ns_ia5_list[3], + &v3_ns_ia5_list[4], + &v3_ns_ia5_list[5], + &v3_ns_ia5_list[6], + &v3_skey_id, + &v3_key_usage, + &v3_pkey_usage_period, + &v3_alt[0], + &v3_alt[1], + &v3_bcons, + &v3_crl_num, + &v3_cpols, + &v3_akey_id, + &v3_crld, + &v3_ext_ku, + &v3_delta_crl, + &v3_crl_reason, +#ifndef OPENSSL_NO_OCSP + &v3_crl_invdate, +#endif + &v3_sxnet, + &v3_info, +#ifndef OPENSSL_NO_RFC3779 + &v3_addr, + &v3_asid, +#endif +#ifndef OPENSSL_NO_OCSP + &v3_ocsp_nonce, + &v3_ocsp_crlid, + &v3_ocsp_accresp, + &v3_ocsp_nocheck, + &v3_ocsp_acutoff, + &v3_ocsp_serviceloc, +#endif + &v3_sinfo, + &v3_policy_constraints, +#ifndef OPENSSL_NO_OCSP + &v3_crl_hold, +#endif + &v3_pci, + &v3_name_constraints, + &v3_policy_mappings, + &v3_inhibit_anyp, + &v3_idp, + &v3_alt[2], + &v3_freshest_crl, +}; + +/* Number of standard extensions */ + +#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *)) diff --git a/libs/openssl/crypto/x509v3/pcy_cache.c b/libs/openssl/crypto/x509v3/pcy_cache.c new file mode 100644 index 00000000..c8f41f24 --- /dev/null +++ b/libs/openssl/crypto/x509v3/pcy_cache.c @@ -0,0 +1,269 @@ +/* pcy_cache.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include +#include + +#include "pcy_int.h" + +static int policy_data_cmp(const X509_POLICY_DATA *const *a, + const X509_POLICY_DATA *const *b); +static int policy_cache_set_int(long *out, ASN1_INTEGER *value); + +/* + * Set cache entry according to CertificatePolicies extension. Note: this + * destroys the passed CERTIFICATEPOLICIES structure. + */ + +static int policy_cache_create(X509 *x, + CERTIFICATEPOLICIES *policies, int crit) +{ + int i; + int ret = 0; + X509_POLICY_CACHE *cache = x->policy_cache; + X509_POLICY_DATA *data = NULL; + POLICYINFO *policy; + if (sk_POLICYINFO_num(policies) == 0) + goto bad_policy; + cache->data = sk_X509_POLICY_DATA_new(policy_data_cmp); + if (!cache->data) + goto bad_policy; + for (i = 0; i < sk_POLICYINFO_num(policies); i++) { + policy = sk_POLICYINFO_value(policies, i); + data = policy_data_new(policy, NULL, crit); + if (!data) + goto bad_policy; + /* + * Duplicate policy OIDs are illegal: reject if matches found. + */ + if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { + if (cache->anyPolicy) { + ret = -1; + goto bad_policy; + } + cache->anyPolicy = data; + } else if (sk_X509_POLICY_DATA_find(cache->data, data) != -1) { + ret = -1; + goto bad_policy; + } else if (!sk_X509_POLICY_DATA_push(cache->data, data)) + goto bad_policy; + data = NULL; + } + ret = 1; + bad_policy: + if (ret == -1) + x->ex_flags |= EXFLAG_INVALID_POLICY; + if (data) + policy_data_free(data); + sk_POLICYINFO_pop_free(policies, POLICYINFO_free); + if (ret <= 0) { + sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); + cache->data = NULL; + } + return ret; +} + +static int policy_cache_new(X509 *x) +{ + X509_POLICY_CACHE *cache; + ASN1_INTEGER *ext_any = NULL; + POLICY_CONSTRAINTS *ext_pcons = NULL; + CERTIFICATEPOLICIES *ext_cpols = NULL; + POLICY_MAPPINGS *ext_pmaps = NULL; + int i; + cache = OPENSSL_malloc(sizeof(X509_POLICY_CACHE)); + if (!cache) + return 0; + cache->anyPolicy = NULL; + cache->data = NULL; + cache->any_skip = -1; + cache->explicit_skip = -1; + cache->map_skip = -1; + + x->policy_cache = cache; + + /* + * Handle requireExplicitPolicy *first*. Need to process this even if we + * don't have any policies. + */ + ext_pcons = X509_get_ext_d2i(x, NID_policy_constraints, &i, NULL); + + if (!ext_pcons) { + if (i != -1) + goto bad_cache; + } else { + if (!ext_pcons->requireExplicitPolicy + && !ext_pcons->inhibitPolicyMapping) + goto bad_cache; + if (!policy_cache_set_int(&cache->explicit_skip, + ext_pcons->requireExplicitPolicy)) + goto bad_cache; + if (!policy_cache_set_int(&cache->map_skip, + ext_pcons->inhibitPolicyMapping)) + goto bad_cache; + } + + /* Process CertificatePolicies */ + + ext_cpols = X509_get_ext_d2i(x, NID_certificate_policies, &i, NULL); + /* + * If no CertificatePolicies extension or problem decoding then there is + * no point continuing because the valid policies will be NULL. + */ + if (!ext_cpols) { + /* If not absent some problem with extension */ + if (i != -1) + goto bad_cache; + return 1; + } + + i = policy_cache_create(x, ext_cpols, i); + + /* NB: ext_cpols freed by policy_cache_set_policies */ + + if (i <= 0) + return i; + + ext_pmaps = X509_get_ext_d2i(x, NID_policy_mappings, &i, NULL); + + if (!ext_pmaps) { + /* If not absent some problem with extension */ + if (i != -1) + goto bad_cache; + } else { + i = policy_cache_set_mapping(x, ext_pmaps); + if (i <= 0) + goto bad_cache; + } + + ext_any = X509_get_ext_d2i(x, NID_inhibit_any_policy, &i, NULL); + + if (!ext_any) { + if (i != -1) + goto bad_cache; + } else if (!policy_cache_set_int(&cache->any_skip, ext_any)) + goto bad_cache; + + if (0) { + bad_cache: + x->ex_flags |= EXFLAG_INVALID_POLICY; + } + + if (ext_pcons) + POLICY_CONSTRAINTS_free(ext_pcons); + + if (ext_any) + ASN1_INTEGER_free(ext_any); + + return 1; + +} + +void policy_cache_free(X509_POLICY_CACHE *cache) +{ + if (!cache) + return; + if (cache->anyPolicy) + policy_data_free(cache->anyPolicy); + if (cache->data) + sk_X509_POLICY_DATA_pop_free(cache->data, policy_data_free); + OPENSSL_free(cache); +} + +const X509_POLICY_CACHE *policy_cache_set(X509 *x) +{ + + if (x->policy_cache == NULL) { + CRYPTO_w_lock(CRYPTO_LOCK_X509); + policy_cache_new(x); + CRYPTO_w_unlock(CRYPTO_LOCK_X509); + } + + return x->policy_cache; + +} + +X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id) +{ + int idx; + X509_POLICY_DATA tmp; + tmp.valid_policy = (ASN1_OBJECT *)id; + idx = sk_X509_POLICY_DATA_find(cache->data, &tmp); + if (idx == -1) + return NULL; + return sk_X509_POLICY_DATA_value(cache->data, idx); +} + +static int policy_data_cmp(const X509_POLICY_DATA *const *a, + const X509_POLICY_DATA *const *b) +{ + return OBJ_cmp((*a)->valid_policy, (*b)->valid_policy); +} + +static int policy_cache_set_int(long *out, ASN1_INTEGER *value) +{ + if (value == NULL) + return 1; + if (value->type == V_ASN1_NEG_INTEGER) + return 0; + *out = ASN1_INTEGER_get(value); + return 1; +} diff --git a/libs/openssl/crypto/x509v3/pcy_data.c b/libs/openssl/crypto/x509v3/pcy_data.c new file mode 100644 index 00000000..90e9970e --- /dev/null +++ b/libs/openssl/crypto/x509v3/pcy_data.c @@ -0,0 +1,129 @@ +/* pcy_data.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include +#include + +#include "pcy_int.h" + +/* Policy Node routines */ + +void policy_data_free(X509_POLICY_DATA *data) +{ + ASN1_OBJECT_free(data->valid_policy); + /* Don't free qualifiers if shared */ + if (!(data->flags & POLICY_DATA_FLAG_SHARED_QUALIFIERS)) + sk_POLICYQUALINFO_pop_free(data->qualifier_set, POLICYQUALINFO_free); + sk_ASN1_OBJECT_pop_free(data->expected_policy_set, ASN1_OBJECT_free); + OPENSSL_free(data); +} + +/* + * Create a data based on an existing policy. If 'id' is NULL use the oid in + * the policy, otherwise use 'id'. This behaviour covers the two types of + * data in RFC3280: data with from a CertificatePolcies extension and + * additional data with just the qualifiers of anyPolicy and ID from another + * source. + */ + +X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, + const ASN1_OBJECT *cid, int crit) +{ + X509_POLICY_DATA *ret; + ASN1_OBJECT *id; + if (!policy && !cid) + return NULL; + if (cid) { + id = OBJ_dup(cid); + if (!id) + return NULL; + } else + id = NULL; + ret = OPENSSL_malloc(sizeof(X509_POLICY_DATA)); + if (!ret) + return NULL; + ret->expected_policy_set = sk_ASN1_OBJECT_new_null(); + if (!ret->expected_policy_set) { + OPENSSL_free(ret); + if (id) + ASN1_OBJECT_free(id); + return NULL; + } + + if (crit) + ret->flags = POLICY_DATA_FLAG_CRITICAL; + else + ret->flags = 0; + + if (id) + ret->valid_policy = id; + else { + ret->valid_policy = policy->policyid; + policy->policyid = NULL; + } + + if (policy) { + ret->qualifier_set = policy->qualifiers; + policy->qualifiers = NULL; + } else + ret->qualifier_set = NULL; + + return ret; +} diff --git a/libs/openssl/crypto/x509v3/pcy_int.h b/libs/openssl/crypto/x509v3/pcy_int.h new file mode 100644 index 00000000..b5075f9e --- /dev/null +++ b/libs/openssl/crypto/x509v3/pcy_int.h @@ -0,0 +1,217 @@ +/* pcy_int.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +typedef struct X509_POLICY_DATA_st X509_POLICY_DATA; + +DECLARE_STACK_OF(X509_POLICY_DATA) + +/* Internal structures */ + +/* + * This structure and the field names correspond to the Policy 'node' of + * RFC3280. NB this structure contains no pointers to parent or child data: + * X509_POLICY_NODE contains that. This means that the main policy data can + * be kept static and cached with the certificate. + */ + +struct X509_POLICY_DATA_st { + unsigned int flags; + /* Policy OID and qualifiers for this data */ + ASN1_OBJECT *valid_policy; + STACK_OF(POLICYQUALINFO) *qualifier_set; + STACK_OF(ASN1_OBJECT) *expected_policy_set; +}; + +/* X509_POLICY_DATA flags values */ + +/* + * This flag indicates the structure has been mapped using a policy mapping + * extension. If policy mapping is not active its references get deleted. + */ + +#define POLICY_DATA_FLAG_MAPPED 0x1 + +/* + * This flag indicates the data doesn't correspond to a policy in Certificate + * Policies: it has been mapped to any policy. + */ + +#define POLICY_DATA_FLAG_MAPPED_ANY 0x2 + +/* AND with flags to see if any mapping has occurred */ + +#define POLICY_DATA_FLAG_MAP_MASK 0x3 + +/* qualifiers are shared and shouldn't be freed */ + +#define POLICY_DATA_FLAG_SHARED_QUALIFIERS 0x4 + +/* Parent node is an extra node and should be freed */ + +#define POLICY_DATA_FLAG_EXTRA_NODE 0x8 + +/* Corresponding CertificatePolicies is critical */ + +#define POLICY_DATA_FLAG_CRITICAL 0x10 + +/* This structure is cached with a certificate */ + +struct X509_POLICY_CACHE_st { + /* anyPolicy data or NULL if no anyPolicy */ + X509_POLICY_DATA *anyPolicy; + /* other policy data */ + STACK_OF(X509_POLICY_DATA) *data; + /* If InhibitAnyPolicy present this is its value or -1 if absent. */ + long any_skip; + /* + * If policyConstraints and requireExplicitPolicy present this is its + * value or -1 if absent. + */ + long explicit_skip; + /* + * If policyConstraints and policyMapping present this is its value or -1 + * if absent. + */ + long map_skip; +}; + +/* + * #define POLICY_CACHE_FLAG_CRITICAL POLICY_DATA_FLAG_CRITICAL + */ + +/* This structure represents the relationship between nodes */ + +struct X509_POLICY_NODE_st { + /* node data this refers to */ + const X509_POLICY_DATA *data; + /* Parent node */ + X509_POLICY_NODE *parent; + /* Number of child nodes */ + int nchild; +}; + +struct X509_POLICY_LEVEL_st { + /* Cert for this level */ + X509 *cert; + /* nodes at this level */ + STACK_OF(X509_POLICY_NODE) *nodes; + /* anyPolicy node */ + X509_POLICY_NODE *anyPolicy; + /* Extra data */ + /* + * STACK_OF(X509_POLICY_DATA) *extra_data; + */ + unsigned int flags; +}; + +struct X509_POLICY_TREE_st { + /* This is the tree 'level' data */ + X509_POLICY_LEVEL *levels; + int nlevel; + /* + * Extra policy data when additional nodes (not from the certificate) are + * required. + */ + STACK_OF(X509_POLICY_DATA) *extra_data; + /* This is the authority constained policy set */ + STACK_OF(X509_POLICY_NODE) *auth_policies; + STACK_OF(X509_POLICY_NODE) *user_policies; + unsigned int flags; +}; + +/* Set if anyPolicy present in user policies */ +#define POLICY_FLAG_ANY_POLICY 0x2 + +/* Useful macros */ + +#define node_data_critical(data) (data->flags & POLICY_DATA_FLAG_CRITICAL) +#define node_critical(node) node_data_critical(node->data) + +/* Internal functions */ + +X509_POLICY_DATA *policy_data_new(POLICYINFO *policy, const ASN1_OBJECT *id, + int crit); +void policy_data_free(X509_POLICY_DATA *data); + +X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id); +int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps); + +STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void); + +void policy_cache_init(void); + +void policy_cache_free(X509_POLICY_CACHE *cache); + +X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, + const X509_POLICY_NODE *parent, + const ASN1_OBJECT *id); + +X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk, + const ASN1_OBJECT *id); + +X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, + const X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, + X509_POLICY_TREE *tree); +void policy_node_free(X509_POLICY_NODE *node); +int policy_node_match(const X509_POLICY_LEVEL *lvl, + const X509_POLICY_NODE *node, const ASN1_OBJECT *oid); + +const X509_POLICY_CACHE *policy_cache_set(X509 *x); diff --git a/libs/openssl/crypto/x509v3/pcy_lib.c b/libs/openssl/crypto/x509v3/pcy_lib.c new file mode 100644 index 00000000..dbb29835 --- /dev/null +++ b/libs/openssl/crypto/x509v3/pcy_lib.c @@ -0,0 +1,167 @@ +/* pcy_lib.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include +#include + +#include "pcy_int.h" + +/* accessor functions */ + +/* X509_POLICY_TREE stuff */ + +int X509_policy_tree_level_count(const X509_POLICY_TREE *tree) +{ + if (!tree) + return 0; + return tree->nlevel; +} + +X509_POLICY_LEVEL *X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, + int i) +{ + if (!tree || (i < 0) || (i >= tree->nlevel)) + return NULL; + return tree->levels + i; +} + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_policies(const + X509_POLICY_TREE + *tree) +{ + if (!tree) + return NULL; + return tree->auth_policies; +} + +STACK_OF(X509_POLICY_NODE) *X509_policy_tree_get0_user_policies(const + X509_POLICY_TREE + *tree) +{ + if (!tree) + return NULL; + if (tree->flags & POLICY_FLAG_ANY_POLICY) + return tree->auth_policies; + else + return tree->user_policies; +} + +/* X509_POLICY_LEVEL stuff */ + +int X509_policy_level_node_count(X509_POLICY_LEVEL *level) +{ + int n; + if (!level) + return 0; + if (level->anyPolicy) + n = 1; + else + n = 0; + if (level->nodes) + n += sk_X509_POLICY_NODE_num(level->nodes); + return n; +} + +X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i) +{ + if (!level) + return NULL; + if (level->anyPolicy) { + if (i == 0) + return level->anyPolicy; + i--; + } + return sk_X509_POLICY_NODE_value(level->nodes, i); +} + +/* X509_POLICY_NODE stuff */ + +const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node) +{ + if (!node) + return NULL; + return node->data->valid_policy; +} + +#if 0 +int X509_policy_node_get_critical(const X509_POLICY_NODE *node) +{ + if (node_critical(node)) + return 1; + return 0; +} +#endif + +STACK_OF(POLICYQUALINFO) *X509_policy_node_get0_qualifiers(const + X509_POLICY_NODE + *node) +{ + if (!node) + return NULL; + return node->data->qualifier_set; +} + +const X509_POLICY_NODE *X509_policy_node_get0_parent(const X509_POLICY_NODE + *node) +{ + if (!node) + return NULL; + return node->parent; +} diff --git a/libs/openssl/crypto/x509v3/pcy_map.c b/libs/openssl/crypto/x509v3/pcy_map.c new file mode 100644 index 00000000..b99eb91c --- /dev/null +++ b/libs/openssl/crypto/x509v3/pcy_map.c @@ -0,0 +1,130 @@ +/* pcy_map.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include +#include + +#include "pcy_int.h" + +/* + * Set policy mapping entries in cache. Note: this modifies the passed + * POLICY_MAPPINGS structure + */ + +int policy_cache_set_mapping(X509 *x, POLICY_MAPPINGS *maps) +{ + POLICY_MAPPING *map; + X509_POLICY_DATA *data; + X509_POLICY_CACHE *cache = x->policy_cache; + int i; + int ret = 0; + if (sk_POLICY_MAPPING_num(maps) == 0) { + ret = -1; + goto bad_mapping; + } + for (i = 0; i < sk_POLICY_MAPPING_num(maps); i++) { + map = sk_POLICY_MAPPING_value(maps, i); + /* Reject if map to or from anyPolicy */ + if ((OBJ_obj2nid(map->subjectDomainPolicy) == NID_any_policy) + || (OBJ_obj2nid(map->issuerDomainPolicy) == NID_any_policy)) { + ret = -1; + goto bad_mapping; + } + + /* Attempt to find matching policy data */ + data = policy_cache_find_data(cache, map->issuerDomainPolicy); + /* If we don't have anyPolicy can't map */ + if (!data && !cache->anyPolicy) + continue; + + /* Create a NODE from anyPolicy */ + if (!data) { + data = policy_data_new(NULL, map->issuerDomainPolicy, + cache->anyPolicy->flags + & POLICY_DATA_FLAG_CRITICAL); + if (!data) + goto bad_mapping; + data->qualifier_set = cache->anyPolicy->qualifier_set; + /* + * map->issuerDomainPolicy = NULL; + */ + data->flags |= POLICY_DATA_FLAG_MAPPED_ANY; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; + if (!sk_X509_POLICY_DATA_push(cache->data, data)) { + policy_data_free(data); + goto bad_mapping; + } + } else + data->flags |= POLICY_DATA_FLAG_MAPPED; + if (!sk_ASN1_OBJECT_push(data->expected_policy_set, + map->subjectDomainPolicy)) + goto bad_mapping; + map->subjectDomainPolicy = NULL; + + } + + ret = 1; + bad_mapping: + if (ret == -1) + x->ex_flags |= EXFLAG_INVALID_POLICY; + sk_POLICY_MAPPING_pop_free(maps, POLICY_MAPPING_free); + return ret; + +} diff --git a/libs/openssl/crypto/x509v3/pcy_node.c b/libs/openssl/crypto/x509v3/pcy_node.c new file mode 100644 index 00000000..d6c91765 --- /dev/null +++ b/libs/openssl/crypto/x509v3/pcy_node.c @@ -0,0 +1,190 @@ +/* pcy_node.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include + +#include "pcy_int.h" + +static int node_cmp(const X509_POLICY_NODE *const *a, + const X509_POLICY_NODE *const *b) +{ + return OBJ_cmp((*a)->data->valid_policy, (*b)->data->valid_policy); +} + +STACK_OF(X509_POLICY_NODE) *policy_node_cmp_new(void) +{ + return sk_X509_POLICY_NODE_new(node_cmp); +} + +X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *nodes, + const ASN1_OBJECT *id) +{ + X509_POLICY_DATA n; + X509_POLICY_NODE l; + int idx; + + n.valid_policy = (ASN1_OBJECT *)id; + l.data = &n; + + idx = sk_X509_POLICY_NODE_find(nodes, &l); + if (idx == -1) + return NULL; + + return sk_X509_POLICY_NODE_value(nodes, idx); + +} + +X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level, + const X509_POLICY_NODE *parent, + const ASN1_OBJECT *id) +{ + X509_POLICY_NODE *node; + int i; + for (i = 0; i < sk_X509_POLICY_NODE_num(level->nodes); i++) { + node = sk_X509_POLICY_NODE_value(level->nodes, i); + if (node->parent == parent) { + if (!OBJ_cmp(node->data->valid_policy, id)) + return node; + } + } + return NULL; +} + +X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level, + const X509_POLICY_DATA *data, + X509_POLICY_NODE *parent, + X509_POLICY_TREE *tree) +{ + X509_POLICY_NODE *node; + node = OPENSSL_malloc(sizeof(X509_POLICY_NODE)); + if (!node) + return NULL; + node->data = data; + node->parent = parent; + node->nchild = 0; + if (level) { + if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) { + if (level->anyPolicy) + goto node_error; + level->anyPolicy = node; + } else { + + if (!level->nodes) + level->nodes = policy_node_cmp_new(); + if (!level->nodes) + goto node_error; + if (!sk_X509_POLICY_NODE_push(level->nodes, node)) + goto node_error; + } + } + + if (tree) { + if (!tree->extra_data) + tree->extra_data = sk_X509_POLICY_DATA_new_null(); + if (!tree->extra_data) + goto node_error; + if (!sk_X509_POLICY_DATA_push(tree->extra_data, data)) + goto node_error; + } + + if (parent) + parent->nchild++; + + return node; + + node_error: + policy_node_free(node); + return 0; + +} + +void policy_node_free(X509_POLICY_NODE *node) +{ + OPENSSL_free(node); +} + +/* + * See if a policy node matches a policy OID. If mapping enabled look through + * expected policy set otherwise just valid policy. + */ + +int policy_node_match(const X509_POLICY_LEVEL *lvl, + const X509_POLICY_NODE *node, const ASN1_OBJECT *oid) +{ + int i; + ASN1_OBJECT *policy_oid; + const X509_POLICY_DATA *x = node->data; + + if ((lvl->flags & X509_V_FLAG_INHIBIT_MAP) + || !(x->flags & POLICY_DATA_FLAG_MAP_MASK)) { + if (!OBJ_cmp(x->valid_policy, oid)) + return 1; + return 0; + } + + for (i = 0; i < sk_ASN1_OBJECT_num(x->expected_policy_set); i++) { + policy_oid = sk_ASN1_OBJECT_value(x->expected_policy_set, i); + if (!OBJ_cmp(policy_oid, oid)) + return 1; + } + return 0; + +} diff --git a/libs/openssl/crypto/x509v3/pcy_tree.c b/libs/openssl/crypto/x509v3/pcy_tree.c new file mode 100644 index 00000000..09b8691c --- /dev/null +++ b/libs/openssl/crypto/x509v3/pcy_tree.c @@ -0,0 +1,831 @@ +/* pcy_tree.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2004. + */ +/* ==================================================================== + * Copyright (c) 2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "cryptlib.h" +#include +#include + +#include "pcy_int.h" + +/* + * Enable this to print out the complete policy tree at various point during + * evaluation. + */ + +/* + * #define OPENSSL_POLICY_DEBUG + */ + +#ifdef OPENSSL_POLICY_DEBUG + +static void expected_print(BIO *err, X509_POLICY_LEVEL *lev, + X509_POLICY_NODE *node, int indent) +{ + if ((lev->flags & X509_V_FLAG_INHIBIT_MAP) + || !(node->data->flags & POLICY_DATA_FLAG_MAP_MASK)) + BIO_puts(err, " Not Mapped\n"); + else { + int i; + STACK_OF(ASN1_OBJECT) *pset = node->data->expected_policy_set; + ASN1_OBJECT *oid; + BIO_puts(err, " Expected: "); + for (i = 0; i < sk_ASN1_OBJECT_num(pset); i++) { + oid = sk_ASN1_OBJECT_value(pset, i); + if (i) + BIO_puts(err, ", "); + i2a_ASN1_OBJECT(err, oid); + } + BIO_puts(err, "\n"); + } +} + +static void tree_print(char *str, X509_POLICY_TREE *tree, + X509_POLICY_LEVEL *curr) +{ + X509_POLICY_LEVEL *plev; + X509_POLICY_NODE *node; + int i; + BIO *err; + err = BIO_new_fp(stderr, BIO_NOCLOSE); + if (!curr) + curr = tree->levels + tree->nlevel; + else + curr++; + BIO_printf(err, "Level print after %s\n", str); + BIO_printf(err, "Printing Up to Level %ld\n", curr - tree->levels); + for (plev = tree->levels; plev != curr; plev++) { + BIO_printf(err, "Level %ld, flags = %x\n", + plev - tree->levels, plev->flags); + for (i = 0; i < sk_X509_POLICY_NODE_num(plev->nodes); i++) { + node = sk_X509_POLICY_NODE_value(plev->nodes, i); + X509_POLICY_NODE_print(err, node, 2); + expected_print(err, plev, node, 2); + BIO_printf(err, " Flags: %x\n", node->data->flags); + } + if (plev->anyPolicy) + X509_POLICY_NODE_print(err, plev->anyPolicy, 2); + } + + BIO_free(err); + +} +#else + +# define tree_print(a,b,c) /* */ + +#endif + +/*- + * Initialize policy tree. Return values: + * 0 Some internal error occurred. + * -1 Inconsistent or invalid extensions in certificates. + * 1 Tree initialized OK. + * 2 Policy tree is empty. + * 5 Tree OK and requireExplicitPolicy true. + * 6 Tree empty and requireExplicitPolicy true. + */ + +static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs, + unsigned int flags) +{ + X509_POLICY_TREE *tree; + X509_POLICY_LEVEL *level; + const X509_POLICY_CACHE *cache; + X509_POLICY_DATA *data = NULL; + X509 *x; + int ret = 1; + int i, n; + int explicit_policy; + int any_skip; + int map_skip; + *ptree = NULL; + n = sk_X509_num(certs); + +#if 0 + /* Disable policy mapping for now... */ + flags |= X509_V_FLAG_INHIBIT_MAP; +#endif + + if (flags & X509_V_FLAG_EXPLICIT_POLICY) + explicit_policy = 0; + else + explicit_policy = n + 1; + + if (flags & X509_V_FLAG_INHIBIT_ANY) + any_skip = 0; + else + any_skip = n + 1; + + if (flags & X509_V_FLAG_INHIBIT_MAP) + map_skip = 0; + else + map_skip = n + 1; + + /* Can't do anything with just a trust anchor */ + if (n == 1) + return 1; + /* + * First setup policy cache in all certificates apart from the trust + * anchor. Note any bad cache results on the way. Also can calculate + * explicit_policy value at this point. + */ + for (i = n - 2; i >= 0; i--) { + x = sk_X509_value(certs, i); + X509_check_purpose(x, -1, -1); + cache = policy_cache_set(x); + /* If cache NULL something bad happened: return immediately */ + if (cache == NULL) + return 0; + /* + * If inconsistent extensions keep a note of it but continue + */ + if (x->ex_flags & EXFLAG_INVALID_POLICY) + ret = -1; + /* + * Otherwise if we have no data (hence no CertificatePolicies) and + * haven't already set an inconsistent code note it. + */ + else if ((ret == 1) && !cache->data) + ret = 2; + if (explicit_policy > 0) { + if (!(x->ex_flags & EXFLAG_SI)) + explicit_policy--; + if ((cache->explicit_skip != -1) + && (cache->explicit_skip < explicit_policy)) + explicit_policy = cache->explicit_skip; + } + } + + if (ret != 1) { + if (ret == 2 && !explicit_policy) + return 6; + return ret; + } + + /* If we get this far initialize the tree */ + + tree = OPENSSL_malloc(sizeof(X509_POLICY_TREE)); + + if (!tree) + return 0; + + tree->flags = 0; + tree->levels = OPENSSL_malloc(sizeof(X509_POLICY_LEVEL) * n); + tree->nlevel = 0; + tree->extra_data = NULL; + tree->auth_policies = NULL; + tree->user_policies = NULL; + + if (!tree->levels) { + OPENSSL_free(tree); + return 0; + } + + memset(tree->levels, 0, n * sizeof(X509_POLICY_LEVEL)); + + tree->nlevel = n; + + level = tree->levels; + + /* Root data: initialize to anyPolicy */ + + data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0); + + if (!data || !level_add_node(level, data, NULL, tree)) + goto bad_tree; + + for (i = n - 2; i >= 0; i--) { + level++; + x = sk_X509_value(certs, i); + cache = policy_cache_set(x); + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + level->cert = x; + + if (!cache->anyPolicy) + level->flags |= X509_V_FLAG_INHIBIT_ANY; + + /* Determine inhibit any and inhibit map flags */ + if (any_skip == 0) { + /* + * Any matching allowed if certificate is self issued and not the + * last in the chain. + */ + if (!(x->ex_flags & EXFLAG_SI) || (i == 0)) + level->flags |= X509_V_FLAG_INHIBIT_ANY; + } else { + if (!(x->ex_flags & EXFLAG_SI)) + any_skip--; + if ((cache->any_skip >= 0) + && (cache->any_skip < any_skip)) + any_skip = cache->any_skip; + } + + if (map_skip == 0) + level->flags |= X509_V_FLAG_INHIBIT_MAP; + else { + if (!(x->ex_flags & EXFLAG_SI)) + map_skip--; + if ((cache->map_skip >= 0) + && (cache->map_skip < map_skip)) + map_skip = cache->map_skip; + } + + } + + *ptree = tree; + + if (explicit_policy) + return 1; + else + return 5; + + bad_tree: + + X509_policy_tree_free(tree); + + return 0; + +} + +static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr, + const X509_POLICY_DATA *data) +{ + X509_POLICY_LEVEL *last = curr - 1; + X509_POLICY_NODE *node; + int i, matched = 0; + /* Iterate through all in nodes linking matches */ + for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { + node = sk_X509_POLICY_NODE_value(last->nodes, i); + if (policy_node_match(last, node, data->valid_policy)) { + if (!level_add_node(curr, data, node, NULL)) + return 0; + matched = 1; + } + } + if (!matched && last->anyPolicy) { + if (!level_add_node(curr, data, last->anyPolicy, NULL)) + return 0; + } + return 1; +} + +/* + * This corresponds to RFC3280 6.1.3(d)(1): link any data from + * CertificatePolicies onto matching parent or anyPolicy if no match. + */ + +static int tree_link_nodes(X509_POLICY_LEVEL *curr, + const X509_POLICY_CACHE *cache) +{ + int i; + X509_POLICY_DATA *data; + + for (i = 0; i < sk_X509_POLICY_DATA_num(cache->data); i++) { + data = sk_X509_POLICY_DATA_value(cache->data, i); + /* + * If a node is mapped any it doesn't have a corresponding + * CertificatePolicies entry. However such an identical node would + * be created if anyPolicy matching is enabled because there would be + * no match with the parent valid_policy_set. So we create link + * because then it will have the mapping flags right and we can prune + * it later. + */ +#if 0 + if ((data->flags & POLICY_DATA_FLAG_MAPPED_ANY) + && !(curr->flags & X509_V_FLAG_INHIBIT_ANY)) + continue; +#endif + /* Look for matching nodes in previous level */ + if (!tree_link_matching_nodes(curr, data)) + return 0; + } + return 1; +} + +/* + * This corresponds to RFC3280 6.1.3(d)(2): Create new data for any unmatched + * policies in the parent and link to anyPolicy. + */ + +static int tree_add_unmatched(X509_POLICY_LEVEL *curr, + const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id, + X509_POLICY_NODE *node, X509_POLICY_TREE *tree) +{ + X509_POLICY_DATA *data; + if (id == NULL) + id = node->data->valid_policy; + /* + * Create a new node with qualifiers from anyPolicy and id from unmatched + * node. + */ + data = policy_data_new(NULL, id, node_critical(node)); + + if (data == NULL) + return 0; + /* Curr may not have anyPolicy */ + data->qualifier_set = cache->anyPolicy->qualifier_set; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; + if (!level_add_node(curr, data, node, tree)) { + policy_data_free(data); + return 0; + } + + return 1; +} + +static int tree_link_unmatched(X509_POLICY_LEVEL *curr, + const X509_POLICY_CACHE *cache, + X509_POLICY_NODE *node, X509_POLICY_TREE *tree) +{ + const X509_POLICY_LEVEL *last = curr - 1; + int i; + + if ((last->flags & X509_V_FLAG_INHIBIT_MAP) + || !(node->data->flags & POLICY_DATA_FLAG_MAPPED)) { + /* If no policy mapping: matched if one child present */ + if (node->nchild) + return 1; + if (!tree_add_unmatched(curr, cache, NULL, node, tree)) + return 0; + /* Add it */ + } else { + /* If mapping: matched if one child per expected policy set */ + STACK_OF(ASN1_OBJECT) *expset = node->data->expected_policy_set; + if (node->nchild == sk_ASN1_OBJECT_num(expset)) + return 1; + /* Locate unmatched nodes */ + for (i = 0; i < sk_ASN1_OBJECT_num(expset); i++) { + ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(expset, i); + if (level_find_node(curr, node, oid)) + continue; + if (!tree_add_unmatched(curr, cache, oid, node, tree)) + return 0; + } + + } + + return 1; + +} + +static int tree_link_any(X509_POLICY_LEVEL *curr, + const X509_POLICY_CACHE *cache, + X509_POLICY_TREE *tree) +{ + int i; + /* + * X509_POLICY_DATA *data; + */ + X509_POLICY_NODE *node; + X509_POLICY_LEVEL *last = curr - 1; + + for (i = 0; i < sk_X509_POLICY_NODE_num(last->nodes); i++) { + node = sk_X509_POLICY_NODE_value(last->nodes, i); + + if (!tree_link_unmatched(curr, cache, node, tree)) + return 0; + +#if 0 + + /* + * Skip any node with any children: we only want unmathced nodes. + * Note: need something better for policy mapping because each node + * may have multiple children + */ + if (node->nchild) + continue; + + /* + * Create a new node with qualifiers from anyPolicy and id from + * unmatched node. + */ + data = policy_data_new(NULL, node->data->valid_policy, + node_critical(node)); + + if (data == NULL) + return 0; + /* Curr may not have anyPolicy */ + data->qualifier_set = cache->anyPolicy->qualifier_set; + data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS; + if (!level_add_node(curr, data, node, tree)) { + policy_data_free(data); + return 0; + } +#endif + + } + /* Finally add link to anyPolicy */ + if (last->anyPolicy) { + if (!level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL)) + return 0; + } + return 1; +} + +/* + * Prune the tree: delete any child mapped child data on the current level + * then proceed up the tree deleting any data with no children. If we ever + * have no data on a level we can halt because the tree will be empty. + */ + +static int tree_prune(X509_POLICY_TREE *tree, X509_POLICY_LEVEL *curr) +{ + STACK_OF(X509_POLICY_NODE) *nodes; + X509_POLICY_NODE *node; + int i; + nodes = curr->nodes; + if (curr->flags & X509_V_FLAG_INHIBIT_MAP) { + for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { + node = sk_X509_POLICY_NODE_value(nodes, i); + /* Delete any mapped data: see RFC3280 XXXX */ + if (node->data->flags & POLICY_DATA_FLAG_MAP_MASK) { + node->parent->nchild--; + OPENSSL_free(node); + (void)sk_X509_POLICY_NODE_delete(nodes, i); + } + } + } + + for (;;) { + --curr; + nodes = curr->nodes; + for (i = sk_X509_POLICY_NODE_num(nodes) - 1; i >= 0; i--) { + node = sk_X509_POLICY_NODE_value(nodes, i); + if (node->nchild == 0) { + node->parent->nchild--; + OPENSSL_free(node); + (void)sk_X509_POLICY_NODE_delete(nodes, i); + } + } + if (curr->anyPolicy && !curr->anyPolicy->nchild) { + if (curr->anyPolicy->parent) + curr->anyPolicy->parent->nchild--; + OPENSSL_free(curr->anyPolicy); + curr->anyPolicy = NULL; + } + if (curr == tree->levels) { + /* If we zapped anyPolicy at top then tree is empty */ + if (!curr->anyPolicy) + return 2; + return 1; + } + } + + return 1; + +} + +static int tree_add_auth_node(STACK_OF(X509_POLICY_NODE) **pnodes, + X509_POLICY_NODE *pcy) +{ + if (!*pnodes) { + *pnodes = policy_node_cmp_new(); + if (!*pnodes) + return 0; + } else if (sk_X509_POLICY_NODE_find(*pnodes, pcy) != -1) + return 1; + + if (!sk_X509_POLICY_NODE_push(*pnodes, pcy)) + return 0; + + return 1; + +} + +/* + * Calculate the authority set based on policy tree. The 'pnodes' parameter + * is used as a store for the set of policy nodes used to calculate the user + * set. If the authority set is not anyPolicy then pnodes will just point to + * the authority set. If however the authority set is anyPolicy then the set + * of valid policies (other than anyPolicy) is store in pnodes. The return + * value of '2' is used in this case to indicate that pnodes should be freed. + */ + +static int tree_calculate_authority_set(X509_POLICY_TREE *tree, + STACK_OF(X509_POLICY_NODE) **pnodes) +{ + X509_POLICY_LEVEL *curr; + X509_POLICY_NODE *node, *anyptr; + STACK_OF(X509_POLICY_NODE) **addnodes; + int i, j; + curr = tree->levels + tree->nlevel - 1; + + /* If last level contains anyPolicy set is anyPolicy */ + if (curr->anyPolicy) { + if (!tree_add_auth_node(&tree->auth_policies, curr->anyPolicy)) + return 0; + addnodes = pnodes; + } else + /* Add policies to authority set */ + addnodes = &tree->auth_policies; + + curr = tree->levels; + for (i = 1; i < tree->nlevel; i++) { + /* + * If no anyPolicy node on this this level it can't appear on lower + * levels so end search. + */ + if (!(anyptr = curr->anyPolicy)) + break; + curr++; + for (j = 0; j < sk_X509_POLICY_NODE_num(curr->nodes); j++) { + node = sk_X509_POLICY_NODE_value(curr->nodes, j); + if ((node->parent == anyptr) + && !tree_add_auth_node(addnodes, node)) + return 0; + } + } + + if (addnodes == pnodes) + return 2; + + *pnodes = tree->auth_policies; + + return 1; +} + +static int tree_calculate_user_set(X509_POLICY_TREE *tree, + STACK_OF(ASN1_OBJECT) *policy_oids, + STACK_OF(X509_POLICY_NODE) *auth_nodes) +{ + int i; + X509_POLICY_NODE *node; + ASN1_OBJECT *oid; + + X509_POLICY_NODE *anyPolicy; + X509_POLICY_DATA *extra; + + /* + * Check if anyPolicy present in authority constrained policy set: this + * will happen if it is a leaf node. + */ + + if (sk_ASN1_OBJECT_num(policy_oids) <= 0) + return 1; + + anyPolicy = tree->levels[tree->nlevel - 1].anyPolicy; + + for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { + oid = sk_ASN1_OBJECT_value(policy_oids, i); + if (OBJ_obj2nid(oid) == NID_any_policy) { + tree->flags |= POLICY_FLAG_ANY_POLICY; + return 1; + } + } + + for (i = 0; i < sk_ASN1_OBJECT_num(policy_oids); i++) { + oid = sk_ASN1_OBJECT_value(policy_oids, i); + node = tree_find_sk(auth_nodes, oid); + if (!node) { + if (!anyPolicy) + continue; + /* + * Create a new node with policy ID from user set and qualifiers + * from anyPolicy. + */ + extra = policy_data_new(NULL, oid, node_critical(anyPolicy)); + if (!extra) + return 0; + extra->qualifier_set = anyPolicy->data->qualifier_set; + extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS + | POLICY_DATA_FLAG_EXTRA_NODE; + node = level_add_node(NULL, extra, anyPolicy->parent, tree); + } + if (!tree->user_policies) { + tree->user_policies = sk_X509_POLICY_NODE_new_null(); + if (!tree->user_policies) + return 1; + } + if (!sk_X509_POLICY_NODE_push(tree->user_policies, node)) + return 0; + } + return 1; + +} + +static int tree_evaluate(X509_POLICY_TREE *tree) +{ + int ret, i; + X509_POLICY_LEVEL *curr = tree->levels + 1; + const X509_POLICY_CACHE *cache; + + for (i = 1; i < tree->nlevel; i++, curr++) { + cache = policy_cache_set(curr->cert); + if (!tree_link_nodes(curr, cache)) + return 0; + + if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY) + && !tree_link_any(curr, cache, tree)) + return 0; + tree_print("before tree_prune()", tree, curr); + ret = tree_prune(tree, curr); + if (ret != 1) + return ret; + } + + return 1; + +} + +static void exnode_free(X509_POLICY_NODE *node) +{ + if (node->data && (node->data->flags & POLICY_DATA_FLAG_EXTRA_NODE)) + OPENSSL_free(node); +} + +void X509_policy_tree_free(X509_POLICY_TREE *tree) +{ + X509_POLICY_LEVEL *curr; + int i; + + if (!tree) + return; + + sk_X509_POLICY_NODE_free(tree->auth_policies); + sk_X509_POLICY_NODE_pop_free(tree->user_policies, exnode_free); + + for (i = 0, curr = tree->levels; i < tree->nlevel; i++, curr++) { + if (curr->cert) + X509_free(curr->cert); + if (curr->nodes) + sk_X509_POLICY_NODE_pop_free(curr->nodes, policy_node_free); + if (curr->anyPolicy) + policy_node_free(curr->anyPolicy); + } + + if (tree->extra_data) + sk_X509_POLICY_DATA_pop_free(tree->extra_data, policy_data_free); + + OPENSSL_free(tree->levels); + OPENSSL_free(tree); + +} + +/*- + * Application policy checking function. + * Return codes: + * 0 Internal Error. + * 1 Successful. + * -1 One or more certificates contain invalid or inconsistent extensions + * -2 User constrained policy set empty and requireExplicit true. + */ + +int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, unsigned int flags) +{ + int ret; + X509_POLICY_TREE *tree = NULL; + STACK_OF(X509_POLICY_NODE) *nodes, *auth_nodes = NULL; + *ptree = NULL; + + *pexplicit_policy = 0; + ret = tree_init(&tree, certs, flags); + + switch (ret) { + + /* Tree empty requireExplicit False: OK */ + case 2: + return 1; + + /* Some internal error */ + case -1: + return -1; + + /* Some internal error */ + case 0: + return 0; + + /* Tree empty requireExplicit True: Error */ + + case 6: + *pexplicit_policy = 1; + return -2; + + /* Tree OK requireExplicit True: OK and continue */ + case 5: + *pexplicit_policy = 1; + break; + + /* Tree OK: continue */ + + case 1: + if (!tree) + /* + * tree_init() returns success and a null tree + * if it's just looking at a trust anchor. + * I'm not sure that returning success here is + * correct, but I'm sure that reporting this + * as an internal error which our caller + * interprets as a malloc failure is wrong. + */ + return 1; + break; + } + + if (!tree) + goto error; + ret = tree_evaluate(tree); + + tree_print("tree_evaluate()", tree, NULL); + + if (ret <= 0) + goto error; + + /* Return value 2 means tree empty */ + if (ret == 2) { + X509_policy_tree_free(tree); + if (*pexplicit_policy) + return -2; + else + return 1; + } + + /* Tree is not empty: continue */ + + ret = tree_calculate_authority_set(tree, &auth_nodes); + + if (!ret) + goto error; + + if (!tree_calculate_user_set(tree, policy_oids, auth_nodes)) + goto error; + + if (ret == 2) + sk_X509_POLICY_NODE_free(auth_nodes); + + if (tree) + *ptree = tree; + + if (*pexplicit_policy) { + nodes = X509_policy_tree_get0_user_policies(tree); + if (sk_X509_POLICY_NODE_num(nodes) <= 0) + return -2; + } + + return 1; + + error: + + X509_policy_tree_free(tree); + + return 0; + +} diff --git a/libs/openssl/crypto/x509v3/tabtest.c b/libs/openssl/crypto/x509v3/tabtest.c new file mode 100644 index 00000000..145dc9de --- /dev/null +++ b/libs/openssl/crypto/x509v3/tabtest.c @@ -0,0 +1,92 @@ +/* tabtest.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * Simple program to check the ext_dat.h is correct and print out problems if + * it is not. + */ + +#include + +#include + +#include "ext_dat.h" + +main() +{ + int i, prev = -1, bad = 0; + X509V3_EXT_METHOD **tmp; + i = sizeof(standard_exts) / sizeof(X509V3_EXT_METHOD *); + if (i != STANDARD_EXTENSION_COUNT) + fprintf(stderr, "Extension number invalid expecting %d\n", i); + tmp = standard_exts; + for (i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) { + if ((*tmp)->ext_nid < prev) + bad = 1; + prev = (*tmp)->ext_nid; + + } + if (bad) { + tmp = standard_exts; + fprintf(stderr, "Extensions out of order!\n"); + for (i = 0; i < STANDARD_EXTENSION_COUNT; i++, tmp++) + printf("%d : %s\n", (*tmp)->ext_nid, OBJ_nid2sn((*tmp)->ext_nid)); + } else + fprintf(stderr, "Order OK\n"); +} diff --git a/libs/openssl/crypto/x509v3/v3_addr.c b/libs/openssl/crypto/x509v3/v3_addr.c new file mode 100644 index 00000000..94cfed05 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_addr.c @@ -0,0 +1,1344 @@ +/* + * Contributed to the OpenSSL Project by the American Registry for + * Internet Numbers ("ARIN"). + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + */ + +/* + * Implementation of RFC 3779 section 2.2. + */ + +#include +#include + +#include "cryptlib.h" +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_RFC3779 + +/* + * OpenSSL ASN.1 template translation of RFC 3779 2.2.3. + */ + +ASN1_SEQUENCE(IPAddressRange) = { + ASN1_SIMPLE(IPAddressRange, min, ASN1_BIT_STRING), + ASN1_SIMPLE(IPAddressRange, max, ASN1_BIT_STRING) +} ASN1_SEQUENCE_END(IPAddressRange) + +ASN1_CHOICE(IPAddressOrRange) = { + ASN1_SIMPLE(IPAddressOrRange, u.addressPrefix, ASN1_BIT_STRING), + ASN1_SIMPLE(IPAddressOrRange, u.addressRange, IPAddressRange) +} ASN1_CHOICE_END(IPAddressOrRange) + +ASN1_CHOICE(IPAddressChoice) = { + ASN1_SIMPLE(IPAddressChoice, u.inherit, ASN1_NULL), + ASN1_SEQUENCE_OF(IPAddressChoice, u.addressesOrRanges, IPAddressOrRange) +} ASN1_CHOICE_END(IPAddressChoice) + +ASN1_SEQUENCE(IPAddressFamily) = { + ASN1_SIMPLE(IPAddressFamily, addressFamily, ASN1_OCTET_STRING), + ASN1_SIMPLE(IPAddressFamily, ipAddressChoice, IPAddressChoice) +} ASN1_SEQUENCE_END(IPAddressFamily) + +ASN1_ITEM_TEMPLATE(IPAddrBlocks) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, + IPAddrBlocks, IPAddressFamily) +ASN1_ITEM_TEMPLATE_END(IPAddrBlocks) + +IMPLEMENT_ASN1_FUNCTIONS(IPAddressRange) +IMPLEMENT_ASN1_FUNCTIONS(IPAddressOrRange) +IMPLEMENT_ASN1_FUNCTIONS(IPAddressChoice) +IMPLEMENT_ASN1_FUNCTIONS(IPAddressFamily) + +/* + * How much buffer space do we need for a raw address? + */ +# define ADDR_RAW_BUF_LEN 16 + +/* + * What's the address length associated with this AFI? + */ +static int length_from_afi(const unsigned afi) +{ + switch (afi) { + case IANA_AFI_IPV4: + return 4; + case IANA_AFI_IPV6: + return 16; + default: + return 0; + } +} + +/* + * Extract the AFI from an IPAddressFamily. + */ +unsigned int v3_addr_get_afi(const IPAddressFamily *f) +{ + return ((f != NULL && + f->addressFamily != NULL && f->addressFamily->data != NULL) + ? ((f->addressFamily->data[0] << 8) | (f->addressFamily->data[1])) + : 0); +} + +/* + * Expand the bitstring form of an address into a raw byte array. + * At the moment this is coded for simplicity, not speed. + */ +static int addr_expand(unsigned char *addr, + const ASN1_BIT_STRING *bs, + const int length, const unsigned char fill) +{ + if (bs->length < 0 || bs->length > length) + return 0; + if (bs->length > 0) { + memcpy(addr, bs->data, bs->length); + if ((bs->flags & 7) != 0) { + unsigned char mask = 0xFF >> (8 - (bs->flags & 7)); + if (fill == 0) + addr[bs->length - 1] &= ~mask; + else + addr[bs->length - 1] |= mask; + } + } + memset(addr + bs->length, fill, length - bs->length); + return 1; +} + +/* + * Extract the prefix length from a bitstring. + */ +# define addr_prefixlen(bs) ((int) ((bs)->length * 8 - ((bs)->flags & 7))) + +/* + * i2r handler for one address bitstring. + */ +static int i2r_address(BIO *out, + const unsigned afi, + const unsigned char fill, const ASN1_BIT_STRING *bs) +{ + unsigned char addr[ADDR_RAW_BUF_LEN]; + int i, n; + + if (bs->length < 0) + return 0; + switch (afi) { + case IANA_AFI_IPV4: + if (!addr_expand(addr, bs, 4, fill)) + return 0; + BIO_printf(out, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); + break; + case IANA_AFI_IPV6: + if (!addr_expand(addr, bs, 16, fill)) + return 0; + for (n = 16; n > 1 && addr[n - 1] == 0x00 && addr[n - 2] == 0x00; + n -= 2) ; + for (i = 0; i < n; i += 2) + BIO_printf(out, "%x%s", (addr[i] << 8) | addr[i + 1], + (i < 14 ? ":" : "")); + if (i < 16) + BIO_puts(out, ":"); + if (i == 0) + BIO_puts(out, ":"); + break; + default: + for (i = 0; i < bs->length; i++) + BIO_printf(out, "%s%02x", (i > 0 ? ":" : ""), bs->data[i]); + BIO_printf(out, "[%d]", (int)(bs->flags & 7)); + break; + } + return 1; +} + +/* + * i2r handler for a sequence of addresses and ranges. + */ +static int i2r_IPAddressOrRanges(BIO *out, + const int indent, + const IPAddressOrRanges *aors, + const unsigned afi) +{ + int i; + for (i = 0; i < sk_IPAddressOrRange_num(aors); i++) { + const IPAddressOrRange *aor = sk_IPAddressOrRange_value(aors, i); + BIO_printf(out, "%*s", indent, ""); + switch (aor->type) { + case IPAddressOrRange_addressPrefix: + if (!i2r_address(out, afi, 0x00, aor->u.addressPrefix)) + return 0; + BIO_printf(out, "/%d\n", addr_prefixlen(aor->u.addressPrefix)); + continue; + case IPAddressOrRange_addressRange: + if (!i2r_address(out, afi, 0x00, aor->u.addressRange->min)) + return 0; + BIO_puts(out, "-"); + if (!i2r_address(out, afi, 0xFF, aor->u.addressRange->max)) + return 0; + BIO_puts(out, "\n"); + continue; + } + } + return 1; +} + +/* + * i2r handler for an IPAddrBlocks extension. + */ +static int i2r_IPAddrBlocks(const X509V3_EXT_METHOD *method, + void *ext, BIO *out, int indent) +{ + const IPAddrBlocks *addr = ext; + int i; + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); + const unsigned int afi = v3_addr_get_afi(f); + switch (afi) { + case IANA_AFI_IPV4: + BIO_printf(out, "%*sIPv4", indent, ""); + break; + case IANA_AFI_IPV6: + BIO_printf(out, "%*sIPv6", indent, ""); + break; + default: + BIO_printf(out, "%*sUnknown AFI %u", indent, "", afi); + break; + } + if (f->addressFamily->length > 2) { + switch (f->addressFamily->data[2]) { + case 1: + BIO_puts(out, " (Unicast)"); + break; + case 2: + BIO_puts(out, " (Multicast)"); + break; + case 3: + BIO_puts(out, " (Unicast/Multicast)"); + break; + case 4: + BIO_puts(out, " (MPLS)"); + break; + case 64: + BIO_puts(out, " (Tunnel)"); + break; + case 65: + BIO_puts(out, " (VPLS)"); + break; + case 66: + BIO_puts(out, " (BGP MDT)"); + break; + case 128: + BIO_puts(out, " (MPLS-labeled VPN)"); + break; + default: + BIO_printf(out, " (Unknown SAFI %u)", + (unsigned)f->addressFamily->data[2]); + break; + } + } + switch (f->ipAddressChoice->type) { + case IPAddressChoice_inherit: + BIO_puts(out, ": inherit\n"); + break; + case IPAddressChoice_addressesOrRanges: + BIO_puts(out, ":\n"); + if (!i2r_IPAddressOrRanges(out, + indent + 2, + f->ipAddressChoice-> + u.addressesOrRanges, afi)) + return 0; + break; + } + } + return 1; +} + +/* + * Sort comparison function for a sequence of IPAddressOrRange + * elements. + * + * There's no sane answer we can give if addr_expand() fails, and an + * assertion failure on externally supplied data is seriously uncool, + * so we just arbitrarily declare that if given invalid inputs this + * function returns -1. If this messes up your preferred sort order + * for garbage input, tough noogies. + */ +static int IPAddressOrRange_cmp(const IPAddressOrRange *a, + const IPAddressOrRange *b, const int length) +{ + unsigned char addr_a[ADDR_RAW_BUF_LEN], addr_b[ADDR_RAW_BUF_LEN]; + int prefixlen_a = 0, prefixlen_b = 0; + int r; + + switch (a->type) { + case IPAddressOrRange_addressPrefix: + if (!addr_expand(addr_a, a->u.addressPrefix, length, 0x00)) + return -1; + prefixlen_a = addr_prefixlen(a->u.addressPrefix); + break; + case IPAddressOrRange_addressRange: + if (!addr_expand(addr_a, a->u.addressRange->min, length, 0x00)) + return -1; + prefixlen_a = length * 8; + break; + } + + switch (b->type) { + case IPAddressOrRange_addressPrefix: + if (!addr_expand(addr_b, b->u.addressPrefix, length, 0x00)) + return -1; + prefixlen_b = addr_prefixlen(b->u.addressPrefix); + break; + case IPAddressOrRange_addressRange: + if (!addr_expand(addr_b, b->u.addressRange->min, length, 0x00)) + return -1; + prefixlen_b = length * 8; + break; + } + + if ((r = memcmp(addr_a, addr_b, length)) != 0) + return r; + else + return prefixlen_a - prefixlen_b; +} + +/* + * IPv4-specific closure over IPAddressOrRange_cmp, since sk_sort() + * comparision routines are only allowed two arguments. + */ +static int v4IPAddressOrRange_cmp(const IPAddressOrRange *const *a, + const IPAddressOrRange *const *b) +{ + return IPAddressOrRange_cmp(*a, *b, 4); +} + +/* + * IPv6-specific closure over IPAddressOrRange_cmp, since sk_sort() + * comparision routines are only allowed two arguments. + */ +static int v6IPAddressOrRange_cmp(const IPAddressOrRange *const *a, + const IPAddressOrRange *const *b) +{ + return IPAddressOrRange_cmp(*a, *b, 16); +} + +/* + * Calculate whether a range collapses to a prefix. + * See last paragraph of RFC 3779 2.2.3.7. + */ +static int range_should_be_prefix(const unsigned char *min, + const unsigned char *max, const int length) +{ + unsigned char mask; + int i, j; + + OPENSSL_assert(memcmp(min, max, length) <= 0); + for (i = 0; i < length && min[i] == max[i]; i++) ; + for (j = length - 1; j >= 0 && min[j] == 0x00 && max[j] == 0xFF; j--) ; + if (i < j) + return -1; + if (i > j) + return i * 8; + mask = min[i] ^ max[i]; + switch (mask) { + case 0x01: + j = 7; + break; + case 0x03: + j = 6; + break; + case 0x07: + j = 5; + break; + case 0x0F: + j = 4; + break; + case 0x1F: + j = 3; + break; + case 0x3F: + j = 2; + break; + case 0x7F: + j = 1; + break; + default: + return -1; + } + if ((min[i] & mask) != 0 || (max[i] & mask) != mask) + return -1; + else + return i * 8 + j; +} + +/* + * Construct a prefix. + */ +static int make_addressPrefix(IPAddressOrRange **result, + unsigned char *addr, const int prefixlen) +{ + int bytelen = (prefixlen + 7) / 8, bitlen = prefixlen % 8; + IPAddressOrRange *aor = IPAddressOrRange_new(); + + if (aor == NULL) + return 0; + aor->type = IPAddressOrRange_addressPrefix; + if (aor->u.addressPrefix == NULL && + (aor->u.addressPrefix = ASN1_BIT_STRING_new()) == NULL) + goto err; + if (!ASN1_BIT_STRING_set(aor->u.addressPrefix, addr, bytelen)) + goto err; + aor->u.addressPrefix->flags &= ~7; + aor->u.addressPrefix->flags |= ASN1_STRING_FLAG_BITS_LEFT; + if (bitlen > 0) { + aor->u.addressPrefix->data[bytelen - 1] &= ~(0xFF >> bitlen); + aor->u.addressPrefix->flags |= 8 - bitlen; + } + + *result = aor; + return 1; + + err: + IPAddressOrRange_free(aor); + return 0; +} + +/* + * Construct a range. If it can be expressed as a prefix, + * return a prefix instead. Doing this here simplifies + * the rest of the code considerably. + */ +static int make_addressRange(IPAddressOrRange **result, + unsigned char *min, + unsigned char *max, const int length) +{ + IPAddressOrRange *aor; + int i, prefixlen; + + if ((prefixlen = range_should_be_prefix(min, max, length)) >= 0) + return make_addressPrefix(result, min, prefixlen); + + if ((aor = IPAddressOrRange_new()) == NULL) + return 0; + aor->type = IPAddressOrRange_addressRange; + OPENSSL_assert(aor->u.addressRange == NULL); + if ((aor->u.addressRange = IPAddressRange_new()) == NULL) + goto err; + if (aor->u.addressRange->min == NULL && + (aor->u.addressRange->min = ASN1_BIT_STRING_new()) == NULL) + goto err; + if (aor->u.addressRange->max == NULL && + (aor->u.addressRange->max = ASN1_BIT_STRING_new()) == NULL) + goto err; + + for (i = length; i > 0 && min[i - 1] == 0x00; --i) ; + if (!ASN1_BIT_STRING_set(aor->u.addressRange->min, min, i)) + goto err; + aor->u.addressRange->min->flags &= ~7; + aor->u.addressRange->min->flags |= ASN1_STRING_FLAG_BITS_LEFT; + if (i > 0) { + unsigned char b = min[i - 1]; + int j = 1; + while ((b & (0xFFU >> j)) != 0) + ++j; + aor->u.addressRange->min->flags |= 8 - j; + } + + for (i = length; i > 0 && max[i - 1] == 0xFF; --i) ; + if (!ASN1_BIT_STRING_set(aor->u.addressRange->max, max, i)) + goto err; + aor->u.addressRange->max->flags &= ~7; + aor->u.addressRange->max->flags |= ASN1_STRING_FLAG_BITS_LEFT; + if (i > 0) { + unsigned char b = max[i - 1]; + int j = 1; + while ((b & (0xFFU >> j)) != (0xFFU >> j)) + ++j; + aor->u.addressRange->max->flags |= 8 - j; + } + + *result = aor; + return 1; + + err: + IPAddressOrRange_free(aor); + return 0; +} + +/* + * Construct a new address family or find an existing one. + */ +static IPAddressFamily *make_IPAddressFamily(IPAddrBlocks *addr, + const unsigned afi, + const unsigned *safi) +{ + IPAddressFamily *f; + unsigned char key[3]; + unsigned keylen; + int i; + + key[0] = (afi >> 8) & 0xFF; + key[1] = afi & 0xFF; + if (safi != NULL) { + key[2] = *safi & 0xFF; + keylen = 3; + } else { + keylen = 2; + } + + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + f = sk_IPAddressFamily_value(addr, i); + OPENSSL_assert(f->addressFamily->data != NULL); + if (f->addressFamily->length == keylen && + !memcmp(f->addressFamily->data, key, keylen)) + return f; + } + + if ((f = IPAddressFamily_new()) == NULL) + goto err; + if (f->ipAddressChoice == NULL && + (f->ipAddressChoice = IPAddressChoice_new()) == NULL) + goto err; + if (f->addressFamily == NULL && + (f->addressFamily = ASN1_OCTET_STRING_new()) == NULL) + goto err; + if (!ASN1_OCTET_STRING_set(f->addressFamily, key, keylen)) + goto err; + if (!sk_IPAddressFamily_push(addr, f)) + goto err; + + return f; + + err: + IPAddressFamily_free(f); + return NULL; +} + +/* + * Add an inheritance element. + */ +int v3_addr_add_inherit(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi) +{ + IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); + if (f == NULL || + f->ipAddressChoice == NULL || + (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && + f->ipAddressChoice->u.addressesOrRanges != NULL)) + return 0; + if (f->ipAddressChoice->type == IPAddressChoice_inherit && + f->ipAddressChoice->u.inherit != NULL) + return 1; + if (f->ipAddressChoice->u.inherit == NULL && + (f->ipAddressChoice->u.inherit = ASN1_NULL_new()) == NULL) + return 0; + f->ipAddressChoice->type = IPAddressChoice_inherit; + return 1; +} + +/* + * Construct an IPAddressOrRange sequence, or return an existing one. + */ +static IPAddressOrRanges *make_prefix_or_range(IPAddrBlocks *addr, + const unsigned afi, + const unsigned *safi) +{ + IPAddressFamily *f = make_IPAddressFamily(addr, afi, safi); + IPAddressOrRanges *aors = NULL; + + if (f == NULL || + f->ipAddressChoice == NULL || + (f->ipAddressChoice->type == IPAddressChoice_inherit && + f->ipAddressChoice->u.inherit != NULL)) + return NULL; + if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges) + aors = f->ipAddressChoice->u.addressesOrRanges; + if (aors != NULL) + return aors; + if ((aors = sk_IPAddressOrRange_new_null()) == NULL) + return NULL; + switch (afi) { + case IANA_AFI_IPV4: + (void)sk_IPAddressOrRange_set_cmp_func(aors, v4IPAddressOrRange_cmp); + break; + case IANA_AFI_IPV6: + (void)sk_IPAddressOrRange_set_cmp_func(aors, v6IPAddressOrRange_cmp); + break; + } + f->ipAddressChoice->type = IPAddressChoice_addressesOrRanges; + f->ipAddressChoice->u.addressesOrRanges = aors; + return aors; +} + +/* + * Add a prefix. + */ +int v3_addr_add_prefix(IPAddrBlocks *addr, + const unsigned afi, + const unsigned *safi, + unsigned char *a, const int prefixlen) +{ + IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); + IPAddressOrRange *aor; + if (aors == NULL || !make_addressPrefix(&aor, a, prefixlen)) + return 0; + if (sk_IPAddressOrRange_push(aors, aor)) + return 1; + IPAddressOrRange_free(aor); + return 0; +} + +/* + * Add a range. + */ +int v3_addr_add_range(IPAddrBlocks *addr, + const unsigned afi, + const unsigned *safi, + unsigned char *min, unsigned char *max) +{ + IPAddressOrRanges *aors = make_prefix_or_range(addr, afi, safi); + IPAddressOrRange *aor; + int length = length_from_afi(afi); + if (aors == NULL) + return 0; + if (!make_addressRange(&aor, min, max, length)) + return 0; + if (sk_IPAddressOrRange_push(aors, aor)) + return 1; + IPAddressOrRange_free(aor); + return 0; +} + +/* + * Extract min and max values from an IPAddressOrRange. + */ +static int extract_min_max(IPAddressOrRange *aor, + unsigned char *min, unsigned char *max, int length) +{ + if (aor == NULL || min == NULL || max == NULL) + return 0; + switch (aor->type) { + case IPAddressOrRange_addressPrefix: + return (addr_expand(min, aor->u.addressPrefix, length, 0x00) && + addr_expand(max, aor->u.addressPrefix, length, 0xFF)); + case IPAddressOrRange_addressRange: + return (addr_expand(min, aor->u.addressRange->min, length, 0x00) && + addr_expand(max, aor->u.addressRange->max, length, 0xFF)); + } + return 0; +} + +/* + * Public wrapper for extract_min_max(). + */ +int v3_addr_get_range(IPAddressOrRange *aor, + const unsigned afi, + unsigned char *min, + unsigned char *max, const int length) +{ + int afi_length = length_from_afi(afi); + if (aor == NULL || min == NULL || max == NULL || + afi_length == 0 || length < afi_length || + (aor->type != IPAddressOrRange_addressPrefix && + aor->type != IPAddressOrRange_addressRange) || + !extract_min_max(aor, min, max, afi_length)) + return 0; + + return afi_length; +} + +/* + * Sort comparision function for a sequence of IPAddressFamily. + * + * The last paragraph of RFC 3779 2.2.3.3 is slightly ambiguous about + * the ordering: I can read it as meaning that IPv6 without a SAFI + * comes before IPv4 with a SAFI, which seems pretty weird. The + * examples in appendix B suggest that the author intended the + * null-SAFI rule to apply only within a single AFI, which is what I + * would have expected and is what the following code implements. + */ +static int IPAddressFamily_cmp(const IPAddressFamily *const *a_, + const IPAddressFamily *const *b_) +{ + const ASN1_OCTET_STRING *a = (*a_)->addressFamily; + const ASN1_OCTET_STRING *b = (*b_)->addressFamily; + int len = ((a->length <= b->length) ? a->length : b->length); + int cmp = memcmp(a->data, b->data, len); + return cmp ? cmp : a->length - b->length; +} + +/* + * Check whether an IPAddrBLocks is in canonical form. + */ +int v3_addr_is_canonical(IPAddrBlocks *addr) +{ + unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; + unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; + IPAddressOrRanges *aors; + int i, j, k; + + /* + * Empty extension is cannonical. + */ + if (addr == NULL) + return 1; + + /* + * Check whether the top-level list is in order. + */ + for (i = 0; i < sk_IPAddressFamily_num(addr) - 1; i++) { + const IPAddressFamily *a = sk_IPAddressFamily_value(addr, i); + const IPAddressFamily *b = sk_IPAddressFamily_value(addr, i + 1); + if (IPAddressFamily_cmp(&a, &b) >= 0) + return 0; + } + + /* + * Top level's ok, now check each address family. + */ + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); + int length = length_from_afi(v3_addr_get_afi(f)); + + /* + * Inheritance is canonical. Anything other than inheritance or + * a SEQUENCE OF IPAddressOrRange is an ASN.1 error or something. + */ + if (f == NULL || f->ipAddressChoice == NULL) + return 0; + switch (f->ipAddressChoice->type) { + case IPAddressChoice_inherit: + continue; + case IPAddressChoice_addressesOrRanges: + break; + default: + return 0; + } + + /* + * It's an IPAddressOrRanges sequence, check it. + */ + aors = f->ipAddressChoice->u.addressesOrRanges; + if (sk_IPAddressOrRange_num(aors) == 0) + return 0; + for (j = 0; j < sk_IPAddressOrRange_num(aors) - 1; j++) { + IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); + IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, j + 1); + + if (!extract_min_max(a, a_min, a_max, length) || + !extract_min_max(b, b_min, b_max, length)) + return 0; + + /* + * Punt misordered list, overlapping start, or inverted range. + */ + if (memcmp(a_min, b_min, length) >= 0 || + memcmp(a_min, a_max, length) > 0 || + memcmp(b_min, b_max, length) > 0) + return 0; + + /* + * Punt if adjacent or overlapping. Check for adjacency by + * subtracting one from b_min first. + */ + for (k = length - 1; k >= 0 && b_min[k]-- == 0x00; k--) ; + if (memcmp(a_max, b_min, length) >= 0) + return 0; + + /* + * Check for range that should be expressed as a prefix. + */ + if (a->type == IPAddressOrRange_addressRange && + range_should_be_prefix(a_min, a_max, length) >= 0) + return 0; + } + + /* + * Check range to see if it's inverted or should be a + * prefix. + */ + j = sk_IPAddressOrRange_num(aors) - 1; + { + IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); + if (a != NULL && a->type == IPAddressOrRange_addressRange) { + if (!extract_min_max(a, a_min, a_max, length)) + return 0; + if (memcmp(a_min, a_max, length) > 0 || + range_should_be_prefix(a_min, a_max, length) >= 0) + return 0; + } + } + } + + /* + * If we made it through all that, we're happy. + */ + return 1; +} + +/* + * Whack an IPAddressOrRanges into canonical form. + */ +static int IPAddressOrRanges_canonize(IPAddressOrRanges *aors, + const unsigned afi) +{ + int i, j, length = length_from_afi(afi); + + /* + * Sort the IPAddressOrRanges sequence. + */ + sk_IPAddressOrRange_sort(aors); + + /* + * Clean up representation issues, punt on duplicates or overlaps. + */ + for (i = 0; i < sk_IPAddressOrRange_num(aors) - 1; i++) { + IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, i); + IPAddressOrRange *b = sk_IPAddressOrRange_value(aors, i + 1); + unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; + unsigned char b_min[ADDR_RAW_BUF_LEN], b_max[ADDR_RAW_BUF_LEN]; + + if (!extract_min_max(a, a_min, a_max, length) || + !extract_min_max(b, b_min, b_max, length)) + return 0; + + /* + * Punt inverted ranges. + */ + if (memcmp(a_min, a_max, length) > 0 || + memcmp(b_min, b_max, length) > 0) + return 0; + + /* + * Punt overlaps. + */ + if (memcmp(a_max, b_min, length) >= 0) + return 0; + + /* + * Merge if a and b are adjacent. We check for + * adjacency by subtracting one from b_min first. + */ + for (j = length - 1; j >= 0 && b_min[j]-- == 0x00; j--) ; + if (memcmp(a_max, b_min, length) == 0) { + IPAddressOrRange *merged; + if (!make_addressRange(&merged, a_min, b_max, length)) + return 0; + (void)sk_IPAddressOrRange_set(aors, i, merged); + (void)sk_IPAddressOrRange_delete(aors, i + 1); + IPAddressOrRange_free(a); + IPAddressOrRange_free(b); + --i; + continue; + } + } + + /* + * Check for inverted final range. + */ + j = sk_IPAddressOrRange_num(aors) - 1; + { + IPAddressOrRange *a = sk_IPAddressOrRange_value(aors, j); + if (a != NULL && a->type == IPAddressOrRange_addressRange) { + unsigned char a_min[ADDR_RAW_BUF_LEN], a_max[ADDR_RAW_BUF_LEN]; + extract_min_max(a, a_min, a_max, length); + if (memcmp(a_min, a_max, length) > 0) + return 0; + } + } + + return 1; +} + +/* + * Whack an IPAddrBlocks extension into canonical form. + */ +int v3_addr_canonize(IPAddrBlocks *addr) +{ + int i; + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); + if (f->ipAddressChoice->type == IPAddressChoice_addressesOrRanges && + !IPAddressOrRanges_canonize(f->ipAddressChoice-> + u.addressesOrRanges, + v3_addr_get_afi(f))) + return 0; + } + (void)sk_IPAddressFamily_set_cmp_func(addr, IPAddressFamily_cmp); + sk_IPAddressFamily_sort(addr); + OPENSSL_assert(v3_addr_is_canonical(addr)); + return 1; +} + +/* + * v2i handler for the IPAddrBlocks extension. + */ +static void *v2i_IPAddrBlocks(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values) +{ + static const char v4addr_chars[] = "0123456789."; + static const char v6addr_chars[] = "0123456789.:abcdefABCDEF"; + IPAddrBlocks *addr = NULL; + char *s = NULL, *t; + int i; + + if ((addr = sk_IPAddressFamily_new(IPAddressFamily_cmp)) == NULL) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + CONF_VALUE *val = sk_CONF_VALUE_value(values, i); + unsigned char min[ADDR_RAW_BUF_LEN], max[ADDR_RAW_BUF_LEN]; + unsigned afi, *safi = NULL, safi_; + const char *addr_chars; + int prefixlen, i1, i2, delim, length; + + if (!name_cmp(val->name, "IPv4")) { + afi = IANA_AFI_IPV4; + } else if (!name_cmp(val->name, "IPv6")) { + afi = IANA_AFI_IPV6; + } else if (!name_cmp(val->name, "IPv4-SAFI")) { + afi = IANA_AFI_IPV4; + safi = &safi_; + } else if (!name_cmp(val->name, "IPv6-SAFI")) { + afi = IANA_AFI_IPV6; + safi = &safi_; + } else { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_NAME_ERROR); + X509V3_conf_err(val); + goto err; + } + + switch (afi) { + case IANA_AFI_IPV4: + addr_chars = v4addr_chars; + break; + case IANA_AFI_IPV6: + addr_chars = v6addr_chars; + break; + } + + length = length_from_afi(afi); + + /* + * Handle SAFI, if any, and BUF_strdup() so we can null-terminate + * the other input values. + */ + if (safi != NULL) { + *safi = strtoul(val->value, &t, 0); + t += strspn(t, " \t"); + if (*safi > 0xFF || *t++ != ':') { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_SAFI); + X509V3_conf_err(val); + goto err; + } + t += strspn(t, " \t"); + s = BUF_strdup(t); + } else { + s = BUF_strdup(val->value); + } + if (s == NULL) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * Check for inheritance. Not worth additional complexity to + * optimize this (seldom-used) case. + */ + if (!strcmp(s, "inherit")) { + if (!v3_addr_add_inherit(addr, afi, safi)) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_INVALID_INHERITANCE); + X509V3_conf_err(val); + goto err; + } + OPENSSL_free(s); + s = NULL; + continue; + } + + i1 = strspn(s, addr_chars); + i2 = i1 + strspn(s + i1, " \t"); + delim = s[i2++]; + s[i1] = '\0'; + + if (a2i_ipadd(min, s) != length) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, X509V3_R_INVALID_IPADDRESS); + X509V3_conf_err(val); + goto err; + } + + switch (delim) { + case '/': + prefixlen = (int)strtoul(s + i2, &t, 10); + if (t == s + i2 || *t != '\0') { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + if (!v3_addr_add_prefix(addr, afi, safi, min, prefixlen)) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + goto err; + } + break; + case '-': + i1 = i2 + strspn(s + i2, " \t"); + i2 = i1 + strspn(s + i1, addr_chars); + if (i1 == i2 || s[i2] != '\0') { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + if (a2i_ipadd(max, s + i1) != length) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_INVALID_IPADDRESS); + X509V3_conf_err(val); + goto err; + } + if (memcmp(min, max, length_from_afi(afi)) > 0) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + if (!v3_addr_add_range(addr, afi, safi, min, max)) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + goto err; + } + break; + case '\0': + if (!v3_addr_add_prefix(addr, afi, safi, min, length * 8)) { + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, ERR_R_MALLOC_FAILURE); + goto err; + } + break; + default: + X509V3err(X509V3_F_V2I_IPADDRBLOCKS, + X509V3_R_EXTENSION_VALUE_ERROR); + X509V3_conf_err(val); + goto err; + } + + OPENSSL_free(s); + s = NULL; + } + + /* + * Canonize the result, then we're done. + */ + if (!v3_addr_canonize(addr)) + goto err; + return addr; + + err: + OPENSSL_free(s); + sk_IPAddressFamily_pop_free(addr, IPAddressFamily_free); + return NULL; +} + +/* + * OpenSSL dispatch + */ +const X509V3_EXT_METHOD v3_addr = { + NID_sbgp_ipAddrBlock, /* nid */ + 0, /* flags */ + ASN1_ITEM_ref(IPAddrBlocks), /* template */ + 0, 0, 0, 0, /* old functions, ignored */ + 0, /* i2s */ + 0, /* s2i */ + 0, /* i2v */ + v2i_IPAddrBlocks, /* v2i */ + i2r_IPAddrBlocks, /* i2r */ + 0, /* r2i */ + NULL /* extension-specific data */ +}; + +/* + * Figure out whether extension sues inheritance. + */ +int v3_addr_inherits(IPAddrBlocks *addr) +{ + int i; + if (addr == NULL) + return 0; + for (i = 0; i < sk_IPAddressFamily_num(addr); i++) { + IPAddressFamily *f = sk_IPAddressFamily_value(addr, i); + if (f->ipAddressChoice->type == IPAddressChoice_inherit) + return 1; + } + return 0; +} + +/* + * Figure out whether parent contains child. + */ +static int addr_contains(IPAddressOrRanges *parent, + IPAddressOrRanges *child, int length) +{ + unsigned char p_min[ADDR_RAW_BUF_LEN], p_max[ADDR_RAW_BUF_LEN]; + unsigned char c_min[ADDR_RAW_BUF_LEN], c_max[ADDR_RAW_BUF_LEN]; + int p, c; + + if (child == NULL || parent == child) + return 1; + if (parent == NULL) + return 0; + + p = 0; + for (c = 0; c < sk_IPAddressOrRange_num(child); c++) { + if (!extract_min_max(sk_IPAddressOrRange_value(child, c), + c_min, c_max, length)) + return -1; + for (;; p++) { + if (p >= sk_IPAddressOrRange_num(parent)) + return 0; + if (!extract_min_max(sk_IPAddressOrRange_value(parent, p), + p_min, p_max, length)) + return 0; + if (memcmp(p_max, c_max, length) < 0) + continue; + if (memcmp(p_min, c_min, length) > 0) + return 0; + break; + } + } + + return 1; +} + +/* + * Test whether a is a subset of b. + */ +int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b) +{ + int i; + if (a == NULL || a == b) + return 1; + if (b == NULL || v3_addr_inherits(a) || v3_addr_inherits(b)) + return 0; + (void)sk_IPAddressFamily_set_cmp_func(b, IPAddressFamily_cmp); + for (i = 0; i < sk_IPAddressFamily_num(a); i++) { + IPAddressFamily *fa = sk_IPAddressFamily_value(a, i); + int j = sk_IPAddressFamily_find(b, fa); + IPAddressFamily *fb; + fb = sk_IPAddressFamily_value(b, j); + if (fb == NULL) + return 0; + if (!addr_contains(fb->ipAddressChoice->u.addressesOrRanges, + fa->ipAddressChoice->u.addressesOrRanges, + length_from_afi(v3_addr_get_afi(fb)))) + return 0; + } + return 1; +} + +/* + * Validation error handling via callback. + */ +# define validation_err(_err_) \ + do { \ + if (ctx != NULL) { \ + ctx->error = _err_; \ + ctx->error_depth = i; \ + ctx->current_cert = x; \ + ret = ctx->verify_cb(0, ctx); \ + } else { \ + ret = 0; \ + } \ + if (!ret) \ + goto done; \ + } while (0) + +/* + * Core code for RFC 3779 2.3 path validation. + */ +static int v3_addr_validate_path_internal(X509_STORE_CTX *ctx, + STACK_OF(X509) *chain, + IPAddrBlocks *ext) +{ + IPAddrBlocks *child = NULL; + int i, j, ret = 1; + X509 *x; + + OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); + OPENSSL_assert(ctx != NULL || ext != NULL); + OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); + + /* + * Figure out where to start. If we don't have an extension to + * check, we're done. Otherwise, check canonical form and + * set up for walking up the chain. + */ + if (ext != NULL) { + i = -1; + x = NULL; + } else { + i = 0; + x = sk_X509_value(chain, i); + OPENSSL_assert(x != NULL); + if ((ext = x->rfc3779_addr) == NULL) + goto done; + } + if (!v3_addr_is_canonical(ext)) + validation_err(X509_V_ERR_INVALID_EXTENSION); + (void)sk_IPAddressFamily_set_cmp_func(ext, IPAddressFamily_cmp); + if ((child = sk_IPAddressFamily_dup(ext)) == NULL) { + X509V3err(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL, + ERR_R_MALLOC_FAILURE); + ret = 0; + goto done; + } + + /* + * Now walk up the chain. No cert may list resources that its + * parent doesn't list. + */ + for (i++; i < sk_X509_num(chain); i++) { + x = sk_X509_value(chain, i); + OPENSSL_assert(x != NULL); + if (!v3_addr_is_canonical(x->rfc3779_addr)) + validation_err(X509_V_ERR_INVALID_EXTENSION); + if (x->rfc3779_addr == NULL) { + for (j = 0; j < sk_IPAddressFamily_num(child); j++) { + IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); + if (fc->ipAddressChoice->type != IPAddressChoice_inherit) { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + break; + } + } + continue; + } + (void)sk_IPAddressFamily_set_cmp_func(x->rfc3779_addr, + IPAddressFamily_cmp); + for (j = 0; j < sk_IPAddressFamily_num(child); j++) { + IPAddressFamily *fc = sk_IPAddressFamily_value(child, j); + int k = sk_IPAddressFamily_find(x->rfc3779_addr, fc); + IPAddressFamily *fp = + sk_IPAddressFamily_value(x->rfc3779_addr, k); + if (fp == NULL) { + if (fc->ipAddressChoice->type == + IPAddressChoice_addressesOrRanges) { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + break; + } + continue; + } + if (fp->ipAddressChoice->type == + IPAddressChoice_addressesOrRanges) { + if (fc->ipAddressChoice->type == IPAddressChoice_inherit + || addr_contains(fp->ipAddressChoice->u.addressesOrRanges, + fc->ipAddressChoice->u.addressesOrRanges, + length_from_afi(v3_addr_get_afi(fc)))) + sk_IPAddressFamily_set(child, j, fp); + else + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + } + } + + /* + * Trust anchor can't inherit. + */ + OPENSSL_assert(x != NULL); + if (x->rfc3779_addr != NULL) { + for (j = 0; j < sk_IPAddressFamily_num(x->rfc3779_addr); j++) { + IPAddressFamily *fp = + sk_IPAddressFamily_value(x->rfc3779_addr, j); + if (fp->ipAddressChoice->type == IPAddressChoice_inherit + && sk_IPAddressFamily_find(child, fp) >= 0) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + } + + done: + sk_IPAddressFamily_free(child); + return ret; +} + +# undef validation_err + +/* + * RFC 3779 2.3 path validation -- called from X509_verify_cert(). + */ +int v3_addr_validate_path(X509_STORE_CTX *ctx) +{ + return v3_addr_validate_path_internal(ctx, ctx->chain, NULL); +} + +/* + * RFC 3779 2.3 path validation of an extension. + * Test whether chain covers extension. + */ +int v3_addr_validate_resource_set(STACK_OF(X509) *chain, + IPAddrBlocks *ext, int allow_inheritance) +{ + if (ext == NULL) + return 1; + if (chain == NULL || sk_X509_num(chain) == 0) + return 0; + if (!allow_inheritance && v3_addr_inherits(ext)) + return 0; + return v3_addr_validate_path_internal(NULL, chain, ext); +} + +#endif /* OPENSSL_NO_RFC3779 */ diff --git a/libs/openssl/crypto/x509v3/v3_akey.c b/libs/openssl/crypto/x509v3/v3_akey.c new file mode 100644 index 00000000..e920270e --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_akey.c @@ -0,0 +1,205 @@ +/* v3_akey.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + AUTHORITY_KEYID *akeyid, + STACK_OF(CONF_VALUE) + *extlist); +static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_akey_id = { + NID_authority_key_identifier, + X509V3_EXT_MULTILINE, ASN1_ITEM_ref(AUTHORITY_KEYID), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_AUTHORITY_KEYID, + (X509V3_EXT_V2I)v2i_AUTHORITY_KEYID, + 0, 0, + NULL +}; + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + AUTHORITY_KEYID *akeyid, + STACK_OF(CONF_VALUE) + *extlist) +{ + char *tmp; + if (akeyid->keyid) { + tmp = hex_to_string(akeyid->keyid->data, akeyid->keyid->length); + X509V3_add_value("keyid", tmp, &extlist); + OPENSSL_free(tmp); + } + if (akeyid->issuer) + extlist = i2v_GENERAL_NAMES(NULL, akeyid->issuer, extlist); + if (akeyid->serial) { + tmp = hex_to_string(akeyid->serial->data, akeyid->serial->length); + X509V3_add_value("serial", tmp, &extlist); + OPENSSL_free(tmp); + } + return extlist; +} + +/*- + * Currently two options: + * keyid: use the issuers subject keyid, the value 'always' means its is + * an error if the issuer certificate doesn't have a key id. + * issuer: use the issuers cert issuer and serial number. The default is + * to only use this if keyid is not present. With the option 'always' + * this is always included. + */ + +static AUTHORITY_KEYID *v2i_AUTHORITY_KEYID(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + char keyid = 0, issuer = 0; + int i; + CONF_VALUE *cnf; + ASN1_OCTET_STRING *ikeyid = NULL; + X509_NAME *isname = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen = NULL; + ASN1_INTEGER *serial = NULL; + X509_EXTENSION *ext; + X509 *cert; + AUTHORITY_KEYID *akeyid; + + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + cnf = sk_CONF_VALUE_value(values, i); + if (!strcmp(cnf->name, "keyid")) { + keyid = 1; + if (cnf->value && !strcmp(cnf->value, "always")) + keyid = 2; + } else if (!strcmp(cnf->name, "issuer")) { + issuer = 1; + if (cnf->value && !strcmp(cnf->value, "always")) + issuer = 2; + } else { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, X509V3_R_UNKNOWN_OPTION); + ERR_add_error_data(2, "name=", cnf->name); + return NULL; + } + } + + if (!ctx || !ctx->issuer_cert) { + if (ctx && (ctx->flags == CTX_TEST)) + return AUTHORITY_KEYID_new(); + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + X509V3_R_NO_ISSUER_CERTIFICATE); + return NULL; + } + + cert = ctx->issuer_cert; + + if (keyid) { + i = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); + if ((i >= 0) && (ext = X509_get_ext(cert, i))) + ikeyid = X509V3_EXT_d2i(ext); + if (keyid == 2 && !ikeyid) { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + X509V3_R_UNABLE_TO_GET_ISSUER_KEYID); + return NULL; + } + } + + if ((issuer && !ikeyid) || (issuer == 2)) { + isname = X509_NAME_dup(X509_get_issuer_name(cert)); + serial = M_ASN1_INTEGER_dup(X509_get_serialNumber(cert)); + if (!isname || !serial) { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, + X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS); + goto err; + } + } + + if (!(akeyid = AUTHORITY_KEYID_new())) + goto err; + + if (isname) { + if (!(gens = sk_GENERAL_NAME_new_null()) + || !(gen = GENERAL_NAME_new()) + || !sk_GENERAL_NAME_push(gens, gen)) { + X509V3err(X509V3_F_V2I_AUTHORITY_KEYID, ERR_R_MALLOC_FAILURE); + goto err; + } + gen->type = GEN_DIRNAME; + gen->d.dirn = isname; + } + + akeyid->issuer = gens; + akeyid->serial = serial; + akeyid->keyid = ikeyid; + + return akeyid; + + err: + X509_NAME_free(isname); + M_ASN1_INTEGER_free(serial); + M_ASN1_OCTET_STRING_free(ikeyid); + return NULL; +} diff --git a/libs/openssl/crypto/x509v3/v3_akeya.c b/libs/openssl/crypto/x509v3/v3_akeya.c new file mode 100644 index 00000000..2cc85b76 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_akeya.c @@ -0,0 +1,73 @@ +/* v3_akey_asn1.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +ASN1_SEQUENCE(AUTHORITY_KEYID) = { + ASN1_IMP_OPT(AUTHORITY_KEYID, keyid, ASN1_OCTET_STRING, 0), + ASN1_IMP_SEQUENCE_OF_OPT(AUTHORITY_KEYID, issuer, GENERAL_NAME, 1), + ASN1_IMP_OPT(AUTHORITY_KEYID, serial, ASN1_INTEGER, 2) +} ASN1_SEQUENCE_END(AUTHORITY_KEYID) + +IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_KEYID) diff --git a/libs/openssl/crypto/x509v3/v3_alt.c b/libs/openssl/crypto/x509v3/v3_alt.c new file mode 100644 index 00000000..22ec2028 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_alt.c @@ -0,0 +1,609 @@ +/* v3_alt.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include + +static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p); +static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens); +static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); +static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx); + +const X509V3_EXT_METHOD v3_alt[] = { + {NID_subject_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_GENERAL_NAMES, + (X509V3_EXT_V2I)v2i_subject_alt, + NULL, NULL, NULL}, + + {NID_issuer_alt_name, 0, ASN1_ITEM_ref(GENERAL_NAMES), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_GENERAL_NAMES, + (X509V3_EXT_V2I)v2i_issuer_alt, + NULL, NULL, NULL}, + + {NID_certificate_issuer, 0, ASN1_ITEM_ref(GENERAL_NAMES), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_GENERAL_NAMES, + NULL, NULL, NULL, NULL}, +}; + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, + GENERAL_NAMES *gens, + STACK_OF(CONF_VALUE) *ret) +{ + int i; + GENERAL_NAME *gen; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gen = sk_GENERAL_NAME_value(gens, i); + ret = i2v_GENERAL_NAME(method, gen, ret); + } + if (!ret) + return sk_CONF_VALUE_new_null(); + return ret; +} + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, + GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret) +{ + unsigned char *p; + char oline[256], htmp[5]; + int i; + switch (gen->type) { + case GEN_OTHERNAME: + X509V3_add_value("othername", "", &ret); + break; + + case GEN_X400: + X509V3_add_value("X400Name", "", &ret); + break; + + case GEN_EDIPARTY: + X509V3_add_value("EdiPartyName", "", &ret); + break; + + case GEN_EMAIL: + X509V3_add_value_uchar("email", gen->d.ia5->data, &ret); + break; + + case GEN_DNS: + X509V3_add_value_uchar("DNS", gen->d.ia5->data, &ret); + break; + + case GEN_URI: + X509V3_add_value_uchar("URI", gen->d.ia5->data, &ret); + break; + + case GEN_DIRNAME: + X509_NAME_oneline(gen->d.dirn, oline, 256); + X509V3_add_value("DirName", oline, &ret); + break; + + case GEN_IPADD: + p = gen->d.ip->data; + if (gen->d.ip->length == 4) + BIO_snprintf(oline, sizeof oline, + "%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + else if (gen->d.ip->length == 16) { + oline[0] = 0; + for (i = 0; i < 8; i++) { + BIO_snprintf(htmp, sizeof htmp, "%X", p[0] << 8 | p[1]); + p += 2; + strcat(oline, htmp); + if (i != 7) + strcat(oline, ":"); + } + } else { + X509V3_add_value("IP Address", "", &ret); + break; + } + X509V3_add_value("IP Address", oline, &ret); + break; + + case GEN_RID: + i2t_ASN1_OBJECT(oline, 256, gen->d.rid); + X509V3_add_value("Registered ID", oline, &ret); + break; + } + return ret; +} + +int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen) +{ + unsigned char *p; + int i; + switch (gen->type) { + case GEN_OTHERNAME: + BIO_printf(out, "othername:"); + break; + + case GEN_X400: + BIO_printf(out, "X400Name:"); + break; + + case GEN_EDIPARTY: + /* Maybe fix this: it is supported now */ + BIO_printf(out, "EdiPartyName:"); + break; + + case GEN_EMAIL: + BIO_printf(out, "email:%s", gen->d.ia5->data); + break; + + case GEN_DNS: + BIO_printf(out, "DNS:%s", gen->d.ia5->data); + break; + + case GEN_URI: + BIO_printf(out, "URI:%s", gen->d.ia5->data); + break; + + case GEN_DIRNAME: + BIO_printf(out, "DirName: "); + X509_NAME_print_ex(out, gen->d.dirn, 0, XN_FLAG_ONELINE); + break; + + case GEN_IPADD: + p = gen->d.ip->data; + if (gen->d.ip->length == 4) + BIO_printf(out, "IP Address:%d.%d.%d.%d", p[0], p[1], p[2], p[3]); + else if (gen->d.ip->length == 16) { + BIO_printf(out, "IP Address"); + for (i = 0; i < 8; i++) { + BIO_printf(out, ":%X", p[0] << 8 | p[1]); + p += 2; + } + BIO_puts(out, "\n"); + } else { + BIO_printf(out, "IP Address:"); + break; + } + break; + + case GEN_RID: + BIO_printf(out, "Registered ID"); + i2a_ASN1_OBJECT(out, gen->d.rid); + break; + } + return 1; +} + +static GENERAL_NAMES *v2i_issuer_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + int i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + X509V3err(X509V3_F_V2I_ISSUER_ALT, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!name_cmp(cnf->name, "issuer") && cnf->value && + !strcmp(cnf->value, "copy")) { + if (!copy_issuer(ctx, gens)) + goto err; + } else { + GENERAL_NAME *gen; + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + sk_GENERAL_NAME_push(gens, gen); + } + } + return gens; + err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +/* Append subject altname of issuer to issuer alt name of subject */ + +static int copy_issuer(X509V3_CTX *ctx, GENERAL_NAMES *gens) +{ + GENERAL_NAMES *ialt; + GENERAL_NAME *gen; + X509_EXTENSION *ext; + int i; + if (ctx && (ctx->flags == CTX_TEST)) + return 1; + if (!ctx || !ctx->issuer_cert) { + X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_NO_ISSUER_DETAILS); + goto err; + } + i = X509_get_ext_by_NID(ctx->issuer_cert, NID_subject_alt_name, -1); + if (i < 0) + return 1; + if (!(ext = X509_get_ext(ctx->issuer_cert, i)) || + !(ialt = X509V3_EXT_d2i(ext))) { + X509V3err(X509V3_F_COPY_ISSUER, X509V3_R_ISSUER_DECODE_ERROR); + goto err; + } + + for (i = 0; i < sk_GENERAL_NAME_num(ialt); i++) { + gen = sk_GENERAL_NAME_value(ialt, i); + if (!sk_GENERAL_NAME_push(gens, gen)) { + X509V3err(X509V3_F_COPY_ISSUER, ERR_R_MALLOC_FAILURE); + goto err; + } + } + sk_GENERAL_NAME_free(ialt); + + return 1; + + err: + return 0; + +} + +static GENERAL_NAMES *v2i_subject_alt(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + int i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + X509V3err(X509V3_F_V2I_SUBJECT_ALT, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!name_cmp(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "copy")) { + if (!copy_email(ctx, gens, 0)) + goto err; + } else if (!name_cmp(cnf->name, "email") && cnf->value && + !strcmp(cnf->value, "move")) { + if (!copy_email(ctx, gens, 1)) + goto err; + } else { + GENERAL_NAME *gen; + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + sk_GENERAL_NAME_push(gens, gen); + } + } + return gens; + err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +/* + * Copy any email addresses in a certificate or request to GENERAL_NAMES + */ + +static int copy_email(X509V3_CTX *ctx, GENERAL_NAMES *gens, int move_p) +{ + X509_NAME *nm; + ASN1_IA5STRING *email = NULL; + X509_NAME_ENTRY *ne; + GENERAL_NAME *gen = NULL; + int i; + if (ctx != NULL && ctx->flags == CTX_TEST) + return 1; + if (!ctx || (!ctx->subject_cert && !ctx->subject_req)) { + X509V3err(X509V3_F_COPY_EMAIL, X509V3_R_NO_SUBJECT_DETAILS); + goto err; + } + /* Find the subject name */ + if (ctx->subject_cert) + nm = X509_get_subject_name(ctx->subject_cert); + else + nm = X509_REQ_get_subject_name(ctx->subject_req); + + /* Now add any email address(es) to STACK */ + i = -1; + while ((i = X509_NAME_get_index_by_NID(nm, + NID_pkcs9_emailAddress, i)) >= 0) { + ne = X509_NAME_get_entry(nm, i); + email = M_ASN1_IA5STRING_dup(X509_NAME_ENTRY_get_data(ne)); + if (move_p) { + X509_NAME_delete_entry(nm, i); + X509_NAME_ENTRY_free(ne); + i--; + } + if (!email || !(gen = GENERAL_NAME_new())) { + X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); + goto err; + } + gen->d.ia5 = email; + email = NULL; + gen->type = GEN_EMAIL; + if (!sk_GENERAL_NAME_push(gens, gen)) { + X509V3err(X509V3_F_COPY_EMAIL, ERR_R_MALLOC_FAILURE); + goto err; + } + gen = NULL; + } + + return 1; + + err: + GENERAL_NAME_free(gen); + M_ASN1_IA5STRING_free(email); + return 0; + +} + +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + GENERAL_NAME *gen; + GENERAL_NAMES *gens = NULL; + CONF_VALUE *cnf; + int i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + X509V3err(X509V3_F_V2I_GENERAL_NAMES, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + sk_GENERAL_NAME_push(gens, gen); + } + return gens; + err: + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return NULL; +} + +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf) +{ + return v2i_GENERAL_NAME_ex(NULL, method, ctx, cnf, 0); +} + +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, int gen_type, char *value, + int is_nc) +{ + char is_string = 0; + GENERAL_NAME *gen = NULL; + + if (!value) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_MISSING_VALUE); + return NULL; + } + + if (out) + gen = out; + else { + gen = GENERAL_NAME_new(); + if (gen == NULL) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); + return NULL; + } + } + + switch (gen_type) { + case GEN_URI: + case GEN_EMAIL: + case GEN_DNS: + is_string = 1; + break; + + case GEN_RID: + { + ASN1_OBJECT *obj; + if (!(obj = OBJ_txt2obj(value, 0))) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_OBJECT); + ERR_add_error_data(2, "value=", value); + goto err; + } + gen->d.rid = obj; + } + break; + + case GEN_IPADD: + if (is_nc) + gen->d.ip = a2i_IPADDRESS_NC(value); + else + gen->d.ip = a2i_IPADDRESS(value); + if (gen->d.ip == NULL) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_BAD_IP_ADDRESS); + ERR_add_error_data(2, "value=", value); + goto err; + } + break; + + case GEN_DIRNAME: + if (!do_dirname(gen, value, ctx)) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_DIRNAME_ERROR); + goto err; + } + break; + + case GEN_OTHERNAME: + if (!do_othername(gen, value, ctx)) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_OTHERNAME_ERROR); + goto err; + } + break; + default: + X509V3err(X509V3_F_A2I_GENERAL_NAME, X509V3_R_UNSUPPORTED_TYPE); + goto err; + } + + if (is_string) { + if (!(gen->d.ia5 = M_ASN1_IA5STRING_new()) || + !ASN1_STRING_set(gen->d.ia5, (unsigned char *)value, + strlen(value))) { + X509V3err(X509V3_F_A2I_GENERAL_NAME, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + gen->type = gen_type; + + return gen; + + err: + if (!out) + GENERAL_NAME_free(gen); + return NULL; +} + +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc) +{ + int type; + + char *name, *value; + + name = cnf->name; + value = cnf->value; + + if (!value) { + X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_MISSING_VALUE); + return NULL; + } + + if (!name_cmp(name, "email")) + type = GEN_EMAIL; + else if (!name_cmp(name, "URI")) + type = GEN_URI; + else if (!name_cmp(name, "DNS")) + type = GEN_DNS; + else if (!name_cmp(name, "RID")) + type = GEN_RID; + else if (!name_cmp(name, "IP")) + type = GEN_IPADD; + else if (!name_cmp(name, "dirName")) + type = GEN_DIRNAME; + else if (!name_cmp(name, "otherName")) + type = GEN_OTHERNAME; + else { + X509V3err(X509V3_F_V2I_GENERAL_NAME_EX, X509V3_R_UNSUPPORTED_OPTION); + ERR_add_error_data(2, "name=", name); + return NULL; + } + + return a2i_GENERAL_NAME(out, method, ctx, type, value, is_nc); + +} + +static int do_othername(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) +{ + char *objtmp = NULL, *p; + int objlen; + if (!(p = strchr(value, ';'))) + return 0; + if (!(gen->d.otherName = OTHERNAME_new())) + return 0; + /* + * Free this up because we will overwrite it. no need to free type_id + * because it is static + */ + ASN1_TYPE_free(gen->d.otherName->value); + if (!(gen->d.otherName->value = ASN1_generate_v3(p + 1, ctx))) + return 0; + objlen = p - value; + objtmp = OPENSSL_malloc(objlen + 1); + strncpy(objtmp, value, objlen); + objtmp[objlen] = 0; + gen->d.otherName->type_id = OBJ_txt2obj(objtmp, 0); + OPENSSL_free(objtmp); + if (!gen->d.otherName->type_id) + return 0; + return 1; +} + +static int do_dirname(GENERAL_NAME *gen, char *value, X509V3_CTX *ctx) +{ + int ret = 0; + STACK_OF(CONF_VALUE) *sk = NULL; + X509_NAME *nm = NULL; + if (!(nm = X509_NAME_new())) + goto err; + sk = X509V3_get_section(ctx, value); + if (!sk) { + X509V3err(X509V3_F_DO_DIRNAME, X509V3_R_SECTION_NOT_FOUND); + ERR_add_error_data(2, "section=", value); + goto err; + } + /* FIXME: should allow other character types... */ + ret = X509V3_NAME_from_section(nm, sk, MBSTRING_ASC); + if (!ret) + goto err; + gen->d.dirn = nm; + +err: + if (ret == 0) + X509_NAME_free(nm); + X509V3_section_free(ctx, sk); + return ret; +} diff --git a/libs/openssl/crypto/x509v3/v3_asid.c b/libs/openssl/crypto/x509v3/v3_asid.c new file mode 100644 index 00000000..2a32c9d0 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_asid.c @@ -0,0 +1,896 @@ +/* + * Contributed to the OpenSSL Project by the American Registry for + * Internet Numbers ("ARIN"). + */ +/* ==================================================================== + * Copyright (c) 2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + */ + +/* + * Implementation of RFC 3779 section 3.2. + */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include +#include +#include +#include + +#ifndef OPENSSL_NO_RFC3779 + +/* + * OpenSSL ASN.1 template translation of RFC 3779 3.2.3. + */ + +ASN1_SEQUENCE(ASRange) = { + ASN1_SIMPLE(ASRange, min, ASN1_INTEGER), + ASN1_SIMPLE(ASRange, max, ASN1_INTEGER) +} ASN1_SEQUENCE_END(ASRange) + +ASN1_CHOICE(ASIdOrRange) = { + ASN1_SIMPLE(ASIdOrRange, u.id, ASN1_INTEGER), + ASN1_SIMPLE(ASIdOrRange, u.range, ASRange) +} ASN1_CHOICE_END(ASIdOrRange) + +ASN1_CHOICE(ASIdentifierChoice) = { + ASN1_SIMPLE(ASIdentifierChoice, u.inherit, ASN1_NULL), + ASN1_SEQUENCE_OF(ASIdentifierChoice, u.asIdsOrRanges, ASIdOrRange) +} ASN1_CHOICE_END(ASIdentifierChoice) + +ASN1_SEQUENCE(ASIdentifiers) = { + ASN1_EXP_OPT(ASIdentifiers, asnum, ASIdentifierChoice, 0), + ASN1_EXP_OPT(ASIdentifiers, rdi, ASIdentifierChoice, 1) +} ASN1_SEQUENCE_END(ASIdentifiers) + +IMPLEMENT_ASN1_FUNCTIONS(ASRange) +IMPLEMENT_ASN1_FUNCTIONS(ASIdOrRange) +IMPLEMENT_ASN1_FUNCTIONS(ASIdentifierChoice) +IMPLEMENT_ASN1_FUNCTIONS(ASIdentifiers) + +/* + * i2r method for an ASIdentifierChoice. + */ +static int i2r_ASIdentifierChoice(BIO *out, + ASIdentifierChoice *choice, + int indent, const char *msg) +{ + int i; + char *s; + if (choice == NULL) + return 1; + BIO_printf(out, "%*s%s:\n", indent, "", msg); + switch (choice->type) { + case ASIdentifierChoice_inherit: + BIO_printf(out, "%*sinherit\n", indent + 2, ""); + break; + case ASIdentifierChoice_asIdsOrRanges: + for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges); i++) { + ASIdOrRange *aor = + sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + switch (aor->type) { + case ASIdOrRange_id: + if ((s = i2s_ASN1_INTEGER(NULL, aor->u.id)) == NULL) + return 0; + BIO_printf(out, "%*s%s\n", indent + 2, "", s); + OPENSSL_free(s); + break; + case ASIdOrRange_range: + if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->min)) == NULL) + return 0; + BIO_printf(out, "%*s%s-", indent + 2, "", s); + OPENSSL_free(s); + if ((s = i2s_ASN1_INTEGER(NULL, aor->u.range->max)) == NULL) + return 0; + BIO_printf(out, "%s\n", s); + OPENSSL_free(s); + break; + default: + return 0; + } + } + break; + default: + return 0; + } + return 1; +} + +/* + * i2r method for an ASIdentifier extension. + */ +static int i2r_ASIdentifiers(const X509V3_EXT_METHOD *method, + void *ext, BIO *out, int indent) +{ + ASIdentifiers *asid = ext; + return (i2r_ASIdentifierChoice(out, asid->asnum, indent, + "Autonomous System Numbers") && + i2r_ASIdentifierChoice(out, asid->rdi, indent, + "Routing Domain Identifiers")); +} + +/* + * Sort comparision function for a sequence of ASIdOrRange elements. + */ +static int ASIdOrRange_cmp(const ASIdOrRange *const *a_, + const ASIdOrRange *const *b_) +{ + const ASIdOrRange *a = *a_, *b = *b_; + + OPENSSL_assert((a->type == ASIdOrRange_id && a->u.id != NULL) || + (a->type == ASIdOrRange_range && a->u.range != NULL && + a->u.range->min != NULL && a->u.range->max != NULL)); + + OPENSSL_assert((b->type == ASIdOrRange_id && b->u.id != NULL) || + (b->type == ASIdOrRange_range && b->u.range != NULL && + b->u.range->min != NULL && b->u.range->max != NULL)); + + if (a->type == ASIdOrRange_id && b->type == ASIdOrRange_id) + return ASN1_INTEGER_cmp(a->u.id, b->u.id); + + if (a->type == ASIdOrRange_range && b->type == ASIdOrRange_range) { + int r = ASN1_INTEGER_cmp(a->u.range->min, b->u.range->min); + return r != 0 ? r : ASN1_INTEGER_cmp(a->u.range->max, + b->u.range->max); + } + + if (a->type == ASIdOrRange_id) + return ASN1_INTEGER_cmp(a->u.id, b->u.range->min); + else + return ASN1_INTEGER_cmp(a->u.range->min, b->u.id); +} + +/* + * Add an inherit element. + */ +int v3_asid_add_inherit(ASIdentifiers *asid, int which) +{ + ASIdentifierChoice **choice; + if (asid == NULL) + return 0; + switch (which) { + case V3_ASID_ASNUM: + choice = &asid->asnum; + break; + case V3_ASID_RDI: + choice = &asid->rdi; + break; + default: + return 0; + } + if (*choice == NULL) { + if ((*choice = ASIdentifierChoice_new()) == NULL) + return 0; + OPENSSL_assert((*choice)->u.inherit == NULL); + if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) + return 0; + (*choice)->type = ASIdentifierChoice_inherit; + } + return (*choice)->type == ASIdentifierChoice_inherit; +} + +/* + * Add an ID or range to an ASIdentifierChoice. + */ +int v3_asid_add_id_or_range(ASIdentifiers *asid, + int which, ASN1_INTEGER *min, ASN1_INTEGER *max) +{ + ASIdentifierChoice **choice; + ASIdOrRange *aor; + if (asid == NULL) + return 0; + switch (which) { + case V3_ASID_ASNUM: + choice = &asid->asnum; + break; + case V3_ASID_RDI: + choice = &asid->rdi; + break; + default: + return 0; + } + if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit) + return 0; + if (*choice == NULL) { + if ((*choice = ASIdentifierChoice_new()) == NULL) + return 0; + OPENSSL_assert((*choice)->u.asIdsOrRanges == NULL); + (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); + if ((*choice)->u.asIdsOrRanges == NULL) + return 0; + (*choice)->type = ASIdentifierChoice_asIdsOrRanges; + } + if ((aor = ASIdOrRange_new()) == NULL) + return 0; + if (max == NULL) { + aor->type = ASIdOrRange_id; + aor->u.id = min; + } else { + aor->type = ASIdOrRange_range; + if ((aor->u.range = ASRange_new()) == NULL) + goto err; + ASN1_INTEGER_free(aor->u.range->min); + aor->u.range->min = min; + ASN1_INTEGER_free(aor->u.range->max); + aor->u.range->max = max; + } + if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor))) + goto err; + return 1; + + err: + ASIdOrRange_free(aor); + return 0; +} + +/* + * Extract min and max values from an ASIdOrRange. + */ +static void extract_min_max(ASIdOrRange *aor, + ASN1_INTEGER **min, ASN1_INTEGER **max) +{ + OPENSSL_assert(aor != NULL && min != NULL && max != NULL); + switch (aor->type) { + case ASIdOrRange_id: + *min = aor->u.id; + *max = aor->u.id; + return; + case ASIdOrRange_range: + *min = aor->u.range->min; + *max = aor->u.range->max; + return; + } +} + +/* + * Check whether an ASIdentifierChoice is in canonical form. + */ +static int ASIdentifierChoice_is_canonical(ASIdentifierChoice *choice) +{ + ASN1_INTEGER *a_max_plus_one = NULL; + BIGNUM *bn = NULL; + int i, ret = 0; + + /* + * Empty element or inheritance is canonical. + */ + if (choice == NULL || choice->type == ASIdentifierChoice_inherit) + return 1; + + /* + * If not a list, or if empty list, it's broken. + */ + if (choice->type != ASIdentifierChoice_asIdsOrRanges || + sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) + return 0; + + /* + * It's a list, check it. + */ + for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { + ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); + ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; + + extract_min_max(a, &a_min, &a_max); + extract_min_max(b, &b_min, &b_max); + + /* + * Punt misordered list, overlapping start, or inverted range. + */ + if (ASN1_INTEGER_cmp(a_min, b_min) >= 0 || + ASN1_INTEGER_cmp(a_min, a_max) > 0 || + ASN1_INTEGER_cmp(b_min, b_max) > 0) + goto done; + + /* + * Calculate a_max + 1 to check for adjacency. + */ + if ((bn == NULL && (bn = BN_new()) == NULL) || + ASN1_INTEGER_to_BN(a_max, bn) == NULL || + !BN_add_word(bn, 1) || + (a_max_plus_one = + BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL, + ERR_R_MALLOC_FAILURE); + goto done; + } + + /* + * Punt if adjacent or overlapping. + */ + if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) >= 0) + goto done; + } + + /* + * Check for inverted range. + */ + i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; + { + ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + ASN1_INTEGER *a_min, *a_max; + if (a != NULL && a->type == ASIdOrRange_range) { + extract_min_max(a, &a_min, &a_max); + if (ASN1_INTEGER_cmp(a_min, a_max) > 0) + goto done; + } + } + + ret = 1; + + done: + ASN1_INTEGER_free(a_max_plus_one); + BN_free(bn); + return ret; +} + +/* + * Check whether an ASIdentifier extension is in canonical form. + */ +int v3_asid_is_canonical(ASIdentifiers *asid) +{ + return (asid == NULL || + (ASIdentifierChoice_is_canonical(asid->asnum) && + ASIdentifierChoice_is_canonical(asid->rdi))); +} + +/* + * Whack an ASIdentifierChoice into canonical form. + */ +static int ASIdentifierChoice_canonize(ASIdentifierChoice *choice) +{ + ASN1_INTEGER *a_max_plus_one = NULL; + BIGNUM *bn = NULL; + int i, ret = 0; + + /* + * Nothing to do for empty element or inheritance. + */ + if (choice == NULL || choice->type == ASIdentifierChoice_inherit) + return 1; + + /* + * If not a list, or if empty list, it's broken. + */ + if (choice->type != ASIdentifierChoice_asIdsOrRanges || + sk_ASIdOrRange_num(choice->u.asIdsOrRanges) == 0) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, + X509V3_R_EXTENSION_VALUE_ERROR); + return 0; + } + + /* + * We have a non-empty list. Sort it. + */ + sk_ASIdOrRange_sort(choice->u.asIdsOrRanges); + + /* + * Now check for errors and suboptimal encoding, rejecting the + * former and fixing the latter. + */ + for (i = 0; i < sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; i++) { + ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + ASIdOrRange *b = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i + 1); + ASN1_INTEGER *a_min, *a_max, *b_min, *b_max; + + extract_min_max(a, &a_min, &a_max); + extract_min_max(b, &b_min, &b_max); + + /* + * Make sure we're properly sorted (paranoia). + */ + OPENSSL_assert(ASN1_INTEGER_cmp(a_min, b_min) <= 0); + + /* + * Punt inverted ranges. + */ + if (ASN1_INTEGER_cmp(a_min, a_max) > 0 || + ASN1_INTEGER_cmp(b_min, b_max) > 0) + goto done; + + /* + * Check for overlaps. + */ + if (ASN1_INTEGER_cmp(a_max, b_min) >= 0) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, + X509V3_R_EXTENSION_VALUE_ERROR); + goto done; + } + + /* + * Calculate a_max + 1 to check for adjacency. + */ + if ((bn == NULL && (bn = BN_new()) == NULL) || + ASN1_INTEGER_to_BN(a_max, bn) == NULL || + !BN_add_word(bn, 1) || + (a_max_plus_one = + BN_to_ASN1_INTEGER(bn, a_max_plus_one)) == NULL) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, + ERR_R_MALLOC_FAILURE); + goto done; + } + + /* + * If a and b are adjacent, merge them. + */ + if (ASN1_INTEGER_cmp(a_max_plus_one, b_min) == 0) { + ASRange *r; + switch (a->type) { + case ASIdOrRange_id: + if ((r = OPENSSL_malloc(sizeof(ASRange))) == NULL) { + X509V3err(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE, + ERR_R_MALLOC_FAILURE); + goto done; + } + r->min = a_min; + r->max = b_max; + a->type = ASIdOrRange_range; + a->u.range = r; + break; + case ASIdOrRange_range: + ASN1_INTEGER_free(a->u.range->max); + a->u.range->max = b_max; + break; + } + switch (b->type) { + case ASIdOrRange_id: + b->u.id = NULL; + break; + case ASIdOrRange_range: + b->u.range->max = NULL; + break; + } + ASIdOrRange_free(b); + (void)sk_ASIdOrRange_delete(choice->u.asIdsOrRanges, i + 1); + i--; + continue; + } + } + + /* + * Check for final inverted range. + */ + i = sk_ASIdOrRange_num(choice->u.asIdsOrRanges) - 1; + { + ASIdOrRange *a = sk_ASIdOrRange_value(choice->u.asIdsOrRanges, i); + ASN1_INTEGER *a_min, *a_max; + if (a != NULL && a->type == ASIdOrRange_range) { + extract_min_max(a, &a_min, &a_max); + if (ASN1_INTEGER_cmp(a_min, a_max) > 0) + goto done; + } + } + + OPENSSL_assert(ASIdentifierChoice_is_canonical(choice)); /* Paranoia */ + + ret = 1; + + done: + ASN1_INTEGER_free(a_max_plus_one); + BN_free(bn); + return ret; +} + +/* + * Whack an ASIdentifier extension into canonical form. + */ +int v3_asid_canonize(ASIdentifiers *asid) +{ + return (asid == NULL || + (ASIdentifierChoice_canonize(asid->asnum) && + ASIdentifierChoice_canonize(asid->rdi))); +} + +/* + * v2i method for an ASIdentifier extension. + */ +static void *v2i_ASIdentifiers(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values) +{ + ASN1_INTEGER *min = NULL, *max = NULL; + ASIdentifiers *asid = NULL; + int i; + + if ((asid = ASIdentifiers_new()) == NULL) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + CONF_VALUE *val = sk_CONF_VALUE_value(values, i); + int i1, i2, i3, is_range, which; + + /* + * Figure out whether this is an AS or an RDI. + */ + if (!name_cmp(val->name, "AS")) { + which = V3_ASID_ASNUM; + } else if (!name_cmp(val->name, "RDI")) { + which = V3_ASID_RDI; + } else { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_EXTENSION_NAME_ERROR); + X509V3_conf_err(val); + goto err; + } + + /* + * Handle inheritance. + */ + if (!strcmp(val->value, "inherit")) { + if (v3_asid_add_inherit(asid, which)) + continue; + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_INVALID_INHERITANCE); + X509V3_conf_err(val); + goto err; + } + + /* + * Number, range, or mistake, pick it apart and figure out which. + */ + i1 = strspn(val->value, "0123456789"); + if (val->value[i1] == '\0') { + is_range = 0; + } else { + is_range = 1; + i2 = i1 + strspn(val->value + i1, " \t"); + if (val->value[i2] != '-') { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_INVALID_ASNUMBER); + X509V3_conf_err(val); + goto err; + } + i2++; + i2 = i2 + strspn(val->value + i2, " \t"); + i3 = i2 + strspn(val->value + i2, "0123456789"); + if (val->value[i3] != '\0') { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_INVALID_ASRANGE); + X509V3_conf_err(val); + goto err; + } + } + + /* + * Syntax is ok, read and add it. + */ + if (!is_range) { + if (!X509V3_get_value_int(val, &min)) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + goto err; + } + } else { + char *s = BUF_strdup(val->value); + if (s == NULL) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + goto err; + } + s[i1] = '\0'; + min = s2i_ASN1_INTEGER(NULL, s); + max = s2i_ASN1_INTEGER(NULL, s + i2); + OPENSSL_free(s); + if (min == NULL || max == NULL) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + goto err; + } + if (ASN1_INTEGER_cmp(min, max) > 0) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, + X509V3_R_EXTENSION_VALUE_ERROR); + goto err; + } + } + if (!v3_asid_add_id_or_range(asid, which, min, max)) { + X509V3err(X509V3_F_V2I_ASIDENTIFIERS, ERR_R_MALLOC_FAILURE); + goto err; + } + min = max = NULL; + } + + /* + * Canonize the result, then we're done. + */ + if (!v3_asid_canonize(asid)) + goto err; + return asid; + + err: + ASIdentifiers_free(asid); + ASN1_INTEGER_free(min); + ASN1_INTEGER_free(max); + return NULL; +} + +/* + * OpenSSL dispatch. + */ +const X509V3_EXT_METHOD v3_asid = { + NID_sbgp_autonomousSysNum, /* nid */ + 0, /* flags */ + ASN1_ITEM_ref(ASIdentifiers), /* template */ + 0, 0, 0, 0, /* old functions, ignored */ + 0, /* i2s */ + 0, /* s2i */ + 0, /* i2v */ + v2i_ASIdentifiers, /* v2i */ + i2r_ASIdentifiers, /* i2r */ + 0, /* r2i */ + NULL /* extension-specific data */ +}; + +/* + * Figure out whether extension uses inheritance. + */ +int v3_asid_inherits(ASIdentifiers *asid) +{ + return (asid != NULL && + ((asid->asnum != NULL && + asid->asnum->type == ASIdentifierChoice_inherit) || + (asid->rdi != NULL && + asid->rdi->type == ASIdentifierChoice_inherit))); +} + +/* + * Figure out whether parent contains child. + */ +static int asid_contains(ASIdOrRanges *parent, ASIdOrRanges *child) +{ + ASN1_INTEGER *p_min, *p_max, *c_min, *c_max; + int p, c; + + if (child == NULL || parent == child) + return 1; + if (parent == NULL) + return 0; + + p = 0; + for (c = 0; c < sk_ASIdOrRange_num(child); c++) { + extract_min_max(sk_ASIdOrRange_value(child, c), &c_min, &c_max); + for (;; p++) { + if (p >= sk_ASIdOrRange_num(parent)) + return 0; + extract_min_max(sk_ASIdOrRange_value(parent, p), &p_min, &p_max); + if (ASN1_INTEGER_cmp(p_max, c_max) < 0) + continue; + if (ASN1_INTEGER_cmp(p_min, c_min) > 0) + return 0; + break; + } + } + + return 1; +} + +/* + * Test whether a is a subet of b. + */ +int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b) +{ + return (a == NULL || + a == b || + (b != NULL && + !v3_asid_inherits(a) && + !v3_asid_inherits(b) && + asid_contains(b->asnum->u.asIdsOrRanges, + a->asnum->u.asIdsOrRanges) && + asid_contains(b->rdi->u.asIdsOrRanges, + a->rdi->u.asIdsOrRanges))); +} + +/* + * Validation error handling via callback. + */ +# define validation_err(_err_) \ + do { \ + if (ctx != NULL) { \ + ctx->error = _err_; \ + ctx->error_depth = i; \ + ctx->current_cert = x; \ + ret = ctx->verify_cb(0, ctx); \ + } else { \ + ret = 0; \ + } \ + if (!ret) \ + goto done; \ + } while (0) + +/* + * Core code for RFC 3779 3.3 path validation. + */ +static int v3_asid_validate_path_internal(X509_STORE_CTX *ctx, + STACK_OF(X509) *chain, + ASIdentifiers *ext) +{ + ASIdOrRanges *child_as = NULL, *child_rdi = NULL; + int i, ret = 1, inherit_as = 0, inherit_rdi = 0; + X509 *x; + + OPENSSL_assert(chain != NULL && sk_X509_num(chain) > 0); + OPENSSL_assert(ctx != NULL || ext != NULL); + OPENSSL_assert(ctx == NULL || ctx->verify_cb != NULL); + + /* + * Figure out where to start. If we don't have an extension to + * check, we're done. Otherwise, check canonical form and + * set up for walking up the chain. + */ + if (ext != NULL) { + i = -1; + x = NULL; + } else { + i = 0; + x = sk_X509_value(chain, i); + OPENSSL_assert(x != NULL); + if ((ext = x->rfc3779_asid) == NULL) + goto done; + } + if (!v3_asid_is_canonical(ext)) + validation_err(X509_V_ERR_INVALID_EXTENSION); + if (ext->asnum != NULL) { + switch (ext->asnum->type) { + case ASIdentifierChoice_inherit: + inherit_as = 1; + break; + case ASIdentifierChoice_asIdsOrRanges: + child_as = ext->asnum->u.asIdsOrRanges; + break; + } + } + if (ext->rdi != NULL) { + switch (ext->rdi->type) { + case ASIdentifierChoice_inherit: + inherit_rdi = 1; + break; + case ASIdentifierChoice_asIdsOrRanges: + child_rdi = ext->rdi->u.asIdsOrRanges; + break; + } + } + + /* + * Now walk up the chain. Extensions must be in canonical form, no + * cert may list resources that its parent doesn't list. + */ + for (i++; i < sk_X509_num(chain); i++) { + x = sk_X509_value(chain, i); + OPENSSL_assert(x != NULL); + if (x->rfc3779_asid == NULL) { + if (child_as != NULL || child_rdi != NULL) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + continue; + } + if (!v3_asid_is_canonical(x->rfc3779_asid)) + validation_err(X509_V_ERR_INVALID_EXTENSION); + if (x->rfc3779_asid->asnum == NULL && child_as != NULL) { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + child_as = NULL; + inherit_as = 0; + } + if (x->rfc3779_asid->asnum != NULL && + x->rfc3779_asid->asnum->type == + ASIdentifierChoice_asIdsOrRanges) { + if (inherit_as + || asid_contains(x->rfc3779_asid->asnum->u.asIdsOrRanges, + child_as)) { + child_as = x->rfc3779_asid->asnum->u.asIdsOrRanges; + inherit_as = 0; + } else { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + } + if (x->rfc3779_asid->rdi == NULL && child_rdi != NULL) { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + child_rdi = NULL; + inherit_rdi = 0; + } + if (x->rfc3779_asid->rdi != NULL && + x->rfc3779_asid->rdi->type == ASIdentifierChoice_asIdsOrRanges) { + if (inherit_rdi || + asid_contains(x->rfc3779_asid->rdi->u.asIdsOrRanges, + child_rdi)) { + child_rdi = x->rfc3779_asid->rdi->u.asIdsOrRanges; + inherit_rdi = 0; + } else { + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + } + } + + /* + * Trust anchor can't inherit. + */ + OPENSSL_assert(x != NULL); + if (x->rfc3779_asid != NULL) { + if (x->rfc3779_asid->asnum != NULL && + x->rfc3779_asid->asnum->type == ASIdentifierChoice_inherit) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + if (x->rfc3779_asid->rdi != NULL && + x->rfc3779_asid->rdi->type == ASIdentifierChoice_inherit) + validation_err(X509_V_ERR_UNNESTED_RESOURCE); + } + + done: + return ret; +} + +# undef validation_err + +/* + * RFC 3779 3.3 path validation -- called from X509_verify_cert(). + */ +int v3_asid_validate_path(X509_STORE_CTX *ctx) +{ + return v3_asid_validate_path_internal(ctx, ctx->chain, NULL); +} + +/* + * RFC 3779 3.3 path validation of an extension. + * Test whether chain covers extension. + */ +int v3_asid_validate_resource_set(STACK_OF(X509) *chain, + ASIdentifiers *ext, int allow_inheritance) +{ + if (ext == NULL) + return 1; + if (chain == NULL || sk_X509_num(chain) == 0) + return 0; + if (!allow_inheritance && v3_asid_inherits(ext)) + return 0; + return v3_asid_validate_path_internal(NULL, chain, ext); +} + +#endif /* OPENSSL_NO_RFC3779 */ diff --git a/libs/openssl/crypto/x509v3/v3_bcons.c b/libs/openssl/crypto/x509v3/v3_bcons.c new file mode 100644 index 00000000..dc00b9cb --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_bcons.c @@ -0,0 +1,132 @@ +/* v3_bcons.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + BASIC_CONSTRAINTS *bcons, + STACK_OF(CONF_VALUE) + *extlist); +static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_bcons = { + NID_basic_constraints, 0, + ASN1_ITEM_ref(BASIC_CONSTRAINTS), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_BASIC_CONSTRAINTS, + (X509V3_EXT_V2I)v2i_BASIC_CONSTRAINTS, + NULL, NULL, + NULL +}; + +ASN1_SEQUENCE(BASIC_CONSTRAINTS) = { + ASN1_OPT(BASIC_CONSTRAINTS, ca, ASN1_FBOOLEAN), + ASN1_OPT(BASIC_CONSTRAINTS, pathlen, ASN1_INTEGER) +} ASN1_SEQUENCE_END(BASIC_CONSTRAINTS) + +IMPLEMENT_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) + +static STACK_OF(CONF_VALUE) *i2v_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + BASIC_CONSTRAINTS *bcons, + STACK_OF(CONF_VALUE) + *extlist) +{ + X509V3_add_value_bool("CA", bcons->ca, &extlist); + X509V3_add_value_int("pathlen", bcons->pathlen, &extlist); + return extlist; +} + +static BASIC_CONSTRAINTS *v2i_BASIC_CONSTRAINTS(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + BASIC_CONSTRAINTS *bcons = NULL; + CONF_VALUE *val; + int i; + if (!(bcons = BASIC_CONSTRAINTS_new())) { + X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + val = sk_CONF_VALUE_value(values, i); + if (!strcmp(val->name, "CA")) { + if (!X509V3_get_value_bool(val, &bcons->ca)) + goto err; + } else if (!strcmp(val->name, "pathlen")) { + if (!X509V3_get_value_int(val, &bcons->pathlen)) + goto err; + } else { + X509V3err(X509V3_F_V2I_BASIC_CONSTRAINTS, X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + return bcons; + err: + BASIC_CONSTRAINTS_free(bcons); + return NULL; +} diff --git a/libs/openssl/crypto/x509v3/v3_bitst.c b/libs/openssl/crypto/x509v3/v3_bitst.c new file mode 100644 index 00000000..b7bb3b55 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_bitst.c @@ -0,0 +1,142 @@ +/* v3_bitst.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include + +static BIT_STRING_BITNAME ns_cert_type_table[] = { + {0, "SSL Client", "client"}, + {1, "SSL Server", "server"}, + {2, "S/MIME", "email"}, + {3, "Object Signing", "objsign"}, + {4, "Unused", "reserved"}, + {5, "SSL CA", "sslCA"}, + {6, "S/MIME CA", "emailCA"}, + {7, "Object Signing CA", "objCA"}, + {-1, NULL, NULL} +}; + +static BIT_STRING_BITNAME key_usage_type_table[] = { + {0, "Digital Signature", "digitalSignature"}, + {1, "Non Repudiation", "nonRepudiation"}, + {2, "Key Encipherment", "keyEncipherment"}, + {3, "Data Encipherment", "dataEncipherment"}, + {4, "Key Agreement", "keyAgreement"}, + {5, "Certificate Sign", "keyCertSign"}, + {6, "CRL Sign", "cRLSign"}, + {7, "Encipher Only", "encipherOnly"}, + {8, "Decipher Only", "decipherOnly"}, + {-1, NULL, NULL} +}; + +const X509V3_EXT_METHOD v3_nscert = +EXT_BITSTRING(NID_netscape_cert_type, ns_cert_type_table); +const X509V3_EXT_METHOD v3_key_usage = +EXT_BITSTRING(NID_key_usage, key_usage_type_table); + +STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *ret) +{ + BIT_STRING_BITNAME *bnam; + for (bnam = method->usr_data; bnam->lname; bnam++) { + if (ASN1_BIT_STRING_get_bit(bits, bnam->bitnum)) + X509V3_add_value(bnam->lname, NULL, &ret); + } + return ret; +} + +ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + CONF_VALUE *val; + ASN1_BIT_STRING *bs; + int i; + BIT_STRING_BITNAME *bnam; + if (!(bs = M_ASN1_BIT_STRING_new())) { + X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + for (bnam = method->usr_data; bnam->lname; bnam++) { + if (!strcmp(bnam->sname, val->name) || + !strcmp(bnam->lname, val->name)) { + if (!ASN1_BIT_STRING_set_bit(bs, bnam->bitnum, 1)) { + X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, + ERR_R_MALLOC_FAILURE); + M_ASN1_BIT_STRING_free(bs); + return NULL; + } + break; + } + } + if (!bnam->lname) { + X509V3err(X509V3_F_V2I_ASN1_BIT_STRING, + X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT); + X509V3_conf_err(val); + M_ASN1_BIT_STRING_free(bs); + return NULL; + } + } + return bs; +} diff --git a/libs/openssl/crypto/x509v3/v3_conf.c b/libs/openssl/crypto/x509v3/v3_conf.c new file mode 100644 index 00000000..eeff8bd1 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_conf.c @@ -0,0 +1,532 @@ +/* v3_conf.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* extension creation utilities */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include + +static int v3_check_critical(char **value); +static int v3_check_generic(char **value); +static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, + int crit, char *value); +static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, + int crit, int type, + X509V3_CTX *ctx); +static char *conf_lhash_get_string(void *db, char *section, char *value); +static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section); +static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, + int ext_nid, int crit, void *ext_struc); +static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, + long *ext_len); +/* CONF *conf: Config file */ +/* char *name: Name */ +/* char *value: Value */ +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, + char *value) +{ + int crit; + int ext_type; + X509_EXTENSION *ret; + crit = v3_check_critical(&value); + if ((ext_type = v3_check_generic(&value))) + return v3_generic_extension(name, value, crit, ext_type, ctx); + ret = do_ext_nconf(conf, ctx, OBJ_sn2nid(name), crit, value); + if (!ret) { + X509V3err(X509V3_F_X509V3_EXT_NCONF, X509V3_R_ERROR_IN_EXTENSION); + ERR_add_error_data(4, "name=", name, ", value=", value); + } + return ret; +} + +/* CONF *conf: Config file */ +/* char *value: Value */ +X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, + char *value) +{ + int crit; + int ext_type; + crit = v3_check_critical(&value); + if ((ext_type = v3_check_generic(&value))) + return v3_generic_extension(OBJ_nid2sn(ext_nid), + value, crit, ext_type, ctx); + return do_ext_nconf(conf, ctx, ext_nid, crit, value); +} + +/* CONF *conf: Config file */ +/* char *value: Value */ +static X509_EXTENSION *do_ext_nconf(CONF *conf, X509V3_CTX *ctx, int ext_nid, + int crit, char *value) +{ + const X509V3_EXT_METHOD *method; + X509_EXTENSION *ext; + STACK_OF(CONF_VALUE) *nval; + void *ext_struc; + if (ext_nid == NID_undef) { + X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION_NAME); + return NULL; + } + if (!(method = X509V3_EXT_get_nid(ext_nid))) { + X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_UNKNOWN_EXTENSION); + return NULL; + } + /* Now get internal extension representation based on type */ + if (method->v2i) { + if (*value == '@') + nval = NCONF_get_section(conf, value + 1); + else + nval = X509V3_parse_list(value); + if (sk_CONF_VALUE_num(nval) <= 0) { + X509V3err(X509V3_F_DO_EXT_NCONF, + X509V3_R_INVALID_EXTENSION_STRING); + ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", + value); + return NULL; + } + ext_struc = method->v2i(method, ctx, nval); + if (*value != '@') + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + if (!ext_struc) + return NULL; + } else if (method->s2i) { + if (!(ext_struc = method->s2i(method, ctx, value))) + return NULL; + } else if (method->r2i) { + if (!ctx->db || !ctx->db_meth) { + X509V3err(X509V3_F_DO_EXT_NCONF, X509V3_R_NO_CONFIG_DATABASE); + return NULL; + } + if (!(ext_struc = method->r2i(method, ctx, value))) + return NULL; + } else { + X509V3err(X509V3_F_DO_EXT_NCONF, + X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED); + ERR_add_error_data(2, "name=", OBJ_nid2sn(ext_nid)); + return NULL; + } + + ext = do_ext_i2d(method, ext_nid, crit, ext_struc); + if (method->it) + ASN1_item_free(ext_struc, ASN1_ITEM_ptr(method->it)); + else + method->ext_free(ext_struc); + return ext; + +} + +static X509_EXTENSION *do_ext_i2d(const X509V3_EXT_METHOD *method, + int ext_nid, int crit, void *ext_struc) +{ + unsigned char *ext_der; + int ext_len; + ASN1_OCTET_STRING *ext_oct; + X509_EXTENSION *ext; + /* Convert internal representation to DER */ + if (method->it) { + ext_der = NULL; + ext_len = + ASN1_item_i2d(ext_struc, &ext_der, ASN1_ITEM_ptr(method->it)); + if (ext_len < 0) + goto merr; + } else { + unsigned char *p; + ext_len = method->i2d(ext_struc, NULL); + if (!(ext_der = OPENSSL_malloc(ext_len))) + goto merr; + p = ext_der; + method->i2d(ext_struc, &p); + } + if (!(ext_oct = M_ASN1_OCTET_STRING_new())) + goto merr; + ext_oct->data = ext_der; + ext_oct->length = ext_len; + + ext = X509_EXTENSION_create_by_NID(NULL, ext_nid, crit, ext_oct); + if (!ext) + goto merr; + M_ASN1_OCTET_STRING_free(ext_oct); + + return ext; + + merr: + X509V3err(X509V3_F_DO_EXT_I2D, ERR_R_MALLOC_FAILURE); + return NULL; + +} + +/* Given an internal structure, nid and critical flag create an extension */ + +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc) +{ + const X509V3_EXT_METHOD *method; + if (!(method = X509V3_EXT_get_nid(ext_nid))) { + X509V3err(X509V3_F_X509V3_EXT_I2D, X509V3_R_UNKNOWN_EXTENSION); + return NULL; + } + return do_ext_i2d(method, ext_nid, crit, ext_struc); +} + +/* Check the extension string for critical flag */ +static int v3_check_critical(char **value) +{ + char *p = *value; + if ((strlen(p) < 9) || strncmp(p, "critical,", 9)) + return 0; + p += 9; + while (isspace((unsigned char)*p)) + p++; + *value = p; + return 1; +} + +/* Check extension string for generic extension and return the type */ +static int v3_check_generic(char **value) +{ + int gen_type = 0; + char *p = *value; + if ((strlen(p) >= 4) && !strncmp(p, "DER:", 4)) { + p += 4; + gen_type = 1; + } else if ((strlen(p) >= 5) && !strncmp(p, "ASN1:", 5)) { + p += 5; + gen_type = 2; + } else + return 0; + + while (isspace((unsigned char)*p)) + p++; + *value = p; + return gen_type; +} + +/* Create a generic extension: for now just handle DER type */ +static X509_EXTENSION *v3_generic_extension(const char *ext, char *value, + int crit, int gen_type, + X509V3_CTX *ctx) +{ + unsigned char *ext_der = NULL; + long ext_len; + ASN1_OBJECT *obj = NULL; + ASN1_OCTET_STRING *oct = NULL; + X509_EXTENSION *extension = NULL; + if (!(obj = OBJ_txt2obj(ext, 0))) { + X509V3err(X509V3_F_V3_GENERIC_EXTENSION, + X509V3_R_EXTENSION_NAME_ERROR); + ERR_add_error_data(2, "name=", ext); + goto err; + } + + if (gen_type == 1) + ext_der = string_to_hex(value, &ext_len); + else if (gen_type == 2) + ext_der = generic_asn1(value, ctx, &ext_len); + + if (ext_der == NULL) { + X509V3err(X509V3_F_V3_GENERIC_EXTENSION, + X509V3_R_EXTENSION_VALUE_ERROR); + ERR_add_error_data(2, "value=", value); + goto err; + } + + if (!(oct = M_ASN1_OCTET_STRING_new())) { + X509V3err(X509V3_F_V3_GENERIC_EXTENSION, ERR_R_MALLOC_FAILURE); + goto err; + } + + oct->data = ext_der; + oct->length = ext_len; + ext_der = NULL; + + extension = X509_EXTENSION_create_by_OBJ(NULL, obj, crit, oct); + + err: + ASN1_OBJECT_free(obj); + M_ASN1_OCTET_STRING_free(oct); + if (ext_der) + OPENSSL_free(ext_der); + return extension; + +} + +static unsigned char *generic_asn1(char *value, X509V3_CTX *ctx, + long *ext_len) +{ + ASN1_TYPE *typ; + unsigned char *ext_der = NULL; + typ = ASN1_generate_v3(value, ctx); + if (typ == NULL) + return NULL; + *ext_len = i2d_ASN1_TYPE(typ, &ext_der); + ASN1_TYPE_free(typ); + return ext_der; +} + +/* + * This is the main function: add a bunch of extensions based on a config + * file section to an extension STACK. + */ + +int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, + STACK_OF(X509_EXTENSION) **sk) +{ + X509_EXTENSION *ext; + STACK_OF(CONF_VALUE) *nval; + CONF_VALUE *val; + int i; + if (!(nval = NCONF_get_section(conf, section))) + return 0; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!(ext = X509V3_EXT_nconf(conf, ctx, val->name, val->value))) + return 0; + if (sk) + X509v3_add_ext(sk, ext, -1); + X509_EXTENSION_free(ext); + } + return 1; +} + +/* + * Convenience functions to add extensions to a certificate, CRL and request + */ + +int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509 *cert) +{ + STACK_OF(X509_EXTENSION) **sk = NULL; + if (cert) + sk = &cert->cert_info->extensions; + return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); +} + +/* Same as above but for a CRL */ + +int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509_CRL *crl) +{ + STACK_OF(X509_EXTENSION) **sk = NULL; + if (crl) + sk = &crl->crl->extensions; + return X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); +} + +/* Add extensions to certificate request */ + +int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509_REQ *req) +{ + STACK_OF(X509_EXTENSION) *extlist = NULL, **sk = NULL; + int i; + if (req) + sk = &extlist; + i = X509V3_EXT_add_nconf_sk(conf, ctx, section, sk); + if (!i || !sk) + return i; + i = X509_REQ_add_extensions(req, extlist); + sk_X509_EXTENSION_pop_free(extlist, X509_EXTENSION_free); + return i; +} + +/* Config database functions */ + +char *X509V3_get_string(X509V3_CTX *ctx, char *name, char *section) +{ + if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_string) { + X509V3err(X509V3_F_X509V3_GET_STRING, X509V3_R_OPERATION_NOT_DEFINED); + return NULL; + } + if (ctx->db_meth->get_string) + return ctx->db_meth->get_string(ctx->db, name, section); + return NULL; +} + +STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, char *section) +{ + if (!ctx->db || !ctx->db_meth || !ctx->db_meth->get_section) { + X509V3err(X509V3_F_X509V3_GET_SECTION, + X509V3_R_OPERATION_NOT_DEFINED); + return NULL; + } + if (ctx->db_meth->get_section) + return ctx->db_meth->get_section(ctx->db, section); + return NULL; +} + +void X509V3_string_free(X509V3_CTX *ctx, char *str) +{ + if (!str) + return; + if (ctx->db_meth->free_string) + ctx->db_meth->free_string(ctx->db, str); +} + +void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section) +{ + if (!section) + return; + if (ctx->db_meth->free_section) + ctx->db_meth->free_section(ctx->db, section); +} + +static char *nconf_get_string(void *db, char *section, char *value) +{ + return NCONF_get_string(db, section, value); +} + +static STACK_OF(CONF_VALUE) *nconf_get_section(void *db, char *section) +{ + return NCONF_get_section(db, section); +} + +static X509V3_CONF_METHOD nconf_method = { + nconf_get_string, + nconf_get_section, + NULL, + NULL +}; + +void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf) +{ + ctx->db_meth = &nconf_method; + ctx->db = conf; +} + +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subj, X509_REQ *req, + X509_CRL *crl, int flags) +{ + ctx->issuer_cert = issuer; + ctx->subject_cert = subj; + ctx->crl = crl; + ctx->subject_req = req; + ctx->flags = flags; +} + +/* Old conf compatibility functions */ + +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *name, char *value) +{ + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_nconf(&ctmp, ctx, name, value); +} + +/* LHASH *conf: Config file */ +/* char *value: Value */ +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, + X509V3_CTX *ctx, int ext_nid, char *value) +{ + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_nconf_nid(&ctmp, ctx, ext_nid, value); +} + +static char *conf_lhash_get_string(void *db, char *section, char *value) +{ + return CONF_get_string(db, section, value); +} + +static STACK_OF(CONF_VALUE) *conf_lhash_get_section(void *db, char *section) +{ + return CONF_get_section(db, section); +} + +static X509V3_CONF_METHOD conf_lhash_method = { + conf_lhash_get_string, + conf_lhash_get_section, + NULL, + NULL +}; + +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash) +{ + ctx->db_meth = &conf_lhash_method; + ctx->db = lhash; +} + +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509 *cert) +{ + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_add_nconf(&ctmp, ctx, section, cert); +} + +/* Same as above but for a CRL */ + +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_CRL *crl) +{ + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_CRL_add_nconf(&ctmp, ctx, section, crl); +} + +/* Add extensions to certificate request */ + +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_REQ *req) +{ + CONF ctmp; + CONF_set_nconf(&ctmp, conf); + return X509V3_EXT_REQ_add_nconf(&ctmp, ctx, section, req); +} diff --git a/libs/openssl/crypto/x509v3/v3_cpols.c b/libs/openssl/crypto/x509v3/v3_cpols.c new file mode 100644 index 00000000..d97f6226 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_cpols.c @@ -0,0 +1,491 @@ +/* v3_cpols.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +#include "pcy_int.h" + +/* Certificate policies extension support: this one is a bit complex... */ + +static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, + BIO *out, int indent); +static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *value); +static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, + int indent); +static void print_notice(BIO *out, USERNOTICE *notice, int indent); +static POLICYINFO *policy_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *polstrs, int ia5org); +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *unot, int ia5org); +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos); + +const X509V3_EXT_METHOD v3_cpols = { + NID_certificate_policies, 0, ASN1_ITEM_ref(CERTIFICATEPOLICIES), + 0, 0, 0, 0, + 0, 0, + 0, 0, + (X509V3_EXT_I2R)i2r_certpol, + (X509V3_EXT_R2I)r2i_certpol, + NULL +}; + +ASN1_ITEM_TEMPLATE(CERTIFICATEPOLICIES) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CERTIFICATEPOLICIES, POLICYINFO) +ASN1_ITEM_TEMPLATE_END(CERTIFICATEPOLICIES) + +IMPLEMENT_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) + +ASN1_SEQUENCE(POLICYINFO) = { + ASN1_SIMPLE(POLICYINFO, policyid, ASN1_OBJECT), + ASN1_SEQUENCE_OF_OPT(POLICYINFO, qualifiers, POLICYQUALINFO) +} ASN1_SEQUENCE_END(POLICYINFO) + +IMPLEMENT_ASN1_FUNCTIONS(POLICYINFO) + +ASN1_ADB_TEMPLATE(policydefault) = ASN1_SIMPLE(POLICYQUALINFO, d.other, ASN1_ANY); + +ASN1_ADB(POLICYQUALINFO) = { + ADB_ENTRY(NID_id_qt_cps, ASN1_SIMPLE(POLICYQUALINFO, d.cpsuri, ASN1_IA5STRING)), + ADB_ENTRY(NID_id_qt_unotice, ASN1_SIMPLE(POLICYQUALINFO, d.usernotice, USERNOTICE)) +} ASN1_ADB_END(POLICYQUALINFO, 0, pqualid, 0, &policydefault_tt, NULL); + +ASN1_SEQUENCE(POLICYQUALINFO) = { + ASN1_SIMPLE(POLICYQUALINFO, pqualid, ASN1_OBJECT), + ASN1_ADB_OBJECT(POLICYQUALINFO) +} ASN1_SEQUENCE_END(POLICYQUALINFO) + +IMPLEMENT_ASN1_FUNCTIONS(POLICYQUALINFO) + +ASN1_SEQUENCE(USERNOTICE) = { + ASN1_OPT(USERNOTICE, noticeref, NOTICEREF), + ASN1_OPT(USERNOTICE, exptext, DISPLAYTEXT) +} ASN1_SEQUENCE_END(USERNOTICE) + +IMPLEMENT_ASN1_FUNCTIONS(USERNOTICE) + +ASN1_SEQUENCE(NOTICEREF) = { + ASN1_SIMPLE(NOTICEREF, organization, DISPLAYTEXT), + ASN1_SEQUENCE_OF(NOTICEREF, noticenos, ASN1_INTEGER) +} ASN1_SEQUENCE_END(NOTICEREF) + +IMPLEMENT_ASN1_FUNCTIONS(NOTICEREF) + +static STACK_OF(POLICYINFO) *r2i_certpol(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *value) +{ + STACK_OF(POLICYINFO) *pols = NULL; + char *pstr; + POLICYINFO *pol; + ASN1_OBJECT *pobj; + STACK_OF(CONF_VALUE) *vals; + CONF_VALUE *cnf; + int i, ia5org; + pols = sk_POLICYINFO_new_null(); + if (pols == NULL) { + X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); + return NULL; + } + vals = X509V3_parse_list(value); + if (vals == NULL) { + X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_X509V3_LIB); + goto err; + } + ia5org = 0; + for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { + cnf = sk_CONF_VALUE_value(vals, i); + if (cnf->value || !cnf->name) { + X509V3err(X509V3_F_R2I_CERTPOL, + X509V3_R_INVALID_POLICY_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pstr = cnf->name; + if (!strcmp(pstr, "ia5org")) { + ia5org = 1; + continue; + } else if (*pstr == '@') { + STACK_OF(CONF_VALUE) *polsect; + polsect = X509V3_get_section(ctx, pstr + 1); + if (!polsect) { + X509V3err(X509V3_F_R2I_CERTPOL, X509V3_R_INVALID_SECTION); + + X509V3_conf_err(cnf); + goto err; + } + pol = policy_section(ctx, polsect, ia5org); + X509V3_section_free(ctx, polsect); + if (!pol) + goto err; + } else { + if (!(pobj = OBJ_txt2obj(cnf->name, 0))) { + X509V3err(X509V3_F_R2I_CERTPOL, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pol = POLICYINFO_new(); + if (pol == NULL) { + X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); + goto err; + } + pol->policyid = pobj; + } + if (!sk_POLICYINFO_push(pols, pol)) { + POLICYINFO_free(pol); + X509V3err(X509V3_F_R2I_CERTPOL, ERR_R_MALLOC_FAILURE); + goto err; + } + } + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + return pols; + err: + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + sk_POLICYINFO_pop_free(pols, POLICYINFO_free); + return NULL; +} + +static POLICYINFO *policy_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *polstrs, int ia5org) +{ + int i; + CONF_VALUE *cnf; + POLICYINFO *pol; + POLICYQUALINFO *qual; + if (!(pol = POLICYINFO_new())) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(polstrs); i++) { + cnf = sk_CONF_VALUE_value(polstrs, i); + if (!strcmp(cnf->name, "policyIdentifier")) { + ASN1_OBJECT *pobj; + if (!(pobj = OBJ_txt2obj(cnf->value, 0))) { + X509V3err(X509V3_F_POLICY_SECTION, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pol->policyid = pobj; + + } else if (!name_cmp(cnf->name, "CPS")) { + if (!pol->qualifiers) + pol->qualifiers = sk_POLICYQUALINFO_new_null(); + if (!(qual = POLICYQUALINFO_new())) + goto merr; + if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) + goto merr; + if (!(qual->pqualid = OBJ_nid2obj(NID_id_qt_cps))) { + X509V3err(X509V3_F_POLICY_SECTION, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!(qual->d.cpsuri = M_ASN1_IA5STRING_new())) + goto merr; + if (!ASN1_STRING_set(qual->d.cpsuri, cnf->value, + strlen(cnf->value))) + goto merr; + } else if (!name_cmp(cnf->name, "userNotice")) { + STACK_OF(CONF_VALUE) *unot; + if (*cnf->value != '@') { + X509V3err(X509V3_F_POLICY_SECTION, + X509V3_R_EXPECTED_A_SECTION_NAME); + X509V3_conf_err(cnf); + goto err; + } + unot = X509V3_get_section(ctx, cnf->value + 1); + if (!unot) { + X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_SECTION); + + X509V3_conf_err(cnf); + goto err; + } + qual = notice_section(ctx, unot, ia5org); + X509V3_section_free(ctx, unot); + if (!qual) + goto err; + if (!pol->qualifiers) + pol->qualifiers = sk_POLICYQUALINFO_new_null(); + if (!sk_POLICYQUALINFO_push(pol->qualifiers, qual)) + goto merr; + } else { + X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_INVALID_OPTION); + + X509V3_conf_err(cnf); + goto err; + } + } + if (!pol->policyid) { + X509V3err(X509V3_F_POLICY_SECTION, X509V3_R_NO_POLICY_IDENTIFIER); + goto err; + } + + return pol; + + merr: + X509V3err(X509V3_F_POLICY_SECTION, ERR_R_MALLOC_FAILURE); + + err: + POLICYINFO_free(pol); + return NULL; + +} + +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *unot, int ia5org) +{ + int i, ret; + CONF_VALUE *cnf; + USERNOTICE *not; + POLICYQUALINFO *qual; + if (!(qual = POLICYQUALINFO_new())) + goto merr; + if (!(qual->pqualid = OBJ_nid2obj(NID_id_qt_unotice))) { + X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!(not = USERNOTICE_new())) + goto merr; + qual->d.usernotice = not; + for (i = 0; i < sk_CONF_VALUE_num(unot); i++) { + cnf = sk_CONF_VALUE_value(unot, i); + if (!strcmp(cnf->name, "explicitText")) { + if (!(not->exptext = M_ASN1_VISIBLESTRING_new())) + goto merr; + if (!ASN1_STRING_set(not->exptext, cnf->value, + strlen(cnf->value))) + goto merr; + } else if (!strcmp(cnf->name, "organization")) { + NOTICEREF *nref; + if (!not->noticeref) { + if (!(nref = NOTICEREF_new())) + goto merr; + not->noticeref = nref; + } else + nref = not->noticeref; + if (ia5org) + nref->organization->type = V_ASN1_IA5STRING; + else + nref->organization->type = V_ASN1_VISIBLESTRING; + if (!ASN1_STRING_set(nref->organization, cnf->value, + strlen(cnf->value))) + goto merr; + } else if (!strcmp(cnf->name, "noticeNumbers")) { + NOTICEREF *nref; + STACK_OF(CONF_VALUE) *nos; + if (!not->noticeref) { + if (!(nref = NOTICEREF_new())) + goto merr; + not->noticeref = nref; + } else + nref = not->noticeref; + nos = X509V3_parse_list(cnf->value); + if (!nos || !sk_CONF_VALUE_num(nos)) { + X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_NUMBERS); + X509V3_conf_err(cnf); + goto err; + } + ret = nref_nos(nref->noticenos, nos); + sk_CONF_VALUE_pop_free(nos, X509V3_conf_free); + if (!ret) + goto err; + } else { + X509V3err(X509V3_F_NOTICE_SECTION, X509V3_R_INVALID_OPTION); + X509V3_conf_err(cnf); + goto err; + } + } + + if (not->noticeref && + (!not->noticeref->noticenos || !not->noticeref->organization)) { + X509V3err(X509V3_F_NOTICE_SECTION, + X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); + goto err; + } + + return qual; + + merr: + X509V3err(X509V3_F_NOTICE_SECTION, ERR_R_MALLOC_FAILURE); + + err: + POLICYQUALINFO_free(qual); + return NULL; +} + +static int nref_nos(STACK_OF(ASN1_INTEGER) *nnums, STACK_OF(CONF_VALUE) *nos) +{ + CONF_VALUE *cnf; + ASN1_INTEGER *aint; + + int i; + + for (i = 0; i < sk_CONF_VALUE_num(nos); i++) { + cnf = sk_CONF_VALUE_value(nos, i); + if (!(aint = s2i_ASN1_INTEGER(NULL, cnf->name))) { + X509V3err(X509V3_F_NREF_NOS, X509V3_R_INVALID_NUMBER); + goto err; + } + if (!sk_ASN1_INTEGER_push(nnums, aint)) + goto merr; + } + return 1; + + merr: + X509V3err(X509V3_F_NREF_NOS, ERR_R_MALLOC_FAILURE); + + err: + sk_ASN1_INTEGER_pop_free(nnums, ASN1_STRING_free); + return 0; +} + +static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, + BIO *out, int indent) +{ + int i; + POLICYINFO *pinfo; + /* First print out the policy OIDs */ + for (i = 0; i < sk_POLICYINFO_num(pol); i++) { + pinfo = sk_POLICYINFO_value(pol, i); + BIO_printf(out, "%*sPolicy: ", indent, ""); + i2a_ASN1_OBJECT(out, pinfo->policyid); + BIO_puts(out, "\n"); + if (pinfo->qualifiers) + print_qualifiers(out, pinfo->qualifiers, indent + 2); + } + return 1; +} + +static void print_qualifiers(BIO *out, STACK_OF(POLICYQUALINFO) *quals, + int indent) +{ + POLICYQUALINFO *qualinfo; + int i; + for (i = 0; i < sk_POLICYQUALINFO_num(quals); i++) { + qualinfo = sk_POLICYQUALINFO_value(quals, i); + switch (OBJ_obj2nid(qualinfo->pqualid)) { + case NID_id_qt_cps: + BIO_printf(out, "%*sCPS: %s\n", indent, "", + qualinfo->d.cpsuri->data); + break; + + case NID_id_qt_unotice: + BIO_printf(out, "%*sUser Notice:\n", indent, ""); + print_notice(out, qualinfo->d.usernotice, indent + 2); + break; + + default: + BIO_printf(out, "%*sUnknown Qualifier: ", indent + 2, ""); + + i2a_ASN1_OBJECT(out, qualinfo->pqualid); + BIO_puts(out, "\n"); + break; + } + } +} + +static void print_notice(BIO *out, USERNOTICE *notice, int indent) +{ + int i; + if (notice->noticeref) { + NOTICEREF *ref; + ref = notice->noticeref; + BIO_printf(out, "%*sOrganization: %s\n", indent, "", + ref->organization->data); + BIO_printf(out, "%*sNumber%s: ", indent, "", + sk_ASN1_INTEGER_num(ref->noticenos) > 1 ? "s" : ""); + for (i = 0; i < sk_ASN1_INTEGER_num(ref->noticenos); i++) { + ASN1_INTEGER *num; + char *tmp; + num = sk_ASN1_INTEGER_value(ref->noticenos, i); + if (i) + BIO_puts(out, ", "); + tmp = i2s_ASN1_INTEGER(NULL, num); + BIO_puts(out, tmp); + OPENSSL_free(tmp); + } + BIO_puts(out, "\n"); + } + if (notice->exptext) + BIO_printf(out, "%*sExplicit Text: %s\n", indent, "", + notice->exptext->data); +} + +void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent) +{ + const X509_POLICY_DATA *dat = node->data; + + BIO_printf(out, "%*sPolicy: ", indent, ""); + + i2a_ASN1_OBJECT(out, dat->valid_policy); + BIO_puts(out, "\n"); + BIO_printf(out, "%*s%s\n", indent + 2, "", + node_data_critical(dat) ? "Critical" : "Non Critical"); + if (dat->qualifier_set) + print_qualifiers(out, dat->qualifier_set, indent + 2); + else + BIO_printf(out, "%*sNo Qualifiers\n", indent + 2, ""); +} + + +IMPLEMENT_STACK_OF(X509_POLICY_NODE) + +IMPLEMENT_STACK_OF(X509_POLICY_DATA) diff --git a/libs/openssl/crypto/x509v3/v3_crld.c b/libs/openssl/crypto/x509v3/v3_crld.c new file mode 100644 index 00000000..d3e1d1b0 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_crld.c @@ -0,0 +1,562 @@ +/* v3_crld.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +static void *v2i_crld(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, + int indent); + +const X509V3_EXT_METHOD v3_crld = { + NID_crl_distribution_points, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), + 0, 0, 0, 0, + 0, 0, + 0, + v2i_crld, + i2r_crldp, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_freshest_crl = { + NID_freshest_crl, 0, ASN1_ITEM_ref(CRL_DIST_POINTS), + 0, 0, 0, 0, + 0, 0, + 0, + v2i_crld, + i2r_crldp, 0, + NULL +}; + +static STACK_OF(GENERAL_NAME) *gnames_from_sectname(X509V3_CTX *ctx, + char *sect) +{ + STACK_OF(CONF_VALUE) *gnsect; + STACK_OF(GENERAL_NAME) *gens; + if (*sect == '@') + gnsect = X509V3_get_section(ctx, sect + 1); + else + gnsect = X509V3_parse_list(sect); + if (!gnsect) { + X509V3err(X509V3_F_GNAMES_FROM_SECTNAME, X509V3_R_SECTION_NOT_FOUND); + return NULL; + } + gens = v2i_GENERAL_NAMES(NULL, ctx, gnsect); + if (*sect == '@') + X509V3_section_free(ctx, gnsect); + else + sk_CONF_VALUE_pop_free(gnsect, X509V3_conf_free); + return gens; +} + +static int set_dist_point_name(DIST_POINT_NAME **pdp, X509V3_CTX *ctx, + CONF_VALUE *cnf) +{ + STACK_OF(GENERAL_NAME) *fnm = NULL; + STACK_OF(X509_NAME_ENTRY) *rnm = NULL; + if (!strncmp(cnf->name, "fullname", 9)) { + fnm = gnames_from_sectname(ctx, cnf->value); + if (!fnm) + goto err; + } else if (!strcmp(cnf->name, "relativename")) { + int ret; + STACK_OF(CONF_VALUE) *dnsect; + X509_NAME *nm; + nm = X509_NAME_new(); + if (!nm) + return -1; + dnsect = X509V3_get_section(ctx, cnf->value); + if (!dnsect) { + X509V3err(X509V3_F_SET_DIST_POINT_NAME, + X509V3_R_SECTION_NOT_FOUND); + return -1; + } + ret = X509V3_NAME_from_section(nm, dnsect, MBSTRING_ASC); + X509V3_section_free(ctx, dnsect); + rnm = nm->entries; + nm->entries = NULL; + X509_NAME_free(nm); + if (!ret || sk_X509_NAME_ENTRY_num(rnm) <= 0) + goto err; + /* + * Since its a name fragment can't have more than one RDNSequence + */ + if (sk_X509_NAME_ENTRY_value(rnm, + sk_X509_NAME_ENTRY_num(rnm) - 1)->set) { + X509V3err(X509V3_F_SET_DIST_POINT_NAME, + X509V3_R_INVALID_MULTIPLE_RDNS); + goto err; + } + } else + return 0; + + if (*pdp) { + X509V3err(X509V3_F_SET_DIST_POINT_NAME, + X509V3_R_DISTPOINT_ALREADY_SET); + goto err; + } + + *pdp = DIST_POINT_NAME_new(); + if (!*pdp) + goto err; + if (fnm) { + (*pdp)->type = 0; + (*pdp)->name.fullname = fnm; + } else { + (*pdp)->type = 1; + (*pdp)->name.relativename = rnm; + } + + return 1; + + err: + if (fnm) + sk_GENERAL_NAME_pop_free(fnm, GENERAL_NAME_free); + if (rnm) + sk_X509_NAME_ENTRY_pop_free(rnm, X509_NAME_ENTRY_free); + return -1; +} + +static const BIT_STRING_BITNAME reason_flags[] = { + {0, "Unused", "unused"}, + {1, "Key Compromise", "keyCompromise"}, + {2, "CA Compromise", "CACompromise"}, + {3, "Affiliation Changed", "affiliationChanged"}, + {4, "Superseded", "superseded"}, + {5, "Cessation Of Operation", "cessationOfOperation"}, + {6, "Certificate Hold", "certificateHold"}, + {7, "Privilege Withdrawn", "privilegeWithdrawn"}, + {8, "AA Compromise", "AACompromise"}, + {-1, NULL, NULL} +}; + +static int set_reasons(ASN1_BIT_STRING **preas, char *value) +{ + STACK_OF(CONF_VALUE) *rsk = NULL; + const BIT_STRING_BITNAME *pbn; + const char *bnam; + int i, ret = 0; + rsk = X509V3_parse_list(value); + if (!rsk) + return 0; + if (*preas) + return 0; + for (i = 0; i < sk_CONF_VALUE_num(rsk); i++) { + bnam = sk_CONF_VALUE_value(rsk, i)->name; + if (!*preas) { + *preas = ASN1_BIT_STRING_new(); + if (!*preas) + goto err; + } + for (pbn = reason_flags; pbn->lname; pbn++) { + if (!strcmp(pbn->sname, bnam)) { + if (!ASN1_BIT_STRING_set_bit(*preas, pbn->bitnum, 1)) + goto err; + break; + } + } + if (!pbn->lname) + goto err; + } + ret = 1; + + err: + sk_CONF_VALUE_pop_free(rsk, X509V3_conf_free); + return ret; +} + +static int print_reasons(BIO *out, const char *rname, + ASN1_BIT_STRING *rflags, int indent) +{ + int first = 1; + const BIT_STRING_BITNAME *pbn; + BIO_printf(out, "%*s%s:\n%*s", indent, "", rname, indent + 2, ""); + for (pbn = reason_flags; pbn->lname; pbn++) { + if (ASN1_BIT_STRING_get_bit(rflags, pbn->bitnum)) { + if (first) + first = 0; + else + BIO_puts(out, ", "); + BIO_puts(out, pbn->lname); + } + } + if (first) + BIO_puts(out, "\n"); + else + BIO_puts(out, "\n"); + return 1; +} + +static DIST_POINT *crldp_from_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + int i; + CONF_VALUE *cnf; + DIST_POINT *point = NULL; + point = DIST_POINT_new(); + if (!point) + goto err; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + int ret; + cnf = sk_CONF_VALUE_value(nval, i); + ret = set_dist_point_name(&point->distpoint, ctx, cnf); + if (ret > 0) + continue; + if (ret < 0) + goto err; + if (!strcmp(cnf->name, "reasons")) { + if (!set_reasons(&point->reasons, cnf->value)) + goto err; + } else if (!strcmp(cnf->name, "CRLissuer")) { + point->CRLissuer = gnames_from_sectname(ctx, cnf->value); + if (!point->CRLissuer) + goto err; + } + } + + return point; + + err: + if (point) + DIST_POINT_free(point); + return NULL; +} + +static void *v2i_crld(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + STACK_OF(DIST_POINT) *crld = NULL; + GENERAL_NAMES *gens = NULL; + GENERAL_NAME *gen = NULL; + CONF_VALUE *cnf; + int i; + if (!(crld = sk_DIST_POINT_new_null())) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + DIST_POINT *point; + cnf = sk_CONF_VALUE_value(nval, i); + if (!cnf->value) { + STACK_OF(CONF_VALUE) *dpsect; + dpsect = X509V3_get_section(ctx, cnf->name); + if (!dpsect) + goto err; + point = crldp_from_section(ctx, dpsect); + X509V3_section_free(ctx, dpsect); + if (!point) + goto err; + if (!sk_DIST_POINT_push(crld, point)) { + DIST_POINT_free(point); + goto merr; + } + } else { + if (!(gen = v2i_GENERAL_NAME(method, ctx, cnf))) + goto err; + if (!(gens = GENERAL_NAMES_new())) + goto merr; + if (!sk_GENERAL_NAME_push(gens, gen)) + goto merr; + gen = NULL; + if (!(point = DIST_POINT_new())) + goto merr; + if (!sk_DIST_POINT_push(crld, point)) { + DIST_POINT_free(point); + goto merr; + } + if (!(point->distpoint = DIST_POINT_NAME_new())) + goto merr; + point->distpoint->name.fullname = gens; + point->distpoint->type = 0; + gens = NULL; + } + } + return crld; + + merr: + X509V3err(X509V3_F_V2I_CRLD, ERR_R_MALLOC_FAILURE); + err: + GENERAL_NAME_free(gen); + GENERAL_NAMES_free(gens); + sk_DIST_POINT_pop_free(crld, DIST_POINT_free); + return NULL; +} + +IMPLEMENT_STACK_OF(DIST_POINT) + +IMPLEMENT_ASN1_SET_OF(DIST_POINT) + +static int dpn_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it, + void *exarg) +{ + DIST_POINT_NAME *dpn = (DIST_POINT_NAME *)*pval; + + switch (operation) { + case ASN1_OP_NEW_POST: + dpn->dpname = NULL; + break; + + case ASN1_OP_FREE_POST: + if (dpn->dpname) + X509_NAME_free(dpn->dpname); + break; + } + return 1; +} + + +ASN1_CHOICE_cb(DIST_POINT_NAME, dpn_cb) = { + ASN1_IMP_SEQUENCE_OF(DIST_POINT_NAME, name.fullname, GENERAL_NAME, 0), + ASN1_IMP_SET_OF(DIST_POINT_NAME, name.relativename, X509_NAME_ENTRY, 1) +} ASN1_CHOICE_END_cb(DIST_POINT_NAME, DIST_POINT_NAME, type) + + +IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT_NAME) + +ASN1_SEQUENCE(DIST_POINT) = { + ASN1_EXP_OPT(DIST_POINT, distpoint, DIST_POINT_NAME, 0), + ASN1_IMP_OPT(DIST_POINT, reasons, ASN1_BIT_STRING, 1), + ASN1_IMP_SEQUENCE_OF_OPT(DIST_POINT, CRLissuer, GENERAL_NAME, 2) +} ASN1_SEQUENCE_END(DIST_POINT) + +IMPLEMENT_ASN1_FUNCTIONS(DIST_POINT) + +ASN1_ITEM_TEMPLATE(CRL_DIST_POINTS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, CRLDistributionPoints, DIST_POINT) +ASN1_ITEM_TEMPLATE_END(CRL_DIST_POINTS) + +IMPLEMENT_ASN1_FUNCTIONS(CRL_DIST_POINTS) + +ASN1_SEQUENCE(ISSUING_DIST_POINT) = { + ASN1_EXP_OPT(ISSUING_DIST_POINT, distpoint, DIST_POINT_NAME, 0), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyuser, ASN1_FBOOLEAN, 1), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyCA, ASN1_FBOOLEAN, 2), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlysomereasons, ASN1_BIT_STRING, 3), + ASN1_IMP_OPT(ISSUING_DIST_POINT, indirectCRL, ASN1_FBOOLEAN, 4), + ASN1_IMP_OPT(ISSUING_DIST_POINT, onlyattr, ASN1_FBOOLEAN, 5) +} ASN1_SEQUENCE_END(ISSUING_DIST_POINT) + +IMPLEMENT_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, + int indent); +static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); + +const X509V3_EXT_METHOD v3_idp = { + NID_issuing_distribution_point, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(ISSUING_DIST_POINT), + 0, 0, 0, 0, + 0, 0, + 0, + v2i_idp, + i2r_idp, 0, + NULL +}; + +static void *v2i_idp(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + ISSUING_DIST_POINT *idp = NULL; + CONF_VALUE *cnf; + char *name, *val; + int i, ret; + idp = ISSUING_DIST_POINT_new(); + if (!idp) + goto merr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + name = cnf->name; + val = cnf->value; + ret = set_dist_point_name(&idp->distpoint, ctx, cnf); + if (ret > 0) + continue; + if (ret < 0) + goto err; + if (!strcmp(name, "onlyuser")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyuser)) + goto err; + } else if (!strcmp(name, "onlyCA")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyCA)) + goto err; + } else if (!strcmp(name, "onlyAA")) { + if (!X509V3_get_value_bool(cnf, &idp->onlyattr)) + goto err; + } else if (!strcmp(name, "indirectCRL")) { + if (!X509V3_get_value_bool(cnf, &idp->indirectCRL)) + goto err; + } else if (!strcmp(name, "onlysomereasons")) { + if (!set_reasons(&idp->onlysomereasons, val)) + goto err; + } else { + X509V3err(X509V3_F_V2I_IDP, X509V3_R_INVALID_NAME); + X509V3_conf_err(cnf); + goto err; + } + } + return idp; + + merr: + X509V3err(X509V3_F_V2I_IDP, ERR_R_MALLOC_FAILURE); + err: + ISSUING_DIST_POINT_free(idp); + return NULL; +} + +static int print_gens(BIO *out, STACK_OF(GENERAL_NAME) *gens, int indent) +{ + int i; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + BIO_printf(out, "%*s", indent + 2, ""); + GENERAL_NAME_print(out, sk_GENERAL_NAME_value(gens, i)); + BIO_puts(out, "\n"); + } + return 1; +} + +static int print_distpoint(BIO *out, DIST_POINT_NAME *dpn, int indent) +{ + if (dpn->type == 0) { + BIO_printf(out, "%*sFull Name:\n", indent, ""); + print_gens(out, dpn->name.fullname, indent); + } else { + X509_NAME ntmp; + ntmp.entries = dpn->name.relativename; + BIO_printf(out, "%*sRelative Name:\n%*s", indent, "", indent + 2, ""); + X509_NAME_print_ex(out, &ntmp, 0, XN_FLAG_ONELINE); + BIO_puts(out, "\n"); + } + return 1; +} + +static int i2r_idp(const X509V3_EXT_METHOD *method, void *pidp, BIO *out, + int indent) +{ + ISSUING_DIST_POINT *idp = pidp; + if (idp->distpoint) + print_distpoint(out, idp->distpoint, indent); + if (idp->onlyuser > 0) + BIO_printf(out, "%*sOnly User Certificates\n", indent, ""); + if (idp->onlyCA > 0) + BIO_printf(out, "%*sOnly CA Certificates\n", indent, ""); + if (idp->indirectCRL > 0) + BIO_printf(out, "%*sIndirect CRL\n", indent, ""); + if (idp->onlysomereasons) + print_reasons(out, "Only Some Reasons", idp->onlysomereasons, indent); + if (idp->onlyattr > 0) + BIO_printf(out, "%*sOnly Attribute Certificates\n", indent, ""); + if (!idp->distpoint && (idp->onlyuser <= 0) && (idp->onlyCA <= 0) + && (idp->indirectCRL <= 0) && !idp->onlysomereasons + && (idp->onlyattr <= 0)) + BIO_printf(out, "%*s\n", indent, ""); + + return 1; +} + +static int i2r_crldp(const X509V3_EXT_METHOD *method, void *pcrldp, BIO *out, + int indent) +{ + STACK_OF(DIST_POINT) *crld = pcrldp; + DIST_POINT *point; + int i; + for (i = 0; i < sk_DIST_POINT_num(crld); i++) { + BIO_puts(out, "\n"); + point = sk_DIST_POINT_value(crld, i); + if (point->distpoint) + print_distpoint(out, point->distpoint, indent); + if (point->reasons) + print_reasons(out, "Reasons", point->reasons, indent); + if (point->CRLissuer) { + BIO_printf(out, "%*sCRL Issuer:\n", indent, ""); + print_gens(out, point->CRLissuer, indent); + } + } + return 1; +} + +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname) +{ + int i; + STACK_OF(X509_NAME_ENTRY) *frag; + X509_NAME_ENTRY *ne; + if (!dpn || (dpn->type != 1)) + return 1; + frag = dpn->name.relativename; + dpn->dpname = X509_NAME_dup(iname); + if (!dpn->dpname) + return 0; + for (i = 0; i < sk_X509_NAME_ENTRY_num(frag); i++) { + ne = sk_X509_NAME_ENTRY_value(frag, i); + if (!X509_NAME_add_entry(dpn->dpname, ne, -1, i ? 0 : 1)) { + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; + } + } + /* generate cached encoding of name */ + if (i2d_X509_NAME(dpn->dpname, NULL) < 0) { + X509_NAME_free(dpn->dpname); + dpn->dpname = NULL; + return 0; + } + return 1; +} diff --git a/libs/openssl/crypto/x509v3/v3_enum.c b/libs/openssl/crypto/x509v3/v3_enum.c new file mode 100644 index 00000000..7678664f --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_enum.c @@ -0,0 +1,100 @@ +/* v3_enum.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +static ENUMERATED_NAMES crl_reasons[] = { + {CRL_REASON_UNSPECIFIED, "Unspecified", "unspecified"}, + {CRL_REASON_KEY_COMPROMISE, "Key Compromise", "keyCompromise"}, + {CRL_REASON_CA_COMPROMISE, "CA Compromise", "CACompromise"}, + {CRL_REASON_AFFILIATION_CHANGED, "Affiliation Changed", + "affiliationChanged"}, + {CRL_REASON_SUPERSEDED, "Superseded", "superseded"}, + {CRL_REASON_CESSATION_OF_OPERATION, + "Cessation Of Operation", "cessationOfOperation"}, + {CRL_REASON_CERTIFICATE_HOLD, "Certificate Hold", "certificateHold"}, + {CRL_REASON_REMOVE_FROM_CRL, "Remove From CRL", "removeFromCRL"}, + {CRL_REASON_PRIVILEGE_WITHDRAWN, "Privilege Withdrawn", + "privilegeWithdrawn"}, + {CRL_REASON_AA_COMPROMISE, "AA Compromise", "AACompromise"}, + {-1, NULL, NULL} +}; + +const X509V3_EXT_METHOD v3_crl_reason = { + NID_crl_reason, 0, ASN1_ITEM_ref(ASN1_ENUMERATED), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_ENUMERATED_TABLE, + 0, + 0, 0, 0, 0, + crl_reasons +}; + +char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *e) +{ + ENUMERATED_NAMES *enam; + long strval; + strval = ASN1_ENUMERATED_get(e); + for (enam = method->usr_data; enam->lname; enam++) { + if (strval == enam->bitnum) + return BUF_strdup(enam->lname); + } + return i2s_ASN1_ENUMERATED(method, e); +} diff --git a/libs/openssl/crypto/x509v3/v3_extku.c b/libs/openssl/crypto/x509v3/v3_extku.c new file mode 100644 index 00000000..6092c2e4 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_extku.c @@ -0,0 +1,149 @@ +/* v3_extku.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD + *method, void *eku, STACK_OF(CONF_VALUE) + *extlist); + +const X509V3_EXT_METHOD v3_ext_ku = { + NID_ext_key_usage, 0, + ASN1_ITEM_ref(EXTENDED_KEY_USAGE), + 0, 0, 0, 0, + 0, 0, + i2v_EXTENDED_KEY_USAGE, + v2i_EXTENDED_KEY_USAGE, + 0, 0, + NULL +}; + +/* NB OCSP acceptable responses also is a SEQUENCE OF OBJECT */ +const X509V3_EXT_METHOD v3_ocsp_accresp = { + NID_id_pkix_OCSP_acceptableResponses, 0, + ASN1_ITEM_ref(EXTENDED_KEY_USAGE), + 0, 0, 0, 0, + 0, 0, + i2v_EXTENDED_KEY_USAGE, + v2i_EXTENDED_KEY_USAGE, + 0, 0, + NULL +}; + +ASN1_ITEM_TEMPLATE(EXTENDED_KEY_USAGE) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, EXTENDED_KEY_USAGE, ASN1_OBJECT) +ASN1_ITEM_TEMPLATE_END(EXTENDED_KEY_USAGE) + +IMPLEMENT_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) + +static STACK_OF(CONF_VALUE) *i2v_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD + *method, void *a, STACK_OF(CONF_VALUE) + *ext_list) +{ + EXTENDED_KEY_USAGE *eku = a; + int i; + ASN1_OBJECT *obj; + char obj_tmp[80]; + for (i = 0; i < sk_ASN1_OBJECT_num(eku); i++) { + obj = sk_ASN1_OBJECT_value(eku, i); + i2t_ASN1_OBJECT(obj_tmp, 80, obj); + X509V3_add_value(NULL, obj_tmp, &ext_list); + } + return ext_list; +} + +static void *v2i_EXTENDED_KEY_USAGE(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + EXTENDED_KEY_USAGE *extku; + char *extval; + ASN1_OBJECT *objtmp; + CONF_VALUE *val; + int i; + + if (!(extku = sk_ASN1_OBJECT_new_null())) { + X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (val->value) + extval = val->value; + else + extval = val->name; + if (!(objtmp = OBJ_txt2obj(extval, 0))) { + sk_ASN1_OBJECT_pop_free(extku, ASN1_OBJECT_free); + X509V3err(X509V3_F_V2I_EXTENDED_KEY_USAGE, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return NULL; + } + sk_ASN1_OBJECT_push(extku, objtmp); + } + return extku; +} diff --git a/libs/openssl/crypto/x509v3/v3_genn.c b/libs/openssl/crypto/x509v3/v3_genn.c new file mode 100644 index 00000000..7f40bfab --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_genn.c @@ -0,0 +1,250 @@ +/* v3_genn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2008 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +ASN1_SEQUENCE(OTHERNAME) = { + ASN1_SIMPLE(OTHERNAME, type_id, ASN1_OBJECT), + /* Maybe have a true ANY DEFINED BY later */ + ASN1_EXP(OTHERNAME, value, ASN1_ANY, 0) +} ASN1_SEQUENCE_END(OTHERNAME) + +IMPLEMENT_ASN1_FUNCTIONS(OTHERNAME) + +ASN1_SEQUENCE(EDIPARTYNAME) = { + ASN1_IMP_OPT(EDIPARTYNAME, nameAssigner, DIRECTORYSTRING, 0), + ASN1_IMP_OPT(EDIPARTYNAME, partyName, DIRECTORYSTRING, 1) +} ASN1_SEQUENCE_END(EDIPARTYNAME) + +IMPLEMENT_ASN1_FUNCTIONS(EDIPARTYNAME) + +ASN1_CHOICE(GENERAL_NAME) = { + ASN1_IMP(GENERAL_NAME, d.otherName, OTHERNAME, GEN_OTHERNAME), + ASN1_IMP(GENERAL_NAME, d.rfc822Name, ASN1_IA5STRING, GEN_EMAIL), + ASN1_IMP(GENERAL_NAME, d.dNSName, ASN1_IA5STRING, GEN_DNS), + /* Don't decode this */ + ASN1_IMP(GENERAL_NAME, d.x400Address, ASN1_SEQUENCE, GEN_X400), + /* X509_NAME is a CHOICE type so use EXPLICIT */ + ASN1_EXP(GENERAL_NAME, d.directoryName, X509_NAME, GEN_DIRNAME), + ASN1_IMP(GENERAL_NAME, d.ediPartyName, EDIPARTYNAME, GEN_EDIPARTY), + ASN1_IMP(GENERAL_NAME, d.uniformResourceIdentifier, ASN1_IA5STRING, GEN_URI), + ASN1_IMP(GENERAL_NAME, d.iPAddress, ASN1_OCTET_STRING, GEN_IPADD), + ASN1_IMP(GENERAL_NAME, d.registeredID, ASN1_OBJECT, GEN_RID) +} ASN1_CHOICE_END(GENERAL_NAME) + +IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAME) + +ASN1_ITEM_TEMPLATE(GENERAL_NAMES) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, GENERAL_NAME) +ASN1_ITEM_TEMPLATE_END(GENERAL_NAMES) + +IMPLEMENT_ASN1_FUNCTIONS(GENERAL_NAMES) + +GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a) +{ + return (GENERAL_NAME *)ASN1_dup((i2d_of_void *)i2d_GENERAL_NAME, + (d2i_of_void *)d2i_GENERAL_NAME, + (char *)a); +} + +/* Returns 0 if they are equal, != 0 otherwise. */ +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b) +{ + int result = -1; + + if (!a || !b || a->type != b->type) + return -1; + switch (a->type) { + case GEN_X400: + case GEN_EDIPARTY: + result = ASN1_TYPE_cmp(a->d.other, b->d.other); + break; + + case GEN_OTHERNAME: + result = OTHERNAME_cmp(a->d.otherName, b->d.otherName); + break; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + result = ASN1_STRING_cmp(a->d.ia5, b->d.ia5); + break; + + case GEN_DIRNAME: + result = X509_NAME_cmp(a->d.dirn, b->d.dirn); + break; + + case GEN_IPADD: + result = ASN1_OCTET_STRING_cmp(a->d.ip, b->d.ip); + break; + + case GEN_RID: + result = OBJ_cmp(a->d.rid, b->d.rid); + break; + } + return result; +} + +/* Returns 0 if they are equal, != 0 otherwise. */ +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b) +{ + int result = -1; + + if (!a || !b) + return -1; + /* Check their type first. */ + if ((result = OBJ_cmp(a->type_id, b->type_id)) != 0) + return result; + /* Check the value. */ + result = ASN1_TYPE_cmp(a->value, b->value); + return result; +} + +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value) +{ + switch (type) { + case GEN_X400: + case GEN_EDIPARTY: + a->d.other = value; + break; + + case GEN_OTHERNAME: + a->d.otherName = value; + break; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + a->d.ia5 = value; + break; + + case GEN_DIRNAME: + a->d.dirn = value; + break; + + case GEN_IPADD: + a->d.ip = value; + break; + + case GEN_RID: + a->d.rid = value; + break; + } + a->type = type; +} + +void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype) +{ + if (ptype) + *ptype = a->type; + switch (a->type) { + case GEN_X400: + case GEN_EDIPARTY: + return a->d.other; + + case GEN_OTHERNAME: + return a->d.otherName; + + case GEN_EMAIL: + case GEN_DNS: + case GEN_URI: + return a->d.ia5; + + case GEN_DIRNAME: + return a->d.dirn; + + case GEN_IPADD: + return a->d.ip; + + case GEN_RID: + return a->d.rid; + + default: + return NULL; + } +} + +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value) +{ + OTHERNAME *oth; + oth = OTHERNAME_new(); + if (!oth) + return 0; + oth->type_id = oid; + oth->value = value; + GENERAL_NAME_set0_value(gen, GEN_OTHERNAME, oth); + return 1; +} + +int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue) +{ + if (gen->type != GEN_OTHERNAME) + return 0; + if (poid) + *poid = gen->d.otherName->type_id; + if (pvalue) + *pvalue = gen->d.otherName->value; + return 1; +} diff --git a/libs/openssl/crypto/x509v3/v3_ia5.c b/libs/openssl/crypto/x509v3/v3_ia5.c new file mode 100644 index 00000000..c170a55f --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_ia5.c @@ -0,0 +1,119 @@ +/* v3_ia5.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + ASN1_IA5STRING *ia5); +static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); +const X509V3_EXT_METHOD v3_ns_ia5_list[] = { + EXT_IA5STRING(NID_netscape_base_url), + EXT_IA5STRING(NID_netscape_revocation_url), + EXT_IA5STRING(NID_netscape_ca_revocation_url), + EXT_IA5STRING(NID_netscape_renewal_url), + EXT_IA5STRING(NID_netscape_ca_policy_url), + EXT_IA5STRING(NID_netscape_ssl_server_name), + EXT_IA5STRING(NID_netscape_comment), + EXT_END +}; + +static char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + ASN1_IA5STRING *ia5) +{ + char *tmp; + if (!ia5 || !ia5->length) + return NULL; + if (!(tmp = OPENSSL_malloc(ia5->length + 1))) { + X509V3err(X509V3_F_I2S_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + memcpy(tmp, ia5->data, ia5->length); + tmp[ia5->length] = 0; + return tmp; +} + +static ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str) +{ + ASN1_IA5STRING *ia5; + if (!str) { + X509V3err(X509V3_F_S2I_ASN1_IA5STRING, + X509V3_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if (!(ia5 = M_ASN1_IA5STRING_new())) + goto err; + if (!ASN1_STRING_set((ASN1_STRING *)ia5, (unsigned char *)str, + strlen(str))) { + M_ASN1_IA5STRING_free(ia5); + goto err; + } +#ifdef CHARSET_EBCDIC + ebcdic2ascii(ia5->data, ia5->data, ia5->length); +#endif /* CHARSET_EBCDIC */ + return ia5; + err: + X509V3err(X509V3_F_S2I_ASN1_IA5STRING, ERR_R_MALLOC_FAILURE); + return NULL; +} diff --git a/libs/openssl/crypto/x509v3/v3_info.c b/libs/openssl/crypto/x509v3/v3_info.c new file mode 100644 index 00000000..e052a34b --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_info.c @@ -0,0 +1,210 @@ +/* v3_info.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD + *method, AUTHORITY_INFO_ACCESS + *ainfo, STACK_OF(CONF_VALUE) + *ret); +static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD + *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) + *nval); + +const X509V3_EXT_METHOD v3_info = { NID_info_access, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS, + (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, + 0, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_sinfo = { NID_sinfo_access, X509V3_EXT_MULTILINE, + ASN1_ITEM_ref(AUTHORITY_INFO_ACCESS), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V) i2v_AUTHORITY_INFO_ACCESS, + (X509V3_EXT_V2I)v2i_AUTHORITY_INFO_ACCESS, + 0, 0, + NULL +}; + +ASN1_SEQUENCE(ACCESS_DESCRIPTION) = { + ASN1_SIMPLE(ACCESS_DESCRIPTION, method, ASN1_OBJECT), + ASN1_SIMPLE(ACCESS_DESCRIPTION, location, GENERAL_NAME) +} ASN1_SEQUENCE_END(ACCESS_DESCRIPTION) + +IMPLEMENT_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) + +ASN1_ITEM_TEMPLATE(AUTHORITY_INFO_ACCESS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, GeneralNames, ACCESS_DESCRIPTION) +ASN1_ITEM_TEMPLATE_END(AUTHORITY_INFO_ACCESS) + +IMPLEMENT_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) + +static STACK_OF(CONF_VALUE) *i2v_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD + *method, AUTHORITY_INFO_ACCESS + *ainfo, STACK_OF(CONF_VALUE) + *ret) +{ + ACCESS_DESCRIPTION *desc; + int i, nlen; + char objtmp[80], *ntmp; + CONF_VALUE *vtmp; + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(ainfo); i++) { + desc = sk_ACCESS_DESCRIPTION_value(ainfo, i); + ret = i2v_GENERAL_NAME(method, desc->location, ret); + if (!ret) + break; + vtmp = sk_CONF_VALUE_value(ret, i); + i2t_ASN1_OBJECT(objtmp, sizeof objtmp, desc->method); + nlen = strlen(objtmp) + strlen(vtmp->name) + 5; + ntmp = OPENSSL_malloc(nlen); + if (!ntmp) { + X509V3err(X509V3_F_I2V_AUTHORITY_INFO_ACCESS, + ERR_R_MALLOC_FAILURE); + return NULL; + } + BUF_strlcpy(ntmp, objtmp, nlen); + BUF_strlcat(ntmp, " - ", nlen); + BUF_strlcat(ntmp, vtmp->name, nlen); + OPENSSL_free(vtmp->name); + vtmp->name = ntmp; + + } + if (!ret) + return sk_CONF_VALUE_new_null(); + return ret; +} + +static AUTHORITY_INFO_ACCESS *v2i_AUTHORITY_INFO_ACCESS(X509V3_EXT_METHOD + *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) + *nval) +{ + AUTHORITY_INFO_ACCESS *ainfo = NULL; + CONF_VALUE *cnf, ctmp; + ACCESS_DESCRIPTION *acc; + int i, objlen; + char *objtmp, *ptmp; + if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!(acc = ACCESS_DESCRIPTION_new()) + || !sk_ACCESS_DESCRIPTION_push(ainfo, acc)) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, + ERR_R_MALLOC_FAILURE); + goto err; + } + ptmp = strchr(cnf->name, ';'); + if (!ptmp) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, + X509V3_R_INVALID_SYNTAX); + goto err; + } + objlen = ptmp - cnf->name; + ctmp.name = ptmp + 1; + ctmp.value = cnf->value; + if (!v2i_GENERAL_NAME_ex(acc->location, method, ctx, &ctmp, 0)) + goto err; + if (!(objtmp = OPENSSL_malloc(objlen + 1))) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, + ERR_R_MALLOC_FAILURE); + goto err; + } + strncpy(objtmp, cnf->name, objlen); + objtmp[objlen] = 0; + acc->method = OBJ_txt2obj(objtmp, 0); + if (!acc->method) { + X509V3err(X509V3_F_V2I_AUTHORITY_INFO_ACCESS, + X509V3_R_BAD_OBJECT); + ERR_add_error_data(2, "value=", objtmp); + OPENSSL_free(objtmp); + goto err; + } + OPENSSL_free(objtmp); + + } + return ainfo; + err: + sk_ACCESS_DESCRIPTION_pop_free(ainfo, ACCESS_DESCRIPTION_free); + return NULL; +} + +int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a) +{ + i2a_ASN1_OBJECT(bp, a->method); +#ifdef UNDEF + i2a_GENERAL_NAME(bp, a->location); +#endif + return 2; +} diff --git a/libs/openssl/crypto/x509v3/v3_int.c b/libs/openssl/crypto/x509v3/v3_int.c new file mode 100644 index 00000000..8bfdb37e --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_int.c @@ -0,0 +1,92 @@ +/* v3_int.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +const X509V3_EXT_METHOD v3_crl_num = { + NID_crl_number, 0, ASN1_ITEM_ref(ASN1_INTEGER), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + 0, + 0, 0, 0, 0, NULL +}; + +const X509V3_EXT_METHOD v3_delta_crl = { + NID_delta_crl, 0, ASN1_ITEM_ref(ASN1_INTEGER), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + 0, + 0, 0, 0, 0, NULL +}; + +static void *s2i_asn1_int(X509V3_EXT_METHOD *meth, X509V3_CTX *ctx, + char *value) +{ + return s2i_ASN1_INTEGER(meth, value); +} + +const X509V3_EXT_METHOD v3_inhibit_anyp = { + NID_inhibit_any_policy, 0, ASN1_ITEM_ref(ASN1_INTEGER), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_INTEGER, + (X509V3_EXT_S2I)s2i_asn1_int, + 0, 0, 0, 0, NULL +}; diff --git a/libs/openssl/crypto/x509v3/v3_lib.c b/libs/openssl/crypto/x509v3/v3_lib.c new file mode 100644 index 00000000..b5598c9a --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_lib.c @@ -0,0 +1,341 @@ +/* v3_lib.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* X509 v3 extension utilities */ + +#include +#include "cryptlib.h" +#include +#include + +#include "ext_dat.h" + +static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL; + +static int ext_cmp(const X509V3_EXT_METHOD *const *a, + const X509V3_EXT_METHOD *const *b); +static void ext_list_free(X509V3_EXT_METHOD *ext); + +int X509V3_EXT_add(X509V3_EXT_METHOD *ext) +{ + if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_cmp))) { + X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) { + X509V3err(X509V3_F_X509V3_EXT_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +static int ext_cmp(const X509V3_EXT_METHOD *const *a, + const X509V3_EXT_METHOD *const *b) +{ + return ((*a)->ext_nid - (*b)->ext_nid); +} + +DECLARE_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, + const X509V3_EXT_METHOD *, ext); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(const X509V3_EXT_METHOD *, + const X509V3_EXT_METHOD *, ext); + +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) +{ + X509V3_EXT_METHOD tmp; + const X509V3_EXT_METHOD *t = &tmp, *const *ret; + int idx; + if (nid < 0) + return NULL; + tmp.ext_nid = nid; + ret = OBJ_bsearch_ext(&t, standard_exts, STANDARD_EXTENSION_COUNT); + if (ret) + return *ret; + if (!ext_list) + return NULL; + idx = sk_X509V3_EXT_METHOD_find(ext_list, &tmp); + if (idx == -1) + return NULL; + return sk_X509V3_EXT_METHOD_value(ext_list, idx); +} + +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext) +{ + int nid; + if ((nid = OBJ_obj2nid(ext->object)) == NID_undef) + return NULL; + return X509V3_EXT_get_nid(nid); +} + +int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist) +{ + for (; extlist->ext_nid != -1; extlist++) + if (!X509V3_EXT_add(extlist)) + return 0; + return 1; +} + +int X509V3_EXT_add_alias(int nid_to, int nid_from) +{ + const X509V3_EXT_METHOD *ext; + X509V3_EXT_METHOD *tmpext; + + if (!(ext = X509V3_EXT_get_nid(nid_from))) { + X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, + X509V3_R_EXTENSION_NOT_FOUND); + return 0; + } + if (! + (tmpext = + (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) { + X509V3err(X509V3_F_X509V3_EXT_ADD_ALIAS, ERR_R_MALLOC_FAILURE); + return 0; + } + *tmpext = *ext; + tmpext->ext_nid = nid_to; + tmpext->ext_flags |= X509V3_EXT_DYNAMIC; + return X509V3_EXT_add(tmpext); +} + +void X509V3_EXT_cleanup(void) +{ + sk_X509V3_EXT_METHOD_pop_free(ext_list, ext_list_free); + ext_list = NULL; +} + +static void ext_list_free(X509V3_EXT_METHOD *ext) +{ + if (ext->ext_flags & X509V3_EXT_DYNAMIC) + OPENSSL_free(ext); +} + +/* + * Legacy function: we don't need to add standard extensions any more because + * they are now kept in ext_dat.h. + */ + +int X509V3_add_standard_extensions(void) +{ + return 1; +} + +/* Return an extension internal structure */ + +void *X509V3_EXT_d2i(X509_EXTENSION *ext) +{ + const X509V3_EXT_METHOD *method; + const unsigned char *p; + + if (!(method = X509V3_EXT_get(ext))) + return NULL; + p = ext->value->data; + if (method->it) + return ASN1_item_d2i(NULL, &p, ext->value->length, + ASN1_ITEM_ptr(method->it)); + return method->d2i(NULL, &p, ext->value->length); +} + +/*- + * Get critical flag and decoded version of extension from a NID. + * The "idx" variable returns the last found extension and can + * be used to retrieve multiple extensions of the same NID. + * However multiple extensions with the same NID is usually + * due to a badly encoded certificate so if idx is NULL we + * choke if multiple extensions exist. + * The "crit" variable is set to the critical value. + * The return value is the decoded extension or NULL on + * error. The actual error can have several different causes, + * the value of *crit reflects the cause: + * >= 0, extension found but not decoded (reflects critical value). + * -1 extension not found. + * -2 extension occurs more than once. + */ + +void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, + int *idx) +{ + int lastpos, i; + X509_EXTENSION *ex, *found_ex = NULL; + if (!x) { + if (idx) + *idx = -1; + if (crit) + *crit = -1; + return NULL; + } + if (idx) + lastpos = *idx + 1; + else + lastpos = 0; + if (lastpos < 0) + lastpos = 0; + for (i = lastpos; i < sk_X509_EXTENSION_num(x); i++) { + ex = sk_X509_EXTENSION_value(x, i); + if (OBJ_obj2nid(ex->object) == nid) { + if (idx) { + *idx = i; + found_ex = ex; + break; + } else if (found_ex) { + /* Found more than one */ + if (crit) + *crit = -2; + return NULL; + } + found_ex = ex; + } + } + if (found_ex) { + /* Found it */ + if (crit) + *crit = X509_EXTENSION_get_critical(found_ex); + return X509V3_EXT_d2i(found_ex); + } + + /* Extension not found */ + if (idx) + *idx = -1; + if (crit) + *crit = -1; + return NULL; +} + +/* + * This function is a general extension append, replace and delete utility. + * The precise operation is governed by the 'flags' value. The 'crit' and + * 'value' arguments (if relevant) are the extensions internal structure. + */ + +int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, + int crit, unsigned long flags) +{ + int extidx = -1; + int errcode; + X509_EXTENSION *ext, *extmp; + unsigned long ext_op = flags & X509V3_ADD_OP_MASK; + + /* + * If appending we don't care if it exists, otherwise look for existing + * extension. + */ + if (ext_op != X509V3_ADD_APPEND) + extidx = X509v3_get_ext_by_NID(*x, nid, -1); + + /* See if extension exists */ + if (extidx >= 0) { + /* If keep existing, nothing to do */ + if (ext_op == X509V3_ADD_KEEP_EXISTING) + return 1; + /* If default then its an error */ + if (ext_op == X509V3_ADD_DEFAULT) { + errcode = X509V3_R_EXTENSION_EXISTS; + goto err; + } + /* If delete, just delete it */ + if (ext_op == X509V3_ADD_DELETE) { + if (!sk_X509_EXTENSION_delete(*x, extidx)) + return -1; + return 1; + } + } else { + /* + * If replace existing or delete, error since extension must exist + */ + if ((ext_op == X509V3_ADD_REPLACE_EXISTING) || + (ext_op == X509V3_ADD_DELETE)) { + errcode = X509V3_R_EXTENSION_NOT_FOUND; + goto err; + } + } + + /* + * If we get this far then we have to create an extension: could have + * some flags for alternative encoding schemes... + */ + + ext = X509V3_EXT_i2d(nid, crit, value); + + if (!ext) { + X509V3err(X509V3_F_X509V3_ADD1_I2D, + X509V3_R_ERROR_CREATING_EXTENSION); + return 0; + } + + /* If extension exists replace it.. */ + if (extidx >= 0) { + extmp = sk_X509_EXTENSION_value(*x, extidx); + X509_EXTENSION_free(extmp); + if (!sk_X509_EXTENSION_set(*x, extidx, ext)) + return -1; + return 1; + } + + if (!*x && !(*x = sk_X509_EXTENSION_new_null())) + return -1; + if (!sk_X509_EXTENSION_push(*x, ext)) + return -1; + + return 1; + + err: + if (!(flags & X509V3_ADD_SILENT)) + X509V3err(X509V3_F_X509V3_ADD1_I2D, errcode); + return 0; +} + +IMPLEMENT_STACK_OF(X509V3_EXT_METHOD) diff --git a/libs/openssl/crypto/x509v3/v3_ncons.c b/libs/openssl/crypto/x509v3/v3_ncons.c new file mode 100644 index 00000000..28552696 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_ncons.c @@ -0,0 +1,479 @@ +/* v3_ncons.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, + BIO *bp, int ind); +static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, + STACK_OF(GENERAL_SUBTREE) *trees, BIO *bp, + int ind, char *name); +static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip); + +static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc); +static int nc_match_single(GENERAL_NAME *sub, GENERAL_NAME *gen); +static int nc_dn(X509_NAME *sub, X509_NAME *nm); +static int nc_dns(ASN1_IA5STRING *sub, ASN1_IA5STRING *dns); +static int nc_email(ASN1_IA5STRING *sub, ASN1_IA5STRING *eml); +static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base); + +const X509V3_EXT_METHOD v3_name_constraints = { + NID_name_constraints, 0, + ASN1_ITEM_ref(NAME_CONSTRAINTS), + 0, 0, 0, 0, + 0, 0, + 0, v2i_NAME_CONSTRAINTS, + i2r_NAME_CONSTRAINTS, 0, + NULL +}; + +ASN1_SEQUENCE(GENERAL_SUBTREE) = { + ASN1_SIMPLE(GENERAL_SUBTREE, base, GENERAL_NAME), + ASN1_IMP_OPT(GENERAL_SUBTREE, minimum, ASN1_INTEGER, 0), + ASN1_IMP_OPT(GENERAL_SUBTREE, maximum, ASN1_INTEGER, 1) +} ASN1_SEQUENCE_END(GENERAL_SUBTREE) + +ASN1_SEQUENCE(NAME_CONSTRAINTS) = { + ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, permittedSubtrees, + GENERAL_SUBTREE, 0), + ASN1_IMP_SEQUENCE_OF_OPT(NAME_CONSTRAINTS, excludedSubtrees, + GENERAL_SUBTREE, 1), +} ASN1_SEQUENCE_END(NAME_CONSTRAINTS) + + +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) + +static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + int i; + CONF_VALUE tval, *val; + STACK_OF(GENERAL_SUBTREE) **ptree = NULL; + NAME_CONSTRAINTS *ncons = NULL; + GENERAL_SUBTREE *sub = NULL; + ncons = NAME_CONSTRAINTS_new(); + if (!ncons) + goto memerr; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!strncmp(val->name, "permitted", 9) && val->name[9]) { + ptree = &ncons->permittedSubtrees; + tval.name = val->name + 10; + } else if (!strncmp(val->name, "excluded", 8) && val->name[8]) { + ptree = &ncons->excludedSubtrees; + tval.name = val->name + 9; + } else { + X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, X509V3_R_INVALID_SYNTAX); + goto err; + } + tval.value = val->value; + sub = GENERAL_SUBTREE_new(); + if (sub == NULL) + goto memerr; + if (!v2i_GENERAL_NAME_ex(sub->base, method, ctx, &tval, 1)) + goto err; + if (!*ptree) + *ptree = sk_GENERAL_SUBTREE_new_null(); + if (!*ptree || !sk_GENERAL_SUBTREE_push(*ptree, sub)) + goto memerr; + sub = NULL; + } + + return ncons; + + memerr: + X509V3err(X509V3_F_V2I_NAME_CONSTRAINTS, ERR_R_MALLOC_FAILURE); + err: + if (ncons) + NAME_CONSTRAINTS_free(ncons); + if (sub) + GENERAL_SUBTREE_free(sub); + + return NULL; +} + +static int i2r_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, void *a, + BIO *bp, int ind) +{ + NAME_CONSTRAINTS *ncons = a; + do_i2r_name_constraints(method, ncons->permittedSubtrees, + bp, ind, "Permitted"); + do_i2r_name_constraints(method, ncons->excludedSubtrees, + bp, ind, "Excluded"); + return 1; +} + +static int do_i2r_name_constraints(const X509V3_EXT_METHOD *method, + STACK_OF(GENERAL_SUBTREE) *trees, + BIO *bp, int ind, char *name) +{ + GENERAL_SUBTREE *tree; + int i; + if (sk_GENERAL_SUBTREE_num(trees) > 0) + BIO_printf(bp, "%*s%s:\n", ind, "", name); + for (i = 0; i < sk_GENERAL_SUBTREE_num(trees); i++) { + tree = sk_GENERAL_SUBTREE_value(trees, i); + BIO_printf(bp, "%*s", ind + 2, ""); + if (tree->base->type == GEN_IPADD) + print_nc_ipadd(bp, tree->base->d.ip); + else + GENERAL_NAME_print(bp, tree->base); + BIO_puts(bp, "\n"); + } + return 1; +} + +static int print_nc_ipadd(BIO *bp, ASN1_OCTET_STRING *ip) +{ + int i, len; + unsigned char *p; + p = ip->data; + len = ip->length; + BIO_puts(bp, "IP:"); + if (len == 8) { + BIO_printf(bp, "%d.%d.%d.%d/%d.%d.%d.%d", + p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); + } else if (len == 32) { + for (i = 0; i < 16; i++) { + BIO_printf(bp, "%X", p[0] << 8 | p[1]); + p += 2; + if (i == 7) + BIO_puts(bp, "/"); + else if (i != 15) + BIO_puts(bp, ":"); + } + } else + BIO_printf(bp, "IP Address:"); + return 1; +} + +/*- + * Check a certificate conforms to a specified set of constraints. + * Return values: + * X509_V_OK: All constraints obeyed. + * X509_V_ERR_PERMITTED_VIOLATION: Permitted subtree violation. + * X509_V_ERR_EXCLUDED_VIOLATION: Excluded subtree violation. + * X509_V_ERR_SUBTREE_MINMAX: Min or max values present and matching type. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: bad unsupported constraint syntax. + * X509_V_ERR_UNSUPPORTED_NAME_SYNTAX: bad or unsupported syntax of name + */ + +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc) +{ + int r, i; + X509_NAME *nm; + + nm = X509_get_subject_name(x); + + if (X509_NAME_entry_count(nm) > 0) { + GENERAL_NAME gntmp; + gntmp.type = GEN_DIRNAME; + gntmp.d.directoryName = nm; + + r = nc_match(&gntmp, nc); + + if (r != X509_V_OK) + return r; + + gntmp.type = GEN_EMAIL; + + /* Process any email address attributes in subject name */ + + for (i = -1;;) { + X509_NAME_ENTRY *ne; + i = X509_NAME_get_index_by_NID(nm, NID_pkcs9_emailAddress, i); + if (i == -1) + break; + ne = X509_NAME_get_entry(nm, i); + gntmp.d.rfc822Name = X509_NAME_ENTRY_get_data(ne); + if (gntmp.d.rfc822Name->type != V_ASN1_IA5STRING) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + + r = nc_match(&gntmp, nc); + + if (r != X509_V_OK) + return r; + } + + } + + for (i = 0; i < sk_GENERAL_NAME_num(x->altname); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, i); + r = nc_match(gen, nc); + if (r != X509_V_OK) + return r; + } + + return X509_V_OK; + +} + +static int nc_match(GENERAL_NAME *gen, NAME_CONSTRAINTS *nc) +{ + GENERAL_SUBTREE *sub; + int i, r, match = 0; + + /* + * Permitted subtrees: if any subtrees exist of matching the type at + * least one subtree must match. + */ + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees); i++) { + sub = sk_GENERAL_SUBTREE_value(nc->permittedSubtrees, i); + if (gen->type != sub->base->type) + continue; + if (sub->minimum || sub->maximum) + return X509_V_ERR_SUBTREE_MINMAX; + /* If we already have a match don't bother trying any more */ + if (match == 2) + continue; + if (match == 0) + match = 1; + r = nc_match_single(gen, sub->base); + if (r == X509_V_OK) + match = 2; + else if (r != X509_V_ERR_PERMITTED_VIOLATION) + return r; + } + + if (match == 1) + return X509_V_ERR_PERMITTED_VIOLATION; + + /* Excluded subtrees: must not match any of these */ + + for (i = 0; i < sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); i++) { + sub = sk_GENERAL_SUBTREE_value(nc->excludedSubtrees, i); + if (gen->type != sub->base->type) + continue; + if (sub->minimum || sub->maximum) + return X509_V_ERR_SUBTREE_MINMAX; + + r = nc_match_single(gen, sub->base); + if (r == X509_V_OK) + return X509_V_ERR_EXCLUDED_VIOLATION; + else if (r != X509_V_ERR_PERMITTED_VIOLATION) + return r; + + } + + return X509_V_OK; + +} + +static int nc_match_single(GENERAL_NAME *gen, GENERAL_NAME *base) +{ + switch (base->type) { + case GEN_DIRNAME: + return nc_dn(gen->d.directoryName, base->d.directoryName); + + case GEN_DNS: + return nc_dns(gen->d.dNSName, base->d.dNSName); + + case GEN_EMAIL: + return nc_email(gen->d.rfc822Name, base->d.rfc822Name); + + case GEN_URI: + return nc_uri(gen->d.uniformResourceIdentifier, + base->d.uniformResourceIdentifier); + + default: + return X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE; + } + +} + +/* + * directoryName name constraint matching. The canonical encoding of + * X509_NAME makes this comparison easy. It is matched if the subtree is a + * subset of the name. + */ + +static int nc_dn(X509_NAME *nm, X509_NAME *base) +{ + /* Ensure canonical encodings are up to date. */ + if (nm->modified && i2d_X509_NAME(nm, NULL) < 0) + return X509_V_ERR_OUT_OF_MEM; + if (base->modified && i2d_X509_NAME(base, NULL) < 0) + return X509_V_ERR_OUT_OF_MEM; + if (base->canon_enclen > nm->canon_enclen) + return X509_V_ERR_PERMITTED_VIOLATION; + if (memcmp(base->canon_enc, nm->canon_enc, base->canon_enclen)) + return X509_V_ERR_PERMITTED_VIOLATION; + return X509_V_OK; +} + +static int nc_dns(ASN1_IA5STRING *dns, ASN1_IA5STRING *base) +{ + char *baseptr = (char *)base->data; + char *dnsptr = (char *)dns->data; + /* Empty matches everything */ + if (!*baseptr) + return X509_V_OK; + /* + * Otherwise can add zero or more components on the left so compare RHS + * and if dns is longer and expect '.' as preceding character. + */ + if (dns->length > base->length) { + dnsptr += dns->length - base->length; + if (*baseptr != '.' && dnsptr[-1] != '.') + return X509_V_ERR_PERMITTED_VIOLATION; + } + + if (strcasecmp(baseptr, dnsptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; + +} + +static int nc_email(ASN1_IA5STRING *eml, ASN1_IA5STRING *base) +{ + const char *baseptr = (char *)base->data; + const char *emlptr = (char *)eml->data; + + const char *baseat = strchr(baseptr, '@'); + const char *emlat = strchr(emlptr, '@'); + if (!emlat) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + /* Special case: inital '.' is RHS match */ + if (!baseat && (*baseptr == '.')) { + if (eml->length > base->length) { + emlptr += eml->length - base->length; + if (!strcasecmp(baseptr, emlptr)) + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + /* If we have anything before '@' match local part */ + + if (baseat) { + if (baseat != baseptr) { + if ((baseat - baseptr) != (emlat - emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + /* Case sensitive match of local part */ + if (strncmp(baseptr, emlptr, emlat - emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + } + /* Position base after '@' */ + baseptr = baseat + 1; + } + emlptr = emlat + 1; + /* Just have hostname left to match: case insensitive */ + if (strcasecmp(baseptr, emlptr)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; + +} + +static int nc_uri(ASN1_IA5STRING *uri, ASN1_IA5STRING *base) +{ + const char *baseptr = (char *)base->data; + const char *hostptr = (char *)uri->data; + const char *p = strchr(hostptr, ':'); + int hostlen; + /* Check for foo:// and skip past it */ + if (!p || (p[1] != '/') || (p[2] != '/')) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + hostptr = p + 3; + + /* Determine length of hostname part of URI */ + + /* Look for a port indicator as end of hostname first */ + + p = strchr(hostptr, ':'); + /* Otherwise look for trailing slash */ + if (!p) + p = strchr(hostptr, '/'); + + if (!p) + hostlen = strlen(hostptr); + else + hostlen = p - hostptr; + + if (hostlen == 0) + return X509_V_ERR_UNSUPPORTED_NAME_SYNTAX; + + /* Special case: inital '.' is RHS match */ + if (*baseptr == '.') { + if (hostlen > base->length) { + p = hostptr + hostlen - base->length; + if (!strncasecmp(p, baseptr, base->length)) + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + if ((base->length != (int)hostlen) + || strncasecmp(hostptr, baseptr, hostlen)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; + +} diff --git a/libs/openssl/crypto/x509v3/v3_ocsp.c b/libs/openssl/crypto/x509v3/v3_ocsp.c new file mode 100644 index 00000000..b151eacc --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_ocsp.c @@ -0,0 +1,312 @@ +/* v3_ocsp.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef OPENSSL_NO_OCSP + +# include +# include "cryptlib.h" +# include +# include +# include +# include + +/* + * OCSP extensions and a couple of CRL entry extensions + */ + +static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); +static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); +static int i2r_object(const X509V3_EXT_METHOD *method, void *obj, BIO *out, + int indent); + +static void *ocsp_nonce_new(void); +static int i2d_ocsp_nonce(void *a, unsigned char **pp); +static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length); +static void ocsp_nonce_free(void *a); +static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent); + +static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, + void *nocheck, BIO *out, int indent); +static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); +static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, + BIO *bp, int ind); + +const X509V3_EXT_METHOD v3_ocsp_crlid = { + NID_id_pkix_OCSP_CrlID, 0, ASN1_ITEM_ref(OCSP_CRLID), + 0, 0, 0, 0, + 0, 0, + 0, 0, + i2r_ocsp_crlid, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_ocsp_acutoff = { + NID_id_pkix_OCSP_archiveCutoff, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), + 0, 0, 0, 0, + 0, 0, + 0, 0, + i2r_ocsp_acutoff, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_crl_invdate = { + NID_invalidity_date, 0, ASN1_ITEM_ref(ASN1_GENERALIZEDTIME), + 0, 0, 0, 0, + 0, 0, + 0, 0, + i2r_ocsp_acutoff, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_crl_hold = { + NID_hold_instruction_code, 0, ASN1_ITEM_ref(ASN1_OBJECT), + 0, 0, 0, 0, + 0, 0, + 0, 0, + i2r_object, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_ocsp_nonce = { + NID_id_pkix_OCSP_Nonce, 0, NULL, + ocsp_nonce_new, + ocsp_nonce_free, + d2i_ocsp_nonce, + i2d_ocsp_nonce, + 0, 0, + 0, 0, + i2r_ocsp_nonce, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_ocsp_nocheck = { + NID_id_pkix_OCSP_noCheck, 0, ASN1_ITEM_ref(ASN1_NULL), + 0, 0, 0, 0, + 0, s2i_ocsp_nocheck, + 0, 0, + i2r_ocsp_nocheck, 0, + NULL +}; + +const X509V3_EXT_METHOD v3_ocsp_serviceloc = { + NID_id_pkix_OCSP_serviceLocator, 0, ASN1_ITEM_ref(OCSP_SERVICELOC), + 0, 0, 0, 0, + 0, 0, + 0, 0, + i2r_ocsp_serviceloc, 0, + NULL +}; + +static int i2r_ocsp_crlid(const X509V3_EXT_METHOD *method, void *in, BIO *bp, + int ind) +{ + OCSP_CRLID *a = in; + if (a->crlUrl) { + if (BIO_printf(bp, "%*scrlUrl: ", ind, "") <= 0) + goto err; + if (!ASN1_STRING_print(bp, (ASN1_STRING *)a->crlUrl)) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (a->crlNum) { + if (BIO_printf(bp, "%*scrlNum: ", ind, "") <= 0) + goto err; + if (i2a_ASN1_INTEGER(bp, a->crlNum) <= 0) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + if (a->crlTime) { + if (BIO_printf(bp, "%*scrlTime: ", ind, "") <= 0) + goto err; + if (!ASN1_GENERALIZEDTIME_print(bp, a->crlTime)) + goto err; + if (BIO_write(bp, "\n", 1) <= 0) + goto err; + } + return 1; + err: + return 0; +} + +static int i2r_ocsp_acutoff(const X509V3_EXT_METHOD *method, void *cutoff, + BIO *bp, int ind) +{ + if (BIO_printf(bp, "%*s", ind, "") <= 0) + return 0; + if (!ASN1_GENERALIZEDTIME_print(bp, cutoff)) + return 0; + return 1; +} + +static int i2r_object(const X509V3_EXT_METHOD *method, void *oid, BIO *bp, + int ind) +{ + if (BIO_printf(bp, "%*s", ind, "") <= 0) + return 0; + if (i2a_ASN1_OBJECT(bp, oid) <= 0) + return 0; + return 1; +} + +/* + * OCSP nonce. This is needs special treatment because it doesn't have an + * ASN1 encoding at all: it just contains arbitrary data. + */ + +static void *ocsp_nonce_new(void) +{ + return ASN1_OCTET_STRING_new(); +} + +static int i2d_ocsp_nonce(void *a, unsigned char **pp) +{ + ASN1_OCTET_STRING *os = a; + if (pp) { + memcpy(*pp, os->data, os->length); + *pp += os->length; + } + return os->length; +} + +static void *d2i_ocsp_nonce(void *a, const unsigned char **pp, long length) +{ + ASN1_OCTET_STRING *os, **pos; + pos = a; + if (!pos || !*pos) + os = ASN1_OCTET_STRING_new(); + else + os = *pos; + if (!ASN1_OCTET_STRING_set(os, *pp, length)) + goto err; + + *pp += length; + + if (pos) + *pos = os; + return os; + + err: + if (os && (!pos || (*pos != os))) + M_ASN1_OCTET_STRING_free(os); + OCSPerr(OCSP_F_D2I_OCSP_NONCE, ERR_R_MALLOC_FAILURE); + return NULL; +} + +static void ocsp_nonce_free(void *a) +{ + M_ASN1_OCTET_STRING_free(a); +} + +static int i2r_ocsp_nonce(const X509V3_EXT_METHOD *method, void *nonce, + BIO *out, int indent) +{ + if (BIO_printf(out, "%*s", indent, "") <= 0) + return 0; + if (i2a_ASN1_STRING(out, nonce, V_ASN1_OCTET_STRING) <= 0) + return 0; + return 1; +} + +/* Nocheck is just a single NULL. Don't print anything and always set it */ + +static int i2r_ocsp_nocheck(const X509V3_EXT_METHOD *method, void *nocheck, + BIO *out, int indent) +{ + return 1; +} + +static void *s2i_ocsp_nocheck(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str) +{ + return ASN1_NULL_new(); +} + +static int i2r_ocsp_serviceloc(const X509V3_EXT_METHOD *method, void *in, + BIO *bp, int ind) +{ + int i; + OCSP_SERVICELOC *a = in; + ACCESS_DESCRIPTION *ad; + + if (BIO_printf(bp, "%*sIssuer: ", ind, "") <= 0) + goto err; + if (X509_NAME_print_ex(bp, a->issuer, 0, XN_FLAG_ONELINE) <= 0) + goto err; + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(a->locator); i++) { + ad = sk_ACCESS_DESCRIPTION_value(a->locator, i); + if (BIO_printf(bp, "\n%*s", (2 * ind), "") <= 0) + goto err; + if (i2a_ASN1_OBJECT(bp, ad->method) <= 0) + goto err; + if (BIO_puts(bp, " - ") <= 0) + goto err; + if (GENERAL_NAME_print(bp, ad->location) <= 0) + goto err; + } + return 1; + err: + return 0; +} +#endif diff --git a/libs/openssl/crypto/x509v3/v3_pci.c b/libs/openssl/crypto/x509v3/v3_pci.c new file mode 100644 index 00000000..34cad53c --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_pci.c @@ -0,0 +1,317 @@ +/* v3_pci.c */ +/* + * Contributed to the OpenSSL Project 2004 by Richard Levitte + * (richard@levitte.org) + */ +/* Copyright (c) 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include "cryptlib.h" +#include +#include + +static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *ext, + BIO *out, int indent); +static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); + +const X509V3_EXT_METHOD v3_pci = + { NID_proxyCertInfo, 0, ASN1_ITEM_ref(PROXY_CERT_INFO_EXTENSION), + 0, 0, 0, 0, + 0, 0, + NULL, NULL, + (X509V3_EXT_I2R)i2r_pci, + (X509V3_EXT_R2I)r2i_pci, + NULL, +}; + +static int i2r_pci(X509V3_EXT_METHOD *method, PROXY_CERT_INFO_EXTENSION *pci, + BIO *out, int indent) +{ + BIO_printf(out, "%*sPath Length Constraint: ", indent, ""); + if (pci->pcPathLengthConstraint) + i2a_ASN1_INTEGER(out, pci->pcPathLengthConstraint); + else + BIO_printf(out, "infinite"); + BIO_puts(out, "\n"); + BIO_printf(out, "%*sPolicy Language: ", indent, ""); + i2a_ASN1_OBJECT(out, pci->proxyPolicy->policyLanguage); + BIO_puts(out, "\n"); + if (pci->proxyPolicy->policy && pci->proxyPolicy->policy->data) + BIO_printf(out, "%*sPolicy Text: %s\n", indent, "", + pci->proxyPolicy->policy->data); + return 1; +} + +static int process_pci_value(CONF_VALUE *val, + ASN1_OBJECT **language, ASN1_INTEGER **pathlen, + ASN1_OCTET_STRING **policy) +{ + int free_policy = 0; + + if (strcmp(val->name, "language") == 0) { + if (*language) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED); + X509V3_conf_err(val); + return 0; + } + if (!(*language = OBJ_txt2obj(val->value, 0))) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return 0; + } + } else if (strcmp(val->name, "pathlen") == 0) { + if (*pathlen) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED); + X509V3_conf_err(val); + return 0; + } + if (!X509V3_get_value_int(val, pathlen)) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_POLICY_PATH_LENGTH); + X509V3_conf_err(val); + return 0; + } + } else if (strcmp(val->name, "policy") == 0) { + unsigned char *tmp_data = NULL; + long val_len; + if (!*policy) { + *policy = ASN1_OCTET_STRING_new(); + if (!*policy) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + return 0; + } + free_policy = 1; + } + if (strncmp(val->value, "hex:", 4) == 0) { + unsigned char *tmp_data2 = + string_to_hex(val->value + 4, &val_len); + + if (!tmp_data2) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_ILLEGAL_HEX_DIGIT); + X509V3_conf_err(val); + goto err; + } + + tmp_data = OPENSSL_realloc((*policy)->data, + (*policy)->length + val_len + 1); + if (tmp_data) { + (*policy)->data = tmp_data; + memcpy(&(*policy)->data[(*policy)->length], + tmp_data2, val_len); + (*policy)->length += val_len; + (*policy)->data[(*policy)->length] = '\0'; + } else { + OPENSSL_free(tmp_data2); + /* + * realloc failure implies the original data space is b0rked + * too! + */ + (*policy)->data = NULL; + (*policy)->length = 0; + X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + OPENSSL_free(tmp_data2); + } else if (strncmp(val->value, "file:", 5) == 0) { + unsigned char buf[2048]; + int n; + BIO *b = BIO_new_file(val->value + 5, "r"); + if (!b) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB); + X509V3_conf_err(val); + goto err; + } + while ((n = BIO_read(b, buf, sizeof(buf))) > 0 + || (n == 0 && BIO_should_retry(b))) { + if (!n) + continue; + + tmp_data = OPENSSL_realloc((*policy)->data, + (*policy)->length + n + 1); + + if (!tmp_data) + break; + + (*policy)->data = tmp_data; + memcpy(&(*policy)->data[(*policy)->length], buf, n); + (*policy)->length += n; + (*policy)->data[(*policy)->length] = '\0'; + } + BIO_free_all(b); + + if (n < 0) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_BIO_LIB); + X509V3_conf_err(val); + goto err; + } + } else if (strncmp(val->value, "text:", 5) == 0) { + val_len = strlen(val->value + 5); + tmp_data = OPENSSL_realloc((*policy)->data, + (*policy)->length + val_len + 1); + if (tmp_data) { + (*policy)->data = tmp_data; + memcpy(&(*policy)->data[(*policy)->length], + val->value + 5, val_len); + (*policy)->length += val_len; + (*policy)->data[(*policy)->length] = '\0'; + } else { + /* + * realloc failure implies the original data space is b0rked + * too! + */ + (*policy)->data = NULL; + (*policy)->length = 0; + X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + } else { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, + X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); + X509V3_conf_err(val); + goto err; + } + if (!tmp_data) { + X509V3err(X509V3_F_PROCESS_PCI_VALUE, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + } + return 1; + err: + if (free_policy) { + ASN1_OCTET_STRING_free(*policy); + *policy = NULL; + } + return 0; +} + +static PROXY_CERT_INFO_EXTENSION *r2i_pci(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *value) +{ + PROXY_CERT_INFO_EXTENSION *pci = NULL; + STACK_OF(CONF_VALUE) *vals; + ASN1_OBJECT *language = NULL; + ASN1_INTEGER *pathlen = NULL; + ASN1_OCTET_STRING *policy = NULL; + int i, j; + + vals = X509V3_parse_list(value); + for (i = 0; i < sk_CONF_VALUE_num(vals); i++) { + CONF_VALUE *cnf = sk_CONF_VALUE_value(vals, i); + if (!cnf->name || (*cnf->name != '@' && !cnf->value)) { + X509V3err(X509V3_F_R2I_PCI, + X509V3_R_INVALID_PROXY_POLICY_SETTING); + X509V3_conf_err(cnf); + goto err; + } + if (*cnf->name == '@') { + STACK_OF(CONF_VALUE) *sect; + int success_p = 1; + + sect = X509V3_get_section(ctx, cnf->name + 1); + if (!sect) { + X509V3err(X509V3_F_R2I_PCI, X509V3_R_INVALID_SECTION); + X509V3_conf_err(cnf); + goto err; + } + for (j = 0; success_p && j < sk_CONF_VALUE_num(sect); j++) { + success_p = + process_pci_value(sk_CONF_VALUE_value(sect, j), + &language, &pathlen, &policy); + } + X509V3_section_free(ctx, sect); + if (!success_p) + goto err; + } else { + if (!process_pci_value(cnf, &language, &pathlen, &policy)) { + X509V3_conf_err(cnf); + goto err; + } + } + } + + /* Language is mandatory */ + if (!language) { + X509V3err(X509V3_F_R2I_PCI, + X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); + goto err; + } + i = OBJ_obj2nid(language); + if ((i == NID_Independent || i == NID_id_ppl_inheritAll) && policy) { + X509V3err(X509V3_F_R2I_PCI, + X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY); + goto err; + } + + pci = PROXY_CERT_INFO_EXTENSION_new(); + if (!pci) { + X509V3err(X509V3_F_R2I_PCI, ERR_R_MALLOC_FAILURE); + goto err; + } + + pci->proxyPolicy->policyLanguage = language; + language = NULL; + pci->proxyPolicy->policy = policy; + policy = NULL; + pci->pcPathLengthConstraint = pathlen; + pathlen = NULL; + goto end; + err: + if (language) { + ASN1_OBJECT_free(language); + language = NULL; + } + if (pathlen) { + ASN1_INTEGER_free(pathlen); + pathlen = NULL; + } + if (policy) { + ASN1_OCTET_STRING_free(policy); + policy = NULL; + } + if (pci) { + PROXY_CERT_INFO_EXTENSION_free(pci); + pci = NULL; + } + end: + sk_CONF_VALUE_pop_free(vals, X509V3_conf_free); + return pci; +} diff --git a/libs/openssl/crypto/x509v3/v3_pcia.c b/libs/openssl/crypto/x509v3/v3_pcia.c new file mode 100644 index 00000000..e53c82e8 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_pcia.c @@ -0,0 +1,56 @@ +/* v3_pcia.c */ +/* + * Contributed to the OpenSSL Project 2004 by Richard Levitte + * (richard@levitte.org) + */ +/* Copyright (c) 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +#include +#include + +ASN1_SEQUENCE(PROXY_POLICY) = + { + ASN1_SIMPLE(PROXY_POLICY,policyLanguage,ASN1_OBJECT), + ASN1_OPT(PROXY_POLICY,policy,ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(PROXY_POLICY) + +IMPLEMENT_ASN1_FUNCTIONS(PROXY_POLICY) + +ASN1_SEQUENCE(PROXY_CERT_INFO_EXTENSION) = + { + ASN1_OPT(PROXY_CERT_INFO_EXTENSION,pcPathLengthConstraint,ASN1_INTEGER), + ASN1_SIMPLE(PROXY_CERT_INFO_EXTENSION,proxyPolicy,PROXY_POLICY) +} ASN1_SEQUENCE_END(PROXY_CERT_INFO_EXTENSION) + +IMPLEMENT_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) diff --git a/libs/openssl/crypto/x509v3/v3_pcons.c b/libs/openssl/crypto/x509v3/v3_pcons.c new file mode 100644 index 00000000..cfccb97d --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_pcons.c @@ -0,0 +1,139 @@ +/* v3_pcons.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD + *method, void *bcons, STACK_OF(CONF_VALUE) + *extlist); +static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values); + +const X509V3_EXT_METHOD v3_policy_constraints = { + NID_policy_constraints, 0, + ASN1_ITEM_ref(POLICY_CONSTRAINTS), + 0, 0, 0, 0, + 0, 0, + i2v_POLICY_CONSTRAINTS, + v2i_POLICY_CONSTRAINTS, + NULL, NULL, + NULL +}; + +ASN1_SEQUENCE(POLICY_CONSTRAINTS) = { + ASN1_IMP_OPT(POLICY_CONSTRAINTS, requireExplicitPolicy, ASN1_INTEGER,0), + ASN1_IMP_OPT(POLICY_CONSTRAINTS, inhibitPolicyMapping, ASN1_INTEGER,1) +} ASN1_SEQUENCE_END(POLICY_CONSTRAINTS) + +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) + +static STACK_OF(CONF_VALUE) *i2v_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD + *method, void *a, STACK_OF(CONF_VALUE) + *extlist) +{ + POLICY_CONSTRAINTS *pcons = a; + X509V3_add_value_int("Require Explicit Policy", + pcons->requireExplicitPolicy, &extlist); + X509V3_add_value_int("Inhibit Policy Mapping", + pcons->inhibitPolicyMapping, &extlist); + return extlist; +} + +static void *v2i_POLICY_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *values) +{ + POLICY_CONSTRAINTS *pcons = NULL; + CONF_VALUE *val; + int i; + if (!(pcons = POLICY_CONSTRAINTS_new())) { + X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, ERR_R_MALLOC_FAILURE); + return NULL; + } + for (i = 0; i < sk_CONF_VALUE_num(values); i++) { + val = sk_CONF_VALUE_value(values, i); + if (!strcmp(val->name, "requireExplicitPolicy")) { + if (!X509V3_get_value_int(val, &pcons->requireExplicitPolicy)) + goto err; + } else if (!strcmp(val->name, "inhibitPolicyMapping")) { + if (!X509V3_get_value_int(val, &pcons->inhibitPolicyMapping)) + goto err; + } else { + X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) { + X509V3err(X509V3_F_V2I_POLICY_CONSTRAINTS, + X509V3_R_ILLEGAL_EMPTY_EXTENSION); + goto err; + } + + return pcons; + err: + POLICY_CONSTRAINTS_free(pcons); + return NULL; +} diff --git a/libs/openssl/crypto/x509v3/v3_pku.c b/libs/openssl/crypto/x509v3/v3_pku.c new file mode 100644 index 00000000..dd01c441 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_pku.c @@ -0,0 +1,114 @@ +/* v3_pku.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, + PKEY_USAGE_PERIOD *usage, BIO *out, + int indent); +/* + * static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, + * X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *values); + */ +const X509V3_EXT_METHOD v3_pkey_usage_period = { + NID_private_key_usage_period, 0, ASN1_ITEM_ref(PKEY_USAGE_PERIOD), + 0, 0, 0, 0, + 0, 0, 0, 0, + (X509V3_EXT_I2R)i2r_PKEY_USAGE_PERIOD, NULL, + NULL +}; + +ASN1_SEQUENCE(PKEY_USAGE_PERIOD) = { + ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notBefore, ASN1_GENERALIZEDTIME, 0), + ASN1_IMP_OPT(PKEY_USAGE_PERIOD, notAfter, ASN1_GENERALIZEDTIME, 1) +} ASN1_SEQUENCE_END(PKEY_USAGE_PERIOD) + +IMPLEMENT_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) + +static int i2r_PKEY_USAGE_PERIOD(X509V3_EXT_METHOD *method, + PKEY_USAGE_PERIOD *usage, BIO *out, + int indent) +{ + BIO_printf(out, "%*s", indent, ""); + if (usage->notBefore) { + BIO_write(out, "Not Before: ", 12); + ASN1_GENERALIZEDTIME_print(out, usage->notBefore); + if (usage->notAfter) + BIO_write(out, ", ", 2); + } + if (usage->notAfter) { + BIO_write(out, "Not After: ", 11); + ASN1_GENERALIZEDTIME_print(out, usage->notAfter); + } + return 1; +} + +/*- +static PKEY_USAGE_PERIOD *v2i_PKEY_USAGE_PERIOD(method, ctx, values) +X509V3_EXT_METHOD *method; +X509V3_CTX *ctx; +STACK_OF(CONF_VALUE) *values; +{ +return NULL; +} +*/ diff --git a/libs/openssl/crypto/x509v3/v3_pmaps.c b/libs/openssl/crypto/x509v3/v3_pmaps.c new file mode 100644 index 00000000..a168343b --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_pmaps.c @@ -0,0 +1,156 @@ +/* v3_pmaps.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include + +static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD + *method, void *pmps, STACK_OF(CONF_VALUE) + *extlist); + +const X509V3_EXT_METHOD v3_policy_mappings = { + NID_policy_mappings, 0, + ASN1_ITEM_ref(POLICY_MAPPINGS), + 0, 0, 0, 0, + 0, 0, + i2v_POLICY_MAPPINGS, + v2i_POLICY_MAPPINGS, + 0, 0, + NULL +}; + +ASN1_SEQUENCE(POLICY_MAPPING) = { + ASN1_SIMPLE(POLICY_MAPPING, issuerDomainPolicy, ASN1_OBJECT), + ASN1_SIMPLE(POLICY_MAPPING, subjectDomainPolicy, ASN1_OBJECT) +} ASN1_SEQUENCE_END(POLICY_MAPPING) + +ASN1_ITEM_TEMPLATE(POLICY_MAPPINGS) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, POLICY_MAPPINGS, + POLICY_MAPPING) +ASN1_ITEM_TEMPLATE_END(POLICY_MAPPINGS) + +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) + +static STACK_OF(CONF_VALUE) *i2v_POLICY_MAPPINGS(const X509V3_EXT_METHOD + *method, void *a, STACK_OF(CONF_VALUE) + *ext_list) +{ + POLICY_MAPPINGS *pmaps = a; + POLICY_MAPPING *pmap; + int i; + char obj_tmp1[80]; + char obj_tmp2[80]; + for (i = 0; i < sk_POLICY_MAPPING_num(pmaps); i++) { + pmap = sk_POLICY_MAPPING_value(pmaps, i); + i2t_ASN1_OBJECT(obj_tmp1, 80, pmap->issuerDomainPolicy); + i2t_ASN1_OBJECT(obj_tmp2, 80, pmap->subjectDomainPolicy); + X509V3_add_value(obj_tmp1, obj_tmp2, &ext_list); + } + return ext_list; +} + +static void *v2i_POLICY_MAPPINGS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + POLICY_MAPPINGS *pmaps; + POLICY_MAPPING *pmap; + ASN1_OBJECT *obj1, *obj2; + CONF_VALUE *val; + int i; + + if (!(pmaps = sk_POLICY_MAPPING_new_null())) { + X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (!val->value || !val->name) { + sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); + X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return NULL; + } + obj1 = OBJ_txt2obj(val->name, 0); + obj2 = OBJ_txt2obj(val->value, 0); + if (!obj1 || !obj2) { + sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); + X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, + X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return NULL; + } + pmap = POLICY_MAPPING_new(); + if (!pmap) { + sk_POLICY_MAPPING_pop_free(pmaps, POLICY_MAPPING_free); + X509V3err(X509V3_F_V2I_POLICY_MAPPINGS, ERR_R_MALLOC_FAILURE); + return NULL; + } + pmap->issuerDomainPolicy = obj1; + pmap->subjectDomainPolicy = obj2; + sk_POLICY_MAPPING_push(pmaps, pmap); + } + return pmaps; +} diff --git a/libs/openssl/crypto/x509v3/v3_prn.c b/libs/openssl/crypto/x509v3/v3_prn.c new file mode 100644 index 00000000..acc9c6d9 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_prn.c @@ -0,0 +1,259 @@ +/* v3_prn.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* X509 v3 extension utilities */ + +#include +#include "cryptlib.h" +#include +#include + +/* Extension printing routines */ + +static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, + unsigned long flag, int indent, int supported); + +/* Print out a name+value stack */ + +void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, + int ml) +{ + int i; + CONF_VALUE *nval; + if (!val) + return; + if (!ml || !sk_CONF_VALUE_num(val)) { + BIO_printf(out, "%*s", indent, ""); + if (!sk_CONF_VALUE_num(val)) + BIO_puts(out, "\n"); + } + for (i = 0; i < sk_CONF_VALUE_num(val); i++) { + if (ml) + BIO_printf(out, "%*s", indent, ""); + else if (i > 0) + BIO_printf(out, ", "); + nval = sk_CONF_VALUE_value(val, i); + if (!nval->name) + BIO_puts(out, nval->value); + else if (!nval->value) + BIO_puts(out, nval->name); +#ifndef CHARSET_EBCDIC + else + BIO_printf(out, "%s:%s", nval->name, nval->value); +#else + else { + int len; + char *tmp; + len = strlen(nval->value) + 1; + tmp = OPENSSL_malloc(len); + if (tmp) { + ascii2ebcdic(tmp, nval->value, len); + BIO_printf(out, "%s:%s", nval->name, tmp); + OPENSSL_free(tmp); + } + } +#endif + if (ml) + BIO_puts(out, "\n"); + } +} + +/* Main routine: print out a general extension */ + +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent) +{ + void *ext_str = NULL; + char *value = NULL; + const unsigned char *p; + const X509V3_EXT_METHOD *method; + STACK_OF(CONF_VALUE) *nval = NULL; + int ok = 1; + + if (!(method = X509V3_EXT_get(ext))) + return unknown_ext_print(out, ext, flag, indent, 0); + p = ext->value->data; + if (method->it) + ext_str = + ASN1_item_d2i(NULL, &p, ext->value->length, + ASN1_ITEM_ptr(method->it)); + else + ext_str = method->d2i(NULL, &p, ext->value->length); + + if (!ext_str) + return unknown_ext_print(out, ext, flag, indent, 1); + + if (method->i2s) { + if (!(value = method->i2s(method, ext_str))) { + ok = 0; + goto err; + } +#ifndef CHARSET_EBCDIC + BIO_printf(out, "%*s%s", indent, "", value); +#else + { + int len; + char *tmp; + len = strlen(value) + 1; + tmp = OPENSSL_malloc(len); + if (tmp) { + ascii2ebcdic(tmp, value, len); + BIO_printf(out, "%*s%s", indent, "", tmp); + OPENSSL_free(tmp); + } + } +#endif + } else if (method->i2v) { + if (!(nval = method->i2v(method, ext_str, NULL))) { + ok = 0; + goto err; + } + X509V3_EXT_val_prn(out, nval, indent, + method->ext_flags & X509V3_EXT_MULTILINE); + } else if (method->i2r) { + if (!method->i2r(method, ext_str, out, indent)) + ok = 0; + } else + ok = 0; + + err: + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + if (value) + OPENSSL_free(value); + if (method->it) + ASN1_item_free(ext_str, ASN1_ITEM_ptr(method->it)); + else + method->ext_free(ext_str); + return ok; +} + +int X509V3_extensions_print(BIO *bp, char *title, + STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent) +{ + int i, j; + + if (sk_X509_EXTENSION_num(exts) <= 0) + return 1; + + if (title) { + BIO_printf(bp, "%*s%s:\n", indent, "", title); + indent += 4; + } + + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + ASN1_OBJECT *obj; + X509_EXTENSION *ex; + ex = sk_X509_EXTENSION_value(exts, i); + if (indent && BIO_printf(bp, "%*s", indent, "") <= 0) + return 0; + obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bp, obj); + j = X509_EXTENSION_get_critical(ex); + if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0) + return 0; + if (!X509V3_EXT_print(bp, ex, flag, indent + 4)) { + BIO_printf(bp, "%*s", indent + 4, ""); + M_ASN1_OCTET_STRING_print(bp, ex->value); + } + if (BIO_write(bp, "\n", 1) <= 0) + return 0; + } + return 1; +} + +static int unknown_ext_print(BIO *out, X509_EXTENSION *ext, + unsigned long flag, int indent, int supported) +{ + switch (flag & X509V3_EXT_UNKNOWN_MASK) { + + case X509V3_EXT_DEFAULT: + return 0; + + case X509V3_EXT_ERROR_UNKNOWN: + if (supported) + BIO_printf(out, "%*s", indent, ""); + else + BIO_printf(out, "%*s", indent, ""); + return 1; + + case X509V3_EXT_PARSE_UNKNOWN: + return ASN1_parse_dump(out, + ext->value->data, ext->value->length, indent, + -1); + case X509V3_EXT_DUMP_UNKNOWN: + return BIO_dump_indent(out, (char *)ext->value->data, + ext->value->length, indent); + + default: + return 1; + } +} + +#ifndef OPENSSL_NO_FP_API +int X509V3_EXT_print_fp(FILE *fp, X509_EXTENSION *ext, int flag, int indent) +{ + BIO *bio_tmp; + int ret; + if (!(bio_tmp = BIO_new_fp(fp, BIO_NOCLOSE))) + return 0; + ret = X509V3_EXT_print(bio_tmp, ext, flag, indent); + BIO_free(bio_tmp); + return ret; +} +#endif diff --git a/libs/openssl/crypto/x509v3/v3_purp.c b/libs/openssl/crypto/x509v3/v3_purp.c new file mode 100644 index 00000000..0d9bc58c --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_purp.c @@ -0,0 +1,836 @@ +/* v3_purp.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include + +static void x509v3_cache_extensions(X509 *x); + +static int check_ssl_ca(const X509 *x); +static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int purpose_smime(const X509 *x, int ca); +static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, + int ca); +static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca); +static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca); + +static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b); +static void xptable_free(X509_PURPOSE *p); + +static X509_PURPOSE xstandard[] = { + {X509_PURPOSE_SSL_CLIENT, X509_TRUST_SSL_CLIENT, 0, + check_purpose_ssl_client, "SSL client", "sslclient", NULL}, + {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, + check_purpose_ssl_server, "SSL server", "sslserver", NULL}, + {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, + check_purpose_ns_ssl_server, "Netscape SSL server", "nssslserver", NULL}, + {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, + "S/MIME signing", "smimesign", NULL}, + {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, + check_purpose_smime_encrypt, "S/MIME encryption", "smimeencrypt", NULL}, + {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, + "CRL signing", "crlsign", NULL}, + {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, "Any Purpose", "any", + NULL}, + {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, + "OCSP helper", "ocsphelper", NULL}, + {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, + check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign", + NULL}, +}; + +#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE)) + +IMPLEMENT_STACK_OF(X509_PURPOSE) + +static STACK_OF(X509_PURPOSE) *xptable = NULL; + +static int xp_cmp(const X509_PURPOSE *const *a, const X509_PURPOSE *const *b) +{ + return (*a)->purpose - (*b)->purpose; +} + +/* + * As much as I'd like to make X509_check_purpose use a "const" X509* I + * really can't because it does recalculate hashes and do other non-const + * things. + */ +int X509_check_purpose(X509 *x, int id, int ca) +{ + int idx; + const X509_PURPOSE *pt; + if (!(x->ex_flags & EXFLAG_SET)) { + CRYPTO_w_lock(CRYPTO_LOCK_X509); + x509v3_cache_extensions(x); + CRYPTO_w_unlock(CRYPTO_LOCK_X509); + } + if (id == -1) + return 1; + idx = X509_PURPOSE_get_by_id(id); + if (idx == -1) + return -1; + pt = X509_PURPOSE_get0(idx); + return pt->check_purpose(pt, x, ca); +} + +int X509_PURPOSE_set(int *p, int purpose) +{ + if (X509_PURPOSE_get_by_id(purpose) == -1) { + X509V3err(X509V3_F_X509_PURPOSE_SET, X509V3_R_INVALID_PURPOSE); + return 0; + } + *p = purpose; + return 1; +} + +int X509_PURPOSE_get_count(void) +{ + if (!xptable) + return X509_PURPOSE_COUNT; + return sk_X509_PURPOSE_num(xptable) + X509_PURPOSE_COUNT; +} + +X509_PURPOSE *X509_PURPOSE_get0(int idx) +{ + if (idx < 0) + return NULL; + if (idx < (int)X509_PURPOSE_COUNT) + return xstandard + idx; + return sk_X509_PURPOSE_value(xptable, idx - X509_PURPOSE_COUNT); +} + +int X509_PURPOSE_get_by_sname(char *sname) +{ + int i; + X509_PURPOSE *xptmp; + for (i = 0; i < X509_PURPOSE_get_count(); i++) { + xptmp = X509_PURPOSE_get0(i); + if (!strcmp(xptmp->sname, sname)) + return i; + } + return -1; +} + +int X509_PURPOSE_get_by_id(int purpose) +{ + X509_PURPOSE tmp; + int idx; + if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX)) + return purpose - X509_PURPOSE_MIN; + tmp.purpose = purpose; + if (!xptable) + return -1; + idx = sk_X509_PURPOSE_find(xptable, &tmp); + if (idx == -1) + return -1; + return idx + X509_PURPOSE_COUNT; +} + +int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck) (const X509_PURPOSE *, const X509 *, int), + char *name, char *sname, void *arg) +{ + int idx; + X509_PURPOSE *ptmp; + /* + * This is set according to what we change: application can't set it + */ + flags &= ~X509_PURPOSE_DYNAMIC; + /* This will always be set for application modified trust entries */ + flags |= X509_PURPOSE_DYNAMIC_NAME; + /* Get existing entry if any */ + idx = X509_PURPOSE_get_by_id(id); + /* Need a new entry */ + if (idx == -1) { + if (!(ptmp = OPENSSL_malloc(sizeof(X509_PURPOSE)))) { + X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + ptmp->flags = X509_PURPOSE_DYNAMIC; + } else + ptmp = X509_PURPOSE_get0(idx); + + /* OPENSSL_free existing name if dynamic */ + if (ptmp->flags & X509_PURPOSE_DYNAMIC_NAME) { + OPENSSL_free(ptmp->name); + OPENSSL_free(ptmp->sname); + } + /* dup supplied name */ + ptmp->name = BUF_strdup(name); + ptmp->sname = BUF_strdup(sname); + if (!ptmp->name || !ptmp->sname) { + X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + /* Keep the dynamic flag of existing entry */ + ptmp->flags &= X509_PURPOSE_DYNAMIC; + /* Set all other flags */ + ptmp->flags |= flags; + + ptmp->purpose = id; + ptmp->trust = trust; + ptmp->check_purpose = ck; + ptmp->usr_data = arg; + + /* If its a new entry manage the dynamic table */ + if (idx == -1) { + if (!xptable && !(xptable = sk_X509_PURPOSE_new(xp_cmp))) { + X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!sk_X509_PURPOSE_push(xptable, ptmp)) { + X509V3err(X509V3_F_X509_PURPOSE_ADD, ERR_R_MALLOC_FAILURE); + return 0; + } + } + return 1; +} + +static void xptable_free(X509_PURPOSE *p) +{ + if (!p) + return; + if (p->flags & X509_PURPOSE_DYNAMIC) { + if (p->flags & X509_PURPOSE_DYNAMIC_NAME) { + OPENSSL_free(p->name); + OPENSSL_free(p->sname); + } + OPENSSL_free(p); + } +} + +void X509_PURPOSE_cleanup(void) +{ + unsigned int i; + sk_X509_PURPOSE_pop_free(xptable, xptable_free); + for (i = 0; i < X509_PURPOSE_COUNT; i++) + xptable_free(xstandard + i); + xptable = NULL; +} + +int X509_PURPOSE_get_id(X509_PURPOSE *xp) +{ + return xp->purpose; +} + +char *X509_PURPOSE_get0_name(X509_PURPOSE *xp) +{ + return xp->name; +} + +char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp) +{ + return xp->sname; +} + +int X509_PURPOSE_get_trust(X509_PURPOSE *xp) +{ + return xp->trust; +} + +static int nid_cmp(const int *a, const int *b) +{ + return *a - *b; +} + +DECLARE_OBJ_BSEARCH_CMP_FN(int, int, nid); +IMPLEMENT_OBJ_BSEARCH_CMP_FN(int, int, nid); + +int X509_supported_extension(X509_EXTENSION *ex) +{ + /* + * This table is a list of the NIDs of supported extensions: that is + * those which are used by the verify process. If an extension is + * critical and doesn't appear in this list then the verify process will + * normally reject the certificate. The list must be kept in numerical + * order because it will be searched using bsearch. + */ + + static const int supported_nids[] = { + NID_netscape_cert_type, /* 71 */ + NID_key_usage, /* 83 */ + NID_subject_alt_name, /* 85 */ + NID_basic_constraints, /* 87 */ + NID_certificate_policies, /* 89 */ + NID_ext_key_usage, /* 126 */ +#ifndef OPENSSL_NO_RFC3779 + NID_sbgp_ipAddrBlock, /* 290 */ + NID_sbgp_autonomousSysNum, /* 291 */ +#endif + NID_policy_constraints, /* 401 */ + NID_proxyCertInfo, /* 663 */ + NID_name_constraints, /* 666 */ + NID_policy_mappings, /* 747 */ + NID_inhibit_any_policy /* 748 */ + }; + + int ex_nid = OBJ_obj2nid(X509_EXTENSION_get_object(ex)); + + if (ex_nid == NID_undef) + return 0; + + if (OBJ_bsearch_nid(&ex_nid, supported_nids, + sizeof(supported_nids) / sizeof(int))) + return 1; + return 0; +} + +static void setup_dp(X509 *x, DIST_POINT *dp) +{ + X509_NAME *iname = NULL; + int i; + if (dp->reasons) { + if (dp->reasons->length > 0) + dp->dp_reasons = dp->reasons->data[0]; + if (dp->reasons->length > 1) + dp->dp_reasons |= (dp->reasons->data[1] << 8); + dp->dp_reasons &= CRLDP_ALL_REASONS; + } else + dp->dp_reasons = CRLDP_ALL_REASONS; + if (!dp->distpoint || (dp->distpoint->type != 1)) + return; + for (i = 0; i < sk_GENERAL_NAME_num(dp->CRLissuer); i++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(dp->CRLissuer, i); + if (gen->type == GEN_DIRNAME) { + iname = gen->d.directoryName; + break; + } + } + if (!iname) + iname = X509_get_issuer_name(x); + + DIST_POINT_set_dpname(dp->distpoint, iname); + +} + +static void setup_crldp(X509 *x) +{ + int i; + x->crldp = X509_get_ext_d2i(x, NID_crl_distribution_points, NULL, NULL); + for (i = 0; i < sk_DIST_POINT_num(x->crldp); i++) + setup_dp(x, sk_DIST_POINT_value(x->crldp, i)); +} + +static void x509v3_cache_extensions(X509 *x) +{ + BASIC_CONSTRAINTS *bs; + PROXY_CERT_INFO_EXTENSION *pci; + ASN1_BIT_STRING *usage; + ASN1_BIT_STRING *ns; + EXTENDED_KEY_USAGE *extusage; + X509_EXTENSION *ex; + + int i; + if (x->ex_flags & EXFLAG_SET) + return; +#ifndef OPENSSL_NO_SHA + X509_digest(x, EVP_sha1(), x->sha1_hash, NULL); +#endif + /* Does subject name match issuer ? */ + if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) + x->ex_flags |= EXFLAG_SI; + /* V1 should mean no extensions ... */ + if (!X509_get_version(x)) + x->ex_flags |= EXFLAG_V1; + /* Handle basic constraints */ + if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) { + if (bs->ca) + x->ex_flags |= EXFLAG_CA; + if (bs->pathlen) { + if ((bs->pathlen->type == V_ASN1_NEG_INTEGER) + || !bs->ca) { + x->ex_flags |= EXFLAG_INVALID; + x->ex_pathlen = 0; + } else + x->ex_pathlen = ASN1_INTEGER_get(bs->pathlen); + } else + x->ex_pathlen = -1; + BASIC_CONSTRAINTS_free(bs); + x->ex_flags |= EXFLAG_BCONS; + } + /* Handle proxy certificates */ + if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) { + if (x->ex_flags & EXFLAG_CA + || X509_get_ext_by_NID(x, NID_subject_alt_name, -1) >= 0 + || X509_get_ext_by_NID(x, NID_issuer_alt_name, -1) >= 0) { + x->ex_flags |= EXFLAG_INVALID; + } + if (pci->pcPathLengthConstraint) { + x->ex_pcpathlen = ASN1_INTEGER_get(pci->pcPathLengthConstraint); + } else + x->ex_pcpathlen = -1; + PROXY_CERT_INFO_EXTENSION_free(pci); + x->ex_flags |= EXFLAG_PROXY; + } + /* Handle key usage */ + if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) { + if (usage->length > 0) { + x->ex_kusage = usage->data[0]; + if (usage->length > 1) + x->ex_kusage |= usage->data[1] << 8; + } else + x->ex_kusage = 0; + x->ex_flags |= EXFLAG_KUSAGE; + ASN1_BIT_STRING_free(usage); + } + x->ex_xkusage = 0; + if ((extusage = X509_get_ext_d2i(x, NID_ext_key_usage, NULL, NULL))) { + x->ex_flags |= EXFLAG_XKUSAGE; + for (i = 0; i < sk_ASN1_OBJECT_num(extusage); i++) { + switch (OBJ_obj2nid(sk_ASN1_OBJECT_value(extusage, i))) { + case NID_server_auth: + x->ex_xkusage |= XKU_SSL_SERVER; + break; + + case NID_client_auth: + x->ex_xkusage |= XKU_SSL_CLIENT; + break; + + case NID_email_protect: + x->ex_xkusage |= XKU_SMIME; + break; + + case NID_code_sign: + x->ex_xkusage |= XKU_CODE_SIGN; + break; + + case NID_ms_sgc: + case NID_ns_sgc: + x->ex_xkusage |= XKU_SGC; + break; + + case NID_OCSP_sign: + x->ex_xkusage |= XKU_OCSP_SIGN; + break; + + case NID_time_stamp: + x->ex_xkusage |= XKU_TIMESTAMP; + break; + + case NID_dvcs: + x->ex_xkusage |= XKU_DVCS; + break; + } + } + sk_ASN1_OBJECT_pop_free(extusage, ASN1_OBJECT_free); + } + + if ((ns = X509_get_ext_d2i(x, NID_netscape_cert_type, NULL, NULL))) { + if (ns->length > 0) + x->ex_nscert = ns->data[0]; + else + x->ex_nscert = 0; + x->ex_flags |= EXFLAG_NSCERT; + ASN1_BIT_STRING_free(ns); + } + x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL); + x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL); + x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL); + if (!x->nc && (i != -1)) + x->ex_flags |= EXFLAG_INVALID; + setup_crldp(x); + +#ifndef OPENSSL_NO_RFC3779 + x->rfc3779_addr = X509_get_ext_d2i(x, NID_sbgp_ipAddrBlock, NULL, NULL); + x->rfc3779_asid = X509_get_ext_d2i(x, NID_sbgp_autonomousSysNum, + NULL, NULL); +#endif + for (i = 0; i < X509_get_ext_count(x); i++) { + ex = X509_get_ext(x, i); + if (OBJ_obj2nid(X509_EXTENSION_get_object(ex)) + == NID_freshest_crl) + x->ex_flags |= EXFLAG_FRESHEST; + if (!X509_EXTENSION_get_critical(ex)) + continue; + if (!X509_supported_extension(ex)) { + x->ex_flags |= EXFLAG_CRITICAL; + break; + } + } + x->ex_flags |= EXFLAG_SET; +} + +/*- + * CA checks common to all purposes + * return codes: + * 0 not a CA + * 1 is a CA + * 2 basicConstraints absent so "maybe" a CA + * 3 basicConstraints absent but self signed V1. + * 4 basicConstraints absent but keyUsage present and keyCertSign asserted. + */ + +#define V1_ROOT (EXFLAG_V1|EXFLAG_SS) +#define ku_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) +#define xku_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage))) +#define ns_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage))) + +static int check_ca(const X509 *x) +{ + /* keyUsage if present should allow cert signing */ + if (ku_reject(x, KU_KEY_CERT_SIGN)) + return 0; + if (x->ex_flags & EXFLAG_BCONS) { + if (x->ex_flags & EXFLAG_CA) + return 1; + /* If basicConstraints says not a CA then say so */ + else + return 0; + } else { + /* we support V1 roots for... uh, I don't really know why. */ + if ((x->ex_flags & V1_ROOT) == V1_ROOT) + return 3; + /* + * If key usage present it must have certSign so tolerate it + */ + else if (x->ex_flags & EXFLAG_KUSAGE) + return 4; + /* Older certificates could have Netscape-specific CA types */ + else if (x->ex_flags & EXFLAG_NSCERT && x->ex_nscert & NS_ANY_CA) + return 5; + /* can this still be regarded a CA certificate? I doubt it */ + return 0; + } +} + +int X509_check_ca(X509 *x) +{ + if (!(x->ex_flags & EXFLAG_SET)) { + CRYPTO_w_lock(CRYPTO_LOCK_X509); + x509v3_cache_extensions(x); + CRYPTO_w_unlock(CRYPTO_LOCK_X509); + } + + return check_ca(x); +} + +/* Check SSL CA: common checks for SSL client and server */ +static int check_ssl_ca(const X509 *x) +{ + int ca_ret; + ca_ret = check_ca(x); + if (!ca_ret) + return 0; + /* check nsCertType if present */ + if (ca_ret != 5 || x->ex_nscert & NS_SSL_CA) + return ca_ret; + else + return 0; +} + +static int check_purpose_ssl_client(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + if (xku_reject(x, XKU_SSL_CLIENT)) + return 0; + if (ca) + return check_ssl_ca(x); + /* We need to do digital signatures with it */ + if (ku_reject(x, KU_DIGITAL_SIGNATURE)) + return 0; + /* nsCertType if present should allow SSL client use */ + if (ns_reject(x, NS_SSL_CLIENT)) + return 0; + return 1; +} + +static int check_purpose_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + if (xku_reject(x, XKU_SSL_SERVER | XKU_SGC)) + return 0; + if (ca) + return check_ssl_ca(x); + + if (ns_reject(x, NS_SSL_SERVER)) + return 0; + /* Now as for keyUsage: we'll at least need to sign OR encipher */ + if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_KEY_ENCIPHERMENT)) + return 0; + + return 1; + +} + +static int check_purpose_ns_ssl_server(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + int ret; + ret = check_purpose_ssl_server(xp, x, ca); + if (!ret || ca) + return ret; + /* We need to encipher or Netscape complains */ + if (ku_reject(x, KU_KEY_ENCIPHERMENT)) + return 0; + return ret; +} + +/* common S/MIME checks */ +static int purpose_smime(const X509 *x, int ca) +{ + if (xku_reject(x, XKU_SMIME)) + return 0; + if (ca) { + int ca_ret; + ca_ret = check_ca(x); + if (!ca_ret) + return 0; + /* check nsCertType if present */ + if (ca_ret != 5 || x->ex_nscert & NS_SMIME_CA) + return ca_ret; + else + return 0; + } + if (x->ex_flags & EXFLAG_NSCERT) { + if (x->ex_nscert & NS_SMIME) + return 1; + /* Workaround for some buggy certificates */ + if (x->ex_nscert & NS_SSL_CLIENT) + return 2; + return 0; + } + return 1; +} + +static int check_purpose_smime_sign(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + int ret; + ret = purpose_smime(x, ca); + if (!ret || ca) + return ret; + if (ku_reject(x, KU_DIGITAL_SIGNATURE | KU_NON_REPUDIATION)) + return 0; + return ret; +} + +static int check_purpose_smime_encrypt(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + int ret; + ret = purpose_smime(x, ca); + if (!ret || ca) + return ret; + if (ku_reject(x, KU_KEY_ENCIPHERMENT)) + return 0; + return ret; +} + +static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + if (ca) { + int ca_ret; + if ((ca_ret = check_ca(x)) != 2) + return ca_ret; + else + return 0; + } + if (ku_reject(x, KU_CRL_SIGN)) + return 0; + return 1; +} + +/* + * OCSP helper: this is *not* a full OCSP check. It just checks that each CA + * is valid. Additional checks must be made on the chain. + */ + +static int ocsp_helper(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + /* + * Must be a valid CA. Should we really support the "I don't know" value + * (2)? + */ + if (ca) + return check_ca(x); + /* leaf certificate is checked in OCSP_verify() */ + return 1; +} + +static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x, + int ca) +{ + int i_ext; + + /* If ca is true we must return if this is a valid CA certificate. */ + if (ca) + return check_ca(x); + + /* + * Check the optional key usage field: + * if Key Usage is present, it must be one of digitalSignature + * and/or nonRepudiation (other values are not consistent and shall + * be rejected). + */ + if ((x->ex_flags & EXFLAG_KUSAGE) + && ((x->ex_kusage & ~(KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)) || + !(x->ex_kusage & (KU_NON_REPUDIATION | KU_DIGITAL_SIGNATURE)))) + return 0; + + /* Only time stamp key usage is permitted and it's required. */ + if (!(x->ex_flags & EXFLAG_XKUSAGE) || x->ex_xkusage != XKU_TIMESTAMP) + return 0; + + /* Extended Key Usage MUST be critical */ + i_ext = X509_get_ext_by_NID((X509 *)x, NID_ext_key_usage, -1); + if (i_ext >= 0) { + X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext); + if (!X509_EXTENSION_get_critical(ext)) + return 0; + } + + return 1; +} + +static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca) +{ + return 1; +} + +/*- + * Various checks to see if one certificate issued the second. + * This can be used to prune a set of possible issuer certificates + * which have been looked up using some simple method such as by + * subject name. + * These are: + * 1. Check issuer_name(subject) == subject_name(issuer) + * 2. If akid(subject) exists check it matches issuer + * 3. If key_usage(issuer) exists check it supports certificate signing + * returns 0 for OK, positive for reason for mismatch, reasons match + * codes for X509_verify_cert() + */ + +int X509_check_issued(X509 *issuer, X509 *subject) +{ + if (X509_NAME_cmp(X509_get_subject_name(issuer), + X509_get_issuer_name(subject))) + return X509_V_ERR_SUBJECT_ISSUER_MISMATCH; + x509v3_cache_extensions(issuer); + x509v3_cache_extensions(subject); + + if (subject->akid) { + int ret = X509_check_akid(issuer, subject->akid); + if (ret != X509_V_OK) + return ret; + } + + if (subject->ex_flags & EXFLAG_PROXY) { + if (ku_reject(issuer, KU_DIGITAL_SIGNATURE)) + return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE; + } else if (ku_reject(issuer, KU_KEY_CERT_SIGN)) + return X509_V_ERR_KEYUSAGE_NO_CERTSIGN; + return X509_V_OK; +} + +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid) +{ + + if (!akid) + return X509_V_OK; + + /* Check key ids (if present) */ + if (akid->keyid && issuer->skid && + ASN1_OCTET_STRING_cmp(akid->keyid, issuer->skid)) + return X509_V_ERR_AKID_SKID_MISMATCH; + /* Check serial number */ + if (akid->serial && + ASN1_INTEGER_cmp(X509_get_serialNumber(issuer), akid->serial)) + return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + /* Check issuer name */ + if (akid->issuer) { + /* + * Ugh, for some peculiar reason AKID includes SEQUENCE OF + * GeneralName. So look for a DirName. There may be more than one but + * we only take any notice of the first. + */ + GENERAL_NAMES *gens; + GENERAL_NAME *gen; + X509_NAME *nm = NULL; + int i; + gens = akid->issuer; + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gen = sk_GENERAL_NAME_value(gens, i); + if (gen->type == GEN_DIRNAME) { + nm = gen->d.dirn; + break; + } + } + if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer))) + return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH; + } + return X509_V_OK; +} diff --git a/libs/openssl/crypto/x509v3/v3_skey.c b/libs/openssl/crypto/x509v3/v3_skey.c new file mode 100644 index 00000000..1cede047 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_skey.c @@ -0,0 +1,150 @@ +/* v3_skey.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include + +static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); +const X509V3_EXT_METHOD v3_skey_id = { + NID_subject_key_identifier, 0, ASN1_ITEM_ref(ASN1_OCTET_STRING), + 0, 0, 0, 0, + (X509V3_EXT_I2S)i2s_ASN1_OCTET_STRING, + (X509V3_EXT_S2I)s2i_skey_id, + 0, 0, 0, 0, + NULL +}; + +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *oct) +{ + return hex_to_string(oct->data, oct->length); +} + +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str) +{ + ASN1_OCTET_STRING *oct; + long length; + + if (!(oct = M_ASN1_OCTET_STRING_new())) { + X509V3err(X509V3_F_S2I_ASN1_OCTET_STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!(oct->data = string_to_hex(str, &length))) { + M_ASN1_OCTET_STRING_free(oct); + return NULL; + } + + oct->length = length; + + return oct; + +} + +static ASN1_OCTET_STRING *s2i_skey_id(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str) +{ + ASN1_OCTET_STRING *oct; + ASN1_BIT_STRING *pk; + unsigned char pkey_dig[EVP_MAX_MD_SIZE]; + unsigned int diglen; + + if (strcmp(str, "hash")) + return s2i_ASN1_OCTET_STRING(method, ctx, str); + + if (!(oct = M_ASN1_OCTET_STRING_new())) { + X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (ctx && (ctx->flags == CTX_TEST)) + return oct; + + if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) { + X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY); + goto err; + } + + if (ctx->subject_req) + pk = ctx->subject_req->req_info->pubkey->public_key; + else + pk = ctx->subject_cert->cert_info->key->public_key; + + if (!pk) { + X509V3err(X509V3_F_S2I_SKEY_ID, X509V3_R_NO_PUBLIC_KEY); + goto err; + } + + if (!EVP_Digest + (pk->data, pk->length, pkey_dig, &diglen, EVP_sha1(), NULL)) + goto err; + + if (!M_ASN1_OCTET_STRING_set(oct, pkey_dig, diglen)) { + X509V3err(X509V3_F_S2I_SKEY_ID, ERR_R_MALLOC_FAILURE); + goto err; + } + + return oct; + + err: + M_ASN1_OCTET_STRING_free(oct); + return NULL; +} diff --git a/libs/openssl/crypto/x509v3/v3_sxnet.c b/libs/openssl/crypto/x509v3/v3_sxnet.c new file mode 100644 index 00000000..a4e6a93e --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_sxnet.c @@ -0,0 +1,273 @@ +/* v3_sxnet.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +/* Support for Thawte strong extranet extension */ + +#define SXNET_TEST + +static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, + int indent); +#ifdef SXNET_TEST +static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +#endif +const X509V3_EXT_METHOD v3_sxnet = { + NID_sxnet, X509V3_EXT_MULTILINE, ASN1_ITEM_ref(SXNET), + 0, 0, 0, 0, + 0, 0, + 0, +#ifdef SXNET_TEST + (X509V3_EXT_V2I)sxnet_v2i, +#else + 0, +#endif + (X509V3_EXT_I2R)sxnet_i2r, + 0, + NULL +}; + +ASN1_SEQUENCE(SXNETID) = { + ASN1_SIMPLE(SXNETID, zone, ASN1_INTEGER), + ASN1_SIMPLE(SXNETID, user, ASN1_OCTET_STRING) +} ASN1_SEQUENCE_END(SXNETID) + +IMPLEMENT_ASN1_FUNCTIONS(SXNETID) + +ASN1_SEQUENCE(SXNET) = { + ASN1_SIMPLE(SXNET, version, ASN1_INTEGER), + ASN1_SEQUENCE_OF(SXNET, ids, SXNETID) +} ASN1_SEQUENCE_END(SXNET) + +IMPLEMENT_ASN1_FUNCTIONS(SXNET) + +static int sxnet_i2r(X509V3_EXT_METHOD *method, SXNET *sx, BIO *out, + int indent) +{ + long v; + char *tmp; + SXNETID *id; + int i; + v = ASN1_INTEGER_get(sx->version); + BIO_printf(out, "%*sVersion: %ld (0x%lX)", indent, "", v + 1, v); + for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { + id = sk_SXNETID_value(sx->ids, i); + tmp = i2s_ASN1_INTEGER(NULL, id->zone); + BIO_printf(out, "\n%*sZone: %s, User: ", indent, "", tmp); + OPENSSL_free(tmp); + M_ASN1_OCTET_STRING_print(out, id->user); + } + return 1; +} + +#ifdef SXNET_TEST + +/* + * NBB: this is used for testing only. It should *not* be used for anything + * else because it will just take static IDs from the configuration file and + * they should really be separate values for each user. + */ + +static SXNET *sxnet_v2i(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval) +{ + CONF_VALUE *cnf; + SXNET *sx = NULL; + int i; + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + cnf = sk_CONF_VALUE_value(nval, i); + if (!SXNET_add_id_asc(&sx, cnf->name, cnf->value, -1)) + return NULL; + } + return sx; +} + +#endif + +/* Strong Extranet utility functions */ + +/* Add an id given the zone as an ASCII number */ + +int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen) +{ + ASN1_INTEGER *izone = NULL; + if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) { + X509V3err(X509V3_F_SXNET_ADD_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE); + return 0; + } + return SXNET_add_id_INTEGER(psx, izone, user, userlen); +} + +/* Add an id given the zone as an unsigned long */ + +int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, + int userlen) +{ + ASN1_INTEGER *izone = NULL; + if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) { + X509V3err(X509V3_F_SXNET_ADD_ID_ULONG, ERR_R_MALLOC_FAILURE); + M_ASN1_INTEGER_free(izone); + return 0; + } + return SXNET_add_id_INTEGER(psx, izone, user, userlen); + +} + +/* + * Add an id given the zone as an ASN1_INTEGER. Note this version uses the + * passed integer and doesn't make a copy so don't free it up afterwards. + */ + +int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *zone, char *user, + int userlen) +{ + SXNET *sx = NULL; + SXNETID *id = NULL; + if (!psx || !zone || !user) { + X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, + X509V3_R_INVALID_NULL_ARGUMENT); + return 0; + } + if (userlen == -1) + userlen = strlen(user); + if (userlen > 64) { + X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_USER_TOO_LONG); + return 0; + } + if (!*psx) { + if (!(sx = SXNET_new())) + goto err; + if (!ASN1_INTEGER_set(sx->version, 0)) + goto err; + *psx = sx; + } else + sx = *psx; + if (SXNET_get_id_INTEGER(sx, zone)) { + X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, X509V3_R_DUPLICATE_ZONE_ID); + return 0; + } + + if (!(id = SXNETID_new())) + goto err; + if (userlen == -1) + userlen = strlen(user); + + if (!M_ASN1_OCTET_STRING_set(id->user, user, userlen)) + goto err; + if (!sk_SXNETID_push(sx->ids, id)) + goto err; + id->zone = zone; + return 1; + + err: + X509V3err(X509V3_F_SXNET_ADD_ID_INTEGER, ERR_R_MALLOC_FAILURE); + SXNETID_free(id); + SXNET_free(sx); + *psx = NULL; + return 0; +} + +ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone) +{ + ASN1_INTEGER *izone = NULL; + ASN1_OCTET_STRING *oct; + if (!(izone = s2i_ASN1_INTEGER(NULL, zone))) { + X509V3err(X509V3_F_SXNET_GET_ID_ASC, X509V3_R_ERROR_CONVERTING_ZONE); + return NULL; + } + oct = SXNET_get_id_INTEGER(sx, izone); + M_ASN1_INTEGER_free(izone); + return oct; +} + +ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone) +{ + ASN1_INTEGER *izone = NULL; + ASN1_OCTET_STRING *oct; + if (!(izone = M_ASN1_INTEGER_new()) || !ASN1_INTEGER_set(izone, lzone)) { + X509V3err(X509V3_F_SXNET_GET_ID_ULONG, ERR_R_MALLOC_FAILURE); + M_ASN1_INTEGER_free(izone); + return NULL; + } + oct = SXNET_get_id_INTEGER(sx, izone); + M_ASN1_INTEGER_free(izone); + return oct; +} + +ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone) +{ + SXNETID *id; + int i; + for (i = 0; i < sk_SXNETID_num(sx->ids); i++) { + id = sk_SXNETID_value(sx->ids, i); + if (!M_ASN1_INTEGER_cmp(id->zone, zone)) + return id->user; + } + return NULL; +} + +IMPLEMENT_STACK_OF(SXNETID) + +IMPLEMENT_ASN1_SET_OF(SXNETID) diff --git a/libs/openssl/crypto/x509v3/v3_utl.c b/libs/openssl/crypto/x509v3/v3_utl.c new file mode 100644 index 00000000..94aaebba --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3_utl.c @@ -0,0 +1,919 @@ +/* v3_utl.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 1999-2003 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* X509 v3 extension utilities */ + +#include +#include +#include "cryptlib.h" +#include +#include +#include + +static char *strip_spaces(char *name); +static int sk_strcmp(const char *const *a, const char *const *b); +static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, + GENERAL_NAMES *gens); +static void str_free(OPENSSL_STRING str); +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email); + +static int ipv4_from_asc(unsigned char *v4, const char *in); +static int ipv6_from_asc(unsigned char *v6, const char *in); +static int ipv6_cb(const char *elem, int len, void *usr); +static int ipv6_hex(unsigned char *out, const char *in, int inlen); + +/* Add a CONF_VALUE name value pair to stack */ + +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist) +{ + CONF_VALUE *vtmp = NULL; + char *tname = NULL, *tvalue = NULL; + if (name && !(tname = BUF_strdup(name))) + goto err; + if (value && !(tvalue = BUF_strdup(value))) + goto err; + if (!(vtmp = (CONF_VALUE *)OPENSSL_malloc(sizeof(CONF_VALUE)))) + goto err; + if (!*extlist && !(*extlist = sk_CONF_VALUE_new_null())) + goto err; + vtmp->section = NULL; + vtmp->name = tname; + vtmp->value = tvalue; + if (!sk_CONF_VALUE_push(*extlist, vtmp)) + goto err; + return 1; + err: + X509V3err(X509V3_F_X509V3_ADD_VALUE, ERR_R_MALLOC_FAILURE); + if (vtmp) + OPENSSL_free(vtmp); + if (tname) + OPENSSL_free(tname); + if (tvalue) + OPENSSL_free(tvalue); + return 0; +} + +int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist) +{ + return X509V3_add_value(name, (const char *)value, extlist); +} + +/* Free function for STACK_OF(CONF_VALUE) */ + +void X509V3_conf_free(CONF_VALUE *conf) +{ + if (!conf) + return; + if (conf->name) + OPENSSL_free(conf->name); + if (conf->value) + OPENSSL_free(conf->value); + if (conf->section) + OPENSSL_free(conf->section); + OPENSSL_free(conf); +} + +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist) +{ + if (asn1_bool) + return X509V3_add_value(name, "TRUE", extlist); + return X509V3_add_value(name, "FALSE", extlist); +} + +int X509V3_add_value_bool_nf(char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist) +{ + if (asn1_bool) + return X509V3_add_value(name, "TRUE", extlist); + return 1; +} + +char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *a) +{ + BIGNUM *bntmp = NULL; + char *strtmp = NULL; + if (!a) + return NULL; + if (!(bntmp = ASN1_ENUMERATED_to_BN(a, NULL)) || + !(strtmp = BN_bn2dec(bntmp))) + X509V3err(X509V3_F_I2S_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE); + BN_free(bntmp); + return strtmp; +} + +char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, ASN1_INTEGER *a) +{ + BIGNUM *bntmp = NULL; + char *strtmp = NULL; + if (!a) + return NULL; + if (!(bntmp = ASN1_INTEGER_to_BN(a, NULL)) || + !(strtmp = BN_bn2dec(bntmp))) + X509V3err(X509V3_F_I2S_ASN1_INTEGER, ERR_R_MALLOC_FAILURE); + BN_free(bntmp); + return strtmp; +} + +ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, char *value) +{ + BIGNUM *bn = NULL; + ASN1_INTEGER *aint; + int isneg, ishex; + int ret; + if (!value) { + X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_INVALID_NULL_VALUE); + return 0; + } + bn = BN_new(); + if (value[0] == '-') { + value++; + isneg = 1; + } else + isneg = 0; + + if (value[0] == '0' && ((value[1] == 'x') || (value[1] == 'X'))) { + value += 2; + ishex = 1; + } else + ishex = 0; + + if (ishex) + ret = BN_hex2bn(&bn, value); + else + ret = BN_dec2bn(&bn, value); + + if (!ret || value[ret]) { + BN_free(bn); + X509V3err(X509V3_F_S2I_ASN1_INTEGER, X509V3_R_BN_DEC2BN_ERROR); + return 0; + } + + if (isneg && BN_is_zero(bn)) + isneg = 0; + + aint = BN_to_ASN1_INTEGER(bn, NULL); + BN_free(bn); + if (!aint) { + X509V3err(X509V3_F_S2I_ASN1_INTEGER, + X509V3_R_BN_TO_ASN1_INTEGER_ERROR); + return 0; + } + if (isneg) + aint->type |= V_ASN1_NEG; + return aint; +} + +int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist) +{ + char *strtmp; + int ret; + if (!aint) + return 1; + if (!(strtmp = i2s_ASN1_INTEGER(NULL, aint))) + return 0; + ret = X509V3_add_value(name, strtmp, extlist); + OPENSSL_free(strtmp); + return ret; +} + +int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool) +{ + char *btmp; + if (!(btmp = value->value)) + goto err; + if (!strcmp(btmp, "TRUE") || !strcmp(btmp, "true") + || !strcmp(btmp, "Y") || !strcmp(btmp, "y") + || !strcmp(btmp, "YES") || !strcmp(btmp, "yes")) { + *asn1_bool = 0xff; + return 1; + } else if (!strcmp(btmp, "FALSE") || !strcmp(btmp, "false") + || !strcmp(btmp, "N") || !strcmp(btmp, "n") + || !strcmp(btmp, "NO") || !strcmp(btmp, "no")) { + *asn1_bool = 0; + return 1; + } + err: + X509V3err(X509V3_F_X509V3_GET_VALUE_BOOL, + X509V3_R_INVALID_BOOLEAN_STRING); + X509V3_conf_err(value); + return 0; +} + +int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint) +{ + ASN1_INTEGER *itmp; + if (!(itmp = s2i_ASN1_INTEGER(NULL, value->value))) { + X509V3_conf_err(value); + return 0; + } + *aint = itmp; + return 1; +} + +#define HDR_NAME 1 +#define HDR_VALUE 2 + +/* + * #define DEBUG + */ + +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line) +{ + char *p, *q, c; + char *ntmp, *vtmp; + STACK_OF(CONF_VALUE) *values = NULL; + char *linebuf; + int state; + /* We are going to modify the line so copy it first */ + linebuf = BUF_strdup(line); + if (linebuf == NULL) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, ERR_R_MALLOC_FAILURE); + goto err; + } + state = HDR_NAME; + ntmp = NULL; + /* Go through all characters */ + for (p = linebuf, q = linebuf; (c = *p) && (c != '\r') && (c != '\n'); + p++) { + + switch (state) { + case HDR_NAME: + if (c == ':') { + state = HDR_VALUE; + *p = 0; + ntmp = strip_spaces(q); + if (!ntmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, + X509V3_R_INVALID_NULL_NAME); + goto err; + } + q = p + 1; + } else if (c == ',') { + *p = 0; + ntmp = strip_spaces(q); + q = p + 1; +#if 0 + printf("%s\n", ntmp); +#endif + if (!ntmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, + X509V3_R_INVALID_NULL_NAME); + goto err; + } + X509V3_add_value(ntmp, NULL, &values); + } + break; + + case HDR_VALUE: + if (c == ',') { + state = HDR_NAME; + *p = 0; + vtmp = strip_spaces(q); +#if 0 + printf("%s\n", ntmp); +#endif + if (!vtmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, + X509V3_R_INVALID_NULL_VALUE); + goto err; + } + X509V3_add_value(ntmp, vtmp, &values); + ntmp = NULL; + q = p + 1; + } + + } + } + + if (state == HDR_VALUE) { + vtmp = strip_spaces(q); +#if 0 + printf("%s=%s\n", ntmp, vtmp); +#endif + if (!vtmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, + X509V3_R_INVALID_NULL_VALUE); + goto err; + } + X509V3_add_value(ntmp, vtmp, &values); + } else { + ntmp = strip_spaces(q); +#if 0 + printf("%s\n", ntmp); +#endif + if (!ntmp) { + X509V3err(X509V3_F_X509V3_PARSE_LIST, X509V3_R_INVALID_NULL_NAME); + goto err; + } + X509V3_add_value(ntmp, NULL, &values); + } + OPENSSL_free(linebuf); + return values; + + err: + OPENSSL_free(linebuf); + sk_CONF_VALUE_pop_free(values, X509V3_conf_free); + return NULL; + +} + +/* Delete leading and trailing spaces from a string */ +static char *strip_spaces(char *name) +{ + char *p, *q; + /* Skip over leading spaces */ + p = name; + while (*p && isspace((unsigned char)*p)) + p++; + if (!*p) + return NULL; + q = p + strlen(p) - 1; + while ((q != p) && isspace((unsigned char)*q)) + q--; + if (p != q) + q[1] = 0; + if (!*p) + return NULL; + return p; +} + +/* hex string utilities */ + +/* + * Given a buffer of length 'len' return a OPENSSL_malloc'ed string with its + * hex representation @@@ (Contents of buffer are always kept in ASCII, also + * on EBCDIC machines) + */ + +char *hex_to_string(const unsigned char *buffer, long len) +{ + char *tmp, *q; + const unsigned char *p; + int i; + const static char hexdig[] = "0123456789ABCDEF"; + if (!buffer || !len) + return NULL; + if (!(tmp = OPENSSL_malloc(len * 3 + 1))) { + X509V3err(X509V3_F_HEX_TO_STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + q = tmp; + for (i = 0, p = buffer; i < len; i++, p++) { + *q++ = hexdig[(*p >> 4) & 0xf]; + *q++ = hexdig[*p & 0xf]; + *q++ = ':'; + } + q[-1] = 0; +#ifdef CHARSET_EBCDIC + ebcdic2ascii(tmp, tmp, q - tmp - 1); +#endif + + return tmp; +} + +/* + * Give a string of hex digits convert to a buffer + */ + +unsigned char *string_to_hex(const char *str, long *len) +{ + unsigned char *hexbuf, *q; + unsigned char ch, cl, *p; + if (!str) { + X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if (!(hexbuf = OPENSSL_malloc(strlen(str) >> 1))) + goto err; + for (p = (unsigned char *)str, q = hexbuf; *p;) { + ch = *p++; +#ifdef CHARSET_EBCDIC + ch = os_toebcdic[ch]; +#endif + if (ch == ':') + continue; + cl = *p++; +#ifdef CHARSET_EBCDIC + cl = os_toebcdic[cl]; +#endif + if (!cl) { + X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ODD_NUMBER_OF_DIGITS); + OPENSSL_free(hexbuf); + return NULL; + } + if (isupper(ch)) + ch = tolower(ch); + if (isupper(cl)) + cl = tolower(cl); + + if ((ch >= '0') && (ch <= '9')) + ch -= '0'; + else if ((ch >= 'a') && (ch <= 'f')) + ch -= 'a' - 10; + else + goto badhex; + + if ((cl >= '0') && (cl <= '9')) + cl -= '0'; + else if ((cl >= 'a') && (cl <= 'f')) + cl -= 'a' - 10; + else + goto badhex; + + *q++ = (ch << 4) | cl; + } + + if (len) + *len = q - hexbuf; + + return hexbuf; + + err: + if (hexbuf) + OPENSSL_free(hexbuf); + X509V3err(X509V3_F_STRING_TO_HEX, ERR_R_MALLOC_FAILURE); + return NULL; + + badhex: + OPENSSL_free(hexbuf); + X509V3err(X509V3_F_STRING_TO_HEX, X509V3_R_ILLEGAL_HEX_DIGIT); + return NULL; + +} + +/* + * V2I name comparison function: returns zero if 'name' matches cmp or cmp.* + */ + +int name_cmp(const char *name, const char *cmp) +{ + int len, ret; + char c; + len = strlen(cmp); + if ((ret = strncmp(name, cmp, len))) + return ret; + c = name[len]; + if (!c || (c == '.')) + return 0; + return 1; +} + +static int sk_strcmp(const char *const *a, const char *const *b) +{ + return strcmp(*a, *b); +} + +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x) +{ + GENERAL_NAMES *gens; + STACK_OF(OPENSSL_STRING) *ret; + + gens = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL); + ret = get_email(X509_get_subject_name(x), gens); + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + return ret; +} + +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x) +{ + AUTHORITY_INFO_ACCESS *info; + STACK_OF(OPENSSL_STRING) *ret = NULL; + int i; + + info = X509_get_ext_d2i(x, NID_info_access, NULL, NULL); + if (!info) + return NULL; + for (i = 0; i < sk_ACCESS_DESCRIPTION_num(info); i++) { + ACCESS_DESCRIPTION *ad = sk_ACCESS_DESCRIPTION_value(info, i); + if (OBJ_obj2nid(ad->method) == NID_ad_OCSP) { + if (ad->location->type == GEN_URI) { + if (!append_ia5 + (&ret, ad->location->d.uniformResourceIdentifier)) + break; + } + } + } + AUTHORITY_INFO_ACCESS_free(info); + return ret; +} + +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x) +{ + GENERAL_NAMES *gens; + STACK_OF(X509_EXTENSION) *exts; + STACK_OF(OPENSSL_STRING) *ret; + + exts = X509_REQ_get_extensions(x); + gens = X509V3_get_d2i(exts, NID_subject_alt_name, NULL, NULL); + ret = get_email(X509_REQ_get_subject_name(x), gens); + sk_GENERAL_NAME_pop_free(gens, GENERAL_NAME_free); + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + return ret; +} + +static STACK_OF(OPENSSL_STRING) *get_email(X509_NAME *name, + GENERAL_NAMES *gens) +{ + STACK_OF(OPENSSL_STRING) *ret = NULL; + X509_NAME_ENTRY *ne; + ASN1_IA5STRING *email; + GENERAL_NAME *gen; + int i; + /* Now add any email address(es) to STACK */ + i = -1; + /* First supplied X509_NAME */ + while ((i = X509_NAME_get_index_by_NID(name, + NID_pkcs9_emailAddress, i)) >= 0) { + ne = X509_NAME_get_entry(name, i); + email = X509_NAME_ENTRY_get_data(ne); + if (!append_ia5(&ret, email)) + return NULL; + } + for (i = 0; i < sk_GENERAL_NAME_num(gens); i++) { + gen = sk_GENERAL_NAME_value(gens, i); + if (gen->type != GEN_EMAIL) + continue; + if (!append_ia5(&ret, gen->d.ia5)) + return NULL; + } + return ret; +} + +static void str_free(OPENSSL_STRING str) +{ + OPENSSL_free(str); +} + +static int append_ia5(STACK_OF(OPENSSL_STRING) **sk, ASN1_IA5STRING *email) +{ + char *emtmp; + /* First some sanity checks */ + if (email->type != V_ASN1_IA5STRING) + return 1; + if (!email->data || !email->length) + return 1; + if (!*sk) + *sk = sk_OPENSSL_STRING_new(sk_strcmp); + if (!*sk) + return 0; + /* Don't add duplicates */ + if (sk_OPENSSL_STRING_find(*sk, (char *)email->data) != -1) + return 1; + emtmp = BUF_strdup((char *)email->data); + if (!emtmp || !sk_OPENSSL_STRING_push(*sk, emtmp)) { + X509_email_free(*sk); + *sk = NULL; + return 0; + } + return 1; +} + +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk) +{ + sk_OPENSSL_STRING_pop_free(sk, str_free); +} + +/* + * Convert IP addresses both IPv4 and IPv6 into an OCTET STRING compatible + * with RFC3280. + */ + +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc) +{ + unsigned char ipout[16]; + ASN1_OCTET_STRING *ret; + int iplen; + + /* If string contains a ':' assume IPv6 */ + + iplen = a2i_ipadd(ipout, ipasc); + + if (!iplen) + return NULL; + + ret = ASN1_OCTET_STRING_new(); + if (!ret) + return NULL; + if (!ASN1_OCTET_STRING_set(ret, ipout, iplen)) { + ASN1_OCTET_STRING_free(ret); + return NULL; + } + return ret; +} + +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc) +{ + ASN1_OCTET_STRING *ret = NULL; + unsigned char ipout[32]; + char *iptmp = NULL, *p; + int iplen1, iplen2; + p = strchr(ipasc, '/'); + if (!p) + return NULL; + iptmp = BUF_strdup(ipasc); + if (!iptmp) + return NULL; + p = iptmp + (p - ipasc); + *p++ = 0; + + iplen1 = a2i_ipadd(ipout, iptmp); + + if (!iplen1) + goto err; + + iplen2 = a2i_ipadd(ipout + iplen1, p); + + OPENSSL_free(iptmp); + iptmp = NULL; + + if (!iplen2 || (iplen1 != iplen2)) + goto err; + + ret = ASN1_OCTET_STRING_new(); + if (!ret) + goto err; + if (!ASN1_OCTET_STRING_set(ret, ipout, iplen1 + iplen2)) + goto err; + + return ret; + + err: + if (iptmp) + OPENSSL_free(iptmp); + if (ret) + ASN1_OCTET_STRING_free(ret); + return NULL; +} + +int a2i_ipadd(unsigned char *ipout, const char *ipasc) +{ + /* If string contains a ':' assume IPv6 */ + + if (strchr(ipasc, ':')) { + if (!ipv6_from_asc(ipout, ipasc)) + return 0; + return 16; + } else { + if (!ipv4_from_asc(ipout, ipasc)) + return 0; + return 4; + } +} + +static int ipv4_from_asc(unsigned char *v4, const char *in) +{ + int a0, a1, a2, a3; + if (sscanf(in, "%d.%d.%d.%d", &a0, &a1, &a2, &a3) != 4) + return 0; + if ((a0 < 0) || (a0 > 255) || (a1 < 0) || (a1 > 255) + || (a2 < 0) || (a2 > 255) || (a3 < 0) || (a3 > 255)) + return 0; + v4[0] = a0; + v4[1] = a1; + v4[2] = a2; + v4[3] = a3; + return 1; +} + +typedef struct { + /* Temporary store for IPV6 output */ + unsigned char tmp[16]; + /* Total number of bytes in tmp */ + int total; + /* The position of a zero (corresponding to '::') */ + int zero_pos; + /* Number of zeroes */ + int zero_cnt; +} IPV6_STAT; + +static int ipv6_from_asc(unsigned char *v6, const char *in) +{ + IPV6_STAT v6stat; + v6stat.total = 0; + v6stat.zero_pos = -1; + v6stat.zero_cnt = 0; + /* + * Treat the IPv6 representation as a list of values separated by ':'. + * The presence of a '::' will parse as one, two or three zero length + * elements. + */ + if (!CONF_parse_list(in, ':', 0, ipv6_cb, &v6stat)) + return 0; + + /* Now for some sanity checks */ + + if (v6stat.zero_pos == -1) { + /* If no '::' must have exactly 16 bytes */ + if (v6stat.total != 16) + return 0; + } else { + /* If '::' must have less than 16 bytes */ + if (v6stat.total == 16) + return 0; + /* More than three zeroes is an error */ + if (v6stat.zero_cnt > 3) + return 0; + /* Can only have three zeroes if nothing else present */ + else if (v6stat.zero_cnt == 3) { + if (v6stat.total > 0) + return 0; + } + /* Can only have two zeroes if at start or end */ + else if (v6stat.zero_cnt == 2) { + if ((v6stat.zero_pos != 0) + && (v6stat.zero_pos != v6stat.total)) + return 0; + } else + /* Can only have one zero if *not* start or end */ + { + if ((v6stat.zero_pos == 0) + || (v6stat.zero_pos == v6stat.total)) + return 0; + } + } + + /* Format result */ + + if (v6stat.zero_pos >= 0) { + /* Copy initial part */ + memcpy(v6, v6stat.tmp, v6stat.zero_pos); + /* Zero middle */ + memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); + /* Copy final part */ + if (v6stat.total != v6stat.zero_pos) + memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, + v6stat.tmp + v6stat.zero_pos, + v6stat.total - v6stat.zero_pos); + } else + memcpy(v6, v6stat.tmp, 16); + + return 1; +} + +static int ipv6_cb(const char *elem, int len, void *usr) +{ + IPV6_STAT *s = usr; + /* Error if 16 bytes written */ + if (s->total == 16) + return 0; + if (len == 0) { + /* Zero length element, corresponds to '::' */ + if (s->zero_pos == -1) + s->zero_pos = s->total; + /* If we've already got a :: its an error */ + else if (s->zero_pos != s->total) + return 0; + s->zero_cnt++; + } else { + /* If more than 4 characters could be final a.b.c.d form */ + if (len > 4) { + /* Need at least 4 bytes left */ + if (s->total > 12) + return 0; + /* Must be end of string */ + if (elem[len]) + return 0; + if (!ipv4_from_asc(s->tmp + s->total, elem)) + return 0; + s->total += 4; + } else { + if (!ipv6_hex(s->tmp + s->total, elem, len)) + return 0; + s->total += 2; + } + } + return 1; +} + +/* + * Convert a string of up to 4 hex digits into the corresponding IPv6 form. + */ + +static int ipv6_hex(unsigned char *out, const char *in, int inlen) +{ + unsigned char c; + unsigned int num = 0; + if (inlen > 4) + return 0; + while (inlen--) { + c = *in++; + num <<= 4; + if ((c >= '0') && (c <= '9')) + num |= c - '0'; + else if ((c >= 'A') && (c <= 'F')) + num |= c - 'A' + 10; + else if ((c >= 'a') && (c <= 'f')) + num |= c - 'a' + 10; + else + return 0; + } + out[0] = num >> 8; + out[1] = num & 0xff; + return 1; +} + +int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, + unsigned long chtype) +{ + CONF_VALUE *v; + int i, mval; + char *p, *type; + if (!nm) + return 0; + + for (i = 0; i < sk_CONF_VALUE_num(dn_sk); i++) { + v = sk_CONF_VALUE_value(dn_sk, i); + type = v->name; + /* + * Skip past any leading X. X: X, etc to allow for multiple instances + */ + for (p = type; *p; p++) +#ifndef CHARSET_EBCDIC + if ((*p == ':') || (*p == ',') || (*p == '.')) +#else + if ((*p == os_toascii[':']) || (*p == os_toascii[',']) + || (*p == os_toascii['.'])) +#endif + { + p++; + if (*p) + type = p; + break; + } +#ifndef CHARSET_EBCDIC + if (*type == '+') +#else + if (*type == os_toascii['+']) +#endif + { + mval = -1; + type++; + } else + mval = 0; + if (!X509_NAME_add_entry_by_txt(nm, type, chtype, + (unsigned char *)v->value, -1, -1, + mval)) + return 0; + + } + return 1; +} diff --git a/libs/openssl/crypto/x509v3/v3conf.c b/libs/openssl/crypto/x509v3/v3conf.c new file mode 100644 index 00000000..41aa2669 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3conf.c @@ -0,0 +1,129 @@ +/* v3conf.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "cryptlib.h" +#include +#include +#include +#include + +/* Test application to add extensions from a config file */ + +int main(int argc, char **argv) +{ + LHASH *conf; + X509 *cert; + FILE *inf; + char *conf_file; + int i; + int count; + X509_EXTENSION *ext; + X509V3_add_standard_extensions(); + ERR_load_crypto_strings(); + if (!argv[1]) { + fprintf(stderr, "Usage: v3conf cert.pem [file.cnf]\n"); + exit(1); + } + conf_file = argv[2]; + if (!conf_file) + conf_file = "test.cnf"; + conf = CONF_load(NULL, "test.cnf", NULL); + if (!conf) { + fprintf(stderr, "Error opening Config file %s\n", conf_file); + ERR_print_errors_fp(stderr); + exit(1); + } + + inf = fopen(argv[1], "r"); + if (!inf) { + fprintf(stderr, "Can't open certificate file %s\n", argv[1]); + exit(1); + } + cert = PEM_read_X509(inf, NULL, NULL); + if (!cert) { + fprintf(stderr, "Error reading certificate file %s\n", argv[1]); + exit(1); + } + fclose(inf); + + sk_pop_free(cert->cert_info->extensions, X509_EXTENSION_free); + cert->cert_info->extensions = NULL; + + if (!X509V3_EXT_add_conf(conf, NULL, "test_section", cert)) { + fprintf(stderr, "Error adding extensions\n"); + ERR_print_errors_fp(stderr); + exit(1); + } + + count = X509_get_ext_count(cert); + printf("%d extensions\n", count); + for (i = 0; i < count; i++) { + ext = X509_get_ext(cert, i); + printf("%s", OBJ_nid2ln(OBJ_obj2nid(ext->object))); + if (ext->critical) + printf(",critical:\n"); + else + printf(":\n"); + X509V3_EXT_print_fp(stdout, ext, 0, 0); + printf("\n"); + + } + return 0; +} diff --git a/libs/openssl/crypto/x509v3/v3err.c b/libs/openssl/crypto/x509v3/v3err.c new file mode 100644 index 00000000..0138f7a8 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3err.c @@ -0,0 +1,246 @@ +/* crypto/x509v3/v3err.c */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_X509V3,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_X509V3,0,reason) + +static ERR_STRING_DATA X509V3_str_functs[] = { + {ERR_FUNC(X509V3_F_A2I_GENERAL_NAME), "A2I_GENERAL_NAME"}, + {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_CANONIZE), + "ASIDENTIFIERCHOICE_CANONIZE"}, + {ERR_FUNC(X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL), + "ASIDENTIFIERCHOICE_IS_CANONICAL"}, + {ERR_FUNC(X509V3_F_COPY_EMAIL), "COPY_EMAIL"}, + {ERR_FUNC(X509V3_F_COPY_ISSUER), "COPY_ISSUER"}, + {ERR_FUNC(X509V3_F_DO_DIRNAME), "DO_DIRNAME"}, + {ERR_FUNC(X509V3_F_DO_EXT_CONF), "DO_EXT_CONF"}, + {ERR_FUNC(X509V3_F_DO_EXT_I2D), "DO_EXT_I2D"}, + {ERR_FUNC(X509V3_F_DO_EXT_NCONF), "DO_EXT_NCONF"}, + {ERR_FUNC(X509V3_F_DO_I2V_NAME_CONSTRAINTS), "DO_I2V_NAME_CONSTRAINTS"}, + {ERR_FUNC(X509V3_F_GNAMES_FROM_SECTNAME), "GNAMES_FROM_SECTNAME"}, + {ERR_FUNC(X509V3_F_HEX_TO_STRING), "hex_to_string"}, + {ERR_FUNC(X509V3_F_I2S_ASN1_ENUMERATED), "i2s_ASN1_ENUMERATED"}, + {ERR_FUNC(X509V3_F_I2S_ASN1_IA5STRING), "I2S_ASN1_IA5STRING"}, + {ERR_FUNC(X509V3_F_I2S_ASN1_INTEGER), "i2s_ASN1_INTEGER"}, + {ERR_FUNC(X509V3_F_I2V_AUTHORITY_INFO_ACCESS), + "I2V_AUTHORITY_INFO_ACCESS"}, + {ERR_FUNC(X509V3_F_NOTICE_SECTION), "NOTICE_SECTION"}, + {ERR_FUNC(X509V3_F_NREF_NOS), "NREF_NOS"}, + {ERR_FUNC(X509V3_F_POLICY_SECTION), "POLICY_SECTION"}, + {ERR_FUNC(X509V3_F_PROCESS_PCI_VALUE), "PROCESS_PCI_VALUE"}, + {ERR_FUNC(X509V3_F_R2I_CERTPOL), "R2I_CERTPOL"}, + {ERR_FUNC(X509V3_F_R2I_PCI), "R2I_PCI"}, + {ERR_FUNC(X509V3_F_S2I_ASN1_IA5STRING), "S2I_ASN1_IA5STRING"}, + {ERR_FUNC(X509V3_F_S2I_ASN1_INTEGER), "s2i_ASN1_INTEGER"}, + {ERR_FUNC(X509V3_F_S2I_ASN1_OCTET_STRING), "s2i_ASN1_OCTET_STRING"}, + {ERR_FUNC(X509V3_F_S2I_ASN1_SKEY_ID), "S2I_ASN1_SKEY_ID"}, + {ERR_FUNC(X509V3_F_S2I_SKEY_ID), "S2I_SKEY_ID"}, + {ERR_FUNC(X509V3_F_SET_DIST_POINT_NAME), "SET_DIST_POINT_NAME"}, + {ERR_FUNC(X509V3_F_STRING_TO_HEX), "string_to_hex"}, + {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ASC), "SXNET_add_id_asc"}, + {ERR_FUNC(X509V3_F_SXNET_ADD_ID_INTEGER), "SXNET_add_id_INTEGER"}, + {ERR_FUNC(X509V3_F_SXNET_ADD_ID_ULONG), "SXNET_add_id_ulong"}, + {ERR_FUNC(X509V3_F_SXNET_GET_ID_ASC), "SXNET_get_id_asc"}, + {ERR_FUNC(X509V3_F_SXNET_GET_ID_ULONG), "SXNET_get_id_ulong"}, + {ERR_FUNC(X509V3_F_V2I_ASIDENTIFIERS), "V2I_ASIDENTIFIERS"}, + {ERR_FUNC(X509V3_F_V2I_ASN1_BIT_STRING), "v2i_ASN1_BIT_STRING"}, + {ERR_FUNC(X509V3_F_V2I_AUTHORITY_INFO_ACCESS), + "V2I_AUTHORITY_INFO_ACCESS"}, + {ERR_FUNC(X509V3_F_V2I_AUTHORITY_KEYID), "V2I_AUTHORITY_KEYID"}, + {ERR_FUNC(X509V3_F_V2I_BASIC_CONSTRAINTS), "V2I_BASIC_CONSTRAINTS"}, + {ERR_FUNC(X509V3_F_V2I_CRLD), "V2I_CRLD"}, + {ERR_FUNC(X509V3_F_V2I_EXTENDED_KEY_USAGE), "V2I_EXTENDED_KEY_USAGE"}, + {ERR_FUNC(X509V3_F_V2I_GENERAL_NAMES), "v2i_GENERAL_NAMES"}, + {ERR_FUNC(X509V3_F_V2I_GENERAL_NAME_EX), "v2i_GENERAL_NAME_ex"}, + {ERR_FUNC(X509V3_F_V2I_IDP), "V2I_IDP"}, + {ERR_FUNC(X509V3_F_V2I_IPADDRBLOCKS), "V2I_IPADDRBLOCKS"}, + {ERR_FUNC(X509V3_F_V2I_ISSUER_ALT), "V2I_ISSUER_ALT"}, + {ERR_FUNC(X509V3_F_V2I_NAME_CONSTRAINTS), "V2I_NAME_CONSTRAINTS"}, + {ERR_FUNC(X509V3_F_V2I_POLICY_CONSTRAINTS), "V2I_POLICY_CONSTRAINTS"}, + {ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS), "V2I_POLICY_MAPPINGS"}, + {ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT), "V2I_SUBJECT_ALT"}, + {ERR_FUNC(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL), + "V3_ADDR_VALIDATE_PATH_INTERNAL"}, + {ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION), "V3_GENERIC_EXTENSION"}, + {ERR_FUNC(X509V3_F_X509V3_ADD1_I2D), "X509V3_add1_i2d"}, + {ERR_FUNC(X509V3_F_X509V3_ADD_VALUE), "X509V3_add_value"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_ADD), "X509V3_EXT_add"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_ADD_ALIAS), "X509V3_EXT_add_alias"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_CONF), "X509V3_EXT_conf"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_I2D), "X509V3_EXT_i2d"}, + {ERR_FUNC(X509V3_F_X509V3_EXT_NCONF), "X509V3_EXT_nconf"}, + {ERR_FUNC(X509V3_F_X509V3_GET_SECTION), "X509V3_get_section"}, + {ERR_FUNC(X509V3_F_X509V3_GET_STRING), "X509V3_get_string"}, + {ERR_FUNC(X509V3_F_X509V3_GET_VALUE_BOOL), "X509V3_get_value_bool"}, + {ERR_FUNC(X509V3_F_X509V3_PARSE_LIST), "X509V3_parse_list"}, + {ERR_FUNC(X509V3_F_X509_PURPOSE_ADD), "X509_PURPOSE_add"}, + {ERR_FUNC(X509V3_F_X509_PURPOSE_SET), "X509_PURPOSE_set"}, + {0, NULL} +}; + +static ERR_STRING_DATA X509V3_str_reasons[] = { + {ERR_REASON(X509V3_R_BAD_IP_ADDRESS), "bad ip address"}, + {ERR_REASON(X509V3_R_BAD_OBJECT), "bad object"}, + {ERR_REASON(X509V3_R_BN_DEC2BN_ERROR), "bn dec2bn error"}, + {ERR_REASON(X509V3_R_BN_TO_ASN1_INTEGER_ERROR), + "bn to asn1 integer error"}, + {ERR_REASON(X509V3_R_DIRNAME_ERROR), "dirname error"}, + {ERR_REASON(X509V3_R_DISTPOINT_ALREADY_SET), "distpoint already set"}, + {ERR_REASON(X509V3_R_DUPLICATE_ZONE_ID), "duplicate zone id"}, + {ERR_REASON(X509V3_R_ERROR_CONVERTING_ZONE), "error converting zone"}, + {ERR_REASON(X509V3_R_ERROR_CREATING_EXTENSION), + "error creating extension"}, + {ERR_REASON(X509V3_R_ERROR_IN_EXTENSION), "error in extension"}, + {ERR_REASON(X509V3_R_EXPECTED_A_SECTION_NAME), "expected a section name"}, + {ERR_REASON(X509V3_R_EXTENSION_EXISTS), "extension exists"}, + {ERR_REASON(X509V3_R_EXTENSION_NAME_ERROR), "extension name error"}, + {ERR_REASON(X509V3_R_EXTENSION_NOT_FOUND), "extension not found"}, + {ERR_REASON(X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED), + "extension setting not supported"}, + {ERR_REASON(X509V3_R_EXTENSION_VALUE_ERROR), "extension value error"}, + {ERR_REASON(X509V3_R_ILLEGAL_EMPTY_EXTENSION), "illegal empty extension"}, + {ERR_REASON(X509V3_R_ILLEGAL_HEX_DIGIT), "illegal hex digit"}, + {ERR_REASON(X509V3_R_INCORRECT_POLICY_SYNTAX_TAG), + "incorrect policy syntax tag"}, + {ERR_REASON(X509V3_R_INVALID_MULTIPLE_RDNS), "invalid multiple rdns"}, + {ERR_REASON(X509V3_R_INVALID_ASNUMBER), "invalid asnumber"}, + {ERR_REASON(X509V3_R_INVALID_ASRANGE), "invalid asrange"}, + {ERR_REASON(X509V3_R_INVALID_BOOLEAN_STRING), "invalid boolean string"}, + {ERR_REASON(X509V3_R_INVALID_EXTENSION_STRING), + "invalid extension string"}, + {ERR_REASON(X509V3_R_INVALID_INHERITANCE), "invalid inheritance"}, + {ERR_REASON(X509V3_R_INVALID_IPADDRESS), "invalid ipaddress"}, + {ERR_REASON(X509V3_R_INVALID_NAME), "invalid name"}, + {ERR_REASON(X509V3_R_INVALID_NULL_ARGUMENT), "invalid null argument"}, + {ERR_REASON(X509V3_R_INVALID_NULL_NAME), "invalid null name"}, + {ERR_REASON(X509V3_R_INVALID_NULL_VALUE), "invalid null value"}, + {ERR_REASON(X509V3_R_INVALID_NUMBER), "invalid number"}, + {ERR_REASON(X509V3_R_INVALID_NUMBERS), "invalid numbers"}, + {ERR_REASON(X509V3_R_INVALID_OBJECT_IDENTIFIER), + "invalid object identifier"}, + {ERR_REASON(X509V3_R_INVALID_OPTION), "invalid option"}, + {ERR_REASON(X509V3_R_INVALID_POLICY_IDENTIFIER), + "invalid policy identifier"}, + {ERR_REASON(X509V3_R_INVALID_PROXY_POLICY_SETTING), + "invalid proxy policy setting"}, + {ERR_REASON(X509V3_R_INVALID_PURPOSE), "invalid purpose"}, + {ERR_REASON(X509V3_R_INVALID_SAFI), "invalid safi"}, + {ERR_REASON(X509V3_R_INVALID_SECTION), "invalid section"}, + {ERR_REASON(X509V3_R_INVALID_SYNTAX), "invalid syntax"}, + {ERR_REASON(X509V3_R_ISSUER_DECODE_ERROR), "issuer decode error"}, + {ERR_REASON(X509V3_R_MISSING_VALUE), "missing value"}, + {ERR_REASON(X509V3_R_NEED_ORGANIZATION_AND_NUMBERS), + "need organization and numbers"}, + {ERR_REASON(X509V3_R_NO_CONFIG_DATABASE), "no config database"}, + {ERR_REASON(X509V3_R_NO_ISSUER_CERTIFICATE), "no issuer certificate"}, + {ERR_REASON(X509V3_R_NO_ISSUER_DETAILS), "no issuer details"}, + {ERR_REASON(X509V3_R_NO_POLICY_IDENTIFIER), "no policy identifier"}, + {ERR_REASON(X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED), + "no proxy cert policy language defined"}, + {ERR_REASON(X509V3_R_NO_PUBLIC_KEY), "no public key"}, + {ERR_REASON(X509V3_R_NO_SUBJECT_DETAILS), "no subject details"}, + {ERR_REASON(X509V3_R_ODD_NUMBER_OF_DIGITS), "odd number of digits"}, + {ERR_REASON(X509V3_R_OPERATION_NOT_DEFINED), "operation not defined"}, + {ERR_REASON(X509V3_R_OTHERNAME_ERROR), "othername error"}, + {ERR_REASON(X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED), + "policy language already defined"}, + {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH), "policy path length"}, + {ERR_REASON(X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED), + "policy path length already defined"}, + {ERR_REASON(X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED), + "policy syntax not currently supported"}, + {ERR_REASON(X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY), + "policy when proxy language requires no policy"}, + {ERR_REASON(X509V3_R_SECTION_NOT_FOUND), "section not found"}, + {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS), + "unable to get issuer details"}, + {ERR_REASON(X509V3_R_UNABLE_TO_GET_ISSUER_KEYID), + "unable to get issuer keyid"}, + {ERR_REASON(X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT), + "unknown bit string argument"}, + {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION), "unknown extension"}, + {ERR_REASON(X509V3_R_UNKNOWN_EXTENSION_NAME), "unknown extension name"}, + {ERR_REASON(X509V3_R_UNKNOWN_OPTION), "unknown option"}, + {ERR_REASON(X509V3_R_UNSUPPORTED_OPTION), "unsupported option"}, + {ERR_REASON(X509V3_R_UNSUPPORTED_TYPE), "unsupported type"}, + {ERR_REASON(X509V3_R_USER_TOO_LONG), "user too long"}, + {0, NULL} +}; + +#endif + +void ERR_load_X509V3_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(X509V3_str_functs[0].error) == NULL) { + ERR_load_strings(0, X509V3_str_functs); + ERR_load_strings(0, X509V3_str_reasons); + } +#endif +} diff --git a/libs/openssl/crypto/x509v3/v3prin.c b/libs/openssl/crypto/x509v3/v3prin.c new file mode 100644 index 00000000..cbc35707 --- /dev/null +++ b/libs/openssl/crypto/x509v3/v3prin.c @@ -0,0 +1,99 @@ +/* v3prin.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include + +int main(int argc, char **argv) +{ + X509 *cert; + FILE *inf; + int i, count; + X509_EXTENSION *ext; + X509V3_add_standard_extensions(); + ERR_load_crypto_strings(); + if (!argv[1]) { + fprintf(stderr, "Usage v3prin cert.pem\n"); + exit(1); + } + if (!(inf = fopen(argv[1], "r"))) { + fprintf(stderr, "Can't open %s\n", argv[1]); + exit(1); + } + if (!(cert = PEM_read_X509(inf, NULL, NULL))) { + fprintf(stderr, "Can't read certificate %s\n", argv[1]); + ERR_print_errors_fp(stderr); + exit(1); + } + fclose(inf); + count = X509_get_ext_count(cert); + printf("%d extensions\n", count); + for (i = 0; i < count; i++) { + ext = X509_get_ext(cert, i); + printf("%s\n", OBJ_nid2ln(OBJ_obj2nid(ext->object))); + if (!X509V3_EXT_print_fp(stdout, ext, 0, 0)) + ERR_print_errors_fp(stderr); + printf("\n"); + + } + return 0; +} diff --git a/libs/openssl/crypto/x509v3/x509v3.h b/libs/openssl/crypto/x509v3/x509v3.h new file mode 100644 index 00000000..db9c3e8b --- /dev/null +++ b/libs/openssl/crypto/x509v3/x509v3.h @@ -0,0 +1,1015 @@ +/* x509v3.h */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * Copyright (c) 1999-2004 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#ifndef HEADER_X509V3_H +# define HEADER_X509V3_H + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Forward reference */ +struct v3_ext_method; +struct v3_ext_ctx; + +/* Useful typedefs */ + +typedef void *(*X509V3_EXT_NEW)(void); +typedef void (*X509V3_EXT_FREE) (void *); +typedef void *(*X509V3_EXT_D2I)(void *, const unsigned char **, long); +typedef int (*X509V3_EXT_I2D) (void *, unsigned char **); +typedef STACK_OF(CONF_VALUE) * + (*X509V3_EXT_I2V) (const struct v3_ext_method *method, void *ext, + STACK_OF(CONF_VALUE) *extlist); +typedef void *(*X509V3_EXT_V2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, + STACK_OF(CONF_VALUE) *values); +typedef char *(*X509V3_EXT_I2S)(const struct v3_ext_method *method, + void *ext); +typedef void *(*X509V3_EXT_S2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); +typedef int (*X509V3_EXT_I2R) (const struct v3_ext_method *method, void *ext, + BIO *out, int indent); +typedef void *(*X509V3_EXT_R2I)(const struct v3_ext_method *method, + struct v3_ext_ctx *ctx, const char *str); + +/* V3 extension structure */ + +struct v3_ext_method { + int ext_nid; + int ext_flags; +/* If this is set the following four fields are ignored */ + ASN1_ITEM_EXP *it; +/* Old style ASN1 calls */ + X509V3_EXT_NEW ext_new; + X509V3_EXT_FREE ext_free; + X509V3_EXT_D2I d2i; + X509V3_EXT_I2D i2d; +/* The following pair is used for string extensions */ + X509V3_EXT_I2S i2s; + X509V3_EXT_S2I s2i; +/* The following pair is used for multi-valued extensions */ + X509V3_EXT_I2V i2v; + X509V3_EXT_V2I v2i; +/* The following are used for raw extensions */ + X509V3_EXT_I2R i2r; + X509V3_EXT_R2I r2i; + void *usr_data; /* Any extension specific data */ +}; + +typedef struct X509V3_CONF_METHOD_st { + char *(*get_string) (void *db, char *section, char *value); + STACK_OF(CONF_VALUE) *(*get_section) (void *db, char *section); + void (*free_string) (void *db, char *string); + void (*free_section) (void *db, STACK_OF(CONF_VALUE) *section); +} X509V3_CONF_METHOD; + +/* Context specific info */ +struct v3_ext_ctx { +# define CTX_TEST 0x1 + int flags; + X509 *issuer_cert; + X509 *subject_cert; + X509_REQ *subject_req; + X509_CRL *crl; + X509V3_CONF_METHOD *db_meth; + void *db; +/* Maybe more here */ +}; + +typedef struct v3_ext_method X509V3_EXT_METHOD; + +DECLARE_STACK_OF(X509V3_EXT_METHOD) + +/* ext_flags values */ +# define X509V3_EXT_DYNAMIC 0x1 +# define X509V3_EXT_CTX_DEP 0x2 +# define X509V3_EXT_MULTILINE 0x4 + +typedef BIT_STRING_BITNAME ENUMERATED_NAMES; + +typedef struct BASIC_CONSTRAINTS_st { + int ca; + ASN1_INTEGER *pathlen; +} BASIC_CONSTRAINTS; + +typedef struct PKEY_USAGE_PERIOD_st { + ASN1_GENERALIZEDTIME *notBefore; + ASN1_GENERALIZEDTIME *notAfter; +} PKEY_USAGE_PERIOD; + +typedef struct otherName_st { + ASN1_OBJECT *type_id; + ASN1_TYPE *value; +} OTHERNAME; + +typedef struct EDIPartyName_st { + ASN1_STRING *nameAssigner; + ASN1_STRING *partyName; +} EDIPARTYNAME; + +typedef struct GENERAL_NAME_st { +# define GEN_OTHERNAME 0 +# define GEN_EMAIL 1 +# define GEN_DNS 2 +# define GEN_X400 3 +# define GEN_DIRNAME 4 +# define GEN_EDIPARTY 5 +# define GEN_URI 6 +# define GEN_IPADD 7 +# define GEN_RID 8 + int type; + union { + char *ptr; + OTHERNAME *otherName; /* otherName */ + ASN1_IA5STRING *rfc822Name; + ASN1_IA5STRING *dNSName; + ASN1_TYPE *x400Address; + X509_NAME *directoryName; + EDIPARTYNAME *ediPartyName; + ASN1_IA5STRING *uniformResourceIdentifier; + ASN1_OCTET_STRING *iPAddress; + ASN1_OBJECT *registeredID; + /* Old names */ + ASN1_OCTET_STRING *ip; /* iPAddress */ + X509_NAME *dirn; /* dirn */ + ASN1_IA5STRING *ia5; /* rfc822Name, dNSName, + * uniformResourceIdentifier */ + ASN1_OBJECT *rid; /* registeredID */ + ASN1_TYPE *other; /* x400Address */ + } d; +} GENERAL_NAME; + +typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; + +typedef struct ACCESS_DESCRIPTION_st { + ASN1_OBJECT *method; + GENERAL_NAME *location; +} ACCESS_DESCRIPTION; + +typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; + +typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; + +DECLARE_STACK_OF(GENERAL_NAME) +DECLARE_ASN1_SET_OF(GENERAL_NAME) + +DECLARE_STACK_OF(ACCESS_DESCRIPTION) +DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) + +typedef struct DIST_POINT_NAME_st { + int type; + union { + GENERAL_NAMES *fullname; + STACK_OF(X509_NAME_ENTRY) *relativename; + } name; +/* If relativename then this contains the full distribution point name */ + X509_NAME *dpname; +} DIST_POINT_NAME; +/* All existing reasons */ +# define CRLDP_ALL_REASONS 0x807f + +# define CRL_REASON_NONE -1 +# define CRL_REASON_UNSPECIFIED 0 +# define CRL_REASON_KEY_COMPROMISE 1 +# define CRL_REASON_CA_COMPROMISE 2 +# define CRL_REASON_AFFILIATION_CHANGED 3 +# define CRL_REASON_SUPERSEDED 4 +# define CRL_REASON_CESSATION_OF_OPERATION 5 +# define CRL_REASON_CERTIFICATE_HOLD 6 +# define CRL_REASON_REMOVE_FROM_CRL 8 +# define CRL_REASON_PRIVILEGE_WITHDRAWN 9 +# define CRL_REASON_AA_COMPROMISE 10 + +struct DIST_POINT_st { + DIST_POINT_NAME *distpoint; + ASN1_BIT_STRING *reasons; + GENERAL_NAMES *CRLissuer; + int dp_reasons; +}; + +typedef STACK_OF(DIST_POINT) CRL_DIST_POINTS; + +DECLARE_STACK_OF(DIST_POINT) +DECLARE_ASN1_SET_OF(DIST_POINT) + +struct AUTHORITY_KEYID_st { + ASN1_OCTET_STRING *keyid; + GENERAL_NAMES *issuer; + ASN1_INTEGER *serial; +}; + +/* Strong extranet structures */ + +typedef struct SXNET_ID_st { + ASN1_INTEGER *zone; + ASN1_OCTET_STRING *user; +} SXNETID; + +DECLARE_STACK_OF(SXNETID) +DECLARE_ASN1_SET_OF(SXNETID) + +typedef struct SXNET_st { + ASN1_INTEGER *version; + STACK_OF(SXNETID) *ids; +} SXNET; + +typedef struct NOTICEREF_st { + ASN1_STRING *organization; + STACK_OF(ASN1_INTEGER) *noticenos; +} NOTICEREF; + +typedef struct USERNOTICE_st { + NOTICEREF *noticeref; + ASN1_STRING *exptext; +} USERNOTICE; + +typedef struct POLICYQUALINFO_st { + ASN1_OBJECT *pqualid; + union { + ASN1_IA5STRING *cpsuri; + USERNOTICE *usernotice; + ASN1_TYPE *other; + } d; +} POLICYQUALINFO; + +DECLARE_STACK_OF(POLICYQUALINFO) +DECLARE_ASN1_SET_OF(POLICYQUALINFO) + +typedef struct POLICYINFO_st { + ASN1_OBJECT *policyid; + STACK_OF(POLICYQUALINFO) *qualifiers; +} POLICYINFO; + +typedef STACK_OF(POLICYINFO) CERTIFICATEPOLICIES; + +DECLARE_STACK_OF(POLICYINFO) +DECLARE_ASN1_SET_OF(POLICYINFO) + +typedef struct POLICY_MAPPING_st { + ASN1_OBJECT *issuerDomainPolicy; + ASN1_OBJECT *subjectDomainPolicy; +} POLICY_MAPPING; + +DECLARE_STACK_OF(POLICY_MAPPING) + +typedef STACK_OF(POLICY_MAPPING) POLICY_MAPPINGS; + +typedef struct GENERAL_SUBTREE_st { + GENERAL_NAME *base; + ASN1_INTEGER *minimum; + ASN1_INTEGER *maximum; +} GENERAL_SUBTREE; + +DECLARE_STACK_OF(GENERAL_SUBTREE) + +struct NAME_CONSTRAINTS_st { + STACK_OF(GENERAL_SUBTREE) *permittedSubtrees; + STACK_OF(GENERAL_SUBTREE) *excludedSubtrees; +}; + +typedef struct POLICY_CONSTRAINTS_st { + ASN1_INTEGER *requireExplicitPolicy; + ASN1_INTEGER *inhibitPolicyMapping; +} POLICY_CONSTRAINTS; + +/* Proxy certificate structures, see RFC 3820 */ +typedef struct PROXY_POLICY_st { + ASN1_OBJECT *policyLanguage; + ASN1_OCTET_STRING *policy; +} PROXY_POLICY; + +typedef struct PROXY_CERT_INFO_EXTENSION_st { + ASN1_INTEGER *pcPathLengthConstraint; + PROXY_POLICY *proxyPolicy; +} PROXY_CERT_INFO_EXTENSION; + +DECLARE_ASN1_FUNCTIONS(PROXY_POLICY) +DECLARE_ASN1_FUNCTIONS(PROXY_CERT_INFO_EXTENSION) + +struct ISSUING_DIST_POINT_st { + DIST_POINT_NAME *distpoint; + int onlyuser; + int onlyCA; + ASN1_BIT_STRING *onlysomereasons; + int indirectCRL; + int onlyattr; +}; + +/* Values in idp_flags field */ +/* IDP present */ +# define IDP_PRESENT 0x1 +/* IDP values inconsistent */ +# define IDP_INVALID 0x2 +/* onlyuser true */ +# define IDP_ONLYUSER 0x4 +/* onlyCA true */ +# define IDP_ONLYCA 0x8 +/* onlyattr true */ +# define IDP_ONLYATTR 0x10 +/* indirectCRL true */ +# define IDP_INDIRECT 0x20 +/* onlysomereasons present */ +# define IDP_REASONS 0x40 + +# define X509V3_conf_err(val) ERR_add_error_data(6, "section:", val->section, \ +",name:", val->name, ",value:", val->value); + +# define X509V3_set_ctx_test(ctx) \ + X509V3_set_ctx(ctx, NULL, NULL, NULL, NULL, CTX_TEST) +# define X509V3_set_ctx_nodb(ctx) (ctx)->db = NULL; + +# define EXT_BITSTRING(nid, table) { nid, 0, ASN1_ITEM_ref(ASN1_BIT_STRING), \ + 0,0,0,0, \ + 0,0, \ + (X509V3_EXT_I2V)i2v_ASN1_BIT_STRING, \ + (X509V3_EXT_V2I)v2i_ASN1_BIT_STRING, \ + NULL, NULL, \ + table} + +# define EXT_IA5STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_IA5STRING), \ + 0,0,0,0, \ + (X509V3_EXT_I2S)i2s_ASN1_IA5STRING, \ + (X509V3_EXT_S2I)s2i_ASN1_IA5STRING, \ + 0,0,0,0, \ + NULL} + +# define EXT_END { -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} + +/* X509_PURPOSE stuff */ + +# define EXFLAG_BCONS 0x1 +# define EXFLAG_KUSAGE 0x2 +# define EXFLAG_XKUSAGE 0x4 +# define EXFLAG_NSCERT 0x8 + +# define EXFLAG_CA 0x10 +/* Really self issued not necessarily self signed */ +# define EXFLAG_SI 0x20 +# define EXFLAG_SS 0x20 +# define EXFLAG_V1 0x40 +# define EXFLAG_INVALID 0x80 +# define EXFLAG_SET 0x100 +# define EXFLAG_CRITICAL 0x200 +# define EXFLAG_PROXY 0x400 + +# define EXFLAG_INVALID_POLICY 0x800 +# define EXFLAG_FRESHEST 0x1000 + +# define KU_DIGITAL_SIGNATURE 0x0080 +# define KU_NON_REPUDIATION 0x0040 +# define KU_KEY_ENCIPHERMENT 0x0020 +# define KU_DATA_ENCIPHERMENT 0x0010 +# define KU_KEY_AGREEMENT 0x0008 +# define KU_KEY_CERT_SIGN 0x0004 +# define KU_CRL_SIGN 0x0002 +# define KU_ENCIPHER_ONLY 0x0001 +# define KU_DECIPHER_ONLY 0x8000 + +# define NS_SSL_CLIENT 0x80 +# define NS_SSL_SERVER 0x40 +# define NS_SMIME 0x20 +# define NS_OBJSIGN 0x10 +# define NS_SSL_CA 0x04 +# define NS_SMIME_CA 0x02 +# define NS_OBJSIGN_CA 0x01 +# define NS_ANY_CA (NS_SSL_CA|NS_SMIME_CA|NS_OBJSIGN_CA) + +# define XKU_SSL_SERVER 0x1 +# define XKU_SSL_CLIENT 0x2 +# define XKU_SMIME 0x4 +# define XKU_CODE_SIGN 0x8 +# define XKU_SGC 0x10 +# define XKU_OCSP_SIGN 0x20 +# define XKU_TIMESTAMP 0x40 +# define XKU_DVCS 0x80 + +# define X509_PURPOSE_DYNAMIC 0x1 +# define X509_PURPOSE_DYNAMIC_NAME 0x2 + +typedef struct x509_purpose_st { + int purpose; + int trust; /* Default trust ID */ + int flags; + int (*check_purpose) (const struct x509_purpose_st *, const X509 *, int); + char *name; + char *sname; + void *usr_data; +} X509_PURPOSE; + +# define X509_PURPOSE_SSL_CLIENT 1 +# define X509_PURPOSE_SSL_SERVER 2 +# define X509_PURPOSE_NS_SSL_SERVER 3 +# define X509_PURPOSE_SMIME_SIGN 4 +# define X509_PURPOSE_SMIME_ENCRYPT 5 +# define X509_PURPOSE_CRL_SIGN 6 +# define X509_PURPOSE_ANY 7 +# define X509_PURPOSE_OCSP_HELPER 8 +# define X509_PURPOSE_TIMESTAMP_SIGN 9 + +# define X509_PURPOSE_MIN 1 +# define X509_PURPOSE_MAX 9 + +/* Flags for X509V3_EXT_print() */ + +# define X509V3_EXT_UNKNOWN_MASK (0xfL << 16) +/* Return error for unknown extensions */ +# define X509V3_EXT_DEFAULT 0 +/* Print error for unknown extensions */ +# define X509V3_EXT_ERROR_UNKNOWN (1L << 16) +/* ASN1 parse unknown extensions */ +# define X509V3_EXT_PARSE_UNKNOWN (2L << 16) +/* BIO_dump unknown extensions */ +# define X509V3_EXT_DUMP_UNKNOWN (3L << 16) + +/* Flags for X509V3_add1_i2d */ + +# define X509V3_ADD_OP_MASK 0xfL +# define X509V3_ADD_DEFAULT 0L +# define X509V3_ADD_APPEND 1L +# define X509V3_ADD_REPLACE 2L +# define X509V3_ADD_REPLACE_EXISTING 3L +# define X509V3_ADD_KEEP_EXISTING 4L +# define X509V3_ADD_DELETE 5L +# define X509V3_ADD_SILENT 0x10 + +DECLARE_STACK_OF(X509_PURPOSE) + +DECLARE_ASN1_FUNCTIONS(BASIC_CONSTRAINTS) + +DECLARE_ASN1_FUNCTIONS(SXNET) +DECLARE_ASN1_FUNCTIONS(SXNETID) + +int SXNET_add_id_asc(SXNET **psx, char *zone, char *user, int userlen); +int SXNET_add_id_ulong(SXNET **psx, unsigned long lzone, char *user, + int userlen); +int SXNET_add_id_INTEGER(SXNET **psx, ASN1_INTEGER *izone, char *user, + int userlen); + +ASN1_OCTET_STRING *SXNET_get_id_asc(SXNET *sx, char *zone); +ASN1_OCTET_STRING *SXNET_get_id_ulong(SXNET *sx, unsigned long lzone); +ASN1_OCTET_STRING *SXNET_get_id_INTEGER(SXNET *sx, ASN1_INTEGER *zone); + +DECLARE_ASN1_FUNCTIONS(AUTHORITY_KEYID) + +DECLARE_ASN1_FUNCTIONS(PKEY_USAGE_PERIOD) + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAME) +GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); +int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b); + +ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); +STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *extlist); + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, + GENERAL_NAME *gen, + STACK_OF(CONF_VALUE) *ret); +int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) + +STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, + GENERAL_NAMES *gen, + STACK_OF(CONF_VALUE) *extlist); +GENERAL_NAMES *v2i_GENERAL_NAMES(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); + +DECLARE_ASN1_FUNCTIONS(OTHERNAME) +DECLARE_ASN1_FUNCTIONS(EDIPARTYNAME) +int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); +void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); +void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype); +int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value); +int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue); + +char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + ASN1_OCTET_STRING *ia5); +ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, char *str); + +DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) +int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a); + +DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) +DECLARE_ASN1_FUNCTIONS(POLICYINFO) +DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO) +DECLARE_ASN1_FUNCTIONS(USERNOTICE) +DECLARE_ASN1_FUNCTIONS(NOTICEREF) + +DECLARE_ASN1_FUNCTIONS(CRL_DIST_POINTS) +DECLARE_ASN1_FUNCTIONS(DIST_POINT) +DECLARE_ASN1_FUNCTIONS(DIST_POINT_NAME) +DECLARE_ASN1_FUNCTIONS(ISSUING_DIST_POINT) + +int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); + +int NAME_CONSTRAINTS_check(X509 *x, NAME_CONSTRAINTS *nc); + +DECLARE_ASN1_FUNCTIONS(ACCESS_DESCRIPTION) +DECLARE_ASN1_FUNCTIONS(AUTHORITY_INFO_ACCESS) + +DECLARE_ASN1_ITEM(POLICY_MAPPING) +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_MAPPING) +DECLARE_ASN1_ITEM(POLICY_MAPPINGS) + +DECLARE_ASN1_ITEM(GENERAL_SUBTREE) +DECLARE_ASN1_ALLOC_FUNCTIONS(GENERAL_SUBTREE) + +DECLARE_ASN1_ITEM(NAME_CONSTRAINTS) +DECLARE_ASN1_ALLOC_FUNCTIONS(NAME_CONSTRAINTS) + +DECLARE_ASN1_ALLOC_FUNCTIONS(POLICY_CONSTRAINTS) +DECLARE_ASN1_ITEM(POLICY_CONSTRAINTS) + +GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, int gen_type, char *value, + int is_nc); + +# ifdef HEADER_CONF_H +GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf); +GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, + int is_nc); +void X509V3_conf_free(CONF_VALUE *val); + +X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, + char *value); +X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, + char *value); +int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, + STACK_OF(X509_EXTENSION) **sk); +int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509 *cert); +int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509_REQ *req); +int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, + X509_CRL *crl); + +X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, + X509V3_CTX *ctx, int ext_nid, + char *value); +X509_EXTENSION *X509V3_EXT_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *name, char *value); +int X509V3_EXT_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509 *cert); +int X509V3_EXT_REQ_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_REQ *req); +int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_CRL *crl); + +int X509V3_add_value_bool_nf(char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool); +int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint); +void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); +void X509V3_set_conf_lhash(X509V3_CTX *ctx, LHASH_OF(CONF_VALUE) *lhash); +# endif + +char *X509V3_get_string(X509V3_CTX *ctx, char *name, char *section); +STACK_OF(CONF_VALUE) *X509V3_get_section(X509V3_CTX *ctx, char *section); +void X509V3_string_free(X509V3_CTX *ctx, char *str); +void X509V3_section_free(X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section); +void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, + X509_REQ *req, X509_CRL *crl, int flags); + +int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); +char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint); +ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value); +char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint); +char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, + ASN1_ENUMERATED *aint); +int X509V3_EXT_add(X509V3_EXT_METHOD *ext); +int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); +int X509V3_EXT_add_alias(int nid_to, int nid_from); +void X509V3_EXT_cleanup(void); + +const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); +int X509V3_add_standard_extensions(void); +STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); +void *X509V3_EXT_d2i(X509_EXTENSION *ext); +void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, + int *idx); + +X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); +int X509V3_add1_i2d(STACK_OF(X509_EXTENSION) **x, int nid, void *value, + int crit, unsigned long flags); + +char *hex_to_string(const unsigned char *buffer, long len); +unsigned char *string_to_hex(const char *str, long *len); +int name_cmp(const char *name, const char *cmp); + +void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, + int ml); +int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, + int indent); +int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); + +int X509V3_extensions_print(BIO *out, char *title, + STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent); + +int X509_check_ca(X509 *x); +int X509_check_purpose(X509 *x, int id, int ca); +int X509_supported_extension(X509_EXTENSION *ex); +int X509_PURPOSE_set(int *p, int purpose); +int X509_check_issued(X509 *issuer, X509 *subject); +int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); +int X509_PURPOSE_get_count(void); +X509_PURPOSE *X509_PURPOSE_get0(int idx); +int X509_PURPOSE_get_by_sname(char *sname); +int X509_PURPOSE_get_by_id(int id); +int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck) (const X509_PURPOSE *, const X509 *, int), + char *name, char *sname, void *arg); +char *X509_PURPOSE_get0_name(X509_PURPOSE *xp); +char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp); +int X509_PURPOSE_get_trust(X509_PURPOSE *xp); +void X509_PURPOSE_cleanup(void); +int X509_PURPOSE_get_id(X509_PURPOSE *); + +STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); +STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); +void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); +STACK_OF(OPENSSL_STRING) *X509_get1_ocsp(X509 *x); + +ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); +ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); +int a2i_ipadd(unsigned char *ipout, const char *ipasc); +int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE) *dn_sk, + unsigned long chtype); + +void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); +DECLARE_STACK_OF(X509_POLICY_NODE) + +# ifndef OPENSSL_NO_RFC3779 + +typedef struct ASRange_st { + ASN1_INTEGER *min, *max; +} ASRange; + +# define ASIdOrRange_id 0 +# define ASIdOrRange_range 1 + +typedef struct ASIdOrRange_st { + int type; + union { + ASN1_INTEGER *id; + ASRange *range; + } u; +} ASIdOrRange; + +typedef STACK_OF(ASIdOrRange) ASIdOrRanges; +DECLARE_STACK_OF(ASIdOrRange) + +# define ASIdentifierChoice_inherit 0 +# define ASIdentifierChoice_asIdsOrRanges 1 + +typedef struct ASIdentifierChoice_st { + int type; + union { + ASN1_NULL *inherit; + ASIdOrRanges *asIdsOrRanges; + } u; +} ASIdentifierChoice; + +typedef struct ASIdentifiers_st { + ASIdentifierChoice *asnum, *rdi; +} ASIdentifiers; + +DECLARE_ASN1_FUNCTIONS(ASRange) +DECLARE_ASN1_FUNCTIONS(ASIdOrRange) +DECLARE_ASN1_FUNCTIONS(ASIdentifierChoice) +DECLARE_ASN1_FUNCTIONS(ASIdentifiers) + +typedef struct IPAddressRange_st { + ASN1_BIT_STRING *min, *max; +} IPAddressRange; + +# define IPAddressOrRange_addressPrefix 0 +# define IPAddressOrRange_addressRange 1 + +typedef struct IPAddressOrRange_st { + int type; + union { + ASN1_BIT_STRING *addressPrefix; + IPAddressRange *addressRange; + } u; +} IPAddressOrRange; + +typedef STACK_OF(IPAddressOrRange) IPAddressOrRanges; +DECLARE_STACK_OF(IPAddressOrRange) + +# define IPAddressChoice_inherit 0 +# define IPAddressChoice_addressesOrRanges 1 + +typedef struct IPAddressChoice_st { + int type; + union { + ASN1_NULL *inherit; + IPAddressOrRanges *addressesOrRanges; + } u; +} IPAddressChoice; + +typedef struct IPAddressFamily_st { + ASN1_OCTET_STRING *addressFamily; + IPAddressChoice *ipAddressChoice; +} IPAddressFamily; + +typedef STACK_OF(IPAddressFamily) IPAddrBlocks; +DECLARE_STACK_OF(IPAddressFamily) + +DECLARE_ASN1_FUNCTIONS(IPAddressRange) +DECLARE_ASN1_FUNCTIONS(IPAddressOrRange) +DECLARE_ASN1_FUNCTIONS(IPAddressChoice) +DECLARE_ASN1_FUNCTIONS(IPAddressFamily) + +/* + * API tag for elements of the ASIdentifer SEQUENCE. + */ +# define V3_ASID_ASNUM 0 +# define V3_ASID_RDI 1 + +/* + * AFI values, assigned by IANA. It'd be nice to make the AFI + * handling code totally generic, but there are too many little things + * that would need to be defined for other address families for it to + * be worth the trouble. + */ +# define IANA_AFI_IPV4 1 +# define IANA_AFI_IPV6 2 + +/* + * Utilities to construct and extract values from RFC3779 extensions, + * since some of the encodings (particularly for IP address prefixes + * and ranges) are a bit tedious to work with directly. + */ +int v3_asid_add_inherit(ASIdentifiers *asid, int which); +int v3_asid_add_id_or_range(ASIdentifiers *asid, int which, + ASN1_INTEGER *min, ASN1_INTEGER *max); +int v3_addr_add_inherit(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi); +int v3_addr_add_prefix(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi, + unsigned char *a, const int prefixlen); +int v3_addr_add_range(IPAddrBlocks *addr, + const unsigned afi, const unsigned *safi, + unsigned char *min, unsigned char *max); +unsigned v3_addr_get_afi(const IPAddressFamily *f); +int v3_addr_get_range(IPAddressOrRange *aor, const unsigned afi, + unsigned char *min, unsigned char *max, + const int length); + +/* + * Canonical forms. + */ +int v3_asid_is_canonical(ASIdentifiers *asid); +int v3_addr_is_canonical(IPAddrBlocks *addr); +int v3_asid_canonize(ASIdentifiers *asid); +int v3_addr_canonize(IPAddrBlocks *addr); + +/* + * Tests for inheritance and containment. + */ +int v3_asid_inherits(ASIdentifiers *asid); +int v3_addr_inherits(IPAddrBlocks *addr); +int v3_asid_subset(ASIdentifiers *a, ASIdentifiers *b); +int v3_addr_subset(IPAddrBlocks *a, IPAddrBlocks *b); + +/* + * Check whether RFC 3779 extensions nest properly in chains. + */ +int v3_asid_validate_path(X509_STORE_CTX *); +int v3_addr_validate_path(X509_STORE_CTX *); +int v3_asid_validate_resource_set(STACK_OF(X509) *chain, + ASIdentifiers *ext, int allow_inheritance); +int v3_addr_validate_resource_set(STACK_OF(X509) *chain, + IPAddrBlocks *ext, int allow_inheritance); + +# endif /* OPENSSL_NO_RFC3779 */ + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_X509V3_strings(void); + +/* Error codes for the X509V3 functions. */ + +/* Function codes. */ +# define X509V3_F_A2I_GENERAL_NAME 164 +# define X509V3_F_ASIDENTIFIERCHOICE_CANONIZE 161 +# define X509V3_F_ASIDENTIFIERCHOICE_IS_CANONICAL 162 +# define X509V3_F_COPY_EMAIL 122 +# define X509V3_F_COPY_ISSUER 123 +# define X509V3_F_DO_DIRNAME 144 +# define X509V3_F_DO_EXT_CONF 124 +# define X509V3_F_DO_EXT_I2D 135 +# define X509V3_F_DO_EXT_NCONF 151 +# define X509V3_F_DO_I2V_NAME_CONSTRAINTS 148 +# define X509V3_F_GNAMES_FROM_SECTNAME 156 +# define X509V3_F_HEX_TO_STRING 111 +# define X509V3_F_I2S_ASN1_ENUMERATED 121 +# define X509V3_F_I2S_ASN1_IA5STRING 149 +# define X509V3_F_I2S_ASN1_INTEGER 120 +# define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 138 +# define X509V3_F_NOTICE_SECTION 132 +# define X509V3_F_NREF_NOS 133 +# define X509V3_F_POLICY_SECTION 131 +# define X509V3_F_PROCESS_PCI_VALUE 150 +# define X509V3_F_R2I_CERTPOL 130 +# define X509V3_F_R2I_PCI 155 +# define X509V3_F_S2I_ASN1_IA5STRING 100 +# define X509V3_F_S2I_ASN1_INTEGER 108 +# define X509V3_F_S2I_ASN1_OCTET_STRING 112 +# define X509V3_F_S2I_ASN1_SKEY_ID 114 +# define X509V3_F_S2I_SKEY_ID 115 +# define X509V3_F_SET_DIST_POINT_NAME 158 +# define X509V3_F_STRING_TO_HEX 113 +# define X509V3_F_SXNET_ADD_ID_ASC 125 +# define X509V3_F_SXNET_ADD_ID_INTEGER 126 +# define X509V3_F_SXNET_ADD_ID_ULONG 127 +# define X509V3_F_SXNET_GET_ID_ASC 128 +# define X509V3_F_SXNET_GET_ID_ULONG 129 +# define X509V3_F_V2I_ASIDENTIFIERS 163 +# define X509V3_F_V2I_ASN1_BIT_STRING 101 +# define X509V3_F_V2I_AUTHORITY_INFO_ACCESS 139 +# define X509V3_F_V2I_AUTHORITY_KEYID 119 +# define X509V3_F_V2I_BASIC_CONSTRAINTS 102 +# define X509V3_F_V2I_CRLD 134 +# define X509V3_F_V2I_EXTENDED_KEY_USAGE 103 +# define X509V3_F_V2I_GENERAL_NAMES 118 +# define X509V3_F_V2I_GENERAL_NAME_EX 117 +# define X509V3_F_V2I_IDP 157 +# define X509V3_F_V2I_IPADDRBLOCKS 159 +# define X509V3_F_V2I_ISSUER_ALT 153 +# define X509V3_F_V2I_NAME_CONSTRAINTS 147 +# define X509V3_F_V2I_POLICY_CONSTRAINTS 146 +# define X509V3_F_V2I_POLICY_MAPPINGS 145 +# define X509V3_F_V2I_SUBJECT_ALT 154 +# define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL 160 +# define X509V3_F_V3_GENERIC_EXTENSION 116 +# define X509V3_F_X509V3_ADD1_I2D 140 +# define X509V3_F_X509V3_ADD_VALUE 105 +# define X509V3_F_X509V3_EXT_ADD 104 +# define X509V3_F_X509V3_EXT_ADD_ALIAS 106 +# define X509V3_F_X509V3_EXT_CONF 107 +# define X509V3_F_X509V3_EXT_I2D 136 +# define X509V3_F_X509V3_EXT_NCONF 152 +# define X509V3_F_X509V3_GET_SECTION 142 +# define X509V3_F_X509V3_GET_STRING 143 +# define X509V3_F_X509V3_GET_VALUE_BOOL 110 +# define X509V3_F_X509V3_PARSE_LIST 109 +# define X509V3_F_X509_PURPOSE_ADD 137 +# define X509V3_F_X509_PURPOSE_SET 141 + +/* Reason codes. */ +# define X509V3_R_BAD_IP_ADDRESS 118 +# define X509V3_R_BAD_OBJECT 119 +# define X509V3_R_BN_DEC2BN_ERROR 100 +# define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 101 +# define X509V3_R_DIRNAME_ERROR 149 +# define X509V3_R_DISTPOINT_ALREADY_SET 160 +# define X509V3_R_DUPLICATE_ZONE_ID 133 +# define X509V3_R_ERROR_CONVERTING_ZONE 131 +# define X509V3_R_ERROR_CREATING_EXTENSION 144 +# define X509V3_R_ERROR_IN_EXTENSION 128 +# define X509V3_R_EXPECTED_A_SECTION_NAME 137 +# define X509V3_R_EXTENSION_EXISTS 145 +# define X509V3_R_EXTENSION_NAME_ERROR 115 +# define X509V3_R_EXTENSION_NOT_FOUND 102 +# define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 103 +# define X509V3_R_EXTENSION_VALUE_ERROR 116 +# define X509V3_R_ILLEGAL_EMPTY_EXTENSION 151 +# define X509V3_R_ILLEGAL_HEX_DIGIT 113 +# define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 152 +# define X509V3_R_INVALID_MULTIPLE_RDNS 161 +# define X509V3_R_INVALID_ASNUMBER 162 +# define X509V3_R_INVALID_ASRANGE 163 +# define X509V3_R_INVALID_BOOLEAN_STRING 104 +# define X509V3_R_INVALID_EXTENSION_STRING 105 +# define X509V3_R_INVALID_INHERITANCE 165 +# define X509V3_R_INVALID_IPADDRESS 166 +# define X509V3_R_INVALID_NAME 106 +# define X509V3_R_INVALID_NULL_ARGUMENT 107 +# define X509V3_R_INVALID_NULL_NAME 108 +# define X509V3_R_INVALID_NULL_VALUE 109 +# define X509V3_R_INVALID_NUMBER 140 +# define X509V3_R_INVALID_NUMBERS 141 +# define X509V3_R_INVALID_OBJECT_IDENTIFIER 110 +# define X509V3_R_INVALID_OPTION 138 +# define X509V3_R_INVALID_POLICY_IDENTIFIER 134 +# define X509V3_R_INVALID_PROXY_POLICY_SETTING 153 +# define X509V3_R_INVALID_PURPOSE 146 +# define X509V3_R_INVALID_SAFI 164 +# define X509V3_R_INVALID_SECTION 135 +# define X509V3_R_INVALID_SYNTAX 143 +# define X509V3_R_ISSUER_DECODE_ERROR 126 +# define X509V3_R_MISSING_VALUE 124 +# define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 142 +# define X509V3_R_NO_CONFIG_DATABASE 136 +# define X509V3_R_NO_ISSUER_CERTIFICATE 121 +# define X509V3_R_NO_ISSUER_DETAILS 127 +# define X509V3_R_NO_POLICY_IDENTIFIER 139 +# define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 154 +# define X509V3_R_NO_PUBLIC_KEY 114 +# define X509V3_R_NO_SUBJECT_DETAILS 125 +# define X509V3_R_ODD_NUMBER_OF_DIGITS 112 +# define X509V3_R_OPERATION_NOT_DEFINED 148 +# define X509V3_R_OTHERNAME_ERROR 147 +# define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 155 +# define X509V3_R_POLICY_PATH_LENGTH 156 +# define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 157 +# define X509V3_R_POLICY_SYNTAX_NOT_CURRENTLY_SUPPORTED 158 +# define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 159 +# define X509V3_R_SECTION_NOT_FOUND 150 +# define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 122 +# define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 123 +# define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 111 +# define X509V3_R_UNKNOWN_EXTENSION 129 +# define X509V3_R_UNKNOWN_EXTENSION_NAME 130 +# define X509V3_R_UNKNOWN_OPTION 120 +# define X509V3_R_UNSUPPORTED_OPTION 117 +# define X509V3_R_UNSUPPORTED_TYPE 167 +# define X509V3_R_USER_TOO_LONG 132 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/crypto/x86_64cpuid.pl b/libs/openssl/crypto/x86_64cpuid.pl new file mode 100644 index 00000000..6ebfd017 --- /dev/null +++ b/libs/openssl/crypto/x86_64cpuid.pl @@ -0,0 +1,284 @@ +#!/usr/bin/env perl + +$flavour = shift; +$output = shift; +if ($flavour =~ /\./) { $output = $flavour; undef $flavour; } + +$win64=0; $win64=1 if ($flavour =~ /[nm]asm|mingw64/ || $output =~ /\.asm$/); + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +( $xlate="${dir}x86_64-xlate.pl" and -f $xlate ) or +( $xlate="${dir}perlasm/x86_64-xlate.pl" and -f $xlate) or +die "can't locate x86_64-xlate.pl"; + +open OUT,"| \"$^X\" $xlate $flavour $output"; +*STDOUT=*OUT; + +($arg1,$arg2,$arg3,$arg4)=$win64?("%rcx","%rdx","%r8", "%r9") : # Win64 order + ("%rdi","%rsi","%rdx","%rcx"); # Unix order + +print<<___; +.extern OPENSSL_cpuid_setup +.hidden OPENSSL_cpuid_setup +.section .init + call OPENSSL_cpuid_setup + +.hidden OPENSSL_ia32cap_P +.comm OPENSSL_ia32cap_P,8,4 + +.text + +.globl OPENSSL_atomic_add +.type OPENSSL_atomic_add,\@abi-omnipotent +.align 16 +OPENSSL_atomic_add: + movl ($arg1),%eax +.Lspin: leaq ($arg2,%rax),%r8 + .byte 0xf0 # lock + cmpxchgl %r8d,($arg1) + jne .Lspin + movl %r8d,%eax + .byte 0x48,0x98 # cltq/cdqe + ret +.size OPENSSL_atomic_add,.-OPENSSL_atomic_add + +.globl OPENSSL_rdtsc +.type OPENSSL_rdtsc,\@abi-omnipotent +.align 16 +OPENSSL_rdtsc: + rdtsc + shl \$32,%rdx + or %rdx,%rax + ret +.size OPENSSL_rdtsc,.-OPENSSL_rdtsc + +.globl OPENSSL_ia32_cpuid +.type OPENSSL_ia32_cpuid,\@abi-omnipotent +.align 16 +OPENSSL_ia32_cpuid: + mov %rbx,%r8 # save %rbx + + xor %eax,%eax + cpuid + mov %eax,%r11d # max value for standard query level + + xor %eax,%eax + cmp \$0x756e6547,%ebx # "Genu" + setne %al + mov %eax,%r9d + cmp \$0x49656e69,%edx # "ineI" + setne %al + or %eax,%r9d + cmp \$0x6c65746e,%ecx # "ntel" + setne %al + or %eax,%r9d # 0 indicates Intel CPU + jz .Lintel + + cmp \$0x68747541,%ebx # "Auth" + setne %al + mov %eax,%r10d + cmp \$0x69746E65,%edx # "enti" + setne %al + or %eax,%r10d + cmp \$0x444D4163,%ecx # "cAMD" + setne %al + or %eax,%r10d # 0 indicates AMD CPU + jnz .Lintel + + # AMD specific + mov \$0x80000000,%eax + cpuid + cmp \$0x80000001,%eax + jb .Lintel + mov %eax,%r10d + mov \$0x80000001,%eax + cpuid + or %ecx,%r9d + and \$0x00000801,%r9d # isolate AMD XOP bit, 1<<11 + + cmp \$0x80000008,%r10d + jb .Lintel + + mov \$0x80000008,%eax + cpuid + movzb %cl,%r10 # number of cores - 1 + inc %r10 # number of cores + + mov \$1,%eax + cpuid + bt \$28,%edx # test hyper-threading bit + jnc .Lgeneric + shr \$16,%ebx # number of logical processors + cmp %r10b,%bl + ja .Lgeneric + and \$0xefffffff,%edx # ~(1<<28) + jmp .Lgeneric + +.Lintel: + cmp \$4,%r11d + mov \$-1,%r10d + jb .Lnocacheinfo + + mov \$4,%eax + mov \$0,%ecx # query L1D + cpuid + mov %eax,%r10d + shr \$14,%r10d + and \$0xfff,%r10d # number of cores -1 per L1D + +.Lnocacheinfo: + mov \$1,%eax + cpuid + and \$0xbfefffff,%edx # force reserved bits to 0 + cmp \$0,%r9d + jne .Lnotintel + or \$0x40000000,%edx # set reserved bit#30 on Intel CPUs + and \$15,%ah + cmp \$15,%ah # examine Family ID + jne .Lnotintel + or \$0x00100000,%edx # set reserved bit#20 to engage RC4_CHAR +.Lnotintel: + bt \$28,%edx # test hyper-threading bit + jnc .Lgeneric + and \$0xefffffff,%edx # ~(1<<28) + cmp \$0,%r10d + je .Lgeneric + + or \$0x10000000,%edx # 1<<28 + shr \$16,%ebx + cmp \$1,%bl # see if cache is shared + ja .Lgeneric + and \$0xefffffff,%edx # ~(1<<28) +.Lgeneric: + and \$0x00000800,%r9d # isolate AMD XOP flag + and \$0xfffff7ff,%ecx + or %ecx,%r9d # merge AMD XOP flag + + mov %edx,%r10d # %r9d:%r10d is copy of %ecx:%edx + bt \$27,%r9d # check OSXSAVE bit + jnc .Lclear_avx + xor %ecx,%ecx # XCR0 + .byte 0x0f,0x01,0xd0 # xgetbv + and \$6,%eax # isolate XMM and YMM state support + cmp \$6,%eax + je .Ldone +.Lclear_avx: + mov \$0xefffe7ff,%eax # ~(1<<28|1<<12|1<<11) + and %eax,%r9d # clear AVX, FMA and AMD XOP bits +.Ldone: + shl \$32,%r9 + mov %r10d,%eax + mov %r8,%rbx # restore %rbx + or %r9,%rax + ret +.size OPENSSL_ia32_cpuid,.-OPENSSL_ia32_cpuid + +.globl OPENSSL_cleanse +.type OPENSSL_cleanse,\@abi-omnipotent +.align 16 +OPENSSL_cleanse: + xor %rax,%rax + cmp \$15,$arg2 + jae .Lot + cmp \$0,$arg2 + je .Lret +.Little: + mov %al,($arg1) + sub \$1,$arg2 + lea 1($arg1),$arg1 + jnz .Little +.Lret: + ret +.align 16 +.Lot: + test \$7,$arg1 + jz .Laligned + mov %al,($arg1) + lea -1($arg2),$arg2 + lea 1($arg1),$arg1 + jmp .Lot +.Laligned: + mov %rax,($arg1) + lea -8($arg2),$arg2 + test \$-8,$arg2 + lea 8($arg1),$arg1 + jnz .Laligned + cmp \$0,$arg2 + jne .Little + ret +.size OPENSSL_cleanse,.-OPENSSL_cleanse +___ + +print<<___ if (!$win64); +.globl OPENSSL_wipe_cpu +.type OPENSSL_wipe_cpu,\@abi-omnipotent +.align 16 +OPENSSL_wipe_cpu: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + pxor %xmm6,%xmm6 + pxor %xmm7,%xmm7 + pxor %xmm8,%xmm8 + pxor %xmm9,%xmm9 + pxor %xmm10,%xmm10 + pxor %xmm11,%xmm11 + pxor %xmm12,%xmm12 + pxor %xmm13,%xmm13 + pxor %xmm14,%xmm14 + pxor %xmm15,%xmm15 + xorq %rcx,%rcx + xorq %rdx,%rdx + xorq %rsi,%rsi + xorq %rdi,%rdi + xorq %r8,%r8 + xorq %r9,%r9 + xorq %r10,%r10 + xorq %r11,%r11 + leaq 8(%rsp),%rax + ret +.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu +___ +print<<___ if ($win64); +.globl OPENSSL_wipe_cpu +.type OPENSSL_wipe_cpu,\@abi-omnipotent +.align 16 +OPENSSL_wipe_cpu: + pxor %xmm0,%xmm0 + pxor %xmm1,%xmm1 + pxor %xmm2,%xmm2 + pxor %xmm3,%xmm3 + pxor %xmm4,%xmm4 + pxor %xmm5,%xmm5 + xorq %rcx,%rcx + xorq %rdx,%rdx + xorq %r8,%r8 + xorq %r9,%r9 + xorq %r10,%r10 + xorq %r11,%r11 + leaq 8(%rsp),%rax + ret +.size OPENSSL_wipe_cpu,.-OPENSSL_wipe_cpu +___ + +print<<___; +.globl OPENSSL_ia32_rdrand +.type OPENSSL_ia32_rdrand,\@abi-omnipotent +.align 16 +OPENSSL_ia32_rdrand: + mov \$8,%ecx +.Loop_rdrand: + rdrand %rax + jc .Lbreak_rdrand + loop .Loop_rdrand +.Lbreak_rdrand: + cmp \$0,%rax + cmove %rcx,%rax + ret +.size OPENSSL_ia32_rdrand,.-OPENSSL_ia32_rdrand +___ + +close STDOUT; # flush diff --git a/libs/openssl/crypto/x86cpuid.pl b/libs/openssl/crypto/x86cpuid.pl new file mode 100644 index 00000000..b270b443 --- /dev/null +++ b/libs/openssl/crypto/x86cpuid.pl @@ -0,0 +1,358 @@ +#!/usr/bin/env perl + +$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1; +push(@INC, "${dir}perlasm", "perlasm"); +require "x86asm.pl"; + +&asm_init($ARGV[0],"x86cpuid"); + +for (@ARGV) { $sse2=1 if (/-DOPENSSL_IA32_SSE2/); } + +&function_begin("OPENSSL_ia32_cpuid"); + &xor ("edx","edx"); + &pushf (); + &pop ("eax"); + &mov ("ecx","eax"); + &xor ("eax",1<<21); + &push ("eax"); + &popf (); + &pushf (); + &pop ("eax"); + &xor ("ecx","eax"); + &xor ("eax","eax"); + &bt ("ecx",21); + &jnc (&label("nocpuid")); + &cpuid (); + &mov ("edi","eax"); # max value for standard query level + + &xor ("eax","eax"); + &cmp ("ebx",0x756e6547); # "Genu" + &setne (&LB("eax")); + &mov ("ebp","eax"); + &cmp ("edx",0x49656e69); # "ineI" + &setne (&LB("eax")); + &or ("ebp","eax"); + &cmp ("ecx",0x6c65746e); # "ntel" + &setne (&LB("eax")); + &or ("ebp","eax"); # 0 indicates Intel CPU + &jz (&label("intel")); + + &cmp ("ebx",0x68747541); # "Auth" + &setne (&LB("eax")); + &mov ("esi","eax"); + &cmp ("edx",0x69746E65); # "enti" + &setne (&LB("eax")); + &or ("esi","eax"); + &cmp ("ecx",0x444D4163); # "cAMD" + &setne (&LB("eax")); + &or ("esi","eax"); # 0 indicates AMD CPU + &jnz (&label("intel")); + + # AMD specific + &mov ("eax",0x80000000); + &cpuid (); + &cmp ("eax",0x80000001); + &jb (&label("intel")); + &mov ("esi","eax"); + &mov ("eax",0x80000001); + &cpuid (); + &or ("ebp","ecx"); + &and ("ebp",1<<11|1); # isolate XOP bit + &cmp ("esi",0x80000008); + &jb (&label("intel")); + + &mov ("eax",0x80000008); + &cpuid (); + &movz ("esi",&LB("ecx")); # number of cores - 1 + &inc ("esi"); # number of cores + + &mov ("eax",1); + &xor ("ecx","ecx"); + &cpuid (); + &bt ("edx",28); + &jnc (&label("generic")); + &shr ("ebx",16); + &and ("ebx",0xff); + &cmp ("ebx","esi"); + &ja (&label("generic")); + &and ("edx",0xefffffff); # clear hyper-threading bit + &jmp (&label("generic")); + +&set_label("intel"); + &cmp ("edi",4); + &mov ("edi",-1); + &jb (&label("nocacheinfo")); + + &mov ("eax",4); + &mov ("ecx",0); # query L1D + &cpuid (); + &mov ("edi","eax"); + &shr ("edi",14); + &and ("edi",0xfff); # number of cores -1 per L1D + +&set_label("nocacheinfo"); + &mov ("eax",1); + &xor ("ecx","ecx"); + &cpuid (); + &and ("edx",0xbfefffff); # force reserved bits #20, #30 to 0 + &cmp ("ebp",0); + &jne (&label("notintel")); + &or ("edx",1<<30); # set reserved bit#30 on Intel CPUs + &and (&HB("eax"),15); # familiy ID + &cmp (&HB("eax"),15); # P4? + &jne (&label("notintel")); + &or ("edx",1<<20); # set reserved bit#20 to engage RC4_CHAR +&set_label("notintel"); + &bt ("edx",28); # test hyper-threading bit + &jnc (&label("generic")); + &and ("edx",0xefffffff); + &cmp ("edi",0); + &je (&label("generic")); + + &or ("edx",0x10000000); + &shr ("ebx",16); + &cmp (&LB("ebx"),1); + &ja (&label("generic")); + &and ("edx",0xefffffff); # clear hyper-threading bit if not + +&set_label("generic"); + &and ("ebp",1<<11); # isolate AMD XOP flag + &and ("ecx",0xfffff7ff); # force 11th bit to 0 + &mov ("esi","edx"); + &or ("ebp","ecx"); # merge AMD XOP flag + + &bt ("ecx",27); # check OSXSAVE bit + &jnc (&label("clear_avx")); + &xor ("ecx","ecx"); + &data_byte(0x0f,0x01,0xd0); # xgetbv + &and ("eax",6); + &cmp ("eax",6); + &je (&label("done")); + &cmp ("eax",2); + &je (&label("clear_avx")); +&set_label("clear_xmm"); + &and ("ebp",0xfdfffffd); # clear AESNI and PCLMULQDQ bits + &and ("esi",0xfeffffff); # clear FXSR +&set_label("clear_avx"); + &and ("ebp",0xefffe7ff); # clear AVX, FMA and AMD XOP bits +&set_label("done"); + &mov ("eax","esi"); + &mov ("edx","ebp"); +&set_label("nocpuid"); +&function_end("OPENSSL_ia32_cpuid"); + +&external_label("OPENSSL_ia32cap_P"); + +&function_begin_B("OPENSSL_rdtsc","EXTRN\t_OPENSSL_ia32cap_P:DWORD"); + &xor ("eax","eax"); + &xor ("edx","edx"); + &picmeup("ecx","OPENSSL_ia32cap_P"); + &bt (&DWP(0,"ecx"),4); + &jnc (&label("notsc")); + &rdtsc (); +&set_label("notsc"); + &ret (); +&function_end_B("OPENSSL_rdtsc"); + +# This works in Ring 0 only [read DJGPP+MS-DOS+privileged DPMI host], +# but it's safe to call it on any [supported] 32-bit platform... +# Just check for [non-]zero return value... +&function_begin_B("OPENSSL_instrument_halt","EXTRN\t_OPENSSL_ia32cap_P:DWORD"); + &picmeup("ecx","OPENSSL_ia32cap_P"); + &bt (&DWP(0,"ecx"),4); + &jnc (&label("nohalt")); # no TSC + + &data_word(0x9058900e); # push %cs; pop %eax + &and ("eax",3); + &jnz (&label("nohalt")); # not enough privileges + + &pushf (); + &pop ("eax"); + &bt ("eax",9); + &jnc (&label("nohalt")); # interrupts are disabled + + &rdtsc (); + &push ("edx"); + &push ("eax"); + &halt (); + &rdtsc (); + + &sub ("eax",&DWP(0,"esp")); + &sbb ("edx",&DWP(4,"esp")); + &add ("esp",8); + &ret (); + +&set_label("nohalt"); + &xor ("eax","eax"); + &xor ("edx","edx"); + &ret (); +&function_end_B("OPENSSL_instrument_halt"); + +# Essentially there is only one use for this function. Under DJGPP: +# +# #include +# ... +# i=OPENSSL_far_spin(_dos_ds,0x46c); +# ... +# to obtain the number of spins till closest timer interrupt. + +&function_begin_B("OPENSSL_far_spin"); + &pushf (); + &pop ("eax") + &bt ("eax",9); + &jnc (&label("nospin")); # interrupts are disabled + + &mov ("eax",&DWP(4,"esp")); + &mov ("ecx",&DWP(8,"esp")); + &data_word (0x90d88e1e); # push %ds, mov %eax,%ds + &xor ("eax","eax"); + &mov ("edx",&DWP(0,"ecx")); + &jmp (&label("spin")); + + &align (16); +&set_label("spin"); + &inc ("eax"); + &cmp ("edx",&DWP(0,"ecx")); + &je (&label("spin")); + + &data_word (0x1f909090); # pop %ds + &ret (); + +&set_label("nospin"); + &xor ("eax","eax"); + &xor ("edx","edx"); + &ret (); +&function_end_B("OPENSSL_far_spin"); + +&function_begin_B("OPENSSL_wipe_cpu","EXTRN\t_OPENSSL_ia32cap_P:DWORD"); + &xor ("eax","eax"); + &xor ("edx","edx"); + &picmeup("ecx","OPENSSL_ia32cap_P"); + &mov ("ecx",&DWP(0,"ecx")); + &bt (&DWP(0,"ecx"),1); + &jnc (&label("no_x87")); + if ($sse2) { + &and ("ecx",1<<26|1<<24); # check SSE2 and FXSR bits + &cmp ("ecx",1<<26|1<<24); + &jne (&label("no_sse2")); + &pxor ("xmm0","xmm0"); + &pxor ("xmm1","xmm1"); + &pxor ("xmm2","xmm2"); + &pxor ("xmm3","xmm3"); + &pxor ("xmm4","xmm4"); + &pxor ("xmm5","xmm5"); + &pxor ("xmm6","xmm6"); + &pxor ("xmm7","xmm7"); + &set_label("no_sse2"); + } + # just a bunch of fldz to zap the fp/mm bank followed by finit... + &data_word(0xeed9eed9,0xeed9eed9,0xeed9eed9,0xeed9eed9,0x90e3db9b); +&set_label("no_x87"); + &lea ("eax",&DWP(4,"esp")); + &ret (); +&function_end_B("OPENSSL_wipe_cpu"); + +&function_begin_B("OPENSSL_atomic_add"); + &mov ("edx",&DWP(4,"esp")); # fetch the pointer, 1st arg + &mov ("ecx",&DWP(8,"esp")); # fetch the increment, 2nd arg + &push ("ebx"); + &nop (); + &mov ("eax",&DWP(0,"edx")); +&set_label("spin"); + &lea ("ebx",&DWP(0,"eax","ecx")); + &nop (); + &data_word(0x1ab10ff0); # lock; cmpxchg %ebx,(%edx) # %eax is envolved and is always reloaded + &jne (&label("spin")); + &mov ("eax","ebx"); # OpenSSL expects the new value + &pop ("ebx"); + &ret (); +&function_end_B("OPENSSL_atomic_add"); + +# This function can become handy under Win32 in situations when +# we don't know which calling convention, __stdcall or __cdecl(*), +# indirect callee is using. In C it can be deployed as +# +#ifdef OPENSSL_CPUID_OBJ +# type OPENSSL_indirect_call(void *f,...); +# ... +# OPENSSL_indirect_call(func,[up to $max arguments]); +#endif +# +# (*) it's designed to work even for __fastcall if number of +# arguments is 1 or 2! +&function_begin_B("OPENSSL_indirect_call"); + { + my ($max,$i)=(7,); # $max has to be chosen as 4*n-1 + # in order to preserve eventual + # stack alignment + &push ("ebp"); + &mov ("ebp","esp"); + &sub ("esp",$max*4); + &mov ("ecx",&DWP(12,"ebp")); + &mov (&DWP(0,"esp"),"ecx"); + &mov ("edx",&DWP(16,"ebp")); + &mov (&DWP(4,"esp"),"edx"); + for($i=2;$i<$max;$i++) + { + # Some copies will be redundant/bogus... + &mov ("eax",&DWP(12+$i*4,"ebp")); + &mov (&DWP(0+$i*4,"esp"),"eax"); + } + &call_ptr (&DWP(8,"ebp"));# make the call... + &mov ("esp","ebp"); # ... and just restore the stack pointer + # without paying attention to what we called, + # (__cdecl *func) or (__stdcall *one). + &pop ("ebp"); + &ret (); + } +&function_end_B("OPENSSL_indirect_call"); + +&function_begin_B("OPENSSL_cleanse"); + &mov ("edx",&wparam(0)); + &mov ("ecx",&wparam(1)); + &xor ("eax","eax"); + &cmp ("ecx",7); + &jae (&label("lot")); + &cmp ("ecx",0); + &je (&label("ret")); +&set_label("little"); + &mov (&BP(0,"edx"),"al"); + &sub ("ecx",1); + &lea ("edx",&DWP(1,"edx")); + &jnz (&label("little")); +&set_label("ret"); + &ret (); + +&set_label("lot",16); + &test ("edx",3); + &jz (&label("aligned")); + &mov (&BP(0,"edx"),"al"); + &lea ("ecx",&DWP(-1,"ecx")); + &lea ("edx",&DWP(1,"edx")); + &jmp (&label("lot")); +&set_label("aligned"); + &mov (&DWP(0,"edx"),"eax"); + &lea ("ecx",&DWP(-4,"ecx")); + &test ("ecx",-4); + &lea ("edx",&DWP(4,"edx")); + &jnz (&label("aligned")); + &cmp ("ecx",0); + &jne (&label("little")); + &ret (); +&function_end_B("OPENSSL_cleanse"); + +&function_begin_B("OPENSSL_ia32_rdrand"); + &mov ("ecx",8); +&set_label("loop"); + &rdrand ("eax"); + &jc (&label("break")); + &loop (&label("loop")); +&set_label("break"); + &cmp ("eax",0); + &cmove ("eax","ecx"); + &ret (); +&function_end_B("OPENSSL_ia32_rdrand"); + +&initseg("OPENSSL_cpuid_setup"); + +&asm_finish(); diff --git a/libs/openssl/e_os.h b/libs/openssl/e_os.h new file mode 100644 index 00000000..76c471e3 --- /dev/null +++ b/libs/openssl/e_os.h @@ -0,0 +1,775 @@ +/* e_os.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_E_OS_H +# define HEADER_E_OS_H + +# include + +# include +/* + * contains what we can justify to make visible to the + * outside; this file e_os.h is not part of the exported interface. + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Used to checking reference counts, most while doing perl5 stuff :-) */ +# ifdef REF_PRINT +# undef REF_PRINT +# define REF_PRINT(a,b) fprintf(stderr,"%08X:%4d:%s\n",(int)b,b->references,a) +# endif + +# ifndef DEVRANDOM +/* + * set this to a comma-separated list of 'random' device files to try out. My + * default, we will try to read at least one of these files + */ +# define DEVRANDOM "/dev/urandom","/dev/random","/dev/srandom" +# endif +# ifndef DEVRANDOM_EGD +/* + * set this to a comma-seperated list of 'egd' sockets to try out. These + * sockets will be tried in the order listed in case accessing the device + * files listed in DEVRANDOM did not return enough entropy. + */ +# define DEVRANDOM_EGD "/var/run/egd-pool","/dev/egd-pool","/etc/egd-pool","/etc/entropy" +# endif + +# if defined(OPENSSL_SYS_VXWORKS) +# define NO_SYS_PARAM_H +# define NO_CHMOD +# define NO_SYSLOG +# endif + +# if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) +# if macintosh==1 +# ifndef MAC_OS_GUSI_SOURCE +# define MAC_OS_pre_X +# define NO_SYS_TYPES_H +# endif +# define NO_SYS_PARAM_H +# define NO_CHMOD +# define NO_SYSLOG +# undef DEVRANDOM +# define GETPID_IS_MEANINGLESS +# endif +# endif + +/******************************************************************** + The Microsoft section + ********************************************************************/ +/* + * The following is used because of the small stack in some Microsoft + * operating systems + */ +# if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYSNAME_WIN32) +# define MS_STATIC static +# else +# define MS_STATIC +# endif + +# if defined(OPENSSL_SYS_WIN32) && !defined(WIN32) +# define WIN32 +# endif +# if defined(OPENSSL_SYS_WINDOWS) && !defined(WINDOWS) +# define WINDOWS +# endif +# if defined(OPENSSL_SYS_MSDOS) && !defined(MSDOS) +# define MSDOS +# endif + +# if defined(MSDOS) && !defined(GETPID_IS_MEANINGLESS) +# define GETPID_IS_MEANINGLESS +# endif + +# ifdef WIN32 +# define get_last_sys_error() GetLastError() +# define clear_sys_error() SetLastError(0) +# if !defined(WINNT) +# define WIN_CONSOLE_BUG +# endif +# else +# define get_last_sys_error() errno +# define clear_sys_error() errno=0 +# endif + +# if defined(WINDOWS) +# define get_last_socket_error() WSAGetLastError() +# define clear_socket_error() WSASetLastError(0) +# define readsocket(s,b,n) recv((s),(b),(n),0) +# define writesocket(s,b,n) send((s),(b),(n),0) +# elif defined(__DJGPP__) +# define WATT32 +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define closesocket(s) close_s(s) +# define readsocket(s,b,n) read_s(s,b,n) +# define writesocket(s,b,n) send(s,b,n,0) +# elif defined(MAC_OS_pre_X) +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define closesocket(s) MacSocket_close(s) +# define readsocket(s,b,n) MacSocket_recv((s),(b),(n),true) +# define writesocket(s,b,n) MacSocket_send((s),(b),(n)) +# elif defined(OPENSSL_SYS_VMS) +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define ioctlsocket(a,b,c) ioctl(a,b,c) +# define closesocket(s) close(s) +# define readsocket(s,b,n) recv((s),(b),(n),0) +# define writesocket(s,b,n) send((s),(b),(n),0) +# elif defined(OPENSSL_SYS_VXWORKS) +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define ioctlsocket(a,b,c) ioctl((a),(b),(int)(c)) +# define closesocket(s) close(s) +# define readsocket(s,b,n) read((s),(b),(n)) +# define writesocket(s,b,n) write((s),(char *)(b),(n)) +# elif defined(OPENSSL_SYS_BEOS_R5) +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define FIONBIO SO_NONBLOCK +# define ioctlsocket(a,b,c) setsockopt((a),SOL_SOCKET,(b),(c),sizeof(*(c))) +# define readsocket(s,b,n) recv((s),(b),(n),0) +# define writesocket(s,b,n) send((s),(b),(n),0) +# elif defined(OPENSSL_SYS_NETWARE) +# if defined(NETWARE_BSDSOCK) +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define closesocket(s) close(s) +# define ioctlsocket(a,b,c) ioctl(a,b,c) +# if defined(NETWARE_LIBC) +# define readsocket(s,b,n) recv((s),(b),(n),0) +# define writesocket(s,b,n) send((s),(b),(n),0) +# else +# define readsocket(s,b,n) recv((s),(char*)(b),(n),0) +# define writesocket(s,b,n) send((s),(char*)(b),(n),0) +# endif +# else +# define get_last_socket_error() WSAGetLastError() +# define clear_socket_error() WSASetLastError(0) +# define readsocket(s,b,n) recv((s),(b),(n),0) +# define writesocket(s,b,n) send((s),(b),(n),0) +# endif +# else +# define get_last_socket_error() errno +# define clear_socket_error() errno=0 +# define ioctlsocket(a,b,c) ioctl(a,b,c) +# define closesocket(s) close(s) +# define readsocket(s,b,n) read((s),(b),(n)) +# define writesocket(s,b,n) write((s),(b),(n)) +# endif + +# ifdef WIN16 /* never the case */ +# define MS_CALLBACK _far _loadds +# define MS_FAR _far +# else +# define MS_CALLBACK +# define MS_FAR +# endif + +# ifdef OPENSSL_NO_STDIO +# undef OPENSSL_NO_FP_API +# define OPENSSL_NO_FP_API +# endif + +# if (defined(WINDOWS) || defined(MSDOS)) + +# ifdef __DJGPP__ +# include +# include +# include +# include +# include +# define _setmode setmode +# define _O_TEXT O_TEXT +# define _O_BINARY O_BINARY +# undef DEVRANDOM +# define DEVRANDOM "/dev/urandom\x24" +# endif /* __DJGPP__ */ + +# ifndef S_IFDIR +# define S_IFDIR _S_IFDIR +# endif + +# ifndef S_IFMT +# define S_IFMT _S_IFMT +# endif + +# if !defined(WINNT) && !defined(__DJGPP__) +# define NO_SYSLOG +# endif +# define NO_DIRENT + +# ifdef WINDOWS +# if !defined(_WIN32_WCE) && !defined(_WIN32_WINNT) + /* + * Defining _WIN32_WINNT here in e_os.h implies certain "discipline." + * Most notably we ought to check for availability of each specific + * routine with GetProcAddress() and/or guard NT-specific calls with + * GetVersion() < 0x80000000. One can argue that in latter "or" case + * we ought to /DELAYLOAD some .DLLs in order to protect ourselves + * against run-time link errors. This doesn't seem to be necessary, + * because it turned out that already Windows 95, first non-NT Win32 + * implementation, is equipped with at least NT 3.51 stubs, dummy + * routines with same name, but which do nothing. Meaning that it's + * apparently sufficient to guard "vanilla" NT calls with GetVersion + * alone, while NT 4.0 and above interfaces ought to be linked with + * GetProcAddress at run-time. + */ +# define _WIN32_WINNT 0x0400 +# endif +# if !defined(OPENSSL_NO_SOCK) && defined(_WIN32_WINNT) + /* + * Just like defining _WIN32_WINNT including winsock2.h implies + * certain "discipline" for maintaining [broad] binary compatibility. + * As long as structures are invariant among Winsock versions, + * it's sufficient to check for specific Winsock2 API availability + * at run-time [DSO_global_lookup is recommended]... + */ +# include +# include + /* yes, they have to be #included prior to */ +# endif +# include +# include +# include +# include +# include +# ifdef _WIN64 +# define strlen(s) _strlen31(s) +/* cut strings to 2GB */ +static __inline unsigned int _strlen31(const char *str) +{ + unsigned int len = 0; + while (*str && len < 0x80000000U) + str++, len++; + return len & 0x7FFFFFFF; +} +# endif +# include +# if defined(_MSC_VER) && _MSC_VER<=1200 && defined(_MT) && defined(isspace) + /* compensate for bug in VC6 ctype.h */ +# undef isspace +# undef isdigit +# undef isalnum +# undef isupper +# undef isxdigit +# endif +# if defined(_MSC_VER) && !defined(_DLL) && defined(stdin) +# if _MSC_VER>=1300 && _MSC_VER<1600 +# undef stdin +# undef stdout +# undef stderr +FILE *__iob_func(); +# define stdin (&__iob_func()[0]) +# define stdout (&__iob_func()[1]) +# define stderr (&__iob_func()[2]) +# elif _MSC_VER<1300 && defined(I_CAN_LIVE_WITH_LNK4049) +# undef stdin +# undef stdout +# undef stderr + /* + * pre-1300 has __p__iob(), but it's available only in msvcrt.lib, + * or in other words with /MD. Declaring implicit import, i.e. with + * _imp_ prefix, works correctly with all compiler options, but + * without /MD results in LINK warning LNK4049: 'locally defined + * symbol "__iob" imported'. + */ +extern FILE *_imp___iob; +# define stdin (&_imp___iob[0]) +# define stdout (&_imp___iob[1]) +# define stderr (&_imp___iob[2]) +# endif +# endif +# endif +# include +# include + +# ifdef OPENSSL_SYS_WINCE +# define OPENSSL_NO_POSIX_IO +# endif + +# if defined (__BORLANDC__) +# define _setmode setmode +# define _O_TEXT O_TEXT +# define _O_BINARY O_BINARY +# define _int64 __int64 +# define _kbhit kbhit +# endif + +# define EXIT(n) exit(n) +# define LIST_SEPARATOR_CHAR ';' +# ifndef X_OK +# define X_OK 0 +# endif +# ifndef W_OK +# define W_OK 2 +# endif +# ifndef R_OK +# define R_OK 4 +# endif +# define OPENSSL_CONF "openssl.cnf" +# define SSLEAY_CONF OPENSSL_CONF +# define NUL_DEV "nul" +# define RFILE ".rnd" +# ifdef OPENSSL_SYS_WINCE +# define DEFAULT_HOME "" +# else +# define DEFAULT_HOME "C:" +# endif + +/* Avoid Visual Studio 13 GetVersion deprecated problems */ +# if defined(_MSC_VER) && _MSC_VER>=1800 +# define check_winnt() (1) +# define check_win_minplat(x) (1) +# else +# define check_winnt() (GetVersion() < 0x80000000) +# define check_win_minplat(x) (LOBYTE(LOWORD(GetVersion())) >= (x)) +# endif + +# else /* The non-microsoft world */ + +# ifdef OPENSSL_SYS_VMS +# define VMS 1 + /* + * some programs don't include stdlib, so exit() and others give implicit + * function warnings + */ +# include +# if defined(__DECC) +# include +# else +# include +# endif +# define OPENSSL_CONF "openssl.cnf" +# define SSLEAY_CONF OPENSSL_CONF +# define RFILE ".rnd" +# define LIST_SEPARATOR_CHAR ',' +# define NUL_DEV "NLA0:" + /* We don't have any well-defined random devices on VMS, yet... */ +# undef DEVRANDOM + /*- + We need to do this since VMS has the following coding on status codes: + + Bits 0-2: status type: 0 = warning, 1 = success, 2 = error, 3 = info ... + The important thing to know is that odd numbers are considered + good, while even ones are considered errors. + Bits 3-15: actual status number + Bits 16-27: facility number. 0 is considered "unknown" + Bits 28-31: control bits. If bit 28 is set, the shell won't try to + output the message (which, for random codes, just looks ugly) + + So, what we do here is to change 0 to 1 to get the default success status, + and everything else is shifted up to fit into the status number field, and + the status is tagged as an error, which I believe is what is wanted here. + -- Richard Levitte + */ +# define EXIT(n) do { int __VMS_EXIT = n; \ + if (__VMS_EXIT == 0) \ + __VMS_EXIT = 1; \ + else \ + __VMS_EXIT = (n << 3) | 2; \ + __VMS_EXIT |= 0x10000000; \ + exit(__VMS_EXIT); } while(0) +# define NO_SYS_PARAM_H + +# elif defined(OPENSSL_SYS_NETWARE) +# include +# include +# define NO_SYS_TYPES_H +# undef DEVRANDOM +# ifdef NETWARE_CLIB +# define getpid GetThreadID +extern int GetThreadID(void); +/* # include */ +extern int kbhit(void); +# else +# include +# endif +# define NO_SYSLOG +# define _setmode setmode +# define _kbhit kbhit +# define _O_TEXT O_TEXT +# define _O_BINARY O_BINARY +# define OPENSSL_CONF "openssl.cnf" +# define SSLEAY_CONF OPENSSL_CONF +# define RFILE ".rnd" +# define LIST_SEPARATOR_CHAR ';' +# define EXIT(n) { if (n) printf("ERROR: %d\n", (int)n); exit(n); } + +# else + /* !defined VMS */ +# ifdef OPENSSL_SYS_MPE +# define NO_SYS_PARAM_H +# endif +# ifdef OPENSSL_UNISTD +# include OPENSSL_UNISTD +# else +# include +# endif +# ifndef NO_SYS_TYPES_H +# include +# endif +# if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) +# define pid_t int /* pid_t is missing on NEXTSTEP/OPENSTEP + * (unless when compiling with + * -D_POSIX_SOURCE, which doesn't work for + * us) */ +# endif +# ifdef OPENSSL_SYS_NEWS4 /* setvbuf is missing on mips-sony-bsd */ +# define setvbuf(a, b, c, d) setbuffer((a), (b), (d)) +typedef unsigned long clock_t; +# endif +# ifdef OPENSSL_SYS_WIN32_CYGWIN +# include +# include +# endif + +# define OPENSSL_CONF "openssl.cnf" +# define SSLEAY_CONF OPENSSL_CONF +# define RFILE ".rnd" +# define LIST_SEPARATOR_CHAR ':' +# define NUL_DEV "/dev/null" +# define EXIT(n) exit(n) +# endif + +# define SSLeay_getpid() getpid() + +# endif + +/*************/ + +# ifdef USE_SOCKETS +# if defined(WINDOWS) || defined(MSDOS) + /* windows world */ + +# ifdef OPENSSL_NO_SOCK +# define SSLeay_Write(a,b,c) (-1) +# define SSLeay_Read(a,b,c) (-1) +# define SHUTDOWN(fd) close(fd) +# define SHUTDOWN2(fd) close(fd) +# elif !defined(__DJGPP__) +# if defined(_WIN32_WCE) && _WIN32_WCE<410 +# define getservbyname _masked_declaration_getservbyname +# endif +# if !defined(IPPROTO_IP) + /* winsock[2].h was included already? */ +# include +# endif +# ifdef getservbyname +# undef getservbyname + /* this is used to be wcecompat/include/winsock_extras.h */ +struct servent *PASCAL getservbyname(const char *, const char *); +# endif + +# ifdef _WIN64 +/* + * Even though sizeof(SOCKET) is 8, it's safe to cast it to int, because + * the value constitutes an index in per-process table of limited size + * and not a real pointer. + */ +# define socket(d,t,p) ((int)socket(d,t,p)) +# define accept(s,f,l) ((int)accept(s,f,l)) +# endif +# define SSLeay_Write(a,b,c) send((a),(b),(c),0) +# define SSLeay_Read(a,b,c) recv((a),(b),(c),0) +# define SHUTDOWN(fd) { shutdown((fd),0); closesocket(fd); } +# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket(fd); } +# else +# define SSLeay_Write(a,b,c) write_s(a,b,c,0) +# define SSLeay_Read(a,b,c) read_s(a,b,c) +# define SHUTDOWN(fd) close_s(fd) +# define SHUTDOWN2(fd) close_s(fd) +# endif + +# elif defined(MAC_OS_pre_X) + +# include "MacSocket.h" +# define SSLeay_Write(a,b,c) MacSocket_send((a),(b),(c)) +# define SSLeay_Read(a,b,c) MacSocket_recv((a),(b),(c),true) +# define SHUTDOWN(fd) MacSocket_close(fd) +# define SHUTDOWN2(fd) MacSocket_close(fd) + +# elif defined(OPENSSL_SYS_NETWARE) + /* + * NetWare uses the WinSock2 interfaces by default, but can be + * configured for BSD + */ +# if defined(NETWARE_BSDSOCK) +# include +# include +# include +# if defined(NETWARE_CLIB) +# include +# else +# include +# endif +# define INVALID_SOCKET (int)(~0) +# else +# include +# endif +# define SSLeay_Write(a,b,c) send((a),(b),(c),0) +# define SSLeay_Read(a,b,c) recv((a),(b),(c),0) +# define SHUTDOWN(fd) { shutdown((fd),0); closesocket(fd); } +# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket(fd); } + +# else + +# ifndef NO_SYS_PARAM_H +# include +# endif +# ifdef OPENSSL_SYS_VXWORKS +# include +# elif !defined(OPENSSL_SYS_MPE) +# include /* Needed under linux for FD_XXX */ +# endif + +# include +# if defined(OPENSSL_SYS_VMS_NODECC) +# include +# include +# include +# else +# include +# ifdef FILIO_H +# include /* Added for FIONBIO under unixware */ +# endif +# include +# if !defined(OPENSSL_SYS_BEOS_R5) +# include +# endif +# endif + +# if defined(NeXT) || defined(_NEXT_SOURCE) +# include +# include +# endif + +# ifdef OPENSSL_SYS_AIX +# include +# endif + +# ifdef __QNX__ +# include +# endif + +# if defined(__sun) || defined(sun) +# include +# else +# ifndef VMS +# include +# else + /* ioctl is only in VMS > 7.0 and when socketshr is not used */ +# if !defined(TCPIP_TYPE_SOCKETSHR) && defined(__VMS_VER) && (__VMS_VER > 70000000) +# include +# endif +# endif +# endif + +# ifdef VMS +# include +# if defined(TCPIP_TYPE_SOCKETSHR) +# include +# endif +# endif + +# define SSLeay_Read(a,b,c) read((a),(b),(c)) +# define SSLeay_Write(a,b,c) write((a),(b),(c)) +# define SHUTDOWN(fd) { shutdown((fd),0); closesocket((fd)); } +# define SHUTDOWN2(fd) { shutdown((fd),2); closesocket((fd)); } +# ifndef INVALID_SOCKET +# define INVALID_SOCKET (-1) +# endif /* INVALID_SOCKET */ +# endif + +/* + * Some IPv6 implementations are broken, disable them in known bad versions. + */ +# if !defined(OPENSSL_USE_IPV6) +# if defined(AF_INET6) && !defined(OPENSSL_SYS_BEOS_BONE) && !defined(NETWARE_CLIB) +# define OPENSSL_USE_IPV6 1 +# else +# define OPENSSL_USE_IPV6 0 +# endif +# endif + +# endif + +# if (defined(__sun) || defined(sun)) && !defined(__svr4__) && !defined(__SVR4) + /* include headers first, so our defines don't break it */ +# include +# include + /* bcopy can handle overlapping moves according to SunOS 4.1.4 manpage */ +# define memmove(s1,s2,n) bcopy((s2),(s1),(n)) +# define strtoul(s,e,b) ((unsigned long int)strtol((s),(e),(b))) +extern char *sys_errlist[]; +extern int sys_nerr; +# define strerror(errnum) \ + (((errnum)<0 || (errnum)>=sys_nerr) ? NULL : sys_errlist[errnum]) + /* Being signed SunOS 4.x memcpy breaks ASN1_OBJECT table lookup */ +# include "crypto/o_str.h" +# define memcmp OPENSSL_memcmp +# endif + +# ifndef OPENSSL_EXIT +# if defined(MONOLITH) && !defined(OPENSSL_C) +# define OPENSSL_EXIT(n) return(n) +# else +# define OPENSSL_EXIT(n) do { EXIT(n); return(n); } while(0) +# endif +# endif + +/***********************************************/ + +# define DG_GCC_BUG /* gcc < 2.6.3 on DGUX */ + +# ifdef sgi +# define IRIX_CC_BUG /* all version of IRIX I've tested (4.* 5.*) */ +# endif +# ifdef OPENSSL_SYS_SNI +# define IRIX_CC_BUG /* CDS++ up to V2.0Bsomething suffered from + * the same bug. */ +# endif + +# if defined(OPENSSL_SYS_WINDOWS) +# define strcasecmp _stricmp +# define strncasecmp _strnicmp +# elif defined(OPENSSL_SYS_VMS) +/* VMS below version 7.0 doesn't have strcasecmp() */ +# include "o_str.h" +# define strcasecmp OPENSSL_strcasecmp +# define strncasecmp OPENSSL_strncasecmp +# define OPENSSL_IMPLEMENTS_strncasecmp +# elif defined(OPENSSL_SYS_OS2) && defined(__EMX__) +# define strcasecmp stricmp +# define strncasecmp strnicmp +# elif defined(OPENSSL_SYS_NETWARE) +# include +# if defined(NETWARE_CLIB) +# define strcasecmp stricmp +# define strncasecmp strnicmp +# endif /* NETWARE_CLIB */ +# endif + +# if defined(OPENSSL_SYS_OS2) && defined(__EMX__) +# include +# include +# define NO_SYSLOG +# endif + +/* vxworks */ +# if defined(OPENSSL_SYS_VXWORKS) +# include +# include +# include + +# define TTY_STRUCT int + +# define sleep(a) taskDelay((a) * sysClkRateGet()) + +# include +# include +# include + +# define getpid taskIdSelf + +/* + * NOTE: these are implemented by helpers in database app! if the database is + * not linked, we need to implement them elswhere + */ +struct hostent *gethostbyname(const char *name); +struct hostent *gethostbyaddr(const char *addr, int length, int type); +struct servent *getservbyname(const char *name, const char *proto); + +# endif +/* end vxworks */ + +/* beos */ +# if defined(OPENSSL_SYS_BEOS_R5) +# define SO_ERROR 0 +# define NO_SYS_UN +# define IPPROTO_IP 0 +# include +# endif + +# if !defined(inline) && !defined(__cplusplus) +# if defined(__STDC_VERSION__) && __STDC_VERSION__>=199901L + /* do nothing, inline works */ +# elif defined(__GNUC__) && __GNUC__>=2 +# define inline __inline__ +# elif defined(_MSC_VER) + /* + * Visual Studio: inline is available in C++ only, however + * __inline is available for C, see + * http://msdn.microsoft.com/en-us/library/z8y1yy88.aspx + */ +# define inline __inline +# else +# define inline +# endif +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/e_os2.h b/libs/openssl/e_os2.h new file mode 100644 index 00000000..2b1b78ff --- /dev/null +++ b/libs/openssl/e_os2.h @@ -0,0 +1,328 @@ +/* e_os2.h */ +/* ==================================================================== + * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include + +#ifndef HEADER_E_OS2_H +# define HEADER_E_OS2_H + +#ifdef __cplusplus +extern "C" { +#endif + +/****************************************************************************** + * Detect operating systems. This probably needs completing. + * The result is that at least one OPENSSL_SYS_os macro should be defined. + * However, if none is defined, Unix is assumed. + **/ + +# define OPENSSL_SYS_UNIX + +/* ---------------------- Macintosh, before MacOS X ----------------------- */ +# if defined(__MWERKS__) && defined(macintosh) || defined(OPENSSL_SYSNAME_MAC) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_MACINTOSH_CLASSIC +# endif + +/* ---------------------- NetWare ----------------------------------------- */ +# if defined(NETWARE) || defined(OPENSSL_SYSNAME_NETWARE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_NETWARE +# endif + +/* --------------------- Microsoft operating systems ---------------------- */ + +/* + * Note that MSDOS actually denotes 32-bit environments running on top of + * MS-DOS, such as DJGPP one. + */ +# if defined(OPENSSL_SYSNAME_MSDOS) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_MSDOS +# endif + +/* + * For 32 bit environment, there seems to be the CygWin environment and then + * all the others that try to do the same thing Microsoft does... + */ +# if defined(OPENSSL_SYSNAME_UWIN) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32_UWIN +# else +# if defined(__CYGWIN32__) || defined(OPENSSL_SYSNAME_CYGWIN32) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32_CYGWIN +# else +# if defined(_WIN32) || defined(OPENSSL_SYSNAME_WIN32) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WIN32 +# endif +# if defined(_WIN64) || defined(OPENSSL_SYSNAME_WIN64) +# undef OPENSSL_SYS_UNIX +# if !defined(OPENSSL_SYS_WIN64) +# define OPENSSL_SYS_WIN64 +# endif +# endif +# if defined(OPENSSL_SYSNAME_WINNT) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINNT +# endif +# if defined(OPENSSL_SYSNAME_WINCE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINCE +# endif +# endif +# endif + +/* Anything that tries to look like Microsoft is "Windows" */ +# if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN64) || defined(OPENSSL_SYS_WINNT) || defined(OPENSSL_SYS_WINCE) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_WINDOWS +# ifndef OPENSSL_SYS_MSDOS +# define OPENSSL_SYS_MSDOS +# endif +# endif + +/* + * DLL settings. This part is a bit tough, because it's up to the + * application implementor how he or she will link the application, so it + * requires some macro to be used. + */ +# ifdef OPENSSL_SYS_WINDOWS +# ifndef OPENSSL_OPT_WINDLL +# if defined(_WINDLL) /* This is used when building OpenSSL to + * indicate that DLL linkage should be used */ +# define OPENSSL_OPT_WINDLL +# endif +# endif +# endif + +/* ------------------------------- OpenVMS -------------------------------- */ +# if defined(__VMS) || defined(VMS) || defined(OPENSSL_SYSNAME_VMS) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_VMS +# if defined(__DECC) +# define OPENSSL_SYS_VMS_DECC +# elif defined(__DECCXX) +# define OPENSSL_SYS_VMS_DECC +# define OPENSSL_SYS_VMS_DECCXX +# else +# define OPENSSL_SYS_VMS_NODECC +# endif +# endif + +/* -------------------------------- OS/2 ---------------------------------- */ +# if defined(__EMX__) || defined(__OS2__) +# undef OPENSSL_SYS_UNIX +# define OPENSSL_SYS_OS2 +# endif + +/* -------------------------------- Unix ---------------------------------- */ +# ifdef OPENSSL_SYS_UNIX +# if defined(linux) || defined(__linux__) || defined(OPENSSL_SYSNAME_LINUX) +# define OPENSSL_SYS_LINUX +# endif +# ifdef OPENSSL_SYSNAME_MPE +# define OPENSSL_SYS_MPE +# endif +# ifdef OPENSSL_SYSNAME_SNI +# define OPENSSL_SYS_SNI +# endif +# ifdef OPENSSL_SYSNAME_ULTRASPARC +# define OPENSSL_SYS_ULTRASPARC +# endif +# ifdef OPENSSL_SYSNAME_NEWS4 +# define OPENSSL_SYS_NEWS4 +# endif +# ifdef OPENSSL_SYSNAME_MACOSX +# define OPENSSL_SYS_MACOSX +# endif +# ifdef OPENSSL_SYSNAME_MACOSX_RHAPSODY +# define OPENSSL_SYS_MACOSX_RHAPSODY +# define OPENSSL_SYS_MACOSX +# endif +# ifdef OPENSSL_SYSNAME_SUNOS +# define OPENSSL_SYS_SUNOS +# endif +# if defined(_CRAY) || defined(OPENSSL_SYSNAME_CRAY) +# define OPENSSL_SYS_CRAY +# endif +# if defined(_AIX) || defined(OPENSSL_SYSNAME_AIX) +# define OPENSSL_SYS_AIX +# endif +# endif + +/* -------------------------------- VOS ----------------------------------- */ +# if defined(__VOS__) || defined(OPENSSL_SYSNAME_VOS) +# define OPENSSL_SYS_VOS +# ifdef __HPPA__ +# define OPENSSL_SYS_VOS_HPPA +# endif +# ifdef __IA32__ +# define OPENSSL_SYS_VOS_IA32 +# endif +# endif + +/* ------------------------------ VxWorks --------------------------------- */ +# ifdef OPENSSL_SYSNAME_VXWORKS +# define OPENSSL_SYS_VXWORKS +# endif + +/* -------------------------------- BeOS ---------------------------------- */ +# if defined(__BEOS__) +# define OPENSSL_SYS_BEOS +# include +# if defined(BONE_VERSION) +# define OPENSSL_SYS_BEOS_BONE +# else +# define OPENSSL_SYS_BEOS_R5 +# endif +# endif + +/** + * That's it for OS-specific stuff + *****************************************************************************/ + +/* Specials for I/O an exit */ +# ifdef OPENSSL_SYS_MSDOS +# define OPENSSL_UNISTD_IO +# define OPENSSL_DECLARE_EXIT extern void exit(int); +# else +# define OPENSSL_UNISTD_IO OPENSSL_UNISTD +# define OPENSSL_DECLARE_EXIT /* declared in unistd.h */ +# endif + +/*- + * Definitions of OPENSSL_GLOBAL and OPENSSL_EXTERN, to define and declare + * certain global symbols that, with some compilers under VMS, have to be + * defined and declared explicitely with globaldef and globalref. + * Definitions of OPENSSL_EXPORT and OPENSSL_IMPORT, to define and declare + * DLL exports and imports for compilers under Win32. These are a little + * more complicated to use. Basically, for any library that exports some + * global variables, the following code must be present in the header file + * that declares them, before OPENSSL_EXTERN is used: + * + * #ifdef SOME_BUILD_FLAG_MACRO + * # undef OPENSSL_EXTERN + * # define OPENSSL_EXTERN OPENSSL_EXPORT + * #endif + * + * The default is to have OPENSSL_EXPORT, OPENSSL_IMPORT and OPENSSL_GLOBAL + * have some generally sensible values, and for OPENSSL_EXTERN to have the + * value OPENSSL_IMPORT. + */ + +# if defined(OPENSSL_SYS_VMS_NODECC) +# define OPENSSL_EXPORT globalref +# define OPENSSL_IMPORT globalref +# define OPENSSL_GLOBAL globaldef +# elif defined(OPENSSL_SYS_WINDOWS) && defined(OPENSSL_OPT_WINDLL) +# define OPENSSL_EXPORT extern __declspec(dllexport) +# define OPENSSL_IMPORT extern __declspec(dllimport) +# define OPENSSL_GLOBAL +# else +# define OPENSSL_EXPORT extern +# define OPENSSL_IMPORT extern +# define OPENSSL_GLOBAL +# endif +# define OPENSSL_EXTERN OPENSSL_IMPORT + +/*- + * Macros to allow global variables to be reached through function calls when + * required (if a shared library version requires it, for example. + * The way it's done allows definitions like this: + * + * // in foobar.c + * OPENSSL_IMPLEMENT_GLOBAL(int,foobar,0) + * // in foobar.h + * OPENSSL_DECLARE_GLOBAL(int,foobar); + * #define foobar OPENSSL_GLOBAL_REF(foobar) + */ +# ifdef OPENSSL_EXPORT_VAR_AS_FUNCTION +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) \ + type *_shadow_##name(void) \ + { static type _hide_##name=value; return &_hide_##name; } +# define OPENSSL_DECLARE_GLOBAL(type,name) type *_shadow_##name(void) +# define OPENSSL_GLOBAL_REF(name) (*(_shadow_##name())) +# else +# define OPENSSL_IMPLEMENT_GLOBAL(type,name,value) OPENSSL_GLOBAL type _shadow_##name=value; +# define OPENSSL_DECLARE_GLOBAL(type,name) OPENSSL_EXPORT type _shadow_##name +# define OPENSSL_GLOBAL_REF(name) _shadow_##name +# endif + +# if defined(OPENSSL_SYS_MACINTOSH_CLASSIC) && macintosh==1 && !defined(MAC_OS_GUSI_SOURCE) +# define ossl_ssize_t long +# endif + +# ifdef OPENSSL_SYS_MSDOS +# define ossl_ssize_t long +# endif + +# if defined(NeXT) || defined(OPENSSL_SYS_NEWS4) || defined(OPENSSL_SYS_SUNOS) +# define ssize_t int +# endif + +# if defined(__ultrix) && !defined(ssize_t) +# define ossl_ssize_t int +# endif + +# ifndef ossl_ssize_t +# define ossl_ssize_t ssize_t +# endif + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/include/openssl/aes.h b/libs/openssl/include/openssl/aes.h new file mode 120000 index 00000000..f555c13e --- /dev/null +++ b/libs/openssl/include/openssl/aes.h @@ -0,0 +1 @@ +../../crypto/aes/aes.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/asn1.h b/libs/openssl/include/openssl/asn1.h new file mode 120000 index 00000000..dd514954 --- /dev/null +++ b/libs/openssl/include/openssl/asn1.h @@ -0,0 +1 @@ +../../crypto/asn1/asn1.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/asn1_mac.h b/libs/openssl/include/openssl/asn1_mac.h new file mode 120000 index 00000000..97781d99 --- /dev/null +++ b/libs/openssl/include/openssl/asn1_mac.h @@ -0,0 +1 @@ +../../crypto/asn1/asn1_mac.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/asn1t.h b/libs/openssl/include/openssl/asn1t.h new file mode 120000 index 00000000..31c87c38 --- /dev/null +++ b/libs/openssl/include/openssl/asn1t.h @@ -0,0 +1 @@ +../../crypto/asn1/asn1t.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/bio.h b/libs/openssl/include/openssl/bio.h new file mode 120000 index 00000000..c598b6f7 --- /dev/null +++ b/libs/openssl/include/openssl/bio.h @@ -0,0 +1 @@ +../../crypto/bio/bio.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/blowfish.h b/libs/openssl/include/openssl/blowfish.h new file mode 120000 index 00000000..88bf9223 --- /dev/null +++ b/libs/openssl/include/openssl/blowfish.h @@ -0,0 +1 @@ +../../crypto/bf/blowfish.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/bn.h b/libs/openssl/include/openssl/bn.h new file mode 120000 index 00000000..5c251c13 --- /dev/null +++ b/libs/openssl/include/openssl/bn.h @@ -0,0 +1 @@ +../../crypto/bn/bn.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/buffer.h b/libs/openssl/include/openssl/buffer.h new file mode 120000 index 00000000..76ea7114 --- /dev/null +++ b/libs/openssl/include/openssl/buffer.h @@ -0,0 +1 @@ +../../crypto/buffer/buffer.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/camellia.h b/libs/openssl/include/openssl/camellia.h new file mode 120000 index 00000000..ad10f979 --- /dev/null +++ b/libs/openssl/include/openssl/camellia.h @@ -0,0 +1 @@ +../../crypto/camellia/camellia.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/cast.h b/libs/openssl/include/openssl/cast.h new file mode 120000 index 00000000..b775ab04 --- /dev/null +++ b/libs/openssl/include/openssl/cast.h @@ -0,0 +1 @@ +../../crypto/cast/cast.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/cmac.h b/libs/openssl/include/openssl/cmac.h new file mode 120000 index 00000000..bfb70c46 --- /dev/null +++ b/libs/openssl/include/openssl/cmac.h @@ -0,0 +1 @@ +../../crypto/cmac/cmac.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/cms.h b/libs/openssl/include/openssl/cms.h new file mode 120000 index 00000000..0f651add --- /dev/null +++ b/libs/openssl/include/openssl/cms.h @@ -0,0 +1 @@ +../../crypto/cms/cms.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/comp.h b/libs/openssl/include/openssl/comp.h new file mode 120000 index 00000000..712c9d4a --- /dev/null +++ b/libs/openssl/include/openssl/comp.h @@ -0,0 +1 @@ +../../crypto/comp/comp.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/conf.h b/libs/openssl/include/openssl/conf.h new file mode 120000 index 00000000..44156b18 --- /dev/null +++ b/libs/openssl/include/openssl/conf.h @@ -0,0 +1 @@ +../../crypto/conf/conf.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/conf_api.h b/libs/openssl/include/openssl/conf_api.h new file mode 120000 index 00000000..26b42198 --- /dev/null +++ b/libs/openssl/include/openssl/conf_api.h @@ -0,0 +1 @@ +../../crypto/conf/conf_api.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/crypto.h b/libs/openssl/include/openssl/crypto.h new file mode 120000 index 00000000..2f3f63cb --- /dev/null +++ b/libs/openssl/include/openssl/crypto.h @@ -0,0 +1 @@ +../../crypto/crypto.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/des.h b/libs/openssl/include/openssl/des.h new file mode 120000 index 00000000..5eb7c88b --- /dev/null +++ b/libs/openssl/include/openssl/des.h @@ -0,0 +1 @@ +../../crypto/des/des.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/des_old.h b/libs/openssl/include/openssl/des_old.h new file mode 120000 index 00000000..97098988 --- /dev/null +++ b/libs/openssl/include/openssl/des_old.h @@ -0,0 +1 @@ +../../crypto/des/des_old.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/dh.h b/libs/openssl/include/openssl/dh.h new file mode 120000 index 00000000..c0eacb5e --- /dev/null +++ b/libs/openssl/include/openssl/dh.h @@ -0,0 +1 @@ +../../crypto/dh/dh.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/dsa.h b/libs/openssl/include/openssl/dsa.h new file mode 120000 index 00000000..ad4695f9 --- /dev/null +++ b/libs/openssl/include/openssl/dsa.h @@ -0,0 +1 @@ +../../crypto/dsa/dsa.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/dso.h b/libs/openssl/include/openssl/dso.h new file mode 120000 index 00000000..b1f215da --- /dev/null +++ b/libs/openssl/include/openssl/dso.h @@ -0,0 +1 @@ +../../crypto/dso/dso.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/dtls1.h b/libs/openssl/include/openssl/dtls1.h new file mode 100644 index 00000000..8deb299a --- /dev/null +++ b/libs/openssl/include/openssl/dtls1.h @@ -0,0 +1,268 @@ +/* ssl/dtls1.h */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef HEADER_DTLS1_H +# define HEADER_DTLS1_H + +# include +# include +# ifdef OPENSSL_SYS_VMS +# include +# include +# endif +# ifdef OPENSSL_SYS_WIN32 +/* Needed for struct timeval */ +# include +# elif defined(OPENSSL_SYS_NETWARE) && !defined(_WINSOCK2API_) +# include +# else +# if defined(OPENSSL_SYS_VXWORKS) +# include +# else +# include +# endif +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +# define DTLS1_VERSION 0xFEFF +# define DTLS_MAX_VERSION DTLS1_VERSION +# define DTLS1_VERSION_MAJOR 0xFE + +# define DTLS1_BAD_VER 0x0100 + +# if 0 +/* this alert description is not specified anywhere... */ +# define DTLS1_AD_MISSING_HANDSHAKE_MESSAGE 110 +# endif + +/* lengths of messages */ +# define DTLS1_COOKIE_LENGTH 256 + +# define DTLS1_RT_HEADER_LENGTH 13 + +# define DTLS1_HM_HEADER_LENGTH 12 + +# define DTLS1_HM_BAD_FRAGMENT -2 +# define DTLS1_HM_FRAGMENT_RETRY -3 + +# define DTLS1_CCS_HEADER_LENGTH 1 + +# ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE +# define DTLS1_AL_HEADER_LENGTH 7 +# else +# define DTLS1_AL_HEADER_LENGTH 2 +# endif + +# ifndef OPENSSL_NO_SSL_INTERN + +# ifndef OPENSSL_NO_SCTP +# define DTLS1_SCTP_AUTH_LABEL "EXPORTER_DTLS_OVER_SCTP" +# endif + +/* Max MTU overhead we know about so far is 40 for IPv6 + 8 for UDP */ +# define DTLS1_MAX_MTU_OVERHEAD 48 + +typedef struct dtls1_bitmap_st { + unsigned long map; /* track 32 packets on 32-bit systems and 64 + * - on 64-bit systems */ + unsigned char max_seq_num[8]; /* max record number seen so far, 64-bit + * value in big-endian encoding */ +} DTLS1_BITMAP; + +struct dtls1_retransmit_state { + EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ + EVP_MD_CTX *write_hash; /* used for mac generation */ +# ifndef OPENSSL_NO_COMP + COMP_CTX *compress; /* compression */ +# else + char *compress; +# endif + SSL_SESSION *session; + unsigned short epoch; +}; + +struct hm_header_st { + unsigned char type; + unsigned long msg_len; + unsigned short seq; + unsigned long frag_off; + unsigned long frag_len; + unsigned int is_ccs; + struct dtls1_retransmit_state saved_retransmit_state; +}; + +struct ccs_header_st { + unsigned char type; + unsigned short seq; +}; + +struct dtls1_timeout_st { + /* Number of read timeouts so far */ + unsigned int read_timeouts; + /* Number of write timeouts so far */ + unsigned int write_timeouts; + /* Number of alerts received so far */ + unsigned int num_alerts; +}; + +typedef struct record_pqueue_st { + unsigned short epoch; + pqueue q; +} record_pqueue; + +typedef struct hm_fragment_st { + struct hm_header_st msg_header; + unsigned char *fragment; + unsigned char *reassembly; +} hm_fragment; + +typedef struct dtls1_state_st { + unsigned int send_cookie; + unsigned char cookie[DTLS1_COOKIE_LENGTH]; + unsigned char rcvd_cookie[DTLS1_COOKIE_LENGTH]; + unsigned int cookie_len; + /* + * The current data and handshake epoch. This is initially + * undefined, and starts at zero once the initial handshake is + * completed + */ + unsigned short r_epoch; + unsigned short w_epoch; + /* records being received in the current epoch */ + DTLS1_BITMAP bitmap; + /* renegotiation starts a new set of sequence numbers */ + DTLS1_BITMAP next_bitmap; + /* handshake message numbers */ + unsigned short handshake_write_seq; + unsigned short next_handshake_write_seq; + unsigned short handshake_read_seq; + /* save last sequence number for retransmissions */ + unsigned char last_write_sequence[8]; + /* Received handshake records (processed and unprocessed) */ + record_pqueue unprocessed_rcds; + record_pqueue processed_rcds; + /* Buffered handshake messages */ + pqueue buffered_messages; + /* Buffered (sent) handshake records */ + pqueue sent_messages; + /* + * Buffered application records. Only for records between CCS and + * Finished to prevent either protocol violation or unnecessary message + * loss. + */ + record_pqueue buffered_app_data; + /* Is set when listening for new connections with dtls1_listen() */ + unsigned int listen; + unsigned int link_mtu; /* max on-the-wire DTLS packet size */ + unsigned int mtu; /* max DTLS packet size */ + struct hm_header_st w_msg_hdr; + struct hm_header_st r_msg_hdr; + struct dtls1_timeout_st timeout; + /* + * Indicates when the last handshake msg or heartbeat sent will timeout + */ + struct timeval next_timeout; + /* Timeout duration */ + unsigned short timeout_duration; + /* + * storage for Alert/Handshake protocol data received but not yet + * processed by ssl3_read_bytes: + */ + unsigned char alert_fragment[DTLS1_AL_HEADER_LENGTH]; + unsigned int alert_fragment_len; + unsigned char handshake_fragment[DTLS1_HM_HEADER_LENGTH]; + unsigned int handshake_fragment_len; + unsigned int retransmitting; + /* + * Set when the handshake is ready to process peer's ChangeCipherSpec message. + * Cleared after the message has been processed. + */ + unsigned int change_cipher_spec_ok; +# ifndef OPENSSL_NO_SCTP + /* used when SSL_ST_XX_FLUSH is entered */ + int next_state; + int shutdown_received; +# endif +} DTLS1_STATE; + +typedef struct dtls1_record_data_st { + unsigned char *packet; + unsigned int packet_length; + SSL3_BUFFER rbuf; + SSL3_RECORD rrec; +# ifndef OPENSSL_NO_SCTP + struct bio_dgram_sctp_rcvinfo recordinfo; +# endif +} DTLS1_RECORD_DATA; + +# endif + +/* Timeout multipliers (timeout slice is defined in apps/timeouts.h */ +# define DTLS1_TMO_READ_COUNT 2 +# define DTLS1_TMO_WRITE_COUNT 2 + +# define DTLS1_TMO_ALERT_COUNT 12 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/include/openssl/e_os2.h b/libs/openssl/include/openssl/e_os2.h new file mode 120000 index 00000000..0e8c0399 --- /dev/null +++ b/libs/openssl/include/openssl/e_os2.h @@ -0,0 +1 @@ +../../e_os2.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/ebcdic.h b/libs/openssl/include/openssl/ebcdic.h new file mode 120000 index 00000000..a7ee60e0 --- /dev/null +++ b/libs/openssl/include/openssl/ebcdic.h @@ -0,0 +1 @@ +../../crypto/ebcdic.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/ec.h b/libs/openssl/include/openssl/ec.h new file mode 120000 index 00000000..245497ed --- /dev/null +++ b/libs/openssl/include/openssl/ec.h @@ -0,0 +1 @@ +../../crypto/ec/ec.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/ecdh.h b/libs/openssl/include/openssl/ecdh.h new file mode 120000 index 00000000..3fd1c3ba --- /dev/null +++ b/libs/openssl/include/openssl/ecdh.h @@ -0,0 +1 @@ +../../crypto/ecdh/ecdh.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/ecdsa.h b/libs/openssl/include/openssl/ecdsa.h new file mode 120000 index 00000000..e48acc66 --- /dev/null +++ b/libs/openssl/include/openssl/ecdsa.h @@ -0,0 +1 @@ +../../crypto/ecdsa/ecdsa.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/engine.h b/libs/openssl/include/openssl/engine.h new file mode 120000 index 00000000..a02073e3 --- /dev/null +++ b/libs/openssl/include/openssl/engine.h @@ -0,0 +1 @@ +../../crypto/engine/engine.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/err.h b/libs/openssl/include/openssl/err.h new file mode 120000 index 00000000..20f65bd9 --- /dev/null +++ b/libs/openssl/include/openssl/err.h @@ -0,0 +1 @@ +../../crypto/err/err.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/evp.h b/libs/openssl/include/openssl/evp.h new file mode 120000 index 00000000..7e3a904a --- /dev/null +++ b/libs/openssl/include/openssl/evp.h @@ -0,0 +1 @@ +../../crypto/evp/evp.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/hmac.h b/libs/openssl/include/openssl/hmac.h new file mode 120000 index 00000000..de19ba7e --- /dev/null +++ b/libs/openssl/include/openssl/hmac.h @@ -0,0 +1 @@ +../../crypto/hmac/hmac.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/idea.h b/libs/openssl/include/openssl/idea.h new file mode 120000 index 00000000..724fa345 --- /dev/null +++ b/libs/openssl/include/openssl/idea.h @@ -0,0 +1 @@ +../../crypto/idea/idea.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/krb5_asn.h b/libs/openssl/include/openssl/krb5_asn.h new file mode 120000 index 00000000..1172e522 --- /dev/null +++ b/libs/openssl/include/openssl/krb5_asn.h @@ -0,0 +1 @@ +../../crypto/krb5/krb5_asn.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/kssl.h b/libs/openssl/include/openssl/kssl.h new file mode 100644 index 00000000..ae8a51f4 --- /dev/null +++ b/libs/openssl/include/openssl/kssl.h @@ -0,0 +1,197 @@ +/* ssl/kssl.h */ +/* + * Written by Vern Staats for the OpenSSL project + * 2000. project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + ** 19990701 VRS Started. + */ + +#ifndef KSSL_H +# define KSSL_H + +# include + +# ifndef OPENSSL_NO_KRB5 + +# include +# include +# include +# ifdef OPENSSL_SYS_WIN32 +/* + * These can sometimes get redefined indirectly by krb5 header files after + * they get undefed in ossl_typ.h + */ +# undef X509_NAME +# undef X509_EXTENSIONS +# undef OCSP_REQUEST +# undef OCSP_RESPONSE +# endif + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Depending on which KRB5 implementation used, some types from + * the other may be missing. Resolve that here and now + */ +# ifdef KRB5_HEIMDAL +typedef unsigned char krb5_octet; +# define FAR +# else + +# ifndef FAR +# define FAR +# endif + +# endif + +/*- + * Uncomment this to debug kssl problems or + * to trace usage of the Kerberos session key + * + * #define KSSL_DEBUG + */ + +# ifndef KRB5SVC +# define KRB5SVC "host" +# endif + +# ifndef KRB5KEYTAB +# define KRB5KEYTAB "/etc/krb5.keytab" +# endif + +# ifndef KRB5SENDAUTH +# define KRB5SENDAUTH 1 +# endif + +# ifndef KRB5CHECKAUTH +# define KRB5CHECKAUTH 1 +# endif + +# ifndef KSSL_CLOCKSKEW +# define KSSL_CLOCKSKEW 300; +# endif + +# define KSSL_ERR_MAX 255 +typedef struct kssl_err_st { + int reason; + char text[KSSL_ERR_MAX + 1]; +} KSSL_ERR; + +/*- Context for passing + * (1) Kerberos session key to SSL, and + * (2) Config data between application and SSL lib + */ +typedef struct kssl_ctx_st { + /* used by: disposition: */ + char *service_name; /* C,S default ok (kssl) */ + char *service_host; /* C input, REQUIRED */ + char *client_princ; /* S output from krb5 ticket */ + char *keytab_file; /* S NULL (/etc/krb5.keytab) */ + char *cred_cache; /* C NULL (default) */ + krb5_enctype enctype; + int length; + krb5_octet FAR *key; +} KSSL_CTX; + +# define KSSL_CLIENT 1 +# define KSSL_SERVER 2 +# define KSSL_SERVICE 3 +# define KSSL_KEYTAB 4 + +# define KSSL_CTX_OK 0 +# define KSSL_CTX_ERR 1 +# define KSSL_NOMEM 2 + +/* Public (for use by applications that use OpenSSL with Kerberos 5 support */ +krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text); +KSSL_CTX *kssl_ctx_new(void); +KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx); +void kssl_ctx_show(KSSL_CTX *kssl_ctx); +krb5_error_code kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, + krb5_data *realm, krb5_data *entity, + int nentities); +krb5_error_code kssl_cget_tkt(KSSL_CTX *kssl_ctx, krb5_data **enc_tktp, + krb5_data *authenp, KSSL_ERR *kssl_err); +krb5_error_code kssl_sget_tkt(KSSL_CTX *kssl_ctx, krb5_data *indata, + krb5_ticket_times *ttimes, KSSL_ERR *kssl_err); +krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session); +void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text); +void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data); +krb5_error_code kssl_build_principal_2(krb5_context context, + krb5_principal *princ, int rlen, + const char *realm, int slen, + const char *svc, int hlen, + const char *host); +krb5_error_code kssl_validate_times(krb5_timestamp atime, + krb5_ticket_times *ttimes); +krb5_error_code kssl_check_authent(KSSL_CTX *kssl_ctx, krb5_data *authentp, + krb5_timestamp *atimep, + KSSL_ERR *kssl_err); +unsigned char *kssl_skip_confound(krb5_enctype enctype, unsigned char *authn); + +void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx); +KSSL_CTX *SSL_get0_kssl_ctx(SSL *s); +char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx); + +#ifdef __cplusplus +} +#endif +# endif /* OPENSSL_NO_KRB5 */ +#endif /* KSSL_H */ diff --git a/libs/openssl/include/openssl/kssl_lcl.h b/libs/openssl/include/openssl/kssl_lcl.h new file mode 100644 index 00000000..8e6a6d69 --- /dev/null +++ b/libs/openssl/include/openssl/kssl_lcl.h @@ -0,0 +1,88 @@ +/* ssl/kssl.h */ +/* + * Written by Vern Staats for the OpenSSL project + * 2000. project 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#ifndef KSSL_LCL_H +# define KSSL_LCL_H + +# include + +# ifndef OPENSSL_NO_KRB5 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Private (internal to OpenSSL) */ +void print_krb5_data(char *label, krb5_data *kdata); +void print_krb5_authdata(char *label, krb5_authdata **adata); +void print_krb5_keyblock(char *label, krb5_keyblock *keyblk); + +char *kstring(char *string); +char *knumber(int len, krb5_octet *contents); + +const EVP_CIPHER *kssl_map_enc(krb5_enctype enctype); + +int kssl_keytab_is_available(KSSL_CTX *kssl_ctx); +int kssl_tgt_is_available(KSSL_CTX *kssl_ctx); + +#ifdef __cplusplus +} +#endif +# endif /* OPENSSL_NO_KRB5 */ +#endif /* KSSL_LCL_H */ diff --git a/libs/openssl/include/openssl/lhash.h b/libs/openssl/include/openssl/lhash.h new file mode 120000 index 00000000..56eb0991 --- /dev/null +++ b/libs/openssl/include/openssl/lhash.h @@ -0,0 +1 @@ +../../crypto/lhash/lhash.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/md4.h b/libs/openssl/include/openssl/md4.h new file mode 120000 index 00000000..4ff863e7 --- /dev/null +++ b/libs/openssl/include/openssl/md4.h @@ -0,0 +1 @@ +../../crypto/md4/md4.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/md5.h b/libs/openssl/include/openssl/md5.h new file mode 120000 index 00000000..26fa47eb --- /dev/null +++ b/libs/openssl/include/openssl/md5.h @@ -0,0 +1 @@ +../../crypto/md5/md5.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/mdc2.h b/libs/openssl/include/openssl/mdc2.h new file mode 120000 index 00000000..0bc32f12 --- /dev/null +++ b/libs/openssl/include/openssl/mdc2.h @@ -0,0 +1 @@ +../../crypto/mdc2/mdc2.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/modes.h b/libs/openssl/include/openssl/modes.h new file mode 120000 index 00000000..ccc17282 --- /dev/null +++ b/libs/openssl/include/openssl/modes.h @@ -0,0 +1 @@ +../../crypto/modes/modes.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/obj_mac.h b/libs/openssl/include/openssl/obj_mac.h new file mode 120000 index 00000000..0f443c82 --- /dev/null +++ b/libs/openssl/include/openssl/obj_mac.h @@ -0,0 +1 @@ +../../crypto/objects/obj_mac.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/objects.h b/libs/openssl/include/openssl/objects.h new file mode 120000 index 00000000..7bd145ca --- /dev/null +++ b/libs/openssl/include/openssl/objects.h @@ -0,0 +1 @@ +../../crypto/objects/objects.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/ocsp.h b/libs/openssl/include/openssl/ocsp.h new file mode 120000 index 00000000..08288c84 --- /dev/null +++ b/libs/openssl/include/openssl/ocsp.h @@ -0,0 +1 @@ +../../crypto/ocsp/ocsp.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/opensslconf.h b/libs/openssl/include/openssl/opensslconf.h new file mode 120000 index 00000000..25d2bea9 --- /dev/null +++ b/libs/openssl/include/openssl/opensslconf.h @@ -0,0 +1 @@ +../../crypto/opensslconf.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/opensslv.h b/libs/openssl/include/openssl/opensslv.h new file mode 120000 index 00000000..f314f5fc --- /dev/null +++ b/libs/openssl/include/openssl/opensslv.h @@ -0,0 +1 @@ +../../crypto/opensslv.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/ossl_typ.h b/libs/openssl/include/openssl/ossl_typ.h new file mode 120000 index 00000000..e8f42456 --- /dev/null +++ b/libs/openssl/include/openssl/ossl_typ.h @@ -0,0 +1 @@ +../../crypto/ossl_typ.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/pem.h b/libs/openssl/include/openssl/pem.h new file mode 120000 index 00000000..ca371423 --- /dev/null +++ b/libs/openssl/include/openssl/pem.h @@ -0,0 +1 @@ +../../crypto/pem/pem.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/pem2.h b/libs/openssl/include/openssl/pem2.h new file mode 120000 index 00000000..c734dbdc --- /dev/null +++ b/libs/openssl/include/openssl/pem2.h @@ -0,0 +1 @@ +../../crypto/pem/pem2.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/pkcs12.h b/libs/openssl/include/openssl/pkcs12.h new file mode 120000 index 00000000..eebba777 --- /dev/null +++ b/libs/openssl/include/openssl/pkcs12.h @@ -0,0 +1 @@ +../../crypto/pkcs12/pkcs12.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/pkcs7.h b/libs/openssl/include/openssl/pkcs7.h new file mode 120000 index 00000000..73e1b23f --- /dev/null +++ b/libs/openssl/include/openssl/pkcs7.h @@ -0,0 +1 @@ +../../crypto/pkcs7/pkcs7.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/pqueue.h b/libs/openssl/include/openssl/pqueue.h new file mode 120000 index 00000000..93817c2d --- /dev/null +++ b/libs/openssl/include/openssl/pqueue.h @@ -0,0 +1 @@ +../../crypto/pqueue/pqueue.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/rand.h b/libs/openssl/include/openssl/rand.h new file mode 120000 index 00000000..11231f85 --- /dev/null +++ b/libs/openssl/include/openssl/rand.h @@ -0,0 +1 @@ +../../crypto/rand/rand.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/rc2.h b/libs/openssl/include/openssl/rc2.h new file mode 120000 index 00000000..bb5a05c5 --- /dev/null +++ b/libs/openssl/include/openssl/rc2.h @@ -0,0 +1 @@ +../../crypto/rc2/rc2.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/rc4.h b/libs/openssl/include/openssl/rc4.h new file mode 120000 index 00000000..ef7deeb7 --- /dev/null +++ b/libs/openssl/include/openssl/rc4.h @@ -0,0 +1 @@ +../../crypto/rc4/rc4.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/ripemd.h b/libs/openssl/include/openssl/ripemd.h new file mode 120000 index 00000000..200f562f --- /dev/null +++ b/libs/openssl/include/openssl/ripemd.h @@ -0,0 +1 @@ +../../crypto/ripemd/ripemd.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/rsa.h b/libs/openssl/include/openssl/rsa.h new file mode 120000 index 00000000..3e5a6547 --- /dev/null +++ b/libs/openssl/include/openssl/rsa.h @@ -0,0 +1 @@ +../../crypto/rsa/rsa.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/safestack.h b/libs/openssl/include/openssl/safestack.h new file mode 120000 index 00000000..8ca5b4cc --- /dev/null +++ b/libs/openssl/include/openssl/safestack.h @@ -0,0 +1 @@ +../../crypto/stack/safestack.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/seed.h b/libs/openssl/include/openssl/seed.h new file mode 120000 index 00000000..05d04a50 --- /dev/null +++ b/libs/openssl/include/openssl/seed.h @@ -0,0 +1 @@ +../../crypto/seed/seed.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/sha.h b/libs/openssl/include/openssl/sha.h new file mode 120000 index 00000000..3025cd5d --- /dev/null +++ b/libs/openssl/include/openssl/sha.h @@ -0,0 +1 @@ +../../crypto/sha/sha.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/srp.h b/libs/openssl/include/openssl/srp.h new file mode 120000 index 00000000..16b73ebd --- /dev/null +++ b/libs/openssl/include/openssl/srp.h @@ -0,0 +1 @@ +../../crypto/srp/srp.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/srtp.h b/libs/openssl/include/openssl/srtp.h new file mode 100644 index 00000000..10082c93 --- /dev/null +++ b/libs/openssl/include/openssl/srtp.h @@ -0,0 +1,148 @@ +/* ssl/srtp.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* + * DTLS code by Eric Rescorla + * + * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc. + */ + +#ifndef HEADER_D1_SRTP_H +# define HEADER_D1_SRTP_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define SRTP_AES128_CM_SHA1_80 0x0001 +# define SRTP_AES128_CM_SHA1_32 0x0002 +# define SRTP_AES128_F8_SHA1_80 0x0003 +# define SRTP_AES128_F8_SHA1_32 0x0004 +# define SRTP_NULL_SHA1_80 0x0005 +# define SRTP_NULL_SHA1_32 0x0006 + +# ifndef OPENSSL_NO_SRTP + +int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles); +int SSL_set_tlsext_use_srtp(SSL *ctx, const char *profiles); +SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s); + +STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl); +SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s); + +# endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/openssl/include/openssl/ssl.h b/libs/openssl/include/openssl/ssl.h new file mode 100644 index 00000000..d6c475c2 --- /dev/null +++ b/libs/openssl/include/openssl/ssl.h @@ -0,0 +1,2770 @@ +/* ssl/ssl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_SSL_H +# define HEADER_SSL_H + +# include + +# ifndef OPENSSL_NO_COMP +# include +# endif +# ifndef OPENSSL_NO_BIO +# include +# endif +# ifndef OPENSSL_NO_DEPRECATED +# ifndef OPENSSL_NO_X509 +# include +# endif +# include +# include +# include +# endif +# include +# include + +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* SSLeay version number for ASN.1 encoding of the session information */ +/*- + * Version 0 - initial version + * Version 1 - added the optional peer certificate + */ +# define SSL_SESSION_ASN1_VERSION 0x0001 + +/* text strings for the ciphers */ +# define SSL_TXT_NULL_WITH_MD5 SSL2_TXT_NULL_WITH_MD5 +# define SSL_TXT_RC4_128_WITH_MD5 SSL2_TXT_RC4_128_WITH_MD5 +# define SSL_TXT_RC4_128_EXPORT40_WITH_MD5 SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 +# define SSL_TXT_RC2_128_CBC_WITH_MD5 SSL2_TXT_RC2_128_CBC_WITH_MD5 +# define SSL_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 +# define SSL_TXT_IDEA_128_CBC_WITH_MD5 SSL2_TXT_IDEA_128_CBC_WITH_MD5 +# define SSL_TXT_DES_64_CBC_WITH_MD5 SSL2_TXT_DES_64_CBC_WITH_MD5 +# define SSL_TXT_DES_64_CBC_WITH_SHA SSL2_TXT_DES_64_CBC_WITH_SHA +# define SSL_TXT_DES_192_EDE3_CBC_WITH_MD5 SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 +# define SSL_TXT_DES_192_EDE3_CBC_WITH_SHA SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA + +/* + * VRS Additional Kerberos5 entries + */ +# define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA +# define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA +# define SSL_TXT_KRB5_RC4_128_SHA SSL3_TXT_KRB5_RC4_128_SHA +# define SSL_TXT_KRB5_IDEA_128_CBC_SHA SSL3_TXT_KRB5_IDEA_128_CBC_SHA +# define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 +# define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 +# define SSL_TXT_KRB5_RC4_128_MD5 SSL3_TXT_KRB5_RC4_128_MD5 +# define SSL_TXT_KRB5_IDEA_128_CBC_MD5 SSL3_TXT_KRB5_IDEA_128_CBC_MD5 + +# define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA +# define SSL_TXT_KRB5_RC2_40_CBC_SHA SSL3_TXT_KRB5_RC2_40_CBC_SHA +# define SSL_TXT_KRB5_RC4_40_SHA SSL3_TXT_KRB5_RC4_40_SHA +# define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 +# define SSL_TXT_KRB5_RC2_40_CBC_MD5 SSL3_TXT_KRB5_RC2_40_CBC_MD5 +# define SSL_TXT_KRB5_RC4_40_MD5 SSL3_TXT_KRB5_RC4_40_MD5 + +# define SSL_TXT_KRB5_DES_40_CBC_SHA SSL3_TXT_KRB5_DES_40_CBC_SHA +# define SSL_TXT_KRB5_DES_40_CBC_MD5 SSL3_TXT_KRB5_DES_40_CBC_MD5 +# define SSL_TXT_KRB5_DES_64_CBC_SHA SSL3_TXT_KRB5_DES_64_CBC_SHA +# define SSL_TXT_KRB5_DES_64_CBC_MD5 SSL3_TXT_KRB5_DES_64_CBC_MD5 +# define SSL_TXT_KRB5_DES_192_CBC3_SHA SSL3_TXT_KRB5_DES_192_CBC3_SHA +# define SSL_TXT_KRB5_DES_192_CBC3_MD5 SSL3_TXT_KRB5_DES_192_CBC3_MD5 +# define SSL_MAX_KRB5_PRINCIPAL_LENGTH 256 + +# define SSL_MAX_SSL_SESSION_ID_LENGTH 32 +# define SSL_MAX_SID_CTX_LENGTH 32 + +# define SSL_MIN_RSA_MODULUS_LENGTH_IN_BYTES (512/8) +# define SSL_MAX_KEY_ARG_LENGTH 8 +# define SSL_MAX_MASTER_KEY_LENGTH 48 + +/* These are used to specify which ciphers to use and not to use */ + +# define SSL_TXT_EXP40 "EXPORT40" +# define SSL_TXT_EXP56 "EXPORT56" +# define SSL_TXT_LOW "LOW" +# define SSL_TXT_MEDIUM "MEDIUM" +# define SSL_TXT_HIGH "HIGH" +# define SSL_TXT_FIPS "FIPS" + +# define SSL_TXT_kFZA "kFZA"/* unused! */ +# define SSL_TXT_aFZA "aFZA"/* unused! */ +# define SSL_TXT_eFZA "eFZA"/* unused! */ +# define SSL_TXT_FZA "FZA"/* unused! */ + +# define SSL_TXT_aNULL "aNULL" +# define SSL_TXT_eNULL "eNULL" +# define SSL_TXT_NULL "NULL" + +# define SSL_TXT_kRSA "kRSA" +# define SSL_TXT_kDHr "kDHr"/* no such ciphersuites supported! */ +# define SSL_TXT_kDHd "kDHd"/* no such ciphersuites supported! */ +# define SSL_TXT_kDH "kDH"/* no such ciphersuites supported! */ +# define SSL_TXT_kEDH "kEDH" +# define SSL_TXT_kKRB5 "kKRB5" +# define SSL_TXT_kECDHr "kECDHr" +# define SSL_TXT_kECDHe "kECDHe" +# define SSL_TXT_kECDH "kECDH" +# define SSL_TXT_kEECDH "kEECDH" +# define SSL_TXT_kPSK "kPSK" +# define SSL_TXT_kGOST "kGOST" +# define SSL_TXT_kSRP "kSRP" + +# define SSL_TXT_aRSA "aRSA" +# define SSL_TXT_aDSS "aDSS" +# define SSL_TXT_aDH "aDH"/* no such ciphersuites supported! */ +# define SSL_TXT_aECDH "aECDH" +# define SSL_TXT_aKRB5 "aKRB5" +# define SSL_TXT_aECDSA "aECDSA" +# define SSL_TXT_aPSK "aPSK" +# define SSL_TXT_aGOST94 "aGOST94" +# define SSL_TXT_aGOST01 "aGOST01" +# define SSL_TXT_aGOST "aGOST" +# define SSL_TXT_aSRP "aSRP" + +# define SSL_TXT_DSS "DSS" +# define SSL_TXT_DH "DH" +# define SSL_TXT_EDH "EDH"/* same as "kEDH:-ADH" */ +# define SSL_TXT_ADH "ADH" +# define SSL_TXT_RSA "RSA" +# define SSL_TXT_ECDH "ECDH" +# define SSL_TXT_EECDH "EECDH"/* same as "kEECDH:-AECDH" */ +# define SSL_TXT_AECDH "AECDH" +# define SSL_TXT_ECDSA "ECDSA" +# define SSL_TXT_KRB5 "KRB5" +# define SSL_TXT_PSK "PSK" +# define SSL_TXT_SRP "SRP" + +# define SSL_TXT_DES "DES" +# define SSL_TXT_3DES "3DES" +# define SSL_TXT_RC4 "RC4" +# define SSL_TXT_RC2 "RC2" +# define SSL_TXT_IDEA "IDEA" +# define SSL_TXT_SEED "SEED" +# define SSL_TXT_AES128 "AES128" +# define SSL_TXT_AES256 "AES256" +# define SSL_TXT_AES "AES" +# define SSL_TXT_AES_GCM "AESGCM" +# define SSL_TXT_CAMELLIA128 "CAMELLIA128" +# define SSL_TXT_CAMELLIA256 "CAMELLIA256" +# define SSL_TXT_CAMELLIA "CAMELLIA" + +# define SSL_TXT_MD5 "MD5" +# define SSL_TXT_SHA1 "SHA1" +# define SSL_TXT_SHA "SHA"/* same as "SHA1" */ +# define SSL_TXT_GOST94 "GOST94" +# define SSL_TXT_GOST89MAC "GOST89MAC" +# define SSL_TXT_SHA256 "SHA256" +# define SSL_TXT_SHA384 "SHA384" + +# define SSL_TXT_SSLV2 "SSLv2" +# define SSL_TXT_SSLV3 "SSLv3" +# define SSL_TXT_TLSV1 "TLSv1" +# define SSL_TXT_TLSV1_1 "TLSv1.1" +# define SSL_TXT_TLSV1_2 "TLSv1.2" + +# define SSL_TXT_EXP "EXP" +# define SSL_TXT_EXPORT "EXPORT" + +# define SSL_TXT_ALL "ALL" + +/*- + * COMPLEMENTOF* definitions. These identifiers are used to (de-select) + * ciphers normally not being used. + * Example: "RC4" will activate all ciphers using RC4 including ciphers + * without authentication, which would normally disabled by DEFAULT (due + * the "!ADH" being part of default). Therefore "RC4:!COMPLEMENTOFDEFAULT" + * will make sure that it is also disabled in the specific selection. + * COMPLEMENTOF* identifiers are portable between version, as adjustments + * to the default cipher setup will also be included here. + * + * COMPLEMENTOFDEFAULT does not experience the same special treatment that + * DEFAULT gets, as only selection is being done and no sorting as needed + * for DEFAULT. + */ +# define SSL_TXT_CMPALL "COMPLEMENTOFALL" +# define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" + +/* + * The following cipher list is used by default. It also is substituted when + * an application-defined cipher list string starts with 'DEFAULT'. + */ +# define SSL_DEFAULT_CIPHER_LIST "ALL:!EXPORT:!LOW:!aNULL:!eNULL:!SSLv2" +/* + * As of OpenSSL 1.0.0, ssl_create_cipher_list() in ssl/ssl_ciph.c always + * starts with a reasonable order, and all we have to do for DEFAULT is + * throwing out anonymous and unencrypted ciphersuites! (The latter are not + * actually enabled by ALL, but "ALL:RSA" would enable some of them.) + */ + +/* Used in SSL_set_shutdown()/SSL_get_shutdown(); */ +# define SSL_SENT_SHUTDOWN 1 +# define SSL_RECEIVED_SHUTDOWN 2 + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +# if (defined(OPENSSL_NO_RSA) || defined(OPENSSL_NO_MD5)) && !defined(OPENSSL_NO_SSL2) +# define OPENSSL_NO_SSL2 +# endif + +# define SSL_FILETYPE_ASN1 X509_FILETYPE_ASN1 +# define SSL_FILETYPE_PEM X509_FILETYPE_PEM + +/* + * This is needed to stop compilers complaining about the 'struct ssl_st *' + * function parameters used to prototype callbacks in SSL_CTX. + */ +typedef struct ssl_st *ssl_crock_st; +typedef struct tls_session_ticket_ext_st TLS_SESSION_TICKET_EXT; +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_cipher_st SSL_CIPHER; +typedef struct ssl_session_st SSL_SESSION; + +DECLARE_STACK_OF(SSL_CIPHER) + +/* SRTP protection profiles for use with the use_srtp extension (RFC 5764)*/ +typedef struct srtp_protection_profile_st { + const char *name; + unsigned long id; +} SRTP_PROTECTION_PROFILE; + +DECLARE_STACK_OF(SRTP_PROTECTION_PROFILE) + +typedef int (*tls_session_ticket_ext_cb_fn) (SSL *s, + const unsigned char *data, + int len, void *arg); +typedef int (*tls_session_secret_cb_fn) (SSL *s, void *secret, + int *secret_len, + STACK_OF(SSL_CIPHER) *peer_ciphers, + SSL_CIPHER **cipher, void *arg); + +# ifndef OPENSSL_NO_SSL_INTERN + +/* used to hold info on the particular ciphers used */ +struct ssl_cipher_st { + int valid; + const char *name; /* text name */ + unsigned long id; /* id, 4 bytes, first is version */ + /* + * changed in 0.9.9: these four used to be portions of a single value + * 'algorithms' + */ + unsigned long algorithm_mkey; /* key exchange algorithm */ + unsigned long algorithm_auth; /* server authentication */ + unsigned long algorithm_enc; /* symmetric encryption */ + unsigned long algorithm_mac; /* symmetric authentication */ + unsigned long algorithm_ssl; /* (major) protocol version */ + unsigned long algo_strength; /* strength and export flags */ + unsigned long algorithm2; /* Extra flags */ + int strength_bits; /* Number of bits really used */ + int alg_bits; /* Number of bits for algorithm */ +}; + +/* Used to hold functions for SSLv2 or SSLv3/TLSv1 functions */ +struct ssl_method_st { + int version; + int (*ssl_new) (SSL *s); + void (*ssl_clear) (SSL *s); + void (*ssl_free) (SSL *s); + int (*ssl_accept) (SSL *s); + int (*ssl_connect) (SSL *s); + int (*ssl_read) (SSL *s, void *buf, int len); + int (*ssl_peek) (SSL *s, void *buf, int len); + int (*ssl_write) (SSL *s, const void *buf, int len); + int (*ssl_shutdown) (SSL *s); + int (*ssl_renegotiate) (SSL *s); + int (*ssl_renegotiate_check) (SSL *s); + long (*ssl_get_message) (SSL *s, int st1, int stn, int mt, long + max, int *ok); + int (*ssl_read_bytes) (SSL *s, int type, unsigned char *buf, int len, + int peek); + int (*ssl_write_bytes) (SSL *s, int type, const void *buf_, int len); + int (*ssl_dispatch_alert) (SSL *s); + long (*ssl_ctrl) (SSL *s, int cmd, long larg, void *parg); + long (*ssl_ctx_ctrl) (SSL_CTX *ctx, int cmd, long larg, void *parg); + const SSL_CIPHER *(*get_cipher_by_char) (const unsigned char *ptr); + int (*put_cipher_by_char) (const SSL_CIPHER *cipher, unsigned char *ptr); + int (*ssl_pending) (const SSL *s); + int (*num_ciphers) (void); + const SSL_CIPHER *(*get_cipher) (unsigned ncipher); + const struct ssl_method_st *(*get_ssl_method) (int version); + long (*get_timeout) (void); + struct ssl3_enc_method *ssl3_enc; /* Extra SSLv3/TLS stuff */ + int (*ssl_version) (void); + long (*ssl_callback_ctrl) (SSL *s, int cb_id, void (*fp) (void)); + long (*ssl_ctx_callback_ctrl) (SSL_CTX *s, int cb_id, void (*fp) (void)); +}; + +/*- + * Lets make this into an ASN.1 type structure as follows + * SSL_SESSION_ID ::= SEQUENCE { + * version INTEGER, -- structure version number + * SSLversion INTEGER, -- SSL version number + * Cipher OCTET STRING, -- the 3 byte cipher ID + * Session_ID OCTET STRING, -- the Session ID + * Master_key OCTET STRING, -- the master key + * KRB5_principal OCTET STRING -- optional Kerberos principal + * Key_Arg [ 0 ] IMPLICIT OCTET STRING, -- the optional Key argument + * Time [ 1 ] EXPLICIT INTEGER, -- optional Start Time + * Timeout [ 2 ] EXPLICIT INTEGER, -- optional Timeout ins seconds + * Peer [ 3 ] EXPLICIT X509, -- optional Peer Certificate + * Session_ID_context [ 4 ] EXPLICIT OCTET STRING, -- the Session ID context + * Verify_result [ 5 ] EXPLICIT INTEGER, -- X509_V_... code for `Peer' + * HostName [ 6 ] EXPLICIT OCTET STRING, -- optional HostName from servername TLS extension + * PSK_identity_hint [ 7 ] EXPLICIT OCTET STRING, -- optional PSK identity hint + * PSK_identity [ 8 ] EXPLICIT OCTET STRING, -- optional PSK identity + * Ticket_lifetime_hint [9] EXPLICIT INTEGER, -- server's lifetime hint for session ticket + * Ticket [10] EXPLICIT OCTET STRING, -- session ticket (clients only) + * Compression_meth [11] EXPLICIT OCTET STRING, -- optional compression method + * SRP_username [ 12 ] EXPLICIT OCTET STRING -- optional SRP username + * } + * Look in ssl/ssl_asn1.c for more details + * I'm using EXPLICIT tags so I can read the damn things using asn1parse :-). + */ +struct ssl_session_st { + int ssl_version; /* what ssl version session info is being + * kept in here? */ + /* only really used in SSLv2 */ + unsigned int key_arg_length; + unsigned char key_arg[SSL_MAX_KEY_ARG_LENGTH]; + int master_key_length; + unsigned char master_key[SSL_MAX_MASTER_KEY_LENGTH]; + /* session_id - valid? */ + unsigned int session_id_length; + unsigned char session_id[SSL_MAX_SSL_SESSION_ID_LENGTH]; + /* + * this is used to determine whether the session is being reused in the + * appropriate context. It is up to the application to set this, via + * SSL_new + */ + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; +# ifndef OPENSSL_NO_KRB5 + unsigned int krb5_client_princ_len; + unsigned char krb5_client_princ[SSL_MAX_KRB5_PRINCIPAL_LENGTH]; +# endif /* OPENSSL_NO_KRB5 */ +# ifndef OPENSSL_NO_PSK + char *psk_identity_hint; + char *psk_identity; +# endif + /* + * Used to indicate that session resumption is not allowed. Applications + * can also set this bit for a new session via not_resumable_session_cb + * to disable session caching and tickets. + */ + int not_resumable; + /* The cert is the certificate used to establish this connection */ + struct sess_cert_st /* SESS_CERT */ *sess_cert; + /* + * This is the cert for the other end. On clients, it will be the same as + * sess_cert->peer_key->x509 (the latter is not enough as sess_cert is + * not retained in the external representation of sessions, see + * ssl_asn1.c). + */ + X509 *peer; + /* + * when app_verify_callback accepts a session where the peer's + * certificate is not ok, we must remember the error for session reuse: + */ + long verify_result; /* only for servers */ + int references; + long timeout; + long time; + unsigned int compress_meth; /* Need to lookup the method */ + const SSL_CIPHER *cipher; + unsigned long cipher_id; /* when ASN.1 loaded, this needs to be used + * to load the 'cipher' structure */ + STACK_OF(SSL_CIPHER) *ciphers; /* shared ciphers? */ + CRYPTO_EX_DATA ex_data; /* application specific data */ + /* + * These are used to make removal of session-ids more efficient and to + * implement a maximum cache size. + */ + struct ssl_session_st *prev, *next; +# ifndef OPENSSL_NO_TLSEXT + char *tlsext_hostname; +# ifndef OPENSSL_NO_EC + size_t tlsext_ecpointformatlist_length; + unsigned char *tlsext_ecpointformatlist; /* peer's list */ + size_t tlsext_ellipticcurvelist_length; + unsigned char *tlsext_ellipticcurvelist; /* peer's list */ +# endif /* OPENSSL_NO_EC */ + /* RFC4507 info */ + unsigned char *tlsext_tick; /* Session ticket */ + size_t tlsext_ticklen; /* Session ticket length */ + long tlsext_tick_lifetime_hint; /* Session lifetime hint in seconds */ +# endif +# ifndef OPENSSL_NO_SRP + char *srp_username; +# endif +}; + +# endif + +# define SSL_OP_MICROSOFT_SESS_ID_BUG 0x00000001L +# define SSL_OP_NETSCAPE_CHALLENGE_BUG 0x00000002L +/* Allow initial connection to servers that don't support RI */ +# define SSL_OP_LEGACY_SERVER_CONNECT 0x00000004L +# define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0x00000008L +# define SSL_OP_TLSEXT_PADDING 0x00000010L +# define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0x00000020L +# define SSL_OP_SAFARI_ECDHE_ECDSA_BUG 0x00000040L +# define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0x00000080L +# define SSL_OP_TLS_D5_BUG 0x00000100L +# define SSL_OP_TLS_BLOCK_PADDING_BUG 0x00000200L + +/* Hasn't done anything since OpenSSL 0.9.7h, retained for compatibility */ +# define SSL_OP_MSIE_SSLV2_RSA_PADDING 0x0 +/* Refers to ancient SSLREF and SSLv2, retained for compatibility */ +# define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0x0 + +/* + * Disable SSL 3.0/TLS 1.0 CBC vulnerability workaround that was added in + * OpenSSL 0.9.6d. Usually (depending on the application protocol) the + * workaround is not needed. Unfortunately some broken SSL/TLS + * implementations cannot handle it at all, which is why we include it in + * SSL_OP_ALL. + */ +/* added in 0.9.6e */ +# define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0x00000800L + +/* + * SSL_OP_ALL: various bug workarounds that should be rather harmless. This + * used to be 0x000FFFFFL before 0.9.7. + */ +# define SSL_OP_ALL 0x80000BFFL + +/* DTLS options */ +# define SSL_OP_NO_QUERY_MTU 0x00001000L +/* Turn on Cookie Exchange (on relevant for servers) */ +# define SSL_OP_COOKIE_EXCHANGE 0x00002000L +/* Don't use RFC4507 ticket extension */ +# define SSL_OP_NO_TICKET 0x00004000L +/* Use Cisco's "speshul" version of DTLS_BAD_VER (as client) */ +# define SSL_OP_CISCO_ANYCONNECT 0x00008000L + +/* As server, disallow session resumption on renegotiation */ +# define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0x00010000L +/* Don't use compression even if supported */ +# define SSL_OP_NO_COMPRESSION 0x00020000L +/* Permit unsafe legacy renegotiation */ +# define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0x00040000L +/* If set, always create a new key when using tmp_ecdh parameters */ +# define SSL_OP_SINGLE_ECDH_USE 0x00080000L +/* Does nothing: retained for compatibility */ +# define SSL_OP_SINGLE_DH_USE 0x00100000L +/* Does nothing: retained for compatibiity */ +# define SSL_OP_EPHEMERAL_RSA 0x0 +/* + * Set on servers to choose the cipher according to the server's preferences + */ +# define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L +/* + * If set, a server will allow a client to issue a SSLv3.0 version number as + * latest version supported in the premaster secret, even when TLSv1.0 + * (version 3.1) was announced in the client hello. Normally this is + * forbidden to prevent version rollback attacks. + */ +# define SSL_OP_TLS_ROLLBACK_BUG 0x00800000L + +# define SSL_OP_NO_SSLv2 0x01000000L +# define SSL_OP_NO_SSLv3 0x02000000L +# define SSL_OP_NO_TLSv1 0x04000000L +# define SSL_OP_NO_TLSv1_2 0x08000000L +# define SSL_OP_NO_TLSv1_1 0x10000000L + +/* + * These next two were never actually used for anything since SSLeay zap so + * we have some more flags. + */ +/* + * The next flag deliberately changes the ciphertest, this is a check for the + * PKCS#1 attack + */ +# define SSL_OP_PKCS1_CHECK_1 0x0 +# define SSL_OP_PKCS1_CHECK_2 0x0 + +# define SSL_OP_NETSCAPE_CA_DN_BUG 0x20000000L +# define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0x40000000L +/* + * Make server add server-hello extension from early version of cryptopro + * draft, when GOST ciphersuite is negotiated. Required for interoperability + * with CryptoPro CSP 3.x + */ +# define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0x80000000L + +/* + * Allow SSL_write(..., n) to return r with 0 < r < n (i.e. report success + * when just a single record has been written): + */ +# define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L +/* + * Make it possible to retry SSL_write() with changed buffer location (buffer + * contents must stay the same!); this is not the default to avoid the + * misconception that non-blocking SSL_write() behaves like non-blocking + * write(): + */ +# define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L +/* + * Never bother the application with retries if the transport is blocking: + */ +# define SSL_MODE_AUTO_RETRY 0x00000004L +/* Don't attempt to automatically build certificate chain */ +# define SSL_MODE_NO_AUTO_CHAIN 0x00000008L +/* + * Save RAM by releasing read and write buffers when they're empty. (SSL3 and + * TLS only.) "Released" buffers are put onto a free-list in the context or + * just freed (depending on the context's setting for freelist_max_len). + */ +# define SSL_MODE_RELEASE_BUFFERS 0x00000010L +/* + * Send the current time in the Random fields of the ClientHello and + * ServerHello records for compatibility with hypothetical implementations + * that require it. + */ +# define SSL_MODE_SEND_CLIENTHELLO_TIME 0x00000020L +# define SSL_MODE_SEND_SERVERHELLO_TIME 0x00000040L +/* + * Send TLS_FALLBACK_SCSV in the ClientHello. To be set only by applications + * that reconnect with a downgraded protocol version; see + * draft-ietf-tls-downgrade-scsv-00 for details. DO NOT ENABLE THIS if your + * application attempts a normal handshake. Only use this in explicit + * fallback retries, following the guidance in + * draft-ietf-tls-downgrade-scsv-00. + */ +# define SSL_MODE_SEND_FALLBACK_SCSV 0x00000080L + +/* + * Note: SSL[_CTX]_set_{options,mode} use |= op on the previous value, they + * cannot be used to clear bits. + */ + +# define SSL_CTX_set_options(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,(op),NULL) +# define SSL_CTX_clear_options(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) +# define SSL_CTX_get_options(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_OPTIONS,0,NULL) +# define SSL_set_options(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_OPTIONS,(op),NULL) +# define SSL_clear_options(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_OPTIONS,(op),NULL) +# define SSL_get_options(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_OPTIONS,0,NULL) + +# define SSL_CTX_set_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,(op),NULL) +# define SSL_CTX_clear_mode(ctx,op) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_CLEAR_MODE,(op),NULL) +# define SSL_CTX_get_mode(ctx) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_MODE,0,NULL) +# define SSL_clear_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_MODE,(op),NULL) +# define SSL_set_mode(ssl,op) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,(op),NULL) +# define SSL_get_mode(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_MODE,0,NULL) +# define SSL_set_mtu(ssl, mtu) \ + SSL_ctrl((ssl),SSL_CTRL_SET_MTU,(mtu),NULL) +# define DTLS_set_link_mtu(ssl, mtu) \ + SSL_ctrl((ssl),DTLS_CTRL_SET_LINK_MTU,(mtu),NULL) +# define DTLS_get_link_min_mtu(ssl) \ + SSL_ctrl((ssl),DTLS_CTRL_GET_LINK_MIN_MTU,0,NULL) + +# define SSL_get_secure_renegotiation_support(ssl) \ + SSL_ctrl((ssl), SSL_CTRL_GET_RI_SUPPORT, 0, NULL) + +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_heartbeat(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_TLS_EXT_SEND_HEARTBEAT,0,NULL) +# endif + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); +void SSL_set_msg_callback(SSL *ssl, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)); +# define SSL_CTX_set_msg_callback_arg(ctx, arg) SSL_CTX_ctrl((ctx), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) +# define SSL_set_msg_callback_arg(ssl, arg) SSL_ctrl((ssl), SSL_CTRL_SET_MSG_CALLBACK_ARG, 0, (arg)) + +# ifndef OPENSSL_NO_SRP + +# ifndef OPENSSL_NO_SSL_INTERN + +typedef struct srp_ctx_st { + /* param for all the callbacks */ + void *SRP_cb_arg; + /* set client Hello login callback */ + int (*TLS_ext_srp_username_callback) (SSL *, int *, void *); + /* set SRP N/g param callback for verification */ + int (*SRP_verify_param_callback) (SSL *, void *); + /* set SRP client passwd callback */ + char *(*SRP_give_srp_client_pwd_callback) (SSL *, void *); + char *login; + BIGNUM *N, *g, *s, *B, *A; + BIGNUM *a, *b, *v; + char *info; + int strength; + unsigned long srp_Mask; +} SRP_CTX; + +# endif + +/* see tls_srp.c */ +int SSL_SRP_CTX_init(SSL *s); +int SSL_CTX_SRP_CTX_init(SSL_CTX *ctx); +int SSL_SRP_CTX_free(SSL *ctx); +int SSL_CTX_SRP_CTX_free(SSL_CTX *ctx); +int SSL_srp_server_param_with_username(SSL *s, int *ad); +int SRP_generate_server_master_secret(SSL *s, unsigned char *master_key); +int SRP_Calc_A_param(SSL *s); +int SRP_generate_client_master_secret(SSL *s, unsigned char *master_key); + +# endif + +# if defined(OPENSSL_SYS_MSDOS) && !defined(OPENSSL_SYS_WIN32) +# define SSL_MAX_CERT_LIST_DEFAULT 1024*30 + /* 30k max cert list :-) */ +# else +# define SSL_MAX_CERT_LIST_DEFAULT 1024*100 + /* 100k max cert list :-) */ +# endif + +# define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024*20) + +/* + * This callback type is used inside SSL_CTX, SSL, and in the functions that + * set them. It is used to override the generation of SSL/TLS session IDs in + * a server. Return value should be zero on an error, non-zero to proceed. + * Also, callbacks should themselves check if the id they generate is unique + * otherwise the SSL handshake will fail with an error - callbacks can do + * this using the 'ssl' value they're passed by; + * SSL_has_matching_session_id(ssl, id, *id_len) The length value passed in + * is set at the maximum size the session ID can be. In SSLv2 this is 16 + * bytes, whereas SSLv3/TLSv1 it is 32 bytes. The callback can alter this + * length to be less if desired, but under SSLv2 session IDs are supposed to + * be fixed at 16 bytes so the id will be padded after the callback returns + * in this case. It is also an error for the callback to set the size to + * zero. + */ +typedef int (*GEN_SESSION_CB) (const SSL *ssl, unsigned char *id, + unsigned int *id_len); + +typedef struct ssl_comp_st SSL_COMP; + +# ifndef OPENSSL_NO_SSL_INTERN + +struct ssl_comp_st { + int id; + const char *name; +# ifndef OPENSSL_NO_COMP + COMP_METHOD *method; +# else + char *method; +# endif +}; + +DECLARE_STACK_OF(SSL_COMP) +DECLARE_LHASH_OF(SSL_SESSION); + +struct ssl_ctx_st { + const SSL_METHOD *method; + STACK_OF(SSL_CIPHER) *cipher_list; + /* same as above but sorted for lookup */ + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + struct x509_store_st /* X509_STORE */ *cert_store; + LHASH_OF(SSL_SESSION) *sessions; + /* + * Most session-ids that will be cached, default is + * SSL_SESSION_CACHE_MAX_SIZE_DEFAULT. 0 is unlimited. + */ + unsigned long session_cache_size; + struct ssl_session_st *session_cache_head; + struct ssl_session_st *session_cache_tail; + /* + * This can have one of 2 values, ored together, SSL_SESS_CACHE_CLIENT, + * SSL_SESS_CACHE_SERVER, Default is SSL_SESSION_CACHE_SERVER, which + * means only SSL_accept which cache SSL_SESSIONS. + */ + int session_cache_mode; + /* + * If timeout is not 0, it is the default timeout value set when + * SSL_new() is called. This has been put in to make life easier to set + * things up + */ + long session_timeout; + /* + * If this callback is not null, it will be called each time a session id + * is added to the cache. If this function returns 1, it means that the + * callback will do a SSL_SESSION_free() when it has finished using it. + * Otherwise, on 0, it means the callback has finished with it. If + * remove_session_cb is not null, it will be called when a session-id is + * removed from the cache. After the call, OpenSSL will + * SSL_SESSION_free() it. + */ + int (*new_session_cb) (struct ssl_st *ssl, SSL_SESSION *sess); + void (*remove_session_cb) (struct ssl_ctx_st *ctx, SSL_SESSION *sess); + SSL_SESSION *(*get_session_cb) (struct ssl_st *ssl, + unsigned char *data, int len, int *copy); + struct { + int sess_connect; /* SSL new conn - started */ + int sess_connect_renegotiate; /* SSL reneg - requested */ + int sess_connect_good; /* SSL new conne/reneg - finished */ + int sess_accept; /* SSL new accept - started */ + int sess_accept_renegotiate; /* SSL reneg - requested */ + int sess_accept_good; /* SSL accept/reneg - finished */ + int sess_miss; /* session lookup misses */ + int sess_timeout; /* reuse attempt on timeouted session */ + int sess_cache_full; /* session removed due to full cache */ + int sess_hit; /* session reuse actually done */ + int sess_cb_hit; /* session-id that was not in the cache was + * passed back via the callback. This + * indicates that the application is + * supplying session-id's from other + * processes - spooky :-) */ + } stats; + + int references; + + /* if defined, these override the X509_verify_cert() calls */ + int (*app_verify_callback) (X509_STORE_CTX *, void *); + void *app_verify_arg; + /* + * before OpenSSL 0.9.7, 'app_verify_arg' was ignored + * ('app_verify_callback' was called with just one argument) + */ + + /* Default password callback. */ + pem_password_cb *default_passwd_callback; + + /* Default password callback user data. */ + void *default_passwd_callback_userdata; + + /* get client cert callback */ + int (*client_cert_cb) (SSL *ssl, X509 **x509, EVP_PKEY **pkey); + + /* cookie generate callback */ + int (*app_gen_cookie_cb) (SSL *ssl, unsigned char *cookie, + unsigned int *cookie_len); + + /* verify cookie callback */ + int (*app_verify_cookie_cb) (SSL *ssl, unsigned char *cookie, + unsigned int cookie_len); + + CRYPTO_EX_DATA ex_data; + + const EVP_MD *rsa_md5; /* For SSLv2 - name is 'ssl2-md5' */ + const EVP_MD *md5; /* For SSLv3/TLSv1 'ssl3-md5' */ + const EVP_MD *sha1; /* For SSLv3/TLSv1 'ssl3->sha1' */ + + STACK_OF(X509) *extra_certs; + STACK_OF(SSL_COMP) *comp_methods; /* stack of SSL_COMP, SSLv3/TLSv1 */ + + /* Default values used when no per-SSL value is defined follow */ + + /* used if SSL's info_callback is NULL */ + void (*info_callback) (const SSL *ssl, int type, int val); + + /* what we put in client cert requests */ + STACK_OF(X509_NAME) *client_CA; + + /* + * Default values to use in SSL structures follow (these are copied by + * SSL_new) + */ + + unsigned long options; + unsigned long mode; + long max_cert_list; + + struct cert_st /* CERT */ *cert; + int read_ahead; + + /* callback that allows applications to peek at protocol messages */ + void (*msg_callback) (int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); + void *msg_callback_arg; + + int verify_mode; + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + /* called 'verify_callback' in the SSL */ + int (*default_verify_callback) (int ok, X509_STORE_CTX *ctx); + + /* Default generate session ID callback. */ + GEN_SESSION_CB generate_session_id; + + X509_VERIFY_PARAM *param; + +# if 0 + int purpose; /* Purpose setting */ + int trust; /* Trust setting */ +# endif + + int quiet_shutdown; + + /* + * Maximum amount of data to send in one fragment. actual record size can + * be more than this due to padding and MAC overheads. + */ + unsigned int max_send_fragment; + +# ifndef OPENSSL_NO_ENGINE + /* + * Engine to pass requests for client certs to + */ + ENGINE *client_cert_engine; +# endif + +# ifndef OPENSSL_NO_TLSEXT + /* TLS extensions servername callback */ + int (*tlsext_servername_callback) (SSL *, int *, void *); + void *tlsext_servername_arg; + /* RFC 4507 session ticket keys */ + unsigned char tlsext_tick_key_name[16]; + unsigned char tlsext_tick_hmac_key[16]; + unsigned char tlsext_tick_aes_key[16]; + /* Callback to support customisation of ticket key setting */ + int (*tlsext_ticket_key_cb) (SSL *ssl, + unsigned char *name, unsigned char *iv, + EVP_CIPHER_CTX *ectx, + HMAC_CTX *hctx, int enc); + + /* certificate status request info */ + /* Callback for status request */ + int (*tlsext_status_cb) (SSL *ssl, void *arg); + void *tlsext_status_arg; + + /* draft-rescorla-tls-opaque-prf-input-00.txt information */ + int (*tlsext_opaque_prf_input_callback) (SSL *, void *peerinput, + size_t len, void *arg); + void *tlsext_opaque_prf_input_callback_arg; +# endif + +# ifndef OPENSSL_NO_PSK + char *psk_identity_hint; + unsigned int (*psk_client_callback) (SSL *ssl, const char *hint, + char *identity, + unsigned int max_identity_len, + unsigned char *psk, + unsigned int max_psk_len); + unsigned int (*psk_server_callback) (SSL *ssl, const char *identity, + unsigned char *psk, + unsigned int max_psk_len); +# endif + +# ifndef OPENSSL_NO_BUF_FREELISTS +# define SSL_MAX_BUF_FREELIST_LEN_DEFAULT 32 + unsigned int freelist_max_len; + struct ssl3_buf_freelist_st *wbuf_freelist; + struct ssl3_buf_freelist_st *rbuf_freelist; +# endif +# ifndef OPENSSL_NO_SRP + SRP_CTX srp_ctx; /* ctx for SRP authentication */ +# endif + +# ifndef OPENSSL_NO_TLSEXT + +# ifndef OPENSSL_NO_NEXTPROTONEG + /* Next protocol negotiation information */ + /* (for experimental NPN extension). */ + + /* + * For a server, this contains a callback function by which the set of + * advertised protocols can be provided. + */ + int (*next_protos_advertised_cb) (SSL *s, const unsigned char **buf, + unsigned int *len, void *arg); + void *next_protos_advertised_cb_arg; + /* + * For a client, this contains a callback function that selects the next + * protocol from the list provided by the server. + */ + int (*next_proto_select_cb) (SSL *s, unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, void *arg); + void *next_proto_select_cb_arg; +# endif + /* SRTP profiles we are willing to do from RFC 5764 */ + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; +# endif +}; + +# endif + +# define SSL_SESS_CACHE_OFF 0x0000 +# define SSL_SESS_CACHE_CLIENT 0x0001 +# define SSL_SESS_CACHE_SERVER 0x0002 +# define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT|SSL_SESS_CACHE_SERVER) +# define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 +/* enough comments already ... see SSL_CTX_set_session_cache_mode(3) */ +# define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 +# define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 +# define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP|SSL_SESS_CACHE_NO_INTERNAL_STORE) + +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx); +# define SSL_CTX_sess_number(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_NUMBER,0,NULL) +# define SSL_CTX_sess_connect(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT,0,NULL) +# define SSL_CTX_sess_connect_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_GOOD,0,NULL) +# define SSL_CTX_sess_connect_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CONNECT_RENEGOTIATE,0,NULL) +# define SSL_CTX_sess_accept(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT,0,NULL) +# define SSL_CTX_sess_accept_renegotiate(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_RENEGOTIATE,0,NULL) +# define SSL_CTX_sess_accept_good(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_ACCEPT_GOOD,0,NULL) +# define SSL_CTX_sess_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_HIT,0,NULL) +# define SSL_CTX_sess_cb_hits(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CB_HIT,0,NULL) +# define SSL_CTX_sess_misses(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_MISSES,0,NULL) +# define SSL_CTX_sess_timeouts(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_TIMEOUTS,0,NULL) +# define SSL_CTX_sess_cache_full(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SESS_CACHE_FULL,0,NULL) + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*new_session_cb) (struct ssl_st *ssl, + SSL_SESSION *sess)); +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, + SSL_SESSION *sess); +void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, + void (*remove_session_cb) (struct ssl_ctx_st + *ctx, + SSL_SESSION + *sess)); +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (struct ssl_ctx_st *ctx, + SSL_SESSION *sess); +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*get_session_cb) (struct ssl_st + *ssl, + unsigned char + *data, int len, + int *copy)); +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (struct ssl_st *ssl, + unsigned char *Data, + int len, int *copy); +void SSL_CTX_set_info_callback(SSL_CTX *ctx, + void (*cb) (const SSL *ssl, int type, + int val)); +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type, + int val); +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, + int (*client_cert_cb) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey)); +int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey); +# ifndef OPENSSL_NO_ENGINE +int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e); +# endif +void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, + int (*app_gen_cookie_cb) (SSL *ssl, + unsigned char + *cookie, + unsigned int + *cookie_len)); +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, + int (*app_verify_cookie_cb) (SSL *ssl, + unsigned char + *cookie, + unsigned int + cookie_len)); +# ifndef OPENSSL_NO_NEXTPROTONEG +void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *s, + int (*cb) (SSL *ssl, + const unsigned char + **out, + unsigned int *outlen, + void *arg), void *arg); +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *s, + int (*cb) (SSL *ssl, + unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg), void *arg); + +int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *in, unsigned int inlen, + const unsigned char *client, + unsigned int client_len); +void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, + unsigned *len); + +# define OPENSSL_NPN_UNSUPPORTED 0 +# define OPENSSL_NPN_NEGOTIATED 1 +# define OPENSSL_NPN_NO_OVERLAP 2 +# endif + +# ifndef OPENSSL_NO_PSK +/* + * the maximum length of the buffer given to callbacks containing the + * resulting identity/psk + */ +# define PSK_MAX_IDENTITY_LEN 128 +# define PSK_MAX_PSK_LEN 256 +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, + unsigned int (*psk_client_callback) (SSL + *ssl, + const + char + *hint, + char + *identity, + unsigned + int + max_identity_len, + unsigned + char + *psk, + unsigned + int + max_psk_len)); +void SSL_set_psk_client_callback(SSL *ssl, + unsigned int (*psk_client_callback) (SSL + *ssl, + const + char + *hint, + char + *identity, + unsigned + int + max_identity_len, + unsigned + char + *psk, + unsigned + int + max_psk_len)); +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, + unsigned int (*psk_server_callback) (SSL + *ssl, + const + char + *identity, + unsigned + char + *psk, + unsigned + int + max_psk_len)); +void SSL_set_psk_server_callback(SSL *ssl, + unsigned int (*psk_server_callback) (SSL + *ssl, + const + char + *identity, + unsigned + char + *psk, + unsigned + int + max_psk_len)); +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint); +int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint); +const char *SSL_get_psk_identity_hint(const SSL *s); +const char *SSL_get_psk_identity(const SSL *s); +# endif + +# define SSL_NOTHING 1 +# define SSL_WRITING 2 +# define SSL_READING 3 +# define SSL_X509_LOOKUP 4 + +/* These will only be used when doing non-blocking IO */ +# define SSL_want_nothing(s) (SSL_want(s) == SSL_NOTHING) +# define SSL_want_read(s) (SSL_want(s) == SSL_READING) +# define SSL_want_write(s) (SSL_want(s) == SSL_WRITING) +# define SSL_want_x509_lookup(s) (SSL_want(s) == SSL_X509_LOOKUP) + +# define SSL_MAC_FLAG_READ_MAC_STREAM 1 +# define SSL_MAC_FLAG_WRITE_MAC_STREAM 2 + +# ifndef OPENSSL_NO_SSL_INTERN + +struct ssl_st { + /* + * protocol version (one of SSL2_VERSION, SSL3_VERSION, TLS1_VERSION, + * DTLS1_VERSION) + */ + int version; + /* SSL_ST_CONNECT or SSL_ST_ACCEPT */ + int type; + /* SSLv3 */ + const SSL_METHOD *method; + /* + * There are 2 BIO's even though they are normally both the same. This + * is so data can be read and written to different handlers + */ +# ifndef OPENSSL_NO_BIO + /* used by SSL_read */ + BIO *rbio; + /* used by SSL_write */ + BIO *wbio; + /* used during session-id reuse to concatenate messages */ + BIO *bbio; +# else + /* used by SSL_read */ + char *rbio; + /* used by SSL_write */ + char *wbio; + char *bbio; +# endif + /* + * This holds a variable that indicates what we were doing when a 0 or -1 + * is returned. This is needed for non-blocking IO so we know what + * request needs re-doing when in SSL_accept or SSL_connect + */ + int rwstate; + /* true when we are actually in SSL_accept() or SSL_connect() */ + int in_handshake; + int (*handshake_func) (SSL *); + /* + * Imagine that here's a boolean member "init" that is switched as soon + * as SSL_set_{accept/connect}_state is called for the first time, so + * that "state" and "handshake_func" are properly initialized. But as + * handshake_func is == 0 until then, we use this test instead of an + * "init" member. + */ + /* are we the server side? - mostly used by SSL_clear */ + int server; + /* + * Generate a new session or reuse an old one. + * NB: For servers, the 'new' session may actually be a previously + * cached session or even the previous session unless + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION is set + */ + int new_session; + /* don't send shutdown packets */ + int quiet_shutdown; + /* we have shut things down, 0x01 sent, 0x02 for received */ + int shutdown; + /* where we are */ + int state; + /* where we are when reading */ + int rstate; + BUF_MEM *init_buf; /* buffer used during init */ + void *init_msg; /* pointer to handshake message body, set by + * ssl3_get_message() */ + int init_num; /* amount read/written */ + int init_off; /* amount read/written */ + /* used internally to point at a raw packet */ + unsigned char *packet; + unsigned int packet_length; + struct ssl2_state_st *s2; /* SSLv2 variables */ + struct ssl3_state_st *s3; /* SSLv3 variables */ + struct dtls1_state_st *d1; /* DTLSv1 variables */ + int read_ahead; /* Read as many input bytes as possible (for + * non-blocking reads) */ + /* callback that allows applications to peek at protocol messages */ + void (*msg_callback) (int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, void *arg); + void *msg_callback_arg; + int hit; /* reusing a previous session */ + X509_VERIFY_PARAM *param; +# if 0 + int purpose; /* Purpose setting */ + int trust; /* Trust setting */ +# endif + /* crypto */ + STACK_OF(SSL_CIPHER) *cipher_list; + STACK_OF(SSL_CIPHER) *cipher_list_by_id; + /* + * These are the ones being used, the ones in SSL_SESSION are the ones to + * be 'copied' into these ones + */ + int mac_flags; + EVP_CIPHER_CTX *enc_read_ctx; /* cryptographic state */ + EVP_MD_CTX *read_hash; /* used for mac generation */ +# ifndef OPENSSL_NO_COMP + COMP_CTX *expand; /* uncompress */ +# else + char *expand; +# endif + EVP_CIPHER_CTX *enc_write_ctx; /* cryptographic state */ + EVP_MD_CTX *write_hash; /* used for mac generation */ +# ifndef OPENSSL_NO_COMP + COMP_CTX *compress; /* compression */ +# else + char *compress; +# endif + /* session info */ + /* client cert? */ + /* This is used to hold the server certificate used */ + struct cert_st /* CERT */ *cert; + /* + * the session_id_context is used to ensure sessions are only reused in + * the appropriate context + */ + unsigned int sid_ctx_length; + unsigned char sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + /* This can also be in the session once a session is established */ + SSL_SESSION *session; + /* Default generate session ID callback. */ + GEN_SESSION_CB generate_session_id; + /* Used in SSL2 and SSL3 */ + /* + * 0 don't care about verify failure. + * 1 fail if verify fails + */ + int verify_mode; + /* fail if callback returns 0 */ + int (*verify_callback) (int ok, X509_STORE_CTX *ctx); + /* optional informational callback */ + void (*info_callback) (const SSL *ssl, int type, int val); + /* error bytes to be written */ + int error; + /* actual code */ + int error_code; +# ifndef OPENSSL_NO_KRB5 + /* Kerberos 5 context */ + KSSL_CTX *kssl_ctx; +# endif /* OPENSSL_NO_KRB5 */ +# ifndef OPENSSL_NO_PSK + unsigned int (*psk_client_callback) (SSL *ssl, const char *hint, + char *identity, + unsigned int max_identity_len, + unsigned char *psk, + unsigned int max_psk_len); + unsigned int (*psk_server_callback) (SSL *ssl, const char *identity, + unsigned char *psk, + unsigned int max_psk_len); +# endif + SSL_CTX *ctx; + /* + * set this flag to 1 and a sleep(1) is put into all SSL_read() and + * SSL_write() calls, good for nbio debuging :-) + */ + int debug; + /* extra application data */ + long verify_result; + CRYPTO_EX_DATA ex_data; + /* for server side, keep the list of CA_dn we can use */ + STACK_OF(X509_NAME) *client_CA; + int references; + /* protocol behaviour */ + unsigned long options; + /* API behaviour */ + unsigned long mode; + long max_cert_list; + int first_packet; + /* what was passed, used for SSLv3/TLS rollback check */ + int client_version; + unsigned int max_send_fragment; +# ifndef OPENSSL_NO_TLSEXT + /* TLS extension debug callback */ + void (*tlsext_debug_cb) (SSL *s, int client_server, int type, + unsigned char *data, int len, void *arg); + void *tlsext_debug_arg; + char *tlsext_hostname; + /*- + * no further mod of servername + * 0 : call the servername extension callback. + * 1 : prepare 2, allow last ack just after in server callback. + * 2 : don't call servername callback, no ack in server hello + */ + int servername_done; + /* certificate status request info */ + /* Status type or -1 if no status type */ + int tlsext_status_type; + /* Expect OCSP CertificateStatus message */ + int tlsext_status_expected; + /* OCSP status request only */ + STACK_OF(OCSP_RESPID) *tlsext_ocsp_ids; + X509_EXTENSIONS *tlsext_ocsp_exts; + /* OCSP response received or to be sent */ + unsigned char *tlsext_ocsp_resp; + int tlsext_ocsp_resplen; + /* RFC4507 session ticket expected to be received or sent */ + int tlsext_ticket_expected; +# ifndef OPENSSL_NO_EC + size_t tlsext_ecpointformatlist_length; + /* our list */ + unsigned char *tlsext_ecpointformatlist; + size_t tlsext_ellipticcurvelist_length; + /* our list */ + unsigned char *tlsext_ellipticcurvelist; +# endif /* OPENSSL_NO_EC */ + /* + * draft-rescorla-tls-opaque-prf-input-00.txt information to be used for + * handshakes + */ + void *tlsext_opaque_prf_input; + size_t tlsext_opaque_prf_input_len; + /* TLS Session Ticket extension override */ + TLS_SESSION_TICKET_EXT *tlsext_session_ticket; + /* TLS Session Ticket extension callback */ + tls_session_ticket_ext_cb_fn tls_session_ticket_ext_cb; + void *tls_session_ticket_ext_cb_arg; + /* TLS pre-shared secret session resumption */ + tls_session_secret_cb_fn tls_session_secret_cb; + void *tls_session_secret_cb_arg; + SSL_CTX *initial_ctx; /* initial ctx, used to store sessions */ +# ifndef OPENSSL_NO_NEXTPROTONEG + /* + * Next protocol negotiation. For the client, this is the protocol that + * we sent in NextProtocol and is set when handling ServerHello + * extensions. For a server, this is the client's selected_protocol from + * NextProtocol and is set when handling the NextProtocol message, before + * the Finished message. + */ + unsigned char *next_proto_negotiated; + unsigned char next_proto_negotiated_len; +# endif +# define session_ctx initial_ctx + /* What we'll do */ + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; + /* What's been chosen */ + SRTP_PROTECTION_PROFILE *srtp_profile; + /*- + * Is use of the Heartbeat extension negotiated? + * 0: disabled + * 1: enabled + * 2: enabled, but not allowed to send Requests + */ + unsigned int tlsext_heartbeat; + /* Indicates if a HeartbeatRequest is in flight */ + unsigned int tlsext_hb_pending; + /* HeartbeatRequest sequence number */ + unsigned int tlsext_hb_seq; +# else +# define session_ctx ctx +# endif /* OPENSSL_NO_TLSEXT */ + /*- + * 1 if we are renegotiating. + * 2 if we are a server and are inside a handshake + * (i.e. not just sending a HelloRequest) + */ + int renegotiate; +# ifndef OPENSSL_NO_SRP + /* ctx for SRP authentication */ + SRP_CTX srp_ctx; +# endif +}; + +# endif + +#ifdef __cplusplus +} +#endif + +# include +# include +# include /* This is mostly sslv3 with a few tweaks */ +# include /* Datagram TLS */ +# include +# include /* Support for the use_srtp extension */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* compatibility */ +# define SSL_set_app_data(s,arg) (SSL_set_ex_data(s,0,(char *)arg)) +# define SSL_get_app_data(s) (SSL_get_ex_data(s,0)) +# define SSL_SESSION_set_app_data(s,a) (SSL_SESSION_set_ex_data(s,0,(char *)a)) +# define SSL_SESSION_get_app_data(s) (SSL_SESSION_get_ex_data(s,0)) +# define SSL_CTX_get_app_data(ctx) (SSL_CTX_get_ex_data(ctx,0)) +# define SSL_CTX_set_app_data(ctx,arg) (SSL_CTX_set_ex_data(ctx,0,(char *)arg)) + +/* + * The following are the possible values for ssl->state are are used to + * indicate where we are up to in the SSL connection establishment. The + * macros that follow are about the only things you should need to use and + * even then, only when using non-blocking IO. It can also be useful to work + * out where you were when the connection failed + */ + +# define SSL_ST_CONNECT 0x1000 +# define SSL_ST_ACCEPT 0x2000 +# define SSL_ST_MASK 0x0FFF +# define SSL_ST_INIT (SSL_ST_CONNECT|SSL_ST_ACCEPT) +# define SSL_ST_BEFORE 0x4000 +# define SSL_ST_OK 0x03 +# define SSL_ST_RENEGOTIATE (0x04|SSL_ST_INIT) +# define SSL_ST_ERR 0x05 + +# define SSL_CB_LOOP 0x01 +# define SSL_CB_EXIT 0x02 +# define SSL_CB_READ 0x04 +# define SSL_CB_WRITE 0x08 +# define SSL_CB_ALERT 0x4000/* used in callback */ +# define SSL_CB_READ_ALERT (SSL_CB_ALERT|SSL_CB_READ) +# define SSL_CB_WRITE_ALERT (SSL_CB_ALERT|SSL_CB_WRITE) +# define SSL_CB_ACCEPT_LOOP (SSL_ST_ACCEPT|SSL_CB_LOOP) +# define SSL_CB_ACCEPT_EXIT (SSL_ST_ACCEPT|SSL_CB_EXIT) +# define SSL_CB_CONNECT_LOOP (SSL_ST_CONNECT|SSL_CB_LOOP) +# define SSL_CB_CONNECT_EXIT (SSL_ST_CONNECT|SSL_CB_EXIT) +# define SSL_CB_HANDSHAKE_START 0x10 +# define SSL_CB_HANDSHAKE_DONE 0x20 + +/* Is the SSL_connection established? */ +# define SSL_get_state(a) SSL_state(a) +# define SSL_is_init_finished(a) (SSL_state(a) == SSL_ST_OK) +# define SSL_in_init(a) (SSL_state(a)&SSL_ST_INIT) +# define SSL_in_before(a) (SSL_state(a)&SSL_ST_BEFORE) +# define SSL_in_connect_init(a) (SSL_state(a)&SSL_ST_CONNECT) +# define SSL_in_accept_init(a) (SSL_state(a)&SSL_ST_ACCEPT) + +/* + * The following 2 states are kept in ssl->rstate when reads fail, you should + * not need these + */ +# define SSL_ST_READ_HEADER 0xF0 +# define SSL_ST_READ_BODY 0xF1 +# define SSL_ST_READ_DONE 0xF2 + +/*- + * Obtain latest Finished message + * -- that we sent (SSL_get_finished) + * -- that we expected from peer (SSL_get_peer_finished). + * Returns length (0 == no Finished so far), copies up to 'count' bytes. + */ +size_t SSL_get_finished(const SSL *s, void *buf, size_t count); +size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count); + +/* + * use either SSL_VERIFY_NONE or SSL_VERIFY_PEER, the last 2 options are + * 'ored' with SSL_VERIFY_PEER if they are desired + */ +# define SSL_VERIFY_NONE 0x00 +# define SSL_VERIFY_PEER 0x01 +# define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 +# define SSL_VERIFY_CLIENT_ONCE 0x04 + +# define OpenSSL_add_ssl_algorithms() SSL_library_init() +# define SSLeay_add_ssl_algorithms() SSL_library_init() + +/* this is for backward compatibility */ +# if 0 /* NEW_SSLEAY */ +# define SSL_CTX_set_default_verify(a,b,c) SSL_CTX_set_verify(a,b,c) +# define SSL_set_pref_cipher(c,n) SSL_set_cipher_list(c,n) +# define SSL_add_session(a,b) SSL_CTX_add_session((a),(b)) +# define SSL_remove_session(a,b) SSL_CTX_remove_session((a),(b)) +# define SSL_flush_sessions(a,b) SSL_CTX_flush_sessions((a),(b)) +# endif +/* More backward compatibility */ +# define SSL_get_cipher(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +# define SSL_get_cipher_bits(s,np) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(s),np) +# define SSL_get_cipher_version(s) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(s)) +# define SSL_get_cipher_name(s) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(s)) +# define SSL_get_time(a) SSL_SESSION_get_time(a) +# define SSL_set_time(a,b) SSL_SESSION_set_time((a),(b)) +# define SSL_get_timeout(a) SSL_SESSION_get_timeout(a) +# define SSL_set_timeout(a,b) SSL_SESSION_set_timeout((a),(b)) + +# define d2i_SSL_SESSION_bio(bp,s_id) ASN1_d2i_bio_of(SSL_SESSION,SSL_SESSION_new,d2i_SSL_SESSION,bp,s_id) +# define i2d_SSL_SESSION_bio(bp,s_id) ASN1_i2d_bio_of(SSL_SESSION,i2d_SSL_SESSION,bp,s_id) + +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) +# define SSL_AD_REASON_OFFSET 1000/* offset to get SSL_R_... value + * from SSL_AD_... */ +/* These alert types are for SSLv3 and TLSv1 */ +# define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY +/* fatal */ +# define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE +/* fatal */ +# define SSL_AD_BAD_RECORD_MAC SSL3_AD_BAD_RECORD_MAC +# define SSL_AD_DECRYPTION_FAILED TLS1_AD_DECRYPTION_FAILED +# define SSL_AD_RECORD_OVERFLOW TLS1_AD_RECORD_OVERFLOW +/* fatal */ +# define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE +/* fatal */ +# define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE +/* Not for TLS */ +# define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE +# define SSL_AD_BAD_CERTIFICATE SSL3_AD_BAD_CERTIFICATE +# define SSL_AD_UNSUPPORTED_CERTIFICATE SSL3_AD_UNSUPPORTED_CERTIFICATE +# define SSL_AD_CERTIFICATE_REVOKED SSL3_AD_CERTIFICATE_REVOKED +# define SSL_AD_CERTIFICATE_EXPIRED SSL3_AD_CERTIFICATE_EXPIRED +# define SSL_AD_CERTIFICATE_UNKNOWN SSL3_AD_CERTIFICATE_UNKNOWN +/* fatal */ +# define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER +/* fatal */ +# define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA +/* fatal */ +# define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED +/* fatal */ +# define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR +# define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR +/* fatal */ +# define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION +/* fatal */ +# define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION +/* fatal */ +# define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY +/* fatal */ +# define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR +# define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED +# define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +# define SSL_AD_UNSUPPORTED_EXTENSION TLS1_AD_UNSUPPORTED_EXTENSION +# define SSL_AD_CERTIFICATE_UNOBTAINABLE TLS1_AD_CERTIFICATE_UNOBTAINABLE +# define SSL_AD_UNRECOGNIZED_NAME TLS1_AD_UNRECOGNIZED_NAME +# define SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE +# define SSL_AD_BAD_CERTIFICATE_HASH_VALUE TLS1_AD_BAD_CERTIFICATE_HASH_VALUE +/* fatal */ +# define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY +/* fatal */ +# define SSL_AD_INAPPROPRIATE_FALLBACK TLS1_AD_INAPPROPRIATE_FALLBACK +# define SSL_ERROR_NONE 0 +# define SSL_ERROR_SSL 1 +# define SSL_ERROR_WANT_READ 2 +# define SSL_ERROR_WANT_WRITE 3 +# define SSL_ERROR_WANT_X509_LOOKUP 4 +# define SSL_ERROR_SYSCALL 5/* look at error stack/return + * value/errno */ +# define SSL_ERROR_ZERO_RETURN 6 +# define SSL_ERROR_WANT_CONNECT 7 +# define SSL_ERROR_WANT_ACCEPT 8 +# define SSL_CTRL_NEED_TMP_RSA 1 +# define SSL_CTRL_SET_TMP_RSA 2 +# define SSL_CTRL_SET_TMP_DH 3 +# define SSL_CTRL_SET_TMP_ECDH 4 +# define SSL_CTRL_SET_TMP_RSA_CB 5 +# define SSL_CTRL_SET_TMP_DH_CB 6 +# define SSL_CTRL_SET_TMP_ECDH_CB 7 +# define SSL_CTRL_GET_SESSION_REUSED 8 +# define SSL_CTRL_GET_CLIENT_CERT_REQUEST 9 +# define SSL_CTRL_GET_NUM_RENEGOTIATIONS 10 +# define SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS 11 +# define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS 12 +# define SSL_CTRL_GET_FLAGS 13 +# define SSL_CTRL_EXTRA_CHAIN_CERT 14 +# define SSL_CTRL_SET_MSG_CALLBACK 15 +# define SSL_CTRL_SET_MSG_CALLBACK_ARG 16 +/* only applies to datagram connections */ +# define SSL_CTRL_SET_MTU 17 +/* Stats */ +# define SSL_CTRL_SESS_NUMBER 20 +# define SSL_CTRL_SESS_CONNECT 21 +# define SSL_CTRL_SESS_CONNECT_GOOD 22 +# define SSL_CTRL_SESS_CONNECT_RENEGOTIATE 23 +# define SSL_CTRL_SESS_ACCEPT 24 +# define SSL_CTRL_SESS_ACCEPT_GOOD 25 +# define SSL_CTRL_SESS_ACCEPT_RENEGOTIATE 26 +# define SSL_CTRL_SESS_HIT 27 +# define SSL_CTRL_SESS_CB_HIT 28 +# define SSL_CTRL_SESS_MISSES 29 +# define SSL_CTRL_SESS_TIMEOUTS 30 +# define SSL_CTRL_SESS_CACHE_FULL 31 +# define SSL_CTRL_OPTIONS 32 +# define SSL_CTRL_MODE 33 +# define SSL_CTRL_GET_READ_AHEAD 40 +# define SSL_CTRL_SET_READ_AHEAD 41 +# define SSL_CTRL_SET_SESS_CACHE_SIZE 42 +# define SSL_CTRL_GET_SESS_CACHE_SIZE 43 +# define SSL_CTRL_SET_SESS_CACHE_MODE 44 +# define SSL_CTRL_GET_SESS_CACHE_MODE 45 +# define SSL_CTRL_GET_MAX_CERT_LIST 50 +# define SSL_CTRL_SET_MAX_CERT_LIST 51 +# define SSL_CTRL_SET_MAX_SEND_FRAGMENT 52 +/* see tls1.h for macros based on these */ +# ifndef OPENSSL_NO_TLSEXT +# define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB 53 +# define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG 54 +# define SSL_CTRL_SET_TLSEXT_HOSTNAME 55 +# define SSL_CTRL_SET_TLSEXT_DEBUG_CB 56 +# define SSL_CTRL_SET_TLSEXT_DEBUG_ARG 57 +# define SSL_CTRL_GET_TLSEXT_TICKET_KEYS 58 +# define SSL_CTRL_SET_TLSEXT_TICKET_KEYS 59 +# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT 60 +# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB 61 +# define SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG 62 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB 63 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG 64 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE 65 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS 66 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS 67 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS 68 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS 69 +# define SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP 70 +# define SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP 71 +# define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 +# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB 75 +# define SSL_CTRL_SET_SRP_VERIFY_PARAM_CB 76 +# define SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB 77 +# define SSL_CTRL_SET_SRP_ARG 78 +# define SSL_CTRL_SET_TLS_EXT_SRP_USERNAME 79 +# define SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH 80 +# define SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD 81 +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_CTRL_TLS_EXT_SEND_HEARTBEAT 85 +# define SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING 86 +# define SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS 87 +# endif +# endif +# define DTLS_CTRL_GET_TIMEOUT 73 +# define DTLS_CTRL_HANDLE_TIMEOUT 74 +# define DTLS_CTRL_LISTEN 75 +# define SSL_CTRL_GET_RI_SUPPORT 76 +# define SSL_CTRL_CLEAR_OPTIONS 77 +# define SSL_CTRL_CLEAR_MODE 78 +# define SSL_CTRL_GET_EXTRA_CHAIN_CERTS 82 +# define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS 83 +# define SSL_CTRL_CHECK_PROTO_VERSION 119 +# define DTLS_CTRL_SET_LINK_MTU 120 +# define DTLS_CTRL_GET_LINK_MIN_MTU 121 +# define DTLSv1_get_timeout(ssl, arg) \ + SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) +# define DTLSv1_handle_timeout(ssl) \ + SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL) +# define DTLSv1_listen(ssl, peer) \ + SSL_ctrl(ssl,DTLS_CTRL_LISTEN,0, (void *)peer) +# define SSL_session_reused(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL) +# define SSL_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_NUM_RENEGOTIATIONS,0,NULL) +# define SSL_clear_num_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS,0,NULL) +# define SSL_total_renegotiations(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_TOTAL_RENEGOTIATIONS,0,NULL) +# define SSL_CTX_need_tmp_RSA(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_NEED_TMP_RSA,0,NULL) +# define SSL_CTX_set_tmp_rsa(ctx,rsa) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa) +# define SSL_CTX_set_tmp_dh(ctx,dh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_DH,0,(char *)dh) +# define SSL_CTX_set_tmp_ecdh(ctx,ecdh) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) +# define SSL_need_tmp_RSA(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_NEED_TMP_RSA,0,NULL) +# define SSL_set_tmp_rsa(ssl,rsa) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_RSA,0,(char *)rsa) +# define SSL_set_tmp_dh(ssl,dh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_DH,0,(char *)dh) +# define SSL_set_tmp_ecdh(ssl,ecdh) \ + SSL_ctrl(ssl,SSL_CTRL_SET_TMP_ECDH,0,(char *)ecdh) +# define SSL_CTX_add_extra_chain_cert(ctx,x509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_EXTRA_CHAIN_CERT,0,(char *)x509) +# define SSL_CTX_get_extra_chain_certs(ctx,px509) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_EXTRA_CHAIN_CERTS,0,px509) +# define SSL_CTX_clear_extra_chain_certs(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS,0,NULL) +# ifndef OPENSSL_NO_BIO +BIO_METHOD *BIO_f_ssl(void); +BIO *BIO_new_ssl(SSL_CTX *ctx, int client); +BIO *BIO_new_ssl_connect(SSL_CTX *ctx); +BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx); +int BIO_ssl_copy_session_id(BIO *to, BIO *from); +void BIO_ssl_shutdown(BIO *ssl_bio); + +# endif + +int SSL_CTX_set_cipher_list(SSL_CTX *, const char *str); +SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth); +void SSL_CTX_free(SSL_CTX *); +long SSL_CTX_set_timeout(SSL_CTX *ctx, long t); +long SSL_CTX_get_timeout(const SSL_CTX *ctx); +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *); +void SSL_CTX_set_cert_store(SSL_CTX *, X509_STORE *); +int SSL_want(const SSL *s); +int SSL_clear(SSL *s); + +void SSL_CTX_flush_sessions(SSL_CTX *ctx, long tm); + +const SSL_CIPHER *SSL_get_current_cipher(const SSL *s); +int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits); +char *SSL_CIPHER_get_version(const SSL_CIPHER *c); +const char *SSL_CIPHER_get_name(const SSL_CIPHER *c); +unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c); + +int SSL_get_fd(const SSL *s); +int SSL_get_rfd(const SSL *s); +int SSL_get_wfd(const SSL *s); +const char *SSL_get_cipher_list(const SSL *s, int n); +char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len); +int SSL_get_read_ahead(const SSL *s); +int SSL_pending(const SSL *s); +# ifndef OPENSSL_NO_SOCK +int SSL_set_fd(SSL *s, int fd); +int SSL_set_rfd(SSL *s, int fd); +int SSL_set_wfd(SSL *s, int fd); +# endif +# ifndef OPENSSL_NO_BIO +void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio); +BIO *SSL_get_rbio(const SSL *s); +BIO *SSL_get_wbio(const SSL *s); +# endif +int SSL_set_cipher_list(SSL *s, const char *str); +void SSL_set_read_ahead(SSL *s, int yes); +int SSL_get_verify_mode(const SSL *s); +int SSL_get_verify_depth(const SSL *s); +int (*SSL_get_verify_callback(const SSL *s)) (int, X509_STORE_CTX *); +void SSL_set_verify(SSL *s, int mode, + int (*callback) (int ok, X509_STORE_CTX *ctx)); +void SSL_set_verify_depth(SSL *s, int depth); +# ifndef OPENSSL_NO_RSA +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); +# endif +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len); +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); +int SSL_use_PrivateKey_ASN1(int pk, SSL *ssl, const unsigned char *d, + long len); +int SSL_use_certificate(SSL *ssl, X509 *x); +int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len); + +# ifndef OPENSSL_NO_STDIO +int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type); +int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type); +int SSL_use_certificate_file(SSL *ssl, const char *file, int type); +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type); +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type); +/* PEM type */ +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file); +STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); +int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *file); +# ifndef OPENSSL_SYS_VMS +/* XXXXX: Better scheme needed! [was: #ifndef MAC_OS_pre_X] */ +# ifndef OPENSSL_SYS_MACINTOSH_CLASSIC +int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stackCAs, + const char *dir); +# endif +# endif + +# endif + +void SSL_load_error_strings(void); +const char *SSL_state_string(const SSL *s); +const char *SSL_rstate_string(const SSL *s); +const char *SSL_state_string_long(const SSL *s); +const char *SSL_rstate_string_long(const SSL *s); +long SSL_SESSION_get_time(const SSL_SESSION *s); +long SSL_SESSION_set_time(SSL_SESSION *s, long t); +long SSL_SESSION_get_timeout(const SSL_SESSION *s); +long SSL_SESSION_set_timeout(SSL_SESSION *s, long t); +void SSL_copy_session_id(SSL *to, const SSL *from); +X509 *SSL_SESSION_get0_peer(SSL_SESSION *s); +int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +SSL_SESSION *SSL_SESSION_new(void); +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, + unsigned int *len); +unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s); +# ifndef OPENSSL_NO_FP_API +int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *ses); +# endif +# ifndef OPENSSL_NO_BIO +int SSL_SESSION_print(BIO *fp, const SSL_SESSION *ses); +# endif +void SSL_SESSION_free(SSL_SESSION *ses); +int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp); +int SSL_set_session(SSL *to, SSL_SESSION *session); +int SSL_CTX_add_session(SSL_CTX *s, SSL_SESSION *c); +int SSL_CTX_remove_session(SSL_CTX *, SSL_SESSION *c); +int SSL_CTX_set_generate_session_id(SSL_CTX *, GEN_SESSION_CB); +int SSL_set_generate_session_id(SSL *, GEN_SESSION_CB); +int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, + unsigned int id_len); +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, + long length); + +# ifdef HEADER_X509_H +X509 *SSL_get_peer_certificate(const SSL *s); +# endif + +STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s); + +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx)) (int, + X509_STORE_CTX *); +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, + int (*callback) (int, X509_STORE_CTX *)); +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, + int (*cb) (X509_STORE_CTX *, void *), + void *arg); +# ifndef OPENSSL_NO_RSA +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); +# endif +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, + long len); +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); +int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, + const unsigned char *d, long len); +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x); +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d); + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb); +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u); + +int SSL_CTX_check_private_key(const SSL_CTX *ctx); +int SSL_check_private_key(const SSL *ctx); + +int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +SSL *SSL_new(SSL_CTX *ctx); +int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, + unsigned int sid_ctx_len); + +int SSL_CTX_set_purpose(SSL_CTX *s, int purpose); +int SSL_set_purpose(SSL *s, int purpose); +int SSL_CTX_set_trust(SSL_CTX *s, int trust); +int SSL_set_trust(SSL *s, int trust); + +int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm); +int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm); + +# ifndef OPENSSL_NO_SRP +int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name); +int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password); +int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength); +int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, + char *(*cb) (SSL *, void *)); +int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, + int (*cb) (SSL *, void *)); +int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, + int (*cb) (SSL *, int *, void *)); +int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg); + +int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, + BIGNUM *sa, BIGNUM *v, char *info); +int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, + const char *grp); + +BIGNUM *SSL_get_srp_g(SSL *s); +BIGNUM *SSL_get_srp_N(SSL *s); + +char *SSL_get_srp_username(SSL *s); +char *SSL_get_srp_userinfo(SSL *s); +# endif + +void SSL_free(SSL *ssl); +int SSL_accept(SSL *ssl); +int SSL_connect(SSL *ssl); +int SSL_read(SSL *ssl, void *buf, int num); +int SSL_peek(SSL *ssl, void *buf, int num); +int SSL_write(SSL *ssl, const void *buf, int num); +long SSL_ctrl(SSL *ssl, int cmd, long larg, void *parg); +long SSL_callback_ctrl(SSL *, int, void (*)(void)); +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); +long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void)); + +int SSL_get_error(const SSL *s, int ret_code); +const char *SSL_get_version(const SSL *s); + +/* This sets the 'default' SSL version that SSL_new() will create */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth); + +# ifndef OPENSSL_NO_SSL2_METHOD +const SSL_METHOD *SSLv2_method(void); /* SSLv2 */ +const SSL_METHOD *SSLv2_server_method(void); /* SSLv2 */ +const SSL_METHOD *SSLv2_client_method(void); /* SSLv2 */ +# endif + +# ifndef OPENSSL_NO_SSL3_METHOD +const SSL_METHOD *SSLv3_method(void); /* SSLv3 */ +const SSL_METHOD *SSLv3_server_method(void); /* SSLv3 */ +const SSL_METHOD *SSLv3_client_method(void); /* SSLv3 */ +# endif + +const SSL_METHOD *SSLv23_method(void); /* Negotiate highest available SSL/TLS + * version */ +const SSL_METHOD *SSLv23_server_method(void); /* Negotiate highest available + * SSL/TLS version */ +const SSL_METHOD *SSLv23_client_method(void); /* Negotiate highest available + * SSL/TLS version */ + +const SSL_METHOD *TLSv1_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_server_method(void); /* TLSv1.0 */ +const SSL_METHOD *TLSv1_client_method(void); /* TLSv1.0 */ + +const SSL_METHOD *TLSv1_1_method(void); /* TLSv1.1 */ +const SSL_METHOD *TLSv1_1_server_method(void); /* TLSv1.1 */ +const SSL_METHOD *TLSv1_1_client_method(void); /* TLSv1.1 */ + +const SSL_METHOD *TLSv1_2_method(void); /* TLSv1.2 */ +const SSL_METHOD *TLSv1_2_server_method(void); /* TLSv1.2 */ +const SSL_METHOD *TLSv1_2_client_method(void); /* TLSv1.2 */ + +const SSL_METHOD *DTLSv1_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_server_method(void); /* DTLSv1.0 */ +const SSL_METHOD *DTLSv1_client_method(void); /* DTLSv1.0 */ + +STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s); + +int SSL_do_handshake(SSL *s); +int SSL_renegotiate(SSL *s); +int SSL_renegotiate_abbreviated(SSL *s); +int SSL_renegotiate_pending(SSL *s); +int SSL_shutdown(SSL *s); + +const SSL_METHOD *SSL_get_ssl_method(SSL *s); +int SSL_set_ssl_method(SSL *s, const SSL_METHOD *method); +const char *SSL_alert_type_string_long(int value); +const char *SSL_alert_type_string(int value); +const char *SSL_alert_desc_string_long(int value); +const char *SSL_alert_desc_string(int value); + +void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list); +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list); +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s); +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *s); +int SSL_add_client_CA(SSL *ssl, X509 *x); +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x); + +void SSL_set_connect_state(SSL *s); +void SSL_set_accept_state(SSL *s); + +long SSL_get_default_timeout(const SSL *s); + +int SSL_library_init(void); + +char *SSL_CIPHER_description(const SSL_CIPHER *, char *buf, int size); +STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk); + +SSL *SSL_dup(SSL *ssl); + +X509 *SSL_get_certificate(const SSL *ssl); +/* + * EVP_PKEY + */ struct evp_pkey_st *SSL_get_privatekey(SSL *ssl); + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); +void SSL_set_quiet_shutdown(SSL *ssl, int mode); +int SSL_get_quiet_shutdown(const SSL *ssl); +void SSL_set_shutdown(SSL *ssl, int mode); +int SSL_get_shutdown(const SSL *ssl); +int SSL_version(const SSL *ssl); +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath); +# define SSL_get0_session SSL_get_session/* just peek at pointer */ +SSL_SESSION *SSL_get_session(const SSL *ssl); +SSL_SESSION *SSL_get1_session(SSL *ssl); /* obtain a reference count */ +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); +void SSL_set_info_callback(SSL *ssl, + void (*cb) (const SSL *ssl, int type, int val)); +void (*SSL_get_info_callback(const SSL *ssl)) (const SSL *ssl, int type, + int val); +int SSL_state(const SSL *ssl); +void SSL_set_state(SSL *ssl, int state); + +void SSL_set_verify_result(SSL *ssl, long v); +long SSL_get_verify_result(const SSL *ssl); + +int SSL_set_ex_data(SSL *ssl, int idx, void *data); +void *SSL_get_ex_data(const SSL *ssl, int idx); +int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func); + +int SSL_SESSION_set_ex_data(SSL_SESSION *ss, int idx, void *data); +void *SSL_SESSION_get_ex_data(const SSL_SESSION *ss, int idx); +int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); + +int SSL_CTX_set_ex_data(SSL_CTX *ssl, int idx, void *data); +void *SSL_CTX_get_ex_data(const SSL_CTX *ssl, int idx); +int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func); + +int SSL_get_ex_data_X509_STORE_CTX_idx(void); + +# define SSL_CTX_sess_set_cache_size(ctx,t) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_SIZE,t,NULL) +# define SSL_CTX_sess_get_cache_size(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_SIZE,0,NULL) +# define SSL_CTX_set_session_cache_mode(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_SESS_CACHE_MODE,m,NULL) +# define SSL_CTX_get_session_cache_mode(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_SESS_CACHE_MODE,0,NULL) + +# define SSL_CTX_get_default_read_ahead(ctx) SSL_CTX_get_read_ahead(ctx) +# define SSL_CTX_set_default_read_ahead(ctx,m) SSL_CTX_set_read_ahead(ctx,m) +# define SSL_CTX_get_read_ahead(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_READ_AHEAD,0,NULL) +# define SSL_CTX_set_read_ahead(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_READ_AHEAD,m,NULL) +# define SSL_CTX_get_max_cert_list(ctx) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +# define SSL_CTX_set_max_cert_list(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) +# define SSL_get_max_cert_list(ssl) \ + SSL_ctrl(ssl,SSL_CTRL_GET_MAX_CERT_LIST,0,NULL) +# define SSL_set_max_cert_list(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_CERT_LIST,m,NULL) + +# define SSL_CTX_set_max_send_fragment(ctx,m) \ + SSL_CTX_ctrl(ctx,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) +# define SSL_set_max_send_fragment(ssl,m) \ + SSL_ctrl(ssl,SSL_CTRL_SET_MAX_SEND_FRAGMENT,m,NULL) + + /* NB: the keylength is only applicable when is_export is true */ +# ifndef OPENSSL_NO_RSA +void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, + RSA *(*cb) (SSL *ssl, int is_export, + int keylength)); + +void SSL_set_tmp_rsa_callback(SSL *ssl, + RSA *(*cb) (SSL *ssl, int is_export, + int keylength)); +# endif +# ifndef OPENSSL_NO_DH +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)); +void SSL_set_tmp_dh_callback(SSL *ssl, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)); +# endif +# ifndef OPENSSL_NO_ECDH +void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, + EC_KEY *(*ecdh) (SSL *ssl, int is_export, + int keylength)); +void SSL_set_tmp_ecdh_callback(SSL *ssl, + EC_KEY *(*ecdh) (SSL *ssl, int is_export, + int keylength)); +# endif + +# ifndef OPENSSL_NO_COMP +const COMP_METHOD *SSL_get_current_compression(SSL *s); +const COMP_METHOD *SSL_get_current_expansion(SSL *s); +const char *SSL_COMP_get_name(const COMP_METHOD *comp); +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); +int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm); +# else +const void *SSL_get_current_compression(SSL *s); +const void *SSL_get_current_expansion(SSL *s); +const char *SSL_COMP_get_name(const void *comp); +void *SSL_COMP_get_compression_methods(void); +int SSL_COMP_add_compression_method(int id, void *cm); +# endif + +/* TLS extensions functions */ +int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len); + +int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, + void *arg); + +/* Pre-shared secret session resumption functions */ +int SSL_set_session_secret_cb(SSL *s, + tls_session_secret_cb_fn tls_session_secret_cb, + void *arg); + +void SSL_set_debug(SSL *s, int debug); +int SSL_cache_hit(SSL *s); + +# ifndef OPENSSL_NO_UNIT_TEST +const struct openssl_ssl_test_functions *SSL_test_functions(void); +# endif + +/* BEGIN ERROR CODES */ +/* + * The following lines are auto generated by the script mkerr.pl. Any changes + * made after this point may be overwritten when the script is next run. + */ +void ERR_load_SSL_strings(void); + +/* Error codes for the SSL functions. */ + +/* Function codes. */ +# define SSL_F_CLIENT_CERTIFICATE 100 +# define SSL_F_CLIENT_FINISHED 167 +# define SSL_F_CLIENT_HELLO 101 +# define SSL_F_CLIENT_MASTER_KEY 102 +# define SSL_F_D2I_SSL_SESSION 103 +# define SSL_F_DO_DTLS1_WRITE 245 +# define SSL_F_DO_SSL3_WRITE 104 +# define SSL_F_DTLS1_ACCEPT 246 +# define SSL_F_DTLS1_ADD_CERT_TO_BUF 295 +# define SSL_F_DTLS1_BUFFER_RECORD 247 +# define SSL_F_DTLS1_CHECK_TIMEOUT_NUM 316 +# define SSL_F_DTLS1_CLIENT_HELLO 248 +# define SSL_F_DTLS1_CONNECT 249 +# define SSL_F_DTLS1_ENC 250 +# define SSL_F_DTLS1_GET_HELLO_VERIFY 251 +# define SSL_F_DTLS1_GET_MESSAGE 252 +# define SSL_F_DTLS1_GET_MESSAGE_FRAGMENT 253 +# define SSL_F_DTLS1_GET_RECORD 254 +# define SSL_F_DTLS1_HANDLE_TIMEOUT 297 +# define SSL_F_DTLS1_HEARTBEAT 305 +# define SSL_F_DTLS1_OUTPUT_CERT_CHAIN 255 +# define SSL_F_DTLS1_PREPROCESS_FRAGMENT 288 +# define SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE 256 +# define SSL_F_DTLS1_PROCESS_RECORD 257 +# define SSL_F_DTLS1_READ_BYTES 258 +# define SSL_F_DTLS1_READ_FAILED 259 +# define SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST 260 +# define SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE 261 +# define SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE 262 +# define SSL_F_DTLS1_SEND_CLIENT_VERIFY 263 +# define SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST 264 +# define SSL_F_DTLS1_SEND_SERVER_CERTIFICATE 265 +# define SSL_F_DTLS1_SEND_SERVER_HELLO 266 +# define SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE 267 +# define SSL_F_DTLS1_WRITE_APP_DATA_BYTES 268 +# define SSL_F_GET_CLIENT_FINISHED 105 +# define SSL_F_GET_CLIENT_HELLO 106 +# define SSL_F_GET_CLIENT_MASTER_KEY 107 +# define SSL_F_GET_SERVER_FINISHED 108 +# define SSL_F_GET_SERVER_HELLO 109 +# define SSL_F_GET_SERVER_VERIFY 110 +# define SSL_F_I2D_SSL_SESSION 111 +# define SSL_F_READ_N 112 +# define SSL_F_REQUEST_CERTIFICATE 113 +# define SSL_F_SERVER_FINISH 239 +# define SSL_F_SERVER_HELLO 114 +# define SSL_F_SERVER_VERIFY 240 +# define SSL_F_SSL23_ACCEPT 115 +# define SSL_F_SSL23_CLIENT_HELLO 116 +# define SSL_F_SSL23_CONNECT 117 +# define SSL_F_SSL23_GET_CLIENT_HELLO 118 +# define SSL_F_SSL23_GET_SERVER_HELLO 119 +# define SSL_F_SSL23_PEEK 237 +# define SSL_F_SSL23_READ 120 +# define SSL_F_SSL23_WRITE 121 +# define SSL_F_SSL2_ACCEPT 122 +# define SSL_F_SSL2_CONNECT 123 +# define SSL_F_SSL2_ENC_INIT 124 +# define SSL_F_SSL2_GENERATE_KEY_MATERIAL 241 +# define SSL_F_SSL2_PEEK 234 +# define SSL_F_SSL2_READ 125 +# define SSL_F_SSL2_READ_INTERNAL 236 +# define SSL_F_SSL2_SET_CERTIFICATE 126 +# define SSL_F_SSL2_WRITE 127 +# define SSL_F_SSL3_ACCEPT 128 +# define SSL_F_SSL3_ADD_CERT_TO_BUF 296 +# define SSL_F_SSL3_CALLBACK_CTRL 233 +# define SSL_F_SSL3_CHANGE_CIPHER_STATE 129 +# define SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM 130 +# define SSL_F_SSL3_CHECK_CLIENT_HELLO 304 +# define SSL_F_SSL3_CHECK_FINISHED 339 +# define SSL_F_SSL3_CLIENT_HELLO 131 +# define SSL_F_SSL3_CONNECT 132 +# define SSL_F_SSL3_CTRL 213 +# define SSL_F_SSL3_CTX_CTRL 133 +# define SSL_F_SSL3_DIGEST_CACHED_RECORDS 293 +# define SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC 292 +# define SSL_F_SSL3_ENC 134 +# define SSL_F_SSL3_GENERATE_KEY_BLOCK 238 +# define SSL_F_SSL3_GENERATE_MASTER_SECRET 388 +# define SSL_F_SSL3_GET_CERTIFICATE_REQUEST 135 +# define SSL_F_SSL3_GET_CERT_STATUS 289 +# define SSL_F_SSL3_GET_CERT_VERIFY 136 +# define SSL_F_SSL3_GET_CLIENT_CERTIFICATE 137 +# define SSL_F_SSL3_GET_CLIENT_HELLO 138 +# define SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE 139 +# define SSL_F_SSL3_GET_FINISHED 140 +# define SSL_F_SSL3_GET_KEY_EXCHANGE 141 +# define SSL_F_SSL3_GET_MESSAGE 142 +# define SSL_F_SSL3_GET_NEW_SESSION_TICKET 283 +# define SSL_F_SSL3_GET_NEXT_PROTO 306 +# define SSL_F_SSL3_GET_RECORD 143 +# define SSL_F_SSL3_GET_SERVER_CERTIFICATE 144 +# define SSL_F_SSL3_GET_SERVER_DONE 145 +# define SSL_F_SSL3_GET_SERVER_HELLO 146 +# define SSL_F_SSL3_HANDSHAKE_MAC 285 +# define SSL_F_SSL3_NEW_SESSION_TICKET 287 +# define SSL_F_SSL3_OUTPUT_CERT_CHAIN 147 +# define SSL_F_SSL3_PEEK 235 +# define SSL_F_SSL3_READ_BYTES 148 +# define SSL_F_SSL3_READ_N 149 +# define SSL_F_SSL3_SEND_CERTIFICATE_REQUEST 150 +# define SSL_F_SSL3_SEND_CLIENT_CERTIFICATE 151 +# define SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE 152 +# define SSL_F_SSL3_SEND_CLIENT_VERIFY 153 +# define SSL_F_SSL3_SEND_SERVER_CERTIFICATE 154 +# define SSL_F_SSL3_SEND_SERVER_HELLO 242 +# define SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE 155 +# define SSL_F_SSL3_SETUP_KEY_BLOCK 157 +# define SSL_F_SSL3_SETUP_READ_BUFFER 156 +# define SSL_F_SSL3_SETUP_WRITE_BUFFER 291 +# define SSL_F_SSL3_WRITE_BYTES 158 +# define SSL_F_SSL3_WRITE_PENDING 159 +# define SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT 298 +# define SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT 277 +# define SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT 307 +# define SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK 215 +# define SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK 216 +# define SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT 299 +# define SSL_F_SSL_ADD_SERVERHELLO_TLSEXT 278 +# define SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT 308 +# define SSL_F_SSL_BAD_METHOD 160 +# define SSL_F_SSL_BYTES_TO_CIPHER_LIST 161 +# define SSL_F_SSL_CERT_DUP 221 +# define SSL_F_SSL_CERT_INST 222 +# define SSL_F_SSL_CERT_INSTANTIATE 214 +# define SSL_F_SSL_CERT_NEW 162 +# define SSL_F_SSL_CHECK_PRIVATE_KEY 163 +# define SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT 280 +# define SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG 279 +# define SSL_F_SSL_CIPHER_PROCESS_RULESTR 230 +# define SSL_F_SSL_CIPHER_STRENGTH_SORT 231 +# define SSL_F_SSL_CLEAR 164 +# define SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD 165 +# define SSL_F_SSL_CREATE_CIPHER_LIST 166 +# define SSL_F_SSL_CTRL 232 +# define SSL_F_SSL_CTX_CHECK_PRIVATE_KEY 168 +# define SSL_F_SSL_CTX_MAKE_PROFILES 309 +# define SSL_F_SSL_CTX_NEW 169 +# define SSL_F_SSL_CTX_SET_CIPHER_LIST 269 +# define SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE 290 +# define SSL_F_SSL_CTX_SET_PURPOSE 226 +# define SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT 219 +# define SSL_F_SSL_CTX_SET_SSL_VERSION 170 +# define SSL_F_SSL_CTX_SET_TRUST 229 +# define SSL_F_SSL_CTX_USE_CERTIFICATE 171 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1 172 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE 220 +# define SSL_F_SSL_CTX_USE_CERTIFICATE_FILE 173 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY 174 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1 175 +# define SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE 176 +# define SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT 272 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY 177 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1 178 +# define SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE 179 +# define SSL_F_SSL_DO_HANDSHAKE 180 +# define SSL_F_SSL_GET_NEW_SESSION 181 +# define SSL_F_SSL_GET_PREV_SESSION 217 +# define SSL_F_SSL_GET_SERVER_SEND_CERT 182 +# define SSL_F_SSL_GET_SERVER_SEND_PKEY 317 +# define SSL_F_SSL_GET_SIGN_PKEY 183 +# define SSL_F_SSL_INIT_WBIO_BUFFER 184 +# define SSL_F_SSL_LOAD_CLIENT_CA_FILE 185 +# define SSL_F_SSL_NEW 186 +# define SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT 300 +# define SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT 302 +# define SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT 310 +# define SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT 301 +# define SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT 303 +# define SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT 311 +# define SSL_F_SSL_PEEK 270 +# define SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT 281 +# define SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT 282 +# define SSL_F_SSL_READ 223 +# define SSL_F_SSL_RSA_PRIVATE_DECRYPT 187 +# define SSL_F_SSL_RSA_PUBLIC_ENCRYPT 188 +# define SSL_F_SSL_SESSION_DUP 348 +# define SSL_F_SSL_SESSION_NEW 189 +# define SSL_F_SSL_SESSION_PRINT_FP 190 +# define SSL_F_SSL_SESSION_SET1_ID_CONTEXT 312 +# define SSL_F_SSL_SESS_CERT_NEW 225 +# define SSL_F_SSL_SET_CERT 191 +# define SSL_F_SSL_SET_CIPHER_LIST 271 +# define SSL_F_SSL_SET_FD 192 +# define SSL_F_SSL_SET_PKEY 193 +# define SSL_F_SSL_SET_PURPOSE 227 +# define SSL_F_SSL_SET_RFD 194 +# define SSL_F_SSL_SET_SESSION 195 +# define SSL_F_SSL_SET_SESSION_ID_CONTEXT 218 +# define SSL_F_SSL_SET_SESSION_TICKET_EXT 294 +# define SSL_F_SSL_SET_TRUST 228 +# define SSL_F_SSL_SET_WFD 196 +# define SSL_F_SSL_SHUTDOWN 224 +# define SSL_F_SSL_SRP_CTX_INIT 313 +# define SSL_F_SSL_UNDEFINED_CONST_FUNCTION 243 +# define SSL_F_SSL_UNDEFINED_FUNCTION 197 +# define SSL_F_SSL_UNDEFINED_VOID_FUNCTION 244 +# define SSL_F_SSL_USE_CERTIFICATE 198 +# define SSL_F_SSL_USE_CERTIFICATE_ASN1 199 +# define SSL_F_SSL_USE_CERTIFICATE_FILE 200 +# define SSL_F_SSL_USE_PRIVATEKEY 201 +# define SSL_F_SSL_USE_PRIVATEKEY_ASN1 202 +# define SSL_F_SSL_USE_PRIVATEKEY_FILE 203 +# define SSL_F_SSL_USE_PSK_IDENTITY_HINT 273 +# define SSL_F_SSL_USE_RSAPRIVATEKEY 204 +# define SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1 205 +# define SSL_F_SSL_USE_RSAPRIVATEKEY_FILE 206 +# define SSL_F_SSL_VERIFY_CERT_CHAIN 207 +# define SSL_F_SSL_WRITE 208 +# define SSL_F_TLS1_CERT_VERIFY_MAC 286 +# define SSL_F_TLS1_CHANGE_CIPHER_STATE 209 +# define SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT 274 +# define SSL_F_TLS1_ENC 210 +# define SSL_F_TLS1_EXPORT_KEYING_MATERIAL 314 +# define SSL_F_TLS1_HEARTBEAT 315 +# define SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT 275 +# define SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT 276 +# define SSL_F_TLS1_PRF 284 +# define SSL_F_TLS1_SETUP_KEY_BLOCK 211 +# define SSL_F_WRITE_PENDING 212 + +/* Reason codes. */ +# define SSL_R_APP_DATA_IN_HANDSHAKE 100 +# define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 272 +# define SSL_R_BAD_ALERT_RECORD 101 +# define SSL_R_BAD_AUTHENTICATION_TYPE 102 +# define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 +# define SSL_R_BAD_CHECKSUM 104 +# define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 106 +# define SSL_R_BAD_DECOMPRESSION 107 +# define SSL_R_BAD_DH_G_LENGTH 108 +# define SSL_R_BAD_DH_G_VALUE 375 +# define SSL_R_BAD_DH_PUB_KEY_LENGTH 109 +# define SSL_R_BAD_DH_PUB_KEY_VALUE 393 +# define SSL_R_BAD_DH_P_LENGTH 110 +# define SSL_R_BAD_DH_P_VALUE 395 +# define SSL_R_BAD_DIGEST_LENGTH 111 +# define SSL_R_BAD_DSA_SIGNATURE 112 +# define SSL_R_BAD_ECC_CERT 304 +# define SSL_R_BAD_ECDSA_SIGNATURE 305 +# define SSL_R_BAD_ECPOINT 306 +# define SSL_R_BAD_HANDSHAKE_LENGTH 332 +# define SSL_R_BAD_HELLO_REQUEST 105 +# define SSL_R_BAD_LENGTH 271 +# define SSL_R_BAD_MAC_DECODE 113 +# define SSL_R_BAD_MAC_LENGTH 333 +# define SSL_R_BAD_MESSAGE_TYPE 114 +# define SSL_R_BAD_PACKET_LENGTH 115 +# define SSL_R_BAD_PROTOCOL_VERSION_NUMBER 116 +# define SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH 316 +# define SSL_R_BAD_RESPONSE_ARGUMENT 117 +# define SSL_R_BAD_RSA_DECRYPT 118 +# define SSL_R_BAD_RSA_ENCRYPT 119 +# define SSL_R_BAD_RSA_E_LENGTH 120 +# define SSL_R_BAD_RSA_MODULUS_LENGTH 121 +# define SSL_R_BAD_RSA_SIGNATURE 122 +# define SSL_R_BAD_SIGNATURE 123 +# define SSL_R_BAD_SRP_A_LENGTH 347 +# define SSL_R_BAD_SRP_B_LENGTH 348 +# define SSL_R_BAD_SRP_G_LENGTH 349 +# define SSL_R_BAD_SRP_N_LENGTH 350 +# define SSL_R_BAD_SRP_PARAMETERS 371 +# define SSL_R_BAD_SRP_S_LENGTH 351 +# define SSL_R_BAD_SRTP_MKI_VALUE 352 +# define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 353 +# define SSL_R_BAD_SSL_FILETYPE 124 +# define SSL_R_BAD_SSL_SESSION_ID_LENGTH 125 +# define SSL_R_BAD_STATE 126 +# define SSL_R_BAD_WRITE_RETRY 127 +# define SSL_R_BIO_NOT_SET 128 +# define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 129 +# define SSL_R_BN_LIB 130 +# define SSL_R_CA_DN_LENGTH_MISMATCH 131 +# define SSL_R_CA_DN_TOO_LONG 132 +# define SSL_R_CCS_RECEIVED_EARLY 133 +# define SSL_R_CERTIFICATE_VERIFY_FAILED 134 +# define SSL_R_CERT_LENGTH_MISMATCH 135 +# define SSL_R_CHALLENGE_IS_DIFFERENT 136 +# define SSL_R_CIPHER_CODE_WRONG_LENGTH 137 +# define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 138 +# define SSL_R_CIPHER_TABLE_SRC_ERROR 139 +# define SSL_R_CLIENTHELLO_TLSEXT 226 +# define SSL_R_COMPRESSED_LENGTH_TOO_LONG 140 +# define SSL_R_COMPRESSION_DISABLED 343 +# define SSL_R_COMPRESSION_FAILURE 141 +# define SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE 307 +# define SSL_R_COMPRESSION_LIBRARY_ERROR 142 +# define SSL_R_CONNECTION_ID_IS_DIFFERENT 143 +# define SSL_R_CONNECTION_TYPE_NOT_SET 144 +# define SSL_R_COOKIE_MISMATCH 308 +# define SSL_R_DATA_BETWEEN_CCS_AND_FINISHED 145 +# define SSL_R_DATA_LENGTH_TOO_LONG 146 +# define SSL_R_DECRYPTION_FAILED 147 +# define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 281 +# define SSL_R_DH_KEY_TOO_SMALL 372 +# define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 148 +# define SSL_R_DIGEST_CHECK_FAILED 149 +# define SSL_R_DTLS_MESSAGE_TOO_BIG 334 +# define SSL_R_DUPLICATE_COMPRESSION_ID 309 +# define SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT 317 +# define SSL_R_ECC_CERT_NOT_FOR_SIGNING 318 +# define SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE 322 +# define SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE 323 +# define SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER 310 +# define SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST 354 +# define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 150 +# define SSL_R_ERROR_GENERATING_TMP_RSA_KEY 282 +# define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 151 +# define SSL_R_EXCESSIVE_MESSAGE_SIZE 152 +# define SSL_R_EXTRA_DATA_IN_MESSAGE 153 +# define SSL_R_GOT_A_FIN_BEFORE_A_CCS 154 +# define SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS 355 +# define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 356 +# define SSL_R_HTTPS_PROXY_REQUEST 155 +# define SSL_R_HTTP_REQUEST 156 +# define SSL_R_ILLEGAL_PADDING 283 +# define SSL_R_INAPPROPRIATE_FALLBACK 373 +# define SSL_R_INCONSISTENT_COMPRESSION 340 +# define SSL_R_INVALID_CHALLENGE_LENGTH 158 +# define SSL_R_INVALID_COMMAND 280 +# define SSL_R_INVALID_COMPRESSION_ALGORITHM 341 +# define SSL_R_INVALID_PURPOSE 278 +# define SSL_R_INVALID_SRP_USERNAME 357 +# define SSL_R_INVALID_STATUS_RESPONSE 328 +# define SSL_R_INVALID_TICKET_KEYS_LENGTH 325 +# define SSL_R_INVALID_TRUST 279 +# define SSL_R_KEY_ARG_TOO_LONG 284 +# define SSL_R_KRB5 285 +# define SSL_R_KRB5_C_CC_PRINC 286 +# define SSL_R_KRB5_C_GET_CRED 287 +# define SSL_R_KRB5_C_INIT 288 +# define SSL_R_KRB5_C_MK_REQ 289 +# define SSL_R_KRB5_S_BAD_TICKET 290 +# define SSL_R_KRB5_S_INIT 291 +# define SSL_R_KRB5_S_RD_REQ 292 +# define SSL_R_KRB5_S_TKT_EXPIRED 293 +# define SSL_R_KRB5_S_TKT_NYV 294 +# define SSL_R_KRB5_S_TKT_SKEW 295 +# define SSL_R_LENGTH_MISMATCH 159 +# define SSL_R_LENGTH_TOO_SHORT 160 +# define SSL_R_LIBRARY_BUG 274 +# define SSL_R_LIBRARY_HAS_NO_CIPHERS 161 +# define SSL_R_MESSAGE_TOO_LONG 296 +# define SSL_R_MISSING_DH_DSA_CERT 162 +# define SSL_R_MISSING_DH_KEY 163 +# define SSL_R_MISSING_DH_RSA_CERT 164 +# define SSL_R_MISSING_DSA_SIGNING_CERT 165 +# define SSL_R_MISSING_EXPORT_TMP_DH_KEY 166 +# define SSL_R_MISSING_EXPORT_TMP_RSA_KEY 167 +# define SSL_R_MISSING_RSA_CERTIFICATE 168 +# define SSL_R_MISSING_RSA_ENCRYPTING_CERT 169 +# define SSL_R_MISSING_RSA_SIGNING_CERT 170 +# define SSL_R_MISSING_SRP_PARAM 358 +# define SSL_R_MISSING_TMP_DH_KEY 171 +# define SSL_R_MISSING_TMP_ECDH_KEY 311 +# define SSL_R_MISSING_TMP_RSA_KEY 172 +# define SSL_R_MISSING_TMP_RSA_PKEY 173 +# define SSL_R_MISSING_VERIFY_MESSAGE 174 +# define SSL_R_MULTIPLE_SGC_RESTARTS 346 +# define SSL_R_NON_SSLV2_INITIAL_PACKET 175 +# define SSL_R_NO_CERTIFICATES_RETURNED 176 +# define SSL_R_NO_CERTIFICATE_ASSIGNED 177 +# define SSL_R_NO_CERTIFICATE_RETURNED 178 +# define SSL_R_NO_CERTIFICATE_SET 179 +# define SSL_R_NO_CERTIFICATE_SPECIFIED 180 +# define SSL_R_NO_CIPHERS_AVAILABLE 181 +# define SSL_R_NO_CIPHERS_PASSED 182 +# define SSL_R_NO_CIPHERS_SPECIFIED 183 +# define SSL_R_NO_CIPHER_LIST 184 +# define SSL_R_NO_CIPHER_MATCH 185 +# define SSL_R_NO_CLIENT_CERT_METHOD 331 +# define SSL_R_NO_CLIENT_CERT_RECEIVED 186 +# define SSL_R_NO_COMPRESSION_SPECIFIED 187 +# define SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER 330 +# define SSL_R_NO_METHOD_SPECIFIED 188 +# define SSL_R_NO_PRIVATEKEY 189 +# define SSL_R_NO_PRIVATE_KEY_ASSIGNED 190 +# define SSL_R_NO_PROTOCOLS_AVAILABLE 191 +# define SSL_R_NO_PUBLICKEY 192 +# define SSL_R_NO_RENEGOTIATION 339 +# define SSL_R_NO_REQUIRED_DIGEST 324 +# define SSL_R_NO_SHARED_CIPHER 193 +# define SSL_R_NO_SRTP_PROFILES 359 +# define SSL_R_NO_VERIFY_CALLBACK 194 +# define SSL_R_NULL_SSL_CTX 195 +# define SSL_R_NULL_SSL_METHOD_PASSED 196 +# define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 197 +# define SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED 344 +# define SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE 297 +# define SSL_R_OPAQUE_PRF_INPUT_TOO_LONG 327 +# define SSL_R_PACKET_LENGTH_TOO_LONG 198 +# define SSL_R_PARSE_TLSEXT 227 +# define SSL_R_PATH_TOO_LONG 270 +# define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 199 +# define SSL_R_PEER_ERROR 200 +# define SSL_R_PEER_ERROR_CERTIFICATE 201 +# define SSL_R_PEER_ERROR_NO_CERTIFICATE 202 +# define SSL_R_PEER_ERROR_NO_CIPHER 203 +# define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 204 +# define SSL_R_PRE_MAC_LENGTH_TOO_LONG 205 +# define SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS 206 +# define SSL_R_PROTOCOL_IS_SHUTDOWN 207 +# define SSL_R_PSK_IDENTITY_NOT_FOUND 223 +# define SSL_R_PSK_NO_CLIENT_CB 224 +# define SSL_R_PSK_NO_SERVER_CB 225 +# define SSL_R_PUBLIC_KEY_ENCRYPT_ERROR 208 +# define SSL_R_PUBLIC_KEY_IS_NOT_RSA 209 +# define SSL_R_PUBLIC_KEY_NOT_RSA 210 +# define SSL_R_READ_BIO_NOT_SET 211 +# define SSL_R_READ_TIMEOUT_EXPIRED 312 +# define SSL_R_READ_WRONG_PACKET_TYPE 212 +# define SSL_R_RECORD_LENGTH_MISMATCH 213 +# define SSL_R_RECORD_TOO_LARGE 214 +# define SSL_R_RECORD_TOO_SMALL 298 +# define SSL_R_RENEGOTIATE_EXT_TOO_LONG 335 +# define SSL_R_RENEGOTIATION_ENCODING_ERR 336 +# define SSL_R_RENEGOTIATION_MISMATCH 337 +# define SSL_R_REQUIRED_CIPHER_MISSING 215 +# define SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING 342 +# define SSL_R_REUSE_CERT_LENGTH_NOT_ZERO 216 +# define SSL_R_REUSE_CERT_TYPE_NOT_ZERO 217 +# define SSL_R_REUSE_CIPHER_LIST_NOT_ZERO 218 +# define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 345 +# define SSL_R_SERVERHELLO_TLSEXT 275 +# define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 277 +# define SSL_R_SHORT_READ 219 +# define SSL_R_SIGNATURE_ALGORITHMS_ERROR 360 +# define SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE 220 +# define SSL_R_SRP_A_CALC 361 +# define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 362 +# define SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG 363 +# define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 364 +# define SSL_R_SSL23_DOING_SESSION_ID_REUSE 221 +# define SSL_R_SSL2_CONNECTION_ID_TOO_LONG 299 +# define SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT 321 +# define SSL_R_SSL3_EXT_INVALID_SERVERNAME 319 +# define SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE 320 +# define SSL_R_SSL3_SESSION_ID_TOO_LONG 300 +# define SSL_R_SSL3_SESSION_ID_TOO_SHORT 222 +# define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 +# define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 +# define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 +# define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 +# define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 +# define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 +# define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 +# define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 +# define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 +# define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 228 +# define SSL_R_SSL_HANDSHAKE_FAILURE 229 +# define SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS 230 +# define SSL_R_SSL_SESSION_ID_CALLBACK_FAILED 301 +# define SSL_R_SSL_SESSION_ID_CONFLICT 302 +# define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 273 +# define SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH 303 +# define SSL_R_SSL_SESSION_ID_IS_DIFFERENT 231 +# define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 +# define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 +# define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 +# define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 +# define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 +# define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 +# define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 +# define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +# define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +# define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 +# define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 +# define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +# define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +# define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +# define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +# define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 +# define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 +# define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 +# define SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER 232 +# define SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT 365 +# define SSL_R_TLS_HEARTBEAT_PENDING 366 +# define SSL_R_TLS_ILLEGAL_EXPORTER_LABEL 367 +# define SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST 157 +# define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 233 +# define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 234 +# define SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER 235 +# define SSL_R_UNABLE_TO_DECODE_DH_CERTS 236 +# define SSL_R_UNABLE_TO_DECODE_ECDH_CERTS 313 +# define SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY 237 +# define SSL_R_UNABLE_TO_FIND_DH_PARAMETERS 238 +# define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 314 +# define SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS 239 +# define SSL_R_UNABLE_TO_FIND_SSL_METHOD 240 +# define SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES 241 +# define SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES 242 +# define SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES 243 +# define SSL_R_UNEXPECTED_MESSAGE 244 +# define SSL_R_UNEXPECTED_RECORD 245 +# define SSL_R_UNINITIALIZED 276 +# define SSL_R_UNKNOWN_ALERT_TYPE 246 +# define SSL_R_UNKNOWN_CERTIFICATE_TYPE 247 +# define SSL_R_UNKNOWN_CIPHER_RETURNED 248 +# define SSL_R_UNKNOWN_CIPHER_TYPE 249 +# define SSL_R_UNKNOWN_DIGEST 368 +# define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 250 +# define SSL_R_UNKNOWN_PKEY_TYPE 251 +# define SSL_R_UNKNOWN_PROTOCOL 252 +# define SSL_R_UNKNOWN_REMOTE_ERROR_TYPE 253 +# define SSL_R_UNKNOWN_SSL_VERSION 254 +# define SSL_R_UNKNOWN_STATE 255 +# define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 338 +# define SSL_R_UNSUPPORTED_CIPHER 256 +# define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 257 +# define SSL_R_UNSUPPORTED_DIGEST_TYPE 326 +# define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 315 +# define SSL_R_UNSUPPORTED_PROTOCOL 258 +# define SSL_R_UNSUPPORTED_SSL_VERSION 259 +# define SSL_R_UNSUPPORTED_STATUS_TYPE 329 +# define SSL_R_USE_SRTP_NOT_NEGOTIATED 369 +# define SSL_R_WRITE_BIO_NOT_SET 260 +# define SSL_R_WRONG_CIPHER_RETURNED 261 +# define SSL_R_WRONG_MESSAGE_TYPE 262 +# define SSL_R_WRONG_NUMBER_OF_KEY_BITS 263 +# define SSL_R_WRONG_SIGNATURE_LENGTH 264 +# define SSL_R_WRONG_SIGNATURE_SIZE 265 +# define SSL_R_WRONG_SIGNATURE_TYPE 370 +# define SSL_R_WRONG_SSL_VERSION 266 +# define SSL_R_WRONG_VERSION_NUMBER 267 +# define SSL_R_X509_LIB 268 +# define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 269 + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/include/openssl/ssl2.h b/libs/openssl/include/openssl/ssl2.h new file mode 100644 index 00000000..03c7dd8c --- /dev/null +++ b/libs/openssl/include/openssl/ssl2.h @@ -0,0 +1,265 @@ +/* ssl/ssl2.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SSL2_H +# define HEADER_SSL2_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Protocol Version Codes */ +# define SSL2_VERSION 0x0002 +# define SSL2_VERSION_MAJOR 0x00 +# define SSL2_VERSION_MINOR 0x02 +/* #define SSL2_CLIENT_VERSION 0x0002 */ +/* #define SSL2_SERVER_VERSION 0x0002 */ + +/* Protocol Message Codes */ +# define SSL2_MT_ERROR 0 +# define SSL2_MT_CLIENT_HELLO 1 +# define SSL2_MT_CLIENT_MASTER_KEY 2 +# define SSL2_MT_CLIENT_FINISHED 3 +# define SSL2_MT_SERVER_HELLO 4 +# define SSL2_MT_SERVER_VERIFY 5 +# define SSL2_MT_SERVER_FINISHED 6 +# define SSL2_MT_REQUEST_CERTIFICATE 7 +# define SSL2_MT_CLIENT_CERTIFICATE 8 + +/* Error Message Codes */ +# define SSL2_PE_UNDEFINED_ERROR 0x0000 +# define SSL2_PE_NO_CIPHER 0x0001 +# define SSL2_PE_NO_CERTIFICATE 0x0002 +# define SSL2_PE_BAD_CERTIFICATE 0x0004 +# define SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE 0x0006 + +/* Cipher Kind Values */ +# define SSL2_CK_NULL_WITH_MD5 0x02000000/* v3 */ +# define SSL2_CK_RC4_128_WITH_MD5 0x02010080 +# define SSL2_CK_RC4_128_EXPORT40_WITH_MD5 0x02020080 +# define SSL2_CK_RC2_128_CBC_WITH_MD5 0x02030080 +# define SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5 0x02040080 +# define SSL2_CK_IDEA_128_CBC_WITH_MD5 0x02050080 +# define SSL2_CK_DES_64_CBC_WITH_MD5 0x02060040 +# define SSL2_CK_DES_64_CBC_WITH_SHA 0x02060140/* v3 */ +# define SSL2_CK_DES_192_EDE3_CBC_WITH_MD5 0x020700c0 +# define SSL2_CK_DES_192_EDE3_CBC_WITH_SHA 0x020701c0/* v3 */ +# define SSL2_CK_RC4_64_WITH_MD5 0x02080080/* MS hack */ + +# define SSL2_CK_DES_64_CFB64_WITH_MD5_1 0x02ff0800/* SSLeay */ +# define SSL2_CK_NULL 0x02ff0810/* SSLeay */ + +# define SSL2_TXT_DES_64_CFB64_WITH_MD5_1 "DES-CFB-M1" +# define SSL2_TXT_NULL_WITH_MD5 "NULL-MD5" +# define SSL2_TXT_RC4_128_WITH_MD5 "RC4-MD5" +# define SSL2_TXT_RC4_128_EXPORT40_WITH_MD5 "EXP-RC4-MD5" +# define SSL2_TXT_RC2_128_CBC_WITH_MD5 "RC2-CBC-MD5" +# define SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5 "EXP-RC2-CBC-MD5" +# define SSL2_TXT_IDEA_128_CBC_WITH_MD5 "IDEA-CBC-MD5" +# define SSL2_TXT_DES_64_CBC_WITH_MD5 "DES-CBC-MD5" +# define SSL2_TXT_DES_64_CBC_WITH_SHA "DES-CBC-SHA" +# define SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5 "DES-CBC3-MD5" +# define SSL2_TXT_DES_192_EDE3_CBC_WITH_SHA "DES-CBC3-SHA" +# define SSL2_TXT_RC4_64_WITH_MD5 "RC4-64-MD5" + +# define SSL2_TXT_NULL "NULL" + +/* Flags for the SSL_CIPHER.algorithm2 field */ +# define SSL2_CF_5_BYTE_ENC 0x01 +# define SSL2_CF_8_BYTE_ENC 0x02 + +/* Certificate Type Codes */ +# define SSL2_CT_X509_CERTIFICATE 0x01 + +/* Authentication Type Code */ +# define SSL2_AT_MD5_WITH_RSA_ENCRYPTION 0x01 + +# define SSL2_MAX_SSL_SESSION_ID_LENGTH 32 + +/* Upper/Lower Bounds */ +# define SSL2_MAX_MASTER_KEY_LENGTH_IN_BITS 256 +# ifdef OPENSSL_SYS_MPE +# define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 29998u +# else +# define SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER 32767u + /* 2^15-1 */ +# endif +# define SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER 16383/* 2^14-1 */ + +# define SSL2_CHALLENGE_LENGTH 16 +/* + * #define SSL2_CHALLENGE_LENGTH 32 + */ +# define SSL2_MIN_CHALLENGE_LENGTH 16 +# define SSL2_MAX_CHALLENGE_LENGTH 32 +# define SSL2_CONNECTION_ID_LENGTH 16 +# define SSL2_MAX_CONNECTION_ID_LENGTH 16 +# define SSL2_SSL_SESSION_ID_LENGTH 16 +# define SSL2_MAX_CERT_CHALLENGE_LENGTH 32 +# define SSL2_MIN_CERT_CHALLENGE_LENGTH 16 +# define SSL2_MAX_KEY_MATERIAL_LENGTH 24 + +# ifndef HEADER_SSL_LOCL_H +# define CERT char +# endif + +# ifndef OPENSSL_NO_SSL_INTERN + +typedef struct ssl2_state_st { + int three_byte_header; + int clear_text; /* clear text */ + int escape; /* not used in SSLv2 */ + int ssl2_rollback; /* used if SSLv23 rolled back to SSLv2 */ + /* + * non-blocking io info, used to make sure the same args were passwd + */ + unsigned int wnum; /* number of bytes sent so far */ + int wpend_tot; + const unsigned char *wpend_buf; + int wpend_off; /* offset to data to write */ + int wpend_len; /* number of bytes passwd to write */ + int wpend_ret; /* number of bytes to return to caller */ + /* buffer raw data */ + int rbuf_left; + int rbuf_offs; + unsigned char *rbuf; + unsigned char *wbuf; + unsigned char *write_ptr; /* used to point to the start due to 2/3 byte + * header. */ + unsigned int padding; + unsigned int rlength; /* passed to ssl2_enc */ + int ract_data_length; /* Set when things are encrypted. */ + unsigned int wlength; /* passed to ssl2_enc */ + int wact_data_length; /* Set when things are decrypted. */ + unsigned char *ract_data; + unsigned char *wact_data; + unsigned char *mac_data; + unsigned char *read_key; + unsigned char *write_key; + /* Stuff specifically to do with this SSL session */ + unsigned int challenge_length; + unsigned char challenge[SSL2_MAX_CHALLENGE_LENGTH]; + unsigned int conn_id_length; + unsigned char conn_id[SSL2_MAX_CONNECTION_ID_LENGTH]; + unsigned int key_material_length; + unsigned char key_material[SSL2_MAX_KEY_MATERIAL_LENGTH * 2]; + unsigned long read_sequence; + unsigned long write_sequence; + struct { + unsigned int conn_id_length; + unsigned int cert_type; + unsigned int cert_length; + unsigned int csl; + unsigned int clear; + unsigned int enc; + unsigned char ccl[SSL2_MAX_CERT_CHALLENGE_LENGTH]; + unsigned int cipher_spec_length; + unsigned int session_id_length; + unsigned int clen; + unsigned int rlen; + } tmp; +} SSL2_STATE; + +# endif + +/* SSLv2 */ +/* client */ +# define SSL2_ST_SEND_CLIENT_HELLO_A (0x10|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_HELLO_B (0x11|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_HELLO_A (0x20|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_HELLO_B (0x21|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_MASTER_KEY_A (0x30|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_MASTER_KEY_B (0x31|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_FINISHED_A (0x40|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_FINISHED_B (0x41|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_CERTIFICATE_A (0x50|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_CERTIFICATE_B (0x51|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_CERTIFICATE_C (0x52|SSL_ST_CONNECT) +# define SSL2_ST_SEND_CLIENT_CERTIFICATE_D (0x53|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_VERIFY_A (0x60|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_VERIFY_B (0x61|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_FINISHED_A (0x70|SSL_ST_CONNECT) +# define SSL2_ST_GET_SERVER_FINISHED_B (0x71|SSL_ST_CONNECT) +# define SSL2_ST_CLIENT_START_ENCRYPTION (0x80|SSL_ST_CONNECT) +# define SSL2_ST_X509_GET_CLIENT_CERTIFICATE (0x90|SSL_ST_CONNECT) +/* server */ +# define SSL2_ST_GET_CLIENT_HELLO_A (0x10|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_HELLO_B (0x11|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_HELLO_C (0x12|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_HELLO_A (0x20|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_HELLO_B (0x21|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_MASTER_KEY_A (0x30|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_MASTER_KEY_B (0x31|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_VERIFY_A (0x40|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_VERIFY_B (0x41|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_VERIFY_C (0x42|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_FINISHED_A (0x50|SSL_ST_ACCEPT) +# define SSL2_ST_GET_CLIENT_FINISHED_B (0x51|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_FINISHED_A (0x60|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_SERVER_FINISHED_B (0x61|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_REQUEST_CERTIFICATE_A (0x70|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_REQUEST_CERTIFICATE_B (0x71|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_REQUEST_CERTIFICATE_C (0x72|SSL_ST_ACCEPT) +# define SSL2_ST_SEND_REQUEST_CERTIFICATE_D (0x73|SSL_ST_ACCEPT) +# define SSL2_ST_SERVER_START_ENCRYPTION (0x80|SSL_ST_ACCEPT) +# define SSL2_ST_X509_GET_SERVER_CERTIFICATE (0x90|SSL_ST_ACCEPT) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/include/openssl/ssl23.h b/libs/openssl/include/openssl/ssl23.h new file mode 100644 index 00000000..9de4685a --- /dev/null +++ b/libs/openssl/include/openssl/ssl23.h @@ -0,0 +1,84 @@ +/* ssl/ssl23.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#ifndef HEADER_SSL23_H +# define HEADER_SSL23_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * client + */ +/* write to server */ +# define SSL23_ST_CW_CLNT_HELLO_A (0x210|SSL_ST_CONNECT) +# define SSL23_ST_CW_CLNT_HELLO_B (0x211|SSL_ST_CONNECT) +/* read from server */ +# define SSL23_ST_CR_SRVR_HELLO_A (0x220|SSL_ST_CONNECT) +# define SSL23_ST_CR_SRVR_HELLO_B (0x221|SSL_ST_CONNECT) + +/* server */ +/* read from client */ +# define SSL23_ST_SR_CLNT_HELLO_A (0x210|SSL_ST_ACCEPT) +# define SSL23_ST_SR_CLNT_HELLO_B (0x211|SSL_ST_ACCEPT) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/include/openssl/ssl3.h b/libs/openssl/include/openssl/ssl3.h new file mode 100644 index 00000000..e9b1170d --- /dev/null +++ b/libs/openssl/include/openssl/ssl3.h @@ -0,0 +1,732 @@ +/* ssl/ssl3.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#ifndef HEADER_SSL3_H +# define HEADER_SSL3_H + +# ifndef OPENSSL_NO_COMP +# include +# endif +# include +# include +# include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Signalling cipher suite value from RFC 5746 + * (TLS_EMPTY_RENEGOTIATION_INFO_SCSV) + */ +# define SSL3_CK_SCSV 0x030000FF + +/* + * Signalling cipher suite value from draft-ietf-tls-downgrade-scsv-00 + * (TLS_FALLBACK_SCSV) + */ +# define SSL3_CK_FALLBACK_SCSV 0x03005600 + +# define SSL3_CK_RSA_NULL_MD5 0x03000001 +# define SSL3_CK_RSA_NULL_SHA 0x03000002 +# define SSL3_CK_RSA_RC4_40_MD5 0x03000003 +# define SSL3_CK_RSA_RC4_128_MD5 0x03000004 +# define SSL3_CK_RSA_RC4_128_SHA 0x03000005 +# define SSL3_CK_RSA_RC2_40_MD5 0x03000006 +# define SSL3_CK_RSA_IDEA_128_SHA 0x03000007 +# define SSL3_CK_RSA_DES_40_CBC_SHA 0x03000008 +# define SSL3_CK_RSA_DES_64_CBC_SHA 0x03000009 +# define SSL3_CK_RSA_DES_192_CBC3_SHA 0x0300000A + +# define SSL3_CK_DH_DSS_DES_40_CBC_SHA 0x0300000B +# define SSL3_CK_DH_DSS_DES_64_CBC_SHA 0x0300000C +# define SSL3_CK_DH_DSS_DES_192_CBC3_SHA 0x0300000D +# define SSL3_CK_DH_RSA_DES_40_CBC_SHA 0x0300000E +# define SSL3_CK_DH_RSA_DES_64_CBC_SHA 0x0300000F +# define SSL3_CK_DH_RSA_DES_192_CBC3_SHA 0x03000010 + +# define SSL3_CK_EDH_DSS_DES_40_CBC_SHA 0x03000011 +# define SSL3_CK_EDH_DSS_DES_64_CBC_SHA 0x03000012 +# define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA 0x03000013 +# define SSL3_CK_EDH_RSA_DES_40_CBC_SHA 0x03000014 +# define SSL3_CK_EDH_RSA_DES_64_CBC_SHA 0x03000015 +# define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA 0x03000016 + +# define SSL3_CK_ADH_RC4_40_MD5 0x03000017 +# define SSL3_CK_ADH_RC4_128_MD5 0x03000018 +# define SSL3_CK_ADH_DES_40_CBC_SHA 0x03000019 +# define SSL3_CK_ADH_DES_64_CBC_SHA 0x0300001A +# define SSL3_CK_ADH_DES_192_CBC_SHA 0x0300001B + +# if 0 +# define SSL3_CK_FZA_DMS_NULL_SHA 0x0300001C +# define SSL3_CK_FZA_DMS_FZA_SHA 0x0300001D +# if 0 /* Because it clashes with KRB5, is never + * used any more, and is safe to remove + * according to David Hopwood + * of the + * ietf-tls list */ +# define SSL3_CK_FZA_DMS_RC4_SHA 0x0300001E +# endif +# endif + +/* + * VRS Additional Kerberos5 entries + */ +# define SSL3_CK_KRB5_DES_64_CBC_SHA 0x0300001E +# define SSL3_CK_KRB5_DES_192_CBC3_SHA 0x0300001F +# define SSL3_CK_KRB5_RC4_128_SHA 0x03000020 +# define SSL3_CK_KRB5_IDEA_128_CBC_SHA 0x03000021 +# define SSL3_CK_KRB5_DES_64_CBC_MD5 0x03000022 +# define SSL3_CK_KRB5_DES_192_CBC3_MD5 0x03000023 +# define SSL3_CK_KRB5_RC4_128_MD5 0x03000024 +# define SSL3_CK_KRB5_IDEA_128_CBC_MD5 0x03000025 + +# define SSL3_CK_KRB5_DES_40_CBC_SHA 0x03000026 +# define SSL3_CK_KRB5_RC2_40_CBC_SHA 0x03000027 +# define SSL3_CK_KRB5_RC4_40_SHA 0x03000028 +# define SSL3_CK_KRB5_DES_40_CBC_MD5 0x03000029 +# define SSL3_CK_KRB5_RC2_40_CBC_MD5 0x0300002A +# define SSL3_CK_KRB5_RC4_40_MD5 0x0300002B + +# define SSL3_TXT_RSA_NULL_MD5 "NULL-MD5" +# define SSL3_TXT_RSA_NULL_SHA "NULL-SHA" +# define SSL3_TXT_RSA_RC4_40_MD5 "EXP-RC4-MD5" +# define SSL3_TXT_RSA_RC4_128_MD5 "RC4-MD5" +# define SSL3_TXT_RSA_RC4_128_SHA "RC4-SHA" +# define SSL3_TXT_RSA_RC2_40_MD5 "EXP-RC2-CBC-MD5" +# define SSL3_TXT_RSA_IDEA_128_SHA "IDEA-CBC-SHA" +# define SSL3_TXT_RSA_DES_40_CBC_SHA "EXP-DES-CBC-SHA" +# define SSL3_TXT_RSA_DES_64_CBC_SHA "DES-CBC-SHA" +# define SSL3_TXT_RSA_DES_192_CBC3_SHA "DES-CBC3-SHA" + +# define SSL3_TXT_DH_DSS_DES_40_CBC_SHA "EXP-DH-DSS-DES-CBC-SHA" +# define SSL3_TXT_DH_DSS_DES_64_CBC_SHA "DH-DSS-DES-CBC-SHA" +# define SSL3_TXT_DH_DSS_DES_192_CBC3_SHA "DH-DSS-DES-CBC3-SHA" +# define SSL3_TXT_DH_RSA_DES_40_CBC_SHA "EXP-DH-RSA-DES-CBC-SHA" +# define SSL3_TXT_DH_RSA_DES_64_CBC_SHA "DH-RSA-DES-CBC-SHA" +# define SSL3_TXT_DH_RSA_DES_192_CBC3_SHA "DH-RSA-DES-CBC3-SHA" + +# define SSL3_TXT_EDH_DSS_DES_40_CBC_SHA "EXP-EDH-DSS-DES-CBC-SHA" +# define SSL3_TXT_EDH_DSS_DES_64_CBC_SHA "EDH-DSS-DES-CBC-SHA" +# define SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA "EDH-DSS-DES-CBC3-SHA" +# define SSL3_TXT_EDH_RSA_DES_40_CBC_SHA "EXP-EDH-RSA-DES-CBC-SHA" +# define SSL3_TXT_EDH_RSA_DES_64_CBC_SHA "EDH-RSA-DES-CBC-SHA" +# define SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA "EDH-RSA-DES-CBC3-SHA" + +# define SSL3_TXT_ADH_RC4_40_MD5 "EXP-ADH-RC4-MD5" +# define SSL3_TXT_ADH_RC4_128_MD5 "ADH-RC4-MD5" +# define SSL3_TXT_ADH_DES_40_CBC_SHA "EXP-ADH-DES-CBC-SHA" +# define SSL3_TXT_ADH_DES_64_CBC_SHA "ADH-DES-CBC-SHA" +# define SSL3_TXT_ADH_DES_192_CBC_SHA "ADH-DES-CBC3-SHA" + +# if 0 +# define SSL3_TXT_FZA_DMS_NULL_SHA "FZA-NULL-SHA" +# define SSL3_TXT_FZA_DMS_FZA_SHA "FZA-FZA-CBC-SHA" +# define SSL3_TXT_FZA_DMS_RC4_SHA "FZA-RC4-SHA" +# endif + +# define SSL3_TXT_KRB5_DES_64_CBC_SHA "KRB5-DES-CBC-SHA" +# define SSL3_TXT_KRB5_DES_192_CBC3_SHA "KRB5-DES-CBC3-SHA" +# define SSL3_TXT_KRB5_RC4_128_SHA "KRB5-RC4-SHA" +# define SSL3_TXT_KRB5_IDEA_128_CBC_SHA "KRB5-IDEA-CBC-SHA" +# define SSL3_TXT_KRB5_DES_64_CBC_MD5 "KRB5-DES-CBC-MD5" +# define SSL3_TXT_KRB5_DES_192_CBC3_MD5 "KRB5-DES-CBC3-MD5" +# define SSL3_TXT_KRB5_RC4_128_MD5 "KRB5-RC4-MD5" +# define SSL3_TXT_KRB5_IDEA_128_CBC_MD5 "KRB5-IDEA-CBC-MD5" + +# define SSL3_TXT_KRB5_DES_40_CBC_SHA "EXP-KRB5-DES-CBC-SHA" +# define SSL3_TXT_KRB5_RC2_40_CBC_SHA "EXP-KRB5-RC2-CBC-SHA" +# define SSL3_TXT_KRB5_RC4_40_SHA "EXP-KRB5-RC4-SHA" +# define SSL3_TXT_KRB5_DES_40_CBC_MD5 "EXP-KRB5-DES-CBC-MD5" +# define SSL3_TXT_KRB5_RC2_40_CBC_MD5 "EXP-KRB5-RC2-CBC-MD5" +# define SSL3_TXT_KRB5_RC4_40_MD5 "EXP-KRB5-RC4-MD5" + +# define SSL3_SSL_SESSION_ID_LENGTH 32 +# define SSL3_MAX_SSL_SESSION_ID_LENGTH 32 + +# define SSL3_MASTER_SECRET_SIZE 48 +# define SSL3_RANDOM_SIZE 32 +# define SSL3_SESSION_ID_SIZE 32 +# define SSL3_RT_HEADER_LENGTH 5 + +# define SSL3_HM_HEADER_LENGTH 4 + +# ifndef SSL3_ALIGN_PAYLOAD + /* + * Some will argue that this increases memory footprint, but it's not + * actually true. Point is that malloc has to return at least 64-bit aligned + * pointers, meaning that allocating 5 bytes wastes 3 bytes in either case. + * Suggested pre-gaping simply moves these wasted bytes from the end of + * allocated region to its front, but makes data payload aligned, which + * improves performance:-) + */ +# define SSL3_ALIGN_PAYLOAD 8 +# else +# if (SSL3_ALIGN_PAYLOAD&(SSL3_ALIGN_PAYLOAD-1))!=0 +# error "insane SSL3_ALIGN_PAYLOAD" +# undef SSL3_ALIGN_PAYLOAD +# endif +# endif + +/* + * This is the maximum MAC (digest) size used by the SSL library. Currently + * maximum of 20 is used by SHA1, but we reserve for future extension for + * 512-bit hashes. + */ + +# define SSL3_RT_MAX_MD_SIZE 64 + +/* + * Maximum block size used in all ciphersuites. Currently 16 for AES. + */ + +# define SSL_RT_MAX_CIPHER_BLOCK_SIZE 16 + +# define SSL3_RT_MAX_EXTRA (16384) + +/* Maximum plaintext length: defined by SSL/TLS standards */ +# define SSL3_RT_MAX_PLAIN_LENGTH 16384 +/* Maximum compression overhead: defined by SSL/TLS standards */ +# define SSL3_RT_MAX_COMPRESSED_OVERHEAD 1024 + +/* + * The standards give a maximum encryption overhead of 1024 bytes. In + * practice the value is lower than this. The overhead is the maximum number + * of padding bytes (256) plus the mac size. + */ +# define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE) + +/* + * OpenSSL currently only uses a padding length of at most one block so the + * send overhead is smaller. + */ + +# define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + (SSL_RT_MAX_CIPHER_BLOCK_SIZE + SSL3_RT_MAX_MD_SIZE) + +/* If compression isn't used don't include the compression overhead */ + +# ifdef OPENSSL_NO_COMP +# define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH +# else +# define SSL3_RT_MAX_COMPRESSED_LENGTH \ + (SSL3_RT_MAX_PLAIN_LENGTH+SSL3_RT_MAX_COMPRESSED_OVERHEAD) +# endif +# define SSL3_RT_MAX_ENCRYPTED_LENGTH \ + (SSL3_RT_MAX_ENCRYPTED_OVERHEAD+SSL3_RT_MAX_COMPRESSED_LENGTH) +# define SSL3_RT_MAX_PACKET_SIZE \ + (SSL3_RT_MAX_ENCRYPTED_LENGTH+SSL3_RT_HEADER_LENGTH) + +# define SSL3_MD_CLIENT_FINISHED_CONST "\x43\x4C\x4E\x54" +# define SSL3_MD_SERVER_FINISHED_CONST "\x53\x52\x56\x52" + +# define SSL3_VERSION 0x0300 +# define SSL3_VERSION_MAJOR 0x03 +# define SSL3_VERSION_MINOR 0x00 + +# define SSL3_RT_CHANGE_CIPHER_SPEC 20 +# define SSL3_RT_ALERT 21 +# define SSL3_RT_HANDSHAKE 22 +# define SSL3_RT_APPLICATION_DATA 23 +# define TLS1_RT_HEARTBEAT 24 + +# define SSL3_AL_WARNING 1 +# define SSL3_AL_FATAL 2 + +# define SSL3_AD_CLOSE_NOTIFY 0 +# define SSL3_AD_UNEXPECTED_MESSAGE 10/* fatal */ +# define SSL3_AD_BAD_RECORD_MAC 20/* fatal */ +# define SSL3_AD_DECOMPRESSION_FAILURE 30/* fatal */ +# define SSL3_AD_HANDSHAKE_FAILURE 40/* fatal */ +# define SSL3_AD_NO_CERTIFICATE 41 +# define SSL3_AD_BAD_CERTIFICATE 42 +# define SSL3_AD_UNSUPPORTED_CERTIFICATE 43 +# define SSL3_AD_CERTIFICATE_REVOKED 44 +# define SSL3_AD_CERTIFICATE_EXPIRED 45 +# define SSL3_AD_CERTIFICATE_UNKNOWN 46 +# define SSL3_AD_ILLEGAL_PARAMETER 47/* fatal */ + +# define TLS1_HB_REQUEST 1 +# define TLS1_HB_RESPONSE 2 + +# ifndef OPENSSL_NO_SSL_INTERN + +typedef struct ssl3_record_st { + /* type of record */ + /* + * r + */ int type; + /* How many bytes available */ + /* + * rw + */ unsigned int length; + /* read/write offset into 'buf' */ + /* + * r + */ unsigned int off; + /* pointer to the record data */ + /* + * rw + */ unsigned char *data; + /* where the decode bytes are */ + /* + * rw + */ unsigned char *input; + /* only used with decompression - malloc()ed */ + /* + * r + */ unsigned char *comp; + /* epoch number, needed by DTLS1 */ + /* + * r + */ unsigned long epoch; + /* sequence number, needed by DTLS1 */ + /* + * r + */ unsigned char seq_num[8]; +} SSL3_RECORD; + +typedef struct ssl3_buffer_st { + /* at least SSL3_RT_MAX_PACKET_SIZE bytes, see ssl3_setup_buffers() */ + unsigned char *buf; + /* buffer size */ + size_t len; + /* where to 'copy from' */ + int offset; + /* how many bytes left */ + int left; +} SSL3_BUFFER; + +# endif + +# define SSL3_CT_RSA_SIGN 1 +# define SSL3_CT_DSS_SIGN 2 +# define SSL3_CT_RSA_FIXED_DH 3 +# define SSL3_CT_DSS_FIXED_DH 4 +# define SSL3_CT_RSA_EPHEMERAL_DH 5 +# define SSL3_CT_DSS_EPHEMERAL_DH 6 +# define SSL3_CT_FORTEZZA_DMS 20 +/* + * SSL3_CT_NUMBER is used to size arrays and it must be large enough to + * contain all of the cert types defined either for SSLv3 and TLSv1. + */ +# define SSL3_CT_NUMBER 9 + +# define SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS 0x0001 +# define SSL3_FLAGS_DELAY_CLIENT_FINISHED 0x0002 +# define SSL3_FLAGS_POP_BUFFER 0x0004 +# define TLS1_FLAGS_TLS_PADDING_BUG 0x0008 +# define TLS1_FLAGS_SKIP_CERT_VERIFY 0x0010 +# define TLS1_FLAGS_KEEP_HANDSHAKE 0x0020 +/* + * Set when the handshake is ready to process peer's ChangeCipherSpec message. + * Cleared after the message has been processed. + */ +# define SSL3_FLAGS_CCS_OK 0x0080 + +/* + * SSL3_FLAGS_SGC_RESTART_DONE is set when we restart a handshake because of + * MS SGC and so prevents us from restarting the handshake in a loop. It's + * reset on a renegotiation, so effectively limits the client to one restart + * per negotiation. This limits the possibility of a DDoS attack where the + * client handshakes in a loop using SGC to restart. Servers which permit + * renegotiation can still be effected, but we can't prevent that. + */ +# define SSL3_FLAGS_SGC_RESTART_DONE 0x0040 + +# ifndef OPENSSL_NO_SSL_INTERN + +typedef struct ssl3_state_st { + long flags; + int delay_buf_pop_ret; + unsigned char read_sequence[8]; + int read_mac_secret_size; + unsigned char read_mac_secret[EVP_MAX_MD_SIZE]; + unsigned char write_sequence[8]; + int write_mac_secret_size; + unsigned char write_mac_secret[EVP_MAX_MD_SIZE]; + unsigned char server_random[SSL3_RANDOM_SIZE]; + unsigned char client_random[SSL3_RANDOM_SIZE]; + /* flags for countermeasure against known-IV weakness */ + int need_empty_fragments; + int empty_fragment_done; + /* The value of 'extra' when the buffers were initialized */ + int init_extra; + SSL3_BUFFER rbuf; /* read IO goes into here */ + SSL3_BUFFER wbuf; /* write IO goes into here */ + SSL3_RECORD rrec; /* each decoded record goes in here */ + SSL3_RECORD wrec; /* goes out from here */ + /* + * storage for Alert/Handshake protocol data received but not yet + * processed by ssl3_read_bytes: + */ + unsigned char alert_fragment[2]; + unsigned int alert_fragment_len; + unsigned char handshake_fragment[4]; + unsigned int handshake_fragment_len; + /* partial write - check the numbers match */ + unsigned int wnum; /* number of bytes sent so far */ + int wpend_tot; /* number bytes written */ + int wpend_type; + int wpend_ret; /* number of bytes submitted */ + const unsigned char *wpend_buf; + /* used during startup, digest all incoming/outgoing packets */ + BIO *handshake_buffer; + /* + * When set of handshake digests is determined, buffer is hashed and + * freed and MD_CTX-es for all required digests are stored in this array + */ + EVP_MD_CTX **handshake_dgst; + /* + * Set whenever an expected ChangeCipherSpec message is processed. + * Unset when the peer's Finished message is received. + * Unexpected ChangeCipherSpec messages trigger a fatal alert. + */ + int change_cipher_spec; + int warn_alert; + int fatal_alert; + /* + * we allow one fatal and one warning alert to be outstanding, send close + * alert via the warning alert + */ + int alert_dispatch; + unsigned char send_alert[2]; + /* + * This flag is set when we should renegotiate ASAP, basically when there + * is no more data in the read or write buffers + */ + int renegotiate; + int total_renegotiations; + int num_renegotiations; + int in_read_app_data; + /* + * Opaque PRF input as used for the current handshake. These fields are + * used only if TLSEXT_TYPE_opaque_prf_input is defined (otherwise, they + * are merely present to improve binary compatibility) + */ + void *client_opaque_prf_input; + size_t client_opaque_prf_input_len; + void *server_opaque_prf_input; + size_t server_opaque_prf_input_len; + struct { + /* actually only needs to be 16+20 */ + unsigned char cert_verify_md[EVP_MAX_MD_SIZE * 2]; + /* actually only need to be 16+20 for SSLv3 and 12 for TLS */ + unsigned char finish_md[EVP_MAX_MD_SIZE * 2]; + int finish_md_len; + unsigned char peer_finish_md[EVP_MAX_MD_SIZE * 2]; + int peer_finish_md_len; + unsigned long message_size; + int message_type; + /* used to hold the new cipher we are going to use */ + const SSL_CIPHER *new_cipher; +# ifndef OPENSSL_NO_DH + DH *dh; +# endif +# ifndef OPENSSL_NO_ECDH + EC_KEY *ecdh; /* holds short lived ECDH key */ +# endif + /* used when SSL_ST_FLUSH_DATA is entered */ + int next_state; + int reuse_message; + /* used for certificate requests */ + int cert_req; + int ctype_num; + char ctype[SSL3_CT_NUMBER]; + STACK_OF(X509_NAME) *ca_names; + int use_rsa_tmp; + int key_block_length; + unsigned char *key_block; + const EVP_CIPHER *new_sym_enc; + const EVP_MD *new_hash; + int new_mac_pkey_type; + int new_mac_secret_size; +# ifndef OPENSSL_NO_COMP + const SSL_COMP *new_compression; +# else + char *new_compression; +# endif + int cert_request; + } tmp; + + /* Connection binding to prevent renegotiation attacks */ + unsigned char previous_client_finished[EVP_MAX_MD_SIZE]; + unsigned char previous_client_finished_len; + unsigned char previous_server_finished[EVP_MAX_MD_SIZE]; + unsigned char previous_server_finished_len; + int send_connection_binding; /* TODOEKR */ + +# ifndef OPENSSL_NO_NEXTPROTONEG + /* + * Set if we saw the Next Protocol Negotiation extension from our peer. + */ + int next_proto_neg_seen; +# endif + +# ifndef OPENSSL_NO_TLSEXT +# ifndef OPENSSL_NO_EC + /* + * This is set to true if we believe that this is a version of Safari + * running on OS X 10.6 or newer. We wish to know this because Safari on + * 10.8 .. 10.8.3 has broken ECDHE-ECDSA support. + */ + char is_probably_safari; +# endif /* !OPENSSL_NO_EC */ +# endif /* !OPENSSL_NO_TLSEXT */ +} SSL3_STATE; + +# endif + +/* SSLv3 */ +/* + * client + */ +/* extra state */ +# define SSL3_ST_CW_FLUSH (0x100|SSL_ST_CONNECT) +# ifndef OPENSSL_NO_SCTP +# define DTLS1_SCTP_ST_CW_WRITE_SOCK (0x310|SSL_ST_CONNECT) +# define DTLS1_SCTP_ST_CR_READ_SOCK (0x320|SSL_ST_CONNECT) +# endif +/* write to server */ +# define SSL3_ST_CW_CLNT_HELLO_A (0x110|SSL_ST_CONNECT) +# define SSL3_ST_CW_CLNT_HELLO_B (0x111|SSL_ST_CONNECT) +/* read from server */ +# define SSL3_ST_CR_SRVR_HELLO_A (0x120|SSL_ST_CONNECT) +# define SSL3_ST_CR_SRVR_HELLO_B (0x121|SSL_ST_CONNECT) +# define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A (0x126|SSL_ST_CONNECT) +# define DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B (0x127|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_A (0x130|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_B (0x131|SSL_ST_CONNECT) +# define SSL3_ST_CR_KEY_EXCH_A (0x140|SSL_ST_CONNECT) +# define SSL3_ST_CR_KEY_EXCH_B (0x141|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_REQ_A (0x150|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_REQ_B (0x151|SSL_ST_CONNECT) +# define SSL3_ST_CR_SRVR_DONE_A (0x160|SSL_ST_CONNECT) +# define SSL3_ST_CR_SRVR_DONE_B (0x161|SSL_ST_CONNECT) +/* write to server */ +# define SSL3_ST_CW_CERT_A (0x170|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_B (0x171|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_C (0x172|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_D (0x173|SSL_ST_CONNECT) +# define SSL3_ST_CW_KEY_EXCH_A (0x180|SSL_ST_CONNECT) +# define SSL3_ST_CW_KEY_EXCH_B (0x181|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_VRFY_A (0x190|SSL_ST_CONNECT) +# define SSL3_ST_CW_CERT_VRFY_B (0x191|SSL_ST_CONNECT) +# define SSL3_ST_CW_CHANGE_A (0x1A0|SSL_ST_CONNECT) +# define SSL3_ST_CW_CHANGE_B (0x1A1|SSL_ST_CONNECT) +# ifndef OPENSSL_NO_NEXTPROTONEG +# define SSL3_ST_CW_NEXT_PROTO_A (0x200|SSL_ST_CONNECT) +# define SSL3_ST_CW_NEXT_PROTO_B (0x201|SSL_ST_CONNECT) +# endif +# define SSL3_ST_CW_FINISHED_A (0x1B0|SSL_ST_CONNECT) +# define SSL3_ST_CW_FINISHED_B (0x1B1|SSL_ST_CONNECT) +/* read from server */ +# define SSL3_ST_CR_CHANGE_A (0x1C0|SSL_ST_CONNECT) +# define SSL3_ST_CR_CHANGE_B (0x1C1|SSL_ST_CONNECT) +# define SSL3_ST_CR_FINISHED_A (0x1D0|SSL_ST_CONNECT) +# define SSL3_ST_CR_FINISHED_B (0x1D1|SSL_ST_CONNECT) +# define SSL3_ST_CR_SESSION_TICKET_A (0x1E0|SSL_ST_CONNECT) +# define SSL3_ST_CR_SESSION_TICKET_B (0x1E1|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_STATUS_A (0x1F0|SSL_ST_CONNECT) +# define SSL3_ST_CR_CERT_STATUS_B (0x1F1|SSL_ST_CONNECT) + +/* server */ +/* extra state */ +# define SSL3_ST_SW_FLUSH (0x100|SSL_ST_ACCEPT) +# ifndef OPENSSL_NO_SCTP +# define DTLS1_SCTP_ST_SW_WRITE_SOCK (0x310|SSL_ST_ACCEPT) +# define DTLS1_SCTP_ST_SR_READ_SOCK (0x320|SSL_ST_ACCEPT) +# endif +/* read from client */ +/* Do not change the number values, they do matter */ +# define SSL3_ST_SR_CLNT_HELLO_A (0x110|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CLNT_HELLO_B (0x111|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CLNT_HELLO_C (0x112|SSL_ST_ACCEPT) +/* write to client */ +# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A (0x113|SSL_ST_ACCEPT) +# define DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B (0x114|SSL_ST_ACCEPT) +# define SSL3_ST_SW_HELLO_REQ_A (0x120|SSL_ST_ACCEPT) +# define SSL3_ST_SW_HELLO_REQ_B (0x121|SSL_ST_ACCEPT) +# define SSL3_ST_SW_HELLO_REQ_C (0x122|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SRVR_HELLO_A (0x130|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SRVR_HELLO_B (0x131|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_A (0x140|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_B (0x141|SSL_ST_ACCEPT) +# define SSL3_ST_SW_KEY_EXCH_A (0x150|SSL_ST_ACCEPT) +# define SSL3_ST_SW_KEY_EXCH_B (0x151|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_REQ_A (0x160|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_REQ_B (0x161|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SRVR_DONE_A (0x170|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SRVR_DONE_B (0x171|SSL_ST_ACCEPT) +/* read from client */ +# define SSL3_ST_SR_CERT_A (0x180|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CERT_B (0x181|SSL_ST_ACCEPT) +# define SSL3_ST_SR_KEY_EXCH_A (0x190|SSL_ST_ACCEPT) +# define SSL3_ST_SR_KEY_EXCH_B (0x191|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CERT_VRFY_A (0x1A0|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CERT_VRFY_B (0x1A1|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CHANGE_A (0x1B0|SSL_ST_ACCEPT) +# define SSL3_ST_SR_CHANGE_B (0x1B1|SSL_ST_ACCEPT) +# ifndef OPENSSL_NO_NEXTPROTONEG +# define SSL3_ST_SR_NEXT_PROTO_A (0x210|SSL_ST_ACCEPT) +# define SSL3_ST_SR_NEXT_PROTO_B (0x211|SSL_ST_ACCEPT) +# endif +# define SSL3_ST_SR_FINISHED_A (0x1C0|SSL_ST_ACCEPT) +# define SSL3_ST_SR_FINISHED_B (0x1C1|SSL_ST_ACCEPT) +/* write to client */ +# define SSL3_ST_SW_CHANGE_A (0x1D0|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CHANGE_B (0x1D1|SSL_ST_ACCEPT) +# define SSL3_ST_SW_FINISHED_A (0x1E0|SSL_ST_ACCEPT) +# define SSL3_ST_SW_FINISHED_B (0x1E1|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SESSION_TICKET_A (0x1F0|SSL_ST_ACCEPT) +# define SSL3_ST_SW_SESSION_TICKET_B (0x1F1|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_STATUS_A (0x200|SSL_ST_ACCEPT) +# define SSL3_ST_SW_CERT_STATUS_B (0x201|SSL_ST_ACCEPT) + +# define SSL3_MT_HELLO_REQUEST 0 +# define SSL3_MT_CLIENT_HELLO 1 +# define SSL3_MT_SERVER_HELLO 2 +# define SSL3_MT_NEWSESSION_TICKET 4 +# define SSL3_MT_CERTIFICATE 11 +# define SSL3_MT_SERVER_KEY_EXCHANGE 12 +# define SSL3_MT_CERTIFICATE_REQUEST 13 +# define SSL3_MT_SERVER_DONE 14 +# define SSL3_MT_CERTIFICATE_VERIFY 15 +# define SSL3_MT_CLIENT_KEY_EXCHANGE 16 +# define SSL3_MT_FINISHED 20 +# define SSL3_MT_CERTIFICATE_STATUS 22 +# ifndef OPENSSL_NO_NEXTPROTONEG +# define SSL3_MT_NEXT_PROTO 67 +# endif +# define DTLS1_MT_HELLO_VERIFY_REQUEST 3 + +# define SSL3_MT_CCS 1 + +/* These are used when changing over to a new cipher */ +# define SSL3_CC_READ 0x01 +# define SSL3_CC_WRITE 0x02 +# define SSL3_CC_CLIENT 0x10 +# define SSL3_CC_SERVER 0x20 +# define SSL3_CHANGE_CIPHER_CLIENT_WRITE (SSL3_CC_CLIENT|SSL3_CC_WRITE) +# define SSL3_CHANGE_CIPHER_SERVER_READ (SSL3_CC_SERVER|SSL3_CC_READ) +# define SSL3_CHANGE_CIPHER_CLIENT_READ (SSL3_CC_CLIENT|SSL3_CC_READ) +# define SSL3_CHANGE_CIPHER_SERVER_WRITE (SSL3_CC_SERVER|SSL3_CC_WRITE) + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/include/openssl/ssl_locl.h b/libs/openssl/include/openssl/ssl_locl.h new file mode 100644 index 00000000..d57b902f --- /dev/null +++ b/libs/openssl/include/openssl/ssl_locl.h @@ -0,0 +1,1246 @@ +/* ssl/ssl_locl.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_SSL_LOCL_H +# define HEADER_SSL_LOCL_H +# include +# include +# include +# include + +# include "e_os.h" + +# include +# ifndef OPENSSL_NO_COMP +# include +# endif +# include +# include +# ifndef OPENSSL_NO_RSA +# include +# endif +# ifndef OPENSSL_NO_DSA +# include +# endif +# include +# include +# include + +# ifdef OPENSSL_BUILD_SHLIBSSL +# undef OPENSSL_EXTERN +# define OPENSSL_EXTERN OPENSSL_EXPORT +# endif + +# undef PKCS1_CHECK + +# define c2l(c,l) (l = ((unsigned long)(*((c)++))) , \ + l|=(((unsigned long)(*((c)++)))<< 8), \ + l|=(((unsigned long)(*((c)++)))<<16), \ + l|=(((unsigned long)(*((c)++)))<<24)) + +/* NOTE - c is not incremented as per c2l */ +# define c2ln(c,l1,l2,n) { \ + c+=n; \ + l1=l2=0; \ + switch (n) { \ + case 8: l2 =((unsigned long)(*(--(c))))<<24; \ + case 7: l2|=((unsigned long)(*(--(c))))<<16; \ + case 6: l2|=((unsigned long)(*(--(c))))<< 8; \ + case 5: l2|=((unsigned long)(*(--(c)))); \ + case 4: l1 =((unsigned long)(*(--(c))))<<24; \ + case 3: l1|=((unsigned long)(*(--(c))))<<16; \ + case 2: l1|=((unsigned long)(*(--(c))))<< 8; \ + case 1: l1|=((unsigned long)(*(--(c)))); \ + } \ + } + +# define l2c(l,c) (*((c)++)=(unsigned char)(((l) )&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff)) + +# define n2l(c,l) (l =((unsigned long)(*((c)++)))<<24, \ + l|=((unsigned long)(*((c)++)))<<16, \ + l|=((unsigned long)(*((c)++)))<< 8, \ + l|=((unsigned long)(*((c)++)))) + +# define l2n(l,c) (*((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +# define l2n6(l,c) (*((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +# define l2n8(l,c) (*((c)++)=(unsigned char)(((l)>>56)&0xff), \ + *((c)++)=(unsigned char)(((l)>>48)&0xff), \ + *((c)++)=(unsigned char)(((l)>>40)&0xff), \ + *((c)++)=(unsigned char)(((l)>>32)&0xff), \ + *((c)++)=(unsigned char)(((l)>>24)&0xff), \ + *((c)++)=(unsigned char)(((l)>>16)&0xff), \ + *((c)++)=(unsigned char)(((l)>> 8)&0xff), \ + *((c)++)=(unsigned char)(((l) )&0xff)) + +# define n2l6(c,l) (l =((BN_ULLONG)(*((c)++)))<<40, \ + l|=((BN_ULLONG)(*((c)++)))<<32, \ + l|=((BN_ULLONG)(*((c)++)))<<24, \ + l|=((BN_ULLONG)(*((c)++)))<<16, \ + l|=((BN_ULLONG)(*((c)++)))<< 8, \ + l|=((BN_ULLONG)(*((c)++)))) + +/* NOTE - c is not incremented as per l2c */ +# define l2cn(l1,l2,c,n) { \ + c+=n; \ + switch (n) { \ + case 8: *(--(c))=(unsigned char)(((l2)>>24)&0xff); \ + case 7: *(--(c))=(unsigned char)(((l2)>>16)&0xff); \ + case 6: *(--(c))=(unsigned char)(((l2)>> 8)&0xff); \ + case 5: *(--(c))=(unsigned char)(((l2) )&0xff); \ + case 4: *(--(c))=(unsigned char)(((l1)>>24)&0xff); \ + case 3: *(--(c))=(unsigned char)(((l1)>>16)&0xff); \ + case 2: *(--(c))=(unsigned char)(((l1)>> 8)&0xff); \ + case 1: *(--(c))=(unsigned char)(((l1) )&0xff); \ + } \ + } + +# define n2s(c,s) ((s=(((unsigned int)(c[0]))<< 8)| \ + (((unsigned int)(c[1])) )),c+=2) +# define s2n(s,c) ((c[0]=(unsigned char)(((s)>> 8)&0xff), \ + c[1]=(unsigned char)(((s) )&0xff)),c+=2) + +# define n2l3(c,l) ((l =(((unsigned long)(c[0]))<<16)| \ + (((unsigned long)(c[1]))<< 8)| \ + (((unsigned long)(c[2])) )),c+=3) + +# define l2n3(l,c) ((c[0]=(unsigned char)(((l)>>16)&0xff), \ + c[1]=(unsigned char)(((l)>> 8)&0xff), \ + c[2]=(unsigned char)(((l) )&0xff)),c+=3) + +/* LOCAL STUFF */ + +# define SSL_DECRYPT 0 +# define SSL_ENCRYPT 1 + +# define TWO_BYTE_BIT 0x80 +# define SEC_ESC_BIT 0x40 +# define TWO_BYTE_MASK 0x7fff +# define THREE_BYTE_MASK 0x3fff + +# define INC32(a) ((a)=((a)+1)&0xffffffffL) +# define DEC32(a) ((a)=((a)-1)&0xffffffffL) +# define MAX_MAC_SIZE 20 /* up from 16 for SSLv3 */ + +/* + * Define the Bitmasks for SSL_CIPHER.algorithms. + * This bits are used packed as dense as possible. If new methods/ciphers + * etc will be added, the bits a likely to change, so this information + * is for internal library use only, even though SSL_CIPHER.algorithms + * can be publicly accessed. + * Use the according functions for cipher management instead. + * + * The bit mask handling in the selection and sorting scheme in + * ssl_create_cipher_list() has only limited capabilities, reflecting + * that the different entities within are mutually exclusive: + * ONLY ONE BIT PER MASK CAN BE SET AT A TIME. + */ + +/* Bits for algorithm_mkey (key exchange algorithm) */ +/* RSA key exchange */ +# define SSL_kRSA 0x00000001L +/* DH cert, RSA CA cert */ +/* no such ciphersuites supported! */ +# define SSL_kDHr 0x00000002L +/* DH cert, DSA CA cert */ +/* no such ciphersuite supported! */ +# define SSL_kDHd 0x00000004L +/* tmp DH key no DH cert */ +# define SSL_kEDH 0x00000008L +/* Kerberos5 key exchange */ +# define SSL_kKRB5 0x00000010L +/* ECDH cert, RSA CA cert */ +# define SSL_kECDHr 0x00000020L +/* ECDH cert, ECDSA CA cert */ +# define SSL_kECDHe 0x00000040L +/* ephemeral ECDH */ +# define SSL_kEECDH 0x00000080L +/* PSK */ +# define SSL_kPSK 0x00000100L +/* GOST key exchange */ +# define SSL_kGOST 0x00000200L +/* SRP */ +# define SSL_kSRP 0x00000400L + +/* Bits for algorithm_auth (server authentication) */ +/* RSA auth */ +# define SSL_aRSA 0x00000001L +/* DSS auth */ +# define SSL_aDSS 0x00000002L +/* no auth (i.e. use ADH or AECDH) */ +# define SSL_aNULL 0x00000004L +/* Fixed DH auth (kDHd or kDHr) */ +/* no such ciphersuites supported! */ +# define SSL_aDH 0x00000008L +/* Fixed ECDH auth (kECDHe or kECDHr) */ +# define SSL_aECDH 0x00000010L +/* KRB5 auth */ +# define SSL_aKRB5 0x00000020L +/* ECDSA auth*/ +# define SSL_aECDSA 0x00000040L +/* PSK auth */ +# define SSL_aPSK 0x00000080L +/* GOST R 34.10-94 signature auth */ +# define SSL_aGOST94 0x00000100L +/* GOST R 34.10-2001 signature auth */ +# define SSL_aGOST01 0x00000200L +/* SRP auth */ +# define SSL_aSRP 0x00000400L + +/* Bits for algorithm_enc (symmetric encryption) */ +# define SSL_DES 0x00000001L +# define SSL_3DES 0x00000002L +# define SSL_RC4 0x00000004L +# define SSL_RC2 0x00000008L +# define SSL_IDEA 0x00000010L +# define SSL_eNULL 0x00000020L +# define SSL_AES128 0x00000040L +# define SSL_AES256 0x00000080L +# define SSL_CAMELLIA128 0x00000100L +# define SSL_CAMELLIA256 0x00000200L +# define SSL_eGOST2814789CNT 0x00000400L +# define SSL_SEED 0x00000800L +# define SSL_AES128GCM 0x00001000L +# define SSL_AES256GCM 0x00002000L + +# define SSL_AES (SSL_AES128|SSL_AES256|SSL_AES128GCM|SSL_AES256GCM) +# define SSL_CAMELLIA (SSL_CAMELLIA128|SSL_CAMELLIA256) + +/* Bits for algorithm_mac (symmetric authentication) */ + +# define SSL_MD5 0x00000001L +# define SSL_SHA1 0x00000002L +# define SSL_GOST94 0x00000004L +# define SSL_GOST89MAC 0x00000008L +# define SSL_SHA256 0x00000010L +# define SSL_SHA384 0x00000020L +/* Not a real MAC, just an indication it is part of cipher */ +# define SSL_AEAD 0x00000040L + +/* Bits for algorithm_ssl (protocol version) */ +# define SSL_SSLV2 0x00000001UL +# define SSL_SSLV3 0x00000002UL +# define SSL_TLSV1 SSL_SSLV3/* for now */ +# define SSL_TLSV1_2 0x00000004UL + +/* Bits for algorithm2 (handshake digests and other extra flags) */ + +# define SSL_HANDSHAKE_MAC_MD5 0x10 +# define SSL_HANDSHAKE_MAC_SHA 0x20 +# define SSL_HANDSHAKE_MAC_GOST94 0x40 +# define SSL_HANDSHAKE_MAC_SHA256 0x80 +# define SSL_HANDSHAKE_MAC_SHA384 0x100 +# define SSL_HANDSHAKE_MAC_DEFAULT (SSL_HANDSHAKE_MAC_MD5 | SSL_HANDSHAKE_MAC_SHA) + +/* + * When adding new digest in the ssl_ciph.c and increment SSM_MD_NUM_IDX make + * sure to update this constant too + */ +# define SSL_MAX_DIGEST 6 + +# define TLS1_PRF_DGST_MASK (0xff << TLS1_PRF_DGST_SHIFT) + +# define TLS1_PRF_DGST_SHIFT 10 +# define TLS1_PRF_MD5 (SSL_HANDSHAKE_MAC_MD5 << TLS1_PRF_DGST_SHIFT) +# define TLS1_PRF_SHA1 (SSL_HANDSHAKE_MAC_SHA << TLS1_PRF_DGST_SHIFT) +# define TLS1_PRF_SHA256 (SSL_HANDSHAKE_MAC_SHA256 << TLS1_PRF_DGST_SHIFT) +# define TLS1_PRF_SHA384 (SSL_HANDSHAKE_MAC_SHA384 << TLS1_PRF_DGST_SHIFT) +# define TLS1_PRF_GOST94 (SSL_HANDSHAKE_MAC_GOST94 << TLS1_PRF_DGST_SHIFT) +# define TLS1_PRF (TLS1_PRF_MD5 | TLS1_PRF_SHA1) + +/* + * Stream MAC for GOST ciphersuites from cryptopro draft (currently this also + * goes into algorithm2) + */ +# define TLS1_STREAM_MAC 0x04 + +/* + * Export and cipher strength information. For each cipher we have to decide + * whether it is exportable or not. This information is likely to change + * over time, since the export control rules are no static technical issue. + * + * Independent of the export flag the cipher strength is sorted into classes. + * SSL_EXP40 was denoting the 40bit US export limit of past times, which now + * is at 56bit (SSL_EXP56). If the exportable cipher class is going to change + * again (eg. to 64bit) the use of "SSL_EXP*" becomes blurred even more, + * since SSL_EXP64 could be similar to SSL_LOW. + * For this reason SSL_MICRO and SSL_MINI macros are included to widen the + * namespace of SSL_LOW-SSL_HIGH to lower values. As development of speed + * and ciphers goes, another extension to SSL_SUPER and/or SSL_ULTRA would + * be possible. + */ +# define SSL_EXP_MASK 0x00000003L +# define SSL_STRONG_MASK 0x000001fcL + +# define SSL_NOT_EXP 0x00000001L +# define SSL_EXPORT 0x00000002L + +# define SSL_STRONG_NONE 0x00000004L +# define SSL_EXP40 0x00000008L +# define SSL_MICRO (SSL_EXP40) +# define SSL_EXP56 0x00000010L +# define SSL_MINI (SSL_EXP56) +# define SSL_LOW 0x00000020L +# define SSL_MEDIUM 0x00000040L +# define SSL_HIGH 0x00000080L +# define SSL_FIPS 0x00000100L +# define SSL_NOT_DEFAULT 0x00000200L + +/* we have used 000003ff - 22 bits left to go */ + +/*- + * Macros to check the export status and cipher strength for export ciphers. + * Even though the macros for EXPORT and EXPORT40/56 have similar names, + * their meaning is different: + * *_EXPORT macros check the 'exportable' status. + * *_EXPORT40/56 macros are used to check whether a certain cipher strength + * is given. + * Since the SSL_IS_EXPORT* and SSL_EXPORT* macros depend on the correct + * algorithm structure element to be passed (algorithms, algo_strength) and no + * typechecking can be done as they are all of type unsigned long, their + * direct usage is discouraged. + * Use the SSL_C_* macros instead. + */ +# define SSL_IS_EXPORT(a) ((a)&SSL_EXPORT) +# define SSL_IS_EXPORT56(a) ((a)&SSL_EXP56) +# define SSL_IS_EXPORT40(a) ((a)&SSL_EXP40) +# define SSL_C_IS_EXPORT(c) SSL_IS_EXPORT((c)->algo_strength) +# define SSL_C_IS_EXPORT56(c) SSL_IS_EXPORT56((c)->algo_strength) +# define SSL_C_IS_EXPORT40(c) SSL_IS_EXPORT40((c)->algo_strength) + +# define SSL_EXPORT_KEYLENGTH(a,s) (SSL_IS_EXPORT40(s) ? 5 : \ + (a) == SSL_DES ? 8 : 7) +# define SSL_EXPORT_PKEYLENGTH(a) (SSL_IS_EXPORT40(a) ? 512 : 1024) +# define SSL_C_EXPORT_KEYLENGTH(c) SSL_EXPORT_KEYLENGTH((c)->algorithm_enc, \ + (c)->algo_strength) +# define SSL_C_EXPORT_PKEYLENGTH(c) SSL_EXPORT_PKEYLENGTH((c)->algo_strength) + +/* Mostly for SSLv3 */ +# define SSL_PKEY_RSA_ENC 0 +# define SSL_PKEY_RSA_SIGN 1 +# define SSL_PKEY_DSA_SIGN 2 +# define SSL_PKEY_DH_RSA 3 +# define SSL_PKEY_DH_DSA 4 +# define SSL_PKEY_ECC 5 +# define SSL_PKEY_GOST94 6 +# define SSL_PKEY_GOST01 7 +# define SSL_PKEY_NUM 8 + +/*- + * SSL_kRSA <- RSA_ENC | (RSA_TMP & RSA_SIGN) | + * <- (EXPORT & (RSA_ENC | RSA_TMP) & RSA_SIGN) + * SSL_kDH <- DH_ENC & (RSA_ENC | RSA_SIGN | DSA_SIGN) + * SSL_kEDH <- RSA_ENC | RSA_SIGN | DSA_SIGN + * SSL_aRSA <- RSA_ENC | RSA_SIGN + * SSL_aDSS <- DSA_SIGN + */ + +/*- +#define CERT_INVALID 0 +#define CERT_PUBLIC_KEY 1 +#define CERT_PRIVATE_KEY 2 +*/ + +# ifndef OPENSSL_NO_EC +/* + * From ECC-TLS draft, used in encoding the curve type in ECParameters + */ +# define EXPLICIT_PRIME_CURVE_TYPE 1 +# define EXPLICIT_CHAR2_CURVE_TYPE 2 +# define NAMED_CURVE_TYPE 3 +# endif /* OPENSSL_NO_EC */ + +typedef struct cert_pkey_st { + X509 *x509; + EVP_PKEY *privatekey; + /* Digest to use when signing */ + const EVP_MD *digest; +} CERT_PKEY; + +typedef struct cert_st { + /* Current active set */ + /* + * ALWAYS points to an element of the pkeys array + * Probably it would make more sense to store + * an index, not a pointer. + */ + CERT_PKEY *key; + /* + * The following masks are for the key and auth algorithms that are + * supported by the certs below + */ + int valid; + unsigned long mask_k; + unsigned long mask_a; + unsigned long export_mask_k; + unsigned long export_mask_a; +# ifndef OPENSSL_NO_RSA + RSA *rsa_tmp; + RSA *(*rsa_tmp_cb) (SSL *ssl, int is_export, int keysize); +# endif +# ifndef OPENSSL_NO_DH + DH *dh_tmp; + DH *(*dh_tmp_cb) (SSL *ssl, int is_export, int keysize); +# endif +# ifndef OPENSSL_NO_ECDH + EC_KEY *ecdh_tmp; + /* Callback for generating ephemeral ECDH keys */ + EC_KEY *(*ecdh_tmp_cb) (SSL *ssl, int is_export, int keysize); +# endif + CERT_PKEY pkeys[SSL_PKEY_NUM]; + int references; /* >1 only if SSL_copy_session_id is used */ +} CERT; + +typedef struct sess_cert_st { + STACK_OF(X509) *cert_chain; /* as received from peer (not for SSL2) */ + /* The 'peer_...' members are used only by clients. */ + int peer_cert_type; + CERT_PKEY *peer_key; /* points to an element of peer_pkeys (never + * NULL!) */ + CERT_PKEY peer_pkeys[SSL_PKEY_NUM]; + /* + * Obviously we don't have the private keys of these, so maybe we + * shouldn't even use the CERT_PKEY type here. + */ +# ifndef OPENSSL_NO_RSA + RSA *peer_rsa_tmp; /* not used for SSL 2 */ +# endif +# ifndef OPENSSL_NO_DH + DH *peer_dh_tmp; /* not used for SSL 2 */ +# endif +# ifndef OPENSSL_NO_ECDH + EC_KEY *peer_ecdh_tmp; +# endif + int references; /* actually always 1 at the moment */ +} SESS_CERT; + +/* + * #define MAC_DEBUG + */ + +/* + * #define ERR_DEBUG + */ +/* + * #define ABORT_DEBUG + */ +/* + * #define PKT_DEBUG 1 + */ +/* + * #define DES_DEBUG + */ +/* + * #define DES_OFB_DEBUG + */ +/* + * #define SSL_DEBUG + */ +/* + * #define RSA_DEBUG + */ +/* + * #define IDEA_DEBUG + */ + +# define FP_ICC (int (*)(const void *,const void *)) +# define ssl_put_cipher_by_char(ssl,ciph,ptr) \ + ((ssl)->method->put_cipher_by_char((ciph),(ptr))) +# define ssl_get_cipher_by_char(ssl,ptr) \ + ((ssl)->method->get_cipher_by_char(ptr)) + +/* + * This is for the SSLv3/TLSv1.0 differences in crypto/hash stuff It is a bit + * of a mess of functions, but hell, think of it as an opaque structure :-) + */ +typedef struct ssl3_enc_method { + int (*enc) (SSL *, int); + int (*mac) (SSL *, unsigned char *, int); + int (*setup_key_block) (SSL *); + int (*generate_master_secret) (SSL *, unsigned char *, unsigned char *, + int); + int (*change_cipher_state) (SSL *, int); + int (*final_finish_mac) (SSL *, const char *, int, unsigned char *); + int finish_mac_length; + int (*cert_verify_mac) (SSL *, int, unsigned char *); + const char *client_finished_label; + int client_finished_label_len; + const char *server_finished_label; + int server_finished_label_len; + int (*alert_value) (int); + int (*export_keying_material) (SSL *, unsigned char *, size_t, + const char *, size_t, + const unsigned char *, size_t, + int use_context); +} SSL3_ENC_METHOD; + +# ifndef OPENSSL_NO_COMP +/* Used for holding the relevant compression methods loaded into SSL_CTX */ +typedef struct ssl3_comp_st { + int comp_id; /* The identifier byte for this compression + * type */ + char *name; /* Text name used for the compression type */ + COMP_METHOD *method; /* The method :-) */ +} SSL3_COMP; +# endif + +# ifndef OPENSSL_NO_BUF_FREELISTS +typedef struct ssl3_buf_freelist_st { + size_t chunklen; + unsigned int len; + struct ssl3_buf_freelist_entry_st *head; +} SSL3_BUF_FREELIST; + +typedef struct ssl3_buf_freelist_entry_st { + struct ssl3_buf_freelist_entry_st *next; +} SSL3_BUF_FREELIST_ENTRY; +# endif + +extern SSL3_ENC_METHOD ssl3_undef_enc_method; +OPENSSL_EXTERN const SSL_CIPHER ssl2_ciphers[]; +OPENSSL_EXTERN SSL_CIPHER ssl3_ciphers[]; + +SSL_METHOD *ssl_bad_method(int ver); + +extern SSL3_ENC_METHOD TLSv1_enc_data; +extern SSL3_ENC_METHOD SSLv3_enc_data; +extern SSL3_ENC_METHOD DTLSv1_enc_data; + +# define SSL_IS_DTLS(s) (s->method->version == DTLS1_VERSION) + +# define IMPLEMENT_tls_meth_func(version, func_name, s_accept, s_connect, \ + s_get_meth) \ +const SSL_METHOD *func_name(void) \ + { \ + static const SSL_METHOD func_name##_data= { \ + version, \ + tls1_new, \ + tls1_clear, \ + tls1_free, \ + s_accept, \ + s_connect, \ + ssl3_read, \ + ssl3_peek, \ + ssl3_write, \ + ssl3_shutdown, \ + ssl3_renegotiate, \ + ssl3_renegotiate_check, \ + ssl3_get_message, \ + ssl3_read_bytes, \ + ssl3_write_bytes, \ + ssl3_dispatch_alert, \ + ssl3_ctrl, \ + ssl3_ctx_ctrl, \ + ssl3_get_cipher_by_char, \ + ssl3_put_cipher_by_char, \ + ssl3_pending, \ + ssl3_num_ciphers, \ + ssl3_get_cipher, \ + s_get_meth, \ + tls1_default_timeout, \ + &TLSv1_enc_data, \ + ssl_undefined_void_function, \ + ssl3_callback_ctrl, \ + ssl3_ctx_callback_ctrl, \ + }; \ + return &func_name##_data; \ + } + +# define IMPLEMENT_ssl3_meth_func(func_name, s_accept, s_connect, s_get_meth) \ +const SSL_METHOD *func_name(void) \ + { \ + static const SSL_METHOD func_name##_data= { \ + SSL3_VERSION, \ + ssl3_new, \ + ssl3_clear, \ + ssl3_free, \ + s_accept, \ + s_connect, \ + ssl3_read, \ + ssl3_peek, \ + ssl3_write, \ + ssl3_shutdown, \ + ssl3_renegotiate, \ + ssl3_renegotiate_check, \ + ssl3_get_message, \ + ssl3_read_bytes, \ + ssl3_write_bytes, \ + ssl3_dispatch_alert, \ + ssl3_ctrl, \ + ssl3_ctx_ctrl, \ + ssl3_get_cipher_by_char, \ + ssl3_put_cipher_by_char, \ + ssl3_pending, \ + ssl3_num_ciphers, \ + ssl3_get_cipher, \ + s_get_meth, \ + ssl3_default_timeout, \ + &SSLv3_enc_data, \ + ssl_undefined_void_function, \ + ssl3_callback_ctrl, \ + ssl3_ctx_callback_ctrl, \ + }; \ + return &func_name##_data; \ + } + +# define IMPLEMENT_ssl23_meth_func(func_name, s_accept, s_connect, s_get_meth) \ +const SSL_METHOD *func_name(void) \ + { \ + static const SSL_METHOD func_name##_data= { \ + TLS1_2_VERSION, \ + tls1_new, \ + tls1_clear, \ + tls1_free, \ + s_accept, \ + s_connect, \ + ssl23_read, \ + ssl23_peek, \ + ssl23_write, \ + ssl_undefined_function, \ + ssl_undefined_function, \ + ssl_ok, \ + ssl3_get_message, \ + ssl3_read_bytes, \ + ssl3_write_bytes, \ + ssl3_dispatch_alert, \ + ssl3_ctrl, \ + ssl3_ctx_ctrl, \ + ssl23_get_cipher_by_char, \ + ssl23_put_cipher_by_char, \ + ssl_undefined_const_function, \ + ssl23_num_ciphers, \ + ssl23_get_cipher, \ + s_get_meth, \ + ssl23_default_timeout, \ + &ssl3_undef_enc_method, \ + ssl_undefined_void_function, \ + ssl3_callback_ctrl, \ + ssl3_ctx_callback_ctrl, \ + }; \ + return &func_name##_data; \ + } + +# define IMPLEMENT_ssl2_meth_func(func_name, s_accept, s_connect, s_get_meth) \ +const SSL_METHOD *func_name(void) \ + { \ + static const SSL_METHOD func_name##_data= { \ + SSL2_VERSION, \ + ssl2_new, /* local */ \ + ssl2_clear, /* local */ \ + ssl2_free, /* local */ \ + s_accept, \ + s_connect, \ + ssl2_read, \ + ssl2_peek, \ + ssl2_write, \ + ssl2_shutdown, \ + ssl_ok, /* NULL - renegotiate */ \ + ssl_ok, /* NULL - check renegotiate */ \ + NULL, /* NULL - ssl_get_message */ \ + NULL, /* NULL - ssl_get_record */ \ + NULL, /* NULL - ssl_write_bytes */ \ + NULL, /* NULL - dispatch_alert */ \ + ssl2_ctrl, /* local */ \ + ssl2_ctx_ctrl, /* local */ \ + ssl2_get_cipher_by_char, \ + ssl2_put_cipher_by_char, \ + ssl2_pending, \ + ssl2_num_ciphers, \ + ssl2_get_cipher, \ + s_get_meth, \ + ssl2_default_timeout, \ + &ssl3_undef_enc_method, \ + ssl_undefined_void_function, \ + ssl2_callback_ctrl, /* local */ \ + ssl2_ctx_callback_ctrl, /* local */ \ + }; \ + return &func_name##_data; \ + } + +# define IMPLEMENT_dtls1_meth_func(func_name, s_accept, s_connect, s_get_meth) \ +const SSL_METHOD *func_name(void) \ + { \ + static const SSL_METHOD func_name##_data= { \ + DTLS1_VERSION, \ + dtls1_new, \ + dtls1_clear, \ + dtls1_free, \ + s_accept, \ + s_connect, \ + ssl3_read, \ + ssl3_peek, \ + ssl3_write, \ + dtls1_shutdown, \ + ssl3_renegotiate, \ + ssl3_renegotiate_check, \ + dtls1_get_message, \ + dtls1_read_bytes, \ + dtls1_write_app_data_bytes, \ + dtls1_dispatch_alert, \ + dtls1_ctrl, \ + ssl3_ctx_ctrl, \ + ssl3_get_cipher_by_char, \ + ssl3_put_cipher_by_char, \ + ssl3_pending, \ + ssl3_num_ciphers, \ + dtls1_get_cipher, \ + s_get_meth, \ + dtls1_default_timeout, \ + &DTLSv1_enc_data, \ + ssl_undefined_void_function, \ + ssl3_callback_ctrl, \ + ssl3_ctx_callback_ctrl, \ + }; \ + return &func_name##_data; \ + } + +struct openssl_ssl_test_functions { + int (*p_ssl_init_wbio_buffer) (SSL *s, int push); + int (*p_ssl3_setup_buffers) (SSL *s); + int (*p_tls1_process_heartbeat) (SSL *s); + int (*p_dtls1_process_heartbeat) (SSL *s); +}; + +# ifndef OPENSSL_UNIT_TEST + +void ssl_clear_cipher_ctx(SSL *s); +int ssl_clear_bad_session(SSL *s); +CERT *ssl_cert_new(void); +CERT *ssl_cert_dup(CERT *cert); +int ssl_cert_inst(CERT **o); +void ssl_cert_free(CERT *c); +SESS_CERT *ssl_sess_cert_new(void); +void ssl_sess_cert_free(SESS_CERT *sc); +int ssl_set_peer_cert_type(SESS_CERT *c, int type); +int ssl_get_new_session(SSL *s, int session); +int ssl_get_prev_session(SSL *s, unsigned char *session, int len, + const unsigned char *limit); +SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket); +int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b); +DECLARE_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); +int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap, + const SSL_CIPHER *const *bp); +STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, + int num, + STACK_OF(SSL_CIPHER) **skp); +int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, + unsigned char *p, + int (*put_cb) (const SSL_CIPHER *, + unsigned char *)); +STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *meth, + STACK_OF(SSL_CIPHER) **pref, + STACK_OF(SSL_CIPHER) **sorted, + const char *rule_str); +void ssl_update_cache(SSL *s, int mode); +int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, + const EVP_MD **md, int *mac_pkey_type, + int *mac_secret_size, SSL_COMP **comp); +int ssl_get_handshake_digest(int i, long *mask, const EVP_MD **md); +int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk); +int ssl_undefined_function(SSL *s); +int ssl_undefined_void_function(void); +int ssl_undefined_const_function(const SSL *s); +CERT_PKEY *ssl_get_server_send_pkey(const SSL *s); +X509 *ssl_get_server_send_cert(const SSL *); +EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *c, const EVP_MD **pmd); +int ssl_cert_type(X509 *x, EVP_PKEY *pkey); +void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher); +STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s); +int ssl_verify_alarm_type(long type); +void ssl_load_ciphers(void); +int ssl_fill_hello_random(SSL *s, int server, unsigned char *field, int len); + +int ssl2_enc_init(SSL *s, int client); +int ssl2_generate_key_material(SSL *s); +int ssl2_enc(SSL *s, int send_data); +void ssl2_mac(SSL *s, unsigned char *mac, int send_data); +const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p); +int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); +int ssl2_part_read(SSL *s, unsigned long f, int i); +int ssl2_do_write(SSL *s); +int ssl2_set_certificate(SSL *s, int type, int len, + const unsigned char *data); +void ssl2_return_error(SSL *s, int reason); +void ssl2_write_error(SSL *s); +int ssl2_num_ciphers(void); +const SSL_CIPHER *ssl2_get_cipher(unsigned int u); +int ssl2_new(SSL *s); +void ssl2_free(SSL *s); +int ssl2_accept(SSL *s); +int ssl2_connect(SSL *s); +int ssl2_read(SSL *s, void *buf, int len); +int ssl2_peek(SSL *s, void *buf, int len); +int ssl2_write(SSL *s, const void *buf, int len); +int ssl2_shutdown(SSL *s); +void ssl2_clear(SSL *s); +long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg); +long ssl2_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg); +long ssl2_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); +long ssl2_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp) (void)); +int ssl2_pending(const SSL *s); +long ssl2_default_timeout(void); + +const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p); +int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); +void ssl3_init_finished_mac(SSL *s); +int ssl3_send_server_certificate(SSL *s); +int ssl3_send_newsession_ticket(SSL *s); +int ssl3_send_cert_status(SSL *s); +int ssl3_get_finished(SSL *s, int state_a, int state_b); +int ssl3_setup_key_block(SSL *s); +int ssl3_send_change_cipher_spec(SSL *s, int state_a, int state_b); +int ssl3_change_cipher_state(SSL *s, int which); +void ssl3_cleanup_key_block(SSL *s); +int ssl3_do_write(SSL *s, int type); +int ssl3_send_alert(SSL *s, int level, int desc); +int ssl3_generate_master_secret(SSL *s, unsigned char *out, + unsigned char *p, int len); +int ssl3_get_req_cert_type(SSL *s, unsigned char *p); +long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok); +int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen); +int ssl3_num_ciphers(void); +const SSL_CIPHER *ssl3_get_cipher(unsigned int u); +int ssl3_renegotiate(SSL *ssl); +int ssl3_renegotiate_check(SSL *ssl); +int ssl3_dispatch_alert(SSL *s); +int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); +int ssl3_write_bytes(SSL *s, int type, const void *buf, int len); +int ssl3_final_finish_mac(SSL *s, const char *sender, int slen, + unsigned char *p); +int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p); +void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len); +int ssl3_enc(SSL *s, int send_data); +int n_ssl3_mac(SSL *ssl, unsigned char *md, int send_data); +void ssl3_free_digest_list(SSL *s); +unsigned long ssl3_output_cert_chain(SSL *s, X509 *x); +SSL_CIPHER *ssl3_choose_cipher(SSL *ssl, STACK_OF(SSL_CIPHER) *clnt, + STACK_OF(SSL_CIPHER) *srvr); +int ssl3_setup_buffers(SSL *s); +int ssl3_setup_read_buffer(SSL *s); +int ssl3_setup_write_buffer(SSL *s); +int ssl3_release_read_buffer(SSL *s); +int ssl3_release_write_buffer(SSL *s); +int ssl3_digest_cached_records(SSL *s); +int ssl3_new(SSL *s); +void ssl3_free(SSL *s); +int ssl3_accept(SSL *s); +int ssl3_connect(SSL *s); +int ssl3_read(SSL *s, void *buf, int len); +int ssl3_peek(SSL *s, void *buf, int len); +int ssl3_write(SSL *s, const void *buf, int len); +int ssl3_shutdown(SSL *s); +void ssl3_clear(SSL *s); +long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg); +long ssl3_ctx_ctrl(SSL_CTX *s, int cmd, long larg, void *parg); +long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); +long ssl3_ctx_callback_ctrl(SSL_CTX *s, int cmd, void (*fp) (void)); +int ssl3_pending(const SSL *s); + +void ssl3_record_sequence_update(unsigned char *seq); +int ssl3_do_change_cipher_spec(SSL *ssl); +long ssl3_default_timeout(void); + +int ssl23_num_ciphers(void); +const SSL_CIPHER *ssl23_get_cipher(unsigned int u); +int ssl23_read(SSL *s, void *buf, int len); +int ssl23_peek(SSL *s, void *buf, int len); +int ssl23_write(SSL *s, const void *buf, int len); +int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p); +const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p); +long ssl23_default_timeout(void); + +long tls1_default_timeout(void); +int dtls1_do_write(SSL *s, int type); +int ssl3_read_n(SSL *s, int n, int max, int extend); +int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek); +int ssl3_do_compress(SSL *ssl); +int ssl3_do_uncompress(SSL *ssl); +int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, + unsigned int len); +unsigned char *dtls1_set_message_header(SSL *s, + unsigned char *p, unsigned char mt, + unsigned long len, + unsigned long frag_off, + unsigned long frag_len); + +int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf, int len); +int dtls1_write_bytes(SSL *s, int type, const void *buf, int len); + +int dtls1_send_change_cipher_spec(SSL *s, int a, int b); +int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen); +unsigned long dtls1_output_cert_chain(SSL *s, X509 *x); +int dtls1_read_failed(SSL *s, int code); +int dtls1_buffer_message(SSL *s, int ccs); +int dtls1_retransmit_message(SSL *s, unsigned short seq, + unsigned long frag_off, int *found); +int dtls1_get_queue_priority(unsigned short seq, int is_ccs); +int dtls1_retransmit_buffered_messages(SSL *s); +void dtls1_clear_record_buffer(SSL *s); +void dtls1_get_message_header(unsigned char *data, + struct hm_header_st *msg_hdr); +void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr); +void dtls1_reset_seq_numbers(SSL *s, int rw); +long dtls1_default_timeout(void); +struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft); +int dtls1_check_timeout_num(SSL *s); +int dtls1_handle_timeout(SSL *s); +const SSL_CIPHER *dtls1_get_cipher(unsigned int u); +void dtls1_start_timer(SSL *s); +void dtls1_stop_timer(SSL *s); +int dtls1_is_timer_expired(SSL *s); +void dtls1_double_timeout(SSL *s); +int dtls1_send_newsession_ticket(SSL *s); +unsigned int dtls1_min_mtu(SSL *s); +unsigned int dtls1_link_min_mtu(void); +void dtls1_hm_fragment_free(hm_fragment *frag); + +/* some client-only functions */ +int ssl3_client_hello(SSL *s); +int ssl3_get_server_hello(SSL *s); +int ssl3_get_certificate_request(SSL *s); +int ssl3_get_new_session_ticket(SSL *s); +int ssl3_get_cert_status(SSL *s); +int ssl3_get_server_done(SSL *s); +int ssl3_send_client_verify(SSL *s); +int ssl3_send_client_certificate(SSL *s); +int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey); +int ssl3_send_client_key_exchange(SSL *s); +int ssl3_get_key_exchange(SSL *s); +int ssl3_get_server_certificate(SSL *s); +int ssl3_check_cert_and_algorithm(SSL *s); +# ifndef OPENSSL_NO_TLSEXT +# ifndef OPENSSL_NO_NEXTPROTONEG +int ssl3_send_next_proto(SSL *s); +# endif +# endif + +int dtls1_client_hello(SSL *s); +int dtls1_send_client_certificate(SSL *s); +int dtls1_send_client_key_exchange(SSL *s); +int dtls1_send_client_verify(SSL *s); + +/* some server-only functions */ +int ssl3_get_client_hello(SSL *s); +int ssl3_send_server_hello(SSL *s); +int ssl3_send_hello_request(SSL *s); +int ssl3_send_server_key_exchange(SSL *s); +int ssl3_send_certificate_request(SSL *s); +int ssl3_send_server_done(SSL *s); +int ssl3_check_client_hello(SSL *s); +int ssl3_get_client_certificate(SSL *s); +int ssl3_get_client_key_exchange(SSL *s); +int ssl3_get_cert_verify(SSL *s); +# ifndef OPENSSL_NO_NEXTPROTONEG +int ssl3_get_next_proto(SSL *s); +# endif + +int dtls1_send_hello_request(SSL *s); +int dtls1_send_server_hello(SSL *s); +int dtls1_send_server_certificate(SSL *s); +int dtls1_send_server_key_exchange(SSL *s); +int dtls1_send_certificate_request(SSL *s); +int dtls1_send_server_done(SSL *s); + +int ssl23_accept(SSL *s); +int ssl23_connect(SSL *s); +int ssl23_read_bytes(SSL *s, int n); +int ssl23_write_bytes(SSL *s); + +int tls1_new(SSL *s); +void tls1_free(SSL *s); +void tls1_clear(SSL *s); +long tls1_ctrl(SSL *s, int cmd, long larg, void *parg); +long tls1_callback_ctrl(SSL *s, int cmd, void (*fp) (void)); + +int dtls1_new(SSL *s); +int dtls1_accept(SSL *s); +int dtls1_connect(SSL *s); +void dtls1_free(SSL *s); +void dtls1_clear(SSL *s); +long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg); +int dtls1_shutdown(SSL *s); + +long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok); +int dtls1_get_record(SSL *s); +int do_dtls1_write(SSL *s, int type, const unsigned char *buf, + unsigned int len, int create_empty_fragement); +int dtls1_dispatch_alert(SSL *s); +int dtls1_enc(SSL *s, int snd); + +int ssl_init_wbio_buffer(SSL *s, int push); +void ssl_free_wbio_buffer(SSL *s); + +int tls1_change_cipher_state(SSL *s, int which); +int tls1_setup_key_block(SSL *s); +int tls1_enc(SSL *s, int snd); +int tls1_final_finish_mac(SSL *s, + const char *str, int slen, unsigned char *p); +int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *p); +int tls1_mac(SSL *ssl, unsigned char *md, int snd); +int tls1_generate_master_secret(SSL *s, unsigned char *out, + unsigned char *p, int len); +int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *p, size_t plen, + int use_context); +int tls1_alert_code(int code); +int ssl3_alert_code(int code); +int ssl_ok(SSL *s); + +# ifndef OPENSSL_NO_ECDH +int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s); +# endif + +SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n); + +# ifndef OPENSSL_NO_EC +int tls1_ec_curve_id2nid(int curve_id); +int tls1_ec_nid2curve_id(int nid); +# endif /* OPENSSL_NO_EC */ + +# ifndef OPENSSL_NO_TLSEXT +unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, + unsigned char *limit); +unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, + unsigned char *limit); +int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **data, + unsigned char *limit, int *al); +int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **data, + unsigned char *d, int n, int *al); +int ssl_prepare_clienthello_tlsext(SSL *s); +int ssl_prepare_serverhello_tlsext(SSL *s); +int ssl_check_clienthello_tlsext_early(SSL *s); +int ssl_check_clienthello_tlsext_late(SSL *s); +int ssl_check_serverhello_tlsext(SSL *s); + +# ifndef OPENSSL_NO_HEARTBEATS +int tls1_heartbeat(SSL *s); +int dtls1_heartbeat(SSL *s); +int tls1_process_heartbeat(SSL *s); +int dtls1_process_heartbeat(SSL *s); +# endif + +# ifdef OPENSSL_NO_SHA256 +# define tlsext_tick_md EVP_sha1 +# else +# define tlsext_tick_md EVP_sha256 +# endif +int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, + const unsigned char *limit, SSL_SESSION **ret); + +int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, + const EVP_MD *md); +int tls12_get_sigid(const EVP_PKEY *pk); +const EVP_MD *tls12_get_hash(unsigned char hash_alg); + +# endif +EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md); +void ssl_clear_hash_ctx(EVP_MD_CTX **hash); +int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, + int maxlen); +int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, + int *al); +int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, + int maxlen); +int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, + int *al); +long ssl_get_algorithm2(SSL *s); +int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize); +int tls12_get_req_sig_algs(SSL *s, unsigned char *p); + +int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, + int maxlen); +int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len, + int *al); +int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, + int maxlen); +int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len, + int *al); + +/* s3_cbc.c */ +void ssl3_cbc_copy_mac(unsigned char *out, + const SSL3_RECORD *rec, + unsigned md_size, unsigned orig_len); +int ssl3_cbc_remove_padding(const SSL *s, + SSL3_RECORD *rec, + unsigned block_size, unsigned mac_size); +int tls1_cbc_remove_padding(const SSL *s, + SSL3_RECORD *rec, + unsigned block_size, unsigned mac_size); +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx); +int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, + unsigned char *md_out, + size_t *md_out_size, + const unsigned char header[13], + const unsigned char *data, + size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const unsigned char *mac_secret, + unsigned mac_secret_length, char is_sslv3); + +void tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx, + EVP_MD_CTX *mac_ctx, const unsigned char *data, + size_t data_len, size_t orig_len); + +int srp_verify_server_param(SSL *s, int *al); + +# else + +# define ssl_init_wbio_buffer SSL_test_functions()->p_ssl_init_wbio_buffer +# define ssl3_setup_buffers SSL_test_functions()->p_ssl3_setup_buffers +# define tls1_process_heartbeat SSL_test_functions()->p_tls1_process_heartbeat +# define dtls1_process_heartbeat SSL_test_functions()->p_dtls1_process_heartbeat + +# endif +#endif diff --git a/libs/openssl/include/openssl/stack.h b/libs/openssl/include/openssl/stack.h new file mode 120000 index 00000000..61d342fc --- /dev/null +++ b/libs/openssl/include/openssl/stack.h @@ -0,0 +1 @@ +../../crypto/stack/stack.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/symhacks.h b/libs/openssl/include/openssl/symhacks.h new file mode 120000 index 00000000..4a1a6913 --- /dev/null +++ b/libs/openssl/include/openssl/symhacks.h @@ -0,0 +1 @@ +../../crypto/symhacks.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/tls1.h b/libs/openssl/include/openssl/tls1.h new file mode 100644 index 00000000..91504b17 --- /dev/null +++ b/libs/openssl/include/openssl/tls1.h @@ -0,0 +1,785 @@ +/* ssl/tls1.h */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifndef HEADER_TLS1_H +# define HEADER_TLS1_H + +# include + +#ifdef __cplusplus +extern "C" { +#endif + +# define TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES 0 + +# define TLS1_VERSION 0x0301 +# define TLS1_1_VERSION 0x0302 +# define TLS1_2_VERSION 0x0303 +# define TLS_MAX_VERSION TLS1_2_VERSION + +# define TLS1_VERSION_MAJOR 0x03 +# define TLS1_VERSION_MINOR 0x01 + +# define TLS1_1_VERSION_MAJOR 0x03 +# define TLS1_1_VERSION_MINOR 0x02 + +# define TLS1_2_VERSION_MAJOR 0x03 +# define TLS1_2_VERSION_MINOR 0x03 + +# define TLS1_get_version(s) \ + ((s->version >> 8) == TLS1_VERSION_MAJOR ? s->version : 0) + +# define TLS1_get_client_version(s) \ + ((s->client_version >> 8) == TLS1_VERSION_MAJOR ? s->client_version : 0) + +# define TLS1_AD_DECRYPTION_FAILED 21 +# define TLS1_AD_RECORD_OVERFLOW 22 +# define TLS1_AD_UNKNOWN_CA 48/* fatal */ +# define TLS1_AD_ACCESS_DENIED 49/* fatal */ +# define TLS1_AD_DECODE_ERROR 50/* fatal */ +# define TLS1_AD_DECRYPT_ERROR 51 +# define TLS1_AD_EXPORT_RESTRICTION 60/* fatal */ +# define TLS1_AD_PROTOCOL_VERSION 70/* fatal */ +# define TLS1_AD_INSUFFICIENT_SECURITY 71/* fatal */ +# define TLS1_AD_INTERNAL_ERROR 80/* fatal */ +# define TLS1_AD_INAPPROPRIATE_FALLBACK 86/* fatal */ +# define TLS1_AD_USER_CANCELLED 90 +# define TLS1_AD_NO_RENEGOTIATION 100 +/* codes 110-114 are from RFC3546 */ +# define TLS1_AD_UNSUPPORTED_EXTENSION 110 +# define TLS1_AD_CERTIFICATE_UNOBTAINABLE 111 +# define TLS1_AD_UNRECOGNIZED_NAME 112 +# define TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE 113 +# define TLS1_AD_BAD_CERTIFICATE_HASH_VALUE 114 +# define TLS1_AD_UNKNOWN_PSK_IDENTITY 115/* fatal */ + +/* ExtensionType values from RFC3546 / RFC4366 / RFC6066 */ +# define TLSEXT_TYPE_server_name 0 +# define TLSEXT_TYPE_max_fragment_length 1 +# define TLSEXT_TYPE_client_certificate_url 2 +# define TLSEXT_TYPE_trusted_ca_keys 3 +# define TLSEXT_TYPE_truncated_hmac 4 +# define TLSEXT_TYPE_status_request 5 +/* ExtensionType values from RFC4681 */ +# define TLSEXT_TYPE_user_mapping 6 + +/* ExtensionType values from RFC5878 */ +# define TLSEXT_TYPE_client_authz 7 +# define TLSEXT_TYPE_server_authz 8 + +/* ExtensionType values from RFC6091 */ +# define TLSEXT_TYPE_cert_type 9 + +/* ExtensionType values from RFC4492 */ +# define TLSEXT_TYPE_elliptic_curves 10 +# define TLSEXT_TYPE_ec_point_formats 11 + +/* ExtensionType value from RFC5054 */ +# define TLSEXT_TYPE_srp 12 + +/* ExtensionType values from RFC5246 */ +# define TLSEXT_TYPE_signature_algorithms 13 + +/* ExtensionType value from RFC5764 */ +# define TLSEXT_TYPE_use_srtp 14 + +/* ExtensionType value from RFC5620 */ +# define TLSEXT_TYPE_heartbeat 15 + +/* + * ExtensionType value for TLS padding extension. + * http://tools.ietf.org/html/draft-agl-tls-padding + */ +# define TLSEXT_TYPE_padding 21 + +/* ExtensionType value from RFC4507 */ +# define TLSEXT_TYPE_session_ticket 35 + +/* ExtensionType value from draft-rescorla-tls-opaque-prf-input-00.txt */ +# if 0 +/* + * will have to be provided externally for now , + * i.e. build with -DTLSEXT_TYPE_opaque_prf_input=38183 + * using whatever extension number you'd like to try + */ +# define TLSEXT_TYPE_opaque_prf_input ?? */ +# endif + +/* Temporary extension type */ +# define TLSEXT_TYPE_renegotiate 0xff01 + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* This is not an IANA defined extension number */ +# define TLSEXT_TYPE_next_proto_neg 13172 +# endif + +/* NameType value from RFC3546 */ +# define TLSEXT_NAMETYPE_host_name 0 +/* status request value from RFC3546 */ +# define TLSEXT_STATUSTYPE_ocsp 1 + +/* ECPointFormat values from RFC4492 */ +# define TLSEXT_ECPOINTFORMAT_first 0 +# define TLSEXT_ECPOINTFORMAT_uncompressed 0 +# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1 +# define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2 2 +# define TLSEXT_ECPOINTFORMAT_last 2 + +/* Signature and hash algorithms from RFC5246 */ +# define TLSEXT_signature_anonymous 0 +# define TLSEXT_signature_rsa 1 +# define TLSEXT_signature_dsa 2 +# define TLSEXT_signature_ecdsa 3 + +# define TLSEXT_hash_none 0 +# define TLSEXT_hash_md5 1 +# define TLSEXT_hash_sha1 2 +# define TLSEXT_hash_sha224 3 +# define TLSEXT_hash_sha256 4 +# define TLSEXT_hash_sha384 5 +# define TLSEXT_hash_sha512 6 + +# ifndef OPENSSL_NO_TLSEXT + +# define TLSEXT_MAXLEN_host_name 255 + +const char *SSL_get_servername(const SSL *s, const int type); +int SSL_get_servername_type(const SSL *s); +/* + * SSL_export_keying_material exports a value derived from the master secret, + * as specified in RFC 5705. It writes |olen| bytes to |out| given a label and + * optional context. (Since a zero length context is allowed, the |use_context| + * flag controls whether a context is included.) It returns 1 on success and + * zero otherwise. + */ +int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *p, size_t plen, + int use_context); + +# define SSL_set_tlsext_host_name(s,name) \ +SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_HOSTNAME,TLSEXT_NAMETYPE_host_name,(char *)name) + +# define SSL_set_tlsext_debug_callback(ssl, cb) \ +SSL_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_CB,(void (*)(void))cb) + +# define SSL_set_tlsext_debug_arg(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_DEBUG_ARG,0, (void *)arg) + +# define SSL_set_tlsext_status_type(ssl, type) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE,type, NULL) + +# define SSL_get_tlsext_status_exts(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg) + +# define SSL_set_tlsext_status_exts(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS,0, (void *)arg) + +# define SSL_get_tlsext_status_ids(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg) + +# define SSL_set_tlsext_status_ids(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS,0, (void *)arg) + +# define SSL_get_tlsext_status_ocsp_resp(ssl, arg) \ +SSL_ctrl(ssl,SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP,0, (void *)arg) + +# define SSL_set_tlsext_status_ocsp_resp(ssl, arg, arglen) \ +SSL_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP,arglen, (void *)arg) + +# define SSL_CTX_set_tlsext_servername_callback(ctx, cb) \ +SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_CB,(void (*)(void))cb) + +# define SSL_TLSEXT_ERR_OK 0 +# define SSL_TLSEXT_ERR_ALERT_WARNING 1 +# define SSL_TLSEXT_ERR_ALERT_FATAL 2 +# define SSL_TLSEXT_ERR_NOACK 3 + +# define SSL_CTX_set_tlsext_servername_arg(ctx, arg) \ +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG,0, (void *)arg) + +# define SSL_CTX_get_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_GET_TLSEXT_TICKET_KEYS,(keylen),(keys)) +# define SSL_CTX_set_tlsext_ticket_keys(ctx, keys, keylen) \ + SSL_CTX_ctrl((ctx),SSL_CTRL_SET_TLSEXT_TICKET_KEYS,(keylen),(keys)) + +# define SSL_CTX_set_tlsext_status_cb(ssl, cb) \ +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB,(void (*)(void))cb) + +# define SSL_CTX_set_tlsext_status_arg(ssl, arg) \ +SSL_CTX_ctrl(ssl,SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG,0, (void *)arg) + +# define SSL_set_tlsext_opaque_prf_input(s, src, len) \ +SSL_ctrl(s,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT, len, src) +# define SSL_CTX_set_tlsext_opaque_prf_input_callback(ctx, cb) \ +SSL_CTX_callback_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB, (void (*)(void))cb) +# define SSL_CTX_set_tlsext_opaque_prf_input_callback_arg(ctx, arg) \ +SSL_CTX_ctrl(ctx,SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG, 0, arg) + +# define SSL_CTX_set_tlsext_ticket_key_cb(ssl, cb) \ +SSL_CTX_callback_ctrl(ssl,SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB,(void (*)(void))cb) + +# ifndef OPENSSL_NO_HEARTBEATS +# define SSL_TLSEXT_HB_ENABLED 0x01 +# define SSL_TLSEXT_HB_DONT_SEND_REQUESTS 0x02 +# define SSL_TLSEXT_HB_DONT_RECV_REQUESTS 0x04 + +# define SSL_get_tlsext_heartbeat_pending(ssl) \ + SSL_ctrl((ssl),SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING,0,NULL) +# define SSL_set_tlsext_heartbeat_no_requests(ssl, arg) \ + SSL_ctrl((ssl),SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS,arg,NULL) +# endif +# endif + +/* PSK ciphersuites from 4279 */ +# define TLS1_CK_PSK_WITH_RC4_128_SHA 0x0300008A +# define TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA 0x0300008B +# define TLS1_CK_PSK_WITH_AES_128_CBC_SHA 0x0300008C +# define TLS1_CK_PSK_WITH_AES_256_CBC_SHA 0x0300008D + +/* + * Additional TLS ciphersuites from expired Internet Draft + * draft-ietf-tls-56-bit-ciphersuites-01.txt (available if + * TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES is defined, see s3_lib.c). We + * actually treat them like SSL 3.0 ciphers, which we probably shouldn't. + * Note that the first two are actually not in the IDs. + */ +# define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5 0x03000060/* not in + * ID */ +# define TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 0x03000061/* not in + * ID */ +# define TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA 0x03000062 +# define TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA 0x03000063 +# define TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA 0x03000064 +# define TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA 0x03000065 +# define TLS1_CK_DHE_DSS_WITH_RC4_128_SHA 0x03000066 + +/* AES ciphersuites from RFC3268 */ +# define TLS1_CK_RSA_WITH_AES_128_SHA 0x0300002F +# define TLS1_CK_DH_DSS_WITH_AES_128_SHA 0x03000030 +# define TLS1_CK_DH_RSA_WITH_AES_128_SHA 0x03000031 +# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA 0x03000032 +# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA 0x03000033 +# define TLS1_CK_ADH_WITH_AES_128_SHA 0x03000034 + +# define TLS1_CK_RSA_WITH_AES_256_SHA 0x03000035 +# define TLS1_CK_DH_DSS_WITH_AES_256_SHA 0x03000036 +# define TLS1_CK_DH_RSA_WITH_AES_256_SHA 0x03000037 +# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA 0x03000038 +# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA 0x03000039 +# define TLS1_CK_ADH_WITH_AES_256_SHA 0x0300003A + +/* TLS v1.2 ciphersuites */ +# define TLS1_CK_RSA_WITH_NULL_SHA256 0x0300003B +# define TLS1_CK_RSA_WITH_AES_128_SHA256 0x0300003C +# define TLS1_CK_RSA_WITH_AES_256_SHA256 0x0300003D +# define TLS1_CK_DH_DSS_WITH_AES_128_SHA256 0x0300003E +# define TLS1_CK_DH_RSA_WITH_AES_128_SHA256 0x0300003F +# define TLS1_CK_DHE_DSS_WITH_AES_128_SHA256 0x03000040 + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000041 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000042 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000043 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 0x03000044 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 0x03000045 +# define TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA 0x03000046 + +/* TLS v1.2 ciphersuites */ +# define TLS1_CK_DHE_RSA_WITH_AES_128_SHA256 0x03000067 +# define TLS1_CK_DH_DSS_WITH_AES_256_SHA256 0x03000068 +# define TLS1_CK_DH_RSA_WITH_AES_256_SHA256 0x03000069 +# define TLS1_CK_DHE_DSS_WITH_AES_256_SHA256 0x0300006A +# define TLS1_CK_DHE_RSA_WITH_AES_256_SHA256 0x0300006B +# define TLS1_CK_ADH_WITH_AES_128_SHA256 0x0300006C +# define TLS1_CK_ADH_WITH_AES_256_SHA256 0x0300006D + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000084 +# define TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000085 +# define TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000086 +# define TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 0x03000087 +# define TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 0x03000088 +# define TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA 0x03000089 + +/* SEED ciphersuites from RFC4162 */ +# define TLS1_CK_RSA_WITH_SEED_SHA 0x03000096 +# define TLS1_CK_DH_DSS_WITH_SEED_SHA 0x03000097 +# define TLS1_CK_DH_RSA_WITH_SEED_SHA 0x03000098 +# define TLS1_CK_DHE_DSS_WITH_SEED_SHA 0x03000099 +# define TLS1_CK_DHE_RSA_WITH_SEED_SHA 0x0300009A +# define TLS1_CK_ADH_WITH_SEED_SHA 0x0300009B + +/* TLS v1.2 GCM ciphersuites from RFC5288 */ +# define TLS1_CK_RSA_WITH_AES_128_GCM_SHA256 0x0300009C +# define TLS1_CK_RSA_WITH_AES_256_GCM_SHA384 0x0300009D +# define TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256 0x0300009E +# define TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384 0x0300009F +# define TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256 0x030000A0 +# define TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384 0x030000A1 +# define TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256 0x030000A2 +# define TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384 0x030000A3 +# define TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256 0x030000A4 +# define TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384 0x030000A5 +# define TLS1_CK_ADH_WITH_AES_128_GCM_SHA256 0x030000A6 +# define TLS1_CK_ADH_WITH_AES_256_GCM_SHA384 0x030000A7 + +/* + * ECC ciphersuites from draft-ietf-tls-ecc-12.txt with changes soon to be in + * draft 13 + */ +# define TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA 0x0300C001 +# define TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA 0x0300C002 +# define TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C003 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA 0x0300C004 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA 0x0300C005 + +# define TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA 0x0300C006 +# define TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA 0x0300C007 +# define TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA 0x0300C008 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA 0x0300C009 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 0x0300C00A + +# define TLS1_CK_ECDH_RSA_WITH_NULL_SHA 0x0300C00B +# define TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA 0x0300C00C +# define TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA 0x0300C00D +# define TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA 0x0300C00E +# define TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA 0x0300C00F + +# define TLS1_CK_ECDHE_RSA_WITH_NULL_SHA 0x0300C010 +# define TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA 0x0300C011 +# define TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA 0x0300C012 +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA 0x0300C013 +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA 0x0300C014 + +# define TLS1_CK_ECDH_anon_WITH_NULL_SHA 0x0300C015 +# define TLS1_CK_ECDH_anon_WITH_RC4_128_SHA 0x0300C016 +# define TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA 0x0300C017 +# define TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA 0x0300C018 +# define TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA 0x0300C019 + +/* SRP ciphersuites from RFC 5054 */ +# define TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA 0x0300C01A +# define TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 0x0300C01B +# define TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 0x0300C01C +# define TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA 0x0300C01D +# define TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA 0x0300C01E +# define TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA 0x0300C01F +# define TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA 0x0300C020 +# define TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA 0x0300C021 +# define TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA 0x0300C022 + +/* ECDH HMAC based ciphersuites from RFC5289 */ + +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256 0x0300C023 +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384 0x0300C024 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256 0x0300C025 +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384 0x0300C026 +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256 0x0300C027 +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384 0x0300C028 +# define TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256 0x0300C029 +# define TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384 0x0300C02A + +/* ECDH GCM based ciphersuites from RFC5289 */ +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02B +# define TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02C +# define TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 0x0300C02D +# define TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 0x0300C02E +# define TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256 0x0300C02F +# define TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384 0x0300C030 +# define TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256 0x0300C031 +# define TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384 0x0300C032 + +/* + * XXX Inconsistency alert: The OpenSSL names of ciphers with ephemeral DH + * here include the string "DHE", while elsewhere it has always been "EDH". + * (The alias for the list of all such ciphers also is "EDH".) The + * specifications speak of "EDH"; maybe we should allow both forms for + * everything. + */ +# define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5 "EXP1024-RC4-MD5" +# define TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5 "EXP1024-RC2-CBC-MD5" +# define TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DES-CBC-SHA" +# define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA "EXP1024-DHE-DSS-DES-CBC-SHA" +# define TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA "EXP1024-RC4-SHA" +# define TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA "EXP1024-DHE-DSS-RC4-SHA" +# define TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA "DHE-DSS-RC4-SHA" + +/* AES ciphersuites from RFC3268 */ +# define TLS1_TXT_RSA_WITH_AES_128_SHA "AES128-SHA" +# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA "DH-DSS-AES128-SHA" +# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA "DH-RSA-AES128-SHA" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA "DHE-DSS-AES128-SHA" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA "DHE-RSA-AES128-SHA" +# define TLS1_TXT_ADH_WITH_AES_128_SHA "ADH-AES128-SHA" + +# define TLS1_TXT_RSA_WITH_AES_256_SHA "AES256-SHA" +# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA "DH-DSS-AES256-SHA" +# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA "DH-RSA-AES256-SHA" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA "DHE-DSS-AES256-SHA" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA "DHE-RSA-AES256-SHA" +# define TLS1_TXT_ADH_WITH_AES_256_SHA "ADH-AES256-SHA" + +/* ECC ciphersuites from RFC4492 */ +# define TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA "ECDH-ECDSA-NULL-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA "ECDH-ECDSA-RC4-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA "ECDH-ECDSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA "ECDH-ECDSA-AES128-SHA" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA "ECDH-ECDSA-AES256-SHA" + +# define TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA "ECDHE-ECDSA-NULL-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA "ECDHE-ECDSA-RC4-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA "ECDHE-ECDSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA "ECDHE-ECDSA-AES128-SHA" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA "ECDHE-ECDSA-AES256-SHA" + +# define TLS1_TXT_ECDH_RSA_WITH_NULL_SHA "ECDH-RSA-NULL-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA "ECDH-RSA-RC4-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA "ECDH-RSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA "ECDH-RSA-AES128-SHA" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA "ECDH-RSA-AES256-SHA" + +# define TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA "ECDHE-RSA-NULL-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA "ECDHE-RSA-RC4-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA "ECDHE-RSA-DES-CBC3-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA "ECDHE-RSA-AES128-SHA" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA "ECDHE-RSA-AES256-SHA" + +# define TLS1_TXT_ECDH_anon_WITH_NULL_SHA "AECDH-NULL-SHA" +# define TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA "AECDH-RC4-SHA" +# define TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA "AECDH-DES-CBC3-SHA" +# define TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA "AECDH-AES128-SHA" +# define TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA "AECDH-AES256-SHA" + +/* PSK ciphersuites from RFC 4279 */ +# define TLS1_TXT_PSK_WITH_RC4_128_SHA "PSK-RC4-SHA" +# define TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA "PSK-3DES-EDE-CBC-SHA" +# define TLS1_TXT_PSK_WITH_AES_128_CBC_SHA "PSK-AES128-CBC-SHA" +# define TLS1_TXT_PSK_WITH_AES_256_CBC_SHA "PSK-AES256-CBC-SHA" + +/* SRP ciphersuite from RFC 5054 */ +# define TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA "SRP-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA "SRP-RSA-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA "SRP-DSS-3DES-EDE-CBC-SHA" +# define TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA "SRP-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA "SRP-RSA-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA "SRP-DSS-AES-128-CBC-SHA" +# define TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA "SRP-AES-256-CBC-SHA" +# define TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA "SRP-RSA-AES-256-CBC-SHA" +# define TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA "SRP-DSS-AES-256-CBC-SHA" + +/* Camellia ciphersuites from RFC4132 */ +# define TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA "CAMELLIA128-SHA" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA "DH-DSS-CAMELLIA128-SHA" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA "DH-RSA-CAMELLIA128-SHA" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA "DHE-DSS-CAMELLIA128-SHA" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA "DHE-RSA-CAMELLIA128-SHA" +# define TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA "ADH-CAMELLIA128-SHA" + +# define TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA "CAMELLIA256-SHA" +# define TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA "DH-DSS-CAMELLIA256-SHA" +# define TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA "DH-RSA-CAMELLIA256-SHA" +# define TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA "DHE-DSS-CAMELLIA256-SHA" +# define TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA "DHE-RSA-CAMELLIA256-SHA" +# define TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA "ADH-CAMELLIA256-SHA" + +/* SEED ciphersuites from RFC4162 */ +# define TLS1_TXT_RSA_WITH_SEED_SHA "SEED-SHA" +# define TLS1_TXT_DH_DSS_WITH_SEED_SHA "DH-DSS-SEED-SHA" +# define TLS1_TXT_DH_RSA_WITH_SEED_SHA "DH-RSA-SEED-SHA" +# define TLS1_TXT_DHE_DSS_WITH_SEED_SHA "DHE-DSS-SEED-SHA" +# define TLS1_TXT_DHE_RSA_WITH_SEED_SHA "DHE-RSA-SEED-SHA" +# define TLS1_TXT_ADH_WITH_SEED_SHA "ADH-SEED-SHA" + +/* TLS v1.2 ciphersuites */ +# define TLS1_TXT_RSA_WITH_NULL_SHA256 "NULL-SHA256" +# define TLS1_TXT_RSA_WITH_AES_128_SHA256 "AES128-SHA256" +# define TLS1_TXT_RSA_WITH_AES_256_SHA256 "AES256-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_128_SHA256 "DH-DSS-AES128-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_128_SHA256 "DH-RSA-AES128-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256 "DHE-DSS-AES128-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256 "DHE-RSA-AES128-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_256_SHA256 "DH-DSS-AES256-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_256_SHA256 "DH-RSA-AES256-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256 "DHE-DSS-AES256-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256 "DHE-RSA-AES256-SHA256" +# define TLS1_TXT_ADH_WITH_AES_128_SHA256 "ADH-AES128-SHA256" +# define TLS1_TXT_ADH_WITH_AES_256_SHA256 "ADH-AES256-SHA256" + +/* TLS v1.2 GCM ciphersuites from RFC5288 */ +# define TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256 "AES128-GCM-SHA256" +# define TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384 "AES256-GCM-SHA384" +# define TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256 "DHE-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384 "DHE-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256 "DH-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384 "DH-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256 "DHE-DSS-AES128-GCM-SHA256" +# define TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384 "DHE-DSS-AES256-GCM-SHA384" +# define TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256 "DH-DSS-AES128-GCM-SHA256" +# define TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384 "DH-DSS-AES256-GCM-SHA384" +# define TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256 "ADH-AES128-GCM-SHA256" +# define TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384 "ADH-AES256-GCM-SHA384" + +/* ECDH HMAC based ciphersuites from RFC5289 */ + +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256 "ECDHE-ECDSA-AES128-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384 "ECDHE-ECDSA-AES256-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256 "ECDH-ECDSA-AES128-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384 "ECDH-ECDSA-AES256-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256 "ECDHE-RSA-AES128-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384 "ECDHE-RSA-AES256-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256 "ECDH-RSA-AES128-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384 "ECDH-RSA-AES256-SHA384" + +/* ECDH GCM based ciphersuites from RFC5289 */ +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 "ECDHE-ECDSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 "ECDHE-ECDSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 "ECDH-ECDSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 "ECDH-ECDSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256 "ECDHE-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384 "ECDHE-RSA-AES256-GCM-SHA384" +# define TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256 "ECDH-RSA-AES128-GCM-SHA256" +# define TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384 "ECDH-RSA-AES256-GCM-SHA384" + +# define TLS_CT_RSA_SIGN 1 +# define TLS_CT_DSS_SIGN 2 +# define TLS_CT_RSA_FIXED_DH 3 +# define TLS_CT_DSS_FIXED_DH 4 +# define TLS_CT_ECDSA_SIGN 64 +# define TLS_CT_RSA_FIXED_ECDH 65 +# define TLS_CT_ECDSA_FIXED_ECDH 66 +# define TLS_CT_GOST94_SIGN 21 +# define TLS_CT_GOST01_SIGN 22 +/* + * when correcting this number, correct also SSL3_CT_NUMBER in ssl3.h (see + * comment there) + */ +# define TLS_CT_NUMBER 9 + +# define TLS1_FINISH_MAC_LENGTH 12 + +# define TLS_MD_MAX_CONST_SIZE 20 +# define TLS_MD_CLIENT_FINISH_CONST "client finished" +# define TLS_MD_CLIENT_FINISH_CONST_SIZE 15 +# define TLS_MD_SERVER_FINISH_CONST "server finished" +# define TLS_MD_SERVER_FINISH_CONST_SIZE 15 +# define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_KEY_EXPANSION_CONST "key expansion" +# define TLS_MD_KEY_EXPANSION_CONST_SIZE 13 +# define TLS_MD_CLIENT_WRITE_KEY_CONST "client write key" +# define TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_SERVER_WRITE_KEY_CONST "server write key" +# define TLS_MD_SERVER_WRITE_KEY_CONST_SIZE 16 +# define TLS_MD_IV_BLOCK_CONST "IV block" +# define TLS_MD_IV_BLOCK_CONST_SIZE 8 +# define TLS_MD_MASTER_SECRET_CONST "master secret" +# define TLS_MD_MASTER_SECRET_CONST_SIZE 13 + +# ifdef CHARSET_EBCDIC +# undef TLS_MD_CLIENT_FINISH_CONST +/* + * client finished + */ +# define TLS_MD_CLIENT_FINISH_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x66\x69\x6e\x69\x73\x68\x65\x64" + +# undef TLS_MD_SERVER_FINISH_CONST +/* + * server finished + */ +# define TLS_MD_SERVER_FINISH_CONST "\x73\x65\x72\x76\x65\x72\x20\x66\x69\x6e\x69\x73\x68\x65\x64" + +# undef TLS_MD_SERVER_WRITE_KEY_CONST +/* + * server write key + */ +# define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_KEY_EXPANSION_CONST +/* + * key expansion + */ +# define TLS_MD_KEY_EXPANSION_CONST "\x6b\x65\x79\x20\x65\x78\x70\x61\x6e\x73\x69\x6f\x6e" + +# undef TLS_MD_CLIENT_WRITE_KEY_CONST +/* + * client write key + */ +# define TLS_MD_CLIENT_WRITE_KEY_CONST "\x63\x6c\x69\x65\x6e\x74\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_SERVER_WRITE_KEY_CONST +/* + * server write key + */ +# define TLS_MD_SERVER_WRITE_KEY_CONST "\x73\x65\x72\x76\x65\x72\x20\x77\x72\x69\x74\x65\x20\x6b\x65\x79" + +# undef TLS_MD_IV_BLOCK_CONST +/* + * IV block + */ +# define TLS_MD_IV_BLOCK_CONST "\x49\x56\x20\x62\x6c\x6f\x63\x6b" + +# undef TLS_MD_MASTER_SECRET_CONST +/* + * master secret + */ +# define TLS_MD_MASTER_SECRET_CONST "\x6d\x61\x73\x74\x65\x72\x20\x73\x65\x63\x72\x65\x74" +# endif + +/* TLS Session Ticket extension struct */ +struct tls_session_ticket_ext_st { + unsigned short length; + void *data; +}; + +#ifdef __cplusplus +} +#endif +#endif diff --git a/libs/openssl/include/openssl/ts.h b/libs/openssl/include/openssl/ts.h new file mode 120000 index 00000000..a75d99db --- /dev/null +++ b/libs/openssl/include/openssl/ts.h @@ -0,0 +1 @@ +../../crypto/ts/ts.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/txt_db.h b/libs/openssl/include/openssl/txt_db.h new file mode 120000 index 00000000..f672e355 --- /dev/null +++ b/libs/openssl/include/openssl/txt_db.h @@ -0,0 +1 @@ +../../crypto/txt_db/txt_db.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/ui.h b/libs/openssl/include/openssl/ui.h new file mode 120000 index 00000000..b07defad --- /dev/null +++ b/libs/openssl/include/openssl/ui.h @@ -0,0 +1 @@ +../../crypto/ui/ui.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/ui_compat.h b/libs/openssl/include/openssl/ui_compat.h new file mode 120000 index 00000000..d8c74b7c --- /dev/null +++ b/libs/openssl/include/openssl/ui_compat.h @@ -0,0 +1 @@ +../../crypto/ui/ui_compat.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/whrlpool.h b/libs/openssl/include/openssl/whrlpool.h new file mode 120000 index 00000000..125a0816 --- /dev/null +++ b/libs/openssl/include/openssl/whrlpool.h @@ -0,0 +1 @@ +../../crypto/whrlpool/whrlpool.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/x509.h b/libs/openssl/include/openssl/x509.h new file mode 120000 index 00000000..b2b85c52 --- /dev/null +++ b/libs/openssl/include/openssl/x509.h @@ -0,0 +1 @@ +../../crypto/x509/x509.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/x509_vfy.h b/libs/openssl/include/openssl/x509_vfy.h new file mode 120000 index 00000000..bb99ad49 --- /dev/null +++ b/libs/openssl/include/openssl/x509_vfy.h @@ -0,0 +1 @@ +../../crypto/x509/x509_vfy.h \ No newline at end of file diff --git a/libs/openssl/include/openssl/x509v3.h b/libs/openssl/include/openssl/x509v3.h new file mode 120000 index 00000000..63d12f9d --- /dev/null +++ b/libs/openssl/include/openssl/x509v3.h @@ -0,0 +1 @@ +../../crypto/x509v3/x509v3.h \ No newline at end of file diff --git a/libs/openssl/ssl/bio_ssl.c b/libs/openssl/ssl/bio_ssl.c new file mode 100644 index 00000000..d2d4d2ea --- /dev/null +++ b/libs/openssl/ssl/bio_ssl.c @@ -0,0 +1,591 @@ +/* ssl/bio_ssl.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static int ssl_write(BIO *h, const char *buf, int num); +static int ssl_read(BIO *h, char *buf, int size); +static int ssl_puts(BIO *h, const char *str); +static long ssl_ctrl(BIO *h, int cmd, long arg1, void *arg2); +static int ssl_new(BIO *h); +static int ssl_free(BIO *data); +static long ssl_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp); +typedef struct bio_ssl_st { + SSL *ssl; /* The ssl handle :-) */ + /* re-negotiate every time the total number of bytes is this size */ + int num_renegotiates; + unsigned long renegotiate_count; + unsigned long byte_count; + unsigned long renegotiate_timeout; + unsigned long last_time; +} BIO_SSL; + +static BIO_METHOD methods_sslp = { + BIO_TYPE_SSL, "ssl", + ssl_write, + ssl_read, + ssl_puts, + NULL, /* ssl_gets, */ + ssl_ctrl, + ssl_new, + ssl_free, + ssl_callback_ctrl, +}; + +BIO_METHOD *BIO_f_ssl(void) +{ + return (&methods_sslp); +} + +static int ssl_new(BIO *bi) +{ + BIO_SSL *bs; + + bs = (BIO_SSL *)OPENSSL_malloc(sizeof(BIO_SSL)); + if (bs == NULL) { + BIOerr(BIO_F_SSL_NEW, ERR_R_MALLOC_FAILURE); + return (0); + } + memset(bs, 0, sizeof(BIO_SSL)); + bi->init = 0; + bi->ptr = (char *)bs; + bi->flags = 0; + return (1); +} + +static int ssl_free(BIO *a) +{ + BIO_SSL *bs; + + if (a == NULL) + return (0); + bs = (BIO_SSL *)a->ptr; + if (bs->ssl != NULL) + SSL_shutdown(bs->ssl); + if (a->shutdown) { + if (a->init && (bs->ssl != NULL)) + SSL_free(bs->ssl); + a->init = 0; + a->flags = 0; + } + if (a->ptr != NULL) + OPENSSL_free(a->ptr); + return (1); +} + +static int ssl_read(BIO *b, char *out, int outl) +{ + int ret = 1; + BIO_SSL *sb; + SSL *ssl; + int retry_reason = 0; + int r = 0; + + if (out == NULL) + return (0); + sb = (BIO_SSL *)b->ptr; + ssl = sb->ssl; + + BIO_clear_retry_flags(b); + +#if 0 + if (!SSL_is_init_finished(ssl)) { +/* ret=SSL_do_handshake(ssl); */ + if (ret > 0) { + + outflags = (BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY); + ret = -1; + goto end; + } + } +#endif +/* if (ret > 0) */ + ret = SSL_read(ssl, out, outl); + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_NONE: + if (ret <= 0) + break; + if (sb->renegotiate_count > 0) { + sb->byte_count += ret; + if (sb->byte_count > sb->renegotiate_count) { + sb->byte_count = 0; + sb->num_renegotiates++; + SSL_renegotiate(ssl); + r = 1; + } + } + if ((sb->renegotiate_timeout > 0) && (!r)) { + unsigned long tm; + + tm = (unsigned long)time(NULL); + if (tm > sb->last_time + sb->renegotiate_timeout) { + sb->last_time = tm; + sb->num_renegotiates++; + SSL_renegotiate(ssl); + } + } + + break; + case SSL_ERROR_WANT_READ: + BIO_set_retry_read(b); + break; + case SSL_ERROR_WANT_WRITE: + BIO_set_retry_write(b); + break; + case SSL_ERROR_WANT_X509_LOOKUP: + BIO_set_retry_special(b); + retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; + case SSL_ERROR_WANT_ACCEPT: + BIO_set_retry_special(b); + retry_reason = BIO_RR_ACCEPT; + break; + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(b); + retry_reason = BIO_RR_CONNECT; + break; + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + case SSL_ERROR_ZERO_RETURN: + default: + break; + } + + b->retry_reason = retry_reason; + return (ret); +} + +static int ssl_write(BIO *b, const char *out, int outl) +{ + int ret, r = 0; + int retry_reason = 0; + SSL *ssl; + BIO_SSL *bs; + + if (out == NULL) + return (0); + bs = (BIO_SSL *)b->ptr; + ssl = bs->ssl; + + BIO_clear_retry_flags(b); + + /* + * ret=SSL_do_handshake(ssl); if (ret > 0) + */ + ret = SSL_write(ssl, out, outl); + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_NONE: + if (ret <= 0) + break; + if (bs->renegotiate_count > 0) { + bs->byte_count += ret; + if (bs->byte_count > bs->renegotiate_count) { + bs->byte_count = 0; + bs->num_renegotiates++; + SSL_renegotiate(ssl); + r = 1; + } + } + if ((bs->renegotiate_timeout > 0) && (!r)) { + unsigned long tm; + + tm = (unsigned long)time(NULL); + if (tm > bs->last_time + bs->renegotiate_timeout) { + bs->last_time = tm; + bs->num_renegotiates++; + SSL_renegotiate(ssl); + } + } + break; + case SSL_ERROR_WANT_WRITE: + BIO_set_retry_write(b); + break; + case SSL_ERROR_WANT_READ: + BIO_set_retry_read(b); + break; + case SSL_ERROR_WANT_X509_LOOKUP: + BIO_set_retry_special(b); + retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(b); + retry_reason = BIO_RR_CONNECT; + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + default: + break; + } + + b->retry_reason = retry_reason; + return (ret); +} + +static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr) +{ + SSL **sslp, *ssl; + BIO_SSL *bs; + BIO *dbio, *bio; + long ret = 1; + + bs = (BIO_SSL *)b->ptr; + ssl = bs->ssl; + if ((ssl == NULL) && (cmd != BIO_C_SET_SSL)) + return (0); + switch (cmd) { + case BIO_CTRL_RESET: + SSL_shutdown(ssl); + + if (ssl->handshake_func == ssl->method->ssl_connect) + SSL_set_connect_state(ssl); + else if (ssl->handshake_func == ssl->method->ssl_accept) + SSL_set_accept_state(ssl); + + SSL_clear(ssl); + + if (b->next_bio != NULL) + ret = BIO_ctrl(b->next_bio, cmd, num, ptr); + else if (ssl->rbio != NULL) + ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + else + ret = 1; + break; + case BIO_CTRL_INFO: + ret = 0; + break; + case BIO_C_SSL_MODE: + if (num) /* client mode */ + SSL_set_connect_state(ssl); + else + SSL_set_accept_state(ssl); + break; + case BIO_C_SET_SSL_RENEGOTIATE_TIMEOUT: + ret = bs->renegotiate_timeout; + if (num < 60) + num = 5; + bs->renegotiate_timeout = (unsigned long)num; + bs->last_time = (unsigned long)time(NULL); + break; + case BIO_C_SET_SSL_RENEGOTIATE_BYTES: + ret = bs->renegotiate_count; + if ((long)num >= 512) + bs->renegotiate_count = (unsigned long)num; + break; + case BIO_C_GET_SSL_NUM_RENEGOTIATES: + ret = bs->num_renegotiates; + break; + case BIO_C_SET_SSL: + if (ssl != NULL) { + ssl_free(b); + if (!ssl_new(b)) + return 0; + } + b->shutdown = (int)num; + ssl = (SSL *)ptr; + ((BIO_SSL *)b->ptr)->ssl = ssl; + bio = SSL_get_rbio(ssl); + if (bio != NULL) { + if (b->next_bio != NULL) + BIO_push(bio, b->next_bio); + b->next_bio = bio; + CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO); + } + b->init = 1; + break; + case BIO_C_GET_SSL: + if (ptr != NULL) { + sslp = (SSL **)ptr; + *sslp = ssl; + } else + ret = 0; + break; + case BIO_CTRL_GET_CLOSE: + ret = b->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + b->shutdown = (int)num; + break; + case BIO_CTRL_WPENDING: + ret = BIO_ctrl(ssl->wbio, cmd, num, ptr); + break; + case BIO_CTRL_PENDING: + ret = SSL_pending(ssl); + if (ret == 0) + ret = BIO_pending(ssl->rbio); + break; + case BIO_CTRL_FLUSH: + BIO_clear_retry_flags(b); + ret = BIO_ctrl(ssl->wbio, cmd, num, ptr); + BIO_copy_next_retry(b); + break; + case BIO_CTRL_PUSH: + if ((b->next_bio != NULL) && (b->next_bio != ssl->rbio)) { + SSL_set_bio(ssl, b->next_bio, b->next_bio); + CRYPTO_add(&b->next_bio->references, 1, CRYPTO_LOCK_BIO); + } + break; + case BIO_CTRL_POP: + /* Only detach if we are the BIO explicitly being popped */ + if (b == ptr) { + /* + * Shouldn't happen in practice because the rbio and wbio are the + * same when pushed. + */ + if (ssl->rbio != ssl->wbio) + BIO_free_all(ssl->wbio); + if (b->next_bio != NULL) + CRYPTO_add(&b->next_bio->references, -1, CRYPTO_LOCK_BIO); + ssl->wbio = NULL; + ssl->rbio = NULL; + } + break; + case BIO_C_DO_STATE_MACHINE: + BIO_clear_retry_flags(b); + + b->retry_reason = 0; + ret = (int)SSL_do_handshake(ssl); + + switch (SSL_get_error(ssl, (int)ret)) { + case SSL_ERROR_WANT_READ: + BIO_set_flags(b, BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY); + break; + case SSL_ERROR_WANT_WRITE: + BIO_set_flags(b, BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY); + break; + case SSL_ERROR_WANT_CONNECT: + BIO_set_flags(b, BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY); + b->retry_reason = b->next_bio->retry_reason; + break; + case SSL_ERROR_WANT_X509_LOOKUP: + BIO_set_retry_special(b); + b->retry_reason = BIO_RR_SSL_X509_LOOKUP; + break; + default: + break; + } + break; + case BIO_CTRL_DUP: + dbio = (BIO *)ptr; + if (((BIO_SSL *)dbio->ptr)->ssl != NULL) + SSL_free(((BIO_SSL *)dbio->ptr)->ssl); + ((BIO_SSL *)dbio->ptr)->ssl = SSL_dup(ssl); + ((BIO_SSL *)dbio->ptr)->renegotiate_count = + ((BIO_SSL *)b->ptr)->renegotiate_count; + ((BIO_SSL *)dbio->ptr)->byte_count = ((BIO_SSL *)b->ptr)->byte_count; + ((BIO_SSL *)dbio->ptr)->renegotiate_timeout = + ((BIO_SSL *)b->ptr)->renegotiate_timeout; + ((BIO_SSL *)dbio->ptr)->last_time = ((BIO_SSL *)b->ptr)->last_time; + ret = (((BIO_SSL *)dbio->ptr)->ssl != NULL); + break; + case BIO_C_GET_FD: + ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + break; + case BIO_CTRL_SET_CALLBACK: + { +#if 0 /* FIXME: Should this be used? -- Richard + * Levitte */ + SSLerr(SSL_F_SSL_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + ret = -1; +#else + ret = 0; +#endif + } + break; + case BIO_CTRL_GET_CALLBACK: + { + void (**fptr) (const SSL *xssl, int type, int val); + + fptr = (void (**)(const SSL *xssl, int type, int val))ptr; + *fptr = SSL_get_info_callback(ssl); + } + break; + default: + ret = BIO_ctrl(ssl->rbio, cmd, num, ptr); + break; + } + return (ret); +} + +static long ssl_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp) +{ + SSL *ssl; + BIO_SSL *bs; + long ret = 1; + + bs = (BIO_SSL *)b->ptr; + ssl = bs->ssl; + switch (cmd) { + case BIO_CTRL_SET_CALLBACK: + { + /* + * FIXME: setting this via a completely different prototype seems + * like a crap idea + */ + SSL_set_info_callback(ssl, (void (*)(const SSL *, int, int))fp); + } + break; + default: + ret = BIO_callback_ctrl(ssl->rbio, cmd, fp); + break; + } + return (ret); +} + +static int ssl_puts(BIO *bp, const char *str) +{ + int n, ret; + + n = strlen(str); + ret = BIO_write(bp, str, n); + return (ret); +} + +BIO *BIO_new_buffer_ssl_connect(SSL_CTX *ctx) +{ +#ifndef OPENSSL_NO_SOCK + BIO *ret = NULL, *buf = NULL, *ssl = NULL; + + if ((buf = BIO_new(BIO_f_buffer())) == NULL) + return (NULL); + if ((ssl = BIO_new_ssl_connect(ctx)) == NULL) + goto err; + if ((ret = BIO_push(buf, ssl)) == NULL) + goto err; + return (ret); + err: + if (buf != NULL) + BIO_free(buf); + if (ssl != NULL) + BIO_free(ssl); +#endif + return (NULL); +} + +BIO *BIO_new_ssl_connect(SSL_CTX *ctx) +{ +#ifndef OPENSSL_NO_SOCK + BIO *ret = NULL, *con = NULL, *ssl = NULL; + + if ((con = BIO_new(BIO_s_connect())) == NULL) + return (NULL); + if ((ssl = BIO_new_ssl(ctx, 1)) == NULL) + goto err; + if ((ret = BIO_push(ssl, con)) == NULL) + goto err; + return (ret); + err: + if (con != NULL) + BIO_free(con); +#endif + return (NULL); +} + +BIO *BIO_new_ssl(SSL_CTX *ctx, int client) +{ + BIO *ret; + SSL *ssl; + + if ((ret = BIO_new(BIO_f_ssl())) == NULL) + return (NULL); + if ((ssl = SSL_new(ctx)) == NULL) { + BIO_free(ret); + return (NULL); + } + if (client) + SSL_set_connect_state(ssl); + else + SSL_set_accept_state(ssl); + + BIO_set_ssl(ret, ssl, BIO_CLOSE); + return (ret); +} + +int BIO_ssl_copy_session_id(BIO *t, BIO *f) +{ + t = BIO_find_type(t, BIO_TYPE_SSL); + f = BIO_find_type(f, BIO_TYPE_SSL); + if ((t == NULL) || (f == NULL)) + return (0); + if ((((BIO_SSL *)t->ptr)->ssl == NULL) || + (((BIO_SSL *)f->ptr)->ssl == NULL)) + return (0); + SSL_copy_session_id(((BIO_SSL *)t->ptr)->ssl, ((BIO_SSL *)f->ptr)->ssl); + return (1); +} + +void BIO_ssl_shutdown(BIO *b) +{ + SSL *s; + + while (b != NULL) { + if (b->method->type == BIO_TYPE_SSL) { + s = ((BIO_SSL *)b->ptr)->ssl; + SSL_shutdown(s); + break; + } + b = b->next_bio; + } +} diff --git a/libs/openssl/ssl/d1_both.c b/libs/openssl/ssl/d1_both.c new file mode 100644 index 00000000..19c3da61 --- /dev/null +++ b/libs/openssl/ssl/d1_both.c @@ -0,0 +1,1700 @@ +/* ssl/d1_both.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include "ssl_locl.h" +#include +#include +#include +#include +#include + +#define RSMBLY_BITMASK_SIZE(msg_len) (((msg_len) + 7) / 8) + +#define RSMBLY_BITMASK_MARK(bitmask, start, end) { \ + if ((end) - (start) <= 8) { \ + long ii; \ + for (ii = (start); ii < (end); ii++) bitmask[((ii) >> 3)] |= (1 << ((ii) & 7)); \ + } else { \ + long ii; \ + bitmask[((start) >> 3)] |= bitmask_start_values[((start) & 7)]; \ + for (ii = (((start) >> 3) + 1); ii < ((((end) - 1)) >> 3); ii++) bitmask[ii] = 0xff; \ + bitmask[(((end) - 1) >> 3)] |= bitmask_end_values[((end) & 7)]; \ + } } + +#define RSMBLY_BITMASK_IS_COMPLETE(bitmask, msg_len, is_complete) { \ + long ii; \ + OPENSSL_assert((msg_len) > 0); \ + is_complete = 1; \ + if (bitmask[(((msg_len) - 1) >> 3)] != bitmask_end_values[((msg_len) & 7)]) is_complete = 0; \ + if (is_complete) for (ii = (((msg_len) - 1) >> 3) - 1; ii >= 0 ; ii--) \ + if (bitmask[ii] != 0xff) { is_complete = 0; break; } } + +#if 0 +# define RSMBLY_BITMASK_PRINT(bitmask, msg_len) { \ + long ii; \ + printf("bitmask: "); for (ii = 0; ii < (msg_len); ii++) \ + printf("%d ", (bitmask[ii >> 3] & (1 << (ii & 7))) >> (ii & 7)); \ + printf("\n"); } +#endif + +static unsigned char bitmask_start_values[] = + { 0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80 }; +static unsigned char bitmask_end_values[] = + { 0xff, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f }; + +/* XDTLS: figure out the right values */ +static const unsigned int g_probable_mtu[] = { 1500, 512, 256 }; + +static void dtls1_fix_message_header(SSL *s, unsigned long frag_off, + unsigned long frag_len); +static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p); +static void dtls1_set_message_header_int(SSL *s, unsigned char mt, + unsigned long len, + unsigned short seq_num, + unsigned long frag_off, + unsigned long frag_len); +static long dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, + int *ok); + +static hm_fragment *dtls1_hm_fragment_new(unsigned long frag_len, + int reassembly) +{ + hm_fragment *frag = NULL; + unsigned char *buf = NULL; + unsigned char *bitmask = NULL; + + frag = (hm_fragment *)OPENSSL_malloc(sizeof(hm_fragment)); + if (frag == NULL) + return NULL; + + if (frag_len) { + buf = (unsigned char *)OPENSSL_malloc(frag_len); + if (buf == NULL) { + OPENSSL_free(frag); + return NULL; + } + } + + /* zero length fragment gets zero frag->fragment */ + frag->fragment = buf; + + /* Initialize reassembly bitmask if necessary */ + if (reassembly) { + bitmask = + (unsigned char *)OPENSSL_malloc(RSMBLY_BITMASK_SIZE(frag_len)); + if (bitmask == NULL) { + if (buf != NULL) + OPENSSL_free(buf); + OPENSSL_free(frag); + return NULL; + } + memset(bitmask, 0, RSMBLY_BITMASK_SIZE(frag_len)); + } + + frag->reassembly = bitmask; + + return frag; +} + +void dtls1_hm_fragment_free(hm_fragment *frag) +{ + + if (frag->msg_header.is_ccs) { + EVP_CIPHER_CTX_free(frag->msg_header. + saved_retransmit_state.enc_write_ctx); + EVP_MD_CTX_destroy(frag->msg_header. + saved_retransmit_state.write_hash); + } + if (frag->fragment) + OPENSSL_free(frag->fragment); + if (frag->reassembly) + OPENSSL_free(frag->reassembly); + OPENSSL_free(frag); +} + +static int dtls1_query_mtu(SSL *s) +{ + if (s->d1->link_mtu) { + s->d1->mtu = + s->d1->link_mtu - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s)); + s->d1->link_mtu = 0; + } + + /* AHA! Figure out the MTU, and stick to the right size */ + if (s->d1->mtu < dtls1_min_mtu(s)) { + if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { + s->d1->mtu = + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); + + /* + * I've seen the kernel return bogus numbers when it doesn't know + * (initial write), so just make sure we have a reasonable number + */ + if (s->d1->mtu < dtls1_min_mtu(s)) { + /* Set to min mtu */ + s->d1->mtu = dtls1_min_mtu(s); + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SET_MTU, + s->d1->mtu, NULL); + } + } else + return 0; + } + return 1; +} + +/* + * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or + * SSL3_RT_CHANGE_CIPHER_SPEC) + */ +int dtls1_do_write(SSL *s, int type) +{ + int ret; + unsigned int curr_mtu; + int retry = 1; + unsigned int len, frag_off, mac_size, blocksize, used_len; + + if (!dtls1_query_mtu(s)) + return -1; + + OPENSSL_assert(s->d1->mtu >= dtls1_min_mtu(s)); /* should have something + * reasonable now */ + + if (s->init_off == 0 && type == SSL3_RT_HANDSHAKE) + OPENSSL_assert(s->init_num == + (int)s->d1->w_msg_hdr.msg_len + + DTLS1_HM_HEADER_LENGTH); + + if (s->write_hash) + mac_size = EVP_MD_CTX_size(s->write_hash); + else + mac_size = 0; + + if (s->enc_write_ctx && + (EVP_CIPHER_mode(s->enc_write_ctx->cipher) & EVP_CIPH_CBC_MODE)) + blocksize = 2 * EVP_CIPHER_block_size(s->enc_write_ctx->cipher); + else + blocksize = 0; + + frag_off = 0; + s->rwstate = SSL_NOTHING; + + /* s->init_num shouldn't ever be < 0...but just in case */ + while (s->init_num > 0) { + if (type == SSL3_RT_HANDSHAKE && s->init_off != 0) { + /* We must be writing a fragment other than the first one */ + + if (frag_off > 0) { + /* This is the first attempt at writing out this fragment */ + + if (s->init_off <= DTLS1_HM_HEADER_LENGTH) { + /* + * Each fragment that was already sent must at least have + * contained the message header plus one other byte. + * Therefore |init_off| must have progressed by at least + * |DTLS1_HM_HEADER_LENGTH + 1| bytes. If not something went + * wrong. + */ + return -1; + } + + /* + * Adjust |init_off| and |init_num| to allow room for a new + * message header for this fragment. + */ + s->init_off -= DTLS1_HM_HEADER_LENGTH; + s->init_num += DTLS1_HM_HEADER_LENGTH; + } else { + /* + * We must have been called again after a retry so use the + * fragment offset from our last attempt. We do not need + * to adjust |init_off| and |init_num| as above, because + * that should already have been done before the retry. + */ + frag_off = s->d1->w_msg_hdr.frag_off; + } + } + + used_len = BIO_wpending(SSL_get_wbio(s)) + DTLS1_RT_HEADER_LENGTH + + mac_size + blocksize; + if (s->d1->mtu > used_len) + curr_mtu = s->d1->mtu - used_len; + else + curr_mtu = 0; + + if (curr_mtu <= DTLS1_HM_HEADER_LENGTH) { + /* + * grr.. we could get an error if MTU picked was wrong + */ + ret = BIO_flush(SSL_get_wbio(s)); + if (ret <= 0) { + s->rwstate = SSL_WRITING; + return ret; + } + used_len = DTLS1_RT_HEADER_LENGTH + mac_size + blocksize; + if (s->d1->mtu > used_len + DTLS1_HM_HEADER_LENGTH) { + curr_mtu = s->d1->mtu - used_len; + } else { + /* Shouldn't happen */ + return -1; + } + } + + /* + * We just checked that s->init_num > 0 so this cast should be safe + */ + if (((unsigned int)s->init_num) > curr_mtu) + len = curr_mtu; + else + len = s->init_num; + + /* Shouldn't ever happen */ + if (len > INT_MAX) + len = INT_MAX; + + /* + * XDTLS: this function is too long. split out the CCS part + */ + if (type == SSL3_RT_HANDSHAKE) { + if (len < DTLS1_HM_HEADER_LENGTH) { + /* + * len is so small that we really can't do anything sensible + * so fail + */ + return -1; + } + dtls1_fix_message_header(s, frag_off, + len - DTLS1_HM_HEADER_LENGTH); + + dtls1_write_message_header(s, + (unsigned char *)&s->init_buf-> + data[s->init_off]); + } + + ret = dtls1_write_bytes(s, type, &s->init_buf->data[s->init_off], + len); + if (ret < 0) { + /* + * might need to update MTU here, but we don't know which + * previous packet caused the failure -- so can't really + * retransmit anything. continue as if everything is fine and + * wait for an alert to handle the retransmit + */ + if (retry && BIO_ctrl(SSL_get_wbio(s), + BIO_CTRL_DGRAM_MTU_EXCEEDED, 0, NULL) > 0) { + if (!(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { + if (!dtls1_query_mtu(s)) + return -1; + /* Have one more go */ + retry = 0; + } else + return -1; + } else { + return (-1); + } + } else { + + /* + * bad if this assert fails, only part of the handshake message + * got sent. but why would this happen? + */ + OPENSSL_assert(len == (unsigned int)ret); + + if (type == SSL3_RT_HANDSHAKE && !s->d1->retransmitting) { + /* + * should not be done for 'Hello Request's, but in that case + * we'll ignore the result anyway + */ + unsigned char *p = + (unsigned char *)&s->init_buf->data[s->init_off]; + const struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + int xlen; + + if (frag_off == 0 && s->version != DTLS1_BAD_VER) { + /* + * reconstruct message header is if it is being sent in + * single fragment + */ + *p++ = msg_hdr->type; + l2n3(msg_hdr->msg_len, p); + s2n(msg_hdr->seq, p); + l2n3(0, p); + l2n3(msg_hdr->msg_len, p); + p -= DTLS1_HM_HEADER_LENGTH; + xlen = ret; + } else { + p += DTLS1_HM_HEADER_LENGTH; + xlen = ret - DTLS1_HM_HEADER_LENGTH; + } + + ssl3_finish_mac(s, p, xlen); + } + + if (ret == s->init_num) { + if (s->msg_callback) + s->msg_callback(1, s->version, type, s->init_buf->data, + (size_t)(s->init_off + s->init_num), s, + s->msg_callback_arg); + + s->init_off = 0; /* done writing this message */ + s->init_num = 0; + + return (1); + } + s->init_off += ret; + s->init_num -= ret; + ret -= DTLS1_HM_HEADER_LENGTH; + frag_off += ret; + + /* + * We save the fragment offset for the next fragment so we have it + * available in case of an IO retry. We don't know the length of the + * next fragment yet so just set that to 0 for now. It will be + * updated again later. + */ + dtls1_fix_message_header(s, frag_off, 0); + } + } + return (0); +} + +/* + * Obtain handshake message of message type 'mt' (any if mt == -1), maximum + * acceptable body length 'max'. Read an entire handshake message. Handshake + * messages arrive in fragments. + */ +long dtls1_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) +{ + int i, al; + struct hm_header_st *msg_hdr; + unsigned char *p; + unsigned long msg_len; + + /* + * s3->tmp is used to store messages that are unexpected, caused by the + * absence of an optional handshake message + */ + if (s->s3->tmp.reuse_message) { + s->s3->tmp.reuse_message = 0; + if ((mt >= 0) && (s->s3->tmp.message_type != mt)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + *ok = 1; + s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + s->init_num = (int)s->s3->tmp.message_size; + return s->init_num; + } + + msg_hdr = &s->d1->r_msg_hdr; + memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); + + again: + i = dtls1_get_message_fragment(s, st1, stn, max, ok); + if (i == DTLS1_HM_BAD_FRAGMENT || i == DTLS1_HM_FRAGMENT_RETRY) { + /* bad fragment received */ + goto again; + } else if (i <= 0 && !*ok) { + return i; + } + + if (mt >= 0 && s->s3->tmp.message_type != mt) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + + p = (unsigned char *)s->init_buf->data; + msg_len = msg_hdr->msg_len; + + /* reconstruct message header */ + *(p++) = msg_hdr->type; + l2n3(msg_len, p); + s2n(msg_hdr->seq, p); + l2n3(0, p); + l2n3(msg_len, p); + if (s->version != DTLS1_BAD_VER) { + p -= DTLS1_HM_HEADER_LENGTH; + msg_len += DTLS1_HM_HEADER_LENGTH; + } + + ssl3_finish_mac(s, p, msg_len); + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + p, msg_len, s, s->msg_callback_arg); + + memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); + + /* Don't change sequence numbers while listening */ + if (!s->d1->listen) + s->d1->handshake_read_seq++; + + s->init_msg = s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + return s->init_num; + + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + *ok = 0; + return -1; +} + +static int dtls1_preprocess_fragment(SSL *s, struct hm_header_st *msg_hdr, + int max) +{ + size_t frag_off, frag_len, msg_len; + + msg_len = msg_hdr->msg_len; + frag_off = msg_hdr->frag_off; + frag_len = msg_hdr->frag_len; + + /* sanity checking */ + if ((frag_off + frag_len) > msg_len) { + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } + + if ((frag_off + frag_len) > (unsigned long)max) { + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } + + if (s->d1->r_msg_hdr.frag_off == 0) { /* first fragment */ + /* + * msg_len is limited to 2^24, but is effectively checked against max + * above + */ + if (!BUF_MEM_grow_clean + (s->init_buf, msg_len + DTLS1_HM_HEADER_LENGTH)) { + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, ERR_R_BUF_LIB); + return SSL_AD_INTERNAL_ERROR; + } + + s->s3->tmp.message_size = msg_len; + s->d1->r_msg_hdr.msg_len = msg_len; + s->s3->tmp.message_type = msg_hdr->type; + s->d1->r_msg_hdr.type = msg_hdr->type; + s->d1->r_msg_hdr.seq = msg_hdr->seq; + } else if (msg_len != s->d1->r_msg_hdr.msg_len) { + /* + * They must be playing with us! BTW, failure to enforce upper limit + * would open possibility for buffer overrun. + */ + SSLerr(SSL_F_DTLS1_PREPROCESS_FRAGMENT, SSL_R_EXCESSIVE_MESSAGE_SIZE); + return SSL_AD_ILLEGAL_PARAMETER; + } + + return 0; /* no error */ +} + +static int dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok) +{ + /*- + * (0) check whether the desired fragment is available + * if so: + * (1) copy over the fragment to s->init_buf->data[] + * (2) update s->init_num + */ + pitem *item; + hm_fragment *frag; + int al; + + *ok = 0; + item = pqueue_peek(s->d1->buffered_messages); + if (item == NULL) + return 0; + + frag = (hm_fragment *)item->data; + + /* Don't return if reassembly still in progress */ + if (frag->reassembly != NULL) + return 0; + + if (s->d1->handshake_read_seq == frag->msg_header.seq) { + unsigned long frag_len = frag->msg_header.frag_len; + pqueue_pop(s->d1->buffered_messages); + + al = dtls1_preprocess_fragment(s, &frag->msg_header, max); + + if (al == 0) { /* no alert */ + unsigned char *p = + (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + memcpy(&p[frag->msg_header.frag_off], frag->fragment, + frag->msg_header.frag_len); + } + + dtls1_hm_fragment_free(frag); + pitem_free(item); + + if (al == 0) { + *ok = 1; + return frag_len; + } + + ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->init_num = 0; + *ok = 0; + return -1; + } else + return 0; +} + +/* + * dtls1_max_handshake_message_len returns the maximum number of bytes + * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but + * may be greater if the maximum certificate list size requires it. + */ +static unsigned long dtls1_max_handshake_message_len(const SSL *s) +{ + unsigned long max_len = + DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; + if (max_len < (unsigned long)s->max_cert_list) + return s->max_cert_list; + return max_len; +} + +static int +dtls1_reassemble_fragment(SSL *s, const struct hm_header_st *msg_hdr, int *ok) +{ + hm_fragment *frag = NULL; + pitem *item = NULL; + int i = -1, is_complete; + unsigned char seq64be[8]; + unsigned long frag_len = msg_hdr->frag_len; + + if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len || + msg_hdr->msg_len > dtls1_max_handshake_message_len(s)) + goto err; + + if (frag_len == 0) + return DTLS1_HM_FRAGMENT_RETRY; + + /* Try to find item in queue */ + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); + seq64be[7] = (unsigned char)msg_hdr->seq; + item = pqueue_find(s->d1->buffered_messages, seq64be); + + if (item == NULL) { + frag = dtls1_hm_fragment_new(msg_hdr->msg_len, 1); + if (frag == NULL) + goto err; + memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + frag->msg_header.frag_len = frag->msg_header.msg_len; + frag->msg_header.frag_off = 0; + } else { + frag = (hm_fragment *)item->data; + if (frag->msg_header.msg_len != msg_hdr->msg_len) { + item = NULL; + frag = NULL; + goto err; + } + } + + /* + * If message is already reassembled, this must be a retransmit and can + * be dropped. In this case item != NULL and so frag does not need to be + * freed. + */ + if (frag->reassembly == NULL) { + unsigned char devnull[256]; + + while (frag_len) { + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + devnull, + frag_len > + sizeof(devnull) ? sizeof(devnull) : + frag_len, 0); + if (i <= 0) + goto err; + frag_len -= i; + } + return DTLS1_HM_FRAGMENT_RETRY; + } + + /* read the body of the fragment (header has already been read */ + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + frag->fragment + msg_hdr->frag_off, + frag_len, 0); + if ((unsigned long)i != frag_len) + i = -1; + if (i <= 0) + goto err; + + RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off, + (long)(msg_hdr->frag_off + frag_len)); + + RSMBLY_BITMASK_IS_COMPLETE(frag->reassembly, (long)msg_hdr->msg_len, + is_complete); + + if (is_complete) { + OPENSSL_free(frag->reassembly); + frag->reassembly = NULL; + } + + if (item == NULL) { + item = pitem_new(seq64be, frag); + if (item == NULL) { + i = -1; + goto err; + } + + item = pqueue_insert(s->d1->buffered_messages, item); + /* + * pqueue_insert fails iff a duplicate item is inserted. However, + * |item| cannot be a duplicate. If it were, |pqueue_find|, above, + * would have returned it and control would never have reached this + * branch. + */ + OPENSSL_assert(item != NULL); + } + + return DTLS1_HM_FRAGMENT_RETRY; + + err: + if (frag != NULL && item == NULL) + dtls1_hm_fragment_free(frag); + *ok = 0; + return i; +} + +static int +dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st *msg_hdr, + int *ok) +{ + int i = -1; + hm_fragment *frag = NULL; + pitem *item = NULL; + unsigned char seq64be[8]; + unsigned long frag_len = msg_hdr->frag_len; + + if ((msg_hdr->frag_off + frag_len) > msg_hdr->msg_len) + goto err; + + /* Try to find item in queue, to prevent duplicate entries */ + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(msg_hdr->seq >> 8); + seq64be[7] = (unsigned char)msg_hdr->seq; + item = pqueue_find(s->d1->buffered_messages, seq64be); + + /* + * If we already have an entry and this one is a fragment, don't discard + * it and rather try to reassemble it. + */ + if (item != NULL && frag_len != msg_hdr->msg_len) + item = NULL; + + /* + * Discard the message if sequence number was already there, is too far + * in the future, already in the queue or if we received a FINISHED + * before the SERVER_HELLO, which then must be a stale retransmit. + */ + if (msg_hdr->seq <= s->d1->handshake_read_seq || + msg_hdr->seq > s->d1->handshake_read_seq + 10 || item != NULL || + (s->d1->handshake_read_seq == 0 && msg_hdr->type == SSL3_MT_FINISHED)) + { + unsigned char devnull[256]; + + while (frag_len) { + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + devnull, + frag_len > + sizeof(devnull) ? sizeof(devnull) : + frag_len, 0); + if (i <= 0) + goto err; + frag_len -= i; + } + } else { + if (frag_len != msg_hdr->msg_len) + return dtls1_reassemble_fragment(s, msg_hdr, ok); + + if (frag_len > dtls1_max_handshake_message_len(s)) + goto err; + + frag = dtls1_hm_fragment_new(frag_len, 0); + if (frag == NULL) + goto err; + + memcpy(&(frag->msg_header), msg_hdr, sizeof(*msg_hdr)); + + if (frag_len) { + /* + * read the body of the fragment (header has already been read + */ + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + frag->fragment, frag_len, 0); + if ((unsigned long)i != frag_len) + i = -1; + if (i <= 0) + goto err; + } + + item = pitem_new(seq64be, frag); + if (item == NULL) + goto err; + + item = pqueue_insert(s->d1->buffered_messages, item); + /* + * pqueue_insert fails iff a duplicate item is inserted. However, + * |item| cannot be a duplicate. If it were, |pqueue_find|, above, + * would have returned it. Then, either |frag_len| != + * |msg_hdr->msg_len| in which case |item| is set to NULL and it will + * have been processed with |dtls1_reassemble_fragment|, above, or + * the record will have been discarded. + */ + OPENSSL_assert(item != NULL); + } + + return DTLS1_HM_FRAGMENT_RETRY; + + err: + if (frag != NULL && item == NULL) + dtls1_hm_fragment_free(frag); + *ok = 0; + return i; +} + +static long +dtls1_get_message_fragment(SSL *s, int st1, int stn, long max, int *ok) +{ + unsigned char wire[DTLS1_HM_HEADER_LENGTH]; + unsigned long len, frag_off, frag_len; + int i, al; + struct hm_header_st msg_hdr; + + redo: + /* see if we have the required fragment already */ + if ((frag_len = dtls1_retrieve_buffered_fragment(s, max, ok)) || *ok) { + if (*ok) + s->init_num = frag_len; + return frag_len; + } + + /* read handshake message header */ + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, wire, + DTLS1_HM_HEADER_LENGTH, 0); + if (i <= 0) { /* nbio, or an error */ + s->rwstate = SSL_READING; + *ok = 0; + return i; + } + /* Handshake fails if message header is incomplete */ + if (i != DTLS1_HM_HEADER_LENGTH) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + + /* parse the message fragment header */ + dtls1_get_message_header(wire, &msg_hdr); + + len = msg_hdr.msg_len; + frag_off = msg_hdr.frag_off; + frag_len = msg_hdr.frag_len; + + /* + * We must have at least frag_len bytes left in the record to be read. + * Fragments must not span records. + */ + if (frag_len > s->s3->rrec.length) { + al = SSL3_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL_R_BAD_LENGTH); + goto f_err; + } + + /* + * if this is a future (or stale) message it gets buffered + * (or dropped)--no further processing at this time + * While listening, we accept seq 1 (ClientHello with cookie) + * although we're still expecting seq 0 (ClientHello) + */ + if (msg_hdr.seq != s->d1->handshake_read_seq + && !(s->d1->listen && msg_hdr.seq == 1)) + return dtls1_process_out_of_seq_message(s, &msg_hdr, ok); + + if (frag_len && frag_len < len) + return dtls1_reassemble_fragment(s, &msg_hdr, ok); + + if (!s->server && s->d1->r_msg_hdr.frag_off == 0 && + wire[0] == SSL3_MT_HELLO_REQUEST) { + /* + * The server may always send 'Hello Request' messages -- we are + * doing a handshake anyway now, so ignore them if their format is + * correct. Does not count for 'Finished' MAC. + */ + if (wire[1] == 0 && wire[2] == 0 && wire[3] == 0) { + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + wire, DTLS1_HM_HEADER_LENGTH, s, + s->msg_callback_arg); + + s->init_num = 0; + goto redo; + } else { /* Incorrectly formated Hello request */ + + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, + SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + } + + if ((al = dtls1_preprocess_fragment(s, &msg_hdr, max))) + goto f_err; + + if (frag_len > 0) { + unsigned char *p = + (unsigned char *)s->init_buf->data + DTLS1_HM_HEADER_LENGTH; + + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + &p[frag_off], frag_len, 0); + + /* + * This shouldn't ever fail due to NBIO because we already checked + * that we have enough data in the record + */ + if (i <= 0) { + s->rwstate = SSL_READING; + *ok = 0; + return i; + } + } else + i = 0; + + /* + * XDTLS: an incorrectly formatted fragment should cause the handshake + * to fail + */ + if (i != (int)frag_len) { + al = SSL3_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT, SSL3_AD_ILLEGAL_PARAMETER); + goto f_err; + } + + *ok = 1; + s->state = stn; + + /* + * Note that s->init_num is *not* used as current offset in + * s->init_buf->data, but as a counter summing up fragments' lengths: as + * soon as they sum up to handshake packet length, we assume we have got + * all the fragments. + */ + s->init_num = frag_len; + return frag_len; + + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->init_num = 0; + + *ok = 0; + return (-1); +} + +int dtls1_send_finished(SSL *s, int a, int b, const char *sender, int slen) +{ + unsigned char *p, *d; + int i; + unsigned long l; + + if (s->state == a) { + d = (unsigned char *)s->init_buf->data; + p = &(d[DTLS1_HM_HEADER_LENGTH]); + + i = s->method->ssl3_enc->final_finish_mac(s, + sender, slen, + s->s3->tmp.finish_md); + s->s3->tmp.finish_md_len = i; + memcpy(p, s->s3->tmp.finish_md, i); + p += i; + l = i; + + /* + * Copy the finished so we can use it for renegotiation checks + */ + if (s->type == SSL_ST_CONNECT) { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_client_finished, s->s3->tmp.finish_md, i); + s->s3->previous_client_finished_len = i; + } else { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md, i); + s->s3->previous_server_finished_len = i; + } + +#ifdef OPENSSL_SYS_WIN16 + /* + * MSVC 1.5 does not clear the top bytes of the word unless I do + * this. + */ + l &= 0xffff; +#endif + + d = dtls1_set_message_header(s, d, SSL3_MT_FINISHED, l, 0, l); + s->init_num = (int)l + DTLS1_HM_HEADER_LENGTH; + s->init_off = 0; + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); + + s->state = b; + } + + /* SSL3_ST_SEND_xxxxxx_HELLO_B */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); +} + +/*- + * for these 2 messages, we need to + * ssl->enc_read_ctx re-init + * ssl->s3->read_sequence zero + * ssl->s3->read_mac_secret re-init + * ssl->session->read_sym_enc assign + * ssl->session->read_compression assign + * ssl->session->read_hash assign + */ +int dtls1_send_change_cipher_spec(SSL *s, int a, int b) +{ + unsigned char *p; + + if (s->state == a) { + p = (unsigned char *)s->init_buf->data; + *p++ = SSL3_MT_CCS; + s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; + s->init_num = DTLS1_CCS_HEADER_LENGTH; + + if (s->version == DTLS1_BAD_VER) { + s->d1->next_handshake_write_seq++; + s2n(s->d1->handshake_write_seq, p); + s->init_num += 2; + } + + s->init_off = 0; + + dtls1_set_message_header_int(s, SSL3_MT_CCS, 0, + s->d1->handshake_write_seq, 0, 0); + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 1); + + s->state = b; + } + + /* SSL3_ST_CW_CHANGE_B */ + return (dtls1_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC)); +} + +static int dtls1_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) +{ + int n; + unsigned char *p; + + n = i2d_X509(x, NULL); + if (!BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) { + SSLerr(SSL_F_DTLS1_ADD_CERT_TO_BUF, ERR_R_BUF_LIB); + return 0; + } + p = (unsigned char *)&(buf->data[*l]); + l2n3(n, p); + i2d_X509(x, &p); + *l += n + 3; + + return 1; +} + +unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) +{ + unsigned char *p; + int i; + unsigned long l = 3 + DTLS1_HM_HEADER_LENGTH; + BUF_MEM *buf; + + /* TLSv1 sends a chain with nothing in it, instead of an alert */ + buf = s->init_buf; + if (!BUF_MEM_grow_clean(buf, 10)) { + SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN, ERR_R_BUF_LIB); + return (0); + } + if (x != NULL) { + X509_STORE_CTX xs_ctx; + + if (!X509_STORE_CTX_init(&xs_ctx, s->ctx->cert_store, x, NULL)) { + SSLerr(SSL_F_DTLS1_OUTPUT_CERT_CHAIN, ERR_R_X509_LIB); + return (0); + } + + X509_verify_cert(&xs_ctx); + /* Don't leave errors in the queue */ + ERR_clear_error(); + for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) { + x = sk_X509_value(xs_ctx.chain, i); + + if (!dtls1_add_cert_to_buf(buf, &l, x)) { + X509_STORE_CTX_cleanup(&xs_ctx); + return 0; + } + } + X509_STORE_CTX_cleanup(&xs_ctx); + } + /* Thawte special :-) */ + for (i = 0; i < sk_X509_num(s->ctx->extra_certs); i++) { + x = sk_X509_value(s->ctx->extra_certs, i); + if (!dtls1_add_cert_to_buf(buf, &l, x)) + return 0; + } + + l -= (3 + DTLS1_HM_HEADER_LENGTH); + + p = (unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]); + l2n3(l, p); + l += 3; + p = (unsigned char *)&(buf->data[0]); + p = dtls1_set_message_header(s, p, SSL3_MT_CERTIFICATE, l, 0, l); + + l += DTLS1_HM_HEADER_LENGTH; + return (l); +} + +int dtls1_read_failed(SSL *s, int code) +{ + if (code > 0) { + fprintf(stderr, "invalid state reached %s:%d", __FILE__, __LINE__); + return 1; + } + + if (!dtls1_is_timer_expired(s)) { + /* + * not a timeout, none of our business, let higher layers handle + * this. in fact it's probably an error + */ + return code; + } +#ifndef OPENSSL_NO_HEARTBEATS + /* done, no need to send a retransmit */ + if (!SSL_in_init(s) && !s->tlsext_hb_pending) +#else + /* done, no need to send a retransmit */ + if (!SSL_in_init(s)) +#endif + { + BIO_set_flags(SSL_get_rbio(s), BIO_FLAGS_READ); + return code; + } +#if 0 /* for now, each alert contains only one + * record number */ + item = pqueue_peek(state->rcvd_records); + if (item) { + /* send an alert immediately for all the missing records */ + } else +#endif + +#if 0 /* no more alert sending, just retransmit the + * last set of messages */ + if (state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT) + ssl3_send_alert(s, SSL3_AL_WARNING, + DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); +#endif + + return dtls1_handle_timeout(s); +} + +int dtls1_get_queue_priority(unsigned short seq, int is_ccs) +{ + /* + * The index of the retransmission queue actually is the message sequence + * number, since the queue only contains messages of a single handshake. + * However, the ChangeCipherSpec has no message sequence number and so + * using only the sequence will result in the CCS and Finished having the + * same index. To prevent this, the sequence number is multiplied by 2. + * In case of a CCS 1 is subtracted. This does not only differ CSS and + * Finished, it also maintains the order of the index (important for + * priority queues) and fits in the unsigned short variable. + */ + return seq * 2 - is_ccs; +} + +int dtls1_retransmit_buffered_messages(SSL *s) +{ + pqueue sent = s->d1->sent_messages; + piterator iter; + pitem *item; + hm_fragment *frag; + int found = 0; + + iter = pqueue_iterator(sent); + + for (item = pqueue_next(&iter); item != NULL; item = pqueue_next(&iter)) { + frag = (hm_fragment *)item->data; + if (dtls1_retransmit_message(s, (unsigned short) + dtls1_get_queue_priority + (frag->msg_header.seq, + frag->msg_header.is_ccs), 0, + &found) <= 0 && found) { + fprintf(stderr, "dtls1_retransmit_message() failed\n"); + return -1; + } + } + + return 1; +} + +int dtls1_buffer_message(SSL *s, int is_ccs) +{ + pitem *item; + hm_fragment *frag; + unsigned char seq64be[8]; + + /* + * this function is called immediately after a message has been + * serialized + */ + OPENSSL_assert(s->init_off == 0); + + frag = dtls1_hm_fragment_new(s->init_num, 0); + if (!frag) + return 0; + + memcpy(frag->fragment, s->init_buf->data, s->init_num); + + if (is_ccs) { + OPENSSL_assert(s->d1->w_msg_hdr.msg_len + + ((s->version == + DTLS1_VERSION) ? DTLS1_CCS_HEADER_LENGTH : 3) == + (unsigned int)s->init_num); + } else { + OPENSSL_assert(s->d1->w_msg_hdr.msg_len + + DTLS1_HM_HEADER_LENGTH == (unsigned int)s->init_num); + } + + frag->msg_header.msg_len = s->d1->w_msg_hdr.msg_len; + frag->msg_header.seq = s->d1->w_msg_hdr.seq; + frag->msg_header.type = s->d1->w_msg_hdr.type; + frag->msg_header.frag_off = 0; + frag->msg_header.frag_len = s->d1->w_msg_hdr.msg_len; + frag->msg_header.is_ccs = is_ccs; + + /* save current state */ + frag->msg_header.saved_retransmit_state.enc_write_ctx = s->enc_write_ctx; + frag->msg_header.saved_retransmit_state.write_hash = s->write_hash; + frag->msg_header.saved_retransmit_state.compress = s->compress; + frag->msg_header.saved_retransmit_state.session = s->session; + frag->msg_header.saved_retransmit_state.epoch = s->d1->w_epoch; + + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = + (unsigned + char)(dtls1_get_queue_priority(frag->msg_header.seq, + frag->msg_header.is_ccs) >> 8); + seq64be[7] = + (unsigned + char)(dtls1_get_queue_priority(frag->msg_header.seq, + frag->msg_header.is_ccs)); + + item = pitem_new(seq64be, frag); + if (item == NULL) { + dtls1_hm_fragment_free(frag); + return 0; + } +#if 0 + fprintf(stderr, "buffered messge: \ttype = %xx\n", msg_buf->type); + fprintf(stderr, "\t\t\t\t\tlen = %d\n", msg_buf->len); + fprintf(stderr, "\t\t\t\t\tseq_num = %d\n", msg_buf->seq_num); +#endif + + pqueue_insert(s->d1->sent_messages, item); + return 1; +} + +int +dtls1_retransmit_message(SSL *s, unsigned short seq, unsigned long frag_off, + int *found) +{ + int ret; + /* XDTLS: for now assuming that read/writes are blocking */ + pitem *item; + hm_fragment *frag; + unsigned long header_length; + unsigned char seq64be[8]; + struct dtls1_retransmit_state saved_state; + unsigned char save_write_sequence[8]; + + /*- + OPENSSL_assert(s->init_num == 0); + OPENSSL_assert(s->init_off == 0); + */ + + /* XDTLS: the requested message ought to be found, otherwise error */ + memset(seq64be, 0, sizeof(seq64be)); + seq64be[6] = (unsigned char)(seq >> 8); + seq64be[7] = (unsigned char)seq; + + item = pqueue_find(s->d1->sent_messages, seq64be); + if (item == NULL) { + fprintf(stderr, "retransmit: message %d non-existant\n", seq); + *found = 0; + return 0; + } + + *found = 1; + frag = (hm_fragment *)item->data; + + if (frag->msg_header.is_ccs) + header_length = DTLS1_CCS_HEADER_LENGTH; + else + header_length = DTLS1_HM_HEADER_LENGTH; + + memcpy(s->init_buf->data, frag->fragment, + frag->msg_header.msg_len + header_length); + s->init_num = frag->msg_header.msg_len + header_length; + + dtls1_set_message_header_int(s, frag->msg_header.type, + frag->msg_header.msg_len, + frag->msg_header.seq, 0, + frag->msg_header.frag_len); + + /* save current state */ + saved_state.enc_write_ctx = s->enc_write_ctx; + saved_state.write_hash = s->write_hash; + saved_state.compress = s->compress; + saved_state.session = s->session; + saved_state.epoch = s->d1->w_epoch; + saved_state.epoch = s->d1->w_epoch; + + s->d1->retransmitting = 1; + + /* restore state in which the message was originally sent */ + s->enc_write_ctx = frag->msg_header.saved_retransmit_state.enc_write_ctx; + s->write_hash = frag->msg_header.saved_retransmit_state.write_hash; + s->compress = frag->msg_header.saved_retransmit_state.compress; + s->session = frag->msg_header.saved_retransmit_state.session; + s->d1->w_epoch = frag->msg_header.saved_retransmit_state.epoch; + + if (frag->msg_header.saved_retransmit_state.epoch == + saved_state.epoch - 1) { + memcpy(save_write_sequence, s->s3->write_sequence, + sizeof(s->s3->write_sequence)); + memcpy(s->s3->write_sequence, s->d1->last_write_sequence, + sizeof(s->s3->write_sequence)); + } + + ret = dtls1_do_write(s, frag->msg_header.is_ccs ? + SSL3_RT_CHANGE_CIPHER_SPEC : SSL3_RT_HANDSHAKE); + + /* restore current state */ + s->enc_write_ctx = saved_state.enc_write_ctx; + s->write_hash = saved_state.write_hash; + s->compress = saved_state.compress; + s->session = saved_state.session; + s->d1->w_epoch = saved_state.epoch; + + if (frag->msg_header.saved_retransmit_state.epoch == + saved_state.epoch - 1) { + memcpy(s->d1->last_write_sequence, s->s3->write_sequence, + sizeof(s->s3->write_sequence)); + memcpy(s->s3->write_sequence, save_write_sequence, + sizeof(s->s3->write_sequence)); + } + + s->d1->retransmitting = 0; + + (void)BIO_flush(SSL_get_wbio(s)); + return ret; +} + +/* call this function when the buffered messages are no longer needed */ +void dtls1_clear_record_buffer(SSL *s) +{ + pitem *item; + + for (item = pqueue_pop(s->d1->sent_messages); + item != NULL; item = pqueue_pop(s->d1->sent_messages)) { + dtls1_hm_fragment_free((hm_fragment *)item->data); + pitem_free(item); + } +} + +unsigned char *dtls1_set_message_header(SSL *s, unsigned char *p, + unsigned char mt, unsigned long len, + unsigned long frag_off, + unsigned long frag_len) +{ + /* Don't change sequence numbers while listening */ + if (frag_off == 0 && !s->d1->listen) { + s->d1->handshake_write_seq = s->d1->next_handshake_write_seq; + s->d1->next_handshake_write_seq++; + } + + dtls1_set_message_header_int(s, mt, len, s->d1->handshake_write_seq, + frag_off, frag_len); + + return p += DTLS1_HM_HEADER_LENGTH; +} + +/* don't actually do the writing, wait till the MTU has been retrieved */ +static void +dtls1_set_message_header_int(SSL *s, unsigned char mt, + unsigned long len, unsigned short seq_num, + unsigned long frag_off, unsigned long frag_len) +{ + struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + + msg_hdr->type = mt; + msg_hdr->msg_len = len; + msg_hdr->seq = seq_num; + msg_hdr->frag_off = frag_off; + msg_hdr->frag_len = frag_len; +} + +static void +dtls1_fix_message_header(SSL *s, unsigned long frag_off, + unsigned long frag_len) +{ + struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + + msg_hdr->frag_off = frag_off; + msg_hdr->frag_len = frag_len; +} + +static unsigned char *dtls1_write_message_header(SSL *s, unsigned char *p) +{ + struct hm_header_st *msg_hdr = &s->d1->w_msg_hdr; + + *p++ = msg_hdr->type; + l2n3(msg_hdr->msg_len, p); + + s2n(msg_hdr->seq, p); + l2n3(msg_hdr->frag_off, p); + l2n3(msg_hdr->frag_len, p); + + return p; +} + +unsigned int dtls1_link_min_mtu(void) +{ + return (g_probable_mtu[(sizeof(g_probable_mtu) / + sizeof(g_probable_mtu[0])) - 1]); +} + +unsigned int dtls1_min_mtu(SSL *s) +{ + return dtls1_link_min_mtu() - BIO_dgram_get_mtu_overhead(SSL_get_wbio(s)); +} + +void +dtls1_get_message_header(unsigned char *data, struct hm_header_st *msg_hdr) +{ + memset(msg_hdr, 0x00, sizeof(struct hm_header_st)); + msg_hdr->type = *(data++); + n2l3(data, msg_hdr->msg_len); + + n2s(data, msg_hdr->seq); + n2l3(data, msg_hdr->frag_off); + n2l3(data, msg_hdr->frag_len); +} + +void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr) +{ + memset(ccs_hdr, 0x00, sizeof(struct ccs_header_st)); + + ccs_hdr->type = *(data++); +} + +int dtls1_shutdown(SSL *s) +{ + int ret; +#ifndef OPENSSL_NO_SCTP + BIO *wbio; + + wbio = SSL_get_wbio(s); + if (wbio != NULL && BIO_dgram_is_sctp(wbio) && + !(s->shutdown & SSL_SENT_SHUTDOWN)) { + ret = BIO_dgram_sctp_wait_for_dry(wbio); + if (ret < 0) + return -1; + + if (ret == 0) + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 1, + NULL); + } +#endif + ret = ssl3_shutdown(s); +#ifndef OPENSSL_NO_SCTP + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SAVE_SHUTDOWN, 0, NULL); +#endif + return ret; +} + +#ifndef OPENSSL_NO_HEARTBEATS +int dtls1_process_heartbeat(SSL *s) +{ + unsigned char *p = &s->s3->rrec.data[0], *pl; + unsigned short hbtype; + unsigned int payload; + unsigned int padding = 16; /* Use minimum padding */ + + if (s->msg_callback) + s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, + &s->s3->rrec.data[0], s->s3->rrec.length, + s, s->msg_callback_arg); + + /* Read type and payload length first */ + if (1 + 2 + 16 > s->s3->rrec.length) + return 0; /* silently discard */ + if (s->s3->rrec.length > SSL3_RT_MAX_PLAIN_LENGTH) + return 0; /* silently discard per RFC 6520 sec. 4 */ + + hbtype = *p++; + n2s(p, payload); + if (1 + 2 + payload + 16 > s->s3->rrec.length) + return 0; /* silently discard per RFC 6520 sec. 4 */ + pl = p; + + if (hbtype == TLS1_HB_REQUEST) { + unsigned char *buffer, *bp; + unsigned int write_length = 1 /* heartbeat type */ + + 2 /* heartbeat length */ + + payload + padding; + int r; + + if (write_length > SSL3_RT_MAX_PLAIN_LENGTH) + return 0; + + /* + * Allocate memory for the response, size is 1 byte message type, + * plus 2 bytes payload length, plus payload, plus padding + */ + buffer = OPENSSL_malloc(write_length); + if (buffer == NULL) + return -1; + bp = buffer; + + /* Enter response type, length and copy payload */ + *bp++ = TLS1_HB_RESPONSE; + s2n(payload, bp); + memcpy(bp, pl, payload); + bp += payload; + /* Random padding */ + if (RAND_pseudo_bytes(bp, padding) < 0) { + OPENSSL_free(buffer); + return -1; + } + + r = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, write_length); + + if (r >= 0 && s->msg_callback) + s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, + buffer, write_length, s, s->msg_callback_arg); + + OPENSSL_free(buffer); + + if (r < 0) + return r; + } else if (hbtype == TLS1_HB_RESPONSE) { + unsigned int seq; + + /* + * We only send sequence numbers (2 bytes unsigned int), and 16 + * random bytes, so we just try to read the sequence number + */ + n2s(pl, seq); + + if (payload == 18 && seq == s->tlsext_hb_seq) { + dtls1_stop_timer(s); + s->tlsext_hb_seq++; + s->tlsext_hb_pending = 0; + } + } + + return 0; +} + +int dtls1_heartbeat(SSL *s) +{ + unsigned char *buf, *p; + int ret = -1; + unsigned int payload = 18; /* Sequence number + random bytes */ + unsigned int padding = 16; /* Use minimum padding */ + + /* Only send if peer supports and accepts HB requests... */ + if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) || + s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) { + SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT); + return -1; + } + + /* ...and there is none in flight yet... */ + if (s->tlsext_hb_pending) { + SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING); + return -1; + } + + /* ...and no handshake in progress. */ + if (SSL_in_init(s) || s->in_handshake) { + SSLerr(SSL_F_DTLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE); + return -1; + } + + /* + * Check if padding is too long, payload and padding must not exceed 2^14 + * - 3 = 16381 bytes in total. + */ + OPENSSL_assert(payload + padding <= 16381); + + /*- + * Create HeartBeat message, we just use a sequence number + * as payload to distuingish different messages and add + * some random stuff. + * - Message Type, 1 byte + * - Payload Length, 2 bytes (unsigned int) + * - Payload, the sequence number (2 bytes uint) + * - Payload, random bytes (16 bytes uint) + * - Padding + */ + buf = OPENSSL_malloc(1 + 2 + payload + padding); + p = buf; + /* Message Type */ + *p++ = TLS1_HB_REQUEST; + /* Payload length (18 bytes here) */ + s2n(payload, p); + /* Sequence number */ + s2n(s->tlsext_hb_seq, p); + /* 16 random bytes */ + if (RAND_pseudo_bytes(p, 16) < 0) + goto err; + p += 16; + /* Random padding */ + if (RAND_pseudo_bytes(p, padding) < 0) + goto err; + + ret = dtls1_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); + if (ret >= 0) { + if (s->msg_callback) + s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, + buf, 3 + payload + padding, + s, s->msg_callback_arg); + + dtls1_start_timer(s); + s->tlsext_hb_pending = 1; + } + +err: + OPENSSL_free(buf); + + return ret; +} +#endif diff --git a/libs/openssl/ssl/d1_clnt.c b/libs/openssl/ssl/d1_clnt.c new file mode 100644 index 00000000..eb371a25 --- /dev/null +++ b/libs/openssl/ssl/d1_clnt.c @@ -0,0 +1,1713 @@ +/* ssl/d1_clnt.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "ssl_locl.h" +#ifndef OPENSSL_NO_KRB5 +# include "kssl_lcl.h" +#endif +#include +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_DH +# include +#endif + +static const SSL_METHOD *dtls1_get_client_method(int ver); +static int dtls1_get_hello_verify(SSL *s); + +static const SSL_METHOD *dtls1_get_client_method(int ver) +{ + if (ver == DTLS1_VERSION || ver == DTLS1_BAD_VER) + return (DTLSv1_client_method()); + else + return (NULL); +} + +IMPLEMENT_dtls1_meth_func(DTLSv1_client_method, + ssl_undefined_function, + dtls1_connect, dtls1_get_client_method) + +int dtls1_connect(SSL *s) +{ + BUF_MEM *buf = NULL; + unsigned long Time = (unsigned long)time(NULL); + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state, skip = 0; +#ifndef OPENSSL_NO_SCTP + unsigned char sctpauthkey[64]; + char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; +#endif + + RAND_add(&Time, sizeof(Time), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + +#ifndef OPENSSL_NO_SCTP + /* + * Notify SCTP BIO socket to enter handshake mode and prevent stream + * identifier other than 0. Will be ignored if no SCTP is used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, + s->in_handshake, NULL); +#endif + +#ifndef OPENSSL_NO_HEARTBEATS + /* + * If we're awaiting a HeartbeatResponse, pretend we already got and + * don't await it anymore, because Heartbeats don't make sense during + * handshakes anyway. + */ + if (s->tlsext_hb_pending) { + dtls1_stop_timer(s); + s->tlsext_hb_pending = 0; + s->tlsext_hb_seq++; + } +#endif + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_RENEGOTIATE: + s->renegotiate = 1; + s->state = SSL_ST_CONNECT; + s->ctx->stats.sess_connect_renegotiate++; + /* break */ + case SSL_ST_BEFORE: + case SSL_ST_CONNECT: + case SSL_ST_BEFORE | SSL_ST_CONNECT: + case SSL_ST_OK | SSL_ST_CONNECT: + + s->server = 0; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00) && + (s->version & 0xff00) != (DTLS1_BAD_VER & 0xff00)) { + SSLerr(SSL_F_DTLS1_CONNECT, ERR_R_INTERNAL_ERROR); + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + /* s->version=SSL3_VERSION; */ + s->type = SSL_ST_CONNECT; + + if (s->init_buf == NULL) { + if ((buf = BUF_MEM_new()) == NULL) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + s->init_buf = buf; + buf = NULL; + } + + if (!ssl3_setup_buffers(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + /* setup buffing BIO */ + if (!ssl_init_wbio_buffer(s, 0)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + /* don't push the buffering BIO quite yet */ + + s->state = SSL3_ST_CW_CLNT_HELLO_A; + s->ctx->stats.sess_connect++; + s->init_num = 0; + /* mark client_random uninitialized */ + memset(s->s3->client_random, 0, sizeof(s->s3->client_random)); + s->d1->send_cookie = 0; + s->hit = 0; + s->d1->change_cipher_spec_ok = 0; + /* + * Should have been reset by ssl3_get_finished, too. + */ + s->s3->change_cipher_spec = 0; + break; + +#ifndef OPENSSL_NO_SCTP + case DTLS1_SCTP_ST_CR_READ_SOCK: + + if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { + s->s3->in_read_app_data = 2; + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + ret = -1; + goto end; + } + + s->state = s->s3->tmp.next_state; + break; + + case DTLS1_SCTP_ST_CW_WRITE_SOCK: + /* read app data until dry event */ + + ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); + if (ret < 0) + goto end; + + if (ret == 0) { + s->s3->in_read_app_data = 2; + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + ret = -1; + goto end; + } + + s->state = s->d1->next_state; + break; +#endif + + case SSL3_ST_CW_CLNT_HELLO_A: + s->shutdown = 0; + + /* every DTLS ClientHello resets Finished MAC */ + ssl3_init_finished_mac(s); + + case SSL3_ST_CW_CLNT_HELLO_B: + dtls1_start_timer(s); + ret = dtls1_client_hello(s); + if (ret <= 0) + goto end; + + if (s->d1->send_cookie) { + s->state = SSL3_ST_CW_FLUSH; + s->s3->tmp.next_state = SSL3_ST_CR_SRVR_HELLO_A; + } else + s->state = SSL3_ST_CR_SRVR_HELLO_A; + + s->init_num = 0; + +#ifndef OPENSSL_NO_SCTP + /* Disable buffering for SCTP */ + if (!BIO_dgram_is_sctp(SSL_get_wbio(s))) { +#endif + /* + * turn on buffering for the next lot of output + */ + if (s->bbio != s->wbio) + s->wbio = BIO_push(s->bbio, s->wbio); +#ifndef OPENSSL_NO_SCTP + } +#endif + + break; + + case SSL3_ST_CR_SRVR_HELLO_A: + case SSL3_ST_CR_SRVR_HELLO_B: + ret = ssl3_get_server_hello(s); + if (ret <= 0) + goto end; + else { + if (s->hit) { +#ifndef OPENSSL_NO_SCTP + /* + * Add new shared key for SCTP-Auth, will be ignored if + * no SCTP used. + */ + snprintf((char *)labelbuffer, + sizeof(DTLS1_SCTP_AUTH_LABEL), + DTLS1_SCTP_AUTH_LABEL); + + if (SSL_export_keying_material(s, sctpauthkey, + sizeof(sctpauthkey), + labelbuffer, + sizeof(labelbuffer), NULL, 0, + 0) <= 0) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + BIO_ctrl(SSL_get_wbio(s), + BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, + sizeof(sctpauthkey), sctpauthkey); +#endif + + s->state = SSL3_ST_CR_FINISHED_A; + if (s->tlsext_ticket_expected) { + /* receive renewed session ticket */ + s->state = SSL3_ST_CR_SESSION_TICKET_A; + } + } else + s->state = DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A; + } + s->init_num = 0; + break; + + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: + + ret = dtls1_get_hello_verify(s); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + if (s->d1->send_cookie) /* start again, with a cookie */ + s->state = SSL3_ST_CW_CLNT_HELLO_A; + else + s->state = SSL3_ST_CR_CERT_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_CERT_A: + case SSL3_ST_CR_CERT_B: + /* Check if it is anon DH or PSK */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && + !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + ret = ssl3_get_server_certificate(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_status_expected) + s->state = SSL3_ST_CR_CERT_STATUS_A; + else + s->state = SSL3_ST_CR_KEY_EXCH_A; + } else { + skip = 1; + s->state = SSL3_ST_CR_KEY_EXCH_A; + } +#else + } else + skip = 1; + + s->state = SSL3_ST_CR_KEY_EXCH_A; +#endif + s->init_num = 0; + break; + + case SSL3_ST_CR_KEY_EXCH_A: + case SSL3_ST_CR_KEY_EXCH_B: + ret = ssl3_get_key_exchange(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_CERT_REQ_A; + s->init_num = 0; + + /* + * at this point we check that we have the required stuff from + * the server + */ + if (!ssl3_check_cert_and_algorithm(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + break; + + case SSL3_ST_CR_CERT_REQ_A: + case SSL3_ST_CR_CERT_REQ_B: + ret = ssl3_get_certificate_request(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_SRVR_DONE_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_SRVR_DONE_A: + case SSL3_ST_CR_SRVR_DONE_B: + ret = ssl3_get_server_done(s); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + if (s->s3->tmp.cert_req) + s->s3->tmp.next_state = SSL3_ST_CW_CERT_A; + else + s->s3->tmp.next_state = SSL3_ST_CW_KEY_EXCH_A; + s->init_num = 0; + +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && + state == SSL_ST_RENEGOTIATE) + s->state = DTLS1_SCTP_ST_CR_READ_SOCK; + else +#endif + s->state = s->s3->tmp.next_state; + break; + + case SSL3_ST_CW_CERT_A: + case SSL3_ST_CW_CERT_B: + case SSL3_ST_CW_CERT_C: + case SSL3_ST_CW_CERT_D: + dtls1_start_timer(s); + ret = dtls1_send_client_certificate(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_KEY_EXCH_A; + s->init_num = 0; + break; + + case SSL3_ST_CW_KEY_EXCH_A: + case SSL3_ST_CW_KEY_EXCH_B: + dtls1_start_timer(s); + ret = dtls1_send_client_key_exchange(s); + if (ret <= 0) + goto end; + +#ifndef OPENSSL_NO_SCTP + /* + * Add new shared key for SCTP-Auth, will be ignored if no SCTP + * used. + */ + snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), + DTLS1_SCTP_AUTH_LABEL); + + if (SSL_export_keying_material(s, sctpauthkey, + sizeof(sctpauthkey), labelbuffer, + sizeof(labelbuffer), NULL, 0, 0) <= 0) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, + sizeof(sctpauthkey), sctpauthkey); +#endif + + /* + * EAY EAY EAY need to check for DH fix cert sent back + */ + /* + * For TLS, cert_req is set to 2, so a cert chain of nothing is + * sent, but no verify packet is sent + */ + if (s->s3->tmp.cert_req == 1) { + s->state = SSL3_ST_CW_CERT_VRFY_A; + } else { +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = SSL3_ST_CW_CHANGE_A; + s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; + } else +#endif + s->state = SSL3_ST_CW_CHANGE_A; + } + + s->init_num = 0; + break; + + case SSL3_ST_CW_CERT_VRFY_A: + case SSL3_ST_CW_CERT_VRFY_B: + dtls1_start_timer(s); + ret = dtls1_send_client_verify(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = SSL3_ST_CW_CHANGE_A; + s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; + } else +#endif + s->state = SSL3_ST_CW_CHANGE_A; + s->init_num = 0; + break; + + case SSL3_ST_CW_CHANGE_A: + case SSL3_ST_CW_CHANGE_B: + if (!s->hit) + dtls1_start_timer(s); + ret = dtls1_send_change_cipher_spec(s, + SSL3_ST_CW_CHANGE_A, + SSL3_ST_CW_CHANGE_B); + if (ret <= 0) + goto end; + + s->state = SSL3_ST_CW_FINISHED_A; + s->init_num = 0; + + s->session->cipher = s->s3->tmp.new_cipher; +#ifdef OPENSSL_NO_COMP + s->session->compress_meth = 0; +#else + if (s->s3->tmp.new_compression == NULL) + s->session->compress_meth = 0; + else + s->session->compress_meth = s->s3->tmp.new_compression->id; +#endif + if (!s->method->ssl3_enc->setup_key_block(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + if (!s->method->ssl3_enc->change_cipher_state(s, + SSL3_CHANGE_CIPHER_CLIENT_WRITE)) + { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } +#ifndef OPENSSL_NO_SCTP + if (s->hit) { + /* + * Change to new shared key of SCTP-Auth, will be ignored if + * no SCTP used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, + 0, NULL); + } +#endif + + dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); + break; + + case SSL3_ST_CW_FINISHED_A: + case SSL3_ST_CW_FINISHED_B: + if (!s->hit) + dtls1_start_timer(s); + ret = dtls1_send_finished(s, + SSL3_ST_CW_FINISHED_A, + SSL3_ST_CW_FINISHED_B, + s->method-> + ssl3_enc->client_finished_label, + s->method-> + ssl3_enc->client_finished_label_len); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_FLUSH; + + /* clear flags */ + s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; + if (s->hit) { + s->s3->tmp.next_state = SSL_ST_OK; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = s->s3->tmp.next_state; + s->s3->tmp.next_state = DTLS1_SCTP_ST_CW_WRITE_SOCK; + } +#endif + if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) { + s->state = SSL_ST_OK; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = SSL_ST_OK; + s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; + } +#endif + s->s3->flags |= SSL3_FLAGS_POP_BUFFER; + s->s3->delay_buf_pop_ret = 0; + } + } else { +#ifndef OPENSSL_NO_SCTP + /* + * Change to new shared key of SCTP-Auth, will be ignored if + * no SCTP used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, + 0, NULL); +#endif + +#ifndef OPENSSL_NO_TLSEXT + /* + * Allow NewSessionTicket if ticket expected + */ + if (s->tlsext_ticket_expected) + s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A; + else +#endif + + s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A; + } + s->init_num = 0; + break; + +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_CR_SESSION_TICKET_A: + case SSL3_ST_CR_SESSION_TICKET_B: + ret = ssl3_get_new_session_ticket(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_FINISHED_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_CERT_STATUS_A: + case SSL3_ST_CR_CERT_STATUS_B: + ret = ssl3_get_cert_status(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_KEY_EXCH_A; + s->init_num = 0; + break; +#endif + + case SSL3_ST_CR_FINISHED_A: + case SSL3_ST_CR_FINISHED_B: + s->d1->change_cipher_spec_ok = 1; + ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, + SSL3_ST_CR_FINISHED_B); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + + if (s->hit) + s->state = SSL3_ST_CW_CHANGE_A; + else + s->state = SSL_ST_OK; + +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && + state == SSL_ST_RENEGOTIATE) { + s->d1->next_state = s->state; + s->state = DTLS1_SCTP_ST_CW_WRITE_SOCK; + } +#endif + + s->init_num = 0; + break; + + case SSL3_ST_CW_FLUSH: + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + /* + * If the write error was fatal, stop trying + */ + if (!BIO_should_retry(s->wbio)) { + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + } + + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + break; + + case SSL_ST_OK: + /* clean a few things up */ + ssl3_cleanup_key_block(s); + +#if 0 + if (s->init_buf != NULL) { + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + } +#endif + + /* + * If we are not 'joining' the last two packets, remove the + * buffering now + */ + if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) + ssl_free_wbio_buffer(s); + /* else do it later in ssl3_write */ + + s->init_num = 0; + s->renegotiate = 0; + s->new_session = 0; + + ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); + if (s->hit) + s->ctx->stats.sess_hit++; + + ret = 1; + /* s->server=0; */ + s->handshake_func = dtls1_connect; + s->ctx->stats.sess_connect_good++; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + + /* done with handshaking */ + s->d1->handshake_read_seq = 0; + s->d1->next_handshake_write_seq = 0; + goto end; + /* break; */ + + case SSL_ST_ERR: + default: + SSLerr(SSL_F_DTLS1_CONNECT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + /* did we do anything */ + if (!s->s3->tmp.reuse_message && !skip) { + if (s->debug) { + if ((ret = BIO_flush(s->wbio)) <= 0) + goto end; + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_CONNECT_LOOP, 1); + s->state = new_state; + } + } + skip = 0; + } + end: + s->in_handshake--; + +#ifndef OPENSSL_NO_SCTP + /* + * Notify SCTP BIO socket to leave handshake mode and allow stream + * identifier other than 0. Will be ignored if no SCTP is used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, + s->in_handshake, NULL); +#endif + + if (buf != NULL) + BUF_MEM_free(buf); + if (cb != NULL) + cb(s, SSL_CB_CONNECT_EXIT, ret); + return (ret); +} + +int dtls1_client_hello(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; + unsigned int i, j; + unsigned long l; + SSL_COMP *comp; + + buf = (unsigned char *)s->init_buf->data; + if (s->state == SSL3_ST_CW_CLNT_HELLO_A) { + SSL_SESSION *sess = s->session; + if ((s->session == NULL) || (s->session->ssl_version != s->version) || +#ifdef OPENSSL_NO_TLSEXT + !sess->session_id_length || +#else + (!sess->session_id_length && !sess->tlsext_tick) || +#endif + (s->session->not_resumable)) { + if (!ssl_get_new_session(s, 0)) + goto err; + } + /* else use the pre-loaded session */ + + p = s->s3->client_random; + + /* + * if client_random is initialized, reuse it, we are required to use + * same upon reply to HelloVerify + */ + for (i = 0; p[i] == '\0' && i < sizeof(s->s3->client_random); i++) ; + if (i == sizeof(s->s3->client_random)) + ssl_fill_hello_random(s, 0, p, sizeof(s->s3->client_random)); + + /* Do the message type and length last */ + d = p = &(buf[DTLS1_HM_HEADER_LENGTH]); + + *(p++) = s->version >> 8; + *(p++) = s->version & 0xff; + s->client_version = s->version; + + /* Random stuff */ + memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /* Session ID */ + if (s->new_session) + i = 0; + else + i = s->session->session_id_length; + *(p++) = i; + if (i != 0) { + if (i > sizeof s->session->session_id) { + SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + goto err; + } + memcpy(p, s->session->session_id, i); + p += i; + } + + /* cookie stuff */ + if (s->d1->cookie_len > sizeof(s->d1->cookie)) { + SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + goto err; + } + *(p++) = s->d1->cookie_len; + memcpy(p, s->d1->cookie, s->d1->cookie_len); + p += s->d1->cookie_len; + + /* Ciphers supported */ + i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), 0); + if (i == 0) { + SSLerr(SSL_F_DTLS1_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); + goto err; + } + s2n(i, p); + p += i; + + /* COMPRESSION */ + if (s->ctx->comp_methods == NULL) + j = 0; + else + j = sk_SSL_COMP_num(s->ctx->comp_methods); + *(p++) = 1 + j; + for (i = 0; i < j; i++) { + comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); + *(p++) = comp->id; + } + *(p++) = 0; /* Add the NULL method */ + +#ifndef OPENSSL_NO_TLSEXT + /* TLS extensions */ + if (ssl_prepare_clienthello_tlsext(s) <= 0) { + SSLerr(SSL_F_DTLS1_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } + if ((p = + ssl_add_clienthello_tlsext(s, p, + buf + SSL3_RT_MAX_PLAIN_LENGTH)) == + NULL) { + SSLerr(SSL_F_DTLS1_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + goto err; + } +#endif + + l = (p - d); + d = buf; + + d = dtls1_set_message_header(s, d, SSL3_MT_CLIENT_HELLO, l, 0, l); + + s->state = SSL3_ST_CW_CLNT_HELLO_B; + /* number of bytes to write */ + s->init_num = p - buf; + s->init_off = 0; + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); + } + + /* SSL3_ST_CW_CLNT_HELLO_B */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); + err: + return (-1); +} + +static int dtls1_get_hello_verify(SSL *s) +{ + int n, al, ok = 0; + unsigned char *data; + unsigned int cookie_len; + + n = s->method->ssl_get_message(s, + DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A, + DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B, + -1, s->max_cert_list, &ok); + + if (!ok) + return ((int)n); + + if (s->s3->tmp.message_type != DTLS1_MT_HELLO_VERIFY_REQUEST) { + s->d1->send_cookie = 0; + s->s3->tmp.reuse_message = 1; + return (1); + } + + data = (unsigned char *)s->init_msg; + + if ((data[0] != (s->version >> 8)) || (data[1] != (s->version & 0xff))) { + SSLerr(SSL_F_DTLS1_GET_HELLO_VERIFY, SSL_R_WRONG_SSL_VERSION); + s->version = (s->version & 0xff00) | data[1]; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + data += 2; + + cookie_len = *(data++); + if (cookie_len > sizeof(s->d1->cookie)) { + al = SSL_AD_ILLEGAL_PARAMETER; + goto f_err; + } + + memcpy(s->d1->cookie, data, cookie_len); + s->d1->cookie_len = cookie_len; + + s->d1->send_cookie = 1; + return 1; + + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->state = SSL_ST_ERR; + return -1; +} + +int dtls1_send_client_key_exchange(SSL *s) +{ + unsigned char *p, *d; + int n; + unsigned long alg_k; +#ifndef OPENSSL_NO_RSA + unsigned char *q; + EVP_PKEY *pkey = NULL; +#endif +#ifndef OPENSSL_NO_KRB5 + KSSL_ERR kssl_err; +#endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_ECDH + EC_KEY *clnt_ecdh = NULL; + const EC_POINT *srvr_ecpoint = NULL; + EVP_PKEY *srvr_pub_pkey = NULL; + unsigned char *encodedPoint = NULL; + int encoded_pt_len = 0; + BN_CTX *bn_ctx = NULL; +#endif + + if (s->state == SSL3_ST_CW_KEY_EXCH_A) { + d = (unsigned char *)s->init_buf->data; + p = &(d[DTLS1_HM_HEADER_LENGTH]); + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + /* Fool emacs indentation */ + if (0) { + } +#ifndef OPENSSL_NO_RSA + else if (alg_k & SSL_kRSA) { + RSA *rsa; + unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; + + if (s->session->sess_cert == NULL) { + /* + * We should always have a server certificate with SSL_kRSA. + */ + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (s->session->sess_cert->peer_rsa_tmp != NULL) + rsa = s->session->sess_cert->peer_rsa_tmp; + else { + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC]. + x509); + if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA) + || (pkey->pkey.rsa == NULL)) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + rsa = pkey->pkey.rsa; + EVP_PKEY_free(pkey); + } + + tmp_buf[0] = s->client_version >> 8; + tmp_buf[1] = s->client_version & 0xff; + if (RAND_bytes(&(tmp_buf[2]), sizeof tmp_buf - 2) <= 0) + goto err; + + s->session->master_key_length = sizeof tmp_buf; + + q = p; + /* Fix buf for TLS and [incidentally] DTLS */ + if (s->version > SSL3_VERSION) + p += 2; + n = RSA_public_encrypt(sizeof tmp_buf, + tmp_buf, p, rsa, RSA_PKCS1_PADDING); +# ifdef PKCS1_CHECK + if (s->options & SSL_OP_PKCS1_CHECK_1) + p[1]++; + if (s->options & SSL_OP_PKCS1_CHECK_2) + tmp_buf[0] = 0x70; +# endif + if (n <= 0) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_BAD_RSA_ENCRYPT); + goto err; + } + + /* Fix buf for TLS and [incidentally] DTLS */ + if (s->version > SSL3_VERSION) { + s2n(n, q); + n += 2; + } + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + tmp_buf, + sizeof tmp_buf); + OPENSSL_cleanse(tmp_buf, sizeof tmp_buf); + } +#endif +#ifndef OPENSSL_NO_KRB5 + else if (alg_k & SSL_kKRB5) { + krb5_error_code krb5rc; + KSSL_CTX *kssl_ctx = s->kssl_ctx; + /* krb5_data krb5_ap_req; */ + krb5_data *enc_ticket; + krb5_data authenticator, *authp = NULL; + EVP_CIPHER_CTX ciph_ctx; + const EVP_CIPHER *enc = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; + unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_IV_LENGTH]; + int padl, outl = sizeof(epms); + + EVP_CIPHER_CTX_init(&ciph_ctx); + +# ifdef KSSL_DEBUG + printf("ssl3_send_client_key_exchange(%lx & %lx)\n", + alg_k, SSL_kKRB5); +# endif /* KSSL_DEBUG */ + + authp = NULL; +# ifdef KRB5SENDAUTH + if (KRB5SENDAUTH) + authp = &authenticator; +# endif /* KRB5SENDAUTH */ + + krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp, &kssl_err); + enc = kssl_map_enc(kssl_ctx->enctype); + if (enc == NULL) + goto err; +# ifdef KSSL_DEBUG + { + printf("kssl_cget_tkt rtn %d\n", krb5rc); + if (krb5rc && kssl_err.text) + printf("kssl_cget_tkt kssl_err=%s\n", kssl_err.text); + } +# endif /* KSSL_DEBUG */ + + if (krb5rc) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, kssl_err.reason); + goto err; + } + + /*- + * 20010406 VRS - Earlier versions used KRB5 AP_REQ + ** in place of RFC 2712 KerberosWrapper, as in: + ** + ** Send ticket (copy to *p, set n = length) + ** n = krb5_ap_req.length; + ** memcpy(p, krb5_ap_req.data, krb5_ap_req.length); + ** if (krb5_ap_req.data) + ** kssl_krb5_free_data_contents(NULL,&krb5_ap_req); + ** + ** Now using real RFC 2712 KerberosWrapper + ** (Thanks to Simon Wilkinson ) + ** Note: 2712 "opaque" types are here replaced + ** with a 2-byte length followed by the value. + ** Example: + ** KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms + ** Where "xx xx" = length bytes. Shown here with + ** optional authenticator omitted. + */ + + /* KerberosWrapper.Ticket */ + s2n(enc_ticket->length, p); + memcpy(p, enc_ticket->data, enc_ticket->length); + p += enc_ticket->length; + n = enc_ticket->length + 2; + + /* KerberosWrapper.Authenticator */ + if (authp && authp->length) { + s2n(authp->length, p); + memcpy(p, authp->data, authp->length); + p += authp->length; + n += authp->length + 2; + + free(authp->data); + authp->data = NULL; + authp->length = 0; + } else { + s2n(0, p); /* null authenticator length */ + n += 2; + } + + if (RAND_bytes(tmp_buf, sizeof tmp_buf) <= 0) + goto err; + + /*- + * 20010420 VRS. Tried it this way; failed. + * EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL); + * EVP_CIPHER_CTX_set_key_length(&ciph_ctx, + * kssl_ctx->length); + * EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv); + */ + + memset(iv, 0, sizeof iv); /* per RFC 1510 */ + EVP_EncryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv); + EVP_EncryptUpdate(&ciph_ctx, epms, &outl, tmp_buf, + sizeof tmp_buf); + EVP_EncryptFinal_ex(&ciph_ctx, &(epms[outl]), &padl); + outl += padl; + if (outl > (int)sizeof epms) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + /* KerberosWrapper.EncryptedPreMasterSecret */ + s2n(outl, p); + memcpy(p, epms, outl); + p += outl; + n += outl + 2; + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + tmp_buf, + sizeof tmp_buf); + + OPENSSL_cleanse(tmp_buf, sizeof tmp_buf); + OPENSSL_cleanse(epms, outl); + } +#endif +#ifndef OPENSSL_NO_DH + else if (alg_k & (SSL_kEDH | SSL_kDHr | SSL_kDHd)) { + DH *dh_srvr, *dh_clnt; + + if (s->session->sess_cert == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_UNEXPECTED_MESSAGE); + goto err; + } + + if (s->session->sess_cert->peer_dh_tmp != NULL) + dh_srvr = s->session->sess_cert->peer_dh_tmp; + else { + /* we get them from the cert */ + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); + goto err; + } + + /* generate a new random key */ + if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + if (!DH_generate_key(dh_clnt)) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + + /* + * use the 'p' output buffer for the DH key, but make sure to + * clear it out afterwards + */ + + n = DH_compute_key(p, dh_srvr->pub_key, dh_clnt); + + if (n <= 0) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + + /* generate master key from the result */ + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + p, n); + /* clean up */ + memset(p, 0, n); + + /* send off the data */ + n = BN_num_bytes(dh_clnt->pub_key); + s2n(n, p); + BN_bn2bin(dh_clnt->pub_key, p); + n += 2; + + DH_free(dh_clnt); + + /* perhaps clean things up a bit EAY EAY EAY EAY */ + } +#endif +#ifndef OPENSSL_NO_ECDH + else if (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) { + const EC_GROUP *srvr_group = NULL; + EC_KEY *tkey; + int ecdh_clnt_cert = 0; + int field_size = 0; + + if (s->session->sess_cert == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_UNEXPECTED_MESSAGE); + goto err; + } + + /* + * Did we send out the client's ECDH share for use in premaster + * computation as part of client certificate? If so, set + * ecdh_clnt_cert to 1. + */ + if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->cert != NULL)) { + /* + * XXX: For now, we do not support client authentication + * using ECDH certificates. To add such support, one needs to + * add code that checks for appropriate conditions and sets + * ecdh_clnt_cert to 1. For example, the cert have an ECC key + * on the same curve as the server's and the key should be + * authorized for key agreement. One also needs to add code + * in ssl3_connect to skip sending the certificate verify + * message. if ((s->cert->key->privatekey != NULL) && + * (s->cert->key->privatekey->type == EVP_PKEY_EC) && ...) + * ecdh_clnt_cert = 1; + */ + } + + if (s->session->sess_cert->peer_ecdh_tmp != NULL) { + tkey = s->session->sess_cert->peer_ecdh_tmp; + } else { + /* Get the Server Public Key from Cert */ + srvr_pub_pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); + if ((srvr_pub_pkey == NULL) + || (srvr_pub_pkey->type != EVP_PKEY_EC) + || (srvr_pub_pkey->pkey.ec == NULL)) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + tkey = srvr_pub_pkey->pkey.ec; + } + + srvr_group = EC_KEY_get0_group(tkey); + srvr_ecpoint = EC_KEY_get0_public_key(tkey); + + if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if ((clnt_ecdh = EC_KEY_new()) == NULL) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + if (ecdh_clnt_cert) { + /* + * Reuse key info from our certificate We only need our + * private key to perform the ECDH computation. + */ + const BIGNUM *priv_key; + tkey = s->cert->key->privatekey->pkey.ec; + priv_key = EC_KEY_get0_private_key(tkey); + if (priv_key == NULL) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_KEY_set_private_key(clnt_ecdh, priv_key)) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_EC_LIB); + goto err; + } + } else { + /* Generate a new ECDH key pair */ + if (!(EC_KEY_generate_key(clnt_ecdh))) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + } + + /* + * use the 'p' output buffer for the ECDH key, but make sure to + * clear it out afterwards + */ + + field_size = EC_GROUP_get_degree(srvr_group); + if (field_size <= 0) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + n = ECDH_compute_key(p, (field_size + 7) / 8, srvr_ecpoint, + clnt_ecdh, NULL); + if (n <= 0) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + /* generate master key from the result */ + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + p, n); + + memset(p, 0, n); /* clean up */ + + if (ecdh_clnt_cert) { + /* Send empty client key exch message */ + n = 0; + } else { + /* + * First check the size of encoding and allocate memory + * accordingly. + */ + encoded_pt_len = + EC_POINT_point2oct(srvr_group, + EC_KEY_get0_public_key(clnt_ecdh), + POINT_CONVERSION_UNCOMPRESSED, + NULL, 0, NULL); + + encodedPoint = (unsigned char *) + OPENSSL_malloc(encoded_pt_len * sizeof(unsigned char)); + bn_ctx = BN_CTX_new(); + if ((encodedPoint == NULL) || (bn_ctx == NULL)) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Encode the public key */ + n = EC_POINT_point2oct(srvr_group, + EC_KEY_get0_public_key(clnt_ecdh), + POINT_CONVERSION_UNCOMPRESSED, + encodedPoint, encoded_pt_len, bn_ctx); + + *p = n; /* length of encoded point */ + /* Encoded point will be copied here */ + p += 1; + /* copy the point */ + memcpy((unsigned char *)p, encodedPoint, n); + /* increment n to account for length field */ + n += 1; + } + + /* Free allocated memory */ + BN_CTX_free(bn_ctx); + if (encodedPoint != NULL) + OPENSSL_free(encodedPoint); + if (clnt_ecdh != NULL) + EC_KEY_free(clnt_ecdh); + EVP_PKEY_free(srvr_pub_pkey); + } +#endif /* !OPENSSL_NO_ECDH */ + +#ifndef OPENSSL_NO_PSK + else if (alg_k & SSL_kPSK) { + char identity[PSK_MAX_IDENTITY_LEN]; + unsigned char *t = NULL; + unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4]; + unsigned int pre_ms_len = 0, psk_len = 0; + int psk_err = 1; + + n = 0; + if (s->psk_client_callback == NULL) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_NO_CLIENT_CB); + goto err; + } + + psk_len = s->psk_client_callback(s, s->ctx->psk_identity_hint, + identity, PSK_MAX_IDENTITY_LEN, + psk_or_pre_ms, + sizeof(psk_or_pre_ms)); + if (psk_len > PSK_MAX_PSK_LEN) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto psk_err; + } else if (psk_len == 0) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_IDENTITY_NOT_FOUND); + goto psk_err; + } + + /* create PSK pre_master_secret */ + pre_ms_len = 2 + psk_len + 2 + psk_len; + t = psk_or_pre_ms; + memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len); + s2n(psk_len, t); + memset(t, 0, psk_len); + t += psk_len; + s2n(psk_len, t); + + if (s->session->psk_identity_hint != NULL) + OPENSSL_free(s->session->psk_identity_hint); + s->session->psk_identity_hint = + BUF_strdup(s->ctx->psk_identity_hint); + if (s->ctx->psk_identity_hint != NULL + && s->session->psk_identity_hint == NULL) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + if (s->session->psk_identity != NULL) + OPENSSL_free(s->session->psk_identity); + s->session->psk_identity = BUF_strdup(identity); + if (s->session->psk_identity == NULL) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + psk_or_pre_ms, + pre_ms_len); + n = strlen(identity); + s2n(n, p); + memcpy(p, identity, n); + n += 2; + psk_err = 0; + psk_err: + OPENSSL_cleanse(identity, PSK_MAX_IDENTITY_LEN); + OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); + if (psk_err != 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + goto err; + } + } +#endif + else { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + d = dtls1_set_message_header(s, d, + SSL3_MT_CLIENT_KEY_EXCHANGE, n, 0, n); + /*- + *(d++)=SSL3_MT_CLIENT_KEY_EXCHANGE; + l2n3(n,d); + l2n(s->d1->handshake_write_seq,d); + s->d1->handshake_write_seq++; + */ + + s->state = SSL3_ST_CW_KEY_EXCH_B; + /* number of bytes to write */ + s->init_num = n + DTLS1_HM_HEADER_LENGTH; + s->init_off = 0; + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); + } + + /* SSL3_ST_CW_KEY_EXCH_B */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); + err: +#ifndef OPENSSL_NO_ECDH + BN_CTX_free(bn_ctx); + if (encodedPoint != NULL) + OPENSSL_free(encodedPoint); + if (clnt_ecdh != NULL) + EC_KEY_free(clnt_ecdh); + EVP_PKEY_free(srvr_pub_pkey); +#endif + return (-1); +} + +int dtls1_send_client_verify(SSL *s) +{ + unsigned char *p, *d; + unsigned char data[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; + EVP_PKEY *pkey; +#ifndef OPENSSL_NO_RSA + unsigned u = 0; +#endif + unsigned long n; +#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_ECDSA) + int j; +#endif + + if (s->state == SSL3_ST_CW_CERT_VRFY_A) { + d = (unsigned char *)s->init_buf->data; + p = &(d[DTLS1_HM_HEADER_LENGTH]); + pkey = s->cert->key->privatekey; + + s->method->ssl3_enc->cert_verify_mac(s, + NID_sha1, + &(data[MD5_DIGEST_LENGTH])); + +#ifndef OPENSSL_NO_RSA + if (pkey->type == EVP_PKEY_RSA) { + s->method->ssl3_enc->cert_verify_mac(s, NID_md5, &(data[0])); + if (RSA_sign(NID_md5_sha1, data, + MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, + &(p[2]), &u, pkey->pkey.rsa) <= 0) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY, ERR_R_RSA_LIB); + goto err; + } + s2n(u, p); + n = u + 2; + } else +#endif +#ifndef OPENSSL_NO_DSA + if (pkey->type == EVP_PKEY_DSA) { + if (!DSA_sign(pkey->save_type, + &(data[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, &(p[2]), + (unsigned int *)&j, pkey->pkey.dsa)) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY, ERR_R_DSA_LIB); + goto err; + } + s2n(j, p); + n = j + 2; + } else +#endif +#ifndef OPENSSL_NO_ECDSA + if (pkey->type == EVP_PKEY_EC) { + if (!ECDSA_sign(pkey->save_type, + &(data[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, &(p[2]), + (unsigned int *)&j, pkey->pkey.ec)) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY, ERR_R_ECDSA_LIB); + goto err; + } + s2n(j, p); + n = j + 2; + } else +#endif + { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + + d = dtls1_set_message_header(s, d, + SSL3_MT_CERTIFICATE_VERIFY, n, 0, n); + + s->init_num = (int)n + DTLS1_HM_HEADER_LENGTH; + s->init_off = 0; + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); + + s->state = SSL3_ST_CW_CERT_VRFY_B; + } + + /* s->state = SSL3_ST_CW_CERT_VRFY_B */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); + err: + return (-1); +} + +int dtls1_send_client_certificate(SSL *s) +{ + X509 *x509 = NULL; + EVP_PKEY *pkey = NULL; + int i; + unsigned long l; + + if (s->state == SSL3_ST_CW_CERT_A) { + if ((s->cert == NULL) || + (s->cert->key->x509 == NULL) || + (s->cert->key->privatekey == NULL)) + s->state = SSL3_ST_CW_CERT_B; + else + s->state = SSL3_ST_CW_CERT_C; + } + + /* We need to get a client cert */ + if (s->state == SSL3_ST_CW_CERT_B) { + /* + * If we get an error, we need to ssl->rwstate=SSL_X509_LOOKUP; + * return(-1); We then get retied later + */ + i = 0; + i = ssl_do_client_cert_cb(s, &x509, &pkey); + if (i < 0) { + s->rwstate = SSL_X509_LOOKUP; + return (-1); + } + s->rwstate = SSL_NOTHING; + if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { + s->state = SSL3_ST_CW_CERT_B; + if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey)) + i = 0; + } else if (i == 1) { + i = 0; + SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE, + SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); + } + + if (x509 != NULL) + X509_free(x509); + if (pkey != NULL) + EVP_PKEY_free(pkey); + if (i == 0) { + if (s->version == SSL3_VERSION) { + s->s3->tmp.cert_req = 0; + ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE); + return (1); + } else { + s->s3->tmp.cert_req = 2; + } + } + + /* Ok, we have a cert */ + s->state = SSL3_ST_CW_CERT_C; + } + + if (s->state == SSL3_ST_CW_CERT_C) { + s->state = SSL3_ST_CW_CERT_D; + l = dtls1_output_cert_chain(s, + (s->s3->tmp.cert_req == + 2) ? NULL : s->cert->key->x509); + if (!l) { + SSLerr(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return 0; + } + s->init_num = (int)l; + s->init_off = 0; + + /* set header called by dtls1_output_cert_chain() */ + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); + } + /* SSL3_ST_CW_CERT_D */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); +} diff --git a/libs/openssl/ssl/d1_enc.c b/libs/openssl/ssl/d1_enc.c new file mode 100644 index 00000000..e876364f --- /dev/null +++ b/libs/openssl/ssl/d1_enc.c @@ -0,0 +1,251 @@ +/* ssl/d1_enc.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "ssl_locl.h" +#ifndef OPENSSL_NO_COMP +# include +#endif +#include +#include +#include +#include +#ifdef KSSL_DEBUG +# include +#endif + +/*- + * dtls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. + * + * Returns: + * 0: (in non-constant time) if the record is publically invalid (i.e. too + * short etc). + * 1: if the record's padding is valid / the encryption was successful. + * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, + * an internal error occured. + */ +int dtls1_enc(SSL *s, int send) +{ + SSL3_RECORD *rec; + EVP_CIPHER_CTX *ds; + unsigned long l; + int bs, i, j, k, mac_size = 0; + const EVP_CIPHER *enc; + + if (send) { + if (EVP_MD_CTX_md(s->write_hash)) { + mac_size = EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + return -1; + } + ds = s->enc_write_ctx; + rec = &(s->s3->wrec); + if (s->enc_write_ctx == NULL) + enc = NULL; + else { + enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); + if (rec->data != rec->input) + /* we can't write into the input stream */ + fprintf(stderr, "%s:%d: rec->data != rec->input\n", + __FILE__, __LINE__); + else if (EVP_CIPHER_block_size(ds->cipher) > 1) { + if (RAND_bytes(rec->input, EVP_CIPHER_block_size(ds->cipher)) + <= 0) + return -1; + } + } + } else { + if (EVP_MD_CTX_md(s->read_hash)) { + mac_size = EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(mac_size >= 0); + } + ds = s->enc_read_ctx; + rec = &(s->s3->rrec); + if (s->enc_read_ctx == NULL) + enc = NULL; + else + enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); + } + +#ifdef KSSL_DEBUG + printf("dtls1_enc(%d)\n", send); +#endif /* KSSL_DEBUG */ + + if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { + memmove(rec->data, rec->input, rec->length); + rec->input = rec->data; + } else { + l = rec->length; + bs = EVP_CIPHER_block_size(ds->cipher); + + if ((bs != 1) && send) { + i = bs - ((int)l % bs); + + /* Add weird padding of upto 256 bytes */ + + /* we need to add 'i' padding bytes of value j */ + j = i - 1; + if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) { + if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) + j++; + } + for (k = (int)l; k < (int)(l + i); k++) + rec->input[k] = j; + l += i; + rec->length += i; + } +#ifdef KSSL_DEBUG + { + unsigned long ui; + printf("EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", + ds, rec->data, rec->input, l); + printf + ("\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%d %d], %d iv_len\n", + ds->buf_len, ds->cipher->key_len, DES_KEY_SZ, + DES_SCHEDULE_SZ, ds->cipher->iv_len); + printf("\t\tIV: "); + for (i = 0; i < ds->cipher->iv_len; i++) + printf("%02X", ds->iv[i]); + printf("\n"); + printf("\trec->input="); + for (ui = 0; ui < l; ui++) + printf(" %02x", rec->input[ui]); + printf("\n"); + } +#endif /* KSSL_DEBUG */ + + if (!send) { + if (l == 0 || l % bs != 0) + return 0; + } + + if (EVP_Cipher(ds, rec->data, rec->input, l) < 1) + return -1; + +#ifdef KSSL_DEBUG + { + unsigned long i; + printf("\trec->data="); + for (i = 0; i < l; i++) + printf(" %02x", rec->data[i]); + printf("\n"); + } +#endif /* KSSL_DEBUG */ + + if ((bs != 1) && !send) + return tls1_cbc_remove_padding(s, rec, bs, mac_size); + } + return (1); +} diff --git a/libs/openssl/ssl/d1_lib.c b/libs/openssl/ssl/d1_lib.c new file mode 100644 index 00000000..011d7b7c --- /dev/null +++ b/libs/openssl/ssl/d1_lib.c @@ -0,0 +1,511 @@ +/* ssl/d1_lib.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#define USE_SOCKETS +#include +#include "ssl_locl.h" + +#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) +# include +#endif + +static void get_current_time(struct timeval *t); +const char dtls1_version_str[] = "DTLSv1" OPENSSL_VERSION_PTEXT; +int dtls1_listen(SSL *s, struct sockaddr *client); + +SSL3_ENC_METHOD DTLSv1_enc_data = { + dtls1_enc, + tls1_mac, + tls1_setup_key_block, + tls1_generate_master_secret, + tls1_change_cipher_state, + tls1_final_finish_mac, + TLS1_FINISH_MAC_LENGTH, + tls1_cert_verify_mac, + TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, + tls1_alert_code, + tls1_export_keying_material, +}; + +long dtls1_default_timeout(void) +{ + /* + * 2 hours, the 24 hours mentioned in the DTLSv1 spec is way too long for + * http, the cache would over fill + */ + return (60 * 60 * 2); +} + +int dtls1_new(SSL *s) +{ + DTLS1_STATE *d1; + + if (!ssl3_new(s)) + return (0); + if ((d1 = OPENSSL_malloc(sizeof *d1)) == NULL) + return (0); + memset(d1, 0, sizeof *d1); + + /* d1->handshake_epoch=0; */ + + d1->unprocessed_rcds.q = pqueue_new(); + d1->processed_rcds.q = pqueue_new(); + d1->buffered_messages = pqueue_new(); + d1->sent_messages = pqueue_new(); + d1->buffered_app_data.q = pqueue_new(); + + if (s->server) { + d1->cookie_len = sizeof(s->d1->cookie); + } + + d1->link_mtu = 0; + d1->mtu = 0; + + if (!d1->unprocessed_rcds.q || !d1->processed_rcds.q + || !d1->buffered_messages || !d1->sent_messages + || !d1->buffered_app_data.q) { + if (d1->unprocessed_rcds.q) + pqueue_free(d1->unprocessed_rcds.q); + if (d1->processed_rcds.q) + pqueue_free(d1->processed_rcds.q); + if (d1->buffered_messages) + pqueue_free(d1->buffered_messages); + if (d1->sent_messages) + pqueue_free(d1->sent_messages); + if (d1->buffered_app_data.q) + pqueue_free(d1->buffered_app_data.q); + OPENSSL_free(d1); + return (0); + } + + s->d1 = d1; + s->method->ssl_clear(s); + return (1); +} + +static void dtls1_clear_queues(SSL *s) +{ + pitem *item = NULL; + hm_fragment *frag = NULL; + DTLS1_RECORD_DATA *rdata; + + while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *)item->data; + if (rdata->rbuf.buf) { + OPENSSL_free(rdata->rbuf.buf); + } + OPENSSL_free(item->data); + pitem_free(item); + } + + while ((item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *)item->data; + if (rdata->rbuf.buf) { + OPENSSL_free(rdata->rbuf.buf); + } + OPENSSL_free(item->data); + pitem_free(item); + } + + while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { + frag = (hm_fragment *)item->data; + dtls1_hm_fragment_free(frag); + pitem_free(item); + } + + while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { + frag = (hm_fragment *)item->data; + dtls1_hm_fragment_free(frag); + pitem_free(item); + } + + while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { + rdata = (DTLS1_RECORD_DATA *)item->data; + if (rdata->rbuf.buf) { + OPENSSL_free(rdata->rbuf.buf); + } + OPENSSL_free(item->data); + pitem_free(item); + } +} + +void dtls1_free(SSL *s) +{ + ssl3_free(s); + + dtls1_clear_queues(s); + + pqueue_free(s->d1->unprocessed_rcds.q); + pqueue_free(s->d1->processed_rcds.q); + pqueue_free(s->d1->buffered_messages); + pqueue_free(s->d1->sent_messages); + pqueue_free(s->d1->buffered_app_data.q); + + OPENSSL_free(s->d1); + s->d1 = NULL; +} + +void dtls1_clear(SSL *s) +{ + pqueue unprocessed_rcds; + pqueue processed_rcds; + pqueue buffered_messages; + pqueue sent_messages; + pqueue buffered_app_data; + unsigned int mtu; + unsigned int link_mtu; + + if (s->d1) { + unprocessed_rcds = s->d1->unprocessed_rcds.q; + processed_rcds = s->d1->processed_rcds.q; + buffered_messages = s->d1->buffered_messages; + sent_messages = s->d1->sent_messages; + buffered_app_data = s->d1->buffered_app_data.q; + mtu = s->d1->mtu; + link_mtu = s->d1->link_mtu; + + dtls1_clear_queues(s); + + memset(s->d1, 0, sizeof(*(s->d1))); + + if (s->server) { + s->d1->cookie_len = sizeof(s->d1->cookie); + } + + if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) { + s->d1->mtu = mtu; + s->d1->link_mtu = link_mtu; + } + + s->d1->unprocessed_rcds.q = unprocessed_rcds; + s->d1->processed_rcds.q = processed_rcds; + s->d1->buffered_messages = buffered_messages; + s->d1->sent_messages = sent_messages; + s->d1->buffered_app_data.q = buffered_app_data; + } + + ssl3_clear(s); + if (s->options & SSL_OP_CISCO_ANYCONNECT) + s->version = DTLS1_BAD_VER; + else + s->version = DTLS1_VERSION; +} + +long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + int ret = 0; + + switch (cmd) { + case DTLS_CTRL_GET_TIMEOUT: + if (dtls1_get_timeout(s, (struct timeval *)parg) != NULL) { + ret = 1; + } + break; + case DTLS_CTRL_HANDLE_TIMEOUT: + ret = dtls1_handle_timeout(s); + break; + case DTLS_CTRL_LISTEN: + ret = dtls1_listen(s, parg); + break; + case SSL_CTRL_CHECK_PROTO_VERSION: + /* + * For library-internal use; checks that the current protocol is the + * highest enabled version (according to s->ctx->method, as version + * negotiation may have changed s->method). + */ +#if DTLS_MAX_VERSION != DTLS1_VERSION +# error Code needs update for DTLS_method() support beyond DTLS1_VERSION. +#endif + /* + * Just one protocol version is supported so far; fail closed if the + * version is not as expected. + */ + return s->version == DTLS_MAX_VERSION; + case DTLS_CTRL_SET_LINK_MTU: + if (larg < (long)dtls1_link_min_mtu()) + return 0; + s->d1->link_mtu = larg; + return 1; + case DTLS_CTRL_GET_LINK_MIN_MTU: + return (long)dtls1_link_min_mtu(); + case SSL_CTRL_SET_MTU: + /* + * We may not have a BIO set yet so can't call dtls1_min_mtu() + * We'll have to make do with dtls1_link_min_mtu() and max overhead + */ + if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD) + return 0; + s->d1->mtu = larg; + return larg; + default: + ret = ssl3_ctrl(s, cmd, larg, parg); + break; + } + return (ret); +} + +/* + * As it's impossible to use stream ciphers in "datagram" mode, this + * simple filter is designed to disengage them in DTLS. Unfortunately + * there is no universal way to identify stream SSL_CIPHER, so we have + * to explicitly list their SSL_* codes. Currently RC4 is the only one + * available, but if new ones emerge, they will have to be added... + */ +const SSL_CIPHER *dtls1_get_cipher(unsigned int u) +{ + const SSL_CIPHER *ciph = ssl3_get_cipher(u); + + if (ciph != NULL) { + if (ciph->algorithm_enc == SSL_RC4) + return NULL; + } + + return ciph; +} + +void dtls1_start_timer(SSL *s) +{ +#ifndef OPENSSL_NO_SCTP + /* Disable timer for SCTP */ + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); + return; + } +#endif + + /* If timer is not set, initialize duration with 1 second */ + if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { + s->d1->timeout_duration = 1; + } + + /* Set timeout to current time */ + get_current_time(&(s->d1->next_timeout)); + + /* Add duration to current time */ + s->d1->next_timeout.tv_sec += s->d1->timeout_duration; + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, + &(s->d1->next_timeout)); +} + +struct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft) +{ + struct timeval timenow; + + /* If no timeout is set, just return NULL */ + if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { + return NULL; + } + + /* Get current time */ + get_current_time(&timenow); + + /* If timer already expired, set remaining time to 0 */ + if (s->d1->next_timeout.tv_sec < timenow.tv_sec || + (s->d1->next_timeout.tv_sec == timenow.tv_sec && + s->d1->next_timeout.tv_usec <= timenow.tv_usec)) { + memset(timeleft, 0, sizeof(struct timeval)); + return timeleft; + } + + /* Calculate time left until timer expires */ + memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); + timeleft->tv_sec -= timenow.tv_sec; + timeleft->tv_usec -= timenow.tv_usec; + if (timeleft->tv_usec < 0) { + timeleft->tv_sec--; + timeleft->tv_usec += 1000000; + } + + /* + * If remaining time is less than 15 ms, set it to 0 to prevent issues + * because of small devergences with socket timeouts. + */ + if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) { + memset(timeleft, 0, sizeof(struct timeval)); + } + + return timeleft; +} + +int dtls1_is_timer_expired(SSL *s) +{ + struct timeval timeleft; + + /* Get time left until timeout, return false if no timer running */ + if (dtls1_get_timeout(s, &timeleft) == NULL) { + return 0; + } + + /* Return false if timer is not expired yet */ + if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { + return 0; + } + + /* Timer expired, so return true */ + return 1; +} + +void dtls1_double_timeout(SSL *s) +{ + s->d1->timeout_duration *= 2; + if (s->d1->timeout_duration > 60) + s->d1->timeout_duration = 60; + dtls1_start_timer(s); +} + +void dtls1_stop_timer(SSL *s) +{ + /* Reset everything */ + memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st)); + memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); + s->d1->timeout_duration = 1; + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, + &(s->d1->next_timeout)); + /* Clear retransmission buffer */ + dtls1_clear_record_buffer(s); +} + +int dtls1_check_timeout_num(SSL *s) +{ + unsigned int mtu; + + s->d1->timeout.num_alerts++; + + /* Reduce MTU after 2 unsuccessful retransmissions */ + if (s->d1->timeout.num_alerts > 2 + && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { + mtu = + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, + NULL); + if (mtu < s->d1->mtu) + s->d1->mtu = mtu; + } + + if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) { + /* fail the connection, enough alerts have been sent */ + SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM, SSL_R_READ_TIMEOUT_EXPIRED); + return -1; + } + + return 0; +} + +int dtls1_handle_timeout(SSL *s) +{ + /* if no timer is expired, don't do anything */ + if (!dtls1_is_timer_expired(s)) { + return 0; + } + + dtls1_double_timeout(s); + + if (dtls1_check_timeout_num(s) < 0) + return -1; + + s->d1->timeout.read_timeouts++; + if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) { + s->d1->timeout.read_timeouts = 1; + } +#ifndef OPENSSL_NO_HEARTBEATS + if (s->tlsext_hb_pending) { + s->tlsext_hb_pending = 0; + return dtls1_heartbeat(s); + } +#endif + + dtls1_start_timer(s); + return dtls1_retransmit_buffered_messages(s); +} + +static void get_current_time(struct timeval *t) +{ +#ifdef OPENSSL_SYS_WIN32 + struct _timeb tb; + _ftime(&tb); + t->tv_sec = (long)tb.time; + t->tv_usec = (long)tb.millitm * 1000; +#elif defined(OPENSSL_SYS_VMS) + struct timeb tb; + ftime(&tb); + t->tv_sec = (long)tb.time; + t->tv_usec = (long)tb.millitm * 1000; +#else + gettimeofday(t, NULL); +#endif +} + +int dtls1_listen(SSL *s, struct sockaddr *client) +{ + int ret; + + /* Ensure there is no state left over from a previous invocation */ + SSL_clear(s); + + SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); + s->d1->listen = 1; + + ret = SSL_accept(s); + if (ret <= 0) + return ret; + + (void)BIO_dgram_get_peer(SSL_get_rbio(s), client); + return 1; +} diff --git a/libs/openssl/ssl/d1_meth.c b/libs/openssl/ssl/d1_meth.c new file mode 100644 index 00000000..aaa718c9 --- /dev/null +++ b/libs/openssl/ssl/d1_meth.c @@ -0,0 +1,74 @@ +/* ssl/d1_meth.h */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include "ssl_locl.h" + +static const SSL_METHOD *dtls1_get_method(int ver); +static const SSL_METHOD *dtls1_get_method(int ver) +{ + if (ver == DTLS1_VERSION) + return (DTLSv1_method()); + else + return (NULL); +} + +IMPLEMENT_dtls1_meth_func(DTLSv1_method, + dtls1_accept, dtls1_connect, dtls1_get_method) diff --git a/libs/openssl/ssl/d1_pkt.c b/libs/openssl/ssl/d1_pkt.c new file mode 100644 index 00000000..d659ed42 --- /dev/null +++ b/libs/openssl/ssl/d1_pkt.c @@ -0,0 +1,1905 @@ +/* ssl/d1_pkt.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#define USE_SOCKETS +#include "ssl_locl.h" +#include +#include +#include +#include + +/* mod 128 saturating subtract of two 64-bit values in big-endian order */ +static int satsub64be(const unsigned char *v1, const unsigned char *v2) +{ + int ret, sat, brw, i; + + if (sizeof(long) == 8) + do { + const union { + long one; + char little; + } is_endian = { + 1 + }; + long l; + + if (is_endian.little) + break; + /* not reached on little-endians */ + /* + * following test is redundant, because input is always aligned, + * but I take no chances... + */ + if (((size_t)v1 | (size_t)v2) & 0x7) + break; + + l = *((long *)v1); + l -= *((long *)v2); + if (l > 128) + return 128; + else if (l < -128) + return -128; + else + return (int)l; + } while (0); + + ret = (int)v1[7] - (int)v2[7]; + sat = 0; + brw = ret >> 8; /* brw is either 0 or -1 */ + if (ret & 0x80) { + for (i = 6; i >= 0; i--) { + brw += (int)v1[i] - (int)v2[i]; + sat |= ~brw; + brw >>= 8; + } + } else { + for (i = 6; i >= 0; i--) { + brw += (int)v1[i] - (int)v2[i]; + sat |= brw; + brw >>= 8; + } + } + brw <<= 8; /* brw is either 0 or -256 */ + + if (sat & 0xff) + return brw | 0x80; + else + return brw + (ret & 0xFF); +} + +static int have_handshake_fragment(SSL *s, int type, unsigned char *buf, + int len, int peek); +static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap); +static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap); +static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, + unsigned int *is_next_epoch); +#if 0 +static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, + unsigned short *priority, + unsigned long *offset); +#endif +static int dtls1_buffer_record(SSL *s, record_pqueue *q, + unsigned char *priority); +static int dtls1_process_record(SSL *s); + +/* copy buffered record into SSL structure */ +static int dtls1_copy_record(SSL *s, pitem *item) +{ + DTLS1_RECORD_DATA *rdata; + + rdata = (DTLS1_RECORD_DATA *)item->data; + + if (s->s3->rbuf.buf != NULL) + OPENSSL_free(s->s3->rbuf.buf); + + s->packet = rdata->packet; + s->packet_length = rdata->packet_length; + memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); + memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); + + /* Set proper sequence number for mac calculation */ + memcpy(&(s->s3->read_sequence[2]), &(rdata->packet[5]), 6); + + return (1); +} + +static int +dtls1_buffer_record(SSL *s, record_pqueue *queue, unsigned char *priority) +{ + DTLS1_RECORD_DATA *rdata; + pitem *item; + + /* Limit the size of the queue to prevent DOS attacks */ + if (pqueue_size(queue->q) >= 100) + return 0; + + rdata = OPENSSL_malloc(sizeof(DTLS1_RECORD_DATA)); + item = pitem_new(priority, rdata); + if (rdata == NULL || item == NULL) { + if (rdata != NULL) + OPENSSL_free(rdata); + if (item != NULL) + pitem_free(item); + + SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); + return -1; + } + + rdata->packet = s->packet; + rdata->packet_length = s->packet_length; + memcpy(&(rdata->rbuf), &(s->s3->rbuf), sizeof(SSL3_BUFFER)); + memcpy(&(rdata->rrec), &(s->s3->rrec), sizeof(SSL3_RECORD)); + + item->data = rdata; + +#ifndef OPENSSL_NO_SCTP + /* Store bio_dgram_sctp_rcvinfo struct */ + if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && + (s->state == SSL3_ST_SR_FINISHED_A + || s->state == SSL3_ST_CR_FINISHED_A)) { + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_GET_RCVINFO, + sizeof(rdata->recordinfo), &rdata->recordinfo); + } +#endif + + s->packet = NULL; + s->packet_length = 0; + memset(&(s->s3->rbuf), 0, sizeof(SSL3_BUFFER)); + memset(&(s->s3->rrec), 0, sizeof(SSL3_RECORD)); + + if (!ssl3_setup_buffers(s)) { + SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); + if (rdata->rbuf.buf != NULL) + OPENSSL_free(rdata->rbuf.buf); + OPENSSL_free(rdata); + pitem_free(item); + return (-1); + } + + /* insert should not fail, since duplicates are dropped */ + if (pqueue_insert(queue->q, item) == NULL) { + SSLerr(SSL_F_DTLS1_BUFFER_RECORD, ERR_R_INTERNAL_ERROR); + if (rdata->rbuf.buf != NULL) + OPENSSL_free(rdata->rbuf.buf); + OPENSSL_free(rdata); + pitem_free(item); + return (-1); + } + + return (1); +} + +static int dtls1_retrieve_buffered_record(SSL *s, record_pqueue *queue) +{ + pitem *item; + + item = pqueue_pop(queue->q); + if (item) { + dtls1_copy_record(s, item); + + OPENSSL_free(item->data); + pitem_free(item); + + return (1); + } + + return (0); +} + +/* + * retrieve a buffered record that belongs to the new epoch, i.e., not + * processed yet + */ +#define dtls1_get_unprocessed_record(s) \ + dtls1_retrieve_buffered_record((s), \ + &((s)->d1->unprocessed_rcds)) + +/* + * retrieve a buffered record that belongs to the current epoch, ie, + * processed + */ +#define dtls1_get_processed_record(s) \ + dtls1_retrieve_buffered_record((s), \ + &((s)->d1->processed_rcds)) + +static int dtls1_process_buffered_records(SSL *s) +{ + pitem *item; + + item = pqueue_peek(s->d1->unprocessed_rcds.q); + if (item) { + /* Check if epoch is current. */ + if (s->d1->unprocessed_rcds.epoch != s->d1->r_epoch) + return (1); /* Nothing to do. */ + + /* Process all the records. */ + while (pqueue_peek(s->d1->unprocessed_rcds.q)) { + dtls1_get_unprocessed_record(s); + if (!dtls1_process_record(s)) + return (0); + if (dtls1_buffer_record(s, &(s->d1->processed_rcds), + s->s3->rrec.seq_num) < 0) + return -1; + } + } + + /* + * sync epoch numbers once all the unprocessed records have been + * processed + */ + s->d1->processed_rcds.epoch = s->d1->r_epoch; + s->d1->unprocessed_rcds.epoch = s->d1->r_epoch + 1; + + return (1); +} + +#if 0 + +static int dtls1_get_buffered_record(SSL *s) +{ + pitem *item; + PQ_64BIT priority = + (((PQ_64BIT) s->d1->handshake_read_seq) << 32) | + ((PQ_64BIT) s->d1->r_msg_hdr.frag_off); + + /* if we're not (re)negotiating, nothing buffered */ + if (!SSL_in_init(s)) + return 0; + + item = pqueue_peek(s->d1->rcvd_records); + if (item && item->priority == priority) { + /* + * Check if we've received the record of interest. It must be a + * handshake record, since data records as passed up without + * buffering + */ + DTLS1_RECORD_DATA *rdata; + item = pqueue_pop(s->d1->rcvd_records); + rdata = (DTLS1_RECORD_DATA *)item->data; + + if (s->s3->rbuf.buf != NULL) + OPENSSL_free(s->s3->rbuf.buf); + + s->packet = rdata->packet; + s->packet_length = rdata->packet_length; + memcpy(&(s->s3->rbuf), &(rdata->rbuf), sizeof(SSL3_BUFFER)); + memcpy(&(s->s3->rrec), &(rdata->rrec), sizeof(SSL3_RECORD)); + + OPENSSL_free(item->data); + pitem_free(item); + + /* s->d1->next_expected_seq_num++; */ + return (1); + } + + return 0; +} + +#endif + +static int dtls1_process_record(SSL *s) +{ + int i, al; + int enc_err; + SSL_SESSION *sess; + SSL3_RECORD *rr; + unsigned int mac_size, orig_len; + unsigned char md[EVP_MAX_MD_SIZE]; + + rr = &(s->s3->rrec); + sess = s->session; + + /* + * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, + * and we have that many bytes in s->packet + */ + rr->input = &(s->packet[DTLS1_RT_HEADER_LENGTH]); + + /* + * ok, we can now read from 's->packet' data into 'rr' rr->input points + * at rr->length bytes, which need to be copied into rr->data by either + * the decryption or by the decompression When the data is 'copied' into + * the rr->data buffer, rr->input will be pointed at the new buffer + */ + + /* + * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length + * bytes of encrypted compressed stuff. + */ + + /* check is not needed I believe */ + if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + goto f_err; + } + + /* decrypt in place in 'rr->input' */ + rr->data = rr->input; + + enc_err = s->method->ssl3_enc->enc(s, 0); + /*- + * enc_err is: + * 0: (in non-constant time) if the record is publically invalid. + * 1: if the padding is valid + * -1: if the padding is invalid + */ + if (enc_err == 0) { + /* For DTLS we simply ignore bad packets. */ + rr->length = 0; + s->packet_length = 0; + goto err; + } +#ifdef TLS_DEBUG + printf("dec %d\n", rr->length); + { + unsigned int z; + for (z = 0; z < rr->length; z++) + printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n'); + } + printf("\n"); +#endif + + /* r->length is now the compressed data plus mac */ + if ((sess != NULL) && + (s->enc_read_ctx != NULL) && (EVP_MD_CTX_md(s->read_hash) != NULL)) { + /* s->read_hash != NULL => mac_size != -1 */ + unsigned char *mac = NULL; + unsigned char mac_tmp[EVP_MAX_MD_SIZE]; + mac_size = EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); + + /* + * kludge: *_cbc_remove_padding passes padding length in rr->type + */ + orig_len = rr->length + ((unsigned int)rr->type >> 8); + + /* + * orig_len is the length of the record before any padding was + * removed. This is public information, as is the MAC in use, + * therefore we can safely process the record in a different amount + * of time if it's too short to possibly contain a MAC. + */ + if (orig_len < mac_size || + /* CBC records must have a padding length byte too. */ + (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && + orig_len < mac_size + 1)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { + /* + * We update the length so that the TLS header bytes can be + * constructed correctly but we need to extract the MAC in + * constant time from within the record, without leaking the + * contents of the padding bytes. + */ + mac = mac_tmp; + ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); + rr->length -= mac_size; + } else { + /* + * In this case there's no padding, so |orig_len| equals + * |rec->length| and we checked that there's enough bytes for + * |mac_size| above. + */ + rr->length -= mac_size; + mac = &rr->data[rr->length]; + } + + i = s->method->ssl3_enc->mac(s, md, 0 /* not send */ ); + if (i < 0 || mac == NULL + || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) + enc_err = -1; + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + mac_size) + enc_err = -1; + } + + if (enc_err < 0) { + /* decryption failed, silently discard message */ + rr->length = 0; + s->packet_length = 0; + goto err; + } + + /* r->length is now just compressed */ + if (s->expand != NULL) { + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_DTLS1_PROCESS_RECORD, + SSL_R_COMPRESSED_LENGTH_TOO_LONG); + goto f_err; + } + if (!ssl3_do_uncompress(s)) { + al = SSL_AD_DECOMPRESSION_FAILURE; + SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_BAD_DECOMPRESSION); + goto f_err; + } + } + + if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_DTLS1_PROCESS_RECORD, SSL_R_DATA_LENGTH_TOO_LONG); + goto f_err; + } + + rr->off = 0; + /*- + * So at this point the following is true + * ssl->s3->rrec.type is the type of record + * ssl->s3->rrec.length == number of bytes in record + * ssl->s3->rrec.off == offset to first valid byte + * ssl->s3->rrec.data == where to take bytes from, increment + * after use :-). + */ + + /* we have pulled in a full packet so zero things */ + s->packet_length = 0; + return (1); + + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (0); +} + +/*- + * Call this to get a new input record. + * It will return <= 0 if more data is needed, normally due to an error + * or non-blocking IO. + * When it finishes, one packet has been decoded and can be found in + * ssl->s3->rrec.type - is the type of record + * ssl->s3->rrec.data, - data + * ssl->s3->rrec.length, - number of bytes + */ +/* used only by dtls1_read_bytes */ +int dtls1_get_record(SSL *s) +{ + int ssl_major, ssl_minor; + int i, n; + SSL3_RECORD *rr; + unsigned char *p = NULL; + unsigned short version; + DTLS1_BITMAP *bitmap; + unsigned int is_next_epoch; + + rr = &(s->s3->rrec); + + /* + * The epoch may have changed. If so, process all the pending records. + * This is a non-blocking operation. + */ + if (dtls1_process_buffered_records(s) < 0) + return -1; + + /* if we're renegotiating, then there may be buffered records */ + if (dtls1_get_processed_record(s)) + return 1; + + /* get something from the wire */ + again: + /* check if we have the header */ + if ((s->rstate != SSL_ST_READ_BODY) || + (s->packet_length < DTLS1_RT_HEADER_LENGTH)) { + n = ssl3_read_n(s, DTLS1_RT_HEADER_LENGTH, s->s3->rbuf.len, 0); + /* read timeout is handled by dtls1_read_bytes */ + if (n <= 0) + return (n); /* error or non-blocking */ + + /* this packet contained a partial record, dump it */ + if (s->packet_length != DTLS1_RT_HEADER_LENGTH) { + s->packet_length = 0; + goto again; + } + + s->rstate = SSL_ST_READ_BODY; + + p = s->packet; + + /* Pull apart the header into the DTLS1_RECORD */ + rr->type = *(p++); + ssl_major = *(p++); + ssl_minor = *(p++); + version = (ssl_major << 8) | ssl_minor; + + /* sequence number is 64 bits, with top 2 bytes = epoch */ + n2s(p, rr->epoch); + + memcpy(&(s->s3->read_sequence[2]), p, 6); + p += 6; + + n2s(p, rr->length); + + /* Lets check version */ + if (!s->first_packet) { + if (version != s->version) { + /* unexpected version, silently discard */ + rr->length = 0; + s->packet_length = 0; + goto again; + } + } + + if ((version & 0xff00) != (s->version & 0xff00)) { + /* wrong version, silently discard record */ + rr->length = 0; + s->packet_length = 0; + goto again; + } + + if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + /* record too long, silently discard it */ + rr->length = 0; + s->packet_length = 0; + goto again; + } + + /* now s->rstate == SSL_ST_READ_BODY */ + } + + /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ + + if (rr->length > s->packet_length - DTLS1_RT_HEADER_LENGTH) { + /* now s->packet_length == DTLS1_RT_HEADER_LENGTH */ + i = rr->length; + n = ssl3_read_n(s, i, i, 1); + /* this packet contained a partial record, dump it */ + if (n != i) { + rr->length = 0; + s->packet_length = 0; + goto again; + } + + /* + * now n == rr->length, and s->packet_length == + * DTLS1_RT_HEADER_LENGTH + rr->length + */ + } + s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ + + /* match epochs. NULL means the packet is dropped on the floor */ + bitmap = dtls1_get_bitmap(s, rr, &is_next_epoch); + if (bitmap == NULL) { + rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } +#ifndef OPENSSL_NO_SCTP + /* Only do replay check if no SCTP bio */ + if (!BIO_dgram_is_sctp(SSL_get_rbio(s))) { +#endif + /* + * Check whether this is a repeat, or aged record. Don't check if + * we're listening and this message is a ClientHello. They can look + * as if they're replayed, since they arrive from different + * connections and would be dropped unnecessarily. + */ + if (!(s->d1->listen && rr->type == SSL3_RT_HANDSHAKE && + s->packet_length > DTLS1_RT_HEADER_LENGTH && + s->packet[DTLS1_RT_HEADER_LENGTH] == SSL3_MT_CLIENT_HELLO) && + !dtls1_record_replay_check(s, bitmap)) { + rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } +#ifndef OPENSSL_NO_SCTP + } +#endif + + /* just read a 0 length packet */ + if (rr->length == 0) + goto again; + + /* + * If this record is from the next epoch (either HM or ALERT), and a + * handshake is currently in progress, buffer it since it cannot be + * processed at this time. However, do not buffer anything while + * listening. + */ + if (is_next_epoch) { + if ((SSL_in_init(s) || s->in_handshake) && !s->d1->listen) { + if (dtls1_buffer_record + (s, &(s->d1->unprocessed_rcds), rr->seq_num) < 0) + return -1; + /* Mark receipt of record. */ + dtls1_record_bitmap_update(s, bitmap); + } + rr->length = 0; + s->packet_length = 0; + goto again; + } + + if (!dtls1_process_record(s)) { + rr->length = 0; + s->packet_length = 0; /* dump this record */ + goto again; /* get another record */ + } + dtls1_record_bitmap_update(s, bitmap); /* Mark receipt of record. */ + + return (1); + +} + +/*- + * Return up to 'len' payload bytes received in 'type' records. + * 'type' is one of the following: + * + * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) + * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) + * - 0 (during a shutdown, no data has to be returned) + * + * If we don't have stored data to work from, read a SSL/TLS record first + * (possibly multiple records if we still don't have anything to return). + * + * This function must handle any surprises the peer may have for us, such as + * Alert records (e.g. close_notify), ChangeCipherSpec records (not really + * a surprise, but handled as if it were), or renegotiation requests. + * Also if record payloads contain fragments too small to process, we store + * them until there is enough for the respective protocol (the record protocol + * may use arbitrary fragmentation and even interleaving): + * Change cipher spec protocol + * just 1 byte needed, no need for keeping anything stored + * Alert protocol + * 2 bytes needed (AlertLevel, AlertDescription) + * Handshake protocol + * 4 bytes needed (HandshakeType, uint24 length) -- we just have + * to detect unexpected Client Hello and Hello Request messages + * here, anything else is handled by higher layers + * Application data protocol + * none of our business + */ +int dtls1_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) +{ + int al, i, j, ret; + unsigned int n; + SSL3_RECORD *rr; + void (*cb) (const SSL *ssl, int type2, int val) = NULL; + + if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ + if (!ssl3_setup_buffers(s)) + return (-1); + + /* XXX: check what the second '&& type' is about */ + if ((type && (type != SSL3_RT_APPLICATION_DATA) && + (type != SSL3_RT_HANDSHAKE) && type) || + (peek && (type != SSL3_RT_APPLICATION_DATA))) { + SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* + * check whether there's a handshake message (client hello?) waiting + */ + if ((ret = have_handshake_fragment(s, type, buf, len, peek))) + return ret; + + /* + * Now s->d1->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. + */ + +#ifndef OPENSSL_NO_SCTP + /* + * Continue handshake if it had to be interrupted to read app data with + * SCTP. + */ + if ((!s->in_handshake && SSL_in_init(s)) || + (BIO_dgram_is_sctp(SSL_get_rbio(s)) && + (s->state == DTLS1_SCTP_ST_SR_READ_SOCK + || s->state == DTLS1_SCTP_ST_CR_READ_SOCK) + && s->s3->in_read_app_data != 2)) +#else + if (!s->in_handshake && SSL_in_init(s)) +#endif + { + /* type == SSL3_RT_APPLICATION_DATA */ + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + } + + start: + s->rwstate = SSL_NOTHING; + + /*- + * s->s3->rrec.type - is the type of record + * s->s3->rrec.data, - data + * s->s3->rrec.off, - offset into 'data' for next read + * s->s3->rrec.length, - number of bytes. + */ + rr = &(s->s3->rrec); + + /* + * We are not handshaking and have no data yet, so process data buffered + * during the last handshake in advance, if any. + */ + if (s->state == SSL_ST_OK && rr->length == 0) { + pitem *item; + item = pqueue_pop(s->d1->buffered_app_data.q); + if (item) { +#ifndef OPENSSL_NO_SCTP + /* Restore bio_dgram_sctp_rcvinfo struct */ + if (BIO_dgram_is_sctp(SSL_get_rbio(s))) { + DTLS1_RECORD_DATA *rdata = (DTLS1_RECORD_DATA *)item->data; + BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SCTP_SET_RCVINFO, + sizeof(rdata->recordinfo), &rdata->recordinfo); + } +#endif + + dtls1_copy_record(s, item); + + OPENSSL_free(item->data); + pitem_free(item); + } + } + + /* Check for timeout */ + if (dtls1_handle_timeout(s) > 0) + goto start; + + /* get new packet if necessary */ + if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) { + ret = dtls1_get_record(s); + if (ret <= 0) { + ret = dtls1_read_failed(s, ret); + /* anything other than a timeout is an error */ + if (ret <= 0) + return (ret); + else + goto start; + } + } + + if (s->d1->listen && rr->type != SSL3_RT_HANDSHAKE) { + rr->length = 0; + goto start; + } + + /* we now have a packet which can be read and processed */ + + if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, + * reset by ssl3_get_finished */ + && (rr->type != SSL3_RT_HANDSHAKE)) { + /* + * We now have application data between CCS and Finished. Most likely + * the packets were reordered on their way, so buffer the application + * data for later processing rather than dropping the connection. + */ + if (dtls1_buffer_record(s, &(s->d1->buffered_app_data), rr->seq_num) < + 0) { + SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); + return -1; + } + rr->length = 0; + goto start; + } + + /* + * If the other end has shut down, throw anything we read away (even in + * 'peek' mode) + */ + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + rr->length = 0; + s->rwstate = SSL_NOTHING; + return (0); + } + + if (type == rr->type) { /* SSL3_RT_APPLICATION_DATA or + * SSL3_RT_HANDSHAKE */ + /* + * make sure that we are not getting application data when we are + * doing a handshake for the first time + */ + if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && + (s->enc_read_ctx == NULL)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_APP_DATA_IN_HANDSHAKE); + goto f_err; + } + + if (len <= 0) + return (len); + + if ((unsigned int)len > rr->length) + n = rr->length; + else + n = (unsigned int)len; + + memcpy(buf, &(rr->data[rr->off]), n); + if (!peek) { + rr->length -= n; + rr->off += n; + if (rr->length == 0) { + s->rstate = SSL_ST_READ_HEADER; + rr->off = 0; + } + } +#ifndef OPENSSL_NO_SCTP + /* + * We were about to renegotiate but had to read belated application + * data first, so retry. + */ + if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && + rr->type == SSL3_RT_APPLICATION_DATA && + (s->state == DTLS1_SCTP_ST_SR_READ_SOCK + || s->state == DTLS1_SCTP_ST_CR_READ_SOCK)) { + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + } + + /* + * We might had to delay a close_notify alert because of reordered + * app data. If there was an alert and there is no message to read + * anymore, finally set shutdown. + */ + if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && + s->d1->shutdown_received + && !BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + return (0); + } +#endif + return (n); + } + + /* + * If we get here, then type != rr->type; if we have a handshake message, + * then it was unexpected (Hello Request or Client Hello). + */ + + /* + * In case of record types for which we have 'fragment' storage, fill + * that so that we can process the data at a fixed place. + */ + { + unsigned int k, dest_maxlen = 0; + unsigned char *dest = NULL; + unsigned int *dest_len = NULL; + + if (rr->type == SSL3_RT_HANDSHAKE) { + dest_maxlen = sizeof s->d1->handshake_fragment; + dest = s->d1->handshake_fragment; + dest_len = &s->d1->handshake_fragment_len; + } else if (rr->type == SSL3_RT_ALERT) { + dest_maxlen = sizeof(s->d1->alert_fragment); + dest = s->d1->alert_fragment; + dest_len = &s->d1->alert_fragment_len; + } +#ifndef OPENSSL_NO_HEARTBEATS + else if (rr->type == TLS1_RT_HEARTBEAT) { + dtls1_process_heartbeat(s); + + /* Exit and notify application to read again */ + rr->length = 0; + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + return (-1); + } +#endif + /* else it's a CCS message, or application data or wrong */ + else if (rr->type != SSL3_RT_CHANGE_CIPHER_SPEC) { + /* + * Application data while renegotiating is allowed. Try again + * reading. + */ + if (rr->type == SSL3_RT_APPLICATION_DATA) { + BIO *bio; + s->s3->in_read_app_data = 2; + bio = SSL_get_rbio(s); + s->rwstate = SSL_READING; + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + + /* Not certain if this is the right error handling */ + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + } + + if (dest_maxlen > 0) { + /* + * XDTLS: In a pathalogical case, the Client Hello may be + * fragmented--don't always expect dest_maxlen bytes + */ + if (rr->length < dest_maxlen) { +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE + /* + * for normal alerts rr->length is 2, while + * dest_maxlen is 7 if we were to handle this + * non-existing alert... + */ + FIX ME +#endif + s->rstate = SSL_ST_READ_HEADER; + rr->length = 0; + goto start; + } + + /* now move 'n' bytes: */ + for (k = 0; k < dest_maxlen; k++) { + dest[k] = rr->data[rr->off++]; + rr->length--; + } + *dest_len = dest_maxlen; + } + } + + /*- + * s->d1->handshake_fragment_len == 12 iff rr->type == SSL3_RT_HANDSHAKE; + * s->d1->alert_fragment_len == 7 iff rr->type == SSL3_RT_ALERT. + * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) + */ + + /* If we are a client, check for an incoming 'Hello Request': */ + if ((!s->server) && + (s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && + (s->d1->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && + (s->session != NULL) && (s->session->cipher != NULL)) { + s->d1->handshake_fragment_len = 0; + + if ((s->d1->handshake_fragment[1] != 0) || + (s->d1->handshake_fragment[2] != 0) || + (s->d1->handshake_fragment[3] != 0)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_HELLO_REQUEST); + goto f_err; + } + + /* + * no need to check sequence number on HELLO REQUEST messages + */ + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + s->d1->handshake_fragment, 4, s, + s->msg_callback_arg); + + if (SSL_is_init_finished(s) && + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && + !s->s3->renegotiate) { + s->d1->handshake_read_seq++; + s->new_session = 1; + ssl3_renegotiate(s); + if (ssl3_renegotiate_check(s)) { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_DTLS1_READ_BYTES, + SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { + if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ + BIO *bio; + /* + * In the case where we try to read application data, + * but we trigger an SSL handshake, we return -1 with + * the retry option set. Otherwise renegotiation may + * cause nasty problems in the blocking world + */ + s->rwstate = SSL_READING; + bio = SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + } + } + } + /* + * we either finished a handshake or ignored the request, now try + * again to obtain the (application) data we were asked for + */ + goto start; + } + + if (s->d1->alert_fragment_len >= DTLS1_AL_HEADER_LENGTH) { + int alert_level = s->d1->alert_fragment[0]; + int alert_descr = s->d1->alert_fragment[1]; + + s->d1->alert_fragment_len = 0; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_ALERT, + s->d1->alert_fragment, 2, s, s->msg_callback_arg); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + if (cb != NULL) { + j = (alert_level << 8) | alert_descr; + cb(s, SSL_CB_READ_ALERT, j); + } + + if (alert_level == SSL3_AL_WARNING) { + s->s3->warn_alert = alert_descr; + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { +#ifndef OPENSSL_NO_SCTP + /* + * With SCTP and streams the socket may deliver app data + * after a close_notify alert. We have to check this first so + * that nothing gets discarded. + */ + if (BIO_dgram_is_sctp(SSL_get_rbio(s)) && + BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { + s->d1->shutdown_received = 1; + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + return -1; + } +#endif + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + return (0); + } +#if 0 + /* XXX: this is a possible improvement in the future */ + /* now check if it's a missing record */ + if (alert_descr == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) { + unsigned short seq; + unsigned int frag_off; + unsigned char *p = &(s->d1->alert_fragment[2]); + + n2s(p, seq); + n2l3(p, frag_off); + + dtls1_retransmit_message(s, + dtls1_get_queue_priority + (frag->msg_header.seq, 0), frag_off, + &found); + if (!found && SSL_in_init(s)) { + /* + * fprintf( stderr,"in init = %d\n", SSL_in_init(s)); + */ + /* + * requested a message not yet sent, send an alert + * ourselves + */ + ssl3_send_alert(s, SSL3_AL_WARNING, + DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); + } + } +#endif + } else if (alert_level == SSL3_AL_FATAL) { + char tmp[16]; + + s->rwstate = SSL_NOTHING; + s->s3->fatal_alert = alert_descr; + SSLerr(SSL_F_DTLS1_READ_BYTES, + SSL_AD_REASON_OFFSET + alert_descr); + BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr); + ERR_add_error_data(2, "SSL alert number ", tmp); + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + SSL_CTX_remove_session(s->ctx, s->session); + return (0); + } else { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE); + goto f_err; + } + + goto start; + } + + if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a + * shutdown */ + s->rwstate = SSL_NOTHING; + rr->length = 0; + return (0); + } + + if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { + struct ccs_header_st ccs_hdr; + unsigned int ccs_hdr_len = DTLS1_CCS_HEADER_LENGTH; + + dtls1_get_ccs_header(rr->data, &ccs_hdr); + + if (s->version == DTLS1_BAD_VER) + ccs_hdr_len = 3; + + /* + * 'Change Cipher Spec' is just a single byte, so we know exactly + * what the record payload has to look like + */ + /* XDTLS: check that epoch is consistent */ + if ((rr->length != ccs_hdr_len) || + (rr->off != 0) || (rr->data[0] != SSL3_MT_CCS)) { + i = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC); + goto err; + } + + rr->length = 0; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, + rr->data, 1, s, s->msg_callback_arg); + + /* + * We can't process a CCS now, because previous handshake messages + * are still missing, so just drop it. + */ + if (!s->d1->change_cipher_spec_ok) { + goto start; + } + + s->d1->change_cipher_spec_ok = 0; + + s->s3->change_cipher_spec = 1; + if (!ssl3_do_change_cipher_spec(s)) + goto err; + + /* do this whenever CCS is processed */ + dtls1_reset_seq_numbers(s, SSL3_CC_READ); + + if (s->version == DTLS1_BAD_VER) + s->d1->handshake_read_seq++; + +#ifndef OPENSSL_NO_SCTP + /* + * Remember that a CCS has been received, so that an old key of + * SCTP-Auth can be deleted when a CCS is sent. Will be ignored if no + * SCTP is used + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_AUTH_CCS_RCVD, 1, NULL); +#endif + + goto start; + } + + /* + * Unexpected handshake message (Client Hello, or protocol violation) + */ + if ((s->d1->handshake_fragment_len >= DTLS1_HM_HEADER_LENGTH) && + !s->in_handshake) { + struct hm_header_st msg_hdr; + + /* this may just be a stale retransmit */ + dtls1_get_message_header(rr->data, &msg_hdr); + if (rr->epoch != s->d1->r_epoch) { + rr->length = 0; + goto start; + } + + /* + * If we are server, we may have a repeated FINISHED of the client + * here, then retransmit our CCS and FINISHED. + */ + if (msg_hdr.type == SSL3_MT_FINISHED) { + if (dtls1_check_timeout_num(s) < 0) + return -1; + + dtls1_retransmit_buffered_messages(s); + rr->length = 0; + goto start; + } + + if (((s->state & SSL_ST_MASK) == SSL_ST_OK) && + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { +#if 0 /* worked only because C operator preferences + * are not as expected (and because this is + * not really needed for clients except for + * detecting protocol violations): */ + s->state = SSL_ST_BEFORE | (s->server) + ? SSL_ST_ACCEPT : SSL_ST_CONNECT; +#else + s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; +#endif + s->renegotiate = 1; + s->new_session = 1; + } + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { + if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ + BIO *bio; + /* + * In the case where we try to read application data, but we + * trigger an SSL handshake, we return -1 with the retry + * option set. Otherwise renegotiation may cause nasty + * problems in the blocking world + */ + s->rwstate = SSL_READING; + bio = SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + } + goto start; + } + + switch (rr->type) { + default: +#ifndef OPENSSL_NO_TLS + /* TLS just ignores unknown message types */ + if (s->version == TLS1_VERSION) { + rr->length = 0; + goto start; + } +#endif + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + case SSL3_RT_CHANGE_CIPHER_SPEC: + case SSL3_RT_ALERT: + case SSL3_RT_HANDSHAKE: + /* + * we already handled all of these, with the possible exception of + * SSL3_RT_HANDSHAKE when s->in_handshake is set, but that should not + * happen when type != rr->type + */ + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, ERR_R_INTERNAL_ERROR); + goto f_err; + case SSL3_RT_APPLICATION_DATA: + /* + * At this point, we were expecting handshake data, but have + * application data. If the library was running inside ssl3_read() + * (i.e. in_read_app_data is set) and it makes sense to read + * application data at this point (session renegotiation not yet + * started), we will indulge it. + */ + if (s->s3->in_read_app_data && + (s->s3->total_renegotiations != 0) && + (((s->state & SSL_ST_CONNECT) && + (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && + (s->state <= SSL3_ST_CR_SRVR_HELLO_A) + ) || ((s->state & SSL_ST_ACCEPT) && + (s->state <= SSL3_ST_SW_HELLO_REQ_A) && + (s->state >= SSL3_ST_SR_CLNT_HELLO_A) + ) + )) { + s->s3->in_read_app_data = 2; + return (-1); + } else { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_DTLS1_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + } + } + /* not reached */ + + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (-1); +} + +int dtls1_write_app_data_bytes(SSL *s, int type, const void *buf_, int len) +{ + int i; + +#ifndef OPENSSL_NO_SCTP + /* + * Check if we have to continue an interrupted handshake for reading + * belated app data with SCTP. + */ + if ((SSL_in_init(s) && !s->in_handshake) || + (BIO_dgram_is_sctp(SSL_get_wbio(s)) && + (s->state == DTLS1_SCTP_ST_SR_READ_SOCK + || s->state == DTLS1_SCTP_ST_CR_READ_SOCK))) +#else + if (SSL_in_init(s) && !s->in_handshake) +#endif + { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, + SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + if (len > SSL3_RT_MAX_PLAIN_LENGTH) { + SSLerr(SSL_F_DTLS1_WRITE_APP_DATA_BYTES, SSL_R_DTLS_MESSAGE_TOO_BIG); + return -1; + } + + i = dtls1_write_bytes(s, type, buf_, len); + return i; +} + + /* + * this only happens when a client hello is received and a handshake + * is started. + */ +static int +have_handshake_fragment(SSL *s, int type, unsigned char *buf, + int len, int peek) +{ + + if ((type == SSL3_RT_HANDSHAKE) && (s->d1->handshake_fragment_len > 0)) + /* (partially) satisfy request from storage */ + { + unsigned char *src = s->d1->handshake_fragment; + unsigned char *dst = buf; + unsigned int k, n; + + /* peek == 0 */ + n = 0; + while ((len > 0) && (s->d1->handshake_fragment_len > 0)) { + *dst++ = *src++; + len--; + s->d1->handshake_fragment_len--; + n++; + } + /* move any remaining fragment bytes: */ + for (k = 0; k < s->d1->handshake_fragment_len; k++) + s->d1->handshake_fragment[k] = *src++; + return n; + } + + return 0; +} + +/* + * Call this to write data in records of type 'type' It will return <= 0 if + * not all data has been sent or non-blocking IO. + */ +int dtls1_write_bytes(SSL *s, int type, const void *buf, int len) +{ + int i; + + OPENSSL_assert(len <= SSL3_RT_MAX_PLAIN_LENGTH); + s->rwstate = SSL_NOTHING; + i = do_dtls1_write(s, type, buf, len, 0); + return i; +} + +int do_dtls1_write(SSL *s, int type, const unsigned char *buf, + unsigned int len, int create_empty_fragment) +{ + unsigned char *p, *pseq; + int i, mac_size, clear = 0; + int prefix_len = 0; + SSL3_RECORD *wr; + SSL3_BUFFER *wb; + SSL_SESSION *sess; + int bs; + + /* + * first check if there is a SSL3_BUFFER still being written out. This + * will happen with non blocking IO + */ + if (s->s3->wbuf.left != 0) { + OPENSSL_assert(0); /* XDTLS: want to see if we ever get here */ + return (ssl3_write_pending(s, type, buf, len)); + } + + /* If we have an alert to send, lets send it */ + if (s->s3->alert_dispatch) { + i = s->method->ssl_dispatch_alert(s); + if (i <= 0) + return (i); + /* if it went, fall through and send more stuff */ + } + + if (len == 0 && !create_empty_fragment) + return 0; + + wr = &(s->s3->wrec); + wb = &(s->s3->wbuf); + sess = s->session; + + if ((sess == NULL) || + (s->enc_write_ctx == NULL) || (EVP_MD_CTX_md(s->write_hash) == NULL)) + clear = 1; + + if (clear) + mac_size = 0; + else { + mac_size = EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + goto err; + } + + /* DTLS implements explicit IV, so no need for empty fragments */ +#if 0 + /* + * 'create_empty_fragment' is true only when this function calls itself + */ + if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done + && SSL_version(s) != DTLS1_VERSION && SSL_version(s) != DTLS1_BAD_VER) + { + /* + * countermeasure against known-IV weakness in CBC ciphersuites (see + * http://www.openssl.org/~bodo/tls-cbc.txt) + */ + + if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) { + /* + * recursive function call with 'create_empty_fragment' set; this + * prepares and buffers the data for an empty fragment (these + * 'prefix_len' bytes are sent out later together with the actual + * payload) + */ + prefix_len = s->method->do_ssl_write(s, type, buf, 0, 1); + if (prefix_len <= 0) + goto err; + + if (s->s3->wbuf.len < + (size_t)prefix_len + SSL3_RT_MAX_PACKET_SIZE) { + /* insufficient space */ + SSLerr(SSL_F_DO_DTLS1_WRITE, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + s->s3->empty_fragment_done = 1; + } +#endif + p = wb->buf + prefix_len; + + /* write the header */ + + *(p++) = type & 0xff; + wr->type = type; + + *(p++) = (s->version >> 8); + *(p++) = s->version & 0xff; + + /* field where we are to write out packet epoch, seq num and len */ + pseq = p; + p += 10; + + /* lets setup the record stuff. */ + + /* + * Make space for the explicit IV in case of CBC. (this is a bit of a + * boundary violation, but what the heck). + */ + if (s->enc_write_ctx && + (EVP_CIPHER_mode(s->enc_write_ctx->cipher) & EVP_CIPH_CBC_MODE)) + bs = EVP_CIPHER_block_size(s->enc_write_ctx->cipher); + else + bs = 0; + + wr->data = p + bs; /* make room for IV in case of CBC */ + wr->length = (int)len; + wr->input = (unsigned char *)buf; + + /* + * we now 'read' from wr->input, wr->length bytes into wr->data + */ + + /* first we compress */ + if (s->compress != NULL) { + if (!ssl3_do_compress(s)) { + SSLerr(SSL_F_DO_DTLS1_WRITE, SSL_R_COMPRESSION_FAILURE); + goto err; + } + } else { + memcpy(wr->data, wr->input, wr->length); + wr->input = wr->data; + } + + /* + * we should still have the output to wr->data and the input from + * wr->input. Length should be wr->length. wr->data still points in the + * wb->buf + */ + + if (mac_size != 0) { + if (s->method->ssl3_enc->mac(s, &(p[wr->length + bs]), 1) < 0) + goto err; + wr->length += mac_size; + } + + /* this is true regardless of mac size */ + wr->input = p; + wr->data = p; + + /* ssl3_enc can only have an error on read */ + if (bs) { /* bs != 0 in case of CBC */ + RAND_pseudo_bytes(p, bs); + /* + * master IV and last CBC residue stand for the rest of randomness + */ + wr->length += bs; + } + + if (s->method->ssl3_enc->enc(s, 1) < 1) + goto err; + + /* record length after mac and block padding */ + /* + * if (type == SSL3_RT_APPLICATION_DATA || (type == SSL3_RT_ALERT && ! + * SSL_in_init(s))) + */ + + /* there's only one epoch between handshake and app data */ + + s2n(s->d1->w_epoch, pseq); + + /* XDTLS: ?? */ + /* + * else s2n(s->d1->handshake_epoch, pseq); + */ + + memcpy(pseq, &(s->s3->write_sequence[2]), 6); + pseq += 6; + s2n(wr->length, pseq); + + /* + * we should now have wr->data pointing to the encrypted data, which is + * wr->length long + */ + wr->type = type; /* not needed but helps for debugging */ + wr->length += DTLS1_RT_HEADER_LENGTH; + +#if 0 /* this is now done at the message layer */ + /* buffer the record, making it easy to handle retransmits */ + if (type == SSL3_RT_HANDSHAKE || type == SSL3_RT_CHANGE_CIPHER_SPEC) + dtls1_buffer_record(s, wr->data, wr->length, + *((PQ_64BIT *) & (s->s3->write_sequence[0]))); +#endif + + ssl3_record_sequence_update(&(s->s3->write_sequence[0])); + + if (create_empty_fragment) { + /* + * we are in a recursive call; just return the length, don't write + * out anything here + */ + return wr->length; + } + + /* now let's set up wb */ + wb->left = prefix_len + wr->length; + wb->offset = 0; + + /* + * memorize arguments so that ssl3_write_pending can detect bad write + * retries later + */ + s->s3->wpend_tot = len; + s->s3->wpend_buf = buf; + s->s3->wpend_type = type; + s->s3->wpend_ret = len; + + /* we now just need to write the buffer */ + return ssl3_write_pending(s, type, buf, len); + err: + return -1; +} + +static int dtls1_record_replay_check(SSL *s, DTLS1_BITMAP *bitmap) +{ + int cmp; + unsigned int shift; + const unsigned char *seq = s->s3->read_sequence; + + cmp = satsub64be(seq, bitmap->max_seq_num); + if (cmp > 0) { + memcpy(s->s3->rrec.seq_num, seq, 8); + return 1; /* this record in new */ + } + shift = -cmp; + if (shift >= sizeof(bitmap->map) * 8) + return 0; /* stale, outside the window */ + else if (bitmap->map & (1UL << shift)) + return 0; /* record previously received */ + + memcpy(s->s3->rrec.seq_num, seq, 8); + return 1; +} + +static void dtls1_record_bitmap_update(SSL *s, DTLS1_BITMAP *bitmap) +{ + int cmp; + unsigned int shift; + const unsigned char *seq = s->s3->read_sequence; + + cmp = satsub64be(seq, bitmap->max_seq_num); + if (cmp > 0) { + shift = cmp; + if (shift < sizeof(bitmap->map) * 8) + bitmap->map <<= shift, bitmap->map |= 1UL; + else + bitmap->map = 1UL; + memcpy(bitmap->max_seq_num, seq, 8); + } else { + shift = -cmp; + if (shift < sizeof(bitmap->map) * 8) + bitmap->map |= 1UL << shift; + } +} + +int dtls1_dispatch_alert(SSL *s) +{ + int i, j; + void (*cb) (const SSL *ssl, int type, int val) = NULL; + unsigned char buf[DTLS1_AL_HEADER_LENGTH]; + unsigned char *ptr = &buf[0]; + + s->s3->alert_dispatch = 0; + + memset(buf, 0x00, sizeof(buf)); + *ptr++ = s->s3->send_alert[0]; + *ptr++ = s->s3->send_alert[1]; + +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE + if (s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE) { + s2n(s->d1->handshake_read_seq, ptr); +# if 0 + if (s->d1->r_msg_hdr.frag_off == 0) + /* + * waiting for a new msg + */ + else + s2n(s->d1->r_msg_hdr.seq, ptr); /* partial msg read */ +# endif + +# if 0 + fprintf(stderr, + "s->d1->handshake_read_seq = %d, s->d1->r_msg_hdr.seq = %d\n", + s->d1->handshake_read_seq, s->d1->r_msg_hdr.seq); +# endif + l2n3(s->d1->r_msg_hdr.frag_off, ptr); + } +#endif + + i = do_dtls1_write(s, SSL3_RT_ALERT, &buf[0], sizeof(buf), 0); + if (i <= 0) { + s->s3->alert_dispatch = 1; + /* fprintf( stderr, "not done with alert\n" ); */ + } else { + if (s->s3->send_alert[0] == SSL3_AL_FATAL +#ifdef DTLS1_AD_MISSING_HANDSHAKE_MESSAGE + || s->s3->send_alert[1] == DTLS1_AD_MISSING_HANDSHAKE_MESSAGE +#endif + ) + (void)BIO_flush(s->wbio); + + if (s->msg_callback) + s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, + 2, s, s->msg_callback_arg); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + if (cb != NULL) { + j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]; + cb(s, SSL_CB_WRITE_ALERT, j); + } + } + return (i); +} + +static DTLS1_BITMAP *dtls1_get_bitmap(SSL *s, SSL3_RECORD *rr, + unsigned int *is_next_epoch) +{ + + *is_next_epoch = 0; + + /* In current epoch, accept HM, CCS, DATA, & ALERT */ + if (rr->epoch == s->d1->r_epoch) + return &s->d1->bitmap; + + /* Only HM and ALERT messages can be from the next epoch */ + else if (rr->epoch == (unsigned long)(s->d1->r_epoch + 1) && + (rr->type == SSL3_RT_HANDSHAKE || rr->type == SSL3_RT_ALERT)) { + *is_next_epoch = 1; + return &s->d1->next_bitmap; + } + + return NULL; +} + +#if 0 +static int +dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr, + unsigned short *priority, unsigned long *offset) +{ + + /* alerts are passed up immediately */ + if (rr->type == SSL3_RT_APPLICATION_DATA || rr->type == SSL3_RT_ALERT) + return 0; + + /* + * Only need to buffer if a handshake is underway. (this implies that + * Hello Request and Client Hello are passed up immediately) + */ + if (SSL_in_init(s)) { + unsigned char *data = rr->data; + /* need to extract the HM/CCS sequence number here */ + if (rr->type == SSL3_RT_HANDSHAKE || + rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { + unsigned short seq_num; + struct hm_header_st msg_hdr; + struct ccs_header_st ccs_hdr; + + if (rr->type == SSL3_RT_HANDSHAKE) { + dtls1_get_message_header(data, &msg_hdr); + seq_num = msg_hdr.seq; + *offset = msg_hdr.frag_off; + } else { + dtls1_get_ccs_header(data, &ccs_hdr); + seq_num = ccs_hdr.seq; + *offset = 0; + } + + /* + * this is either a record we're waiting for, or a retransmit of + * something we happened to previously receive (higher layers + * will drop the repeat silently + */ + if (seq_num < s->d1->handshake_read_seq) + return 0; + if (rr->type == SSL3_RT_HANDSHAKE && + seq_num == s->d1->handshake_read_seq && + msg_hdr.frag_off < s->d1->r_msg_hdr.frag_off) + return 0; + else if (seq_num == s->d1->handshake_read_seq && + (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC || + msg_hdr.frag_off == s->d1->r_msg_hdr.frag_off)) + return 0; + else { + *priority = seq_num; + return 1; + } + } else /* unknown record type */ + return 0; + } + + return 0; +} +#endif + +void dtls1_reset_seq_numbers(SSL *s, int rw) +{ + unsigned char *seq; + unsigned int seq_bytes = sizeof(s->s3->read_sequence); + + if (rw & SSL3_CC_READ) { + seq = s->s3->read_sequence; + s->d1->r_epoch++; + memcpy(&(s->d1->bitmap), &(s->d1->next_bitmap), sizeof(DTLS1_BITMAP)); + memset(&(s->d1->next_bitmap), 0x00, sizeof(DTLS1_BITMAP)); + } else { + seq = s->s3->write_sequence; + memcpy(s->d1->last_write_sequence, seq, + sizeof(s->s3->write_sequence)); + s->d1->w_epoch++; + } + + memset(seq, 0x00, seq_bytes); +} diff --git a/libs/openssl/ssl/d1_srtp.c b/libs/openssl/ssl/d1_srtp.c new file mode 100644 index 00000000..6c6e07ce --- /dev/null +++ b/libs/openssl/ssl/d1_srtp.c @@ -0,0 +1,449 @@ +/* ssl/t1_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* + * DTLS code by Eric Rescorla + * + * Copyright (C) 2006, Network Resonance, Inc. Copyright (C) 2011, RTFM, Inc. + */ + +#include +#include +#include "ssl_locl.h" + +#ifndef OPENSSL_NO_SRTP + +# include "srtp.h" + +static SRTP_PROTECTION_PROFILE srtp_known_profiles[] = { + { + "SRTP_AES128_CM_SHA1_80", + SRTP_AES128_CM_SHA1_80, + }, + { + "SRTP_AES128_CM_SHA1_32", + SRTP_AES128_CM_SHA1_32, + }, +# if 0 + { + "SRTP_NULL_SHA1_80", + SRTP_NULL_SHA1_80, + }, + { + "SRTP_NULL_SHA1_32", + SRTP_NULL_SHA1_32, + }, +# endif + {0} +}; + +static int find_profile_by_name(char *profile_name, + SRTP_PROTECTION_PROFILE **pptr, unsigned len) +{ + SRTP_PROTECTION_PROFILE *p; + + p = srtp_known_profiles; + while (p->name) { + if ((len == strlen(p->name)) && !strncmp(p->name, profile_name, len)) { + *pptr = p; + return 0; + } + + p++; + } + + return 1; +} + +static int ssl_ctx_make_profiles(const char *profiles_string, + STACK_OF(SRTP_PROTECTION_PROFILE) **out) +{ + STACK_OF(SRTP_PROTECTION_PROFILE) *profiles; + + char *col; + char *ptr = (char *)profiles_string; + + SRTP_PROTECTION_PROFILE *p; + + if (!(profiles = sk_SRTP_PROTECTION_PROFILE_new_null())) { + SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, + SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); + return 1; + } + + do { + col = strchr(ptr, ':'); + + if (!find_profile_by_name(ptr, &p, + col ? col - ptr : (int)strlen(ptr))) { + if (sk_SRTP_PROTECTION_PROFILE_find(profiles, p) >= 0) { + SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + sk_SRTP_PROTECTION_PROFILE_free(profiles); + return 1; + } + + sk_SRTP_PROTECTION_PROFILE_push(profiles, p); + } else { + SSLerr(SSL_F_SSL_CTX_MAKE_PROFILES, + SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); + sk_SRTP_PROTECTION_PROFILE_free(profiles); + return 1; + } + + if (col) + ptr = col + 1; + } while (col); + + *out = profiles; + + return 0; +} + +int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) +{ + return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles); +} + +int SSL_set_tlsext_use_srtp(SSL *s, const char *profiles) +{ + return ssl_ctx_make_profiles(profiles, &s->srtp_profiles); +} + +STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *s) +{ + if (s != NULL) { + if (s->srtp_profiles != NULL) { + return s->srtp_profiles; + } else if ((s->ctx != NULL) && (s->ctx->srtp_profiles != NULL)) { + return s->ctx->srtp_profiles; + } + } + + return NULL; +} + +SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *s) +{ + return s->srtp_profile; +} + +/* + * Note: this function returns 0 length if there are no profiles specified + */ +int ssl_add_clienthello_use_srtp_ext(SSL *s, unsigned char *p, int *len, + int maxlen) +{ + int ct = 0; + int i; + STACK_OF(SRTP_PROTECTION_PROFILE) *clnt = 0; + SRTP_PROTECTION_PROFILE *prof; + + clnt = SSL_get_srtp_profiles(s); + ct = sk_SRTP_PROTECTION_PROFILE_num(clnt); /* -1 if clnt == 0 */ + + if (p) { + if (ct == 0) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST); + return 1; + } + + if ((2 + ct * 2 + 1) > maxlen) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG); + return 1; + } + + /* Add the length */ + s2n(ct * 2, p); + for (i = 0; i < ct; i++) { + prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i); + s2n(prof->id, p); + } + + /* Add an empty use_mki value */ + *p++ = 0; + } + + *len = 2 + ct * 2 + 1; + + return 0; +} + +int ssl_parse_clienthello_use_srtp_ext(SSL *s, unsigned char *d, int len, + int *al) +{ + SRTP_PROTECTION_PROFILE *sprof; + STACK_OF(SRTP_PROTECTION_PROFILE) *srvr; + int ct; + int mki_len; + int i, srtp_pref; + unsigned int id; + + /* Length value + the MKI length */ + if (len < 3) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + /* Pull off the length of the cipher suite list */ + n2s(d, ct); + len -= 2; + + /* Check that it is even */ + if (ct % 2) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + /* Check that lengths are consistent */ + if (len < (ct + 1)) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + srvr = SSL_get_srtp_profiles(s); + s->srtp_profile = NULL; + /* Search all profiles for a match initially */ + srtp_pref = sk_SRTP_PROTECTION_PROFILE_num(srvr); + + while (ct) { + n2s(d, id); + ct -= 2; + len -= 2; + + /* + * Only look for match in profiles of higher preference than + * current match. + * If no profiles have been have been configured then this + * does nothing. + */ + for (i = 0; i < srtp_pref; i++) { + sprof = sk_SRTP_PROTECTION_PROFILE_value(srvr, i); + if (sprof->id == id) { + s->srtp_profile = sprof; + srtp_pref = i; + break; + } + } + } + + /* + * Now extract the MKI value as a sanity check, but discard it for now + */ + mki_len = *d; + d++; + len--; + + if (mki_len != len) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_MKI_VALUE); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + return 0; +} + +int ssl_add_serverhello_use_srtp_ext(SSL *s, unsigned char *p, int *len, + int maxlen) +{ + if (p) { + if (maxlen < 5) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT, + SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG); + return 1; + } + + if (s->srtp_profile == 0) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT, + SSL_R_USE_SRTP_NOT_NEGOTIATED); + return 1; + } + s2n(2, p); + s2n(s->srtp_profile->id, p); + *p++ = 0; + } + *len = 5; + + return 0; +} + +int ssl_parse_serverhello_use_srtp_ext(SSL *s, unsigned char *d, int len, + int *al) +{ + unsigned id; + int i; + int ct; + + STACK_OF(SRTP_PROTECTION_PROFILE) *clnt; + SRTP_PROTECTION_PROFILE *prof; + + if (len != 5) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + n2s(d, ct); + if (ct != 2) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + n2s(d, id); + if (*d) { /* Must be no MKI, since we never offer one */ + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_MKI_VALUE); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 1; + } + + clnt = SSL_get_srtp_profiles(s); + + /* Throw an error if the server gave us an unsolicited extension */ + if (clnt == NULL) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_NO_SRTP_PROFILES); + *al = SSL_AD_DECODE_ERROR; + return 1; + } + + /* + * Check to see if the server gave us something we support (and + * presumably offered) + */ + for (i = 0; i < sk_SRTP_PROTECTION_PROFILE_num(clnt); i++) { + prof = sk_SRTP_PROTECTION_PROFILE_value(clnt, i); + + if (prof->id == id) { + s->srtp_profile = prof; + *al = 0; + return 0; + } + } + + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT, + SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *al = SSL_AD_DECODE_ERROR; + return 1; +} + +#endif diff --git a/libs/openssl/ssl/d1_srvr.c b/libs/openssl/ssl/d1_srvr.c new file mode 100644 index 00000000..f01b8a69 --- /dev/null +++ b/libs/openssl/ssl/d1_srvr.c @@ -0,0 +1,1759 @@ +/* ssl/d1_srvr.c */ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * Copyright (c) 1999-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "ssl_locl.h" +#include +#include +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_DH +# include +#endif + +static const SSL_METHOD *dtls1_get_server_method(int ver); +static int dtls1_send_hello_verify_request(SSL *s); + +static const SSL_METHOD *dtls1_get_server_method(int ver) +{ + if (ver == DTLS1_VERSION) + return (DTLSv1_server_method()); + else + return (NULL); +} + +IMPLEMENT_dtls1_meth_func(DTLSv1_server_method, + dtls1_accept, + ssl_undefined_function, dtls1_get_server_method) + +int dtls1_accept(SSL *s) +{ + BUF_MEM *buf; + unsigned long Time = (unsigned long)time(NULL); + void (*cb) (const SSL *ssl, int type, int val) = NULL; + unsigned long alg_k; + int ret = -1; + int new_state, state, skip = 0; + int listen; +#ifndef OPENSSL_NO_SCTP + unsigned char sctpauthkey[64]; + char labelbuffer[sizeof(DTLS1_SCTP_AUTH_LABEL)]; +#endif + + RAND_add(&Time, sizeof(Time), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + listen = s->d1->listen; + + /* init things to blank */ + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + s->d1->listen = listen; +#ifndef OPENSSL_NO_SCTP + /* + * Notify SCTP BIO socket to enter handshake mode and prevent stream + * identifier other than 0. Will be ignored if no SCTP is used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, + s->in_handshake, NULL); +#endif + + if (s->cert == NULL) { + SSLerr(SSL_F_DTLS1_ACCEPT, SSL_R_NO_CERTIFICATE_SET); + return (-1); + } +#ifndef OPENSSL_NO_HEARTBEATS + /* + * If we're awaiting a HeartbeatResponse, pretend we already got and + * don't await it anymore, because Heartbeats don't make sense during + * handshakes anyway. + */ + if (s->tlsext_hb_pending) { + dtls1_stop_timer(s); + s->tlsext_hb_pending = 0; + s->tlsext_hb_seq++; + } +#endif + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_RENEGOTIATE: + s->renegotiate = 1; + /* s->state=SSL_ST_ACCEPT; */ + + case SSL_ST_BEFORE: + case SSL_ST_ACCEPT: + case SSL_ST_BEFORE | SSL_ST_ACCEPT: + case SSL_ST_OK | SSL_ST_ACCEPT: + + s->server = 1; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + if ((s->version & 0xff00) != (DTLS1_VERSION & 0xff00)) { + SSLerr(SSL_F_DTLS1_ACCEPT, ERR_R_INTERNAL_ERROR); + return -1; + } + s->type = SSL_ST_ACCEPT; + + if (s->init_buf == NULL) { + if ((buf = BUF_MEM_new()) == NULL) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { + BUF_MEM_free(buf); + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + s->init_buf = buf; + } + + if (!ssl3_setup_buffers(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + s->init_num = 0; + s->d1->change_cipher_spec_ok = 0; + /* + * Should have been reset by ssl3_get_finished, too. + */ + s->s3->change_cipher_spec = 0; + + if (s->state != SSL_ST_RENEGOTIATE) { + /* + * Ok, we now need to push on a buffering BIO so that the + * output is sent in a way that TCP likes :-) ...but not with + * SCTP :-) + */ +#ifndef OPENSSL_NO_SCTP + if (!BIO_dgram_is_sctp(SSL_get_wbio(s))) +#endif + if (!ssl_init_wbio_buffer(s, 1)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + ssl3_init_finished_mac(s); + s->state = SSL3_ST_SR_CLNT_HELLO_A; + s->ctx->stats.sess_accept++; + } else if (!s->s3->send_connection_binding && + !(s->options & + SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { + /* + * Server attempting to renegotiate with client that doesn't + * support secure renegotiation. + */ + SSLerr(SSL_F_DTLS1_ACCEPT, + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } else { + /* + * s->state == SSL_ST_RENEGOTIATE, we will just send a + * HelloRequest + */ + s->ctx->stats.sess_accept_renegotiate++; + s->state = SSL3_ST_SW_HELLO_REQ_A; + } + + break; + + case SSL3_ST_SW_HELLO_REQ_A: + case SSL3_ST_SW_HELLO_REQ_B: + + s->shutdown = 0; + dtls1_clear_record_buffer(s); + dtls1_start_timer(s); + ret = dtls1_send_hello_request(s); + if (ret <= 0) + goto end; + s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A; + s->state = SSL3_ST_SW_FLUSH; + s->init_num = 0; + + ssl3_init_finished_mac(s); + break; + + case SSL3_ST_SW_HELLO_REQ_C: + s->state = SSL_ST_OK; + break; + + case SSL3_ST_SR_CLNT_HELLO_A: + case SSL3_ST_SR_CLNT_HELLO_B: + case SSL3_ST_SR_CLNT_HELLO_C: + + s->shutdown = 0; + ret = ssl3_get_client_hello(s); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + + if (ret == 1 && (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE)) + s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A; + else + s->state = SSL3_ST_SW_SRVR_HELLO_A; + + s->init_num = 0; + + /* + * Reflect ClientHello sequence to remain stateless while + * listening + */ + if (listen) { + memcpy(s->s3->write_sequence, s->s3->read_sequence, + sizeof(s->s3->write_sequence)); + } + + /* If we're just listening, stop here */ + if (listen && s->state == SSL3_ST_SW_SRVR_HELLO_A) { + ret = 2; + s->d1->listen = 0; + /* + * Set expected sequence numbers to continue the handshake. + */ + s->d1->handshake_read_seq = 2; + s->d1->handshake_write_seq = 1; + s->d1->next_handshake_write_seq = 1; + goto end; + } + + break; + + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: + + ret = dtls1_send_hello_verify_request(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_FLUSH; + s->s3->tmp.next_state = SSL3_ST_SR_CLNT_HELLO_A; + + /* HelloVerifyRequest resets Finished MAC */ + if (s->version != DTLS1_BAD_VER) + ssl3_init_finished_mac(s); + break; + +#ifndef OPENSSL_NO_SCTP + case DTLS1_SCTP_ST_SR_READ_SOCK: + + if (BIO_dgram_sctp_msg_waiting(SSL_get_rbio(s))) { + s->s3->in_read_app_data = 2; + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + ret = -1; + goto end; + } + + s->state = SSL3_ST_SR_FINISHED_A; + break; + + case DTLS1_SCTP_ST_SW_WRITE_SOCK: + ret = BIO_dgram_sctp_wait_for_dry(SSL_get_wbio(s)); + if (ret < 0) + goto end; + + if (ret == 0) { + if (s->d1->next_state != SSL_ST_OK) { + s->s3->in_read_app_data = 2; + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + ret = -1; + goto end; + } + } + + s->state = s->d1->next_state; + break; +#endif + + case SSL3_ST_SW_SRVR_HELLO_A: + case SSL3_ST_SW_SRVR_HELLO_B: + s->renegotiate = 2; + dtls1_start_timer(s); + ret = dtls1_send_server_hello(s); + if (ret <= 0) + goto end; + + if (s->hit) { +#ifndef OPENSSL_NO_SCTP + /* + * Add new shared key for SCTP-Auth, will be ignored if no + * SCTP used. + */ + snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), + DTLS1_SCTP_AUTH_LABEL); + + if (SSL_export_keying_material(s, sctpauthkey, + sizeof(sctpauthkey), labelbuffer, + sizeof(labelbuffer), NULL, 0, 0) <= 0) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, + sizeof(sctpauthkey), sctpauthkey); +#endif +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_ticket_expected) + s->state = SSL3_ST_SW_SESSION_TICKET_A; + else + s->state = SSL3_ST_SW_CHANGE_A; +#else + s->state = SSL3_ST_SW_CHANGE_A; +#endif + } else + s->state = SSL3_ST_SW_CERT_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_A: + case SSL3_ST_SW_CERT_B: + /* Check if it is anon DH or normal PSK */ + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + dtls1_start_timer(s); + ret = dtls1_send_server_certificate(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_status_expected) + s->state = SSL3_ST_SW_CERT_STATUS_A; + else + s->state = SSL3_ST_SW_KEY_EXCH_A; + } else { + skip = 1; + s->state = SSL3_ST_SW_KEY_EXCH_A; + } +#else + } else + skip = 1; + + s->state = SSL3_ST_SW_KEY_EXCH_A; +#endif + s->init_num = 0; + break; + + case SSL3_ST_SW_KEY_EXCH_A: + case SSL3_ST_SW_KEY_EXCH_B: + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + /* + * clear this, it may get reset by + * send_server_key_exchange + */ + s->s3->tmp.use_rsa_tmp = 0; + + /* + * only send if a DH key exchange or RSA but we have a sign only + * certificate + */ + if (0 + /* + * PSK: send ServerKeyExchange if PSK identity hint if + * provided + */ +#ifndef OPENSSL_NO_PSK + || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) +#endif + || (alg_k & SSL_kEDH) + || (alg_k & SSL_kEECDH) + || ((alg_k & SSL_kRSA) + && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL + || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) + && EVP_PKEY_size(s->cert->pkeys + [SSL_PKEY_RSA_ENC].privatekey) * + 8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) + ) + ) + ) + ) { + dtls1_start_timer(s); + ret = dtls1_send_server_key_exchange(s); + if (ret <= 0) + goto end; + } else + skip = 1; + + s->state = SSL3_ST_SW_CERT_REQ_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_REQ_A: + case SSL3_ST_SW_CERT_REQ_B: + if ( /* don't request cert unless asked for it: */ + !(s->verify_mode & SSL_VERIFY_PEER) || + /* + * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert + * during re-negotiation: + */ + ((s->session->peer != NULL) && + (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || + /* + * never request cert in anonymous ciphersuites (see + * section "Certificate request" in SSL 3 drafts and in + * RFC 2246): + */ + ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && + /* + * ... except when the application insists on + * verification (against the specs, but s3_clnt.c accepts + * this for SSL 3) + */ + !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || + /* + * never request cert in Kerberos ciphersuites + */ + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) + /* + * With normal PSK Certificates and Certificate Requests + * are omitted + */ + || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + /* no cert request */ + skip = 1; + s->s3->tmp.cert_request = 0; + s->state = SSL3_ST_SW_SRVR_DONE_A; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A; + s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK; + } +#endif + } else { + s->s3->tmp.cert_request = 1; + dtls1_start_timer(s); + ret = dtls1_send_certificate_request(s); + if (ret <= 0) + goto end; +#ifndef NETSCAPE_HANG_BUG + s->state = SSL3_ST_SW_SRVR_DONE_A; +# ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = SSL3_ST_SW_SRVR_DONE_A; + s->state = DTLS1_SCTP_ST_SW_WRITE_SOCK; + } +# endif +#else + s->state = SSL3_ST_SW_FLUSH; + s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; +# ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = s->s3->tmp.next_state; + s->s3->tmp.next_state = DTLS1_SCTP_ST_SW_WRITE_SOCK; + } +# endif +#endif + s->init_num = 0; + } + break; + + case SSL3_ST_SW_SRVR_DONE_A: + case SSL3_ST_SW_SRVR_DONE_B: + dtls1_start_timer(s); + ret = dtls1_send_server_done(s); + if (ret <= 0) + goto end; + s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; + s->state = SSL3_ST_SW_FLUSH; + s->init_num = 0; + break; + + case SSL3_ST_SW_FLUSH: + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + /* + * If the write error was fatal, stop trying + */ + if (!BIO_should_retry(s->wbio)) { + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + } + + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + break; + + case SSL3_ST_SR_CERT_A: + case SSL3_ST_SR_CERT_B: + /* Check for second client hello (MS SGC) */ + ret = ssl3_check_client_hello(s); + if (ret <= 0) + goto end; + if (ret == 2) { + dtls1_stop_timer(s); + s->state = SSL3_ST_SR_CLNT_HELLO_C; + } else { + if (s->s3->tmp.cert_request) { + ret = ssl3_get_client_certificate(s); + if (ret <= 0) + goto end; + } + s->init_num = 0; + s->state = SSL3_ST_SR_KEY_EXCH_A; + } + break; + + case SSL3_ST_SR_KEY_EXCH_A: + case SSL3_ST_SR_KEY_EXCH_B: + ret = ssl3_get_client_key_exchange(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_SCTP + /* + * Add new shared key for SCTP-Auth, will be ignored if no SCTP + * used. + */ + snprintf((char *)labelbuffer, sizeof(DTLS1_SCTP_AUTH_LABEL), + DTLS1_SCTP_AUTH_LABEL); + + if (SSL_export_keying_material(s, sctpauthkey, + sizeof(sctpauthkey), labelbuffer, + sizeof(labelbuffer), NULL, 0, 0) <= 0) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_ADD_AUTH_KEY, + sizeof(sctpauthkey), sctpauthkey); +#endif + + s->state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + + if (ret == 2) { + /* + * For the ECDH ciphersuites when the client sends its ECDH + * pub key in a certificate, the CertificateVerify message is + * not sent. + */ + s->state = SSL3_ST_SR_FINISHED_A; + s->init_num = 0; + } else { + s->state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + + /* + * We need to get hashes here so if there is a client cert, + * it can be verified + */ + s->method->ssl3_enc->cert_verify_mac(s, + NID_md5, + &(s->s3-> + tmp.cert_verify_md + [0])); + s->method->ssl3_enc->cert_verify_mac(s, NID_sha1, + &(s->s3-> + tmp.cert_verify_md + [MD5_DIGEST_LENGTH])); + } + break; + + case SSL3_ST_SR_CERT_VRFY_A: + case SSL3_ST_SR_CERT_VRFY_B: + ret = ssl3_get_cert_verify(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s)) && + state == SSL_ST_RENEGOTIATE) + s->state = DTLS1_SCTP_ST_SR_READ_SOCK; + else +#endif + s->state = SSL3_ST_SR_FINISHED_A; + s->init_num = 0; + break; + + case SSL3_ST_SR_FINISHED_A: + case SSL3_ST_SR_FINISHED_B: + /* + * Enable CCS. Receiving a CCS clears the flag, so make + * sure not to re-enable it to ban duplicates. This *should* be the + * first time we have received one - but we check anyway to be + * cautious. + * s->s3->change_cipher_spec is set when a CCS is + * processed in d1_pkt.c, and remains set until + * the client's Finished message is read. + */ + if (!s->s3->change_cipher_spec) + s->d1->change_cipher_spec_ok = 1; + ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, + SSL3_ST_SR_FINISHED_B); + if (ret <= 0) + goto end; + dtls1_stop_timer(s); + if (s->hit) + s->state = SSL_ST_OK; +#ifndef OPENSSL_NO_TLSEXT + else if (s->tlsext_ticket_expected) + s->state = SSL3_ST_SW_SESSION_TICKET_A; +#endif + else + s->state = SSL3_ST_SW_CHANGE_A; + s->init_num = 0; + break; + +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_SW_SESSION_TICKET_A: + case SSL3_ST_SW_SESSION_TICKET_B: + ret = dtls1_send_newsession_ticket(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_CHANGE_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_STATUS_A: + case SSL3_ST_SW_CERT_STATUS_B: + ret = ssl3_send_cert_status(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_KEY_EXCH_A; + s->init_num = 0; + break; + +#endif + + case SSL3_ST_SW_CHANGE_A: + case SSL3_ST_SW_CHANGE_B: + + s->session->cipher = s->s3->tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + ret = dtls1_send_change_cipher_spec(s, + SSL3_ST_SW_CHANGE_A, + SSL3_ST_SW_CHANGE_B); + + if (ret <= 0) + goto end; + +#ifndef OPENSSL_NO_SCTP + if (!s->hit) { + /* + * Change to new shared key of SCTP-Auth, will be ignored if + * no SCTP used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, + 0, NULL); + } +#endif + + s->state = SSL3_ST_SW_FINISHED_A; + s->init_num = 0; + + if (!s->method->ssl3_enc->change_cipher_state(s, + SSL3_CHANGE_CIPHER_SERVER_WRITE)) + { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + dtls1_reset_seq_numbers(s, SSL3_CC_WRITE); + break; + + case SSL3_ST_SW_FINISHED_A: + case SSL3_ST_SW_FINISHED_B: + ret = dtls1_send_finished(s, + SSL3_ST_SW_FINISHED_A, + SSL3_ST_SW_FINISHED_B, + s->method-> + ssl3_enc->server_finished_label, + s->method-> + ssl3_enc->server_finished_label_len); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_FLUSH; + if (s->hit) { + s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; + +#ifndef OPENSSL_NO_SCTP + /* + * Change to new shared key of SCTP-Auth, will be ignored if + * no SCTP used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_NEXT_AUTH_KEY, + 0, NULL); +#endif + } else { + s->s3->tmp.next_state = SSL_ST_OK; +#ifndef OPENSSL_NO_SCTP + if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { + s->d1->next_state = s->s3->tmp.next_state; + s->s3->tmp.next_state = DTLS1_SCTP_ST_SW_WRITE_SOCK; + } +#endif + } + s->init_num = 0; + break; + + case SSL_ST_OK: + /* clean a few things up */ + ssl3_cleanup_key_block(s); + +#if 0 + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; +#endif + + /* remove buffering on output */ + ssl_free_wbio_buffer(s); + + s->init_num = 0; + + if (s->renegotiate == 2) { /* skipped if we just sent a + * HelloRequest */ + s->renegotiate = 0; + s->new_session = 0; + + ssl_update_cache(s, SSL_SESS_CACHE_SERVER); + + s->ctx->stats.sess_accept_good++; + /* s->server=1; */ + s->handshake_func = dtls1_accept; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + } + + ret = 1; + + /* done handshaking, next message is client hello */ + s->d1->handshake_read_seq = 0; + /* next message is server hello */ + s->d1->handshake_write_seq = 0; + s->d1->next_handshake_write_seq = 0; + goto end; + /* break; */ + + case SSL_ST_ERR: + default: + SSLerr(SSL_F_DTLS1_ACCEPT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + if (!s->s3->tmp.reuse_message && !skip) { + if (s->debug) { + if ((ret = BIO_flush(s->wbio)) <= 0) + goto end; + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_ACCEPT_LOOP, 1); + s->state = new_state; + } + } + skip = 0; + } + end: + /* BIO_flush(s->wbio); */ + + s->in_handshake--; +#ifndef OPENSSL_NO_SCTP + /* + * Notify SCTP BIO socket to leave handshake mode and prevent stream + * identifier other than 0. Will be ignored if no SCTP is used. + */ + BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_SCTP_SET_IN_HANDSHAKE, + s->in_handshake, NULL); +#endif + + if (cb != NULL) + cb(s, SSL_CB_ACCEPT_EXIT, ret); + return (ret); +} + +int dtls1_send_hello_request(SSL *s) +{ + unsigned char *p; + + if (s->state == SSL3_ST_SW_HELLO_REQ_A) { + p = (unsigned char *)s->init_buf->data; + p = dtls1_set_message_header(s, p, SSL3_MT_HELLO_REQUEST, 0, 0, 0); + + s->state = SSL3_ST_SW_HELLO_REQ_B; + /* number of bytes to write */ + s->init_num = DTLS1_HM_HEADER_LENGTH; + s->init_off = 0; + + /* + * no need to buffer this message, since there are no retransmit + * requests for it + */ + } + + /* SSL3_ST_SW_HELLO_REQ_B */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); +} + +int dtls1_send_hello_verify_request(SSL *s) +{ + unsigned int msg_len; + unsigned char *msg, *buf, *p; + + if (s->state == DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A) { + buf = (unsigned char *)s->init_buf->data; + + msg = p = &(buf[DTLS1_HM_HEADER_LENGTH]); + *(p++) = s->version >> 8; + *(p++) = s->version & 0xFF; + + if (s->ctx->app_gen_cookie_cb == NULL || + s->ctx->app_gen_cookie_cb(s, s->d1->cookie, + &(s->d1->cookie_len)) == 0) { + SSLerr(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST, + ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return 0; + } + + *(p++) = (unsigned char)s->d1->cookie_len; + memcpy(p, s->d1->cookie, s->d1->cookie_len); + p += s->d1->cookie_len; + msg_len = p - msg; + + dtls1_set_message_header(s, buf, + DTLS1_MT_HELLO_VERIFY_REQUEST, msg_len, 0, + msg_len); + + s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B; + /* number of bytes to write */ + s->init_num = p - buf; + s->init_off = 0; + } + + /* s->state = DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); +} + +int dtls1_send_server_hello(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; + int i; + unsigned int sl; + unsigned long l; + + if (s->state == SSL3_ST_SW_SRVR_HELLO_A) { + buf = (unsigned char *)s->init_buf->data; + p = s->s3->server_random; + ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE); + /* Do the message type and length last */ + d = p = &(buf[DTLS1_HM_HEADER_LENGTH]); + + *(p++) = s->version >> 8; + *(p++) = s->version & 0xff; + + /* Random stuff */ + memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /* + * now in theory we have 3 options to sending back the session id. + * If it is a re-use, we send back the old session-id, if it is a new + * session, we send back the new session-id or we send back a 0 + * length session-id if we want it to be single use. Currently I will + * not implement the '0' length session-id 12-Jan-98 - I'll now + * support the '0' length stuff. + */ + if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)) + s->session->session_id_length = 0; + + sl = s->session->session_id_length; + if (sl > sizeof s->session->session_id) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + return -1; + } + *(p++) = sl; + memcpy(p, s->session->session_id, sl); + p += sl; + + /* put the cipher */ + if (s->s3->tmp.new_cipher == NULL) + return -1; + i = ssl3_put_cipher_by_char(s->s3->tmp.new_cipher, p); + p += i; + + /* put the compression method */ +#ifdef OPENSSL_NO_COMP + *(p++) = 0; +#else + if (s->s3->tmp.new_compression == NULL) + *(p++) = 0; + else + *(p++) = s->s3->tmp.new_compression->id; +#endif + +#ifndef OPENSSL_NO_TLSEXT + if (ssl_prepare_serverhello_tlsext(s) <= 0) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT); + return -1; + } + if ((p = + ssl_add_serverhello_tlsext(s, p, + buf + SSL3_RT_MAX_PLAIN_LENGTH)) == + NULL) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + return -1; + } +#endif + + /* do the header */ + l = (p - d); + d = buf; + + d = dtls1_set_message_header(s, d, SSL3_MT_SERVER_HELLO, l, 0, l); + + s->state = SSL3_ST_SW_SRVR_HELLO_B; + /* number of bytes to write */ + s->init_num = p - buf; + s->init_off = 0; + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); + } + + /* SSL3_ST_SW_SRVR_HELLO_B */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); +} + +int dtls1_send_server_done(SSL *s) +{ + unsigned char *p; + + if (s->state == SSL3_ST_SW_SRVR_DONE_A) { + p = (unsigned char *)s->init_buf->data; + + /* do the header */ + p = dtls1_set_message_header(s, p, SSL3_MT_SERVER_DONE, 0, 0, 0); + + s->state = SSL3_ST_SW_SRVR_DONE_B; + /* number of bytes to write */ + s->init_num = DTLS1_HM_HEADER_LENGTH; + s->init_off = 0; + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); + } + + /* SSL3_ST_SW_SRVR_DONE_B */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); +} + +int dtls1_send_server_key_exchange(SSL *s) +{ +#ifndef OPENSSL_NO_RSA + unsigned char *q; + int j, num; + RSA *rsa; + unsigned char md_buf[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; + unsigned int u; +#endif +#ifndef OPENSSL_NO_DH + DH *dh = NULL, *dhp; +#endif +#ifndef OPENSSL_NO_ECDH + EC_KEY *ecdh = NULL, *ecdhp; + unsigned char *encodedPoint = NULL; + int encodedlen = 0; + int curve_id = 0; + BN_CTX *bn_ctx = NULL; +#endif + EVP_PKEY *pkey; + unsigned char *p, *d; + int al, i; + unsigned long type; + int n; + CERT *cert; + BIGNUM *r[4]; + int nr[4], kn; + BUF_MEM *buf; + EVP_MD_CTX md_ctx; + + EVP_MD_CTX_init(&md_ctx); + if (s->state == SSL3_ST_SW_KEY_EXCH_A) { + type = s->s3->tmp.new_cipher->algorithm_mkey; + cert = s->cert; + + buf = s->init_buf; + + r[0] = r[1] = r[2] = r[3] = NULL; + n = 0; +#ifndef OPENSSL_NO_RSA + if (type & SSL_kRSA) { + rsa = cert->rsa_tmp; + if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) { + rsa = s->cert->rsa_tmp_cb(s, + SSL_C_IS_EXPORT(s->s3-> + tmp.new_cipher), + SSL_C_EXPORT_PKEYLENGTH(s->s3-> + tmp.new_cipher)); + if (rsa == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + SSL_R_ERROR_GENERATING_TMP_RSA_KEY); + goto f_err; + } + RSA_up_ref(rsa); + cert->rsa_tmp = rsa; + } + if (rsa == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + SSL_R_MISSING_TMP_RSA_KEY); + goto f_err; + } + r[0] = rsa->n; + r[1] = rsa->e; + s->s3->tmp.use_rsa_tmp = 1; + } else +#endif +#ifndef OPENSSL_NO_DH + if (type & SSL_kEDH) { + dhp = cert->dh_tmp; + if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL)) + dhp = s->cert->dh_tmp_cb(s, + SSL_C_IS_EXPORT(s->s3-> + tmp.new_cipher), + SSL_C_EXPORT_PKEYLENGTH(s->s3-> + tmp.new_cipher)); + if (dhp == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + SSL_R_MISSING_TMP_DH_KEY); + goto f_err; + } + + if (s->s3->tmp.dh != NULL) { + DH_free(dh); + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if ((dh = DHparams_dup(dhp)) == NULL) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + + s->s3->tmp.dh = dh; + if ((dhp->pub_key == NULL || + dhp->priv_key == NULL || + (s->options & SSL_OP_SINGLE_DH_USE))) { + if (!DH_generate_key(dh)) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + ERR_R_DH_LIB); + goto err; + } + } else { + dh->pub_key = BN_dup(dhp->pub_key); + dh->priv_key = BN_dup(dhp->priv_key); + if ((dh->pub_key == NULL) || (dh->priv_key == NULL)) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + ERR_R_DH_LIB); + goto err; + } + } + r[0] = dh->p; + r[1] = dh->g; + r[2] = dh->pub_key; + } else +#endif +#ifndef OPENSSL_NO_ECDH + if (type & SSL_kEECDH) { + const EC_GROUP *group; + + ecdhp = cert->ecdh_tmp; + if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL)) { + ecdhp = s->cert->ecdh_tmp_cb(s, + SSL_C_IS_EXPORT(s->s3-> + tmp.new_cipher), + SSL_C_EXPORT_PKEYLENGTH(s-> + s3->tmp.new_cipher)); + } + if (ecdhp == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + SSL_R_MISSING_TMP_ECDH_KEY); + goto f_err; + } + + if (s->s3->tmp.ecdh != NULL) { + EC_KEY_free(s->s3->tmp.ecdh); + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + /* Duplicate the ECDH structure. */ + if (ecdhp == NULL) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + s->s3->tmp.ecdh = ecdh; + if ((EC_KEY_get0_public_key(ecdh) == NULL) || + (EC_KEY_get0_private_key(ecdh) == NULL) || + (s->options & SSL_OP_SINGLE_ECDH_USE)) { + if (!EC_KEY_generate_key(ecdh)) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + } + + if (((group = EC_KEY_get0_group(ecdh)) == NULL) || + (EC_KEY_get0_public_key(ecdh) == NULL) || + (EC_KEY_get0_private_key(ecdh) == NULL)) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && + (EC_GROUP_get_degree(group) > 163)) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); + goto err; + } + + /* + * XXX: For now, we only support ephemeral ECDH keys over named + * (not generic) curves. For supported named curves, curve_id is + * non-zero. + */ + if ((curve_id = + tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group))) + == 0) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + goto err; + } + + /* + * Encode the public key. First check the size of encoding and + * allocate memory accordingly. + */ + encodedlen = EC_POINT_point2oct(group, + EC_KEY_get0_public_key(ecdh), + POINT_CONVERSION_UNCOMPRESSED, + NULL, 0, NULL); + + encodedPoint = (unsigned char *) + OPENSSL_malloc(encodedlen * sizeof(unsigned char)); + bn_ctx = BN_CTX_new(); + if ((encodedPoint == NULL) || (bn_ctx == NULL)) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + encodedlen = EC_POINT_point2oct(group, + EC_KEY_get0_public_key(ecdh), + POINT_CONVERSION_UNCOMPRESSED, + encodedPoint, encodedlen, bn_ctx); + + if (encodedlen == 0) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + BN_CTX_free(bn_ctx); + bn_ctx = NULL; + + /* + * XXX: For now, we only support named (not generic) curves in + * ECDH ephemeral key exchanges. In this situation, we need four + * additional bytes to encode the entire ServerECDHParams + * structure. + */ + n = 4 + encodedlen; + + /* + * We'll generate the serverKeyExchange message explicitly so we + * can set these to NULLs + */ + r[0] = NULL; + r[1] = NULL; + r[2] = NULL; + r[3] = NULL; + } else +#endif /* !OPENSSL_NO_ECDH */ +#ifndef OPENSSL_NO_PSK + if (type & SSL_kPSK) { + /* + * reserve size for record length and PSK identity hint + */ + n += 2 + strlen(s->ctx->psk_identity_hint); + } else +#endif /* !OPENSSL_NO_PSK */ + { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); + goto f_err; + } + for (i = 0; r[i] != NULL; i++) { + nr[i] = BN_num_bytes(r[i]); + n += 2 + nr[i]; + } + + if (!(s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + if ((pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher, NULL)) + == NULL) { + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + kn = EVP_PKEY_size(pkey); + } else { + pkey = NULL; + kn = 0; + } + + if (!BUF_MEM_grow_clean(buf, n + DTLS1_HM_HEADER_LENGTH + kn)) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_BUF); + goto err; + } + d = (unsigned char *)s->init_buf->data; + p = &(d[DTLS1_HM_HEADER_LENGTH]); + + for (i = 0; r[i] != NULL; i++) { + s2n(nr[i], p); + BN_bn2bin(r[i], p); + p += nr[i]; + } + +#ifndef OPENSSL_NO_ECDH + if (type & SSL_kEECDH) { + /* + * XXX: For now, we only support named (not generic) curves. In + * this situation, the serverKeyExchange message has: [1 byte + * CurveType], [2 byte CurveName] [1 byte length of encoded + * point], followed by the actual encoded point itself + */ + *p = NAMED_CURVE_TYPE; + p += 1; + *p = 0; + p += 1; + *p = curve_id; + p += 1; + *p = encodedlen; + p += 1; + memcpy((unsigned char *)p, + (unsigned char *)encodedPoint, encodedlen); + OPENSSL_free(encodedPoint); + encodedPoint = NULL; + p += encodedlen; + } +#endif + +#ifndef OPENSSL_NO_PSK + if (type & SSL_kPSK) { + /* copy PSK identity hint */ + s2n(strlen(s->ctx->psk_identity_hint), p); + strncpy((char *)p, s->ctx->psk_identity_hint, + strlen(s->ctx->psk_identity_hint)); + p += strlen(s->ctx->psk_identity_hint); + } +#endif + + /* not anonymous */ + if (pkey != NULL) { + /* + * n is the length of the params, they start at + * &(d[DTLS1_HM_HEADER_LENGTH]) and p points to the space at the + * end. + */ +#ifndef OPENSSL_NO_RSA + if (pkey->type == EVP_PKEY_RSA) { + q = md_buf; + j = 0; + for (num = 2; num > 0; num--) { + EVP_DigestInit_ex(&md_ctx, (num == 2) + ? s->ctx->md5 : s->ctx->sha1, NULL); + EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]), + SSL3_RANDOM_SIZE); + EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]), + SSL3_RANDOM_SIZE); + EVP_DigestUpdate(&md_ctx, &(d[DTLS1_HM_HEADER_LENGTH]), + n); + EVP_DigestFinal_ex(&md_ctx, q, (unsigned int *)&i); + q += i; + j += i; + } + if (RSA_sign(NID_md5_sha1, md_buf, j, + &(p[2]), &u, pkey->pkey.rsa) <= 0) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_RSA); + goto err; + } + s2n(u, p); + n += u + 2; + } else +#endif +#if !defined(OPENSSL_NO_DSA) + if (pkey->type == EVP_PKEY_DSA) { + /* lets do DSS */ + EVP_SignInit_ex(&md_ctx, EVP_dss1(), NULL); + EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]), + SSL3_RANDOM_SIZE); + EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]), + SSL3_RANDOM_SIZE); + EVP_SignUpdate(&md_ctx, &(d[DTLS1_HM_HEADER_LENGTH]), n); + if (!EVP_SignFinal(&md_ctx, &(p[2]), + (unsigned int *)&i, pkey)) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_DSA); + goto err; + } + s2n(i, p); + n += i + 2; + } else +#endif +#if !defined(OPENSSL_NO_ECDSA) + if (pkey->type == EVP_PKEY_EC) { + /* let's do ECDSA */ + EVP_SignInit_ex(&md_ctx, EVP_ecdsa(), NULL); + EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]), + SSL3_RANDOM_SIZE); + EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]), + SSL3_RANDOM_SIZE); + EVP_SignUpdate(&md_ctx, &(d[DTLS1_HM_HEADER_LENGTH]), n); + if (!EVP_SignFinal(&md_ctx, &(p[2]), + (unsigned int *)&i, pkey)) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + ERR_LIB_ECDSA); + goto err; + } + s2n(i, p); + n += i + 2; + } else +#endif + { + /* Is this error check actually needed? */ + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE, + SSL_R_UNKNOWN_PKEY_TYPE); + goto f_err; + } + } + + d = dtls1_set_message_header(s, d, + SSL3_MT_SERVER_KEY_EXCHANGE, n, 0, n); + + /* + * we should now have things packed up, so lets send it off + */ + s->init_num = n + DTLS1_HM_HEADER_LENGTH; + s->init_off = 0; + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); + } + + s->state = SSL3_ST_SW_KEY_EXCH_B; + EVP_MD_CTX_cleanup(&md_ctx); + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: +#ifndef OPENSSL_NO_ECDH + if (encodedPoint != NULL) + OPENSSL_free(encodedPoint); + BN_CTX_free(bn_ctx); +#endif + EVP_MD_CTX_cleanup(&md_ctx); + return (-1); +} + +int dtls1_send_certificate_request(SSL *s) +{ + unsigned char *p, *d; + int i, j, nl, off, n; + STACK_OF(X509_NAME) *sk = NULL; + X509_NAME *name; + BUF_MEM *buf; + unsigned int msg_len; + + if (s->state == SSL3_ST_SW_CERT_REQ_A) { + buf = s->init_buf; + + d = p = (unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH]); + + /* get the list of acceptable cert types */ + p++; + n = ssl3_get_req_cert_type(s, p); + d[0] = n; + p += n; + n++; + + off = n; + p += 2; + n += 2; + + sk = SSL_get_client_CA_list(s); + nl = 0; + if (sk != NULL) { + for (i = 0; i < sk_X509_NAME_num(sk); i++) { + name = sk_X509_NAME_value(sk, i); + j = i2d_X509_NAME(name, NULL); + if (!BUF_MEM_grow_clean + (buf, DTLS1_HM_HEADER_LENGTH + n + j + 2)) { + SSLerr(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST, + ERR_R_BUF_LIB); + goto err; + } + p = (unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH + n]); + if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) { + s2n(j, p); + i2d_X509_NAME(name, &p); + n += 2 + j; + nl += 2 + j; + } else { + d = p; + i2d_X509_NAME(name, &p); + j -= 2; + s2n(j, d); + j += 2; + n += j; + nl += j; + } + } + } + /* else no CA names */ + p = (unsigned char *)&(buf->data[DTLS1_HM_HEADER_LENGTH + off]); + s2n(nl, p); + + d = (unsigned char *)buf->data; + *(d++) = SSL3_MT_CERTIFICATE_REQUEST; + l2n3(n, d); + s2n(s->d1->handshake_write_seq, d); + s->d1->handshake_write_seq++; + + /* + * we should now have things packed up, so lets send it off + */ + + s->init_num = n + DTLS1_HM_HEADER_LENGTH; + s->init_off = 0; +#ifdef NETSCAPE_HANG_BUG +/* XXX: what to do about this? */ + p = (unsigned char *)s->init_buf->data + s->init_num; + + /* do the header */ + *(p++) = SSL3_MT_SERVER_DONE; + *(p++) = 0; + *(p++) = 0; + *(p++) = 0; + s->init_num += 4; +#endif + + /* XDTLS: set message header ? */ + msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH; + dtls1_set_message_header(s, (void *)s->init_buf->data, + SSL3_MT_CERTIFICATE_REQUEST, msg_len, 0, + msg_len); + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); + + s->state = SSL3_ST_SW_CERT_REQ_B; + } + + /* SSL3_ST_SW_CERT_REQ_B */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); + err: + return (-1); +} + +int dtls1_send_server_certificate(SSL *s) +{ + unsigned long l; + X509 *x; + + if (s->state == SSL3_ST_SW_CERT_A) { + x = ssl_get_server_send_cert(s); + if (x == NULL) { + /* VRS: allow null cert if auth == KRB5 */ + if ((s->s3->tmp.new_cipher->algorithm_mkey != SSL_kKRB5) || + (s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5)) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE, + ERR_R_INTERNAL_ERROR); + return (0); + } + } + + l = dtls1_output_cert_chain(s, x); + if (!l) { + SSLerr(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); + return (0); + } + s->state = SSL3_ST_SW_CERT_B; + s->init_num = (int)l; + s->init_off = 0; + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); + } + + /* SSL3_ST_SW_CERT_B */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); +} + +#ifndef OPENSSL_NO_TLSEXT +int dtls1_send_newsession_ticket(SSL *s) +{ + if (s->state == SSL3_ST_SW_SESSION_TICKET_A) { + unsigned char *p, *senc, *macstart; + int len, slen; + unsigned int hlen, msg_len; + EVP_CIPHER_CTX ctx; + HMAC_CTX hctx; + SSL_CTX *tctx = s->initial_ctx; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char key_name[16]; + + /* get session encoding length */ + slen = i2d_SSL_SESSION(s->session, NULL); + /* + * Some length values are 16 bits, so forget it if session is too + * long + */ + if (slen > 0xFF00) + return -1; + /* + * Grow buffer if need be: the length calculation is as follows 12 + * (DTLS handshake message header) + 4 (ticket lifetime hint) + 2 + * (ticket length) + 16 (key name) + max_iv_len (iv length) + + * session_length + max_enc_block_size (max encrypted session length) + * + max_md_size (HMAC). + */ + if (!BUF_MEM_grow(s->init_buf, + DTLS1_HM_HEADER_LENGTH + 22 + EVP_MAX_IV_LENGTH + + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE + slen)) + return -1; + senc = OPENSSL_malloc(slen); + if (!senc) + return -1; + p = senc; + i2d_SSL_SESSION(s->session, &p); + + p = (unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]); + EVP_CIPHER_CTX_init(&ctx); + HMAC_CTX_init(&hctx); + /* + * Initialize HMAC and cipher contexts. If callback present it does + * all the work otherwise use generated values from parent ctx. + */ + if (tctx->tlsext_ticket_key_cb) { + if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, + &hctx, 1) < 0) { + OPENSSL_free(senc); + return -1; + } + } else { + RAND_pseudo_bytes(iv, 16); + EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, + tctx->tlsext_tick_aes_key, iv); + HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, + tlsext_tick_md(), NULL); + memcpy(key_name, tctx->tlsext_tick_key_name, 16); + } + l2n(s->session->tlsext_tick_lifetime_hint, p); + /* Skip ticket length for now */ + p += 2; + /* Output key name */ + macstart = p; + memcpy(p, key_name, 16); + p += 16; + /* output IV */ + memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx)); + p += EVP_CIPHER_CTX_iv_length(&ctx); + /* Encrypt session data */ + EVP_EncryptUpdate(&ctx, p, &len, senc, slen); + p += len; + EVP_EncryptFinal(&ctx, p, &len); + p += len; + EVP_CIPHER_CTX_cleanup(&ctx); + + HMAC_Update(&hctx, macstart, p - macstart); + HMAC_Final(&hctx, p, &hlen); + HMAC_CTX_cleanup(&hctx); + + p += hlen; + /* Now write out lengths: p points to end of data written */ + /* Total length */ + len = p - (unsigned char *)(s->init_buf->data); + /* Ticket length */ + p = (unsigned char *)&(s->init_buf->data[DTLS1_HM_HEADER_LENGTH]) + 4; + s2n(len - DTLS1_HM_HEADER_LENGTH - 6, p); + + /* number of bytes to write */ + s->init_num = len; + s->state = SSL3_ST_SW_SESSION_TICKET_B; + s->init_off = 0; + OPENSSL_free(senc); + + /* XDTLS: set message header ? */ + msg_len = s->init_num - DTLS1_HM_HEADER_LENGTH; + dtls1_set_message_header(s, (void *)s->init_buf->data, + SSL3_MT_NEWSESSION_TICKET, msg_len, 0, + msg_len); + + /* buffer the message to handle re-xmits */ + dtls1_buffer_message(s, 0); + } + + /* SSL3_ST_SW_SESSION_TICKET_B */ + return (dtls1_do_write(s, SSL3_RT_HANDSHAKE)); +} +#endif diff --git a/libs/openssl/ssl/kssl.c b/libs/openssl/ssl/kssl.c new file mode 100644 index 00000000..f2839bdc --- /dev/null +++ b/libs/openssl/ssl/kssl.c @@ -0,0 +1,2260 @@ +/* ssl/kssl.c */ +/* + * Written by Vern Staats for the OpenSSL project + * 2000. + */ +/* ==================================================================== + * Copyright (c) 2000 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/*- + * ssl/kssl.c -- Routines to support (& debug) Kerberos5 auth for openssl + * + * 19990701 VRS Started. + * 200011?? Jeffrey Altman, Richard Levitte + * Generalized for Heimdal, Newer MIT, & Win32. + * Integrated into main OpenSSL 0.9.7 snapshots. + * 20010413 Simon Wilkinson, VRS + * Real RFC2712 KerberosWrapper replaces AP_REQ. + */ + +#include + +#include + +#define KRB5_PRIVATE 1 + +#include +#include +#include +#include +#include "kssl_lcl.h" + +#ifndef OPENSSL_NO_KRB5 + +# ifndef ENOMEM +# define ENOMEM KRB5KRB_ERR_GENERIC +# endif + +/* + * When OpenSSL is built on Windows, we do not want to require that + * the Kerberos DLLs be available in order for the OpenSSL DLLs to + * work. Therefore, all Kerberos routines are loaded at run time + * and we do not link to a .LIB file. + */ + +# if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) +/* + * The purpose of the following pre-processor statements is to provide + * compatibility with different releases of MIT Kerberos for Windows. + * All versions up to 1.2 used macros. But macros do not allow for + * a binary compatible interface for DLLs. Therefore, all macros are + * being replaced by function calls. The following code will allow + * an OpenSSL DLL built on Windows to work whether or not the macro + * or function form of the routines are utilized. + */ +# ifdef krb5_cc_get_principal +# define NO_DEF_KRB5_CCACHE +# undef krb5_cc_get_principal +# endif +# define krb5_cc_get_principal kssl_krb5_cc_get_principal + +# define krb5_free_data_contents kssl_krb5_free_data_contents +# define krb5_free_context kssl_krb5_free_context +# define krb5_auth_con_free kssl_krb5_auth_con_free +# define krb5_free_principal kssl_krb5_free_principal +# define krb5_mk_req_extended kssl_krb5_mk_req_extended +# define krb5_get_credentials kssl_krb5_get_credentials +# define krb5_cc_default kssl_krb5_cc_default +# define krb5_sname_to_principal kssl_krb5_sname_to_principal +# define krb5_init_context kssl_krb5_init_context +# define krb5_free_ticket kssl_krb5_free_ticket +# define krb5_rd_req kssl_krb5_rd_req +# define krb5_kt_default kssl_krb5_kt_default +# define krb5_kt_resolve kssl_krb5_kt_resolve +/* macros in mit 1.2.2 and earlier; functions in mit 1.2.3 and greater */ +# ifndef krb5_kt_close +# define krb5_kt_close kssl_krb5_kt_close +# endif /* krb5_kt_close */ +# ifndef krb5_kt_get_entry +# define krb5_kt_get_entry kssl_krb5_kt_get_entry +# endif /* krb5_kt_get_entry */ +# define krb5_auth_con_init kssl_krb5_auth_con_init + +# define krb5_principal_compare kssl_krb5_principal_compare +# define krb5_decrypt_tkt_part kssl_krb5_decrypt_tkt_part +# define krb5_timeofday kssl_krb5_timeofday +# define krb5_rc_default kssl_krb5_rc_default + +# ifdef krb5_rc_initialize +# undef krb5_rc_initialize +# endif +# define krb5_rc_initialize kssl_krb5_rc_initialize + +# ifdef krb5_rc_get_lifespan +# undef krb5_rc_get_lifespan +# endif +# define krb5_rc_get_lifespan kssl_krb5_rc_get_lifespan + +# ifdef krb5_rc_destroy +# undef krb5_rc_destroy +# endif +# define krb5_rc_destroy kssl_krb5_rc_destroy + +# define valid_cksumtype kssl_valid_cksumtype +# define krb5_checksum_size kssl_krb5_checksum_size +# define krb5_kt_free_entry kssl_krb5_kt_free_entry +# define krb5_auth_con_setrcache kssl_krb5_auth_con_setrcache +# define krb5_auth_con_getrcache kssl_krb5_auth_con_getrcache +# define krb5_get_server_rcache kssl_krb5_get_server_rcache + +/* Prototypes for built in stubs */ +void kssl_krb5_free_data_contents(krb5_context, krb5_data *); +void kssl_krb5_free_principal(krb5_context, krb5_principal); +krb5_error_code kssl_krb5_kt_resolve(krb5_context, + krb5_const char *, krb5_keytab *); +krb5_error_code kssl_krb5_kt_default(krb5_context, krb5_keytab *); +krb5_error_code kssl_krb5_free_ticket(krb5_context, krb5_ticket *); +krb5_error_code kssl_krb5_rd_req(krb5_context, krb5_auth_context *, + krb5_const krb5_data *, + krb5_const_principal, krb5_keytab, + krb5_flags *, krb5_ticket **); + +krb5_boolean kssl_krb5_principal_compare(krb5_context, krb5_const_principal, + krb5_const_principal); +krb5_error_code kssl_krb5_mk_req_extended(krb5_context, + krb5_auth_context *, + krb5_const krb5_flags, + krb5_data *, + krb5_creds *, krb5_data *); +krb5_error_code kssl_krb5_init_context(krb5_context *); +void kssl_krb5_free_context(krb5_context); +krb5_error_code kssl_krb5_cc_default(krb5_context, krb5_ccache *); +krb5_error_code kssl_krb5_sname_to_principal(krb5_context, + krb5_const char *, + krb5_const char *, + krb5_int32, krb5_principal *); +krb5_error_code kssl_krb5_get_credentials(krb5_context, + krb5_const krb5_flags, + krb5_ccache, + krb5_creds *, krb5_creds * *); +krb5_error_code kssl_krb5_auth_con_init(krb5_context, krb5_auth_context *); +krb5_error_code kssl_krb5_cc_get_principal(krb5_context context, + krb5_ccache cache, + krb5_principal *principal); +krb5_error_code kssl_krb5_auth_con_free(krb5_context, krb5_auth_context); +size_t kssl_krb5_checksum_size(krb5_context context, krb5_cksumtype ctype); +krb5_boolean kssl_valid_cksumtype(krb5_cksumtype ctype); +krb5_error_code krb5_kt_free_entry(krb5_context, krb5_keytab_entry FAR *); +krb5_error_code kssl_krb5_auth_con_setrcache(krb5_context, + krb5_auth_context, krb5_rcache); +krb5_error_code kssl_krb5_get_server_rcache(krb5_context, + krb5_const krb5_data *, + krb5_rcache *); +krb5_error_code kssl_krb5_auth_con_getrcache(krb5_context, + krb5_auth_context, + krb5_rcache *); + +/* Function pointers (almost all Kerberos functions are _stdcall) */ +static void (_stdcall *p_krb5_free_data_contents) (krb5_context, krb5_data *) + = NULL; +static void (_stdcall *p_krb5_free_principal) (krb5_context, krb5_principal) + = NULL; +static krb5_error_code(_stdcall *p_krb5_kt_resolve) + (krb5_context, krb5_const char *, krb5_keytab *) = NULL; +static krb5_error_code(_stdcall *p_krb5_kt_default) (krb5_context, + krb5_keytab *) = NULL; +static krb5_error_code(_stdcall *p_krb5_free_ticket) (krb5_context, + krb5_ticket *) = NULL; +static krb5_error_code(_stdcall *p_krb5_rd_req) (krb5_context, + krb5_auth_context *, + krb5_const krb5_data *, + krb5_const_principal, + krb5_keytab, krb5_flags *, + krb5_ticket **) = NULL; +static krb5_error_code(_stdcall *p_krb5_mk_req_extended) + (krb5_context, krb5_auth_context *, + krb5_const krb5_flags, krb5_data *, krb5_creds *, krb5_data *) = NULL; +static krb5_error_code(_stdcall *p_krb5_init_context) (krb5_context *) = NULL; +static void (_stdcall *p_krb5_free_context) (krb5_context) = NULL; +static krb5_error_code(_stdcall *p_krb5_cc_default) (krb5_context, + krb5_ccache *) = NULL; +static krb5_error_code(_stdcall *p_krb5_sname_to_principal) + (krb5_context, krb5_const char *, krb5_const char *, + krb5_int32, krb5_principal *) = NULL; +static krb5_error_code(_stdcall *p_krb5_get_credentials) + (krb5_context, krb5_const krb5_flags, krb5_ccache, + krb5_creds *, krb5_creds **) = NULL; +static krb5_error_code(_stdcall *p_krb5_auth_con_init) + (krb5_context, krb5_auth_context *) = NULL; +static krb5_error_code(_stdcall *p_krb5_cc_get_principal) + (krb5_context context, krb5_ccache cache, krb5_principal *principal) = NULL; +static krb5_error_code(_stdcall *p_krb5_auth_con_free) + (krb5_context, krb5_auth_context) = NULL; +static krb5_error_code(_stdcall *p_krb5_decrypt_tkt_part) + (krb5_context, krb5_const krb5_keyblock *, krb5_ticket *) = NULL; +static krb5_error_code(_stdcall *p_krb5_timeofday) + (krb5_context context, krb5_int32 *timeret) = NULL; +static krb5_error_code(_stdcall *p_krb5_rc_default) + (krb5_context context, krb5_rcache *rc) = NULL; +static krb5_error_code(_stdcall *p_krb5_rc_initialize) + (krb5_context context, krb5_rcache rc, krb5_deltat lifespan) = NULL; +static krb5_error_code(_stdcall *p_krb5_rc_get_lifespan) + (krb5_context context, krb5_rcache rc, krb5_deltat *lifespan) = NULL; +static krb5_error_code(_stdcall *p_krb5_rc_destroy) + (krb5_context context, krb5_rcache rc) = NULL; +static krb5_boolean(_stdcall *p_krb5_principal_compare) + (krb5_context, krb5_const_principal, krb5_const_principal) = NULL; +static size_t (_stdcall *p_krb5_checksum_size) (krb5_context context, + krb5_cksumtype ctype) = NULL; +static krb5_boolean(_stdcall *p_valid_cksumtype) (krb5_cksumtype ctype) = + NULL; +static krb5_error_code(_stdcall *p_krb5_kt_free_entry) + (krb5_context, krb5_keytab_entry *) = NULL; +static krb5_error_code(_stdcall *p_krb5_auth_con_setrcache) (krb5_context, + krb5_auth_context, + krb5_rcache) = + NULL; +static krb5_error_code(_stdcall *p_krb5_get_server_rcache) (krb5_context, + krb5_const + krb5_data *, + krb5_rcache *) = + NULL; +static krb5_error_code(*p_krb5_auth_con_getrcache) (krb5_context, + krb5_auth_context, + krb5_rcache *) = NULL; +static krb5_error_code(_stdcall *p_krb5_kt_close) (krb5_context context, + krb5_keytab keytab) = NULL; +static krb5_error_code(_stdcall *p_krb5_kt_get_entry) (krb5_context context, + krb5_keytab keytab, + krb5_const_principal + principal, + krb5_kvno vno, + krb5_enctype enctype, + krb5_keytab_entry + *entry) = NULL; +static int krb5_loaded = 0; /* only attempt to initialize func ptrs once */ + +/* Function to Load the Kerberos 5 DLL and initialize function pointers */ +void load_krb5_dll(void) +{ + HANDLE hKRB5_32; + + krb5_loaded++; + hKRB5_32 = LoadLibrary(TEXT("KRB5_32")); + if (!hKRB5_32) + return; + + (FARPROC) p_krb5_free_data_contents = + GetProcAddress(hKRB5_32, "krb5_free_data_contents"); + (FARPROC) p_krb5_free_context = + GetProcAddress(hKRB5_32, "krb5_free_context"); + (FARPROC) p_krb5_auth_con_free = + GetProcAddress(hKRB5_32, "krb5_auth_con_free"); + (FARPROC) p_krb5_free_principal = + GetProcAddress(hKRB5_32, "krb5_free_principal"); + (FARPROC) p_krb5_mk_req_extended = + GetProcAddress(hKRB5_32, "krb5_mk_req_extended"); + (FARPROC) p_krb5_get_credentials = + GetProcAddress(hKRB5_32, "krb5_get_credentials"); + (FARPROC) p_krb5_cc_get_principal = + GetProcAddress(hKRB5_32, "krb5_cc_get_principal"); + (FARPROC) p_krb5_cc_default = GetProcAddress(hKRB5_32, "krb5_cc_default"); + (FARPROC) p_krb5_sname_to_principal = + GetProcAddress(hKRB5_32, "krb5_sname_to_principal"); + (FARPROC) p_krb5_init_context = + GetProcAddress(hKRB5_32, "krb5_init_context"); + (FARPROC) p_krb5_free_ticket = + GetProcAddress(hKRB5_32, "krb5_free_ticket"); + (FARPROC) p_krb5_rd_req = GetProcAddress(hKRB5_32, "krb5_rd_req"); + (FARPROC) p_krb5_principal_compare = + GetProcAddress(hKRB5_32, "krb5_principal_compare"); + (FARPROC) p_krb5_decrypt_tkt_part = + GetProcAddress(hKRB5_32, "krb5_decrypt_tkt_part"); + (FARPROC) p_krb5_timeofday = GetProcAddress(hKRB5_32, "krb5_timeofday"); + (FARPROC) p_krb5_rc_default = GetProcAddress(hKRB5_32, "krb5_rc_default"); + (FARPROC) p_krb5_rc_initialize = + GetProcAddress(hKRB5_32, "krb5_rc_initialize"); + (FARPROC) p_krb5_rc_get_lifespan = + GetProcAddress(hKRB5_32, "krb5_rc_get_lifespan"); + (FARPROC) p_krb5_rc_destroy = GetProcAddress(hKRB5_32, "krb5_rc_destroy"); + (FARPROC) p_krb5_kt_default = GetProcAddress(hKRB5_32, "krb5_kt_default"); + (FARPROC) p_krb5_kt_resolve = GetProcAddress(hKRB5_32, "krb5_kt_resolve"); + (FARPROC) p_krb5_auth_con_init = + GetProcAddress(hKRB5_32, "krb5_auth_con_init"); + (FARPROC) p_valid_cksumtype = GetProcAddress(hKRB5_32, "valid_cksumtype"); + (FARPROC) p_krb5_checksum_size = + GetProcAddress(hKRB5_32, "krb5_checksum_size"); + (FARPROC) p_krb5_kt_free_entry = + GetProcAddress(hKRB5_32, "krb5_kt_free_entry"); + (FARPROC) p_krb5_auth_con_setrcache = + GetProcAddress(hKRB5_32, "krb5_auth_con_setrcache"); + (FARPROC) p_krb5_get_server_rcache = + GetProcAddress(hKRB5_32, "krb5_get_server_rcache"); + (FARPROC) p_krb5_auth_con_getrcache = + GetProcAddress(hKRB5_32, "krb5_auth_con_getrcache"); + (FARPROC) p_krb5_kt_close = GetProcAddress(hKRB5_32, "krb5_kt_close"); + (FARPROC) p_krb5_kt_get_entry = + GetProcAddress(hKRB5_32, "krb5_kt_get_entry"); +} + +/* Stubs for each function to be dynamicly loaded */ +void kssl_krb5_free_data_contents(krb5_context CO, krb5_data *data) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_free_data_contents) + p_krb5_free_data_contents(CO, data); +} + +krb5_error_code +kssl_krb5_mk_req_extended(krb5_context CO, + krb5_auth_context *pACO, + krb5_const krb5_flags F, + krb5_data *pD1, krb5_creds *pC, krb5_data *pD2) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_mk_req_extended) + return (p_krb5_mk_req_extended(CO, pACO, F, pD1, pC, pD2)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_auth_con_init(krb5_context CO, krb5_auth_context *pACO) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_auth_con_init) + return (p_krb5_auth_con_init(CO, pACO)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_auth_con_free(krb5_context CO, krb5_auth_context ACO) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_auth_con_free) + return (p_krb5_auth_con_free(CO, ACO)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_get_credentials(krb5_context CO, + krb5_const krb5_flags F, + krb5_ccache CC, krb5_creds *pCR, krb5_creds **ppCR) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_get_credentials) + return (p_krb5_get_credentials(CO, F, CC, pCR, ppCR)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_sname_to_principal(krb5_context CO, + krb5_const char *pC1, + krb5_const char *pC2, + krb5_int32 I, krb5_principal *pPR) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_sname_to_principal) + return (p_krb5_sname_to_principal(CO, pC1, pC2, I, pPR)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code kssl_krb5_cc_default(krb5_context CO, krb5_ccache *pCC) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_cc_default) + return (p_krb5_cc_default(CO, pCC)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code kssl_krb5_init_context(krb5_context *pCO) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_init_context) + return (p_krb5_init_context(pCO)); + else + return KRB5KRB_ERR_GENERIC; +} + +void kssl_krb5_free_context(krb5_context CO) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_free_context) + p_krb5_free_context(CO); +} + +void kssl_krb5_free_principal(krb5_context c, krb5_principal p) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_free_principal) + p_krb5_free_principal(c, p); +} + +krb5_error_code +kssl_krb5_kt_resolve(krb5_context con, krb5_const char *sz, krb5_keytab *kt) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_kt_resolve) + return (p_krb5_kt_resolve(con, sz, kt)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code kssl_krb5_kt_default(krb5_context con, krb5_keytab *kt) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_kt_default) + return (p_krb5_kt_default(con, kt)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code kssl_krb5_free_ticket(krb5_context con, krb5_ticket *kt) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_free_ticket) + return (p_krb5_free_ticket(con, kt)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_rd_req(krb5_context con, krb5_auth_context *pacon, + krb5_const krb5_data *data, + krb5_const_principal princ, krb5_keytab keytab, + krb5_flags *flags, krb5_ticket **pptkt) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_rd_req) + return (p_krb5_rd_req(con, pacon, data, princ, keytab, flags, pptkt)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_boolean +krb5_principal_compare(krb5_context con, krb5_const_principal princ1, + krb5_const_principal princ2) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_principal_compare) + return (p_krb5_principal_compare(con, princ1, princ2)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +krb5_decrypt_tkt_part(krb5_context con, krb5_const krb5_keyblock *keys, + krb5_ticket *ticket) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_decrypt_tkt_part) + return (p_krb5_decrypt_tkt_part(con, keys, ticket)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code krb5_timeofday(krb5_context con, krb5_int32 *timeret) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_timeofday) + return (p_krb5_timeofday(con, timeret)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code krb5_rc_default(krb5_context con, krb5_rcache *rc) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_rc_default) + return (p_krb5_rc_default(con, rc)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +krb5_rc_initialize(krb5_context con, krb5_rcache rc, krb5_deltat lifespan) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_rc_initialize) + return (p_krb5_rc_initialize(con, rc, lifespan)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +krb5_rc_get_lifespan(krb5_context con, krb5_rcache rc, krb5_deltat *lifespanp) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_rc_get_lifespan) + return (p_krb5_rc_get_lifespan(con, rc, lifespanp)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code krb5_rc_destroy(krb5_context con, krb5_rcache rc) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_rc_destroy) + return (p_krb5_rc_destroy(con, rc)); + else + return KRB5KRB_ERR_GENERIC; +} + +size_t krb5_checksum_size(krb5_context context, krb5_cksumtype ctype) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_checksum_size) + return (p_krb5_checksum_size(context, ctype)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_boolean valid_cksumtype(krb5_cksumtype ctype) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_valid_cksumtype) + return (p_valid_cksumtype(ctype)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code krb5_kt_free_entry(krb5_context con, krb5_keytab_entry *entry) +{ + if (!krb5_loaded) + load_krb5_dll(); + + if (p_krb5_kt_free_entry) + return (p_krb5_kt_free_entry(con, entry)); + else + return KRB5KRB_ERR_GENERIC; +} + +/* Structure definitions */ +# ifndef NO_DEF_KRB5_CCACHE +# ifndef krb5_x +# define krb5_x(ptr,args) ((ptr)?((*(ptr)) args):(abort(),1)) +# define krb5_xc(ptr,args) ((ptr)?((*(ptr)) args):(abort(),(char*)0)) +# endif + +typedef krb5_pointer krb5_cc_cursor; /* cursor for sequential lookup */ + +typedef struct _krb5_ccache { + krb5_magic magic; + struct _krb5_cc_ops FAR *ops; + krb5_pointer data; +} *krb5_ccache; + +typedef struct _krb5_cc_ops { + krb5_magic magic; + char *prefix; + char *(KRB5_CALLCONV *get_name) + (krb5_context, krb5_ccache); + krb5_error_code(KRB5_CALLCONV *resolve) + (krb5_context, krb5_ccache *, const char *); + krb5_error_code(KRB5_CALLCONV *gen_new) + (krb5_context, krb5_ccache *); + krb5_error_code(KRB5_CALLCONV *init) + (krb5_context, krb5_ccache, krb5_principal); + krb5_error_code(KRB5_CALLCONV *destroy) + (krb5_context, krb5_ccache); + krb5_error_code(KRB5_CALLCONV *close) + (krb5_context, krb5_ccache); + krb5_error_code(KRB5_CALLCONV *store) + (krb5_context, krb5_ccache, krb5_creds *); + krb5_error_code(KRB5_CALLCONV *retrieve) + (krb5_context, krb5_ccache, krb5_flags, krb5_creds *, krb5_creds *); + krb5_error_code(KRB5_CALLCONV *get_princ) + (krb5_context, krb5_ccache, krb5_principal *); + krb5_error_code(KRB5_CALLCONV *get_first) + (krb5_context, krb5_ccache, krb5_cc_cursor *); + krb5_error_code(KRB5_CALLCONV *get_next) + (krb5_context, krb5_ccache, krb5_cc_cursor *, krb5_creds *); + krb5_error_code(KRB5_CALLCONV *end_get) + (krb5_context, krb5_ccache, krb5_cc_cursor *); + krb5_error_code(KRB5_CALLCONV *remove_cred) + (krb5_context, krb5_ccache, krb5_flags, krb5_creds *); + krb5_error_code(KRB5_CALLCONV *set_flags) + (krb5_context, krb5_ccache, krb5_flags); +} krb5_cc_ops; +# endif /* NO_DEF_KRB5_CCACHE */ + +krb5_error_code + kssl_krb5_cc_get_principal + (krb5_context context, krb5_ccache cache, krb5_principal *principal) { + if (p_krb5_cc_get_principal) + return (p_krb5_cc_get_principal(context, cache, principal)); + else + return (krb5_x((cache)->ops->get_princ, (context, cache, principal))); +} + +krb5_error_code +kssl_krb5_auth_con_setrcache(krb5_context con, krb5_auth_context acon, + krb5_rcache rcache) +{ + if (p_krb5_auth_con_setrcache) + return (p_krb5_auth_con_setrcache(con, acon, rcache)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_get_server_rcache(krb5_context con, krb5_const krb5_data *data, + krb5_rcache *rcache) +{ + if (p_krb5_get_server_rcache) + return (p_krb5_get_server_rcache(con, data, rcache)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_auth_con_getrcache(krb5_context con, krb5_auth_context acon, + krb5_rcache *prcache) +{ + if (p_krb5_auth_con_getrcache) + return (p_krb5_auth_con_getrcache(con, acon, prcache)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code kssl_krb5_kt_close(krb5_context context, krb5_keytab keytab) +{ + if (p_krb5_kt_close) + return (p_krb5_kt_close(context, keytab)); + else + return KRB5KRB_ERR_GENERIC; +} + +krb5_error_code +kssl_krb5_kt_get_entry(krb5_context context, krb5_keytab keytab, + krb5_const_principal principal, krb5_kvno vno, + krb5_enctype enctype, krb5_keytab_entry *entry) +{ + if (p_krb5_kt_get_entry) + return (p_krb5_kt_get_entry + (context, keytab, principal, vno, enctype, entry)); + else + return KRB5KRB_ERR_GENERIC; +} +# endif /* OPENSSL_SYS_WINDOWS || OPENSSL_SYS_WIN32 */ + +/* + * memory allocation functions for non-temporary storage (e.g. stuff that + * gets saved into the kssl context) + */ +static void *kssl_calloc(size_t nmemb, size_t size) +{ + void *p; + + p = OPENSSL_malloc(nmemb * size); + if (p) { + memset(p, 0, nmemb * size); + } + return p; +} + +# define kssl_malloc(size) OPENSSL_malloc((size)) +# define kssl_realloc(ptr, size) OPENSSL_realloc(ptr, size) +# define kssl_free(ptr) OPENSSL_free((ptr)) + +char +*kstring(char *string) +{ + static char *null = "[NULL]"; + + return ((string == NULL) ? null : string); +} + +/* + * Given KRB5 enctype (basically DES or 3DES), return closest match openssl + * EVP_ encryption algorithm. Return NULL for unknown or problematic + * (krb5_dk_encrypt) enctypes. Assume ENCTYPE_*_RAW (krb5_raw_encrypt) are + * OK. + */ +const EVP_CIPHER *kssl_map_enc(krb5_enctype enctype) +{ + switch (enctype) { + case ENCTYPE_DES_HMAC_SHA1: /* EVP_des_cbc(); */ + case ENCTYPE_DES_CBC_CRC: + case ENCTYPE_DES_CBC_MD4: + case ENCTYPE_DES_CBC_MD5: + case ENCTYPE_DES_CBC_RAW: + return EVP_des_cbc(); + break; + case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */ + case ENCTYPE_DES3_CBC_SHA: + case ENCTYPE_DES3_CBC_RAW: + return EVP_des_ede3_cbc(); + break; + default: + return NULL; + break; + } +} + +/* + * Return true:1 if p "looks like" the start of the real authenticator + * described in kssl_skip_confound() below. The ASN.1 pattern is "62 xx 30 + * yy" (APPLICATION-2, SEQUENCE), where xx-yy =~ 2, and xx and yy are + * possibly multi-byte length fields. + */ +static int kssl_test_confound(unsigned char *p) +{ + int len = 2; + int xx = 0, yy = 0; + + if (*p++ != 0x62) + return 0; + if (*p > 0x82) + return 0; + switch (*p) { + case 0x82: + p++; + xx = (*p++ << 8); + xx += *p++; + break; + case 0x81: + p++; + xx = *p++; + break; + case 0x80: + return 0; + default: + xx = *p++; + break; + } + if (*p++ != 0x30) + return 0; + if (*p > 0x82) + return 0; + switch (*p) { + case 0x82: + p++; + len += 2; + yy = (*p++ << 8); + yy += *p++; + break; + case 0x81: + p++; + len++; + yy = *p++; + break; + case 0x80: + return 0; + default: + yy = *p++; + break; + } + + return (xx - len == yy) ? 1 : 0; +} + +/* + * Allocate, fill, and return cksumlens array of checksum lengths. This + * array holds just the unique elements from the krb5_cksumarray[]. array[n] + * == 0 signals end of data. The krb5_cksumarray[] was an internal variable + * that has since been replaced by a more general method for storing the + * data. It should not be used. Instead we use real API calls and make a + * guess for what the highest assigned CKSUMTYPE_ constant is. As of 1.2.2 + * it is 0x000c (CKSUMTYPE_HMAC_SHA1_DES3). So we will use 0x0010. + */ +static size_t *populate_cksumlens(void) +{ + int i, j, n; + static size_t *cklens = NULL; + +# ifdef KRB5_MIT_OLD11 + n = krb5_max_cksum; +# else + n = 0x0010; +# endif /* KRB5_MIT_OLD11 */ + +# ifdef KRB5CHECKAUTH + if (!cklens && !(cklens = (size_t *)calloc(sizeof(int), n + 1))) + return NULL; + + for (i = 0; i < n; i++) { + if (!valid_cksumtype(i)) + continue; /* array has holes */ + for (j = 0; j < n; j++) { + if (cklens[j] == 0) { + cklens[j] = krb5_checksum_size(NULL, i); + break; /* krb5 elem was new: add */ + } + if (cklens[j] == krb5_checksum_size(NULL, i)) { + break; /* ignore duplicate elements */ + } + } + } +# endif /* KRB5CHECKAUTH */ + + return cklens; +} + +/*- + * Return pointer to start of real authenticator within authenticator, or + * return NULL on error. + * Decrypted authenticator looks like this: + * [0 or 8 byte confounder] [4-24 byte checksum] [real authent'r] + * This hackery wouldn't be necessary if MIT KRB5 1.0.6 had the + * krb5_auth_con_getcksumtype() function advertised in its krb5.h. + */ +unsigned char *kssl_skip_confound(krb5_enctype etype, unsigned char *a) +{ + int i, conlen; + size_t cklen; + static size_t *cksumlens = NULL; + unsigned char *test_auth; + + conlen = (etype) ? 8 : 0; + + if (!cksumlens && !(cksumlens = populate_cksumlens())) + return NULL; + for (i = 0; (cklen = cksumlens[i]) != 0; i++) { + test_auth = a + conlen + cklen; + if (kssl_test_confound(test_auth)) + return test_auth; + } + + return NULL; +} + +/* + * Set kssl_err error info when reason text is a simple string kssl_err = + * struct { int reason; char text[KSSL_ERR_MAX+1]; } + */ +void kssl_err_set(KSSL_ERR *kssl_err, int reason, char *text) +{ + if (kssl_err == NULL) + return; + + kssl_err->reason = reason; + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, "%s", text); + return; +} + +/* + * Display contents of krb5_data struct, for debugging + */ +void print_krb5_data(char *label, krb5_data *kdata) +{ + int i; + + fprintf(stderr, "%s[%d] ", label, kdata->length); + for (i = 0; i < (int)kdata->length; i++) { + if (0 && isprint((int)kdata->data[i])) + fprintf(stderr, "%c ", kdata->data[i]); + else + fprintf(stderr, "%02x ", (unsigned char)kdata->data[i]); + } + fprintf(stderr, "\n"); +} + +/* + * Display contents of krb5_authdata struct, for debugging + */ +void print_krb5_authdata(char *label, krb5_authdata **adata) +{ + if (adata == NULL) { + fprintf(stderr, "%s, authdata==0\n", label); + return; + } + fprintf(stderr, "%s [%p]\n", label, (void *)adata); +# if 0 + { + int i; + fprintf(stderr, "%s[at%d:%d] ", label, adata->ad_type, adata->length); + for (i = 0; i < adata->length; i++) { + fprintf(stderr, (isprint(adata->contents[i])) ? "%c " : "%02x", + adata->contents[i]); + } + fprintf(stderr, "\n"); + } +# endif +} + +/* + * Display contents of krb5_keyblock struct, for debugging + */ +void print_krb5_keyblock(char *label, krb5_keyblock *keyblk) +{ + int i; + + if (keyblk == NULL) { + fprintf(stderr, "%s, keyblk==0\n", label); + return; + } +# ifdef KRB5_HEIMDAL + fprintf(stderr, "%s\n\t[et%d:%d]: ", label, keyblk->keytype, + keyblk->keyvalue->length); + for (i = 0; i < (int)keyblk->keyvalue->length; i++) { + fprintf(stderr, "%02x", + (unsigned char *)(keyblk->keyvalue->contents)[i]); + } + fprintf(stderr, "\n"); +# else + fprintf(stderr, "%s\n\t[et%d:%d]: ", label, keyblk->enctype, + keyblk->length); + for (i = 0; i < (int)keyblk->length; i++) { + fprintf(stderr, "%02x", keyblk->contents[i]); + } + fprintf(stderr, "\n"); +# endif +} + +/* + * Display contents of krb5_principal_data struct, for debugging + * (krb5_principal is typedef'd == krb5_principal_data *) + */ +static void print_krb5_princ(char *label, krb5_principal_data *princ) +{ + int i, ui, uj; + + fprintf(stderr, "%s principal Realm: ", label); + if (princ == NULL) + return; + for (ui = 0; ui < (int)princ->realm.length; ui++) + putchar(princ->realm.data[ui]); + fprintf(stderr, " (nametype %d) has %d strings:\n", princ->type, + princ->length); + for (i = 0; i < (int)princ->length; i++) { + fprintf(stderr, "\t%d [%d]: ", i, princ->data[i].length); + for (uj = 0; uj < (int)princ->data[i].length; uj++) { + putchar(princ->data[i].data[uj]); + } + fprintf(stderr, "\n"); + } + return; +} + +/*- Given krb5 service (typically "kssl") and hostname in kssl_ctx, + * Return encrypted Kerberos ticket for service @ hostname. + * If authenp is non-NULL, also return encrypted authenticator, + * whose data should be freed by caller. + * (Originally was: Create Kerberos AP_REQ message for SSL Client.) + * + * 19990628 VRS Started; Returns Kerberos AP_REQ message. + * 20010409 VRS Modified for RFC2712; Returns enc tkt. + * 20010606 VRS May also return optional authenticator. + */ +krb5_error_code kssl_cget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, + /* + * OUT + */ krb5_data **enc_ticketp, + /* + * UPDATE + */ krb5_data *authenp, + /* + * OUT + */ KSSL_ERR *kssl_err) +{ + krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; + krb5_context krb5context = NULL; + krb5_auth_context krb5auth_context = NULL; + krb5_ccache krb5ccdef = NULL; + krb5_creds krb5creds, *krb5credsp = NULL; + krb5_data krb5_app_req; + + kssl_err_set(kssl_err, 0, ""); + memset((char *)&krb5creds, 0, sizeof(krb5creds)); + + if (!kssl_ctx) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "No kssl_ctx defined.\n"); + goto err; + } else if (!kssl_ctx->service_host) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "kssl_ctx service_host undefined.\n"); + goto err; + } + + if ((krb5rc = krb5_init_context(&krb5context)) != 0) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "krb5_init_context() fails: %d\n", krb5rc); + kssl_err->reason = SSL_R_KRB5_C_INIT; + goto err; + } + + if ((krb5rc = krb5_sname_to_principal(krb5context, + kssl_ctx->service_host, + (kssl_ctx->service_name) ? + kssl_ctx->service_name : KRB5SVC, + KRB5_NT_SRV_HST, + &krb5creds.server)) != 0) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "krb5_sname_to_principal() fails for %s/%s\n", + kssl_ctx->service_host, + (kssl_ctx-> + service_name) ? kssl_ctx->service_name : KRB5SVC); + kssl_err->reason = SSL_R_KRB5_C_INIT; + goto err; + } + + if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) { + kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC, + "krb5_cc_default fails.\n"); + goto err; + } + + if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef, + &krb5creds.client)) != 0) { + kssl_err_set(kssl_err, SSL_R_KRB5_C_CC_PRINC, + "krb5_cc_get_principal() fails.\n"); + goto err; + } + + if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef, + &krb5creds, &krb5credsp)) != 0) { + kssl_err_set(kssl_err, SSL_R_KRB5_C_GET_CRED, + "krb5_get_credentials() fails.\n"); + goto err; + } + + *enc_ticketp = &krb5credsp->ticket; +# ifdef KRB5_HEIMDAL + kssl_ctx->enctype = krb5credsp->session.keytype; +# else + kssl_ctx->enctype = krb5credsp->keyblock.enctype; +# endif + + krb5rc = KRB5KRB_ERR_GENERIC; + /* caller should free data of krb5_app_req */ + /* + * 20010406 VRS deleted for real KerberosWrapper 20010605 VRS reinstated + * to offer Authenticator to KerberosWrapper + */ + krb5_app_req.length = 0; + if (authenp) { + krb5_data krb5in_data; + const unsigned char *p; + long arlen; + KRB5_APREQBODY *ap_req; + + authenp->length = 0; + krb5in_data.data = NULL; + krb5in_data.length = 0; + if ((krb5rc = krb5_mk_req_extended(krb5context, + &krb5auth_context, 0, &krb5in_data, + krb5credsp, &krb5_app_req)) != 0) { + kssl_err_set(kssl_err, SSL_R_KRB5_C_MK_REQ, + "krb5_mk_req_extended() fails.\n"); + goto err; + } + + arlen = krb5_app_req.length; + p = (unsigned char *)krb5_app_req.data; + ap_req = (KRB5_APREQBODY *)d2i_KRB5_APREQ(NULL, &p, arlen); + if (ap_req) { + authenp->length = i2d_KRB5_ENCDATA(ap_req->authenticator, NULL); + if (authenp->length && (authenp->data = malloc(authenp->length))) { + unsigned char *adp = (unsigned char *)authenp->data; + authenp->length = + i2d_KRB5_ENCDATA(ap_req->authenticator, &adp); + } + } + + if (ap_req) + KRB5_APREQ_free((KRB5_APREQ *) ap_req); + if (krb5_app_req.length) + kssl_krb5_free_data_contents(krb5context, &krb5_app_req); + } +# ifdef KRB5_HEIMDAL + if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->session)) { + kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, + "kssl_ctx_setkey() fails.\n"); + } +# else + if (kssl_ctx_setkey(kssl_ctx, &krb5credsp->keyblock)) { + kssl_err_set(kssl_err, SSL_R_KRB5_C_INIT, + "kssl_ctx_setkey() fails.\n"); + } +# endif + else + krb5rc = 0; + + err: +# ifdef KSSL_DEBUG + kssl_ctx_show(kssl_ctx); +# endif /* KSSL_DEBUG */ + + if (krb5creds.client) + krb5_free_principal(krb5context, krb5creds.client); + if (krb5creds.server) + krb5_free_principal(krb5context, krb5creds.server); + if (krb5auth_context) + krb5_auth_con_free(krb5context, krb5auth_context); + if (krb5context) + krb5_free_context(krb5context); + return (krb5rc); +} + +/*- + * Given d2i_-decoded asn1ticket, allocate and return a new krb5_ticket. + * Return Kerberos error code and kssl_err struct on error. + * Allocates krb5_ticket and krb5_principal; caller should free these. + * + * 20010410 VRS Implemented krb5_decode_ticket() as + * old_krb5_decode_ticket(). Missing from MIT1.0.6. + * 20010615 VRS Re-cast as openssl/asn1 d2i_*() functions. + * Re-used some of the old krb5_decode_ticket() + * code here. This tkt should alloc/free just + * like the real thing. + */ +static krb5_error_code kssl_TKT2tkt( /* IN */ krb5_context krb5context, + /* + * IN + */ KRB5_TKTBODY *asn1ticket, + /* + * OUT + */ krb5_ticket **krb5ticket, + /* + * OUT + */ KSSL_ERR *kssl_err) +{ + krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; + krb5_ticket *new5ticket = NULL; + ASN1_GENERALSTRING *gstr_svc, *gstr_host; + + *krb5ticket = NULL; + + if (asn1ticket == NULL || asn1ticket->realm == NULL || + asn1ticket->sname == NULL || + sk_ASN1_GENERALSTRING_num(asn1ticket->sname->namestring) < 2) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "Null field in asn1ticket.\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + return KRB5KRB_ERR_GENERIC; + } + + if ((new5ticket = (krb5_ticket *)calloc(1, sizeof(krb5_ticket))) == NULL) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "Unable to allocate new krb5_ticket.\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + return ENOMEM; /* or KRB5KRB_ERR_GENERIC; */ + } + + gstr_svc = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 0); + gstr_host = sk_ASN1_GENERALSTRING_value(asn1ticket->sname->namestring, 1); + + if ((krb5rc = kssl_build_principal_2(krb5context, + &new5ticket->server, + asn1ticket->realm->length, + (char *)asn1ticket->realm->data, + gstr_svc->length, + (char *)gstr_svc->data, + gstr_host->length, + (char *)gstr_host->data)) != 0) { + free(new5ticket); + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "Error building ticket server principal.\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + return krb5rc; /* or KRB5KRB_ERR_GENERIC; */ + } + + krb5_princ_type(krb5context, new5ticket->server) = + asn1ticket->sname->nametype->data[0]; + new5ticket->enc_part.enctype = asn1ticket->encdata->etype->data[0]; + new5ticket->enc_part.kvno = asn1ticket->encdata->kvno->data[0]; + new5ticket->enc_part.ciphertext.length = + asn1ticket->encdata->cipher->length; + if ((new5ticket->enc_part.ciphertext.data = + calloc(1, asn1ticket->encdata->cipher->length)) == NULL) { + free(new5ticket); + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "Error allocating cipher in krb5ticket.\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + return KRB5KRB_ERR_GENERIC; + } else { + memcpy(new5ticket->enc_part.ciphertext.data, + asn1ticket->encdata->cipher->data, + asn1ticket->encdata->cipher->length); + } + + *krb5ticket = new5ticket; + return 0; +} + +/*- + * Given krb5 service name in KSSL_CTX *kssl_ctx (typically "kssl"), + * and krb5 AP_REQ message & message length, + * Return Kerberos session key and client principle + * to SSL Server in KSSL_CTX *kssl_ctx. + * + * 19990702 VRS Started. + */ +krb5_error_code kssl_sget_tkt( /* UPDATE */ KSSL_CTX *kssl_ctx, + /* + * IN + */ krb5_data *indata, + /* + * OUT + */ krb5_ticket_times *ttimes, + /* + * OUT + */ KSSL_ERR *kssl_err) +{ + krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; + static krb5_context krb5context = NULL; + static krb5_auth_context krb5auth_context = NULL; + krb5_ticket *krb5ticket = NULL; + KRB5_TKTBODY *asn1ticket = NULL; + const unsigned char *p; + krb5_keytab krb5keytab = NULL; + krb5_keytab_entry kt_entry; + krb5_principal krb5server; + krb5_rcache rcache = NULL; + + kssl_err_set(kssl_err, 0, ""); + + if (!kssl_ctx) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, "No kssl_ctx defined.\n"); + goto err; + } +# ifdef KSSL_DEBUG + fprintf(stderr, "in kssl_sget_tkt(%s)\n", + kstring(kssl_ctx->service_name)); +# endif /* KSSL_DEBUG */ + + if (!krb5context && (krb5rc = krb5_init_context(&krb5context))) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_init_context() fails.\n"); + goto err; + } + if (krb5auth_context && + (krb5rc = krb5_auth_con_free(krb5context, krb5auth_context))) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_auth_con_free() fails.\n"); + goto err; + } else + krb5auth_context = NULL; + if (!krb5auth_context && + (krb5rc = krb5_auth_con_init(krb5context, &krb5auth_context))) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_auth_con_init() fails.\n"); + goto err; + } + + if ((krb5rc = krb5_auth_con_getrcache(krb5context, krb5auth_context, + &rcache))) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_auth_con_getrcache() fails.\n"); + goto err; + } + + if ((krb5rc = krb5_sname_to_principal(krb5context, NULL, + (kssl_ctx->service_name) ? + kssl_ctx->service_name : KRB5SVC, + KRB5_NT_SRV_HST, + &krb5server)) != 0) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_sname_to_principal() fails.\n"); + goto err; + } + + if (rcache == NULL) { + if ((krb5rc = krb5_get_server_rcache(krb5context, + krb5_princ_component(krb5context, + krb5server, + 0), + &rcache))) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_get_server_rcache() fails.\n"); + goto err; + } + } + + if ((krb5rc = + krb5_auth_con_setrcache(krb5context, krb5auth_context, rcache))) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_auth_con_setrcache() fails.\n"); + goto err; + } + + /* + * kssl_ctx->keytab_file == NULL ==> use Kerberos default + */ + if (kssl_ctx->keytab_file) { + krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, + &krb5keytab); + if (krb5rc) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_kt_resolve() fails.\n"); + goto err; + } + } else { + krb5rc = krb5_kt_default(krb5context, &krb5keytab); + if (krb5rc) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "krb5_kt_default() fails.\n"); + goto err; + } + } + + /*- Actual Kerberos5 krb5_recvauth() has initial conversation here + * o check KRB5_SENDAUTH_BADAUTHVERS + * unless KRB5_RECVAUTH_SKIP_VERSION + * o check KRB5_SENDAUTH_BADAPPLVERS + * o send "0" msg if all OK + */ + + /*- + * 20010411 was using AP_REQ instead of true KerberosWrapper + * + * if ((krb5rc = krb5_rd_req(krb5context, &krb5auth_context, + * &krb5in_data, krb5server, krb5keytab, + * &ap_option, &krb5ticket)) != 0) { Error } + */ + + p = (unsigned char *)indata->data; + if ((asn1ticket = (KRB5_TKTBODY *)d2i_KRB5_TICKET(NULL, &p, + (long)indata->length)) + == NULL) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "d2i_KRB5_TICKET() ASN.1 decode failure.\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + goto err; + } + + /* + * Was: krb5rc = krb5_decode_ticket(krb5in_data,&krb5ticket)) != 0) + */ + if ((krb5rc = kssl_TKT2tkt(krb5context, asn1ticket, &krb5ticket, + kssl_err)) != 0) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "Error converting ASN.1 ticket to krb5_ticket.\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + goto err; + } + + if (!krb5_principal_compare(krb5context, krb5server, krb5ticket->server)) { + krb5rc = KRB5_PRINC_NOMATCH; + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "server principal != ticket principal\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + goto err; + } + if ((krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, + krb5ticket->server, + krb5ticket->enc_part.kvno, + krb5ticket->enc_part.enctype, + &kt_entry)) != 0) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "krb5_kt_get_entry() fails with %x.\n", krb5rc); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + goto err; + } + if ((krb5rc = krb5_decrypt_tkt_part(krb5context, &kt_entry.key, + krb5ticket)) != 0) { + BIO_snprintf(kssl_err->text, KSSL_ERR_MAX, + "krb5_decrypt_tkt_part() failed.\n"); + kssl_err->reason = SSL_R_KRB5_S_RD_REQ; + goto err; + } else { + krb5_kt_free_entry(krb5context, &kt_entry); +# ifdef KSSL_DEBUG + { + int i; + krb5_address **paddr = krb5ticket->enc_part2->caddrs; + fprintf(stderr, "Decrypted ticket fields:\n"); + fprintf(stderr, "\tflags: %X, transit-type: %X", + krb5ticket->enc_part2->flags, + krb5ticket->enc_part2->transited.tr_type); + print_krb5_data("\ttransit-data: ", + &(krb5ticket->enc_part2->transited.tr_contents)); + fprintf(stderr, "\tcaddrs: %p, authdata: %p\n", + krb5ticket->enc_part2->caddrs, + krb5ticket->enc_part2->authorization_data); + if (paddr) { + fprintf(stderr, "\tcaddrs:\n"); + for (i = 0; paddr[i] != NULL; i++) { + krb5_data d; + d.length = paddr[i]->length; + d.data = paddr[i]->contents; + print_krb5_data("\t\tIP: ", &d); + } + } + fprintf(stderr, "\tstart/auth/end times: %d / %d / %d\n", + krb5ticket->enc_part2->times.starttime, + krb5ticket->enc_part2->times.authtime, + krb5ticket->enc_part2->times.endtime); + } +# endif /* KSSL_DEBUG */ + } + + krb5rc = KRB5_NO_TKT_SUPPLIED; + if (!krb5ticket || !krb5ticket->enc_part2 || + !krb5ticket->enc_part2->client || + !krb5ticket->enc_part2->client->data || + !krb5ticket->enc_part2->session) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, + "bad ticket from krb5_rd_req.\n"); + } else if (kssl_ctx_setprinc(kssl_ctx, KSSL_CLIENT, + &krb5ticket->enc_part2->client->realm, + krb5ticket->enc_part2->client->data, + krb5ticket->enc_part2->client->length)) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, + "kssl_ctx_setprinc() fails.\n"); + } else if (kssl_ctx_setkey(kssl_ctx, krb5ticket->enc_part2->session)) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, + "kssl_ctx_setkey() fails.\n"); + } else if (krb5ticket->enc_part2->flags & TKT_FLG_INVALID) { + krb5rc = KRB5KRB_AP_ERR_TKT_INVALID; + kssl_err_set(kssl_err, SSL_R_KRB5_S_BAD_TICKET, + "invalid ticket from krb5_rd_req.\n"); + } else + krb5rc = 0; + + kssl_ctx->enctype = krb5ticket->enc_part.enctype; + ttimes->authtime = krb5ticket->enc_part2->times.authtime; + ttimes->starttime = krb5ticket->enc_part2->times.starttime; + ttimes->endtime = krb5ticket->enc_part2->times.endtime; + ttimes->renew_till = krb5ticket->enc_part2->times.renew_till; + + err: +# ifdef KSSL_DEBUG + kssl_ctx_show(kssl_ctx); +# endif /* KSSL_DEBUG */ + + if (asn1ticket) + KRB5_TICKET_free((KRB5_TICKET *) asn1ticket); + if (krb5keytab) + krb5_kt_close(krb5context, krb5keytab); + if (krb5ticket) + krb5_free_ticket(krb5context, krb5ticket); + if (krb5server) + krb5_free_principal(krb5context, krb5server); + return (krb5rc); +} + +/* + * Allocate & return a new kssl_ctx struct. + */ +KSSL_CTX *kssl_ctx_new(void) +{ + return ((KSSL_CTX *)kssl_calloc(1, sizeof(KSSL_CTX))); +} + +/* + * Frees a kssl_ctx struct and any allocated memory it holds. Returns NULL. + */ +KSSL_CTX *kssl_ctx_free(KSSL_CTX *kssl_ctx) +{ + if (kssl_ctx == NULL) + return kssl_ctx; + + if (kssl_ctx->key) + OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); + if (kssl_ctx->key) + kssl_free(kssl_ctx->key); + if (kssl_ctx->client_princ) + kssl_free(kssl_ctx->client_princ); + if (kssl_ctx->service_host) + kssl_free(kssl_ctx->service_host); + if (kssl_ctx->service_name) + kssl_free(kssl_ctx->service_name); + if (kssl_ctx->keytab_file) + kssl_free(kssl_ctx->keytab_file); + + kssl_free(kssl_ctx); + return (KSSL_CTX *)NULL; +} + +/* + * Given an array of (krb5_data *) entity (and optional realm), set the plain + * (char *) client_princ or service_host member of the kssl_ctx struct. + */ +krb5_error_code +kssl_ctx_setprinc(KSSL_CTX *kssl_ctx, int which, + krb5_data *realm, krb5_data *entity, int nentities) +{ + char **princ; + int length; + int i; + + if (kssl_ctx == NULL || entity == NULL) + return KSSL_CTX_ERR; + + switch (which) { + case KSSL_CLIENT: + princ = &kssl_ctx->client_princ; + break; + case KSSL_SERVER: + princ = &kssl_ctx->service_host; + break; + default: + return KSSL_CTX_ERR; + break; + } + if (*princ) + kssl_free(*princ); + + /* Add up all the entity->lengths */ + length = 0; + for (i = 0; i < nentities; i++) { + length += entity[i].length; + } + /* Add in space for the '/' character(s) (if any) */ + length += nentities - 1; + /* Space for the ('@'+realm+NULL | NULL) */ + length += ((realm) ? realm->length + 2 : 1); + + if ((*princ = kssl_calloc(1, length)) == NULL) + return KSSL_CTX_ERR; + else { + for (i = 0; i < nentities; i++) { + strncat(*princ, entity[i].data, entity[i].length); + if (i < nentities - 1) { + strcat(*princ, "/"); + } + } + if (realm) { + strcat(*princ, "@"); + (void)strncat(*princ, realm->data, realm->length); + } + } + + return KSSL_CTX_OK; +} + +/*- Set one of the plain (char *) string members of the kssl_ctx struct. + * Default values should be: + * which == KSSL_SERVICE => "khost" (KRB5SVC) + * which == KSSL_KEYTAB => "/etc/krb5.keytab" (KRB5KEYTAB) + */ +krb5_error_code kssl_ctx_setstring(KSSL_CTX *kssl_ctx, int which, char *text) +{ + char **string; + + if (!kssl_ctx) + return KSSL_CTX_ERR; + + switch (which) { + case KSSL_SERVICE: + string = &kssl_ctx->service_name; + break; + case KSSL_SERVER: + string = &kssl_ctx->service_host; + break; + case KSSL_CLIENT: + string = &kssl_ctx->client_princ; + break; + case KSSL_KEYTAB: + string = &kssl_ctx->keytab_file; + break; + default: + return KSSL_CTX_ERR; + break; + } + if (*string) + kssl_free(*string); + + if (!text) { + *string = '\0'; + return KSSL_CTX_OK; + } + + if ((*string = kssl_calloc(1, strlen(text) + 1)) == NULL) + return KSSL_CTX_ERR; + else + strcpy(*string, text); + + return KSSL_CTX_OK; +} + +/* + * Copy the Kerberos session key from a (krb5_keyblock *) to a kssl_ctx + * struct. Clear kssl_ctx->key if Kerberos session key is NULL. + */ +krb5_error_code kssl_ctx_setkey(KSSL_CTX *kssl_ctx, krb5_keyblock *session) +{ + int length; + krb5_enctype enctype; + krb5_octet FAR *contents = NULL; + + if (!kssl_ctx) + return KSSL_CTX_ERR; + + if (kssl_ctx->key) { + OPENSSL_cleanse(kssl_ctx->key, kssl_ctx->length); + kssl_free(kssl_ctx->key); + } + + if (session) { + +# ifdef KRB5_HEIMDAL + length = session->keyvalue->length; + enctype = session->keytype; + contents = session->keyvalue->contents; +# else + length = session->length; + enctype = session->enctype; + contents = session->contents; +# endif + kssl_ctx->enctype = enctype; + kssl_ctx->length = length; + } else { + kssl_ctx->enctype = ENCTYPE_UNKNOWN; + kssl_ctx->length = 0; + return KSSL_CTX_OK; + } + + if ((kssl_ctx->key = + (krb5_octet FAR *)kssl_calloc(1, kssl_ctx->length)) == NULL) { + kssl_ctx->length = 0; + return KSSL_CTX_ERR; + } else + memcpy(kssl_ctx->key, contents, length); + + return KSSL_CTX_OK; +} + +/* + * Display contents of kssl_ctx struct + */ +void kssl_ctx_show(KSSL_CTX *kssl_ctx) +{ + int i; + + printf("kssl_ctx: "); + if (kssl_ctx == NULL) { + printf("NULL\n"); + return; + } else + printf("%p\n", (void *)kssl_ctx); + + printf("\tservice:\t%s\n", + (kssl_ctx->service_name) ? kssl_ctx->service_name : "NULL"); + printf("\tclient:\t%s\n", + (kssl_ctx->client_princ) ? kssl_ctx->client_princ : "NULL"); + printf("\tserver:\t%s\n", + (kssl_ctx->service_host) ? kssl_ctx->service_host : "NULL"); + printf("\tkeytab:\t%s\n", + (kssl_ctx->keytab_file) ? kssl_ctx->keytab_file : "NULL"); + printf("\tkey [%d:%d]:\t", kssl_ctx->enctype, kssl_ctx->length); + + for (i = 0; i < kssl_ctx->length && kssl_ctx->key; i++) { + printf("%02x", kssl_ctx->key[i]); + } + printf("\n"); + return; +} + +int kssl_keytab_is_available(KSSL_CTX *kssl_ctx) +{ + krb5_context krb5context = NULL; + krb5_keytab krb5keytab = NULL; + krb5_keytab_entry entry; + krb5_principal princ = NULL; + krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; + int rc = 0; + + if ((krb5rc = krb5_init_context(&krb5context))) + return (0); + + /* + * kssl_ctx->keytab_file == NULL ==> use Kerberos default + */ + if (kssl_ctx->keytab_file) { + krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file, + &krb5keytab); + if (krb5rc) + goto exit; + } else { + krb5rc = krb5_kt_default(krb5context, &krb5keytab); + if (krb5rc) + goto exit; + } + + /* the host key we are looking for */ + krb5rc = krb5_sname_to_principal(krb5context, NULL, + kssl_ctx-> + service_name ? kssl_ctx->service_name : + KRB5SVC, KRB5_NT_SRV_HST, &princ); + + if (krb5rc) + goto exit; + + krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, princ, + /* IGNORE_VNO */ + 0, + /* IGNORE_ENCTYPE */ + 0, &entry); + if (krb5rc == KRB5_KT_NOTFOUND) { + rc = 1; + goto exit; + } else if (krb5rc) + goto exit; + + krb5_kt_free_entry(krb5context, &entry); + rc = 1; + + exit: + if (krb5keytab) + krb5_kt_close(krb5context, krb5keytab); + if (princ) + krb5_free_principal(krb5context, princ); + if (krb5context) + krb5_free_context(krb5context); + return (rc); +} + +int kssl_tgt_is_available(KSSL_CTX *kssl_ctx) +{ + krb5_error_code krb5rc = KRB5KRB_ERR_GENERIC; + krb5_context krb5context = NULL; + krb5_ccache krb5ccdef = NULL; + krb5_creds krb5creds, *krb5credsp = NULL; + int rc = 0; + + memset((char *)&krb5creds, 0, sizeof(krb5creds)); + + if (!kssl_ctx) + return (0); + + if (!kssl_ctx->service_host) + return (0); + + if ((krb5rc = krb5_init_context(&krb5context)) != 0) + goto err; + + if ((krb5rc = krb5_sname_to_principal(krb5context, + kssl_ctx->service_host, + (kssl_ctx->service_name) ? + kssl_ctx->service_name : KRB5SVC, + KRB5_NT_SRV_HST, + &krb5creds.server)) != 0) + goto err; + + if ((krb5rc = krb5_cc_default(krb5context, &krb5ccdef)) != 0) + goto err; + + if ((krb5rc = krb5_cc_get_principal(krb5context, krb5ccdef, + &krb5creds.client)) != 0) + goto err; + + if ((krb5rc = krb5_get_credentials(krb5context, 0, krb5ccdef, + &krb5creds, &krb5credsp)) != 0) + goto err; + + rc = 1; + + err: +# ifdef KSSL_DEBUG + kssl_ctx_show(kssl_ctx); +# endif /* KSSL_DEBUG */ + + if (krb5creds.client) + krb5_free_principal(krb5context, krb5creds.client); + if (krb5creds.server) + krb5_free_principal(krb5context, krb5creds.server); + if (krb5context) + krb5_free_context(krb5context); + return (rc); +} + +# if !defined(OPENSSL_SYS_WINDOWS) && !defined(OPENSSL_SYS_WIN32) +void kssl_krb5_free_data_contents(krb5_context context, krb5_data *data) +{ +# ifdef KRB5_HEIMDAL + data->length = 0; + if (data->data) + free(data->data); +# elif defined(KRB5_MIT_OLD11) + if (data->data) { + krb5_xfree(data->data); + data->data = 0; + } +# else + krb5_free_data_contents(NULL, data); +# endif +} +# endif +/* !OPENSSL_SYS_WINDOWS && !OPENSSL_SYS_WIN32 */ + +/* + * Given pointers to KerberosTime and struct tm structs, convert the + * KerberosTime string to struct tm. Note that KerberosTime is a + * ASN1_GENERALIZEDTIME value, constrained to GMT with no fractional seconds + * as defined in RFC 1510. Return pointer to the (partially) filled in + * struct tm on success, return NULL on failure. + */ +static struct tm *k_gmtime(ASN1_GENERALIZEDTIME *gtime, struct tm *k_tm) +{ + char c, *p; + + if (!k_tm) + return NULL; + if (gtime == NULL || gtime->length < 14) + return NULL; + if (gtime->data == NULL) + return NULL; + + p = (char *)>ime->data[14]; + + c = *p; + *p = '\0'; + p -= 2; + k_tm->tm_sec = atoi(p); + *(p + 2) = c; + c = *p; + *p = '\0'; + p -= 2; + k_tm->tm_min = atoi(p); + *(p + 2) = c; + c = *p; + *p = '\0'; + p -= 2; + k_tm->tm_hour = atoi(p); + *(p + 2) = c; + c = *p; + *p = '\0'; + p -= 2; + k_tm->tm_mday = atoi(p); + *(p + 2) = c; + c = *p; + *p = '\0'; + p -= 2; + k_tm->tm_mon = atoi(p) - 1; + *(p + 2) = c; + c = *p; + *p = '\0'; + p -= 4; + k_tm->tm_year = atoi(p) - 1900; + *(p + 4) = c; + + return k_tm; +} + +/* + * Helper function for kssl_validate_times(). We need context->clockskew, + * but krb5_context is an opaque struct. So we try to sneek the clockskew + * out through the replay cache. If that fails just return a likely default + * (300 seconds). + */ +static krb5_deltat get_rc_clockskew(krb5_context context) +{ + krb5_rcache rc; + krb5_deltat clockskew; + + if (krb5_rc_default(context, &rc)) + return KSSL_CLOCKSKEW; + if (krb5_rc_initialize(context, rc, 0)) + return KSSL_CLOCKSKEW; + if (krb5_rc_get_lifespan(context, rc, &clockskew)) { + clockskew = KSSL_CLOCKSKEW; + } + (void)krb5_rc_destroy(context, rc); + return clockskew; +} + +/* + * kssl_validate_times() combines (and more importantly exposes) the MIT KRB5 + * internal function krb5_validate_times() and the in_clock_skew() macro. + * The authenticator client time is checked to be within clockskew secs of + * the current time and the current time is checked to be within the ticket + * start and expire times. Either check may be omitted by supplying a NULL + * value. Returns 0 for valid times, SSL_R_KRB5* error codes otherwise. See + * Also: (Kerberos source)/krb5/lib/krb5/krb/valid_times.c 20010420 VRS + */ +krb5_error_code kssl_validate_times(krb5_timestamp atime, + krb5_ticket_times *ttimes) +{ + krb5_deltat skew; + krb5_timestamp start, now; + krb5_error_code rc; + krb5_context context; + + if ((rc = krb5_init_context(&context))) + return SSL_R_KRB5_S_BAD_TICKET; + skew = get_rc_clockskew(context); + if ((rc = krb5_timeofday(context, &now))) + return SSL_R_KRB5_S_BAD_TICKET; + krb5_free_context(context); + + if (atime && labs(atime - now) >= skew) + return SSL_R_KRB5_S_TKT_SKEW; + + if (!ttimes) + return 0; + + start = (ttimes->starttime != 0) ? ttimes->starttime : ttimes->authtime; + if (start - now > skew) + return SSL_R_KRB5_S_TKT_NYV; + if ((now - ttimes->endtime) > skew) + return SSL_R_KRB5_S_TKT_EXPIRED; + +# ifdef KSSL_DEBUG + fprintf(stderr, "kssl_validate_times: %d |<- | %d - %d | < %d ->| %d\n", + start, atime, now, skew, ttimes->endtime); +# endif /* KSSL_DEBUG */ + + return 0; +} + +/* + * Decode and decrypt given DER-encoded authenticator, then pass + * authenticator ctime back in *atimep (or 0 if time unavailable). Returns + * krb5_error_code and kssl_err on error. A NULL authenticator + * (authentp->length == 0) is not considered an error. Note that + * kssl_check_authent() makes use of the KRB5 session key; you must call + * kssl_sget_tkt() to get the key before calling this routine. + */ +krb5_error_code kssl_check_authent( + /* + * IN + */ KSSL_CTX *kssl_ctx, + /* + * IN + */ krb5_data *authentp, + /* + * OUT + */ krb5_timestamp *atimep, + /* + * OUT + */ KSSL_ERR *kssl_err) +{ + krb5_error_code krb5rc = 0; + KRB5_ENCDATA *dec_authent = NULL; + KRB5_AUTHENTBODY *auth = NULL; + krb5_enctype enctype; + EVP_CIPHER_CTX ciph_ctx; + const EVP_CIPHER *enc = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + const unsigned char *p; + unsigned char *unenc_authent; + int outl, unencbufsize; + struct tm tm_time, *tm_l, *tm_g; + time_t now, tl, tg, tr, tz_offset; + + EVP_CIPHER_CTX_init(&ciph_ctx); + *atimep = 0; + kssl_err_set(kssl_err, 0, ""); + +# ifndef KRB5CHECKAUTH + authentp = NULL; +# else +# if KRB5CHECKAUTH == 0 + authentp = NULL; +# endif +# endif /* KRB5CHECKAUTH */ + + if (authentp == NULL || authentp->length == 0) + return 0; + +# ifdef KSSL_DEBUG + { + unsigned int ui; + fprintf(stderr, "kssl_check_authent: authenticator[%d]:\n", + authentp->length); + p = authentp->data; + for (ui = 0; ui < authentp->length; ui++) + fprintf(stderr, "%02x ", p[ui]); + fprintf(stderr, "\n"); + } +# endif /* KSSL_DEBUG */ + + unencbufsize = 2 * authentp->length; + if ((unenc_authent = calloc(1, unencbufsize)) == NULL) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "Unable to allocate authenticator buffer.\n"); + krb5rc = KRB5KRB_ERR_GENERIC; + goto err; + } + + p = (unsigned char *)authentp->data; + if ((dec_authent = d2i_KRB5_ENCDATA(NULL, &p, + (long)authentp->length)) == NULL) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "Error decoding authenticator.\n"); + krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto err; + } + + enctype = dec_authent->etype->data[0]; /* should = kssl_ctx->enctype */ +# if !defined(KRB5_MIT_OLD11) + switch (enctype) { + case ENCTYPE_DES3_CBC_SHA1: /* EVP_des_ede3_cbc(); */ + case ENCTYPE_DES3_CBC_SHA: + case ENCTYPE_DES3_CBC_RAW: + krb5rc = 0; /* Skip, can't handle derived keys */ + goto err; + } +# endif + enc = kssl_map_enc(enctype); + memset(iv, 0, sizeof iv); /* per RFC 1510 */ + + if (enc == NULL) { + /* + * Disable kssl_check_authent for ENCTYPE_DES3_CBC_SHA1. This + * enctype indicates the authenticator was encrypted using key-usage + * derived keys which openssl cannot decrypt. + */ + goto err; + } + + if (!EVP_CipherInit(&ciph_ctx, enc, kssl_ctx->key, iv, 0)) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "EVP_CipherInit error decrypting authenticator.\n"); + krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto err; + } + outl = dec_authent->cipher->length; + if (!EVP_Cipher + (&ciph_ctx, unenc_authent, dec_authent->cipher->data, outl)) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "EVP_Cipher error decrypting authenticator.\n"); + krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto err; + } + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + +# ifdef KSSL_DEBUG + { + int padl; + fprintf(stderr, "kssl_check_authent: decrypted authenticator[%d] =\n", + outl); + for (padl = 0; padl < outl; padl++) + fprintf(stderr, "%02x ", unenc_authent[padl]); + fprintf(stderr, "\n"); + } +# endif /* KSSL_DEBUG */ + + if ((p = kssl_skip_confound(enctype, unenc_authent)) == NULL) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "confounded by authenticator.\n"); + krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto err; + } + outl -= p - unenc_authent; + + if ((auth = (KRB5_AUTHENTBODY *)d2i_KRB5_AUTHENT(NULL, &p, + (long)outl)) == NULL) { + kssl_err_set(kssl_err, SSL_R_KRB5_S_INIT, + "Error decoding authenticator body.\n"); + krb5rc = KRB5KRB_AP_ERR_BAD_INTEGRITY; + goto err; + } + + memset(&tm_time, 0, sizeof(struct tm)); + if (k_gmtime(auth->ctime, &tm_time) && + ((tr = mktime(&tm_time)) != (time_t)(-1))) { + now = time(&now); + tm_l = localtime(&now); + tl = mktime(tm_l); + tm_g = gmtime(&now); + tg = mktime(tm_g); + tz_offset = tg - tl; + + *atimep = (krb5_timestamp)(tr - tz_offset); + } +# ifdef KSSL_DEBUG + fprintf(stderr, "kssl_check_authent: returns %d for client time ", + *atimep); + if (auth && auth->ctime && auth->ctime->length && auth->ctime->data) + fprintf(stderr, "%.*s\n", auth->ctime->length, auth->ctime->data); + else + fprintf(stderr, "NULL\n"); +# endif /* KSSL_DEBUG */ + + err: + if (auth) + KRB5_AUTHENT_free((KRB5_AUTHENT *) auth); + if (dec_authent) + KRB5_ENCDATA_free(dec_authent); + if (unenc_authent) + free(unenc_authent); + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + return krb5rc; +} + +/* + * Replaces krb5_build_principal_ext(), with varargs length == 2 (svc, host), + * because I don't know how to stub varargs. Returns krb5_error_code == + * ENOMEM on alloc error, otherwise passes back newly constructed principal, + * which should be freed by caller. + */ +krb5_error_code kssl_build_principal_2( + /* + * UPDATE + */ krb5_context context, + /* + * OUT + */ krb5_principal *princ, + /* + * IN + */ int rlen, const char *realm, + /* + * IN + */ int slen, const char *svc, + /* + * IN + */ int hlen, const char *host) +{ + krb5_data *p_data = NULL; + krb5_principal new_p = NULL; + char *new_r = NULL; + + if ((p_data = (krb5_data *)calloc(2, sizeof(krb5_data))) == NULL || + (new_p = (krb5_principal)calloc(1, sizeof(krb5_principal_data))) + == NULL) + goto err; + new_p->length = 2; + new_p->data = p_data; + + if ((new_r = calloc(1, rlen + 1)) == NULL) + goto err; + memcpy(new_r, realm, rlen); + krb5_princ_set_realm_length(context, new_p, rlen); + krb5_princ_set_realm_data(context, new_p, new_r); + + if ((new_p->data[0].data = calloc(1, slen + 1)) == NULL) + goto err; + memcpy(new_p->data[0].data, svc, slen); + new_p->data[0].length = slen; + + if ((new_p->data[1].data = calloc(1, hlen + 1)) == NULL) + goto err; + memcpy(new_p->data[1].data, host, hlen); + new_p->data[1].length = hlen; + + krb5_princ_type(context, new_p) = KRB5_NT_UNKNOWN; + *princ = new_p; + return 0; + + err: + if (new_p && new_p[0].data) + free(new_p[0].data); + if (new_p && new_p[1].data) + free(new_p[1].data); + if (new_p) + free(new_p); + if (new_r) + free(new_r); + return ENOMEM; +} + +void SSL_set0_kssl_ctx(SSL *s, KSSL_CTX *kctx) +{ + s->kssl_ctx = kctx; +} + +KSSL_CTX *SSL_get0_kssl_ctx(SSL *s) +{ + return s->kssl_ctx; +} + +char *kssl_ctx_get0_client_princ(KSSL_CTX *kctx) +{ + if (kctx) + return kctx->client_princ; + return NULL; +} + +#else /* !OPENSSL_NO_KRB5 */ + +# if defined(PEDANTIC) || defined(OPENSSL_SYS_VMS) +static void *dummy = &dummy; +# endif + +#endif /* !OPENSSL_NO_KRB5 */ diff --git a/libs/openssl/ssl/s23_clnt.c b/libs/openssl/ssl/s23_clnt.c new file mode 100644 index 00000000..2b2855de --- /dev/null +++ b/libs/openssl/ssl/s23_clnt.c @@ -0,0 +1,790 @@ +/* ssl/s23_clnt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "ssl_locl.h" +#include +#include +#include +#include + +static const SSL_METHOD *ssl23_get_client_method(int ver); +static int ssl23_client_hello(SSL *s); +static int ssl23_get_server_hello(SSL *s); +static const SSL_METHOD *ssl23_get_client_method(int ver) +{ +#ifndef OPENSSL_NO_SSL2 + if (ver == SSL2_VERSION) + return (SSLv2_client_method()); +#endif +#ifndef OPENSSL_NO_SSL3 + if (ver == SSL3_VERSION) + return (SSLv3_client_method()); +#endif + if (ver == TLS1_VERSION) + return (TLSv1_client_method()); + else if (ver == TLS1_1_VERSION) + return (TLSv1_1_client_method()); + else if (ver == TLS1_2_VERSION) + return (TLSv1_2_client_method()); + else + return (NULL); +} + +IMPLEMENT_ssl23_meth_func(SSLv23_client_method, + ssl_undefined_function, + ssl23_connect, ssl23_get_client_method) + +int ssl23_connect(SSL *s) +{ + BUF_MEM *buf = NULL; + unsigned long Time = (unsigned long)time(NULL); + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state; + + RAND_add(&Time, sizeof(Time), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_BEFORE: + case SSL_ST_CONNECT: + case SSL_ST_BEFORE | SSL_ST_CONNECT: + case SSL_ST_OK | SSL_ST_CONNECT: + + if (s->session != NULL) { + SSLerr(SSL_F_SSL23_CONNECT, + SSL_R_SSL23_DOING_SESSION_ID_REUSE); + ret = -1; + goto end; + } + s->server = 0; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + /* s->version=TLS1_VERSION; */ + s->type = SSL_ST_CONNECT; + + if (s->init_buf == NULL) { + if ((buf = BUF_MEM_new()) == NULL) { + ret = -1; + goto end; + } + if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { + ret = -1; + goto end; + } + s->init_buf = buf; + buf = NULL; + } + + if (!ssl3_setup_buffers(s)) { + ret = -1; + goto end; + } + + ssl3_init_finished_mac(s); + + s->state = SSL23_ST_CW_CLNT_HELLO_A; + s->ctx->stats.sess_connect++; + s->init_num = 0; + break; + + case SSL23_ST_CW_CLNT_HELLO_A: + case SSL23_ST_CW_CLNT_HELLO_B: + + s->shutdown = 0; + ret = ssl23_client_hello(s); + if (ret <= 0) + goto end; + s->state = SSL23_ST_CR_SRVR_HELLO_A; + s->init_num = 0; + + break; + + case SSL23_ST_CR_SRVR_HELLO_A: + case SSL23_ST_CR_SRVR_HELLO_B: + ret = ssl23_get_server_hello(s); + if (ret >= 0) + cb = NULL; + goto end; + /* break; */ + + default: + SSLerr(SSL_F_SSL23_CONNECT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + if (s->debug) { + (void)BIO_flush(s->wbio); + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_CONNECT_LOOP, 1); + s->state = new_state; + } + } + end: + s->in_handshake--; + if (buf != NULL) + BUF_MEM_free(buf); + if (cb != NULL) + cb(s, SSL_CB_CONNECT_EXIT, ret); + return (ret); +} + +static int ssl23_no_ssl2_ciphers(SSL *s) +{ + SSL_CIPHER *cipher; + STACK_OF(SSL_CIPHER) *ciphers; + int i; + ciphers = SSL_get_ciphers(s); + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + cipher = sk_SSL_CIPHER_value(ciphers, i); + if (cipher->algorithm_ssl == SSL_SSLV2) + return 0; + } + return 1; +} + +/* + * Fill a ClientRandom or ServerRandom field of length len. Returns <= 0 on + * failure, 1 on success. + */ +int ssl_fill_hello_random(SSL *s, int server, unsigned char *result, int len) +{ + int send_time = 0; + + if (len < 4) + return 0; + if (server) + send_time = (s->mode & SSL_MODE_SEND_SERVERHELLO_TIME) != 0; + else + send_time = (s->mode & SSL_MODE_SEND_CLIENTHELLO_TIME) != 0; + if (send_time) { + unsigned long Time = (unsigned long)time(NULL); + unsigned char *p = result; + l2n(Time, p); + return RAND_pseudo_bytes(p, len - 4); + } else + return RAND_pseudo_bytes(result, len); +} + +static int ssl23_client_hello(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; + int i, ch_len; + unsigned long l; + int ssl2_compat; + int version = 0, version_major, version_minor; +#ifndef OPENSSL_NO_COMP + int j; + SSL_COMP *comp; +#endif + int ret; + unsigned long mask, options = s->options; + + ssl2_compat = (options & SSL_OP_NO_SSLv2) ? 0 : 1; + + if (ssl2_compat && ssl23_no_ssl2_ciphers(s)) + ssl2_compat = 0; + + /* + * SSL_OP_NO_X disables all protocols above X *if* there are + * some protocols below X enabled. This is required in order + * to maintain "version capability" vector contiguous. So + * that if application wants to disable TLS1.0 in favour of + * TLS1>=1, it would be insufficient to pass SSL_NO_TLSv1, the + * answer is SSL_OP_NO_TLSv1|SSL_OP_NO_SSLv3|SSL_OP_NO_SSLv2. + */ + mask = SSL_OP_NO_TLSv1_1 | SSL_OP_NO_TLSv1 +#if !defined(OPENSSL_NO_SSL3) + | SSL_OP_NO_SSLv3 +#endif +#if !defined(OPENSSL_NO_SSL2) + | (ssl2_compat ? SSL_OP_NO_SSLv2 : 0) +#endif + ; +#if !defined(OPENSSL_NO_TLS1_2_CLIENT) + version = TLS1_2_VERSION; + + if ((options & SSL_OP_NO_TLSv1_2) && (options & mask) != mask) + version = TLS1_1_VERSION; +#else + version = TLS1_1_VERSION; +#endif + mask &= ~SSL_OP_NO_TLSv1_1; + if ((options & SSL_OP_NO_TLSv1_1) && (options & mask) != mask) + version = TLS1_VERSION; + mask &= ~SSL_OP_NO_TLSv1; +#if !defined(OPENSSL_NO_SSL3) + if ((options & SSL_OP_NO_TLSv1) && (options & mask) != mask) + version = SSL3_VERSION; + mask &= ~SSL_OP_NO_SSLv3; +#endif +#if !defined(OPENSSL_NO_SSL2) + if ((options & SSL_OP_NO_SSLv3) && (options & mask) != mask) + version = SSL2_VERSION; +#endif + +#ifndef OPENSSL_NO_TLSEXT + if (version != SSL2_VERSION) { + /* + * have to disable SSL 2.0 compatibility if we need TLS extensions + */ + + if (s->tlsext_hostname != NULL) + ssl2_compat = 0; + if (s->tlsext_status_type != -1) + ssl2_compat = 0; +# ifdef TLSEXT_TYPE_opaque_prf_input + if (s->ctx->tlsext_opaque_prf_input_callback != 0 + || s->tlsext_opaque_prf_input != NULL) + ssl2_compat = 0; +# endif + } +#endif + + buf = (unsigned char *)s->init_buf->data; + if (s->state == SSL23_ST_CW_CLNT_HELLO_A) { + /* + * Since we're sending s23 client hello, we're not reusing a session, as + * we'd be using the method from the saved session instead + */ + if (!ssl_get_new_session(s, 0)) { + return -1; + } + + p = s->s3->client_random; + if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0) + return -1; + + if (version == TLS1_2_VERSION) { + version_major = TLS1_2_VERSION_MAJOR; + version_minor = TLS1_2_VERSION_MINOR; + } else if (version == TLS1_1_VERSION) { + version_major = TLS1_1_VERSION_MAJOR; + version_minor = TLS1_1_VERSION_MINOR; + } else if (version == TLS1_VERSION) { + version_major = TLS1_VERSION_MAJOR; + version_minor = TLS1_VERSION_MINOR; + } +#ifdef OPENSSL_FIPS + else if (FIPS_mode()) { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, + SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + return -1; + } +#endif + else if (version == SSL3_VERSION) { + version_major = SSL3_VERSION_MAJOR; + version_minor = SSL3_VERSION_MINOR; + } else if (version == SSL2_VERSION) { + version_major = SSL2_VERSION_MAJOR; + version_minor = SSL2_VERSION_MINOR; + } else { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_PROTOCOLS_AVAILABLE); + return (-1); + } + + s->client_version = version; + + if (ssl2_compat) { + /* create SSL 2.0 compatible Client Hello */ + + /* two byte record header will be written last */ + d = &(buf[2]); + p = d + 9; /* leave space for message type, version, + * individual length fields */ + + *(d++) = SSL2_MT_CLIENT_HELLO; + *(d++) = version_major; + *(d++) = version_minor; + + /* Ciphers supported */ + i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), p, 0); + if (i == 0) { + /* no ciphers */ + SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); + return -1; + } + s2n(i, d); + p += i; + + /* + * put in the session-id length (zero since there is no reuse) + */ + s2n(0, d); + + if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) + ch_len = SSL2_CHALLENGE_LENGTH; + else + ch_len = SSL2_MAX_CHALLENGE_LENGTH; + + /* write out sslv2 challenge */ + /* + * Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because it + * is one of SSL2_MAX_CHALLENGE_LENGTH (32) or + * SSL2_MAX_CHALLENGE_LENGTH (16), but leave the check in for + * futurproofing + */ + if (SSL3_RANDOM_SIZE < ch_len) + i = SSL3_RANDOM_SIZE; + else + i = ch_len; + s2n(i, d); + memset(&(s->s3->client_random[0]), 0, SSL3_RANDOM_SIZE); + if (RAND_pseudo_bytes + (&(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i) <= 0) + return -1; + + memcpy(p, &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i); + p += i; + + i = p - &(buf[2]); + buf[0] = ((i >> 8) & 0xff) | 0x80; + buf[1] = (i & 0xff); + + /* number of bytes to write */ + s->init_num = i + 2; + s->init_off = 0; + + ssl3_finish_mac(s, &(buf[2]), i); + } else { + /* create Client Hello in SSL 3.0/TLS 1.0 format */ + + /* + * do the record header (5 bytes) and handshake message header (4 + * bytes) last + */ + d = p = &(buf[9]); + + *(p++) = version_major; + *(p++) = version_minor; + + /* Random stuff */ + memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /* Session ID (zero since there is no reuse) */ + *(p++) = 0; + + /* Ciphers supported (using SSL 3.0/TLS 1.0 format) */ + i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), + ssl3_put_cipher_by_char); + if (i == 0) { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); + return -1; + } +#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH + /* + * Some servers hang if client hello > 256 bytes as hack + * workaround chop number of supported ciphers to keep it well + * below this if we use TLS v1.2 + */ + if (TLS1_get_version(s) >= TLS1_2_VERSION + && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH) + i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1; +#endif + s2n(i, p); + p += i; + + /* COMPRESSION */ +#ifdef OPENSSL_NO_COMP + *(p++) = 1; +#else + if ((s->options & SSL_OP_NO_COMPRESSION) + || !s->ctx->comp_methods) + j = 0; + else + j = sk_SSL_COMP_num(s->ctx->comp_methods); + *(p++) = 1 + j; + for (i = 0; i < j; i++) { + comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); + *(p++) = comp->id; + } +#endif + *(p++) = 0; /* Add the NULL method */ + +#ifndef OPENSSL_NO_TLSEXT + /* TLS extensions */ + if (ssl_prepare_clienthello_tlsext(s) <= 0) { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); + return -1; + } + if ((p = + ssl_add_clienthello_tlsext(s, p, + buf + + SSL3_RT_MAX_PLAIN_LENGTH)) == + NULL) { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + return -1; + } +#endif + + l = p - d; + + /* fill in 4-byte handshake header */ + d = &(buf[5]); + *(d++) = SSL3_MT_CLIENT_HELLO; + l2n3(l, d); + + l += 4; + + if (l > SSL3_RT_MAX_PLAIN_LENGTH) { + SSLerr(SSL_F_SSL23_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* fill in 5-byte record header */ + d = buf; + *(d++) = SSL3_RT_HANDSHAKE; + *(d++) = version_major; + /* + * Some servers hang if we use long client hellos and a record + * number > TLS 1.0. + */ + if (TLS1_get_client_version(s) > TLS1_VERSION) + *(d++) = 1; + else + *(d++) = version_minor; + s2n((int)l, d); + + /* number of bytes to write */ + s->init_num = p - buf; + s->init_off = 0; + + ssl3_finish_mac(s, &(buf[5]), s->init_num - 5); + } + + s->state = SSL23_ST_CW_CLNT_HELLO_B; + s->init_off = 0; + } + + /* SSL3_ST_CW_CLNT_HELLO_B */ + ret = ssl23_write_bytes(s); + + if ((ret >= 2) && s->msg_callback) { + /* Client Hello has been sent; tell msg_callback */ + + if (ssl2_compat) + s->msg_callback(1, SSL2_VERSION, 0, s->init_buf->data + 2, + ret - 2, s, s->msg_callback_arg); + else + s->msg_callback(1, version, SSL3_RT_HANDSHAKE, + s->init_buf->data + 5, ret - 5, s, + s->msg_callback_arg); + } + + return ret; +} + +static int ssl23_get_server_hello(SSL *s) +{ + char buf[8]; + unsigned char *p; + int i; + int n; + + n = ssl23_read_bytes(s, 7); + + if (n != 7) + return (n); + p = s->packet; + + memcpy(buf, p, n); + + if ((p[0] & 0x80) && (p[2] == SSL2_MT_SERVER_HELLO) && + (p[5] == 0x00) && (p[6] == 0x02)) { +#ifdef OPENSSL_NO_SSL2 + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); + goto err; +#else + /* we are talking sslv2 */ + /* + * we need to clean up the SSLv3 setup and put in the sslv2 stuff. + */ + int ch_len; + + if (s->options & SSL_OP_NO_SSLv2) { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); + goto err; + } + if (s->s2 == NULL) { + if (!ssl2_new(s)) + goto err; + } else + ssl2_clear(s); + + if (s->options & SSL_OP_NETSCAPE_CHALLENGE_BUG) + ch_len = SSL2_CHALLENGE_LENGTH; + else + ch_len = SSL2_MAX_CHALLENGE_LENGTH; + + /* write out sslv2 challenge */ + /* + * Note that ch_len must be <= SSL3_RANDOM_SIZE (32), because it is + * one of SSL2_MAX_CHALLENGE_LENGTH (32) or SSL2_MAX_CHALLENGE_LENGTH + * (16), but leave the check in for futurproofing + */ + i = (SSL3_RANDOM_SIZE < ch_len) + ? SSL3_RANDOM_SIZE : ch_len; + s->s2->challenge_length = i; + memcpy(s->s2->challenge, + &(s->s3->client_random[SSL3_RANDOM_SIZE - i]), i); + + if (s->s3 != NULL) + ssl3_free(s); + + if (!BUF_MEM_grow_clean(s->init_buf, + SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, ERR_R_BUF_LIB); + goto err; + } + + s->state = SSL2_ST_GET_SERVER_HELLO_A; + if (!(s->client_version == SSL2_VERSION)) + /* + * use special padding (SSL 3.0 draft/RFC 2246, App. E.2) + */ + s->s2->ssl2_rollback = 1; + + /* + * setup the 7 bytes we have read so we get them from the sslv2 + * buffer + */ + s->rstate = SSL_ST_READ_HEADER; + s->packet_length = n; + s->packet = &(s->s2->rbuf[0]); + memcpy(s->packet, buf, n); + s->s2->rbuf_left = n; + s->s2->rbuf_offs = 0; + + /* we have already written one */ + s->s2->write_sequence = 1; + + s->method = SSLv2_client_method(); + s->handshake_func = s->method->ssl_connect; +#endif + } else if (p[1] == SSL3_VERSION_MAJOR && + p[2] <= TLS1_2_VERSION_MINOR && + ((p[0] == SSL3_RT_HANDSHAKE && p[5] == SSL3_MT_SERVER_HELLO) || + (p[0] == SSL3_RT_ALERT && p[3] == 0 && p[4] == 2))) { + /* we have sslv3 or tls1 (server hello or alert) */ + +#ifndef OPENSSL_NO_SSL3 + if ((p[2] == SSL3_VERSION_MINOR) && !(s->options & SSL_OP_NO_SSLv3)) { +# ifdef OPENSSL_FIPS + if (FIPS_mode()) { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, + SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + goto err; + } +# endif + s->version = SSL3_VERSION; + s->method = SSLv3_client_method(); + } else +#endif + if ((p[2] == TLS1_VERSION_MINOR) && !(s->options & SSL_OP_NO_TLSv1)) { + s->version = TLS1_VERSION; + s->method = TLSv1_client_method(); + } else if ((p[2] == TLS1_1_VERSION_MINOR) && + !(s->options & SSL_OP_NO_TLSv1_1)) { + s->version = TLS1_1_VERSION; + s->method = TLSv1_1_client_method(); + } else if ((p[2] == TLS1_2_VERSION_MINOR) && + !(s->options & SSL_OP_NO_TLSv1_2)) { + s->version = TLS1_2_VERSION; + s->method = TLSv1_2_client_method(); + } else { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); + goto err; + } + + s->session->ssl_version = s->version; + + /* ensure that TLS_MAX_VERSION is up-to-date */ + OPENSSL_assert(s->version <= TLS_MAX_VERSION); + + if (p[0] == SSL3_RT_ALERT && p[5] != SSL3_AL_WARNING) { + /* fatal alert */ + + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int j; + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + i = p[5]; + if (cb != NULL) { + j = (i << 8) | p[6]; + cb(s, SSL_CB_READ_ALERT, j); + } + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_ALERT, p + 5, 2, s, + s->msg_callback_arg); + + s->rwstate = SSL_NOTHING; + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_AD_REASON_OFFSET + p[6]); + goto err; + } + + if (!ssl_init_wbio_buffer(s, 1)) + goto err; + + /* we are in this state */ + s->state = SSL3_ST_CR_SRVR_HELLO_A; + + /* + * put the 7 bytes we have read into the input buffer for SSLv3 + */ + s->rstate = SSL_ST_READ_HEADER; + s->packet_length = n; + if (s->s3->rbuf.buf == NULL) + if (!ssl3_setup_read_buffer(s)) + goto err; + s->packet = &(s->s3->rbuf.buf[0]); + memcpy(s->packet, buf, n); + s->s3->rbuf.left = n; + s->s3->rbuf.offset = 0; + + s->handshake_func = s->method->ssl_connect; + } else { + SSLerr(SSL_F_SSL23_GET_SERVER_HELLO, SSL_R_UNKNOWN_PROTOCOL); + goto err; + } + s->init_num = 0; + + return (SSL_connect(s)); + err: + return (-1); +} diff --git a/libs/openssl/ssl/s23_lib.c b/libs/openssl/ssl/s23_lib.c new file mode 100644 index 00000000..9056d39e --- /dev/null +++ b/libs/openssl/ssl/s23_lib.c @@ -0,0 +1,185 @@ +/* ssl/s23_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "ssl_locl.h" + +long ssl23_default_timeout(void) +{ + return (300); +} + +int ssl23_num_ciphers(void) +{ + return (ssl3_num_ciphers() +#ifndef OPENSSL_NO_SSL2 + + ssl2_num_ciphers() +#endif + ); +} + +const SSL_CIPHER *ssl23_get_cipher(unsigned int u) +{ + unsigned int uu = ssl3_num_ciphers(); + + if (u < uu) + return (ssl3_get_cipher(u)); + else +#ifndef OPENSSL_NO_SSL2 + return (ssl2_get_cipher(u - uu)); +#else + return (NULL); +#endif +} + +/* + * This function needs to check if the ciphers required are actually + * available + */ +const SSL_CIPHER *ssl23_get_cipher_by_char(const unsigned char *p) +{ + const SSL_CIPHER *cp; + + cp = ssl3_get_cipher_by_char(p); +#ifndef OPENSSL_NO_SSL2 + if (cp == NULL) + cp = ssl2_get_cipher_by_char(p); +#endif + return (cp); +} + +int ssl23_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) +{ + long l; + + /* We can write SSLv2 and SSLv3 ciphers */ + /* but no ECC ciphers */ + if (c->algorithm_mkey == SSL_kECDHr || + c->algorithm_mkey == SSL_kECDHe || + c->algorithm_mkey == SSL_kEECDH || + c->algorithm_auth == SSL_aECDH || c->algorithm_auth == SSL_aECDSA) + return 0; + if (p != NULL) { + l = c->id; + p[0] = ((unsigned char)(l >> 16L)) & 0xFF; + p[1] = ((unsigned char)(l >> 8L)) & 0xFF; + p[2] = ((unsigned char)(l)) & 0xFF; + } + return (3); +} + +int ssl23_read(SSL *s, void *buf, int len) +{ + int n; + + clear_sys_error(); + if (SSL_in_init(s) && (!s->in_handshake)) { + n = s->handshake_func(s); + if (n < 0) + return (n); + if (n == 0) { + SSLerr(SSL_F_SSL23_READ, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + return (SSL_read(s, buf, len)); + } else { + ssl_undefined_function(s); + return (-1); + } +} + +int ssl23_peek(SSL *s, void *buf, int len) +{ + int n; + + clear_sys_error(); + if (SSL_in_init(s) && (!s->in_handshake)) { + n = s->handshake_func(s); + if (n < 0) + return (n); + if (n == 0) { + SSLerr(SSL_F_SSL23_PEEK, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + return (SSL_peek(s, buf, len)); + } else { + ssl_undefined_function(s); + return (-1); + } +} + +int ssl23_write(SSL *s, const void *buf, int len) +{ + int n; + + clear_sys_error(); + if (SSL_in_init(s) && (!s->in_handshake)) { + n = s->handshake_func(s); + if (n < 0) + return (n); + if (n == 0) { + SSLerr(SSL_F_SSL23_WRITE, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + return (SSL_write(s, buf, len)); + } else { + ssl_undefined_function(s); + return (-1); + } +} diff --git a/libs/openssl/ssl/s23_meth.c b/libs/openssl/ssl/s23_meth.c new file mode 100644 index 00000000..eb760987 --- /dev/null +++ b/libs/openssl/ssl/s23_meth.c @@ -0,0 +1,89 @@ +/* ssl/s23_meth.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "ssl_locl.h" + +static const SSL_METHOD *ssl23_get_method(int ver); +static const SSL_METHOD *ssl23_get_method(int ver) +{ +#ifndef OPENSSL_NO_SSL2 + if (ver == SSL2_VERSION) + return (SSLv2_method()); + else +#endif +#ifndef OPENSSL_NO_SSL3 + if (ver == SSL3_VERSION) + return (SSLv3_method()); + else +#endif +#ifndef OPENSSL_NO_TLS1 + if (ver == TLS1_VERSION) + return (TLSv1_method()); + else if (ver == TLS1_1_VERSION) + return (TLSv1_1_method()); + else if (ver == TLS1_2_VERSION) + return (TLSv1_2_method()); + else +#endif + return (NULL); +} + +IMPLEMENT_ssl23_meth_func(SSLv23_method, + ssl23_accept, ssl23_connect, ssl23_get_method) diff --git a/libs/openssl/ssl/s23_pkt.c b/libs/openssl/ssl/s23_pkt.c new file mode 100644 index 00000000..efc86478 --- /dev/null +++ b/libs/openssl/ssl/s23_pkt.c @@ -0,0 +1,113 @@ +/* ssl/s23_pkt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#define USE_SOCKETS +#include "ssl_locl.h" +#include +#include + +int ssl23_write_bytes(SSL *s) +{ + int i, num, tot; + char *buf; + + buf = s->init_buf->data; + tot = s->init_off; + num = s->init_num; + for (;;) { + s->rwstate = SSL_WRITING; + i = BIO_write(s->wbio, &(buf[tot]), num); + if (i <= 0) { + s->init_off = tot; + s->init_num = num; + return (i); + } + s->rwstate = SSL_NOTHING; + if (i == num) + return (tot + i); + + num -= i; + tot += i; + } +} + +/* return regularly only when we have read (at least) 'n' bytes */ +int ssl23_read_bytes(SSL *s, int n) +{ + unsigned char *p; + int j; + + if (s->packet_length < (unsigned int)n) { + p = s->packet; + + for (;;) { + s->rwstate = SSL_READING; + j = BIO_read(s->rbio, (char *)&(p[s->packet_length]), + n - s->packet_length); + if (j <= 0) + return (j); + s->rwstate = SSL_NOTHING; + s->packet_length += j; + if (s->packet_length >= (unsigned int)n) + return (s->packet_length); + } + } + return (n); +} diff --git a/libs/openssl/ssl/s23_srvr.c b/libs/openssl/ssl/s23_srvr.c new file mode 100644 index 00000000..50f98dce --- /dev/null +++ b/libs/openssl/ssl/s23_srvr.c @@ -0,0 +1,647 @@ +/* ssl/s23_srvr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "ssl_locl.h" +#include +#include +#include +#include +#ifdef OPENSSL_FIPS +# include +#endif + +static const SSL_METHOD *ssl23_get_server_method(int ver); +int ssl23_get_client_hello(SSL *s); +static const SSL_METHOD *ssl23_get_server_method(int ver) +{ +#ifndef OPENSSL_NO_SSL2 + if (ver == SSL2_VERSION) + return (SSLv2_server_method()); +#endif +#ifndef OPENSSL_NO_SSL3 + if (ver == SSL3_VERSION) + return (SSLv3_server_method()); +#endif + if (ver == TLS1_VERSION) + return (TLSv1_server_method()); + else if (ver == TLS1_1_VERSION) + return (TLSv1_1_server_method()); + else if (ver == TLS1_2_VERSION) + return (TLSv1_2_server_method()); + else + return (NULL); +} + +IMPLEMENT_ssl23_meth_func(SSLv23_server_method, + ssl23_accept, + ssl_undefined_function, ssl23_get_server_method) + +int ssl23_accept(SSL *s) +{ + BUF_MEM *buf; + unsigned long Time = (unsigned long)time(NULL); + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state; + + RAND_add(&Time, sizeof(Time), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_BEFORE: + case SSL_ST_ACCEPT: + case SSL_ST_BEFORE | SSL_ST_ACCEPT: + case SSL_ST_OK | SSL_ST_ACCEPT: + + s->server = 1; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + /* s->version=SSL3_VERSION; */ + s->type = SSL_ST_ACCEPT; + + if (s->init_buf == NULL) { + if ((buf = BUF_MEM_new()) == NULL) { + ret = -1; + goto end; + } + if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { + BUF_MEM_free(buf); + ret = -1; + goto end; + } + s->init_buf = buf; + } + + ssl3_init_finished_mac(s); + + s->state = SSL23_ST_SR_CLNT_HELLO_A; + s->ctx->stats.sess_accept++; + s->init_num = 0; + break; + + case SSL23_ST_SR_CLNT_HELLO_A: + case SSL23_ST_SR_CLNT_HELLO_B: + + s->shutdown = 0; + ret = ssl23_get_client_hello(s); + if (ret >= 0) + cb = NULL; + goto end; + /* break; */ + + default: + SSLerr(SSL_F_SSL23_ACCEPT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_ACCEPT_LOOP, 1); + s->state = new_state; + } + } + end: + s->in_handshake--; + if (cb != NULL) + cb(s, SSL_CB_ACCEPT_EXIT, ret); + return (ret); +} + +int ssl23_get_client_hello(SSL *s) +{ + /*- + * Request this many bytes in initial read. + * We can detect SSL 3.0/TLS 1.0 Client Hellos + * ('type == 3') correctly only when the following + * is in a single record, which is not guaranteed by + * the protocol specification: + * Byte Content + * 0 type \ + * 1/2 version > record header + * 3/4 length / + * 5 msg_type \ + * 6-8 length > Client Hello message + * 9/10 client_version / + */ + char buf_space[11]; + char *buf = &(buf_space[0]); + unsigned char *p, *d, *d_len, *dd; + unsigned int i; + unsigned int csl, sil, cl; + int n = 0, j; + int type = 0; + int v[2]; + + if (s->state == SSL23_ST_SR_CLNT_HELLO_A) { + /* read the initial header */ + v[0] = v[1] = 0; + + if (!ssl3_setup_buffers(s)) + goto err; + + n = ssl23_read_bytes(s, sizeof buf_space); + if (n != sizeof buf_space) + return (n); /* n == -1 || n == 0 */ + + p = s->packet; + + memcpy(buf, p, n); + + if ((p[0] & 0x80) && (p[2] == SSL2_MT_CLIENT_HELLO)) { + /* + * SSLv2 header + */ + if ((p[3] == 0x00) && (p[4] == 0x02)) { + v[0] = p[3]; + v[1] = p[4]; + /* SSLv2 */ + if (!(s->options & SSL_OP_NO_SSLv2)) + type = 1; + } else if (p[3] == SSL3_VERSION_MAJOR) { + v[0] = p[3]; + v[1] = p[4]; + /* SSLv3/TLSv1 */ + if (p[4] >= TLS1_VERSION_MINOR) { + if (p[4] >= TLS1_2_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_2)) { + s->version = TLS1_2_VERSION; + s->state = SSL23_ST_SR_CLNT_HELLO_B; + } else if (p[4] >= TLS1_1_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_1)) { + s->version = TLS1_1_VERSION; + /* + * type=2; + *//* + * done later to survive restarts + */ + s->state = SSL23_ST_SR_CLNT_HELLO_B; + } else if (!(s->options & SSL_OP_NO_TLSv1)) { + s->version = TLS1_VERSION; + /* + * type=2; + *//* + * done later to survive restarts + */ + s->state = SSL23_ST_SR_CLNT_HELLO_B; + } else if (!(s->options & SSL_OP_NO_SSLv3)) { + s->version = SSL3_VERSION; + /* type=2; */ + s->state = SSL23_ST_SR_CLNT_HELLO_B; + } else if (!(s->options & SSL_OP_NO_SSLv2)) { + type = 1; + } + } else if (!(s->options & SSL_OP_NO_SSLv3)) { + s->version = SSL3_VERSION; + /* type=2; */ + s->state = SSL23_ST_SR_CLNT_HELLO_B; + } else if (!(s->options & SSL_OP_NO_SSLv2)) + type = 1; + + } + } + /* p[4] < 5 ... silly record length? */ + else if ((p[0] == SSL3_RT_HANDSHAKE) && + (p[1] == SSL3_VERSION_MAJOR) && + (p[5] == SSL3_MT_CLIENT_HELLO) && ((p[3] == 0 && p[4] < 5) + || (p[9] >= p[1]))) { + /* + * SSLv3 or tls1 header + */ + + v[0] = p[1]; /* major version (= SSL3_VERSION_MAJOR) */ + /* + * We must look at client_version inside the Client Hello message + * to get the correct minor version. However if we have only a + * pathologically small fragment of the Client Hello message, this + * would be difficult, and we'd have to read more records to find + * out. No known SSL 3.0 client fragments ClientHello like this, + * so we simply reject such connections to avoid protocol version + * downgrade attacks. + */ + if (p[3] == 0 && p[4] < 6) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_TOO_SMALL); + goto err; + } + /* + * if major version number > 3 set minor to a value which will + * use the highest version 3 we support. If TLS 2.0 ever appears + * we will need to revise this.... + */ + if (p[9] > SSL3_VERSION_MAJOR) + v[1] = 0xff; + else + v[1] = p[10]; /* minor version according to client_version */ + if (v[1] >= TLS1_VERSION_MINOR) { + if (v[1] >= TLS1_2_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_2)) { + s->version = TLS1_2_VERSION; + type = 3; + } else if (v[1] >= TLS1_1_VERSION_MINOR && + !(s->options & SSL_OP_NO_TLSv1_1)) { + s->version = TLS1_1_VERSION; + type = 3; + } else if (!(s->options & SSL_OP_NO_TLSv1)) { + s->version = TLS1_VERSION; + type = 3; + } else if (!(s->options & SSL_OP_NO_SSLv3)) { + s->version = SSL3_VERSION; + type = 3; + } + } else { + /* client requests SSL 3.0 */ + if (!(s->options & SSL_OP_NO_SSLv3)) { + s->version = SSL3_VERSION; + type = 3; + } else if (!(s->options & SSL_OP_NO_TLSv1)) { + /* + * we won't be able to use TLS of course, but this will + * send an appropriate alert + */ + s->version = TLS1_VERSION; + type = 3; + } + } + } else if ((strncmp("GET ", (char *)p, 4) == 0) || + (strncmp("POST ", (char *)p, 5) == 0) || + (strncmp("HEAD ", (char *)p, 5) == 0) || + (strncmp("PUT ", (char *)p, 4) == 0)) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_HTTP_REQUEST); + goto err; + } else if (strncmp("CONNECT", (char *)p, 7) == 0) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_HTTPS_PROXY_REQUEST); + goto err; + } + } + + /* ensure that TLS_MAX_VERSION is up-to-date */ + OPENSSL_assert(s->version <= TLS_MAX_VERSION); + +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (s->version < TLS1_VERSION)) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, + SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + goto err; + } +#endif + + if (s->state == SSL23_ST_SR_CLNT_HELLO_B) { + /* + * we have SSLv3/TLSv1 in an SSLv2 header (other cases skip this + * state) + */ + + type = 2; + p = s->packet; + v[0] = p[3]; /* == SSL3_VERSION_MAJOR */ + v[1] = p[4]; + + /*- + * An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2 + * header is sent directly on the wire, not wrapped as a TLS + * record. It's format is: + * Byte Content + * 0-1 msg_length + * 2 msg_type + * 3-4 version + * 5-6 cipher_spec_length + * 7-8 session_id_length + * 9-10 challenge_length + * ... ... + */ + n = ((p[0] & 0x7f) << 8) | p[1]; + if (n > (1024 * 4)) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_RECORD_TOO_LARGE); + goto err; + } + if (n < 9) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, + SSL_R_RECORD_LENGTH_MISMATCH); + goto err; + } + + j = ssl23_read_bytes(s, n + 2); + /* + * We previously read 11 bytes, so if j > 0, we must have j == n+2 == + * s->packet_length. We have at least 11 valid packet bytes. + */ + if (j <= 0) + return (j); + + ssl3_finish_mac(s, s->packet + 2, s->packet_length - 2); + + /* CLIENT-HELLO */ + if (s->msg_callback) + s->msg_callback(0, SSL2_VERSION, 0, s->packet + 2, + s->packet_length - 2, s, s->msg_callback_arg); + + p = s->packet; + p += 5; + n2s(p, csl); + n2s(p, sil); + n2s(p, cl); + d = (unsigned char *)s->init_buf->data; + if ((csl + sil + cl + 11) != s->packet_length) { /* We can't have TLS + * extensions in SSL + * 2.0 format * + * Client Hello, can + * we? Error + * condition should + * be * '>' + * otherweise */ + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, + SSL_R_RECORD_LENGTH_MISMATCH); + goto err; + } + + /* record header: msg_type ... */ + *(d++) = SSL3_MT_CLIENT_HELLO; + /* ... and length (actual value will be written later) */ + d_len = d; + d += 3; + + /* client_version */ + *(d++) = SSL3_VERSION_MAJOR; /* == v[0] */ + *(d++) = v[1]; + + /* lets populate the random area */ + /* get the challenge_length */ + i = (cl > SSL3_RANDOM_SIZE) ? SSL3_RANDOM_SIZE : cl; + memset(d, 0, SSL3_RANDOM_SIZE); + memcpy(&(d[SSL3_RANDOM_SIZE - i]), &(p[csl + sil]), i); + d += SSL3_RANDOM_SIZE; + + /* no session-id reuse */ + *(d++) = 0; + + /* ciphers */ + j = 0; + dd = d; + d += 2; + for (i = 0; i < csl; i += 3) { + if (p[i] != 0) + continue; + *(d++) = p[i + 1]; + *(d++) = p[i + 2]; + j += 2; + } + s2n(j, dd); + + /* COMPRESSION */ + *(d++) = 1; + *(d++) = 0; + +#if 0 + /* copy any remaining data with may be extensions */ + p = p + csl + sil + cl; + while (p < s->packet + s->packet_length) { + *(d++) = *(p++); + } +#endif + + i = (d - (unsigned char *)s->init_buf->data) - 4; + l2n3((long)i, d_len); + + /* get the data reused from the init_buf */ + s->s3->tmp.reuse_message = 1; + s->s3->tmp.message_type = SSL3_MT_CLIENT_HELLO; + s->s3->tmp.message_size = i; + } + + /* imaginary new state (for program structure): */ + /* s->state = SSL23_SR_CLNT_HELLO_C */ + + if (type == 1) { +#ifdef OPENSSL_NO_SSL2 + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); + goto err; +#else + /* we are talking sslv2 */ + /* + * we need to clean up the SSLv3/TLSv1 setup and put in the sslv2 + * stuff. + */ + + if (s->s2 == NULL) { + if (!ssl2_new(s)) + goto err; + } else + ssl2_clear(s); + + if (s->s3 != NULL) + ssl3_free(s); + + if (!BUF_MEM_grow_clean(s->init_buf, + SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { + goto err; + } + + s->state = SSL2_ST_GET_CLIENT_HELLO_A; + if (s->options & SSL_OP_NO_TLSv1 && s->options & SSL_OP_NO_SSLv3) + s->s2->ssl2_rollback = 0; + else + /* + * reject SSL 2.0 session if client supports SSL 3.0 or TLS 1.0 + * (SSL 3.0 draft/RFC 2246, App. E.2) + */ + s->s2->ssl2_rollback = 1; + + /* + * setup the n bytes we have read so we get them from the sslv2 + * buffer + */ + s->rstate = SSL_ST_READ_HEADER; + s->packet_length = n; + s->packet = &(s->s2->rbuf[0]); + memcpy(s->packet, buf, n); + s->s2->rbuf_left = n; + s->s2->rbuf_offs = 0; + + s->method = SSLv2_server_method(); + s->handshake_func = s->method->ssl_accept; +#endif + } + + if ((type == 2) || (type == 3)) { + /* + * we have SSLv3/TLSv1 (type 2: SSL2 style, type 3: SSL3/TLS style) + */ + const SSL_METHOD *new_method; + new_method = ssl23_get_server_method(s->version); + if (new_method == NULL) { + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNSUPPORTED_PROTOCOL); + goto err; + } + s->method = new_method; + + if (!ssl_init_wbio_buffer(s, 1)) + goto err; + + /* we are in this state */ + s->state = SSL3_ST_SR_CLNT_HELLO_A; + + if (type == 3) { + /* + * put the 'n' bytes we have read into the input buffer for SSLv3 + */ + s->rstate = SSL_ST_READ_HEADER; + s->packet_length = n; + if (s->s3->rbuf.buf == NULL) + if (!ssl3_setup_read_buffer(s)) + goto err; + + s->packet = &(s->s3->rbuf.buf[0]); + memcpy(s->packet, buf, n); + s->s3->rbuf.left = n; + s->s3->rbuf.offset = 0; + } else { + s->packet_length = 0; + s->s3->rbuf.left = 0; + s->s3->rbuf.offset = 0; + } +#if 0 /* ssl3_get_client_hello does this */ + s->client_version = (v[0] << 8) | v[1]; +#endif + s->handshake_func = s->method->ssl_accept; + } + + if ((type < 1) || (type > 3)) { + /* bad, very bad */ + SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO, SSL_R_UNKNOWN_PROTOCOL); + goto err; + } + s->init_num = 0; + + if (buf != buf_space) + OPENSSL_free(buf); + return (SSL_accept(s)); + err: + if (buf != buf_space) + OPENSSL_free(buf); + return (-1); +} diff --git a/libs/openssl/ssl/s2_clnt.c b/libs/openssl/ssl/s2_clnt.c new file mode 100644 index 00000000..b23b0831 --- /dev/null +++ b/libs/openssl/ssl/s2_clnt.c @@ -0,0 +1,1094 @@ +/* ssl/s2_clnt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ssl_locl.h" +#ifndef OPENSSL_NO_SSL2 +# include +# include +# include +# include +# include + +static const SSL_METHOD *ssl2_get_client_method(int ver); +static int get_server_finished(SSL *s); +static int get_server_verify(SSL *s); +static int get_server_hello(SSL *s); +static int client_hello(SSL *s); +static int client_master_key(SSL *s); +static int client_finished(SSL *s); +static int client_certificate(SSL *s); +static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from, + unsigned char *to, int padding); +# define BREAK break + +static const SSL_METHOD *ssl2_get_client_method(int ver) +{ + if (ver == SSL2_VERSION) + return (SSLv2_client_method()); + else + return (NULL); +} + +IMPLEMENT_ssl2_meth_func(SSLv2_client_method, + ssl_undefined_function, + ssl2_connect, ssl2_get_client_method) + +int ssl2_connect(SSL *s) +{ + unsigned long l = (unsigned long)time(NULL); + BUF_MEM *buf = NULL; + int ret = -1; + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int new_state, state; + + RAND_add(&l, sizeof(l), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + /* init things to blank */ + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_BEFORE: + case SSL_ST_CONNECT: + case SSL_ST_BEFORE | SSL_ST_CONNECT: + case SSL_ST_OK | SSL_ST_CONNECT: + + s->server = 0; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + s->version = SSL2_VERSION; + s->type = SSL_ST_CONNECT; + + buf = s->init_buf; + if ((buf == NULL) && ((buf = BUF_MEM_new()) == NULL)) { + ret = -1; + goto end; + } + if (!BUF_MEM_grow(buf, SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { + if (buf == s->init_buf) + buf = NULL; + ret = -1; + goto end; + } + s->init_buf = buf; + buf = NULL; + s->init_num = 0; + s->state = SSL2_ST_SEND_CLIENT_HELLO_A; + s->ctx->stats.sess_connect++; + s->handshake_func = ssl2_connect; + BREAK; + + case SSL2_ST_SEND_CLIENT_HELLO_A: + case SSL2_ST_SEND_CLIENT_HELLO_B: + s->shutdown = 0; + ret = client_hello(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_GET_SERVER_HELLO_A; + BREAK; + + case SSL2_ST_GET_SERVER_HELLO_A: + case SSL2_ST_GET_SERVER_HELLO_B: + ret = get_server_hello(s); + if (ret <= 0) + goto end; + s->init_num = 0; + if (!s->hit) { /* new session */ + s->state = SSL2_ST_SEND_CLIENT_MASTER_KEY_A; + BREAK; + } else { + s->state = SSL2_ST_CLIENT_START_ENCRYPTION; + break; + } + + case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: + case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: + ret = client_master_key(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_CLIENT_START_ENCRYPTION; + break; + + case SSL2_ST_CLIENT_START_ENCRYPTION: + /* + * Ok, we now have all the stuff needed to start encrypting, so + * lets fire it up :-) + */ + if (!ssl2_enc_init(s, 1)) { + ret = -1; + goto end; + } + s->s2->clear_text = 0; + s->state = SSL2_ST_SEND_CLIENT_FINISHED_A; + break; + + case SSL2_ST_SEND_CLIENT_FINISHED_A: + case SSL2_ST_SEND_CLIENT_FINISHED_B: + ret = client_finished(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_GET_SERVER_VERIFY_A; + break; + + case SSL2_ST_GET_SERVER_VERIFY_A: + case SSL2_ST_GET_SERVER_VERIFY_B: + ret = get_server_verify(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_GET_SERVER_FINISHED_A; + break; + + case SSL2_ST_GET_SERVER_FINISHED_A: + case SSL2_ST_GET_SERVER_FINISHED_B: + ret = get_server_finished(s); + if (ret <= 0) + goto end; + break; + + case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: + case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: + case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: + case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: + case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: + ret = client_certificate(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_GET_SERVER_FINISHED_A; + break; + + case SSL_ST_OK: + if (s->init_buf != NULL) { + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + } + s->init_num = 0; + /* ERR_clear_error(); */ + + /* + * If we want to cache session-ids in the client and we + * successfully add the session-id to the cache, and there is a + * callback, then pass it out. 26/11/96 - eay - only add if not a + * re-used session. + */ + + ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); + if (s->hit) + s->ctx->stats.sess_hit++; + + ret = 1; + /* s->server=0; */ + s->ctx->stats.sess_connect_good++; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + + goto end; + /* break; */ + default: + SSLerr(SSL_F_SSL2_CONNECT, SSL_R_UNKNOWN_STATE); + return (-1); + /* break; */ + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_CONNECT_LOOP, 1); + s->state = new_state; + } + } + end: + s->in_handshake--; + if (buf != NULL) + BUF_MEM_free(buf); + if (cb != NULL) + cb(s, SSL_CB_CONNECT_EXIT, ret); + return (ret); +} + +static int get_server_hello(SSL *s) +{ + unsigned char *buf; + unsigned char *p; + int i, j; + unsigned long len; + STACK_OF(SSL_CIPHER) *sk = NULL, *cl, *prio, *allow; + + buf = (unsigned char *)s->init_buf->data; + p = buf; + if (s->state == SSL2_ST_GET_SERVER_HELLO_A) { + i = ssl2_read(s, (char *)&(buf[s->init_num]), 11 - s->init_num); + if (i < (11 - s->init_num)) + return (ssl2_part_read(s, SSL_F_GET_SERVER_HELLO, i)); + s->init_num = 11; + + if (*(p++) != SSL2_MT_SERVER_HELLO) { + if (p[-1] != SSL2_MT_ERROR) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_READ_WRONG_PACKET_TYPE); + } else + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_PEER_ERROR); + return (-1); + } +# if 0 + s->hit = (*(p++)) ? 1 : 0; + /* + * Some [PPC?] compilers fail to increment p in above statement, e.g. + * one provided with Rhapsody 5.5, but most recent example XL C 11.1 + * for AIX, even without optimization flag... + */ +# else + s->hit = (*p) ? 1 : 0; + p++; +# endif + s->s2->tmp.cert_type = *(p++); + n2s(p, i); + if (i < s->version) + s->version = i; + n2s(p, i); + s->s2->tmp.cert_length = i; + n2s(p, i); + s->s2->tmp.csl = i; + n2s(p, i); + s->s2->tmp.conn_id_length = i; + s->state = SSL2_ST_GET_SERVER_HELLO_B; + } + + /* SSL2_ST_GET_SERVER_HELLO_B */ + len = + 11 + (unsigned long)s->s2->tmp.cert_length + + (unsigned long)s->s2->tmp.csl + + (unsigned long)s->s2->tmp.conn_id_length; + if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_MESSAGE_TOO_LONG); + return -1; + } + j = (int)len - s->init_num; + i = ssl2_read(s, (char *)&(buf[s->init_num]), j); + if (i != j) + return (ssl2_part_read(s, SSL_F_GET_SERVER_HELLO, i)); + if (s->msg_callback) { + /* SERVER-HELLO */ + s->msg_callback(0, s->version, 0, buf, (size_t)len, s, + s->msg_callback_arg); + } + + /* things are looking good */ + + p = buf + 11; + if (s->hit) { + if (s->s2->tmp.cert_length != 0) { + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_REUSE_CERT_LENGTH_NOT_ZERO); + return (-1); + } + if (s->s2->tmp.cert_type != 0) { + if (!(s->options & SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG)) { + SSLerr(SSL_F_GET_SERVER_HELLO, + SSL_R_REUSE_CERT_TYPE_NOT_ZERO); + return (-1); + } + } + if (s->s2->tmp.csl != 0) { + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_REUSE_CIPHER_LIST_NOT_ZERO); + return (-1); + } + } else { +# ifdef undef + /* very bad */ + memset(s->session->session_id, 0, + SSL_MAX_SSL_SESSION_ID_LENGTH_IN_BYTES); + s->session->session_id_length = 0; + */ +# endif + /* + * we need to do this in case we were trying to reuse a client + * session but others are already reusing it. If this was a new + * 'blank' session ID, the session-id length will still be 0 + */ + if (s->session->session_id_length > 0) { + if (!ssl_get_new_session(s, 0)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + return (-1); + } + } + + if (ssl2_set_certificate(s, s->s2->tmp.cert_type, + s->s2->tmp.cert_length, p) <= 0) { + ssl2_return_error(s, SSL2_PE_BAD_CERTIFICATE); + return (-1); + } + p += s->s2->tmp.cert_length; + + if (s->s2->tmp.csl == 0) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_NO_CIPHER_LIST); + return (-1); + } + + /* + * We have just received a list of ciphers back from the server. We + * need to get the ones that match, then select the one we want the + * most :-). + */ + + /* load the ciphers */ + sk = ssl_bytes_to_cipher_list(s, p, s->s2->tmp.csl, + &s->session->ciphers); + p += s->s2->tmp.csl; + if (sk == NULL) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_MALLOC_FAILURE); + return (-1); + } + + (void)sk_SSL_CIPHER_set_cmp_func(sk, ssl_cipher_ptr_id_cmp); + + /* get the array of ciphers we will accept */ + cl = SSL_get_ciphers(s); + (void)sk_SSL_CIPHER_set_cmp_func(cl, ssl_cipher_ptr_id_cmp); + + /* + * If server preference flag set, choose the first + * (highest priority) cipher the server sends, otherwise + * client preference has priority. + */ + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + prio = sk; + allow = cl; + } else { + prio = cl; + allow = sk; + } + /* + * In theory we could have ciphers sent back that we don't want to + * use but that does not matter since we will check against the list + * we originally sent and for performance reasons we should not + * bother to match the two lists up just to check. + */ + for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { + if (sk_SSL_CIPHER_find(allow, sk_SSL_CIPHER_value(prio, i)) >= 0) + break; + } + + if (i >= sk_SSL_CIPHER_num(prio)) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_NO_CIPHER_MATCH); + return (-1); + } + s->session->cipher = sk_SSL_CIPHER_value(prio, i); + + if (s->session->peer != NULL) { /* can't happen */ + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + return (-1); + } + + s->session->peer = s->session->sess_cert->peer_key->x509; + /* peer_key->x509 has been set by ssl2_set_certificate. */ + CRYPTO_add(&s->session->peer->references, 1, CRYPTO_LOCK_X509); + } + + if (s->session->sess_cert == NULL + || s->session->peer != s->session->sess_cert->peer_key->x509) + /* can't happen */ + { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + return (-1); + } + + s->s2->conn_id_length = s->s2->tmp.conn_id_length; + if (s->s2->conn_id_length > sizeof s->s2->conn_id) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_HELLO, SSL_R_SSL2_CONNECTION_ID_TOO_LONG); + return -1; + } + memcpy(s->s2->conn_id, p, s->s2->tmp.conn_id_length); + return (1); +} + +static int client_hello(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; +/* CIPHER **cipher;*/ + int i, n, j; + + buf = (unsigned char *)s->init_buf->data; + if (s->state == SSL2_ST_SEND_CLIENT_HELLO_A) { + if ((s->session == NULL) || (s->session->ssl_version != s->version)) { + if (!ssl_get_new_session(s, 0)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + return (-1); + } + } + /* else use the pre-loaded session */ + + p = buf; /* header */ + d = p + 9; /* data section */ + *(p++) = SSL2_MT_CLIENT_HELLO; /* type */ + s2n(SSL2_VERSION, p); /* version */ + n = j = 0; + + n = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), d, 0); + d += n; + + if (n == 0) { + SSLerr(SSL_F_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); + return (-1); + } + + s2n(n, p); /* cipher spec num bytes */ + + if ((s->session->session_id_length > 0) && + (s->session->session_id_length <= + SSL2_MAX_SSL_SESSION_ID_LENGTH)) { + i = s->session->session_id_length; + s2n(i, p); /* session id length */ + memcpy(d, s->session->session_id, (unsigned int)i); + d += i; + } else { + s2n(0, p); + } + + s->s2->challenge_length = SSL2_CHALLENGE_LENGTH; + s2n(SSL2_CHALLENGE_LENGTH, p); /* challenge length */ + /* + * challenge id data + */ + if (RAND_pseudo_bytes(s->s2->challenge, SSL2_CHALLENGE_LENGTH) <= 0) + return -1; + memcpy(d, s->s2->challenge, SSL2_CHALLENGE_LENGTH); + d += SSL2_CHALLENGE_LENGTH; + + s->state = SSL2_ST_SEND_CLIENT_HELLO_B; + s->init_num = d - buf; + s->init_off = 0; + } + /* SSL2_ST_SEND_CLIENT_HELLO_B */ + return (ssl2_do_write(s)); +} + +static int client_master_key(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; + int clear, enc, karg, i; + SSL_SESSION *sess; + const EVP_CIPHER *c; + const EVP_MD *md; + + buf = (unsigned char *)s->init_buf->data; + if (s->state == SSL2_ST_SEND_CLIENT_MASTER_KEY_A) { + + if (!ssl_cipher_get_evp(s->session, &c, &md, NULL, NULL, NULL)) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_CLIENT_MASTER_KEY, + SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); + return (-1); + } + sess = s->session; + p = buf; + d = p + 10; + *(p++) = SSL2_MT_CLIENT_MASTER_KEY; /* type */ + + i = ssl_put_cipher_by_char(s, sess->cipher, p); + p += i; + + /* make key_arg data */ + i = EVP_CIPHER_iv_length(c); + sess->key_arg_length = i; + if (i > SSL_MAX_KEY_ARG_LENGTH) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); + return -1; + } + if (i > 0) + if (RAND_pseudo_bytes(sess->key_arg, i) <= 0) + return -1; + + /* make a master key */ + i = EVP_CIPHER_key_length(c); + sess->master_key_length = i; + if (i > 0) { + if (i > (int)sizeof(sess->master_key)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); + return -1; + } + if (RAND_bytes(sess->master_key, i) <= 0) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + return (-1); + } + } + + if (sess->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) + enc = 8; + else if (SSL_C_IS_EXPORT(sess->cipher)) + enc = 5; + else + enc = i; + + if ((int)i < enc) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_CLIENT_MASTER_KEY, SSL_R_CIPHER_TABLE_SRC_ERROR); + return (-1); + } + clear = i - enc; + s2n(clear, p); + memcpy(d, sess->master_key, (unsigned int)clear); + d += clear; + + enc = ssl_rsa_public_encrypt(sess->sess_cert, enc, + &(sess->master_key[clear]), d, + (s-> + s2->ssl2_rollback) ? RSA_SSLV23_PADDING + : RSA_PKCS1_PADDING); + if (enc <= 0) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_CLIENT_MASTER_KEY, SSL_R_PUBLIC_KEY_ENCRYPT_ERROR); + return (-1); + } +# ifdef PKCS1_CHECK + if (s->options & SSL_OP_PKCS1_CHECK_1) + d[1]++; + if (s->options & SSL_OP_PKCS1_CHECK_2) + sess->master_key[clear]++; +# endif + s2n(enc, p); + d += enc; + karg = sess->key_arg_length; + s2n(karg, p); /* key arg size */ + if (karg > (int)sizeof(sess->key_arg)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); + return -1; + } + memcpy(d, sess->key_arg, (unsigned int)karg); + d += karg; + + s->state = SSL2_ST_SEND_CLIENT_MASTER_KEY_B; + s->init_num = d - buf; + s->init_off = 0; + } + + /* SSL2_ST_SEND_CLIENT_MASTER_KEY_B */ + return (ssl2_do_write(s)); +} + +static int client_finished(SSL *s) +{ + unsigned char *p; + + if (s->state == SSL2_ST_SEND_CLIENT_FINISHED_A) { + p = (unsigned char *)s->init_buf->data; + *(p++) = SSL2_MT_CLIENT_FINISHED; + if (s->s2->conn_id_length > sizeof s->s2->conn_id) { + SSLerr(SSL_F_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR); + return -1; + } + memcpy(p, s->s2->conn_id, (unsigned int)s->s2->conn_id_length); + + s->state = SSL2_ST_SEND_CLIENT_FINISHED_B; + s->init_num = s->s2->conn_id_length + 1; + s->init_off = 0; + } + return (ssl2_do_write(s)); +} + +/* read the data and then respond */ +static int client_certificate(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; + int i; + unsigned int n; + int cert_ch_len; + unsigned char *cert_ch; + + buf = (unsigned char *)s->init_buf->data; + + /* + * We have a cert associated with the SSL, so attach it to the session if + * it does not have one + */ + + if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_A) { + i = ssl2_read(s, (char *)&(buf[s->init_num]), + SSL2_MAX_CERT_CHALLENGE_LENGTH + 2 - s->init_num); + if (i < (SSL2_MIN_CERT_CHALLENGE_LENGTH + 2 - s->init_num)) + return (ssl2_part_read(s, SSL_F_CLIENT_CERTIFICATE, i)); + s->init_num += i; + if (s->msg_callback) { + /* REQUEST-CERTIFICATE */ + s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, + s->msg_callback_arg); + } + + /* type=buf[0]; */ + /* type eq x509 */ + if (buf[1] != SSL2_AT_MD5_WITH_RSA_ENCRYPTION) { + ssl2_return_error(s, SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE); + SSLerr(SSL_F_CLIENT_CERTIFICATE, SSL_R_BAD_AUTHENTICATION_TYPE); + return (-1); + } + + if ((s->cert == NULL) || + (s->cert->key->x509 == NULL) || + (s->cert->key->privatekey == NULL)) { + s->state = SSL2_ST_X509_GET_CLIENT_CERTIFICATE; + } else + s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_C; + } + + cert_ch = buf + 2; + cert_ch_len = s->init_num - 2; + + if (s->state == SSL2_ST_X509_GET_CLIENT_CERTIFICATE) { + X509 *x509 = NULL; + EVP_PKEY *pkey = NULL; + + /* + * If we get an error we need to ssl->rwstate=SSL_X509_LOOKUP; + * return(error); We should then be retried when things are ok and we + * can get a cert or not + */ + + i = 0; + if (s->ctx->client_cert_cb != NULL) { + i = s->ctx->client_cert_cb(s, &(x509), &(pkey)); + } + + if (i < 0) { + s->rwstate = SSL_X509_LOOKUP; + return (-1); + } + s->rwstate = SSL_NOTHING; + + if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { + s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_C; + if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey)) { + i = 0; + } + X509_free(x509); + EVP_PKEY_free(pkey); + } else if (i == 1) { + if (x509 != NULL) + X509_free(x509); + if (pkey != NULL) + EVP_PKEY_free(pkey); + SSLerr(SSL_F_CLIENT_CERTIFICATE, + SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); + i = 0; + } + + if (i == 0) { + /* + * We have no client certificate to respond with so send the + * correct error message back + */ + s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_B; + p = buf; + *(p++) = SSL2_MT_ERROR; + s2n(SSL2_PE_NO_CERTIFICATE, p); + s->init_off = 0; + s->init_num = 3; + /* Write is done at the end */ + } + } + + if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_B) { + return (ssl2_do_write(s)); + } + + if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_C) { + EVP_MD_CTX ctx; + + /* + * ok, now we calculate the checksum do it first so we can reuse buf + * :-) + */ + p = buf; + EVP_MD_CTX_init(&ctx); + EVP_SignInit_ex(&ctx, s->ctx->rsa_md5, NULL); + EVP_SignUpdate(&ctx, s->s2->key_material, s->s2->key_material_length); + EVP_SignUpdate(&ctx, cert_ch, (unsigned int)cert_ch_len); + i = i2d_X509(s->session->sess_cert->peer_key->x509, &p); + /* + * Don't update the signature if it fails - FIXME: probably should + * handle this better + */ + if (i > 0) + EVP_SignUpdate(&ctx, buf, (unsigned int)i); + + p = buf; + d = p + 6; + *(p++) = SSL2_MT_CLIENT_CERTIFICATE; + *(p++) = SSL2_CT_X509_CERTIFICATE; + n = i2d_X509(s->cert->key->x509, &d); + s2n(n, p); + + if (!EVP_SignFinal(&ctx, d, &n, s->cert->key->privatekey)) { + /* + * this is not good. If things have failed it means there so + * something wrong with the key. We will continue with a 0 length + * signature + */ + } + EVP_MD_CTX_cleanup(&ctx); + s2n(n, p); + d += n; + + s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_D; + s->init_num = d - buf; + s->init_off = 0; + } + /* if (s->state == SSL2_ST_SEND_CLIENT_CERTIFICATE_D) */ + return (ssl2_do_write(s)); +} + +static int get_server_verify(SSL *s) +{ + unsigned char *p; + int i, n, len; + + p = (unsigned char *)s->init_buf->data; + if (s->state == SSL2_ST_GET_SERVER_VERIFY_A) { + i = ssl2_read(s, (char *)&(p[s->init_num]), 1 - s->init_num); + if (i < (1 - s->init_num)) + return (ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i)); + s->init_num += i; + + s->state = SSL2_ST_GET_SERVER_VERIFY_B; + if (*p != SSL2_MT_SERVER_VERIFY) { + if (p[0] != SSL2_MT_ERROR) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_READ_WRONG_PACKET_TYPE); + } else { + SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_PEER_ERROR); + /* try to read the error message */ + i = ssl2_read(s, (char *)&(p[s->init_num]), 3 - s->init_num); + return ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i); + } + return (-1); + } + } + + p = (unsigned char *)s->init_buf->data; + len = 1 + s->s2->challenge_length; + n = len - s->init_num; + i = ssl2_read(s, (char *)&(p[s->init_num]), n); + if (i < n) + return (ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i)); + if (s->msg_callback) { + /* SERVER-VERIFY */ + s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); + } + p += 1; + + if (CRYPTO_memcmp(p, s->s2->challenge, s->s2->challenge_length) != 0) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_VERIFY, SSL_R_CHALLENGE_IS_DIFFERENT); + return (-1); + } + return (1); +} + +static int get_server_finished(SSL *s) +{ + unsigned char *buf; + unsigned char *p; + int i, n, len; + + buf = (unsigned char *)s->init_buf->data; + p = buf; + if (s->state == SSL2_ST_GET_SERVER_FINISHED_A) { + i = ssl2_read(s, (char *)&(buf[s->init_num]), 1 - s->init_num); + if (i < (1 - s->init_num)) + return (ssl2_part_read(s, SSL_F_GET_SERVER_FINISHED, i)); + s->init_num += i; + + if (*p == SSL2_MT_REQUEST_CERTIFICATE) { + s->state = SSL2_ST_SEND_CLIENT_CERTIFICATE_A; + return (1); + } else if (*p != SSL2_MT_SERVER_FINISHED) { + if (p[0] != SSL2_MT_ERROR) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_FINISHED, + SSL_R_READ_WRONG_PACKET_TYPE); + } else { + SSLerr(SSL_F_GET_SERVER_FINISHED, SSL_R_PEER_ERROR); + /* try to read the error message */ + i = ssl2_read(s, (char *)&(p[s->init_num]), 3 - s->init_num); + return ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i); + } + return (-1); + } + s->state = SSL2_ST_GET_SERVER_FINISHED_B; + } + + len = 1 + SSL2_SSL_SESSION_ID_LENGTH; + n = len - s->init_num; + i = ssl2_read(s, (char *)&(buf[s->init_num]), n); + if (i < n) { + /* + * XXX could be shorter than SSL2_SSL_SESSION_ID_LENGTH, + * that's the maximum + */ + return (ssl2_part_read(s, SSL_F_GET_SERVER_FINISHED, i)); + } + s->init_num += i; + if (s->msg_callback) { + /* SERVER-FINISHED */ + s->msg_callback(0, s->version, 0, buf, (size_t)s->init_num, s, + s->msg_callback_arg); + } + + if (!s->hit) { /* new session */ + /* new session-id */ + /* + * Make sure we were not trying to re-use an old SSL_SESSION or bad + * things can happen + */ + /* ZZZZZZZZZZZZZ */ + s->session->session_id_length = SSL2_SSL_SESSION_ID_LENGTH; + memcpy(s->session->session_id, p + 1, SSL2_SSL_SESSION_ID_LENGTH); + } else { + if (!(s->options & SSL_OP_MICROSOFT_SESS_ID_BUG)) { + if ((s->session->session_id_length > + sizeof s->session->session_id) + || (0 != + memcmp(buf + 1, s->session->session_id, + (unsigned int)s->session->session_id_length))) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_SERVER_FINISHED, + SSL_R_SSL_SESSION_ID_IS_DIFFERENT); + return (-1); + } + } + } + s->state = SSL_ST_OK; + return (1); +} + +/* loads in the certificate from the server */ +int ssl2_set_certificate(SSL *s, int type, int len, const unsigned char *data) +{ + STACK_OF(X509) *sk = NULL; + EVP_PKEY *pkey = NULL; + SESS_CERT *sc = NULL; + int i; + X509 *x509 = NULL; + int ret = 0; + + x509 = d2i_X509(NULL, &data, (long)len); + if (x509 == NULL) { + SSLerr(SSL_F_SSL2_SET_CERTIFICATE, ERR_R_X509_LIB); + goto err; + } + + if ((sk = sk_X509_new_null()) == NULL || !sk_X509_push(sk, x509)) { + SSLerr(SSL_F_SSL2_SET_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto err; + } + + i = ssl_verify_cert_chain(s, sk); + + if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0)) { + SSLerr(SSL_F_SSL2_SET_CERTIFICATE, SSL_R_CERTIFICATE_VERIFY_FAILED); + goto err; + } + ERR_clear_error(); /* but we keep s->verify_result */ + s->session->verify_result = s->verify_result; + + /* server's cert for this session */ + sc = ssl_sess_cert_new(); + if (sc == NULL) { + ret = -1; + goto err; + } + if (s->session->sess_cert) + ssl_sess_cert_free(s->session->sess_cert); + s->session->sess_cert = sc; + + sc->peer_pkeys[SSL_PKEY_RSA_ENC].x509 = x509; + sc->peer_key = &(sc->peer_pkeys[SSL_PKEY_RSA_ENC]); + + pkey = X509_get_pubkey(x509); + x509 = NULL; + if (pkey == NULL) { + SSLerr(SSL_F_SSL2_SET_CERTIFICATE, + SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY); + goto err; + } + if (pkey->type != EVP_PKEY_RSA) { + SSLerr(SSL_F_SSL2_SET_CERTIFICATE, SSL_R_PUBLIC_KEY_NOT_RSA); + goto err; + } + + if (!ssl_set_peer_cert_type(sc, SSL2_CT_X509_CERTIFICATE)) + goto err; + ret = 1; + err: + sk_X509_free(sk); + X509_free(x509); + EVP_PKEY_free(pkey); + return (ret); +} + +static int ssl_rsa_public_encrypt(SESS_CERT *sc, int len, unsigned char *from, + unsigned char *to, int padding) +{ + EVP_PKEY *pkey = NULL; + int i = -1; + + if ((sc == NULL) || (sc->peer_key->x509 == NULL) || + ((pkey = X509_get_pubkey(sc->peer_key->x509)) == NULL)) { + SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, SSL_R_NO_PUBLICKEY); + return (-1); + } + if (pkey->type != EVP_PKEY_RSA) { + SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, SSL_R_PUBLIC_KEY_IS_NOT_RSA); + goto end; + } + + /* we have the public key */ + i = RSA_public_encrypt(len, from, to, pkey->pkey.rsa, padding); + if (i < 0) + SSLerr(SSL_F_SSL_RSA_PUBLIC_ENCRYPT, ERR_R_RSA_LIB); + end: + EVP_PKEY_free(pkey); + return (i); +} +#else /* !OPENSSL_NO_SSL2 */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif diff --git a/libs/openssl/ssl/s2_enc.c b/libs/openssl/ssl/s2_enc.c new file mode 100644 index 00000000..23eef72a --- /dev/null +++ b/libs/openssl/ssl/s2_enc.c @@ -0,0 +1,197 @@ +/* ssl/s2_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "ssl_locl.h" +#ifndef OPENSSL_NO_SSL2 +# include + +int ssl2_enc_init(SSL *s, int client) +{ + /* Max number of bytes needed */ + EVP_CIPHER_CTX *rs, *ws; + const EVP_CIPHER *c; + const EVP_MD *md; + int num; + + if (!ssl_cipher_get_evp(s->session, &c, &md, NULL, NULL, NULL)) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_SSL2_ENC_INIT, SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); + return (0); + } + ssl_replace_hash(&s->read_hash, md); + ssl_replace_hash(&s->write_hash, md); + + if ((s->enc_read_ctx == NULL) && ((s->enc_read_ctx = (EVP_CIPHER_CTX *) + OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) + == NULL)) + goto err; + + /* + * make sure it's intialized in case the malloc for enc_write_ctx fails + * and we exit with an error + */ + rs = s->enc_read_ctx; + EVP_CIPHER_CTX_init(rs); + + if ((s->enc_write_ctx == NULL) && ((s->enc_write_ctx = (EVP_CIPHER_CTX *) + OPENSSL_malloc(sizeof + (EVP_CIPHER_CTX))) == + NULL)) + goto err; + + ws = s->enc_write_ctx; + EVP_CIPHER_CTX_init(ws); + + num = c->key_len; + s->s2->key_material_length = num * 2; + OPENSSL_assert(s->s2->key_material_length <= sizeof s->s2->key_material); + + if (ssl2_generate_key_material(s) <= 0) + return 0; + + OPENSSL_assert(c->iv_len <= (int)sizeof(s->session->key_arg)); + EVP_EncryptInit_ex(ws, c, NULL, + &(s->s2->key_material[(client) ? num : 0]), + s->session->key_arg); + EVP_DecryptInit_ex(rs, c, NULL, + &(s->s2->key_material[(client) ? 0 : num]), + s->session->key_arg); + s->s2->read_key = &(s->s2->key_material[(client) ? 0 : num]); + s->s2->write_key = &(s->s2->key_material[(client) ? num : 0]); + return (1); + err: + SSLerr(SSL_F_SSL2_ENC_INIT, ERR_R_MALLOC_FAILURE); + return (0); +} + +/* + * read/writes from s->s2->mac_data using length for encrypt and decrypt. + * It sets s->s2->padding and s->[rw]length if we are encrypting Returns 0 on + * error and 1 on success + */ +int ssl2_enc(SSL *s, int send) +{ + EVP_CIPHER_CTX *ds; + unsigned long l; + int bs; + + if (send) { + ds = s->enc_write_ctx; + l = s->s2->wlength; + } else { + ds = s->enc_read_ctx; + l = s->s2->rlength; + } + + /* check for NULL cipher */ + if (ds == NULL) + return 1; + + bs = ds->cipher->block_size; + /* + * This should be using (bs-1) and bs instead of 7 and 8, but what the + * hell. + */ + if (bs == 8) + l = (l + 7) / 8 * 8; + + if (EVP_Cipher(ds, s->s2->mac_data, s->s2->mac_data, l) < 1) + return 0; + + return 1; +} + +void ssl2_mac(SSL *s, unsigned char *md, int send) +{ + EVP_MD_CTX c; + unsigned char sequence[4], *p, *sec, *act; + unsigned long seq; + unsigned int len; + + if (send) { + seq = s->s2->write_sequence; + sec = s->s2->write_key; + len = s->s2->wact_data_length; + act = s->s2->wact_data; + } else { + seq = s->s2->read_sequence; + sec = s->s2->read_key; + len = s->s2->ract_data_length; + act = s->s2->ract_data; + } + + p = &(sequence[0]); + l2n(seq, p); + + /* There has to be a MAC algorithm. */ + EVP_MD_CTX_init(&c); + EVP_MD_CTX_copy(&c, s->read_hash); + EVP_DigestUpdate(&c, sec, EVP_CIPHER_CTX_key_length(s->enc_read_ctx)); + EVP_DigestUpdate(&c, act, len); + /* the above line also does the pad data */ + EVP_DigestUpdate(&c, sequence, 4); + EVP_DigestFinal_ex(&c, md, NULL); + EVP_MD_CTX_cleanup(&c); +} +#else /* !OPENSSL_NO_SSL2 */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif diff --git a/libs/openssl/ssl/s2_lib.c b/libs/openssl/ssl/s2_lib.c new file mode 100644 index 00000000..7bcb81a1 --- /dev/null +++ b/libs/openssl/ssl/s2_lib.c @@ -0,0 +1,573 @@ +/* ssl/s2_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ssl_locl.h" +#ifndef OPENSSL_NO_SSL2 +# include +# include +# include +# include + +const char ssl2_version_str[] = "SSLv2" OPENSSL_VERSION_PTEXT; + +# define SSL2_NUM_CIPHERS (sizeof(ssl2_ciphers)/sizeof(SSL_CIPHER)) + +/* list of available SSLv2 ciphers (sorted by id) */ +OPENSSL_GLOBAL const SSL_CIPHER ssl2_ciphers[] = { +# if 0 +/* NULL_WITH_MD5 v3 */ + { + 1, + SSL2_TXT_NULL_WITH_MD5, + SSL2_CK_NULL_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_MD5, + SSL_SSLV2, + SSL_EXPORT | SSL_EXP40 | SSL_STRONG_NONE, + 0, + 0, + 0, + }, +# endif + +/* RC4_128_WITH_MD5 */ + { + 1, + SSL2_TXT_RC4_128_WITH_MD5, + SSL2_CK_RC4_128_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + 0, + 128, + 128, + }, + +# if 0 +/* RC4_128_EXPORT40_WITH_MD5 */ + { + 1, + SSL2_TXT_RC4_128_EXPORT40_WITH_MD5, + SSL2_CK_RC4_128_EXPORT40_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL2_CF_5_BYTE_ENC, + 40, + 128, + }, +# endif + +/* RC2_128_CBC_WITH_MD5 */ + { + 1, + SSL2_TXT_RC2_128_CBC_WITH_MD5, + SSL2_CK_RC2_128_CBC_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC2, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + 0, + 128, + 128, + }, + +# if 0 +/* RC2_128_CBC_EXPORT40_WITH_MD5 */ + { + 1, + SSL2_TXT_RC2_128_CBC_EXPORT40_WITH_MD5, + SSL2_CK_RC2_128_CBC_EXPORT40_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC2, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL2_CF_5_BYTE_ENC, + 40, + 128, + }, +# endif + +# ifndef OPENSSL_NO_IDEA +/* IDEA_128_CBC_WITH_MD5 */ + { + 1, + SSL2_TXT_IDEA_128_CBC_WITH_MD5, + SSL2_CK_IDEA_128_CBC_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_IDEA, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + 0, + 128, + 128, + }, +# endif + +# if 0 +/* DES_64_CBC_WITH_MD5 */ + { + 1, + SSL2_TXT_DES_64_CBC_WITH_MD5, + SSL2_CK_DES_64_CBC_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_DES, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + 0, + 56, + 56, + }, +# endif + +/* DES_192_EDE3_CBC_WITH_MD5 */ + { + 1, + SSL2_TXT_DES_192_EDE3_CBC_WITH_MD5, + SSL2_CK_DES_192_EDE3_CBC_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_3DES, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH, + 0, + 112, + 168, + }, + +# if 0 +/* RC4_64_WITH_MD5 */ + { + 1, + SSL2_TXT_RC4_64_WITH_MD5, + SSL2_CK_RC4_64_WITH_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL2_CF_8_BYTE_ENC, + 64, + 64, + }, +# endif + +# if 0 +/* NULL SSLeay (testing) */ + { + 0, + SSL2_TXT_NULL, + SSL2_CK_NULL, + 0, + 0, + 0, + 0, + SSL_SSLV2, + SSL_STRONG_NONE, + 0, + 0, + 0, + }, +# endif + +/* end of list :-) */ +}; + +long ssl2_default_timeout(void) +{ + return (300); +} + +int ssl2_num_ciphers(void) +{ + return (SSL2_NUM_CIPHERS); +} + +const SSL_CIPHER *ssl2_get_cipher(unsigned int u) +{ + if (u < SSL2_NUM_CIPHERS) + return (&(ssl2_ciphers[SSL2_NUM_CIPHERS - 1 - u])); + else + return (NULL); +} + +int ssl2_pending(const SSL *s) +{ + return SSL_in_init(s) ? 0 : s->s2->ract_data_length; +} + +int ssl2_new(SSL *s) +{ + SSL2_STATE *s2; + + if ((s2 = OPENSSL_malloc(sizeof *s2)) == NULL) + goto err; + memset(s2, 0, sizeof *s2); + +# if SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER + 3 > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2 +# error "assertion failed" +# endif + + if ((s2->rbuf = + OPENSSL_malloc(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2)) == NULL) + goto err; + /* + * wbuf needs one byte more because when using two-byte headers, we leave + * the first byte unused in do_ssl_write (s2_pkt.c) + */ + if ((s2->wbuf = + OPENSSL_malloc(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 3)) == NULL) + goto err; + s->s2 = s2; + + ssl2_clear(s); + return (1); + err: + if (s2 != NULL) { + if (s2->wbuf != NULL) + OPENSSL_free(s2->wbuf); + if (s2->rbuf != NULL) + OPENSSL_free(s2->rbuf); + OPENSSL_free(s2); + } + return (0); +} + +void ssl2_free(SSL *s) +{ + SSL2_STATE *s2; + + if (s == NULL) + return; + + s2 = s->s2; + if (s2->rbuf != NULL) + OPENSSL_free(s2->rbuf); + if (s2->wbuf != NULL) + OPENSSL_free(s2->wbuf); + OPENSSL_cleanse(s2, sizeof *s2); + OPENSSL_free(s2); + s->s2 = NULL; +} + +void ssl2_clear(SSL *s) +{ + SSL2_STATE *s2; + unsigned char *rbuf, *wbuf; + + s2 = s->s2; + + rbuf = s2->rbuf; + wbuf = s2->wbuf; + + memset(s2, 0, sizeof *s2); + + s2->rbuf = rbuf; + s2->wbuf = wbuf; + s2->clear_text = 1; + s->packet = s2->rbuf; + s->version = SSL2_VERSION; + s->packet_length = 0; +} + +long ssl2_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + int ret = 0; + + switch (cmd) { + case SSL_CTRL_GET_SESSION_REUSED: + ret = s->hit; + break; + case SSL_CTRL_CHECK_PROTO_VERSION: + return ssl3_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, larg, parg); + default: + break; + } + return (ret); +} + +long ssl2_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) +{ + return (0); +} + +long ssl2_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) +{ + return (0); +} + +long ssl2_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) +{ + return (0); +} + +/* + * This function needs to check if the ciphers required are actually + * available + */ +const SSL_CIPHER *ssl2_get_cipher_by_char(const unsigned char *p) +{ + SSL_CIPHER c; + const SSL_CIPHER *cp; + unsigned long id; + + id = 0x02000000L | ((unsigned long)p[0] << 16L) | + ((unsigned long)p[1] << 8L) | (unsigned long)p[2]; + c.id = id; + cp = OBJ_bsearch_ssl_cipher_id(&c, ssl2_ciphers, SSL2_NUM_CIPHERS); + if ((cp == NULL) || (cp->valid == 0)) + return NULL; + else + return cp; +} + +int ssl2_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) +{ + long l; + + if (p != NULL) { + l = c->id; + if ((l & 0xff000000) != 0x02000000 && l != SSL3_CK_FALLBACK_SCSV) + return (0); + p[0] = ((unsigned char)(l >> 16L)) & 0xFF; + p[1] = ((unsigned char)(l >> 8L)) & 0xFF; + p[2] = ((unsigned char)(l)) & 0xFF; + } + return (3); +} + +int ssl2_generate_key_material(SSL *s) +{ + unsigned int i; + EVP_MD_CTX ctx; + unsigned char *km; + unsigned char c = '0'; + const EVP_MD *md5; + int md_size; + + md5 = EVP_md5(); + +# ifdef CHARSET_EBCDIC + c = os_toascii['0']; /* Must be an ASCII '0', not EBCDIC '0', see + * SSLv2 docu */ +# endif + EVP_MD_CTX_init(&ctx); + km = s->s2->key_material; + + if (s->session->master_key_length < 0 || + s->session->master_key_length > (int)sizeof(s->session->master_key)) { + SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR); + return 0; + } + md_size = EVP_MD_size(md5); + if (md_size < 0) + return 0; + for (i = 0; i < s->s2->key_material_length; i += md_size) { + if (((km - s->s2->key_material) + md_size) > + (int)sizeof(s->s2->key_material)) { + /* + * EVP_DigestFinal_ex() below would write beyond buffer + */ + SSLerr(SSL_F_SSL2_GENERATE_KEY_MATERIAL, ERR_R_INTERNAL_ERROR); + return 0; + } + + EVP_DigestInit_ex(&ctx, md5, NULL); + + OPENSSL_assert(s->session->master_key_length >= 0 + && s->session->master_key_length + <= (int)sizeof(s->session->master_key)); + EVP_DigestUpdate(&ctx, s->session->master_key, + s->session->master_key_length); + EVP_DigestUpdate(&ctx, &c, 1); + c++; + EVP_DigestUpdate(&ctx, s->s2->challenge, s->s2->challenge_length); + EVP_DigestUpdate(&ctx, s->s2->conn_id, s->s2->conn_id_length); + EVP_DigestFinal_ex(&ctx, km, NULL); + km += md_size; + } + + EVP_MD_CTX_cleanup(&ctx); + return 1; +} + +void ssl2_return_error(SSL *s, int err) +{ + if (!s->error) { + s->error = 3; + s->error_code = err; + + ssl2_write_error(s); + } +} + +void ssl2_write_error(SSL *s) +{ + unsigned char buf[3]; + int i, error; + + buf[0] = SSL2_MT_ERROR; + buf[1] = (s->error_code >> 8) & 0xff; + buf[2] = (s->error_code) & 0xff; + +/* state=s->rwstate;*/ + + error = s->error; /* number of bytes left to write */ + s->error = 0; + OPENSSL_assert(error >= 0 && error <= (int)sizeof(buf)); + i = ssl2_write(s, &(buf[3 - error]), error); + +/* if (i == error) s->rwstate=state; */ + + if (i < 0) + s->error = error; + else { + s->error = error - i; + + if (s->error == 0) + if (s->msg_callback) { + /* ERROR */ + s->msg_callback(1, s->version, 0, buf, 3, s, + s->msg_callback_arg); + } + } +} + +int ssl2_shutdown(SSL *s) +{ + s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); + return (1); +} +#else /* !OPENSSL_NO_SSL2 */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif diff --git a/libs/openssl/ssl/s2_meth.c b/libs/openssl/ssl/s2_meth.c new file mode 100644 index 00000000..73885b7e --- /dev/null +++ b/libs/openssl/ssl/s2_meth.c @@ -0,0 +1,91 @@ +/* ssl/s2_meth.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include "ssl_locl.h" +#ifndef OPENSSL_NO_SSL2_METHOD +# ifndef OPENSSL_NO_SSL2 +# include +# include + +static const SSL_METHOD *ssl2_get_method(int ver); +static const SSL_METHOD *ssl2_get_method(int ver) +{ + if (ver == SSL2_VERSION) + return (SSLv2_method()); + else + return (NULL); +} + +IMPLEMENT_ssl2_meth_func(SSLv2_method, + ssl2_accept, ssl2_connect, ssl2_get_method) + +# else /* !OPENSSL_NO_SSL2 */ + +const SSL_METHOD *SSLv2_method(void) { return NULL; } +const SSL_METHOD *SSLv2_client_method(void) { return NULL; } +const SSL_METHOD *SSLv2_server_method(void) { return NULL; } + +# endif + +#else /* !OPENSSL_NO_SSL2_METHOD */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif diff --git a/libs/openssl/ssl/s2_pkt.c b/libs/openssl/ssl/s2_pkt.c new file mode 100644 index 00000000..7a618881 --- /dev/null +++ b/libs/openssl/ssl/s2_pkt.c @@ -0,0 +1,725 @@ +/* ssl/s2_pkt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ssl_locl.h" +#ifndef OPENSSL_NO_SSL2 +# include +# include +# define USE_SOCKETS + +static int read_n(SSL *s, unsigned int n, unsigned int max, + unsigned int extend); +static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len); +static int write_pending(SSL *s, const unsigned char *buf, unsigned int len); +static int ssl_mt_error(int n); + +/* + * SSL 2.0 imlementation for SSL_read/SSL_peek - This routine will return 0 + * to len bytes, decrypted etc if required. + */ +static int ssl2_read_internal(SSL *s, void *buf, int len, int peek) +{ + int n; + unsigned char mac[MAX_MAC_SIZE]; + unsigned char *p; + int i; + int mac_size; + + ssl2_read_again: + if (SSL_in_init(s) && !s->in_handshake) { + n = s->handshake_func(s); + if (n < 0) + return (n); + if (n == 0) { + SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + } + + clear_sys_error(); + s->rwstate = SSL_NOTHING; + if (len <= 0) + return (len); + + if (s->s2->ract_data_length != 0) { /* read from buffer */ + if (len > s->s2->ract_data_length) + n = s->s2->ract_data_length; + else + n = len; + + memcpy(buf, s->s2->ract_data, (unsigned int)n); + if (!peek) { + s->s2->ract_data_length -= n; + s->s2->ract_data += n; + if (s->s2->ract_data_length == 0) + s->rstate = SSL_ST_READ_HEADER; + } + + return (n); + } + + /* + * s->s2->ract_data_length == 0 Fill the buffer, then goto + * ssl2_read_again. + */ + + if (s->rstate == SSL_ST_READ_HEADER) { + if (s->first_packet) { + n = read_n(s, 5, SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2, 0); + if (n <= 0) + return (n); /* error or non-blocking */ + s->first_packet = 0; + p = s->packet; + if (!((p[0] & 0x80) && ((p[2] == SSL2_MT_CLIENT_HELLO) || + (p[2] == SSL2_MT_SERVER_HELLO)))) { + SSLerr(SSL_F_SSL2_READ_INTERNAL, + SSL_R_NON_SSLV2_INITIAL_PACKET); + return (-1); + } + } else { + n = read_n(s, 2, SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2, 0); + if (n <= 0) + return (n); /* error or non-blocking */ + } + /* part read stuff */ + + s->rstate = SSL_ST_READ_BODY; + p = s->packet; + /* Do header */ + /* + * s->s2->padding=0; + */ + s->s2->escape = 0; + s->s2->rlength = (((unsigned int)p[0]) << 8) | ((unsigned int)p[1]); + if ((p[0] & TWO_BYTE_BIT)) { /* Two byte header? */ + s->s2->three_byte_header = 0; + s->s2->rlength &= TWO_BYTE_MASK; + } else { + s->s2->three_byte_header = 1; + s->s2->rlength &= THREE_BYTE_MASK; + + /* security >s2->escape */ + s->s2->escape = ((p[0] & SEC_ESC_BIT)) ? 1 : 0; + } + } + + if (s->rstate == SSL_ST_READ_BODY) { + n = s->s2->rlength + 2 + s->s2->three_byte_header; + if (n > (int)s->packet_length) { + n -= s->packet_length; + i = read_n(s, (unsigned int)n, (unsigned int)n, 1); + if (i <= 0) + return (i); /* ERROR */ + } + + p = &(s->packet[2]); + s->rstate = SSL_ST_READ_HEADER; + if (s->s2->three_byte_header) + s->s2->padding = *(p++); + else + s->s2->padding = 0; + + /* Data portion */ + if (s->s2->clear_text) { + mac_size = 0; + s->s2->mac_data = p; + s->s2->ract_data = p; + if (s->s2->padding) { + SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_ILLEGAL_PADDING); + return (-1); + } + } else { + mac_size = EVP_MD_CTX_size(s->read_hash); + if (mac_size < 0) + return -1; + OPENSSL_assert(mac_size <= MAX_MAC_SIZE); + s->s2->mac_data = p; + s->s2->ract_data = &p[mac_size]; + if (s->s2->padding + mac_size > s->s2->rlength) { + SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_ILLEGAL_PADDING); + return (-1); + } + } + + s->s2->ract_data_length = s->s2->rlength; + /* + * added a check for length > max_size in case encryption was not + * turned on yet due to an error + */ + if ((!s->s2->clear_text) && + (s->s2->rlength >= (unsigned int)mac_size)) { + if (!ssl2_enc(s, 0)) { + SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_DECRYPTION_FAILED); + return (-1); + } + s->s2->ract_data_length -= mac_size; + ssl2_mac(s, mac, 0); + s->s2->ract_data_length -= s->s2->padding; + if ((CRYPTO_memcmp(mac, s->s2->mac_data, mac_size) != 0) || + (s->s2->rlength % + EVP_CIPHER_CTX_block_size(s->enc_read_ctx) != 0)) { + SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_BAD_MAC_DECODE); + return (-1); + } + } + INC32(s->s2->read_sequence); /* expect next number */ + /* s->s2->ract_data is now available for processing */ + + /* + * Possibly the packet that we just read had 0 actual data bytes. + * (SSLeay/OpenSSL itself never sends such packets; see ssl2_write.) + * In this case, returning 0 would be interpreted by the caller as + * indicating EOF, so it's not a good idea. Instead, we just + * continue reading; thus ssl2_read_internal may have to process + * multiple packets before it can return. [Note that using select() + * for blocking sockets *never* guarantees that the next SSL_read + * will not block -- the available data may contain incomplete + * packets, and except for SSL 2, renegotiation can confuse things + * even more.] + */ + + goto ssl2_read_again; /* This should really be "return + * ssl2_read(s,buf,len)", but that would + * allow for denial-of-service attacks if a C + * compiler is used that does not recognize + * end-recursion. */ + } else { + SSLerr(SSL_F_SSL2_READ_INTERNAL, SSL_R_BAD_STATE); + return (-1); + } +} + +int ssl2_read(SSL *s, void *buf, int len) +{ + return ssl2_read_internal(s, buf, len, 0); +} + +int ssl2_peek(SSL *s, void *buf, int len) +{ + return ssl2_read_internal(s, buf, len, 1); +} + +static int read_n(SSL *s, unsigned int n, unsigned int max, + unsigned int extend) +{ + int i, off, newb; + + /* + * if there is stuff still in the buffer from a previous read, and there + * is more than we want, take some. + */ + if (s->s2->rbuf_left >= (int)n) { + if (extend) + s->packet_length += n; + else { + s->packet = &(s->s2->rbuf[s->s2->rbuf_offs]); + s->packet_length = n; + } + s->s2->rbuf_left -= n; + s->s2->rbuf_offs += n; + return (n); + } + + if (!s->read_ahead) + max = n; + if (max > (unsigned int)(SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2)) + max = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + 2; + + /* + * Else we want more than we have. First, if there is some left or we + * want to extend + */ + off = 0; + if ((s->s2->rbuf_left != 0) || ((s->packet_length != 0) && extend)) { + newb = s->s2->rbuf_left; + if (extend) { + off = s->packet_length; + if (s->packet != s->s2->rbuf) + memcpy(s->s2->rbuf, s->packet, (unsigned int)newb + off); + } else if (s->s2->rbuf_offs != 0) { + memcpy(s->s2->rbuf, &(s->s2->rbuf[s->s2->rbuf_offs]), + (unsigned int)newb); + s->s2->rbuf_offs = 0; + } + s->s2->rbuf_left = 0; + } else + newb = 0; + + /* + * off is the offset to start writing too. r->s2->rbuf_offs is the + * 'unread data', now 0. newb is the number of new bytes so far + */ + s->packet = s->s2->rbuf; + while (newb < (int)n) { + clear_sys_error(); + if (s->rbio != NULL) { + s->rwstate = SSL_READING; + i = BIO_read(s->rbio, (char *)&(s->s2->rbuf[off + newb]), + max - newb); + } else { + SSLerr(SSL_F_READ_N, SSL_R_READ_BIO_NOT_SET); + i = -1; + } +# ifdef PKT_DEBUG + if (s->debug & 0x01) + sleep(1); +# endif + if (i <= 0) { + s->s2->rbuf_left += newb; + return (i); + } + newb += i; + } + + /* record unread data */ + if (newb > (int)n) { + s->s2->rbuf_offs = n + off; + s->s2->rbuf_left = newb - n; + } else { + s->s2->rbuf_offs = 0; + s->s2->rbuf_left = 0; + } + if (extend) + s->packet_length += n; + else + s->packet_length = n; + s->rwstate = SSL_NOTHING; + return (n); +} + +int ssl2_write(SSL *s, const void *_buf, int len) +{ + const unsigned char *buf = _buf; + unsigned int n, tot; + int i; + + if (SSL_in_init(s) && !s->in_handshake) { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_SSL2_WRITE, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + } + + if (s->error) { + ssl2_write_error(s); + if (s->error) + return (-1); + } + + clear_sys_error(); + s->rwstate = SSL_NOTHING; + if (len <= 0) + return (len); + + tot = s->s2->wnum; + s->s2->wnum = 0; + + n = (len - tot); + for (;;) { + i = n_do_ssl_write(s, &(buf[tot]), n); + if (i <= 0) { + s->s2->wnum = tot; + return (i); + } + if ((i == (int)n) || (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) { + return (tot + i); + } + + n -= i; + tot += i; + } +} + +static int write_pending(SSL *s, const unsigned char *buf, unsigned int len) +{ + int i; + + /* s->s2->wpend_len != 0 MUST be true. */ + + /* + * check that they have given us the same buffer to write + */ + if ((s->s2->wpend_tot > (int)len) || + ((s->s2->wpend_buf != buf) && + !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER))) { + SSLerr(SSL_F_WRITE_PENDING, SSL_R_BAD_WRITE_RETRY); + return (-1); + } + + for (;;) { + clear_sys_error(); + if (s->wbio != NULL) { + s->rwstate = SSL_WRITING; + i = BIO_write(s->wbio, + (char *)&(s->s2->write_ptr[s->s2->wpend_off]), + (unsigned int)s->s2->wpend_len); + } else { + SSLerr(SSL_F_WRITE_PENDING, SSL_R_WRITE_BIO_NOT_SET); + i = -1; + } +# ifdef PKT_DEBUG + if (s->debug & 0x01) + sleep(1); +# endif + if (i == s->s2->wpend_len) { + s->s2->wpend_len = 0; + s->rwstate = SSL_NOTHING; + return (s->s2->wpend_ret); + } else if (i <= 0) + return (i); + s->s2->wpend_off += i; + s->s2->wpend_len -= i; + } +} + +static int n_do_ssl_write(SSL *s, const unsigned char *buf, unsigned int len) +{ + unsigned int j, k, olen, p, bs; + int mac_size; + register unsigned char *pp; + + olen = len; + + /* + * first check if there is data from an encryption waiting to be sent - + * it must be sent because the other end is waiting. This will happen + * with non-blocking IO. We print it and then return. + */ + if (s->s2->wpend_len != 0) + return (write_pending(s, buf, len)); + + /* set mac_size to mac size */ + if (s->s2->clear_text) + mac_size = 0; + else { + mac_size = EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + return -1; + } + + /* lets set the pad p */ + if (s->s2->clear_text) { + if (len > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) + len = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER; + p = 0; + s->s2->three_byte_header = 0; + /* len=len; */ + } else { + bs = EVP_CIPHER_CTX_block_size(s->enc_read_ctx); + j = len + mac_size; + /* + * Two-byte headers allow for a larger record length than three-byte + * headers, but we can't use them if we need padding or if we have to + * set the escape bit. + */ + if ((j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) && (!s->s2->escape)) { + if (j > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) + j = SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER; + /* + * set k to the max number of bytes with 2 byte header + */ + k = j - (j % bs); + /* how many data bytes? */ + len = k - mac_size; + s->s2->three_byte_header = 0; + p = 0; + } else if ((bs <= 1) && (!s->s2->escape)) { + /*- + * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, thus + * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + */ + s->s2->three_byte_header = 0; + p = 0; + } else { /* we may have to use a 3 byte header */ + + /*- + * If s->s2->escape is not set, then + * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER, and thus + * j < SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER. + */ + p = (j % bs); + p = (p == 0) ? 0 : (bs - p); + if (s->s2->escape) { + s->s2->three_byte_header = 1; + if (j > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) + j = SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER; + } else + s->s2->three_byte_header = (p == 0) ? 0 : 1; + } + } + + /*- + * Now + * j <= SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER + * holds, and if s->s2->three_byte_header is set, then even + * j <= SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER. + */ + + /* + * mac_size is the number of MAC bytes len is the number of data bytes we + * are going to send p is the number of padding bytes (if it is a + * two-byte header, then p == 0) + */ + + s->s2->wlength = len; + s->s2->padding = p; + s->s2->mac_data = &(s->s2->wbuf[3]); + s->s2->wact_data = &(s->s2->wbuf[3 + mac_size]); + + /* + * It would be clearer to write this as follows: + * if (mac_size + len + p > SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER) + * However |len| is user input that could in theory be very large. We + * know |mac_size| and |p| are small, so to avoid any possibility of + * overflow we write it like this. + * + * In theory this should never fail because the logic above should have + * modified |len| if it is too big. But we are being cautious. + */ + if (len > (SSL2_MAX_RECORD_LENGTH_2_BYTE_HEADER - (mac_size + p))) { + return -1; + } + /* we copy the data into s->s2->wbuf */ + memcpy(s->s2->wact_data, buf, len); + if (p) + memset(&(s->s2->wact_data[len]), 0, p); /* arbitrary padding */ + + if (!s->s2->clear_text) { + s->s2->wact_data_length = len + p; + ssl2_mac(s, s->s2->mac_data, 1); + s->s2->wlength += p + mac_size; + if (ssl2_enc(s, 1) < 1) + return -1; + } + + /* package up the header */ + s->s2->wpend_len = s->s2->wlength; + if (s->s2->three_byte_header) { /* 3 byte header */ + pp = s->s2->mac_data; + pp -= 3; + pp[0] = (s->s2->wlength >> 8) & (THREE_BYTE_MASK >> 8); + if (s->s2->escape) + pp[0] |= SEC_ESC_BIT; + pp[1] = s->s2->wlength & 0xff; + pp[2] = s->s2->padding; + s->s2->wpend_len += 3; + } else { + pp = s->s2->mac_data; + pp -= 2; + pp[0] = ((s->s2->wlength >> 8) & (TWO_BYTE_MASK >> 8)) | TWO_BYTE_BIT; + pp[1] = s->s2->wlength & 0xff; + s->s2->wpend_len += 2; + } + s->s2->write_ptr = pp; + + INC32(s->s2->write_sequence); /* expect next number */ + + /* lets try to actually write the data */ + s->s2->wpend_tot = olen; + s->s2->wpend_buf = buf; + + s->s2->wpend_ret = len; + + s->s2->wpend_off = 0; + return (write_pending(s, buf, olen)); +} + +int ssl2_part_read(SSL *s, unsigned long f, int i) +{ + unsigned char *p; + int j; + + if (i < 0) { + /* ssl2_return_error(s); */ + /* + * for non-blocking io, this is not necessarily fatal + */ + return (i); + } else { + s->init_num += i; + + /* + * Check for error. While there are recoverable errors, this + * function is not called when those must be expected; any error + * detected here is fatal. + */ + if (s->init_num >= 3) { + p = (unsigned char *)s->init_buf->data; + if (p[0] == SSL2_MT_ERROR) { + j = (p[1] << 8) | p[2]; + SSLerr((int)f, ssl_mt_error(j)); + s->init_num -= 3; + if (s->init_num > 0) + memmove(p, p + 3, s->init_num); + } + } + + /* + * If it's not an error message, we have some error anyway -- the + * message was shorter than expected. This too is treated as fatal + * (at least if SSL_get_error is asked for its opinion). + */ + return (0); + } +} + +int ssl2_do_write(SSL *s) +{ + int ret; + + ret = ssl2_write(s, &s->init_buf->data[s->init_off], s->init_num); + if (ret == s->init_num) { + if (s->msg_callback) + s->msg_callback(1, s->version, 0, s->init_buf->data, + (size_t)(s->init_off + s->init_num), s, + s->msg_callback_arg); + return (1); + } + if (ret < 0) + return (-1); + s->init_off += ret; + s->init_num -= ret; + return (0); +} + +static int ssl_mt_error(int n) +{ + int ret; + + switch (n) { + case SSL2_PE_NO_CIPHER: + ret = SSL_R_PEER_ERROR_NO_CIPHER; + break; + case SSL2_PE_NO_CERTIFICATE: + ret = SSL_R_PEER_ERROR_NO_CERTIFICATE; + break; + case SSL2_PE_BAD_CERTIFICATE: + ret = SSL_R_PEER_ERROR_CERTIFICATE; + break; + case SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE: + ret = SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE; + break; + default: + ret = SSL_R_UNKNOWN_REMOTE_ERROR_TYPE; + break; + } + return (ret); +} +#else /* !OPENSSL_NO_SSL2 */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif diff --git a/libs/openssl/ssl/s2_srvr.c b/libs/openssl/ssl/s2_srvr.c new file mode 100644 index 00000000..07e9df82 --- /dev/null +++ b/libs/openssl/ssl/s2_srvr.c @@ -0,0 +1,1171 @@ +/* ssl/s2_srvr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "ssl_locl.h" +#ifndef OPENSSL_NO_SSL2 +#include "../crypto/constant_time_locl.h" +# include +# include +# include +# include +# include + +static const SSL_METHOD *ssl2_get_server_method(int ver); +static int get_client_master_key(SSL *s); +static int get_client_hello(SSL *s); +static int server_hello(SSL *s); +static int get_client_finished(SSL *s); +static int server_verify(SSL *s); +static int server_finish(SSL *s); +static int request_certificate(SSL *s); +static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from, + unsigned char *to, int padding); +# define BREAK break + +static const SSL_METHOD *ssl2_get_server_method(int ver) +{ + if (ver == SSL2_VERSION) + return (SSLv2_server_method()); + else + return (NULL); +} + +IMPLEMENT_ssl2_meth_func(SSLv2_server_method, + ssl2_accept, + ssl_undefined_function, ssl2_get_server_method) + +int ssl2_accept(SSL *s) +{ + unsigned long l = (unsigned long)time(NULL); + BUF_MEM *buf = NULL; + int ret = -1; + long num1; + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int new_state, state; + + RAND_add(&l, sizeof(l), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + /* init things to blank */ + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + if (s->cert == NULL) { + SSLerr(SSL_F_SSL2_ACCEPT, SSL_R_NO_CERTIFICATE_SET); + return (-1); + } + + clear_sys_error(); + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_BEFORE: + case SSL_ST_ACCEPT: + case SSL_ST_BEFORE | SSL_ST_ACCEPT: + case SSL_ST_OK | SSL_ST_ACCEPT: + + s->server = 1; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + s->version = SSL2_VERSION; + s->type = SSL_ST_ACCEPT; + + if (s->init_buf == NULL) { + if ((buf = BUF_MEM_new()) == NULL) { + ret = -1; + goto end; + } + if (!BUF_MEM_grow + (buf, (int)SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER)) { + BUF_MEM_free(buf); + ret = -1; + goto end; + } + s->init_buf = buf; + } + s->init_num = 0; + s->ctx->stats.sess_accept++; + s->handshake_func = ssl2_accept; + s->state = SSL2_ST_GET_CLIENT_HELLO_A; + BREAK; + + case SSL2_ST_GET_CLIENT_HELLO_A: + case SSL2_ST_GET_CLIENT_HELLO_B: + case SSL2_ST_GET_CLIENT_HELLO_C: + s->shutdown = 0; + ret = get_client_hello(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_SEND_SERVER_HELLO_A; + BREAK; + + case SSL2_ST_SEND_SERVER_HELLO_A: + case SSL2_ST_SEND_SERVER_HELLO_B: + ret = server_hello(s); + if (ret <= 0) + goto end; + s->init_num = 0; + if (!s->hit) { + s->state = SSL2_ST_GET_CLIENT_MASTER_KEY_A; + BREAK; + } else { + s->state = SSL2_ST_SERVER_START_ENCRYPTION; + BREAK; + } + case SSL2_ST_GET_CLIENT_MASTER_KEY_A: + case SSL2_ST_GET_CLIENT_MASTER_KEY_B: + ret = get_client_master_key(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_SERVER_START_ENCRYPTION; + BREAK; + + case SSL2_ST_SERVER_START_ENCRYPTION: + /* + * Ok we how have sent all the stuff needed to start encrypting, + * the next packet back will be encrypted. + */ + if (!ssl2_enc_init(s, 0)) { + ret = -1; + goto end; + } + s->s2->clear_text = 0; + s->state = SSL2_ST_SEND_SERVER_VERIFY_A; + BREAK; + + case SSL2_ST_SEND_SERVER_VERIFY_A: + case SSL2_ST_SEND_SERVER_VERIFY_B: + ret = server_verify(s); + if (ret <= 0) + goto end; + s->init_num = 0; + if (s->hit) { + /* + * If we are in here, we have been buffering the output, so + * we need to flush it and remove buffering from future + * traffic + */ + s->state = SSL2_ST_SEND_SERVER_VERIFY_C; + BREAK; + } else { + s->state = SSL2_ST_GET_CLIENT_FINISHED_A; + break; + } + + case SSL2_ST_SEND_SERVER_VERIFY_C: + /* get the number of bytes to write */ + num1 = BIO_ctrl(s->wbio, BIO_CTRL_INFO, 0, NULL); + if (num1 > 0) { + s->rwstate = SSL_WRITING; + num1 = BIO_flush(s->wbio); + if (num1 <= 0) { + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + } + + /* flushed and now remove buffering */ + s->wbio = BIO_pop(s->wbio); + + s->state = SSL2_ST_GET_CLIENT_FINISHED_A; + BREAK; + + case SSL2_ST_GET_CLIENT_FINISHED_A: + case SSL2_ST_GET_CLIENT_FINISHED_B: + ret = get_client_finished(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_A; + BREAK; + + case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: + case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: + case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: + case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: + /* + * don't do a 'request certificate' if we don't want to, or we + * already have one, and we only want to do it once. + */ + if (!(s->verify_mode & SSL_VERIFY_PEER) || + ((s->session->peer != NULL) && + (s->verify_mode & SSL_VERIFY_CLIENT_ONCE))) { + s->state = SSL2_ST_SEND_SERVER_FINISHED_A; + break; + } else { + ret = request_certificate(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL2_ST_SEND_SERVER_FINISHED_A; + } + BREAK; + + case SSL2_ST_SEND_SERVER_FINISHED_A: + case SSL2_ST_SEND_SERVER_FINISHED_B: + ret = server_finish(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL_ST_OK; + break; + + case SSL_ST_OK: + BUF_MEM_free(s->init_buf); + ssl_free_wbio_buffer(s); + s->init_buf = NULL; + s->init_num = 0; + /* ERR_clear_error(); */ + + ssl_update_cache(s, SSL_SESS_CACHE_SERVER); + + s->ctx->stats.sess_accept_good++; + /* s->server=1; */ + ret = 1; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + + goto end; + /* BREAK; */ + + default: + SSLerr(SSL_F_SSL2_ACCEPT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* BREAK; */ + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_ACCEPT_LOOP, 1); + s->state = new_state; + } + } + end: + s->in_handshake--; + if (cb != NULL) + cb(s, SSL_CB_ACCEPT_EXIT, ret); + return (ret); +} + +static int get_client_master_key(SSL *s) +{ + int is_export, i, n, keya; + unsigned int num_encrypted_key_bytes, key_length; + unsigned long len; + unsigned char *p; + const SSL_CIPHER *cp; + const EVP_CIPHER *c; + const EVP_MD *md; + unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; + unsigned char decrypt_good; + size_t j; + + p = (unsigned char *)s->init_buf->data; + if (s->state == SSL2_ST_GET_CLIENT_MASTER_KEY_A) { + i = ssl2_read(s, (char *)&(p[s->init_num]), 10 - s->init_num); + + if (i < (10 - s->init_num)) + return (ssl2_part_read(s, SSL_F_GET_CLIENT_MASTER_KEY, i)); + s->init_num = 10; + + if (*(p++) != SSL2_MT_CLIENT_MASTER_KEY) { + if (p[-1] != SSL2_MT_ERROR) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, + SSL_R_READ_WRONG_PACKET_TYPE); + } else + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_PEER_ERROR); + return (-1); + } + + cp = ssl2_get_cipher_by_char(p); + if (cp == NULL || sk_SSL_CIPHER_find(s->session->ciphers, cp) < 0) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_CIPHER_MATCH); + return (-1); + } + s->session->cipher = cp; + + p += 3; + n2s(p, i); + s->s2->tmp.clear = i; + n2s(p, i); + s->s2->tmp.enc = i; + n2s(p, i); + if (i > SSL_MAX_KEY_ARG_LENGTH) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_KEY_ARG_TOO_LONG); + return -1; + } + s->session->key_arg_length = i; + s->state = SSL2_ST_GET_CLIENT_MASTER_KEY_B; + } + + /* SSL2_ST_GET_CLIENT_MASTER_KEY_B */ + p = (unsigned char *)s->init_buf->data; + if (s->init_buf->length < SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); + return -1; + } + keya = s->session->key_arg_length; + len = + 10 + (unsigned long)s->s2->tmp.clear + (unsigned long)s->s2->tmp.enc + + (unsigned long)keya; + if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_MESSAGE_TOO_LONG); + return -1; + } + n = (int)len - s->init_num; + i = ssl2_read(s, (char *)&(p[s->init_num]), n); + if (i != n) + return (ssl2_part_read(s, SSL_F_GET_CLIENT_MASTER_KEY, i)); + if (s->msg_callback) { + /* CLIENT-MASTER-KEY */ + s->msg_callback(0, s->version, 0, p, (size_t)len, s, + s->msg_callback_arg); + } + p += 10; + + memcpy(s->session->key_arg, &(p[s->s2->tmp.clear + s->s2->tmp.enc]), + (unsigned int)keya); + + if (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, SSL_R_NO_PRIVATEKEY); + return (-1); + } + + is_export = SSL_C_IS_EXPORT(s->session->cipher); + + if (!ssl_cipher_get_evp(s->session, &c, &md, NULL, NULL, NULL)) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, + SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS); + return (0); + } + + /* + * The format of the CLIENT-MASTER-KEY message is + * 1 byte message type + * 3 bytes cipher + * 2-byte clear key length (stored in s->s2->tmp.clear) + * 2-byte encrypted key length (stored in s->s2->tmp.enc) + * 2-byte key args length (IV etc) + * clear key + * encrypted key + * key args + * + * If the cipher is an export cipher, then the encrypted key bytes + * are a fixed portion of the total key (5 or 8 bytes). The size of + * this portion is in |num_encrypted_key_bytes|. If the cipher is not an + * export cipher, then the entire key material is encrypted (i.e., clear + * key length must be zero). + */ + key_length = (unsigned int)EVP_CIPHER_key_length(c); + if (key_length > SSL_MAX_MASTER_KEY_LENGTH) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY, ERR_R_INTERNAL_ERROR); + return -1; + } + + if (s->session->cipher->algorithm2 & SSL2_CF_8_BYTE_ENC) { + is_export = 1; + num_encrypted_key_bytes = 8; + } else if (is_export) { + num_encrypted_key_bytes = 5; + } else { + num_encrypted_key_bytes = key_length; + } + + if (s->s2->tmp.clear + num_encrypted_key_bytes != key_length) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_BAD_LENGTH); + return -1; + } + /* + * The encrypted blob must decrypt to the encrypted portion of the key. + * Decryption can't be expanding, so if we don't have enough encrypted + * bytes to fit the key in the buffer, stop now. + */ + if (s->s2->tmp.enc < num_encrypted_key_bytes) { + ssl2_return_error(s,SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_MASTER_KEY,SSL_R_LENGTH_TOO_SHORT); + return -1; + } + + /* + * We must not leak whether a decryption failure occurs because of + * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246, + * section 7.4.7.1). The code follows that advice of the TLS RFC and + * generates a random premaster secret for the case that the decrypt + * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 + */ + + /* + * should be RAND_bytes, but we cannot work around a failure. + */ + if (RAND_pseudo_bytes(rand_premaster_secret, + (int)num_encrypted_key_bytes) <= 0) + return 0; + + i = ssl_rsa_private_decrypt(s->cert, s->s2->tmp.enc, + &(p[s->s2->tmp.clear]), + &(p[s->s2->tmp.clear]), + (s->s2->ssl2_rollback) ? RSA_SSLV23_PADDING : + RSA_PKCS1_PADDING); + ERR_clear_error(); + /* + * If a bad decrypt, continue with protocol but with a random master + * secret (Bleichenbacher attack) + */ + decrypt_good = constant_time_eq_int_8(i, (int)num_encrypted_key_bytes); + for (j = 0; j < num_encrypted_key_bytes; j++) { + p[s->s2->tmp.clear + j] = + constant_time_select_8(decrypt_good, p[s->s2->tmp.clear + j], + rand_premaster_secret[j]); + } + + s->session->master_key_length = (int)key_length; + memcpy(s->session->master_key, p, key_length); + OPENSSL_cleanse(p, key_length); + + return 1; +} + +static int get_client_hello(SSL *s) +{ + int i, n; + unsigned long len; + unsigned char *p; + STACK_OF(SSL_CIPHER) *cs; /* a stack of SSL_CIPHERS */ + STACK_OF(SSL_CIPHER) *cl; /* the ones we want to use */ + STACK_OF(SSL_CIPHER) *prio, *allow; + int z; + + /* + * This is a bit of a hack to check for the correct packet type the first + * time round. + */ + if (s->state == SSL2_ST_GET_CLIENT_HELLO_A) { + s->first_packet = 1; + s->state = SSL2_ST_GET_CLIENT_HELLO_B; + } + + p = (unsigned char *)s->init_buf->data; + if (s->state == SSL2_ST_GET_CLIENT_HELLO_B) { + i = ssl2_read(s, (char *)&(p[s->init_num]), 9 - s->init_num); + if (i < (9 - s->init_num)) + return (ssl2_part_read(s, SSL_F_GET_CLIENT_HELLO, i)); + s->init_num = 9; + + if (*(p++) != SSL2_MT_CLIENT_HELLO) { + if (p[-1] != SSL2_MT_ERROR) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_READ_WRONG_PACKET_TYPE); + } else + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_PEER_ERROR); + return (-1); + } + n2s(p, i); + if (i < s->version) + s->version = i; + n2s(p, i); + s->s2->tmp.cipher_spec_length = i; + n2s(p, i); + s->s2->tmp.session_id_length = i; + if ((i < 0) || (i > SSL_MAX_SSL_SESSION_ID_LENGTH)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); + return -1; + } + n2s(p, i); + s->s2->challenge_length = i; + if ((i < SSL2_MIN_CHALLENGE_LENGTH) || + (i > SSL2_MAX_CHALLENGE_LENGTH)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_INVALID_CHALLENGE_LENGTH); + return (-1); + } + s->state = SSL2_ST_GET_CLIENT_HELLO_C; + } + + /* SSL2_ST_GET_CLIENT_HELLO_C */ + p = (unsigned char *)s->init_buf->data; + len = + 9 + (unsigned long)s->s2->tmp.cipher_spec_length + + (unsigned long)s->s2->challenge_length + + (unsigned long)s->s2->tmp.session_id_length; + if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_MESSAGE_TOO_LONG); + return -1; + } + n = (int)len - s->init_num; + i = ssl2_read(s, (char *)&(p[s->init_num]), n); + if (i != n) + return (ssl2_part_read(s, SSL_F_GET_CLIENT_HELLO, i)); + if (s->msg_callback) { + /* CLIENT-HELLO */ + s->msg_callback(0, s->version, 0, p, (size_t)len, s, + s->msg_callback_arg); + } + p += 9; + + /* + * get session-id before cipher stuff so we can get out session structure + * if it is cached + */ + /* session-id */ + if ((s->s2->tmp.session_id_length != 0) && + (s->s2->tmp.session_id_length != SSL2_SSL_SESSION_ID_LENGTH)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_BAD_SSL_SESSION_ID_LENGTH); + return (-1); + } + + if (s->s2->tmp.session_id_length == 0) { + if (!ssl_get_new_session(s, 1)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + return (-1); + } + } else { + i = ssl_get_prev_session(s, &(p[s->s2->tmp.cipher_spec_length]), + s->s2->tmp.session_id_length, NULL); + if (i == 1) { /* previous session */ + s->hit = 1; + } else if (i == -1) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + return (-1); + } else { + if (s->cert == NULL) { + ssl2_return_error(s, SSL2_PE_NO_CERTIFICATE); + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_NO_CERTIFICATE_SET); + return (-1); + } + + if (!ssl_get_new_session(s, 1)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + return (-1); + } + } + } + + if (!s->hit) { + cs = ssl_bytes_to_cipher_list(s, p, s->s2->tmp.cipher_spec_length, + &s->session->ciphers); + if (cs == NULL) + goto mem_err; + + cl = SSL_get_ciphers(s); + + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + prio = sk_SSL_CIPHER_dup(cl); + if (prio == NULL) + goto mem_err; + allow = cs; + } else { + prio = cs; + allow = cl; + } + + /* Generate list of SSLv2 ciphers shared between client and server */ + for (z = 0; z < sk_SSL_CIPHER_num(prio); z++) { + const SSL_CIPHER *cp = sk_SSL_CIPHER_value(prio, z); + if ((cp->algorithm_ssl & SSL_SSLV2) == 0 || + sk_SSL_CIPHER_find(allow, cp) < 0) { + (void)sk_SSL_CIPHER_delete(prio, z); + z--; + } + } + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + sk_SSL_CIPHER_free(s->session->ciphers); + s->session->ciphers = prio; + } + + /* Make sure we have at least one cipher in common */ + if (sk_SSL_CIPHER_num(s->session->ciphers) == 0) { + ssl2_return_error(s, SSL2_PE_NO_CIPHER); + SSLerr(SSL_F_GET_CLIENT_HELLO, SSL_R_NO_CIPHER_MATCH); + return -1; + } + /* + * s->session->ciphers should now have a list of ciphers that are on + * both the client and server. This list is ordered by the order the + * client sent the ciphers or in the order of the server's preference + * if SSL_OP_CIPHER_SERVER_PREFERENCE was set. + */ + } + p += s->s2->tmp.cipher_spec_length; + /* done cipher selection */ + + /* session id extracted already */ + p += s->s2->tmp.session_id_length; + + /* challenge */ + if (s->s2->challenge_length > sizeof s->s2->challenge) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + return -1; + } + memcpy(s->s2->challenge, p, (unsigned int)s->s2->challenge_length); + return (1); + mem_err: + SSLerr(SSL_F_GET_CLIENT_HELLO, ERR_R_MALLOC_FAILURE); + return (0); +} + +static int server_hello(SSL *s) +{ + unsigned char *p, *d; + int n, hit; + + p = (unsigned char *)s->init_buf->data; + if (s->state == SSL2_ST_SEND_SERVER_HELLO_A) { + d = p + 11; + *(p++) = SSL2_MT_SERVER_HELLO; /* type */ + hit = s->hit; + *(p++) = (unsigned char)hit; +# if 1 + if (!hit) { + if (s->session->sess_cert != NULL) + /* + * This can't really happen because get_client_hello has + * called ssl_get_new_session, which does not set sess_cert. + */ + ssl_sess_cert_free(s->session->sess_cert); + s->session->sess_cert = ssl_sess_cert_new(); + if (s->session->sess_cert == NULL) { + SSLerr(SSL_F_SERVER_HELLO, ERR_R_MALLOC_FAILURE); + return (-1); + } + } + /* + * If 'hit' is set, then s->sess_cert may be non-NULL or NULL, + * depending on whether it survived in the internal cache or was + * retrieved from an external cache. If it is NULL, we cannot put any + * useful data in it anyway, so we don't touch it. + */ + +# else /* That's what used to be done when cert_st + * and sess_cert_st were * the same. */ + if (!hit) { /* else add cert to session */ + CRYPTO_add(&s->cert->references, 1, CRYPTO_LOCK_SSL_CERT); + if (s->session->sess_cert != NULL) + ssl_cert_free(s->session->sess_cert); + s->session->sess_cert = s->cert; + } else { /* We have a session id-cache hit, if the * + * session-id has no certificate listed + * against * the 'cert' structure, grab the + * 'old' one * listed against the SSL + * connection */ + if (s->session->sess_cert == NULL) { + CRYPTO_add(&s->cert->references, 1, CRYPTO_LOCK_SSL_CERT); + s->session->sess_cert = s->cert; + } + } +# endif + + if (s->cert == NULL) { + ssl2_return_error(s, SSL2_PE_NO_CERTIFICATE); + SSLerr(SSL_F_SERVER_HELLO, SSL_R_NO_CERTIFICATE_SPECIFIED); + return (-1); + } + + if (hit) { + *(p++) = 0; /* no certificate type */ + s2n(s->version, p); /* version */ + s2n(0, p); /* cert len */ + s2n(0, p); /* ciphers len */ + } else { + /* EAY EAY */ + /* put certificate type */ + *(p++) = SSL2_CT_X509_CERTIFICATE; + s2n(s->version, p); /* version */ + n = i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, NULL); + s2n(n, p); /* certificate length */ + i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, &d); + n = 0; + + /* + * lets send out the ciphers we like in the prefered order + */ + n = ssl_cipher_list_to_bytes(s, s->session->ciphers, d, 0); + d += n; + s2n(n, p); /* add cipher length */ + } + + /* make and send conn_id */ + s2n(SSL2_CONNECTION_ID_LENGTH, p); /* add conn_id length */ + s->s2->conn_id_length = SSL2_CONNECTION_ID_LENGTH; + if (RAND_pseudo_bytes(s->s2->conn_id, (int)s->s2->conn_id_length) <= + 0) + return -1; + memcpy(d, s->s2->conn_id, SSL2_CONNECTION_ID_LENGTH); + d += SSL2_CONNECTION_ID_LENGTH; + + s->state = SSL2_ST_SEND_SERVER_HELLO_B; + s->init_num = d - (unsigned char *)s->init_buf->data; + s->init_off = 0; + } + /* SSL2_ST_SEND_SERVER_HELLO_B */ + /* + * If we are using TCP/IP, the performance is bad if we do 2 writes + * without a read between them. This occurs when Session-id reuse is + * used, so I will put in a buffering module + */ + if (s->hit) { + if (!ssl_init_wbio_buffer(s, 1)) + return (-1); + } + + return (ssl2_do_write(s)); +} + +static int get_client_finished(SSL *s) +{ + unsigned char *p; + int i, n; + unsigned long len; + + p = (unsigned char *)s->init_buf->data; + if (s->state == SSL2_ST_GET_CLIENT_FINISHED_A) { + i = ssl2_read(s, (char *)&(p[s->init_num]), 1 - s->init_num); + if (i < 1 - s->init_num) + return (ssl2_part_read(s, SSL_F_GET_CLIENT_FINISHED, i)); + s->init_num += i; + + if (*p != SSL2_MT_CLIENT_FINISHED) { + if (*p != SSL2_MT_ERROR) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_FINISHED, + SSL_R_READ_WRONG_PACKET_TYPE); + } else { + SSLerr(SSL_F_GET_CLIENT_FINISHED, SSL_R_PEER_ERROR); + /* try to read the error message */ + i = ssl2_read(s, (char *)&(p[s->init_num]), 3 - s->init_num); + return ssl2_part_read(s, SSL_F_GET_SERVER_VERIFY, i); + } + return (-1); + } + s->state = SSL2_ST_GET_CLIENT_FINISHED_B; + } + + /* SSL2_ST_GET_CLIENT_FINISHED_B */ + if (s->s2->conn_id_length > sizeof s->s2->conn_id) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_FINISHED, ERR_R_INTERNAL_ERROR); + return -1; + } + len = 1 + (unsigned long)s->s2->conn_id_length; + n = (int)len - s->init_num; + i = ssl2_read(s, (char *)&(p[s->init_num]), n); + if (i < n) { + return (ssl2_part_read(s, SSL_F_GET_CLIENT_FINISHED, i)); + } + if (s->msg_callback) { + /* CLIENT-FINISHED */ + s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); + } + p += 1; + if (memcmp(p, s->s2->conn_id, s->s2->conn_id_length) != 0) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_GET_CLIENT_FINISHED, SSL_R_CONNECTION_ID_IS_DIFFERENT); + return (-1); + } + return (1); +} + +static int server_verify(SSL *s) +{ + unsigned char *p; + + if (s->state == SSL2_ST_SEND_SERVER_VERIFY_A) { + p = (unsigned char *)s->init_buf->data; + *(p++) = SSL2_MT_SERVER_VERIFY; + if (s->s2->challenge_length > sizeof s->s2->challenge) { + SSLerr(SSL_F_SERVER_VERIFY, ERR_R_INTERNAL_ERROR); + return -1; + } + memcpy(p, s->s2->challenge, (unsigned int)s->s2->challenge_length); + /* p+=s->s2->challenge_length; */ + + s->state = SSL2_ST_SEND_SERVER_VERIFY_B; + s->init_num = s->s2->challenge_length + 1; + s->init_off = 0; + } + return (ssl2_do_write(s)); +} + +static int server_finish(SSL *s) +{ + unsigned char *p; + + if (s->state == SSL2_ST_SEND_SERVER_FINISHED_A) { + p = (unsigned char *)s->init_buf->data; + *(p++) = SSL2_MT_SERVER_FINISHED; + + if (s->session->session_id_length > sizeof s->session->session_id) { + SSLerr(SSL_F_SERVER_FINISH, ERR_R_INTERNAL_ERROR); + return -1; + } + memcpy(p, s->session->session_id, + (unsigned int)s->session->session_id_length); + /* p+=s->session->session_id_length; */ + + s->state = SSL2_ST_SEND_SERVER_FINISHED_B; + s->init_num = s->session->session_id_length + 1; + s->init_off = 0; + } + + /* SSL2_ST_SEND_SERVER_FINISHED_B */ + return (ssl2_do_write(s)); +} + +/* send the request and check the response */ +static int request_certificate(SSL *s) +{ + const unsigned char *cp; + unsigned char *p, *p2, *buf2; + unsigned char *ccd; + int i, j, ctype, ret = -1; + unsigned long len; + X509 *x509 = NULL; + STACK_OF(X509) *sk = NULL; + + ccd = s->s2->tmp.ccl; + if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_A) { + p = (unsigned char *)s->init_buf->data; + *(p++) = SSL2_MT_REQUEST_CERTIFICATE; + *(p++) = SSL2_AT_MD5_WITH_RSA_ENCRYPTION; + if (RAND_pseudo_bytes(ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH) <= 0) + return -1; + memcpy(p, ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH); + + s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_B; + s->init_num = SSL2_MIN_CERT_CHALLENGE_LENGTH + 2; + s->init_off = 0; + } + + if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_B) { + i = ssl2_do_write(s); + if (i <= 0) { + ret = i; + goto end; + } + + s->init_num = 0; + s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_C; + } + + if (s->state == SSL2_ST_SEND_REQUEST_CERTIFICATE_C) { + p = (unsigned char *)s->init_buf->data; + /* try to read 6 octets ... */ + i = ssl2_read(s, (char *)&(p[s->init_num]), 6 - s->init_num); + /* + * ... but don't call ssl2_part_read now if we got at least 3 + * (probably NO-CERTIFICATE-ERROR) + */ + if (i < 3 - s->init_num) { + ret = ssl2_part_read(s, SSL_F_REQUEST_CERTIFICATE, i); + goto end; + } + s->init_num += i; + + if ((s->init_num >= 3) && (p[0] == SSL2_MT_ERROR)) { + n2s(p, i); + if (i != SSL2_PE_NO_CERTIFICATE) { + /* + * not the error message we expected -- let ssl2_part_read + * handle it + */ + s->init_num -= 3; + ret = ssl2_part_read(s, SSL_F_REQUEST_CERTIFICATE, 3); + goto end; + } + + if (s->msg_callback) { + /* ERROR */ + s->msg_callback(0, s->version, 0, p, 3, s, + s->msg_callback_arg); + } + + /* + * this is the one place where we can recover from an SSL 2.0 + * error + */ + + if (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { + ssl2_return_error(s, SSL2_PE_BAD_CERTIFICATE); + SSLerr(SSL_F_REQUEST_CERTIFICATE, + SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + goto end; + } + ret = 1; + goto end; + } + if ((*(p++) != SSL2_MT_CLIENT_CERTIFICATE) || (s->init_num < 6)) { + ssl2_return_error(s, SSL2_PE_UNDEFINED_ERROR); + SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_SHORT_READ); + goto end; + } + if (s->init_num != 6) { + SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_INTERNAL_ERROR); + goto end; + } + + /* ok we have a response */ + /* certificate type, there is only one right now. */ + ctype = *(p++); + if (ctype != SSL2_AT_MD5_WITH_RSA_ENCRYPTION) { + ssl2_return_error(s, SSL2_PE_UNSUPPORTED_CERTIFICATE_TYPE); + SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_BAD_RESPONSE_ARGUMENT); + goto end; + } + n2s(p, i); + s->s2->tmp.clen = i; + n2s(p, i); + s->s2->tmp.rlen = i; + s->state = SSL2_ST_SEND_REQUEST_CERTIFICATE_D; + } + + /* SSL2_ST_SEND_REQUEST_CERTIFICATE_D */ + p = (unsigned char *)s->init_buf->data; + len = 6 + (unsigned long)s->s2->tmp.clen + (unsigned long)s->s2->tmp.rlen; + if (len > SSL2_MAX_RECORD_LENGTH_3_BYTE_HEADER) { + SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_MESSAGE_TOO_LONG); + goto end; + } + j = (int)len - s->init_num; + i = ssl2_read(s, (char *)&(p[s->init_num]), j); + if (i < j) { + ret = ssl2_part_read(s, SSL_F_REQUEST_CERTIFICATE, i); + goto end; + } + if (s->msg_callback) { + /* CLIENT-CERTIFICATE */ + s->msg_callback(0, s->version, 0, p, len, s, s->msg_callback_arg); + } + p += 6; + + cp = p; + x509 = (X509 *)d2i_X509(NULL, &cp, (long)s->s2->tmp.clen); + if (x509 == NULL) { + SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_X509_LIB); + goto msg_end; + } + + if (((sk = sk_X509_new_null()) == NULL) || (!sk_X509_push(sk, x509))) { + SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto msg_end; + } + + i = ssl_verify_cert_chain(s, sk); + + if (i > 0) { /* we like the packet, now check the chksum */ + EVP_MD_CTX ctx; + EVP_PKEY *pkey = NULL; + + EVP_MD_CTX_init(&ctx); + if (!EVP_VerifyInit_ex(&ctx, s->ctx->rsa_md5, NULL) + || !EVP_VerifyUpdate(&ctx, s->s2->key_material, + s->s2->key_material_length) + || !EVP_VerifyUpdate(&ctx, ccd, SSL2_MIN_CERT_CHALLENGE_LENGTH)) + goto msg_end; + + i = i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, NULL); + buf2 = OPENSSL_malloc((unsigned int)i); + if (buf2 == NULL) { + SSLerr(SSL_F_REQUEST_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto msg_end; + } + p2 = buf2; + i = i2d_X509(s->cert->pkeys[SSL_PKEY_RSA_ENC].x509, &p2); + if (!EVP_VerifyUpdate(&ctx, buf2, (unsigned int)i)) { + OPENSSL_free(buf2); + goto msg_end; + } + OPENSSL_free(buf2); + + pkey = X509_get_pubkey(x509); + if (pkey == NULL) + goto end; + i = EVP_VerifyFinal(&ctx, cp, s->s2->tmp.rlen, pkey); + EVP_PKEY_free(pkey); + EVP_MD_CTX_cleanup(&ctx); + + if (i > 0) { + if (s->session->peer != NULL) + X509_free(s->session->peer); + s->session->peer = x509; + CRYPTO_add(&x509->references, 1, CRYPTO_LOCK_X509); + s->session->verify_result = s->verify_result; + ret = 1; + goto end; + } else { + SSLerr(SSL_F_REQUEST_CERTIFICATE, SSL_R_BAD_CHECKSUM); + goto msg_end; + } + } else { + msg_end: + ssl2_return_error(s, SSL2_PE_BAD_CERTIFICATE); + } + end: + sk_X509_free(sk); + X509_free(x509); + return (ret); +} + +static int ssl_rsa_private_decrypt(CERT *c, int len, unsigned char *from, + unsigned char *to, int padding) +{ + RSA *rsa; + int i; + + if ((c == NULL) || (c->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL)) { + SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT, SSL_R_NO_PRIVATEKEY); + return (-1); + } + if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey->type != EVP_PKEY_RSA) { + SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT, SSL_R_PUBLIC_KEY_IS_NOT_RSA); + return (-1); + } + rsa = c->pkeys[SSL_PKEY_RSA_ENC].privatekey->pkey.rsa; + + /* we have the public key */ + i = RSA_private_decrypt(len, from, to, rsa, padding); + if (i < 0) + SSLerr(SSL_F_SSL_RSA_PRIVATE_DECRYPT, ERR_R_RSA_LIB); + return (i); +} +#else /* !OPENSSL_NO_SSL2 */ + +# if PEDANTIC +static void *dummy = &dummy; +# endif + +#endif diff --git a/libs/openssl/ssl/s3_both.c b/libs/openssl/ssl/s3_both.c new file mode 100644 index 00000000..107b460f --- /dev/null +++ b/libs/openssl/ssl/s3_both.c @@ -0,0 +1,818 @@ +/* ssl/s3_both.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include +#include +#include +#include "ssl_locl.h" +#include +#include +#include +#include +#include + +/* + * send s->init_buf in records of type 'type' (SSL3_RT_HANDSHAKE or + * SSL3_RT_CHANGE_CIPHER_SPEC) + */ +int ssl3_do_write(SSL *s, int type) +{ + int ret; + + ret = ssl3_write_bytes(s, type, &s->init_buf->data[s->init_off], + s->init_num); + if (ret < 0) + return (-1); + if (type == SSL3_RT_HANDSHAKE) + /* + * should not be done for 'Hello Request's, but in that case we'll + * ignore the result anyway + */ + ssl3_finish_mac(s, (unsigned char *)&s->init_buf->data[s->init_off], + ret); + + if (ret == s->init_num) { + if (s->msg_callback) + s->msg_callback(1, s->version, type, s->init_buf->data, + (size_t)(s->init_off + s->init_num), s, + s->msg_callback_arg); + return (1); + } + s->init_off += ret; + s->init_num -= ret; + return (0); +} + +int ssl3_send_finished(SSL *s, int a, int b, const char *sender, int slen) +{ + unsigned char *p, *d; + int i; + unsigned long l; + + if (s->state == a) { + d = (unsigned char *)s->init_buf->data; + p = &(d[4]); + + i = s->method->ssl3_enc->final_finish_mac(s, + sender, slen, + s->s3->tmp.finish_md); + if (i <= 0) + return 0; + s->s3->tmp.finish_md_len = i; + memcpy(p, s->s3->tmp.finish_md, i); + p += i; + l = i; + + /* + * Copy the finished so we can use it for renegotiation checks + */ + if (s->type == SSL_ST_CONNECT) { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_client_finished, s->s3->tmp.finish_md, i); + s->s3->previous_client_finished_len = i; + } else { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_server_finished, s->s3->tmp.finish_md, i); + s->s3->previous_server_finished_len = i; + } + +#ifdef OPENSSL_SYS_WIN16 + /* + * MSVC 1.5 does not clear the top bytes of the word unless I do + * this. + */ + l &= 0xffff; +#endif + + *(d++) = SSL3_MT_FINISHED; + l2n3(l, d); + s->init_num = (int)l + 4; + s->init_off = 0; + + s->state = b; + } + + /* SSL3_ST_SEND_xxxxxx_HELLO_B */ + return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); +} + +#ifndef OPENSSL_NO_NEXTPROTONEG +/* + * ssl3_take_mac calculates the Finished MAC for the handshakes messages seen + * to far. + */ +static void ssl3_take_mac(SSL *s) +{ + const char *sender; + int slen; + /* + * If no new cipher setup return immediately: other functions will set + * the appropriate error. + */ + if (s->s3->tmp.new_cipher == NULL) + return; + if (s->state & SSL_ST_CONNECT) { + sender = s->method->ssl3_enc->server_finished_label; + slen = s->method->ssl3_enc->server_finished_label_len; + } else { + sender = s->method->ssl3_enc->client_finished_label; + slen = s->method->ssl3_enc->client_finished_label_len; + } + + s->s3->tmp.peer_finish_md_len = s->method->ssl3_enc->final_finish_mac(s, + sender, + slen, + s->s3->tmp.peer_finish_md); +} +#endif + +int ssl3_get_finished(SSL *s, int a, int b) +{ + int al, i, ok; + long n; + unsigned char *p; + +#ifdef OPENSSL_NO_NEXTPROTONEG + /* + * the mac has already been generated when we received the change cipher + * spec message and is in s->s3->tmp.peer_finish_md. + */ +#endif + + /* 64 argument should actually be 36+4 :-) */ + n = s->method->ssl_get_message(s, a, b, SSL3_MT_FINISHED, 64, &ok); + + if (!ok) + return ((int)n); + + /* If this occurs, we have missed a message */ + if (!s->s3->change_cipher_spec) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_GOT_A_FIN_BEFORE_A_CCS); + goto f_err; + } + s->s3->change_cipher_spec = 0; + + p = (unsigned char *)s->init_msg; + i = s->s3->tmp.peer_finish_md_len; + + if (i != n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_BAD_DIGEST_LENGTH); + goto f_err; + } + + if (CRYPTO_memcmp(p, s->s3->tmp.peer_finish_md, i) != 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_FINISHED, SSL_R_DIGEST_CHECK_FAILED); + goto f_err; + } + + /* + * Copy the finished so we can use it for renegotiation checks + */ + if (s->type == SSL_ST_ACCEPT) { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_client_finished, s->s3->tmp.peer_finish_md, i); + s->s3->previous_client_finished_len = i; + } else { + OPENSSL_assert(i <= EVP_MAX_MD_SIZE); + memcpy(s->s3->previous_server_finished, s->s3->tmp.peer_finish_md, i); + s->s3->previous_server_finished_len = i; + } + + return (1); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return (0); +} + +/*- + * for these 2 messages, we need to + * ssl->enc_read_ctx re-init + * ssl->s3->read_sequence zero + * ssl->s3->read_mac_secret re-init + * ssl->session->read_sym_enc assign + * ssl->session->read_compression assign + * ssl->session->read_hash assign + */ +int ssl3_send_change_cipher_spec(SSL *s, int a, int b) +{ + unsigned char *p; + + if (s->state == a) { + p = (unsigned char *)s->init_buf->data; + *p = SSL3_MT_CCS; + s->init_num = 1; + s->init_off = 0; + + s->state = b; + } + + /* SSL3_ST_CW_CHANGE_B */ + return (ssl3_do_write(s, SSL3_RT_CHANGE_CIPHER_SPEC)); +} + +static int ssl3_add_cert_to_buf(BUF_MEM *buf, unsigned long *l, X509 *x) +{ + int n; + unsigned char *p; + + n = i2d_X509(x, NULL); + if (!BUF_MEM_grow_clean(buf, (int)(n + (*l) + 3))) { + SSLerr(SSL_F_SSL3_ADD_CERT_TO_BUF, ERR_R_BUF_LIB); + return (-1); + } + p = (unsigned char *)&(buf->data[*l]); + l2n3(n, p); + i2d_X509(x, &p); + *l += n + 3; + + return (0); +} + +unsigned long ssl3_output_cert_chain(SSL *s, X509 *x) +{ + unsigned char *p; + int i; + unsigned long l = 7; + BUF_MEM *buf; + int no_chain; + + if ((s->mode & SSL_MODE_NO_AUTO_CHAIN) || s->ctx->extra_certs) + no_chain = 1; + else + no_chain = 0; + + /* TLSv1 sends a chain with nothing in it, instead of an alert */ + buf = s->init_buf; + if (!BUF_MEM_grow_clean(buf, 10)) { + SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_BUF_LIB); + return (0); + } + if (x != NULL) { + if (no_chain) { + if (ssl3_add_cert_to_buf(buf, &l, x)) + return (0); + } else { + X509_STORE_CTX xs_ctx; + + if (!X509_STORE_CTX_init(&xs_ctx, s->ctx->cert_store, x, NULL)) { + SSLerr(SSL_F_SSL3_OUTPUT_CERT_CHAIN, ERR_R_X509_LIB); + return (0); + } + X509_verify_cert(&xs_ctx); + /* Don't leave errors in the queue */ + ERR_clear_error(); + for (i = 0; i < sk_X509_num(xs_ctx.chain); i++) { + x = sk_X509_value(xs_ctx.chain, i); + + if (ssl3_add_cert_to_buf(buf, &l, x)) { + X509_STORE_CTX_cleanup(&xs_ctx); + return 0; + } + } + X509_STORE_CTX_cleanup(&xs_ctx); + } + } + /* Thawte special :-) */ + for (i = 0; i < sk_X509_num(s->ctx->extra_certs); i++) { + x = sk_X509_value(s->ctx->extra_certs, i); + if (ssl3_add_cert_to_buf(buf, &l, x)) + return (0); + } + + l -= 7; + p = (unsigned char *)&(buf->data[4]); + l2n3(l, p); + l += 3; + p = (unsigned char *)&(buf->data[0]); + *(p++) = SSL3_MT_CERTIFICATE; + l2n3(l, p); + l += 4; + return (l); +} + +/* + * Obtain handshake message of message type 'mt' (any if mt == -1), maximum + * acceptable body length 'max'. The first four bytes (msg_type and length) + * are read in state 'st1', the body is read in state 'stn'. + */ +long ssl3_get_message(SSL *s, int st1, int stn, int mt, long max, int *ok) +{ + unsigned char *p; + unsigned long l; + long n; + int i, al; + + if (s->s3->tmp.reuse_message) { + s->s3->tmp.reuse_message = 0; + if ((mt >= 0) && (s->s3->tmp.message_type != mt)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + *ok = 1; + s->state = stn; + s->init_msg = s->init_buf->data + 4; + s->init_num = (int)s->s3->tmp.message_size; + return s->init_num; + } + + p = (unsigned char *)s->init_buf->data; + + if (s->state == st1) { /* s->init_num < 4 */ + int skip_message; + + do { + while (s->init_num < 4) { + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, + &p[s->init_num], + 4 - s->init_num, 0); + if (i <= 0) { + s->rwstate = SSL_READING; + *ok = 0; + return i; + } + s->init_num += i; + } + + skip_message = 0; + if (!s->server) + if (p[0] == SSL3_MT_HELLO_REQUEST) + /* + * The server may always send 'Hello Request' messages -- + * we are doing a handshake anyway now, so ignore them if + * their format is correct. Does not count for 'Finished' + * MAC. + */ + if (p[1] == 0 && p[2] == 0 && p[3] == 0) { + s->init_num = 0; + skip_message = 1; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + p, 4, s, s->msg_callback_arg); + } + } + while (skip_message); + + /* s->init_num == 4 */ + + if ((mt >= 0) && (*p != mt)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + if ((mt < 0) && (*p == SSL3_MT_CLIENT_HELLO) && + (st1 == SSL3_ST_SR_CERT_A) && (stn == SSL3_ST_SR_CERT_B)) { + /* + * At this point we have got an MS SGC second client hello (maybe + * we should always allow the client to start a new handshake?). + * We need to restart the mac. Don't increment + * {num,total}_renegotiations because we have not completed the + * handshake. + */ + ssl3_init_finished_mac(s); + } + + s->s3->tmp.message_type = *(p++); + + n2l3(p, l); + if (l > (unsigned long)max) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE); + goto f_err; + } + if (l > (INT_MAX - 4)) { /* BUF_MEM_grow takes an 'int' parameter */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_MESSAGE, SSL_R_EXCESSIVE_MESSAGE_SIZE); + goto f_err; + } + if (l && !BUF_MEM_grow_clean(s->init_buf, (int)l + 4)) { + SSLerr(SSL_F_SSL3_GET_MESSAGE, ERR_R_BUF_LIB); + goto err; + } + s->s3->tmp.message_size = l; + s->state = stn; + + s->init_msg = s->init_buf->data + 4; + s->init_num = 0; + } + + /* next state (stn) */ + p = s->init_msg; + n = s->s3->tmp.message_size - s->init_num; + while (n > 0) { + i = s->method->ssl_read_bytes(s, SSL3_RT_HANDSHAKE, &p[s->init_num], + n, 0); + if (i <= 0) { + s->rwstate = SSL_READING; + *ok = 0; + return i; + } + s->init_num += i; + n -= i; + } + +#ifndef OPENSSL_NO_NEXTPROTONEG + /* + * If receiving Finished, record MAC of prior handshake messages for + * Finished verification. + */ + if (*s->init_buf->data == SSL3_MT_FINISHED) + ssl3_take_mac(s); +#endif + + /* Feed this message into MAC computation. */ + ssl3_finish_mac(s, (unsigned char *)s->init_buf->data, s->init_num + 4); + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, s->init_buf->data, + (size_t)s->init_num + 4, s, s->msg_callback_arg); + *ok = 1; + return s->init_num; + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + *ok = 0; + return (-1); +} + +int ssl_cert_type(X509 *x, EVP_PKEY *pkey) +{ + EVP_PKEY *pk; + int ret = -1, i; + + if (pkey == NULL) + pk = X509_get_pubkey(x); + else + pk = pkey; + if (pk == NULL) + goto err; + + i = pk->type; + if (i == EVP_PKEY_RSA) { + ret = SSL_PKEY_RSA_ENC; + } else if (i == EVP_PKEY_DSA) { + ret = SSL_PKEY_DSA_SIGN; + } +#ifndef OPENSSL_NO_EC + else if (i == EVP_PKEY_EC) { + ret = SSL_PKEY_ECC; + } +#endif + else if (i == NID_id_GostR3410_94 || i == NID_id_GostR3410_94_cc) { + ret = SSL_PKEY_GOST94; + } else if (i == NID_id_GostR3410_2001 || i == NID_id_GostR3410_2001_cc) { + ret = SSL_PKEY_GOST01; + } + err: + if (!pkey) + EVP_PKEY_free(pk); + return (ret); +} + +int ssl_verify_alarm_type(long type) +{ + int al; + + switch (type) { + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + case X509_V_ERR_UNABLE_TO_GET_CRL: + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + al = SSL_AD_UNKNOWN_CA; + break; + case X509_V_ERR_UNABLE_TO_DECRYPT_CERT_SIGNATURE: + case X509_V_ERR_UNABLE_TO_DECRYPT_CRL_SIGNATURE: + case X509_V_ERR_UNABLE_TO_DECODE_ISSUER_PUBLIC_KEY: + case X509_V_ERR_ERROR_IN_CERT_NOT_BEFORE_FIELD: + case X509_V_ERR_ERROR_IN_CERT_NOT_AFTER_FIELD: + case X509_V_ERR_ERROR_IN_CRL_LAST_UPDATE_FIELD: + case X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD: + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_CRL_NOT_YET_VALID: + case X509_V_ERR_CERT_UNTRUSTED: + case X509_V_ERR_CERT_REJECTED: + al = SSL_AD_BAD_CERTIFICATE; + break; + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + al = SSL_AD_DECRYPT_ERROR; + break; + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_CRL_HAS_EXPIRED: + al = SSL_AD_CERTIFICATE_EXPIRED; + break; + case X509_V_ERR_CERT_REVOKED: + al = SSL_AD_CERTIFICATE_REVOKED; + break; + case X509_V_ERR_OUT_OF_MEM: + al = SSL_AD_INTERNAL_ERROR; + break; + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + case X509_V_ERR_INVALID_CA: + al = SSL_AD_UNKNOWN_CA; + break; + case X509_V_ERR_APPLICATION_VERIFICATION: + al = SSL_AD_HANDSHAKE_FAILURE; + break; + case X509_V_ERR_INVALID_PURPOSE: + al = SSL_AD_UNSUPPORTED_CERTIFICATE; + break; + default: + al = SSL_AD_CERTIFICATE_UNKNOWN; + break; + } + return (al); +} + +#ifndef OPENSSL_NO_BUF_FREELISTS +/*- + * On some platforms, malloc() performance is bad enough that you can't just + * free() and malloc() buffers all the time, so we need to use freelists from + * unused buffers. Currently, each freelist holds memory chunks of only a + * given size (list->chunklen); other sized chunks are freed and malloced. + * This doesn't help much if you're using many different SSL option settings + * with a given context. (The options affecting buffer size are + * max_send_fragment, read buffer vs write buffer, + * SSL_OP_MICROSOFT_BIG_WRITE_BUFFER, SSL_OP_NO_COMPRESSION, and + * SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS.) Using a separate freelist for every + * possible size is not an option, since max_send_fragment can take on many + * different values. + * + * If you are on a platform with a slow malloc(), and you're using SSL + * connections with many different settings for these options, and you need to + * use the SSL_MOD_RELEASE_BUFFERS feature, you have a few options: + * - Link against a faster malloc implementation. + * - Use a separate SSL_CTX for each option set. + * - Improve this code. + */ +static void *freelist_extract(SSL_CTX *ctx, int for_read, int sz) +{ + SSL3_BUF_FREELIST *list; + SSL3_BUF_FREELIST_ENTRY *ent = NULL; + void *result = NULL; + + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist; + if (list != NULL && sz == (int)list->chunklen) + ent = list->head; + if (ent != NULL) { + list->head = ent->next; + result = ent; + if (--list->len == 0) + list->chunklen = 0; + } + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + if (!result) + result = OPENSSL_malloc(sz); + return result; +} + +static void freelist_insert(SSL_CTX *ctx, int for_read, size_t sz, void *mem) +{ + SSL3_BUF_FREELIST *list; + SSL3_BUF_FREELIST_ENTRY *ent; + + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + list = for_read ? ctx->rbuf_freelist : ctx->wbuf_freelist; + if (list != NULL && + (sz == list->chunklen || list->chunklen == 0) && + list->len < ctx->freelist_max_len && sz >= sizeof(*ent)) { + list->chunklen = sz; + ent = mem; + ent->next = list->head; + list->head = ent; + ++list->len; + mem = NULL; + } + + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + if (mem) + OPENSSL_free(mem); +} +#else +# define freelist_extract(c,fr,sz) OPENSSL_malloc(sz) +# define freelist_insert(c,fr,sz,m) OPENSSL_free(m) +#endif + +int ssl3_setup_read_buffer(SSL *s) +{ + unsigned char *p; + size_t len, align = 0, headerlen; + + if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) + headerlen = DTLS1_RT_HEADER_LENGTH; + else + headerlen = SSL3_RT_HEADER_LENGTH; + +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 + align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); +#endif + + if (s->s3->rbuf.buf == NULL) { + len = SSL3_RT_MAX_PLAIN_LENGTH + + SSL3_RT_MAX_ENCRYPTED_OVERHEAD + headerlen + align; + if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) { + s->s3->init_extra = 1; + len += SSL3_RT_MAX_EXTRA; + } +#ifndef OPENSSL_NO_COMP + if (!(s->options & SSL_OP_NO_COMPRESSION)) + len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; +#endif + if ((p = freelist_extract(s->ctx, 1, len)) == NULL) + goto err; + s->s3->rbuf.buf = p; + s->s3->rbuf.len = len; + } + + s->packet = &(s->s3->rbuf.buf[0]); + return 1; + + err: + SSLerr(SSL_F_SSL3_SETUP_READ_BUFFER, ERR_R_MALLOC_FAILURE); + return 0; +} + +int ssl3_setup_write_buffer(SSL *s) +{ + unsigned char *p; + size_t len, align = 0, headerlen; + + if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) + headerlen = DTLS1_RT_HEADER_LENGTH + 1; + else + headerlen = SSL3_RT_HEADER_LENGTH; + +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 + align = (-SSL3_RT_HEADER_LENGTH) & (SSL3_ALIGN_PAYLOAD - 1); +#endif + + if (s->s3->wbuf.buf == NULL) { + len = s->max_send_fragment + + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + headerlen + align; +#ifndef OPENSSL_NO_COMP + if (!(s->options & SSL_OP_NO_COMPRESSION)) + len += SSL3_RT_MAX_COMPRESSED_OVERHEAD; +#endif + if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) + len += headerlen + align + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD; + + if ((p = freelist_extract(s->ctx, 0, len)) == NULL) + goto err; + s->s3->wbuf.buf = p; + s->s3->wbuf.len = len; + } + + return 1; + + err: + SSLerr(SSL_F_SSL3_SETUP_WRITE_BUFFER, ERR_R_MALLOC_FAILURE); + return 0; +} + +int ssl3_setup_buffers(SSL *s) +{ + if (!ssl3_setup_read_buffer(s)) + return 0; + if (!ssl3_setup_write_buffer(s)) + return 0; + return 1; +} + +int ssl3_release_write_buffer(SSL *s) +{ + if (s->s3->wbuf.buf != NULL) { + freelist_insert(s->ctx, 0, s->s3->wbuf.len, s->s3->wbuf.buf); + s->s3->wbuf.buf = NULL; + } + return 1; +} + +int ssl3_release_read_buffer(SSL *s) +{ + if (s->s3->rbuf.buf != NULL) { + freelist_insert(s->ctx, 1, s->s3->rbuf.len, s->s3->rbuf.buf); + s->s3->rbuf.buf = NULL; + } + return 1; +} diff --git a/libs/openssl/ssl/s3_cbc.c b/libs/openssl/ssl/s3_cbc.c new file mode 100644 index 00000000..b3bff743 --- /dev/null +++ b/libs/openssl/ssl/s3_cbc.c @@ -0,0 +1,820 @@ +/* ssl/s3_cbc.c */ +/* ==================================================================== + * Copyright (c) 2012 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include "../crypto/constant_time_locl.h" +#include "ssl_locl.h" + +#include +#include + +/* + * MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's + * length field. (SHA-384/512 have 128-bit length.) + */ +#define MAX_HASH_BIT_COUNT_BYTES 16 + +/* + * MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support. + * Currently SHA-384/512 has a 128-byte block size and that's the largest + * supported by TLS.) + */ +#define MAX_HASH_BLOCK_SIZE 128 + +/*- + * ssl3_cbc_remove_padding removes padding from the decrypted, SSLv3, CBC + * record in |rec| by updating |rec->length| in constant time. + * + * block_size: the block size of the cipher used to encrypt the record. + * returns: + * 0: (in non-constant time) if the record is publicly invalid. + * 1: if the padding was valid + * -1: otherwise. + */ +int ssl3_cbc_remove_padding(const SSL *s, + SSL3_RECORD *rec, + unsigned block_size, unsigned mac_size) +{ + unsigned padding_length, good; + const unsigned overhead = 1 /* padding length byte */ + mac_size; + + /* + * These lengths are all public so we can test them in non-constant time. + */ + if (overhead > rec->length) + return 0; + + padding_length = rec->data[rec->length - 1]; + good = constant_time_ge(rec->length, padding_length + overhead); + /* SSLv3 requires that the padding is minimal. */ + good &= constant_time_ge(block_size, padding_length + 1); + padding_length = good & (padding_length + 1); + rec->length -= padding_length; + rec->type |= padding_length << 8; /* kludge: pass padding length */ + return constant_time_select_int(good, 1, -1); +} + +/*- + * tls1_cbc_remove_padding removes the CBC padding from the decrypted, TLS, CBC + * record in |rec| in constant time and returns 1 if the padding is valid and + * -1 otherwise. It also removes any explicit IV from the start of the record + * without leaking any timing about whether there was enough space after the + * padding was removed. + * + * block_size: the block size of the cipher used to encrypt the record. + * returns: + * 0: (in non-constant time) if the record is publicly invalid. + * 1: if the padding was valid + * -1: otherwise. + */ +int tls1_cbc_remove_padding(const SSL *s, + SSL3_RECORD *rec, + unsigned block_size, unsigned mac_size) +{ + unsigned padding_length, good, to_check, i; + const unsigned overhead = 1 /* padding length byte */ + mac_size; + /* Check if version requires explicit IV */ + if (s->version >= TLS1_1_VERSION || s->version == DTLS1_BAD_VER) { + /* + * These lengths are all public so we can test them in non-constant + * time. + */ + if (overhead + block_size > rec->length) + return 0; + /* We can now safely skip explicit IV */ + rec->data += block_size; + rec->input += block_size; + rec->length -= block_size; + } else if (overhead > rec->length) + return 0; + + padding_length = rec->data[rec->length - 1]; + + /* + * NB: if compression is in operation the first packet may not be of even + * length so the padding bug check cannot be performed. This bug + * workaround has been around since SSLeay so hopefully it is either + * fixed now or no buggy implementation supports compression [steve] + */ + if ((s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) && !s->expand) { + /* First packet is even in size, so check */ + if ((CRYPTO_memcmp(s->s3->read_sequence, "\0\0\0\0\0\0\0\0", 8) == 0) && + !(padding_length & 1)) { + s->s3->flags |= TLS1_FLAGS_TLS_PADDING_BUG; + } + if ((s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) && padding_length > 0) { + padding_length--; + } + } + + if (EVP_CIPHER_flags(s->enc_read_ctx->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { + /* padding is already verified */ + rec->length -= padding_length + 1; + return 1; + } + + good = constant_time_ge(rec->length, overhead + padding_length); + /* + * The padding consists of a length byte at the end of the record and + * then that many bytes of padding, all with the same value as the length + * byte. Thus, with the length byte included, there are i+1 bytes of + * padding. We can't check just |padding_length+1| bytes because that + * leaks decrypted information. Therefore we always have to check the + * maximum amount of padding possible. (Again, the length of the record + * is public information so we can use it.) + */ + to_check = 255; /* maximum amount of padding. */ + if (to_check > rec->length - 1) + to_check = rec->length - 1; + + for (i = 0; i < to_check; i++) { + unsigned char mask = constant_time_ge_8(padding_length, i); + unsigned char b = rec->data[rec->length - 1 - i]; + /* + * The final |padding_length+1| bytes should all have the value + * |padding_length|. Therefore the XOR should be zero. + */ + good &= ~(mask & (padding_length ^ b)); + } + + /* + * If any of the final |padding_length+1| bytes had the wrong value, one + * or more of the lower eight bits of |good| will be cleared. + */ + good = constant_time_eq(0xff, good & 0xff); + padding_length = good & (padding_length + 1); + rec->length -= padding_length; + rec->type |= padding_length << 8; /* kludge: pass padding length */ + + return constant_time_select_int(good, 1, -1); +} + +/*- + * ssl3_cbc_copy_mac copies |md_size| bytes from the end of |rec| to |out| in + * constant time (independent of the concrete value of rec->length, which may + * vary within a 256-byte window). + * + * ssl3_cbc_remove_padding or tls1_cbc_remove_padding must be called prior to + * this function. + * + * On entry: + * rec->orig_len >= md_size + * md_size <= EVP_MAX_MD_SIZE + * + * If CBC_MAC_ROTATE_IN_PLACE is defined then the rotation is performed with + * variable accesses in a 64-byte-aligned buffer. Assuming that this fits into + * a single or pair of cache-lines, then the variable memory accesses don't + * actually affect the timing. CPUs with smaller cache-lines [if any] are + * not multi-core and are not considered vulnerable to cache-timing attacks. + */ +#define CBC_MAC_ROTATE_IN_PLACE + +void ssl3_cbc_copy_mac(unsigned char *out, + const SSL3_RECORD *rec, + unsigned md_size, unsigned orig_len) +{ +#if defined(CBC_MAC_ROTATE_IN_PLACE) + unsigned char rotated_mac_buf[64 + EVP_MAX_MD_SIZE]; + unsigned char *rotated_mac; +#else + unsigned char rotated_mac[EVP_MAX_MD_SIZE]; +#endif + + /* + * mac_end is the index of |rec->data| just after the end of the MAC. + */ + unsigned mac_end = rec->length; + unsigned mac_start = mac_end - md_size; + /* + * scan_start contains the number of bytes that we can ignore because the + * MAC's position can only vary by 255 bytes. + */ + unsigned scan_start = 0; + unsigned i, j; + unsigned div_spoiler; + unsigned rotate_offset; + + OPENSSL_assert(orig_len >= md_size); + OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); + +#if defined(CBC_MAC_ROTATE_IN_PLACE) + rotated_mac = rotated_mac_buf + ((0 - (size_t)rotated_mac_buf) & 63); +#endif + + /* This information is public so it's safe to branch based on it. */ + if (orig_len > md_size + 255 + 1) + scan_start = orig_len - (md_size + 255 + 1); + /* + * div_spoiler contains a multiple of md_size that is used to cause the + * modulo operation to be constant time. Without this, the time varies + * based on the amount of padding when running on Intel chips at least. + * The aim of right-shifting md_size is so that the compiler doesn't + * figure out that it can remove div_spoiler as that would require it to + * prove that md_size is always even, which I hope is beyond it. + */ + div_spoiler = md_size >> 1; + div_spoiler <<= (sizeof(div_spoiler) - 1) * 8; + rotate_offset = (div_spoiler + mac_start - scan_start) % md_size; + + memset(rotated_mac, 0, md_size); + for (i = scan_start, j = 0; i < orig_len; i++) { + unsigned char mac_started = constant_time_ge_8(i, mac_start); + unsigned char mac_ended = constant_time_ge_8(i, mac_end); + unsigned char b = rec->data[i]; + rotated_mac[j++] |= b & mac_started & ~mac_ended; + j &= constant_time_lt(j, md_size); + } + + /* Now rotate the MAC */ +#if defined(CBC_MAC_ROTATE_IN_PLACE) + j = 0; + for (i = 0; i < md_size; i++) { + /* in case cache-line is 32 bytes, touch second line */ + ((volatile unsigned char *)rotated_mac)[rotate_offset ^ 32]; + out[j++] = rotated_mac[rotate_offset++]; + rotate_offset &= constant_time_lt(rotate_offset, md_size); + } +#else + memset(out, 0, md_size); + rotate_offset = md_size - rotate_offset; + rotate_offset &= constant_time_lt(rotate_offset, md_size); + for (i = 0; i < md_size; i++) { + for (j = 0; j < md_size; j++) + out[j] |= rotated_mac[i] & constant_time_eq_8(j, rotate_offset); + rotate_offset++; + rotate_offset &= constant_time_lt(rotate_offset, md_size); + } +#endif +} + +/* + * u32toLE serialises an unsigned, 32-bit number (n) as four bytes at (p) in + * little-endian order. The value of p is advanced by four. + */ +#define u32toLE(n, p) \ + (*((p)++)=(unsigned char)(n), \ + *((p)++)=(unsigned char)(n>>8), \ + *((p)++)=(unsigned char)(n>>16), \ + *((p)++)=(unsigned char)(n>>24)) + +/* + * These functions serialize the state of a hash and thus perform the + * standard "final" operation without adding the padding and length that such + * a function typically does. + */ +static void tls1_md5_final_raw(void *ctx, unsigned char *md_out) +{ + MD5_CTX *md5 = ctx; + u32toLE(md5->A, md_out); + u32toLE(md5->B, md_out); + u32toLE(md5->C, md_out); + u32toLE(md5->D, md_out); +} + +static void tls1_sha1_final_raw(void *ctx, unsigned char *md_out) +{ + SHA_CTX *sha1 = ctx; + l2n(sha1->h0, md_out); + l2n(sha1->h1, md_out); + l2n(sha1->h2, md_out); + l2n(sha1->h3, md_out); + l2n(sha1->h4, md_out); +} + +#define LARGEST_DIGEST_CTX SHA_CTX + +#ifndef OPENSSL_NO_SHA256 +static void tls1_sha256_final_raw(void *ctx, unsigned char *md_out) +{ + SHA256_CTX *sha256 = ctx; + unsigned i; + + for (i = 0; i < 8; i++) { + l2n(sha256->h[i], md_out); + } +} + +# undef LARGEST_DIGEST_CTX +# define LARGEST_DIGEST_CTX SHA256_CTX +#endif + +#ifndef OPENSSL_NO_SHA512 +static void tls1_sha512_final_raw(void *ctx, unsigned char *md_out) +{ + SHA512_CTX *sha512 = ctx; + unsigned i; + + for (i = 0; i < 8; i++) { + l2n8(sha512->h[i], md_out); + } +} + +# undef LARGEST_DIGEST_CTX +# define LARGEST_DIGEST_CTX SHA512_CTX +#endif + +/* + * ssl3_cbc_record_digest_supported returns 1 iff |ctx| uses a hash function + * which ssl3_cbc_digest_record supports. + */ +char ssl3_cbc_record_digest_supported(const EVP_MD_CTX *ctx) +{ +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return 0; +#endif + switch (EVP_MD_CTX_type(ctx)) { + case NID_md5: + case NID_sha1: +#ifndef OPENSSL_NO_SHA256 + case NID_sha224: + case NID_sha256: +#endif +#ifndef OPENSSL_NO_SHA512 + case NID_sha384: + case NID_sha512: +#endif + return 1; + default: + return 0; + } +} + +/*- + * ssl3_cbc_digest_record computes the MAC of a decrypted, padded SSLv3/TLS + * record. + * + * ctx: the EVP_MD_CTX from which we take the hash function. + * ssl3_cbc_record_digest_supported must return true for this EVP_MD_CTX. + * md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written. + * md_out_size: if non-NULL, the number of output bytes is written here. + * header: the 13-byte, TLS record header. + * data: the record data itself, less any preceeding explicit IV. + * data_plus_mac_size: the secret, reported length of the data and MAC + * once the padding has been removed. + * data_plus_mac_plus_padding_size: the public length of the whole + * record, including padding. + * is_sslv3: non-zero if we are to use SSLv3. Otherwise, TLS. + * + * On entry: by virtue of having been through one of the remove_padding + * functions, above, we know that data_plus_mac_size is large enough to contain + * a padding byte and MAC. (If the padding was invalid, it might contain the + * padding too. ) + * Returns 1 on success or 0 on error + */ +int ssl3_cbc_digest_record(const EVP_MD_CTX *ctx, + unsigned char *md_out, + size_t *md_out_size, + const unsigned char header[13], + const unsigned char *data, + size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const unsigned char *mac_secret, + unsigned mac_secret_length, char is_sslv3) +{ + union { + double align; + unsigned char c[sizeof(LARGEST_DIGEST_CTX)]; + } md_state; + void (*md_final_raw) (void *ctx, unsigned char *md_out); + void (*md_transform) (void *ctx, const unsigned char *block); + unsigned md_size, md_block_size = 64; + unsigned sslv3_pad_length = 40, header_length, variance_blocks, + len, max_mac_bytes, num_blocks, + num_starting_blocks, k, mac_end_offset, c, index_a, index_b; + unsigned int bits; /* at most 18 bits */ + unsigned char length_bytes[MAX_HASH_BIT_COUNT_BYTES]; + /* hmac_pad is the masked HMAC key. */ + unsigned char hmac_pad[MAX_HASH_BLOCK_SIZE]; + unsigned char first_block[MAX_HASH_BLOCK_SIZE]; + unsigned char mac_out[EVP_MAX_MD_SIZE]; + unsigned i, j, md_out_size_u; + EVP_MD_CTX md_ctx; + /* + * mdLengthSize is the number of bytes in the length field that + * terminates * the hash. + */ + unsigned md_length_size = 8; + char length_is_big_endian = 1; + + /* + * This is a, hopefully redundant, check that allows us to forget about + * many possible overflows later in this function. + */ + OPENSSL_assert(data_plus_mac_plus_padding_size < 1024 * 1024); + + switch (EVP_MD_CTX_type(ctx)) { + case NID_md5: + if (MD5_Init((MD5_CTX *)md_state.c) <= 0) + return 0; + md_final_raw = tls1_md5_final_raw; + md_transform = + (void (*)(void *ctx, const unsigned char *block))MD5_Transform; + md_size = 16; + sslv3_pad_length = 48; + length_is_big_endian = 0; + break; + case NID_sha1: + if (SHA1_Init((SHA_CTX *)md_state.c) <= 0) + return 0; + md_final_raw = tls1_sha1_final_raw; + md_transform = + (void (*)(void *ctx, const unsigned char *block))SHA1_Transform; + md_size = 20; + break; +#ifndef OPENSSL_NO_SHA256 + case NID_sha224: + if (SHA224_Init((SHA256_CTX *)md_state.c) <= 0) + return 0; + md_final_raw = tls1_sha256_final_raw; + md_transform = + (void (*)(void *ctx, const unsigned char *block))SHA256_Transform; + md_size = 224 / 8; + break; + case NID_sha256: + if (SHA256_Init((SHA256_CTX *)md_state.c) <= 0) + return 0; + md_final_raw = tls1_sha256_final_raw; + md_transform = + (void (*)(void *ctx, const unsigned char *block))SHA256_Transform; + md_size = 32; + break; +#endif +#ifndef OPENSSL_NO_SHA512 + case NID_sha384: + if (SHA384_Init((SHA512_CTX *)md_state.c) <= 0) + return 0; + md_final_raw = tls1_sha512_final_raw; + md_transform = + (void (*)(void *ctx, const unsigned char *block))SHA512_Transform; + md_size = 384 / 8; + md_block_size = 128; + md_length_size = 16; + break; + case NID_sha512: + if (SHA512_Init((SHA512_CTX *)md_state.c) <= 0) + return 0; + md_final_raw = tls1_sha512_final_raw; + md_transform = + (void (*)(void *ctx, const unsigned char *block))SHA512_Transform; + md_size = 64; + md_block_size = 128; + md_length_size = 16; + break; +#endif + default: + /* + * ssl3_cbc_record_digest_supported should have been called first to + * check that the hash function is supported. + */ + OPENSSL_assert(0); + if (md_out_size) + *md_out_size = -1; + return 0; + } + + OPENSSL_assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); + OPENSSL_assert(md_block_size <= MAX_HASH_BLOCK_SIZE); + OPENSSL_assert(md_size <= EVP_MAX_MD_SIZE); + + header_length = 13; + if (is_sslv3) { + header_length = mac_secret_length + sslv3_pad_length + 8 /* sequence + * number */ + + 1 /* record type */ + + 2 /* record length */ ; + } + + /* + * variance_blocks is the number of blocks of the hash that we have to + * calculate in constant time because they could be altered by the + * padding value. In SSLv3, the padding must be minimal so the end of + * the plaintext varies by, at most, 15+20 = 35 bytes. (We conservatively + * assume that the MAC size varies from 0..20 bytes.) In case the 9 bytes + * of hash termination (0x80 + 64-bit length) don't fit in the final + * block, we say that the final two blocks can vary based on the padding. + * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not + * required to be minimal. Therefore we say that the final six blocks can + * vary based on the padding. Later in the function, if the message is + * short and there obviously cannot be this many blocks then + * variance_blocks can be reduced. + */ + variance_blocks = is_sslv3 ? 2 : 6; + /* + * From now on we're dealing with the MAC, which conceptually has 13 + * bytes of `header' before the start of the data (TLS) or 71/75 bytes + * (SSLv3) + */ + len = data_plus_mac_plus_padding_size + header_length; + /* + * max_mac_bytes contains the maximum bytes of bytes in the MAC, + * including * |header|, assuming that there's no padding. + */ + max_mac_bytes = len - md_size - 1; + /* num_blocks is the maximum number of hash blocks. */ + num_blocks = + (max_mac_bytes + 1 + md_length_size + md_block_size - + 1) / md_block_size; + /* + * In order to calculate the MAC in constant time we have to handle the + * final blocks specially because the padding value could cause the end + * to appear somewhere in the final |variance_blocks| blocks and we can't + * leak where. However, |num_starting_blocks| worth of data can be hashed + * right away because no padding value can affect whether they are + * plaintext. + */ + num_starting_blocks = 0; + /* + * k is the starting byte offset into the conceptual header||data where + * we start processing. + */ + k = 0; + /* + * mac_end_offset is the index just past the end of the data to be MACed. + */ + mac_end_offset = data_plus_mac_size + header_length - md_size; + /* + * c is the index of the 0x80 byte in the final hash block that contains + * application data. + */ + c = mac_end_offset % md_block_size; + /* + * index_a is the hash block number that contains the 0x80 terminating + * value. + */ + index_a = mac_end_offset / md_block_size; + /* + * index_b is the hash block number that contains the 64-bit hash length, + * in bits. + */ + index_b = (mac_end_offset + md_length_size) / md_block_size; + /* + * bits is the hash-length in bits. It includes the additional hash block + * for the masked HMAC key, or whole of |header| in the case of SSLv3. + */ + + /* + * For SSLv3, if we're going to have any starting blocks then we need at + * least two because the header is larger than a single block. + */ + if (num_blocks > variance_blocks + (is_sslv3 ? 1 : 0)) { + num_starting_blocks = num_blocks - variance_blocks; + k = md_block_size * num_starting_blocks; + } + + bits = 8 * mac_end_offset; + if (!is_sslv3) { + /* + * Compute the initial HMAC block. For SSLv3, the padding and secret + * bytes are included in |header| because they take more than a + * single block. + */ + bits += 8 * md_block_size; + memset(hmac_pad, 0, md_block_size); + OPENSSL_assert(mac_secret_length <= sizeof(hmac_pad)); + memcpy(hmac_pad, mac_secret, mac_secret_length); + for (i = 0; i < md_block_size; i++) + hmac_pad[i] ^= 0x36; + + md_transform(md_state.c, hmac_pad); + } + + if (length_is_big_endian) { + memset(length_bytes, 0, md_length_size - 4); + length_bytes[md_length_size - 4] = (unsigned char)(bits >> 24); + length_bytes[md_length_size - 3] = (unsigned char)(bits >> 16); + length_bytes[md_length_size - 2] = (unsigned char)(bits >> 8); + length_bytes[md_length_size - 1] = (unsigned char)bits; + } else { + memset(length_bytes, 0, md_length_size); + length_bytes[md_length_size - 5] = (unsigned char)(bits >> 24); + length_bytes[md_length_size - 6] = (unsigned char)(bits >> 16); + length_bytes[md_length_size - 7] = (unsigned char)(bits >> 8); + length_bytes[md_length_size - 8] = (unsigned char)bits; + } + + if (k > 0) { + if (is_sslv3) { + unsigned overhang; + + /* + * The SSLv3 header is larger than a single block. overhang is + * the number of bytes beyond a single block that the header + * consumes: either 7 bytes (SHA1) or 11 bytes (MD5). There are no + * ciphersuites in SSLv3 that are not SHA1 or MD5 based and + * therefore we can be confident that the header_length will be + * greater than |md_block_size|. However we add a sanity check just + * in case + */ + if (header_length <= md_block_size) { + /* Should never happen */ + return 0; + } + overhang = header_length - md_block_size; + md_transform(md_state.c, header); + memcpy(first_block, header + md_block_size, overhang); + memcpy(first_block + overhang, data, md_block_size - overhang); + md_transform(md_state.c, first_block); + for (i = 1; i < k / md_block_size - 1; i++) + md_transform(md_state.c, data + md_block_size * i - overhang); + } else { + /* k is a multiple of md_block_size. */ + memcpy(first_block, header, 13); + memcpy(first_block + 13, data, md_block_size - 13); + md_transform(md_state.c, first_block); + for (i = 1; i < k / md_block_size; i++) + md_transform(md_state.c, data + md_block_size * i - 13); + } + } + + memset(mac_out, 0, sizeof(mac_out)); + + /* + * We now process the final hash blocks. For each block, we construct it + * in constant time. If the |i==index_a| then we'll include the 0x80 + * bytes and zero pad etc. For each block we selectively copy it, in + * constant time, to |mac_out|. + */ + for (i = num_starting_blocks; i <= num_starting_blocks + variance_blocks; + i++) { + unsigned char block[MAX_HASH_BLOCK_SIZE]; + unsigned char is_block_a = constant_time_eq_8(i, index_a); + unsigned char is_block_b = constant_time_eq_8(i, index_b); + for (j = 0; j < md_block_size; j++) { + unsigned char b = 0, is_past_c, is_past_cp1; + if (k < header_length) + b = header[k]; + else if (k < data_plus_mac_plus_padding_size + header_length) + b = data[k - header_length]; + k++; + + is_past_c = is_block_a & constant_time_ge_8(j, c); + is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1); + /* + * If this is the block containing the end of the application + * data, and we are at the offset for the 0x80 value, then + * overwrite b with 0x80. + */ + b = constant_time_select_8(is_past_c, 0x80, b); + /* + * If this the the block containing the end of the application + * data and we're past the 0x80 value then just write zero. + */ + b = b & ~is_past_cp1; + /* + * If this is index_b (the final block), but not index_a (the end + * of the data), then the 64-bit length didn't fit into index_a + * and we're having to add an extra block of zeros. + */ + b &= ~is_block_b | is_block_a; + + /* + * The final bytes of one of the blocks contains the length. + */ + if (j >= md_block_size - md_length_size) { + /* If this is index_b, write a length byte. */ + b = constant_time_select_8(is_block_b, + length_bytes[j - + (md_block_size - + md_length_size)], b); + } + block[j] = b; + } + + md_transform(md_state.c, block); + md_final_raw(md_state.c, block); + /* If this is index_b, copy the hash value to |mac_out|. */ + for (j = 0; j < md_size; j++) + mac_out[j] |= block[j] & is_block_b; + } + + EVP_MD_CTX_init(&md_ctx); + if (EVP_DigestInit_ex(&md_ctx, ctx->digest, NULL /* engine */ ) <= 0) + goto err; + if (is_sslv3) { + /* We repurpose |hmac_pad| to contain the SSLv3 pad2 block. */ + memset(hmac_pad, 0x5c, sslv3_pad_length); + + if (EVP_DigestUpdate(&md_ctx, mac_secret, mac_secret_length) <= 0 + || EVP_DigestUpdate(&md_ctx, hmac_pad, sslv3_pad_length) <= 0 + || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0) + goto err; + } else { + /* Complete the HMAC in the standard manner. */ + for (i = 0; i < md_block_size; i++) + hmac_pad[i] ^= 0x6a; + + if (EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size) <= 0 + || EVP_DigestUpdate(&md_ctx, mac_out, md_size) <= 0) + goto err; + } + EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); + if (md_out_size) + *md_out_size = md_out_size_u; + EVP_MD_CTX_cleanup(&md_ctx); + + return 1; +err: + EVP_MD_CTX_cleanup(&md_ctx); + return 0; +} + +#ifdef OPENSSL_FIPS + +/* + * Due to the need to use EVP in FIPS mode we can't reimplement digests but + * we can ensure the number of blocks processed is equal for all cases by + * digesting additional data. + */ + +void tls_fips_digest_extra(const EVP_CIPHER_CTX *cipher_ctx, + EVP_MD_CTX *mac_ctx, const unsigned char *data, + size_t data_len, size_t orig_len) +{ + size_t block_size, digest_pad, blocks_data, blocks_orig; + if (EVP_CIPHER_CTX_mode(cipher_ctx) != EVP_CIPH_CBC_MODE) + return; + block_size = EVP_MD_CTX_block_size(mac_ctx); + /*- + * We are in FIPS mode if we get this far so we know we have only SHA* + * digests and TLS to deal with. + * Minimum digest padding length is 17 for SHA384/SHA512 and 9 + * otherwise. + * Additional header is 13 bytes. To get the number of digest blocks + * processed round up the amount of data plus padding to the nearest + * block length. Block length is 128 for SHA384/SHA512 and 64 otherwise. + * So we have: + * blocks = (payload_len + digest_pad + 13 + block_size - 1)/block_size + * equivalently: + * blocks = (payload_len + digest_pad + 12)/block_size + 1 + * HMAC adds a constant overhead. + * We're ultimately only interested in differences so this becomes + * blocks = (payload_len + 29)/128 + * for SHA384/SHA512 and + * blocks = (payload_len + 21)/64 + * otherwise. + */ + digest_pad = block_size == 64 ? 21 : 29; + blocks_orig = (orig_len + digest_pad) / block_size; + blocks_data = (data_len + digest_pad) / block_size; + /* + * MAC enough blocks to make up the difference between the original and + * actual lengths plus one extra block to ensure this is never a no op. + * The "data" pointer should always have enough space to perform this + * operation as it is large enough for a maximum length TLS buffer. + */ + EVP_DigestSignUpdate(mac_ctx, data, + (blocks_orig - blocks_data + 1) * block_size); +} +#endif diff --git a/libs/openssl/ssl/s3_clnt.c b/libs/openssl/ssl/s3_clnt.c new file mode 100644 index 00000000..9e5875f1 --- /dev/null +++ b/libs/openssl/ssl/s3_clnt.c @@ -0,0 +1,3570 @@ +/* ssl/s3_clnt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include "ssl_locl.h" +#include "kssl_lcl.h" +#include +#include +#include +#include +#include +#ifdef OPENSSL_FIPS +# include +#endif +#ifndef OPENSSL_NO_DH +# include +#endif +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif + +static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b); +#ifndef OPENSSL_NO_TLSEXT +static int ssl3_check_finished(SSL *s); +#endif + +#ifndef OPENSSL_NO_SSL3_METHOD +static const SSL_METHOD *ssl3_get_client_method(int ver) +{ + if (ver == SSL3_VERSION) + return (SSLv3_client_method()); + else + return (NULL); +} + +IMPLEMENT_ssl3_meth_func(SSLv3_client_method, + ssl_undefined_function, + ssl3_connect, ssl3_get_client_method) +#endif +int ssl3_connect(SSL *s) +{ + BUF_MEM *buf = NULL; + unsigned long Time = (unsigned long)time(NULL); + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state, skip = 0; + + RAND_add(&Time, sizeof(Time), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + +#ifndef OPENSSL_NO_HEARTBEATS + /* + * If we're awaiting a HeartbeatResponse, pretend we already got and + * don't await it anymore, because Heartbeats don't make sense during + * handshakes anyway. + */ + if (s->tlsext_hb_pending) { + s->tlsext_hb_pending = 0; + s->tlsext_hb_seq++; + } +#endif + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_RENEGOTIATE: + s->renegotiate = 1; + s->state = SSL_ST_CONNECT; + s->ctx->stats.sess_connect_renegotiate++; + /* break */ + case SSL_ST_BEFORE: + case SSL_ST_CONNECT: + case SSL_ST_BEFORE | SSL_ST_CONNECT: + case SSL_ST_OK | SSL_ST_CONNECT: + + s->server = 0; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + if ((s->version & 0xff00) != 0x0300) { + SSLerr(SSL_F_SSL3_CONNECT, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + ret = -1; + goto end; + } + + /* s->version=SSL3_VERSION; */ + s->type = SSL_ST_CONNECT; + + if (s->init_buf == NULL) { + if ((buf = BUF_MEM_new()) == NULL) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + s->init_buf = buf; + buf = NULL; + } + + if (!ssl3_setup_buffers(s)) { + ret = -1; + goto end; + } + + /* setup buffing BIO */ + if (!ssl_init_wbio_buffer(s, 0)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + /* don't push the buffering BIO quite yet */ + + ssl3_init_finished_mac(s); + + s->state = SSL3_ST_CW_CLNT_HELLO_A; + s->ctx->stats.sess_connect++; + s->init_num = 0; + s->s3->flags &= ~SSL3_FLAGS_CCS_OK; + /* + * Should have been reset by ssl3_get_finished, too. + */ + s->s3->change_cipher_spec = 0; + break; + + case SSL3_ST_CW_CLNT_HELLO_A: + case SSL3_ST_CW_CLNT_HELLO_B: + + s->shutdown = 0; + ret = ssl3_client_hello(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_SRVR_HELLO_A; + s->init_num = 0; + + /* turn on buffering for the next lot of output */ + if (s->bbio != s->wbio) + s->wbio = BIO_push(s->bbio, s->wbio); + + break; + + case SSL3_ST_CR_SRVR_HELLO_A: + case SSL3_ST_CR_SRVR_HELLO_B: + ret = ssl3_get_server_hello(s); + if (ret <= 0) + goto end; + + if (s->hit) { + s->state = SSL3_ST_CR_FINISHED_A; +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_ticket_expected) { + /* receive renewed session ticket */ + s->state = SSL3_ST_CR_SESSION_TICKET_A; + } +#endif + } else + s->state = SSL3_ST_CR_CERT_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_CERT_A: + case SSL3_ST_CR_CERT_B: +#ifndef OPENSSL_NO_TLSEXT + /* Noop (ret = 0) for everything but EAP-FAST. */ + ret = ssl3_check_finished(s); + if (ret < 0) + goto end; + if (ret == 1) { + s->hit = 1; + s->state = SSL3_ST_CR_FINISHED_A; + s->init_num = 0; + break; + } +#endif + /* Check if it is anon DH/ECDH, SRP auth */ + /* or PSK */ + if (! + (s->s3->tmp. + new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + ret = ssl3_get_server_certificate(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_status_expected) + s->state = SSL3_ST_CR_CERT_STATUS_A; + else + s->state = SSL3_ST_CR_KEY_EXCH_A; + } else { + skip = 1; + s->state = SSL3_ST_CR_KEY_EXCH_A; + } +#else + } else + skip = 1; + + s->state = SSL3_ST_CR_KEY_EXCH_A; +#endif + s->init_num = 0; + break; + + case SSL3_ST_CR_KEY_EXCH_A: + case SSL3_ST_CR_KEY_EXCH_B: + ret = ssl3_get_key_exchange(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_CERT_REQ_A; + s->init_num = 0; + + /* + * at this point we check that we have the required stuff from + * the server + */ + if (!ssl3_check_cert_and_algorithm(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + break; + + case SSL3_ST_CR_CERT_REQ_A: + case SSL3_ST_CR_CERT_REQ_B: + ret = ssl3_get_certificate_request(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_SRVR_DONE_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_SRVR_DONE_A: + case SSL3_ST_CR_SRVR_DONE_B: + ret = ssl3_get_server_done(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_SRP + if (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) { + if ((ret = SRP_Calc_A_param(s)) <= 0) { + SSLerr(SSL_F_SSL3_CONNECT, SSL_R_SRP_A_CALC); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + goto end; + } + } +#endif + if (s->s3->tmp.cert_req) + s->state = SSL3_ST_CW_CERT_A; + else + s->state = SSL3_ST_CW_KEY_EXCH_A; + s->init_num = 0; + + break; + + case SSL3_ST_CW_CERT_A: + case SSL3_ST_CW_CERT_B: + case SSL3_ST_CW_CERT_C: + case SSL3_ST_CW_CERT_D: + ret = ssl3_send_client_certificate(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_KEY_EXCH_A; + s->init_num = 0; + break; + + case SSL3_ST_CW_KEY_EXCH_A: + case SSL3_ST_CW_KEY_EXCH_B: + ret = ssl3_send_client_key_exchange(s); + if (ret <= 0) + goto end; + /* + * EAY EAY EAY need to check for DH fix cert sent back + */ + /* + * For TLS, cert_req is set to 2, so a cert chain of nothing is + * sent, but no verify packet is sent + */ + /* + * XXX: For now, we do not support client authentication in ECDH + * cipher suites with ECDH (rather than ECDSA) certificates. We + * need to skip the certificate verify message when client's + * ECDH public key is sent inside the client certificate. + */ + if (s->s3->tmp.cert_req == 1) { + s->state = SSL3_ST_CW_CERT_VRFY_A; + } else { + s->state = SSL3_ST_CW_CHANGE_A; + } + if (s->s3->flags & TLS1_FLAGS_SKIP_CERT_VERIFY) { + s->state = SSL3_ST_CW_CHANGE_A; + } + + s->init_num = 0; + break; + + case SSL3_ST_CW_CERT_VRFY_A: + case SSL3_ST_CW_CERT_VRFY_B: + ret = ssl3_send_client_verify(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_CHANGE_A; + s->init_num = 0; + break; + + case SSL3_ST_CW_CHANGE_A: + case SSL3_ST_CW_CHANGE_B: + ret = ssl3_send_change_cipher_spec(s, + SSL3_ST_CW_CHANGE_A, + SSL3_ST_CW_CHANGE_B); + if (ret <= 0) + goto end; + +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) + s->state = SSL3_ST_CW_FINISHED_A; +#else + if (s->s3->next_proto_neg_seen) + s->state = SSL3_ST_CW_NEXT_PROTO_A; + else + s->state = SSL3_ST_CW_FINISHED_A; +#endif + s->init_num = 0; + + s->session->cipher = s->s3->tmp.new_cipher; +#ifdef OPENSSL_NO_COMP + s->session->compress_meth = 0; +#else + if (s->s3->tmp.new_compression == NULL) + s->session->compress_meth = 0; + else + s->session->compress_meth = s->s3->tmp.new_compression->id; +#endif + if (!s->method->ssl3_enc->setup_key_block(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + if (!s->method->ssl3_enc->change_cipher_state(s, + SSL3_CHANGE_CIPHER_CLIENT_WRITE)) + { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + break; + +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) + case SSL3_ST_CW_NEXT_PROTO_A: + case SSL3_ST_CW_NEXT_PROTO_B: + ret = ssl3_send_next_proto(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_FINISHED_A; + break; +#endif + + case SSL3_ST_CW_FINISHED_A: + case SSL3_ST_CW_FINISHED_B: + ret = ssl3_send_finished(s, + SSL3_ST_CW_FINISHED_A, + SSL3_ST_CW_FINISHED_B, + s->method-> + ssl3_enc->client_finished_label, + s->method-> + ssl3_enc->client_finished_label_len); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CW_FLUSH; + + /* clear flags */ + s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; + if (s->hit) { + s->s3->tmp.next_state = SSL_ST_OK; + if (s->s3->flags & SSL3_FLAGS_DELAY_CLIENT_FINISHED) { + s->state = SSL_ST_OK; + s->s3->flags |= SSL3_FLAGS_POP_BUFFER; + s->s3->delay_buf_pop_ret = 0; + } + } else { +#ifndef OPENSSL_NO_TLSEXT + /* + * Allow NewSessionTicket if ticket expected + */ + if (s->tlsext_ticket_expected) + s->s3->tmp.next_state = SSL3_ST_CR_SESSION_TICKET_A; + else +#endif + + s->s3->tmp.next_state = SSL3_ST_CR_FINISHED_A; + } + s->init_num = 0; + break; + +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_CR_SESSION_TICKET_A: + case SSL3_ST_CR_SESSION_TICKET_B: + ret = ssl3_get_new_session_ticket(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_FINISHED_A; + s->init_num = 0; + break; + + case SSL3_ST_CR_CERT_STATUS_A: + case SSL3_ST_CR_CERT_STATUS_B: + ret = ssl3_get_cert_status(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_CR_KEY_EXCH_A; + s->init_num = 0; + break; +#endif + + case SSL3_ST_CR_FINISHED_A: + case SSL3_ST_CR_FINISHED_B: + if (!s->s3->change_cipher_spec) + s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret = ssl3_get_finished(s, SSL3_ST_CR_FINISHED_A, + SSL3_ST_CR_FINISHED_B); + if (ret <= 0) + goto end; + + if (s->hit) + s->state = SSL3_ST_CW_CHANGE_A; + else + s->state = SSL_ST_OK; + s->init_num = 0; + break; + + case SSL3_ST_CW_FLUSH: + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + s->state = s->s3->tmp.next_state; + break; + + case SSL_ST_OK: + /* clean a few things up */ + ssl3_cleanup_key_block(s); + + if (s->init_buf != NULL) { + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + } + + /* + * If we are not 'joining' the last two packets, remove the + * buffering now + */ + if (!(s->s3->flags & SSL3_FLAGS_POP_BUFFER)) + ssl_free_wbio_buffer(s); + /* else do it later in ssl3_write */ + + s->init_num = 0; + s->renegotiate = 0; + s->new_session = 0; + + ssl_update_cache(s, SSL_SESS_CACHE_CLIENT); + if (s->hit) + s->ctx->stats.sess_hit++; + + ret = 1; + /* s->server=0; */ + s->handshake_func = ssl3_connect; + s->ctx->stats.sess_connect_good++; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + + goto end; + /* break; */ + + case SSL_ST_ERR: + default: + SSLerr(SSL_F_SSL3_CONNECT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + /* did we do anything */ + if (!s->s3->tmp.reuse_message && !skip) { + if (s->debug) { + if ((ret = BIO_flush(s->wbio)) <= 0) + goto end; + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_CONNECT_LOOP, 1); + s->state = new_state; + } + } + skip = 0; + } + end: + s->in_handshake--; + if (buf != NULL) + BUF_MEM_free(buf); + if (cb != NULL) + cb(s, SSL_CB_CONNECT_EXIT, ret); + return (ret); +} + +int ssl3_client_hello(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; + int i; + unsigned long l; +#ifndef OPENSSL_NO_COMP + int j; + SSL_COMP *comp; +#endif + + buf = (unsigned char *)s->init_buf->data; + if (s->state == SSL3_ST_CW_CLNT_HELLO_A) { + SSL_SESSION *sess = s->session; + if ((sess == NULL) || (sess->ssl_version != s->version) || +#ifdef OPENSSL_NO_TLSEXT + !sess->session_id_length || +#else + /* + * In the case of EAP-FAST, we can have a pre-shared + * "ticket" without a session ID. + */ + (!sess->session_id_length && !sess->tlsext_tick) || +#endif + (sess->not_resumable)) { + if (!ssl_get_new_session(s, 0)) + goto err; + } + /* else use the pre-loaded session */ + + p = s->s3->client_random; + + if (ssl_fill_hello_random(s, 0, p, SSL3_RANDOM_SIZE) <= 0) + goto err; + + /* Do the message type and length last */ + d = p = &(buf[4]); + + /*- + * version indicates the negotiated version: for example from + * an SSLv2/v3 compatible client hello). The client_version + * field is the maximum version we permit and it is also + * used in RSA encrypted premaster secrets. Some servers can + * choke if we initially report a higher version then + * renegotiate to a lower one in the premaster secret. This + * didn't happen with TLS 1.0 as most servers supported it + * but it can with TLS 1.1 or later if the server only supports + * 1.0. + * + * Possible scenario with previous logic: + * 1. Client hello indicates TLS 1.2 + * 2. Server hello says TLS 1.0 + * 3. RSA encrypted premaster secret uses 1.2. + * 4. Handhaked proceeds using TLS 1.0. + * 5. Server sends hello request to renegotiate. + * 6. Client hello indicates TLS v1.0 as we now + * know that is maximum server supports. + * 7. Server chokes on RSA encrypted premaster secret + * containing version 1.0. + * + * For interoperability it should be OK to always use the + * maximum version we support in client hello and then rely + * on the checking of version to ensure the servers isn't + * being inconsistent: for example initially negotiating with + * TLS 1.0 and renegotiating with TLS 1.2. We do this by using + * client_version in client hello and not resetting it to + * the negotiated version. + */ +#if 0 + *(p++) = s->version >> 8; + *(p++) = s->version & 0xff; + s->client_version = s->version; +#else + *(p++) = s->client_version >> 8; + *(p++) = s->client_version & 0xff; +#endif + + /* Random stuff */ + memcpy(p, s->s3->client_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /* Session ID */ + if (s->new_session) + i = 0; + else + i = s->session->session_id_length; + *(p++) = i; + if (i != 0) { + if (i > (int)sizeof(s->session->session_id)) { + SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + goto err; + } + memcpy(p, s->session->session_id, i); + p += i; + } + + /* Ciphers supported */ + i = ssl_cipher_list_to_bytes(s, SSL_get_ciphers(s), &(p[2]), 0); + if (i == 0) { + SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_NO_CIPHERS_AVAILABLE); + goto err; + } +#ifdef OPENSSL_MAX_TLS1_2_CIPHER_LENGTH + /* + * Some servers hang if client hello > 256 bytes as hack workaround + * chop number of supported ciphers to keep it well below this if we + * use TLS v1.2 + */ + if (TLS1_get_version(s) >= TLS1_2_VERSION + && i > OPENSSL_MAX_TLS1_2_CIPHER_LENGTH) + i = OPENSSL_MAX_TLS1_2_CIPHER_LENGTH & ~1; +#endif + s2n(i, p); + p += i; + + /* COMPRESSION */ +#ifdef OPENSSL_NO_COMP + *(p++) = 1; +#else + + if ((s->options & SSL_OP_NO_COMPRESSION) + || !s->ctx->comp_methods) + j = 0; + else + j = sk_SSL_COMP_num(s->ctx->comp_methods); + *(p++) = 1 + j; + for (i = 0; i < j; i++) { + comp = sk_SSL_COMP_value(s->ctx->comp_methods, i); + *(p++) = comp->id; + } +#endif + *(p++) = 0; /* Add the NULL method */ + +#ifndef OPENSSL_NO_TLSEXT + /* TLS extensions */ + if (ssl_prepare_clienthello_tlsext(s) <= 0) { + SSLerr(SSL_F_SSL3_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } + if ((p = + ssl_add_clienthello_tlsext(s, p, + buf + SSL3_RT_MAX_PLAIN_LENGTH)) == + NULL) { + SSLerr(SSL_F_SSL3_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + goto err; + } +#endif + + l = (p - d); + d = buf; + *(d++) = SSL3_MT_CLIENT_HELLO; + l2n3(l, d); + + s->state = SSL3_ST_CW_CLNT_HELLO_B; + /* number of bytes to write */ + s->init_num = p - buf; + s->init_off = 0; + } + + /* SSL3_ST_CW_CLNT_HELLO_B */ + return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); + err: + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_get_server_hello(SSL *s) +{ + STACK_OF(SSL_CIPHER) *sk; + const SSL_CIPHER *c; + unsigned char *p, *d; + int i, al, ok; + unsigned int j; + long n; +#ifndef OPENSSL_NO_COMP + SSL_COMP *comp; +#endif + + n = s->method->ssl_get_message(s, + SSL3_ST_CR_SRVR_HELLO_A, + SSL3_ST_CR_SRVR_HELLO_B, -1, 20000, &ok); + + if (!ok) + return ((int)n); + + if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) { + if (s->s3->tmp.message_type == DTLS1_MT_HELLO_VERIFY_REQUEST) { + if (s->d1->send_cookie == 0) { + s->s3->tmp.reuse_message = 1; + return 1; + } else { /* already sent a cookie */ + + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_MESSAGE_TYPE); + goto f_err; + } + } + } + + if (s->s3->tmp.message_type != SSL3_MT_SERVER_HELLO) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_MESSAGE_TYPE); + goto f_err; + } + + d = p = (unsigned char *)s->init_msg; + + if ((p[0] != (s->version >> 8)) || (p[1] != (s->version & 0xff))) { + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_SSL_VERSION); + s->version = (s->version & 0xff00) | p[1]; + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + p += 2; + + /* load the server hello data */ + /* load the server random */ + memcpy(s->s3->server_random, p, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + s->hit = 0; + + /* get the session-id */ + j = *(p++); + + if ((j > sizeof s->session->session_id) || (j > SSL3_SESSION_ID_SIZE)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_SSL3_SESSION_ID_TOO_LONG); + goto f_err; + } +#ifndef OPENSSL_NO_TLSEXT + /* + * Check if we can resume the session based on external pre-shared secret. + * EAP-FAST (RFC 4851) supports two types of session resumption. + * Resumption based on server-side state works with session IDs. + * Resumption based on pre-shared Protected Access Credentials (PACs) + * works by overriding the SessionTicket extension at the application + * layer, and does not send a session ID. (We do not know whether EAP-FAST + * servers would honour the session ID.) Therefore, the session ID alone + * is not a reliable indicator of session resumption, so we first check if + * we can resume, and later peek at the next handshake message to see if the + * server wants to resume. + */ + if (s->version >= TLS1_VERSION && s->tls_session_secret_cb && + s->session->tlsext_tick) { + SSL_CIPHER *pref_cipher = NULL; + s->session->master_key_length = sizeof(s->session->master_key); + if (s->tls_session_secret_cb(s, s->session->master_key, + &s->session->master_key_length, + NULL, &pref_cipher, + s->tls_session_secret_cb_arg)) { + s->session->cipher = pref_cipher ? + pref_cipher : ssl_get_cipher_by_char(s, p + j); + } else { + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + } +#endif /* OPENSSL_NO_TLSEXT */ + + if (j != 0 && j == s->session->session_id_length + && memcmp(p, s->session->session_id, j) == 0) { + if (s->sid_ctx_length != s->session->sid_ctx_length + || memcmp(s->session->sid_ctx, s->sid_ctx, s->sid_ctx_length)) { + /* actually a client application bug */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); + goto f_err; + } + s->hit = 1; + } else { + /* + * If we were trying for session-id reuse but the server + * didn't echo the ID, make a new SSL_SESSION. + * In the case of EAP-FAST and PAC, we do not send a session ID, + * so the PAC-based session secret is always preserved. It'll be + * overwritten if the server refuses resumption. + */ + if (s->session->session_id_length > 0) { + if (!ssl_get_new_session(s, 0)) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + } + s->session->session_id_length = j; + memcpy(s->session->session_id, p, j); /* j could be 0 */ + } + p += j; + c = ssl_get_cipher_by_char(s, p); + if (c == NULL) { + /* unknown cipher */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_UNKNOWN_CIPHER_RETURNED); + goto f_err; + } + /* TLS v1.2 only ciphersuites require v1.2 or later */ + if ((c->algorithm_ssl & SSL_TLSV1_2) && + (TLS1_get_version(s) < TLS1_2_VERSION)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED); + goto f_err; + } +#ifndef OPENSSL_NO_SRP + if (((c->algorithm_mkey & SSL_kSRP) || (c->algorithm_auth & SSL_aSRP)) && + !(s->srp_ctx.srp_Mask & SSL_kSRP)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED); + goto f_err; + } +#endif /* OPENSSL_NO_SRP */ + p += ssl_put_cipher_by_char(s, NULL, NULL); + + sk = ssl_get_ciphers_by_id(s); + i = sk_SSL_CIPHER_find(sk, c); + if (i < 0) { + /* we did not say we would use this cipher */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_WRONG_CIPHER_RETURNED); + goto f_err; + } + + /* + * Depending on the session caching (internal/external), the cipher + * and/or cipher_id values may not be set. Make sure that cipher_id is + * set and use it for comparison. + */ + if (s->session->cipher) + s->session->cipher_id = s->session->cipher->id; + if (s->hit && (s->session->cipher_id != c->id)) { +/* Workaround is now obsolete */ +#if 0 + if (!(s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)) +#endif + { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); + goto f_err; + } + } + s->s3->tmp.new_cipher = c; + /* + * Don't digest cached records if TLS v1.2: we may need them for client + * authentication. + */ + if (TLS1_get_version(s) < TLS1_2_VERSION + && !ssl3_digest_cached_records(s)) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + /* lets get the compression algorithm */ + /* COMPRESSION */ +#ifdef OPENSSL_NO_COMP + if (*(p++) != 0) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + goto f_err; + } + /* + * If compression is disabled we'd better not try to resume a session + * using compression. + */ + if (s->session->compress_meth != 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_INCONSISTENT_COMPRESSION); + goto f_err; + } +#else + j = *(p++); + if (s->hit && j != s->session->compress_meth) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED); + goto f_err; + } + if (j == 0) + comp = NULL; + else if (s->options & SSL_OP_NO_COMPRESSION) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_COMPRESSION_DISABLED); + goto f_err; + } else + comp = ssl3_comp_find(s->ctx->comp_methods, j); + + if ((j != 0) && (comp == NULL)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, + SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + goto f_err; + } else { + s->s3->tmp.new_compression = comp; + } +#endif + +#ifndef OPENSSL_NO_TLSEXT + /* TLS extensions */ + if (s->version >= SSL3_VERSION) { + if (!ssl_parse_serverhello_tlsext(s, &p, d, n, &al)) { + /* 'al' set by ssl_parse_serverhello_tlsext */ + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_PARSE_TLSEXT); + goto f_err; + } + if (ssl_check_serverhello_tlsext(s) <= 0) { + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT); + goto err; + } + } +#endif + + if (p != (d + n)) { + /* wrong packet length */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_HELLO, SSL_R_BAD_PACKET_LENGTH); + goto f_err; + } + + return (1); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_get_server_certificate(SSL *s) +{ + int al, i, ok, ret = -1; + unsigned long n, nc, llen, l; + X509 *x = NULL; + const unsigned char *q, *p; + unsigned char *d; + STACK_OF(X509) *sk = NULL; + SESS_CERT *sc; + EVP_PKEY *pkey = NULL; + int need_cert = 1; /* VRS: 0=> will allow null cert if auth == + * KRB5 */ + + n = s->method->ssl_get_message(s, + SSL3_ST_CR_CERT_A, + SSL3_ST_CR_CERT_B, + -1, s->max_cert_list, &ok); + + if (!ok) + return ((int)n); + + if ((s->s3->tmp.message_type == SSL3_MT_SERVER_KEY_EXCHANGE) || + ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) && + (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE))) { + s->s3->tmp.reuse_message = 1; + return (1); + } + + if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, SSL_R_BAD_MESSAGE_TYPE); + goto f_err; + } + p = d = (unsigned char *)s->init_msg; + + if ((sk = sk_X509_new_null()) == NULL) { + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto err; + } + + n2l3(p, llen); + if (llen + 3 != n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + for (nc = 0; nc < llen;) { + n2l3(p, l); + if ((l + nc + 3) > llen) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + + q = p; + x = d2i_X509(NULL, &q, l); + if (x == NULL) { + al = SSL_AD_BAD_CERTIFICATE; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_ASN1_LIB); + goto f_err; + } + if (q != (p + l)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + if (!sk_X509_push(sk, x)) { + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto err; + } + x = NULL; + nc += l + 3; + p = q; + } + + i = ssl_verify_cert_chain(s, sk); + if ((s->verify_mode != SSL_VERIFY_NONE) && (i <= 0) +#ifndef OPENSSL_NO_KRB5 + && !((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) && + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) +#endif /* OPENSSL_NO_KRB5 */ + ) { + al = ssl_verify_alarm_type(s->verify_result); + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_CERTIFICATE_VERIFY_FAILED); + goto f_err; + } + ERR_clear_error(); /* but we keep s->verify_result */ + + sc = ssl_sess_cert_new(); + if (sc == NULL) + goto err; + + if (s->session->sess_cert) + ssl_sess_cert_free(s->session->sess_cert); + s->session->sess_cert = sc; + + sc->cert_chain = sk; + /* + * Inconsistency alert: cert_chain does include the peer's certificate, + * which we don't include in s3_srvr.c + */ + x = sk_X509_value(sk, 0); + sk = NULL; + /* + * VRS 19990621: possible memory leak; sk=null ==> !sk_pop_free() @end + */ + + pkey = X509_get_pubkey(x); + + /* VRS: allow null cert if auth == KRB5 */ + need_cert = ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5) && + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5)) + ? 0 : 1; + +#ifdef KSSL_DEBUG + fprintf(stderr, "pkey,x = %p, %p\n", pkey, x); + fprintf(stderr, "ssl_cert_type(x,pkey) = %d\n", ssl_cert_type(x, pkey)); + fprintf(stderr, "cipher, alg, nc = %s, %lx, %lx, %d\n", + s->s3->tmp.new_cipher->name, + s->s3->tmp.new_cipher->algorithm_mkey, + s->s3->tmp.new_cipher->algorithm_auth, need_cert); +#endif /* KSSL_DEBUG */ + + if (need_cert && ((pkey == NULL) || EVP_PKEY_missing_parameters(pkey))) { + x = NULL; + al = SSL3_AL_FATAL; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS); + goto f_err; + } + + i = ssl_cert_type(x, pkey); + if (need_cert && i < 0) { + x = NULL; + al = SSL3_AL_FATAL; + SSLerr(SSL_F_SSL3_GET_SERVER_CERTIFICATE, + SSL_R_UNKNOWN_CERTIFICATE_TYPE); + goto f_err; + } + + if (need_cert) { + sc->peer_cert_type = i; + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + /* + * Why would the following ever happen? We just created sc a couple + * of lines ago. + */ + if (sc->peer_pkeys[i].x509 != NULL) + X509_free(sc->peer_pkeys[i].x509); + sc->peer_pkeys[i].x509 = x; + sc->peer_key = &(sc->peer_pkeys[i]); + + if (s->session->peer != NULL) + X509_free(s->session->peer); + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + s->session->peer = x; + } else { + sc->peer_cert_type = i; + sc->peer_key = NULL; + + if (s->session->peer != NULL) + X509_free(s->session->peer); + s->session->peer = NULL; + } + s->session->verify_result = s->verify_result; + + x = NULL; + ret = 1; + + if (0) { + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + s->state = SSL_ST_ERR; + } + + EVP_PKEY_free(pkey); + X509_free(x); + sk_X509_pop_free(sk, X509_free); + return (ret); +} + +int ssl3_get_key_exchange(SSL *s) +{ +#ifndef OPENSSL_NO_RSA + unsigned char *q, md_buf[EVP_MAX_MD_SIZE * 2]; +#endif + EVP_MD_CTX md_ctx; + unsigned char *param, *p; + int al, j, ok; + long i, param_len, n, alg_k, alg_a; + EVP_PKEY *pkey = NULL; + const EVP_MD *md = NULL; +#ifndef OPENSSL_NO_RSA + RSA *rsa = NULL; +#endif +#ifndef OPENSSL_NO_DH + DH *dh = NULL; +#endif +#ifndef OPENSSL_NO_ECDH + EC_KEY *ecdh = NULL; + BN_CTX *bn_ctx = NULL; + EC_POINT *srvr_ecpoint = NULL; + int curve_nid = 0; + int encoded_pt_len = 0; +#endif + + EVP_MD_CTX_init(&md_ctx); + + /* + * use same message size as in ssl3_get_certificate_request() as + * ServerKeyExchange message may be skipped + */ + n = s->method->ssl_get_message(s, + SSL3_ST_CR_KEY_EXCH_A, + SSL3_ST_CR_KEY_EXCH_B, + -1, s->max_cert_list, &ok); + if (!ok) + return ((int)n); + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + if (s->s3->tmp.message_type != SSL3_MT_SERVER_KEY_EXCHANGE) { + /* + * Can't skip server key exchange if this is an ephemeral + * ciphersuite. + */ + if (alg_k & (SSL_kEDH | SSL_kEECDH)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); + al = SSL_AD_UNEXPECTED_MESSAGE; + goto f_err; + } +#ifndef OPENSSL_NO_PSK + /* + * In plain PSK ciphersuite, ServerKeyExchange can be omitted if no + * identity hint is sent. Set session->sess_cert anyway to avoid + * problems later. + */ + if (alg_k & SSL_kPSK) { + s->session->sess_cert = ssl_sess_cert_new(); + if (s->ctx->psk_identity_hint) + OPENSSL_free(s->ctx->psk_identity_hint); + s->ctx->psk_identity_hint = NULL; + } +#endif + s->s3->tmp.reuse_message = 1; + return (1); + } + + param = p = (unsigned char *)s->init_msg; + if (s->session->sess_cert != NULL) { +#ifndef OPENSSL_NO_RSA + if (s->session->sess_cert->peer_rsa_tmp != NULL) { + RSA_free(s->session->sess_cert->peer_rsa_tmp); + s->session->sess_cert->peer_rsa_tmp = NULL; + } +#endif +#ifndef OPENSSL_NO_DH + if (s->session->sess_cert->peer_dh_tmp) { + DH_free(s->session->sess_cert->peer_dh_tmp); + s->session->sess_cert->peer_dh_tmp = NULL; + } +#endif +#ifndef OPENSSL_NO_ECDH + if (s->session->sess_cert->peer_ecdh_tmp) { + EC_KEY_free(s->session->sess_cert->peer_ecdh_tmp); + s->session->sess_cert->peer_ecdh_tmp = NULL; + } +#endif + } else { + s->session->sess_cert = ssl_sess_cert_new(); + } + + /* Total length of the parameters including the length prefix */ + param_len = 0; + + alg_a = s->s3->tmp.new_cipher->algorithm_auth; + + al = SSL_AD_DECODE_ERROR; + +#ifndef OPENSSL_NO_PSK + if (alg_k & SSL_kPSK) { + param_len = 2; + if (param_len > n) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p, i); + + /* + * Store PSK identity hint for later use, hint is used in + * ssl3_send_client_key_exchange. Assume that the maximum length of + * a PSK identity hint can be as long as the maximum length of a PSK + * identity. + */ + if (i > PSK_MAX_IDENTITY_LEN) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_DATA_LENGTH_TOO_LONG); + goto f_err; + } + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH); + goto f_err; + } + param_len += i; + + s->session->psk_identity_hint = BUF_strndup((char *)p, i); + if (s->session->psk_identity_hint == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto f_err; + } + + p += i; + n -= param_len; + } else +#endif /* !OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + if (alg_k & SSL_kSRP) { + param_len = 2; + if (param_len > n) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_N_LENGTH); + goto f_err; + } + param_len += i; + + if (!(s->srp_ctx.N = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + + if (2 > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_G_LENGTH); + goto f_err; + } + param_len += i; + + if (!(s->srp_ctx.g = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + + if (1 > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 1; + + i = (unsigned int)(p[0]); + p++; + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_S_LENGTH); + goto f_err; + } + param_len += i; + + if (!(s->srp_ctx.s = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + + if (2 > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_B_LENGTH); + goto f_err; + } + param_len += i; + + if (!(s->srp_ctx.B = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + n -= param_len; + + if (!srp_verify_server_param(s, &al)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SRP_PARAMETERS); + goto f_err; + } + +/* We must check if there is a certificate */ +# ifndef OPENSSL_NO_RSA + if (alg_a & SSL_aRSA) + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); +# else + if (0) ; +# endif +# ifndef OPENSSL_NO_DSA + else if (alg_a & SSL_aDSS) + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN]. + x509); +# endif + } else +#endif /* !OPENSSL_NO_SRP */ +#ifndef OPENSSL_NO_RSA + if (alg_k & SSL_kRSA) { + /* Temporary RSA keys only allowed in export ciphersuites */ + if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + if ((rsa = RSA_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + + param_len = 2; + if (param_len > n) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_MODULUS_LENGTH); + goto f_err; + } + param_len += i; + + if (!(rsa->n = BN_bin2bn(p, i, rsa->n))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + + if (2 > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_E_LENGTH); + goto f_err; + } + param_len += i; + + if (!(rsa->e = BN_bin2bn(p, i, rsa->e))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + n -= param_len; + + /* this should be because we are using an export cipher */ + if (alg_a & SSL_aRSA) + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); + else { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (EVP_PKEY_bits(pkey) <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } + + s->session->sess_cert->peer_rsa_tmp = rsa; + rsa = NULL; + } +#else /* OPENSSL_NO_RSA */ + if (0) ; +#endif +#ifndef OPENSSL_NO_DH + else if (alg_k & SSL_kEDH) { + if ((dh = DH_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + + param_len = 2; + if (param_len > n) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_LENGTH); + goto f_err; + } + param_len += i; + + if (!(dh->p = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + + if (BN_is_zero(dh->p)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_P_VALUE); + goto f_err; + } + + + if (2 > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_LENGTH); + goto f_err; + } + param_len += i; + + if (!(dh->g = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + + if (BN_is_zero(dh->g)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_G_VALUE); + goto f_err; + } + + if (2 > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + param_len += 2; + + n2s(p, i); + + if (i > n - param_len) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_LENGTH); + goto f_err; + } + param_len += i; + + if (!(dh->pub_key = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + p += i; + n -= param_len; + + if (BN_is_zero(dh->pub_key)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_DH_PUB_KEY_VALUE); + goto f_err; + } + +# ifndef OPENSSL_NO_RSA + if (alg_a & SSL_aRSA) + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); +# else + if (0) ; +# endif +# ifndef OPENSSL_NO_DSA + else if (alg_a & SSL_aDSS) + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_DSA_SIGN]. + x509); +# endif + /* else anonymous DH, so no certificate or pkey. */ + + s->session->sess_cert->peer_dh_tmp = dh; + dh = NULL; + } else if ((alg_k & SSL_kDHr) || (alg_k & SSL_kDHd)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER); + goto f_err; + } +#endif /* !OPENSSL_NO_DH */ + +#ifndef OPENSSL_NO_ECDH + else if (alg_k & SSL_kEECDH) { + EC_GROUP *ngroup; + const EC_GROUP *group; + + if ((ecdh = EC_KEY_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* + * Extract elliptic curve parameters and the server's ephemeral ECDH + * public key. Keep accumulating lengths of various components in + * param_len and make sure it never exceeds n. + */ + + /* + * XXX: For now we only support named (not generic) curves and the + * ECParameters in this case is just three bytes. We also need one + * byte for the length of the encoded point + */ + param_len = 4; + if (param_len > n) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + if ((*p != NAMED_CURVE_TYPE) || + ((curve_nid = tls1_ec_curve_id2nid(*(p + 2))) == 0)) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS); + goto f_err; + } + + ngroup = EC_GROUP_new_by_curve_name(curve_nid); + if (ngroup == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + if (EC_KEY_set_group(ecdh, ngroup) == 0) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + EC_GROUP_free(ngroup); + + group = EC_KEY_get0_group(ecdh); + + if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && + (EC_GROUP_get_degree(group) > 163)) { + al = SSL_AD_EXPORT_RESTRICTION; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); + goto f_err; + } + + p += 3; + + /* Next, get the encoded ECPoint */ + if (((srvr_ecpoint = EC_POINT_new(group)) == NULL) || + ((bn_ctx = BN_CTX_new()) == NULL)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + + encoded_pt_len = *p; /* length of encoded point */ + p += 1; + + if ((encoded_pt_len > n - param_len) || + (EC_POINT_oct2point(group, srvr_ecpoint, + p, encoded_pt_len, bn_ctx) == 0)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_ECPOINT); + goto f_err; + } + param_len += encoded_pt_len; + + n -= param_len; + p += encoded_pt_len; + + /* + * The ECC/TLS specification does not mention the use of DSA to sign + * ECParameters in the server key exchange message. We do support RSA + * and ECDSA. + */ + if (0) ; +# ifndef OPENSSL_NO_RSA + else if (alg_a & SSL_aRSA) + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC].x509); +# endif +# ifndef OPENSSL_NO_ECDSA + else if (alg_a & SSL_aECDSA) + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); +# endif + /* else anonymous ECDH, so no certificate or pkey. */ + EC_KEY_set_public_key(ecdh, srvr_ecpoint); + s->session->sess_cert->peer_ecdh_tmp = ecdh; + ecdh = NULL; + BN_CTX_free(bn_ctx); + bn_ctx = NULL; + EC_POINT_free(srvr_ecpoint); + srvr_ecpoint = NULL; + } else if (alg_k) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNEXPECTED_MESSAGE); + goto f_err; + } +#endif /* !OPENSSL_NO_ECDH */ + + /* p points to the next byte, there are 'n' bytes left */ + + /* if it was signed, check the signature */ + if (pkey != NULL) { + if (TLS1_get_version(s) >= TLS1_2_VERSION) { + int sigalg; + if (2 > n) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + sigalg = tls12_get_sigid(pkey); + /* Should never happen */ + if (sigalg == -1) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + /* Check key type is consistent with signature */ + if (sigalg != (int)p[1]) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + SSL_R_WRONG_SIGNATURE_TYPE); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + md = tls12_get_hash(p[0]); + if (md == NULL) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_UNKNOWN_DIGEST); + goto f_err; + } +#ifdef SSL_DEBUG + fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); +#endif + p += 2; + n -= 2; + } else + md = EVP_sha1(); + + if (2 > n) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p, i); + n -= 2; + j = EVP_PKEY_size(pkey); + + /* + * Check signature length. If n is 0 then signature is empty + */ + if ((i != n) || (n > j) || (n <= 0)) { + /* wrong packet length */ + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_WRONG_SIGNATURE_LENGTH); + goto f_err; + } +#ifndef OPENSSL_NO_RSA + if (pkey->type == EVP_PKEY_RSA + && TLS1_get_version(s) < TLS1_2_VERSION) { + int num; + unsigned int size; + + j = 0; + q = md_buf; + for (num = 2; num > 0; num--) { + EVP_MD_CTX_set_flags(&md_ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + if (EVP_DigestInit_ex(&md_ctx, + (num == 2) ? s->ctx->md5 : s->ctx->sha1, + NULL) <= 0 + || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestUpdate(&md_ctx, param, param_len) <= 0 + || EVP_DigestFinal_ex(&md_ctx, q, &size) <= 0) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + q += size; + j += size; + } + i = RSA_verify(NID_md5_sha1, md_buf, j, p, n, pkey->pkey.rsa); + if (i < 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_RSA_DECRYPT); + goto f_err; + } + if (i == 0) { + /* bad signature */ + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE); + goto f_err; + } + } else +#endif + { + if (EVP_VerifyInit_ex(&md_ctx, md, NULL) <= 0 + || EVP_VerifyUpdate(&md_ctx, &(s->s3->client_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_VerifyUpdate(&md_ctx, &(s->s3->server_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_VerifyUpdate(&md_ctx, param, param_len) <= 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_EVP_LIB); + goto f_err; + } + if (EVP_VerifyFinal(&md_ctx, p, (int)n, pkey) <= 0) { + /* bad signature */ + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_BAD_SIGNATURE); + goto f_err; + } + } + } else { + /* aNULL, aSRP or kPSK do not need public keys */ + if (!(alg_a & (SSL_aNULL | SSL_aSRP)) && !(alg_k & SSL_kPSK)) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + /* still data left over */ + if (n != 0) { + SSLerr(SSL_F_SSL3_GET_KEY_EXCHANGE, SSL_R_EXTRA_DATA_IN_MESSAGE); + goto f_err; + } + } + EVP_PKEY_free(pkey); + EVP_MD_CTX_cleanup(&md_ctx); + return (1); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + EVP_PKEY_free(pkey); +#ifndef OPENSSL_NO_RSA + if (rsa != NULL) + RSA_free(rsa); +#endif +#ifndef OPENSSL_NO_DH + if (dh != NULL) + DH_free(dh); +#endif +#ifndef OPENSSL_NO_ECDH + BN_CTX_free(bn_ctx); + EC_POINT_free(srvr_ecpoint); + if (ecdh != NULL) + EC_KEY_free(ecdh); +#endif + EVP_MD_CTX_cleanup(&md_ctx); + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_get_certificate_request(SSL *s) +{ + int ok, ret = 0; + unsigned long n, nc, l; + unsigned int llen, ctype_num, i; + X509_NAME *xn = NULL; + const unsigned char *p, *q; + unsigned char *d; + STACK_OF(X509_NAME) *ca_sk = NULL; + + n = s->method->ssl_get_message(s, + SSL3_ST_CR_CERT_REQ_A, + SSL3_ST_CR_CERT_REQ_B, + -1, s->max_cert_list, &ok); + + if (!ok) + return ((int)n); + + s->s3->tmp.cert_req = 0; + + if (s->s3->tmp.message_type == SSL3_MT_SERVER_DONE) { + s->s3->tmp.reuse_message = 1; + /* + * If we get here we don't need any cached handshake records as we + * wont be doing client auth. + */ + if (s->s3->handshake_buffer) { + if (!ssl3_digest_cached_records(s)) + goto err; + } + return (1); + } + + if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_REQUEST) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_WRONG_MESSAGE_TYPE); + goto err; + } + + /* TLS does not like anon-DH with client cert */ + if (s->version > SSL3_VERSION) { + if (s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER); + goto err; + } + } + + p = d = (unsigned char *)s->init_msg; + + if ((ca_sk = sk_X509_NAME_new(ca_dn_cmp)) == NULL) { + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* get the certificate types */ + ctype_num = *(p++); + if (ctype_num > SSL3_CT_NUMBER) + ctype_num = SSL3_CT_NUMBER; + for (i = 0; i < ctype_num; i++) + s->s3->tmp.ctype[i] = p[i]; + p += ctype_num; + if (TLS1_get_version(s) >= TLS1_2_VERSION) { + n2s(p, llen); + /* + * Check we have enough room for signature algorithms and following + * length value. + */ + if ((unsigned long)(p - d + llen + 2) > n) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + if ((llen & 1) || !tls1_process_sigalgs(s, p, llen)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_SIGNATURE_ALGORITHMS_ERROR); + goto err; + } + p += llen; + } + + /* get the CA RDNs */ + n2s(p, llen); +#if 0 + { + FILE *out; + out = fopen("/tmp/vsign.der", "w"); + fwrite(p, 1, llen, out); + fclose(out); + } +#endif + + if ((unsigned long)(p - d + llen) != n) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_LENGTH_MISMATCH); + goto err; + } + + for (nc = 0; nc < llen;) { + n2s(p, l); + if ((l + nc + 2) > llen) { + if ((s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) + goto cont; /* netscape bugs */ + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, SSL_R_CA_DN_TOO_LONG); + goto err; + } + + q = p; + + if ((xn = d2i_X509_NAME(NULL, &q, l)) == NULL) { + /* If netscape tolerance is on, ignore errors */ + if (s->options & SSL_OP_NETSCAPE_CA_DN_BUG) + goto cont; + else { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_ASN1_LIB); + goto err; + } + } + + if (q != (p + l)) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, + SSL_R_CA_DN_LENGTH_MISMATCH); + goto err; + } + if (!sk_X509_NAME_push(ca_sk, xn)) { + SSLerr(SSL_F_SSL3_GET_CERTIFICATE_REQUEST, ERR_R_MALLOC_FAILURE); + goto err; + } + xn = NULL; + + p += l; + nc += l + 2; + } + + if (0) { + cont: + ERR_clear_error(); + } + + /* we should setup a certificate to return.... */ + s->s3->tmp.cert_req = 1; + s->s3->tmp.ctype_num = ctype_num; + if (s->s3->tmp.ca_names != NULL) + sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); + s->s3->tmp.ca_names = ca_sk; + ca_sk = NULL; + + ret = 1; + goto done; + err: + s->state = SSL_ST_ERR; + done: + X509_NAME_free(xn); + if (ca_sk != NULL) + sk_X509_NAME_pop_free(ca_sk, X509_NAME_free); + return (ret); +} + +static int ca_dn_cmp(const X509_NAME *const *a, const X509_NAME *const *b) +{ + return (X509_NAME_cmp(*a, *b)); +} + +#ifndef OPENSSL_NO_TLSEXT +int ssl3_get_new_session_ticket(SSL *s) +{ + int ok, al, ret = 0, ticklen; + long n; + const unsigned char *p; + unsigned char *d; + unsigned long ticket_lifetime_hint; + + n = s->method->ssl_get_message(s, + SSL3_ST_CR_SESSION_TICKET_A, + SSL3_ST_CR_SESSION_TICKET_B, + SSL3_MT_NEWSESSION_TICKET, 16384, &ok); + + if (!ok) + return ((int)n); + + if (n < 6) { + /* need at least ticket_lifetime_hint + ticket length */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + p = d = (unsigned char *)s->init_msg; + + n2l(p, ticket_lifetime_hint); + n2s(p, ticklen); + /* ticket_lifetime_hint + ticket_length + ticket */ + if (ticklen + 6 != n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + /* Server is allowed to change its mind and send an empty ticket. */ + if (ticklen == 0) + return 1; + + if (s->session->session_id_length > 0) { + int i = s->session_ctx->session_cache_mode; + SSL_SESSION *new_sess; + /* + * We reused an existing session, so we need to replace it with a new + * one + */ + if (i & SSL_SESS_CACHE_CLIENT) { + /* + * Remove the old session from the cache + */ + if (i & SSL_SESS_CACHE_NO_INTERNAL_STORE) { + if (s->session_ctx->remove_session_cb != NULL) + s->session_ctx->remove_session_cb(s->session_ctx, + s->session); + } else { + /* We carry on if this fails */ + SSL_CTX_remove_session(s->session_ctx, s->session); + } + } + + if ((new_sess = ssl_session_dup(s->session, 0)) == 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); + goto f_err; + } + + SSL_SESSION_free(s->session); + s->session = new_sess; + } + + if (s->session->tlsext_tick) { + OPENSSL_free(s->session->tlsext_tick); + s->session->tlsext_ticklen = 0; + } + s->session->tlsext_tick = OPENSSL_malloc(ticklen); + if (!s->session->tlsext_tick) { + SSLerr(SSL_F_SSL3_GET_NEW_SESSION_TICKET, ERR_R_MALLOC_FAILURE); + goto err; + } + memcpy(s->session->tlsext_tick, p, ticklen); + s->session->tlsext_tick_lifetime_hint = ticket_lifetime_hint; + s->session->tlsext_ticklen = ticklen; + /* + * There are two ways to detect a resumed ticket session. One is to set + * an appropriate session ID and then the server must return a match in + * ServerHello. This allows the normal client session ID matching to work + * and we know much earlier that the ticket has been accepted. The + * other way is to set zero length session ID when the ticket is + * presented and rely on the handshake to determine session resumption. + * We choose the former approach because this fits in with assumptions + * elsewhere in OpenSSL. The session ID is set to the SHA256 (or SHA1 is + * SHA256 is disabled) hash of the ticket. + */ + EVP_Digest(p, ticklen, + s->session->session_id, &s->session->session_id_length, +# ifndef OPENSSL_NO_SHA256 + EVP_sha256(), NULL); +# else + EVP_sha1(), NULL); +# endif + ret = 1; + return (ret); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_get_cert_status(SSL *s) +{ + int ok, al; + unsigned long resplen, n; + const unsigned char *p; + + n = s->method->ssl_get_message(s, + SSL3_ST_CR_CERT_STATUS_A, + SSL3_ST_CR_CERT_STATUS_B, + -1, 16384, &ok); + + if (!ok) + return ((int)n); + + if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE_STATUS) { + /* + * The CertificateStatus message is optional even if + * tlsext_status_expected is set + */ + s->s3->tmp.reuse_message = 1; + } else { + if (n < 4) { + /* need at least status type + length */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + p = (unsigned char *)s->init_msg; + if (*p++ != TLSEXT_STATUSTYPE_ocsp) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_UNSUPPORTED_STATUS_TYPE); + goto f_err; + } + n2l3(p, resplen); + if (resplen + 4 != n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + s->tlsext_ocsp_resp = BUF_memdup(p, resplen); + if (s->tlsext_ocsp_resp == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, ERR_R_MALLOC_FAILURE); + goto f_err; + } + s->tlsext_ocsp_resplen = resplen; + } + if (s->ctx->tlsext_status_cb) { + int ret; + ret = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); + if (ret == 0) { + al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, SSL_R_INVALID_STATUS_RESPONSE); + goto f_err; + } + if (ret < 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_STATUS, ERR_R_MALLOC_FAILURE); + goto f_err; + } + } + return 1; + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->state = SSL_ST_ERR; + return (-1); +} +#endif + +int ssl3_get_server_done(SSL *s) +{ + int ok, ret = 0; + long n; + + /* Second to last param should be very small, like 0 :-) */ + n = s->method->ssl_get_message(s, + SSL3_ST_CR_SRVR_DONE_A, + SSL3_ST_CR_SRVR_DONE_B, + SSL3_MT_SERVER_DONE, 30, &ok); + + if (!ok) + return ((int)n); + if (n > 0) { + /* should contain no data */ + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + SSLerr(SSL_F_SSL3_GET_SERVER_DONE, SSL_R_LENGTH_MISMATCH); + s->state = SSL_ST_ERR; + return -1; + } + ret = 1; + return (ret); +} + +int ssl3_send_client_key_exchange(SSL *s) +{ + unsigned char *p, *d; + int n; + unsigned long alg_k; +#ifndef OPENSSL_NO_RSA + unsigned char *q; + EVP_PKEY *pkey = NULL; +#endif +#ifndef OPENSSL_NO_KRB5 + KSSL_ERR kssl_err; +#endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_ECDH + EC_KEY *clnt_ecdh = NULL; + const EC_POINT *srvr_ecpoint = NULL; + EVP_PKEY *srvr_pub_pkey = NULL; + unsigned char *encodedPoint = NULL; + int encoded_pt_len = 0; + BN_CTX *bn_ctx = NULL; +#endif + + if (s->state == SSL3_ST_CW_KEY_EXCH_A) { + d = (unsigned char *)s->init_buf->data; + p = &(d[4]); + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + /* Fool emacs indentation */ + if (0) { + } +#ifndef OPENSSL_NO_RSA + else if (alg_k & SSL_kRSA) { + RSA *rsa; + unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; + + if (s->session->sess_cert == NULL) { + /* + * We should always have a server certificate with SSL_kRSA. + */ + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if (s->session->sess_cert->peer_rsa_tmp != NULL) + rsa = s->session->sess_cert->peer_rsa_tmp; + else { + pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_RSA_ENC]. + x509); + if ((pkey == NULL) || (pkey->type != EVP_PKEY_RSA) + || (pkey->pkey.rsa == NULL)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + EVP_PKEY_free(pkey); + goto err; + } + rsa = pkey->pkey.rsa; + EVP_PKEY_free(pkey); + } + + tmp_buf[0] = s->client_version >> 8; + tmp_buf[1] = s->client_version & 0xff; + if (RAND_bytes(&(tmp_buf[2]), sizeof tmp_buf - 2) <= 0) + goto err; + + s->session->master_key_length = sizeof tmp_buf; + + q = p; + /* Fix buf for TLS and beyond */ + if (s->version > SSL3_VERSION) + p += 2; + n = RSA_public_encrypt(sizeof tmp_buf, + tmp_buf, p, rsa, RSA_PKCS1_PADDING); +# ifdef PKCS1_CHECK + if (s->options & SSL_OP_PKCS1_CHECK_1) + p[1]++; + if (s->options & SSL_OP_PKCS1_CHECK_2) + tmp_buf[0] = 0x70; +# endif + if (n <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_BAD_RSA_ENCRYPT); + goto err; + } + + /* Fix buf for TLS and beyond */ + if (s->version > SSL3_VERSION) { + s2n(n, q); + n += 2; + } + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + tmp_buf, + sizeof tmp_buf); + OPENSSL_cleanse(tmp_buf, sizeof tmp_buf); + } +#endif +#ifndef OPENSSL_NO_KRB5 + else if (alg_k & SSL_kKRB5) { + krb5_error_code krb5rc; + KSSL_CTX *kssl_ctx = s->kssl_ctx; + /* krb5_data krb5_ap_req; */ + krb5_data *enc_ticket; + krb5_data authenticator, *authp = NULL; + EVP_CIPHER_CTX ciph_ctx; + const EVP_CIPHER *enc = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH]; + unsigned char epms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_IV_LENGTH]; + int padl, outl = sizeof(epms); + + EVP_CIPHER_CTX_init(&ciph_ctx); + +# ifdef KSSL_DEBUG + fprintf(stderr, "ssl3_send_client_key_exchange(%lx & %lx)\n", + alg_k, SSL_kKRB5); +# endif /* KSSL_DEBUG */ + + authp = NULL; +# ifdef KRB5SENDAUTH + if (KRB5SENDAUTH) + authp = &authenticator; +# endif /* KRB5SENDAUTH */ + + krb5rc = kssl_cget_tkt(kssl_ctx, &enc_ticket, authp, &kssl_err); + enc = kssl_map_enc(kssl_ctx->enctype); + if (enc == NULL) + goto err; +# ifdef KSSL_DEBUG + { + fprintf(stderr, "kssl_cget_tkt rtn %d\n", krb5rc); + if (krb5rc && kssl_err.text) + fprintf(stderr, "kssl_cget_tkt kssl_err=%s\n", + kssl_err.text); + } +# endif /* KSSL_DEBUG */ + + if (krb5rc) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, kssl_err.reason); + goto err; + } + + /*- + * 20010406 VRS - Earlier versions used KRB5 AP_REQ + * in place of RFC 2712 KerberosWrapper, as in: + * + * Send ticket (copy to *p, set n = length) + * n = krb5_ap_req.length; + * memcpy(p, krb5_ap_req.data, krb5_ap_req.length); + * if (krb5_ap_req.data) + * kssl_krb5_free_data_contents(NULL,&krb5_ap_req); + * + * Now using real RFC 2712 KerberosWrapper + * (Thanks to Simon Wilkinson ) + * Note: 2712 "opaque" types are here replaced + * with a 2-byte length followed by the value. + * Example: + * KerberosWrapper= xx xx asn1ticket 0 0 xx xx encpms + * Where "xx xx" = length bytes. Shown here with + * optional authenticator omitted. + */ + + /* KerberosWrapper.Ticket */ + s2n(enc_ticket->length, p); + memcpy(p, enc_ticket->data, enc_ticket->length); + p += enc_ticket->length; + n = enc_ticket->length + 2; + + /* KerberosWrapper.Authenticator */ + if (authp && authp->length) { + s2n(authp->length, p); + memcpy(p, authp->data, authp->length); + p += authp->length; + n += authp->length + 2; + + free(authp->data); + authp->data = NULL; + authp->length = 0; + } else { + s2n(0, p); /* null authenticator length */ + n += 2; + } + + tmp_buf[0] = s->client_version >> 8; + tmp_buf[1] = s->client_version & 0xff; + if (RAND_bytes(&(tmp_buf[2]), sizeof tmp_buf - 2) <= 0) + goto err; + + /*- + * 20010420 VRS. Tried it this way; failed. + * EVP_EncryptInit_ex(&ciph_ctx,enc, NULL,NULL); + * EVP_CIPHER_CTX_set_key_length(&ciph_ctx, + * kssl_ctx->length); + * EVP_EncryptInit_ex(&ciph_ctx,NULL, key,iv); + */ + + memset(iv, 0, sizeof iv); /* per RFC 1510 */ + EVP_EncryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv); + EVP_EncryptUpdate(&ciph_ctx, epms, &outl, tmp_buf, + sizeof tmp_buf); + EVP_EncryptFinal_ex(&ciph_ctx, &(epms[outl]), &padl); + outl += padl; + if (outl > (int)sizeof epms) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + /* KerberosWrapper.EncryptedPreMasterSecret */ + s2n(outl, p); + memcpy(p, epms, outl); + p += outl; + n += outl + 2; + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + tmp_buf, + sizeof tmp_buf); + + OPENSSL_cleanse(tmp_buf, sizeof tmp_buf); + OPENSSL_cleanse(epms, outl); + } +#endif +#ifndef OPENSSL_NO_DH + else if (alg_k & (SSL_kEDH | SSL_kDHr | SSL_kDHd)) { + DH *dh_srvr, *dh_clnt; + + if (s->session->sess_cert == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_UNEXPECTED_MESSAGE); + goto err; + } + + if (s->session->sess_cert->peer_dh_tmp != NULL) + dh_srvr = s->session->sess_cert->peer_dh_tmp; + else { + /* we get them from the cert */ + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_UNABLE_TO_FIND_DH_PARAMETERS); + goto err; + } + + /* generate a new random key */ + if ((dh_clnt = DHparams_dup(dh_srvr)) == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + if (!DH_generate_key(dh_clnt)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); + DH_free(dh_clnt); + goto err; + } + + /* + * use the 'p' output buffer for the DH key, but make sure to + * clear it out afterwards + */ + + n = DH_compute_key(p, dh_srvr->pub_key, dh_clnt); + + if (n <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); + DH_free(dh_clnt); + goto err; + } + + /* generate master key from the result */ + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + p, n); + /* clean up */ + memset(p, 0, n); + + /* send off the data */ + n = BN_num_bytes(dh_clnt->pub_key); + s2n(n, p); + BN_bn2bin(dh_clnt->pub_key, p); + n += 2; + + DH_free(dh_clnt); + } +#endif + +#ifndef OPENSSL_NO_ECDH + else if (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) { + const EC_GROUP *srvr_group = NULL; + EC_KEY *tkey; + int ecdh_clnt_cert = 0; + int field_size = 0; + + if (s->session->sess_cert == NULL) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_UNEXPECTED_MESSAGE); + goto err; + } + + /* + * Did we send out the client's ECDH share for use in premaster + * computation as part of client certificate? If so, set + * ecdh_clnt_cert to 1. + */ + if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->cert != NULL)) { + /*- + * XXX: For now, we do not support client + * authentication using ECDH certificates. + * To add such support, one needs to add + * code that checks for appropriate + * conditions and sets ecdh_clnt_cert to 1. + * For example, the cert have an ECC + * key on the same curve as the server's + * and the key should be authorized for + * key agreement. + * + * One also needs to add code in ssl3_connect + * to skip sending the certificate verify + * message. + * + * if ((s->cert->key->privatekey != NULL) && + * (s->cert->key->privatekey->type == + * EVP_PKEY_EC) && ...) + * ecdh_clnt_cert = 1; + */ + } + + if (s->session->sess_cert->peer_ecdh_tmp != NULL) { + tkey = s->session->sess_cert->peer_ecdh_tmp; + } else { + /* Get the Server Public Key from Cert */ + srvr_pub_pkey = + X509_get_pubkey(s->session-> + sess_cert->peer_pkeys[SSL_PKEY_ECC].x509); + if ((srvr_pub_pkey == NULL) + || (srvr_pub_pkey->type != EVP_PKEY_EC) + || (srvr_pub_pkey->pkey.ec == NULL)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + tkey = srvr_pub_pkey->pkey.ec; + } + + srvr_group = EC_KEY_get0_group(tkey); + srvr_ecpoint = EC_KEY_get0_public_key(tkey); + + if ((srvr_group == NULL) || (srvr_ecpoint == NULL)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if ((clnt_ecdh = EC_KEY_new()) == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_KEY_set_group(clnt_ecdh, srvr_group)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + if (ecdh_clnt_cert) { + /* + * Reuse key info from our certificate We only need our + * private key to perform the ECDH computation. + */ + const BIGNUM *priv_key; + tkey = s->cert->key->privatekey->pkey.ec; + priv_key = EC_KEY_get0_private_key(tkey); + if (priv_key == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + if (!EC_KEY_set_private_key(clnt_ecdh, priv_key)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + } else { + /* Generate a new ECDH key pair */ + if (!(EC_KEY_generate_key(clnt_ecdh))) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + } + + /* + * use the 'p' output buffer for the ECDH key, but make sure to + * clear it out afterwards + */ + + field_size = EC_GROUP_get_degree(srvr_group); + if (field_size <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + n = ECDH_compute_key(p, (field_size + 7) / 8, srvr_ecpoint, + clnt_ecdh, NULL); + if (n <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + /* generate master key from the result */ + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + p, n); + + memset(p, 0, n); /* clean up */ + + if (ecdh_clnt_cert) { + /* Send empty client key exch message */ + n = 0; + } else { + /* + * First check the size of encoding and allocate memory + * accordingly. + */ + encoded_pt_len = + EC_POINT_point2oct(srvr_group, + EC_KEY_get0_public_key(clnt_ecdh), + POINT_CONVERSION_UNCOMPRESSED, + NULL, 0, NULL); + + encodedPoint = (unsigned char *) + OPENSSL_malloc(encoded_pt_len * sizeof(unsigned char)); + bn_ctx = BN_CTX_new(); + if ((encodedPoint == NULL) || (bn_ctx == NULL)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Encode the public key */ + n = EC_POINT_point2oct(srvr_group, + EC_KEY_get0_public_key(clnt_ecdh), + POINT_CONVERSION_UNCOMPRESSED, + encodedPoint, encoded_pt_len, bn_ctx); + + *p = n; /* length of encoded point */ + /* Encoded point will be copied here */ + p += 1; + /* copy the point */ + memcpy((unsigned char *)p, encodedPoint, n); + /* increment n to account for length field */ + n += 1; + } + + /* Free allocated memory */ + BN_CTX_free(bn_ctx); + if (encodedPoint != NULL) + OPENSSL_free(encodedPoint); + if (clnt_ecdh != NULL) + EC_KEY_free(clnt_ecdh); + EVP_PKEY_free(srvr_pub_pkey); + } +#endif /* !OPENSSL_NO_ECDH */ + else if (alg_k & SSL_kGOST) { + /* GOST key exchange message creation */ + EVP_PKEY_CTX *pkey_ctx; + X509 *peer_cert; + size_t msglen; + unsigned int md_len; + int keytype; + unsigned char premaster_secret[32], shared_ukm[32], tmp[256]; + EVP_MD_CTX *ukm_hash; + EVP_PKEY *pub_key; + + /* + * Get server sertificate PKEY and create ctx from it + */ + peer_cert = + s->session-> + sess_cert->peer_pkeys[(keytype = SSL_PKEY_GOST01)].x509; + if (!peer_cert) + peer_cert = + s->session-> + sess_cert->peer_pkeys[(keytype = SSL_PKEY_GOST94)].x509; + if (!peer_cert) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER); + goto err; + } + + pkey_ctx = EVP_PKEY_CTX_new(pub_key = + X509_get_pubkey(peer_cert), NULL); + if (pkey_ctx == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + /* + * If we have send a certificate, and certificate key + * + * * parameters match those of server certificate, use + * certificate key for key exchange + */ + + /* Otherwise, generate ephemeral key pair */ + + if (pkey_ctx == NULL + || EVP_PKEY_encrypt_init(pkey_ctx) <= 0 + /* Generate session key */ + || RAND_bytes(premaster_secret, 32) <= 0) { + EVP_PKEY_CTX_free(pkey_ctx); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + /* + * If we have client certificate, use its secret as peer key + */ + if (s->s3->tmp.cert_req && s->cert->key->privatekey) { + if (EVP_PKEY_derive_set_peer + (pkey_ctx, s->cert->key->privatekey) <= 0) { + /* + * If there was an error - just ignore it. Ephemeral key + * * would be used + */ + ERR_clear_error(); + } + } + /* + * Compute shared IV and store it in algorithm-specific context + * data + */ + ukm_hash = EVP_MD_CTX_create(); + if (EVP_DigestInit(ukm_hash, + EVP_get_digestbynid(NID_id_GostR3411_94)) <= 0 + || EVP_DigestUpdate(ukm_hash, s->s3->client_random, + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestUpdate(ukm_hash, s->s3->server_random, + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestFinal_ex(ukm_hash, shared_ukm, &md_len) <= 0) { + EVP_MD_CTX_destroy(ukm_hash); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + EVP_MD_CTX_destroy(ukm_hash); + if (EVP_PKEY_CTX_ctrl + (pkey_ctx, -1, EVP_PKEY_OP_ENCRYPT, EVP_PKEY_CTRL_SET_IV, 8, + shared_ukm) < 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_LIBRARY_BUG); + goto err; + } + /* Make GOST keytransport blob message */ + /* + * Encapsulate it into sequence + */ + *(p++) = V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED; + msglen = 255; + if (EVP_PKEY_encrypt(pkey_ctx, tmp, &msglen, premaster_secret, 32) + <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_LIBRARY_BUG); + goto err; + } + if (msglen >= 0x80) { + *(p++) = 0x81; + *(p++) = msglen & 0xff; + n = msglen + 3; + } else { + *(p++) = msglen & 0xff; + n = msglen + 2; + } + memcpy(p, tmp, msglen); + /* Check if pubkey from client certificate was used */ + if (EVP_PKEY_CTX_ctrl + (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) { + /* Set flag "skip certificate verify" */ + s->s3->flags |= TLS1_FLAGS_SKIP_CERT_VERIFY; + } + EVP_PKEY_CTX_free(pkey_ctx); + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + premaster_secret, + 32); + EVP_PKEY_free(pub_key); + + } +#ifndef OPENSSL_NO_SRP + else if (alg_k & SSL_kSRP) { + if (s->srp_ctx.A != NULL) { + /* send off the data */ + n = BN_num_bytes(s->srp_ctx.A); + s2n(n, p); + BN_bn2bin(s->srp_ctx.A, p); + n += 2; + } else { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + if (s->session->srp_username != NULL) + OPENSSL_free(s->session->srp_username); + s->session->srp_username = BUF_strdup(s->srp_ctx.login); + if (s->session->srp_username == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if ((s->session->master_key_length = + SRP_generate_client_master_secret(s, + s->session->master_key)) < + 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + } +#endif +#ifndef OPENSSL_NO_PSK + else if (alg_k & SSL_kPSK) { + /* + * The callback needs PSK_MAX_IDENTITY_LEN + 1 bytes to return a + * \0-terminated identity. The last byte is for us for simulating + * strnlen. + */ + char identity[PSK_MAX_IDENTITY_LEN + 2]; + size_t identity_len; + unsigned char *t = NULL; + unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4]; + unsigned int pre_ms_len = 0, psk_len = 0; + int psk_err = 1; + + n = 0; + if (s->psk_client_callback == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_NO_CLIENT_CB); + goto err; + } + + memset(identity, 0, sizeof(identity)); + psk_len = s->psk_client_callback(s, s->session->psk_identity_hint, + identity, sizeof(identity) - 1, + psk_or_pre_ms, + sizeof(psk_or_pre_ms)); + if (psk_len > PSK_MAX_PSK_LEN) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto psk_err; + } else if (psk_len == 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_IDENTITY_NOT_FOUND); + goto psk_err; + } + identity[PSK_MAX_IDENTITY_LEN + 1] = '\0'; + identity_len = strlen(identity); + if (identity_len > PSK_MAX_IDENTITY_LEN) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto psk_err; + } + /* create PSK pre_master_secret */ + pre_ms_len = 2 + psk_len + 2 + psk_len; + t = psk_or_pre_ms; + memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len); + s2n(psk_len, t); + memset(t, 0, psk_len); + t += psk_len; + s2n(psk_len, t); + + if (s->session->psk_identity_hint != NULL) + OPENSSL_free(s->session->psk_identity_hint); + s->session->psk_identity_hint = + BUF_strdup(s->ctx->psk_identity_hint); + if (s->ctx->psk_identity_hint != NULL + && s->session->psk_identity_hint == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + if (s->session->psk_identity != NULL) + OPENSSL_free(s->session->psk_identity); + s->session->psk_identity = BUF_strdup(identity); + if (s->session->psk_identity == NULL) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + psk_or_pre_ms, + pre_ms_len); + s2n(identity_len, p); + memcpy(p, identity, identity_len); + n = 2 + identity_len; + psk_err = 0; + psk_err: + OPENSSL_cleanse(identity, sizeof(identity)); + OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); + if (psk_err != 0) { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + goto err; + } + } +#endif + else { + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + + *(d++) = SSL3_MT_CLIENT_KEY_EXCHANGE; + l2n3(n, d); + + s->state = SSL3_ST_CW_KEY_EXCH_B; + /* number of bytes to write */ + s->init_num = n + 4; + s->init_off = 0; + } + + /* SSL3_ST_CW_KEY_EXCH_B */ + return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); + err: +#ifndef OPENSSL_NO_ECDH + BN_CTX_free(bn_ctx); + if (encodedPoint != NULL) + OPENSSL_free(encodedPoint); + if (clnt_ecdh != NULL) + EC_KEY_free(clnt_ecdh); + EVP_PKEY_free(srvr_pub_pkey); +#endif + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_send_client_verify(SSL *s) +{ + unsigned char *p, *d; + unsigned char data[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; + EVP_PKEY *pkey; + EVP_PKEY_CTX *pctx = NULL; + EVP_MD_CTX mctx; + unsigned u = 0; + unsigned long n; + int j; + + EVP_MD_CTX_init(&mctx); + + if (s->state == SSL3_ST_CW_CERT_VRFY_A) { + d = (unsigned char *)s->init_buf->data; + p = &(d[4]); + pkey = s->cert->key->privatekey; +/* Create context from key and test if sha1 is allowed as digest */ + pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (pctx == NULL || EVP_PKEY_sign_init(pctx) <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + if (EVP_PKEY_CTX_set_signature_md(pctx, EVP_sha1()) > 0) { + if (TLS1_get_version(s) < TLS1_2_VERSION) + s->method->ssl3_enc->cert_verify_mac(s, + NID_sha1, + &(data + [MD5_DIGEST_LENGTH])); + } else { + ERR_clear_error(); + } + /* + * For TLS v1.2 send signature algorithm and signature using agreed + * digest and cached handshake records. + */ + if (TLS1_get_version(s) >= TLS1_2_VERSION) { + long hdatalen = 0; + void *hdata; + const EVP_MD *md = s->cert->key->digest; + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0 || !tls12_get_sigandhash(p, pkey, md)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + p += 2; +#ifdef SSL_DEBUG + fprintf(stderr, "Using TLS 1.2 with client alg %s\n", + EVP_MD_name(md)); +#endif + if (!EVP_SignInit_ex(&mctx, md, NULL) + || !EVP_SignUpdate(&mctx, hdata, hdatalen) + || !EVP_SignFinal(&mctx, p + 2, &u, pkey)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_EVP_LIB); + goto err; + } + s2n(u, p); + n = u + 4; + if (!ssl3_digest_cached_records(s)) + goto err; + } else +#ifndef OPENSSL_NO_RSA + if (pkey->type == EVP_PKEY_RSA) { + s->method->ssl3_enc->cert_verify_mac(s, NID_md5, &(data[0])); + if (RSA_sign(NID_md5_sha1, data, + MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, + &(p[2]), &u, pkey->pkey.rsa) <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_RSA_LIB); + goto err; + } + s2n(u, p); + n = u + 2; + } else +#endif +#ifndef OPENSSL_NO_DSA + if (pkey->type == EVP_PKEY_DSA) { + if (!DSA_sign(pkey->save_type, + &(data[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, &(p[2]), + (unsigned int *)&j, pkey->pkey.dsa)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_DSA_LIB); + goto err; + } + s2n(j, p); + n = j + 2; + } else +#endif +#ifndef OPENSSL_NO_ECDSA + if (pkey->type == EVP_PKEY_EC) { + if (!ECDSA_sign(pkey->save_type, + &(data[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, &(p[2]), + (unsigned int *)&j, pkey->pkey.ec)) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_ECDSA_LIB); + goto err; + } + s2n(j, p); + n = j + 2; + } else +#endif + if (pkey->type == NID_id_GostR3410_94 + || pkey->type == NID_id_GostR3410_2001) { + unsigned char signbuf[64]; + int i; + size_t sigsize = 64; + s->method->ssl3_enc->cert_verify_mac(s, + NID_id_GostR3411_94, data); + if (EVP_PKEY_sign(pctx, signbuf, &sigsize, data, 32) <= 0) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + for (i = 63, j = 0; i >= 0; j++, i--) { + p[2 + j] = signbuf[i]; + } + s2n(j, p); + n = j + 2; + } else { + SSLerr(SSL_F_SSL3_SEND_CLIENT_VERIFY, ERR_R_INTERNAL_ERROR); + goto err; + } + *(d++) = SSL3_MT_CERTIFICATE_VERIFY; + l2n3(n, d); + + s->state = SSL3_ST_CW_CERT_VRFY_B; + s->init_num = (int)n + 4; + s->init_off = 0; + } + EVP_MD_CTX_cleanup(&mctx); + EVP_PKEY_CTX_free(pctx); + return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); + err: + EVP_MD_CTX_cleanup(&mctx); + EVP_PKEY_CTX_free(pctx); + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_send_client_certificate(SSL *s) +{ + X509 *x509 = NULL; + EVP_PKEY *pkey = NULL; + int i; + unsigned long l; + + if (s->state == SSL3_ST_CW_CERT_A) { + if ((s->cert == NULL) || + (s->cert->key->x509 == NULL) || + (s->cert->key->privatekey == NULL)) + s->state = SSL3_ST_CW_CERT_B; + else + s->state = SSL3_ST_CW_CERT_C; + } + + /* We need to get a client cert */ + if (s->state == SSL3_ST_CW_CERT_B) { + /* + * If we get an error, we need to ssl->rwstate=SSL_X509_LOOKUP; + * return(-1); We then get retied later + */ + i = ssl_do_client_cert_cb(s, &x509, &pkey); + if (i < 0) { + s->rwstate = SSL_X509_LOOKUP; + return (-1); + } + s->rwstate = SSL_NOTHING; + if ((i == 1) && (pkey != NULL) && (x509 != NULL)) { + s->state = SSL3_ST_CW_CERT_B; + if (!SSL_use_certificate(s, x509) || !SSL_use_PrivateKey(s, pkey)) + i = 0; + } else if (i == 1) { + i = 0; + SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, + SSL_R_BAD_DATA_RETURNED_BY_CALLBACK); + } + + if (x509 != NULL) + X509_free(x509); + if (pkey != NULL) + EVP_PKEY_free(pkey); + if (i == 0) { + if (s->version == SSL3_VERSION) { + s->s3->tmp.cert_req = 0; + ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_CERTIFICATE); + return (1); + } else { + s->s3->tmp.cert_req = 2; + } + } + + /* Ok, we have a cert */ + s->state = SSL3_ST_CW_CERT_C; + } + + if (s->state == SSL3_ST_CW_CERT_C) { + s->state = SSL3_ST_CW_CERT_D; + l = ssl3_output_cert_chain(s, + (s->s3->tmp.cert_req == + 2) ? NULL : s->cert->key->x509); + if (!l) { + SSLerr(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE, ERR_R_INTERNAL_ERROR); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return 0; + } + s->init_num = (int)l; + s->init_off = 0; + } + /* SSL3_ST_CW_CERT_D */ + return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); +} + +#define has_bits(i,m) (((i)&(m)) == (m)) + +int ssl3_check_cert_and_algorithm(SSL *s) +{ + int i, idx; + long alg_k, alg_a; + EVP_PKEY *pkey = NULL; + int pkey_bits; + SESS_CERT *sc; +#ifndef OPENSSL_NO_RSA + RSA *rsa; +#endif +#ifndef OPENSSL_NO_DH + DH *dh; +#endif + int al = SSL_AD_HANDSHAKE_FAILURE; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + alg_a = s->s3->tmp.new_cipher->algorithm_auth; + + /* we don't have a certificate */ + if ((alg_a & (SSL_aDH | SSL_aNULL | SSL_aKRB5)) || (alg_k & SSL_kPSK)) + return (1); + + sc = s->session->sess_cert; + if (sc == NULL) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); + goto err; + } +#ifndef OPENSSL_NO_RSA + rsa = s->session->sess_cert->peer_rsa_tmp; +#endif +#ifndef OPENSSL_NO_DH + dh = s->session->sess_cert->peer_dh_tmp; +#endif + + /* This is the passed certificate */ + + idx = sc->peer_cert_type; +#ifndef OPENSSL_NO_ECDH + if (idx == SSL_PKEY_ECC) { + if (ssl_check_srvr_ecc_cert_and_alg(sc->peer_pkeys[idx].x509, s) == 0) { + /* check failed */ + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_BAD_ECC_CERT); + goto f_err; + } else { + return 1; + } + } +#endif + pkey = X509_get_pubkey(sc->peer_pkeys[idx].x509); + pkey_bits = EVP_PKEY_bits(pkey); + i = X509_certificate_type(sc->peer_pkeys[idx].x509, pkey); + EVP_PKEY_free(pkey); + + /* Check that we have a certificate if we require one */ + if ((alg_a & SSL_aRSA) && !has_bits(i, EVP_PK_RSA | EVP_PKT_SIGN)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_RSA_SIGNING_CERT); + goto f_err; + } +#ifndef OPENSSL_NO_DSA + else if ((alg_a & SSL_aDSS) && !has_bits(i, EVP_PK_DSA | EVP_PKT_SIGN)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_DSA_SIGNING_CERT); + goto f_err; + } +#endif +#ifndef OPENSSL_NO_RSA + if (alg_k & SSL_kRSA) { + if (!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && + !has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_RSA_ENCRYPTING_CERT); + goto f_err; + } else if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher)) { + if (pkey_bits <= SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { + if (!has_bits(i, EVP_PK_RSA | EVP_PKT_ENC)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_RSA_ENCRYPTING_CERT); + goto f_err; + } + if (rsa != NULL) { + /* server key exchange is not allowed. */ + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); + goto f_err; + } + } + } + } +#endif +#ifndef OPENSSL_NO_DH + if ((alg_k & SSL_kEDH) && dh == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, ERR_R_INTERNAL_ERROR); + goto f_err; + } + if ((alg_k & SSL_kDHr) && !has_bits(i, EVP_PK_DH | EVP_PKS_RSA)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_DH_RSA_CERT); + goto f_err; + } +# ifndef OPENSSL_NO_DSA + if ((alg_k & SSL_kDHd) && !has_bits(i, EVP_PK_DH | EVP_PKS_DSA)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_DH_DSA_CERT); + goto f_err; + } +# endif + + /* Check DHE only: static DH not implemented. */ + if (alg_k & SSL_kEDH) { + int dh_size = BN_num_bits(dh->p); + if ((!SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 1024) + || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && dh_size < 512)) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, SSL_R_DH_KEY_TOO_SMALL); + goto f_err; + } + } +#endif /* !OPENSSL_NO_DH */ + + if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && + pkey_bits > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { +#ifndef OPENSSL_NO_RSA + if (alg_k & SSL_kRSA) { + if (rsa == NULL) { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_EXPORT_TMP_RSA_KEY); + goto f_err; + } else if (BN_num_bits(rsa->n) > + SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { + /* We have a temporary RSA key but it's too large. */ + al = SSL_AD_EXPORT_RESTRICTION; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_EXPORT_TMP_RSA_KEY); + goto f_err; + } + } else +#endif +#ifndef OPENSSL_NO_DH + if (alg_k & SSL_kEDH) { + if (BN_num_bits(dh->p) > + SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher)) { + /* We have a temporary DH key but it's too large. */ + al = SSL_AD_EXPORT_RESTRICTION; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_EXPORT_TMP_DH_KEY); + goto f_err; + } + } else if (alg_k & (SSL_kDHr | SSL_kDHd)) { + /* The cert should have had an export DH key. */ + al = SSL_AD_EXPORT_RESTRICTION; + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_MISSING_EXPORT_TMP_DH_KEY); + goto f_err; + } else +#endif + { + SSLerr(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM, + SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); + goto f_err; + } + } + return (1); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (0); +} + +#ifndef OPENSSL_NO_TLSEXT +/* + * Normally, we can tell if the server is resuming the session from + * the session ID. EAP-FAST (RFC 4851), however, relies on the next server + * message after the ServerHello to determine if the server is resuming. + * Therefore, we allow EAP-FAST to peek ahead. + * ssl3_check_finished returns 1 if we are resuming from an external + * pre-shared secret, we have a "ticket" and the next server handshake message + * is Finished; and 0 otherwise. It returns -1 upon an error. + */ +static int ssl3_check_finished(SSL *s) +{ + int ok = 0; + + if (s->version < TLS1_VERSION || !s->tls_session_secret_cb || + !s->session->tlsext_tick) + return 0; + + /* Need to permit this temporarily, in case the next message is Finished. */ + s->s3->flags |= SSL3_FLAGS_CCS_OK; + /* + * This function is called when we might get a Certificate message instead, + * so permit appropriate message length. + * We ignore the return value as we're only interested in the message type + * and not its length. + */ + s->method->ssl_get_message(s, + SSL3_ST_CR_CERT_A, + SSL3_ST_CR_CERT_B, + -1, s->max_cert_list, &ok); + s->s3->flags &= ~SSL3_FLAGS_CCS_OK; + + if (!ok) + return -1; + + s->s3->tmp.reuse_message = 1; + + if (s->s3->tmp.message_type == SSL3_MT_FINISHED) + return 1; + + /* If we're not done, then the CCS arrived early and we should bail. */ + if (s->s3->change_cipher_spec) { + SSLerr(SSL_F_SSL3_CHECK_FINISHED, SSL_R_CCS_RECEIVED_EARLY); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return -1; + } + + return 0; +} + +# ifndef OPENSSL_NO_NEXTPROTONEG +int ssl3_send_next_proto(SSL *s) +{ + unsigned int len, padding_len; + unsigned char *d; + + if (s->state == SSL3_ST_CW_NEXT_PROTO_A) { + len = s->next_proto_negotiated_len; + padding_len = 32 - ((len + 2) % 32); + d = (unsigned char *)s->init_buf->data; + d[4] = len; + memcpy(d + 5, s->next_proto_negotiated, len); + d[5 + len] = padding_len; + memset(d + 6 + len, 0, padding_len); + *(d++) = SSL3_MT_NEXT_PROTO; + l2n3(2 + len + padding_len, d); + s->state = SSL3_ST_CW_NEXT_PROTO_B; + s->init_num = 4 + 2 + len + padding_len; + s->init_off = 0; + } + + return ssl3_do_write(s, SSL3_RT_HANDSHAKE); +} +#endif /* !OPENSSL_NO_NEXTPROTONEG */ +#endif /* !OPENSSL_NO_TLSEXT */ + +int ssl_do_client_cert_cb(SSL *s, X509 **px509, EVP_PKEY **ppkey) +{ + int i = 0; +#ifndef OPENSSL_NO_ENGINE + if (s->ctx->client_cert_engine) { + i = ENGINE_load_ssl_client_cert(s->ctx->client_cert_engine, s, + SSL_get_client_CA_list(s), + px509, ppkey, NULL, NULL, NULL); + if (i != 0) + return i; + } +#endif + if (s->ctx->client_cert_cb) + i = s->ctx->client_cert_cb(s, px509, ppkey); + return i; +} diff --git a/libs/openssl/ssl/s3_enc.c b/libs/openssl/ssl/s3_enc.c new file mode 100644 index 00000000..85ebac8d --- /dev/null +++ b/libs/openssl/ssl/s3_enc.c @@ -0,0 +1,934 @@ +/* ssl/s3_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include "ssl_locl.h" +#include +#include + +static unsigned char ssl3_pad_1[48] = { + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, + 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36 +}; + +static unsigned char ssl3_pad_2[48] = { + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, + 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c +}; + +static int ssl3_handshake_mac(SSL *s, int md_nid, + const char *sender, int len, unsigned char *p); +static int ssl3_generate_key_block(SSL *s, unsigned char *km, int num) +{ + EVP_MD_CTX m5; + EVP_MD_CTX s1; + unsigned char buf[16], smd[SHA_DIGEST_LENGTH]; + unsigned char c = 'A'; + unsigned int i, j, k; + +#ifdef CHARSET_EBCDIC + c = os_toascii[c]; /* 'A' in ASCII */ +#endif + k = 0; + EVP_MD_CTX_init(&m5); + EVP_MD_CTX_set_flags(&m5, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + EVP_MD_CTX_init(&s1); + for (i = 0; (int)i < num; i += MD5_DIGEST_LENGTH) { + k++; + if (k > sizeof buf) { + /* bug: 'buf' is too small for this ciphersuite */ + SSLerr(SSL_F_SSL3_GENERATE_KEY_BLOCK, ERR_R_INTERNAL_ERROR); + return 0; + } + + for (j = 0; j < k; j++) + buf[j] = c; + c++; + EVP_DigestInit_ex(&s1, EVP_sha1(), NULL); + EVP_DigestUpdate(&s1, buf, k); + EVP_DigestUpdate(&s1, s->session->master_key, + s->session->master_key_length); + EVP_DigestUpdate(&s1, s->s3->server_random, SSL3_RANDOM_SIZE); + EVP_DigestUpdate(&s1, s->s3->client_random, SSL3_RANDOM_SIZE); + EVP_DigestFinal_ex(&s1, smd, NULL); + + EVP_DigestInit_ex(&m5, EVP_md5(), NULL); + EVP_DigestUpdate(&m5, s->session->master_key, + s->session->master_key_length); + EVP_DigestUpdate(&m5, smd, SHA_DIGEST_LENGTH); + if ((int)(i + MD5_DIGEST_LENGTH) > num) { + EVP_DigestFinal_ex(&m5, smd, NULL); + memcpy(km, smd, (num - i)); + } else + EVP_DigestFinal_ex(&m5, km, NULL); + + km += MD5_DIGEST_LENGTH; + } + OPENSSL_cleanse(smd, SHA_DIGEST_LENGTH); + EVP_MD_CTX_cleanup(&m5); + EVP_MD_CTX_cleanup(&s1); + return 1; +} + +int ssl3_change_cipher_state(SSL *s, int which) +{ + unsigned char *p, *mac_secret; + unsigned char exp_key[EVP_MAX_KEY_LENGTH]; + unsigned char exp_iv[EVP_MAX_IV_LENGTH]; + unsigned char *ms, *key, *iv, *er1, *er2; + EVP_CIPHER_CTX *dd; + const EVP_CIPHER *c; +#ifndef OPENSSL_NO_COMP + COMP_METHOD *comp; +#endif + const EVP_MD *m; + EVP_MD_CTX md; + int is_exp, n, i, j, k, cl; + int reuse_dd = 0; + + is_exp = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); + c = s->s3->tmp.new_sym_enc; + m = s->s3->tmp.new_hash; + /* m == NULL will lead to a crash later */ + OPENSSL_assert(m); +#ifndef OPENSSL_NO_COMP + if (s->s3->tmp.new_compression == NULL) + comp = NULL; + else + comp = s->s3->tmp.new_compression->method; +#endif + + if (which & SSL3_CC_READ) { + if (s->enc_read_ctx != NULL) + reuse_dd = 1; + else if ((s->enc_read_ctx = + OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) + goto err; + else + /* + * make sure it's intialized in case we exit later with an error + */ + EVP_CIPHER_CTX_init(s->enc_read_ctx); + dd = s->enc_read_ctx; + + if (ssl_replace_hash(&s->read_hash, m) == NULL) { + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } +#ifndef OPENSSL_NO_COMP + /* COMPRESS */ + if (s->expand != NULL) { + COMP_CTX_free(s->expand); + s->expand = NULL; + } + if (comp != NULL) { + s->expand = COMP_CTX_new(comp); + if (s->expand == NULL) { + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, + SSL_R_COMPRESSION_LIBRARY_ERROR); + goto err2; + } + if (s->s3->rrec.comp == NULL) + s->s3->rrec.comp = (unsigned char *) + OPENSSL_malloc(SSL3_RT_MAX_PLAIN_LENGTH); + if (s->s3->rrec.comp == NULL) + goto err; + } +#endif + memset(&(s->s3->read_sequence[0]), 0, 8); + mac_secret = &(s->s3->read_mac_secret[0]); + } else { + if (s->enc_write_ctx != NULL) + reuse_dd = 1; + else if ((s->enc_write_ctx = + OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) + goto err; + else + /* + * make sure it's intialized in case we exit later with an error + */ + EVP_CIPHER_CTX_init(s->enc_write_ctx); + dd = s->enc_write_ctx; + if (ssl_replace_hash(&s->write_hash, m) == NULL) { + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } +#ifndef OPENSSL_NO_COMP + /* COMPRESS */ + if (s->compress != NULL) { + COMP_CTX_free(s->compress); + s->compress = NULL; + } + if (comp != NULL) { + s->compress = COMP_CTX_new(comp); + if (s->compress == NULL) { + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, + SSL_R_COMPRESSION_LIBRARY_ERROR); + goto err2; + } + } +#endif + memset(&(s->s3->write_sequence[0]), 0, 8); + mac_secret = &(s->s3->write_mac_secret[0]); + } + + if (reuse_dd) + EVP_CIPHER_CTX_cleanup(dd); + + p = s->s3->tmp.key_block; + i = EVP_MD_size(m); + if (i < 0) + goto err2; + cl = EVP_CIPHER_key_length(c); + j = is_exp ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? + cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; + /* Was j=(is_exp)?5:EVP_CIPHER_key_length(c); */ + k = EVP_CIPHER_iv_length(c); + if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || + (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { + ms = &(p[0]); + n = i + i; + key = &(p[n]); + n += j + j; + iv = &(p[n]); + n += k + k; + er1 = &(s->s3->client_random[0]); + er2 = &(s->s3->server_random[0]); + } else { + n = i; + ms = &(p[n]); + n += i + j; + key = &(p[n]); + n += j + k; + iv = &(p[n]); + n += k; + er1 = &(s->s3->server_random[0]); + er2 = &(s->s3->client_random[0]); + } + + if (n > s->s3->tmp.key_block_length) { + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } + + EVP_MD_CTX_init(&md); + memcpy(mac_secret, ms, i); + if (is_exp) { + /* + * In here I set both the read and write key/iv to the same value + * since only the correct one will be used :-). + */ + EVP_DigestInit_ex(&md, EVP_md5(), NULL); + EVP_DigestUpdate(&md, key, j); + EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE); + EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE); + EVP_DigestFinal_ex(&md, &(exp_key[0]), NULL); + key = &(exp_key[0]); + + if (k > 0) { + EVP_DigestInit_ex(&md, EVP_md5(), NULL); + EVP_DigestUpdate(&md, er1, SSL3_RANDOM_SIZE); + EVP_DigestUpdate(&md, er2, SSL3_RANDOM_SIZE); + EVP_DigestFinal_ex(&md, &(exp_iv[0]), NULL); + iv = &(exp_iv[0]); + } + } + + s->session->key_arg_length = 0; + + EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE)); + + OPENSSL_cleanse(&(exp_key[0]), sizeof(exp_key)); + OPENSSL_cleanse(&(exp_iv[0]), sizeof(exp_iv)); + EVP_MD_CTX_cleanup(&md); + return (1); + err: + SSLerr(SSL_F_SSL3_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); + err2: + return (0); +} + +int ssl3_setup_key_block(SSL *s) +{ + unsigned char *p; + const EVP_CIPHER *c; + const EVP_MD *hash; + int num; + int ret = 0; + SSL_COMP *comp; + + if (s->s3->tmp.key_block_length != 0) + return (1); + + if (!ssl_cipher_get_evp(s->session, &c, &hash, NULL, NULL, &comp)) { + SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + return (0); + } + + s->s3->tmp.new_sym_enc = c; + s->s3->tmp.new_hash = hash; +#ifdef OPENSSL_NO_COMP + s->s3->tmp.new_compression = NULL; +#else + s->s3->tmp.new_compression = comp; +#endif + + num = EVP_MD_size(hash); + if (num < 0) + return 0; + + num = EVP_CIPHER_key_length(c) + num + EVP_CIPHER_iv_length(c); + num *= 2; + + ssl3_cleanup_key_block(s); + + if ((p = OPENSSL_malloc(num)) == NULL) + goto err; + + s->s3->tmp.key_block_length = num; + s->s3->tmp.key_block = p; + + ret = ssl3_generate_key_block(s, p, num); + + if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)) { + /* + * enable vulnerability countermeasure for CBC ciphers with known-IV + * problem (http://www.openssl.org/~bodo/tls-cbc.txt) + */ + s->s3->need_empty_fragments = 1; + + if (s->session->cipher != NULL) { + if (s->session->cipher->algorithm_enc == SSL_eNULL) + s->s3->need_empty_fragments = 0; + +#ifndef OPENSSL_NO_RC4 + if (s->session->cipher->algorithm_enc == SSL_RC4) + s->s3->need_empty_fragments = 0; +#endif + } + } + + return ret; + + err: + SSLerr(SSL_F_SSL3_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); + return (0); +} + +void ssl3_cleanup_key_block(SSL *s) +{ + if (s->s3->tmp.key_block != NULL) { + OPENSSL_cleanse(s->s3->tmp.key_block, s->s3->tmp.key_block_length); + OPENSSL_free(s->s3->tmp.key_block); + s->s3->tmp.key_block = NULL; + } + s->s3->tmp.key_block_length = 0; +} + +/*- + * ssl3_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. + * + * Returns: + * 0: (in non-constant time) if the record is publically invalid (i.e. too + * short etc). + * 1: if the record's padding is valid / the encryption was successful. + * -1: if the record's padding is invalid or, if sending, an internal error + * occured. + */ +int ssl3_enc(SSL *s, int send) +{ + SSL3_RECORD *rec; + EVP_CIPHER_CTX *ds; + unsigned long l; + int bs, i, mac_size = 0; + const EVP_CIPHER *enc; + + if (send) { + ds = s->enc_write_ctx; + rec = &(s->s3->wrec); + if (s->enc_write_ctx == NULL) + enc = NULL; + else + enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); + } else { + ds = s->enc_read_ctx; + rec = &(s->s3->rrec); + if (s->enc_read_ctx == NULL) + enc = NULL; + else + enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); + } + + if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { + memmove(rec->data, rec->input, rec->length); + rec->input = rec->data; + } else { + l = rec->length; + bs = EVP_CIPHER_block_size(ds->cipher); + + /* COMPRESS */ + + if ((bs != 1) && send) { + i = bs - ((int)l % bs); + + /* we need to add 'i-1' padding bytes */ + l += i; + /* + * the last of these zero bytes will be overwritten with the + * padding length. + */ + memset(&rec->input[rec->length], 0, i); + rec->length += i; + rec->input[l - 1] = (i - 1); + } + + if (!send) { + if (l == 0 || l % bs != 0) + return 0; + /* otherwise, rec->length >= bs */ + } + + if (EVP_Cipher(ds, rec->data, rec->input, l) < 1) + return -1; + + if (EVP_MD_CTX_md(s->read_hash) != NULL) + mac_size = EVP_MD_CTX_size(s->read_hash); + if ((bs != 1) && !send) + return ssl3_cbc_remove_padding(s, rec, bs, mac_size); + } + return (1); +} + +void ssl3_init_finished_mac(SSL *s) +{ + if (s->s3->handshake_buffer) + BIO_free(s->s3->handshake_buffer); + if (s->s3->handshake_dgst) + ssl3_free_digest_list(s); + s->s3->handshake_buffer = BIO_new(BIO_s_mem()); + (void)BIO_set_close(s->s3->handshake_buffer, BIO_CLOSE); +} + +void ssl3_free_digest_list(SSL *s) +{ + int i; + if (!s->s3->handshake_dgst) + return; + for (i = 0; i < SSL_MAX_DIGEST; i++) { + if (s->s3->handshake_dgst[i]) + EVP_MD_CTX_destroy(s->s3->handshake_dgst[i]); + } + OPENSSL_free(s->s3->handshake_dgst); + s->s3->handshake_dgst = NULL; +} + +void ssl3_finish_mac(SSL *s, const unsigned char *buf, int len) +{ + if (s->s3->handshake_buffer + && !(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) { + BIO_write(s->s3->handshake_buffer, (void *)buf, len); + } else { + int i; + for (i = 0; i < SSL_MAX_DIGEST; i++) { + if (s->s3->handshake_dgst[i] != NULL) + EVP_DigestUpdate(s->s3->handshake_dgst[i], buf, len); + } + } +} + +int ssl3_digest_cached_records(SSL *s) +{ + int i; + long mask; + const EVP_MD *md; + long hdatalen; + void *hdata; + + /* Allocate handshake_dgst array */ + ssl3_free_digest_list(s); + s->s3->handshake_dgst = + OPENSSL_malloc(SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *)); + memset(s->s3->handshake_dgst, 0, SSL_MAX_DIGEST * sizeof(EVP_MD_CTX *)); + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0) { + SSLerr(SSL_F_SSL3_DIGEST_CACHED_RECORDS, SSL_R_BAD_HANDSHAKE_LENGTH); + return 0; + } + + /* Loop through bitso of algorithm2 field and create MD_CTX-es */ + for (i = 0; ssl_get_handshake_digest(i, &mask, &md); i++) { + if ((mask & ssl_get_algorithm2(s)) && md) { + s->s3->handshake_dgst[i] = EVP_MD_CTX_create(); +#ifdef OPENSSL_FIPS + if (EVP_MD_nid(md) == NID_md5) { + EVP_MD_CTX_set_flags(s->s3->handshake_dgst[i], + EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + } +#endif + EVP_DigestInit_ex(s->s3->handshake_dgst[i], md, NULL); + EVP_DigestUpdate(s->s3->handshake_dgst[i], hdata, hdatalen); + } else { + s->s3->handshake_dgst[i] = NULL; + } + } + if (!(s->s3->flags & TLS1_FLAGS_KEEP_HANDSHAKE)) { + /* Free handshake_buffer BIO */ + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; + } + + return 1; +} + +int ssl3_cert_verify_mac(SSL *s, int md_nid, unsigned char *p) +{ + return (ssl3_handshake_mac(s, md_nid, NULL, 0, p)); +} + +int ssl3_final_finish_mac(SSL *s, + const char *sender, int len, unsigned char *p) +{ + int ret, sha1len; + ret = ssl3_handshake_mac(s, NID_md5, sender, len, p); + if (ret == 0) + return 0; + + p += ret; + + sha1len = ssl3_handshake_mac(s, NID_sha1, sender, len, p); + if (sha1len == 0) + return 0; + + ret += sha1len; + return (ret); +} + +static int ssl3_handshake_mac(SSL *s, int md_nid, + const char *sender, int len, unsigned char *p) +{ + unsigned int ret; + int npad, n; + unsigned int i; + unsigned char md_buf[EVP_MAX_MD_SIZE]; + EVP_MD_CTX ctx, *d = NULL; + + if (s->s3->handshake_buffer) + if (!ssl3_digest_cached_records(s)) + return 0; + + /* + * Search for digest of specified type in the handshake_dgst array + */ + for (i = 0; i < SSL_MAX_DIGEST; i++) { + if (s->s3->handshake_dgst[i] + && EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) { + d = s->s3->handshake_dgst[i]; + break; + } + } + if (!d) { + SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, SSL_R_NO_REQUIRED_DIGEST); + return 0; + } + EVP_MD_CTX_init(&ctx); + EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + EVP_MD_CTX_copy_ex(&ctx, d); + n = EVP_MD_CTX_size(&ctx); + if (n < 0) + return 0; + + npad = (48 / n) * n; + if ((sender != NULL && EVP_DigestUpdate(&ctx, sender, len) <= 0) + || EVP_DigestUpdate(&ctx, s->session->master_key, + s->session->master_key_length) <= 0 + || EVP_DigestUpdate(&ctx, ssl3_pad_1, npad) <= 0 + || EVP_DigestFinal_ex(&ctx, md_buf, &i) <= 0 + + || EVP_DigestInit_ex(&ctx, EVP_MD_CTX_md(&ctx), NULL) <= 0 + || EVP_DigestUpdate(&ctx, s->session->master_key, + s->session->master_key_length) <= 0 + || EVP_DigestUpdate(&ctx, ssl3_pad_2, npad) <= 0 + || EVP_DigestUpdate(&ctx, md_buf, i) <= 0 + || EVP_DigestFinal_ex(&ctx, p, &ret) <= 0) { + SSLerr(SSL_F_SSL3_HANDSHAKE_MAC, ERR_R_INTERNAL_ERROR); + ret = 0; + } + + EVP_MD_CTX_cleanup(&ctx); + + return ((int)ret); +} + +int n_ssl3_mac(SSL *ssl, unsigned char *md, int send) +{ + SSL3_RECORD *rec; + unsigned char *mac_sec, *seq; + EVP_MD_CTX md_ctx; + const EVP_MD_CTX *hash; + unsigned char *p, rec_char; + size_t md_size, orig_len; + int npad; + int t; + + if (send) { + rec = &(ssl->s3->wrec); + mac_sec = &(ssl->s3->write_mac_secret[0]); + seq = &(ssl->s3->write_sequence[0]); + hash = ssl->write_hash; + } else { + rec = &(ssl->s3->rrec); + mac_sec = &(ssl->s3->read_mac_secret[0]); + seq = &(ssl->s3->read_sequence[0]); + hash = ssl->read_hash; + } + + t = EVP_MD_CTX_size(hash); + if (t < 0) + return -1; + md_size = t; + npad = (48 / md_size) * md_size; + + /* + * kludge: ssl3_cbc_remove_padding passes padding length in rec->type + */ + orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8); + rec->type &= 0xff; + + if (!send && + EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && + ssl3_cbc_record_digest_supported(hash)) { + /* + * This is a CBC-encrypted record. We must avoid leaking any + * timing-side channel information about how many blocks of data we + * are hashing because that gives an attacker a timing-oracle. + */ + + /*- + * npad is, at most, 48 bytes and that's with MD5: + * 16 + 48 + 8 (sequence bytes) + 1 + 2 = 75. + * + * With SHA-1 (the largest hash speced for SSLv3) the hash size + * goes up 4, but npad goes down by 8, resulting in a smaller + * total size. + */ + unsigned char header[75]; + unsigned j = 0; + memcpy(header + j, mac_sec, md_size); + j += md_size; + memcpy(header + j, ssl3_pad_1, npad); + j += npad; + memcpy(header + j, seq, 8); + j += 8; + header[j++] = rec->type; + header[j++] = rec->length >> 8; + header[j++] = rec->length & 0xff; + + /* Final param == is SSLv3 */ + if (ssl3_cbc_digest_record(hash, + md, &md_size, + header, rec->input, + rec->length + md_size, orig_len, + mac_sec, md_size, 1) <= 0) + return -1; + } else { + unsigned int md_size_u; + /* Chop the digest off the end :-) */ + EVP_MD_CTX_init(&md_ctx); + + rec_char = rec->type; + p = md; + s2n(rec->length, p); + if (EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0 + || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0 + || EVP_DigestUpdate(&md_ctx, ssl3_pad_1, npad) <= 0 + || EVP_DigestUpdate(&md_ctx, seq, 8) <= 0 + || EVP_DigestUpdate(&md_ctx, &rec_char, 1) <= 0 + || EVP_DigestUpdate(&md_ctx, md, 2) <= 0 + || EVP_DigestUpdate(&md_ctx, rec->input, rec->length) <= 0 + || EVP_DigestFinal_ex(&md_ctx, md, NULL) <= 0 + || EVP_MD_CTX_copy_ex(&md_ctx, hash) <= 0 + || EVP_DigestUpdate(&md_ctx, mac_sec, md_size) <= 0 + || EVP_DigestUpdate(&md_ctx, ssl3_pad_2, npad) <= 0 + || EVP_DigestUpdate(&md_ctx, md, md_size) <= 0 + || EVP_DigestFinal_ex(&md_ctx, md, &md_size_u) <= 0) { + EVP_MD_CTX_cleanup(&md_ctx); + return -1; + } + md_size = md_size_u; + + EVP_MD_CTX_cleanup(&md_ctx); + } + + ssl3_record_sequence_update(seq); + return (md_size); +} + +void ssl3_record_sequence_update(unsigned char *seq) +{ + int i; + + for (i = 7; i >= 0; i--) { + ++seq[i]; + if (seq[i] != 0) + break; + } +} + +int ssl3_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, + int len) +{ + static const unsigned char *salt[3] = { +#ifndef CHARSET_EBCDIC + (const unsigned char *)"A", + (const unsigned char *)"BB", + (const unsigned char *)"CCC", +#else + (const unsigned char *)"\x41", + (const unsigned char *)"\x42\x42", + (const unsigned char *)"\x43\x43\x43", +#endif + }; + unsigned char buf[EVP_MAX_MD_SIZE]; + EVP_MD_CTX ctx; + int i, ret = 0; + unsigned int n; + + EVP_MD_CTX_init(&ctx); + for (i = 0; i < 3; i++) { + if (EVP_DigestInit_ex(&ctx, s->ctx->sha1, NULL) <= 0 + || EVP_DigestUpdate(&ctx, salt[i], + strlen((const char *)salt[i])) <= 0 + || EVP_DigestUpdate(&ctx, p, len) <= 0 + || EVP_DigestUpdate(&ctx, &(s->s3->client_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestUpdate(&ctx, &(s->s3->server_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestFinal_ex(&ctx, buf, &n) <= 0 + + || EVP_DigestInit_ex(&ctx, s->ctx->md5, NULL) <= 0 + || EVP_DigestUpdate(&ctx, p, len) <= 0 + || EVP_DigestUpdate(&ctx, buf, n) <= 0 + || EVP_DigestFinal_ex(&ctx, out, &n) <= 0) { + SSLerr(SSL_F_SSL3_GENERATE_MASTER_SECRET, ERR_R_INTERNAL_ERROR); + ret = 0; + break; + } + out += n; + ret += n; + } + EVP_MD_CTX_cleanup(&ctx); + OPENSSL_cleanse(buf, sizeof buf); + return (ret); +} + +int ssl3_alert_code(int code) +{ + switch (code) { + case SSL_AD_CLOSE_NOTIFY: + return (SSL3_AD_CLOSE_NOTIFY); + case SSL_AD_UNEXPECTED_MESSAGE: + return (SSL3_AD_UNEXPECTED_MESSAGE); + case SSL_AD_BAD_RECORD_MAC: + return (SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_DECRYPTION_FAILED: + return (SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_RECORD_OVERFLOW: + return (SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_DECOMPRESSION_FAILURE: + return (SSL3_AD_DECOMPRESSION_FAILURE); + case SSL_AD_HANDSHAKE_FAILURE: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_NO_CERTIFICATE: + return (SSL3_AD_NO_CERTIFICATE); + case SSL_AD_BAD_CERTIFICATE: + return (SSL3_AD_BAD_CERTIFICATE); + case SSL_AD_UNSUPPORTED_CERTIFICATE: + return (SSL3_AD_UNSUPPORTED_CERTIFICATE); + case SSL_AD_CERTIFICATE_REVOKED: + return (SSL3_AD_CERTIFICATE_REVOKED); + case SSL_AD_CERTIFICATE_EXPIRED: + return (SSL3_AD_CERTIFICATE_EXPIRED); + case SSL_AD_CERTIFICATE_UNKNOWN: + return (SSL3_AD_CERTIFICATE_UNKNOWN); + case SSL_AD_ILLEGAL_PARAMETER: + return (SSL3_AD_ILLEGAL_PARAMETER); + case SSL_AD_UNKNOWN_CA: + return (SSL3_AD_BAD_CERTIFICATE); + case SSL_AD_ACCESS_DENIED: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_DECODE_ERROR: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_DECRYPT_ERROR: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_EXPORT_RESTRICTION: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_PROTOCOL_VERSION: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_INSUFFICIENT_SECURITY: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_INTERNAL_ERROR: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_USER_CANCELLED: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_NO_RENEGOTIATION: + return (-1); /* Don't send it :-) */ + case SSL_AD_UNSUPPORTED_EXTENSION: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_CERTIFICATE_UNOBTAINABLE: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_UNRECOGNIZED_NAME: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_UNKNOWN_PSK_IDENTITY: + return (TLS1_AD_UNKNOWN_PSK_IDENTITY); + case SSL_AD_INAPPROPRIATE_FALLBACK: + return (TLS1_AD_INAPPROPRIATE_FALLBACK); + default: + return (-1); + } +} diff --git a/libs/openssl/ssl/s3_lib.c b/libs/openssl/ssl/s3_lib.c new file mode 100644 index 00000000..35d6587d --- /dev/null +++ b/libs/openssl/ssl/s3_lib.c @@ -0,0 +1,4366 @@ +/* ssl/s3_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include +#include "ssl_locl.h" +#include "kssl_lcl.h" +#ifndef OPENSSL_NO_TLSEXT +# ifndef OPENSSL_NO_EC +# include "../crypto/ec/ec_lcl.h" +# endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_NO_TLSEXT */ +#include +#ifndef OPENSSL_NO_DH +# include +#endif + +const char ssl3_version_str[] = "SSLv3" OPENSSL_VERSION_PTEXT; + +#define SSL3_NUM_CIPHERS (sizeof(ssl3_ciphers)/sizeof(SSL_CIPHER)) + +/* list of available SSLv3 ciphers (sorted by id) */ +OPENSSL_GLOBAL SSL_CIPHER ssl3_ciphers[] = { + +/* The RSA ciphers */ +/* Cipher 01 */ + { + 1, + SSL3_TXT_RSA_NULL_MD5, + SSL3_CK_RSA_NULL_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_EXP | SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + +/* Cipher 02 */ + { + 1, + SSL3_TXT_RSA_NULL_SHA, + SSL3_CK_RSA_NULL_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + +/* Cipher 03 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_RSA_RC4_40_MD5, + SSL3_CK_RSA_RC4_40_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +#endif + +/* Cipher 04 */ + { + 1, + SSL3_TXT_RSA_RC4_128_MD5, + SSL3_CK_RSA_RC4_128_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 05 */ + { + 1, + SSL3_TXT_RSA_RC4_128_SHA, + SSL3_CK_RSA_RC4_128_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 06 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_RSA_RC2_40_MD5, + SSL3_CK_RSA_RC2_40_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC2, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +#endif + +/* Cipher 07 */ +#ifndef OPENSSL_NO_IDEA + { + 1, + SSL3_TXT_RSA_IDEA_128_SHA, + SSL3_CK_RSA_IDEA_128_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_IDEA, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +#endif + +/* Cipher 08 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_RSA_DES_40_CBC_SHA, + SSL3_CK_RSA_DES_40_CBC_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 56, + }, +#endif + +/* Cipher 09 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_RSA_DES_64_CBC_SHA, + SSL3_CK_RSA_DES_64_CBC_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +#endif + +/* Cipher 0A */ + { + 1, + SSL3_TXT_RSA_DES_192_CBC3_SHA, + SSL3_CK_RSA_DES_192_CBC3_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* The DH ciphers */ +/* Cipher 0B */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 0, + SSL3_TXT_DH_DSS_DES_40_CBC_SHA, + SSL3_CK_DH_DSS_DES_40_CBC_SHA, + SSL_kDHd, + SSL_aDH, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 56, + }, +#endif + +/* Cipher 0C */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 0, /* not implemented (non-ephemeral DH) */ + SSL3_TXT_DH_DSS_DES_64_CBC_SHA, + SSL3_CK_DH_DSS_DES_64_CBC_SHA, + SSL_kDHd, + SSL_aDH, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +#endif + +/* Cipher 0D */ + { + 0, /* not implemented (non-ephemeral DH) */ + SSL3_TXT_DH_DSS_DES_192_CBC3_SHA, + SSL3_CK_DH_DSS_DES_192_CBC3_SHA, + SSL_kDHd, + SSL_aDH, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* Cipher 0E */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 0, /* not implemented (non-ephemeral DH) */ + SSL3_TXT_DH_RSA_DES_40_CBC_SHA, + SSL3_CK_DH_RSA_DES_40_CBC_SHA, + SSL_kDHr, + SSL_aDH, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 56, + }, +#endif + +/* Cipher 0F */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 0, /* not implemented (non-ephemeral DH) */ + SSL3_TXT_DH_RSA_DES_64_CBC_SHA, + SSL3_CK_DH_RSA_DES_64_CBC_SHA, + SSL_kDHr, + SSL_aDH, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +#endif + +/* Cipher 10 */ + { + 0, /* not implemented (non-ephemeral DH) */ + SSL3_TXT_DH_RSA_DES_192_CBC3_SHA, + SSL3_CK_DH_RSA_DES_192_CBC3_SHA, + SSL_kDHr, + SSL_aDH, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* The Ephemeral DH ciphers */ +/* Cipher 11 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_EDH_DSS_DES_40_CBC_SHA, + SSL3_CK_EDH_DSS_DES_40_CBC_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 56, + }, +#endif + +/* Cipher 12 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_EDH_DSS_DES_64_CBC_SHA, + SSL3_CK_EDH_DSS_DES_64_CBC_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +#endif + +/* Cipher 13 */ + { + 1, + SSL3_TXT_EDH_DSS_DES_192_CBC3_SHA, + SSL3_CK_EDH_DSS_DES_192_CBC3_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* Cipher 14 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_EDH_RSA_DES_40_CBC_SHA, + SSL3_CK_EDH_RSA_DES_40_CBC_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 56, + }, +#endif + +/* Cipher 15 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_EDH_RSA_DES_64_CBC_SHA, + SSL3_CK_EDH_RSA_DES_64_CBC_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +#endif + +/* Cipher 16 */ + { + 1, + SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA, + SSL3_CK_EDH_RSA_DES_192_CBC3_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* Cipher 17 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_ADH_RC4_40_MD5, + SSL3_CK_ADH_RC4_40_MD5, + SSL_kEDH, + SSL_aNULL, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +#endif + +/* Cipher 18 */ + { + 1, + SSL3_TXT_ADH_RC4_128_MD5, + SSL3_CK_ADH_RC4_128_MD5, + SSL_kEDH, + SSL_aNULL, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 19 */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_ADH_DES_40_CBC_SHA, + SSL3_CK_ADH_DES_40_CBC_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +#endif + +/* Cipher 1A */ +#ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_ADH_DES_64_CBC_SHA, + SSL3_CK_ADH_DES_64_CBC_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +#endif + +/* Cipher 1B */ + { + 1, + SSL3_TXT_ADH_DES_192_CBC_SHA, + SSL3_CK_ADH_DES_192_CBC_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* Fortezza ciphersuite from SSL 3.0 spec */ +#if 0 +/* Cipher 1C */ + { + 0, + SSL3_TXT_FZA_DMS_NULL_SHA, + SSL3_CK_FZA_DMS_NULL_SHA, + SSL_kFZA, + SSL_aFZA, + SSL_eNULL, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + +/* Cipher 1D */ + { + 0, + SSL3_TXT_FZA_DMS_FZA_SHA, + SSL3_CK_FZA_DMS_FZA_SHA, + SSL_kFZA, + SSL_aFZA, + SSL_eFZA, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + +/* Cipher 1E */ + { + 0, + SSL3_TXT_FZA_DMS_RC4_SHA, + SSL3_CK_FZA_DMS_RC4_SHA, + SSL_kFZA, + SSL_aFZA, + SSL_RC4, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +#endif + +#ifndef OPENSSL_NO_KRB5 +/* The Kerberos ciphers*/ +/* Cipher 1E */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_DES_64_CBC_SHA, + SSL3_CK_KRB5_DES_64_CBC_SHA, + SSL_kKRB5, + SSL_aKRB5, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +# endif + +/* Cipher 1F */ + { + 1, + SSL3_TXT_KRB5_DES_192_CBC3_SHA, + SSL3_CK_KRB5_DES_192_CBC3_SHA, + SSL_kKRB5, + SSL_aKRB5, + SSL_3DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* Cipher 20 */ + { + 1, + SSL3_TXT_KRB5_RC4_128_SHA, + SSL3_CK_KRB5_RC4_128_SHA, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC4, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 21 */ + { + 1, + SSL3_TXT_KRB5_IDEA_128_CBC_SHA, + SSL3_CK_KRB5_IDEA_128_CBC_SHA, + SSL_kKRB5, + SSL_aKRB5, + SSL_IDEA, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 22 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_DES_64_CBC_MD5, + SSL3_CK_KRB5_DES_64_CBC_MD5, + SSL_kKRB5, + SSL_aKRB5, + SSL_DES, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_LOW, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +# endif + +/* Cipher 23 */ + { + 1, + SSL3_TXT_KRB5_DES_192_CBC3_MD5, + SSL3_CK_KRB5_DES_192_CBC3_MD5, + SSL_kKRB5, + SSL_aKRB5, + SSL_3DES, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + +/* Cipher 24 */ + { + 1, + SSL3_TXT_KRB5_RC4_128_MD5, + SSL3_CK_KRB5_RC4_128_MD5, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 25 */ + { + 1, + SSL3_TXT_KRB5_IDEA_128_CBC_MD5, + SSL3_CK_KRB5_IDEA_128_CBC_MD5, + SSL_kKRB5, + SSL_aKRB5, + SSL_IDEA, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 26 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_DES_40_CBC_SHA, + SSL3_CK_KRB5_DES_40_CBC_SHA, + SSL_kKRB5, + SSL_aKRB5, + SSL_DES, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 56, + }, +# endif + +/* Cipher 27 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_RC2_40_CBC_SHA, + SSL3_CK_KRB5_RC2_40_CBC_SHA, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC2, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +# endif + +/* Cipher 28 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_RC4_40_SHA, + SSL3_CK_KRB5_RC4_40_SHA, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC4, + SSL_SHA1, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +# endif + +/* Cipher 29 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_DES_40_CBC_MD5, + SSL3_CK_KRB5_DES_40_CBC_MD5, + SSL_kKRB5, + SSL_aKRB5, + SSL_DES, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 56, + }, +# endif + +/* Cipher 2A */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_RC2_40_CBC_MD5, + SSL3_CK_KRB5_RC2_40_CBC_MD5, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC2, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +# endif + +/* Cipher 2B */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + SSL3_TXT_KRB5_RC4_40_MD5, + SSL3_CK_KRB5_RC4_40_MD5, + SSL_kKRB5, + SSL_aKRB5, + SSL_RC4, + SSL_MD5, + SSL_SSLV3, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP40, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 40, + 128, + }, +# endif +#endif /* OPENSSL_NO_KRB5 */ + +/* New AES ciphersuites */ +/* Cipher 2F */ + { + 1, + TLS1_TXT_RSA_WITH_AES_128_SHA, + TLS1_CK_RSA_WITH_AES_128_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +/* Cipher 30 */ + { + 0, + TLS1_TXT_DH_DSS_WITH_AES_128_SHA, + TLS1_CK_DH_DSS_WITH_AES_128_SHA, + SSL_kDHd, + SSL_aDH, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +/* Cipher 31 */ + { + 0, + TLS1_TXT_DH_RSA_WITH_AES_128_SHA, + TLS1_CK_DH_RSA_WITH_AES_128_SHA, + SSL_kDHr, + SSL_aDH, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +/* Cipher 32 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_AES_128_SHA, + TLS1_CK_DHE_DSS_WITH_AES_128_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +/* Cipher 33 */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_AES_128_SHA, + TLS1_CK_DHE_RSA_WITH_AES_128_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +/* Cipher 34 */ + { + 1, + TLS1_TXT_ADH_WITH_AES_128_SHA, + TLS1_CK_ADH_WITH_AES_128_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +/* Cipher 35 */ + { + 1, + TLS1_TXT_RSA_WITH_AES_256_SHA, + TLS1_CK_RSA_WITH_AES_256_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, +/* Cipher 36 */ + { + 0, + TLS1_TXT_DH_DSS_WITH_AES_256_SHA, + TLS1_CK_DH_DSS_WITH_AES_256_SHA, + SSL_kDHd, + SSL_aDH, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + +/* Cipher 37 */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_RSA_WITH_AES_256_SHA, + TLS1_CK_DH_RSA_WITH_AES_256_SHA, + SSL_kDHr, + SSL_aDH, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + +/* Cipher 38 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_AES_256_SHA, + TLS1_CK_DHE_DSS_WITH_AES_256_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + +/* Cipher 39 */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_AES_256_SHA, + TLS1_CK_DHE_RSA_WITH_AES_256_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 3A */ + { + 1, + TLS1_TXT_ADH_WITH_AES_256_SHA, + TLS1_CK_ADH_WITH_AES_256_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* TLS v1.2 ciphersuites */ + /* Cipher 3B */ + { + 1, + TLS1_TXT_RSA_WITH_NULL_SHA256, + TLS1_CK_RSA_WITH_NULL_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + + /* Cipher 3C */ + { + 1, + TLS1_TXT_RSA_WITH_AES_128_SHA256, + TLS1_CK_RSA_WITH_AES_128_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 3D */ + { + 1, + TLS1_TXT_RSA_WITH_AES_256_SHA256, + TLS1_CK_RSA_WITH_AES_256_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 3E */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_DSS_WITH_AES_128_SHA256, + TLS1_CK_DH_DSS_WITH_AES_128_SHA256, + SSL_kDHd, + SSL_aDH, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 3F */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_RSA_WITH_AES_128_SHA256, + TLS1_CK_DH_RSA_WITH_AES_128_SHA256, + SSL_kDHr, + SSL_aDH, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 40 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_AES_128_SHA256, + TLS1_CK_DHE_DSS_WITH_AES_128_SHA256, + SSL_kEDH, + SSL_aDSS, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +#ifndef OPENSSL_NO_CAMELLIA + /* Camellia ciphersuites from RFC4132 (128-bit portion) */ + + /* Cipher 41 */ + { + 1, + TLS1_TXT_RSA_WITH_CAMELLIA_128_CBC_SHA, + TLS1_CK_RSA_WITH_CAMELLIA_128_CBC_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 42 */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_DSS_WITH_CAMELLIA_128_CBC_SHA, + TLS1_CK_DH_DSS_WITH_CAMELLIA_128_CBC_SHA, + SSL_kDHd, + SSL_aDH, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 43 */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_RSA_WITH_CAMELLIA_128_CBC_SHA, + TLS1_CK_DH_RSA_WITH_CAMELLIA_128_CBC_SHA, + SSL_kDHr, + SSL_aDH, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 44 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, + TLS1_CK_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 45 */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + TLS1_CK_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 46 */ + { + 1, + TLS1_TXT_ADH_WITH_CAMELLIA_128_CBC_SHA, + TLS1_CK_ADH_WITH_CAMELLIA_128_CBC_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_CAMELLIA128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +#endif /* OPENSSL_NO_CAMELLIA */ + +#if TLS1_ALLOW_EXPERIMENTAL_CIPHERSUITES + /* New TLS Export CipherSuites from expired ID */ +# if 0 + /* Cipher 60 */ + { + 1, + TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_MD5, + TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_MD5, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 128, + }, + + /* Cipher 61 */ + { + 1, + TLS1_TXT_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, + TLS1_CK_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, + SSL_kRSA, + SSL_aRSA, + SSL_RC2, + SSL_MD5, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 128, + }, +# endif + + /* Cipher 62 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + TLS1_TXT_RSA_EXPORT1024_WITH_DES_CBC_SHA, + TLS1_CK_RSA_EXPORT1024_WITH_DES_CBC_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +# endif + + /* Cipher 63 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + TLS1_TXT_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, + TLS1_CK_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 56, + }, +# endif + + /* Cipher 64 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + TLS1_TXT_RSA_EXPORT1024_WITH_RC4_56_SHA, + TLS1_CK_RSA_EXPORT1024_WITH_RC4_56_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 128, + }, +# endif + + /* Cipher 65 */ +# ifndef OPENSSL_NO_WEAK_SSL_CIPHERS + { + 1, + TLS1_TXT_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, + TLS1_CK_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_EXPORT | SSL_EXP56, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 56, + 128, + }, +# endif + + /* Cipher 66 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_RC4_128_SHA, + TLS1_CK_DHE_DSS_WITH_RC4_128_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, +#endif + + /* TLS v1.2 ciphersuites */ + /* Cipher 67 */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_AES_128_SHA256, + TLS1_CK_DHE_RSA_WITH_AES_128_SHA256, + SSL_kEDH, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 68 */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_DSS_WITH_AES_256_SHA256, + TLS1_CK_DH_DSS_WITH_AES_256_SHA256, + SSL_kDHd, + SSL_aDH, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 69 */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_RSA_WITH_AES_256_SHA256, + TLS1_CK_DH_RSA_WITH_AES_256_SHA256, + SSL_kDHr, + SSL_aDH, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 6A */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_AES_256_SHA256, + TLS1_CK_DHE_DSS_WITH_AES_256_SHA256, + SSL_kEDH, + SSL_aDSS, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 6B */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_AES_256_SHA256, + TLS1_CK_DHE_RSA_WITH_AES_256_SHA256, + SSL_kEDH, + SSL_aRSA, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 6C */ + { + 1, + TLS1_TXT_ADH_WITH_AES_128_SHA256, + TLS1_CK_ADH_WITH_AES_128_SHA256, + SSL_kEDH, + SSL_aNULL, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 6D */ + { + 1, + TLS1_TXT_ADH_WITH_AES_256_SHA256, + TLS1_CK_ADH_WITH_AES_256_SHA256, + SSL_kEDH, + SSL_aNULL, + SSL_AES256, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* GOST Ciphersuites */ + + { + 1, + "GOST94-GOST89-GOST89", + 0x3000080, + SSL_kGOST, + SSL_aGOST94, + SSL_eGOST2814789CNT, + SSL_GOST89MAC, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94 | TLS1_STREAM_MAC, + 256, + 256}, + { + 1, + "GOST2001-GOST89-GOST89", + 0x3000081, + SSL_kGOST, + SSL_aGOST01, + SSL_eGOST2814789CNT, + SSL_GOST89MAC, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94 | TLS1_STREAM_MAC, + 256, + 256}, + { + 1, + "GOST94-NULL-GOST94", + 0x3000082, + SSL_kGOST, + SSL_aGOST94, + SSL_eNULL, + SSL_GOST94, + SSL_TLSV1, + SSL_NOT_EXP | SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94, + 0, + 0}, + { + 1, + "GOST2001-NULL-GOST94", + 0x3000083, + SSL_kGOST, + SSL_aGOST01, + SSL_eNULL, + SSL_GOST94, + SSL_TLSV1, + SSL_NOT_EXP | SSL_STRONG_NONE, + SSL_HANDSHAKE_MAC_GOST94 | TLS1_PRF_GOST94, + 0, + 0}, + +#ifndef OPENSSL_NO_CAMELLIA + /* Camellia ciphersuites from RFC4132 (256-bit portion) */ + + /* Cipher 84 */ + { + 1, + TLS1_TXT_RSA_WITH_CAMELLIA_256_CBC_SHA, + TLS1_CK_RSA_WITH_CAMELLIA_256_CBC_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + /* Cipher 85 */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_DSS_WITH_CAMELLIA_256_CBC_SHA, + TLS1_CK_DH_DSS_WITH_CAMELLIA_256_CBC_SHA, + SSL_kDHd, + SSL_aDH, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 86 */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_RSA_WITH_CAMELLIA_256_CBC_SHA, + TLS1_CK_DH_RSA_WITH_CAMELLIA_256_CBC_SHA, + SSL_kDHr, + SSL_aDH, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 87 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, + TLS1_CK_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 88 */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + TLS1_CK_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher 89 */ + { + 1, + TLS1_TXT_ADH_WITH_CAMELLIA_256_CBC_SHA, + TLS1_CK_ADH_WITH_CAMELLIA_256_CBC_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_CAMELLIA256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, +#endif /* OPENSSL_NO_CAMELLIA */ + +#ifndef OPENSSL_NO_PSK + /* Cipher 8A */ + { + 1, + TLS1_TXT_PSK_WITH_RC4_128_SHA, + TLS1_CK_PSK_WITH_RC4_128_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 8B */ + { + 1, + TLS1_TXT_PSK_WITH_3DES_EDE_CBC_SHA, + TLS1_CK_PSK_WITH_3DES_EDE_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher 8C */ + { + 1, + TLS1_TXT_PSK_WITH_AES_128_CBC_SHA, + TLS1_CK_PSK_WITH_AES_128_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 8D */ + { + 1, + TLS1_TXT_PSK_WITH_AES_256_CBC_SHA, + TLS1_CK_PSK_WITH_AES_256_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, +#endif /* OPENSSL_NO_PSK */ + +#ifndef OPENSSL_NO_SEED + /* SEED ciphersuites from RFC4162 */ + + /* Cipher 96 */ + { + 1, + TLS1_TXT_RSA_WITH_SEED_SHA, + TLS1_CK_RSA_WITH_SEED_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 97 */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_DSS_WITH_SEED_SHA, + TLS1_CK_DH_DSS_WITH_SEED_SHA, + SSL_kDHd, + SSL_aDH, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 98 */ + { + 0, /* not implemented (non-ephemeral DH) */ + TLS1_TXT_DH_RSA_WITH_SEED_SHA, + TLS1_CK_DH_RSA_WITH_SEED_SHA, + SSL_kDHr, + SSL_aDH, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 99 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_SEED_SHA, + TLS1_CK_DHE_DSS_WITH_SEED_SHA, + SSL_kEDH, + SSL_aDSS, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 9A */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_SEED_SHA, + TLS1_CK_DHE_RSA_WITH_SEED_SHA, + SSL_kEDH, + SSL_aRSA, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher 9B */ + { + 1, + TLS1_TXT_ADH_WITH_SEED_SHA, + TLS1_CK_ADH_WITH_SEED_SHA, + SSL_kEDH, + SSL_aNULL, + SSL_SEED, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + +#endif /* OPENSSL_NO_SEED */ + + /* GCM ciphersuites from RFC5288 */ + + /* Cipher 9C */ + { + 1, + TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher 9D */ + { + 1, + TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, + SSL_kRSA, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher 9E */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_DHE_RSA_WITH_AES_128_GCM_SHA256, + SSL_kEDH, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher 9F */ + { + 1, + TLS1_TXT_DHE_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_DHE_RSA_WITH_AES_256_GCM_SHA384, + SSL_kEDH, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher A0 */ + { + 0, + TLS1_TXT_DH_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_DH_RSA_WITH_AES_128_GCM_SHA256, + SSL_kDHr, + SSL_aDH, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher A1 */ + { + 0, + TLS1_TXT_DH_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_DH_RSA_WITH_AES_256_GCM_SHA384, + SSL_kDHr, + SSL_aDH, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher A2 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_AES_128_GCM_SHA256, + TLS1_CK_DHE_DSS_WITH_AES_128_GCM_SHA256, + SSL_kEDH, + SSL_aDSS, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher A3 */ + { + 1, + TLS1_TXT_DHE_DSS_WITH_AES_256_GCM_SHA384, + TLS1_CK_DHE_DSS_WITH_AES_256_GCM_SHA384, + SSL_kEDH, + SSL_aDSS, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher A4 */ + { + 0, + TLS1_TXT_DH_DSS_WITH_AES_128_GCM_SHA256, + TLS1_CK_DH_DSS_WITH_AES_128_GCM_SHA256, + SSL_kDHd, + SSL_aDH, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher A5 */ + { + 0, + TLS1_TXT_DH_DSS_WITH_AES_256_GCM_SHA384, + TLS1_CK_DH_DSS_WITH_AES_256_GCM_SHA384, + SSL_kDHd, + SSL_aDH, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher A6 */ + { + 1, + TLS1_TXT_ADH_WITH_AES_128_GCM_SHA256, + TLS1_CK_ADH_WITH_AES_128_GCM_SHA256, + SSL_kEDH, + SSL_aNULL, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher A7 */ + { + 1, + TLS1_TXT_ADH_WITH_AES_256_GCM_SHA384, + TLS1_CK_ADH_WITH_AES_256_GCM_SHA384, + SSL_kEDH, + SSL_aNULL, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + +#ifndef OPENSSL_NO_ECDH + /* Cipher C001 */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_NULL_SHA, + TLS1_CK_ECDH_ECDSA_WITH_NULL_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + + /* Cipher C002 */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_RC4_128_SHA, + TLS1_CK_ECDH_ECDSA_WITH_RC4_128_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C003 */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDH_ECDSA_WITH_DES_192_CBC3_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C004 */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C005 */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + SSL_kECDHe, + SSL_aECDH, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher C006 */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_NULL_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_NULL_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + + /* Cipher C007 */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_RC4_128_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_RC4_128_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C008 */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_DES_192_CBC3_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C009 */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C00A */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + SSL_kEECDH, + SSL_aECDSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher C00B */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_NULL_SHA, + TLS1_CK_ECDH_RSA_WITH_NULL_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + + /* Cipher C00C */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_RC4_128_SHA, + TLS1_CK_ECDH_RSA_WITH_RC4_128_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C00D */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDH_RSA_WITH_DES_192_CBC3_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C00E */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDH_RSA_WITH_AES_128_CBC_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C00F */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDH_RSA_WITH_AES_256_CBC_SHA, + SSL_kECDHr, + SSL_aECDH, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher C010 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_NULL_SHA, + TLS1_CK_ECDHE_RSA_WITH_NULL_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + + /* Cipher C011 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_RC4_128_SHA, + TLS1_CK_ECDHE_RSA_WITH_RC4_128_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C012 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDHE_RSA_WITH_DES_192_CBC3_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C013 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C014 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, + SSL_kEECDH, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher C015 */ + { + 1, + TLS1_TXT_ECDH_anon_WITH_NULL_SHA, + TLS1_CK_ECDH_anon_WITH_NULL_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_eNULL, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_STRONG_NONE | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 0, + 0, + }, + + /* Cipher C016 */ + { + 1, + TLS1_TXT_ECDH_anon_WITH_RC4_128_SHA, + TLS1_CK_ECDH_anon_WITH_RC4_128_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_RC4, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_MEDIUM, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C017 */ + { + 1, + TLS1_TXT_ECDH_anon_WITH_DES_192_CBC3_SHA, + TLS1_CK_ECDH_anon_WITH_DES_192_CBC3_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C018 */ + { + 1, + TLS1_TXT_ECDH_anon_WITH_AES_128_CBC_SHA, + TLS1_CK_ECDH_anon_WITH_AES_128_CBC_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C019 */ + { + 1, + TLS1_TXT_ECDH_anon_WITH_AES_256_CBC_SHA, + TLS1_CK_ECDH_anon_WITH_AES_256_CBC_SHA, + SSL_kEECDH, + SSL_aNULL, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_DEFAULT | SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, +#endif /* OPENSSL_NO_ECDH */ + +#ifndef OPENSSL_NO_SRP + /* Cipher C01A */ + { + 1, + TLS1_TXT_SRP_SHA_WITH_3DES_EDE_CBC_SHA, + TLS1_CK_SRP_SHA_WITH_3DES_EDE_CBC_SHA, + SSL_kSRP, + SSL_aSRP, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C01B */ + { + 1, + TLS1_TXT_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, + TLS1_CK_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA, + SSL_kSRP, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C01C */ + { + 1, + TLS1_TXT_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, + TLS1_CK_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA, + SSL_kSRP, + SSL_aDSS, + SSL_3DES, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 112, + 168, + }, + + /* Cipher C01D */ + { + 1, + TLS1_TXT_SRP_SHA_WITH_AES_128_CBC_SHA, + TLS1_CK_SRP_SHA_WITH_AES_128_CBC_SHA, + SSL_kSRP, + SSL_aSRP, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C01E */ + { + 1, + TLS1_TXT_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, + TLS1_CK_SRP_SHA_RSA_WITH_AES_128_CBC_SHA, + SSL_kSRP, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C01F */ + { + 1, + TLS1_TXT_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, + TLS1_CK_SRP_SHA_DSS_WITH_AES_128_CBC_SHA, + SSL_kSRP, + SSL_aDSS, + SSL_AES128, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 128, + 128, + }, + + /* Cipher C020 */ + { + 1, + TLS1_TXT_SRP_SHA_WITH_AES_256_CBC_SHA, + TLS1_CK_SRP_SHA_WITH_AES_256_CBC_SHA, + SSL_kSRP, + SSL_aSRP, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher C021 */ + { + 1, + TLS1_TXT_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, + TLS1_CK_SRP_SHA_RSA_WITH_AES_256_CBC_SHA, + SSL_kSRP, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + + /* Cipher C022 */ + { + 1, + TLS1_TXT_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, + TLS1_CK_SRP_SHA_DSS_WITH_AES_256_CBC_SHA, + SSL_kSRP, + SSL_aDSS, + SSL_AES256, + SSL_SHA1, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, +#endif /* OPENSSL_NO_SRP */ +#ifndef OPENSSL_NO_ECDH + + /* HMAC based TLS v1.2 ciphersuites from RFC5289 */ + + /* Cipher C023 */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256, + SSL_kEECDH, + SSL_aECDSA, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C024 */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384, + SSL_kEECDH, + SSL_aECDSA, + SSL_AES256, + SSL_SHA384, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher C025 */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_AES_128_SHA256, + TLS1_CK_ECDH_ECDSA_WITH_AES_128_SHA256, + SSL_kECDHe, + SSL_aECDH, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C026 */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_AES_256_SHA384, + TLS1_CK_ECDH_ECDSA_WITH_AES_256_SHA384, + SSL_kECDHe, + SSL_aECDH, + SSL_AES256, + SSL_SHA384, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher C027 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256, + TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, + SSL_kEECDH, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C028 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384, + TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, + SSL_kEECDH, + SSL_aRSA, + SSL_AES256, + SSL_SHA384, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher C029 */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_AES_128_SHA256, + TLS1_CK_ECDH_RSA_WITH_AES_128_SHA256, + SSL_kECDHr, + SSL_aECDH, + SSL_AES128, + SSL_SHA256, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C02A */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_AES_256_SHA384, + TLS1_CK_ECDH_RSA_WITH_AES_256_SHA384, + SSL_kECDHr, + SSL_aECDH, + SSL_AES256, + SSL_SHA384, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* GCM based TLS v1.2 ciphersuites from RFC5289 */ + + /* Cipher C02B */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + SSL_kEECDH, + SSL_aECDSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C02C */ + { + 1, + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + SSL_kEECDH, + SSL_aECDSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher C02D */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + SSL_kECDHe, + SSL_aECDH, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C02E */ + { + 1, + TLS1_TXT_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + SSL_kECDHe, + SSL_aECDH, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher C02F */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + SSL_kEECDH, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C030 */ + { + 1, + TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + SSL_kEECDH, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + + /* Cipher C031 */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_AES_128_GCM_SHA256, + TLS1_CK_ECDH_RSA_WITH_AES_128_GCM_SHA256, + SSL_kECDHr, + SSL_aECDH, + SSL_AES128GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256, + 128, + 128, + }, + + /* Cipher C032 */ + { + 1, + TLS1_TXT_ECDH_RSA_WITH_AES_256_GCM_SHA384, + TLS1_CK_ECDH_RSA_WITH_AES_256_GCM_SHA384, + SSL_kECDHr, + SSL_aECDH, + SSL_AES256GCM, + SSL_AEAD, + SSL_TLSV1_2, + SSL_NOT_EXP | SSL_HIGH | SSL_FIPS, + SSL_HANDSHAKE_MAC_SHA384 | TLS1_PRF_SHA384, + 256, + 256, + }, + +#endif /* OPENSSL_NO_ECDH */ + +#ifdef TEMP_GOST_TLS +/* Cipher FF00 */ + { + 1, + "GOST-MD5", + 0x0300ff00, + SSL_kRSA, + SSL_aRSA, + SSL_eGOST2814789CNT, + SSL_MD5, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256, + }, + { + 1, + "GOST-GOST94", + 0x0300ff01, + SSL_kRSA, + SSL_aRSA, + SSL_eGOST2814789CNT, + SSL_GOST94, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256}, + { + 1, + "GOST-GOST89MAC", + 0x0300ff02, + SSL_kRSA, + SSL_aRSA, + SSL_eGOST2814789CNT, + SSL_GOST89MAC, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF, + 256, + 256}, + { + 1, + "GOST-GOST89STREAM", + 0x0300ff03, + SSL_kRSA, + SSL_aRSA, + SSL_eGOST2814789CNT, + SSL_GOST89MAC, + SSL_TLSV1, + SSL_NOT_EXP | SSL_HIGH, + SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF | TLS1_STREAM_MAC, + 256, + 256}, +#endif + +/* end of list */ +}; + +SSL3_ENC_METHOD SSLv3_enc_data = { + ssl3_enc, + n_ssl3_mac, + ssl3_setup_key_block, + ssl3_generate_master_secret, + ssl3_change_cipher_state, + ssl3_final_finish_mac, + MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, + ssl3_cert_verify_mac, + SSL3_MD_CLIENT_FINISHED_CONST, 4, + SSL3_MD_SERVER_FINISHED_CONST, 4, + ssl3_alert_code, + (int (*)(SSL *, unsigned char *, size_t, const char *, + size_t, const unsigned char *, size_t, + int use_context))ssl_undefined_function, +}; + +long ssl3_default_timeout(void) +{ + /* + * 2 hours, the 24 hours mentioned in the SSLv3 spec is way too long for + * http, the cache would over fill + */ + return (60 * 60 * 2); +} + +int ssl3_num_ciphers(void) +{ + return (SSL3_NUM_CIPHERS); +} + +const SSL_CIPHER *ssl3_get_cipher(unsigned int u) +{ + if (u < SSL3_NUM_CIPHERS) + return (&(ssl3_ciphers[SSL3_NUM_CIPHERS - 1 - u])); + else + return (NULL); +} + +int ssl3_pending(const SSL *s) +{ + if (s->rstate == SSL_ST_READ_BODY) + return 0; + + return (s->s3->rrec.type == + SSL3_RT_APPLICATION_DATA) ? s->s3->rrec.length : 0; +} + +int ssl3_new(SSL *s) +{ + SSL3_STATE *s3; + + if ((s3 = OPENSSL_malloc(sizeof *s3)) == NULL) + goto err; + memset(s3, 0, sizeof *s3); + memset(s3->rrec.seq_num, 0, sizeof(s3->rrec.seq_num)); + memset(s3->wrec.seq_num, 0, sizeof(s3->wrec.seq_num)); + + s->s3 = s3; + +#ifndef OPENSSL_NO_SRP + SSL_SRP_CTX_init(s); +#endif + s->method->ssl_clear(s); + return (1); + err: + return (0); +} + +void ssl3_free(SSL *s) +{ + if (s == NULL || s->s3 == NULL) + return; + +#ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->client_opaque_prf_input != NULL) + OPENSSL_free(s->s3->client_opaque_prf_input); + if (s->s3->server_opaque_prf_input != NULL) + OPENSSL_free(s->s3->server_opaque_prf_input); +#endif + + ssl3_cleanup_key_block(s); + if (s->s3->rbuf.buf != NULL) + ssl3_release_read_buffer(s); + if (s->s3->wbuf.buf != NULL) + ssl3_release_write_buffer(s); + if (s->s3->rrec.comp != NULL) + OPENSSL_free(s->s3->rrec.comp); +#ifndef OPENSSL_NO_DH + if (s->s3->tmp.dh != NULL) + DH_free(s->s3->tmp.dh); +#endif +#ifndef OPENSSL_NO_ECDH + if (s->s3->tmp.ecdh != NULL) + EC_KEY_free(s->s3->tmp.ecdh); +#endif + + if (s->s3->tmp.ca_names != NULL) + sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); + if (s->s3->handshake_buffer) { + BIO_free(s->s3->handshake_buffer); + } + if (s->s3->handshake_dgst) + ssl3_free_digest_list(s); +#ifndef OPENSSL_NO_SRP + SSL_SRP_CTX_free(s); +#endif + OPENSSL_cleanse(s->s3, sizeof *s->s3); + OPENSSL_free(s->s3); + s->s3 = NULL; +} + +void ssl3_clear(SSL *s) +{ + unsigned char *rp, *wp; + size_t rlen, wlen; + int init_extra; + +#ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->client_opaque_prf_input != NULL) + OPENSSL_free(s->s3->client_opaque_prf_input); + s->s3->client_opaque_prf_input = NULL; + if (s->s3->server_opaque_prf_input != NULL) + OPENSSL_free(s->s3->server_opaque_prf_input); + s->s3->server_opaque_prf_input = NULL; +#endif + + ssl3_cleanup_key_block(s); + if (s->s3->tmp.ca_names != NULL) + sk_X509_NAME_pop_free(s->s3->tmp.ca_names, X509_NAME_free); + + if (s->s3->rrec.comp != NULL) { + OPENSSL_free(s->s3->rrec.comp); + s->s3->rrec.comp = NULL; + } +#ifndef OPENSSL_NO_DH + if (s->s3->tmp.dh != NULL) { + DH_free(s->s3->tmp.dh); + s->s3->tmp.dh = NULL; + } +#endif +#ifndef OPENSSL_NO_ECDH + if (s->s3->tmp.ecdh != NULL) { + EC_KEY_free(s->s3->tmp.ecdh); + s->s3->tmp.ecdh = NULL; + } +#endif +#ifndef OPENSSL_NO_TLSEXT +# ifndef OPENSSL_NO_EC + s->s3->is_probably_safari = 0; +# endif /* !OPENSSL_NO_EC */ +#endif /* !OPENSSL_NO_TLSEXT */ + + rp = s->s3->rbuf.buf; + wp = s->s3->wbuf.buf; + rlen = s->s3->rbuf.len; + wlen = s->s3->wbuf.len; + init_extra = s->s3->init_extra; + if (s->s3->handshake_buffer) { + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; + } + if (s->s3->handshake_dgst) { + ssl3_free_digest_list(s); + } + memset(s->s3, 0, sizeof *s->s3); + s->s3->rbuf.buf = rp; + s->s3->wbuf.buf = wp; + s->s3->rbuf.len = rlen; + s->s3->wbuf.len = wlen; + s->s3->init_extra = init_extra; + + ssl_free_wbio_buffer(s); + + s->packet_length = 0; + s->s3->renegotiate = 0; + s->s3->total_renegotiations = 0; + s->s3->num_renegotiations = 0; + s->s3->in_read_app_data = 0; + s->version = SSL3_VERSION; + +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) + if (s->next_proto_negotiated) { + OPENSSL_free(s->next_proto_negotiated); + s->next_proto_negotiated = NULL; + s->next_proto_negotiated_len = 0; + } +#endif +} + +#ifndef OPENSSL_NO_SRP +static char *MS_CALLBACK srp_password_from_info_cb(SSL *s, void *arg) +{ + return BUF_strdup(s->srp_ctx.info); +} +#endif + +long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + int ret = 0; + +#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA) + if ( +# ifndef OPENSSL_NO_RSA + cmd == SSL_CTRL_SET_TMP_RSA || cmd == SSL_CTRL_SET_TMP_RSA_CB || +# endif +# ifndef OPENSSL_NO_DSA + cmd == SSL_CTRL_SET_TMP_DH || cmd == SSL_CTRL_SET_TMP_DH_CB || +# endif + 0) { + if (!ssl_cert_inst(&s->cert)) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_MALLOC_FAILURE); + return (0); + } + } +#endif + + switch (cmd) { + case SSL_CTRL_GET_SESSION_REUSED: + ret = s->hit; + break; + case SSL_CTRL_GET_CLIENT_CERT_REQUEST: + break; + case SSL_CTRL_GET_NUM_RENEGOTIATIONS: + ret = s->s3->num_renegotiations; + break; + case SSL_CTRL_CLEAR_NUM_RENEGOTIATIONS: + ret = s->s3->num_renegotiations; + s->s3->num_renegotiations = 0; + break; + case SSL_CTRL_GET_TOTAL_RENEGOTIATIONS: + ret = s->s3->total_renegotiations; + break; + case SSL_CTRL_GET_FLAGS: + ret = (int)(s->s3->flags); + break; +#ifndef OPENSSL_NO_RSA + case SSL_CTRL_NEED_TMP_RSA: + if ((s->cert != NULL) && (s->cert->rsa_tmp == NULL) && + ((s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) || + (EVP_PKEY_size(s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey) > + (512 / 8)))) + ret = 1; + break; + case SSL_CTRL_SET_TMP_RSA: + { + RSA *rsa = (RSA *)parg; + if (rsa == NULL) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return (ret); + } + if ((rsa = RSAPrivateKey_dup(rsa)) == NULL) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_RSA_LIB); + return (ret); + } + if (s->cert->rsa_tmp != NULL) + RSA_free(s->cert->rsa_tmp); + s->cert->rsa_tmp = rsa; + ret = 1; + } + break; + case SSL_CTRL_SET_TMP_RSA_CB: + { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (ret); + } + break; +#endif +#ifndef OPENSSL_NO_DH + case SSL_CTRL_SET_TMP_DH: + { + DH *dh = (DH *)parg; + if (dh == NULL) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return (ret); + } + if ((dh = DHparams_dup(dh)) == NULL) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_DH_LIB); + return (ret); + } + if (s->cert->dh_tmp != NULL) + DH_free(s->cert->dh_tmp); + s->cert->dh_tmp = dh; + ret = 1; + } + break; + case SSL_CTRL_SET_TMP_DH_CB: + { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (ret); + } + break; +#endif +#ifndef OPENSSL_NO_ECDH + case SSL_CTRL_SET_TMP_ECDH: + { + EC_KEY *ecdh = NULL; + + if (parg == NULL) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_PASSED_NULL_PARAMETER); + return (ret); + } + if (!EC_KEY_up_ref((EC_KEY *)parg)) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_ECDH_LIB); + return (ret); + } + ecdh = (EC_KEY *)parg; + if (!(s->options & SSL_OP_SINGLE_ECDH_USE)) { + if (!EC_KEY_generate_key(ecdh)) { + EC_KEY_free(ecdh); + SSLerr(SSL_F_SSL3_CTRL, ERR_R_ECDH_LIB); + return (ret); + } + } + if (s->cert->ecdh_tmp != NULL) + EC_KEY_free(s->cert->ecdh_tmp); + s->cert->ecdh_tmp = ecdh; + ret = 1; + } + break; + case SSL_CTRL_SET_TMP_ECDH_CB: + { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (ret); + } + break; +#endif /* !OPENSSL_NO_ECDH */ +#ifndef OPENSSL_NO_TLSEXT + case SSL_CTRL_SET_TLSEXT_HOSTNAME: + if (larg == TLSEXT_NAMETYPE_host_name) { + size_t len; + + if (s->tlsext_hostname != NULL) + OPENSSL_free(s->tlsext_hostname); + s->tlsext_hostname = NULL; + + ret = 1; + if (parg == NULL) + break; + len = strlen((char *)parg); + if (len == 0 || len > TLSEXT_MAXLEN_host_name) { + SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME); + return 0; + } + if ((s->tlsext_hostname = BUF_strdup((char *)parg)) == NULL) { + SSLerr(SSL_F_SSL3_CTRL, ERR_R_INTERNAL_ERROR); + return 0; + } + } else { + SSLerr(SSL_F_SSL3_CTRL, SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE); + return 0; + } + break; + case SSL_CTRL_SET_TLSEXT_DEBUG_ARG: + s->tlsext_debug_arg = parg; + ret = 1; + break; + +# ifdef TLSEXT_TYPE_opaque_prf_input + case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT: + if (larg > 12288) { /* actual internal limit is 2^16 for the + * complete hello message * (including the + * cert chain and everything) */ + SSLerr(SSL_F_SSL3_CTRL, SSL_R_OPAQUE_PRF_INPUT_TOO_LONG); + break; + } + if (s->tlsext_opaque_prf_input != NULL) + OPENSSL_free(s->tlsext_opaque_prf_input); + if ((size_t)larg == 0) + s->tlsext_opaque_prf_input = OPENSSL_malloc(1); /* dummy byte + * just to get + * non-NULL */ + else + s->tlsext_opaque_prf_input = BUF_memdup(parg, (size_t)larg); + if (s->tlsext_opaque_prf_input != NULL) { + s->tlsext_opaque_prf_input_len = (size_t)larg; + ret = 1; + } else + s->tlsext_opaque_prf_input_len = 0; + break; +# endif + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_TYPE: + s->tlsext_status_type = larg; + ret = 1; + break; + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_EXTS: + *(STACK_OF(X509_EXTENSION) **)parg = s->tlsext_ocsp_exts; + ret = 1; + break; + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_EXTS: + s->tlsext_ocsp_exts = parg; + ret = 1; + break; + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_IDS: + *(STACK_OF(OCSP_RESPID) **)parg = s->tlsext_ocsp_ids; + ret = 1; + break; + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_IDS: + s->tlsext_ocsp_ids = parg; + ret = 1; + break; + + case SSL_CTRL_GET_TLSEXT_STATUS_REQ_OCSP_RESP: + *(unsigned char **)parg = s->tlsext_ocsp_resp; + return s->tlsext_ocsp_resplen; + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_OCSP_RESP: + if (s->tlsext_ocsp_resp) + OPENSSL_free(s->tlsext_ocsp_resp); + s->tlsext_ocsp_resp = parg; + s->tlsext_ocsp_resplen = larg; + ret = 1; + break; + +# ifndef OPENSSL_NO_HEARTBEATS + case SSL_CTRL_TLS_EXT_SEND_HEARTBEAT: + if (SSL_version(s) == DTLS1_VERSION + || SSL_version(s) == DTLS1_BAD_VER) + ret = dtls1_heartbeat(s); + else + ret = tls1_heartbeat(s); + break; + + case SSL_CTRL_GET_TLS_EXT_HEARTBEAT_PENDING: + ret = s->tlsext_hb_pending; + break; + + case SSL_CTRL_SET_TLS_EXT_HEARTBEAT_NO_REQUESTS: + if (larg) + s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_RECV_REQUESTS; + else + s->tlsext_heartbeat &= ~SSL_TLSEXT_HB_DONT_RECV_REQUESTS; + ret = 1; + break; +# endif + +#endif /* !OPENSSL_NO_TLSEXT */ + + case SSL_CTRL_CHECK_PROTO_VERSION: + /* + * For library-internal use; checks that the current protocol is the + * highest enabled version (according to s->ctx->method, as version + * negotiation may have changed s->method). + */ + if (s->version == s->ctx->method->version) + return 1; + /* + * Apparently we're using a version-flexible SSL_METHOD (not at its + * highest protocol version). + */ + if (s->ctx->method->version == SSLv23_method()->version) { +#if TLS_MAX_VERSION != TLS1_2_VERSION +# error Code needs update for SSLv23_method() support beyond TLS1_2_VERSION. +#endif + if (!(s->options & SSL_OP_NO_TLSv1_2)) + return s->version == TLS1_2_VERSION; + if (!(s->options & SSL_OP_NO_TLSv1_1)) + return s->version == TLS1_1_VERSION; + if (!(s->options & SSL_OP_NO_TLSv1)) + return s->version == TLS1_VERSION; + if (!(s->options & SSL_OP_NO_SSLv3)) + return s->version == SSL3_VERSION; + if (!(s->options & SSL_OP_NO_SSLv2)) + return s->version == SSL2_VERSION; + } + return 0; /* Unexpected state; fail closed. */ + + default: + break; + } + return (ret); +} + +long ssl3_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) +{ + int ret = 0; + +#if !defined(OPENSSL_NO_DSA) || !defined(OPENSSL_NO_RSA) + if ( +# ifndef OPENSSL_NO_RSA + cmd == SSL_CTRL_SET_TMP_RSA_CB || +# endif +# ifndef OPENSSL_NO_DSA + cmd == SSL_CTRL_SET_TMP_DH_CB || +# endif + 0) { + if (!ssl_cert_inst(&s->cert)) { + SSLerr(SSL_F_SSL3_CALLBACK_CTRL, ERR_R_MALLOC_FAILURE); + return (0); + } + } +#endif + + switch (cmd) { +#ifndef OPENSSL_NO_RSA + case SSL_CTRL_SET_TMP_RSA_CB: + { + s->cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp; + } + break; +#endif +#ifndef OPENSSL_NO_DH + case SSL_CTRL_SET_TMP_DH_CB: + { + s->cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; + } + break; +#endif +#ifndef OPENSSL_NO_ECDH + case SSL_CTRL_SET_TMP_ECDH_CB: + { + s->cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp; + } + break; +#endif +#ifndef OPENSSL_NO_TLSEXT + case SSL_CTRL_SET_TLSEXT_DEBUG_CB: + s->tlsext_debug_cb = (void (*)(SSL *, int, int, + unsigned char *, int, void *))fp; + break; +#endif + default: + break; + } + return (ret); +} + +long ssl3_ctx_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) +{ + CERT *cert; + + cert = ctx->cert; + + switch (cmd) { +#ifndef OPENSSL_NO_RSA + case SSL_CTRL_NEED_TMP_RSA: + if ((cert->rsa_tmp == NULL) && + ((cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL) || + (EVP_PKEY_size(cert->pkeys[SSL_PKEY_RSA_ENC].privatekey) > + (512 / 8))) + ) + return (1); + else + return (0); + /* break; */ + case SSL_CTRL_SET_TMP_RSA: + { + RSA *rsa; + int i; + + rsa = (RSA *)parg; + i = 1; + if (rsa == NULL) + i = 0; + else { + if ((rsa = RSAPrivateKey_dup(rsa)) == NULL) + i = 0; + } + if (!i) { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_RSA_LIB); + return (0); + } else { + if (cert->rsa_tmp != NULL) + RSA_free(cert->rsa_tmp); + cert->rsa_tmp = rsa; + return (1); + } + } + /* break; */ + case SSL_CTRL_SET_TMP_RSA_CB: + { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); + } + break; +#endif +#ifndef OPENSSL_NO_DH + case SSL_CTRL_SET_TMP_DH: + { + DH *new = NULL, *dh; + + dh = (DH *)parg; + if ((new = DHparams_dup(dh)) == NULL) { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_DH_LIB); + return 0; + } + if (cert->dh_tmp != NULL) + DH_free(cert->dh_tmp); + cert->dh_tmp = new; + return 1; + } + /* + * break; + */ + case SSL_CTRL_SET_TMP_DH_CB: + { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); + } + break; +#endif +#ifndef OPENSSL_NO_ECDH + case SSL_CTRL_SET_TMP_ECDH: + { + EC_KEY *ecdh = NULL; + + if (parg == NULL) { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_ECDH_LIB); + return 0; + } + ecdh = EC_KEY_dup((EC_KEY *)parg); + if (ecdh == NULL) { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_EC_LIB); + return 0; + } + if (!(ctx->options & SSL_OP_SINGLE_ECDH_USE)) { + if (!EC_KEY_generate_key(ecdh)) { + EC_KEY_free(ecdh); + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_ECDH_LIB); + return 0; + } + } + + if (cert->ecdh_tmp != NULL) { + EC_KEY_free(cert->ecdh_tmp); + } + cert->ecdh_tmp = ecdh; + return 1; + } + /* break; */ + case SSL_CTRL_SET_TMP_ECDH_CB: + { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); + } + break; +#endif /* !OPENSSL_NO_ECDH */ +#ifndef OPENSSL_NO_TLSEXT + case SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG: + ctx->tlsext_servername_arg = parg; + break; + case SSL_CTRL_SET_TLSEXT_TICKET_KEYS: + case SSL_CTRL_GET_TLSEXT_TICKET_KEYS: + { + unsigned char *keys = parg; + if (!keys) + return 48; + if (larg != 48) { + SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_TICKET_KEYS_LENGTH); + return 0; + } + if (cmd == SSL_CTRL_SET_TLSEXT_TICKET_KEYS) { + memcpy(ctx->tlsext_tick_key_name, keys, 16); + memcpy(ctx->tlsext_tick_hmac_key, keys + 16, 16); + memcpy(ctx->tlsext_tick_aes_key, keys + 32, 16); + } else { + memcpy(keys, ctx->tlsext_tick_key_name, 16); + memcpy(keys + 16, ctx->tlsext_tick_hmac_key, 16); + memcpy(keys + 32, ctx->tlsext_tick_aes_key, 16); + } + return 1; + } + +# ifdef TLSEXT_TYPE_opaque_prf_input + case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB_ARG: + ctx->tlsext_opaque_prf_input_callback_arg = parg; + return 1; +# endif + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB_ARG: + ctx->tlsext_status_arg = parg; + return 1; + break; + +# ifndef OPENSSL_NO_SRP + case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME: + ctx->srp_ctx.srp_Mask |= SSL_kSRP; + if (ctx->srp_ctx.login != NULL) + OPENSSL_free(ctx->srp_ctx.login); + ctx->srp_ctx.login = NULL; + if (parg == NULL) + break; + if (strlen((const char *)parg) > 255 + || strlen((const char *)parg) < 1) { + SSLerr(SSL_F_SSL3_CTX_CTRL, SSL_R_INVALID_SRP_USERNAME); + return 0; + } + if ((ctx->srp_ctx.login = BUF_strdup((char *)parg)) == NULL) { + SSLerr(SSL_F_SSL3_CTX_CTRL, ERR_R_INTERNAL_ERROR); + return 0; + } + break; + case SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD: + ctx->srp_ctx.SRP_give_srp_client_pwd_callback = + srp_password_from_info_cb; + ctx->srp_ctx.info = parg; + break; + case SSL_CTRL_SET_SRP_ARG: + ctx->srp_ctx.srp_Mask |= SSL_kSRP; + ctx->srp_ctx.SRP_cb_arg = parg; + break; + + case SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH: + ctx->srp_ctx.strength = larg; + break; +# endif +#endif /* !OPENSSL_NO_TLSEXT */ + + /* A Thawte special :-) */ + case SSL_CTRL_EXTRA_CHAIN_CERT: + if (ctx->extra_certs == NULL) { + if ((ctx->extra_certs = sk_X509_new_null()) == NULL) + return (0); + } + sk_X509_push(ctx->extra_certs, (X509 *)parg); + break; + + case SSL_CTRL_GET_EXTRA_CHAIN_CERTS: + *(STACK_OF(X509) **)parg = ctx->extra_certs; + break; + + case SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS: + if (ctx->extra_certs) { + sk_X509_pop_free(ctx->extra_certs, X509_free); + ctx->extra_certs = NULL; + } + break; + + default: + return (0); + } + return (1); +} + +long ssl3_ctx_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) +{ + CERT *cert; + + cert = ctx->cert; + + switch (cmd) { +#ifndef OPENSSL_NO_RSA + case SSL_CTRL_SET_TMP_RSA_CB: + { + cert->rsa_tmp_cb = (RSA *(*)(SSL *, int, int))fp; + } + break; +#endif +#ifndef OPENSSL_NO_DH + case SSL_CTRL_SET_TMP_DH_CB: + { + cert->dh_tmp_cb = (DH *(*)(SSL *, int, int))fp; + } + break; +#endif +#ifndef OPENSSL_NO_ECDH + case SSL_CTRL_SET_TMP_ECDH_CB: + { + cert->ecdh_tmp_cb = (EC_KEY *(*)(SSL *, int, int))fp; + } + break; +#endif +#ifndef OPENSSL_NO_TLSEXT + case SSL_CTRL_SET_TLSEXT_SERVERNAME_CB: + ctx->tlsext_servername_callback = (int (*)(SSL *, int *, void *))fp; + break; + +# ifdef TLSEXT_TYPE_opaque_prf_input + case SSL_CTRL_SET_TLSEXT_OPAQUE_PRF_INPUT_CB: + ctx->tlsext_opaque_prf_input_callback = + (int (*)(SSL *, void *, size_t, void *))fp; + break; +# endif + + case SSL_CTRL_SET_TLSEXT_STATUS_REQ_CB: + ctx->tlsext_status_cb = (int (*)(SSL *, void *))fp; + break; + + case SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB: + ctx->tlsext_ticket_key_cb = (int (*)(SSL *, unsigned char *, + unsigned char *, + EVP_CIPHER_CTX *, + HMAC_CTX *, int))fp; + break; + +# ifndef OPENSSL_NO_SRP + case SSL_CTRL_SET_SRP_VERIFY_PARAM_CB: + ctx->srp_ctx.srp_Mask |= SSL_kSRP; + ctx->srp_ctx.SRP_verify_param_callback = (int (*)(SSL *, void *))fp; + break; + case SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB: + ctx->srp_ctx.srp_Mask |= SSL_kSRP; + ctx->srp_ctx.TLS_ext_srp_username_callback = + (int (*)(SSL *, int *, void *))fp; + break; + case SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB: + ctx->srp_ctx.srp_Mask |= SSL_kSRP; + ctx->srp_ctx.SRP_give_srp_client_pwd_callback = + (char *(*)(SSL *, void *))fp; + break; +# endif +#endif + + default: + return (0); + } + return (1); +} + +/* + * This function needs to check if the ciphers required are actually + * available + */ +const SSL_CIPHER *ssl3_get_cipher_by_char(const unsigned char *p) +{ + SSL_CIPHER c; + const SSL_CIPHER *cp; + unsigned long id; + + id = 0x03000000L | ((unsigned long)p[0] << 8L) | (unsigned long)p[1]; + c.id = id; + cp = OBJ_bsearch_ssl_cipher_id(&c, ssl3_ciphers, SSL3_NUM_CIPHERS); +#ifdef DEBUG_PRINT_UNKNOWN_CIPHERSUITES + if (cp == NULL) + fprintf(stderr, "Unknown cipher ID %x\n", (p[0] << 8) | p[1]); +#endif + if (cp == NULL || cp->valid == 0) + return NULL; + else + return cp; +} + +int ssl3_put_cipher_by_char(const SSL_CIPHER *c, unsigned char *p) +{ + long l; + + if (p != NULL) { + l = c->id; + if ((l & 0xff000000) != 0x03000000) + return (0); + p[0] = ((unsigned char)(l >> 8L)) & 0xFF; + p[1] = ((unsigned char)(l)) & 0xFF; + } + return (2); +} + +SSL_CIPHER *ssl3_choose_cipher(SSL *s, STACK_OF(SSL_CIPHER) *clnt, + STACK_OF(SSL_CIPHER) *srvr) +{ + SSL_CIPHER *c, *ret = NULL; + STACK_OF(SSL_CIPHER) *prio, *allow; + int i, ii, ok; +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_EC) + unsigned int j; + int ec_ok, ec_nid; + unsigned char ec_search1 = 0, ec_search2 = 0; +#endif + CERT *cert; + unsigned long alg_k, alg_a, mask_k, mask_a, emask_k, emask_a; + + /* Let's see which ciphers we can support */ + cert = s->cert; + +#if 0 + /* + * Do not set the compare functions, because this may lead to a + * reordering by "id". We want to keep the original ordering. We may pay + * a price in performance during sk_SSL_CIPHER_find(), but would have to + * pay with the price of sk_SSL_CIPHER_dup(). + */ + sk_SSL_CIPHER_set_cmp_func(srvr, ssl_cipher_ptr_id_cmp); + sk_SSL_CIPHER_set_cmp_func(clnt, ssl_cipher_ptr_id_cmp); +#endif + +#ifdef CIPHER_DEBUG + fprintf(stderr, "Server has %d from %p:\n", sk_SSL_CIPHER_num(srvr), + (void *)srvr); + for (i = 0; i < sk_SSL_CIPHER_num(srvr); ++i) { + c = sk_SSL_CIPHER_value(srvr, i); + fprintf(stderr, "%p:%s\n", (void *)c, c->name); + } + fprintf(stderr, "Client sent %d from %p:\n", sk_SSL_CIPHER_num(clnt), + (void *)clnt); + for (i = 0; i < sk_SSL_CIPHER_num(clnt); ++i) { + c = sk_SSL_CIPHER_value(clnt, i); + fprintf(stderr, "%p:%s\n", (void *)c, c->name); + } +#endif + + if (s->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + prio = srvr; + allow = clnt; + } else { + prio = clnt; + allow = srvr; + } + + for (i = 0; i < sk_SSL_CIPHER_num(prio); i++) { + c = sk_SSL_CIPHER_value(prio, i); + + /* Skip TLS v1.2 only ciphersuites if lower than v1.2 */ + if ((c->algorithm_ssl & SSL_TLSV1_2) && + (TLS1_get_version(s) < TLS1_2_VERSION)) + continue; + + ssl_set_cert_masks(cert, c); + mask_k = cert->mask_k; + mask_a = cert->mask_a; + emask_k = cert->export_mask_k; + emask_a = cert->export_mask_a; +#ifndef OPENSSL_NO_SRP + if (s->srp_ctx.srp_Mask & SSL_kSRP) { + mask_k |= SSL_kSRP; + emask_k |= SSL_kSRP; + mask_a |= SSL_aSRP; + emask_a |= SSL_aSRP; + } +#endif + +#ifdef KSSL_DEBUG + /* + * fprintf(stderr,"ssl3_choose_cipher %d alg= %lx\n", + * i,c->algorithms); + */ +#endif /* KSSL_DEBUG */ + + alg_k = c->algorithm_mkey; + alg_a = c->algorithm_auth; + +#ifndef OPENSSL_NO_KRB5 + if (alg_k & SSL_kKRB5) { + if (!kssl_keytab_is_available(s->kssl_ctx)) + continue; + } +#endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_PSK + /* with PSK there must be server callback set */ + if ((alg_k & SSL_kPSK) && s->psk_server_callback == NULL) + continue; +#endif /* OPENSSL_NO_PSK */ + + if (SSL_C_IS_EXPORT(c)) { + ok = (alg_k & emask_k) && (alg_a & emask_a); +#ifdef CIPHER_DEBUG + fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s (export)\n", + ok, alg_k, alg_a, emask_k, emask_a, (void *)c, c->name); +#endif + } else { + ok = (alg_k & mask_k) && (alg_a & mask_a); +#ifdef CIPHER_DEBUG + fprintf(stderr, "%d:[%08lX:%08lX:%08lX:%08lX]%p:%s\n", ok, alg_k, + alg_a, mask_k, mask_a, (void *)c, c->name); +#endif + } + +#ifndef OPENSSL_NO_TLSEXT +# ifndef OPENSSL_NO_EC + if ( + /* + * if we are considering an ECC cipher suite that uses our + * certificate + */ + (alg_a & SSL_aECDSA || alg_a & SSL_aECDH) + /* and we have an ECC certificate */ + && (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL) + /* + * and the client specified a Supported Point Formats + * extension + */ + && ((s->session->tlsext_ecpointformatlist_length > 0) + && (s->session->tlsext_ecpointformatlist != NULL)) + /* and our certificate's point is compressed */ + && ((s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info != NULL) + && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info->key != + NULL) + && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info-> + key->public_key != NULL) + && (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info-> + key->public_key->data != NULL) + && + ((* + (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info-> + key->public_key->data) == POINT_CONVERSION_COMPRESSED) + || + (* + (s->cert->pkeys[SSL_PKEY_ECC].x509->cert_info-> + key->public_key->data) == + POINT_CONVERSION_COMPRESSED + 1) + ) + ) + ) { + ec_ok = 0; + /* + * if our certificate's curve is over a field type that the + * client does not support then do not allow this cipher suite to + * be negotiated + */ + if ((s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL) + && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != + NULL) + && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec-> + group->meth != NULL) + && + (EC_METHOD_get_field_type + (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec-> + group->meth) == NID_X9_62_prime_field) + ) { + for (j = 0; j < s->session->tlsext_ecpointformatlist_length; + j++) { + if (s->session->tlsext_ecpointformatlist[j] == + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime) { + ec_ok = 1; + break; + } + } + } else + if (EC_METHOD_get_field_type + (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec-> + group->meth) == NID_X9_62_characteristic_two_field) { + for (j = 0; j < s->session->tlsext_ecpointformatlist_length; + j++) { + if (s->session->tlsext_ecpointformatlist[j] == + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2) { + ec_ok = 1; + break; + } + } + } + ok = ok && ec_ok; + } + if ( + /* + * if we are considering an ECC cipher suite that uses our + * certificate + */ + (alg_a & SSL_aECDSA || alg_a & SSL_aECDH) + /* and we have an ECC certificate */ + && (s->cert->pkeys[SSL_PKEY_ECC].x509 != NULL) + /* + * and the client specified an EllipticCurves extension + */ + && ((s->session->tlsext_ellipticcurvelist_length > 0) + && (s->session->tlsext_ellipticcurvelist != NULL)) + ) { + ec_ok = 0; + if ((s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec != NULL) + && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec->group != + NULL) + ) { + ec_nid = + EC_GROUP_get_curve_name(s->cert-> + pkeys[SSL_PKEY_ECC].privatekey-> + pkey.ec->group); + if ((ec_nid == 0) + && (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey. + ec->group->meth != NULL) + ) { + if (EC_METHOD_get_field_type + (s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey. + ec->group->meth) == NID_X9_62_prime_field) { + ec_search1 = 0xFF; + ec_search2 = 0x01; + } else + if (EC_METHOD_get_field_type + (s->cert->pkeys[SSL_PKEY_ECC].privatekey-> + pkey.ec->group->meth) == + NID_X9_62_characteristic_two_field) { + ec_search1 = 0xFF; + ec_search2 = 0x02; + } + } else { + ec_search1 = 0x00; + ec_search2 = tls1_ec_nid2curve_id(ec_nid); + } + if ((ec_search1 != 0) || (ec_search2 != 0)) { + for (j = 0; + j < s->session->tlsext_ellipticcurvelist_length / 2; + j++) { + if ((s->session->tlsext_ellipticcurvelist[2 * j] == + ec_search1) + && (s->session->tlsext_ellipticcurvelist[2 * j + + 1] == + ec_search2)) { + ec_ok = 1; + break; + } + } + } + } + ok = ok && ec_ok; + } +# ifndef OPENSSL_NO_ECDH + if ( + /* + * if we are considering an ECC cipher suite that uses an + * ephemeral EC key + */ + (alg_k & SSL_kEECDH) + /* and we have an ephemeral EC key */ + && (s->cert->ecdh_tmp != NULL) + /* + * and the client specified an EllipticCurves extension + */ + && ((s->session->tlsext_ellipticcurvelist_length > 0) + && (s->session->tlsext_ellipticcurvelist != NULL)) + ) { + ec_ok = 0; + if (s->cert->ecdh_tmp->group != NULL) { + ec_nid = EC_GROUP_get_curve_name(s->cert->ecdh_tmp->group); + if ((ec_nid == 0) + && (s->cert->ecdh_tmp->group->meth != NULL) + ) { + if (EC_METHOD_get_field_type + (s->cert->ecdh_tmp->group->meth) == + NID_X9_62_prime_field) { + ec_search1 = 0xFF; + ec_search2 = 0x01; + } else + if (EC_METHOD_get_field_type + (s->cert->ecdh_tmp->group->meth) == + NID_X9_62_characteristic_two_field) { + ec_search1 = 0xFF; + ec_search2 = 0x02; + } + } else { + ec_search1 = 0x00; + ec_search2 = tls1_ec_nid2curve_id(ec_nid); + } + if ((ec_search1 != 0) || (ec_search2 != 0)) { + for (j = 0; + j < s->session->tlsext_ellipticcurvelist_length / 2; + j++) { + if ((s->session->tlsext_ellipticcurvelist[2 * j] == + ec_search1) + && (s->session->tlsext_ellipticcurvelist[2 * j + + 1] == + ec_search2)) { + ec_ok = 1; + break; + } + } + } + } + ok = ok && ec_ok; + } +# endif /* OPENSSL_NO_ECDH */ +# endif /* OPENSSL_NO_EC */ +#endif /* OPENSSL_NO_TLSEXT */ + + if (!ok) + continue; + ii = sk_SSL_CIPHER_find(allow, c); + if (ii >= 0) { +#if !defined(OPENSSL_NO_EC) && !defined(OPENSSL_NO_TLSEXT) + if ((alg_k & SSL_kEECDH) && (alg_a & SSL_aECDSA) + && s->s3->is_probably_safari) { + if (!ret) + ret = sk_SSL_CIPHER_value(allow, ii); + continue; + } +#endif + ret = sk_SSL_CIPHER_value(allow, ii); + break; + } + } + return (ret); +} + +int ssl3_get_req_cert_type(SSL *s, unsigned char *p) +{ + int ret = 0; + unsigned long alg_k; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + +#ifndef OPENSSL_NO_GOST + if (s->version >= TLS1_VERSION) { + if (alg_k & SSL_kGOST) { + p[ret++] = TLS_CT_GOST94_SIGN; + p[ret++] = TLS_CT_GOST01_SIGN; + return (ret); + } + } +#endif + +#ifndef OPENSSL_NO_DH + if (alg_k & (SSL_kDHr | SSL_kEDH)) { +# ifndef OPENSSL_NO_RSA + p[ret++] = SSL3_CT_RSA_FIXED_DH; +# endif +# ifndef OPENSSL_NO_DSA + p[ret++] = SSL3_CT_DSS_FIXED_DH; +# endif + } + if ((s->version == SSL3_VERSION) && + (alg_k & (SSL_kEDH | SSL_kDHd | SSL_kDHr))) { +# ifndef OPENSSL_NO_RSA + p[ret++] = SSL3_CT_RSA_EPHEMERAL_DH; +# endif +# ifndef OPENSSL_NO_DSA + p[ret++] = SSL3_CT_DSS_EPHEMERAL_DH; +# endif + } +#endif /* !OPENSSL_NO_DH */ +#ifndef OPENSSL_NO_RSA + p[ret++] = SSL3_CT_RSA_SIGN; +#endif +#ifndef OPENSSL_NO_DSA + p[ret++] = SSL3_CT_DSS_SIGN; +#endif +#ifndef OPENSSL_NO_ECDH + if ((alg_k & (SSL_kECDHr | SSL_kECDHe)) && (s->version >= TLS1_VERSION)) { + p[ret++] = TLS_CT_RSA_FIXED_ECDH; + p[ret++] = TLS_CT_ECDSA_FIXED_ECDH; + } +#endif + +#ifndef OPENSSL_NO_ECDSA + /* + * ECDSA certs can be used with RSA cipher suites as well so we don't + * need to check for SSL_kECDH or SSL_kEECDH + */ + if (s->version >= TLS1_VERSION) { + p[ret++] = TLS_CT_ECDSA_SIGN; + } +#endif + return (ret); +} + +int ssl3_shutdown(SSL *s) +{ + int ret; + + /* + * Don't do anything much if we have not done the handshake or we don't + * want to send messages :-) + */ + if ((s->quiet_shutdown) || (s->state == SSL_ST_BEFORE)) { + s->shutdown = (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN); + return (1); + } + + if (!(s->shutdown & SSL_SENT_SHUTDOWN)) { + s->shutdown |= SSL_SENT_SHUTDOWN; +#if 1 + ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY); +#endif + /* + * our shutdown alert has been sent now, and if it still needs to be + * written, s->s3->alert_dispatch will be true + */ + if (s->s3->alert_dispatch) + return (-1); /* return WANT_WRITE */ + } else if (s->s3->alert_dispatch) { + /* resend it if not sent */ +#if 1 + ret = s->method->ssl_dispatch_alert(s); + if (ret == -1) { + /* + * we only get to return -1 here the 2nd/Nth invocation, we must + * have already signalled return 0 upon a previous invoation, + * return WANT_WRITE + */ + return (ret); + } +#endif + } else if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) { + /* + * If we are waiting for a close from our peer, we are closed + */ + s->method->ssl_read_bytes(s, 0, NULL, 0, 0); + if (!(s->shutdown & SSL_RECEIVED_SHUTDOWN)) { + return (-1); /* return WANT_READ */ + } + } + + if ((s->shutdown == (SSL_SENT_SHUTDOWN | SSL_RECEIVED_SHUTDOWN)) && + !s->s3->alert_dispatch) + return (1); + else + return (0); +} + +int ssl3_write(SSL *s, const void *buf, int len) +{ + int ret, n; + +#if 0 + if (s->shutdown & SSL_SEND_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + return (0); + } +#endif + clear_sys_error(); + if (s->s3->renegotiate) + ssl3_renegotiate_check(s); + + /* + * This is an experimental flag that sends the last handshake message in + * the same packet as the first use data - used to see if it helps the + * TCP protocol during session-id reuse + */ + /* The second test is because the buffer may have been removed */ + if ((s->s3->flags & SSL3_FLAGS_POP_BUFFER) && (s->wbio == s->bbio)) { + /* First time through, we write into the buffer */ + if (s->s3->delay_buf_pop_ret == 0) { + ret = ssl3_write_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len); + if (ret <= 0) + return (ret); + + s->s3->delay_buf_pop_ret = ret; + } + + s->rwstate = SSL_WRITING; + n = BIO_flush(s->wbio); + if (n <= 0) + return (n); + s->rwstate = SSL_NOTHING; + + /* We have flushed the buffer, so remove it */ + ssl_free_wbio_buffer(s); + s->s3->flags &= ~SSL3_FLAGS_POP_BUFFER; + + ret = s->s3->delay_buf_pop_ret; + s->s3->delay_buf_pop_ret = 0; + } else { + ret = s->method->ssl_write_bytes(s, SSL3_RT_APPLICATION_DATA, + buf, len); + if (ret <= 0) + return (ret); + } + + return (ret); +} + +static int ssl3_read_internal(SSL *s, void *buf, int len, int peek) +{ + int ret; + + clear_sys_error(); + if (s->s3->renegotiate) + ssl3_renegotiate_check(s); + s->s3->in_read_app_data = 1; + ret = + s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len, + peek); + if ((ret == -1) && (s->s3->in_read_app_data == 2)) { + /* + * ssl3_read_bytes decided to call s->handshake_func, which called + * ssl3_read_bytes to read handshake data. However, ssl3_read_bytes + * actually found application data and thinks that application data + * makes sense here; so disable handshake processing and try to read + * application data again. + */ + s->in_handshake++; + ret = + s->method->ssl_read_bytes(s, SSL3_RT_APPLICATION_DATA, buf, len, + peek); + s->in_handshake--; + } else + s->s3->in_read_app_data = 0; + + return (ret); +} + +int ssl3_read(SSL *s, void *buf, int len) +{ + return ssl3_read_internal(s, buf, len, 0); +} + +int ssl3_peek(SSL *s, void *buf, int len) +{ + return ssl3_read_internal(s, buf, len, 1); +} + +int ssl3_renegotiate(SSL *s) +{ + if (s->handshake_func == NULL) + return (1); + + if (s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) + return (0); + + s->s3->renegotiate = 1; + return (1); +} + +int ssl3_renegotiate_check(SSL *s) +{ + int ret = 0; + + if (s->s3->renegotiate) { + if ((s->s3->rbuf.left == 0) && + (s->s3->wbuf.left == 0) && !SSL_in_init(s)) { + /* + * if we are the server, and we have sent a 'RENEGOTIATE' + * message, we need to go to SSL_ST_ACCEPT. + */ + /* SSL_ST_ACCEPT */ + s->state = SSL_ST_RENEGOTIATE; + s->s3->renegotiate = 0; + s->s3->num_renegotiations++; + s->s3->total_renegotiations++; + ret = 1; + } + } + return (ret); +} + +/* + * If we are using TLS v1.2 or later and default SHA1+MD5 algorithms switch + * to new SHA256 PRF and handshake macs + */ +long ssl_get_algorithm2(SSL *s) +{ + long alg2 = s->s3->tmp.new_cipher->algorithm2; + if (s->method->version == TLS1_2_VERSION && + alg2 == (SSL_HANDSHAKE_MAC_DEFAULT | TLS1_PRF)) + return SSL_HANDSHAKE_MAC_SHA256 | TLS1_PRF_SHA256; + return alg2; +} diff --git a/libs/openssl/ssl/s3_meth.c b/libs/openssl/ssl/s3_meth.c new file mode 100644 index 00000000..e5a52993 --- /dev/null +++ b/libs/openssl/ssl/s3_meth.c @@ -0,0 +1,74 @@ +/* ssl/s3_meth.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "ssl_locl.h" + +#ifndef OPENSSL_NO_SSL3_METHOD +static const SSL_METHOD *ssl3_get_method(int ver) +{ + if (ver == SSL3_VERSION) + return (SSLv3_method()); + else + return (NULL); +} + +IMPLEMENT_ssl3_meth_func(SSLv3_method, + ssl3_accept, ssl3_connect, ssl3_get_method) +#endif diff --git a/libs/openssl/ssl/s3_pkt.c b/libs/openssl/ssl/s3_pkt.c new file mode 100644 index 00000000..25cf929a --- /dev/null +++ b/libs/openssl/ssl/s3_pkt.c @@ -0,0 +1,1576 @@ +/* ssl/s3_pkt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#define USE_SOCKETS +#include "ssl_locl.h" +#include +#include +#include + +static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, + unsigned int len, int create_empty_fragment); +static int ssl3_get_record(SSL *s); + +int ssl3_read_n(SSL *s, int n, int max, int extend) +{ + /* + * If extend == 0, obtain new n-byte packet; if extend == 1, increase + * packet by another n bytes. The packet will be in the sub-array of + * s->s3->rbuf.buf specified by s->packet and s->packet_length. (If + * s->read_ahead is set, 'max' bytes may be stored in rbuf [plus + * s->packet_length bytes if extend == 1].) + */ + int i, len, left; + long align = 0; + unsigned char *pkt; + SSL3_BUFFER *rb; + + if (n <= 0) + return n; + + rb = &(s->s3->rbuf); + if (rb->buf == NULL) + if (!ssl3_setup_read_buffer(s)) + return -1; + + left = rb->left; +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 + align = (long)rb->buf + SSL3_RT_HEADER_LENGTH; + align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); +#endif + + if (!extend) { + /* start with empty packet ... */ + if (left == 0) + rb->offset = align; + else if (align != 0 && left >= SSL3_RT_HEADER_LENGTH) { + /* + * check if next packet length is large enough to justify payload + * alignment... + */ + pkt = rb->buf + rb->offset; + if (pkt[0] == SSL3_RT_APPLICATION_DATA + && (pkt[3] << 8 | pkt[4]) >= 128) { + /* + * Note that even if packet is corrupted and its length field + * is insane, we can only be led to wrong decision about + * whether memmove will occur or not. Header values has no + * effect on memmove arguments and therefore no buffer + * overrun can be triggered. + */ + memmove(rb->buf + align, pkt, left); + rb->offset = align; + } + } + s->packet = rb->buf + rb->offset; + s->packet_length = 0; + /* ... now we can act as if 'extend' was set */ + } + + /* + * For DTLS/UDP reads should not span multiple packets because the read + * operation returns the whole packet at once (as long as it fits into + * the buffer). + */ + if (SSL_version(s) == DTLS1_VERSION || SSL_version(s) == DTLS1_BAD_VER) { + if (left == 0 && extend) + return 0; + if (left > 0 && n > left) + n = left; + } + + /* if there is enough in the buffer from a previous read, take some */ + if (left >= n) { + s->packet_length += n; + rb->left = left - n; + rb->offset += n; + return (n); + } + + /* else we need to read more data */ + + len = s->packet_length; + pkt = rb->buf + align; + /* + * Move any available bytes to front of buffer: 'len' bytes already + * pointed to by 'packet', 'left' extra ones at the end + */ + if (s->packet != pkt) { /* len > 0 */ + memmove(pkt, s->packet, len + left); + s->packet = pkt; + rb->offset = len + align; + } + + if (n > (int)(rb->len - rb->offset)) { /* does not happen */ + SSLerr(SSL_F_SSL3_READ_N, ERR_R_INTERNAL_ERROR); + return -1; + } + + /* We always act like read_ahead is set for DTLS */ + if (!s->read_ahead && !SSL_IS_DTLS(s)) + /* ignore max parameter */ + max = n; + else { + if (max < n) + max = n; + if (max > (int)(rb->len - rb->offset)) + max = rb->len - rb->offset; + } + + while (left < n) { + /* + * Now we have len+left bytes at the front of s->s3->rbuf.buf and + * need to read in more until we have len+n (up to len+max if + * possible) + */ + + clear_sys_error(); + if (s->rbio != NULL) { + s->rwstate = SSL_READING; + i = BIO_read(s->rbio, pkt + len + left, max - left); + } else { + SSLerr(SSL_F_SSL3_READ_N, SSL_R_READ_BIO_NOT_SET); + i = -1; + } + + if (i <= 0) { + rb->left = left; + if (s->mode & SSL_MODE_RELEASE_BUFFERS && + SSL_version(s) != DTLS1_VERSION + && SSL_version(s) != DTLS1_BAD_VER) + if (len + left == 0) + ssl3_release_read_buffer(s); + return (i); + } + left += i; + /* + * reads should *never* span multiple packets for DTLS because the + * underlying transport protocol is message oriented as opposed to + * byte oriented as in the TLS case. + */ + if (SSL_version(s) == DTLS1_VERSION + || SSL_version(s) == DTLS1_BAD_VER) { + if (n > left) + n = left; /* makes the while condition false */ + } + } + + /* done reading, now the book-keeping */ + rb->offset += n; + rb->left = left - n; + s->packet_length += n; + s->rwstate = SSL_NOTHING; + return (n); +} + +/* + * MAX_EMPTY_RECORDS defines the number of consecutive, empty records that + * will be processed per call to ssl3_get_record. Without this limit an + * attacker could send empty records at a faster rate than we can process and + * cause ssl3_get_record to loop forever. + */ +#define MAX_EMPTY_RECORDS 32 + +/*- + * Call this to get a new input record. + * It will return <= 0 if more data is needed, normally due to an error + * or non-blocking IO. + * When it finishes, one packet has been decoded and can be found in + * ssl->s3->rrec.type - is the type of record + * ssl->s3->rrec.data, - data + * ssl->s3->rrec.length, - number of bytes + */ +/* used only by ssl3_read_bytes */ +static int ssl3_get_record(SSL *s) +{ + int ssl_major, ssl_minor, al; + int enc_err, n, i, ret = -1; + SSL3_RECORD *rr; + SSL_SESSION *sess; + unsigned char *p; + unsigned char md[EVP_MAX_MD_SIZE]; + short version; + unsigned mac_size, orig_len; + size_t extra; + unsigned empty_record_count = 0; + + rr = &(s->s3->rrec); + sess = s->session; + + if (s->options & SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER) + extra = SSL3_RT_MAX_EXTRA; + else + extra = 0; + if (extra && !s->s3->init_extra) { + /* + * An application error: SLS_OP_MICROSOFT_BIG_SSLV3_BUFFER set after + * ssl3_setup_buffers() was done + */ + SSLerr(SSL_F_SSL3_GET_RECORD, ERR_R_INTERNAL_ERROR); + return -1; + } + + again: + /* check if we have the header */ + if ((s->rstate != SSL_ST_READ_BODY) || + (s->packet_length < SSL3_RT_HEADER_LENGTH)) { + n = ssl3_read_n(s, SSL3_RT_HEADER_LENGTH, s->s3->rbuf.len, 0); + if (n <= 0) + return (n); /* error or non-blocking */ + s->rstate = SSL_ST_READ_BODY; + + p = s->packet; + + /* Pull apart the header into the SSL3_RECORD */ + rr->type = *(p++); + ssl_major = *(p++); + ssl_minor = *(p++); + version = (ssl_major << 8) | ssl_minor; + n2s(p, rr->length); +#if 0 + fprintf(stderr, "Record type=%d, Length=%d\n", rr->type, rr->length); +#endif + + /* Lets check version */ + if (!s->first_packet) { + if (version != s->version) { + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER); + if ((s->version & 0xFF00) == (version & 0xFF00) + && !s->enc_write_ctx && !s->write_hash) { + if (rr->type == SSL3_RT_ALERT) { + /* + * The record is using an incorrect version number, but + * what we've got appears to be an alert. We haven't + * read the body yet to check whether its a fatal or + * not - but chances are it is. We probably shouldn't + * send a fatal alert back. We'll just end. + */ + goto err; + } + /* + * Send back error using their minor version number :-) + */ + s->version = (unsigned short)version; + } + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + } + + if ((version >> 8) != SSL3_VERSION_MAJOR) { + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_WRONG_VERSION_NUMBER); + goto err; + } + + if (rr->length > s->s3->rbuf.len - SSL3_RT_HEADER_LENGTH) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_PACKET_LENGTH_TOO_LONG); + goto f_err; + } + + /* now s->rstate == SSL_ST_READ_BODY */ + } + + /* s->rstate == SSL_ST_READ_BODY, get and decode the data */ + + if (rr->length > s->packet_length - SSL3_RT_HEADER_LENGTH) { + /* now s->packet_length == SSL3_RT_HEADER_LENGTH */ + i = rr->length; + n = ssl3_read_n(s, i, i, 1); + if (n <= 0) + return (n); /* error or non-blocking io */ + /* + * now n == rr->length, and s->packet_length == SSL3_RT_HEADER_LENGTH + * + rr->length + */ + } + + s->rstate = SSL_ST_READ_HEADER; /* set state for later operations */ + + /* + * At this point, s->packet_length == SSL3_RT_HEADER_LNGTH + rr->length, + * and we have that many bytes in s->packet + */ + rr->input = &(s->packet[SSL3_RT_HEADER_LENGTH]); + + /* + * ok, we can now read from 's->packet' data into 'rr' rr->input points + * at rr->length bytes, which need to be copied into rr->data by either + * the decryption or by the decompression When the data is 'copied' into + * the rr->data buffer, rr->input will be pointed at the new buffer + */ + + /* + * We now have - encrypted [ MAC [ compressed [ plain ] ] ] rr->length + * bytes of encrypted compressed stuff. + */ + + /* check is not needed I believe */ + if (rr->length > SSL3_RT_MAX_ENCRYPTED_LENGTH + extra) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + goto f_err; + } + + /* decrypt in place in 'rr->input' */ + rr->data = rr->input; + + enc_err = s->method->ssl3_enc->enc(s, 0); + /*- + * enc_err is: + * 0: (in non-constant time) if the record is publically invalid. + * 1: if the padding is valid + * -1: if the padding is invalid + */ + if (enc_err == 0) { + al = SSL_AD_DECRYPTION_FAILED; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BLOCK_CIPHER_PAD_IS_WRONG); + goto f_err; + } +#ifdef TLS_DEBUG + printf("dec %d\n", rr->length); + { + unsigned int z; + for (z = 0; z < rr->length; z++) + printf("%02X%c", rr->data[z], ((z + 1) % 16) ? ' ' : '\n'); + } + printf("\n"); +#endif + + /* r->length is now the compressed data plus mac */ + if ((sess != NULL) && + (s->enc_read_ctx != NULL) && (EVP_MD_CTX_md(s->read_hash) != NULL)) { + /* s->read_hash != NULL => mac_size != -1 */ + unsigned char *mac = NULL; + unsigned char mac_tmp[EVP_MAX_MD_SIZE]; + mac_size = EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(mac_size <= EVP_MAX_MD_SIZE); + + /* + * kludge: *_cbc_remove_padding passes padding length in rr->type + */ + orig_len = rr->length + ((unsigned int)rr->type >> 8); + + /* + * orig_len is the length of the record before any padding was + * removed. This is public information, as is the MAC in use, + * therefore we can safely process the record in a different amount + * of time if it's too short to possibly contain a MAC. + */ + if (orig_len < mac_size || + /* CBC records must have a padding length byte too. */ + (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE && + orig_len < mac_size + 1)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + if (EVP_CIPHER_CTX_mode(s->enc_read_ctx) == EVP_CIPH_CBC_MODE) { + /* + * We update the length so that the TLS header bytes can be + * constructed correctly but we need to extract the MAC in + * constant time from within the record, without leaking the + * contents of the padding bytes. + */ + mac = mac_tmp; + ssl3_cbc_copy_mac(mac_tmp, rr, mac_size, orig_len); + rr->length -= mac_size; + } else { + /* + * In this case there's no padding, so |orig_len| equals + * |rec->length| and we checked that there's enough bytes for + * |mac_size| above. + */ + rr->length -= mac_size; + mac = &rr->data[rr->length]; + } + + i = s->method->ssl3_enc->mac(s, md, 0 /* not send */ ); + if (i < 0 || mac == NULL + || CRYPTO_memcmp(md, mac, (size_t)mac_size) != 0) + enc_err = -1; + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + extra + mac_size) + enc_err = -1; + } + + if (enc_err < 0) { + /* + * A separate 'decryption_failed' alert was introduced with TLS 1.0, + * SSL 3.0 only has 'bad_record_mac'. But unless a decryption + * failure is directly visible from the ciphertext anyway, we should + * not reveal which kind of error occured -- this might become + * visible to an attacker (e.g. via a logfile) + */ + al = SSL_AD_BAD_RECORD_MAC; + SSLerr(SSL_F_SSL3_GET_RECORD, + SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + goto f_err; + } + + /* r->length is now just compressed */ + if (s->expand != NULL) { + if (rr->length > SSL3_RT_MAX_COMPRESSED_LENGTH + extra) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_COMPRESSED_LENGTH_TOO_LONG); + goto f_err; + } + if (!ssl3_do_uncompress(s)) { + al = SSL_AD_DECOMPRESSION_FAILURE; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_BAD_DECOMPRESSION); + goto f_err; + } + } + + if (rr->length > SSL3_RT_MAX_PLAIN_LENGTH + extra) { + al = SSL_AD_RECORD_OVERFLOW; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_DATA_LENGTH_TOO_LONG); + goto f_err; + } + + rr->off = 0; + /*- + * So at this point the following is true + * ssl->s3->rrec.type is the type of record + * ssl->s3->rrec.length == number of bytes in record + * ssl->s3->rrec.off == offset to first valid byte + * ssl->s3->rrec.data == where to take bytes from, increment + * after use :-). + */ + + /* we have pulled in a full packet so zero things */ + s->packet_length = 0; + + /* just read a 0 length packet */ + if (rr->length == 0) { + empty_record_count++; + if (empty_record_count > MAX_EMPTY_RECORDS) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_RECORD, SSL_R_RECORD_TOO_SMALL); + goto f_err; + } + goto again; + } +#if 0 + fprintf(stderr, "Ultimate Record type=%d, Length=%d\n", rr->type, + rr->length); +#endif + + return (1); + + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (ret); +} + +int ssl3_do_uncompress(SSL *ssl) +{ +#ifndef OPENSSL_NO_COMP + int i; + SSL3_RECORD *rr; + + rr = &(ssl->s3->rrec); + i = COMP_expand_block(ssl->expand, rr->comp, + SSL3_RT_MAX_PLAIN_LENGTH, rr->data, + (int)rr->length); + if (i < 0) + return (0); + else + rr->length = i; + rr->data = rr->comp; +#endif + return (1); +} + +int ssl3_do_compress(SSL *ssl) +{ +#ifndef OPENSSL_NO_COMP + int i; + SSL3_RECORD *wr; + + wr = &(ssl->s3->wrec); + i = COMP_compress_block(ssl->compress, wr->data, + SSL3_RT_MAX_COMPRESSED_LENGTH, + wr->input, (int)wr->length); + if (i < 0) + return (0); + else + wr->length = i; + + wr->input = wr->data; +#endif + return (1); +} + +/* + * Call this to write data in records of type 'type' It will return <= 0 if + * not all data has been sent or non-blocking IO. + */ +int ssl3_write_bytes(SSL *s, int type, const void *buf_, int len) +{ + const unsigned char *buf = buf_; + unsigned int n, nw; + int i, tot; + + s->rwstate = SSL_NOTHING; + OPENSSL_assert(s->s3->wnum <= INT_MAX); + tot = s->s3->wnum; + s->s3->wnum = 0; + + if (SSL_in_init(s) && !s->in_handshake) { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + /* + * ensure that if we end up with a smaller value of data to write out + * than the the original len from a write which didn't complete for + * non-blocking I/O and also somehow ended up avoiding the check for + * this in ssl3_write_pending/SSL_R_BAD_WRITE_RETRY as it must never be + * possible to end up with (len-tot) as a large number that will then + * promptly send beyond the end of the users buffer ... so we trap and + * report the error in a way the user will notice + */ + if (len < tot) { + SSLerr(SSL_F_SSL3_WRITE_BYTES, SSL_R_BAD_LENGTH); + return (-1); + } + + n = (len - tot); + for (;;) { + if (n > s->max_send_fragment) + nw = s->max_send_fragment; + else + nw = n; + + i = do_ssl3_write(s, type, &(buf[tot]), nw, 0); + if (i <= 0) { + s->s3->wnum = tot; + return i; + } + + if ((i == (int)n) || + (type == SSL3_RT_APPLICATION_DATA && + (s->mode & SSL_MODE_ENABLE_PARTIAL_WRITE))) { + /* + * next chunk of data should get another prepended empty fragment + * in ciphersuites with known-IV weakness: + */ + s->s3->empty_fragment_done = 0; + + return tot + i; + } + + n -= i; + tot += i; + } +} + +static int do_ssl3_write(SSL *s, int type, const unsigned char *buf, + unsigned int len, int create_empty_fragment) +{ + unsigned char *p, *plen; + int i, mac_size, clear = 0; + int prefix_len = 0; + int eivlen; + long align = 0; + SSL3_RECORD *wr; + SSL3_BUFFER *wb = &(s->s3->wbuf); + SSL_SESSION *sess; + + /* + * first check if there is a SSL3_BUFFER still being written out. This + * will happen with non blocking IO + */ + if (wb->left != 0) + return (ssl3_write_pending(s, type, buf, len)); + + /* If we have an alert to send, lets send it */ + if (s->s3->alert_dispatch) { + i = s->method->ssl_dispatch_alert(s); + if (i <= 0) + return (i); + /* if it went, fall through and send more stuff */ + } + + if (wb->buf == NULL) + if (!ssl3_setup_write_buffer(s)) + return -1; + + if (len == 0 && !create_empty_fragment) + return 0; + + wr = &(s->s3->wrec); + sess = s->session; + + if ((sess == NULL) || + (s->enc_write_ctx == NULL) || + (EVP_MD_CTX_md(s->write_hash) == NULL)) { +#if 1 + clear = s->enc_write_ctx ? 0 : 1; /* must be AEAD cipher */ +#else + clear = 1; +#endif + mac_size = 0; + } else { + mac_size = EVP_MD_CTX_size(s->write_hash); + if (mac_size < 0) + goto err; + } + + /* + * 'create_empty_fragment' is true only when this function calls itself + */ + if (!clear && !create_empty_fragment && !s->s3->empty_fragment_done) { + /* + * countermeasure against known-IV weakness in CBC ciphersuites (see + * http://www.openssl.org/~bodo/tls-cbc.txt) + */ + + if (s->s3->need_empty_fragments && type == SSL3_RT_APPLICATION_DATA) { + /* + * recursive function call with 'create_empty_fragment' set; this + * prepares and buffers the data for an empty fragment (these + * 'prefix_len' bytes are sent out later together with the actual + * payload) + */ + prefix_len = do_ssl3_write(s, type, buf, 0, 1); + if (prefix_len <= 0) + goto err; + + if (prefix_len > + (SSL3_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD)) + { + /* insufficient space */ + SSLerr(SSL_F_DO_SSL3_WRITE, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + s->s3->empty_fragment_done = 1; + } + + if (create_empty_fragment) { +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 + /* + * extra fragment would be couple of cipher blocks, which would be + * multiple of SSL3_ALIGN_PAYLOAD, so if we want to align the real + * payload, then we can just pretent we simply have two headers. + */ + align = (long)wb->buf + 2 * SSL3_RT_HEADER_LENGTH; + align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); +#endif + p = wb->buf + align; + wb->offset = align; + } else if (prefix_len) { + p = wb->buf + wb->offset + prefix_len; + } else { +#if defined(SSL3_ALIGN_PAYLOAD) && SSL3_ALIGN_PAYLOAD!=0 + align = (long)wb->buf + SSL3_RT_HEADER_LENGTH; + align = (-align) & (SSL3_ALIGN_PAYLOAD - 1); +#endif + p = wb->buf + align; + wb->offset = align; + } + + /* write the header */ + + *(p++) = type & 0xff; + wr->type = type; + + *(p++) = (s->version >> 8); + /* + * Some servers hang if iniatial client hello is larger than 256 bytes + * and record version number > TLS 1.0 + */ + if (s->state == SSL3_ST_CW_CLNT_HELLO_B + && !s->renegotiate && TLS1_get_version(s) > TLS1_VERSION) + *(p++) = 0x1; + else + *(p++) = s->version & 0xff; + + /* field where we are to write out packet length */ + plen = p; + p += 2; + /* Explicit IV length, block ciphers and TLS version 1.1 or later */ + if (s->enc_write_ctx && s->version >= TLS1_1_VERSION) { + int mode = EVP_CIPHER_CTX_mode(s->enc_write_ctx); + if (mode == EVP_CIPH_CBC_MODE) { + eivlen = EVP_CIPHER_CTX_iv_length(s->enc_write_ctx); + if (eivlen <= 1) + eivlen = 0; + } + /* Need explicit part of IV for GCM mode */ + else if (mode == EVP_CIPH_GCM_MODE) + eivlen = EVP_GCM_TLS_EXPLICIT_IV_LEN; + else + eivlen = 0; + } else + eivlen = 0; + + /* lets setup the record stuff. */ + wr->data = p + eivlen; + wr->length = (int)len; + wr->input = (unsigned char *)buf; + + /* + * we now 'read' from wr->input, wr->length bytes into wr->data + */ + + /* first we compress */ + if (s->compress != NULL) { + if (!ssl3_do_compress(s)) { + SSLerr(SSL_F_DO_SSL3_WRITE, SSL_R_COMPRESSION_FAILURE); + goto err; + } + } else { + memcpy(wr->data, wr->input, wr->length); + wr->input = wr->data; + } + + /* + * we should still have the output to wr->data and the input from + * wr->input. Length should be wr->length. wr->data still points in the + * wb->buf + */ + + if (mac_size != 0) { + if (s->method->ssl3_enc->mac(s, &(p[wr->length + eivlen]), 1) < 0) + goto err; + wr->length += mac_size; + } + + wr->input = p; + wr->data = p; + + if (eivlen) { + /* + * if (RAND_pseudo_bytes(p, eivlen) <= 0) goto err; + */ + wr->length += eivlen; + } + + if (s->method->ssl3_enc->enc(s, 1) < 1) + goto err; + + /* record length after mac and block padding */ + s2n(wr->length, plen); + + /* + * we should now have wr->data pointing to the encrypted data, which is + * wr->length long + */ + wr->type = type; /* not needed but helps for debugging */ + wr->length += SSL3_RT_HEADER_LENGTH; + + if (create_empty_fragment) { + /* + * we are in a recursive call; just return the length, don't write + * out anything here + */ + return wr->length; + } + + /* now let's set up wb */ + wb->left = prefix_len + wr->length; + + /* + * memorize arguments so that ssl3_write_pending can detect bad write + * retries later + */ + s->s3->wpend_tot = len; + s->s3->wpend_buf = buf; + s->s3->wpend_type = type; + s->s3->wpend_ret = len; + + /* we now just need to write the buffer */ + return ssl3_write_pending(s, type, buf, len); + err: + return -1; +} + +/* if s->s3->wbuf.left != 0, we need to call this */ +int ssl3_write_pending(SSL *s, int type, const unsigned char *buf, + unsigned int len) +{ + int i; + SSL3_BUFFER *wb = &(s->s3->wbuf); + +/* XXXX */ + if ((s->s3->wpend_tot > (int)len) + || ((s->s3->wpend_buf != buf) && + !(s->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER)) + || (s->s3->wpend_type != type)) { + SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BAD_WRITE_RETRY); + return (-1); + } + + for (;;) { + clear_sys_error(); + if (s->wbio != NULL) { + s->rwstate = SSL_WRITING; + i = BIO_write(s->wbio, + (char *)&(wb->buf[wb->offset]), + (unsigned int)wb->left); + } else { + SSLerr(SSL_F_SSL3_WRITE_PENDING, SSL_R_BIO_NOT_SET); + i = -1; + } + if (i == wb->left) { + wb->left = 0; + wb->offset += i; + if (s->mode & SSL_MODE_RELEASE_BUFFERS && + SSL_version(s) != DTLS1_VERSION + && SSL_version(s) != DTLS1_BAD_VER) + ssl3_release_write_buffer(s); + s->rwstate = SSL_NOTHING; + return (s->s3->wpend_ret); + } else if (i <= 0) { + if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { + /* + * For DTLS, just drop it. That's kind of the whole point in + * using a datagram service + */ + wb->left = 0; + } + return (i); + } + wb->offset += i; + wb->left -= i; + } +} + +/*- + * Return up to 'len' payload bytes received in 'type' records. + * 'type' is one of the following: + * + * - SSL3_RT_HANDSHAKE (when ssl3_get_message calls us) + * - SSL3_RT_APPLICATION_DATA (when ssl3_read calls us) + * - 0 (during a shutdown, no data has to be returned) + * + * If we don't have stored data to work from, read a SSL/TLS record first + * (possibly multiple records if we still don't have anything to return). + * + * This function must handle any surprises the peer may have for us, such as + * Alert records (e.g. close_notify), ChangeCipherSpec records (not really + * a surprise, but handled as if it were), or renegotiation requests. + * Also if record payloads contain fragments too small to process, we store + * them until there is enough for the respective protocol (the record protocol + * may use arbitrary fragmentation and even interleaving): + * Change cipher spec protocol + * just 1 byte needed, no need for keeping anything stored + * Alert protocol + * 2 bytes needed (AlertLevel, AlertDescription) + * Handshake protocol + * 4 bytes needed (HandshakeType, uint24 length) -- we just have + * to detect unexpected Client Hello and Hello Request messages + * here, anything else is handled by higher layers + * Application data protocol + * none of our business + */ +int ssl3_read_bytes(SSL *s, int type, unsigned char *buf, int len, int peek) +{ + int al, i, j, ret; + unsigned int n; + SSL3_RECORD *rr; + void (*cb) (const SSL *ssl, int type2, int val) = NULL; + + if (s->s3->rbuf.buf == NULL) /* Not initialized yet */ + if (!ssl3_setup_read_buffer(s)) + return (-1); + + if ((type && (type != SSL3_RT_APPLICATION_DATA) + && (type != SSL3_RT_HANDSHAKE)) || (peek + && (type != + SSL3_RT_APPLICATION_DATA))) { + SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR); + return -1; + } + + if ((type == SSL3_RT_HANDSHAKE) && (s->s3->handshake_fragment_len > 0)) + /* (partially) satisfy request from storage */ + { + unsigned char *src = s->s3->handshake_fragment; + unsigned char *dst = buf; + unsigned int k; + + /* peek == 0 */ + n = 0; + while ((len > 0) && (s->s3->handshake_fragment_len > 0)) { + *dst++ = *src++; + len--; + s->s3->handshake_fragment_len--; + n++; + } + /* move any remaining fragment bytes: */ + for (k = 0; k < s->s3->handshake_fragment_len; k++) + s->s3->handshake_fragment[k] = *src++; + return n; + } + + /* + * Now s->s3->handshake_fragment_len == 0 if type == SSL3_RT_HANDSHAKE. + */ + + if (!s->in_handshake && SSL_in_init(s)) { + /* type == SSL3_RT_APPLICATION_DATA */ + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + } + start: + s->rwstate = SSL_NOTHING; + + /*- + * s->s3->rrec.type - is the type of record + * s->s3->rrec.data, - data + * s->s3->rrec.off, - offset into 'data' for next read + * s->s3->rrec.length, - number of bytes. + */ + rr = &(s->s3->rrec); + + /* get new packet if necessary */ + if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) { + ret = ssl3_get_record(s); + if (ret <= 0) + return (ret); + } + + /* we now have a packet which can be read and processed */ + + if (s->s3->change_cipher_spec /* set when we receive ChangeCipherSpec, + * reset by ssl3_get_finished */ + && (rr->type != SSL3_RT_HANDSHAKE)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_DATA_BETWEEN_CCS_AND_FINISHED); + goto f_err; + } + + /* + * If the other end has shut down, throw anything we read away (even in + * 'peek' mode) + */ + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + rr->length = 0; + s->rwstate = SSL_NOTHING; + return (0); + } + + if (type == rr->type) { /* SSL3_RT_APPLICATION_DATA or + * SSL3_RT_HANDSHAKE */ + /* + * make sure that we are not getting application data when we are + * doing a handshake for the first time + */ + if (SSL_in_init(s) && (type == SSL3_RT_APPLICATION_DATA) && + (s->enc_read_ctx == NULL)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_APP_DATA_IN_HANDSHAKE); + goto f_err; + } + + if (len <= 0) + return (len); + + if ((unsigned int)len > rr->length) + n = rr->length; + else + n = (unsigned int)len; + + memcpy(buf, &(rr->data[rr->off]), n); + if (!peek) { + rr->length -= n; + rr->off += n; + if (rr->length == 0) { + s->rstate = SSL_ST_READ_HEADER; + rr->off = 0; + if (s->mode & SSL_MODE_RELEASE_BUFFERS + && s->s3->rbuf.left == 0) + ssl3_release_read_buffer(s); + } + } + return (n); + } + + /* + * If we get here, then type != rr->type; if we have a handshake message, + * then it was unexpected (Hello Request or Client Hello). + */ + + /* + * In case of record types for which we have 'fragment' storage, fill + * that so that we can process the data at a fixed place. + */ + { + unsigned int dest_maxlen = 0; + unsigned char *dest = NULL; + unsigned int *dest_len = NULL; + + if (rr->type == SSL3_RT_HANDSHAKE) { + dest_maxlen = sizeof s->s3->handshake_fragment; + dest = s->s3->handshake_fragment; + dest_len = &s->s3->handshake_fragment_len; + } else if (rr->type == SSL3_RT_ALERT) { + dest_maxlen = sizeof s->s3->alert_fragment; + dest = s->s3->alert_fragment; + dest_len = &s->s3->alert_fragment_len; + } +#ifndef OPENSSL_NO_HEARTBEATS + else if (rr->type == TLS1_RT_HEARTBEAT) { + tls1_process_heartbeat(s); + + /* Exit and notify application to read again */ + rr->length = 0; + s->rwstate = SSL_READING; + BIO_clear_retry_flags(SSL_get_rbio(s)); + BIO_set_retry_read(SSL_get_rbio(s)); + return (-1); + } +#endif + + if (dest_maxlen > 0) { + n = dest_maxlen - *dest_len; /* available space in 'dest' */ + if (rr->length < n) + n = rr->length; /* available bytes */ + + /* now move 'n' bytes: */ + while (n-- > 0) { + dest[(*dest_len)++] = rr->data[rr->off++]; + rr->length--; + } + + if (*dest_len < dest_maxlen) + goto start; /* fragment was too small */ + } + } + + /*- + * s->s3->handshake_fragment_len == 4 iff rr->type == SSL3_RT_HANDSHAKE; + * s->s3->alert_fragment_len == 2 iff rr->type == SSL3_RT_ALERT. + * (Possibly rr is 'empty' now, i.e. rr->length may be 0.) + */ + + /* If we are a client, check for an incoming 'Hello Request': */ + if ((!s->server) && + (s->s3->handshake_fragment_len >= 4) && + (s->s3->handshake_fragment[0] == SSL3_MT_HELLO_REQUEST) && + (s->session != NULL) && (s->session->cipher != NULL)) { + s->s3->handshake_fragment_len = 0; + + if ((s->s3->handshake_fragment[1] != 0) || + (s->s3->handshake_fragment[2] != 0) || + (s->s3->handshake_fragment[3] != 0)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_HELLO_REQUEST); + goto f_err; + } + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_HANDSHAKE, + s->s3->handshake_fragment, 4, s, + s->msg_callback_arg); + + if (SSL_is_init_finished(s) && + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS) && + !s->s3->renegotiate) { + ssl3_renegotiate(s); + if (ssl3_renegotiate_check(s)) { + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_SSL3_READ_BYTES, + SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { + if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ + BIO *bio; + /* + * In the case where we try to read application data, + * but we trigger an SSL handshake, we return -1 with + * the retry option set. Otherwise renegotiation may + * cause nasty problems in the blocking world + */ + s->rwstate = SSL_READING; + bio = SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + } + } + } + /* + * we either finished a handshake or ignored the request, now try + * again to obtain the (application) data we were asked for + */ + goto start; + } + /* + * If we are a server and get a client hello when renegotiation isn't + * allowed send back a no renegotiation alert and carry on. WARNING: + * experimental code, needs reviewing (steve) + */ + if (s->server && + SSL_is_init_finished(s) && + !s->s3->send_connection_binding && + (s->version > SSL3_VERSION) && + (s->s3->handshake_fragment_len >= 4) && + (s->s3->handshake_fragment[0] == SSL3_MT_CLIENT_HELLO) && + (s->session != NULL) && (s->session->cipher != NULL) && + !(s->ctx->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { + /* + * s->s3->handshake_fragment_len = 0; + */ + rr->length = 0; + ssl3_send_alert(s, SSL3_AL_WARNING, SSL_AD_NO_RENEGOTIATION); + goto start; + } + if (s->s3->alert_fragment_len >= 2) { + int alert_level = s->s3->alert_fragment[0]; + int alert_descr = s->s3->alert_fragment[1]; + + s->s3->alert_fragment_len = 0; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_ALERT, + s->s3->alert_fragment, 2, s, s->msg_callback_arg); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + if (cb != NULL) { + j = (alert_level << 8) | alert_descr; + cb(s, SSL_CB_READ_ALERT, j); + } + + if (alert_level == SSL3_AL_WARNING) { + s->s3->warn_alert = alert_descr; + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + return (0); + } + /* + * This is a warning but we receive it if we requested + * renegotiation and the peer denied it. Terminate with a fatal + * alert because if application tried to renegotiatie it + * presumably had a good reason and expects it to succeed. In + * future we might have a renegotiation where we don't care if + * the peer refused it where we carry on. + */ + else if (alert_descr == SSL_AD_NO_RENEGOTIATION) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_NO_RENEGOTIATION); + goto f_err; + } +#ifdef SSL_AD_MISSING_SRP_USERNAME + else if (alert_descr == SSL_AD_MISSING_SRP_USERNAME) + return (0); +#endif + } else if (alert_level == SSL3_AL_FATAL) { + char tmp[16]; + + s->rwstate = SSL_NOTHING; + s->s3->fatal_alert = alert_descr; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_AD_REASON_OFFSET + alert_descr); + BIO_snprintf(tmp, sizeof tmp, "%d", alert_descr); + ERR_add_error_data(2, "SSL alert number ", tmp); + s->shutdown |= SSL_RECEIVED_SHUTDOWN; + SSL_CTX_remove_session(s->ctx, s->session); + return (0); + } else { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNKNOWN_ALERT_TYPE); + goto f_err; + } + + goto start; + } + + if (s->shutdown & SSL_SENT_SHUTDOWN) { /* but we have not received a + * shutdown */ + s->rwstate = SSL_NOTHING; + rr->length = 0; + return (0); + } + + if (rr->type == SSL3_RT_CHANGE_CIPHER_SPEC) { + /* + * 'Change Cipher Spec' is just a single byte, so we know exactly + * what the record payload has to look like + */ + if ((rr->length != 1) || (rr->off != 0) || + (rr->data[0] != SSL3_MT_CCS)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_BAD_CHANGE_CIPHER_SPEC); + goto f_err; + } + + /* Check we have a cipher to change to */ + if (s->s3->tmp.new_cipher == NULL) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY); + goto f_err; + } + + if (!(s->s3->flags & SSL3_FLAGS_CCS_OK)) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_CCS_RECEIVED_EARLY); + goto f_err; + } + + s->s3->flags &= ~SSL3_FLAGS_CCS_OK; + + rr->length = 0; + + if (s->msg_callback) + s->msg_callback(0, s->version, SSL3_RT_CHANGE_CIPHER_SPEC, + rr->data, 1, s, s->msg_callback_arg); + + s->s3->change_cipher_spec = 1; + if (!ssl3_do_change_cipher_spec(s)) + goto err; + else + goto start; + } + + /* + * Unexpected handshake message (Client Hello, or protocol violation) + */ + if ((s->s3->handshake_fragment_len >= 4) && !s->in_handshake) { + if (((s->state & SSL_ST_MASK) == SSL_ST_OK) && + !(s->s3->flags & SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)) { +#if 0 /* worked only because C operator preferences + * are not as expected (and because this is + * not really needed for clients except for + * detecting protocol violations): */ + s->state = SSL_ST_BEFORE | (s->server) + ? SSL_ST_ACCEPT : SSL_ST_CONNECT; +#else + s->state = s->server ? SSL_ST_ACCEPT : SSL_ST_CONNECT; +#endif + s->renegotiate = 1; + s->new_session = 1; + } + i = s->handshake_func(s); + if (i < 0) + return (i); + if (i == 0) { + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_SSL_HANDSHAKE_FAILURE); + return (-1); + } + + if (!(s->mode & SSL_MODE_AUTO_RETRY)) { + if (s->s3->rbuf.left == 0) { /* no read-ahead left? */ + BIO *bio; + /* + * In the case where we try to read application data, but we + * trigger an SSL handshake, we return -1 with the retry + * option set. Otherwise renegotiation may cause nasty + * problems in the blocking world + */ + s->rwstate = SSL_READING; + bio = SSL_get_rbio(s); + BIO_clear_retry_flags(bio); + BIO_set_retry_read(bio); + return (-1); + } + } + goto start; + } + + switch (rr->type) { + default: +#ifndef OPENSSL_NO_TLS + /* + * TLS up to v1.1 just ignores unknown message types: TLS v1.2 give + * an unexpected message alert. + */ + if (s->version >= TLS1_VERSION && s->version <= TLS1_1_VERSION) { + rr->length = 0; + goto start; + } +#endif + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + case SSL3_RT_CHANGE_CIPHER_SPEC: + case SSL3_RT_ALERT: + case SSL3_RT_HANDSHAKE: + /* + * we already handled all of these, with the possible exception of + * SSL3_RT_HANDSHAKE when s->in_handshake is set, but that should not + * happen when type != rr->type + */ + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, ERR_R_INTERNAL_ERROR); + goto f_err; + case SSL3_RT_APPLICATION_DATA: + /* + * At this point, we were expecting handshake data, but have + * application data. If the library was running inside ssl3_read() + * (i.e. in_read_app_data is set) and it makes sense to read + * application data at this point (session renegotiation not yet + * started), we will indulge it. + */ + if (s->s3->in_read_app_data && + (s->s3->total_renegotiations != 0) && + (((s->state & SSL_ST_CONNECT) && + (s->state >= SSL3_ST_CW_CLNT_HELLO_A) && + (s->state <= SSL3_ST_CR_SRVR_HELLO_A) + ) || ((s->state & SSL_ST_ACCEPT) && + (s->state <= SSL3_ST_SW_HELLO_REQ_A) && + (s->state >= SSL3_ST_SR_CLNT_HELLO_A) + ) + )) { + s->s3->in_read_app_data = 2; + return (-1); + } else { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_READ_BYTES, SSL_R_UNEXPECTED_RECORD); + goto f_err; + } + } + /* not reached */ + + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + return (-1); +} + +int ssl3_do_change_cipher_spec(SSL *s) +{ + int i; + const char *sender; + int slen; + + if (s->state & SSL_ST_ACCEPT) + i = SSL3_CHANGE_CIPHER_SERVER_READ; + else + i = SSL3_CHANGE_CIPHER_CLIENT_READ; + + if (s->s3->tmp.key_block == NULL) { + if (s->session == NULL || s->session->master_key_length == 0) { + /* might happen if dtls1_read_bytes() calls this */ + SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, + SSL_R_CCS_RECEIVED_EARLY); + return (0); + } + + s->session->cipher = s->s3->tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) + return (0); + } + + if (!s->method->ssl3_enc->change_cipher_state(s, i)) + return (0); + + /* + * we have to record the message digest at this point so we can get it + * before we read the finished message + */ + if (s->state & SSL_ST_CONNECT) { + sender = s->method->ssl3_enc->server_finished_label; + slen = s->method->ssl3_enc->server_finished_label_len; + } else { + sender = s->method->ssl3_enc->client_finished_label; + slen = s->method->ssl3_enc->client_finished_label_len; + } + + i = s->method->ssl3_enc->final_finish_mac(s, + sender, slen, + s->s3->tmp.peer_finish_md); + if (i == 0) { + SSLerr(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC, ERR_R_INTERNAL_ERROR); + return 0; + } + s->s3->tmp.peer_finish_md_len = i; + + return (1); +} + +int ssl3_send_alert(SSL *s, int level, int desc) +{ + /* Map tls/ssl alert value to correct one */ + desc = s->method->ssl3_enc->alert_value(desc); + if (s->version == SSL3_VERSION && desc == SSL_AD_PROTOCOL_VERSION) + desc = SSL_AD_HANDSHAKE_FAILURE; /* SSL 3.0 does not have + * protocol_version alerts */ + if (desc < 0) + return -1; + /* If a fatal one, remove from cache */ + if ((level == 2) && (s->session != NULL)) + SSL_CTX_remove_session(s->ctx, s->session); + + s->s3->alert_dispatch = 1; + s->s3->send_alert[0] = level; + s->s3->send_alert[1] = desc; + if (s->s3->wbuf.left == 0) /* data still being written out? */ + return s->method->ssl_dispatch_alert(s); + /* + * else data is still being written out, we will get written some time in + * the future + */ + return -1; +} + +int ssl3_dispatch_alert(SSL *s) +{ + int i, j; + void (*cb) (const SSL *ssl, int type, int val) = NULL; + + s->s3->alert_dispatch = 0; + i = do_ssl3_write(s, SSL3_RT_ALERT, &s->s3->send_alert[0], 2, 0); + if (i <= 0) { + s->s3->alert_dispatch = 1; + } else { + /* + * Alert sent to BIO. If it is important, flush it now. If the + * message does not get sent due to non-blocking IO, we will not + * worry too much. + */ + if (s->s3->send_alert[0] == SSL3_AL_FATAL) + (void)BIO_flush(s->wbio); + + if (s->msg_callback) + s->msg_callback(1, s->version, SSL3_RT_ALERT, s->s3->send_alert, + 2, s, s->msg_callback_arg); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + if (cb != NULL) { + j = (s->s3->send_alert[0] << 8) | s->s3->send_alert[1]; + cb(s, SSL_CB_WRITE_ALERT, j); + } + } + return (i); +} diff --git a/libs/openssl/ssl/s3_srvr.c b/libs/openssl/ssl/s3_srvr.c new file mode 100644 index 00000000..04cf93a0 --- /dev/null +++ b/libs/openssl/ssl/s3_srvr.c @@ -0,0 +1,3649 @@ +/* ssl/s3_srvr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * + * Portions of the attached software ("Contribution") are developed by + * SUN MICROSYSTEMS, INC., and are contributed to the OpenSSL project. + * + * The Contribution is licensed pursuant to the OpenSSL open source + * license provided above. + * + * ECC cipher suite support in OpenSSL originally written by + * Vipul Gupta and Sumit Gupta of Sun Microsystems Laboratories. + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#define REUSE_CIPHER_BUG +#define NETSCAPE_HANG_BUG + +#include +#include "ssl_locl.h" +#include "kssl_lcl.h" +#include "../crypto/constant_time_locl.h" +#include +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_DH +# include +#endif +#include +#ifndef OPENSSL_NO_KRB5 +# include +#endif +#include + +#ifndef OPENSSL_NO_SSL3_METHOD +static const SSL_METHOD *ssl3_get_server_method(int ver); + +static const SSL_METHOD *ssl3_get_server_method(int ver) +{ + if (ver == SSL3_VERSION) + return (SSLv3_server_method()); + else + return (NULL); +} + +IMPLEMENT_ssl3_meth_func(SSLv3_server_method, + ssl3_accept, + ssl_undefined_function, ssl3_get_server_method) +#endif +#ifndef OPENSSL_NO_SRP +static int ssl_check_srp_ext_ClientHello(SSL *s, int *al) +{ + int ret = SSL_ERROR_NONE; + + *al = SSL_AD_UNRECOGNIZED_NAME; + + if ((s->s3->tmp.new_cipher->algorithm_mkey & SSL_kSRP) && + (s->srp_ctx.TLS_ext_srp_username_callback != NULL)) { + if (s->srp_ctx.login == NULL) { + /* + * RFC 5054 says SHOULD reject, we do so if There is no srp + * login name + */ + ret = SSL3_AL_FATAL; + *al = SSL_AD_UNKNOWN_PSK_IDENTITY; + } else { + ret = SSL_srp_server_param_with_username(s, al); + } + } + return ret; +} +#endif + +int ssl3_accept(SSL *s) +{ + BUF_MEM *buf; + unsigned long alg_k, Time = (unsigned long)time(NULL); + void (*cb) (const SSL *ssl, int type, int val) = NULL; + int ret = -1; + int new_state, state, skip = 0; + + RAND_add(&Time, sizeof(Time), 0); + ERR_clear_error(); + clear_sys_error(); + + if (s->info_callback != NULL) + cb = s->info_callback; + else if (s->ctx->info_callback != NULL) + cb = s->ctx->info_callback; + + /* init things to blank */ + s->in_handshake++; + if (!SSL_in_init(s) || SSL_in_before(s)) + SSL_clear(s); + + if (s->cert == NULL) { + SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_NO_CERTIFICATE_SET); + return (-1); + } +#ifndef OPENSSL_NO_HEARTBEATS + /* + * If we're awaiting a HeartbeatResponse, pretend we already got and + * don't await it anymore, because Heartbeats don't make sense during + * handshakes anyway. + */ + if (s->tlsext_hb_pending) { + s->tlsext_hb_pending = 0; + s->tlsext_hb_seq++; + } +#endif + + for (;;) { + state = s->state; + + switch (s->state) { + case SSL_ST_RENEGOTIATE: + s->renegotiate = 1; + /* s->state=SSL_ST_ACCEPT; */ + + case SSL_ST_BEFORE: + case SSL_ST_ACCEPT: + case SSL_ST_BEFORE | SSL_ST_ACCEPT: + case SSL_ST_OK | SSL_ST_ACCEPT: + + s->server = 1; + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_START, 1); + + if ((s->version >> 8) != 3) { + SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return -1; + } + s->type = SSL_ST_ACCEPT; + + if (s->init_buf == NULL) { + if ((buf = BUF_MEM_new()) == NULL) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + if (!BUF_MEM_grow(buf, SSL3_RT_MAX_PLAIN_LENGTH)) { + BUF_MEM_free(buf); + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + s->init_buf = buf; + } + + if (!ssl3_setup_buffers(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + s->init_num = 0; + s->s3->flags &= ~SSL3_FLAGS_SGC_RESTART_DONE; + s->s3->flags &= ~SSL3_FLAGS_CCS_OK; + /* + * Should have been reset by ssl3_get_finished, too. + */ + s->s3->change_cipher_spec = 0; + + if (s->state != SSL_ST_RENEGOTIATE) { + /* + * Ok, we now need to push on a buffering BIO so that the + * output is sent in a way that TCP likes :-) + */ + if (!ssl_init_wbio_buffer(s, 1)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + ssl3_init_finished_mac(s); + s->state = SSL3_ST_SR_CLNT_HELLO_A; + s->ctx->stats.sess_accept++; + } else if (!s->s3->send_connection_binding && + !(s->options & + SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { + /* + * Server attempting to renegotiate with client that doesn't + * support secure renegotiation. + */ + SSLerr(SSL_F_SSL3_ACCEPT, + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } else { + /* + * s->state == SSL_ST_RENEGOTIATE, we will just send a + * HelloRequest + */ + s->ctx->stats.sess_accept_renegotiate++; + s->state = SSL3_ST_SW_HELLO_REQ_A; + } + break; + + case SSL3_ST_SW_HELLO_REQ_A: + case SSL3_ST_SW_HELLO_REQ_B: + + s->shutdown = 0; + ret = ssl3_send_hello_request(s); + if (ret <= 0) + goto end; + s->s3->tmp.next_state = SSL3_ST_SW_HELLO_REQ_C; + s->state = SSL3_ST_SW_FLUSH; + s->init_num = 0; + + ssl3_init_finished_mac(s); + break; + + case SSL3_ST_SW_HELLO_REQ_C: + s->state = SSL_ST_OK; + break; + + case SSL3_ST_SR_CLNT_HELLO_A: + case SSL3_ST_SR_CLNT_HELLO_B: + case SSL3_ST_SR_CLNT_HELLO_C: + + s->shutdown = 0; + if (s->rwstate != SSL_X509_LOOKUP) { + ret = ssl3_get_client_hello(s); + if (ret <= 0) + goto end; + } +#ifndef OPENSSL_NO_SRP + { + int al; + if ((ret = ssl_check_srp_ext_ClientHello(s, &al)) < 0) { + /* + * callback indicates firther work to be done + */ + s->rwstate = SSL_X509_LOOKUP; + goto end; + } + if (ret != SSL_ERROR_NONE) { + ssl3_send_alert(s, SSL3_AL_FATAL, al); + /* + * This is not really an error but the only means to for + * a client to detect whether srp is supported. + */ + if (al != TLS1_AD_UNKNOWN_PSK_IDENTITY) + SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_CLIENTHELLO_TLSEXT); + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + } +#endif + + s->renegotiate = 2; + s->state = SSL3_ST_SW_SRVR_HELLO_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_SRVR_HELLO_A: + case SSL3_ST_SW_SRVR_HELLO_B: + ret = ssl3_send_server_hello(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_TLSEXT + if (s->hit) { + if (s->tlsext_ticket_expected) + s->state = SSL3_ST_SW_SESSION_TICKET_A; + else + s->state = SSL3_ST_SW_CHANGE_A; + } +#else + if (s->hit) + s->state = SSL3_ST_SW_CHANGE_A; +#endif + else + s->state = SSL3_ST_SW_CERT_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_A: + case SSL3_ST_SW_CERT_B: + /* Check if it is anon DH or anon ECDH, */ + /* normal PSK or KRB5 or SRP */ + if (! + (s->s3->tmp. + new_cipher->algorithm_auth & (SSL_aNULL | SSL_aKRB5 | + SSL_aSRP)) +&& !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + ret = ssl3_send_server_certificate(s); + if (ret <= 0) + goto end; +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_status_expected) + s->state = SSL3_ST_SW_CERT_STATUS_A; + else + s->state = SSL3_ST_SW_KEY_EXCH_A; + } else { + skip = 1; + s->state = SSL3_ST_SW_KEY_EXCH_A; + } +#else + } else + skip = 1; + + s->state = SSL3_ST_SW_KEY_EXCH_A; +#endif + s->init_num = 0; + break; + + case SSL3_ST_SW_KEY_EXCH_A: + case SSL3_ST_SW_KEY_EXCH_B: + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + + /* + * clear this, it may get reset by + * send_server_key_exchange + */ + s->s3->tmp.use_rsa_tmp = 0; + + /* + * only send if a DH key exchange, fortezza or RSA but we have a + * sign only certificate PSK: may send PSK identity hints For + * ECC ciphersuites, we send a serverKeyExchange message only if + * the cipher suite is either ECDH-anon or ECDHE. In other cases, + * the server certificate contains the server's public key for + * key exchange. + */ + if (0 + /* + * PSK: send ServerKeyExchange if PSK identity hint if + * provided + */ +#ifndef OPENSSL_NO_PSK + || ((alg_k & SSL_kPSK) && s->ctx->psk_identity_hint) +#endif +#ifndef OPENSSL_NO_SRP + /* SRP: send ServerKeyExchange */ + || (alg_k & SSL_kSRP) +#endif + || (alg_k & (SSL_kDHr | SSL_kDHd | SSL_kEDH)) + || (alg_k & SSL_kEECDH) + || ((alg_k & SSL_kRSA) + && (s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey == NULL + || (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) + && EVP_PKEY_size(s->cert->pkeys + [SSL_PKEY_RSA_ENC].privatekey) * + 8 > SSL_C_EXPORT_PKEYLENGTH(s->s3->tmp.new_cipher) + ) + ) + ) + ) { + ret = ssl3_send_server_key_exchange(s); + if (ret <= 0) + goto end; + } else + skip = 1; + + s->state = SSL3_ST_SW_CERT_REQ_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_REQ_A: + case SSL3_ST_SW_CERT_REQ_B: + if ( /* don't request cert unless asked for it: */ + !(s->verify_mode & SSL_VERIFY_PEER) || + /* + * if SSL_VERIFY_CLIENT_ONCE is set, don't request cert + * during re-negotiation: + */ + ((s->session->peer != NULL) && + (s->verify_mode & SSL_VERIFY_CLIENT_ONCE)) || + /* + * never request cert in anonymous ciphersuites (see + * section "Certificate request" in SSL 3 drafts and in + * RFC 2246): + */ + ((s->s3->tmp.new_cipher->algorithm_auth & SSL_aNULL) && + /* + * ... except when the application insists on + * verification (against the specs, but s3_clnt.c accepts + * this for SSL 3) + */ + !(s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) || + /* + * never request cert in Kerberos ciphersuites + */ + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aKRB5) || + /* don't request certificate for SRP auth */ + (s->s3->tmp.new_cipher->algorithm_auth & SSL_aSRP) + /* + * With normal PSK Certificates and Certificate Requests + * are omitted + */ + || (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + /* no cert request */ + skip = 1; + s->s3->tmp.cert_request = 0; + s->state = SSL3_ST_SW_SRVR_DONE_A; + if (s->s3->handshake_buffer) { + if (!ssl3_digest_cached_records(s)) { + s->state = SSL_ST_ERR; + return -1; + } + } + } else { + s->s3->tmp.cert_request = 1; + ret = ssl3_send_certificate_request(s); + if (ret <= 0) + goto end; +#ifndef NETSCAPE_HANG_BUG + s->state = SSL3_ST_SW_SRVR_DONE_A; +#else + s->state = SSL3_ST_SW_FLUSH; + s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; +#endif + s->init_num = 0; + } + break; + + case SSL3_ST_SW_SRVR_DONE_A: + case SSL3_ST_SW_SRVR_DONE_B: + ret = ssl3_send_server_done(s); + if (ret <= 0) + goto end; + s->s3->tmp.next_state = SSL3_ST_SR_CERT_A; + s->state = SSL3_ST_SW_FLUSH; + s->init_num = 0; + break; + + case SSL3_ST_SW_FLUSH: + + /* + * This code originally checked to see if any data was pending + * using BIO_CTRL_INFO and then flushed. This caused problems as + * documented in PR#1939. The proposed fix doesn't completely + * resolve this issue as buggy implementations of + * BIO_CTRL_PENDING still exist. So instead we just flush + * unconditionally. + */ + + s->rwstate = SSL_WRITING; + if (BIO_flush(s->wbio) <= 0) { + ret = -1; + goto end; + } + s->rwstate = SSL_NOTHING; + + s->state = s->s3->tmp.next_state; + break; + + case SSL3_ST_SR_CERT_A: + case SSL3_ST_SR_CERT_B: + /* Check for second client hello (MS SGC) */ + ret = ssl3_check_client_hello(s); + if (ret <= 0) + goto end; + if (ret == 2) + s->state = SSL3_ST_SR_CLNT_HELLO_C; + else { + if (s->s3->tmp.cert_request) { + ret = ssl3_get_client_certificate(s); + if (ret <= 0) + goto end; + } + s->init_num = 0; + s->state = SSL3_ST_SR_KEY_EXCH_A; + } + break; + + case SSL3_ST_SR_KEY_EXCH_A: + case SSL3_ST_SR_KEY_EXCH_B: + ret = ssl3_get_client_key_exchange(s); + if (ret <= 0) + goto end; + if (ret == 2) { + /* + * For the ECDH ciphersuites when the client sends its ECDH + * pub key in a certificate, the CertificateVerify message is + * not sent. Also for GOST ciphersuites when the client uses + * its key from the certificate for key exchange. + */ +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) + s->state = SSL3_ST_SR_FINISHED_A; +#else + if (s->s3->next_proto_neg_seen) + s->state = SSL3_ST_SR_NEXT_PROTO_A; + else + s->state = SSL3_ST_SR_FINISHED_A; +#endif + s->init_num = 0; + } else if (TLS1_get_version(s) >= TLS1_2_VERSION) { + s->state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + if (!s->session->peer) + break; + /* + * For TLS v1.2 freeze the handshake buffer at this point and + * digest cached records. + */ + if (!s->s3->handshake_buffer) { + SSLerr(SSL_F_SSL3_ACCEPT, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return -1; + } + s->s3->flags |= TLS1_FLAGS_KEEP_HANDSHAKE; + if (!ssl3_digest_cached_records(s)) { + s->state = SSL_ST_ERR; + return -1; + } + } else { + int offset = 0; + int dgst_num; + + s->state = SSL3_ST_SR_CERT_VRFY_A; + s->init_num = 0; + + /* + * We need to get hashes here so if there is a client cert, + * it can be verified FIXME - digest processing for + * CertificateVerify should be generalized. But it is next + * step + */ + if (s->s3->handshake_buffer) { + if (!ssl3_digest_cached_records(s)) { + s->state = SSL_ST_ERR; + return -1; + } + } + for (dgst_num = 0; dgst_num < SSL_MAX_DIGEST; dgst_num++) + if (s->s3->handshake_dgst[dgst_num]) { + int dgst_size; + + s->method->ssl3_enc->cert_verify_mac(s, + EVP_MD_CTX_type + (s-> + s3->handshake_dgst + [dgst_num]), + &(s->s3-> + tmp.cert_verify_md + [offset])); + dgst_size = + EVP_MD_CTX_size(s->s3->handshake_dgst[dgst_num]); + if (dgst_size < 0) { + s->state = SSL_ST_ERR; + ret = -1; + goto end; + } + offset += dgst_size; + } + } + break; + + case SSL3_ST_SR_CERT_VRFY_A: + case SSL3_ST_SR_CERT_VRFY_B: + ret = ssl3_get_cert_verify(s); + if (ret <= 0) + goto end; + +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) + s->state = SSL3_ST_SR_FINISHED_A; +#else + if (s->s3->next_proto_neg_seen) + s->state = SSL3_ST_SR_NEXT_PROTO_A; + else + s->state = SSL3_ST_SR_FINISHED_A; +#endif + s->init_num = 0; + break; + +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) + case SSL3_ST_SR_NEXT_PROTO_A: + case SSL3_ST_SR_NEXT_PROTO_B: + /* + * Enable CCS for NPN. Receiving a CCS clears the flag, so make + * sure not to re-enable it to ban duplicates. This *should* be the + * first time we have received one - but we check anyway to be + * cautious. + * s->s3->change_cipher_spec is set when a CCS is + * processed in s3_pkt.c, and remains set until + * the client's Finished message is read. + */ + if (!s->s3->change_cipher_spec) + s->s3->flags |= SSL3_FLAGS_CCS_OK; + + ret = ssl3_get_next_proto(s); + if (ret <= 0) + goto end; + s->init_num = 0; + s->state = SSL3_ST_SR_FINISHED_A; + break; +#endif + + case SSL3_ST_SR_FINISHED_A: + case SSL3_ST_SR_FINISHED_B: + /* + * Enable CCS for handshakes without NPN. In NPN the CCS flag has + * already been set. Receiving a CCS clears the flag, so make + * sure not to re-enable it to ban duplicates. + * s->s3->change_cipher_spec is set when a CCS is + * processed in s3_pkt.c, and remains set until + * the client's Finished message is read. + */ + if (!s->s3->change_cipher_spec) + s->s3->flags |= SSL3_FLAGS_CCS_OK; + ret = ssl3_get_finished(s, SSL3_ST_SR_FINISHED_A, + SSL3_ST_SR_FINISHED_B); + if (ret <= 0) + goto end; + if (s->hit) + s->state = SSL_ST_OK; +#ifndef OPENSSL_NO_TLSEXT + else if (s->tlsext_ticket_expected) + s->state = SSL3_ST_SW_SESSION_TICKET_A; +#endif + else + s->state = SSL3_ST_SW_CHANGE_A; + s->init_num = 0; + break; + +#ifndef OPENSSL_NO_TLSEXT + case SSL3_ST_SW_SESSION_TICKET_A: + case SSL3_ST_SW_SESSION_TICKET_B: + ret = ssl3_send_newsession_ticket(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_CHANGE_A; + s->init_num = 0; + break; + + case SSL3_ST_SW_CERT_STATUS_A: + case SSL3_ST_SW_CERT_STATUS_B: + ret = ssl3_send_cert_status(s); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_KEY_EXCH_A; + s->init_num = 0; + break; + +#endif + + case SSL3_ST_SW_CHANGE_A: + case SSL3_ST_SW_CHANGE_B: + + s->session->cipher = s->s3->tmp.new_cipher; + if (!s->method->ssl3_enc->setup_key_block(s)) { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + ret = ssl3_send_change_cipher_spec(s, + SSL3_ST_SW_CHANGE_A, + SSL3_ST_SW_CHANGE_B); + + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_FINISHED_A; + s->init_num = 0; + + if (!s->method->ssl3_enc->change_cipher_state(s, + SSL3_CHANGE_CIPHER_SERVER_WRITE)) + { + ret = -1; + s->state = SSL_ST_ERR; + goto end; + } + + break; + + case SSL3_ST_SW_FINISHED_A: + case SSL3_ST_SW_FINISHED_B: + ret = ssl3_send_finished(s, + SSL3_ST_SW_FINISHED_A, + SSL3_ST_SW_FINISHED_B, + s->method-> + ssl3_enc->server_finished_label, + s->method-> + ssl3_enc->server_finished_label_len); + if (ret <= 0) + goto end; + s->state = SSL3_ST_SW_FLUSH; + if (s->hit) { +#if defined(OPENSSL_NO_TLSEXT) || defined(OPENSSL_NO_NEXTPROTONEG) + s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; +#else + if (s->s3->next_proto_neg_seen) { + s->s3->tmp.next_state = SSL3_ST_SR_NEXT_PROTO_A; + } else + s->s3->tmp.next_state = SSL3_ST_SR_FINISHED_A; +#endif + } else + s->s3->tmp.next_state = SSL_ST_OK; + s->init_num = 0; + break; + + case SSL_ST_OK: + /* clean a few things up */ + ssl3_cleanup_key_block(s); + + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + + /* remove buffering on output */ + ssl_free_wbio_buffer(s); + + s->init_num = 0; + + if (s->renegotiate == 2) { /* skipped if we just sent a + * HelloRequest */ + s->renegotiate = 0; + s->new_session = 0; + + ssl_update_cache(s, SSL_SESS_CACHE_SERVER); + + s->ctx->stats.sess_accept_good++; + /* s->server=1; */ + s->handshake_func = ssl3_accept; + + if (cb != NULL) + cb(s, SSL_CB_HANDSHAKE_DONE, 1); + } + + ret = 1; + goto end; + /* break; */ + + case SSL_ST_ERR: + default: + SSLerr(SSL_F_SSL3_ACCEPT, SSL_R_UNKNOWN_STATE); + ret = -1; + goto end; + /* break; */ + } + + if (!s->s3->tmp.reuse_message && !skip) { + if (s->debug) { + if ((ret = BIO_flush(s->wbio)) <= 0) + goto end; + } + + if ((cb != NULL) && (s->state != state)) { + new_state = s->state; + s->state = state; + cb(s, SSL_CB_ACCEPT_LOOP, 1); + s->state = new_state; + } + } + skip = 0; + } + end: + /* BIO_flush(s->wbio); */ + + s->in_handshake--; + if (cb != NULL) + cb(s, SSL_CB_ACCEPT_EXIT, ret); + return (ret); +} + +int ssl3_send_hello_request(SSL *s) +{ + unsigned char *p; + + if (s->state == SSL3_ST_SW_HELLO_REQ_A) { + p = (unsigned char *)s->init_buf->data; + *(p++) = SSL3_MT_HELLO_REQUEST; + *(p++) = 0; + *(p++) = 0; + *(p++) = 0; + + s->state = SSL3_ST_SW_HELLO_REQ_B; + /* number of bytes to write */ + s->init_num = 4; + s->init_off = 0; + } + + /* SSL3_ST_SW_HELLO_REQ_B */ + return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); +} + +int ssl3_check_client_hello(SSL *s) +{ + int ok; + long n; + + /* + * this function is called when we really expect a Certificate message, + * so permit appropriate message length + */ + n = s->method->ssl_get_message(s, + SSL3_ST_SR_CERT_A, + SSL3_ST_SR_CERT_B, + -1, s->max_cert_list, &ok); + if (!ok) + return ((int)n); + s->s3->tmp.reuse_message = 1; + if (s->s3->tmp.message_type == SSL3_MT_CLIENT_HELLO) { + /* + * We only allow the client to restart the handshake once per + * negotiation. + */ + if (s->s3->flags & SSL3_FLAGS_SGC_RESTART_DONE) { + SSLerr(SSL_F_SSL3_CHECK_CLIENT_HELLO, + SSL_R_MULTIPLE_SGC_RESTARTS); + return -1; + } + /* + * Throw away what we have done so far in the current handshake, + * which will now be aborted. (A full SSL_clear would be too much.) + */ +#ifndef OPENSSL_NO_DH + if (s->s3->tmp.dh != NULL) { + DH_free(s->s3->tmp.dh); + s->s3->tmp.dh = NULL; + } +#endif +#ifndef OPENSSL_NO_ECDH + if (s->s3->tmp.ecdh != NULL) { + EC_KEY_free(s->s3->tmp.ecdh); + s->s3->tmp.ecdh = NULL; + } +#endif + s->s3->flags |= SSL3_FLAGS_SGC_RESTART_DONE; + return 2; + } + return 1; +} + +int ssl3_get_client_hello(SSL *s) +{ + int i, j, ok, al, ret = -1, cookie_valid = 0; + unsigned int cookie_len; + long n; + unsigned long id; + unsigned char *p, *d, *q; + SSL_CIPHER *c; +#ifndef OPENSSL_NO_COMP + SSL_COMP *comp = NULL; +#endif + STACK_OF(SSL_CIPHER) *ciphers = NULL; + + /* + * We do this so that we will respond with our native type. If we are + * TLSv1 and we get SSLv3, we will respond with TLSv1, This down + * switching should be handled by a different method. If we are SSLv3, we + * will respond with SSLv3, even if prompted with TLSv1. + */ + if (s->state == SSL3_ST_SR_CLNT_HELLO_A) { + s->state = SSL3_ST_SR_CLNT_HELLO_B; + } + s->first_packet = 1; + n = s->method->ssl_get_message(s, + SSL3_ST_SR_CLNT_HELLO_B, + SSL3_ST_SR_CLNT_HELLO_C, + SSL3_MT_CLIENT_HELLO, + SSL3_RT_MAX_PLAIN_LENGTH, &ok); + + if (!ok) + return ((int)n); + s->first_packet = 0; + d = p = (unsigned char *)s->init_msg; + + /* + * 2 bytes for client version, SSL3_RANDOM_SIZE bytes for random, 1 byte + * for session id length + */ + if (n < 2 + SSL3_RANDOM_SIZE + 1) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + /* + * use version from inside client hello, not from record header (may + * differ: see RFC 2246, Appendix E, second paragraph) + */ + s->client_version = (((int)p[0]) << 8) | (int)p[1]; + p += 2; + + if ((s->version == DTLS1_VERSION && s->client_version > s->version) || + (s->version != DTLS1_VERSION && s->client_version < s->version)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_WRONG_VERSION_NUMBER); + if ((s->client_version >> 8) == SSL3_VERSION_MAJOR && + !s->enc_write_ctx && !s->write_hash) { + /* + * similar to ssl3_get_record, send alert using remote version + * number + */ + s->version = s->client_version; + } + al = SSL_AD_PROTOCOL_VERSION; + goto f_err; + } + + /* + * If we require cookies and this ClientHello doesn't contain one, just + * return since we do not want to allocate any memory yet. So check + * cookie length... + */ + if (SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) { + unsigned int session_length, cookie_length; + + session_length = *(p + SSL3_RANDOM_SIZE); + + if (p + SSL3_RANDOM_SIZE + session_length + 1 >= d + n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + cookie_length = *(p + SSL3_RANDOM_SIZE + session_length + 1); + + if (cookie_length == 0) + return 1; + } + + /* load the client random */ + memcpy(s->s3->client_random, p, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /* get the session-id */ + j = *(p++); + + if (p + j > d + n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + if ((j < 0) || (j > SSL_MAX_SSL_SESSION_ID_LENGTH)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + + s->hit = 0; + /* + * Versions before 0.9.7 always allow clients to resume sessions in + * renegotiation. 0.9.7 and later allow this by default, but optionally + * ignore resumption requests with flag + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION (it's a new flag rather + * than a change to default behavior so that applications relying on this + * for security won't even compile against older library versions). + * 1.0.1 and later also have a function SSL_renegotiate_abbreviated() to + * request renegotiation but not a new session (s->new_session remains + * unset): for servers, this essentially just means that the + * SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION setting will be ignored. + */ + if ((s->new_session + && (s->options & SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION))) { + if (!ssl_get_new_session(s, 1)) + goto err; + } else { + i = ssl_get_prev_session(s, p, j, d + n); + /* + * Only resume if the session's version matches the negotiated + * version. + * RFC 5246 does not provide much useful advice on resumption + * with a different protocol version. It doesn't forbid it but + * the sanity of such behaviour would be questionable. + * In practice, clients do not accept a version mismatch and + * will abort the handshake with an error. + */ + if (i == 1 && s->version == s->session->ssl_version) { /* previous + * session */ + s->hit = 1; + } else if (i == -1) + goto err; + else { /* i == 0 */ + + if (!ssl_get_new_session(s, 1)) + goto err; + } + } + + p += j; + + if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { + /* cookie stuff */ + if (p + 1 > d + n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + cookie_len = *(p++); + + if (p + cookie_len > d + n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + + /* + * The ClientHello may contain a cookie even if the + * HelloVerify message has not been sent--make sure that it + * does not cause an overflow. + */ + if (cookie_len > sizeof(s->d1->rcvd_cookie)) { + /* too much data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); + goto f_err; + } + + /* verify the cookie if appropriate option is set. */ + if ((SSL_get_options(s) & SSL_OP_COOKIE_EXCHANGE) && cookie_len > 0) { + memcpy(s->d1->rcvd_cookie, p, cookie_len); + + if (s->ctx->app_verify_cookie_cb != NULL) { + if (s->ctx->app_verify_cookie_cb(s, s->d1->rcvd_cookie, + cookie_len) == 0) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_COOKIE_MISMATCH); + goto f_err; + } + /* else cookie verification succeeded */ + } + /* default verification */ + else if (memcmp(s->d1->rcvd_cookie, s->d1->cookie, + s->d1->cookie_len) != 0) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_COOKIE_MISMATCH); + goto f_err; + } + cookie_valid = 1; + } + + p += cookie_len; + } + + if (p + 2 > d + n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_TOO_SHORT); + goto f_err; + } + n2s(p, i); + + if (i == 0) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_CIPHERS_SPECIFIED); + goto f_err; + } + + /* i bytes of cipher data + 1 byte for compression length later */ + if ((p + i + 1) > (d + n)) { + /* not enough data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + if (ssl_bytes_to_cipher_list(s, p, i, &(ciphers)) == NULL) { + goto err; + } + p += i; + + /* If it is a hit, check that the cipher is in the list */ + if (s->hit) { + j = 0; + id = s->session->cipher->id; + +#ifdef CIPHER_DEBUG + fprintf(stderr, "client sent %d ciphers\n", + sk_SSL_CIPHER_num(ciphers)); +#endif + for (i = 0; i < sk_SSL_CIPHER_num(ciphers); i++) { + c = sk_SSL_CIPHER_value(ciphers, i); +#ifdef CIPHER_DEBUG + fprintf(stderr, "client [%2d of %2d]:%s\n", + i, sk_SSL_CIPHER_num(ciphers), SSL_CIPHER_get_name(c)); +#endif + if (c->id == id) { + j = 1; + break; + } + } + /* + * Disabled because it can be used in a ciphersuite downgrade attack: + * CVE-2010-4180. + */ +#if 0 + if (j == 0 && (s->options & SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG) + && (sk_SSL_CIPHER_num(ciphers) == 1)) { + /* + * Special case as client bug workaround: the previously used + * cipher may not be in the current list, the client instead + * might be trying to continue using a cipher that before wasn't + * chosen due to server preferences. We'll have to reject the + * connection if the cipher is not enabled, though. + */ + c = sk_SSL_CIPHER_value(ciphers, 0); + if (sk_SSL_CIPHER_find(SSL_get_ciphers(s), c) >= 0) { + s->session->cipher = c; + j = 1; + } + } +#endif + if (j == 0) { + /* + * we need to have the cipher in the cipher list if we are asked + * to reuse it + */ + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_REQUIRED_CIPHER_MISSING); + goto f_err; + } + } + + /* compression */ + i = *(p++); + if ((p + i) > (d + n)) { + /* not enough data */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + q = p; + for (j = 0; j < i; j++) { + if (p[j] == 0) + break; + } + + p += i; + if (j >= i) { + /* no compress */ + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_COMPRESSION_SPECIFIED); + goto f_err; + } +#ifndef OPENSSL_NO_TLSEXT + /* TLS extensions */ + if (s->version >= SSL3_VERSION) { + if (!ssl_parse_clienthello_tlsext(s, &p, d + n, &al)) { + /* 'al' set by ssl_parse_clienthello_tlsext */ + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_PARSE_TLSEXT); + goto f_err; + } + } + if (ssl_check_clienthello_tlsext_early(s) <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } + + /* + * Check if we want to use external pre-shared secret for this handshake + * for not reused session only. We need to generate server_random before + * calling tls_session_secret_cb in order to allow SessionTicket + * processing to use it in key derivation. + */ + { + unsigned char *pos; + pos = s->s3->server_random; + if (ssl_fill_hello_random(s, 1, pos, SSL3_RANDOM_SIZE) <= 0) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + } + + if (!s->hit && s->version >= TLS1_VERSION && s->tls_session_secret_cb) { + SSL_CIPHER *pref_cipher = NULL; + + s->session->master_key_length = sizeof(s->session->master_key); + if (s->tls_session_secret_cb(s, s->session->master_key, + &s->session->master_key_length, ciphers, + &pref_cipher, + s->tls_session_secret_cb_arg)) { + s->hit = 1; + s->session->ciphers = ciphers; + s->session->verify_result = X509_V_OK; + + ciphers = NULL; + + /* check if some cipher was preferred by call back */ + pref_cipher = + pref_cipher ? pref_cipher : ssl3_choose_cipher(s, + s-> + session->ciphers, + SSL_get_ciphers + (s)); + if (pref_cipher == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER); + goto f_err; + } + + s->session->cipher = pref_cipher; + + if (s->cipher_list) + sk_SSL_CIPHER_free(s->cipher_list); + + if (s->cipher_list_by_id) + sk_SSL_CIPHER_free(s->cipher_list_by_id); + + s->cipher_list = sk_SSL_CIPHER_dup(s->session->ciphers); + s->cipher_list_by_id = sk_SSL_CIPHER_dup(s->session->ciphers); + } + } +#endif + + /* + * Worst case, we will use the NULL compression, but if we have other + * options, we will now look for them. We have i-1 compression + * algorithms from the client, starting at q. + */ + s->s3->tmp.new_compression = NULL; +#ifndef OPENSSL_NO_COMP + /* This only happens if we have a cache hit */ + if (s->session->compress_meth != 0) { + int m, comp_id = s->session->compress_meth; + /* Perform sanity checks on resumed compression algorithm */ + /* Can't disable compression */ + if (s->options & SSL_OP_NO_COMPRESSION) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_INCONSISTENT_COMPRESSION); + goto f_err; + } + /* Look for resumed compression method */ + for (m = 0; m < sk_SSL_COMP_num(s->ctx->comp_methods); m++) { + comp = sk_SSL_COMP_value(s->ctx->comp_methods, m); + if (comp_id == comp->id) { + s->s3->tmp.new_compression = comp; + break; + } + } + if (s->s3->tmp.new_compression == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_INVALID_COMPRESSION_ALGORITHM); + goto f_err; + } + /* Look for resumed method in compression list */ + for (m = 0; m < i; m++) { + if (q[m] == comp_id) + break; + } + if (m >= i) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, + SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING); + goto f_err; + } + } else if (s->hit) + comp = NULL; + else if (!(s->options & SSL_OP_NO_COMPRESSION) && s->ctx->comp_methods) { + /* See if we have a match */ + int m, nn, o, v, done = 0; + + nn = sk_SSL_COMP_num(s->ctx->comp_methods); + for (m = 0; m < nn; m++) { + comp = sk_SSL_COMP_value(s->ctx->comp_methods, m); + v = comp->id; + for (o = 0; o < i; o++) { + if (v == q[o]) { + done = 1; + break; + } + } + if (done) + break; + } + if (done) + s->s3->tmp.new_compression = comp; + else + comp = NULL; + } +#else + /* + * If compression is disabled we'd better not try to resume a session + * using compression. + */ + if (s->session->compress_meth != 0) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_INCONSISTENT_COMPRESSION); + goto f_err; + } +#endif + + /* + * Given s->session->ciphers and SSL_get_ciphers, we must pick a cipher + */ + + if (!s->hit) { +#ifdef OPENSSL_NO_COMP + s->session->compress_meth = 0; +#else + s->session->compress_meth = (comp == NULL) ? 0 : comp->id; +#endif + if (s->session->ciphers != NULL) + sk_SSL_CIPHER_free(s->session->ciphers); + s->session->ciphers = ciphers; + if (ciphers == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, ERR_R_INTERNAL_ERROR); + goto f_err; + } + ciphers = NULL; + c = ssl3_choose_cipher(s, s->session->ciphers, SSL_get_ciphers(s)); + + if (c == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_NO_SHARED_CIPHER); + goto f_err; + } + s->s3->tmp.new_cipher = c; + } else { + /* Session-id reuse */ +#ifdef REUSE_CIPHER_BUG + STACK_OF(SSL_CIPHER) *sk; + SSL_CIPHER *nc = NULL; + SSL_CIPHER *ec = NULL; + + if (s->options & SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG) { + sk = s->session->ciphers; + for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + c = sk_SSL_CIPHER_value(sk, i); + if (c->algorithm_enc & SSL_eNULL) + nc = c; + if (SSL_C_IS_EXPORT(c)) + ec = c; + } + if (nc != NULL) + s->s3->tmp.new_cipher = nc; + else if (ec != NULL) + s->s3->tmp.new_cipher = ec; + else + s->s3->tmp.new_cipher = s->session->cipher; + } else +#endif + s->s3->tmp.new_cipher = s->session->cipher; + } + + if (TLS1_get_version(s) < TLS1_2_VERSION + || !(s->verify_mode & SSL_VERIFY_PEER)) { + if (!ssl3_digest_cached_records(s)) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + } + + /*- + * we now have the following setup. + * client_random + * cipher_list - our prefered list of ciphers + * ciphers - the clients prefered list of ciphers + * compression - basically ignored right now + * ssl version is set - sslv3 + * s->session - The ssl session has been setup. + * s->hit - session reuse flag + * s->tmp.new_cipher - the new cipher to use. + */ + + /* Handles TLS extensions that we couldn't check earlier */ + if (s->version >= SSL3_VERSION) { + if (ssl_check_clienthello_tlsext_late(s) <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO, SSL_R_CLIENTHELLO_TLSEXT); + goto err; + } + } + + ret = cookie_valid ? 2 : 1; + if (0) { + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + s->state = SSL_ST_ERR; + } + + if (ciphers != NULL) + sk_SSL_CIPHER_free(ciphers); + return ret; +} + +int ssl3_send_server_hello(SSL *s) +{ + unsigned char *buf; + unsigned char *p, *d; + int i, sl; + unsigned long l; + + if (s->state == SSL3_ST_SW_SRVR_HELLO_A) { + buf = (unsigned char *)s->init_buf->data; +#ifdef OPENSSL_NO_TLSEXT + p = s->s3->server_random; + if (ssl_fill_hello_random(s, 1, p, SSL3_RANDOM_SIZE) <= 0) { + s->state = SSL_ST_ERR; + return -1; + } +#endif + /* Do the message type and length last */ + d = p = &(buf[4]); + + *(p++) = s->version >> 8; + *(p++) = s->version & 0xff; + + /* Random stuff */ + memcpy(p, s->s3->server_random, SSL3_RANDOM_SIZE); + p += SSL3_RANDOM_SIZE; + + /*- + * There are several cases for the session ID to send + * back in the server hello: + * - For session reuse from the session cache, + * we send back the old session ID. + * - If stateless session reuse (using a session ticket) + * is successful, we send back the client's "session ID" + * (which doesn't actually identify the session). + * - If it is a new session, we send back the new + * session ID. + * - However, if we want the new session to be single-use, + * we send back a 0-length session ID. + * s->hit is non-zero in either case of session reuse, + * so the following won't overwrite an ID that we're supposed + * to send back. + */ + if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER) + && !s->hit) + s->session->session_id_length = 0; + + sl = s->session->session_id_length; + if (sl > (int)sizeof(s->session->session_id)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return -1; + } + *(p++) = sl; + memcpy(p, s->session->session_id, sl); + p += sl; + + /* put the cipher */ + i = ssl3_put_cipher_by_char(s->s3->tmp.new_cipher, p); + p += i; + + /* put the compression method */ +#ifdef OPENSSL_NO_COMP + *(p++) = 0; +#else + if (s->s3->tmp.new_compression == NULL) + *(p++) = 0; + else + *(p++) = s->s3->tmp.new_compression->id; +#endif +#ifndef OPENSSL_NO_TLSEXT + if (ssl_prepare_serverhello_tlsext(s) <= 0) { + SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, SSL_R_SERVERHELLO_TLSEXT); + s->state = SSL_ST_ERR; + return -1; + } + if ((p = + ssl_add_serverhello_tlsext(s, p, + buf + SSL3_RT_MAX_PLAIN_LENGTH)) == + NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_HELLO, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return -1; + } +#endif + /* do the header */ + l = (p - d); + d = buf; + *(d++) = SSL3_MT_SERVER_HELLO; + l2n3(l, d); + + s->state = SSL3_ST_SW_SRVR_HELLO_B; + /* number of bytes to write */ + s->init_num = p - buf; + s->init_off = 0; + } + + /* SSL3_ST_SW_SRVR_HELLO_B */ + return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); +} + +int ssl3_send_server_done(SSL *s) +{ + unsigned char *p; + + if (s->state == SSL3_ST_SW_SRVR_DONE_A) { + p = (unsigned char *)s->init_buf->data; + + /* do the header */ + *(p++) = SSL3_MT_SERVER_DONE; + *(p++) = 0; + *(p++) = 0; + *(p++) = 0; + + s->state = SSL3_ST_SW_SRVR_DONE_B; + /* number of bytes to write */ + s->init_num = 4; + s->init_off = 0; + } + + /* SSL3_ST_SW_SRVR_DONE_B */ + return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); +} + +int ssl3_send_server_key_exchange(SSL *s) +{ +#ifndef OPENSSL_NO_RSA + unsigned char *q; + int j, num; + RSA *rsa; + unsigned char md_buf[MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH]; + unsigned int u; +#endif +#ifndef OPENSSL_NO_DH + DH *dh = NULL, *dhp; +#endif +#ifndef OPENSSL_NO_ECDH + EC_KEY *ecdh = NULL, *ecdhp; + unsigned char *encodedPoint = NULL; + int encodedlen = 0; + int curve_id = 0; + BN_CTX *bn_ctx = NULL; +#endif + EVP_PKEY *pkey; + const EVP_MD *md = NULL; + unsigned char *p, *d; + int al, i; + unsigned long type; + int n; + CERT *cert; + BIGNUM *r[4]; + int nr[4], kn; + BUF_MEM *buf; + EVP_MD_CTX md_ctx; + + EVP_MD_CTX_init(&md_ctx); + if (s->state == SSL3_ST_SW_KEY_EXCH_A) { + type = s->s3->tmp.new_cipher->algorithm_mkey; + cert = s->cert; + + buf = s->init_buf; + + r[0] = r[1] = r[2] = r[3] = NULL; + n = 0; +#ifndef OPENSSL_NO_RSA + if (type & SSL_kRSA) { + rsa = cert->rsa_tmp; + if ((rsa == NULL) && (s->cert->rsa_tmp_cb != NULL)) { + rsa = s->cert->rsa_tmp_cb(s, + SSL_C_IS_EXPORT(s->s3-> + tmp.new_cipher), + SSL_C_EXPORT_PKEYLENGTH(s->s3-> + tmp.new_cipher)); + if (rsa == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_ERROR_GENERATING_TMP_RSA_KEY); + goto f_err; + } + RSA_up_ref(rsa); + cert->rsa_tmp = rsa; + } + if (rsa == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_MISSING_TMP_RSA_KEY); + goto f_err; + } + r[0] = rsa->n; + r[1] = rsa->e; + s->s3->tmp.use_rsa_tmp = 1; + } else +#endif +#ifndef OPENSSL_NO_DH + if (type & SSL_kEDH) { + dhp = cert->dh_tmp; + if ((dhp == NULL) && (s->cert->dh_tmp_cb != NULL)) + dhp = s->cert->dh_tmp_cb(s, + SSL_C_IS_EXPORT(s->s3-> + tmp.new_cipher), + SSL_C_EXPORT_PKEYLENGTH(s->s3-> + tmp.new_cipher)); + if (dhp == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_MISSING_TMP_DH_KEY); + goto f_err; + } + + if (s->s3->tmp.dh != NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + if ((dh = DHparams_dup(dhp)) == NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + + s->s3->tmp.dh = dh; + if (!DH_generate_key(dh)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_DH_LIB); + goto err; + } + r[0] = dh->p; + r[1] = dh->g; + r[2] = dh->pub_key; + } else +#endif +#ifndef OPENSSL_NO_ECDH + if (type & SSL_kEECDH) { + const EC_GROUP *group; + + ecdhp = cert->ecdh_tmp; + if ((ecdhp == NULL) && (s->cert->ecdh_tmp_cb != NULL)) { + ecdhp = s->cert->ecdh_tmp_cb(s, + SSL_C_IS_EXPORT(s->s3-> + tmp.new_cipher), + SSL_C_EXPORT_PKEYLENGTH(s-> + s3->tmp.new_cipher)); + } + if (ecdhp == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_MISSING_TMP_ECDH_KEY); + goto f_err; + } + + if (s->s3->tmp.ecdh != NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto err; + } + + /* Duplicate the ECDH structure. */ + if (ecdhp == NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + if ((ecdh = EC_KEY_dup(ecdhp)) == NULL) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + s->s3->tmp.ecdh = ecdh; + if ((EC_KEY_get0_public_key(ecdh) == NULL) || + (EC_KEY_get0_private_key(ecdh) == NULL) || + (s->options & SSL_OP_SINGLE_ECDH_USE)) { + if (!EC_KEY_generate_key(ecdh)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_ECDH_LIB); + goto err; + } + } + + if (((group = EC_KEY_get0_group(ecdh)) == NULL) || + (EC_KEY_get0_public_key(ecdh) == NULL) || + (EC_KEY_get0_private_key(ecdh) == NULL)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + if (SSL_C_IS_EXPORT(s->s3->tmp.new_cipher) && + (EC_GROUP_get_degree(group) > 163)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER); + goto err; + } + + /* + * XXX: For now, we only support ephemeral ECDH keys over named + * (not generic) curves. For supported named curves, curve_id is + * non-zero. + */ + if ((curve_id = + tls1_ec_nid2curve_id(EC_GROUP_get_curve_name(group))) + == 0) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_UNSUPPORTED_ELLIPTIC_CURVE); + goto err; + } + + /* + * Encode the public key. First check the size of encoding and + * allocate memory accordingly. + */ + encodedlen = EC_POINT_point2oct(group, + EC_KEY_get0_public_key(ecdh), + POINT_CONVERSION_UNCOMPRESSED, + NULL, 0, NULL); + + encodedPoint = (unsigned char *) + OPENSSL_malloc(encodedlen * sizeof(unsigned char)); + bn_ctx = BN_CTX_new(); + if ((encodedPoint == NULL) || (bn_ctx == NULL)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + encodedlen = EC_POINT_point2oct(group, + EC_KEY_get0_public_key(ecdh), + POINT_CONVERSION_UNCOMPRESSED, + encodedPoint, encodedlen, bn_ctx); + + if (encodedlen == 0) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + BN_CTX_free(bn_ctx); + bn_ctx = NULL; + + /* + * XXX: For now, we only support named (not generic) curves in + * ECDH ephemeral key exchanges. In this situation, we need four + * additional bytes to encode the entire ServerECDHParams + * structure. + */ + n = 4 + encodedlen; + + /* + * We'll generate the serverKeyExchange message explicitly so we + * can set these to NULLs + */ + r[0] = NULL; + r[1] = NULL; + r[2] = NULL; + r[3] = NULL; + } else +#endif /* !OPENSSL_NO_ECDH */ +#ifndef OPENSSL_NO_PSK + if (type & SSL_kPSK) { + /* + * reserve size for record length and PSK identity hint + */ + n += 2 + strlen(s->ctx->psk_identity_hint); + } else +#endif /* !OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + if (type & SSL_kSRP) { + if ((s->srp_ctx.N == NULL) || + (s->srp_ctx.g == NULL) || + (s->srp_ctx.s == NULL) || (s->srp_ctx.B == NULL)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_MISSING_SRP_PARAM); + goto err; + } + r[0] = s->srp_ctx.N; + r[1] = s->srp_ctx.g; + r[2] = s->srp_ctx.s; + r[3] = s->srp_ctx.B; + } else +#endif + { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE); + goto f_err; + } + for (i = 0; i < 4 && r[i] != NULL; i++) { + nr[i] = BN_num_bytes(r[i]); +#ifndef OPENSSL_NO_SRP + if ((i == 2) && (type & SSL_kSRP)) + n += 1 + nr[i]; + else +#endif + n += 2 + nr[i]; + } + + if (!(s->s3->tmp.new_cipher->algorithm_auth & (SSL_aNULL | SSL_aSRP)) + && !(s->s3->tmp.new_cipher->algorithm_mkey & SSL_kPSK)) { + if ((pkey = ssl_get_sign_pkey(s, s->s3->tmp.new_cipher, &md)) + == NULL) { + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + kn = EVP_PKEY_size(pkey); + } else { + pkey = NULL; + kn = 0; + } + + if (!BUF_MEM_grow_clean(buf, n + 4 + kn)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_BUF); + goto err; + } + d = (unsigned char *)s->init_buf->data; + p = &(d[4]); + + for (i = 0; i < 4 && r[i] != NULL; i++) { +#ifndef OPENSSL_NO_SRP + if ((i == 2) && (type & SSL_kSRP)) { + *p = nr[i]; + p++; + } else +#endif + s2n(nr[i], p); + BN_bn2bin(r[i], p); + p += nr[i]; + } + +#ifndef OPENSSL_NO_ECDH + if (type & SSL_kEECDH) { + /* + * XXX: For now, we only support named (not generic) curves. In + * this situation, the serverKeyExchange message has: [1 byte + * CurveType], [2 byte CurveName] [1 byte length of encoded + * point], followed by the actual encoded point itself + */ + *p = NAMED_CURVE_TYPE; + p += 1; + *p = 0; + p += 1; + *p = curve_id; + p += 1; + *p = encodedlen; + p += 1; + memcpy((unsigned char *)p, + (unsigned char *)encodedPoint, encodedlen); + OPENSSL_free(encodedPoint); + encodedPoint = NULL; + p += encodedlen; + } +#endif + +#ifndef OPENSSL_NO_PSK + if (type & SSL_kPSK) { + /* copy PSK identity hint */ + s2n(strlen(s->ctx->psk_identity_hint), p); + strncpy((char *)p, s->ctx->psk_identity_hint, + strlen(s->ctx->psk_identity_hint)); + p += strlen(s->ctx->psk_identity_hint); + } +#endif + + /* not anonymous */ + if (pkey != NULL) { + /* + * n is the length of the params, they start at &(d[4]) and p + * points to the space at the end. + */ +#ifndef OPENSSL_NO_RSA + if (pkey->type == EVP_PKEY_RSA + && TLS1_get_version(s) < TLS1_2_VERSION) { + q = md_buf; + j = 0; + for (num = 2; num > 0; num--) { + EVP_MD_CTX_set_flags(&md_ctx, + EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + if (EVP_DigestInit_ex(&md_ctx, + (num == 2) ? s->ctx->md5 + : s->ctx->sha1, + NULL) <= 0 + || EVP_DigestUpdate(&md_ctx, &(s->s3->client_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestUpdate(&md_ctx, &(s->s3->server_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_DigestUpdate(&md_ctx, &(d[4]), n) <= 0 + || EVP_DigestFinal_ex(&md_ctx, q, + (unsigned int *)&i) <= 0) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_LIB_EVP); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + q += i; + j += i; + } + if (RSA_sign(NID_md5_sha1, md_buf, j, + &(p[2]), &u, pkey->pkey.rsa) <= 0) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_RSA); + goto err; + } + s2n(u, p); + n += u + 2; + } else +#endif + if (md) { + /* + * For TLS1.2 and later send signature algorithm + */ + if (TLS1_get_version(s) >= TLS1_2_VERSION) { + if (!tls12_get_sigandhash(p, pkey, md)) { + /* Should never happen */ + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + ERR_R_INTERNAL_ERROR); + goto f_err; + } + p += 2; + } +#ifdef SSL_DEBUG + fprintf(stderr, "Using hash %s\n", EVP_MD_name(md)); +#endif + if (EVP_SignInit_ex(&md_ctx, md, NULL) <= 0 + || EVP_SignUpdate(&md_ctx, &(s->s3->client_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_SignUpdate(&md_ctx, &(s->s3->server_random[0]), + SSL3_RANDOM_SIZE) <= 0 + || EVP_SignUpdate(&md_ctx, &(d[4]), n) <= 0 + || EVP_SignFinal(&md_ctx, &(p[2]), + (unsigned int *)&i, pkey) <= 0) { + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, ERR_LIB_EVP); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + s2n(i, p); + n += i + 2; + if (TLS1_get_version(s) >= TLS1_2_VERSION) + n += 2; + } else { + /* Is this error check actually needed? */ + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE, + SSL_R_UNKNOWN_PKEY_TYPE); + goto f_err; + } + } + + *(d++) = SSL3_MT_SERVER_KEY_EXCHANGE; + l2n3(n, d); + + /* + * we should now have things packed up, so lets send it off + */ + s->init_num = n + 4; + s->init_off = 0; + } + + s->state = SSL3_ST_SW_KEY_EXCH_B; + EVP_MD_CTX_cleanup(&md_ctx); + return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: +#ifndef OPENSSL_NO_ECDH + if (encodedPoint != NULL) + OPENSSL_free(encodedPoint); + BN_CTX_free(bn_ctx); +#endif + EVP_MD_CTX_cleanup(&md_ctx); + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_send_certificate_request(SSL *s) +{ + unsigned char *p, *d; + int i, j, nl, off, n; + STACK_OF(X509_NAME) *sk = NULL; + X509_NAME *name; + BUF_MEM *buf; + + if (s->state == SSL3_ST_SW_CERT_REQ_A) { + buf = s->init_buf; + + d = p = (unsigned char *)&(buf->data[4]); + + /* get the list of acceptable cert types */ + p++; + n = ssl3_get_req_cert_type(s, p); + d[0] = n; + p += n; + n++; + + if (TLS1_get_version(s) >= TLS1_2_VERSION) { + nl = tls12_get_req_sig_algs(s, p + 2); + s2n(nl, p); + p += nl + 2; + n += nl + 2; + } + + off = n; + p += 2; + n += 2; + + sk = SSL_get_client_CA_list(s); + nl = 0; + if (sk != NULL) { + for (i = 0; i < sk_X509_NAME_num(sk); i++) { + name = sk_X509_NAME_value(sk, i); + j = i2d_X509_NAME(name, NULL); + if (!BUF_MEM_grow_clean(buf, 4 + n + j + 2)) { + SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, + ERR_R_BUF_LIB); + goto err; + } + p = (unsigned char *)&(buf->data[4 + n]); + if (!(s->options & SSL_OP_NETSCAPE_CA_DN_BUG)) { + s2n(j, p); + i2d_X509_NAME(name, &p); + n += 2 + j; + nl += 2 + j; + } else { + d = p; + i2d_X509_NAME(name, &p); + j -= 2; + s2n(j, d); + j += 2; + n += j; + nl += j; + } + } + } + /* else no CA names */ + p = (unsigned char *)&(buf->data[4 + off]); + s2n(nl, p); + + d = (unsigned char *)buf->data; + *(d++) = SSL3_MT_CERTIFICATE_REQUEST; + l2n3(n, d); + + /* + * we should now have things packed up, so lets send it off + */ + + s->init_num = n + 4; + s->init_off = 0; +#ifdef NETSCAPE_HANG_BUG + if (!BUF_MEM_grow_clean(buf, s->init_num + 4)) { + SSLerr(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST, ERR_R_BUF_LIB); + goto err; + } + p = (unsigned char *)s->init_buf->data + s->init_num; + + /* do the header */ + *(p++) = SSL3_MT_SERVER_DONE; + *(p++) = 0; + *(p++) = 0; + *(p++) = 0; + s->init_num += 4; +#endif + + s->state = SSL3_ST_SW_CERT_REQ_B; + } + + /* SSL3_ST_SW_CERT_REQ_B */ + return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); + err: + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_get_client_key_exchange(SSL *s) +{ + int i, al, ok; + long n; + unsigned long alg_k; + unsigned char *p; +#ifndef OPENSSL_NO_RSA + RSA *rsa = NULL; + EVP_PKEY *pkey = NULL; +#endif +#ifndef OPENSSL_NO_DH + BIGNUM *pub = NULL; + DH *dh_srvr; +#endif +#ifndef OPENSSL_NO_KRB5 + KSSL_ERR kssl_err; +#endif /* OPENSSL_NO_KRB5 */ + +#ifndef OPENSSL_NO_ECDH + EC_KEY *srvr_ecdh = NULL; + EVP_PKEY *clnt_pub_pkey = NULL; + EC_POINT *clnt_ecpoint = NULL; + BN_CTX *bn_ctx = NULL; +#endif + + n = s->method->ssl_get_message(s, + SSL3_ST_SR_KEY_EXCH_A, + SSL3_ST_SR_KEY_EXCH_B, + SSL3_MT_CLIENT_KEY_EXCHANGE, 2048, &ok); + + if (!ok) + return ((int)n); + p = (unsigned char *)s->init_msg; + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + +#ifndef OPENSSL_NO_RSA + if (alg_k & SSL_kRSA) { + unsigned char rand_premaster_secret[SSL_MAX_MASTER_KEY_LENGTH]; + int decrypt_len; + unsigned char decrypt_good, version_good; + size_t j; + + /* FIX THIS UP EAY EAY EAY EAY */ + if (s->s3->tmp.use_rsa_tmp) { + if ((s->cert != NULL) && (s->cert->rsa_tmp != NULL)) + rsa = s->cert->rsa_tmp; + /* + * Don't do a callback because rsa_tmp should be sent already + */ + if (rsa == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_TMP_RSA_PKEY); + goto f_err; + + } + } else { + pkey = s->cert->pkeys[SSL_PKEY_RSA_ENC].privatekey; + if ((pkey == NULL) || + (pkey->type != EVP_PKEY_RSA) || (pkey->pkey.rsa == NULL)) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_RSA_CERTIFICATE); + goto f_err; + } + rsa = pkey->pkey.rsa; + } + + /* TLS and [incidentally] DTLS{0xFEFF} */ + if (s->version > SSL3_VERSION && s->version != DTLS1_BAD_VER) { + n2s(p, i); + if (n != i + 2) { + if (!(s->options & SSL_OP_TLS_D5_BUG)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); + goto f_err; + } else + p -= 2; + } else + n = i; + } + + /* + * Reject overly short RSA ciphertext because we want to be sure + * that the buffer size makes it safe to iterate over the entire + * size of a premaster secret (SSL_MAX_MASTER_KEY_LENGTH). The + * actual expected size is larger due to RSA padding, but the + * bound is sufficient to be safe. + */ + if (n < SSL_MAX_MASTER_KEY_LENGTH) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG); + goto f_err; + } + + /* + * We must not leak whether a decryption failure occurs because of + * Bleichenbacher's attack on PKCS #1 v1.5 RSA padding (see RFC 2246, + * section 7.4.7.1). The code follows that advice of the TLS RFC and + * generates a random premaster secret for the case that the decrypt + * fails. See https://tools.ietf.org/html/rfc5246#section-7.4.7.1 + */ + + /* + * should be RAND_bytes, but we cannot work around a failure. + */ + if (RAND_pseudo_bytes(rand_premaster_secret, + sizeof(rand_premaster_secret)) <= 0) + goto err; + decrypt_len = + RSA_private_decrypt((int)n, p, p, rsa, RSA_PKCS1_PADDING); + ERR_clear_error(); + + /* + * decrypt_len should be SSL_MAX_MASTER_KEY_LENGTH. decrypt_good will + * be 0xff if so and zero otherwise. + */ + decrypt_good = + constant_time_eq_int_8(decrypt_len, SSL_MAX_MASTER_KEY_LENGTH); + + /* + * If the version in the decrypted pre-master secret is correct then + * version_good will be 0xff, otherwise it'll be zero. The + * Klima-Pokorny-Rosa extension of Bleichenbacher's attack + * (http://eprint.iacr.org/2003/052/) exploits the version number + * check as a "bad version oracle". Thus version checks are done in + * constant time and are treated like any other decryption error. + */ + version_good = + constant_time_eq_8(p[0], (unsigned)(s->client_version >> 8)); + version_good &= + constant_time_eq_8(p[1], (unsigned)(s->client_version & 0xff)); + + /* + * The premaster secret must contain the same version number as the + * ClientHello to detect version rollback attacks (strangely, the + * protocol does not offer such protection for DH ciphersuites). + * However, buggy clients exist that send the negotiated protocol + * version instead if the server does not support the requested + * protocol version. If SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such + * clients. + */ + if (s->options & SSL_OP_TLS_ROLLBACK_BUG) { + unsigned char workaround_good; + workaround_good = + constant_time_eq_8(p[0], (unsigned)(s->version >> 8)); + workaround_good &= + constant_time_eq_8(p[1], (unsigned)(s->version & 0xff)); + version_good |= workaround_good; + } + + /* + * Both decryption and version must be good for decrypt_good to + * remain non-zero (0xff). + */ + decrypt_good &= version_good; + + /* + * Now copy rand_premaster_secret over from p using + * decrypt_good_mask. If decryption failed, then p does not + * contain valid plaintext, however, a check above guarantees + * it is still sufficiently large to read from. + */ + for (j = 0; j < sizeof(rand_premaster_secret); j++) { + p[j] = constant_time_select_8(decrypt_good, p[j], + rand_premaster_secret[j]); + } + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + p, + sizeof + (rand_premaster_secret)); + OPENSSL_cleanse(p, sizeof(rand_premaster_secret)); + } else +#endif +#ifndef OPENSSL_NO_DH + if (alg_k & (SSL_kEDH | SSL_kDHr | SSL_kDHd)) { + n2s(p, i); + if (n != i + 2) { + if (!(s->options & SSL_OP_SSLEAY_080_CLIENT_DH_BUG)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG); + goto err; + } else { + p -= 2; + i = (int)n; + } + } + + if (n == 0L) { /* the parameters are in the cert */ + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_UNABLE_TO_DECODE_DH_CERTS); + goto f_err; + } else { + if (s->s3->tmp.dh == NULL) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_TMP_DH_KEY); + goto f_err; + } else + dh_srvr = s->s3->tmp.dh; + } + + pub = BN_bin2bn(p, i, NULL); + if (pub == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_BN_LIB); + goto err; + } + + i = DH_compute_key(p, pub, dh_srvr); + + if (i <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_DH_LIB); + BN_clear_free(pub); + goto err; + } + + DH_free(s->s3->tmp.dh); + s->s3->tmp.dh = NULL; + + BN_clear_free(pub); + pub = NULL; + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + p, i); + OPENSSL_cleanse(p, i); + } else +#endif +#ifndef OPENSSL_NO_KRB5 + if (alg_k & SSL_kKRB5) { + krb5_error_code krb5rc; + krb5_data enc_ticket; + krb5_data authenticator; + krb5_data enc_pms; + KSSL_CTX *kssl_ctx = s->kssl_ctx; + EVP_CIPHER_CTX ciph_ctx; + const EVP_CIPHER *enc = NULL; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char pms[SSL_MAX_MASTER_KEY_LENGTH + EVP_MAX_BLOCK_LENGTH]; + int padl, outl; + krb5_timestamp authtime = 0; + krb5_ticket_times ttimes; + int kerr = 0; + + EVP_CIPHER_CTX_init(&ciph_ctx); + + if (!kssl_ctx) + kssl_ctx = kssl_ctx_new(); + + n2s(p, i); + enc_ticket.length = i; + + if (n < (long)(enc_ticket.length + 6)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + enc_ticket.data = (char *)p; + p += enc_ticket.length; + + n2s(p, i); + authenticator.length = i; + + if (n < (long)(enc_ticket.length + authenticator.length + 6)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + authenticator.data = (char *)p; + p += authenticator.length; + + n2s(p, i); + enc_pms.length = i; + enc_pms.data = (char *)p; + p += enc_pms.length; + + /* + * Note that the length is checked again below, ** after decryption + */ + if (enc_pms.length > sizeof pms) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + if (n != (long)(enc_ticket.length + authenticator.length + + enc_pms.length + 6)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto err; + } + + if ((krb5rc = kssl_sget_tkt(kssl_ctx, &enc_ticket, &ttimes, + &kssl_err)) != 0) { +# ifdef KSSL_DEBUG + fprintf(stderr, "kssl_sget_tkt rtn %d [%d]\n", + krb5rc, kssl_err.reason); + if (kssl_err.text) + fprintf(stderr, "kssl_err text= %s\n", kssl_err.text); +# endif /* KSSL_DEBUG */ + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); + goto err; + } + + /* + * Note: no authenticator is not considered an error, ** but will + * return authtime == 0. + */ + if ((krb5rc = kssl_check_authent(kssl_ctx, &authenticator, + &authtime, &kssl_err)) != 0) { +# ifdef KSSL_DEBUG + fprintf(stderr, "kssl_check_authent rtn %d [%d]\n", + krb5rc, kssl_err.reason); + if (kssl_err.text) + fprintf(stderr, "kssl_err text= %s\n", kssl_err.text); +# endif /* KSSL_DEBUG */ + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, kssl_err.reason); + goto err; + } + + if ((krb5rc = kssl_validate_times(authtime, &ttimes)) != 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, krb5rc); + goto err; + } +# ifdef KSSL_DEBUG + kssl_ctx_show(kssl_ctx); +# endif /* KSSL_DEBUG */ + + enc = kssl_map_enc(kssl_ctx->enctype); + if (enc == NULL) + goto err; + + memset(iv, 0, sizeof iv); /* per RFC 1510 */ + + if (!EVP_DecryptInit_ex(&ciph_ctx, enc, NULL, kssl_ctx->key, iv)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + goto err; + } + if (!EVP_DecryptUpdate(&ciph_ctx, pms, &outl, + (unsigned char *)enc_pms.data, enc_pms.length)) + { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + kerr = 1; + goto kclean; + } + if (outl > SSL_MAX_MASTER_KEY_LENGTH) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + kerr = 1; + goto kclean; + } + if (!EVP_DecryptFinal_ex(&ciph_ctx, &(pms[outl]), &padl)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + kerr = 1; + goto kclean; + } + outl += padl; + if (outl > SSL_MAX_MASTER_KEY_LENGTH) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + kerr = 1; + goto kclean; + } + if (!((pms[0] == (s->client_version >> 8)) + && (pms[1] == (s->client_version & 0xff)))) { + /* + * The premaster secret must contain the same version number as + * the ClientHello to detect version rollback attacks (strangely, + * the protocol does not offer such protection for DH + * ciphersuites). However, buggy clients exist that send random + * bytes instead of the protocol version. If + * SSL_OP_TLS_ROLLBACK_BUG is set, tolerate such clients. + * (Perhaps we should have a separate BUG value for the Kerberos + * cipher) + */ + if (!(s->options & SSL_OP_TLS_ROLLBACK_BUG)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_AD_DECODE_ERROR); + kerr = 1; + goto kclean; + } + } + + EVP_CIPHER_CTX_cleanup(&ciph_ctx); + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + pms, outl); + + if (kssl_ctx->client_princ) { + size_t len = strlen(kssl_ctx->client_princ); + if (len < SSL_MAX_KRB5_PRINCIPAL_LENGTH) { + s->session->krb5_client_princ_len = len; + memcpy(s->session->krb5_client_princ, kssl_ctx->client_princ, + len); + } + } + + /*- Was doing kssl_ctx_free() here, + * but it caused problems for apache. + * kssl_ctx = kssl_ctx_free(kssl_ctx); + * if (s->kssl_ctx) s->kssl_ctx = NULL; + */ + + kclean: + OPENSSL_cleanse(pms, sizeof(pms)); + if (kerr) + goto err; + } else +#endif /* OPENSSL_NO_KRB5 */ + +#ifndef OPENSSL_NO_ECDH + if (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) { + int ret = 1; + int field_size = 0; + const EC_KEY *tkey; + const EC_GROUP *group; + const BIGNUM *priv_key; + + /* initialize structures for server's ECDH key pair */ + if ((srvr_ecdh = EC_KEY_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Let's get server private key and group information */ + if (alg_k & (SSL_kECDHr | SSL_kECDHe)) { + /* use the certificate */ + tkey = s->cert->pkeys[SSL_PKEY_ECC].privatekey->pkey.ec; + } else { + /* + * use the ephermeral values we saved when generating the + * ServerKeyExchange msg. + */ + tkey = s->s3->tmp.ecdh; + } + + group = EC_KEY_get0_group(tkey); + priv_key = EC_KEY_get0_private_key(tkey); + + if (!EC_KEY_set_group(srvr_ecdh, group) || + !EC_KEY_set_private_key(srvr_ecdh, priv_key)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + + /* Let's get client's public key */ + if ((clnt_ecpoint = EC_POINT_new(group)) == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (n == 0L) { + /* Client Publickey was in Client Certificate */ + + if (alg_k & SSL_kEECDH) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_MISSING_TMP_ECDH_KEY); + goto f_err; + } + if (((clnt_pub_pkey = X509_get_pubkey(s->session->peer)) + == NULL) || (clnt_pub_pkey->type != EVP_PKEY_EC)) { + /* + * XXX: For now, we do not support client authentication + * using ECDH certificates so this branch (n == 0L) of the + * code is never executed. When that support is added, we + * ought to ensure the key received in the certificate is + * authorized for key agreement. ECDH_compute_key implicitly + * checks that the two ECDH shares are for the same group. + */ + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_UNABLE_TO_DECODE_ECDH_CERTS); + goto f_err; + } + + if (EC_POINT_copy(clnt_ecpoint, + EC_KEY_get0_public_key(clnt_pub_pkey-> + pkey.ec)) == 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + ret = 2; /* Skip certificate verify processing */ + } else { + /* + * Get client's public key from encoded point in the + * ClientKeyExchange message. + */ + if ((bn_ctx = BN_CTX_new()) == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Get encoded point length */ + i = *p; + p += 1; + if (n != 1 + i) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + if (EC_POINT_oct2point(group, clnt_ecpoint, p, i, bn_ctx) == 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_EC_LIB); + goto err; + } + /* + * p is pointing to somewhere in the buffer currently, so set it + * to the start + */ + p = (unsigned char *)s->init_buf->data; + } + + /* Compute the shared pre-master secret */ + field_size = EC_GROUP_get_degree(group); + if (field_size <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + i = ECDH_compute_key(p, (field_size + 7) / 8, clnt_ecpoint, srvr_ecdh, + NULL); + if (i <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_ECDH_LIB); + goto err; + } + + EVP_PKEY_free(clnt_pub_pkey); + EC_POINT_free(clnt_ecpoint); + EC_KEY_free(srvr_ecdh); + BN_CTX_free(bn_ctx); + EC_KEY_free(s->s3->tmp.ecdh); + s->s3->tmp.ecdh = NULL; + + /* Compute the master secret */ + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + p, i); + + OPENSSL_cleanse(p, i); + return (ret); + } else +#endif +#ifndef OPENSSL_NO_PSK + if (alg_k & SSL_kPSK) { + unsigned char *t = NULL; + unsigned char psk_or_pre_ms[PSK_MAX_PSK_LEN * 2 + 4]; + unsigned int pre_ms_len = 0, psk_len = 0; + int psk_err = 1; + char tmp_id[PSK_MAX_IDENTITY_LEN + 1]; + + al = SSL_AD_HANDSHAKE_FAILURE; + + n2s(p, i); + if (n != i + 2) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_LENGTH_MISMATCH); + goto psk_err; + } + if (i > PSK_MAX_IDENTITY_LEN) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DATA_LENGTH_TOO_LONG); + goto psk_err; + } + if (s->psk_server_callback == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_NO_SERVER_CB); + goto psk_err; + } + + /* + * Create guaranteed NULL-terminated identity string for the callback + */ + memcpy(tmp_id, p, i); + memset(tmp_id + i, 0, PSK_MAX_IDENTITY_LEN + 1 - i); + psk_len = s->psk_server_callback(s, tmp_id, + psk_or_pre_ms, + sizeof(psk_or_pre_ms)); + OPENSSL_cleanse(tmp_id, PSK_MAX_IDENTITY_LEN + 1); + + if (psk_len > PSK_MAX_PSK_LEN) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto psk_err; + } else if (psk_len == 0) { + /* + * PSK related to the given identity not found + */ + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_PSK_IDENTITY_NOT_FOUND); + al = SSL_AD_UNKNOWN_PSK_IDENTITY; + goto psk_err; + } + + /* create PSK pre_master_secret */ + pre_ms_len = 2 + psk_len + 2 + psk_len; + t = psk_or_pre_ms; + memmove(psk_or_pre_ms + psk_len + 4, psk_or_pre_ms, psk_len); + s2n(psk_len, t); + memset(t, 0, psk_len); + t += psk_len; + s2n(psk_len, t); + + if (s->session->psk_identity != NULL) + OPENSSL_free(s->session->psk_identity); + s->session->psk_identity = BUF_strndup((char *)p, i); + if (s->session->psk_identity == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + if (s->session->psk_identity_hint != NULL) + OPENSSL_free(s->session->psk_identity_hint); + s->session->psk_identity_hint = BUF_strdup(s->ctx->psk_identity_hint); + if (s->ctx->psk_identity_hint != NULL && + s->session->psk_identity_hint == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto psk_err; + } + + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + psk_or_pre_ms, + pre_ms_len); + psk_err = 0; + psk_err: + OPENSSL_cleanse(psk_or_pre_ms, sizeof(psk_or_pre_ms)); + if (psk_err != 0) + goto f_err; + } else +#endif +#ifndef OPENSSL_NO_SRP + if (alg_k & SSL_kSRP) { + int param_len; + + n2s(p, i); + param_len = i + 2; + if (param_len > n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_BAD_SRP_A_LENGTH); + goto f_err; + } + if (!(s->srp_ctx.A = BN_bin2bn(p, i, NULL))) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_BN_LIB); + goto err; + } + if (BN_ucmp(s->srp_ctx.A, s->srp_ctx.N) >= 0 + || BN_is_zero(s->srp_ctx.A)) { + al = SSL_AD_ILLEGAL_PARAMETER; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_BAD_SRP_PARAMETERS); + goto f_err; + } + if (s->session->srp_username != NULL) + OPENSSL_free(s->session->srp_username); + s->session->srp_username = BUF_strdup(s->srp_ctx.login); + if (s->session->srp_username == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto err; + } + + if ((s->session->master_key_length = + SRP_generate_server_master_secret(s, + s->session->master_key)) < 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto err; + } + + p += i; + } else +#endif /* OPENSSL_NO_SRP */ + if (alg_k & SSL_kGOST) { + int ret = 0; + EVP_PKEY_CTX *pkey_ctx; + EVP_PKEY *client_pub_pkey = NULL, *pk = NULL; + unsigned char premaster_secret[32], *start; + size_t outlen = 32, inlen; + unsigned long alg_a; + int Ttag, Tclass; + long Tlen; + + /* Get our certificate private key */ + alg_a = s->s3->tmp.new_cipher->algorithm_auth; + if (alg_a & SSL_aGOST94) + pk = s->cert->pkeys[SSL_PKEY_GOST94].privatekey; + else if (alg_a & SSL_aGOST01) + pk = s->cert->pkeys[SSL_PKEY_GOST01].privatekey; + + pkey_ctx = EVP_PKEY_CTX_new(pk, NULL); + if (pkey_ctx == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_MALLOC_FAILURE); + goto f_err; + } + if (EVP_PKEY_decrypt_init(pkey_ctx) <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, ERR_R_INTERNAL_ERROR); + goto gerr; + } + /* + * If client certificate is present and is of the same type, maybe + * use it for key exchange. Don't mind errors from + * EVP_PKEY_derive_set_peer, because it is completely valid to use a + * client certificate for authorization only. + */ + client_pub_pkey = X509_get_pubkey(s->session->peer); + if (client_pub_pkey) { + if (EVP_PKEY_derive_set_peer(pkey_ctx, client_pub_pkey) <= 0) + ERR_clear_error(); + } + /* Decrypt session key */ + if (ASN1_get_object + ((const unsigned char **)&p, &Tlen, &Ttag, &Tclass, + n) != V_ASN1_CONSTRUCTED || Ttag != V_ASN1_SEQUENCE + || Tclass != V_ASN1_UNIVERSAL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + goto gerr; + } + start = p; + inlen = Tlen; + if (EVP_PKEY_decrypt + (pkey_ctx, premaster_secret, &outlen, start, inlen) <= 0) { + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, + SSL_R_DECRYPTION_FAILED); + goto gerr; + } + /* Generate master secret */ + s->session->master_key_length = + s->method->ssl3_enc->generate_master_secret(s, + s-> + session->master_key, + premaster_secret, 32); + OPENSSL_cleanse(premaster_secret, sizeof(premaster_secret)); + /* Check if pubkey from client certificate was used */ + if (EVP_PKEY_CTX_ctrl + (pkey_ctx, -1, -1, EVP_PKEY_CTRL_PEER_KEY, 2, NULL) > 0) + ret = 2; + else + ret = 1; + gerr: + EVP_PKEY_free(client_pub_pkey); + EVP_PKEY_CTX_free(pkey_ctx); + if (ret) + return ret; + else + goto err; + } else { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE, SSL_R_UNKNOWN_CIPHER_TYPE); + goto f_err; + } + + return (1); + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA) || !defined(OPENSSL_NO_ECDH) || defined(OPENSSL_NO_SRP) + err: +#endif +#ifndef OPENSSL_NO_ECDH + EVP_PKEY_free(clnt_pub_pkey); + EC_POINT_free(clnt_ecpoint); + if (srvr_ecdh != NULL) + EC_KEY_free(srvr_ecdh); + BN_CTX_free(bn_ctx); +#endif + s->state = SSL_ST_ERR; + return (-1); +} + +int ssl3_get_cert_verify(SSL *s) +{ + EVP_PKEY *pkey = NULL; + unsigned char *p; + int al, ok, ret = 0; + long n; + int type = 0, i, j; + X509 *peer; + const EVP_MD *md = NULL; + EVP_MD_CTX mctx; + EVP_MD_CTX_init(&mctx); + + /* + * We should only process a CertificateVerify message if we have received + * a Certificate from the client. If so then |s->session->peer| will be non + * NULL. In some instances a CertificateVerify message is not required even + * if the peer has sent a Certificate (e.g. such as in the case of static + * DH). In that case the ClientKeyExchange processing will skip the + * CertificateVerify state so we should not arrive here. + */ + if (s->session->peer == NULL) { + ret = 1; + goto end; + } + + n = s->method->ssl_get_message(s, + SSL3_ST_SR_CERT_VRFY_A, + SSL3_ST_SR_CERT_VRFY_B, + SSL3_MT_CERTIFICATE_VERIFY, + SSL3_RT_MAX_PLAIN_LENGTH, &ok); + + if (!ok) + return ((int)n); + + peer = s->session->peer; + pkey = X509_get_pubkey(peer); + type = X509_certificate_type(peer, pkey); + + if (!(type & EVP_PKT_SIGN)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE); + al = SSL_AD_ILLEGAL_PARAMETER; + goto f_err; + } + + /* we now have a signature that we need to verify */ + p = (unsigned char *)s->init_msg; + /* Check for broken implementations of GOST ciphersuites */ + /* + * If key is GOST and n is exactly 64, it is bare signature without + * length field + */ + if (n == 64 && (pkey->type == NID_id_GostR3410_94 || + pkey->type == NID_id_GostR3410_2001)) { + i = 64; + } else { + if (TLS1_get_version(s) >= TLS1_2_VERSION) { + int sigalg = tls12_get_sigid(pkey); + /* Should never happen */ + if (sigalg == -1) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + /* Check key type is consistent with signature */ + if (sigalg != (int)p[1]) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, + SSL_R_WRONG_SIGNATURE_TYPE); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + md = tls12_get_hash(p[0]); + if (md == NULL) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_UNKNOWN_DIGEST); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } +#ifdef SSL_DEBUG + fprintf(stderr, "USING TLSv1.2 HASH %s\n", EVP_MD_name(md)); +#endif + p += 2; + n -= 2; + } + n2s(p, i); + n -= 2; + if (i > n) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_LENGTH_MISMATCH); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + } + j = EVP_PKEY_size(pkey); + if ((i > j) || (n > j) || (n <= 0)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_WRONG_SIGNATURE_SIZE); + al = SSL_AD_DECODE_ERROR; + goto f_err; + } + + if (TLS1_get_version(s) >= TLS1_2_VERSION) { + long hdatalen = 0; + void *hdata; + hdatalen = BIO_get_mem_data(s->s3->handshake_buffer, &hdata); + if (hdatalen <= 0) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } +#ifdef SSL_DEBUG + fprintf(stderr, "Using TLS 1.2 with client verify alg %s\n", + EVP_MD_name(md)); +#endif + if (!EVP_VerifyInit_ex(&mctx, md, NULL) + || !EVP_VerifyUpdate(&mctx, hdata, hdatalen)) { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_EVP_LIB); + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + + if (EVP_VerifyFinal(&mctx, p, i, pkey) <= 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_SIGNATURE); + goto f_err; + } + } else +#ifndef OPENSSL_NO_RSA + if (pkey->type == EVP_PKEY_RSA) { + i = RSA_verify(NID_md5_sha1, s->s3->tmp.cert_verify_md, + MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH, p, i, + pkey->pkey.rsa); + if (i < 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_RSA_DECRYPT); + goto f_err; + } + if (i == 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_RSA_SIGNATURE); + goto f_err; + } + } else +#endif +#ifndef OPENSSL_NO_DSA + if (pkey->type == EVP_PKEY_DSA) { + j = DSA_verify(pkey->save_type, + &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, p, i, pkey->pkey.dsa); + if (j <= 0) { + /* bad signature */ + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_DSA_SIGNATURE); + goto f_err; + } + } else +#endif +#ifndef OPENSSL_NO_ECDSA + if (pkey->type == EVP_PKEY_EC) { + j = ECDSA_verify(pkey->save_type, + &(s->s3->tmp.cert_verify_md[MD5_DIGEST_LENGTH]), + SHA_DIGEST_LENGTH, p, i, pkey->pkey.ec); + if (j <= 0) { + /* bad signature */ + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE); + goto f_err; + } + } else +#endif + if (pkey->type == NID_id_GostR3410_94 + || pkey->type == NID_id_GostR3410_2001) { + unsigned char signature[64]; + int idx; + EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new(pkey, NULL); + if (pctx == NULL) { + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_MALLOC_FAILURE); + goto f_err; + } + if (EVP_PKEY_verify_init(pctx) <= 0) { + EVP_PKEY_CTX_free(pctx); + al = SSL_AD_INTERNAL_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); + goto f_err; + } + if (i != 64) { + fprintf(stderr, "GOST signature length is %d", i); + } + for (idx = 0; idx < 64; idx++) { + signature[63 - idx] = p[idx]; + } + j = EVP_PKEY_verify(pctx, signature, 64, s->s3->tmp.cert_verify_md, + 32); + EVP_PKEY_CTX_free(pctx); + if (j <= 0) { + al = SSL_AD_DECRYPT_ERROR; + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, SSL_R_BAD_ECDSA_SIGNATURE); + goto f_err; + } + } else { + SSLerr(SSL_F_SSL3_GET_CERT_VERIFY, ERR_R_INTERNAL_ERROR); + al = SSL_AD_UNSUPPORTED_CERTIFICATE; + goto f_err; + } + + ret = 1; + if (0) { + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + s->state = SSL_ST_ERR; + } + end: + if (s->s3->handshake_buffer) { + BIO_free(s->s3->handshake_buffer); + s->s3->handshake_buffer = NULL; + s->s3->flags &= ~TLS1_FLAGS_KEEP_HANDSHAKE; + } + EVP_MD_CTX_cleanup(&mctx); + EVP_PKEY_free(pkey); + return (ret); +} + +int ssl3_get_client_certificate(SSL *s) +{ + int i, ok, al, ret = -1; + X509 *x = NULL; + unsigned long l, nc, llen, n; + const unsigned char *p, *q; + unsigned char *d; + STACK_OF(X509) *sk = NULL; + + n = s->method->ssl_get_message(s, + SSL3_ST_SR_CERT_A, + SSL3_ST_SR_CERT_B, + -1, s->max_cert_list, &ok); + + if (!ok) + return ((int)n); + + if (s->s3->tmp.message_type == SSL3_MT_CLIENT_KEY_EXCHANGE) { + if ((s->verify_mode & SSL_VERIFY_PEER) && + (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; + } + /* + * If tls asked for a client cert, the client must return a 0 list + */ + if ((s->version > SSL3_VERSION) && s->s3->tmp.cert_request) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST); + al = SSL_AD_UNEXPECTED_MESSAGE; + goto f_err; + } + s->s3->tmp.reuse_message = 1; + return (1); + } + + if (s->s3->tmp.message_type != SSL3_MT_CERTIFICATE) { + al = SSL_AD_UNEXPECTED_MESSAGE; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_WRONG_MESSAGE_TYPE); + goto f_err; + } + p = d = (unsigned char *)s->init_msg; + + if ((sk = sk_X509_new_null()) == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto err; + } + + n2l3(p, llen); + if (llen + 3 != n) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, SSL_R_LENGTH_MISMATCH); + goto f_err; + } + for (nc = 0; nc < llen;) { + n2l3(p, l); + if ((l + nc + 3) > llen) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + + q = p; + x = d2i_X509(NULL, &p, l); + if (x == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_ASN1_LIB); + goto err; + } + if (p != (q + l)) { + al = SSL_AD_DECODE_ERROR; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_CERT_LENGTH_MISMATCH); + goto f_err; + } + if (!sk_X509_push(sk, x)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto err; + } + x = NULL; + nc += l + 3; + } + + if (sk_X509_num(sk) <= 0) { + /* TLS does not mind 0 certs returned */ + if (s->version == SSL3_VERSION) { + al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_NO_CERTIFICATES_RETURNED); + goto f_err; + } + /* Fail for TLS only if we required a certificate */ + else if ((s->verify_mode & SSL_VERIFY_PEER) && + (s->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT)) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + al = SSL_AD_HANDSHAKE_FAILURE; + goto f_err; + } + /* No client certificate so digest cached records */ + if (s->s3->handshake_buffer && !ssl3_digest_cached_records(s)) { + al = SSL_AD_INTERNAL_ERROR; + goto f_err; + } + } else { + i = ssl_verify_cert_chain(s, sk); + if (i <= 0) { + al = ssl_verify_alarm_type(s->verify_result); + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, + SSL_R_NO_CERTIFICATE_RETURNED); + goto f_err; + } + } + + if (s->session->peer != NULL) /* This should not be needed */ + X509_free(s->session->peer); + s->session->peer = sk_X509_shift(sk); + s->session->verify_result = s->verify_result; + + /* + * With the current implementation, sess_cert will always be NULL when we + * arrive here. + */ + if (s->session->sess_cert == NULL) { + s->session->sess_cert = ssl_sess_cert_new(); + if (s->session->sess_cert == NULL) { + SSLerr(SSL_F_SSL3_GET_CLIENT_CERTIFICATE, ERR_R_MALLOC_FAILURE); + goto err; + } + } + if (s->session->sess_cert->cert_chain != NULL) + sk_X509_pop_free(s->session->sess_cert->cert_chain, X509_free); + s->session->sess_cert->cert_chain = sk; + /* + * Inconsistency alert: cert_chain does *not* include the peer's own + * certificate, while we do include it in s3_clnt.c + */ + + sk = NULL; + + ret = 1; + if (0) { + f_err: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + err: + s->state = SSL_ST_ERR; + } + + if (x != NULL) + X509_free(x); + if (sk != NULL) + sk_X509_pop_free(sk, X509_free); + return (ret); +} + +int ssl3_send_server_certificate(SSL *s) +{ + unsigned long l; + X509 *x; + + if (s->state == SSL3_ST_SW_CERT_A) { + x = ssl_get_server_send_cert(s); + if (x == NULL) { + /* VRS: allow null cert if auth == KRB5 */ + if ((s->s3->tmp.new_cipher->algorithm_auth != SSL_aKRB5) || + (s->s3->tmp.new_cipher->algorithm_mkey & SSL_kKRB5)) { + SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, + ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return (0); + } + } + + l = ssl3_output_cert_chain(s, x); + if (!l) { + SSLerr(SSL_F_SSL3_SEND_SERVER_CERTIFICATE, ERR_R_INTERNAL_ERROR); + s->state = SSL_ST_ERR; + return (0); + } + s->state = SSL3_ST_SW_CERT_B; + s->init_num = (int)l; + s->init_off = 0; + } + + /* SSL3_ST_SW_CERT_B */ + return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); +} + +#ifndef OPENSSL_NO_TLSEXT +/* send a new session ticket (not necessarily for a new session) */ +int ssl3_send_newsession_ticket(SSL *s) +{ + unsigned char *senc = NULL; + EVP_CIPHER_CTX ctx; + HMAC_CTX hctx; + + if (s->state == SSL3_ST_SW_SESSION_TICKET_A) { + unsigned char *p, *macstart; + const unsigned char *const_p; + int len, slen_full, slen; + SSL_SESSION *sess; + unsigned int hlen; + SSL_CTX *tctx = s->initial_ctx; + unsigned char iv[EVP_MAX_IV_LENGTH]; + unsigned char key_name[16]; + + /* get session encoding length */ + slen_full = i2d_SSL_SESSION(s->session, NULL); + /* + * Some length values are 16 bits, so forget it if session is too + * long + */ + if (slen_full == 0 || slen_full > 0xFF00) { + s->state = SSL_ST_ERR; + return -1; + } + senc = OPENSSL_malloc(slen_full); + if (!senc) { + s->state = SSL_ST_ERR; + return -1; + } + + EVP_CIPHER_CTX_init(&ctx); + HMAC_CTX_init(&hctx); + + p = senc; + if (!i2d_SSL_SESSION(s->session, &p)) + goto err; + + /* + * create a fresh copy (not shared with other threads) to clean up + */ + const_p = senc; + sess = d2i_SSL_SESSION(NULL, &const_p, slen_full); + if (sess == NULL) + goto err; + sess->session_id_length = 0; /* ID is irrelevant for the ticket */ + + slen = i2d_SSL_SESSION(sess, NULL); + if (slen == 0 || slen > slen_full) { /* shouldn't ever happen */ + SSL_SESSION_free(sess); + goto err; + } + p = senc; + if (!i2d_SSL_SESSION(sess, &p)) { + SSL_SESSION_free(sess); + goto err; + } + SSL_SESSION_free(sess); + + /*- + * Grow buffer if need be: the length calculation is as + * follows 1 (size of message name) + 3 (message length + * bytes) + 4 (ticket lifetime hint) + 2 (ticket length) + + * 16 (key name) + max_iv_len (iv length) + + * session_length + max_enc_block_size (max encrypted session + * length) + max_md_size (HMAC). + */ + if (!BUF_MEM_grow(s->init_buf, + 26 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + + EVP_MAX_MD_SIZE + slen)) + goto err; + + p = (unsigned char *)s->init_buf->data; + /* do the header */ + *(p++) = SSL3_MT_NEWSESSION_TICKET; + /* Skip message length for now */ + p += 3; + /* + * Initialize HMAC and cipher contexts. If callback present it does + * all the work otherwise use generated values from parent ctx. + */ + if (tctx->tlsext_ticket_key_cb) { + if (tctx->tlsext_ticket_key_cb(s, key_name, iv, &ctx, + &hctx, 1) < 0) + goto err; + } else { + if (RAND_bytes(iv, 16) <= 0) + goto err; + if (!EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, + tctx->tlsext_tick_aes_key, iv)) + goto err; + if (!HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, + tlsext_tick_md(), NULL)) + goto err; + memcpy(key_name, tctx->tlsext_tick_key_name, 16); + } + + /* + * Ticket lifetime hint (advisory only): We leave this unspecified + * for resumed session (for simplicity), and guess that tickets for + * new sessions will live as long as their sessions. + */ + l2n(s->hit ? 0 : s->session->timeout, p); + + /* Skip ticket length for now */ + p += 2; + /* Output key name */ + macstart = p; + memcpy(p, key_name, 16); + p += 16; + /* output IV */ + memcpy(p, iv, EVP_CIPHER_CTX_iv_length(&ctx)); + p += EVP_CIPHER_CTX_iv_length(&ctx); + /* Encrypt session data */ + if (!EVP_EncryptUpdate(&ctx, p, &len, senc, slen)) + goto err; + p += len; + if (!EVP_EncryptFinal(&ctx, p, &len)) + goto err; + p += len; + + if (!HMAC_Update(&hctx, macstart, p - macstart)) + goto err; + if (!HMAC_Final(&hctx, p, &hlen)) + goto err; + + EVP_CIPHER_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&hctx); + + p += hlen; + /* Now write out lengths: p points to end of data written */ + /* Total length */ + len = p - (unsigned char *)s->init_buf->data; + p = (unsigned char *)s->init_buf->data + 1; + l2n3(len - 4, p); /* Message length */ + p += 4; + s2n(len - 10, p); /* Ticket length */ + + /* number of bytes to write */ + s->init_num = len; + s->state = SSL3_ST_SW_SESSION_TICKET_B; + s->init_off = 0; + OPENSSL_free(senc); + } + + /* SSL3_ST_SW_SESSION_TICKET_B */ + return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); + err: + if (senc) + OPENSSL_free(senc); + EVP_CIPHER_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&hctx); + s->state = SSL_ST_ERR; + return -1; +} + +int ssl3_send_cert_status(SSL *s) +{ + if (s->state == SSL3_ST_SW_CERT_STATUS_A) { + unsigned char *p; + /*- + * Grow buffer if need be: the length calculation is as + * follows 1 (message type) + 3 (message length) + + * 1 (ocsp response type) + 3 (ocsp response length) + * + (ocsp response) + */ + if (!BUF_MEM_grow(s->init_buf, 8 + s->tlsext_ocsp_resplen)) { + s->state = SSL_ST_ERR; + return -1; + } + + p = (unsigned char *)s->init_buf->data; + + /* do the header */ + *(p++) = SSL3_MT_CERTIFICATE_STATUS; + /* message length */ + l2n3(s->tlsext_ocsp_resplen + 4, p); + /* status type */ + *(p++) = s->tlsext_status_type; + /* length of OCSP response */ + l2n3(s->tlsext_ocsp_resplen, p); + /* actual response */ + memcpy(p, s->tlsext_ocsp_resp, s->tlsext_ocsp_resplen); + /* number of bytes to write */ + s->init_num = 8 + s->tlsext_ocsp_resplen; + s->state = SSL3_ST_SW_CERT_STATUS_B; + s->init_off = 0; + } + + /* SSL3_ST_SW_CERT_STATUS_B */ + return (ssl3_do_write(s, SSL3_RT_HANDSHAKE)); +} + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* + * ssl3_get_next_proto reads a Next Protocol Negotiation handshake message. + * It sets the next_proto member in s if found + */ +int ssl3_get_next_proto(SSL *s) +{ + int ok; + int proto_len, padding_len; + long n; + const unsigned char *p; + + /* + * Clients cannot send a NextProtocol message if we didn't see the + * extension in their ClientHello + */ + if (!s->s3->next_proto_neg_seen) { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, + SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION); + s->state = SSL_ST_ERR; + return -1; + } + + /* See the payload format below */ + n = s->method->ssl_get_message(s, + SSL3_ST_SR_NEXT_PROTO_A, + SSL3_ST_SR_NEXT_PROTO_B, + SSL3_MT_NEXT_PROTO, 514, &ok); + + if (!ok) + return ((int)n); + + /* + * s->state doesn't reflect whether ChangeCipherSpec has been received in + * this handshake, but s->s3->change_cipher_spec does (will be reset by + * ssl3_get_finished). + */ + if (!s->s3->change_cipher_spec) { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS); + s->state = SSL_ST_ERR; + return -1; + } + + if (n < 2) { + s->state = SSL_ST_ERR; + return 0; /* The body must be > 1 bytes long */ + } + + p = (unsigned char *)s->init_msg; + + /*- + * The payload looks like: + * uint8 proto_len; + * uint8 proto[proto_len]; + * uint8 padding_len; + * uint8 padding[padding_len]; + */ + proto_len = p[0]; + if (proto_len + 2 > s->init_num) { + s->state = SSL_ST_ERR; + return 0; + } + padding_len = p[proto_len + 1]; + if (proto_len + padding_len + 2 != s->init_num) { + s->state = SSL_ST_ERR; + return 0; + } + + s->next_proto_negotiated = OPENSSL_malloc(proto_len); + if (!s->next_proto_negotiated) { + SSLerr(SSL_F_SSL3_GET_NEXT_PROTO, ERR_R_MALLOC_FAILURE); + s->state = SSL_ST_ERR; + return 0; + } + memcpy(s->next_proto_negotiated, p + 1, proto_len); + s->next_proto_negotiated_len = proto_len; + + return 1; +} +# endif +#endif diff --git a/libs/openssl/ssl/ssl-lib.com b/libs/openssl/ssl/ssl-lib.com new file mode 100644 index 00000000..7303bc4d --- /dev/null +++ b/libs/openssl/ssl/ssl-lib.com @@ -0,0 +1,1229 @@ +$! +$! SSL-LIB.COM +$! Written By: Robert Byer +$! Vice-President +$! A-Com Computing, Inc. +$! byer@mail.all-net.net +$! +$! Changes by Richard Levitte +$! +$! This command file compiles and creates the "[.xxx.EXE.SSL]LIBSSL.OLB" +$! library for OpenSSL. The "xxx" denotes the machine architecture of +$! ALPHA, IA64 or VAX. +$! +$! It is written to detect what type of machine you are compiling on +$! (i.e. ALPHA or VAX) and which "C" compiler you have (i.e. VAXC, DECC +$! or GNU C) or you can specify which compiler to use. +$! +$! Specify the following as P1 to build just that part or ALL to just +$! build everything. +$! +$! LIBRARY To just compile the [.xxx.EXE.SSL]LIBSSL.OLB Library. +$! SSL_TASK To just compile the [.xxx.EXE.SSL]SSL_TASK.EXE +$! +$! Specify DEBUG or NODEBUG as P2 to compile with or without debugger +$! information. +$! +$! Specify which compiler at P3 to try to compile under. +$! +$! VAXC For VAX C. +$! DECC For DEC C. +$! GNUC For GNU C. +$! +$! If you don't specify a compiler, it will try to determine which +$! "C" compiler to use. +$! +$! P4, if defined, sets a TCP/IP library to use, through one of the following +$! keywords: +$! +$! UCX for UCX +$! TCPIP for TCPIP (post UCX) +$! SOCKETSHR for SOCKETSHR+NETLIB +$! +$! P5, if defined, sets a compiler thread NOT needed on OpenVMS 7.1 (and up) +$! +$! P6, if defined, specifies the C pointer size. Ignored on VAX. +$! ("64=ARGV" gives more efficient code with HP C V7.3 or newer.) +$! Supported values are: +$! +$! "" Compile with default (/NOPOINTER_SIZE) +$! 32 Compile with /POINTER_SIZE=32 (SHORT) +$! 64 Compile with /POINTER_SIZE=64[=ARGV] (LONG[=ARGV]) +$! (Automatically select ARGV if compiler supports it.) +$! 64= Compile with /POINTER_SIZE=64 (LONG). +$! 64=ARGV Compile with /POINTER_SIZE=64=ARGV (LONG=ARGV). +$! +$! P7, if defined, specifies a directory where ZLIB files (zlib.h, +$! libz.olb) may be found. Optionally, a non-default object library +$! name may be included ("dev:[dir]libz_64.olb", for example). +$! +$! +$! Announce/identify. +$! +$ proc = f$environment( "procedure") +$ write sys$output "@@@ "+ - + f$parse( proc, , , "name")+ f$parse( proc, , , "type") +$! +$! Define A TCP/IP Library That We Will Need To Link To. +$! (That Is, If We Need To Link To One.) +$! +$ TCPIP_LIB = "" +$ ZLIB_LIB = "" +$! +$! Check What Architecture We Are Using. +$! +$ IF (F$GETSYI("CPU").LT.128) +$ THEN +$! +$! The Architecture Is VAX. +$! +$ ARCH = "VAX" +$! +$! Else... +$! +$ ELSE +$! +$! The Architecture Is Alpha, IA64 or whatever comes in the future. +$! +$ ARCH = F$EDIT( F$GETSYI( "ARCH_NAME"), "UPCASE") +$ IF (ARCH .EQS. "") THEN ARCH = "UNK" +$! +$! End The Architecture Check. +$! +$ ENDIF +$! +$ ARCHD = ARCH +$ LIB32 = "32" +$ OPT_FILE = "" +$ POINTER_SIZE = "" +$! +$! Check To Make Sure We Have Valid Command Line Parameters. +$! +$ GOSUB CHECK_OPTIONS +$! +$! Define The OBJ and EXE Directories. +$! +$ OBJ_DIR := SYS$DISK:[-.'ARCHD'.OBJ.SSL] +$ EXE_DIR := SYS$DISK:[-.'ARCHD'.EXE.SSL] +$! +$! Specify the destination directory in any /MAP option. +$! +$ if (LINKMAP .eqs. "MAP") +$ then +$ LINKMAP = LINKMAP+ "=''EXE_DIR'" +$ endif +$! +$! Add the location prefix to the linker options file name. +$! +$ if (OPT_FILE .nes. "") +$ then +$ OPT_FILE = EXE_DIR+ OPT_FILE +$ endif +$! +$! Initialise logical names and such +$! +$ GOSUB INITIALISE +$! +$! Tell The User What Kind of Machine We Run On. +$! +$ WRITE SYS$OUTPUT "Host system architecture: ''ARCHD'" +$! +$! Check To See If The Architecture Specific OBJ Directory Exists. +$! +$ IF (F$PARSE(OBJ_DIR).EQS."") +$ THEN +$! +$! It Dosen't Exist, So Create It. +$! +$ CREATE/DIR 'OBJ_DIR' +$! +$! End The Architecture Specific OBJ Directory Check. +$! +$ ENDIF +$! +$! Check To See If The Architecture Specific Directory Exists. +$! +$ IF (F$PARSE(EXE_DIR).EQS."") +$ THEN +$! +$! It Dosen't Exist, So Create It. +$! +$ CREATE/DIR 'EXE_DIR' +$! +$! End The Architecture Specific Directory Check. +$! +$ ENDIF +$! +$! Define The Library Name. +$! +$ SSL_LIB := 'EXE_DIR'SSL_LIBSSL'LIB32'.OLB +$! +$! Define The CRYPTO-LIB We Are To Use. +$! +$ CRYPTO_LIB := SYS$DISK:[-.'ARCHD'.EXE.CRYPTO]SSL_LIBCRYPTO'LIB32'.OLB +$! +$! Set up exceptional compilations. +$! +$ CC5_SHOWN = 0 +$! +$! Check To See What We Are To Do. +$! +$ IF (BUILDALL.EQS."TRUE") +$ THEN +$! +$! Since Nothing Special Was Specified, Do Everything. +$! +$ GOSUB LIBRARY +$ GOSUB SSL_TASK +$! +$! Else... +$! +$ ELSE +$! +$! Build Just What The User Wants Us To Build. +$! +$ GOSUB 'BUILDALL' +$! +$! End The BUILDALL Check. +$! +$ ENDIF +$! +$! Time To EXIT. +$! +$ EXIT: +$ GOSUB CLEANUP +$ EXIT +$! +$! Compile The Library. +$! +$ LIBRARY: +$! +$! Check To See If We Already Have A "[.xxx.EXE.SSL]SSL_LIBSSL''LIB32'.OLB" Library... +$! +$ IF (F$SEARCH(SSL_LIB).EQS."") +$ THEN +$! +$! Guess Not, Create The Library. +$! +$ LIBRARY/CREATE/OBJECT 'SSL_LIB' +$! +$! End The Library Exist Check. +$! +$ ENDIF +$! +$! Define The Different SSL "library" Files. +$! +$ LIB_SSL = "s2_meth, s2_srvr, s2_clnt, s2_lib, s2_enc, s2_pkt,"+ - + "s3_meth, s3_srvr, s3_clnt, s3_lib, s3_enc, s3_pkt, s3_both, s3_cbc,"+ - + "s23_meth,s23_srvr,s23_clnt,s23_lib, s23_pkt,"+ - + "t1_meth, t1_srvr, t1_clnt, t1_lib, t1_enc,"+ - + "d1_meth, d1_srvr, d1_clnt, d1_lib, d1_pkt,"+ - + "d1_both,d1_enc,d1_srtp,"+ - + "ssl_lib,ssl_err2,ssl_cert,ssl_sess,"+ - + "ssl_ciph,ssl_stat,ssl_rsa,"+ - + "ssl_asn1,ssl_txt,ssl_algs,"+ - + "bio_ssl,ssl_err,kssl,tls_srp,t1_reneg,ssl_utst" +$! +$ COMPILEWITH_CC5 = "" +$! +$! Tell The User That We Are Compiling The Library. +$! +$ WRITE SYS$OUTPUT "Building The ",SSL_LIB," Library." +$! +$! Define A File Counter And Set It To "0" +$! +$ FILE_COUNTER = 0 +$! +$! Top Of The File Loop. +$! +$ NEXT_FILE: +$! +$! O.K, Extract The File Name From The File List. +$! +$ FILE_NAME = F$EDIT(F$ELEMENT(FILE_COUNTER,",",LIB_SSL),"COLLAPSE") +$! +$! Check To See If We Are At The End Of The File List. +$! +$ IF (FILE_NAME.EQS.",") THEN GOTO FILE_DONE +$! +$! Increment The Counter. +$! +$ FILE_COUNTER = FILE_COUNTER + 1 +$! +$! Create The Source File Name. +$! +$ SOURCE_FILE = "SYS$DISK:[]" + FILE_NAME + ".C" +$! +$! Create The Object File Name. +$! +$ OBJECT_FILE = OBJ_DIR + FILE_NAME + ".OBJ" +$ ON WARNING THEN GOTO NEXT_FILE +$! +$! Check To See If The File We Want To Compile Is Actually There. +$! +$ IF (F$SEARCH(SOURCE_FILE).EQS."") +$ THEN +$! +$! Tell The User That The File Dosen't Exist. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The File ",SOURCE_FILE," Dosen't Exist." +$ WRITE SYS$OUTPUT "" +$! +$! Exit The Build. +$! +$ EXIT +$! +$! End The File Exists Check. +$! +$ ENDIF +$! +$! Tell The User What File We Are Compiling. +$! +$ WRITE SYS$OUTPUT " ",FILE_NAME,".c" +$! +$! Compile The File. +$! +$ ON ERROR THEN GOTO NEXT_FILE +$ CC/OBJECT='OBJECT_FILE' 'SOURCE_FILE' +$! +$! Add It To The Library. +$! +$ LIBRARY/REPLACE/OBJECT 'SSL_LIB' 'OBJECT_FILE' +$! +$! Time To Clean Up The Object File. +$! +$ DELETE 'OBJECT_FILE';* +$! +$! Go Back And Get The Next File Name. +$! +$ GOTO NEXT_FILE +$! +$! All Done With This Library. +$! +$ FILE_DONE: +$! +$! Tell The User That We Are All Done. +$! +$ WRITE SYS$OUTPUT "Library ",SSL_LIB," Compiled." +$! +$! Time To RETURN. +$! +$ RETURN +$ SSL_TASK: +$! +$! Check To See If We Have The Proper Libraries. +$! +$ GOSUB LIB_CHECK +$! +$! Check To See If We Have A Linker Option File. +$! +$ GOSUB CHECK_OPT_FILE +$! +$! Check To See If The File We Want To Compile Is Actually There. +$! +$ IF (F$SEARCH("SYS$DISK:[]SSL_TASK.C").EQS."") +$ THEN +$! +$! Tell The User That The File Dosen't Exist. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The File SSL_TASK.C Dosen't Exist." +$ WRITE SYS$OUTPUT "" +$! +$! Exit The Build. +$! +$ EXIT +$! +$! End The SSL_TASK.C File Check. +$! +$ ENDIF +$! +$ COMPILEWITH_CC5 = "" !!! ",ssl_task," +$! +$! Tell The User We Are Creating The SSL_TASK. +$! +$! Tell The User We Are Creating The SSL_TASK. +$! +$ WRITE SYS$OUTPUT "Creating SSL_TASK OSU HTTP SSL Engine." +$! +$! Tell The User What File We Are Compiling. +$! +$ FILE_NAME = "ssl_task" +$ WRITE SYS$OUTPUT " ",FILE_NAME,".c" +$! +$! Compile The File. +$! +$ ON ERROR THEN GOTO SSL_TASK_END +$! +$ FILE_NAME0 = ","+ F$ELEMENT(0,".",FILE_NAME)+ "," +$ IF COMPILEWITH_CC5 - FILE_NAME0 .NES. COMPILEWITH_CC5 +$ THEN +$ if (.not. CC5_SHOWN) +$ then +$ CC5_SHOWN = 1 +$ write sys$output " \Using special rule (5)" +$ x = " "+ CC5 +$ write /symbol sys$output x +$ endif +$ CC5 /OBJECT='OBJ_DIR''FILE_NAME'.OBJ SYS$DISK:[]'FILE_NAME'.C +$ ELSE +$ CC /OBJECT='OBJ_DIR''FILE_NAME'.OBJ SYS$DISK:[]'FILE_NAME'.C +$ ENDIF +$! +$! Link The Program. +$! +$ LINK /'DEBUGGER' /'LINKMAP' /'TRACEBACK' /EXE='EXE_DIR'SSL_TASK.EXE - + 'OBJ_DIR'SSL_TASK.OBJ, - + 'SSL_LIB'/LIBRARY, - + 'CRYPTO_LIB'/LIBRARY - + 'TCPIP_LIB' - + 'ZLIB_LIB' - + ,'OPT_FILE' /OPTIONS +$! +$! Time To Return. +$! +$SSL_TASK_END: +$ RETURN +$! +$! Check For The Link Option FIle. +$! +$ CHECK_OPT_FILE: +$! +$! Check To See If We Need To Make A VAX C Option File. +$! +$ IF (COMPILER.EQS."VAXC") +$ THEN +$! +$! Check To See If We Already Have A VAX C Linker Option File. +$! +$ IF (F$SEARCH(OPT_FILE).EQS."") +$ THEN +$! +$! We Need A VAX C Linker Option File. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File To Link Against +! The Sharable VAX C Runtime Library. +! +SYS$SHARE:VAXCRTL.EXE/SHARE +$EOD +$! +$! End The Option File Check. +$! +$ ENDIF +$! +$! End The VAXC Check. +$! +$ ENDIF +$! +$! Check To See If We Need A GNU C Option File. +$! +$ IF (COMPILER.EQS."GNUC") +$ THEN +$! +$! Check To See If We Already Have A GNU C Linker Option File. +$! +$ IF (F$SEARCH(OPT_FILE).EQS."") +$ THEN +$! +$! We Need A GNU C Linker Option File. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File To Link Against +! The Sharable C Runtime Library. +! +GNU_CC:[000000]GCCLIB/LIBRARY +SYS$SHARE:VAXCRTL/SHARE +$EOD +$! +$! End The Option File Check. +$! +$ ENDIF +$! +$! End The GNU C Check. +$! +$ ENDIF +$! +$! Check To See If We Need A DEC C Option File. +$! +$ IF (COMPILER.EQS."DECC") +$ THEN +$! +$! Check To See If We Already Have A DEC C Linker Option File. +$! +$ IF (F$SEARCH(OPT_FILE).EQS."") +$ THEN +$! +$! Figure Out If We Need A non-VAX Or A VAX Linker Option File. +$! +$ IF (ARCH.EQS."VAX") +$ THEN +$! +$! We Need A DEC C Linker Option File For VAX. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File To Link Against +! The Sharable DEC C Runtime Library. +! +SYS$SHARE:DECC$SHR.EXE/SHARE +$EOD +$! +$! Else... +$! +$ ELSE +$! +$! Create The non-VAX Linker Option File. +$! +$ CREATE 'OPT_FILE' +$DECK +! +! Default System Options File For non-VAX To Link Against +! The Sharable C Runtime Library. +! +SYS$SHARE:CMA$OPEN_LIB_SHR/SHARE +SYS$SHARE:CMA$OPEN_RTL/SHARE +$EOD +$! +$! End The DEC C Option File Check. +$! +$ ENDIF +$! +$! End The Option File Search. +$! +$ ENDIF +$! +$! End The DEC C Check. +$! +$ ENDIF +$! +$! Tell The User What Linker Option File We Are Using. +$! +$ WRITE SYS$OUTPUT "Using Linker Option File ",OPT_FILE,"." +$! +$! Time To RETURN. +$! +$ RETURN +$ LIB_CHECK: +$! +$! Look For The VAX Library LIBSSL.OLB. +$! +$ IF (F$SEARCH(SSL_LIB).EQS."") +$ THEN +$! +$! Tell The User We Can't Find The LIBSSL.OLB Library. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "Can't Find The Library ",SSL_LIB,"." +$ WRITE SYS$OUTPUT "We Can't Link Without It." +$ WRITE SYS$OUTPUT "" +$! +$! Since We Can't Link Without It, Exit. +$! +$ EXIT +$! +$! End The LIBSSL.OLB Library Check. +$! +$ ENDIF +$! +$! Look For The Library LIBCRYPTO.OLB. +$! +$ IF (F$SEARCH(CRYPTO_LIB).EQS."") +$ THEN +$! +$! Tell The User We Can't Find The LIBCRYPTO.OLB Library. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "Can't Find The Library ",CRYPTO_LIB,"." +$ WRITE SYS$OUTPUT "We Can't Link Without It." +$ WRITE SYS$OUTPUT "" +$! +$! Since We Can't Link Without It, Exit. +$! +$ EXIT +$! +$! End The LIBCRYPTO.OLB Library Check. +$! +$ ENDIF +$! +$! Time To Return. +$! +$ RETURN +$! +$! Check The User's Options. +$! +$ CHECK_OPTIONS: +$! +$! Check To See If P1 Is Blank. +$! +$ IF (P1.EQS."ALL") +$ THEN +$! +$! P1 Is Blank, So Build Everything. +$! +$ BUILDALL = "TRUE" +$! +$! Else... +$! +$ ELSE +$! +$! Else, Check To See If P1 Has A Valid Argument. +$! +$ IF (P1.EQS."LIBRARY").OR.(P1.EQS."SSL_TASK") +$ THEN +$! +$! A Valid Argument. +$! +$ BUILDALL = P1 +$! +$! Else... +$! +$ ELSE +$! +$! Tell The User We Don't Know What They Want. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P1," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " ALL : Just Build Everything." +$ WRITE SYS$OUTPUT " LIBRARY : To Compile Just The [.xxx.EXE.SSL]LIBSSL.OLB Library." +$ WRITE SYS$OUTPUT " SSL_TASK : To Compile Just The [.xxx.EXE.SSL]SSL_TASK.EXE Program." +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " Where 'xxx' Stands For:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " ALPHA[64]: Alpha Architecture." +$ WRITE SYS$OUTPUT " IA64[64] : IA64 Architecture." +$ WRITE SYS$OUTPUT " VAX : VAX Architecture." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$! End The Valid Argument Check. +$! +$ ENDIF +$! +$! End The P1 Check. +$! +$ ENDIF +$! +$! Check To See If P2 Is Blank. +$! +$ IF (P2.EQS."NODEBUG") +$ THEN +$! +$! P2 Is NODEBUG, So Compile Without Debugger Information. +$! +$ DEBUGGER = "NODEBUG" +$ LINKMAP = "NOMAP" +$ TRACEBACK = "NOTRACEBACK" +$ GCC_OPTIMIZE = "OPTIMIZE" +$ CC_OPTIMIZE = "OPTIMIZE" +$ WRITE SYS$OUTPUT "No Debugger Information Will Be Produced During Compile." +$ WRITE SYS$OUTPUT "Compiling With Compiler Optimization." +$! +$! Else... +$! +$ ELSE +$! +$! Check To See If We Are To Compile With Debugger Information. +$! +$ IF (P2.EQS."DEBUG") +$ THEN +$! +$! Compile With Debugger Information. +$! +$ DEBUGGER = "DEBUG" +$ LINKMAP = "MAP" +$ TRACEBACK = "TRACEBACK" +$ GCC_OPTIMIZE = "NOOPTIMIZE" +$ CC_OPTIMIZE = "NOOPTIMIZE" +$ WRITE SYS$OUTPUT "Debugger Information Will Be Produced During Compile." +$ WRITE SYS$OUTPUT "Compiling Without Compiler Optimization." +$ ELSE +$! +$! Tell The User Entered An Invalid Option. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P2," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " DEBUG : Compile With The Debugger Information." +$ WRITE SYS$OUTPUT " NODEBUG : Compile Without The Debugger Information." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$! End The Valid Argument Check. +$! +$ ENDIF +$! +$! End The P2 Check. +$! +$ ENDIF +$! +$! Special Threads For OpenVMS v7.1 Or Later +$! +$! Written By: Richard Levitte +$! richard@levitte.org +$! +$! +$! Check To See If We Have A Option For P5. +$! +$ IF (P5.EQS."") +$ THEN +$! +$! Get The Version Of VMS We Are Using. +$! +$ ISSEVEN := +$ TMP = F$ELEMENT(0,"-",F$EXTRACT(1,4,F$GETSYI("VERSION"))) +$ TMP = F$INTEGER(F$ELEMENT(0,".",TMP)+F$ELEMENT(1,".",TMP)) +$! +$! Check To See If The VMS Version Is v7.1 Or Later. +$! +$ IF (TMP.GE.71) +$ THEN +$! +$! We Have OpenVMS v7.1 Or Later, So Use The Special Threads. +$! +$ ISSEVEN := ,PTHREAD_USE_D4 +$! +$! End The VMS Version Check. +$! +$ ENDIF +$! +$! End The P5 Check. +$! +$ ENDIF +$! +$! Check P6 (POINTER_SIZE). +$! +$ IF (P6 .NES. "") .AND. (ARCH .NES. "VAX") +$ THEN +$! +$ IF (P6 .EQS. "32") +$ THEN +$ POINTER_SIZE = " /POINTER_SIZE=32" +$ ELSE +$ POINTER_SIZE = F$EDIT( P6, "COLLAPSE, UPCASE") +$ IF ((POINTER_SIZE .EQS. "64") .OR. - + (POINTER_SIZE .EQS. "64=") .OR. - + (POINTER_SIZE .EQS. "64=ARGV")) +$ THEN +$ ARCHD = ARCH+ "_64" +$ LIB32 = "" +$ POINTER_SIZE = " /POINTER_SIZE=64" +$ ELSE +$! +$! Tell The User Entered An Invalid Option. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ", P6, - + " Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT - + " """" : Compile with default (short) pointers." +$ WRITE SYS$OUTPUT - + " 32 : Compile with 32-bit (short) pointers." +$ WRITE SYS$OUTPUT - + " 64 : Compile with 64-bit (long) pointers (auto ARGV)." +$ WRITE SYS$OUTPUT - + " 64= : Compile with 64-bit (long) pointers (no ARGV)." +$ WRITE SYS$OUTPUT - + " 64=ARGV : Compile with 64-bit (long) pointers (ARGV)." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$ ENDIF +$! +$ ENDIF +$! +$! End The P6 (POINTER_SIZE) Check. +$! +$ ENDIF +$! +$! Set basic C compiler /INCLUDE directories. +$! +$ CC_INCLUDES = "SYS$DISK:[-.CRYPTO],SYS$DISK:[-]" +$! +$! Check To See If P3 Is Blank. +$! +$ IF (P3.EQS."") +$ THEN +$! +$! O.K., The User Didn't Specify A Compiler, Let's Try To +$! Find Out Which One To Use. +$! +$! Check To See If We Have GNU C. +$! +$ IF (F$TRNLNM("GNU_CC").NES."") +$ THEN +$! +$! Looks Like GNUC, Set To Use GNUC. +$! +$ P3 = "GNUC" +$! +$! End The GNU C Compiler Check. +$! +$ ELSE +$! +$! Check To See If We Have VAXC Or DECC. +$! +$ IF (ARCH.NES."VAX").OR.(F$TRNLNM("DECC$CC_DEFAULT").NES."") +$ THEN +$! +$! Looks Like DECC, Set To Use DECC. +$! +$ P3 = "DECC" +$! +$! Else... +$! +$ ELSE +$! +$! Looks Like VAXC, Set To Use VAXC. +$! +$ P3 = "VAXC" +$! +$! End The VAXC Compiler Check. +$! +$ ENDIF +$! +$! End The DECC & VAXC Compiler Check. +$! +$ ENDIF +$! +$! End The Compiler Check. +$! +$ ENDIF +$! +$! Check To See If We Have A Option For P4. +$! +$ IF (P4.EQS."") +$ THEN +$! +$! Find out what socket library we have available +$! +$ IF F$PARSE("SOCKETSHR:") .NES. "" +$ THEN +$! +$! We have SOCKETSHR, and it is my opinion that it's the best to use. +$! +$ P4 = "SOCKETSHR" +$! +$! Tell the user +$! +$ WRITE SYS$OUTPUT "Using SOCKETSHR for TCP/IP" +$! +$! Else, let's look for something else +$! +$ ELSE +$! +$! Like UCX (the reason to do this before Multinet is that the UCX +$! emulation is easier to use...) +$! +$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" - + .OR. F$PARSE("SYS$SHARE:UCX$IPC_SHR.EXE") .NES. "" - + .OR. F$PARSE("SYS$LIBRARY:UCX$IPC.OLB") .NES. "" +$ THEN +$! +$! Last resort: a UCX or UCX-compatible library +$! +$ P4 = "UCX" +$! +$! Tell the user +$! +$ WRITE SYS$OUTPUT "Using UCX or an emulation thereof for TCP/IP" +$! +$! That was all... +$! +$ ENDIF +$ ENDIF +$ ENDIF +$! +$! Set Up Initial CC Definitions, Possibly With User Ones +$! +$ CCDEFS = "TCPIP_TYPE_''P4'" +$ IF F$TYPE(USER_CCDEFS) .NES. "" THEN CCDEFS = CCDEFS + "," + USER_CCDEFS +$ CCEXTRAFLAGS = "" +$ IF F$TYPE(USER_CCFLAGS) .NES. "" THEN CCEXTRAFLAGS = USER_CCFLAGS +$ CCDISABLEWARNINGS = "" !!! "MAYLOSEDATA3" !!! "LONGLONGTYPE,LONGLONGSUFX,FOUNDCR" +$ IF F$TYPE(USER_CCDISABLEWARNINGS) .NES. "" +$ THEN +$ IF CCDISABLEWARNINGS .NES. "" THEN CCDISABLEWARNINGS = CCDISABLEWARNINGS + "," +$ CCDISABLEWARNINGS = CCDISABLEWARNINGS + USER_CCDISABLEWARNINGS +$ ENDIF +$! +$! Check To See If We Have A ZLIB Option. +$! +$ ZLIB = P7 +$ IF (ZLIB .NES. "") +$ THEN +$! +$! Check for expected ZLIB files. +$! +$ err = 0 +$ file1 = f$parse( "zlib.h", ZLIB, , , "SYNTAX_ONLY") +$ if (f$search( file1) .eqs. "") +$ then +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid." +$ WRITE SYS$OUTPUT " Can't find header: ''file1'" +$ err = 1 +$ endif +$ file1 = f$parse( "A.;", ZLIB)- "A.;" +$! +$ file2 = f$parse( ZLIB, "libz.olb", , , "SYNTAX_ONLY") +$ if (f$search( file2) .eqs. "") +$ then +$ if (err .eq. 0) +$ then +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ", ZLIB, " Is Invalid." +$ endif +$ WRITE SYS$OUTPUT " Can't find library: ''file2'" +$ WRITE SYS$OUTPUT "" +$ err = err+ 2 +$ endif +$ if (err .eq. 1) +$ then +$ WRITE SYS$OUTPUT "" +$ endif +$! +$ if (err .ne. 0) +$ then +$ EXIT +$ endif +$! +$ CCDEFS = """ZLIB=1"", "+ CCDEFS +$ CC_INCLUDES = CC_INCLUDES+ ", "+ file1 +$ ZLIB_LIB = ", ''file2' /library" +$! +$! Print info +$! +$ WRITE SYS$OUTPUT "ZLIB library spec: ", file2 +$! +$! End The ZLIB Check. +$! +$ ENDIF +$! +$! Check To See If The User Entered A Valid Parameter. +$! +$ IF (P3.EQS."VAXC").OR.(P3.EQS."DECC").OR.(P3.EQS."GNUC") +$ THEN +$! +$! Check To See If The User Wanted DECC. +$! +$ IF (P3.EQS."DECC") +$ THEN +$! +$! Looks Like DECC, Set To Use DECC. +$! +$ COMPILER = "DECC" +$! +$! Tell The User We Are Using DECC. +$! +$ WRITE SYS$OUTPUT "Using DECC 'C' Compiler." +$! +$! Use DECC... +$! +$ CC = "CC" +$ IF ARCH.EQS."VAX" .AND. F$TRNLNM("DECC$CC_DEFAULT").NES."/DECC" - + THEN CC = "CC/DECC" +$ CC = CC + " /''CC_OPTIMIZE' /''DEBUGGER' /STANDARD=RELAXED"+ - + "''POINTER_SIZE' /NOLIST /PREFIX=ALL" + - + " /INCLUDE=(''CC_INCLUDES') " + CCEXTRAFLAGS +$! +$! Define The Linker Options File Name. +$! +$ OPT_FILE = "VAX_DECC_OPTIONS.OPT" +$! +$! End DECC Check. +$! +$ ENDIF +$! +$! Check To See If We Are To Use VAXC. +$! +$ IF (P3.EQS."VAXC") +$ THEN +$! +$! Looks Like VAXC, Set To Use VAXC. +$! +$ COMPILER = "VAXC" +$! +$! Tell The User We Are Using VAX C. +$! +$ WRITE SYS$OUTPUT "Using VAXC 'C' Compiler." +$! +$! Compile Using VAXC. +$! +$ CC = "CC" +$ IF ARCH.NES."VAX" +$ THEN +$ WRITE SYS$OUTPUT "There is no VAX C on ''ARCH'!" +$ EXIT +$ ENDIF +$ IF F$TRNLNM("DECC$CC_DEFAULT").EQS."/DECC" THEN CC = "CC/VAXC" +$ CC = CC + "/''CC_OPTIMIZE'/''DEBUGGER'/NOLIST" + - + "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS +$ CCDEFS = CCDEFS + ",""VAXC""" +$! +$! Define As SYS$COMMON:[SYSLIB] +$! +$ DEFINE/NOLOG SYS SYS$COMMON:[SYSLIB] +$! +$! Define The Linker Options File Name. +$! +$ OPT_FILE = "VAX_VAXC_OPTIONS.OPT" +$! +$! End VAXC Check +$! +$ ENDIF +$! +$! Check To See If We Are To Use GNU C. +$! +$ IF (P3.EQS."GNUC") +$ THEN +$! +$! Looks Like GNUC, Set To Use GNUC. +$! +$ COMPILER = "GNUC" +$! +$! Tell The User We Are Using GNUC. +$! +$ WRITE SYS$OUTPUT "Using GNU 'C' Compiler." +$! +$! Use GNU C... +$! +$ IF F$TYPE(GCC) .EQS. "" THEN GCC := GCC +$ CC = GCC+"/NOCASE_HACK/''GCC_OPTIMIZE'/''DEBUGGER'/NOLIST" + - + "/INCLUDE=(''CC_INCLUDES')" + CCEXTRAFLAGS +$! +$! Define The Linker Options File Name. +$! +$ OPT_FILE = "VAX_GNUC_OPTIONS.OPT" +$! +$! End The GNU C Check. +$! +$ ENDIF +$! +$! Set up default defines +$! +$ CCDEFS = """FLAT_INC=1""," + CCDEFS +$! +$! Finish up the definition of CC. +$! +$ IF COMPILER .EQS. "DECC" +$ THEN +$! Not all compiler versions support MAYLOSEDATA3. +$ OPT_TEST = "MAYLOSEDATA3" +$ DEFINE /USER_MODE SYS$ERROR NL: +$ DEFINE /USER_MODE SYS$OUTPUT NL: +$ 'CC' /NOCROSS_REFERENCE /NOLIST /NOOBJECT - + /WARNINGS = DISABLE = ('OPT_TEST', EMPTYFILE) NL: +$ IF ($SEVERITY) +$ THEN +$ IF CCDISABLEWARNINGS .NES. "" THEN - + CCDISABLEWARNINGS = CCDISABLEWARNINGS+ "," +$ CCDISABLEWARNINGS = CCDISABLEWARNINGS+ OPT_TEST +$ ENDIF +$ IF CCDISABLEWARNINGS .EQS. "" +$ THEN +$ CC4DISABLEWARNINGS = "DOLLARID" +$ ELSE +$ CC4DISABLEWARNINGS = CCDISABLEWARNINGS + ",DOLLARID" +$ CCDISABLEWARNINGS = " /WARNING=(DISABLE=(" + CCDISABLEWARNINGS + "))" +$ ENDIF +$ CC4DISABLEWARNINGS = " /WARNING=(DISABLE=(" + CC4DISABLEWARNINGS + "))" +$ ELSE +$ CCDISABLEWARNINGS = "" +$ CC4DISABLEWARNINGS = "" +$ ENDIF +$ CC2 = CC + " /DEFINE=(" + CCDEFS + ",_POSIX_C_SOURCE)" + CCDISABLEWARNINGS +$ CC3 = CC + " /DEFINE=(" + CCDEFS + ISSEVEN + ")" + CCDISABLEWARNINGS +$ CC = CC + " /DEFINE=(" + CCDEFS + ")" + CCDISABLEWARNINGS +$ IF COMPILER .EQS. "DECC" +$ THEN +$ CC4 = CC - CCDISABLEWARNINGS + CC4DISABLEWARNINGS +$ CC5 = CC3 - CCDISABLEWARNINGS + CC4DISABLEWARNINGS +$ ELSE +$ CC4 = CC +$ CC5 = CC3 +$ ENDIF +$! +$! Show user the result +$! +$ WRITE/SYMBOL SYS$OUTPUT "Main Compiling Command: ",CC +$! +$! Else The User Entered An Invalid Argument. +$! +$ ELSE +$! +$! Tell The User We Don't Know What They Want. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P3," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " VAXC : To Compile With VAX C." +$ WRITE SYS$OUTPUT " DECC : To Compile With DEC C." +$ WRITE SYS$OUTPUT " GNUC : To Compile With GNU C." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$ ENDIF +$! +$! Time to check the contents, and to make sure we get the correct library. +$! +$ IF P4.EQS."SOCKETSHR" .OR. P4.EQS."MULTINET" .OR. P4.EQS."UCX" - + .OR. P4.EQS."TCPIP" .OR. P4.EQS."NONE" +$ THEN +$! +$! Check to see if SOCKETSHR was chosen +$! +$ IF P4.EQS."SOCKETSHR" +$ THEN +$! +$! Set the library to use SOCKETSHR +$! +$ TCPIP_LIB = ",SYS$DISK:[-.VMS]SOCKETSHR_SHR.OPT /OPTIONS" +$! +$! Done with SOCKETSHR +$! +$ ENDIF +$! +$! Check to see if MULTINET was chosen +$! +$ IF P4.EQS."MULTINET" +$ THEN +$! +$! Set the library to use UCX emulation. +$! +$ P4 = "UCX" +$! +$! Done with MULTINET +$! +$ ENDIF +$! +$! Check to see if UCX was chosen +$! +$ IF P4.EQS."UCX" +$ THEN +$! +$! Set the library to use UCX. +$! +$ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC.OPT /OPTIONS" +$ IF F$TRNLNM("UCX$IPC_SHR") .NES. "" +$ THEN +$ TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_DECC_LOG.OPT /OPTIONS" +$ ELSE +$ IF COMPILER .NES. "DECC" .AND. ARCH .EQS. "VAX" THEN - + TCPIP_LIB = ",SYS$DISK:[-.VMS]UCX_SHR_VAXC.OPT /OPTIONS" +$ ENDIF +$! +$! Done with UCX +$! +$ ENDIF +$! +$! Check to see if TCPIP was chosen +$! +$ IF P4.EQS."TCPIP" +$ THEN +$! +$! Set the library to use TCPIP (post UCX). +$! +$ TCPIP_LIB = ",SYS$DISK:[-.VMS]TCPIP_SHR_DECC.OPT /OPTIONS" +$! +$! Done with TCPIP +$! +$ ENDIF +$! +$! Check to see if NONE was chosen +$! +$ IF P4.EQS."NONE" +$ THEN +$! +$! Do not use a TCPIP library. +$! +$ TCPIP_LIB = "" +$! +$! Done with NONE +$! +$ ENDIF +$! +$! Print info +$! +$ WRITE SYS$OUTPUT "TCP/IP library spec: ", TCPIP_LIB- "," +$! +$! Else The User Entered An Invalid Argument. +$! +$ ELSE +$! +$! Tell The User We Don't Know What They Want. +$! +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT "The Option ",P4," Is Invalid. The Valid Options Are:" +$ WRITE SYS$OUTPUT "" +$ WRITE SYS$OUTPUT " SOCKETSHR : To link with SOCKETSHR TCP/IP library." +$ WRITE SYS$OUTPUT " UCX : To link with UCX TCP/IP library." +$ WRITE SYS$OUTPUT " TCPIP : To link with TCPIP (post UCX) TCP/IP library." +$ WRITE SYS$OUTPUT "" +$! +$! Time To EXIT. +$! +$ EXIT +$! +$! Done with TCP/IP libraries +$! +$ ENDIF +$! +$! Time To RETURN... +$! +$ RETURN +$! +$ INITIALISE: +$! +$! Save old value of the logical name OPENSSL +$! +$ __SAVE_OPENSSL = F$TRNLNM("OPENSSL","LNM$PROCESS_TABLE") +$! +$! Save directory information +$! +$ __HERE = F$PARSE(F$PARSE("A.;",F$ENVIRONMENT("PROCEDURE"))-"A.;","[]A.;") - "A.;" +$ __HERE = F$EDIT(__HERE,"UPCASE") +$ __TOP = __HERE - "SSL]" +$ __INCLUDE = __TOP + "INCLUDE.OPENSSL]" +$! +$! Set up the logical name OPENSSL to point at the include directory +$! +$ DEFINE OPENSSL/NOLOG '__INCLUDE' +$! +$! Done +$! +$ RETURN +$! +$ CLEANUP: +$! +$! Restore the logical name OPENSSL if it had a value +$! +$ IF __SAVE_OPENSSL .EQS. "" +$ THEN +$ DEASSIGN OPENSSL +$ ELSE +$ DEFINE/NOLOG OPENSSL '__SAVE_OPENSSL' +$ ENDIF +$! +$! Done +$! +$ RETURN diff --git a/libs/openssl/ssl/ssl_algs.c b/libs/openssl/ssl/ssl_algs.c new file mode 100644 index 00000000..151422ae --- /dev/null +++ b/libs/openssl/ssl/ssl_algs.c @@ -0,0 +1,151 @@ +/* ssl/ssl_algs.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include +#include "ssl_locl.h" + +int SSL_library_init(void) +{ + +#ifndef OPENSSL_NO_DES + EVP_add_cipher(EVP_des_cbc()); + EVP_add_cipher(EVP_des_ede3_cbc()); +#endif +#ifndef OPENSSL_NO_IDEA + EVP_add_cipher(EVP_idea_cbc()); +#endif +#ifndef OPENSSL_NO_RC4 + EVP_add_cipher(EVP_rc4()); +# if !defined(OPENSSL_NO_MD5) && (defined(__x86_64) || defined(__x86_64__)) + EVP_add_cipher(EVP_rc4_hmac_md5()); +# endif +#endif +#ifndef OPENSSL_NO_RC2 + EVP_add_cipher(EVP_rc2_cbc()); + /* + * Not actually used for SSL/TLS but this makes PKCS#12 work if an + * application only calls SSL_library_init(). + */ + EVP_add_cipher(EVP_rc2_40_cbc()); +#endif +#ifndef OPENSSL_NO_AES + EVP_add_cipher(EVP_aes_128_cbc()); + EVP_add_cipher(EVP_aes_192_cbc()); + EVP_add_cipher(EVP_aes_256_cbc()); + EVP_add_cipher(EVP_aes_128_gcm()); + EVP_add_cipher(EVP_aes_256_gcm()); +# if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1) + EVP_add_cipher(EVP_aes_128_cbc_hmac_sha1()); + EVP_add_cipher(EVP_aes_256_cbc_hmac_sha1()); +# endif + +#endif +#ifndef OPENSSL_NO_CAMELLIA + EVP_add_cipher(EVP_camellia_128_cbc()); + EVP_add_cipher(EVP_camellia_256_cbc()); +#endif + +#ifndef OPENSSL_NO_SEED + EVP_add_cipher(EVP_seed_cbc()); +#endif + +#ifndef OPENSSL_NO_MD5 + EVP_add_digest(EVP_md5()); + EVP_add_digest_alias(SN_md5, "ssl2-md5"); + EVP_add_digest_alias(SN_md5, "ssl3-md5"); +#endif +#ifndef OPENSSL_NO_SHA + EVP_add_digest(EVP_sha1()); /* RSA with sha1 */ + EVP_add_digest_alias(SN_sha1, "ssl3-sha1"); + EVP_add_digest_alias(SN_sha1WithRSAEncryption, SN_sha1WithRSA); +#endif +#ifndef OPENSSL_NO_SHA256 + EVP_add_digest(EVP_sha224()); + EVP_add_digest(EVP_sha256()); +#endif +#ifndef OPENSSL_NO_SHA512 + EVP_add_digest(EVP_sha384()); + EVP_add_digest(EVP_sha512()); +#endif +#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_DSA) + EVP_add_digest(EVP_dss1()); /* DSA with sha1 */ + EVP_add_digest_alias(SN_dsaWithSHA1, SN_dsaWithSHA1_2); + EVP_add_digest_alias(SN_dsaWithSHA1, "DSS1"); + EVP_add_digest_alias(SN_dsaWithSHA1, "dss1"); +#endif +#ifndef OPENSSL_NO_ECDSA + EVP_add_digest(EVP_ecdsa()); +#endif + /* If you want support for phased out ciphers, add the following */ +#if 0 + EVP_add_digest(EVP_sha()); + EVP_add_digest(EVP_dss()); +#endif +#ifndef OPENSSL_NO_COMP + /* + * This will initialise the built-in compression algorithms. The value + * returned is a STACK_OF(SSL_COMP), but that can be discarded safely + */ + (void)SSL_COMP_get_compression_methods(); +#endif + /* initialize cipher/digest methods table */ + ssl_load_ciphers(); + return (1); +} diff --git a/libs/openssl/ssl/ssl_asn1.c b/libs/openssl/ssl/ssl_asn1.c new file mode 100644 index 00000000..35cc27c5 --- /dev/null +++ b/libs/openssl/ssl/ssl_asn1.c @@ -0,0 +1,636 @@ +/* ssl/ssl_asn1.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include +#include "ssl_locl.h" +#include +#include +#include + +typedef struct ssl_session_asn1_st { + ASN1_INTEGER version; + ASN1_INTEGER ssl_version; + ASN1_OCTET_STRING cipher; + ASN1_OCTET_STRING comp_id; + ASN1_OCTET_STRING master_key; + ASN1_OCTET_STRING session_id; + ASN1_OCTET_STRING session_id_context; + ASN1_OCTET_STRING key_arg; +#ifndef OPENSSL_NO_KRB5 + ASN1_OCTET_STRING krb5_princ; +#endif /* OPENSSL_NO_KRB5 */ + ASN1_INTEGER time; + ASN1_INTEGER timeout; + ASN1_INTEGER verify_result; +#ifndef OPENSSL_NO_TLSEXT + ASN1_OCTET_STRING tlsext_hostname; + ASN1_INTEGER tlsext_tick_lifetime; + ASN1_OCTET_STRING tlsext_tick; +#endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_PSK + ASN1_OCTET_STRING psk_identity_hint; + ASN1_OCTET_STRING psk_identity; +#endif /* OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + ASN1_OCTET_STRING srp_username; +#endif /* OPENSSL_NO_SRP */ +} SSL_SESSION_ASN1; + +int i2d_SSL_SESSION(SSL_SESSION *in, unsigned char **pp) +{ +#define LSIZE2 (sizeof(long)*2) + int v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0; + unsigned char buf[4], ibuf1[LSIZE2], ibuf2[LSIZE2]; + unsigned char ibuf3[LSIZE2], ibuf4[LSIZE2], ibuf5[LSIZE2]; +#ifndef OPENSSL_NO_TLSEXT + int v6 = 0, v9 = 0, v10 = 0; + unsigned char ibuf6[LSIZE2]; +#endif +#ifndef OPENSSL_NO_PSK + int v7 = 0, v8 = 0; +#endif +#ifndef OPENSSL_NO_COMP + unsigned char cbuf; + int v11 = 0; +#endif +#ifndef OPENSSL_NO_SRP + int v12 = 0; +#endif + long l; + SSL_SESSION_ASN1 a; + M_ASN1_I2D_vars(in); + + if ((in == NULL) || ((in->cipher == NULL) && (in->cipher_id == 0))) + return (0); + + /* + * Note that I cheat in the following 2 assignments. I know that if the + * ASN1_INTEGER passed to ASN1_INTEGER_set is > sizeof(long)+1, the + * buffer will not be re-OPENSSL_malloc()ed. This is a bit evil but makes + * things simple, no dynamic allocation to clean up :-) + */ + a.version.length = LSIZE2; + a.version.type = V_ASN1_INTEGER; + a.version.data = ibuf1; + ASN1_INTEGER_set(&(a.version), SSL_SESSION_ASN1_VERSION); + + a.ssl_version.length = LSIZE2; + a.ssl_version.type = V_ASN1_INTEGER; + a.ssl_version.data = ibuf2; + ASN1_INTEGER_set(&(a.ssl_version), in->ssl_version); + + a.cipher.type = V_ASN1_OCTET_STRING; + a.cipher.data = buf; + + if (in->cipher == NULL) + l = in->cipher_id; + else + l = in->cipher->id; + if (in->ssl_version == SSL2_VERSION) { + a.cipher.length = 3; + buf[0] = ((unsigned char)(l >> 16L)) & 0xff; + buf[1] = ((unsigned char)(l >> 8L)) & 0xff; + buf[2] = ((unsigned char)(l)) & 0xff; + } else { + a.cipher.length = 2; + buf[0] = ((unsigned char)(l >> 8L)) & 0xff; + buf[1] = ((unsigned char)(l)) & 0xff; + } + +#ifndef OPENSSL_NO_COMP + if (in->compress_meth) { + cbuf = (unsigned char)in->compress_meth; + a.comp_id.length = 1; + a.comp_id.type = V_ASN1_OCTET_STRING; + a.comp_id.data = &cbuf; + } +#endif + + a.master_key.length = in->master_key_length; + a.master_key.type = V_ASN1_OCTET_STRING; + a.master_key.data = in->master_key; + + a.session_id.length = in->session_id_length; + a.session_id.type = V_ASN1_OCTET_STRING; + a.session_id.data = in->session_id; + + a.session_id_context.length = in->sid_ctx_length; + a.session_id_context.type = V_ASN1_OCTET_STRING; + a.session_id_context.data = in->sid_ctx; + + a.key_arg.length = in->key_arg_length; + a.key_arg.type = V_ASN1_OCTET_STRING; + a.key_arg.data = in->key_arg; + +#ifndef OPENSSL_NO_KRB5 + if (in->krb5_client_princ_len) { + a.krb5_princ.length = in->krb5_client_princ_len; + a.krb5_princ.type = V_ASN1_OCTET_STRING; + a.krb5_princ.data = in->krb5_client_princ; + } +#endif /* OPENSSL_NO_KRB5 */ + + if (in->time != 0L) { + a.time.length = LSIZE2; + a.time.type = V_ASN1_INTEGER; + a.time.data = ibuf3; + ASN1_INTEGER_set(&(a.time), in->time); + } + + if (in->timeout != 0L) { + a.timeout.length = LSIZE2; + a.timeout.type = V_ASN1_INTEGER; + a.timeout.data = ibuf4; + ASN1_INTEGER_set(&(a.timeout), in->timeout); + } + + if (in->verify_result != X509_V_OK) { + a.verify_result.length = LSIZE2; + a.verify_result.type = V_ASN1_INTEGER; + a.verify_result.data = ibuf5; + ASN1_INTEGER_set(&a.verify_result, in->verify_result); + } +#ifndef OPENSSL_NO_TLSEXT + if (in->tlsext_hostname) { + a.tlsext_hostname.length = strlen(in->tlsext_hostname); + a.tlsext_hostname.type = V_ASN1_OCTET_STRING; + a.tlsext_hostname.data = (unsigned char *)in->tlsext_hostname; + } + if (in->tlsext_tick) { + a.tlsext_tick.length = in->tlsext_ticklen; + a.tlsext_tick.type = V_ASN1_OCTET_STRING; + a.tlsext_tick.data = (unsigned char *)in->tlsext_tick; + } + if (in->tlsext_tick_lifetime_hint > 0) { + a.tlsext_tick_lifetime.length = LSIZE2; + a.tlsext_tick_lifetime.type = V_ASN1_INTEGER; + a.tlsext_tick_lifetime.data = ibuf6; + ASN1_INTEGER_set(&a.tlsext_tick_lifetime, + in->tlsext_tick_lifetime_hint); + } +#endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_PSK + if (in->psk_identity_hint) { + a.psk_identity_hint.length = strlen(in->psk_identity_hint); + a.psk_identity_hint.type = V_ASN1_OCTET_STRING; + a.psk_identity_hint.data = (unsigned char *)(in->psk_identity_hint); + } + if (in->psk_identity) { + a.psk_identity.length = strlen(in->psk_identity); + a.psk_identity.type = V_ASN1_OCTET_STRING; + a.psk_identity.data = (unsigned char *)(in->psk_identity); + } +#endif /* OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + if (in->srp_username) { + a.srp_username.length = strlen(in->srp_username); + a.srp_username.type = V_ASN1_OCTET_STRING; + a.srp_username.data = (unsigned char *)(in->srp_username); + } +#endif /* OPENSSL_NO_SRP */ + + M_ASN1_I2D_len(&(a.version), i2d_ASN1_INTEGER); + M_ASN1_I2D_len(&(a.ssl_version), i2d_ASN1_INTEGER); + M_ASN1_I2D_len(&(a.cipher), i2d_ASN1_OCTET_STRING); + M_ASN1_I2D_len(&(a.session_id), i2d_ASN1_OCTET_STRING); + M_ASN1_I2D_len(&(a.master_key), i2d_ASN1_OCTET_STRING); +#ifndef OPENSSL_NO_KRB5 + if (in->krb5_client_princ_len) + M_ASN1_I2D_len(&(a.krb5_princ), i2d_ASN1_OCTET_STRING); +#endif /* OPENSSL_NO_KRB5 */ + if (in->key_arg_length > 0) + M_ASN1_I2D_len_IMP_opt(&(a.key_arg), i2d_ASN1_OCTET_STRING); + if (in->time != 0L) + M_ASN1_I2D_len_EXP_opt(&(a.time), i2d_ASN1_INTEGER, 1, v1); + if (in->timeout != 0L) + M_ASN1_I2D_len_EXP_opt(&(a.timeout), i2d_ASN1_INTEGER, 2, v2); + if (in->peer != NULL) + M_ASN1_I2D_len_EXP_opt(in->peer, i2d_X509, 3, v3); + M_ASN1_I2D_len_EXP_opt(&a.session_id_context, i2d_ASN1_OCTET_STRING, 4, + v4); + if (in->verify_result != X509_V_OK) + M_ASN1_I2D_len_EXP_opt(&(a.verify_result), i2d_ASN1_INTEGER, 5, v5); + +#ifndef OPENSSL_NO_TLSEXT + if (in->tlsext_tick_lifetime_hint > 0) + M_ASN1_I2D_len_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER, 9, + v9); + if (in->tlsext_tick) + M_ASN1_I2D_len_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING, 10, + v10); + if (in->tlsext_hostname) + M_ASN1_I2D_len_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING, 6, + v6); +# ifndef OPENSSL_NO_COMP + if (in->compress_meth) + M_ASN1_I2D_len_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING, 11, v11); +# endif +#endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_PSK + if (in->psk_identity_hint) + M_ASN1_I2D_len_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING, + 7, v7); + if (in->psk_identity) + M_ASN1_I2D_len_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING, 8, + v8); +#endif /* OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + if (in->srp_username) + M_ASN1_I2D_len_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING, 12, + v12); +#endif /* OPENSSL_NO_SRP */ + + M_ASN1_I2D_seq_total(); + + M_ASN1_I2D_put(&(a.version), i2d_ASN1_INTEGER); + M_ASN1_I2D_put(&(a.ssl_version), i2d_ASN1_INTEGER); + M_ASN1_I2D_put(&(a.cipher), i2d_ASN1_OCTET_STRING); + M_ASN1_I2D_put(&(a.session_id), i2d_ASN1_OCTET_STRING); + M_ASN1_I2D_put(&(a.master_key), i2d_ASN1_OCTET_STRING); +#ifndef OPENSSL_NO_KRB5 + if (in->krb5_client_princ_len) + M_ASN1_I2D_put(&(a.krb5_princ), i2d_ASN1_OCTET_STRING); +#endif /* OPENSSL_NO_KRB5 */ + if (in->key_arg_length > 0) + M_ASN1_I2D_put_IMP_opt(&(a.key_arg), i2d_ASN1_OCTET_STRING, 0); + if (in->time != 0L) + M_ASN1_I2D_put_EXP_opt(&(a.time), i2d_ASN1_INTEGER, 1, v1); + if (in->timeout != 0L) + M_ASN1_I2D_put_EXP_opt(&(a.timeout), i2d_ASN1_INTEGER, 2, v2); + if (in->peer != NULL) + M_ASN1_I2D_put_EXP_opt(in->peer, i2d_X509, 3, v3); + M_ASN1_I2D_put_EXP_opt(&a.session_id_context, i2d_ASN1_OCTET_STRING, 4, + v4); + if (in->verify_result != X509_V_OK) + M_ASN1_I2D_put_EXP_opt(&a.verify_result, i2d_ASN1_INTEGER, 5, v5); +#ifndef OPENSSL_NO_TLSEXT + if (in->tlsext_hostname) + M_ASN1_I2D_put_EXP_opt(&(a.tlsext_hostname), i2d_ASN1_OCTET_STRING, 6, + v6); +#endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_PSK + if (in->psk_identity_hint) + M_ASN1_I2D_put_EXP_opt(&(a.psk_identity_hint), i2d_ASN1_OCTET_STRING, + 7, v7); + if (in->psk_identity) + M_ASN1_I2D_put_EXP_opt(&(a.psk_identity), i2d_ASN1_OCTET_STRING, 8, + v8); +#endif /* OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_TLSEXT + if (in->tlsext_tick_lifetime_hint > 0) + M_ASN1_I2D_put_EXP_opt(&a.tlsext_tick_lifetime, i2d_ASN1_INTEGER, 9, + v9); + if (in->tlsext_tick) + M_ASN1_I2D_put_EXP_opt(&(a.tlsext_tick), i2d_ASN1_OCTET_STRING, 10, + v10); +#endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_COMP + if (in->compress_meth) + M_ASN1_I2D_put_EXP_opt(&(a.comp_id), i2d_ASN1_OCTET_STRING, 11, v11); +#endif +#ifndef OPENSSL_NO_SRP + if (in->srp_username) + M_ASN1_I2D_put_EXP_opt(&(a.srp_username), i2d_ASN1_OCTET_STRING, 12, + v12); +#endif /* OPENSSL_NO_SRP */ + M_ASN1_I2D_finish(); +} + +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const unsigned char **pp, + long length) +{ + int ssl_version = 0, i; + long id; + ASN1_INTEGER ai, *aip; + ASN1_OCTET_STRING os, *osp; + M_ASN1_D2I_vars(a, SSL_SESSION *, SSL_SESSION_new); + + aip = &ai; + osp = &os; + + M_ASN1_D2I_Init(); + M_ASN1_D2I_start_sequence(); + + ai.data = NULL; + ai.length = 0; + M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER); + if (ai.data != NULL) { + OPENSSL_free(ai.data); + ai.data = NULL; + ai.length = 0; + } + + /* we don't care about the version right now :-) */ + M_ASN1_D2I_get_x(ASN1_INTEGER, aip, d2i_ASN1_INTEGER); + ssl_version = (int)ASN1_INTEGER_get(aip); + ret->ssl_version = ssl_version; + if (ai.data != NULL) { + OPENSSL_free(ai.data); + ai.data = NULL; + ai.length = 0; + } + + os.data = NULL; + os.length = 0; + M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING); + if (ssl_version == SSL2_VERSION) { + if (os.length != 3) { + c.error = SSL_R_CIPHER_CODE_WRONG_LENGTH; + c.line = __LINE__; + goto err; + } + id = 0x02000000L | + ((unsigned long)os.data[0] << 16L) | + ((unsigned long)os.data[1] << 8L) | (unsigned long)os.data[2]; + } else if ((ssl_version >> 8) == SSL3_VERSION_MAJOR + || (ssl_version >> 8) == DTLS1_VERSION_MAJOR + || ssl_version == DTLS1_BAD_VER) { + if (os.length != 2) { + c.error = SSL_R_CIPHER_CODE_WRONG_LENGTH; + c.line = __LINE__; + goto err; + } + id = 0x03000000L | + ((unsigned long)os.data[0] << 8L) | (unsigned long)os.data[1]; + } else { + c.error = SSL_R_UNKNOWN_SSL_VERSION; + c.line = __LINE__; + goto err; + } + + ret->cipher = NULL; + ret->cipher_id = id; + + M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING); + if ((ssl_version >> 8) >= SSL3_VERSION_MAJOR) + i = SSL3_MAX_SSL_SESSION_ID_LENGTH; + else /* if (ssl_version>>8 == SSL2_VERSION_MAJOR) */ + i = SSL2_MAX_SSL_SESSION_ID_LENGTH; + + if (os.length > i) + os.length = i; + if (os.length > (int)sizeof(ret->session_id)) /* can't happen */ + os.length = sizeof(ret->session_id); + + ret->session_id_length = os.length; + OPENSSL_assert(os.length <= (int)sizeof(ret->session_id)); + memcpy(ret->session_id, os.data, os.length); + + M_ASN1_D2I_get_x(ASN1_OCTET_STRING, osp, d2i_ASN1_OCTET_STRING); + if (os.length > SSL_MAX_MASTER_KEY_LENGTH) + ret->master_key_length = SSL_MAX_MASTER_KEY_LENGTH; + else + ret->master_key_length = os.length; + memcpy(ret->master_key, os.data, ret->master_key_length); + + os.length = 0; + +#ifndef OPENSSL_NO_KRB5 + os.length = 0; + M_ASN1_D2I_get_opt(osp, d2i_ASN1_OCTET_STRING, V_ASN1_OCTET_STRING); + if (os.data) { + if (os.length > SSL_MAX_KRB5_PRINCIPAL_LENGTH) + ret->krb5_client_princ_len = 0; + else + ret->krb5_client_princ_len = os.length; + memcpy(ret->krb5_client_princ, os.data, ret->krb5_client_princ_len); + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } else + ret->krb5_client_princ_len = 0; +#endif /* OPENSSL_NO_KRB5 */ + + M_ASN1_D2I_get_IMP_opt(osp, d2i_ASN1_OCTET_STRING, 0, + V_ASN1_OCTET_STRING); + if (os.length > SSL_MAX_KEY_ARG_LENGTH) + ret->key_arg_length = SSL_MAX_KEY_ARG_LENGTH; + else + ret->key_arg_length = os.length; + memcpy(ret->key_arg, os.data, ret->key_arg_length); + if (os.data != NULL) + OPENSSL_free(os.data); + + ai.length = 0; + M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 1); + if (ai.data != NULL) { + ret->time = ASN1_INTEGER_get(aip); + OPENSSL_free(ai.data); + ai.data = NULL; + ai.length = 0; + } else + ret->time = (unsigned long)time(NULL); + + ai.length = 0; + M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 2); + if (ai.data != NULL) { + ret->timeout = ASN1_INTEGER_get(aip); + OPENSSL_free(ai.data); + ai.data = NULL; + ai.length = 0; + } else + ret->timeout = 3; + + if (ret->peer != NULL) { + X509_free(ret->peer); + ret->peer = NULL; + } + M_ASN1_D2I_get_EXP_opt(ret->peer, d2i_X509, 3); + + os.length = 0; + os.data = NULL; + M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 4); + + if (os.data != NULL) { + if (os.length > SSL_MAX_SID_CTX_LENGTH) { + c.error = SSL_R_BAD_LENGTH; + c.line = __LINE__; + goto err; + } else { + ret->sid_ctx_length = os.length; + memcpy(ret->sid_ctx, os.data, os.length); + } + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } else + ret->sid_ctx_length = 0; + + ai.length = 0; + M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 5); + if (ai.data != NULL) { + ret->verify_result = ASN1_INTEGER_get(aip); + OPENSSL_free(ai.data); + ai.data = NULL; + ai.length = 0; + } else + ret->verify_result = X509_V_OK; + +#ifndef OPENSSL_NO_TLSEXT + os.length = 0; + os.data = NULL; + M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 6); + if (os.data) { + ret->tlsext_hostname = BUF_strndup((char *)os.data, os.length); + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } else + ret->tlsext_hostname = NULL; +#endif /* OPENSSL_NO_TLSEXT */ + +#ifndef OPENSSL_NO_PSK + os.length = 0; + os.data = NULL; + M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 7); + if (os.data) { + ret->psk_identity_hint = BUF_strndup((char *)os.data, os.length); + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } else + ret->psk_identity_hint = NULL; + + os.length = 0; + os.data = NULL; + M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 8); + if (os.data) { + ret->psk_identity = BUF_strndup((char *)os.data, os.length); + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } else + ret->psk_identity = NULL; +#endif /* OPENSSL_NO_PSK */ + +#ifndef OPENSSL_NO_TLSEXT + ai.length = 0; + M_ASN1_D2I_get_EXP_opt(aip, d2i_ASN1_INTEGER, 9); + if (ai.data != NULL) { + ret->tlsext_tick_lifetime_hint = ASN1_INTEGER_get(aip); + OPENSSL_free(ai.data); + ai.data = NULL; + ai.length = 0; + } else if (ret->tlsext_ticklen && ret->session_id_length) + ret->tlsext_tick_lifetime_hint = -1; + else + ret->tlsext_tick_lifetime_hint = 0; + os.length = 0; + os.data = NULL; + M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 10); + if (os.data) { + ret->tlsext_tick = os.data; + ret->tlsext_ticklen = os.length; + os.data = NULL; + os.length = 0; + } else + ret->tlsext_tick = NULL; +#endif /* OPENSSL_NO_TLSEXT */ +#ifndef OPENSSL_NO_COMP + os.length = 0; + os.data = NULL; + M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 11); + if (os.data) { + ret->compress_meth = os.data[0]; + OPENSSL_free(os.data); + os.data = NULL; + } +#endif + +#ifndef OPENSSL_NO_SRP + os.length = 0; + os.data = NULL; + M_ASN1_D2I_get_EXP_opt(osp, d2i_ASN1_OCTET_STRING, 12); + if (os.data) { + ret->srp_username = BUF_strndup((char *)os.data, os.length); + OPENSSL_free(os.data); + os.data = NULL; + os.length = 0; + } else + ret->srp_username = NULL; +#endif /* OPENSSL_NO_SRP */ + + M_ASN1_D2I_Finish(a, SSL_SESSION_free, SSL_F_D2I_SSL_SESSION); +} diff --git a/libs/openssl/ssl/ssl_cert.c b/libs/openssl/ssl/ssl_cert.c new file mode 100644 index 00000000..9a4e1041 --- /dev/null +++ b/libs/openssl/ssl/ssl_cert.c @@ -0,0 +1,799 @@ +/* + * ! \file ssl/ssl_cert.c + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ + +#include + +#include "e_os.h" +#ifndef NO_SYS_TYPES_H +# include +#endif + +#include "o_dir.h" +#include +#include +#include +#include +#ifndef OPENSSL_NO_DH +# include +#endif +#include +#include "ssl_locl.h" + +int SSL_get_ex_data_X509_STORE_CTX_idx(void) +{ + static volatile int ssl_x509_store_ctx_idx = -1; + int got_write_lock = 0; + + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + + if (ssl_x509_store_ctx_idx < 0) { + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + got_write_lock = 1; + + if (ssl_x509_store_ctx_idx < 0) { + ssl_x509_store_ctx_idx = + X509_STORE_CTX_get_ex_new_index(0, "SSL for verify callback", + NULL, NULL, NULL); + } + } + + if (got_write_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + else + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + + return ssl_x509_store_ctx_idx; +} + +static void ssl_cert_set_default_md(CERT *cert) +{ + /* Set digest values to defaults */ +#ifndef OPENSSL_NO_DSA + cert->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); +#endif +#ifndef OPENSSL_NO_RSA + cert->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); + cert->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); +#endif +#ifndef OPENSSL_NO_ECDSA + cert->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); +#endif +} + +CERT *ssl_cert_new(void) +{ + CERT *ret; + + ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); + if (ret == NULL) { + SSLerr(SSL_F_SSL_CERT_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); + } + memset(ret, 0, sizeof(CERT)); + + ret->key = &(ret->pkeys[SSL_PKEY_RSA_ENC]); + ret->references = 1; + ssl_cert_set_default_md(ret); + return (ret); +} + +CERT *ssl_cert_dup(CERT *cert) +{ + CERT *ret; + int i; + + ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); + if (ret == NULL) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + memset(ret, 0, sizeof(CERT)); + + ret->references = 1; + ret->key = &ret->pkeys[cert->key - &cert->pkeys[0]]; + /* + * or ret->key = ret->pkeys + (cert->key - cert->pkeys), if you find that + * more readable + */ + + ret->valid = cert->valid; + ret->mask_k = cert->mask_k; + ret->mask_a = cert->mask_a; + ret->export_mask_k = cert->export_mask_k; + ret->export_mask_a = cert->export_mask_a; + +#ifndef OPENSSL_NO_RSA + if (cert->rsa_tmp != NULL) { + RSA_up_ref(cert->rsa_tmp); + ret->rsa_tmp = cert->rsa_tmp; + } + ret->rsa_tmp_cb = cert->rsa_tmp_cb; +#endif + +#ifndef OPENSSL_NO_DH + if (cert->dh_tmp != NULL) { + ret->dh_tmp = DHparams_dup(cert->dh_tmp); + if (ret->dh_tmp == NULL) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_DH_LIB); + goto err; + } + if (cert->dh_tmp->priv_key) { + BIGNUM *b = BN_dup(cert->dh_tmp->priv_key); + if (!b) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); + goto err; + } + ret->dh_tmp->priv_key = b; + } + if (cert->dh_tmp->pub_key) { + BIGNUM *b = BN_dup(cert->dh_tmp->pub_key); + if (!b) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_BN_LIB); + goto err; + } + ret->dh_tmp->pub_key = b; + } + } + ret->dh_tmp_cb = cert->dh_tmp_cb; +#endif + +#ifndef OPENSSL_NO_ECDH + if (cert->ecdh_tmp) { + ret->ecdh_tmp = EC_KEY_dup(cert->ecdh_tmp); + if (ret->ecdh_tmp == NULL) { + SSLerr(SSL_F_SSL_CERT_DUP, ERR_R_EC_LIB); + goto err; + } + } + ret->ecdh_tmp_cb = cert->ecdh_tmp_cb; +#endif + + for (i = 0; i < SSL_PKEY_NUM; i++) { + if (cert->pkeys[i].x509 != NULL) { + ret->pkeys[i].x509 = cert->pkeys[i].x509; + CRYPTO_add(&ret->pkeys[i].x509->references, 1, CRYPTO_LOCK_X509); + } + + if (cert->pkeys[i].privatekey != NULL) { + ret->pkeys[i].privatekey = cert->pkeys[i].privatekey; + CRYPTO_add(&ret->pkeys[i].privatekey->references, 1, + CRYPTO_LOCK_EVP_PKEY); + } + } + + /* + * ret->extra_certs *should* exist, but currently the own certificate + * chain is held inside SSL_CTX + */ + + /* + * Set digests to defaults. NB: we don't copy existing values as they + * will be set during handshake. + */ + ssl_cert_set_default_md(ret); + + return (ret); + +#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_ECDH) + err: +#endif +#ifndef OPENSSL_NO_RSA + if (ret->rsa_tmp != NULL) + RSA_free(ret->rsa_tmp); +#endif +#ifndef OPENSSL_NO_DH + if (ret->dh_tmp != NULL) + DH_free(ret->dh_tmp); +#endif +#ifndef OPENSSL_NO_ECDH + if (ret->ecdh_tmp != NULL) + EC_KEY_free(ret->ecdh_tmp); +#endif + + for (i = 0; i < SSL_PKEY_NUM; i++) { + if (ret->pkeys[i].x509 != NULL) + X509_free(ret->pkeys[i].x509); + if (ret->pkeys[i].privatekey != NULL) + EVP_PKEY_free(ret->pkeys[i].privatekey); + } + + return NULL; +} + +void ssl_cert_free(CERT *c) +{ + int i; + + if (c == NULL) + return; + + i = CRYPTO_add(&c->references, -1, CRYPTO_LOCK_SSL_CERT); +#ifdef REF_PRINT + REF_PRINT("CERT", c); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "ssl_cert_free, bad reference count\n"); + abort(); /* ok */ + } +#endif + +#ifndef OPENSSL_NO_RSA + if (c->rsa_tmp) + RSA_free(c->rsa_tmp); +#endif +#ifndef OPENSSL_NO_DH + if (c->dh_tmp) + DH_free(c->dh_tmp); +#endif +#ifndef OPENSSL_NO_ECDH + if (c->ecdh_tmp) + EC_KEY_free(c->ecdh_tmp); +#endif + + for (i = 0; i < SSL_PKEY_NUM; i++) { + if (c->pkeys[i].x509 != NULL) + X509_free(c->pkeys[i].x509); + if (c->pkeys[i].privatekey != NULL) + EVP_PKEY_free(c->pkeys[i].privatekey); +#if 0 + if (c->pkeys[i].publickey != NULL) + EVP_PKEY_free(c->pkeys[i].publickey); +#endif + } + OPENSSL_free(c); +} + +int ssl_cert_inst(CERT **o) +{ + /* + * Create a CERT if there isn't already one (which cannot really happen, + * as it is initially created in SSL_CTX_new; but the earlier code + * usually allows for that one being non-existant, so we follow that + * behaviour, as it might turn out that there actually is a reason for it + * -- but I'm not sure that *all* of the existing code could cope with + * s->cert being NULL, otherwise we could do without the initialization + * in SSL_CTX_new). + */ + + if (o == NULL) { + SSLerr(SSL_F_SSL_CERT_INST, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (*o == NULL) { + if ((*o = ssl_cert_new()) == NULL) { + SSLerr(SSL_F_SSL_CERT_INST, ERR_R_MALLOC_FAILURE); + return (0); + } + } + return (1); +} + +SESS_CERT *ssl_sess_cert_new(void) +{ + SESS_CERT *ret; + + ret = OPENSSL_malloc(sizeof *ret); + if (ret == NULL) { + SSLerr(SSL_F_SSL_SESS_CERT_NEW, ERR_R_MALLOC_FAILURE); + return NULL; + } + + memset(ret, 0, sizeof *ret); + ret->peer_key = &(ret->peer_pkeys[SSL_PKEY_RSA_ENC]); + ret->references = 1; + + return ret; +} + +void ssl_sess_cert_free(SESS_CERT *sc) +{ + int i; + + if (sc == NULL) + return; + + i = CRYPTO_add(&sc->references, -1, CRYPTO_LOCK_SSL_SESS_CERT); +#ifdef REF_PRINT + REF_PRINT("SESS_CERT", sc); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "ssl_sess_cert_free, bad reference count\n"); + abort(); /* ok */ + } +#endif + + /* i == 0 */ + if (sc->cert_chain != NULL) + sk_X509_pop_free(sc->cert_chain, X509_free); + for (i = 0; i < SSL_PKEY_NUM; i++) { + if (sc->peer_pkeys[i].x509 != NULL) + X509_free(sc->peer_pkeys[i].x509); +#if 0 /* We don't have the peer's private key. + * These lines are just * here as a reminder + * that we're still using a + * not-quite-appropriate * data structure. */ + if (sc->peer_pkeys[i].privatekey != NULL) + EVP_PKEY_free(sc->peer_pkeys[i].privatekey); +#endif + } + +#ifndef OPENSSL_NO_RSA + if (sc->peer_rsa_tmp != NULL) + RSA_free(sc->peer_rsa_tmp); +#endif +#ifndef OPENSSL_NO_DH + if (sc->peer_dh_tmp != NULL) + DH_free(sc->peer_dh_tmp); +#endif +#ifndef OPENSSL_NO_ECDH + if (sc->peer_ecdh_tmp != NULL) + EC_KEY_free(sc->peer_ecdh_tmp); +#endif + + OPENSSL_free(sc); +} + +int ssl_set_peer_cert_type(SESS_CERT *sc, int type) +{ + sc->peer_cert_type = type; + return (1); +} + +int ssl_verify_cert_chain(SSL *s, STACK_OF(X509) *sk) +{ + X509 *x; + int i; + X509_STORE_CTX ctx; + + if ((sk == NULL) || (sk_X509_num(sk) == 0)) + return (0); + + x = sk_X509_value(sk, 0); + if (!X509_STORE_CTX_init(&ctx, s->ctx->cert_store, x, sk)) { + SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, ERR_R_X509_LIB); + return (0); + } +#if 0 + if (SSL_get_verify_depth(s) >= 0) + X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s)); +#endif + X509_STORE_CTX_set_ex_data(&ctx, SSL_get_ex_data_X509_STORE_CTX_idx(), s); + + /* + * We need to inherit the verify parameters. These can be determined by + * the context: if its a server it will verify SSL client certificates or + * vice versa. + */ + + X509_STORE_CTX_set_default(&ctx, s->server ? "ssl_client" : "ssl_server"); + /* + * Anything non-default in "param" should overwrite anything in the ctx. + */ + X509_VERIFY_PARAM_set1(X509_STORE_CTX_get0_param(&ctx), s->param); + + if (s->verify_callback) + X509_STORE_CTX_set_verify_cb(&ctx, s->verify_callback); + + if (s->ctx->app_verify_callback != NULL) +#if 1 /* new with OpenSSL 0.9.7 */ + i = s->ctx->app_verify_callback(&ctx, s->ctx->app_verify_arg); +#else + i = s->ctx->app_verify_callback(&ctx); /* should pass app_verify_arg */ +#endif + else { +#ifndef OPENSSL_NO_X509_VERIFY + i = X509_verify_cert(&ctx); +#else + i = 0; + ctx.error = X509_V_ERR_APPLICATION_VERIFICATION; + SSLerr(SSL_F_SSL_VERIFY_CERT_CHAIN, SSL_R_NO_VERIFY_CALLBACK); +#endif + } + + s->verify_result = ctx.error; + X509_STORE_CTX_cleanup(&ctx); + + return (i); +} + +static void set_client_CA_list(STACK_OF(X509_NAME) **ca_list, + STACK_OF(X509_NAME) *name_list) +{ + if (*ca_list != NULL) + sk_X509_NAME_pop_free(*ca_list, X509_NAME_free); + + *ca_list = name_list; +} + +STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *sk) +{ + int i; + STACK_OF(X509_NAME) *ret; + X509_NAME *name; + + ret = sk_X509_NAME_new_null(); + for (i = 0; i < sk_X509_NAME_num(sk); i++) { + name = X509_NAME_dup(sk_X509_NAME_value(sk, i)); + if ((name == NULL) || !sk_X509_NAME_push(ret, name)) { + sk_X509_NAME_pop_free(ret, X509_NAME_free); + return (NULL); + } + } + return (ret); +} + +void SSL_set_client_CA_list(SSL *s, STACK_OF(X509_NAME) *name_list) +{ + set_client_CA_list(&(s->client_CA), name_list); +} + +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) +{ + set_client_CA_list(&(ctx->client_CA), name_list); +} + +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) +{ + return (ctx->client_CA); +} + +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *s) +{ + if (s->type == SSL_ST_CONNECT) { /* we are in the client */ + if (((s->version >> 8) == SSL3_VERSION_MAJOR) && (s->s3 != NULL)) + return (s->s3->tmp.ca_names); + else + return (NULL); + } else { + if (s->client_CA != NULL) + return (s->client_CA); + else + return (s->ctx->client_CA); + } +} + +static int add_client_CA(STACK_OF(X509_NAME) **sk, X509 *x) +{ + X509_NAME *name; + + if (x == NULL) + return (0); + if ((*sk == NULL) && ((*sk = sk_X509_NAME_new_null()) == NULL)) + return (0); + + if ((name = X509_NAME_dup(X509_get_subject_name(x))) == NULL) + return (0); + + if (!sk_X509_NAME_push(*sk, name)) { + X509_NAME_free(name); + return (0); + } + return (1); +} + +int SSL_add_client_CA(SSL *ssl, X509 *x) +{ + return (add_client_CA(&(ssl->client_CA), x)); +} + +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x) +{ + return (add_client_CA(&(ctx->client_CA), x)); +} + +static int xname_cmp(const X509_NAME *const *a, const X509_NAME *const *b) +{ + return (X509_NAME_cmp(*a, *b)); +} + +#ifndef OPENSSL_NO_STDIO +/** + * Load CA certs from a file into a ::STACK. Note that it is somewhat misnamed; + * it doesn't really have anything to do with clients (except that a common use + * for a stack of CAs is to send it to the client). Actually, it doesn't have + * much to do with CAs, either, since it will load any old cert. + * \param file the file containing one or more certs. + * \return a ::STACK containing the certs. + */ +STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file) +{ + BIO *in; + X509 *x = NULL; + X509_NAME *xn = NULL; + STACK_OF(X509_NAME) *ret = NULL, *sk; + + sk = sk_X509_NAME_new(xname_cmp); + + in = BIO_new(BIO_s_file_internal()); + + if ((sk == NULL) || (in == NULL)) { + SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BIO_read_filename(in, file)) + goto err; + + for (;;) { + if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) + break; + if (ret == NULL) { + ret = sk_X509_NAME_new_null(); + if (ret == NULL) { + SSLerr(SSL_F_SSL_LOAD_CLIENT_CA_FILE, ERR_R_MALLOC_FAILURE); + goto err; + } + } + if ((xn = X509_get_subject_name(x)) == NULL) + goto err; + /* check for duplicates */ + xn = X509_NAME_dup(xn); + if (xn == NULL) + goto err; + if (sk_X509_NAME_find(sk, xn) >= 0) + X509_NAME_free(xn); + else { + sk_X509_NAME_push(sk, xn); + sk_X509_NAME_push(ret, xn); + } + } + + if (0) { + err: + if (ret != NULL) + sk_X509_NAME_pop_free(ret, X509_NAME_free); + ret = NULL; + } + if (sk != NULL) + sk_X509_NAME_free(sk); + if (in != NULL) + BIO_free(in); + if (x != NULL) + X509_free(x); + if (ret != NULL) + ERR_clear_error(); + return (ret); +} +#endif + +/** + * Add a file of certs to a stack. + * \param stack the stack to add to. + * \param file the file to add from. All certs in this file that are not + * already in the stack will be added. + * \return 1 for success, 0 for failure. Note that in the case of failure some + * certs may have been added to \c stack. + */ + +int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, + const char *file) +{ + BIO *in; + X509 *x = NULL; + X509_NAME *xn = NULL; + int ret = 1; + int (*oldcmp) (const X509_NAME *const *a, const X509_NAME *const *b); + + oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); + + in = BIO_new(BIO_s_file_internal()); + + if (in == NULL) { + SSLerr(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK, + ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BIO_read_filename(in, file)) + goto err; + + for (;;) { + if (PEM_read_bio_X509(in, &x, NULL, NULL) == NULL) + break; + if ((xn = X509_get_subject_name(x)) == NULL) + goto err; + xn = X509_NAME_dup(xn); + if (xn == NULL) + goto err; + if (sk_X509_NAME_find(stack, xn) >= 0) + X509_NAME_free(xn); + else + sk_X509_NAME_push(stack, xn); + } + + ERR_clear_error(); + + if (0) { + err: + ret = 0; + } + if (in != NULL) + BIO_free(in); + if (x != NULL) + X509_free(x); + + (void)sk_X509_NAME_set_cmp_func(stack, oldcmp); + + return ret; +} + +/** + * Add a directory of certs to a stack. + * \param stack the stack to append to. + * \param dir the directory to append from. All files in this directory will be + * examined as potential certs. Any that are acceptable to + * SSL_add_dir_cert_subjects_to_stack() that are not already in the stack will be + * included. + * \return 1 for success, 0 for failure. Note that in the case of failure some + * certs may have been added to \c stack. + */ + +int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *stack, + const char *dir) +{ + OPENSSL_DIR_CTX *d = NULL; + const char *filename; + int ret = 0; + + CRYPTO_w_lock(CRYPTO_LOCK_READDIR); + + /* Note that a side effect is that the CAs will be sorted by name */ + + while ((filename = OPENSSL_DIR_read(&d, dir))) { + char buf[1024]; + int r; + + if (strlen(dir) + strlen(filename) + 2 > sizeof buf) { + SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, + SSL_R_PATH_TOO_LONG); + goto err; + } +#ifdef OPENSSL_SYS_VMS + r = BIO_snprintf(buf, sizeof buf, "%s%s", dir, filename); +#else + r = BIO_snprintf(buf, sizeof buf, "%s/%s", dir, filename); +#endif + if (r <= 0 || r >= (int)sizeof(buf)) + goto err; + if (!SSL_add_file_cert_subjects_to_stack(stack, buf)) + goto err; + } + + if (errno) { + SYSerr(SYS_F_OPENDIR, get_last_sys_error()); + ERR_add_error_data(3, "OPENSSL_DIR_read(&ctx, '", dir, "')"); + SSLerr(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK, ERR_R_SYS_LIB); + goto err; + } + + ret = 1; + + err: + if (d) + OPENSSL_DIR_end(&d); + CRYPTO_w_unlock(CRYPTO_LOCK_READDIR); + return ret; +} diff --git a/libs/openssl/ssl/ssl_ciph.c b/libs/openssl/ssl/ssl_ciph.c new file mode 100644 index 00000000..56dd4372 --- /dev/null +++ b/libs/openssl/ssl/ssl_ciph.c @@ -0,0 +1,1911 @@ +/* ssl/ssl_ciph.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include +#ifndef OPENSSL_NO_COMP +# include +#endif +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include "ssl_locl.h" + +#define SSL_ENC_DES_IDX 0 +#define SSL_ENC_3DES_IDX 1 +#define SSL_ENC_RC4_IDX 2 +#define SSL_ENC_RC2_IDX 3 +#define SSL_ENC_IDEA_IDX 4 +#define SSL_ENC_NULL_IDX 5 +#define SSL_ENC_AES128_IDX 6 +#define SSL_ENC_AES256_IDX 7 +#define SSL_ENC_CAMELLIA128_IDX 8 +#define SSL_ENC_CAMELLIA256_IDX 9 +#define SSL_ENC_GOST89_IDX 10 +#define SSL_ENC_SEED_IDX 11 +#define SSL_ENC_AES128GCM_IDX 12 +#define SSL_ENC_AES256GCM_IDX 13 +#define SSL_ENC_NUM_IDX 14 + +static const EVP_CIPHER *ssl_cipher_methods[SSL_ENC_NUM_IDX] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL +}; + +#define SSL_COMP_NULL_IDX 0 +#define SSL_COMP_ZLIB_IDX 1 +#define SSL_COMP_NUM_IDX 2 + +static STACK_OF(SSL_COMP) *ssl_comp_methods = NULL; + +#define SSL_MD_MD5_IDX 0 +#define SSL_MD_SHA1_IDX 1 +#define SSL_MD_GOST94_IDX 2 +#define SSL_MD_GOST89MAC_IDX 3 +#define SSL_MD_SHA256_IDX 4 +#define SSL_MD_SHA384_IDX 5 +/* + * Constant SSL_MAX_DIGEST equal to size of digests array should be defined + * in the ssl_locl.h + */ +#define SSL_MD_NUM_IDX SSL_MAX_DIGEST +static const EVP_MD *ssl_digest_methods[SSL_MD_NUM_IDX] = { + NULL, NULL, NULL, NULL, NULL, NULL +}; + +/* + * PKEY_TYPE for GOST89MAC is known in advance, but, because implementation + * is engine-provided, we'll fill it only if corresponding EVP_PKEY_METHOD is + * found + */ +static int ssl_mac_pkey_id[SSL_MD_NUM_IDX] = { + EVP_PKEY_HMAC, EVP_PKEY_HMAC, EVP_PKEY_HMAC, NID_undef, + EVP_PKEY_HMAC, EVP_PKEY_HMAC +}; + +static int ssl_mac_secret_size[SSL_MD_NUM_IDX] = { + 0, 0, 0, 0, 0, 0 +}; + +static int ssl_handshake_digest_flag[SSL_MD_NUM_IDX] = { + SSL_HANDSHAKE_MAC_MD5, SSL_HANDSHAKE_MAC_SHA, + SSL_HANDSHAKE_MAC_GOST94, 0, SSL_HANDSHAKE_MAC_SHA256, + SSL_HANDSHAKE_MAC_SHA384 +}; + +#define CIPHER_ADD 1 +#define CIPHER_KILL 2 +#define CIPHER_DEL 3 +#define CIPHER_ORD 4 +#define CIPHER_SPECIAL 5 + +typedef struct cipher_order_st { + const SSL_CIPHER *cipher; + int active; + int dead; + struct cipher_order_st *next, *prev; +} CIPHER_ORDER; + +static const SSL_CIPHER cipher_aliases[] = { + /* "ALL" doesn't include eNULL (must be specifically enabled) */ + {0, SSL_TXT_ALL, 0, 0, 0, ~SSL_eNULL, 0, 0, 0, 0, 0, 0}, + /* "COMPLEMENTOFALL" */ + {0, SSL_TXT_CMPALL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0}, + + /* + * "COMPLEMENTOFDEFAULT" (does *not* include ciphersuites not found in + * ALL!) + */ + {0, SSL_TXT_CMPDEF, 0, 0, 0, 0, 0, 0, SSL_NOT_DEFAULT, 0, 0, 0}, + + /* + * key exchange aliases (some of those using only a single bit here + * combine multiple key exchange algs according to the RFCs, e.g. kEDH + * combines DHE_DSS and DHE_RSA) + */ + {0, SSL_TXT_kRSA, 0, SSL_kRSA, 0, 0, 0, 0, 0, 0, 0, 0}, + + /* no such ciphersuites supported! */ + {0, SSL_TXT_kDHr, 0, SSL_kDHr, 0, 0, 0, 0, 0, 0, 0, 0}, + /* no such ciphersuites supported! */ + {0, SSL_TXT_kDHd, 0, SSL_kDHd, 0, 0, 0, 0, 0, 0, 0, 0}, + /* no such ciphersuites supported! */ + {0, SSL_TXT_kDH, 0, SSL_kDHr | SSL_kDHd, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kEDH, 0, SSL_kEDH, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_DH, 0, SSL_kDHr | SSL_kDHd | SSL_kEDH, 0, 0, 0, 0, 0, 0, 0, + 0}, + + {0, SSL_TXT_kKRB5, 0, SSL_kKRB5, 0, 0, 0, 0, 0, 0, 0, 0}, + + {0, SSL_TXT_kECDHr, 0, SSL_kECDHr, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kECDHe, 0, SSL_kECDHe, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kECDH, 0, SSL_kECDHr | SSL_kECDHe, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kEECDH, 0, SSL_kEECDH, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_ECDH, 0, SSL_kECDHr | SSL_kECDHe | SSL_kEECDH, 0, 0, 0, 0, 0, + 0, 0, 0}, + + {0, SSL_TXT_kPSK, 0, SSL_kPSK, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kSRP, 0, SSL_kSRP, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_kGOST, 0, SSL_kGOST, 0, 0, 0, 0, 0, 0, 0, 0}, + + /* server authentication aliases */ + {0, SSL_TXT_aRSA, 0, 0, SSL_aRSA, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aDSS, 0, 0, SSL_aDSS, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_DSS, 0, 0, SSL_aDSS, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aKRB5, 0, 0, SSL_aKRB5, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aNULL, 0, 0, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, + /* no such ciphersuites supported! */ + {0, SSL_TXT_aDH, 0, 0, SSL_aDH, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aECDH, 0, 0, SSL_aECDH, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aECDSA, 0, 0, SSL_aECDSA, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_ECDSA, 0, 0, SSL_aECDSA, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aPSK, 0, 0, SSL_aPSK, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aGOST94, 0, 0, SSL_aGOST94, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aGOST01, 0, 0, SSL_aGOST01, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aGOST, 0, 0, SSL_aGOST94 | SSL_aGOST01, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_aSRP, 0, 0, SSL_aSRP, 0, 0, 0, 0, 0, 0, 0}, + + /* aliases combining key exchange and server authentication */ + {0, SSL_TXT_EDH, 0, SSL_kEDH, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_EECDH, 0, SSL_kEECDH, ~SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_NULL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_KRB5, 0, SSL_kKRB5, SSL_aKRB5, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_RSA, 0, SSL_kRSA, SSL_aRSA, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_ADH, 0, SSL_kEDH, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_AECDH, 0, SSL_kEECDH, SSL_aNULL, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_PSK, 0, SSL_kPSK, SSL_aPSK, 0, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_SRP, 0, SSL_kSRP, 0, 0, 0, 0, 0, 0, 0, 0}, + + /* symmetric encryption aliases */ + {0, SSL_TXT_DES, 0, 0, 0, SSL_DES, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_3DES, 0, 0, 0, SSL_3DES, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_RC4, 0, 0, 0, SSL_RC4, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_RC2, 0, 0, 0, SSL_RC2, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_IDEA, 0, 0, 0, SSL_IDEA, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_SEED, 0, 0, 0, SSL_SEED, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_eNULL, 0, 0, 0, SSL_eNULL, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_AES128, 0, 0, 0, SSL_AES128 | SSL_AES128GCM, 0, 0, 0, 0, 0, + 0}, + {0, SSL_TXT_AES256, 0, 0, 0, SSL_AES256 | SSL_AES256GCM, 0, 0, 0, 0, 0, + 0}, + {0, SSL_TXT_AES, 0, 0, 0, SSL_AES, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_AES_GCM, 0, 0, 0, SSL_AES128GCM | SSL_AES256GCM, 0, 0, 0, 0, + 0, 0}, + {0, SSL_TXT_CAMELLIA128, 0, 0, 0, SSL_CAMELLIA128, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_CAMELLIA256, 0, 0, 0, SSL_CAMELLIA256, 0, 0, 0, 0, 0, 0}, + {0, SSL_TXT_CAMELLIA, 0, 0, 0, SSL_CAMELLIA128 | SSL_CAMELLIA256, 0, 0, 0, + 0, 0, 0}, + + /* MAC aliases */ + {0, SSL_TXT_MD5, 0, 0, 0, 0, SSL_MD5, 0, 0, 0, 0, 0}, + {0, SSL_TXT_SHA1, 0, 0, 0, 0, SSL_SHA1, 0, 0, 0, 0, 0}, + {0, SSL_TXT_SHA, 0, 0, 0, 0, SSL_SHA1, 0, 0, 0, 0, 0}, + {0, SSL_TXT_GOST94, 0, 0, 0, 0, SSL_GOST94, 0, 0, 0, 0, 0}, + {0, SSL_TXT_GOST89MAC, 0, 0, 0, 0, SSL_GOST89MAC, 0, 0, 0, 0, 0}, + {0, SSL_TXT_SHA256, 0, 0, 0, 0, SSL_SHA256, 0, 0, 0, 0, 0}, + {0, SSL_TXT_SHA384, 0, 0, 0, 0, SSL_SHA384, 0, 0, 0, 0, 0}, + + /* protocol version aliases */ + {0, SSL_TXT_SSLV2, 0, 0, 0, 0, 0, SSL_SSLV2, 0, 0, 0, 0}, + {0, SSL_TXT_SSLV3, 0, 0, 0, 0, 0, SSL_SSLV3, 0, 0, 0, 0}, + {0, SSL_TXT_TLSV1, 0, 0, 0, 0, 0, SSL_TLSV1, 0, 0, 0, 0}, + {0, SSL_TXT_TLSV1_2, 0, 0, 0, 0, 0, SSL_TLSV1_2, 0, 0, 0, 0}, + + /* export flag */ + {0, SSL_TXT_EXP, 0, 0, 0, 0, 0, 0, SSL_EXPORT, 0, 0, 0}, + {0, SSL_TXT_EXPORT, 0, 0, 0, 0, 0, 0, SSL_EXPORT, 0, 0, 0}, + + /* strength classes */ + {0, SSL_TXT_EXP40, 0, 0, 0, 0, 0, 0, SSL_EXP40, 0, 0, 0}, + {0, SSL_TXT_EXP56, 0, 0, 0, 0, 0, 0, SSL_EXP56, 0, 0, 0}, + {0, SSL_TXT_LOW, 0, 0, 0, 0, 0, 0, SSL_LOW, 0, 0, 0}, + {0, SSL_TXT_MEDIUM, 0, 0, 0, 0, 0, 0, SSL_MEDIUM, 0, 0, 0}, + {0, SSL_TXT_HIGH, 0, 0, 0, 0, 0, 0, SSL_HIGH, 0, 0, 0}, + /* FIPS 140-2 approved ciphersuite */ + {0, SSL_TXT_FIPS, 0, 0, 0, ~SSL_eNULL, 0, 0, SSL_FIPS, 0, 0, 0}, +}; + +/* + * Search for public key algorithm with given name and return its pkey_id if + * it is available. Otherwise return 0 + */ +#ifdef OPENSSL_NO_ENGINE + +static int get_optional_pkey_id(const char *pkey_name) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + int pkey_id = 0; + ameth = EVP_PKEY_asn1_find_str(NULL, pkey_name, -1); + if (ameth && EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, + ameth) > 0) { + return pkey_id; + } + return 0; +} + +#else + +static int get_optional_pkey_id(const char *pkey_name) +{ + const EVP_PKEY_ASN1_METHOD *ameth; + ENGINE *tmpeng = NULL; + int pkey_id = 0; + ameth = EVP_PKEY_asn1_find_str(&tmpeng, pkey_name, -1); + if (ameth) { + if (EVP_PKEY_asn1_get0_info(&pkey_id, NULL, NULL, NULL, NULL, + ameth) <= 0) + pkey_id = 0; + } + if (tmpeng) + ENGINE_finish(tmpeng); + return pkey_id; +} + +#endif + +void ssl_load_ciphers(void) +{ + ssl_cipher_methods[SSL_ENC_DES_IDX] = EVP_get_cipherbyname(SN_des_cbc); + ssl_cipher_methods[SSL_ENC_3DES_IDX] = + EVP_get_cipherbyname(SN_des_ede3_cbc); + ssl_cipher_methods[SSL_ENC_RC4_IDX] = EVP_get_cipherbyname(SN_rc4); + ssl_cipher_methods[SSL_ENC_RC2_IDX] = EVP_get_cipherbyname(SN_rc2_cbc); +#ifndef OPENSSL_NO_IDEA + ssl_cipher_methods[SSL_ENC_IDEA_IDX] = EVP_get_cipherbyname(SN_idea_cbc); +#else + ssl_cipher_methods[SSL_ENC_IDEA_IDX] = NULL; +#endif + ssl_cipher_methods[SSL_ENC_AES128_IDX] = + EVP_get_cipherbyname(SN_aes_128_cbc); + ssl_cipher_methods[SSL_ENC_AES256_IDX] = + EVP_get_cipherbyname(SN_aes_256_cbc); + ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] = + EVP_get_cipherbyname(SN_camellia_128_cbc); + ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] = + EVP_get_cipherbyname(SN_camellia_256_cbc); + ssl_cipher_methods[SSL_ENC_GOST89_IDX] = + EVP_get_cipherbyname(SN_gost89_cnt); + ssl_cipher_methods[SSL_ENC_SEED_IDX] = EVP_get_cipherbyname(SN_seed_cbc); + + ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] = + EVP_get_cipherbyname(SN_aes_128_gcm); + ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] = + EVP_get_cipherbyname(SN_aes_256_gcm); + + ssl_digest_methods[SSL_MD_MD5_IDX] = EVP_get_digestbyname(SN_md5); + ssl_mac_secret_size[SSL_MD_MD5_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_MD5_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_MD5_IDX] >= 0); + ssl_digest_methods[SSL_MD_SHA1_IDX] = EVP_get_digestbyname(SN_sha1); + ssl_mac_secret_size[SSL_MD_SHA1_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_SHA1_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_SHA1_IDX] >= 0); + ssl_digest_methods[SSL_MD_GOST94_IDX] = + EVP_get_digestbyname(SN_id_GostR3411_94); + if (ssl_digest_methods[SSL_MD_GOST94_IDX]) { + ssl_mac_secret_size[SSL_MD_GOST94_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_GOST94_IDX]); + OPENSSL_assert(ssl_mac_secret_size[SSL_MD_GOST94_IDX] >= 0); + } + ssl_digest_methods[SSL_MD_GOST89MAC_IDX] = + EVP_get_digestbyname(SN_id_Gost28147_89_MAC); + ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] = get_optional_pkey_id("gost-mac"); + if (ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX]) { + ssl_mac_secret_size[SSL_MD_GOST89MAC_IDX] = 32; + } + + ssl_digest_methods[SSL_MD_SHA256_IDX] = EVP_get_digestbyname(SN_sha256); + ssl_mac_secret_size[SSL_MD_SHA256_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_SHA256_IDX]); + ssl_digest_methods[SSL_MD_SHA384_IDX] = EVP_get_digestbyname(SN_sha384); + ssl_mac_secret_size[SSL_MD_SHA384_IDX] = + EVP_MD_size(ssl_digest_methods[SSL_MD_SHA384_IDX]); +} + +#ifndef OPENSSL_NO_COMP + +static int sk_comp_cmp(const SSL_COMP *const *a, const SSL_COMP *const *b) +{ + return ((*a)->id - (*b)->id); +} + +static void load_builtin_compressions(void) +{ + int got_write_lock = 0; + + CRYPTO_r_lock(CRYPTO_LOCK_SSL); + if (ssl_comp_methods == NULL) { + CRYPTO_r_unlock(CRYPTO_LOCK_SSL); + CRYPTO_w_lock(CRYPTO_LOCK_SSL); + got_write_lock = 1; + + if (ssl_comp_methods == NULL) { + SSL_COMP *comp = NULL; + + MemCheck_off(); + ssl_comp_methods = sk_SSL_COMP_new(sk_comp_cmp); + if (ssl_comp_methods != NULL) { + comp = (SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); + if (comp != NULL) { + comp->method = COMP_zlib(); + if (comp->method && comp->method->type == NID_undef) + OPENSSL_free(comp); + else { + comp->id = SSL_COMP_ZLIB_IDX; + comp->name = comp->method->name; + sk_SSL_COMP_push(ssl_comp_methods, comp); + } + } + sk_SSL_COMP_sort(ssl_comp_methods); + } + MemCheck_on(); + } + } + + if (got_write_lock) + CRYPTO_w_unlock(CRYPTO_LOCK_SSL); + else + CRYPTO_r_unlock(CRYPTO_LOCK_SSL); +} +#endif + +int ssl_cipher_get_evp(const SSL_SESSION *s, const EVP_CIPHER **enc, + const EVP_MD **md, int *mac_pkey_type, + int *mac_secret_size, SSL_COMP **comp) +{ + int i; + const SSL_CIPHER *c; + + c = s->cipher; + if (c == NULL) + return (0); + if (comp != NULL) { + SSL_COMP ctmp; +#ifndef OPENSSL_NO_COMP + load_builtin_compressions(); +#endif + + *comp = NULL; + ctmp.id = s->compress_meth; + if (ssl_comp_methods != NULL) { + i = sk_SSL_COMP_find(ssl_comp_methods, &ctmp); + if (i >= 0) + *comp = sk_SSL_COMP_value(ssl_comp_methods, i); + else + *comp = NULL; + } + } + + if ((enc == NULL) || (md == NULL)) + return (0); + + switch (c->algorithm_enc) { + case SSL_DES: + i = SSL_ENC_DES_IDX; + break; + case SSL_3DES: + i = SSL_ENC_3DES_IDX; + break; + case SSL_RC4: + i = SSL_ENC_RC4_IDX; + break; + case SSL_RC2: + i = SSL_ENC_RC2_IDX; + break; + case SSL_IDEA: + i = SSL_ENC_IDEA_IDX; + break; + case SSL_eNULL: + i = SSL_ENC_NULL_IDX; + break; + case SSL_AES128: + i = SSL_ENC_AES128_IDX; + break; + case SSL_AES256: + i = SSL_ENC_AES256_IDX; + break; + case SSL_CAMELLIA128: + i = SSL_ENC_CAMELLIA128_IDX; + break; + case SSL_CAMELLIA256: + i = SSL_ENC_CAMELLIA256_IDX; + break; + case SSL_eGOST2814789CNT: + i = SSL_ENC_GOST89_IDX; + break; + case SSL_SEED: + i = SSL_ENC_SEED_IDX; + break; + case SSL_AES128GCM: + i = SSL_ENC_AES128GCM_IDX; + break; + case SSL_AES256GCM: + i = SSL_ENC_AES256GCM_IDX; + break; + default: + i = -1; + break; + } + + if ((i < 0) || (i >= SSL_ENC_NUM_IDX)) + *enc = NULL; + else { + if (i == SSL_ENC_NULL_IDX) + *enc = EVP_enc_null(); + else + *enc = ssl_cipher_methods[i]; + } + + switch (c->algorithm_mac) { + case SSL_MD5: + i = SSL_MD_MD5_IDX; + break; + case SSL_SHA1: + i = SSL_MD_SHA1_IDX; + break; + case SSL_SHA256: + i = SSL_MD_SHA256_IDX; + break; + case SSL_SHA384: + i = SSL_MD_SHA384_IDX; + break; + case SSL_GOST94: + i = SSL_MD_GOST94_IDX; + break; + case SSL_GOST89MAC: + i = SSL_MD_GOST89MAC_IDX; + break; + default: + i = -1; + break; + } + if ((i < 0) || (i >= SSL_MD_NUM_IDX)) { + *md = NULL; + if (mac_pkey_type != NULL) + *mac_pkey_type = NID_undef; + if (mac_secret_size != NULL) + *mac_secret_size = 0; + if (c->algorithm_mac == SSL_AEAD) + mac_pkey_type = NULL; + } else { + *md = ssl_digest_methods[i]; + if (mac_pkey_type != NULL) + *mac_pkey_type = ssl_mac_pkey_id[i]; + if (mac_secret_size != NULL) + *mac_secret_size = ssl_mac_secret_size[i]; + } + + if ((*enc != NULL) && + (*md != NULL || (EVP_CIPHER_flags(*enc) & EVP_CIPH_FLAG_AEAD_CIPHER)) + && (!mac_pkey_type || *mac_pkey_type != NID_undef)) { + const EVP_CIPHER *evp; + + if (s->ssl_version >> 8 != TLS1_VERSION_MAJOR || + s->ssl_version < TLS1_VERSION) + return 1; + +#ifdef OPENSSL_FIPS + if (FIPS_mode()) + return 1; +#endif + + if (c->algorithm_enc == SSL_RC4 && + c->algorithm_mac == SSL_MD5 && + (evp = EVP_get_cipherbyname("RC4-HMAC-MD5"))) + *enc = evp, *md = NULL; + else if (c->algorithm_enc == SSL_AES128 && + c->algorithm_mac == SSL_SHA1 && + (evp = EVP_get_cipherbyname("AES-128-CBC-HMAC-SHA1"))) + *enc = evp, *md = NULL; + else if (c->algorithm_enc == SSL_AES256 && + c->algorithm_mac == SSL_SHA1 && + (evp = EVP_get_cipherbyname("AES-256-CBC-HMAC-SHA1"))) + *enc = evp, *md = NULL; + return (1); + } else + return (0); +} + +int ssl_get_handshake_digest(int idx, long *mask, const EVP_MD **md) +{ + if (idx < 0 || idx >= SSL_MD_NUM_IDX) { + return 0; + } + *mask = ssl_handshake_digest_flag[idx]; + if (*mask) + *md = ssl_digest_methods[idx]; + else + *md = NULL; + return 1; +} + +#define ITEM_SEP(a) \ + (((a) == ':') || ((a) == ' ') || ((a) == ';') || ((a) == ',')) + +static void ll_append_tail(CIPHER_ORDER **head, CIPHER_ORDER *curr, + CIPHER_ORDER **tail) +{ + if (curr == *tail) + return; + if (curr == *head) + *head = curr->next; + if (curr->prev != NULL) + curr->prev->next = curr->next; + if (curr->next != NULL) + curr->next->prev = curr->prev; + (*tail)->next = curr; + curr->prev = *tail; + curr->next = NULL; + *tail = curr; +} + +static void ll_append_head(CIPHER_ORDER **head, CIPHER_ORDER *curr, + CIPHER_ORDER **tail) +{ + if (curr == *head) + return; + if (curr == *tail) + *tail = curr->prev; + if (curr->next != NULL) + curr->next->prev = curr->prev; + if (curr->prev != NULL) + curr->prev->next = curr->next; + (*head)->prev = curr; + curr->next = *head; + curr->prev = NULL; + *head = curr; +} + +static void ssl_cipher_get_disabled(unsigned long *mkey, unsigned long *auth, + unsigned long *enc, unsigned long *mac, + unsigned long *ssl) +{ + *mkey = 0; + *auth = 0; + *enc = 0; + *mac = 0; + *ssl = 0; + +#ifdef OPENSSL_NO_RSA + *mkey |= SSL_kRSA; + *auth |= SSL_aRSA; +#endif +#ifdef OPENSSL_NO_DSA + *auth |= SSL_aDSS; +#endif + *mkey |= SSL_kDHr | SSL_kDHd; /* no such ciphersuites supported! */ + *auth |= SSL_aDH; +#ifdef OPENSSL_NO_DH + *mkey |= SSL_kDHr | SSL_kDHd | SSL_kEDH; + *auth |= SSL_aDH; +#endif +#ifdef OPENSSL_NO_KRB5 + *mkey |= SSL_kKRB5; + *auth |= SSL_aKRB5; +#endif +#ifdef OPENSSL_NO_ECDSA + *auth |= SSL_aECDSA; +#endif +#ifdef OPENSSL_NO_ECDH + *mkey |= SSL_kECDHe | SSL_kECDHr; + *auth |= SSL_aECDH; +#endif +#ifdef OPENSSL_NO_PSK + *mkey |= SSL_kPSK; + *auth |= SSL_aPSK; +#endif +#ifdef OPENSSL_NO_SRP + *mkey |= SSL_kSRP; +#endif + /* + * Check for presence of GOST 34.10 algorithms, and if they do not + * present, disable appropriate auth and key exchange + */ + if (!get_optional_pkey_id("gost94")) { + *auth |= SSL_aGOST94; + } + if (!get_optional_pkey_id("gost2001")) { + *auth |= SSL_aGOST01; + } + /* + * Disable GOST key exchange if no GOST signature algs are available * + */ + if ((*auth & (SSL_aGOST94 | SSL_aGOST01)) == (SSL_aGOST94 | SSL_aGOST01)) { + *mkey |= SSL_kGOST; + } +#ifdef SSL_FORBID_ENULL + *enc |= SSL_eNULL; +#endif + + *enc |= (ssl_cipher_methods[SSL_ENC_DES_IDX] == NULL) ? SSL_DES : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_3DES_IDX] == NULL) ? SSL_3DES : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_RC4_IDX] == NULL) ? SSL_RC4 : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_RC2_IDX] == NULL) ? SSL_RC2 : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_IDEA_IDX] == NULL) ? SSL_IDEA : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_AES128_IDX] == NULL) ? SSL_AES128 : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_AES256_IDX] == NULL) ? SSL_AES256 : 0; + *enc |= + (ssl_cipher_methods[SSL_ENC_AES128GCM_IDX] == + NULL) ? SSL_AES128GCM : 0; + *enc |= + (ssl_cipher_methods[SSL_ENC_AES256GCM_IDX] == + NULL) ? SSL_AES256GCM : 0; + *enc |= + (ssl_cipher_methods[SSL_ENC_CAMELLIA128_IDX] == + NULL) ? SSL_CAMELLIA128 : 0; + *enc |= + (ssl_cipher_methods[SSL_ENC_CAMELLIA256_IDX] == + NULL) ? SSL_CAMELLIA256 : 0; + *enc |= + (ssl_cipher_methods[SSL_ENC_GOST89_IDX] == + NULL) ? SSL_eGOST2814789CNT : 0; + *enc |= (ssl_cipher_methods[SSL_ENC_SEED_IDX] == NULL) ? SSL_SEED : 0; + + *mac |= (ssl_digest_methods[SSL_MD_MD5_IDX] == NULL) ? SSL_MD5 : 0; + *mac |= (ssl_digest_methods[SSL_MD_SHA1_IDX] == NULL) ? SSL_SHA1 : 0; + *mac |= (ssl_digest_methods[SSL_MD_SHA256_IDX] == NULL) ? SSL_SHA256 : 0; + *mac |= (ssl_digest_methods[SSL_MD_SHA384_IDX] == NULL) ? SSL_SHA384 : 0; + *mac |= (ssl_digest_methods[SSL_MD_GOST94_IDX] == NULL) ? SSL_GOST94 : 0; + *mac |= (ssl_digest_methods[SSL_MD_GOST89MAC_IDX] == NULL + || ssl_mac_pkey_id[SSL_MD_GOST89MAC_IDX] == + NID_undef) ? SSL_GOST89MAC : 0; + +} + +static void ssl_cipher_collect_ciphers(const SSL_METHOD *ssl_method, + int num_of_ciphers, + unsigned long disabled_mkey, + unsigned long disabled_auth, + unsigned long disabled_enc, + unsigned long disabled_mac, + unsigned long disabled_ssl, + CIPHER_ORDER *co_list, + CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) +{ + int i, co_list_num; + const SSL_CIPHER *c; + + /* + * We have num_of_ciphers descriptions compiled in, depending on the + * method selected (SSLv2 and/or SSLv3, TLSv1 etc). + * These will later be sorted in a linked list with at most num + * entries. + */ + + /* Get the initial list of ciphers */ + co_list_num = 0; /* actual count of ciphers */ + for (i = 0; i < num_of_ciphers; i++) { + c = ssl_method->get_cipher(i); + /* drop those that use any of that is not available */ + if ((c != NULL) && c->valid && +#ifdef OPENSSL_FIPS + (!FIPS_mode() || (c->algo_strength & SSL_FIPS)) && +#endif + !(c->algorithm_mkey & disabled_mkey) && + !(c->algorithm_auth & disabled_auth) && + !(c->algorithm_enc & disabled_enc) && + !(c->algorithm_mac & disabled_mac) && + !(c->algorithm_ssl & disabled_ssl)) { + co_list[co_list_num].cipher = c; + co_list[co_list_num].next = NULL; + co_list[co_list_num].prev = NULL; + co_list[co_list_num].active = 0; + co_list_num++; +#ifdef KSSL_DEBUG + fprintf(stderr, "\t%d: %s %lx %lx %lx\n", i, c->name, c->id, + c->algorithm_mkey, c->algorithm_auth); +#endif /* KSSL_DEBUG */ + /* + * if (!sk_push(ca_list,(char *)c)) goto err; + */ + } + } + + /* + * Prepare linked list from list entries + */ + if (co_list_num > 0) { + co_list[0].prev = NULL; + + if (co_list_num > 1) { + co_list[0].next = &co_list[1]; + + for (i = 1; i < co_list_num - 1; i++) { + co_list[i].prev = &co_list[i - 1]; + co_list[i].next = &co_list[i + 1]; + } + + co_list[co_list_num - 1].prev = &co_list[co_list_num - 2]; + } + + co_list[co_list_num - 1].next = NULL; + + *head_p = &co_list[0]; + *tail_p = &co_list[co_list_num - 1]; + } +} + +static void ssl_cipher_collect_aliases(const SSL_CIPHER **ca_list, + int num_of_group_aliases, + unsigned long disabled_mkey, + unsigned long disabled_auth, + unsigned long disabled_enc, + unsigned long disabled_mac, + unsigned long disabled_ssl, + CIPHER_ORDER *head) +{ + CIPHER_ORDER *ciph_curr; + const SSL_CIPHER **ca_curr; + int i; + unsigned long mask_mkey = ~disabled_mkey; + unsigned long mask_auth = ~disabled_auth; + unsigned long mask_enc = ~disabled_enc; + unsigned long mask_mac = ~disabled_mac; + unsigned long mask_ssl = ~disabled_ssl; + + /* + * First, add the real ciphers as already collected + */ + ciph_curr = head; + ca_curr = ca_list; + while (ciph_curr != NULL) { + *ca_curr = ciph_curr->cipher; + ca_curr++; + ciph_curr = ciph_curr->next; + } + + /* + * Now we add the available ones from the cipher_aliases[] table. + * They represent either one or more algorithms, some of which + * in any affected category must be supported (set in enabled_mask), + * or represent a cipher strength value (will be added in any case because algorithms=0). + */ + for (i = 0; i < num_of_group_aliases; i++) { + unsigned long algorithm_mkey = cipher_aliases[i].algorithm_mkey; + unsigned long algorithm_auth = cipher_aliases[i].algorithm_auth; + unsigned long algorithm_enc = cipher_aliases[i].algorithm_enc; + unsigned long algorithm_mac = cipher_aliases[i].algorithm_mac; + unsigned long algorithm_ssl = cipher_aliases[i].algorithm_ssl; + + if (algorithm_mkey) + if ((algorithm_mkey & mask_mkey) == 0) + continue; + + if (algorithm_auth) + if ((algorithm_auth & mask_auth) == 0) + continue; + + if (algorithm_enc) + if ((algorithm_enc & mask_enc) == 0) + continue; + + if (algorithm_mac) + if ((algorithm_mac & mask_mac) == 0) + continue; + + if (algorithm_ssl) + if ((algorithm_ssl & mask_ssl) == 0) + continue; + + *ca_curr = (SSL_CIPHER *)(cipher_aliases + i); + ca_curr++; + } + + *ca_curr = NULL; /* end of list */ +} + +static void ssl_cipher_apply_rule(unsigned long cipher_id, + unsigned long alg_mkey, + unsigned long alg_auth, + unsigned long alg_enc, + unsigned long alg_mac, + unsigned long alg_ssl, + unsigned long algo_strength, int rule, + int strength_bits, CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) +{ + CIPHER_ORDER *head, *tail, *curr, *next, *last; + const SSL_CIPHER *cp; + int reverse = 0; + +#ifdef CIPHER_DEBUG + fprintf(stderr, + "Applying rule %d with %08lx/%08lx/%08lx/%08lx/%08lx %08lx (%d)\n", + rule, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, + algo_strength, strength_bits); +#endif + + if (rule == CIPHER_DEL) + reverse = 1; /* needed to maintain sorting between + * currently deleted ciphers */ + + head = *head_p; + tail = *tail_p; + + if (reverse) { + next = tail; + last = head; + } else { + next = head; + last = tail; + } + + curr = NULL; + for (;;) { + if (curr == last) + break; + + curr = next; + + if (curr == NULL) + break; + + next = reverse ? curr->prev : curr->next; + + cp = curr->cipher; + + /* + * Selection criteria is either the value of strength_bits + * or the algorithms used. + */ + if (strength_bits >= 0) { + if (strength_bits != cp->strength_bits) + continue; + } else { +#ifdef CIPHER_DEBUG + fprintf(stderr, + "\nName: %s:\nAlgo = %08lx/%08lx/%08lx/%08lx/%08lx Algo_strength = %08lx\n", + cp->name, cp->algorithm_mkey, cp->algorithm_auth, + cp->algorithm_enc, cp->algorithm_mac, cp->algorithm_ssl, + cp->algo_strength); +#endif + if (alg_mkey && !(alg_mkey & cp->algorithm_mkey)) + continue; + if (alg_auth && !(alg_auth & cp->algorithm_auth)) + continue; + if (alg_enc && !(alg_enc & cp->algorithm_enc)) + continue; + if (alg_mac && !(alg_mac & cp->algorithm_mac)) + continue; + if (alg_ssl && !(alg_ssl & cp->algorithm_ssl)) + continue; + if ((algo_strength & SSL_EXP_MASK) + && !(algo_strength & SSL_EXP_MASK & cp->algo_strength)) + continue; + if ((algo_strength & SSL_STRONG_MASK) + && !(algo_strength & SSL_STRONG_MASK & cp->algo_strength)) + continue; + if ((algo_strength & SSL_NOT_DEFAULT) + && !(cp->algo_strength & SSL_NOT_DEFAULT)) + continue; + } + +#ifdef CIPHER_DEBUG + fprintf(stderr, "Action = %d\n", rule); +#endif + + /* add the cipher if it has not been added yet. */ + if (rule == CIPHER_ADD) { + /* reverse == 0 */ + if (!curr->active) { + ll_append_tail(&head, curr, &tail); + curr->active = 1; + } + } + /* Move the added cipher to this location */ + else if (rule == CIPHER_ORD) { + /* reverse == 0 */ + if (curr->active) { + ll_append_tail(&head, curr, &tail); + } + } else if (rule == CIPHER_DEL) { + /* reverse == 1 */ + if (curr->active) { + /* + * most recently deleted ciphersuites get best positions for + * any future CIPHER_ADD (note that the CIPHER_DEL loop works + * in reverse to maintain the order) + */ + ll_append_head(&head, curr, &tail); + curr->active = 0; + } + } else if (rule == CIPHER_KILL) { + /* reverse == 0 */ + if (head == curr) + head = curr->next; + else + curr->prev->next = curr->next; + if (tail == curr) + tail = curr->prev; + curr->active = 0; + if (curr->next != NULL) + curr->next->prev = curr->prev; + if (curr->prev != NULL) + curr->prev->next = curr->next; + curr->next = NULL; + curr->prev = NULL; + } + } + + *head_p = head; + *tail_p = tail; +} + +static int ssl_cipher_strength_sort(CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) +{ + int max_strength_bits, i, *number_uses; + CIPHER_ORDER *curr; + + /* + * This routine sorts the ciphers with descending strength. The sorting + * must keep the pre-sorted sequence, so we apply the normal sorting + * routine as '+' movement to the end of the list. + */ + max_strength_bits = 0; + curr = *head_p; + while (curr != NULL) { + if (curr->active && (curr->cipher->strength_bits > max_strength_bits)) + max_strength_bits = curr->cipher->strength_bits; + curr = curr->next; + } + + number_uses = OPENSSL_malloc((max_strength_bits + 1) * sizeof(int)); + if (!number_uses) { + SSLerr(SSL_F_SSL_CIPHER_STRENGTH_SORT, ERR_R_MALLOC_FAILURE); + return (0); + } + memset(number_uses, 0, (max_strength_bits + 1) * sizeof(int)); + + /* + * Now find the strength_bits values actually used + */ + curr = *head_p; + while (curr != NULL) { + if (curr->active) + number_uses[curr->cipher->strength_bits]++; + curr = curr->next; + } + /* + * Go through the list of used strength_bits values in descending + * order. + */ + for (i = max_strength_bits; i >= 0; i--) + if (number_uses[i] > 0) + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ORD, i, head_p, + tail_p); + + OPENSSL_free(number_uses); + return (1); +} + +static int ssl_cipher_process_rulestr(const char *rule_str, + CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p, + const SSL_CIPHER **ca_list) +{ + unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, + algo_strength; + const char *l, *buf; + int j, multi, found, rule, retval, ok, buflen; + unsigned long cipher_id = 0; + char ch; + + retval = 1; + l = rule_str; + for (;;) { + ch = *l; + + if (ch == '\0') + break; /* done */ + if (ch == '-') { + rule = CIPHER_DEL; + l++; + } else if (ch == '+') { + rule = CIPHER_ORD; + l++; + } else if (ch == '!') { + rule = CIPHER_KILL; + l++; + } else if (ch == '@') { + rule = CIPHER_SPECIAL; + l++; + } else { + rule = CIPHER_ADD; + } + + if (ITEM_SEP(ch)) { + l++; + continue; + } + + alg_mkey = 0; + alg_auth = 0; + alg_enc = 0; + alg_mac = 0; + alg_ssl = 0; + algo_strength = 0; + + for (;;) { + ch = *l; + buf = l; + buflen = 0; +#ifndef CHARSET_EBCDIC + while (((ch >= 'A') && (ch <= 'Z')) || + ((ch >= '0') && (ch <= '9')) || + ((ch >= 'a') && (ch <= 'z')) || (ch == '-') || (ch == '.')) +#else + while (isalnum(ch) || (ch == '-') || (ch == '.')) +#endif + { + ch = *(++l); + buflen++; + } + + if (buflen == 0) { + /* + * We hit something we cannot deal with, + * it is no command or separator nor + * alphanumeric, so we call this an error. + */ + SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, + SSL_R_INVALID_COMMAND); + retval = found = 0; + l++; + break; + } + + if (rule == CIPHER_SPECIAL) { + found = 0; /* unused -- avoid compiler warning */ + break; /* special treatment */ + } + + /* check for multi-part specification */ + if (ch == '+') { + multi = 1; + l++; + } else + multi = 0; + + /* + * Now search for the cipher alias in the ca_list. Be careful + * with the strncmp, because the "buflen" limitation + * will make the rule "ADH:SOME" and the cipher + * "ADH-MY-CIPHER" look like a match for buflen=3. + * So additionally check whether the cipher name found + * has the correct length. We can save a strlen() call: + * just checking for the '\0' at the right place is + * sufficient, we have to strncmp() anyway. (We cannot + * use strcmp(), because buf is not '\0' terminated.) + */ + j = found = 0; + cipher_id = 0; + while (ca_list[j]) { + if (!strncmp(buf, ca_list[j]->name, buflen) && + (ca_list[j]->name[buflen] == '\0')) { + found = 1; + break; + } else + j++; + } + + if (!found) + break; /* ignore this entry */ + + if (ca_list[j]->algorithm_mkey) { + if (alg_mkey) { + alg_mkey &= ca_list[j]->algorithm_mkey; + if (!alg_mkey) { + found = 0; + break; + } + } else + alg_mkey = ca_list[j]->algorithm_mkey; + } + + if (ca_list[j]->algorithm_auth) { + if (alg_auth) { + alg_auth &= ca_list[j]->algorithm_auth; + if (!alg_auth) { + found = 0; + break; + } + } else + alg_auth = ca_list[j]->algorithm_auth; + } + + if (ca_list[j]->algorithm_enc) { + if (alg_enc) { + alg_enc &= ca_list[j]->algorithm_enc; + if (!alg_enc) { + found = 0; + break; + } + } else + alg_enc = ca_list[j]->algorithm_enc; + } + + if (ca_list[j]->algorithm_mac) { + if (alg_mac) { + alg_mac &= ca_list[j]->algorithm_mac; + if (!alg_mac) { + found = 0; + break; + } + } else + alg_mac = ca_list[j]->algorithm_mac; + } + + if (ca_list[j]->algo_strength & SSL_EXP_MASK) { + if (algo_strength & SSL_EXP_MASK) { + algo_strength &= + (ca_list[j]->algo_strength & SSL_EXP_MASK) | + ~SSL_EXP_MASK; + if (!(algo_strength & SSL_EXP_MASK)) { + found = 0; + break; + } + } else + algo_strength |= ca_list[j]->algo_strength & SSL_EXP_MASK; + } + + if (ca_list[j]->algo_strength & SSL_STRONG_MASK) { + if (algo_strength & SSL_STRONG_MASK) { + algo_strength &= + (ca_list[j]->algo_strength & SSL_STRONG_MASK) | + ~SSL_STRONG_MASK; + if (!(algo_strength & SSL_STRONG_MASK)) { + found = 0; + break; + } + } else + algo_strength |= + ca_list[j]->algo_strength & SSL_STRONG_MASK; + } + + if (ca_list[j]->algo_strength & SSL_NOT_DEFAULT) { + algo_strength |= SSL_NOT_DEFAULT; + } + + if (ca_list[j]->valid) { + /* + * explicit ciphersuite found; its protocol version does not + * become part of the search pattern! + */ + + cipher_id = ca_list[j]->id; + } else { + /* + * not an explicit ciphersuite; only in this case, the + * protocol version is considered part of the search pattern + */ + + if (ca_list[j]->algorithm_ssl) { + if (alg_ssl) { + alg_ssl &= ca_list[j]->algorithm_ssl; + if (!alg_ssl) { + found = 0; + break; + } + } else + alg_ssl = ca_list[j]->algorithm_ssl; + } + } + + if (!multi) + break; + } + + /* + * Ok, we have the rule, now apply it + */ + if (rule == CIPHER_SPECIAL) { /* special command */ + ok = 0; + if ((buflen == 8) && !strncmp(buf, "STRENGTH", 8)) + ok = ssl_cipher_strength_sort(head_p, tail_p); + else + SSLerr(SSL_F_SSL_CIPHER_PROCESS_RULESTR, + SSL_R_INVALID_COMMAND); + if (ok == 0) + retval = 0; + /* + * We do not support any "multi" options + * together with "@", so throw away the + * rest of the command, if any left, until + * end or ':' is found. + */ + while ((*l != '\0') && !ITEM_SEP(*l)) + l++; + } else if (found) { + ssl_cipher_apply_rule(cipher_id, + alg_mkey, alg_auth, alg_enc, alg_mac, + alg_ssl, algo_strength, rule, -1, head_p, + tail_p); + } else { + while ((*l != '\0') && !ITEM_SEP(*l)) + l++; + } + if (*l == '\0') + break; /* done */ + } + + return (retval); +} + +STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(const SSL_METHOD *ssl_method, STACK_OF(SSL_CIPHER) + **cipher_list, STACK_OF(SSL_CIPHER) + **cipher_list_by_id, + const char *rule_str) +{ + int ok, num_of_ciphers, num_of_alias_max, num_of_group_aliases; + unsigned long disabled_mkey, disabled_auth, disabled_enc, disabled_mac, + disabled_ssl; + STACK_OF(SSL_CIPHER) *cipherstack, *tmp_cipher_list; + const char *rule_p; + CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; + const SSL_CIPHER **ca_list = NULL; + + /* + * Return with error if nothing to do. + */ + if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL) + return NULL; + + /* + * To reduce the work to do we only want to process the compiled + * in algorithms, so we first get the mask of disabled ciphers. + */ + ssl_cipher_get_disabled(&disabled_mkey, &disabled_auth, &disabled_enc, + &disabled_mac, &disabled_ssl); + + /* + * Now we have to collect the available ciphers from the compiled + * in ciphers. We cannot get more than the number compiled in, so + * it is used for allocation. + */ + num_of_ciphers = ssl_method->num_ciphers(); +#ifdef KSSL_DEBUG + fprintf(stderr, "ssl_create_cipher_list() for %d ciphers\n", + num_of_ciphers); +#endif /* KSSL_DEBUG */ + co_list = + (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * num_of_ciphers); + if (co_list == NULL) { + SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + return (NULL); /* Failure */ + } + + ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers, + disabled_mkey, disabled_auth, disabled_enc, + disabled_mac, disabled_ssl, co_list, &head, + &tail); + + /* Now arrange all ciphers by preference: */ + + /* + * Everything else being equal, prefer ephemeral ECDH over other key + * exchange mechanisms + */ + ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, + &tail); + ssl_cipher_apply_rule(0, SSL_kEECDH, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, + &tail); + + /* AES is our preferred symmetric cipher */ + ssl_cipher_apply_rule(0, 0, 0, SSL_AES, 0, 0, 0, CIPHER_ADD, -1, &head, + &tail); + + /* Temporarily enable everything else for sorting */ + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_ADD, -1, &head, &tail); + + /* Low priority for MD5 */ + ssl_cipher_apply_rule(0, 0, 0, 0, SSL_MD5, 0, 0, CIPHER_ORD, -1, &head, + &tail); + + /* + * Move anonymous ciphers to the end. Usually, these will remain + * disabled. (For applications that allow them, they aren't too bad, but + * we prefer authenticated ciphers.) + */ + ssl_cipher_apply_rule(0, 0, SSL_aNULL, 0, 0, 0, 0, CIPHER_ORD, -1, &head, + &tail); + + /* Move ciphers without forward secrecy to the end */ + ssl_cipher_apply_rule(0, 0, SSL_aECDH, 0, 0, 0, 0, CIPHER_ORD, -1, &head, + &tail); + /* + * ssl_cipher_apply_rule(0, 0, SSL_aDH, 0, 0, 0, 0, CIPHER_ORD, -1, + * &head, &tail); + */ + ssl_cipher_apply_rule(0, SSL_kRSA, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, + &tail); + ssl_cipher_apply_rule(0, SSL_kPSK, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, + &tail); + ssl_cipher_apply_rule(0, SSL_kKRB5, 0, 0, 0, 0, 0, CIPHER_ORD, -1, &head, + &tail); + + /* RC4 is sort-of broken -- move the the end */ + ssl_cipher_apply_rule(0, 0, 0, SSL_RC4, 0, 0, 0, CIPHER_ORD, -1, &head, + &tail); + + /* + * Now sort by symmetric encryption strength. The above ordering remains + * in force within each class + */ + if (!ssl_cipher_strength_sort(&head, &tail)) { + OPENSSL_free(co_list); + return NULL; + } + + /* Now disable everything (maintaining the ordering!) */ + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, 0, CIPHER_DEL, -1, &head, &tail); + + /* + * We also need cipher aliases for selecting based on the rule_str. + * There might be two types of entries in the rule_str: 1) names + * of ciphers themselves 2) aliases for groups of ciphers. + * For 1) we need the available ciphers and for 2) the cipher + * groups of cipher_aliases added together in one list (otherwise + * we would be happy with just the cipher_aliases table). + */ + num_of_group_aliases = sizeof(cipher_aliases) / sizeof(SSL_CIPHER); + num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1; + ca_list = OPENSSL_malloc(sizeof(SSL_CIPHER *) * num_of_alias_max); + if (ca_list == NULL) { + OPENSSL_free(co_list); + SSLerr(SSL_F_SSL_CREATE_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + return (NULL); /* Failure */ + } + ssl_cipher_collect_aliases(ca_list, num_of_group_aliases, + disabled_mkey, disabled_auth, disabled_enc, + disabled_mac, disabled_ssl, head); + + /* + * If the rule_string begins with DEFAULT, apply the default rule + * before using the (possibly available) additional rules. + */ + ok = 1; + rule_p = rule_str; + if (strncmp(rule_str, "DEFAULT", 7) == 0) { + ok = ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, + &head, &tail, ca_list); + rule_p += 7; + if (*rule_p == ':') + rule_p++; + } + + if (ok && (strlen(rule_p) > 0)) + ok = ssl_cipher_process_rulestr(rule_p, &head, &tail, ca_list); + + OPENSSL_free((void *)ca_list); /* Not needed anymore */ + + if (!ok) { /* Rule processing failure */ + OPENSSL_free(co_list); + return (NULL); + } + + /* + * Allocate new "cipherstack" for the result, return with error + * if we cannot get one. + */ + if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) { + OPENSSL_free(co_list); + return (NULL); + } + + /* + * The cipher selection for the list is done. The ciphers are added + * to the resulting precedence to the STACK_OF(SSL_CIPHER). + */ + for (curr = head; curr != NULL; curr = curr->next) { +#ifdef OPENSSL_FIPS + if (curr->active + && (!FIPS_mode() || curr->cipher->algo_strength & SSL_FIPS)) +#else + if (curr->active) +#endif + { + sk_SSL_CIPHER_push(cipherstack, curr->cipher); +#ifdef CIPHER_DEBUG + fprintf(stderr, "<%s>\n", curr->cipher->name); +#endif + } + } + OPENSSL_free(co_list); /* Not needed any longer */ + + tmp_cipher_list = sk_SSL_CIPHER_dup(cipherstack); + if (tmp_cipher_list == NULL) { + sk_SSL_CIPHER_free(cipherstack); + return NULL; + } + if (*cipher_list != NULL) + sk_SSL_CIPHER_free(*cipher_list); + *cipher_list = cipherstack; + if (*cipher_list_by_id != NULL) + sk_SSL_CIPHER_free(*cipher_list_by_id); + *cipher_list_by_id = tmp_cipher_list; + (void)sk_SSL_CIPHER_set_cmp_func(*cipher_list_by_id, + ssl_cipher_ptr_id_cmp); + + sk_SSL_CIPHER_sort(*cipher_list_by_id); + return (cipherstack); +} + +char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len) +{ + int is_export, pkl, kl; + const char *ver, *exp_str; + const char *kx, *au, *enc, *mac; + unsigned long alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl, alg2; +#ifdef KSSL_DEBUG + static const char *format = + "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s AL=%lx/%lx/%lx/%lx/%lx\n"; +#else + static const char *format = + "%-23s %s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s%s\n"; +#endif /* KSSL_DEBUG */ + + alg_mkey = cipher->algorithm_mkey; + alg_auth = cipher->algorithm_auth; + alg_enc = cipher->algorithm_enc; + alg_mac = cipher->algorithm_mac; + alg_ssl = cipher->algorithm_ssl; + + alg2 = cipher->algorithm2; + + is_export = SSL_C_IS_EXPORT(cipher); + pkl = SSL_C_EXPORT_PKEYLENGTH(cipher); + kl = SSL_C_EXPORT_KEYLENGTH(cipher); + exp_str = is_export ? " export" : ""; + + if (alg_ssl & SSL_SSLV2) + ver = "SSLv2"; + else if (alg_ssl & SSL_SSLV3) + ver = "SSLv3"; + else if (alg_ssl & SSL_TLSV1_2) + ver = "TLSv1.2"; + else + ver = "unknown"; + + switch (alg_mkey) { + case SSL_kRSA: + kx = is_export ? (pkl == 512 ? "RSA(512)" : "RSA(1024)") : "RSA"; + break; + case SSL_kDHr: + kx = "DH/RSA"; + break; + case SSL_kDHd: + kx = "DH/DSS"; + break; + case SSL_kKRB5: + kx = "KRB5"; + break; + case SSL_kEDH: + kx = is_export ? (pkl == 512 ? "DH(512)" : "DH(1024)") : "DH"; + break; + case SSL_kECDHr: + kx = "ECDH/RSA"; + break; + case SSL_kECDHe: + kx = "ECDH/ECDSA"; + break; + case SSL_kEECDH: + kx = "ECDH"; + break; + case SSL_kPSK: + kx = "PSK"; + break; + case SSL_kSRP: + kx = "SRP"; + break; + case SSL_kGOST: + kx = "GOST"; + break; + default: + kx = "unknown"; + } + + switch (alg_auth) { + case SSL_aRSA: + au = "RSA"; + break; + case SSL_aDSS: + au = "DSS"; + break; + case SSL_aDH: + au = "DH"; + break; + case SSL_aKRB5: + au = "KRB5"; + break; + case SSL_aECDH: + au = "ECDH"; + break; + case SSL_aNULL: + au = "None"; + break; + case SSL_aECDSA: + au = "ECDSA"; + break; + case SSL_aPSK: + au = "PSK"; + break; + case SSL_aSRP: + au = "SRP"; + break; + case SSL_aGOST94: + au = "GOST94"; + break; + case SSL_aGOST01: + au = "GOST01"; + break; + default: + au = "unknown"; + break; + } + + switch (alg_enc) { + case SSL_DES: + enc = (is_export && kl == 5) ? "DES(40)" : "DES(56)"; + break; + case SSL_3DES: + enc = "3DES(168)"; + break; + case SSL_RC4: + enc = is_export ? (kl == 5 ? "RC4(40)" : "RC4(56)") + : ((alg2 & SSL2_CF_8_BYTE_ENC) ? "RC4(64)" : "RC4(128)"); + break; + case SSL_RC2: + enc = is_export ? (kl == 5 ? "RC2(40)" : "RC2(56)") : "RC2(128)"; + break; + case SSL_IDEA: + enc = "IDEA(128)"; + break; + case SSL_eNULL: + enc = "None"; + break; + case SSL_AES128: + enc = "AES(128)"; + break; + case SSL_AES256: + enc = "AES(256)"; + break; + case SSL_AES128GCM: + enc = "AESGCM(128)"; + break; + case SSL_AES256GCM: + enc = "AESGCM(256)"; + break; + case SSL_CAMELLIA128: + enc = "Camellia(128)"; + break; + case SSL_CAMELLIA256: + enc = "Camellia(256)"; + break; + case SSL_SEED: + enc = "SEED(128)"; + break; + case SSL_eGOST2814789CNT: + enc = "GOST89(256)"; + break; + default: + enc = "unknown"; + break; + } + + switch (alg_mac) { + case SSL_MD5: + mac = "MD5"; + break; + case SSL_SHA1: + mac = "SHA1"; + break; + case SSL_SHA256: + mac = "SHA256"; + break; + case SSL_SHA384: + mac = "SHA384"; + break; + case SSL_AEAD: + mac = "AEAD"; + break; + case SSL_GOST89MAC: + mac = "GOST89"; + break; + case SSL_GOST94: + mac = "GOST94"; + break; + default: + mac = "unknown"; + break; + } + + if (buf == NULL) { + len = 128; + buf = OPENSSL_malloc(len); + if (buf == NULL) + return ("OPENSSL_malloc Error"); + } else if (len < 128) + return ("Buffer too small"); + +#ifdef KSSL_DEBUG + BIO_snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac, + exp_str, alg_mkey, alg_auth, alg_enc, alg_mac, alg_ssl); +#else + BIO_snprintf(buf, len, format, cipher->name, ver, kx, au, enc, mac, + exp_str); +#endif /* KSSL_DEBUG */ + return (buf); +} + +char *SSL_CIPHER_get_version(const SSL_CIPHER *c) +{ + int i; + + if (c == NULL) + return ("(NONE)"); + i = (int)(c->id >> 24L); + if (i == 3) + return ("TLSv1/SSLv3"); + else if (i == 2) + return ("SSLv2"); + else + return ("unknown"); +} + +/* return the actual cipher being used */ +const char *SSL_CIPHER_get_name(const SSL_CIPHER *c) +{ + if (c != NULL) + return (c->name); + return ("(NONE)"); +} + +/* number of bits for symmetric cipher */ +int SSL_CIPHER_get_bits(const SSL_CIPHER *c, int *alg_bits) +{ + int ret = 0; + + if (c != NULL) { + if (alg_bits != NULL) + *alg_bits = c->alg_bits; + ret = c->strength_bits; + } + return (ret); +} + +unsigned long SSL_CIPHER_get_id(const SSL_CIPHER *c) +{ + return c->id; +} + +SSL_COMP *ssl3_comp_find(STACK_OF(SSL_COMP) *sk, int n) +{ + SSL_COMP *ctmp; + int i, nn; + + if ((n == 0) || (sk == NULL)) + return (NULL); + nn = sk_SSL_COMP_num(sk); + for (i = 0; i < nn; i++) { + ctmp = sk_SSL_COMP_value(sk, i); + if (ctmp->id == n) + return (ctmp); + } + return (NULL); +} + +#ifdef OPENSSL_NO_COMP +void *SSL_COMP_get_compression_methods(void) +{ + return NULL; +} + +int SSL_COMP_add_compression_method(int id, void *cm) +{ + return 1; +} + +const char *SSL_COMP_get_name(const void *comp) +{ + return NULL; +} +#else +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) +{ + load_builtin_compressions(); + return (ssl_comp_methods); +} + +int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm) +{ + SSL_COMP *comp; + + if (cm == NULL || cm->type == NID_undef) + return 1; + + /*- + * According to draft-ietf-tls-compression-04.txt, the + * compression number ranges should be the following: + * + * 0 to 63: methods defined by the IETF + * 64 to 192: external party methods assigned by IANA + * 193 to 255: reserved for private use + */ + if (id < 193 || id > 255) { + SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, + SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE); + return 0; + } + + MemCheck_off(); + comp = (SSL_COMP *)OPENSSL_malloc(sizeof(SSL_COMP)); + comp->id = id; + comp->method = cm; + load_builtin_compressions(); + if (ssl_comp_methods && sk_SSL_COMP_find(ssl_comp_methods, comp) >= 0) { + OPENSSL_free(comp); + MemCheck_on(); + SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, + SSL_R_DUPLICATE_COMPRESSION_ID); + return (1); + } else if ((ssl_comp_methods == NULL) + || !sk_SSL_COMP_push(ssl_comp_methods, comp)) { + OPENSSL_free(comp); + MemCheck_on(); + SSLerr(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD, ERR_R_MALLOC_FAILURE); + return (1); + } else { + MemCheck_on(); + return (0); + } +} + +const char *SSL_COMP_get_name(const COMP_METHOD *comp) +{ + if (comp) + return comp->name; + return NULL; +} + +#endif diff --git a/libs/openssl/ssl/ssl_err.c b/libs/openssl/ssl/ssl_err.c new file mode 100644 index 00000000..caa671a2 --- /dev/null +++ b/libs/openssl/ssl/ssl_err.c @@ -0,0 +1,797 @@ +/* ssl/ssl_err.c */ +/* ==================================================================== + * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +/* + * NOTE: this file was auto generated by the mkerr.pl script: any changes + * made to it will be overwritten when the script next updates this file, + * only reason strings will be preserved. + */ + +#include +#include +#include + +/* BEGIN ERROR CODES */ +#ifndef OPENSSL_NO_ERR + +# define ERR_FUNC(func) ERR_PACK(ERR_LIB_SSL,func,0) +# define ERR_REASON(reason) ERR_PACK(ERR_LIB_SSL,0,reason) + +static ERR_STRING_DATA SSL_str_functs[] = { + {ERR_FUNC(SSL_F_CLIENT_CERTIFICATE), "CLIENT_CERTIFICATE"}, + {ERR_FUNC(SSL_F_CLIENT_FINISHED), "CLIENT_FINISHED"}, + {ERR_FUNC(SSL_F_CLIENT_HELLO), "CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_CLIENT_MASTER_KEY), "CLIENT_MASTER_KEY"}, + {ERR_FUNC(SSL_F_D2I_SSL_SESSION), "d2i_SSL_SESSION"}, + {ERR_FUNC(SSL_F_DO_DTLS1_WRITE), "DO_DTLS1_WRITE"}, + {ERR_FUNC(SSL_F_DO_SSL3_WRITE), "DO_SSL3_WRITE"}, + {ERR_FUNC(SSL_F_DTLS1_ACCEPT), "DTLS1_ACCEPT"}, + {ERR_FUNC(SSL_F_DTLS1_ADD_CERT_TO_BUF), "DTLS1_ADD_CERT_TO_BUF"}, + {ERR_FUNC(SSL_F_DTLS1_BUFFER_RECORD), "DTLS1_BUFFER_RECORD"}, + {ERR_FUNC(SSL_F_DTLS1_CHECK_TIMEOUT_NUM), "DTLS1_CHECK_TIMEOUT_NUM"}, + {ERR_FUNC(SSL_F_DTLS1_CLIENT_HELLO), "DTLS1_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_DTLS1_CONNECT), "DTLS1_CONNECT"}, + {ERR_FUNC(SSL_F_DTLS1_ENC), "DTLS1_ENC"}, + {ERR_FUNC(SSL_F_DTLS1_GET_HELLO_VERIFY), "DTLS1_GET_HELLO_VERIFY"}, + {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE), "DTLS1_GET_MESSAGE"}, + {ERR_FUNC(SSL_F_DTLS1_GET_MESSAGE_FRAGMENT), + "DTLS1_GET_MESSAGE_FRAGMENT"}, + {ERR_FUNC(SSL_F_DTLS1_GET_RECORD), "DTLS1_GET_RECORD"}, + {ERR_FUNC(SSL_F_DTLS1_HANDLE_TIMEOUT), "DTLS1_HANDLE_TIMEOUT"}, + {ERR_FUNC(SSL_F_DTLS1_HEARTBEAT), "DTLS1_HEARTBEAT"}, + {ERR_FUNC(SSL_F_DTLS1_OUTPUT_CERT_CHAIN), "DTLS1_OUTPUT_CERT_CHAIN"}, + {ERR_FUNC(SSL_F_DTLS1_PREPROCESS_FRAGMENT), "DTLS1_PREPROCESS_FRAGMENT"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE), + "DTLS1_PROCESS_OUT_OF_SEQ_MESSAGE"}, + {ERR_FUNC(SSL_F_DTLS1_PROCESS_RECORD), "DTLS1_PROCESS_RECORD"}, + {ERR_FUNC(SSL_F_DTLS1_READ_BYTES), "DTLS1_READ_BYTES"}, + {ERR_FUNC(SSL_F_DTLS1_READ_FAILED), "DTLS1_READ_FAILED"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_CERTIFICATE_REQUEST), + "DTLS1_SEND_CERTIFICATE_REQUEST"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_CERTIFICATE), + "DTLS1_SEND_CLIENT_CERTIFICATE"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE), + "DTLS1_SEND_CLIENT_KEY_EXCHANGE"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_CLIENT_VERIFY), "DTLS1_SEND_CLIENT_VERIFY"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_HELLO_VERIFY_REQUEST), + "DTLS1_SEND_HELLO_VERIFY_REQUEST"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_CERTIFICATE), + "DTLS1_SEND_SERVER_CERTIFICATE"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_HELLO), "DTLS1_SEND_SERVER_HELLO"}, + {ERR_FUNC(SSL_F_DTLS1_SEND_SERVER_KEY_EXCHANGE), + "DTLS1_SEND_SERVER_KEY_EXCHANGE"}, + {ERR_FUNC(SSL_F_DTLS1_WRITE_APP_DATA_BYTES), + "DTLS1_WRITE_APP_DATA_BYTES"}, + {ERR_FUNC(SSL_F_GET_CLIENT_FINISHED), "GET_CLIENT_FINISHED"}, + {ERR_FUNC(SSL_F_GET_CLIENT_HELLO), "GET_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_GET_CLIENT_MASTER_KEY), "GET_CLIENT_MASTER_KEY"}, + {ERR_FUNC(SSL_F_GET_SERVER_FINISHED), "GET_SERVER_FINISHED"}, + {ERR_FUNC(SSL_F_GET_SERVER_HELLO), "GET_SERVER_HELLO"}, + {ERR_FUNC(SSL_F_GET_SERVER_VERIFY), "GET_SERVER_VERIFY"}, + {ERR_FUNC(SSL_F_I2D_SSL_SESSION), "i2d_SSL_SESSION"}, + {ERR_FUNC(SSL_F_READ_N), "READ_N"}, + {ERR_FUNC(SSL_F_REQUEST_CERTIFICATE), "REQUEST_CERTIFICATE"}, + {ERR_FUNC(SSL_F_SERVER_FINISH), "SERVER_FINISH"}, + {ERR_FUNC(SSL_F_SERVER_HELLO), "SERVER_HELLO"}, + {ERR_FUNC(SSL_F_SERVER_VERIFY), "SERVER_VERIFY"}, + {ERR_FUNC(SSL_F_SSL23_ACCEPT), "SSL23_ACCEPT"}, + {ERR_FUNC(SSL_F_SSL23_CLIENT_HELLO), "SSL23_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_SSL23_CONNECT), "SSL23_CONNECT"}, + {ERR_FUNC(SSL_F_SSL23_GET_CLIENT_HELLO), "SSL23_GET_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_SSL23_GET_SERVER_HELLO), "SSL23_GET_SERVER_HELLO"}, + {ERR_FUNC(SSL_F_SSL23_PEEK), "SSL23_PEEK"}, + {ERR_FUNC(SSL_F_SSL23_READ), "SSL23_READ"}, + {ERR_FUNC(SSL_F_SSL23_WRITE), "SSL23_WRITE"}, + {ERR_FUNC(SSL_F_SSL2_ACCEPT), "SSL2_ACCEPT"}, + {ERR_FUNC(SSL_F_SSL2_CONNECT), "SSL2_CONNECT"}, + {ERR_FUNC(SSL_F_SSL2_ENC_INIT), "SSL2_ENC_INIT"}, + {ERR_FUNC(SSL_F_SSL2_GENERATE_KEY_MATERIAL), + "SSL2_GENERATE_KEY_MATERIAL"}, + {ERR_FUNC(SSL_F_SSL2_PEEK), "SSL2_PEEK"}, + {ERR_FUNC(SSL_F_SSL2_READ), "SSL2_READ"}, + {ERR_FUNC(SSL_F_SSL2_READ_INTERNAL), "SSL2_READ_INTERNAL"}, + {ERR_FUNC(SSL_F_SSL2_SET_CERTIFICATE), "SSL2_SET_CERTIFICATE"}, + {ERR_FUNC(SSL_F_SSL2_WRITE), "SSL2_WRITE"}, + {ERR_FUNC(SSL_F_SSL3_ACCEPT), "SSL3_ACCEPT"}, + {ERR_FUNC(SSL_F_SSL3_ADD_CERT_TO_BUF), "SSL3_ADD_CERT_TO_BUF"}, + {ERR_FUNC(SSL_F_SSL3_CALLBACK_CTRL), "SSL3_CALLBACK_CTRL"}, + {ERR_FUNC(SSL_F_SSL3_CHANGE_CIPHER_STATE), "SSL3_CHANGE_CIPHER_STATE"}, + {ERR_FUNC(SSL_F_SSL3_CHECK_CERT_AND_ALGORITHM), + "SSL3_CHECK_CERT_AND_ALGORITHM"}, + {ERR_FUNC(SSL_F_SSL3_CHECK_CLIENT_HELLO), "SSL3_CHECK_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_SSL3_CLIENT_HELLO), "SSL3_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_SSL3_CONNECT), "SSL3_CONNECT"}, + {ERR_FUNC(SSL_F_SSL3_CTRL), "SSL3_CTRL"}, + {ERR_FUNC(SSL_F_SSL3_CTX_CTRL), "SSL3_CTX_CTRL"}, + {ERR_FUNC(SSL_F_SSL3_DIGEST_CACHED_RECORDS), + "SSL3_DIGEST_CACHED_RECORDS"}, + {ERR_FUNC(SSL_F_SSL3_DO_CHANGE_CIPHER_SPEC), + "SSL3_DO_CHANGE_CIPHER_SPEC"}, + {ERR_FUNC(SSL_F_SSL3_ENC), "SSL3_ENC"}, + {ERR_FUNC(SSL_F_SSL3_CHECK_FINISHED), "SSL3_CHECK_FINISHED"}, + {ERR_FUNC(SSL_F_SSL3_GENERATE_KEY_BLOCK), "SSL3_GENERATE_KEY_BLOCK"}, + {ERR_FUNC(SSL_F_SSL3_GENERATE_MASTER_SECRET), + "ssl3_generate_master_secret"}, + {ERR_FUNC(SSL_F_SSL3_GET_CERTIFICATE_REQUEST), + "SSL3_GET_CERTIFICATE_REQUEST"}, + {ERR_FUNC(SSL_F_SSL3_GET_CERT_STATUS), "SSL3_GET_CERT_STATUS"}, + {ERR_FUNC(SSL_F_SSL3_GET_CERT_VERIFY), "SSL3_GET_CERT_VERIFY"}, + {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_CERTIFICATE), + "SSL3_GET_CLIENT_CERTIFICATE"}, + {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_HELLO), "SSL3_GET_CLIENT_HELLO"}, + {ERR_FUNC(SSL_F_SSL3_GET_CLIENT_KEY_EXCHANGE), + "SSL3_GET_CLIENT_KEY_EXCHANGE"}, + {ERR_FUNC(SSL_F_SSL3_GET_FINISHED), "SSL3_GET_FINISHED"}, + {ERR_FUNC(SSL_F_SSL3_GET_KEY_EXCHANGE), "SSL3_GET_KEY_EXCHANGE"}, + {ERR_FUNC(SSL_F_SSL3_GET_MESSAGE), "SSL3_GET_MESSAGE"}, + {ERR_FUNC(SSL_F_SSL3_GET_NEW_SESSION_TICKET), + "SSL3_GET_NEW_SESSION_TICKET"}, + {ERR_FUNC(SSL_F_SSL3_GET_NEXT_PROTO), "SSL3_GET_NEXT_PROTO"}, + {ERR_FUNC(SSL_F_SSL3_GET_RECORD), "SSL3_GET_RECORD"}, + {ERR_FUNC(SSL_F_SSL3_GET_SERVER_CERTIFICATE), + "SSL3_GET_SERVER_CERTIFICATE"}, + {ERR_FUNC(SSL_F_SSL3_GET_SERVER_DONE), "SSL3_GET_SERVER_DONE"}, + {ERR_FUNC(SSL_F_SSL3_GET_SERVER_HELLO), "SSL3_GET_SERVER_HELLO"}, + {ERR_FUNC(SSL_F_SSL3_HANDSHAKE_MAC), "ssl3_handshake_mac"}, + {ERR_FUNC(SSL_F_SSL3_NEW_SESSION_TICKET), "SSL3_NEW_SESSION_TICKET"}, + {ERR_FUNC(SSL_F_SSL3_OUTPUT_CERT_CHAIN), "SSL3_OUTPUT_CERT_CHAIN"}, + {ERR_FUNC(SSL_F_SSL3_PEEK), "SSL3_PEEK"}, + {ERR_FUNC(SSL_F_SSL3_READ_BYTES), "SSL3_READ_BYTES"}, + {ERR_FUNC(SSL_F_SSL3_READ_N), "SSL3_READ_N"}, + {ERR_FUNC(SSL_F_SSL3_SEND_CERTIFICATE_REQUEST), + "SSL3_SEND_CERTIFICATE_REQUEST"}, + {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_CERTIFICATE), + "SSL3_SEND_CLIENT_CERTIFICATE"}, + {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE), + "SSL3_SEND_CLIENT_KEY_EXCHANGE"}, + {ERR_FUNC(SSL_F_SSL3_SEND_CLIENT_VERIFY), "SSL3_SEND_CLIENT_VERIFY"}, + {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_CERTIFICATE), + "SSL3_SEND_SERVER_CERTIFICATE"}, + {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_HELLO), "SSL3_SEND_SERVER_HELLO"}, + {ERR_FUNC(SSL_F_SSL3_SEND_SERVER_KEY_EXCHANGE), + "SSL3_SEND_SERVER_KEY_EXCHANGE"}, + {ERR_FUNC(SSL_F_SSL3_SETUP_KEY_BLOCK), "SSL3_SETUP_KEY_BLOCK"}, + {ERR_FUNC(SSL_F_SSL3_SETUP_READ_BUFFER), "SSL3_SETUP_READ_BUFFER"}, + {ERR_FUNC(SSL_F_SSL3_SETUP_WRITE_BUFFER), "SSL3_SETUP_WRITE_BUFFER"}, + {ERR_FUNC(SSL_F_SSL3_WRITE_BYTES), "SSL3_WRITE_BYTES"}, + {ERR_FUNC(SSL_F_SSL3_WRITE_PENDING), "SSL3_WRITE_PENDING"}, + {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT), + "SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT"}, + {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT), + "SSL_ADD_CLIENTHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_ADD_CLIENTHELLO_USE_SRTP_EXT), + "SSL_ADD_CLIENTHELLO_USE_SRTP_EXT"}, + {ERR_FUNC(SSL_F_SSL_ADD_DIR_CERT_SUBJECTS_TO_STACK), + "SSL_add_dir_cert_subjects_to_stack"}, + {ERR_FUNC(SSL_F_SSL_ADD_FILE_CERT_SUBJECTS_TO_STACK), + "SSL_add_file_cert_subjects_to_stack"}, + {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT), + "SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT"}, + {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT), + "SSL_ADD_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_ADD_SERVERHELLO_USE_SRTP_EXT), + "SSL_ADD_SERVERHELLO_USE_SRTP_EXT"}, + {ERR_FUNC(SSL_F_SSL_BAD_METHOD), "SSL_BAD_METHOD"}, + {ERR_FUNC(SSL_F_SSL_BYTES_TO_CIPHER_LIST), "SSL_BYTES_TO_CIPHER_LIST"}, + {ERR_FUNC(SSL_F_SSL_CERT_DUP), "SSL_CERT_DUP"}, + {ERR_FUNC(SSL_F_SSL_CERT_INST), "SSL_CERT_INST"}, + {ERR_FUNC(SSL_F_SSL_CERT_INSTANTIATE), "SSL_CERT_INSTANTIATE"}, + {ERR_FUNC(SSL_F_SSL_CERT_NEW), "SSL_CERT_NEW"}, + {ERR_FUNC(SSL_F_SSL_CHECK_PRIVATE_KEY), "SSL_check_private_key"}, + {ERR_FUNC(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT), + "SSL_CHECK_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG), + "SSL_CHECK_SRVR_ECC_CERT_AND_ALG"}, + {ERR_FUNC(SSL_F_SSL_CIPHER_PROCESS_RULESTR), + "SSL_CIPHER_PROCESS_RULESTR"}, + {ERR_FUNC(SSL_F_SSL_CIPHER_STRENGTH_SORT), "SSL_CIPHER_STRENGTH_SORT"}, + {ERR_FUNC(SSL_F_SSL_CLEAR), "SSL_clear"}, + {ERR_FUNC(SSL_F_SSL_COMP_ADD_COMPRESSION_METHOD), + "SSL_COMP_add_compression_method"}, + {ERR_FUNC(SSL_F_SSL_CREATE_CIPHER_LIST), "SSL_CREATE_CIPHER_LIST"}, + {ERR_FUNC(SSL_F_SSL_CTRL), "SSL_ctrl"}, + {ERR_FUNC(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY), "SSL_CTX_check_private_key"}, + {ERR_FUNC(SSL_F_SSL_CTX_MAKE_PROFILES), "SSL_CTX_MAKE_PROFILES"}, + {ERR_FUNC(SSL_F_SSL_CTX_NEW), "SSL_CTX_new"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_CIPHER_LIST), "SSL_CTX_set_cipher_list"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE), + "SSL_CTX_set_client_cert_engine"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_PURPOSE), "SSL_CTX_set_purpose"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT), + "SSL_CTX_set_session_id_context"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_SSL_VERSION), "SSL_CTX_set_ssl_version"}, + {ERR_FUNC(SSL_F_SSL_CTX_SET_TRUST), "SSL_CTX_set_trust"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE), "SSL_CTX_use_certificate"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1), + "SSL_CTX_use_certificate_ASN1"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE), + "SSL_CTX_use_certificate_chain_file"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE), + "SSL_CTX_use_certificate_file"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY), "SSL_CTX_use_PrivateKey"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1), + "SSL_CTX_use_PrivateKey_ASN1"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE), + "SSL_CTX_use_PrivateKey_file"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT), + "SSL_CTX_use_psk_identity_hint"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY), "SSL_CTX_use_RSAPrivateKey"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1), + "SSL_CTX_use_RSAPrivateKey_ASN1"}, + {ERR_FUNC(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE), + "SSL_CTX_use_RSAPrivateKey_file"}, + {ERR_FUNC(SSL_F_SSL_DO_HANDSHAKE), "SSL_do_handshake"}, + {ERR_FUNC(SSL_F_SSL_GET_NEW_SESSION), "SSL_GET_NEW_SESSION"}, + {ERR_FUNC(SSL_F_SSL_GET_PREV_SESSION), "SSL_GET_PREV_SESSION"}, + {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_CERT), "SSL_GET_SERVER_SEND_CERT"}, + {ERR_FUNC(SSL_F_SSL_GET_SERVER_SEND_PKEY), "SSL_GET_SERVER_SEND_PKEY"}, + {ERR_FUNC(SSL_F_SSL_GET_SIGN_PKEY), "SSL_GET_SIGN_PKEY"}, + {ERR_FUNC(SSL_F_SSL_INIT_WBIO_BUFFER), "SSL_INIT_WBIO_BUFFER"}, + {ERR_FUNC(SSL_F_SSL_LOAD_CLIENT_CA_FILE), "SSL_load_client_CA_file"}, + {ERR_FUNC(SSL_F_SSL_NEW), "SSL_new"}, + {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT), + "SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT"}, + {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT), + "SSL_PARSE_CLIENTHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT), + "SSL_PARSE_CLIENTHELLO_USE_SRTP_EXT"}, + {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT), + "SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT"}, + {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT), + "SSL_PARSE_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_PARSE_SERVERHELLO_USE_SRTP_EXT), + "SSL_PARSE_SERVERHELLO_USE_SRTP_EXT"}, + {ERR_FUNC(SSL_F_SSL_PEEK), "SSL_peek"}, + {ERR_FUNC(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT), + "SSL_PREPARE_CLIENTHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT), + "SSL_PREPARE_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_SSL_READ), "SSL_read"}, + {ERR_FUNC(SSL_F_SSL_RSA_PRIVATE_DECRYPT), "SSL_RSA_PRIVATE_DECRYPT"}, + {ERR_FUNC(SSL_F_SSL_RSA_PUBLIC_ENCRYPT), "SSL_RSA_PUBLIC_ENCRYPT"}, + {ERR_FUNC(SSL_F_SSL_SESSION_DUP), "ssl_session_dup"}, + {ERR_FUNC(SSL_F_SSL_SESSION_NEW), "SSL_SESSION_new"}, + {ERR_FUNC(SSL_F_SSL_SESSION_PRINT_FP), "SSL_SESSION_print_fp"}, + {ERR_FUNC(SSL_F_SSL_SESSION_SET1_ID_CONTEXT), + "SSL_SESSION_set1_id_context"}, + {ERR_FUNC(SSL_F_SSL_SESS_CERT_NEW), "SSL_SESS_CERT_NEW"}, + {ERR_FUNC(SSL_F_SSL_SET_CERT), "SSL_SET_CERT"}, + {ERR_FUNC(SSL_F_SSL_SET_CIPHER_LIST), "SSL_set_cipher_list"}, + {ERR_FUNC(SSL_F_SSL_SET_FD), "SSL_set_fd"}, + {ERR_FUNC(SSL_F_SSL_SET_PKEY), "SSL_SET_PKEY"}, + {ERR_FUNC(SSL_F_SSL_SET_PURPOSE), "SSL_set_purpose"}, + {ERR_FUNC(SSL_F_SSL_SET_RFD), "SSL_set_rfd"}, + {ERR_FUNC(SSL_F_SSL_SET_SESSION), "SSL_set_session"}, + {ERR_FUNC(SSL_F_SSL_SET_SESSION_ID_CONTEXT), + "SSL_set_session_id_context"}, + {ERR_FUNC(SSL_F_SSL_SET_SESSION_TICKET_EXT), + "SSL_set_session_ticket_ext"}, + {ERR_FUNC(SSL_F_SSL_SET_TRUST), "SSL_set_trust"}, + {ERR_FUNC(SSL_F_SSL_SET_WFD), "SSL_set_wfd"}, + {ERR_FUNC(SSL_F_SSL_SHUTDOWN), "SSL_shutdown"}, + {ERR_FUNC(SSL_F_SSL_SRP_CTX_INIT), "SSL_SRP_CTX_init"}, + {ERR_FUNC(SSL_F_SSL_UNDEFINED_CONST_FUNCTION), + "SSL_UNDEFINED_CONST_FUNCTION"}, + {ERR_FUNC(SSL_F_SSL_UNDEFINED_FUNCTION), "SSL_UNDEFINED_FUNCTION"}, + {ERR_FUNC(SSL_F_SSL_UNDEFINED_VOID_FUNCTION), + "SSL_UNDEFINED_VOID_FUNCTION"}, + {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE), "SSL_use_certificate"}, + {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_ASN1), "SSL_use_certificate_ASN1"}, + {ERR_FUNC(SSL_F_SSL_USE_CERTIFICATE_FILE), "SSL_use_certificate_file"}, + {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY), "SSL_use_PrivateKey"}, + {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_ASN1), "SSL_use_PrivateKey_ASN1"}, + {ERR_FUNC(SSL_F_SSL_USE_PRIVATEKEY_FILE), "SSL_use_PrivateKey_file"}, + {ERR_FUNC(SSL_F_SSL_USE_PSK_IDENTITY_HINT), "SSL_use_psk_identity_hint"}, + {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY), "SSL_use_RSAPrivateKey"}, + {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1), + "SSL_use_RSAPrivateKey_ASN1"}, + {ERR_FUNC(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE), + "SSL_use_RSAPrivateKey_file"}, + {ERR_FUNC(SSL_F_SSL_VERIFY_CERT_CHAIN), "SSL_VERIFY_CERT_CHAIN"}, + {ERR_FUNC(SSL_F_SSL_WRITE), "SSL_write"}, + {ERR_FUNC(SSL_F_TLS1_CERT_VERIFY_MAC), "tls1_cert_verify_mac"}, + {ERR_FUNC(SSL_F_TLS1_CHANGE_CIPHER_STATE), "TLS1_CHANGE_CIPHER_STATE"}, + {ERR_FUNC(SSL_F_TLS1_CHECK_SERVERHELLO_TLSEXT), + "TLS1_CHECK_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_TLS1_ENC), "TLS1_ENC"}, + {ERR_FUNC(SSL_F_TLS1_EXPORT_KEYING_MATERIAL), + "TLS1_EXPORT_KEYING_MATERIAL"}, + {ERR_FUNC(SSL_F_TLS1_HEARTBEAT), "SSL_F_TLS1_HEARTBEAT"}, + {ERR_FUNC(SSL_F_TLS1_PREPARE_CLIENTHELLO_TLSEXT), + "TLS1_PREPARE_CLIENTHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_TLS1_PREPARE_SERVERHELLO_TLSEXT), + "TLS1_PREPARE_SERVERHELLO_TLSEXT"}, + {ERR_FUNC(SSL_F_TLS1_PRF), "tls1_prf"}, + {ERR_FUNC(SSL_F_TLS1_SETUP_KEY_BLOCK), "TLS1_SETUP_KEY_BLOCK"}, + {ERR_FUNC(SSL_F_WRITE_PENDING), "WRITE_PENDING"}, + {0, NULL} +}; + +static ERR_STRING_DATA SSL_str_reasons[] = { + {ERR_REASON(SSL_R_APP_DATA_IN_HANDSHAKE), "app data in handshake"}, + {ERR_REASON(SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT), + "attempt to reuse session in different context"}, + {ERR_REASON(SSL_R_BAD_ALERT_RECORD), "bad alert record"}, + {ERR_REASON(SSL_R_BAD_AUTHENTICATION_TYPE), "bad authentication type"}, + {ERR_REASON(SSL_R_BAD_CHANGE_CIPHER_SPEC), "bad change cipher spec"}, + {ERR_REASON(SSL_R_BAD_CHECKSUM), "bad checksum"}, + {ERR_REASON(SSL_R_BAD_DATA_RETURNED_BY_CALLBACK), + "bad data returned by callback"}, + {ERR_REASON(SSL_R_BAD_DECOMPRESSION), "bad decompression"}, + {ERR_REASON(SSL_R_BAD_DH_G_LENGTH), "bad dh g length"}, + {ERR_REASON(SSL_R_BAD_DH_G_VALUE), "bad dh g value"}, + {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_LENGTH), "bad dh pub key length"}, + {ERR_REASON(SSL_R_BAD_DH_PUB_KEY_VALUE), "bad dh pub key value"}, + {ERR_REASON(SSL_R_BAD_DH_P_LENGTH), "bad dh p length"}, + {ERR_REASON(SSL_R_BAD_DH_P_VALUE), "bad dh p value"}, + {ERR_REASON(SSL_R_BAD_DIGEST_LENGTH), "bad digest length"}, + {ERR_REASON(SSL_R_BAD_DSA_SIGNATURE), "bad dsa signature"}, + {ERR_REASON(SSL_R_BAD_ECC_CERT), "bad ecc cert"}, + {ERR_REASON(SSL_R_BAD_ECDSA_SIGNATURE), "bad ecdsa signature"}, + {ERR_REASON(SSL_R_BAD_ECPOINT), "bad ecpoint"}, + {ERR_REASON(SSL_R_BAD_HANDSHAKE_LENGTH), "bad handshake length"}, + {ERR_REASON(SSL_R_BAD_HELLO_REQUEST), "bad hello request"}, + {ERR_REASON(SSL_R_BAD_LENGTH), "bad length"}, + {ERR_REASON(SSL_R_BAD_MAC_DECODE), "bad mac decode"}, + {ERR_REASON(SSL_R_BAD_MAC_LENGTH), "bad mac length"}, + {ERR_REASON(SSL_R_BAD_MESSAGE_TYPE), "bad message type"}, + {ERR_REASON(SSL_R_BAD_PACKET_LENGTH), "bad packet length"}, + {ERR_REASON(SSL_R_BAD_PROTOCOL_VERSION_NUMBER), + "bad protocol version number"}, + {ERR_REASON(SSL_R_BAD_PSK_IDENTITY_HINT_LENGTH), + "bad psk identity hint length"}, + {ERR_REASON(SSL_R_BAD_RESPONSE_ARGUMENT), "bad response argument"}, + {ERR_REASON(SSL_R_BAD_RSA_DECRYPT), "bad rsa decrypt"}, + {ERR_REASON(SSL_R_BAD_RSA_ENCRYPT), "bad rsa encrypt"}, + {ERR_REASON(SSL_R_BAD_RSA_E_LENGTH), "bad rsa e length"}, + {ERR_REASON(SSL_R_BAD_RSA_MODULUS_LENGTH), "bad rsa modulus length"}, + {ERR_REASON(SSL_R_BAD_RSA_SIGNATURE), "bad rsa signature"}, + {ERR_REASON(SSL_R_BAD_SIGNATURE), "bad signature"}, + {ERR_REASON(SSL_R_BAD_SRP_A_LENGTH), "bad srp a length"}, + {ERR_REASON(SSL_R_BAD_SRP_B_LENGTH), "bad srp b length"}, + {ERR_REASON(SSL_R_BAD_SRP_G_LENGTH), "bad srp g length"}, + {ERR_REASON(SSL_R_BAD_SRP_N_LENGTH), "bad srp n length"}, + {ERR_REASON(SSL_R_BAD_SRP_PARAMETERS), "bad srp parameters"}, + {ERR_REASON(SSL_R_BAD_SRP_S_LENGTH), "bad srp s length"}, + {ERR_REASON(SSL_R_BAD_SRTP_MKI_VALUE), "bad srtp mki value"}, + {ERR_REASON(SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST), + "bad srtp protection profile list"}, + {ERR_REASON(SSL_R_BAD_SSL_FILETYPE), "bad ssl filetype"}, + {ERR_REASON(SSL_R_BAD_SSL_SESSION_ID_LENGTH), + "bad ssl session id length"}, + {ERR_REASON(SSL_R_BAD_STATE), "bad state"}, + {ERR_REASON(SSL_R_BAD_WRITE_RETRY), "bad write retry"}, + {ERR_REASON(SSL_R_BIO_NOT_SET), "bio not set"}, + {ERR_REASON(SSL_R_BLOCK_CIPHER_PAD_IS_WRONG), + "block cipher pad is wrong"}, + {ERR_REASON(SSL_R_BN_LIB), "bn lib"}, + {ERR_REASON(SSL_R_CA_DN_LENGTH_MISMATCH), "ca dn length mismatch"}, + {ERR_REASON(SSL_R_CA_DN_TOO_LONG), "ca dn too long"}, + {ERR_REASON(SSL_R_CCS_RECEIVED_EARLY), "ccs received early"}, + {ERR_REASON(SSL_R_CERTIFICATE_VERIFY_FAILED), + "certificate verify failed"}, + {ERR_REASON(SSL_R_CERT_LENGTH_MISMATCH), "cert length mismatch"}, + {ERR_REASON(SSL_R_CHALLENGE_IS_DIFFERENT), "challenge is different"}, + {ERR_REASON(SSL_R_CIPHER_CODE_WRONG_LENGTH), "cipher code wrong length"}, + {ERR_REASON(SSL_R_CIPHER_OR_HASH_UNAVAILABLE), + "cipher or hash unavailable"}, + {ERR_REASON(SSL_R_CIPHER_TABLE_SRC_ERROR), "cipher table src error"}, + {ERR_REASON(SSL_R_CLIENTHELLO_TLSEXT), "clienthello tlsext"}, + {ERR_REASON(SSL_R_COMPRESSED_LENGTH_TOO_LONG), + "compressed length too long"}, + {ERR_REASON(SSL_R_COMPRESSION_DISABLED), "compression disabled"}, + {ERR_REASON(SSL_R_COMPRESSION_FAILURE), "compression failure"}, + {ERR_REASON(SSL_R_COMPRESSION_ID_NOT_WITHIN_PRIVATE_RANGE), + "compression id not within private range"}, + {ERR_REASON(SSL_R_COMPRESSION_LIBRARY_ERROR), + "compression library error"}, + {ERR_REASON(SSL_R_CONNECTION_ID_IS_DIFFERENT), + "connection id is different"}, + {ERR_REASON(SSL_R_CONNECTION_TYPE_NOT_SET), "connection type not set"}, + {ERR_REASON(SSL_R_COOKIE_MISMATCH), "cookie mismatch"}, + {ERR_REASON(SSL_R_DATA_BETWEEN_CCS_AND_FINISHED), + "data between ccs and finished"}, + {ERR_REASON(SSL_R_DATA_LENGTH_TOO_LONG), "data length too long"}, + {ERR_REASON(SSL_R_DECRYPTION_FAILED), "decryption failed"}, + {ERR_REASON(SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC), + "decryption failed or bad record mac"}, + {ERR_REASON(SSL_R_DH_KEY_TOO_SMALL), "dh key too small"}, + {ERR_REASON(SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG), + "dh public value length is wrong"}, + {ERR_REASON(SSL_R_DIGEST_CHECK_FAILED), "digest check failed"}, + {ERR_REASON(SSL_R_DTLS_MESSAGE_TOO_BIG), "dtls message too big"}, + {ERR_REASON(SSL_R_DUPLICATE_COMPRESSION_ID), "duplicate compression id"}, + {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT), + "ecc cert not for key agreement"}, + {ERR_REASON(SSL_R_ECC_CERT_NOT_FOR_SIGNING), "ecc cert not for signing"}, + {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE), + "ecc cert should have rsa signature"}, + {ERR_REASON(SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE), + "ecc cert should have sha1 signature"}, + {ERR_REASON(SSL_R_ECGROUP_TOO_LARGE_FOR_CIPHER), + "ecgroup too large for cipher"}, + {ERR_REASON(SSL_R_EMPTY_SRTP_PROTECTION_PROFILE_LIST), + "empty srtp protection profile list"}, + {ERR_REASON(SSL_R_ENCRYPTED_LENGTH_TOO_LONG), + "encrypted length too long"}, + {ERR_REASON(SSL_R_ERROR_GENERATING_TMP_RSA_KEY), + "error generating tmp rsa key"}, + {ERR_REASON(SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST), + "error in received cipher list"}, + {ERR_REASON(SSL_R_EXCESSIVE_MESSAGE_SIZE), "excessive message size"}, + {ERR_REASON(SSL_R_EXTRA_DATA_IN_MESSAGE), "extra data in message"}, + {ERR_REASON(SSL_R_GOT_A_FIN_BEFORE_A_CCS), "got a fin before a ccs"}, + {ERR_REASON(SSL_R_GOT_NEXT_PROTO_BEFORE_A_CCS), + "got next proto before a ccs"}, + {ERR_REASON(SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION), + "got next proto without seeing extension"}, + {ERR_REASON(SSL_R_HTTPS_PROXY_REQUEST), "https proxy request"}, + {ERR_REASON(SSL_R_HTTP_REQUEST), "http request"}, + {ERR_REASON(SSL_R_ILLEGAL_PADDING), "illegal padding"}, + {ERR_REASON(SSL_R_INAPPROPRIATE_FALLBACK), "inappropriate fallback"}, + {ERR_REASON(SSL_R_INCONSISTENT_COMPRESSION), "inconsistent compression"}, + {ERR_REASON(SSL_R_INVALID_CHALLENGE_LENGTH), "invalid challenge length"}, + {ERR_REASON(SSL_R_INVALID_COMMAND), "invalid command"}, + {ERR_REASON(SSL_R_INVALID_COMPRESSION_ALGORITHM), + "invalid compression algorithm"}, + {ERR_REASON(SSL_R_INVALID_PURPOSE), "invalid purpose"}, + {ERR_REASON(SSL_R_INVALID_SRP_USERNAME), "invalid srp username"}, + {ERR_REASON(SSL_R_INVALID_STATUS_RESPONSE), "invalid status response"}, + {ERR_REASON(SSL_R_INVALID_TICKET_KEYS_LENGTH), + "invalid ticket keys length"}, + {ERR_REASON(SSL_R_INVALID_TRUST), "invalid trust"}, + {ERR_REASON(SSL_R_KEY_ARG_TOO_LONG), "key arg too long"}, + {ERR_REASON(SSL_R_KRB5), "krb5"}, + {ERR_REASON(SSL_R_KRB5_C_CC_PRINC), "krb5 client cc principal (no tkt?)"}, + {ERR_REASON(SSL_R_KRB5_C_GET_CRED), "krb5 client get cred"}, + {ERR_REASON(SSL_R_KRB5_C_INIT), "krb5 client init"}, + {ERR_REASON(SSL_R_KRB5_C_MK_REQ), "krb5 client mk_req (expired tkt?)"}, + {ERR_REASON(SSL_R_KRB5_S_BAD_TICKET), "krb5 server bad ticket"}, + {ERR_REASON(SSL_R_KRB5_S_INIT), "krb5 server init"}, + {ERR_REASON(SSL_R_KRB5_S_RD_REQ), "krb5 server rd_req (keytab perms?)"}, + {ERR_REASON(SSL_R_KRB5_S_TKT_EXPIRED), "krb5 server tkt expired"}, + {ERR_REASON(SSL_R_KRB5_S_TKT_NYV), "krb5 server tkt not yet valid"}, + {ERR_REASON(SSL_R_KRB5_S_TKT_SKEW), "krb5 server tkt skew"}, + {ERR_REASON(SSL_R_LENGTH_MISMATCH), "length mismatch"}, + {ERR_REASON(SSL_R_LENGTH_TOO_SHORT), "length too short"}, + {ERR_REASON(SSL_R_LIBRARY_BUG), "library bug"}, + {ERR_REASON(SSL_R_LIBRARY_HAS_NO_CIPHERS), "library has no ciphers"}, + {ERR_REASON(SSL_R_MESSAGE_TOO_LONG), "message too long"}, + {ERR_REASON(SSL_R_MISSING_DH_DSA_CERT), "missing dh dsa cert"}, + {ERR_REASON(SSL_R_MISSING_DH_KEY), "missing dh key"}, + {ERR_REASON(SSL_R_MISSING_DH_RSA_CERT), "missing dh rsa cert"}, + {ERR_REASON(SSL_R_MISSING_DSA_SIGNING_CERT), "missing dsa signing cert"}, + {ERR_REASON(SSL_R_MISSING_EXPORT_TMP_DH_KEY), + "missing export tmp dh key"}, + {ERR_REASON(SSL_R_MISSING_EXPORT_TMP_RSA_KEY), + "missing export tmp rsa key"}, + {ERR_REASON(SSL_R_MISSING_RSA_CERTIFICATE), "missing rsa certificate"}, + {ERR_REASON(SSL_R_MISSING_RSA_ENCRYPTING_CERT), + "missing rsa encrypting cert"}, + {ERR_REASON(SSL_R_MISSING_RSA_SIGNING_CERT), "missing rsa signing cert"}, + {ERR_REASON(SSL_R_MISSING_SRP_PARAM), "can't find SRP server param"}, + {ERR_REASON(SSL_R_MISSING_TMP_DH_KEY), "missing tmp dh key"}, + {ERR_REASON(SSL_R_MISSING_TMP_ECDH_KEY), "missing tmp ecdh key"}, + {ERR_REASON(SSL_R_MISSING_TMP_RSA_KEY), "missing tmp rsa key"}, + {ERR_REASON(SSL_R_MISSING_TMP_RSA_PKEY), "missing tmp rsa pkey"}, + {ERR_REASON(SSL_R_MISSING_VERIFY_MESSAGE), "missing verify message"}, + {ERR_REASON(SSL_R_MULTIPLE_SGC_RESTARTS), "multiple sgc restarts"}, + {ERR_REASON(SSL_R_NON_SSLV2_INITIAL_PACKET), "non sslv2 initial packet"}, + {ERR_REASON(SSL_R_NO_CERTIFICATES_RETURNED), "no certificates returned"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_ASSIGNED), "no certificate assigned"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_RETURNED), "no certificate returned"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_SET), "no certificate set"}, + {ERR_REASON(SSL_R_NO_CERTIFICATE_SPECIFIED), "no certificate specified"}, + {ERR_REASON(SSL_R_NO_CIPHERS_AVAILABLE), "no ciphers available"}, + {ERR_REASON(SSL_R_NO_CIPHERS_PASSED), "no ciphers passed"}, + {ERR_REASON(SSL_R_NO_CIPHERS_SPECIFIED), "no ciphers specified"}, + {ERR_REASON(SSL_R_NO_CIPHER_LIST), "no cipher list"}, + {ERR_REASON(SSL_R_NO_CIPHER_MATCH), "no cipher match"}, + {ERR_REASON(SSL_R_NO_CLIENT_CERT_METHOD), "no client cert method"}, + {ERR_REASON(SSL_R_NO_CLIENT_CERT_RECEIVED), "no client cert received"}, + {ERR_REASON(SSL_R_NO_COMPRESSION_SPECIFIED), "no compression specified"}, + {ERR_REASON(SSL_R_NO_GOST_CERTIFICATE_SENT_BY_PEER), + "Peer haven't sent GOST certificate, required for selected ciphersuite"}, + {ERR_REASON(SSL_R_NO_METHOD_SPECIFIED), "no method specified"}, + {ERR_REASON(SSL_R_NO_PRIVATEKEY), "no privatekey"}, + {ERR_REASON(SSL_R_NO_PRIVATE_KEY_ASSIGNED), "no private key assigned"}, + {ERR_REASON(SSL_R_NO_PROTOCOLS_AVAILABLE), "no protocols available"}, + {ERR_REASON(SSL_R_NO_PUBLICKEY), "no publickey"}, + {ERR_REASON(SSL_R_NO_RENEGOTIATION), "no renegotiation"}, + {ERR_REASON(SSL_R_NO_REQUIRED_DIGEST), + "digest requred for handshake isn't computed"}, + {ERR_REASON(SSL_R_NO_SHARED_CIPHER), "no shared cipher"}, + {ERR_REASON(SSL_R_NO_SRTP_PROFILES), "no srtp profiles"}, + {ERR_REASON(SSL_R_NO_VERIFY_CALLBACK), "no verify callback"}, + {ERR_REASON(SSL_R_NULL_SSL_CTX), "null ssl ctx"}, + {ERR_REASON(SSL_R_NULL_SSL_METHOD_PASSED), "null ssl method passed"}, + {ERR_REASON(SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED), + "old session cipher not returned"}, + {ERR_REASON(SSL_R_OLD_SESSION_COMPRESSION_ALGORITHM_NOT_RETURNED), + "old session compression algorithm not returned"}, + {ERR_REASON(SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE), + "only tls allowed in fips mode"}, + {ERR_REASON(SSL_R_OPAQUE_PRF_INPUT_TOO_LONG), + "opaque PRF input too long"}, + {ERR_REASON(SSL_R_PACKET_LENGTH_TOO_LONG), "packet length too long"}, + {ERR_REASON(SSL_R_PARSE_TLSEXT), "parse tlsext"}, + {ERR_REASON(SSL_R_PATH_TOO_LONG), "path too long"}, + {ERR_REASON(SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE), + "peer did not return a certificate"}, + {ERR_REASON(SSL_R_PEER_ERROR), "peer error"}, + {ERR_REASON(SSL_R_PEER_ERROR_CERTIFICATE), "peer error certificate"}, + {ERR_REASON(SSL_R_PEER_ERROR_NO_CERTIFICATE), + "peer error no certificate"}, + {ERR_REASON(SSL_R_PEER_ERROR_NO_CIPHER), "peer error no cipher"}, + {ERR_REASON(SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE), + "peer error unsupported certificate type"}, + {ERR_REASON(SSL_R_PRE_MAC_LENGTH_TOO_LONG), "pre mac length too long"}, + {ERR_REASON(SSL_R_PROBLEMS_MAPPING_CIPHER_FUNCTIONS), + "problems mapping cipher functions"}, + {ERR_REASON(SSL_R_PROTOCOL_IS_SHUTDOWN), "protocol is shutdown"}, + {ERR_REASON(SSL_R_PSK_IDENTITY_NOT_FOUND), "psk identity not found"}, + {ERR_REASON(SSL_R_PSK_NO_CLIENT_CB), "psk no client cb"}, + {ERR_REASON(SSL_R_PSK_NO_SERVER_CB), "psk no server cb"}, + {ERR_REASON(SSL_R_PUBLIC_KEY_ENCRYPT_ERROR), "public key encrypt error"}, + {ERR_REASON(SSL_R_PUBLIC_KEY_IS_NOT_RSA), "public key is not rsa"}, + {ERR_REASON(SSL_R_PUBLIC_KEY_NOT_RSA), "public key not rsa"}, + {ERR_REASON(SSL_R_READ_BIO_NOT_SET), "read bio not set"}, + {ERR_REASON(SSL_R_READ_TIMEOUT_EXPIRED), "read timeout expired"}, + {ERR_REASON(SSL_R_READ_WRONG_PACKET_TYPE), "read wrong packet type"}, + {ERR_REASON(SSL_R_RECORD_LENGTH_MISMATCH), "record length mismatch"}, + {ERR_REASON(SSL_R_RECORD_TOO_LARGE), "record too large"}, + {ERR_REASON(SSL_R_RECORD_TOO_SMALL), "record too small"}, + {ERR_REASON(SSL_R_RENEGOTIATE_EXT_TOO_LONG), "renegotiate ext too long"}, + {ERR_REASON(SSL_R_RENEGOTIATION_ENCODING_ERR), + "renegotiation encoding err"}, + {ERR_REASON(SSL_R_RENEGOTIATION_MISMATCH), "renegotiation mismatch"}, + {ERR_REASON(SSL_R_REQUIRED_CIPHER_MISSING), "required cipher missing"}, + {ERR_REASON(SSL_R_REQUIRED_COMPRESSSION_ALGORITHM_MISSING), + "required compresssion algorithm missing"}, + {ERR_REASON(SSL_R_REUSE_CERT_LENGTH_NOT_ZERO), + "reuse cert length not zero"}, + {ERR_REASON(SSL_R_REUSE_CERT_TYPE_NOT_ZERO), "reuse cert type not zero"}, + {ERR_REASON(SSL_R_REUSE_CIPHER_LIST_NOT_ZERO), + "reuse cipher list not zero"}, + {ERR_REASON(SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING), + "scsv received when renegotiating"}, + {ERR_REASON(SSL_R_SERVERHELLO_TLSEXT), "serverhello tlsext"}, + {ERR_REASON(SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED), + "session id context uninitialized"}, + {ERR_REASON(SSL_R_SHORT_READ), "short read"}, + {ERR_REASON(SSL_R_SIGNATURE_ALGORITHMS_ERROR), + "signature algorithms error"}, + {ERR_REASON(SSL_R_SIGNATURE_FOR_NON_SIGNING_CERTIFICATE), + "signature for non signing certificate"}, + {ERR_REASON(SSL_R_SRP_A_CALC), "error with the srp params"}, + {ERR_REASON(SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES), + "srtp could not allocate profiles"}, + {ERR_REASON(SSL_R_SRTP_PROTECTION_PROFILE_LIST_TOO_LONG), + "srtp protection profile list too long"}, + {ERR_REASON(SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE), + "srtp unknown protection profile"}, + {ERR_REASON(SSL_R_SSL23_DOING_SESSION_ID_REUSE), + "ssl23 doing session id reuse"}, + {ERR_REASON(SSL_R_SSL2_CONNECTION_ID_TOO_LONG), + "ssl2 connection id too long"}, + {ERR_REASON(SSL_R_SSL3_EXT_INVALID_ECPOINTFORMAT), + "ssl3 ext invalid ecpointformat"}, + {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME), + "ssl3 ext invalid servername"}, + {ERR_REASON(SSL_R_SSL3_EXT_INVALID_SERVERNAME_TYPE), + "ssl3 ext invalid servername type"}, + {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_LONG), "ssl3 session id too long"}, + {ERR_REASON(SSL_R_SSL3_SESSION_ID_TOO_SHORT), + "ssl3 session id too short"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_CERTIFICATE), + "sslv3 alert bad certificate"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_BAD_RECORD_MAC), + "sslv3 alert bad record mac"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED), + "sslv3 alert certificate expired"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED), + "sslv3 alert certificate revoked"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN), + "sslv3 alert certificate unknown"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE), + "sslv3 alert decompression failure"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE), + "sslv3 alert handshake failure"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER), + "sslv3 alert illegal parameter"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_NO_CERTIFICATE), + "sslv3 alert no certificate"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE), + "sslv3 alert unexpected message"}, + {ERR_REASON(SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE), + "sslv3 alert unsupported certificate"}, + {ERR_REASON(SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION), + "ssl ctx has no default ssl version"}, + {ERR_REASON(SSL_R_SSL_HANDSHAKE_FAILURE), "ssl handshake failure"}, + {ERR_REASON(SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS), + "ssl library has no ciphers"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_CALLBACK_FAILED), + "ssl session id callback failed"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_CONFLICT), "ssl session id conflict"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG), + "ssl session id context too long"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH), + "ssl session id has bad length"}, + {ERR_REASON(SSL_R_SSL_SESSION_ID_IS_DIFFERENT), + "ssl session id is different"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_ACCESS_DENIED), + "tlsv1 alert access denied"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_DECODE_ERROR), "tlsv1 alert decode error"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPTION_FAILED), + "tlsv1 alert decryption failed"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_DECRYPT_ERROR), + "tlsv1 alert decrypt error"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION), + "tlsv1 alert export restriction"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK), + "tlsv1 alert inappropriate fallback"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY), + "tlsv1 alert insufficient security"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_INTERNAL_ERROR), + "tlsv1 alert internal error"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION), + "tlsv1 alert no renegotiation"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_PROTOCOL_VERSION), + "tlsv1 alert protocol version"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_RECORD_OVERFLOW), + "tlsv1 alert record overflow"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_UNKNOWN_CA), "tlsv1 alert unknown ca"}, + {ERR_REASON(SSL_R_TLSV1_ALERT_USER_CANCELLED), + "tlsv1 alert user cancelled"}, + {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE), + "tlsv1 bad certificate hash value"}, + {ERR_REASON(SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE), + "tlsv1 bad certificate status response"}, + {ERR_REASON(SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE), + "tlsv1 certificate unobtainable"}, + {ERR_REASON(SSL_R_TLSV1_UNRECOGNIZED_NAME), "tlsv1 unrecognized name"}, + {ERR_REASON(SSL_R_TLSV1_UNSUPPORTED_EXTENSION), + "tlsv1 unsupported extension"}, + {ERR_REASON(SSL_R_TLS_CLIENT_CERT_REQ_WITH_ANON_CIPHER), + "tls client cert req with anon cipher"}, + {ERR_REASON(SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT), + "peer does not accept heartbeats"}, + {ERR_REASON(SSL_R_TLS_HEARTBEAT_PENDING), + "heartbeat request already pending"}, + {ERR_REASON(SSL_R_TLS_ILLEGAL_EXPORTER_LABEL), + "tls illegal exporter label"}, + {ERR_REASON(SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST), + "tls invalid ecpointformat list"}, + {ERR_REASON(SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST), + "tls peer did not respond with certificate list"}, + {ERR_REASON(SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG), + "tls rsa encrypted value length is wrong"}, + {ERR_REASON(SSL_R_TRIED_TO_USE_UNSUPPORTED_CIPHER), + "tried to use unsupported cipher"}, + {ERR_REASON(SSL_R_UNABLE_TO_DECODE_DH_CERTS), + "unable to decode dh certs"}, + {ERR_REASON(SSL_R_UNABLE_TO_DECODE_ECDH_CERTS), + "unable to decode ecdh certs"}, + {ERR_REASON(SSL_R_UNABLE_TO_EXTRACT_PUBLIC_KEY), + "unable to extract public key"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_DH_PARAMETERS), + "unable to find dh parameters"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS), + "unable to find ecdh parameters"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_PUBLIC_KEY_PARAMETERS), + "unable to find public key parameters"}, + {ERR_REASON(SSL_R_UNABLE_TO_FIND_SSL_METHOD), + "unable to find ssl method"}, + {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES), + "unable to load ssl2 md5 routines"}, + {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES), + "unable to load ssl3 md5 routines"}, + {ERR_REASON(SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES), + "unable to load ssl3 sha1 routines"}, + {ERR_REASON(SSL_R_UNEXPECTED_MESSAGE), "unexpected message"}, + {ERR_REASON(SSL_R_UNEXPECTED_RECORD), "unexpected record"}, + {ERR_REASON(SSL_R_UNINITIALIZED), "uninitialized"}, + {ERR_REASON(SSL_R_UNKNOWN_ALERT_TYPE), "unknown alert type"}, + {ERR_REASON(SSL_R_UNKNOWN_CERTIFICATE_TYPE), "unknown certificate type"}, + {ERR_REASON(SSL_R_UNKNOWN_CIPHER_RETURNED), "unknown cipher returned"}, + {ERR_REASON(SSL_R_UNKNOWN_CIPHER_TYPE), "unknown cipher type"}, + {ERR_REASON(SSL_R_UNKNOWN_DIGEST), "unknown digest"}, + {ERR_REASON(SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE), + "unknown key exchange type"}, + {ERR_REASON(SSL_R_UNKNOWN_PKEY_TYPE), "unknown pkey type"}, + {ERR_REASON(SSL_R_UNKNOWN_PROTOCOL), "unknown protocol"}, + {ERR_REASON(SSL_R_UNKNOWN_REMOTE_ERROR_TYPE), + "unknown remote error type"}, + {ERR_REASON(SSL_R_UNKNOWN_SSL_VERSION), "unknown ssl version"}, + {ERR_REASON(SSL_R_UNKNOWN_STATE), "unknown state"}, + {ERR_REASON(SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED), + "unsafe legacy renegotiation disabled"}, + {ERR_REASON(SSL_R_UNSUPPORTED_CIPHER), "unsupported cipher"}, + {ERR_REASON(SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM), + "unsupported compression algorithm"}, + {ERR_REASON(SSL_R_UNSUPPORTED_DIGEST_TYPE), "unsupported digest type"}, + {ERR_REASON(SSL_R_UNSUPPORTED_ELLIPTIC_CURVE), + "unsupported elliptic curve"}, + {ERR_REASON(SSL_R_UNSUPPORTED_PROTOCOL), "unsupported protocol"}, + {ERR_REASON(SSL_R_UNSUPPORTED_SSL_VERSION), "unsupported ssl version"}, + {ERR_REASON(SSL_R_UNSUPPORTED_STATUS_TYPE), "unsupported status type"}, + {ERR_REASON(SSL_R_USE_SRTP_NOT_NEGOTIATED), "use srtp not negotiated"}, + {ERR_REASON(SSL_R_WRITE_BIO_NOT_SET), "write bio not set"}, + {ERR_REASON(SSL_R_WRONG_CIPHER_RETURNED), "wrong cipher returned"}, + {ERR_REASON(SSL_R_WRONG_MESSAGE_TYPE), "wrong message type"}, + {ERR_REASON(SSL_R_WRONG_NUMBER_OF_KEY_BITS), "wrong number of key bits"}, + {ERR_REASON(SSL_R_WRONG_SIGNATURE_LENGTH), "wrong signature length"}, + {ERR_REASON(SSL_R_WRONG_SIGNATURE_SIZE), "wrong signature size"}, + {ERR_REASON(SSL_R_WRONG_SIGNATURE_TYPE), "wrong signature type"}, + {ERR_REASON(SSL_R_WRONG_SSL_VERSION), "wrong ssl version"}, + {ERR_REASON(SSL_R_WRONG_VERSION_NUMBER), "wrong version number"}, + {ERR_REASON(SSL_R_X509_LIB), "x509 lib"}, + {ERR_REASON(SSL_R_X509_VERIFICATION_SETUP_PROBLEMS), + "x509 verification setup problems"}, + {0, NULL} +}; + +#endif + +void ERR_load_SSL_strings(void) +{ +#ifndef OPENSSL_NO_ERR + + if (ERR_func_error_string(SSL_str_functs[0].error) == NULL) { + ERR_load_strings(0, SSL_str_functs); + ERR_load_strings(0, SSL_str_reasons); + } +#endif +} diff --git a/libs/openssl/ssl/ssl_err2.c b/libs/openssl/ssl/ssl_err2.c new file mode 100644 index 00000000..14e48221 --- /dev/null +++ b/libs/openssl/ssl/ssl_err2.c @@ -0,0 +1,69 @@ +/* ssl/ssl_err2.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include + +void SSL_load_error_strings(void) +{ +#ifndef OPENSSL_NO_ERR + ERR_load_crypto_strings(); + ERR_load_SSL_strings(); +#endif +} diff --git a/libs/openssl/ssl/ssl_lib.c b/libs/openssl/ssl/ssl_lib.c new file mode 100644 index 00000000..33c52ac5 --- /dev/null +++ b/libs/openssl/ssl/ssl_lib.c @@ -0,0 +1,3325 @@ +/* + * ! \file ssl/ssl_lib.c \brief Version independent SSL functions. + */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. + * ECC cipher suite support in OpenSSL originally developed by + * SUN MICROSYSTEMS, INC., and contributed to the OpenSSL project. + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#ifdef REF_CHECK +# include +#endif +#include +#include "ssl_locl.h" +#include "kssl_lcl.h" +#include +#include +#include +#include +#include +#ifndef OPENSSL_NO_DH +# include +#endif +#ifndef OPENSSL_NO_ENGINE +# include +#endif + +const char *SSL_version_str = OPENSSL_VERSION_TEXT; + +SSL3_ENC_METHOD ssl3_undef_enc_method = { + /* + * evil casts, but these functions are only called if there's a library + * bug + */ + (int (*)(SSL *, int))ssl_undefined_function, + (int (*)(SSL *, unsigned char *, int))ssl_undefined_function, + ssl_undefined_function, + (int (*)(SSL *, unsigned char *, unsigned char *, int)) + ssl_undefined_function, + (int (*)(SSL *, int))ssl_undefined_function, + (int (*)(SSL *, const char *, int, unsigned char *)) + ssl_undefined_function, + 0, /* finish_mac_length */ + (int (*)(SSL *, int, unsigned char *))ssl_undefined_function, + NULL, /* client_finished_label */ + 0, /* client_finished_label_len */ + NULL, /* server_finished_label */ + 0, /* server_finished_label_len */ + (int (*)(int))ssl_undefined_function, + (int (*)(SSL *, unsigned char *, size_t, const char *, + size_t, const unsigned char *, size_t, + int use_context))ssl_undefined_function, +}; + +int SSL_clear(SSL *s) +{ + + if (s->method == NULL) { + SSLerr(SSL_F_SSL_CLEAR, SSL_R_NO_METHOD_SPECIFIED); + return (0); + } + + if (ssl_clear_bad_session(s)) { + SSL_SESSION_free(s->session); + s->session = NULL; + } + + s->error = 0; + s->hit = 0; + s->shutdown = 0; + +#if 0 + /* + * Disabled since version 1.10 of this file (early return not + * needed because SSL_clear is not called when doing renegotiation) + */ + /* + * This is set if we are doing dynamic renegotiation so keep + * the old cipher. It is sort of a SSL_clear_lite :-) + */ + if (s->renegotiate) + return (1); +#else + if (s->renegotiate) { + SSLerr(SSL_F_SSL_CLEAR, ERR_R_INTERNAL_ERROR); + return 0; + } +#endif + + s->type = 0; + + s->state = SSL_ST_BEFORE | ((s->server) ? SSL_ST_ACCEPT : SSL_ST_CONNECT); + + s->version = s->method->version; + s->client_version = s->version; + s->rwstate = SSL_NOTHING; + s->rstate = SSL_ST_READ_HEADER; +#if 0 + s->read_ahead = s->ctx->read_ahead; +#endif + + if (s->init_buf != NULL) { + BUF_MEM_free(s->init_buf); + s->init_buf = NULL; + } + + ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); + + s->first_packet = 0; + +#if 1 + /* + * Check to see if we were changed into a different method, if so, revert + * back if we are not doing session-id reuse. + */ + if (!s->in_handshake && (s->session == NULL) + && (s->method != s->ctx->method)) { + s->method->ssl_free(s); + s->method = s->ctx->method; + if (!s->method->ssl_new(s)) + return (0); + } else +#endif + s->method->ssl_clear(s); + return (1); +} + +/** Used to change an SSL_CTXs default SSL method type */ +int SSL_CTX_set_ssl_version(SSL_CTX *ctx, const SSL_METHOD *meth) +{ + STACK_OF(SSL_CIPHER) *sk; + + ctx->method = meth; + + sk = ssl_create_cipher_list(ctx->method, &(ctx->cipher_list), + &(ctx->cipher_list_by_id), + meth->version == + SSL2_VERSION ? "SSLv2" : + SSL_DEFAULT_CIPHER_LIST); + if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) { + SSLerr(SSL_F_SSL_CTX_SET_SSL_VERSION, + SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS); + return (0); + } + return (1); +} + +SSL *SSL_new(SSL_CTX *ctx) +{ + SSL *s; + + if (ctx == NULL) { + SSLerr(SSL_F_SSL_NEW, SSL_R_NULL_SSL_CTX); + return (NULL); + } + if (ctx->method == NULL) { + SSLerr(SSL_F_SSL_NEW, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION); + return (NULL); + } + + s = (SSL *)OPENSSL_malloc(sizeof(SSL)); + if (s == NULL) + goto err; + memset(s, 0, sizeof(SSL)); + +#ifndef OPENSSL_NO_KRB5 + s->kssl_ctx = kssl_ctx_new(); +#endif /* OPENSSL_NO_KRB5 */ + + s->options = ctx->options; + s->mode = ctx->mode; + s->max_cert_list = ctx->max_cert_list; + s->references = 1; + + if (ctx->cert != NULL) { + /* + * Earlier library versions used to copy the pointer to the CERT, not + * its contents; only when setting new parameters for the per-SSL + * copy, ssl_cert_new would be called (and the direct reference to + * the per-SSL_CTX settings would be lost, but those still were + * indirectly accessed for various purposes, and for that reason they + * used to be known as s->ctx->default_cert). Now we don't look at the + * SSL_CTX's CERT after having duplicated it once. + */ + + s->cert = ssl_cert_dup(ctx->cert); + if (s->cert == NULL) + goto err; + } else + s->cert = NULL; /* Cannot really happen (see SSL_CTX_new) */ + + s->read_ahead = ctx->read_ahead; + s->msg_callback = ctx->msg_callback; + s->msg_callback_arg = ctx->msg_callback_arg; + s->verify_mode = ctx->verify_mode; +#if 0 + s->verify_depth = ctx->verify_depth; +#endif + s->sid_ctx_length = ctx->sid_ctx_length; + OPENSSL_assert(s->sid_ctx_length <= sizeof s->sid_ctx); + memcpy(&s->sid_ctx, &ctx->sid_ctx, sizeof(s->sid_ctx)); + s->verify_callback = ctx->default_verify_callback; + s->generate_session_id = ctx->generate_session_id; + + s->param = X509_VERIFY_PARAM_new(); + if (!s->param) + goto err; + X509_VERIFY_PARAM_inherit(s->param, ctx->param); +#if 0 + s->purpose = ctx->purpose; + s->trust = ctx->trust; +#endif + s->quiet_shutdown = ctx->quiet_shutdown; + s->max_send_fragment = ctx->max_send_fragment; + + CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); + s->ctx = ctx; +#ifndef OPENSSL_NO_TLSEXT + s->tlsext_debug_cb = 0; + s->tlsext_debug_arg = NULL; + s->tlsext_ticket_expected = 0; + s->tlsext_status_type = -1; + s->tlsext_status_expected = 0; + s->tlsext_ocsp_ids = NULL; + s->tlsext_ocsp_exts = NULL; + s->tlsext_ocsp_resp = NULL; + s->tlsext_ocsp_resplen = -1; + CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); + s->initial_ctx = ctx; +# ifndef OPENSSL_NO_NEXTPROTONEG + s->next_proto_negotiated = NULL; +# endif +#endif + + s->verify_result = X509_V_OK; + + s->method = ctx->method; + + if (!s->method->ssl_new(s)) + goto err; + + s->server = (ctx->method->ssl_accept == ssl_undefined_function) ? 0 : 1; + + SSL_clear(s); + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); + +#ifndef OPENSSL_NO_PSK + s->psk_client_callback = ctx->psk_client_callback; + s->psk_server_callback = ctx->psk_server_callback; +#endif + + return (s); + err: + if (s != NULL) + SSL_free(s); + SSLerr(SSL_F_SSL_NEW, ERR_R_MALLOC_FAILURE); + return (NULL); +} + +int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const unsigned char *sid_ctx, + unsigned int sid_ctx_len) +{ + if (sid_ctx_len > sizeof ctx->sid_ctx) { + SSLerr(SSL_F_SSL_CTX_SET_SESSION_ID_CONTEXT, + SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + ctx->sid_ctx_length = sid_ctx_len; + memcpy(ctx->sid_ctx, sid_ctx, sid_ctx_len); + + return 1; +} + +int SSL_set_session_id_context(SSL *ssl, const unsigned char *sid_ctx, + unsigned int sid_ctx_len) +{ + if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { + SSLerr(SSL_F_SSL_SET_SESSION_ID_CONTEXT, + SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + ssl->sid_ctx_length = sid_ctx_len; + memcpy(ssl->sid_ctx, sid_ctx, sid_ctx_len); + + return 1; +} + +int SSL_CTX_set_generate_session_id(SSL_CTX *ctx, GEN_SESSION_CB cb) +{ + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + ctx->generate_session_id = cb; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + return 1; +} + +int SSL_set_generate_session_id(SSL *ssl, GEN_SESSION_CB cb) +{ + CRYPTO_w_lock(CRYPTO_LOCK_SSL); + ssl->generate_session_id = cb; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL); + return 1; +} + +int SSL_has_matching_session_id(const SSL *ssl, const unsigned char *id, + unsigned int id_len) +{ + /* + * A quick examination of SSL_SESSION_hash and SSL_SESSION_cmp shows how + * we can "construct" a session to give us the desired check - ie. to + * find if there's a session in the hash table that would conflict with + * any new session built out of this id/id_len and the ssl_version in use + * by this SSL. + */ + SSL_SESSION r, *p; + + if (id_len > sizeof r.session_id) + return 0; + + r.ssl_version = ssl->version; + r.session_id_length = id_len; + memcpy(r.session_id, id, id_len); + /* + * NB: SSLv2 always uses a fixed 16-byte session ID, so even if a + * callback is calling us to check the uniqueness of a shorter ID, it + * must be compared as a padded-out ID because that is what it will be + * converted to when the callback has finished choosing it. + */ + if ((r.ssl_version == SSL2_VERSION) && + (id_len < SSL2_SSL_SESSION_ID_LENGTH)) { + memset(r.session_id + id_len, 0, SSL2_SSL_SESSION_ID_LENGTH - id_len); + r.session_id_length = SSL2_SSL_SESSION_ID_LENGTH; + } + + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + p = lh_SSL_SESSION_retrieve(ssl->ctx->sessions, &r); + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + return (p != NULL); +} + +int SSL_CTX_set_purpose(SSL_CTX *s, int purpose) +{ + return X509_VERIFY_PARAM_set_purpose(s->param, purpose); +} + +int SSL_set_purpose(SSL *s, int purpose) +{ + return X509_VERIFY_PARAM_set_purpose(s->param, purpose); +} + +int SSL_CTX_set_trust(SSL_CTX *s, int trust) +{ + return X509_VERIFY_PARAM_set_trust(s->param, trust); +} + +int SSL_set_trust(SSL *s, int trust) +{ + return X509_VERIFY_PARAM_set_trust(s->param, trust); +} + +int SSL_CTX_set1_param(SSL_CTX *ctx, X509_VERIFY_PARAM *vpm) +{ + return X509_VERIFY_PARAM_set1(ctx->param, vpm); +} + +int SSL_set1_param(SSL *ssl, X509_VERIFY_PARAM *vpm) +{ + return X509_VERIFY_PARAM_set1(ssl->param, vpm); +} + +void SSL_free(SSL *s) +{ + int i; + + if (s == NULL) + return; + + i = CRYPTO_add(&s->references, -1, CRYPTO_LOCK_SSL); +#ifdef REF_PRINT + REF_PRINT("SSL", s); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "SSL_free, bad reference count\n"); + abort(); /* ok */ + } +#endif + + if (s->param) + X509_VERIFY_PARAM_free(s->param); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL, s, &s->ex_data); + + if (s->bbio != NULL) { + /* If the buffering BIO is in place, pop it off */ + if (s->bbio == s->wbio) { + s->wbio = BIO_pop(s->wbio); + } + BIO_free(s->bbio); + s->bbio = NULL; + } + if (s->rbio != NULL) + BIO_free_all(s->rbio); + if ((s->wbio != NULL) && (s->wbio != s->rbio)) + BIO_free_all(s->wbio); + + if (s->init_buf != NULL) + BUF_MEM_free(s->init_buf); + + /* add extra stuff */ + if (s->cipher_list != NULL) + sk_SSL_CIPHER_free(s->cipher_list); + if (s->cipher_list_by_id != NULL) + sk_SSL_CIPHER_free(s->cipher_list_by_id); + + /* Make the next call work :-) */ + if (s->session != NULL) { + ssl_clear_bad_session(s); + SSL_SESSION_free(s->session); + } + + ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); + + if (s->cert != NULL) + ssl_cert_free(s->cert); + /* Free up if allocated */ + +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_hostname) + OPENSSL_free(s->tlsext_hostname); + if (s->initial_ctx) + SSL_CTX_free(s->initial_ctx); +# ifndef OPENSSL_NO_EC + if (s->tlsext_ecpointformatlist) + OPENSSL_free(s->tlsext_ecpointformatlist); + if (s->tlsext_ellipticcurvelist) + OPENSSL_free(s->tlsext_ellipticcurvelist); +# endif /* OPENSSL_NO_EC */ + if (s->tlsext_opaque_prf_input) + OPENSSL_free(s->tlsext_opaque_prf_input); + if (s->tlsext_ocsp_exts) + sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, X509_EXTENSION_free); + if (s->tlsext_ocsp_ids) + sk_OCSP_RESPID_pop_free(s->tlsext_ocsp_ids, OCSP_RESPID_free); + if (s->tlsext_ocsp_resp) + OPENSSL_free(s->tlsext_ocsp_resp); +#endif + + if (s->client_CA != NULL) + sk_X509_NAME_pop_free(s->client_CA, X509_NAME_free); + + if (s->method != NULL) + s->method->ssl_free(s); + + if (s->ctx) + SSL_CTX_free(s->ctx); + +#ifndef OPENSSL_NO_KRB5 + if (s->kssl_ctx != NULL) + kssl_ctx_free(s->kssl_ctx); +#endif /* OPENSSL_NO_KRB5 */ + +#if !defined(OPENSSL_NO_TLSEXT) && !defined(OPENSSL_NO_NEXTPROTONEG) + if (s->next_proto_negotiated) + OPENSSL_free(s->next_proto_negotiated); +#endif + +#ifndef OPENSSL_NO_SRTP + if (s->srtp_profiles) + sk_SRTP_PROTECTION_PROFILE_free(s->srtp_profiles); +#endif + + OPENSSL_free(s); +} + +void SSL_set_bio(SSL *s, BIO *rbio, BIO *wbio) +{ + /* + * If the output buffering BIO is still in place, remove it + */ + if (s->bbio != NULL) { + if (s->wbio == s->bbio) { + s->wbio = s->wbio->next_bio; + s->bbio->next_bio = NULL; + } + } + if ((s->rbio != NULL) && (s->rbio != rbio)) + BIO_free_all(s->rbio); + if ((s->wbio != NULL) && (s->wbio != wbio) && (s->rbio != s->wbio)) + BIO_free_all(s->wbio); + s->rbio = rbio; + s->wbio = wbio; +} + +BIO *SSL_get_rbio(const SSL *s) +{ + return (s->rbio); +} + +BIO *SSL_get_wbio(const SSL *s) +{ + return (s->wbio); +} + +int SSL_get_fd(const SSL *s) +{ + return (SSL_get_rfd(s)); +} + +int SSL_get_rfd(const SSL *s) +{ + int ret = -1; + BIO *b, *r; + + b = SSL_get_rbio(s); + r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR); + if (r != NULL) + BIO_get_fd(r, &ret); + return (ret); +} + +int SSL_get_wfd(const SSL *s) +{ + int ret = -1; + BIO *b, *r; + + b = SSL_get_wbio(s); + r = BIO_find_type(b, BIO_TYPE_DESCRIPTOR); + if (r != NULL) + BIO_get_fd(r, &ret); + return (ret); +} + +#ifndef OPENSSL_NO_SOCK +int SSL_set_fd(SSL *s, int fd) +{ + int ret = 0; + BIO *bio = NULL; + + bio = BIO_new(BIO_s_socket()); + + if (bio == NULL) { + SSLerr(SSL_F_SSL_SET_FD, ERR_R_BUF_LIB); + goto err; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(s, bio, bio); + ret = 1; + err: + return (ret); +} + +int SSL_set_wfd(SSL *s, int fd) +{ + int ret = 0; + BIO *bio = NULL; + + if ((s->rbio == NULL) || (BIO_method_type(s->rbio) != BIO_TYPE_SOCKET) + || ((int)BIO_get_fd(s->rbio, NULL) != fd)) { + bio = BIO_new(BIO_s_socket()); + + if (bio == NULL) { + SSLerr(SSL_F_SSL_SET_WFD, ERR_R_BUF_LIB); + goto err; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(s, SSL_get_rbio(s), bio); + } else + SSL_set_bio(s, SSL_get_rbio(s), SSL_get_rbio(s)); + ret = 1; + err: + return (ret); +} + +int SSL_set_rfd(SSL *s, int fd) +{ + int ret = 0; + BIO *bio = NULL; + + if ((s->wbio == NULL) || (BIO_method_type(s->wbio) != BIO_TYPE_SOCKET) + || ((int)BIO_get_fd(s->wbio, NULL) != fd)) { + bio = BIO_new(BIO_s_socket()); + + if (bio == NULL) { + SSLerr(SSL_F_SSL_SET_RFD, ERR_R_BUF_LIB); + goto err; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(s, bio, SSL_get_wbio(s)); + } else + SSL_set_bio(s, SSL_get_wbio(s), SSL_get_wbio(s)); + ret = 1; + err: + return (ret); +} +#endif + +/* return length of latest Finished message we sent, copy to 'buf' */ +size_t SSL_get_finished(const SSL *s, void *buf, size_t count) +{ + size_t ret = 0; + + if (s->s3 != NULL) { + ret = s->s3->tmp.finish_md_len; + if (count > ret) + count = ret; + memcpy(buf, s->s3->tmp.finish_md, count); + } + return ret; +} + +/* return length of latest Finished message we expected, copy to 'buf' */ +size_t SSL_get_peer_finished(const SSL *s, void *buf, size_t count) +{ + size_t ret = 0; + + if (s->s3 != NULL) { + ret = s->s3->tmp.peer_finish_md_len; + if (count > ret) + count = ret; + memcpy(buf, s->s3->tmp.peer_finish_md, count); + } + return ret; +} + +int SSL_get_verify_mode(const SSL *s) +{ + return (s->verify_mode); +} + +int SSL_get_verify_depth(const SSL *s) +{ + return X509_VERIFY_PARAM_get_depth(s->param); +} + +int (*SSL_get_verify_callback(const SSL *s)) (int, X509_STORE_CTX *) { + return (s->verify_callback); +} + +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) +{ + return (ctx->verify_mode); +} + +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) +{ + return X509_VERIFY_PARAM_get_depth(ctx->param); +} + +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx)) (int, X509_STORE_CTX *) { + return (ctx->default_verify_callback); +} + +void SSL_set_verify(SSL *s, int mode, + int (*callback) (int ok, X509_STORE_CTX *ctx)) +{ + s->verify_mode = mode; + if (callback != NULL) + s->verify_callback = callback; +} + +void SSL_set_verify_depth(SSL *s, int depth) +{ + X509_VERIFY_PARAM_set_depth(s->param, depth); +} + +void SSL_set_read_ahead(SSL *s, int yes) +{ + s->read_ahead = yes; +} + +int SSL_get_read_ahead(const SSL *s) +{ + return (s->read_ahead); +} + +int SSL_pending(const SSL *s) +{ + /* + * SSL_pending cannot work properly if read-ahead is enabled + * (SSL_[CTX_]ctrl(..., SSL_CTRL_SET_READ_AHEAD, 1, NULL)), and it is + * impossible to fix since SSL_pending cannot report errors that may be + * observed while scanning the new data. (Note that SSL_pending() is + * often used as a boolean value, so we'd better not return -1.) + */ + return (s->method->ssl_pending(s)); +} + +X509 *SSL_get_peer_certificate(const SSL *s) +{ + X509 *r; + + if ((s == NULL) || (s->session == NULL)) + r = NULL; + else + r = s->session->peer; + + if (r == NULL) + return (r); + + CRYPTO_add(&r->references, 1, CRYPTO_LOCK_X509); + + return (r); +} + +STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s) +{ + STACK_OF(X509) *r; + + if ((s == NULL) || (s->session == NULL) + || (s->session->sess_cert == NULL)) + r = NULL; + else + r = s->session->sess_cert->cert_chain; + + /* + * If we are a client, cert_chain includes the peer's own certificate; if + * we are a server, it does not. + */ + + return (r); +} + +/* + * Now in theory, since the calling process own 't' it should be safe to + * modify. We need to be able to read f without being hassled + */ +void SSL_copy_session_id(SSL *t, const SSL *f) +{ + CERT *tmp; + + /* Do we need to to SSL locking? */ + SSL_set_session(t, SSL_get_session(f)); + + /* + * what if we are setup as SSLv2 but want to talk SSLv3 or vice-versa + */ + if (t->method != f->method) { + t->method->ssl_free(t); /* cleanup current */ + t->method = f->method; /* change method */ + t->method->ssl_new(t); /* setup new */ + } + + tmp = t->cert; + if (f->cert != NULL) { + CRYPTO_add(&f->cert->references, 1, CRYPTO_LOCK_SSL_CERT); + t->cert = f->cert; + } else + t->cert = NULL; + if (tmp != NULL) + ssl_cert_free(tmp); + SSL_set_session_id_context(t, f->sid_ctx, f->sid_ctx_length); +} + +/* Fix this so it checks all the valid key/cert options */ +int SSL_CTX_check_private_key(const SSL_CTX *ctx) +{ + if ((ctx == NULL) || + (ctx->cert == NULL) || (ctx->cert->key->x509 == NULL)) { + SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, + SSL_R_NO_CERTIFICATE_ASSIGNED); + return (0); + } + if (ctx->cert->key->privatekey == NULL) { + SSLerr(SSL_F_SSL_CTX_CHECK_PRIVATE_KEY, + SSL_R_NO_PRIVATE_KEY_ASSIGNED); + return (0); + } + return (X509_check_private_key + (ctx->cert->key->x509, ctx->cert->key->privatekey)); +} + +/* Fix this function so that it takes an optional type parameter */ +int SSL_check_private_key(const SSL *ssl) +{ + if (ssl == NULL) { + SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (ssl->cert == NULL) { + SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); + return 0; + } + if (ssl->cert->key->x509 == NULL) { + SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_CERTIFICATE_ASSIGNED); + return (0); + } + if (ssl->cert->key->privatekey == NULL) { + SSLerr(SSL_F_SSL_CHECK_PRIVATE_KEY, SSL_R_NO_PRIVATE_KEY_ASSIGNED); + return (0); + } + return (X509_check_private_key(ssl->cert->key->x509, + ssl->cert->key->privatekey)); +} + +int SSL_accept(SSL *s) +{ + if (s->handshake_func == 0) + /* Not properly initialized yet */ + SSL_set_accept_state(s); + + return (s->method->ssl_accept(s)); +} + +int SSL_connect(SSL *s) +{ + if (s->handshake_func == 0) + /* Not properly initialized yet */ + SSL_set_connect_state(s); + + return (s->method->ssl_connect(s)); +} + +long SSL_get_default_timeout(const SSL *s) +{ + return (s->method->get_timeout()); +} + +int SSL_read(SSL *s, void *buf, int num) +{ + if (s->handshake_func == 0) { + SSLerr(SSL_F_SSL_READ, SSL_R_UNINITIALIZED); + return -1; + } + + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + return (0); + } + return (s->method->ssl_read(s, buf, num)); +} + +int SSL_peek(SSL *s, void *buf, int num) +{ + if (s->handshake_func == 0) { + SSLerr(SSL_F_SSL_PEEK, SSL_R_UNINITIALIZED); + return -1; + } + + if (s->shutdown & SSL_RECEIVED_SHUTDOWN) { + return (0); + } + return (s->method->ssl_peek(s, buf, num)); +} + +int SSL_write(SSL *s, const void *buf, int num) +{ + if (s->handshake_func == 0) { + SSLerr(SSL_F_SSL_WRITE, SSL_R_UNINITIALIZED); + return -1; + } + + if (s->shutdown & SSL_SENT_SHUTDOWN) { + s->rwstate = SSL_NOTHING; + SSLerr(SSL_F_SSL_WRITE, SSL_R_PROTOCOL_IS_SHUTDOWN); + return (-1); + } + return (s->method->ssl_write(s, buf, num)); +} + +int SSL_shutdown(SSL *s) +{ + /* + * Note that this function behaves differently from what one might + * expect. Return values are 0 for no success (yet), 1 for success; but + * calling it once is usually not enough, even if blocking I/O is used + * (see ssl3_shutdown). + */ + + if (s->handshake_func == 0) { + SSLerr(SSL_F_SSL_SHUTDOWN, SSL_R_UNINITIALIZED); + return -1; + } + + if ((s != NULL) && !SSL_in_init(s)) + return (s->method->ssl_shutdown(s)); + else + return (1); +} + +int SSL_renegotiate(SSL *s) +{ + if (s->renegotiate == 0) + s->renegotiate = 1; + + s->new_session = 1; + + return (s->method->ssl_renegotiate(s)); +} + +int SSL_renegotiate_abbreviated(SSL *s) +{ + if (s->renegotiate == 0) + s->renegotiate = 1; + + s->new_session = 0; + + return (s->method->ssl_renegotiate(s)); +} + +int SSL_renegotiate_pending(SSL *s) +{ + /* + * becomes true when negotiation is requested; false again once a + * handshake has finished + */ + return (s->renegotiate != 0); +} + +long SSL_ctrl(SSL *s, int cmd, long larg, void *parg) +{ + long l; + + switch (cmd) { + case SSL_CTRL_GET_READ_AHEAD: + return (s->read_ahead); + case SSL_CTRL_SET_READ_AHEAD: + l = s->read_ahead; + s->read_ahead = larg; + return (l); + + case SSL_CTRL_SET_MSG_CALLBACK_ARG: + s->msg_callback_arg = parg; + return 1; + + case SSL_CTRL_OPTIONS: + return (s->options |= larg); + case SSL_CTRL_CLEAR_OPTIONS: + return (s->options &= ~larg); + case SSL_CTRL_MODE: + return (s->mode |= larg); + case SSL_CTRL_CLEAR_MODE: + return (s->mode &= ~larg); + case SSL_CTRL_GET_MAX_CERT_LIST: + return (s->max_cert_list); + case SSL_CTRL_SET_MAX_CERT_LIST: + l = s->max_cert_list; + s->max_cert_list = larg; + return (l); + case SSL_CTRL_SET_MAX_SEND_FRAGMENT: + if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) + return 0; + s->max_send_fragment = larg; + return 1; + case SSL_CTRL_GET_RI_SUPPORT: + if (s->s3) + return s->s3->send_connection_binding; + else + return 0; + default: + return (s->method->ssl_ctrl(s, cmd, larg, parg)); + } +} + +long SSL_callback_ctrl(SSL *s, int cmd, void (*fp) (void)) +{ + switch (cmd) { + case SSL_CTRL_SET_MSG_CALLBACK: + s->msg_callback = (void (*) + (int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, + void *arg))(fp); + return 1; + + default: + return (s->method->ssl_callback_ctrl(s, cmd, fp)); + } +} + +LHASH_OF(SSL_SESSION) *SSL_CTX_sessions(SSL_CTX *ctx) +{ + return ctx->sessions; +} + +long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg) +{ + long l; + + switch (cmd) { + case SSL_CTRL_GET_READ_AHEAD: + return (ctx->read_ahead); + case SSL_CTRL_SET_READ_AHEAD: + l = ctx->read_ahead; + ctx->read_ahead = larg; + return (l); + + case SSL_CTRL_SET_MSG_CALLBACK_ARG: + ctx->msg_callback_arg = parg; + return 1; + + case SSL_CTRL_GET_MAX_CERT_LIST: + return (ctx->max_cert_list); + case SSL_CTRL_SET_MAX_CERT_LIST: + l = ctx->max_cert_list; + ctx->max_cert_list = larg; + return (l); + + case SSL_CTRL_SET_SESS_CACHE_SIZE: + l = ctx->session_cache_size; + ctx->session_cache_size = larg; + return (l); + case SSL_CTRL_GET_SESS_CACHE_SIZE: + return (ctx->session_cache_size); + case SSL_CTRL_SET_SESS_CACHE_MODE: + l = ctx->session_cache_mode; + ctx->session_cache_mode = larg; + return (l); + case SSL_CTRL_GET_SESS_CACHE_MODE: + return (ctx->session_cache_mode); + + case SSL_CTRL_SESS_NUMBER: + return (lh_SSL_SESSION_num_items(ctx->sessions)); + case SSL_CTRL_SESS_CONNECT: + return (ctx->stats.sess_connect); + case SSL_CTRL_SESS_CONNECT_GOOD: + return (ctx->stats.sess_connect_good); + case SSL_CTRL_SESS_CONNECT_RENEGOTIATE: + return (ctx->stats.sess_connect_renegotiate); + case SSL_CTRL_SESS_ACCEPT: + return (ctx->stats.sess_accept); + case SSL_CTRL_SESS_ACCEPT_GOOD: + return (ctx->stats.sess_accept_good); + case SSL_CTRL_SESS_ACCEPT_RENEGOTIATE: + return (ctx->stats.sess_accept_renegotiate); + case SSL_CTRL_SESS_HIT: + return (ctx->stats.sess_hit); + case SSL_CTRL_SESS_CB_HIT: + return (ctx->stats.sess_cb_hit); + case SSL_CTRL_SESS_MISSES: + return (ctx->stats.sess_miss); + case SSL_CTRL_SESS_TIMEOUTS: + return (ctx->stats.sess_timeout); + case SSL_CTRL_SESS_CACHE_FULL: + return (ctx->stats.sess_cache_full); + case SSL_CTRL_OPTIONS: + return (ctx->options |= larg); + case SSL_CTRL_CLEAR_OPTIONS: + return (ctx->options &= ~larg); + case SSL_CTRL_MODE: + return (ctx->mode |= larg); + case SSL_CTRL_CLEAR_MODE: + return (ctx->mode &= ~larg); + case SSL_CTRL_SET_MAX_SEND_FRAGMENT: + if (larg < 512 || larg > SSL3_RT_MAX_PLAIN_LENGTH) + return 0; + ctx->max_send_fragment = larg; + return 1; + default: + return (ctx->method->ssl_ctx_ctrl(ctx, cmd, larg, parg)); + } +} + +long SSL_CTX_callback_ctrl(SSL_CTX *ctx, int cmd, void (*fp) (void)) +{ + switch (cmd) { + case SSL_CTRL_SET_MSG_CALLBACK: + ctx->msg_callback = (void (*) + (int write_p, int version, int content_type, + const void *buf, size_t len, SSL *ssl, + void *arg))(fp); + return 1; + + default: + return (ctx->method->ssl_ctx_callback_ctrl(ctx, cmd, fp)); + } +} + +int ssl_cipher_id_cmp(const SSL_CIPHER *a, const SSL_CIPHER *b) +{ + long l; + + l = a->id - b->id; + if (l == 0L) + return (0); + else + return ((l > 0) ? 1 : -1); +} + +int ssl_cipher_ptr_id_cmp(const SSL_CIPHER *const *ap, + const SSL_CIPHER *const *bp) +{ + long l; + + l = (*ap)->id - (*bp)->id; + if (l == 0L) + return (0); + else + return ((l > 0) ? 1 : -1); +} + +/** return a STACK of the ciphers available for the SSL and in order of + * preference */ +STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s) +{ + if (s != NULL) { + if (s->cipher_list != NULL) { + return (s->cipher_list); + } else if ((s->ctx != NULL) && (s->ctx->cipher_list != NULL)) { + return (s->ctx->cipher_list); + } + } + return (NULL); +} + +/** return a STACK of the ciphers available for the SSL and in order of + * algorithm id */ +STACK_OF(SSL_CIPHER) *ssl_get_ciphers_by_id(SSL *s) +{ + if (s != NULL) { + if (s->cipher_list_by_id != NULL) { + return (s->cipher_list_by_id); + } else if ((s->ctx != NULL) && (s->ctx->cipher_list_by_id != NULL)) { + return (s->ctx->cipher_list_by_id); + } + } + return (NULL); +} + +/** The old interface to get the same thing as SSL_get_ciphers() */ +const char *SSL_get_cipher_list(const SSL *s, int n) +{ + SSL_CIPHER *c; + STACK_OF(SSL_CIPHER) *sk; + + if (s == NULL) + return (NULL); + sk = SSL_get_ciphers(s); + if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= n)) + return (NULL); + c = sk_SSL_CIPHER_value(sk, n); + if (c == NULL) + return (NULL); + return (c->name); +} + +/** specify the ciphers to be used by default by the SSL_CTX */ +int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) +{ + STACK_OF(SSL_CIPHER) *sk; + + sk = ssl_create_cipher_list(ctx->method, &ctx->cipher_list, + &ctx->cipher_list_by_id, str); + /* + * ssl_create_cipher_list may return an empty stack if it was unable to + * find a cipher matching the given rule string (for example if the rule + * string specifies a cipher which has been disabled). This is not an + * error as far as ssl_create_cipher_list is concerned, and hence + * ctx->cipher_list and ctx->cipher_list_by_id has been updated. + */ + if (sk == NULL) + return 0; + else if (sk_SSL_CIPHER_num(sk) == 0) { + SSLerr(SSL_F_SSL_CTX_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH); + return 0; + } + return 1; +} + +/** specify the ciphers to be used by the SSL */ +int SSL_set_cipher_list(SSL *s, const char *str) +{ + STACK_OF(SSL_CIPHER) *sk; + + sk = ssl_create_cipher_list(s->ctx->method, &s->cipher_list, + &s->cipher_list_by_id, str); + /* see comment in SSL_CTX_set_cipher_list */ + if (sk == NULL) + return 0; + else if (sk_SSL_CIPHER_num(sk) == 0) { + SSLerr(SSL_F_SSL_SET_CIPHER_LIST, SSL_R_NO_CIPHER_MATCH); + return 0; + } + return 1; +} + +/* works well for SSLv2, not so good for SSLv3 */ +char *SSL_get_shared_ciphers(const SSL *s, char *buf, int len) +{ + char *p; + STACK_OF(SSL_CIPHER) *sk; + SSL_CIPHER *c; + int i; + + if ((s->session == NULL) || (s->session->ciphers == NULL) || (len < 2)) + return (NULL); + + p = buf; + sk = s->session->ciphers; + + if (sk_SSL_CIPHER_num(sk) == 0) + return NULL; + + for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + int n; + + c = sk_SSL_CIPHER_value(sk, i); + n = strlen(c->name); + if (n + 1 > len) { + if (p != buf) + --p; + *p = '\0'; + return buf; + } + strcpy(p, c->name); + p += n; + *(p++) = ':'; + len -= n + 1; + } + p[-1] = '\0'; + return (buf); +} + +int ssl_cipher_list_to_bytes(SSL *s, STACK_OF(SSL_CIPHER) *sk, + unsigned char *p, + int (*put_cb) (const SSL_CIPHER *, + unsigned char *)) +{ + int i, j = 0; + SSL_CIPHER *c; + unsigned char *q; +#ifndef OPENSSL_NO_KRB5 + int nokrb5 = !kssl_tgt_is_available(s->kssl_ctx); +#endif /* OPENSSL_NO_KRB5 */ + + if (sk == NULL) + return (0); + q = p; + if (put_cb == NULL) + put_cb = s->method->put_cipher_by_char; + + for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) { + c = sk_SSL_CIPHER_value(sk, i); + /* Skip TLS v1.2 only ciphersuites if lower than v1.2 */ + if ((c->algorithm_ssl & SSL_TLSV1_2) && + (TLS1_get_client_version(s) < TLS1_2_VERSION)) + continue; +#ifndef OPENSSL_NO_KRB5 + if (((c->algorithm_mkey & SSL_kKRB5) + || (c->algorithm_auth & SSL_aKRB5)) && nokrb5) + continue; +#endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_PSK + /* with PSK there must be client callback set */ + if (((c->algorithm_mkey & SSL_kPSK) || (c->algorithm_auth & SSL_aPSK)) + && s->psk_client_callback == NULL) + continue; +#endif /* OPENSSL_NO_PSK */ +#ifndef OPENSSL_NO_SRP + if (((c->algorithm_mkey & SSL_kSRP) || (c->algorithm_auth & SSL_aSRP)) + && !(s->srp_ctx.srp_Mask & SSL_kSRP)) + continue; +#endif /* OPENSSL_NO_SRP */ + j = put_cb(c, p); + p += j; + } + /* + * If p == q, no ciphers; caller indicates an error. Otherwise, add + * applicable SCSVs. + */ + if (p != q) { + if (!s->renegotiate) { + static SSL_CIPHER scsv = { + 0, NULL, SSL3_CK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + j = put_cb(&scsv, p); + p += j; +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, + "TLS_EMPTY_RENEGOTIATION_INFO_SCSV sent by client\n"); +#endif + } + + if (s->mode & SSL_MODE_SEND_FALLBACK_SCSV) { + static SSL_CIPHER scsv = { + 0, NULL, SSL3_CK_FALLBACK_SCSV, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + j = put_cb(&scsv, p); + p += j; + } + } + + return (p - q); +} + +STACK_OF(SSL_CIPHER) *ssl_bytes_to_cipher_list(SSL *s, unsigned char *p, + int num, + STACK_OF(SSL_CIPHER) **skp) +{ + const SSL_CIPHER *c; + STACK_OF(SSL_CIPHER) *sk; + int i, n; + + if (s->s3) + s->s3->send_connection_binding = 0; + + n = ssl_put_cipher_by_char(s, NULL, NULL); + if (n == 0 || (num % n) != 0) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + return (NULL); + } + if ((skp == NULL) || (*skp == NULL)) { + sk = sk_SSL_CIPHER_new_null(); /* change perhaps later */ + if(sk == NULL) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + return NULL; + } + } else { + sk = *skp; + sk_SSL_CIPHER_zero(sk); + } + + for (i = 0; i < num; i += n) { + /* Check for TLS_EMPTY_RENEGOTIATION_INFO_SCSV */ + if (s->s3 && (n != 3 || !p[0]) && + (p[n - 2] == ((SSL3_CK_SCSV >> 8) & 0xff)) && + (p[n - 1] == (SSL3_CK_SCSV & 0xff))) { + /* SCSV fatal if renegotiating */ + if (s->renegotiate) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING); + ssl3_send_alert(s, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + goto err; + } + s->s3->send_connection_binding = 1; + p += n; +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, "SCSV received by server\n"); +#endif + continue; + } + + /* Check for TLS_FALLBACK_SCSV */ + if ((n != 3 || !p[0]) && + (p[n - 2] == ((SSL3_CK_FALLBACK_SCSV >> 8) & 0xff)) && + (p[n - 1] == (SSL3_CK_FALLBACK_SCSV & 0xff))) { + /* + * The SCSV indicates that the client previously tried a higher + * version. Fail if the current version is an unexpected + * downgrade. + */ + if (!SSL_ctrl(s, SSL_CTRL_CHECK_PROTO_VERSION, 0, NULL)) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, + SSL_R_INAPPROPRIATE_FALLBACK); + if (s->s3) + ssl3_send_alert(s, SSL3_AL_FATAL, + SSL_AD_INAPPROPRIATE_FALLBACK); + goto err; + } + p += n; + continue; + } + + c = ssl_get_cipher_by_char(s, p); + p += n; + if (c != NULL) { + if (!sk_SSL_CIPHER_push(sk, c)) { + SSLerr(SSL_F_SSL_BYTES_TO_CIPHER_LIST, ERR_R_MALLOC_FAILURE); + goto err; + } + } + } + + if (skp != NULL) + *skp = sk; + return (sk); + err: + if ((skp == NULL) || (*skp == NULL)) + sk_SSL_CIPHER_free(sk); + return (NULL); +} + +#ifndef OPENSSL_NO_TLSEXT +/** return a servername extension value if provided in Client Hello, or NULL. + * So far, only host_name types are defined (RFC 3546). + */ + +const char *SSL_get_servername(const SSL *s, const int type) +{ + if (type != TLSEXT_NAMETYPE_host_name) + return NULL; + + return s->session && !s->tlsext_hostname ? + s->session->tlsext_hostname : s->tlsext_hostname; +} + +int SSL_get_servername_type(const SSL *s) +{ + if (s->session + && (!s->tlsext_hostname ? s->session-> + tlsext_hostname : s->tlsext_hostname)) + return TLSEXT_NAMETYPE_host_name; + return -1; +} + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* + * SSL_select_next_proto implements the standard protocol selection. It is + * expected that this function is called from the callback set by + * SSL_CTX_set_next_proto_select_cb. The protocol data is assumed to be a + * vector of 8-bit, length prefixed byte strings. The length byte itself is + * not included in the length. A byte string of length 0 is invalid. No byte + * string may be truncated. The current, but experimental algorithm for + * selecting the protocol is: 1) If the server doesn't support NPN then this + * is indicated to the callback. In this case, the client application has to + * abort the connection or have a default application level protocol. 2) If + * the server supports NPN, but advertises an empty list then the client + * selects the first protcol in its list, but indicates via the API that this + * fallback case was enacted. 3) Otherwise, the client finds the first + * protocol in the server's list that it supports and selects this protocol. + * This is because it's assumed that the server has better information about + * which protocol a client should use. 4) If the client doesn't support any + * of the server's advertised protocols, then this is treated the same as + * case 2. It returns either OPENSSL_NPN_NEGOTIATED if a common protocol was + * found, or OPENSSL_NPN_NO_OVERLAP if the fallback case was reached. + */ +int SSL_select_next_proto(unsigned char **out, unsigned char *outlen, + const unsigned char *server, + unsigned int server_len, + const unsigned char *client, + unsigned int client_len) +{ + unsigned int i, j; + const unsigned char *result; + int status = OPENSSL_NPN_UNSUPPORTED; + + /* + * For each protocol in server preference order, see if we support it. + */ + for (i = 0; i < server_len;) { + for (j = 0; j < client_len;) { + if (server[i] == client[j] && + memcmp(&server[i + 1], &client[j + 1], server[i]) == 0) { + /* We found a match */ + result = &server[i]; + status = OPENSSL_NPN_NEGOTIATED; + goto found; + } + j += client[j]; + j++; + } + i += server[i]; + i++; + } + + /* There's no overlap between our protocols and the server's list. */ + result = client; + status = OPENSSL_NPN_NO_OVERLAP; + + found: + *out = (unsigned char *)result + 1; + *outlen = result[0]; + return status; +} + +/* + * SSL_get0_next_proto_negotiated sets *data and *len to point to the + * client's requested protocol for this connection and returns 0. If the + * client didn't request any protocol, then *data is set to NULL. Note that + * the client can request any protocol it chooses. The value returned from + * this function need not be a member of the list of supported protocols + * provided by the callback. + */ +void SSL_get0_next_proto_negotiated(const SSL *s, const unsigned char **data, + unsigned *len) +{ + *data = s->next_proto_negotiated; + if (!*data) { + *len = 0; + } else { + *len = s->next_proto_negotiated_len; + } +} + +/* + * SSL_CTX_set_next_protos_advertised_cb sets a callback that is called when + * a TLS server needs a list of supported protocols for Next Protocol + * Negotiation. The returned list must be in wire format. The list is + * returned by setting |out| to point to it and |outlen| to its length. This + * memory will not be modified, but one should assume that the SSL* keeps a + * reference to it. The callback should return SSL_TLSEXT_ERR_OK if it + * wishes to advertise. Otherwise, no such extension will be included in the + * ServerHello. + */ +void SSL_CTX_set_next_protos_advertised_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + const unsigned char + **out, + unsigned int *outlen, + void *arg), void *arg) +{ + ctx->next_protos_advertised_cb = cb; + ctx->next_protos_advertised_cb_arg = arg; +} + +/* + * SSL_CTX_set_next_proto_select_cb sets a callback that is called when a + * client needs to select a protocol from the server's provided list. |out| + * must be set to point to the selected protocol (which may be within |in|). + * The length of the protocol name must be written into |outlen|. The + * server's advertised protocols are provided in |in| and |inlen|. The + * callback can assume that |in| is syntactically valid. The client must + * select a protocol. It is fatal to the connection if this callback returns + * a value other than SSL_TLSEXT_ERR_OK. + */ +void SSL_CTX_set_next_proto_select_cb(SSL_CTX *ctx, + int (*cb) (SSL *s, unsigned char **out, + unsigned char *outlen, + const unsigned char *in, + unsigned int inlen, + void *arg), void *arg) +{ + ctx->next_proto_select_cb = cb; + ctx->next_proto_select_cb_arg = arg; +} +# endif +#endif + +int SSL_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *p, size_t plen, + int use_context) +{ + if (s->version < TLS1_VERSION) + return -1; + + return s->method->ssl3_enc->export_keying_material(s, out, olen, label, + llen, p, plen, + use_context); +} + +static unsigned long ssl_session_hash(const SSL_SESSION *a) +{ + unsigned long l; + + l = (unsigned long) + ((unsigned int)a->session_id[0]) | + ((unsigned int)a->session_id[1] << 8L) | + ((unsigned long)a->session_id[2] << 16L) | + ((unsigned long)a->session_id[3] << 24L); + return (l); +} + +/* + * NB: If this function (or indeed the hash function which uses a sort of + * coarser function than this one) is changed, ensure + * SSL_CTX_has_matching_session_id() is checked accordingly. It relies on + * being able to construct an SSL_SESSION that will collide with any existing + * session with a matching session ID. + */ +static int ssl_session_cmp(const SSL_SESSION *a, const SSL_SESSION *b) +{ + if (a->ssl_version != b->ssl_version) + return (1); + if (a->session_id_length != b->session_id_length) + return (1); + return (memcmp(a->session_id, b->session_id, a->session_id_length)); +} + +/* + * These wrapper functions should remain rather than redeclaring + * SSL_SESSION_hash and SSL_SESSION_cmp for void* types and casting each + * variable. The reason is that the functions aren't static, they're exposed + * via ssl.h. + */ +static IMPLEMENT_LHASH_HASH_FN(ssl_session, SSL_SESSION) +static IMPLEMENT_LHASH_COMP_FN(ssl_session, SSL_SESSION) + +SSL_CTX *SSL_CTX_new(const SSL_METHOD *meth) +{ + SSL_CTX *ret = NULL; + + if (meth == NULL) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_NULL_SSL_METHOD_PASSED); + return (NULL); + } +#ifdef OPENSSL_FIPS + if (FIPS_mode() && (meth->version < TLS1_VERSION)) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_ONLY_TLS_ALLOWED_IN_FIPS_MODE); + return NULL; + } +#endif + + if (SSL_get_ex_data_X509_STORE_CTX_idx() < 0) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); + goto err; + } + ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX)); + if (ret == NULL) + goto err; + + memset(ret, 0, sizeof(SSL_CTX)); + + ret->method = meth; + + ret->cert_store = NULL; + ret->session_cache_mode = SSL_SESS_CACHE_SERVER; + ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT; + ret->session_cache_head = NULL; + ret->session_cache_tail = NULL; + + /* We take the system default */ + ret->session_timeout = meth->get_timeout(); + + ret->new_session_cb = 0; + ret->remove_session_cb = 0; + ret->get_session_cb = 0; + ret->generate_session_id = 0; + + memset((char *)&ret->stats, 0, sizeof(ret->stats)); + + ret->references = 1; + ret->quiet_shutdown = 0; + +/* ret->cipher=NULL;*/ +/*- + ret->s2->challenge=NULL; + ret->master_key=NULL; + ret->key_arg=NULL; + ret->s2->conn_id=NULL; */ + + ret->info_callback = NULL; + + ret->app_verify_callback = 0; + ret->app_verify_arg = NULL; + + ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT; + ret->read_ahead = 0; + ret->msg_callback = 0; + ret->msg_callback_arg = NULL; + ret->verify_mode = SSL_VERIFY_NONE; +#if 0 + ret->verify_depth = -1; /* Don't impose a limit (but x509_lu.c does) */ +#endif + ret->sid_ctx_length = 0; + ret->default_verify_callback = NULL; + if ((ret->cert = ssl_cert_new()) == NULL) + goto err; + + ret->default_passwd_callback = 0; + ret->default_passwd_callback_userdata = NULL; + ret->client_cert_cb = 0; + ret->app_gen_cookie_cb = 0; + ret->app_verify_cookie_cb = 0; + + ret->sessions = lh_SSL_SESSION_new(); + if (ret->sessions == NULL) + goto err; + ret->cert_store = X509_STORE_new(); + if (ret->cert_store == NULL) + goto err; + + ssl_create_cipher_list(ret->method, + &ret->cipher_list, &ret->cipher_list_by_id, + meth->version == + SSL2_VERSION ? "SSLv2" : SSL_DEFAULT_CIPHER_LIST); + if (ret->cipher_list == NULL || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_LIBRARY_HAS_NO_CIPHERS); + goto err2; + } + + ret->param = X509_VERIFY_PARAM_new(); + if (!ret->param) + goto err; + + if ((ret->rsa_md5 = EVP_get_digestbyname("ssl2-md5")) == NULL) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL2_MD5_ROUTINES); + goto err2; + } + if ((ret->md5 = EVP_get_digestbyname("ssl3-md5")) == NULL) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_MD5_ROUTINES); + goto err2; + } + if ((ret->sha1 = EVP_get_digestbyname("ssl3-sha1")) == NULL) { + SSLerr(SSL_F_SSL_CTX_NEW, SSL_R_UNABLE_TO_LOAD_SSL3_SHA1_ROUTINES); + goto err2; + } + + if ((ret->client_CA = sk_X509_NAME_new_null()) == NULL) + goto err; + + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_CTX, ret, &ret->ex_data); + + ret->extra_certs = NULL; + /* No compression for DTLS */ + if (meth->version != DTLS1_VERSION) + ret->comp_methods = SSL_COMP_get_compression_methods(); + + ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + +#ifndef OPENSSL_NO_TLSEXT + ret->tlsext_servername_callback = 0; + ret->tlsext_servername_arg = NULL; + /* Setup RFC4507 ticket keys */ + if ((RAND_pseudo_bytes(ret->tlsext_tick_key_name, 16) <= 0) + || (RAND_bytes(ret->tlsext_tick_hmac_key, 16) <= 0) + || (RAND_bytes(ret->tlsext_tick_aes_key, 16) <= 0)) + ret->options |= SSL_OP_NO_TICKET; + + ret->tlsext_status_cb = 0; + ret->tlsext_status_arg = NULL; + +# ifndef OPENSSL_NO_NEXTPROTONEG + ret->next_protos_advertised_cb = 0; + ret->next_proto_select_cb = 0; +# endif +#endif +#ifndef OPENSSL_NO_PSK + ret->psk_identity_hint = NULL; + ret->psk_client_callback = NULL; + ret->psk_server_callback = NULL; +#endif +#ifndef OPENSSL_NO_SRP + SSL_CTX_SRP_CTX_init(ret); +#endif +#ifndef OPENSSL_NO_BUF_FREELISTS + ret->freelist_max_len = SSL_MAX_BUF_FREELIST_LEN_DEFAULT; + ret->rbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); + if (!ret->rbuf_freelist) + goto err; + ret->rbuf_freelist->chunklen = 0; + ret->rbuf_freelist->len = 0; + ret->rbuf_freelist->head = NULL; + ret->wbuf_freelist = OPENSSL_malloc(sizeof(SSL3_BUF_FREELIST)); + if (!ret->wbuf_freelist) { + OPENSSL_free(ret->rbuf_freelist); + goto err; + } + ret->wbuf_freelist->chunklen = 0; + ret->wbuf_freelist->len = 0; + ret->wbuf_freelist->head = NULL; +#endif +#ifndef OPENSSL_NO_ENGINE + ret->client_cert_engine = NULL; +# ifdef OPENSSL_SSL_CLIENT_ENGINE_AUTO +# define eng_strx(x) #x +# define eng_str(x) eng_strx(x) + /* Use specific client engine automatically... ignore errors */ + { + ENGINE *eng; + eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); + if (!eng) { + ERR_clear_error(); + ENGINE_load_builtin_engines(); + eng = ENGINE_by_id(eng_str(OPENSSL_SSL_CLIENT_ENGINE_AUTO)); + } + if (!eng || !SSL_CTX_set_client_cert_engine(ret, eng)) + ERR_clear_error(); + } +# endif +#endif + /* + * Default is to connect to non-RI servers. When RI is more widely + * deployed might change this. + */ + ret->options |= SSL_OP_LEGACY_SERVER_CONNECT; + + /* + * Disable SSLv2 by default, callers that want to enable SSLv2 will have to + * explicitly clear this option via either of SSL_CTX_clear_options() or + * SSL_clear_options(). + */ + ret->options |= SSL_OP_NO_SSLv2; + + return (ret); + err: + SSLerr(SSL_F_SSL_CTX_NEW, ERR_R_MALLOC_FAILURE); + err2: + if (ret != NULL) + SSL_CTX_free(ret); + return (NULL); +} + +#if 0 +static void SSL_COMP_free(SSL_COMP *comp) +{ + OPENSSL_free(comp); +} +#endif + +#ifndef OPENSSL_NO_BUF_FREELISTS +static void ssl_buf_freelist_free(SSL3_BUF_FREELIST *list) +{ + SSL3_BUF_FREELIST_ENTRY *ent, *next; + for (ent = list->head; ent; ent = next) { + next = ent->next; + OPENSSL_free(ent); + } + OPENSSL_free(list); +} +#endif + +void SSL_CTX_free(SSL_CTX *a) +{ + int i; + + if (a == NULL) + return; + + i = CRYPTO_add(&a->references, -1, CRYPTO_LOCK_SSL_CTX); +#ifdef REF_PRINT + REF_PRINT("SSL_CTX", a); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "SSL_CTX_free, bad reference count\n"); + abort(); /* ok */ + } +#endif + + if (a->param) + X509_VERIFY_PARAM_free(a->param); + + /* + * Free internal session cache. However: the remove_cb() may reference + * the ex_data of SSL_CTX, thus the ex_data store can only be removed + * after the sessions were flushed. + * As the ex_data handling routines might also touch the session cache, + * the most secure solution seems to be: empty (flush) the cache, then + * free ex_data, then finally free the cache. + * (See ticket [openssl.org #212].) + */ + if (a->sessions != NULL) + SSL_CTX_flush_sessions(a, 0); + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_CTX, a, &a->ex_data); + + if (a->sessions != NULL) + lh_SSL_SESSION_free(a->sessions); + + if (a->cert_store != NULL) + X509_STORE_free(a->cert_store); + if (a->cipher_list != NULL) + sk_SSL_CIPHER_free(a->cipher_list); + if (a->cipher_list_by_id != NULL) + sk_SSL_CIPHER_free(a->cipher_list_by_id); + if (a->cert != NULL) + ssl_cert_free(a->cert); + if (a->client_CA != NULL) + sk_X509_NAME_pop_free(a->client_CA, X509_NAME_free); + if (a->extra_certs != NULL) + sk_X509_pop_free(a->extra_certs, X509_free); +#if 0 /* This should never be done, since it + * removes a global database */ + if (a->comp_methods != NULL) + sk_SSL_COMP_pop_free(a->comp_methods, SSL_COMP_free); +#else + a->comp_methods = NULL; +#endif + +#ifndef OPENSSL_NO_SRTP + if (a->srtp_profiles) + sk_SRTP_PROTECTION_PROFILE_free(a->srtp_profiles); +#endif + +#ifndef OPENSSL_NO_PSK + if (a->psk_identity_hint) + OPENSSL_free(a->psk_identity_hint); +#endif +#ifndef OPENSSL_NO_SRP + SSL_CTX_SRP_CTX_free(a); +#endif +#ifndef OPENSSL_NO_ENGINE + if (a->client_cert_engine) + ENGINE_finish(a->client_cert_engine); +#endif + +#ifndef OPENSSL_NO_BUF_FREELISTS + if (a->wbuf_freelist) + ssl_buf_freelist_free(a->wbuf_freelist); + if (a->rbuf_freelist) + ssl_buf_freelist_free(a->rbuf_freelist); +#endif + + OPENSSL_free(a); +} + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) +{ + ctx->default_passwd_callback = cb; +} + +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *u) +{ + ctx->default_passwd_callback_userdata = u; +} + +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, + int (*cb) (X509_STORE_CTX *, void *), + void *arg) +{ + ctx->app_verify_callback = cb; + ctx->app_verify_arg = arg; +} + +void SSL_CTX_set_verify(SSL_CTX *ctx, int mode, + int (*cb) (int, X509_STORE_CTX *)) +{ + ctx->verify_mode = mode; + ctx->default_verify_callback = cb; +} + +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) +{ + X509_VERIFY_PARAM_set_depth(ctx->param, depth); +} + +void ssl_set_cert_masks(CERT *c, const SSL_CIPHER *cipher) +{ + CERT_PKEY *cpk; + int rsa_enc, rsa_tmp, rsa_sign, dh_tmp, dh_rsa, dh_dsa, dsa_sign; + int rsa_enc_export, dh_rsa_export, dh_dsa_export; + int rsa_tmp_export, dh_tmp_export, kl; + unsigned long mask_k, mask_a, emask_k, emask_a; +#ifndef OPENSSL_NO_ECDSA + int have_ecc_cert, ecdsa_ok, ecc_pkey_size; +#endif +#ifndef OPENSSL_NO_ECDH + int have_ecdh_tmp, ecdh_ok; +#endif +#ifndef OPENSSL_NO_EC + X509 *x = NULL; + EVP_PKEY *ecc_pkey = NULL; + int signature_nid = 0, pk_nid = 0, md_nid = 0; +#endif + if (c == NULL) + return; + + kl = SSL_C_EXPORT_PKEYLENGTH(cipher); + +#ifndef OPENSSL_NO_RSA + rsa_tmp = (c->rsa_tmp != NULL || c->rsa_tmp_cb != NULL); + rsa_tmp_export = (c->rsa_tmp_cb != NULL || + (rsa_tmp && RSA_size(c->rsa_tmp) * 8 <= kl)); +#else + rsa_tmp = rsa_tmp_export = 0; +#endif +#ifndef OPENSSL_NO_DH + dh_tmp = (c->dh_tmp != NULL || c->dh_tmp_cb != NULL); + dh_tmp_export = (c->dh_tmp_cb != NULL || + (dh_tmp && DH_size(c->dh_tmp) * 8 <= kl)); +#else + dh_tmp = dh_tmp_export = 0; +#endif + +#ifndef OPENSSL_NO_ECDH + have_ecdh_tmp = (c->ecdh_tmp != NULL || c->ecdh_tmp_cb != NULL); +#endif + cpk = &(c->pkeys[SSL_PKEY_RSA_ENC]); + rsa_enc = (cpk->x509 != NULL && cpk->privatekey != NULL); + rsa_enc_export = (rsa_enc && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); + cpk = &(c->pkeys[SSL_PKEY_RSA_SIGN]); + rsa_sign = (cpk->x509 != NULL && cpk->privatekey != NULL); + cpk = &(c->pkeys[SSL_PKEY_DSA_SIGN]); + dsa_sign = (cpk->x509 != NULL && cpk->privatekey != NULL); + cpk = &(c->pkeys[SSL_PKEY_DH_RSA]); + dh_rsa = (cpk->x509 != NULL && cpk->privatekey != NULL); + dh_rsa_export = (dh_rsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); + cpk = &(c->pkeys[SSL_PKEY_DH_DSA]); +/* FIX THIS EAY EAY EAY */ + dh_dsa = (cpk->x509 != NULL && cpk->privatekey != NULL); + dh_dsa_export = (dh_dsa && EVP_PKEY_size(cpk->privatekey) * 8 <= kl); + cpk = &(c->pkeys[SSL_PKEY_ECC]); +#ifndef OPENSSL_NO_EC + have_ecc_cert = (cpk->x509 != NULL && cpk->privatekey != NULL); +#endif + mask_k = 0; + mask_a = 0; + emask_k = 0; + emask_a = 0; + +#ifdef CIPHER_DEBUG + fprintf(stderr, + "rt=%d rte=%d dht=%d ecdht=%d re=%d ree=%d rs=%d ds=%d dhr=%d dhd=%d\n", + rsa_tmp, rsa_tmp_export, dh_tmp, have_ecdh_tmp, rsa_enc, + rsa_enc_export, rsa_sign, dsa_sign, dh_rsa, dh_dsa); +#endif + + cpk = &(c->pkeys[SSL_PKEY_GOST01]); + if (cpk->x509 != NULL && cpk->privatekey != NULL) { + mask_k |= SSL_kGOST; + mask_a |= SSL_aGOST01; + } + cpk = &(c->pkeys[SSL_PKEY_GOST94]); + if (cpk->x509 != NULL && cpk->privatekey != NULL) { + mask_k |= SSL_kGOST; + mask_a |= SSL_aGOST94; + } + + if (rsa_enc || (rsa_tmp && rsa_sign)) + mask_k |= SSL_kRSA; + if (rsa_enc_export || (rsa_tmp_export && (rsa_sign || rsa_enc))) + emask_k |= SSL_kRSA; + +#if 0 + /* The match needs to be both kEDH and aRSA or aDSA, so don't worry */ + if ((dh_tmp || dh_rsa || dh_dsa) && (rsa_enc || rsa_sign || dsa_sign)) + mask_k |= SSL_kEDH; + if ((dh_tmp_export || dh_rsa_export || dh_dsa_export) && + (rsa_enc || rsa_sign || dsa_sign)) + emask_k |= SSL_kEDH; +#endif + + if (dh_tmp_export) + emask_k |= SSL_kEDH; + + if (dh_tmp) + mask_k |= SSL_kEDH; + + if (dh_rsa) + mask_k |= SSL_kDHr; + if (dh_rsa_export) + emask_k |= SSL_kDHr; + + if (dh_dsa) + mask_k |= SSL_kDHd; + if (dh_dsa_export) + emask_k |= SSL_kDHd; + + if (rsa_enc || rsa_sign) { + mask_a |= SSL_aRSA; + emask_a |= SSL_aRSA; + } + + if (dsa_sign) { + mask_a |= SSL_aDSS; + emask_a |= SSL_aDSS; + } + + mask_a |= SSL_aNULL; + emask_a |= SSL_aNULL; + +#ifndef OPENSSL_NO_KRB5 + mask_k |= SSL_kKRB5; + mask_a |= SSL_aKRB5; + emask_k |= SSL_kKRB5; + emask_a |= SSL_aKRB5; +#endif + + /* + * An ECC certificate may be usable for ECDH and/or ECDSA cipher suites + * depending on the key usage extension. + */ +#ifndef OPENSSL_NO_EC + if (have_ecc_cert) { + /* This call populates extension flags (ex_flags) */ + x = (c->pkeys[SSL_PKEY_ECC]).x509; + X509_check_purpose(x, -1, 0); + ecdh_ok = (x->ex_flags & EXFLAG_KUSAGE) ? + (x->ex_kusage & X509v3_KU_KEY_AGREEMENT) : 1; + ecdsa_ok = (x->ex_flags & EXFLAG_KUSAGE) ? + (x->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE) : 1; + ecc_pkey = X509_get_pubkey(x); + ecc_pkey_size = (ecc_pkey != NULL) ? EVP_PKEY_bits(ecc_pkey) : 0; + EVP_PKEY_free(ecc_pkey); + if ((x->sig_alg) && (x->sig_alg->algorithm)) { + signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); + OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); + } +#ifndef OPENSSL_NO_ECDH + if (ecdh_ok) { + + if (pk_nid == NID_rsaEncryption || pk_nid == NID_rsa) { + mask_k |= SSL_kECDHr; + mask_a |= SSL_aECDH; + if (ecc_pkey_size <= 163) { + emask_k |= SSL_kECDHr; + emask_a |= SSL_aECDH; + } + } + + if (pk_nid == NID_X9_62_id_ecPublicKey) { + mask_k |= SSL_kECDHe; + mask_a |= SSL_aECDH; + if (ecc_pkey_size <= 163) { + emask_k |= SSL_kECDHe; + emask_a |= SSL_aECDH; + } + } + } +#endif +#ifndef OPENSSL_NO_ECDSA + if (ecdsa_ok) { + mask_a |= SSL_aECDSA; + emask_a |= SSL_aECDSA; + } +#endif + } +#endif +#ifndef OPENSSL_NO_ECDH + if (have_ecdh_tmp) { + mask_k |= SSL_kEECDH; + emask_k |= SSL_kEECDH; + } +#endif + +#ifndef OPENSSL_NO_PSK + mask_k |= SSL_kPSK; + mask_a |= SSL_aPSK; + emask_k |= SSL_kPSK; + emask_a |= SSL_aPSK; +#endif + + c->mask_k = mask_k; + c->mask_a = mask_a; + c->export_mask_k = emask_k; + c->export_mask_a = emask_a; + c->valid = 1; +} + +/* This handy macro borrowed from crypto/x509v3/v3_purp.c */ +#define ku_reject(x, usage) \ + (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage))) + +#ifndef OPENSSL_NO_EC + +int ssl_check_srvr_ecc_cert_and_alg(X509 *x, SSL *s) +{ + unsigned long alg_k, alg_a; + EVP_PKEY *pkey = NULL; + int keysize = 0; + int signature_nid = 0, md_nid = 0, pk_nid = 0; + const SSL_CIPHER *cs = s->s3->tmp.new_cipher; + + alg_k = cs->algorithm_mkey; + alg_a = cs->algorithm_auth; + + if (SSL_C_IS_EXPORT(cs)) { + /* ECDH key length in export ciphers must be <= 163 bits */ + pkey = X509_get_pubkey(x); + if (pkey == NULL) + return 0; + keysize = EVP_PKEY_bits(pkey); + EVP_PKEY_free(pkey); + if (keysize > 163) + return 0; + } + + /* This call populates the ex_flags field correctly */ + X509_check_purpose(x, -1, 0); + if ((x->sig_alg) && (x->sig_alg->algorithm)) { + signature_nid = OBJ_obj2nid(x->sig_alg->algorithm); + OBJ_find_sigid_algs(signature_nid, &md_nid, &pk_nid); + } + if (alg_k & SSL_kECDHe || alg_k & SSL_kECDHr) { + /* key usage, if present, must allow key agreement */ + if (ku_reject(x, X509v3_KU_KEY_AGREEMENT)) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, + SSL_R_ECC_CERT_NOT_FOR_KEY_AGREEMENT); + return 0; + } + if ((alg_k & SSL_kECDHe) && TLS1_get_version(s) < TLS1_2_VERSION) { + /* signature alg must be ECDSA */ + if (pk_nid != NID_X9_62_id_ecPublicKey) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, + SSL_R_ECC_CERT_SHOULD_HAVE_SHA1_SIGNATURE); + return 0; + } + } + if ((alg_k & SSL_kECDHr) && TLS1_get_version(s) < TLS1_2_VERSION) { + /* signature alg must be RSA */ + + if (pk_nid != NID_rsaEncryption && pk_nid != NID_rsa) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, + SSL_R_ECC_CERT_SHOULD_HAVE_RSA_SIGNATURE); + return 0; + } + } + } + if (alg_a & SSL_aECDSA) { + /* key usage, if present, must allow signing */ + if (ku_reject(x, X509v3_KU_DIGITAL_SIGNATURE)) { + SSLerr(SSL_F_SSL_CHECK_SRVR_ECC_CERT_AND_ALG, + SSL_R_ECC_CERT_NOT_FOR_SIGNING); + return 0; + } + } + + return 1; /* all checks are ok */ +} + +#endif + +/* THIS NEEDS CLEANING UP */ +CERT_PKEY *ssl_get_server_send_pkey(const SSL *s) +{ + unsigned long alg_k, alg_a; + CERT *c; + int i; + + c = s->cert; + ssl_set_cert_masks(c, s->s3->tmp.new_cipher); + + alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + alg_a = s->s3->tmp.new_cipher->algorithm_auth; + + if (alg_k & (SSL_kECDHr | SSL_kECDHe)) { + /* + * we don't need to look at SSL_kEECDH since no certificate is needed + * for anon ECDH and for authenticated EECDH, the check for the auth + * algorithm will set i correctly NOTE: For ECDH-RSA, we need an ECC + * not an RSA cert but for EECDH-RSA we need an RSA cert. Placing the + * checks for SSL_kECDH before RSA checks ensures the correct cert is + * chosen. + */ + i = SSL_PKEY_ECC; + } else if (alg_a & SSL_aECDSA) { + i = SSL_PKEY_ECC; + } else if (alg_k & SSL_kDHr) + i = SSL_PKEY_DH_RSA; + else if (alg_k & SSL_kDHd) + i = SSL_PKEY_DH_DSA; + else if (alg_a & SSL_aDSS) + i = SSL_PKEY_DSA_SIGN; + else if (alg_a & SSL_aRSA) { + if (c->pkeys[SSL_PKEY_RSA_ENC].x509 == NULL) + i = SSL_PKEY_RSA_SIGN; + else + i = SSL_PKEY_RSA_ENC; + } else if (alg_a & SSL_aKRB5) { + /* VRS something else here? */ + return (NULL); + } else if (alg_a & SSL_aGOST94) + i = SSL_PKEY_GOST94; + else if (alg_a & SSL_aGOST01) + i = SSL_PKEY_GOST01; + else { /* if (alg_a & SSL_aNULL) */ + + SSLerr(SSL_F_SSL_GET_SERVER_SEND_PKEY, ERR_R_INTERNAL_ERROR); + return (NULL); + } + + return c->pkeys + i; +} + +X509 *ssl_get_server_send_cert(const SSL *s) +{ + CERT_PKEY *cpk; + cpk = ssl_get_server_send_pkey(s); + if (!cpk) + return NULL; + return cpk->x509; +} + +EVP_PKEY *ssl_get_sign_pkey(SSL *s, const SSL_CIPHER *cipher, + const EVP_MD **pmd) +{ + unsigned long alg_a; + CERT *c; + int idx = -1; + + alg_a = cipher->algorithm_auth; + c = s->cert; + + if ((alg_a & SSL_aDSS) && + (c->pkeys[SSL_PKEY_DSA_SIGN].privatekey != NULL)) + idx = SSL_PKEY_DSA_SIGN; + else if (alg_a & SSL_aRSA) { + if (c->pkeys[SSL_PKEY_RSA_SIGN].privatekey != NULL) + idx = SSL_PKEY_RSA_SIGN; + else if (c->pkeys[SSL_PKEY_RSA_ENC].privatekey != NULL) + idx = SSL_PKEY_RSA_ENC; + } else if ((alg_a & SSL_aECDSA) && + (c->pkeys[SSL_PKEY_ECC].privatekey != NULL)) + idx = SSL_PKEY_ECC; + if (idx == -1) { + SSLerr(SSL_F_SSL_GET_SIGN_PKEY, ERR_R_INTERNAL_ERROR); + return (NULL); + } + if (pmd) + *pmd = c->pkeys[idx].digest; + return c->pkeys[idx].privatekey; +} + +void ssl_update_cache(SSL *s, int mode) +{ + int i; + + /* + * If the session_id_length is 0, we are not supposed to cache it, and it + * would be rather hard to do anyway :-) + */ + if (s->session->session_id_length == 0) + return; + + i = s->session_ctx->session_cache_mode; + if ((i & mode) && (!s->hit) + && ((i & SSL_SESS_CACHE_NO_INTERNAL_STORE) + || SSL_CTX_add_session(s->session_ctx, s->session)) + && (s->session_ctx->new_session_cb != NULL)) { + CRYPTO_add(&s->session->references, 1, CRYPTO_LOCK_SSL_SESSION); + if (!s->session_ctx->new_session_cb(s, s->session)) + SSL_SESSION_free(s->session); + } + + /* auto flush every 255 connections */ + if ((!(i & SSL_SESS_CACHE_NO_AUTO_CLEAR)) && ((i & mode) == mode)) { + if ((((mode & SSL_SESS_CACHE_CLIENT) + ? s->session_ctx->stats.sess_connect_good + : s->session_ctx->stats.sess_accept_good) & 0xff) == 0xff) { + SSL_CTX_flush_sessions(s->session_ctx, (unsigned long)time(NULL)); + } + } +} + +const SSL_METHOD *SSL_get_ssl_method(SSL *s) +{ + return (s->method); +} + +int SSL_set_ssl_method(SSL *s, const SSL_METHOD *meth) +{ + int conn = -1; + int ret = 1; + + if (s->method != meth) { + if (s->handshake_func != NULL) + conn = (s->handshake_func == s->method->ssl_connect); + + if (s->method->version == meth->version) + s->method = meth; + else { + s->method->ssl_free(s); + s->method = meth; + ret = s->method->ssl_new(s); + } + + if (conn == 1) + s->handshake_func = meth->ssl_connect; + else if (conn == 0) + s->handshake_func = meth->ssl_accept; + } + return (ret); +} + +int SSL_get_error(const SSL *s, int i) +{ + int reason; + unsigned long l; + BIO *bio; + + if (i > 0) + return (SSL_ERROR_NONE); + + /* + * Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc, + * where we do encode the error + */ + if ((l = ERR_peek_error()) != 0) { + if (ERR_GET_LIB(l) == ERR_LIB_SYS) + return (SSL_ERROR_SYSCALL); + else + return (SSL_ERROR_SSL); + } + + if ((i < 0) && SSL_want_read(s)) { + bio = SSL_get_rbio(s); + if (BIO_should_read(bio)) + return (SSL_ERROR_WANT_READ); + else if (BIO_should_write(bio)) + /* + * This one doesn't make too much sense ... We never try to write + * to the rbio, and an application program where rbio and wbio + * are separate couldn't even know what it should wait for. + * However if we ever set s->rwstate incorrectly (so that we have + * SSL_want_read(s) instead of SSL_want_write(s)) and rbio and + * wbio *are* the same, this test works around that bug; so it + * might be safer to keep it. + */ + return (SSL_ERROR_WANT_WRITE); + else if (BIO_should_io_special(bio)) { + reason = BIO_get_retry_reason(bio); + if (reason == BIO_RR_CONNECT) + return (SSL_ERROR_WANT_CONNECT); + else if (reason == BIO_RR_ACCEPT) + return (SSL_ERROR_WANT_ACCEPT); + else + return (SSL_ERROR_SYSCALL); /* unknown */ + } + } + + if ((i < 0) && SSL_want_write(s)) { + bio = SSL_get_wbio(s); + if (BIO_should_write(bio)) + return (SSL_ERROR_WANT_WRITE); + else if (BIO_should_read(bio)) + /* + * See above (SSL_want_read(s) with BIO_should_write(bio)) + */ + return (SSL_ERROR_WANT_READ); + else if (BIO_should_io_special(bio)) { + reason = BIO_get_retry_reason(bio); + if (reason == BIO_RR_CONNECT) + return (SSL_ERROR_WANT_CONNECT); + else if (reason == BIO_RR_ACCEPT) + return (SSL_ERROR_WANT_ACCEPT); + else + return (SSL_ERROR_SYSCALL); + } + } + if ((i < 0) && SSL_want_x509_lookup(s)) { + return (SSL_ERROR_WANT_X509_LOOKUP); + } + + if (i == 0) { + if (s->version == SSL2_VERSION) { + /* assume it is the socket being closed */ + return (SSL_ERROR_ZERO_RETURN); + } else { + if ((s->shutdown & SSL_RECEIVED_SHUTDOWN) && + (s->s3->warn_alert == SSL_AD_CLOSE_NOTIFY)) + return (SSL_ERROR_ZERO_RETURN); + } + } + return (SSL_ERROR_SYSCALL); +} + +int SSL_do_handshake(SSL *s) +{ + int ret = 1; + + if (s->handshake_func == NULL) { + SSLerr(SSL_F_SSL_DO_HANDSHAKE, SSL_R_CONNECTION_TYPE_NOT_SET); + return (-1); + } + + s->method->ssl_renegotiate_check(s); + + if (SSL_in_init(s) || SSL_in_before(s)) { + ret = s->handshake_func(s); + } + return (ret); +} + +/* + * For the next 2 functions, SSL_clear() sets shutdown and so one of these + * calls will reset it + */ +void SSL_set_accept_state(SSL *s) +{ + s->server = 1; + s->shutdown = 0; + s->state = SSL_ST_ACCEPT | SSL_ST_BEFORE; + s->handshake_func = s->method->ssl_accept; + /* clear the current cipher */ + ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); +} + +void SSL_set_connect_state(SSL *s) +{ + s->server = 0; + s->shutdown = 0; + s->state = SSL_ST_CONNECT | SSL_ST_BEFORE; + s->handshake_func = s->method->ssl_connect; + /* clear the current cipher */ + ssl_clear_cipher_ctx(s); + ssl_clear_hash_ctx(&s->read_hash); + ssl_clear_hash_ctx(&s->write_hash); +} + +int ssl_undefined_function(SSL *s) +{ + SSLerr(SSL_F_SSL_UNDEFINED_FUNCTION, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); +} + +int ssl_undefined_void_function(void) +{ + SSLerr(SSL_F_SSL_UNDEFINED_VOID_FUNCTION, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); +} + +int ssl_undefined_const_function(const SSL *s) +{ + SSLerr(SSL_F_SSL_UNDEFINED_CONST_FUNCTION, + ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (0); +} + +SSL_METHOD *ssl_bad_method(int ver) +{ + SSLerr(SSL_F_SSL_BAD_METHOD, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return (NULL); +} + +const char *SSL_get_version(const SSL *s) +{ + if (s->version == TLS1_2_VERSION) + return ("TLSv1.2"); + else if (s->version == TLS1_1_VERSION) + return ("TLSv1.1"); + else if (s->version == TLS1_VERSION) + return ("TLSv1"); + else if (s->version == SSL3_VERSION) + return ("SSLv3"); + else if (s->version == SSL2_VERSION) + return ("SSLv2"); + else + return ("unknown"); +} + +SSL *SSL_dup(SSL *s) +{ + STACK_OF(X509_NAME) *sk; + X509_NAME *xn; + SSL *ret; + int i; + + if ((ret = SSL_new(SSL_get_SSL_CTX(s))) == NULL) + return (NULL); + + ret->version = s->version; + ret->type = s->type; + ret->method = s->method; + + if (s->session != NULL) { + /* This copies session-id, SSL_METHOD, sid_ctx, and 'cert' */ + SSL_copy_session_id(ret, s); + } else { + /* + * No session has been established yet, so we have to expect that + * s->cert or ret->cert will be changed later -- they should not both + * point to the same object, and thus we can't use + * SSL_copy_session_id. + */ + + ret->method->ssl_free(ret); + ret->method = s->method; + ret->method->ssl_new(ret); + + if (s->cert != NULL) { + if (ret->cert != NULL) { + ssl_cert_free(ret->cert); + } + ret->cert = ssl_cert_dup(s->cert); + if (ret->cert == NULL) + goto err; + } + + SSL_set_session_id_context(ret, s->sid_ctx, s->sid_ctx_length); + } + + ret->options = s->options; + ret->mode = s->mode; + SSL_set_max_cert_list(ret, SSL_get_max_cert_list(s)); + SSL_set_read_ahead(ret, SSL_get_read_ahead(s)); + ret->msg_callback = s->msg_callback; + ret->msg_callback_arg = s->msg_callback_arg; + SSL_set_verify(ret, SSL_get_verify_mode(s), SSL_get_verify_callback(s)); + SSL_set_verify_depth(ret, SSL_get_verify_depth(s)); + ret->generate_session_id = s->generate_session_id; + + SSL_set_info_callback(ret, SSL_get_info_callback(s)); + + ret->debug = s->debug; + + /* copy app data, a little dangerous perhaps */ + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL, &ret->ex_data, &s->ex_data)) + goto err; + + /* setup rbio, and wbio */ + if (s->rbio != NULL) { + if (!BIO_dup_state(s->rbio, (char *)&ret->rbio)) + goto err; + } + if (s->wbio != NULL) { + if (s->wbio != s->rbio) { + if (!BIO_dup_state(s->wbio, (char *)&ret->wbio)) + goto err; + } else + ret->wbio = ret->rbio; + } + ret->rwstate = s->rwstate; + ret->in_handshake = s->in_handshake; + ret->handshake_func = s->handshake_func; + ret->server = s->server; + ret->renegotiate = s->renegotiate; + ret->new_session = s->new_session; + ret->quiet_shutdown = s->quiet_shutdown; + ret->shutdown = s->shutdown; + ret->state = s->state; /* SSL_dup does not really work at any state, + * though */ + ret->rstate = s->rstate; + ret->init_num = 0; /* would have to copy ret->init_buf, + * ret->init_msg, ret->init_num, + * ret->init_off */ + ret->hit = s->hit; + + X509_VERIFY_PARAM_inherit(ret->param, s->param); + + /* dup the cipher_list and cipher_list_by_id stacks */ + if (s->cipher_list != NULL) { + if ((ret->cipher_list = sk_SSL_CIPHER_dup(s->cipher_list)) == NULL) + goto err; + } + if (s->cipher_list_by_id != NULL) + if ((ret->cipher_list_by_id = sk_SSL_CIPHER_dup(s->cipher_list_by_id)) + == NULL) + goto err; + + /* Dup the client_CA list */ + if (s->client_CA != NULL) { + if ((sk = sk_X509_NAME_dup(s->client_CA)) == NULL) + goto err; + ret->client_CA = sk; + for (i = 0; i < sk_X509_NAME_num(sk); i++) { + xn = sk_X509_NAME_value(sk, i); + if (sk_X509_NAME_set(sk, i, X509_NAME_dup(xn)) == NULL) { + X509_NAME_free(xn); + goto err; + } + } + } + + if (0) { + err: + if (ret != NULL) + SSL_free(ret); + ret = NULL; + } + return (ret); +} + +void ssl_clear_cipher_ctx(SSL *s) +{ + if (s->enc_read_ctx != NULL) { + EVP_CIPHER_CTX_cleanup(s->enc_read_ctx); + OPENSSL_free(s->enc_read_ctx); + s->enc_read_ctx = NULL; + } + if (s->enc_write_ctx != NULL) { + EVP_CIPHER_CTX_cleanup(s->enc_write_ctx); + OPENSSL_free(s->enc_write_ctx); + s->enc_write_ctx = NULL; + } +#ifndef OPENSSL_NO_COMP + if (s->expand != NULL) { + COMP_CTX_free(s->expand); + s->expand = NULL; + } + if (s->compress != NULL) { + COMP_CTX_free(s->compress); + s->compress = NULL; + } +#endif +} + +/* Fix this function so that it takes an optional type parameter */ +X509 *SSL_get_certificate(const SSL *s) +{ + if (s->cert != NULL) + return (s->cert->key->x509); + else + return (NULL); +} + +/* Fix this function so that it takes an optional type parameter */ +EVP_PKEY *SSL_get_privatekey(SSL *s) +{ + if (s->cert != NULL) + return (s->cert->key->privatekey); + else + return (NULL); +} + +const SSL_CIPHER *SSL_get_current_cipher(const SSL *s) +{ + if ((s->session != NULL) && (s->session->cipher != NULL)) + return (s->session->cipher); + return (NULL); +} + +#ifdef OPENSSL_NO_COMP +const void *SSL_get_current_compression(SSL *s) +{ + return NULL; +} + +const void *SSL_get_current_expansion(SSL *s) +{ + return NULL; +} +#else + +const COMP_METHOD *SSL_get_current_compression(SSL *s) +{ + if (s->compress != NULL) + return (s->compress->meth); + return (NULL); +} + +const COMP_METHOD *SSL_get_current_expansion(SSL *s) +{ + if (s->expand != NULL) + return (s->expand->meth); + return (NULL); +} +#endif + +int ssl_init_wbio_buffer(SSL *s, int push) +{ + BIO *bbio; + + if (s->bbio == NULL) { + bbio = BIO_new(BIO_f_buffer()); + if (bbio == NULL) + return (0); + s->bbio = bbio; + } else { + bbio = s->bbio; + if (s->bbio == s->wbio) + s->wbio = BIO_pop(s->wbio); + } + (void)BIO_reset(bbio); +/* if (!BIO_set_write_buffer_size(bbio,16*1024)) */ + if (!BIO_set_read_buffer_size(bbio, 1)) { + SSLerr(SSL_F_SSL_INIT_WBIO_BUFFER, ERR_R_BUF_LIB); + return (0); + } + if (push) { + if (s->wbio != bbio) + s->wbio = BIO_push(bbio, s->wbio); + } else { + if (s->wbio == bbio) + s->wbio = BIO_pop(bbio); + } + return (1); +} + +void ssl_free_wbio_buffer(SSL *s) +{ + if (s->bbio == NULL) + return; + + if (s->bbio == s->wbio) { + /* remove buffering */ + s->wbio = BIO_pop(s->wbio); +#ifdef REF_CHECK /* not the usual REF_CHECK, but this avoids + * adding one more preprocessor symbol */ + assert(s->wbio != NULL); +#endif + } + BIO_free(s->bbio); + s->bbio = NULL; +} + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) +{ + ctx->quiet_shutdown = mode; +} + +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) +{ + return (ctx->quiet_shutdown); +} + +void SSL_set_quiet_shutdown(SSL *s, int mode) +{ + s->quiet_shutdown = mode; +} + +int SSL_get_quiet_shutdown(const SSL *s) +{ + return (s->quiet_shutdown); +} + +void SSL_set_shutdown(SSL *s, int mode) +{ + s->shutdown = mode; +} + +int SSL_get_shutdown(const SSL *s) +{ + return (s->shutdown); +} + +int SSL_version(const SSL *s) +{ + return (s->version); +} + +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) +{ + return (ssl->ctx); +} + +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) +{ + CERT *ocert = ssl->cert; + if (ssl->ctx == ctx) + return ssl->ctx; +#ifndef OPENSSL_NO_TLSEXT + if (ctx == NULL) + ctx = ssl->initial_ctx; +#endif + ssl->cert = ssl_cert_dup(ctx->cert); + if (ocert != NULL) { + int i; + /* Copy negotiated digests from original */ + for (i = 0; i < SSL_PKEY_NUM; i++) { + CERT_PKEY *cpk = ocert->pkeys + i; + CERT_PKEY *rpk = ssl->cert->pkeys + i; + rpk->digest = cpk->digest; + } + ssl_cert_free(ocert); + } + + /* + * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH), + * so setter APIs must prevent invalid lengths from entering the system. + */ + OPENSSL_assert(ssl->sid_ctx_length <= sizeof(ssl->sid_ctx)); + + /* + * If the session ID context matches that of the parent SSL_CTX, + * inherit it from the new SSL_CTX as well. If however the context does + * not match (i.e., it was set per-ssl with SSL_set_session_id_context), + * leave it unchanged. + */ + if ((ssl->ctx != NULL) && + (ssl->sid_ctx_length == ssl->ctx->sid_ctx_length) && + (memcmp(ssl->sid_ctx, ssl->ctx->sid_ctx, ssl->sid_ctx_length) == 0)) { + ssl->sid_ctx_length = ctx->sid_ctx_length; + memcpy(&ssl->sid_ctx, &ctx->sid_ctx, sizeof(ssl->sid_ctx)); + } + + CRYPTO_add(&ctx->references, 1, CRYPTO_LOCK_SSL_CTX); + if (ssl->ctx != NULL) + SSL_CTX_free(ssl->ctx); /* decrement reference count */ + ssl->ctx = ctx; + + return (ssl->ctx); +} + +#ifndef OPENSSL_NO_STDIO +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) +{ + return (X509_STORE_set_default_paths(ctx->cert_store)); +} + +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *CAfile, + const char *CApath) +{ + return (X509_STORE_load_locations(ctx->cert_store, CAfile, CApath)); +} +#endif + +void SSL_set_info_callback(SSL *ssl, + void (*cb) (const SSL *ssl, int type, int val)) +{ + ssl->info_callback = cb; +} + +/* + * One compiler (Diab DCC) doesn't like argument names in returned function + * pointer. + */ +void (*SSL_get_info_callback(const SSL *ssl)) (const SSL * /* ssl */ , + int /* type */ , + int /* val */ ) { + return ssl->info_callback; +} + +int SSL_state(const SSL *ssl) +{ + return (ssl->state); +} + +void SSL_set_state(SSL *ssl, int state) +{ + ssl->state = state; +} + +void SSL_set_verify_result(SSL *ssl, long arg) +{ + ssl->verify_result = arg; +} + +long SSL_get_verify_result(const SSL *ssl) +{ + return (ssl->verify_result); +} + +int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL, argl, argp, + new_func, dup_func, free_func); +} + +int SSL_set_ex_data(SSL *s, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); +} + +void *SSL_get_ex_data(const SSL *s, int idx) +{ + return (CRYPTO_get_ex_data(&s->ex_data, idx)); +} + +int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_CTX, argl, argp, + new_func, dup_func, free_func); +} + +int SSL_CTX_set_ex_data(SSL_CTX *s, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); +} + +void *SSL_CTX_get_ex_data(const SSL_CTX *s, int idx) +{ + return (CRYPTO_get_ex_data(&s->ex_data, idx)); +} + +int ssl_ok(SSL *s) +{ + return (1); +} + +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) +{ + return (ctx->cert_store); +} + +void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) +{ + if (ctx->cert_store != NULL) + X509_STORE_free(ctx->cert_store); + ctx->cert_store = store; +} + +int SSL_want(const SSL *s) +{ + return (s->rwstate); +} + +/** + * \brief Set the callback for generating temporary RSA keys. + * \param ctx the SSL context. + * \param cb the callback + */ + +#ifndef OPENSSL_NO_RSA +void SSL_CTX_set_tmp_rsa_callback(SSL_CTX *ctx, RSA *(*cb) (SSL *ssl, + int is_export, + int keylength)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb); +} + +void SSL_set_tmp_rsa_callback(SSL *ssl, RSA *(*cb) (SSL *ssl, + int is_export, + int keylength)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_RSA_CB, (void (*)(void))cb); +} +#endif + +#ifdef DOXYGEN +/** + * \brief The RSA temporary key callback function. + * \param ssl the SSL session. + * \param is_export \c TRUE if the temp RSA key is for an export ciphersuite. + * \param keylength if \c is_export is \c TRUE, then \c keylength is the size + * of the required key in bits. + * \return the temporary RSA key. + * \sa SSL_CTX_set_tmp_rsa_callback, SSL_set_tmp_rsa_callback + */ + +RSA *cb(SSL *ssl, int is_export, int keylength) +{ +} +#endif + +/** + * \brief Set the callback for generating temporary DH keys. + * \param ctx the SSL context. + * \param dh the callback + */ + +#ifndef OPENSSL_NO_DH +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*dh) (SSL *ssl, int is_export, + int keylength)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh); +} + +void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*dh) (SSL *ssl, int is_export, + int keylength)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_DH_CB, (void (*)(void))dh); +} +#endif + +#ifndef OPENSSL_NO_ECDH +void SSL_CTX_set_tmp_ecdh_callback(SSL_CTX *ctx, + EC_KEY *(*ecdh) (SSL *ssl, int is_export, + int keylength)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_TMP_ECDH_CB, + (void (*)(void))ecdh); +} + +void SSL_set_tmp_ecdh_callback(SSL *ssl, + EC_KEY *(*ecdh) (SSL *ssl, int is_export, + int keylength)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_TMP_ECDH_CB, (void (*)(void))ecdh); +} +#endif + +#ifndef OPENSSL_NO_PSK +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) +{ + if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { + SSLerr(SSL_F_SSL_CTX_USE_PSK_IDENTITY_HINT, + SSL_R_DATA_LENGTH_TOO_LONG); + return 0; + } + if (ctx->psk_identity_hint != NULL) + OPENSSL_free(ctx->psk_identity_hint); + if (identity_hint != NULL) { + ctx->psk_identity_hint = BUF_strdup(identity_hint); + if (ctx->psk_identity_hint == NULL) + return 0; + } else + ctx->psk_identity_hint = NULL; + return 1; +} + +int SSL_use_psk_identity_hint(SSL *s, const char *identity_hint) +{ + if (s == NULL) + return 0; + + if (s->session == NULL) + return 1; /* session not created yet, ignored */ + + if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { + SSLerr(SSL_F_SSL_USE_PSK_IDENTITY_HINT, SSL_R_DATA_LENGTH_TOO_LONG); + return 0; + } + if (s->session->psk_identity_hint != NULL) + OPENSSL_free(s->session->psk_identity_hint); + if (identity_hint != NULL) { + s->session->psk_identity_hint = BUF_strdup(identity_hint); + if (s->session->psk_identity_hint == NULL) + return 0; + } else + s->session->psk_identity_hint = NULL; + return 1; +} + +const char *SSL_get_psk_identity_hint(const SSL *s) +{ + if (s == NULL || s->session == NULL) + return NULL; + return (s->session->psk_identity_hint); +} + +const char *SSL_get_psk_identity(const SSL *s) +{ + if (s == NULL || s->session == NULL) + return NULL; + return (s->session->psk_identity); +} + +void SSL_set_psk_client_callback(SSL *s, + unsigned int (*cb) (SSL *ssl, + const char *hint, + char *identity, + unsigned int + max_identity_len, + unsigned char *psk, + unsigned int + max_psk_len)) +{ + s->psk_client_callback = cb; +} + +void SSL_CTX_set_psk_client_callback(SSL_CTX *ctx, + unsigned int (*cb) (SSL *ssl, + const char *hint, + char *identity, + unsigned int + max_identity_len, + unsigned char *psk, + unsigned int + max_psk_len)) +{ + ctx->psk_client_callback = cb; +} + +void SSL_set_psk_server_callback(SSL *s, + unsigned int (*cb) (SSL *ssl, + const char *identity, + unsigned char *psk, + unsigned int + max_psk_len)) +{ + s->psk_server_callback = cb; +} + +void SSL_CTX_set_psk_server_callback(SSL_CTX *ctx, + unsigned int (*cb) (SSL *ssl, + const char *identity, + unsigned char *psk, + unsigned int + max_psk_len)) +{ + ctx->psk_server_callback = cb; +} +#endif + +void SSL_CTX_set_msg_callback(SSL_CTX *ctx, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)) +{ + SSL_CTX_callback_ctrl(ctx, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb); +} + +void SSL_set_msg_callback(SSL *ssl, + void (*cb) (int write_p, int version, + int content_type, const void *buf, + size_t len, SSL *ssl, void *arg)) +{ + SSL_callback_ctrl(ssl, SSL_CTRL_SET_MSG_CALLBACK, (void (*)(void))cb); +} + +/* + * Allocates new EVP_MD_CTX and sets pointer to it into given pointer + * vairable, freeing EVP_MD_CTX previously stored in that variable, if any. + * If EVP_MD pointer is passed, initializes ctx with this md Returns newly + * allocated ctx; + */ + +EVP_MD_CTX *ssl_replace_hash(EVP_MD_CTX **hash, const EVP_MD *md) +{ + ssl_clear_hash_ctx(hash); + *hash = EVP_MD_CTX_create(); + if (*hash == NULL || (md && EVP_DigestInit_ex(*hash, md, NULL) <= 0)) { + EVP_MD_CTX_destroy(*hash); + *hash = NULL; + return NULL; + } + return *hash; +} + +void ssl_clear_hash_ctx(EVP_MD_CTX **hash) +{ + + if (*hash) + EVP_MD_CTX_destroy(*hash); + *hash = NULL; +} + +void SSL_set_debug(SSL *s, int debug) +{ + s->debug = debug; +} + +int SSL_cache_hit(SSL *s) +{ + return s->hit; +} + +#if defined(_WINDLL) && defined(OPENSSL_SYS_WIN16) +# include "../crypto/bio/bss_file.c" +#endif + +IMPLEMENT_STACK_OF(SSL_CIPHER) +IMPLEMENT_STACK_OF(SSL_COMP) +IMPLEMENT_OBJ_BSEARCH_GLOBAL_CMP_FN(SSL_CIPHER, SSL_CIPHER, ssl_cipher_id); diff --git a/libs/openssl/ssl/ssl_rsa.c b/libs/openssl/ssl/ssl_rsa.c new file mode 100644 index 00000000..c91a9981 --- /dev/null +++ b/libs/openssl/ssl/ssl_rsa.c @@ -0,0 +1,749 @@ +/* ssl/ssl_rsa.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "ssl_locl.h" +#include +#include +#include +#include +#include + +static int ssl_set_cert(CERT *c, X509 *x509); +static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey); +int SSL_use_certificate(SSL *ssl, X509 *x) +{ + if (x == NULL) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ssl->cert)) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE); + return (0); + } + return (ssl_set_cert(ssl->cert, x)); +} + +#ifndef OPENSSL_NO_STDIO +int SSL_use_certificate_file(SSL *ssl, const char *file, int type) +{ + int j; + BIO *in; + int ret = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (x == NULL) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_FILE, j); + goto end; + } + + ret = SSL_use_certificate(ssl, x); + end: + if (x != NULL) + X509_free(x); + if (in != NULL) + BIO_free(in); + return (ret); +} +#endif + +int SSL_use_certificate_ASN1(SSL *ssl, const unsigned char *d, int len) +{ + X509 *x; + int ret; + + x = d2i_X509(NULL, &d, (long)len); + if (x == NULL) { + SSLerr(SSL_F_SSL_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_use_certificate(ssl, x); + X509_free(x); + return (ret); +} + +#ifndef OPENSSL_NO_RSA +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) +{ + EVP_PKEY *pkey; + int ret; + + if (rsa == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ssl->cert)) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); + return (0); + } + if ((pkey = EVP_PKEY_new()) == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); + return (0); + } + + RSA_up_ref(rsa); + if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { + RSA_free(rsa); + return 0; + } + + ret = ssl_set_pkey(ssl->cert, pkey); + EVP_PKEY_free(pkey); + return (ret); +} +#endif + +static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey) +{ + int i; + + i = ssl_cert_type(NULL, pkey); + if (i < 0) { + SSLerr(SSL_F_SSL_SET_PKEY, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return (0); + } + + if (c->pkeys[i].x509 != NULL) { + EVP_PKEY *pktmp; + pktmp = X509_get_pubkey(c->pkeys[i].x509); + if (pktmp == NULL) { + SSLerr(SSL_F_SSL_SET_PKEY, ERR_R_MALLOC_FAILURE); + EVP_PKEY_free(pktmp); + return 0; + } + /* + * The return code from EVP_PKEY_copy_parameters is deliberately + * ignored. Some EVP_PKEY types cannot do this. + */ + EVP_PKEY_copy_parameters(pktmp, pkey); + EVP_PKEY_free(pktmp); + ERR_clear_error(); + +#ifndef OPENSSL_NO_RSA + /* + * Don't check the public/private key, this is mostly for smart + * cards. + */ + if ((pkey->type == EVP_PKEY_RSA) && + (RSA_flags(pkey->pkey.rsa) & RSA_METHOD_FLAG_NO_CHECK)) ; + else +#endif + if (!X509_check_private_key(c->pkeys[i].x509, pkey)) { + X509_free(c->pkeys[i].x509); + c->pkeys[i].x509 = NULL; + return 0; + } + } + + if (c->pkeys[i].privatekey != NULL) + EVP_PKEY_free(c->pkeys[i].privatekey); + CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); + c->pkeys[i].privatekey = pkey; + c->key = &(c->pkeys[i]); + + c->valid = 0; + return (1); +} + +#ifndef OPENSSL_NO_RSA +# ifndef OPENSSL_NO_STDIO +int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + rsa = PEM_read_bio_RSAPrivateKey(in, NULL, + ssl->ctx->default_passwd_callback, + ssl-> + ctx->default_passwd_callback_userdata); + } else { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (rsa == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_FILE, j); + goto end; + } + ret = SSL_use_RSAPrivateKey(ssl, rsa); + RSA_free(rsa); + end: + if (in != NULL) + BIO_free(in); + return (ret); +} +# endif + +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, unsigned char *d, long len) +{ + int ret; + const unsigned char *p; + RSA *rsa; + + p = d; + if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { + SSLerr(SSL_F_SSL_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_use_RSAPrivateKey(ssl, rsa); + RSA_free(rsa); + return (ret); +} +#endif /* !OPENSSL_NO_RSA */ + +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) +{ + int ret; + + if (pkey == NULL) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ssl->cert)) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); + return (0); + } + ret = ssl_set_pkey(ssl->cert, pkey); + return (ret); +} + +#ifndef OPENSSL_NO_STDIO +int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + pkey = PEM_read_bio_PrivateKey(in, NULL, + ssl->ctx->default_passwd_callback, + ssl-> + ctx->default_passwd_callback_userdata); + } else if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + pkey = d2i_PrivateKey_bio(in, NULL); + } else { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (pkey == NULL) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_FILE, j); + goto end; + } + ret = SSL_use_PrivateKey(ssl, pkey); + EVP_PKEY_free(pkey); + end: + if (in != NULL) + BIO_free(in); + return (ret); +} +#endif + +int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const unsigned char *d, + long len) +{ + int ret; + const unsigned char *p; + EVP_PKEY *pkey; + + p = d; + if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { + SSLerr(SSL_F_SSL_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_use_PrivateKey(ssl, pkey); + EVP_PKEY_free(pkey); + return (ret); +} + +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) +{ + if (x == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ctx->cert)) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE, ERR_R_MALLOC_FAILURE); + return (0); + } + return (ssl_set_cert(ctx->cert, x)); +} + +static int ssl_set_cert(CERT *c, X509 *x) +{ + EVP_PKEY *pkey; + int i; + + pkey = X509_get_pubkey(x); + if (pkey == NULL) { + SSLerr(SSL_F_SSL_SET_CERT, SSL_R_X509_LIB); + return (0); + } + + i = ssl_cert_type(x, pkey); + if (i < 0) { + SSLerr(SSL_F_SSL_SET_CERT, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + EVP_PKEY_free(pkey); + return (0); + } + + if (c->pkeys[i].privatekey != NULL) { + /* + * The return code from EVP_PKEY_copy_parameters is deliberately + * ignored. Some EVP_PKEY types cannot do this. + */ + EVP_PKEY_copy_parameters(pkey, c->pkeys[i].privatekey); + ERR_clear_error(); + +#ifndef OPENSSL_NO_RSA + /* + * Don't check the public/private key, this is mostly for smart + * cards. + */ + if ((c->pkeys[i].privatekey->type == EVP_PKEY_RSA) && + (RSA_flags(c->pkeys[i].privatekey->pkey.rsa) & + RSA_METHOD_FLAG_NO_CHECK)) ; + else +#endif /* OPENSSL_NO_RSA */ + if (!X509_check_private_key(x, c->pkeys[i].privatekey)) { + /* + * don't fail for a cert/key mismatch, just free current private + * key (when switching to a different cert & key, first this + * function should be used, then ssl_set_pkey + */ + EVP_PKEY_free(c->pkeys[i].privatekey); + c->pkeys[i].privatekey = NULL; + /* clear error queue */ + ERR_clear_error(); + } + } + + EVP_PKEY_free(pkey); + + if (c->pkeys[i].x509 != NULL) + X509_free(c->pkeys[i].x509); + CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509); + c->pkeys[i].x509 = x; + c->key = &(c->pkeys[i]); + + c->valid = 0; + return (1); +} + +#ifndef OPENSSL_NO_STDIO +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) +{ + int j; + BIO *in; + int ret = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (x == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, j); + goto end; + } + + ret = SSL_CTX_use_certificate(ctx, x); + end: + if (x != NULL) + X509_free(x); + if (in != NULL) + BIO_free(in); + return (ret); +} +#endif + +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, int len, + const unsigned char *d) +{ + X509 *x; + int ret; + + x = d2i_X509(NULL, &d, (long)len); + if (x == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_CTX_use_certificate(ctx, x); + X509_free(x); + return (ret); +} + +#ifndef OPENSSL_NO_RSA +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) +{ + int ret; + EVP_PKEY *pkey; + + if (rsa == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ctx->cert)) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_MALLOC_FAILURE); + return (0); + } + if ((pkey = EVP_PKEY_new()) == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY, ERR_R_EVP_LIB); + return (0); + } + + RSA_up_ref(rsa); + if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) { + RSA_free(rsa); + return 0; + } + + ret = ssl_set_pkey(ctx->cert, pkey); + EVP_PKEY_free(pkey); + return (ret); +} + +# ifndef OPENSSL_NO_STDIO +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + rsa = PEM_read_bio_RSAPrivateKey(in, NULL, + ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (rsa == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_FILE, j); + goto end; + } + ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + RSA_free(rsa); + end: + if (in != NULL) + BIO_free(in); + return (ret); +} +# endif + +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const unsigned char *d, + long len) +{ + int ret; + const unsigned char *p; + RSA *rsa; + + p = d; + if ((rsa = d2i_RSAPrivateKey(NULL, &p, (long)len)) == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_RSAPRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + RSA_free(rsa); + return (ret); +} +#endif /* !OPENSSL_NO_RSA */ + +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) +{ + if (pkey == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_PASSED_NULL_PARAMETER); + return (0); + } + if (!ssl_cert_inst(&ctx->cert)) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY, ERR_R_MALLOC_FAILURE); + return (0); + } + return (ssl_set_pkey(ctx->cert, pkey)); +} + +#ifndef OPENSSL_NO_STDIO +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) +{ + int j, ret = 0; + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, ERR_R_SYS_LIB); + goto end; + } + if (type == SSL_FILETYPE_PEM) { + j = ERR_R_PEM_LIB; + pkey = PEM_read_bio_PrivateKey(in, NULL, + ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else if (type == SSL_FILETYPE_ASN1) { + j = ERR_R_ASN1_LIB; + pkey = d2i_PrivateKey_bio(in, NULL); + } else { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + if (pkey == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_FILE, j); + goto end; + } + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + end: + if (in != NULL) + BIO_free(in); + return (ret); +} +#endif + +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, + const unsigned char *d, long len) +{ + int ret; + const unsigned char *p; + EVP_PKEY *pkey; + + p = d; + if ((pkey = d2i_PrivateKey(type, NULL, &p, (long)len)) == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_PRIVATEKEY_ASN1, ERR_R_ASN1_LIB); + return (0); + } + + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + return (ret); +} + +#ifndef OPENSSL_NO_STDIO +/* + * Read a file that contains our certificate in "PEM" format, possibly + * followed by a sequence of CA certificates that should be sent to the peer + * in the Certificate message. + */ +int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, const char *file) +{ + BIO *in; + int ret = 0; + X509 *x = NULL; + + ERR_clear_error(); /* clear error stack for + * SSL_CTX_use_certificate() */ + + in = BIO_new(BIO_s_file_internal()); + if (in == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_SYS_LIB); + goto end; + } + + x = PEM_read_bio_X509_AUX(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + if (x == NULL) { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_CHAIN_FILE, ERR_R_PEM_LIB); + goto end; + } + + ret = SSL_CTX_use_certificate(ctx, x); + + if (ERR_peek_error() != 0) + ret = 0; /* Key/certificate mismatch doesn't imply + * ret==0 ... */ + if (ret) { + /* + * If we could set up our certificate, now proceed to the CA + * certificates. + */ + X509 *ca; + int r; + unsigned long err; + + if (ctx->extra_certs != NULL) { + sk_X509_pop_free(ctx->extra_certs, X509_free); + ctx->extra_certs = NULL; + } + + while ((ca = PEM_read_bio_X509(in, NULL, + ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata)) + != NULL) { + r = SSL_CTX_add_extra_chain_cert(ctx, ca); + if (!r) { + X509_free(ca); + ret = 0; + goto end; + } + /* + * Note that we must not free r if it was successfully added to + * the chain (while we must free the main certificate, since its + * reference count is increased by SSL_CTX_use_certificate). + */ + } + /* When the while loop ends, it's usually just EOF. */ + err = ERR_peek_last_error(); + if (ERR_GET_LIB(err) == ERR_LIB_PEM + && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) + ERR_clear_error(); + else + ret = 0; /* some real error */ + } + + end: + if (x != NULL) + X509_free(x); + if (in != NULL) + BIO_free(in); + return (ret); +} +#endif diff --git a/libs/openssl/ssl/ssl_sess.c b/libs/openssl/ssl/ssl_sess.c new file mode 100644 index 00000000..48fc4511 --- /dev/null +++ b/libs/openssl/ssl/ssl_sess.c @@ -0,0 +1,1302 @@ +/* ssl/ssl_sess.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include +#include +#ifndef OPENSSL_NO_ENGINE +# include +#endif +#include "ssl_locl.h" + +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s); +static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s); +static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck); + +SSL_SESSION *SSL_get_session(const SSL *ssl) +/* aka SSL_get0_session; gets 0 objects, just returns a copy of the pointer */ +{ + return (ssl->session); +} + +SSL_SESSION *SSL_get1_session(SSL *ssl) +/* variant of SSL_get_session: caller really gets something */ +{ + SSL_SESSION *sess; + /* + * Need to lock this all up rather than just use CRYPTO_add so that + * somebody doesn't free ssl->session between when we check it's non-null + * and when we up the reference count. + */ + CRYPTO_w_lock(CRYPTO_LOCK_SSL_SESSION); + sess = ssl->session; + if (sess) + sess->references++; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_SESSION); + return (sess); +} + +int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_new *new_func, + CRYPTO_EX_dup *dup_func, + CRYPTO_EX_free *free_func) +{ + return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_SSL_SESSION, argl, argp, + new_func, dup_func, free_func); +} + +int SSL_SESSION_set_ex_data(SSL_SESSION *s, int idx, void *arg) +{ + return (CRYPTO_set_ex_data(&s->ex_data, idx, arg)); +} + +void *SSL_SESSION_get_ex_data(const SSL_SESSION *s, int idx) +{ + return (CRYPTO_get_ex_data(&s->ex_data, idx)); +} + +SSL_SESSION *SSL_SESSION_new(void) +{ + SSL_SESSION *ss; + + ss = (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION)); + if (ss == NULL) { + SSLerr(SSL_F_SSL_SESSION_NEW, ERR_R_MALLOC_FAILURE); + return (0); + } + memset(ss, 0, sizeof(SSL_SESSION)); + + ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */ + ss->references = 1; + ss->timeout = 60 * 5 + 4; /* 5 minute timeout by default */ + ss->time = (unsigned long)time(NULL); + ss->prev = NULL; + ss->next = NULL; + ss->compress_meth = 0; +#ifndef OPENSSL_NO_TLSEXT + ss->tlsext_hostname = NULL; +# ifndef OPENSSL_NO_EC + ss->tlsext_ecpointformatlist_length = 0; + ss->tlsext_ecpointformatlist = NULL; + ss->tlsext_ellipticcurvelist_length = 0; + ss->tlsext_ellipticcurvelist = NULL; +# endif +#endif + CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); +#ifndef OPENSSL_NO_PSK + ss->psk_identity_hint = NULL; + ss->psk_identity = NULL; +#endif +#ifndef OPENSSL_NO_SRP + ss->srp_username = NULL; +#endif + return (ss); +} + +/* + * Create a new SSL_SESSION and duplicate the contents of |src| into it. If + * ticket == 0 then no ticket information is duplicated, otherwise it is. + */ +SSL_SESSION *ssl_session_dup(SSL_SESSION *src, int ticket) +{ + SSL_SESSION *dest; + + dest = OPENSSL_malloc(sizeof(*src)); + if (dest == NULL) { + goto err; + } + memcpy(dest, src, sizeof(*dest)); + + /* + * Set the various pointers to NULL so that we can call SSL_SESSION_free in + * the case of an error whilst halfway through constructing dest + */ +#ifndef OPENSSL_NO_PSK + dest->psk_identity_hint = NULL; + dest->psk_identity = NULL; +#endif + dest->ciphers = NULL; +#ifndef OPENSSL_NO_TLSEXT + dest->tlsext_hostname = NULL; +# ifndef OPENSSL_NO_EC + dest->tlsext_ecpointformatlist = NULL; + dest->tlsext_ellipticcurvelist = NULL; +# endif + dest->tlsext_tick = NULL; +#endif +#ifndef OPENSSL_NO_SRP + dest->srp_username = NULL; +#endif + memset(&dest->ex_data, 0, sizeof(dest->ex_data)); + + /* We deliberately don't copy the prev and next pointers */ + dest->prev = NULL; + dest->next = NULL; + + dest->references = 1; + + if (src->sess_cert != NULL) + CRYPTO_add(&src->sess_cert->references, 1, CRYPTO_LOCK_SSL_SESS_CERT); + + if (src->peer != NULL) + CRYPTO_add(&src->peer->references, 1, CRYPTO_LOCK_X509); + +#ifndef OPENSSL_NO_PSK + if (src->psk_identity_hint) { + dest->psk_identity_hint = BUF_strdup(src->psk_identity_hint); + if (dest->psk_identity_hint == NULL) { + goto err; + } + } + if (src->psk_identity) { + dest->psk_identity = BUF_strdup(src->psk_identity); + if (dest->psk_identity == NULL) { + goto err; + } + } +#endif + + if(src->ciphers != NULL) { + dest->ciphers = sk_SSL_CIPHER_dup(src->ciphers); + if (dest->ciphers == NULL) + goto err; + } + + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, + &dest->ex_data, &src->ex_data)) { + goto err; + } + +#ifndef OPENSSL_NO_TLSEXT + if (src->tlsext_hostname) { + dest->tlsext_hostname = BUF_strdup(src->tlsext_hostname); + if (dest->tlsext_hostname == NULL) { + goto err; + } + } +# ifndef OPENSSL_NO_EC + if (src->tlsext_ecpointformatlist) { + dest->tlsext_ecpointformatlist = + BUF_memdup(src->tlsext_ecpointformatlist, + src->tlsext_ecpointformatlist_length); + if (dest->tlsext_ecpointformatlist == NULL) + goto err; + } + if (src->tlsext_ellipticcurvelist) { + dest->tlsext_ellipticcurvelist = + BUF_memdup(src->tlsext_ellipticcurvelist, + src->tlsext_ellipticcurvelist_length); + if (dest->tlsext_ellipticcurvelist == NULL) + goto err; + } +# endif + + if (ticket != 0) { + dest->tlsext_tick = BUF_memdup(src->tlsext_tick, src->tlsext_ticklen); + if(dest->tlsext_tick == NULL) + goto err; + } else { + dest->tlsext_tick_lifetime_hint = 0; + dest->tlsext_ticklen = 0; + } +#endif + +#ifndef OPENSSL_NO_SRP + if (src->srp_username) { + dest->srp_username = BUF_strdup(src->srp_username); + if (dest->srp_username == NULL) { + goto err; + } + } +#endif + + return dest; +err: + SSLerr(SSL_F_SSL_SESSION_DUP, ERR_R_MALLOC_FAILURE); + SSL_SESSION_free(dest); + return NULL; +} + +const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, + unsigned int *len) +{ + if (len) + *len = s->session_id_length; + return s->session_id; +} + +unsigned int SSL_SESSION_get_compress_id(const SSL_SESSION *s) +{ + return s->compress_meth; +} + +/* + * Even with SSLv2, we have 16 bytes (128 bits) of session ID space. + * SSLv3/TLSv1 has 32 bytes (256 bits). As such, filling the ID with random + * gunk repeatedly until we have no conflict is going to complete in one + * iteration pretty much "most" of the time (btw: understatement). So, if it + * takes us 10 iterations and we still can't avoid a conflict - well that's a + * reasonable point to call it quits. Either the RAND code is broken or + * someone is trying to open roughly very close to 2^128 (or 2^256) SSL + * sessions to our server. How you might store that many sessions is perhaps + * a more interesting question ... + */ + +#define MAX_SESS_ID_ATTEMPTS 10 +static int def_generate_session_id(const SSL *ssl, unsigned char *id, + unsigned int *id_len) +{ + unsigned int retry = 0; + do + if (RAND_pseudo_bytes(id, *id_len) <= 0) + return 0; + while (SSL_has_matching_session_id(ssl, id, *id_len) && + (++retry < MAX_SESS_ID_ATTEMPTS)) ; + if (retry < MAX_SESS_ID_ATTEMPTS) + return 1; + /* else - woops a session_id match */ + /* + * XXX We should also check the external cache -- but the probability of + * a collision is negligible, and we could not prevent the concurrent + * creation of sessions with identical IDs since we currently don't have + * means to atomically check whether a session ID already exists and make + * a reservation for it if it does not (this problem applies to the + * internal cache as well). + */ + return 0; +} + +int ssl_get_new_session(SSL *s, int session) +{ + /* This gets used by clients and servers. */ + + unsigned int tmp; + SSL_SESSION *ss = NULL; + GEN_SESSION_CB cb = def_generate_session_id; + + if ((ss = SSL_SESSION_new()) == NULL) + return (0); + + /* If the context has a default timeout, use it */ + if (s->session_ctx->session_timeout == 0) + ss->timeout = SSL_get_default_timeout(s); + else + ss->timeout = s->session_ctx->session_timeout; + + if (s->session != NULL) { + SSL_SESSION_free(s->session); + s->session = NULL; + } + + if (session) { + if (s->version == SSL2_VERSION) { + ss->ssl_version = SSL2_VERSION; + ss->session_id_length = SSL2_SSL_SESSION_ID_LENGTH; + } else if (s->version == SSL3_VERSION) { + ss->ssl_version = SSL3_VERSION; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + } else if (s->version == TLS1_VERSION) { + ss->ssl_version = TLS1_VERSION; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + } else if (s->version == TLS1_1_VERSION) { + ss->ssl_version = TLS1_1_VERSION; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + } else if (s->version == TLS1_2_VERSION) { + ss->ssl_version = TLS1_2_VERSION; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + } else if (s->version == DTLS1_BAD_VER) { + ss->ssl_version = DTLS1_BAD_VER; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + } else if (s->version == DTLS1_VERSION) { + ss->ssl_version = DTLS1_VERSION; + ss->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + } else { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_UNSUPPORTED_SSL_VERSION); + SSL_SESSION_free(ss); + return (0); + } +#ifndef OPENSSL_NO_TLSEXT + /*- + * If RFC5077 ticket, use empty session ID (as server). + * Note that: + * (a) ssl_get_prev_session() does lookahead into the + * ClientHello extensions to find the session ticket. + * When ssl_get_prev_session() fails, s3_srvr.c calls + * ssl_get_new_session() in ssl3_get_client_hello(). + * At that point, it has not yet parsed the extensions, + * however, because of the lookahead, it already knows + * whether a ticket is expected or not. + * + * (b) s3_clnt.c calls ssl_get_new_session() before parsing + * ServerHello extensions, and before recording the session + * ID received from the server, so this block is a noop. + */ + if (s->tlsext_ticket_expected) { + ss->session_id_length = 0; + goto sess_id_done; + } +#endif + /* Choose which callback will set the session ID */ + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + if (s->generate_session_id) + cb = s->generate_session_id; + else if (s->session_ctx->generate_session_id) + cb = s->session_ctx->generate_session_id; + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + /* Choose a session ID */ + tmp = ss->session_id_length; + if (!cb(s, ss->session_id, &tmp)) { + /* The callback failed */ + SSLerr(SSL_F_SSL_GET_NEW_SESSION, + SSL_R_SSL_SESSION_ID_CALLBACK_FAILED); + SSL_SESSION_free(ss); + return (0); + } + /* + * Don't allow the callback to set the session length to zero. nor + * set it higher than it was. + */ + if (!tmp || (tmp > ss->session_id_length)) { + /* The callback set an illegal length */ + SSLerr(SSL_F_SSL_GET_NEW_SESSION, + SSL_R_SSL_SESSION_ID_HAS_BAD_LENGTH); + SSL_SESSION_free(ss); + return (0); + } + /* If the session length was shrunk and we're SSLv2, pad it */ + if ((tmp < ss->session_id_length) && (s->version == SSL2_VERSION)) + memset(ss->session_id + tmp, 0, ss->session_id_length - tmp); + else + ss->session_id_length = tmp; + /* Finally, check for a conflict */ + if (SSL_has_matching_session_id(s, ss->session_id, + ss->session_id_length)) { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, SSL_R_SSL_SESSION_ID_CONFLICT); + SSL_SESSION_free(ss); + return (0); + } +#ifndef OPENSSL_NO_TLSEXT + sess_id_done: + if (s->tlsext_hostname) { + ss->tlsext_hostname = BUF_strdup(s->tlsext_hostname); + if (ss->tlsext_hostname == NULL) { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); + SSL_SESSION_free(ss); + return 0; + } + } +# ifndef OPENSSL_NO_EC + if (s->tlsext_ecpointformatlist) { + if (ss->tlsext_ecpointformatlist != NULL) + OPENSSL_free(ss->tlsext_ecpointformatlist); + if ((ss->tlsext_ecpointformatlist = + OPENSSL_malloc(s->tlsext_ecpointformatlist_length)) == + NULL) { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE); + SSL_SESSION_free(ss); + return 0; + } + ss->tlsext_ecpointformatlist_length = + s->tlsext_ecpointformatlist_length; + memcpy(ss->tlsext_ecpointformatlist, s->tlsext_ecpointformatlist, + s->tlsext_ecpointformatlist_length); + } + if (s->tlsext_ellipticcurvelist) { + if (ss->tlsext_ellipticcurvelist != NULL) + OPENSSL_free(ss->tlsext_ellipticcurvelist); + if ((ss->tlsext_ellipticcurvelist = + OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == + NULL) { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_MALLOC_FAILURE); + SSL_SESSION_free(ss); + return 0; + } + ss->tlsext_ellipticcurvelist_length = + s->tlsext_ellipticcurvelist_length; + memcpy(ss->tlsext_ellipticcurvelist, s->tlsext_ellipticcurvelist, + s->tlsext_ellipticcurvelist_length); + } +# endif +#endif + } else { + ss->session_id_length = 0; + } + + if (s->sid_ctx_length > sizeof ss->sid_ctx) { + SSLerr(SSL_F_SSL_GET_NEW_SESSION, ERR_R_INTERNAL_ERROR); + SSL_SESSION_free(ss); + return 0; + } + memcpy(ss->sid_ctx, s->sid_ctx, s->sid_ctx_length); + ss->sid_ctx_length = s->sid_ctx_length; + s->session = ss; + ss->ssl_version = s->version; + ss->verify_result = X509_V_OK; + + return (1); +} + +/*- + * ssl_get_prev attempts to find an SSL_SESSION to be used to resume this + * connection. It is only called by servers. + * + * session_id: points at the session ID in the ClientHello. This code will + * read past the end of this in order to parse out the session ticket + * extension, if any. + * len: the length of the session ID. + * limit: a pointer to the first byte after the ClientHello. + * + * Returns: + * -1: error + * 0: a session may have been found. + * + * Side effects: + * - If a session is found then s->session is pointed at it (after freeing an + * existing session if need be) and s->verify_result is set from the session. + * - Both for new and resumed sessions, s->tlsext_ticket_expected is set to 1 + * if the server should issue a new session ticket (to 0 otherwise). + */ +int ssl_get_prev_session(SSL *s, unsigned char *session_id, int len, + const unsigned char *limit) +{ + /* This is used only by servers. */ + + SSL_SESSION *ret = NULL; + int fatal = 0; + int try_session_cache = 1; +#ifndef OPENSSL_NO_TLSEXT + int r; +#endif + + if (session_id + len > limit) { + fatal = 1; + goto err; + } + + if (len == 0) + try_session_cache = 0; + +#ifndef OPENSSL_NO_TLSEXT + /* sets s->tlsext_ticket_expected */ + r = tls1_process_ticket(s, session_id, len, limit, &ret); + switch (r) { + case -1: /* Error during processing */ + fatal = 1; + goto err; + case 0: /* No ticket found */ + case 1: /* Zero length ticket found */ + break; /* Ok to carry on processing session id. */ + case 2: /* Ticket found but not decrypted. */ + case 3: /* Ticket decrypted, *ret has been set. */ + try_session_cache = 0; + break; + default: + abort(); + } +#endif + + if (try_session_cache && + ret == NULL && + !(s->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) { + SSL_SESSION data; + data.ssl_version = s->version; + data.session_id_length = len; + if (len == 0) + return 0; + memcpy(data.session_id, session_id, len); + CRYPTO_r_lock(CRYPTO_LOCK_SSL_CTX); + ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data); + if (ret != NULL) { + /* don't allow other threads to steal it: */ + CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION); + } + CRYPTO_r_unlock(CRYPTO_LOCK_SSL_CTX); + if (ret == NULL) + s->session_ctx->stats.sess_miss++; + } + + if (try_session_cache && + ret == NULL && s->session_ctx->get_session_cb != NULL) { + int copy = 1; + + if ((ret = s->session_ctx->get_session_cb(s, session_id, len, ©))) { + s->session_ctx->stats.sess_cb_hit++; + + /* + * Increment reference count now if the session callback asks us + * to do so (note that if the session structures returned by the + * callback are shared between threads, it must handle the + * reference count itself [i.e. copy == 0], or things won't be + * thread-safe). + */ + if (copy) + CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_SSL_SESSION); + + /* + * Add the externally cached session to the internal cache as + * well if and only if we are supposed to. + */ + if (! + (s->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_STORE)) + /* + * The following should not return 1, otherwise, things are + * very strange + */ + SSL_CTX_add_session(s->session_ctx, ret); + } + } + + if (ret == NULL) + goto err; + + /* Now ret is non-NULL and we own one of its reference counts. */ + + if (ret->sid_ctx_length != s->sid_ctx_length + || memcmp(ret->sid_ctx, s->sid_ctx, ret->sid_ctx_length)) { + /* + * We have the session requested by the client, but we don't want to + * use it in this context. + */ + goto err; /* treat like cache miss */ + } + + if ((s->verify_mode & SSL_VERIFY_PEER) && s->sid_ctx_length == 0) { + /* + * We can't be sure if this session is being used out of context, + * which is especially important for SSL_VERIFY_PEER. The application + * should have used SSL[_CTX]_set_session_id_context. For this error + * case, we generate an error instead of treating the event like a + * cache miss (otherwise it would be easy for applications to + * effectively disable the session cache by accident without anyone + * noticing). + */ + + SSLerr(SSL_F_SSL_GET_PREV_SESSION, + SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED); + fatal = 1; + goto err; + } + + if (ret->cipher == NULL) { + unsigned char buf[5], *p; + unsigned long l; + + p = buf; + l = ret->cipher_id; + l2n(l, p); + if ((ret->ssl_version >> 8) >= SSL3_VERSION_MAJOR) + ret->cipher = ssl_get_cipher_by_char(s, &(buf[2])); + else + ret->cipher = ssl_get_cipher_by_char(s, &(buf[1])); + if (ret->cipher == NULL) + goto err; + } + + if (ret->timeout < (long)(time(NULL) - ret->time)) { /* timeout */ + s->session_ctx->stats.sess_timeout++; + if (try_session_cache) { + /* session was from the cache, so remove it */ + SSL_CTX_remove_session(s->session_ctx, ret); + } + goto err; + } + + s->session_ctx->stats.sess_hit++; + + if (s->session != NULL) + SSL_SESSION_free(s->session); + s->session = ret; + s->verify_result = s->session->verify_result; + return 1; + + err: + if (ret != NULL) { + SSL_SESSION_free(ret); +#ifndef OPENSSL_NO_TLSEXT + if (!try_session_cache) { + /* + * The session was from a ticket, so we should issue a ticket for + * the new session + */ + s->tlsext_ticket_expected = 1; + } +#endif + } + if (fatal) + return -1; + else + return 0; +} + +int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c) +{ + int ret = 0; + SSL_SESSION *s; + + /* + * add just 1 reference count for the SSL_CTX's session cache even though + * it has two ways of access: each session is in a doubly linked list and + * an lhash + */ + CRYPTO_add(&c->references, 1, CRYPTO_LOCK_SSL_SESSION); + /* + * if session c is in already in cache, we take back the increment later + */ + + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + s = lh_SSL_SESSION_insert(ctx->sessions, c); + + /* + * s != NULL iff we already had a session with the given PID. In this + * case, s == c should hold (then we did not really modify + * ctx->sessions), or we're in trouble. + */ + if (s != NULL && s != c) { + /* We *are* in trouble ... */ + SSL_SESSION_list_remove(ctx, s); + SSL_SESSION_free(s); + /* + * ... so pretend the other session did not exist in cache (we cannot + * handle two SSL_SESSION structures with identical session ID in the + * same cache, which could happen e.g. when two threads concurrently + * obtain the same session from an external cache) + */ + s = NULL; + } + + /* Put at the head of the queue unless it is already in the cache */ + if (s == NULL) + SSL_SESSION_list_add(ctx, c); + + if (s != NULL) { + /* + * existing cache entry -- decrement previously incremented reference + * count because it already takes into account the cache + */ + + SSL_SESSION_free(s); /* s == c */ + ret = 0; + } else { + /* + * new cache entry -- remove old ones if cache has become too large + */ + + ret = 1; + + if (SSL_CTX_sess_get_cache_size(ctx) > 0) { + while (SSL_CTX_sess_number(ctx) > + SSL_CTX_sess_get_cache_size(ctx)) { + if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) + break; + else + ctx->stats.sess_cache_full++; + } + } + } + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + return (ret); +} + +int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *c) +{ + return remove_session_lock(ctx, c, 1); +} + +static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *c, int lck) +{ + SSL_SESSION *r; + int ret = 0; + + if ((c != NULL) && (c->session_id_length != 0)) { + if (lck) + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + if ((r = lh_SSL_SESSION_retrieve(ctx->sessions, c)) == c) { + ret = 1; + r = lh_SSL_SESSION_delete(ctx->sessions, c); + SSL_SESSION_list_remove(ctx, c); + } + + if (lck) + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); + + if (ret) { + r->not_resumable = 1; + if (ctx->remove_session_cb != NULL) + ctx->remove_session_cb(ctx, r); + SSL_SESSION_free(r); + } + } else + ret = 0; + return (ret); +} + +void SSL_SESSION_free(SSL_SESSION *ss) +{ + int i; + + if (ss == NULL) + return; + + i = CRYPTO_add(&ss->references, -1, CRYPTO_LOCK_SSL_SESSION); +#ifdef REF_PRINT + REF_PRINT("SSL_SESSION", ss); +#endif + if (i > 0) + return; +#ifdef REF_CHECK + if (i < 0) { + fprintf(stderr, "SSL_SESSION_free, bad reference count\n"); + abort(); /* ok */ + } +#endif + + CRYPTO_free_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data); + + OPENSSL_cleanse(ss->key_arg, sizeof ss->key_arg); + OPENSSL_cleanse(ss->master_key, sizeof ss->master_key); + OPENSSL_cleanse(ss->session_id, sizeof ss->session_id); + if (ss->sess_cert != NULL) + ssl_sess_cert_free(ss->sess_cert); + if (ss->peer != NULL) + X509_free(ss->peer); + if (ss->ciphers != NULL) + sk_SSL_CIPHER_free(ss->ciphers); +#ifndef OPENSSL_NO_TLSEXT + if (ss->tlsext_hostname != NULL) + OPENSSL_free(ss->tlsext_hostname); + if (ss->tlsext_tick != NULL) + OPENSSL_free(ss->tlsext_tick); +# ifndef OPENSSL_NO_EC + ss->tlsext_ecpointformatlist_length = 0; + if (ss->tlsext_ecpointformatlist != NULL) + OPENSSL_free(ss->tlsext_ecpointformatlist); + ss->tlsext_ellipticcurvelist_length = 0; + if (ss->tlsext_ellipticcurvelist != NULL) + OPENSSL_free(ss->tlsext_ellipticcurvelist); +# endif /* OPENSSL_NO_EC */ +#endif +#ifndef OPENSSL_NO_PSK + if (ss->psk_identity_hint != NULL) + OPENSSL_free(ss->psk_identity_hint); + if (ss->psk_identity != NULL) + OPENSSL_free(ss->psk_identity); +#endif +#ifndef OPENSSL_NO_SRP + if (ss->srp_username != NULL) + OPENSSL_free(ss->srp_username); +#endif + OPENSSL_cleanse(ss, sizeof(*ss)); + OPENSSL_free(ss); +} + +int SSL_set_session(SSL *s, SSL_SESSION *session) +{ + int ret = 0; + const SSL_METHOD *meth; + + if (session != NULL) { + meth = s->ctx->method->get_ssl_method(session->ssl_version); + if (meth == NULL) + meth = s->method->get_ssl_method(session->ssl_version); + if (meth == NULL) { + SSLerr(SSL_F_SSL_SET_SESSION, SSL_R_UNABLE_TO_FIND_SSL_METHOD); + return (0); + } + + if (meth != s->method) { + if (!SSL_set_ssl_method(s, meth)) + return (0); + } +#ifndef OPENSSL_NO_KRB5 + if (s->kssl_ctx && !s->kssl_ctx->client_princ && + session->krb5_client_princ_len > 0) { + s->kssl_ctx->client_princ = + (char *)OPENSSL_malloc(session->krb5_client_princ_len + 1); + memcpy(s->kssl_ctx->client_princ, session->krb5_client_princ, + session->krb5_client_princ_len); + s->kssl_ctx->client_princ[session->krb5_client_princ_len] = '\0'; + } +#endif /* OPENSSL_NO_KRB5 */ + + /* CRYPTO_w_lock(CRYPTO_LOCK_SSL); */ + CRYPTO_add(&session->references, 1, CRYPTO_LOCK_SSL_SESSION); + if (s->session != NULL) + SSL_SESSION_free(s->session); + s->session = session; + s->verify_result = s->session->verify_result; + /* CRYPTO_w_unlock(CRYPTO_LOCK_SSL); */ + ret = 1; + } else { + if (s->session != NULL) { + SSL_SESSION_free(s->session); + s->session = NULL; + } + + meth = s->ctx->method; + if (meth != s->method) { + if (!SSL_set_ssl_method(s, meth)) + return (0); + } + ret = 1; + } + return (ret); +} + +long SSL_SESSION_set_timeout(SSL_SESSION *s, long t) +{ + if (s == NULL) + return (0); + s->timeout = t; + return (1); +} + +long SSL_SESSION_get_timeout(const SSL_SESSION *s) +{ + if (s == NULL) + return (0); + return (s->timeout); +} + +long SSL_SESSION_get_time(const SSL_SESSION *s) +{ + if (s == NULL) + return (0); + return (s->time); +} + +long SSL_SESSION_set_time(SSL_SESSION *s, long t) +{ + if (s == NULL) + return (0); + s->time = t; + return (t); +} + +X509 *SSL_SESSION_get0_peer(SSL_SESSION *s) +{ + return s->peer; +} + +int SSL_SESSION_set1_id_context(SSL_SESSION *s, const unsigned char *sid_ctx, + unsigned int sid_ctx_len) +{ + if (sid_ctx_len > SSL_MAX_SID_CTX_LENGTH) { + SSLerr(SSL_F_SSL_SESSION_SET1_ID_CONTEXT, + SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + s->sid_ctx_length = sid_ctx_len; + memcpy(s->sid_ctx, sid_ctx, sid_ctx_len); + + return 1; +} + +long SSL_CTX_set_timeout(SSL_CTX *s, long t) +{ + long l; + if (s == NULL) + return (0); + l = s->session_timeout; + s->session_timeout = t; + return (l); +} + +long SSL_CTX_get_timeout(const SSL_CTX *s) +{ + if (s == NULL) + return (0); + return (s->session_timeout); +} + +#ifndef OPENSSL_NO_TLSEXT +int SSL_set_session_secret_cb(SSL *s, + int (*tls_session_secret_cb) (SSL *s, + void *secret, + int *secret_len, + STACK_OF(SSL_CIPHER) + *peer_ciphers, + SSL_CIPHER + **cipher, + void *arg), + void *arg) +{ + if (s == NULL) + return (0); + s->tls_session_secret_cb = tls_session_secret_cb; + s->tls_session_secret_cb_arg = arg; + return (1); +} + +int SSL_set_session_ticket_ext_cb(SSL *s, tls_session_ticket_ext_cb_fn cb, + void *arg) +{ + if (s == NULL) + return (0); + s->tls_session_ticket_ext_cb = cb; + s->tls_session_ticket_ext_cb_arg = arg; + return (1); +} + +int SSL_set_session_ticket_ext(SSL *s, void *ext_data, int ext_len) +{ + if (s->version >= TLS1_VERSION) { + if (s->tlsext_session_ticket) { + OPENSSL_free(s->tlsext_session_ticket); + s->tlsext_session_ticket = NULL; + } + + s->tlsext_session_ticket = + OPENSSL_malloc(sizeof(TLS_SESSION_TICKET_EXT) + ext_len); + if (!s->tlsext_session_ticket) { + SSLerr(SSL_F_SSL_SET_SESSION_TICKET_EXT, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (ext_data) { + s->tlsext_session_ticket->length = ext_len; + s->tlsext_session_ticket->data = s->tlsext_session_ticket + 1; + memcpy(s->tlsext_session_ticket->data, ext_data, ext_len); + } else { + s->tlsext_session_ticket->length = 0; + s->tlsext_session_ticket->data = NULL; + } + + return 1; + } + + return 0; +} +#endif /* OPENSSL_NO_TLSEXT */ + +typedef struct timeout_param_st { + SSL_CTX *ctx; + long time; + LHASH_OF(SSL_SESSION) *cache; +} TIMEOUT_PARAM; + +static void timeout_doall_arg(SSL_SESSION *s, TIMEOUT_PARAM *p) +{ + if ((p->time == 0) || (p->time > (s->time + s->timeout))) { /* timeout */ + /* + * The reason we don't call SSL_CTX_remove_session() is to save on + * locking overhead + */ + (void)lh_SSL_SESSION_delete(p->cache, s); + SSL_SESSION_list_remove(p->ctx, s); + s->not_resumable = 1; + if (p->ctx->remove_session_cb != NULL) + p->ctx->remove_session_cb(p->ctx, s); + SSL_SESSION_free(s); + } +} + +static IMPLEMENT_LHASH_DOALL_ARG_FN(timeout, SSL_SESSION, TIMEOUT_PARAM) + +void SSL_CTX_flush_sessions(SSL_CTX *s, long t) +{ + unsigned long i; + TIMEOUT_PARAM tp; + + tp.ctx = s; + tp.cache = s->sessions; + if (tp.cache == NULL) + return; + tp.time = t; + CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); + i = CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load; + CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = 0; + lh_SSL_SESSION_doall_arg(tp.cache, LHASH_DOALL_ARG_FN(timeout), + TIMEOUT_PARAM, &tp); + CHECKED_LHASH_OF(SSL_SESSION, tp.cache)->down_load = i; + CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); +} + +int ssl_clear_bad_session(SSL *s) +{ + if ((s->session != NULL) && + !(s->shutdown & SSL_SENT_SHUTDOWN) && + !(SSL_in_init(s) || SSL_in_before(s))) { + SSL_CTX_remove_session(s->ctx, s->session); + return (1); + } else + return (0); +} + +/* locked by SSL_CTX in the calling function */ +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *s) +{ + if ((s->next == NULL) || (s->prev == NULL)) + return; + + if (s->next == (SSL_SESSION *)&(ctx->session_cache_tail)) { + /* last element in list */ + if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { + /* only one element in list */ + ctx->session_cache_head = NULL; + ctx->session_cache_tail = NULL; + } else { + ctx->session_cache_tail = s->prev; + s->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail); + } + } else { + if (s->prev == (SSL_SESSION *)&(ctx->session_cache_head)) { + /* first element in list */ + ctx->session_cache_head = s->next; + s->next->prev = (SSL_SESSION *)&(ctx->session_cache_head); + } else { + /* middle of list */ + s->next->prev = s->prev; + s->prev->next = s->next; + } + } + s->prev = s->next = NULL; +} + +static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *s) +{ + if ((s->next != NULL) && (s->prev != NULL)) + SSL_SESSION_list_remove(ctx, s); + + if (ctx->session_cache_head == NULL) { + ctx->session_cache_head = s; + ctx->session_cache_tail = s; + s->prev = (SSL_SESSION *)&(ctx->session_cache_head); + s->next = (SSL_SESSION *)&(ctx->session_cache_tail); + } else { + s->next = ctx->session_cache_head; + s->next->prev = s; + s->prev = (SSL_SESSION *)&(ctx->session_cache_head); + ctx->session_cache_head = s; + } +} + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*cb) (struct ssl_st *ssl, + SSL_SESSION *sess)) +{ + ctx->new_session_cb = cb; +} + +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx)) (SSL *ssl, SSL_SESSION *sess) { + return ctx->new_session_cb; +} + +void SSL_CTX_sess_set_remove_cb(SSL_CTX *ctx, + void (*cb) (SSL_CTX *ctx, SSL_SESSION *sess)) +{ + ctx->remove_session_cb = cb; +} + +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx)) (SSL_CTX *ctx, + SSL_SESSION *sess) { + return ctx->remove_session_cb; +} + +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*cb) (struct ssl_st *ssl, + unsigned char *data, int len, + int *copy)) +{ + ctx->get_session_cb = cb; +} + +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx)) (SSL *ssl, + unsigned char *data, + int len, int *copy) { + return ctx->get_session_cb; +} + +void SSL_CTX_set_info_callback(SSL_CTX *ctx, + void (*cb) (const SSL *ssl, int type, int val)) +{ + ctx->info_callback = cb; +} + +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx)) (const SSL *ssl, int type, + int val) { + return ctx->info_callback; +} + +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey)) +{ + ctx->client_cert_cb = cb; +} + +int (*SSL_CTX_get_client_cert_cb(SSL_CTX *ctx)) (SSL *ssl, X509 **x509, + EVP_PKEY **pkey) { + return ctx->client_cert_cb; +} + +#ifndef OPENSSL_NO_ENGINE +int SSL_CTX_set_client_cert_engine(SSL_CTX *ctx, ENGINE *e) +{ + if (!ENGINE_init(e)) { + SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, ERR_R_ENGINE_LIB); + return 0; + } + if (!ENGINE_get_ssl_client_cert_function(e)) { + SSLerr(SSL_F_SSL_CTX_SET_CLIENT_CERT_ENGINE, + SSL_R_NO_CLIENT_CERT_METHOD); + ENGINE_finish(e); + return 0; + } + ctx->client_cert_engine = e; + return 1; +} +#endif + +void SSL_CTX_set_cookie_generate_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, + unsigned char *cookie, + unsigned int *cookie_len)) +{ + ctx->app_gen_cookie_cb = cb; +} + +void SSL_CTX_set_cookie_verify_cb(SSL_CTX *ctx, + int (*cb) (SSL *ssl, unsigned char *cookie, + unsigned int cookie_len)) +{ + ctx->app_verify_cookie_cb = cb; +} + +IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, + SSL_SESSION) diff --git a/libs/openssl/ssl/ssl_stat.c b/libs/openssl/ssl/ssl_stat.c new file mode 100644 index 00000000..1b9069f9 --- /dev/null +++ b/libs/openssl/ssl/ssl_stat.c @@ -0,0 +1,1078 @@ +/* ssl/ssl_stat.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include "ssl_locl.h" + +const char *SSL_state_string_long(const SSL *s) +{ + const char *str; + + switch (s->state) { + case SSL_ST_BEFORE: + str = "before SSL initialization"; + break; + case SSL_ST_ACCEPT: + str = "before accept initialization"; + break; + case SSL_ST_CONNECT: + str = "before connect initialization"; + break; + case SSL_ST_OK: + str = "SSL negotiation finished successfully"; + break; + case SSL_ST_RENEGOTIATE: + str = "SSL renegotiate ciphers"; + break; + case SSL_ST_BEFORE | SSL_ST_CONNECT: + str = "before/connect initialization"; + break; + case SSL_ST_OK | SSL_ST_CONNECT: + str = "ok/connect SSL initialization"; + break; + case SSL_ST_BEFORE | SSL_ST_ACCEPT: + str = "before/accept initialization"; + break; + case SSL_ST_OK | SSL_ST_ACCEPT: + str = "ok/accept SSL initialization"; + break; + case SSL_ST_ERR: + str = "error"; + break; +#ifndef OPENSSL_NO_SSL2 + case SSL2_ST_CLIENT_START_ENCRYPTION: + str = "SSLv2 client start encryption"; + break; + case SSL2_ST_SERVER_START_ENCRYPTION: + str = "SSLv2 server start encryption"; + break; + case SSL2_ST_SEND_CLIENT_HELLO_A: + str = "SSLv2 write client hello A"; + break; + case SSL2_ST_SEND_CLIENT_HELLO_B: + str = "SSLv2 write client hello B"; + break; + case SSL2_ST_GET_SERVER_HELLO_A: + str = "SSLv2 read server hello A"; + break; + case SSL2_ST_GET_SERVER_HELLO_B: + str = "SSLv2 read server hello B"; + break; + case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: + str = "SSLv2 write client master key A"; + break; + case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: + str = "SSLv2 write client master key B"; + break; + case SSL2_ST_SEND_CLIENT_FINISHED_A: + str = "SSLv2 write client finished A"; + break; + case SSL2_ST_SEND_CLIENT_FINISHED_B: + str = "SSLv2 write client finished B"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: + str = "SSLv2 write client certificate A"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: + str = "SSLv2 write client certificate B"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: + str = "SSLv2 write client certificate C"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: + str = "SSLv2 write client certificate D"; + break; + case SSL2_ST_GET_SERVER_VERIFY_A: + str = "SSLv2 read server verify A"; + break; + case SSL2_ST_GET_SERVER_VERIFY_B: + str = "SSLv2 read server verify B"; + break; + case SSL2_ST_GET_SERVER_FINISHED_A: + str = "SSLv2 read server finished A"; + break; + case SSL2_ST_GET_SERVER_FINISHED_B: + str = "SSLv2 read server finished B"; + break; + case SSL2_ST_GET_CLIENT_HELLO_A: + str = "SSLv2 read client hello A"; + break; + case SSL2_ST_GET_CLIENT_HELLO_B: + str = "SSLv2 read client hello B"; + break; + case SSL2_ST_GET_CLIENT_HELLO_C: + str = "SSLv2 read client hello C"; + break; + case SSL2_ST_SEND_SERVER_HELLO_A: + str = "SSLv2 write server hello A"; + break; + case SSL2_ST_SEND_SERVER_HELLO_B: + str = "SSLv2 write server hello B"; + break; + case SSL2_ST_GET_CLIENT_MASTER_KEY_A: + str = "SSLv2 read client master key A"; + break; + case SSL2_ST_GET_CLIENT_MASTER_KEY_B: + str = "SSLv2 read client master key B"; + break; + case SSL2_ST_SEND_SERVER_VERIFY_A: + str = "SSLv2 write server verify A"; + break; + case SSL2_ST_SEND_SERVER_VERIFY_B: + str = "SSLv2 write server verify B"; + break; + case SSL2_ST_SEND_SERVER_VERIFY_C: + str = "SSLv2 write server verify C"; + break; + case SSL2_ST_GET_CLIENT_FINISHED_A: + str = "SSLv2 read client finished A"; + break; + case SSL2_ST_GET_CLIENT_FINISHED_B: + str = "SSLv2 read client finished B"; + break; + case SSL2_ST_SEND_SERVER_FINISHED_A: + str = "SSLv2 write server finished A"; + break; + case SSL2_ST_SEND_SERVER_FINISHED_B: + str = "SSLv2 write server finished B"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: + str = "SSLv2 write request certificate A"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: + str = "SSLv2 write request certificate B"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: + str = "SSLv2 write request certificate C"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: + str = "SSLv2 write request certificate D"; + break; + case SSL2_ST_X509_GET_SERVER_CERTIFICATE: + str = "SSLv2 X509 read server certificate"; + break; + case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: + str = "SSLv2 X509 read client certificate"; + break; +#endif + +#ifndef OPENSSL_NO_SSL3 +/* SSLv3 additions */ + case SSL3_ST_CW_CLNT_HELLO_A: + str = "SSLv3 write client hello A"; + break; + case SSL3_ST_CW_CLNT_HELLO_B: + str = "SSLv3 write client hello B"; + break; + case SSL3_ST_CR_SRVR_HELLO_A: + str = "SSLv3 read server hello A"; + break; + case SSL3_ST_CR_SRVR_HELLO_B: + str = "SSLv3 read server hello B"; + break; + case SSL3_ST_CR_CERT_A: + str = "SSLv3 read server certificate A"; + break; + case SSL3_ST_CR_CERT_B: + str = "SSLv3 read server certificate B"; + break; + case SSL3_ST_CR_KEY_EXCH_A: + str = "SSLv3 read server key exchange A"; + break; + case SSL3_ST_CR_KEY_EXCH_B: + str = "SSLv3 read server key exchange B"; + break; + case SSL3_ST_CR_CERT_REQ_A: + str = "SSLv3 read server certificate request A"; + break; + case SSL3_ST_CR_CERT_REQ_B: + str = "SSLv3 read server certificate request B"; + break; + case SSL3_ST_CR_SESSION_TICKET_A: + str = "SSLv3 read server session ticket A"; + break; + case SSL3_ST_CR_SESSION_TICKET_B: + str = "SSLv3 read server session ticket B"; + break; + case SSL3_ST_CR_SRVR_DONE_A: + str = "SSLv3 read server done A"; + break; + case SSL3_ST_CR_SRVR_DONE_B: + str = "SSLv3 read server done B"; + break; + case SSL3_ST_CW_CERT_A: + str = "SSLv3 write client certificate A"; + break; + case SSL3_ST_CW_CERT_B: + str = "SSLv3 write client certificate B"; + break; + case SSL3_ST_CW_CERT_C: + str = "SSLv3 write client certificate C"; + break; + case SSL3_ST_CW_CERT_D: + str = "SSLv3 write client certificate D"; + break; + case SSL3_ST_CW_KEY_EXCH_A: + str = "SSLv3 write client key exchange A"; + break; + case SSL3_ST_CW_KEY_EXCH_B: + str = "SSLv3 write client key exchange B"; + break; + case SSL3_ST_CW_CERT_VRFY_A: + str = "SSLv3 write certificate verify A"; + break; + case SSL3_ST_CW_CERT_VRFY_B: + str = "SSLv3 write certificate verify B"; + break; + + case SSL3_ST_CW_CHANGE_A: + case SSL3_ST_SW_CHANGE_A: + str = "SSLv3 write change cipher spec A"; + break; + case SSL3_ST_CW_CHANGE_B: + case SSL3_ST_SW_CHANGE_B: + str = "SSLv3 write change cipher spec B"; + break; + case SSL3_ST_CW_FINISHED_A: + case SSL3_ST_SW_FINISHED_A: + str = "SSLv3 write finished A"; + break; + case SSL3_ST_CW_FINISHED_B: + case SSL3_ST_SW_FINISHED_B: + str = "SSLv3 write finished B"; + break; + case SSL3_ST_CR_CHANGE_A: + case SSL3_ST_SR_CHANGE_A: + str = "SSLv3 read change cipher spec A"; + break; + case SSL3_ST_CR_CHANGE_B: + case SSL3_ST_SR_CHANGE_B: + str = "SSLv3 read change cipher spec B"; + break; + case SSL3_ST_CR_FINISHED_A: + case SSL3_ST_SR_FINISHED_A: + str = "SSLv3 read finished A"; + break; + case SSL3_ST_CR_FINISHED_B: + case SSL3_ST_SR_FINISHED_B: + str = "SSLv3 read finished B"; + break; + + case SSL3_ST_CW_FLUSH: + case SSL3_ST_SW_FLUSH: + str = "SSLv3 flush data"; + break; + + case SSL3_ST_SR_CLNT_HELLO_A: + str = "SSLv3 read client hello A"; + break; + case SSL3_ST_SR_CLNT_HELLO_B: + str = "SSLv3 read client hello B"; + break; + case SSL3_ST_SR_CLNT_HELLO_C: + str = "SSLv3 read client hello C"; + break; + case SSL3_ST_SW_HELLO_REQ_A: + str = "SSLv3 write hello request A"; + break; + case SSL3_ST_SW_HELLO_REQ_B: + str = "SSLv3 write hello request B"; + break; + case SSL3_ST_SW_HELLO_REQ_C: + str = "SSLv3 write hello request C"; + break; + case SSL3_ST_SW_SRVR_HELLO_A: + str = "SSLv3 write server hello A"; + break; + case SSL3_ST_SW_SRVR_HELLO_B: + str = "SSLv3 write server hello B"; + break; + case SSL3_ST_SW_CERT_A: + str = "SSLv3 write certificate A"; + break; + case SSL3_ST_SW_CERT_B: + str = "SSLv3 write certificate B"; + break; + case SSL3_ST_SW_KEY_EXCH_A: + str = "SSLv3 write key exchange A"; + break; + case SSL3_ST_SW_KEY_EXCH_B: + str = "SSLv3 write key exchange B"; + break; + case SSL3_ST_SW_CERT_REQ_A: + str = "SSLv3 write certificate request A"; + break; + case SSL3_ST_SW_CERT_REQ_B: + str = "SSLv3 write certificate request B"; + break; + case SSL3_ST_SW_SESSION_TICKET_A: + str = "SSLv3 write session ticket A"; + break; + case SSL3_ST_SW_SESSION_TICKET_B: + str = "SSLv3 write session ticket B"; + break; + case SSL3_ST_SW_SRVR_DONE_A: + str = "SSLv3 write server done A"; + break; + case SSL3_ST_SW_SRVR_DONE_B: + str = "SSLv3 write server done B"; + break; + case SSL3_ST_SR_CERT_A: + str = "SSLv3 read client certificate A"; + break; + case SSL3_ST_SR_CERT_B: + str = "SSLv3 read client certificate B"; + break; + case SSL3_ST_SR_KEY_EXCH_A: + str = "SSLv3 read client key exchange A"; + break; + case SSL3_ST_SR_KEY_EXCH_B: + str = "SSLv3 read client key exchange B"; + break; + case SSL3_ST_SR_CERT_VRFY_A: + str = "SSLv3 read certificate verify A"; + break; + case SSL3_ST_SR_CERT_VRFY_B: + str = "SSLv3 read certificate verify B"; + break; +#endif + +/* SSLv2/v3 compatibility states */ +/* client */ + case SSL23_ST_CW_CLNT_HELLO_A: + str = "SSLv2/v3 write client hello A"; + break; + case SSL23_ST_CW_CLNT_HELLO_B: + str = "SSLv2/v3 write client hello B"; + break; + case SSL23_ST_CR_SRVR_HELLO_A: + str = "SSLv2/v3 read server hello A"; + break; + case SSL23_ST_CR_SRVR_HELLO_B: + str = "SSLv2/v3 read server hello B"; + break; +/* server */ + case SSL23_ST_SR_CLNT_HELLO_A: + str = "SSLv2/v3 read client hello A"; + break; + case SSL23_ST_SR_CLNT_HELLO_B: + str = "SSLv2/v3 read client hello B"; + break; + +/* DTLS */ + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: + str = "DTLS1 read hello verify request A"; + break; + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: + str = "DTLS1 read hello verify request B"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: + str = "DTLS1 write hello verify request A"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: + str = "DTLS1 write hello verify request B"; + break; + + default: + str = "unknown state"; + break; + } + return (str); +} + +const char *SSL_rstate_string_long(const SSL *s) +{ + const char *str; + + switch (s->rstate) { + case SSL_ST_READ_HEADER: + str = "read header"; + break; + case SSL_ST_READ_BODY: + str = "read body"; + break; + case SSL_ST_READ_DONE: + str = "read done"; + break; + default: + str = "unknown"; + break; + } + return (str); +} + +const char *SSL_state_string(const SSL *s) +{ + const char *str; + + switch (s->state) { + case SSL_ST_BEFORE: + str = "PINIT "; + break; + case SSL_ST_ACCEPT: + str = "AINIT "; + break; + case SSL_ST_CONNECT: + str = "CINIT "; + break; + case SSL_ST_OK: + str = "SSLOK "; + break; + case SSL_ST_ERR: + str = "SSLERR"; + break; +#ifndef OPENSSL_NO_SSL2 + case SSL2_ST_CLIENT_START_ENCRYPTION: + str = "2CSENC"; + break; + case SSL2_ST_SERVER_START_ENCRYPTION: + str = "2SSENC"; + break; + case SSL2_ST_SEND_CLIENT_HELLO_A: + str = "2SCH_A"; + break; + case SSL2_ST_SEND_CLIENT_HELLO_B: + str = "2SCH_B"; + break; + case SSL2_ST_GET_SERVER_HELLO_A: + str = "2GSH_A"; + break; + case SSL2_ST_GET_SERVER_HELLO_B: + str = "2GSH_B"; + break; + case SSL2_ST_SEND_CLIENT_MASTER_KEY_A: + str = "2SCMKA"; + break; + case SSL2_ST_SEND_CLIENT_MASTER_KEY_B: + str = "2SCMKB"; + break; + case SSL2_ST_SEND_CLIENT_FINISHED_A: + str = "2SCF_A"; + break; + case SSL2_ST_SEND_CLIENT_FINISHED_B: + str = "2SCF_B"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_A: + str = "2SCC_A"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_B: + str = "2SCC_B"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_C: + str = "2SCC_C"; + break; + case SSL2_ST_SEND_CLIENT_CERTIFICATE_D: + str = "2SCC_D"; + break; + case SSL2_ST_GET_SERVER_VERIFY_A: + str = "2GSV_A"; + break; + case SSL2_ST_GET_SERVER_VERIFY_B: + str = "2GSV_B"; + break; + case SSL2_ST_GET_SERVER_FINISHED_A: + str = "2GSF_A"; + break; + case SSL2_ST_GET_SERVER_FINISHED_B: + str = "2GSF_B"; + break; + case SSL2_ST_GET_CLIENT_HELLO_A: + str = "2GCH_A"; + break; + case SSL2_ST_GET_CLIENT_HELLO_B: + str = "2GCH_B"; + break; + case SSL2_ST_GET_CLIENT_HELLO_C: + str = "2GCH_C"; + break; + case SSL2_ST_SEND_SERVER_HELLO_A: + str = "2SSH_A"; + break; + case SSL2_ST_SEND_SERVER_HELLO_B: + str = "2SSH_B"; + break; + case SSL2_ST_GET_CLIENT_MASTER_KEY_A: + str = "2GCMKA"; + break; + case SSL2_ST_GET_CLIENT_MASTER_KEY_B: + str = "2GCMKA"; + break; + case SSL2_ST_SEND_SERVER_VERIFY_A: + str = "2SSV_A"; + break; + case SSL2_ST_SEND_SERVER_VERIFY_B: + str = "2SSV_B"; + break; + case SSL2_ST_SEND_SERVER_VERIFY_C: + str = "2SSV_C"; + break; + case SSL2_ST_GET_CLIENT_FINISHED_A: + str = "2GCF_A"; + break; + case SSL2_ST_GET_CLIENT_FINISHED_B: + str = "2GCF_B"; + break; + case SSL2_ST_SEND_SERVER_FINISHED_A: + str = "2SSF_A"; + break; + case SSL2_ST_SEND_SERVER_FINISHED_B: + str = "2SSF_B"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_A: + str = "2SRC_A"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_B: + str = "2SRC_B"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_C: + str = "2SRC_C"; + break; + case SSL2_ST_SEND_REQUEST_CERTIFICATE_D: + str = "2SRC_D"; + break; + case SSL2_ST_X509_GET_SERVER_CERTIFICATE: + str = "2X9GSC"; + break; + case SSL2_ST_X509_GET_CLIENT_CERTIFICATE: + str = "2X9GCC"; + break; +#endif + +#ifndef OPENSSL_NO_SSL3 +/* SSLv3 additions */ + case SSL3_ST_SW_FLUSH: + case SSL3_ST_CW_FLUSH: + str = "3FLUSH"; + break; + case SSL3_ST_CW_CLNT_HELLO_A: + str = "3WCH_A"; + break; + case SSL3_ST_CW_CLNT_HELLO_B: + str = "3WCH_B"; + break; + case SSL3_ST_CR_SRVR_HELLO_A: + str = "3RSH_A"; + break; + case SSL3_ST_CR_SRVR_HELLO_B: + str = "3RSH_B"; + break; + case SSL3_ST_CR_CERT_A: + str = "3RSC_A"; + break; + case SSL3_ST_CR_CERT_B: + str = "3RSC_B"; + break; + case SSL3_ST_CR_KEY_EXCH_A: + str = "3RSKEA"; + break; + case SSL3_ST_CR_KEY_EXCH_B: + str = "3RSKEB"; + break; + case SSL3_ST_CR_CERT_REQ_A: + str = "3RCR_A"; + break; + case SSL3_ST_CR_CERT_REQ_B: + str = "3RCR_B"; + break; + case SSL3_ST_CR_SRVR_DONE_A: + str = "3RSD_A"; + break; + case SSL3_ST_CR_SRVR_DONE_B: + str = "3RSD_B"; + break; + case SSL3_ST_CW_CERT_A: + str = "3WCC_A"; + break; + case SSL3_ST_CW_CERT_B: + str = "3WCC_B"; + break; + case SSL3_ST_CW_CERT_C: + str = "3WCC_C"; + break; + case SSL3_ST_CW_CERT_D: + str = "3WCC_D"; + break; + case SSL3_ST_CW_KEY_EXCH_A: + str = "3WCKEA"; + break; + case SSL3_ST_CW_KEY_EXCH_B: + str = "3WCKEB"; + break; + case SSL3_ST_CW_CERT_VRFY_A: + str = "3WCV_A"; + break; + case SSL3_ST_CW_CERT_VRFY_B: + str = "3WCV_B"; + break; + + case SSL3_ST_SW_CHANGE_A: + case SSL3_ST_CW_CHANGE_A: + str = "3WCCSA"; + break; + case SSL3_ST_SW_CHANGE_B: + case SSL3_ST_CW_CHANGE_B: + str = "3WCCSB"; + break; + case SSL3_ST_SW_FINISHED_A: + case SSL3_ST_CW_FINISHED_A: + str = "3WFINA"; + break; + case SSL3_ST_SW_FINISHED_B: + case SSL3_ST_CW_FINISHED_B: + str = "3WFINB"; + break; + case SSL3_ST_SR_CHANGE_A: + case SSL3_ST_CR_CHANGE_A: + str = "3RCCSA"; + break; + case SSL3_ST_SR_CHANGE_B: + case SSL3_ST_CR_CHANGE_B: + str = "3RCCSB"; + break; + case SSL3_ST_SR_FINISHED_A: + case SSL3_ST_CR_FINISHED_A: + str = "3RFINA"; + break; + case SSL3_ST_SR_FINISHED_B: + case SSL3_ST_CR_FINISHED_B: + str = "3RFINB"; + break; + + case SSL3_ST_SW_HELLO_REQ_A: + str = "3WHR_A"; + break; + case SSL3_ST_SW_HELLO_REQ_B: + str = "3WHR_B"; + break; + case SSL3_ST_SW_HELLO_REQ_C: + str = "3WHR_C"; + break; + case SSL3_ST_SR_CLNT_HELLO_A: + str = "3RCH_A"; + break; + case SSL3_ST_SR_CLNT_HELLO_B: + str = "3RCH_B"; + break; + case SSL3_ST_SR_CLNT_HELLO_C: + str = "3RCH_C"; + break; + case SSL3_ST_SW_SRVR_HELLO_A: + str = "3WSH_A"; + break; + case SSL3_ST_SW_SRVR_HELLO_B: + str = "3WSH_B"; + break; + case SSL3_ST_SW_CERT_A: + str = "3WSC_A"; + break; + case SSL3_ST_SW_CERT_B: + str = "3WSC_B"; + break; + case SSL3_ST_SW_KEY_EXCH_A: + str = "3WSKEA"; + break; + case SSL3_ST_SW_KEY_EXCH_B: + str = "3WSKEB"; + break; + case SSL3_ST_SW_CERT_REQ_A: + str = "3WCR_A"; + break; + case SSL3_ST_SW_CERT_REQ_B: + str = "3WCR_B"; + break; + case SSL3_ST_SW_SRVR_DONE_A: + str = "3WSD_A"; + break; + case SSL3_ST_SW_SRVR_DONE_B: + str = "3WSD_B"; + break; + case SSL3_ST_SR_CERT_A: + str = "3RCC_A"; + break; + case SSL3_ST_SR_CERT_B: + str = "3RCC_B"; + break; + case SSL3_ST_SR_KEY_EXCH_A: + str = "3RCKEA"; + break; + case SSL3_ST_SR_KEY_EXCH_B: + str = "3RCKEB"; + break; + case SSL3_ST_SR_CERT_VRFY_A: + str = "3RCV_A"; + break; + case SSL3_ST_SR_CERT_VRFY_B: + str = "3RCV_B"; + break; +#endif + +/* SSLv2/v3 compatibility states */ +/* client */ + case SSL23_ST_CW_CLNT_HELLO_A: + str = "23WCHA"; + break; + case SSL23_ST_CW_CLNT_HELLO_B: + str = "23WCHB"; + break; + case SSL23_ST_CR_SRVR_HELLO_A: + str = "23RSHA"; + break; + case SSL23_ST_CR_SRVR_HELLO_B: + str = "23RSHA"; + break; +/* server */ + case SSL23_ST_SR_CLNT_HELLO_A: + str = "23RCHA"; + break; + case SSL23_ST_SR_CLNT_HELLO_B: + str = "23RCHB"; + break; + +/* DTLS */ + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_A: + str = "DRCHVA"; + break; + case DTLS1_ST_CR_HELLO_VERIFY_REQUEST_B: + str = "DRCHVB"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A: + str = "DWCHVA"; + break; + case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B: + str = "DWCHVB"; + break; + + default: + str = "UNKWN "; + break; + } + return (str); +} + +const char *SSL_alert_type_string_long(int value) +{ + value >>= 8; + if (value == SSL3_AL_WARNING) + return ("warning"); + else if (value == SSL3_AL_FATAL) + return ("fatal"); + else + return ("unknown"); +} + +const char *SSL_alert_type_string(int value) +{ + value >>= 8; + if (value == SSL3_AL_WARNING) + return ("W"); + else if (value == SSL3_AL_FATAL) + return ("F"); + else + return ("U"); +} + +const char *SSL_alert_desc_string(int value) +{ + const char *str; + + switch (value & 0xff) { + case SSL3_AD_CLOSE_NOTIFY: + str = "CN"; + break; + case SSL3_AD_UNEXPECTED_MESSAGE: + str = "UM"; + break; + case SSL3_AD_BAD_RECORD_MAC: + str = "BM"; + break; + case SSL3_AD_DECOMPRESSION_FAILURE: + str = "DF"; + break; + case SSL3_AD_HANDSHAKE_FAILURE: + str = "HF"; + break; + case SSL3_AD_NO_CERTIFICATE: + str = "NC"; + break; + case SSL3_AD_BAD_CERTIFICATE: + str = "BC"; + break; + case SSL3_AD_UNSUPPORTED_CERTIFICATE: + str = "UC"; + break; + case SSL3_AD_CERTIFICATE_REVOKED: + str = "CR"; + break; + case SSL3_AD_CERTIFICATE_EXPIRED: + str = "CE"; + break; + case SSL3_AD_CERTIFICATE_UNKNOWN: + str = "CU"; + break; + case SSL3_AD_ILLEGAL_PARAMETER: + str = "IP"; + break; + case TLS1_AD_DECRYPTION_FAILED: + str = "DC"; + break; + case TLS1_AD_RECORD_OVERFLOW: + str = "RO"; + break; + case TLS1_AD_UNKNOWN_CA: + str = "CA"; + break; + case TLS1_AD_ACCESS_DENIED: + str = "AD"; + break; + case TLS1_AD_DECODE_ERROR: + str = "DE"; + break; + case TLS1_AD_DECRYPT_ERROR: + str = "CY"; + break; + case TLS1_AD_EXPORT_RESTRICTION: + str = "ER"; + break; + case TLS1_AD_PROTOCOL_VERSION: + str = "PV"; + break; + case TLS1_AD_INSUFFICIENT_SECURITY: + str = "IS"; + break; + case TLS1_AD_INTERNAL_ERROR: + str = "IE"; + break; + case TLS1_AD_USER_CANCELLED: + str = "US"; + break; + case TLS1_AD_NO_RENEGOTIATION: + str = "NR"; + break; + case TLS1_AD_UNSUPPORTED_EXTENSION: + str = "UE"; + break; + case TLS1_AD_CERTIFICATE_UNOBTAINABLE: + str = "CO"; + break; + case TLS1_AD_UNRECOGNIZED_NAME: + str = "UN"; + break; + case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + str = "BR"; + break; + case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: + str = "BH"; + break; + case TLS1_AD_UNKNOWN_PSK_IDENTITY: + str = "UP"; + break; + default: + str = "UK"; + break; + } + return (str); +} + +const char *SSL_alert_desc_string_long(int value) +{ + const char *str; + + switch (value & 0xff) { + case SSL3_AD_CLOSE_NOTIFY: + str = "close notify"; + break; + case SSL3_AD_UNEXPECTED_MESSAGE: + str = "unexpected_message"; + break; + case SSL3_AD_BAD_RECORD_MAC: + str = "bad record mac"; + break; + case SSL3_AD_DECOMPRESSION_FAILURE: + str = "decompression failure"; + break; + case SSL3_AD_HANDSHAKE_FAILURE: + str = "handshake failure"; + break; + case SSL3_AD_NO_CERTIFICATE: + str = "no certificate"; + break; + case SSL3_AD_BAD_CERTIFICATE: + str = "bad certificate"; + break; + case SSL3_AD_UNSUPPORTED_CERTIFICATE: + str = "unsupported certificate"; + break; + case SSL3_AD_CERTIFICATE_REVOKED: + str = "certificate revoked"; + break; + case SSL3_AD_CERTIFICATE_EXPIRED: + str = "certificate expired"; + break; + case SSL3_AD_CERTIFICATE_UNKNOWN: + str = "certificate unknown"; + break; + case SSL3_AD_ILLEGAL_PARAMETER: + str = "illegal parameter"; + break; + case TLS1_AD_DECRYPTION_FAILED: + str = "decryption failed"; + break; + case TLS1_AD_RECORD_OVERFLOW: + str = "record overflow"; + break; + case TLS1_AD_UNKNOWN_CA: + str = "unknown CA"; + break; + case TLS1_AD_ACCESS_DENIED: + str = "access denied"; + break; + case TLS1_AD_DECODE_ERROR: + str = "decode error"; + break; + case TLS1_AD_DECRYPT_ERROR: + str = "decrypt error"; + break; + case TLS1_AD_EXPORT_RESTRICTION: + str = "export restriction"; + break; + case TLS1_AD_PROTOCOL_VERSION: + str = "protocol version"; + break; + case TLS1_AD_INSUFFICIENT_SECURITY: + str = "insufficient security"; + break; + case TLS1_AD_INTERNAL_ERROR: + str = "internal error"; + break; + case TLS1_AD_USER_CANCELLED: + str = "user canceled"; + break; + case TLS1_AD_NO_RENEGOTIATION: + str = "no renegotiation"; + break; + case TLS1_AD_UNSUPPORTED_EXTENSION: + str = "unsupported extension"; + break; + case TLS1_AD_CERTIFICATE_UNOBTAINABLE: + str = "certificate unobtainable"; + break; + case TLS1_AD_UNRECOGNIZED_NAME: + str = "unrecognized name"; + break; + case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + str = "bad certificate status response"; + break; + case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: + str = "bad certificate hash value"; + break; + case TLS1_AD_UNKNOWN_PSK_IDENTITY: + str = "unknown PSK identity"; + break; + default: + str = "unknown"; + break; + } + return (str); +} + +const char *SSL_rstate_string(const SSL *s) +{ + const char *str; + + switch (s->rstate) { + case SSL_ST_READ_HEADER: + str = "RH"; + break; + case SSL_ST_READ_BODY: + str = "RB"; + break; + case SSL_ST_READ_DONE: + str = "RD"; + break; + default: + str = "unknown"; + break; + } + return (str); +} diff --git a/libs/openssl/ssl/ssl_txt.c b/libs/openssl/ssl/ssl_txt.c new file mode 100644 index 00000000..bd67dc70 --- /dev/null +++ b/libs/openssl/ssl/ssl_txt.c @@ -0,0 +1,260 @@ +/* ssl/ssl_txt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include +#include "ssl_locl.h" + +#ifndef OPENSSL_NO_FP_API +int SSL_SESSION_print_fp(FILE *fp, const SSL_SESSION *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file_internal())) == NULL) { + SSLerr(SSL_F_SSL_SESSION_PRINT_FP, ERR_R_BUF_LIB); + return (0); + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = SSL_SESSION_print(b, x); + BIO_free(b); + return (ret); +} +#endif + +int SSL_SESSION_print(BIO *bp, const SSL_SESSION *x) +{ + unsigned int i; + const char *s; + + if (x == NULL) + goto err; + if (BIO_puts(bp, "SSL-Session:\n") <= 0) + goto err; + if (x->ssl_version == SSL2_VERSION) + s = "SSLv2"; + else if (x->ssl_version == SSL3_VERSION) + s = "SSLv3"; + else if (x->ssl_version == TLS1_2_VERSION) + s = "TLSv1.2"; + else if (x->ssl_version == TLS1_1_VERSION) + s = "TLSv1.1"; + else if (x->ssl_version == TLS1_VERSION) + s = "TLSv1"; + else if (x->ssl_version == DTLS1_VERSION) + s = "DTLSv1"; + else if (x->ssl_version == DTLS1_BAD_VER) + s = "DTLSv1-bad"; + else + s = "unknown"; + if (BIO_printf(bp, " Protocol : %s\n", s) <= 0) + goto err; + + if (x->cipher == NULL) { + if (((x->cipher_id) & 0xff000000) == 0x02000000) { + if (BIO_printf + (bp, " Cipher : %06lX\n", x->cipher_id & 0xffffff) <= 0) + goto err; + } else { + if (BIO_printf + (bp, " Cipher : %04lX\n", x->cipher_id & 0xffff) <= 0) + goto err; + } + } else { + if (BIO_printf + (bp, " Cipher : %s\n", + ((x->cipher == NULL) ? "unknown" : x->cipher->name)) <= 0) + goto err; + } + if (BIO_puts(bp, " Session-ID: ") <= 0) + goto err; + for (i = 0; i < x->session_id_length; i++) { + if (BIO_printf(bp, "%02X", x->session_id[i]) <= 0) + goto err; + } + if (BIO_puts(bp, "\n Session-ID-ctx: ") <= 0) + goto err; + for (i = 0; i < x->sid_ctx_length; i++) { + if (BIO_printf(bp, "%02X", x->sid_ctx[i]) <= 0) + goto err; + } + if (BIO_puts(bp, "\n Master-Key: ") <= 0) + goto err; + for (i = 0; i < (unsigned int)x->master_key_length; i++) { + if (BIO_printf(bp, "%02X", x->master_key[i]) <= 0) + goto err; + } + if (BIO_puts(bp, "\n Key-Arg : ") <= 0) + goto err; + if (x->key_arg_length == 0) { + if (BIO_puts(bp, "None") <= 0) + goto err; + } else + for (i = 0; i < x->key_arg_length; i++) { + if (BIO_printf(bp, "%02X", x->key_arg[i]) <= 0) + goto err; + } +#ifndef OPENSSL_NO_KRB5 + if (BIO_puts(bp, "\n Krb5 Principal: ") <= 0) + goto err; + if (x->krb5_client_princ_len == 0) { + if (BIO_puts(bp, "None") <= 0) + goto err; + } else + for (i = 0; i < x->krb5_client_princ_len; i++) { + if (BIO_printf(bp, "%02X", x->krb5_client_princ[i]) <= 0) + goto err; + } +#endif /* OPENSSL_NO_KRB5 */ +#ifndef OPENSSL_NO_PSK + if (BIO_puts(bp, "\n PSK identity: ") <= 0) + goto err; + if (BIO_printf(bp, "%s", x->psk_identity ? x->psk_identity : "None") <= 0) + goto err; + if (BIO_puts(bp, "\n PSK identity hint: ") <= 0) + goto err; + if (BIO_printf + (bp, "%s", x->psk_identity_hint ? x->psk_identity_hint : "None") <= 0) + goto err; +#endif +#ifndef OPENSSL_NO_SRP + if (BIO_puts(bp, "\n SRP username: ") <= 0) + goto err; + if (BIO_printf(bp, "%s", x->srp_username ? x->srp_username : "None") <= 0) + goto err; +#endif +#ifndef OPENSSL_NO_TLSEXT + if (x->tlsext_tick_lifetime_hint) { + if (BIO_printf(bp, + "\n TLS session ticket lifetime hint: %ld (seconds)", + x->tlsext_tick_lifetime_hint) <= 0) + goto err; + } + if (x->tlsext_tick) { + if (BIO_puts(bp, "\n TLS session ticket:\n") <= 0) + goto err; + if (BIO_dump_indent(bp, (char *)x->tlsext_tick, x->tlsext_ticklen, 4) + <= 0) + goto err; + } +#endif + +#ifndef OPENSSL_NO_COMP + if (x->compress_meth != 0) { + SSL_COMP *comp = NULL; + + ssl_cipher_get_evp(x, NULL, NULL, NULL, NULL, &comp); + if (comp == NULL) { + if (BIO_printf(bp, "\n Compression: %d", x->compress_meth) <= + 0) + goto err; + } else { + if (BIO_printf + (bp, "\n Compression: %d (%s)", comp->id, + comp->method->name) <= 0) + goto err; + } + } +#endif + if (x->time != 0L) { + if (BIO_printf(bp, "\n Start Time: %ld", x->time) <= 0) + goto err; + } + if (x->timeout != 0L) { + if (BIO_printf(bp, "\n Timeout : %ld (sec)", x->timeout) <= 0) + goto err; + } + if (BIO_puts(bp, "\n") <= 0) + goto err; + + if (BIO_puts(bp, " Verify return code: ") <= 0) + goto err; + if (BIO_printf(bp, "%ld (%s)\n", x->verify_result, + X509_verify_cert_error_string(x->verify_result)) <= 0) + goto err; + + return (1); + err: + return (0); +} diff --git a/libs/openssl/ssl/ssl_utst.c b/libs/openssl/ssl/ssl_utst.c new file mode 100644 index 00000000..53bdde33 --- /dev/null +++ b/libs/openssl/ssl/ssl_utst.c @@ -0,0 +1,72 @@ +/* ssl_utst.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL + * project. + */ +/* ==================================================================== + * Copyright (c) 2014 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + */ + +#include "ssl_locl.h" + +#ifndef OPENSSL_NO_UNIT_TEST + +static const struct openssl_ssl_test_functions ssl_test_functions = { + ssl_init_wbio_buffer, + ssl3_setup_buffers, + tls1_process_heartbeat, + dtls1_process_heartbeat +}; + +const struct openssl_ssl_test_functions *SSL_test_functions(void) +{ + return &ssl_test_functions; +} + +#endif diff --git a/libs/openssl/ssl/t1_clnt.c b/libs/openssl/ssl/t1_clnt.c new file mode 100644 index 00000000..05c7f200 --- /dev/null +++ b/libs/openssl/ssl/t1_clnt.c @@ -0,0 +1,88 @@ +/* ssl/t1_clnt.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "ssl_locl.h" +#include +#include +#include +#include + +static const SSL_METHOD *tls1_get_client_method(int ver); +static const SSL_METHOD *tls1_get_client_method(int ver) +{ + if (ver == TLS1_2_VERSION) + return TLSv1_2_client_method(); + if (ver == TLS1_1_VERSION) + return TLSv1_1_client_method(); + if (ver == TLS1_VERSION) + return TLSv1_client_method(); + return NULL; +} + +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_client_method, + ssl_undefined_function, + ssl3_connect, tls1_get_client_method) + + IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_client_method, + ssl_undefined_function, + ssl3_connect, tls1_get_client_method) + + IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_client_method, + ssl_undefined_function, + ssl3_connect, tls1_get_client_method) diff --git a/libs/openssl/ssl/t1_enc.c b/libs/openssl/ssl/t1_enc.c new file mode 100644 index 00000000..9786b263 --- /dev/null +++ b/libs/openssl/ssl/t1_enc.c @@ -0,0 +1,1343 @@ +/* ssl/t1_enc.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +/* ==================================================================== + * Copyright 2005 Nokia. All rights reserved. + * + * The portions of the attached software ("Contribution") is developed by + * Nokia Corporation and is licensed pursuant to the OpenSSL open source + * license. + * + * The Contribution, originally written by Mika Kousa and Pasi Eronen of + * Nokia Corporation, consists of the "PSK" (Pre-Shared Key) ciphersuites + * support (see RFC 4279) to OpenSSL. + * + * No patent licenses or other rights except those expressly stated in + * the OpenSSL open source license shall be deemed granted or received + * expressly, by implication, estoppel, or otherwise. + * + * No assurances are provided by Nokia that the Contribution does not + * infringe the patent or other intellectual property rights of any third + * party or that the license provides you with all the necessary rights + * to make use of the Contribution. + * + * THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. IN + * ADDITION TO THE DISCLAIMERS INCLUDED IN THE LICENSE, NOKIA + * SPECIFICALLY DISCLAIMS ANY LIABILITY FOR CLAIMS BROUGHT BY YOU OR ANY + * OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL PROPERTY RIGHTS OR + * OTHERWISE. + */ + +#include +#include "ssl_locl.h" +#ifndef OPENSSL_NO_COMP +# include +#endif +#include +#include +#include +#include +#ifdef KSSL_DEBUG +# include +#endif + +/* seed1 through seed5 are virtually concatenated */ +static int tls1_P_hash(const EVP_MD *md, const unsigned char *sec, + int sec_len, + const void *seed1, int seed1_len, + const void *seed2, int seed2_len, + const void *seed3, int seed3_len, + const void *seed4, int seed4_len, + const void *seed5, int seed5_len, + unsigned char *out, int olen) +{ + int chunk; + size_t j; + EVP_MD_CTX ctx, ctx_tmp; + EVP_PKEY *mac_key; + unsigned char A1[EVP_MAX_MD_SIZE]; + size_t A1_len; + int ret = 0; + + chunk = EVP_MD_size(md); + OPENSSL_assert(chunk >= 0); + + EVP_MD_CTX_init(&ctx); + EVP_MD_CTX_init(&ctx_tmp); + EVP_MD_CTX_set_flags(&ctx, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + EVP_MD_CTX_set_flags(&ctx_tmp, EVP_MD_CTX_FLAG_NON_FIPS_ALLOW); + mac_key = EVP_PKEY_new_mac_key(EVP_PKEY_HMAC, NULL, sec, sec_len); + if (!mac_key) + goto err; + if (!EVP_DigestSignInit(&ctx, NULL, md, NULL, mac_key)) + goto err; + if (!EVP_DigestSignInit(&ctx_tmp, NULL, md, NULL, mac_key)) + goto err; + if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) + goto err; + if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) + goto err; + if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) + goto err; + if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len)) + goto err; + if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len)) + goto err; + if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) + goto err; + + for (;;) { + /* Reinit mac contexts */ + if (!EVP_DigestSignInit(&ctx, NULL, md, NULL, mac_key)) + goto err; + if (!EVP_DigestSignInit(&ctx_tmp, NULL, md, NULL, mac_key)) + goto err; + if (!EVP_DigestSignUpdate(&ctx, A1, A1_len)) + goto err; + if (!EVP_DigestSignUpdate(&ctx_tmp, A1, A1_len)) + goto err; + if (seed1 && !EVP_DigestSignUpdate(&ctx, seed1, seed1_len)) + goto err; + if (seed2 && !EVP_DigestSignUpdate(&ctx, seed2, seed2_len)) + goto err; + if (seed3 && !EVP_DigestSignUpdate(&ctx, seed3, seed3_len)) + goto err; + if (seed4 && !EVP_DigestSignUpdate(&ctx, seed4, seed4_len)) + goto err; + if (seed5 && !EVP_DigestSignUpdate(&ctx, seed5, seed5_len)) + goto err; + + if (olen > chunk) { + if (!EVP_DigestSignFinal(&ctx, out, &j)) + goto err; + out += j; + olen -= j; + /* calc the next A1 value */ + if (!EVP_DigestSignFinal(&ctx_tmp, A1, &A1_len)) + goto err; + } else { /* last one */ + + if (!EVP_DigestSignFinal(&ctx, A1, &A1_len)) + goto err; + memcpy(out, A1, olen); + break; + } + } + ret = 1; + err: + EVP_PKEY_free(mac_key); + EVP_MD_CTX_cleanup(&ctx); + EVP_MD_CTX_cleanup(&ctx_tmp); + OPENSSL_cleanse(A1, sizeof(A1)); + return ret; +} + +/* seed1 through seed5 are virtually concatenated */ +static int tls1_PRF(long digest_mask, + const void *seed1, int seed1_len, + const void *seed2, int seed2_len, + const void *seed3, int seed3_len, + const void *seed4, int seed4_len, + const void *seed5, int seed5_len, + const unsigned char *sec, int slen, + unsigned char *out1, unsigned char *out2, int olen) +{ + int len, i, idx, count; + const unsigned char *S1; + long m; + const EVP_MD *md; + int ret = 0; + + /* Count number of digests and partition sec evenly */ + count = 0; + for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { + if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) + count++; + } + if (!count) { + /* Should never happen */ + SSLerr(SSL_F_TLS1_PRF, ERR_R_INTERNAL_ERROR); + goto err; + } + len = slen / count; + if (count == 1) + slen = 0; + S1 = sec; + memset(out1, 0, olen); + for (idx = 0; ssl_get_handshake_digest(idx, &m, &md); idx++) { + if ((m << TLS1_PRF_DGST_SHIFT) & digest_mask) { + if (!md) { + SSLerr(SSL_F_TLS1_PRF, SSL_R_UNSUPPORTED_DIGEST_TYPE); + goto err; + } + if (!tls1_P_hash(md, S1, len + (slen & 1), + seed1, seed1_len, seed2, seed2_len, seed3, + seed3_len, seed4, seed4_len, seed5, seed5_len, + out2, olen)) + goto err; + S1 += len; + for (i = 0; i < olen; i++) { + out1[i] ^= out2[i]; + } + } + } + ret = 1; + err: + return ret; +} + +static int tls1_generate_key_block(SSL *s, unsigned char *km, + unsigned char *tmp, int num) +{ + int ret; + ret = tls1_PRF(ssl_get_algorithm2(s), + TLS_MD_KEY_EXPANSION_CONST, + TLS_MD_KEY_EXPANSION_CONST_SIZE, s->s3->server_random, + SSL3_RANDOM_SIZE, s->s3->client_random, SSL3_RANDOM_SIZE, + NULL, 0, NULL, 0, s->session->master_key, + s->session->master_key_length, km, tmp, num); +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_generate_key_block() ==> %d byte master_key =\n\t", + s->session->master_key_length); + { + int i; + for (i = 0; i < s->session->master_key_length; i++) { + fprintf(stderr, "%02X", s->session->master_key[i]); + } + fprintf(stderr, "\n"); + } +#endif /* KSSL_DEBUG */ + return ret; +} + +int tls1_change_cipher_state(SSL *s, int which) +{ + static const unsigned char empty[] = ""; + unsigned char *p, *mac_secret; + unsigned char *exp_label; + unsigned char tmp1[EVP_MAX_KEY_LENGTH]; + unsigned char tmp2[EVP_MAX_KEY_LENGTH]; + unsigned char iv1[EVP_MAX_IV_LENGTH * 2]; + unsigned char iv2[EVP_MAX_IV_LENGTH * 2]; + unsigned char *ms, *key, *iv; + int client_write; + EVP_CIPHER_CTX *dd; + const EVP_CIPHER *c; +#ifndef OPENSSL_NO_COMP + const SSL_COMP *comp; +#endif + const EVP_MD *m; + int mac_type; + int *mac_secret_size; + EVP_MD_CTX *mac_ctx; + EVP_PKEY *mac_key; + int is_export, n, i, j, k, exp_label_len, cl; + int reuse_dd = 0; + + is_export = SSL_C_IS_EXPORT(s->s3->tmp.new_cipher); + c = s->s3->tmp.new_sym_enc; + m = s->s3->tmp.new_hash; + mac_type = s->s3->tmp.new_mac_pkey_type; +#ifndef OPENSSL_NO_COMP + comp = s->s3->tmp.new_compression; +#endif + +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_change_cipher_state(which= %d) w/\n", which); + fprintf(stderr, "\talg= %ld/%ld, comp= %p\n", + s->s3->tmp.new_cipher->algorithm_mkey, + s->s3->tmp.new_cipher->algorithm_auth, comp); + fprintf(stderr, "\tevp_cipher == %p ==? &d_cbc_ede_cipher3\n", c); + fprintf(stderr, "\tevp_cipher: nid, blksz= %d, %d, keylen=%d, ivlen=%d\n", + c->nid, c->block_size, c->key_len, c->iv_len); + fprintf(stderr, "\tkey_block: len= %d, data= ", + s->s3->tmp.key_block_length); + { + int i; + for (i = 0; i < s->s3->tmp.key_block_length; i++) + fprintf(stderr, "%02x", s->s3->tmp.key_block[i]); + fprintf(stderr, "\n"); + } +#endif /* KSSL_DEBUG */ + + if (which & SSL3_CC_READ) { + if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) + s->mac_flags |= SSL_MAC_FLAG_READ_MAC_STREAM; + else + s->mac_flags &= ~SSL_MAC_FLAG_READ_MAC_STREAM; + + if (s->enc_read_ctx != NULL) + reuse_dd = 1; + else if ((s->enc_read_ctx = + OPENSSL_malloc(sizeof(EVP_CIPHER_CTX))) == NULL) + goto err; + else + /* + * make sure it's intialized in case we exit later with an error + */ + EVP_CIPHER_CTX_init(s->enc_read_ctx); + dd = s->enc_read_ctx; + mac_ctx = ssl_replace_hash(&s->read_hash, NULL); + if (mac_ctx == NULL) + goto err; +#ifndef OPENSSL_NO_COMP + if (s->expand != NULL) { + COMP_CTX_free(s->expand); + s->expand = NULL; + } + if (comp != NULL) { + s->expand = COMP_CTX_new(comp->method); + if (s->expand == NULL) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, + SSL_R_COMPRESSION_LIBRARY_ERROR); + goto err2; + } + if (s->s3->rrec.comp == NULL) + s->s3->rrec.comp = (unsigned char *) + OPENSSL_malloc(SSL3_RT_MAX_ENCRYPTED_LENGTH); + if (s->s3->rrec.comp == NULL) + goto err; + } +#endif + /* + * this is done by dtls1_reset_seq_numbers for DTLS1_VERSION + */ + if (s->version != DTLS1_VERSION) + memset(&(s->s3->read_sequence[0]), 0, 8); + mac_secret = &(s->s3->read_mac_secret[0]); + mac_secret_size = &(s->s3->read_mac_secret_size); + } else { + if (s->s3->tmp.new_cipher->algorithm2 & TLS1_STREAM_MAC) + s->mac_flags |= SSL_MAC_FLAG_WRITE_MAC_STREAM; + else + s->mac_flags &= ~SSL_MAC_FLAG_WRITE_MAC_STREAM; + if (s->enc_write_ctx != NULL && !SSL_IS_DTLS(s)) + reuse_dd = 1; + else if ((s->enc_write_ctx = EVP_CIPHER_CTX_new()) == NULL) + goto err; + dd = s->enc_write_ctx; + if (SSL_IS_DTLS(s)) { + mac_ctx = EVP_MD_CTX_create(); + if (mac_ctx == NULL) + goto err; + s->write_hash = mac_ctx; + } else { + mac_ctx = ssl_replace_hash(&s->write_hash, NULL); + if (mac_ctx == NULL) + goto err; + } +#ifndef OPENSSL_NO_COMP + if (s->compress != NULL) { + COMP_CTX_free(s->compress); + s->compress = NULL; + } + if (comp != NULL) { + s->compress = COMP_CTX_new(comp->method); + if (s->compress == NULL) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, + SSL_R_COMPRESSION_LIBRARY_ERROR); + goto err2; + } + } +#endif + /* + * this is done by dtls1_reset_seq_numbers for DTLS1_VERSION + */ + if (s->version != DTLS1_VERSION) + memset(&(s->s3->write_sequence[0]), 0, 8); + mac_secret = &(s->s3->write_mac_secret[0]); + mac_secret_size = &(s->s3->write_mac_secret_size); + } + + if (reuse_dd) + EVP_CIPHER_CTX_cleanup(dd); + + p = s->s3->tmp.key_block; + i = *mac_secret_size = s->s3->tmp.new_mac_secret_size; + + cl = EVP_CIPHER_key_length(c); + j = is_export ? (cl < SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher) ? + cl : SSL_C_EXPORT_KEYLENGTH(s->s3->tmp.new_cipher)) : cl; + /* Was j=(exp)?5:EVP_CIPHER_key_length(c); */ + /* If GCM mode only part of IV comes from PRF */ + if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) + k = EVP_GCM_TLS_FIXED_IV_LEN; + else + k = EVP_CIPHER_iv_length(c); + if ((which == SSL3_CHANGE_CIPHER_CLIENT_WRITE) || + (which == SSL3_CHANGE_CIPHER_SERVER_READ)) { + ms = &(p[0]); + n = i + i; + key = &(p[n]); + n += j + j; + iv = &(p[n]); + n += k + k; + exp_label = (unsigned char *)TLS_MD_CLIENT_WRITE_KEY_CONST; + exp_label_len = TLS_MD_CLIENT_WRITE_KEY_CONST_SIZE; + client_write = 1; + } else { + n = i; + ms = &(p[n]); + n += i + j; + key = &(p[n]); + n += j + k; + iv = &(p[n]); + n += k; + exp_label = (unsigned char *)TLS_MD_SERVER_WRITE_KEY_CONST; + exp_label_len = TLS_MD_SERVER_WRITE_KEY_CONST_SIZE; + client_write = 0; + } + + if (n > s->s3->tmp.key_block_length) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } + + memcpy(mac_secret, ms, i); + + if (!(EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER)) { + mac_key = EVP_PKEY_new_mac_key(mac_type, NULL, + mac_secret, *mac_secret_size); + if (mac_key == NULL + || EVP_DigestSignInit(mac_ctx, NULL, m, NULL, mac_key) <= 0) { + EVP_PKEY_free(mac_key); + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } + EVP_PKEY_free(mac_key); + } +#ifdef TLS_DEBUG + printf("which = %04X\nmac key=", which); + { + int z; + for (z = 0; z < i; z++) + printf("%02X%c", ms[z], ((z + 1) % 16) ? ' ' : '\n'); + } +#endif + if (is_export) { + /* + * In here I set both the read and write key/iv to the same value + * since only the correct one will be used :-). + */ + if (!tls1_PRF(ssl_get_algorithm2(s), + exp_label, exp_label_len, + s->s3->client_random, SSL3_RANDOM_SIZE, + s->s3->server_random, SSL3_RANDOM_SIZE, + NULL, 0, NULL, 0, + key, j, tmp1, tmp2, EVP_CIPHER_key_length(c))) + goto err2; + key = tmp1; + + if (k > 0) { + if (!tls1_PRF(ssl_get_algorithm2(s), + TLS_MD_IV_BLOCK_CONST, TLS_MD_IV_BLOCK_CONST_SIZE, + s->s3->client_random, SSL3_RANDOM_SIZE, + s->s3->server_random, SSL3_RANDOM_SIZE, + NULL, 0, NULL, 0, empty, 0, iv1, iv2, k * 2)) + goto err2; + if (client_write) + iv = iv1; + else + iv = &(iv1[k]); + } + } + + s->session->key_arg_length = 0; +#ifdef KSSL_DEBUG + { + int i; + fprintf(stderr, "EVP_CipherInit_ex(dd,c,key=,iv=,which)\n"); + fprintf(stderr, "\tkey= "); + for (i = 0; i < c->key_len; i++) + fprintf(stderr, "%02x", key[i]); + fprintf(stderr, "\n"); + fprintf(stderr, "\t iv= "); + for (i = 0; i < c->iv_len; i++) + fprintf(stderr, "%02x", iv[i]); + fprintf(stderr, "\n"); + } +#endif /* KSSL_DEBUG */ + + if (EVP_CIPHER_mode(c) == EVP_CIPH_GCM_MODE) { + if (!EVP_CipherInit_ex(dd, c, NULL, key, NULL, (which & SSL3_CC_WRITE)) + || !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_GCM_SET_IV_FIXED, k, iv)) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } + } else { + if (!EVP_CipherInit_ex(dd, c, NULL, key, iv, (which & SSL3_CC_WRITE))) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } + } + /* Needed for "composite" AEADs, such as RC4-HMAC-MD5 */ + if ((EVP_CIPHER_flags(c) & EVP_CIPH_FLAG_AEAD_CIPHER) && *mac_secret_size + && !EVP_CIPHER_CTX_ctrl(dd, EVP_CTRL_AEAD_SET_MAC_KEY, + *mac_secret_size, mac_secret)) { + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_INTERNAL_ERROR); + goto err2; + } + +#ifdef TLS_DEBUG + printf("which = %04X\nkey=", which); + { + int z; + for (z = 0; z < EVP_CIPHER_key_length(c); z++) + printf("%02X%c", key[z], ((z + 1) % 16) ? ' ' : '\n'); + } + printf("\niv="); + { + int z; + for (z = 0; z < k; z++) + printf("%02X%c", iv[z], ((z + 1) % 16) ? ' ' : '\n'); + } + printf("\n"); +#endif + + OPENSSL_cleanse(tmp1, sizeof(tmp1)); + OPENSSL_cleanse(tmp2, sizeof(tmp1)); + OPENSSL_cleanse(iv1, sizeof(iv1)); + OPENSSL_cleanse(iv2, sizeof(iv2)); + return (1); + err: + SSLerr(SSL_F_TLS1_CHANGE_CIPHER_STATE, ERR_R_MALLOC_FAILURE); + err2: + return (0); +} + +int tls1_setup_key_block(SSL *s) +{ + unsigned char *p1, *p2 = NULL; + const EVP_CIPHER *c; + const EVP_MD *hash; + int num; + SSL_COMP *comp; + int mac_type = NID_undef, mac_secret_size = 0; + int ret = 0; + +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_setup_key_block()\n"); +#endif /* KSSL_DEBUG */ + + if (s->s3->tmp.key_block_length != 0) + return (1); + + if (!ssl_cipher_get_evp + (s->session, &c, &hash, &mac_type, &mac_secret_size, &comp)) { + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + return (0); + } + + s->s3->tmp.new_sym_enc = c; + s->s3->tmp.new_hash = hash; + s->s3->tmp.new_mac_pkey_type = mac_type; + s->s3->tmp.new_mac_secret_size = mac_secret_size; + num = + EVP_CIPHER_key_length(c) + mac_secret_size + EVP_CIPHER_iv_length(c); + num *= 2; + + ssl3_cleanup_key_block(s); + + if ((p1 = (unsigned char *)OPENSSL_malloc(num)) == NULL) { + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); + goto err; + } + + s->s3->tmp.key_block_length = num; + s->s3->tmp.key_block = p1; + + if ((p2 = (unsigned char *)OPENSSL_malloc(num)) == NULL) { + SSLerr(SSL_F_TLS1_SETUP_KEY_BLOCK, ERR_R_MALLOC_FAILURE); + OPENSSL_free(p1); + goto err; + } +#ifdef TLS_DEBUG + printf("client random\n"); + { + int z; + for (z = 0; z < SSL3_RANDOM_SIZE; z++) + printf("%02X%c", s->s3->client_random[z], + ((z + 1) % 16) ? ' ' : '\n'); + } + printf("server random\n"); + { + int z; + for (z = 0; z < SSL3_RANDOM_SIZE; z++) + printf("%02X%c", s->s3->server_random[z], + ((z + 1) % 16) ? ' ' : '\n'); + } + printf("pre-master\n"); + { + int z; + for (z = 0; z < s->session->master_key_length; z++) + printf("%02X%c", s->session->master_key[z], + ((z + 1) % 16) ? ' ' : '\n'); + } +#endif + if (!tls1_generate_key_block(s, p1, p2, num)) + goto err; +#ifdef TLS_DEBUG + printf("\nkey block\n"); + { + int z; + for (z = 0; z < num; z++) + printf("%02X%c", p1[z], ((z + 1) % 16) ? ' ' : '\n'); + } +#endif + + if (!(s->options & SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) + && s->method->version <= TLS1_VERSION) { + /* + * enable vulnerability countermeasure for CBC ciphers with known-IV + * problem (http://www.openssl.org/~bodo/tls-cbc.txt) + */ + s->s3->need_empty_fragments = 1; + + if (s->session->cipher != NULL) { + if (s->session->cipher->algorithm_enc == SSL_eNULL) + s->s3->need_empty_fragments = 0; + +#ifndef OPENSSL_NO_RC4 + if (s->session->cipher->algorithm_enc == SSL_RC4) + s->s3->need_empty_fragments = 0; +#endif + } + } + + ret = 1; + err: + if (p2) { + OPENSSL_cleanse(p2, num); + OPENSSL_free(p2); + } + return (ret); +} + +/*- + * tls1_enc encrypts/decrypts the record in |s->wrec| / |s->rrec|, respectively. + * + * Returns: + * 0: (in non-constant time) if the record is publically invalid (i.e. too + * short etc). + * 1: if the record's padding is valid / the encryption was successful. + * -1: if the record's padding/AEAD-authenticator is invalid or, if sending, + * an internal error occured. + */ +int tls1_enc(SSL *s, int send) +{ + SSL3_RECORD *rec; + EVP_CIPHER_CTX *ds; + unsigned long l; + int bs, i, j, k, pad = 0, ret, mac_size = 0; + const EVP_CIPHER *enc; + + if (send) { + if (EVP_MD_CTX_md(s->write_hash)) { + int n = EVP_MD_CTX_size(s->write_hash); + OPENSSL_assert(n >= 0); + } + ds = s->enc_write_ctx; + rec = &(s->s3->wrec); + if (s->enc_write_ctx == NULL) + enc = NULL; + else { + int ivlen; + enc = EVP_CIPHER_CTX_cipher(s->enc_write_ctx); + /* For TLSv1.1 and later explicit IV */ + if (s->version >= TLS1_1_VERSION + && EVP_CIPHER_mode(enc) == EVP_CIPH_CBC_MODE) + ivlen = EVP_CIPHER_iv_length(enc); + else + ivlen = 0; + if (ivlen > 1) { + if (rec->data != rec->input) + /* + * we can't write into the input stream: Can this ever + * happen?? (steve) + */ + fprintf(stderr, + "%s:%d: rec->data != rec->input\n", + __FILE__, __LINE__); + else if (RAND_bytes(rec->input, ivlen) <= 0) + return -1; + } + } + } else { + if (EVP_MD_CTX_md(s->read_hash)) { + int n = EVP_MD_CTX_size(s->read_hash); + OPENSSL_assert(n >= 0); + } + ds = s->enc_read_ctx; + rec = &(s->s3->rrec); + if (s->enc_read_ctx == NULL) + enc = NULL; + else + enc = EVP_CIPHER_CTX_cipher(s->enc_read_ctx); + } + +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_enc(%d)\n", send); +#endif /* KSSL_DEBUG */ + + if ((s->session == NULL) || (ds == NULL) || (enc == NULL)) { + memmove(rec->data, rec->input, rec->length); + rec->input = rec->data; + ret = 1; + } else { + l = rec->length; + bs = EVP_CIPHER_block_size(ds->cipher); + + if (EVP_CIPHER_flags(ds->cipher) & EVP_CIPH_FLAG_AEAD_CIPHER) { + unsigned char buf[EVP_AEAD_TLS1_AAD_LEN], *seq; + + seq = send ? s->s3->write_sequence : s->s3->read_sequence; + + if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { + unsigned char dtlsseq[9], *p = dtlsseq; + + s2n(send ? s->d1->w_epoch : s->d1->r_epoch, p); + memcpy(p, &seq[2], 6); + memcpy(buf, dtlsseq, 8); + } else { + memcpy(buf, seq, 8); + for (i = 7; i >= 0; i--) { /* increment */ + ++seq[i]; + if (seq[i] != 0) + break; + } + } + + buf[8] = rec->type; + buf[9] = (unsigned char)(s->version >> 8); + buf[10] = (unsigned char)(s->version); + buf[11] = rec->length >> 8; + buf[12] = rec->length & 0xff; + pad = EVP_CIPHER_CTX_ctrl(ds, EVP_CTRL_AEAD_TLS1_AAD, + EVP_AEAD_TLS1_AAD_LEN, buf); + if (pad <= 0) + return -1; + if (send) { + l += pad; + rec->length += pad; + } + } else if ((bs != 1) && send) { + i = bs - ((int)l % bs); + + /* Add weird padding of upto 256 bytes */ + + /* we need to add 'i' padding bytes of value j */ + j = i - 1; + if (s->options & SSL_OP_TLS_BLOCK_PADDING_BUG) { + if (s->s3->flags & TLS1_FLAGS_TLS_PADDING_BUG) + j++; + } + for (k = (int)l; k < (int)(l + i); k++) + rec->input[k] = j; + l += i; + rec->length += i; + } +#ifdef KSSL_DEBUG + { + unsigned long ui; + fprintf(stderr, + "EVP_Cipher(ds=%p,rec->data=%p,rec->input=%p,l=%ld) ==>\n", + ds, rec->data, rec->input, l); + fprintf(stderr, + "\tEVP_CIPHER_CTX: %d buf_len, %d key_len [%lu %lu], %d iv_len\n", + ds->buf_len, ds->cipher->key_len, DES_KEY_SZ, + DES_SCHEDULE_SZ, ds->cipher->iv_len); + fprintf(stderr, "\t\tIV: "); + for (i = 0; i < ds->cipher->iv_len; i++) + fprintf(stderr, "%02X", ds->iv[i]); + fprintf(stderr, "\n"); + fprintf(stderr, "\trec->input="); + for (ui = 0; ui < l; ui++) + fprintf(stderr, " %02x", rec->input[ui]); + fprintf(stderr, "\n"); + } +#endif /* KSSL_DEBUG */ + + if (!send) { + if (l == 0 || l % bs != 0) + return 0; + } + + i = EVP_Cipher(ds, rec->data, rec->input, l); + if ((EVP_CIPHER_flags(ds->cipher) & EVP_CIPH_FLAG_CUSTOM_CIPHER) + ? (i < 0) + : (i == 0)) + return -1; /* AEAD can fail to verify MAC */ + if (EVP_CIPHER_mode(enc) == EVP_CIPH_GCM_MODE && !send) { + rec->data += EVP_GCM_TLS_EXPLICIT_IV_LEN; + rec->input += EVP_GCM_TLS_EXPLICIT_IV_LEN; + rec->length -= EVP_GCM_TLS_EXPLICIT_IV_LEN; + } +#ifdef KSSL_DEBUG + { + unsigned long i; + fprintf(stderr, "\trec->data="); + for (i = 0; i < l; i++) + fprintf(stderr, " %02x", rec->data[i]); + fprintf(stderr, "\n"); + } +#endif /* KSSL_DEBUG */ + + ret = 1; + if (EVP_MD_CTX_md(s->read_hash) != NULL) + mac_size = EVP_MD_CTX_size(s->read_hash); + if ((bs != 1) && !send) + ret = tls1_cbc_remove_padding(s, rec, bs, mac_size); + if (pad && !send) + rec->length -= pad; + } + return ret; +} + +int tls1_cert_verify_mac(SSL *s, int md_nid, unsigned char *out) +{ + unsigned int ret; + EVP_MD_CTX ctx, *d = NULL; + int i; + + if (s->s3->handshake_buffer) + if (!ssl3_digest_cached_records(s)) + return 0; + + for (i = 0; i < SSL_MAX_DIGEST; i++) { + if (s->s3->handshake_dgst[i] + && EVP_MD_CTX_type(s->s3->handshake_dgst[i]) == md_nid) { + d = s->s3->handshake_dgst[i]; + break; + } + } + if (!d) { + SSLerr(SSL_F_TLS1_CERT_VERIFY_MAC, SSL_R_NO_REQUIRED_DIGEST); + return 0; + } + + EVP_MD_CTX_init(&ctx); + if (EVP_MD_CTX_copy_ex(&ctx, d) <=0 + || EVP_DigestFinal_ex(&ctx, out, &ret) <= 0) + ret = 0; + EVP_MD_CTX_cleanup(&ctx); + return ((int)ret); +} + +int tls1_final_finish_mac(SSL *s, + const char *str, int slen, unsigned char *out) +{ + unsigned int i; + EVP_MD_CTX ctx; + unsigned char buf[2 * EVP_MAX_MD_SIZE]; + unsigned char *q, buf2[12]; + int idx; + long mask; + int err = 0; + const EVP_MD *md; + + q = buf; + + if (s->s3->handshake_buffer) + if (!ssl3_digest_cached_records(s)) + return 0; + + EVP_MD_CTX_init(&ctx); + + for (idx = 0; ssl_get_handshake_digest(idx, &mask, &md); idx++) { + if (mask & ssl_get_algorithm2(s)) { + int hashsize = EVP_MD_size(md); + EVP_MD_CTX *hdgst = s->s3->handshake_dgst[idx]; + if (!hdgst || hashsize < 0 + || hashsize > (int)(sizeof buf - (size_t)(q - buf))) { + /* + * internal error: 'buf' is too small for this cipersuite! + */ + err = 1; + } else { + if (!EVP_MD_CTX_copy_ex(&ctx, hdgst) || + !EVP_DigestFinal_ex(&ctx, q, &i) || + (i != (unsigned int)hashsize)) + err = 1; + q += hashsize; + } + } + } + + if (!tls1_PRF(ssl_get_algorithm2(s), + str, slen, buf, (int)(q - buf), NULL, 0, NULL, 0, NULL, 0, + s->session->master_key, s->session->master_key_length, + out, buf2, sizeof buf2)) + err = 1; + EVP_MD_CTX_cleanup(&ctx); + + OPENSSL_cleanse(buf, (int)(q - buf)); + OPENSSL_cleanse(buf2, sizeof(buf2)); + if (err) + return 0; + else + return sizeof buf2; +} + +int tls1_mac(SSL *ssl, unsigned char *md, int send) +{ + SSL3_RECORD *rec; + unsigned char *seq; + EVP_MD_CTX *hash; + size_t md_size, orig_len; + int i; + EVP_MD_CTX hmac, *mac_ctx; + unsigned char header[13]; + int stream_mac = (send ? (ssl->mac_flags & SSL_MAC_FLAG_WRITE_MAC_STREAM) + : (ssl->mac_flags & SSL_MAC_FLAG_READ_MAC_STREAM)); + int t; + + if (send) { + rec = &(ssl->s3->wrec); + seq = &(ssl->s3->write_sequence[0]); + hash = ssl->write_hash; + } else { + rec = &(ssl->s3->rrec); + seq = &(ssl->s3->read_sequence[0]); + hash = ssl->read_hash; + } + + t = EVP_MD_CTX_size(hash); + OPENSSL_assert(t >= 0); + md_size = t; + + /* I should fix this up TLS TLS TLS TLS TLS XXXXXXXX */ + if (stream_mac) { + mac_ctx = hash; + } else { + if (!EVP_MD_CTX_copy(&hmac, hash)) + return -1; + mac_ctx = &hmac; + } + + if (ssl->version == DTLS1_VERSION || ssl->version == DTLS1_BAD_VER) { + unsigned char dtlsseq[8], *p = dtlsseq; + + s2n(send ? ssl->d1->w_epoch : ssl->d1->r_epoch, p); + memcpy(p, &seq[2], 6); + + memcpy(header, dtlsseq, 8); + } else + memcpy(header, seq, 8); + + /* + * kludge: tls1_cbc_remove_padding passes padding length in rec->type + */ + orig_len = rec->length + md_size + ((unsigned int)rec->type >> 8); + rec->type &= 0xff; + + header[8] = rec->type; + header[9] = (unsigned char)(ssl->version >> 8); + header[10] = (unsigned char)(ssl->version); + header[11] = (rec->length) >> 8; + header[12] = (rec->length) & 0xff; + + if (!send && + EVP_CIPHER_CTX_mode(ssl->enc_read_ctx) == EVP_CIPH_CBC_MODE && + ssl3_cbc_record_digest_supported(mac_ctx)) { + /* + * This is a CBC-encrypted record. We must avoid leaking any + * timing-side channel information about how many blocks of data we + * are hashing because that gives an attacker a timing-oracle. + */ + /* Final param == not SSLv3 */ + if (ssl3_cbc_digest_record(mac_ctx, + md, &md_size, + header, rec->input, + rec->length + md_size, orig_len, + ssl->s3->read_mac_secret, + ssl->s3->read_mac_secret_size, 0) <= 0) { + if (!stream_mac) + EVP_MD_CTX_cleanup(&hmac); + return -1; + } + } else { + if (EVP_DigestSignUpdate(mac_ctx, header, sizeof(header)) <= 0 + || EVP_DigestSignUpdate(mac_ctx, rec->input, rec->length) <= 0 + || EVP_DigestSignFinal(mac_ctx, md, &md_size) <= 0) { + if (!stream_mac) + EVP_MD_CTX_cleanup(&hmac); + return -1; + } +#ifdef OPENSSL_FIPS + if (!send && FIPS_mode()) + tls_fips_digest_extra(ssl->enc_read_ctx, + mac_ctx, rec->input, rec->length, orig_len); +#endif + } + + if (!stream_mac) + EVP_MD_CTX_cleanup(&hmac); +#ifdef TLS_DEBUG + fprintf(stderr, "seq="); + { + int z; + for (z = 0; z < 8; z++) + fprintf(stderr, "%02X ", seq[z]); + fprintf(stderr, "\n"); + } + fprintf(stderr, "rec="); + { + unsigned int z; + for (z = 0; z < rec->length; z++) + fprintf(stderr, "%02X ", rec->data[z]); + fprintf(stderr, "\n"); + } +#endif + + if (ssl->version != DTLS1_VERSION && ssl->version != DTLS1_BAD_VER) { + for (i = 7; i >= 0; i--) { + ++seq[i]; + if (seq[i] != 0) + break; + } + } +#ifdef TLS_DEBUG + { + unsigned int z; + for (z = 0; z < md_size; z++) + fprintf(stderr, "%02X ", md[z]); + fprintf(stderr, "\n"); + } +#endif + return (md_size); +} + +int tls1_generate_master_secret(SSL *s, unsigned char *out, unsigned char *p, + int len) +{ + unsigned char buff[SSL_MAX_MASTER_KEY_LENGTH]; + const void *co = NULL, *so = NULL; + int col = 0, sol = 0; + +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_generate_master_secret(%p,%p, %p, %d)\n", s, out, p, + len); +#endif /* KSSL_DEBUG */ + +#ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->client_opaque_prf_input != NULL + && s->s3->server_opaque_prf_input != NULL + && s->s3->client_opaque_prf_input_len > 0 + && s->s3->client_opaque_prf_input_len == + s->s3->server_opaque_prf_input_len) { + co = s->s3->client_opaque_prf_input; + col = s->s3->server_opaque_prf_input_len; + so = s->s3->server_opaque_prf_input; + /* + * must be same as col (see + * draft-rescorla-tls-opaque-prf-input-00.txt, section 3.1) + */ + sol = s->s3->client_opaque_prf_input_len; + } +#endif + + tls1_PRF(ssl_get_algorithm2(s), + TLS_MD_MASTER_SECRET_CONST, TLS_MD_MASTER_SECRET_CONST_SIZE, + s->s3->client_random, SSL3_RANDOM_SIZE, + co, col, + s->s3->server_random, SSL3_RANDOM_SIZE, + so, sol, p, len, s->session->master_key, buff, sizeof buff); + OPENSSL_cleanse(buff, sizeof buff); +#ifdef SSL_DEBUG + fprintf(stderr, "Premaster Secret:\n"); + BIO_dump_fp(stderr, (char *)p, len); + fprintf(stderr, "Client Random:\n"); + BIO_dump_fp(stderr, (char *)s->s3->client_random, SSL3_RANDOM_SIZE); + fprintf(stderr, "Server Random:\n"); + BIO_dump_fp(stderr, (char *)s->s3->server_random, SSL3_RANDOM_SIZE); + fprintf(stderr, "Master Secret:\n"); + BIO_dump_fp(stderr, (char *)s->session->master_key, + SSL3_MASTER_SECRET_SIZE); +#endif + +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_generate_master_secret() complete\n"); +#endif /* KSSL_DEBUG */ + return (SSL3_MASTER_SECRET_SIZE); +} + +int tls1_export_keying_material(SSL *s, unsigned char *out, size_t olen, + const char *label, size_t llen, + const unsigned char *context, + size_t contextlen, int use_context) +{ + unsigned char *buff; + unsigned char *val = NULL; + size_t vallen, currentvalpos; + int rv; + +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_export_keying_material(%p,%p,%lu,%s,%lu,%p,%lu)\n", + s, out, olen, label, llen, context, contextlen); +#endif /* KSSL_DEBUG */ + + buff = OPENSSL_malloc(olen); + if (buff == NULL) + goto err2; + + /* + * construct PRF arguments we construct the PRF argument ourself rather + * than passing separate values into the TLS PRF to ensure that the + * concatenation of values does not create a prohibited label. + */ + vallen = llen + SSL3_RANDOM_SIZE * 2; + if (use_context) { + vallen += 2 + contextlen; + } + + val = OPENSSL_malloc(vallen); + if (val == NULL) + goto err2; + currentvalpos = 0; + memcpy(val + currentvalpos, (unsigned char *)label, llen); + currentvalpos += llen; + memcpy(val + currentvalpos, s->s3->client_random, SSL3_RANDOM_SIZE); + currentvalpos += SSL3_RANDOM_SIZE; + memcpy(val + currentvalpos, s->s3->server_random, SSL3_RANDOM_SIZE); + currentvalpos += SSL3_RANDOM_SIZE; + + if (use_context) { + val[currentvalpos] = (contextlen >> 8) & 0xff; + currentvalpos++; + val[currentvalpos] = contextlen & 0xff; + currentvalpos++; + if ((contextlen > 0) || (context != NULL)) { + memcpy(val + currentvalpos, context, contextlen); + } + } + + /* + * disallow prohibited labels note that SSL3_RANDOM_SIZE > max(prohibited + * label len) = 15, so size of val > max(prohibited label len) = 15 and + * the comparisons won't have buffer overflow + */ + if (memcmp(val, TLS_MD_CLIENT_FINISH_CONST, + TLS_MD_CLIENT_FINISH_CONST_SIZE) == 0) + goto err1; + if (memcmp(val, TLS_MD_SERVER_FINISH_CONST, + TLS_MD_SERVER_FINISH_CONST_SIZE) == 0) + goto err1; + if (memcmp(val, TLS_MD_MASTER_SECRET_CONST, + TLS_MD_MASTER_SECRET_CONST_SIZE) == 0) + goto err1; + if (memcmp(val, TLS_MD_KEY_EXPANSION_CONST, + TLS_MD_KEY_EXPANSION_CONST_SIZE) == 0) + goto err1; + + rv = tls1_PRF(ssl_get_algorithm2(s), + val, vallen, + NULL, 0, + NULL, 0, + NULL, 0, + NULL, 0, + s->session->master_key, s->session->master_key_length, + out, buff, olen); + OPENSSL_cleanse(val, vallen); + OPENSSL_cleanse(buff, olen); + +#ifdef KSSL_DEBUG + fprintf(stderr, "tls1_export_keying_material() complete\n"); +#endif /* KSSL_DEBUG */ + goto ret; + err1: + SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, + SSL_R_TLS_ILLEGAL_EXPORTER_LABEL); + rv = 0; + goto ret; + err2: + SSLerr(SSL_F_TLS1_EXPORT_KEYING_MATERIAL, ERR_R_MALLOC_FAILURE); + rv = 0; + ret: + if (buff != NULL) + OPENSSL_free(buff); + if (val != NULL) + OPENSSL_free(val); + return (rv); +} + +int tls1_alert_code(int code) +{ + switch (code) { + case SSL_AD_CLOSE_NOTIFY: + return (SSL3_AD_CLOSE_NOTIFY); + case SSL_AD_UNEXPECTED_MESSAGE: + return (SSL3_AD_UNEXPECTED_MESSAGE); + case SSL_AD_BAD_RECORD_MAC: + return (SSL3_AD_BAD_RECORD_MAC); + case SSL_AD_DECRYPTION_FAILED: + return (TLS1_AD_DECRYPTION_FAILED); + case SSL_AD_RECORD_OVERFLOW: + return (TLS1_AD_RECORD_OVERFLOW); + case SSL_AD_DECOMPRESSION_FAILURE: + return (SSL3_AD_DECOMPRESSION_FAILURE); + case SSL_AD_HANDSHAKE_FAILURE: + return (SSL3_AD_HANDSHAKE_FAILURE); + case SSL_AD_NO_CERTIFICATE: + return (-1); + case SSL_AD_BAD_CERTIFICATE: + return (SSL3_AD_BAD_CERTIFICATE); + case SSL_AD_UNSUPPORTED_CERTIFICATE: + return (SSL3_AD_UNSUPPORTED_CERTIFICATE); + case SSL_AD_CERTIFICATE_REVOKED: + return (SSL3_AD_CERTIFICATE_REVOKED); + case SSL_AD_CERTIFICATE_EXPIRED: + return (SSL3_AD_CERTIFICATE_EXPIRED); + case SSL_AD_CERTIFICATE_UNKNOWN: + return (SSL3_AD_CERTIFICATE_UNKNOWN); + case SSL_AD_ILLEGAL_PARAMETER: + return (SSL3_AD_ILLEGAL_PARAMETER); + case SSL_AD_UNKNOWN_CA: + return (TLS1_AD_UNKNOWN_CA); + case SSL_AD_ACCESS_DENIED: + return (TLS1_AD_ACCESS_DENIED); + case SSL_AD_DECODE_ERROR: + return (TLS1_AD_DECODE_ERROR); + case SSL_AD_DECRYPT_ERROR: + return (TLS1_AD_DECRYPT_ERROR); + case SSL_AD_EXPORT_RESTRICTION: + return (TLS1_AD_EXPORT_RESTRICTION); + case SSL_AD_PROTOCOL_VERSION: + return (TLS1_AD_PROTOCOL_VERSION); + case SSL_AD_INSUFFICIENT_SECURITY: + return (TLS1_AD_INSUFFICIENT_SECURITY); + case SSL_AD_INTERNAL_ERROR: + return (TLS1_AD_INTERNAL_ERROR); + case SSL_AD_USER_CANCELLED: + return (TLS1_AD_USER_CANCELLED); + case SSL_AD_NO_RENEGOTIATION: + return (TLS1_AD_NO_RENEGOTIATION); + case SSL_AD_UNSUPPORTED_EXTENSION: + return (TLS1_AD_UNSUPPORTED_EXTENSION); + case SSL_AD_CERTIFICATE_UNOBTAINABLE: + return (TLS1_AD_CERTIFICATE_UNOBTAINABLE); + case SSL_AD_UNRECOGNIZED_NAME: + return (TLS1_AD_UNRECOGNIZED_NAME); + case SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + return (TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE); + case SSL_AD_BAD_CERTIFICATE_HASH_VALUE: + return (TLS1_AD_BAD_CERTIFICATE_HASH_VALUE); + case SSL_AD_UNKNOWN_PSK_IDENTITY: + return (TLS1_AD_UNKNOWN_PSK_IDENTITY); + case SSL_AD_INAPPROPRIATE_FALLBACK: + return (TLS1_AD_INAPPROPRIATE_FALLBACK); +#if 0 + /* not appropriate for TLS, not used for DTLS */ + case DTLS1_AD_MISSING_HANDSHAKE_MESSAGE: + return (DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); +#endif + default: + return (-1); + } +} diff --git a/libs/openssl/ssl/t1_lib.c b/libs/openssl/ssl/t1_lib.c new file mode 100644 index 00000000..0bdb77d4 --- /dev/null +++ b/libs/openssl/ssl/t1_lib.c @@ -0,0 +1,2706 @@ +/* ssl/t1_lib.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2007 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include +#include +#include +#include +#include +#include "ssl_locl.h" + +const char tls1_version_str[] = "TLSv1" OPENSSL_VERSION_PTEXT; + +#ifndef OPENSSL_NO_TLSEXT +static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, + const unsigned char *sess_id, int sesslen, + SSL_SESSION **psess); +#endif + +SSL3_ENC_METHOD TLSv1_enc_data = { + tls1_enc, + tls1_mac, + tls1_setup_key_block, + tls1_generate_master_secret, + tls1_change_cipher_state, + tls1_final_finish_mac, + TLS1_FINISH_MAC_LENGTH, + tls1_cert_verify_mac, + TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, + TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, + tls1_alert_code, + tls1_export_keying_material, +}; + +long tls1_default_timeout(void) +{ + /* + * 2 hours, the 24 hours mentioned in the TLSv1 spec is way too long for + * http, the cache would over fill + */ + return (60 * 60 * 2); +} + +int tls1_new(SSL *s) +{ + if (!ssl3_new(s)) + return (0); + s->method->ssl_clear(s); + return (1); +} + +void tls1_free(SSL *s) +{ +#ifndef OPENSSL_NO_TLSEXT + if (s->tlsext_session_ticket) { + OPENSSL_free(s->tlsext_session_ticket); + } +#endif /* OPENSSL_NO_TLSEXT */ + ssl3_free(s); +} + +void tls1_clear(SSL *s) +{ + ssl3_clear(s); + s->version = s->method->version; +} + +#ifndef OPENSSL_NO_EC + +static int nid_list[] = { + NID_sect163k1, /* sect163k1 (1) */ + NID_sect163r1, /* sect163r1 (2) */ + NID_sect163r2, /* sect163r2 (3) */ + NID_sect193r1, /* sect193r1 (4) */ + NID_sect193r2, /* sect193r2 (5) */ + NID_sect233k1, /* sect233k1 (6) */ + NID_sect233r1, /* sect233r1 (7) */ + NID_sect239k1, /* sect239k1 (8) */ + NID_sect283k1, /* sect283k1 (9) */ + NID_sect283r1, /* sect283r1 (10) */ + NID_sect409k1, /* sect409k1 (11) */ + NID_sect409r1, /* sect409r1 (12) */ + NID_sect571k1, /* sect571k1 (13) */ + NID_sect571r1, /* sect571r1 (14) */ + NID_secp160k1, /* secp160k1 (15) */ + NID_secp160r1, /* secp160r1 (16) */ + NID_secp160r2, /* secp160r2 (17) */ + NID_secp192k1, /* secp192k1 (18) */ + NID_X9_62_prime192v1, /* secp192r1 (19) */ + NID_secp224k1, /* secp224k1 (20) */ + NID_secp224r1, /* secp224r1 (21) */ + NID_secp256k1, /* secp256k1 (22) */ + NID_X9_62_prime256v1, /* secp256r1 (23) */ + NID_secp384r1, /* secp384r1 (24) */ + NID_secp521r1 /* secp521r1 (25) */ +}; + +static int pref_list[] = { +# ifndef OPENSSL_NO_EC2M + NID_sect571r1, /* sect571r1 (14) */ + NID_sect571k1, /* sect571k1 (13) */ +# endif + NID_secp521r1, /* secp521r1 (25) */ +# ifndef OPENSSL_NO_EC2M + NID_sect409k1, /* sect409k1 (11) */ + NID_sect409r1, /* sect409r1 (12) */ +# endif + NID_secp384r1, /* secp384r1 (24) */ +# ifndef OPENSSL_NO_EC2M + NID_sect283k1, /* sect283k1 (9) */ + NID_sect283r1, /* sect283r1 (10) */ +# endif + NID_secp256k1, /* secp256k1 (22) */ + NID_X9_62_prime256v1, /* secp256r1 (23) */ +# ifndef OPENSSL_NO_EC2M + NID_sect239k1, /* sect239k1 (8) */ + NID_sect233k1, /* sect233k1 (6) */ + NID_sect233r1, /* sect233r1 (7) */ +# endif + NID_secp224k1, /* secp224k1 (20) */ + NID_secp224r1, /* secp224r1 (21) */ +# ifndef OPENSSL_NO_EC2M + NID_sect193r1, /* sect193r1 (4) */ + NID_sect193r2, /* sect193r2 (5) */ +# endif + NID_secp192k1, /* secp192k1 (18) */ + NID_X9_62_prime192v1, /* secp192r1 (19) */ +# ifndef OPENSSL_NO_EC2M + NID_sect163k1, /* sect163k1 (1) */ + NID_sect163r1, /* sect163r1 (2) */ + NID_sect163r2, /* sect163r2 (3) */ +# endif + NID_secp160k1, /* secp160k1 (15) */ + NID_secp160r1, /* secp160r1 (16) */ + NID_secp160r2, /* secp160r2 (17) */ +}; + +int tls1_ec_curve_id2nid(int curve_id) +{ + /* ECC curves from RFC 4492 */ + if ((curve_id < 1) || ((unsigned int)curve_id > + sizeof(nid_list) / sizeof(nid_list[0]))) + return 0; + return nid_list[curve_id - 1]; +} + +int tls1_ec_nid2curve_id(int nid) +{ + /* ECC curves from RFC 4492 */ + switch (nid) { + case NID_sect163k1: /* sect163k1 (1) */ + return 1; + case NID_sect163r1: /* sect163r1 (2) */ + return 2; + case NID_sect163r2: /* sect163r2 (3) */ + return 3; + case NID_sect193r1: /* sect193r1 (4) */ + return 4; + case NID_sect193r2: /* sect193r2 (5) */ + return 5; + case NID_sect233k1: /* sect233k1 (6) */ + return 6; + case NID_sect233r1: /* sect233r1 (7) */ + return 7; + case NID_sect239k1: /* sect239k1 (8) */ + return 8; + case NID_sect283k1: /* sect283k1 (9) */ + return 9; + case NID_sect283r1: /* sect283r1 (10) */ + return 10; + case NID_sect409k1: /* sect409k1 (11) */ + return 11; + case NID_sect409r1: /* sect409r1 (12) */ + return 12; + case NID_sect571k1: /* sect571k1 (13) */ + return 13; + case NID_sect571r1: /* sect571r1 (14) */ + return 14; + case NID_secp160k1: /* secp160k1 (15) */ + return 15; + case NID_secp160r1: /* secp160r1 (16) */ + return 16; + case NID_secp160r2: /* secp160r2 (17) */ + return 17; + case NID_secp192k1: /* secp192k1 (18) */ + return 18; + case NID_X9_62_prime192v1: /* secp192r1 (19) */ + return 19; + case NID_secp224k1: /* secp224k1 (20) */ + return 20; + case NID_secp224r1: /* secp224r1 (21) */ + return 21; + case NID_secp256k1: /* secp256k1 (22) */ + return 22; + case NID_X9_62_prime256v1: /* secp256r1 (23) */ + return 23; + case NID_secp384r1: /* secp384r1 (24) */ + return 24; + case NID_secp521r1: /* secp521r1 (25) */ + return 25; + default: + return 0; + } +} +#endif /* OPENSSL_NO_EC */ + +#ifndef OPENSSL_NO_TLSEXT + +/* + * List of supported signature algorithms and hashes. Should make this + * customisable at some point, for now include everything we support. + */ + +# ifdef OPENSSL_NO_RSA +# define tlsext_sigalg_rsa(md) /* */ +# else +# define tlsext_sigalg_rsa(md) md, TLSEXT_signature_rsa, +# endif + +# ifdef OPENSSL_NO_DSA +# define tlsext_sigalg_dsa(md) /* */ +# else +# define tlsext_sigalg_dsa(md) md, TLSEXT_signature_dsa, +# endif + +# ifdef OPENSSL_NO_ECDSA +# define tlsext_sigalg_ecdsa(md) + /* */ +# else +# define tlsext_sigalg_ecdsa(md) md, TLSEXT_signature_ecdsa, +# endif + +# define tlsext_sigalg(md) \ + tlsext_sigalg_rsa(md) \ + tlsext_sigalg_dsa(md) \ + tlsext_sigalg_ecdsa(md) + +static unsigned char tls12_sigalgs[] = { +# ifndef OPENSSL_NO_SHA512 + tlsext_sigalg(TLSEXT_hash_sha512) + tlsext_sigalg(TLSEXT_hash_sha384) +# endif +# ifndef OPENSSL_NO_SHA256 + tlsext_sigalg(TLSEXT_hash_sha256) + tlsext_sigalg(TLSEXT_hash_sha224) +# endif +# ifndef OPENSSL_NO_SHA + tlsext_sigalg(TLSEXT_hash_sha1) +# endif +}; + +int tls12_get_req_sig_algs(SSL *s, unsigned char *p) +{ + size_t slen = sizeof(tls12_sigalgs); + if (p) + memcpy(p, tls12_sigalgs, slen); + return (int)slen; +} + +unsigned char *ssl_add_clienthello_tlsext(SSL *s, unsigned char *buf, + unsigned char *limit) +{ + int extdatalen = 0; + unsigned char *orig = buf; + unsigned char *ret = buf; + + /* don't add extensions for SSLv3 unless doing secure renegotiation */ + if (s->client_version == SSL3_VERSION && !s->s3->send_connection_binding) + return orig; + + ret += 2; + + if (ret >= limit) + return NULL; /* this really never occurs, but ... */ + + if (s->tlsext_hostname != NULL) { + /* Add TLS extension servername to the Client Hello message */ + unsigned long size_str; + long lenmax; + + /*- + * check for enough space. + * 4 for the servername type and entension length + * 2 for servernamelist length + * 1 for the hostname type + * 2 for hostname length + * + hostname length + */ + + if ((lenmax = limit - ret - 9) < 0 + || (size_str = + strlen(s->tlsext_hostname)) > (unsigned long)lenmax) + return NULL; + + /* extension type and length */ + s2n(TLSEXT_TYPE_server_name, ret); + s2n(size_str + 5, ret); + + /* length of servername list */ + s2n(size_str + 3, ret); + + /* hostname type, length and hostname */ + *(ret++) = (unsigned char)TLSEXT_NAMETYPE_host_name; + s2n(size_str, ret); + memcpy(ret, s->tlsext_hostname, size_str); + ret += size_str; + } + + /* Add RI if renegotiating */ + if (s->renegotiate) { + int el; + + if (!ssl_add_clienthello_renegotiate_ext(s, 0, &el, 0)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + if ((limit - ret - 4 - el) < 0) + return NULL; + + s2n(TLSEXT_TYPE_renegotiate, ret); + s2n(el, ret); + + if (!ssl_add_clienthello_renegotiate_ext(s, ret, &el, el)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + ret += el; + } +# ifndef OPENSSL_NO_SRP + /* Add SRP username if there is one */ + if (s->srp_ctx.login != NULL) { /* Add TLS extension SRP username to the + * Client Hello message */ + + int login_len = strlen(s->srp_ctx.login); + if (login_len > 255 || login_len == 0) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + /*- + * check for enough space. + * 4 for the srp type type and entension length + * 1 for the srp user identity + * + srp user identity length + */ + if ((limit - ret - 5 - login_len) < 0) + return NULL; + + /* fill in the extension */ + s2n(TLSEXT_TYPE_srp, ret); + s2n(login_len + 1, ret); + (*ret++) = (unsigned char)login_len; + memcpy(ret, s->srp_ctx.login, login_len); + ret += login_len; + } +# endif + +# ifndef OPENSSL_NO_EC + if (s->tlsext_ecpointformatlist != NULL) { + /* + * Add TLS extension ECPointFormats to the ClientHello message + */ + long lenmax; + + if ((lenmax = limit - ret - 5) < 0) + return NULL; + if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) + return NULL; + if (s->tlsext_ecpointformatlist_length > 255) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + s2n(TLSEXT_TYPE_ec_point_formats, ret); + s2n(s->tlsext_ecpointformatlist_length + 1, ret); + *(ret++) = (unsigned char)s->tlsext_ecpointformatlist_length; + memcpy(ret, s->tlsext_ecpointformatlist, + s->tlsext_ecpointformatlist_length); + ret += s->tlsext_ecpointformatlist_length; + } + if (s->tlsext_ellipticcurvelist != NULL) { + /* + * Add TLS extension EllipticCurves to the ClientHello message + */ + long lenmax; + + if ((lenmax = limit - ret - 6) < 0) + return NULL; + if (s->tlsext_ellipticcurvelist_length > (unsigned long)lenmax) + return NULL; + if (s->tlsext_ellipticcurvelist_length > 65532) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + s2n(TLSEXT_TYPE_elliptic_curves, ret); + s2n(s->tlsext_ellipticcurvelist_length + 2, ret); + + s2n(s->tlsext_ellipticcurvelist_length, ret); + memcpy(ret, s->tlsext_ellipticcurvelist, + s->tlsext_ellipticcurvelist_length); + ret += s->tlsext_ellipticcurvelist_length; + } +# endif /* OPENSSL_NO_EC */ + + if (!(SSL_get_options(s) & SSL_OP_NO_TICKET)) { + int ticklen; + if (!s->new_session && s->session && s->session->tlsext_tick) + ticklen = s->session->tlsext_ticklen; + else if (s->session && s->tlsext_session_ticket && + s->tlsext_session_ticket->data) { + ticklen = s->tlsext_session_ticket->length; + s->session->tlsext_tick = OPENSSL_malloc(ticklen); + if (!s->session->tlsext_tick) + return NULL; + memcpy(s->session->tlsext_tick, + s->tlsext_session_ticket->data, ticklen); + s->session->tlsext_ticklen = ticklen; + } else + ticklen = 0; + if (ticklen == 0 && s->tlsext_session_ticket && + s->tlsext_session_ticket->data == NULL) + goto skip_ext; + /* + * Check for enough room 2 for extension type, 2 for len rest for + * ticket + */ + if ((long)(limit - ret - 4 - ticklen) < 0) + return NULL; + s2n(TLSEXT_TYPE_session_ticket, ret); + s2n(ticklen, ret); + if (ticklen) { + memcpy(ret, s->session->tlsext_tick, ticklen); + ret += ticklen; + } + } + skip_ext: + + if (TLS1_get_client_version(s) >= TLS1_2_VERSION) { + if ((size_t)(limit - ret) < sizeof(tls12_sigalgs) + 6) + return NULL; + s2n(TLSEXT_TYPE_signature_algorithms, ret); + s2n(sizeof(tls12_sigalgs) + 2, ret); + s2n(sizeof(tls12_sigalgs), ret); + memcpy(ret, tls12_sigalgs, sizeof(tls12_sigalgs)); + ret += sizeof(tls12_sigalgs); + } +# ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->client_opaque_prf_input != NULL && s->version != DTLS1_VERSION) { + size_t col = s->s3->client_opaque_prf_input_len; + + if ((long)(limit - ret - 6 - col < 0)) + return NULL; + if (col > 0xFFFD) /* can't happen */ + return NULL; + + s2n(TLSEXT_TYPE_opaque_prf_input, ret); + s2n(col + 2, ret); + s2n(col, ret); + memcpy(ret, s->s3->client_opaque_prf_input, col); + ret += col; + } +# endif + + if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp && + s->version != DTLS1_VERSION) { + int i; + long extlen, idlen, itmp; + OCSP_RESPID *id; + + idlen = 0; + for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { + id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); + itmp = i2d_OCSP_RESPID(id, NULL); + if (itmp <= 0) + return NULL; + idlen += itmp + 2; + } + + if (s->tlsext_ocsp_exts) { + extlen = i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, NULL); + if (extlen < 0) + return NULL; + } else + extlen = 0; + + if ((long)(limit - ret - 7 - extlen - idlen) < 0) + return NULL; + s2n(TLSEXT_TYPE_status_request, ret); + if (extlen + idlen > 0xFFF0) + return NULL; + s2n(extlen + idlen + 5, ret); + *(ret++) = TLSEXT_STATUSTYPE_ocsp; + s2n(idlen, ret); + for (i = 0; i < sk_OCSP_RESPID_num(s->tlsext_ocsp_ids); i++) { + /* save position of id len */ + unsigned char *q = ret; + id = sk_OCSP_RESPID_value(s->tlsext_ocsp_ids, i); + /* skip over id len */ + ret += 2; + itmp = i2d_OCSP_RESPID(id, &ret); + /* write id len */ + s2n(itmp, q); + } + s2n(extlen, ret); + if (extlen > 0) + i2d_X509_EXTENSIONS(s->tlsext_ocsp_exts, &ret); + } +# ifndef OPENSSL_NO_HEARTBEATS + /* Add Heartbeat extension */ + if ((limit - ret - 4 - 1) < 0) + return NULL; + s2n(TLSEXT_TYPE_heartbeat, ret); + s2n(1, ret); + /*- + * Set mode: + * 1: peer may send requests + * 2: peer not allowed to send requests + */ + if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS) + *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS; + else + *(ret++) = SSL_TLSEXT_HB_ENABLED; +# endif + +# ifndef OPENSSL_NO_NEXTPROTONEG + if (s->ctx->next_proto_select_cb && !s->s3->tmp.finish_md_len) { + /* + * The client advertises an emtpy extension to indicate its support + * for Next Protocol Negotiation + */ + if (limit - ret - 4 < 0) + return NULL; + s2n(TLSEXT_TYPE_next_proto_neg, ret); + s2n(0, ret); + } +# endif + +# ifndef OPENSSL_NO_SRTP + if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s)) { + int el; + + ssl_add_clienthello_use_srtp_ext(s, 0, &el, 0); + + if ((limit - ret - 4 - el) < 0) + return NULL; + + s2n(TLSEXT_TYPE_use_srtp, ret); + s2n(el, ret); + + if (ssl_add_clienthello_use_srtp_ext(s, ret, &el, el)) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + ret += el; + } +# endif + /* + * Add padding to workaround bugs in F5 terminators. See + * https://tools.ietf.org/html/draft-agl-tls-padding-03 NB: because this + * code works out the length of all existing extensions it MUST always + * appear last. + */ + if (s->options & SSL_OP_TLSEXT_PADDING) { + int hlen = ret - (unsigned char *)s->init_buf->data; + /* + * The code in s23_clnt.c to build ClientHello messages includes the + * 5-byte record header in the buffer, while the code in s3_clnt.c + * does not. + */ + if (s->state == SSL23_ST_CW_CLNT_HELLO_A) + hlen -= 5; + if (hlen > 0xff && hlen < 0x200) { + hlen = 0x200 - hlen; + if (hlen >= 4) + hlen -= 4; + else + hlen = 0; + + s2n(TLSEXT_TYPE_padding, ret); + s2n(hlen, ret); + memset(ret, 0, hlen); + ret += hlen; + } + } + + if ((extdatalen = ret - orig - 2) == 0) + return orig; + + s2n(extdatalen, orig); + return ret; +} + +unsigned char *ssl_add_serverhello_tlsext(SSL *s, unsigned char *buf, + unsigned char *limit) +{ + int extdatalen = 0; + unsigned char *orig = buf; + unsigned char *ret = buf; +# ifndef OPENSSL_NO_NEXTPROTONEG + int next_proto_neg_seen; +# endif + + /* + * don't add extensions for SSLv3, unless doing secure renegotiation + */ + if (s->version == SSL3_VERSION && !s->s3->send_connection_binding) + return orig; + + ret += 2; + if (ret >= limit) + return NULL; /* this really never occurs, but ... */ + + if (!s->hit && s->servername_done == 1 + && s->session->tlsext_hostname != NULL) { + if ((long)(limit - ret - 4) < 0) + return NULL; + + s2n(TLSEXT_TYPE_server_name, ret); + s2n(0, ret); + } + + if (s->s3->send_connection_binding) { + int el; + + if (!ssl_add_serverhello_renegotiate_ext(s, 0, &el, 0)) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + if ((limit - ret - 4 - el) < 0) + return NULL; + + s2n(TLSEXT_TYPE_renegotiate, ret); + s2n(el, ret); + + if (!ssl_add_serverhello_renegotiate_ext(s, ret, &el, el)) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + ret += el; + } +# ifndef OPENSSL_NO_EC + if (s->tlsext_ecpointformatlist != NULL) { + /* + * Add TLS extension ECPointFormats to the ServerHello message + */ + long lenmax; + + if ((lenmax = limit - ret - 5) < 0) + return NULL; + if (s->tlsext_ecpointformatlist_length > (unsigned long)lenmax) + return NULL; + if (s->tlsext_ecpointformatlist_length > 255) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + + s2n(TLSEXT_TYPE_ec_point_formats, ret); + s2n(s->tlsext_ecpointformatlist_length + 1, ret); + *(ret++) = (unsigned char)s->tlsext_ecpointformatlist_length; + memcpy(ret, s->tlsext_ecpointformatlist, + s->tlsext_ecpointformatlist_length); + ret += s->tlsext_ecpointformatlist_length; + + } + /* + * Currently the server should not respond with a SupportedCurves + * extension + */ +# endif /* OPENSSL_NO_EC */ + + if (s->tlsext_ticket_expected && !(SSL_get_options(s) & SSL_OP_NO_TICKET)) { + if ((long)(limit - ret - 4) < 0) + return NULL; + s2n(TLSEXT_TYPE_session_ticket, ret); + s2n(0, ret); + } + + if (s->tlsext_status_expected) { + if ((long)(limit - ret - 4) < 0) + return NULL; + s2n(TLSEXT_TYPE_status_request, ret); + s2n(0, ret); + } +# ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->server_opaque_prf_input != NULL && s->version != DTLS1_VERSION) { + size_t sol = s->s3->server_opaque_prf_input_len; + + if ((long)(limit - ret - 6 - sol) < 0) + return NULL; + if (sol > 0xFFFD) /* can't happen */ + return NULL; + + s2n(TLSEXT_TYPE_opaque_prf_input, ret); + s2n(sol + 2, ret); + s2n(sol, ret); + memcpy(ret, s->s3->server_opaque_prf_input, sol); + ret += sol; + } +# endif + +# ifndef OPENSSL_NO_SRTP + if (SSL_IS_DTLS(s) && s->srtp_profile) { + int el; + + ssl_add_serverhello_use_srtp_ext(s, 0, &el, 0); + + if ((limit - ret - 4 - el) < 0) + return NULL; + + s2n(TLSEXT_TYPE_use_srtp, ret); + s2n(el, ret); + + if (ssl_add_serverhello_use_srtp_ext(s, ret, &el, el)) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_TLSEXT, ERR_R_INTERNAL_ERROR); + return NULL; + } + ret += el; + } +# endif + + if (((s->s3->tmp.new_cipher->id & 0xFFFF) == 0x80 + || (s->s3->tmp.new_cipher->id & 0xFFFF) == 0x81) + && (SSL_get_options(s) & SSL_OP_CRYPTOPRO_TLSEXT_BUG)) { + const unsigned char cryptopro_ext[36] = { + 0xfd, 0xe8, /* 65000 */ + 0x00, 0x20, /* 32 bytes length */ + 0x30, 0x1e, 0x30, 0x08, 0x06, 0x06, 0x2a, 0x85, + 0x03, 0x02, 0x02, 0x09, 0x30, 0x08, 0x06, 0x06, + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, 0x30, 0x08, + 0x06, 0x06, 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17 + }; + if (limit - ret < 36) + return NULL; + memcpy(ret, cryptopro_ext, 36); + ret += 36; + + } +# ifndef OPENSSL_NO_HEARTBEATS + /* Add Heartbeat extension if we've received one */ + if (s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) { + if ((limit - ret - 4 - 1) < 0) + return NULL; + s2n(TLSEXT_TYPE_heartbeat, ret); + s2n(1, ret); + /*- + * Set mode: + * 1: peer may send requests + * 2: peer not allowed to send requests + */ + if (s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_RECV_REQUESTS) + *(ret++) = SSL_TLSEXT_HB_DONT_SEND_REQUESTS; + else + *(ret++) = SSL_TLSEXT_HB_ENABLED; + + } +# endif + +# ifndef OPENSSL_NO_NEXTPROTONEG + next_proto_neg_seen = s->s3->next_proto_neg_seen; + s->s3->next_proto_neg_seen = 0; + if (next_proto_neg_seen && s->ctx->next_protos_advertised_cb) { + const unsigned char *npa; + unsigned int npalen; + int r; + + r = s->ctx->next_protos_advertised_cb(s, &npa, &npalen, + s-> + ctx->next_protos_advertised_cb_arg); + if (r == SSL_TLSEXT_ERR_OK) { + if ((long)(limit - ret - 4 - npalen) < 0) + return NULL; + s2n(TLSEXT_TYPE_next_proto_neg, ret); + s2n(npalen, ret); + memcpy(ret, npa, npalen); + ret += npalen; + s->s3->next_proto_neg_seen = 1; + } + } +# endif + + if ((extdatalen = ret - orig - 2) == 0) + return orig; + + s2n(extdatalen, orig); + return ret; +} + +# ifndef OPENSSL_NO_EC +/*- + * ssl_check_for_safari attempts to fingerprint Safari using OS X + * SecureTransport using the TLS extension block in |d|, of length |n|. + * Safari, since 10.6, sends exactly these extensions, in this order: + * SNI, + * elliptic_curves + * ec_point_formats + * + * We wish to fingerprint Safari because they broke ECDHE-ECDSA support in 10.8, + * but they advertise support. So enabling ECDHE-ECDSA ciphers breaks them. + * Sadly we cannot differentiate 10.6, 10.7 and 10.8.4 (which work), from + * 10.8..10.8.3 (which don't work). + */ +static void ssl_check_for_safari(SSL *s, const unsigned char *data, + const unsigned char *limit) +{ + unsigned short type, size; + static const unsigned char kSafariExtensionsBlock[] = { + 0x00, 0x0a, /* elliptic_curves extension */ + 0x00, 0x08, /* 8 bytes */ + 0x00, 0x06, /* 6 bytes of curve ids */ + 0x00, 0x17, /* P-256 */ + 0x00, 0x18, /* P-384 */ + 0x00, 0x19, /* P-521 */ + + 0x00, 0x0b, /* ec_point_formats */ + 0x00, 0x02, /* 2 bytes */ + 0x01, /* 1 point format */ + 0x00, /* uncompressed */ + }; + + /* The following is only present in TLS 1.2 */ + static const unsigned char kSafariTLS12ExtensionsBlock[] = { + 0x00, 0x0d, /* signature_algorithms */ + 0x00, 0x0c, /* 12 bytes */ + 0x00, 0x0a, /* 10 bytes */ + 0x05, 0x01, /* SHA-384/RSA */ + 0x04, 0x01, /* SHA-256/RSA */ + 0x02, 0x01, /* SHA-1/RSA */ + 0x04, 0x03, /* SHA-256/ECDSA */ + 0x02, 0x03, /* SHA-1/ECDSA */ + }; + + if (data >= (limit - 2)) + return; + data += 2; + + if (data > (limit - 4)) + return; + n2s(data, type); + n2s(data, size); + + if (type != TLSEXT_TYPE_server_name) + return; + + if (data + size > limit) + return; + data += size; + + if (TLS1_get_client_version(s) >= TLS1_2_VERSION) { + const size_t len1 = sizeof(kSafariExtensionsBlock); + const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock); + + if (data + len1 + len2 != limit) + return; + if (memcmp(data, kSafariExtensionsBlock, len1) != 0) + return; + if (memcmp(data + len1, kSafariTLS12ExtensionsBlock, len2) != 0) + return; + } else { + const size_t len = sizeof(kSafariExtensionsBlock); + + if (data + len != limit) + return; + if (memcmp(data, kSafariExtensionsBlock, len) != 0) + return; + } + + s->s3->is_probably_safari = 1; +} +# endif /* !OPENSSL_NO_EC */ + +int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, + unsigned char *limit, int *al) +{ + unsigned short type; + unsigned short size; + unsigned short len; + unsigned char *data = *p; + int renegotiate_seen = 0; + int sigalg_seen = 0; + + s->servername_done = 0; + s->tlsext_status_type = -1; +# ifndef OPENSSL_NO_NEXTPROTONEG + s->s3->next_proto_neg_seen = 0; +# endif + +# ifndef OPENSSL_NO_HEARTBEATS + s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED | + SSL_TLSEXT_HB_DONT_SEND_REQUESTS); +# endif + +# ifndef OPENSSL_NO_EC + if (s->options & SSL_OP_SAFARI_ECDHE_ECDSA_BUG) + ssl_check_for_safari(s, data, limit); +# endif /* !OPENSSL_NO_EC */ + +# ifndef OPENSSL_NO_SRP + if (s->srp_ctx.login != NULL) { + OPENSSL_free(s->srp_ctx.login); + s->srp_ctx.login = NULL; + } +# endif + + s->srtp_profile = NULL; + + if (data == limit) + goto ri_check; + + if (data > (limit - 2)) + goto err; + + n2s(data, len); + + if (data + len != limit) + goto err; + + while (data <= (limit - 4)) { + n2s(data, type); + n2s(data, size); + + if (data + size > (limit)) + goto err; +# if 0 + fprintf(stderr, "Received extension type %d size %d\n", type, size); +# endif + if (s->tlsext_debug_cb) + s->tlsext_debug_cb(s, 0, type, data, size, s->tlsext_debug_arg); +/*- + * The servername extension is treated as follows: + * + * - Only the hostname type is supported with a maximum length of 255. + * - The servername is rejected if too long or if it contains zeros, + * in which case an fatal alert is generated. + * - The servername field is maintained together with the session cache. + * - When a session is resumed, the servername call back invoked in order + * to allow the application to position itself to the right context. + * - The servername is acknowledged if it is new for a session or when + * it is identical to a previously used for the same session. + * Applications can control the behaviour. They can at any time + * set a 'desirable' servername for a new SSL object. This can be the + * case for example with HTTPS when a Host: header field is received and + * a renegotiation is requested. In this case, a possible servername + * presented in the new client hello is only acknowledged if it matches + * the value of the Host: field. + * - Applications must use SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION + * if they provide for changing an explicit servername context for the + * session, i.e. when the session has been established with a servername + * extension. + * - On session reconnect, the servername extension may be absent. + * + */ + + if (type == TLSEXT_TYPE_server_name) { + unsigned char *sdata; + int servname_type; + int dsize; + + if (size < 2) + goto err; + n2s(data, dsize); + size -= 2; + if (dsize > size) + goto err; + + sdata = data; + while (dsize > 3) { + servname_type = *(sdata++); + n2s(sdata, len); + dsize -= 3; + + if (len > dsize) + goto err; + + if (s->servername_done == 0) + switch (servname_type) { + case TLSEXT_NAMETYPE_host_name: + if (!s->hit) { + if (s->session->tlsext_hostname) + goto err; + + if (len > TLSEXT_MAXLEN_host_name) { + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } + if ((s->session->tlsext_hostname = + OPENSSL_malloc(len + 1)) == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + memcpy(s->session->tlsext_hostname, sdata, len); + s->session->tlsext_hostname[len] = '\0'; + if (strlen(s->session->tlsext_hostname) != len) { + OPENSSL_free(s->session->tlsext_hostname); + s->session->tlsext_hostname = NULL; + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } + s->servername_done = 1; + + } else + s->servername_done = s->session->tlsext_hostname + && strlen(s->session->tlsext_hostname) == len + && strncmp(s->session->tlsext_hostname, + (char *)sdata, len) == 0; + + break; + + default: + break; + } + + dsize -= len; + } + if (dsize != 0) + goto err; + + } +# ifndef OPENSSL_NO_SRP + else if (type == TLSEXT_TYPE_srp) { + if (size == 0 || ((len = data[0])) != (size - 1)) + goto err; + if (s->srp_ctx.login != NULL) + goto err; + if ((s->srp_ctx.login = OPENSSL_malloc(len + 1)) == NULL) + return -1; + memcpy(s->srp_ctx.login, &data[1], len); + s->srp_ctx.login[len] = '\0'; + + if (strlen(s->srp_ctx.login) != len) + goto err; + } +# endif + +# ifndef OPENSSL_NO_EC + else if (type == TLSEXT_TYPE_ec_point_formats) { + unsigned char *sdata = data; + int ecpointformatlist_length = *(sdata++); + + if (ecpointformatlist_length != size - 1) + goto err; + if (!s->hit) { + if (s->session->tlsext_ecpointformatlist) { + OPENSSL_free(s->session->tlsext_ecpointformatlist); + s->session->tlsext_ecpointformatlist = NULL; + } + s->session->tlsext_ecpointformatlist_length = 0; + if ((s->session->tlsext_ecpointformatlist = + OPENSSL_malloc(ecpointformatlist_length)) == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->session->tlsext_ecpointformatlist_length = + ecpointformatlist_length; + memcpy(s->session->tlsext_ecpointformatlist, sdata, + ecpointformatlist_length); + } +# if 0 + fprintf(stderr, + "ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", + s->session->tlsext_ecpointformatlist_length); + sdata = s->session->tlsext_ecpointformatlist; + for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) + fprintf(stderr, "%i ", *(sdata++)); + fprintf(stderr, "\n"); +# endif + } else if (type == TLSEXT_TYPE_elliptic_curves) { + unsigned char *sdata = data; + int ellipticcurvelist_length = (*(sdata++) << 8); + ellipticcurvelist_length += (*(sdata++)); + + if (ellipticcurvelist_length != size - 2 || + ellipticcurvelist_length < 1 || + /* Each NamedCurve is 2 bytes. */ + ellipticcurvelist_length & 1) + goto err; + + if (!s->hit) { + if (s->session->tlsext_ellipticcurvelist) + goto err; + + s->session->tlsext_ellipticcurvelist_length = 0; + if ((s->session->tlsext_ellipticcurvelist = + OPENSSL_malloc(ellipticcurvelist_length)) == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->session->tlsext_ellipticcurvelist_length = + ellipticcurvelist_length; + memcpy(s->session->tlsext_ellipticcurvelist, sdata, + ellipticcurvelist_length); + } +# if 0 + fprintf(stderr, + "ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", + s->session->tlsext_ellipticcurvelist_length); + sdata = s->session->tlsext_ellipticcurvelist; + for (i = 0; i < s->session->tlsext_ellipticcurvelist_length; i++) + fprintf(stderr, "%i ", *(sdata++)); + fprintf(stderr, "\n"); +# endif + } +# endif /* OPENSSL_NO_EC */ +# ifdef TLSEXT_TYPE_opaque_prf_input + else if (type == TLSEXT_TYPE_opaque_prf_input && + s->version != DTLS1_VERSION) { + unsigned char *sdata = data; + + if (size < 2) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + n2s(sdata, s->s3->client_opaque_prf_input_len); + if (s->s3->client_opaque_prf_input_len != size - 2) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + if (s->s3->client_opaque_prf_input != NULL) { + /* shouldn't really happen */ + OPENSSL_free(s->s3->client_opaque_prf_input); + } + + /* dummy byte just to get non-NULL */ + if (s->s3->client_opaque_prf_input_len == 0) + s->s3->client_opaque_prf_input = OPENSSL_malloc(1); + else + s->s3->client_opaque_prf_input = + BUF_memdup(sdata, s->s3->client_opaque_prf_input_len); + if (s->s3->client_opaque_prf_input == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + } +# endif + else if (type == TLSEXT_TYPE_session_ticket) { + if (s->tls_session_ticket_ext_cb && + !s->tls_session_ticket_ext_cb(s, data, size, + s->tls_session_ticket_ext_cb_arg)) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + } else if (type == TLSEXT_TYPE_renegotiate) { + if (!ssl_parse_clienthello_renegotiate_ext(s, data, size, al)) + return 0; + renegotiate_seen = 1; + } else if (type == TLSEXT_TYPE_signature_algorithms) { + int dsize; + if (sigalg_seen || size < 2) + goto err; + sigalg_seen = 1; + n2s(data, dsize); + size -= 2; + if (dsize != size || dsize & 1) + goto err; + if (!tls1_process_sigalgs(s, data, dsize)) + goto err; + } else if (type == TLSEXT_TYPE_status_request && + s->version != DTLS1_VERSION) { + + if (size < 5) + goto err; + + s->tlsext_status_type = *data++; + size--; + if (s->tlsext_status_type == TLSEXT_STATUSTYPE_ocsp) { + const unsigned char *sdata; + int dsize; + /* Read in responder_id_list */ + n2s(data, dsize); + size -= 2; + if (dsize > size) + goto err; + while (dsize > 0) { + OCSP_RESPID *id; + int idsize; + if (dsize < 4) + goto err; + n2s(data, idsize); + dsize -= 2 + idsize; + size -= 2 + idsize; + if (dsize < 0) + goto err; + sdata = data; + data += idsize; + id = d2i_OCSP_RESPID(NULL, &sdata, idsize); + if (!id) + goto err; + if (data != sdata) { + OCSP_RESPID_free(id); + goto err; + } + if (!s->tlsext_ocsp_ids + && !(s->tlsext_ocsp_ids = + sk_OCSP_RESPID_new_null())) { + OCSP_RESPID_free(id); + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + if (!sk_OCSP_RESPID_push(s->tlsext_ocsp_ids, id)) { + OCSP_RESPID_free(id); + *al = SSL_AD_INTERNAL_ERROR; + return 0; + } + } + + /* Read in request_extensions */ + if (size < 2) + goto err; + n2s(data, dsize); + size -= 2; + if (dsize != size) + goto err; + sdata = data; + if (dsize > 0) { + if (s->tlsext_ocsp_exts) { + sk_X509_EXTENSION_pop_free(s->tlsext_ocsp_exts, + X509_EXTENSION_free); + } + + s->tlsext_ocsp_exts = + d2i_X509_EXTENSIONS(NULL, &sdata, dsize); + if (!s->tlsext_ocsp_exts || (data + dsize != sdata)) + goto err; + } + } + /* + * We don't know what to do with any other type * so ignore it. + */ + else + s->tlsext_status_type = -1; + } +# ifndef OPENSSL_NO_HEARTBEATS + else if (type == TLSEXT_TYPE_heartbeat) { + switch (data[0]) { + case 0x01: /* Client allows us to send HB requests */ + s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; + break; + case 0x02: /* Client doesn't accept HB requests */ + s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; + s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS; + break; + default: + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + } +# endif +# ifndef OPENSSL_NO_NEXTPROTONEG + else if (type == TLSEXT_TYPE_next_proto_neg && + s->s3->tmp.finish_md_len == 0) { + /*- + * We shouldn't accept this extension on a + * renegotiation. + * + * s->new_session will be set on renegotiation, but we + * probably shouldn't rely that it couldn't be set on + * the initial renegotation too in certain cases (when + * there's some other reason to disallow resuming an + * earlier session -- the current code won't be doing + * anything like that, but this might change). + * + * A valid sign that there's been a previous handshake + * in this connection is if s->s3->tmp.finish_md_len > + * 0. (We are talking about a check that will happen + * in the Hello protocol round, well before a new + * Finished message could have been computed.) + */ + s->s3->next_proto_neg_seen = 1; + } +# endif + + /* session ticket processed earlier */ +# ifndef OPENSSL_NO_SRTP + else if (SSL_IS_DTLS(s) && SSL_get_srtp_profiles(s) + && type == TLSEXT_TYPE_use_srtp) { + if (ssl_parse_clienthello_use_srtp_ext(s, data, size, al)) + return 0; + } +# endif + + data += size; + } + + /* Spurious data on the end */ + if (data != limit) + goto err; + + *p = data; + + ri_check: + + /* Need RI if renegotiating */ + + if (!renegotiate_seen && s->renegotiate && + !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { + *al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_TLSEXT, + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + return 0; + } + + return 1; +err: + *al = SSL_AD_DECODE_ERROR; + return 0; +} + +# ifndef OPENSSL_NO_NEXTPROTONEG +/* + * ssl_next_proto_validate validates a Next Protocol Negotiation block. No + * elements of zero length are allowed and the set of elements must exactly + * fill the length of the block. + */ +static char ssl_next_proto_validate(unsigned char *d, unsigned len) +{ + unsigned int off = 0; + + while (off < len) { + if (d[off] == 0) + return 0; + off += d[off]; + off++; + } + + return off == len; +} +# endif + +int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, + int n, int *al) +{ + unsigned short length; + unsigned short type; + unsigned short size; + unsigned char *data = *p; + int tlsext_servername = 0; + int renegotiate_seen = 0; + +# ifndef OPENSSL_NO_NEXTPROTONEG + s->s3->next_proto_neg_seen = 0; +# endif + s->tlsext_ticket_expected = 0; + +# ifndef OPENSSL_NO_HEARTBEATS + s->tlsext_heartbeat &= ~(SSL_TLSEXT_HB_ENABLED | + SSL_TLSEXT_HB_DONT_SEND_REQUESTS); +# endif + + if (data >= (d + n - 2)) + goto ri_check; + + n2s(data, length); + if (data + length != d + n) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + while (data <= (d + n - 4)) { + n2s(data, type); + n2s(data, size); + + if (data + size > (d + n)) + goto ri_check; + + if (s->tlsext_debug_cb) + s->tlsext_debug_cb(s, 1, type, data, size, s->tlsext_debug_arg); + + if (type == TLSEXT_TYPE_server_name) { + if (s->tlsext_hostname == NULL || size > 0) { + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } + tlsext_servername = 1; + } +# ifndef OPENSSL_NO_EC + else if (type == TLSEXT_TYPE_ec_point_formats) { + unsigned char *sdata = data; + int ecpointformatlist_length = *(sdata++); + + if (ecpointformatlist_length != size - 1 || + ecpointformatlist_length < 1) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + if (!s->hit) { + s->session->tlsext_ecpointformatlist_length = 0; + if (s->session->tlsext_ecpointformatlist != NULL) + OPENSSL_free(s->session->tlsext_ecpointformatlist); + if ((s->session->tlsext_ecpointformatlist = + OPENSSL_malloc(ecpointformatlist_length)) == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->session->tlsext_ecpointformatlist_length = + ecpointformatlist_length; + memcpy(s->session->tlsext_ecpointformatlist, sdata, + ecpointformatlist_length); + } +# if 0 + fprintf(stderr, + "ssl_parse_serverhello_tlsext s->session->tlsext_ecpointformatlist "); + sdata = s->session->tlsext_ecpointformatlist; + for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) + fprintf(stderr, "%i ", *(sdata++)); + fprintf(stderr, "\n"); +# endif + } +# endif /* OPENSSL_NO_EC */ + + else if (type == TLSEXT_TYPE_session_ticket) { + if (s->tls_session_ticket_ext_cb && + !s->tls_session_ticket_ext_cb(s, data, size, + s->tls_session_ticket_ext_cb_arg)) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + if ((SSL_get_options(s) & SSL_OP_NO_TICKET) + || (size > 0)) { + *al = TLS1_AD_UNSUPPORTED_EXTENSION; + return 0; + } + s->tlsext_ticket_expected = 1; + } +# ifdef TLSEXT_TYPE_opaque_prf_input + else if (type == TLSEXT_TYPE_opaque_prf_input && + s->version != DTLS1_VERSION) { + unsigned char *sdata = data; + + if (size < 2) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + n2s(sdata, s->s3->server_opaque_prf_input_len); + if (s->s3->server_opaque_prf_input_len != size - 2) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + if (s->s3->server_opaque_prf_input != NULL) { + /* shouldn't really happen */ + OPENSSL_free(s->s3->server_opaque_prf_input); + } + if (s->s3->server_opaque_prf_input_len == 0) { + /* dummy byte just to get non-NULL */ + s->s3->server_opaque_prf_input = OPENSSL_malloc(1); + } else { + s->s3->server_opaque_prf_input = + BUF_memdup(sdata, s->s3->server_opaque_prf_input_len); + } + + if (s->s3->server_opaque_prf_input == NULL) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + } +# endif + else if (type == TLSEXT_TYPE_status_request && + s->version != DTLS1_VERSION) { + /* + * MUST be empty and only sent if we've requested a status + * request message. + */ + if ((s->tlsext_status_type == -1) || (size > 0)) { + *al = TLS1_AD_UNSUPPORTED_EXTENSION; + return 0; + } + /* Set flag to expect CertificateStatus message */ + s->tlsext_status_expected = 1; + } +# ifndef OPENSSL_NO_NEXTPROTONEG + else if (type == TLSEXT_TYPE_next_proto_neg && + s->s3->tmp.finish_md_len == 0) { + unsigned char *selected; + unsigned char selected_len; + + /* We must have requested it. */ + if (s->ctx->next_proto_select_cb == NULL) { + *al = TLS1_AD_UNSUPPORTED_EXTENSION; + return 0; + } + /* The data must be valid */ + if (!ssl_next_proto_validate(data, size)) { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + if (s-> + ctx->next_proto_select_cb(s, &selected, &selected_len, data, + size, + s->ctx->next_proto_select_cb_arg) != + SSL_TLSEXT_ERR_OK) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->next_proto_negotiated = OPENSSL_malloc(selected_len); + if (!s->next_proto_negotiated) { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + memcpy(s->next_proto_negotiated, selected, selected_len); + s->next_proto_negotiated_len = selected_len; + s->s3->next_proto_neg_seen = 1; + } +# endif + else if (type == TLSEXT_TYPE_renegotiate) { + if (!ssl_parse_serverhello_renegotiate_ext(s, data, size, al)) + return 0; + renegotiate_seen = 1; + } +# ifndef OPENSSL_NO_HEARTBEATS + else if (type == TLSEXT_TYPE_heartbeat) { + switch (data[0]) { + case 0x01: /* Server allows us to send HB requests */ + s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; + break; + case 0x02: /* Server doesn't accept HB requests */ + s->tlsext_heartbeat |= SSL_TLSEXT_HB_ENABLED; + s->tlsext_heartbeat |= SSL_TLSEXT_HB_DONT_SEND_REQUESTS; + break; + default: + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + } +# endif +# ifndef OPENSSL_NO_SRTP + else if (SSL_IS_DTLS(s) && type == TLSEXT_TYPE_use_srtp) { + if (ssl_parse_serverhello_use_srtp_ext(s, data, size, al)) + return 0; + } +# endif + + data += size; + } + + if (data != d + n) { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + + if (!s->hit && tlsext_servername == 1) { + if (s->tlsext_hostname) { + if (s->session->tlsext_hostname == NULL) { + s->session->tlsext_hostname = BUF_strdup(s->tlsext_hostname); + if (!s->session->tlsext_hostname) { + *al = SSL_AD_UNRECOGNIZED_NAME; + return 0; + } + } else { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + } + } + + *p = data; + + ri_check: + + /* + * Determine if we need to see RI. Strictly speaking if we want to avoid + * an attack we should *always* see RI even on initial server hello + * because the client doesn't see any renegotiation during an attack. + * However this would mean we could not connect to any server which + * doesn't support RI so for the immediate future tolerate RI absence on + * initial connect only. + */ + if (!renegotiate_seen && !(s->options & SSL_OP_LEGACY_SERVER_CONNECT) + && !(s->options & SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION)) { + *al = SSL_AD_HANDSHAKE_FAILURE; + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_TLSEXT, + SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED); + return 0; + } + + return 1; +} + +int ssl_prepare_clienthello_tlsext(SSL *s) +{ +# ifndef OPENSSL_NO_EC + /* + * If we are client and using an elliptic curve cryptography cipher + * suite, send the point formats and elliptic curves we support. + */ + int using_ecc = 0; + int i; + unsigned char *j; + unsigned long alg_k, alg_a; + STACK_OF(SSL_CIPHER) *cipher_stack = SSL_get_ciphers(s); + + for (i = 0; i < sk_SSL_CIPHER_num(cipher_stack); i++) { + SSL_CIPHER *c = sk_SSL_CIPHER_value(cipher_stack, i); + + alg_k = c->algorithm_mkey; + alg_a = c->algorithm_auth; + if ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe) + || (alg_a & SSL_aECDSA))) { + using_ecc = 1; + break; + } + } + using_ecc = using_ecc && (s->version >= TLS1_VERSION); + if (using_ecc) { + if (s->tlsext_ecpointformatlist != NULL) + OPENSSL_free(s->tlsext_ecpointformatlist); + if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL) { + SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT, + ERR_R_MALLOC_FAILURE); + return -1; + } + s->tlsext_ecpointformatlist_length = 3; + s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed; + s->tlsext_ecpointformatlist[1] = + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; + s->tlsext_ecpointformatlist[2] = + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; + + /* we support all named elliptic curves in RFC 4492 */ + if (s->tlsext_ellipticcurvelist != NULL) + OPENSSL_free(s->tlsext_ellipticcurvelist); + s->tlsext_ellipticcurvelist_length = + sizeof(pref_list) / sizeof(pref_list[0]) * 2; + if ((s->tlsext_ellipticcurvelist = + OPENSSL_malloc(s->tlsext_ellipticcurvelist_length)) == NULL) { + s->tlsext_ellipticcurvelist_length = 0; + SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT, + ERR_R_MALLOC_FAILURE); + return -1; + } + for (i = 0, j = s->tlsext_ellipticcurvelist; (unsigned int)i < + sizeof(pref_list) / sizeof(pref_list[0]); i++) { + int id = tls1_ec_nid2curve_id(pref_list[i]); + s2n(id, j); + } + } +# endif /* OPENSSL_NO_EC */ + +# ifdef TLSEXT_TYPE_opaque_prf_input + { + int r = 1; + + if (s->ctx->tlsext_opaque_prf_input_callback != 0) { + r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, + s-> + ctx->tlsext_opaque_prf_input_callback_arg); + if (!r) + return -1; + } + + if (s->tlsext_opaque_prf_input != NULL) { + if (s->s3->client_opaque_prf_input != NULL) { + /* shouldn't really happen */ + OPENSSL_free(s->s3->client_opaque_prf_input); + } + + if (s->tlsext_opaque_prf_input_len == 0) { + /* dummy byte just to get non-NULL */ + s->s3->client_opaque_prf_input = OPENSSL_malloc(1); + } else { + s->s3->client_opaque_prf_input = + BUF_memdup(s->tlsext_opaque_prf_input, + s->tlsext_opaque_prf_input_len); + } + if (s->s3->client_opaque_prf_input == NULL) { + SSLerr(SSL_F_SSL_PREPARE_CLIENTHELLO_TLSEXT, + ERR_R_MALLOC_FAILURE); + return -1; + } + s->s3->client_opaque_prf_input_len = + s->tlsext_opaque_prf_input_len; + } + + if (r == 2) + /* + * at callback's request, insist on receiving an appropriate + * server opaque PRF input + */ + s->s3->server_opaque_prf_input_len = + s->tlsext_opaque_prf_input_len; + } +# endif + + return 1; +} + +int ssl_prepare_serverhello_tlsext(SSL *s) +{ +# ifndef OPENSSL_NO_EC + /* + * If we are server and using an ECC cipher suite, send the point formats + * we support if the client sent us an ECPointsFormat extension. Note + * that the server is not supposed to send an EllipticCurves extension. + */ + + unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; + int using_ecc = (alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) + || (alg_a & SSL_aECDSA); + using_ecc = using_ecc && (s->session->tlsext_ecpointformatlist != NULL); + + if (using_ecc) { + if (s->tlsext_ecpointformatlist != NULL) + OPENSSL_free(s->tlsext_ecpointformatlist); + if ((s->tlsext_ecpointformatlist = OPENSSL_malloc(3)) == NULL) { + SSLerr(SSL_F_SSL_PREPARE_SERVERHELLO_TLSEXT, + ERR_R_MALLOC_FAILURE); + return -1; + } + s->tlsext_ecpointformatlist_length = 3; + s->tlsext_ecpointformatlist[0] = TLSEXT_ECPOINTFORMAT_uncompressed; + s->tlsext_ecpointformatlist[1] = + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime; + s->tlsext_ecpointformatlist[2] = + TLSEXT_ECPOINTFORMAT_ansiX962_compressed_char2; + } +# endif /* OPENSSL_NO_EC */ + + return 1; +} + +int ssl_check_clienthello_tlsext_early(SSL *s) +{ + int ret = SSL_TLSEXT_ERR_NOACK; + int al = SSL_AD_UNRECOGNIZED_NAME; + +# ifndef OPENSSL_NO_EC + /* + * The handling of the ECPointFormats extension is done elsewhere, namely + * in ssl3_choose_cipher in s3_lib.c. + */ + /* + * The handling of the EllipticCurves extension is done elsewhere, namely + * in ssl3_choose_cipher in s3_lib.c. + */ +# endif + + if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) + ret = + s->ctx->tlsext_servername_callback(s, &al, + s->ctx->tlsext_servername_arg); + else if (s->initial_ctx != NULL + && s->initial_ctx->tlsext_servername_callback != 0) + ret = + s->initial_ctx->tlsext_servername_callback(s, &al, + s-> + initial_ctx->tlsext_servername_arg); + +# ifdef TLSEXT_TYPE_opaque_prf_input + { + /* + * This sort of belongs into ssl_prepare_serverhello_tlsext(), but we + * might be sending an alert in response to the client hello, so this + * has to happen here in ssl_check_clienthello_tlsext_early(). + */ + + int r = 1; + + if (s->ctx->tlsext_opaque_prf_input_callback != 0) { + r = s->ctx->tlsext_opaque_prf_input_callback(s, NULL, 0, + s-> + ctx->tlsext_opaque_prf_input_callback_arg); + if (!r) { + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_INTERNAL_ERROR; + goto err; + } + } + + if (s->s3->server_opaque_prf_input != NULL) { + /* shouldn't really happen */ + OPENSSL_free(s->s3->server_opaque_prf_input); + } + s->s3->server_opaque_prf_input = NULL; + + if (s->tlsext_opaque_prf_input != NULL) { + if (s->s3->client_opaque_prf_input != NULL && + s->s3->client_opaque_prf_input_len == + s->tlsext_opaque_prf_input_len) { + /* + * can only use this extension if we have a server opaque PRF + * input of the same length as the client opaque PRF input! + */ + + if (s->tlsext_opaque_prf_input_len == 0) { + /* dummy byte just to get non-NULL */ + s->s3->server_opaque_prf_input = OPENSSL_malloc(1); + } else { + s->s3->server_opaque_prf_input = + BUF_memdup(s->tlsext_opaque_prf_input, + s->tlsext_opaque_prf_input_len); + } + if (s->s3->server_opaque_prf_input == NULL) { + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_INTERNAL_ERROR; + goto err; + } + s->s3->server_opaque_prf_input_len = + s->tlsext_opaque_prf_input_len; + } + } + + if (r == 2 && s->s3->server_opaque_prf_input == NULL) { + /* + * The callback wants to enforce use of the extension, but we + * can't do that with the client opaque PRF input; abort the + * handshake. + */ + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_HANDSHAKE_FAILURE; + } + } + + err: +# endif + switch (ret) { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; + + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s, SSL3_AL_WARNING, al); + return 1; + + case SSL_TLSEXT_ERR_NOACK: + s->servername_done = 0; + default: + return 1; + } +} + +int ssl_check_clienthello_tlsext_late(SSL *s) +{ + int ret = SSL_TLSEXT_ERR_OK; + int al; + + /* + * If status request then ask callback what to do. Note: this must be + * called after servername callbacks in case the certificate has + * changed, and must be called after the cipher has been chosen because + * this may influence which certificate is sent + */ + if ((s->tlsext_status_type != -1) && s->ctx && s->ctx->tlsext_status_cb) { + int r; + CERT_PKEY *certpkey; + certpkey = ssl_get_server_send_pkey(s); + /* If no certificate can't return certificate status */ + if (certpkey == NULL) { + s->tlsext_status_expected = 0; + return 1; + } + /* + * Set current certificate to one we will use so SSL_get_certificate + * et al can pick it up. + */ + s->cert->key = certpkey; + r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); + switch (r) { + /* We don't want to send a status request response */ + case SSL_TLSEXT_ERR_NOACK: + s->tlsext_status_expected = 0; + break; + /* status request response should be sent */ + case SSL_TLSEXT_ERR_OK: + if (s->tlsext_ocsp_resp) + s->tlsext_status_expected = 1; + else + s->tlsext_status_expected = 0; + break; + /* something bad happened */ + case SSL_TLSEXT_ERR_ALERT_FATAL: + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_INTERNAL_ERROR; + goto err; + } + } else + s->tlsext_status_expected = 0; + + err: + switch (ret) { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; + + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s, SSL3_AL_WARNING, al); + return 1; + + default: + return 1; + } +} + +int ssl_check_serverhello_tlsext(SSL *s) +{ + int ret = SSL_TLSEXT_ERR_NOACK; + int al = SSL_AD_UNRECOGNIZED_NAME; + +# ifndef OPENSSL_NO_EC + /* + * If we are client and using an elliptic curve cryptography cipher + * suite, then if server returns an EC point formats lists extension it + * must contain uncompressed. + */ + unsigned long alg_k = s->s3->tmp.new_cipher->algorithm_mkey; + unsigned long alg_a = s->s3->tmp.new_cipher->algorithm_auth; + if ((s->tlsext_ecpointformatlist != NULL) + && (s->tlsext_ecpointformatlist_length > 0) + && (s->session->tlsext_ecpointformatlist != NULL) + && (s->session->tlsext_ecpointformatlist_length > 0) + && ((alg_k & (SSL_kEECDH | SSL_kECDHr | SSL_kECDHe)) + || (alg_a & SSL_aECDSA))) { + /* we are using an ECC cipher */ + size_t i; + unsigned char *list; + int found_uncompressed = 0; + list = s->session->tlsext_ecpointformatlist; + for (i = 0; i < s->session->tlsext_ecpointformatlist_length; i++) { + if (*(list++) == TLSEXT_ECPOINTFORMAT_uncompressed) { + found_uncompressed = 1; + break; + } + } + if (!found_uncompressed) { + SSLerr(SSL_F_SSL_CHECK_SERVERHELLO_TLSEXT, + SSL_R_TLS_INVALID_ECPOINTFORMAT_LIST); + return -1; + } + } + ret = SSL_TLSEXT_ERR_OK; +# endif /* OPENSSL_NO_EC */ + + if (s->ctx != NULL && s->ctx->tlsext_servername_callback != 0) + ret = + s->ctx->tlsext_servername_callback(s, &al, + s->ctx->tlsext_servername_arg); + else if (s->initial_ctx != NULL + && s->initial_ctx->tlsext_servername_callback != 0) + ret = + s->initial_ctx->tlsext_servername_callback(s, &al, + s-> + initial_ctx->tlsext_servername_arg); + +# ifdef TLSEXT_TYPE_opaque_prf_input + if (s->s3->server_opaque_prf_input_len > 0) { + /* + * This case may indicate that we, as a client, want to insist on + * using opaque PRF inputs. So first verify that we really have a + * value from the server too. + */ + + if (s->s3->server_opaque_prf_input == NULL) { + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_HANDSHAKE_FAILURE; + } + + /* + * Anytime the server *has* sent an opaque PRF input, we need to + * check that we have a client opaque PRF input of the same size. + */ + if (s->s3->client_opaque_prf_input == NULL || + s->s3->client_opaque_prf_input_len != + s->s3->server_opaque_prf_input_len) { + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + al = SSL_AD_ILLEGAL_PARAMETER; + } + } +# endif + + OPENSSL_free(s->tlsext_ocsp_resp); + s->tlsext_ocsp_resp = NULL; + s->tlsext_ocsp_resplen = -1; + /* + * If we've requested certificate status and we wont get one tell the + * callback + */ + if ((s->tlsext_status_type != -1) && !(s->tlsext_status_expected) + && !(s->hit) && s->ctx && s->ctx->tlsext_status_cb) { + int r; + /* + * Call callback with resp == NULL and resplen == -1 so callback + * knows there is no response + */ + r = s->ctx->tlsext_status_cb(s, s->ctx->tlsext_status_arg); + if (r == 0) { + al = SSL_AD_BAD_CERTIFICATE_STATUS_RESPONSE; + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + } + if (r < 0) { + al = SSL_AD_INTERNAL_ERROR; + ret = SSL_TLSEXT_ERR_ALERT_FATAL; + } + } + + switch (ret) { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl3_send_alert(s, SSL3_AL_FATAL, al); + return -1; + + case SSL_TLSEXT_ERR_ALERT_WARNING: + ssl3_send_alert(s, SSL3_AL_WARNING, al); + return 1; + + case SSL_TLSEXT_ERR_NOACK: + s->servername_done = 0; + default: + return 1; + } +} + +/*- + * Since the server cache lookup is done early on in the processing of the + * ClientHello, and other operations depend on the result, we need to handle + * any TLS session ticket extension at the same time. + * + * session_id: points at the session ID in the ClientHello. This code will + * read past the end of this in order to parse out the session ticket + * extension, if any. + * len: the length of the session ID. + * limit: a pointer to the first byte after the ClientHello. + * ret: (output) on return, if a ticket was decrypted, then this is set to + * point to the resulting session. + * + * If s->tls_session_secret_cb is set then we are expecting a pre-shared key + * ciphersuite, in which case we have no use for session tickets and one will + * never be decrypted, nor will s->tlsext_ticket_expected be set to 1. + * + * Returns: + * -1: fatal error, either from parsing or decrypting the ticket. + * 0: no ticket was found (or was ignored, based on settings). + * 1: a zero length extension was found, indicating that the client supports + * session tickets but doesn't currently have one to offer. + * 2: either s->tls_session_secret_cb was set, or a ticket was offered but + * couldn't be decrypted because of a non-fatal error. + * 3: a ticket was successfully decrypted and *ret was set. + * + * Side effects: + * Sets s->tlsext_ticket_expected to 1 if the server will have to issue + * a new session ticket to the client because the client indicated support + * (and s->tls_session_secret_cb is NULL) but the client either doesn't have + * a session ticket or we couldn't use the one it gave us, or if + * s->ctx->tlsext_ticket_key_cb asked to renew the client's ticket. + * Otherwise, s->tlsext_ticket_expected is set to 0. + */ +int tls1_process_ticket(SSL *s, unsigned char *session_id, int len, + const unsigned char *limit, SSL_SESSION **ret) +{ + /* Point after session ID in client hello */ + const unsigned char *p = session_id + len; + unsigned short i; + + *ret = NULL; + s->tlsext_ticket_expected = 0; + + /* + * If tickets disabled behave as if no ticket present to permit stateful + * resumption. + */ + if (SSL_get_options(s) & SSL_OP_NO_TICKET) + return 0; + if ((s->version <= SSL3_VERSION) || !limit) + return 0; + if (p >= limit) + return -1; + /* Skip past DTLS cookie */ + if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER) { + i = *(p++); + p += i; + if (p >= limit) + return -1; + } + /* Skip past cipher list */ + n2s(p, i); + p += i; + if (p >= limit) + return -1; + /* Skip past compression algorithm list */ + i = *(p++); + p += i; + if (p > limit) + return -1; + /* Now at start of extensions */ + if ((p + 2) >= limit) + return 0; + n2s(p, i); + while ((p + 4) <= limit) { + unsigned short type, size; + n2s(p, type); + n2s(p, size); + if (p + size > limit) + return 0; + if (type == TLSEXT_TYPE_session_ticket) { + int r; + if (size == 0) { + /* + * The client will accept a ticket but doesn't currently have + * one. + */ + s->tlsext_ticket_expected = 1; + return 1; + } + if (s->tls_session_secret_cb) { + /* + * Indicate that the ticket couldn't be decrypted rather than + * generating the session from ticket now, trigger + * abbreviated handshake based on external mechanism to + * calculate the master secret later. + */ + return 2; + } + r = tls_decrypt_ticket(s, p, size, session_id, len, ret); + switch (r) { + case 2: /* ticket couldn't be decrypted */ + s->tlsext_ticket_expected = 1; + return 2; + case 3: /* ticket was decrypted */ + return r; + case 4: /* ticket decrypted but need to renew */ + s->tlsext_ticket_expected = 1; + return 3; + default: /* fatal error */ + return -1; + } + } + p += size; + } + return 0; +} + +/*- + * tls_decrypt_ticket attempts to decrypt a session ticket. + * + * etick: points to the body of the session ticket extension. + * eticklen: the length of the session tickets extenion. + * sess_id: points at the session ID. + * sesslen: the length of the session ID. + * psess: (output) on return, if a ticket was decrypted, then this is set to + * point to the resulting session. + * + * Returns: + * -1: fatal error, either from parsing or decrypting the ticket. + * 2: the ticket couldn't be decrypted. + * 3: a ticket was successfully decrypted and *psess was set. + * 4: same as 3, but the ticket needs to be renewed. + */ +static int tls_decrypt_ticket(SSL *s, const unsigned char *etick, + int eticklen, const unsigned char *sess_id, + int sesslen, SSL_SESSION **psess) +{ + SSL_SESSION *sess; + unsigned char *sdec; + const unsigned char *p; + int slen, mlen, renew_ticket = 0; + unsigned char tick_hmac[EVP_MAX_MD_SIZE]; + HMAC_CTX hctx; + EVP_CIPHER_CTX ctx; + SSL_CTX *tctx = s->initial_ctx; + /* Need at least keyname + iv + some encrypted data */ + if (eticklen < 48) + return 2; + /* Initialize session ticket encryption and HMAC contexts */ + HMAC_CTX_init(&hctx); + EVP_CIPHER_CTX_init(&ctx); + if (tctx->tlsext_ticket_key_cb) { + unsigned char *nctick = (unsigned char *)etick; + int rv = tctx->tlsext_ticket_key_cb(s, nctick, nctick + 16, + &ctx, &hctx, 0); + if (rv < 0) + return -1; + if (rv == 0) + return 2; + if (rv == 2) + renew_ticket = 1; + } else { + /* Check key name matches */ + if (memcmp(etick, tctx->tlsext_tick_key_name, 16)) + return 2; + if (HMAC_Init_ex(&hctx, tctx->tlsext_tick_hmac_key, 16, + tlsext_tick_md(), NULL) <= 0 + || EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, + tctx->tlsext_tick_aes_key, + etick + 16) <= 0) { + goto err; + } + } + /* + * Attempt to process session ticket, first conduct sanity and integrity + * checks on ticket. + */ + mlen = HMAC_size(&hctx); + if (mlen < 0) { + goto err; + } + eticklen -= mlen; + /* Check HMAC of encrypted ticket */ + if (HMAC_Update(&hctx, etick, eticklen) <= 0 + || HMAC_Final(&hctx, tick_hmac, NULL) <= 0) { + goto err; + } + HMAC_CTX_cleanup(&hctx); + if (CRYPTO_memcmp(tick_hmac, etick + eticklen, mlen)) { + EVP_CIPHER_CTX_cleanup(&ctx); + return 2; + } + /* Attempt to decrypt session data */ + /* Move p after IV to start of encrypted ticket, update length */ + p = etick + 16 + EVP_CIPHER_CTX_iv_length(&ctx); + eticklen -= 16 + EVP_CIPHER_CTX_iv_length(&ctx); + sdec = OPENSSL_malloc(eticklen); + if (sdec == NULL + || EVP_DecryptUpdate(&ctx, sdec, &slen, p, eticklen) <= 0) { + EVP_CIPHER_CTX_cleanup(&ctx); + OPENSSL_free(sdec); + return -1; + } + if (EVP_DecryptFinal(&ctx, sdec + slen, &mlen) <= 0) { + EVP_CIPHER_CTX_cleanup(&ctx); + OPENSSL_free(sdec); + return 2; + } + slen += mlen; + EVP_CIPHER_CTX_cleanup(&ctx); + p = sdec; + + sess = d2i_SSL_SESSION(NULL, &p, slen); + OPENSSL_free(sdec); + if (sess) { + /* + * The session ID, if non-empty, is used by some clients to detect + * that the ticket has been accepted. So we copy it to the session + * structure. If it is empty set length to zero as required by + * standard. + */ + if (sesslen) + memcpy(sess->session_id, sess_id, sesslen); + sess->session_id_length = sesslen; + *psess = sess; + if (renew_ticket) + return 4; + else + return 3; + } + ERR_clear_error(); + /* + * For session parse failure, indicate that we need to send a new ticket. + */ + return 2; +err: + EVP_CIPHER_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&hctx); + return -1; +} + +/* Tables to translate from NIDs to TLS v1.2 ids */ + +typedef struct { + int nid; + int id; +} tls12_lookup; + +static tls12_lookup tls12_md[] = { +# ifndef OPENSSL_NO_MD5 + {NID_md5, TLSEXT_hash_md5}, +# endif +# ifndef OPENSSL_NO_SHA + {NID_sha1, TLSEXT_hash_sha1}, +# endif +# ifndef OPENSSL_NO_SHA256 + {NID_sha224, TLSEXT_hash_sha224}, + {NID_sha256, TLSEXT_hash_sha256}, +# endif +# ifndef OPENSSL_NO_SHA512 + {NID_sha384, TLSEXT_hash_sha384}, + {NID_sha512, TLSEXT_hash_sha512} +# endif +}; + +static tls12_lookup tls12_sig[] = { +# ifndef OPENSSL_NO_RSA + {EVP_PKEY_RSA, TLSEXT_signature_rsa}, +# endif +# ifndef OPENSSL_NO_DSA + {EVP_PKEY_DSA, TLSEXT_signature_dsa}, +# endif +# ifndef OPENSSL_NO_ECDSA + {EVP_PKEY_EC, TLSEXT_signature_ecdsa} +# endif +}; + +static int tls12_find_id(int nid, tls12_lookup *table, size_t tlen) +{ + size_t i; + for (i = 0; i < tlen; i++) { + if (table[i].nid == nid) + return table[i].id; + } + return -1; +} + +# if 0 +static int tls12_find_nid(int id, tls12_lookup *table, size_t tlen) +{ + size_t i; + for (i = 0; i < tlen; i++) { + if (table[i].id == id) + return table[i].nid; + } + return -1; +} +# endif + +int tls12_get_sigandhash(unsigned char *p, const EVP_PKEY *pk, + const EVP_MD *md) +{ + int sig_id, md_id; + if (!md) + return 0; + md_id = tls12_find_id(EVP_MD_type(md), tls12_md, + sizeof(tls12_md) / sizeof(tls12_lookup)); + if (md_id == -1) + return 0; + sig_id = tls12_get_sigid(pk); + if (sig_id == -1) + return 0; + p[0] = (unsigned char)md_id; + p[1] = (unsigned char)sig_id; + return 1; +} + +int tls12_get_sigid(const EVP_PKEY *pk) +{ + return tls12_find_id(pk->type, tls12_sig, + sizeof(tls12_sig) / sizeof(tls12_lookup)); +} + +const EVP_MD *tls12_get_hash(unsigned char hash_alg) +{ + switch (hash_alg) { +# ifndef OPENSSL_NO_SHA + case TLSEXT_hash_sha1: + return EVP_sha1(); +# endif +# ifndef OPENSSL_NO_SHA256 + case TLSEXT_hash_sha224: + return EVP_sha224(); + + case TLSEXT_hash_sha256: + return EVP_sha256(); +# endif +# ifndef OPENSSL_NO_SHA512 + case TLSEXT_hash_sha384: + return EVP_sha384(); + + case TLSEXT_hash_sha512: + return EVP_sha512(); +# endif + default: + return NULL; + + } +} + +/* Set preferred digest for each key type */ + +int tls1_process_sigalgs(SSL *s, const unsigned char *data, int dsize) +{ + int i, idx; + const EVP_MD *md; + CERT *c = s->cert; + /* Extension ignored for TLS versions below 1.2 */ + if (TLS1_get_version(s) < TLS1_2_VERSION) + return 1; + /* Should never happen */ + if (!c) + return 0; + + c->pkeys[SSL_PKEY_DSA_SIGN].digest = NULL; + c->pkeys[SSL_PKEY_RSA_SIGN].digest = NULL; + c->pkeys[SSL_PKEY_RSA_ENC].digest = NULL; + c->pkeys[SSL_PKEY_ECC].digest = NULL; + + for (i = 0; i < dsize; i += 2) { + unsigned char hash_alg = data[i], sig_alg = data[i + 1]; + + switch (sig_alg) { +# ifndef OPENSSL_NO_RSA + case TLSEXT_signature_rsa: + idx = SSL_PKEY_RSA_SIGN; + break; +# endif +# ifndef OPENSSL_NO_DSA + case TLSEXT_signature_dsa: + idx = SSL_PKEY_DSA_SIGN; + break; +# endif +# ifndef OPENSSL_NO_ECDSA + case TLSEXT_signature_ecdsa: + idx = SSL_PKEY_ECC; + break; +# endif + default: + continue; + } + + if (c->pkeys[idx].digest == NULL) { + md = tls12_get_hash(hash_alg); + if (md) { + c->pkeys[idx].digest = md; + if (idx == SSL_PKEY_RSA_SIGN) + c->pkeys[SSL_PKEY_RSA_ENC].digest = md; + } + } + + } + + /* + * Set any remaining keys to default values. NOTE: if alg is not + * supported it stays as NULL. + */ +# ifndef OPENSSL_NO_DSA + if (!c->pkeys[SSL_PKEY_DSA_SIGN].digest) + c->pkeys[SSL_PKEY_DSA_SIGN].digest = EVP_sha1(); +# endif +# ifndef OPENSSL_NO_RSA + if (!c->pkeys[SSL_PKEY_RSA_SIGN].digest) { + c->pkeys[SSL_PKEY_RSA_SIGN].digest = EVP_sha1(); + c->pkeys[SSL_PKEY_RSA_ENC].digest = EVP_sha1(); + } +# endif +# ifndef OPENSSL_NO_ECDSA + if (!c->pkeys[SSL_PKEY_ECC].digest) + c->pkeys[SSL_PKEY_ECC].digest = EVP_sha1(); +# endif + return 1; +} + +#endif + +#ifndef OPENSSL_NO_HEARTBEATS +int tls1_process_heartbeat(SSL *s) +{ + unsigned char *p = &s->s3->rrec.data[0], *pl; + unsigned short hbtype; + unsigned int payload; + unsigned int padding = 16; /* Use minimum padding */ + + if (s->msg_callback) + s->msg_callback(0, s->version, TLS1_RT_HEARTBEAT, + &s->s3->rrec.data[0], s->s3->rrec.length, + s, s->msg_callback_arg); + + /* Read type and payload length first */ + if (1 + 2 + 16 > s->s3->rrec.length) + return 0; /* silently discard */ + hbtype = *p++; + n2s(p, payload); + if (1 + 2 + payload + 16 > s->s3->rrec.length) + return 0; /* silently discard per RFC 6520 sec. 4 */ + pl = p; + + if (hbtype == TLS1_HB_REQUEST) { + unsigned char *buffer, *bp; + int r; + + /* + * Allocate memory for the response, size is 1 bytes message type, + * plus 2 bytes payload length, plus payload, plus padding + */ + buffer = OPENSSL_malloc(1 + 2 + payload + padding); + if (buffer == NULL) + return -1; + bp = buffer; + + /* Enter response type, length and copy payload */ + *bp++ = TLS1_HB_RESPONSE; + s2n(payload, bp); + memcpy(bp, pl, payload); + bp += payload; + /* Random padding */ + if (RAND_pseudo_bytes(bp, padding) < 0) { + OPENSSL_free(buffer); + return -1; + } + + r = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buffer, + 3 + payload + padding); + + if (r >= 0 && s->msg_callback) + s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, + buffer, 3 + payload + padding, + s, s->msg_callback_arg); + + OPENSSL_free(buffer); + + if (r < 0) + return r; + } else if (hbtype == TLS1_HB_RESPONSE) { + unsigned int seq; + + /* + * We only send sequence numbers (2 bytes unsigned int), and 16 + * random bytes, so we just try to read the sequence number + */ + n2s(pl, seq); + + if (payload == 18 && seq == s->tlsext_hb_seq) { + s->tlsext_hb_seq++; + s->tlsext_hb_pending = 0; + } + } + + return 0; +} + +int tls1_heartbeat(SSL *s) +{ + unsigned char *buf, *p; + int ret = -1; + unsigned int payload = 18; /* Sequence number + random bytes */ + unsigned int padding = 16; /* Use minimum padding */ + + /* Only send if peer supports and accepts HB requests... */ + if (!(s->tlsext_heartbeat & SSL_TLSEXT_HB_ENABLED) || + s->tlsext_heartbeat & SSL_TLSEXT_HB_DONT_SEND_REQUESTS) { + SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PEER_DOESNT_ACCEPT); + return -1; + } + + /* ...and there is none in flight yet... */ + if (s->tlsext_hb_pending) { + SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_TLS_HEARTBEAT_PENDING); + return -1; + } + + /* ...and no handshake in progress. */ + if (SSL_in_init(s) || s->in_handshake) { + SSLerr(SSL_F_TLS1_HEARTBEAT, SSL_R_UNEXPECTED_MESSAGE); + return -1; + } + + /* + * Check if padding is too long, payload and padding must not exceed 2^14 + * - 3 = 16381 bytes in total. + */ + OPENSSL_assert(payload + padding <= 16381); + + /*- + * Create HeartBeat message, we just use a sequence number + * as payload to distuingish different messages and add + * some random stuff. + * - Message Type, 1 byte + * - Payload Length, 2 bytes (unsigned int) + * - Payload, the sequence number (2 bytes uint) + * - Payload, random bytes (16 bytes uint) + * - Padding + */ + buf = OPENSSL_malloc(1 + 2 + payload + padding); + p = buf; + /* Message Type */ + *p++ = TLS1_HB_REQUEST; + /* Payload length (18 bytes here) */ + s2n(payload, p); + /* Sequence number */ + s2n(s->tlsext_hb_seq, p); + /* 16 random bytes */ + if (RAND_pseudo_bytes(p, 16) < 0) { + SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); + goto err; + } + p += 16; + /* Random padding */ + if (RAND_pseudo_bytes(p, padding) < 0) { + SSLerr(SSL_F_TLS1_HEARTBEAT, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = ssl3_write_bytes(s, TLS1_RT_HEARTBEAT, buf, 3 + payload + padding); + if (ret >= 0) { + if (s->msg_callback) + s->msg_callback(1, s->version, TLS1_RT_HEARTBEAT, + buf, 3 + payload + padding, + s, s->msg_callback_arg); + + s->tlsext_hb_pending = 1; + } + +err: + OPENSSL_free(buf); + + return ret; +} +#endif diff --git a/libs/openssl/ssl/t1_meth.c b/libs/openssl/ssl/t1_meth.c new file mode 100644 index 00000000..4a1b0529 --- /dev/null +++ b/libs/openssl/ssl/t1_meth.c @@ -0,0 +1,81 @@ +/* ssl/t1_meth.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include +#include "ssl_locl.h" + +static const SSL_METHOD *tls1_get_method(int ver) +{ + if (ver == TLS1_2_VERSION) + return TLSv1_2_method(); + if (ver == TLS1_1_VERSION) + return TLSv1_1_method(); + if (ver == TLS1_VERSION) + return TLSv1_method(); + return NULL; +} + +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_method, + ssl3_accept, ssl3_connect, tls1_get_method) + + IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_method, + ssl3_accept, ssl3_connect, tls1_get_method) + + IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_method, + ssl3_accept, ssl3_connect, tls1_get_method) diff --git a/libs/openssl/ssl/t1_reneg.c b/libs/openssl/ssl/t1_reneg.c new file mode 100644 index 00000000..b9a35c7f --- /dev/null +++ b/libs/openssl/ssl/t1_reneg.c @@ -0,0 +1,292 @@ +/* ssl/t1_reneg.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ +/* ==================================================================== + * Copyright (c) 1998-2009 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include +#include +#include "ssl_locl.h" + +/* Add the client's renegotiation binding */ +int ssl_add_clienthello_renegotiate_ext(SSL *s, unsigned char *p, int *len, + int maxlen) +{ + if (p) { + if ((s->s3->previous_client_finished_len + 1) > maxlen) { + SSLerr(SSL_F_SSL_ADD_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATE_EXT_TOO_LONG); + return 0; + } + + /* Length byte */ + *p = s->s3->previous_client_finished_len; + p++; + + memcpy(p, s->s3->previous_client_finished, + s->s3->previous_client_finished_len); +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, "%s RI extension sent by client\n", + s->s3->previous_client_finished_len ? "Non-empty" : "Empty"); +#endif + } + + *len = s->s3->previous_client_finished_len + 1; + + return 1; +} + +/* + * Parse the client's renegotiation binding and abort if it's not right + */ +int ssl_parse_clienthello_renegotiate_ext(SSL *s, unsigned char *d, int len, + int *al) +{ + int ilen; + + /* Parse the length byte */ + if (len < 1) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_ENCODING_ERR); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + ilen = *d; + d++; + + /* Consistency check */ + if ((ilen + 1) != len) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_ENCODING_ERR); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + /* Check that the extension matches */ + if (ilen != s->s3->previous_client_finished_len) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } + + if (memcmp(d, s->s3->previous_client_finished, + s->s3->previous_client_finished_len)) { + SSLerr(SSL_F_SSL_PARSE_CLIENTHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, "%s RI extension received by server\n", + ilen ? "Non-empty" : "Empty"); +#endif + + s->s3->send_connection_binding = 1; + + return 1; +} + +/* Add the server's renegotiation binding */ +int ssl_add_serverhello_renegotiate_ext(SSL *s, unsigned char *p, int *len, + int maxlen) +{ + if (p) { + if ((s->s3->previous_client_finished_len + + s->s3->previous_server_finished_len + 1) > maxlen) { + SSLerr(SSL_F_SSL_ADD_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATE_EXT_TOO_LONG); + return 0; + } + + /* Length byte */ + *p = s->s3->previous_client_finished_len + + s->s3->previous_server_finished_len; + p++; + + memcpy(p, s->s3->previous_client_finished, + s->s3->previous_client_finished_len); + p += s->s3->previous_client_finished_len; + + memcpy(p, s->s3->previous_server_finished, + s->s3->previous_server_finished_len); +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, "%s RI extension sent by server\n", + s->s3->previous_client_finished_len ? "Non-empty" : "Empty"); +#endif + } + + *len = s->s3->previous_client_finished_len + + s->s3->previous_server_finished_len + 1; + + return 1; +} + +/* + * Parse the server's renegotiation binding and abort if it's not right + */ +int ssl_parse_serverhello_renegotiate_ext(SSL *s, unsigned char *d, int len, + int *al) +{ + int expected_len = s->s3->previous_client_finished_len + + s->s3->previous_server_finished_len; + int ilen; + + /* Check for logic errors */ + OPENSSL_assert(!expected_len || s->s3->previous_client_finished_len); + OPENSSL_assert(!expected_len || s->s3->previous_server_finished_len); + + /* Parse the length byte */ + if (len < 1) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_ENCODING_ERR); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + ilen = *d; + d++; + + /* Consistency check */ + if (ilen + 1 != len) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_ENCODING_ERR); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + /* Check that the extension matches */ + if (ilen != expected_len) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } + + if (memcmp(d, s->s3->previous_client_finished, + s->s3->previous_client_finished_len)) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_HANDSHAKE_FAILURE; + return 0; + } + d += s->s3->previous_client_finished_len; + + if (memcmp(d, s->s3->previous_server_finished, + s->s3->previous_server_finished_len)) { + SSLerr(SSL_F_SSL_PARSE_SERVERHELLO_RENEGOTIATE_EXT, + SSL_R_RENEGOTIATION_MISMATCH); + *al = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } +#ifdef OPENSSL_RI_DEBUG + fprintf(stderr, "%s RI extension received by client\n", + ilen ? "Non-empty" : "Empty"); +#endif + s->s3->send_connection_binding = 1; + + return 1; +} diff --git a/libs/openssl/ssl/t1_srvr.c b/libs/openssl/ssl/t1_srvr.c new file mode 100644 index 00000000..076ec86e --- /dev/null +++ b/libs/openssl/ssl/t1_srvr.c @@ -0,0 +1,89 @@ +/* ssl/t1_srvr.c */ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + +#include +#include "ssl_locl.h" +#include +#include +#include +#include +#include + +static const SSL_METHOD *tls1_get_server_method(int ver); +static const SSL_METHOD *tls1_get_server_method(int ver) +{ + if (ver == TLS1_2_VERSION) + return TLSv1_2_server_method(); + if (ver == TLS1_1_VERSION) + return TLSv1_1_server_method(); + if (ver == TLS1_VERSION) + return TLSv1_server_method(); + return NULL; +} + +IMPLEMENT_tls_meth_func(TLS1_2_VERSION, TLSv1_2_server_method, + ssl3_accept, + ssl_undefined_function, tls1_get_server_method) + + IMPLEMENT_tls_meth_func(TLS1_1_VERSION, TLSv1_1_server_method, + ssl3_accept, + ssl_undefined_function, tls1_get_server_method) + + IMPLEMENT_tls_meth_func(TLS1_VERSION, TLSv1_server_method, + ssl3_accept, + ssl_undefined_function, tls1_get_server_method) diff --git a/libs/openssl/ssl/tls_srp.c b/libs/openssl/ssl/tls_srp.c new file mode 100644 index 00000000..bb719ba4 --- /dev/null +++ b/libs/openssl/ssl/tls_srp.c @@ -0,0 +1,542 @@ +/* ssl/tls_srp.c */ +/* + * Written by Christophe Renou (christophe.renou@edelweb.fr) with the + * precious help of Peter Sylvester (peter.sylvester@edelweb.fr) for the + * EdelKey project and contributed to the OpenSSL project 2004. + */ +/* ==================================================================== + * Copyright (c) 2004-2011 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ +#include "ssl_locl.h" +#ifndef OPENSSL_NO_SRP + +# include +# include +# include + +int SSL_CTX_SRP_CTX_free(struct ssl_ctx_st *ctx) +{ + if (ctx == NULL) + return 0; + OPENSSL_free(ctx->srp_ctx.login); + BN_free(ctx->srp_ctx.N); + BN_free(ctx->srp_ctx.g); + BN_free(ctx->srp_ctx.s); + BN_free(ctx->srp_ctx.B); + BN_free(ctx->srp_ctx.A); + BN_free(ctx->srp_ctx.a); + BN_free(ctx->srp_ctx.b); + BN_free(ctx->srp_ctx.v); + ctx->srp_ctx.TLS_ext_srp_username_callback = NULL; + ctx->srp_ctx.SRP_cb_arg = NULL; + ctx->srp_ctx.SRP_verify_param_callback = NULL; + ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; + ctx->srp_ctx.N = NULL; + ctx->srp_ctx.g = NULL; + ctx->srp_ctx.s = NULL; + ctx->srp_ctx.B = NULL; + ctx->srp_ctx.A = NULL; + ctx->srp_ctx.a = NULL; + ctx->srp_ctx.b = NULL; + ctx->srp_ctx.v = NULL; + ctx->srp_ctx.login = NULL; + ctx->srp_ctx.info = NULL; + ctx->srp_ctx.strength = SRP_MINIMAL_N; + ctx->srp_ctx.srp_Mask = 0; + return (1); +} + +int SSL_SRP_CTX_free(struct ssl_st *s) +{ + if (s == NULL) + return 0; + OPENSSL_free(s->srp_ctx.login); + BN_free(s->srp_ctx.N); + BN_free(s->srp_ctx.g); + BN_free(s->srp_ctx.s); + BN_free(s->srp_ctx.B); + BN_free(s->srp_ctx.A); + BN_free(s->srp_ctx.a); + BN_free(s->srp_ctx.b); + BN_free(s->srp_ctx.v); + s->srp_ctx.TLS_ext_srp_username_callback = NULL; + s->srp_ctx.SRP_cb_arg = NULL; + s->srp_ctx.SRP_verify_param_callback = NULL; + s->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; + s->srp_ctx.N = NULL; + s->srp_ctx.g = NULL; + s->srp_ctx.s = NULL; + s->srp_ctx.B = NULL; + s->srp_ctx.A = NULL; + s->srp_ctx.a = NULL; + s->srp_ctx.b = NULL; + s->srp_ctx.v = NULL; + s->srp_ctx.login = NULL; + s->srp_ctx.info = NULL; + s->srp_ctx.strength = SRP_MINIMAL_N; + s->srp_ctx.srp_Mask = 0; + return (1); +} + +int SSL_SRP_CTX_init(struct ssl_st *s) +{ + SSL_CTX *ctx; + + if ((s == NULL) || ((ctx = s->ctx) == NULL)) + return 0; + s->srp_ctx.SRP_cb_arg = ctx->srp_ctx.SRP_cb_arg; + /* set client Hello login callback */ + s->srp_ctx.TLS_ext_srp_username_callback = + ctx->srp_ctx.TLS_ext_srp_username_callback; + /* set SRP N/g param callback for verification */ + s->srp_ctx.SRP_verify_param_callback = + ctx->srp_ctx.SRP_verify_param_callback; + /* set SRP client passwd callback */ + s->srp_ctx.SRP_give_srp_client_pwd_callback = + ctx->srp_ctx.SRP_give_srp_client_pwd_callback; + + s->srp_ctx.N = NULL; + s->srp_ctx.g = NULL; + s->srp_ctx.s = NULL; + s->srp_ctx.B = NULL; + s->srp_ctx.A = NULL; + s->srp_ctx.a = NULL; + s->srp_ctx.b = NULL; + s->srp_ctx.v = NULL; + s->srp_ctx.login = NULL; + s->srp_ctx.info = ctx->srp_ctx.info; + s->srp_ctx.strength = ctx->srp_ctx.strength; + + if (((ctx->srp_ctx.N != NULL) && + ((s->srp_ctx.N = BN_dup(ctx->srp_ctx.N)) == NULL)) || + ((ctx->srp_ctx.g != NULL) && + ((s->srp_ctx.g = BN_dup(ctx->srp_ctx.g)) == NULL)) || + ((ctx->srp_ctx.s != NULL) && + ((s->srp_ctx.s = BN_dup(ctx->srp_ctx.s)) == NULL)) || + ((ctx->srp_ctx.B != NULL) && + ((s->srp_ctx.B = BN_dup(ctx->srp_ctx.B)) == NULL)) || + ((ctx->srp_ctx.A != NULL) && + ((s->srp_ctx.A = BN_dup(ctx->srp_ctx.A)) == NULL)) || + ((ctx->srp_ctx.a != NULL) && + ((s->srp_ctx.a = BN_dup(ctx->srp_ctx.a)) == NULL)) || + ((ctx->srp_ctx.v != NULL) && + ((s->srp_ctx.v = BN_dup(ctx->srp_ctx.v)) == NULL)) || + ((ctx->srp_ctx.b != NULL) && + ((s->srp_ctx.b = BN_dup(ctx->srp_ctx.b)) == NULL))) { + SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_BN_LIB); + goto err; + } + if ((ctx->srp_ctx.login != NULL) && + ((s->srp_ctx.login = BUF_strdup(ctx->srp_ctx.login)) == NULL)) { + SSLerr(SSL_F_SSL_SRP_CTX_INIT, ERR_R_INTERNAL_ERROR); + goto err; + } + s->srp_ctx.srp_Mask = ctx->srp_ctx.srp_Mask; + + return (1); + err: + OPENSSL_free(s->srp_ctx.login); + BN_free(s->srp_ctx.N); + BN_free(s->srp_ctx.g); + BN_free(s->srp_ctx.s); + BN_free(s->srp_ctx.B); + BN_free(s->srp_ctx.A); + BN_free(s->srp_ctx.a); + BN_free(s->srp_ctx.b); + BN_free(s->srp_ctx.v); + return (0); +} + +int SSL_CTX_SRP_CTX_init(struct ssl_ctx_st *ctx) +{ + if (ctx == NULL) + return 0; + + ctx->srp_ctx.SRP_cb_arg = NULL; + /* set client Hello login callback */ + ctx->srp_ctx.TLS_ext_srp_username_callback = NULL; + /* set SRP N/g param callback for verification */ + ctx->srp_ctx.SRP_verify_param_callback = NULL; + /* set SRP client passwd callback */ + ctx->srp_ctx.SRP_give_srp_client_pwd_callback = NULL; + + ctx->srp_ctx.N = NULL; + ctx->srp_ctx.g = NULL; + ctx->srp_ctx.s = NULL; + ctx->srp_ctx.B = NULL; + ctx->srp_ctx.A = NULL; + ctx->srp_ctx.a = NULL; + ctx->srp_ctx.b = NULL; + ctx->srp_ctx.v = NULL; + ctx->srp_ctx.login = NULL; + ctx->srp_ctx.srp_Mask = 0; + ctx->srp_ctx.info = NULL; + ctx->srp_ctx.strength = SRP_MINIMAL_N; + + return (1); +} + +/* server side */ +int SSL_srp_server_param_with_username(SSL *s, int *ad) +{ + unsigned char b[SSL_MAX_MASTER_KEY_LENGTH]; + int al; + + *ad = SSL_AD_UNKNOWN_PSK_IDENTITY; + if ((s->srp_ctx.TLS_ext_srp_username_callback != NULL) && + ((al = + s->srp_ctx.TLS_ext_srp_username_callback(s, ad, + s->srp_ctx.SRP_cb_arg)) != + SSL_ERROR_NONE)) + return al; + + *ad = SSL_AD_INTERNAL_ERROR; + if ((s->srp_ctx.N == NULL) || + (s->srp_ctx.g == NULL) || + (s->srp_ctx.s == NULL) || (s->srp_ctx.v == NULL)) + return SSL3_AL_FATAL; + + if (RAND_bytes(b, sizeof(b)) <= 0) + return SSL3_AL_FATAL; + s->srp_ctx.b = BN_bin2bn(b, sizeof(b), NULL); + OPENSSL_cleanse(b, sizeof(b)); + + /* Calculate: B = (kv + g^b) % N */ + + return ((s->srp_ctx.B = + SRP_Calc_B(s->srp_ctx.b, s->srp_ctx.N, s->srp_ctx.g, + s->srp_ctx.v)) != + NULL) ? SSL_ERROR_NONE : SSL3_AL_FATAL; +} + +/* + * If the server just has the raw password, make up a verifier entry on the + * fly + */ +int SSL_set_srp_server_param_pw(SSL *s, const char *user, const char *pass, + const char *grp) +{ + SRP_gN *GN = SRP_get_default_gN(grp); + if (GN == NULL) + return -1; + s->srp_ctx.N = BN_dup(GN->N); + s->srp_ctx.g = BN_dup(GN->g); + if (s->srp_ctx.v != NULL) { + BN_clear_free(s->srp_ctx.v); + s->srp_ctx.v = NULL; + } + if (s->srp_ctx.s != NULL) { + BN_clear_free(s->srp_ctx.s); + s->srp_ctx.s = NULL; + } + if (!SRP_create_verifier_BN + (user, pass, &s->srp_ctx.s, &s->srp_ctx.v, GN->N, GN->g)) + return -1; + + return 1; +} + +int SSL_set_srp_server_param(SSL *s, const BIGNUM *N, const BIGNUM *g, + BIGNUM *sa, BIGNUM *v, char *info) +{ + if (N != NULL) { + if (s->srp_ctx.N != NULL) { + if (!BN_copy(s->srp_ctx.N, N)) { + BN_free(s->srp_ctx.N); + s->srp_ctx.N = NULL; + } + } else + s->srp_ctx.N = BN_dup(N); + } + if (g != NULL) { + if (s->srp_ctx.g != NULL) { + if (!BN_copy(s->srp_ctx.g, g)) { + BN_free(s->srp_ctx.g); + s->srp_ctx.g = NULL; + } + } else + s->srp_ctx.g = BN_dup(g); + } + if (sa != NULL) { + if (s->srp_ctx.s != NULL) { + if (!BN_copy(s->srp_ctx.s, sa)) { + BN_free(s->srp_ctx.s); + s->srp_ctx.s = NULL; + } + } else + s->srp_ctx.s = BN_dup(sa); + } + if (v != NULL) { + if (s->srp_ctx.v != NULL) { + if (!BN_copy(s->srp_ctx.v, v)) { + BN_free(s->srp_ctx.v); + s->srp_ctx.v = NULL; + } + } else + s->srp_ctx.v = BN_dup(v); + } + s->srp_ctx.info = info; + + if (!(s->srp_ctx.N) || + !(s->srp_ctx.g) || !(s->srp_ctx.s) || !(s->srp_ctx.v)) + return -1; + + return 1; +} + +int SRP_generate_server_master_secret(SSL *s, unsigned char *master_key) +{ + BIGNUM *K = NULL, *u = NULL; + int ret = -1, tmp_len; + unsigned char *tmp = NULL; + + if (!SRP_Verify_A_mod_N(s->srp_ctx.A, s->srp_ctx.N)) + goto err; + if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N))) + goto err; + if (! + (K = + SRP_Calc_server_key(s->srp_ctx.A, s->srp_ctx.v, u, s->srp_ctx.b, + s->srp_ctx.N))) + goto err; + + tmp_len = BN_num_bytes(K); + if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) + goto err; + BN_bn2bin(K, tmp); + ret = + s->method->ssl3_enc->generate_master_secret(s, master_key, tmp, + tmp_len); + err: + if (tmp) { + OPENSSL_cleanse(tmp, tmp_len); + OPENSSL_free(tmp); + } + BN_clear_free(K); + BN_clear_free(u); + return ret; +} + +/* client side */ +int SRP_generate_client_master_secret(SSL *s, unsigned char *master_key) +{ + BIGNUM *x = NULL, *u = NULL, *K = NULL; + int ret = -1, tmp_len; + char *passwd = NULL; + unsigned char *tmp = NULL; + + /* + * Checks if b % n == 0 + */ + if (SRP_Verify_B_mod_N(s->srp_ctx.B, s->srp_ctx.N) == 0) + goto err; + if (!(u = SRP_Calc_u(s->srp_ctx.A, s->srp_ctx.B, s->srp_ctx.N))) + goto err; + if (s->srp_ctx.SRP_give_srp_client_pwd_callback == NULL) + goto err; + if (! + (passwd = + s->srp_ctx.SRP_give_srp_client_pwd_callback(s, + s->srp_ctx.SRP_cb_arg))) + goto err; + if (!(x = SRP_Calc_x(s->srp_ctx.s, s->srp_ctx.login, passwd))) + goto err; + if (! + (K = + SRP_Calc_client_key(s->srp_ctx.N, s->srp_ctx.B, s->srp_ctx.g, x, + s->srp_ctx.a, u))) + goto err; + + tmp_len = BN_num_bytes(K); + if ((tmp = OPENSSL_malloc(tmp_len)) == NULL) + goto err; + BN_bn2bin(K, tmp); + ret = + s->method->ssl3_enc->generate_master_secret(s, master_key, tmp, + tmp_len); + err: + if (tmp) { + OPENSSL_cleanse(tmp, tmp_len); + OPENSSL_free(tmp); + } + BN_clear_free(K); + BN_clear_free(x); + if (passwd) { + OPENSSL_cleanse(passwd, strlen(passwd)); + OPENSSL_free(passwd); + } + BN_clear_free(u); + return ret; +} + +int srp_verify_server_param(SSL *s, int *al) +{ + SRP_CTX *srp = &s->srp_ctx; + /* + * Sanity check parameters: we can quickly check B % N == 0 by checking B + * != 0 since B < N + */ + if (BN_ucmp(srp->g, srp->N) >= 0 || BN_ucmp(srp->B, srp->N) >= 0 + || BN_is_zero(srp->B)) { + *al = SSL3_AD_ILLEGAL_PARAMETER; + return 0; + } + + if (BN_num_bits(srp->N) < srp->strength) { + *al = TLS1_AD_INSUFFICIENT_SECURITY; + return 0; + } + + if (srp->SRP_verify_param_callback) { + if (srp->SRP_verify_param_callback(s, srp->SRP_cb_arg) <= 0) { + *al = TLS1_AD_INSUFFICIENT_SECURITY; + return 0; + } + } else if (!SRP_check_known_gN_param(srp->g, srp->N)) { + *al = TLS1_AD_INSUFFICIENT_SECURITY; + return 0; + } + + return 1; +} + +int SRP_Calc_A_param(SSL *s) +{ + unsigned char rnd[SSL_MAX_MASTER_KEY_LENGTH]; + + if (RAND_bytes(rnd, sizeof(rnd)) <= 0) + return -1; + s->srp_ctx.a = BN_bin2bn(rnd, sizeof(rnd), s->srp_ctx.a); + OPENSSL_cleanse(rnd, sizeof(rnd)); + + if (! + (s->srp_ctx.A = SRP_Calc_A(s->srp_ctx.a, s->srp_ctx.N, s->srp_ctx.g))) + return -1; + + return 1; +} + +BIGNUM *SSL_get_srp_g(SSL *s) +{ + if (s->srp_ctx.g != NULL) + return s->srp_ctx.g; + return s->ctx->srp_ctx.g; +} + +BIGNUM *SSL_get_srp_N(SSL *s) +{ + if (s->srp_ctx.N != NULL) + return s->srp_ctx.N; + return s->ctx->srp_ctx.N; +} + +char *SSL_get_srp_username(SSL *s) +{ + if (s->srp_ctx.login != NULL) + return s->srp_ctx.login; + return s->ctx->srp_ctx.login; +} + +char *SSL_get_srp_userinfo(SSL *s) +{ + if (s->srp_ctx.info != NULL) + return s->srp_ctx.info; + return s->ctx->srp_ctx.info; +} + +# define tls1_ctx_ctrl ssl3_ctx_ctrl +# define tls1_ctx_callback_ctrl ssl3_ctx_callback_ctrl + +int SSL_CTX_set_srp_username(SSL_CTX *ctx, char *name) +{ + return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME, 0, name); +} + +int SSL_CTX_set_srp_password(SSL_CTX *ctx, char *password) +{ + return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_PASSWORD, 0, password); +} + +int SSL_CTX_set_srp_strength(SSL_CTX *ctx, int strength) +{ + return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_STRENGTH, strength, + NULL); +} + +int SSL_CTX_set_srp_verify_param_callback(SSL_CTX *ctx, + int (*cb) (SSL *, void *)) +{ + return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_VERIFY_PARAM_CB, + (void (*)(void))cb); +} + +int SSL_CTX_set_srp_cb_arg(SSL_CTX *ctx, void *arg) +{ + return tls1_ctx_ctrl(ctx, SSL_CTRL_SET_SRP_ARG, 0, arg); +} + +int SSL_CTX_set_srp_username_callback(SSL_CTX *ctx, + int (*cb) (SSL *, int *, void *)) +{ + return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_TLS_EXT_SRP_USERNAME_CB, + (void (*)(void))cb); +} + +int SSL_CTX_set_srp_client_pwd_callback(SSL_CTX *ctx, + char *(*cb) (SSL *, void *)) +{ + return tls1_ctx_callback_ctrl(ctx, SSL_CTRL_SET_SRP_GIVE_CLIENT_PWD_CB, + (void (*)(void))cb); +} + +#endif